diff --git a/.gitignore b/.gitignore index 59d383265d43..5be9ae80dc7c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +# Two-trick pony for OSX and other case insensitive file systems: +# Ignore ./python binary on Unix but still look into ./Python/ directory. +/python +!/Python/** *.cover *.o *.orig @@ -7,13 +11,13 @@ *.rej *.swp *~ +*.gc?? +*.profclang? +*.profraw .gdb_history Doc/build/ -Doc/tools/docutils/ -Doc/tools/jinja/ -Doc/tools/jinja2/ -Doc/tools/pygments/ -Doc/tools/sphinx/ +Doc/venv/ +Lib/distutils/command/*.pdb Lib/lib2to3/*.pickle Lib/test/data/* Lib/_sysconfigdata.py @@ -27,18 +31,31 @@ Modules/Setup.config Modules/Setup.local Modules/config.c Modules/ld_so_aix -Modules/_freeze_importlib -Modules/_testembed -PCbuild/*.bsc -PCbuild/*.dll -PCbuild/*.exe -PCbuild/*.exp -PCbuild/*.lib -PCbuild/*.ncb -PCbuild/*.o -PCbuild/*.pdb -PCbuild/Win32-temp-* +Programs/_freeze_importlib +Programs/_testembed +PC/python_nt*.h +PC/pythonnt_rc*.h +PC/*/*.exe +PC/*/*.exp +PC/*/*.lib +PC/*/*.bsc +PC/*/*.dll +PC/*/*.pdb +PC/*/*.user +PC/*/*.ncb +PC/*/*.suo +PC/*/Win32-temp-* +PC/*/x64-temp-* +PC/*/amd64 +PCbuild/*.user +PCbuild/*.suo +PCbuild/*.*sdf +PCbuild/*-pgi +PCbuild/*-pgo +PCbuild/.vs/ PCbuild/amd64/ +PCbuild/obj/ +PCBuild/win32/ .purify Parser/pgen __pycache__ @@ -58,9 +75,9 @@ libpython*.so* platform pybuilddir.txt pyconfig.h -python python-config python-config.py +python.bat python.exe python-gdb.py python.exe-gdb.py @@ -70,4 +87,8 @@ tags TAGS .coverage coverage/ +externals/ htmlcov/ +Tools/msi/obj +Tools/ssl/amd64 +Tools/ssl/win32 diff --git a/.hgeol b/.hgeol index aad79c21136b..05557851c98d 100644 --- a/.hgeol +++ b/.hgeol @@ -38,6 +38,14 @@ Lib/test/xmltestdata/* = BIN Lib/venv/scripts/nt/* = BIN +Lib/test/coding20731.py = BIN + +# Windows batch files work best with CRLF, there can be subtle problems with LF +**.bat = CRLF + +# The Windows readme is likely to be read in Notepad, so make it readable +PCbuild/readme.txt = CRLF + # All other files (which presumably are human-editable) are "native". # This must be the last rule! diff --git a/.hgignore b/.hgignore index 6128c2bbaef1..7f14dd63111a 100644 --- a/.hgignore +++ b/.hgignore @@ -9,6 +9,7 @@ TAGS$ autom4te.cache$ ^build/ ^Doc/build/ +^Doc/venv/ buildno$ config.cache config.log @@ -18,17 +19,13 @@ db_home platform$ pyconfig.h$ python$ +python.bat$ python.exe$ python-config$ python-config.py$ reflog.txt$ tags$ Lib/plat-mac/errors.rsrc.df.rsrc -Doc/tools/sphinx/ -Doc/tools/docutils/ -Doc/tools/jinja/ -Doc/tools/jinja2/ -Doc/tools/pygments/ Misc/python.pc Misc/python-config.sh$ Modules/Setup$ @@ -53,13 +50,15 @@ libpython*.so* *.pyd *.cover *~ +*.gc?? +*.profclang? +*.profraw +Lib/distutils/command/*.pdb Lib/lib2to3/*.pickle Lib/test/data/* Misc/*.wpu PC/python_nt*.h PC/pythonnt_rc*.h -PC/*.obj -PC/*.exe PC/*/*.exe PC/*/*.exp PC/*/*.lib @@ -72,31 +71,29 @@ PC/*/*.suo PC/*/Win32-temp-* PC/*/x64-temp-* PC/*/amd64 -PCbuild/*.exe -PCbuild/*.dll -PCbuild/*.pdb -PCbuild/*.lib -PCbuild/*.exp -PCbuild/*.o -PCbuild/*.ncb -PCbuild/*.bsc PCbuild/*.user PCbuild/*.suo PCbuild/*.*sdf -PCbuild/Win32-temp-* -PCbuild/x64-temp-* +PCbuild/*-pgi +PCbuild/*-pgo +PCbuild/.vs PCbuild/amd64 -PCbuild/ipch +PCbuild/obj +PCbuild/win32 Tools/unicode/build/ Tools/unicode/MAPPINGS/ BuildLog.htm __pycache__ -Modules/_freeze_importlib -Modules/_testembed +Programs/_freeze_importlib +Programs/_testembed .coverage coverage/ +externals/ htmlcov/ *.gcda *.gcno *.gcov coverage.info +Tools/msi/obj +Tools/ssl/amd64 +Tools/ssl/win32 diff --git a/.hgtouch b/.hgtouch index 7e3a5e737088..b9be0f11fdb8 100644 --- a/.hgtouch +++ b/.hgtouch @@ -2,7 +2,9 @@ # Define dependencies of generated files that are checked into hg. # The syntax of this file uses make rule dependencies, without actions -Python/importlib.h: Lib/importlib/_bootstrap.py Modules/_freeze_importlib.c +Python/importlib.h: Lib/importlib/_bootstrap.py Programs/_freeze_importlib.c + +Include/opcode.h: Lib/opcode.py Tools/scripts/generate_opcode_h.py Include/Python-ast.h: Parser/Python.asdl Parser/asdl.py Parser/asdl_c.py Python/Python-ast.c: Include/Python-ast.h diff --git a/Doc/Makefile b/Doc/Makefile index 3c7196e367bf..a42e98bd9cd7 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -5,24 +5,24 @@ # You can set these variables from the command line. PYTHON = python -SVNROOT = http://svn.python.org/projects -SPHINXOPTS = +SPHINXBUILD = sphinx-build PAPER = SOURCES = -DISTVERSION = $(shell $(PYTHON) tools/sphinxext/patchlevel.py) +DISTVERSION = $(shell $(PYTHON) tools/extensions/patchlevel.py) ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees -D latex_paper_size=$(PAPER) \ $(SPHINXOPTS) . build/$(BUILDER) $(SOURCES) -.PHONY: help checkout update build html htmlhelp latex text changes linkcheck \ +.PHONY: help build html htmlhelp latex text changes linkcheck \ suspicious coverage doctest pydoc-topics htmlview clean dist check serve \ - autobuild-dev autobuild-stable + autobuild-dev autobuild-stable venv help: @echo "Please use \`make ' where is one of" @echo " clean to remove build files" - @echo " update to update build tools" + @echo " venv to create a venv with necessary tools" @echo " html to make standalone HTML files" + @echo " htmlview to open the index page built by the html target in your browser" @echo " htmlhelp to make HTML files and a HTML help project" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " text to make plain text files" @@ -37,30 +37,8 @@ help: @echo " check to run a check for frequent markup errors" @echo " serve to serve the documentation on the localhost (8000)" -# Note: if you update versions here, do the same in make.bat and README.txt -checkout: - @if [ ! -d tools/sphinx ]; then \ - echo "Checking out Sphinx..."; \ - svn checkout $(SVNROOT)/external/Sphinx-1.0.7/sphinx tools/sphinx; \ - fi - @if [ ! -d tools/docutils ]; then \ - echo "Checking out Docutils..."; \ - svn checkout $(SVNROOT)/external/docutils-0.6/docutils tools/docutils; \ - fi - @if [ ! -d tools/jinja2 ]; then \ - echo "Checking out Jinja..."; \ - svn checkout $(SVNROOT)/external/Jinja-2.3.1/jinja2 tools/jinja2; \ - fi - @if [ ! -d tools/pygments ]; then \ - echo "Checking out Pygments..."; \ - svn checkout $(SVNROOT)/external/Pygments-1.5dev-20120930/pygments tools/pygments; \ - fi - -update: clean checkout - -build: checkout - mkdir -p build/$(BUILDER) build/doctrees - $(PYTHON) tools/sphinx-build.py $(ALLSPHINXOPTS) +build: + $(SPHINXBUILD) $(ALLSPHINXOPTS) @echo html: BUILDER = html @@ -91,39 +69,45 @@ changes: build @echo "The overview file is in build/changes." linkcheck: BUILDER = linkcheck -linkcheck: build - @echo "Link check complete; look for any errors in the above output" \ - "or in build/$(BUILDER)/output.txt" +linkcheck: + @$(MAKE) build BUILDER=$(BUILDER) || { \ + echo "Link check complete; look for any errors in the above output" \ + "or in build/$(BUILDER)/output.txt"; \ + false; } suspicious: BUILDER = suspicious -suspicious: build - @echo "Suspicious check complete; look for any errors in the above output" \ - "or in build/$(BUILDER)/suspicious.csv. If all issues are false" \ - "positives, append that file to tools/sphinxext/susp-ignored.csv." +suspicious: + @$(MAKE) build BUILDER=$(BUILDER) || { \ + echo "Suspicious check complete; look for any errors in the above output" \ + "or in build/$(BUILDER)/suspicious.csv. If all issues are false" \ + "positives, append that file to tools/susp-ignored.csv."; \ + false; } coverage: BUILDER = coverage coverage: build @echo "Coverage finished; see c.txt and python.txt in build/coverage" doctest: BUILDER = doctest -doctest: build - @echo "Testing of doctests in the sources finished, look at the" \ - "results in build/doctest/output.txt" +doctest: + @$(MAKE) build BUILDER=$(BUILDER) || { \ + echo "Testing of doctests in the sources finished, look at the" \ + "results in build/doctest/output.txt"; \ + false; } pydoc-topics: BUILDER = pydoc-topics pydoc-topics: build - @echo "Building finished; now copy build/pydoc-topics/topics.py" \ - "to ../Lib/pydoc_data/topics.py" + @echo "Building finished; now run this:" \ + "cp build/pydoc-topics/topics.py ../Lib/pydoc_data/topics.py" htmlview: html $(PYTHON) -c "import webbrowser; webbrowser.open('build/html/index.html')" clean: - -rm -rf build/* - -rm -rf tools/sphinx - -rm -rf tools/pygments - -rm -rf tools/jinja2 - -rm -rf tools/docutils + -rm -rf build/* venv/* + +venv: + $(PYTHON) -m venv venv + ./venv/bin/python3 -m pip install -U Sphinx dist: rm -rf dist @@ -163,16 +147,10 @@ dist: cp build/latex/docs-pdf.zip dist/python-$(DISTVERSION)-docs-pdf-letter.zip cp build/latex/docs-pdf.tar.bz2 dist/python-$(DISTVERSION)-docs-pdf-letter.tar.bz2 - # archive the epub build + # copy the epub build rm -rf build/epub make epub - mkdir -p dist/python-$(DISTVERSION)-docs-epub - cp -pPR build/epub/*.epub dist/python-$(DISTVERSION)-docs-epub/ - tar -C dist -cf dist/python-$(DISTVERSION)-docs-epub.tar python-$(DISTVERSION)-docs-epub - bzip2 -9 -k dist/python-$(DISTVERSION)-docs-epub.tar - (cd dist; zip -q -r -9 python-$(DISTVERSION)-docs-epub.zip python-$(DISTVERSION)-docs-epub) - rm -r dist/python-$(DISTVERSION)-docs-epub - rm dist/python-$(DISTVERSION)-docs-epub.tar + cp -pPR build/epub/Python.epub dist/python-$(DISTVERSION)-docs.epub check: $(PYTHON) tools/rstlint.py -i tools @@ -184,7 +162,6 @@ serve: # for development releases: always build autobuild-dev: - make update make dist SPHINXOPTS='-A daily=1 -A versionswitcher=1' -make suspicious @@ -192,11 +169,11 @@ autobuild-dev: autobuild-html: make html SPHINXOPTS='-A daily=1 -A versionswitcher=1' -# for stable releases: only build if not in pre-release stage (alpha, beta, rc) +# for stable releases: only build if not in pre-release stage (alpha, beta) +# release candidate downloads are okay, since the stable tree can be in that stage autobuild-stable: - @case $(DISTVERSION) in *[abc]*) \ + @case $(DISTVERSION) in *[ab]*) \ echo "Not building; $(DISTVERSION) is not a release version."; \ exit 1;; \ esac @make autobuild-dev - diff --git a/Doc/README.txt b/Doc/README.txt index 64e307ee6543..580d10241db5 100644 --- a/Doc/README.txt +++ b/Doc/README.txt @@ -3,124 +3,116 @@ Python Documentation README This directory contains the reStructuredText (reST) sources to the Python documentation. You don't need to build them yourself, prebuilt versions are -available at http://docs.python.org/download/. +available at . -Documentation on the authoring Python documentation, including information about +Documentation on authoring Python documentation, including information about both style and markup, is available in the "Documenting Python" chapter of the -developers guide (http://docs.python.org/devguide/documenting.html). -There's also a chapter intended to point out differences to -those familiar with the previous docs written in LaTeX. +developers guide . Building the docs ================= -You need to have Python 2.4 or higher installed; the toolset used to build the -docs is written in Python. It is called *Sphinx*, it is not included in this -tree, but maintained separately. Also needed are the docutils, supplying the -base markup that Sphinx uses, Jinja, a templating engine, and optionally -Pygments, a code highlighter. +You need to have Sphinx installed; it is the toolset +used to build the docs. It is not included in this tree, but maintained +separately and available from PyPI . Using make ---------- -Luckily, a Makefile has been prepared so that on Unix, provided you have -installed Python and Subversion, you can just run :: +A Makefile has been prepared so that on Unix, provided you have installed +Sphinx, you can just run :: make html -to check out the necessary toolset in the `tools/` subdirectory and build the -HTML output files. To view the generated HTML, point your favorite browser at -the top-level index `build/html/index.html` after running "make". +to build the HTML output files. + +On Windows, we try to emulate the Makefile as closely as possible with a +``make.bat`` file. To use a Python interpreter that's not called ``python``, use the standard way to set Makefile variables, using e.g. :: - make html PYTHON=/usr/bin/python2.5 - -Available make targets are: - - * "html", which builds standalone HTML files for offline viewing. - - * "htmlhelp", which builds HTML files and a HTML Help project file usable to - convert them into a single Compiled HTML (.chm) file -- these are popular - under Microsoft Windows, but very handy on every platform. - - To create the CHM file, you need to run the Microsoft HTML Help Workshop over - the generated project (.hhp) file. + make html PYTHON=python3 - * "latex", which builds LaTeX source files as input to "pdflatex" to produce - PDF documents. +On Windows, set the PYTHON environment variable instead. - * "text", which builds a plain text file for each source file. +To use a specific sphinx-build (something other than ``sphinx-build``), set +the SPHINXBUILD variable. - * "epub", which builds an EPUB document, suitable to be viewed on e-book - readers. - - * "linkcheck", which checks all external references to see whether they are - broken, redirected or malformed, and outputs this information to stdout as - well as a plain-text (.txt) file. +Available make targets are: - * "changes", which builds an overview over all versionadded/versionchanged/ - deprecated items in the current version. This is meant as a help for the - writer of the "What's New" document. +* "clean", which removes all build files. - * "coverage", which builds a coverage overview for standard library modules and - C API. +* "html", which builds standalone HTML files for offline viewing. - * "pydoc-topics", which builds a Python module containing a dictionary with - plain text documentation for the labels defined in - `tools/sphinxext/pyspecific.py` -- pydoc needs these to show topic and - keyword help. +* "htmlview", which re-uses the "html" builder, but then opens the main page + in your default web browser. -A "make update" updates the Subversion checkouts in `tools/`. +* "htmlhelp", which builds HTML files and a HTML Help project file usable to + convert them into a single Compiled HTML (.chm) file -- these are popular + under Microsoft Windows, but very handy on every platform. + To create the CHM file, you need to run the Microsoft HTML Help Workshop + over the generated project (.hhp) file. The make.bat script does this for + you on Windows. -Without make ------------- +* "latex", which builds LaTeX source files as input to "pdflatex" to produce + PDF documents. -You'll need to install the Sphinx package, either by checking it out via :: +* "text", which builds a plain text file for each source file. - svn co http://svn.python.org/projects/external/Sphinx-1.0.7/sphinx tools/sphinx +* "epub", which builds an EPUB document, suitable to be viewed on e-book + readers. -or by installing it from PyPI. +* "linkcheck", which checks all external references to see whether they are + broken, redirected or malformed, and outputs this information to stdout as + well as a plain-text (.txt) file. -Then, you need to install Docutils, either by checking it out via :: +* "changes", which builds an overview over all versionadded/versionchanged/ + deprecated items in the current version. This is meant as a help for the + writer of the "What's New" document. - svn co http://svn.python.org/projects/external/docutils-0.6/docutils tools/docutils +* "coverage", which builds a coverage overview for standard library modules and + C API. -or by installing it from http://docutils.sf.net/. +* "pydoc-topics", which builds a Python module containing a dictionary with + plain text documentation for the labels defined in + `tools/pyspecific.py` -- pydoc needs these to show topic and keyword help. -You also need Jinja2, either by checking it out via :: +* "suspicious", which checks the parsed markup for text that looks like + malformed and thus unconverted reST. - svn co http://svn.python.org/projects/external/Jinja-2.3.1/jinja2 tools/jinja2 +* "check", which checks for frequent markup errors. -or by installing it from PyPI. +* "serve", which serves the build/html directory on port 8000. -You can optionally also install Pygments, either as a checkout via :: +* "dist", (Unix only) which creates distributable archives of HTML, text, + PDF, and EPUB builds. - svn co http://svn.python.org/projects/external/Pygments-1.3.1/pygments tools/pygments -or from PyPI at http://pypi.python.org/pypi/Pygments. +Without make +------------ +Install the Sphinx package and its dependencies from PyPI. -Then, make an output directory, e.g. under `build/`, and run :: +Then, from the ``Doc`` directory, run :: - python tools/sphinx-build.py -b . build/ + sphinx-build -b . build/ -where `` is one of html, text, latex, or htmlhelp (for explanations see -the make targets above). +where ```` is one of html, text, latex, or htmlhelp (for explanations +see the make targets above). Contributing ============ Bugs in the content should be reported to the Python bug tracker at -http://bugs.python.org. +https://bugs.python.org. Bugs in the toolset should be reported in the Sphinx bug tracker at -http://www.bitbucket.org/birkenfeld/sphinx/issues/. +https://www.bitbucket.org/birkenfeld/sphinx/issues/. You can also send a mail to the Python Documentation Team at docs@python.org, and we will process your request as soon as possible. @@ -136,7 +128,7 @@ The Python source is copyrighted, but you can freely use and copy it as long as you don't change or remove the copyright notice: ---------------------------------------------------------------------- -Copyright (c) 2000-2013 Python Software Foundation. +Copyright (c) 2000-2015 Python Software Foundation. All rights reserved. Copyright (c) 2000 BeOpen.com. diff --git a/Doc/about.rst b/Doc/about.rst index d316f09ff345..3ea311fa629d 100644 --- a/Doc/about.rst +++ b/Doc/about.rst @@ -6,29 +6,27 @@ About these documents These documents are generated from `reStructuredText`_ sources by `Sphinx`_, a document processor specifically written for the Python documentation. -.. _reStructuredText: http://docutils.sf.net/rst.html -.. _Sphinx: http://sphinx.pocoo.org/ +.. _reStructuredText: http://docutils.sourceforge.net/rst.html +.. _Sphinx: http://sphinx-doc.org/ .. In the online version of these documents, you can submit comments and suggest changes directly on the documentation pages. -Development of the documentation and its toolchain takes place on the -docs@python.org mailing list. We're always looking for volunteers wanting -to help with the docs, so feel free to send a mail there! +Development of the documentation and its toolchain is an entirely volunteer +effort, just like Python itself. If you want to contribute, please take a +look at the :ref:`reporting-bugs` page for information on how to do so. New +volunteers are always welcome! Many thanks go to: * Fred L. Drake, Jr., the creator of the original Python documentation toolset and writer of much of the content; -* the `Docutils `_ project for creating +* the `Docutils `_ project for creating reStructuredText and the Docutils suite; * Fredrik Lundh for his `Alternative Python Reference `_ project from which Sphinx got many good ideas. -See :ref:`reporting-bugs` for information how to report bugs in this -documentation, or Python itself. - Contributors to the Python Documentation ---------------------------------------- diff --git a/Doc/bugs.rst b/Doc/bugs.rst index 3785ccb72b30..f01ae0e3900e 100644 --- a/Doc/bugs.rst +++ b/Doc/bugs.rst @@ -13,21 +13,23 @@ Documentation bugs ================== If you find a bug in this documentation or would like to propose an improvement, -please send an e-mail to docs@python.org describing the bug and where you found -it. If you have a suggestion how to fix it, include that as well. +please submit a bug report on the :ref:`tracker `. If you +have a suggestion how to fix it, include that as well. -docs@python.org is a mailing list run by volunteers; your request will be -noticed, even if it takes a while to be processed. +If you're short on time, you can also email your bug report to docs@python.org. +'docs@' is a mailing list run by volunteers; your request will be noticed, +though it may take a while to be processed. -Of course, if you want a more persistent record of your issue, you can use the -issue tracker for documentation bugs as well. +.. seealso:: + `Documentation bugs`_ on the Python issue tracker +.. _using-the-tracker: Using the Python issue tracker ============================== Bug reports for Python itself should be submitted via the Python Bug Tracker -(http://bugs.python.org/). The bug tracker offers a Web form which allows +(https://bugs.python.org/). The bug tracker offers a Web form which allows pertinent information to be entered and submitted to the developers. The first step in filing a report is to determine whether the problem has @@ -62,14 +64,24 @@ taken on the bug. .. seealso:: - `Python Developer's Guide `_ - Detailed description of the issue workflow and developers tools. - `How to Report Bugs Effectively `_ Article which goes into some detail about how to create a useful bug report. This describes what kind of information is useful and why it is useful. - `Bug Writing Guidelines `_ + `Bug Writing Guidelines `_ Information about writing a good bug report. Some of this is specific to the Mozilla project, but describes general good practices. + +Getting started contributing to Python yourself +=============================================== + +Beyond just reporting bugs that you find, you are also welcome to submit +patches to fix them. You can find more information on how to get started +patching Python in the `Python Developer's Guide`_. If you have questions, +the `core-mentorship mailing list`_ is a friendly place to get answers to +any and all questions pertaining to the process of fixing issues in Python. + +.. _Documentation bugs: https://bugs.python.org/issue?@filter=status&@filter=components&components=4&status=1&@columns=id,activity,title,status&@sort=-activity +.. _Python Developer's Guide: https://docs.python.org/devguide/ +.. _core-mentorship mailing list: https://mail.python.org/mailman/listinfo/core-mentorship/ diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst index b4efbf00f76f..ed62deaec1c8 100644 --- a/Doc/c-api/arg.rst +++ b/Doc/c-api/arg.rst @@ -45,6 +45,7 @@ in any early abort case). Unless otherwise stated, buffers are not NUL-terminated. .. note:: + For all ``#`` variants of formats (``s#``, ``y#``, etc.), the type of the length argument (int or :c:type:`Py_ssize_t`) is controlled by defining the macro :c:macro:`PY_SSIZE_T_CLEAN` before including @@ -64,19 +65,20 @@ Unless otherwise stated, buffers are not NUL-terminated. :exc:`UnicodeError` is raised. .. note:: - This format does not accept bytes-like objects. If you want to accept + This format does not accept :term:`bytes-like objects + `. If you want to accept filesystem paths and convert them to C character strings, it is preferable to use the ``O&`` format with :c:func:`PyUnicode_FSConverter` as *converter*. -``s*`` (:class:`str`, :class:`bytes`, :class:`bytearray` or buffer compatible object) [Py_buffer] - This format accepts Unicode objects as well as :term:`bytes-like object`\ s. +``s*`` (:class:`str` or :term:`bytes-like object`) [Py_buffer] + This format accepts Unicode objects as well as bytes-like objects. It fills a :c:type:`Py_buffer` structure provided by the caller. In this case the resulting C string may contain embedded NUL bytes. Unicode objects are converted to C strings using ``'utf-8'`` encoding. -``s#`` (:class:`str`, :class:`bytes` or read-only buffer compatible object) [const char \*, int or :c:type:`Py_ssize_t`] - Like ``s*``, except that it doesn't accept mutable buffer-like objects +``s#`` (:class:`str`, read-only :term:`bytes-like object`) [const char \*, int or :c:type:`Py_ssize_t`] + Like ``s*``, except that it doesn't accept mutable bytes-like objects such as :class:`bytearray`. The result is stored into two C variables, the first one a pointer to a C string, the second one its length. The string may contain embedded null bytes. Unicode objects are converted @@ -86,28 +88,28 @@ Unless otherwise stated, buffers are not NUL-terminated. Like ``s``, but the Python object may also be ``None``, in which case the C pointer is set to *NULL*. -``z*`` (:class:`str`, :class:`bytes`, :class:`bytearray`, buffer compatible object or ``None``) [Py_buffer] +``z*`` (:class:`str`, :term:`bytes-like object` or ``None``) [Py_buffer] Like ``s*``, but the Python object may also be ``None``, in which case the ``buf`` member of the :c:type:`Py_buffer` structure is set to *NULL*. -``z#`` (:class:`str`, :class:`bytes`, read-only buffer compatible object or ``None``) [const char \*, int] +``z#`` (:class:`str`, read-only :term:`bytes-like object` or ``None``) [const char \*, int] Like ``s#``, but the Python object may also be ``None``, in which case the C pointer is set to *NULL*. -``y`` (:class:`bytes`) [const char \*] +``y`` (read-only :term:`bytes-like object`) [const char \*] This format converts a bytes-like object to a C pointer to a character string; it does not accept Unicode objects. The bytes buffer must not contain embedded NUL bytes; if it does, a :exc:`TypeError` exception is raised. -``y*`` (:class:`bytes`, :class:`bytearray` or :term:`bytes-like object`) [Py_buffer] +``y*`` (:term:`bytes-like object`) [Py_buffer] This variant on ``s*`` doesn't accept Unicode objects, only - :term:`bytes-like object`\ s. **This is the recommended way to accept + bytes-like objects. **This is the recommended way to accept binary data.** -``y#`` (:class:`bytes`) [const char \*, int] - This variant on ``s#`` doesn't accept Unicode objects, only :term:`bytes-like - object`\ s. +``y#`` (read-only :term:`bytes-like object`) [const char \*, int] + This variant on ``s#`` doesn't accept Unicode objects, only bytes-like + objects. ``S`` (:class:`bytes`) [PyBytesObject \*] Requires that the Python object is a :class:`bytes` object, without @@ -150,7 +152,7 @@ Unless otherwise stated, buffers are not NUL-terminated. any conversion. Raises :exc:`TypeError` if the object is not a Unicode object. The C variable may also be declared as :c:type:`PyObject\*`. -``w*`` (:class:`bytearray` or read-write byte-oriented buffer) [Py_buffer] +``w*`` (read-write :term:`bytes-like object`) [Py_buffer] This format accepts any object which implements the read-write buffer interface. It fills a :c:type:`Py_buffer` structure provided by the caller. The buffer may contain embedded null bytes. The caller have to call @@ -294,6 +296,8 @@ Other objects the object pointer is stored. If the Python object does not have the required type, :exc:`TypeError` is raised. +.. _o_ampersand: + ``O&`` (object) [*converter*, *anything*] Convert a Python object to a C variable through a *converter* function. This takes two arguments: the first is a function, the second is the address of a C @@ -426,10 +430,11 @@ API Functions Function used to deconstruct the argument lists of "old-style" functions --- these are functions which use the :const:`METH_OLDARGS` parameter parsing - method. This is not recommended for use in parameter parsing in new code, and - most code in the standard interpreter has been modified to no longer use this - for that purpose. It does remain a convenient way to decompose other tuples, - however, and may continue to be used for that purpose. + method, which has been removed in Python 3. This is not recommended for use + in parameter parsing in new code, and most code in the standard interpreter + has been modified to no longer use this for that purpose. It does remain a + convenient way to decompose other tuples, however, and may continue to be + used for that purpose. .. c:function:: int PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...) @@ -513,7 +518,7 @@ Building values ``None`` is returned. ``y`` (:class:`bytes`) [char \*] - This converts a C string to a Python :func:`bytes` object. If the C + This converts a C string to a Python :class:`bytes` object. If the C string pointer is *NULL*, ``None`` is returned. ``y#`` (:class:`bytes`) [char \*, int] diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst index f703e9caf781..46c19d3ca3a9 100644 --- a/Doc/c-api/buffer.rst +++ b/Doc/c-api/buffer.rst @@ -89,6 +89,16 @@ a buffer, see :c:func:`PyObject_GetBuffer`. .. c:type:: Py_buffer + .. c:member:: void \*buf + + A pointer to the start of the logical structure described by the buffer + fields. This can be any location within the underlying physical memory + block of the exporter. For example, with negative :c:member:`~Py_buffer.strides` + the value may point to the end of the memory block. + + For :term:`contiguous` arrays, the value points to the beginning of + the memory block. + .. c:member:: void \*obj A new reference to the exporting object. The reference is owned by @@ -101,16 +111,6 @@ a buffer, see :c:func:`PyObject_GetBuffer`. this field is *NULL*. In general, exporting objects MUST NOT use this scheme. - .. c:member:: void \*buf - - A pointer to the start of the logical structure described by the buffer - fields. This can be any location within the underlying physical memory - block of the exporter. For example, with negative :c:member:`~Py_buffer.strides` - the value may point to the end of the memory block. - - For contiguous arrays, the value points to the beginning of the memory - block. - .. c:member:: Py_ssize_t len ``product(shape) * itemsize``. For contiguous arrays, this is the length @@ -133,15 +133,15 @@ a buffer, see :c:func:`PyObject_GetBuffer`. called on non-NULL :c:member:`~Py_buffer.format` values. Important exception: If a consumer requests a buffer without the - :c:macro:`PyBUF_FORMAT` flag, :c:member:`~Py_Buffer.format` will + :c:macro:`PyBUF_FORMAT` flag, :c:member:`~Py_buffer.format` will be set to *NULL*, but :c:member:`~Py_buffer.itemsize` still has the value for the original format. - If :c:member:`~Py_Buffer.shape` is present, the equality + If :c:member:`~Py_buffer.shape` is present, the equality ``product(shape) * itemsize == len`` still holds and the consumer can use :c:member:`~Py_buffer.itemsize` to navigate the buffer. - If :c:member:`~Py_Buffer.shape` is *NULL* as a result of a :c:macro:`PyBUF_SIMPLE` + If :c:member:`~Py_buffer.shape` is *NULL* as a result of a :c:macro:`PyBUF_SIMPLE` or a :c:macro:`PyBUF_WRITABLE` request, the consumer must disregard :c:member:`~Py_buffer.itemsize` and assume ``itemsize == 1``. @@ -156,7 +156,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`. .. c:member:: int ndim The number of dimensions the memory represents as an n-dimensional array. - If it is 0, :c:member:`~Py_Buffer.buf` points to a single item representing + If it is 0, :c:member:`~Py_buffer.buf` points to a single item representing a scalar. In this case, :c:member:`~Py_buffer.shape`, :c:member:`~Py_buffer.strides` and :c:member:`~Py_buffer.suboffsets` MUST be *NULL*. @@ -198,6 +198,9 @@ a buffer, see :c:func:`PyObject_GetBuffer`. indicates that no de-referencing should occur (striding in a contiguous memory block). + If all suboffsets are negative (i.e. no de-referencing is needed, then + this field must be NULL (the default value). + This type of array representation is used by the Python Imaging Library (PIL). See `complex arrays`_ for further information how to access elements of such an array. @@ -278,11 +281,14 @@ of the flags below it. +-----------------------------+-------+---------+------------+ +.. index:: contiguous, C-contiguous, Fortran contiguous + contiguity requests ~~~~~~~~~~~~~~~~~~~ -C or Fortran contiguity can be explicitly requested, with and without stride -information. Without stride information, the buffer must be C-contiguous. +C or Fortran :term:`contiguity ` can be explicitly requested, +with and without stride information. Without stride information, the buffer +must be C-contiguous. .. tabularcolumns:: |p{0.35\linewidth}|l|l|l|l| @@ -463,13 +469,13 @@ Buffer-related functions .. c:function:: int PyBuffer_IsContiguous(Py_buffer *view, char order) Return 1 if the memory defined by the *view* is C-style (*order* is - ``'C'``) or Fortran-style (*order* is ``'F'``) contiguous or either one + ``'C'``) or Fortran-style (*order* is ``'F'``) :term:`contiguous` or either one (*order* is ``'A'``). Return 0 otherwise. .. c:function:: void PyBuffer_FillContiguousStrides(int ndim, Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t itemsize, char order) - Fill the *strides* array with byte-strides of a contiguous (C-style if + Fill the *strides* array with byte-strides of a :term:`contiguous` (C-style if *order* is ``'C'`` or Fortran-style if *order* is ``'F'``) array of the given shape with the given number of bytes per element. @@ -489,8 +495,8 @@ Buffer-related functions :c:member:`view->obj` to *NULL* and return -1; If this function is used as part of a :ref:`getbufferproc `, - *exporter* MUST be set to the exporting object. Otherwise, *exporter* MUST - be NULL. + *exporter* MUST be set to the exporting object and *flags* must be passed + unmodified. Otherwise, *exporter* MUST be NULL. diff --git a/Doc/c-api/bytearray.rst b/Doc/c-api/bytearray.rst index 82022056df21..41b6e3c71be5 100644 --- a/Doc/c-api/bytearray.rst +++ b/Doc/c-api/bytearray.rst @@ -64,7 +64,8 @@ Direct API functions .. c:function:: char* PyByteArray_AsString(PyObject *bytearray) Return the contents of *bytearray* as a char array after checking for a - *NULL* pointer. + *NULL* pointer. The returned array always has an extra + null byte appended. .. c:function:: int PyByteArray_Resize(PyObject *bytearray, Py_ssize_t len) diff --git a/Doc/c-api/bytes.rst b/Doc/c-api/bytes.rst index 5666dac22c6f..23b712881af4 100644 --- a/Doc/c-api/bytes.rst +++ b/Doc/c-api/bytes.rst @@ -69,8 +69,8 @@ called with a non-bytes parameter. +===================+===============+================================+ | :attr:`%%` | *n/a* | The literal % character. | +-------------------+---------------+--------------------------------+ - | :attr:`%c` | int | A single character, | - | | | represented as an C int. | + | :attr:`%c` | int | A single byte, | + | | | represented as a C int. | +-------------------+---------------+--------------------------------+ | :attr:`%d` | int | Exactly equivalent to | | | | ``printf("%d")``. | @@ -109,7 +109,7 @@ called with a non-bytes parameter. +-------------------+---------------+--------------------------------+ An unrecognized format character causes all the rest of the format string to be - copied as-is to the result string, and any extra arguments discarded. + copied as-is to the result object, and any extra arguments discarded. .. c:function:: PyObject* PyBytes_FromFormatV(const char *format, va_list vargs) @@ -136,11 +136,13 @@ called with a non-bytes parameter. .. c:function:: char* PyBytes_AsString(PyObject *o) - Return a NUL-terminated representation of the contents of *o*. The pointer - refers to the internal buffer of *o*, not a copy. The data must not be - modified in any way, unless the string was just created using + Return a pointer to the contents of *o*. The pointer + refers to the internal buffer of *o*, which consists of ``len(o) + 1`` + bytes. The last byte in the buffer is always null, regardless of + whether there are any other null bytes. The data must not be + modified in any way, unless the object was just created using ``PyBytes_FromStringAndSize(NULL, size)``. It must not be deallocated. If - *o* is not a string object at all, :c:func:`PyBytes_AsString` returns *NULL* + *o* is not a bytes object at all, :c:func:`PyBytes_AsString` returns *NULL* and raises :exc:`TypeError`. @@ -151,16 +153,18 @@ called with a non-bytes parameter. .. c:function:: int PyBytes_AsStringAndSize(PyObject *obj, char **buffer, Py_ssize_t *length) - Return a NUL-terminated representation of the contents of the object *obj* + Return the null-terminated contents of the object *obj* through the output variables *buffer* and *length*. - If *length* is *NULL*, the resulting buffer may not contain NUL characters; + If *length* is *NULL*, the bytes object + may not contain embedded null bytes; if it does, the function returns ``-1`` and a :exc:`TypeError` is raised. - The buffer refers to an internal string buffer of *obj*, not a copy. The data - must not be modified in any way, unless the string was just created using + The buffer refers to an internal buffer of *obj*, which includes an + additional null byte at the end (not counted in *length*). The data + must not be modified in any way, unless the object was just created using ``PyBytes_FromStringAndSize(NULL, size)``. It must not be deallocated. If - *string* is not a string object at all, :c:func:`PyBytes_AsStringAndSize` + *obj* is not a bytes object at all, :c:func:`PyBytes_AsStringAndSize` returns ``-1`` and raises :exc:`TypeError`. @@ -168,14 +172,14 @@ called with a non-bytes parameter. Create a new bytes object in *\*bytes* containing the contents of *newpart* appended to *bytes*; the caller will own the new reference. The reference to - the old value of *bytes* will be stolen. If the new string cannot be + the old value of *bytes* will be stolen. If the new object cannot be created, the old reference to *bytes* will still be discarded and the value of *\*bytes* will be set to *NULL*; the appropriate exception will be set. .. c:function:: void PyBytes_ConcatAndDel(PyObject **bytes, PyObject *newpart) - Create a new string object in *\*bytes* containing the contents of *newpart* + Create a new bytes object in *\*bytes* containing the contents of *newpart* appended to *bytes*. This version decrements the reference count of *newpart*. diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst index 57e8072d99c8..9c9356338243 100644 --- a/Doc/c-api/code.rst +++ b/Doc/c-api/code.rst @@ -29,7 +29,7 @@ bound into a function. .. c:function:: int PyCode_Check(PyObject *co) - Return true if *co* is a :class:`code` object + Return true if *co* is a :class:`code` object. .. c:function:: int PyCode_GetNumFree(PyCodeObject *co) diff --git a/Doc/c-api/codec.rst b/Doc/c-api/codec.rst index 83252afbb7f7..dfe3d436e5f4 100644 --- a/Doc/c-api/codec.rst +++ b/Doc/c-api/codec.rst @@ -116,3 +116,8 @@ Registry API for Unicode encoding error handlers Replace the unicode encode error with backslash escapes (``\x``, ``\u`` and ``\U``). +.. c:function:: PyObject* PyCodec_NameReplaceErrors(PyObject *exc) + + Replace the unicode encode error with ``\N{...}`` escapes. + + .. versionadded:: 3.5 diff --git a/Doc/c-api/concrete.rst b/Doc/c-api/concrete.rst index 2d5638670ea4..47dab81891d3 100644 --- a/Doc/c-api/concrete.rst +++ b/Doc/c-api/concrete.rst @@ -112,5 +112,6 @@ Other Objects weakref.rst capsule.rst gen.rst + coro.rst datetime.rst diff --git a/Doc/c-api/conversion.rst b/Doc/c-api/conversion.rst index 9578f984fd8e..9566d9d79200 100644 --- a/Doc/c-api/conversion.rst +++ b/Doc/c-api/conversion.rst @@ -119,13 +119,13 @@ The following functions provide locale-independent string to number conversions. .. versionadded:: 3.1 -.. c:function:: int PyOS_stricmp(char *s1, char *s2) +.. c:function:: int PyOS_stricmp(const char *s1, const char *s2) Case insensitive comparison of strings. The function works almost identically to :c:func:`strcmp` except that it ignores the case. -.. c:function:: int PyOS_strnicmp(char *s1, char *s2, Py_ssize_t size) +.. c:function:: int PyOS_strnicmp(const char *s1, const char *s2, Py_ssize_t size) Case insensitive comparison of strings. The function works almost identically to :c:func:`strncmp` except that it ignores the case. diff --git a/Doc/c-api/coro.rst b/Doc/c-api/coro.rst new file mode 100644 index 000000000000..2fe50b5d8c44 --- /dev/null +++ b/Doc/c-api/coro.rst @@ -0,0 +1,34 @@ +.. highlightlang:: c + +.. _coro-objects: + +Coroutine Objects +----------------- + +.. versionadded:: 3.5 + +Coroutine objects are what functions declared with an ``async`` keyword +return. + + +.. c:type:: PyCoroObject + + The C structure used for coroutine objects. + + +.. c:var:: PyTypeObject PyCoro_Type + + The type object corresponding to coroutine objects. + + +.. c:function:: int PyCoro_CheckExact(PyObject *ob) + + Return true if *ob*'s type is *PyCoro_Type*; *ob* must not be *NULL*. + + +.. c:function:: PyObject* PyCoro_New(PyFrameObject *frame, PyObject *name, PyObject *qualname) + + Create and return a new coroutine object based on the *frame* object, + with ``__name__`` and ``__qualname__`` set to *name* and *qualname*. + A reference to *frame* is stolen by this function. The *frame* argument + must not be *NULL*. diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index 5a9dca284500..aeff640564b0 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -201,8 +201,11 @@ Dictionary Objects .. c:function:: int PyDict_Update(PyObject *a, PyObject *b) - This is the same as ``PyDict_Merge(a, b, 1)`` in C, or ``a.update(b)`` in - Python. Return ``0`` on success or ``-1`` if an exception was raised. + This is the same as ``PyDict_Merge(a, b, 1)`` in C, and is similar to + ``a.update(b)`` in Python except that :c:func:`PyDict_Update` doesn't fall + back to the iterating over a sequence of key value pairs if the second + argument has no "keys" attribute. Return ``0`` on success or ``-1`` if an + exception was raised. .. c:function:: int PyDict_MergeFromSeq2(PyObject *a, PyObject *seq2, int override) diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index 8658a5854104..3fd69ba80fa3 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -9,13 +9,19 @@ Exception Handling The functions described in this chapter will let you handle and raise Python exceptions. It is important to understand some of the basics of Python -exception handling. It works somewhat like the Unix :c:data:`errno` variable: +exception handling. It works somewhat like the POSIX :c:data:`errno` variable: there is a global indicator (per thread) of the last error that occurred. Most -functions don't clear this on success, but will set it to indicate the cause of -the error on failure. Most functions also return an error indicator, usually -*NULL* if they are supposed to return a pointer, or ``-1`` if they return an -integer (exception: the :c:func:`PyArg_\*` functions return ``1`` for success and -``0`` for failure). +C API functions don't clear this on success, but will set it to indicate the +cause of the error on failure. Most C API functions also return an error +indicator, usually *NULL* if they are supposed to return a pointer, or ``-1`` +if they return an integer (exception: the :c:func:`PyArg_\*` functions +return ``1`` for success and ``0`` for failure). + +Concretely, the error indicator consists of three object pointers: the +exception's type, the exception's value, and the traceback object. Any +of those pointers can be NULL if non-set (although some combinations are +forbidden, for example you can't have a non-NULL traceback if the exception +type is NULL). When a function must fail because some function it called failed, it generally doesn't set the error indicator; the function it called already set it. It is @@ -27,12 +33,21 @@ the caller that an error has been set. If the error is not handled or carefully propagated, additional calls into the Python/C API may not behave as intended and may fail in mysterious ways. -The error indicator consists of three Python objects corresponding to the result -of ``sys.exc_info()``. API functions exist to interact with the error indicator -in various ways. There is a separate error indicator for each thread. +.. note:: + The error indicator is **not** the result of :func:`sys.exc_info()`. + The former corresponds to an exception that is not yet caught (and is + therefore still propagating), while the latter returns an exception after + it is caught (and has therefore stopped propagating). -.. XXX Order of these should be more thoughtful. - Either alphabetical or some kind of structure. + +Printing and clearing +===================== + + +.. c:function:: void PyErr_Clear() + + Clear the error indicator. If the error indicator is not set, there is no + effect. .. c:function:: void PyErr_PrintEx(int set_sys_last_vars) @@ -51,117 +66,24 @@ in various ways. There is a separate error indicator for each thread. Alias for ``PyErr_PrintEx(1)``. -.. c:function:: PyObject* PyErr_Occurred() - - Test whether the error indicator is set. If set, return the exception *type* - (the first argument to the last call to one of the :c:func:`PyErr_Set\*` - functions or to :c:func:`PyErr_Restore`). If not set, return *NULL*. You do not - own a reference to the return value, so you do not need to :c:func:`Py_DECREF` - it. - - .. note:: - - Do not compare the return value to a specific exception; use - :c:func:`PyErr_ExceptionMatches` instead, shown below. (The comparison could - easily fail since the exception may be an instance instead of a class, in the - case of a class exception, or it may the a subclass of the expected exception.) - - -.. c:function:: int PyErr_ExceptionMatches(PyObject *exc) - - Equivalent to ``PyErr_GivenExceptionMatches(PyErr_Occurred(), exc)``. This - should only be called when an exception is actually set; a memory access - violation will occur if no exception has been raised. - - -.. c:function:: int PyErr_GivenExceptionMatches(PyObject *given, PyObject *exc) - - Return true if the *given* exception matches the exception in *exc*. If - *exc* is a class object, this also returns true when *given* is an instance - of a subclass. If *exc* is a tuple, all exceptions in the tuple (and - recursively in subtuples) are searched for a match. - - -.. c:function:: void PyErr_NormalizeException(PyObject**exc, PyObject**val, PyObject**tb) - - Under certain circumstances, the values returned by :c:func:`PyErr_Fetch` below - can be "unnormalized", meaning that ``*exc`` is a class object but ``*val`` is - not an instance of the same class. This function can be used to instantiate - the class in that case. If the values are already normalized, nothing happens. - The delayed normalization is implemented to improve performance. - - -.. c:function:: void PyErr_Clear() - - Clear the error indicator. If the error indicator is not set, there is no - effect. - - -.. c:function:: void PyErr_Fetch(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback) - - Retrieve the error indicator into three variables whose addresses are passed. - If the error indicator is not set, set all three variables to *NULL*. If it is - set, it will be cleared and you own a reference to each object retrieved. The - value and traceback object may be *NULL* even when the type object is not. - - .. note:: - - This function is normally only used by code that needs to handle exceptions or - by code that needs to save and restore the error indicator temporarily. - - -.. c:function:: void PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback) - - Set the error indicator from the three objects. If the error indicator is - already set, it is cleared first. If the objects are *NULL*, the error - indicator is cleared. Do not pass a *NULL* type and non-*NULL* value or - traceback. The exception type should be a class. Do not pass an invalid - exception type or value. (Violating these rules will cause subtle problems - later.) This call takes away a reference to each object: you must own a - reference to each object before the call and after the call you no longer own - these references. (If you don't understand this, don't use this function. I - warned you.) - - .. note:: - - This function is normally only used by code that needs to save and restore the - error indicator temporarily; use :c:func:`PyErr_Fetch` to save the current - exception state. - - -.. c:function:: void PyErr_GetExcInfo(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback) - - Retrieve the exception info, as known from ``sys.exc_info()``. This refers - to an exception that was already caught, not to an exception that was - freshly raised. Returns new references for the three objects, any of which - may be *NULL*. Does not modify the exception info state. - - .. note:: - - This function is not normally used by code that wants to handle exceptions. - Rather, it can be used when code needs to save and restore the exception - state temporarily. Use :c:func:`PyErr_SetExcInfo` to restore or clear the - exception state. - - .. versionadded:: 3.3 - +.. c:function:: void PyErr_WriteUnraisable(PyObject *obj) -.. c:function:: void PyErr_SetExcInfo(PyObject *type, PyObject *value, PyObject *traceback) + This utility function prints a warning message to ``sys.stderr`` when an + exception has been set but it is impossible for the interpreter to actually + raise the exception. It is used, for example, when an exception occurs in an + :meth:`__del__` method. - Set the exception info, as known from ``sys.exc_info()``. This refers - to an exception that was already caught, not to an exception that was - freshly raised. This function steals the references of the arguments. - To clear the exception state, pass *NULL* for all three arguments. - For general rules about the three arguments, see :c:func:`PyErr_Restore`. + The function is called with a single argument *obj* that identifies the context + in which the unraisable exception occurred. The repr of *obj* will be printed in + the warning message. - .. note:: - This function is not normally used by code that wants to handle exceptions. - Rather, it can be used when code needs to save and restore the exception - state temporarily. Use :c:func:`PyErr_GetExcInfo` to read the exception - state. +Raising exceptions +================== - .. versionadded:: 3.3 +These functions help you set the current thread's error indicator. +For convenience, some of these functions will always return a +NULL pointer for use in a ``return`` statement. .. c:function:: void PyErr_SetString(PyObject *type, const char *message) @@ -187,6 +109,14 @@ in various ways. There is a separate error indicator for each thread. string. +.. c:function:: PyObject* PyErr_FormatV(PyObject *exception, const char *format, va_list vargs) + + Same as :c:func:`PyErr_Format`, but taking a :c:type:`va_list` argument rather + than a variable number of arguments. + + .. versionadded:: 3.5 + + .. c:function:: void PyErr_SetNone(PyObject *type) This is a shorthand for ``PyErr_SetObject(type, Py_None)``. @@ -226,11 +156,20 @@ in various ways. There is a separate error indicator for each thread. Similar to :c:func:`PyErr_SetFromErrno`, with the additional behavior that if *filenameObject* is not *NULL*, it is passed to the constructor of *type* as - a third parameter. In the case of exceptions such as :exc:`IOError` and - :exc:`OSError`, this is used to define the :attr:`filename` attribute of the + a third parameter. In the case of :exc:`OSError` exception, + this is used to define the :attr:`filename` attribute of the exception instance. +.. c:function:: PyObject* PyErr_SetFromErrnoWithFilenameObjects(PyObject *type, PyObject *filenameObject, PyObject *filenameObject2) + + Similar to :c:func:`PyErr_SetFromErrnoWithFilenameObject`, but takes a second + filename object, for raising errors when a function that takes two filenames + fails. + + .. versionadded:: 3.4 + + .. c:function:: PyObject* PyErr_SetFromErrnoWithFilename(PyObject *type, const char *filename) Similar to :c:func:`PyErr_SetFromErrnoWithFilenameObject`, but the filename @@ -256,13 +195,6 @@ in various ways. There is a separate error indicator for each thread. specifying the exception type to be raised. Availability: Windows. -.. c:function:: PyObject* PyErr_SetFromWindowsErrWithFilenameObject(int ierr, PyObject *filenameObject) - - Similar to :c:func:`PyErr_SetFromWindowsErr`, with the additional behavior - that if *filenameObject* is not *NULL*, it is passed to the constructor of - :exc:`WindowsError` as a third parameter. Availability: Windows. - - .. c:function:: PyObject* PyErr_SetFromWindowsErrWithFilename(int ierr, const char *filename) Similar to :c:func:`PyErr_SetFromWindowsErrWithFilenameObject`, but the @@ -277,6 +209,15 @@ in various ways. There is a separate error indicator for each thread. Availability: Windows. +.. c:function:: PyObject* PyErr_SetExcFromWindowsErrWithFilenameObjects(PyObject *type, int ierr, PyObject *filename, PyObject *filename2) + + Similar to :c:func:`PyErr_SetExcFromWindowsErrWithFilenameObject`, + but accepts a second filename object. + Availability: Windows. + + .. versionadded:: 3.4 + + .. c:function:: PyObject* PyErr_SetExcFromWindowsErrWithFilename(PyObject *type, int ierr, const char *filename) Similar to :c:func:`PyErr_SetFromWindowsErrWithFilename`, with an additional @@ -300,18 +241,18 @@ in various ways. There is a separate error indicator for each thread. attributes, which make the exception printing subsystem think the exception is a :exc:`SyntaxError`. -.. versionadded:: 3.4 + .. versionadded:: 3.4 -.. c:function:: void PyErr_SyntaxLocationEx(char *filename, int lineno, int col_offset) +.. c:function:: void PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset) Like :c:func:`PyErr_SyntaxLocationObject`, but *filename* is a byte string decoded from the filesystem encoding (:func:`os.fsdecode`). -.. versionadded:: 3.2 + .. versionadded:: 3.2 -.. c:function:: void PyErr_SyntaxLocation(char *filename, int lineno) +.. c:function:: void PyErr_SyntaxLocation(const char *filename, int lineno) Like :c:func:`PyErr_SyntaxLocationEx`, but the col_offset parameter is omitted. @@ -325,7 +266,23 @@ in various ways. There is a separate error indicator for each thread. use. -.. c:function:: int PyErr_WarnEx(PyObject *category, char *message, int stack_level) +Issuing warnings +================ + +Use these functions to issue warnings from C code. They mirror similar +functions exported by the Python :mod:`warnings` module. They normally +print a warning message to *sys.stderr*; however, it is +also possible that the user has specified that warnings are to be turned into +errors, and in that case they will raise an exception. It is also possible that +the functions raise an exception because of a problem with the warning machinery. +The return value is ``0`` if no exception is raised, or ``-1`` if an exception +is raised. (It is not possible to determine whether a warning message is +actually printed, nor what the reason is for the exception; this is +intentional.) If an exception is raised, the caller should do its normal +exception handling (for example, :c:func:`Py_DECREF` owned references and return +an error value). + +.. c:function:: int PyErr_WarnEx(PyObject *category, const char *message, Py_ssize_t stack_level) Issue a warning message. The *category* argument is a warning category (see below) or *NULL*; the *message* argument is an UTF-8 encoded string. *stack_level* is a @@ -334,18 +291,6 @@ in various ways. There is a separate error indicator for each thread. is the function calling :c:func:`PyErr_WarnEx`, 2 is the function above that, and so forth. - This function normally prints a warning message to *sys.stderr*; however, it is - also possible that the user has specified that warnings are to be turned into - errors, and in that case this will raise an exception. It is also possible that - the function raises an exception because of a problem with the warning machinery - (the implementation imports the :mod:`warnings` module to do the heavy lifting). - The return value is ``0`` if no exception is raised, or ``-1`` if an exception - is raised. (It is not possible to determine whether a warning message is - actually printed, nor what the reason is for the exception; this is - intentional.) If an exception is raised, the caller should do its normal - exception handling (for example, :c:func:`Py_DECREF` owned references and return - an error value). - Warning categories must be subclasses of :c:data:`Warning`; the default warning category is :c:data:`RuntimeWarning`. The standard Python warning categories are available as global variables whose names are ``PyExc_`` followed by the Python @@ -389,6 +334,139 @@ in various ways. There is a separate error indicator for each thread. .. versionadded:: 3.2 +Querying the error indicator +============================ + +.. c:function:: PyObject* PyErr_Occurred() + + Test whether the error indicator is set. If set, return the exception *type* + (the first argument to the last call to one of the :c:func:`PyErr_Set\*` + functions or to :c:func:`PyErr_Restore`). If not set, return *NULL*. You do not + own a reference to the return value, so you do not need to :c:func:`Py_DECREF` + it. + + .. note:: + + Do not compare the return value to a specific exception; use + :c:func:`PyErr_ExceptionMatches` instead, shown below. (The comparison could + easily fail since the exception may be an instance instead of a class, in the + case of a class exception, or it may be a subclass of the expected exception.) + + +.. c:function:: int PyErr_ExceptionMatches(PyObject *exc) + + Equivalent to ``PyErr_GivenExceptionMatches(PyErr_Occurred(), exc)``. This + should only be called when an exception is actually set; a memory access + violation will occur if no exception has been raised. + + +.. c:function:: int PyErr_GivenExceptionMatches(PyObject *given, PyObject *exc) + + Return true if the *given* exception matches the exception type in *exc*. If + *exc* is a class object, this also returns true when *given* is an instance + of a subclass. If *exc* is a tuple, all exception types in the tuple (and + recursively in subtuples) are searched for a match. + + +.. c:function:: void PyErr_Fetch(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback) + + Retrieve the error indicator into three variables whose addresses are passed. + If the error indicator is not set, set all three variables to *NULL*. If it is + set, it will be cleared and you own a reference to each object retrieved. The + value and traceback object may be *NULL* even when the type object is not. + + .. note:: + + This function is normally only used by code that needs to catch exceptions or + by code that needs to save and restore the error indicator temporarily, e.g.:: + + { + PyObject **type, **value, **traceback; + PyErr_Fetch(&type, &value, &traceback); + + /* ... code that might produce other errors ... */ + + PyErr_Restore(type, value, traceback); + } + + +.. c:function:: void PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback) + + Set the error indicator from the three objects. If the error indicator is + already set, it is cleared first. If the objects are *NULL*, the error + indicator is cleared. Do not pass a *NULL* type and non-*NULL* value or + traceback. The exception type should be a class. Do not pass an invalid + exception type or value. (Violating these rules will cause subtle problems + later.) This call takes away a reference to each object: you must own a + reference to each object before the call and after the call you no longer own + these references. (If you don't understand this, don't use this function. I + warned you.) + + .. note:: + + This function is normally only used by code that needs to save and restore the + error indicator temporarily. Use :c:func:`PyErr_Fetch` to save the current + error indicator. + + +.. c:function:: void PyErr_NormalizeException(PyObject**exc, PyObject**val, PyObject**tb) + + Under certain circumstances, the values returned by :c:func:`PyErr_Fetch` below + can be "unnormalized", meaning that ``*exc`` is a class object but ``*val`` is + not an instance of the same class. This function can be used to instantiate + the class in that case. If the values are already normalized, nothing happens. + The delayed normalization is implemented to improve performance. + + .. note:: + + This function *does not* implicitly set the ``__traceback__`` + attribute on the exception value. If setting the traceback + appropriately is desired, the following additional snippet is needed:: + + if (tb != NULL) { + PyException_SetTraceback(val, tb); + } + + +.. c:function:: void PyErr_GetExcInfo(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback) + + Retrieve the exception info, as known from ``sys.exc_info()``. This refers + to an exception that was *already caught*, not to an exception that was + freshly raised. Returns new references for the three objects, any of which + may be *NULL*. Does not modify the exception info state. + + .. note:: + + This function is not normally used by code that wants to handle exceptions. + Rather, it can be used when code needs to save and restore the exception + state temporarily. Use :c:func:`PyErr_SetExcInfo` to restore or clear the + exception state. + + .. versionadded:: 3.3 + + +.. c:function:: void PyErr_SetExcInfo(PyObject *type, PyObject *value, PyObject *traceback) + + Set the exception info, as known from ``sys.exc_info()``. This refers + to an exception that was *already caught*, not to an exception that was + freshly raised. This function steals the references of the arguments. + To clear the exception state, pass *NULL* for all three arguments. + For general rules about the three arguments, see :c:func:`PyErr_Restore`. + + .. note:: + + This function is not normally used by code that wants to handle exceptions. + Rather, it can be used when code needs to save and restore the exception + state temporarily. Use :c:func:`PyErr_GetExcInfo` to read the exception + state. + + .. versionadded:: 3.3 + + +Signal Handling +=============== + + .. c:function:: int PyErr_CheckSignals() .. index:: @@ -422,15 +500,23 @@ in various ways. There is a separate error indicator for each thread. .. c:function:: int PySignal_SetWakeupFd(int fd) - This utility function specifies a file descriptor to which a ``'\0'`` byte will - be written whenever a signal is received. It returns the previous such file - descriptor. The value ``-1`` disables the feature; this is the initial state. + This utility function specifies a file descriptor to which the signal number + is written as a single byte whenever a signal is received. *fd* must be + non-blocking. It returns the previous such file descriptor. + + The value ``-1`` disables the feature; this is the initial state. This is equivalent to :func:`signal.set_wakeup_fd` in Python, but without any error checking. *fd* should be a valid file descriptor. The function should only be called from the main thread. + .. versionchanged:: 3.5 + On Windows, the function now also supports socket handles. + -.. c:function:: PyObject* PyErr_NewException(char *name, PyObject *base, PyObject *dict) +Exception Classes +================= + +.. c:function:: PyObject* PyErr_NewException(const char *name, PyObject *base, PyObject *dict) This utility function creates and returns a new exception class. The *name* argument must be the name of the new exception, a C string of the form @@ -445,7 +531,7 @@ in various ways. There is a separate error indicator for each thread. argument can be used to specify a dictionary of class variables and methods. -.. c:function:: PyObject* PyErr_NewExceptionWithDoc(char *name, char *doc, PyObject *base, PyObject *dict) +.. c:function:: PyObject* PyErr_NewExceptionWithDoc(const char *name, const char *doc, PyObject *base, PyObject *dict) Same as :c:func:`PyErr_NewException`, except that the new exception class can easily be given a docstring: If *doc* is non-*NULL*, it will be used as the @@ -454,18 +540,6 @@ in various ways. There is a separate error indicator for each thread. .. versionadded:: 3.2 -.. c:function:: void PyErr_WriteUnraisable(PyObject *obj) - - This utility function prints a warning message to ``sys.stderr`` when an - exception has been set but it is impossible for the interpreter to actually - raise the exception. It is used, for example, when an exception occurs in an - :meth:`__del__` method. - - The function is called with a single argument *obj* that identifies the context - in which the unraisable exception occurred. The repr of *obj* will be printed in - the warning message. - - Exception Objects ================= @@ -504,11 +578,11 @@ Exception Objects reference, as accessible from Python through :attr:`__cause__`. -.. c:function:: void PyException_SetCause(PyObject *ex, PyObject *ctx) +.. c:function:: void PyException_SetCause(PyObject *ex, PyObject *cause) - Set the cause associated with the exception to *ctx*. Use *NULL* to clear - it. There is no type check to make sure that *ctx* is either an exception - instance or :const:`None`. This steals a reference to *ctx*. + Set the cause associated with the exception to *cause*. Use *NULL* to clear + it. There is no type check to make sure that *cause* is either an exception + instance or :const:`None`. This steals a reference to *cause*. :attr:`__suppress_context__` is implicitly set to ``True`` by this function. @@ -600,7 +674,7 @@ level, both in the core and in extension modules. They are needed if the recursive code does not necessarily invoke Python code (which tracks its recursion depth automatically). -.. c:function:: int Py_EnterRecursiveCall(char *where) +.. c:function:: int Py_EnterRecursiveCall(const char *where) Marks a point where a recursive C-level call is about to be performed. @@ -609,12 +683,12 @@ recursion depth automatically). sets a :exc:`MemoryError` and returns a nonzero value. The function then checks if the recursion limit is reached. If this is the - case, a :exc:`RuntimeError` is set and a nonzero value is returned. + case, a :exc:`RecursionError` is set and a nonzero value is returned. Otherwise, zero is returned. *where* should be a string such as ``" in instance check"`` to be - concatenated to the :exc:`RuntimeError` message caused by the recursion depth - limit. + concatenated to the :exc:`RecursionError` message caused by the recursion + depth limit. .. c:function:: void Py_LeaveRecursiveCall() @@ -726,6 +800,8 @@ the variables: +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_ProcessLookupError` | :exc:`ProcessLookupError` | | +-----------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_RecursionError` | :exc:`RecursionError` | | ++-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_ReferenceError` | :exc:`ReferenceError` | \(2) | +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_RuntimeError` | :exc:`RuntimeError` | | @@ -755,6 +831,9 @@ the variables: :c:data:`PyExc_PermissionError`, :c:data:`PyExc_ProcessLookupError` and :c:data:`PyExc_TimeoutError` were introduced following :pep:`3151`. +.. versionadded:: 3.5 + :c:data:`PyExc_RecursionError`. + These are compatibility aliases to :c:data:`PyExc_OSError`: @@ -803,6 +882,7 @@ These are compatibility aliases to :c:data:`PyExc_OSError`: single: PyExc_OverflowError single: PyExc_PermissionError single: PyExc_ProcessLookupError + single: PyExc_RecursionError single: PyExc_ReferenceError single: PyExc_RuntimeError single: PyExc_SyntaxError diff --git a/Doc/c-api/gen.rst b/Doc/c-api/gen.rst index 33cd27a5aa6c..1efbae4fcba0 100644 --- a/Doc/c-api/gen.rst +++ b/Doc/c-api/gen.rst @@ -7,7 +7,7 @@ Generator Objects Generator objects are what Python uses to implement generator iterators. They are normally created by iterating over a function that yields values, rather -than explicitly calling :c:func:`PyGen_New`. +than explicitly calling :c:func:`PyGen_New` or :c:func:`PyGen_NewWithQualName`. .. c:type:: PyGenObject @@ -17,22 +17,28 @@ than explicitly calling :c:func:`PyGen_New`. .. c:var:: PyTypeObject PyGen_Type - The type object corresponding to generator objects + The type object corresponding to generator objects. -.. c:function:: int PyGen_Check(ob) +.. c:function:: int PyGen_Check(PyObject *ob) Return true if *ob* is a generator object; *ob* must not be *NULL*. -.. c:function:: int PyGen_CheckExact(ob) +.. c:function:: int PyGen_CheckExact(PyObject *ob) - Return true if *ob*'s type is *PyGen_Type* is a generator object; *ob* must not - be *NULL*. + Return true if *ob*'s type is *PyGen_Type*; *ob* must not be *NULL*. .. c:function:: PyObject* PyGen_New(PyFrameObject *frame) - Create and return a new generator object based on the *frame* object. A - reference to *frame* is stolen by this function. The parameter must not be + Create and return a new generator object based on the *frame* object. + A reference to *frame* is stolen by this function. The argument must not be *NULL*. + +.. c:function:: PyObject* PyGen_NewWithQualName(PyFrameObject *frame, PyObject *name, PyObject *qualname) + + Create and return a new generator object based on the *frame* object, + with ``__name__`` and ``__qualname__`` set to *name* and *qualname*. + A reference to *frame* is stolen by this function. The *frame* argument + must not be *NULL*. diff --git a/Doc/c-api/import.rst b/Doc/c-api/import.rst index 6cd2b8bea0e1..bf1b49577e4c 100644 --- a/Doc/c-api/import.rst +++ b/Doc/c-api/import.rst @@ -39,7 +39,7 @@ Importing Modules behaviour isn't needed anymore. -.. c:function:: PyObject* PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist) +.. c:function:: PyObject* PyImport_ImportModuleEx(const char *name, PyObject *globals, PyObject *locals, PyObject *fromlist) .. index:: builtin: __import__ @@ -70,7 +70,7 @@ Importing Modules .. versionadded:: 3.3 -.. c:function:: PyObject* PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level) +.. c:function:: PyObject* PyImport_ImportModuleLevel(const char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level) Similar to :c:func:`PyImport_ImportModuleLevelObject`, but the name is an UTF-8 encoded string instead of a Unicode object. @@ -132,8 +132,14 @@ Importing Modules such modules have no way to know that the module object is an unknown (and probably damaged with respect to the module author's intents) state. + The module's :attr:`__spec__` and :attr:`__loader__` will be set, if + not set already, with the appropriate values. The spec's loader will + be set to the module's ``__loader__`` (if set) and to an instance of + :class:`SourceFileLoader` otherwise. + The module's :attr:`__file__` attribute will be set to the code object's - :c:member:`co_filename`. + :c:member:`co_filename`. If applicable, :attr:`__cached__` will also + be set. This function will reload the module if it was already imported. See :c:func:`PyImport_ReloadModule` for the intended way to reload a module. @@ -177,9 +183,9 @@ Importing Modules .. c:function:: long PyImport_GetMagicNumber() - Return the magic number for Python bytecode files (a.k.a. :file:`.pyc` and - :file:`.pyo` files). The magic number should be present in the first four bytes - of the bytecode file, in little-endian byte order. Returns -1 on error. + Return the magic number for Python bytecode files (a.k.a. :file:`.pyc` file). + The magic number should be present in the first four bytes of the bytecode + file, in little-endian byte order. Returns -1 on error. .. versionchanged:: 3.3 Return value of -1 upon failure. @@ -245,6 +251,9 @@ Importing Modules .. versionadded:: 3.3 + .. versionchanged:: 3.4 + The ``__file__`` attribute is no longer set on the module. + .. c:function:: int PyImport_ImportFrozenModule(const char *name) diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 6439d7f11de3..81823bf38305 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -86,7 +86,7 @@ Process-wide parameters ======================= -.. c:function:: int Py_SetStandardStreamEncoding(char *encoding, char *errors) +.. c:function:: int Py_SetStandardStreamEncoding(const char *encoding, const char *errors) .. index:: single: Py_Initialize() @@ -134,6 +134,9 @@ Process-wide parameters change for the duration of the program's execution. No code in the Python interpreter will change the contents of this storage. + Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a + :c:type:`wchar_*` string. + .. c:function:: wchar* Py_GetProgramName() @@ -236,13 +239,21 @@ Process-wide parameters :c:func:`Py_Initialize`, then :c:func:`Py_GetPath` won't attempt to compute a default search path but uses the one provided instead. This is useful if Python is embedded by an application that has full knowledge of the location - of all modules. The path components should be separated by semicolons. + of all modules. The path components should be separated by the platform + dependent delimiter character, which is ``':'`` on Unix and Mac OS X, ``';'`` + on Windows. This also causes :data:`sys.executable` to be set only to the raw program name (see :c:func:`Py_SetProgramName`) and for :data:`sys.prefix` and :data:`sys.exec_prefix` to be empty. It is up to the caller to modify these if required after calling :c:func:`Py_Initialize`. + Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a + :c:type:`wchar_*` string. + + The path argument is copied internally, so the caller may free it after the + call completes. + .. c:function:: const char* Py_GetVersion() @@ -339,6 +350,9 @@ Process-wide parameters :data:`sys.path`, which is the same as prepending the current working directory (``"."``). + Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a + :c:type:`wchar_*` string. + .. note:: It is recommended that applications embedding the Python interpreter for purposes other than executing a single script pass 0 as *updatepath*, @@ -363,6 +377,9 @@ Process-wide parameters to 1 unless the :program:`python` interpreter was started with the :option:`-I`. + Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a + :c:type:`wchar_*` string. + .. versionchanged:: 3.4 The *updatepath* value depends on :option:`-I`. @@ -377,6 +394,9 @@ Process-wide parameters execution. No code in the Python interpreter will change the contents of this storage. + Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a + :c:type:`wchar_*` string. + .. c:function:: w_char* Py_GetPythonHome() @@ -582,6 +602,7 @@ code, or when embedding the Python interpreter: .. index:: module: _thread .. note:: + When only the main thread exists, no GIL operations are needed. This is a common situation (most Python programs do not use threads), and the lock operations slow the interpreter down a bit. Therefore, the lock is not @@ -852,6 +873,8 @@ been created. instead. +.. _sub-interpreter-support: + Sub-interpreter support ======================= @@ -1176,7 +1199,7 @@ These functions are only intended to be used by advanced debugging tools. .. c:function:: PyThreadState * PyInterpreterState_ThreadHead(PyInterpreterState *interp) - Return the a pointer to the first :c:type:`PyThreadState` object in the list of + Return the pointer to the first :c:type:`PyThreadState` object in the list of threads associated with the interpreter *interp*. diff --git a/Doc/c-api/mapping.rst b/Doc/c-api/mapping.rst index 2803fd044e27..e34104708ca6 100644 --- a/Doc/c-api/mapping.rst +++ b/Doc/c-api/mapping.rst @@ -34,7 +34,7 @@ Mapping Protocol failure. This is equivalent to the Python statement ``del o[key]``. -.. c:function:: int PyMapping_HasKeyString(PyObject *o, char *key) +.. c:function:: int PyMapping_HasKeyString(PyObject *o, const char *key) On success, return ``1`` if the mapping object has the key *key* and ``0`` otherwise. This is equivalent to the Python expression ``key in o``. diff --git a/Doc/c-api/marshal.rst b/Doc/c-api/marshal.rst index da402a808624..a6d0f4688d1b 100644 --- a/Doc/c-api/marshal.rst +++ b/Doc/c-api/marshal.rst @@ -53,6 +53,8 @@ written using these routines? for reading. Only a 32-bit value can be read in using this function, regardless of the native size of :c:type:`long`. + On error, raise an exception and return ``-1``. + .. c:function:: int PyMarshal_ReadShortFromFile(FILE *file) @@ -60,11 +62,15 @@ written using these routines? for reading. Only a 16-bit value can be read in using this function, regardless of the native size of :c:type:`short`. + On error, raise an exception and return ``-1``. + .. c:function:: PyObject* PyMarshal_ReadObjectFromFile(FILE *file) Return a Python object from the data stream in a :c:type:`FILE\*` opened for - reading. On error, sets the appropriate exception (:exc:`EOFError` or + reading. + + On error, sets the appropriate exception (:exc:`EOFError` or :exc:`TypeError`) and returns *NULL*. @@ -76,14 +82,17 @@ written using these routines? aggressively load file data into memory so that the de-serialization can operate from data in memory rather than reading a byte at a time from the file. Only use these variant if you are certain that you won't be reading - anything else from the file. On error, sets the appropriate exception - (:exc:`EOFError` or :exc:`TypeError`) and returns *NULL*. + anything else from the file. + On error, sets the appropriate exception (:exc:`EOFError` or + :exc:`TypeError`) and returns *NULL*. -.. c:function:: PyObject* PyMarshal_ReadObjectFromString(char *string, Py_ssize_t len) + +.. c:function:: PyObject* PyMarshal_ReadObjectFromString(const char *string, Py_ssize_t len) Return a Python object from the data stream in a character buffer - containing *len* bytes pointed to by *string*. On error, sets the - appropriate exception (:exc:`EOFError` or :exc:`TypeError`) and returns - *NULL*. + containing *len* bytes pointed to by *string*. + + On error, sets the appropriate exception (:exc:`EOFError` or + :exc:`TypeError`) and returns *NULL*. diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index a82e1c2f2c50..7339006b5e71 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -92,8 +92,8 @@ functions are thread-safe, the :term:`GIL ` does not need to be held. The default raw memory block allocator uses the following functions: -:c:func:`malloc`, :c:func:`realloc` and :c:func:`free`; call ``malloc(1)`` when -requesting zero bytes. +:c:func:`malloc`, :c:func:`calloc`, :c:func:`realloc` and :c:func:`free`; call +``malloc(1)`` (or ``calloc(1, 1)``) when requesting zero bytes. .. versionadded:: 3.4 @@ -106,6 +106,17 @@ requesting zero bytes. been initialized in any way. +.. c:function:: void* PyMem_RawCalloc(size_t nelem, size_t elsize) + + Allocates *nelem* elements each whose size in bytes is *elsize* and returns + a pointer of type :c:type:`void\*` to the allocated memory, or *NULL* if the + request fails. The memory is initialized to zeros. Requesting zero elements + or elements of size zero bytes returns a distinct non-*NULL* pointer if + possible, as if ``PyMem_RawCalloc(1, 1)`` had been called instead. + + .. versionadded:: 3.5 + + .. c:function:: void* PyMem_RawRealloc(void *p, size_t n) Resizes the memory block pointed to by *p* to *n* bytes. The contents will @@ -136,8 +147,8 @@ behavior when requesting zero bytes, are available for allocating and releasing memory from the Python heap. The default memory block allocator uses the following functions: -:c:func:`malloc`, :c:func:`realloc` and :c:func:`free`; call ``malloc(1)`` when -requesting zero bytes. +:c:func:`malloc`, :c:func:`calloc`, :c:func:`realloc` and :c:func:`free`; call +``malloc(1)`` (or ``calloc(1, 1)``) when requesting zero bytes. .. warning:: @@ -152,6 +163,17 @@ requesting zero bytes. been called instead. The memory will not have been initialized in any way. +.. c:function:: void* PyMem_Calloc(size_t nelem, size_t elsize) + + Allocates *nelem* elements each whose size in bytes is *elsize* and returns + a pointer of type :c:type:`void\*` to the allocated memory, or *NULL* if the + request fails. The memory is initialized to zeros. Requesting zero elements + or elements of size zero bytes returns a distinct non-*NULL* pointer if + possible, as if ``PyMem_Calloc(1, 1)`` had been called instead. + + .. versionadded:: 3.5 + + .. c:function:: void* PyMem_Realloc(void *p, size_t n) Resizes the memory block pointed to by *p* to *n* bytes. The contents will be @@ -210,7 +232,7 @@ Customize Memory Allocators .. versionadded:: 3.4 -.. c:type:: PyMemAllocator +.. c:type:: PyMemAllocatorEx Structure used to describe a memory block allocator. The structure has four fields: @@ -222,11 +244,19 @@ Customize Memory Allocators +----------------------------------------------------------+---------------------------------------+ | ``void* malloc(void *ctx, size_t size)`` | allocate a memory block | +----------------------------------------------------------+---------------------------------------+ + | ``void* calloc(void *ctx, size_t nelem, size_t elsize)`` | allocate a memory block initialized | + | | with zeros | + +----------------------------------------------------------+---------------------------------------+ | ``void* realloc(void *ctx, void *ptr, size_t new_size)`` | allocate or resize a memory block | +----------------------------------------------------------+---------------------------------------+ | ``void free(void *ctx, void *ptr)`` | free a memory block | +----------------------------------------------------------+---------------------------------------+ + .. versionchanged:: 3.5 + The :c:type:`PyMemAllocator` structure was renamed to + :c:type:`PyMemAllocatorEx` and a new ``calloc`` field was added. + + .. c:type:: PyMemAllocatorDomain Enum used to identify an allocator domain. Domains: @@ -239,12 +269,12 @@ Customize Memory Allocators :c:func:`PyObject_Realloc` and :c:func:`PyObject_Free` -.. c:function:: void PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocator *allocator) +.. c:function:: void PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) Get the memory block allocator of the specified domain. -.. c:function:: void PyMem_SetAllocator(PyMemAllocatorDomain domain, PyMemAllocator *allocator) +.. c:function:: void PyMem_SetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) Set the memory block allocator of the specified domain. @@ -272,7 +302,7 @@ Customize Memory Allocators :c:func:`PyObject_Free` Newly allocated memory is filled with the byte ``0xCB``, freed memory is - filled with the byte ``0xDB``. Additionnal checks: + filled with the byte ``0xDB``. Additional checks: - detect API violations, ex: :c:func:`PyObject_Free` called on a buffer allocated by :c:func:`PyMem_Malloc` diff --git a/Doc/c-api/memoryview.rst b/Doc/c-api/memoryview.rst index 5e50977cbee3..9f6bfd751ade 100644 --- a/Doc/c-api/memoryview.rst +++ b/Doc/c-api/memoryview.rst @@ -35,7 +35,7 @@ any other object. .. c:function:: PyObject *PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char order) - Create a memoryview object to a contiguous chunk of memory (in either + Create a memoryview object to a :term:`contiguous` chunk of memory (in either 'C' or 'F'ortran *order*) from an object that defines the buffer interface. If memory is contiguous, the memoryview object points to the original memory. Otherwise, a copy is made and the memoryview points to a diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst index 26c4384f856a..ef778ccaedbb 100644 --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -7,8 +7,6 @@ Module Objects .. index:: object: module -There are only a few functions special to module objects. - .. c:var:: PyTypeObject PyModule_Type @@ -84,6 +82,18 @@ There are only a few functions special to module objects. Similar to :c:func:`PyModule_GetNameObject` but return the name encoded to ``'utf-8'``. +.. c:function:: void* PyModule_GetState(PyObject *module) + + Return the "state" of the module, that is, a pointer to the block of memory + allocated at module creation time, or *NULL*. See + :c:member:`PyModuleDef.m_size`. + + +.. c:function:: PyModuleDef* PyModule_GetDef(PyObject *module) + + Return a pointer to the :c:type:`PyModuleDef` struct from which the module was + created, or *NULL* if the module wasn't created from a definition. + .. c:function:: PyObject* PyModule_GetFilenameObject(PyObject *module) @@ -109,55 +119,109 @@ There are only a few functions special to module objects. unencodable filenames, use :c:func:`PyModule_GetFilenameObject` instead. -.. c:function:: void* PyModule_GetState(PyObject *module) +.. _initializing-modules: - Return the "state" of the module, that is, a pointer to the block of memory - allocated at module creation time, or *NULL*. See - :c:member:`PyModuleDef.m_size`. +Initializing C modules +^^^^^^^^^^^^^^^^^^^^^^ +Modules objects are usually created from extension modules (shared libraries +which export an initialization function), or compiled-in modules +(where the initialization function is added using :c:func:`PyImport_AppendInittab`). +See :ref:`building` or :ref:`extending-with-embedding` for details. -.. c:function:: PyModuleDef* PyModule_GetDef(PyObject *module) +The initialization function can either pass pass a module definition instance +to :c:func:`PyModule_Create`, and return the resulting module object, +or request "multi-phase initialization" by returning the definition struct itself. - Return a pointer to the :c:type:`PyModuleDef` struct from which the module was - created, or *NULL* if the module wasn't created with - :c:func:`PyModule_Create`.i +.. c:type:: PyModuleDef -.. c:function:: PyObject* PyState_FindModule(PyModuleDef *def) + The module definition struct, which holds all information needed to create + a module object. There is usually only one statically initialized variable + of this type for each module. - Returns the module object that was created from *def* for the current interpreter. - This method requires that the module object has been attached to the interpreter state with - :c:func:`PyState_AddModule` beforehand. In case the corresponding module object is not - found or has not been attached to the interpreter state yet, it returns NULL. + .. c:member:: PyModuleDef_Base m_base -.. c:function:: int PyState_AddModule(PyObject *module, PyModuleDef *def) + Always initialize this member to :const:`PyModuleDef_HEAD_INIT`. - Attaches the module object passed to the function to the interpreter state. This allows - the module object to be accessible via - :c:func:`PyState_FindModule`. + .. c:member:: char* m_name - .. versionadded:: 3.3 + Name for the new module. -.. c:function:: int PyState_RemoveModule(PyModuleDef *def) + .. c:member:: char* m_doc - Removes the module object created from *def* from the interpreter state. + Docstring for the module; usually a docstring variable created with + :c:func:`PyDoc_STRVAR` is used. - .. versionadded:: 3.3 + .. c:member:: Py_ssize_t m_size -Initializing C modules -^^^^^^^^^^^^^^^^^^^^^^ + Module state may be kept in a per-module memory area that can be + retrieved with :c:func:`PyModule_GetState`, rather than in static globals. + This makes modules safe for use in multiple sub-interpreters. + + This memory area is allocated based on *m_size* on module creation, + and freed when the module object is deallocated, after the + :c:member:`m_free` function has been called, if present. + + Setting ``m_size`` to ``-1`` means that the module does not support + sub-interpreters, because it has global state. -These functions are usually used in the module initialization function. + Setting it to a non-negative value means that the module can be + re-initialized and specifies the additional amount of memory it requires + for its state. Non-negative ``m_size`` is required for multi-phase + initialization. -.. c:function:: PyObject* PyModule_Create(PyModuleDef *module) + See :PEP:`3121` for more details. + + .. c:member:: PyMethodDef* m_methods - Create a new module object, given the definition in *module*. This behaves + A pointer to a table of module-level functions, described by + :c:type:`PyMethodDef` values. Can be *NULL* if no functions are present. + + .. c:member:: PyModuleDef_Slot* m_slots + + An array of slot definitions for multi-phase initialization, terminated by + a ``{0, NULL}`` entry. + When using single-phase initialization, *m_slots* must be *NULL*. + + .. versionchanged:: 3.5 + + Prior to version 3.5, this member was always set to *NULL*, + and was defined as: + + .. c:member:: inquiry m_reload + + .. c:member:: traverseproc m_traverse + + A traversal function to call during GC traversal of the module object, or + *NULL* if not needed. + + .. c:member:: inquiry m_clear + + A clear function to call during GC clearing of the module object, or + *NULL* if not needed. + + .. c:member:: freefunc m_free + + A function to call during deallocation of the module object, or *NULL* if + not needed. + +Single-phase initialization +........................... + +The module initialization function may create and return the module object +directly. This is referred to as "single-phase initialization", and uses one +of the following two module creation functions: + +.. c:function:: PyObject* PyModule_Create(PyModuleDef *def) + + Create a new module object, given the definition in *def*. This behaves like :c:func:`PyModule_Create2` with *module_api_version* set to :const:`PYTHON_API_VERSION`. -.. c:function:: PyObject* PyModule_Create2(PyModuleDef *module, int module_api_version) +.. c:function:: PyObject* PyModule_Create2(PyModuleDef *def, int module_api_version) - Create a new module object, given the definition in *module*, assuming the + Create a new module object, given the definition in *def*, assuming the API version *module_api_version*. If that version does not match the version of the running interpreter, a :exc:`RuntimeWarning` is emitted. @@ -166,69 +230,179 @@ These functions are usually used in the module initialization function. Most uses of this function should be using :c:func:`PyModule_Create` instead; only use this if you are sure you need it. +Before it is returned from in the initialization function, the resulting module +object is typically populated using functions like :c:func:`PyModule_AddObject`. -.. c:type:: PyModuleDef +.. _multi-phase-initialization: - This struct holds all information that is needed to create a module object. - There is usually only one static variable of that type for each module, which - is statically initialized and then passed to :c:func:`PyModule_Create` in the - module initialization function. +Multi-phase initialization +.......................... - .. c:member:: PyModuleDef_Base m_base +An alternate way to specify extensions is to request "multi-phase initialization". +Extension modules created this way behave more like Python modules: the +initialization is split between the *creation phase*, when the module object +is created, and the *execution phase*, when it is populated. +The distinction is similar to the :py:meth:`__new__` and :py:meth:`__init__` methods +of classes. - Always initialize this member to :const:`PyModuleDef_HEAD_INIT`. +Unlike modules created using single-phase initialization, these modules are not +singletons: if the *sys.modules* entry is removed and the module is re-imported, +a new module object is created, and the old module is subject to normal garbage +collection -- as with Python modules. +By default, multiple modules created from the same definition should be +independent: changes to one should not affect the others. +This means that all state should be specific to the module object (using e.g. +using :c:func:`PyModule_GetState`), or its contents (such as the module's +:attr:`__dict__` or individual classes created with :c:func:`PyType_FromSpec`). - .. c:member:: char* m_name +All modules created using multi-phase initialization are expected to support +:ref:`sub-interpreters `. Making sure multiple modules +are independent is typically enough to achieve this. - Name for the new module. +To request multi-phase initialization, the initialization function +(PyInit_modulename) returns a :c:type:`PyModuleDef` instance with non-empty +:c:member:`~PyModuleDef.m_slots`. Before it is returned, the ``PyModuleDef`` +instance must be initialized with the following function: - .. c:member:: char* m_doc +.. c:function:: PyObject* PyModuleDef_Init(PyModuleDef *def) - Docstring for the module; usually a docstring variable created with - :c:func:`PyDoc_STRVAR` is used. + Ensures a module definition is a properly initialized Python object that + correctly reports its type and reference count. - .. c:member:: Py_ssize_t m_size + Returns *def* cast to ``PyObject*``, or *NULL* if an error occurred. - Some modules allow re-initialization (calling their ``PyInit_*`` function - more than once). These modules should keep their state in a per-module - memory area that can be retrieved with :c:func:`PyModule_GetState`. + .. versionadded:: 3.5 - This memory should be used, rather than static globals, to hold per-module - state, since it is then safe for use in multiple sub-interpreters. It is - freed when the module object is deallocated, after the :c:member:`m_free` - function has been called, if present. +The *m_slots* member of the module definition must point to an array of +``PyModuleDef_Slot`` structures: - Setting ``m_size`` to ``-1`` means that the module can not be - re-initialized because it has global state. Setting it to a non-negative - value means that the module can be re-initialized and specifies the - additional amount of memory it requires for its state. +.. c:type:: PyModuleDef_Slot - See :PEP:`3121` for more details. + .. c:member:: int slot - .. c:member:: PyMethodDef* m_methods + A slot ID, chosen from the available values explained below. - A pointer to a table of module-level functions, described by - :c:type:`PyMethodDef` values. Can be *NULL* if no functions are present. + .. c:member:: void* value - .. c:member:: inquiry m_reload + Value of the slot, whose meaning depends on the slot ID. - Currently unused, should be *NULL*. + .. versionadded:: 3.5 - .. c:member:: traverseproc m_traverse +The *m_slots* array must be terminated by a slot with id 0. - A traversal function to call during GC traversal of the module object, or - *NULL* if not needed. +The available slot types are: - .. c:member:: inquiry m_clear +.. c:var:: Py_mod_create - A clear function to call during GC clearing of the module object, or - *NULL* if not needed. + Specifies a function that is called to create the module object itself. + The *value* pointer of this slot must point to a function of the signature: - .. c:member:: freefunc m_free + .. c:function:: PyObject* create_module(PyObject *spec, PyModuleDef *def) - A function to call during deallocation of the module object, or *NULL* if - not needed. + The function receives a :py:class:`~importlib.machinery.ModuleSpec` + instance, as defined in :PEP:`451`, and the module definition. + It should return a new module object, or set an error + and return *NULL*. + + This function should be kept minimal. In particular, it should not + call arbitrary Python code, as trying to import the same module again may + result in an infinite loop. + + Multiple ``Py_mod_create`` slots may not be specified in one module + definition. + + If ``Py_mod_create`` is not specified, the import machinery will create + a normal module object using :c:func:`PyModule_New`. The name is taken from + *spec*, not the definition, to allow extension modules to dynamically adjust + to their place in the module hierarchy and be imported under different + names through symlinks, all while sharing a single module definition. + + There is no requirement for the returned object to be an instance of + :c:type:`PyModule_Type`. Any type can be used, as long as it supports + setting and getting import-related attributes. + However, only ``PyModule_Type`` instances may be returned if the + ``PyModuleDef`` has non-*NULL* ``m_methods``, ``m_traverse``, ``m_clear``, + ``m_free``; non-zero ``m_size``; or slots other than ``Py_mod_create``. + +.. c:var:: Py_mod_exec + + Specifies a function that is called to *execute* the module. + This is equivalent to executing the code of a Python module: typically, + this function adds classes and constants to the module. + The signature of the function is: + + .. c:function:: int exec_module(PyObject* module) + + If multiple ``Py_mod_exec`` slots are specified, they are processed in the + order they appear in the *m_slots* array. + +See :PEP:`489` for more details on multi-phase initialization. + +Low-level module creation functions +................................... + +The following functions are called under the hood when using multi-phase +initialization. They can be used directly, for example when creating module +objects dynamically. Note that both ``PyModule_FromDefAndSpec`` and +``PyModule_ExecDef`` must be called to fully initialize a module. + +.. c:function:: PyObject * PyModule_FromDefAndSpec(PyModuleDef *def, PyObject *spec) + + Create a new module object, given the definition in *module* and the + ModuleSpec *spec*. This behaves like :c:func:`PyModule_FromDefAndSpec2` + with *module_api_version* set to :const:`PYTHON_API_VERSION`. + + .. versionadded:: 3.5 + +.. c:function:: PyObject * PyModule_FromDefAndSpec2(PyModuleDef *def, PyObject *spec, int module_api_version) + + Create a new module object, given the definition in *module* and the + ModuleSpec *spec*, assuming the API version *module_api_version*. + If that version does not match the version of the running interpreter, + a :exc:`RuntimeWarning` is emitted. + + .. note:: + Most uses of this function should be using :c:func:`PyModule_FromDefAndSpec` + instead; only use this if you are sure you need it. + + .. versionadded:: 3.5 + +.. c:function:: int PyModule_ExecDef(PyObject *module, PyModuleDef *def) + + Process any execution slots (:c:data:`Py_mod_exec`) given in *def*. + + .. versionadded:: 3.5 + +.. c:function:: int PyModule_SetDocString(PyObject *module, const char *docstring) + + Set the docstring for *module* to *docstring*. + This function is called automatically when creating a module from + ``PyModuleDef``, using either ``PyModule_Create`` or + ``PyModule_FromDefAndSpec``. + + .. versionadded:: 3.5 + +.. c:function:: int PyModule_AddFunctions(PyObject *module, PyMethodDef *functions) + + Add the functions from the *NULL* terminated *functions* array to *module*. + Refer to the :c:type:`PyMethodDef` documentation for details on individual + entries (due to the lack of a shared module namespace, module level + "functions" implemented in C typically receive the module as their first + parameter, making them similar to instance methods on Python classes). + This function is called automatically when creating a module from + ``PyModuleDef``, using either ``PyModule_Create`` or + ``PyModule_FromDefAndSpec``. + + .. versionadded:: 3.5 + +Support functions +................. + +The module initialization function (if using single phase initialization) or +a function called from a module execution slot (if using multi-phase +initialization), can use the following functions to help initialize the module +state: .. c:function:: int PyModule_AddObject(PyObject *module, const char *name, PyObject *value) @@ -236,7 +410,6 @@ These functions are usually used in the module initialization function. be used from the module's initialization function. This steals a reference to *value*. Return ``-1`` on error, ``0`` on success. - .. c:function:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value) Add an integer constant to *module* as *name*. This convenience function can be @@ -248,7 +421,7 @@ These functions are usually used in the module initialization function. Add a string constant to *module* as *name*. This convenience function can be used from the module's initialization function. The string *value* must be - null-terminated. Return ``-1`` on error, ``0`` on success. + *NULL*-terminated. Return ``-1`` on error, ``0`` on success. .. c:function:: int PyModule_AddIntMacro(PyObject *module, macro) @@ -262,3 +435,36 @@ These functions are usually used in the module initialization function. .. c:function:: int PyModule_AddStringMacro(PyObject *module, macro) Add a string constant to *module*. + + +Module lookup +^^^^^^^^^^^^^ + +Single-phase initialization creates singleton modules that can be looked up +in the context of the current interpreter. This allows the module object to be +retrieved later with only a reference to the module definition. + +These functions will not work on modules created using multi-phase initialization, +since multiple such modules can be created from a single definition. + +.. c:function:: PyObject* PyState_FindModule(PyModuleDef *def) + + Returns the module object that was created from *def* for the current interpreter. + This method requires that the module object has been attached to the interpreter state with + :c:func:`PyState_AddModule` beforehand. In case the corresponding module object is not + found or has not been attached to the interpreter state yet, it returns *NULL*. + +.. c:function:: int PyState_AddModule(PyObject *module, PyModuleDef *def) + + Attaches the module object passed to the function to the interpreter state. This allows + the module object to be accessible via :c:func:`PyState_FindModule`. + + Only effective on modules created using single-phase initialization. + + .. versionadded:: 3.3 + +.. c:function:: int PyState_RemoveModule(PyModuleDef *def) + + Removes the module object created from *def* from the interpreter state. + + .. versionadded:: 3.3 diff --git a/Doc/c-api/number.rst b/Doc/c-api/number.rst index 21951c38c0df..9bcb649c9d57 100644 --- a/Doc/c-api/number.rst +++ b/Doc/c-api/number.rst @@ -30,6 +30,14 @@ Number Protocol the equivalent of the Python expression ``o1 * o2``. +.. c:function:: PyObject* PyNumber_MatrixMultiply(PyObject *o1, PyObject *o2) + + Returns the result of matrix multiplication on *o1* and *o2*, or *NULL* on + failure. This is the equivalent of the Python expression ``o1 @ o2``. + + .. versionadded:: 3.5 + + .. c:function:: PyObject* PyNumber_FloorDivide(PyObject *o1, PyObject *o2) Return the floor of *o1* divided by *o2*, or *NULL* on failure. This is @@ -146,6 +154,15 @@ Number Protocol the Python statement ``o1 *= o2``. +.. c:function:: PyObject* PyNumber_InPlaceMatrixMultiply(PyObject *o1, PyObject *o2) + + Returns the result of matrix multiplication on *o1* and *o2*, or *NULL* on + failure. The operation is done *in-place* when *o1* supports it. This is + the equivalent of the Python statement ``o1 @= o2``. + + .. versionadded:: 3.5 + + .. c:function:: PyObject* PyNumber_InPlaceFloorDivide(PyObject *o1, PyObject *o2) Returns the mathematical floor of dividing *o1* by *o2*, or *NULL* on failure. diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index be6d798f631e..97b45b12cbb2 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -101,7 +101,7 @@ Object Protocol This is the equivalent of the Python statement ``del o.attr_name``. -.. c:function:: PyObject* PyType_GenericGetDict(PyObject *o, void *context) +.. c:function:: PyObject* PyObject_GenericGetDict(PyObject *o, void *context) A generic implementation for the getter of a ``__dict__`` descriptor. It creates the dictionary if necessary. @@ -109,7 +109,7 @@ Object Protocol .. versionadded:: 3.3 -.. c:function:: int PyType_GenericSetDict(PyObject *o, void *context) +.. c:function:: int PyObject_GenericSetDict(PyObject *o, void *context) A generic implementation for the setter of a ``__dict__`` descriptor. This implementation does not allow the dictionary to be deleted. @@ -149,6 +149,9 @@ Object Protocol representation on success, *NULL* on failure. This is the equivalent of the Python expression ``repr(o)``. Called by the :func:`repr` built-in function. + .. versionchanged:: 3.4 + This function now includes a debug assertion to help ensure that it + does not silently discard an active exception. .. c:function:: PyObject* PyObject_ASCII(PyObject *o) @@ -170,6 +173,10 @@ Object Protocol Python expression ``str(o)``. Called by the :func:`str` built-in function and, therefore, by the :func:`print` function. + .. versionchanged:: 3.4 + This function now includes a debug assertion to help ensure that it + does not silently discard an active exception. + .. c:function:: PyObject* PyObject_Bytes(PyObject *o) .. index:: builtin: bytes @@ -180,40 +187,45 @@ Object Protocol a TypeError is raised when *o* is an integer instead of a zero-initialized bytes object. + +.. c:function:: int PyObject_IsSubclass(PyObject *derived, PyObject *cls) + + Return ``1`` if the class *derived* is identical to or derived from the class + *cls*, otherwise return ``0``. In case of an error, return ``-1``. + + If *cls* is a tuple, the check will be done against every entry in *cls*. + The result will be ``1`` when at least one of the checks returns ``1``, + otherwise it will be ``0``. + + If *cls* has a :meth:`~class.__subclasscheck__` method, it will be called to + determine the subclass status as described in :pep:`3119`. Otherwise, + *derived* is a subclass of *cls* if it is a direct or indirect subclass, + i.e. contained in ``cls.__mro__``. + + Normally only class objects, i.e. instances of :class:`type` or a derived + class, are considered classes. However, objects can override this by having + a :attr:`__bases__` attribute (which must be a tuple of base classes). + + .. c:function:: int PyObject_IsInstance(PyObject *inst, PyObject *cls) - Returns ``1`` if *inst* is an instance of the class *cls* or a subclass of - *cls*, or ``0`` if not. On error, returns ``-1`` and sets an exception. If - *cls* is a type object rather than a class object, :c:func:`PyObject_IsInstance` - returns ``1`` if *inst* is of type *cls*. If *cls* is a tuple, the check will - be done against every entry in *cls*. The result will be ``1`` when at least one - of the checks returns ``1``, otherwise it will be ``0``. If *inst* is not a - class instance and *cls* is neither a type object, nor a class object, nor a - tuple, *inst* must have a :attr:`~instance.__class__` attribute --- the - class relationship of the value of that attribute with *cls* will be used - to determine the result of this function. - - -Subclass determination is done in a fairly straightforward way, but includes a -wrinkle that implementors of extensions to the class system may want to be aware -of. If :class:`A` and :class:`B` are class objects, :class:`B` is a subclass of -:class:`A` if it inherits from :class:`A` either directly or indirectly. If -either is not a class object, a more general mechanism is used to determine the -class relationship of the two objects. When testing if *B* is a subclass of -*A*, if *A* is *B*, :c:func:`PyObject_IsSubclass` returns true. If *A* and *B* -are different objects, *B*'s :attr:`~class.__bases__` attribute is searched in -a depth-first fashion for *A* --- the presence of the :attr:`~class.__bases__` -attribute is considered sufficient for this determination. + Return ``1`` if *inst* is an instance of the class *cls* or a subclass of + *cls*, or ``0`` if not. On error, returns ``-1`` and sets an exception. + If *cls* is a tuple, the check will be done against every entry in *cls*. + The result will be ``1`` when at least one of the checks returns ``1``, + otherwise it will be ``0``. -.. c:function:: int PyObject_IsSubclass(PyObject *derived, PyObject *cls) + If *cls* has a :meth:`~class.__instancecheck__` method, it will be called to + determine the subclass status as described in :pep:`3119`. Otherwise, *inst* + is an instance of *cls* if its class is a subclass of *cls*. + + An instance *inst* can override what is considered its class by having a + :attr:`__class__` attribute. - Returns ``1`` if the class *derived* is identical to or derived from the class - *cls*, otherwise returns ``0``. In case of an error, returns ``-1``. If *cls* - is a tuple, the check will be done against every entry in *cls*. The result will - be ``1`` when at least one of the checks returns ``1``, otherwise it will be - ``0``. If either *derived* or *cls* is not an actual class object (or tuple), - this function uses the generic algorithm described above. + An object *cls* can override if it is considered a class, and what its base + classes are, by having a :attr:`__bases__` attribute (which must be a tuple + of base classes). .. c:function:: int PyCallable_Check(PyObject *o) @@ -350,13 +362,14 @@ attribute is considered sufficient for this determination. .. c:function:: Py_ssize_t PyObject_LengthHint(PyObject *o, Py_ssize_t default) - Return an estimated length for the object *o*. First trying to return its - actual length, then an estimate using ``__length_hint__``, and finally - returning the default value. On error ``-1`` is returned. This is the + Return an estimated length for the object *o*. First try to return its + actual length, then an estimate using :meth:`~object.__length_hint__`, and + finally return the default value. On error return ``-1``. This is the equivalent to the Python expression ``operator.length_hint(o, default)``. .. versionadded:: 3.4 + .. c:function:: PyObject* PyObject_GetItem(PyObject *o, PyObject *key) Return element of *o* corresponding to the object *key* or *NULL* on failure. diff --git a/Doc/c-api/sequence.rst b/Doc/c-api/sequence.rst index 0297ba3588b0..5960db9d42f9 100644 --- a/Doc/c-api/sequence.rst +++ b/Doc/c-api/sequence.rst @@ -107,8 +107,9 @@ Sequence Protocol .. c:function:: PyObject* PySequence_List(PyObject *o) - Return a list object with the same contents as the arbitrary sequence *o*. The - returned list is guaranteed to be new. + Return a list object with the same contents as the sequence or iterable *o*, + or *NULL* on failure. The returned list is guaranteed to be new. This is + equivalent to the Python expression ``list(o)``. .. c:function:: PyObject* PySequence_Tuple(PyObject *o) @@ -123,10 +124,10 @@ Sequence Protocol .. c:function:: PyObject* PySequence_Fast(PyObject *o, const char *m) - Returns the sequence *o* as a tuple, unless it is already a tuple or list, in - which case *o* is returned. Use :c:func:`PySequence_Fast_GET_ITEM` to access the - members of the result. Returns *NULL* on failure. If the object is not a - sequence, raises :exc:`TypeError` with *m* as the message text. + Return the sequence *o* as a list, unless it is already a tuple or list, in + which case *o* is returned. Use :c:func:`PySequence_Fast_GET_ITEM` to access + the members of the result. Returns *NULL* on failure. If the object is not + a sequence, raises :exc:`TypeError` with *m* as the message text. .. c:function:: PyObject* PySequence_Fast_GET_ITEM(PyObject *o, Py_ssize_t i) diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index bb741fb099ea..e9e8add6c1d8 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -21,53 +21,66 @@ the definition of all other Python objects. All object types are extensions of this type. This is a type which contains the information Python needs to treat a pointer to an object as an object. In a normal "release" build, it contains only the object's - reference count and a pointer to the corresponding type object. It - corresponds to the fields defined by the expansion of the ``PyObject_HEAD`` - macro. + reference count and a pointer to the corresponding type object. + Nothing is actually declared to be a :c:type:`PyObject`, but every pointer + to a Python object can be cast to a :c:type:`PyObject*`. Access to the + members must be done by using the macros :c:macro:`Py_REFCNT` and + :c:macro:`Py_TYPE`. .. c:type:: PyVarObject This is an extension of :c:type:`PyObject` that adds the :attr:`ob_size` field. This is only used for objects that have some notion of *length*. - This type does not often appear in the Python/C API. It corresponds to the - fields defined by the expansion of the ``PyObject_VAR_HEAD`` macro. + This type does not often appear in the Python/C API. + Access to the members must be done by using the macros + :c:macro:`Py_REFCNT`, :c:macro:`Py_TYPE`, and :c:macro:`Py_SIZE`. -These macros are used in the definition of :c:type:`PyObject` and -:c:type:`PyVarObject`: - -.. XXX need to document PEP 3123 changes here .. c:macro:: PyObject_HEAD - This is a macro which expands to the declarations of the fields of the - :c:type:`PyObject` type; it is used when declaring new types which represent - objects without a varying length. The specific fields it expands to depend - on the definition of :c:macro:`Py_TRACE_REFS`. By default, that macro is - not defined, and :c:macro:`PyObject_HEAD` expands to:: - - Py_ssize_t ob_refcnt; - PyTypeObject *ob_type; + This is a macro used when declaring new types which represent objects + without a varying length. The PyObject_HEAD macro expands to:: - When :c:macro:`Py_TRACE_REFS` is defined, it expands to:: + PyObject ob_base; - PyObject *_ob_next, *_ob_prev; - Py_ssize_t ob_refcnt; - PyTypeObject *ob_type; + See documentation of :c:type:`PyObject` above. .. c:macro:: PyObject_VAR_HEAD - This is a macro which expands to the declarations of the fields of the - :c:type:`PyVarObject` type; it is used when declaring new types which - represent objects with a length that varies from instance to instance. - This macro always expands to:: + This is a macro used when declaring new types which represent objects + with a length that varies from instance to instance. + The PyObject_VAR_HEAD macro expands to:: + + PyVarObject ob_base; + + See documentation of :c:type:`PyVarObject` above. + + +.. c:macro:: Py_TYPE(o) + + This macro is used to access the :attr:`ob_type` member of a Python object. + It expands to:: + + (((PyObject*)(o))->ob_type) + + +.. c:macro:: Py_REFCNT(o) + + This macro is used to access the :attr:`ob_refcnt` member of a Python + object. + It expands to:: + + (((PyObject*)(o))->ob_refcnt) + + +.. c:macro:: Py_SIZE(o) - PyObject_HEAD - Py_ssize_t ob_size; + This macro is used to access the :attr:`ob_size` member of a Python object. + It expands to:: - Note that :c:macro:`PyObject_HEAD` is part of the expansion, and that its own - expansion varies depending on the definition of :c:macro:`Py_TRACE_REFS`. + (((PyVarObject*)(o))->ob_size) .. c:macro:: PyObject_HEAD_INIT(type) @@ -131,7 +144,7 @@ The :attr:`ml_meth` is a C function pointer. The functions may be of different types, but they always return :c:type:`PyObject\*`. If the function is not of the :c:type:`PyCFunction`, the compiler will require a cast in the method table. Even though :c:type:`PyCFunction` defines the first parameter as -:c:type:`PyObject\*`, it is common that the method implementation uses a the +:c:type:`PyObject\*`, it is common that the method implementation uses the specific C type of the *self* object. The :attr:`ml_flags` field is a bitfield which can include the following flags. diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst index 9760dca2df1e..3d83b279c234 100644 --- a/Doc/c-api/sys.rst +++ b/Doc/c-api/sys.rst @@ -47,6 +47,60 @@ Operating System Utilities not call those functions directly! :c:type:`PyOS_sighandler_t` is a typedef alias for :c:type:`void (\*)(int)`. +.. c:function:: wchar_t* Py_DecodeLocale(const char* arg, size_t *size) + + Decode a byte string from the locale encoding with the :ref:`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 + :c:func:`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 :c:func:`Py_EncodeLocale` function to encode the character string + back to a byte string. + + .. seealso:: + + The :c:func:`PyUnicode_DecodeFSDefaultAndSize` and + :c:func:`PyUnicode_DecodeLocaleAndSize` functions. + + .. versionadded:: 3.5 + + +.. c:function:: char* Py_EncodeLocale(const wchar_t *text, size_t *error_pos) + + Encode a wide character string to the locale encoding with the + :ref:`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 :c:func:`PyMem_Free` + to free the memory. Return ``NULL`` on encoding error or memory allocation + error + + If error_pos is not ``NULL``, ``*error_pos`` is set to the index of the + invalid character on encoding error, or set to ``(size_t)-1`` otherwise. + + Use the :c:func:`Py_DecodeLocale` function to decode the bytes string back + to a wide character string. + + .. seealso:: + + The :c:func:`PyUnicode_EncodeFSDefault` and + :c:func:`PyUnicode_EncodeLocale` functions. + + .. versionadded:: 3.5 + + .. _systemfunctions: System Functions @@ -56,12 +110,12 @@ These are utility functions that make functionality from the :mod:`sys` module accessible to C code. They all work with the current interpreter thread's :mod:`sys` module's dict, which is contained in the internal thread state structure. -.. c:function:: PyObject *PySys_GetObject(char *name) +.. c:function:: PyObject *PySys_GetObject(const char *name) Return the object *name* from the :mod:`sys` module or *NULL* if it does not exist, without setting an exception. -.. c:function:: int PySys_SetObject(char *name, PyObject *v) +.. c:function:: int PySys_SetObject(const char *name, PyObject *v) Set *name* in the :mod:`sys` module to *v* unless *v* is *NULL*, in which case *name* is deleted from the sys module. Returns ``0`` on success, ``-1`` diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst index 184affb2224f..3922d50f80a2 100644 --- a/Doc/c-api/tuple.rst +++ b/Doc/c-api/tuple.rst @@ -129,6 +129,14 @@ type. Initializes a struct sequence type *type* from *desc* in place. +.. c:function:: int PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc) + + The same as ``PyStructSequence_InitType``, but returns ``0`` on success and ``-1`` on + failure. + + .. versionadded:: 3.4 + + .. c:type:: PyStructSequence_Desc Contains the meta information of a struct sequence type to create. diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index 5d832541f20c..60c5e73960b3 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -44,6 +44,7 @@ Type Objects .. versionadded:: 3.2 + .. c:function:: void PyType_Modified(PyTypeObject *type) Invalidate the internal lookup cache for the type and all of its @@ -67,6 +68,11 @@ Type Objects Return true if *a* is a subtype of *b*. + This function only checks for actual subtypes, which means that + :meth:`~class.__subclasscheck__` is not called on *b*. Call + :c:func:`PyObject_IsSubclass` to do the same check that :func:`issubclass` + would do. + .. c:function:: PyObject* PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems) @@ -97,3 +103,13 @@ Type Objects types. This allows the caller to reference other heap types as base types. .. versionadded:: 3.3 + +.. c:function:: void* PyType_GetSlot(PyTypeObject *type, int slot) + + Return the function pointer stored in the given slot. If the + result is *NULL*, this indicates that either the slot is *NULL*, + or that the function was called with invalid parameters. + Callers will typically cast the result pointer into the appropriate + function type. + + .. versionadded:: 3.4 diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 48b13e57aeb1..b5113aaef19d 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -94,7 +94,7 @@ type objects) *must* have the :attr:`ob_size` field. This field is not inherited by subtypes. -.. c:member:: char* PyTypeObject.tp_name +.. c:member:: const char* PyTypeObject.tp_name Pointer to a NUL-terminated string containing the name of the type. For types that are accessible as module globals, the string should be the full module @@ -189,31 +189,7 @@ type objects) *must* have the :attr:`ob_size` field. .. c:member:: printfunc PyTypeObject.tp_print - An optional pointer to the instance print function. - - The print function is only called when the instance is printed to a *real* file; - when it is printed to a pseudo-file (like a :class:`io.StringIO` instance), the - instance's :c:member:`~PyTypeObject.tp_repr` or :c:member:`~PyTypeObject.tp_str` function is called to convert it to - a string. These are also called when the type's :c:member:`~PyTypeObject.tp_print` field is - *NULL*. A type should never implement :c:member:`~PyTypeObject.tp_print` in a way that produces - different output than :c:member:`~PyTypeObject.tp_repr` or :c:member:`~PyTypeObject.tp_str` would. - - The print function is called with the same signature as :c:func:`PyObject_Print`: - ``int tp_print(PyObject *self, FILE *file, int flags)``. The *self* argument is - the instance to be printed. The *file* argument is the stdio file to which it - is to be printed. The *flags* argument is composed of flag bits. The only flag - bit currently defined is :const:`Py_PRINT_RAW`. When the :const:`Py_PRINT_RAW` - flag bit is set, the instance should be printed the same way as :c:member:`~PyTypeObject.tp_str` - would format it; when the :const:`Py_PRINT_RAW` flag bit is clear, the instance - should be printed the same was as :c:member:`~PyTypeObject.tp_repr` would format it. It should - return ``-1`` and set an exception condition when an error occurred during the - comparison. - - It is possible that the :c:member:`~PyTypeObject.tp_print` field will be deprecated. In any case, - it is recommended not to define :c:member:`~PyTypeObject.tp_print`, but instead to rely on - :c:member:`~PyTypeObject.tp_repr` and :c:member:`~PyTypeObject.tp_str` for printing. - - This field is inherited by subtypes. + Reserved slot, formerly used for print formatting in Python 2.x. .. c:member:: getattrfunc PyTypeObject.tp_getattr @@ -244,9 +220,14 @@ type objects) *must* have the :attr:`ob_size` field. the subtype's :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` are both *NULL*. -.. c:member:: void* PyTypeObject.tp_reserved +.. c:member:: PyAsyncMethods* tp_as_async - Reserved slot, formerly known as tp_compare. + Pointer to an additional structure that contains fields relevant only to + objects which implement :term:`awaitable` and :term:`asynchronous iterator` + protocols at the C-level. See :ref:`async-structs` for details. + + .. versionadded:: 3.5 + Formerly known as ``tp_compare`` and ``tp_reserved``. .. c:member:: reprfunc PyTypeObject.tp_repr @@ -391,7 +372,7 @@ type objects) *must* have the :attr:`ob_size` field. inherited individually. -.. c:member:: long PyTypeObject.tp_flags +.. c:member:: unsigned long PyTypeObject.tp_flags This field is a bit mask of various flags. Some flags indicate variant semantics for certain situations; others are used to indicate that certain @@ -465,6 +446,24 @@ type objects) *must* have the :attr:`ob_size` field. :const:`Py_TPFLAGS_HAVE_VERSION_TAG`. + .. data:: Py_TPFLAGS_LONG_SUBCLASS + .. data:: Py_TPFLAGS_LIST_SUBCLASS + .. data:: Py_TPFLAGS_TUPLE_SUBCLASS + .. data:: Py_TPFLAGS_BYTES_SUBCLASS + .. data:: Py_TPFLAGS_UNICODE_SUBCLASS + .. data:: Py_TPFLAGS_DICT_SUBCLASS + .. data:: Py_TPFLAGS_BASE_EXC_SUBCLASS + .. data:: Py_TPFLAGS_TYPE_SUBCLASS + + These flags are used by functions such as + :c:func:`PyLong_Check` to quickly determine if a type is a subclass + of a built-in type; such specific checks are faster than a generic + check, like :c:func:`PyObject_IsInstance`. Custom types that inherit + from built-ins should have their :c:member:`~PyTypeObject.tp_flags` + set appropriately, or the code that interacts with such types + will behave differently depending on what kind of check is used. + + .. data:: Py_TPFLAGS_HAVE_FINALIZE This bit is set when the :c:member:`~PyTypeObject.tp_finalize` slot is present in the @@ -473,7 +472,7 @@ type objects) *must* have the :attr:`ob_size` field. .. versionadded:: 3.4 -.. c:member:: char* PyTypeObject.tp_doc +.. c:member:: const char* PyTypeObject.tp_doc An optional pointer to a NUL-terminated C string giving the docstring for this type object. This is exposed as the :attr:`__doc__` attribute on the type and @@ -580,7 +579,9 @@ type objects) *must* have the :attr:`ob_size` field. .. c:member:: richcmpfunc PyTypeObject.tp_richcompare An optional pointer to the rich comparison function, whose signature is - ``PyObject *tp_richcompare(PyObject *a, PyObject *b, int op)``. + ``PyObject *tp_richcompare(PyObject *a, PyObject *b, int op)``. The first + parameter is guaranteed to be an instance of the type that is defined + by :c:type:`PyTypeObject`. The function should return the result of the comparison (usually ``Py_True`` or ``Py_False``). If the comparison is undefined, it must return @@ -618,7 +619,7 @@ type objects) *must* have the :attr:`ob_size` field. +----------------+------------+ -.. c:member:: long PyTypeObject.tp_weaklistoffset +.. c:member:: Py_ssize_t PyTypeObject.tp_weaklistoffset If the instances of this type are weakly referenceable, this field is greater than zero and contains the offset in the instance structure of the weak @@ -785,7 +786,7 @@ type objects) *must* have the :attr:`ob_size` field. .. XXX explain. -.. c:member:: long PyTypeObject.tp_dictoffset +.. c:member:: Py_ssize_t PyTypeObject.tp_dictoffset If the instances of this type have a dictionary containing instance variables, this field is non-zero and contains the offset in the instances of the type of @@ -1122,6 +1123,9 @@ Number Object Structures binaryfunc nb_inplace_true_divide; unaryfunc nb_index; + + binaryfunc nb_matrix_multiply; + binaryfunc nb_inplace_matrix_multiply; } PyNumberMethods; .. note:: @@ -1200,7 +1204,8 @@ Sequence Object Structures This function is used by :c:func:`PySequence_Repeat` and has the same signature. It is also used by the ``*`` operator, after trying numeric - multiplication via the :c:member:`~PyTypeObject.tp_as_number.nb_mul` slot. + multiplication via the :c:member:`~PyTypeObject.tp_as_number.nb_multiply` + slot. .. c:member:: ssizeargfunc PySequenceMethods.sq_item @@ -1332,3 +1337,58 @@ Buffer Object Structures :c:func:`PyBuffer_Release` is the interface for the consumer that wraps this function. + + +.. _async-structs: + + +Async Object Structures +======================= + +.. sectionauthor:: Yury Selivanov + +.. versionadded:: 3.5 + +.. c:type:: PyAsyncMethods + + This structure holds pointers to the functions required to implement + :term:`awaitable` and :term:`asynchronous iterator` objects. + + Here is the structure definition:: + + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + } PyAsyncMethods; + +.. c:member:: unaryfunc PyAsyncMethods.am_await + + The signature of this function is:: + + PyObject *am_await(PyObject *self) + + The returned object must be an iterator, i.e. :c:func:`PyIter_Check` must + return ``1`` for it. + + This slot may be set to *NULL* if an object is not an :term:`awaitable`. + +.. c:member:: unaryfunc PyAsyncMethods.am_aiter + + The signature of this function is:: + + PyObject *am_aiter(PyObject *self) + + Must return an :term:`awaitable` object. See :meth:`__anext__` for details. + + This slot may be set to *NULL* if an object does not implement + asynchronous iteration protocol. + +.. c:member:: unaryfunc PyAsyncMethods.am_anext + + The signature of this function is:: + + PyObject *am_anext(PyObject *self) + + Must return an :term:`awaitable` object. See :meth:`__anext__` for details. + This slot may be set to *NULL*. diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index c7ed5e598793..2eeadb52c90b 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -227,7 +227,10 @@ access internal read-only data of Unicode objects: const char* PyUnicode_AS_DATA(PyObject *o) Return a pointer to a :c:type:`Py_UNICODE` representation of the object. The - ``AS_DATA`` form casts the pointer to :c:type:`const char *`. *o* has to be + returned buffer is always terminated with an extra null code point. It + may also contain embedded null code points, which would cause the string + to be truncated when used in most C functions. The ``AS_DATA`` form + casts the pointer to :c:type:`const char *`. The *o* argument has to be a Unicode object (not checked). .. versionchanged:: 3.3 @@ -556,7 +559,8 @@ APIs: Coerce an encoded object *obj* to an Unicode object and return a reference with incremented refcount. - :class:`bytes`, :class:`bytearray` and other char buffer compatible objects + :class:`bytes`, :class:`bytearray` and other + :term:`bytes-like objects ` are decoded according to the given *encoding* and using the error handling defined by *errors*. Both can be *NULL* to have the interface use the default values (see the next section for details). @@ -649,7 +653,8 @@ APIs: Copy the string *u* into a new UCS4 buffer that is allocated using :c:func:`PyMem_Malloc`. If this fails, *NULL* is returned with a - :exc:`MemoryError` set. + :exc:`MemoryError` set. The returned buffer always has an extra + null code point appended. .. versionadded:: 3.3 @@ -688,8 +693,9 @@ Extension modules can continue using them, as they will not be removed in Python Return a read-only pointer to the Unicode object's internal :c:type:`Py_UNICODE` buffer, or *NULL* on error. This will create the :c:type:`Py_UNICODE*` representation of the object if it is not yet - available. Note that the resulting :c:type:`Py_UNICODE` string may contain - embedded null characters, which would cause the string to be truncated when + available. The buffer is always terminated with an extra null code point. + Note that the resulting :c:type:`Py_UNICODE` string may also contain + embedded null code points, which would cause the string to be truncated when used in most C functions. Please migrate to using :c:func:`PyUnicode_AsUCS4`, @@ -707,8 +713,9 @@ Extension modules can continue using them, as they will not be removed in Python .. c:function:: Py_UNICODE* PyUnicode_AsUnicodeAndSize(PyObject *unicode, Py_ssize_t *size) Like :c:func:`PyUnicode_AsUnicode`, but also saves the :c:func:`Py_UNICODE` - array length in *size*. Note that the resulting :c:type:`Py_UNICODE*` string - may contain embedded null characters, which would cause the string to be + array length (excluding the extra null terminator) in *size*. + Note that the resulting :c:type:`Py_UNICODE*` string + may contain embedded null code points, which would cause the string to be truncated when used in most C functions. .. versionadded:: 3.3 @@ -716,11 +723,11 @@ Extension modules can continue using them, as they will not be removed in Python .. c:function:: Py_UNICODE* PyUnicode_AsUnicodeCopy(PyObject *unicode) - Create a copy of a Unicode string ending with a nul character. Return *NULL* + Create a copy of a Unicode string ending with a null code point. Return *NULL* and raise a :exc:`MemoryError` exception on memory allocation failure, otherwise return a new allocated buffer (use :c:func:`PyMem_Free` to free the buffer). Note that the resulting :c:type:`Py_UNICODE*` string may - contain embedded null characters, which would cause the string to be + contain embedded null code points, which would cause the string to be truncated when used in most C functions. .. versionadded:: 3.2 @@ -758,11 +765,13 @@ system. *errors* is ``NULL``. *str* must end with a null character but cannot contain embedded null characters. + Use :c:func:`PyUnicode_DecodeFSDefaultAndSize` to decode a string from + :c:data:`Py_FileSystemDefaultEncoding` (the locale encoding read at + Python startup). + .. seealso:: - Use :c:func:`PyUnicode_DecodeFSDefaultAndSize` to decode a string from - :c:data:`Py_FileSystemDefaultEncoding` (the locale encoding read at - Python startup). + The :c:func:`Py_DecodeLocale` function. .. versionadded:: 3.3 @@ -783,11 +792,13 @@ system. *errors* is ``NULL``. Return a :class:`bytes` object. *str* cannot contain embedded null characters. + Use :c:func:`PyUnicode_EncodeFSDefault` to encode a string to + :c:data:`Py_FileSystemDefaultEncoding` (the locale encoding read at + Python startup). + .. seealso:: - Use :c:func:`PyUnicode_EncodeFSDefault` to encode a string to - :c:data:`Py_FileSystemDefaultEncoding` (the locale encoding read at - Python startup). + The :c:func:`Py_EncodeLocale` function. .. versionadded:: 3.3 @@ -832,12 +843,14 @@ used, passing :c:func:`PyUnicode_FSDecoder` as the conversion function: If :c:data:`Py_FileSystemDefaultEncoding` is not set, fall back to the locale encoding. + :c:data:`Py_FileSystemDefaultEncoding` is initialized at startup from the + locale encoding and cannot be modified later. If you need to decode a string + from the current locale encoding, use + :c:func:`PyUnicode_DecodeLocaleAndSize`. + .. seealso:: - :c:data:`Py_FileSystemDefaultEncoding` is initialized at startup from the - locale encoding and cannot be modified later. If you need to decode a - string from the current locale encoding, use - :c:func:`PyUnicode_DecodeLocaleAndSize`. + The :c:func:`Py_DecodeLocale` function. .. versionchanged:: 3.2 Use ``"strict"`` error handler on Windows. @@ -867,12 +880,13 @@ used, passing :c:func:`PyUnicode_FSDecoder` as the conversion function: If :c:data:`Py_FileSystemDefaultEncoding` is not set, fall back to the locale encoding. + :c:data:`Py_FileSystemDefaultEncoding` is initialized at startup from the + locale encoding and cannot be modified later. If you need to encode a string + to the current locale encoding, use :c:func:`PyUnicode_EncodeLocale`. + .. seealso:: - :c:data:`Py_FileSystemDefaultEncoding` is initialized at startup from the - locale encoding and cannot be modified later. If you need to encode a - string to the current locale encoding, use - :c:func:`PyUnicode_EncodeLocale`. + The :c:func:`Py_EncodeLocale` function. .. versionadded:: 3.2 @@ -894,10 +908,10 @@ wchar_t Support Copy the Unicode object contents into the :c:type:`wchar_t` buffer *w*. At most *size* :c:type:`wchar_t` characters are copied (excluding a possibly trailing - 0-termination character). Return the number of :c:type:`wchar_t` characters + null termination character). Return the number of :c:type:`wchar_t` characters copied or -1 in case of an error. Note that the resulting :c:type:`wchar_t*` - string may or may not be 0-terminated. It is the responsibility of the caller - to make sure that the :c:type:`wchar_t*` string is 0-terminated in case this is + string may or may not be null-terminated. It is the responsibility of the caller + to make sure that the :c:type:`wchar_t*` string is null-terminated in case this is required by the application. Also, note that the :c:type:`wchar_t*` string might contain null characters, which would cause the string to be truncated when used with most C functions. @@ -906,8 +920,8 @@ wchar_t Support .. c:function:: wchar_t* PyUnicode_AsWideCharString(PyObject *unicode, Py_ssize_t *size) 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 trailing 0-termination character) into + always ends with a null character. If *size* is not *NULL*, write the number + of wide characters (excluding the trailing null termination character) into *\*size*. Returns a buffer allocated by :c:func:`PyMem_Alloc` (use @@ -1037,9 +1051,11 @@ These are the UTF-8 codec APIs: .. c:function:: char* PyUnicode_AsUTF8AndSize(PyObject *unicode, Py_ssize_t *size) - Return a pointer to the default encoding (UTF-8) of the Unicode object, and - store the size of the encoded representation (in bytes) in *size*. *size* - can be *NULL*, in this case no size will be stored. + Return a pointer to the UTF-8 encoding of the Unicode object, and + store the size of the encoded representation (in bytes) in *size*. The + *size* argument can be *NULL*; in this case no size will be stored. The + returned buffer always has an extra null byte appended (not included in + *size*), regardless of whether there are any other null code points. In the case of an error, *NULL* is returned with an exception set and no *size* is stored. @@ -1133,7 +1149,7 @@ These are the UTF-32 codec APIs: mark (U+FEFF). In the other two modes, no BOM mark is prepended. If *Py_UNICODE_WIDE* is not defined, surrogate pairs will be output - as a single codepoint. + as a single code point. Return *NULL* if an exception was raised by the codec. @@ -1568,7 +1584,7 @@ They all return *NULL* or ``-1`` if an exception occurs. Unicode string. -.. c:function:: int PyUnicode_Tailmatch(PyObject *str, PyObject *substr, \ +.. c:function:: Py_ssize_t PyUnicode_Tailmatch(PyObject *str, PyObject *substr, \ Py_ssize_t start, Py_ssize_t end, int direction) Return 1 if *substr* matches ``str[start:end]`` at the given tail end @@ -1619,12 +1635,12 @@ They all return *NULL* or ``-1`` if an exception occurs. respectively. -.. c:function:: int PyUnicode_CompareWithASCIIString(PyObject *uni, char *string) +.. c:function:: int PyUnicode_CompareWithASCIIString(PyObject *uni, const char *string) Compare a unicode object, *uni*, with *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". + ISO-8859-1 if it contains non-ASCII characters. .. c:function:: PyObject* PyUnicode_RichCompare(PyObject *left, PyObject *right, int op) @@ -1646,7 +1662,7 @@ They all return *NULL* or ``-1`` if an exception occurs. .. c:function:: PyObject* PyUnicode_Format(PyObject *format, PyObject *args) Return a new string object from *format* and *args*; this is analogous to - ``format % args``. The *args* argument must be a tuple. + ``format % args``. .. c:function:: int PyUnicode_Contains(PyObject *container, PyObject *element) diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index 9f21b89b9421..f8aaf0f67ad7 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -201,7 +201,7 @@ the same library that the Python runtime is using. .. c:function:: struct _node* PyParser_SimpleParseFile(FILE *fp, const char *filename, int start) This is a simplified interface to :c:func:`PyParser_SimpleParseFileFlags` below, - leaving *flags* set to ``0`` + leaving *flags* set to ``0``. .. c:function:: struct _node* PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int flags) @@ -322,6 +322,10 @@ the same library that the Python runtime is using. it causes an exception to immediately be thrown; this is used for the :meth:`~generator.throw` methods of generator objects. + .. versionchanged:: 3.4 + This function now includes a debug assertion to help ensure that it + does not silently discard an active exception. + .. c:function:: int PyEval_MergeCompilerFlags(PyCompilerFlags *cf) diff --git a/Doc/conf.py b/Doc/conf.py index 5b63cad02891..28dd80f8590f 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -7,26 +7,18 @@ # that aren't pickleable (module imports are okay, they're removed automatically). import sys, os, time -sys.path.append(os.path.abspath('tools/sphinxext')) +sys.path.append(os.path.abspath('tools/extensions')) # General configuration # --------------------- extensions = ['sphinx.ext.coverage', 'sphinx.ext.doctest', 'pyspecific', 'c_annotations'] -templates_path = ['tools/sphinxext'] # General substitutions. project = 'Python' copyright = '1990-%s, Python Software Foundation' % time.strftime('%Y') -# The default replacements for |version| and |release|. -# -# The short X.Y version. -# version = '2.6' -# The full version, including alpha/beta/rc tags. -# release = '2.6a0' - # We look for the Include/patchlevel.h file in the current Python source tree # and replace the values accordingly. import patchlevel @@ -38,46 +30,33 @@ # Else, today_fmt is used as the format for a strftime call. today_fmt = '%B %d, %Y' -# List of files that shouldn't be included in the build. -unused_docs = [ - 'maclib/scrap', - 'library/xmllib', - 'library/xml.etree', -] - -# Ignore .rst in Sphinx its self. -exclude_trees = ['tools/sphinx'] - -# Relative filename of the reference count data file. -refcount_file = 'data/refcounts.dat' - -# If true, '()' will be appended to :func: etc. cross-reference text. -add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -add_module_names = True - # By default, highlight as Python 3. highlight_language = 'python3' +# Require Sphinx 1.2 for build. +needs_sphinx = '1.2' + +# Ignore any .rst files in the venv/ directory. +exclude_patterns = ['venv/*'] + # Options for HTML output # ----------------------- +# Use our custom theme. html_theme = 'pydoctheme' -html_theme_path = ['tools/sphinxext'] +html_theme_path = ['tools'] html_theme_options = {'collapsiblesidebar': True} +# Short title used e.g. for HTML tags. html_short_title = '%s Documentation' % release # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. html_last_updated_fmt = '%b %d, %Y' -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -html_use_smartypants = True +# Path to find HTML templates. +templates_path = ['tools/templates'] # Custom sidebar templates, filenames relative to this file. html_sidebars = { @@ -91,10 +70,10 @@ } # Output an OpenSearch description file. -html_use_opensearch = 'http://docs.python.org/' + version +html_use_opensearch = 'https://docs.python.org/' + version # Additional static files. -html_static_path = ['tools/sphinxext/static'] +html_static_path = ['tools/static'] # Output file base name for HTML help builder. htmlhelp_basename = 'python' + release.replace('.', '') @@ -114,15 +93,15 @@ # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, document class [howto/manual]). -_stdauthor = r'Guido van Rossum\\Fred L. Drake, Jr., editor' +_stdauthor = r'Guido van Rossum\\and the Python development team' latex_documents = [ ('c-api/index', 'c-api.tex', 'The Python/C API', _stdauthor, 'manual'), - ('distutils/index', 'distutils.tex', + ('distributing/index', 'distributing.tex', 'Distributing Python Modules', _stdauthor, 'manual'), ('extending/index', 'extending.tex', 'Extending and Embedding Python', _stdauthor, 'manual'), - ('install/index', 'install.tex', + ('installing/index', 'installing.tex', 'Installing Python Modules', _stdauthor, 'manual'), ('library/index', 'library.tex', 'The Python Library Reference', _stdauthor, 'manual'), @@ -159,6 +138,7 @@ # Get LaTeX to handle Unicode correctly latex_elements = {'inputenc': r'\usepackage[utf8x]{inputenc}', 'utf8extra': ''} + # Options for the coverage checker # -------------------------------- @@ -194,3 +174,19 @@ coverage_ignore_c_items = { # 'cfunction': [...] } + + +# Options for the link checker +# ---------------------------- + +# Ignore certain URLs. +linkcheck_ignore = [r'https://bugs.python.org/(issue)?\d+', + # Ignore PEPs for now, they all have permanent redirects. + r'http://www.python.org/dev/peps/pep-/d+'] + + +# Options for extensions +# ---------------------- + +# Relative filename of the reference count data file. +refcount_file = 'data/refcounts.dat' diff --git a/Doc/contents.rst b/Doc/contents.rst index c0c6af34d9d1..8690de77bf3d 100644 --- a/Doc/contents.rst +++ b/Doc/contents.rst @@ -11,8 +11,8 @@ library/index.rst extending/index.rst c-api/index.rst - distutils/index.rst - install/index.rst + distributing/index.rst + installing/index.rst howto/index.rst faq/index.rst glossary.rst @@ -21,3 +21,11 @@ bugs.rst copyright.rst license.rst + +.. to include legacy packaging docs in build + +.. toctree:: + :hidden: + + distutils/index.rst + install/index.rst diff --git a/Doc/copyright.rst b/Doc/copyright.rst index 94f777c4ef69..2b2f88700f63 100644 --- a/Doc/copyright.rst +++ b/Doc/copyright.rst @@ -4,7 +4,7 @@ Copyright Python and this documentation is: -Copyright © 2001-2013 Python Software Foundation. All rights reserved. +Copyright © 2001-2015 Python Software Foundation. All rights reserved. Copyright © 2000 BeOpen.com. All rights reserved. diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat index 814c3b043793..e38819575794 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat @@ -29,7 +29,7 @@ # reference to the item argument! # The parameter names are as they appear in the API manual, not the source -# code. +# code. PyBool_FromLong:PyObject*::+1: PyBool_FromLong:long:v:0: @@ -349,6 +349,11 @@ PyErr_Format:PyObject*:exception:+1: PyErr_Format:const char*:format:: PyErr_Format::...:: +PyErr_FormatV:PyObject*::null: +PyErr_FormatV:PyObject*:exception:+1: +PyErr_FormatV:const char*:format:: +PyErr_FormatV:va_list:vargs:: + PyErr_WarnEx:int::: PyErr_WarnEx:PyObject*:category:0: PyErr_WarnEx:const char*:message:: @@ -486,6 +491,12 @@ PyFunction_SetDefaults:PyObject*:defaults:+1: PyGen_New:PyObject*::+1: PyGen_New:PyFrameObject*:frame:0: +PyGen_NewWithQualName:PyObject*::+1: +PyGen_NewWithQualName:PyFrameObject*:frame:0: + +PyCoro_New:PyObject*::+1: +PyCoro_New:PyFrameObject*:frame:0: + Py_InitModule:PyObject*::0: Py_InitModule:const char*:name:: Py_InitModule:PyMethodDef[]:methods:: @@ -907,7 +918,7 @@ PyNumber_Xor:PyObject*::+1: PyNumber_Xor:PyObject*:o1:0: PyNumber_Xor:PyObject*:o2:0: -PyObject_AsFileDescriptor:int::: +PyObject_AsFileDescriptor:int::: PyObject_AsFileDescriptor:PyObject*:o:0: PyObject_Call:PyObject*::+1: diff --git a/Doc/distributing/index.rst b/Doc/distributing/index.rst new file mode 100644 index 000000000000..1774d23643ec --- /dev/null +++ b/Doc/distributing/index.rst @@ -0,0 +1,170 @@ +.. _distributing-index: + +############################### + Distributing Python Modules +############################### + +:Email: distutils-sig@python.org + + +As a popular open source development project, Python has an active +supporting community of contributors and users that also make their software +available for other Python developers to use under open source license terms. + +This allows Python users to share and collaborate effectively, benefiting +from the solutions others have already created to common (and sometimes +even rare!) problems, as well as potentially contributing their own +solutions to the common pool. + +This guide covers the distribution part of the process. For a guide to +installing other Python projects, refer to the +:ref:`installation guide <installing-index>`. + +.. note:: + + For corporate and other institutional users, be aware that many + organisations have their own policies around using and contributing to + open source software. Please take such policies into account when making + use of the distribution and installation tools provided with Python. + + +Key terms +========= + +* the `Python Packaging Index <https://pypi.python.org/pypi>`__ is a public + repository of open source licensed packages made available for use by + other Python users +* the `Python Packaging Authority + <https://packaging.python.org/en/latest/future.html>`__ are the group of + developers and documentation authors responsible for the maintenance and + evolution of the standard packaging tools and the associated metadata and + file format standards. They maintain a variety of tools, documentation + and issue trackers on both `GitHub <https://github.com/pypa>`__ and + `BitBucket <https://bitbucket.org/pypa/>`__. +* :mod:`distutils` is the original build and distribution system first added + to the Python standard library in 1998. While direct use of :mod:`distutils` + is being phased out, it still laid the foundation for the current packaging + and distribution infrastructure, and it not only remains part of the + standard library, but its name lives on in other ways (such as the name + of the mailing list used to coordinate Python packaging standards + development). +* `setuptools`_ is a (largely) drop-in replacement for :mod:`distutils` first + published in 2004. Its most notable addition over the unmodified + :mod:`distutils` tools was the ability to declare dependencies on other + packages. It is currently recommended as a more regularly updated + alternative to :mod:`distutils` that offers consistent support for more + recent packaging standards across a wide range of Python versions. +* `wheel`_ (in this context) is a project that adds the ``bdist_wheel`` + command to :mod:`distutils`/`setuptools`_. This produces a cross platform + binary packaging format (called "wheels" or "wheel files" and defined in + :pep:`427`) that allows Python libraries, even those including binary + extensions, to be installed on a system without needing to be built + locally. + +.. _setuptools: https://setuptools.pypa.io/en/latest/setuptools.html +.. _wheel: http://wheel.readthedocs.org + +Open source licensing and collaboration +======================================= + +In most parts of the world, software is automatically covered by copyright. +This means that other developers require explicit permission to copy, use, +modify and redistribute the software. + +Open source licensing is a way of explicitly granting such permission in a +relatively consistent way, allowing developers to share and collaborate +efficiently by making common solutions to various problems freely available. +This leaves many developers free to spend more time focusing on the problems +that are relatively unique to their specific situation. + +The distribution tools provided with Python are designed to make it +reasonably straightforward for developers to make their own contributions +back to that common pool of software if they choose to do so. + +The same distribution tools can also be used to distribute software within +an organisation, regardless of whether that software is published as open +source software or not. + + +Installing the tools +==================== + +The standard library does not include build tools that support modern +Python packaging standards, as the core development team has found that it +is important to have standard tools that work consistently, even on older +versions of Python. + +The currently recommended build and distribution tools can be installed +by invoking the ``pip`` module at the command line:: + + python -m pip install setuptools wheel twine + +.. note:: + + For POSIX users (including Mac OS X and Linux users), these instructions + assume the use of a :term:`virtual environment`. + + For Windows users, these instructions assume that the option to + adjust the system PATH environment variable was selected when installing + Python. + +The Python Packaging User Guide includes more details on the `currently +recommended tools`_. + +.. _currently recommended tools: https://packaging.python.org/en/latest/current.html#packaging-tool-recommendations + +Reading the guide +================= + +The Python Packaging User Guide covers the various key steps and elements +involved in creating a project: + +* `Project structure`_ +* `Building and packaging the project`_ +* `Uploading the project to the Python Packaging Index`_ + +.. _Project structure: \ + https://packaging.python.org/en/latest/distributing.html#creating-your-own-project +.. _Building and packaging the project: \ + https://packaging.python.org/en/latest/distributing.html#packaging-your-project +.. _Uploading the project to the Python Packaging Index: \ + https://packaging.python.org/en/latest/distributing.html#uploading-your-project-to-pypi + + +How do I...? +============ + +These are quick answers or links for some common tasks. + +... choose a name for my project? +--------------------------------- + +This isn't an easy topic, but here are a few tips: + +* check the Python Packaging Index to see if the name is already in use +* check popular hosting sites like GitHub, BitBucket, etc to see if there + is already a project with that name +* check what comes up in a web search for the name you're considering +* avoid particularly common words, especially ones with multiple meanings, + as they can make it difficult for users to find your software when + searching for it + + +... create and distribute binary extensions? +-------------------------------------------- + +This is actually quite a complex topic, with a variety of alternatives +available depending on exactly what you're aiming to achieve. See the +Python Packaging User Guide for more information and recommendations. + +.. seealso:: + + `Python Packaging User Guide: Binary Extensions + <https://packaging.python.org/en/latest/extensions.html>`__ + +.. other topics: + + Once the Development & Deployment part of PPUG is fleshed out, some of + those sections should be linked from new questions here (most notably, + we should have a question about avoiding depending on PyPI that links to + https://packaging.python.org/en/latest/deployment.html#pypi-mirrors-and-caches) diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst index 54f0a4eca6fa..554d2c878db4 100644 --- a/Doc/distutils/apiref.rst +++ b/Doc/distutils/apiref.rst @@ -78,7 +78,7 @@ setup script). Indirectly provides the :class:`distutils.dist.Distribution` and | | be built | :class:`distutils.core.Extension` | +--------------------+--------------------------------+-------------------------------------------------------------+ | *classifiers* | A list of categories for the | a list of strings; valid classifiers are listed on `PyPI | - | | package | <http://pypi.python.org/pypi?:action=list_classifiers>`_. | + | | package | <https://pypi.python.org/pypi?:action=list_classifiers>`_. | +--------------------+--------------------------------+-------------------------------------------------------------+ | *distclass* | the :class:`Distribution` | a subclass of | | | class to use | :class:`distutils.core.Distribution` | @@ -521,7 +521,7 @@ This module provides the following functions. .. method:: CCompiler.library_option(lib) - Return the compiler option to add *dir* to the list of libraries linked into the + Return the compiler option to add *lib* to the list of libraries linked into the shared library or executable. @@ -853,17 +853,6 @@ Windows. It also contains the Mingw32CCompiler class which handles the mingw32 port of GCC (same as cygwin in no-cygwin mode). -:mod:`distutils.emxccompiler` --- OS/2 EMX Compiler -=================================================== - -.. module:: distutils.emxccompiler - :synopsis: OS/2 EMX Compiler support - - -This module provides the EMXCCompiler class, a subclass of -:class:`UnixCCompiler` that handles the EMX port of the GNU C compiler to OS/2. - - :mod:`distutils.archive_util` --- Archiving utilities ====================================================== @@ -879,23 +868,31 @@ tarballs or zipfiles. Create an archive file (eg. ``zip`` or ``tar``). *base_name* is the name of the file to create, minus any format-specific extension; *format* is the - archive format: one of ``zip``, ``tar``, ``ztar``, or ``gztar``. *root_dir* is - a directory that will be the root directory of the archive; ie. we typically - ``chdir`` into *root_dir* before creating the archive. *base_dir* is the - directory where we start archiving from; ie. *base_dir* will be the common - prefix of all files and directories in the archive. *root_dir* and *base_dir* - both default to the current directory. Returns the name of the archive file. + archive format: one of ``zip``, ``tar``, ``gztar``, ``bztar``, ``xztar``, or + ``ztar``. *root_dir* is a directory that will be the root directory of the + archive; ie. we typically ``chdir`` into *root_dir* before creating the + archive. *base_dir* is the directory where we start archiving from; ie. + *base_dir* will be the common prefix of all files and directories in the + archive. *root_dir* and *base_dir* both default to the current directory. + Returns the name of the archive file. + + .. versionchanged: 3.5 + Added support for the ``xztar`` format. .. function:: make_tarball(base_name, base_dir[, compress='gzip', verbose=0, dry_run=0]) 'Create an (optional compressed) archive as a tar file from all files in and - under *base_dir*. *compress* must be ``'gzip'`` (the default), ``'compress'``, - ``'bzip2'``, or ``None``. Both :program:`tar` and the compression utility named - by *compress* must be on the default program search path, so this is probably - Unix-specific. The output tar file will be named :file:`base_dir.tar`, - possibly plus the appropriate compression extension (:file:`.gz`, :file:`.bz2` - or :file:`.Z`). Return the output filename. + under *base_dir*. *compress* must be ``'gzip'`` (the default), + ``'bzip2'``, ``'xz'``, ``'compress'``, or ``None``. For the ``'compress'`` + method the compression utility named by :program:`compress` must be on the + default program search path, so this is probably Unix-specific. The output + tar file will be named :file:`base_dir.tar`, possibly plus the appropriate + compression extension (``.gz``, ``.bz2``, ``.xz`` or ``.Z``). Return the + output filename. + + .. versionchanged: 3.5 + Added support for the ``xz`` compression. .. function:: make_zipfile(base_name, base_dir[, verbose=0, dry_run=0]) @@ -931,7 +928,7 @@ timestamp dependency analysis. Walk two filename lists in parallel, testing if each source is newer than its corresponding target. Return a pair of lists (*sources*, *targets*) where - source is newer than target, according to the semantics of :func:`newer` + source is newer than target, according to the semantics of :func:`newer`. .. % % equivalent to a listcomp... @@ -975,7 +972,7 @@ directories. .. function:: create_tree(base_dir, files[, mode=0o777, verbose=0, dry_run=0]) Create all the empty directories under *base_dir* needed to put *files* there. - *base_dir* is just the a name of a directory which doesn't necessarily exist + *base_dir* is just the name of a directory which doesn't necessarily exist yet; *files* is a list of filenames to be interpreted relative to *base_dir*. *base_dir* + the directory portion of every file in *files* will be created if it doesn't already exist. *mode*, *verbose* and *dry_run* flags are as for @@ -1004,7 +1001,7 @@ directories. Files in *src* that begin with :file:`.nfs` are skipped (more information on these files is available in answer D2 of the `NFS FAQ page - <http://nfs.sourceforge.net/#section_d>`_. + <http://nfs.sourceforge.net/#section_d>`_). .. versionchanged:: 3.3.1 NFS files are ignored. @@ -1110,13 +1107,13 @@ other utility module. during the build of Python), not the OS version of the current system. For universal binary builds on Mac OS X the architecture value reflects - the univeral binary status instead of the architecture of the current + the universal binary status instead of the architecture of the current processor. For 32-bit universal binaries the architecture is ``fat``, for 64-bit universal binaries the architecture is ``fat64``, and for 4-way universal binaries the architecture is ``universal``. Starting from Python 2.7 and Python 3.2 the architecture ``fat3`` is used for a 3-way universal build (ppc, i386, x86_64) and ``intel`` is used for - a univeral build with the i386 and x86_64 architectures + a universal build with the i386 and x86_64 architectures Examples of returned values on Mac OS X: @@ -1171,15 +1168,6 @@ other utility module. underscore. No { } or ( ) style quoting is available. -.. function:: grok_environment_error(exc[, prefix='error: ']) - - Generate a useful error message from an :exc:`OSError` exception object. - Handles Python 1.5.1 and later styles, and does what it can to deal with - exception objects that don't have a filename (which happens when the error - is due to a two-file operation, such as :func:`~os.rename` or :func:`~os.link`). - Returns the error message as a string prefixed with *prefix*. - - .. function:: split_quoted(s) Split a string up according to Unix shell-like rules for quotes and backslashes. @@ -1213,12 +1201,12 @@ other utility module. .. function:: byte_compile(py_files[, optimize=0, force=0, prefix=None, base_dir=None, verbose=1, dry_run=0, direct=None]) - Byte-compile a collection of Python source files to either :file:`.pyc` or - :file:`.pyo` files in a :file:`__pycache__` subdirectory (see :pep:`3147`). + Byte-compile a collection of Python source files to :file:`.pyc` files in a + :file:`__pycache__` subdirectory (see :pep:`3147` and :pep:`488`). *py_files* is a list of files to compile; any files that don't end in :file:`.py` are silently skipped. *optimize* must be one of the following: - * ``0`` - don't optimize (generate :file:`.pyc`) + * ``0`` - don't optimize * ``1`` - normal optimization (like ``python -O``) * ``2`` - extra optimization (like ``python -OO``) @@ -1242,10 +1230,13 @@ other utility module. doing, leave it set to ``None``. .. versionchanged:: 3.2.3 - Create ``.pyc`` or ``.pyo`` files with an :func:`import magic tag + Create ``.pyc`` files with an :func:`import magic tag <imp.get_tag>` in their name, in a :file:`__pycache__` subdirectory instead of files without tag in the current directory. + .. versionchanged: 3.5 + Create ``.pyc`` files according to :pep:`488`. + .. function:: rfc822_escape(header) @@ -1943,8 +1934,12 @@ Subclasses of :class:`Command` must define the following methods. .. module:: distutils.command.clean :synopsis: Clean a package build area +This command removes the temporary files created by :command:`build` +and its subcommands, like intermediary compiled object files. With +the ``--all`` option, the complete build directory will be removed. -.. % todo +Extension modules built :ref:`in place <distutils-build-ext-inplace>` +will not be cleaned, as they are not in the build directory. :mod:`distutils.command.config` --- Perform package configuration diff --git a/Doc/distutils/builtdist.rst b/Doc/distutils/builtdist.rst index 83c68ae20c75..523d1e0fff1b 100644 --- a/Doc/distutils/builtdist.rst +++ b/Doc/distutils/builtdist.rst @@ -72,13 +72,19 @@ The available formats for built distributions are: +-------------+------------------------------+---------+ | Format | Description | Notes | +=============+==============================+=========+ -| ``gztar`` | gzipped tar file | (1),(3) | +| ``gztar`` | gzipped tar file | \(1) | | | (:file:`.tar.gz`) | | +-------------+------------------------------+---------+ +| ``bztar`` | bzipped tar file | | +| | (:file:`.tar.bz2`) | | ++-------------+------------------------------+---------+ +| ``xztar`` | xzipped tar file | | +| | (:file:`.tar.xz`) | | ++-------------+------------------------------+---------+ | ``ztar`` | compressed tar file | \(3) | | | (:file:`.tar.Z`) | | +-------------+------------------------------+---------+ -| ``tar`` | tar file (:file:`.tar`) | \(3) | +| ``tar`` | tar file (:file:`.tar`) | | +-------------+------------------------------+---------+ | ``zip`` | zip file (:file:`.zip`) | (2),(4) | +-------------+------------------------------+---------+ @@ -94,6 +100,9 @@ The available formats for built distributions are: | ``msi`` | Microsoft Installer. | | +-------------+------------------------------+---------+ +.. versionchanged:: 3.5 + Added support for the ``xztar`` format. + Notes: @@ -104,8 +113,7 @@ Notes: default on Windows (3) - requires external utilities: :program:`tar` and possibly one of :program:`gzip`, - :program:`bzip2`, or :program:`compress` + requires external :program:`compress` utility. (4) requires either external :program:`zip` utility or :mod:`zipfile` module (part @@ -119,21 +127,22 @@ You don't have to use the :command:`bdist` command with the :option:`--formats` option; you can also use the command that directly implements the format you're interested in. Some of these :command:`bdist` "sub-commands" actually generate several similar formats; for instance, the :command:`bdist_dumb` command -generates all the "dumb" archive formats (``tar``, ``ztar``, ``gztar``, and -``zip``), and :command:`bdist_rpm` generates both binary and source RPMs. The -:command:`bdist` sub-commands, and the formats generated by each, are: - -+--------------------------+-----------------------+ -| Command | Formats | -+==========================+=======================+ -| :command:`bdist_dumb` | tar, ztar, gztar, zip | -+--------------------------+-----------------------+ -| :command:`bdist_rpm` | rpm, srpm | -+--------------------------+-----------------------+ -| :command:`bdist_wininst` | wininst | -+--------------------------+-----------------------+ -| :command:`bdist_msi` | msi | -+--------------------------+-----------------------+ +generates all the "dumb" archive formats (``tar``, ``gztar``, ``bztar``, +``xztar``, ``ztar``, and ``zip``), and :command:`bdist_rpm` generates both +binary and source RPMs. The :command:`bdist` sub-commands, and the formats +generated by each, are: + ++--------------------------+-------------------------------------+ +| Command | Formats | ++==========================+=====================================+ +| :command:`bdist_dumb` | tar, gztar, bztar, xztar, ztar, zip | ++--------------------------+-------------------------------------+ +| :command:`bdist_rpm` | rpm, srpm | ++--------------------------+-------------------------------------+ +| :command:`bdist_wininst` | wininst | ++--------------------------+-------------------------------------+ +| :command:`bdist_msi` | msi | ++--------------------------+-------------------------------------+ The following sections give details on the individual :command:`bdist_\*` commands. @@ -186,21 +195,21 @@ Distutils configuration files. Various options and sections in the +------------------------------------------+----------------------------------------------+ | RPM :file:`.spec` file option or section | Distutils setup script option | +==========================================+==============================================+ -| Name | :option:`name` | +| Name | ``name`` | +------------------------------------------+----------------------------------------------+ -| Summary (in preamble) | :option:`description` | +| Summary (in preamble) | ``description`` | +------------------------------------------+----------------------------------------------+ -| Version | :option:`version` | +| Version | ``version`` | +------------------------------------------+----------------------------------------------+ -| Vendor | :option:`author` and :option:`author_email`, | -| | or --- & :option:`maintainer` and | -| | :option:`maintainer_email` | +| Vendor | ``author`` and ``author_email``, | +| | or --- & ``maintainer`` and | +| | ``maintainer_email`` | +------------------------------------------+----------------------------------------------+ -| Copyright | :option:`license` | +| Copyright | ``license`` | +------------------------------------------+----------------------------------------------+ -| Url | :option:`url` | +| Url | ``url`` | +------------------------------------------+----------------------------------------------+ -| %description (section) | :option:`long_description` | +| %description (section) | ``long_description`` | +------------------------------------------+----------------------------------------------+ Additionally, there are many options in :file:`.spec` files that don't have @@ -211,27 +220,27 @@ options to the :command:`bdist_rpm` command as follows: | RPM :file:`.spec` file option | :command:`bdist_rpm` option | default value | | or section | | | +===============================+=============================+=========================+ -| Release | :option:`release` | "1" | +| Release | ``release`` | "1" | +-------------------------------+-----------------------------+-------------------------+ -| Group | :option:`group` | "Development/Libraries" | +| Group | ``group`` | "Development/Libraries" | +-------------------------------+-----------------------------+-------------------------+ -| Vendor | :option:`vendor` | (see above) | +| Vendor | ``vendor`` | (see above) | +-------------------------------+-----------------------------+-------------------------+ -| Packager | :option:`packager` | (none) | +| Packager | ``packager`` | (none) | +-------------------------------+-----------------------------+-------------------------+ -| Provides | :option:`provides` | (none) | +| Provides | ``provides`` | (none) | +-------------------------------+-----------------------------+-------------------------+ -| Requires | :option:`requires` | (none) | +| Requires | ``requires`` | (none) | +-------------------------------+-----------------------------+-------------------------+ -| Conflicts | :option:`conflicts` | (none) | +| Conflicts | ``conflicts`` | (none) | +-------------------------------+-----------------------------+-------------------------+ -| Obsoletes | :option:`obsoletes` | (none) | +| Obsoletes | ``obsoletes`` | (none) | +-------------------------------+-----------------------------+-------------------------+ -| Distribution | :option:`distribution_name` | (none) | +| Distribution | ``distribution_name`` | (none) | +-------------------------------+-----------------------------+-------------------------+ -| BuildRequires | :option:`build_requires` | (none) | +| BuildRequires | ``build_requires`` | (none) | +-------------------------------+-----------------------------+-------------------------+ -| Icon | :option:`icon` | (none) | +| Icon | ``icon`` | (none) | +-------------------------------+-----------------------------+-------------------------+ Obviously, supplying even a few of these options on the command-line would be @@ -355,7 +364,7 @@ support this option, so the command:: would create a 64bit installation executable on your 32bit version of Windows. To cross-compile, you must download the Python source code and cross-compile -Python itself for the platform you are targetting - it is not possible from a +Python itself for the platform you are targeting - it is not possible from a binary installation of Python (as the .lib etc file for other platforms are not included.) In practice, this means the user of a 32 bit operating system will need to use Visual Studio 2008 to open the diff --git a/Doc/distutils/configfile.rst b/Doc/distutils/configfile.rst index 890047c08e54..8faffe6c200d 100644 --- a/Doc/distutils/configfile.rst +++ b/Doc/distutils/configfile.rst @@ -67,7 +67,9 @@ universal :option:`--help` option, e.g. :: [...] Note that an option spelled :option:`--foo-bar` on the command-line is spelled -:option:`foo_bar` in configuration files. +``foo_bar`` in configuration files. + +.. _distutils-build-ext-inplace: For example, say you want your extensions to be built "in-place"---that is, you have an extension :mod:`pkg.ext`, and you want the compiled extension file @@ -112,7 +114,7 @@ own :file:`setup.cfg`:: doc/ examples/ -Note that the :option:`doc_files` option is simply a whitespace-separated string +Note that the ``doc_files`` option is simply a whitespace-separated string split across multiple lines for readability. diff --git a/Doc/distutils/examples.rst b/Doc/distutils/examples.rst index 5eb654a529a1..af9125a7b3f1 100644 --- a/Doc/distutils/examples.rst +++ b/Doc/distutils/examples.rst @@ -11,7 +11,7 @@ Distutils Cookbook. .. seealso:: - `Distutils Cookbook <http://wiki.python.org/moin/Distutils/Cookbook>`_ + `Distutils Cookbook <https://wiki.python.org/moin/Distutils/Cookbook>`_ Collection of recipes showing how to achieve more control over distutils. @@ -22,7 +22,7 @@ Pure Python distribution (by module) If you're just distributing a couple of modules, especially if they don't live in a particular package, you can specify them individually using the -:option:`py_modules` option in the setup script. +``py_modules`` option in the setup script. In the simplest case, you'll have two files to worry about: a setup script and the single module you're distributing, :file:`foo.py` in this example:: @@ -41,12 +41,12 @@ directory.) A minimal setup script to describe this situation would be:: ) Note that the name of the distribution is specified independently with the -:option:`name` option, and there's no rule that says it has to be the same as +``name`` option, and there's no rule that says it has to be the same as the name of the sole module in the distribution (although that's probably a good convention to follow). However, the distribution name is used to generate filenames, so you should stick to letters, digits, underscores, and hyphens. -Since :option:`py_modules` is a list, you can of course specify multiple +Since ``py_modules`` is a list, you can of course specify multiple modules, eg. if you're distributing modules :mod:`foo` and :mod:`bar`, your setup might look like this:: @@ -130,7 +130,7 @@ requires the least work to describe in your setup script:: ) If you want to put modules in directories not named for their package, then you -need to use the :option:`package_dir` option again. For example, if the +need to use the ``package_dir`` option again. For example, if the :file:`src` directory holds modules in the :mod:`foobar` package:: <root>/ @@ -169,8 +169,8 @@ in which case your setup script would be :: (The empty string also stands for the current directory.) -If you have sub-packages, they must be explicitly listed in :option:`packages`, -but any entries in :option:`package_dir` automatically extend to sub-packages. +If you have sub-packages, they must be explicitly listed in ``packages``, +but any entries in ``package_dir`` automatically extend to sub-packages. (In other words, the Distutils does *not* scan your source tree, trying to figure out which directories correspond to Python packages by looking for :file:`__init__.py` files.) Thus, if the default layout grows a sub-package:: @@ -193,17 +193,14 @@ then the corresponding setup script would be :: packages=['foobar', 'foobar.subfoo'], ) -(Again, the empty string in :option:`package_dir` stands for the current -directory.) - .. _single-ext: Single extension module ======================= -Extension modules are specified using the :option:`ext_modules` option. -:option:`package_dir` has no effect on where extension source files are found; +Extension modules are specified using the ``ext_modules`` option. +``package_dir`` has no effect on where extension source files are found; it only affects the source for pure Python modules. The simplest case, a single extension module in a single C source file, is:: @@ -267,7 +264,7 @@ For example, if the :file:`setup.py` script is changed like this:: desc = """\ My description - ============= + ============== This is the description of the ``foobar`` package. """ @@ -289,20 +286,20 @@ Reading the metadata The :func:`distutils.core.setup` function provides a command-line interface that allows you to query the metadata fields of a project through the -`setup.py` script of a given project:: +``setup.py`` script of a given project:: $ python setup.py --name distribute -This call reads the `name` metadata by running the +This call reads the ``name`` metadata by running the :func:`distutils.core.setup` function. Although, when a source or binary distribution is created with Distutils, the metadata fields are written in a static file called :file:`PKG-INFO`. When a Distutils-based project is installed in Python, the :file:`PKG-INFO` file is copied alongside the modules and packages of the distribution under :file:`NAME-VERSION-pyX.X.egg-info`, -where `NAME` is the name of the project, `VERSION` its version as defined -in the Metadata, and `pyX.X` the major and minor version of Python like -`2.7` or `3.2`. +where ``NAME`` is the name of the project, ``VERSION`` its version as defined +in the Metadata, and ``pyX.X`` the major and minor version of Python like +``2.7`` or ``3.2``. You can read back this static file, by using the :class:`distutils.dist.DistributionMetadata` class and its diff --git a/Doc/distutils/extending.rst b/Doc/distutils/extending.rst index 5a70d031cc6c..5139c6dc81f8 100644 --- a/Doc/distutils/extending.rst +++ b/Doc/distutils/extending.rst @@ -61,7 +61,7 @@ commands to be added which can support existing :file:`setup.py` scripts without requiring modifications to the Python installation. This is expected to allow third-party extensions to provide support for additional packaging systems, but the commands can be used for anything distutils commands can be used for. A new -configuration option, :option:`command_packages` (command-line option +configuration option, ``command_packages`` (command-line option :option:`--command-packages`), can be used to specify additional packages to be searched for modules implementing commands. Like all distutils options, this can be specified on the command line or in a configuration file. This option @@ -75,7 +75,7 @@ This new option can be used to add any number of packages to the list of packages searched for command implementations; multiple package names should be separated by commas. When not specified, the search is only performed in the :mod:`distutils.command` package. When :file:`setup.py` is run with the option -:option:`--command-packages` :option:`distcmds,buildcmds`, however, the packages +``--command-packages distcmds,buildcmds``, however, the packages :mod:`distutils.command`, :mod:`distcmds`, and :mod:`buildcmds` will be searched in that order. New commands are expected to be implemented in modules of the same name as the command by classes sharing the same name. Given the example diff --git a/Doc/distutils/index.rst b/Doc/distutils/index.rst index 1cd5f3c5dc6e..90d1c1ab34f6 100644 --- a/Doc/distutils/index.rst +++ b/Doc/distutils/index.rst @@ -1,8 +1,8 @@ .. _distutils-index: -############################### - Distributing Python Modules -############################### +############################################## + Distributing Python Modules (Legacy version) +############################################## :Authors: Greg Ward, Anthony Baxter :Email: distutils-sig@python.org @@ -12,6 +12,16 @@ the module developer's point of view, describing how to use the Distutils to make Python modules and extensions easily available to a wider audience with very little overhead for build/release/install mechanics. +.. note:: + + This guide only covers the basic tools for building and distributing + extensions that are provided as part of this version of Python. Third + party tools offer easier to use and more secure alternatives. Refer to the + `quick recommendations section + <https://python-packaging-user-guide.readthedocs.org/en/latest/current.html>`__ + in the Python Packaging User Guide for more information. + + .. toctree:: :maxdepth: 2 :numbered: diff --git a/Doc/distutils/introduction.rst b/Doc/distutils/introduction.rst index 0ece646c3452..8f46bd74c5b0 100644 --- a/Doc/distutils/introduction.rst +++ b/Doc/distutils/introduction.rst @@ -156,8 +156,8 @@ module pure Python module a module written in Python and contained in a single :file:`.py` file (and - possibly associated :file:`.pyc` and/or :file:`.pyo` files). Sometimes referred - to as a "pure module." + possibly associated :file:`.pyc` files). Sometimes referred to as a + "pure module." extension module a module written in the low-level language of the Python implementation: C/C++ @@ -210,5 +210,3 @@ distribution root the top-level directory of your source tree (or source distribution); the directory where :file:`setup.py` exists. Generally :file:`setup.py` will be run from this directory. - - diff --git a/Doc/distutils/packageindex.rst b/Doc/distutils/packageindex.rst index dae8c545d0d3..daf934526487 100644 --- a/Doc/distutils/packageindex.rst +++ b/Doc/distutils/packageindex.rst @@ -8,26 +8,57 @@ The Python Package Index (PyPI) ******************************* -The `Python Package Index (PyPI)`_ holds :ref:`meta-data <meta-data>` +The `Python Package Index (PyPI)`_ stores :ref:`meta-data <meta-data>` describing distributions packaged with distutils, as well as package data like -distribution files if the package author wishes. +distribution files if a package author wishes. + +Distutils provides the :command:`register` and :command:`upload` commands for +pushing meta-data and distribution files to PyPI, respectively. See +:ref:`package-commands` for information on these commands. + + +PyPI overview +============= + +PyPI lets you submit any number of versions of your distribution to the index. +If you alter the meta-data for a particular version, you can submit it again +and the index will be updated. + +PyPI holds a record for each (name, version) combination submitted. The first +user to submit information for a given name is designated the Owner of that +name. Changes can be submitted through the :command:`register` command or +through the web interface. Owners can designate other users as Owners or +Maintainers. Maintainers can edit the package information, but not designate +new Owners or Maintainers. + +By default PyPI displays only the newest version of a given package. The web +interface lets one change this default behavior and manually select which +versions to display and hide. + +For each version, PyPI displays a home page. The home page is created from +the ``long_description`` which can be submitted via the :command:`register` +command. See :ref:`package-display` for more information. + + +.. _package-commands: + +Distutils commands +================== Distutils exposes two commands for submitting package data to PyPI: the :ref:`register <package-register>` command for submitting meta-data to PyPI and the :ref:`upload <package-upload>` command for submitting distribution -files. Both commands read configuration data from a special file called the -:ref:`.pypirc file <pypirc>`. PyPI :ref:`displays a home page -<package-display>` for each package created from the ``long_description`` -submitted by the :command:`register` command. +files. Both commands read configuration data from a special file called a +:ref:`.pypirc file <pypirc>`. .. _package-register: -Registering Packages -==================== +The ``register`` command +------------------------ The distutils command :command:`register` is used to submit your distribution's -meta-data to the index. It is invoked as follows:: +meta-data to an index server. It is invoked as follows:: python setup.py register @@ -42,7 +73,8 @@ Distutils will respond with the following prompt:: Your selection [default 1]: Note: if your username and password are saved locally, you will not see this -menu. +menu. Also, refer to :ref:`pypirc` for how to store your credentials in a +:file:`.pypirc` file. If you have not registered with PyPI, then you will need to do so now. You should choose option 2, and enter your details as required. Soon after @@ -53,26 +85,13 @@ Once you are registered, you may choose option 1 from the menu. You will be prompted for your PyPI username and password, and :command:`register` will then submit your meta-data to the index. -You may submit any number of versions of your distribution to the index. If you -alter the meta-data for a particular version, you may submit it again and the -index will be updated. - -PyPI holds a record for each (name, version) combination submitted. The first -user to submit information for a given name is designated the Owner of that -name. They may submit changes through the :command:`register` command or through -the web interface. They may also designate other users as Owners or Maintainers. -Maintainers may edit the package information, but not designate other Owners or -Maintainers. - -By default PyPI displays only the newest version of a given package. The web -interface lets one change this default behavior and manually select which -versions to display and hide. +See :ref:`package-cmdoptions` for options to the :command:`register` command. .. _package-upload: -Uploading Packages -================== +The ``upload`` command +---------------------- The distutils command :command:`upload` pushes the distribution files to PyPI. @@ -86,29 +105,42 @@ PyPI. Note that these will be uploaded even if they are built using an earlier invocation of :file:`setup.py`, but that only distributions named on the command line for the invocation including the :command:`upload` command are uploaded. -The :command:`upload` command uses the username, password, and repository URL -from the :file:`$HOME/.pypirc` file (see section :ref:`pypirc` for more on this -file). If a :command:`register` command was previously called in the same command, +If a :command:`register` command was previously called in the same command, and if the password was entered in the prompt, :command:`upload` will reuse the -entered password. This is useful if you do not want to store a clear text -password in the :file:`$HOME/.pypirc` file. - -You can specify another PyPI server with the ``--repository=url`` option:: - - python setup.py sdist bdist_wininst upload -r http://example.com/pypi - -See section :ref:`pypirc` for more on defining several servers. +entered password. This is useful if you do not want to store a password in +clear text in a :file:`.pypirc` file. You can use the ``--sign`` option to tell :command:`upload` to sign each uploaded file using GPG (GNU Privacy Guard). The :program:`gpg` program must be available for execution on the system :envvar:`PATH`. You can also specify which key to use for signing using the ``--identity=name`` option. -Other :command:`upload` options include ``--repository=url`` or -``--repository=section`` where *url* is the url of the server and -*section* the name of the section in :file:`$HOME/.pypirc`, and -``--show-response`` (which displays the full response text from the PyPI -server for help in debugging upload problems). +See :ref:`package-cmdoptions` for additional options to the :command:`upload` +command. + + +.. _package-cmdoptions: + +Additional command options +-------------------------- + +This section describes options common to both the :command:`register` and +:command:`upload` commands. + +The ``--repository`` or ``-r`` option lets you specify a PyPI server +different from the default. For example:: + + python setup.py sdist bdist_wininst upload -r https://example.com/pypi + +For convenience, a name can be used in place of the URL when the +:file:`.pypirc` file is configured to do so. For example:: + + python setup.py register -r other + +See :ref:`pypirc` for more information on defining alternate servers. + +The ``--show-response`` option displays the full response text from the PyPI +server, which is useful when debugging problems with registering and uploading. .. index:: @@ -117,10 +149,14 @@ server for help in debugging upload problems). .. _pypirc: -The .pypirc file -================ +The ``.pypirc`` file +-------------------- -The format of the :file:`.pypirc` file is as follows:: +The :command:`register` and :command:`upload` commands both check for the +existence of a :file:`.pypirc` file at the location :file:`$HOME/.pypirc`. +If this file exists, the command uses the username, password, and repository +URL configured in the file. The format of a :file:`.pypirc` file is as +follows:: [distutils] index-servers = @@ -137,7 +173,7 @@ name of all sections describing a repository. Each section describing a repository defines three variables: - *repository*, that defines the url of the PyPI server. Defaults to - ``http://www.python.org/pypi``. + ``https://www.python.org/pypi``. - *username*, which is the registered username on the PyPI server. - *password*, that will be used to authenticate. If omitted the user will be prompt to type it when needed. @@ -156,19 +192,17 @@ listed in the *index-servers* variable:: password: <password> [other] - repository: http://example.com/pypi + repository: https://example.com/pypi username: <username> password: <password> -:command:`register` can then be called with the -r option to point the -repository to work with:: - - python setup.py register -r http://example.com/pypi +This allows the :command:`register` and :command:`upload` commands to be +called with the ``--repository`` option as described in +:ref:`package-cmdoptions`. -For convenience, the name of the section that describes the repository -may also be used:: - - python setup.py register -r other +Specifically, you might want to add the `PyPI Test Repository +<https://wiki.python.org/moin/TestPyPI>`_ to your ``.pypirc`` to facilitate +testing before doing your first upload to ``PyPI`` itself. .. _package-display: @@ -210,4 +244,4 @@ without warnings does not guarantee that PyPI will convert the content successfully. -.. _Python Package Index (PyPI): http://pypi.python.org/ +.. _Python Package Index (PyPI): https://pypi.python.org/pypi diff --git a/Doc/distutils/setupscript.rst b/Doc/distutils/setupscript.rst index ee96302ce1ee..914a34f1c891 100644 --- a/Doc/distutils/setupscript.rst +++ b/Doc/distutils/setupscript.rst @@ -28,7 +28,7 @@ the package into Python 1.5.2.) :: description='Python Distribution Utilities', author='Greg Ward', author_email='gward@python.net', - url='http://www.python.org/sigs/distutils-sig/', + url='https://www.python.org/sigs/distutils-sig/', packages=['distutils', 'distutils.command'], ) @@ -62,9 +62,9 @@ code instead of hardcoding path separators:: Listing whole packages ====================== -The :option:`packages` option tells the Distutils to process (build, distribute, +The ``packages`` option tells the Distutils to process (build, distribute, install, etc.) all pure Python modules found in each package mentioned in the -:option:`packages` list. In order to do this, of course, there has to be a +``packages`` list. In order to do this, of course, there has to be a correspondence between package names and directories in the filesystem. The default correspondence is the most obvious one, i.e. package :mod:`distutils` is found in the directory :file:`distutils` relative to the distribution root. @@ -75,7 +75,7 @@ the directory where your setup script lives. If you break this promise, the Distutils will issue a warning but still process the broken package anyway. If you use a different convention to lay out your source directory, that's no -problem: you just have to supply the :option:`package_dir` option to tell the +problem: you just have to supply the ``package_dir`` option to tell the Distutils about your convention. For example, say you keep all Python source under :file:`lib`, so that modules in the "root package" (i.e., not in any package at all) are in :file:`lib`, modules in the :mod:`foo` package are in @@ -94,13 +94,13 @@ written in the setup script as :: package_dir = {'foo': 'lib'} -A ``package: dir`` entry in the :option:`package_dir` dictionary implicitly +A ``package: dir`` entry in the ``package_dir`` dictionary implicitly applies to all packages below *package*, so the :mod:`foo.bar` case is automatically handled here. In this example, having ``packages = ['foo', 'foo.bar']`` tells the Distutils to look for :file:`lib/__init__.py` and -:file:`lib/bar/__init__.py`. (Keep in mind that although :option:`package_dir` +:file:`lib/bar/__init__.py`. (Keep in mind that although ``package_dir`` applies recursively, you must explicitly list all packages in -:option:`packages`: the Distutils will *not* recursively scan your source tree +``packages``: the Distutils will *not* recursively scan your source tree looking for any directory with an :file:`__init__.py` file.) @@ -120,7 +120,7 @@ This describes two modules, one of them in the "root" package, the other in the :mod:`pkg` package. Again, the default package/directory layout implies that these two modules can be found in :file:`mod1.py` and :file:`pkg/mod2.py`, and that :file:`pkg/__init__.py` exists as well. And again, you can override the -package/directory correspondence using the :option:`package_dir` option. +package/directory correspondence using the ``package_dir`` option. .. _describing-extensions: @@ -138,7 +138,7 @@ directories, libraries to link with, etc.). .. XXX read over this section All of this is done through another keyword argument to :func:`setup`, the -:option:`ext_modules` option. :option:`ext_modules` is just a list of +``ext_modules`` option. ``ext_modules`` is just a list of :class:`~distutils.core.Extension` instances, each of which describes a single extension module. Suppose your distribution includes a single extension, called :mod:`foo` and @@ -181,7 +181,7 @@ in the filesystem (and therefore where in Python's namespace hierarchy) the resulting extension lives. If you have a number of extensions all in the same package (or all under the -same base package), use the :option:`ext_package` keyword argument to +same base package), use the ``ext_package`` keyword argument to :func:`setup`. For example, :: setup(..., @@ -336,24 +336,24 @@ Other options There are still some other options which can be used to handle special cases. -The :option:`optional` option is a boolean; if it is true, +The ``optional`` option is a boolean; if it is true, a build failure in the extension will not abort the build process, but instead simply not install the failing extension. -The :option:`extra_objects` option is a list of object files to be passed to the +The ``extra_objects`` option is a list of object files to be passed to the linker. These files must not have extensions, as the default extension for the compiler is used. -:option:`extra_compile_args` and :option:`extra_link_args` can be used to +``extra_compile_args`` and ``extra_link_args`` can be used to specify additional command line options for the respective compiler and linker command lines. -:option:`export_symbols` is only useful on Windows. It can contain a list of +``export_symbols`` is only useful on Windows. It can contain a list of symbols (functions or variables) to be exported. This option is not needed when building compiled extensions: Distutils will automatically add ``initmodule`` to the list of exported symbols. -The :option:`depends` option is a list of files that the extension depends on +The ``depends`` option is a list of files that the extension depends on (for example header files). The build command will call the compiler on the sources to rebuild extension if any on this files has been modified since the previous build. @@ -449,7 +449,7 @@ to refer to the current interpreter location. By default, it is replaced with the current interpreter location. The :option:`--executable` (or :option:`-e`) option will allow the interpreter path to be explicitly overridden. -The :option:`scripts` option simply is a list of files to be handled in this +The ``scripts`` option simply is a list of files to be handled in this way. From the PyXML setup script:: setup(..., @@ -514,11 +514,11 @@ The corresponding call to :func:`setup` might be:: Installing Additional Files =========================== -The :option:`data_files` option can be used to specify additional files needed +The ``data_files`` option can be used to specify additional files needed by the module distribution: configuration files, message catalogs, data files, anything which doesn't fit in the previous categories. -:option:`data_files` specifies a sequence of (*directory*, *files*) pairs in the +``data_files`` specifies a sequence of (*directory*, *files*) pairs in the following way:: setup(..., @@ -539,7 +539,7 @@ modules). Each file name in *files* is interpreted relative to the directory information from *files* is used to determine the final location of the installed file; only the name of the file is used. -You can specify the :option:`data_files` options as a simple sequence of files +You can specify the ``data_files`` options as a simple sequence of files without specifying a target directory, but this is not recommended, and the :command:`install` command will print a warning in this case. To install data files directly in the target directory, an empty string should be given as the @@ -609,7 +609,7 @@ Notes: (4) These fields should not be used if your package is to be compatible with Python versions prior to 2.2.3 or 2.3. The list is available from the `PyPI website - <http://pypi.python.org/pypi>`_. + <https://pypi.python.org/pypi>`_. (5) The ``long_description`` field is used by PyPI when you are @@ -628,7 +628,7 @@ Notes: 'long string' Multiple lines of plain text in reStructuredText format (see - http://docutils.sf.net/). + http://docutils.sourceforge.net/). 'list of strings' See below. @@ -650,7 +650,7 @@ information is sometimes used to indicate sub-releases. These are 1.0.1a2 the second alpha release of the first patch version of 1.0 -:option:`classifiers` are specified in a Python list:: +``classifiers`` are specified in a Python list:: setup(..., classifiers=[ @@ -671,19 +671,7 @@ information is sometimes used to indicate sub-releases. These are ], ) -If you wish to include classifiers in your :file:`setup.py` file and also wish -to remain backwards-compatible with Python releases prior to 2.2.3, then you can -include the following code fragment in your :file:`setup.py` before the -:func:`setup` call. :: - - # patch distutils if it can't cope with the "classifiers" or - # "download_url" keywords - from sys import version - if version < '2.2.3': - from distutils.dist import DistributionMetadata - DistributionMetadata.classifiers = None - DistributionMetadata.download_url = None - +.. _debug-setup-script: Debugging the setup script ========================== @@ -700,7 +688,8 @@ installation is broken because they don't read all the way down to the bottom and see that it's a permission problem. On the other hand, this doesn't help the developer to find the cause of the -failure. For this purpose, the DISTUTILS_DEBUG environment variable can be set +failure. For this purpose, the :envvar:`DISTUTILS_DEBUG` environment variable can be set to anything except an empty string, and distutils will now print detailed -information what it is doing, and prints the full traceback in case an exception -occurs. +information about what it is doing, dump the full traceback when an exception +occurs, and print the whole command line when an external program (like a C +compiler) fails. diff --git a/Doc/distutils/sourcedist.rst b/Doc/distutils/sourcedist.rst index 9f7a38eda66d..fb70514b7909 100644 --- a/Doc/distutils/sourcedist.rst +++ b/Doc/distutils/sourcedist.rst @@ -32,12 +32,18 @@ to create a gzipped tarball and a zip file. The available formats are: | ``bztar`` | bzip2'ed tar file | | | | (:file:`.tar.bz2`) | | +-----------+-------------------------+---------+ +| ``xztar`` | xz'ed tar file | | +| | (:file:`.tar.xz`) | | ++-----------+-------------------------+---------+ | ``ztar`` | compressed tar file | \(4) | | | (:file:`.tar.Z`) | | +-----------+-------------------------+---------+ | ``tar`` | tar file (:file:`.tar`) | | +-----------+-------------------------+---------+ +.. versionchanged:: 3.5 + Added support for the ``xztar`` format. + Notes: (1) @@ -54,7 +60,7 @@ Notes: requires the :program:`compress` program. Notice that this format is now pending for deprecation and will be removed in the future versions of Python. -When using any ``tar`` format (``gztar``, ``bztar``, ``ztar`` or +When using any ``tar`` format (``gztar``, ``bztar``, ``xztar``, ``ztar`` or ``tar``), under Unix you can specify the ``owner`` and ``group`` names that will be set for each member of the archive. @@ -72,16 +78,16 @@ If you don't supply an explicit list of files (or instructions on how to generate one), the :command:`sdist` command puts a minimal default set into the source distribution: -* all Python source files implied by the :option:`py_modules` and - :option:`packages` options +* all Python source files implied by the ``py_modules`` and + ``packages`` options -* all C source files mentioned in the :option:`ext_modules` or - :option:`libraries` options ( +* all C source files mentioned in the ``ext_modules`` or + ``libraries`` options .. XXX getting C library sources currently broken---no :meth:`get_source_files` method in :file:`build_clib.py`! -* scripts identified by the :option:`scripts` option +* scripts identified by the ``scripts`` option See :ref:`distutils-installing-scripts`. * anything that looks like a test script: :file:`test/test\*.py` (currently, the @@ -167,7 +173,7 @@ source distribution: #. include all Python source files in the :file:`distutils` and :file:`distutils/command` subdirectories (because packages corresponding to - those two directories were mentioned in the :option:`packages` option in the + those two directories were mentioned in the ``packages`` option in the setup script---see section :ref:`setup-script`) #. include :file:`README.txt`, :file:`setup.py`, and :file:`setup.cfg` (standard diff --git a/Doc/extending/building.rst b/Doc/extending/building.rst index 08b0cc2ceda2..163179d68365 100644 --- a/Doc/extending/building.rst +++ b/Doc/extending/building.rst @@ -1,27 +1,58 @@ .. highlightlang:: c - .. _building: -******************************************** -Building C and C++ Extensions with distutils -******************************************** +***************************** +Building C and C++ Extensions +***************************** -.. sectionauthor:: Martin v. Löwis <martin@v.loewis.de> +A C extension for CPython is a shared library (e.g. a ``.so`` file on Linux, +``.pyd`` on Windows), which exports an *initialization function*. + +To be importable, the shared library must be available on :envvar:`PYTHONPATH`, +and must be named after the module name, with an appropriate extension. +When using distutils, the correct filename is generated automatically. + +The initialization function has the signature: + +.. c:function:: PyObject* PyInit_modulename(void) + +It returns either a fully-initialized module, or a :c:type:`PyModuleDef` +instance. See :ref:`initializing-modules` for details. + +.. highlightlang:: python +For modules with ASCII-only names, the function must be named +``PyInit_<modulename>``, with ``<modulename>`` replaced by the name of the +module. When using :ref:`multi-phase-initialization`, non-ASCII module names +are allowed. In this case, the initialization function name is +``PyInitU_<modulename>``, with ``<modulename>`` encoded using Python's +*punycode* encoding with hyphens replaced by underscores. In Python:: -Starting in Python 1.4, Python provides, on Unix, a special make file for -building make files for building dynamically-linked extensions and custom -interpreters. Starting with Python 2.0, this mechanism (known as related to -Makefile.pre.in, and Setup files) is no longer supported. Building custom -interpreters was rarely used, and extension modules can be built using -distutils. + def initfunc_name(name): + try: + suffix = b'_' + name.encode('ascii') + except UnicodeEncodeError: + suffix = b'U_' + name.encode('punycode').replace(b'-', b'_') + return b'PyInit' + suffix + +It is possible to export multiple modules from a single shared library by +defining multiple initialization functions. However, importing them requires +using symbolic links or a custom importer, because by default only the +function corresponding to the filename is found. +See :PEP:`489#multiple-modules-in-one-library` for details. + + +.. highlightlang:: c + +Building C and C++ Extensions with distutils +============================================ + +.. sectionauthor:: Martin v. Löwis <martin@v.loewis.de> -Building an extension module using distutils requires that distutils is -installed on the build machine, which is included in Python 2.x and available -separately for Python 1.5. Since distutils also supports creation of binary -packages, users don't necessarily need a compiler and distutils to install the -extension. +Extension modules can be built using distutils, which is included in Python. +Since distutils also supports creation of binary packages, users don't +necessarily need a compiler and distutils to install the extension. A distutils package contains a driver script, :file:`setup.py`. This is a plain Python file, which, in the most simple case, could look like this:: @@ -56,7 +87,7 @@ documentation in :ref:`distutils-index` to learn more about the features of distutils; this section explains building extension modules only. It is common to pre-compute arguments to :func:`setup`, to better structure the -driver script. In the example above, the\ ``ext_modules`` argument to +driver script. In the example above, the ``ext_modules`` argument to :func:`setup` is a list of extension modules, each of which is an instance of the :class:`~distutils.extension.Extension`. In the example, the instance defines an extension named ``demo`` which is build by compiling a single source @@ -81,7 +112,7 @@ example below. :: description = 'This is a demo package', author = 'Martin v. Loewis', author_email = 'martin@v.loewis.de', - url = 'http://docs.python.org/extending/building', + url = 'https://docs.python.org/extending/building', long_description = ''' This is really just a demo package. ''', diff --git a/Doc/extending/embedding.rst b/Doc/extending/embedding.rst index 6cb686ab096a..acd60aef8c81 100644 --- a/Doc/extending/embedding.rst +++ b/Doc/extending/embedding.rst @@ -58,12 +58,18 @@ perform some operation on a file. :: int main(int argc, char *argv[]) { - Py_SetProgramName(argv[0]); /* optional but recommended */ - Py_Initialize(); - PyRun_SimpleString("from time import time,ctime\n" - "print('Today is', ctime(time()))\n"); - Py_Finalize(); - return 0; + wchar_t *program = Py_DecodeLocale(argv[0], NULL); + if (program == NULL) { + fprintf(stderr, "Fatal error: cannot decode argv[0]\n"); + exit(1); + } + Py_SetProgramName(program); /* optional but recommended */ + Py_Initialize(); + PyRun_SimpleString("from time import time,ctime\n" + "print('Today is', ctime(time()))\n"); + Py_Finalize(); + PyMem_RawFree(program); + return 0; } The :c:func:`Py_SetProgramName` function should be called before @@ -160,7 +166,7 @@ for data conversion between Python and C, and for error reporting. The interesting part with respect to embedding Python starts with :: Py_Initialize(); - pName = PyUnicode_FromString(argv[1]); + pName = PyUnicode_DecodeFSDefault(argv[1]); /* Error checking of pName left out */ pModule = PyImport_Import(pName); diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst index a3bf2656ed84..8cc41840d7c8 100644 --- a/Doc/extending/extending.rst +++ b/Doc/extending/extending.rst @@ -20,12 +20,17 @@ source file by including the header ``"Python.h"``. The compilation of an extension module depends on its intended use as well as on your system setup; details are given in later chapters. -Do note that if your use case is calling C library functions or system calls, -you should consider using the :mod:`ctypes` module rather than writing custom -C code. Not only does :mod:`ctypes` let you write Python code to interface -with C code, but it is more portable between implementations of Python than -writing and compiling an extension module which typically ties you to CPython. +.. note:: + The C extension interface is specific to CPython, and extension modules do + not work on other Python implementations. In many cases, it is possible to + avoid writing C extensions and preserve portability to other implementations. + For example, if your use case is calling C library functions or system calls, + you should consider using the :mod:`ctypes` module or the `cffi + <http://cffi.readthedocs.org>`_ library rather than writing custom C code. + These modules let you write Python code to interface with C code and are more + portable between implementations of Python than writing and compiling a C + extension module. .. _extending-simpleexample: @@ -370,11 +375,17 @@ optionally followed by an import of the module:: int main(int argc, char *argv[]) { + wchar_t *program = Py_DecodeLocale(argv[0], NULL); + if (program == NULL) { + fprintf(stderr, "Fatal error: cannot decode argv[0]\n"); + exit(1); + } + /* Add a built-in module, before Py_Initialize */ PyImport_AppendInittab("spam", PyInit_spam); /* Pass argv[0] to the Python interpreter */ - Py_SetProgramName(argv[0]); + Py_SetProgramName(program); /* Initialize the Python interpreter. Required. */ Py_Initialize(); @@ -386,6 +397,10 @@ optionally followed by an import of the module:: ... + PyMem_RawFree(program); + return 0; + } + .. note:: Removing entries from ``sys.modules`` or importing compiled modules into @@ -398,6 +413,13 @@ A more substantial example module is included in the Python source distribution as :file:`Modules/xxmodule.c`. This file may be used as a template or simply read as an example. +.. note:: + + Unlike our ``spam`` example, ``xxmodule`` uses *multi-phase initialization* + (new in Python 3.5), where a PyModuleDef structure is returned from + ``PyInit_spam``, and creation of the module is left to the import machinery. + For details on multi-phase initialization, see :PEP:`489`. + .. _compilation: @@ -585,7 +607,7 @@ Extracting Parameters in Extension Functions The :c:func:`PyArg_ParseTuple` function is declared as follows:: - int PyArg_ParseTuple(PyObject *arg, char *format, ...); + int PyArg_ParseTuple(PyObject *arg, const char *format, ...); The *arg* argument must be a tuple object containing an argument list passed from Python to a C function. The *format* argument must be a format string, @@ -678,7 +700,7 @@ Keyword Parameters for Extension Functions The :c:func:`PyArg_ParseTupleAndKeywords` function is declared as follows:: int PyArg_ParseTupleAndKeywords(PyObject *arg, PyObject *kwdict, - char *format, char *kwlist[], ...); + const char *format, char *kwlist[], ...); The *arg* and *format* parameters are identical to those of the :c:func:`PyArg_ParseTuple` function. The *kwdict* parameter is the dictionary of @@ -755,7 +777,7 @@ Building Arbitrary Values This function is the counterpart to :c:func:`PyArg_ParseTuple`. It is declared as follows:: - PyObject *Py_BuildValue(char *format, ...); + PyObject *Py_BuildValue(const char *format, ...); It recognizes a set of format units similar to the ones recognized by :c:func:`PyArg_ParseTuple`, but the arguments (which are input to the function, @@ -857,11 +879,8 @@ reclaim the memory belonging to any objects in a reference cycle, or referenced from the objects in the cycle, even though there are no further references to the cycle itself. -The cycle detector is able to detect garbage cycles and can reclaim them so long -as there are no finalizers implemented in Python (:meth:`__del__` methods). -When there are such finalizers, the detector exposes the cycles through the -:mod:`gc` module (specifically, the :attr:`~gc.garbage` variable in that module). -The :mod:`gc` module also exposes a way to run the detector (the +The cycle detector is able to detect garbage cycles and can reclaim them. +The :mod:`gc` module exposes a way to run the detector (the :func:`~gc.collect` function), as well as configuration interfaces and the ability to disable the detector at runtime. The cycle detector is considered an optional component; though it is included by default, diff --git a/Doc/extending/index.rst b/Doc/extending/index.rst index 611294399585..dd4392645023 100644 --- a/Doc/extending/index.rst +++ b/Doc/extending/index.rst @@ -21,6 +21,32 @@ Python) that give the language its wide application range. For a detailed description of the whole Python/C API, see the separate :ref:`c-api-index`. + +Recommended third party tools +============================= + +This guide only covers the basic tools for creating extensions provided +as part of this version of CPython. Third party tools like Cython, +``cffi``, SWIG and Numba offer both simpler and more sophisticated +approaches to creating C and C++ extensions for Python. + +.. seealso:: + + `Python Packaging User Guide: Binary Extensions <https://packaging.python.org/en/latest/extensions.html>`_ + The Python Packaging User Guide not only covers several available + tools that simplify the creation of binary extensions, but also + discusses the various reasons why creating an extension module may be + desirable in the first place. + + +Creating extensions without third party tools +============================================= + +This section of the guide covers creating C and C++ extensions without +assistance from third party tools. It is intended primarily for creators +of those tools, rather than being a recommended way to create your own +C extensions. + .. toctree:: :maxdepth: 2 :numbered: @@ -29,4 +55,17 @@ For a detailed description of the whole Python/C API, see the separate newtypes.rst building.rst windows.rst + +Embedding the CPython runtime in a larger application +===================================================== + +Sometimes, rather than creating an extension that runs inside the Python +interpreter as the main application, it is desirable to instead embed +the CPython runtime inside a larger application. This section covers +some of the details involved in doing that successfully. + +.. toctree:: + :maxdepth: 2 + :numbered: + embedding.rst diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst index 45b57211b679..f60e208e8660 100644 --- a/Doc/extending/newtypes.rst +++ b/Doc/extending/newtypes.rst @@ -80,7 +80,7 @@ Moving on, we come to the crunch --- the type object. :: 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -383,7 +383,8 @@ is used to initialize an object after it's created. Unlike the new method, we can't guarantee that the initializer is called. The initializer isn't called when unpickling objects and it can be overridden. Our initializer accepts arguments to provide initial values for our instance. Initializers always accept -positional and keyword arguments. +positional and keyword arguments. Initializers should return either 0 on +success or -1 on error. Initializers can be called multiple times. Anyone can call the :meth:`__init__` method on our objects. For this reason, we have to be extra careful when @@ -892,20 +893,20 @@ fields in the right order! It's often easiest to find an example that includes all the fields you need (even if they're initialized to ``0``) and then change the values to suit your new type. :: - char *tp_name; /* For printing */ + const char *tp_name; /* For printing */ The name of the type - as mentioned in the last section, this will appear in various places, almost entirely for diagnostic purposes. Try to choose something that will be helpful in such a situation! :: - int tp_basicsize, tp_itemsize; /* For allocation */ + Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */ These fields tell the runtime how much memory to allocate when new objects of this type are created. Python has some built-in support for variable length structures (think: strings, lists) which is where the :c:member:`~PyTypeObject.tp_itemsize` field comes in. This will be dealt with later. :: - char *tp_doc; + const char *tp_doc; Here you can put a string (or its address) that you want returned when the Python script references ``obj.__doc__`` to retrieve the doc string. @@ -1205,7 +1206,7 @@ Here is an example:: { if (strcmp(name, "data") == 0) { - return PyInt_FromLong(obj->data); + return PyLong_FromLong(obj->data); } PyErr_Format(PyExc_AttributeError, diff --git a/Doc/extending/windows.rst b/Doc/extending/windows.rst index 3fd5e576de0e..67bdd475aeb6 100644 --- a/Doc/extending/windows.rst +++ b/Doc/extending/windows.rst @@ -37,150 +37,9 @@ There are two approaches to building extension modules on Windows, just as there are on Unix: use the :mod:`distutils` package to control the build process, or do things manually. The distutils approach works well for most extensions; documentation on using :mod:`distutils` to build and package extension modules -is available in :ref:`distutils-index`. This section describes the manual -approach to building Python extensions written in C or C++. - -To build extensions using these instructions, you need to have a copy of the -Python sources of the same version as your installed Python. You will need -Microsoft Visual C++ "Developer Studio"; project files are supplied for VC++ -version 7.1, but you can use older versions of VC++. Notice that you should use -the same version of VC++that was used to build Python itself. The example files -described here are distributed with the Python sources in the -:file:`PC\\example_nt\\` directory. - -#. **Copy the example files** --- The :file:`example_nt` directory is a - subdirectory of the :file:`PC` directory, in order to keep all the PC-specific - files under the same directory in the source distribution. However, the - :file:`example_nt` directory can't actually be used from this location. You - first need to copy or move it up one level, so that :file:`example_nt` is a - sibling of the :file:`PC` and :file:`Include` directories. Do all your work - from within this new location. - -#. **Open the project** --- From VC++, use the :menuselection:`File --> Open - Solution` dialog (not :menuselection:`File --> Open`!). Navigate to and select - the file :file:`example.sln`, in the *copy* of the :file:`example_nt` directory - you made above. Click Open. - -#. **Build the example DLL** --- In order to check that everything is set up - right, try building: - -#. Select a configuration. This step is optional. Choose - :menuselection:`Build --> Configuration Manager --> Active Solution Configuration` - and select either :guilabel:`Release` or :guilabel:`Debug`. If you skip this - step, VC++ will use the Debug configuration by default. - -#. Build the DLL. Choose :menuselection:`Build --> Build Solution`. This - creates all intermediate and result files in a subdirectory called either - :file:`Debug` or :file:`Release`, depending on which configuration you selected - in the preceding step. - -#. **Testing the debug-mode DLL** --- Once the Debug build has succeeded, bring - up a DOS box, and change to the :file:`example_nt\\Debug` directory. You should - now be able to repeat the following session (``C>`` is the DOS prompt, ``>>>`` - is the Python prompt; note that build information and various debug output from - Python may not match this screen dump exactly):: - - C>..\..\PCbuild\python_d - Adding parser accelerators ... - Done. - Python 2.2 (#28, Dec 19 2001, 23:26:37) [MSC 32 bit (Intel)] on win32 - Type "copyright", "credits" or "license" for more information. - >>> import example - [4897 refs] - >>> example.foo() - Hello, world - [4903 refs] - >>> - - Congratulations! You've successfully built your first Python extension module. - -#. **Creating your own project** --- Choose a name and create a directory for - it. Copy your C sources into it. Note that the module source file name does - not necessarily have to match the module name, but the name of the - initialization function should match the module name --- you can only import a - module :mod:`spam` if its initialization function is called :c:func:`initspam`, - and it should call :c:func:`Py_InitModule` with the string ``"spam"`` as its - first argument (use the minimal :file:`example.c` in this directory as a guide). - By convention, it lives in a file called :file:`spam.c` or :file:`spammodule.c`. - The output file should be called :file:`spam.pyd` (in Release mode) or - :file:`spam_d.pyd` (in Debug mode). The extension :file:`.pyd` was chosen - to avoid confusion with a system library :file:`spam.dll` to which your module - could be a Python interface. - - Now your options are: - -#. Copy :file:`example.sln` and :file:`example.vcproj`, rename them to - :file:`spam.\*`, and edit them by hand, or - -#. Create a brand new project; instructions are below. - - In either case, copy :file:`example_nt\\example.def` to :file:`spam\\spam.def`, - and edit the new :file:`spam.def` so its second line contains the string - '``initspam``'. If you created a new project yourself, add the file - :file:`spam.def` to the project now. (This is an annoying little file with only - two lines. An alternative approach is to forget about the :file:`.def` file, - and add the option :option:`/export:initspam` somewhere to the Link settings, by - manually editing the setting in Project Properties dialog). - -#. **Creating a brand new project** --- Use the :menuselection:`File --> New - --> Project` dialog to create a new Project Workspace. Select :guilabel:`Visual - C++ Projects/Win32/ Win32 Project`, enter the name (``spam``), and make sure the - Location is set to parent of the :file:`spam` directory you have created (which - should be a direct subdirectory of the Python build tree, a sibling of - :file:`Include` and :file:`PC`). Select Win32 as the platform (in my version, - this is the only choice). Make sure the Create new workspace radio button is - selected. Click OK. - - You should now create the file :file:`spam.def` as instructed in the previous - section. Add the source files to the project, using :menuselection:`Project --> - Add Existing Item`. Set the pattern to ``*.*`` and select both :file:`spam.c` - and :file:`spam.def` and click OK. (Inserting them one by one is fine too.) - - Now open the :menuselection:`Project --> spam properties` dialog. You only need - to change a few settings. Make sure :guilabel:`All Configurations` is selected - from the :guilabel:`Settings for:` dropdown list. Select the C/C++ tab. Choose - the General category in the popup menu at the top. Type the following text in - the entry box labeled :guilabel:`Additional Include Directories`:: - - ..\Include,..\PC - - Then, choose the General category in the Linker tab, and enter :: - - ..\PCbuild - - in the text box labelled :guilabel:`Additional library Directories`. - - Now you need to add some mode-specific settings: - - Select :guilabel:`Release` in the :guilabel:`Configuration` dropdown list. - Choose the :guilabel:`Link` tab, choose the :guilabel:`Input` category, and - append ``pythonXY.lib`` to the list in the :guilabel:`Additional Dependencies` - box. - - Select :guilabel:`Debug` in the :guilabel:`Configuration` dropdown list, and - append ``pythonXY_d.lib`` to the list in the :guilabel:`Additional Dependencies` - box. Then click the C/C++ tab, select :guilabel:`Code Generation`, and select - :guilabel:`Multi-threaded Debug DLL` from the :guilabel:`Runtime library` - dropdown list. - - Select :guilabel:`Release` again from the :guilabel:`Configuration` dropdown - list. Select :guilabel:`Multi-threaded DLL` from the :guilabel:`Runtime - library` dropdown list. - -If your module creates a new type, you may have trouble with this line:: - - PyVarObject_HEAD_INIT(&PyType_Type, 0) - -Static type object initializers in extension modules may cause -compiles to fail with an error message like "initializer not a -constant". This shows up when building DLL under MSVC. Change it to:: - - PyVarObject_HEAD_INIT(NULL, 0) - -and add the following to the module initialization function:: - - if (PyType_Ready(&MyObject_Type) < 0) - return NULL; +is available in :ref:`distutils-index`. If you find you really need to do +things manually, it may be instructive to study the project file for the +:source:`winsound <PCbuild/winsound.vcxproj>` standard library module. .. _dynamic-linking: diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst index 49e0c6d7deb8..9fdf8cb94981 100644 --- a/Doc/faq/design.rst +++ b/Doc/faq/design.rst @@ -49,7 +49,7 @@ Why are floating-point calculations so inaccurate? Users are often surprised by results like this:: >>> 1.2 - 1.0 - 0.199999999999999996 + 0.19999999999999996 and think it is a bug in Python. It's not. This has little to do with Python, and much more to do with how the underlying platform handles floating-point @@ -368,9 +368,9 @@ Can Python be compiled to machine code, C or some other language? Practical answer: -`Cython <http://cython.org/>`_ and `Pyrex <http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/>`_ +`Cython <http://cython.org/>`_ and `Pyrex <http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/>`_ compile a modified version of Python with optional annotations into C -extensions. `Weave <http://www.scipy.org/Weave>`_ makes it easy to +extensions. `Weave <http://docs.scipy.org/doc/scipy-dev/reference/tutorial/weave.html>`_ makes it easy to intermingle Python and C code in various ways to increase performance. `Nuitka <http://www.nuitka.net/>`_ is an up-and-coming compiler of Python into C++ code, aiming to support the full Python language. @@ -386,13 +386,13 @@ mostly of calls into the Python run-time system, even for seemingly simple operations like ``x+1``. Several projects described in the Python newsgroup or at past `Python -conferences <http://python.org/community/workshops/>`_ have shown that this +conferences <https://www.python.org/community/workshops/>`_ have shown that this approach is feasible, although the speedups reached so far are only modest (e.g. 2x). Jython uses the same strategy for compiling to Java bytecode. (Jim Hugunin has demonstrated that in combination with whole-program analysis, speedups of 1000x are feasible for small demo programs. See the proceedings from the `1997 Python conference -<http://python.org/workshops/1997-10/proceedings/>`_ for more information.) +<http://legacy.python.org/workshops/1997-10/proceedings/>`_ for more information.) How does Python manage memory? @@ -664,62 +664,6 @@ before you write any of the actual code. Of course Python allows you to be sloppy and not write test cases at all. -Why are default values shared between objects? ----------------------------------------------- - -This type of bug commonly bites neophyte programmers. Consider this function:: - - def foo(mydict={}): # Danger: shared reference to one dict for all calls - ... compute something ... - mydict[key] = value - return mydict - -The first time you call this function, ``mydict`` contains a single item. The -second time, ``mydict`` contains two items because when ``foo()`` begins -executing, ``mydict`` starts out with an item already in it. - -It is often expected that a function call creates new objects for default -values. This is not what happens. Default values are created exactly once, when -the function is defined. If that object is changed, like the dictionary in this -example, subsequent calls to the function will refer to this changed object. - -By definition, immutable objects such as numbers, strings, tuples, and ``None``, -are safe from change. Changes to mutable objects such as dictionaries, lists, -and class instances can lead to confusion. - -Because of this feature, it is good programming practice to not use mutable -objects as default values. Instead, use ``None`` as the default value and -inside the function, check if the parameter is ``None`` and create a new -list/dictionary/whatever if it is. For example, don't write:: - - def foo(mydict={}): - ... - -but:: - - def foo(mydict=None): - if mydict is None: - mydict = {} # create a new dict for local namespace - -This feature can be useful. When you have a function that's time-consuming to -compute, a common technique is to cache the parameters and the resulting value -of each call to the function, and return the cached value if the same value is -requested again. This is called "memoizing", and can be implemented like this:: - - # Callers will never provide a third parameter for this function. - def expensive(arg1, arg2, _cache={}): - if (arg1, arg2) in _cache: - return _cache[(arg1, arg2)] - - # Calculate the value - result = ... expensive computation ... - _cache[(arg1, arg2)] = result # Store result in the cache - return result - -You could use a global variable containing a dictionary instead of the default -value; it's a matter of taste. - - Why is there no goto? --------------------- diff --git a/Doc/faq/extending.rst b/Doc/faq/extending.rst index a9a234b1ecae..7bb4dc2e6088 100644 --- a/Doc/faq/extending.rst +++ b/Doc/faq/extending.rst @@ -42,7 +42,7 @@ on what you're trying to do. .. XXX make sure these all work `Cython <http://cython.org>`_ and its relative `Pyrex -<http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/>`_ are compilers +<http://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/>`_ are compilers that accept a slightly modified form of Python and generate the corresponding C code. Cython and Pyrex make it possible to write an extension without having to learn Python's C API. @@ -50,11 +50,11 @@ to learn Python's C API. If you need to interface to some C or C++ library for which no Python extension currently exists, you can try wrapping the library's data types and functions with a tool such as `SWIG <http://www.swig.org>`_. `SIP -<http://www.riverbankcomputing.co.uk/software/sip/>`__, `CXX +<http://www.riverbankcomputing.co.uk/software/sip/intro>`__, `CXX <http://cxx.sourceforge.net/>`_ `Boost <http://www.boost.org/libs/python/doc/index.html>`_, or `Weave -<http://www.scipy.org/Weave>`_ are also alternatives for wrapping -C++ libraries. +<http://docs.scipy.org/doc/scipy-dev/reference/tutorial/weave.html>`_ are also +alternatives for wrapping C++ libraries. How can I execute arbitrary Python statements from C? @@ -95,8 +95,8 @@ To test the type of an object, first make sure it isn't *NULL*, and then use There is also a high-level API to Python objects which is provided by the so-called 'abstract' interface -- read ``Include/abstract.h`` for further details. It allows interfacing with any kind of Python sequence using calls -like :c:func:`PySequence_Length`, :c:func:`PySequence_GetItem`, etc.) as well -as many other useful protocols such as numbers (:c:func:`PyNumber_Index` et. +like :c:func:`PySequence_Length`, :c:func:`PySequence_GetItem`, etc. as well +as many other useful protocols such as numbers (:c:func:`PyNumber_Index` et al.) and mappings in the PyMapping APIs. @@ -115,8 +115,8 @@ call, a format string like that used with :c:func:`Py_BuildValue`, and the argument values:: PyObject * - PyObject_CallMethod(PyObject *object, char *method_name, - char *arg_format, ...); + PyObject_CallMethod(PyObject *object, const char *method_name, + const char *arg_format, ...); This works for any object that has methods -- whether built-in or user-defined. You are responsible for eventually :c:func:`Py_DECREF`\ 'ing the return value. @@ -348,7 +348,7 @@ complete example using the GNU readline library (you may want to ignore { line = readline (prompt); - if (NULL == line) /* CTRL-D pressed */ + if (NULL == line) /* Ctrl-D pressed */ { done = 1; } @@ -443,8 +443,8 @@ extension module using g++ (e.g., ``g++ -shared -o mymodule.so mymodule.o``). Can I create an object class with some methods implemented in C and others in Python (e.g. through inheritance)? ---------------------------------------------------------------------------------------------------------------- -In Python 2.2, you can inherit from built-in classes such as :class:`int`, -:class:`list`, :class:`dict`, etc. +Yes, you can inherit from built-in classes such as :class:`int`, :class:`list`, +:class:`dict`, etc. The Boost Python Library (BPL, http://www.boost.org/libs/python/doc/index.html) provides a way of doing this from C++ (i.e. you can inherit from an extension diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst index 9a893eca2f13..2221f1492739 100644 --- a/Doc/faq/general.rst +++ b/Doc/faq/general.rst @@ -25,7 +25,7 @@ Finally, Python is portable: it runs on many Unix variants, on the Mac, and on Windows 2000 and later. To find out more, start with :ref:`tutorial-index`. The `Beginner's Guide to -Python <http://wiki.python.org/moin/BeginnersGuide>`_ links to other +Python <https://wiki.python.org/moin/BeginnersGuide>`_ links to other introductory tutorials and resources for learning Python. @@ -36,11 +36,11 @@ The Python Software Foundation is an independent non-profit organization that holds the copyright on Python versions 2.1 and newer. The PSF's mission is to advance open source technology related to the Python programming language and to publicize the use of Python. The PSF's home page is at -http://www.python.org/psf/. +https://www.python.org/psf/. Donations to the PSF are tax-exempt in the US. If you use Python and find it helpful, please contribute via `the PSF donation page -<http://www.python.org/psf/donations/>`_. +<https://www.python.org/psf/donations/>`_. Are there copyright restrictions on the use of Python? @@ -53,12 +53,12 @@ commercial use, to sell copies of Python in source or binary form (modified or unmodified), or to sell products that incorporate Python in some form. We would still like to know about all commercial use of Python, of course. -See `the PSF license page <http://python.org/psf/license/>`_ to find further +See `the PSF license page <https://www.python.org/psf/license/>`_ to find further explanations and a link to the full text of the license. The Python logo is trademarked, and in certain cases permission is required to use it. Consult `the Trademark Usage Policy -<http://www.python.org/psf/trademarks/>`__ for more information. +<https://www.python.org/psf/trademarks/>`__ for more information. Why was Python created in the first place? @@ -117,7 +117,7 @@ programming), software engineering (unit testing, logging, profiling, parsing Python code), and operating system interfaces (system calls, filesystems, TCP/IP sockets). Look at the table of contents for :ref:`library-index` to get an idea of what's available. A wide variety of third-party extensions are also -available. Consult `the Python Package Index <http://pypi.python.org/pypi>`_ to +available. Consult `the Python Package Index <https://pypi.python.org/pypi>`_ to find packages of interest to you. @@ -151,23 +151,24 @@ after a final minor release is made, the Subversion trunk is incremented to the next minor version, which becomes the "a0" version, e.g. "2.4a0". -See also the documentation for ``sys.version``, ``sys.hexversion``, and -``sys.version_info``. +See also the documentation for :data:`sys.version`, :data:`sys.hexversion`, and +:data:`sys.version_info`. How do I obtain a copy of the Python source? -------------------------------------------- The latest Python source distribution is always available from python.org, at -http://www.python.org/download/. The latest development sources can be obtained -via anonymous Mercurial access at http://hg.python.org/cpython. +https://www.python.org/download/. The latest development sources can be obtained +via anonymous Mercurial access at https://hg.python.org/cpython. The source distribution is a gzipped tar file containing the complete C source, Sphinx-formatted documentation, Python library modules, example programs, and several useful pieces of freely distributable software. The source will compile and run out of the box on most UNIX platforms. -Consult the `Developer FAQ <http://docs.python.org/devguide/faq>`__ for more +Consult the `Getting Started section of the Python Developer's Guide +<https://docs.python.org/devguide/setup.html>`__ for more information on getting the source code and compiling it. @@ -177,12 +178,12 @@ How do I get documentation on Python? .. XXX mention py3k The standard documentation for the current stable version of Python is available -at http://docs.python.org/. PDF, plain text, and downloadable HTML versions are -also available at http://docs.python.org/download.html. +at https://docs.python.org/3/. PDF, plain text, and downloadable HTML versions are +also available at https://docs.python.org/3/download.html. The documentation is written in reStructuredText and processed by `the Sphinx -documentation tool <http://sphinx.pocoo.org/>`__. The reStructuredText source -for the documentation is part of the Python source distribution. +documentation tool <http://sphinx-doc.org/>`__. The reStructuredText source for +the documentation is part of the Python source distribution. I've never programmed before. Is there a Python tutorial? @@ -191,7 +192,7 @@ I've never programmed before. Is there a Python tutorial? There are numerous tutorials and books available. The standard documentation includes :ref:`tutorial-index`. -Consult `the Beginner's Guide <http://wiki.python.org/moin/BeginnersGuide>`_ to +Consult `the Beginner's Guide <https://wiki.python.org/moin/BeginnersGuide>`_ to find information for beginning Python programmers, including lists of tutorials. @@ -199,7 +200,7 @@ Is there a newsgroup or mailing list devoted to Python? ------------------------------------------------------- There is a newsgroup, :newsgroup:`comp.lang.python`, and a mailing list, -`python-list <http://mail.python.org/mailman/listinfo/python-list>`_. The +`python-list <https://mail.python.org/mailman/listinfo/python-list>`_. The newsgroup and mailing list are gatewayed into each other -- if you can read news it's unnecessary to subscribe to the mailing list. :newsgroup:`comp.lang.python` is high-traffic, receiving hundreds of postings @@ -208,38 +209,38 @@ every day, and Usenet readers are often more able to cope with this volume. Announcements of new software releases and events can be found in comp.lang.python.announce, a low-traffic moderated list that receives about five postings per day. It's available as `the python-announce mailing list -<http://mail.python.org/mailman/listinfo/python-announce-list>`_. +<https://mail.python.org/mailman/listinfo/python-announce-list>`_. More info about other mailing lists and newsgroups -can be found at http://www.python.org/community/lists/. +can be found at https://www.python.org/community/lists/. How do I get a beta test version of Python? ------------------------------------------- -Alpha and beta releases are available from http://www.python.org/download/. All +Alpha and beta releases are available from https://www.python.org/download/. All releases are announced on the comp.lang.python and comp.lang.python.announce -newsgroups and on the Python home page at http://www.python.org/; an RSS feed of +newsgroups and on the Python home page at https://www.python.org/; an RSS feed of news is available. -You can also access the development version of Python through Subversion. See -http://docs.python.org/devguide/faq for details. +You can also access the development version of Python through Mercurial. See +https://docs.python.org/devguide/faq.html for details. How do I submit bug reports and patches for Python? --------------------------------------------------- To report a bug or submit a patch, please use the Roundup installation at -http://bugs.python.org/. +https://bugs.python.org/. You must have a Roundup account to report bugs; this makes it possible for us to contact you if we have follow-up questions. It will also enable Roundup to send you updates as we act on your bug. If you had previously used SourceForge to report bugs to Python, you can obtain your Roundup password through Roundup's -`password reset procedure <http://bugs.python.org/user?@template=forgotten>`_. +`password reset procedure <https://bugs.python.org/user?@template=forgotten>`_. For more information on how Python is developed, consult `the Python Developer's -Guide <http://docs.python.org/devguide/>`_. +Guide <https://docs.python.org/devguide/>`_. Are there any published articles about Python that I can reference? @@ -259,7 +260,7 @@ Are there any books on Python? ------------------------------ Yes, there are many, and more are being published. See the python.org wiki at -http://wiki.python.org/moin/PythonBooks for a list. +https://wiki.python.org/moin/PythonBooks for a list. You can also search online bookstores for "Python" and filter out the Monty Python references; or perhaps search for "Python" and "language". @@ -268,9 +269,14 @@ Python references; or perhaps search for "Python" and "language". Where in the world is www.python.org located? --------------------------------------------- -It's currently in Amsterdam, graciously hosted by `XS4ALL -<http://www.xs4all.nl>`_. Thanks to Thomas Wouters for his work in arranging -python.org's hosting. +The Python project's infrastructure is located all over the world. +`www.python.org <https://www.python.org>`_ is graciously hosted by `Rackspace +<http://www.rackspace.com>`_, with CDN caching provided by `Fastly +<https://www.fastly.com>`_. `Upfront Systems +<http://www.upfrontsystems.co.za>`_ hosts `bugs.python.org +<https://bugs.python.org>`_. Many other Python services like `the Wiki +<https://wiki.python.org>`_ are hosted by `Oregon State +University Open Source Lab <https://osuosl.org>`_. Why is it called Python? @@ -278,7 +284,7 @@ Why is it called Python? When he began implementing Python, Guido van Rossum was also reading the published scripts from `"Monty Python's Flying Circus" -<http://pythonline.com/>`__, a BBC comedy series from the 1970s. Van Rossum +<http://en.wikipedia.org/wiki/Monty_Python>`__, a BBC comedy series from the 1970s. Van Rossum thought he needed a name that was short, unique, and slightly mysterious, so he decided to call the language Python. @@ -307,7 +313,7 @@ guaranteed that interfaces will remain the same throughout a series of bugfix releases. The latest stable releases can always be found on the `Python download page -<http://python.org/download/>`_. There are two recommended production-ready +<https://www.python.org/download/>`_. There are two recommended production-ready versions at this point in time, because at the moment there are two branches of stable releases: 2.x and 3.x. Python 3.x may be less useful than 2.x, since currently there is more third party software available for Python 2 than for @@ -331,9 +337,9 @@ the group or even read it. Have any significant projects been done in Python? -------------------------------------------------- -See http://python.org/about/success for a list of projects that use Python. +See https://www.python.org/about/success for a list of projects that use Python. Consulting the proceedings for `past Python conferences -<http://python.org/community/workshops/>`_ will reveal contributions from many +<https://www.python.org/community/workshops/>`_ will reveal contributions from many different companies and organizations. High-profile Python projects include `the Mailman mailing list manager @@ -347,14 +353,14 @@ include Google, Yahoo, and Lucasfilm Ltd. What new developments are expected for Python in the future? ------------------------------------------------------------ -See http://www.python.org/dev/peps/ for the Python Enhancement Proposals +See https://www.python.org/dev/peps/ for the Python Enhancement Proposals (PEPs). PEPs are design documents describing a suggested new feature for Python, providing a concise technical specification and a rationale. Look for a PEP titled "Python X.Y Release Schedule", where X.Y is a version that hasn't been publicly released yet. New development is discussed on `the python-dev mailing list -<http://mail.python.org/mailman/listinfo/python-dev/>`_. +<https://mail.python.org/mailman/listinfo/python-dev/>`_. Is it reasonable to propose incompatible changes to Python? @@ -372,43 +378,6 @@ Providing a gradual upgrade path is necessary if a feature has to be changed. changes while minimizing disruption for users. -Is Python Y2K (Year 2000) Compliant? ------------------------------------- - -.. remove this question? - -As of August, 2003 no major problems have been reported and Y2K compliance seems -to be a non-issue. - -Python does very few date calculations and for those it does perform relies on -the C library functions. Python generally represents times either as seconds -since 1970 or as a ``(year, month, day, ...)`` tuple where the year is expressed -with four digits, which makes Y2K bugs unlikely. So as long as your C library -is okay, Python should be okay. Of course, it's possible that a particular -application written in Python makes assumptions about 2-digit years. - -Because Python is available free of charge, there are no absolute guarantees. -If there *are* unforeseen problems, liability is the user's problem rather than -the developers', and there is nobody you can sue for damages. The Python -copyright notice contains the following disclaimer: - - 4. PSF is making Python 2.3 available to Licensee on an "AS IS" - basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY - WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY - REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR - PURPOSE OR THAT THE USE OF PYTHON 2.3 WILL NOT INFRINGE ANY THIRD PARTY - RIGHTS. - - 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON - 2.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS - A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.3, - OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. - -The good news is that *if* you encounter a problem, you have full source -available to track it down and fix it. This is one advantage of an open source -programming environment. - - Is Python a good language for beginning programmers? ---------------------------------------------------- @@ -447,14 +416,25 @@ while they enter their program's source in another window. If they can't remember the methods for a list, they can do something like this:: >>> L = [] - >>> dir(L) - ['append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', + >>> dir(L) # doctest: +NORMALIZE_WHITESPACE + ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', + '__dir__', '__doc__', '__eq__', '__format__', '__ge__', + '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', + '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', + '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', + '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', + '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', + 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] + >>> [d for d in dir(L) if '__' not in d] + ['append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] + >>> help(L.append) Help on built-in function append: - + <BLANKLINE> append(...) - L.append(object) -- append object to end + L.append(object) -> None -- append object to end + <BLANKLINE> >>> L.append(1) >>> L [1] @@ -467,8 +447,9 @@ that is written in Python using Tkinter. PythonWin is a Windows-specific IDE. Emacs users will be happy to know that there is a very good Python mode for Emacs. All of these programming environments provide syntax highlighting, auto-indenting, and access to the interactive interpreter while coding. Consult -http://www.python.org/editors/ for a full list of Python editing environments. +`the Python wiki <https://wiki.python.org/moin/PythonEditors>`_ for a full list +of Python editing environments. If you want to discuss Python's use in education, you may be interested in joining `the edu-sig mailing list -<http://python.org/community/sigs/current/edu-sig>`_. +<https://www.python.org/community/sigs/current/edu-sig>`_. diff --git a/Doc/faq/gui.rst b/Doc/faq/gui.rst index 5827f28c3bdc..5122de1c1a99 100644 --- a/Doc/faq/gui.rst +++ b/Doc/faq/gui.rst @@ -29,17 +29,17 @@ Tkinter Standard builds of Python include an object-oriented interface to the Tcl/Tk widget set, called :ref:`tkinter <Tkinter>`. This is probably the easiest to install (since it comes included with most -`binary distributions <http://www.python.org/download/>`_ of Python) and use. +`binary distributions <https://www.python.org/download/>`_ of Python) and use. For more info about Tk, including pointers to the source, see the `Tcl/Tk home page <http://www.tcl.tk>`_. Tcl/Tk is fully portable to the -MacOS, Windows, and Unix platforms. +Mac OS X, Windows, and Unix platforms. wxWidgets --------- wxWidgets (http://www.wxwidgets.org) is a free, portable GUI class library written in C++ that provides a native look and feel on a -number of platforms, with Windows, MacOS X, GTK, X11, all listed as +number of platforms, with Windows, Mac OS X, GTK, X11, all listed as current stable targets. Language bindings are available for a number of languages including Python, Perl, Ruby, etc. @@ -58,14 +58,14 @@ Qt --- There are bindings available for the Qt toolkit (using either `PyQt -<http://www.riverbankcomputing.co.uk/software/pyqt/>`_ or `PySide -<http://www.pyside.org/>`_) and for KDE (`PyKDE <http://www.riverbankcomputing.co.uk/software/pykde/intro>`__). +<http://www.riverbankcomputing.co.uk/software/pyqt/intro>`_ or `PySide +<http://www.pyside.org/>`_) and for KDE (`PyKDE <https://techbase.kde.org/Development/Languages/Python>`__). PyQt is currently more mature than PySide, but you must buy a PyQt license from `Riverbank Computing <http://www.riverbankcomputing.co.uk/software/pyqt/license>`_ if you want to write proprietary applications. PySide is free for all applications. Qt 4.5 upwards is licensed under the LGPL license; also, commercial licenses -are available from `Nokia <http://qt.nokia.com/>`_. +are available from `The Qt Company <http://www.qt.io/licensing/>`_. Gtk+ ---- @@ -102,13 +102,9 @@ For OpenGL bindings, see `PyOpenGL <http://pyopengl.sourceforge.net>`_. What platform-specific GUI toolkits exist for Python? ======================================================== -`The Mac port <http://python.org/download/mac>`_ by Jack Jansen has a rich and -ever-growing set of modules that support the native Mac toolbox calls. The port -supports MacOS X's Carbon libraries. - By installing the `PyObjc Objective-C bridge -<http://pyobjc.sourceforge.net>`_, Python programs can use MacOS X's -Cocoa libraries. See the documentation that comes with the Mac port. +<https://pythonhosted.org/pyobjc/>`_, Python programs can use Mac OS X's +Cocoa libraries. :ref:`Pythonwin <windows-faq>` by Mark Hammond includes an interface to the Microsoft Foundation Classes and a Python programming environment @@ -143,30 +139,11 @@ might include the Tix libraries as well). Can I have Tk events handled while waiting for I/O? --------------------------------------------------- -Yes, and you don't even need threads! But you'll have to restructure your I/O +On platforms other than Windows, yes, and you don't even +need threads! But you'll have to restructure your I/O code a bit. Tk has the equivalent of Xt's :c:func:`XtAddInput()` call, which allows you to register a callback function which will be called from the Tk mainloop when -I/O is possible on a file descriptor. Here's what you need:: - - from Tkinter import tkinter - tkinter.createfilehandler(file, mask, callback) - -The file may be a Python file or socket object (actually, anything with a -fileno() method), or an integer file descriptor. The mask is one of the -constants tkinter.READABLE or tkinter.WRITABLE. The callback is called as -follows:: - - callback(file, mask) - -You must unregister the callback when you're done, using :: - - tkinter.deletefilehandler(file) - -Note: since you don't know *how many bytes* are available for reading, you can't -use the Python file object's read or readline methods, since these will insist -on reading a predefined number of bytes. For sockets, the :meth:`recv` or -:meth:`recvfrom` methods will work fine; for other files, use -``os.read(file.fileno(), maxbytecount)``. +I/O is possible on a file descriptor. See :ref:`tkinter-file-handlers`. I can't get key bindings to work in Tkinter: why? diff --git a/Doc/faq/installed.rst b/Doc/faq/installed.rst index efec9bf7910a..42296533e26f 100644 --- a/Doc/faq/installed.rst +++ b/Doc/faq/installed.rst @@ -11,7 +11,7 @@ language because Python is easy to learn, but it's also used by professional software developers at places such as Google, NASA, and Lucasfilm Ltd. If you wish to learn more about Python, start with the `Beginner's Guide to -Python <http://wiki.python.org/moin/BeginnersGuide>`_. +Python <https://wiki.python.org/moin/BeginnersGuide>`_. Why is Python installed on my machine? diff --git a/Doc/faq/library.rst b/Doc/faq/library.rst index 8bd774bdce20..064728ff6865 100644 --- a/Doc/faq/library.rst +++ b/Doc/faq/library.rst @@ -19,7 +19,7 @@ standard library module. (Eventually you'll learn what's in the standard library and will be able to skip this step.) For third-party packages, search the `Python Package Index -<http://pypi.python.org/pypi>`_ or try `Google <http://www.google.com>`_ or +<https://pypi.python.org/pypi>`_ or try `Google <https://www.google.com>`_ or another Web search engine. Searching for "Python" plus a keyword or two for your topic of interest will usually find something helpful. @@ -181,8 +181,8 @@ How do I create documentation from doc strings? The :mod:`pydoc` module can create HTML from the doc strings in your Python source code. An alternative for creating API documentation purely from -docstrings is `epydoc <http://epydoc.sf.net/>`_. `Sphinx -<http://sphinx.pocoo.org>`_ can also include docstring content. +docstrings is `epydoc <http://epydoc.sourceforge.net/>`_. `Sphinx +<http://sphinx-doc.org>`_ can also include docstring content. How do I get a single keypress at a time? @@ -513,6 +513,7 @@ For data that is more regular (e.g. a homogeneous list of ints or floats), you can also use the :mod:`array` module. .. note:: + To read and write binary data, it is mandatory to open the file in binary mode (here, passing ``"rb"`` to :func:`open`). If you use ``"r"`` instead (the default), the file will be open in text mode @@ -606,7 +607,7 @@ use ``p.read(n)``. "expect" library. A Python extension that interfaces to expect is called "expy" and available from http://expectpy.sourceforge.net. A pure Python solution that works like expect is `pexpect - <http://pypi.python.org/pypi/pexpect/>`_. + <https://pypi.python.org/pypi/pexpect/>`_. How do I access the serial (RS232) port? @@ -662,7 +663,7 @@ and client-side web systems. .. XXX check if wiki page is still up to date A summary of available frameworks is maintained by Paul Boddie at -http://wiki.python.org/moin/WebProgramming . +https://wiki.python.org/moin/WebProgramming\ . Cameron Laird maintains a useful set of pages about Python web technologies at http://phaseit.net/claird/comp.lang.python/web_python. @@ -686,7 +687,8 @@ Yes. Here's a simple example that uses urllib.request:: ### connect and send the server a path req = urllib.request.urlopen('http://www.some-server.out-there/' '/cgi-bin/some-cgi-script', data=qs) - msg, hdrs = req.read(), req.info() + with req: + msg, hdrs = req.read(), req.info() Note that in general for percent-encoded POST operations, query strings must be quoted using :func:`urllib.parse.urlencode`. For example, to send @@ -705,7 +707,7 @@ What module should I use to help with generating HTML? .. XXX add modern template languages You can find a collection of useful links on the `Web Programming wiki page -<http://wiki.python.org/moin/WebProgramming>`_. +<https://wiki.python.org/moin/WebProgramming>`_. How do I send mail from a Python script? @@ -772,7 +774,7 @@ socket to select to check if it's writable. .. note:: The :mod:`asyncore` module presents a framework-like approach to the problem of writing non-blocking networking code. - The third-party `Twisted <http://twistedmatrix.com/>`_ library is + The third-party `Twisted <https://twistedmatrix.com/trac/>`_ library is a popular and feature-rich alternative. @@ -791,7 +793,7 @@ database. Support for most relational databases is available. See the `DatabaseProgramming wiki page -<http://wiki.python.org/moin/DatabaseProgramming>`_ for details. +<https://wiki.python.org/moin/DatabaseProgramming>`_ for details. How do you implement persistent objects in Python? diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index ac12da3d7476..67a9c5663b16 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -23,15 +23,14 @@ for pdb as an example. The IDLE interactive development environment, which is part of the standard Python distribution (normally available as Tools/scripts/idle), includes a -graphical debugger. There is documentation for the IDLE debugger at -http://www.python.org/idle/doc/idle2.html#Debugger. +graphical debugger. PythonWin is a Python IDE that includes a GUI debugger based on pdb. The Pythonwin debugger colors breakpoints and has quite a few cool features such as debugging non-Pythonwin programs. Pythonwin is available as part of the `Python for Windows Extensions <http://sourceforge.net/projects/pywin32/>`__ project and as a part of the ActivePython distribution (see -http://www.activestate.com/Products/ActivePython/index.html). +http://www.activestate.com/activepython\ ). `Boa Constructor <http://boa-constructor.sourceforge.net/>`_ is an IDE and GUI builder that uses wxWidgets. It offers visual frame creation and manipulation, @@ -39,7 +38,7 @@ an object inspector, many views on the source like object browsers, inheritance hierarchies, doc string generated html documentation, an advanced debugger, integrated help, and Zope support. -`Eric <http://www.die-offenbachs.de/eric/index.html>`_ is an IDE built on PyQt +`Eric <http://eric-ide.python-projects.org/>`_ is an IDE built on PyQt and the Scintilla editing component. Pydb is a version of the standard Python debugger pdb, modified for use with DDD @@ -51,7 +50,8 @@ There are a number of commercial Python IDEs that include graphical debuggers. They include: * Wing IDE (http://wingware.com/) -* Komodo IDE (http://www.activestate.com/Products/Komodo) +* Komodo IDE (http://komodoide.com/) +* PyCharm (https://www.jetbrains.com/pycharm/) Is there a tool to help find bugs or perform static analysis? @@ -61,7 +61,7 @@ Yes. PyChecker is a static analysis tool that finds bugs in Python source code and warns about code complexity and style. You can get PyChecker from -http://pychecker.sf.net. +http://pychecker.sourceforge.net/. `Pylint <http://www.logilab.org/projects/pylint>`_ is another tool that checks if a module satisfies a coding standard, and also makes it possible to write @@ -69,8 +69,7 @@ plug-ins to add a custom feature. In addition to the bug checking that PyChecker performs, Pylint offers some additional features such as checking line length, whether variable names are well-formed according to your coding standard, whether declared interfaces are fully implemented, and more. -http://www.logilab.org/card/pylint_manual provides a full list of Pylint's -features. +http://docs.pylint.org/ provides a full list of Pylint's features. How can I create a stand-alone binary from a Python script? @@ -101,13 +100,7 @@ which don't. One is Thomas Heller's py2exe (Windows only) at http://www.py2exe.org/ -Another is Christian Tismer's `SQFREEZE <http://starship.python.net/crew/pirx>`_ -which appends the byte code to a specially-prepared Python interpreter that can -find the byte code in the executable. - -Other tools include Fredrik Lundh's `Squeeze -<http://www.pythonware.com/products/python/squeeze>`_ and Anthony Tuininga's -`cx_Freeze <http://starship.python.net/crew/atuining/cx_Freeze/index.html>`_. +Another tool is Anthony Tuininga's `cx_Freeze <http://cx-freeze.sourceforge.net/>`_. Are there coding standards or a style guide for Python programs? @@ -194,10 +187,8 @@ What are the rules for local and global variables in Python? ------------------------------------------------------------ In Python, variables that are only referenced inside a function are implicitly -global. If a variable is assigned a new value anywhere within the function's -body, it's assumed to be a local. If a variable is ever assigned a new value -inside the function, the variable is implicitly local, and you need to -explicitly declare it as 'global'. +global. If a variable is assigned a value anywhere within the function's body, +it's assumed to be a local unless explicitly declared as global. Though a bit surprising at first, a moment's consideration explains this. On one hand, requiring :keyword:`global` for assigned variables provides a bar @@ -292,9 +283,8 @@ What are the "best practices" for using import in a module? ----------------------------------------------------------- In general, don't use ``from modulename import *``. Doing so clutters the -importer's namespace. Some people avoid this idiom even with the few modules -that were designed to be imported in this manner. Modules designed in this -manner include :mod:`tkinter`, and :mod:`threading`. +importer's namespace, and makes it much harder for linters to detect undefined +names. Import modules at the top of a file. Doing so makes it clear what other modules your code requires and avoids questions of whether the module name is in scope. @@ -308,11 +298,6 @@ It's good practice if you import modules in the following order: directory) -- e.g. mx.DateTime, ZODB, PIL.Image, etc. 3. locally-developed modules -Never use relative package imports. If you're writing code that's in the -``package.sub.m1`` module and want to import ``package.sub.m2``, do not just -write ``from . import m2``, even though it's legal. Write ``from package.sub -import m2`` instead. See :pep:`328` for details. - It is sometimes necessary to move imports to a function or class to avoid problems with circular imports. Gordon McMillan says: @@ -343,13 +328,61 @@ module, but loading a module multiple times is virtually free, costing only a couple of dictionary lookups. Even if the module name has gone out of scope, the module is probably available in :data:`sys.modules`. -If only instances of a specific class use a module, then it is reasonable to -import the module in the class's ``__init__`` method and then assign the module -to an instance variable so that the module is always available (via that -instance variable) during the life of the object. Note that to delay an import -until the class is instantiated, the import must be inside a method. Putting -the import inside the class but outside of any method still causes the import to -occur when the module is initialized. + +Why are default values shared between objects? +---------------------------------------------- + +This type of bug commonly bites neophyte programmers. Consider this function:: + + def foo(mydict={}): # Danger: shared reference to one dict for all calls + ... compute something ... + mydict[key] = value + return mydict + +The first time you call this function, ``mydict`` contains a single item. The +second time, ``mydict`` contains two items because when ``foo()`` begins +executing, ``mydict`` starts out with an item already in it. + +It is often expected that a function call creates new objects for default +values. This is not what happens. Default values are created exactly once, when +the function is defined. If that object is changed, like the dictionary in this +example, subsequent calls to the function will refer to this changed object. + +By definition, immutable objects such as numbers, strings, tuples, and ``None``, +are safe from change. Changes to mutable objects such as dictionaries, lists, +and class instances can lead to confusion. + +Because of this feature, it is good programming practice to not use mutable +objects as default values. Instead, use ``None`` as the default value and +inside the function, check if the parameter is ``None`` and create a new +list/dictionary/whatever if it is. For example, don't write:: + + def foo(mydict={}): + ... + +but:: + + def foo(mydict=None): + if mydict is None: + mydict = {} # create a new dict for local namespace + +This feature can be useful. When you have a function that's time-consuming to +compute, a common technique is to cache the parameters and the resulting value +of each call to the function, and return the cached value if the same value is +requested again. This is called "memoizing", and can be implemented like this:: + + # Callers will never provide a third parameter for this function. + def expensive(arg1, arg2, _cache={}): + if (arg1, arg2) in _cache: + return _cache[(arg1, arg2)] + + # Calculate the value + result = ... expensive computation ... + _cache[(arg1, arg2)] = result # Store result in the cache + return result + +You could use a global variable containing a dictionary instead of the default +value; it's a matter of taste. How can I pass optional or keyword parameters from one function to another? @@ -392,6 +425,81 @@ arguments a function can accept. For example, given the function definition:: the values ``42``, ``314``, and ``somevar`` are arguments. +Why did changing list 'y' also change list 'x'? +------------------------------------------------ + +If you wrote code like:: + + >>> x = [] + >>> y = x + >>> y.append(10) + >>> y + [10] + >>> x + [10] + +you might be wondering why appending an element to ``y`` changed ``x`` too. + +There are two factors that produce this result: + +1) Variables are simply names that refer to objects. Doing ``y = x`` doesn't + create a copy of the list -- it creates a new variable ``y`` that refers to + the same object ``x`` refers to. This means that there is only one object + (the list), and both ``x`` and ``y`` refer to it. +2) Lists are :term:`mutable`, which means that you can change their content. + +After the call to :meth:`~list.append`, the content of the mutable object has +changed from ``[]`` to ``[10]``. Since both the variables refer to the same +object, using either name accesses the modified value ``[10]``. + +If we instead assign an immutable object to ``x``:: + + >>> x = 5 # ints are immutable + >>> y = x + >>> x = x + 1 # 5 can't be mutated, we are creating a new object here + >>> x + 6 + >>> y + 5 + +we can see that in this case ``x`` and ``y`` are not equal anymore. This is +because integers are :term:`immutable`, and when we do ``x = x + 1`` we are not +mutating the int ``5`` by incrementing its value; instead, we are creating a +new object (the int ``6``) and assigning it to ``x`` (that is, changing which +object ``x`` refers to). After this assignment we have two objects (the ints +``6`` and ``5``) and two variables that refer to them (``x`` now refers to +``6`` but ``y`` still refers to ``5``). + +Some operations (for example ``y.append(10)`` and ``y.sort()``) mutate the +object, whereas superficially similar operations (for example ``y = y + [10]`` +and ``sorted(y)``) create a new object. In general in Python (and in all cases +in the standard library) a method that mutates an object will return ``None`` +to help avoid getting the two types of operations confused. So if you +mistakenly write ``y.sort()`` thinking it will give you a sorted copy of ``y``, +you'll instead end up with ``None``, which will likely cause your program to +generate an easily diagnosed error. + +However, there is one class of operations where the same operation sometimes +has different behaviors with different types: the augmented assignment +operators. For example, ``+=`` mutates lists but not tuples or ints (``a_list ++= [1, 2, 3]`` is equivalent to ``a_list.extend([1, 2, 3])`` and mutates +``a_list``, whereas ``some_tuple += (1, 2, 3)`` and ``some_int += 1`` create +new objects). + +In other words: + +* If we have a mutable object (:class:`list`, :class:`dict`, :class:`set`, + etc.), we can use some specific operations to mutate it and all the variables + that refer to it will see the change. +* If we have an immutable object (:class:`str`, :class:`int`, :class:`tuple`, + etc.), all the variables that refer to it will always see the same value, + but operations that transform that value into a new value always return a new + object. + +If you want to know if two variables refer to the same object or not, you can +use the :keyword:`is` operator, or the built-in function :func:`id`. + + How do I write a function with output parameters (call by reference)? --------------------------------------------------------------------- @@ -711,7 +819,7 @@ By default, these interpret the number as decimal, so that ``int('0144') == 144`` and ``int('0x144')`` raises :exc:`ValueError`. ``int(string, base)`` takes the base to convert from as a second optional argument, so ``int('0x144', 16) == 324``. If the base is specified as 0, the number is interpreted using Python's -rules: a leading '0' indicates octal, and '0x' indicates a hex number. +rules: a leading '0o' indicates octal, and '0x' indicates a hex number. Do not use the built-in function :func:`eval` if all you need is to convert strings to numbers. :func:`eval` will be significantly slower and it presents a @@ -732,7 +840,7 @@ To convert, e.g., the number 144 to the string '144', use the built-in type constructor :func:`str`. If you want a hexadecimal or octal representation, use the built-in functions :func:`hex` or :func:`oct`. For fancy formatting, see the :ref:`string-formatting` section, e.g. ``"{:04d}".format(144)`` yields -``'0144'`` and ``"{:.3f}".format(1/3)`` yields ``'0.333'``. +``'0144'`` and ``"{:.3f}".format(1.0/3.0)`` yields ``'0.333'``. How do I modify a string in place? @@ -903,7 +1011,7 @@ performance levels: as builtins and some extension types. For example, be sure to use either the :meth:`list.sort` built-in method or the related :func:`sorted` function to do sorting (and see the - `sorting mini-HOWTO <http://wiki.python.org/moin/HowTo/Sorting>`_ for examples + `sorting mini-HOWTO <https://wiki.python.org/moin/HowTo/Sorting>`_ for examples of moderately advanced usage). * Abstractions tend to create indirections and force the interpreter to work @@ -923,7 +1031,7 @@ yourself. .. seealso:: The wiki page devoted to `performance tips - <http://wiki.python.org/moin/PythonSpeed/PerformanceTips>`_. + <https://wiki.python.org/moin/PythonSpeed/PerformanceTips>`_. .. _efficient_string_concatenation: @@ -1008,7 +1116,7 @@ How do you remove duplicates from a list? See the Python Cookbook for a long discussion of many ways to do this: - http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52560 + http://code.activestate.com/recipes/52560/ If you don't mind reordering the list, sort it and then scan from the end of the list, deleting duplicates as you go:: @@ -1056,6 +1164,8 @@ analogue of lisp car is ``lisp_list[0]`` and the analogue of cdr is usually a lot slower than using Python lists. +.. _faq-multidimensional-list: + How do I create a multidimensional list? ---------------------------------------- @@ -1103,6 +1213,7 @@ Use a list comprehension:: result = [obj.method() for obj in mylist] +.. _faq-augmented-assignment-tuple-error: Why does a_tuple[i] += ['item'] raise an exception when the addition works? --------------------------------------------------------------------------- @@ -1607,26 +1718,34 @@ Modules How do I create a .pyc file? ---------------------------- -When a module is imported for the first time (or when the source is more recent -than the current compiled file) a ``.pyc`` file containing the compiled code -should be created in the same directory as the ``.py`` file. +When a module is imported for the first time (or when the source file has +changed since the current compiled file was created) a ``.pyc`` file containing +the compiled code should be created in a ``__pycache__`` subdirectory of the +directory containing the ``.py`` file. The ``.pyc`` file will have a +filename that starts with the same name as the ``.py`` file, and ends with +``.pyc``, with a middle component that depends on the particular ``python`` +binary that created it. (See :pep:`3147` for details.) -One reason that a ``.pyc`` file may not be created is permissions problems with -the directory. This can happen, for example, if you develop as one user but run -as another, such as if you are testing with a web server. Creation of a .pyc -file is automatic if you're importing a module and Python has the ability -(permissions, free space, etc...) to write the compiled module back to the -directory. +One reason that a ``.pyc`` file may not be created is a permissions problem +with the directory containing the source file, meaning that the ``__pycache__`` +subdirectory cannot be created. This can happen, for example, if you develop as +one user but run as another, such as if you are testing with a web server. + +Unless the :envvar:`PYTHONDONTWRITEBYTECODE` environment variable is set, +creation of a .pyc file is automatic if you're importing a module and Python +has the ability (permissions, free space, etc...) to create a ``__pycache__`` +subdirectory and write the compiled module to that subdirectory. Running Python on a top level script is not considered an import and no ``.pyc`` will be created. For example, if you have a top-level module -``foo.py`` that imports another module ``xyz.py``, when you run ``foo``, -``xyz.pyc`` will be created since ``xyz`` is imported, but no ``foo.pyc`` file -will be created since ``foo.py`` isn't being imported. +``foo.py`` that imports another module ``xyz.py``, when you run ``foo`` (by +typing ``python foo.py`` as a shell command), a ``.pyc`` will be created for +``xyz`` because ``xyz`` is imported, but no ``.pyc`` file will be created for +``foo`` since ``foo.py`` isn't being imported. -If you need to create ``foo.pyc`` -- that is, to create a ``.pyc`` file for a module -that is not imported -- you can, using the :mod:`py_compile` and -:mod:`compileall` modules. +If you need to create a ``.pyc`` file for ``foo`` -- that is, to create a +``.pyc`` file for a module that is not imported -- you can, using the +:mod:`py_compile` and :mod:`compileall` modules. The :mod:`py_compile` module can manually compile any module. One way is to use the ``compile()`` function in that module interactively:: @@ -1634,8 +1753,9 @@ the ``compile()`` function in that module interactively:: >>> import py_compile >>> py_compile.compile('foo.py') # doctest: +SKIP -This will write the ``.pyc`` to the same location as ``foo.py`` (or you can -override that with the optional parameter ``cfile``). +This will write the ``.pyc`` to a ``__pycache__`` subdirectory in the same +location as ``foo.py`` (or you can override that with the optional parameter +``cfile``). You can also automatically compile all files in a directory or directories using the :mod:`compileall` module. You can do it from the shell prompt by running @@ -1720,19 +1840,10 @@ These solutions are not mutually exclusive. __import__('x.y.z') returns <module 'x'>; how do I get z? --------------------------------------------------------- -Try:: - - __import__('x.y.z').y.z - -For more realistic situations, you may have to do something like :: - - m = __import__(s) - for i in s.split(".")[1:]: - m = getattr(m, i) - -See :mod:`importlib` for a convenience function called -:func:`~importlib.import_module`. +Consider using the convenience function :func:`~importlib.import_module` from +:mod:`importlib` instead:: + z = importlib.import_module('x.y.z') When I edit an imported module and reimport it, the changes don't show up. Why does this happen? diff --git a/Doc/faq/windows.rst b/Doc/faq/windows.rst index 651ba2268306..6db6637ed78d 100644 --- a/Doc/faq/windows.rst +++ b/Doc/faq/windows.rst @@ -31,7 +31,7 @@ obvious; otherwise, you might need a little more guidance. .. |Python Development on XP| image:: python-video-icon.png .. _`Python Development on XP`: - http://www.showmedo.com/videos/series?name=pythonOzsvaldPyNewbieSeries + http://showmedo.com/videotutorials/series?name=pythonOzsvaldPyNewbieSeries Unless you use some sort of integrated development environment, you will end up *typing* Windows commands into what is variously referred to as a "DOS window" @@ -78,17 +78,17 @@ by entering a few expressions of your choice and seeing the results:: >>> print("Hello") Hello >>> "Hello" * 3 - HelloHelloHello + 'HelloHelloHello' Many people use the interactive mode as a convenient yet highly programmable -calculator. When you want to end your interactive Python session, hold the Ctrl -key down while you enter a Z, then hit the "Enter" key to get back to your +calculator. When you want to end your interactive Python session, hold the :kbd:`Ctrl` +key down while you enter a :kbd:`Z`, then hit the ":kbd:`Enter`" key to get back to your Windows command prompt. You may also find that you have a Start-menu entry such as :menuselection:`Start --> Programs --> Python 3.3 --> Python (command line)` that results in you seeing the ``>>>`` prompt in a new window. If so, the window will disappear -after you enter the Ctrl-Z character; Windows is running a single "python" +after you enter the :kbd:`Ctrl-Z` character; Windows is running a single "python" command in the window, and closes it when you terminate the interpreter. If the ``python`` command, instead of displaying the interpreter prompt ``>>>``, @@ -105,7 +105,7 @@ gives you a message like:: .. |Adding Python to DOS Path| image:: python-video-icon.png .. _`Adding Python to DOS Path`: - http://showmedo.com/videos/video?name=960000&fromSeriesID=96 + http://showmedo.com/videotutorials/video?name=960000&fromSeriesID=96 or:: @@ -131,8 +131,8 @@ you should make sure that entering the command :: c:\Python33\python -starts up the interpreter as above (and don't forget you'll need a "CTRL-Z" and -an "Enter" to get out of it). Once you have verified the directory, you can +starts up the interpreter as above (and don't forget you'll need a ":kbd:`Ctrl-Z`" and +an ":kbd:`Enter`" to get out of it). Once you have verified the directory, you can add it to the system path to make it easier to start Python by just running the ``python`` command. This is currently an option in the installer as of CPython 3.3. @@ -170,18 +170,20 @@ offender. How do I make an executable from a Python script? ------------------------------------------------- -See http://www.py2exe.org/ for a distutils extension that allows you +See http://cx-freeze.sourceforge.net/ for a distutils extension that allows you to create console and GUI executables from Python code. +`py2exe <http://www.py2exe.org/>`_, the most popular extension for building +Python 2.x-based executables, does not yet support Python 3 but a version that +does is in development. + Is a ``*.pyd`` file the same as a DLL? -------------------------------------- -.. XXX update for py3k (PyInit_foo) - Yes, .pyd files are dll's, but there are a few differences. If you have a DLL -named ``foo.pyd``, then it must have a function ``initfoo()``. You can then +named ``foo.pyd``, then it must have a function ``PyInit_foo()``. You can then write Python "import foo", and Python will search for foo.pyd (as well as -foo.py, foo.pyc) and if it finds it, will attempt to call ``initfoo()`` to +foo.py, foo.pyc) and if it finds it, will attempt to call ``PyInit_foo()`` to initialize it. You do not link your .exe with foo.lib, as that would cause Windows to require the DLL to be present. @@ -247,7 +249,7 @@ Embedding the Python interpreter in a Windows app can be summarized as follows: ... Py_Initialize(); // Initialize Python. initmyAppc(); // Initialize (import) the helper class. - PyRun_SimpleString("import myApp") ; // Import the shadow class. + PyRun_SimpleString("import myApp"); // Import the shadow class. 5. There are two problems with Python's C API which will become apparent if you use a compiler other than MSVC, the compiler used to build pythonNN.dll. @@ -325,7 +327,7 @@ Prior to Python 2.7 and 3.2, to terminate a process, you can use :mod:`ctypes`:: return (0 != kernel32.TerminateProcess(handle, 0)) In 2.7 and 3.2, :func:`os.kill` is implemented similar to the above function, -with the additional feature of being able to send CTRL+C and CTRL+BREAK +with the additional feature of being able to send :kbd:`Ctrl+C` and :kbd:`Ctrl+Break` to console subprocesses which are designed to handle those signals. See :func:`os.kill` for further details. diff --git a/Doc/glossary.rst b/Doc/glossary.rst index df470515d61c..6808e7ac5d50 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -69,22 +69,61 @@ Glossary :ref:`the difference between arguments and parameters <faq-argument-vs-parameter>`, and :pep:`362`. + asynchronous context manager + An object which controls the environment seen in an + :keyword:`async with` statement by defining :meth:`__aenter__` and + :meth:`__aexit__` methods. Introduced by :pep:`492`. + + asynchronous iterable + An object, that can be used in an :keyword:`async for` statement. + Must return an :term:`awaitable` from its :meth:`__aiter__` method, + which should in turn be resolved in an :term:`asynchronous iterator` + object. Introduced by :pep:`492`. + + asynchronous iterator + An object that implements :meth:`__aiter__` and :meth:`__anext__` + methods, that must return :term:`awaitable` objects. + :keyword:`async for` resolves awaitable returned from asynchronous + iterator's :meth:`__anext__` method until it raises + :exc:`StopAsyncIteration` exception. Introduced by :pep:`492`. + attribute A value associated with an object which is referenced by name using dotted expressions. For example, if an object *o* has an attribute *a* it would be referenced as *o.a*. + awaitable + An object that can be used in an :keyword:`await` expression. Can be + a :term:`coroutine` or an object with an :meth:`__await__` method. + See also :pep:`492`. + BDFL Benevolent Dictator For Life, a.k.a. `Guido van Rossum - <http://www.python.org/~guido/>`_, Python's creator. + <https://www.python.org/~guido/>`_, Python's creator. + + binary file + A :term:`file object` able to read and write + :term:`bytes-like objects <bytes-like object>`. + + .. seealso:: + A :term:`text file` reads and writes :class:`str` objects. bytes-like object - An object that supports the :ref:`bufferobjects`, like :class:`bytes`, - :class:`bytearray` or :class:`memoryview`. Bytes-like objects can - be used for various operations that expect binary data, such as - compression, saving to a binary file or sending over a socket. - Some operations need the binary data to be mutable, in which case - not all bytes-like objects can apply. + An object that supports the :ref:`bufferobjects` and can + export a C-:term:`contiguous` buffer. This includes all :class:`bytes`, + :class:`bytearray`, and :class:`array.array` objects, as well as many + common :class:`memoryview` objects. Bytes-like objects can + be used for various operations that work with binary data; these include + compression, saving to a binary file, and sending over a socket. + + Some operations need the binary data to be mutable. The documentation + often refers to these as "read-write bytes-like objects". Example + mutable buffer objects include :class:`bytearray` and a + :class:`memoryview` of a :class:`bytearray`. + Other operations require the binary data to be stored in + immutable objects ("read-only bytes-like objects"); examples + of these include :class:`bytes` and a :class:`memoryview` + of a :class:`bytes` object. bytecode Python source code is compiled into bytecode, the internal representation @@ -132,9 +171,35 @@ Glossary statement by defining :meth:`__enter__` and :meth:`__exit__` methods. See :pep:`343`. + contiguous + .. index:: C-contiguous, Fortran contiguous + + A buffer is considered contiguous exactly if it is either + *C-contiguous* or *Fortran contiguous*. Zero-dimensional buffers are + C and Fortran contiguous. In one-dimensional arrays, the items + must be layed out in memory next to each other, in order of + increasing indexes starting from zero. In multidimensional + C-contiguous arrays, the last index varies the fastest when + visiting items in order of memory address. However, in + Fortran contiguous arrays, the first index varies the fastest. + + coroutine + Coroutines is a more generalized form of subroutines. Subroutines are + entered at one point and exited at another point. Coroutines can be + entered, exited, and resumed at many different points. They can be + implemented with the :keyword:`async def` statement. See also + :pep:`492`. + + coroutine function + A function which returns a :term:`coroutine` object. A coroutine + function may be defined with the :keyword:`async def` statement, + and may contain :keyword:`await`, :keyword:`async for`, and + :keyword:`async with` keywords. These were introduced + by :pep:`492`. + CPython The canonical implementation of the Python programming language, as - distributed on `python.org <http://python.org>`_. The term "CPython" + distributed on `python.org <https://www.python.org>`_. The term "CPython" is used when necessary to distinguish this implementation from others such as Jython or IronPython. @@ -176,6 +241,14 @@ Glossary keys can be any object with :meth:`__hash__` and :meth:`__eq__` methods. Called a hash in Perl. + dictionary view + The objects returned from :meth:`dict.keys`, :meth:`dict.values`, and + :meth:`dict.items` are called dictionary views. They provide a dynamic + view on the dictionary’s entries, which means that when the dictionary + changes, the view reflects these changes. To force the + dictionary view to become a full list use ``list(dictview)``. See + :ref:`dict-views`. + docstring A string literal which appears as the first expression in a class, function or module. While ignored when the suite is executed, it is @@ -225,10 +298,11 @@ Glossary etc.). File objects are also called :dfn:`file-like objects` or :dfn:`streams`. - There are actually three categories of file objects: raw binary files, - buffered binary files and text files. Their interfaces are defined in the - :mod:`io` module. The canonical way to create a file object is by using - the :func:`open` function. + There are actually three categories of file objects: raw + :term:`binary files <binary file>`, buffered + :term:`binary files <binary file>` and :term:`text files <text file>`. + Their interfaces are defined in the :mod:`io` module. The canonical + way to create a file object is by using the :func:`open` function. file-like object A synonym for :term:`file object`. @@ -282,14 +356,23 @@ Glossary .. index:: single: generator generator - A function which returns an iterator. It looks like a normal function - except that it contains :keyword:`yield` statements for producing a series - a values usable in a for-loop or that can be retrieved one at a time with - the :func:`next` function. Each :keyword:`yield` temporarily suspends - processing, remembering the location execution state (including local - variables and pending try-statements). When the generator resumes, it - picks-up where it left-off (in contrast to functions which start fresh on - every invocation). + A function which returns a :term:`generator iterator`. It looks like a + normal function except that it contains :keyword:`yield` expressions + for producing a series of values usable in a for-loop or that can be + retrieved one at a time with the :func:`next` function. + + Usually refers to a generator function, but may refer to a + *generator iterator* in some contexts. In cases where the intended + meaning isn't clear, using the full terms avoids ambiguity. + + generator iterator + An object created by a :term:`generator` function. + + Each :keyword:`yield` temporarily suspends processing, remembering the + location execution state (including local variables and pending + try-statements). When the *generator iterator* resumes, it picks-up where + it left-off (in contrast to functions which start fresh on every + invocation). .. index:: single: generator expression @@ -347,8 +430,8 @@ Glossary All of Python's immutable built-in objects are hashable, while no mutable containers (such as lists or dictionaries) are. Objects which are instances of user-defined classes are hashable by default; they all - compare unequal (except with themselves), and their hash value is their - :func:`id`. + compare unequal (except with themselves), and their hash value is derived + from their :func:`id`. IDLE An Integrated Development Environment for Python. IDLE is a basic editor @@ -394,6 +477,19 @@ Glossary than compiled ones, though their programs generally also run more slowly. See also :term:`interactive`. + interpreter shutdown + When asked to shut down, the Python interpreter enters a special phase + where it gradually releases all allocated resources, such as modules + and various critical internal structures. It also makes several calls + to the :term:`garbage collector <garbage collection>`. This can trigger + the execution of code in user-defined destructors or weakref callbacks. + Code executed during the shutdown phase can encounter various + exceptions as the resources it relies on may not function anymore + (common examples are library modules or the warnings machinery). + + The main reason for interpreter shutdown is that the ``__main__`` module + or the script being run has finished executing. + iterable An object capable of returning its members one at a time. Examples of iterables include all sequence types (such as :class:`list`, :class:`str`, @@ -436,12 +532,13 @@ Glossary A number of tools in Python accept key functions to control how elements are ordered or grouped. They include :func:`min`, :func:`max`, - :func:`sorted`, :meth:`list.sort`, :func:`heapq.nsmallest`, - :func:`heapq.nlargest`, and :func:`itertools.groupby`. + :func:`sorted`, :meth:`list.sort`, :func:`heapq.merge`, + :func:`heapq.nsmallest`, :func:`heapq.nlargest`, and + :func:`itertools.groupby`. There are several ways to create a key function. For example. the :meth:`str.lower` method can serve as a key function for case insensitive - sorts. Alternatively, an ad-hoc key function can be built from a + sorts. Alternatively, a key function can be built from a :keyword:`lambda` expression such as ``lambda r: (r[0], r[2])``. Also, the :mod:`operator` module provides three key function constructors: :func:`~operator.attrgetter`, :func:`~operator.itemgetter`, and @@ -522,7 +619,7 @@ Glossary method resolution order Method Resolution Order is the order in which base classes are searched for a member during lookup. See `The Python 2.3 Method Resolution Order - <http://www.python.org/download/releases/2.3/mro/>`_. + <https://www.python.org/download/releases/2.3/mro/>`_. module An object that serves as an organizational unit of Python code. Modules @@ -531,6 +628,10 @@ Glossary See also :term:`package`. + module spec + A namespace containing the import-related information used to load a + module. + MRO See :term:`method resolution order`. @@ -771,6 +872,14 @@ Glossary mapping rather than a sequence because the lookups use arbitrary :term:`immutable` keys rather than integers. + The :class:`collections.abc.Sequence` abstract base class + defines a much richer interface that goes beyond just + :meth:`__getitem__` and :meth:`__len__`, adding :meth:`count`, + :meth:`index`, :meth:`__contains__`, and + :meth:`__reversed__`. Types that implement this expanded + interface can be registered explicitly using + :func:`~abc.register`. + single dispatch A form of :term:`generic function` dispatch where the implementation is chosen based on the type of a single argument. @@ -800,6 +909,17 @@ Glossary :meth:`~collections.somenamedtuple._asdict`. Examples of struct sequences include :data:`sys.float_info` and the return value of :func:`os.stat`. + text encoding + A codec which encodes Unicode strings to bytes. + + text file + A :term:`file object` able to read and write :class:`str` objects. + Often, a text file actually accesses a byte-oriented datastream + and handles the :term:`text encoding` automatically. + + .. seealso:: + A :term:`binary file` reads and write :class:`bytes` objects. + triple-quoted string A string which is bound by three instances of either a quotation mark (") or an apostrophe ('). While they don't provide any functionality @@ -820,14 +940,15 @@ Glossary recognized as ending a line: the Unix end-of-line convention ``'\n'``, the Windows convention ``'\r\n'``, and the old Macintosh convention ``'\r'``. See :pep:`278` and :pep:`3116`, as well as - :func:`str.splitlines` for an additional use. + :func:`bytes.splitlines` for an additional use. - view - The objects returned from :meth:`dict.keys`, :meth:`dict.values`, and - :meth:`dict.items` are called dictionary views. They are lazy sequences - that will see changes in the underlying dictionary. To force the - dictionary view to become a full list use ``list(dictview)``. See - :ref:`dict-views`. + virtual environment + A cooperatively isolated runtime environment that allows Python users + and applications to install and upgrade Python distribution packages + without interfering with the behaviour of other Python applications + running on the same system. + + See also :ref:`scripts-pyvenv`. virtual machine A computer defined entirely in software. Python's virtual machine diff --git a/Doc/howto/argparse.rst b/Doc/howto/argparse.rst index 510d1d49dbd5..9c111b4bdf53 100644 --- a/Doc/howto/argparse.rst +++ b/Doc/howto/argparse.rst @@ -547,7 +547,8 @@ And this is what it gives: Traceback (most recent call last): File "prog.py", line 11, in <module> if args.verbosity >= 2: - TypeError: unorderable types: NoneType() >= int() + TypeError: '>=' not supported between instances of 'NoneType' and 'int' + * First output went well, and fixes the bug we had before. That is, we want any value >= 2 to be as verbose as possible. diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst new file mode 100644 index 000000000000..7524c4ad9013 --- /dev/null +++ b/Doc/howto/clinic.rst @@ -0,0 +1,1683 @@ +********************** +Argument Clinic How-To +********************** + +:author: Larry Hastings + + +.. topic:: Abstract + + Argument Clinic is a preprocessor for CPython C files. + Its purpose is to automate all the boilerplate involved + with writing argument parsing code for "builtins". + This document shows you how to convert your first C + function to work with Argument Clinic, and then introduces + some advanced topics on Argument Clinic usage. + + Currently Argument Clinic is considered internal-only + for CPython. Its use is not supported for files outside + CPython, and no guarantees are made regarding backwards + compatibility for future versions. In other words: if you + maintain an external C extension for CPython, you're welcome + to experiment with Argument Clinic in your own code. But the + version of Argument Clinic that ships with CPython 3.5 *could* + be totally incompatible and break all your code. + +The Goals Of Argument Clinic +============================ + +Argument Clinic's primary goal +is to take over responsibility for all argument parsing code +inside CPython. This means that, when you convert a function +to work with Argument Clinic, that function should no longer +do any of its own argument parsing--the code generated by +Argument Clinic should be a "black box" to you, where CPython +calls in at the top, and your code gets called at the bottom, +with ``PyObject *args`` (and maybe ``PyObject *kwargs``) +magically converted into the C variables and types you need. + +In order for Argument Clinic to accomplish its primary goal, +it must be easy to use. Currently, working with CPython's +argument parsing library is a chore, requiring maintaining +redundant information in a surprising number of places. +When you use Argument Clinic, you don't have to repeat yourself. + +Obviously, no one would want to use Argument Clinic unless +it's solving their problem--and without creating new problems of +its own. +So it's paramount that Argument Clinic generate correct code. +It'd be nice if the code was faster, too, but at the very least +it should not introduce a major speed regression. (Eventually Argument +Clinic *should* make a major speedup possible--we could +rewrite its code generator to produce tailor-made argument +parsing code, rather than calling the general-purpose CPython +argument parsing library. That would make for the fastest +argument parsing possible!) + +Additionally, Argument Clinic must be flexible enough to +work with any approach to argument parsing. Python has +some functions with some very strange parsing behaviors; +Argument Clinic's goal is to support all of them. + +Finally, the original motivation for Argument Clinic was +to provide introspection "signatures" for CPython builtins. +It used to be, the introspection query functions would throw +an exception if you passed in a builtin. With Argument +Clinic, that's a thing of the past! + +One idea you should keep in mind, as you work with +Argument Clinic: the more information you give it, the +better job it'll be able to do. +Argument Clinic is admittedly relatively simple right +now. But as it evolves it will get more sophisticated, +and it should be able to do many interesting and smart +things with all the information you give it. + + +Basic Concepts And Usage +======================== + +Argument Clinic ships with CPython; you'll find it in ``Tools/clinic/clinic.py``. +If you run that script, specifying a C file as an argument:: + + % python3 Tools/clinic/clinic.py foo.c + +Argument Clinic will scan over the file looking for lines that +look exactly like this:: + + /*[clinic input] + +When it finds one, it reads everything up to a line that looks +exactly like this:: + + [clinic start generated code]*/ + +Everything in between these two lines is input for Argument Clinic. +All of these lines, including the beginning and ending comment +lines, are collectively called an Argument Clinic "block". + +When Argument Clinic parses one of these blocks, it +generates output. This output is rewritten into the C file +immediately after the block, followed by a comment containing a checksum. +The Argument Clinic block now looks like this:: + + /*[clinic input] + ... clinic input goes here ... + [clinic start generated code]*/ + ... clinic output goes here ... + /*[clinic end generated code: checksum=...]*/ + +If you run Argument Clinic on the same file a second time, Argument Clinic +will discard the old output and write out the new output with a fresh checksum +line. However, if the input hasn't changed, the output won't change either. + +You should never modify the output portion of an Argument Clinic block. Instead, +change the input until it produces the output you want. (That's the purpose of the +checksum--to detect if someone changed the output, as these edits would be lost +the next time Argument Clinic writes out fresh output.) + +For the sake of clarity, here's the terminology we'll use with Argument Clinic: + +* The first line of the comment (``/*[clinic input]``) is the *start line*. +* The last line of the initial comment (``[clinic start generated code]*/``) is the *end line*. +* The last line (``/*[clinic end generated code: checksum=...]*/``) is the *checksum line*. +* In between the start line and the end line is the *input*. +* In between the end line and the checksum line is the *output*. +* All the text collectively, from the start line to the checksum line inclusively, + is the *block*. (A block that hasn't been successfully processed by Argument + Clinic yet doesn't have output or a checksum line, but it's still considered + a block.) + + +Converting Your First Function +============================== + +The best way to get a sense of how Argument Clinic works is to +convert a function to work with it. Here, then, are the bare +minimum steps you'd need to follow to convert a function to +work with Argument Clinic. Note that for code you plan to +check in to CPython, you really should take the conversion farther, +using some of the advanced concepts you'll see later on in +the document (like "return converters" and "self converters"). +But we'll keep it simple for this walkthrough so you can learn. + +Let's dive in! + +0. Make sure you're working with a freshly updated checkout + of the CPython trunk. + +1. Find a Python builtin that calls either :c:func:`PyArg_ParseTuple` + or :c:func:`PyArg_ParseTupleAndKeywords`, and hasn't been converted + to work with Argument Clinic yet. + For my example I'm using ``_pickle.Pickler.dump()``. + +2. If the call to the ``PyArg_Parse`` function uses any of the + following format units:: + + O& + O! + es + es# + et + et# + + or if it has multiple calls to :c:func:`PyArg_ParseTuple`, + you should choose a different function. Argument Clinic *does* + support all of these scenarios. But these are advanced + topics--let's do something simpler for your first function. + + Also, if the function has multiple calls to :c:func:`PyArg_ParseTuple` + or :c:func:`PyArg_ParseTupleAndKeywords` where it supports different + types for the same argument, or if the function uses something besides + PyArg_Parse functions to parse its arguments, it probably + isn't suitable for conversion to Argument Clinic. Argument Clinic + doesn't support generic functions or polymorphic parameters. + +3. Add the following boilerplate above the function, creating our block:: + + /*[clinic input] + [clinic start generated code]*/ + +4. Cut the docstring and paste it in between the ``[clinic]`` lines, + removing all the junk that makes it a properly quoted C string. + When you're done you should have just the text, based at the left + margin, with no line wider than 80 characters. + (Argument Clinic will preserve indents inside the docstring.) + + If the old docstring had a first line that looked like a function + signature, throw that line away. (The docstring doesn't need it + anymore--when you use ``help()`` on your builtin in the future, + the first line will be built automatically based on the function's + signature.) + + Sample:: + + /*[clinic input] + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +5. If your docstring doesn't have a "summary" line, Argument Clinic will + complain. So let's make sure it has one. The "summary" line should + be a paragraph consisting of a single 80-column line + at the beginning of the docstring. + + (Our example docstring consists solely of a summary line, so the sample + code doesn't have to change for this step.) + +6. Above the docstring, enter the name of the function, followed + by a blank line. This should be the Python name of the function, + and should be the full dotted path + to the function--it should start with the name of the module, + include any sub-modules, and if the function is a method on + a class it should include the class name too. + + Sample:: + + /*[clinic input] + _pickle.Pickler.dump + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +7. If this is the first time that module or class has been used with Argument + Clinic in this C file, + you must declare the module and/or class. Proper Argument Clinic hygiene + prefers declaring these in a separate block somewhere near the + top of the C file, in the same way that include files and statics go at + the top. (In our sample code we'll just show the two blocks next to + each other.) + + The name of the class and module should be the same as the one + seen by Python. Check the name defined in the :c:type:`PyModuleDef` + or :c:type:`PyTypeObject` as appropriate. + + When you declare a class, you must also specify two aspects of its type + in C: the type declaration you'd use for a pointer to an instance of + this class, and a pointer to the :c:type:`PyTypeObject` for this class. + + Sample:: + + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ + + /*[clinic input] + _pickle.Pickler.dump + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + + + + +8. Declare each of the parameters to the function. Each parameter + should get its own line. All the parameter lines should be + indented from the function name and the docstring. + + The general form of these parameter lines is as follows:: + + name_of_parameter: converter + + If the parameter has a default value, add that after the + converter:: + + name_of_parameter: converter = default_value + + Argument Clinic's support for "default values" is quite sophisticated; + please see :ref:`the section below on default values <default_values>` + for more information. + + Add a blank line below the parameters. + + What's a "converter"? It establishes both the type + of the variable used in C, and the method to convert the Python + value into a C value at runtime. + For now you're going to use what's called a "legacy converter"--a + convenience syntax intended to make porting old code into Argument + Clinic easier. + + For each parameter, copy the "format unit" for that + parameter from the ``PyArg_Parse()`` format argument and + specify *that* as its converter, as a quoted + string. ("format unit" is the formal name for the one-to-three + character substring of the ``format`` parameter that tells + the argument parsing function what the type of the variable + is and how to convert it. For more on format units please + see :ref:`arg-parsing`.) + + For multicharacter format units like ``z#``, use the + entire two-or-three character string. + + Sample:: + + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ + + /*[clinic input] + _pickle.Pickler.dump + + obj: 'O' + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +9. If your function has ``|`` in the format string, meaning some + parameters have default values, you can ignore it. Argument + Clinic infers which parameters are optional based on whether + or not they have default values. + + If your function has ``$`` in the format string, meaning it + takes keyword-only arguments, specify ``*`` on a line by + itself before the first keyword-only argument, indented the + same as the parameter lines. + + (``_pickle.Pickler.dump`` has neither, so our sample is unchanged.) + + +10. If the existing C function calls :c:func:`PyArg_ParseTuple` + (as opposed to :c:func:`PyArg_ParseTupleAndKeywords`), then all its + arguments are positional-only. + + To mark all parameters as positional-only in Argument Clinic, + add a ``/`` on a line by itself after the last parameter, + indented the same as the parameter lines. + + Currently this is all-or-nothing; either all parameters are + positional-only, or none of them are. (In the future Argument + Clinic may relax this restriction.) + + Sample:: + + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ + + /*[clinic input] + _pickle.Pickler.dump + + obj: 'O' + / + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +11. It's helpful to write a per-parameter docstring for each parameter. + But per-parameter docstrings are optional; you can skip this step + if you prefer. + + Here's how to add a per-parameter docstring. The first line + of the per-parameter docstring must be indented further than the + parameter definition. The left margin of this first line establishes + the left margin for the whole per-parameter docstring; all the text + you write will be outdented by this amount. You can write as much + text as you like, across multiple lines if you wish. + + Sample:: + + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ + + /*[clinic input] + _pickle.Pickler.dump + + obj: 'O' + The object to be pickled. + / + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +12. Save and close the file, then run ``Tools/clinic/clinic.py`` on it. + With luck everything worked and your block now has output! Reopen + the file in your text editor to see:: + + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ + /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + + /*[clinic input] + _pickle.Pickler.dump + + obj: 'O' + The object to be pickled. + / + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + + PyDoc_STRVAR(_pickle_Pickler_dump__doc__, + "Write a pickled representation of obj to the open file.\n" + "\n" + ... + static PyObject * + _pickle_Pickler_dump_impl(PicklerObject *self, PyObject *obj) + /*[clinic end generated code: checksum=3bd30745bf206a48f8b576a1da3d90f55a0a4187]*/ + + Obviously, if Argument Clinic didn't produce any output, it's because + it found an error in your input. Keep fixing your errors and retrying + until Argument Clinic processes your file without complaint. + +13. Double-check that the argument-parsing code Argument Clinic generated + looks basically the same as the existing code. + + First, ensure both places use the same argument-parsing function. + The existing code must call either + :c:func:`PyArg_ParseTuple` or :c:func:`PyArg_ParseTupleAndKeywords`; + ensure that the code generated by Argument Clinic calls the + *exact* same function. + + Second, the format string passed in to :c:func:`PyArg_ParseTuple` or + :c:func:`PyArg_ParseTupleAndKeywords` should be *exactly* the same + as the hand-written one in the existing function, up to the colon + or semi-colon. + + (Argument Clinic always generates its format strings + with a ``:`` followed by the name of the function. If the + existing code's format string ends with ``;``, to provide + usage help, this change is harmless--don't worry about it.) + + Third, for parameters whose format units require two arguments + (like a length variable, or an encoding string, or a pointer + to a conversion function), ensure that the second argument is + *exactly* the same between the two invocations. + + Fourth, inside the output portion of the block you'll find a preprocessor + macro defining the appropriate static :c:type:`PyMethodDef` structure for + this builtin:: + + #define __PICKLE_PICKLER_DUMP_METHODDEF \ + {"dump", (PyCFunction)__pickle_Pickler_dump, METH_O, __pickle_Pickler_dump__doc__}, + + This static structure should be *exactly* the same as the existing static + :c:type:`PyMethodDef` structure for this builtin. + + If any of these items differ in *any way*, + adjust your Argument Clinic function specification and rerun + ``Tools/clinic/clinic.py`` until they *are* the same. + + +14. Notice that the last line of its output is the declaration + of your "impl" function. This is where the builtin's implementation goes. + Delete the existing prototype of the function you're modifying, but leave + the opening curly brace. Now delete its argument parsing code and the + declarations of all the variables it dumps the arguments into. + Notice how the Python arguments are now arguments to this impl function; + if the implementation used different names for these variables, fix it. + + Let's reiterate, just because it's kind of weird. Your code should now + look like this:: + + static return_type + your_function_impl(...) + /*[clinic end generated code: checksum=...]*/ + { + ... + + Argument Clinic generated the checksum line and the function prototype just + above it. You should write the opening (and closing) curly braces for the + function, and the implementation inside. + + Sample:: + + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ + /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + + /*[clinic input] + _pickle.Pickler.dump + + obj: 'O' + The object to be pickled. + / + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + + PyDoc_STRVAR(__pickle_Pickler_dump__doc__, + "Write a pickled representation of obj to the open file.\n" + "\n" + ... + static PyObject * + _pickle_Pickler_dump_impl(PicklerObject *self, PyObject *obj) + /*[clinic end generated code: checksum=3bd30745bf206a48f8b576a1da3d90f55a0a4187]*/ + { + /* 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) { + PyErr_Format(PicklingError, + "Pickler.__init__() was not called by %s.__init__()", + Py_TYPE(self)->tp_name); + return NULL; + } + + if (_Pickler_ClearBuffer(self) < 0) + return NULL; + + ... + +15. Remember the macro with the :c:type:`PyMethodDef` structure for this + function? Find the existing :c:type:`PyMethodDef` structure for this + function and replace it with a reference to the macro. (If the builtin + is at module scope, this will probably be very near the end of the file; + if the builtin is a class method, this will probably be below but relatively + near to the implementation.) + + Note that the body of the macro contains a trailing comma. So when you + replace the existing static :c:type:`PyMethodDef` structure with the macro, + *don't* add a comma to the end. + + Sample:: + + static struct PyMethodDef Pickler_methods[] = { + __PICKLE_PICKLER_DUMP_METHODDEF + __PICKLE_PICKLER_CLEAR_MEMO_METHODDEF + {NULL, NULL} /* sentinel */ + }; + + +16. Compile, then run the relevant portions of the regression-test suite. + This change should not introduce any new compile-time warnings or errors, + and there should be no externally-visible change to Python's behavior. + + Well, except for one difference: ``inspect.signature()`` run on your function + should now provide a valid signature! + + Congratulations, you've ported your first function to work with Argument Clinic! + +Advanced Topics +=============== + +Now that you've had some experience working with Argument Clinic, it's time +for some advanced topics. + + +Symbolic default values +----------------------- + +The default value you provide for a parameter can't be any arbitrary +expression. Currently the following are explicitly supported: + +* Numeric constants (integer and float) +* String constants +* ``True``, ``False``, and ``None`` +* Simple symbolic constants like ``sys.maxsize``, which must + start with the name of the module + +In case you're curious, this is implemented in ``from_builtin()`` +in ``Lib/inspect.py``. + +(In the future, this may need to get even more elaborate, +to allow full expressions like ``CONSTANT - 1``.) + + +Renaming the C functions and variables generated by Argument Clinic +------------------------------------------------------------------- + +Argument Clinic automatically names the functions it generates for you. +Occasionally this may cause a problem, if the generated name collides with +the name of an existing C function. There's an easy solution: override the names +used for the C functions. Just add the keyword ``"as"`` +to your function declaration line, followed by the function name you wish to use. +Argument Clinic will use that function name for the base (generated) function, +then add ``"_impl"`` to the end and use that for the name of the impl function. + +For example, if we wanted to rename the C function names generated for +``pickle.Pickler.dump``, it'd look like this:: + + /*[clinic input] + pickle.Pickler.dump as pickler_dumper + + ... + +The base function would now be named ``pickler_dumper()``, +and the impl function would now be named ``pickler_dumper_impl()``. + + +Similarly, you may have a problem where you want to give a parameter +a specific Python name, but that name may be inconvenient in C. Argument +Clinic allows you to give a parameter different names in Python and in C, +using the same ``"as"`` syntax:: + + /*[clinic input] + pickle.Pickler.dump + + obj: object + file as file_obj: object + protocol: object = NULL + * + fix_imports: bool = True + +Here, the name used in Python (in the signature and the ``keywords`` +array) would be ``file``, but the C variable would be named ``file_obj``. + +You can use this to rename the ``self`` parameter too! + + +Converting functions using PyArg_UnpackTuple +-------------------------------------------- + +To convert a function parsing its arguments with :c:func:`PyArg_UnpackTuple`, +simply write out all the arguments, specifying each as an ``object``. You +may specify the ``type`` argument to cast the type as appropriate. All +arguments should be marked positional-only (add a ``/`` on a line by itself +after the last argument). + +Currently the generated code will use :c:func:`PyArg_ParseTuple`, but this +will change soon. + +Optional Groups +--------------- + +Some legacy functions have a tricky approach to parsing their arguments: +they count the number of positional arguments, then use a ``switch`` statement +to call one of several different :c:func:`PyArg_ParseTuple` calls depending on +how many positional arguments there are. (These functions cannot accept +keyword-only arguments.) This approach was used to simulate optional +arguments back before :c:func:`PyArg_ParseTupleAndKeywords` was created. + +While functions using this approach can often be converted to +use :c:func:`PyArg_ParseTupleAndKeywords`, optional arguments, and default values, +it's not always possible. Some of these legacy functions have +behaviors :c:func:`PyArg_ParseTupleAndKeywords` doesn't directly support. +The most obvious example is the builtin function ``range()``, which has +an optional argument on the *left* side of its required argument! +Another example is ``curses.window.addch()``, which has a group of two +arguments that must always be specified together. (The arguments are +called ``x`` and ``y``; if you call the function passing in ``x``, +you must also pass in ``y``--and if you don't pass in ``x`` you may not +pass in ``y`` either.) + +In any case, the goal of Argument Clinic is to support argument parsing +for all existing CPython builtins without changing their semantics. +Therefore Argument Clinic supports +this alternate approach to parsing, using what are called *optional groups*. +Optional groups are groups of arguments that must all be passed in together. +They can be to the left or the right of the required arguments. They +can *only* be used with positional-only parameters. + +.. note:: Optional groups are *only* intended for use when converting + functions that make multiple calls to :c:func:`PyArg_ParseTuple`! + Functions that use *any* other approach for parsing arguments + should *almost never* be converted to Argument Clinic using + optional groups. Functions using optional groups currently + cannot have accurate sigantures in Python, because Python just + doesn't understand the concept. Please avoid using optional + groups wherever possible. + +To specify an optional group, add a ``[`` on a line by itself before +the parameters you wish to group together, and a ``]`` on a line by itself +after these parameters. As an example, here's how ``curses.window.addch`` +uses optional groups to make the first two parameters and the last +parameter optional:: + + /*[clinic input] + + curses.window.addch + + [ + x: int + X-coordinate. + y: int + Y-coordinate. + ] + + ch: object + Character to add. + + [ + attr: long + Attributes for the character. + ] + / + + ... + + +Notes: + +* For every optional group, one additional parameter will be passed into the + impl function representing the group. The parameter will be an int named + ``group_{direction}_{number}``, + where ``{direction}`` is either ``right`` or ``left`` depending on whether the group + is before or after the required parameters, and ``{number}`` is a monotonically + increasing number (starting at 1) indicating how far away the group is from + the required parameters. When the impl is called, this parameter will be set + to zero if this group was unused, and set to non-zero if this group was used. + (By used or unused, I mean whether or not the parameters received arguments + in this invocation.) + +* If there are no required arguments, the optional groups will behave + as if they're to the right of the required arguments. + +* In the case of ambiguity, the argument parsing code + favors parameters on the left (before the required parameters). + +* Optional groups can only contain positional-only parameters. + +* Optional groups are *only* intended for legacy code. Please do not + use optional groups for new code. + + +Using real Argument Clinic converters, instead of "legacy converters" +--------------------------------------------------------------------- + +To save time, and to minimize how much you need to learn +to achieve your first port to Argument Clinic, the walkthrough above tells +you to use "legacy converters". "Legacy converters" are a convenience, +designed explicitly to make porting existing code to Argument Clinic +easier. And to be clear, their use is acceptable when porting code for +Python 3.4. + +However, in the long term we probably want all our blocks to +use Argument Clinic's real syntax for converters. Why? A couple +reasons: + +* The proper converters are far easier to read and clearer in their intent. +* There are some format units that are unsupported as "legacy converters", + because they require arguments, and the legacy converter syntax doesn't + support specifying arguments. +* In the future we may have a new argument parsing library that isn't + restricted to what :c:func:`PyArg_ParseTuple` supports; this flexibility + won't be available to parameters using legacy converters. + +Therefore, if you don't mind a little extra effort, please use the normal +converters instead of legacy converters. + +In a nutshell, the syntax for Argument Clinic (non-legacy) converters +looks like a Python function call. However, if there are no explicit +arguments to the function (all functions take their default values), +you may omit the parentheses. Thus ``bool`` and ``bool()`` are exactly +the same converters. + +All arguments to Argument Clinic converters are keyword-only. +All Argument Clinic converters accept the following arguments: + + ``c_default`` + The default value for this parameter when defined in C. + Specifically, this will be the initializer for the variable declared + in the "parse function". See :ref:`the section on default values <default_values>` + for how to use this. + Specified as a string. + + ``annotation`` + The annotation value for this parameter. Not currently supported, + because PEP 8 mandates that the Python library may not use + annotations. + +In addition, some converters accept additional arguments. Here is a list +of these arguments, along with their meanings: + + ``accept`` + A set of Python types (and possibly pseudo-types); + this restricts the allowable Python argument to values of these types. + (This is not a general-purpose facility; as a rule it only supports + specific lists of types as shown in the legacy converter table.) + + To accept ``None``, add ``NoneType`` to this set. + + ``bitwise`` + Only supported for unsigned integers. The native integer value of this + Python argument will be written to the parameter without any range checking, + even for negative values. + + ``converter`` + Only supported by the ``object`` converter. Specifies the name of a + :ref:`C "converter function" <o_ampersand>` + to use to convert this object to a native type. + + ``encoding`` + Only supported for strings. Specifies the encoding to use when converting + this string from a Python str (Unicode) value into a C ``char *`` value. + + + ``subclass_of`` + Only supported for the ``object`` converter. Requires that the Python + value be a subclass of a Python type, as expressed in C. + + ``type`` + Only supported for the ``object`` and ``self`` converters. Specifies + the C type that will be used to declare the variable. Default value is + ``"PyObject *"``. + + ``zeroes`` + Only supported for strings. If true, embedded NUL bytes (``'\\0'``) are + permitted inside the value. The length of the string will be passed in + to the impl function, just after the string parameter, as a parameter named + ``<parameter_name>_length``. + +Please note, not every possible combination of arguments will work. +Usually these arguments are implemented by specific ``PyArg_ParseTuple`` +*format units*, with specific behavior. For example, currently you cannot +call ``unsigned_short`` without also specifying ``bitwise=True``. +Although it's perfectly reasonable to think this would work, these semantics don't +map to any existing format unit. So Argument Clinic doesn't support it. (Or, at +least, not yet.) + +Below is a table showing the mapping of legacy converters into real +Argument Clinic converters. On the left is the legacy converter, +on the right is the text you'd replace it with. + +========= ================================================================================= +``'B'`` ``unsigned_char(bitwise=True)`` +``'b'`` ``unsigned_char`` +``'c'`` ``char`` +``'C'`` ``int(accept={str})`` +``'d'`` ``double`` +``'D'`` ``Py_complex`` +``'es'`` ``str(encoding='name_of_encoding')`` +``'es#'`` ``str(encoding='name_of_encoding', zeroes=True)`` +``'et'`` ``str(encoding='name_of_encoding', accept={bytes, bytearray, str})`` +``'et#'`` ``str(encoding='name_of_encoding', accept={bytes, bytearray, str}, zeroes=True)`` +``'f'`` ``float`` +``'h'`` ``short`` +``'H'`` ``unsigned_short(bitwise=True)`` +``'i'`` ``int`` +``'I'`` ``unsigned_int(bitwise=True)`` +``'k'`` ``unsigned_long(bitwise=True)`` +``'K'`` ``unsigned_PY_LONG_LONG(bitwise=True)`` +``'l'`` ``long`` +``'L'`` ``PY_LONG_LONG`` +``'n'`` ``Py_ssize_t`` +``'O'`` ``object`` +``'O!'`` ``object(subclass_of='&PySomething_Type')`` +``'O&'`` ``object(converter='name_of_c_function')`` +``'p'`` ``bool`` +``'S'`` ``PyBytesObject`` +``'s'`` ``str`` +``'s#'`` ``str(zeroes=True)`` +``'s*'`` ``Py_buffer(accept={buffer, str})`` +``'U'`` ``unicode`` +``'u'`` ``Py_UNICODE`` +``'u#'`` ``Py_UNICODE(zeroes=True)`` +``'w*'`` ``Py_buffer(accept={rwbuffer})`` +``'Y'`` ``PyByteArrayObject`` +``'y'`` ``str(accept={bytes})`` +``'y#'`` ``str(accept={robuffer}, zeroes=True)`` +``'y*'`` ``Py_buffer`` +``'Z'`` ``Py_UNICODE(accept={str, NoneType})`` +``'Z#'`` ``Py_UNICODE(accept={str, NoneType}, zeroes=True)`` +``'z'`` ``str(accept={str, NoneType})`` +``'z#'`` ``str(accept={str, NoneType}, zeroes=True)`` +``'z*'`` ``Py_buffer(accept={buffer, str, NoneType})`` +========= ================================================================================= + +As an example, here's our sample ``pickle.Pickler.dump`` using the proper +converter:: + + /*[clinic input] + pickle.Pickler.dump + + obj: object + The object to be pickled. + / + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +Argument Clinic will show you all the converters it has +available. For each converter it'll show you all the parameters +it accepts, along with the default value for each parameter. +Just run ``Tools/clinic/clinic.py --converters`` to see the full list. + +Py_buffer +--------- + +When using the ``Py_buffer`` converter +(or the ``'s*'``, ``'w*'``, ``'*y'``, or ``'z*'`` legacy converters), +you *must* not call :c:func:`PyBuffer_Release` on the provided buffer. +Argument Clinic generates code that does it for you (in the parsing function). + + + +Advanced converters +------------------- + +Remember those format units you skipped for your first +time because they were advanced? Here's how to handle those too. + +The trick is, all those format units take arguments--either +conversion functions, or types, or strings specifying an encoding. +(But "legacy converters" don't support arguments. That's why we +skipped them for your first function.) The argument you specified +to the format unit is now an argument to the converter; this +argument is either ``converter`` (for ``O&``), ``subclass_of`` (for ``O!``), +or ``encoding`` (for all the format units that start with ``e``). + +When using ``subclass_of``, you may also want to use the other +custom argument for ``object()``: ``type``, which lets you set the type +actually used for the parameter. For example, if you want to ensure +that the object is a subclass of ``PyUnicode_Type``, you probably want +to use the converter ``object(type='PyUnicodeObject *', subclass_of='&PyUnicode_Type')``. + +One possible problem with using Argument Clinic: it takes away some possible +flexibility for the format units starting with ``e``. When writing a +``PyArg_Parse`` call by hand, you could theoretically decide at runtime what +encoding string to pass in to :c:func:`PyArg_ParseTuple`. But now this string must +be hard-coded at Argument-Clinic-preprocessing-time. This limitation is deliberate; +it made supporting this format unit much easier, and may allow for future optimizations. +This restriction doesn't seem unreasonable; CPython itself always passes in static +hard-coded encoding strings for parameters whose format units start with ``e``. + + +.. _default_values: + +Parameter default values +------------------------ + +Default values for parameters can be any of a number of values. +At their simplest, they can be string, int, or float literals:: + + foo: str = "abc" + bar: int = 123 + bat: float = 45.6 + +They can also use any of Python's built-in constants:: + + yep: bool = True + nope: bool = False + nada: object = None + +There's also special support for a default value of ``NULL``, and +for simple expressions, documented in the following sections. + + +The ``NULL`` default value +-------------------------- + +For string and object parameters, you can set them to ``None`` to indicate +that there's no default. However, that means the C variable will be +initialized to ``Py_None``. For convenience's sakes, there's a special +value called ``NULL`` for just this reason: from Python's perspective it +behaves like a default value of ``None``, but the C variable is initialized +with ``NULL``. + +Expressions specified as default values +--------------------------------------- + +The default value for a parameter can be more than just a literal value. +It can be an entire expression, using math operators and looking up attributes +on objects. However, this support isn't exactly simple, because of some +non-obvious semantics. + +Consider the following example:: + + foo: Py_ssize_t = sys.maxsize - 1 + +``sys.maxsize`` can have different values on different platforms. Therefore +Argument Clinic can't simply evaluate that expression locally and hard-code it +in C. So it stores the default in such a way that it will get evaluated at +runtime, when the user asks for the function's signature. + +What namespace is available when the expression is evaluated? It's evaluated +in the context of the module the builtin came from. So, if your module has an +attribute called "``max_widgets``", you may simply use it:: + + foo: Py_ssize_t = max_widgets + +If the symbol isn't found in the current module, it fails over to looking in +``sys.modules``. That's how it can find ``sys.maxsize`` for example. (Since you +don't know in advance what modules the user will load into their interpreter, +it's best to restrict yourself to modules that are preloaded by Python itself.) + +Evaluating default values only at runtime means Argument Clinic can't compute +the correct equivalent C default value. So you need to tell it explicitly. +When you use an expression, you must also specify the equivalent expression +in C, using the ``c_default`` parameter to the converter:: + + foo: Py_ssize_t(c_default="PY_SSIZE_T_MAX - 1") = sys.maxsize - 1 + +Another complication: Argument Clinic can't know in advance whether or not the +expression you supply is valid. It parses it to make sure it looks legal, but +it can't *actually* know. You must be very careful when using expressions to +specify values that are guaranteed to be valid at runtime! + +Finally, because expressions must be representable as static C values, there +are many restrictions on legal expressions. Here's a list of Python features +you're not permitted to use: + +* Function calls. +* Inline if statements (``3 if foo else 5``). +* Automatic sequence unpacking (``*[1, 2, 3]``). +* List/set/dict comprehensions and generator expressions. +* Tuple/list/set/dict literals. + + + +Using a return converter +------------------------ + +By default the impl function Argument Clinic generates for you returns ``PyObject *``. +But your C function often computes some C type, then converts it into the ``PyObject *`` +at the last moment. Argument Clinic handles converting your inputs from Python types +into native C types--why not have it convert your return value from a native C type +into a Python type too? + +That's what a "return converter" does. It changes your impl function to return +some C type, then adds code to the generated (non-impl) function to handle converting +that value into the appropriate ``PyObject *``. + +The syntax for return converters is similar to that of parameter converters. +You specify the return converter like it was a return annotation on the +function itself. Return converters behave much the same as parameter converters; +they take arguments, the arguments are all keyword-only, and if you're not changing +any of the default arguments you can omit the parentheses. + +(If you use both ``"as"`` *and* a return converter for your function, +the ``"as"`` should come before the return converter.) + +There's one additional complication when using return converters: how do you +indicate an error has occurred? Normally, a function returns a valid (non-``NULL``) +pointer for success, and ``NULL`` for failure. But if you use an integer return converter, +all integers are valid. How can Argument Clinic detect an error? Its solution: each return +converter implicitly looks for a special value that indicates an error. If you return +that value, and an error has been set (``PyErr_Occurred()`` returns a true +value), then the generated code will propagate the error. Otherwise it will +encode the value you return like normal. + +Currently Argument Clinic supports only a few return converters:: + + bool + int + unsigned int + long + unsigned int + size_t + Py_ssize_t + float + double + DecodeFSDefault + +None of these take parameters. For the first three, return -1 to indicate +error. For ``DecodeFSDefault``, the return type is ``char *``; return a NULL +pointer to indicate an error. + +(There's also an experimental ``NoneType`` converter, which lets you +return ``Py_None`` on success or ``NULL`` on failure, without having +to increment the reference count on ``Py_None``. I'm not sure it adds +enough clarity to be worth using.) + +To see all the return converters Argument Clinic supports, along with +their parameters (if any), +just run ``Tools/clinic/clinic.py --converters`` for the full list. + + +Cloning existing functions +-------------------------- + +If you have a number of functions that look similar, you may be able to +use Clinic's "clone" feature. When you clone an existing function, +you reuse: + +* its parameters, including + + * their names, + + * their converters, with all parameters, + + * their default values, + + * their per-parameter docstrings, + + * their *kind* (whether they're positional only, + positional or keyword, or keyword only), and + +* its return converter. + +The only thing not copied from the original function is its docstring; +the syntax allows you to specify a new docstring. + +Here's the syntax for cloning a function:: + + /*[clinic input] + module.class.new_function [as c_basename] = module.class.existing_function + + Docstring for new_function goes here. + [clinic start generated code]*/ + +(The functions can be in different modules or classes. I wrote +``module.class`` in the sample just to illustrate that you must +use the full path to *both* functions.) + +Sorry, there's no syntax for partially-cloning a function, or cloning a function +then modifying it. Cloning is an all-or nothing proposition. + +Also, the function you are cloning from must have been previously defined +in the current file. + +Calling Python code +------------------- + +The rest of the advanced topics require you to write Python code +which lives inside your C file and modifies Argument Clinic's +runtime state. This is simple: you simply define a Python block. + +A Python block uses different delimiter lines than an Argument +Clinic function block. It looks like this:: + + /*[python input] + # python code goes here + [python start generated code]*/ + +All the code inside the Python block is executed at the +time it's parsed. All text written to stdout inside the block +is redirected into the "output" after the block. + +As an example, here's a Python block that adds a static integer +variable to the C code:: + + /*[python input] + print('static int __ignored_unused_variable__ = 0;') + [python start generated code]*/ + static int __ignored_unused_variable__ = 0; + /*[python checksum:...]*/ + + +Using a "self converter" +------------------------ + +Argument Clinic automatically adds a "self" parameter for you +using a default converter. It automatically sets the ``type`` +of this parameter to the "pointer to an instance" you specified +when you declared the type. However, you can override +Argument Clinic's converter and specify one yourself. +Just add your own ``self`` parameter as the first parameter in a +block, and ensure that its converter is an instance of +``self_converter`` or a subclass thereof. + +What's the point? This lets you override the type of ``self``, +or give it a different default name. + +How do you specify the custom type you want to cast ``self`` to? +If you only have one or two functions with the same type for ``self``, +you can directly use Argument Clinic's existing ``self`` converter, +passing in the type you want to use as the ``type`` parameter:: + + /*[clinic input] + + _pickle.Pickler.dump + + self: self(type="PicklerObject *") + obj: object + / + + Write a pickled representation of the given object to the open file. + [clinic start generated code]*/ + +On the other hand, if you have a lot of functions that will use the same +type for ``self``, it's best to create your own converter, subclassing +``self_converter`` but overwriting the ``type`` member:: + + /*[python input] + class PicklerObject_converter(self_converter): + type = "PicklerObject *" + [python start generated code]*/ + + /*[clinic input] + + _pickle.Pickler.dump + + self: PicklerObject + obj: object + / + + Write a pickled representation of the given object to the open file. + [clinic start generated code]*/ + + + +Writing a custom converter +-------------------------- + +As we hinted at in the previous section... you can write your own converters! +A converter is simply a Python class that inherits from ``CConverter``. +The main purpose of a custom converter is if you have a parameter using +the ``O&`` format unit--parsing this parameter means calling +a :c:func:`PyArg_ParseTuple` "converter function". + +Your converter class should be named ``*something*_converter``. +If the name follows this convention, then your converter class +will be automatically registered with Argument Clinic; its name +will be the name of your class with the ``_converter`` suffix +stripped off. (This is accomplished with a metaclass.) + +You shouldn't subclass ``CConverter.__init__``. Instead, you should +write a ``converter_init()`` function. ``converter_init()`` +always accepts a ``self`` parameter; after that, all additional +parameters *must* be keyword-only. Any arguments passed in to +the converter in Argument Clinic will be passed along to your +``converter_init()``. + +There are some additional members of ``CConverter`` you may wish +to specify in your subclass. Here's the current list: + +``type`` + The C type to use for this variable. + ``type`` should be a Python string specifying the type, e.g. ``int``. + If this is a pointer type, the type string should end with ``' *'``. + +``default`` + The Python default value for this parameter, as a Python value. + Or the magic value ``unspecified`` if there is no default. + +``py_default`` + ``default`` as it should appear in Python code, + as a string. + Or ``None`` if there is no default. + +``c_default`` + ``default`` as it should appear in C code, + as a string. + Or ``None`` if there is no default. + +``c_ignored_default`` + The default value used to initialize the C variable when + there is no default, but not specifying a default may + result in an "uninitialized variable" warning. This can + easily happen when using option groups--although + properly-written code will never actually use this value, + the variable does get passed in to the impl, and the + C compiler will complain about the "use" of the + uninitialized value. This value should always be a + non-empty string. + +``converter`` + The name of the C converter function, as a string. + +``impl_by_reference`` + A boolean value. If true, + Argument Clinic will add a ``&`` in front of the name of + the variable when passing it into the impl function. + +``parse_by_reference`` + A boolean value. If true, + Argument Clinic will add a ``&`` in front of the name of + the variable when passing it into :c:func:`PyArg_ParseTuple`. + + +Here's the simplest example of a custom converter, from ``Modules/zlibmodule.c``:: + + /*[python input] + + class uint_converter(CConverter): + type = 'unsigned int' + converter = 'uint_converter' + + [python start generated code]*/ + /*[python end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + +This block adds a converter to Argument Clinic named ``uint``. Parameters +declared as ``uint`` will be declared as type ``unsigned int``, and will +be parsed by the ``'O&'`` format unit, which will call the ``uint_converter`` +converter function. +``uint`` variables automatically support default values. + +More sophisticated custom converters can insert custom C code to +handle initialization and cleanup. +You can see more examples of custom converters in the CPython +source tree; grep the C files for the string ``CConverter``. + +Writing a custom return converter +--------------------------------- + +Writing a custom return converter is much like writing +a custom converter. Except it's somewhat simpler, because return +converters are themselves much simpler. + +Return converters must subclass ``CReturnConverter``. +There are no examples yet of custom return converters, +because they are not widely used yet. If you wish to +write your own return converter, please read ``Tools/clinic/clinic.py``, +specifically the implementation of ``CReturnConverter`` and +all its subclasses. + +METH_O and METH_NOARGS +---------------------------------------------- + +To convert a function using ``METH_O``, make sure the function's +single argument is using the ``object`` converter, and mark the +arguments as positional-only:: + + /*[clinic input] + meth_o_sample + + argument: object + / + [clinic start generated code]*/ + + +To convert a function using ``METH_NOARGS``, just don't specify +any arguments. + +You can still use a self converter, a return converter, and specify +a ``type`` argument to the object converter for ``METH_O``. + +tp_new and tp_init functions +---------------------------------------------- + +You can convert ``tp_new`` and ``tp_init`` functions. Just name +them ``__new__`` or ``__init__`` as appropriate. Notes: + +* The function name generated for ``__new__`` doesn't end in ``__new__`` + like it would by default. It's just the name of the class, converted + into a valid C identifier. + +* No ``PyMethodDef`` ``#define`` is generated for these functions. + +* ``__init__`` functions return ``int``, not ``PyObject *``. + +* Use the docstring as the class docstring. + +* Although ``__new__`` and ``__init__`` functions must always + accept both the ``args`` and ``kwargs`` objects, when converting + you may specify any signature for these functions that you like. + (If your function doesn't support keywords, the parsing function + generated will throw an exception if it receives any.) + +Changing and redirecting Clinic's output +---------------------------------------- + +It can be inconvenient to have Clinic's output interspersed with +your conventional hand-edited C code. Luckily, Clinic is configurable: +you can buffer up its output for printing later (or earlier!), or write +its output to a separate file. You can also add a prefix or suffix to +every line of Clinic's generated output. + +While changing Clinic's output in this manner can be a boon to readability, +it may result in Clinic code using types before they are defined, or +your code attempting to use Clinic-generated code befire it is defined. +These problems can be easily solved by rearranging the declarations in your file, +or moving where Clinic's generated code goes. (This is why the default behavior +of Clinic is to output everything into the current block; while many people +consider this hampers readability, it will never require rearranging your +code to fix definition-before-use problems.) + +Let's start with defining some terminology: + +*field* + A field, in this context, is a subsection of Clinic's output. + For example, the ``#define`` for the ``PyMethodDef`` structure + is a field, called ``methoddef_define``. Clinic has seven + different fields it can output per function definition:: + + docstring_prototype + docstring_definition + methoddef_define + impl_prototype + parser_prototype + parser_definition + impl_definition + + All the names are of the form ``"<a>_<b>"``, + where ``"<a>"`` is the semantic object represented (the parsing function, + the impl function, the docstring, or the methoddef structure) and ``"<b>"`` + represents what kind of statement the field is. Field names that end in + ``"_prototype"`` + represent forward declarations of that thing, without the actual body/data + of the thing; field names that end in ``"_definition"`` represent the actual + definition of the thing, with the body/data of the thing. (``"methoddef"`` + is special, it's the only one that ends with ``"_define"``, representing that + it's a preprocessor #define.) + +*destination* + A destination is a place Clinic can write output to. There are + five built-in destinations: + + ``block`` + The default destination: printed in the output section of + the current Clinic block. + + ``buffer`` + A text buffer where you can save text for later. Text sent + here is appended to the end of any exsiting text. It's an + error to have any text left in the buffer when Clinic finishes + processing a file. + + ``file`` + A separate "clinic file" that will be created automatically by Clinic. + The filename chosen for the file is ``{basename}.clinic{extension}``, + where ``basename`` and ``extension`` were assigned the output + from ``os.path.splitext()`` run on the current file. (Example: + the ``file`` destination for ``_pickle.c`` would be written to + ``_pickle.clinic.c``.) + + **Important: When using a** ``file`` **destination, you** + *must check in* **the generated file!** + + ``two-pass`` + A buffer like ``buffer``. However, a two-pass buffer can only + be written once, and it prints out all text sent to it during + all of processing, even from Clinic blocks *after* the + + ``suppress`` + The text is suppressed--thrown away. + + +Clinic defines five new directives that let you reconfigure its output. + +The first new directive is ``dump``:: + + dump <destination> + +This dumps the current contents of the named destination into the output of +the current block, and empties it. This only works with ``buffer`` and +``two-pass`` destinations. + +The second new directive is ``output``. The most basic form of ``output`` +is like this:: + + output <field> <destination> + +This tells Clinic to output *field* to *destination*. ``output`` also +supports a special meta-destination, called ``everything``, which tells +Clinic to output *all* fields to that *destination*. + +``output`` has a number of other functions:: + + output push + output pop + output preset <preset> + + +``output push`` and ``output pop`` allow you to push and pop +configurations on an internal configuration stack, so that you +can temporarily modify the output configuration, then easily restore +the previous configuration. Simply push before your change to save +the current configuration, then pop when you wish to restore the +previous configuration. + +``output preset`` sets Clinic's output to one of several built-in +preset configurations, as follows: + + ``block`` + Clinic's original starting configuration. Writes everything + immediately after the input block. + + Suppress the ``parser_prototype`` + and ``docstring_prototype``, write everything else to ``block``. + + ``file`` + Designed to write everything to the "clinic file" that it can. + You then ``#include`` this file near the top of your file. + You may need to rearrange your file to make this work, though + usually this just means creating forward declarations for various + ``typedef`` and ``PyTypeObject`` definitions. + + Suppress the ``parser_prototype`` + and ``docstring_prototype``, write the ``impl_definition`` to + ``block``, and write everything else to ``file``. + + The default filename is ``"{dirname}/clinic/{basename}.h"``. + + ``buffer`` + Save up all most of the output from Clinic, to be written into + your file near the end. For Python files implementing modules + or builtin types, it's recommended that you dump the buffer + just above the static structures for your module or + builtin type; these are normally very near the end. Using + ``buffer`` may require even more editing than ``file``, if + your file has static ``PyMethodDef`` arrays defined in the + middle of the file. + + Suppress the ``parser_prototype``, ``impl_prototype``, + and ``docstring_prototype``, write the ``impl_definition`` to + ``block``, and write everything else to ``file``. + + ``two-pass`` + Similar to the ``buffer`` preset, but writes forward declarations to + the ``two-pass`` buffer, and definitions to the ``buffer``. + This is similar to the ``buffer`` preset, but may require + less editing than ``buffer``. Dump the ``two-pass`` buffer + near the top of your file, and dump the ``buffer`` near + the end just like you would when using the ``buffer`` preset. + + Suppresses the ``impl_prototype``, write the ``impl_definition`` + to ``block``, write ``docstring_prototype``, ``methoddef_define``, + and ``parser_prototype`` to ``two-pass``, write everything else + to ``buffer``. + + ``partial-buffer`` + Similar to the ``buffer`` preset, but writes more things to ``block``, + only writing the really big chunks of generated code to ``buffer``. + This avoids the definition-before-use problem of ``buffer`` completely, + at the small cost of having slightly more stuff in the block's output. + Dump the ``buffer`` near the end, just like you would when using + the ``buffer`` preset. + + Suppresses the ``impl_prototype``, write the ``docstring_definition`` + and ``parser_definition`` to ``buffer``, write everything else to ``block``. + +The third new directive is ``destination``:: + + destination <name> <command> [...] + +This performs an operation on the destination named ``name``. + +There are two defined subcommands: ``new`` and ``clear``. + +The ``new`` subcommand works like this:: + + destination <name> new <type> + +This creates a new destination with name ``<name>`` and type ``<type>``. + +There are five destination types: + + ``suppress`` + Throws the text away. + + ``block`` + Writes the text to the current block. This is what Clinic + originally did. + + ``buffer`` + A simple text buffer, like the "buffer" builtin destination above. + + ``file`` + A text file. The file destination takes an extra argument, + a template to use for building the filename, like so: + + destination <name> new <type> <file_template> + + The template can use three strings internally that will be replaced + by bits of the filename: + + {path} + The full path to the file, including directory and full filename. + {dirname} + The name of the directory the file is in. + {basename} + Just the name of the file, not including the directory. + {basename_root} + Basename with the extension clipped off + (everything up to but not including the last '.'). + {basename_extension} + The last '.' and everything after it. If the basename + does not contain a period, this will be the empty string. + + If there are no periods in the filename, {basename} and {filename} + are the same, and {extension} is empty. "{basename}{extension}" + is always exactly the same as "{filename}"." + + ``two-pass`` + A two-pass buffer, like the "two-pass" builtin destination above. + + +The ``clear`` subcommand works like this:: + + destination <name> clear + +It removes all the accumulated text up to this point in the destination. +(I don't know what you'd need this for, but I thought maybe it'd be +useful while someone's experimenting.) + +The fourth new directive is ``set``:: + + set line_prefix "string" + set line_suffix "string" + +``set`` lets you set two internal variables in Clinic. +``line_prefix`` is a string that will be prepended to every line of Clinic's output; +``line_suffix`` is a string that will be appended to every line of Clinic's output. + +Both of these support two format strings: + + ``{block comment start}`` + Turns into the string ``/*``, the start-comment text sequence for C files. + + ``{block comment end}`` + Turns into the string ``*/``, the end-comment text sequence for C files. + +The final new directive is one you shouldn't need to use directly, +called ``preserve``:: + + preserve + +This tells Clinic that the current contents of the output should be kept, unmodifed. +This is used internally by Clinic when dumping output into ``file`` files; wrapping +it in a Clinic block lets Clinic use its existing checksum functionality to ensure +the file was not modified by hand before it gets overwritten. + + +The #ifdef trick +---------------------------------------------- + +If you're converting a function that isn't available on all platforms, +there's a trick you can use to make life a little easier. The existing +code probably looks like this:: + + #ifdef HAVE_FUNCTIONNAME + static module_functionname(...) + { + ... + } + #endif /* HAVE_FUNCTIONNAME */ + +And then in the ``PyMethodDef`` structure at the bottom the existing code +will have:: + + #ifdef HAVE_FUNCTIONNAME + {'functionname', ... }, + #endif /* HAVE_FUNCTIONNAME */ + +In this scenario, you should enclose the body of your impl function inside the ``#ifdef``, +like so:: + + #ifdef HAVE_FUNCTIONNAME + /*[clinic input] + module.functionname + ... + [clinic start generated code]*/ + static module_functionname(...) + { + ... + } + #endif /* HAVE_FUNCTIONNAME */ + +Then, remove those three lines from the ``PyMethodDef`` structure, +replacing them with the macro Argument Clinic generated:: + + MODULE_FUNCTIONNAME_METHODDEF + +(You can find the real name for this macro inside the generated code. +Or you can calculate it yourself: it's the name of your function as defined +on the first line of your block, but with periods changed to underscores, +uppercased, and ``"_METHODDEF"`` added to the end.) + +Perhaps you're wondering: what if ``HAVE_FUNCTIONNAME`` isn't defined? +The ``MODULE_FUNCTIONNAME_METHODDEF`` macro won't be defined either! + +Here's where Argument Clinic gets very clever. It actually detects that the +Argument Clinic block might be deactivated by the ``#ifdef``. When that +happens, it generates a little extra code that looks like this:: + + #ifndef MODULE_FUNCTIONNAME_METHODDEF + #define MODULE_FUNCTIONNAME_METHODDEF + #endif /* !defined(MODULE_FUNCTIONNAME_METHODDEF) */ + +That means the macro always works. If the function is defined, this turns +into the correct structure, including the trailing comma. If the function is +undefined, this turns into nothing. + +However, this causes one ticklish problem: where should Argument Clinic put this +extra code when using the "block" output preset? It can't go in the output block, +because that could be decativated by the ``#ifdef``. (That's the whole point!) + +In this situation, Argument Clinic writes the extra code to the "buffer" destination. +This may mean that you get a complaint from Argument Clinic:: + + Warning in file "Modules/posixmodule.c" on line 12357: + Destination buffer 'buffer' not empty at end of file, emptying. + +When this happens, just open your file, find the ``dump buffer`` block that +Argument Clinic added to your file (it'll be at the very bottom), then +move it above the ``PyMethodDef`` structure where that macro is used. + + + +Using Argument Clinic in Python files +------------------------------------- + +It's actually possible to use Argument Clinic to preprocess Python files. +There's no point to using Argument Clinic blocks, of course, as the output +wouldn't make any sense to the Python interpreter. But using Argument Clinic +to run Python blocks lets you use Python as a Python preprocessor! + +Since Python comments are different from C comments, Argument Clinic +blocks embedded in Python files look slightly different. They look like this:: + + #/*[python input] + #print("def foo(): pass") + #[python start generated code]*/ + def foo(): pass + #/*[python checksum:...]*/ diff --git a/Doc/howto/cporting.rst b/Doc/howto/cporting.rst index 1ad77d687e7c..d7a708630259 100644 --- a/Doc/howto/cporting.rst +++ b/Doc/howto/cporting.rst @@ -43,10 +43,9 @@ separating others. str/unicode Unification ----------------------- - -Python 3's :func:`str` (``PyString_*`` functions in C) type is equivalent to -Python 2's :func:`unicode` (``PyUnicode_*``). The old 8-bit string type has -become :func:`bytes`. Python 2.6 and later provide a compatibility header, +Python 3's :func:`str` type is equivalent to Python 2's :func:`unicode`; the C +functions are called ``PyUnicode_*`` for both. The old 8-bit string type has become +:func:`bytes`, with C functions called ``PyBytes_*``. Python 2.6 and later provide a compatibility header, :file:`bytesobject.h`, mapping ``PyBytes`` names to ``PyString`` ones. For best compatibility with Python 3, :c:type:`PyUnicode` should be used for textual data and :c:type:`PyBytes` for binary data. It's also important to remember that @@ -253,6 +252,6 @@ Other options ============= If you are writing a new extension module, you might consider `Cython -<http://www.cython.org>`_. It translates a Python-like language to C. The +<http://cython.org/>`_. It translates a Python-like language to C. The extension modules it creates are compatible with Python 3 and Python 2. diff --git a/Doc/howto/curses.rst b/Doc/howto/curses.rst index ea62b1c849e3..87a5cab142bf 100644 --- a/Doc/howto/curses.rst +++ b/Doc/howto/curses.rst @@ -538,12 +538,12 @@ the Python interface. Often this isn't because they're difficult to implement, but because no one has needed them yet. Also, Python doesn't yet support the menu library associated with ncurses. Patches adding support for these would be welcome; see -`the Python Developer's Guide <http://docs.python.org/devguide/>`_ to +`the Python Developer's Guide <https://docs.python.org/devguide/>`_ to learn more about submitting patches to Python. * `Writing Programs with NCURSES <http://invisible-island.net/ncurses/ncurses-intro.html>`_: a lengthy tutorial for C programmers. -* `The ncurses man page <http://www.linuxmanpages.com/man3/ncurses.3x.php>`_ +* `The ncurses man page <http://linux.die.net/man/3/ncurses>`_ * `The ncurses FAQ <http://invisible-island.net/ncurses/ncurses.faq.html>`_ * `"Use curses... don't swear" <http://www.youtube.com/watch?v=eN1eZtjLEnU>`_: video of a PyCon 2013 talk on controlling terminals using curses or Urwid. diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst index a0c698899b72..f018b0e89310 100644 --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -92,9 +92,9 @@ For objects, the machinery is in :meth:`object.__getattribute__` which transforms ``b.x`` into ``type(b).__dict__['x'].__get__(b, type(b))``. The implementation works through a precedence chain that gives data descriptors priority over instance variables, instance variables priority over non-data -descriptors, and assigns lowest priority to :meth:`__getattr__` if provided. The -full C implementation can be found in :c:func:`PyObject_GenericGetAttr()` in -`Objects/object.c <http://svn.python.org/view/python/trunk/Objects/object.c?view=markup>`_\. +descriptors, and assigns lowest priority to :meth:`__getattr__` if provided. +The full C implementation can be found in :c:func:`PyObject_GenericGetAttr()` in +:source:`Objects/object.c`. For classes, the machinery is in :meth:`type.__getattribute__` which transforms ``B.x`` into ``B.__dict__['x'].__get__(None, B)``. In pure Python, it looks @@ -124,10 +124,10 @@ and then returns ``A.__dict__['m'].__get__(obj, B)``. If not a descriptor, search using :meth:`object.__getattribute__`. The implementation details are in :c:func:`super_getattro()` in -`Objects/typeobject.c <http://svn.python.org/view/python/trunk/Objects/typeobject.c?view=markup>`_ -and a pure Python equivalent can be found in `Guido's Tutorial`_. +:source:`Objects/typeobject.c`. and a pure Python equivalent can be found in +`Guido's Tutorial`_. -.. _`Guido's Tutorial`: http://www.python.org/2.2.3/descrintro.html#cooperation +.. _`Guido's Tutorial`: https://www.python.org/download/releases/2.2.3/descrintro/#cooperation The details above show that the mechanism for descriptors is embedded in the :meth:`__getattribute__()` methods for :class:`object`, :class:`type`, and @@ -300,10 +300,9 @@ Running the interpreter shows how the function descriptor works in practice:: The output suggests that bound and unbound methods are two different types. While they could have been implemented that way, the actual C implementation of -:c:type:`PyMethod_Type` in -`Objects/classobject.c <http://svn.python.org/view/python/trunk/Objects/classobject.c?view=markup>`_ -is a single object with two different representations depending on whether the -:attr:`im_self` field is set or is *NULL* (the C equivalent of *None*). +:c:type:`PyMethod_Type` in :source:`Objects/classobject.c` is a single object +with two different representations depending on whether the :attr:`im_self` +field is set or is *NULL* (the C equivalent of *None*). Likewise, the effects of calling a method object depend on the :attr:`im_self` field. If set (meaning bound), the original function (stored in the diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst index 97c90c7c0b88..945a240666cf 100644 --- a/Doc/howto/functional.rst +++ b/Doc/howto/functional.rst @@ -481,10 +481,10 @@ Here's a sample usage of the ``generate_ints()`` generator: You could equally write ``for i in generate_ints(5)``, or ``a,b,c = generate_ints(3)``. -Inside a generator function, ``return value`` is semantically equivalent to -``raise StopIteration(value)``. If no value is returned or the bottom of the -function is reached, the procession of values ends and the generator cannot -return any further values. +Inside a generator function, ``return value`` causes ``StopIteration(value)`` +to be raised from the :meth:`~generator.__next__` method. Once this happens, or +the bottom of the function is reached, the procession of values ends and the +generator cannot yield any further values. You could achieve the effect of generators manually by writing your own class and storing all the local variables of the generator as instance variables. For @@ -583,7 +583,7 @@ And here's an example of changing the counter: Because ``yield`` will often be returning ``None``, you should always check for this case. Don't just use its value in expressions unless you're sure that the -:meth:`~generator.send` method will be the only method used resume your +:meth:`~generator.send` method will be the only method used to resume your generator function. In addition to :meth:`~generator.send`, there are two other methods on diff --git a/Doc/howto/index.rst b/Doc/howto/index.rst index 81a4f8b98d5c..2c9d69910a6d 100644 --- a/Doc/howto/index.rst +++ b/Doc/howto/index.rst @@ -28,4 +28,5 @@ Currently, the HOWTOs are: webservers.rst argparse.rst ipaddress.rst + clinic.rst diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index feb9b6c1a854..b979aa7d7d83 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -325,6 +325,15 @@ which, when run, will produce:: MainThread: Look out! +.. versionchanged:: 3.5 + Prior to Python 3.5, the :class:`QueueListener` always passed every message + received from the queue to every handler it was initialized with. (This was + because it was assumed that level filtering was all done on the other side, + where the queue is filled.) From 3.5 onwards, this behaviour can be changed + by passing a keyword argument ``respect_handler_level=True`` to the + listener's constructor. When this is done, the listener compares the level + of each message with the handler's level, and only passes a message to a + handler if it's appropriate to do so. .. _network-logging: @@ -416,7 +425,7 @@ module. Here is a basic working example:: Simple TCP socket-based logging receiver suitable for testing. """ - allow_reuse_address = 1 + allow_reuse_address = True def __init__(self, host='localhost', port=logging.handlers.DEFAULT_TCP_LOGGING_PORT, @@ -649,7 +658,7 @@ file from your processes. The existing :class:`FileHandler` and subclasses do not make use of :mod:`multiprocessing` at present, though they may do so in the future. Note that at present, the :mod:`multiprocessing` module does not provide working lock functionality on all platforms (see -http://bugs.python.org/issue3770). +https://bugs.python.org/issue3770). .. currentmodule:: logging.handlers @@ -839,7 +848,7 @@ separate thread:: }, 'loggers': { 'foo': { - 'handlers' : ['foofile'] + 'handlers': ['foofile'] } }, 'root': { @@ -1308,7 +1317,7 @@ This dictionary is passed to :func:`~config.dictConfig` to put the configuration } For more information about this configuration, you can see the `relevant -section <https://docs.djangoproject.com/en/1.3/topics/logging/#configuring-logging>`_ +section <https://docs.djangoproject.com/en/1.6/topics/logging/#configuring-logging>`_ of the Django documentation. .. _cookbook-rotator-namer: @@ -1408,7 +1417,7 @@ works:: def worker_process(config): """ A number of these are spawned for the purpose of illustration. In - practice, they could be a heterogenous bunch of processes rather than + practice, they could be a heterogeneous bunch of processes rather than ones which are identical to each other. This initialises logging according to the specified configuration, @@ -1527,7 +1536,7 @@ works:: }, 'loggers': { 'foo': { - 'handlers' : ['foofile'] + 'handlers': ['foofile'] } }, 'root': { @@ -1680,7 +1689,7 @@ as in the following complete example:: def main(): logging.basicConfig(level=logging.INFO, format='%(message)s') - logging.info(_('message 1', set_value=set([1, 2, 3]), snowman='\u2603')) + logging.info(_('message 1', set_value={1, 2, 3}, snowman='\u2603')) if __name__ == '__main__': main() @@ -1692,6 +1701,9 @@ When the above script is run, it prints:: Note that the order of items might be different according to the version of Python used. + +.. _custom-handlers: + .. currentmodule:: logging.config Customizing handlers with :func:`dictConfig` @@ -1827,3 +1839,518 @@ Of course, the approach could also be extended to types of handler other than a :class:`~logging.FileHandler` - for example, one of the rotating file handlers, or a different type of handler altogether. + +.. currentmodule:: logging + +.. _formatting-styles: + +Using particular formatting styles throughout your application +-------------------------------------------------------------- + +In Python 3.2, the :class:`~logging.Formatter` gained a ``style`` keyword +parameter which, while defaulting to ``%`` for backward compatibility, allowed +the specification of ``{`` or ``$`` to support the formatting approaches +supported by :meth:`str.format` and :class:`string.Template`. Note that this +governs the formatting of logging messages for final output to logs, and is +completely orthogonal to how an individual logging message is constructed. + +Logging calls (:meth:`~Logger.debug`, :meth:`~Logger.info` etc.) only take +positional parameters for the actual logging message itself, with keyword +parameters used only for determining options for how to handle the logging call +(e.g. the ``exc_info`` keyword parameter to indicate that traceback information +should be logged, or the ``extra`` keyword parameter to indicate additional +contextual information to be added to the log). So you cannot directly make +logging calls using :meth:`str.format` or :class:`string.Template` syntax, +because internally the logging package uses %-formatting to merge the format +string and the variable arguments. There would no changing this while preserving +backward compatibility, since all logging calls which are out there in existing +code will be using %-format strings. + +There have been suggestions to associate format styles with specific loggers, +but that approach also runs into backward compatibility problems because any +existing code could be using a given logger name and using %-formatting. + +For logging to work interoperably between any third-party libraries and your +code, decisions about formatting need to be made at the level of the +individual logging call. This opens up a couple of ways in which alternative +formatting styles can be accommodated. + + +Using LogRecord factories +^^^^^^^^^^^^^^^^^^^^^^^^^ + +In Python 3.2, along with the :class:`~logging.Formatter` changes mentioned +above, the logging package gained the ability to allow users to set their own +:class:`LogRecord` subclasses, using the :func:`setLogRecordFactory` function. +You can use this to set your own subclass of :class:`LogRecord`, which does the +Right Thing by overriding the :meth:`~LogRecord.getMessage` method. The base +class implementation of this method is where the ``msg % args`` formatting +happens, and where you can substitute your alternate formatting; however, you +should be careful to support all formatting styles and allow %-formatting as +the default, to ensure interoperability with other code. Care should also be +taken to call ``str(self.msg)``, just as the base implementation does. + +Refer to the reference documentation on :func:`setLogRecordFactory` and +:class:`LogRecord` for more information. + + +Using custom message objects +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +There is another, perhaps simpler way that you can use {}- and $- formatting to +construct your individual log messages. You may recall (from +:ref:`arbitrary-object-messages`) that when logging you can use an arbitrary +object as a message format string, and that the logging package will call +:func:`str` on that object to get the actual format string. Consider the +following two classes:: + + class BraceMessage(object): + def __init__(self, fmt, *args, **kwargs): + self.fmt = fmt + self.args = args + self.kwargs = kwargs + + def __str__(self): + return self.fmt.format(*self.args, **self.kwargs) + + class DollarMessage(object): + def __init__(self, fmt, **kwargs): + self.fmt = fmt + self.kwargs = kwargs + + def __str__(self): + from string import Template + return Template(self.fmt).substitute(**self.kwargs) + +Either of these can be used in place of a format string, to allow {}- or +$-formatting to be used to build the actual "message" part which appears in the +formatted log output in place of “%(message)s” or “{message}” or “$message”. +If you find it a little unwieldy to use the class names whenever you want to log +something, you can make it more palatable if you use an alias such as ``M`` or +``_`` for the message (or perhaps ``__``, if you are using ``_`` for +localization). + +Examples of this approach are given below. Firstly, formatting with +:meth:`str.format`:: + + >>> __ = BraceMessage + >>> print(__('Message with {0} {1}', 2, 'placeholders')) + Message with 2 placeholders + >>> class Point: pass + ... + >>> p = Point() + >>> p.x = 0.5 + >>> p.y = 0.5 + >>> print(__('Message with coordinates: ({point.x:.2f}, {point.y:.2f})', point=p)) + Message with coordinates: (0.50, 0.50) + +Secondly, formatting with :class:`string.Template`:: + + >>> __ = DollarMessage + >>> print(__('Message with $num $what', num=2, what='placeholders')) + Message with 2 placeholders + >>> + +One thing to note is that you pay no significant performance penalty with this +approach: the actual formatting happens not when you make the logging call, but +when (and if) the logged message is actually about to be output to a log by a +handler. So the only slightly unusual thing which might trip you up is that the +parentheses go around the format string and the arguments, not just the format +string. That’s because the __ notation is just syntax sugar for a constructor +call to one of the ``XXXMessage`` classes shown above. + + +.. _filters-dictconfig: + +.. currentmodule:: logging.config + +Configuring filters with :func:`dictConfig` +------------------------------------------- + +You *can* configure filters using :func:`~logging.config.dictConfig`, though it +might not be obvious at first glance how to do it (hence this recipe). Since +:class:`~logging.Filter` is the only filter class included in the standard +library, and it is unlikely to cater to many requirements (it's only there as a +base class), you will typically need to define your own :class:`~logging.Filter` +subclass with an overridden :meth:`~logging.Filter.filter` method. To do this, +specify the ``()`` key in the configuration dictionary for the filter, +specifying a callable which will be used to create the filter (a class is the +most obvious, but you can provide any callable which returns a +:class:`~logging.Filter` instance). Here is a complete example:: + + import logging + import logging.config + import sys + + class MyFilter(logging.Filter): + def __init__(self, param=None): + self.param = param + + def filter(self, record): + if self.param is None: + allow = True + else: + allow = self.param not in record.msg + if allow: + record.msg = 'changed: ' + record.msg + return allow + + LOGGING = { + 'version': 1, + 'filters': { + 'myfilter': { + '()': MyFilter, + 'param': 'noshow', + } + }, + 'handlers': { + 'console': { + 'class': 'logging.StreamHandler', + 'filters': ['myfilter'] + } + }, + 'root': { + 'level': 'DEBUG', + 'handlers': ['console'] + }, + } + + if __name__ == '__main__': + logging.config.dictConfig(LOGGING) + logging.debug('hello') + logging.debug('hello - noshow') + +This example shows how you can pass configuration data to the callable which +constructs the instance, in the form of keyword parameters. When run, the above +script will print:: + + changed: hello + +which shows that the filter is working as configured. + +A couple of extra points to note: + +* If you can't refer to the callable directly in the configuration (e.g. if it + lives in a different module, and you can't import it directly where the + configuration dictionary is), you can use the form ``ext://...`` as described + in :ref:`logging-config-dict-externalobj`. For example, you could have used + the text ``'ext://__main__.MyFilter'`` instead of ``MyFilter`` in the above + example. + +* As well as for filters, this technique can also be used to configure custom + handlers and formatters. See :ref:`logging-config-dict-userdef` for more + information on how logging supports using user-defined objects in its + configuration, and see the other cookbook recipe :ref:`custom-handlers` above. + + +.. _custom-format-exception: + +Customized exception formatting +------------------------------- + +There might be times when you want to do customized exception formatting - for +argument's sake, let's say you want exactly one line per logged event, even +when exception information is present. You can do this with a custom formatter +class, as shown in the following example:: + + import logging + + class OneLineExceptionFormatter(logging.Formatter): + def formatException(self, exc_info): + """ + Format an exception so that it prints on a single line. + """ + result = super(OneLineExceptionFormatter, self).formatException(exc_info) + return repr(result) # or format into one line however you want to + + def format(self, record): + s = super(OneLineExceptionFormatter, self).format(record) + if record.exc_text: + s = s.replace('\n', '') + '|' + return s + + def configure_logging(): + fh = logging.FileHandler('output.txt', 'w') + f = OneLineExceptionFormatter('%(asctime)s|%(levelname)s|%(message)s|', + '%d/%m/%Y %H:%M:%S') + fh.setFormatter(f) + root = logging.getLogger() + root.setLevel(logging.DEBUG) + root.addHandler(fh) + + def main(): + configure_logging() + logging.info('Sample message') + try: + x = 1 / 0 + except ZeroDivisionError as e: + logging.exception('ZeroDivisionError: %s', e) + + if __name__ == '__main__': + main() + +When run, this produces a file with exactly two lines:: + + 28/01/2015 07:21:23|INFO|Sample message| + 28/01/2015 07:21:23|ERROR|ZeroDivisionError: integer division or modulo by zero|'Traceback (most recent call last):\n File "logtest7.py", line 30, in main\n x = 1 / 0\nZeroDivisionError: integer division or modulo by zero'| + +While the above treatment is simplistic, it points the way to how exception +information can be formatted to your liking. The :mod:`traceback` module may be +helpful for more specialized needs. + +.. _spoken-messages: + +Speaking logging messages +------------------------- + +There might be situations when it is desirable to have logging messages rendered +in an audible rather than a visible format. This is easy to do if you have text- +to-speech (TTS) functionality available in your system, even if it doesn't have +a Python binding. Most TTS systems have a command line program you can run, and +this can be invoked from a handler using :mod:`subprocess`. It's assumed here +that TTS command line programs won't expect to interact with users or take a +long time to complete, and that the frequency of logged messages will be not so +high as to swamp the user with messages, and that it's acceptable to have the +messages spoken one at a time rather than concurrently, The example implementation +below waits for one message to be spoken before the next is processed, and this +might cause other handlers to be kept waiting. Here is a short example showing +the approach, which assumes that the ``espeak`` TTS package is available:: + + import logging + import subprocess + import sys + + class TTSHandler(logging.Handler): + def emit(self, record): + msg = self.format(record) + # Speak slowly in a female English voice + cmd = ['espeak', '-s150', '-ven+f3', msg] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + # wait for the program to finish + p.communicate() + + def configure_logging(): + h = TTSHandler() + root = logging.getLogger() + root.addHandler(h) + # the default formatter just returns the message + root.setLevel(logging.DEBUG) + + def main(): + logging.info('Hello') + logging.debug('Goodbye') + + if __name__ == '__main__': + configure_logging() + sys.exit(main()) + +When run, this script should say "Hello" and then "Goodbye" in a female voice. + +The above approach can, of course, be adapted to other TTS systems and even +other systems altogether which can process messages via external programs run +from a command line. + + +.. _buffered-logging: + +Buffering logging messages and outputting them conditionally +------------------------------------------------------------ + +There might be situations where you want to log messages in a temporary area +and only output them if a certain condition occurs. For example, you may want to +start logging debug events in a function, and if the function completes without +errors, you don't want to clutter the log with the collected debug information, +but if there is an error, you want all the debug information to be output as well +as the error. + +Here is an example which shows how you could do this using a decorator for your +functions where you want logging to behave this way. It makes use of the +:class:`logging.handlers.MemoryHandler`, which allows buffering of logged events +until some condition occurs, at which point the buffered events are ``flushed`` +- passed to another handler (the ``target`` handler) for processing. By default, +the ``MemoryHandler`` flushed when its buffer gets filled up or an event whose +level is greater than or equal to a specified threshold is seen. You can use this +recipe with a more specialised subclass of ``MemoryHandler`` if you want custom +flushing behavior. + +The example script has a simple function, ``foo``, which just cycles through +all the logging levels, writing to ``sys.stderr`` to say what level it's about +to log at, and then actually logging a message that that level. You can pass a +parameter to ``foo`` which, if true, will log at ERROR and CRITICAL levels - +otherwise, it only logs at DEBUG, INFO and WARNING levels. + +The script just arranges to decorate ``foo`` with a decorator which will do the +conditional logging that's required. The decorator takes a logger as a parameter +and attaches a memory handler for the duration of the call to the decorated +function. The decorator can be additionally parameterised using a target handler, +a level at which flushing should occur, and a capacity for the buffer. These +default to a :class:`~logging.StreamHandler` which writes to ``sys.stderr``, +``logging.ERROR`` and ``100`` respectively. + +Here's the script:: + + import logging + from logging.handlers import MemoryHandler + import sys + + logger = logging.getLogger(__name__) + logger.addHandler(logging.NullHandler()) + + def log_if_errors(logger, target_handler=None, flush_level=None, capacity=None): + if target_handler is None: + target_handler = logging.StreamHandler() + if flush_level is None: + flush_level = logging.ERROR + if capacity is None: + capacity = 100 + handler = MemoryHandler(capacity, flushLevel=flush_level, target=target_handler) + + def decorator(fn): + def wrapper(*args, **kwargs): + logger.addHandler(handler) + try: + return fn(*args, **kwargs) + except Exception: + logger.exception('call failed') + raise + finally: + super(MemoryHandler, handler).flush() + logger.removeHandler(handler) + return wrapper + + return decorator + + def write_line(s): + sys.stderr.write('%s\n' % s) + + def foo(fail=False): + write_line('about to log at DEBUG ...') + logger.debug('Actually logged at DEBUG') + write_line('about to log at INFO ...') + logger.info('Actually logged at INFO') + write_line('about to log at WARNING ...') + logger.warning('Actually logged at WARNING') + if fail: + write_line('about to log at ERROR ...') + logger.error('Actually logged at ERROR') + write_line('about to log at CRITICAL ...') + logger.critical('Actually logged at CRITICAL') + return fail + + decorated_foo = log_if_errors(logger)(foo) + + if __name__ == '__main__': + logger.setLevel(logging.DEBUG) + write_line('Calling undecorated foo with False') + assert not foo(False) + write_line('Calling undecorated foo with True') + assert foo(True) + write_line('Calling decorated foo with False') + assert not decorated_foo(False) + write_line('Calling decorated foo with True') + assert decorated_foo(True) + +When this script is run, the following output should be observed:: + + Calling undecorated foo with False + about to log at DEBUG ... + about to log at INFO ... + about to log at WARNING ... + Calling undecorated foo with True + about to log at DEBUG ... + about to log at INFO ... + about to log at WARNING ... + about to log at ERROR ... + about to log at CRITICAL ... + Calling decorated foo with False + about to log at DEBUG ... + about to log at INFO ... + about to log at WARNING ... + Calling decorated foo with True + about to log at DEBUG ... + about to log at INFO ... + about to log at WARNING ... + about to log at ERROR ... + Actually logged at DEBUG + Actually logged at INFO + Actually logged at WARNING + Actually logged at ERROR + about to log at CRITICAL ... + Actually logged at CRITICAL + +As you can see, actual logging output only occurs when an event is logged whose +severity is ERROR or greater, but in that case, any previous events at lower +severities are also logged. + +You can of course use the conventional means of decoration:: + + @log_if_errors(logger) + def foo(fail=False): + ... + + +.. _utc-formatting: + +Formatting times using UTC (GMT) via configuration +-------------------------------------------------- + +Sometimes you want to format times using UTC, which can be done using a class +such as `UTCFormatter`, shown below:: + + import logging + import time + + class UTCFormatter(logging.Formatter): + converter = time.gmtime + +and you can then use the ``UTCFormatter`` in your code instead of +:class:`~logging.Formatter`. If you want to do that via configuration, you can +use the :func:`~logging.config.dictConfig` API with an approach illustrated by +the following complete example:: + + import logging + import logging.config + import time + + class UTCFormatter(logging.Formatter): + converter = time.gmtime + + LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'formatters': { + 'utc': { + '()': UTCFormatter, + 'format': '%(asctime)s %(message)s', + }, + 'local': { + 'format': '%(asctime)s %(message)s', + } + }, + 'handlers': { + 'console1': { + 'class': 'logging.StreamHandler', + 'formatter': 'utc', + }, + 'console2': { + 'class': 'logging.StreamHandler', + 'formatter': 'local', + }, + }, + 'root': { + 'handlers': ['console1', 'console2'], + } + } + + if __name__ == '__main__': + logging.config.dictConfig(LOGGING) + logging.warning('The local time is %s', time.asctime()) + +When this script is run, it should print something like:: + + 2015-10-17 12:53:29,501 The local time is Sat Oct 17 13:53:29 2015 + 2015-10-17 13:53:29,501 The local time is Sat Oct 17 13:53:29 2015 + +showing how the time is formatted both as local time and UTC, one for each +handler. diff --git a/Doc/howto/logging.rst b/Doc/howto/logging.rst index c7a802a1e32c..4ce14f98addc 100644 --- a/Doc/howto/logging.rst +++ b/Doc/howto/logging.rst @@ -122,7 +122,8 @@ Logging to a file ^^^^^^^^^^^^^^^^^ A very common situation is that of recording logging events in a file, so let's -look at that next:: +look at that next. Be sure to try the following in a newly-started Python +interpreter, and don't just continue from the session described above:: import logging logging.basicConfig(filename='example.log',level=logging.DEBUG) @@ -238,7 +239,7 @@ uses the old, %-style of string formatting. This is for backwards compatibility: the logging package pre-dates newer formatting options such as :meth:`str.format` and :class:`string.Template`. These newer formatting options *are* supported, but exploring them is outside the scope of this -tutorial. +tutorial: see :ref:`formatting-styles` for more information. Changing the format of displayed messages @@ -1026,6 +1027,15 @@ You can write code like this:: so that if the logger's threshold is set above ``DEBUG``, the calls to :func:`expensive_func1` and :func:`expensive_func2` are never made. +.. note:: In some cases, :meth:`~Logger.isEnabledFor` can itself be more + expensive than you'd like (e.g. for deeply nested loggers where an explicit + level is only set high up in the logger hierarchy). In such cases (or if you + want to avoid calling a method in tight loops), you can cache the result of a + call to :meth:`~Logger.isEnabledFor` in a local or instance variable, and use + that instead of calling the method each time. Such a cached value would only + need to be recomputed when the logging configuration changes dynamically + while the application is running (which is not all that common). + There are other optimizations which can be made for specific applications which need more precise control over what logging information is collected. Here's a list of things you can do to avoid processing during logging which you don't @@ -1035,6 +1045,12 @@ need: | What you don't want to collect | How to avoid collecting it | +===============================================+========================================+ | Information about where calls were made from. | Set ``logging._srcfile`` to ``None``. | +| | This avoids calling | +| | :func:`sys._getframe`, which may help | +| | to speed up your code in environments | +| | like PyPy (which can't speed up code | +| | that uses :func:`sys._getframe`), if | +| | and when PyPy supports Python 3.x. | +-----------------------------------------------+----------------------------------------+ | Threading information. | Set ``logging.logThreads`` to ``0``. | +-----------------------------------------------+----------------------------------------+ diff --git a/Doc/howto/pyporting.rst b/Doc/howto/pyporting.rst index 9015372bde06..a2aaf367c78a 100644 --- a/Doc/howto/pyporting.rst +++ b/Doc/howto/pyporting.rst @@ -10,737 +10,385 @@ Porting Python 2 Code to Python 3 With Python 3 being the future of Python while Python 2 is still in active use, it is good to have your project available for both major releases of - Python. This guide is meant to help you choose which strategy works best - for your project to support both Python 2 & 3 along with how to execute - that strategy. + Python. This guide is meant to help you figure out how best to support both + Python 2 & 3 simultaneously. If you are looking to port an extension module instead of pure Python code, please see :ref:`cporting-howto`. - -Choosing a Strategy -=================== - -When a project chooses to support both Python 2 & 3, -a decision needs to be made as to how to go about accomplishing that goal. -The chosen strategy will depend on how large the project's existing -codebase is and how much divergence you want from your current Python 2 codebase -(e.g., changing your code to work simultaneously with Python 2 and 3). - -If you would prefer to maintain a codebase which is semantically **and** -syntactically compatible with Python 2 & 3 simultaneously, you can write -:ref:`use_same_source`. While this tends to lead to somewhat non-idiomatic -code, it does mean you keep a rapid development process for you, the developer. - -If your project is brand-new or does not have a large codebase, then you may -want to consider writing/porting :ref:`all of your code for Python 3 -and use 3to2 <use_3to2>` to port your code for Python 2. - -Finally, you do have the option of :ref:`using 2to3 <use_2to3>` to translate -Python 2 code into Python 3 code (with some manual help). This can take the -form of branching your code and using 2to3 to start a Python 3 branch. You can -also have users perform the translation at installation time automatically so -that you only have to maintain a Python 2 codebase. - -Regardless of which approach you choose, porting is not as hard or -time-consuming as you might initially think. You can also tackle the problem -piece-meal as a good portion of porting is simply updating your code to follow -current best practices in a Python 2/3 compatible way. - - -Universal Bits of Advice ------------------------- - -Regardless of what strategy you pick, there are a few things you should -consider. - -One is make sure you have a robust test suite. You need to make sure everything -continues to work, just like when you support a new minor/feature release of -Python. This means making sure your test suite is thorough and is ported -properly between Python 2 & 3. You will also most likely want to use something -like tox_ to automate testing between both a Python 2 and Python 3 interpreter. - -Two, once your project has Python 3 support, make sure to add the proper -classifier on the Cheeseshop_ (PyPI_). To have your project listed as Python 3 -compatible it must have the -`Python 3 classifier <http://pypi.python.org/pypi?:action=browse&c=533>`_ -(from -http://techspot.zzzeek.org/2011/01/24/zzzeek-s-guide-to-python-3-porting/):: - - setup( - name='Your Library', - version='1.0', - classifiers=[ - # make sure to use :: Python *and* :: Python :: 3 so - # that pypi can list the package on the python 3 page - 'Programming Language :: Python', - 'Programming Language :: Python :: 3' - ], - packages=['yourlibrary'], - # make sure to add custom_fixers to the MANIFEST.in - include_package_data=True, - # ... - ) - - -Doing so will cause your project to show up in the -`Python 3 packages list -<http://pypi.python.org/pypi?:action=browse&c=533&show=all>`_. You will know -you set the classifier properly as visiting your project page on the Cheeseshop -will show a Python 3 logo in the upper-left corner of the page. - -Three, the six_ project provides a library which helps iron out differences -between Python 2 & 3. If you find there is a sticky point that is a continual -point of contention in your translation or maintenance of code, consider using -a source-compatible solution relying on six. If you have to create your own -Python 2/3 compatible solution, you can use ``sys.version_info[0] >= 3`` as a -guard. - -Four, read all the approaches. Just because some bit of advice applies to one -approach more than another doesn't mean that some advice doesn't apply to other -strategies. This is especially true of whether you decide to use 2to3 or be -source-compatible; tips for one approach almost always apply to the other. - -Five, drop support for older Python versions if possible. `Python 2.5`_ -introduced a lot of useful syntax and libraries which have become idiomatic -in Python 3. `Python 2.6`_ introduced future statements which makes -compatibility much easier if you are going from Python 2 to 3. -`Python 2.7`_ continues the trend in the stdlib. So choose the newest version -of Python which you believe can be your minimum support version -and work from there. - -Six, target the newest version of Python 3 that you can. Beyond just the usual -bugfixes, compatibility has continued to improve between Python 2 and 3 as time -has passed. This is especially true for Python 3.3 where the ``u`` prefix for -strings is allowed, making source-compatible Python code easier. - -Seven, make sure to look at the `Other Resources`_ for tips from other people -which may help you out. - - -.. _tox: http://codespeak.net/tox/ -.. _Cheeseshop: -.. _PyPI: http://pypi.python.org/ -.. _six: http://packages.python.org/six -.. _Python 2.7: http://www.python.org/2.7.x -.. _Python 2.6: http://www.python.org/2.6.x -.. _Python 2.5: http://www.python.org/2.5.x -.. _Python 2.4: http://www.python.org/2.4.x -.. _Python 2.3: http://www.python.org/2.3.x -.. _Python 2.2: http://www.python.org/2.2.x - - -.. _use_3to2: - -Python 3 and 3to2 -================= - -If you are starting a new project or your codebase is small enough, you may -want to consider writing your code for Python 3 and backporting to Python 2 -using 3to2_. Thanks to Python 3 being more strict about things than Python 2 -(e.g., bytes vs. strings), the source translation can be easier and more -straightforward than from Python 2 to 3. Plus it gives you more direct -experience developing in Python 3 which, since it is the future of Python, is a -good thing long-term. - -A drawback of this approach is that 3to2 is a third-party project. This means -that the Python core developers (and thus this guide) can make no promises -about how well 3to2 works at any time. There is nothing to suggest, though, -that 3to2 is not a high-quality project. - - -.. _3to2: https://bitbucket.org/amentajo/lib3to2/overview - - -.. _use_2to3: - -Python 2 and 2to3 -================= - -Included with Python since 2.6, the 2to3_ tool (and :mod:`lib2to3` module) -helps with porting Python 2 to Python 3 by performing various source -translations. This is a perfect solution for projects which wish to branch -their Python 3 code from their Python 2 codebase and maintain them as -independent codebases. You can even begin preparing to use this approach -today by writing future-compatible Python code which works cleanly in -Python 2 in conjunction with 2to3; all steps outlined below will work -with Python 2 code up to the point when the actual use of 2to3 occurs. - -Use of 2to3 as an on-demand translation step at install time is also possible, -preventing the need to maintain a separate Python 3 codebase, but this approach -does come with some drawbacks. While users will only have to pay the -translation cost once at installation, you as a developer will need to pay the -cost regularly during development. If your codebase is sufficiently large -enough then the translation step ends up acting like a compilation step, -robbing you of the rapid development process you are used to with Python. -Obviously the time required to translate a project will vary, so do an -experimental translation just to see how long it takes to evaluate whether you -prefer this approach compared to using :ref:`use_same_source` or simply keeping -a separate Python 3 codebase. - -Below are the typical steps taken by a project which tries to support -Python 2 & 3 while keeping the code directly executable by Python 2. - - -Support Python 2.7 ------------------- - -As a first step, make sure that your project is compatible with `Python 2.7`_. -This is just good to do as Python 2.7 is the last release of Python 2 and thus -will be used for a rather long time. It also allows for use of the ``-3`` flag -to Python to help discover places in your code which 2to3 cannot handle but are -known to cause issues. - -Try to Support `Python 2.6`_ and Newer Only -------------------------------------------- - -While not possible for all projects, if you can support `Python 2.6`_ and newer -**only**, your life will be much easier. Various future statements, stdlib -additions, etc. exist only in Python 2.6 and later which greatly assist in -porting to Python 3. But if you project must keep support for `Python 2.5`_ (or -even `Python 2.4`_) then it is still possible to port to Python 3. - -Below are the benefits you gain if you only have to support Python 2.6 and -newer. Some of these options are personal choice while others are -**strongly** recommended (the ones that are more for personal choice are -labeled as such). If you continue to support older versions of Python then you -at least need to watch out for situations that these solutions fix. - - -``from __future__ import print_function`` -''''''''''''''''''''''''''''''''''''''''' - -This is a personal choice. 2to3 handles the translation from the print -statement to the print function rather well so this is an optional step. This -future statement does help, though, with getting used to typing -``print('Hello, World')`` instead of ``print 'Hello, World'``. - - -``from __future__ import unicode_literals`` -''''''''''''''''''''''''''''''''''''''''''' - -Another personal choice. You can always mark what you want to be a (unicode) -string with a ``u`` prefix to get the same effect. But regardless of whether -you use this future statement or not, you **must** make sure you know exactly -which Python 2 strings you want to be bytes, and which are to be strings. This -means you should, **at minimum** mark all strings that are meant to be text -strings with a ``u`` prefix if you do not use this future statement. Python 3.3 -allows strings to continue to have the ``u`` prefix (it's a no-op in that case) -to make it easier for code to be source-compatible between Python 2 & 3. - - -Bytes literals -'''''''''''''' - -This is a **very** important one. The ability to prefix Python 2 strings that -are meant to contain bytes with a ``b`` prefix help to very clearly delineate -what is and is not a Python 3 string. When you run 2to3 on code, all Python 2 -strings become Python 3 strings **unless** they are prefixed with ``b``. - -This point cannot be stressed enough: make sure you know what all of your string -literals in Python 2 are meant to become in Python 3. Any string literal that -should be treated as bytes should have the ``b`` prefix. Any string literal -that should be Unicode/text in Python 2 should either have the ``u`` literal -(supported, but ignored, in Python 3.3 and later) or you should have -``from __future__ import unicode_literals`` at the top of the file. But the key -point is you should know how Python 3 will treat everyone one of your string -literals and you should mark them as appropriate. - -There are some differences between byte literals in Python 2 and those in -Python 3 thanks to the bytes type just being an alias to ``str`` in Python 2. -Probably the biggest "gotcha" is that indexing results in different values. In -Python 2, the value of ``b'py'[1]`` is ``'y'``, while in Python 3 it's ``121``. -You can avoid this disparity by always slicing at the size of a single element: -``b'py'[1:2]`` is ``'y'`` in Python 2 and ``b'y'`` in Python 3 (i.e., close -enough). - -You cannot concatenate bytes and strings in Python 3. But since Python -2 has bytes aliased to ``str``, it will succeed: ``b'a' + u'b'`` works in -Python 2, but ``b'a' + 'b'`` in Python 3 is a :exc:`TypeError`. A similar issue -also comes about when doing comparisons between bytes and strings. - - -Supporting `Python 2.5`_ and Newer Only ---------------------------------------- - -If you are supporting `Python 2.5`_ and newer there are still some features of -Python that you can utilize. - - -``from __future__ import absolute_import`` -'''''''''''''''''''''''''''''''''''''''''' - -Implicit relative imports (e.g., importing ``spam.bacon`` from within -``spam.eggs`` with the statement ``import bacon``) does not work in Python 3. -This future statement moves away from that and allows the use of explicit -relative imports (e.g., ``from . import bacon``). - -In `Python 2.5`_ you must use -the __future__ statement to get to use explicit relative imports and prevent -implicit ones. In `Python 2.6`_ explicit relative imports are available without -the statement, but you still want the __future__ statement to prevent implicit -relative imports. In `Python 2.7`_ the __future__ statement is not needed. In -other words, unless you are only supporting Python 2.7 or a version earlier -than Python 2.5, use the __future__ statement. - - -Mark all Unicode strings with a ``u`` prefix -''''''''''''''''''''''''''''''''''''''''''''' - -While Python 2.6 has a ``__future__`` statement to automatically cause Python 2 -to treat all string literals as Unicode, Python 2.5 does not have that shortcut. -This means you should go through and mark all string literals with a ``u`` -prefix to turn them explicitly into Unicode strings where appropriate. That -leaves all unmarked string literals to be considered byte literals in Python 3. - - - -Handle Common "Gotchas" + If you would like to read one core Python developer's take on why Python 3 + came into existence, you can read Nick Coghlan's `Python 3 Q & A`_. + + For help with porting, you can email the python-porting_ mailing list with + questions. + +The Short Explanation +===================== + +To make your project be single-source Python 2/3 compatible, the basic steps +are: + +#. Only worry about supporting Python 2.7 +#. Make sure you have good test coverage (coverage.py_ can help; + ``pip install coverage``) +#. Learn the differences between Python 2 & 3 +#. Use Modernize_ or Futurize_ to update your code (``pip install modernize`` or + ``pip install future``, respectively) +#. Use Pylint_ to help make sure you don't regress on your Python 3 support + (``pip install pylint``) +#. Use caniusepython3_ to find out which of your dependencies are blocking your + use of Python 3 (``pip install caniusepython3``) +#. Once your dependencies are no longer blocking you, use continuous integration + to make sure you stay compatible with Python 2 & 3 (tox_ can help test + against multiple versions of Python; ``pip install tox``) + +If you are dropping support for Python 2 entirely, then after you learn the +differences between Python 2 & 3 you can run 2to3_ over your code and skip the +rest of the steps outlined above. + + +Details +======= + +A key point about supporting Python 2 & 3 simultaneously is that you can start +**today**! Even if your dependencies are not supporting Python 3 yet that does +not mean you can't modernize your code **now** to support Python 3. Most changes +required to support Python 3 lead to cleaner code using newer practices even in +Python 2. + +Another key point is that modernizing your Python 2 code to also support +Python 3 is largely automated for you. While you might have to make some API +decisions thanks to Python 3 clarifying text data versus binary data, the +lower-level work is now mostly done for you and thus can at least benefit from +the automated changes immediately. + +Keep those key points in mind while you read on about the details of porting +your code to support Python 2 & 3 simultaneously. + + +Drop support for Python 2.6 and older +------------------------------------- + +While you can make Python 2.5 work with Python 3, it is **much** easier if you +only have to work with Python 2.7. If dropping Python 2.5 is not an +option then the six_ project can help you support Python 2.5 & 3 simultaneously +(``pip install six``). Do realize, though, that nearly all the projects listed +in this HOWTO will not be available to you. + +If you are able to skip Python 2.5 and older, then the required changes +to your code should continue to look and feel like idiomatic Python code. At +worst you will have to use a function instead of a method in some instances or +have to import a function instead of using a built-in one, but otherwise the +overall transformation should not feel foreign to you. + +But you should aim for only supporting Python 2.7. Python 2.6 is no longer +supported and thus is not receiving bugfixes. This means **you** will have to +work around any issues you come across with Python 2.6. There are also some +tools mentioned in this HOWTO which do not support Python 2.6 (e.g., Pylint_), +and this will become more commonplace as time goes on. It will simply be easier +for you if you only support the versions of Python that you have to support. + +Make sure you specify the proper version support in your ``setup.py`` file +-------------------------------------------------------------------------- + +In your ``setup.py`` file you should have the proper `trove classifier`_ +specifying what versions of Python you support. As your project does not support +Python 3 yet you should at least have +``Programming Language :: Python :: 2 :: Only`` specified. Ideally you should +also specify each major/minor version of Python that you do support, e.g. +``Programming Language :: Python :: 2.7``. + +Have good test coverage ----------------------- -There are a few things that just consistently come up as sticking points for -people which 2to3 cannot handle automatically or can easily be done in Python 2 -to help modernize your code. - +Once you have your code supporting the oldest version of Python 2 you want it +to, you will want to make sure your test suite has good coverage. A good rule of +thumb is that if you want to be confident enough in your test suite that any +failures that appear after having tools rewrite your code are actual bugs in the +tools and not in your code. If you want a number to aim for, try to get over 80% +coverage (and don't feel bad if you can't easily get past 90%). If you +don't already have a tool to measure test coverage then coverage.py_ is +recommended. -``from __future__ import division`` -''''''''''''''''''''''''''''''''''' - -While the exact same outcome can be had by using the ``-Qnew`` argument to -Python, using this future statement lifts the requirement that your users use -the flag to get the expected behavior of division in Python 3 -(e.g., ``1/2 == 0.5; 1//2 == 0``). - - - -Specify when opening a file as binary -''''''''''''''''''''''''''''''''''''' +Learn the differences between Python 2 & 3 +------------------------------------------- +Once you have your code well-tested you are ready to begin porting your code to +Python 3! But to fully understand how your code is going to change and what +you want to look out for while you code, you will want to learn what changes +Python 3 makes in terms of Python 2. Typically the two best ways of doing that +is reading the `"What's New"`_ doc for each release of Python 3 and the +`Porting to Python 3`_ book (which is free online). There is also a handy +`cheat sheet`_ from the Python-Future project. + + +Update your code +---------------- + +Once you feel like you know what is different in Python 3 compared to Python 2, +it's time to update your code! You have a choice between two tools in porting +your code automatically: Modernize_ and Futurize_. Which tool you choose will +depend on how much like Python 3 you want your code to be. Futurize_ does its +best to make Python 3 idioms and practices exist in Python 2, e.g. backporting +the ``bytes`` type from Python 3 so that you have semantic parity between the +major versions of Python. Modernize_, +on the other hand, is more conservative and targets a Python 2/3 subset of +Python, relying on six_ to help provide compatibility. + +Regardless of which tool you choose, they will update your code to run under +Python 3 while staying compatible with the version of Python 2 you started with. +Depending on how conservative you want to be, you may want to run the tool over +your test suite first and visually inspect the diff to make sure the +transformation is accurate. After you have transformed your test suite and +verified that all the tests still pass as expected, then you can transform your +application code knowing that any tests which fail is a translation failure. + +Unfortunately the tools can't automate everything to make your code work under +Python 3 and so there are a handful of things you will need to update manually +to get full Python 3 support (which of these steps are necessary vary between +the tools). Read the documentation for the tool you choose to use to see what it +fixes by default and what it can do optionally to know what will (not) be fixed +for you and what you may have to fix on your own (e.g. using ``io.open()`` over +the built-in ``open()`` function is off by default in Modernize). Luckily, +though, there are only a couple of things to watch out for which can be +considered large issues that may be hard to debug if not watched for. + +Division +++++++++ + +In Python 3, ``5 / 2 == 2.5`` and not ``2``; all division between ``int`` values +result in a ``float``. This change has actually been planned since Python 2.2 +which was released in 2002. Since then users have been encouraged to add +``from __future__ import division`` to any and all files which use the ``/`` and +``//`` operators or to be running the interpreter with the ``-Q`` flag. If you +have not been doing this then you will need to go through your code and do two +things: + +#. Add ``from __future__ import division`` to your files +#. Update any division operator as necessary to either use ``//`` to use floor + division or continue using ``/`` and expect a float + +The reason that ``/`` isn't simply translated to ``//`` automatically is that if +an object defines a ``__truediv__`` method but not ``__floordiv__`` then your +code would begin to fail (e.g. a user-defined class that uses ``/`` to +signify some operation but not ``//`` for the same thing or at all). + +Text versus binary data ++++++++++++++++++++++++ + +In Python 2 you could use the ``str`` type for both text and binary data. +Unfortunately this confluence of two different concepts could lead to brittle +code which sometimes worked for either kind of data, sometimes not. It also +could lead to confusing APIs if people didn't explicitly state that something +that accepted ``str`` accepted either text or binary data instead of one +specific type. This complicated the situation especially for anyone supporting +multiple languages as APIs wouldn't bother explicitly supporting ``unicode`` +when they claimed text data support. + +To make the distinction between text and binary data clearer and more +pronounced, Python 3 did what most languages created in the age of the internet +have done and made text and binary data distinct types that cannot blindly be +mixed together (Python predates widespread access to the internet). For any code +that only deals with text or only binary data, this separation doesn't pose an +issue. But for code that has to deal with both, it does mean you might have to +now care about when you are using text compared to binary data, which is why +this cannot be entirely automated. + +To start, you will need to decide which APIs take text and which take binary +(it is **highly** recommended you don't design APIs that can take both due to +the difficulty of keeping the code working; as stated earlier it is difficult to +do well). In Python 2 this means making sure the APIs that take text can work +with ``unicode`` in Python 2 and those that work with binary data work with the +``bytes`` type from Python 3 and thus a subset of ``str`` in Python 2 (which the +``bytes`` type in Python 2 is an alias for). Usually the biggest issue is +realizing which methods exist for which types in Python 2 & 3 simultaneously +(for text that's ``unicode`` in Python 2 and ``str`` in Python 3, for binary +that's ``str``/``bytes`` in Python 2 and ``bytes`` in Python 3). The following +table lists the **unique** methods of each data type across Python 2 & 3 +(e.g., the ``decode()`` method is usable on the equivalent binary data type in +either Python 2 or 3, but it can't be used by the text data type consistently +between Python 2 and 3 because ``str`` in Python 3 doesn't have the method). Do +note that as of Python 3.5 the ``__mod__`` method was added to the bytes type. + +======================== ===================== +**Text data** **Binary data** +------------------------ --------------------- +\ decode +------------------------ --------------------- +encode +------------------------ --------------------- +format +------------------------ --------------------- +isdecimal +------------------------ --------------------- +isnumeric +======================== ===================== + +Making the distinction easier to handle can be accomplished by encoding and +decoding between binary data and text at the edge of your code. This means that +when you receive text in binary data, you should immediately decode it. And if +your code needs to send text as binary data then encode it as late as possible. +This allows your code to work with only text internally and thus eliminates +having to keep track of what type of data you are working with. + +The next issue is making sure you know whether the string literals in your code +represent text or binary data. At minimum you should add a ``b`` prefix to any +literal that presents binary data. For text you should either use the +``from __future__ import unicode_literals`` statement or add a ``u`` prefix to +the text literal. + +As part of this dichotomy you also need to be careful about opening files. Unless you have been working on Windows, there is a chance you have not always bothered to add the ``b`` mode when opening a binary file (e.g., ``rb`` for binary reading). Under Python 3, binary files and text files are clearly distinct and mutually incompatible; see the :mod:`io` module for details. Therefore, you **must** make a decision of whether a file will be used for -binary access (allowing to read and/or write bytes data) or text access -(allowing to read and/or write unicode data). - -Text files -'''''''''' - -Text files created using ``open()`` under Python 2 return byte strings, -while under Python 3 they return unicode strings. Depending on your porting -strategy, this can be an issue. - -If you want text files to return unicode strings in Python 2, you have two -possibilities: - -* Under Python 2.6 and higher, use :func:`io.open`. Since :func:`io.open` - is essentially the same function in both Python 2 and Python 3, it will - help iron out any issues that might arise. - -* If pre-2.6 compatibility is needed, then you should use :func:`codecs.open` - instead. This will make sure that you get back unicode strings in Python 2. - -Subclass ``object`` -''''''''''''''''''' - -New-style classes have been around since `Python 2.2`_. You need to make sure -you are subclassing from ``object`` to avoid odd edge cases involving method -resolution order, etc. This continues to be totally valid in Python 3 (although -unneeded as all classes implicitly inherit from ``object``). - - -Deal With the Bytes/String Dichotomy -'''''''''''''''''''''''''''''''''''' - -One of the biggest issues people have when porting code to Python 3 is handling -the bytes/string dichotomy. Because Python 2 allowed the ``str`` type to hold -textual data, people have over the years been rather loose in their delineation -of what ``str`` instances held text compared to bytes. In Python 3 you cannot -be so care-free anymore and need to properly handle the difference. The key -handling this issue is to make sure that **every** string literal in your -Python 2 code is either syntactically of functionally marked as either bytes or -text data. After this is done you then need to make sure your APIs are designed -to either handle a specific type or made to be properly polymorphic. - - -Mark Up Python 2 String Literals -******************************** - -First thing you must do is designate every single string literal in Python 2 -as either textual or bytes data. If you are only supporting Python 2.6 or -newer, this can be accomplished by marking bytes literals with a ``b`` prefix -and then designating textual data with a ``u`` prefix or using the -``unicode_literals`` future statement. - -If your project supports versions of Python predating 2.6, then you should use -the six_ project and its ``b()`` function to denote bytes literals. For text -literals you can either use six's ``u()`` function or use a ``u`` prefix. - - -Decide what APIs Will Accept -**************************** - -In Python 2 it was very easy to accidentally create an API that accepted both -bytes and textual data. But in Python 3, thanks to the more strict handling of -disparate types, this loose usage of bytes and text together tends to fail. - -Take the dict ``{b'a': 'bytes', u'a': 'text'}`` in Python 2.6. It creates the -dict ``{u'a': 'text'}`` since ``b'a' == u'a'``. But in Python 3 the equivalent -dict creates ``{b'a': 'bytes', 'a': 'text'}``, i.e., no lost data. Similar -issues can crop up when transitioning Python 2 code to Python 3. - -This means you need to choose what an API is going to accept and create and -consistently stick to that API in both Python 2 and 3. - - -Bytes / Unicode Comparison -************************** - -In Python 3, mixing bytes and unicode is forbidden in most situations; it -will raise a :class:`TypeError` where Python 2 would have attempted an implicit -coercion between types. However, there is one case where it doesn't and -it can be very misleading:: - - >>> b"" == "" - False - -This is because an equality comparison is required by the language to always -succeed (and return ``False`` for incompatible types). However, this also -means that code incorrectly ported to Python 3 can display buggy behaviour -if such comparisons are silently executed. To detect such situations, -Python 3 has a ``-b`` flag that will display a warning:: - - $ python3 -b - >>> b"" == "" - __main__:1: BytesWarning: Comparison between bytes and string - False - -To turn the warning into an exception, use the ``-bb`` flag instead:: - - $ python3 -bb - >>> b"" == "" - Traceback (most recent call last): - File "<stdin>", line 1, in <module> - BytesWarning: Comparison between bytes and string - - -Indexing bytes objects -'''''''''''''''''''''' - -Another potentially surprising change is the indexing behaviour of bytes -objects in Python 3:: - - >>> b"xyz"[0] - 120 - -Indeed, Python 3 bytes objects (as well as :class:`bytearray` objects) -are sequences of integers. But code converted from Python 2 will often -assume that indexing a bytestring produces another bytestring, not an -integer. To reconcile both behaviours, use slicing:: - - >>> b"xyz"[0:1] - b'x' - >>> n = 1 - >>> b"xyz"[n:n+1] - b'y' - -The only remaining gotcha is that an out-of-bounds slice returns an empty -bytes object instead of raising ``IndexError``: - - >>> b"xyz"[3] - Traceback (most recent call last): - File "<stdin>", line 1, in <module> - IndexError: index out of range - >>> b"xyz"[3:4] - b'' - - -``__str__()``/``__unicode__()`` -''''''''''''''''''''''''''''''' - -In Python 2, objects can specify both a string and unicode representation of -themselves. In Python 3, though, there is only a string representation. This -becomes an issue as people can inadvertently do things in their ``__str__()`` -methods which have unpredictable results (e.g., infinite recursion if you -happen to use the ``unicode(self).encode('utf8')`` idiom as the body of your -``__str__()`` method). - -There are two ways to solve this issue. One is to use a custom 2to3 fixer. The -blog post at http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/ -specifies how to do this. That will allow 2to3 to change all instances of ``def -__unicode(self): ...`` to ``def __str__(self): ...``. This does require that you -define your ``__str__()`` method in Python 2 before your ``__unicode__()`` -method. - -The other option is to use a mixin class. This allows you to only define a -``__unicode__()`` method for your class and let the mixin derive -``__str__()`` for you (code from -http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/):: - - import sys - - class UnicodeMixin(object): - - """Mixin class to handle defining the proper __str__/__unicode__ - methods in Python 2 or 3.""" - - if sys.version_info[0] >= 3: # Python 3 - def __str__(self): - return self.__unicode__() - else: # Python 2 - def __str__(self): - return self.__unicode__().encode('utf8') - - - class Spam(UnicodeMixin): - - def __unicode__(self): - return u'spam-spam-bacon-spam' # 2to3 will remove the 'u' prefix - - -Don't Index on Exceptions -''''''''''''''''''''''''' - -In Python 2, the following worked:: - - >>> exc = Exception(1, 2, 3) - >>> exc.args[1] - 2 - >>> exc[1] # Python 2 only! - 2 - -But in Python 3, indexing directly on an exception is an error. You need to -make sure to only index on the :attr:`BaseException.args` attribute which is a -sequence containing all arguments passed to the :meth:`__init__` method. - -Even better is to use the documented attributes the exception provides. - -Don't use ``__getslice__`` & Friends -'''''''''''''''''''''''''''''''''''' - -Been deprecated for a while, but Python 3 finally drops support for -``__getslice__()``, etc. Move completely over to :meth:`__getitem__` and -friends. - - -Updating doctests -''''''''''''''''' - -2to3_ will attempt to generate fixes for doctests that it comes across. It's -not perfect, though. If you wrote a monolithic set of doctests (e.g., a single -docstring containing all of your doctests), you should at least consider -breaking the doctests up into smaller pieces to make it more manageable to fix. -Otherwise it might very well be worth your time and effort to port your tests -to :mod:`unittest`. - - -Update `map` for imbalanced input sequences -''''''''''''''''''''''''''''''''''''''''''' - -With Python 2, `map` would pad input sequences of unequal length with -`None` values, returning a sequence as long as the longest input sequence. - -With Python 3, if the input sequences to `map` are of unequal length, `map` -will stop at the termination of the shortest of the sequences. For full -compatibility with `map` from Python 2.x, also wrap the sequences in -:func:`itertools.zip_longest`, e.g. ``map(func, *sequences)`` becomes -``list(map(func, itertools.zip_longest(*sequences)))``. - -Eliminate ``-3`` Warnings -------------------------- - -When you run your application's test suite, run it using the ``-3`` flag passed -to Python. This will cause various warnings to be raised during execution about -things that 2to3 cannot handle automatically (e.g., modules that have been -removed). Try to eliminate those warnings to make your code even more portable -to Python 3. - - -Run 2to3 --------- - -Once you have made your Python 2 code future-compatible with Python 3, it's -time to use 2to3_ to actually port your code. - - -Manually -'''''''' - -To manually convert source code using 2to3_, you use the ``2to3`` script that -is installed with Python 2.6 and later.:: - - 2to3 <directory or file to convert> - -This will cause 2to3 to write out a diff with all of the fixers applied for the -converted source code. If you would like 2to3 to go ahead and apply the changes -you can pass it the ``-w`` flag:: - - 2to3 -w <stuff to convert> - -There are other flags available to control exactly which fixers are applied, -etc. - - -During Installation -''''''''''''''''''' - -When a user installs your project for Python 3, you can have either -:mod:`distutils` or Distribute_ run 2to3_ on your behalf. -For distutils, use the following idiom:: - - try: # Python 3 - from distutils.command.build_py import build_py_2to3 as build_py - except ImportError: # Python 2 - from distutils.command.build_py import build_py - - setup(cmdclass = {'build_py': build_py}, - # ... - ) - -For Distribute:: - - setup(use_2to3=True, - # ... - ) - -This will allow you to not have to distribute a separate Python 3 version of -your project. It does require, though, that when you perform development that -you at least build your project and use the built Python 3 source for testing. - - -Verify & Test -------------- - -At this point you should (hopefully) have your project converted in such a way -that it works in Python 3. Verify it by running your unit tests and making sure -nothing has gone awry. If you miss something then figure out how to fix it in -Python 3, backport to your Python 2 code, and run your code through 2to3 again -to verify the fix transforms properly. - - -.. _2to3: http://docs.python.org/py3k/library/2to3.html -.. _Distribute: http://packages.python.org/distribute/ - - -.. _use_same_source: - -Python 2/3 Compatible Source -============================ - -While it may seem counter-intuitive, you can write Python code which is -source-compatible between Python 2 & 3. It does lead to code that is not -entirely idiomatic Python (e.g., having to extract the currently raised -exception from ``sys.exc_info()[1]``), but it can be run under Python 2 -**and** Python 3 without using 2to3_ as a translation step (although the tool -should be used to help find potential portability problems). This allows you to -continue to have a rapid development process regardless of whether you are -developing under Python 2 or Python 3. Whether this approach or using -:ref:`use_2to3` works best for you will be a per-project decision. - -To get a complete idea of what issues you will need to deal with, see the -`What's New in Python 3.0`_. Others have reorganized the data in other formats -such as http://docs.pythonsprints.com/python3_porting/py-porting.html . - -The following are some steps to take to try to support both Python 2 & 3 from -the same source code. - - -.. _What's New in Python 3.0: http://docs.python.org/release/3.0/whatsnew/3.0.html - - -Follow The Steps for Using 2to3_ --------------------------------- - -All of the steps outlined in how to -:ref:`port Python 2 code with 2to3 <use_2to3>` apply -to creating a Python 2/3 codebase. This includes trying only support Python 2.6 -or newer (the :mod:`__future__` statements work in Python 3 without issue), -eliminating warnings that are triggered by ``-3``, etc. - -You should even consider running 2to3_ over your code (without committing the -changes). This will let you know where potential pain points are within your -code so that you can fix them properly before they become an issue. - - -Use six_ --------- - -The six_ project contains many things to help you write portable Python code. -You should make sure to read its documentation from beginning to end and use -any and all features it provides. That way you will minimize any mistakes you -might make in writing cross-version code. - - -Capturing the Currently Raised Exception ----------------------------------------- - -One change between Python 2 and 3 that will require changing how you code (if -you support `Python 2.5`_ and earlier) is -accessing the currently raised exception. In Python 2.5 and earlier the syntax -to access the current exception is:: - - try: - raise Exception() - except Exception, exc: - # Current exception is 'exc' - pass - -This syntax changed in Python 3 (and backported to `Python 2.6`_ and later) -to:: - - try: - raise Exception() - except Exception as exc: - # Current exception is 'exc' - # In Python 3, 'exc' is restricted to the block; Python 2.6 will "leak" - pass - -Because of this syntax change you must change to capturing the current -exception to:: - - try: - raise Exception() - except Exception: - import sys - exc = sys.exc_info()[1] - # Current exception is 'exc' - pass - -You can get more information about the raised exception from -:func:`sys.exc_info` than simply the current exception instance, but you most -likely don't need it. - -.. note:: - In Python 3, the traceback is attached to the exception instance - through the ``__traceback__`` attribute. If the instance is saved in - a local variable that persists outside of the ``except`` block, the - traceback will create a reference cycle with the current frame and its - dictionary of local variables. This will delay reclaiming dead - resources until the next cyclic :term:`garbage collection` pass. - - In Python 2, this problem only occurs if you save the traceback itself - (e.g. the third element of the tuple returned by :func:`sys.exc_info`) - in a variable. - - -Other Resources -=============== - -The authors of the following blog posts, wiki pages, and books deserve special -thanks for making public their tips for porting Python 2 code to Python 3 (and -thus helping provide information for this document): - -* http://python3porting.com/ -* http://docs.pythonsprints.com/python3_porting/py-porting.html -* http://techspot.zzzeek.org/2011/01/24/zzzeek-s-guide-to-python-3-porting/ -* http://dabeaz.blogspot.com/2011/01/porting-py65-and-my-superboard-to.html -* http://lucumr.pocoo.org/2011/1/22/forwards-compatible-python/ -* http://lucumr.pocoo.org/2010/2/11/porting-to-python-3-a-guide/ -* http://wiki.python.org/moin/PortingPythonToPy3k -* https://wiki.ubuntu.com/Python/3 - -If you feel there is something missing from this document that should be added, -please email the python-porting_ mailing list. - -.. _python-porting: http://mail.python.org/mailman/listinfo/python-porting +binary access (allowing to read and/or write binary data) or text access +(allowing to read and/or write text data). You should also use :func:`io.open` +for opening files instead of the built-in :func:`open` function as the :mod:`io` +module is consistent from Python 2 to 3 while the built-in :func:`open` function +is not (in Python 3 it's actually :func:`io.open`). + +The constructors of both ``str`` and ``bytes`` have different semantics for the +same arguments between Python 2 & 3. Passing an integer to ``bytes`` in Python 2 +will give you the string representation of the integer: ``bytes(3) == '3'``. +But in Python 3, an integer argument to ``bytes`` will give you a bytes object +as long as the integer specified, filled with null bytes: +``bytes(3) == b'\x00\x00\x00'``. A similar worry is necessary when passing a +bytes object to ``str``. In Python 2 you just get the bytes object back: +``str(b'3') == b'3'``. But in Python 3 you get the string representation of the +bytes object: ``str(b'3') == "b'3'"``. + +Finally, the indexing of binary data requires careful handling (slicing does +**not** require any special handling). In Python 2, +``b'123'[1] == b'2'`` while in Python 3 ``b'123'[1] == 50``. Because binary data +is simply a collection of binary numbers, Python 3 returns the integer value for +the byte you index on. But in Python 2 because ``bytes == str``, indexing +returns a one-item slice of bytes. The six_ project has a function +named ``six.indexbytes()`` which will return an integer like in Python 3: +``six.indexbytes(b'123', 1)``. + +To summarize: + +#. Decide which of your APIs take text and which take binary data +#. Make sure that your code that works with text also works with ``unicode`` and + code for binary data works with ``bytes`` in Python 2 (see the table above + for what methods you cannot use for each type) +#. Mark all binary literals with a ``b`` prefix, use a ``u`` prefix or + :mod:`__future__` import statement for text literals +#. Decode binary data to text as soon as possible, encode text as binary data as + late as possible +#. Open files using :func:`io.open` and make sure to specify the ``b`` mode when + appropriate +#. Be careful when indexing binary data + +Prevent compatibility regressions +--------------------------------- + +Once you have fully translated your code to be compatible with Python 3, you +will want to make sure your code doesn't regress and stop working under +Python 3. This is especially true if you have a dependency which is blocking you +from actually running under Python 3 at the moment. + +To help with staying compatible, any new modules you create should have +at least the following block of code at the top of it:: + + from __future__ import absolute_import + from __future__ import division + from __future__ import print_function + from __future__ import unicode_literals + +You can also run Python 2 with the ``-3`` flag to be warned about various +compatibility issues your code triggers during execution. If you turn warnings +into errors with ``-Werror`` then you can make sure that you don't accidentally +miss a warning. + + +You can also use the Pylint_ project and its ``--py3k`` flag to lint your code +to receive warnings when your code begins to deviate from Python 3 +compatibility. This also prevents you from having to run Modernize_ or Futurize_ +over your code regularly to catch compatibility regressions. This does require +you only support Python 2.7 and Python 3.4 or newer as that is Pylint's +minimum Python version support. + + +Check which dependencies block your transition +---------------------------------------------- + +**After** you have made your code compatible with Python 3 you should begin to +care about whether your dependencies have also been ported. The caniusepython3_ +project was created to help you determine which projects +-- directly or indirectly -- are blocking you from supporting Python 3. There +is both a command-line tool as well as a web interface at +https://caniusepython3.com . + +The project also provides code which you can integrate into your test suite so +that you will have a failing test when you no longer have dependencies blocking +you from using Python 3. This allows you to avoid having to manually check your +dependencies and to be notified quickly when you can start running on Python 3. + +Update your ``setup.py`` file to denote Python 3 compatibility +-------------------------------------------------------------- + +Once your code works under Python 3, you should update the classifiers in +your ``setup.py`` to contain ``Programming Language :: Python :: 3`` and to not +specify sole Python 2 support. This will tell +anyone using your code that you support Python 2 **and** 3. Ideally you will +also want to add classifiers for each major/minor version of Python you now +support. + +Use continuous integration to stay compatible +--------------------------------------------- + +Once you are able to fully run under Python 3 you will want to make sure your +code always works under both Python 2 & 3. Probably the best tool for running +your tests under multiple Python interpreters is tox_. You can then integrate +tox with your continuous integration system so that you never accidentally break +Python 2 or 3 support. + +You may also want to use use the ``-bb`` flag with the Python 3 interpreter to +trigger an exception when you are comparing bytes to strings or bytes to an int +(the latter is available starting in Python 3.5). By default type-differing +comparisons simply return ``False``, but if you made a mistake in your +separation of text/binary data handling or indexing on bytes you wouldn't easily +find the mistake. This flag will raise an exception when these kinds of +comparisons occur, making the mistake much easier to track down. + +And that's mostly it! At this point your code base is compatible with both +Python 2 and 3 simultaneously. Your testing will also be set up so that you +don't accidentally break Python 2 or 3 compatibility regardless of which version +you typically run your tests under while developing. + + +Dropping Python 2 support completely +==================================== + +If you are able to fully drop support for Python 2, then the steps required +to transition to Python 3 simplify greatly. + +#. Update your code to only support Python 2.7 +#. Make sure you have good test coverage (coverage.py_ can help) +#. Learn the differences between Python 2 & 3 +#. Use 2to3_ to rewrite your code to run only under Python 3 + +After this your code will be fully Python 3 compliant but in a way that is not +supported by Python 2. You should also update the classifiers in your +``setup.py`` to contain ``Programming Language :: Python :: 3 :: Only``. + + +.. _2to3: https://docs.python.org/3/library/2to3.html +.. _caniusepython3: https://pypi.python.org/pypi/caniusepython3 +.. _cheat sheet: http://python-future.org/compatible_idioms.html +.. _coverage.py: https://pypi.python.org/pypi/coverage +.. _Futurize: http://python-future.org/automatic_conversion.html +.. _Modernize: http://python-modernize.readthedocs.org/en/latest/ +.. _Porting to Python 3: http://python3porting.com/ +.. _Pylint: https://pypi.python.org/pypi/pylint +.. _Python 3 Q & A: http://ncoghlan-devs-python-notes.readthedocs.org/en/latest/python3/questions_and_answers.html + +.. _python-future: http://python-future.org/ +.. _python-porting: https://mail.python.org/mailman/listinfo/python-porting +.. _six: https://pypi.python.org/pypi/six +.. _tox: https://pypi.python.org/pypi/tox +.. _trove classifier: https://pypi.python.org/pypi?%3Aaction=list_classifiers +.. _"What's New": https://docs.python.org/3/whatsnew/index.html diff --git a/Doc/howto/regex.rst b/Doc/howto/regex.rst index fbe763b3f2a3..ad2c6ab7d54d 100644 --- a/Doc/howto/regex.rst +++ b/Doc/howto/regex.rst @@ -852,7 +852,7 @@ keep track of the group numbers. There are two features which help with this problem. Both of them use a common syntax for regular expression extensions, so we'll look at that first. -Perl 5 is well-known for its powerful additions to standard regular expressions. +Perl 5 is well known for its powerful additions to standard regular expressions. For these new features the Perl developers couldn't choose new single-keystroke metacharacters or new special sequences beginning with ``\`` without making Perl's regular expressions confusingly different from standard REs. If they chose ``&`` as a @@ -1138,7 +1138,7 @@ Empty matches are replaced only when they're not adjacent to a previous match. If *replacement* is a string, any backslash escapes in it are processed. That is, ``\n`` is converted to a single newline character, ``\r`` is converted to a -carriage return, and so forth. Unknown escapes such as ``\j`` are left alone. +carriage return, and so forth. Unknown escapes such as ``\&`` are left alone. Backreferences, such as ``\6``, are replaced with the substring matched by the corresponding group in the RE. This lets you incorporate portions of the original text in the resulting replacement string. diff --git a/Doc/howto/sockets.rst b/Doc/howto/sockets.rst index 7a9b0edc1944..04394d49f019 100644 --- a/Doc/howto/sockets.rst +++ b/Doc/howto/sockets.rst @@ -180,7 +180,7 @@ righter than others). Assuming you don't want to end the connection, the simplest solution is a fixed length message:: - class mysocket: + class MySocket: """demonstration class only - coded for clarity, not efficiency """ @@ -189,8 +189,8 @@ length message:: if sock is None: self.sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM) - else: - self.sock = sock + else: + self.sock = sock def connect(self, host, port): self.sock.connect((host, port)) @@ -204,13 +204,15 @@ length message:: totalsent = totalsent + sent def myreceive(self): - msg = b'' - while len(msg) < MSGLEN: - chunk = self.sock.recv(MSGLEN-len(msg)) + chunks = [] + bytes_recd = 0 + while bytes_recd < MSGLEN: + chunk = self.sock.recv(min(MSGLEN - bytes_recd, 2048)) if chunk == b'': raise RuntimeError("socket connection broken") - msg = msg + chunk - return msg + chunks.append(chunk) + bytes_recd = bytes_recd + len(chunk) + return b''.join(chunks) The sending code here is usable for almost any messaging scheme - in Python you send strings, and you can use ``len()`` to determine its length (even if it has @@ -232,7 +234,7 @@ messages to be sent back to back (without some kind of reply), and you pass following message. You'll need to put that aside and hold onto it, until it's needed. -Prefixing the message with it's length (say, as 5 numeric characters) gets more +Prefixing the message with its length (say, as 5 numeric characters) gets more complex, because (believe it or not), you may not get all 5 characters in one ``recv``. In playing around, you'll get away with it; but in high network loads, your code will very quickly break unless you use two ``recv`` loops - the first diff --git a/Doc/howto/unicode.rst b/Doc/howto/unicode.rst index 9d48a787e85d..ee31a9c98193 100644 --- a/Doc/howto/unicode.rst +++ b/Doc/howto/unicode.rst @@ -32,11 +32,11 @@ For a while people just wrote programs that didn't display accents. In the mid-1980s an Apple II BASIC program written by a French speaker might have lines like these:: - PRINT "FICHIER EST COMPLETE." - PRINT "CARACTERE NON ACCEPTE." + PRINT "MISE A JOUR TERMINEE" + PRINT "PARAMETRES ENREGISTRES" -Those messages should contain accents (completé, caractère, accepté), -and they just look wrong to someone who can read French. +Those messages should contain accents (terminée, paramètre, enregistrés) and +they just look wrong to someone who can read French. In the 1980s, almost all personal computers were 8-bit, meaning that bytes could hold values ranging from 0 to 255. ASCII codes only went up to 127, so some @@ -49,7 +49,7 @@ another and managed to catch on. 255 characters aren't very many. For example, you can't fit both the accented characters used in Western Europe and the Cyrillic alphabet used for Russian -into the 128--255 range because there are more than 127 such characters. +into the 128--255 range because there are more than 128 such characters. You could write files using different codes (all your Russian files in a coding system called KOI8, all your French files in a different coding system called @@ -246,7 +246,7 @@ include a Unicode character in a string literal:: try: with open('/tmp/input.txt', 'r') as f: ... - except IOError: + except OSError: # 'File not found' error message. print("Fichier non trouvé") @@ -280,8 +280,9 @@ and optionally an *errors* argument. The *errors* argument specifies the response when the input string can't be converted according to the encoding's rules. Legal values for this argument are ``'strict'`` (raise a :exc:`UnicodeDecodeError` exception), ``'replace'`` (use -``U+FFFD``, ``REPLACEMENT CHARACTER``), or ``'ignore'`` (just leave the -character out of the Unicode result). +``U+FFFD``, ``REPLACEMENT CHARACTER``), ``'ignore'`` (just leave the +character out of the Unicode result), or ``'backslashreplace'`` (inserts a +``\xNN`` escape sequence). The following examples show the differences:: >>> b'\x80abc'.decode("utf-8", "strict") #doctest: +NORMALIZE_WHITESPACE @@ -291,6 +292,8 @@ The following examples show the differences:: invalid start byte >>> b'\x80abc'.decode("utf-8", "replace") '\ufffdabc' + >>> b'\x80abc'.decode("utf-8", "backslashreplace") + '\\x80abc' >>> b'\x80abc'.decode("utf-8", "ignore") 'abc' @@ -325,8 +328,9 @@ The *errors* parameter is the same as the parameter of the :meth:`~bytes.decode` method but supports a few more possible handlers. As well as ``'strict'``, ``'ignore'``, and ``'replace'`` (which in this case inserts a question mark instead of the unencodable character), there is -also ``'xmlcharrefreplace'`` (inserts an XML character reference) and -``backslashreplace`` (inserts a ``\uNNNN`` escape sequence). +also ``'xmlcharrefreplace'`` (inserts an XML character reference), +``backslashreplace`` (inserts a ``\uNNNN`` escape sequence) and +``namereplace`` (inserts a ``\N{...}`` escape sequence). The following example shows the different results:: @@ -346,6 +350,8 @@ The following example shows the different results:: b'ꀀabcd޴' >>> u.encode('ascii', 'backslashreplace') b'\\ua000abcd\\u07b4' + >>> u.encode('ascii', 'namereplace') + b'\\N{YI SYLLABLE IT}abcd\\u07b4' The low-level routines for registering and accessing the available encodings are found in the :mod:`codecs` module. Implementing new @@ -493,10 +499,11 @@ The documentation for the :mod:`unicodedata` module. The documentation for the :mod:`codecs` module. -Marc-André Lemburg gave `a presentation titled "Python and Unicode" (PDF slides) <http://downloads.egenix.com/python/Unicode-EPC2002-Talk.pdf>`_ at -EuroPython 2002. The slides are an excellent overview of the design -of Python 2's Unicode features (where the Unicode string type is -called ``unicode`` and literals start with ``u``). +Marc-André Lemburg gave `a presentation titled "Python and Unicode" (PDF slides) +<https://downloads.egenix.com/python/Unicode-EPC2002-Talk.pdf>`_ at +EuroPython 2002. The slides are an excellent overview of the design of Python +2's Unicode features (where the Unicode string type is called ``unicode`` and +literals start with ``u``). Reading and Writing Unicode Data @@ -696,13 +703,20 @@ encoding the data and writing it back out. References ---------- -One section of `Mastering Python 3 Input/Output <http://pyvideo.org/video/289/pycon-2010--mastering-python-3-i-o>`_, a PyCon 2010 talk by David Beazley, discusses text processing and binary data handling. +One section of `Mastering Python 3 Input/Output +<http://pyvideo.org/video/289/pycon-2010--mastering-python-3-i-o>`_, +a PyCon 2010 talk by David Beazley, discusses text processing and binary data handling. -The `PDF slides for Marc-André Lemburg's presentation "Writing Unicode-aware Applications in Python" <http://downloads.egenix.com/python/LSM2005-Developing-Unicode-aware-applications-in-Python.pdf>`_ +The `PDF slides for Marc-André Lemburg's presentation "Writing Unicode-aware +Applications in Python" +<https://downloads.egenix.com/python/LSM2005-Developing-Unicode-aware-applications-in-Python.pdf>`_ discuss questions of character encodings as well as how to internationalize and localize an application. These slides cover Python 2.x only. -`The Guts of Unicode in Python <http://pyvideo.org/video/1768/the-guts-of-unicode-in-python>`_ is a PyCon 2013 talk by Benjamin Peterson that discusses the internal Unicode representation in Python 3.3. +`The Guts of Unicode in Python +<http://pyvideo.org/video/1768/the-guts-of-unicode-in-python>`_ +is a PyCon 2013 talk by Benjamin Peterson that discusses the internal Unicode +representation in Python 3.3. Acknowledgements diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst index 7b217eaef911..e3d77142f4e4 100644 --- a/Doc/howto/urllib2.rst +++ b/Doc/howto/urllib2.rst @@ -26,7 +26,7 @@ Introduction A tutorial on *Basic Authentication*, with examples in Python. -**urllib.request** is a `Python <http://www.python.org>`_ module for fetching URLs +**urllib.request** is a Python module for fetching URLs (Uniform Resource Locators). It offers a very simple interface, in the form of the *urlopen* function. This is capable of fetching URLs using a variety of different protocols. It also offers a slightly more complex interface for @@ -53,8 +53,8 @@ Fetching URLs The simplest way to use urllib.request is as follows:: import urllib.request - response = urllib.request.urlopen('http://python.org/') - html = response.read() + with urllib.request.urlopen('http://python.org/') as response: + html = response.read() If you wish to retrieve a resource via URL and store it in a temporary location, you can do so via the :func:`~urllib.request.urlretrieve` function:: @@ -79,8 +79,8 @@ response:: import urllib.request req = urllib.request.Request('http://www.voidspace.org.uk/') - response = urllib.request.urlopen(req) - the_page = response.read() + with urllib.request.urlopen(req) as response: + the_page = response.read() Note that urllib.request makes use of the same Request interface to handle all URL schemes. For example, you can make an FTP request like so:: @@ -97,7 +97,7 @@ Data ---- Sometimes you want to send data to a URL (often the URL will refer to a CGI -(Common Gateway Interface) script [#]_ or other web application). With HTTP, +(Common Gateway Interface) script or other web application). With HTTP, this is often done using what's known as a **POST** request. This is often what your browser does when you submit a HTML form that you filled in on the web. Not all POSTs have to come from forms: you can use a POST to transmit arbitrary data @@ -117,8 +117,8 @@ library. :: data = urllib.parse.urlencode(values) data = data.encode('utf-8') # data should be bytes req = urllib.request.Request(url, data) - response = urllib.request.urlopen(req) - the_page = response.read() + with urllib.request.urlopen(req) as response: + the_page = response.read() Note that other encodings are sometimes required (e.g. for file upload from HTML forms - see `HTML Specification, Form Submission @@ -160,7 +160,7 @@ We'll discuss here one particular HTTP header, to illustrate how to add headers to your HTTP request. Some websites [#]_ dislike being browsed by programs, or send different versions -to different browsers [#]_ . By default urllib identifies itself as +to different browsers [#]_. By default urllib identifies itself as ``Python-urllib/x.y`` (where ``x`` and ``y`` are the major and minor version numbers of the Python release, e.g. ``Python-urllib/2.5``), which may confuse the site, or just plain @@ -174,7 +174,7 @@ Explorer [#]_. :: import urllib.request url = 'http://www.someserver.com/cgi-bin/register.cgi' - user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' + user_agent = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)' values = {'name' : 'Michael Foord', 'location' : 'Northampton', 'language' : 'Python' } @@ -183,8 +183,8 @@ Explorer [#]_. :: data = urllib.parse.urlencode(values) data = data.encode('utf-8') req = urllib.request.Request(url, data, headers) - response = urllib.request.urlopen(req) - the_page = response.read() + with urllib.request.urlopen(req) as response: + the_page = response.read() The response also has two useful methods. See the section on `info and geturl`_ which comes after we have a look at what happens when things go wrong. @@ -454,7 +454,7 @@ Authentication Tutorial When authentication is required, the server sends a header (as well as the 401 error code) requesting authentication. This specifies the authentication scheme -and a 'realm'. The header looks like : ``WWW-Authenticate: SCHEME +and a 'realm'. The header looks like: ``WWW-Authenticate: SCHEME realm="REALM"``. e.g. :: @@ -526,7 +526,7 @@ the ``ProxyHandler``, which is part of the normal handler chain when a proxy setting is detected. Normally that's a good thing, but there are occasions when it may not be helpful [#]_. One way to do this is to setup our own ``ProxyHandler``, with no proxies defined. This is done using similar steps to -setting up a `Basic Authentication`_ handler : :: +setting up a `Basic Authentication`_ handler: :: >>> proxy_support = urllib.request.ProxyHandler({}) >>> opener = urllib.request.build_opener(proxy_support) @@ -572,12 +572,7 @@ Footnotes This document was reviewed and revised by John Lee. -.. [#] For an introduction to the CGI protocol see - `Writing Web Applications in Python <http://www.pyzine.com/Issue008/Section_Articles/article_CGIOne.html>`_. -.. [#] Like Google for example. The *proper* way to use google from a program - is to use `PyGoogle <http://pygoogle.sourceforge.net>`_ of course. See - `Voidspace Google <http://www.voidspace.org.uk/python/recipebook.shtml#google>`_ - for some examples of using the Google API. +.. [#] Google for example. .. [#] Browser sniffing is a very bad practise for website design - building sites using web standards is much more sensible. Unfortunately a lot of sites still send different versions to different browsers. @@ -591,5 +586,5 @@ This document was reviewed and revised by John Lee. scripts with a localhost server, I have to prevent urllib from using the proxy. .. [#] urllib opener for SSL proxy (CONNECT method): `ASPN Cookbook Recipe - <http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/456195>`_. + <http://code.activestate.com/recipes/456195/>`_. diff --git a/Doc/howto/webservers.rst b/Doc/howto/webservers.rst index 72ccd1f690aa..9e9b69d9eb48 100644 --- a/Doc/howto/webservers.rst +++ b/Doc/howto/webservers.rst @@ -26,7 +26,7 @@ of the most popular libraries is provided. While this HOWTO tries to give an overview of Python in the web, it cannot always be as up to date as desired. Web development in Python is rapidly moving forward, so the wiki page on `Web Programming - <http://wiki.python.org/moin/WebProgramming>`_ may be more in sync with + <https://wiki.python.org/moin/WebProgramming>`_ may be more in sync with recent development. @@ -86,7 +86,7 @@ available. applications, instead of presenting a "500 Internal Server Error" message The Python wiki features a page on `CGI scripts - <http://wiki.python.org/moin/CgiScripts>`_ with some additional information + <https://wiki.python.org/moin/CgiScripts>`_ with some additional information about CGI in Python. @@ -146,7 +146,7 @@ server may not be needed. tutorial also describes the most common gotchas that might arise. * On lighttpd you need to use the `CGI module - <http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModCGI>`_\ , which can be configured + <http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModCGI>`_\ , which can be configured in a straightforward way. It boils down to setting ``cgi.assign`` properly. @@ -210,7 +210,7 @@ mod_python ---------- People coming from PHP often find it hard to grasp how to use Python in the web. -Their first thought is mostly `mod_python <http://www.modpython.org/>`_\ , +Their first thought is mostly `mod_python <http://modpython.org/>`_\ , because they think that this is the equivalent to ``mod_php``. Actually, there are many differences. What ``mod_python`` does is embed the interpreter into the Apache process, thus speeding up requests by not having to start a Python @@ -260,13 +260,6 @@ the latter. These days, FastCGI is never used directly. Just like ``mod_python``, it is only used for the deployment of WSGI applications. -.. seealso:: - - * `FastCGI, SCGI, and Apache: Background and Future - <http://www.vmunix.com/mark/blog/archives/2006/01/02/fastcgi-scgi-and-apache-background-and-future/>`_ - is a discussion on why the concept of FastCGI and SCGI is better than that - of mod_python. - Setting up FastCGI ^^^^^^^^^^^^^^^^^^ @@ -280,8 +273,8 @@ Each web server requires a specific module. to be loaded by Apache. * lighttpd ships its own `FastCGI module - <http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModFastCGI>`_ as well as an - `SCGI module <http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModSCGI>`_. + <http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModFastCGI>`_ as well as an + `SCGI module <http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ModSCGI>`_. * `nginx <http://nginx.org/>`_ also supports `FastCGI <http://wiki.nginx.org/NginxSimplePythonFCGI>`_. @@ -309,13 +302,13 @@ following WSGI-application:: WSGIServer(app).run() This is a simple WSGI application, but you need to install `flup -<http://pypi.python.org/pypi/flup/1.0>`_ first, as flup handles the low level +<https://pypi.python.org/pypi/flup/1.0>`_ first, as flup handles the low level FastCGI access. .. seealso:: There is some documentation on `setting up Django with FastCGI - <http://docs.djangoproject.com/en/dev/howto/deployment/fastcgi/>`_, most of + <https://docs.djangoproject.com/en/dev/howto/deployment/fastcgi/>`_, most of which can be reused for other WSGI-compliant frameworks and libraries. Only the ``manage.py`` part has to be changed, the example used here can be used instead. Django does more or less the exact same thing. @@ -486,7 +479,7 @@ developing a web site. There are far more components than can be presented here. The Python wiki has a page about these components, called - `Web Components <http://wiki.python.org/moin/WebComponents>`_. + `Web Components <https://wiki.python.org/moin/WebComponents>`_. Templates @@ -522,13 +515,13 @@ Popular template engines include: * `Mako <http://www.makotemplates.org/>`_ * `Genshi <http://genshi.edgewall.org/>`_ - * `Jinja <http://jinja.pocoo.org/2/>`_ + * `Jinja <http://jinja.pocoo.org/>`_ .. seealso:: There are many template engines competing for attention, because it is pretty easy to create them in Python. The page `Templating - <http://wiki.python.org/moin/Templating>`_ in the wiki lists a big, + <https://wiki.python.org/moin/Templating>`_ in the wiki lists a big, ever-growing number of these. The three listed above are considered "second generation" template engines and are a good place to start. @@ -578,11 +571,11 @@ alternate storage mechanism. .. seealso:: - * `Persistence Tools <http://wiki.python.org/moin/PersistenceTools>`_ lists + * `Persistence Tools <https://wiki.python.org/moin/PersistenceTools>`_ lists possibilities on how to save data in the file system. Some of these modules are part of the standard library - * `Database Programming <http://wiki.python.org/moin/DatabaseProgramming>`_ + * `Database Programming <https://wiki.python.org/moin/DatabaseProgramming>`_ helps with choosing a method for saving data * `SQLAlchemy <http://www.sqlalchemy.org/>`_, the most powerful OR-Mapper @@ -644,7 +637,7 @@ here. Instead we will briefly touch on some of the most popular. Django ^^^^^^ -`Django <http://www.djangoproject.com/>`_ is a framework consisting of several +`Django <https://www.djangoproject.com/>`_ is a framework consisting of several tightly coupled elements which were written from scratch and work together very well. It includes an ORM which is quite powerful while being simple to use, and has a great online administration interface which makes it possible to edit @@ -657,7 +650,7 @@ which make it possible to create web sites almost without writing any Python cod It has a big, international community, the members of which have created many web sites. There are also a lot of add-on projects which extend Django's normal functionality. This is partly due to Django's well written `online -documentation <http://docs.djangoproject.com/>`_ and the `Django book +documentation <https://docs.djangoproject.com/>`_ and the `Django book <http://www.djangobook.com/>`_. @@ -665,7 +658,7 @@ documentation <http://docs.djangoproject.com/>`_ and the `Django book Although Django is an MVC-style framework, it names the elements differently, which is described in the `Django FAQ - <http://docs.djangoproject.com/en/dev/faq/general/#django-appears-to-be-a-mvc-framework-but-you-call-the-controller-the-view-and-the-view-the-template-how-come-you-don-t-use-the-standard-names>`_. + <https://docs.djangoproject.com/en/dev/faq/general/#django-appears-to-be-a-mvc-framework-but-you-call-the-controller-the-view-and-the-view-the-template-how-come-you-don-t-use-the-standard-names>`_. TurboGears @@ -687,7 +680,7 @@ published, which is a good starting point. The newest version of TurboGears, version 2.0, moves even further in direction of WSGI support and a component-based architecture. TurboGears 2 is based on the WSGI stack of another popular component-based web framework, `Pylons -<http://pylonshq.com/>`_. +<http://www.pylonsproject.org/>`_. Zope @@ -708,7 +701,7 @@ access to these components to the wider Python community. There is even a separate framework based on the Zope components: `Grok <http://grok.zope.org/>`_. -Zope is also the infrastructure used by the `Plone <http://plone.org/>`_ content +Zope is also the infrastructure used by the `Plone <https://plone.org/>`_ content management system, one of the most powerful and popular content management systems available. @@ -732,9 +725,7 @@ found in the Python wiki. .. seealso:: The Python wiki contains an extensive list of `web frameworks - <http://wiki.python.org/moin/WebFrameworks>`_. + <https://wiki.python.org/moin/WebFrameworks>`_. Most frameworks also have their own mailing lists and IRC channels, look out - for these on the projects' web sites. There is also a general "Python in the - Web" IRC channel on freenode called `#python.web - <http://wiki.python.org/moin/PoundPythonWeb>`_. + for these on the projects' web sites. diff --git a/Doc/includes/email-alternative-new-api.py b/Doc/includes/email-alternative-new-api.py new file mode 100644 index 000000000000..c1255a68dfb5 --- /dev/null +++ b/Doc/includes/email-alternative-new-api.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 + +import smtplib + +from email.message import EmailMessage +from email.headerregistry import Address +from email.utils import make_msgid + +# Create the base text message. +msg = EmailMessage() +msg['Subject'] = "Ayons asperges pour le déjeuner" +msg['From'] = Address("Pepé Le Pew", "pepe@example.com") +msg['To'] = (Address("Penelope Pussycat", "penelope@example.com"), + Address("Fabrette Pussycat", "fabrette@example.com")) +msg.set_content("""\ +Salut! + +Cela ressemble à un excellent recipie[1] déjeuner. + +[1] http://www.yummly.com/recipe/Roasted-Asparagus-Epicurious-203718 + +--Pepé +""") + +# Add the html version. This converts the message into a multipart/alternative +# container, with the original text message as the first part and the new html +# message as the second part. +asparagus_cid = make_msgid() +msg.add_alternative("""\ +<html> + <head></head> + <body> + <p>Salut!<\p> + <p>Cela ressemble à un excellent + <a href="http://www.yummly.com/recipe/Roasted-Asparagus-Epicurious-203718%3E+%20%20%20%20%20%20%20%20%20%20%20%20recipie+%20%20%20%20%20%20%20%20%3C/a%3E%20d%C3%A9jeuner.+%20%20%20%20%3C/p%3E+%20%20%20%20%3Cimg%20src="/service/cid:{asparagus_cid}" \> + </body> +</html> +""".format(asparagus_cid=asparagus_cid[1:-1]), subtype='html') +# note that we needed to peel the <> off the msgid for use in the html. + +# Now add the related image to the html part. +with open("roasted-asparagus.jpg", 'rb') as img: + msg.get_payload()[1].add_related(img.read(), 'image', 'jpeg', + cid=asparagus_cid) + +# Make a local copy of what we are going to send. +with open('outgoing.msg', 'wb') as f: + f.write(bytes(msg)) + +# Send the message via local SMTP server. +with smtplib.SMTP('localhost') as s: + s.send_message(msg) diff --git a/Doc/includes/email-alternative.py b/Doc/includes/email-alternative.py old mode 100644 new mode 100755 index 33c430ab95ca..85070f36ae6d --- a/Doc/includes/email-alternative.py +++ b/Doc/includes/email-alternative.py @@ -17,14 +17,14 @@ msg['To'] = you # Create the body of the message (a plain-text and an HTML version). -text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttp://www.python.org" +text = "Hi!\nHow are you?\nHere is the link you wanted:\nhttps://www.python.org" html = """\ <html> <head></head> <body> <p>Hi!<br> How are you?<br> - Here is the <a href="http://www.python.org/">link</a> you wanted. + Here is the <a href="https://www.python.org/">link</a> you wanted. </p> </body> </html> diff --git a/Doc/includes/email-headers.py b/Doc/includes/email-headers.py index a53317dbd843..89c8f3af32f3 100644 --- a/Doc/includes/email-headers.py +++ b/Doc/includes/email-headers.py @@ -1,8 +1,9 @@ # Import the email modules we'll need from email.parser import Parser -# If the e-mail headers are in a file, uncomment this line: -#headers = Parser().parse(open(messagefile, 'r')) +# If the e-mail headers are in a file, uncomment these two lines: +# with open(messagefile) as fp: +# headers = Parser().parse(fp) # Or for parsing headers in a string, use: headers = Parser().parsestr('From: <user@example.com>\n' diff --git a/Doc/includes/email-mime.py b/Doc/includes/email-mime.py index a90edc137372..61d08302a2cb 100644 --- a/Doc/includes/email-mime.py +++ b/Doc/includes/email-mime.py @@ -20,9 +20,8 @@ for file in pngfiles: # Open the files in binary mode. Let the MIMEImage class automatically # guess the specific image type. - fp = open(file, 'rb') - img = MIMEImage(fp.read()) - fp.close() + with open(file, 'rb') as fp: + img = MIMEImage(fp.read()) msg.attach(img) # Send the email via our own SMTP server. diff --git a/Doc/includes/email-read-alternative-new-api.py b/Doc/includes/email-read-alternative-new-api.py new file mode 100644 index 000000000000..3f5ab24c0fbd --- /dev/null +++ b/Doc/includes/email-read-alternative-new-api.py @@ -0,0 +1,75 @@ +import os +import sys +import tempfile +import mimetypes +import webbrowser + +# Import the email modules we'll need +from email import policy +from email.parser import BytesParser + +# An imaginary module that would make this work and be safe. +from imaginary import magic_html_parser + +# In a real program you'd get the filename from the arguments. +with open('outgoing.msg', 'rb') as fp: + msg = BytesParser(policy=policy.default).parse(fp) + +# Now the header items can be accessed as a dictionary, and any non-ASCII will +# be converted to unicode: +print('To:', msg['to']) +print('From:', msg['from']) +print('Subject:', msg['subject']) + +# If we want to print a priview of the message content, we can extract whatever +# the least formatted payload is and print the first three lines. Of course, +# if the message has no plain text part printing the first three lines of html +# is probably useless, but this is just a conceptual example. +simplest = msg.get_body(preferencelist=('plain', 'html')) +print() +print(''.join(simplest.get_content().splitlines(keepends=True)[:3])) + +ans = input("View full message?") +if ans.lower()[0] == 'n': + sys.exit() + +# We can extract the richest alternative in order to display it: +richest = msg.get_body() +partfiles = {} +if richest['content-type'].maintype == 'text': + if richest['content-type'].subtype == 'plain': + for line in richest.get_content().splitlines(): + print(line) + sys.exit() + elif richest['content-type'].subtype == 'html': + body = richest + else: + print("Don't know how to display {}".format(richest.get_content_type())) + sys.exit() +elif richest['content-type'].content_type == 'multipart/related': + body = richest.get_body(preferencelist=('html')) + for part in richest.iter_attachments(): + fn = part.get_filename() + if fn: + extension = os.path.splitext(part.get_filename())[1] + else: + extension = mimetypes.guess_extension(part.get_content_type()) + with tempfile.NamedTemporaryFile(suffix=extension, delete=False) as f: + f.write(part.get_content()) + # again strip the <> to go from email form of cid to html form. + partfiles[part['content-id'][1:-1]] = f.name +else: + print("Don't know how to display {}".format(richest.get_content_type())) + sys.exit() +with tempfile.NamedTemporaryFile(mode='w', delete=False) as f: + # The magic_html_parser has to rewrite the href="/service/cid:...." attributes to + # point to the filenames in partfiles. It also has to do a safety-sanitize + # of the html. It could be written using html.parser. + f.write(magic_html_parser(body.get_content(), partfiles)) +webbrowser.open(f.name) +os.remove(f.name) +for fn in partfiles.values(): + os.remove(fn) + +# Of course, there are lots of email messages that could break this simple +# minded program, but it will handle the most common ones. diff --git a/Doc/includes/email-simple.py b/Doc/includes/email-simple.py index 077568d563be..b9b8b410a643 100644 --- a/Doc/includes/email-simple.py +++ b/Doc/includes/email-simple.py @@ -6,10 +6,9 @@ # Open a plain text file for reading. For this example, assume that # the text file contains only ASCII characters. -fp = open(textfile, 'rb') -# Create a text/plain message -msg = MIMEText(fp.read()) -fp.close() +with open(textfile) as fp: + # Create a text/plain message + msg = MIMEText(fp.read()) # me == the sender's email address # you == the recipient's email address diff --git a/Doc/includes/noddy.c b/Doc/includes/noddy.c index 8f79fcf6bf4c..19a27a89e883 100644 --- a/Doc/includes/noddy.c +++ b/Doc/includes/noddy.c @@ -38,7 +38,7 @@ static PyModuleDef noddymodule = { }; PyMODINIT_FUNC -PyInit_noddy(void) +PyInit_noddy(void) { PyObject* m; diff --git a/Doc/includes/run-func.c b/Doc/includes/run-func.c index 1c9860d7a823..986d670319ff 100644 --- a/Doc/includes/run-func.c +++ b/Doc/includes/run-func.c @@ -13,7 +13,7 @@ main(int argc, char *argv[]) } Py_Initialize(); - pName = PyUnicode_FromString(argv[1]); + pName = PyUnicode_DecodeFSDefault(argv[1]); /* Error checking of pName left out */ pModule = PyImport_Import(pName); diff --git a/Doc/includes/typestruct.h b/Doc/includes/typestruct.h index fcb846acca5c..9f47899a198e 100644 --- a/Doc/includes/typestruct.h +++ b/Doc/includes/typestruct.h @@ -1,7 +1,7 @@ typedef struct _typeobject { PyObject_VAR_HEAD - char *tp_name; /* For printing, in format "<module>.<name>" */ - int tp_basicsize, tp_itemsize; /* For allocation */ + const char *tp_name; /* For printing, in format "<module>.<name>" */ + Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */ /* Methods to implement standard operations */ @@ -9,7 +9,8 @@ typedef struct _typeobject { printfunc tp_print; getattrfunc tp_getattr; setattrfunc tp_setattr; - void *tp_reserved; + PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2) + or tp_reserved (Python 3) */ reprfunc tp_repr; /* Method suites for standard classes */ @@ -30,9 +31,9 @@ typedef struct _typeobject { PyBufferProcs *tp_as_buffer; /* Flags to define presence of optional/expanded features */ - long tp_flags; + unsigned long tp_flags; - char *tp_doc; /* Documentation string */ + const char *tp_doc; /* Documentation string */ /* call function for all accessible objects */ traverseproc tp_traverse; @@ -44,7 +45,7 @@ typedef struct _typeobject { richcmpfunc tp_richcompare; /* weak reference enabler */ - long tp_weaklistoffset; + Py_ssize_t tp_weaklistoffset; /* Iterators */ getiterfunc tp_iter; @@ -58,7 +59,7 @@ typedef struct _typeobject { PyObject *tp_dict; descrgetfunc tp_descr_get; descrsetfunc tp_descr_set; - long tp_dictoffset; + Py_ssize_t tp_dictoffset; initproc tp_init; allocfunc tp_alloc; newfunc tp_new; @@ -69,7 +70,6 @@ typedef struct _typeobject { PyObject *tp_cache; PyObject *tp_subclasses; PyObject *tp_weaklist; - destructor tp_del; /* Type attribute cache version tag. Added in version 2.6 */ diff --git a/Doc/install/index.rst b/Doc/install/index.rst index 738aaa152fc8..876f350f90e8 100644 --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -2,9 +2,9 @@ .. _install-index: -***************************** - Installing Python Modules -***************************** +******************************************** + Installing Python Modules (Legacy version) +******************************************** :Author: Greg Ward @@ -20,12 +20,20 @@ Finally, it might be useful to include all the material from my "Care and Feeding of a Python Installation" talk in here somewhere. Yow! -.. topic:: Abstract +This document describes the Python Distribution Utilities ("Distutils") from the +end-user's point-of-view, describing how to extend the capabilities of a +standard Python installation by building and installing third-party Python +modules and extensions. - This document describes the Python Distribution Utilities ("Distutils") from the - end-user's point-of-view, describing how to extend the capabilities of a - standard Python installation by building and installing third-party Python - modules and extensions. + +.. note:: + + This guide only covers the basic tools for installing extensions that are + provided as part of this version of Python. Third party tools offer easier + to use and more secure alternatives. Refer to the + `quick recommendations section + <https://python-packaging-user-guide.readthedocs.org/en/latest/current.html>`__ + in the Python Packaging User Guide for more information. .. _inst-intro: @@ -50,7 +58,8 @@ new goodies to their toolbox. You don't need to know Python to read this document; there will be some brief forays into using Python's interactive mode to explore your installation, but that's it. If you're looking for information on how to distribute your own Python modules so that others may use them, see -the :ref:`distutils-index` manual. +the :ref:`distutils-index` manual. :ref:`debug-setup-script` may also be of +interest. .. _inst-trivial-install: @@ -352,7 +361,7 @@ And here are the values used on Windows: Type of file Installation directory =============== =========================================================== modules :file:`{userbase}\\Python{XY}\\site-packages` -scripts :file:`{userbase}\\Scripts` +scripts :file:`{userbase}\\Python{XY}\\Scripts` data :file:`{userbase}` C headers :file:`{userbase}\\Python{XY}\\Include\\{distname}` =============== =========================================================== @@ -1003,7 +1012,7 @@ section :ref:`inst-config-files`.) .. seealso:: - `C++Builder Compiler <http://www.codegear.com/downloads/free/cppbuilder>`_ + `C++Builder Compiler <http://www.embarcadero.com/downloads>`_ Information about the free C++ compiler from Borland, including links to the download pages. @@ -1075,7 +1084,7 @@ normal libraries do. .. seealso:: - `Building Python modules on MS Windows platform with MinGW <http://www.zope.org/Members/als/tips/win32_mingw_modules>`_ + `Building Python modules on MS Windows platform with MinGW <http://old.zope.org/Members/als/tips/win32_mingw_modules>`_ Information about building the required libraries for the MinGW environment. @@ -1084,7 +1093,7 @@ normal libraries do. .. [#] This also means you could replace all existing COFF-libraries with OMF-libraries of the same name. -.. [#] Check http://sources.redhat.com/cygwin/ and http://www.mingw.org/ for more +.. [#] Check http://www.sourceware.org/cygwin/ and http://www.mingw.org/ for more information .. [#] Then you have no POSIX emulation available, but you also don't need diff --git a/Doc/installing/index.rst b/Doc/installing/index.rst new file mode 100644 index 000000000000..973c689861f5 --- /dev/null +++ b/Doc/installing/index.rst @@ -0,0 +1,220 @@ +.. highlightlang:: none + +.. _installing-index: + +***************************** + Installing Python Modules +***************************** + +:Email: distutils-sig@python.org + +As a popular open source development project, Python has an active +supporting community of contributors and users that also make their software +available for other Python developers to use under open source license terms. + +This allows Python users to share and collaborate effectively, benefiting +from the solutions others have already created to common (and sometimes +even rare!) problems, as well as potentially contributing their own +solutions to the common pool. + +This guide covers the installation part of the process. For a guide to +creating and sharing your own Python projects, refer to the +:ref:`distribution guide <distributing-index>`. + +.. note:: + + For corporate and other institutional users, be aware that many + organisations have their own policies around using and contributing to + open source software. Please take such policies into account when making + use of the distribution and installation tools provided with Python. + + +Key terms +========= + +* ``pip`` is the preferred installer program. Starting with Python 3.4, it + is included by default with the Python binary installers. +* a virtual environment is a semi-isolated Python environment that allows + packages to be installed for use by a particular application, rather than + being installed system wide +* ``pyvenv`` is the standard tool for creating virtual environments, and has + been part of Python since Python 3.3. Starting with Python 3.4, it + defaults to installing ``pip`` into all created virtual environments +* ``virtualenv`` is a third party alternative (and predecessor) to + ``pyvenv``. It allows virtual environments to be used on versions of + Python prior to 3.4, which either don't provide ``pyvenv`` at all, or + aren't able to automatically install ``pip`` into created environments. +* the `Python Packaging Index <https://pypi.python.org/pypi>`__ is a public + repository of open source licensed packages made available for use by + other Python users +* the `Python Packaging Authority + <https://packaging.python.org/en/latest/future.html>`__ are the group of + developers and documentation authors responsible for the maintenance and + evolution of the standard packaging tools and the associated metadata and + file format standards. They maintain a variety of tools, documentation + and issue trackers on both `GitHub <https://github.com/pypa>`__ and + `BitBucket <https://bitbucket.org/pypa/>`__. +* ``distutils`` is the original build and distribution system first added to + the Python standard library in 1998. While direct use of ``distutils`` is + being phased out, it still laid the foundation for the current packaging + and distribution infrastructure, and it not only remains part of the + standard library, but its name lives on in other ways (such as the name + of the mailing list used to coordinate Python packaging standards + development). + + +Basic usage +=========== + +The standard packaging tools are all designed to be used from the command +line. + +The following command will install the latest version of a module and its +dependencies from the Python Packaging Index:: + + python -m pip install SomePackage + +.. note:: + + For POSIX users (including Mac OS X and Linux users), the examples in + this guide assume the use of a :term:`virtual environment`. + + For Windows users, the examples in this guide assume that the option to + adjust the system PATH environment variable was selected when installing + Python. + +It's also possible to specify an exact or minimum version directly on the +command line:: + + python -m pip install SomePackage==1.0.4 # specific version + python -m pip install 'SomePackage>=1.0.4' # minimum version + +Normally, if a suitable module is already installed, attempting to install +it again will have no effect. Upgrading existing modules must be requested +explicitly:: + + python -m pip install --upgrade SomePackage + +More information and resources regarding ``pip`` and its capabilities can be +found in the `Python Packaging User Guide <https://packaging.python.org>`__. + +``pyvenv`` has its own documentation at :ref:`scripts-pyvenv`. Installing +into an active virtual environment uses the commands shown above. + +.. seealso:: + + `Python Packaging User Guide: Installing Python Distribution Packages + <https://packaging.python.org/en/latest/installing.html#installing-python-distribution-packages>`__ + + +How do I ...? +============= + +These are quick answers or links for some common tasks. + +... install ``pip`` in versions of Python prior to Python 3.4? +-------------------------------------------------------------- + +Python only started bundling ``pip`` with Python 3.4. For earlier versions, +``pip`` needs to be "bootstrapped" as described in the Python Packaging +User Guide. + +.. seealso:: + + `Python Packaging User Guide: Setup for Installing Distribution Packages + <https://packaging.python.org/en/latest/installing.html#setup-for-installing-distribution-packages>`__ + + +.. installing-per-user-installation: + +... install packages just for the current user? +----------------------------------------------- + +Passing the ``--user`` option to ``python -m pip install`` will install a +package just for the current user, rather than for all users of the system. + + +... install scientific Python packages? +--------------------------------------- + +A number of scientific Python packages have complex binary dependencies, and +aren't currently easy to install using ``pip`` directly. At this point in +time, it will often be easier for users to install these packages by +`other means +<https://packaging.python.org/en/latest/science.html>`__ +rather than attempting to install them with ``pip``. + +.. seealso:: + + `Python Packaging User Guide: Installing Scientific Packages + <https://packaging.python.org/en/latest/science.html>`__ + + +... work with multiple versions of Python installed in parallel? +---------------------------------------------------------------- + +On Linux, Mac OS X and other POSIX systems, use the versioned Python commands +in combination with the ``-m`` switch to run the appropriate copy of +``pip``:: + + python2 -m pip install SomePackage # default Python 2 + python2.7 -m pip install SomePackage # specifically Python 2.7 + python3 -m pip install SomePackage # default Python 3 + python3.4 -m pip install SomePackage # specifically Python 3.4 + +(appropriately versioned ``pip`` commands may also be available) + +On Windows, use the ``py`` Python launcher in combination with the ``-m`` +switch:: + + py -2 -m pip install SomePackage # default Python 2 + py -2.7 -m pip install SomePackage # specifically Python 2.7 + py -3 -m pip install SomePackage # default Python 3 + py -3.4 -m pip install SomePackage # specifically Python 3.4 + +.. other questions: + + Once the Development & Deployment part of PPUG is fleshed out, some of + those sections should be linked from new questions here (most notably, + we should have a question about avoiding depending on PyPI that links to + https://packaging.python.org/en/latest/deployment.html#pypi-mirrors-and-caches) + + +Common installation issues +========================== + +Installing into the system Python on Linux +------------------------------------------ + +On Linux systems, a Python installation will typically be included as part +of the distribution. Installing into this Python installation requires +root access to the system, and may interfere with the operation of the +system package manager and other components of the system if a component +is unexpectedly upgraded using ``pip``. + +On such systems, it is often better to use a virtual environment or a +per-user installation when installing packages with ``pip``. + + +Installing binary extensions +---------------------------- + +Python has typically relied heavily on source based distribution, with end +users being expected to compile extension modules from source as part of +the installation process. + +With the introduction of support for the binary ``wheel`` format, and the +ability to publish wheels for at least Windows and Mac OS X through the +Python Packaging Index, this problem is expected to diminish over time, +as users are more regularly able to install pre-built extensions rather +than needing to build them themselves. + +Some of the solutions for installing `scientific software +<https://packaging.python.org/en/latest/science.html>`__ +that is not yet available as pre-built ``wheel`` files may also help with +obtaining other binary extensions without needing to build them locally. + +.. seealso:: + + `Python Packaging User Guide: Binary Extensions + <https://packaging.python.org/en/latest/extensions.html>`__ diff --git a/Doc/library/2to3.rst b/Doc/library/2to3.rst index 1092e6b6207d..31f681d7e099 100644 --- a/Doc/library/2to3.rst +++ b/Doc/library/2to3.rst @@ -271,7 +271,7 @@ and off individually. They are described here in more detail. .. 2to3fixer:: input - Converts ``input(prompt)`` to ``eval(input(prompt))`` + Converts ``input(prompt)`` to ``eval(input(prompt))``. .. 2to3fixer:: intern @@ -392,7 +392,7 @@ and off individually. They are described here in more detail. Replaces use of the :class:`set` constructor with set literals. This fixer is optional. -.. 2to3fixer:: standard_error +.. 2to3fixer:: standarderror Renames :exc:`StandardError` to :exc:`Exception`. diff --git a/Doc/library/__future__.rst b/Doc/library/__future__.rst index 72f2963a2cd0..73d8b6b7e8af 100644 --- a/Doc/library/__future__.rst +++ b/Doc/library/__future__.rst @@ -87,6 +87,9 @@ language using this mechanism: | unicode_literals | 2.6.0a2 | 3.0 | :pep:`3112`: | | | | | *Bytes literals in Python 3000* | +------------------+-------------+--------------+---------------------------------------------+ +| generator_stop | 3.5.0b1 | 3.7 | :pep:`479`: | +| | | | *StopIteration handling inside generators* | ++------------------+-------------+--------------+---------------------------------------------+ .. seealso:: diff --git a/Doc/library/__main__.rst b/Doc/library/__main__.rst index a1d3c24bea5a..a46993d55ed2 100644 --- a/Doc/library/__main__.rst +++ b/Doc/library/__main__.rst @@ -5,13 +5,19 @@ .. module:: __main__ :synopsis: The environment where the top-level script is run. +``'__main__'`` is the name of the scope in which top-level code executes. +A module's __name__ is set equal to ``'__main__'`` when read from +standard input, a script, or from an interactive prompt. -This module represents the (otherwise anonymous) scope in which the -interpreter's main program executes --- commands read either from standard -input, from a script file, or from an interactive prompt. It is this -environment in which the idiomatic "conditional script" stanza causes a script -to run:: +A module can discover whether or not it is running in the main scope by +checking its own ``__name__``, which allows a common idiom for conditionally +executing code in a module when it is run as a script or with ``python +-m`` but not when it is imported:: if __name__ == "__main__": + # execute only if run as a script main() +For a package, the same effect can be achieved by including a +``__main__.py`` module, the contents of which will be executed when the +module is run with ``-m``. diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst index 2e130c1e52df..7122861c4517 100644 --- a/Doc/library/_thread.rst +++ b/Doc/library/_thread.rst @@ -93,7 +93,8 @@ It defines the following constants and functions: Return the thread stack size used when creating new threads. The optional *size* argument specifies the stack size to be used for subsequently created threads, and must be 0 (use platform or configured default) or a positive - integer value of at least 32,768 (32 KiB). If changing the thread stack size is + integer value of at least 32,768 (32 KiB). If *size* is not specified, + 0 is used. If changing the thread stack size is unsupported, a :exc:`RuntimeError` is raised. If the specified stack size is invalid, a :exc:`ValueError` is raised and the stack size is unmodified. 32 KiB is currently the minimum supported stack size value to guarantee sufficient @@ -176,10 +177,6 @@ In addition to these methods, lock objects can also be used via the * Calling :func:`sys.exit` or raising the :exc:`SystemExit` exception is equivalent to calling :func:`_thread.exit`. -* Not all built-in functions that may block waiting for I/O allow other threads - to run. (The most popular ones (:func:`time.sleep`, :meth:`io.FileIO.read`, - :func:`select.select`) work as expected.) - * It is not possible to interrupt the :meth:`acquire` method on a lock --- the :exc:`KeyboardInterrupt` exception will happen after the lock has been acquired. diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst index 7853d31b55a1..7a73704bf682 100644 --- a/Doc/library/abc.rst +++ b/Doc/library/abc.rst @@ -318,9 +318,9 @@ The :mod:`abc` module also provides the following functions: Returns the current abstract base class cache token. - The token is an opaque integer identifying the current version of the - abstract base class cache for virtual subclasses. This number changes - with every call to :meth:`ABCMeta.register` on any ABC. + The token is an opaque object (that supports equality testing) identifying + the current version of the abstract base class cache for virtual subclasses. + The token changes with every call to :meth:`ABCMeta.register` on any ABC. .. versionadded:: 3.4 diff --git a/Doc/library/aifc.rst b/Doc/library/aifc.rst index 9ffb5a3ffe9d..6fbcf286cf1f 100644 --- a/Doc/library/aifc.rst +++ b/Doc/library/aifc.rst @@ -54,8 +54,8 @@ Module :mod:`aifc` defines the following function: The :func:`.open` function may be used in a :keyword:`with` statement. When the :keyword:`with` block completes, the :meth:`~aifc.close` method is called. -.. versionchanged:: 3.4 - Support for the :keyword:`with` statement was added. + .. versionchanged:: 3.4 + Support for the :keyword:`with` statement was added. Objects returned by :func:`.open` when a file is opened for reading have the following methods: @@ -226,7 +226,7 @@ number of frames must be filled in. file parameters have been set. .. versionchanged:: 3.4 - Any :term:`bytes-like object`\ s are now accepted. + Any :term:`bytes-like object` is now accepted. .. method:: aifc.writeframesraw(data) @@ -235,7 +235,7 @@ number of frames must be filled in. updated. .. versionchanged:: 3.4 - Any :term:`bytes-like object`\ s are now accepted. + Any :term:`bytes-like object` is now accepted. .. method:: aifc.close() diff --git a/Doc/library/allos.rst b/Doc/library/allos.rst index bf9171744791..f7105d8af8e2 100644 --- a/Doc/library/allos.rst +++ b/Doc/library/allos.rst @@ -16,7 +16,6 @@ but they are available on most other systems as well. Here's an overview: io.rst time.rst argparse.rst - optparse.rst getopt.rst logging.rst logging.config.rst diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 51abc7a90965..03cad9f1c87e 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -135,7 +135,7 @@ ArgumentParser objects formatter_class=argparse.HelpFormatter, \ prefix_chars='-', fromfile_prefix_chars=None, \ argument_default=None, conflict_handler='error', \ - add_help=True) + add_help=True, allow_abbrev=True) Create a new :class:`ArgumentParser` object. All parameters should be passed as keyword arguments. Each parameter has its own more detailed description @@ -169,6 +169,12 @@ ArgumentParser objects * add_help_ - Add a -h/--help option to the parser (default: ``True``) + * allow_abbrev_ - Allows long options to be abbreviated if the + abbreviation is unambiguous. (default: ``True``) + + .. versionchanged:: 3.5 + *allow_abbrev* parameter was added. + The following sections describe how each of these are used. @@ -518,6 +524,26 @@ calls, we supply ``argument_default=SUPPRESS``:: >>> parser.parse_args([]) Namespace() +.. _allow_abbrev: + +allow_abbrev +^^^^^^^^^^^^ + +Normally, when you pass an argument list to the +:meth:`~ArgumentParser.parse_args` method of a :class:`ArgumentParser`, +it :ref:`recognizes abbreviations <prefix-matching>` of long options. + +This feature can be disabled by setting ``allow_abbrev`` to ``False``:: + + >>> parser = argparse.ArgumentParser(prog='PROG', allow_abbrev=False) + >>> parser.add_argument('--foobar', action='http://github.com/store_true') + >>> parser.add_argument('--foonley', action='http://github.com/store_false') + >>> parser.parse_args(['--foon']) + usage: PROG [-h] [--foobar] [--foonley] + PROG: error: unrecognized arguments: --foon + +.. versionadded:: 3.5 + conflict_handler ^^^^^^^^^^^^^^^^ @@ -683,7 +709,7 @@ action actions can do just about anything with the command-line arguments associated with them, though most actions simply add an attribute to the object returned by :meth:`~ArgumentParser.parse_args`. The ``action`` keyword argument specifies -how the command-line arguments should be handled. The supported actions are: +how the command-line arguments should be handled. The supplied actions are: * ``'store'`` - This just stores the argument's value. This is the default action. For example:: @@ -757,28 +783,18 @@ how the command-line arguments should be handled. The supported actions are: >>> parser.parse_args(['--version']) PROG 2.0 -You can also specify an arbitrary action by passing an object that implements -the Action API. The easiest way to do this is to extend -:class:`argparse.Action`, supplying an appropriate ``__call__`` method. The -``__call__`` method should accept four parameters: - -* ``parser`` - The ArgumentParser object which contains this action. - -* ``namespace`` - The :class:`Namespace` object that will be returned by - :meth:`~ArgumentParser.parse_args`. Most actions add an attribute to this - object. - -* ``values`` - The associated command-line arguments, with any type conversions - applied. (Type conversions are specified with the type_ keyword argument to - :meth:`~ArgumentParser.add_argument`.) - -* ``option_string`` - The option string that was used to invoke this action. - The ``option_string`` argument is optional, and will be absent if the action - is associated with a positional argument. +You may also specify an arbitrary action by passing an Action subclass or +other object that implements the same interface. The recommended way to do +this is to extend :class:`Action`, overriding the ``__call__`` method +and optionally the ``__init__`` method. An example of a custom action:: >>> class FooAction(argparse.Action): + ... def __init__(self, option_strings, dest, nargs=None, **kwargs): + ... if nargs is not None: + ... raise ValueError("nargs not allowed") + ... super(FooAction, self).__init__(option_strings, dest, **kwargs) ... def __call__(self, parser, namespace, values, option_string=None): ... print('%r %r %r' % (namespace, values, option_string)) ... setattr(namespace, self.dest, values) @@ -792,6 +808,7 @@ An example of a custom action:: >>> args Namespace(bar='1', foo='2') +For more details, see :class:`Action`. nargs ^^^^^ @@ -1238,6 +1255,49 @@ behavior:: >>> parser.parse_args('--foo XXX'.split()) Namespace(bar='XXX') +Action classes +^^^^^^^^^^^^^^ + +Action classes implement the Action API, a callable which returns a callable +which processes arguments from the command-line. Any object which follows +this API may be passed as the ``action`` parameter to +:meth:`add_argument`. + +.. class:: Action(option_strings, dest, nargs=None, const=None, default=None, \ + type=None, choices=None, required=False, help=None, \ + metavar=None) + +Action objects are used by an ArgumentParser to represent the information +needed to parse a single argument from one or more strings from the +command line. The Action class must accept the two positional arguments +plus any keyword arguments passed to :meth:`ArgumentParser.add_argument` +except for the ``action`` itself. + +Instances of Action (or return value of any callable to the ``action`` +parameter) should have attributes "dest", "option_strings", "default", "type", +"required", "help", etc. defined. The easiest way to ensure these attributes +are defined is to call ``Action.__init__``. + +Action instances should be callable, so subclasses must override the +``__call__`` method, which should accept four parameters: + +* ``parser`` - The ArgumentParser object which contains this action. + +* ``namespace`` - The :class:`Namespace` object that will be returned by + :meth:`~ArgumentParser.parse_args`. Most actions add an attribute to this + object using :func:`setattr`. + +* ``values`` - The associated command-line arguments, with any type conversions + applied. Type conversions are specified with the type_ keyword argument to + :meth:`~ArgumentParser.add_argument`. + +* ``option_string`` - The option string that was used to invoke this action. + The ``option_string`` argument is optional, and will be absent if the action + is associated with a positional argument. + +The ``__call__`` method may perform arbitrary actions, but will typically set +attributes on the ``namespace`` based on ``dest`` and ``values``. + The parse_args() method ----------------------- @@ -1376,9 +1436,9 @@ argument:: Argument abbreviations (prefix matching) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The :meth:`~ArgumentParser.parse_args` method allows long options to be -abbreviated to a prefix, if the abbreviation is unambiguous (the prefix matches -a unique option):: +The :meth:`~ArgumentParser.parse_args` method :ref:`by default <allow_abbrev>` +allows long options to be abbreviated to a prefix, if the abbreviation is +unambiguous (the prefix matches a unique option):: >>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('-bacon') @@ -1392,6 +1452,7 @@ a unique option):: PROG: error: ambiguous option: -ba could match -badger, -bacon An error is produced for arguments that could produce more than one options. +This feature can be disabled by setting :ref:`allow_abbrev` to ``False``. Beyond ``sys.argv`` @@ -1487,12 +1548,15 @@ Sub-commands * parser_class - class which will be used to create sub-parser instances, by default the class of the current parser (e.g. ArgumentParser) - * dest - name of the attribute under which sub-command name will be + * action_ - the basic type of action to be taken when this argument is + encountered at the command line + + * dest_ - name of the attribute under which sub-command name will be stored; by default None and no value is stored - * help - help for sub-parser group in help output, by default None + * help_ - help for sub-parser group in help output, by default None - * metavar - string presenting available sub-commands in help; by default it + * metavar_ - string presenting available sub-commands in help; by default it is None and presents sub-commands in form {cmd1, cmd2, ..} Some example usage:: @@ -1671,6 +1735,9 @@ FileType objects >>> parser.parse_args(['-']) Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>) + .. versionadded:: 3.4 + The *encodings* and *errors* keyword arguments. + Argument groups ^^^^^^^^^^^^^^^ @@ -1870,7 +1937,7 @@ Customizing file parsing Arguments that are read from a file (see the *fromfile_prefix_chars* keyword argument to the :class:`ArgumentParser` constructor) are read one - argument per line. :meth:`convert_arg_line_to_args` can be overriden for + argument per line. :meth:`convert_arg_line_to_args` can be overridden for fancier reading. This method takes a single argument *arg_line* which is a string read from @@ -1881,10 +1948,7 @@ Customizing file parsing as an argument:: def convert_arg_line_to_args(self, arg_line): - for arg in arg_line.split(): - if not arg.strip(): - continue - yield arg + return arg_line.split() Exiting methods @@ -1912,6 +1976,16 @@ transparently, particularly with the changes required to support the new :mod:`optparse` had either been copy-pasted over or monkey-patched, it no longer seemed practical to try to maintain the backwards compatibility. +The :mod:`argparse` module improves on the standard library :mod:`optparse` +module in a number of ways including: + +* Handling positional arguments. +* Supporting sub-commands. +* Allowing alternative option prefixes like ``+`` and ``/``. +* Handling zero-or-more and one-or-more style arguments. +* Producing more informative usage messages. +* Providing a much simpler interface for custom ``type`` and ``action``. + A partial upgrade path from :mod:`optparse` to :mod:`argparse`: * Replace all :meth:`optparse.OptionParser.add_option` calls with @@ -1937,4 +2011,4 @@ A partial upgrade path from :mod:`optparse` to :mod:`argparse`: ``%(default)s`` and ``%(prog)s``. * Replace the OptionParser constructor ``version`` argument with a call to - ``parser.add_argument('--version', action='http://github.com/version', version='<the version>')`` + ``parser.add_argument('--version', action='http://github.com/version', version='<the version>')``. diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index daf28de29e72..1ee511021157 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -115,13 +115,15 @@ and classes for traversing abstract syntax trees: .. function:: literal_eval(node_or_string) - Safely evaluate an expression node or a string containing a Python - expression. The string or node provided may only consist of the following - Python literal structures: strings, bytes, numbers, tuples, lists, dicts, - sets, booleans, and ``None``. - - This can be used for safely evaluating strings containing Python expressions - from untrusted sources without the need to parse the values oneself. + Safely evaluate an expression node or a string containing a Python literal or + container display. The string or node provided may only consist of the + following Python literal structures: strings, bytes, numbers, tuples, lists, + dicts, sets, booleans, and ``None``. + + This can be used for safely evaluating strings containing Python values from + untrusted sources without the need to parse the values oneself. It is not + capable of evaluating arbitrarily complex expressions, for example involving + operators or indexing. .. versionchanged:: 3.2 Now allows bytes and set literals. diff --git a/Doc/library/asynchat.rst b/Doc/library/asynchat.rst index 7b8107434a70..794da8cced7f 100644 --- a/Doc/library/asynchat.rst +++ b/Doc/library/asynchat.rst @@ -61,8 +61,8 @@ connection requests. have only one method, :meth:`more`, which should return data to be transmitted on the channel. The producer indicates exhaustion (*i.e.* that it contains no more data) by - having its :meth:`more` method return the empty string. At this point the - :class:`async_chat` object removes the producer from the fifo and starts + having its :meth:`more` method return the empty bytes object. At this point + the :class:`async_chat` object removes the producer from the fifo and starts using the next producer, if any. When the producer fifo is empty the :meth:`handle_write` method does nothing. You use the channel object's :meth:`set_terminator` method to describe how to recognize the end of, or @@ -147,40 +147,6 @@ connection requests. by the channel after :meth:`found_terminator` is called. -asynchat - Auxiliary Classes ------------------------------------------- - -.. class:: fifo(list=None) - - A :class:`fifo` holding data which has been pushed by the application but - not yet popped for writing to the channel. A :class:`fifo` is a list used - to hold data and/or producers until they are required. If the *list* - argument is provided then it should contain producers or data items to be - written to the channel. - - - .. method:: is_empty() - - Returns ``True`` if and only if the fifo is empty. - - - .. method:: first() - - Returns the least-recently :meth:`push`\ ed item from the fifo. - - - .. method:: push(data) - - Adds the given data (which may be a string or a producer object) to the - producer fifo. - - - .. method:: pop() - - If the fifo is not empty, returns ``True, first()``, deleting the popped - item. Returns ``False, None`` for an empty fifo. - - .. _asynchat-example: asynchat Example @@ -226,7 +192,7 @@ any extraneous data sent by the web client are ignored. :: def found_terminator(self): if self.reading_headers: self.reading_headers = False - self.parse_headers("".join(self.ibuffer)) + self.parse_headers(b"".join(self.ibuffer)) self.ibuffer = [] if self.op.upper() == b"POST": clen = self.headers.getheader("content-length") diff --git a/Doc/library/asyncio-dev.rst b/Doc/library/asyncio-dev.rst new file mode 100644 index 000000000000..156c5c06ac26 --- /dev/null +++ b/Doc/library/asyncio-dev.rst @@ -0,0 +1,402 @@ +.. currentmodule:: asyncio + +.. _asyncio-dev: + +Develop with asyncio +==================== + +Asynchronous programming is different than classical "sequential" programming. +This page lists common traps and explains how to avoid them. + + +.. _asyncio-debug-mode: + +Debug mode of asyncio +--------------------- + +The implementation of :mod:`asyncio` has been written for performance. +In order to ease the development of asynchronous code, you may wish to +enable *debug mode*. + +To enable all debug checks for an application: + +* Enable the asyncio debug mode globally by setting the environment variable + :envvar:`PYTHONASYNCIODEBUG` to ``1``, or by calling :meth:`BaseEventLoop.set_debug`. +* Set the log level of the :ref:`asyncio logger <asyncio-logger>` to + :py:data:`logging.DEBUG`. For example, call + ``logging.basicConfig(level=logging.DEBUG)`` at startup. +* Configure the :mod:`warnings` module to display :exc:`ResourceWarning` + warnings. For example, use the ``-Wdefault`` command line option of Python to + display them. + +Examples debug checks: + +* Log :ref:`coroutines defined but never "yielded from" + <asyncio-coroutine-not-scheduled>` +* :meth:`~BaseEventLoop.call_soon` and :meth:`~BaseEventLoop.call_at` methods + raise an exception if they are called from the wrong thread. +* Log the execution time of the selector +* Log callbacks taking more than 100 ms to be executed. The + :attr:`BaseEventLoop.slow_callback_duration` attribute is the minimum + duration in seconds of "slow" callbacks. +* :exc:`ResourceWarning` warnings are emitted when transports and event loops + are :ref:`not closed explicitly <asyncio-close-transports>`. + +.. seealso:: + + The :meth:`BaseEventLoop.set_debug` method and the :ref:`asyncio logger + <asyncio-logger>`. + + +Cancellation +------------ + +Cancellation of tasks is not common in classic programming. In asynchronous +programming, not only it is something common, but you have to prepare your +code to handle it. + +Futures and tasks can be cancelled explicitly with their :meth:`Future.cancel` +method. The :func:`wait_for` function cancels the waited task when the timeout +occurs. There are many other cases where a task can be cancelled indirectly. + +Don't call :meth:`~Future.set_result` or :meth:`~Future.set_exception` method +of :class:`Future` if the future is cancelled: it would fail with an exception. +For example, write:: + + if not fut.cancelled(): + fut.set_result('done') + +Don't schedule directly a call to the :meth:`~Future.set_result` or the +:meth:`~Future.set_exception` method of a future with +:meth:`BaseEventLoop.call_soon`: the future can be cancelled before its method +is called. + +If you wait for a future, you should check early if the future was cancelled to +avoid useless operations. Example:: + + @coroutine + def slow_operation(fut): + if fut.cancelled(): + return + # ... slow computation ... + yield from fut + # ... + +The :func:`shield` function can also be used to ignore cancellation. + + +.. _asyncio-multithreading: + +Concurrency and multithreading +------------------------------ + +An event loop runs in a thread and executes all callbacks and tasks in the same +thread. While a task is running in the event loop, no other task is running in +the same thread. But when the task uses ``yield from``, the task is suspended +and the event loop executes the next task. + +To schedule a callback from a different thread, the +:meth:`BaseEventLoop.call_soon_threadsafe` method should be used. Example:: + + loop.call_soon_threadsafe(callback, *args) + +Most asyncio objects are not thread safe. You should only worry if you access +objects outside the event loop. For example, to cancel a future, don't call +directly its :meth:`Future.cancel` method, but:: + + loop.call_soon_threadsafe(fut.cancel) + +To handle signals and to execute subprocesses, the event loop must be run in +the main thread. + +To schedule a coroutine object from a different thread, the +:func:`run_coroutine_threadsafe` function should be used. It returns a +:class:`concurrent.futures.Future` to access the result:: + + future = asyncio.run_coroutine_threadsafe(coro_func(), loop) + result = future.result(timeout) # Wait for the result with a timeout + +The :meth:`BaseEventLoop.run_in_executor` method can be used with a thread pool +executor to execute a callback in different thread to not block the thread of +the event loop. + +.. seealso:: + + The :ref:`Synchronization primitives <asyncio-sync>` section describes ways + to synchronize tasks. + + The :ref:`Subprocess and threads <asyncio-subprocess-threads>` section lists + asyncio limitations to run subprocesses from different threads. + + + + +.. _asyncio-handle-blocking: + +Handle blocking functions correctly +----------------------------------- + +Blocking functions should not be called directly. For example, if a function +blocks for 1 second, other tasks are delayed by 1 second which can have an +important impact on reactivity. + +For networking and subprocesses, the :mod:`asyncio` module provides high-level +APIs like :ref:`protocols <asyncio-protocol>`. + +An executor can be used to run a task in a different thread or even in a +different process, to not block the thread of the event loop. See the +:meth:`BaseEventLoop.run_in_executor` method. + +.. seealso:: + + The :ref:`Delayed calls <asyncio-delayed-calls>` section details how the + event loop handles time. + + +.. _asyncio-logger: + +Logging +------- + +The :mod:`asyncio` module logs information with the :mod:`logging` module in +the logger ``'asyncio'``. + + +.. _asyncio-coroutine-not-scheduled: + +Detect coroutine objects never scheduled +---------------------------------------- + +When a coroutine function is called and its result is not passed to +:func:`ensure_future` or to the :meth:`BaseEventLoop.create_task` method, +the execution of the coroutine object will never be scheduled which is +probably a bug. :ref:`Enable the debug mode of asyncio <asyncio-debug-mode>` +to :ref:`log a warning <asyncio-logger>` to detect it. + +Example with the bug:: + + import asyncio + + @asyncio.coroutine + def test(): + print("never scheduled") + + test() + +Output in debug mode:: + + Coroutine test() at test.py:3 was never yielded from + Coroutine object created at (most recent call last): + File "test.py", line 7, in <module> + test() + +The fix is to call the :func:`ensure_future` function or the +:meth:`BaseEventLoop.create_task` method with the coroutine object. + +.. seealso:: + + :ref:`Pending task destroyed <asyncio-pending-task-destroyed>`. + + +Detect exceptions never consumed +-------------------------------- + +Python usually calls :func:`sys.displayhook` on unhandled exceptions. If +:meth:`Future.set_exception` is called, but the exception is never consumed, +:func:`sys.displayhook` is not called. Instead, :ref:`a log is emitted +<asyncio-logger>` when the future is deleted by the garbage collector, with the +traceback where the exception was raised. + +Example of unhandled exception:: + + import asyncio + + @asyncio.coroutine + def bug(): + raise Exception("not consumed") + + loop = asyncio.get_event_loop() + asyncio.ensure_future(bug()) + loop.run_forever() + loop.close() + +Output:: + + Task exception was never retrieved + future: <Task finished coro=<coro() done, defined at asyncio/coroutines.py:139> exception=Exception('not consumed',)> + Traceback (most recent call last): + File "asyncio/tasks.py", line 237, in _step + result = next(coro) + File "asyncio/coroutines.py", line 141, in coro + res = func(*args, **kw) + File "test.py", line 5, in bug + raise Exception("not consumed") + Exception: not consumed + +:ref:`Enable the debug mode of asyncio <asyncio-debug-mode>` to get the +traceback where the task was created. Output in debug mode:: + + Task exception was never retrieved + future: <Task finished coro=<bug() done, defined at test.py:3> exception=Exception('not consumed',) created at test.py:8> + source_traceback: Object created at (most recent call last): + File "test.py", line 8, in <module> + asyncio.ensure_future(bug()) + Traceback (most recent call last): + File "asyncio/tasks.py", line 237, in _step + result = next(coro) + File "asyncio/coroutines.py", line 79, in __next__ + return next(self.gen) + File "asyncio/coroutines.py", line 141, in coro + res = func(*args, **kw) + File "test.py", line 5, in bug + raise Exception("not consumed") + Exception: not consumed + +There are different options to fix this issue. The first option is to chain the +coroutine in another coroutine and use classic try/except:: + + @asyncio.coroutine + def handle_exception(): + try: + yield from bug() + except Exception: + print("exception consumed") + + loop = asyncio.get_event_loop() + asyncio.ensure_future(handle_exception()) + loop.run_forever() + loop.close() + +Another option is to use the :meth:`BaseEventLoop.run_until_complete` +function:: + + task = asyncio.ensure_future(bug()) + try: + loop.run_until_complete(task) + except Exception: + print("exception consumed") + +.. seealso:: + + The :meth:`Future.exception` method. + + +Chain coroutines correctly +-------------------------- + +When a coroutine function calls other coroutine functions and tasks, they +should be chained explicitly with ``yield from``. Otherwise, the execution is +not guaranteed to be sequential. + +Example with different bugs using :func:`asyncio.sleep` to simulate slow +operations:: + + import asyncio + + @asyncio.coroutine + def create(): + yield from asyncio.sleep(3.0) + print("(1) create file") + + @asyncio.coroutine + def write(): + yield from asyncio.sleep(1.0) + print("(2) write into file") + + @asyncio.coroutine + def close(): + print("(3) close file") + + @asyncio.coroutine + def test(): + asyncio.ensure_future(create()) + asyncio.ensure_future(write()) + asyncio.ensure_future(close()) + yield from asyncio.sleep(2.0) + loop.stop() + + loop = asyncio.get_event_loop() + asyncio.ensure_future(test()) + loop.run_forever() + print("Pending tasks at exit: %s" % asyncio.Task.all_tasks(loop)) + loop.close() + +Expected output:: + + (1) create file + (2) write into file + (3) close file + Pending tasks at exit: set() + +Actual output:: + + (3) close file + (2) write into file + Pending tasks at exit: {<Task pending create() at test.py:7 wait_for=<Future pending cb=[Task._wakeup()]>>} + Task was destroyed but it is pending! + task: <Task pending create() done at test.py:5 wait_for=<Future pending cb=[Task._wakeup()]>> + +The loop stopped before the ``create()`` finished, ``close()`` has been called +before ``write()``, whereas coroutine functions were called in this order: +``create()``, ``write()``, ``close()``. + +To fix the example, tasks must be marked with ``yield from``:: + + @asyncio.coroutine + def test(): + yield from asyncio.ensure_future(create()) + yield from asyncio.ensure_future(write()) + yield from asyncio.ensure_future(close()) + yield from asyncio.sleep(2.0) + loop.stop() + +Or without ``asyncio.ensure_future()``:: + + @asyncio.coroutine + def test(): + yield from create() + yield from write() + yield from close() + yield from asyncio.sleep(2.0) + loop.stop() + + +.. _asyncio-pending-task-destroyed: + +Pending task destroyed +---------------------- + +If a pending task is destroyed, the execution of its wrapped :ref:`coroutine +<coroutine>` did not complete. It is probably a bug and so a warning is logged. + +Example of log:: + + Task was destroyed but it is pending! + task: <Task pending coro=<kill_me() done, defined at test.py:5> wait_for=<Future pending cb=[Task._wakeup()]>> + +:ref:`Enable the debug mode of asyncio <asyncio-debug-mode>` to get the +traceback where the task was created. Example of log in debug mode:: + + Task was destroyed but it is pending! + source_traceback: Object created at (most recent call last): + File "test.py", line 15, in <module> + task = asyncio.ensure_future(coro, loop=loop) + task: <Task pending coro=<kill_me() done, defined at test.py:5> wait_for=<Future pending cb=[Task._wakeup()] created at test.py:7> created at test.py:15> + + +.. seealso:: + + :ref:`Detect coroutine objects never scheduled <asyncio-coroutine-not-scheduled>`. + +.. _asyncio-close-transports: + +Close transports and event loops +-------------------------------- + +When a transport is no more needed, call its ``close()`` method to release +resources. Event loops must also be closed explicitly. + +If a transport or an event loop is not closed explicitly, a +:exc:`ResourceWarning` warning will be emitted in its destructor. By default, +:exc:`ResourceWarning` warnings are ignored. The :ref:`Debug mode of asyncio +<asyncio-debug-mode>` section explains how to display them. diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst new file mode 100644 index 000000000000..279bc2963632 --- /dev/null +++ b/Doc/library/asyncio-eventloop.rst @@ -0,0 +1,912 @@ +.. currentmodule:: asyncio + +.. _asyncio-event-loop: + +Base Event Loop +=============== + +The event loop is the central execution device provided by :mod:`asyncio`. +It provides multiple facilities, including: + +* Registering, executing and cancelling delayed calls (timeouts). + +* Creating client and server :ref:`transports <asyncio-transport>` for various + kinds of communication. + +* Launching subprocesses and the associated :ref:`transports + <asyncio-transport>` for communication with an external program. + +* Delegating costly function calls to a pool of threads. + +.. class:: BaseEventLoop + + Base class of event loops. + + This class is :ref:`not thread safe <asyncio-multithreading>`. + +Run an event loop +----------------- + +.. method:: BaseEventLoop.run_forever() + + Run until :meth:`stop` is called. + +.. method:: BaseEventLoop.run_until_complete(future) + + Run until the :class:`Future` is done. + + If the argument is a :ref:`coroutine object <coroutine>`, it is wrapped by + :func:`ensure_future`. + + Return the Future's result, or raise its exception. + +.. method:: BaseEventLoop.is_running() + + Returns running status of event loop. + +.. method:: BaseEventLoop.stop() + + Stop running the event loop. + + Every callback scheduled before :meth:`stop` is called will run. + Callbacks scheduled after :meth:`stop` is called will not run. + However, those callbacks will run if :meth:`run_forever` is called + again later. + +.. method:: BaseEventLoop.is_closed() + + Returns ``True`` if the event loop was closed. + + .. versionadded:: 3.4.2 + +.. method:: BaseEventLoop.close() + + Close the event loop. The loop must not be running. + + This clears the queues and shuts down the executor, but does not wait for + the executor to finish. + + This is idempotent and irreversible. No other methods should be called after + this one. + +.. _asyncio-pass-keywords: + +Calls +----- + +Most :mod:`asyncio` functions don't accept keywords. If you want to pass +keywords to your callback, use :func:`functools.partial`. For example, +``loop.call_soon(functools.partial(print, "Hello", flush=True))`` will call +``print("Hello", flush=True)``. + +.. note:: + :func:`functools.partial` is better than ``lambda`` functions, because + :mod:`asyncio` can inspect :func:`functools.partial` object to display + parameters in debug mode, whereas ``lambda`` functions have a poor + representation. + +.. method:: BaseEventLoop.call_soon(callback, \*args) + + Arrange for a callback to be called as soon as possible. The callback is + called after :meth:`call_soon` returns, when control returns to the event + loop. + + This operates as a FIFO queue, callbacks are called in the order in + which they are registered. Each callback will be called exactly once. + + Any positional arguments after the callback will be passed to the + callback when it is called. + + An instance of :class:`asyncio.Handle` is returned, which can be + used to cancel the callback. + + :ref:`Use functools.partial to pass keywords to the callback + <asyncio-pass-keywords>`. + +.. method:: BaseEventLoop.call_soon_threadsafe(callback, \*args) + + Like :meth:`call_soon`, but thread safe. + + See the :ref:`concurrency and multithreading <asyncio-multithreading>` + section of the documentation. + + +.. _asyncio-delayed-calls: + +Delayed calls +------------- + +The event loop has its own internal clock for computing timeouts. +Which clock is used depends on the (platform-specific) event loop +implementation; ideally it is a monotonic clock. This will generally be +a different clock than :func:`time.time`. + +.. note:: + + Timeouts (relative *delay* or absolute *when*) should not exceed one day. + + +.. method:: BaseEventLoop.call_later(delay, callback, *args) + + Arrange for the *callback* to be called after the given *delay* + seconds (either an int or float). + + An instance of :class:`asyncio.Handle` is returned, which can be + used to cancel the callback. + + *callback* will be called exactly once per call to :meth:`call_later`. + If two callbacks are scheduled for exactly the same time, it is + undefined which will be called first. + + The optional positional *args* will be passed to the callback when it + is called. If you want the callback to be called with some named + arguments, use a closure or :func:`functools.partial`. + + :ref:`Use functools.partial to pass keywords to the callback + <asyncio-pass-keywords>`. + +.. method:: BaseEventLoop.call_at(when, callback, *args) + + Arrange for the *callback* to be called at the given absolute timestamp + *when* (an int or float), using the same time reference as + :meth:`BaseEventLoop.time`. + + This method's behavior is the same as :meth:`call_later`. + + An instance of :class:`asyncio.Handle` is returned, which can be + used to cancel the callback. + + :ref:`Use functools.partial to pass keywords to the callback + <asyncio-pass-keywords>`. + +.. method:: BaseEventLoop.time() + + Return the current time, as a :class:`float` value, according to the + event loop's internal clock. + +.. seealso:: + + The :func:`asyncio.sleep` function. + + +Tasks +----- + +.. method:: BaseEventLoop.create_task(coro) + + Schedule the execution of a :ref:`coroutine object <coroutine>`: wrap it in + a future. Return a :class:`Task` object. + + Third-party event loops can use their own subclass of :class:`Task` for + interoperability. In this case, the result type is a subclass of + :class:`Task`. + + This method was added in Python 3.4.2. Use the :func:`async` function to + support also older Python versions. + + .. versionadded:: 3.4.2 + +.. method:: BaseEventLoop.set_task_factory(factory) + + Set a task factory that will be used by + :meth:`BaseEventLoop.create_task`. + + If *factory* is ``None`` the default task factory will be set. + + If *factory* is a *callable*, it should have a signature matching + ``(loop, coro)``, where *loop* will be a reference to the active + event loop, *coro* will be a coroutine object. The callable + must return an :class:`asyncio.Future` compatible object. + + .. versionadded:: 3.4.4 + +.. method:: BaseEventLoop.get_task_factory() + + Return a task factory, or ``None`` if the default one is in use. + + .. versionadded:: 3.4.4 + + +Creating connections +-------------------- + +.. coroutinemethod:: BaseEventLoop.create_connection(protocol_factory, host=None, port=None, \*, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None) + + Create a streaming transport connection to a given Internet *host* and + *port*: socket family :py:data:`~socket.AF_INET` or + :py:data:`~socket.AF_INET6` depending on *host* (or *family* if specified), + socket type :py:data:`~socket.SOCK_STREAM`. *protocol_factory* must be a + callable returning a :ref:`protocol <asyncio-protocol>` instance. + + This method is a :ref:`coroutine <coroutine>` which will try to + establish the connection in the background. When successful, the + coroutine returns a ``(transport, protocol)`` pair. + + The chronological synopsis of the underlying operation is as follows: + + #. The connection is established, and a :ref:`transport <asyncio-transport>` + is created to represent it. + + #. *protocol_factory* is called without arguments and must return a + :ref:`protocol <asyncio-protocol>` instance. + + #. The protocol instance is tied to the transport, and its + :meth:`connection_made` method is called. + + #. The coroutine returns successfully with the ``(transport, protocol)`` + pair. + + The created transport is an implementation-dependent bidirectional stream. + + .. note:: + *protocol_factory* can be any kind of callable, not necessarily + a class. For example, if you want to use a pre-created + protocol instance, you can pass ``lambda: my_protocol``. + + Options allowing to change how the connection is created: + + * *ssl*: if given and not false, a SSL/TLS transport is created + (by default a plain TCP transport is created). If *ssl* is + a :class:`ssl.SSLContext` object, this context is used to create + the transport; if *ssl* is :const:`True`, a context with some + unspecified default settings is used. + + .. seealso:: :ref:`SSL/TLS security considerations <ssl-security>` + + * *server_hostname*, is only for use together with *ssl*, + and sets or overrides the hostname that the target server's certificate + will be matched against. By default the value of the *host* argument + is used. If *host* is empty, there is no default and you must pass a + value for *server_hostname*. If *server_hostname* is an empty + string, hostname matching is disabled (which is a serious security + risk, allowing for man-in-the-middle-attacks). + + * *family*, *proto*, *flags* are the optional address family, protocol + and flags to be passed through to getaddrinfo() for *host* resolution. + If given, these should all be integers from the corresponding + :mod:`socket` module constants. + + * *sock*, if given, should be an existing, already connected + :class:`socket.socket` object to be used by the transport. + If *sock* is given, none of *host*, *port*, *family*, *proto*, *flags* + and *local_addr* should be specified. + + * *local_addr*, if given, is a ``(local_host, local_port)`` tuple used + to bind the socket to locally. The *local_host* and *local_port* + are looked up using getaddrinfo(), similarly to *host* and *port*. + + .. versionchanged:: 3.5 + + On Windows with :class:`ProactorEventLoop`, SSL/TLS is now supported. + + .. seealso:: + + The :func:`open_connection` function can be used to get a pair of + (:class:`StreamReader`, :class:`StreamWriter`) instead of a protocol. + + +.. coroutinemethod:: BaseEventLoop.create_datagram_endpoint(protocol_factory, local_addr=None, remote_addr=None, \*, family=0, proto=0, flags=0, reuse_address=None, reuse_port=None, allow_broadcast=None, sock=None) + + Create datagram connection: socket family :py:data:`~socket.AF_INET` or + :py:data:`~socket.AF_INET6` depending on *host* (or *family* if specified), + socket type :py:data:`~socket.SOCK_DGRAM`. *protocol_factory* must be a + callable returning a :ref:`protocol <asyncio-protocol>` instance. + + This method is a :ref:`coroutine <coroutine>` which will try to + establish the connection in the background. When successful, the + coroutine returns a ``(transport, protocol)`` pair. + + Options changing how the connection is created: + + * *local_addr*, if given, is a ``(local_host, local_port)`` tuple used + to bind the socket to locally. The *local_host* and *local_port* + are looked up using :meth:`getaddrinfo`. + + * *remote_addr*, if given, is a ``(remote_host, remote_port)`` tuple used + to connect the socket to a remote address. The *remote_host* and + *remote_port* are looked up using :meth:`getaddrinfo`. + + * *family*, *proto*, *flags* are the optional address family, protocol + and flags to be passed through to :meth:`getaddrinfo` for *host* + resolution. If given, these should all be integers from the + corresponding :mod:`socket` module constants. + + * *reuse_address* tells the kernel to reuse a local socket in + TIME_WAIT state, without waiting for its natural timeout to + expire. If not specified will automatically be set to True on + UNIX. + + * *reuse_port* tells the kernel to allow this endpoint to be bound to the + same port as other existing endpoints are bound to, so long as they all + set this flag when being created. This option is not supported on Windows + and some UNIX's. If the :py:data:`~socket.SO_REUSEPORT` constant is not + defined then this capability is unsupported. + + * *allow_broadcast* tells the kernel to allow this endpoint to send + messages to the broadcast address. + + * *sock* can optionally be specified in order to use a preexisting, + already connected, :class:`socket.socket` object to be used by the + transport. If specified, *local_addr* and *remote_addr* should be omitted + (must be :const:`None`). + + On Windows with :class:`ProactorEventLoop`, this method is not supported. + + See :ref:`UDP echo client protocol <asyncio-udp-echo-client-protocol>` and + :ref:`UDP echo server protocol <asyncio-udp-echo-server-protocol>` examples. + + +.. coroutinemethod:: BaseEventLoop.create_unix_connection(protocol_factory, path, \*, ssl=None, sock=None, server_hostname=None) + + Create UNIX connection: socket family :py:data:`~socket.AF_UNIX`, socket + type :py:data:`~socket.SOCK_STREAM`. The :py:data:`~socket.AF_UNIX` socket + family is used to communicate between processes on the same machine + efficiently. + + This method is a :ref:`coroutine <coroutine>` which will try to + establish the connection in the background. When successful, the + coroutine returns a ``(transport, protocol)`` pair. + + See the :meth:`BaseEventLoop.create_connection` method for parameters. + + Availability: UNIX. + + +Creating listening connections +------------------------------ + +.. coroutinemethod:: BaseEventLoop.create_server(protocol_factory, host=None, port=None, \*, family=socket.AF_UNSPEC, flags=socket.AI_PASSIVE, sock=None, backlog=100, ssl=None, reuse_address=None, reuse_port=None) + + Create a TCP server (socket type :data:`~socket.SOCK_STREAM`) bound to + *host* and *port*. + + Return a :class:`Server` object, its :attr:`~Server.sockets` attribute + contains created sockets. Use the :meth:`Server.close` method to stop the + server: close listening sockets. + + Parameters: + + * The *host* parameter can be a string, in that case the TCP server is + bound to *host* and *port*. The *host* parameter can also be a sequence + of strings and in that case the TCP server is bound to all hosts of the + sequence. If *host* is an empty string or ``None``, all interfaces are + assumed and a list of multiple sockets will be returned (most likely one + for IPv4 and another one for IPv6). + + * *family* can be set to either :data:`socket.AF_INET` or + :data:`~socket.AF_INET6` to force the socket to use IPv4 or IPv6. If not set + it will be determined from host (defaults to :data:`socket.AF_UNSPEC`). + + * *flags* is a bitmask for :meth:`getaddrinfo`. + + * *sock* can optionally be specified in order to use a preexisting + socket object. If specified, *host* and *port* should be omitted (must be + :const:`None`). + + * *backlog* is the maximum number of queued connections passed to + :meth:`~socket.socket.listen` (defaults to 100). + + * *ssl* can be set to an :class:`~ssl.SSLContext` to enable SSL over the + accepted connections. + + * *reuse_address* tells the kernel to reuse a local socket in + TIME_WAIT state, without waiting for its natural timeout to + expire. If not specified will automatically be set to True on + UNIX. + + * *reuse_port* tells the kernel to allow this endpoint to be bound to the + same port as other existing endpoints are bound to, so long as they all + set this flag when being created. This option is not supported on + Windows. + + This method is a :ref:`coroutine <coroutine>`. + + .. versionchanged:: 3.5 + + On Windows with :class:`ProactorEventLoop`, SSL/TLS is now supported. + + .. seealso:: + + The function :func:`start_server` creates a (:class:`StreamReader`, + :class:`StreamWriter`) pair and calls back a function with this pair. + + .. versionchanged:: 3.5.1 + + The *host* parameter can now be a sequence of strings. + + +.. coroutinemethod:: BaseEventLoop.create_unix_server(protocol_factory, path=None, \*, sock=None, backlog=100, ssl=None) + + Similar to :meth:`BaseEventLoop.create_server`, but specific to the + socket family :py:data:`~socket.AF_UNIX`. + + This method is a :ref:`coroutine <coroutine>`. + + Availability: UNIX. + + +Watch file descriptors +---------------------- + +On Windows with :class:`SelectorEventLoop`, only socket handles are supported +(ex: pipe file descriptors are not supported). + +On Windows with :class:`ProactorEventLoop`, these methods are not supported. + +.. method:: BaseEventLoop.add_reader(fd, callback, \*args) + + Start watching the file descriptor for read availability and then call the + *callback* with specified arguments. + + :ref:`Use functools.partial to pass keywords to the callback + <asyncio-pass-keywords>`. + +.. method:: BaseEventLoop.remove_reader(fd) + + Stop watching the file descriptor for read availability. + +.. method:: BaseEventLoop.add_writer(fd, callback, \*args) + + Start watching the file descriptor for write availability and then call the + *callback* with specified arguments. + + :ref:`Use functools.partial to pass keywords to the callback + <asyncio-pass-keywords>`. + +.. method:: BaseEventLoop.remove_writer(fd) + + Stop watching the file descriptor for write availability. + +The :ref:`watch a file descriptor for read events <asyncio-watch-read-event>` +example uses the low-level :meth:`BaseEventLoop.add_reader` method to register +the file descriptor of a socket. + + +Low-level socket operations +--------------------------- + +.. coroutinemethod:: BaseEventLoop.sock_recv(sock, nbytes) + + Receive data from the socket. The return value is a bytes object + representing the data received. The maximum amount of data to be received + at once is specified by *nbytes*. + + With :class:`SelectorEventLoop` event loop, the socket *sock* must be + non-blocking. + + This method is a :ref:`coroutine <coroutine>`. + + .. seealso:: + + The :meth:`socket.socket.recv` method. + +.. coroutinemethod:: BaseEventLoop.sock_sendall(sock, data) + + Send data to the socket. The socket must be connected to a remote socket. + This method continues to send data from *data* until either all data has + been sent or an error occurs. ``None`` is returned on success. On error, + an exception is raised, and there is no way to determine how much data, if + any, was successfully processed by the receiving end of the connection. + + With :class:`SelectorEventLoop` event loop, the socket *sock* must be + non-blocking. + + This method is a :ref:`coroutine <coroutine>`. + + .. seealso:: + + The :meth:`socket.socket.sendall` method. + +.. coroutinemethod:: BaseEventLoop.sock_connect(sock, address) + + Connect to a remote socket at *address*. + + The *address* must be already resolved to avoid the trap of hanging the + entire event loop when the address requires doing a DNS lookup. For + example, it must be an IP address, not an hostname, for + :py:data:`~socket.AF_INET` and :py:data:`~socket.AF_INET6` address families. + Use :meth:`getaddrinfo` to resolve the hostname asynchronously. + + With :class:`SelectorEventLoop` event loop, the socket *sock* must be + non-blocking. + + This method is a :ref:`coroutine <coroutine>`. + + .. seealso:: + + The :meth:`BaseEventLoop.create_connection` method, the + :func:`open_connection` function and the :meth:`socket.socket.connect` + method. + + +.. coroutinemethod:: BaseEventLoop.sock_accept(sock) + + Accept a connection. The socket must be bound to an address and listening + for connections. The return value is a pair ``(conn, address)`` where *conn* + is a *new* socket object usable to send and receive data on the connection, + and *address* is the address bound to the socket on the other end of the + connection. + + The socket *sock* must be non-blocking. + + This method is a :ref:`coroutine <coroutine>`. + + .. seealso:: + + The :meth:`BaseEventLoop.create_server` method, the :func:`start_server` + function and the :meth:`socket.socket.accept` method. + + +Resolve host name +----------------- + +.. coroutinemethod:: BaseEventLoop.getaddrinfo(host, port, \*, family=0, type=0, proto=0, flags=0) + + This method is a :ref:`coroutine <coroutine>`, similar to + :meth:`socket.getaddrinfo` function but non-blocking. + +.. coroutinemethod:: BaseEventLoop.getnameinfo(sockaddr, flags=0) + + This method is a :ref:`coroutine <coroutine>`, similar to + :meth:`socket.getnameinfo` function but non-blocking. + + +Connect pipes +------------- + +On Windows with :class:`SelectorEventLoop`, these methods are not supported. +Use :class:`ProactorEventLoop` to support pipes on Windows. + +.. coroutinemethod:: BaseEventLoop.connect_read_pipe(protocol_factory, pipe) + + Register read pipe in eventloop. + + *protocol_factory* should instantiate object with :class:`Protocol` + interface. *pipe* is a :term:`file-like object <file object>`. + Return pair ``(transport, protocol)``, where *transport* supports the + :class:`ReadTransport` interface. + + With :class:`SelectorEventLoop` event loop, the *pipe* is set to + non-blocking mode. + + This method is a :ref:`coroutine <coroutine>`. + +.. coroutinemethod:: BaseEventLoop.connect_write_pipe(protocol_factory, pipe) + + Register write pipe in eventloop. + + *protocol_factory* should instantiate object with :class:`BaseProtocol` + interface. *pipe* is :term:`file-like object <file object>`. + Return pair ``(transport, protocol)``, where *transport* supports + :class:`WriteTransport` interface. + + With :class:`SelectorEventLoop` event loop, the *pipe* is set to + non-blocking mode. + + This method is a :ref:`coroutine <coroutine>`. + +.. seealso:: + + The :meth:`BaseEventLoop.subprocess_exec` and + :meth:`BaseEventLoop.subprocess_shell` methods. + + +UNIX signals +------------ + +Availability: UNIX only. + +.. method:: BaseEventLoop.add_signal_handler(signum, callback, \*args) + + Add a handler for a signal. + + Raise :exc:`ValueError` if the signal number is invalid or uncatchable. + Raise :exc:`RuntimeError` if there is a problem setting up the handler. + + :ref:`Use functools.partial to pass keywords to the callback + <asyncio-pass-keywords>`. + +.. method:: BaseEventLoop.remove_signal_handler(sig) + + Remove a handler for a signal. + + Return ``True`` if a signal handler was removed, ``False`` if not. + +.. seealso:: + + The :mod:`signal` module. + + +Executor +-------- + +Call a function in an :class:`~concurrent.futures.Executor` (pool of threads or +pool of processes). By default, an event loop uses a thread pool executor +(:class:`~concurrent.futures.ThreadPoolExecutor`). + +.. coroutinemethod:: BaseEventLoop.run_in_executor(executor, func, \*args) + + Arrange for a *func* to be called in the specified executor. + + The *executor* argument should be an :class:`~concurrent.futures.Executor` + instance. The default executor is used if *executor* is ``None``. + + :ref:`Use functools.partial to pass keywords to the *func* + <asyncio-pass-keywords>`. + + This method is a :ref:`coroutine <coroutine>`. + +.. method:: BaseEventLoop.set_default_executor(executor) + + Set the default executor used by :meth:`run_in_executor`. + + +Error Handling API +------------------ + +Allows to customize how exceptions are handled in the event loop. + +.. method:: BaseEventLoop.set_exception_handler(handler) + + Set *handler* as the new event loop exception handler. + + If *handler* is ``None``, the default exception handler will + be set. + + If *handler* is a callable object, it should have a + matching signature to ``(loop, context)``, where ``loop`` + will be a reference to the active event loop, ``context`` + will be a ``dict`` object (see :meth:`call_exception_handler` + documentation for details about context). + +.. method:: BaseEventLoop.default_exception_handler(context) + + Default exception handler. + + This is called when an exception occurs and no exception + handler is set, and can be called by a custom exception + handler that wants to defer to the default behavior. + + *context* parameter has the same meaning as in + :meth:`call_exception_handler`. + +.. method:: BaseEventLoop.call_exception_handler(context) + + Call the current event loop exception handler. + + *context* is a ``dict`` object containing the following keys + (new keys may be introduced later): + + * 'message': Error message; + * 'exception' (optional): Exception object; + * 'future' (optional): :class:`asyncio.Future` instance; + * 'handle' (optional): :class:`asyncio.Handle` instance; + * 'protocol' (optional): :ref:`Protocol <asyncio-protocol>` instance; + * 'transport' (optional): :ref:`Transport <asyncio-transport>` instance; + * 'socket' (optional): :class:`socket.socket` instance. + + .. note:: + + Note: this method should not be overloaded in subclassed + event loops. For any custom exception handling, use + :meth:`set_exception_handler()` method. + +Debug mode +---------- + +.. method:: BaseEventLoop.get_debug() + + Get the debug mode (:class:`bool`) of the event loop. + + The default value is ``True`` if the environment variable + :envvar:`PYTHONASYNCIODEBUG` is set to a non-empty string, ``False`` + otherwise. + + .. versionadded:: 3.4.2 + +.. method:: BaseEventLoop.set_debug(enabled: bool) + + Set the debug mode of the event loop. + + .. versionadded:: 3.4.2 + +.. seealso:: + + The :ref:`debug mode of asyncio <asyncio-debug-mode>`. + +Server +------ + +.. class:: Server + + Server listening on sockets. + + Object created by the :meth:`BaseEventLoop.create_server` method and the + :func:`start_server` function. Don't instantiate the class directly. + + .. method:: close() + + Stop serving: close listening sockets and set the :attr:`sockets` + attribute to ``None``. + + The sockets that represent existing incoming client connections are + leaved open. + + The server is closed asynchonously, use the :meth:`wait_closed` coroutine + to wait until the server is closed. + + .. coroutinemethod:: wait_closed() + + Wait until the :meth:`close` method completes. + + This method is a :ref:`coroutine <coroutine>`. + + .. attribute:: sockets + + List of :class:`socket.socket` objects the server is listening to, or + ``None`` if the server is closed. + + +Handle +------ + +.. class:: Handle + + A callback wrapper object returned by :func:`BaseEventLoop.call_soon`, + :func:`BaseEventLoop.call_soon_threadsafe`, :func:`BaseEventLoop.call_later`, + and :func:`BaseEventLoop.call_at`. + + .. method:: cancel() + + Cancel the call. If the callback is already canceled or executed, + this method has no effect. + + +Event loop examples +------------------- + +.. _asyncio-hello-world-callback: + +Hello World with call_soon() +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Example using the :meth:`BaseEventLoop.call_soon` method to schedule a +callback. The callback displays ``"Hello World"`` and then stops the event +loop:: + + import asyncio + + def hello_world(loop): + print('Hello World') + loop.stop() + + loop = asyncio.get_event_loop() + + # Schedule a call to hello_world() + loop.call_soon(hello_world, loop) + + # Blocking call interrupted by loop.stop() + loop.run_forever() + loop.close() + +.. seealso:: + + The :ref:`Hello World coroutine <asyncio-hello-world-coroutine>` example + uses a :ref:`coroutine <coroutine>`. + + +.. _asyncio-date-callback: + +Display the current date with call_later() +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Example of callback displaying the current date every second. The callback uses +the :meth:`BaseEventLoop.call_later` method to reschedule itself during 5 +seconds, and then stops the event loop:: + + import asyncio + import datetime + + def display_date(end_time, loop): + print(datetime.datetime.now()) + if (loop.time() + 1.0) < end_time: + loop.call_later(1, display_date, end_time, loop) + else: + loop.stop() + + loop = asyncio.get_event_loop() + + # Schedule the first call to display_date() + end_time = loop.time() + 5.0 + loop.call_soon(display_date, end_time, loop) + + # Blocking call interrupted by loop.stop() + loop.run_forever() + loop.close() + +.. seealso:: + + The :ref:`coroutine displaying the current date + <asyncio-date-coroutine>` example uses a :ref:`coroutine + <coroutine>`. + + +.. _asyncio-watch-read-event: + +Watch a file descriptor for read events +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Wait until a file descriptor received some data using the +:meth:`BaseEventLoop.add_reader` method and then close the event loop:: + + import asyncio + try: + from socket import socketpair + except ImportError: + from asyncio.windows_utils import socketpair + + # Create a pair of connected file descriptors + rsock, wsock = socketpair() + loop = asyncio.get_event_loop() + + def reader(): + data = rsock.recv(100) + print("Received:", data.decode()) + # We are done: unregister the file descriptor + loop.remove_reader(rsock) + # Stop the event loop + loop.stop() + + # Register the file descriptor for read event + loop.add_reader(rsock, reader) + + # Simulate the reception of data from the network + loop.call_soon(wsock.send, 'abc'.encode()) + + # Run the event loop + loop.run_forever() + + # We are done, close sockets and the event loop + rsock.close() + wsock.close() + loop.close() + +.. seealso:: + + The :ref:`register an open socket to wait for data using a protocol + <asyncio-register-socket>` example uses a low-level protocol created by the + :meth:`BaseEventLoop.create_connection` method. + + The :ref:`register an open socket to wait for data using streams + <asyncio-register-socket-streams>` example uses high-level streams + created by the :func:`open_connection` function in a coroutine. + + +Set signal handlers for SIGINT and SIGTERM +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Register handlers for signals :py:data:`SIGINT` and :py:data:`SIGTERM` using +the :meth:`BaseEventLoop.add_signal_handler` method:: + + import asyncio + import functools + import os + import signal + + def ask_exit(signame): + print("got signal %s: exit" % signame) + loop.stop() + + loop = asyncio.get_event_loop() + for signame in ('SIGINT', 'SIGTERM'): + loop.add_signal_handler(getattr(signal, signame), + functools.partial(ask_exit, signame)) + + print("Event loop running forever, press Ctrl+C to interrupt.") + print("pid %s: send SIGINT or SIGTERM to exit." % os.getpid()) + try: + loop.run_forever() + finally: + loop.close() + +This example only works on UNIX. diff --git a/Doc/library/asyncio-eventloops.rst b/Doc/library/asyncio-eventloops.rst new file mode 100644 index 000000000000..ae3bf9029806 --- /dev/null +++ b/Doc/library/asyncio-eventloops.rst @@ -0,0 +1,201 @@ +.. currentmodule:: asyncio + +Event loops +=========== + +Event loop functions +-------------------- + +The following functions are convenient shortcuts to accessing the methods of the +global policy. Note that this provides access to the default policy, unless an +alternative policy was set by calling :func:`set_event_loop_policy` earlier in +the execution of the process. + +.. function:: get_event_loop() + + Equivalent to calling ``get_event_loop_policy().get_event_loop()``. + +.. function:: set_event_loop(loop) + + Equivalent to calling ``get_event_loop_policy().set_event_loop(loop)``. + +.. function:: new_event_loop() + + Equivalent to calling ``get_event_loop_policy().new_event_loop()``. + + +.. _asyncio-event-loops: + +Available event loops +--------------------- + +asyncio currently provides two implementations of event loops: +:class:`SelectorEventLoop` and :class:`ProactorEventLoop`. + +.. class:: SelectorEventLoop + + Event loop based on the :mod:`selectors` module. Subclass of + :class:`BaseEventLoop`. + + Use the most efficient selector available on the platform. + + On Windows, only sockets are supported (ex: pipes are not supported): + see the `MSDN documentation of select + <http://msdn.microsoft.com/en-us/library/windows/desktop/ms740141%28v=vs.85%29.aspx>`_. + +.. class:: ProactorEventLoop + + Proactor event loop for Windows using "I/O Completion Ports" aka IOCP. + Subclass of :class:`BaseEventLoop`. + + Availability: Windows. + + .. seealso:: + + `MSDN documentation on I/O Completion Ports + <http://msdn.microsoft.com/en-us/library/windows/desktop/aa365198%28v=vs.85%29.aspx>`_. + +Example to use a :class:`ProactorEventLoop` on Windows:: + + import asyncio, os + + if os.name == 'nt': + loop = asyncio.ProactorEventLoop() + asyncio.set_event_loop(loop) + +.. _asyncio-platform-support: + +Platform support +---------------- + +The :mod:`asyncio` module has been designed to be portable, but each platform +still has subtle differences and may not support all :mod:`asyncio` features. + +Windows +^^^^^^^ + +Common limits of Windows event loops: + +- :meth:`~BaseEventLoop.create_unix_connection` and + :meth:`~BaseEventLoop.create_unix_server` are not supported: the socket + family :data:`socket.AF_UNIX` is specific to UNIX +- :meth:`~BaseEventLoop.add_signal_handler` and + :meth:`~BaseEventLoop.remove_signal_handler` are not supported +- :meth:`EventLoopPolicy.set_child_watcher` is not supported. + :class:`ProactorEventLoop` supports subprocesses. It has only one + implementation to watch child processes, there is no need to configure it. + +:class:`SelectorEventLoop` specific limits: + +- :class:`~selectors.SelectSelector` is used which only supports sockets + and is limited to 512 sockets. +- :meth:`~BaseEventLoop.add_reader` and :meth:`~BaseEventLoop.add_writer` only + accept file descriptors of sockets +- Pipes are not supported + (ex: :meth:`~BaseEventLoop.connect_read_pipe`, + :meth:`~BaseEventLoop.connect_write_pipe`) +- :ref:`Subprocesses <asyncio-subprocess>` are not supported + (ex: :meth:`~BaseEventLoop.subprocess_exec`, + :meth:`~BaseEventLoop.subprocess_shell`) + +:class:`ProactorEventLoop` specific limits: + +- :meth:`~BaseEventLoop.create_datagram_endpoint` (UDP) is not supported +- :meth:`~BaseEventLoop.add_reader` and :meth:`~BaseEventLoop.add_writer` are + not supported + +The resolution of the monotonic clock on Windows is usually around 15.6 msec. +The best resolution is 0.5 msec. The resolution depends on the hardware +(availability of `HPET +<http://fr.wikipedia.org/wiki/High_Precision_Event_Timer>`_) and on the Windows +configuration. See :ref:`asyncio delayed calls <asyncio-delayed-calls>`. + +.. versionchanged:: 3.5 + + :class:`ProactorEventLoop` now supports SSL. + + +Mac OS X +^^^^^^^^ + +Character devices like PTY are only well supported since Mavericks (Mac OS +10.9). They are not supported at all on Mac OS 10.5 and older. + +On Mac OS 10.6, 10.7 and 10.8, the default event loop is +:class:`SelectorEventLoop` which uses :class:`selectors.KqueueSelector`. +:class:`selectors.KqueueSelector` does not support character devices on these +versions. The :class:`SelectorEventLoop` can be used with +:class:`~selectors.SelectSelector` or :class:`~selectors.PollSelector` to +support character devices on these versions of Mac OS X. Example:: + + import asyncio + import selectors + + selector = selectors.SelectSelector() + loop = asyncio.SelectorEventLoop(selector) + asyncio.set_event_loop(loop) + + +Event loop policies and the default policy +------------------------------------------ + +Event loop management is abstracted with a *policy* pattern, to provide maximal +flexibility for custom platforms and frameworks. Throughout the execution of a +process, a single global policy object manages the event loops available to the +process based on the calling context. A policy is an object implementing the +:class:`AbstractEventLoopPolicy` interface. + +For most users of :mod:`asyncio`, policies never have to be dealt with +explicitly, since the default global policy is sufficient. + +The default policy defines context as the current thread, and manages an event +loop per thread that interacts with :mod:`asyncio`. The module-level functions +:func:`get_event_loop` and :func:`set_event_loop` provide convenient access to +event loops managed by the default policy. + + +Event loop policy interface +--------------------------- + +An event loop policy must implement the following interface: + +.. class:: AbstractEventLoopPolicy + + Event loop policy. + + .. method:: get_event_loop() + + Get the event loop for the current context. + + Returns an event loop object implementing the :class:`BaseEventLoop` + interface. + + Raises an exception in case no event loop has been set for the current + context and the current policy does not specify to create one. It must + never return ``None``. + + .. method:: set_event_loop(loop) + + Set the event loop for the current context to *loop*. + + .. method:: new_event_loop() + + Create and return a new event loop object according to this policy's + rules. + + If there's need to set this loop as the event loop for the current + context, :meth:`set_event_loop` must be called explicitly. + + +Access to the global loop policy +-------------------------------- + +.. function:: get_event_loop_policy() + + Get the current event loop policy. + +.. function:: set_event_loop_policy(policy) + + Set the current event loop policy. If *policy* is ``None``, the default + policy is restored. + diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst new file mode 100644 index 000000000000..93694f3847d4 --- /dev/null +++ b/Doc/library/asyncio-protocol.rst @@ -0,0 +1,711 @@ +.. currentmodule:: asyncio + ++++++++++++++++++++++++++++++++++++++++++ +Transports and protocols (low-level API) ++++++++++++++++++++++++++++++++++++++++++ + +.. _asyncio-transport: + +Transports +========== + +Transports are classes provided by :mod:`asyncio` in order to abstract +various kinds of communication channels. You generally won't instantiate +a transport yourself; instead, you will call a :class:`BaseEventLoop` method +which will create the transport and try to initiate the underlying +communication channel, calling you back when it succeeds. + +Once the communication channel is established, a transport is always +paired with a :ref:`protocol <asyncio-protocol>` instance. The protocol can +then call the transport's methods for various purposes. + +:mod:`asyncio` currently implements transports for TCP, UDP, SSL, and +subprocess pipes. The methods available on a transport depend on +the transport's kind. + +The transport classes are :ref:`not thread safe <asyncio-multithreading>`. + + +BaseTransport +------------- + +.. class:: BaseTransport + + Base class for transports. + + .. method:: close(self) + + Close the transport. If the transport has a buffer for outgoing + data, buffered data will be flushed asynchronously. No more data + will be received. After all buffered data is flushed, the + protocol's :meth:`connection_lost` method will be called with + :const:`None` as its argument. + + + .. method:: get_extra_info(name, default=None) + + Return optional transport information. *name* is a string representing + the piece of transport-specific information to get, *default* is the + value to return if the information doesn't exist. + + This method allows transport implementations to easily expose + channel-specific information. + + * socket: + + - ``'peername'``: the remote address to which the socket is connected, + result of :meth:`socket.socket.getpeername` (``None`` on error) + - ``'socket'``: :class:`socket.socket` instance + - ``'sockname'``: the socket's own address, + result of :meth:`socket.socket.getsockname` + + * SSL socket: + + - ``'compression'``: the compression algorithm being used as a string, + or ``None`` if the connection isn't compressed; result of + :meth:`ssl.SSLSocket.compression` + - ``'cipher'``: a three-value tuple containing the name of the cipher + being used, the version of the SSL protocol that defines its use, and + the number of secret bits being used; result of + :meth:`ssl.SSLSocket.cipher` + - ``'peercert'``: peer certificate; result of + :meth:`ssl.SSLSocket.getpeercert` + - ``'sslcontext'``: :class:`ssl.SSLContext` instance + - ``'ssl_object'``: :class:`ssl.SSLObject` or :class:`ssl.SSLSocket` + instance + + * pipe: + + - ``'pipe'``: pipe object + + * subprocess: + + - ``'subprocess'``: :class:`subprocess.Popen` instance + + .. versionchanged:: 3.5.1 + ``'ssl_object'`` info was added to SSL sockets. + + +ReadTransport +------------- + +.. class:: ReadTransport + + Interface for read-only transports. + + .. method:: pause_reading() + + Pause the receiving end of the transport. No data will be passed to + the protocol's :meth:`data_received` method until :meth:`resume_reading` + is called. + + .. method:: resume_reading() + + Resume the receiving end. The protocol's :meth:`data_received` method + will be called once again if some data is available for reading. + + +WriteTransport +-------------- + +.. class:: WriteTransport + + Interface for write-only transports. + + .. method:: abort() + + Close the transport immediately, without waiting for pending operations + to complete. Buffered data will be lost. No more data will be received. + The protocol's :meth:`connection_lost` method will eventually be + called with :const:`None` as its argument. + + .. method:: can_write_eof() + + Return :const:`True` if the transport supports :meth:`write_eof`, + :const:`False` if not. + + .. method:: get_write_buffer_size() + + Return the current size of the output buffer used by the transport. + + .. method:: get_write_buffer_limits() + + Get the *high*- and *low*-water limits for write flow control. Return a + tuple ``(low, high)`` where *low* and *high* are positive number of + bytes. + + Use :meth:`set_write_buffer_limits` to set the limits. + + .. versionadded:: 3.4.2 + + .. method:: set_write_buffer_limits(high=None, low=None) + + Set the *high*- and *low*-water limits for write flow control. + + These two values control when call the protocol's + :meth:`pause_writing` and :meth:`resume_writing` methods are called. + If specified, the low-water limit must be less than or equal to the + high-water limit. Neither *high* nor *low* can be negative. + + The defaults are implementation-specific. If only the + high-water limit is given, the low-water limit defaults to a + implementation-specific value less than or equal to the + high-water limit. Setting *high* to zero forces *low* to zero as + well, and causes :meth:`pause_writing` to be called whenever the + buffer becomes non-empty. Setting *low* to zero causes + :meth:`resume_writing` to be called only once the buffer is empty. + Use of zero for either limit is generally sub-optimal as it + reduces opportunities for doing I/O and computation + concurrently. + + Use :meth:`get_write_buffer_limits` to get the limits. + + .. method:: write(data) + + Write some *data* bytes to the transport. + + This method does not block; it buffers the data and arranges for it + to be sent out asynchronously. + + .. method:: writelines(list_of_data) + + Write a list (or any iterable) of data bytes to the transport. + This is functionally equivalent to calling :meth:`write` on each + element yielded by the iterable, but may be implemented more efficiently. + + .. method:: write_eof() + + Close the write end of the transport after flushing buffered data. + Data may still be received. + + This method can raise :exc:`NotImplementedError` if the transport + (e.g. SSL) doesn't support half-closes. + + +DatagramTransport +----------------- + +.. method:: DatagramTransport.sendto(data, addr=None) + + Send the *data* bytes to the remote peer given by *addr* (a + transport-dependent target address). If *addr* is :const:`None`, the + data is sent to the target address given on transport creation. + + This method does not block; it buffers the data and arranges for it + to be sent out asynchronously. + +.. method:: DatagramTransport.abort() + + Close the transport immediately, without waiting for pending operations + to complete. Buffered data will be lost. No more data will be received. + The protocol's :meth:`connection_lost` method will eventually be + called with :const:`None` as its argument. + + +BaseSubprocessTransport +----------------------- + +.. class:: BaseSubprocessTransport + + .. method:: get_pid() + + Return the subprocess process id as an integer. + + .. method:: get_pipe_transport(fd) + + Return the transport for the communication pipe corresponding to the + integer file descriptor *fd*: + + * ``0``: readable streaming transport of the standard input (*stdin*), + or :const:`None` if the subprocess was not created with ``stdin=PIPE`` + * ``1``: writable streaming transport of the standard output (*stdout*), + or :const:`None` if the subprocess was not created with ``stdout=PIPE`` + * ``2``: writable streaming transport of the standard error (*stderr*), + or :const:`None` if the subprocess was not created with ``stderr=PIPE`` + * other *fd*: :const:`None` + + .. method:: get_returncode() + + Return the subprocess returncode as an integer or :const:`None` + if it hasn't returned, similarly to the + :attr:`subprocess.Popen.returncode` attribute. + + .. method:: kill(self) + + Kill the subprocess, as in :meth:`subprocess.Popen.kill`. + + On POSIX systems, the function sends SIGKILL to the subprocess. + On Windows, this method is an alias for :meth:`terminate`. + + .. method:: send_signal(signal) + + Send the *signal* number to the subprocess, as in + :meth:`subprocess.Popen.send_signal`. + + .. method:: terminate() + + Ask the subprocess to stop, as in :meth:`subprocess.Popen.terminate`. + This method is an alias for the :meth:`close` method. + + On POSIX systems, this method sends SIGTERM to the subprocess. + On Windows, the Windows API function TerminateProcess() is called to + stop the subprocess. + + .. method:: close() + + Ask the subprocess to stop by calling the :meth:`terminate` method if the + subprocess hasn't returned yet, and close transports of all pipes + (*stdin*, *stdout* and *stderr*). + + +.. _asyncio-protocol: + +Protocols +========= + +:mod:`asyncio` provides base classes that you can subclass to implement +your network protocols. Those classes are used in conjunction with +:ref:`transports <asyncio-transport>` (see below): the protocol parses incoming +data and asks for the writing of outgoing data, while the transport is +responsible for the actual I/O and buffering. + +When subclassing a protocol class, it is recommended you override certain +methods. Those methods are callbacks: they will be called by the transport +on certain events (for example when some data is received); you shouldn't +call them yourself, unless you are implementing a transport. + +.. note:: + All callbacks have default implementations, which are empty. Therefore, + you only need to implement the callbacks for the events in which you + are interested. + + +Protocol classes +---------------- + +.. class:: Protocol + + The base class for implementing streaming protocols (for use with + e.g. TCP and SSL transports). + +.. class:: DatagramProtocol + + The base class for implementing datagram protocols (for use with + e.g. UDP transports). + +.. class:: SubprocessProtocol + + The base class for implementing protocols communicating with child + processes (through a set of unidirectional pipes). + + +Connection callbacks +-------------------- + +These callbacks may be called on :class:`Protocol`, :class:`DatagramProtocol` +and :class:`SubprocessProtocol` instances: + +.. method:: BaseProtocol.connection_made(transport) + + Called when a connection is made. + + The *transport* argument is the transport representing the + connection. You are responsible for storing it somewhere + (e.g. as an attribute) if you need to. + +.. method:: BaseProtocol.connection_lost(exc) + + Called when the connection is lost or closed. + + The argument is either an exception object or :const:`None`. + The latter means a regular EOF is received, or the connection was + aborted or closed by this side of the connection. + +:meth:`~BaseProtocol.connection_made` and :meth:`~BaseProtocol.connection_lost` +are called exactly once per successful connection. All other callbacks will be +called between those two methods, which allows for easier resource management +in your protocol implementation. + +The following callbacks may be called only on :class:`SubprocessProtocol` +instances: + +.. method:: SubprocessProtocol.pipe_data_received(fd, data) + + Called when the child process writes data into its stdout or stderr pipe. + *fd* is the integer file descriptor of the pipe. *data* is a non-empty + bytes object containing the data. + +.. method:: SubprocessProtocol.pipe_connection_lost(fd, exc) + + Called when one of the pipes communicating with the child process + is closed. *fd* is the integer file descriptor that was closed. + +.. method:: SubprocessProtocol.process_exited() + + Called when the child process has exited. + + +Streaming protocols +------------------- + +The following callbacks are called on :class:`Protocol` instances: + +.. method:: Protocol.data_received(data) + + Called when some data is received. *data* is a non-empty bytes object + containing the incoming data. + + .. note:: + Whether the data is buffered, chunked or reassembled depends on + the transport. In general, you shouldn't rely on specific semantics + and instead make your parsing generic and flexible enough. However, + data is always received in the correct order. + +.. method:: Protocol.eof_received() + + Calls when the other end signals it won't send any more data + (for example by calling :meth:`write_eof`, if the other end also uses + asyncio). + + This method may return a false value (including None), in which case + the transport will close itself. Conversely, if this method returns a + true value, closing the transport is up to the protocol. Since the + default implementation returns None, it implicitly closes the connection. + + .. note:: + Some transports such as SSL don't support half-closed connections, + in which case returning true from this method will not prevent closing + the connection. + +:meth:`data_received` can be called an arbitrary number of times during +a connection. However, :meth:`eof_received` is called at most once +and, if called, :meth:`data_received` won't be called after it. + +State machine: + + start -> :meth:`~BaseProtocol.connection_made` + [-> :meth:`~Protocol.data_received` \*] + [-> :meth:`~Protocol.eof_received` ?] + -> :meth:`~BaseProtocol.connection_lost` -> end + + +Datagram protocols +------------------ + +The following callbacks are called on :class:`DatagramProtocol` instances. + +.. method:: DatagramProtocol.datagram_received(data, addr) + + Called when a datagram is received. *data* is a bytes object containing + the incoming data. *addr* is the address of the peer sending the data; + the exact format depends on the transport. + +.. method:: DatagramProtocol.error_received(exc) + + Called when a previous send or receive operation raises an + :class:`OSError`. *exc* is the :class:`OSError` instance. + + This method is called in rare conditions, when the transport (e.g. UDP) + detects that a datagram couldn't be delivered to its recipient. + In many conditions though, undeliverable datagrams will be silently + dropped. + + +Flow control callbacks +---------------------- + +These callbacks may be called on :class:`Protocol`, +:class:`DatagramProtocol` and :class:`SubprocessProtocol` instances: + +.. method:: BaseProtocol.pause_writing() + + Called when the transport's buffer goes over the high-water mark. + +.. method:: BaseProtocol.resume_writing() + + Called when the transport's buffer drains below the low-water mark. + + +:meth:`pause_writing` and :meth:`resume_writing` calls are paired -- +:meth:`pause_writing` is called once when the buffer goes strictly over +the high-water mark (even if subsequent writes increases the buffer size +even more), and eventually :meth:`resume_writing` is called once when the +buffer size reaches the low-water mark. + +.. note:: + If the buffer size equals the high-water mark, + :meth:`pause_writing` is not called -- it must go strictly over. + Conversely, :meth:`resume_writing` is called when the buffer size is + equal or lower than the low-water mark. These end conditions + are important to ensure that things go as expected when either + mark is zero. + +.. note:: + On BSD systems (OS X, FreeBSD, etc.) flow control is not supported + for :class:`DatagramProtocol`, because send failures caused by + writing too many packets cannot be detected easily. The socket + always appears 'ready' and excess packets are dropped; an + :class:`OSError` with errno set to :const:`errno.ENOBUFS` may or + may not be raised; if it is raised, it will be reported to + :meth:`DatagramProtocol.error_received` but otherwise ignored. + + +Coroutines and protocols +------------------------ + +Coroutines can be scheduled in a protocol method using :func:`ensure_future`, +but there is no guarantee made about the execution order. Protocols are not +aware of coroutines created in protocol methods and so will not wait for them. + +To have a reliable execution order, use :ref:`stream objects <asyncio-streams>` in a +coroutine with ``yield from``. For example, the :meth:`StreamWriter.drain` +coroutine can be used to wait until the write buffer is flushed. + + +Protocol examples +================= + +.. _asyncio-tcp-echo-client-protocol: + +TCP echo client protocol +------------------------ + +TCP echo client using the :meth:`BaseEventLoop.create_connection` method, send +data and wait until the connection is closed:: + + import asyncio + + class EchoClientProtocol(asyncio.Protocol): + def __init__(self, message, loop): + self.message = message + self.loop = loop + + def connection_made(self, transport): + transport.write(self.message.encode()) + print('Data sent: {!r}'.format(self.message)) + + def data_received(self, data): + print('Data received: {!r}'.format(data.decode())) + + def connection_lost(self, exc): + print('The server closed the connection') + print('Stop the event lop') + self.loop.stop() + + loop = asyncio.get_event_loop() + message = 'Hello World!' + coro = loop.create_connection(lambda: EchoClientProtocol(message, loop), + '127.0.0.1', 8888) + loop.run_until_complete(coro) + loop.run_forever() + loop.close() + +The event loop is running twice. The +:meth:`~BaseEventLoop.run_until_complete` method is preferred in this short +example to raise an exception if the server is not listening, instead of +having to write a short coroutine to handle the exception and stop the +running loop. At :meth:`~BaseEventLoop.run_until_complete` exit, the loop is +no longer running, so there is no need to stop the loop in case of an error. + +.. seealso:: + + The :ref:`TCP echo client using streams <asyncio-tcp-echo-client-streams>` + example uses the :func:`asyncio.open_connection` function. + + +.. _asyncio-tcp-echo-server-protocol: + +TCP echo server protocol +------------------------ + +TCP echo server using the :meth:`BaseEventLoop.create_server` method, send back +received data and close the connection:: + + import asyncio + + class EchoServerClientProtocol(asyncio.Protocol): + def connection_made(self, transport): + peername = transport.get_extra_info('peername') + print('Connection from {}'.format(peername)) + self.transport = transport + + def data_received(self, data): + message = data.decode() + print('Data received: {!r}'.format(message)) + + print('Send: {!r}'.format(message)) + self.transport.write(data) + + print('Close the client socket') + self.transport.close() + + loop = asyncio.get_event_loop() + # Each client connection will create a new protocol instance + coro = loop.create_server(EchoServerClientProtocol, '127.0.0.1', 8888) + server = loop.run_until_complete(coro) + + # Serve requests until Ctrl+C is pressed + print('Serving on {}'.format(server.sockets[0].getsockname())) + try: + loop.run_forever() + except KeyboardInterrupt: + pass + + # Close the server + server.close() + loop.run_until_complete(server.wait_closed()) + loop.close() + +:meth:`Transport.close` can be called immediately after +:meth:`WriteTransport.write` even if data are not sent yet on the socket: both +methods are asynchronous. ``yield from`` is not needed because these transport +methods are not coroutines. + +.. seealso:: + + The :ref:`TCP echo server using streams <asyncio-tcp-echo-server-streams>` + example uses the :func:`asyncio.start_server` function. + + +.. _asyncio-udp-echo-client-protocol: + +UDP echo client protocol +------------------------ + +UDP echo client using the :meth:`BaseEventLoop.create_datagram_endpoint` +method, send data and close the transport when we received the answer:: + + import asyncio + + class EchoClientProtocol: + def __init__(self, message, loop): + self.message = message + self.loop = loop + self.transport = None + + def connection_made(self, transport): + self.transport = transport + print('Send:', self.message) + self.transport.sendto(self.message.encode()) + + def datagram_received(self, data, addr): + print("Received:", data.decode()) + + print("Close the socket") + self.transport.close() + + def error_received(self, exc): + print('Error received:', exc) + + def connection_lost(self, exc): + print("Socket closed, stop the event loop") + loop = asyncio.get_event_loop() + loop.stop() + + loop = asyncio.get_event_loop() + message = "Hello World!" + connect = loop.create_datagram_endpoint( + lambda: EchoClientProtocol(message, loop), + remote_addr=('127.0.0.1', 9999)) + transport, protocol = loop.run_until_complete(connect) + loop.run_forever() + transport.close() + loop.close() + + +.. _asyncio-udp-echo-server-protocol: + +UDP echo server protocol +------------------------ + +UDP echo server using the :meth:`BaseEventLoop.create_datagram_endpoint` +method, send back received data:: + + import asyncio + + class EchoServerProtocol: + def connection_made(self, transport): + self.transport = transport + + def datagram_received(self, data, addr): + message = data.decode() + print('Received %r from %s' % (message, addr)) + print('Send %r to %s' % (message, addr)) + self.transport.sendto(data, addr) + + loop = asyncio.get_event_loop() + print("Starting UDP server") + # One protocol instance will be created to serve all client requests + listen = loop.create_datagram_endpoint( + EchoServerProtocol, local_addr=('127.0.0.1', 9999)) + transport, protocol = loop.run_until_complete(listen) + + try: + loop.run_forever() + except KeyboardInterrupt: + pass + + transport.close() + loop.close() + + +.. _asyncio-register-socket: + +Register an open socket to wait for data using a protocol +--------------------------------------------------------- + +Wait until a socket receives data using the +:meth:`BaseEventLoop.create_connection` method with a protocol, and then close +the event loop :: + + import asyncio + try: + from socket import socketpair + except ImportError: + from asyncio.windows_utils import socketpair + + # Create a pair of connected sockets + rsock, wsock = socketpair() + loop = asyncio.get_event_loop() + + class MyProtocol(asyncio.Protocol): + transport = None + + def connection_made(self, transport): + self.transport = transport + + def data_received(self, data): + print("Received:", data.decode()) + + # We are done: close the transport (it will call connection_lost()) + self.transport.close() + + def connection_lost(self, exc): + # The socket has been closed, stop the event loop + loop.stop() + + # Register the socket to wait for data + connect_coro = loop.create_connection(MyProtocol, sock=rsock) + transport, protocol = loop.run_until_complete(connect_coro) + + # Simulate the reception of data from the network + loop.call_soon(wsock.send, 'abc'.encode()) + + # Run the event loop + loop.run_forever() + + # We are done, close sockets and the event loop + rsock.close() + wsock.close() + loop.close() + +.. seealso:: + + The :ref:`watch a file descriptor for read events + <asyncio-watch-read-event>` example uses the low-level + :meth:`BaseEventLoop.add_reader` method to register the file descriptor of a + socket. + + The :ref:`register an open socket to wait for data using streams + <asyncio-register-socket-streams>` example uses high-level streams + created by the :func:`open_connection` function in a coroutine. diff --git a/Doc/library/asyncio-queue.rst b/Doc/library/asyncio-queue.rst new file mode 100644 index 000000000000..f11c09ac2905 --- /dev/null +++ b/Doc/library/asyncio-queue.rst @@ -0,0 +1,158 @@ +.. currentmodule:: asyncio + +Queues +====== + +Queues: + +* :class:`Queue` +* :class:`PriorityQueue` +* :class:`LifoQueue` + +asyncio queue API was designed to be close to classes of the :mod:`queue` +module (:class:`~queue.Queue`, :class:`~queue.PriorityQueue`, +:class:`~queue.LifoQueue`), but it has no *timeout* parameter. The +:func:`asyncio.wait_for` function can be used to cancel a task after a timeout. + +Queue +----- + +.. class:: Queue(maxsize=0, \*, loop=None) + + A queue, useful for coordinating producer and consumer coroutines. + + If *maxsize* is less than or equal to zero, the queue size is infinite. If + it is an integer greater than ``0``, then ``yield from put()`` will block + when the queue reaches *maxsize*, until an item is removed by :meth:`get`. + + Unlike the standard library :mod:`queue`, you can reliably know this Queue's + size with :meth:`qsize`, since your single-threaded asyncio application won't + be interrupted between calling :meth:`qsize` and doing an operation on the + Queue. + + This class is :ref:`not thread safe <asyncio-multithreading>`. + + .. versionchanged:: 3.4.4 + New :meth:`join` and :meth:`task_done` methods. + + .. method:: empty() + + Return ``True`` if the queue is empty, ``False`` otherwise. + + .. method:: full() + + Return ``True`` if there are :attr:`maxsize` items in the queue. + + .. note:: + + If the Queue was initialized with ``maxsize=0`` (the default), then + :meth:`full()` is never ``True``. + + .. coroutinemethod:: get() + + Remove and return an item from the queue. If queue is empty, wait until + an item is available. + + This method is a :ref:`coroutine <coroutine>`. + + .. seealso:: + + The :meth:`empty` method. + + .. method:: get_nowait() + + Remove and return an item from the queue. + + Return an item if one is immediately available, else raise + :exc:`QueueEmpty`. + + .. coroutinemethod:: join() + + Block until all items in the queue have been gotten and processed. + + The count of unfinished tasks goes up whenever an item is added to the + queue. The count goes down whenever a consumer thread calls + :meth:`task_done` to indicate that the item was retrieved and all work on + it is complete. When the count of unfinished tasks drops to zero, + :meth:`join` unblocks. + + This method is a :ref:`coroutine <coroutine>`. + + .. versionadded:: 3.4.4 + + .. coroutinemethod:: put(item) + + Put an item into the queue. If the queue is full, wait until a free slot + is available before adding item. + + This method is a :ref:`coroutine <coroutine>`. + + .. seealso:: + + The :meth:`full` method. + + .. method:: put_nowait(item) + + Put an item into the queue without blocking. + + If no free slot is immediately available, raise :exc:`QueueFull`. + + .. method:: qsize() + + Number of items in the queue. + + .. method:: task_done() + + Indicate that a formerly enqueued task is complete. + + Used by queue consumers. For each :meth:`~Queue.get` used to fetch a task, a + subsequent call to :meth:`task_done` tells the queue that the processing + on the task is complete. + + If a :meth:`join` is currently blocking, it will resume when all items + have been processed (meaning that a :meth:`task_done` call was received + for every item that had been :meth:`~Queue.put` into the queue). + + Raises :exc:`ValueError` if called more times than there were items + placed in the queue. + + .. versionadded:: 3.4.4 + + .. attribute:: maxsize + + Number of items allowed in the queue. + + +PriorityQueue +------------- + +.. class:: PriorityQueue + + A subclass of :class:`Queue`; retrieves entries in priority order (lowest + first). + + Entries are typically tuples of the form: (priority number, data). + + +LifoQueue +--------- + +.. class:: LifoQueue + + A subclass of :class:`Queue` that retrieves most recently added entries + first. + + +Exceptions +^^^^^^^^^^ + +.. exception:: QueueEmpty + + Exception raised when the :meth:`~Queue.get_nowait` method is called on a + :class:`Queue` object which is empty. + + +.. exception:: QueueFull + + Exception raised when the :meth:`~Queue.put_nowait` method is called on a + :class:`Queue` object which is full. diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst new file mode 100644 index 000000000000..171fd8627620 --- /dev/null +++ b/Doc/library/asyncio-stream.rst @@ -0,0 +1,431 @@ +.. currentmodule:: asyncio + +.. _asyncio-streams: + +++++++++++++++++++++++++ +Streams (high-level API) +++++++++++++++++++++++++ + +Stream functions +================ + +.. note:: + + The top-level functions in this module are meant convenience wrappers + only; there's really nothing special there, and if they don't do + exactly what you want, feel free to copy their code. + + +.. coroutinefunction:: open_connection(host=None, port=None, \*, loop=None, limit=None, \*\*kwds) + + A wrapper for :meth:`~BaseEventLoop.create_connection()` returning a (reader, + writer) pair. + + The reader returned is a :class:`StreamReader` instance; the writer is + a :class:`StreamWriter` instance. + + The arguments are all the usual arguments to + :meth:`BaseEventLoop.create_connection` except *protocol_factory*; most + common are positional host and port, with various optional keyword arguments + following. + + Additional optional keyword arguments are *loop* (to set the event loop + instance to use) and *limit* (to set the buffer limit passed to the + :class:`StreamReader`). + + This function is a :ref:`coroutine <coroutine>`. + +.. coroutinefunction:: start_server(client_connected_cb, host=None, port=None, \*, loop=None, limit=None, \*\*kwds) + + Start a socket server, with a callback for each client connected. The return + value is the same as :meth:`~BaseEventLoop.create_server()`. + + The *client_connected_cb* parameter is called with two parameters: + *client_reader*, *client_writer*. *client_reader* is a + :class:`StreamReader` object, while *client_writer* is a + :class:`StreamWriter` object. The *client_connected_cb* parameter can + either be a plain callback function or a :ref:`coroutine function + <coroutine>`; if it is a coroutine function, it will be automatically + converted into a :class:`Task`. + + The rest of the arguments are all the usual arguments to + :meth:`~BaseEventLoop.create_server()` except *protocol_factory*; most + common are positional *host* and *port*, with various optional keyword + arguments following. + + Additional optional keyword arguments are *loop* (to set the event loop + instance to use) and *limit* (to set the buffer limit passed to the + :class:`StreamReader`). + + This function is a :ref:`coroutine <coroutine>`. + +.. coroutinefunction:: open_unix_connection(path=None, \*, loop=None, limit=None, **kwds) + + A wrapper for :meth:`~BaseEventLoop.create_unix_connection()` returning + a (reader, writer) pair. + + See :func:`open_connection` for information about return value and other + details. + + This function is a :ref:`coroutine <coroutine>`. + + Availability: UNIX. + +.. coroutinefunction:: start_unix_server(client_connected_cb, path=None, \*, loop=None, limit=None, **kwds) + + Start a UNIX Domain Socket server, with a callback for each client connected. + + See :func:`start_server` for information about return value and other + details. + + This function is a :ref:`coroutine <coroutine>`. + + Availability: UNIX. + + +StreamReader +============ + +.. class:: StreamReader(limit=None, loop=None) + + This class is :ref:`not thread safe <asyncio-multithreading>`. + + .. method:: exception() + + Get the exception. + + .. method:: feed_eof() + + Acknowledge the EOF. + + .. method:: feed_data(data) + + Feed *data* bytes in the internal buffer. Any operations waiting + for the data will be resumed. + + .. method:: set_exception(exc) + + Set the exception. + + .. method:: set_transport(transport) + + Set the transport. + + .. coroutinemethod:: read(n=-1) + + Read up to *n* bytes. If *n* is not provided, or set to ``-1``, + read until EOF and return all read bytes. + + If the EOF was received and the internal buffer is empty, + return an empty ``bytes`` object. + + This method is a :ref:`coroutine <coroutine>`. + + .. coroutinemethod:: readline() + + Read one line, where "line" is a sequence of bytes ending with ``\n``. + + If EOF is received, and ``\n`` was not found, the method will + return the partial read bytes. + + If the EOF was received and the internal buffer is empty, + return an empty ``bytes`` object. + + This method is a :ref:`coroutine <coroutine>`. + + .. coroutinemethod:: readexactly(n) + + Read exactly *n* bytes. Raise an :exc:`IncompleteReadError` if the end of + the stream is reached before *n* can be read, the + :attr:`IncompleteReadError.partial` attribute of the exception contains + the partial read bytes. + + This method is a :ref:`coroutine <coroutine>`. + + .. method:: at_eof() + + Return ``True`` if the buffer is empty and :meth:`feed_eof` was called. + + +StreamWriter +============ + +.. class:: StreamWriter(transport, protocol, reader, loop) + + Wraps a Transport. + + This exposes :meth:`write`, :meth:`writelines`, :meth:`can_write_eof()`, + :meth:`write_eof`, :meth:`get_extra_info` and :meth:`close`. It adds + :meth:`drain` which returns an optional :class:`Future` on which you can + wait for flow control. It also adds a transport attribute which references + the :class:`Transport` directly. + + This class is :ref:`not thread safe <asyncio-multithreading>`. + + .. attribute:: transport + + Transport. + + .. method:: can_write_eof() + + Return :const:`True` if the transport supports :meth:`write_eof`, + :const:`False` if not. See :meth:`WriteTransport.can_write_eof`. + + .. method:: close() + + Close the transport: see :meth:`BaseTransport.close`. + + .. coroutinemethod:: drain() + + Let the write buffer of the underlying transport a chance to be flushed. + + The intended use is to write:: + + w.write(data) + yield from w.drain() + + When the size of the transport buffer reaches the high-water limit (the + protocol is paused), block until the size of the buffer is drained down + to the low-water limit and the protocol is resumed. When there is nothing + to wait for, the yield-from continues immediately. + + Yielding from :meth:`drain` gives the opportunity for the loop to + schedule the write operation and flush the buffer. It should especially + be used when a possibly large amount of data is written to the transport, + and the coroutine does not yield-from between calls to :meth:`write`. + + This method is a :ref:`coroutine <coroutine>`. + + .. method:: get_extra_info(name, default=None) + + Return optional transport information: see + :meth:`BaseTransport.get_extra_info`. + + .. method:: write(data) + + Write some *data* bytes to the transport: see + :meth:`WriteTransport.write`. + + .. method:: writelines(data) + + Write a list (or any iterable) of data bytes to the transport: + see :meth:`WriteTransport.writelines`. + + .. method:: write_eof() + + Close the write end of the transport after flushing buffered data: + see :meth:`WriteTransport.write_eof`. + + +StreamReaderProtocol +==================== + +.. class:: StreamReaderProtocol(stream_reader, client_connected_cb=None, loop=None) + + Trivial helper class to adapt between :class:`Protocol` and + :class:`StreamReader`. Sublclass of :class:`Protocol`. + + *stream_reader* is a :class:`StreamReader` instance, *client_connected_cb* + is an optional function called with (stream_reader, stream_writer) when a + connection is made, *loop* is the event loop instance to use. + + (This is a helper class instead of making :class:`StreamReader` itself a + :class:`Protocol` subclass, because the :class:`StreamReader` has other + potential uses, and to prevent the user of the :class:`StreamReader` from + accidentally calling inappropriate methods of the protocol.) + + +IncompleteReadError +=================== + +.. exception:: IncompleteReadError + + Incomplete read error, subclass of :exc:`EOFError`. + + .. attribute:: expected + + Total number of expected bytes (:class:`int`). + + .. attribute:: partial + + Read bytes string before the end of stream was reached (:class:`bytes`). + + +Stream examples +=============== + +.. _asyncio-tcp-echo-client-streams: + +TCP echo client using streams +----------------------------- + +TCP echo client using the :func:`asyncio.open_connection` function:: + + import asyncio + + @asyncio.coroutine + def tcp_echo_client(message, loop): + reader, writer = yield from asyncio.open_connection('127.0.0.1', 8888, + loop=loop) + + print('Send: %r' % message) + writer.write(message.encode()) + + data = yield from reader.read(100) + print('Received: %r' % data.decode()) + + print('Close the socket') + writer.close() + + message = 'Hello World!' + loop = asyncio.get_event_loop() + loop.run_until_complete(tcp_echo_client(message, loop)) + loop.close() + +.. seealso:: + + The :ref:`TCP echo client protocol <asyncio-tcp-echo-client-protocol>` + example uses the :meth:`BaseEventLoop.create_connection` method. + + +.. _asyncio-tcp-echo-server-streams: + +TCP echo server using streams +----------------------------- + +TCP echo server using the :func:`asyncio.start_server` function:: + + import asyncio + + @asyncio.coroutine + def handle_echo(reader, writer): + data = yield from reader.read(100) + message = data.decode() + addr = writer.get_extra_info('peername') + print("Received %r from %r" % (message, addr)) + + print("Send: %r" % message) + writer.write(data) + yield from writer.drain() + + print("Close the client socket") + writer.close() + + loop = asyncio.get_event_loop() + coro = asyncio.start_server(handle_echo, '127.0.0.1', 8888, loop=loop) + server = loop.run_until_complete(coro) + + # Serve requests until Ctrl+C is pressed + print('Serving on {}'.format(server.sockets[0].getsockname())) + try: + loop.run_forever() + except KeyboardInterrupt: + pass + + # Close the server + server.close() + loop.run_until_complete(server.wait_closed()) + loop.close() + +.. seealso:: + + The :ref:`TCP echo server protocol <asyncio-tcp-echo-server-protocol>` + example uses the :meth:`BaseEventLoop.create_server` method. + + +Get HTTP headers +---------------- + +Simple example querying HTTP headers of the URL passed on the command line:: + + import asyncio + import urllib.parse + import sys + + @asyncio.coroutine + def print_http_headers(url): + url = urllib.parse.urlsplit(url) + if url.scheme == 'https': + connect = asyncio.open_connection(url.hostname, 443, ssl=True) + else: + connect = asyncio.open_connection(url.hostname, 80) + reader, writer = yield from connect + query = ('HEAD {path} HTTP/1.0\r\n' + 'Host: {hostname}\r\n' + '\r\n').format(path=url.path or '/', hostname=url.hostname) + writer.write(query.encode('latin-1')) + while True: + line = yield from reader.readline() + if not line: + break + line = line.decode('latin1').rstrip() + if line: + print('HTTP header> %s' % line) + + # Ignore the body, close the socket + writer.close() + + url = sys.argv[1] + loop = asyncio.get_event_loop() + task = asyncio.ensure_future(print_http_headers(url)) + loop.run_until_complete(task) + loop.close() + +Usage:: + + python example.py http://example.com/path/page.html + +or with HTTPS:: + + python example.py https://example.com/path/page.html + +.. _asyncio-register-socket-streams: + +Register an open socket to wait for data using streams +------------------------------------------------------ + +Coroutine waiting until a socket receives data using the +:func:`open_connection` function:: + + import asyncio + try: + from socket import socketpair + except ImportError: + from asyncio.windows_utils import socketpair + + @asyncio.coroutine + def wait_for_data(loop): + # Create a pair of connected sockets + rsock, wsock = socketpair() + + # Register the open socket to wait for data + reader, writer = yield from asyncio.open_connection(sock=rsock, loop=loop) + + # Simulate the reception of data from the network + loop.call_soon(wsock.send, 'abc'.encode()) + + # Wait for data + data = yield from reader.read(100) + + # Got data, we are done: close the socket + print("Received:", data.decode()) + writer.close() + + # Close the second socket + wsock.close() + + loop = asyncio.get_event_loop() + loop.run_until_complete(wait_for_data(loop)) + loop.close() + +.. seealso:: + + The :ref:`register an open socket to wait for data using a protocol + <asyncio-register-socket>` example uses a low-level protocol created by the + :meth:`BaseEventLoop.create_connection` method. + + The :ref:`watch a file descriptor for read events + <asyncio-watch-read-event>` example uses the low-level + :meth:`BaseEventLoop.add_reader` method to register the file descriptor of a + socket. + diff --git a/Doc/library/asyncio-subprocess.rst b/Doc/library/asyncio-subprocess.rst new file mode 100644 index 000000000000..c0704cde2ce3 --- /dev/null +++ b/Doc/library/asyncio-subprocess.rst @@ -0,0 +1,419 @@ +.. currentmodule:: asyncio + +.. _asyncio-subprocess: + +Subprocess +========== + +Windows event loop +------------------ + +On Windows, the default event loop is :class:`SelectorEventLoop` which does not +support subprocesses. :class:`ProactorEventLoop` should be used instead. +Example to use it on Windows:: + + import asyncio, os + + if os.name == 'nt': + loop = asyncio.ProactorEventLoop() + asyncio.set_event_loop(loop) + +.. seealso:: + + :ref:`Available event loops <asyncio-event-loops>` and :ref:`Platform + support <asyncio-platform-support>`. + + +Create a subprocess: high-level API using Process +------------------------------------------------- + +.. coroutinefunction:: create_subprocess_exec(\*args, stdin=None, stdout=None, stderr=None, loop=None, limit=None, \*\*kwds) + + Create a subprocess. + + The *limit* parameter sets the buffer limit passed to the + :class:`StreamReader`. See :meth:`BaseEventLoop.subprocess_exec` for other + parameters. + + Return a :class:`~asyncio.subprocess.Process` instance. + + This function is a :ref:`coroutine <coroutine>`. + +.. coroutinefunction:: create_subprocess_shell(cmd, stdin=None, stdout=None, stderr=None, loop=None, limit=None, \*\*kwds) + + Run the shell command *cmd*. + + The *limit* parameter sets the buffer limit passed to the + :class:`StreamReader`. See :meth:`BaseEventLoop.subprocess_shell` for other + parameters. + + Return a :class:`~asyncio.subprocess.Process` instance. + + It is the application's responsibility to ensure that all whitespace and + metacharacters are quoted appropriately to avoid `shell injection + <http://en.wikipedia.org/wiki/Shell_injection#Shell_injection>`_ + vulnerabilities. The :func:`shlex.quote` function can be used to properly + escape whitespace and shell metacharacters in strings that are going to be + used to construct shell commands. + + This function is a :ref:`coroutine <coroutine>`. + +Use the :meth:`BaseEventLoop.connect_read_pipe` and +:meth:`BaseEventLoop.connect_write_pipe` methods to connect pipes. + + +Create a subprocess: low-level API using subprocess.Popen +--------------------------------------------------------- + +Run subprocesses asynchronously using the :mod:`subprocess` module. + +.. coroutinemethod:: BaseEventLoop.subprocess_exec(protocol_factory, \*args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, \*\*kwargs) + + Create a subprocess from one or more string arguments (character strings or + bytes strings encoded to the :ref:`filesystem encoding + <filesystem-encoding>`), where the first string + specifies the program to execute, and the remaining strings specify the + program's arguments. (Thus, together the string arguments form the + ``sys.argv`` value of the program, assuming it is a Python script.) This is + similar to the standard library :class:`subprocess.Popen` class called with + shell=False and the list of strings passed as the first argument; + however, where :class:`~subprocess.Popen` takes a single argument which is + list of strings, :func:`subprocess_exec` takes multiple string arguments. + + The *protocol_factory* must instanciate a subclass of the + :class:`asyncio.SubprocessProtocol` class. + + Other parameters: + + * *stdin*: Either a file-like object representing the pipe to be connected + to the subprocess's standard input stream using + :meth:`~BaseEventLoop.connect_write_pipe`, or the constant + :const:`subprocess.PIPE` (the default). By default a new pipe will be + created and connected. + + * *stdout*: Either a file-like object representing the pipe to be connected + to the subprocess's standard output stream using + :meth:`~BaseEventLoop.connect_read_pipe`, or the constant + :const:`subprocess.PIPE` (the default). By default a new pipe will be + created and connected. + + * *stderr*: Either a file-like object representing the pipe to be connected + to the subprocess's standard error stream using + :meth:`~BaseEventLoop.connect_read_pipe`, or one of the constants + :const:`subprocess.PIPE` (the default) or :const:`subprocess.STDOUT`. + By default a new pipe will be created and connected. When + :const:`subprocess.STDOUT` is specified, the subprocess's standard error + stream will be connected to the same pipe as the standard output stream. + + * All other keyword arguments are passed to :class:`subprocess.Popen` + without interpretation, except for *bufsize*, *universal_newlines* and + *shell*, which should not be specified at all. + + Returns a pair of ``(transport, protocol)``, where *transport* is an + instance of :class:`BaseSubprocessTransport`. + + This method is a :ref:`coroutine <coroutine>`. + + See the constructor of the :class:`subprocess.Popen` class for parameters. + +.. coroutinemethod:: BaseEventLoop.subprocess_shell(protocol_factory, cmd, \*, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, \*\*kwargs) + + Create a subprocess from *cmd*, which is a character string or a bytes + string encoded to the :ref:`filesystem encoding <filesystem-encoding>`, + using the platform's "shell" syntax. This is similar to the standard library + :class:`subprocess.Popen` class called with ``shell=True``. + + The *protocol_factory* must instanciate a subclass of the + :class:`asyncio.SubprocessProtocol` class. + + See :meth:`~BaseEventLoop.subprocess_exec` for more details about + the remaining arguments. + + Returns a pair of ``(transport, protocol)``, where *transport* is an + instance of :class:`BaseSubprocessTransport`. + + It is the application's responsibility to ensure that all whitespace and + metacharacters are quoted appropriately to avoid `shell injection + <http://en.wikipedia.org/wiki/Shell_injection#Shell_injection>`_ + vulnerabilities. The :func:`shlex.quote` function can be used to properly + escape whitespace and shell metacharacters in strings that are going to be + used to construct shell commands. + + This method is a :ref:`coroutine <coroutine>`. + +.. seealso:: + + The :meth:`BaseEventLoop.connect_read_pipe` and + :meth:`BaseEventLoop.connect_write_pipe` methods. + + +Constants +--------- + +.. data:: asyncio.subprocess.PIPE + + Special value that can be used as the *stdin*, *stdout* or *stderr* argument + to :func:`create_subprocess_shell` and :func:`create_subprocess_exec` and + indicates that a pipe to the standard stream should be opened. + +.. data:: asyncio.subprocess.STDOUT + + Special value that can be used as the *stderr* argument to + :func:`create_subprocess_shell` and :func:`create_subprocess_exec` and + indicates that standard error should go into the same handle as standard + output. + +.. data:: asyncio.subprocess.DEVNULL + + Special value that can be used as the *stdin*, *stdout* or *stderr* argument + to :func:`create_subprocess_shell` and :func:`create_subprocess_exec` and + indicates that the special file :data:`os.devnull` will be used. + + +Process +------- + +.. class:: asyncio.subprocess.Process + + A subprocess created by the :func:`create_subprocess_exec` or the + :func:`create_subprocess_shell` function. + + The API of the :class:`~asyncio.subprocess.Process` class was designed to be + close to the API of the :class:`subprocess.Popen` class, but there are some + differences: + + * There is no explicit :meth:`~subprocess.Popen.poll` method + * The :meth:`~subprocess.Popen.communicate` and + :meth:`~subprocess.Popen.wait` methods don't take a *timeout* parameter: + use the :func:`wait_for` function + * The *universal_newlines* parameter is not supported (only bytes strings + are supported) + * The :meth:`~asyncio.subprocess.Process.wait` method of + the :class:`~asyncio.subprocess.Process` class is asynchronous whereas the + :meth:`~subprocess.Popen.wait` method of the :class:`~subprocess.Popen` + class is implemented as a busy loop. + + This class is :ref:`not thread safe <asyncio-multithreading>`. See also the + :ref:`Subprocess and threads <asyncio-subprocess-threads>` section. + + .. coroutinemethod:: wait() + + Wait for child process to terminate. Set and return :attr:`returncode` + attribute. + + This method is a :ref:`coroutine <coroutine>`. + + .. note:: + + This will deadlock when using ``stdout=PIPE`` or ``stderr=PIPE`` and + the child process generates enough output to a pipe such that it + blocks waiting for the OS pipe buffer to accept more data. Use the + :meth:`communicate` method when using pipes to avoid that. + + .. coroutinemethod:: communicate(input=None) + + Interact with process: Send data to stdin. Read data from stdout and + stderr, until end-of-file is reached. Wait for process to terminate. + The optional *input* argument should be data to be sent to the child + process, or ``None``, if no data should be sent to the child. The type + of *input* must be bytes. + + :meth:`communicate` returns a tuple ``(stdout_data, stderr_data)``. + + If a :exc:`BrokenPipeError` or :exc:`ConnectionResetError` exception is + raised when writing *input* into stdin, the exception is ignored. It + occurs when the process exits before all data are written into stdin. + + Note that if you want to send data to the process's stdin, you need to + create the Process object with ``stdin=PIPE``. Similarly, to get anything + other than ``None`` in the result tuple, you need to give ``stdout=PIPE`` + and/or ``stderr=PIPE`` too. + + This method is a :ref:`coroutine <coroutine>`. + + .. note:: + + The data read is buffered in memory, so do not use this method if the + data size is large or unlimited. + + .. versionchanged:: 3.4.2 + The method now ignores :exc:`BrokenPipeError` and + :exc:`ConnectionResetError`. + + .. method:: send_signal(signal) + + Sends the signal *signal* to the child process. + + .. note:: + + On Windows, :py:data:`SIGTERM` is an alias for :meth:`terminate`. + ``CTRL_C_EVENT`` and ``CTRL_BREAK_EVENT`` can be sent to processes + started with a *creationflags* parameter which includes + ``CREATE_NEW_PROCESS_GROUP``. + + .. method:: terminate() + + Stop the child. On Posix OSs the method sends :py:data:`signal.SIGTERM` + to the child. On Windows the Win32 API function + :c:func:`TerminateProcess` is called to stop the child. + + .. method:: kill() + + Kills the child. On Posix OSs the function sends :py:data:`SIGKILL` to + the child. On Windows :meth:`kill` is an alias for :meth:`terminate`. + + .. attribute:: stdin + + Standard input stream (:class:`StreamWriter`), ``None`` if the process + was created with ``stdin=None``. + + .. attribute:: stdout + + Standard output stream (:class:`StreamReader`), ``None`` if the process + was created with ``stdout=None``. + + .. attribute:: stderr + + Standard error stream (:class:`StreamReader`), ``None`` if the process + was created with ``stderr=None``. + + .. warning:: + + Use the :meth:`communicate` method rather than :attr:`.stdin.write + <stdin>`, :attr:`.stdout.read <stdout>` or :attr:`.stderr.read <stderr>` + to avoid deadlocks due to streams pausing reading or writing and blocking + the child process. + + .. attribute:: pid + + The identifier of the process. + + Note that for processes created by the :func:`create_subprocess_shell` + function, this attribute is the process identifier of the spawned shell. + + .. attribute:: returncode + + Return code of the process when it exited. A ``None`` value indicates + that the process has not terminated yet. + + A negative value ``-N`` indicates that the child was terminated by signal + ``N`` (Unix only). + + +.. _asyncio-subprocess-threads: + +Subprocess and threads +---------------------- + +asyncio supports running subprocesses from different threads, but there +are limits: + +* An event loop must run in the main thread +* The child watcher must be instantiated in the main thread, before executing + subprocesses from other threads. Call the :func:`get_child_watcher` + function in the main thread to instantiate the child watcher. + +The :class:`asyncio.subprocess.Process` class is not thread safe. + +.. seealso:: + + The :ref:`Concurrency and multithreading in asyncio + <asyncio-multithreading>` section. + + +Subprocess examples +------------------- + +Subprocess using transport and protocol +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Example of a subprocess protocol using to get the output of a subprocess and to +wait for the subprocess exit. The subprocess is created by the +:meth:`BaseEventLoop.subprocess_exec` method:: + + import asyncio + import sys + + class DateProtocol(asyncio.SubprocessProtocol): + def __init__(self, exit_future): + self.exit_future = exit_future + self.output = bytearray() + + def pipe_data_received(self, fd, data): + self.output.extend(data) + + def process_exited(self): + self.exit_future.set_result(True) + + @asyncio.coroutine + def get_date(loop): + code = 'import datetime; print(datetime.datetime.now())' + exit_future = asyncio.Future(loop=loop) + + # Create the subprocess controlled by the protocol DateProtocol, + # redirect the standard output into a pipe + create = loop.subprocess_exec(lambda: DateProtocol(exit_future), + sys.executable, '-c', code, + stdin=None, stderr=None) + transport, protocol = yield from create + + # Wait for the subprocess exit using the process_exited() method + # of the protocol + yield from exit_future + + # Close the stdout pipe + transport.close() + + # Read the output which was collected by the pipe_data_received() + # method of the protocol + data = bytes(protocol.output) + return data.decode('ascii').rstrip() + + if sys.platform == "win32": + loop = asyncio.ProactorEventLoop() + asyncio.set_event_loop(loop) + else: + loop = asyncio.get_event_loop() + + date = loop.run_until_complete(get_date(loop)) + print("Current date: %s" % date) + loop.close() + + +Subprocess using streams +^^^^^^^^^^^^^^^^^^^^^^^^ + +Example using the :class:`~asyncio.subprocess.Process` class to control the +subprocess and the :class:`StreamReader` class to read from the standard +output. The subprocess is created by the :func:`create_subprocess_exec` +function:: + + import asyncio.subprocess + import sys + + @asyncio.coroutine + def get_date(): + code = 'import datetime; print(datetime.datetime.now())' + + # Create the subprocess, redirect the standard output into a pipe + create = asyncio.create_subprocess_exec(sys.executable, '-c', code, + stdout=asyncio.subprocess.PIPE) + proc = yield from create + + # Read one line of output + data = yield from proc.stdout.readline() + line = data.decode('ascii').rstrip() + + # Wait for the subprocess exit + yield from proc.wait() + return line + + if sys.platform == "win32": + loop = asyncio.ProactorEventLoop() + asyncio.set_event_loop(loop) + else: + loop = asyncio.get_event_loop() + + date = loop.run_until_complete(get_date()) + print("Current date: %s" % date) + loop.close() diff --git a/Doc/library/asyncio-sync.rst b/Doc/library/asyncio-sync.rst new file mode 100644 index 000000000000..ad3b523f989b --- /dev/null +++ b/Doc/library/asyncio-sync.rst @@ -0,0 +1,293 @@ +.. currentmodule:: asyncio +.. _asyncio-sync: + +Synchronization primitives +========================== + +Locks: + +* :class:`Lock` +* :class:`Event` +* :class:`Condition` + +Semaphores: + +* :class:`Semaphore` +* :class:`BoundedSemaphore` + +asyncio lock API was designed to be close to classes of the :mod:`threading` +module (:class:`~threading.Lock`, :class:`~threading.Event`, +:class:`~threading.Condition`, :class:`~threading.Semaphore`, +:class:`~threading.BoundedSemaphore`), but it has no *timeout* parameter. The +:func:`asyncio.wait_for` function can be used to cancel a task after a timeout. + +Locks +----- + +Lock +^^^^ + +.. class:: Lock(\*, loop=None) + + Primitive lock objects. + + A primitive lock is a synchronization primitive that is not owned by a + particular coroutine when locked. A primitive lock is in one of two states, + 'locked' or 'unlocked'. + + It is created in the unlocked state. It has two basic methods, :meth:`acquire` + and :meth:`release`. When the state is unlocked, acquire() changes the state to + locked and returns immediately. When the state is locked, acquire() blocks + until a call to release() in another coroutine changes it to unlocked, then + the acquire() call resets it to locked and returns. The release() method + should only be called in the locked state; it changes the state to unlocked + and returns immediately. If an attempt is made to release an unlocked lock, + a :exc:`RuntimeError` will be raised. + + When more than one coroutine is blocked in acquire() waiting for the state + to turn to unlocked, only one coroutine proceeds when a release() call + resets the state to unlocked; first coroutine which is blocked in acquire() + is being processed. + + :meth:`acquire` is a coroutine and should be called with ``yield from``. + + Locks also support the context management protocol. ``(yield from lock)`` + should be used as context manager expression. + + This class is :ref:`not thread safe <asyncio-multithreading>`. + + Usage:: + + lock = Lock() + ... + yield from lock + try: + ... + finally: + lock.release() + + Context manager usage:: + + lock = Lock() + ... + with (yield from lock): + ... + + Lock objects can be tested for locking state:: + + if not lock.locked(): + yield from lock + else: + # lock is acquired + ... + + .. method:: locked() + + Return ``True`` if the lock is acquired. + + .. coroutinemethod:: acquire() + + Acquire a lock. + + This method blocks until the lock is unlocked, then sets it to locked and + returns ``True``. + + This method is a :ref:`coroutine <coroutine>`. + + .. method:: release() + + Release a lock. + + When the lock is locked, reset it to unlocked, and return. If any other + coroutines are blocked waiting for the lock to become unlocked, allow + exactly one of them to proceed. + + When invoked on an unlocked lock, a :exc:`RuntimeError` is raised. + + There is no return value. + + +Event +^^^^^ + +.. class:: Event(\*, loop=None) + + An Event implementation, asynchronous equivalent to :class:`threading.Event`. + + Class implementing event objects. An event manages a flag that can be set to + true with the :meth:`set` method and reset to false with the :meth:`clear` + method. The :meth:`wait` method blocks until the flag is true. The flag is + initially false. + + This class is :ref:`not thread safe <asyncio-multithreading>`. + + .. method:: clear() + + Reset the internal flag to false. Subsequently, coroutines calling + :meth:`wait` will block until :meth:`set` is called to set the internal + flag to true again. + + .. method:: is_set() + + Return ``True`` if and only if the internal flag is true. + + .. method:: set() + + Set the internal flag to true. All coroutines waiting for it to become + true are awakened. Coroutine that call :meth:`wait` once the flag is true + will not block at all. + + .. coroutinemethod:: wait() + + Block until the internal flag is true. + + If the internal flag is true on entry, return ``True`` immediately. + Otherwise, block until another coroutine calls :meth:`set` to set the + flag to true, then return ``True``. + + This method is a :ref:`coroutine <coroutine>`. + + +Condition +^^^^^^^^^ + +.. class:: Condition(lock=None, \*, loop=None) + + A Condition implementation, asynchronous equivalent to + :class:`threading.Condition`. + + This class implements condition variable objects. A condition variable + allows one or more coroutines to wait until they are notified by another + coroutine. + + If the *lock* argument is given and not ``None``, it must be a :class:`Lock` + object, and it is used as the underlying lock. Otherwise, + a new :class:`Lock` object is created and used as the underlying lock. + + This class is :ref:`not thread safe <asyncio-multithreading>`. + + .. coroutinemethod:: acquire() + + Acquire the underlying lock. + + This method blocks until the lock is unlocked, then sets it to locked and + returns ``True``. + + This method is a :ref:`coroutine <coroutine>`. + + .. method:: notify(n=1) + + By default, wake up one coroutine waiting on this condition, if any. + If the calling coroutine has not acquired the lock when this method is + called, a :exc:`RuntimeError` is raised. + + This method wakes up at most *n* of the coroutines waiting for the + condition variable; it is a no-op if no coroutines are waiting. + + .. note:: + + An awakened coroutine does not actually return from its :meth:`wait` + call until it can reacquire the lock. Since :meth:`notify` does not + release the lock, its caller should. + + .. method:: locked() + + Return ``True`` if the underlying lock is acquired. + + .. method:: notify_all() + + Wake up all coroutines waiting on this condition. This method acts like + :meth:`notify`, but wakes up all waiting coroutines instead of one. If the + calling coroutine has not acquired the lock when this method is called, a + :exc:`RuntimeError` is raised. + + .. method:: release() + + Release the underlying lock. + + When the lock is locked, reset it to unlocked, and return. If any other + coroutines are blocked waiting for the lock to become unlocked, allow + exactly one of them to proceed. + + When invoked on an unlocked lock, a :exc:`RuntimeError` is raised. + + There is no return value. + + .. coroutinemethod:: wait() + + Wait until notified. + + If the calling coroutine has not acquired the lock when this method is + called, a :exc:`RuntimeError` is raised. + + This method releases the underlying lock, and then blocks until it is + awakened by a :meth:`notify` or :meth:`notify_all` call for the same + condition variable in another coroutine. Once awakened, it re-acquires + the lock and returns ``True``. + + This method is a :ref:`coroutine <coroutine>`. + + .. coroutinemethod:: wait_for(predicate) + + Wait until a predicate becomes true. + + The predicate should be a callable which result will be interpreted as a + boolean value. The final predicate value is the return value. + + This method is a :ref:`coroutine <coroutine>`. + + +Semaphores +---------- + +Semaphore +^^^^^^^^^ + +.. class:: Semaphore(value=1, \*, loop=None) + + A Semaphore implementation. + + A semaphore manages an internal counter which is decremented by each + :meth:`acquire` call and incremented by each :meth:`release` call. The + counter can never go below zero; when :meth:`acquire` finds that it is zero, + it blocks, waiting until some other coroutine calls :meth:`release`. + + Semaphores also support the context management protocol. + + The optional argument gives the initial value for the internal counter; it + defaults to ``1``. If the value given is less than ``0``, :exc:`ValueError` + is raised. + + This class is :ref:`not thread safe <asyncio-multithreading>`. + + .. coroutinemethod:: acquire() + + Acquire a semaphore. + + If the internal counter is larger than zero on entry, decrement it by one + and return ``True`` immediately. If it is zero on entry, block, waiting + until some other coroutine has called :meth:`release` to make it larger + than ``0``, and then return ``True``. + + This method is a :ref:`coroutine <coroutine>`. + + .. method:: locked() + + Returns ``True`` if semaphore can not be acquired immediately. + + .. method:: release() + + Release a semaphore, incrementing the internal counter by one. When it + was zero on entry and another coroutine is waiting for it to become + larger than zero again, wake up that coroutine. + + +BoundedSemaphore +^^^^^^^^^^^^^^^^ + +.. class:: BoundedSemaphore(value=1, \*, loop=None) + + A bounded semaphore implementation. Inherit from :class:`Semaphore`. + + This raises :exc:`ValueError` in :meth:`~Semaphore.release` if it would + increase the value above the initial value. diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst new file mode 100644 index 000000000000..08c5873d8bd7 --- /dev/null +++ b/Doc/library/asyncio-task.rst @@ -0,0 +1,724 @@ +.. currentmodule:: asyncio + +Tasks and coroutines +==================== + +.. _coroutine: + +Coroutines +---------- + +Coroutines used with :mod:`asyncio` may be implemented using the +:keyword:`async def` statement, or by using :term:`generators <generator>`. +The :keyword:`async def` type of coroutine was added in Python 3.5, and +is recommended if there is no need to support older Python versions. + +Generator-based coroutines should be decorated with :func:`@asyncio.coroutine +<asyncio.coroutine>`, although this is not strictly enforced. +The decorator enables compatibility with :keyword:`async def` coroutines, +and also serves as documentation. Generator-based +coroutines use the ``yield from`` syntax introduced in :pep:`380`, +instead of the original ``yield`` syntax. + +The word "coroutine", like the word "generator", is used for two +different (though related) concepts: + +- The function that defines a coroutine + (a function definition using :keyword:`async def` or + decorated with ``@asyncio.coroutine``). If disambiguation is needed + we will call this a *coroutine function* (:func:`iscoroutinefunction` + returns ``True``). + +- The object obtained by calling a coroutine function. This object + represents a computation or an I/O operation (usually a combination) + that will complete eventually. If disambiguation is needed we will + call it a *coroutine object* (:func:`iscoroutine` returns ``True``). + +Things a coroutine can do: + +- ``result = await future`` or ``result = yield from future`` -- + suspends the coroutine until the + future is done, then returns the future's result, or raises an + exception, which will be propagated. (If the future is cancelled, + it will raise a ``CancelledError`` exception.) Note that tasks are + futures, and everything said about futures also applies to tasks. + +- ``result = await coroutine`` or ``result = yield from coroutine`` -- + wait for another coroutine to + produce a result (or raise an exception, which will be propagated). + The ``coroutine`` expression must be a *call* to another coroutine. + +- ``return expression`` -- produce a result to the coroutine that is + waiting for this one using :keyword:`await` or ``yield from``. + +- ``raise exception`` -- raise an exception in the coroutine that is + waiting for this one using :keyword:`await` or ``yield from``. + +Calling a coroutine does not start its code running -- +the coroutine object returned by the call doesn't do anything until you +schedule its execution. There are two basic ways to start it running: +call ``await coroutine`` or ``yield from coroutine`` from another coroutine +(assuming the other coroutine is already running!), or schedule its execution +using the :func:`ensure_future` function or the :meth:`BaseEventLoop.create_task` +method. + + +Coroutines (and tasks) can only run when the event loop is running. + +.. decorator:: coroutine + + Decorator to mark generator-based coroutines. This enables + the generator use :keyword:`!yield from` to call :keyword:`async + def` coroutines, and also enables the generator to be called by + :keyword:`async def` coroutines, for instance using an + :keyword:`await` expression. + + There is no need to decorate :keyword:`async def` coroutines themselves. + + If the generator is not yielded from before it is destroyed, an error + message is logged. See :ref:`Detect coroutines never scheduled + <asyncio-coroutine-not-scheduled>`. + +.. note:: + + In this documentation, some methods are documented as coroutines, + even if they are plain Python functions returning a :class:`Future`. + This is intentional to have a freedom of tweaking the implementation + of these functions in the future. If such a function is needed to be + used in a callback-style code, wrap its result with :func:`ensure_future`. + + +.. _asyncio-hello-world-coroutine: + +Example: Hello World coroutine +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Example of coroutine displaying ``"Hello World"``:: + + import asyncio + + async def hello_world(): + print("Hello World!") + + loop = asyncio.get_event_loop() + # Blocking call which returns when the hello_world() coroutine is done + loop.run_until_complete(hello_world()) + loop.close() + +.. seealso:: + + The :ref:`Hello World with call_soon() <asyncio-hello-world-callback>` + example uses the :meth:`BaseEventLoop.call_soon` method to schedule a + callback. + + +.. _asyncio-date-coroutine: + +Example: Coroutine displaying the current date +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Example of coroutine displaying the current date every second during 5 seconds +using the :meth:`sleep` function:: + + import asyncio + import datetime + + async def display_date(loop): + end_time = loop.time() + 5.0 + while True: + print(datetime.datetime.now()) + if (loop.time() + 1.0) >= end_time: + break + await asyncio.sleep(1) + + loop = asyncio.get_event_loop() + # Blocking call which returns when the display_date() coroutine is done + loop.run_until_complete(display_date(loop)) + loop.close() + +The same coroutine implemented using a generator:: + + @asyncio.coroutine + def display_date(loop): + end_time = loop.time() + 5.0 + while True: + print(datetime.datetime.now()) + if (loop.time() + 1.0) >= end_time: + break + yield from asyncio.sleep(1) + +.. seealso:: + + The :ref:`display the current date with call_later() + <asyncio-date-callback>` example uses a callback with the + :meth:`BaseEventLoop.call_later` method. + + +Example: Chain coroutines +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Example chaining coroutines:: + + import asyncio + + async def compute(x, y): + print("Compute %s + %s ..." % (x, y)) + await asyncio.sleep(1.0) + return x + y + + async def print_sum(x, y): + result = await compute(x, y) + print("%s + %s = %s" % (x, y, result)) + + loop = asyncio.get_event_loop() + loop.run_until_complete(print_sum(1, 2)) + loop.close() + +``compute()`` is chained to ``print_sum()``: ``print_sum()`` coroutine waits +until ``compute()`` is completed before returning its result. + +Sequence diagram of the example: + +.. image:: tulip_coro.png + :align: center + +The "Task" is created by the :meth:`BaseEventLoop.run_until_complete` method +when it gets a coroutine object instead of a task. + +The diagram shows the control flow, it does not describe exactly how things +work internally. For example, the sleep coroutine creates an internal future +which uses :meth:`BaseEventLoop.call_later` to wake up the task in 1 second. + + +InvalidStateError +----------------- + +.. exception:: InvalidStateError + + The operation is not allowed in this state. + + +TimeoutError +------------ + +.. exception:: TimeoutError + + The operation exceeded the given deadline. + +.. note:: + + This exception is different from the builtin :exc:`TimeoutError` exception! + + +Future +------ + +.. class:: Future(\*, loop=None) + + This class is *almost* compatible with :class:`concurrent.futures.Future`. + + Differences: + + - :meth:`result` and :meth:`exception` do not take a timeout argument and + raise an exception when the future isn't done yet. + + - Callbacks registered with :meth:`add_done_callback` are always called + via the event loop's :meth:`~BaseEventLoop.call_soon_threadsafe`. + + - This class is not compatible with the :func:`~concurrent.futures.wait` and + :func:`~concurrent.futures.as_completed` functions in the + :mod:`concurrent.futures` package. + + This class is :ref:`not thread safe <asyncio-multithreading>`. + + .. method:: 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``. + + .. method:: cancelled() + + Return ``True`` if the future was cancelled. + + .. method:: done() + + Return True if the future is done. + + Done means either that a result / exception are available, or that the + future was cancelled. + + .. method:: result() + + Return the result this future represents. + + If the future has been cancelled, raises :exc:`CancelledError`. If the + future's result isn't yet available, raises :exc:`InvalidStateError`. If + the future is done and has an exception set, this exception is raised. + + .. method:: 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 + :exc:`CancelledError`. If the future isn't done yet, raises + :exc:`InvalidStateError`. + + .. method:: add_done_callback(fn) + + 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 :meth:`~BaseEventLoop.call_soon`. + + :ref:`Use functools.partial to pass parameters to the callback + <asyncio-pass-keywords>`. For example, + ``fut.add_done_callback(functools.partial(print, "Future:", + flush=True))`` will call ``print("Future:", fut, flush=True)``. + + .. method:: remove_done_callback(fn) + + Remove all instances of a callback from the "call when done" list. + + Returns the number of callbacks removed. + + .. method:: set_result(result) + + Mark the future done and set its result. + + If the future is already done when this method is called, raises + :exc:`InvalidStateError`. + + .. method:: set_exception(exception) + + Mark the future done and set an exception. + + If the future is already done when this method is called, raises + :exc:`InvalidStateError`. + + +Example: Future with run_until_complete() +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Example combining a :class:`Future` and a :ref:`coroutine function +<coroutine>`:: + + import asyncio + + @asyncio.coroutine + def slow_operation(future): + yield from asyncio.sleep(1) + future.set_result('Future is done!') + + loop = asyncio.get_event_loop() + future = asyncio.Future() + asyncio.ensure_future(slow_operation(future)) + loop.run_until_complete(future) + print(future.result()) + loop.close() + +The coroutine function is responsible for the computation (which takes 1 second) +and it stores the result into the future. The +:meth:`~BaseEventLoop.run_until_complete` method waits for the completion of +the future. + +.. note:: + The :meth:`~BaseEventLoop.run_until_complete` method uses internally the + :meth:`~Future.add_done_callback` method to be notified when the future is + done. + + +Example: Future with run_forever() +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The previous example can be written differently using the +:meth:`Future.add_done_callback` method to describe explicitly the control +flow:: + + import asyncio + + @asyncio.coroutine + def slow_operation(future): + yield from asyncio.sleep(1) + future.set_result('Future is done!') + + def got_result(future): + print(future.result()) + loop.stop() + + loop = asyncio.get_event_loop() + future = asyncio.Future() + asyncio.ensure_future(slow_operation(future)) + future.add_done_callback(got_result) + try: + loop.run_forever() + finally: + loop.close() + +In this example, the future is used to link ``slow_operation()`` to +``got_result()``: when ``slow_operation()`` is done, ``got_result()`` is called +with the result. + + +Task +---- + +.. class:: Task(coro, \*, loop=None) + + Schedule the execution of a :ref:`coroutine <coroutine>`: wrap it in a + future. A task is a subclass of :class:`Future`. + + A task is responsible for executing a coroutine object in an event loop. If + the wrapped coroutine yields from a future, the task suspends the execution + of the wrapped coroutine and waits for the completition of the future. When + the future is done, the execution of the wrapped coroutine restarts with the + result or the exception of the future. + + Event loops use cooperative scheduling: an event loop only runs one task at + a time. Other tasks may run in parallel if other event loops are + running in different threads. While a task waits for the completion of a + future, the event loop executes a new task. + + The cancellation of a task is different from the cancelation of a future. Calling + :meth:`cancel` will throw a :exc:`~concurrent.futures.CancelledError` to the + wrapped coroutine. :meth:`~Future.cancelled` only returns ``True`` if the + wrapped coroutine did not catch the + :exc:`~concurrent.futures.CancelledError` exception, or raised a + :exc:`~concurrent.futures.CancelledError` exception. + + If a pending task is destroyed, the execution of its wrapped :ref:`coroutine + <coroutine>` did not complete. It is probably a bug and a warning is + logged: see :ref:`Pending task destroyed <asyncio-pending-task-destroyed>`. + + Don't directly create :class:`Task` instances: use the :func:`ensure_future` + function or the :meth:`BaseEventLoop.create_task` method. + + This class is :ref:`not thread safe <asyncio-multithreading>`. + + .. classmethod:: all_tasks(loop=None) + + Return a set of all tasks for an event loop. + + By default all tasks for the current event loop are returned. + + .. classmethod:: current_task(loop=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 :class:`Task`. + + .. method:: cancel() + + Request that this task cancel itself. + + This arranges for a :exc:`~concurrent.futures.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 :meth:`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, :meth:`~Future.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 + :exc:`~concurrent.futures.CancelledError` exception (even if + :meth:`cancel` was not called). + + .. method:: get_stack(\*, limit=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. + + .. method:: print_stack(\*, limit=None, file=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. + + +Example: Parallel execution of tasks +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Example executing 3 tasks (A, B, C) in parallel:: + + import asyncio + + @asyncio.coroutine + def factorial(name, number): + f = 1 + for i in range(2, number+1): + print("Task %s: Compute factorial(%s)..." % (name, i)) + yield from asyncio.sleep(1) + f *= i + print("Task %s: factorial(%s) = %s" % (name, number, f)) + + loop = asyncio.get_event_loop() + tasks = [ + asyncio.ensure_future(factorial("A", 2)), + asyncio.ensure_future(factorial("B", 3)), + asyncio.ensure_future(factorial("C", 4))] + loop.run_until_complete(asyncio.wait(tasks)) + loop.close() + +Output:: + + Task A: Compute factorial(2)... + Task B: Compute factorial(2)... + Task C: Compute factorial(2)... + Task A: factorial(2) = 2 + Task B: Compute factorial(3)... + Task C: Compute factorial(3)... + Task B: factorial(3) = 6 + Task C: Compute factorial(4)... + Task C: factorial(4) = 24 + +A task is automatically scheduled for execution when it is created. The event +loop stops when all tasks are done. + + +Task functions +-------------- + +.. note:: + + In the functions below, the optional *loop* argument allows to explicitly set + the event loop object used by the underlying task or coroutine. If it's + not provided, the default event loop is used. + +.. function:: as_completed(fs, \*, loop=None, timeout=None) + + Return an iterator whose values, when waited for, are :class:`Future` + instances. + + Raises :exc:`asyncio.TimeoutError` if the timeout occurs before all Futures + are done. + + Example:: + + for f in as_completed(fs): + result = yield from f # The 'yield from' may raise + # Use result + + .. note:: + + The futures ``f`` are not necessarily members of fs. + +.. function:: ensure_future(coro_or_future, \*, loop=None) + + Schedule the execution of a :ref:`coroutine object <coroutine>`: wrap it in + a future. Return a :class:`Task` object. + + If the argument is a :class:`Future`, it is returned directly. + + .. versionadded:: 3.4.4 + + .. seealso:: + + The :meth:`BaseEventLoop.create_task` method. + +.. function:: async(coro_or_future, \*, loop=None) + + A deprecated alias to :func:`ensure_future`. + + .. deprecated:: 3.4.4 + +.. function:: gather(\*coros_or_futures, loop=None, return_exceptions=False) + + Return a future aggregating results from the given coroutine objects or + futures. + + All futures must share the same event loop. If all the tasks are done + successfully, the returned future's result is the list of results (in the + order of the original sequence, not necessarily the order of results + arrival). If *return_exceptions* is True, exceptions in the tasks are + treated the same as successful results, and gathered in the result list; + otherwise, the first raised exception will be immediately propagated to the + returned future. + + Cancellation: if the outer Future is cancelled, all children (that have not + completed yet) are also cancelled. If any child is cancelled, this is + treated as if it raised :exc:`~concurrent.futures.CancelledError` -- the + outer Future is *not* cancelled in this case. (This is to prevent the + cancellation of one child to cause other children to be cancelled.) + +.. function:: iscoroutine(obj) + + Return ``True`` if *obj* is a :ref:`coroutine object <coroutine>`, + which may be based on a generator or an :keyword:`async def` coroutine. + +.. function:: iscoroutinefunction(func) + + Return ``True`` if *func* is determined to be a :ref:`coroutine function + <coroutine>`, which may be a decorated generator function or an + :keyword:`async def` function. + +.. coroutinefunction:: sleep(delay, result=None, \*, loop=None) + + Create a :ref:`coroutine <coroutine>` that completes after a given + time (in seconds). If *result* is provided, it is produced to the caller + when the coroutine completes. + + The resolution of the sleep depends on the :ref:`granularity of the event + loop <asyncio-delayed-calls>`. + + This function is a :ref:`coroutine <coroutine>`. + +.. function:: shield(arg, \*, loop=None) + + Wait for a future, shielding it from cancellation. + + The statement:: + + res = yield from shield(something()) + + is exactly equivalent to the statement:: + + res = yield from something() + + *except* that if the coroutine containing it is cancelled, the task running + in ``something()`` is not cancelled. From the point of view of + ``something()``, the cancellation did not happen. But its caller is still + cancelled, so the yield-from expression still raises + :exc:`~concurrent.futures.CancelledError`. Note: If ``something()`` is + cancelled by other means this will still cancel ``shield()``. + + If you want to completely ignore cancellation (not recommended) you can + combine ``shield()`` with a try/except clause, as follows:: + + try: + res = yield from shield(something()) + except CancelledError: + res = None + +.. coroutinefunction:: wait(futures, \*, loop=None, timeout=None, return_when=ALL_COMPLETED) + + Wait for the Futures and coroutine objects given by the sequence *futures* + to complete. Coroutines will be wrapped in Tasks. Returns two sets of + :class:`Future`: (done, pending). + + The sequence *futures* must not be empty. + + *timeout* can be used to control the maximum number of seconds to wait before + returning. *timeout* can be an int or float. If *timeout* is not specified + or ``None``, there is no limit to the wait time. + + *return_when* indicates when this function should return. It must be one of + the following constants of the :mod:`concurrent.futures` module: + + .. tabularcolumns:: |l|L| + + +-----------------------------+----------------------------------------+ + | Constant | Description | + +=============================+========================================+ + | :const:`FIRST_COMPLETED` | The function will return when any | + | | future finishes or is cancelled. | + +-----------------------------+----------------------------------------+ + | :const:`FIRST_EXCEPTION` | The function will return when any | + | | future finishes by raising an | + | | exception. If no future raises an | + | | exception then it is equivalent to | + | | :const:`ALL_COMPLETED`. | + +-----------------------------+----------------------------------------+ + | :const:`ALL_COMPLETED` | The function will return when all | + | | futures finish or are cancelled. | + +-----------------------------+----------------------------------------+ + + This function is a :ref:`coroutine <coroutine>`. + + Usage:: + + done, pending = yield from asyncio.wait(fs) + + .. note:: + + This does not raise :exc:`asyncio.TimeoutError`! Futures that aren't done + when the timeout occurs are returned in the second set. + + +.. coroutinefunction:: wait_for(fut, timeout, \*, loop=None) + + Wait for the single :class:`Future` or :ref:`coroutine object <coroutine>` + to complete with timeout. If *timeout* is ``None``, block until the future + completes. + + Coroutine will be wrapped in :class:`Task`. + + Returns result of the Future or coroutine. When a timeout occurs, it + cancels the task and raises :exc:`asyncio.TimeoutError`. To avoid the task + cancellation, wrap it in :func:`shield`. + + If the wait is cancelled, the future *fut* is also cancelled. + + This function is a :ref:`coroutine <coroutine>`, usage:: + + result = yield from asyncio.wait_for(fut, 60.0) + + .. versionchanged:: 3.4.3 + If the wait is cancelled, the future *fut* is now also cancelled. + + +.. function:: run_coroutine_threadsafe(coro, loop) + + Submit a :ref:`coroutine object <coroutine>` to a given event loop. + + Return a :class:`concurrent.futures.Future` to access the result. + + This function is meant to be called from a different thread than the one + where the event loop is running. Usage:: + + # Create a coroutine + coro = asyncio.sleep(1, result=3) + # Submit the coroutine to a given loop + future = asyncio.run_coroutine_threadsafe(coro, loop) + # Wait for the result with an optional timeout argument + assert future.result(timeout) == 3 + + If an exception is raised in the coroutine, the returned future will be + notified. It can also be used to cancel the task in the event loop:: + + try: + result = future.result(timeout) + except asyncio.TimeoutError: + print('The coroutine took too long, cancelling the task...') + future.cancel() + except Exception as exc: + print('The coroutine raised an exception: {!r}'.format(exc)) + else: + print('The coroutine returned: {!r}'.format(result)) + + See the :ref:`concurrency and multithreading <asyncio-multithreading>` + section of the documentation. + + .. note:: + + Unlike the functions above, :func:`run_coroutine_threadsafe` requires the + *loop* argument to be passed explicitely. + + .. versionadded:: 3.4.4 diff --git a/Doc/library/asyncio.rst b/Doc/library/asyncio.rst index 1b8d701ccb30..9b4d65e5da0f 100644 --- a/Doc/library/asyncio.rst +++ b/Doc/library/asyncio.rst @@ -4,6 +4,13 @@ .. module:: asyncio :synopsis: Asynchronous I/O, event loop, coroutines and tasks. +.. note:: + + The asyncio package has been included in the standard library on a + :term:`provisional basis <provisional package>`. Backwards incompatible + changes (up to and including removal of the module) may occur if deemed + necessary by the core developers. + .. versionadded:: 3.4 **Source code:** :source:`Lib/asyncio/` @@ -13,1289 +20,54 @@ This module provides infrastructure for writing single-threaded concurrent code using coroutines, multiplexing I/O access over sockets and other resources, running network clients and servers, and other related primitives. - Here is a more detailed list of the package contents: -* a pluggable :ref:`event loop <event-loop>` with various system-specific +* a pluggable :ref:`event loop <asyncio-event-loop>` with various system-specific implementations; -* :ref:`transport <transport>` and :ref:`protocol <protocol>` abstractions - (similar to those in `Twisted <http://twistedmatrix.com/>`_); +* :ref:`transport <asyncio-transport>` and :ref:`protocol <asyncio-protocol>` abstractions + (similar to those in `Twisted <https://twistedmatrix.com/trac/>`_); * concrete support for TCP, UDP, SSL, subprocess pipes, delayed calls, and others (some may be system-dependent); -* a Future class that mimicks the one in the :mod:`concurrent.futures` module, - but adapted for use with the event loop; +* a :class:`Future` class that mimics the one in the :mod:`concurrent.futures` + module, but adapted for use with the event loop; * coroutines and tasks based on ``yield from`` (:PEP:`380`), to help write concurrent code in a sequential fashion; -* cancellation support for Futures and coroutines; +* cancellation support for :class:`Future`\s and coroutines; -* :ref:`synchronization primitives <sync>` for use between coroutines in +* :ref:`synchronization primitives <asyncio-sync>` for use between coroutines in a single thread, mimicking those in the :mod:`threading` module; * an interface for passing work off to a threadpool, for times when you absolutely, positively have to use a library that makes blocking I/O calls. +Asynchronous programming is more complex than classical "sequential" +programming: see the :ref:`Develop with asyncio <asyncio-dev>` page which lists +common traps and explains how to avoid them. :ref:`Enable the debug mode +<asyncio-debug-mode>` during development to detect common issues. -Disclaimer ----------- - -Full documentation is not yet ready; we hope to have it written -before Python 3.4 leaves beta. Until then, the best reference is -:PEP:`3156`. For a motivational primer on transports and protocols, -see :PEP:`3153`. - - -.. XXX should the asyncio documentation come in several pages, as for logging? - - -.. _event-loop: - -Event loops ------------ - -The event loop is the central execution device provided by :mod:`asyncio`. -It provides multiple facilities, amongst which: - -* Registering, executing and cancelling delayed calls (timeouts) - -* Creating client and server :ref:`transports <transport>` for various - kinds of communication - -* Launching subprocesses and the associated :ref:`transports <transport>` - for communication with an external program - -* Delegating costly function calls to a pool of threads - -Getting an event loop -^^^^^^^^^^^^^^^^^^^^^ - -The easiest way to get an event loop is to call the :func:`get_event_loop` -function. - -.. function:: get_event_loop() - - Get the event loop for current context. Returns an event loop object - implementing :class:`BaseEventLoop` interface, or raises an exception in case no - event loop has been set for the current context and the current policy does - not specify to create one. It should never return ``None``. - - -Run an event loop -^^^^^^^^^^^^^^^^^ - -.. method:: BaseEventLoop.run_forever() - - Run until :meth:`stop` is called. - -.. method:: BaseEventLoop.run_until_complete(future) - - Run until the :class:`Future` is done. - - If the argument is a coroutine, it is wrapped in a :class:`Task`. - - Return the Future's result, or raise its exception. - -.. method:: BaseEventLoop.is_running() - - Returns running status of event loop. - -.. method:: stop() - - Stop running the event loop. - - Every callback scheduled before :meth:`stop` is called will run. - Callback scheduled after :meth:`stop` is called won't. However, those - callbacks will run if :meth:`run_forever` is called again later. - -.. method:: BaseEventLoop.close() - - Close the event loop. - - This clears the queues and shuts down the executor, but does not wait for - the executor to finish. - - -Calls -^^^^^ - -.. method:: BaseEventLoop.call_soon(callback, \*args) - - Arrange for a callback to be called as soon as possible. - - This operates as a FIFO queue, callbacks are called in the order in - which they are registered. Each callback will be called exactly once. - - Any positional arguments after the callback will be passed to the - callback when it is called. - -.. method:: BaseEventLoop.call_soon_threadsafe(callback, \*args) - - Like :meth:`call_soon`, but thread safe. - - -Delayed calls -^^^^^^^^^^^^^ - -The event loop has its own internal clock for computing timeouts. -Which clock is used depends on the (platform-specific) event loop -implementation; ideally it is a monotonic clock. This will generally be -a different clock than :func:`time.time`. - -.. method:: BaseEventLoop.call_later(delay, callback, *args) - - Arrange for the *callback* to be called after the given *delay* - seconds (either an int or float). - - A "handle" is returned: an opaque object with a :meth:`cancel` method - that can be used to cancel the call. - - *callback* will be called exactly once per call to :meth:`call_later`. - If two callbacks are scheduled for exactly the same time, it is - undefined which will be called first. - - The optional positional *args* will be passed to the callback when it - is called. If you want the callback to be called with some named - arguments, use a closure or :func:`functools.partial`. - -.. method:: BaseEventLoop.call_at(when, callback, *args) - - Arrange for the *callback* to be called at the given absolute timestamp - *when* (an int or float), using the same time reference as :meth:`time`. - - This method's behavior is the same as :meth:`call_later`. - -.. method:: BaseEventLoop.time() - - Return the current time, as a :class:`float` value, according to the - event loop's internal clock. - - -Executor -^^^^^^^^ - -Call a function in an :class:`~concurrent.futures.Executor` (pool of threads or -pool of processes). By default, an event loop uses a thread pool executor -(:class:`~concurrent.futures.ThreadPoolExecutor`). - -.. method:: BaseEventLoop.run_in_executor(executor, callback, \*args) - - Arrange for a callback to be called in the specified executor. - - *executor* is a :class:`~concurrent.futures.Executor` instance, - the default executor is used if *executor* is ``None``. - -.. method:: BaseEventLoop.set_default_executor(executor) - - Set the default executor used by :meth:`run_in_executor`. - - -Creating listening connections -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. method:: BaseEventLoop.create_server(protocol_factory, host=None, port=None, \*, family=socket.AF_UNSPEC, flags=socket.AI_PASSIVE, sock=None, backlog=100, ssl=None, reuse_address=None) - - XXX - - * *protocol_factory* - * *host*, *port* - * *family* - * *flags* - * *sock* - * *backlog* : the maximum number of queued connections and should be at - least ``0``; the maximum value is system-dependent (usually ``5``), - the minimum value is forced to ``0``. - * *ssl*: ``True`` or :class:`ssl.SSLContext` - * *reuse_address*: if ``True``, set :data:`socket.SO_REUSEADDR` option - on the listening socket. Default value: ``True`` on POSIX systems, - ``False`` on Windows. - - This method returns a :ref:`coroutine <coroutine>`. - -.. method:: BaseEventLoop.create_datagram_endpoint(protocol_factory, local_addr=None, remote_addr=None, \*, family=0, proto=0, flags=0) - - XXX - - This method returns a :ref:`coroutine <coroutine>`. - - - -Creating connections -^^^^^^^^^^^^^^^^^^^^ - -.. method:: BaseEventLoop.create_connection(protocol_factory, host=None, port=None, **options) - - Create a streaming transport connection to a given Internet *host* and - *port*. *protocol_factory* must be a callable returning a - :ref:`protocol <protocol>` instance. - - This method returns a :ref:`coroutine <coroutine>` which will try to - establish the connection in the background. When successful, the - coroutine returns a ``(transport, protocol)`` pair. - - The chronological synopsis of the underlying operation is as follows: - - #. The connection is established, and a :ref:`transport <transport>` - is created to represent it. - - #. *protocol_factory* is called without arguments and must return a - :ref:`protocol <protocol>` instance. - - #. The protocol instance is tied to the transport, and its - :meth:`connection_made` method is called. - - #. The coroutine returns successfully with the ``(transport, protocol)`` - pair. - - The created transport is an implementation-dependent bidirectional stream. - - .. note:: - *protocol_factory* can be any kind of callable, not necessarily - a class. For example, if you want to use a pre-created - protocol instance, you can pass ``lambda: my_protocol``. - - *options* are optional named arguments allowing to change how the - connection is created: - - * *ssl*: if given and not false, a SSL/TLS transport is created - (by default a plain TCP transport is created). If *ssl* is - a :class:`ssl.SSLContext` object, this context is used to create - the transport; if *ssl* is :const:`True`, a context with some - unspecified default settings is used. - - * *server_hostname*, is only for use together with *ssl*, - and sets or overrides the hostname that the target server's certificate - will be matched against. By default the value of the *host* argument - is used. If *host* is empty, there is no default and you must pass a - value for *server_hostname*. If *server_hostname* is an empty - string, hostname matching is disabled (which is a serious security - risk, allowing for man-in-the-middle-attacks). - - * *family*, *proto*, *flags* are the optional address family, protocol - and flags to be passed through to getaddrinfo() for *host* resolution. - If given, these should all be integers from the corresponding - :mod:`socket` module constants. - - * *sock*, if given, should be an existing, already connected - :class:`socket.socket` object to be used by the transport. - If *sock* is given, none of *host*, *port*, *family*, *proto*, *flags* - and *local_addr* should be specified. - - * *local_addr*, if given, is a ``(local_host, local_port)`` tuple used - to bind the socket to locally. The *local_host* and *local_port* - are looked up using getaddrinfo(), similarly to *host* and *port*. - -.. method:: BaseEventLoop.connect_read_pipe(protocol_factory, pipe) - - XXX - - This method returns a :ref:`coroutine <coroutine>`. - -.. method:: BaseEventLoop.connect_write_pipe(protocol_factory, pipe) - - XXX - - This method returns a :ref:`coroutine <coroutine>`. - - -Resolve name -^^^^^^^^^^^^ - -.. method:: BaseEventLoop.getaddrinfo(host, port, \*, family=0, type=0, proto=0, flags=0) - - XXX - -.. method:: BaseEventLoop.getnameinfo(sockaddr, flags=0) - - XXX - - -Running subprocesses -^^^^^^^^^^^^^^^^^^^^ - -Run subprocesses asynchronously using the :mod:`subprocess` module. - -.. method:: BaseEventLoop.subprocess_shell(protocol_factory, cmd, \*, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=False, shell=True, bufsize=0, \*\*kwargs) - - XXX - - This method returns a :ref:`coroutine <coroutine>`. - - See the constructor of the :class:`subprocess.Popen` class for parameters. - -.. method:: BaseEventLoop.subprocess_exec(protocol_factory, \*args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=False, shell=False, bufsize=0, \*\*kwargs) - - XXX - - This method returns a :ref:`coroutine <coroutine>`. - - See the constructor of the :class:`subprocess.Popen` class for parameters. - - -.. _protocol: - -Protocols ---------- - -:mod:`asyncio` provides base classes that you can subclass to implement -your network protocols. Those classes are used in conjunction with -:ref:`transports <transport>` (see below): the protocol parses incoming -data and asks for the writing of outgoing data, while the transport is -responsible for the actual I/O and buffering. - -When subclassing a protocol class, it is recommended you override certain -methods. Those methods are callbacks: they will be called by the transport -on certain events (for example when some data is received); you shouldn't -call them yourself, unless you are implementing a transport. - -.. note:: - All callbacks have default implementations, which are empty. Therefore, - you only need to implement the callbacks for the events in which you - are interested. - - -Protocol classes -^^^^^^^^^^^^^^^^ - -.. class:: Protocol - - The base class for implementing streaming protocols (for use with - e.g. TCP and SSL transports). - -.. class:: DatagramProtocol - - The base class for implementing datagram protocols (for use with - e.g. UDP transports). - -.. class:: SubprocessProtocol - - The base class for implementing protocols communicating with child - processes (through a set of unidirectional pipes). - - -Connection callbacks -^^^^^^^^^^^^^^^^^^^^ - -These callbacks may be called on :class:`Protocol` and -:class:`SubprocessProtocol` instances: - -.. method:: BaseProtocol.connection_made(transport) - - Called when a connection is made. - - The *transport* argument is the transport representing the - connection. You are responsible for storing it somewhere - (e.g. as an attribute) if you need to. - -.. method:: BaseProtocol.connection_lost(exc) - - Called when the connection is lost or closed. - - The argument is either an exception object or :const:`None`. - The latter means a regular EOF is received, or the connection was - aborted or closed by this side of the connection. - -:meth:`connection_made` and :meth:`connection_lost` are called exactly once -per successful connection. All other callbacks will be called between those -two methods, which allows for easier resource management in your protocol -implementation. - -The following callbacks may be called only on :class:`SubprocessProtocol` -instances: - -.. method:: SubprocessProtocol.pipe_data_received(fd, data) - - Called when the child process writes data into its stdout or stderr pipe. - *fd* is the integer file descriptor of the pipe. *data* is a non-empty - bytes object containing the data. - -.. method:: SubprocessProtocol.pipe_connection_lost(fd, exc) - - Called when one of the pipes communicating with the child process - is closed. *fd* is the integer file descriptor that was closed. - -.. method:: SubprocessProtocol.process_exited() - - Called when the child process has exited. - - -Data reception callbacks -^^^^^^^^^^^^^^^^^^^^^^^^ - -Streaming protocols -""""""""""""""""""" - -The following callbacks are called on :class:`Protocol` instances: - -.. method:: Protocol.data_received(data) - - Called when some data is received. *data* is a non-empty bytes object - containing the incoming data. - - .. note:: - Whether the data is buffered, chunked or reassembled depends on - the transport. In general, you shouldn't rely on specific semantics - and instead make your parsing generic and flexible enough. However, - data is always received in the correct order. - -.. method:: Protocol.eof_received() - - Calls when the other end signals it won't send any more data - (for example by calling :meth:`write_eof`, if the other end also uses - asyncio). - - This method may return a false value (including None), in which case - the transport will close itself. Conversely, if this method returns a - true value, closing the transport is up to the protocol. Since the - default implementation returns None, it implicitly closes the connection. - - .. note:: - Some transports such as SSL don't support half-closed connections, - in which case returning true from this method will not prevent closing - the connection. - -:meth:`data_received` can be called an arbitrary number of times during -a connection. However, :meth:`eof_received` is called at most once -and, if called, :meth:`data_received` won't be called after it. - -Datagram protocols -"""""""""""""""""" - -The following callbacks are called on :class:`DatagramProtocol` instances. - -.. method:: DatagramProtocol.datagram_received(data, addr) - - Called when a datagram is received. *data* is a bytes object containing - the incoming data. *addr* is the address of the peer sending the data; - the exact format depends on the transport. - -.. method:: DatagramProtocol.error_received(exc) - - Called when a previous send or receive operation raises an - :class:`OSError`. *exc* is the :class:`OSError` instance. - - This method is called in rare conditions, when the transport (e.g. UDP) - detects that a datagram couldn't be delivered to its recipient. - In many conditions though, undeliverable datagrams will be silently - dropped. - - -Flow control callbacks -^^^^^^^^^^^^^^^^^^^^^^ - -These callbacks may be called on :class:`Protocol` and -:class:`SubprocessProtocol` instances: - -.. method:: BaseProtocol.pause_writing() - - Called when the transport's buffer goes over the high-water mark. - -.. method:: BaseProtocol.resume_writing() - - Called when the transport's buffer drains below the low-water mark. - - -:meth:`pause_writing` and :meth:`resume_writing` calls are paired -- -:meth:`pause_writing` is called once when the buffer goes strictly over -the high-water mark (even if subsequent writes increases the buffer size -even more), and eventually :meth:`resume_writing` is called once when the -buffer size reaches the low-water mark. - -.. note:: - If the buffer size equals the high-water mark, - :meth:`pause_writing` is not called -- it must go strictly over. - Conversely, :meth:`resume_writing` is called when the buffer size is - equal or lower than the low-water mark. These end conditions - are important to ensure that things go as expected when either - mark is zero. - - -.. _transport: - -Transports ----------- - -Transports are classed provided by :mod:`asyncio` in order to abstract -various kinds of communication channels. You generally won't instantiate -a transport yourself; instead, you will call a :class:`BaseEventLoop` method -which will create the transport and try to initiate the underlying -communication channel, calling you back when it succeeds. - -Once the communication channel is established, a transport is always -paired with a :ref:`protocol <protocol>` instance. The protocol can -then call the transport's methods for various purposes. - -:mod:`asyncio` currently implements transports for TCP, UDP, SSL, and -subprocess pipes. The methods available on a transport depend on -the transport's kind. - -Methods common to all transports -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. method:: BaseTransport.close(self) - - Close the transport. If the transport has a buffer for outgoing - data, buffered data will be flushed asynchronously. No more data - will be received. After all buffered data is flushed, the - protocol's :meth:`connection_lost` method will be called with - :const:`None` as its argument. - - -.. method:: BaseTransport.get_extra_info(name, default=None) - - Return optional transport information. *name* is a string representing - the piece of transport-specific information to get, *default* is the - value to return if the information doesn't exist. - - This method allows transport implementations to easily expose - channel-specific information. - -Methods of readable streaming transports -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. method:: ReadTransport.pause_reading() - - Pause the receiving end of the transport. No data will be passed to - the protocol's :meth:`data_received` method until meth:`resume_reading` - is called. - -.. method:: ReadTransport.resume_reading() - - Resume the receiving end. The protocol's :meth:`data_received` method - will be called once again if some data is available for reading. - -Methods of writable streaming transports -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. method:: WriteTransport.write(data) - - Write some *data* bytes to the transport. - - This method does not block; it buffers the data and arranges for it - to be sent out asynchronously. - -.. method:: WriteTransport.writelines(list_of_data) - - Write a list (or any iterable) of data bytes to the transport. - This is functionally equivalent to calling :meth:`write` on each - element yielded by the iterable, but may be implemented more efficiently. - -.. method:: WriteTransport.write_eof() - - Close the write end of the transport after flushing buffered data. - Data may still be received. - - This method can raise :exc:`NotImplementedError` if the transport - (e.g. SSL) doesn't support half-closes. - -.. method:: WriteTransport.can_write_eof() - - Return :const:`True` if the transport supports :meth:`write_eof`, - :const:`False` if not. - -.. method:: WriteTransport.abort() - - Close the transport immediately, without waiting for pending operations - to complete. Buffered data will be lost. No more data will be received. - The protocol's :meth:`connection_lost` method will eventually be - called with :const:`None` as its argument. - -.. method:: WriteTransport.set_write_buffer_limits(high=None, low=None) - - Set the *high*- and *low*-water limits for write flow control. - - These two values control when call the protocol's - :meth:`pause_writing` and :meth:`resume_writing` methods are called. - If specified, the low-water limit must be less than or equal to the - high-water limit. Neither *high* nor *low* can be negative. - - The defaults are implementation-specific. If only the - high-water limit is given, the low-water limit defaults to a - implementation-specific value less than or equal to the - high-water limit. Setting *high* to zero forces *low* to zero as - well, and causes :meth:`pause_writing` to be called whenever the - buffer becomes non-empty. Setting *low* to zero causes - :meth:`resume_writing` to be called only once the buffer is empty. - Use of zero for either limit is generally sub-optimal as it - reduces opportunities for doing I/O and computation - concurrently. - -.. method:: WriteTransport.get_write_buffer_size() - - Return the current size of the output buffer used by the transport. - -Methods of datagram transports -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. method:: DatagramTransport.sendto(data, addr=None) - - Send the *data* bytes to the remote peer given by *addr* (a - transport-dependent target address). If *addr* is :const:`None`, the - data is sent to the target address given on transport creation. - - This method does not block; it buffers the data and arranges for it - to be sent out asynchronously. - -.. method:: DatagramTransport.abort() - - Close the transport immediately, without waiting for pending operations - to complete. Buffered data will be lost. No more data will be received. - The protocol's :meth:`connection_lost` method will eventually be - called with :const:`None` as its argument. - -Methods of subprocess transports -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. method:: BaseSubprocessTransport.get_pid() - - Return the subprocess process id as an integer. - -.. method:: BaseSubprocessTransport.get_returncode() - - Return the subprocess returncode as an integer or :const:`None` - if it hasn't returned, similarly to the - :attr:`subprocess.Popen.returncode` attribute. - -.. method:: BaseSubprocessTransport.get_pipe_transport(fd) - - Return the transport for the communication pipe correspondong to the - integer file descriptor *fd*. The return value can be a readable or - writable streaming transport, depending on the *fd*. If *fd* doesn't - correspond to a pipe belonging to this transport, :const:`None` is - returned. - -.. method:: BaseSubprocessTransport.send_signal(signal) - - Send the *signal* number to the subprocess, as in - :meth:`subprocess.Popen.send_signal`. - -.. method:: BaseSubprocessTransport.terminate() - - Ask the subprocess to stop, as in :meth:`subprocess.Popen.terminate`. - This method is an alias for the :meth:`close` method. - - On POSIX systems, this method sends SIGTERM to the subprocess. - On Windows, the Windows API function TerminateProcess() is called to - stop the subprocess. - -.. method:: BaseSubprocessTransport.kill(self) - - Kill the subprocess, as in :meth:`subprocess.Popen.kill` - - On POSIX systems, the function sends SIGKILL to the subprocess. - On Windows, this method is an alias for :meth:`terminate`. - - -Task functions --------------- - -.. function:: as_completed(fs, *, loop=None, timeout=None) - - Return an iterator whose values, when waited for, are - :class:`~concurrent.futures.Future` instances. - - Raises :exc:`TimeoutError` if the timeout occurs before all Futures are done. - - Example:: - - for f in as_completed(fs): - result = yield from f # The 'yield from' may raise - # Use result - - .. note:: - - The futures ``f`` are not necessarily members of fs. - -.. function:: async(coro_or_future, *, loop=None) - - Wrap a :ref:`coroutine <coroutine>` in a future. - - If the argument is a :class:`~concurrent.futures.Future`, it is returned - directly. - -.. function:: gather(*coros_or_futures, loop=None, return_exceptions=False) - - Return a future aggregating results from the given coroutines or futures. - - All futures must share the same event loop. If all the tasks are done - successfully, the returned future's result is the list of results (in the - order of the original sequence, not necessarily the order of results - arrival). If *result_exception* is True, exceptions in the tasks are - treated the same as successful results, and gathered in the result list; - otherwise, the first raised exception will be immediately propagated to the - returned future. - - Cancellation: if the outer Future is cancelled, all children (that have not - completed yet) are also cancelled. If any child is cancelled, this is - treated as if it raised :exc:`~concurrent.futures.CancelledError` -- the - outer Future is *not* cancelled in this case. (This is to prevent the - cancellation of one child to cause other children to be cancelled.) - -.. function:: iscoroutinefunction(func) - - Return ``True`` if *func* is a decorated coroutine function. - -.. function:: iscoroutine(obj) - - Return ``True`` if *obj* is a coroutine object. - -.. function:: sleep(delay, result=None, *, loop=None) - - Create a :ref:`coroutine <coroutine>` that completes after a given time - (in seconds). - -.. function:: shield(arg, *, loop=None) - - Wait for a future, shielding it from cancellation. - - The statement:: - - res = yield from shield(something()) - - is exactly equivalent to the statement:: - - res = yield from something() - - *except* that if the coroutine containing it is cancelled, the task running - in ``something()`` is not cancelled. From the point of view of - ``something()``, the cancellation did not happen. But its caller is still - cancelled, so the yield-from expression still raises - :exc:`~concurrent.futures.CancelledError`. Note: If ``something()`` is - cancelled by other means this will still cancel ``shield()``. - - If you want to completely ignore cancellation (not recommended) you can - combine ``shield()`` with a try/except clause, as follows:: - - try: - res = yield from shield(something()) - except CancelledError: - res = None - - -Task ----- - -.. class:: Task(coro, *, loop=None) - - A coroutine wrapped in a :class:`~concurrent.futures.Future`. - - .. classmethod:: all_tasks(loop=None) - - Return a set of all tasks for an event loop. - - By default all tasks for the current event loop are returned. - - .. method:: cancel() - - Cancel the task. - - .. method:: get_stack(self, *, limit=None) - - Return the list of stack frames for this task's coroutine. - - If the coroutine is active, 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 nummber 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. - - .. method:: print_stack(*, limit=None, file=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 - goes; by default it goes to sys.stderr. - - -Protocols ---------- - -:mod:`asyncio` provides base classes that you can subclass to implement -your network protocols. Those classes are used in conjunction with -:ref:`transports <transport>` (see below): the protocol parses incoming -data and asks for the writing of outgoing data, while the transport is -responsible for the actual I/O and buffering. - -When subclassing a protocol class, it is recommended you override certain -methods. Those methods are callbacks: they will be called by the transport -on certain events (for example when some data is received); you shouldn't -call them yourself, unless you are implementing a transport. - -.. note:: - All callbacks have default implementations, which are empty. Therefore, - you only need to implement the callbacks for the events in which you - are interested. - - -.. _coroutine: - -Coroutines ----------- - -A coroutine is a generator that follows certain conventions. For -documentation purposes, all coroutines should be decorated with -``@asyncio.coroutine``, but this cannot be strictly enforced. - -Coroutines use the ``yield from`` syntax introduced in :pep:`380`, -instead of the original ``yield`` syntax. - -The word "coroutine", like the word "generator", is used for two -different (though related) concepts: - -- The function that defines a coroutine (a function definition - decorated with ``asyncio.coroutine``). If disambiguation is needed - we will call this a *coroutine function*. - -- The object obtained by calling a coroutine function. This object - represents a computation or an I/O operation (usually a combination) - that will complete eventually. If disambiguation is needed we will - call it a *coroutine object*. - -Things a coroutine can do: - -- ``result = yield from future`` -- suspends the coroutine until the - future is done, then returns the future's result, or raises an - exception, which will be propagated. (If the future is cancelled, - it will raise a ``CancelledError`` exception.) Note that tasks are - futures, and everything said about futures also applies to tasks. - -- ``result = yield from coroutine`` -- wait for another coroutine to - produce a result (or raise an exception, which will be propagated). - The ``coroutine`` expression must be a *call* to another coroutine. - -- ``return expression`` -- produce a result to the coroutine that is - waiting for this one using ``yield from``. - -- ``raise exception`` -- raise an exception in the coroutine that is - waiting for this one using ``yield from``. - -Calling a coroutine does not start its code running -- it is just a -generator, and the coroutine object returned by the call is really a -generator object, which doesn't do anything until you iterate over it. -In the case of a coroutine object, there are two basic ways to start -it running: call ``yield from coroutine`` from another coroutine -(assuming the other coroutine is already running!), or convert it to a -:class:`Task`. - -Coroutines (and tasks) can only run when the event loop is running. - - -.. _sync: - -Synchronization primitives --------------------------- - -.. class:: Lock(\*, loop=None) - - Primitive lock objects. - - A primitive lock is a synchronization primitive that is not owned by a - particular coroutine when locked. A primitive lock is in one of two states, - 'locked' or 'unlocked'. - - It is created in the unlocked state. It has two basic methods, :meth:`acquire` - and :meth:`release`. When the state is unlocked, acquire() changes the state to - locked and returns immediately. When the state is locked, acquire() blocks - until a call to release() in another coroutine changes it to unlocked, then - the acquire() call resets it to locked and returns. The release() method - should only be called in the locked state; it changes the state to unlocked - and returns immediately. If an attempt is made to release an unlocked lock, - a :exc:`RuntimeError` will be raised. - - When more than one coroutine is blocked in acquire() waiting for the state - to turn to unlocked, only one coroutine proceeds when a release() call - resets the state to unlocked; first coroutine which is blocked in acquire() - is being processed. - - :meth:`acquire` is a coroutine and should be called with ``yield from``. - - Locks also support the context manager protocol. ``(yield from lock)`` - should be used as context manager expression. - - Usage:: - - lock = Lock() - ... - yield from lock - try: - ... - finally: - lock.release() - - Context manager usage:: - - lock = Lock() - ... - with (yield from lock): - ... - - Lock objects can be tested for locking state:: - - if not lock.locked(): - yield from lock - else: - # lock is acquired - ... - - .. method:: locked() - - Return ``True`` if lock is acquired. - - .. method:: acquire() - - Acquire a lock. - - This method blocks until the lock is unlocked, then sets it to locked and - returns ``True``. - - This method returns a :ref:`coroutine <coroutine>`. - - .. method:: release() - - Release a lock. - - When the lock is locked, reset it to unlocked, and return. If any other - coroutines are blocked waiting for the lock to become unlocked, allow - exactly one of them to proceed. - - When invoked on an unlocked lock, a :exc:`RuntimeError` is raised. - - There is no return value. - - -.. class:: Event(\*, loop=None) - - An Event implementation, asynchronous equivalent to :class:`threading.Event`. - - Class implementing event objects. An event manages a flag that can be set to - true with the :meth:`set` method and reset to false with the :meth:`clear` - method. The :meth:`wait` method blocks until the flag is true. The flag is - initially false. - - .. method:: is_set() - - Return ``True`` if and only if the internal flag is true. - - .. method:: set() - - Set the internal flag to true. All coroutines waiting for it to become - true are awakened. Coroutine that call :meth:`wait` once the flag is true - will not block at all. - - .. method:: clear() - - Reset the internal flag to false. Subsequently, coroutines calling - :meth:`wait` will block until :meth:`set` is called to set the internal - flag to true again. - - .. method:: wait() - - Block until the internal flag is true. - - If the internal flag is true on entry, return ``True`` immediately. - Otherwise, block until another coroutine calls :meth:`set` to set the - flag to true, then return ``True``. - - This method returns a :ref:`coroutine <coroutine>`. - - -.. class:: Condition(\*, loop=None) - - A Condition implementation, asynchronous equivalent to - :class:`threading.Condition`. - - This class implements condition variable objects. A condition variable - allows one or more coroutines to wait until they are notified by another - coroutine. - - A new :class:`Lock` object is created and used as the underlying lock. - - .. method:: wait() - - Wait until notified. - - If the calling coroutine has not acquired the lock when this method is - called, a :exc:`RuntimeError` is raised. - - This method releases the underlying lock, and then blocks until it is - awakened by a :meth:`notify` or :meth:`notify_all` call for the same - condition variable in another coroutine. Once awakened, it re-acquires - the lock and returns ``True``. - - This method returns a :ref:`coroutine <coroutine>`. - - .. method:: wait_for(predicate) - - Wait until a predicate becomes true. - - The predicate should be a callable which result will be interpreted as a - boolean value. The final predicate value is the return value. - - This method returns a :ref:`coroutine <coroutine>`. - - .. method:: notify(n=1) - - By default, wake up one coroutine waiting on this condition, if any. - If the calling coroutine has not acquired the lock when this method is - called, a :exc:`RuntimeError` is raised. - - This method wakes up at most *n* of the coroutines waiting for the - condition variable; it is a no-op if no coroutines are waiting. - - .. note:: - - An awakened coroutine does not actually return from its :meth:`wait` - call until it can reacquire the lock. Since :meth:`notify` does not - release the lock, its caller should. - - .. method:: notify_all() - - Wake up all threads waiting on this condition. This method acts like - :meth:`notify`, but wakes up all waiting threads instead of one. If the - calling thread has not acquired the lock when this method is called, a - :exc:`RuntimeError` is raised. - - -.. class:: Semaphore(value=1, \*, loop=None) - - A Semaphore implementation. - - A semaphore manages an internal counter which is decremented by each - :meth:`acquire` call and incremented by each :meth:`release` call. The - counter can never go below zero; when :meth:`acquire` finds that it is zero, - it blocks, waiting until some other thread calls :meth:`release`. - - Semaphores also support the context manager protocol. - - The optional argument gives the initial value for the internal counter; it - defaults to ``1``. If the value given is less than ``0``, :exc:`ValueError` - is raised. - - .. method:: locked() - - Returns ``True`` if semaphore can not be acquired immediately. - - .. method:: acquire() - - Acquire a semaphore. - - If the internal counter is larger than zero on entry, decrement it by one - and return ``True`` immediately. If it is zero on entry, block, waiting - until some other coroutine has called :meth:`release` to make it larger - than ``0``, and then return ``True``. - - This method returns a :ref:`coroutine <coroutine>`. - - .. method:: release() - - Release a semaphore, incrementing the internal counter by one. When it - was zero on entry and another coroutine is waiting for it to become - larger than zero again, wake up that coroutine. - - -.. class:: BoundedSemaphore(value=1, \*, loop=None) - - A bounded semaphore implementation. Inherit from :class:`Semaphore`. - - This raises :exc:`ValueError` in :meth:`~Semaphore.release` if it would - increase the value above the initial value. - - -.. class:: Queue(maxsize=0, \*, loop=None) - - A queue, useful for coordinating producer and consumer coroutines. - - If *maxsize* is less than or equal to zero, the queue size is infinite. If - it is an integer greater than ``0``, then ``yield from put()`` will block - when the queue reaches *maxsize*, until an item is removed by :meth:`get`. - - Unlike the standard library :mod:`queue`, you can reliably know this Queue's - size with :meth:`qsize`, since your single-threaded Tulip application won't - be interrupted between calling :meth:`qsize` and doing an operation on the - Queue. - - .. method:: empty() - - Return ``True`` if the queue is empty, ``False`` otherwise. - - .. method:: full() - - Return ``True`` if there are maxsize items in the queue. - - .. note:: - - If the Queue was initialized with ``maxsize=0`` (the default), then - :meth:`full()` is never ``True``. - - .. method:: get() - - Remove and return an item from the queue. - - If you yield from :meth:`get()`, wait until a item is available. - - This method returns a :ref:`coroutine <coroutine>`. - - .. method:: get_nowait() - - Remove and return an item from the queue. - - Return an item if one is immediately available, else raise - :exc:`~queue.Empty`. - - .. method:: put(item) - - Put an item into the queue. - - If you yield from ``put()``, wait until a free slot is available before - adding item. - - This method returns a :ref:`coroutine <coroutine>`. - - .. method:: put_nowait(item) - - Put an item into the queue without blocking. - - If no free slot is immediately available, raise :exc:`~queue.Full`. - - .. method:: qsize() - - Number of items in the queue. - - .. attribute:: maxsize - - Number of items allowed in the queue. - -.. class:: PriorityQueue - - A subclass of :class:`Queue`; retrieves entries in priority order (lowest - first). - - Entries are typically tuples of the form: (priority number, data). - -.. class:: LifoQueue - - A subclass of :class:`Queue` that retrieves most recently added entries - first. - -.. class:: JoinableQueue - - A subclass of :class:`Queue` with :meth:`task_done` and :meth:`join` - methods. - - .. method:: task_done() - - Indicate that a formerly enqueued task is complete. - - Used by queue consumers. For each :meth:`~Queue.get` used to fetch a task, a - subsequent call to :meth:`task_done` tells the queue that the processing - on the task is complete. - - If a :meth:`join` is currently blocking, it will resume when all items - have been processed (meaning that a :meth:`task_done` call was received - for every item that had been :meth:`~Queue.put` into the queue). - - Raises :exc:`ValueError` if called more times than there were items - placed in the queue. - - .. method:: join() - - Block until all items in the queue have been gotten and processed. - - The count of unfinished tasks goes up whenever an item is added to the - queue. The count goes down whenever a consumer thread calls - :meth:`task_done` to indicate that the item was retrieved and all work on - it is complete. When the count of unfinished tasks drops to zero, - :meth:`join` unblocks. - - This method returns a :ref:`coroutine <coroutine>`. - - -Examples --------- - -Hello World (callback) -^^^^^^^^^^^^^^^^^^^^^^ - -Print ``Hello World`` every two seconds, using a callback:: - - import asyncio - - def print_and_repeat(loop): - print('Hello World') - loop.call_later(2, print_and_repeat, loop) - - loop = asyncio.get_event_loop() - print_and_repeat(loop) - loop.run_forever() - - -Hello World (callback) -^^^^^^^^^^^^^^^^^^^^^^ - -Print ``Hello World`` every two seconds, using a coroutine:: - - import asyncio - - @asyncio.coroutine - def greet_every_two_seconds(): - while True: - print('Hello World') - yield from asyncio.sleep(2) - - loop = asyncio.get_event_loop() - loop.run_until_complete(greet_every_two_seconds()) - - -Echo server -^^^^^^^^^^^ - -A :class:`Protocol` implementing an echo server:: - - class EchoServer(asyncio.Protocol): - - TIMEOUT = 5.0 - - def timeout(self): - print('connection timeout, closing.') - self.transport.close() - - def connection_made(self, transport): - print('connection made') - self.transport = transport - - # start 5 seconds timeout timer - self.h_timeout = asyncio.get_event_loop().call_later( - self.TIMEOUT, self.timeout) +Table of contents: - def data_received(self, data): - print('data received: ', data.decode()) - self.transport.write(b'Re: ' + data) +.. toctree:: + :maxdepth: 3 - # restart timeout timer - self.h_timeout.cancel() - self.h_timeout = asyncio.get_event_loop().call_later( - self.TIMEOUT, self.timeout) + asyncio-eventloop.rst + asyncio-eventloops.rst + asyncio-task.rst + asyncio-protocol.rst + asyncio-stream.rst + asyncio-subprocess.rst + asyncio-sync.rst + asyncio-queue.rst + asyncio-dev.rst - def eof_received(self): - pass +.. seealso:: - def connection_lost(self, exc): - print('connection lost:', exc) - self.h_timeout.cancel() + The :mod:`asyncio` module was designed in :PEP:`3156`. For a + motivational primer on transports and protocols, see :PEP:`3153`. diff --git a/Doc/library/asyncore.rst b/Doc/library/asyncore.rst index 61079c5b34c0..917d0448c2f0 100644 --- a/Doc/library/asyncore.rst +++ b/Doc/library/asyncore.rst @@ -213,7 +213,12 @@ any that have been added to the map during asynchronous service) is closed. .. method:: recv(buffer_size) Read at most *buffer_size* bytes from the socket's remote end-point. An - empty string implies that the channel has been closed from the other end. + empty bytes object implies that the channel has been closed from the + other end. + + Note that :meth:`recv` may raise :exc:`BlockingIOError` , even though + :func:`select.select` or :func:`select.poll` has reported the socket + ready for reading. .. method:: listen(backlog) diff --git a/Doc/library/audioop.rst b/Doc/library/audioop.rst index fbb7fc629442..ce127aa06a61 100644 --- a/Doc/library/audioop.rst +++ b/Doc/library/audioop.rst @@ -12,10 +12,8 @@ integers, unless specified otherwise. .. versionchanged:: 3.4 Support for 24-bit samples was added. - -.. versionchanged:: 3.4 - Any :term:`bytes-like object`\ s are now accepted by all functions in this - module. Strings no more supported. + All functions now accept any :term:`bytes-like object`. + String input now results in an immediate error. .. index:: single: Intel/DVI ADPCM @@ -82,7 +80,7 @@ The module defines the following variables and functions: "Byteswap" all samples in a fragment and returns the modified fragment. Converts big-endian samples to little-endian and vice versa. - .. versionadded: 3.4 + .. versionadded:: 3.4 .. function:: cross(fragment, width) diff --git a/Doc/library/base64.rst b/Doc/library/base64.rst index a7eed0899b8c..3d23dfc765df 100644 --- a/Doc/library/base64.rst +++ b/Doc/library/base64.rst @@ -1,27 +1,33 @@ -:mod:`base64` --- RFC 3548: Base16, Base32, Base64 Data Encodings -================================================================= +:mod:`base64` --- Base16, Base32, Base64, Base85 Data Encodings +=============================================================== .. module:: base64 - :synopsis: RFC 3548: Base16, Base32, Base64 Data Encodings + :synopsis: RFC 3548: Base16, Base32, Base64 Data Encodings; + Base85 and Ascii85 .. index:: pair: base64; encoding single: MIME; base64 encoding -This module provides data encoding and decoding as specified in :rfc:`3548`. -This standard defines the Base16, Base32, and Base64 algorithms for encoding -and decoding arbitrary binary strings into ASCII-only byte strings that can be +This module provides functions for encoding binary data to printable +ASCII characters and decoding such encodings back to binary data. +It provides encoding and decoding functions for the encodings specified in +:rfc:`3548`, which defines the Base16, Base32, and Base64 algorithms, +and for the de-facto standard Ascii85 and Base85 encodings. + +The :rfc:`3548` encodings are suitable for encoding binary data so that it can safely sent by email, used as parts of URLs, or included as part of an HTTP POST request. The encoding algorithm is not the same as the :program:`uuencode` program. -There are two interfaces provided by this module. The modern interface -supports encoding and decoding ASCII byte string objects using all three -alphabets. Additionally, the decoding functions of the modern interface also -accept Unicode strings containing only ASCII characters. The legacy interface -provides for encoding and decoding to and from file-like objects as well as -byte strings, but only using the Base64 standard alphabet. +There are two :rfc:`3548` interfaces provided by this module. The modern +interface supports encoding and decoding ASCII byte string objects using all +three :rfc:`3548` defined alphabets (normal, URL-safe, and filesystem-safe). +Additionally, the decoding functions of the modern interface also accept +Unicode strings containing only ASCII characters. The legacy interface provides +for encoding and decoding to and from file-like objects as well as byte +strings, but only using the Base64 standard alphabet. .. versionchanged:: 3.3 ASCII-only Unicode strings are now accepted by the decoding functions of @@ -29,7 +35,7 @@ byte strings, but only using the Base64 standard alphabet. .. versionchanged:: 3.4 Any :term:`bytes-like object`\ s are now accepted by all - encoding and decoding functions in this module. + encoding and decoding functions in this module. Ascii85/Base85 support added. The modern interface provides: @@ -107,7 +113,7 @@ The modern interface provides: digit 0 is always mapped to the letter O). For security purposes the default is ``None``, so that 0 and 1 are not allowed in the input. - The decoded byte string is returned. A :exc:`binascii.Error` is raised if *s* were + The decoded byte string is returned. A :exc:`binascii.Error` is raised if *s* is incorrectly padded or if there are non-alphabet characters present in the string. diff --git a/Doc/library/bdb.rst b/Doc/library/bdb.rst index 7229087b5db1..8ee9921553bb 100644 --- a/Doc/library/bdb.rst +++ b/Doc/library/bdb.rst @@ -231,7 +231,7 @@ The :mod:`bdb` module also defines two classes: .. method:: set_until(frame) Stop when the line with the line no greater than the current one is - reached or when returning from current frame + reached or when returning from current frame. .. method:: set_trace([frame]) diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst index c92a8e160a97..441aa57d52bd 100644 --- a/Doc/library/binascii.rst +++ b/Doc/library/binascii.rst @@ -52,22 +52,24 @@ The :mod:`binascii` module defines the following functions: than one line may be passed at a time. -.. function:: b2a_base64(data) +.. function:: b2a_base64(data, \*, newline=True) Convert binary data to a line of ASCII characters in base64 coding. The return - value is the converted line, including a newline char. The length of *data* - should be at most 57 to adhere to the base64 standard. + value is the converted line, including a newline char if *newline* is + true. The length of *data* should be at most 57 to adhere to the + base64 standard. -.. function:: a2b_qp(string, header=False) + .. versionchanged:: 3.6 + Added the *newline* parameter. + + +.. function:: a2b_qp(data, header=False) Convert a block of quoted-printable data back to binary and return the binary data. More than one line may be passed at a time. If the optional argument *header* is present and true, underscores will be decoded as spaces. - .. versionchanged:: 3.2 - Accept only bytestring or bytearray objects as input. - .. function:: b2a_qp(data, quotetabs=False, istext=True, header=False) @@ -156,9 +158,6 @@ The :mod:`binascii` module defines the following functions: of hexadecimal digits (which can be upper or lower case), otherwise a :exc:`TypeError` is raised. - .. versionchanged:: 3.2 - Accept only bytestring or bytearray objects as input. - .. exception:: Error diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst index 9027a3554e83..1b8d9cffc655 100644 --- a/Doc/library/bz2.rst +++ b/Doc/library/bz2.rst @@ -95,6 +95,11 @@ All of the classes in this module may safely be accessed from multiple threads. byte of data will be returned (unless at EOF). The exact number of bytes returned is unspecified. + .. note:: While calling :meth:`peek` does not change the file position of + the :class:`BZ2File`, it may change the position of the underlying file + object (e.g. if the :class:`BZ2File` was constructed by passing a file + object for *filename*). + .. versionadded:: 3.3 .. versionchanged:: 3.1 @@ -115,6 +120,10 @@ All of the classes in this module may safely be accessed from multiple threads. .. versionchanged:: 3.4 The ``'x'`` (exclusive creation) mode was added. + .. versionchanged:: 3.5 + The :meth:`~io.BufferedIOBase.read` method now accepts an argument of + ``None``. + Incremental (de)compression --------------------------- @@ -157,15 +166,32 @@ Incremental (de)compression you need to decompress a multi-stream input with :class:`BZ2Decompressor`, you must use a new decompressor for each stream. - .. method:: decompress(data) + .. method:: decompress(data, max_length=-1) + + Decompress *data* (a :term:`bytes-like object`), returning + uncompressed data as bytes. Some of *data* may be buffered + internally, for use in later calls to :meth:`decompress`. The + returned data should be concatenated with the output of any + previous calls to :meth:`decompress`. + + 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, the :attr:`~.needs_input` attribute will + be set to ``False``. In this case, the next call to + :meth:`~.decompress` may provide *data* as ``b''`` to obtain + more of the output. - Provide data to the decompressor object. Returns a chunk of decompressed - data if possible, or an empty byte string otherwise. + 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), the :attr:`~.needs_input` attribute + will be set to ``True``. - Attempting to decompress data after the end of the current stream is - reached raises an :exc:`EOFError`. If any data is found after the end of - the stream, it is ignored and saved in the :attr:`unused_data` attribute. + 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 :attr:`~.unused_data` attribute. + .. versionchanged:: 3.5 + Added the *max_length* parameter. .. attribute:: eof @@ -181,6 +207,13 @@ Incremental (de)compression If this attribute is accessed before the end of the stream has been reached, its value will be ``b''``. + .. attribute:: needs_input + + ``False`` if the :meth:`.decompress` method can provide more + decompressed data before requiring new uncompressed input. + + .. versionadded:: 3.5 + One-shot (de)compression ------------------------ diff --git a/Doc/library/cgi.rst b/Doc/library/cgi.rst index c4e7c60539b2..7e496ca3611e 100644 --- a/Doc/library/cgi.rst +++ b/Doc/library/cgi.rst @@ -142,9 +142,11 @@ If a field represents an uploaded file, accessing the value via the method reads the entire file in memory as bytes. This may not be what you want. You can test for an uploaded file by testing either the :attr:`~FieldStorage.filename` attribute or the :attr:`~FieldStorage.file` -attribute. You can then read the data at leisure from the :attr:`!file` -attribute (the :func:`~io.RawIOBase.read` and :func:`~io.IOBase.readline` -methods will return bytes):: +attribute. You can then read the data from the :attr:`!file` +attribute before it is automatically closed as part of the garbage collection of +the :class:`FieldStorage` instance +(the :func:`~io.RawIOBase.read` and :func:`~io.IOBase.readline` methods will +return bytes):: fileitem = form["userfile"] if fileitem.file: @@ -155,6 +157,9 @@ methods will return bytes):: if not line: break linecount = linecount + 1 +:class:`FieldStorage` objects also support being used in a :keyword:`with` +statement, which will automatically close them when done. + If an error is encountered when obtaining the contents of an uploaded file (for example, when the user interrupts the form submission by clicking on a Back or Cancel button) the :attr:`~FieldStorage.done` attribute of the @@ -176,6 +181,15 @@ actually be instances of the class :class:`MiniFieldStorage`. In this case, the A form submitted via POST that also has a query string will contain both :class:`FieldStorage` and :class:`MiniFieldStorage` items. +.. versionchanged:: 3.4 + The :attr:`~FieldStorage.file` attribute is automatically closed upon the + garbage collection of the creating :class:`FieldStorage` instance. + +.. versionchanged:: 3.5 + Added support for the context management protocol to the + :class:`FieldStorage` class. + + Higher Level Interface ---------------------- @@ -278,7 +292,7 @@ algorithms implemented in this module in other circumstances. .. function:: parse_qsl(qs, keep_blank_values=False, strict_parsing=False) - This function is deprecated in this module. Use :func:`urllib.parse.parse_qs` + This function is deprecated in this module. Use :func:`urllib.parse.parse_qsl` instead. It is maintained here only for backward compatibility. .. function:: parse_multipart(fp, pdict) diff --git a/Doc/library/chunk.rst b/Doc/library/chunk.rst index ae0a22156b43..50b6979f836c 100644 --- a/Doc/library/chunk.rst +++ b/Doc/library/chunk.rst @@ -113,15 +113,15 @@ instance will fail with a :exc:`EOFError` exception. Read at most *size* bytes from the chunk (less if the read hits the end of the chunk before obtaining *size* bytes). If the *size* argument is - negative or omitted, read all data until the end of the chunk. The bytes - are returned as a string object. An empty string is returned when the end - of the chunk is encountered immediately. + negative or omitted, read all data until the end of the chunk. An empty + bytes object is returned when the end of the chunk is encountered + immediately. .. method:: skip() Skip to the end of the chunk. All further calls to :meth:`read` for the - chunk will return ``''``. If you are not interested in the contents of + chunk will return ``b''``. If you are not interested in the contents of the chunk, this method should be called so that the file points to the start of the next chunk. diff --git a/Doc/library/cmath.rst b/Doc/library/cmath.rst index d7778df31730..ab619a082aea 100644 --- a/Doc/library/cmath.rst +++ b/Doc/library/cmath.rst @@ -149,13 +149,13 @@ Hyperbolic functions .. function:: acosh(x) - Return the hyperbolic arc cosine of *x*. There is one branch cut, extending left - from 1 along the real axis to -∞, continuous from above. + Return the inverse hyperbolic cosine of *x*. There is one branch cut, + extending left from 1 along the real axis to -∞, continuous from above. .. function:: asinh(x) - Return the hyperbolic arc sine of *x*. There are two branch cuts: + Return the inverse hyperbolic sine of *x*. There are two branch cuts: One extends from ``1j`` along the imaginary axis to ``∞j``, continuous from the right. The other extends from ``-1j`` along the imaginary axis to ``-∞j``, continuous from the left. @@ -163,7 +163,7 @@ Hyperbolic functions .. function:: atanh(x) - Return the hyperbolic arc tangent of *x*. There are two branch cuts: One + Return the inverse hyperbolic tangent of *x*. There are two branch cuts: One extends from ``1`` along the real axis to ``∞``, continuous from below. The other extends from ``-1`` along the real axis to ``-∞``, continuous from above. @@ -207,6 +207,38 @@ Classification functions and ``False`` otherwise. +.. function:: isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0) + + Return ``True`` if the values *a* and *b* are close to each other and + ``False`` otherwise. + + Whether or not two values are considered close is determined according to + given absolute and relative tolerances. + + *rel_tol* is the relative tolerance -- it is the maximum allowed difference + between *a* and *b*, relative to the larger absolute value of *a* or *b*. + For example, to set a tolerance of 5%, pass ``rel_tol=0.05``. The default + tolerance is ``1e-09``, which assures that the two values are the same + within about 9 decimal digits. *rel_tol* must be greater than zero. + + *abs_tol* is the minimum absolute tolerance -- useful for comparisons near + zero. *abs_tol* must be at least zero. + + If no errors occur, the result will be: + ``abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)``. + + The IEEE 754 special values of ``NaN``, ``inf``, and ``-inf`` will be + handled according to IEEE rules. Specifically, ``NaN`` is not considered + close to any other value, including ``NaN``. ``inf`` and ``-inf`` are only + considered close to themselves. + + .. versionadded:: 3.5 + + .. seealso:: + + :pep:`485` -- A function for testing approximate equality + + Constants --------- diff --git a/Doc/library/cmd.rst b/Doc/library/cmd.rst index 97229280c31f..1ab2d7423fc4 100644 --- a/Doc/library/cmd.rst +++ b/Doc/library/cmd.rst @@ -148,8 +148,8 @@ A :class:`Cmd` instance has the following methods: Hook method executed once when :meth:`cmdloop` is about to return. This method is a stub in :class:`Cmd`; it exists to be overridden by subclasses. -Instances of :class:`Cmd` subclasses have some public instance variables: +Instances of :class:`Cmd` subclasses have some public instance variables: .. attribute:: Cmd.prompt @@ -166,6 +166,13 @@ Instances of :class:`Cmd` subclasses have some public instance variables: The last nonempty command prefix seen. +.. attribute:: Cmd.cmdqueue + + A list of queued input lines. The cmdqueue list is checked in + :meth:`cmdloop` when new input is needed; if it is nonempty, its elements + will be processed in order, as if entered at the prompt. + + .. attribute:: Cmd.intro A string to issue as an intro or banner. May be overridden by giving the @@ -252,7 +259,7 @@ immediate playback:: 'Move turtle to an absolute position with changing orientation. GOTO 100 200' goto(*parse(arg)) def do_home(self, arg): - 'Return turtle to the home postion: HOME' + 'Return turtle to the home position: HOME' home() def do_circle(self, arg): 'Draw circle with given radius an options extent and steps: CIRCLE 50' diff --git a/Doc/library/code.rst b/Doc/library/code.rst index 5b5d7cc8c1ad..275201c69b9b 100644 --- a/Doc/library/code.rst +++ b/Doc/library/code.rst @@ -4,6 +4,7 @@ .. module:: code :synopsis: Facilities to implement read-eval-print loops. +**Source code:** :source:`Lib/code.py` The ``code`` module provides facilities to implement read-eval-print loops in Python. Two classes and convenience functions are included which can be used to @@ -113,6 +114,9 @@ Interactive Interpreter Objects because it is within the interpreter object implementation. The output is written by the :meth:`write` method. + .. versionchanged:: 3.5 The full chained traceback is displayed instead + of just the primary traceback. + .. method:: InteractiveInterpreter.write(data) @@ -165,4 +169,3 @@ interpreter objects as well as the following additions. newline. When the user enters the EOF key sequence, :exc:`EOFError` is raised. The base implementation reads from ``sys.stdin``; a subclass may replace this with a different implementation. - diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst index 843de27ae35b..46d72b5e9bd9 100644 --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -7,6 +7,7 @@ .. sectionauthor:: Marc-André Lemburg <mal@lemburg.com> .. sectionauthor:: Martin v. Löwis <martin@v.loewis.de> +**Source code:** :source:`Lib/codecs.py` .. index:: single: Unicode @@ -17,17 +18,24 @@ pair: stackable; streams This module defines base classes for standard Python codecs (encoders and -decoders) and provides access to the internal Python codec registry which -manages the codec and error handling lookup process. - -It defines the following functions: +decoders) and provides access to the internal Python codec registry, which +manages the codec and error handling lookup process. Most standard codecs +are :term:`text encodings <text encoding>`, which encode text to bytes, +but there are also codecs provided that encode text to text, and bytes to +bytes. Custom codecs may encode and decode between arbitrary types, but some +module features are restricted to use specifically with +:term:`text encodings <text encoding>`, or with codecs that encode to +:class:`bytes`. + +The module defines the following functions for encoding and decoding with +any codec: .. function:: encode(obj, encoding='utf-8', errors='strict') Encodes *obj* using the codec registered for *encoding*. *Errors* may be given to set the desired error handling scheme. The - default error handler is ``strict`` meaning that encoding errors raise + default error handler is ``'strict'`` meaning that encoding errors raise :exc:`ValueError` (or a more codec specific subclass, such as :exc:`UnicodeEncodeError`). Refer to :ref:`codec-base-classes` for more information on codec error handling. @@ -37,91 +45,63 @@ It defines the following functions: Decodes *obj* using the codec registered for *encoding*. *Errors* may be given to set the desired error handling scheme. The - default error handler is ``strict`` meaning that decoding errors raise + default error handler is ``'strict'`` meaning that decoding errors raise :exc:`ValueError` (or a more codec specific subclass, such as :exc:`UnicodeDecodeError`). Refer to :ref:`codec-base-classes` for more information on codec error handling. -.. function:: register(search_function) - - Register a codec search function. Search functions are expected to take one - argument, the encoding name in all lower case letters, and return a - :class:`CodecInfo` object having the following attributes: - - * ``name`` The name of the encoding; - - * ``encode`` The stateless encoding function; - - * ``decode`` The stateless decoding function; - - * ``incrementalencoder`` An incremental encoder class or factory function; - - * ``incrementaldecoder`` An incremental decoder class or factory function; - - * ``streamwriter`` A stream writer class or factory function; - - * ``streamreader`` A stream reader class or factory function. +The full details for each codec can also be looked up directly: - The various functions or classes take the following arguments: +.. function:: lookup(encoding) - *encode* and *decode*: These must be functions or methods which have the same - interface as the :meth:`~Codec.encode`/:meth:`~Codec.decode` methods of Codec - instances (see :ref:`Codec Interface <codec-objects>`). The functions/methods - are expected to work in a stateless mode. + Looks up the codec info in the Python codec registry and returns a + :class:`CodecInfo` object as defined below. - *incrementalencoder* and *incrementaldecoder*: These have to be factory - functions providing the following interface: + Encodings are first looked up in the registry's cache. If not found, the list of + registered search functions is scanned. If no :class:`CodecInfo` object is + found, a :exc:`LookupError` is raised. Otherwise, the :class:`CodecInfo` object + is stored in the cache and returned to the caller. - ``factory(errors='strict')`` +.. class:: CodecInfo(encode, decode, streamreader=None, streamwriter=None, incrementalencoder=None, incrementaldecoder=None, name=None) - The factory functions must return objects providing the interfaces defined by - the base classes :class:`IncrementalEncoder` and :class:`IncrementalDecoder`, - respectively. Incremental codecs can maintain state. + Codec details when looking up the codec registry. The constructor + arguments are stored in attributes of the same name: - *streamreader* and *streamwriter*: These have to be factory functions providing - the following interface: - ``factory(stream, errors='strict')`` + .. attribute:: name - The factory functions must return objects providing the interfaces defined by - the base classes :class:`StreamReader` and :class:`StreamWriter`, respectively. - Stream codecs can maintain state. + The name of the encoding. - Possible values for errors are - * ``'strict'``: raise an exception in case of an encoding error - * ``'replace'``: replace malformed data with a suitable replacement marker, - such as ``'?'`` or ``'\ufffd'`` - * ``'ignore'``: ignore malformed data and continue without further notice - * ``'xmlcharrefreplace'``: replace with the appropriate XML character - reference (for encoding only) - * ``'backslashreplace'``: replace with backslashed escape sequences (for - encoding only) - * ``'surrogateescape'``: on decoding, replace with code points in the Unicode - Private Use Area ranging from U+DC80 to U+DCFF. These private code - points will then be turned back into the same bytes when the - ``surrogateescape`` error handler is used when encoding the data. - (See :pep:`383` for more.) + .. attribute:: encode + decode - as well as any other error handling name defined via :func:`register_error`. + The stateless encoding and decoding functions. These must be + functions or methods which have the same interface as + the :meth:`~Codec.encode` and :meth:`~Codec.decode` methods of Codec + instances (see :ref:`Codec Interface <codec-objects>`). + The functions or methods are expected to work in a stateless mode. - In case a search function cannot find a given encoding, it should return - ``None``. + .. attribute:: incrementalencoder + incrementaldecoder -.. function:: lookup(encoding) + Incremental encoder and decoder classes or factory functions. + These have to provide the interface defined by the base classes + :class:`IncrementalEncoder` and :class:`IncrementalDecoder`, + respectively. Incremental codecs can maintain state. - Looks up the codec info in the Python codec registry and returns a - :class:`CodecInfo` object as defined above. - Encodings are first looked up in the registry's cache. If not found, the list of - registered search functions is scanned. If no :class:`CodecInfo` object is - found, a :exc:`LookupError` is raised. Otherwise, the :class:`CodecInfo` object - is stored in the cache and returned to the caller. + .. attribute:: streamwriter + streamreader -To simplify access to the various codecs, the module provides these additional -functions which use :func:`lookup` for the codec lookup: + Stream writer and reader classes or factory functions. These have to + provide the interface defined by the base classes + :class:`StreamWriter` and :class:`StreamReader`, respectively. + Stream codecs can maintain state. +To simplify access to the various codec components, the module provides +these additional functions which use :func:`lookup` for the codec lookup: .. function:: getencoder(encoding) @@ -170,90 +150,43 @@ functions which use :func:`lookup` for the codec lookup: Raises a :exc:`LookupError` in case the encoding cannot be found. +Custom codecs are made available by registering a suitable codec search +function: -.. function:: register_error(name, error_handler) - - Register the error handling function *error_handler* under the name *name*. - *error_handler* will be called during encoding and decoding in case of an error, - when *name* is specified as the errors parameter. - - For encoding *error_handler* will be called with a :exc:`UnicodeEncodeError` - instance, which contains information about the location of the error. The - error handler must either raise this or a different exception or return a - tuple with a replacement for the unencodable part of the input and a position - where encoding should continue. The replacement may be either :class:`str` or - :class:`bytes`. If the replacement is bytes, the encoder will simply copy - them into the output buffer. If the replacement is a string, the encoder will - encode the replacement. Encoding continues on original input at the - specified position. Negative position values will be treated as being - relative to the end of the input string. If the resulting position is out of - bound an :exc:`IndexError` will be raised. - - Decoding and translating works similar, except :exc:`UnicodeDecodeError` or - :exc:`UnicodeTranslateError` will be passed to the handler and that the - replacement from the error handler will be put into the output directly. - - -.. function:: lookup_error(name) - - Return the error handler previously registered under the name *name*. - - Raises a :exc:`LookupError` in case the handler cannot be found. - - -.. function:: strict_errors(exception) - - Implements the ``strict`` error handling: each encoding or decoding error - raises a :exc:`UnicodeError`. - - -.. function:: replace_errors(exception) - - Implements the ``replace`` error handling: malformed data is replaced with a - suitable replacement character such as ``'?'`` in bytestrings and - ``'\ufffd'`` in Unicode strings. - - -.. function:: ignore_errors(exception) - - Implements the ``ignore`` error handling: malformed data is ignored and - encoding or decoding is continued without further notice. - - -.. function:: xmlcharrefreplace_errors(exception) - - Implements the ``xmlcharrefreplace`` error handling (for encoding only): the - unencodable character is replaced by an appropriate XML character reference. - - -.. function:: backslashreplace_errors(exception) - - Implements the ``backslashreplace`` error handling (for encoding only): the - unencodable character is replaced by a backslashed escape sequence. +.. function:: register(search_function) -To simplify working with encoded files or stream, the module also defines these -utility functions: + Register a codec search function. Search functions are expected to take one + argument, being the encoding name in all lower case letters, and return a + :class:`CodecInfo` object. In case a search function cannot find + a given encoding, it should return ``None``. + .. note:: -.. function:: open(filename, mode[, encoding[, errors[, buffering]]]) + Search function registration is not currently reversible, + which may cause problems in some cases, such as unit testing or + module reloading. - Open an encoded file using the given *mode* and return a wrapped version - providing transparent encoding/decoding. The default file mode is ``'r'`` - meaning to open the file in read mode. +While the builtin :func:`open` and the associated :mod:`io` module are the +recommended approach for working with encoded text files, this module +provides additional utility functions and classes that allow the use of a +wider range of codecs when working with binary files: - .. note:: +.. function:: open(filename, mode='r', encoding=None, errors='strict', buffering=1) - The wrapped version's methods will accept and return strings only. Bytes - arguments will be rejected. + Open an encoded file using the given *mode* and return an instance of + :class:`StreamReaderWriter`, providing transparent encoding/decoding. + The default file mode is ``'r'``, meaning to open the file in read mode. .. note:: - Files are always opened in binary mode, even if no binary mode was - specified. This is done to avoid data loss due to encodings using 8-bit - values. This means that no automatic conversion of ``b'\n'`` is done - on reading and writing. + Underlying encoded files are always opened in binary mode. + No automatic conversion of ``'\n'`` is done on reading and writing. + The *mode* argument may be any binary mode acceptable to the built-in + :func:`open` function; the ``'b'`` is automatically added. *encoding* specifies the encoding which is to be used for the file. + Any encoding that encodes to and decodes from bytes is allowed, and + the data types supported by the file methods depend on the codec used. *errors* may be given to define the error handling. It defaults to ``'strict'`` which causes a :exc:`ValueError` to be raised in case an encoding error occurs. @@ -264,12 +197,15 @@ utility functions: .. function:: EncodedFile(file, data_encoding, file_encoding=None, errors='strict') - Return a wrapped version of file which provides transparent encoding - translation. + Return a :class:`StreamRecoder` instance, a wrapped version of *file* + which provides transparent transcoding. The original file is closed + when the wrapped version is closed. - Bytes written to the wrapped file are interpreted according to the given - *data_encoding* and then written to the original file as bytes using the - *file_encoding*. + Data written to the wrapped file is decoded according to the given + *data_encoding* and then written to the original file as bytes using + *file_encoding*. Bytes read from the original file are decoded + according to *file_encoding*, and the result is encoded + using *data_encoding*. If *file_encoding* is not given, it defaults to *data_encoding*. @@ -281,14 +217,16 @@ utility functions: .. function:: iterencode(iterator, encoding, errors='strict', **kwargs) Uses an incremental encoder to iteratively encode the input provided by - *iterator*. This function is a :term:`generator`. *errors* (as well as any + *iterator*. This function is a :term:`generator`. + The *errors* argument (as well as any other keyword argument) is passed through to the incremental encoder. .. function:: iterdecode(iterator, encoding, errors='strict', **kwargs) Uses an incremental decoder to iteratively decode the input provided by - *iterator*. This function is a :term:`generator`. *errors* (as well as any + *iterator*. This function is a :term:`generator`. + The *errors* argument (as well as any other keyword argument) is passed through to the incremental decoder. @@ -307,9 +245,10 @@ and writing to platform dependent files: BOM_UTF32_BE BOM_UTF32_LE - These constants define various encodings of the Unicode byte order mark (BOM) - used in UTF-16 and UTF-32 data streams to indicate the byte order used in the - stream or file and in UTF-8 as a Unicode signature. :const:`BOM_UTF16` is either + These constants define various byte sequences, + being Unicode byte order marks (BOMs) for several encodings. They are + used in UTF-16 and UTF-32 data streams to indicate the byte order used, + and in UTF-8 as a Unicode signature. :const:`BOM_UTF16` is either :const:`BOM_UTF16_BE` or :const:`BOM_UTF16_LE` depending on the platform's native byte order, :const:`BOM` is an alias for :const:`BOM_UTF16`, :const:`BOM_LE` for :const:`BOM_UTF16_LE` and :const:`BOM_BE` for @@ -323,20 +262,26 @@ Codec Base Classes ------------------ The :mod:`codecs` module defines a set of base classes which define the -interface and can also be used to easily write your own codecs for use in -Python. +interfaces for working with codec objects, and can also be used as the basis +for custom codec implementations. Each codec has to define four interfaces to make it usable as codec in Python: stateless encoder, stateless decoder, stream reader and stream writer. The stream reader and writers typically reuse the stateless encoder/decoder to -implement the file protocols. +implement the file protocols. Codec authors also need to define how the +codec will handle encoding and decoding errors. -The :class:`Codec` class defines the interface for stateless encoders/decoders. -To simplify and standardize error handling, the :meth:`~Codec.encode` and -:meth:`~Codec.decode` methods may implement different error handling schemes by -providing the *errors* string argument. The following string values are defined -and implemented by all standard Python codecs: +.. _surrogateescape: +.. _error-handlers: + +Error Handlers +^^^^^^^^^^^^^^ + +To simplify and standardize error handling, +codecs may implement different error handling schemes by +accepting the *errors* string argument. The following string values are +defined and implemented by all standard Python codecs: .. tabularcolumns:: |l|L| @@ -344,36 +289,56 @@ and implemented by all standard Python codecs: | Value | Meaning | +=========================+===============================================+ | ``'strict'`` | Raise :exc:`UnicodeError` (or a subclass); | -| | this is the default. | +| | this is the default. Implemented in | +| | :func:`strict_errors`. | +-------------------------+-----------------------------------------------+ -| ``'ignore'`` | Ignore the character and continue with the | -| | next. | +| ``'ignore'`` | Ignore the malformed data and continue | +| | without further notice. Implemented in | +| | :func:`ignore_errors`. | ++-------------------------+-----------------------------------------------+ + +The following error handlers are only applicable to +:term:`text encodings <text encoding>`: + +-------------------------+-----------------------------------------------+ +| Value | Meaning | ++=========================+===============================================+ | ``'replace'`` | Replace with a suitable replacement | -| | character; Python will use the official | -| | U+FFFD REPLACEMENT CHARACTER for the built-in | -| | Unicode codecs on decoding and '?' on | -| | encoding. | +| | marker; Python will use the official | +| | ``U+FFFD`` REPLACEMENT CHARACTER for the | +| | built-in codecs on decoding, and '?' on | +| | encoding. Implemented in | +| | :func:`replace_errors`. | +-------------------------+-----------------------------------------------+ | ``'xmlcharrefreplace'`` | Replace with the appropriate XML character | -| | reference (only for encoding). | +| | reference (only for encoding). Implemented | +| | in :func:`xmlcharrefreplace_errors`. | +-------------------------+-----------------------------------------------+ -| ``'backslashreplace'`` | Replace with backslashed escape sequences | -| | (only for encoding). | +| ``'backslashreplace'`` | Replace with backslashed escape sequences. | +| | Implemented in | +| | :func:`backslashreplace_errors`. | +-------------------------+-----------------------------------------------+ -| ``'surrogateescape'`` | Replace byte with surrogate U+DCxx, as defined| -| | in :pep:`383`. | +| ``'namereplace'`` | Replace with ``\N{...}`` escape sequences | +| | (only for encoding). Implemented in | +| | :func:`namereplace_errors`. | ++-------------------------+-----------------------------------------------+ +| ``'surrogateescape'`` | On decoding, replace byte with individual | +| | surrogate code ranging from ``U+DC80`` to | +| | ``U+DCFF``. This code will then be turned | +| | back into the same byte when the | +| | ``'surrogateescape'`` error handler is used | +| | when encoding the data. (See :pep:`383` for | +| | more.) | +-------------------------+-----------------------------------------------+ -In addition, the following error handlers are specific to Unicode encoding -schemes: +In addition, the following error handler is specific to the given codecs: +-------------------+------------------------+-------------------------------------------+ -| Value | Codec | Meaning | +| Value | Codecs | Meaning | +===================+========================+===========================================+ |``'surrogatepass'``| utf-8, utf-16, utf-32, | Allow encoding and decoding of surrogate | -| | utf-16-be, utf-16-le, | codes in all the Unicode encoding schemes.| -| | utf-32-be, utf-32-le | | +| | utf-16-be, utf-16-le, | codes. These codecs normally treat the | +| | utf-32-be, utf-32-le | presence of surrogates as an error. | +-------------------+------------------------+-------------------------------------------+ .. versionadded:: 3.1 @@ -382,30 +347,115 @@ schemes: .. versionchanged:: 3.4 The ``'surrogatepass'`` error handlers now works with utf-16\* and utf-32\* codecs. -The set of allowed values can be extended via :meth:`register_error`. +.. versionadded:: 3.5 + The ``'namereplace'`` error handler. + +.. versionchanged:: 3.5 + The ``'backslashreplace'`` error handlers now works with decoding and + translating. + +The set of allowed values can be extended by registering a new named error +handler: + +.. function:: register_error(name, error_handler) + + Register the error handling function *error_handler* under the name *name*. + The *error_handler* argument will be called during encoding and decoding + in case of an error, when *name* is specified as the errors parameter. + + For encoding, *error_handler* will be called with a :exc:`UnicodeEncodeError` + instance, which contains information about the location of the error. The + error handler must either raise this or a different exception, or return a + tuple with a replacement for the unencodable part of the input and a position + where encoding should continue. The replacement may be either :class:`str` or + :class:`bytes`. If the replacement is bytes, the encoder will simply copy + them into the output buffer. If the replacement is a string, the encoder will + encode the replacement. Encoding continues on original input at the + specified position. Negative position values will be treated as being + relative to the end of the input string. If the resulting position is out of + bound an :exc:`IndexError` will be raised. + + Decoding and translating works similarly, except :exc:`UnicodeDecodeError` or + :exc:`UnicodeTranslateError` will be passed to the handler and that the + replacement from the error handler will be put into the output directly. + + +Previously registered error handlers (including the standard error handlers) +can be looked up by name: + +.. function:: lookup_error(name) + + Return the error handler previously registered under the name *name*. + + Raises a :exc:`LookupError` in case the handler cannot be found. + +The following standard error handlers are also made available as module level +functions: + +.. function:: strict_errors(exception) + + Implements the ``'strict'`` error handling: each encoding or + decoding error raises a :exc:`UnicodeError`. + + +.. function:: replace_errors(exception) + + Implements the ``'replace'`` error handling (for :term:`text encodings + <text encoding>` only): substitutes ``'?'`` for encoding errors + (to be encoded by the codec), and ``'\ufffd'`` (the Unicode replacement + character) for decoding errors. + + +.. function:: ignore_errors(exception) + + Implements the ``'ignore'`` error handling: malformed data is ignored and + encoding or decoding is continued without further notice. + + +.. function:: xmlcharrefreplace_errors(exception) + + Implements the ``'xmlcharrefreplace'`` error handling (for encoding with + :term:`text encodings <text encoding>` only): the + unencodable character is replaced by an appropriate XML character reference. + + +.. function:: backslashreplace_errors(exception) + + Implements the ``'backslashreplace'`` error handling (for + :term:`text encodings <text encoding>` only): malformed data is + replaced by a backslashed escape sequence. + +.. function:: namereplace_errors(exception) + + Implements the ``'namereplace'`` error handling (for encoding with + :term:`text encodings <text encoding>` only): the + unencodable character is replaced by a ``\N{...}`` escape sequence. + + .. versionadded:: 3.5 .. _codec-objects: -Codec Objects -^^^^^^^^^^^^^ +Stateless Encoding and Decoding +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The :class:`Codec` class defines these methods which also define the function -interfaces of the stateless encoder and decoder: +The base :class:`Codec` class defines these methods which also define the +function interfaces of the stateless encoder and decoder: .. method:: Codec.encode(input[, errors]) Encodes the object *input* and returns a tuple (output object, length consumed). - Encoding converts a string object to a bytes object using a particular + For instance, :term:`text encoding` converts + a string object to a bytes object using a particular character set encoding (e.g., ``cp1252`` or ``iso-8859-1``). - *errors* defines the error handling to apply. It defaults to ``'strict'`` - handling. + The *errors* argument defines the error handling to apply. + It defaults to ``'strict'`` handling. The method may not store state in the :class:`Codec` instance. Use - :class:`StreamCodec` for codecs which have to keep state in order to make - encoding/decoding efficient. + :class:`StreamWriter` for codecs which have to keep state in order to make + encoding efficient. The encoder must be able to handle zero length input and return an empty object of the output object type in this situation. @@ -414,22 +464,28 @@ interfaces of the stateless encoder and decoder: .. method:: Codec.decode(input[, errors]) Decodes the object *input* and returns a tuple (output object, length - consumed). Decoding converts a bytes object encoded using a particular + consumed). For instance, for a :term:`text encoding`, decoding converts + a bytes object encoded using a particular character set encoding to a string object. - *input* must be a bytes object or one which provides the read-only character + For text encodings and bytes-to-bytes codecs, + *input* must be a bytes object or one which provides the read-only buffer interface -- for example, buffer objects and memory mapped files. - *errors* defines the error handling to apply. It defaults to ``'strict'`` - handling. + The *errors* argument defines the error handling to apply. + It defaults to ``'strict'`` handling. The method may not store state in the :class:`Codec` instance. Use - :class:`StreamCodec` for codecs which have to keep state in order to make - encoding/decoding efficient. + :class:`StreamReader` for codecs which have to keep state in order to make + decoding efficient. The decoder must be able to handle zero length input and return an empty object of the output object type in this situation. + +Incremental Encoding and Decoding +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + The :class:`IncrementalEncoder` and :class:`IncrementalDecoder` classes provide the basic interface for incremental encoding and decoding. Encoding/decoding the input isn't done with one call to the stateless encoder/decoder function, but @@ -447,14 +503,14 @@ encoded/decoded with the stateless encoder/decoder. .. _incremental-encoder-objects: IncrementalEncoder Objects -^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~ The :class:`IncrementalEncoder` class is used for encoding an input in multiple steps. It defines the following methods which every incremental encoder must define in order to be compatible with the Python codec registry. -.. class:: IncrementalEncoder([errors]) +.. class:: IncrementalEncoder(errors='strict') Constructor for an :class:`IncrementalEncoder` instance. @@ -463,26 +519,14 @@ define in order to be compatible with the Python codec registry. the Python codec registry. The :class:`IncrementalEncoder` may implement different error handling schemes - by providing the *errors* keyword argument. These parameters are predefined: - - * ``'strict'`` Raise :exc:`ValueError` (or a subclass); this is the default. - - * ``'ignore'`` Ignore the character and continue with the next. - - * ``'replace'`` Replace with a suitable replacement character - - * ``'xmlcharrefreplace'`` Replace with the appropriate XML character reference - - * ``'backslashreplace'`` Replace with backslashed escape sequences. + by providing the *errors* keyword argument. See :ref:`error-handlers` for + possible values. The *errors* argument will be assigned to an attribute of the same name. Assigning to this attribute makes it possible to switch between different error handling strategies during the lifetime of the :class:`IncrementalEncoder` object. - The set of allowed values for the *errors* argument can be extended with - :func:`register_error`. - .. method:: encode(object[, final]) @@ -494,7 +538,8 @@ define in order to be compatible with the Python codec registry. .. method:: reset() Reset the encoder to the initial state. The output is discarded: call - ``.encode('', final=True)`` to reset the encoder and to get the output. + ``.encode(object, final=True)``, passing an empty byte or text string + if necessary, to reset the encoder and to get the output. .. method:: IncrementalEncoder.getstate() @@ -515,14 +560,14 @@ define in order to be compatible with the Python codec registry. .. _incremental-decoder-objects: IncrementalDecoder Objects -^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~ The :class:`IncrementalDecoder` class is used for decoding an input in multiple steps. It defines the following methods which every incremental decoder must define in order to be compatible with the Python codec registry. -.. class:: IncrementalDecoder([errors]) +.. class:: IncrementalDecoder(errors='strict') Constructor for an :class:`IncrementalDecoder` instance. @@ -531,22 +576,14 @@ define in order to be compatible with the Python codec registry. the Python codec registry. The :class:`IncrementalDecoder` may implement different error handling schemes - by providing the *errors* keyword argument. These parameters are predefined: - - * ``'strict'`` Raise :exc:`ValueError` (or a subclass); this is the default. - - * ``'ignore'`` Ignore the character and continue with the next. - - * ``'replace'`` Replace with a suitable replacement character. + by providing the *errors* keyword argument. See :ref:`error-handlers` for + possible values. The *errors* argument will be assigned to an attribute of the same name. Assigning to this attribute makes it possible to switch between different error handling strategies during the lifetime of the :class:`IncrementalDecoder` object. - The set of allowed values for the *errors* argument can be extended with - :func:`register_error`. - .. method:: decode(object[, final]) @@ -585,6 +622,10 @@ define in order to be compatible with the Python codec registry. returned by :meth:`getstate`. +Stream Encoding and Decoding +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + The :class:`StreamWriter` and :class:`StreamReader` classes provide generic working interfaces which can be used to implement new encoding submodules very easily. See :mod:`encodings.utf_8` for an example of how this is done. @@ -593,14 +634,14 @@ easily. See :mod:`encodings.utf_8` for an example of how this is done. .. _stream-writer-objects: StreamWriter Objects -^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~ The :class:`StreamWriter` class is a subclass of :class:`Codec` and defines the following methods which every stream writer must define in order to be compatible with the Python codec registry. -.. class:: StreamWriter(stream[, errors]) +.. class:: StreamWriter(stream, errors='strict') Constructor for a :class:`StreamWriter` instance. @@ -608,29 +649,17 @@ compatible with the Python codec registry. additional keyword arguments, but only the ones defined here are used by the Python codec registry. - *stream* must be a file-like object open for writing binary data. + The *stream* argument must be a file-like object open for writing + text or binary data, as appropriate for the specific codec. The :class:`StreamWriter` may implement different error handling schemes by - providing the *errors* keyword argument. These parameters are predefined: - - * ``'strict'`` Raise :exc:`ValueError` (or a subclass); this is the default. - - * ``'ignore'`` Ignore the character and continue with the next. - - * ``'replace'`` Replace with a suitable replacement character - - * ``'xmlcharrefreplace'`` Replace with the appropriate XML character reference - - * ``'backslashreplace'`` Replace with backslashed escape sequences. + providing the *errors* keyword argument. See :ref:`error-handlers` for + the standard error handlers the underlying stream codec may support. The *errors* argument will be assigned to an attribute of the same name. Assigning to this attribute makes it possible to switch between different error handling strategies during the lifetime of the :class:`StreamWriter` object. - The set of allowed values for the *errors* argument can be extended with - :func:`register_error`. - - .. method:: write(object) Writes the object's contents encoded to the stream. @@ -639,7 +668,8 @@ compatible with the Python codec registry. .. method:: writelines(list) Writes the concatenated list of strings to the stream (possibly by reusing - the :meth:`write` method). + the :meth:`write` method). The standard bytes-to-bytes codecs + do not support this method. .. method:: reset() @@ -658,14 +688,14 @@ all other methods and attributes from the underlying stream. .. _stream-reader-objects: StreamReader Objects -^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~ The :class:`StreamReader` class is a subclass of :class:`Codec` and defines the following methods which every stream reader must define in order to be compatible with the Python codec registry. -.. class:: StreamReader(stream[, errors]) +.. class:: StreamReader(stream, errors='strict') Constructor for a :class:`StreamReader` instance. @@ -673,16 +703,12 @@ compatible with the Python codec registry. additional keyword arguments, but only the ones defined here are used by the Python codec registry. - *stream* must be a file-like object open for reading (binary) data. + The *stream* argument must be a file-like object open for reading + text or binary data, as appropriate for the specific codec. The :class:`StreamReader` may implement different error handling schemes by - providing the *errors* keyword argument. These parameters are defined: - - * ``'strict'`` Raise :exc:`ValueError` (or a subclass); this is the default. - - * ``'ignore'`` Ignore the character and continue with the next. - - * ``'replace'`` Replace with a suitable replacement character. + providing the *errors* keyword argument. See :ref:`error-handlers` for + the standard error handlers the underlying stream codec may support. The *errors* argument will be assigned to an attribute of the same name. Assigning to this attribute makes it possible to switch between different error @@ -696,17 +722,20 @@ compatible with the Python codec registry. Decodes data from the stream and returns the resulting object. - *chars* indicates the number of characters to read from the - stream. :func:`read` will never return more than *chars* characters, but - it might return less, if there are not enough characters available. + The *chars* argument indicates the number of decoded + code points or bytes to return. The :func:`read` method will + never return more data than requested, but it might return less, + if there is not enough available. - *size* indicates the approximate maximum number of bytes to read from the - stream for decoding purposes. The decoder can modify this setting as + The *size* argument indicates the approximate maximum + number of encoded bytes or code points to read + for decoding. The decoder can modify this setting as appropriate. The default value -1 indicates to read and decode as much as - possible. *size* is intended to prevent having to decode huge files in - one step. + possible. This parameter is intended to + prevent having to decode huge files in one step. - *firstline* indicates that it would be sufficient to only return the first + The *firstline* flag indicates that + it would be sufficient to only return the first line, if there are decoding errors on later lines. The method should use a greedy read strategy meaning that it should read @@ -749,17 +778,13 @@ compatible with the Python codec registry. In addition to the above methods, the :class:`StreamReader` must also inherit all other methods and attributes from the underlying stream. -The next two base classes are included for convenience. They are not needed by -the codec registry, but may provide useful in practice. - - .. _stream-reader-writer: StreamReaderWriter Objects -^^^^^^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~~~~~~ -The :class:`StreamReaderWriter` allows wrapping streams which work in both read -and write modes. +The :class:`StreamReaderWriter` is a convenience class that allows wrapping +streams which work in both read and write modes. The design is such that one can use the factory functions returned by the :func:`lookup` function to construct the instance. @@ -780,9 +805,9 @@ methods and attributes from the underlying stream. .. _stream-recoder-objects: StreamRecoder Objects -^^^^^^^^^^^^^^^^^^^^^ +~~~~~~~~~~~~~~~~~~~~~ -The :class:`StreamRecoder` provide a frontend - backend view of encoding data +The :class:`StreamRecoder` translates data from one encoding to another, which is sometimes useful when dealing with different encoding environments. The design is such that one can use the factory functions returned by the @@ -792,22 +817,20 @@ The design is such that one can use the factory functions returned by the .. class:: StreamRecoder(stream, encode, decode, Reader, Writer, errors) Creates a :class:`StreamRecoder` instance which implements a two-way conversion: - *encode* and *decode* work on the frontend (the input to :meth:`read` and output - of :meth:`write`) while *Reader* and *Writer* work on the backend (reading and - writing to the stream). + *encode* and *decode* work on the frontend — the data visible to + code calling :meth:`read` and :meth:`write`, while *Reader* and *Writer* + work on the backend — the data in *stream*. - You can use these objects to do transparent direct recodings from e.g. Latin-1 + You can use these objects to do transparent transcodings from e.g. Latin-1 to UTF-8 and back. - *stream* must be a file-like object. + The *stream* argument must be a file-like object. - *encode*, *decode* must adhere to the :class:`Codec` interface. *Reader*, + The *encode* and *decode* arguments must + adhere to the :class:`Codec` interface. *Reader* and *Writer* must be factory functions or classes providing objects of the :class:`StreamReader` and :class:`StreamWriter` interface respectively. - *encode* and *decode* are needed for the frontend translation, *Reader* and - *Writer* for the backend translation. - Error handling is done in the same way as defined for the stream readers and writers. @@ -822,31 +845,34 @@ methods and attributes from the underlying stream. Encodings and Unicode --------------------- -Strings are stored internally as sequences of codepoints in range ``0 - 10FFFF`` -(see :pep:`393` for more details about the implementation). -Once a string object is used outside of CPU and memory, CPU endianness -and how these arrays are stored as bytes become an issue. Transforming a -string object into a sequence of bytes is called encoding and recreating the -string object from the sequence of bytes is known as decoding. There are many -different methods for how this transformation can be done (these methods are -also called encodings). The simplest method is to map the codepoints 0-255 to -the bytes ``0x0``-``0xff``. This means that a string object that contains -codepoints above ``U+00FF`` can't be encoded with this method (which is called -``'latin-1'`` or ``'iso-8859-1'``). :func:`str.encode` will raise a -:exc:`UnicodeEncodeError` that looks like this: ``UnicodeEncodeError: 'latin-1' -codec can't encode character '\u1234' in position 3: ordinal not in -range(256)``. +Strings are stored internally as sequences of code points in +range ``0x0``-``0x10FFFF``. (See :pep:`393` for +more details about the implementation.) +Once a string object is used outside of CPU and memory, endianness +and how these arrays are stored as bytes become an issue. As with other +codecs, serialising a string into a sequence of bytes is known as *encoding*, +and recreating the string from the sequence of bytes is known as *decoding*. +There are a variety of different text serialisation codecs, which are +collectivity referred to as :term:`text encodings <text encoding>`. + +The simplest text encoding (called ``'latin-1'`` or ``'iso-8859-1'``) maps +the code points 0-255 to the bytes ``0x0``-``0xff``, which means that a string +object that contains code points above ``U+00FF`` can't be encoded with this +codec. Doing so will raise a :exc:`UnicodeEncodeError` that looks +like the following (although the details of the error message may differ): +``UnicodeEncodeError: 'latin-1' codec can't encode character '\u1234' in +position 3: ordinal not in range(256)``. There's another group of encodings (the so called charmap encodings) that choose -a different subset of all Unicode code points and how these codepoints are +a different subset of all Unicode code points and how these code points are mapped to the bytes ``0x0``-``0xff``. To see how this is done simply open e.g. :file:`encodings/cp1252.py` (which is an encoding that is used primarily on Windows). There's a string constant with 256 characters that shows you which character is mapped to which byte value. -All of these encodings can only encode 256 of the 1114112 codepoints +All of these encodings can only encode 256 of the 1114112 code points defined in Unicode. A simple and straightforward way that can store each Unicode -code point, is to store each codepoint as four consecutive bytes. There are two +code point, is to store each code point as four consecutive bytes. There are two possibilities: store the bytes in big endian or in little endian order. These two encodings are called ``UTF-32-BE`` and ``UTF-32-LE`` respectively. Their disadvantage is that if e.g. you use ``UTF-32-BE`` on a little endian machine you @@ -971,6 +997,10 @@ particular, the following variants typically exist: +-----------------+--------------------------------+--------------------------------+ | cp037 | IBM037, IBM039 | English | +-----------------+--------------------------------+--------------------------------+ +| cp273 | 273, IBM273, csIBM273 | German | +| | | | +| | | .. versionadded:: 3.4 | ++-----------------+--------------------------------+--------------------------------+ | cp424 | EBCDIC-CP-HE, IBM424 | Hebrew | +-----------------+--------------------------------+--------------------------------+ | cp437 | 437, IBM437 | English | @@ -1118,6 +1148,8 @@ particular, the following variants typically exist: +-----------------+--------------------------------+--------------------------------+ | iso8859_10 | iso-8859-10, latin6, L6 | Nordic languages | +-----------------+--------------------------------+--------------------------------+ +| iso8859_11 | iso-8859-11, thai | Thai languages | ++-----------------+--------------------------------+--------------------------------+ | iso8859_13 | iso-8859-13, latin7, L7 | Baltic languages | +-----------------+--------------------------------+--------------------------------+ | iso8859_14 | iso-8859-14, latin8, L8 | Celtic languages | @@ -1130,8 +1162,16 @@ particular, the following variants typically exist: +-----------------+--------------------------------+--------------------------------+ | koi8_r | | Russian | +-----------------+--------------------------------+--------------------------------+ +| koi8_t | | Tajik | +| | | | +| | | .. versionadded:: 3.5 | ++-----------------+--------------------------------+--------------------------------+ | koi8_u | | Ukrainian | +-----------------+--------------------------------+--------------------------------+ +| kz1048 | kz_1048, strk1048_2002, rk1048 | Kazakh | +| | | | +| | | .. versionadded:: 3.5 | ++-----------------+--------------------------------+--------------------------------+ | mac_cyrillic | maccyrillic | Bulgarian, Byelorussian, | | | | Macedonian, Russian, Serbian | +-----------------+--------------------------------+--------------------------------+ @@ -1178,7 +1218,8 @@ particular, the following variants typically exist: .. versionchanged:: 3.4 The utf-16\* and utf-32\* encoders no longer allow surrogate code points - (U+D800--U+DFFF) to be encoded. The utf-32\* decoders no longer decode + (``U+D800``--``U+DFFF``) to be encoded. + The utf-32\* decoders no longer decode byte sequences that correspond to surrogate code points. @@ -1206,7 +1247,9 @@ encodings. +====================+=========+===========================+ | idna | | Implements :rfc:`3490`, | | | | see also | -| | | :mod:`encodings.idna` | +| | | :mod:`encodings.idna`. | +| | | Only ``errors='strict'`` | +| | | is supported. | +--------------------+---------+---------------------------+ | mbcs | dbcs | Windows only: Encode | | | | operand according to the | @@ -1214,31 +1257,44 @@ encodings. +--------------------+---------+---------------------------+ | palmos | | Encoding of PalmOS 3.5 | +--------------------+---------+---------------------------+ -| punycode | | Implements :rfc:`3492` | +| punycode | | Implements :rfc:`3492`. | +| | | Stateful codecs are not | +| | | supported. | +--------------------+---------+---------------------------+ -| raw_unicode_escape | | Produce a string that is | -| | | suitable as raw Unicode | -| | | literal in Python source | -| | | code | +| raw_unicode_escape | | Latin-1 encoding with | +| | | ``\uXXXX`` and | +| | | ``\UXXXXXXXX`` for other | +| | | code points. Existing | +| | | backslashes are not | +| | | escaped in any way. | +| | | It is used in the Python | +| | | pickle protocol. | +--------------------+---------+---------------------------+ | undefined | | Raise an exception for | -| | | all conversions. Can be | -| | | used as the system | -| | | encoding if no automatic | -| | | coercion between byte and | -| | | Unicode strings is | -| | | desired. | +| | | all conversions, even | +| | | empty strings. The error | +| | | handler is ignored. | +--------------------+---------+---------------------------+ -| unicode_escape | | Produce a string that is | -| | | suitable as Unicode | -| | | literal in Python source | -| | | code | +| unicode_escape | | Encoding suitable as the | +| | | contents of a Unicode | +| | | literal in ASCII-encoded | +| | | Python source code, | +| | | except that quotes are | +| | | not escaped. Decodes from | +| | | Latin-1 source code. | +| | | Beware that Python source | +| | | code actually uses UTF-8 | +| | | by default. | +--------------------+---------+---------------------------+ | unicode_internal | | Return the internal | | | | representation of the | -| | | operand | +| | | operand. Stateful codecs | +| | | are not supported. | | | | | | | | .. deprecated:: 3.3 | +| | | This representation is | +| | | obsoleted by | +| | | :pep:`393`. | +--------------------+---------+---------------------------+ .. _binary-transforms: @@ -1247,7 +1303,8 @@ Binary Transforms ^^^^^^^^^^^^^^^^^ The following codecs provide binary transforms: :term:`bytes-like object` -to :class:`bytes` mappings. +to :class:`bytes` mappings. They are not supported by :meth:`bytes.decode` +(which only produces :class:`str` output). .. tabularcolumns:: |l|L|L|L| @@ -1255,9 +1312,9 @@ to :class:`bytes` mappings. +----------------------+------------------+------------------------------+------------------------------+ | Codec | Aliases | Purpose | Encoder / decoder | +======================+==================+==============================+==============================+ -| base64_codec [#b64]_ | base64, base_64 | Convert operand to MIME | :meth:`base64.b64encode` / | -| | | base64 (the result always | :meth:`base64.b64decode` | -| | | includes a trailing | | +| base64_codec [#b64]_ | base64, base_64 | Convert operand to multiline | :meth:`base64.encodebytes` / | +| | | MIME base64 (the result | :meth:`base64.decodebytes` | +| | | always includes a trailing | | | | | ``'\n'``) | | | | | | | | | | .. versionchanged:: 3.4 | | @@ -1269,14 +1326,14 @@ to :class:`bytes` mappings. | bz2_codec | bz2 | Compress the operand | :meth:`bz2.compress` / | | | | using bz2 | :meth:`bz2.decompress` | +----------------------+------------------+------------------------------+------------------------------+ -| hex_codec | hex | Convert operand to | :meth:`base64.b16encode` / | -| | | hexadecimal | :meth:`base64.b16decode` | +| hex_codec | hex | Convert operand to | :meth:`binascii.b2a_hex` / | +| | | hexadecimal | :meth:`binascii.a2b_hex` | | | | representation, with two | | | | | digits per byte | | +----------------------+------------------+------------------------------+------------------------------+ -| quopri_codec | quopri, | Convert operand to MIME | :meth:`quopri.encodestring` /| -| | quotedprintable, | quoted printable | :meth:`quopri.decodestring` | -| | quoted_printable | | | +| quopri_codec | quopri, | Convert operand to MIME | :meth:`quopri.encode` with | +| | quotedprintable, | quoted printable | ``quotetabs=True`` / | +| | quoted_printable | | :meth:`quopri.decode` | +----------------------+------------------+------------------------------+------------------------------+ | uu_codec | uu | Convert the operand using | :meth:`uu.encode` / | | | | uuencode | :meth:`uu.decode` | @@ -1302,7 +1359,8 @@ Text Transforms ^^^^^^^^^^^^^^^ The following codec provides a text transform: a :class:`str` to :class:`str` -mapping. +mapping. It is not supported by :meth:`str.encode` (which only produces +:class:`bytes` output). .. tabularcolumns:: |l|l|L| @@ -1414,4 +1472,3 @@ This module implements a variant of the UTF-8 codec: On encoding a UTF-8 encoded BOM will be prepended to the UTF-8 encoded bytes. For the stateful encoder this is only done once (on the first write to the byte stream). For decoding an optional UTF-8 encoded BOM at the start of the data will be skipped. - diff --git a/Doc/library/collections.abc.rst b/Doc/library/collections.abc.rst index 356f47332f67..d9b93ad26273 100644 --- a/Doc/library/collections.abc.rst +++ b/Doc/library/collections.abc.rst @@ -33,13 +33,14 @@ The collections module offers the following :term:`ABCs <abstract base class>`: .. tabularcolumns:: |l|L|L|L| -========================= ===================== ====================== ==================================================== +========================== ====================== ======================= ==================================================== ABC Inherits from Abstract Methods Mixin Methods -========================= ===================== ====================== ==================================================== +========================== ====================== ======================= ==================================================== :class:`Container` ``__contains__`` :class:`Hashable` ``__hash__`` :class:`Iterable` ``__iter__`` :class:`Iterator` :class:`Iterable` ``__next__`` ``__iter__`` +:class:`Generator` :class:`Iterator` ``send``, ``throw`` ``close``, ``__iter__``, ``__next__`` :class:`Sized` ``__len__`` :class:`Callable` ``__call__`` @@ -80,7 +81,11 @@ ABC Inherits from Abstract Methods Mixin :class:`KeysView` :class:`MappingView`, ``__contains__``, :class:`Set` ``__iter__`` :class:`ValuesView` :class:`MappingView` ``__contains__``, ``__iter__`` -========================= ===================== ====================== ==================================================== +:class:`Awaitable` ``__await__`` +:class:`Coroutine` :class:`Awaitable` ``send``, ``throw`` ``close`` +:class:`AsyncIterable` ``__aiter__`` +:class:`AsyncIterator` :class:`AsyncIterable` ``__anext__`` ``__aiter__`` +========================== ====================== ======================= ==================================================== .. class:: Container @@ -102,11 +107,34 @@ ABC Inherits from Abstract Methods Mixin :meth:`~iterator.__next__` methods. See also the definition of :term:`iterator`. +.. class:: Generator + + ABC for generator classes that implement the protocol defined in + :pep:`342` that extends iterators with the :meth:`~generator.send`, + :meth:`~generator.throw` and :meth:`~generator.close` methods. + See also the definition of :term:`generator`. + + .. versionadded:: 3.5 + .. class:: Sequence MutableSequence ABCs for read-only and mutable :term:`sequences <sequence>`. + Implementation note: Some of the mixin methods, such as + :meth:`__iter__`, :meth:`__reversed__` and :meth:`index`, make + repeated calls to the underlying :meth:`__getitem__` method. + Consequently, if :meth:`__getitem__` is implemented with constant + access speed, the mixin methods will have linear performance; + however, if the underlying method is linear (as it would be with a + linked list), the mixins will have quadratic performance and will + likely need to be overridden. + + .. versionchanged:: 3.5 + The index() method added support for *stop* and *start* + arguments. + + .. class:: Set MutableSet @@ -122,7 +150,57 @@ ABC Inherits from Abstract Methods Mixin KeysView ValuesView - ABCs for mapping, items, keys, and values :term:`views <view>`. + ABCs for mapping, items, keys, and values :term:`views <dictionary view>`. + +.. class:: Awaitable + + ABC for :term:`awaitable` objects, which can be used in :keyword:`await` + expressions. Custom implementations must provide the :meth:`__await__` + method. + + :term:`Coroutine` objects and instances of the + :class:`~collections.abc.Coroutine` ABC are all instances of this ABC. + + .. note:: + In CPython, generator-based coroutines (generators decorated with + :func:`types.coroutine` or :func:`asyncio.coroutine`) are + *awaitables*, even though they do not have an :meth:`__await__` method. + Using ``isinstance(gencoro, Awaitable)`` for them will return ``False``. + Use :func:`inspect.isawaitable` to detect them. + + .. versionadded:: 3.5 + +.. class:: Coroutine + + ABC for coroutine compatible classes. These implement the + following methods, defined in :ref:`coroutine-objects`: + :meth:`~coroutine.send`, :meth:`~coroutine.throw`, and + :meth:`~coroutine.close`. Custom implementations must also implement + :meth:`__await__`. All :class:`Coroutine` instances are also instances of + :class:`Awaitable`. See also the definition of :term:`coroutine`. + + .. note:: + In CPython, generator-based coroutines (generators decorated with + :func:`types.coroutine` or :func:`asyncio.coroutine`) are + *awaitables*, even though they do not have an :meth:`__await__` method. + Using ``isinstance(gencoro, Coroutine)`` for them will return ``False``. + Use :func:`inspect.isawaitable` to detect them. + + .. versionadded:: 3.5 + +.. class:: AsyncIterable + + ABC for classes that provide ``__aiter__`` method. See also the + definition of :term:`asynchronous iterable`. + + .. versionadded:: 3.5 + +.. class:: AsyncIterator + + ABC for classes that provide ``__aiter__`` and ``__anext__`` + methods. See also the definition of :term:`asynchronous iterator`. + + .. versionadded:: 3.5 These ABCs allow us to ask classes or instances if they provide @@ -134,7 +212,7 @@ particular functionality, for example:: Several of the ABCs are also useful as mixins that make it easier to develop classes supporting container APIs. For example, to write a class supporting -the full :class:`Set` API, it only necessary to supply the three underlying +the full :class:`Set` API, it is only necessary to supply the three underlying abstract methods: :meth:`__contains__`, :meth:`__iter__`, and :meth:`__len__`. The ABC supplies the remaining methods such as :meth:`__and__` and :meth:`isdisjoint`:: @@ -173,13 +251,13 @@ Notes on using :class:`Set` and :class:`MutableSet` as a mixin: (2) To override the comparisons (presumably for speed, as the - semantics are fixed), redefine :meth:`__le__` and + semantics are fixed), redefine :meth:`__le__` and :meth:`__ge__`, then the other operations will automatically follow suit. (3) The :class:`Set` mixin provides a :meth:`_hash` method to compute a hash value for the set; however, :meth:`__hash__` is not defined because not all sets - are hashable or immutable. To add set hashabilty using mixins, + are hashable or immutable. To add set hashability using mixins, inherit from both :meth:`Set` and :meth:`Hashable`, then define ``__hash__ = Set._hash``. diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index 80c6c767c6da..2e2e16f36d6b 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -109,7 +109,7 @@ The class can be used to simulate nested scopes and is useful in templating. writing to any mapping in the chain. * Django's `Context class - <http://code.djangoproject.com/browser/django/trunk/django/template/context.py>`_ + <https://github.com/django/django/blob/master/django/template/context.py>`_ for templating is a read-only chain of mappings. It also features pushing and popping of contexts similar to the :meth:`~collections.ChainMap.new_child` method and the @@ -193,7 +193,7 @@ updates keys found deeper in the chain:: return raise KeyError(key) - >>> d = DeepChainMap({'zebra': 'black'}, {'elephant' : 'blue'}, {'lion' : 'yellow'}) + >>> d = DeepChainMap({'zebra': 'black'}, {'elephant': 'blue'}, {'lion': 'yellow'}) >>> d['lion'] = 'orange' # update an existing key two levels down >>> d['snake'] = 'red' # new keys get added to the topmost dict >>> del d['elephant'] # remove an existing key one level down @@ -268,9 +268,9 @@ For example:: .. method:: most_common([n]) Return a list of the *n* most common elements and their counts from the - most common to the least. If *n* is not specified, :func:`most_common` - returns *all* elements in the counter. Elements with equal counts are - ordered arbitrarily: + most common to the least. If *n* is omitted or ``None``, + :func:`most_common` returns *all* elements in the counter. + Elements with equal counts are ordered arbitrarily: >>> Counter('abracadabra').most_common(3) [('a', 5), ('r', 2), ('b', 2)] @@ -333,7 +333,7 @@ counts, but the output will exclude results with counts of zero or less. >>> c | d # union: max(c[x], d[x]) Counter({'a': 3, 'b': 2}) -Unary addition and substraction are shortcuts for adding an empty counter +Unary addition and subtraction are shortcuts for adding an empty counter or subtracting from an empty counter. >>> c = Counter(a=2, b=-4) @@ -387,7 +387,7 @@ or subtracting from an empty counter. Section 4.6.3, Exercise 19*. * To enumerate all distinct multisets of a given size over a given set of - elements, see :func:`itertools.combinations_with_replacement`. + elements, see :func:`itertools.combinations_with_replacement`: map(Counter, combinations_with_replacement('ABC', 2)) --> AA AB AC BB BC CC @@ -437,6 +437,13 @@ or subtracting from an empty counter. Remove all elements from the deque leaving it with length 0. + .. method:: copy() + + Create a shallow copy of the deque. + + .. versionadded:: 3.5 + + .. method:: count(x) Count the number of deque elements equal to *x*. @@ -457,6 +464,22 @@ or subtracting from an empty counter. elements in the iterable argument. + .. method:: index(x[, start[, stop]]) + + Return the position of *x* in the deque (at or after index *start* + and before index *stop*). Returns the first match or raises + :exc:`ValueError` if not found. + + .. versionadded:: 3.5 + + + .. method:: insert(i, x) + + Insert *x* into the deque at position *i*. + + .. versionadded:: 3.5 + + .. method:: pop() Remove and return an element from the right side of the deque. If no @@ -471,7 +494,7 @@ or subtracting from an empty counter. .. method:: remove(value) - Removed the first occurrence of *value*. If not found, raises a + Remove the first occurrence of *value*. If not found, raises a :exc:`ValueError`. @@ -504,6 +527,9 @@ the :keyword:`in` operator, and subscript references such as ``d[-1]``. Indexed access is O(1) at both ends but slows to O(n) in the middle. For fast random access, use lists instead. +Starting in version 3.5, deques support ``__add__()``, ``__mul__()``, +and ``__imul__()``. + Example: .. doctest:: @@ -816,10 +842,10 @@ field names, the method and attribute names start with an underscore. .. method:: somenamedtuple._asdict() Return a new :class:`OrderedDict` which maps field names to their corresponding - values. Note, this method is no longer needed now that the same effect can - be achieved by using the built-in :func:`vars` function:: + values:: - >>> vars(p) + >>> p = Point(x=11, y=22) + >>> p._asdict() OrderedDict([('x', 11), ('y', 22)]) .. versionchanged:: 3.1 @@ -899,6 +925,15 @@ create a new named tuple type from the :attr:`_fields` attribute: >>> Point3D = namedtuple('Point3D', Point._fields + ('z',)) +Docstrings can be customized by making direct assignments to the ``__doc__`` +fields: + + >>> Book = namedtuple('Book', ['id', 'title', 'authors']) + >>> Book.__doc__ = 'Hardcover book in active collection' + >>> Book.id.__doc__ = '13-digit ISBN' + >>> Book.title.__doc__ = 'Title of first printing' + >>> Book.author.__doc__ = 'List of authors sorted by last name' + Default values can be implemented by using :meth:`_replace` to customize a prototype instance: @@ -908,13 +943,17 @@ customize a prototype instance: >>> janes_account = default_account._replace(owner='Jane') Enumerated constants can be implemented with named tuples, but it is simpler -and more efficient to use a simple class declaration: +and more efficient to use a simple :class:`~enum.Enum`: >>> Status = namedtuple('Status', 'open pending closed')._make(range(3)) >>> Status.open, Status.pending, Status.closed (0, 1, 2) - >>> class Status: - open, pending, closed = range(3) + >>> from enum import Enum + >>> class Status(Enum): + ... open, pending, closed = range(3) + + +.. seealso:: * `Recipe for named tuple abstract base class with a metaclass mix-in <http://code.activestate.com/recipes/577629-namedtupleabc-abstract-base-class-mix-in-for-named/>`_ @@ -923,6 +962,9 @@ and more efficient to use a simple class declaration: constructor that is convenient for use cases where named tuples are being subclassed. + * :meth:`types.SimpleNamespace` for a mutable namespace based on an underlying + dictionary instead of a tuple. + :class:`OrderedDict` objects ---------------------------- @@ -976,14 +1018,17 @@ anywhere a regular dictionary is used. The :class:`OrderedDict` constructor and :meth:`update` method both accept keyword arguments, but their order is lost because Python's function call -semantics pass-in keyword arguments using a regular unordered dictionary. +semantics pass in keyword arguments using a regular unordered dictionary. +.. versionchanged:: 3.5 + The items, keys, and values :term:`views <dictionary view>` + of :class:`OrderedDict` now support reverse iteration using :func:`reversed`. :class:`OrderedDict` Examples and Recipes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Since an ordered dictionary remembers its insertion order, it can be used -in conjuction with sorting to make a sorted dictionary:: +in conjunction with sorting to make a sorted dictionary:: >>> # regular unsorted dictionary >>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2} @@ -1085,7 +1130,7 @@ to work with because the underlying list is accessible as an attribute. A real :class:`list` object used to store the contents of the :class:`UserList` class. -**Subclassing requirements:** Subclasses of :class:`UserList` are expect to +**Subclassing requirements:** Subclasses of :class:`UserList` are expected to offer a constructor which can be called with either no arguments or one argument. List operations which return a new sequence attempt to create an instance of the actual implementation class. To do so, it assumes that the @@ -1115,3 +1160,7 @@ attribute. be an instance of :class:`bytes`, :class:`str`, :class:`UserString` (or a subclass) or an arbitrary sequence which can be converted into a string using the built-in :func:`str` function. + + .. versionchanged:: 3.5 + New methods ``__getnewargs__``, ``__rmod__``, ``casefold``, + ``format_map``, ``isprintable``, and ``maketrans``. diff --git a/Doc/library/compileall.rst b/Doc/library/compileall.rst index b12c2173c030..c5736f204399 100644 --- a/Doc/library/compileall.rst +++ b/Doc/library/compileall.rst @@ -4,6 +4,10 @@ .. module:: compileall :synopsis: Tools for byte-compiling all Python source files in a directory tree. +**Source code:** :source:`Lib/compileall.py` + +-------------- + This module provides some utility functions to support installing Python libraries. These functions compile Python source files in a directory tree. @@ -20,7 +24,8 @@ compile Python sources. .. program:: compileall -.. cmdoption:: [directory|file]... +.. cmdoption:: directory ... + file ... Positional arguments are files to compile or directories that contain source files, traversed recursively. If no argument is given, behave as if @@ -37,7 +42,8 @@ compile Python sources. .. cmdoption:: -q - Do not print the list of files compiled, print only error messages. + Do not print the list of files compiled. If passed once, error messages will + still be printed. If passed twice (``-qq``), all output is suppressed. .. cmdoption:: -d destdir @@ -65,9 +71,28 @@ compile Python sources. is to write files to their :pep:`3147` locations and names, which allows byte-code files from multiple versions of Python to coexist. +.. cmdoption:: -r + + Control the maximum recursion level for subdirectories. + If this is given, then ``-l`` option will not be taken into account. + :program:`python -m compileall <directory> -r 0` is equivalent to + :program:`python -m compileall <directory> -l`. + +.. cmdoption:: -j N + + Use *N* workers to compile the files within the given directory. + If ``0`` is used, then the result of :func:`os.cpu_count()` + will be used. + .. versionchanged:: 3.2 Added the ``-i``, ``-b`` and ``-h`` options. +.. versionchanged:: 3.5 + Added the ``-j``, ``-r``, and ``-qq`` options. ``-q`` option + was changed to a multilevel value. ``-b`` will always produce a + byte-code file ending in ``.pyc``, never ``.pyo``. + + There is no command-line option to control the optimization level used by the :func:`compile` function, because the Python interpreter itself already provides the option: :program:`python -O -m compileall`. @@ -75,7 +100,7 @@ provides the option: :program:`python -O -m compileall`. Public functions ---------------- -.. function:: compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, quiet=False, legacy=False, optimize=-1) +.. function:: compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, workers=1) Recursively descend the directory tree named by *dir*, compiling all :file:`.py` files along the way. @@ -96,8 +121,9 @@ Public functions file considered for compilation, and if it returns a true value, the file is skipped. - If *quiet* is true, nothing is printed to the standard output unless errors - occur. + If *quiet* is ``False`` or ``0`` (the default), the filenames and other + information are printed to standard out. Set to ``1``, only errors are + printed. Set to ``2``, all output is suppressed. If *legacy* is true, byte-code files are written to their legacy locations and names, which may overwrite byte-code files created by another version of @@ -108,11 +134,26 @@ Public functions *optimize* specifies the optimization level for the compiler. It is passed to the built-in :func:`compile` function. + The argument *workers* specifies how many workers are used to + compile files in parallel. The default is to not use multiple workers. + If the platform can't use multiple workers and *workers* argument is given, + then sequential compilation will be used as a fallback. If *workers* is + lower than ``0``, a :exc:`ValueError` will be raised. + .. versionchanged:: 3.2 Added the *legacy* and *optimize* parameter. + .. versionchanged:: 3.5 + Added the *workers* parameter. + + .. versionchanged:: 3.5 + *quiet* parameter was changed to a multilevel value. -.. function:: compile_file(fullname, ddir=None, force=False, rx=None, quiet=False, legacy=False, optimize=-1) + .. versionchanged:: 3.5 + The *legacy* parameter only writes out ``.pyc`` files, not ``.pyo`` files + no matter what the value of *optimize* is. + +.. function:: compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1) Compile the file with path *fullname*. @@ -126,8 +167,9 @@ Public functions file being compiled, and if it returns a true value, the file is not compiled and ``True`` is returned. - If *quiet* is true, nothing is printed to the standard output unless errors - occur. + If *quiet* is ``False`` or ``0`` (the default), the filenames and other + information are printed to standard out. Set to ``1``, only errors are + printed. Set to ``2``, all output is suppressed. If *legacy* is true, byte-code files are written to their legacy locations and names, which may overwrite byte-code files created by another version of @@ -140,8 +182,14 @@ Public functions .. versionadded:: 3.2 + .. versionchanged:: 3.5 + *quiet* parameter was changed to a multilevel value. + + .. versionchanged:: 3.5 + The *legacy* parameter only writes out ``.pyc`` files, not ``.pyo`` files + no matter what the value of *optimize* is. -.. function:: compile_path(skip_curdir=True, maxlevels=0, force=False, legacy=False, optimize=-1) +.. function:: compile_path(skip_curdir=True, maxlevels=0, force=False, quiet=0, legacy=False, optimize=-1) Byte-compile all the :file:`.py` files found along ``sys.path``. If *skip_curdir* is true (the default), the current directory is not included @@ -152,6 +200,12 @@ Public functions .. versionchanged:: 3.2 Added the *legacy* and *optimize* parameter. + .. versionchanged:: 3.5 + *quiet* parameter was changed to a multilevel value. + + .. versionchanged:: 3.5 + The *legacy* parameter only writes out ``.pyc`` files, not ``.pyo`` files + no matter what the value of *optimize* is. To force a recompile of all the :file:`.py` files in the :file:`Lib/` subdirectory and all its subdirectories:: diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst index 93538e4a7375..9ac617117f44 100644 --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -38,7 +38,7 @@ Executor Objects future = executor.submit(pow, 323, 1235) print(future.result()) - .. method:: map(func, *iterables, timeout=None) + .. method:: map(func, *iterables, timeout=None, chunksize=1) Equivalent to :func:`map(func, *iterables) <map>` except *func* is executed asynchronously and several calls to *func* may be made concurrently. The @@ -48,7 +48,16 @@ Executor Objects *timeout* can be an int or a float. If *timeout* is not specified or ``None``, there is no limit to the wait time. If a call raises an exception, then that exception will be raised when its value is - retrieved from the iterator. + retrieved from the iterator. When using :class:`ProcessPoolExecutor`, this + method chops *iterables* into a number of chunks which it submits to the + pool as separate tasks. The (approximate) size of these chunks can be + specified by setting *chunksize* to a positive integer. For very long + iterables, using a large value for *chunksize* can significantly improve + performance compared to the default size of 1. With :class:`ThreadPoolExecutor`, + *chunksize* has no effect. + + .. versionchanged:: 3.5 + Added the *chunksize* argument. .. method:: shutdown(wait=True) @@ -75,7 +84,7 @@ Executor Objects e.submit(shutil.copy, 'src1.txt', 'dest1.txt') e.submit(shutil.copy, 'src2.txt', 'dest2.txt') e.submit(shutil.copy, 'src3.txt', 'dest3.txt') - e.submit(shutil.copy, 'src3.txt', 'dest4.txt') + e.submit(shutil.copy, 'src4.txt', 'dest4.txt') ThreadPoolExecutor @@ -115,11 +124,19 @@ And:: executor.submit(wait_on_future) -.. class:: ThreadPoolExecutor(max_workers) +.. class:: ThreadPoolExecutor(max_workers=None) An :class:`Executor` subclass that uses a pool of at most *max_workers* threads to execute calls asynchronously. + .. versionchanged:: 3.5 + If *max_workers* is ``None`` or + not given, it will default to the number of processors on the machine, + multiplied by ``5``, assuming that :class:`ThreadPoolExecutor` is often + used to overlap I/O instead of CPU work and the number of workers + should be higher than the number of workers + for :class:`ProcessPoolExecutor`. + .. _threadpoolexecutor-example: @@ -138,8 +155,8 @@ ThreadPoolExecutor Example # Retrieve a single page and report the url and contents def load_url(http://github.com/url,%20timeout): - conn = urllib.request.urlopen(url, timeout=timeout) - return conn.readall() + with urllib.request.urlopen(url, timeout=timeout) as conn: + return conn.read() # We can use a with statement to ensure threads are cleaned up promptly with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: @@ -175,6 +192,8 @@ to a :class:`ProcessPoolExecutor` will result in deadlock. An :class:`Executor` subclass that executes calls asynchronously using a pool of at most *max_workers* processes. If *max_workers* is ``None`` or not given, it will default to the number of processors on the machine. + If *max_workers* is lower or equal to ``0``, then a :exc:`ValueError` + will be raised. .. versionchanged:: 3.3 When one of the worker processes terminates abruptly, a @@ -371,7 +390,8 @@ Module Functions Returns an iterator over the :class:`Future` instances (possibly created by different :class:`Executor` instances) given by *fs* that yields futures as - they complete (finished or were cancelled). Any futures that completed + they complete (finished or were cancelled). Any futures given by *fs* that + are duplicated will be returned once. Any futures that completed before :func:`as_completed` is called will be yielded first. The returned iterator raises a :exc:`TimeoutError` if :meth:`~iterator.__next__` is called and the result isn't available after *timeout* seconds from the @@ -390,6 +410,8 @@ Module Functions Exception classes ----------------- +.. currentmodule:: concurrent.futures.process + .. exception:: BrokenProcessPool Derived from :exc:`RuntimeError`, this exception class is raised when diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index 024d27cb84dd..c9187a3441a7 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -11,6 +11,8 @@ .. sectionauthor:: Christopher G. Petrilli <petrilli@amber.org> .. sectionauthor:: Łukasz Langa <lukasz@langa.pl> +**Source code:** :source:`Lib/configparser.py` + .. index:: pair: .ini; file pair: configuration; file @@ -142,12 +144,13 @@ datatypes, you should convert on your own: >>> float(topsecret['CompressionLevel']) 9.0 -Extracting Boolean values is not that simple, though. Passing the value -to ``bool()`` would do no good since ``bool('False')`` is still -``True``. This is why config parsers also provide :meth:`getboolean`. -This method is case-insensitive and recognizes Boolean values from -``'yes'``/``'no'``, ``'on'``/``'off'`` and ``'1'``/``'0'`` [1]_. -For example: +Since this task is so common, config parsers provide a range of handy getter +methods to handle integers, floats and booleans. The last one is the most +interesting because simply passing the value to ``bool()`` would do no good +since ``bool('False')`` is still ``True``. This is why config parsers also +provide :meth:`getboolean`. This method is case-insensitive and recognizes +Boolean values from ``'yes'``/``'no'``, ``'on'``/``'off'``, +``'true'``/``'false'`` and ``'1'``/``'0'`` [1]_. For example: .. doctest:: @@ -159,10 +162,8 @@ For example: True Apart from :meth:`getboolean`, config parsers also provide equivalent -:meth:`getint` and :meth:`getfloat` methods, but these are far less -useful since conversion using :func:`int` and :func:`float` is -sufficient for these types. - +:meth:`getint` and :meth:`getfloat` methods. You can register your own +converters and customize the provided ones. [1]_ Fallback Values --------------- @@ -317,11 +318,11 @@ from ``get()`` calls. .. class:: ExtendedInterpolation() An alternative handler for interpolation which implements a more advanced - syntax, used for instance in ``zc.buildout``. Extended interpolation is + syntax, used for instance in ``zc.buildout``. Extended interpolation is using ``${section:option}`` to denote a value from a foreign section. - Interpolation can span multiple levels. For convenience, if the ``section:`` - part is omitted, interpolation defaults to the current section (and possibly - the default values from the special section). + Interpolation can span multiple levels. For convenience, if the + ``section:`` part is omitted, interpolation defaults to the current section + (and possibly the default values from the special section). For example, the configuration specified above with basic interpolation, would look like this with extended interpolation: @@ -386,7 +387,7 @@ However, there are a few differences that should be taken into account: * All sections include ``DEFAULTSECT`` values as well which means that ``.clear()`` on a section may not leave the section visibly empty. This is because default values cannot be deleted from the section (because technically - they are not there). If they are overriden in the section, deleting causes + they are not there). If they are overridden in the section, deleting causes the default value to be visible again. Trying to delete a default value causes a ``KeyError``. @@ -399,13 +400,13 @@ However, there are a few differences that should be taken into account: * ``parser.popitem()`` never returns it. * ``parser.get(section, option, **kwargs)`` - the second argument is **not** - a fallback value. Note however that the section-level ``get()`` methods are + a fallback value. Note however that the section-level ``get()`` methods are compatible both with the mapping protocol and the classic configparser API. * ``parser.items()`` is compatible with the mapping protocol (returns a list of *section_name*, *section_proxy* pairs including the DEFAULTSECT). However, this method can also be invoked with arguments: ``parser.items(section, raw, - vars)``. The latter call returns a list of *option*, *value* pairs for + vars)``. The latter call returns a list of *option*, *value* pairs for a specified ``section``, with all interpolations expanded (unless ``raw=True`` is provided). @@ -539,9 +540,9 @@ the :meth:`__init__` options: * *delimiters*, default value: ``('=', ':')`` - Delimiters are substrings that delimit keys from values within a section. The - first occurrence of a delimiting substring on a line is considered a delimiter. - This means values (but not keys) can contain the delimiters. + Delimiters are substrings that delimit keys from values within a section. + The first occurrence of a delimiting substring on a line is considered + a delimiter. This means values (but not keys) can contain the delimiters. See also the *space_around_delimiters* argument to :meth:`ConfigParser.write`. @@ -553,7 +554,7 @@ the :meth:`__init__` options: Comment prefixes are strings that indicate the start of a valid comment within a config file. *comment_prefixes* are used only on otherwise empty lines (optionally indented) whereas *inline_comment_prefixes* can be used after - every valid value (e.g. section names, options and empty lines as well). By + every valid value (e.g. section names, options and empty lines as well). By default inline comments are disabled and ``'#'`` and ``';'`` are used as prefixes for whole line comments. @@ -563,10 +564,10 @@ the :meth:`__init__` options: Please note that config parsers don't support escaping of comment prefixes so using *inline_comment_prefixes* may prevent users from specifying option - values with characters used as comment prefixes. When in doubt, avoid setting - *inline_comment_prefixes*. In any circumstances, the only way of storing - comment prefix characters at the beginning of a line in multiline values is to - interpolate the prefix, for example:: + values with characters used as comment prefixes. When in doubt, avoid + setting *inline_comment_prefixes*. In any circumstances, the only way of + storing comment prefix characters at the beginning of a line in multiline + values is to interpolate the prefix, for example:: >>> from configparser import ConfigParser, ExtendedInterpolation >>> parser = ConfigParser(interpolation=ExtendedInterpolation()) @@ -611,7 +612,7 @@ the :meth:`__init__` options: When set to ``True``, the parser will not allow for any section or option duplicates while reading from a single source (using :meth:`read_file`, - :meth:`read_string` or :meth:`read_dict`). It is recommended to use strict + :meth:`read_string` or :meth:`read_dict`). It is recommended to use strict parsers in new applications. .. versionchanged:: 3.2 @@ -646,12 +647,12 @@ the :meth:`__init__` options: The convention of allowing a special section of default values for other sections or interpolation purposes is a powerful concept of this library, - letting users create complex declarative configurations. This section is + letting users create complex declarative configurations. This section is normally called ``"DEFAULT"`` but this can be customized to point to any - other valid section name. Some typical values include: ``"general"`` or - ``"common"``. The name provided is used for recognizing default sections when - reading from any source and is used when writing configuration back to - a file. Its current value can be retrieved using the + other valid section name. Some typical values include: ``"general"`` or + ``"common"``. The name provided is used for recognizing default sections + when reading from any source and is used when writing configuration back to + a file. Its current value can be retrieved using the ``parser_instance.default_section`` attribute and may be modified at runtime (i.e. to convert files from one format to another). @@ -660,14 +661,30 @@ the :meth:`__init__` options: Interpolation behaviour may be customized by providing a custom handler through the *interpolation* argument. ``None`` can be used to turn off interpolation completely, ``ExtendedInterpolation()`` provides a more - advanced variant inspired by ``zc.buildout``. More on the subject in the + advanced variant inspired by ``zc.buildout``. More on the subject in the `dedicated documentation section <#interpolation-of-values>`_. :class:`RawConfigParser` has a default value of ``None``. +* *converters*, default value: not set + + Config parsers provide option value getters that perform type conversion. By + default :meth:`getint`, :meth:`getfloat`, and :meth:`getboolean` are + implemented. Should other getters be desirable, users may define them in + a subclass or pass a dictionary where each key is a name of the converter and + each value is a callable implementing said conversion. For instance, passing + ``{'decimal': decimal.Decimal}`` would add :meth:`getdecimal` on both the + parser object and all section proxies. In other words, it will be possible + to write both ``parser_instance.getdecimal('section', 'key', fallback=0)`` + and ``parser_instance['section'].getdecimal('key', 0)``. + + If the converter needs to access the state of the parser, it can be + implemented as a method on a config parser subclass. If the name of this + method starts with ``get``, it will be available on all section proxies, in + the dict-compatible form (see the ``getdecimal()`` example above). More advanced customization may be achieved by overriding default values of -these parser attributes. The defaults are defined on the classes, so they -may be overriden by subclasses or by attribute assignment. +these parser attributes. The defaults are defined on the classes, so they may +be overridden by subclasses or by attribute assignment. .. attribute:: BOOLEAN_STATES @@ -725,10 +742,11 @@ may be overriden by subclasses or by attribute assignment. .. attribute:: SECTCRE - A compiled regular expression used to parse section headers. The default - matches ``[section]`` to the name ``"section"``. Whitespace is considered part - of the section name, thus ``[ larch ]`` will be read as a section of name - ``" larch "``. Override this attribute if that's unsuitable. For example: + A compiled regular expression used to parse section headers. The default + matches ``[section]`` to the name ``"section"``. Whitespace is considered + part of the section name, thus ``[ larch ]`` will be read as a section of + name ``" larch "``. Override this attribute if that's unsuitable. For + example: .. doctest:: @@ -859,7 +877,7 @@ interpolation if an option used is not defined elsewhere. :: ConfigParser Objects -------------------- -.. class:: ConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, empty_lines_in_values=True, default_section=configparser.DEFAULTSECT, interpolation=BasicInterpolation()) +.. class:: ConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, empty_lines_in_values=True, default_section=configparser.DEFAULTSECT, interpolation=BasicInterpolation(), converters={}) The main configuration parser. When *defaults* is given, it is initialized into the dictionary of intrinsic defaults. When *dict_type* is given, it @@ -869,8 +887,8 @@ ConfigParser Objects When *delimiters* is given, it is used as the set of substrings that divide keys from values. When *comment_prefixes* is given, it will be used as the set of substrings that prefix comments in otherwise empty lines. - Comments can be indented. When *inline_comment_prefixes* is given, it will be - used as the set of substrings that prefix comments in non-empty lines. + Comments can be indented. When *inline_comment_prefixes* is given, it will + be used as the set of substrings that prefix comments in non-empty lines. When *strict* is ``True`` (the default), the parser won't allow for any section or option duplicates while reading from a single source (file, @@ -884,13 +902,13 @@ ConfigParser Objects When *default_section* is given, it specifies the name for the special section holding default values for other sections and interpolation purposes - (normally named ``"DEFAULT"``). This value can be retrieved and changed on + (normally named ``"DEFAULT"``). This value can be retrieved and changed on runtime using the ``default_section`` instance attribute. Interpolation behaviour may be customized by providing a custom handler through the *interpolation* argument. ``None`` can be used to turn off interpolation completely, ``ExtendedInterpolation()`` provides a more - advanced variant inspired by ``zc.buildout``. More on the subject in the + advanced variant inspired by ``zc.buildout``. More on the subject in the `dedicated documentation section <#interpolation-of-values>`_. All option names used in interpolation will be passed through the @@ -899,6 +917,12 @@ ConfigParser Objects converts option names to lower case), the values ``foo %(bar)s`` and ``foo %(BAR)s`` are equivalent. + When *converters* is given, it should be a dictionary where each key + represents the name of a type converter and each value is a callable + implementing the conversion from string to the desired datatype. Every + converter gets its own corresponding :meth:`get*()` method on the parser + object and section proxies. + .. versionchanged:: 3.1 The default *dict_type* is :class:`collections.OrderedDict`. @@ -907,6 +931,9 @@ ConfigParser Objects *empty_lines_in_values*, *default_section* and *interpolation* were added. + .. versionchanged:: 3.5 + The *converters* argument was added. + .. method:: defaults() @@ -944,7 +971,7 @@ ConfigParser Objects .. method:: has_option(section, option) If the given *section* exists, and contains the given *option*, return - :const:`True`; otherwise return :const:`False`. If the specified + :const:`True`; otherwise return :const:`False`. If the specified *section* is :const:`None` or an empty string, DEFAULT is assumed. @@ -1069,7 +1096,7 @@ ConfigParser Objects :meth:`get` method. .. versionchanged:: 3.2 - Items present in *vars* no longer appear in the result. The previous + Items present in *vars* no longer appear in the result. The previous behaviour mixed actual parser options with variables provided for interpolation. @@ -1170,7 +1197,7 @@ RawConfigParser Objects .. note:: Consider using :class:`ConfigParser` instead which checks types of - the values to be stored internally. If you don't want interpolation, you + the values to be stored internally. If you don't want interpolation, you can use ``ConfigParser(interpolation=None)``. @@ -1181,7 +1208,7 @@ RawConfigParser Objects *default section* name is passed, :exc:`ValueError` is raised. Type of *section* is not checked which lets users create non-string named - sections. This behaviour is unsupported and may cause internal errors. + sections. This behaviour is unsupported and may cause internal errors. .. method:: set(section, option, value) @@ -1282,3 +1309,4 @@ Exceptions .. [1] Config parsers allow for heavy customization. If you are interested in changing the behaviour outlined by the footnote reference, consult the `Customizing Parser Behaviour`_ section. + diff --git a/Doc/library/constants.rst b/Doc/library/constants.rst index 059a21d5c83e..d5a0f09173b3 100644 --- a/Doc/library/constants.rst +++ b/Doc/library/constants.rst @@ -26,9 +26,23 @@ A small number of constants live in the built-in namespace. They are: .. data:: NotImplemented - Special value which can be returned by the "rich comparison" special methods - (:meth:`__eq__`, :meth:`__lt__`, and friends), to indicate that the comparison - is not implemented with respect to the other type. + Special value which should be returned by the binary special methods + (e.g. :meth:`__eq__`, :meth:`__lt__`, :meth:`__add__`, :meth:`__rsub__`, + etc.) to indicate that the operation is not implemented with respect to + the other type; may be returned by the in-place binary special methods + (e.g. :meth:`__imul__`, :meth:`__iand__`, etc.) for the same purpose. + Its truth value is true. + +.. note:: + + When ``NotImplemented`` is returned, the interpreter will then try the + reflected operation on the other type, or some other fallback, depending + on the operator. If all attempted operations return ``NotImplemented``, the + interpreter will raise an appropriate exception. + + See + :ref:`implementing-the-arithmetic-operations` + for more details. .. data:: Ellipsis diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst index 82efd0cca151..38f37821563a 100644 --- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -167,11 +167,21 @@ Functions and classes provided: applications. It also has no effect on the output of subprocesses. However, it is still a useful approach for many utility scripts. - This context manager is :ref:`reusable but not reentrant <reusable-cms>`. + This context manager is :ref:`reentrant <reentrant-cms>`. .. versionadded:: 3.4 +.. function:: redirect_stderr(new_target) + + Similar to :func:`~contextlib.redirect_stdout` but redirecting + :data:`sys.stderr` to another file or file-like object. + + This context manager is :ref:`reentrant <reentrant-cms>`. + + .. versionadded:: 3.5 + + .. class:: ContextDecorator() A base class that enables a context manager to also be used as a decorator. @@ -371,7 +381,7 @@ some of the context managers being optional:: with ExitStack() as stack: for resource in resources: stack.enter_context(resource) - if need_special resource: + if need_special_resource(): special = acquire_special_resource() stack.callback(release_special_resource, special) # Perform operations that use the acquired resources @@ -543,7 +553,7 @@ advance:: Due to the way the decorator protocol works, a callback function declared this way cannot take any parameters. Instead, any resources to -be released must be accessed as closure variables +be released must be accessed as closure variables. Using a context manager as a function decorator @@ -568,10 +578,10 @@ single definition:: self.name = name def __enter__(self): - logging.info('Entering: {}'.format(name)) + logging.info('Entering: {}'.format(self.name)) def __exit__(self, exc_type, exc, exc_tb): - logging.info('Exiting: {}'.format(name)) + logging.info('Exiting: {}'.format(self.name)) Instances of this class can be used as both a context manager:: diff --git a/Doc/library/copyreg.rst b/Doc/library/copyreg.rst index 50d5879ae529..18306c7f99f0 100644 --- a/Doc/library/copyreg.rst +++ b/Doc/library/copyreg.rst @@ -9,7 +9,7 @@ module: pickle module: copy -The :mod:`copyreg` module offers a way to define fuctions used while pickling +The :mod:`copyreg` module offers a way to define functions used while pickling specific objects. The :mod:`pickle` and :mod:`copy` modules use those functions when pickling/copying those objects. The module provides configuration information about object constructors which are not classes. diff --git a/Doc/library/crypt.rst b/Doc/library/crypt.rst index b4c90cd59232..04ffdb289b68 100644 --- a/Doc/library/crypt.rst +++ b/Doc/library/crypt.rst @@ -64,7 +64,7 @@ Module Attributes A list of available password hashing algorithms, as ``crypt.METHOD_*`` objects. This list is sorted from strongest to - weakest, and is guaranteed to have at least ``crypt.METHOD_CRYPT``. + weakest. Module Functions diff --git a/Doc/library/crypto.rst b/Doc/library/crypto.rst index 469ede4982c8..8ad24c8d4fbf 100644 --- a/Doc/library/crypto.rst +++ b/Doc/library/crypto.rst @@ -25,6 +25,5 @@ Here's an overview: Hardcore cypherpunks will probably find the cryptographic modules written by A.M. Kuchling of further interest; the package contains modules for various encryption algorithms, most notably AES. These modules are not distributed with -Python but available separately. See the URL -http://www.pycrypto.org for more information. - +Python but available separately. See the URL http://www.pycrypto.org/ for more +information. diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst index a20c4be901b0..4fcfaef2581e 100644 --- a/Doc/library/csv.rst +++ b/Doc/library/csv.rst @@ -5,6 +5,7 @@ :synopsis: Write and read tabular data to and from delimited files. .. sectionauthor:: Skip Montanaro <skip@pobox.com> +**Source code:** :source:`Lib/csv.py` .. index:: single: csv @@ -108,7 +109,7 @@ The :mod:`csv` module defines the following functions: spamwriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam']) -.. function:: register_dialect(name[, dialect], **fmtparams) +.. function:: register_dialect(name[, dialect[, **fmtparams]]) Associate *dialect* with *name*. *name* must be a string. The dialect can be specified either by passing a sub-class of :class:`Dialect`, or @@ -142,36 +143,68 @@ The :mod:`csv` module defines the following functions: The :mod:`csv` module defines the following classes: -.. class:: DictReader(csvfile, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds) +.. class:: DictReader(csvfile, fieldnames=None, restkey=None, restval=None, \ + dialect='excel', *args, **kwds) + + Create an object which operates like a regular reader but maps the + information read into a dict whose keys are given by the optional + *fieldnames* parameter. The *fieldnames* parameter is a :mod:`sequence + <collections.abc>` whose elements are associated with the fields of the + input data in order. These elements become the keys of the resulting + dictionary. If the *fieldnames* parameter is omitted, the values in the + first row of the *csvfile* will be used as the fieldnames. If the row read + has more fields than the fieldnames sequence, the remaining data is added as + a sequence keyed by the value of *restkey*. If the row read has fewer + fields than the fieldnames sequence, the remaining keys take the value of + the optional *restval* parameter. Any other optional or keyword arguments + are passed to the underlying :class:`reader` instance. - Create an object which operates like a regular reader but maps the information - read into a dict whose keys are given by the optional *fieldnames* parameter. - If the *fieldnames* parameter is omitted, the values in the first row of the - *csvfile* will be used as the fieldnames. If the row read has more fields - than the fieldnames sequence, the remaining data is added as a sequence - keyed by the value of *restkey*. If the row read has fewer fields than the - fieldnames sequence, the remaining keys take the value of the optional - *restval* parameter. Any other optional or keyword arguments are passed to - the underlying :class:`reader` instance. + A short usage example:: + + >>> import csv + >>> with open('names.csv') as csvfile: + ... reader = csv.DictReader(csvfile) + ... for row in reader: + ... print(row['first_name'], row['last_name']) + ... + Baked Beans + Lovely Spam + Wonderful Spam + + +.. class:: DictWriter(csvfile, fieldnames, restval='', extrasaction='http://github.com/raise', \ + dialect='excel', *args, **kwds) + + Create an object which operates like a regular writer but maps dictionaries + onto output rows. The *fieldnames* parameter is a :mod:`sequence + <collections.abc>` of keys that identify the order in which values in the + dictionary passed to the :meth:`writerow` method are written to the + *csvfile*. The optional *restval* parameter specifies the value to be + written if the dictionary is missing a key in *fieldnames*. If the + dictionary passed to the :meth:`writerow` method contains a key not found in + *fieldnames*, the optional *extrasaction* parameter indicates what action to + take. If it is set to ``'raise'`` a :exc:`ValueError` is raised. If it is + set to ``'ignore'``, extra values in the dictionary are ignored. Any other + optional or keyword arguments are passed to the underlying :class:`writer` + instance. + + Note that unlike the :class:`DictReader` class, the *fieldnames* parameter + of the :class:`DictWriter` is not optional. Since Python's :class:`dict` + objects are not ordered, there is not enough information available to deduce + the order in which the row should be written to the *csvfile*. + A short usage example:: -.. class:: DictWriter(csvfile, fieldnames, restval='', extrasaction='http://github.com/raise', dialect='excel', *args, **kwds) + import csv - Create an object which operates like a regular writer but maps dictionaries onto - output rows. The *fieldnames* parameter identifies the order in which values in - the dictionary passed to the :meth:`writerow` method are written to the - *csvfile*. The optional *restval* parameter specifies the value to be written - if the dictionary is missing a key in *fieldnames*. If the dictionary passed to - the :meth:`writerow` method contains a key not found in *fieldnames*, the - optional *extrasaction* parameter indicates what action to take. If it is set - to ``'raise'`` a :exc:`ValueError` is raised. If it is set to ``'ignore'``, - extra values in the dictionary are ignored. Any other optional or keyword - arguments are passed to the underlying :class:`writer` instance. + with open('names.csv', 'w') as csvfile: + fieldnames = ['first_name', 'last_name'] + writer = csv.DictWriter(csvfile, fieldnames=fieldnames) - Note that unlike the :class:`DictReader` class, the *fieldnames* parameter of - the :class:`DictWriter` is not optional. Since Python's :class:`dict` objects - are not ordered, there is not enough information available to deduce the order - in which the row should be written to the *csvfile*. + writer.writeheader() + writer.writerow({'first_name': 'Baked', 'last_name': 'Beans'}) + writer.writerow({'first_name': 'Lovely', 'last_name': 'Spam'}) + writer.writerow({'first_name': 'Wonderful', 'last_name': 'Spam'}) .. class:: Dialect @@ -292,7 +325,7 @@ Dialects support the following attributes: .. attribute:: Dialect.doublequote - Controls how instances of *quotechar* appearing inside a field should be + Controls how instances of *quotechar* appearing inside a field should themselves be quoted. When :const:`True`, the character is doubled. When :const:`False`, the *escapechar* is used as a prefix to the *quotechar*. It defaults to :const:`True`. @@ -386,7 +419,7 @@ Writer Objects :class:`Writer` objects (:class:`DictWriter` instances and objects returned by the :func:`writer` function) have the following public methods. A *row* must be -a sequence of strings or numbers for :class:`Writer` objects and a dictionary +an iterable of strings or numbers for :class:`Writer` objects and a dictionary mapping fieldnames to strings or numbers (by passing them through :func:`str` first) for :class:`DictWriter` objects. Note that complex numbers are written out surrounded by parens. This may cause some problems for other programs which @@ -398,6 +431,8 @@ read CSV files (assuming they support complex numbers at all). Write the *row* parameter to the writer's file object, formatted according to the current dialect. + .. versionchanged:: 3.5 + Added support of arbitrary iterables. .. method:: csvwriter.writerows(rows) diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index ccbb8ec563e5..588ac7c16c7b 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -218,7 +218,7 @@ more about :mod:`ctypes` data types. Fundamental data types ^^^^^^^^^^^^^^^^^^^^^^ -:mod:`ctypes` defines a number of primitive C compatible data types : +:mod:`ctypes` defines a number of primitive C compatible data types: +----------------------+------------------------------------------+----------------------------+ | ctypes type | C type | Python type | @@ -1022,12 +1022,18 @@ As we can easily check, our array is sorted now:: 1 5 7 33 99 >>> -**Important note for callback functions:** +.. note:: -Make sure you keep references to :func:`CFUNCTYPE` objects as long as they are -used from C code. :mod:`ctypes` doesn't, and if you don't, they may be garbage -collected, crashing your program when a callback is made. + Make sure you keep references to :func:`CFUNCTYPE` objects as long as they + are used from C code. :mod:`ctypes` doesn't, and if you don't, they may be + garbage collected, crashing your program when a callback is made. + Also, note that if the callback function is called in a thread created + outside of Python's control (e.g. by the foreign code that calls the + callback), ctypes creates a new dummy Python thread on every invocation. This + behavior is correct for most purposes, but it means that values stored with + :class:`threading.local` will *not* survive across different callbacks, even when + those calls are made from the same C thread. .. _ctypes-accessing-values-exported-from-dlls: @@ -1380,11 +1386,16 @@ copy of the windows error code. The default mode which is used to load shared libraries. On OSX 10.3, this is *RTLD_GLOBAL*, otherwise it is the same as *RTLD_LOCAL*. -Instances of these classes have no public methods, however :meth:`__getattr__` -and :meth:`__getitem__` have special behavior: functions exported by the shared -library can be accessed as attributes of by index. Please note that both -:meth:`__getattr__` and :meth:`__getitem__` cache their result, so calling them -repeatedly returns the same object each time. +Instances of these classes have no public methods. Functions exported by the +shared library can be accessed as attributes or by index. Please note that +accessing the function through an attribute caches the result and therefore +accessing it repeatedly returns the same object each time. On the other hand, +accessing it through an index returns a new object each time: + + >>> libc.time == libc.time + True + >>> libc['time'] == libc['time'] + False The following public attributes are available, their name starts with an underscore to not clash with exported function names: @@ -1651,7 +1662,7 @@ the windows header file is this:: WINUSERAPI int WINAPI MessageBoxA( - HWND hWnd , + HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType); @@ -1822,7 +1833,7 @@ Utility functions .. function:: find_msvcrt() :module: ctypes.util - Windows only: return the filename of the VC runtype library used by Python, + Windows only: return the filename of the VC runtime library used by Python, and by the extension modules. If the name of the library cannot be determined, ``None`` is returned. @@ -2324,11 +2335,6 @@ other data types containing pointer type fields. and so on). Later assignments to the :attr:`_fields_` class variable will raise an AttributeError. - Structure and union subclass constructors accept both positional and named - arguments. Positional arguments are used to initialize the fields in the - same order as they appear in the :attr:`_fields_` definition, named - arguments are used to initialize the fields with the corresponding name. - It is possible to defined sub-subclasses of structure types, they inherit the fields of the base class plus the :attr:`_fields_` defined in the sub-subclass, if any. diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index 314636e4b48c..e8dfd833e414 100644 --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -12,7 +12,7 @@ The :mod:`curses` module provides an interface to the curses library, the de-facto standard for portable advanced terminal handling. While curses is most widely used in the Unix environment, versions are available -for DOS, OS/2, and possibly other systems as well. This extension module is +for Windows, DOS, and possibly other systems as well. This extension module is designed to match the API of ncurses, an open-source curses library hosted on Linux and the BSD variants of Unix. @@ -599,6 +599,13 @@ The module :mod:`curses` defines the following functions: Only one *ch* can be pushed before :meth:`getch` is called. +.. function:: update_lines_cols() + + Update :envvar:`LINES` and :envvar:`COLS`. Useful for detecting manual screen resize. + + .. versionadded:: 3.5 + + .. function:: unget_wch(ch) Push *ch* so the next :meth:`get_wch` will return it. diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index e4f1eb230177..cf5d5b85436f 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -7,6 +7,8 @@ .. sectionauthor:: Tim Peters <tim@zope.com> .. sectionauthor:: A.M. Kuchling <amk@amk.ca> +**Source code:** :source:`Lib/datetime.py` + .. XXX what order should the types be discussed in? The :mod:`datetime` module supplies classes for manipulating dates and times in @@ -558,7 +560,7 @@ Instance methods: Return a 3-tuple, (ISO year, ISO week number, ISO weekday). The ISO calendar is a widely used variant of the Gregorian calendar. See - http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm for a good + http://www.staff.science.uu.nl/~gent0113/calendar/isocalendar.htm for a good explanation. The ISO year consists of 52 or 53 full weeks, and where a week starts on a @@ -664,8 +666,8 @@ Example of working with :class:`date`: .. _datetime-datetime: -:class:`datetime` Objects -------------------------- +:class:`.datetime` Objects +-------------------------- A :class:`.datetime` object is a single object containing all the information from a :class:`date` object and a :class:`.time` object. Like a :class:`date` @@ -757,13 +759,19 @@ Other constructors, all class methods: :attr:`tzinfo` ``None``. This may raise :exc:`OverflowError`, if the timestamp is out of the range of values supported by the platform C :c:func:`gmtime` function, and :exc:`OSError` on :c:func:`gmtime` failure. - It's common for this to be restricted to years in 1970 through 2038. See also - :meth:`fromtimestamp`. + It's common for this to be restricted to years in 1970 through 2038. + + To get an aware :class:`.datetime` object, call :meth:`fromtimestamp`:: + + datetime.fromtimestamp(timestamp, timezone.utc) - On the POSIX compliant platforms, ``utcfromtimestamp(timestamp)`` - is equivalent to the following expression:: + On the POSIX compliant platforms, it is equivalent to the following + expression:: - datetime(1970, 1, 1) + timedelta(seconds=timestamp) + datetime(1970, 1, 1, tzinfo=timezone.utc) + timedelta(seconds=timestamp) + + except the latter formula always supports the full years range: between + :const:`MINYEAR` and :const:`MAXYEAR` inclusive. .. versionchanged:: 3.3 Raise :exc:`OverflowError` instead of :exc:`ValueError` if the timestamp @@ -1376,10 +1384,13 @@ Supported operations: * efficient pickling -* in Boolean contexts, a :class:`.time` object is considered to be true if and - only if, after converting it to minutes and subtracting :meth:`utcoffset` (or - ``0`` if that's ``None``), the result is non-zero. +In boolean contexts, a :class:`.time` object is always considered to be true. +.. versionchanged:: 3.5 + Before Python 3.5, a :class:`.time` object was considered to be false if it + represented midnight in UTC. This behavior was considered obscure and + error-prone and has been removed in Python 3.5. See :issue:`13936` for full + details. Instance methods: @@ -1686,12 +1697,12 @@ only EST (fixed offset -5 hours), or only EDT (fixed offset -4 hours)). .. seealso:: - `pytz <http://pypi.python.org/pypi/pytz/>`_ - The standard library has no :class:`tzinfo` instances except for UTC, but - there exists a third-party library which brings the *IANA timezone - database* (also known as the Olson database) to Python: *pytz*. + `pytz <https://pypi.python.org/pypi/pytz/>`_ + The standard library has :class:`timezone` class for handling arbitrary + fixed offsets from UTC and :attr:`timezone.utc` as UTC timezone instance. - *pytz* contains up-to-date information and its usage is recommended. + *pytz* library brings the *IANA timezone database* (also known as the + Olson database) to Python and its usage is recommended. `IANA timezone database <http://www.iana.org/time-zones>`_ The Time Zone Database (often called tz or zoneinfo) contains code and @@ -1723,10 +1734,9 @@ made to civil time. otherwise :exc:`ValueError` is raised. The *name* argument is optional. If specified it must be a string that - is used as the value returned by the ``tzname(dt)`` method. Otherwise, - ``tzname(dt)`` returns a string 'UTCsHH:MM', where s is the sign of - *offset*, HH and MM are two digits of ``offset.hours`` and - ``offset.minutes`` respectively. + will be used as the value returned by the :meth:`datetime.tzname` method. + + .. versionadded:: 3.2 .. method:: timezone.utcoffset(dt) @@ -1737,11 +1747,19 @@ made to civil time. .. method:: timezone.tzname(dt) - Return the fixed value specified when the :class:`timezone` instance is - constructed or a string 'UTCsHH:MM', where s is the sign of - *offset*, HH and MM are two digits of ``offset.hours`` and + Return the fixed value specified when the :class:`timezone` instance + is constructed. If *name* is not provided in the constructor, the + name returned by ``tzname(dt)`` is generated from the value of the + ``offset`` as follows. If *offset* is ``timedelta(0)``, the name + is "UTC", otherwise it is a string 'UTC±HH:MM', where ± is the sign + of ``offset``, HH and MM are two digits of ``offset.hours`` and ``offset.minutes`` respectively. + .. versionchanged:: 3.6 + Name generated from ``offset=timedelta(0)`` is now plain 'UTC', not + 'UTC+00:00'. + + .. method:: timezone.dst(dt) Always returns ``None``. @@ -1891,6 +1909,34 @@ format codes. | ``%%`` | A literal ``'%'`` character. | % | | +-----------+--------------------------------+------------------------+-------+ +Several additional directives not required by the C89 standard are included for +convenience. These parameters all correspond to ISO 8601 date values. These +may not be available on all platforms when used with the :meth:`strftime` +method. The ISO 8601 year and ISO 8601 week directives are not interchangeable +with the year and week number directives above. Calling :meth:`strptime` with +incomplete or ambiguous ISO 8601 directives will raise a :exc:`ValueError`. + ++-----------+--------------------------------+------------------------+-------+ +| Directive | Meaning | Example | Notes | ++===========+================================+========================+=======+ +| ``%G`` | ISO 8601 year with century | 0001, 0002, ..., 2013, | \(8) | +| | representing the year that | 2014, ..., 9998, 9999 | | +| | contains the greater part of | | | +| | the ISO week (``%V``). | | | ++-----------+--------------------------------+------------------------+-------+ +| ``%u`` | ISO 8601 weekday as a decimal | 1, 2, ..., 7 | | +| | number where 1 is Monday. | | | ++-----------+--------------------------------+------------------------+-------+ +| ``%V`` | ISO 8601 week as a decimal | 01, 02, ..., 53 | \(8) | +| | number with Monday as | | | +| | the first day of the week. | | | +| | Week 01 is the week containing | | | +| | Jan 4. | | | ++-----------+--------------------------------+------------------------+-------+ + +.. versionadded:: 3.6 + ``%G``, ``%u`` and ``%V`` were added. + Notes: (1) @@ -1955,7 +2001,14 @@ Notes: (7) When used with the :meth:`strptime` method, ``%U`` and ``%W`` are only used - in calculations when the day of the week and the year are specified. + in calculations when the day of the week and the calendar year (``%Y``) + are specified. + +(8) + Similar to ``%U`` and ``%W``, ``%V`` is only used in calculations when the + day of the week and the ISO year (``%G``) are specified in a + :meth:`strptime` format string. Also note that ``%G`` and ``%Y`` are not + interchangable. .. rubric:: Footnotes diff --git a/Doc/library/dbm.rst b/Doc/library/dbm.rst index f5496d5b99c6..3f3c43d4383f 100644 --- a/Doc/library/dbm.rst +++ b/Doc/library/dbm.rst @@ -222,6 +222,9 @@ supported. When the database has been opened in fast mode, this method forces any unwritten data to be written to the disk. + .. method:: gdbm.close() + + Close the ``gdbm`` database. :mod:`dbm.ndbm` --- Interface based on ndbm ------------------------------------------- @@ -253,7 +256,7 @@ to locate the appropriate header file to simplify building this module. .. function:: open(filename[, flag[, mode]]) - Open a dbm database and return a ``dbm`` object. The *filename* argument is the + Open a dbm database and return a ``ndbm`` object. The *filename* argument is the name of the database file (without the :file:`.dir` or :file:`.pag` extensions). The optional *flag* argument must be one of these values: @@ -278,6 +281,12 @@ to locate the appropriate header file to simplify building this module. database has to be created. It defaults to octal ``0o666`` (and will be modified by the prevailing umask). + In addition to the dictionary-like methods, ``ndbm`` objects + provide the following method: + + .. method:: ndbm.close() + + Close the ``ndbm`` database. :mod:`dbm.dumb` --- Portable DBM implementation @@ -316,18 +325,28 @@ The module defines the following: dumbdbm database is created, files with :file:`.dat` and :file:`.dir` extensions are created. - The optional *flag* argument is currently ignored; the database is always opened - for update, and will be created if it does not exist. + The optional *flag* argument supports only the semantics of ``'c'`` + and ``'n'`` values. Other values will default to database being always + opened for update, and will be created if it does not exist. 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`` (and will be modified by the prevailing umask). + .. versionchanged:: 3.5 + :func:`.open` always creates a new database when the flag has the value + ``'n'``. + In addition to the methods provided by the :class:`collections.abc.MutableMapping` class, :class:`dumbdbm` objects - provide the following method: + provide the following methods: .. method:: dumbdbm.sync() Synchronize the on-disk directory and data files. This method is called by the :meth:`Shelve.sync` method. + + .. method:: dumbdbm.close() + + Close the ``dumbdbm`` database. + diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index 059ae7cb1690..2de0ea0870c3 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -12,6 +12,8 @@ .. moduleauthor:: Stefan Krah <skrah at bytereef.org> .. sectionauthor:: Raymond D. Hettinger <python at rcn.com> +**Source code:** :source:`Lib/decimal.py` + .. import modules for testing inline doctests with the Sphinx doctest builder .. testsetup:: * @@ -261,7 +263,7 @@ For more advanced work, it may be useful to create alternate contexts using the Context() constructor. To make an alternate active, use the :func:`setcontext` function. -In accordance with the standard, the :mod:`Decimal` module provides two ready to +In accordance with the standard, the :mod:`decimal` module provides two ready to use standard contexts, :const:`BasicContext` and :const:`ExtendedContext`. The former is especially useful for debugging because many of the traps are enabled: @@ -742,7 +744,7 @@ Decimal objects * ``"NaN"``, indicating that the operand is a quiet NaN (Not a Number). * ``"sNaN"``, indicating that the operand is a signaling NaN. - .. method:: quantize(exp, rounding=None, context=None, watchexp=True) + .. method:: quantize(exp, rounding=None, context=None) Return a value equal to the first operand after rounding and having the exponent of the second operand. @@ -765,14 +767,8 @@ Decimal objects ``context`` argument; if neither argument is given the rounding mode of the current thread's context is used. - If *watchexp* is set (default), then an error is returned whenever the - resulting exponent is greater than :attr:`Emax` or less than - :attr:`Etiny`. - - .. deprecated:: 3.3 - *watchexp* is an implementation detail from the pure Python version - and is not present in the C version. It will be removed in version - 3.4, where it defaults to ``True``. + An error is returned whenever the resulting exponent is greater than + :attr:`Emax` or less than :attr:`Etiny`. .. method:: radix() @@ -845,7 +841,7 @@ Decimal objects Engineering notation has an exponent which is a multiple of 3, so there are up to 3 digits left of the decimal place. For example, converts - ``Decimal('123E+1')`` to ``Decimal('1.23E+3')`` + ``Decimal('123E+1')`` to ``Decimal('1.23E+3')``. .. method:: to_integral(rounding=None, context=None) @@ -2092,4 +2088,3 @@ Alternatively, inputs can be rounded upon creation using the >>> Context(prec=5, rounding=ROUND_DOWN).create_decimal('1.2345678') Decimal('1.2345') - diff --git a/Doc/library/development.rst b/Doc/library/development.rst index 06e7048a04a6..d2b5fa2aa4f5 100644 --- a/Doc/library/development.rst +++ b/Doc/library/development.rst @@ -16,6 +16,7 @@ The list of modules described in this chapter is: .. toctree:: + typing.rst pydoc.rst doctest.rst unittest.rst diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index 81dc0f16be3f..38245e776ac3 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -7,6 +7,8 @@ .. sectionauthor:: Tim Peters <tim_one@users.sourceforge.net> .. Markup by Fred L. Drake, Jr. <fdrake@acm.org> +**Source code:** :source:`Lib/difflib.py` + .. testsetup:: import sys @@ -25,7 +27,9 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. little fancier than, an algorithm published in the late 1980's by Ratcliff and Obershelp under the hyperbolic name "gestalt pattern matching." The idea is to find the longest contiguous matching subsequence that contains no "junk" - elements (the Ratcliff and Obershelp algorithm doesn't address junk). The same + elements; these "junk" elements are ones that are uninteresting in some + sense, such as blank lines or whitespace. (Handling junk is an + extension to the Ratcliff and Obershelp algorithm.) The same idea is then applied recursively to the pieces of the sequences to the left and to the right of the matching subsequence. This does not yield minimal edit sequences, but does tend to yield matches that "look right" to people. @@ -100,7 +104,8 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. The following methods are public: - .. method:: make_file(fromlines, tolines, fromdesc='', todesc='', context=False, numlines=5) + .. method:: make_file(fromlines, tolines, fromdesc='', todesc='', context=False, \ + numlines=5, *, charset='utf-8') Compares *fromlines* and *tolines* (lists of strings) and returns a string which is a complete HTML file containing a table showing line by line differences with @@ -119,6 +124,10 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. the next difference highlight at the top of the browser without any leading context). + .. versionchanged:: 3.5 + *charset* keyword-only argument was added. The default charset of + HTML document changed from ``'ISO-8859-1'`` to ``'utf-8'``. + .. method:: make_table(fromlines, tolines, fromdesc='', todesc='', context=False, numlines=5) Compares *fromlines* and *tolines* (lists of strings) and returns a string which @@ -208,7 +217,7 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. Compare *a* and *b* (lists of strings); return a :class:`Differ`\ -style delta (a :term:`generator` generating the delta lines). - Optional keyword parameters *linejunk* and *charjunk* are for filter functions + Optional keyword parameters *linejunk* and *charjunk* are filtering functions (or ``None``): *linejunk*: A function that accepts a single string argument, and returns @@ -222,12 +231,12 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. *charjunk*: A function that accepts a character (a string of length 1), and returns if the character is junk, or false if not. The default is module-level function :func:`IS_CHARACTER_JUNK`, which filters out whitespace characters (a - blank or tab; note: bad idea to include newline in this!). + blank or tab; it's a bad idea to include newline in this!). :file:`Tools/scripts/ndiff.py` is a command-line front-end to this function. - >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1), - ... 'ore\ntree\nemu\n'.splitlines(1)) + >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(keepends=True), + ... 'ore\ntree\nemu\n'.splitlines(keepends=True)) >>> print(''.join(diff), end="") - one ? ^ @@ -250,8 +259,8 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. Example: - >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1), - ... 'ore\ntree\nemu\n'.splitlines(1)) + >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(keepends=True), + ... 'ore\ntree\nemu\n'.splitlines(keepends=True)) >>> diff = list(diff) # materialize the generated delta into a list >>> print(''.join(restore(diff, 1)), end="") one @@ -306,6 +315,21 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. See :ref:`difflib-interface` for a more detailed example. +.. function:: diff_bytes(dfunc, a, b, fromfile=b'', tofile=b'', fromfiledate=b'', tofiledate=b'', n=3, lineterm=b'\\n') + + Compare *a* and *b* (lists of bytes objects) using *dfunc*; yield a + sequence of delta lines (also bytes) in the format returned by *dfunc*. + *dfunc* must be a callable, typically either :func:`unified_diff` or + :func:`context_diff`. + + Allows you to compare data with unknown or inconsistent encoding. All + inputs except *n* must be bytes objects, not str. Works by losslessly + converting all inputs (except *n*) to str, and calling ``dfunc(a, b, + fromfile, tofile, fromfiledate, tofiledate, n, lineterm)``. The output of + *dfunc* is then converted back to bytes, so the delta lines that you + receive have the same unknown/inconsistent encodings as *a* and *b*. + + .. versionadded:: 3.5 .. function:: IS_LINE_JUNK(line) @@ -323,9 +347,9 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. .. seealso:: - `Pattern Matching: The Gestalt Approach <http://www.ddj.com/184407970?pgno=5>`_ + `Pattern Matching: The Gestalt Approach <http://www.drdobbs.com/database/pattern-matching-the-gestalt-approach/184407970>`_ Discussion of a similar algorithm by John W. Ratcliff and D. E. Metzener. This - was published in `Dr. Dobb's Journal <http://www.ddj.com/>`_ in July, 1988. + was published in `Dr. Dobb's Journal <http://www.drdobbs.com/>`_ in July, 1988. .. _sequence-matcher: @@ -622,6 +646,12 @@ The :class:`Differ` class has this constructor: length 1), and returns true if the character is junk. The default is ``None``, meaning that no character is considered junk. + These junk-filtering functions speed up matching to find + differences and do not cause any differing lines or characters to + be ignored. Read the description of the + :meth:`~SequenceMatcher.find_longest_match` method's *isjunk* + parameter for an explanation. + :class:`Differ` objects are used (deltas generated) via a single method: @@ -650,7 +680,7 @@ obtained from the :meth:`~io.BaseIO.readlines` method of file-like objects): ... 2. Explicit is better than implicit. ... 3. Simple is better than complex. ... 4. Complex is better than complicated. - ... '''.splitlines(1) + ... '''.splitlines(keepends=True) >>> len(text1) 4 >>> text1[0][-1] @@ -659,7 +689,7 @@ obtained from the :meth:`~io.BaseIO.readlines` method of file-like objects): ... 3. Simple is better than complex. ... 4. Complicated is better than complex. ... 5. Flat is better than nested. - ... '''.splitlines(1) + ... '''.splitlines(keepends=True) Next we instantiate a Differ object: @@ -713,65 +743,4 @@ This example shows how to use difflib to create a ``diff``-like utility. It is also contained in the Python source distribution, as :file:`Tools/scripts/diff.py`. -.. testcode:: - - """ Command line interface to difflib.py providing diffs in four formats: - - * ndiff: lists every line and highlights interline changes. - * context: highlights clusters of changes in a before/after format. - * unified: highlights clusters of changes in an inline format. - * html: generates side by side comparison with change highlights. - - """ - - import sys, os, time, difflib, optparse - - def main(): - # Configure the option parser - usage = "usage: %prog [options] fromfile tofile" - parser = optparse.OptionParser(usage) - parser.add_option("-c", action="http://github.com/store_true", default=False, - help='Produce a context format diff (default)') - parser.add_option("-u", action="http://github.com/store_true", default=False, - help='Produce a unified format diff') - hlp = 'Produce HTML side by side diff (can use -c and -l in conjunction)' - parser.add_option("-m", action="http://github.com/store_true", default=False, help=hlp) - parser.add_option("-n", action="http://github.com/store_true", default=False, - help='Produce a ndiff format diff') - parser.add_option("-l", "--lines", type="int", default=3, - help='Set number of context lines (default 3)') - (options, args) = parser.parse_args() - - if len(args) == 0: - parser.print_help() - sys.exit(1) - if len(args) != 2: - parser.error("need to specify both a fromfile and tofile") - - n = options.lines - fromfile, tofile = args # as specified in the usage string - - # we're passing these as arguments to the diff function - fromdate = time.ctime(os.stat(fromfile).st_mtime) - todate = time.ctime(os.stat(tofile).st_mtime) - with open(fromfile) as fromf, open(tofile) as tof: - fromlines, tolines = list(fromf), list(tof) - - if options.u: - diff = difflib.unified_diff(fromlines, tolines, fromfile, tofile, - fromdate, todate, n=n) - elif options.n: - diff = difflib.ndiff(fromlines, tolines) - elif options.m: - diff = difflib.HtmlDiff().make_file(fromlines, tolines, fromfile, - tofile, context=options.c, - numlines=n) - else: - diff = difflib.context_diff(fromlines, tolines, fromfile, tofile, - fromdate, todate, n=n) - - # we're using writelines because diff is a generator - sys.stdout.writelines(diff) - - if __name__ == '__main__': - main() +.. literalinclude:: ../../Tools/scripts/diff.py diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 8293d498a362..1bcb3a4a07f4 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -9,9 +9,9 @@ -------------- The :mod:`dis` module supports the analysis of CPython :term:`bytecode` by -disassembling it. The CPython bytecode which this module takes as an -input is defined in the file :file:`Include/opcode.h` and used by the compiler -and the interpreter. +disassembling it. The CPython bytecode which this module takes as an input is +defined in the file :file:`Include/opcode.h` and used by the compiler and the +interpreter. .. impl-detail:: @@ -40,34 +40,35 @@ the following command can be used to display the disassembly of Bytecode analysis ----------------- +.. versionadded:: 3.4 + The bytecode analysis API allows pieces of Python code to be wrapped in a -:class:`Bytecode` object that provides easy access to details of the -compiled code. +:class:`Bytecode` object that provides easy access to details of the compiled +code. .. class:: Bytecode(x, *, first_line=None, current_offset=None) - Analyse the bytecode corresponding to a function, method, string of - source code, or a code object (as returned by :func:`compile`). - This is a convenience wrapper around many of the functions listed below, - most notably :func:`get_instructions`, as iterating over a - :class:`Bytecode` instance yields the bytecode operations as - :class:`Instruction` instances. + Analyse the bytecode corresponding to a function, generator, method, string + of source code, or a code object (as returned by :func:`compile`). + + This is a convenience wrapper around many of the functions listed below, most + notably :func:`get_instructions`, as iterating over a :class:`Bytecode` + instance yields the bytecode operations as :class:`Instruction` instances. - If *first_line* is not None, it indicates the line number that should - be reported for the first source line in the disassembled code. - Otherwise, the source line information (if any) is taken directly from - the disassembled code object. + If *first_line* is not None, it indicates the line number that should be + reported for the first source line in the disassembled code. Otherwise, the + source line information (if any) is taken directly from the disassembled code + object. - If *current_offset* is not None, it refers to an instruction offset - in the disassembled code. Setting this means :meth:`dis` will display - a "current instruction" marker against the specified opcode. + If *current_offset* is not None, it refers to an instruction offset in the + disassembled code. Setting this means :meth:`.dis` will display a "current + instruction" marker against the specified opcode. .. classmethod:: from_traceback(tb) - Construct a :class:`Bytecode` instance from the given traceback, - setting *current_offset* to the instruction responsible for the - exception. + Construct a :class:`Bytecode` instance from the given traceback, setting + *current_offset* to the instruction responsible for the exception. .. data:: codeobj @@ -79,8 +80,8 @@ compiled code. .. method:: dis() - Return a formatted view of the bytecode operations (the same as - printed by :func:`dis`, but returned as a multi-line string). + Return a formatted view of the bytecode operations (the same as printed by + :func:`dis.dis`, but returned as a multi-line string). .. method:: info() @@ -102,15 +103,14 @@ Example:: Analysis functions ------------------ -The :mod:`dis` module also defines the following analysis functions that -convert the input directly to the desired output. They can be useful if -only a single operation is being performed, so the intermediate analysis -object isn't useful: +The :mod:`dis` module also defines the following analysis functions that convert +the input directly to the desired output. They can be useful if only a single +operation is being performed, so the intermediate analysis object isn't useful: .. function:: code_info(x) Return a formatted multi-line string with detailed code object information - for the supplied function, method, source code string or code object. + for the supplied function, generator, method, source code string or code object. Note that the exact contents of code info strings are highly implementation dependent and they may change arbitrarily across Python VMs or Python @@ -131,25 +131,25 @@ object isn't useful: .. versionadded:: 3.2 .. versionchanged:: 3.4 - Added ``file`` parameter + Added *file* parameter. .. function:: dis(x=None, *, file=None) Disassemble the *x* object. *x* can denote either a module, a class, a - method, a function, a code object, a string of source code or a byte sequence - of raw bytecode. For a module, it disassembles all functions. For a class, - it disassembles all methods. For a code object or sequence of raw bytecode, - it prints one line per bytecode instruction. Strings are first compiled to - code objects with the :func:`compile` built-in function before being + method, a function, a generator, a code object, a string of source code or + a byte sequence of raw bytecode. For a module, it disassembles all functions. + For a class, it disassembles all methods. For a code object or sequence of + raw bytecode, it prints one line per bytecode instruction. Strings are first + compiled to code objects with the :func:`compile` built-in function before being disassembled. If no object is provided, this function disassembles the last traceback. - The disassembly is written as text to the supplied ``file`` argument if + The disassembly is written as text to the supplied *file* argument if provided and to ``sys.stdout`` otherwise. .. versionchanged:: 3.4 - Added ``file`` parameter + Added *file* parameter. .. function:: distb(tb=None, *, file=None) @@ -158,11 +158,11 @@ object isn't useful: traceback if none was passed. The instruction causing the exception is indicated. - The disassembly is written as text to the supplied ``file`` argument if + The disassembly is written as text to the supplied *file* argument if provided and to ``sys.stdout`` otherwise. .. versionchanged:: 3.4 - Added ``file`` parameter + Added *file* parameter. .. function:: disassemble(code, lasti=-1, *, file=None) @@ -182,11 +182,11 @@ object isn't useful: The parameter interpretation recognizes local and global variable names, constant values, branch targets, and compare operators. - The disassembly is written as text to the supplied ``file`` argument if + The disassembly is written as text to the supplied *file* argument if provided and to ``sys.stdout`` otherwise. .. versionchanged:: 3.4 - Added ``file`` parameter + Added *file* parameter. .. function:: get_instructions(x, *, first_line=None) @@ -194,13 +194,13 @@ object isn't useful: Return an iterator over the instructions in the supplied function, method, source code string or code object. - The iterator generates a series of :class:`Instruction` named tuples - giving the details of each operation in the supplied code. + The iterator generates a series of :class:`Instruction` named tuples giving + the details of each operation in the supplied code. - If *first_line* is not None, it indicates the line number that should - be reported for the first source line in the disassembled code. - Otherwise, the source line information (if any) is taken directly from - the disassembled code object. + If *first_line* is not None, it indicates the line number that should be + reported for the first source line in the disassembled code. Otherwise, the + source line information (if any) is taken directly from the disassembled code + object. .. versionadded:: 3.4 @@ -346,6 +346,14 @@ result back on the stack. Implements ``TOS = iter(TOS)``. +.. opcode:: GET_YIELD_FROM_ITER + + If ``TOS`` is a :term:`generator iterator` or :term:`coroutine` object + it is left as is. Otherwise, implements ``TOS = iter(TOS)``. + + .. versionadded:: 3.5 + + **Binary operations** Binary operations remove the top of the stack (TOS) and the second top-most @@ -362,6 +370,13 @@ result back on the stack. Implements ``TOS = TOS1 * TOS``. +.. opcode:: BINARY_MATRIX_MULTIPLY + + Implements ``TOS = TOS1 @ TOS``. + + .. versionadded:: 3.5 + + .. opcode:: BINARY_FLOOR_DIVIDE Implements ``TOS = TOS1 // TOS``. @@ -434,6 +449,13 @@ the original TOS1. Implements in-place ``TOS = TOS1 * TOS``. +.. opcode:: INPLACE_MATRIX_MULTIPLY + + Implements in-place ``TOS = TOS1 @ TOS``. + + .. versionadded:: 3.5 + + .. opcode:: INPLACE_FLOOR_DIVIDE Implements in-place ``TOS = TOS1 // TOS``. @@ -494,13 +516,47 @@ the original TOS1. Implements ``del TOS1[TOS]``. +**Coroutine opcodes** + +.. opcode:: GET_AWAITABLE + + Implements ``TOS = get_awaitable(TOS)``, where ``get_awaitable(o)`` + returns ``o`` if ``o`` is a coroutine object or a generator object with + the CO_ITERABLE_COROUTINE flag, or resolves + ``o.__await__``. + + +.. opcode:: GET_AITER + + Implements ``TOS = get_awaitable(TOS.__aiter__())``. See ``GET_AWAITABLE`` + for details about ``get_awaitable`` + + +.. opcode:: GET_ANEXT + + Implements ``PUSH(get_awaitable(TOS.__anext__()))``. See ``GET_AWAITABLE`` + for details about ``get_awaitable`` + + +.. opcode:: BEFORE_ASYNC_WITH + + Resolves ``__aenter__`` and ``__aexit__`` from the object on top of the + stack. Pushes ``__aexit__`` and result of ``__aenter__()`` to the stack. + + +.. opcode:: SETUP_ASYNC_WITH + + Creates a new frame object. + + + **Miscellaneous opcodes** .. opcode:: PRINT_EXPR Implements the expression statement for the interactive mode. TOS is removed - from the stack and printed. In non-interactive mode, an expression statement is - terminated with ``POP_STACK``. + from the stack and printed. In non-interactive mode, an expression statement + is terminated with :opcode:`POP_TOP`. .. opcode:: BREAK_LOOP @@ -511,7 +567,7 @@ the original TOS1. .. opcode:: CONTINUE_LOOP (target) Continues a loop due to a :keyword:`continue` statement. *target* is the - address to jump to (which should be a ``FOR_ITER`` instruction). + address to jump to (which should be a :opcode:`FOR_ITER` instruction). .. opcode:: SET_ADD (i) @@ -529,9 +585,10 @@ the original TOS1. Calls ``dict.setitem(TOS1[-i], TOS, TOS1)``. Used to implement dict comprehensions. -For all of the SET_ADD, LIST_APPEND and MAP_ADD instructions, while the -added value or key/value pair is popped off, the container object remains on -the stack so that it is available for further iterations of the loop. +For all of the :opcode:`SET_ADD`, :opcode:`LIST_APPEND` and :opcode:`MAP_ADD` +instructions, while the added value or key/value pair is popped off, the +container object remains on the stack so that it is available for further +iterations of the loop. .. opcode:: RETURN_VALUE @@ -541,35 +598,35 @@ the stack so that it is available for further iterations of the loop. .. opcode:: YIELD_VALUE - Pops ``TOS`` and yields it from a :term:`generator`. + Pops TOS and yields it from a :term:`generator`. .. opcode:: YIELD_FROM - Pops ``TOS`` and delegates to it as a subiterator from a :term:`generator`. + Pops TOS and delegates to it as a subiterator from a :term:`generator`. .. versionadded:: 3.3 .. opcode:: IMPORT_STAR - Loads all symbols not starting with ``'_'`` directly from the module TOS to the - local namespace. The module is popped after loading all names. This opcode - implements ``from module import *``. + Loads all symbols not starting with ``'_'`` directly from the module TOS to + the local namespace. The module is popped after loading all names. This + opcode implements ``from module import *``. .. opcode:: POP_BLOCK - Removes one block from the block stack. Per frame, there is a stack of blocks, - denoting nested loops, try statements, and such. + Removes one block from the block stack. Per frame, there is a stack of + blocks, denoting nested loops, try statements, and such. .. opcode:: POP_EXCEPT Removes one block from the block stack. The popped block must be an exception - handler block, as implicitly created when entering an except handler. - In addition to popping extraneous values from the frame stack, the - last three popped values are used to restore the exception state. + handler block, as implicitly created when entering an except handler. In + addition to popping extraneous values from the frame stack, the last three + popped values are used to restore the exception state. .. opcode:: END_FINALLY @@ -582,7 +639,7 @@ the stack so that it is available for further iterations of the loop. .. opcode:: LOAD_BUILD_CLASS Pushes :func:`builtins.__build_class__` onto the stack. It is later called - by ``CALL_FUNCTION`` to construct a class. + by :opcode:`CALL_FUNCTION` to construct a class. .. opcode:: SETUP_WITH (delta) @@ -597,11 +654,11 @@ the stack so that it is available for further iterations of the loop. :opcode:`UNPACK_SEQUENCE`). -.. opcode:: WITH_CLEANUP +.. opcode:: WITH_CLEANUP_START - Cleans up the stack when a :keyword:`with` statement block exits. TOS is - the context manager's :meth:`__exit__` bound method. Below TOS are 1--3 - values indicating how/why the finally clause was entered: + Cleans up the stack when a :keyword:`with` statement block exits. TOS is the + context manager's :meth:`__exit__` bound method. Below TOS are 1--3 values + indicating how/why the finally clause was entered: * SECOND = ``None`` * (SECOND, THIRD) = (``WHY_{RETURN,CONTINUE}``), retval @@ -609,12 +666,18 @@ the stack so that it is available for further iterations of the loop. * (SECOND, THIRD, FOURTH) = exc_info() In the last case, ``TOS(SECOND, THIRD, FOURTH)`` is called, otherwise - ``TOS(None, None, None)``. In addition, TOS is removed from the stack. + ``TOS(None, None, None)``. Pushes SECOND and result of the call + to the stack. + + +.. opcode:: WITH_CLEANUP_FINISH - If the stack represents an exception, *and* the function call returns - a 'true' value, this information is "zapped" and replaced with a single - ``WHY_SILENCED`` to prevent ``END_FINALLY`` from re-raising the exception. - (But non-local gotos will still be resumed.) + Pops exception type and result of 'exit' function call from the stack. + + If the stack represents an exception, *and* the function call returns a + 'true' value, this information is "zapped" and replaced with a single + ``WHY_SILENCED`` to prevent :opcode:`END_FINALLY` from re-raising the + exception. (But non-local gotos will still be resumed.) .. XXX explain the WHY stuff! @@ -625,8 +688,8 @@ the more significant byte last. .. opcode:: STORE_NAME (namei) Implements ``name = TOS``. *namei* is the index of *name* in the attribute - :attr:`co_names` of the code object. The compiler tries to use ``STORE_FAST`` - or ``STORE_GLOBAL`` if possible. + :attr:`co_names` of the code object. The compiler tries to use + :opcode:`STORE_FAST` or :opcode:`STORE_GLOBAL` if possible. .. opcode:: DELETE_NAME (namei) @@ -666,12 +729,12 @@ the more significant byte last. .. opcode:: STORE_GLOBAL (namei) - Works as ``STORE_NAME``, but stores the name as a global. + Works as :opcode:`STORE_NAME`, but stores the name as a global. .. opcode:: DELETE_GLOBAL (namei) - Works as ``DELETE_NAME``, but deletes a global name. + Works as :opcode:`DELETE_NAME`, but deletes a global name. .. opcode:: LOAD_CONST (consti) @@ -686,18 +749,18 @@ the more significant byte last. .. opcode:: BUILD_TUPLE (count) - Creates a tuple consuming *count* items from the stack, and pushes the resulting - tuple onto the stack. + Creates a tuple consuming *count* items from the stack, and pushes the + resulting tuple onto the stack. .. opcode:: BUILD_LIST (count) - Works as ``BUILD_TUPLE``, but creates a list. + Works as :opcode:`BUILD_TUPLE`, but creates a list. .. opcode:: BUILD_SET (count) - Works as ``BUILD_TUPLE``, but creates a set. + Works as :opcode:`BUILD_TUPLE`, but creates a set. .. opcode:: BUILD_MAP (count) @@ -721,8 +784,8 @@ the more significant byte last. Imports the module ``co_names[namei]``. TOS and TOS1 are popped and provide the *fromlist* and *level* arguments of :func:`__import__`. The module - object is pushed onto the stack. The current namespace is not affected: - for a proper import statement, a subsequent ``STORE_FAST`` instruction + object is pushed onto the stack. The current namespace is not affected: for + a proper import statement, a subsequent :opcode:`STORE_FAST` instruction modifies the namespace. @@ -730,7 +793,7 @@ the more significant byte last. Loads the attribute ``co_names[namei]`` from the module found in TOS. The resulting object is pushed onto the stack, to be subsequently stored by a - ``STORE_FAST`` instruction. + :opcode:`STORE_FAST` instruction. .. opcode:: JUMP_FORWARD (delta) @@ -750,14 +813,14 @@ the more significant byte last. .. opcode:: JUMP_IF_TRUE_OR_POP (target) - If TOS is true, sets the bytecode counter to *target* and leaves TOS - on the stack. Otherwise (TOS is false), TOS is popped. + If TOS is true, sets the bytecode counter to *target* and leaves TOS on the + stack. Otherwise (TOS is false), TOS is popped. .. opcode:: JUMP_IF_FALSE_OR_POP (target) - If TOS is false, sets the bytecode counter to *target* and leaves - TOS on the stack. Otherwise (TOS is true), TOS is popped. + If TOS is false, sets the bytecode counter to *target* and leaves TOS on the + stack. Otherwise (TOS is true), TOS is popped. .. opcode:: JUMP_ABSOLUTE (target) @@ -767,10 +830,10 @@ the more significant byte last. .. opcode:: FOR_ITER (delta) - ``TOS`` is an :term:`iterator`. Call its :meth:`~iterator.__next__` method. - If this yields a new value, push it on the stack (leaving the iterator below - it). If the iterator indicates it is exhausted ``TOS`` is popped, and the - byte code counter is incremented by *delta*. + TOS is an :term:`iterator`. Call its :meth:`~iterator.__next__` method. If + this yields a new value, push it on the stack (leaving the iterator below + it). If the iterator indicates it is exhausted TOS is popped, and the byte + code counter is incremented by *delta*. .. opcode:: LOAD_GLOBAL (namei) @@ -786,19 +849,15 @@ the more significant byte last. .. opcode:: SETUP_EXCEPT (delta) - Pushes a try block from a try-except clause onto the block stack. *delta* points - to the first except block. + Pushes a try block from a try-except clause onto the block stack. *delta* + points to the first except block. .. opcode:: SETUP_FINALLY (delta) - Pushes a try block from a try-except clause onto the block stack. *delta* points - to the finally block. - -.. opcode:: STORE_MAP + Pushes a try block from a try-except clause onto the block stack. *delta* + points to the finally block. - Store a key and value pair in a dictionary. Pops the key and value while leaving - the dictionary on the stack. .. opcode:: LOAD_FAST (var_num) @@ -818,8 +877,8 @@ the more significant byte last. .. opcode:: LOAD_CLOSURE (i) Pushes a reference to the cell contained in slot *i* of the cell and free - variable storage. The name of the variable is ``co_cellvars[i]`` if *i* is - less than the length of *co_cellvars*. Otherwise it is ``co_freevars[i - + variable storage. The name of the variable is ``co_cellvars[i]`` if *i* is + less than the length of *co_cellvars*. Otherwise it is ``co_freevars[i - len(co_cellvars)]``. @@ -859,11 +918,12 @@ the more significant byte last. Calls a function. The low byte of *argc* indicates the number of positional parameters, the high byte the number of keyword parameters. On the stack, the - opcode finds the keyword parameters first. For each keyword argument, the value - is on top of the key. Below the keyword parameters, the positional parameters - are on the stack, with the right-most parameter on top. Below the parameters, - the function object to call is on the stack. Pops all function arguments, and - the function itself off the stack, and pushes the return value. + opcode finds the keyword parameters first. For each keyword argument, the + value is on top of the key. Below the keyword parameters, the positional + parameters are on the stack, with the right-most parameter on top. Below the + parameters, the function object to call is on the stack. Pops all function + arguments, and the function itself off the stack, and pushes the return + value. .. opcode:: MAKE_FUNCTION (argc) @@ -886,8 +946,8 @@ the more significant byte last. Creates a new function object, sets its *__closure__* slot, and pushes it on the stack. TOS is the :term:`qualified name` of the function, TOS1 is the code associated with the function, and TOS2 is the tuple containing cells for - the closure's free variables. The function also has *argc* default parameters, - which are found below the cells. + the closure's free variables. *argc* is interpreted as in ``MAKE_FUNCTION``; + the annotations and defaults are also in the same order below TOS2. .. opcode:: BUILD_SLICE (argc) @@ -903,36 +963,37 @@ the more significant byte last. Prefixes any opcode which has an argument too big to fit into the default two bytes. *ext* holds two additional bytes which, taken together with the - subsequent opcode's argument, comprise a four-byte argument, *ext* being the two - most-significant bytes. + subsequent opcode's argument, comprise a four-byte argument, *ext* being the + two most-significant bytes. .. opcode:: CALL_FUNCTION_VAR (argc) - Calls a function. *argc* is interpreted as in ``CALL_FUNCTION``. The top element - on the stack contains the variable argument list, followed by keyword and - positional arguments. + Calls a function. *argc* is interpreted as in :opcode:`CALL_FUNCTION`. The + top element on the stack contains the variable argument list, followed by + keyword and positional arguments. .. opcode:: CALL_FUNCTION_KW (argc) - Calls a function. *argc* is interpreted as in ``CALL_FUNCTION``. The top element - on the stack contains the keyword arguments dictionary, followed by explicit - keyword and positional arguments. + Calls a function. *argc* is interpreted as in :opcode:`CALL_FUNCTION`. The + top element on the stack contains the keyword arguments dictionary, followed + by explicit keyword and positional arguments. .. opcode:: CALL_FUNCTION_VAR_KW (argc) - Calls a function. *argc* is interpreted as in ``CALL_FUNCTION``. The top - element on the stack contains the keyword arguments dictionary, followed by the - variable-arguments tuple, followed by explicit keyword and positional arguments. + Calls a function. *argc* is interpreted as in :opcode:`CALL_FUNCTION`. The + top element on the stack contains the keyword arguments dictionary, followed + by the variable-arguments tuple, followed by explicit keyword and positional + arguments. .. opcode:: HAVE_ARGUMENT - This is not really an opcode. It identifies the dividing line between opcodes - which don't take arguments ``< HAVE_ARGUMENT`` and those which do ``>= - HAVE_ARGUMENT``. + This is not really an opcode. It identifies the dividing line between + opcodes which don't take arguments ``< HAVE_ARGUMENT`` and those which do + ``>= HAVE_ARGUMENT``. .. _opcode_collections: @@ -964,10 +1025,10 @@ instructions: .. data:: hasfree - Sequence of bytecodes that access a free variable (note that 'free' in - this context refers to names in the current scope that are referenced by - inner scopes or names in outer scopes that are referenced from this scope. - It does *not* include references to global or builtin scopes). + Sequence of bytecodes that access a free variable (note that 'free' in this + context refers to names in the current scope that are referenced by inner + scopes or names in outer scopes that are referenced from this scope. It does + *not* include references to global or builtin scopes). .. data:: hasname diff --git a/Doc/library/distribution.rst b/Doc/library/distribution.rst index fb3f5df59984..3e6e84b42a2e 100644 --- a/Doc/library/distribution.rst +++ b/Doc/library/distribution.rst @@ -4,7 +4,7 @@ Software Packaging and Distribution These libraries help you with publishing and installing Python software. While these modules are designed to work in conjunction with the -`Python Package Index <https://pypi.python.org>`__, they can also be used +`Python Package Index <https://pypi.python.org/pypi>`__, they can also be used with a local index server, or without any index server at all. .. toctree:: @@ -12,3 +12,4 @@ with a local index server, or without any index server at all. distutils.rst ensurepip.rst venv.rst + zipapp.rst diff --git a/Doc/library/distutils.rst b/Doc/library/distutils.rst index 6666a9b7d725..e3d131457255 100644 --- a/Doc/library/distutils.rst +++ b/Doc/library/distutils.rst @@ -12,14 +12,31 @@ additional modules into a Python installation. The new modules may be either 100%-pure Python, or may be extension modules written in C, or may be collections of Python packages which include modules coded in both Python and C. +Most Python users will *not* want to use this module directly, but instead +use the cross-version tools maintained by the Python Packaging Authority. In +particular, +`setuptools <https://setuptools.pypa.io/en/latest/setuptools.html>`__ is an +enhanced alternative to :mod:`distutils` that provides: -User documentation and API reference are provided in another document: +* support for declaring project dependencies +* additional mechanisms for configuring which files to include in source + releases (including plugins for integration with version control systems) +* the ability to declare project "entry points", which can be used as the + basis for application plugin systems +* the ability to automatically generate Windows command line executables at + installation time rather than needing to prebuild them +* consistent behaviour across all supported Python versions -.. seealso:: +The recommended `pip <https://pip.pypa.io/>`__ installer runs all +``setup.py`` scripts with ``setuptools``, even if the script itself only +imports ``distutils``. Refer to the +`Python Packaging User Guide <https://packaging.python.org>`_ for more +information. - :ref:`distutils-index` - The manual for developers and packagers of Python modules. This describes - how to prepare :mod:`distutils`\ -based packages so that they may be - easily installed into an existing Python installation. It also contains - instructions for end-users wanting to install a distutils-based package, - :ref:`install-index`. +For the benefits of packaging tool authors and users seeking a deeper +understanding of the details of the current packaging and distribution +system, the legacy :mod:`distutils` based user documentation and API +reference remain available: + +* :ref:`install-index` +* :ref:`distutils-index` diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst index 28df49c70036..9f7d12c626b2 100644 --- a/Doc/library/doctest.rst +++ b/Doc/library/doctest.rst @@ -502,7 +502,8 @@ or'ed together and passed to various functions. The names can also be used in :ref:`doctest directives <doctest-directives>`, and may be passed to the doctest command line interface via the ``-o`` option. -.. versionadded:: 3.4 the ``-o`` command line option +.. versionadded:: 3.4 + The ``-o`` command line option. The first group of options define test semantics, controlling aspects of how doctest decides whether actual output matches an example's expected output: @@ -864,8 +865,8 @@ and :ref:`doctest-simple-testfile`. nothing at the end. In verbose mode, the summary is detailed, else the summary is very brief (in fact, empty if all tests passed). - Optional argument *optionflags* or's together option flags. See section - :ref:`doctest-options`. + Optional argument *optionflags* (default value 0) takes the bitwise-or of + option flags. See section :ref:`doctest-options`. Optional argument *raise_on_error* defaults to false. If true, an exception is raised upon the first failure or unexpected exception in an example. This @@ -913,15 +914,10 @@ and :ref:`doctest-simple-testfile`. above, except that *globs* defaults to ``m.__dict__``. -There's also a function to run the doctests associated with a single object. -This function is provided for backward compatibility. There are no plans to -deprecate it, but it's rarely useful: - - .. function:: run_docstring_examples(f, globs, verbose=False, name="NoName", compileflags=None, optionflags=0) - Test examples associated with object *f*; for example, *f* may be a module, - function, or class object. + Test examples associated with object *f*; for example, *f* may be a string, + a module, a function, or a class object. A shallow copy of dictionary argument *globs* is used for the execution context. @@ -1057,15 +1053,9 @@ from text files and modules with doctests: This function uses the same search technique as :func:`testmod`. - .. note:: - Unlike :func:`testmod` and :class:`DocTestFinder`, this function raises - a :exc:`ValueError` if *module* contains no docstrings. You can prevent - this error by passing a :class:`DocTestFinder` instance as the - *test_finder* argument with its *exclude_empty* keyword argument set - to ``False``:: - - >>> finder = doctest.DocTestFinder(exclude_empty=False) - >>> suite = doctest.DocTestSuite(test_finder=finder) + .. versionchanged:: 3.5 + :func:`DocTestSuite` returns an empty :class:`unittest.TestSuite` if *module* + contains no docstrings instead of raising :exc:`ValueError`. Under the covers, :func:`DocTestSuite` creates a :class:`unittest.TestSuite` out @@ -1096,7 +1086,7 @@ reporting flags specific to :mod:`unittest` support, via this function: Set the :mod:`doctest` reporting flags to use. - Argument *flags* or's together option flags. See section + Argument *flags* takes the bitwise-or of option flags. See section :ref:`doctest-options`. Only "reporting flags" can be used. This is a module-global setting, and affects all future doctests run by module @@ -1820,6 +1810,27 @@ several options for organizing tests: * Define a ``__test__`` dictionary mapping from regression test topics to docstrings containing test cases. +When you have placed your tests in a module, the module can itself be the test +runner. When a test fails, you can arrange for your test runner to re-run only +the failing doctest while you debug the problem. Here is a minimal example of +such a test runner:: + + if __name__ == '__main__': + import doctest + flags = doctest.REPORT_NDIFF|doctest.FAIL_FAST + if len(sys.argv) > 1: + name = sys.argv[1] + if name in globals(): + obj = globals()[name] + else: + obj = __test__[name] + doctest.run_docstring_examples(obj, globals(), name=name, + optionflags=flags) + else: + fail, total = doctest.testmod(optionflags=flags) + print("{} failures out of {} tests".format(fail, total)) + + .. rubric:: Footnotes .. [#] Examples containing both expected output and an exception are not supported. diff --git a/Doc/library/email-examples.rst b/Doc/library/email-examples.rst index 32cecf3486c1..cbbcb78e245c 100644 --- a/Doc/library/email-examples.rst +++ b/Doc/library/email-examples.rst @@ -40,6 +40,36 @@ text version: [2]_ .. literalinclude:: ../includes/email-alternative.py +.. _email-contentmanager-api-examples: + +Examples using the Provisional API +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Here is a reworking of the last example using the provisional API. To make +things a bit more interesting, we include a related image in the html part, and +we save a copy of what we are going to send to disk, as well as sending it. + +This example also shows how easy it is to include non-ASCII, and simplifies the +sending of the message using the :meth:`.send_message` method of the +:mod:`smtplib` module. + +.. literalinclude:: ../includes/email-alternative-new-api.py + +If we were instead sent the message from the last example, here is one +way we could process it: + +.. literalinclude:: ../includes/email-read-alternative-new-api.py + +Up to the prompt, the output from the above is:: + + To: Penelope Pussycat <"penelope@example.com">, Fabrette Pussycat <"fabrette@example.com"> + From: Pepé Le Pew <pepe@example.com> + Subject: Ayons asperges pour le déjeuner + + Salut! + + Cela ressemble à un excellent recipie[1] déjeuner. + + .. rubric:: Footnotes .. [1] Thanks to Matthew Dixon Cowles for the original inspiration and examples. diff --git a/Doc/library/email.charset.rst b/Doc/library/email.charset.rst index 19a69532edab..80ef3d62ccc4 100644 --- a/Doc/library/email.charset.rst +++ b/Doc/library/email.charset.rst @@ -234,5 +234,5 @@ new entries to the global character set, alias, and codec registries: *charset* is the canonical name of a character set. *codecname* is the name of a Python codec, as appropriate for the second argument to the :class:`str`'s - :meth:`~str.encode` method + :meth:`~str.encode` method. diff --git a/Doc/library/email.contentmanager.rst b/Doc/library/email.contentmanager.rst index 5162da18faab..f53d34b34cba 100644 --- a/Doc/library/email.contentmanager.rst +++ b/Doc/library/email.contentmanager.rst @@ -54,6 +54,7 @@ this module. documented in this module because of the provisional nature of the code, the implementation lives in the :mod:`email.message` module. +.. currentmodule:: email.message .. class:: EmailMessage(policy=default) @@ -69,11 +70,15 @@ this module. the following methods: - .. attribute:: is_attachment + .. method:: is_attachment - Set to ``True`` if there is a :mailheader:`Content-Disposition` header + Return ``True`` if there is a :mailheader:`Content-Disposition` header and its (case insensitive) value is ``attachment``, ``False`` otherwise. + .. versionchanged:: 3.4.2 + is_attachment is now a method instead of a property, for consistency + with :meth:`~email.message.Message.is_multipart`. + .. method:: get_body(preferencelist=('related', 'html', 'plain')) @@ -235,6 +240,16 @@ this module. all other headers intact and in their original order. +.. class:: MIMEPart(policy=default) + + This class represents a subpart of a MIME message. It is identical to + :class:`EmailMessage`, except that no :mailheader:`MIME-Version` headers are + added when :meth:`~EmailMessage.set_content` is called, since sub-parts do + not need their own :mailheader:`MIME-Version` headers. + + +.. currentmodule:: email.contentmanager + .. class:: ContentManager() Base class for content managers. Provides the standard registry mechanisms @@ -305,14 +320,6 @@ this module. values of *typekey*, see :meth:`set_content`. -.. class:: MIMEPart(policy=default) - - This class represents a subpart of a MIME message. It is identical to - :class:`EmailMessage`, except that no :mailheader:`MIME-Version` headers are - added when :meth:`~EmailMessage.set_content` is called, since sub-parts do - not need their own :mailheader:`MIME-Version` headers. - - Content Manager Instances ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -418,7 +425,7 @@ Currently the email package provides only one concrete content manager, *cid* as its value. If *params* is specified, iterate its ``items`` method and use the - resulting ``(key, value)`` pairs to set additional paramters on the + resulting ``(key, value)`` pairs to set additional parameters on the :mailheader:`Content-Type` header. If *headers* is specified and is a list of strings of the form diff --git a/Doc/library/email.generator.rst b/Doc/library/email.generator.rst index c172acbad305..48d41e1dc78e 100644 --- a/Doc/library/email.generator.rst +++ b/Doc/library/email.generator.rst @@ -112,7 +112,7 @@ formatted string representation of a message object. For more detail, see :mod:`email.message`. .. class:: BytesGenerator(outfp, mangle_from_=True, maxheaderlen=78, *, \ - policy=policy.default) + policy=None) The constructor for the :class:`BytesGenerator` class takes a binary :term:`file-like object` called *outfp* for an argument. *outfp* must @@ -134,9 +134,11 @@ formatted string representation of a message object. For more detail, see wrapping. The default is 78, as recommended (but not required) by :rfc:`2822`. + The *policy* keyword specifies a :mod:`~email.policy` object that controls a - number of aspects of the generator's operation. The default policy - maintains backward compatibility. + number of aspects of the generator's operation. If no *policy* is specified, + then the *policy* attached to the message object passed to :attr:`flatten` + is used. .. versionchanged:: 3.3 Added the *policy* keyword. @@ -174,7 +176,7 @@ formatted string representation of a message object. For more detail, see Optional *linesep* specifies the line separator character used to terminate lines in the output. If specified it overrides the value - specified by the ``Generator``\ 's ``policy``. + specified by the ``Generator``\ or *msg*\ 's ``policy``. .. method:: clone(fp) diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst index 84a5f5138ccb..b91f26d12045 100644 --- a/Doc/library/email.message.rst +++ b/Doc/library/email.message.rst @@ -34,7 +34,7 @@ Here are the methods of the :class:`Message` class: .. class:: Message(policy=compat32) If *policy* is specified (it must be an instance of a :mod:`~email.policy` - class) use the rules it specifies to udpate and serialize the representation + class) use the rules it specifies to update and serialize the representation of the message. If *policy* is not set, use the :class:`compat32 <email.policy.Compat32>` policy, which maintains backward compatibility with the Python 3.2 version of the email package. For more information see the @@ -131,7 +131,11 @@ Here are the methods of the :class:`Message` class: Return ``True`` if the message's payload is a list of sub-\ :class:`Message` objects, otherwise return ``False``. When - :meth:`is_multipart` returns ``False``, the payload should be a string object. + :meth:`is_multipart` returns ``False``, the payload should be a string + object. (Note that :meth:`is_multipart` returning ``True`` does not + necessarily mean that "msg.get_content_maintype() == 'multipart'" will + return the ``True``. For example, ``is_multipart`` will return ``True`` + when the :class:`Message` is of type ``message/rfc822``.) .. method:: set_unixfrom(unixfrom) @@ -466,7 +470,7 @@ Here are the methods of the :class:`Message` class: to ``False``. - .. method:: set_param(param, value, header='Content-Type', requote=True, + .. method:: set_param(param, value, header='Content-Type', requote=True, \ charset=None, language='', replace=False) Set a parameter in the :mailheader:`Content-Type` header. If the @@ -488,7 +492,7 @@ Here are the methods of the :class:`Message` class: end of the list of headers. If *replace* is ``True``, the header will be updated in place. - .. versionchanged: 3.4 ``replace`` keyword was added. + .. versionchanged:: 3.4 ``replace`` keyword was added. .. method:: del_param(param, header='content-type', requote=True) @@ -574,6 +578,15 @@ Here are the methods of the :class:`Message` class: will be *failobj*. + .. method:: get_content_disposition() + + Return the lowercased value (without parameters) of the message's + :mailheader:`Content-Disposition` header if it has one, or ``None``. The + possible values for this method are *inline*, *attachment* or ``None`` + if the message follows :rfc:`2183`. + + .. versionadded:: 3.5 + .. method:: walk() The :meth:`walk` method is an all-purpose generator which can be used to @@ -584,23 +597,56 @@ Here are the methods of the :class:`Message` class: Here's an example that prints the MIME type of every part of a multipart message structure: - .. testsetup:: - - >>> from email import message_from_binary_file - >>> with open('Lib/test/test_email/data/msg_16.txt', 'rb') as f: - ... msg = message_from_binary_file(f) - - .. doctest:: + .. testsetup:: + + >>> from email import message_from_binary_file + >>> with open('Lib/test/test_email/data/msg_16.txt', 'rb') as f: + ... msg = message_from_binary_file(f) + >>> from email.iterators import _structure + + .. doctest:: + + >>> for part in msg.walk(): + ... print(part.get_content_type()) + multipart/report + text/plain + message/delivery-status + text/plain + text/plain + message/rfc822 + text/plain + + ``walk`` iterates over the subparts of any part where + :meth:`is_multipart` returns ``True``, even though + ``msg.get_content_maintype() == 'multipart'`` may return ``False``. We + can see this in our example by making use of the ``_structure`` debug + helper function: + + .. doctest:: + + >>> for part in msg.walk(): + ... print(part.get_content_maintype() == 'multipart'), + ... part.is_multipart()) + True True + False False + False True + False False + False False + False True + False False + >>> _structure(msg) + multipart/report + text/plain + message/delivery-status + text/plain + text/plain + message/rfc822 + text/plain + + Here the ``message`` parts are not ``multiparts``, but they do contain + subparts. ``is_multipart()`` returns ``True`` and ``walk`` descends + into the subparts. - >>> for part in msg.walk(): - ... print(part.get_content_type()) - multipart/report - text/plain - message/delivery-status - text/plain - text/plain - message/rfc822 - text/plain :class:`Message` objects can also optionally contain two instance attributes, which can be used when generating the plain text of a MIME message. diff --git a/Doc/library/email.mime.rst b/Doc/library/email.mime.rst index 4cdb322f4604..67d0a679549c 100644 --- a/Doc/library/email.mime.rst +++ b/Doc/library/email.mime.rst @@ -194,8 +194,9 @@ Here are the classes: minor type and defaults to :mimetype:`plain`. *_charset* is the character set of the text and is passed as an argument to the :class:`~email.mime.nonmultipart.MIMENonMultipart` constructor; it defaults - to ``us-ascii`` if the string contains only ``ascii`` codepoints, and - ``utf-8`` otherwise. + to ``us-ascii`` if the string contains only ``ascii`` code points, and + ``utf-8`` otherwise. The *_charset* parameter accepts either a string or a + :class:`~email.charset.Charset` instance. Unless the *_charset* argument is explicitly set to ``None``, the MIMEText object created will have both a :mailheader:`Content-Type` header @@ -206,3 +207,6 @@ Here are the classes: ``Content-Transfer-Encoding`` header, after which a ``set_payload`` call will automatically encode the new payload (and add a new :mailheader:`Content-Transfer-Encoding` header). + + .. versionchanged:: 3.5 + *_charset* also accepts :class:`~email.charset.Charset` instances. diff --git a/Doc/library/email.parser.rst b/Doc/library/email.parser.rst index ee6af3fb392a..ec74fe028a58 100644 --- a/Doc/library/email.parser.rst +++ b/Doc/library/email.parser.rst @@ -60,15 +60,18 @@ list of defects that it can find. Here is the API for the :class:`FeedParser`: -.. class:: FeedParser(_factory=email.message.Message, *, policy=policy.default) +.. class:: FeedParser(_factory=email.message.Message, *, policy=policy.compat32) Create a :class:`FeedParser` instance. Optional *_factory* is a no-argument callable that will be called whenever a new message object is needed. It defaults to the :class:`email.message.Message` class. - The *policy* keyword specifies a :mod:`~email.policy` object that controls a - number of aspects of the parser's operation. The default policy maintains - backward compatibility. + If *policy* is specified (it must be an instance of a :mod:`~email.policy` + class) use the rules it specifies to update the representation of the + message. If *policy* is not set, use the :class:`compat32 + <email.policy.Compat32>` policy, which maintains backward compatibility with + the Python 3.2 version of the email package. For more information see the + :mod:`~email.policy` documentation. .. versionchanged:: 3.3 Added the *policy* keyword. @@ -113,7 +116,7 @@ have the same API as the :class:`Parser` and :class:`BytesParser` classes. The BytesHeaderParser class. -.. class:: Parser(_class=email.message.Message, *, policy=policy.default) +.. class:: Parser(_class=email.message.Message, *, policy=policy.compat32) The constructor for the :class:`Parser` class takes an optional argument *_class*. This must be a callable factory (such as a function or a class), and @@ -121,9 +124,12 @@ have the same API as the :class:`Parser` and :class:`BytesParser` classes. :class:`~email.message.Message` (see :mod:`email.message`). The factory will be called without arguments. - The *policy* keyword specifies a :mod:`~email.policy` object that controls a - number of aspects of the parser's operation. The default policy maintains - backward compatibility. + If *policy* is specified (it must be an instance of a :mod:`~email.policy` + class) use the rules it specifies to update the representation of the + message. If *policy* is not set, use the :class:`compat32 + <email.policy.Compat32>` policy, which maintains backward compatibility with + the Python 3.2 version of the email package. For more information see the + :mod:`~email.policy` documentation. .. versionchanged:: 3.3 Removed the *strict* argument that was deprecated in 2.4. Added the @@ -159,20 +165,23 @@ have the same API as the :class:`Parser` and :class:`BytesParser` classes. Optional *headersonly* is as with the :meth:`parse` method. -.. class:: BytesParser(_class=email.message.Message, *, policy=policy.default) +.. class:: BytesParser(_class=email.message.Message, *, policy=policy.compat32) This class is exactly parallel to :class:`Parser`, but handles bytes input. The *_class* and *strict* arguments are interpreted in the same way as for the :class:`Parser` constructor. - The *policy* keyword specifies a :mod:`~email.policy` object that - controls a number of aspects of the parser's operation. The default - policy maintains backward compatibility. + If *policy* is specified (it must be an instance of a :mod:`~email.policy` + class) use the rules it specifies to update the representation of the + message. If *policy* is not set, use the :class:`compat32 + <email.policy.Compat32>` policy, which maintains backward compatibility with + the Python 3.2 version of the email package. For more information see the + :mod:`~email.policy` documentation. .. versionchanged:: 3.3 Removed the *strict* argument. Added the *policy* keyword. - .. method:: parse(fp, headeronly=False) + .. method:: parse(fp, headersonly=False) Read all the data from the binary file-like object *fp*, parse the resulting bytes, and return the message object. *fp* must support @@ -209,7 +218,7 @@ in the top-level :mod:`email` package namespace. .. currentmodule:: email .. function:: message_from_string(s, _class=email.message.Message, *, \ - policy=policy.default) + policy=policy.compat32) Return a message object structure from a string. This is exactly equivalent to ``Parser().parsestr(s)``. *_class* and *policy* are interpreted as @@ -219,7 +228,7 @@ in the top-level :mod:`email` package namespace. Removed the *strict* argument. Added the *policy* keyword. .. function:: message_from_bytes(s, _class=email.message.Message, *, \ - policy=policy.default) + policy=policy.compat32) Return a message object structure from a byte string. This is exactly equivalent to ``BytesParser().parsebytes(s)``. Optional *_class* and @@ -231,7 +240,7 @@ in the top-level :mod:`email` package namespace. Removed the *strict* argument. Added the *policy* keyword. .. function:: message_from_file(fp, _class=email.message.Message, *, \ - policy=policy.default) + policy=policy.compat32) Return a message object structure tree from an open :term:`file object`. This is exactly equivalent to ``Parser().parse(fp)``. *_class* @@ -242,7 +251,7 @@ in the top-level :mod:`email` package namespace. Removed the *strict* argument. Added the *policy* keyword. .. function:: message_from_binary_file(fp, _class=email.message.Message, *, \ - policy=policy.default) + policy=policy.compat32) Return a message object structure tree from an open binary :term:`file object`. This is exactly equivalent to ``BytesParser().parse(fp)``. diff --git a/Doc/library/email.policy.rst b/Doc/library/email.policy.rst index c2f9e6a9abd4..045b11930305 100644 --- a/Doc/library/email.policy.rst +++ b/Doc/library/email.policy.rst @@ -99,7 +99,7 @@ separators. Some email package methods accept a *policy* keyword argument, allowing the policy to be overridden for that method. For example, the following code uses -the :meth:`~email.message.Message.as_string` method of the *msg* object from +the :meth:`~email.message.Message.as_bytes` method of the *msg* object from the previous example and writes the message to a file using the native line separators for the platform on which it is running:: @@ -187,6 +187,18 @@ added matters. To illustrate:: :const:`False` (the default), defects will be passed to the :meth:`register_defect` method. + + + .. attribute:: mangle_from\_ + + If :const:`True`, lines starting with *"From "* in the body are + escaped by putting a ``>`` in front of them. This parameter is used when + the message is being serialized by a generator. + Default: :const:`False`. + + .. versionadded:: 3.5 + The *mangle_from_* parameter. + The following :class:`Policy` method is intended to be called by code using the email library to create policy instances with custom settings: @@ -319,6 +331,13 @@ added matters. To illustrate:: :const:`compat32`, that is used as the default policy. Thus the default behavior of the email package is to maintain compatibility with Python 3.2. + The following attributes have values that are different from the + :class:`Policy` default: + + .. attribute:: mangle_from_ + + The default is ``True``. + The class provides the following concrete implementations of the abstract methods of :class:`Policy`: @@ -356,6 +375,14 @@ added matters. To illustrate:: line breaks and any (RFC invalid) binary data it may contain. +An instance of :class:`Compat32` is provided as a module constant: + +.. data:: compat32 + + An instance of :class:`Compat32`, providing backward compatibility with the + behavior of the email package in Python 3.2. + + .. note:: The documentation below describes new policies that are included in the @@ -378,6 +405,14 @@ added matters. To illustrate:: In addition to the settable attributes listed above that apply to all policies, this policy adds the following additional attributes: + .. attribute:: utf8 + + If ``False``, follow :rfc:`5322`, supporting non-ASCII characters in + headers by encoding them as "encoded words". If ``True``, follow + :rfc:`6532` and use ``utf-8`` encoding for headers. Messages + formatted in this way may be passed to SMTP servers that support + the ``SMTPUTF8`` extension (:rfc:`6531`). + .. attribute:: refold_source If the value for a header in the ``Message`` object originated from a @@ -419,7 +454,7 @@ added matters. To illustrate:: additional arguments. By default ``content_manager`` is set to :data:`~email.contentmanager.raw_data_manager`. - .. versionadded 3.4 + .. versionadded:: 3.4 The class provides the following concrete implementations of the abstract @@ -499,6 +534,14 @@ more closely to the RFCs relevant to their domains. Like ``default``, but with ``linesep`` set to ``\r\n``, which is RFC compliant. +.. data:: SMTPUTF8 + + The same as ``SMTP`` except that :attr:`~EmailPolicy.utf8` is ``True``. + Useful for serializing messages to a message store without using encoded + words in the headers. Should only be used for SMTP trasmission if the + sender or recipient addresses have non-ASCII characters (the + :meth:`smtplib.SMTP.send_message` method handles this automatically). + .. data:: HTTP Suitable for serializing headers with for use in HTTP traffic. Like diff --git a/Doc/library/email.rst b/Doc/library/email.rst index 331d2ef0e4b2..95c0a2f4a860 100644 --- a/Doc/library/email.rst +++ b/Doc/library/email.rst @@ -91,15 +91,19 @@ table also describes the Python compatibility of each version of the package. +---------------+------------------------------+-----------------------+ | :const:`2.5` | Python 2.2.2+ and Python 2.3 | Python 2.1 to 2.5 | +---------------+------------------------------+-----------------------+ -| :const:`3.0` | Python 2.4 | Python 2.3 to 2.5 | +| :const:`3.0` | Python 2.4 and Python 2.5 | Python 2.3 to 2.6 | +---------------+------------------------------+-----------------------+ -| :const:`4.0` | Python 2.5 | Python 2.3 to 2.5 | +| :const:`4.0` | Python 2.5 to Python 2.7 | Python 2.3 to 2.7 | +---------------+------------------------------+-----------------------+ | :const:`5.0` | Python 3.0 and Python 3.1 | Python 3.0 to 3.2 | +---------------+------------------------------+-----------------------+ -| :const:`5.1` | Python 3.2 | Python 3.0 to 3.2 | +| :const:`5.1` | Python 3.2 | Python 3.2 | +---------------+------------------------------+-----------------------+ +After Version 5.1 (Python 3.2), the email package no longer has a version that +is separate from the Python version. (See the :ref:`whatsnew-index` documents +for the respective Python versions for details on changes.) + Here are the major differences between :mod:`email` version 5.1 and version 5.0: @@ -258,7 +262,7 @@ Differences from :mod:`mimelib` ------------------------------- The :mod:`email` package was originally prototyped as a separate library called -`mimelib <http://mimelib.sf.net/>`_. Changes have been made so that method names +`mimelib <http://mimelib.sourceforge.net/>`_. Changes have been made so that method names are more consistent, and some methods or modules have either been added or removed. The semantics of some of the methods have also changed. For the most part, any functionality available in :mod:`mimelib` is still available in the diff --git a/Doc/library/email.util.rst b/Doc/library/email.util.rst index f75975eaa922..219e2847ea2d 100644 --- a/Doc/library/email.util.rst +++ b/Doc/library/email.util.rst @@ -98,12 +98,9 @@ There are several useful utilities provided in the :mod:`email.utils` module: .. function:: mktime_tz(tuple) - Turn a 10-tuple as returned by :func:`parsedate_tz` into a UTC timestamp. It - the timezone item in the tuple is ``None``, assume local time. Minor - deficiency: :func:`mktime_tz` interprets the first 8 elements of *tuple* as a - local time and then compensates for the timezone difference. This may yield a - slight error around changes in daylight savings time, though not worth worrying - about for common use. + Turn a 10-tuple as returned by :func:`parsedate_tz` into a UTC + timestamp (seconds since the Epoch). If the timezone item in the + tuple is ``None``, assume local time. .. function:: formatdate(timeval=None, localtime=False, usegmt=False) @@ -210,4 +207,3 @@ There are several useful utilities provided in the :mod:`email.utils` module: .. [#] Note that the sign of the timezone offset is the opposite of the sign of the ``time.timezone`` variable for the same timezone; the latter variable follows the POSIX standard while this module follows :rfc:`2822`. - diff --git a/Doc/library/ensurepip.rst b/Doc/library/ensurepip.rst index 3756d4fbcb75..d589f1cf12f3 100644 --- a/Doc/library/ensurepip.rst +++ b/Doc/library/ensurepip.rst @@ -2,9 +2,11 @@ ======================================================== .. module:: ensurepip - :synopsis: Bootstrapping the ``pip`` installer into an existing Python + :synopsis: Bootstrapping the "pip" installer into an existing Python installation or virtual environment. +.. versionadded:: 3.4 + The :mod:`ensurepip` package provides support for bootstrapping the ``pip`` installer into an existing Python installation or virtual environment. This bootstrapping approach reflects the fact that ``pip`` is an independent @@ -18,8 +20,6 @@ needed if installing ``pip`` was skipped when installing Python (or when creating a virtual environment) or after explicitly uninstalling ``pip``. -.. versionadded:: 3.4 - .. note:: This module *does not* access the internet. All of the components @@ -28,7 +28,7 @@ when creating a virtual environment) or after explicitly uninstalling .. seealso:: - :ref:`install-index` + :ref:`installing-index` The end user guide for installing Python packages :pep:`453`: Explicit bootstrapping of pip in Python installations @@ -117,6 +117,12 @@ Module API *verbosity* controls the level of output to :data:`sys.stdout` from the bootstrapping operation. + .. note:: + + The bootstrapping process has side effects on both ``sys.path`` and + ``os.environ``. Invoking the command line interface in a subprocess + instead allows these side effects to be avoided. + .. note:: The bootstrapping process may install additional modules required by diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index c2030faf8bbd..0fbbf5af79fc 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -9,18 +9,37 @@ .. :sectionauthor:: Eli Bendersky <eliben@gmail.com>, .. :sectionauthor:: Ethan Furman <ethan@stoneleaf.us> +.. versionadded:: 3.4 + **Source code:** :source:`Lib/enum.py` ---------------- -An enumeration is a set of symbolic names (members) bound to unique, constant -values. Within an enumeration, the members can be compared by identity, and -the enumeration itself can be iterated over. +An enumeration is a set of symbolic names (members) bound to unique, +constant values. Within an enumeration, the members can be compared +by identity, and the enumeration itself can be iterated over. + + +Module Contents +--------------- This module defines two enumeration classes that can be used to define unique sets of names and values: :class:`Enum` and :class:`IntEnum`. It also defines -one decorator, :func:`unique`, that ensures only unique member values are -present in an enumeration. +one decorator, :func:`unique`. + +.. class:: Enum + + Base class for creating enumerated constants. See section + `Functional API`_ for an alternate construction syntax. + +.. class:: IntEnum + + Base class for creating enumerated constants that are also + subclasses of :class:`int`. + +.. function:: unique + + Enum class decorator that ensures only one name is bound to any one value. Creating an Enum @@ -120,7 +139,7 @@ If you want to access enum members by *name*, use item access:: >>> Color['green'] <Color.green: 2> -If have an enum member and need its :attr:`name` or :attr:`value`:: +If you have an enum member and need its :attr:`name` or :attr:`value`:: >>> member = Color.red >>> member.name @@ -238,7 +257,7 @@ members are not integers (but see `IntEnum`_ below):: >>> Color.red < Color.blue Traceback (most recent call last): File "<stdin>", line 1, in <module> - TypeError: unorderable types: Color() < Color() + TypeError: '<' not supported between instances of 'Color' and 'Color' Equality comparisons are defined though:: @@ -295,11 +314,11 @@ Then:: >>> str(Mood.funky) 'my custom str! 1' -The rules for what is allowed are as follows: _sunder_ names (starting and -ending with a single underscore) are reserved by enum and cannot be used; -all other attributes defined within an enumeration will become members of this -enumeration, with the exception of *__dunder__* names and descriptors (methods -are also descriptors). +The rules for what is allowed are as follows: names that start and end with a +with a single underscore are reserved by enum and cannot be used; all other +attributes defined within an enumeration will become members of this +enumeration, with the exception of special methods (:meth:`__str__`, +:meth:`__add__`, etc.) and descriptors (methods are also descriptors). Note: if your enumeration defines :meth:`__new__` and/or :meth:`__init__` then whatever value(s) were given to the enum member will be passed into those @@ -350,10 +369,13 @@ The usual restrictions for pickling apply: picklable enums must be defined in the top level of a module, since unpickling requires them to be importable from that module. -.. warning:: +.. note:: + + With pickle protocol version 4 it is possible to easily pickle enums + nested in other classes. - In order to support the singleton nature of enumeration members, pickle - protocol version 2 or higher must be used. +It is possible to modify how Enum members are pickled/unpickled by defining +:meth:`__reduce_ex__` in the enumeration class. Functional API @@ -378,11 +400,12 @@ The second argument is the *source* of enumeration member names. It can be a whitespace-separated string of names, a sequence of names, a sequence of 2-tuples with key/value pairs, or a mapping (e.g. dictionary) of names to values. The last two options enable assigning arbitrary values to -enumerations; the others auto-assign increasing integers starting with 1. A +enumerations; the others auto-assign increasing integers starting with 1 (use +the ``start`` parameter to specify a different starting value). A new class derived from :class:`Enum` is returned. In other words, the above assignment to :class:`Animal` is equivalent to:: - >>> class Animals(Enum): + >>> class Animal(Enum): ... ant = 1 ... bee = 2 ... cat = 3 @@ -399,7 +422,55 @@ enumeration is being created in (e.g. it will fail if you use a utility function in separate module, and also may not work on IronPython or Jython). The solution is to specify the module name explicitly as follows:: - >>> Animals = Enum('Animals', 'ant bee cat dog', module=__name__) + >>> Animal = Enum('Animal', 'ant bee cat dog', module=__name__) + +.. warning:: + + If ``module`` is not supplied, and Enum cannot determine what it is, + the new Enum members will not be unpicklable; to keep errors closer to + the source, pickling will be disabled. + +The new pickle protocol 4 also, in some circumstances, relies on +:attr:`__qualname__` being set to the location where pickle will be able +to find the class. For example, if the class was made available in class +SomeData in the global scope:: + + >>> Animal = Enum('Animal', 'ant bee cat dog', qualname='SomeData.Animal') + +The complete signature is:: + + Enum(value='NewEnumName', names=<...>, *, module='...', qualname='...', type=<mixed-in class>, start=1) + +:value: What the new Enum class will record as its name. + +:names: The Enum members. This can be a whitespace or comma separated string + (values will start at 1 unless otherwise specified):: + + 'red green blue' | 'red,green,blue' | 'red, green, blue' + + or an iterator of names:: + + ['red', 'green', 'blue'] + + or an iterator of (name, value) pairs:: + + [('cyan', 4), ('magenta', 5), ('yellow', 6)] + + or a mapping:: + + {'chartreuse': 7, 'sea_green': 11, 'rosemary': 42} + +:module: name of module where new Enum class can be found. + +:qualname: where in module new Enum class can be found. + +:type: type to mix in to new Enum class. + +:start: number to start counting at if only names are passed in. + +.. versionchanged:: 3.5 + The *start* parameter was added. + Derived Enumerations -------------------- @@ -482,7 +553,7 @@ Some rules: add methods and don't specify another data type such as :class:`int` or :class:`str`. 3. When another data type is mixed in, the :attr:`value` attribute is *not the - same* as the enum member itself, although it is equivalant and will compare + same* as the enum member itself, although it is equivalent and will compare equal. 4. %-style formatting: `%s` and `%r` call :class:`Enum`'s :meth:`__str__` and :meth:`__repr__` respectively; other codes (such as `%i` or `%h` for @@ -525,8 +596,7 @@ Avoids having to specify the value for each enumeration member:: The :meth:`__new__` method, if defined, is used during creation of the Enum members; it is then replaced by Enum's :meth:`__new__` which is used after - class creation for lookup of existing members. Due to the way Enums are - supposed to behave, there is no way to customize Enum's :meth:`__new__`. + class creation for lookup of existing members. OrderedEnum @@ -644,7 +714,7 @@ allow one to do things with an :class:`Enum` class that fail on a typical class, such as `list(Color)` or `some_var in Color`. :class:`EnumMeta` is responsible for ensuring that various other methods on the final :class:`Enum` class are correct (such as :meth:`__new__`, :meth:`__getnewargs__`, -:meth:`__str__` and :meth:`__repr__`) +:meth:`__str__` and :meth:`__repr__`). Enum Members (aka instances) @@ -682,7 +752,11 @@ but not of the class:: >>> dir(Planet.EARTH) ['__class__', '__doc__', '__module__', 'name', 'surface_gravity', 'value'] -A :meth:`__new__` method will only be used for the creation of the -:class:`Enum` members -- after that it is replaced. This means if you wish to -change how :class:`Enum` members are looked up you either have to write a -helper function or a :func:`classmethod`. +The :meth:`__new__` method will only be used for the creation of the +:class:`Enum` members -- after that it is replaced. Any custom :meth:`__new__` +method must create the object and set the :attr:`_value_` attribute +appropriately. + +If you wish to change how :class:`Enum` members are looked up you should either +write a helper function or a :func:`classmethod` for the :class:`Enum` +subclass. diff --git a/Doc/library/errno.rst b/Doc/library/errno.rst index d2163b62582c..22a5cbc4507e 100644 --- a/Doc/library/errno.rst +++ b/Doc/library/errno.rst @@ -41,7 +41,10 @@ defined by the module. The specific list of defined symbols is available as .. data:: EINTR - Interrupted system call + Interrupted system call. + + .. seealso:: + This error is mapped to the exception :exc:`InterruptedError`. .. data:: EIO diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index 704abbbf2b82..e9e68b97900d 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -28,13 +28,14 @@ handler or to report an error condition "just like" the situation in which the interpreter raises the same exception; but beware that there is nothing to prevent user code from raising an inappropriate error. -The built-in exception classes can be sub-classed to define new exceptions; -programmers are encouraged to at least derive new exceptions from the -:exc:`Exception` class and not :exc:`BaseException`. More information on -defining exceptions is available in the Python Tutorial under +The built-in exception classes can be subclassed to define new exceptions; +programmers are encouraged to derive new exceptions from the :exc:`Exception` +class or one of its subclasses, and not from :exc:`BaseException`. More +information on defining exceptions is available in the Python Tutorial under :ref:`tut-userexceptions`. -When raising (or re-raising) an exception in an :keyword:`except` clause +When raising (or re-raising) an exception in an :keyword:`except` or +:keyword:`finally` clause :attr:`__context__` is automatically set to the last exception caught; if the new exception is not handled the traceback that is eventually displayed will include the originating exception(s) and the final exception. @@ -82,7 +83,7 @@ The following exceptions are used mostly as base classes for other exceptions. .. attribute:: args The tuple of arguments given to the exception constructor. Some built-in - exceptions (like :exc:`IOError`) expect a certain number of arguments and + exceptions (like :exc:`OSError`) expect a certain number of arguments and assign a special meaning to the elements of this tuple, while others are usually called only with a single string giving an error message. @@ -161,7 +162,8 @@ The following exceptions are the exceptions that are usually raised. .. exception:: GeneratorExit - Raise when a :term:`generator`\'s :meth:`close` method is called. It + Raised when a :term:`generator` or :term:`coroutine` is closed; + see :meth:`generator.close` and :meth:`coroutine.close`. It directly inherits from :exc:`BaseException` instead of :exc:`Exception` since it is technically not an error. @@ -253,6 +255,11 @@ The following exceptions are the exceptions that are usually raised. For exceptions that involve a file system path (such as :func:`open` or :func:`os.unlink`), the exception instance will contain an additional attribute, :attr:`filename`, which is the file name passed to the function. + For functions that involve two file system paths (such as + :func:`os.rename`), the exception instance will contain a second + :attr:`filename2` attribute corresponding to the second file name passed + to the function. + .. versionchanged:: 3.3 :exc:`EnvironmentError`, :exc:`IOError`, :exc:`WindowsError`, @@ -260,19 +267,29 @@ The following exceptions are the exceptions that are usually raised. :exc:`mmap.error` have been merged into :exc:`OSError`. .. versionchanged:: 3.4 - The :attr:`filename` attribute is now the original file name passed to the function, instead of the name encoded to or decoded from the - filesystem encoding. + filesystem encoding. Also, the :attr:`filename2` attribute was added. .. exception:: OverflowError Raised when the result of an arithmetic operation is too large to be represented. This cannot occur for integers (which would rather raise - :exc:`MemoryError` than give up). Because of the lack of standardization of - floating point exception handling in C, most floating point operations also - aren't checked. + :exc:`MemoryError` than give up). However, for historical reasons, + OverflowError is sometimes raised for integers that are outside a required + range. Because of the lack of standardization of floating point exception + handling in C, most floating point operations are not checked. + + +.. exception:: RecursionError + + This exception is derived from :exc:`RuntimeError`. It is raised when the + interpreter detects that the maximum recursion depth (see + :func:`sys.getrecursionlimit`) is exceeded. + + .. versionadded:: 3.5 + Previously, a plain :exc:`RuntimeError` was raised. .. exception:: ReferenceError @@ -300,14 +317,30 @@ The following exceptions are the exceptions that are usually raised. given as an argument when constructing the exception, and defaults to :const:`None`. - When a generator function returns, a new :exc:`StopIteration` instance is + When a :term:`generator` or :term:`coroutine` function + returns, a new :exc:`StopIteration` instance is raised, and the value returned by the function is used as the :attr:`value` parameter to the constructor of the exception. + If a generator function defined in the presence of a ``from __future__ + import generator_stop`` directive raises :exc:`StopIteration`, it will be + converted into a :exc:`RuntimeError` (retaining the :exc:`StopIteration` + as the new exception's cause). + .. versionchanged:: 3.3 Added ``value`` attribute and the ability for generator functions to use it to return a value. + .. versionchanged:: 3.5 + Introduced the RuntimeError transformation. + +.. exception:: StopAsyncIteration + + Must be raised by :meth:`__anext__` method of an + :term:`asynchronous iterator` object to stop the iteration. + + .. versionadded:: 3.5 + .. exception:: SyntaxError Raised when the parser encounters a syntax error. This may occur in an @@ -347,18 +380,17 @@ The following exceptions are the exceptions that are usually raised. .. exception:: SystemExit - This exception is raised by the :func:`sys.exit` function. When it is not - handled, the Python interpreter exits; no stack traceback is printed. If the - associated value is an integer, it specifies the system exit status (passed - to C's :c:func:`exit` function); if it is ``None``, the exit status is zero; - if it has another type (such as a string), the object's value is printed and + This exception is raised by the :func:`sys.exit` function. It inherits from + :exc:`BaseException` instead of :exc:`Exception` so that it is not accidentally + caught by code that catches :exc:`Exception`. This allows the exception to + properly propagate up and cause the interpreter to exit. When it is not + handled, the Python interpreter exits; no stack traceback is printed. The + constructor accepts the same optional argument passed to :func:`sys.exit`. + If the value is an integer, it specifies the system exit status (passed to + C's :c:func:`exit` function); if it is ``None``, the exit status is zero; if + it has another type (such as a string), the object's value is printed and the exit status is one. - Instances have an attribute :attr:`!code` which is set to the proposed exit - status or error message (defaulting to ``None``). Also, this exception derives - directly from :exc:`BaseException` and not :exc:`Exception`, since it is not - technically an error. - A call to :func:`sys.exit` is translated into an exception so that clean-up handlers (:keyword:`finally` clauses of :keyword:`try` statements) can be executed, and so that a debugger can execute a script without running the risk @@ -366,9 +398,10 @@ The following exceptions are the exceptions that are usually raised. absolutely positively necessary to exit immediately (for example, in the child process after a call to :func:`os.fork`). - The exception inherits from :exc:`BaseException` instead of :exc:`Exception` so - that it is not accidentally caught by code that catches :exc:`Exception`. This - allows the exception to properly propagate up and cause the interpreter to exit. + .. attribute:: code + + The exit status or error message that is passed to the constructor. + (Defaults to ``None``.) .. exception:: TypeError @@ -453,10 +486,6 @@ starting from Python 3.3, they are aliases of :exc:`OSError`. .. exception:: IOError -.. exception:: VMSError - - Only available on VMS. - .. exception:: WindowsError Only available on Windows. @@ -534,7 +563,12 @@ depending on the system error code. .. exception:: InterruptedError Raised when a system call is interrupted by an incoming signal. - Corresponds to :c:data:`errno` ``EINTR``. + Corresponds to :c:data:`errno` :py:data:`~errno.EINTR`. + + .. versionchanged:: 3.5 + Python now retries system calls when a syscall is interrupted by a + signal, except if the signal handler raises an exception (see :pep:`475` + for the rationale), instead of raising :exc:`InterruptedError`. .. exception:: IsADirectoryError @@ -601,7 +635,7 @@ module for more information. .. exception:: SyntaxWarning - Base class for warnings about dubious syntax + Base class for warnings about dubious syntax. .. exception:: RuntimeWarning diff --git a/Doc/library/faulthandler.rst b/Doc/library/faulthandler.rst index 61bc503d8f36..3a5badd0ffa3 100644 --- a/Doc/library/faulthandler.rst +++ b/Doc/library/faulthandler.rst @@ -4,12 +4,14 @@ .. module:: faulthandler :synopsis: Dump the Python traceback. +.. versionadded:: 3.3 + This module contains functions to dump Python tracebacks explicitly, on a fault, after a timeout, or on a user signal. Call :func:`faulthandler.enable` to install fault handlers for the :const:`SIGSEGV`, :const:`SIGFPE`, :const:`SIGABRT`, :const:`SIGBUS`, and :const:`SIGILL` signals. You can also enable them at startup by setting the :envvar:`PYTHONFAULTHANDLER` environment -variable or by using :option:`-X` ``faulthandler`` command line option. +variable or by using the :option:`-X` ``faulthandler`` command line option. The fault handler is compatible with system fault handlers like Apport or the Windows fault handler. The module uses an alternative stack for signal handlers @@ -36,17 +38,18 @@ alternatively be passed to :func:`faulthandler.enable`. The module is implemented in C, so tracebacks can be dumped on a crash or when Python is deadlocked. -.. versionadded:: 3.3 - -Dump the traceback ------------------- +Dumping the traceback +--------------------- .. function:: dump_traceback(file=sys.stderr, all_threads=True) Dump the tracebacks of all threads into *file*. If *all_threads* is ``False``, dump only the current thread. + .. versionchanged:: 3.5 + Added support for passing file descriptor to this function. + Fault handler state ------------------- @@ -59,6 +62,12 @@ Fault handler state produce tracebacks for every running thread. Otherwise, dump only the current thread. + The *file* must be kept open until the fault handler is disabled: see + :ref:`issue with file descriptors <faulthandler-fd>`. + + .. versionchanged:: 3.5 + Added support for passing file descriptor to this function. + .. function:: disable() Disable the fault handler: uninstall the signal handlers installed by @@ -69,8 +78,8 @@ Fault handler state Check if the fault handler is enabled. -Dump the tracebacks after a timeout ------------------------------------ +Dumping the tracebacks after a timeout +-------------------------------------- .. function:: dump_traceback_later(timeout, repeat=False, file=sys.stderr, exit=False) @@ -82,16 +91,23 @@ Dump the tracebacks after a timeout call replaces previous parameters and resets the timeout. The timer has a sub-second resolution. + The *file* must be kept open until the traceback is dumped or + :func:`cancel_dump_traceback_later` is called: see :ref:`issue with file + descriptors <faulthandler-fd>`. + This function is implemented using a watchdog thread and therefore is not available if Python is compiled with threads disabled. + .. versionchanged:: 3.5 + Added support for passing file descriptor to this function. + .. function:: cancel_dump_traceback_later() Cancel the last call to :func:`dump_traceback_later`. -Dump the traceback on a user signal ------------------------------------ +Dumping the traceback on a user signal +-------------------------------------- .. function:: register(signum, file=sys.stderr, all_threads=True, chain=False) @@ -99,8 +115,14 @@ Dump the traceback on a user signal the traceback of all threads, or of the current thread if *all_threads* is ``False``, into *file*. Call the previous handler if chain is ``True``. + The *file* must be kept open until the signal is unregistered by + :func:`unregister`: see :ref:`issue with file descriptors <faulthandler-fd>`. + Not available on Windows. + .. versionchanged:: 3.5 + Added support for passing file descriptor to this function. + .. function:: unregister(signum) Unregister a user signal: uninstall the handler of the *signum* signal @@ -110,8 +132,10 @@ Dump the traceback on a user signal Not available on Windows. -File descriptor issue ---------------------- +.. _faulthandler-fd: + +Issue with file descriptors +--------------------------- :func:`enable`, :func:`dump_traceback_later` and :func:`register` keep the file descriptor of their *file* argument. If the file is closed and its file @@ -123,9 +147,15 @@ these functions again each time that the file is replaced. Example ------- -Example of a segmentation fault on Linux: :: +.. highlight:: sh + +Example of a segmentation fault on Linux with and without enabling the fault +handler:: + + $ python3 -c "import ctypes; ctypes.string_at(0)" + Segmentation fault - $ python -q -X faulthandler + $ python3 -q -X faulthandler >>> import ctypes >>> ctypes.string_at(0) Fatal Python error: Segmentation fault diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst index 8e932fb95401..432140f279b1 100644 --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -28,41 +28,41 @@ descriptor. The module defines the following functions: -.. function:: fcntl(fd, op[, arg]) +.. function:: fcntl(fd, cmd, arg=0) - Perform the operation *op* on file descriptor *fd* (file objects providing + Perform the operation *cmd* on file descriptor *fd* (file objects providing a :meth:`~io.IOBase.fileno` method are accepted as well). The values used - for *op* are operating system dependent, and are available as constants + for *cmd* are operating system dependent, and are available as constants in the :mod:`fcntl` module, using the same names as used in the relevant C - header files. The argument *arg* is optional, and defaults to the integer - value ``0``. When present, it can either be an integer value, or a string. - With the argument missing or an integer value, the return value of this function - is the integer return value of the C :c:func:`fcntl` call. When the argument is - a string it represents a binary structure, e.g. created by :func:`struct.pack`. - The binary data is copied to a buffer whose address is passed to the C - :c:func:`fcntl` call. The return value after a successful call is the contents - of the buffer, converted to a string object. The length of the returned string - will be the same as the length of the *arg* argument. This is limited to 1024 - bytes. If the information returned in the buffer by the operating system is - larger than 1024 bytes, this is most likely to result in a segmentation - violation or a more subtle data corruption. + header files. The argument *arg* can either be an integer value, or a + :class:`bytes` object. With an integer value, the return value of this + function is the integer return value of the C :c:func:`fcntl` call. When + the argument is bytes it represents a binary structure, e.g. created by + :func:`struct.pack`. The binary data is copied to a buffer whose address is + passed to the C :c:func:`fcntl` call. The return value after a successful + call is the contents of the buffer, converted to a :class:`bytes` object. + The length of the returned object will be the same as the length of the + *arg* argument. This is limited to 1024 bytes. If the information returned + in the buffer by the operating system is larger than 1024 bytes, this is + most likely to result in a segmentation violation or a more subtle data + corruption. If the :c:func:`fcntl` fails, an :exc:`OSError` is raised. -.. function:: ioctl(fd, op[, arg[, mutate_flag]]) +.. function:: ioctl(fd, request, arg=0, mutate_flag=True) This function is identical to the :func:`~fcntl.fcntl` function, except that the argument handling is even more complicated. - The op parameter is limited to values that can fit in 32-bits. - Additional constants of interest for use as the *op* argument can be + The *request* parameter is limited to values that can fit in 32-bits. + Additional constants of interest for use as the *request* argument can be found in the :mod:`termios` module, under the same names as used in the relevant C header files. - The parameter *arg* can be one of an integer, absent (treated identically to the - integer ``0``), an object supporting the read-only buffer interface (most likely - a plain Python string) or an object supporting the read-write buffer interface. + The parameter *arg* can be one of an integer, an object supporting the + read-only buffer interface (like :class:`bytes`) or an object supporting + the read-write buffer interface (like :class:`bytearray`). In all but the last case, behaviour is as for the :func:`~fcntl.fcntl` function. @@ -72,7 +72,7 @@ The module defines the following functions: If it is false, the buffer's mutability is ignored and behaviour is as for a read-only buffer, except that the 1024 byte limit mentioned above is avoided -- - so long as the buffer you pass is as least as long as what the operating system + so long as the buffer you pass is at least as long as what the operating system wants to put there, things should work. If *mutate_flag* is true (the default), then the buffer is (in effect) passed @@ -97,25 +97,25 @@ The module defines the following functions: array('h', [13341]) -.. function:: flock(fd, op) +.. function:: flock(fd, operation) - Perform the lock operation *op* on file descriptor *fd* (file objects providing + Perform the lock operation *operation* on file descriptor *fd* (file objects providing a :meth:`~io.IOBase.fileno` method are accepted as well). See the Unix manual :manpage:`flock(2)` for details. (On some systems, this function is emulated using :c:func:`fcntl`.) -.. function:: lockf(fd, operation, [length, [start, [whence]]]) +.. function:: lockf(fd, cmd, len=0, start=0, whence=0) This is essentially a wrapper around the :func:`~fcntl.fcntl` locking calls. - *fd* is the file descriptor of the file to lock or unlock, and *operation* + *fd* is the file descriptor of the file to lock or unlock, and *cmd* is one of the following values: * :const:`LOCK_UN` -- unlock * :const:`LOCK_SH` -- acquire a shared lock * :const:`LOCK_EX` -- acquire an exclusive lock - When *operation* is :const:`LOCK_SH` or :const:`LOCK_EX`, it can also be + When *cmd* is :const:`LOCK_SH` or :const:`LOCK_EX`, it can also be bitwise ORed with :const:`LOCK_NB` to avoid blocking on lock acquisition. If :const:`LOCK_NB` is used and the lock cannot be acquired, an :exc:`OSError` will be raised and the exception will have an *errno* @@ -124,7 +124,7 @@ The module defines the following functions: systems, :const:`LOCK_EX` can only be used if the file descriptor refers to a file opened for writing. - *length* is the number of bytes to lock, *start* is the byte offset at + *len* is the number of bytes to lock, *start* is the byte offset at which the lock starts, relative to *whence*, and *whence* is as with :func:`io.IOBase.seek`, specifically: @@ -133,7 +133,7 @@ The module defines the following functions: * :const:`2` -- relative to the end of the file (:data:`os.SEEK_END`) The default for *start* is 0, which means to start at the beginning of the file. - The default for *length* is 0 which means to lock to the end of the file. The + The default for *len* is 0 which means to lock to the end of the file. The default for *whence* is also 0. Examples (all on a SVR4 compliant system):: @@ -147,9 +147,9 @@ Examples (all on a SVR4 compliant system):: rv = fcntl.fcntl(f, fcntl.F_SETLKW, lockdata) Note that in the first example the return value variable *rv* will hold an -integer value; in the second example it will hold a string value. The structure -lay-out for the *lockdata* variable is system dependent --- therefore using the -:func:`flock` call may be better. +integer value; in the second example it will hold a :class:`bytes` object. The +structure lay-out for the *lockdata* variable is system dependent --- therefore +using the :func:`flock` call may be better. .. seealso:: diff --git a/Doc/library/filecmp.rst b/Doc/library/filecmp.rst index 8471a7263078..06d3f21300a7 100644 --- a/Doc/library/filecmp.rst +++ b/Doc/library/filecmp.rst @@ -28,8 +28,8 @@ The :mod:`filecmp` module defines the following functions: portability and efficiency. This function uses a cache for past comparisons and the results, - with a cache invalidation mechanism relying on stale signatures - or by explicitly calling :func:`clear_cache`. + with cache entries invalidated if the :func:`os.stat` information for the + file changes. The entire cache may be cleared using :func:`clear_cache`. .. function:: cmpfiles(dir1, dir2, common, shallow=True) @@ -54,12 +54,12 @@ The :mod:`filecmp` module defines the following functions: .. function:: clear_cache() - .. versionadded:: 3.4 - Clear the filecmp cache. This may be useful if a file is compared so quickly after it is modified that it is within the mtime resolution of the underlying filesystem. + .. versionadded:: 3.4 + .. _dircmp-objects: diff --git a/Doc/library/fnmatch.rst b/Doc/library/fnmatch.rst index ef93f05a7a5c..68b437f2c041 100644 --- a/Doc/library/fnmatch.rst +++ b/Doc/library/fnmatch.rst @@ -83,7 +83,7 @@ patterns. >>> >>> regex = fnmatch.translate('*.txt') >>> regex - '.*\\.txt$' + '.*\\.txt\\Z(?ms)' >>> reobj = re.compile(regex) >>> reobj.match('foobar.txt') <_sre.SRE_Match object; span=(0, 10), match='foobar.txt'> diff --git a/Doc/library/formatter.rst b/Doc/library/formatter.rst index bdc9e7b0e040..8e8e201ae1e7 100644 --- a/Doc/library/formatter.rst +++ b/Doc/library/formatter.rst @@ -3,10 +3,10 @@ .. module:: formatter :synopsis: Generic output formatter and device interface. + :deprecated: .. deprecated:: 3.4 - Due to lack of usage, the formatter module has been deprecated and is slated - for removal in Python 3.6. + Due to lack of usage, the formatter module has been deprecated. This module supports two interface definitions, each with multiple diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst index fba199bf7877..d24f80ac4bdc 100644 --- a/Doc/library/fractions.rst +++ b/Doc/library/fractions.rst @@ -97,9 +97,11 @@ another rational number, or from a string. This class method constructs a :class:`Fraction` representing the exact value of *flt*, which must be a :class:`float`. Beware that - ``Fraction.from_float(0.3)`` is not the same value as ``Fraction(3, 10)`` + ``Fraction.from_float(0.3)`` is not the same value as ``Fraction(3, 10)``. - .. note:: From Python 3.2 onwards, you can also construct a + .. note:: + + From Python 3.2 onwards, you can also construct a :class:`Fraction` instance directly from a :class:`float`. @@ -108,7 +110,9 @@ another rational number, or from a string. This class method constructs a :class:`Fraction` representing the exact value of *dec*, which must be a :class:`decimal.Decimal` instance. - .. note:: From Python 3.2 onwards, you can also construct a + .. note:: + + From Python 3.2 onwards, you can also construct a :class:`Fraction` instance directly from a :class:`decimal.Decimal` instance. @@ -168,6 +172,9 @@ another rational number, or from a string. sign as *b* if *b* is nonzero; otherwise it takes the sign of *a*. ``gcd(0, 0)`` returns ``0``. + .. deprecated:: 3.5 + Use :func:`math.gcd` instead. + .. seealso:: diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst index 7f98d0bd81b0..3b9f50ca49ef 100644 --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -80,14 +80,14 @@ The module defines the following items: :rfc:`4217`. Connect as usual to port 21 implicitly securing the FTP control connection before authenticating. Securing the data connection requires the user to - explicitly ask for it by calling the :meth:`prot_p` method. - *keyfile* and *certfile* are optional -- they can contain a PEM formatted - private key and certificate chain file name for the SSL connection. - *context* parameter is a :class:`ssl.SSLContext` object which allows - bundling SSL configuration options, certificates and private keys into a - single (potentially long-lived) structure. *source_address* is a 2-tuple - ``(host, port)`` for the socket to bind to as its source address before - connecting. + explicitly ask for it by calling the :meth:`prot_p` method. *context* + is a :class:`ssl.SSLContext` object which allows bundling SSL configuration + options, certificates and private keys into a single (potentially + long-lived) structure. Please read :ref:`ssl-security` for best practices. + + *keyfile* and *certfile* are a legacy alternative to *context* -- they + can point to PEM-formatted private key and certificate chain files + (respectively) for the SSL connection. .. versionadded:: 3.2 @@ -96,29 +96,18 @@ The module defines the following items: .. versionchanged:: 3.4 The class now supports hostname check with - :attr:`SSLContext.check_hostname` and *Server Name Indicator* (see - :data:`~ssl.HAS_SNI`). - - Here's a sample session using the :class:`FTP_TLS` class: - - >>> from ftplib import FTP_TLS - >>> ftps = FTP_TLS('ftp.python.org') - >>> ftps.login() # login anonymously before securing control channel - >>> ftps.prot_p() # switch to secure data connection - >>> ftps.retrlines('LIST') # list directory content securely - total 9 - drwxr-xr-x 8 root wheel 1024 Jan 3 1994 . - drwxr-xr-x 8 root wheel 1024 Jan 3 1994 .. - drwxr-xr-x 2 root wheel 1024 Jan 3 1994 bin - drwxr-xr-x 2 root wheel 1024 Jan 3 1994 etc - d-wxrwxr-x 2 ftp wheel 1024 Sep 5 13:43 incoming - drwxr-xr-x 2 root wheel 1024 Nov 17 1993 lib - drwxr-xr-x 6 1094 wheel 1024 Sep 13 19:07 pub - drwxr-xr-x 3 root wheel 1024 Jan 3 1994 usr - -rw-r--r-- 1 root root 312 Aug 1 1994 welcome.msg - '226 Transfer complete.' - >>> ftps.quit() - >>> + :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see + :data:`ssl.HAS_SNI`). + + Here's a sample session using the :class:`FTP_TLS` class:: + + >>> ftps = FTP_TLS('ftp.pureftpd.org') + >>> ftps.login() + '230 Anonymous user logged in' + >>> ftps.prot_p() + '200 Data protection level set to "private"' + >>> ftps.nlst() + ['6jack', 'OpenBSD', 'antilink', 'blogbench', 'bsdcam', 'clockspeed', 'djbdns-jedi', 'docs', 'eaccelerator-jedi', 'favicon.ico', 'francotone', 'fugu', 'ignore', 'libpuzzle', 'metalog', 'minidentd', 'misc', 'mysql-udf-global-user-variables', 'php-jenkins-hash', 'php-skein-hash', 'php-webdav', 'phpaudit', 'phpbench', 'pincaster', 'ping', 'posto', 'pub', 'public', 'public_keys', 'pure-ftpd', 'qscan', 'qtc', 'sharedance', 'skycache', 'sound', 'tmp', 'ucarp'] .. exception:: error_reply @@ -273,10 +262,10 @@ followed by ``lines`` for the text version or ``binary`` for the binary version. Passive mode is on by default. -.. method:: FTP.storbinary(cmd, file, blocksize=8192, callback=None, rest=None) +.. method:: FTP.storbinary(cmd, fp, blocksize=8192, callback=None, rest=None) Store a file in binary transfer mode. *cmd* should be an appropriate - ``STOR`` command: ``"STOR filename"``. *file* is a :term:`file object` + ``STOR`` command: ``"STOR filename"``. *fp* is a :term:`file object` (opened in binary mode) which is read until EOF using its :meth:`~io.IOBase.read` method in blocks of size *blocksize* to provide the data to be stored. The *blocksize* argument defaults to 8192. *callback* is an optional single @@ -287,11 +276,11 @@ followed by ``lines`` for the text version or ``binary`` for the binary version. *rest* parameter added. -.. method:: FTP.storlines(cmd, file, callback=None) +.. method:: FTP.storlines(cmd, fp, callback=None) Store a file in ASCII transfer mode. *cmd* should be an appropriate ``STOR`` command (see :meth:`storbinary`). Lines are read until EOF from the - :term:`file object` *file* (opened in binary mode) using its :meth:`~io.IOBase.readline` + :term:`file object` *fp* (opened in binary mode) using its :meth:`~io.IOBase.readline` method to provide the data to be stored. *callback* is an optional single parameter callable that is called on each line after it is sent. @@ -425,7 +414,7 @@ FTP_TLS Objects .. attribute:: FTP_TLS.ssl_version - The SSL version to use (defaults to *TLSv1*). + The SSL version to use (defaults to :attr:`ssl.PROTOCOL_SSLv23`). .. method:: FTP_TLS.auth() @@ -434,8 +423,8 @@ FTP_TLS Objects .. versionchanged:: 3.4 The method now supports hostname check with - :attr:`SSLContext.check_hostname` and *Server Name Indicator* (see - :data:`~ssl.HAS_SNI`). + :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see + :data:`ssl.HAS_SNI`). .. method:: FTP_TLS.ccc() diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index fb4fc7f350be..409f6c4fe117 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -85,22 +85,22 @@ are always available. They are listed here in alphabetical order. :meth:`__index__` method that returns an integer. -.. function:: bool([x]) +.. class:: bool([x]) - Convert a value to a Boolean, using the standard :ref:`truth testing - procedure <truth>`. If *x* is false or omitted, this returns ``False``; - otherwise it returns ``True``. :class:`bool` is also a class, which is a - subclass of :class:`int` (see :ref:`typesnumeric`). Class :class:`bool` - cannot be subclassed further. Its only instances are ``False`` and + Return a Boolean value, i.e. one of ``True`` or ``False``. *x* is converted + using the standard :ref:`truth testing procedure <truth>`. If *x* is false + or omitted, this returns ``False``; otherwise it returns ``True``. The + :class:`bool` class is a subclass of :class:`int` (see :ref:`typesnumeric`). + It cannot be subclassed further. Its only instances are ``False`` and ``True`` (see :ref:`bltin-boolean-values`). .. index:: pair: Boolean; type .. _func-bytearray: -.. function:: bytearray([source[, encoding[, errors]]]) +.. class:: bytearray([source[, encoding[, errors]]]) - Return a new array of bytes. The :class:`bytearray` type is a mutable + Return a new array of bytes. The :class:`bytearray` class is a mutable sequence of integers in the range 0 <= x < 256. It has most of the usual methods of mutable sequences, described in :ref:`typesseq-mutable`, as well as most methods that the :class:`bytes` type has, see :ref:`bytes-methods`. @@ -127,7 +127,7 @@ are always available. They are listed here in alphabetical order. .. _func-bytes: -.. function:: bytes([source[, encoding[, errors]]]) +.. class:: bytes([source[, encoding[, errors]]]) Return a new "bytes" object, which is an immutable sequence of integers in the range ``0 <= x < 256``. :class:`bytes` is an immutable version of @@ -156,11 +156,12 @@ are always available. They are listed here in alphabetical order. .. function:: chr(i) - Return the string representing a character whose Unicode codepoint is the integer - *i*. For example, ``chr(97)`` returns the string ``'a'``. This is the - inverse of :func:`ord`. The valid range for the argument is from 0 through - 1,114,111 (0x10FFFF in base 16). :exc:`ValueError` will be raised if *i* is - outside that range. + Return the string representing a character whose Unicode code point is the + integer *i*. For example, ``chr(97)`` returns the string ``'a'``, while + ``chr(957)`` returns the string ``'ν'``. This is the inverse of :func:`ord`. + + The valid range for the argument is from 0 through 1,114,111 (0x10FFFF in + base 16). :exc:`ValueError` will be raised if *i* is outside that range. .. function:: classmethod(function) @@ -193,9 +194,9 @@ are always available. They are listed here in alphabetical order. .. function:: compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1) Compile the *source* into a code or AST object. Code objects can be executed - by :func:`exec` or :func:`eval`. *source* can either be a string or an AST - object. Refer to the :mod:`ast` module documentation for information on how - to work with AST objects. + by :func:`exec` or :func:`eval`. *source* can either be a normal string, a + byte string, or an AST object. Refer to the :mod:`ast` module documentation + for information on how to work with AST objects. The *filename* argument should give the file from which the code was read; pass some recognizable value if it wasn't read from a file (``'<string>'`` is @@ -210,7 +211,7 @@ are always available. They are listed here in alphabetical order. The optional arguments *flags* and *dont_inherit* control which future statements (see :pep:`236`) affect the compilation of *source*. If neither is present (or both are zero) the code is compiled with those future - statements that are in effect in the code that is calling compile. If the + statements that are in effect in the code that is calling :func:`compile`. If the *flags* argument is given and *dont_inherit* is not (or is zero) then the future statements specified by the *flags* argument are used in addition to those that would be used anyway. If *dont_inherit* is a non-zero integer then @@ -231,6 +232,9 @@ are always available. They are listed here in alphabetical order. This function raises :exc:`SyntaxError` if the compiled source is invalid, and :exc:`TypeError` if the source contains null bytes. + If you want to parse Python code into its AST representation, see + :func:`ast.parse`. + .. note:: When compiling a string with multi-line code in ``'single'`` or @@ -243,15 +247,16 @@ are always available. They are listed here in alphabetical order. does not have to end in a newline anymore. Added the *optimize* parameter. -.. function:: complex([real[, imag]]) +.. class:: complex([real[, imag]]) - Create a complex number with the value *real* + *imag*\*j or convert a string or - number to a complex number. If the first parameter is a string, it will be - interpreted as a complex number and the function must be called without a second - parameter. The second parameter can never be a string. Each argument may be any - numeric type (including complex). If *imag* is omitted, it defaults to zero and - the function serves as a numeric conversion function like :func:`int` - and :func:`float`. If both arguments are omitted, returns ``0j``. + Return a complex number with the value *real* + *imag*\*1j or convert a string + or number to a complex number. If the first parameter is a string, it will + be interpreted as a complex number and the function must be called without a + second parameter. The second parameter can never be a string. Each argument + may be any numeric type (including complex). If *imag* is omitted, it + defaults to zero and the constructor serves as a numeric conversion like + :class:`int` and :class:`float`. If both arguments are omitted, returns + ``0j``. .. note:: @@ -272,14 +277,13 @@ are always available. They are listed here in alphabetical order. .. _func-dict: -.. function:: dict(**kwarg) - dict(mapping, **kwarg) - dict(iterable, **kwarg) +.. class:: dict(**kwarg) + dict(mapping, **kwarg) + dict(iterable, **kwarg) :noindex: Create a new dictionary. The :class:`dict` object is the dictionary class. - See :class:`dict` and :ref:`typesmapping` for documentation about this - class. + See :class:`dict` and :ref:`typesmapping` for documentation about this class. For other containers see the built-in :class:`list`, :class:`set`, and :class:`tuple` classes, as well as the :mod:`collections` module. @@ -410,6 +414,7 @@ are always available. They are listed here in alphabetical order. See :func:`ast.literal_eval` for a function that can safely evaluate strings with expressions containing only literals. +.. index:: builtin: exec .. function:: exec(object[, globals[, locals]]) @@ -469,13 +474,13 @@ are always available. They are listed here in alphabetical order. elements of *iterable* for which *function* returns false. -.. function:: float([x]) +.. class:: float([x]) .. index:: single: NaN single: Infinity - Convert a string or a number to floating point. + Return a floating point number constructed from a number or string *x*. If the argument is a string, it should contain a decimal number, optionally preceded by a sign, and optionally embedded in whitespace. The optional @@ -538,18 +543,19 @@ are always available. They are listed here in alphabetical order. effect as calling :func:`str(value) <str>`. A call to ``format(value, format_spec)`` is translated to - ``type(value).__format__(format_spec)`` which bypasses the instance + ``type(value).__format__(value, format_spec)`` which bypasses the instance dictionary when searching for the value's :meth:`__format__` method. A - :exc:`TypeError` exception is raised if the method is not found or if either - the *format_spec* or the return value are not strings. + :exc:`TypeError` exception is raised if the method search reaches + :mod:`object` and the *format_spec* is non-empty, or if either the + *format_spec* or the return value are not strings. - .. versionadded:: 3.4 + .. versionchanged:: 3.4 ``object().__format__(format_spec)`` raises :exc:`TypeError` - if *format_spec* is not empty string. + if *format_spec* is not an empty string. .. _func-frozenset: -.. function:: frozenset([iterable]) +.. class:: frozenset([iterable]) :noindex: Return a new :class:`frozenset` object, optionally with elements taken from @@ -609,12 +615,26 @@ are always available. They are listed here in alphabetical order. This function is added to the built-in namespace by the :mod:`site` module. + .. versionchanged:: 3.4 + Changes to :mod:`pydoc` and :mod:`inspect` mean that the reported + signatures for callables are now more comprehensive and consistent. + .. function:: hex(x) - Convert an integer number to a hexadecimal string. The result is a valid Python - expression. If *x* is not a Python :class:`int` object, it has to define an - :meth:`__index__` method that returns an integer. + Convert an integer number to a lowercase hexadecimal string + prefixed with "0x", for example: + + >>> hex(255) + '0xff' + >>> hex(-42) + '-0x2a' + + If x is not a Python :class:`int` object, it has to define an __index__() + method that returns an integer. + + See also :func:`int` for converting a hexadecimal string to an + integer using a base of 16. .. note:: @@ -648,12 +668,13 @@ are always available. They are listed here in alphabetical order. to provide elaborate line editing and history features. -.. function:: int(x=0) - int(x, base=10) +.. class:: int(x=0) + int(x, base=10) - Convert a number or string *x* to an integer, or return ``0`` if no - arguments are given. If *x* is a number, return :meth:`x.__int__() - <object.__int__>`. For floating point numbers, this truncates towards zero. + Return an integer object constructed from a number or string *x*, or return + ``0`` if no arguments are given. If *x* is a number, return + :meth:`x.__int__() <object.__int__>`. For floating point numbers, this + truncates towards zero. If *x* is not a number or if *base* is given, then *x* must be a string, :class:`bytes`, or :class:`bytearray` instance representing an :ref:`integer @@ -727,11 +748,12 @@ are always available. They are listed here in alphabetical order. .. function:: len(s) Return the length (the number of items) of an object. The argument may be a - sequence (string, tuple or list) or a mapping (dictionary). + sequence (such as a string, bytes, tuple, list, or range) or a collection + (such as a dictionary, set, or frozen set). .. _func-list: -.. function:: list([iterable]) +.. class:: list([iterable]) :noindex: Rather than being a function, :class:`list` is actually a mutable @@ -758,7 +780,7 @@ are always available. They are listed here in alphabetical order. already arranged into argument tuples, see :func:`itertools.starmap`\. -.. function:: max(iterable, *[, default, key]) +.. function:: max(iterable, *[, key, default]) max(arg1, arg2, *args[, key]) Return the largest item in an iterable or the largest of two or more @@ -766,7 +788,7 @@ are always available. They are listed here in alphabetical order. If one positional argument is provided, it should be an :term:`iterable`. The largest item in the iterable is returned. If two or more positional - arguments are provided, the smallest of the positional arguments is + arguments are provided, the largest of the positional arguments is returned. There are two optional keyword-only arguments. The *key* argument specifies @@ -780,6 +802,9 @@ are always available. They are listed here in alphabetical order. such as ``sorted(iterable, key=keyfunc, reverse=True)[0]`` and ``heapq.nlargest(1, iterable, key=keyfunc)``. + .. versionadded:: 3.4 + The *default* keyword-only argument. + .. _func-memoryview: .. function:: memoryview(obj) @@ -789,7 +814,7 @@ are always available. They are listed here in alphabetical order. :ref:`typememoryview` for more information. -.. function:: min(iterable, *[, default, key]) +.. function:: min(iterable, *[, key, default]) min(arg1, arg2, *args[, key]) Return the smallest item in an iterable or the smallest of two or more @@ -811,6 +836,10 @@ are always available. They are listed here in alphabetical order. such as ``sorted(iterable, key=keyfunc)[0]`` and ``heapq.nsmallest(1, iterable, key=keyfunc)``. + .. versionadded:: 3.4 + The *default* keyword-only argument. + + .. function:: next(iterator[, default]) Retrieve the next item from the *iterator* by calling its @@ -818,7 +847,7 @@ are always available. They are listed here in alphabetical order. if the iterator is exhausted, otherwise :exc:`StopIteration` is raised. -.. function:: object() +.. class:: object() Return a new featureless object. :class:`object` is a base for all classes. It has the methods that are common to all instances of Python classes. This @@ -911,15 +940,17 @@ are always available. They are listed here in alphabetical order. *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 (whatever :func:`locale.getpreferredencoding` returns), but any - encoding supported by Python can be used. See the :mod:`codecs` module for + :term:`text encoding` supported by Python + can be used. See the :mod:`codecs` module for the list of supported encodings. *errors* is an optional string that specifies how encoding and decoding errors are to be handled--this cannot be used in binary mode. - A variety of standard error handlers are available, though any + A variety of standard error handlers are available + (listed under :ref:`error-handlers`), though any error handling name that has been registered with :func:`codecs.register_error` is also valid. The standard names - are: + include: * ``'strict'`` to raise a :exc:`ValueError` exception if there is an encoding error. The default value of ``None`` has the same @@ -942,9 +973,11 @@ are always available. They are listed here in alphabetical order. Characters not supported by the encoding are replaced with the appropriate XML character reference ``&#nnn;``. - * ``'backslashreplace'`` (also only supported when writing) - replaces unsupported characters with Python's backslashed escape - sequences. + * ``'backslashreplace'`` replaces malformed data by Python's backslashed + escape sequences. + + * ``'namereplace'`` (also only supported when writing) + replaces unsupported characters with ``\N{...}`` escape sequences. .. index:: single: universal newlines; open() built-in function @@ -969,8 +1002,8 @@ are always available. They are listed here in alphabetical order. If *closefd* is ``False`` and a file descriptor rather than a filename was given, the underlying file descriptor will be kept open when the file is - closed. If a filename is given *closefd* has no effect and must be ``True`` - (the default). + closed. If a filename is given *closefd* must be ``True`` (the default) + otherwise an error will be raised. 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 @@ -1029,16 +1062,21 @@ are always available. They are listed here in alphabetical order. The file is now non-inheritable. .. deprecated-removed:: 3.4 4.0 + The ``'U'`` mode. + .. versionchanged:: 3.5 + If the system call is interrupted and the signal handler does not raise an + exception, the function now retries the system call instead of raising an + :exc:`InterruptedError` exception (see :pep:`475` for the rationale). + -.. XXX works for bytes too, but should it? .. function:: ord(c) Given a string representing one Unicode character, return an integer - representing the Unicode code - point of that character. For example, ``ord('a')`` returns the integer ``97`` - and ``ord('\u2020')`` returns ``8224``. This is the inverse of :func:`chr`. + representing the Unicode code point of that character. For example, + ``ord('a')`` returns the integer ``97`` and ``ord('ν')`` returns ``957``. + This is the inverse of :func:`chr`. .. function:: pow(x, y[, z]) @@ -1059,8 +1097,8 @@ are always available. They are listed here in alphabetical order. .. function:: print(*objects, sep=' ', end='\\n', file=sys.stdout, flush=False) - Print *objects* to the stream *file*, separated by *sep* and followed by - *end*. *sep*, *end* and *file*, if present, must be given as keyword + Print *objects* to the text stream *file*, separated by *sep* and followed + by *end*. *sep*, *end* and *file*, if present, must be given as keyword arguments. All non-keyword arguments are converted to strings like :func:`str` does and @@ -1070,21 +1108,26 @@ are always available. They are listed here in alphabetical order. *end*. The *file* argument must be an object with a ``write(string)`` method; if it - is not present or ``None``, :data:`sys.stdout` will be used. Whether output - is buffered is usually determined by *file*, but if the *flush* keyword - argument is true, the stream is forcibly flushed. + is not present or ``None``, :data:`sys.stdout` will be used. Since printed + arguments are converted to text strings, :func:`print` cannot be used with + binary mode file objects. For these, use ``file.write(...)`` instead. + + Whether output is buffered is usually determined by *file*, but if the + *flush* keyword argument is true, the stream is forcibly flushed. .. versionchanged:: 3.3 Added the *flush* keyword argument. -.. function:: property(fget=None, fset=None, fdel=None, doc=None) +.. class:: property(fget=None, fset=None, fdel=None, doc=None) Return a property attribute. - *fget* is a function for getting an attribute value, likewise *fset* is a - function for setting, and *fdel* a function for del'ing, an attribute. Typical - use is to define a managed attribute ``x``:: + *fget* is a function for getting an attribute value. *fset* is a function + for setting an attribute value. *fdel* is a function for deleting an attribute + value. And *doc* creates a docstring for the attribute. + + A typical use is to define a managed attribute ``x``:: class C: def __init__(self): @@ -1092,13 +1135,16 @@ are always available. They are listed here in alphabetical order. 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.") - If then *c* is an instance of *C*, ``c.x`` will invoke the getter, + If *c* is an instance of *C*, ``c.x`` will invoke the getter, ``c.x = value`` will invoke the setter and ``del c.x`` the deleter. If given, *doc* will be the docstring of the property attribute. Otherwise, the @@ -1114,8 +1160,9 @@ are always available. They are listed here in alphabetical order. """Get the current voltage.""" return self._voltage - turns the :meth:`voltage` method into a "getter" for a read-only attribute - with the same name. + The ``@property`` decorator turns the :meth:`voltage` method into a "getter" + for a read-only attribute with the same name, and it sets the docstring for + *voltage* to "Get the current voltage." A property object has :attr:`~property.getter`, :attr:`~property.setter`, and :attr:`~property.deleter` methods usable as decorators that create a @@ -1143,9 +1190,12 @@ are always available. They are listed here in alphabetical order. additional functions the same name as the original property (``x`` in this case.) - The returned property also has the attributes ``fget``, ``fset``, and + The returned property object also has the attributes ``fget``, ``fset``, and ``fdel`` corresponding to the constructor arguments. + .. versionchanged:: 3.5 + The docstrings of property objects are now writeable. + .. _func-range: .. function:: range(stop) @@ -1178,8 +1228,8 @@ are always available. They are listed here in alphabetical order. .. function:: round(number[, ndigits]) Return the floating point value *number* rounded to *ndigits* digits after - the decimal point. If *ndigits* is omitted, it defaults to zero. Delegates - to ``number.__round__(ndigits)``. + the decimal point. If *ndigits* is omitted, it returns the nearest integer + to its input. Delegates to ``number.__round__(ndigits)``. For the built-in types supporting :func:`round`, values are rounded to the closest multiple of 10 to the power minus *ndigits*; if two multiples are @@ -1198,7 +1248,7 @@ are always available. They are listed here in alphabetical order. .. _func-set: -.. function:: set([iterable]) +.. class:: set([iterable]) :noindex: Return a new :class:`set` object, optionally with elements taken from @@ -1219,8 +1269,8 @@ are always available. They are listed here in alphabetical order. ``x.foobar = 123``. -.. function:: slice(stop) - slice(start, stop[, step]) +.. class:: slice(stop) + slice(start, stop[, step]) .. index:: single: Numerical Python @@ -1251,8 +1301,13 @@ are always available. They are listed here in alphabetical order. Use :func:`functools.cmp_to_key` to convert an old-style *cmp* function to a *key* function. + The built-in :func:`sorted` function is guaranteed to be stable. A sort is + stable if it guarantees not to change the relative order of elements that + compare equal --- this is helpful for sorting in multiple passes (for + example, sort by department, then by salary grade). + For sorting examples and a brief sorting tutorial, see `Sorting HowTo - <http://wiki.python.org/moin/HowTo/Sorting/>`_\. + <https://wiki.python.org/moin/HowTo/Sorting/>`_\. .. function:: staticmethod(function) @@ -1283,8 +1338,8 @@ are always available. They are listed here in alphabetical order. .. _func-str: -.. function:: str(object='') - str(object=b'', encoding='utf-8', errors='strict') +.. class:: str(object='') + str(object=b'', encoding='utf-8', errors='strict') :noindex: Return a :class:`str` version of *object*. See :func:`str` for details. @@ -1371,12 +1426,11 @@ are always available. They are listed here in alphabetical order. sequence type, as documented in :ref:`typesseq-tuple` and :ref:`typesseq`. -.. function:: type(object) - type(name, bases, dict) +.. class:: type(object) + type(name, bases, dict) .. index:: object: type - With one argument, return the type of an *object*. The return value is a type object and generally the same object as returned by :attr:`object.__class__ <instance.__class__>`. @@ -1441,7 +1495,9 @@ are always available. They are listed here in alphabetical order. The left-to-right evaluation order of the iterables is guaranteed. This makes possible an idiom for clustering a data series into n-length groups - using ``zip(*[iter(s)]*n)``. + using ``zip(*[iter(s)]*n)``. This repeats the *same* iterator ``n`` times + so that each output tuple has the result of ``n`` calls to the iterator. + This has the effect of dividing the input into n-length chunks. :func:`zip` should only be used with unequal length inputs when you don't care about trailing, unmatched values from the longer iterables. If those diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index 77cd8384b1ff..46aa88767ea9 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -21,8 +21,8 @@ The :mod:`functools` module defines the following functions: .. function:: cmp_to_key(func) - Transform an old-style comparison function to a key function. Used with - tools that accept key functions (such as :func:`sorted`, :func:`min`, + Transform an old-style comparison function to a :term:`key function`. Used + with tools that accept key functions (such as :func:`sorted`, :func:`min`, :func:`max`, :func:`heapq.nlargest`, :func:`heapq.nsmallest`, :func:`itertools.groupby`). This function is primarily used as a transition tool for programs being converted from Python 2 which supported the use of @@ -31,13 +31,14 @@ The :mod:`functools` module defines the following functions: A comparison function is any callable that accept two arguments, compares them, and returns a negative number for less-than, zero for equality, or a positive number for greater-than. A key function is a callable that accepts one - argument and returns another value indicating the position in the desired - collation sequence. + argument and returns another value to be used as the sort key. Example:: sorted(iterable, key=cmp_to_key(locale.strcoll)) # locale-aware sort order + For sorting examples and a brief sorting tutorial, see :ref:`sortinghowto`. + .. versionadded:: 3.2 @@ -72,7 +73,7 @@ The :mod:`functools` module defines the following functions: bypassing the cache, or for rewrapping the function with a different cache. An `LRU (least recently used) cache - <http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used>`_ works + <http://en.wikipedia.org/wiki/Cache_algorithms#Examples>`_ works best when the most recent calls are the best predictors of upcoming calls (for example, the most popular articles on a news server tend to change each day). The cache's size limit assures that the cache does not grow without bound on @@ -218,6 +219,8 @@ The :mod:`functools` module defines the following functions: Example:: >>> class Cell(object): + ... def __init__(self): + ... self._alive = False ... @property ... def alive(self): ... return self._alive @@ -247,7 +250,7 @@ The :mod:`functools` module defines the following functions: a default when the sequence is empty. If *initializer* is not given and *sequence* contains only one item, the first item is returned. - Equivalent to:: + Roughly equivalent to:: def reduce(function, iterable, initializer=None): it = iter(iterable) @@ -411,9 +414,10 @@ The :mod:`functools` module defines the following functions: .. decorator:: wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES) - This is a convenience function for invoking ``partial(update_wrapper, - wrapped=wrapped, assigned=assigned, updated=updated)`` as a function decorator - when defining a wrapper function. For example: + This is a convenience function for invoking :func:`update_wrapper` as a + function decorator when defining a wrapper function. It is equivalent to + ``partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated)``. + For example:: >>> from functools import wraps >>> def my_decorator(f): diff --git a/Doc/library/gc.rst b/Doc/library/gc.rst index 6b95dc564526..d11c2e128273 100644 --- a/Doc/library/gc.rst +++ b/Doc/library/gc.rst @@ -69,9 +69,10 @@ The :mod:`gc` module provides the following functions: .. function:: get_stats() - Return a list of 3 per-generation dictionaries containing collection - statistics since interpreter start. At this moment, each dictionary will - contain the following items: + Return a list of three per-generation dictionaries containing collection + statistics since interpreter start. The number of keys may change + in the future, but currently each dictionary will contain the following + items: * ``collections`` is the number of times this generation was collected; @@ -185,7 +186,7 @@ values but should not rebind them): added to this list rather than freed. .. versionchanged:: 3.2 - If this list is non-empty at interpreter shutdown, a + If this list is non-empty at :term:`interpreter shutdown`, a :exc:`ResourceWarning` is emitted, which is silent by default. If :const:`DEBUG_UNCOLLECTABLE` is set, in addition all uncollectable objects are printed. @@ -251,8 +252,8 @@ The following constants are provided for use with :func:`set_debug`: to the ``garbage`` list. .. versionchanged:: 3.2 - Also print the contents of the :data:`garbage` list at interpreter - shutdown, if it isn't empty. + Also print the contents of the :data:`garbage` list at + :term:`interpreter shutdown`, if it isn't empty. .. data:: DEBUG_SAVEALL diff --git a/Doc/library/getopt.rst b/Doc/library/getopt.rst index b6ab3df02286..f9a1e53e38ba 100644 --- a/Doc/library/getopt.rst +++ b/Doc/library/getopt.rst @@ -10,6 +10,7 @@ -------------- .. note:: + The :mod:`getopt` module is a parser for command line options whose API is designed to be familiar to users of the C :c:func:`getopt` function. Users who are unfamiliar with the C :c:func:`getopt` function or who would like to write diff --git a/Doc/library/getpass.rst b/Doc/library/getpass.rst index ffe2b1256ba5..211563e23e56 100644 --- a/Doc/library/getpass.rst +++ b/Doc/library/getpass.rst @@ -13,10 +13,11 @@ The :mod:`getpass` module provides two functions: .. function:: getpass(prompt='Password: ', stream=None) Prompt the user for a password without echoing. The user is prompted using - the string *prompt*, which defaults to ``'Password: '``. On Unix, the prompt - is written to the file-like object *stream*. *stream* defaults to the - controlling terminal (:file:`/dev/tty`) or if that is unavailable to - ``sys.stderr`` (this argument is ignored on Windows). + the string *prompt*, which defaults to ``'Password: '``. On Unix, the + prompt is written to the file-like object *stream* using the replace error + handler if needed. *stream* defaults to the controlling terminal + (:file:`/dev/tty`) or if that is unavailable to ``sys.stderr`` (this + argument is ignored on Windows). If echo free input is unavailable getpass() falls back to printing a warning message to *stream* and reading from ``sys.stdin`` and diff --git a/Doc/library/gettext.rst b/Doc/library/gettext.rst index 982780fec15b..514cc5a9893f 100644 --- a/Doc/library/gettext.rst +++ b/Doc/library/gettext.rst @@ -344,9 +344,9 @@ will assume message ids as Unicode strings, not byte strings. The entire set of key/value pairs are placed into a dictionary and set as the "protected" :attr:`_info` instance variable. -If the :file:`.mo` file's magic number is invalid, or if other problems occur -while reading the file, instantiating a :class:`GNUTranslations` class can raise -:exc:`OSError`. +If the :file:`.mo` file's magic number is invalid, the major version number is +unexpected, or if other problems occur while reading the file, instantiating a +:class:`GNUTranslations` class can raise :exc:`OSError`. The following methods are overridden from the base class implementation: @@ -460,7 +460,7 @@ translatable. `Babel <http://babel.pocoo.org/>`__ is a Python internationalization library that includes a :file:`pybabel` script to extract and compile message catalogs. François Pinard's program called :program:`xpot` does a similar job and is available as part of -his `po-utils package <http://po-utils.progiciels-bpi.ca/>`__. +his `po-utils package <https://github.com/pinard/po-utils>`__. (Python also includes pure-Python versions of these programs, called :program:`pygettext.py` and :program:`msgfmt.py`; some Python distributions diff --git a/Doc/library/glob.rst b/Doc/library/glob.rst index abcbf380d95e..50f38a4d3656 100644 --- a/Doc/library/glob.rst +++ b/Doc/library/glob.rst @@ -29,7 +29,7 @@ For example, ``'[?]'`` matches the character ``'?'``. The :mod:`pathlib` module offers high-level path objects. -.. function:: glob(pathname) +.. function:: glob(pathname, *, recursive=False) Return a possibly-empty list of path names that match *pathname*, which must be a string containing a path specification. *pathname* can be either absolute @@ -37,8 +37,19 @@ For example, ``'[?]'`` matches the character ``'?'``. :file:`../../Tools/\*/\*.gif`), and can contain shell-style wildcards. Broken symlinks are included in the results (as in the shell). + If *recursive* is true, the pattern "``**``" will match any files and zero or + more directories and subdirectories. If the pattern is followed by a + ``os.sep``, only directories and subdirectories match. -.. function:: iglob(pathname) + .. note:: + Using the "``**``" pattern in large directory trees may consume + an inordinate amount of time. + + .. versionchanged:: 3.5 + Support for recursive globs using "``**``". + + +.. function:: iglob(pathname, recursive=False) Return an :term:`iterator` which yields the same values as :func:`glob` without actually storing them all simultaneously. @@ -55,8 +66,9 @@ For example, ``'[?]'`` matches the character ``'?'``. .. versionadded:: 3.4 -For example, consider a directory containing only the following files: -:file:`1.gif`, :file:`2.txt`, and :file:`card.gif`. :func:`glob` will produce +For example, consider a directory containing the following files: +:file:`1.gif`, :file:`2.txt`, :file:`card.gif` and a subdirectory :file:`sub` +which contains only the file :file:`3.txt`. :func:`glob` will produce the following results. Notice how any leading components of the path are preserved. :: @@ -67,6 +79,10 @@ preserved. :: ['1.gif', 'card.gif'] >>> glob.glob('?.gif') ['1.gif'] + >>> glob.glob('**/*.txt', recursive=True) + ['2.txt', 'sub/3.txt'] + >>> glob.glob('./**/', recursive=True) + ['./', './sub/'] If the directory contains files starting with ``.`` they won't be matched by default. For example, consider a directory containing :file:`card.gif` and diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst index de5063a7c7cf..04c41d585c8e 100644 --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -90,13 +90,9 @@ The module defines the following items: is no compression. The default is ``9``. The *mtime* argument is an optional numeric timestamp to be written to - the stream when compressing. All :program:`gzip` compressed streams are - required to contain a timestamp. If omitted or ``None``, the current - time is used. This module ignores the timestamp when decompressing; - however, some programs, such as :program:`gunzip`\ , make use of it. - The format of the timestamp is the same as that of the return value of - ``time.time()`` and of the ``st_mtime`` attribute of the object returned - by ``os.stat()``. + the last modification time field in the stream when compressing. It + should only be provided in compression mode. If omitted or ``None``, the + current time is used. See the :attr:`mtime` attribute for more details. Calling a :class:`GzipFile` object's :meth:`close` method does not close *fileobj*, since you might wish to append more material after the compressed @@ -108,20 +104,37 @@ The module defines the following items: including iteration and the :keyword:`with` statement. Only the :meth:`truncate` method isn't implemented. - :class:`GzipFile` also provides the following method: + :class:`GzipFile` also provides the following method and attribute: - .. method:: peek([n]) + .. method:: peek(n) Read *n* uncompressed bytes without advancing the file position. At most one single read on the compressed stream is done to satisfy the call. The number of bytes returned may be more or less than requested. + .. note:: While calling :meth:`peek` does not change the file position of + the :class:`GzipFile`, it may change the position of the underlying + file object (e.g. if the :class:`GzipFile` was constructed with the + *fileobj* parameter). + .. versionadded:: 3.2 + .. attribute:: mtime + + When decompressing, the value of the last modification time field in + the most recently read header may be read from this attribute, as an + integer. The initial value before reading any headers is ``None``. + + All :program:`gzip` compressed streams are required to contain this + timestamp field. Some programs, such as :program:`gunzip`\ , make use + of the timestamp. The format is the same as the return value of + :func:`time.time` and the :attr:`~os.stat_result.st_mtime` attribute of + the object returned by :func:`os.stat`. + .. versionchanged:: 3.1 Support for the :keyword:`with` statement was added, along with the - *mtime* argument. + *mtime* constructor argument and :attr:`mtime` attribute. .. versionchanged:: 3.2 Support for zero-padded and unseekable files was added. @@ -132,6 +145,12 @@ The module defines the following items: .. versionchanged:: 3.4 Added support for the ``'x'`` and ``'xb'`` modes. + .. versionchanged:: 3.5 + Added support for writing arbitrary + :term:`bytes-like objects <bytes-like object>`. + The :meth:`~io.BufferedIOBase.read` method now accepts an argument of + ``None``. + .. function:: compress(data, compresslevel=9) @@ -170,9 +189,10 @@ Example of how to create a compressed GZIP file:: Example of how to GZIP compress an existing file:: import gzip + import shutil with open('/home/joe/file.txt', 'rb') as f_in: with gzip.open('/home/joe/file.txt.gz', 'wb') as f_out: - f_out.writelines(f_in) + shutil.copyfileobj(f_in, f_out) Example of how to GZIP compress a binary string:: diff --git a/Doc/library/hashlib.rst b/Doc/library/hashlib.rst index b1daba124ffb..769f96f0176e 100644 --- a/Doc/library/hashlib.rst +++ b/Doc/library/hashlib.rst @@ -33,6 +33,8 @@ digests. The modern term is secure hash. also" section at the end. +.. _hash-algorithms: + Hash algorithms --------------- @@ -58,13 +60,9 @@ concatenation of the data fed to it so far using the :meth:`digest` or Constructors for hash algorithms that are always present in this module are :func:`md5`, :func:`sha1`, :func:`sha224`, :func:`sha256`, :func:`sha384`, -:func:`sha512`, :func:`sha3_224`, :func:`sha3_256`, :func:`sha3_384`, and -:func:`sha3_512`. Additional algorithms may also be available depending upon +and :func:`sha512`. Additional algorithms may also be available depending upon the OpenSSL library that Python uses on your platform. - .. versionchanged:: 3.4 - Add sha3 family of hash algorithms. - For example, to obtain the digest of the byte string ``b'Nobody inspects the spammish repetition'``:: @@ -103,18 +101,18 @@ Hashlib provides the following constant attributes: .. data:: algorithms_guaranteed - Contains the names of the hash algorithms guaranteed to be supported + A set containing the names of the hash algorithms guaranteed to be supported by this module on all platforms. .. versionadded:: 3.2 .. data:: algorithms_available - Contains the names of the hash algorithms that are available - in the running Python interpreter. These names will be recognized - when passed to :func:`new`. :attr:`algorithms_guaranteed` - will always be a subset. Duplicate algorithms with different - name formats may appear in this set (thanks to OpenSSL). + A set containing the names of the hash algorithms that are available in the + running Python interpreter. These names will be recognized when passed to + :func:`new`. :attr:`algorithms_guaranteed` will always be a subset. The + same algorithm may appear multiple times in this set under different names + (thanks to OpenSSL). .. versionadded:: 3.2 @@ -178,13 +176,13 @@ A hash object has the following methods: compute the digests of data sharing a common initial substring. -Key Derivation Function ------------------------ +Key derivation +-------------- Key derivation and key stretching algorithms are designed for secure password -hashing. Naive algorithms such as ``sha1(password)`` are not resistant -against brute-force attacks. A good password hashing function must be tunable, -slow and include a salt. +hashing. Naive algorithms such as ``sha1(password)`` are not resistant against +brute-force attacks. A good password hashing function must be tunable, slow, and +include a `salt <https://en.wikipedia.org/wiki/Salt_%28cryptography%29>`_. .. function:: pbkdf2_hmac(name, password, salt, rounds, dklen=None) @@ -199,8 +197,7 @@ slow and include a salt. a proper source, e.g. :func:`os.urandom`. The number of *rounds* should be chosen based on the hash algorithm and - computing power. As of 2013 a value of at least 100,000 rounds of SHA-256 - have been suggested. + computing power. As of 2013, at least 100,000 rounds of SHA-256 is suggested. *dklen* is the length of the derived key. If *dklen* is ``None`` then the digest size of the hash algorithm *name* is used, e.g. 64 for SHA-512. @@ -212,9 +209,11 @@ slow and include a salt. .. versionadded:: 3.4 - .. note:: A fast implementation of *pbkdf2_hmac* is available with OpenSSL. - The Python implementation uses an inline version of :mod:`hmac`. It is - about three times slower and doesn't release the GIL. + .. note:: + + A fast implementation of *pbkdf2_hmac* is available with OpenSSL. The + Python implementation uses an inline version of :mod:`hmac`. It is about + three times slower and doesn't release the GIL. .. seealso:: @@ -228,7 +227,7 @@ slow and include a salt. http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf The FIPS 180-2 publication on Secure Hash Algorithms. - http://en.wikipedia.org/wiki/Cryptographic_hash_function#Cryptographic_hash_algorithms + https://en.wikipedia.org/wiki/Cryptographic_hash_function#Cryptographic_hash_algorithms Wikipedia article with information on which algorithms have known issues and what that means regarding their use. diff --git a/Doc/library/heapq.rst b/Doc/library/heapq.rst index 4f1a682a875b..9fbbcc690491 100644 --- a/Doc/library/heapq.rst +++ b/Doc/library/heapq.rst @@ -47,7 +47,8 @@ The following functions are provided: .. function:: heappop(heap) Pop and return the smallest item from the *heap*, maintaining the heap - invariant. If the heap is empty, :exc:`IndexError` is raised. + invariant. If the heap is empty, :exc:`IndexError` is raised. To access the + smallest item without popping it, use ``heap[0]``. .. function:: heappushpop(heap, item) @@ -81,7 +82,7 @@ The following functions are provided: The module also offers three general purpose functions based on heaps. -.. function:: merge(*iterables) +.. function:: merge(*iterables, key=None, reverse=False) Merge multiple sorted inputs into a single sorted output (for example, merge timestamped entries from multiple log files). Returns an :term:`iterator` @@ -91,6 +92,18 @@ The module also offers three general purpose functions based on heaps. not pull the data into memory all at once, and assumes that each of the input streams is already sorted (smallest to largest). + Has two optional arguments which must be specified as keyword arguments. + + *key* specifies a :term:`key function` of one argument that is used to + extract a comparison key from each input element. The default value is + ``None`` (compare the elements directly). + + *reverse* is a boolean value. If set to ``True``, then the input elements + are merged as if each comparison were reversed. + + .. versionchanged:: 3.5 + Added the optional *key* and *reverse* parameters. + .. function:: nlargest(n, iterable, key=None) @@ -112,7 +125,8 @@ The module also offers three general purpose functions based on heaps. The latter two functions perform best for smaller values of *n*. For larger values, it is more efficient to use the :func:`sorted` function. Also, when ``n==1``, it is more efficient to use the built-in :func:`min` and :func:`max` -functions. +functions. If repeated usage of these functions is required, consider turning +the iterable into an actual heap. Basic Examples @@ -123,7 +137,6 @@ pushing all values onto a heap and then popping off the smallest values one at a time:: >>> def heapsort(iterable): - ... 'Equivalent to sorted(iterable)' ... h = [] ... for value in iterable: ... heappush(h, value) @@ -132,6 +145,9 @@ time:: >>> heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0]) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +This is similar to ``sorted(iterable)``, but unlike :func:`sorted`, this +implementation is not stable. + Heap elements can be tuples. This is useful for assigning comparison values (such as task priorities) alongside the main record being tracked:: @@ -258,11 +274,11 @@ However, there are other representations which are more efficient overall, yet the worst cases might be terrible. Heaps are also very useful in big disk sorts. You most probably all know that a -big sort implies producing "runs" (which are pre-sorted sequences, which size is +big sort implies producing "runs" (which are pre-sorted sequences, whose size is usually related to the amount of CPU memory), followed by a merging passes for these runs, which merging is often very cleverly organised [#]_. It is very important that the initial sort produces the longest runs possible. Tournaments -are a good way to that. If, using all the memory available to hold a +are a good way to achieve that. If, using all the memory available to hold a tournament, you replace and percolate items that happen to fit the current run, you'll produce runs which are twice the size of the memory for random input, and much better for input fuzzily ordered. diff --git a/Doc/library/hmac.rst b/Doc/library/hmac.rst index 2e9b0b26a575..1446da6ee653 100644 --- a/Doc/library/hmac.rst +++ b/Doc/library/hmac.rst @@ -3,7 +3,6 @@ .. module:: hmac :synopsis: Keyed-Hashing for Message Authentication (HMAC) implementation - for Python. .. moduleauthor:: Gerhard Häring <ghaering@users.sourceforge.net> .. sectionauthor:: Gerhard Häring <ghaering@users.sourceforge.net> @@ -23,10 +22,9 @@ This module implements the HMAC algorithm as described by :rfc:`2104`. defaults to the :data:`hashlib.md5` constructor. .. versionchanged:: 3.4 - Parameter *key* can be a bytes or bytearray object. Parameter *msg* can - be of any type supported by :mod:`hashlib`. - - Paramter *digestmod* can be the name of a hash algorithm. + Parameter *key* can be a bytes or bytearray object. + Parameter *msg* can be of any type supported by :mod:`hashlib`. + Parameter *digestmod* can be the name of a hash algorithm. .. deprecated:: 3.4 MD5 as implicit default digest for *digestmod* is deprecated. diff --git a/Doc/library/html.entities.rst b/Doc/library/html.entities.rst index 09b0abc83793..e10e46e2b8dd 100644 --- a/Doc/library/html.entities.rst +++ b/Doc/library/html.entities.rst @@ -33,12 +33,12 @@ This module defines four dictionaries, :data:`html5`, .. data:: name2codepoint - A dictionary that maps HTML entity names to the Unicode codepoints. + A dictionary that maps HTML entity names to the Unicode code points. .. data:: codepoint2name - A dictionary that maps Unicode codepoints to HTML entity names. + A dictionary that maps Unicode code points to HTML entity names. .. rubric:: Footnotes diff --git a/Doc/library/html.parser.rst b/Doc/library/html.parser.rst index 44b7d6ea6d28..824995eddcee 100644 --- a/Doc/library/html.parser.rst +++ b/Doc/library/html.parser.rst @@ -16,21 +16,13 @@ This module defines a class :class:`HTMLParser` which serves as the basis for parsing text files formatted in HTML (HyperText Mark-up Language) and XHTML. -.. class:: HTMLParser(strict=False, *, convert_charrefs=False) +.. class:: HTMLParser(*, convert_charrefs=True) - Create a parser instance. + Create a parser instance able to parse invalid markup. - If *convert_charrefs* is ``True`` (default: ``False``), all character + If *convert_charrefs* is ``True`` (the default), all character references (except the ones in ``script``/``style`` elements) are automatically converted to the corresponding Unicode characters. - The use of ``convert_charrefs=True`` is encouraged and will become - the default in Python 3.5. - - If *strict* is ``False`` (the default), the parser will accept and parse - invalid markup. If *strict* is ``True`` the parser will raise an - :exc:`~html.parser.HTMLParseError` exception instead [#]_ when it's not - able to parse the markup. The use of ``strict=True`` is discouraged and - the *strict* argument is deprecated. An :class:`.HTMLParser` instance is fed HTML data and calls handler methods when start tags, end tags, text, comments, and other markup elements are @@ -40,31 +32,11 @@ parsing text files formatted in HTML (HyperText Mark-up Language) and XHTML. This parser does not check that end tags match start tags or call the end-tag handler for elements which are closed implicitly by closing an outer element. - .. versionchanged:: 3.2 - *strict* argument added. - - .. deprecated-removed:: 3.3 3.5 - The *strict* argument and the strict mode have been deprecated. - The parser is now able to accept and parse invalid markup too. - .. versionchanged:: 3.4 *convert_charrefs* keyword argument added. -An exception is defined as well: - - -.. exception:: HTMLParseError - - Exception raised by the :class:`HTMLParser` class when it encounters an error - while parsing and *strict* is ``True``. This exception provides three - attributes: :attr:`msg` is a brief message explaining the error, - :attr:`lineno` is the number of the line on which the broken construct was - detected, and :attr:`offset` is the number of characters into the line at - which the construct starts. - - .. deprecated-removed:: 3.3 3.5 - This exception has been deprecated because it's never raised by the parser - (when the default non-strict mode is used). + .. versionchanged:: 3.5 + The default value for argument *convert_charrefs* is now ``True``. Example HTML Parser Application @@ -213,7 +185,7 @@ implementations do nothing (except for :meth:`~HTMLParser.handle_startendtag`): The content of Internet Explorer conditional comments (condcoms) will also be sent to this method, so, for ``<!--[if IE 9]>IE9-specific content<![endif]-->``, - this method will receive ``'[if IE 9]>IE-specific content<![endif]'``. + this method will receive ``'[if IE 9]>IE9-specific content<![endif]'``. .. method:: HTMLParser.handle_decl(decl) @@ -246,8 +218,7 @@ implementations do nothing (except for :meth:`~HTMLParser.handle_startendtag`): The *data* parameter will be the entire contents of the declaration inside the ``<![...]>`` markup. It is sometimes useful to be overridden by a - derived class. The base class implementation raises an :exc:`HTMLParseError` - when *strict* is ``True``. + derived class. The base class implementation does nothing. .. _htmlparser-examples: @@ -358,9 +329,3 @@ Parsing invalid HTML (e.g. unquoted attributes) also works:: Data : tag soup End tag : p End tag : a - -.. rubric:: Footnotes - -.. [#] For backward compatibility reasons *strict* mode does not raise - exceptions for all non-compliant HTML. That is, some invalid HTML - is tolerated even in *strict* mode. diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst index 2dbfa200ea56..d57649c4aaa6 100644 --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -19,6 +19,11 @@ This module defines classes which implement the client side of the HTTP and HTTPS protocols. It is normally not used directly --- the module :mod:`urllib.request` uses it to handle URLs that use HTTP and HTTPS. +.. seealso:: + + The `Requests package <http://requests.readthedocs.org/>`_ + is recommended for a higher-level http client interface. + .. note:: HTTPS support is only available if Python was compiled with SSL support @@ -43,17 +48,17 @@ The module provides the following classes: For example, the following calls all create instances that connect to the server at the same host and port:: - >>> h1 = http.client.HTTPConnection('www.cwi.nl') - >>> h2 = http.client.HTTPConnection('www.cwi.nl:80') - >>> h3 = http.client.HTTPConnection('www.cwi.nl', 80) - >>> h3 = http.client.HTTPConnection('www.cwi.nl', 80, timeout=10) + >>> h1 = http.client.HTTPConnection('www.python.org') + >>> h2 = http.client.HTTPConnection('www.python.org:80') + >>> h3 = http.client.HTTPConnection('www.python.org', 80) + >>> h4 = http.client.HTTPConnection('www.python.org', 80, timeout=10) .. versionchanged:: 3.2 *source_address* was added. .. versionchanged:: 3.4 - The *strict* parameter is removed. HTTP 0.9-style "Simple Responses" are - not supported. + The *strict* parameter was removed. HTTP 0.9-style "Simple Responses" are + not longer supported. .. class:: HTTPSConnection(host, port=None, key_file=None, \ @@ -64,23 +69,16 @@ The module provides the following classes: A subclass of :class:`HTTPConnection` that uses SSL for communication with secure servers. Default port is ``443``. If *context* is specified, it must be a :class:`ssl.SSLContext` instance describing the various SSL - options. If *context* is specified and has a :attr:`~ssl.SSLContext.verify_mode` - of either :data:`~ssl.CERT_OPTIONAL` or :data:`~ssl.CERT_REQUIRED`, then - by default *host* is matched against the host name(s) allowed by the - server's certificate. If you want to change that behaviour, you can - explicitly set *check_hostname* to False. + options. *key_file* and *cert_file* are deprecated, please use - :meth:`ssl.SSLContext.load_cert_chain` instead. - - If you access arbitrary hosts on the Internet, it is recommended to - require certificate checking and feed the *context* with a set of - trusted CA certificates:: + :meth:`ssl.SSLContext.load_cert_chain` instead, or let + :func:`ssl.create_default_context` select the system's trusted CA + certificates for you. The *check_hostname* parameter is also deprecated; the + :attr:`ssl.SSLContext.check_hostname` attribute of *context* should be used + instead. - context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) - context.verify_mode = ssl.CERT_REQUIRED - context.load_verify_locations('/etc/pki/tls/certs/ca-bundle.crt') - h = client.HTTPSConnection('svn.python.org', 443, context=context) + Please read :ref:`ssl-security` for more information on best practices. .. versionchanged:: 3.2 *source_address*, *context* and *check_hostname* were added. @@ -90,8 +88,14 @@ The module provides the following classes: if :data:`ssl.HAS_SNI` is true). .. versionchanged:: 3.4 - The *strict* parameter is removed. HTTP 0.9-style "Simple Responses" are - not supported anymore. + The *strict* parameter was removed. HTTP 0.9-style "Simple Responses" are + no longer supported. + + .. versionchanged:: 3.4.3 + This class now performs all the necessary certificate and hostname checks + by default. To revert to the previous, unverified, behavior + :func:`ssl._create_unverified_context` can be passed to the *context* + parameter. .. class:: HTTPResponse(sock, debuglevel=0, method=None, url=None) @@ -100,8 +104,8 @@ The module provides the following classes: instantiated directly by user. .. versionchanged:: 3.4 - The *strict* parameter is removed. HTTP 0.9 style "Simple Responses" are - not supported anymore. + The *strict* parameter was removed. HTTP 0.9 style "Simple Responses" are + no longer supported. The following exceptions are raised as appropriate: @@ -170,6 +174,23 @@ The following exceptions are raised as appropriate: status code that we don't understand. +.. exception:: LineTooLong + + A subclass of :exc:`HTTPException`. Raised if an excessively long line + is received in the HTTP protocol from the server. + + +.. exception:: RemoteDisconnected + + A subclass of :exc:`ConnectionResetError` and :exc:`BadStatusLine`. Raised + by :meth:`HTTPConnection.getresponse` when the attempt to read the response + results in no data read from the connection, indicating that the remote end + has closed the connection. + + .. versionadded:: 3.5 + Previously, :exc:`BadStatusLine`\ ``('')`` was raised. + + The constants defined in this module are: .. data:: HTTP_PORT @@ -181,221 +202,15 @@ The constants defined in this module are: The default port for the HTTPS protocol (always ``443``). -and also the following constants for integer status codes: - -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| Constant | Value | Definition | -+==========================================+=========+=======================================================================+ -| :const:`CONTINUE` | ``100`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.1.1 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.1.1>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`SWITCHING_PROTOCOLS` | ``101`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.1.2 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.1.2>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`PROCESSING` | ``102`` | WEBDAV, `RFC 2518, Section 10.1 | -| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_102>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`OK` | ``200`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.2.1 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.1>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`CREATED` | ``201`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.2.2 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.2>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`ACCEPTED` | ``202`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.2.3 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.3>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`NON_AUTHORITATIVE_INFORMATION` | ``203`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.2.4 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.4>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`NO_CONTENT` | ``204`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.2.5 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.5>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`RESET_CONTENT` | ``205`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.2.6 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.6>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`PARTIAL_CONTENT` | ``206`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.2.7 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.7>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`MULTI_STATUS` | ``207`` | WEBDAV `RFC 2518, Section 10.2 | -| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_207>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`IM_USED` | ``226`` | Delta encoding in HTTP, | -| | | :rfc:`3229`, Section 10.4.1 | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`MULTIPLE_CHOICES` | ``300`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.3.1 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.1>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`MOVED_PERMANENTLY` | ``301`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.3.2 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.2>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`FOUND` | ``302`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.3.3 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.3>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`SEE_OTHER` | ``303`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.3.4 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.4>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`NOT_MODIFIED` | ``304`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.3.5 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`USE_PROXY` | ``305`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.3.6 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.6>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`TEMPORARY_REDIRECT` | ``307`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.3.8 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.8>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`BAD_REQUEST` | ``400`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.1 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.1>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`UNAUTHORIZED` | ``401`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.2 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`PAYMENT_REQUIRED` | ``402`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.3 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.3>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`FORBIDDEN` | ``403`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.4 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.4>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`NOT_FOUND` | ``404`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.5 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`METHOD_NOT_ALLOWED` | ``405`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.6 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.6>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`NOT_ACCEPTABLE` | ``406`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.7 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.7>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`PROXY_AUTHENTICATION_REQUIRED` | ``407`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.8 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.8>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`REQUEST_TIMEOUT` | ``408`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.9 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.9>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`CONFLICT` | ``409`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.10 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.10>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`GONE` | ``410`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.11 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.11>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`LENGTH_REQUIRED` | ``411`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.12 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.12>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`PRECONDITION_FAILED` | ``412`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.13 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.13>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`REQUEST_ENTITY_TOO_LARGE` | ``413`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.14 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.14>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`REQUEST_URI_TOO_LONG` | ``414`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.15 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.15>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`UNSUPPORTED_MEDIA_TYPE` | ``415`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.16 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.16>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`REQUESTED_RANGE_NOT_SATISFIABLE` | ``416`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.17 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.17>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`EXPECTATION_FAILED` | ``417`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.4.18 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.18>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`UNPROCESSABLE_ENTITY` | ``422`` | WEBDAV, `RFC 2518, Section 10.3 | -| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_422>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`LOCKED` | ``423`` | WEBDAV `RFC 2518, Section 10.4 | -| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_423>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`FAILED_DEPENDENCY` | ``424`` | WEBDAV, `RFC 2518, Section 10.5 | -| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_424>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`UPGRADE_REQUIRED` | ``426`` | HTTP Upgrade to TLS, | -| | | :rfc:`2817`, Section 6 | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`PRECONDITION_REQUIRED` | ``428`` | Additional HTTP Status Codes, | -| | | :rfc:`6585`, Section 3 | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`TOO_MANY_REQUESTS` | ``429`` | Additional HTTP Status Codes, | -| | | :rfc:`6585`, Section 4 | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`REQUEST_HEADER_FIELDS_TOO_LARGE` | ``431`` | Additional HTTP Status Codes, | -| | | :rfc:`6585`, Section 5 | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`INTERNAL_SERVER_ERROR` | ``500`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.5.1 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`NOT_IMPLEMENTED` | ``501`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.5.2 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.2>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`BAD_GATEWAY` | ``502`` | HTTP/1.1 `RFC 2616, Section | -| | | 10.5.3 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.3>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`SERVICE_UNAVAILABLE` | ``503`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.5.4 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.4>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`GATEWAY_TIMEOUT` | ``504`` | HTTP/1.1 `RFC 2616, Section | -| | | 10.5.5 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.5>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`HTTP_VERSION_NOT_SUPPORTED` | ``505`` | HTTP/1.1, `RFC 2616, Section | -| | | 10.5.6 | -| | | <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.6>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`INSUFFICIENT_STORAGE` | ``507`` | WEBDAV, `RFC 2518, Section 10.6 | -| | | <http://www.webdav.org/specs/rfc2518.html#STATUS_507>`_ | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`NOT_EXTENDED` | ``510`` | An HTTP Extension Framework, | -| | | :rfc:`2774`, Section 7 | -+------------------------------------------+---------+-----------------------------------------------------------------------+ -| :const:`NETWORK_AUTHENTICATION_REQUIRED` | ``511`` | Additional HTTP Status Codes, | -| | | :rfc:`6585`, Section 6 | -+------------------------------------------+---------+-----------------------------------------------------------------------+ - -.. versionchanged:: 3.3 - Added codes ``428``, ``429``, ``431`` and ``511`` from :rfc:`6585`. - - .. data:: responses This dictionary maps the HTTP 1.1 status codes to the W3C names. Example: ``http.client.responses[http.client.NOT_FOUND]`` is ``'Not Found'``. +See :ref:`http-status-codes` for a list of HTTP status codes that are +available in this module as constants. + .. _httpconnection-objects: @@ -408,23 +223,33 @@ HTTPConnection Objects .. method:: HTTPConnection.request(method, url, body=None, headers={}) This will send a request to the server using the HTTP request - method *method* and the selector *url*. If the *body* argument is - present, it should be string or bytes object of data to send after - the headers are finished. Strings are encoded as ISO-8859-1, the - default charset for HTTP. To use other encodings, pass a bytes - object. The Content-Length header is set to the length of the - string. - - The *body* may also be an open :term:`file object`, in which case the - contents of the file is sent; this file object should support ``fileno()`` - and ``read()`` methods. The header Content-Length is automatically set to - the length of the file as reported by stat. The *body* argument may also be - an iterable and Content-Length header should be explicitly provided when the - body is an iterable. + method *method* and the selector *url*. + + If *body* is specified, the specified data is sent after the headers are + finished. It may be a string, a :term:`bytes-like object`, an open + :term:`file object`, or an iterable of :term:`bytes-like object`\s. If + *body* is a string, it is encoded as ISO-8851-1, the default for HTTP. If + it is a bytes-like object the bytes are sent as is. If it is a :term:`file + object`, the contents of the file is sent; this file object should support + at least the ``read()`` method. If the file object has a ``mode`` + attribute, the data returned by the ``read()`` method will be encoded as + ISO-8851-1 unless the ``mode`` attribute contains the substring ``b``, + otherwise the data returned by ``read()`` is sent as is. If *body* is an + iterable, the elements of the iterable are sent as is until the iterable is + exhausted. The *headers* argument should be a mapping of extra HTTP headers to send with the request. + If *headers* does not contain a Content-Length item, one is added + automatically if possible. If *body* is ``None``, the Content-Length header + is set to ``0`` for methods that expect a body (``PUT``, ``POST``, and + ``PATCH``). If *body* is a string or bytes object, the Content-Length + header is set to its length. If *body* is a :term:`file object` and it + works to call :func:`~os.fstat` on the result of its ``fileno()`` method, + then the Content-Length header is set to the ``st_size`` reported by the + ``fstat`` call. Otherwise no Content-Length header is added. + .. versionadded:: 3.2 *body* can now be an iterable. @@ -438,6 +263,11 @@ HTTPConnection Objects Note that you must have read the whole response before you can send a new request to the server. + .. versionchanged:: 3.5 + If a :exc:`ConnectionError` or subclass is raised, the + :class:`HTTPConnection` object will be ready to reconnect when + a new request is sent. + .. method:: HTTPConnection.set_debuglevel(level) @@ -451,18 +281,34 @@ HTTPConnection Objects .. method:: HTTPConnection.set_tunnel(host, port=None, headers=None) - Set the host and the port for HTTP Connect Tunnelling. Normally used when it - is required to a HTTPS Connection through a proxy server. + Set the host and the port for HTTP Connect Tunnelling. This allows running + the connection through a proxy server. + + The host and port arguments specify the endpoint of the tunneled connection + (i.e. the address included in the CONNECT request, *not* the address of the + proxy server). + + The headers argument should be a mapping of extra HTTP headers to send with + the CONNECT request. + + For example, to tunnel through a HTTPS proxy server running locally on port + 8080, we would pass the address of the proxy to the :class:`HTTPSConnection` + constructor, and the address of the host that we eventually want to reach to + the :meth:`~HTTPConnection.set_tunnel` method:: - The headers argument should be a mapping of extra HTTP headers to send - with the CONNECT request. + >>> import http.client + >>> conn = http.client.HTTPSConnection("localhost", 8080) + >>> conn.set_tunnel("www.python.org") + >>> conn.request("HEAD","/index.html") .. versionadded:: 3.2 .. method:: HTTPConnection.connect() - Connect to the server specified when the object was created. + Connect to the server specified when the object was created. By default, + this is called automatically when making a request if the client does not + already have a connection. .. method:: HTTPConnection.close() @@ -581,18 +427,18 @@ Examples Here is an example session that uses the ``GET`` method:: >>> import http.client - >>> conn = http.client.HTTPConnection("www.python.org") - >>> conn.request("GET", "/index.html") + >>> conn = http.client.HTTPSConnection("www.python.org") + >>> conn.request("GET", "/") >>> r1 = conn.getresponse() >>> print(r1.status, r1.reason) 200 OK >>> data1 = r1.read() # This will return entire content. >>> # The following example demonstrates reading data in chunks. - >>> conn.request("GET", "/index.html") + >>> conn.request("GET", "/") >>> r1 = conn.getresponse() >>> while not r1.closed: ... print(r1.read(200)) # 200 bytes - b'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"... + b'<!doctype html>\n<!--[if"... ... >>> # Example of an invalid request >>> conn.request("GET", "/parrot.spam") @@ -606,8 +452,8 @@ Here is an example session that uses the ``HEAD`` method. Note that the ``HEAD`` method never returns any data. :: >>> import http.client - >>> conn = http.client.HTTPConnection("www.python.org") - >>> conn.request("HEAD","/index.html") + >>> conn = http.client.HTTPSConnection("www.python.org") + >>> conn.request("HEAD", "/") >>> res = conn.getresponse() >>> print(res.status, res.reason) 200 OK @@ -642,7 +488,7 @@ request using http.client:: >>> # This creates an HTTP message >>> # with the content of BODY as the enclosed representation - >>> # for the resource http://localhost:8080/foobar + >>> # for the resource http://localhost:8080/file ... >>> import http.client >>> BODY = "***filecontents***" diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst index b50cb226b780..30648acbf0f5 100644 --- a/Doc/library/http.cookiejar.rst +++ b/Doc/library/http.cookiejar.rst @@ -115,7 +115,7 @@ The following classes are provided: :mod:`http.cookiejar` and :mod:`http.cookies` modules do not depend on each other. - http://wp.netscape.com/newsref/std/cookie_spec.html + http://curl.haxx.se/rfc/cookie_spec.html The specification of the original Netscape cookie protocol. Though this is still the dominant protocol, the 'Netscape cookie protocol' implemented by all the major browsers (and :mod:`http.cookiejar`) only bears a passing resemblance to @@ -309,7 +309,7 @@ FileCookieJar subclasses and co-operation with web browsers ----------------------------------------------------------- The following :class:`CookieJar` subclasses are provided for reading and -writing . +writing. .. class:: MozillaCookieJar(filename, delayload=None, policy=None) @@ -540,7 +540,7 @@ Netscape protocol strictness switches: .. attribute:: DefaultCookiePolicy.strict_ns_unverifiable - apply RFC 2965 rules on unverifiable transactions even to Netscape cookies + Apply RFC 2965 rules on unverifiable transactions even to Netscape cookies. .. attribute:: DefaultCookiePolicy.strict_ns_domain diff --git a/Doc/library/http.cookies.rst b/Doc/library/http.cookies.rst index 646f2e88602b..c2bb80d5d19d 100644 --- a/Doc/library/http.cookies.rst +++ b/Doc/library/http.cookies.rst @@ -84,7 +84,7 @@ Cookie Objects Return an encoded value. *val* can be any type, but return value must be a string. This method does nothing in :class:`BaseCookie` --- it exists so it can - be overridden + be overridden. In general, it should be the case that :meth:`value_encode` and :meth:`value_decode` are inverses on the range of *value_decode*. @@ -143,26 +143,43 @@ Morsel Objects The keys are case-insensitive. + .. versionchanged:: 3.5 + :meth:`~Morsel.__eq__` now takes :attr:`~Morsel.key` and :attr:`~Morsel.value` + into account. + .. attribute:: Morsel.value The value of the cookie. + .. deprecated:: 3.5 + assigning to ``value``; use :meth:`~Morsel.set` instead. + .. attribute:: Morsel.coded_value The encoded value of the cookie --- this is what should be sent. + .. deprecated:: 3.5 + assigning to ``coded_value``; use :meth:`~Morsel.set` instead. + .. attribute:: Morsel.key The name of the cookie. + .. deprecated:: 3.5 + assigning to ``key``; use :meth:`~Morsel.set` instead. + .. method:: Morsel.set(key, value, coded_value) Set the *key*, *value* and *coded_value* attributes. + .. deprecated:: 3.5 + The undocumented *LegalChars* parameter is ignored and will be removed in + a future version. + .. method:: Morsel.isReservedKey(K) @@ -193,6 +210,30 @@ Morsel Objects The meaning for *attrs* is the same as in :meth:`output`. +.. method:: Morsel.update(values) + + Update the values in the Morsel dictionary with the values in the dictionary + *values*. Raise an error if any of the keys in the *values* dict is not a + valid :rfc:`2109` attribute. + + .. versionchanged:: 3.5 + an error is raised for invalid keys. + + +.. method:: Morsel.copy(value) + + Return a shallow copy of the Morsel object. + + .. versionchanged:: 3.5 + return a Morsel object instead of a dict. + + +.. method:: Morsel.setdefault(key, value=None) + + Raise an error if key is not a valid :rfc:`2109` attribute, otherwise + behave the same as :meth:`dict.setdefault`. + + .. _cookie-example: Example diff --git a/Doc/library/http.rst b/Doc/library/http.rst index a387a37ddd2a..b6f2c582185e 100644 --- a/Doc/library/http.rst +++ b/Doc/library/http.rst @@ -1,7 +1,16 @@ :mod:`http` --- HTTP modules ============================ -``http`` is a package that collects several modules for working with the +.. module:: http + :synopsis: HTTP status codes and messages + +.. index:: + pair: HTTP; protocol + single: HTTP; http (standard module) + +**Source code:** :source:`Lib/http/__init__.py` + +:mod:`http` is a package that collects several modules for working with the HyperText Transfer Protocol: * :mod:`http.client` is a low-level HTTP protocol client; for high-level URL @@ -9,3 +18,105 @@ HyperText Transfer Protocol: * :mod:`http.server` contains basic HTTP server classes based on :mod:`socketserver` * :mod:`http.cookies` has utilities for implementing state management with cookies * :mod:`http.cookiejar` provides persistence of cookies + +:mod:`http` is also a module that defines a number of HTTP status codes and +associated messages through the :class:`http.HTTPStatus` enum: + +.. class:: HTTPStatus + + .. versionadded:: 3.5 + + A subclass of :class:`enum.IntEnum` that defines a set of HTTP status codes, + reason phrases and long descriptions written in English. + + Usage:: + + >>> from http import HTTPStatus + >>> HTTPStatus.OK + <HTTPStatus.OK: 200> + >>> HTTPStatus.OK == 200 + True + >>> http.HTTPStatus.OK.value + 200 + >>> HTTPStatus.OK.phrase + 'OK' + >>> HTTPStatus.OK.description + 'Request fulfilled, document follows' + >>> list(HTTPStatus) + [<HTTPStatus.CONTINUE: 100>, <HTTPStatus.SWITCHING_PROTOCOLS: 101>, ...] + +.. _http-status-codes: + +HTTP status codes +----------------- + +Supported, +`IANA-registered <http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml>`_ +status codes available in :class:`http.HTTPStatus` are: + +======= =================================== ================================================================== +Code Enum Name Details +======= =================================== ================================================================== +``100`` ``CONTINUE`` HTTP/1.1 :rfc:`7231`, Section 6.2.1 +``101`` ``SWITCHING_PROTOCOLS`` HTTP/1.1 :rfc:`7231`, Section 6.2.2 +``102`` ``PROCESSING`` WebDAV :rfc:`2518`, Section 10.1 +``200`` ``OK`` HTTP/1.1 :rfc:`7231`, Section 6.3.1 +``201`` ``CREATED`` HTTP/1.1 :rfc:`7231`, Section 6.3.2 +``202`` ``ACCEPTED`` HTTP/1.1 :rfc:`7231`, Section 6.3.3 +``203`` ``NON_AUTHORITATIVE_INFORMATION`` HTTP/1.1 :rfc:`7231`, Section 6.3.4 +``204`` ``NO_CONTENT`` HTTP/1.1 :rfc:`7231`, Section 6.3.5 +``205`` ``RESET_CONTENT`` HTTP/1.1 :rfc:`7231`, Section 6.3.6 +``206`` ``PARTIAL_CONTENT`` HTTP/1.1 :rfc:`7233`, Section 4.1 +``207`` ``MULTI_STATUS`` WebDAV :rfc:`4918`, Section 11.1 +``208`` ``ALREADY_REPORTED`` WebDAV Binding Extensions :rfc:`5842`, Section 7.1 (Experimental) +``226`` ``IM_USED`` Delta Encoding in HTTP :rfc:`3229`, Section 10.4.1 +``300`` ``MULTIPLE_CHOICES`` HTTP/1.1 :rfc:`7231`, Section 6.4.1 +``301`` ``MOVED_PERMANENTLY`` HTTP/1.1 :rfc:`7231`, Section 6.4.2 +``302`` ``FOUND`` HTTP/1.1 :rfc:`7231`, Section 6.4.3 +``303`` ``SEE_OTHER`` HTTP/1.1 :rfc:`7231`, Section 6.4.4 +``304`` ``NOT_MODIFIED`` HTTP/1.1 :rfc:`7232`, Section 4.1 +``305`` ``USE_PROXY`` HTTP/1.1 :rfc:`7231`, Section 6.4.5 +``307`` ``TEMPORARY_REDIRECT`` HTTP/1.1 :rfc:`7231`, Section 6.4.7 +``308`` ``PERMANENT_REDIRECT`` Permanent Redirect :rfc:`7238`, Section 3 (Experimental) +``400`` ``BAD_REQUEST`` HTTP/1.1 :rfc:`7231`, Section 6.5.1 +``401`` ``UNAUTHORIZED`` HTTP/1.1 Authentication :rfc:`7235`, Section 3.1 +``402`` ``PAYMENT_REQUIRED`` HTTP/1.1 :rfc:`7231`, Section 6.5.2 +``403`` ``FORBIDDEN`` HTTP/1.1 :rfc:`7231`, Section 6.5.3 +``404`` ``NOT_FOUND`` HTTP/1.1 :rfc:`7231`, Section 6.5.4 +``405`` ``METHOD_NOT_ALLOWED`` HTTP/1.1 :rfc:`7231`, Section 6.5.5 +``406`` ``NOT_ACCEPTABLE`` HTTP/1.1 :rfc:`7231`, Section 6.5.6 +``407`` ``PROXY_AUTHENTICATION_REQUIRED`` HTTP/1.1 Authentication :rfc:`7235`, Section 3.2 +``408`` ``REQUEST_TIMEOUT`` HTTP/1.1 :rfc:`7231`, Section 6.5.7 +``409`` ``CONFLICT`` HTTP/1.1 :rfc:`7231`, Section 6.5.8 +``410`` ``GONE`` HTTP/1.1 :rfc:`7231`, Section 6.5.9 +``411`` ``LENGTH_REQUIRED`` HTTP/1.1 :rfc:`7231`, Section 6.5.10 +``412`` ``PRECONDITION_FAILED`` HTTP/1.1 :rfc:`7232`, Section 4.2 +``413`` ``REQUEST_ENTITY_TOO_LARGE`` HTTP/1.1 :rfc:`7231`, Section 6.5.11 +``414`` ``REQUEST_URI_TOO_LONG`` HTTP/1.1 :rfc:`7231`, Section 6.5.12 +``415`` ``UNSUPPORTED_MEDIA_TYPE`` HTTP/1.1 :rfc:`7231`, Section 6.5.13 +``416`` ``REQUEST_RANGE_NOT_SATISFIABLE`` HTTP/1.1 Range Requests :rfc:`7233`, Section 4.4 +``417`` ``EXPECTATION_FAILED`` HTTP/1.1 :rfc:`7231`, Section 6.5.14 +``422`` ``UNPROCESSABLE_ENTITY`` WebDAV :rfc:`4918`, Section 11.2 +``423`` ``LOCKED`` WebDAV :rfc:`4918`, Section 11.3 +``424`` ``FAILED_DEPENDENCY`` WebDAV :rfc:`4918`, Section 11.4 +``426`` ``UPGRADE_REQUIRED`` HTTP/1.1 :rfc:`7231`, Section 6.5.15 +``428`` ``PRECONDITION_REQUIRED`` Additional HTTP Status Codes :rfc:`6585` +``429`` ``TOO_MANY_REQUESTS`` Additional HTTP Status Codes :rfc:`6585` +``431`` ``REQUEST_HEADER_FIELDS_TOO_LARGE`` Additional HTTP Status Codes :rfc:`6585` +``500`` ``INTERNAL_SERVER_ERROR`` HTTP/1.1 :rfc:`7231`, Section 6.6.1 +``501`` ``NOT_IMPLEMENTED`` HTTP/1.1 :rfc:`7231`, Section 6.6.2 +``502`` ``BAD_GATEWAY`` HTTP/1.1 :rfc:`7231`, Section 6.6.3 +``503`` ``SERVICE_UNAVAILABLE`` HTTP/1.1 :rfc:`7231`, Section 6.6.4 +``504`` ``GATEWAY_TIMEOUT`` HTTP/1.1 :rfc:`7231`, Section 6.6.5 +``505`` ``HTTP_VERSION_NOT_SUPPORTED`` HTTP/1.1 :rfc:`7231`, Section 6.6.6 +``506`` ``VARIANT_ALSO_NEGOTIATES`` Transparent Content Negotiation in HTTP :rfc:`2295`, Section 8.1 (Experimental) +``507`` ``INSUFFICIENT_STORAGE`` WebDAV :rfc:`4918`, Section 11.5 +``508`` ``LOOP_DETECTED`` WebDAV Binding Extensions :rfc:`5842`, Section 7.2 (Experimental) +``510`` ``NOT_EXTENDED`` An HTTP Extension Framework :rfc:`2774`, Section 7 (Experimental) +``511`` ``NETWORK_AUTHENTICATION_REQUIRED`` Additional HTTP Status Codes :rfc:`6585`, Section 6 +======= =================================== ================================================================== + +In order to preserve backwards compatibility, enum values are also present +in the :mod:`http.client` module in the form of constants. The enum name is +equal to the constant name (i.e. ``http.HTTPStatus.OK`` is also available as +``http.client.OK``). diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst index 113ac4454e0d..1c3e20260936 100644 --- a/Doc/library/http.server.rst +++ b/Doc/library/http.server.rst @@ -64,6 +64,18 @@ of which this module provides three different variants: Contains the server instance. + .. attribute:: close_connection + + Boolean that should be set before :meth:`handle_one_request` returns, + indicating if another request may be expected, or if the connection should + be shut down. + + .. attribute:: requestline + + Contains the string representation of the HTTP request line. The + terminating CRLF is stripped. This attribute should be set by + :meth:`handle_one_request`. If no valid request line was processed, it + should be set to the empty string. .. attribute:: command @@ -81,7 +93,10 @@ of which this module provides three different variants: Holds an instance of the class specified by the :attr:`MessageClass` class variable. This instance parses and manages the headers in the HTTP - request. + request. The :func:`~http.client.parse_headers` function from + :mod:`http.client` is used to parse the headers and it requires that the + HTTP request provide a valid :rfc:`2822` style header. + .. attribute:: rfile @@ -116,7 +131,7 @@ of which this module provides three different variants: HTTP error code value. *message* should be a string containing a (detailed) error message of what occurred, and *explain* should be an explanation of the error code number. Default *message* and *explain* - values can found in the *responses* class variable. + values can found in the :attr:`responses` class variable. .. attribute:: error_content_type @@ -173,11 +188,14 @@ of which this module provides three different variants: .. method:: send_error(code, message=None, explain=None) Sends and logs a complete error reply to the client. The numeric *code* - specifies the HTTP error code, with *message* as optional, more specific - text, usually referring to short message response. The *explain* - argument can be used to send a detailed information about the error in - response content body. A complete set of headers is sent, followed by - text composed using the :attr:`error_message_format` class variable. + specifies the HTTP error code, with *message* as an optional, short, human + readable description of the error. The *explain* argument can be used to + provide more detailed information about the error; it will be formatted + using the :attr:`error_message_format` class variable and emitted, after + a complete set of headers, as the response body. The :attr:`responses` + class variable holds the default values for *message* and *explain* that + will be used if no value is provided; for unknown codes the default value + for both is the string ``???``. .. versionchanged:: 3.4 The error response includes a Content-Length header. @@ -214,7 +232,7 @@ of which this module provides three different variants: .. method:: send_response_only(code, message=None) - Sends the reponse header only, used for the purposes when ``100 + Sends the response header only, used for the purposes when ``100 Continue`` response is sent by the server to the client. The headers not buffered and sent directly the output stream.If the *message* is not specified, the HTTP message corresponding the response *code* is sent. @@ -348,7 +366,7 @@ of which this module provides three different variants: The :class:`SimpleHTTPRequestHandler` class can be used in the following manner in order to create a very basic webserver serving files relative to -the current directory. :: +the current directory:: import http.server import socketserver @@ -362,15 +380,17 @@ the current directory. :: print("serving at port", PORT) httpd.serve_forever() +.. _http-server-cli: + :mod:`http.server` can also be invoked directly using the :option:`-m` switch of the interpreter with a ``port number`` argument. Similar to -the previous example, this serves files relative to the current directory. :: +the previous example, this serves files relative to the current directory:: python -m http.server 8000 -By default, server binds itself to all interfaces. To restrict it to bind to a -particular interface only, ``--bind ADDRESS`` argument can be used. For e.g, to -restrict the server to bind only to localhost. :: +By default, server binds itself to all interfaces. The option ``-b/--bind`` +specifies a specific address to which it should bind. For example, the +following command causes the server to bind to localhost only:: python -m http.server 8000 --bind 127.0.0.1 @@ -419,7 +439,7 @@ restrict the server to bind only to localhost. :: reasons. Problems with the CGI script will be translated to error 403. :class:`CGIHTTPRequestHandler` can be enabled in the command line by passing -the ``--cgi`` option.:: +the ``--cgi`` option:: python -m http.server --cgi 8000 diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 2718cef3d5e3..4384d56814e1 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -3,162 +3,177 @@ IDLE ==== -.. moduleauthor:: Guido van Rossum <guido@Python.org> - .. index:: single: IDLE single: Python Editor single: Integrated Development Environment -IDLE is the Python IDE built with the :mod:`tkinter` GUI toolkit. +.. moduleauthor:: Guido van Rossum <guido@python.org> + +IDLE is Python's Integrated Development and Learning Environment. IDLE has the following features: * coded in 100% pure Python, using the :mod:`tkinter` GUI toolkit -* cross-platform: works on Windows, Unix, and Mac OS X +* cross-platform: works mostly the same on Windows, Unix, and Mac OS X + +* Python shell window (interactive interpreter) with colorizing + of code input, output, and error messages * multi-window text editor with multiple undo, Python colorizing, - smart indent, call tips, and many other features + smart indent, call tips, auto completion, and other features -* Python shell window (a.k.a. interactive interpreter) +* search within any window, replace within editor windows, and search + through multiple files (grep) -* debugger (not complete, but you can set breakpoints, view and step) +* debugger with persistent breakpoints, stepping, and viewing + of global and local namespaces +* configuration, browsers, and other dialogs Menus ----- -IDLE has two window types, the Shell window and the Editor window. It is -possible to have multiple editor windows simultaneously. IDLE's -menus dynamically change based on which window is currently selected. Each menu -documented below indicates which window type it is associated with. Click on -the dotted line at the top of a menu to "tear it off": a separate window -containing the menu is created (for Unix and Windows only). +IDLE has two main window types, the Shell window and the Editor window. It is +possible to have multiple editor windows simultaneously. Output windows, such +as used for Edit / Find in Files, are a subtype of edit window. They currently +have the same top menu as Editor windows but a different default title and +context menu. + +IDLE's menus dynamically change based on which window is currently selected. +Each menu documented below indicates which window type it is associated with. File menu (Shell and Editor) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -New file - Create a new file editing window +New File + Create a new file editing window. Open... - Open an existing file - -Open module... - Open an existing module (searches sys.path) + Open an existing file with an Open dialog. Recent Files - Open a list of recent files + Open a list of recent files. Click one to open it. -Class browser - Show classes and methods in current file - -Path browser - Show sys.path directories, modules, classes and methods +Open Module... + Open an existing module (searches sys.path). .. index:: single: Class browser single: Path browser +Class Browser + Show functions, classes, and methods in the current Editor file in a + tree structure. In the shell, open a module first. + +Path Browser + Show sys.path directories, modules, functions, classes and methods in a + tree structure. + Save - Save current window to the associated file (unsaved windows have a - \* before and after the window title) + Save the current window to the associated file, if there is one. Windows + that have been changed since being opened or last saved have a \* before + and after the window title. If there is no associated file, + do Save As instead. Save As... - Save current window to new file, which becomes the associated file + Save the current window with a Save As dialog. The file saved becomes the + new associated file for the window. Save Copy As... - Save current window to different file without changing the associated file + Save the current window to different file without changing the associated + file. Print Window - Print the current window + Print the current window to the default printer. Close - Close current window (asks to save if unsaved) + Close the current window (ask to save if unsaved). Exit - Close all windows and quit IDLE (asks to save if unsaved) - + Close all windows and quit IDLE (ask to save unsaved windows). Edit menu (Shell and Editor) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undo - Undo last change to current window (a maximum of 1000 changes may be undone) + Undo the last change to the current window. A maximum of 1000 changes may + be undone. Redo - Redo last undone change to current window + Redo the last undone change to the current window. Cut - Copy selection into system-wide clipboard; then delete the selection + Copy selection into the system-wide clipboard; then delete the selection. Copy - Copy selection into system-wide clipboard + Copy selection into the system-wide clipboard. Paste - Insert system-wide clipboard into window + Insert contents of the system-wide clipboard into the current window. + +The clipboard functions are also available in context menus. Select All - Select the entire contents of the edit buffer + Select the entire contents of the current window. Find... - Open a search dialog box with many options + Open a search dialog with many options -Find again - Repeat last search +Find Again + Repeat the last search, if there is one. -Find selection - Search for the string in the selection +Find Selection + Search for the currently selected string, if there is one. Find in Files... - Open a search dialog box for searching files + Open a file search dialog. Put results in an new output window. Replace... - Open a search-and-replace dialog box + Open a search-and-replace dialog. -Go to line - Ask for a line number and show that line +Go to Line + Move cursor to the line number requested and make that line visible. -Expand word - Expand the word you have typed to match another word in the same buffer; - repeat to get a different expansion +Show Completions + Open a scrollable list allowing selection of keywords and attributes. See + Completions in the Tips sections below. + +Expand Word + Expand a prefix you have typed to match a full word in the same window; + repeat to get a different expansion. Show call tip After an unclosed parenthesis for a function, open a small window with - function parameter hints + function parameter hints. Show surrounding parens - Highlight the surrounding parenthesis - -Show Completions - Open a scroll window allowing selection keywords and attributes. See - Completions below. - + Highlight the surrounding parenthesis. Format menu (Editor window only) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Indent region - Shift selected lines right by the indent width (default 4 spaces) +Indent Region + Shift selected lines right by the indent width (default 4 spaces). -Dedent region - Shift selected lines left by the indent width (default 4 spaces) +Dedent Region + Shift selected lines left by the indent width (default 4 spaces). -Comment out region - Insert ## in front of selected lines +Comment Out Region + Insert ## in front of selected lines. -Uncomment region - Remove leading # or ## from selected lines +Uncomment Region + Remove leading # or ## from selected lines. -Tabify region - Turns *leading* stretches of spaces into tabs. (Note: We recommend using +Tabify Region + Turn *leading* stretches of spaces into tabs. (Note: We recommend using 4 space blocks to indent Python code.) -Untabify region - Turn *all* tabs into the correct number of spaces +Untabify Region + Turn *all* tabs into the correct number of spaces. -Toggle tabs +Toggle Tabs Open a dialog to switch between indenting with spaces and tabs. New Indent Width @@ -166,82 +181,99 @@ New Indent Width community is 4 spaces. Format Paragraph - Reformat the current blank-line-separated paragraph. All lines in the - paragraph will be formatted to less than 80 columns. + Reformat the current blank-line-delimited paragraph in comment block or + multiline string or selected line in a string. All lines in the + paragraph will be formatted to less than N columns, where N defaults to 72. Strip trailing whitespace - Removes any space characters after the end of the last non-space character + Remove any space characters after the last non-space character of a line. .. index:: - single: Import module single: Run script - Run menu (Editor window only) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Python Shell - Open or wake up the Python Shell window + Open or wake up the Python Shell window. -Check module +Check Module Check the syntax of the module currently open in the Editor window. If the - module has not been saved IDLE will prompt the user to save the code. - -Run module - Restart the shell to clean the environment, then execute the currently - open module. If the module has not been saved IDLE will prompt the user - to save the code. + module has not been saved IDLE will either prompt the user to save or + autosave, as selected in the General tab of the Idle Settings dialog. If + there is a syntax error, the approximate location is indicated in the + Editor window. + +Run Module + Do Check Module (above). If no error, restart the shell to clean the + environment, then execute the module. Output is displayed in the Shell + window. Note that output requires use of ``print`` or ``write``. + When execution is complete, the Shell retains focus and displays a prompt. + At this point, one may interactively explore the result of execution. + This is similar to executing a file with ``python -i file`` at a command + line. Shell menu (Shell window only) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ View Last Restart - Scroll the shell window to the last Shell restart + Scroll the shell window to the last Shell restart. Restart Shell - Restart the shell to clean the environment + Restart the shell to clean the environment. Debug menu (Shell window only) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Go to file/line - Look around the insert point for a filename and line number, open the file, - and show the line. Useful to view the source lines referenced in an - exception traceback. Available in the context menu of the Shell window. +Go to File/Line + Look on the current line. with the cursor, and the line above for a filename + and line number. If found, open the file if not already open, and show the + line. Use this to view source lines referenced in an exception traceback + and lines found by Find in Files. Also available in the context menu of + the Shell window and Output windows. + +.. index:: + single: debugger + single: stack viewer Debugger (toggle) - This feature is not complete and considered experimental. Run commands in - the shell under the debugger + When actived, code entered in the Shell or run from an Editor will run + under the debugger. In the Editor, breakpoints can be set with the context + menu. This feature is still incomplete and somewhat experimental. -Stack viewer - Show the stack traceback of the last exception +Stack Viewer + Show the stack traceback of the last exception in a tree widget, with + access to locals and globals. Auto-open Stack Viewer - Toggle automatically opening the stack viewer on unhandled exception - -.. index:: - single: stack viewer - single: debugger + Toggle automatically opening the stack viewer on an unhandled exception. Options menu (Shell and Editor) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Configure IDLE - Open a configuration dialog. Fonts, indentation, keybindings, and color - themes may be altered. Startup Preferences may be set, and additional - help sources can be specified. + Open a configuration dialog and change preferences for the following: + fonts, indentation, keybindings, text color themes, startup windows and + size, additional help sources, and extensions (see below). On OS X, + open the configuration dialog by selecting Preferences in the application + menu. To use a new built-in color theme (IDLE Dark) with older IDLEs, + save it as a new custom theme. + + Non-default user settings are saved in a .idlerc directory in the user's + home directory. Problems caused by bad user configuration files are solved + by editing or deleting one or more of the files in .idlerc. Code Context (toggle)(Editor Window only) Open a pane at the top of the edit window which shows the block context - of the section of code which is scrolling off the top of the window. + of the code which has scrolled above the top of the window. -Windows menu (Shell and Editor) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Window menu (Shell and Editor) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Zoom Height - Toggles the window between normal size (40x80 initial setting) and maximum - height. The initial size is in the Configure IDLE dialog under the general - tab. + Toggles the window between normal size and maximum height. The initial size + defaults to 40 lines by 80 chars unless changed on the General tab of the + Configure IDLE dialog. The rest of this menu lists the names of all open windows; select one to bring it to the foreground (deiconifying it if necessary). @@ -250,39 +282,22 @@ Help menu (Shell and Editor) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ About IDLE - Version, copyright, license, credits + Display version, copyright, license, credits, and more. IDLE Help Display a help file for IDLE detailing the menu options, basic editing and navigation, and other tips. Python Docs - Access local Python documentation, if installed. Or will start a web browser + Access local Python documentation, if installed, or start a web browser and open docs.python.org showing the latest Python documentation. +Turtle Demo + Run the turtledemo module with example python code and turtle drawings. + Additional help sources may be added here with the Configure IDLE dialog under the General tab. -Editor Window context menu -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -* Right-click in Editor window (Control-click on OS X) - -Cut - Copy selection into system-wide clipboard; then delete selection - -Copy - Copy selection into system-wide clipboard - -Paste - Insert system-wide clipboard into window - -Set Breakpoint - Sets a breakpoint. Breakpoints are only enabled when the debugger is open. - -Clear Breakpoint - Clears the breakpoint on that line. - .. index:: single: Cut single: Copy @@ -291,20 +306,32 @@ Clear Breakpoint single: Clear Breakpoint single: breakpoints +Context Menus +^^^^^^^^^^^^^^^^^^^^^^^^^^ -Shell Window context menu -^^^^^^^^^^^^^^^^^^^^^^^^^ - -* Right-click in Python Shell window (Control-click on OS X) +Open a context menu by right-clicking in a window (Control-click on OS X). +Context menus have the standard clipboard functions also on the Edit menu. Cut - Copy selection into system-wide clipboard; then delete selection + Copy selection into the system-wide clipboard; then delete the selection. Copy - Copy selection into system-wide clipboard + Copy selection into the system-wide clipboard. Paste - Insert system-wide clipboard into window + Insert contents of the system-wide clipboard into the current window. + +Editor windows also have breakpoint functions. Lines with a breakpoint set are +specially marked. Breakpoints only have an effect when running under the +debugger. Breakpoints for a file are saved in the user's .idlerc directory. + +Set Breakpoint + Set a breakpoint on the current line. + +Clear Breakpoint + Clear the breakpoint on that line. + +Shell and Output windows have the following. Go to file/line Same as in Debug menu. @@ -313,6 +340,9 @@ Go to file/line Editing and navigation ---------------------- +In this section, 'C' refers to the :kbd:`Control` key on Windows and Unix and +the :kbd:`Command` key on Mac OSX. + * :kbd:`Backspace` deletes to the left; :kbd:`Del` deletes to the right * :kbd:`C-Backspace` delete word left; :kbd:`C-Del` delete word to the right @@ -404,9 +434,35 @@ Note that IDLE itself places quite a few modules in sys.modules, so much can be found by default, e.g. the re module. If you don't like the ACW popping up unbidden, simply make the delay -longer or disable the extension. Or another option is the delay could -be set to zero. Another alternative to preventing ACW popups is to -disable the call tips extension. +longer or disable the extension. + +Calltips +^^^^^^^^ + +A calltip is shown when one types :kbd:`(` after the name of an *acccessible* +function. A name expression may include dots and subscripts. A calltip +remains until it is clicked, the cursor is moved out of the argument area, +or :kbd:`)` is typed. When the cursor is in the argument part of a definition, +the menu or shortcut display a calltip. + +A calltip consists of the function signature and the first line of the +docstring. For builtins without an accessible signature, the calltip +consists of all lines up the fifth line or the first blank line. These +details may change. + +The set of *accessible* functions depends on what modules have been imported +into the user process, including those imported by Idle itself, +and what definitions have been run, all since the last restart. + +For example, restart the Shell and enter ``itertools.count(``. A calltip +appears because Idle imports itertools into the user process for its own use. +(This could change.) Enter ``turtle.write(`` and nothing appears. Idle does +not import turtle. The menu or shortcut do nothing either. Enter +``import turtle`` and then ``turtle.write(`` will work. + +In an editor, import statements have no effect until one runs the file. One +might want to run a file after writing the import statements at the top, +or immediately run an existing file before editing. Python Shell window ^^^^^^^^^^^^^^^^^^^ @@ -414,7 +470,6 @@ Python Shell window * :kbd:`C-c` interrupts executing command * :kbd:`C-d` sends end-of-file; closes window if typed at a ``>>>`` prompt - (this is :kbd:`C-z` on Windows). * :kbd:`Alt-/` (Expand word) is also useful to reduce typing @@ -428,42 +483,24 @@ Python Shell window * :kbd:`Return` while on any previous command retrieves that command -Syntax colors -------------- - -The coloring is applied in a background "thread," so you may occasionally see -uncolorized text. To change the color scheme, edit the ``[Colors]`` section in -:file:`config.txt`. - -Python syntax colors: - Keywords - orange - - Strings - green - - Comments - red - - Definitions - blue - -Shell colors: - Console output - brown - - stdout - blue +Text colors +^^^^^^^^^^^ - stderr - dark green +Idle defaults to black on white text, but colors text with special meanings. +For the shell, these are shell output, shell error, user output, and +user error. For Python code, at the shell prompt or in an editor, these are +keywords, builtin class and function names, names following ``class`` and +``def``, strings, and comments. For any text window, these are the cursor (when +present), found text (when possible), and selected text. - stdin - black +Text coloring is done in the background, so uncolorized text is occasionally +visible. To change the color scheme, use the Configure IDLE dialog +Highlighting tab. The marking of debugger breakpoint lines in the editor and +text in popups and dialogs is not user-configurable. -Startup -------- +Startup and code execution +-------------------------- Upon startup with the ``-s`` option, IDLE will execute the file referenced by the environment variables :envvar:`IDLESTARTUP` or :envvar:`PYTHONSTARTUP`. @@ -476,8 +513,8 @@ shell, or for executing import statements to import common modules. In addition, ``Tk`` also loads a startup file if it is present. Note that the Tk file is loaded unconditionally. This additional file is ``.Idle.py`` and is looked for in the user's home directory. Statements in this file will be -executed in the Tk namespace, so this file is not useful for importing functions -to be used from IDLE's Python shell. +executed in the Tk namespace, so this file is not useful for importing +functions to be used from IDLE's Python shell. Command line usage @@ -485,31 +522,79 @@ Command line usage :: - idle.py [-c command] [-d] [-e] [-s] [-t title] [arg] ... + idle.py [-c command] [-d] [-e] [-h] [-i] [-r file] [-s] [-t title] [-] [arg] ... - -c command run this command - -d enable debugger - -e edit mode; arguments are files to be edited - -s run $IDLESTARTUP or $PYTHONSTARTUP first + -c command run command in the shell window + -d enable debugger and open shell window + -e open editor window + -h print help message with legal combinatios and exit + -i open shell window + -r file run file in shell window + -s run $IDLESTARTUP or $PYTHONSTARTUP first, in shell window -t title set title of shell window + - run stdin in shell (- must be last option before args) If there are arguments: -#. If ``-e`` is used, arguments are files opened for editing and - ``sys.argv`` reflects the arguments passed to IDLE itself. +* If ``-``, ``-c``, or ``r`` is used, all arguments are placed in + ``sys.argv[1:...]`` and ``sys.argv[0]`` is set to ``''``, ``'-c'``, + or ``'-r'``. No editor window is opened, even if that is the default + set in the Options dialog. + +* Otherwise, arguments are files opened for editing and + ``sys.argv`` reflects the arguments passed to IDLE itself. + -#. Otherwise, if ``-c`` is used, all arguments are placed in - ``sys.argv[1:...]``, with ``sys.argv[0]`` set to ``'-c'``. +IDLE-console differences +^^^^^^^^^^^^^^^^^^^^^^^^ -#. Otherwise, if neither ``-e`` nor ``-c`` is used, the first - argument is a script which is executed with the remaining arguments in - ``sys.argv[1:...]`` and ``sys.argv[0]`` set to the script name. If the script - name is '-', no script is executed but an interactive Python session is started; - the arguments are still available in ``sys.argv``. +As much as possible, the result of executing Python code with IDLE is the +same as executing the same code in a console window. However, the different +interface and operation occasionally affects results. +For instance, IDLE normally executes user code in a separate process from +the IDLE GUI itself. The IDLE versions of sys.stdin, .stdout, and .stderr in the +execution process get input from and send output to the GUI process, +which keeps control of the keyboard and screen. This is normally transparent, +but code that access these object will see different attribute values. +Also, functions that directly access the keyboard and screen will not work. + +With IDLE's Shell, one enters, edits, and recalls complete statements. +Some consoles only work with a single physical line at a time. + +Running without a subprocess +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +By default, IDLE executes user code in a separate subprocess via a socket, +which uses the internal loopback interface. This connection is not +externally visible and no data is sent to or received from the Internet. +If firewall software complains anyway, you can ignore it. + +If the attempt to make the socket connection fails, Idle will notify you. +Such failures are sometimes transient, but if persistent, the problem +may be either a firewall blocking the connecton or misconfiguration of +a particular system. Until the problem is fixed, one can run Idle with +the -n command line switch. + +If IDLE is started with the -n command line switch it will run in a +single process and will not create the subprocess which runs the RPC +Python execution server. This can be useful if Python cannot create +the subprocess or the RPC socket interface on your platform. However, +in this mode user code is not isolated from IDLE itself. Also, the +environment is not restarted when Run/Run Module (F5) is selected. If +your code has been modified, you must reload() the affected modules and +re-import any specific items (e.g. from foo import baz) if the changes +are to take effect. For these reasons, it is preferable to run IDLE +with the default subprocess if at all possible. + +.. deprecated:: 3.4 + + +Help and preferences +-------------------- Additional help sources ------------------------ +^^^^^^^^^^^^^^^^^^^^^^^ IDLE includes a help menu entry called "Python Docs" that will open the extensive sources of help, including tutorials, available at docs.python.org. @@ -518,21 +603,22 @@ Configure IDLE dialog. See the IDLE help option in the help menu of IDLE for more information. -Other preferences ------------------ +Setting preferences +^^^^^^^^^^^^^^^^^^^ The font preferences, highlighting, keys, and general preferences can be -changed via the Configure IDLE menu option. Be sure to note that -keys can be user defined, IDLE ships with four built in key sets. In -addition a user can create a custom key set in the Configure IDLE dialog -under the keys tab. +changed via Configure IDLE on the Option menu. Keys can be user defined; +IDLE ships with four built in key sets. In addition a user can create a +custom key set in the Configure IDLE dialog under the keys tab. + Extensions ----------- +^^^^^^^^^^ -IDLE contains an extension facility. See the beginning of -config-extensions.def in the idlelib directory for further information. The -default extensions are currently: +IDLE contains an extension facility. Peferences for extensions can be +changed with Configure Extensions. See the beginning of config-extensions.def +in the idlelib directory for further information. The default extensions +are currently: * FormatParagraph @@ -550,3 +636,4 @@ default extensions are currently: * CodeContext +* RstripExtension diff --git a/Doc/library/imaplib.rst b/Doc/library/imaplib.rst index 01236fbb8ea5..15b0932973dc 100644 --- a/Doc/library/imaplib.rst +++ b/Doc/library/imaplib.rst @@ -37,6 +37,19 @@ base class: initialized. If *host* is not specified, ``''`` (the local host) is used. If *port* is omitted, the standard IMAP4 port (143) is used. + The :class:`IMAP4` class supports the :keyword:`with` statement. When used + like this, the IMAP4 ``LOGOUT`` command is issued automatically when the + :keyword:`with` statement exits. E.g.:: + + >>> from imaplib import IMAP4 + >>> with IMAP4("domain.org") as M: + ... M.noop() + ... + ('OK', [b'Nothing Accomplished. d25if65hy903weo.87']) + + .. versionchanged:: 3.5 + Support for the :keyword:`with` statement was added. + Three exceptions are defined as attributes of the :class:`IMAP4` class: @@ -64,22 +77,31 @@ Three exceptions are defined as attributes of the :class:`IMAP4` class: There's also a subclass for secure connections: -.. class:: IMAP4_SSL(host='', port=IMAP4_SSL_PORT, keyfile=None, certfile=None, ssl_context=None) +.. class:: IMAP4_SSL(host='', port=IMAP4_SSL_PORT, keyfile=None, \ + certfile=None, ssl_context=None) This is a subclass derived from :class:`IMAP4` that connects over an SSL encrypted socket (to use this class you need a socket module that was compiled with SSL support). If *host* is not specified, ``''`` (the local host) is used. - If *port* is omitted, the standard IMAP4-over-SSL port (993) is used. *keyfile* - and *certfile* are also optional - they can contain a PEM formatted private key - and certificate chain file for the SSL connection. *ssl_context* parameter is a - :class:`ssl.SSLContext` object which allows bundling SSL configuration - options, certificates and private keys into a single (potentially long-lived) - structure. Note that the *keyfile*/*certfile* parameters are mutually exclusive with *ssl_context*, - a :class:`ValueError` is raised if *keyfile*/*certfile* is provided along with *ssl_context*. + If *port* is omitted, the standard IMAP4-over-SSL port (993) is used. + *ssl_context* is a :class:`ssl.SSLContext` object which allows bundling + SSL configuration options, certificates and private keys into a single + (potentially long-lived) structure. Please read :ref:`ssl-security` for + best practices. + + *keyfile* and *certfile* are a legacy alternative to *ssl_context* - they + can point to PEM-formatted private key and certificate chain files for + the SSL connection. Note that the *keyfile*/*certfile* parameters are + mutually exclusive with *ssl_context*, a :class:`ValueError` is raised + if *keyfile*/*certfile* is provided along with *ssl_context*. .. versionchanged:: 3.3 *ssl_context* parameter added. + .. versionchanged:: 3.4 + The class now supports hostname check with + :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see + :data:`ssl.HAS_SNI`). The second subclass allows for connections created by a child process: @@ -190,6 +212,10 @@ An :class:`IMAP4` instance has the following methods: that will be base64 encoded and sent to the server. It should return ``None`` if the client abort response ``*`` should be sent instead. + .. versionchanged:: 3.5 + string usernames and passwords are now encoded to ``utf-8`` instead of + being limited to ASCII. + .. method:: IMAP4.check() @@ -222,6 +248,16 @@ An :class:`IMAP4` instance has the following methods: Delete the ACLs (remove any rights) set for who on mailbox. +.. method:: IMAP4.enable(capability) + + Enable *capability* (see :rfc:`5161`). Most capabilities do not need to be + enabled. Currently only the ``UTF8=ACCEPT`` capability is supported + (see :RFC:`6855`). + + .. versionadded:: 3.5 + The :meth:`enable` method itself, and :RFC:`6855` support. + + .. method:: IMAP4.expunge() Permanently remove deleted items from selected mailbox. Generates an ``EXPUNGE`` @@ -359,7 +395,9 @@ An :class:`IMAP4` instance has the following methods: Search mailbox for matching messages. *charset* may be ``None``, in which case no ``CHARSET`` will be specified in the request to the server. The IMAP protocol requires that at least one criterion be specified; an exception will be - raised when the server returns an error. + raised when the server returns an error. *charset* must be ``None`` if + the ``UTF8=ACCEPT`` capability was enabled using the :meth:`enable` + command. Example:: @@ -433,10 +471,16 @@ An :class:`IMAP4` instance has the following methods: Send a ``STARTTLS`` command. The *ssl_context* argument is optional and should be a :class:`ssl.SSLContext` object. This will enable - encryption on the IMAP connection. + encryption on the IMAP connection. Please read :ref:`ssl-security` for + best practices. .. versionadded:: 3.2 + .. versionchanged:: 3.4 + The method now supports hostname check with + :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see + :data:`ssl.HAS_SNI`). + .. method:: IMAP4.status(mailbox, names) @@ -515,6 +559,15 @@ The following attributes are defined on instances of :class:`IMAP4`: the module variable ``Debug``. Values greater than three trace each command. +.. attribute:: IMAP4.utf8_enabled + + Boolean value that is normally ``False``, but is set to ``True`` if an + :meth:`enable` command is successfully issued for the ``UTF8=ACCEPT`` + capability. + + .. versionadded:: 3.5 + + .. _imap4-example: IMAP4 Example diff --git a/Doc/library/imghdr.rst b/Doc/library/imghdr.rst index 9e8952339cca..f11f6dcf8e67 100644 --- a/Doc/library/imghdr.rst +++ b/Doc/library/imghdr.rst @@ -48,6 +48,14 @@ from :func:`what`: +------------+-----------------------------------+ | ``'png'`` | Portable Network Graphics | +------------+-----------------------------------+ +| ``'webp'`` | WebP files | ++------------+-----------------------------------+ +| ``'exr'`` | OpenEXR Files | ++------------+-----------------------------------+ + +.. versionadded:: 3.5 + The *exr* and *webp* formats were added. + You can extend the list of file types :mod:`imghdr` can recognize by appending to this variable: diff --git a/Doc/library/imp.rst b/Doc/library/imp.rst index ee02c3f29f63..68a6b681ef54 100644 --- a/Doc/library/imp.rst +++ b/Doc/library/imp.rst @@ -1,12 +1,12 @@ :mod:`imp` --- Access the :ref:`import <importsystem>` internals ================================================================ -.. deprecated:: 3.4 - The :mod:`imp` package is pending deprecation in favor of :mod:`importlib`. - .. module:: imp :synopsis: Access the implementation of the import statement. + :deprecated: +.. deprecated:: 3.4 + The :mod:`imp` package is pending deprecation in favor of :mod:`importlib`. .. index:: statement: import @@ -79,7 +79,9 @@ This module provides an interface to the mechanisms used to implement the When *P* itself has a dotted name, apply this recipe recursively. .. deprecated:: 3.3 - Use :func:`importlib.find_loader` instead. + Use :func:`importlib.util.find_spec` instead unless Python 3.3 + compatibility is required, in which case use + :func:`importlib.find_loader`. .. function:: load_module(name, file, pathname, description) @@ -104,9 +106,11 @@ This module provides an interface to the mechanisms used to implement the .. deprecated:: 3.3 If previously used in conjunction with :func:`imp.find_module` then - call ``load_module()`` on the returned loader. If you wish to load a - module from a specific file, then use one of the file-based loaders found - in :mod:`importlib.machinery`. + consider using :func:`importlib.import_module`, otherwise use the loader + returned by the replacement you chose for :func:`imp.find_module`. If you + called :func:`imp.load_module` and related functions directly then use the + classes in :mod:`importlib.machinery`, e.g. + ``importlib.machinery.SourceFileLoader(name, path).load_module()``. .. function:: new_module(name) @@ -145,12 +149,6 @@ This module provides an interface to the mechanisms used to implement the There are a number of other caveats: - If a module is syntactically correct but its initialization fails, the first - :keyword:`import` statement for it does not bind its name locally, but does - store a (partially initialized) module object in ``sys.modules``. To reload the - module you must first :keyword:`import` it again (this will bind the name to the - partially initialized module object) before you can :func:`reload` it. - When a module is reloaded, its dictionary (containing the module's global variables) is retained. Redefinitions of names will override the old definitions, so this is generally not a problem. If the new version of a module @@ -199,11 +197,9 @@ file paths. value would be ``/foo/bar/__pycache__/baz.cpython-32.pyc`` for Python 3.2. The ``cpython-32`` string comes from the current magic tag (see :func:`get_tag`; if :attr:`sys.implementation.cache_tag` is not defined then - :exc:`NotImplementedError` will be raised). The returned path will end in - ``.pyc`` when ``__debug__`` is ``True`` or ``.pyo`` for an optimized Python - (i.e. ``__debug__`` is ``False``). By passing in ``True`` or ``False`` for - *debug_override* you can override the system's value for ``__debug__`` for - extension selection. + :exc:`NotImplementedError` will be raised). By passing in ``True`` or + ``False`` for *debug_override* you can override the system's value for + ``__debug__``, leading to optimized bytecode. *path* need not exist. @@ -214,6 +210,9 @@ file paths. .. deprecated:: 3.4 Use :func:`importlib.util.cache_from_source` instead. + .. versionchanged:: 3.5 + The *debug_override* parameter no longer creates a ``.pyo`` file. + .. function:: source_from_cache(path) @@ -262,12 +261,12 @@ that circular imports work without any deadlocks. exception is made for circular imports, which by construction have to expose an incomplete module object at some point. -.. versionchanged:: 3.3 - The locking scheme has changed to per-module locks for - the most part. A global import lock is kept for some critical tasks, - such as initializing the per-module locks. + .. versionchanged:: 3.3 + The locking scheme has changed to per-module locks for + the most part. A global import lock is kept for some critical tasks, + such as initializing the per-module locks. -.. deprecated:: 3.4 + .. deprecated:: 3.4 .. function:: acquire_lock() @@ -282,12 +281,12 @@ that circular imports work without any deadlocks. On platforms without threads, this function does nothing. -.. versionchanged:: 3.3 - The locking scheme has changed to per-module locks for - the most part. A global import lock is kept for some critical tasks, - such as initializing the per-module locks. + .. versionchanged:: 3.3 + The locking scheme has changed to per-module locks for + the most part. A global import lock is kept for some critical tasks, + such as initializing the per-module locks. -.. deprecated:: 3.4 + .. deprecated:: 3.4 .. function:: release_lock() @@ -295,12 +294,12 @@ that circular imports work without any deadlocks. Release the interpreter's global import lock. On platforms without threads, this function does nothing. -.. versionchanged:: 3.3 - The locking scheme has changed to per-module locks for - the most part. A global import lock is kept for some critical tasks, - such as initializing the per-module locks. + .. versionchanged:: 3.3 + The locking scheme has changed to per-module locks for + the most part. A global import lock is kept for some critical tasks, + such as initializing the per-module locks. -.. deprecated:: 3.4 + .. deprecated:: 3.4 The following constants with integer values, defined in this module, are used diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 177f15b86790..da6135345394 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -1,8 +1,8 @@ -:mod:`importlib` -- An implementation of :keyword:`import` -========================================================== +:mod:`importlib` -- The implementation of :keyword:`import` +=========================================================== .. module:: importlib - :synopsis: An implementation of the import machinery. + :synopsis: The implementation of the import machinery. .. moduleauthor:: Brett Cannon <brett@python.org> .. sectionauthor:: Brett Cannon <brett@python.org> @@ -13,24 +13,23 @@ Introduction ------------ -The purpose of the :mod:`importlib` package is two-fold. One is to provide an +The purpose of the :mod:`importlib` package is two-fold. One is to provide the implementation of the :keyword:`import` statement (and thus, by extension, the :func:`__import__` function) in Python source code. This provides an implementation of :keyword:`import` which is portable to any Python -interpreter. This also provides a reference implementation which is easier to +interpreter. This also provides an implementation which is easier to comprehend than one implemented in a programming language other than Python. Two, the components to implement :keyword:`import` are exposed in this package, making it easier for users to create their own custom objects (known generically as an :term:`importer`) to participate in the import process. -Details on custom importers can be found in :pep:`302`. .. seealso:: :ref:`import` The language reference for the :keyword:`import` statement. - `Packages specification <http://www.python.org/doc/essays/packages.html>`__ + `Packages specification <http://legacy.python.org/doc/essays/packages.html>`__ Original specification of packages. Some semantics have changed since the writing of this document (e.g. redirecting based on ``None`` in :data:`sys.modules`). @@ -53,6 +52,15 @@ Details on custom importers can be found in :pep:`302`. :pep:`366` Main module explicit relative imports + :pep:`451` + A ModuleSpec Type for the Import System + + :pep:`488` + Elimination of PYO files + + :pep:`489` + Multi-phase extension module initialization + :pep:`3120` Using UTF-8 as the Default Source Encoding @@ -67,6 +75,10 @@ Functions An implementation of the built-in :func:`__import__` function. + .. note:: + Programmatic importing of modules should use :func:`import_module` + instead of this function. + .. function:: import_module(name, package=None) Import a module. The *name* argument specifies what module to @@ -79,12 +91,18 @@ Functions The :func:`import_module` function acts as a simplifying wrapper around :func:`importlib.__import__`. This means all semantics of the function are - derived from :func:`importlib.__import__`, including requiring the package - from which an import is occurring to have been previously imported - (i.e., *package* must already be imported). The most important difference - is that :func:`import_module` returns the most nested package or module - that was imported (e.g. ``pkg.mod``), while :func:`__import__` returns the - top-level package or module (e.g. ``pkg``). + derived from :func:`importlib.__import__`. The most important difference + between these two functions is that :func:`import_module` returns the + specified package or module (e.g. ``pkg.mod``), while :func:`__import__` + returns the top-level package or module (e.g. ``pkg``). + + If you are dynamically importing a module that was created since the + interpreter began execution (e.g., created a Python source file), you may + need to call :func:`invalidate_caches` in order for the new module to be + noticed by the import system. + + .. versionchanged:: 3.3 + Parent packages are automatically imported. .. function:: find_loader(name, path=None) @@ -105,6 +123,9 @@ Functions If ``__loader__`` is not set, raise :exc:`ValueError`, just like when the attribute is set to ``None``. + .. deprecated:: 3.4 + Use :func:`importlib.util.find_spec` instead. + .. function:: invalidate_caches() Invalidate the internal caches of finders stored at @@ -126,7 +147,7 @@ Functions When :func:`reload` is executed: - * Python modules' code is recompiled and the module-level code re-executed, + * Python module's code is recompiled and the module-level code re-executed, defining a new set of objects which are bound to names in the module's dictionary by reusing the :term:`loader` which originally loaded the module. The ``init`` function of extension modules is not called a second @@ -144,12 +165,6 @@ Functions There are a number of other caveats: - If a module is syntactically correct but its initialization fails, the first - :keyword:`import` statement for it does not bind its name locally, but does - store a (partially initialized) module object in ``sys.modules``. To reload - the module you must first :keyword:`import` it again (this will bind the name - to the partially initialized module object) before you can :func:`reload` it. - When a module is reloaded, its dictionary (containing the module's global variables) is retained. Redefinitions of names will override the old definitions, so this is generally not a problem. If the new version of a @@ -164,11 +179,11 @@ Functions except NameError: cache = {} - It is legal though generally not very useful to reload built-in or - dynamically loaded modules (this is not true for e.g. :mod:`sys`, - :mod:`__main__`, :mod:`builtins` and other key modules where reloading is - frowned upon). In many cases, however, extension modules are not designed to - be initialized more than once, and may fail in arbitrary ways when reloaded. + It is generally not very useful to reload built-in or dynamically loaded + modules. Reloading :mod:`sys`, :mod:`__main__`, :mod:`builtins` and other + key modules is not recommended. In many cases extension modules are not + designed to be initialized more than once, and may fail in arbitrary ways + when reloaded. If a module imports objects from another module using :keyword:`from` ... :keyword:`import` ..., calling :func:`reload` for the other module does not @@ -233,17 +248,36 @@ ABC hierarchy:: .. versionadded:: 3.3 + .. method:: find_spec(fullname, path, target=None) + + An abstract method for finding a :term:`spec <module spec>` for + the specified module. If this is a top-level import, *path* will + be ``None``. Otherwise, this is a search for a subpackage or + module and *path* will be the value of :attr:`__path__` from the + parent package. If a spec cannot be found, ``None`` is returned. + When passed in, ``target`` is a module object that the finder may + use to make a more educated about what spec to return. + + .. versionadded:: 3.4 + .. method:: find_module(fullname, path) - An abstract method for finding a :term:`loader` for the specified + A legacy method for finding a :term:`loader` for the specified module. If this is a top-level import, *path* will be ``None``. Otherwise, this is a search for a subpackage or module and *path* will be the value of :attr:`__path__` from the parent package. If a loader cannot be found, ``None`` is returned. + If :meth:`find_spec` is defined, backwards-compatible functionality is + provided. + .. versionchanged:: 3.4 Returns ``None`` when called instead of raising - :exc:`NotImplementedError`. + :exc:`NotImplementedError`. Can use :meth:`find_spec` to provide + functionality. + + .. deprecated:: 3.4 + Use :meth:`find_spec` instead. .. method:: invalidate_caches() @@ -265,9 +299,20 @@ ABC hierarchy:: .. versionadded:: 3.3 + .. method:: find_spec(fullname, target=None) + + An abstract method for finding a :term:`spec <module spec>` for + the specified module. The finder will search for the module only + within the :term:`path entry` to which it is assigned. If a spec + cannot be found, ``None`` is returned. When passed in, ``target`` + is a module object that the finder may use to make a more educated + about what spec to return. + + .. versionadded:: 3.4 + .. method:: find_loader(fullname) - An abstract method for finding a :term:`loader` for the specified + A legacy method for finding a :term:`loader` for the specified module. Returns a 2-tuple of ``(loader, portion)`` where ``portion`` is a sequence of file system locations contributing to part of a namespace package. The loader may be ``None`` while specifying ``portion`` to @@ -277,14 +322,24 @@ ABC hierarchy:: ``portion`` is the empty list then no loader or location for a namespace package were found (i.e. failure to find anything for the module). + If :meth:`find_spec` is defined then backwards-compatible functionality is + provided. + .. versionchanged:: 3.4 Returns ``(None, [])`` instead of raising :exc:`NotImplementedError`. + Uses :meth:`find_spec` when available to provide functionality. + + .. deprecated:: 3.4 + Use :meth:`find_spec` instead. .. method:: find_module(fullname) A concrete implementation of :meth:`Finder.find_module` which is equivalent to ``self.find_loader(fullname)[0]``. + .. deprecated:: 3.4 + Use :meth:`find_spec` instead. + .. method:: invalidate_caches() An optional method which, when called, should invalidate any internal @@ -297,9 +352,29 @@ ABC hierarchy:: An abstract base class for a :term:`loader`. See :pep:`302` for the exact definition for a loader. + .. method:: create_module(spec) + + A method that returns the module object to use when + importing a module. This method may return ``None``, + indicating that default module creation semantics should take place. + + .. versionadded:: 3.4 + + .. versionchanged:: 3.5 + Starting in Python 3.6, this method will not be optional when + :meth:`exec_module` is defined. + + .. method:: exec_module(module) + + An abstract method that executes the module in its own namespace + when a module is imported or reloaded. The module should already + be initialized when exec_module() is called. + + .. versionadded:: 3.4 + .. method:: load_module(fullname) - An abstract method for loading a module. If the module cannot be + A legacy method for loading a module. If the module cannot be loaded, :exc:`ImportError` is raised, otherwise the loaded module is returned. @@ -342,13 +417,24 @@ ABC hierarchy:: :func:`importlib.util.module_for_loader` decorator can handle the details for :attr:`__package__`. + When :meth:`exec_module` is available then backwards-compatible + functionality is provided. + .. versionchanged:: 3.4 Raise :exc:`ImportError` when called instead of - :exc:`NotImplementedError`. + :exc:`NotImplementedError`. Functionality provided when + :meth:`exec_module` is available. + + .. deprecated:: 3.4 + The recommended API for loading a module is :meth:`exec_module` + (and :meth:`create_module`). Loaders should implement + it instead of load_module(). The import machinery takes care of + all the other responsibilities of load_module() when exec_module() + is implemented. .. method:: module_repr(module) - An optional method which when implemented calculates and returns the + A legacy method which when implemented calculates and returns the given module's repr, as a string. The module type's default repr() will use the result of this method as appropriate. @@ -357,6 +443,9 @@ ABC hierarchy:: .. versionchanged:: 3.4 Made optional instead of an abstractmethod. + .. deprecated:: 3.4 + The import machinery now takes care of this automatically. + .. class:: ResourceLoader @@ -370,12 +459,12 @@ ABC hierarchy:: Loaders that have a file-like storage back-end that allows storing arbitrary data can implement this abstract method to give direct access - to the data stored. :exc:`IOError` is to be raised if the *path* cannot + to the data stored. :exc:`OSError` is to be raised if the *path* cannot be found. The *path* is expected to be constructed using a module's :attr:`__file__` attribute or an item from a package's :attr:`__path__`. .. versionchanged:: 3.4 - Raises :exc:`IOError` instead of :exc:`NotImplementedError`. + Raises :exc:`OSError` instead of :exc:`NotImplementedError`. .. class:: InspectLoader @@ -385,10 +474,10 @@ ABC hierarchy:: .. method:: get_code(fullname) - Return the code object for a module. - ``None`` should be returned if the module does not have a code object - (e.g. built-in module). :exc:`ImportError` is raised if loader cannot - find the requested module. + Return the code object for a module, or ``None`` if the module does not + have a code object (as would be the case, for example, for a built-in + module). Raise an :exc:`ImportError` if loader cannot find the + requested module. .. note:: While the method has a default implementation, it is suggested that @@ -420,7 +509,7 @@ ABC hierarchy:: .. versionchanged:: 3.4 Raises :exc:`ImportError` instead of :exc:`NotImplementedError`. - .. method:: source_to_code(data, path='<string>') + .. staticmethod:: source_to_code(data, path='<string>') Create a code object from Python source. @@ -429,11 +518,26 @@ ABC hierarchy:: the "path" to where the source code originated from, which can be an abstract concept (e.g. location in a zip file). + With the subsequent code object one can execute it in a module by + running ``exec(code, module.__dict__)``. + .. versionadded:: 3.4 + .. versionchanged:: 3.5 + Made the method static. + + .. method:: exec_module(module) + + Implementation of :meth:`Loader.exec_module`. + + .. versionadded:: 3.4 + .. method:: load_module(fullname) - Implementation of :meth:`Loader.load_module`. + Implementation of :meth:`Loader.load_module`. + + .. deprecated:: 3.4 + use :meth:`exec_module` instead. .. class:: ExecutionLoader @@ -479,6 +583,9 @@ ABC hierarchy:: Calls super's ``load_module()``. + .. deprecated:: 3.4 + Use :meth:`Loader.exec_module` instead. + .. method:: get_filename(fullname) Returns :attr:`path`. @@ -518,12 +625,12 @@ ABC hierarchy:: - ``'size'`` (optional): the size in bytes of the source code. Any other keys in the dictionary are ignored, to allow for future - extensions. If the path cannot be handled, :exc:`IOError` is raised. + extensions. If the path cannot be handled, :exc:`OSError` is raised. .. versionadded:: 3.3 .. versionchanged:: 3.4 - Raise :exc:`IOError` instead of :exc:`NotImplementedError`. + Raise :exc:`OSError` instead of :exc:`NotImplementedError`. .. method:: path_mtime(path) @@ -533,10 +640,10 @@ ABC hierarchy:: .. deprecated:: 3.3 This method is deprecated in favour of :meth:`path_stats`. You don't have to implement it, but it is still available for compatibility - purposes. Raise :exc:`IOError` if the path cannot be handled. + purposes. Raise :exc:`OSError` if the path cannot be handled. - .. versionchanged:: 3.4 - Raise :exc:`IOError` instead of :exc:`NotImplementedError`. + .. versionchanged:: 3.4 + Raise :exc:`OSError` instead of :exc:`NotImplementedError`. .. method:: set_data(path, data) @@ -555,9 +662,18 @@ ABC hierarchy:: Concrete implementation of :meth:`InspectLoader.get_code`. + .. method:: exec_module(module) + + Concrete implementation of :meth:`Loader.exec_module`. + + .. versionadded:: 3.4 + .. method:: load_module(fullname) - Concrete implementation of :meth:`Loader.load_module`. + Concrete implementation of :meth:`Loader.load_module`. + + .. deprecated:: 3.4 + Use :meth:`exec_module` instead. .. method:: get_source(fullname) @@ -595,6 +711,9 @@ find and load modules. .. versionadded:: 3.3 + .. deprecated:: 3.5 + Use :attr:`BYTECODE_SUFFIXES` instead. + .. attribute:: OPTIMIZED_BYTECODE_SUFFIXES A list of strings representing the file suffixes for optimized bytecode @@ -602,14 +721,19 @@ find and load modules. .. versionadded:: 3.3 + .. deprecated:: 3.5 + Use :attr:`BYTECODE_SUFFIXES` instead. + .. attribute:: BYTECODE_SUFFIXES A list of strings representing the recognized file suffixes for bytecode - modules. Set to either :attr:`DEBUG_BYTECODE_SUFFIXES` or - :attr:`OPTIMIZED_BYTECODE_SUFFIXES` based on whether ``__debug__`` is true. + modules (including the leading dot). .. versionadded:: 3.3 + .. versionchanged:: 3.5 + The value is no longer dependent on ``__debug__``. + .. attribute:: EXTENSION_SUFFIXES A list of strings representing the recognized file suffixes for @@ -623,7 +747,7 @@ find and load modules. modules recognized by the standard import machinery. This is a helper for code which simply needs to know if a filesystem path potentially refers to a module without needing any details on the kind - of module (for example, :func:`inspect.getmodulename`) + of module (for example, :func:`inspect.getmodulename`). .. versionadded:: 3.3 @@ -638,6 +762,10 @@ find and load modules. Only class methods are defined by this class to alleviate the need for instantiation. + .. versionchanged:: 3.5 + As part of :pep:`489`, the builtin importer now implements + :meth:`Loader.create_module` and :meth:`Loader.exec_module` + .. class:: FrozenImporter @@ -668,28 +796,42 @@ find and load modules. Only class methods are defined by this class to alleviate the need for instantiation. + .. classmethod:: find_spec(fullname, path=None, target=None) + + Class method that attempts to find a :term:`spec <module spec>` + for the module specified by *fullname* on :data:`sys.path` or, if + defined, on *path*. For each path entry that is searched, + :data:`sys.path_importer_cache` is checked. If a non-false object + is found then it is used as the :term:`path entry finder` to look + for the module being searched for. If no entry is found in + :data:`sys.path_importer_cache`, then :data:`sys.path_hooks` is + searched for a finder for the path entry and, if found, is stored + in :data:`sys.path_importer_cache` along with being queried about + the module. If no finder is ever found then ``None`` is both + stored in the cache and returned. + + .. versionadded:: 3.4 + + .. versionchanged:: 3.5 + If the current working directory -- represented by an empty string -- + is no longer valid then ``None`` is returned but no value is cached + in :data:`sys.path_importer_cache`. + .. classmethod:: find_module(fullname, path=None) - Class method that attempts to find a :term:`loader` for the module - specified by *fullname* on :data:`sys.path` or, if defined, on - *path*. For each path entry that is searched, - :data:`sys.path_importer_cache` is checked. If a non-false object is - found then it is used as the :term:`path entry finder` to look for the - module being searched for. If no entry is found in - :data:`sys.path_importer_cache`, then :data:`sys.path_hooks` is - searched for a finder for the path entry and, if found, is stored in - :data:`sys.path_importer_cache` along with being queried about the - module. If no finder is ever found then ``None`` is both stored in - the cache and returned. + A legacy wrapper around :meth:`find_spec`. + + .. deprecated:: 3.4 + Use :meth:`find_spec` instead. .. classmethod:: invalidate_caches() - Calls :meth:`importlib.abc.PathEntryFinder.invalidate_caches` on all - finders stored in :attr:`sys.path_importer_cache`. + Calls :meth:`importlib.abc.PathEntryFinder.invalidate_caches` on all + finders stored in :attr:`sys.path_importer_cache`. - .. versionchanged:: 3.4 - Calls objects in :data:`sys.path_hooks` with the current working directory - for ``''`` (i.e. the empty string). + .. versionchanged:: 3.4 + Calls objects in :data:`sys.path_hooks` with the current working + directory for ``''`` (i.e. the empty string). .. class:: FileFinder(path, \*loader_details) @@ -721,6 +863,12 @@ find and load modules. The path the finder will search in. + .. method:: find_spec(fullname, target=None) + + Attempt to find the spec to handle *fullname* within :attr:`path`. + + .. versionadded:: 3.4 + .. method:: find_loader(fullname) Attempt to find the loader to handle *fullname* within :attr:`path`. @@ -768,6 +916,11 @@ find and load modules. Concrete implementation of :meth:`importlib.abc.SourceLoader.set_data`. + .. method:: load_module(name=None) + + Concrete implementation of :meth:`importlib.abc.Loader.load_module` where + specifying the name of the module to load is optional. + .. class:: SourcelessFileLoader(fullname, path) @@ -802,6 +955,11 @@ find and load modules. Returns ``None`` as bytecode files have no source when this loader is used. + .. method:: load_module(name=None) + + Concrete implementation of :meth:`importlib.abc.Loader.load_module` where + specifying the name of the module to load is optional. + .. class:: ExtensionFileLoader(fullname, path) @@ -821,10 +979,18 @@ find and load modules. Path to the extension module. - .. method:: load_module(fullname) + .. method:: create_module(spec) + + Creates the module object from the given specification in accordance + with :pep:`489`. + + .. versionadded:: 3.5 - Loads the extension module if and only if *fullname* is the same as - :attr:`name` or is ``None``. + .. method:: exec_module(module) + + Initializes the given module object in accordance with :pep:`489`. + + .. versionadded:: 3.5 .. method:: is_package(fullname) @@ -901,7 +1067,7 @@ find and load modules. .. attribute:: has_location - (Read-only) Boolean indicating whether or not the module's "origin" + Boolean indicating whether or not the module's "origin" attribute refers to a loadable location. :mod:`importlib.util` -- Utility code for importers @@ -920,23 +1086,37 @@ an :term:`importer`. .. versionadded:: 3.4 -.. function:: cache_from_source(path, debug_override=None) +.. function:: cache_from_source(path, debug_override=None, *, optimization=None) - Return the :pep:`3147` path to the byte-compiled file associated with the - source *path*. For example, if *path* is ``/foo/bar/baz.py`` the return + Return the :pep:`3147`/:pep:`488` path to the byte-compiled file associated + with the source *path*. For example, if *path* is ``/foo/bar/baz.py`` the return value would be ``/foo/bar/__pycache__/baz.cpython-32.pyc`` for Python 3.2. The ``cpython-32`` string comes from the current magic tag (see :func:`get_tag`; if :attr:`sys.implementation.cache_tag` is not defined then - :exc:`NotImplementedError` will be raised). The returned path will end in - ``.pyc`` when ``__debug__`` is ``True`` or ``.pyo`` for an optimized Python - (i.e. ``__debug__`` is ``False``). By passing in ``True`` or ``False`` for - *debug_override* you can override the system's value for ``__debug__`` for - extension selection. - - *path* need not exist. + :exc:`NotImplementedError` will be raised). + + The *optimization* parameter is used to specify the optimization level of the + bytecode file. An empty string represents no optimization, so + ``/foo/bar/baz.py`` with an *optimization* of ``''`` will result in a + bytecode path of ``/foo/bar/__pycache__/baz.cpython-32.pyc``. ``None`` causes + the interpter's optimization level to be used. Any other value's string + representation being used, so ``/foo/bar/baz.py`` with an *optimization* of + ``2`` will lead to the bytecode path of + ``/foo/bar/__pycache__/baz.cpython-32.opt-2.pyc``. The string representation + of *optimization* can only be alphanumeric, else :exc:`ValueError` is raised. + + The *debug_override* parameter is deprecated and can be used to override + the system's value for ``__debug__``. A ``True`` value is the equivalent of + setting *optimization* to the empty string. A ``False`` value is the same as + setting *optimization* to ``1``. If both *debug_override* an *optimization* + are not ``None`` then :exc:`TypeError` is raised. .. versionadded:: 3.4 + .. versionchanged ::3.5 + The *optimization* parameter was added and the *debug_override* parameter + was deprecated. + .. function:: source_from_cache(path) @@ -944,7 +1124,7 @@ an :term:`importer`. file path. For example, if *path* is ``/foo/bar/__pycache__/baz.cpython-32.pyc`` the returned path would be ``/foo/bar/baz.py``. *path* need not exist, however if it does not conform - to :pep:`3147` format, a ``ValueError`` is raised. If + to :pep:`3147` or :pep:`488` format, a ``ValueError`` is raised. If :attr:`sys.implementation.cache_tag` is not defined, :exc:`NotImplementedError` is raised. @@ -974,6 +1154,37 @@ an :term:`importer`. .. versionadded:: 3.3 +.. function:: find_spec(name, package=None) + + Find the :term:`spec <module spec>` for a module, optionally relative to + the specified **package** name. If the module is in :attr:`sys.modules`, + then ``sys.modules[name].__spec__`` is returned (unless the spec would be + ``None`` or is not set, in which case :exc:`ValueError` is raised). + Otherwise a search using :attr:`sys.meta_path` is done. ``None`` is + returned if no spec is found. + + If **name** is for a submodule (contains a dot), the parent module is + automatically imported. + + **name** and **package** work the same as for :func:`import_module`. + + .. versionadded:: 3.4 + +.. function:: module_from_spec(spec) + + Create a new module based on **spec** and ``spec.loader.create_module()``. + + If ``spec.loader.create_module()`` does not return ``None``, then any + pre-existing attributes will not be reset. Also, no :exc:`AttributeError` + will be raised if triggered while accessing **spec** or setting an attribute + on the module. + + This function is preferred over using :class:`types.ModuleType` to create a + new module as **spec** is used to set as many import-controlled attributes on + the module as possible. + + .. versionadded:: 3.5 + .. decorator:: module_for_loader A :term:`decorator` for :meth:`importlib.abc.Loader.load_module` @@ -1023,11 +1234,17 @@ an :term:`importer`. Set ``__loader__`` if set to ``None``, as if the attribute does not exist. + .. deprecated:: 3.4 + The import machinery takes care of this automatically. + .. decorator:: set_package A :term:`decorator` for :meth:`importlib.abc.Loader.load_module` to set the :attr:`__package__` attribute on the returned module. If :attr:`__package__` is set and has a value other than ``None`` it will not be changed. + .. deprecated:: 3.4 + The import machinery takes care of this automatically. + .. function:: spec_from_loader(name, loader, *, origin=None, is_package=None) A factory function for creating a :class:`ModuleSpec` instance based @@ -1046,3 +1263,39 @@ an :term:`importer`. module will be file-based. .. versionadded:: 3.4 + +.. class:: LazyLoader(loader) + + A class which postpones the execution of the loader of a module until the + module has an attribute accessed. + + This class **only** works with loaders that define + :meth:`~importlib.abc.Loader.exec_module` as control over what module type + is used for the module is required. For those same reasons, the loader's + :meth:`~importlib.abc.Loader.create_module` method will be ignored (i.e., the + loader's method should only return ``None``). Finally, + modules which substitute the object placed into :attr:`sys.modules` will + not work as there is no way to properly replace the module references + throughout the interpreter safely; :exc:`ValueError` is raised if such a + substitution is detected. + + .. note:: + For projects where startup time is critical, this class allows for + potentially minimizing the cost of loading a module if it is never used. + For projects where startup time is not essential then use of this class is + **heavily** discouraged due to error messages created during loading being + postponed and thus occurring out of context. + + .. versionadded:: 3.5 + + .. classmethod:: factory(loader) + + A static method which returns a callable that creates a lazy loader. This + is meant to be used in situations where the loader is passed by class + instead of by instance. + :: + + suffixes = importlib.machinery.SOURCE_SUFFIXES + loader = importlib.machinery.SourceFileLoader + lazy_loader = importlib.util.LazyLoader.factory(loader) + finder = importlib.machinery.FileFinder(path, [(lazy_loader, suffixes)]) diff --git a/Doc/library/index.rst b/Doc/library/index.rst index 81289a56c518..a925e10ee498 100644 --- a/Doc/library/index.rst +++ b/Doc/library/index.rst @@ -20,7 +20,7 @@ everyday programming. Some of these modules are explicitly designed to encourage and enhance the portability of Python programs by abstracting away platform-specifics into platform-neutral APIs. -The Python installers for the Windows platform usually includes +The Python installers for the Windows platform usually include the entire standard library and often also include many additional components. For Unix-like operating systems Python is normally provided as a collection of packages, so it may be necessary to use the packaging @@ -30,7 +30,7 @@ optional components. In addition to the standard library, there is a growing collection of several thousand components (from individual programs and modules to packages and entire application development frameworks), available from -the `Python Package Index <http://pypi.python.org/pypi>`_. +the `Python Package Index <https://pypi.python.org/pypi>`_. .. toctree:: @@ -73,4 +73,5 @@ the `Python Package Index <http://pypi.python.org/pypi>`_. misc.rst windows.rst unix.rst + superseded.rst undoc.rst diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 41c61b79374d..af0422f3e101 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -28,7 +28,7 @@ Types and members ----------------- The :func:`getmembers` function retrieves the members of an object such as a -class or module. The sixteen functions whose names begin with "is" are mainly +class or module. The functions whose names begin with "is" are mainly provided as convenient choices for the second argument to :func:`getmembers`. They also help you determine when you can expect to find the following special attributes: @@ -43,6 +43,11 @@ attributes: +-----------+-----------------+---------------------------+ | class | __doc__ | documentation string | +-----------+-----------------+---------------------------+ +| | __name__ | name with which this | +| | | class was defined | ++-----------+-----------------+---------------------------+ +| | __qualname__ | qualified name | ++-----------+-----------------+---------------------------+ | | __module__ | name of module in which | | | | this class was defined | +-----------+-----------------+---------------------------+ @@ -51,6 +56,8 @@ attributes: | | __name__ | name with which this | | | | method was defined | +-----------+-----------------+---------------------------+ +| | __qualname__ | qualified name | ++-----------+-----------------+---------------------------+ | | __func__ | function object | | | | containing implementation | | | | of method | @@ -64,12 +71,19 @@ attributes: | | __name__ | name with which this | | | | function was defined | +-----------+-----------------+---------------------------+ +| | __qualname__ | qualified name | ++-----------+-----------------+---------------------------+ | | __code__ | code object containing | | | | compiled function | | | | :term:`bytecode` | +-----------+-----------------+---------------------------+ | | __defaults__ | tuple of any default | -| | | values for arguments | +| | | values for positional or | +| | | keyword parameters | ++-----------+-----------------+---------------------------+ +| | __kwdefaults__ | mapping of any default | +| | | values for keyword-only | +| | | parameters | +-----------+-----------------+---------------------------+ | | __globals__ | global namespace in which | | | | this function was defined | @@ -154,16 +168,52 @@ attributes: | | | arguments and local | | | | variables | +-----------+-----------------+---------------------------+ +| generator | __name__ | name | ++-----------+-----------------+---------------------------+ +| | __qualname__ | qualified name | ++-----------+-----------------+---------------------------+ +| | gi_frame | frame | ++-----------+-----------------+---------------------------+ +| | gi_running | is the generator running? | ++-----------+-----------------+---------------------------+ +| | gi_code | code | ++-----------+-----------------+---------------------------+ +| | gi_yieldfrom | object being iterated by | +| | | ``yield from``, or | +| | | ``None`` | ++-----------+-----------------+---------------------------+ +| coroutine | __name__ | name | ++-----------+-----------------+---------------------------+ +| | __qualname__ | qualified name | ++-----------+-----------------+---------------------------+ +| | cr_await | object being awaited on, | +| | | or ``None`` | ++-----------+-----------------+---------------------------+ +| | cr_frame | frame | ++-----------+-----------------+---------------------------+ +| | cr_running | is the coroutine running? | ++-----------+-----------------+---------------------------+ +| | cr_code | code | ++-----------+-----------------+---------------------------+ | builtin | __doc__ | documentation string | +-----------+-----------------+---------------------------+ | | __name__ | original name of this | | | | function or method | +-----------+-----------------+---------------------------+ +| | __qualname__ | qualified name | ++-----------+-----------------+---------------------------+ | | __self__ | instance to which a | | | | method is bound, or | | | | ``None`` | +-----------+-----------------+---------------------------+ +.. versionchanged:: 3.5 + + Add ``__qualname__`` and ``gi_yieldfrom`` attributes to generators. + + The ``__name__`` attribute of generators is now set from the function + name, instead of the code name, and it can now be modified. + .. function:: getmembers(object[, predicate]) @@ -178,24 +228,6 @@ attributes: listed in the metaclass' custom :meth:`__dir__`. -.. function:: getmoduleinfo(path) - - Returns a :term:`named tuple` ``ModuleInfo(name, suffix, mode, module_type)`` - of values that describe how Python will interpret the file identified by - *path* if it is a module, or ``None`` if it would not be identified as a - module. In that tuple, *name* is the name of the module without the name of - any enclosing package, *suffix* is the trailing part of the file name (which - may not be a dot-delimited extension), *mode* is the :func:`open` mode that - would be used (``'r'`` or ``'rb'``), and *module_type* is an integer giving - the type of the module. *module_type* will have a value which can be - compared to the constants defined in the :mod:`imp` module; see the - documentation for that module for more information on module types. - - .. deprecated:: 3.3 - You may check the file path's suffix against the supported suffixes - listed in :mod:`importlib.machinery` to infer the same information. - - .. function:: getmodulename(path) Return the name of the module named by the file *path*, without including the @@ -209,8 +241,7 @@ attributes: still return ``None``. .. versionchanged:: 3.3 - This function is now based directly on :mod:`importlib` rather than the - deprecated :func:`getmoduleinfo`. + The function is based directly on :mod:`importlib`. .. function:: ismodule(object) @@ -245,6 +276,41 @@ attributes: Return true if the object is a generator. +.. function:: iscoroutinefunction(object) + + Return true if the object is a :term:`coroutine function` + (a function defined with an :keyword:`async def` syntax). + + .. versionadded:: 3.5 + + +.. function:: iscoroutine(object) + + Return true if the object is a :term:`coroutine` created by an + :keyword:`async def` function. + + .. versionadded:: 3.5 + + +.. function:: isawaitable(object) + + Return true if the object can be used in :keyword:`await` expression. + + Can also be used to distinguish generator-based coroutines from regular + generators:: + + def gen(): + yield + @types.coroutine + def gen_coro(): + yield + + assert not isawaitable(gen()) + assert isawaitable(gen_coro()) + + .. versionadded:: 3.5 + + .. function:: istraceback(object) Return true if the object is a traceback. @@ -335,6 +401,12 @@ Retrieving source code .. function:: getdoc(object) Get the documentation string for an object, cleaned up with :func:`cleandoc`. + If the documentation string for an object is not provided and the object is + a class, a method, a property or a descriptor, retrieve the documentation + string from the inheritance hierarchy. + + .. versionchanged:: 3.5 + Documentation strings are now inherited if not overridden. .. function:: getcomments(object) @@ -407,7 +479,7 @@ The Signature object represents the call signature of a callable object and its return annotation. To retrieve a Signature object, use the :func:`signature` function. -.. function:: signature(callable) +.. function:: signature(callable, \*, follow_wrapped=True) Return a :class:`Signature` object for the given ``callable``:: @@ -429,22 +501,42 @@ function. Accepts a wide range of python callables, from plain functions and classes to :func:`functools.partial` objects. + Raises :exc:`ValueError` if no signature can be provided, and + :exc:`TypeError` if that type of object is not supported. + + .. versionadded:: 3.5 + ``follow_wrapped`` parameter. Pass ``False`` to get a signature of + ``callable`` specifically (``callable.__wrapped__`` will not be used to + unwrap decorated callables.) + .. note:: Some callables may not be introspectable in certain implementations of - Python. For example, in CPython, built-in functions defined in C provide - no metadata about their arguments. + Python. For example, in CPython, some built-in functions defined in + C provide no metadata about their arguments. -.. class:: Signature +.. class:: Signature(parameters=None, \*, return_annotation=Signature.empty) A Signature object represents the call signature of a function and its return annotation. For each parameter accepted by the function it stores a :class:`Parameter` object in its :attr:`parameters` collection. + The optional *parameters* argument is a sequence of :class:`Parameter` + objects, which is validated to check that there are no parameters with + duplicate names, and that the parameters are in the right order, i.e. + positional-only first, then positional-or-keyword, and that parameters with + defaults follow parameters without defaults. + + The optional *return_annotation* argument, can be an arbitrary Python object, + is the "return" annotation of the callable. + Signature objects are *immutable*. Use :meth:`Signature.replace` to make a modified copy. + .. versionchanged:: 3.5 + Signature objects are picklable and hashable. + .. attribute:: Signature.empty A special class-level marker to specify absence of a return annotation. @@ -489,12 +581,30 @@ function. >>> str(new_sig) "(a, b) -> 'new return anno'" + .. classmethod:: Signature.from_callable(obj, \*, follow_wrapped=True) + + Return a :class:`Signature` (or its subclass) object for a given callable + ``obj``. Pass ``follow_wrapped=False`` to get a signature of ``obj`` + without unwrapping its ``__wrapped__`` chain. -.. class:: Parameter + This method simplifies subclassing of :class:`Signature`:: + + class MySignature(Signature): + pass + sig = MySignature.from_callable(min) + assert isinstance(sig, MySignature) + + .. versionadded:: 3.5 + + +.. class:: Parameter(name, kind, \*, default=Parameter.empty, annotation=Parameter.empty) Parameter objects are *immutable*. Instead of modifying a Parameter object, you can use :meth:`Parameter.replace` to create a modified copy. + .. versionchanged:: 3.5 + Parameter objects are picklable and hashable. + .. attribute:: Parameter.empty A special class-level marker to specify absence of default values and @@ -502,9 +612,8 @@ function. .. attribute:: Parameter.name - The name of the parameter as a string. Must be a valid python identifier - name (with the exception of ``POSITIONAL_ONLY`` parameters, which can have - it set to ``None``). + The name of the parameter as a string. The name must be a valid + Python identifier. .. attribute:: Parameter.default @@ -588,6 +697,10 @@ function. >>> str(param.replace(default=Parameter.empty, annotation='spam')) "foo:'spam'" + .. versionchanged:: 3.4 + In Python 3.3 Parameter objects were allowed to have ``name`` set + to ``None`` if their ``kind`` was set to ``POSITIONAL_ONLY``. + This is no longer permitted. .. class:: BoundArguments @@ -608,36 +721,42 @@ function. Arguments for which :meth:`Signature.bind` or :meth:`Signature.bind_partial` relied on a default value are skipped. - However, if needed, it is easy to include them. + However, if needed, use :meth:`BoundArguments.apply_defaults` to add + them. - :: + .. attribute:: BoundArguments.args + + A tuple of positional arguments values. Dynamically computed from the + :attr:`arguments` attribute. + + .. attribute:: BoundArguments.kwargs - >>> def foo(a, b=10): - ... pass + A dict of keyword arguments values. Dynamically computed from the + :attr:`arguments` attribute. - >>> sig = signature(foo) - >>> ba = sig.bind(5) + .. attribute:: BoundArguments.signature - >>> ba.args, ba.kwargs - ((5,), {}) + A reference to the parent :class:`Signature` object. - >>> for param in sig.parameters.values(): - ... if param.name not in ba.arguments: - ... ba.arguments[param.name] = param.default + .. method:: BoundArguments.apply_defaults() - >>> ba.args, ba.kwargs - ((5, 10), {}) + Set default values for missing arguments. + For variable-positional arguments (``*args``) the default is an + empty tuple. - .. attribute:: BoundArguments.args + For variable-keyword arguments (``**kwargs``) the default is an + empty dict. - A tuple of positional arguments values. Dynamically computed from the - :attr:`arguments` attribute. + :: - .. attribute:: BoundArguments.kwargs + >>> def foo(a, b='ham', *args): pass + >>> ba = inspect.signature(foo).bind('spam') + >>> ba.apply_defaults() + >>> ba.arguments + OrderedDict([('a', 'spam'), ('b', 'ham'), ('args', ())]) - A dict of keyword arguments values. Dynamically computed from the - :attr:`arguments` attribute. + .. versionadded:: 3.5 The :attr:`args` and :attr:`kwargs` properties can be used to invoke functions:: @@ -671,22 +790,6 @@ Classes and functions classes using multiple inheritance and their descendants will appear multiple times. - -.. function:: getargspec(func) - - Get the names and default values of a Python function's arguments. A - :term:`named tuple` ``ArgSpec(args, varargs, keywords, defaults)`` is - returned. *args* is a list of the argument names. *varargs* and *keywords* - are the names of the ``*`` and ``**`` arguments or ``None``. *defaults* is a - tuple of default argument values or ``None`` if there are no default - arguments; if this tuple has *n* elements, they correspond to the last - *n* elements listed in *args*. - - .. deprecated:: 3.0 - Use :func:`getfullargspec` instead, which provides information about - keyword-only arguments and annotations. - - .. function:: getfullargspec(func) Get the names and default values of a Python function's arguments. A @@ -703,11 +806,15 @@ Classes and functions from kwonlyargs to defaults. *annotations* is a dictionary mapping argument names to annotations. - The first four items in the tuple correspond to :func:`getargspec`. + .. versionchanged:: 3.4 + This function is now based on :func:`signature`, but still ignores + ``__wrapped__`` attributes and includes the already bound first + parameter in the signature output for bound methods. - .. note:: - Consider using the new :ref:`Signature Object <inspect-signature-object>` - interface, which provides a better way of introspecting functions. + .. deprecated:: 3.5 + Use :func:`signature` and + :ref:`Signature Object <inspect-signature-object>`, which provide a + better introspecting API for callables. .. function:: getargvalues(frame) @@ -718,24 +825,37 @@ Classes and functions are the names of the ``*`` and ``**`` arguments or ``None``. *locals* is the locals dictionary of the given frame. + .. deprecated:: 3.5 + Use :func:`signature` and + :ref:`Signature Object <inspect-signature-object>`, which provide a + better introspecting API for callables. + .. function:: formatargspec(args[, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations[, formatarg, formatvarargs, formatvarkw, formatvalue, formatreturns, formatannotations]]) Format a pretty argument spec from the values returned by - :func:`getargspec` or :func:`getfullargspec`. + :func:`getfullargspec`. The first seven arguments are (``args``, ``varargs``, ``varkw``, - ``defaults``, ``kwonlyargs``, ``kwonlydefaults``, ``annotations``). The - other five arguments are the corresponding optional formatting functions - that are called to turn names and values into strings. The last argument - is an optional function to format the sequence of arguments. For example:: + ``defaults``, ``kwonlyargs``, ``kwonlydefaults``, ``annotations``). - >>> from inspect import formatargspec, getfullargspec - >>> def f(a: int, b: float): - ... pass - ... - >>> formatargspec(*getfullargspec(f)) - '(a: int, b: float)' + The other six arguments are functions that are called to turn argument names, + ``*`` argument name, ``**`` argument name, default values, return annotation + and individual annotations into strings, respectively. + + For example: + + >>> from inspect import formatargspec, getfullargspec + >>> def f(a: int, b: float): + ... pass + ... + >>> formatargspec(*getfullargspec(f)) + '(a: int, b: float)' + + .. deprecated:: 3.5 + Use :func:`signature` and + :ref:`Signature Object <inspect-signature-object>`, which provide a + better introspecting API for callables. .. function:: formatargvalues(args[, varargs, varkw, locals, formatarg, formatvarargs, formatvarkw, formatvalue]) @@ -744,6 +864,11 @@ Classes and functions :func:`getargvalues`. The format\* arguments are the corresponding optional formatting functions that are called to turn names and values into strings. + .. deprecated:: 3.5 + Use :func:`signature` and + :ref:`Signature Object <inspect-signature-object>`, which provide a + better introspecting API for callables. + .. function:: getmro(cls) @@ -753,7 +878,7 @@ Classes and functions metatype is in use, cls will be the first element of the tuple. -.. function:: getcallargs(func[, *args][, **kwds]) +.. function:: getcallargs(func, *args, **kwds) Bind the *args* and *kwds* to the argument names of the Python function or method *func*, as if it was called with them. For bound methods, bind also the @@ -778,8 +903,8 @@ Classes and functions .. versionadded:: 3.2 - .. note:: - Consider using the new :meth:`Signature.bind` instead. + .. deprecated:: 3.5 + Use :meth:`Signature.bind` and :meth:`Signature.bind_partial` instead. .. function:: getclosurevars(func) @@ -820,11 +945,17 @@ Classes and functions The interpreter stack --------------------- -When the following functions return "frame records," each record is a tuple of -six items: the frame object, the filename, the line number of the current line, +When the following functions return "frame records," each record is a +:term:`named tuple` +``FrameInfo(frame, filename, lineno, function, code_context, index)``. +The tuple contains the frame object, the filename, the line number of the +current line, the function name, a list of lines of context from the source code, and the index of the current line within that list. +.. versionchanged:: 3.5 + Return a named tuple instead of a tuple. + .. note:: Keeping references to frame objects, as found in the first element of the frame @@ -869,6 +1000,11 @@ line. returned list represents *frame*; the last entry represents the outermost call on *frame*'s stack. + .. versionchanged:: 3.5 + A list of :term:`named tuples <named tuple>` + ``FrameInfo(frame, filename, lineno, function, code_context, index)`` + is returned. + .. function:: getinnerframes(traceback, context=1) @@ -877,6 +1013,11 @@ line. list represents *traceback*; the last entry represents where the exception was raised. + .. versionchanged:: 3.5 + A list of :term:`named tuples <named tuple>` + ``FrameInfo(frame, filename, lineno, function, code_context, index)`` + is returned. + .. function:: currentframe() @@ -896,6 +1037,11 @@ line. returned list represents the caller; the last entry represents the outermost call on the stack. + .. versionchanged:: 3.5 + A list of :term:`named tuples <named tuple>` + ``FrameInfo(frame, filename, lineno, function, code_context, index)`` + is returned. + .. function:: trace(context=1) @@ -904,6 +1050,11 @@ line. entry in the list represents the caller; the last entry represents where the exception was raised. + .. versionchanged:: 3.5 + A list of :term:`named tuples <named tuple>` + ``FrameInfo(frame, filename, lineno, function, code_context, index)`` + is returned. + Fetching attributes statically ------------------------------ @@ -963,8 +1114,8 @@ code execution:: pass -Current State of a Generator ----------------------------- +Current State of Generators and Coroutines +------------------------------------------ When implementing coroutine schedulers and for other advanced uses of generators, it is useful to determine whether a generator is currently @@ -984,6 +1135,21 @@ generator to be determined easily. .. versionadded:: 3.2 +.. function:: getcoroutinestate(coroutine) + + Get current state of a coroutine object. The function is intended to be + used with coroutine objects created by :keyword:`async def` functions, but + will accept any coroutine-like object that has ``cr_running`` and + ``cr_frame`` attributes. + + Possible states are: + * CORO_CREATED: Waiting to start execution. + * CORO_RUNNING: Currently being executed by the interpreter. + * CORO_SUSPENDED: Currently suspended at an await expression. + * CORO_CLOSED: Execution has completed. + + .. versionadded:: 3.5 + The current internal state of the generator can also be queried. This is mostly useful for testing purposes, to ensure that internal state is being updated as expected: @@ -1008,6 +1174,13 @@ updated as expected: .. versionadded:: 3.3 +.. function:: getcoroutinelocals(coroutine) + + This function is analogous to :func:`~inspect.getgeneratorlocals`, but + works for coroutine objects created by :keyword:`async def` functions. + + .. versionadded:: 3.5 + .. _inspect-module-cli: diff --git a/Doc/library/intro.rst b/Doc/library/intro.rst index a0f2d6324f65..e3283cac9947 100644 --- a/Doc/library/intro.rst +++ b/Doc/library/intro.rst @@ -30,10 +30,8 @@ requires them; yet others are available only when a particular configuration option was chosen at the time when Python was compiled and installed. This manual is organized "from the inside out:" it first describes the built-in -data types, then the built-in functions and exceptions, and finally the modules, -grouped in chapters of related modules. The ordering of the chapters as well as -the ordering of the modules within each chapter is roughly from most relevant to -least important. +functions, data types and exceptions, and finally the modules, grouped in +chapters of related modules. This means that if you start reading this manual from the start, and skip to the next chapter when you get bored, you will get a reasonable overview of the diff --git a/Doc/library/io.rst b/Doc/library/io.rst index 2b55018550c5..cb3e9edf11dd 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -289,7 +289,7 @@ I/O Base Classes most *size* bytes will be read. The line terminator is always ``b'\n'`` for binary files; for text files, - the *newlines* argument to :func:`open` can be used to select the line + the *newline* argument to :func:`open` can be used to select the line terminator(s) recognized. .. method:: readlines(hint=-1) @@ -301,11 +301,11 @@ I/O Base Classes Note that it's already possible to iterate on file objects using ``for line in file: ...`` without calling ``file.readlines()``. - .. method:: seek(offset, whence=SEEK_SET) + .. method:: seek(offset[, whence]) Change the stream position to the given byte *offset*. *offset* is - interpreted relative to the position indicated by *whence*. Values for - *whence* are: + interpreted relative to the position indicated by *whence*. The default + value for *whence* is :data:`SEEK_SET`. Values for *whence* are: * :data:`SEEK_SET` or ``0`` -- start of the stream (the default); *offset* should be zero or positive @@ -339,8 +339,11 @@ I/O Base Classes if *size* is not specified). The current stream position isn't changed. This resizing can extend or reduce the current file size. In case of extension, the contents of the new file area depend on the platform - (on most systems, additional bytes are zero-filled, on Windows they're - undetermined). The new file size is returned. + (on most systems, additional bytes are zero-filled). The new file size + is returned. + + .. versionchanged:: 3.5 + Windows will now zero-fill files when extending. .. method:: writable() @@ -353,6 +356,12 @@ I/O Base Classes is usual for each of the lines provided to have a line separator at the end. + .. method:: __del__() + + Prepare for object destruction. :class:`IOBase` provides a default + implementation of this method that calls the instance's + :meth:`~IOBase.close` method. + .. class:: RawIOBase @@ -385,8 +394,8 @@ I/O Base Classes .. method:: readinto(b) Read up to ``len(b)`` bytes into :class:`bytearray` *b* and return the - number of bytes read. If the object is in non-blocking mode and no - bytes are available, ``None`` is returned. + number of bytes read. If the object is in non-blocking mode and no bytes + are available, ``None`` is returned. .. method:: write(b) @@ -459,9 +468,10 @@ I/O Base Classes .. method:: read1(size=-1) - Read and return up to *size* bytes, with at most one call to the underlying - raw stream's :meth:`~RawIOBase.read` method. This can be useful if you - are implementing your own buffering on top of a :class:`BufferedIOBase` + Read and return up to *size* bytes, with at most one call to the + underlying raw stream's :meth:`~RawIOBase.read` (or + :meth:`~RawIOBase.readinto`) method. This can be useful if you are + implementing your own buffering on top of a :class:`BufferedIOBase` object. .. method:: readinto(b) @@ -472,8 +482,19 @@ I/O Base Classes Like :meth:`read`, multiple reads may be issued to the underlying raw stream, unless the latter is interactive. - A :exc:`BlockingIOError` is raised if the underlying raw stream is in - non blocking-mode, and has no data available at the moment. + A :exc:`BlockingIOError` is raised if the underlying raw stream is in non + blocking-mode, and has no data available at the moment. + + .. method:: readinto1(b) + + Read up to ``len(b)`` bytes into bytearray *b*, using at most one call to + the underlying raw stream's :meth:`~RawIOBase.read` (or + :meth:`~RawIOBase.readinto`) method. Return the number of bytes read. + + A :exc:`BlockingIOError` is raised if the underlying raw stream is in non + blocking-mode, and has no data available at the moment. + + .. versionadded:: 3.5 .. method:: write(b) @@ -501,9 +522,12 @@ Raw File I/O The *name* can be one of two things: * a character string or :class:`bytes` object representing the path to the - file which will be opened; + file which will be opened. In this case closefd must be True (the default) + otherwise an error will be raised. * an integer representing the number of an existing OS-level file descriptor - to which the resulting :class:`FileIO` object will give access. + to which the resulting :class:`FileIO` object will give access. When the + FileIO object is closed this fd will be closed as well, unless *closefd* + is set to ``False``. The *mode* can be ``'r'``, ``'w'``, ``'x'`` or ``'a'`` for reading (default), writing, exclusive creation or appending. The file will be @@ -557,7 +581,8 @@ than raw I/O does. .. class:: BytesIO([initial_bytes]) A stream implementation using an in-memory bytes buffer. It inherits - :class:`BufferedIOBase`. + :class:`BufferedIOBase`. The buffer is discarded when the + :meth:`~IOBase.close` method is called. The argument *initial_bytes* contains optional initial :class:`bytes` data. @@ -578,7 +603,7 @@ than raw I/O does. .. note:: As long as the view exists, the :class:`BytesIO` object cannot be - resized. + resized or closed. .. versionadded:: 3.2 @@ -586,10 +611,16 @@ than raw I/O does. Return :class:`bytes` containing the entire contents of the buffer. + .. method:: read1() In :class:`BytesIO`, this is the same as :meth:`read`. + .. method:: readinto1() + + In :class:`BytesIO`, this is the same as :meth:`readinto`. + + .. versionadded:: 3.5 .. class:: BufferedReader(raw, buffer_size=DEFAULT_BUFFER_SIZE) @@ -686,6 +717,7 @@ than raw I/O does. :exc:`UnsupportedOperation`. .. warning:: + :class:`BufferedRWPair` does not attempt to synchronize accesses to its underlying raw streams. You should not pass it the same object as reader and writer; use :class:`BufferedRandom` instead. @@ -751,10 +783,11 @@ Text I/O If *size* is specified, at most *size* characters will be read. - .. method:: seek(offset, whence=SEEK_SET) + .. method:: seek(offset[, whence]) - Change the stream position to the given *offset*. Behaviour depends - on the *whence* parameter: + Change the stream position to the given *offset*. Behaviour depends on + the *whence* parameter. The default value for *whence* is + :data:`SEEK_SET`. * :data:`SEEK_SET` or ``0``: seek from the start of the stream (the default); *offset* must either be a number returned by @@ -798,11 +831,13 @@ Text I/O 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.) ``'replace'`` causes a replacement marker - (such as ``'?'``) to be inserted where there is malformed data. When - writing, ``'xmlcharrefreplace'`` (replace with the appropriate XML character - reference) or ``'backslashreplace'`` (replace with backslashed escape - sequences) can be used. Any other error handling name that has been - registered with :func:`codecs.register_error` is also valid. + (such as ``'?'``) to be inserted where there is malformed data. + ``'backslashreplace'`` causes malformed data to be replaced by a + backslashed escape sequence. When writing, ``'xmlcharrefreplace'`` + (replace with the appropriate XML character reference) or ``'namereplace'`` + (replace with ``\N{...}`` escape sequences) can be used. Any other error + handling name that has been registered with + :func:`codecs.register_error` is also valid. .. index:: single: universal newlines; io.TextIOWrapper class @@ -849,22 +884,30 @@ Text I/O Whether line buffering is enabled. -.. class:: StringIO(initial_value='', newline=None) +.. class:: StringIO(initial_value='', newline='\\n') + + An in-memory stream for text I/O. The text buffer is discarded when the + :meth:`~IOBase.close` method is called. - An in-memory stream for text I/O. + The initial value of the buffer can be set by providing *initial_value*. + If newline translation is enabled, newlines will be encoded as if by + :meth:`~TextIOBase.write`. The stream is positioned at the start of + the buffer. - The initial value of the buffer (an empty string by default) can be set by - providing *initial_value*. The *newline* argument works like that of - :class:`TextIOWrapper`. The default is to do no newline translation. + The *newline* argument works like that of :class:`TextIOWrapper`. + The default is to consider only ``\n`` characters as ends of lines and + to do no newline translation. If *newline* is set to ``None``, + newlines are written as ``\n`` on all platforms, but universal + newline decoding is still performed when reading. :class:`StringIO` provides this method in addition to those from :class:`TextIOBase` and its parents: .. method:: getvalue() - Return a ``str`` containing the entire contents of the buffer at any - time before the :class:`StringIO` object's :meth:`close` method is - called. + Return a ``str`` containing the entire contents of the buffer. + Newlines are decoded as if by :meth:`~TextIOBase.read`, although + the stream position is not changed. Example usage:: diff --git a/Doc/library/ipaddress.rst b/Doc/library/ipaddress.rst index 826e4aa948f5..90fcc748e761 100644 --- a/Doc/library/ipaddress.rst +++ b/Doc/library/ipaddress.rst @@ -9,13 +9,6 @@ -------------- -.. note:: - - The ``ipaddress`` module has been included in the standard library on a - :term:`provisional basis <provisional package>`. Backwards incompatible - changes (up to and including removal of the package) may occur if deemed - necessary by the core developers. - :mod:`ipaddress` provides the capabilities to create, manipulate and operate on IPv4 and IPv6 addresses and networks. @@ -25,8 +18,8 @@ hosts are on the same subnet, iterating over all hosts in a particular subnet, checking whether or not a string represents a valid IP address or network definition, and so on. -This is the full module API reference - for an overview and introduction, -see :ref:`ipaddress-howto`. +This is the full module API reference—for an overview and introduction, see +:ref:`ipaddress-howto`. .. versionadded:: 3.3 @@ -110,7 +103,7 @@ write code that handles both IP versions correctly. 1. A string in decimal-dot notation, consisting of four decimal integers in the inclusive range 0-255, separated by dots (e.g. ``192.168.0.1``). Each integer represents an octet (byte) in the address. Leading zeroes are - tolerated only for values less then 8 (as there is no ambiguity + tolerated only for values less than 8 (as there is no ambiguity between the decimal and octal interpretations of such strings). 2. An integer that fits into 32 bits. 3. An integer packed into a :class:`bytes` object of length 4 (most @@ -153,6 +146,20 @@ write code that handles both IP versions correctly. the appropriate length (most significant octet first). This is 4 bytes for IPv4 and 16 bytes for IPv6. + .. attribute:: reverse_pointer + + The name of the reverse DNS PTR record for the IP address, e.g.:: + + >>> ipaddress.ip_address("127.0.0.1").reverse_pointer + '1.0.0.127.in-addr.arpa' + >>> ipaddress.ip_address("2001:db8::1").reverse_pointer + '1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa' + + This is the name that could be used for performing a PTR lookup, not the + resolved hostname itself. + + .. versionadded:: 3.5 + .. attribute:: is_multicast ``True`` if the address is reserved for multicast use. See @@ -161,20 +168,20 @@ write code that handles both IP versions correctly. .. attribute:: is_private ``True`` if the address is allocated for private networks. See - iana-ipv4-special-registry (for IPv4) or iana-ipv6-special-registry + iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ (for IPv6). .. attribute:: is_global ``True`` if the address is allocated for public networks. See - iana-ipv4-special-registry (for IPv4) or iana-ipv6-special-registry + iana-ipv4-special-registry_ (for IPv4) or iana-ipv6-special-registry_ (for IPv6). - .. versionadded:: 3.4 + .. versionadded:: 3.4 .. attribute:: is_unspecified - ``True`` if the address is unspecified. See :RFC:`5375` (for IPv4) + ``True`` if the address is unspecified. See :RFC:`5735` (for IPv4) or :RFC:`2373` (for IPv6). .. attribute:: is_reserved @@ -191,6 +198,9 @@ write code that handles both IP versions correctly. ``True`` if the address is reserved for link-local usage. See :RFC:`3927`. +.. _iana-ipv4-special-registry: http://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml +.. _iana-ipv6-special-registry: http://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml + .. class:: IPv6Address(address) @@ -225,18 +235,24 @@ write code that handles both IP versions correctly. The long form of the address representation, with all leading zeroes and groups consisting entirely of zeroes included. + + For the following attributes, see the corresponding documention of the + :class:`IPv4Address` class: + .. attribute:: packed + .. attribute:: reverse_pointer .. attribute:: version .. attribute:: max_prefixlen .. attribute:: is_multicast .. attribute:: is_private + .. attribute:: is_global .. attribute:: is_unspecified .. attribute:: is_reserved .. attribute:: is_loopback .. attribute:: is_link_local - Refer to the corresponding attribute documentation in - :class:`IPv4Address` + .. versionadded:: 3.4 + is_global .. attribute:: is_site_local @@ -376,6 +392,12 @@ so to avoid duplication they are only documented for :class:`IPv4Network`. 3. An integer packed into a :class:`bytes` object of length 4, big-endian. The interpretation is similar to an integer *address*. + 4. A two-tuple of an address description and a netmask, where the address + description is either a string, a 32-bits integer, a 4-bytes packed + integer, or an existing IPv4Address object; and the netmask is either + an integer representing the prefix length (e.g. ``24``) or a string + representing the prefix mask (e.g. ``255.255.255.0``). + An :exc:`AddressValueError` is raised if *address* is not a valid IPv4 address. A :exc:`NetmaskValueError` is raised if the mask is not valid for an IPv4 address. @@ -388,6 +410,10 @@ so to avoid duplication they are only documented for :class:`IPv4Network`. objects will raise :exc:`TypeError` if the argument's IP version is incompatible to ``self`` + .. versionchanged:: 3.5 + + Added the two-tuple form for the *address* constructor parameter. + .. attribute:: version .. attribute:: max_prefixlen @@ -414,7 +440,7 @@ so to avoid duplication they are only documented for :class:`IPv4Network`. The broadcast address for the network. Packets sent to the broadcast address should be received by every host on the network. - .. attribute:: host mask + .. attribute:: hostmask The host mask, as a string. @@ -549,9 +575,14 @@ so to avoid duplication they are only documented for :class:`IPv4Network`. single-address network, with the network address being *address* and the mask being ``/128``. - 3. An integer packed into a :class:`bytes` object of length 16, bit-endian. + 3. An integer packed into a :class:`bytes` object of length 16, big-endian. The interpretation is similar to an integer *address*. + 4. A two-tuple of an address description and a netmask, where the address + description is either a string, a 128-bits integer, a 16-bytes packed + integer, or an existing IPv4Address object; and the netmask is an + integer representing the prefix length. + An :exc:`AddressValueError` is raised if *address* is not a valid IPv6 address. A :exc:`NetmaskValueError` is raised if the mask is not valid for an IPv6 address. @@ -560,6 +591,10 @@ so to avoid duplication they are only documented for :class:`IPv4Network`. then :exc:`ValueError` is raised. Otherwise, the host bits are masked out to determine the appropriate network address. + .. versionchanged:: 3.5 + + Added the two-tuple form for the *address* constructor parameter. + .. attribute:: version .. attribute:: max_prefixlen .. attribute:: is_multicast @@ -570,7 +605,7 @@ so to avoid duplication they are only documented for :class:`IPv4Network`. .. attribute:: is_link_local .. attribute:: network_address .. attribute:: broadcast_address - .. attribute:: host mask + .. attribute:: hostmask .. attribute:: with_prefixlen .. attribute:: compressed .. attribute:: exploded diff --git a/Doc/library/ipc.rst b/Doc/library/ipc.rst index 2440bd4d6bde..6b1756331ec0 100644 --- a/Doc/library/ipc.rst +++ b/Doc/library/ipc.rst @@ -9,7 +9,7 @@ to communicate. Some modules only work for two processes that are on the same machine, e.g. :mod:`signal` and :mod:`mmap`. Other modules support networking protocols -that two or more processes can used to communicate across machines. +that two or more processes can use to communicate across machines. The list of modules described in this chapter is: diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 6929192b4fe0..8c7592d17e9e 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -43,22 +43,22 @@ Iterator Arguments Results **Iterators terminating on the shortest input sequence:** -==================== ============================ ================================================= ============================================================= -Iterator Arguments Results Example -==================== ============================ ================================================= ============================================================= -:func:`accumulate` p [,func] p0, p0+p1, p0+p1+p2, ... ``accumulate([1,2,3,4,5]) --> 1 3 6 10 15`` -:func:`chain` p, q, ... p0, p1, ... plast, q0, q1, ... ``chain('ABC', 'DEF') --> A B C D E F`` -chain.from_iterable iterable p0, p1, ... plast, q0, q1, ... ``chain.from_iterable(['ABC', 'DEF']) --> A B C D E F`` -:func:`compress` data, selectors (d[0] if s[0]), (d[1] if s[1]), ... ``compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F`` -:func:`dropwhile` pred, seq seq[n], seq[n+1], starting when pred fails ``dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1`` -:func:`filterfalse` pred, seq elements of seq where pred(elem) is false ``filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8`` -:func:`groupby` iterable[, keyfunc] sub-iterators grouped by value of keyfunc(v) -:func:`islice` seq, [start,] stop [, step] elements from seq[start:stop:step] ``islice('ABCDEFG', 2, None) --> C D E F G`` -:func:`starmap` func, seq func(\*seq[0]), func(\*seq[1]), ... ``starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000`` -:func:`takewhile` pred, seq seq[0], seq[1], until pred fails ``takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4`` -:func:`tee` it, n it1, it2 , ... itn splits one iterator into n -:func:`zip_longest` p, q, ... (p[0], q[0]), (p[1], q[1]), ... ``zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-`` -==================== ============================ ================================================= ============================================================= +============================ ============================ ================================================= ============================================================= +Iterator Arguments Results Example +============================ ============================ ================================================= ============================================================= +:func:`accumulate` p [,func] p0, p0+p1, p0+p1+p2, ... ``accumulate([1,2,3,4,5]) --> 1 3 6 10 15`` +:func:`chain` p, q, ... p0, p1, ... plast, q0, q1, ... ``chain('ABC', 'DEF') --> A B C D E F`` +:func:`chain.from_iterable` iterable p0, p1, ... plast, q0, q1, ... ``chain.from_iterable(['ABC', 'DEF']) --> A B C D E F`` +:func:`compress` data, selectors (d[0] if s[0]), (d[1] if s[1]), ... ``compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F`` +:func:`dropwhile` pred, seq seq[n], seq[n+1], starting when pred fails ``dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1`` +:func:`filterfalse` pred, seq elements of seq where pred(elem) is false ``filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8`` +:func:`groupby` iterable[, keyfunc] sub-iterators grouped by value of keyfunc(v) +:func:`islice` seq, [start,] stop [, step] elements from seq[start:stop:step] ``islice('ABCDEFG', 2, None) --> C D E F G`` +:func:`starmap` func, seq func(\*seq[0]), func(\*seq[1]), ... ``starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000`` +:func:`takewhile` pred, seq seq[0], seq[1], until pred fails ``takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4`` +:func:`tee` it, n it1, it2, ... itn splits one iterator into n +:func:`zip_longest` p, q, ... (p[0], q[0]), (p[1], q[1]), ... ``zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-`` +============================ ============================ ================================================= ============================================================= **Combinatoric generators:** @@ -87,10 +87,15 @@ loops that truncate the stream. .. function:: accumulate(iterable[, func]) - Make an iterator that returns accumulated sums. Elements may be any addable - type including :class:`~decimal.Decimal` or :class:`~fractions.Fraction`. - If the optional *func* argument is supplied, it should be a function of two - arguments and it will be used instead of addition. + Make an iterator that returns accumulated sums, or accumulated + results of other binary functions (specified via the optional + *func* argument). If *func* is supplied, it should be a function + of two arguments. Elements of the input *iterable* may be any type + that can be accepted as arguments to *func*. (For example, with + the default operation of addition, elements may be any addable + type including :class:`~decimal.Decimal` or + :class:`~fractions.Fraction`.) If the input iterable is empty, the + output iterable will also be empty. Equivalent to:: @@ -99,7 +104,10 @@ loops that truncate the stream. # accumulate([1,2,3,4,5]) --> 1 3 6 10 15 # accumulate([1,2,3,4,5], operator.mul) --> 1 2 6 24 120 it = iter(iterable) - total = next(it) + try: + total = next(it) + except StopIteration: + return yield total for element in it: total = func(total, element) @@ -131,7 +139,7 @@ loops that truncate the stream. >>> inputs = repeat(x0, 36) # only the initial value is used >>> [format(x, '.2f') for x in accumulate(inputs, logistic_map)] ['0.40', '0.91', '0.30', '0.81', '0.60', '0.92', '0.29', '0.79', '0.63', - '0.88' ,'0.39', '0.90', '0.33', '0.84', '0.52', '0.95', '0.18', '0.57', + '0.88', '0.39', '0.90', '0.33', '0.84', '0.52', '0.95', '0.18', '0.57', '0.93', '0.25', '0.71', '0.79', '0.63', '0.88', '0.39', '0.91', '0.32', '0.83', '0.54', '0.95', '0.20', '0.60', '0.91', '0.30', '0.80', '0.60'] @@ -400,7 +408,10 @@ loops that truncate the stream. def _grouper(self, tgtkey): while self.currkey == tgtkey: yield self.currvalue - self.currvalue = next(self.it) # Exit on StopIteration + try: + self.currvalue = next(self.it) + except StopIteration: + return self.currkey = self.keyfunc(self.currvalue) @@ -424,7 +435,10 @@ loops that truncate the stream. # islice('ABCDEFG', 0, None, 2) --> A C E G s = slice(*args) it = iter(range(s.start or 0, s.stop or sys.maxsize, s.step or 1)) - nexti = next(it) + try: + nexti = next(it) + except StopIteration: + return for i, element in enumerate(iterable): if i == nexti: yield element @@ -582,7 +596,10 @@ loops that truncate the stream. def gen(mydeque): while True: if not mydeque: # when the local deque is empty - newval = next(it) # fetch a new value and + try: + newval = next(it) # fetch a new value and + except StopIteration: + return for d in deques: # load it to all the deques d.append(newval) yield mydeque.popleft() @@ -657,6 +674,11 @@ which incur interpreter overhead. "Return function(0), function(1), ..." return map(function, count(start)) + def tail(n, iterable): + "Return an iterator over the last n items" + # tail(3, 'ABCDEFG') --> E F G + return iter(collections.deque(iterable, maxlen=n)) + def consume(iterator, n): "Advance the iterator n-steps ahead. If n is none, consume entirely." # Use functions that consume iterators at C speed. @@ -784,6 +806,19 @@ which incur interpreter overhead. except exception: pass + def first_true(iterable, default=False, pred=None): + """Returns the first true value in the iterable. + + If no true value is found, returns *default* + + If *pred* is not None, returns the first item + for which pred(item) is true. + + """ + # first_true([a,b,c], x) --> a or b or c or x + # first_true([a,b], x, f) --> a if f(a) else b if f(b) else x + return next(filter(pred, iterable), default) + def random_product(*args, repeat=1): "Random selection from itertools.product(*args, **kwds)" pools = [tuple(pool) for pool in args] * repeat diff --git a/Doc/library/json.rst b/Doc/library/json.rst index 5d97ee88fc49..d62f14be60e3 100644 --- a/Doc/library/json.rst +++ b/Doc/library/json.rst @@ -7,9 +7,11 @@ .. sectionauthor:: Bob Ippolito <bob@redivi.com> `JSON (JavaScript Object Notation) <http://json.org>`_, specified by -:rfc:`4627`, is a lightweight data interchange format based on a subset of -`JavaScript <http://en.wikipedia.org/wiki/JavaScript>`_ syntax (`ECMA-262 3rd -edition <http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,%20December%201999.pdf>`_). +:rfc:`7159` (which obsoletes :rfc:`4627`) and by +`ECMA-404 <http://www.ecma-international.org/publications/standards/Ecma-404.htm>`_, +is a lightweight data interchange format inspired by +`JavaScript <http://en.wikipedia.org/wiki/JavaScript>`_ object literal syntax +(although it is not a strict subset of JavaScript [#rfc-errata]_ ). :mod:`json` exposes an API familiar to users of the standard library :mod:`marshal` and :mod:`pickle` modules. @@ -97,13 +99,15 @@ Extending :class:`JSONEncoder`:: Using json.tool from the shell to validate and pretty-print:: - $ echo '{"json":"obj"}' | python -mjson.tool + $ echo '{"json":"obj"}' | python -m json.tool { "json": "obj" } - $ echo '{1.2:3.4}' | python -mjson.tool + $ echo '{1.2:3.4}' | python -m json.tool Expecting property name enclosed in double quotes: line 1 column 2 (char 1) +See :ref:`json-commandline` for detailed documentation. + .. highlight:: python3 .. note:: @@ -246,7 +250,7 @@ Basic Usage will be passed to the constructor of the class. If the data being deserialized is not a valid JSON document, a - :exc:`ValueError` will be raised. + :exc:`JSONDecodeError` will be raised. .. function:: loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw) @@ -257,7 +261,7 @@ Basic Usage *encoding* which is ignored and deprecated. If the data being deserialized is not a valid JSON document, a - :exc:`ValueError` will be raised. + :exc:`JSONDecodeError` will be raised. Encoders and Decoders --------------------- @@ -330,12 +334,15 @@ Encoders and Decoders ``'\n'``, ``'\r'`` and ``'\0'``. If the data being deserialized is not a valid JSON document, a - :exc:`ValueError` will be raised. + :exc:`JSONDecodeError` will be raised. .. method:: decode(s) Return the Python representation of *s* (a :class:`str` instance - containing a JSON document) + containing a JSON document). + + :exc:`JSONDecodeError` will be raised if the given JSON document is not + valid. .. method:: raw_decode(s) @@ -465,18 +472,48 @@ Encoders and Decoders mysocket.write(chunk) -Standard Compliance -------------------- +Exceptions +---------- + +.. exception:: JSONDecodeError(msg, doc, pos, end=None) + + Subclass of :exc:`ValueError` with the following additional attributes: + + .. attribute:: msg + + The unformatted error message. + + .. attribute:: doc + + The JSON document being parsed. + + .. attribute:: pos + + The start index of *doc* where parsing failed. + + .. attribute:: lineno + + The line corresponding to *pos*. + + .. attribute:: colno + + The column corresponding to *pos*. + + .. versionadded:: 3.5 + -The JSON format is specified by :rfc:`4627`. This section details this -module's level of compliance with the RFC. For simplicity, -:class:`JSONEncoder` and :class:`JSONDecoder` subclasses, and parameters other -than those explicitly mentioned, are not considered. +Standard Compliance and Interoperability +---------------------------------------- + +The JSON format is specified by :rfc:`7159` and by +`ECMA-404 <http://www.ecma-international.org/publications/standards/Ecma-404.htm>`_. +This section details this module's level of compliance with the RFC. +For simplicity, :class:`JSONEncoder` and :class:`JSONDecoder` subclasses, and +parameters other than those explicitly mentioned, are not considered. This module does not comply with the RFC in a strict fashion, implementing some extensions that are valid JavaScript but not valid JSON. In particular: -- Top-level non-object, non-array values are accepted and output; - Infinite and NaN number values are accepted and output; - Repeated names within an object are accepted, and only the value of the last name-value pair is used. @@ -488,8 +525,8 @@ default settings. Character Encodings ^^^^^^^^^^^^^^^^^^^ -The RFC recommends that JSON be represented using either UTF-8, UTF-16, or -UTF-32, with UTF-8 being the default. +The RFC requires that JSON be represented using either UTF-8, UTF-16, or +UTF-32, with UTF-8 being the recommended default for maximum interoperability. As permitted, though not required, by the RFC, this module's serializer sets *ensure_ascii=True* by default, thus escaping the output so that the resulting @@ -497,34 +534,20 @@ strings only contain ASCII characters. Other than the *ensure_ascii* parameter, this module is defined strictly in terms of conversion between Python objects and -:class:`Unicode strings <str>`, and thus does not otherwise address the issue -of character encodings. - - -Top-level Non-Object, Non-Array Values -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The RFC specifies that the top-level value of a JSON text must be either a -JSON object or array (Python :class:`dict` or :class:`list`). This module's -deserializer also accepts input texts consisting solely of a -JSON null, boolean, number, or string value:: - - >>> just_a_json_string = '"spam and eggs"' # Not by itself a valid JSON text - >>> json.loads(just_a_json_string) - 'spam and eggs' - -This module itself does not include a way to request that such input texts be -regarded as illegal. Likewise, this module's serializer also accepts single -Python :data:`None`, :class:`bool`, numeric, and :class:`str` -values as input and will generate output texts consisting solely of a top-level -JSON null, boolean, number, or string value without raising an exception:: +:class:`Unicode strings <str>`, and thus does not otherwise directly address +the issue of character encodings. - >>> neither_a_list_nor_a_dict = "spam and eggs" - >>> json.dumps(neither_a_list_nor_a_dict) # The result is not a valid JSON text - '"spam and eggs"' +The RFC prohibits adding a byte order mark (BOM) to the start of a JSON text, +and this module's serializer does not add a BOM to its output. +The RFC permits, but does not require, JSON deserializers to ignore an initial +BOM in their input. This module's deserializer raises a :exc:`ValueError` +when an initial BOM is present. -This module's serializer does not itself include a way to enforce the -aforementioned constraint. +The RFC does not explicitly forbid JSON strings which contain byte sequences +that don't correspond to valid Unicode characters (e.g. unpaired UTF-16 +surrogates), but it does note that they may cause interoperability problems. +By default, this module accepts and outputs (when present in the original +:class:`str`) code points for such sequences. Infinite and NaN Number Values @@ -554,7 +577,7 @@ Repeated Names Within an Object ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The RFC specifies that the names within a JSON object should be unique, but -does not specify how repeated names in JSON objects should be handled. By +does not mandate how repeated names in JSON objects should be handled. By default, this module does not raise an exception; instead, it ignores all but the last name-value pair for a given name:: @@ -563,3 +586,110 @@ the last name-value pair for a given name:: {'x': 3} The *object_pairs_hook* parameter can be used to alter this behavior. + + +Top-level Non-Object, Non-Array Values +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The old version of JSON specified by the obsolete :rfc:`4627` required that +the top-level value of a JSON text must be either a JSON object or array +(Python :class:`dict` or :class:`list`), and could not be a JSON null, +boolean, number, or string value. :rfc:`7159` removed that restriction, and +this module does not and has never implemented that restriction in either its +serializer or its deserializer. + +Regardless, for maximum interoperability, you may wish to voluntarily adhere +to the restriction yourself. + + +Implementation Limitations +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Some JSON deserializer implementations may set limits on: + +* the size of accepted JSON texts +* the maximum level of nesting of JSON objects and arrays +* the range and precision of JSON numbers +* the content and maximum length of JSON strings + +This module does not impose any such limits beyond those of the relevant +Python datatypes themselves or the Python interpreter itself. + +When serializing to JSON, beware any such limitations in applications that may +consume your JSON. In particular, it is common for JSON numbers to be +deserialized into IEEE 754 double precision numbers and thus subject to that +representation's range and precision limitations. This is especially relevant +when serializing Python :class:`int` values of extremely large magnitude, or +when serializing instances of "exotic" numerical types such as +:class:`decimal.Decimal`. + +.. highlight:: bash +.. module:: json.tool + +.. _json-commandline: + +Command Line Interface +---------------------- + +The :mod:`json.tool` module provides a simple command line interface to validate +and pretty-print JSON objects. + +If the optional ``infile`` and ``outfile`` arguments are not +specified, :attr:`sys.stdin` and :attr:`sys.stdout` will be used respectively:: + + $ echo '{"json": "obj"}' | python -m json.tool + { + "json": "obj" + } + $ echo '{1.2:3.4}' | python -m json.tool + Expecting property name enclosed in double quotes: line 1 column 2 (char 1) + +.. versionchanged:: 3.5 + The output is now in the same order as the input. Use the + :option:`--sort-keys` option to sort the output of dictionaries + alphabetically by key. + +Command line options +^^^^^^^^^^^^^^^^^^^^ + +.. cmdoption:: infile + + The JSON file to be validated or pretty-printed:: + + $ python -m json.tool mp_films.json + [ + { + "title": "And Now for Something Completely Different", + "year": 1971 + }, + { + "title": "Monty Python and the Holy Grail", + "year": 1975 + } + ] + + If *infile* is not specified, read from :attr:`sys.stdin`. + +.. cmdoption:: outfile + + Write the output of the *infile* to the given *outfile*. Otherwise, write it + to :attr:`sys.stdout`. + +.. cmdoption:: --sort-keys + + Sort the output of dictionaries alphabetically by key. + + .. versionadded:: 3.5 + +.. cmdoption:: -h, --help + + Show the help message. + + +.. rubric:: Footnotes + +.. [#rfc-errata] As noted in `the errata for RFC 7159 + <http://www.rfc-editor.org/errata_search.php?rfc=7159>`_, + JSON permits literal U+2028 (LINE SEPARATOR) and + U+2029 (PARAGRAPH SEPARATOR) characters in strings, whereas JavaScript + (as of ECMAScript Edition 5.1) does not. diff --git a/Doc/library/linecache.rst b/Doc/library/linecache.rst index dacf8aa002a2..6c92cc58d2c2 100644 --- a/Doc/library/linecache.rst +++ b/Doc/library/linecache.rst @@ -9,11 +9,15 @@ -------------- -The :mod:`linecache` module allows one to get any line from any file, while +The :mod:`linecache` module allows one to get any line from a Python source file, while attempting to optimize internally, using a cache, the common case where many lines are read from a single file. This is used by the :mod:`traceback` module to retrieve source lines for inclusion in the formatted traceback. +The :func:`tokenize.open` function is used to open files. This +function uses :func:`tokenize.detect_encoding` to get the encoding of the +file; in the absence of an encoding token, the file encoding defaults to UTF-8. + The :mod:`linecache` module defines the following functions: @@ -43,10 +47,17 @@ The :mod:`linecache` module defines the following functions: changed on disk, and you require the updated version. If *filename* is omitted, it will check all the entries in the cache. +.. function:: lazycache(filename, module_globals) + + Capture enough detail about a non-file based module to permit getting its + lines later via :func:`getline` even if *module_globals* is None in the later + call. This avoids doing I/O until a line is actually needed, without having + to carry the module globals around indefinitely. + + .. versionadded:: 3.5 Example:: >>> import linecache - >>> linecache.getline('/etc/passwd', 4) - 'sys:x:3:3:sys:/dev:/bin/sh\n' - + >>> linecache.getline(linecache.__file__, 8) + 'import sys\n' diff --git a/Doc/library/locale.rst b/Doc/library/locale.rst index 9600193547e1..61b79faf328e 100644 --- a/Doc/library/locale.rst +++ b/Doc/library/locale.rst @@ -204,7 +204,7 @@ The :mod:`locale` module defines the following exception and functions: .. data:: RADIXCHAR - Get the radix character (decimal dot, decimal comma, etc.) + Get the radix character (decimal dot, decimal comma, etc.). .. data:: THOUSEP @@ -387,6 +387,14 @@ The :mod:`locale` module defines the following exception and functions: ``str(float)``, but takes the decimal point into account. +.. function:: delocalize(string) + + Converts a string into a normalized number string, following the + :const:`LC_NUMERIC` settings. + + .. versionadded:: 3.5 + + .. function:: atof(string) Converts a string to a floating point number, following the :const:`LC_NUMERIC` diff --git a/Doc/library/logging.config.rst b/Doc/library/logging.config.rst index 8c15ee27614c..fd6a47778fce 100644 --- a/Doc/library/logging.config.rst +++ b/Doc/library/logging.config.rst @@ -80,7 +80,9 @@ in :mod:`logging` itself) and defining handlers which are declared either in .. function:: fileConfig(fname, defaults=None, disable_existing_loggers=True) - Reads the logging configuration from a :mod:`configparser`\-format file. + Reads the logging configuration from a :mod:`configparser`\-format file. The + format of the file should be as described in + :ref:`logging-config-fileformat`. This function can be called several times from an application, allowing an end user to select from various pre-canned configurations (if the developer provides a mechanism to present the choices and load the chosen @@ -103,7 +105,7 @@ in :mod:`logging` itself) and defining handlers which are declared either in :param disable_existing_loggers: If specified as ``False``, loggers which exist when this call is made are left - alone. The default is ``True`` because this + enabled. The default is ``True`` because this enables old behaviour in a backward- compatible way. This behaviour is to disable any existing loggers unless they or @@ -146,7 +148,9 @@ in :mod:`logging` itself) and defining handlers which are declared either in send it to the socket as a string of bytes preceded by a four-byte length string packed in binary using ``struct.pack('>L', n)``. - .. note:: Because portions of the configuration are passed through + .. note:: + + Because portions of the configuration are passed through :func:`eval`, use of this function may open its users to a security risk. While the function only binds to a socket on ``localhost``, and so does not accept connections from remote machines, there are scenarios where @@ -611,6 +615,18 @@ called ``form01`` in the ``[formatters]`` section will have its configuration specified in a section called ``[formatter_form01]``. The root logger configuration must be specified in a section called ``[logger_root]``. +.. note:: + + The :func:`fileConfig` API is older than the :func:`dictConfig` API and does + not provide functionality to cover certain aspects of logging. For example, + you cannot configure :class:`~logging.Filter` objects, which provide for + filtering of messages beyond simple integer levels, using :func:`fileConfig`. + If you need to have instances of :class:`~logging.Filter` in your logging + configuration, you will need to use :func:`dictConfig`. Note that future + enhancements to configuration functionality will be added to + :func:`dictConfig`, so it's worth considering transitioning to this newer + API when it's convenient to do so. + Examples of these sections in the file are given below. :: [loggers] @@ -750,7 +766,9 @@ The ``class`` entry is optional. It indicates the name of the formatter's class :class:`~logging.Formatter` can present exception tracebacks in an expanded or condensed format. -.. note:: Due to the use of :func:`eval` as described above, there are +.. note:: + + Due to the use of :func:`eval` as described above, there are potential security risks which result from using the :func:`listen` to send and receive configurations via sockets. The risks are limited to where multiple users with no mutual trust run code on the same machine; see the diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index 315c168f1ddf..446a070a9d10 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -162,11 +162,19 @@ for this value. first call to :meth:`emit`. By default, the file grows indefinitely. + .. method:: reopenIfNeeded() + + Checks to see if the file has changed. If it has, the existing stream is + flushed and closed and the file opened again, typically as a precursor to + outputting the record to the file. + + .. versionadded:: 3.6 + + .. method:: emit(record) - Outputs the record to the file, but first checks to see if the file has - changed. If it has, the existing stream is flushed and closed and the - file opened again, before outputting the record to the file. + Outputs the record to the file, but first calls :meth:`reopenIfNeeded` to + reopen the file if it has changed. .. _base-rotating-handler: @@ -230,7 +238,7 @@ need to override. renamed to the destination. :param source: The source filename. This is normally the base - filename, e.g. 'test.log' + filename, e.g. 'test.log'. :param dest: The destination filename. This is normally what the source is rotated to, e.g. 'test.log.1'. @@ -269,15 +277,16 @@ module, supports rotation of disk log files. You can use the *maxBytes* and *backupCount* values to allow the file to :dfn:`rollover` at a predetermined size. When the size is about to be exceeded, the file is closed and a new file is silently opened for output. Rollover occurs - whenever the current log file is nearly *maxBytes* in length; if *maxBytes* is - zero, rollover never occurs. If *backupCount* is non-zero, the system will save - old log files by appending the extensions '.1', '.2' etc., to the filename. For - example, with a *backupCount* of 5 and a base file name of :file:`app.log`, you - would get :file:`app.log`, :file:`app.log.1`, :file:`app.log.2`, up to - :file:`app.log.5`. The file being written to is always :file:`app.log`. When - this file is filled, it is closed and renamed to :file:`app.log.1`, and if files - :file:`app.log.1`, :file:`app.log.2`, etc. exist, then they are renamed to - :file:`app.log.2`, :file:`app.log.3` etc. respectively. + whenever the current log file is nearly *maxBytes* in length; if either of + *maxBytes* or *backupCount* is zero, rollover never occurs. If *backupCount* + is non-zero, the system will save old log files by appending the extensions + '.1', '.2' etc., to the filename. For example, with a *backupCount* of 5 and + a base file name of :file:`app.log`, you would get :file:`app.log`, + :file:`app.log.1`, :file:`app.log.2`, up to :file:`app.log.5`. The file being + written to is always :file:`app.log`. When this file is filled, it is closed + and renamed to :file:`app.log.1`, and if files :file:`app.log.1`, + :file:`app.log.2`, etc. exist, then they are renamed to :file:`app.log.2`, + :file:`app.log.3` etc. respectively. .. method:: doRollover() @@ -435,7 +444,7 @@ sends logging output to a network socket. The base class uses a TCP socket. .. method:: createSocket() Tries to create a socket; on failure, uses an exponential back-off - algorithm. On intial failure, the handler will drop the message it was + algorithm. On initial failure, the handler will drop the message it was trying to send. When subsequent messages are handled by the same instance, it will not try connecting until some time has passed. The default parameters are such that the initial delay is one second, and if @@ -839,21 +848,43 @@ supports sending logging messages to a Web server, using either ``GET`` or ``POST`` semantics. -.. class:: HTTPHandler(host, url, method='GET', secure=False, credentials=None) +.. class:: HTTPHandler(host, url, method='GET', secure=False, credentials=None, context=None) Returns a new instance of the :class:`HTTPHandler` class. The *host* can be - of the form ``host:port``, should you need to use a specific port number. - If no *method* is specified, ``GET`` is used. If *secure* is true, an HTTPS - connection will be used. If *credentials* is specified, it should be a - 2-tuple consisting of userid and password, which will be placed in an HTTP + of the form ``host:port``, should you need to use a specific port number. If + no *method* is specified, ``GET`` is used. If *secure* is true, a HTTPS + connection will be used. The *context* parameter may be set to a + :class:`ssl.SSLContext` instance to configure the SSL settings used for the + HTTPS connection. If *credentials* is specified, it should be a 2-tuple + consisting of userid and password, which will be placed in a HTTP 'Authorization' header using Basic authentication. If you specify credentials, you should also specify secure=True so that your userid and password are not passed in cleartext across the wire. + .. versionchanged:: 3.5 + The *context* parameter was added. + + .. method:: mapLogRecord(record) + + Provides a dictionary, based on ``record``, which is to be URL-encoded + and sent to the web server. The default implementation just returns + ``record.__dict__``. This method can be overridden if e.g. only a + subset of :class:`~logging.LogRecord` is to be sent to the web server, or + if more specific customization of what's sent to the server is required. .. method:: emit(record) - Sends the record to the Web server as a percent-encoded dictionary. + Sends the record to the Web server as an URL-encoded dictionary. The + :meth:`mapLogRecord` method is used to convert the record to the + dictionary to be sent. + + .. note:: Since preparing a record for sending it to a Web server is not + the same as a generic formatting operation, using + :meth:`~logging.Handler.setFormatter` to specify a + :class:`~logging.Formatter` for a :class:`HTTPHandler` has no effect. + Instead of calling :meth:`~logging.Handler.format`, this handler calls + :meth:`mapLogRecord` and then :func:`urllib.parse.urlencode` to encode the + dictionary in a form suitable for sending to a Web server. .. _queue-handler: @@ -930,13 +961,20 @@ applications where threads servicing clients need to respond as quickly as possible, while any potentially slow operations (such as sending an email via :class:`SMTPHandler`) are done on a separate thread. -.. class:: QueueListener(queue, *handlers) +.. class:: QueueListener(queue, *handlers, respect_handler_level=False) Returns a new instance of the :class:`QueueListener` class. The instance is initialized with the queue to send messages to and a list of handlers which will handle entries placed on the queue. The queue can be any queue- like object; it's passed as-is to the :meth:`dequeue` method, which needs - to know how to get messages from it. + to know how to get messages from it. If ``respect_handler_level`` is ``True``, + a handler's level is respected (compared with the level for the message) when + deciding whether to pass messages to that handler; otherwise, the behaviour + is as in previous Python versions - to always pass each message to each + handler. + + .. versionchanged:: 3.5 + The ``respect_handler_levels`` argument was added. .. method:: dequeue(block) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 29e9617283e4..bf821abac16c 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -113,10 +113,14 @@ is the module's name in the Python package namespace. If the root is reached, and it has a level of NOTSET, then all messages will be processed. Otherwise, the root's level will be used as the effective level. + See :ref:`levels` for a list of levels. + .. versionchanged:: 3.2 The *lvl* parameter now accepts a string representation of the level such as 'INFO' as an alternative to the integer constants - such as :const:`INFO`. + such as :const:`INFO`. Note, however, that levels are internally stored + as integers, and methods such as e.g. :meth:`getEffectiveLevel` and + :meth:`isEnabledFor` will return/expect to be passed integers. .. method:: Logger.isEnabledFor(lvl) @@ -132,7 +136,9 @@ is the module's name in the Python package namespace. Indicates the effective level for this logger. If a value other than :const:`NOTSET` has been set using :meth:`setLevel`, it is returned. Otherwise, the hierarchy is traversed towards the root until a value other than - :const:`NOTSET` is found, and that value is returned. + :const:`NOTSET` is found, and that value is returned. The value returned is + an integer, typically one of :const:`logging.DEBUG`, :const:`logging.INFO` + etc. .. method:: Logger.getChild(suffix) @@ -153,11 +159,13 @@ is the module's name in the Python package namespace. *msg* using the string formatting operator. (Note that this means that you can use keywords in the format string, together with a single dictionary argument.) - There are three keyword arguments in *kwargs* which are inspected: *exc_info* - which, if it does not evaluate as false, causes exception information to be + There are three keyword arguments in *kwargs* which are inspected: + *exc_info*, *stack_info*, and *extra*. + + If *exc_info* does not evaluate as false, it causes exception information to be added to the logging message. If an exception tuple (in the format returned by - :func:`sys.exc_info`) is provided, it is used; otherwise, :func:`sys.exc_info` - is called to get the exception information. + :func:`sys.exc_info`) or an exception instance is provided, it is used; + otherwise, :func:`sys.exc_info` is called to get the exception information. The second optional keyword argument is *stack_info*, which defaults to ``False``. If true, stack information is added to the logging @@ -214,6 +222,9 @@ is the module's name in the Python package namespace. .. versionadded:: 3.2 The *stack_info* parameter was added. + .. versionchanged:: 3.5 + The *exc_info* parameter can now accept exception instances. + .. method:: Logger.info(msg, *args, **kwargs) @@ -248,7 +259,7 @@ is the module's name in the Python package namespace. interpreted as for :meth:`debug`. -.. method:: Logger.exception(msg, *args) +.. method:: Logger.exception(msg, *args, **kwargs) Logs a message with level :const:`ERROR` on this logger. The arguments are interpreted as for :meth:`debug`. Exception info is added to the logging @@ -316,6 +327,34 @@ is the module's name in the Python package namespace. .. versionadded:: 3.2 +.. _levels: + +Logging Levels +-------------- + +The numeric values of logging levels are given in the following table. These are +primarily of interest if you want to define your own levels, and need them to +have specific values relative to the predefined levels. If you define a level +with the same numeric value, it overwrites the predefined value; the predefined +name is lost. + ++--------------+---------------+ +| Level | Numeric value | ++==============+===============+ +| ``CRITICAL`` | 50 | ++--------------+---------------+ +| ``ERROR`` | 40 | ++--------------+---------------+ +| ``WARNING`` | 30 | ++--------------+---------------+ +| ``INFO`` | 20 | ++--------------+---------------+ +| ``DEBUG`` | 10 | ++--------------+---------------+ +| ``NOTSET`` | 0 | ++--------------+---------------+ + + .. _handler: Handler Objects @@ -356,6 +395,8 @@ subclasses. However, the :meth:`__init__` method in subclasses needs to call severe than *lvl* will be ignored. When a handler is created, the level is set to :const:`NOTSET` (which causes all messages to be processed). + See :ref:`levels` for a list of levels. + .. versionchanged:: 3.2 The *lvl* parameter now accepts a string representation of the level such as 'INFO' as an alternative to the integer constants @@ -445,7 +486,9 @@ Formatter Objects responsible for converting a :class:`LogRecord` to (usually) a string which can be interpreted by either a human or an external system. The base :class:`Formatter` allows a formatting string to be specified. If none is -supplied, the default value of ``'%(message)s'`` is used. +supplied, the default value of ``'%(message)s'`` is used, which just includes +the message in the logging call. To have additional items of information in the +formatted output (such as a timestamp), keep reading. A Formatter can be initialized with a format string which makes use of knowledge of the :class:`LogRecord` attributes - such as the default value mentioned above @@ -468,7 +511,8 @@ The useful mapping keys in a :class:`LogRecord` are given in the section on The *style* parameter can be one of '%', '{' or '$' and determines how the format string will be merged with its data: using one of %-formatting, - :meth:`str.format` or :class:`string.Template`. + :meth:`str.format` or :class:`string.Template`. See :ref:`formatting-styles` + for more information on using {- and $-formatting for log messages. .. versionchanged:: 3.2 The *style* parameter was added. @@ -777,7 +821,7 @@ LoggerAdapter Objects --------------------- :class:`LoggerAdapter` instances are used to conveniently pass contextual -information into logging calls. For a usage example , see the section on +information into logging calls. For a usage example, see the section on :ref:`adding contextual information to your logging output <context-info>`. .. class:: LoggerAdapter(logger, extra) @@ -959,7 +1003,7 @@ functions. are interpreted as for :func:`debug`. -.. function:: exception(msg, *args) +.. function:: exception(msg, *args, **kwargs) Logs a message with level :const:`ERROR` on the root logger. The arguments are interpreted as for :func:`debug`. Exception info is added to the logging @@ -970,14 +1014,15 @@ functions. Logs a message with level *level* on the root logger. The other arguments are interpreted as for :func:`debug`. - .. note:: The above module-level functions which delegate to the root - logger should *not* be used in threads, in versions of Python earlier - than 2.7.1 and 3.2, unless at least one handler has been added to the - root logger *before* the threads are started. These convenience functions - call :func:`basicConfig` to ensure that at least one handler is - available; in earlier versions of Python, this can (under rare - circumstances) lead to handlers being added multiple times to the root - logger, which can in turn lead to multiple messages for the same event. + .. note:: The above module-level convenience functions, which delegate to the + root logger, call :func:`basicConfig` to ensure that at least one handler + is available. Because of this, they should *not* be used in threads, + in versions of Python earlier than 2.7.1 and 3.2, unless at least one + handler has been added to the root logger *before* the threads are + started. In earlier versions of Python, due to a thread safety shortcoming + in :func:`basicConfig`, this can (under rare circumstances) lead to + handlers being added multiple times to the root logger, which can in turn + lead to multiple messages for the same event. .. function:: disable(lvl) @@ -1015,6 +1060,16 @@ functions. of the defined levels is passed in, the corresponding string representation is returned. Otherwise, the string 'Level %s' % lvl is returned. + .. note:: Levels are internally integers (as they need to be compared in the + logging logic). This function is used to convert between an integer level + and the level name displayed in the formatted log output by means of the + ``%(levelname)s`` format specifier (see :ref:`logrecord-attributes`). + + .. versionchanged:: 3.4 + In Python versions earlier than 3.4, this function could also be passed a + text level, and would return the corresponding numeric value of the level. + This undocumented behaviour was considered a mistake, and was removed in + Python 3.4, but reinstated in 3.4.2 due to retain backward compatibility. .. function:: makeLogRecord(attrdict) diff --git a/Doc/library/lzma.rst b/Doc/library/lzma.rst index 53fba89f1a66..054600530bcd 100644 --- a/Doc/library/lzma.rst +++ b/Doc/library/lzma.rst @@ -102,9 +102,18 @@ Reading and writing compressed files byte of data will be returned, unless EOF has been reached. The exact number of bytes returned is unspecified (the *size* argument is ignored). + .. note:: While calling :meth:`peek` does not change the file position of + the :class:`LZMAFile`, it may change the position of the underlying + file object (e.g. if the :class:`LZMAFile` was constructed by passing a + file object for *filename*). + .. versionchanged:: 3.4 Added support for the ``"x"`` and ``"xb"`` modes. + .. versionchanged:: 3.5 + The :meth:`~io.BufferedIOBase.read` method now accepts an argument of + ``None``. + Compressing and decompressing data in memory -------------------------------------------- @@ -216,13 +225,32 @@ Compressing and decompressing data in memory decompress a multi-stream input with :class:`LZMADecompressor`, you must create a new decompressor for each stream. - .. method:: decompress(data) + .. method:: decompress(data, max_length=-1) + + Decompress *data* (a :term:`bytes-like object`), returning + uncompressed data as bytes. Some of *data* may be buffered + internally, for use in later calls to :meth:`decompress`. The + returned data should be concatenated with the output of any + previous calls to :meth:`decompress`. + + 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, the :attr:`~.needs_input` attribute will + be set to ``False``. In this case, the next call to + :meth:`~.decompress` may provide *data* as ``b''`` to obtain + more of the output. - Decompress *data* (a :class:`bytes` object), returning a :class:`bytes` - object containing the decompressed data for at least part of the input. - Some of *data* may be buffered internally, for use in later calls to - :meth:`decompress`. The returned data should be concatenated with the - output of any previous calls to :meth:`decompress`. + 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), the :attr:`~.needs_input` attribute + 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 :attr:`~.unused_data` attribute. + + .. versionchanged:: 3.5 + Added the *max_length* parameter. .. attribute:: check @@ -240,6 +268,12 @@ Compressing and decompressing data in memory Before the end of the stream is reached, this will be ``b""``. + .. attribute:: needs_input + + ``False`` if the :meth:`.decompress` method can provide more + decompressed data before requiring new uncompressed input. + + .. versionadded:: 3.5 .. function:: compress(data, format=FORMAT_XZ, check=-1, preset=None, filters=None) diff --git a/Doc/library/mailbox.rst b/Doc/library/mailbox.rst index d668a6eacb3f..6334bd6e9882 100644 --- a/Doc/library/mailbox.rst +++ b/Doc/library/mailbox.rst @@ -202,7 +202,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF. .. versionchanged:: 3.2 The file object really is a binary file; previously it was incorrectly returned in text mode. Also, the file-like object now supports the - context manager protocol: you can use a :keyword:`with` statement to + context management protocol: you can use a :keyword:`with` statement to automatically close it. .. note:: @@ -487,7 +487,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF. `Configuring Netscape Mail on Unix: Why The Content-Length Format is Bad <http://www.jwz.org/doc/content-length.html>`_ An argument for using the original mbox format rather than a variation. - `"mbox" is a family of several mutually incompatible mailbox formats <http://homepages.tesco.net./~J.deBoynePollard/FGA/mail-mbox-formats.html>`_ + `"mbox" is a family of several mutually incompatible mailbox formats <http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/mail-mbox-formats.html>`_ A history of mbox variations. @@ -1550,7 +1550,7 @@ programs, mail loss due to interruption of the program, or premature termination due to malformed messages in the mailbox:: import mailbox - import email.Errors + import email.errors list_names = ('python-list', 'python-dev', 'python-bugs') @@ -1560,7 +1560,7 @@ due to malformed messages in the mailbox:: for key in inbox.iterkeys(): try: message = inbox[key] - except email.Errors.MessageParseError: + except email.errors.MessageParseError: continue # The message is malformed. Just leave it. for name in list_names: diff --git a/Doc/library/marshal.rst b/Doc/library/marshal.rst index 124eb6168e7e..af43944b2c92 100644 --- a/Doc/library/marshal.rst +++ b/Doc/library/marshal.rst @@ -106,7 +106,7 @@ In addition, the following constants are defined: format, version 1 shares interned strings and version 2 uses a binary format for floating point numbers. Version 3 adds support for object instancing and recursion. - The current version is 3. + The current version is 4. .. rubric:: Footnotes diff --git a/Doc/library/math.rst b/Doc/library/math.rst index 7c3ab596b9b2..244663eda9a9 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -36,9 +36,9 @@ Number-theoretic and representation functions .. function:: copysign(x, y) - Return *x* with the sign of *y*. On a platform that supports - signed zeros, ``copysign(1.0, -0.0)`` returns *-1.0*. - + Return a float with the magnitude (absolute value) of *x* but the sign of + *y*. On platforms that support signed zeros, ``copysign(1.0, -0.0)`` + returns *-1.0*. .. function:: fabs(x) @@ -100,6 +100,48 @@ Number-theoretic and representation functions <http://code.activestate.com/recipes/393090/>`_\. +.. function:: gcd(a, b) + + Return the greatest common divisor of the integers *a* and *b*. If either + *a* or *b* is nonzero, then the value of ``gcd(a, b)`` is the largest + positive integer that divides both *a* and *b*. ``gcd(0, 0)`` returns + ``0``. + + .. versionadded:: 3.5 + + +.. function:: isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0) + + Return ``True`` if the values *a* and *b* are close to each other and + ``False`` otherwise. + + Whether or not two values are considered close is determined according to + given absolute and relative tolerances. + + *rel_tol* is the relative tolerance -- it is the maximum allowed difference + between *a* and *b*, relative to the larger absolute value of *a* or *b*. + For example, to set a tolerance of 5%, pass ``rel_tol=0.05``. The default + tolerance is ``1e-09``, which assures that the two values are the same + within about 9 decimal digits. *rel_tol* must be greater than zero. + + *abs_tol* is the minimum absolute tolerance -- useful for comparisons near + zero. *abs_tol* must be at least zero. + + If no errors occur, the result will be: + ``abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)``. + + The IEEE 754 special values of ``NaN``, ``inf``, and ``-inf`` will be + handled according to IEEE rules. Specifically, ``NaN`` is not considered + close to any other value, including ``NaN``. ``inf`` and ``-inf`` are only + considered close to themselves. + + .. versionadded:: 3.5 + + .. seealso:: + + :pep:`485` -- A function for testing approximate equality + + .. function:: isfinite(x) Return ``True`` if *x* is neither an infinity nor a NaN, and @@ -280,12 +322,12 @@ Angular conversion .. function:: degrees(x) - Converts angle *x* from radians to degrees. + Convert angle *x* from radians to degrees. .. function:: radians(x) - Converts angle *x* from degrees to radians. + Convert angle *x* from degrees to radians. Hyperbolic functions -------------------- @@ -383,6 +425,22 @@ Constants The mathematical constant e = 2.718281..., to available precision. +.. data:: inf + + A floating-point positive infinity. (For negative infinity, use + ``-math.inf``.) Equivalent to the output of ``float('inf')``. + + .. versionadded:: 3.5 + + +.. data:: nan + + A floating-point "not a number" (NaN) value. Equivalent to the output of + ``float('nan')``. + + .. versionadded:: 3.5 + + .. impl-detail:: The :mod:`math` module consists mostly of thin wrappers around the platform C diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index 12c9eca6e853..8739ea3dcd26 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -44,7 +44,7 @@ the information :func:`init` sets up. The optional *strict* argument is a flag specifying whether the list of known MIME types is limited to only the official types `registered with IANA - <http://www.iana.org/assignments/media-types/>`_. + <http://www.iana.org/assignments/media-types/media-types.xhtml>`_. When *strict* is ``True`` (the default), only the IANA types are supported; when *strict* is ``False``, some additional non-standard but commonly used MIME types are also recognized. @@ -106,8 +106,8 @@ behavior of the module. extension is already known, the new type will replace the old one. When the type is already known the extension will be added to the list of known extensions. - When *strict* is ``True`` (the default), the mapping will added to the official MIME - types, otherwise to the non-standard ones. + When *strict* is ``True`` (the default), the mapping will be added to the + official MIME types, otherwise to the non-standard ones. .. data:: inited diff --git a/Doc/library/mmap.rst b/Doc/library/mmap.rst index 18e05e31f751..b74a8231ea92 100644 --- a/Doc/library/mmap.rst +++ b/Doc/library/mmap.rst @@ -174,6 +174,9 @@ To map anonymous memory, -1 should be passed as the fileno along with the length Optional arguments *start* and *end* are interpreted as in slice notation. Returns ``-1`` on failure. + .. versionchanged: 3.5 + Writable :term:`bytes-like object` is now accepted. + .. method:: flush([offset[, size]]) @@ -234,6 +237,9 @@ To map anonymous memory, -1 should be passed as the fileno along with the length Optional arguments *start* and *end* are interpreted as in slice notation. Returns ``-1`` on failure. + .. versionchanged: 3.5 + Writable :term:`bytes-like object` is now accepted. + .. method:: seek(pos[, whence]) @@ -261,6 +267,9 @@ To map anonymous memory, -1 should be passed as the fileno along with the length were written. If the mmap was created with :const:`ACCESS_READ`, then writing to it will raise a :exc:`TypeError` exception. + .. versionchanged: 3.5 + Writable :term:`bytes-like object` is now accepted. + .. method:: write_byte(byte) diff --git a/Doc/library/modulefinder.rst b/Doc/library/modulefinder.rst index 97ace60179aa..e84a4964a07e 100644 --- a/Doc/library/modulefinder.rst +++ b/Doc/library/modulefinder.rst @@ -53,7 +53,7 @@ report of the imported modules will be printed. .. attribute:: modules A dictionary mapping module names to modules. See - :ref:`modulefinder-example` + :ref:`modulefinder-example`. .. _modulefinder-example: @@ -104,7 +104,7 @@ Sample output (may vary depending on the architecture):: re: __module__,finditer,_expand itertools: __main__: re,itertools,baconhameggs - sre_parse: __getslice__,_PATTERNENDERS,SRE_FLAG_UNICODE + sre_parse: _PATTERNENDERS,SRE_FLAG_UNICODE array: types: __module__,IntType,TypeType --------------------------------------------------- diff --git a/Doc/library/modules.rst b/Doc/library/modules.rst index d89ef1062812..6b2a40a1b714 100644 --- a/Doc/library/modules.rst +++ b/Doc/library/modules.rst @@ -12,7 +12,6 @@ The full list of modules described in this chapter is: .. toctree:: - imp.rst zipimport.rst pkgutil.rst modulefinder.rst diff --git a/Doc/library/msilib.rst b/Doc/library/msilib.rst index d3451c844bc1..4145c8e7cc04 100644 --- a/Doc/library/msilib.rst +++ b/Doc/library/msilib.rst @@ -120,9 +120,9 @@ structures. .. seealso:: - `FCICreateFile <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devnotes/winprog/fcicreate.asp>`_ - `UuidCreate <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/uuidcreate.asp>`_ - `UuidToString <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/rpc/rpc/uuidtostring.asp>`_ + `FCICreateFile <http://msdn.microsoft.com/library?url=/library/en-us/devnotes/winprog/fcicreate.asp>`_ + `UuidCreate <http://msdn.microsoft.com/library?url=/library/en-us/rpc/rpc/uuidcreate.asp>`_ + `UuidToString <http://msdn.microsoft.com/library?url=/library/en-us/rpc/rpc/uuidtostring.asp>`_ .. _database-objects: @@ -151,9 +151,9 @@ Database Objects .. seealso:: - `MSIDatabaseOpenView <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msidatabaseopenview.asp>`_ - `MSIDatabaseCommit <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msidatabasecommit.asp>`_ - `MSIGetSummaryInformation <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msigetsummaryinformation.asp>`_ + `MSIDatabaseOpenView <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msidatabaseopenview.asp>`_ + `MSIDatabaseCommit <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msidatabasecommit.asp>`_ + `MSIGetSummaryInformation <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msigetsummaryinformation.asp>`_ .. _view-objects: @@ -199,11 +199,11 @@ View Objects .. seealso:: - `MsiViewExecute <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiviewexecute.asp>`_ - `MSIViewGetColumnInfo <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiviewgetcolumninfo.asp>`_ - `MsiViewFetch <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiviewfetch.asp>`_ - `MsiViewModify <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiviewmodify.asp>`_ - `MsiViewClose <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiviewclose.asp>`_ + `MsiViewExecute <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewexecute.asp>`_ + `MSIViewGetColumnInfo <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewgetcolumninfo.asp>`_ + `MsiViewFetch <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewfetch.asp>`_ + `MsiViewModify <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewmodify.asp>`_ + `MsiViewClose <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msiviewclose.asp>`_ .. _summary-objects: @@ -243,10 +243,10 @@ Summary Information Objects .. seealso:: - `MsiSummaryInfoGetProperty <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msisummaryinfogetproperty.asp>`_ - `MsiSummaryInfoGetPropertyCount <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msisummaryinfogetpropertycount.asp>`_ - `MsiSummaryInfoSetProperty <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msisummaryinfosetproperty.asp>`_ - `MsiSummaryInfoPersist <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msisummaryinfopersist.asp>`_ + `MsiSummaryInfoGetProperty <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msisummaryinfogetproperty.asp>`_ + `MsiSummaryInfoGetPropertyCount <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msisummaryinfogetpropertycount.asp>`_ + `MsiSummaryInfoSetProperty <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msisummaryinfosetproperty.asp>`_ + `MsiSummaryInfoPersist <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msisummaryinfopersist.asp>`_ .. _record-objects: @@ -297,11 +297,11 @@ Record Objects .. seealso:: - `MsiRecordGetFieldCount <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msirecordgetfieldcount.asp>`_ - `MsiRecordSetString <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msirecordsetstring.asp>`_ - `MsiRecordSetStream <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msirecordsetstream.asp>`_ - `MsiRecordSetInteger <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msirecordsetinteger.asp>`_ - `MsiRecordClear <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msirecordclear.asp>`_ + `MsiRecordGetFieldCount <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordgetfieldcount.asp>`_ + `MsiRecordSetString <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordsetstring.asp>`_ + `MsiRecordSetStream <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordsetstream.asp>`_ + `MsiRecordSetInteger <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordsetinteger.asp>`_ + `MsiRecordClear <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/msirecordclear.asp>`_ .. _msi-errors: @@ -393,10 +393,10 @@ Directory Objects .. seealso:: - `Directory Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/directory_table.asp>`_ - `File Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/file_table.asp>`_ - `Component Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/component_table.asp>`_ - `FeatureComponents Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/featurecomponents_table.asp>`_ + `Directory Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/directory_table.asp>`_ + `File Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/file_table.asp>`_ + `Component Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/component_table.asp>`_ + `FeatureComponents Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/featurecomponents_table.asp>`_ .. _features: @@ -421,7 +421,7 @@ Features .. seealso:: - `Feature Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/feature_table.asp>`_ + `Feature Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/feature_table.asp>`_ .. _msi-gui: @@ -516,13 +516,13 @@ for installing Python packages. .. seealso:: - `Dialog Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/dialog_table.asp>`_ - `Control Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/control_table.asp>`_ - `Control Types <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/controls.asp>`_ - `ControlCondition Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/controlcondition_table.asp>`_ - `ControlEvent Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/controlevent_table.asp>`_ - `EventMapping Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/eventmapping_table.asp>`_ - `RadioButton Table <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/radiobutton_table.asp>`_ + `Dialog Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/dialog_table.asp>`_ + `Control Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/control_table.asp>`_ + `Control Types <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/controls.asp>`_ + `ControlCondition Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/controlcondition_table.asp>`_ + `ControlEvent Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/controlevent_table.asp>`_ + `EventMapping Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/eventmapping_table.asp>`_ + `RadioButton Table <http://msdn.microsoft.com/library?url=/library/en-us/msi/setup/radiobutton_table.asp>`_ .. _msi-tables: diff --git a/Doc/library/msvcrt.rst b/Doc/library/msvcrt.rst index 9d23720e3225..fadaf05a09f0 100644 --- a/Doc/library/msvcrt.rst +++ b/Doc/library/msvcrt.rst @@ -18,7 +18,7 @@ documentation. The module implements both the normal and wide char variants of the console I/O api. The normal API deals only with ASCII characters and is of limited use for internationalized applications. The wide char API should be used where -ever possible +ever possible. .. versionchanged:: 3.3 Operations in this module now raise :exc:`OSError` where :exc:`IOError` diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 2c44dc923a1d..3c320cafc56b 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -16,41 +16,27 @@ to this, the :mod:`multiprocessing` module allows the programmer to fully leverage multiple processors on a given machine. It runs on both Unix and Windows. -.. note:: +The :mod:`multiprocessing` module also introduces APIs which do not have +analogs in the :mod:`threading` module. A prime example of this is the +:class:`~multiprocessing.pool.Pool` object which offers a convenient means of +parallelizing the execution of a function across multiple input values, +distributing the input data across processes (data parallelism). The following +example demonstrates the common practice of defining such functions in a module +so that child processes can successfully import that module. This basic example +of data parallelism using :class:`~multiprocessing.pool.Pool`, :: - Some of this package's functionality requires a functioning shared semaphore - implementation on the host operating system. Without one, the - :mod:`multiprocessing.synchronize` module will be disabled, and attempts to - import it will result in an :exc:`ImportError`. See - :issue:`3770` for additional information. + from multiprocessing import Pool -.. note:: + def f(x): + return x*x + + if __name__ == '__main__': + with Pool(5) as p: + print(p.map(f, [1, 2, 3])) - Functionality within this package requires that the ``__main__`` module be - importable by the children. This is covered in :ref:`multiprocessing-programming` - however it is worth pointing out here. This means that some examples, such - as the :class:`multiprocessing.pool.Pool` examples will not work in the - interactive interpreter. For example:: - - >>> from multiprocessing import Pool - >>> p = Pool(5) - >>> def f(x): - ... return x*x - ... - >>> p.map(f, [1,2,3]) - Process PoolWorker-1: - Process PoolWorker-2: - Process PoolWorker-3: - Traceback (most recent call last): - Traceback (most recent call last): - Traceback (most recent call last): - AttributeError: 'module' object has no attribute 'f' - AttributeError: 'module' object has no attribute 'f' - AttributeError: 'module' object has no attribute 'f' - - (If you try this it will actually output three full tracebacks - interleaved in a semi-random fashion, and then you may have to - stop the master process somehow.) +will print to standard output :: + + [1, 4, 9] The :class:`Process` class @@ -79,8 +65,7 @@ To show the individual process IDs involved, here is an expanded example:: def info(title): print(title) print('module name:', __name__) - if hasattr(os, 'getppid'): # only available on Unix - print('parent process:', os.getppid()) + print('parent process:', os.getppid()) print('process id:', os.getpid()) def f(name): @@ -101,6 +86,8 @@ necessary, see :ref:`multiprocessing-programming`. Contexts and start methods ~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. _multiprocessing-start-methods: + Depending on the platform, :mod:`multiprocessing` supports three ways to start a process. These *start methods* are @@ -134,9 +121,11 @@ to start a process. These *start methods* are Available on Unix platforms which support passing file descriptors over Unix pipes. -Before Python 3.4 *fork* was the only option available on Unix. Also, -prior to Python 3.4, child processes would inherit all the parents -inheritable handles on Windows. +.. versionchanged:: 3.4 + *spawn* added on all unix platforms, and *forkserver* added for + some unix platforms. + Child processes no longer inherit all of the parents inheritable + handles on Windows. On Unix using the *spawn* or *forkserver* start methods will also start a *semaphore tracker* process which tracks the unlinked named @@ -147,7 +136,7 @@ there may some "leaked" semaphores. (Unlinking the named semaphores is a serious matter since the system allows only a limited number, and they will not be automatically unlinked until the next reboot.) -To select the a start method you use the :func:`set_start_method` in +To select a start method you use the :func:`set_start_method` in the ``if __name__ == '__main__'`` clause of the main module. For example:: @@ -258,8 +247,10 @@ that only one process prints to standard output at a time:: def f(l, i): l.acquire() - print('hello world', i) - l.release() + try: + print('hello world', i) + finally: + l.release() if __name__ == '__main__': lock = Lock() @@ -392,7 +383,7 @@ For example:: print(res.get(timeout=1)) # prints "100" # make worker sleep for 10 secs - res = pool.apply_async(sleep, 10) + res = pool.apply_async(sleep, [10]) print(res.get(timeout=1)) # raises multiprocessing.TimeoutError # exiting the 'with'-block has stopped the pool @@ -400,6 +391,34 @@ For example:: Note that the methods of a pool should only ever be used by the process which created it. +.. note:: + + Functionality within this package requires that the ``__main__`` module be + importable by the children. This is covered in :ref:`multiprocessing-programming` + however it is worth pointing out here. This means that some examples, such + as the :class:`multiprocessing.pool.Pool` examples will not work in the + interactive interpreter. For example:: + + >>> from multiprocessing import Pool + >>> p = Pool(5) + >>> def f(x): + ... return x*x + ... + >>> p.map(f, [1,2,3]) + Process PoolWorker-1: + Process PoolWorker-2: + Process PoolWorker-3: + Traceback (most recent call last): + Traceback (most recent call last): + Traceback (most recent call last): + AttributeError: 'module' object has no attribute 'f' + AttributeError: 'module' object has no attribute 'f' + AttributeError: 'module' object has no attribute 'f' + + (If you try this it will actually output three full tracebacks + interleaved in a semi-random fashion, and then you may have to + stop the master process somehow.) + Reference --------- @@ -780,6 +799,14 @@ For an example of the usage of queues for interprocess communication see immediately without waiting to flush enqueued data to the underlying pipe, and you don't care about lost data. + .. note:: + + This class's functionality requires a functioning shared semaphore + implementation on the host operating system. Without one, the + functionality in this class will be disabled, and attempts to + instantiate a :class:`Queue` will result in an :exc:`ImportError`. See + :issue:`3770` for additional information. The same holds true for any + of the specialized queue types listed below. .. class:: SimpleQueue() @@ -836,13 +863,18 @@ Miscellaneous Return list of all live children of the current process. - Calling this has the side affect of "joining" any processes which have + Calling this has the side effect of "joining" any processes which have already finished. .. function:: cpu_count() - Return the number of CPUs in the system. May raise - :exc:`NotImplementedError`. + Return the number of CPUs in the system. + + 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))`` + + May raise :exc:`NotImplementedError`. .. seealso:: :func:`os.cpu_count` @@ -1040,7 +1072,7 @@ Connection objects are usually created using :func:`Pipe` -- see also using :meth:`Connection.send` and :meth:`Connection.recv`. .. versionadded:: 3.3 - Connection objects now support the context manager protocol -- see + Connection objects now support the context management protocol -- see :ref:`typecontextmanager`. :meth:`~contextmanager.__enter__` returns the connection object, and :meth:`~contextmanager.__exit__` calls :meth:`close`. @@ -1102,10 +1134,15 @@ object -- see :ref:`multiprocessing-managers`. .. class:: BoundedSemaphore([value]) - A bounded semaphore object: a clone of :class:`threading.BoundedSemaphore`. + A bounded semaphore object: a close analog of + :class:`threading.BoundedSemaphore`. - (On Mac OS X, this is indistinguishable from :class:`Semaphore` because - ``sem_getvalue()`` is not implemented on that platform). + A solitary difference from its close analog exists: its ``acquire`` method's + first argument is named *block*, as is consistent with :meth:`Lock.acquire`. + + .. note:: + On Mac OS X, this is indistinguishable from :class:`Semaphore` because + ``sem_getvalue()`` is not implemented on that platform. .. class:: Condition([lock]) @@ -1121,32 +1158,134 @@ object -- see :ref:`multiprocessing-managers`. A clone of :class:`threading.Event`. + .. class:: Lock() - A non-recursive lock object: a clone of :class:`threading.Lock`. + A non-recursive lock object: a close analog of :class:`threading.Lock`. + Once a process or thread has acquired a lock, subsequent attempts to + acquire it from any process or thread will block until it is released; + any process or thread may release it. The concepts and behaviors of + :class:`threading.Lock` as it applies to threads are replicated here in + :class:`multiprocessing.Lock` as it applies to either processes or threads, + except as noted. + + Note that :class:`Lock` is actually a factory function which returns an + instance of ``multiprocessing.synchronize.Lock`` initialized with a + default context. + + :class:`Lock` supports the :term:`context manager` protocol and thus may be + used in :keyword:`with` statements. + + .. method:: acquire(block=True, timeout=None) + + Acquire a lock, blocking or non-blocking. + + With the *block* argument set to ``True`` (the default), the method call + will block until the lock is in an unlocked state, then set it to locked + and return ``True``. Note that the name of this first argument differs + from that in :meth:`threading.Lock.acquire`. + + With the *block* argument set to ``False``, the method call does not + block. If the lock is currently in a locked state, return ``False``; + otherwise set the lock to a locked state and return ``True``. + + When invoked with a positive, floating-point value for *timeout*, block + for at most the number of seconds specified by *timeout* as long as + the lock can not be acquired. Invocations with a negative value for + *timeout* are equivalent to a *timeout* of zero. Invocations with a + *timeout* value of ``None`` (the default) set the timeout period to + infinite. Note that the treatment of negative or ``None`` values for + *timeout* differs from the implemented behavior in + :meth:`threading.Lock.acquire`. The *timeout* argument has no practical + implications if the *block* argument is set to ``False`` and is thus + ignored. Returns ``True`` if the lock has been acquired or ``False`` if + the timeout period has elapsed. + + + .. method:: release() + + Release a lock. This can be called from any process or thread, not only + the process or thread which originally acquired the lock. + + Behavior is the same as in :meth:`threading.Lock.release` except that + when invoked on an unlocked lock, a :exc:`ValueError` is raised. + .. class:: RLock() - A recursive lock object: a clone of :class:`threading.RLock`. + A recursive lock object: a close analog of :class:`threading.RLock`. A + recursive lock must be released by the process or thread that acquired it. + Once a process or thread has acquired a recursive lock, the same process + or thread may acquire it again without blocking; that process or thread + must release it once for each time it has been acquired. + + Note that :class:`RLock` is actually a factory function which returns an + instance of ``multiprocessing.synchronize.RLock`` initialized with a + default context. + + :class:`RLock` supports the :term:`context manager` protocol and thus may be + used in :keyword:`with` statements. + + + .. method:: acquire(block=True, timeout=None) + + Acquire a lock, blocking or non-blocking. + + When invoked with the *block* argument set to ``True``, block until the + lock is in an unlocked state (not owned by any process or thread) unless + the lock is already owned by the current process or thread. The current + process or thread then takes ownership of the lock (if it does not + already have ownership) and the recursion level inside the lock increments + by one, resulting in a return value of ``True``. Note that there are + several differences in this first argument's behavior compared to the + implementation of :meth:`threading.RLock.acquire`, starting with the name + of the argument itself. + + When invoked with the *block* argument set to ``False``, do not block. + If the lock has already been acquired (and thus is owned) by another + process or thread, the current process or thread does not take ownership + and the recursion level within the lock is not changed, resulting in + a return value of ``False``. If the lock is in an unlocked state, the + current process or thread takes ownership and the recursion level is + incremented, resulting in a return value of ``True``. + + Use and behaviors of the *timeout* argument are the same as in + :meth:`Lock.acquire`. Note that some of these behaviors of *timeout* + differ from the implemented behaviors in :meth:`threading.RLock.acquire`. + + + .. method:: release() + + Release a lock, decrementing the recursion level. If after the + decrement the recursion level is zero, reset the lock to unlocked (not + owned by any process or thread) and if any other processes or threads + are blocked waiting for the lock to become unlocked, allow exactly one + of them to proceed. If after the decrement the recursion level is still + nonzero, the lock remains locked and owned by the calling process or + thread. + + Only call this method when the calling process or thread owns the lock. + An :exc:`AssertionError` is raised if this method is called by a process + or thread other than the owner or if the lock is in an unlocked (unowned) + state. Note that the type of exception raised in this situation + differs from the implemented behavior in :meth:`threading.RLock.release`. + .. class:: Semaphore([value]) - A semaphore object: a clone of :class:`threading.Semaphore`. + A semaphore object: a close analog of :class:`threading.Semaphore`. -.. note:: + A solitary difference from its close analog exists: its ``acquire`` method's + first argument is named *block*, as is consistent with :meth:`Lock.acquire`. - The :meth:`acquire` and :meth:`wait` methods of each of these types - treat negative timeouts as zero timeouts. This differs from - :mod:`threading` where, since version 3.2, the equivalent - :meth:`acquire` methods treat negative timeouts as infinite - timeouts. +.. note:: On Mac OS X, ``sem_timedwait`` is unsupported, so calling ``acquire()`` with a timeout will emulate that function's behavior using a sleeping loop. .. note:: - If the SIGINT signal generated by Ctrl-C arrives while the main thread is + If the SIGINT signal generated by :kbd:`Ctrl-C` arrives while the main thread is blocked by a call to :meth:`BoundedSemaphore.acquire`, :meth:`Lock.acquire`, :meth:`RLock.acquire`, :meth:`Semaphore.acquire`, :meth:`Condition.acquire` or :meth:`Condition.wait` then the call will be immediately interrupted and @@ -1155,6 +1294,14 @@ object -- see :ref:`multiprocessing-managers`. This differs from the behaviour of :mod:`threading` where SIGINT will be ignored while the equivalent blocking calls are in progress. +.. note:: + + Some of this package's functionality requires a functioning shared semaphore + implementation on the host operating system. Without one, the + :mod:`multiprocessing.synchronize` module will be disabled, and attempts to + import it will result in an :exc:`ImportError`. See + :issue:`3770` for additional information. + Shared :mod:`ctypes` Objects ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1316,6 +1463,9 @@ processes. Note that accessing the ctypes object through the wrapper can be a lot slower than accessing the raw ctypes object. + .. versionchanged:: 3.5 + Synchronized objects support the :term:`context manager` protocol. + The table below compares the syntax for creating shared ctypes objects from shared memory with the normal ctypes syntax. (In the table ``MyStruct`` is some @@ -1472,7 +1622,7 @@ their parent process exits. The manager classes are defined in the *exposed* is used to specify a sequence of method names which proxies for this typeid should be allowed to access using - :meth:`BaseProxy._callMethod`. (If *exposed* is ``None`` then + :meth:`BaseProxy._callmethod`. (If *exposed* is ``None`` then :attr:`proxytype._exposed_` is used instead if it exists.) In the case where no exposed list is specified, all "public methods" of the shared object will be accessible. (Here a "public method" means any attribute @@ -1497,7 +1647,7 @@ their parent process exits. The manager classes are defined in the The address used by the manager. .. versionchanged:: 3.3 - Manager objects support the context manager protocol -- see + Manager objects support the context management protocol -- see :ref:`typecontextmanager`. :meth:`~contextmanager.__enter__` starts the server process (if it has not already started) and then returns the manager object. :meth:`~contextmanager.__exit__` calls :meth:`shutdown`. @@ -1794,7 +1944,7 @@ itself. This means, for example, that one shared object can contain a second: raised by :meth:`_callmethod`. Note in particular that an exception will be raised if *methodname* has - not been *exposed* + not been *exposed*. An example of the usage of :meth:`_callmethod`: @@ -1803,9 +1953,9 @@ itself. This means, for example, that one shared object can contain a second: >>> l = manager.list(range(10)) >>> l._callmethod('__len__') 10 - >>> l._callmethod('__getslice__', (2, 7)) # equiv to `l[2:7]` + >>> l._callmethod('__getitem__', (slice(2, 7),)) # equivalent to l[2:7] [2, 3, 4, 5, 6] - >>> l._callmethod('__getitem__', (20,)) # equiv to `l[20]` + >>> l._callmethod('__getitem__', (20,)) # equivalent to l[20] Traceback (most recent call last): ... IndexError: list index out of range @@ -1851,25 +2001,30 @@ with the :class:`Pool` class. callbacks and has a parallel map implementation. *processes* is the number of worker processes to use. If *processes* is - ``None`` then the number returned by :func:`os.cpu_count` is used. If - *initializer* is not ``None`` then each worker process will call + ``None`` then the number returned by :func:`os.cpu_count` is used. + + If *initializer* is not ``None`` then each worker process will call ``initializer(*initargs)`` when it starts. + *maxtasksperchild* is the number of tasks a worker process can complete + before it will exit and be replaced with a fresh worker process, to enable + unused resources to be freed. The default *maxtasksperchild* is None, which + means worker processes will live as long as the pool. + + *context* can be used to specify the context used for starting + the worker processes. Usually a pool is created using the + function :func:`multiprocessing.Pool` or the :meth:`Pool` method + of a context object. In both cases *context* is set + appropriately. + Note that the methods of the pool object should only be called by the process which created the pool. .. versionadded:: 3.2 - *maxtasksperchild* is the number of tasks a worker process can complete - before it will exit and be replaced with a fresh worker process, to enable - unused resources to be freed. The default *maxtasksperchild* is None, which - means worker processes will live as long as the pool. + *maxtasksperchild* .. versionadded:: 3.4 - *context* can be used to specify the context used for starting - the worker processes. Usually a pool is created using the - function :func:`multiprocessing.Pool` or the :meth:`Pool` method - of a context object. In both cases *context* is set - appropriately. + *context* .. note:: @@ -1895,7 +2050,7 @@ with the :class:`Pool` class. If *callback* is specified then it should be a callable which accepts a single argument. When the result becomes ready *callback* is applied to it, that is unless the call failed, in which case the *error_callback* - is applied instead + is applied instead. If *error_callback* is specified then it should be a callable which accepts a single argument. If the target function fails, then @@ -1920,7 +2075,7 @@ with the :class:`Pool` class. If *callback* is specified then it should be a callable which accepts a single argument. When the result becomes ready *callback* is applied to it, that is unless the call failed, in which case the *error_callback* - is applied instead + is applied instead. If *error_callback* is specified then it should be a callable which accepts a single argument. If the target function fails, then @@ -1951,18 +2106,18 @@ with the :class:`Pool` class. .. method:: starmap(func, iterable[, chunksize]) - Like :meth:`map` except that the elements of the `iterable` are expected + Like :meth:`map` except that the elements of the *iterable* are expected to be iterables that are unpacked as arguments. - Hence an `iterable` of `[(1,2), (3, 4)]` results in `[func(1,2), - func(3,4)]`. + Hence an *iterable* of ``[(1,2), (3, 4)]`` results in ``[func(1,2), + func(3,4)]``. .. versionadded:: 3.3 .. method:: starmap_async(func, iterable[, chunksize[, callback[, error_back]]]) A combination of :meth:`starmap` and :meth:`map_async` that iterates over - `iterable` of iterables and calls `func` with the iterables unpacked. + *iterable* of iterables and calls *func* with the iterables unpacked. Returns a result object. .. versionadded:: 3.3 @@ -1984,7 +2139,7 @@ with the :class:`Pool` class. :meth:`terminate` before using :meth:`join`. .. versionadded:: 3.3 - Pool objects now support the context manager protocol -- see + Pool objects now support the context management protocol -- see :ref:`typecontextmanager`. :meth:`~contextmanager.__enter__` returns the pool object, and :meth:`~contextmanager.__exit__` calls :meth:`terminate`. @@ -2157,7 +2312,7 @@ multiple connections at the same time. unavailable then it is ``None``. .. versionadded:: 3.3 - Listener objects now support the context manager protocol -- see + Listener objects now support the context management protocol -- see :ref:`typecontextmanager`. :meth:`~contextmanager.__enter__` returns the listener object, and :meth:`~contextmanager.__exit__` calls :meth:`close`. @@ -2453,7 +2608,7 @@ Joining processes that use queues items which have been put on the queue will eventually be removed before the process is joined. Otherwise you cannot be sure that processes which have put items on the queue will terminate. Remember also that non-daemonic - processes will be automatically be joined. + processes will be joined automatically. An example which will deadlock is the following:: @@ -2469,7 +2624,7 @@ Joining processes that use queues p.join() # this deadlocks obj = queue.get() - A fix here would be to swap the last two lines round (or simply remove the + A fix here would be to swap the last two lines (or simply remove the ``p.join()`` line). Explicitly pass resources to child processes diff --git a/Doc/library/nntplib.rst b/Doc/library/nntplib.rst index 0098041e1d98..3943f2c249dd 100644 --- a/Doc/library/nntplib.rst +++ b/Doc/library/nntplib.rst @@ -94,6 +94,7 @@ The module itself defines the following classes: port *port*. :class:`NNTP_SSL` objects have the same methods as :class:`NNTP` objects. If *port* is omitted, port 563 (NNTPS) is used. *ssl_context* is also optional, and is a :class:`~ssl.SSLContext` object. + Please read :ref:`ssl-security` for best practices. All other parameters behave the same as for :class:`NNTP`. Note that SSL-on-563 is discouraged per :rfc:`4642`, in favor of @@ -102,6 +103,10 @@ The module itself defines the following classes: .. versionadded:: 3.2 + .. versionchanged:: 3.4 + The class now supports hostname check with + :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see + :data:`ssl.HAS_SNI`). .. exception:: NNTPError @@ -230,9 +235,10 @@ tuples or objects that the method normally returns will be empty. .. method:: NNTP.starttls(ssl_context=None) - Send a ``STARTTLS`` command. The *ssl_context* argument is optional - and should be a :class:`ssl.SSLContext` object. This will enable - encryption on the NNTP connection. + Send a ``STARTTLS`` command. This will enable encryption on the NNTP + connection. The *ssl_context* argument is optional and should be a + :class:`ssl.SSLContext` object. Please read :ref:`ssl-security` for best + practices. Note that this may not be done after authentication information has been transmitted, and authentication occurs by default if possible during a @@ -241,6 +247,10 @@ tuples or objects that the method normally returns will be empty. .. versionadded:: 3.2 + .. versionchanged:: 3.4 + The method now supports hostname check with + :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see + :data:`ssl.HAS_SNI`). .. method:: NNTP.newgroups(date, *, file=None) diff --git a/Doc/library/numbers.rst b/Doc/library/numbers.rst index fec04ed722cf..8ab07d0b93d9 100644 --- a/Doc/library/numbers.rst +++ b/Doc/library/numbers.rst @@ -110,6 +110,8 @@ those. You can add ``MyFoo`` between :class:`Complex` and MyFoo.register(Real) +.. _implementing-the-arithmetic-operations: + Implementing the arithmetic operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/Doc/library/operator.rst b/Doc/library/operator.rst index 80bad7142c63..06953917e78d 100644 --- a/Doc/library/operator.rst +++ b/Doc/library/operator.rst @@ -138,6 +138,14 @@ The mathematical and bitwise operations are the most numerous: Return ``a * b``, for *a* and *b* numbers. +.. function:: matmul(a, b) + __matmul__(a, b) + + Return ``a @ b``. + + .. versionadded:: 3.5 + + .. function:: neg(obj) __neg__(obj) @@ -228,21 +236,12 @@ Operations which work with sequences (some of them with mappings too) include: Set the value of *a* at index *b* to *c*. -Example: Build a dictionary that maps the ordinals from ``0`` to ``255`` to -their character equivalents. - - >>> d = {} - >>> keys = range(256) - >>> vals = map(chr, keys) - >>> map(operator.setitem, [d]*len(keys), keys, vals) # doctest: +SKIP - -.. XXX: find a better, readable, example .. function:: length_hint(obj, default=0) - Return an estimated length for the object *o*. First trying to return its + Return an estimated length for the object *o*. First try to return its actual length, then an estimate using :meth:`object.__length_hint__`, and - finally returning the default value. + finally return the default value. .. versionadded:: 3.4 @@ -265,7 +264,7 @@ expect a function argument. ``(b.name, b.date)``. * After ``f = attrgetter('name.first', 'name.last')``, the call ``f(b)`` - returns ``(r.name.first, r.name.last)``. + returns ``(b.name.first, b.name.last)``. Equivalent to:: @@ -334,6 +333,21 @@ expect a function argument. [('orange', 1), ('banana', 2), ('apple', 3), ('pear', 5)] +.. data:: subscript + + A helper to turn subscript notation into indexing objects. This can be + used to create item access patterns ahead of time to pass them into + various subscriptable objects. + + For example: + + * ``subscript[5] == 5`` + * ``subscript[3:7:2] == slice(3, 7, 2)`` + * ``subscript[5, 8] == (5, 8)`` + + .. versionadded:: 3.6 + + .. function:: methodcaller(name[, args...]) Return a callable object that calls the method *name* on its operand. If @@ -400,6 +414,8 @@ Python syntax and the functions in the :mod:`operator` module. +-----------------------+-------------------------+---------------------------------------+ | Multiplication | ``a * b`` | ``mul(a, b)`` | +-----------------------+-------------------------+---------------------------------------+ +| Matrix Multiplication | ``a @ b`` | ``matmul(a, b)`` | ++-----------------------+-------------------------+---------------------------------------+ | Negation (Arithmetic) | ``- a`` | ``neg(a)`` | +-----------------------+-------------------------+---------------------------------------+ | Negation (Logical) | ``not a`` | ``not_(a)`` | @@ -508,6 +524,14 @@ will perform the update, so no subsequent assignment is necessary: ``a = imul(a, b)`` is equivalent to ``a *= b``. +.. function:: imatmul(a, b) + __imatmul__(a, b) + + ``a = imatmul(a, b)`` is equivalent to ``a @= b``. + + .. versionadded:: 3.5 + + .. function:: ior(a, b) __ior__(a, b) diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index 13395b636d44..72145aa59b5f 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -8,8 +8,8 @@ .. sectionauthor:: Greg Ward <gward@python.net> .. deprecated:: 3.2 - The :mod:`optparse` module is deprecated and will not be developed further; - development will continue with the :mod:`argparse` module. + The :mod:`optparse` module is deprecated and will not be developed further; + development will continue with the :mod:`argparse` module. **Source code:** :source:`Lib/optparse.py` diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst index 269856c62846..a3fe73c1523b 100644 --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -66,11 +66,37 @@ the :mod:`glob` module.) empty string (``''``). +.. function:: commonpath(paths) + + Return the longest common sub-path of each pathname in the sequence + *paths*. Raise ValueError if *paths* contains both absolute and relative + pathnames, or if *paths* is empty. Unlike :func:`commonprefix`, this + returns a valid path. + + Availability: Unix, Windows + + .. versionadded:: 3.5 + + .. function:: commonprefix(list) - Return the longest path prefix (taken character-by-character) that is a prefix - of all paths in *list*. If *list* is empty, return the empty string (``''``). - Note that this may return invalid paths because it works a character at a time. + Return the longest path prefix (taken character-by-character) that is a + prefix of all paths in *list*. If *list* is empty, return the empty string + (``''``). + + .. note:: + + This function may return invalid paths because it works a + character at a time. To obtain a valid path, see + :func:`commonpath`. + + :: + + >>> os.path.commonprefix(['/usr/lib', '/usr/local/lib']) + '/usr/l' + + >>> os.path.commonpath(['/usr/lib', '/usr/local/lib']) + '/usr' .. function:: dirname(path) @@ -188,29 +214,40 @@ the :mod:`glob` module.) .. function:: islink(path) Return ``True`` if *path* refers to a directory entry that is a symbolic link. - Always ``False`` if symbolic links are not supported. + Always ``False`` if symbolic links are not supported by the python runtime. .. function:: ismount(path) - Return ``True`` if pathname *path* is a :dfn:`mount point`: a point in a file - system where a different file system has been mounted. The function checks - whether *path*'s parent, :file:`path/..`, is on a different device than *path*, - or whether :file:`path/..` and *path* point to the same i-node on the same - device --- this should detect mount points for all Unix and POSIX variants. + Return ``True`` if pathname *path* is a :dfn:`mount point`: a point in a + file system where a different file system has been mounted. On POSIX, the + function checks whether *path*'s parent, :file:`path/..`, is on a different + device than *path*, or whether :file:`path/..` and *path* point to the same + i-node on the same device --- this should detect mount points for all Unix + and POSIX variants. On Windows, a drive letter root and a share UNC are + always mount points, and for any other path ``GetVolumePathName`` is called + to see if it is different from the input path. + + .. versionadded:: 3.4 + Support for detecting non-root mount points on Windows. + +.. function:: join(path, *paths) -.. function:: join(path1[, path2[, ...]]) + Join one or more path components intelligently. The return value is the + concatenation of *path* and any members of *\*paths* with exactly one + directory separator (``os.sep``) following each non-empty part except the + last, meaning that the result will only end in a separator if the last + part is empty. If a component is an absolute path, all previous + components are thrown away and joining continues from the absolute path + component. - Join one or more path components intelligently. If any component is an absolute - path, all previous components (on Windows, including the previous drive letter, - if there was one) are thrown away, and joining continues. The return value is - the concatenation of *path1*, and optionally *path2*, etc., with exactly one - directory separator (``os.sep``) following each non-empty part except the last. - (This means that an empty last part will result in a path that ends with a - separator.) Note that on Windows, since there is a current directory for - each drive, ``os.path.join("c:", "foo")`` represents a path relative to the - current directory on drive :file:`C:` (:file:`c:foo`), not :file:`c:\\foo`. + On Windows, the drive letter is not reset when an absolute path component + (e.g., ``r'\foo'``) is encountered. If a component contains a drive + letter, all previous components are thrown away and the drive letter is + reset. Note that since there is a current directory for each drive, + ``os.path.join("c:", "foo")`` represents a path relative to the current + directory on drive :file:`C:` (:file:`c:foo`), not :file:`c:\\foo`. .. function:: normcase(path) @@ -236,7 +273,7 @@ the :mod:`glob` module.) links encountered in the path (if they are supported by the operating system). -.. function:: relpath(path, start=None) +.. function:: relpath(path, start=os.curdir) Return a relative filepath to *path* either from the current directory or from an optional *start* directory. This is a path computation: the @@ -251,7 +288,7 @@ the :mod:`glob` module.) .. function:: samefile(path1, path2) Return ``True`` if both pathname arguments refer to the same file or directory. - On Unix, this is determined by the device number and i-node number and raises an + This is determined by the device number and i-node number and raises an exception if a :func:`os.stat` call on either pathname fails. Availability: Unix, Windows. diff --git a/Doc/library/os.rst b/Doc/library/os.rst index f5f2e16f2e5e..dcd5e65aad51 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -53,7 +53,7 @@ Notes on the availability of these functions: .. data:: name The name of the operating system dependent module imported. The following - names have currently been registered: ``'posix'``, ``'nt'``, ``'mac'``, + names have currently been registered: ``'posix'``, ``'nt'``, ``'ce'``, ``'java'``. .. seealso:: @@ -65,6 +65,7 @@ Notes on the availability of these functions: .. _os-filenames: +.. _filesystem-encoding: File Names, Command Line Arguments, and Environment Variables ------------------------------------------------------------- @@ -77,9 +78,10 @@ uses the file system encoding to perform this conversion (see .. versionchanged:: 3.1 On some systems, conversion using the file system encoding may fail. In this - case, Python uses the ``surrogateescape`` encoding error handler, which means - that undecodable bytes are replaced by a Unicode character U+DCxx on - decoding, and these are again translated to the original byte on encoding. + case, Python uses the :ref:`surrogateescape encoding error handler + <surrogateescape>`, which means that undecodable bytes are replaced by a + Unicode character U+DCxx on decoding, and these are again translated to the + original byte on encoding. The file system encoding must guarantee to successfully decode all bytes @@ -260,7 +262,9 @@ process and user. Availability: Unix. - .. note:: On Mac OS X, :func:`getgroups` behavior differs somewhat from + .. note:: + + On Mac OS X, :func:`getgroups` behavior differs somewhat from other Unix platforms. If the Python interpreter was built with a deployment target of :const:`10.5` or earlier, :func:`getgroups` returns the list of effective group ids associated with the current user process; @@ -278,10 +282,10 @@ process and user. .. function:: getlogin() Return the name of the user logged in on the controlling terminal of the - process. For most purposes, it is more useful to use the environment variables - :envvar:`LOGNAME` or :envvar:`USERNAME` to find out who the user is, or - ``pwd.getpwuid(os.getuid())[0]`` to get the login name of the currently - effective user id. + process. For most purposes, it is more useful to use the environment + variables :envvar:`LOGNAME` or :envvar:`USERNAME` to find out who the user + is, or ``pwd.getpwuid(os.getuid())[0]`` to get the login name of the current + real user id. Availability: Unix, Windows. @@ -308,8 +312,6 @@ process and user. Return the current process id. - Availability: Unix, Windows. - .. function:: getppid() @@ -377,7 +379,7 @@ process and user. .. index:: single: user; id - Return the current process's user id. + Return the current process's real user id. Availability: Unix. @@ -546,8 +548,6 @@ process and user. On platforms where :c:func:`strerror` returns ``NULL`` when given an unknown error number, :exc:`ValueError` is raised. - Availability: Unix, Windows. - .. data:: supports_bytes_environ @@ -561,8 +561,6 @@ process and user. Set the current numeric umask and return the previous umask. - Availability: Unix, Windows. - .. function:: uname() @@ -653,8 +651,6 @@ as internal buffering of data. Close file descriptor *fd*. - Availability: Unix, Windows. - .. note:: This function is intended for low-level I/O and must be applied to a file @@ -674,8 +670,6 @@ as internal buffering of data. except OSError: pass - Availability: Unix, Windows. - .. function:: device_encoding(fd) @@ -692,8 +686,6 @@ as internal buffering of data. 2: stderr), the new file descriptor is :ref:`inheritable <fd_inheritance>`. - Availability: Unix, Windows. - .. versionchanged:: 3.4 The new file descriptor is now non-inheritable. @@ -704,8 +696,6 @@ as internal buffering of data. The file descriptor *fd2* is :ref:`inheritable <fd_inheritance>` by default, or non-inheritable if *inheritable* is ``False``. - Availability: Unix, Windows. - .. versionchanged:: 3.4 Add the optional *inheritable* parameter. @@ -762,10 +752,14 @@ as internal buffering of data. .. function:: fstat(fd) - Return status for file descriptor *fd*, like :func:`~os.stat`. As of Python - 3.3, this is equivalent to ``os.stat(fd)``. + Get the status of the file descriptor *fd*. Return a :class:`stat_result` + object. - Availability: Unix, Windows. + As of Python 3.3, this is equivalent to ``os.stat(fd)``. + + .. seealso:: + + The :func:`.stat` function. .. function:: fstatvfs(fd) @@ -795,8 +789,21 @@ as internal buffering of data. most *length* bytes in size. As of Python 3.3, this is equivalent to ``os.truncate(fd, length)``. + Availability: Unix, Windows. + + .. versionchanged:: 3.5 + Added support for Windows + +.. function:: get_blocking(fd) + + Get the blocking mode of the file descriptor: ``False`` if the + :data:`O_NONBLOCK` flag is set, ``True`` if the flag is cleared. + + See also :func:`set_blocking` and :meth:`socket.socket.setblocking`. + Availability: Unix. + .. versionadded:: 3.5 .. function:: isatty(fd) @@ -837,8 +844,6 @@ as internal buffering of data. current position; :const:`SEEK_END` or ``2`` to set it relative to the end of the file. Return the new cursor position in bytes, starting from the beginning. - Availability: Unix, Windows. - .. data:: SEEK_SET SEEK_CUR @@ -847,16 +852,14 @@ as internal buffering of data. Parameters to the :func:`lseek` function. Their values are 0, 1, and 2, respectively. - Availability: Unix, Windows. - .. versionadded:: 3.3 Some operating systems could support additional values, like :data:`os.SEEK_HOLE` or :data:`os.SEEK_DATA`. -.. function:: open(file, flags, mode=0o777, *, dir_fd=None) +.. function:: open(path, flags, mode=0o777, *, dir_fd=None) - Open the file *file* and set various flags according to *flags* and possibly + Open the file *path* and set various flags according to *flags* and possibly its mode according to *mode*. When computing *mode*, the current umask value is first masked out. Return the file descriptor for the newly opened file. The new file descriptor is :ref:`non-inheritable <fd_inheritance>`. @@ -869,8 +872,6 @@ as internal buffering of data. This function can support :ref:`paths relative to directory descriptors <dir_fd>` with the *dir_fd* parameter. - Availability: Unix, Windows. - .. versionchanged:: 3.4 The new file descriptor is now non-inheritable. @@ -884,6 +885,11 @@ as internal buffering of data. .. versionadded:: 3.3 The *dir_fd* argument. + .. versionchanged:: 3.5 + If the system call is interrupted and the signal handler does not raise an + exception, the function now retries the system call instead of raising an + :exc:`InterruptedError` exception (see :pep:`475` for the rationale). + The following constants are options for the *flags* parameter to the :func:`~os.open` function. They can be combined using the bitwise OR operator ``|``. Some of them are not available on all platforms. For descriptions of @@ -940,8 +946,9 @@ or `the MSDN <http://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Window the C library. .. versionchanged:: 3.4 - Add :data:`O_TMPFILE` constant. It's only available on Linux Kernel 3.11 - or newer. + Add :data:`O_PATH` on systems that support it. + Add :data:`O_TMPFILE`, only available on Linux Kernel 3.11 + or newer. .. function:: openpty() @@ -1034,10 +1041,10 @@ or `the MSDN <http://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Window .. versionadded:: 3.3 -.. function:: pwrite(fd, string, offset) +.. function:: pwrite(fd, str, offset) - Write *string* to a file descriptor, *fd*, from *offset*, leaving the file - offset unchanged. + Write *bytestring* to a file descriptor, *fd*, from *offset*, + leaving the file offset unchanged. Availability: Unix. @@ -1050,8 +1057,6 @@ or `the MSDN <http://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Window bytes read. If the end of the file referred to by *fd* has been reached, an empty bytes object is returned. - Availability: Unix, Windows. - .. note:: This function is intended for low-level I/O and must be applied to a file @@ -1060,11 +1065,16 @@ or `the MSDN <http://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Window :func:`popen` or :func:`fdopen`, or :data:`sys.stdin`, use its :meth:`~file.read` or :meth:`~file.readline` methods. + .. versionchanged:: 3.5 + If the system call is interrupted and the signal handler does not raise an + exception, the function now retries the system call instead of raising an + :exc:`InterruptedError` exception (see :pep:`475` for the rationale). + -.. function:: sendfile(out, in, offset, nbytes) - sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0) +.. function:: sendfile(out, in, offset, count) + sendfile(out, in, offset, count, [headers], [trailers], flags=0) - Copy *nbytes* bytes from file descriptor *in* to file descriptor *out* + Copy *count* bytes from file descriptor *in* to file descriptor *out* starting at *offset*. Return the number of bytes sent. When EOF is reached return 0. @@ -1078,17 +1088,37 @@ or `the MSDN <http://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Window *trailers* are arbitrary sequences of buffers that are written before and after the data from *in* is written. It returns the same as the first case. - On Mac OS X and FreeBSD, a value of 0 for *nbytes* specifies to send until + On Mac OS X and FreeBSD, a value of 0 for *count* specifies to send until the end of *in* is reached. All platforms support sockets as *out* file descriptor, and some platforms allow other types (e.g. regular file, pipe) as well. + Cross-platform applications should not use *headers*, *trailers* and *flags* + arguments. + Availability: Unix. + .. note:: + + For a higher-level wrapper of :func:`sendfile`, see + :meth:`socket.socket.sendfile`. + .. versionadded:: 3.3 +.. function:: set_blocking(fd, blocking) + + Set the blocking mode of the specified file descriptor. Set the + :data:`O_NONBLOCK` flag if blocking is ``False``, clear the flag otherwise. + + See also :func:`get_blocking` and :meth:`socket.socket.setblocking`. + + Availability: Unix. + + .. versionadded:: 3.5 + + .. data:: SF_NODISKIO SF_MNOWAIT SF_SYNC @@ -1103,9 +1133,12 @@ or `the MSDN <http://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Window .. function:: readv(fd, buffers) - Read from a file descriptor into a number of writable buffers. *buffers* is - an arbitrary sequence of writable buffers. Returns the total number of bytes - read. + Read from a file descriptor *fd* into a number of mutable :term:`bytes-like + objects <bytes-like object>` *buffers*. :func:`~os.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. :func:`~os.readv` returns the total + number of bytes read (which may be less than the total capacity of all the + objects). Availability: Unix. @@ -1142,8 +1175,6 @@ or `the MSDN <http://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Window Write the bytestring in *str* to file descriptor *fd*. Return the number of bytes actually written. - Availability: Unix, Windows. - .. note:: This function is intended for low-level I/O and must be applied to a file @@ -1152,12 +1183,18 @@ or `the MSDN <http://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Window :func:`fdopen`, or :data:`sys.stdout` or :data:`sys.stderr`, use its :meth:`~file.write` method. + .. versionchanged:: 3.5 + If the system call is interrupted and the signal handler does not raise an + exception, the function now retries the system call instead of raising an + :exc:`InterruptedError` exception (see :pep:`475` for the rationale). + .. function:: writev(fd, buffers) - Write the contents of *buffers* to file descriptor *fd*, where *buffers* - is an arbitrary sequence of buffers. - Returns the total number of bytes written. + Write the contents of *buffers* to file descriptor *fd*. *buffers* must be a + sequence of :term:`bytes-like objects <bytes-like object>`. + :func:`~os.writev` writes the contents of each object to the file descriptor + and returns the total number of bytes written. Availability: Unix. @@ -1313,8 +1350,6 @@ features: or not it is available using :data:`os.supports_effective_ids`. If it is unavailable, using it will raise a :exc:`NotImplementedError`. - Availability: Unix, Windows. - .. note:: Using :func:`access` to check if a user is authorized to e.g. open a file @@ -1367,8 +1402,6 @@ features: This function can support :ref:`specifying a file descriptor <path_fd>`. The descriptor must refer to an opened directory, not an open file. - Availability: Unix, Windows. - .. versionadded:: 3.3 Added support for specifying *path* as a file descriptor on some platforms. @@ -1430,8 +1463,6 @@ features: :ref:`paths relative to directory descriptors <dir_fd>` and :ref:`not following symlinks <follow_symlinks>`. - Availability: Unix, Windows. - .. note:: Although Windows supports :func:`chmod`, you can only set the file's @@ -1482,15 +1513,11 @@ features: Return a string representing the current working directory. - Availability: Unix, Windows. - .. function:: getcwdb() Return a bytestring representing the current working directory. - Availability: Unix, Windows. - .. function:: lchflags(path, flags) @@ -1553,7 +1580,11 @@ features: .. note:: To encode ``str`` filenames to ``bytes``, use :func:`~os.fsencode`. - Availability: Unix, Windows. + .. seealso:: + + The :func:`scandir` function returns directory entries along with + file attribute information, giving better performance for many + common use cases. .. versionchanged:: 3.2 The *path* parameter became optional. @@ -1562,17 +1593,25 @@ features: Added support for specifying an open file descriptor for *path*. -.. function:: lstat(path, *, dir_fd=None) +.. function:: lstat(path, \*, dir_fd=None) Perform the equivalent of an :c:func:`lstat` system call on the given path. - Similar to :func:`~os.stat`, but does not follow symbolic links. On - platforms that do not support symbolic links, this is an alias for - :func:`~os.stat`. As of Python 3.3, this is equivalent to ``os.stat(path, - dir_fd=dir_fd, follow_symlinks=False)``. + Similar to :func:`~os.stat`, but does not follow symbolic links. Return a + :class:`stat_result` object. + + On platforms that do not support symbolic links, this is an alias for + :func:`~os.stat`. + + As of Python 3.3, this is equivalent to ``os.stat(path, dir_fd=dir_fd, + follow_symlinks=False)``. This function can also support :ref:`paths relative to directory descriptors <dir_fd>`. + .. seealso:: + + The :func:`.stat` function. + .. versionchanged:: 3.2 Added support for Windows 6.0 (Vista) symbolic links. @@ -1594,13 +1633,11 @@ features: It is also possible to create temporary directories; see the :mod:`tempfile` module's :func:`tempfile.mkdtemp` function. - Availability: Unix, Windows. - .. versionadded:: 3.3 The *dir_fd* argument. -.. function:: makedirs(path, mode=0o777, exist_ok=False) +.. function:: makedirs(name, mode=0o777, exist_ok=False) .. index:: single: directory; creating @@ -1612,11 +1649,8 @@ features: The default *mode* is ``0o777`` (octal). On some systems, *mode* is ignored. Where it is used, the current umask value is first masked out. - If *exist_ok* is ``False`` (the default), an :exc:`OSError` is raised if - the target directory already exists. If *exist_ok* is ``True`` an - :exc:`OSError` is still raised if the umask-masked *mode* is different from - the existing mode, on systems where the mode is used. :exc:`OSError` will - also be raised if the directory creation fails. + If *exist_ok* is ``False`` (the default), an :exc:`OSError` is raised if the + target directory already exists. .. note:: @@ -1628,6 +1662,13 @@ features: .. versionadded:: 3.2 The *exist_ok* parameter. + .. versionchanged:: 3.4.1 + + Before Python 3.4.1, if *exist_ok* was ``True`` and the directory existed, + :func:`makedirs` would still raise an error if *mode* did not match the + mode of the existing directory. Since this behavior was impossible to + implement safely, it was removed in Python 3.4.1. See :issue:`21082`. + .. function:: mkfifo(path, mode=0o666, *, dir_fd=None) @@ -1649,10 +1690,10 @@ features: The *dir_fd* argument. -.. function:: mknod(filename, mode=0o600, device=0, *, dir_fd=None) +.. function:: mknod(path, mode=0o600, device=0, *, dir_fd=None) Create a filesystem node (file, device special file or named pipe) named - *filename*. *mode* specifies both the permissions to use and the type of node + *path*. *mode* specifies both the permissions to use and the type of node to be created, being combined (bitwise OR) with one of ``stat.S_IFREG``, ``stat.S_IFCHR``, ``stat.S_IFBLK``, and ``stat.S_IFIFO`` (those constants are available in :mod:`stat`). For ``stat.S_IFCHR`` and ``stat.S_IFBLK``, @@ -1750,13 +1791,11 @@ features: This function is identical to :func:`unlink`. - Availability: Unix, Windows. - .. versionadded:: 3.3 The *dir_fd* argument. -.. function:: removedirs(path) +.. function:: removedirs(name) .. index:: single: directory; deleting @@ -1785,8 +1824,6 @@ features: If you want cross-platform overwriting of the destination, use :func:`replace`. - Availability: Unix, Windows. - .. versionadded:: 3.3 The *src_dir_fd* and *dst_dir_fd* arguments. @@ -1815,8 +1852,6 @@ features: This function can support specifying *src_dir_fd* and/or *dst_dir_fd* to supply :ref:`paths relative to directory descriptors <dir_fd>`. - Availability: Unix, Windows. - .. versionadded:: 3.3 @@ -1829,61 +1864,288 @@ features: This function can support :ref:`paths relative to directory descriptors <dir_fd>`. - Availability: Unix, Windows. - .. versionadded:: 3.3 The *dir_fd* parameter. -.. function:: stat(path, *, dir_fd=None, follow_symlinks=True) - - Perform the equivalent of a :c:func:`stat` system call on the given path. - *path* may be specified as either a string or as an open file descriptor. - (This function normally follows symlinks; to stat a symlink add the argument - ``follow_symlinks=False``, or use :func:`lstat`.) - - The return value is an object whose attributes correspond roughly - to the members of the :c:type:`stat` structure, namely: - - * :attr:`st_mode` - protection bits, - * :attr:`st_ino` - inode number, - * :attr:`st_dev` - device, - * :attr:`st_nlink` - number of hard links, - * :attr:`st_uid` - user id of owner, - * :attr:`st_gid` - group id of owner, - * :attr:`st_size` - size of file, in bytes, - * :attr:`st_atime` - time of most recent access expressed in seconds, - * :attr:`st_mtime` - time of most recent content modification - expressed in seconds, - * :attr:`st_ctime` - platform dependent; time of most recent metadata - change on Unix, or the time of creation on Windows, expressed in seconds - * :attr:`st_atime_ns` - time of most recent access - expressed in nanoseconds as an integer, - * :attr:`st_mtime_ns` - time of most recent content modification - expressed in nanoseconds as an integer, - * :attr:`st_ctime_ns` - platform dependent; time of most recent metadata - change on Unix, or the time of creation on Windows, - expressed in nanoseconds as an integer +.. function:: scandir(path='.') - On some Unix systems (such as Linux), the following attributes may also be - available: + Return an iterator of :class:`DirEntry` objects corresponding to the entries + in the directory given by *path*. The entries are yielded in arbitrary + order, and the special entries ``'.'`` and ``'..'`` are not included. - * :attr:`st_blocks` - number of 512-byte blocks allocated for file - * :attr:`st_blksize` - filesystem blocksize for efficient file system I/O - * :attr:`st_rdev` - type of device if an inode device - * :attr:`st_flags` - user defined flags for file + Using :func:`scandir` instead of :func:`listdir` can significantly + increase the performance of code that also needs file type or file + attribute information, because :class:`DirEntry` objects expose this + information if the operating system provides it when scanning a directory. + All :class:`DirEntry` methods may perform a system call, but + :func:`~DirEntry.is_dir` and :func:`~DirEntry.is_file` usually only + require a system call for symbolic links; :func:`DirEntry.stat` + always requires a system call on Unix but only requires one for + symbolic links on Windows. - On other Unix systems (such as FreeBSD), the following attributes may be - available (but may be only filled out if root tries to use them): + On Unix, *path* can be of type :class:`str` or :class:`bytes` (use + :func:`~os.fsencode` and :func:`~os.fsdecode` to encode and decode + :class:`bytes` paths). On Windows, *path* must be of type :class:`str`. + On both sytems, the type of the :attr:`~DirEntry.name` and + :attr:`~DirEntry.path` attributes of each :class:`DirEntry` will be of + the same type as *path*. - * :attr:`st_gen` - file generation number - * :attr:`st_birthtime` - time of file creation + The following example shows a simple use of :func:`scandir` to display all + the files (excluding directories) in the given *path* that don't start with + ``'.'``. The ``entry.is_file()`` call will generally not make an additional + system call:: - On Mac OS systems, the following attributes may also be available: + for entry in os.scandir(path): + if not entry.name.startswith('.') and entry.is_file(): + print(entry.name) + + .. note:: + + On Unix-based systems, :func:`scandir` uses the system's + `opendir() <http://pubs.opengroup.org/onlinepubs/009695399/functions/opendir.html>`_ + and + `readdir() <http://pubs.opengroup.org/onlinepubs/009695399/functions/readdir_r.html>`_ + functions. On Windows, it uses the Win32 + `FindFirstFileW <http://msdn.microsoft.com/en-us/library/windows/desktop/aa364418(v=vs.85).aspx>`_ + and + `FindNextFileW <http://msdn.microsoft.com/en-us/library/windows/desktop/aa364428(v=vs.85).aspx>`_ + functions. + + .. versionadded:: 3.5 + + +.. class:: DirEntry + + Object yielded by :func:`scandir` to expose the file path and other file + attributes of a directory entry. + + :func:`scandir` will provide as much of this information as possible without + making additional system calls. When a ``stat()`` or ``lstat()`` system call + is made, the ``DirEntry`` object will cache the result. + + ``DirEntry`` instances are not intended to be stored in long-lived data + structures; if you know the file metadata has changed or if a long time has + elapsed since calling :func:`scandir`, call ``os.stat(entry.path)`` to fetch + up-to-date information. + + Because the ``DirEntry`` methods can make operating system calls, they may + also raise :exc:`OSError`. If you need very fine-grained + control over errors, you can catch :exc:`OSError` when calling one of the + ``DirEntry`` methods and handle as appropriate. + + Attributes and methods on a ``DirEntry`` instance are as follows: + + .. attribute:: name + + The entry's base filename, relative to the :func:`scandir` *path* + argument. + + The :attr:`name` attribute will be of the same type (``str`` or + ``bytes``) as the :func:`scandir` *path* argument. Use + :func:`~os.fsdecode` to decode byte filenames. + + .. attribute:: path + + The entry's full path name: equivalent to ``os.path.join(scandir_path, + entry.name)`` where *scandir_path* is the :func:`scandir` *path* + argument. The path is only absolute if the :func:`scandir` *path* + argument was absolute. + + The :attr:`path` attribute will be of the same type (``str`` or + ``bytes``) as the :func:`scandir` *path* argument. Use + :func:`~os.fsdecode` to decode byte filenames. + + .. method:: inode() + + Return the inode number of the entry. + + The result is cached on the ``DirEntry`` object, use ``os.stat(entry.path, + follow_symlinks=False).st_ino`` to fetch up-to-date information. + + On Unix, no system call is required. + + .. method:: is_dir(\*, follow_symlinks=True) + + If *follow_symlinks* is ``True`` (the default), return ``True`` if the + entry is a directory or a symbolic link pointing to a directory; + return ``False`` if it is or points to any other kind of file, or if it + doesn't exist anymore. + + If *follow_symlinks* is ``False``, return ``True`` only if this entry + is a directory; return ``False`` if it is any other kind of file + or if it doesn't exist anymore. + + The result is cached on the ``DirEntry`` object. Call :func:`os.stat` + along with :func:`stat.S_ISDIR` to fetch up-to-date information. + + This method can raise :exc:`OSError`, such as :exc:`PermissionError`, + but :exc:`FileNotFoundError` is caught and not raised. + + In most cases, no system call is required. + + .. method:: is_file(\*, follow_symlinks=True) + + If *follow_symlinks* is ``True`` (the default), return ``True`` if the + entry is a file or a symbolic link pointing to a file; return ``False`` + if it is or points to a directory or other non-file entry, or if it + doesn't exist anymore. + + If *follow_symlinks* is ``False``, return ``True`` only if this entry + is a file; return ``False`` if it is a directory or other non-file entry, + or if it doesn't exist anymore. + + The result is cached on the ``DirEntry`` object. Call :func:`os.stat` + along with :func:`stat.S_ISREG` to fetch up-to-date information. + + This method can raise :exc:`OSError`, such as :exc:`PermissionError`, + but :exc:`FileNotFoundError` is caught and not raised. + + In most cases, no system call is required. + + .. method:: is_symlink() + + Return ``True`` if this entry is a symbolic link (even if broken); + return ``False`` if it points to a directory or any kind of file, + or if it doesn't exist anymore. + + The result is cached on the ``DirEntry`` object. Call + :func:`os.path.islink` to fetch up-to-date information. + + The method can raise :exc:`OSError`, such as :exc:`PermissionError`, + but :exc:`FileNotFoundError` is caught and not raised. + + In most cases, no system call is required. + + .. method:: stat(\*, follow_symlinks=True) + + Return a :class:`stat_result` object for this entry. This method + follows symbolic links by default; to stat a symbolic link add the + ``follow_symlinks=False`` argument. + + On Unix, this method always requires a system call. On Windows, + ``DirEntry.stat()`` requires a system call only if the + entry is a symbolic link, and ``DirEntry.stat(follow_symlinks=False)`` + never requires a system call. + + On Windows, the ``st_ino``, ``st_dev`` and ``st_nlink`` attributes of the + :class:`stat_result` are always set to zero. Call :func:`os.stat` to + get these attributes. + + The result is cached on the ``DirEntry`` object. Call :func:`os.stat` + to fetch up-to-date information. - * :attr:`st_rsize` - * :attr:`st_creator` - * :attr:`st_type` + .. versionadded:: 3.5 + + +.. function:: stat(path, \*, dir_fd=None, follow_symlinks=True) + + Get the status of a file or a file descriptor. Perform the equivalent of a + :c:func:`stat` system call on the given path. *path* may be specified as + either a string or as an open file descriptor. Return a :class:`stat_result` + object. + + This function normally follows symlinks; to stat a symlink add the argument + ``follow_symlinks=False``, or use :func:`lstat`. + + This function can support :ref:`specifying a file descriptor <path_fd>` and + :ref:`not following symlinks <follow_symlinks>`. + + .. index:: module: stat + + Example:: + + >>> import os + >>> statinfo = os.stat('somefile.txt') + >>> statinfo + os.stat_result(st_mode=33188, st_ino=7876932, st_dev=234881026, + st_nlink=1, st_uid=501, st_gid=501, st_size=264, st_atime=1297230295, + st_mtime=1297230027, st_ctime=1297230027) + >>> statinfo.st_size + 264 + + .. seealso:: + + :func:`fstat` and :func:`lstat` functions. + + .. versionadded:: 3.3 + Added the *dir_fd* and *follow_symlinks* arguments, specifying a file + descriptor instead of a path. + + +.. class:: stat_result + + Object whose attributes correspond roughly to the members of the + :c:type:`stat` structure. It is used for the result of :func:`os.stat`, + :func:`os.fstat` and :func:`os.lstat`. + + Attributes: + + .. attribute:: st_mode + + File mode: file type and file mode bits (permissions). + + .. attribute:: st_ino + + Inode number. + + .. attribute:: st_dev + + Identifier of the device on which this file resides. + + .. attribute:: st_nlink + + Number of hard links. + + .. attribute:: st_uid + + User identifier of the file owner. + + .. attribute:: st_gid + + Group identifier of the file owner. + + .. attribute:: st_size + + Size of the file in bytes, if it is a regular file or a symbolic link. + The size of a symbolic link is the length of the pathname it contains, + without a terminating null byte. + + Timestamps: + + .. attribute:: st_atime + + Time of most recent access expressed in seconds. + + .. attribute:: st_mtime + + Time of most recent content modification expressed in seconds. + + .. attribute:: st_ctime + + Platform dependent: + + * the time of most recent metadata change on Unix, + * the time of creation on Windows, expressed in seconds. + + .. attribute:: st_atime_ns + + Time of most recent access expressed in nanoseconds as an integer. + + .. attribute:: st_mtime_ns + + Time of most recent content modification expressed in nanoseconds as an + integer. + + .. attribute:: st_ctime_ns + + Platform dependent: + + * the time of most recent metadata change on Unix, + * the time of creation on Windows, expressed in nanoseconds as an + integer. + + See also the :func:`stat_float_times` function. .. note:: @@ -1893,6 +2155,7 @@ features: or FAT32 file systems, :attr:`st_mtime` has 2-second resolution, and :attr:`st_atime` has only 1-day resolution. See your operating system documentation for details. + Similarly, although :attr:`st_atime_ns`, :attr:`st_mtime_ns`, and :attr:`st_ctime_ns` are always expressed in nanoseconds, many systems do not provide nanosecond precision. On systems that do @@ -1902,41 +2165,80 @@ features: If you need the exact timestamps you should always use :attr:`st_atime_ns`, :attr:`st_mtime_ns`, and :attr:`st_ctime_ns`. - For backward compatibility, the return value of :func:`~os.stat` is also - accessible as a tuple of at least 10 integers giving the most important (and - portable) members of the :c:type:`stat` structure, in the order - :attr:`st_mode`, :attr:`st_ino`, :attr:`st_dev`, :attr:`st_nlink`, - :attr:`st_uid`, :attr:`st_gid`, :attr:`st_size`, :attr:`st_atime`, - :attr:`st_mtime`, :attr:`st_ctime`. More items may be added at the end by - some implementations. + On some Unix systems (such as Linux), the following attributes may also be + available: - This function can support :ref:`specifying a file descriptor <path_fd>` and - :ref:`not following symlinks <follow_symlinks>`. + .. attribute:: st_blocks - .. index:: module: stat + Number of 512-byte blocks allocated for file. + This may be smaller than :attr:`st_size`/512 when the file has holes. - The standard module :mod:`stat` defines functions and constants that are useful - for extracting information from a :c:type:`stat` structure. (On Windows, some - items are filled with dummy values.) + .. attribute:: st_blksize - Example:: + "Preferred" blocksize for efficient file system I/O. Writing to a file in + smaller chunks may cause an inefficient read-modify-rewrite. - >>> import os - >>> statinfo = os.stat('somefile.txt') - >>> statinfo - posix.stat_result(st_mode=33188, st_ino=7876932, st_dev=234881026, - st_nlink=1, st_uid=501, st_gid=501, st_size=264, st_atime=1297230295, - st_mtime=1297230027, st_ctime=1297230027) - >>> statinfo.st_size - 264 + .. attribute:: st_rdev - Availability: Unix, Windows. + Type of device if an inode device. + + .. attribute:: st_flags + + User defined flags for file. + + On other Unix systems (such as FreeBSD), the following attributes may be + available (but may be only filled out if root tries to use them): + + .. attribute:: st_gen + + File generation number. + + .. attribute:: st_birthtime + + Time of file creation. + + On Mac OS systems, the following attributes may also be available: + + .. attribute:: st_rsize + + Real size of the file. + + .. attribute:: st_creator + + Creator of the file. + + .. attribute:: st_type + + File type. + + On Windows systems, the following attribute is also available: + + .. attribute:: st_file_attributes + + Windows file attributes: ``dwFileAttributes`` member of the + ``BY_HANDLE_FILE_INFORMATION`` structure returned by + :c:func:`GetFileInformationByHandle`. See the ``FILE_ATTRIBUTE_*`` + constants in the :mod:`stat` module. + + The standard module :mod:`stat` defines functions and constants that are + useful for extracting information from a :c:type:`stat` structure. (On + Windows, some items are filled with dummy values.) + + For backward compatibility, a :class:`stat_result` instance is also + accessible as a tuple of at least 10 integers giving the most important (and + portable) members of the :c:type:`stat` structure, in the order + :attr:`st_mode`, :attr:`st_ino`, :attr:`st_dev`, :attr:`st_nlink`, + :attr:`st_uid`, :attr:`st_gid`, :attr:`st_size`, :attr:`st_atime`, + :attr:`st_mtime`, :attr:`st_ctime`. More items may be added at the end by + some implementations. For compatibility with older Python versions, + accessing :class:`stat_result` as a tuple always returns integers. .. versionadded:: 3.3 - Added the *dir_fd* and *follow_symlinks* arguments, - specifying a file descriptor instead of a path, - and the :attr:`st_atime_ns`, :attr:`st_mtime_ns`, - and :attr:`st_ctime_ns` members. + Added the :attr:`st_atime_ns`, :attr:`st_mtime_ns`, and + :attr:`st_ctime_ns` members. + + .. versionadded:: 3.5 + Added the :attr:`st_file_attributes` member on Windows. .. function:: stat_float_times([newvalue]) @@ -1980,11 +2282,26 @@ features: read-only, and if :const:`ST_NOSUID` is set, the semantics of setuid/setgid bits are disabled or not supported. + Additional module-level constants are defined for GNU/glibc based systems. + These are :const:`ST_NODEV` (disallow access to device special files), + :const:`ST_NOEXEC` (disallow program execution), :const:`ST_SYNCHRONOUS` + (writes are synced at once), :const:`ST_MANDLOCK` (allow mandatory locks on an FS), + :const:`ST_WRITE` (write on file/directory/symlink), :const:`ST_APPEND` + (append-only file), :const:`ST_IMMUTABLE` (immutable file), :const:`ST_NOATIME` + (do not update access times), :const:`ST_NODIRATIME` (do not update directory access + times), :const:`ST_RELATIME` (update atime relative to mtime/ctime). + This function can support :ref:`specifying a file descriptor <path_fd>`. .. versionchanged:: 3.2 The :const:`ST_RDONLY` and :const:`ST_NOSUID` constants were added. + .. versionchanged:: 3.4 + The :const:`ST_NODEV`, :const:`ST_NOEXEC`, :const:`ST_SYNCHRONOUS`, + :const:`ST_MANDLOCK`, :const:`ST_WRITE`, :const:`ST_APPEND`, + :const:`ST_IMMUTABLE`, :const:`ST_NOATIME`, :const:`ST_NODIRATIME`, + and :const:`ST_RELATIME` constants were added. + Availability: Unix. .. versionadded:: 3.3 @@ -2021,7 +2338,8 @@ features: contain :func:`os.access`, otherwise it will be empty. To check whether you can use the *effective_ids* parameter for - :func:`os.access`, use the ``in`` operator on ``supports_dir_fd``, like so:: + :func:`os.access`, use the ``in`` operator on ``supports_effective_ids``, + like so:: os.access in os.supports_effective_ids @@ -2071,9 +2389,9 @@ features: .. versionadded:: 3.3 -.. function:: symlink(source, link_name, target_is_directory=False, *, dir_fd=None) +.. function:: symlink(src, dst, target_is_directory=False, *, dir_fd=None) - Create a symbolic link pointing to *source* named *link_name*. + Create a symbolic link pointing to *src* named *dst*. On Windows, a symlink represents either a file or a directory, and does not morph to the target dynamically. If the target is present, the type of the @@ -2125,10 +2443,12 @@ features: This function can support :ref:`specifying a file descriptor <path_fd>`. - Availability: Unix. + Availability: Unix, Windows. .. versionadded:: 3.3 + .. versionchanged:: 3.5 + Added support for Windows .. function:: unlink(path, *, dir_fd=None) @@ -2137,26 +2457,24 @@ features: name. Please see the documentation for :func:`remove` for further information. - Availability: Unix, Windows. - .. versionadded:: 3.3 The *dir_fd* parameter. -.. function:: utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True) +.. function:: utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True) Set the access and modified times of the file specified by *path*. :func:`utime` takes two optional parameters, *times* and *ns*. These specify the times set on *path* and are used as follows: - - If *ns* is not ``None``, + - If *ns* is specified, it must be a 2-tuple of the form ``(atime_ns, mtime_ns)`` where each member is an int expressing nanoseconds. - If *times* is not ``None``, it must be a 2-tuple of the form ``(atime, mtime)`` where each member is an int or float expressing seconds. - - If *times* and *ns* are both ``None``, + - If *times* is ``None`` and *ns* is unspecified, this is equivalent to specifying ``ns=(atime_ns, mtime_ns)`` where both times are the current time. @@ -2175,8 +2493,6 @@ features: :ref:`paths relative to directory descriptors <dir_fd>` and :ref:`not following symlinks <follow_symlinks>`. - Availability: Unix, Windows. - .. versionadded:: 3.3 Added support for specifying an open file descriptor for *path*, and the *dir_fd*, *follow_symlinks*, and *ns* parameters. @@ -2202,9 +2518,11 @@ features: If optional argument *topdown* is ``True`` or not specified, the triple for a directory is generated before the triples for any of its subdirectories - (directories are generated top-down). If *topdown* is ``False``, the triple for a - directory is generated after the triples for all of its subdirectories - (directories are generated bottom-up). + (directories are generated top-down). If *topdown* is ``False``, the triple + for a directory is generated after the triples for all of its subdirectories + (directories are generated bottom-up). No matter the value of *topdown*, the + list of subdirectories is retrieved before the tuples for the directory and + its subdirectories are generated. When *topdown* is ``True``, the caller can modify the *dirnames* list in-place (perhaps using :keyword:`del` or slice assignment), and :func:`walk` will only @@ -2250,8 +2568,9 @@ features: if 'CVS' in dirs: dirs.remove('CVS') # don't visit CVS directories - In the next example, walking the tree bottom-up is essential: :func:`rmdir` - doesn't allow deleting a directory before the directory is empty:: + In the next example (simple implementation of :func:`shutil.rmtree`), + walking the tree bottom-up is essential, :func:`rmdir` doesn't allow + deleting a directory before the directory is empty:: # Delete everything reachable from the directory named in "top", # assuming there are no symbolic links. @@ -2264,6 +2583,10 @@ features: for name in dirs: os.rmdir(os.path.join(root, name)) + .. versionchanged:: 3.5 + This function now calls :func:`os.scandir` instead of :func:`os.listdir`, + making it faster by reducing the number of calls to :func:`os.stat`. + .. function:: fwalk(top='.', topdown=True, onerror=None, *, follow_symlinks=False, dir_fd=None) @@ -2420,8 +2743,6 @@ to be ignored. Python signal handler registered for :const:`SIGABRT` with :func:`signal.signal`. - Availability: Unix, Windows. - .. function:: execl(path, arg0, arg1, ...) execle(path, arg0, arg1, ..., env) @@ -2485,8 +2806,6 @@ to be ignored. Exit the process with status *n*, without calling cleanup handlers, flushing stdio buffers, etc. - Availability: Unix, Windows. - .. note:: The standard way to exit is ``sys.exit(n)``. :func:`_exit` should @@ -2634,7 +2953,7 @@ written in Python, such as a mail server's external command delivery program. Fork a child process. Return ``0`` in the child and the child's process id in the parent. If an error occurs :exc:`OSError` is raised. - Note that some platforms including FreeBSD <= 6.3, Cygwin and OS/2 EMX have + Note that some platforms including FreeBSD <= 6.3 and Cygwin have known issues when using fork() from a thread. .. warning:: @@ -2704,10 +3023,28 @@ written in Python, such as a mail server's external command delivery program. Availability: Unix. -.. function:: popen(...) +.. function:: popen(cmd, mode='r', buffering=-1) - Run child processes, returning opened pipes for communications. These functions - are described in section :ref:`os-newstreams`. + Open a pipe to or from command *cmd*. + The return value is an open file object + connected to the pipe, which can be read or written depending on whether *mode* + is ``'r'`` (default) or ``'w'``. The *buffering* argument has the same meaning as + the corresponding argument to the built-in :func:`open` function. The + returned file object reads or writes text strings rather than bytes. + + The ``close`` method returns :const:`None` if the subprocess exited + successfully, or the subprocess's return code if there was an + error. On POSIX systems, if the return code is positive it + represents the return value of the process left-shifted by one + byte. If the return code is negative, the process was terminated + by the signal given by the negated value of the return code. (For + example, the return value might be ``- signal.SIGKILL`` if the + subprocess was killed.) On Windows systems, the return value + contains the signed integer return code from the child process. + + This is implemented using :class:`subprocess.Popen`; see that class's + documentation for more powerful ways to manage and communicate with + subprocesses. .. function:: spawnl(mode, path, ...) @@ -2831,6 +3168,10 @@ written in Python, such as a mail server's external command delivery program. doesn't work if it is. Use the :func:`os.path.normpath` function to ensure that the path is properly encoded for Win32. + To reduce interpreter startup overhead, the Win32 :c:func:`ShellExecute` + function is not resolved until this function is first called. If the function + cannot be resolved, :exc:`NotImplementedError` will be raised. + Availability: Windows. @@ -2880,7 +3221,6 @@ written in Python, such as a mail server's external command delivery program. :manpage:`times(2)` or the corresponding Windows Platform API documentation. On Windows, only :attr:`user` and :attr:`system` are known; the other attributes are zero. - On OS/2, only :attr:`elapsed` is known; the other attributes are zero. Availability: Unix, Windows. @@ -2979,6 +3319,11 @@ written in Python, such as a mail server's external command delivery program. id is known, not necessarily a child process. The :func:`spawn\* <spawnl>` functions called with :const:`P_NOWAIT` return suitable process handles. + .. versionchanged:: 3.5 + If the system call is interrupted and the signal handler does not raise an + exception, the function now retries the system call instead of raising an + :exc:`InterruptedError` exception (see :pep:`475` for the rationale). + .. function:: wait3(options) @@ -3252,6 +3597,11 @@ Miscellaneous System Information Return the number of CPUs in the system. Returns None if undetermined. + 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))`` + + .. versionadded:: 3.4 @@ -3386,3 +3736,9 @@ Miscellaneous Functions For an easy-to-use interface to the random number generator provided by your platform, please see :class:`random.SystemRandom`. + + .. versionchanged:: 3.5 + On Linux 3.17 and newer, the ``getrandom()`` syscall is now used + when available. On OpenBSD 5.6 and newer, the C ``getentropy()`` + function is now used. These functions avoid the usage of an internal file + descriptor. diff --git a/Doc/library/ossaudiodev.rst b/Doc/library/ossaudiodev.rst index b53e80f93735..c60d596506c2 100644 --- a/Doc/library/ossaudiodev.rst +++ b/Doc/library/ossaudiodev.rst @@ -49,7 +49,7 @@ the standard audio interface for Linux and recent versions of FreeBSD. the official documentation for the OSS C API The module defines a large number of constants supplied by the OSS device - driver; see ``<sys/soundcard.h>`` on either Linux or FreeBSD for a listing . + driver; see ``<sys/soundcard.h>`` on either Linux or FreeBSD for a listing. :mod:`ossaudiodev` defines the following variables and functions: @@ -148,24 +148,33 @@ and (read-only) attributes: .. method:: oss_audio_device.write(data) - Write the Python string *data* to the audio device and return the number of - bytes written. If the audio device is in blocking mode (the default), the - entire string is always written (again, this is different from usual Unix device - semantics). If the device is in non-blocking mode, some data may not be written + Write a :term:`bytes-like object` *data* to the audio device and return the + number of bytes written. If the audio device is in blocking mode (the + default), the entire data is always written (again, this is different from + usual Unix device semantics). If the device is in non-blocking mode, some + data may not be written ---see :meth:`writeall`. + .. versionchanged: 3.5 + Writable :term:`bytes-like object` is now accepted. + .. method:: oss_audio_device.writeall(data) - Write the entire Python string *data* to the audio device: waits until the audio - device is able to accept data, writes as much data as it will accept, and - repeats until *data* has been completely written. If the device is in blocking - mode (the default), this has the same effect as :meth:`write`; :meth:`writeall` - is only useful in non-blocking mode. Has no return value, since the amount of - data written is always equal to the amount of data supplied. + Write a :term:`bytes-like object` *data* to the audio device: waits until + the audio device is able to accept data, writes as much data as it will + accept, and repeats until *data* has been completely written. If the device + is in blocking mode (the default), this has the same effect as + :meth:`write`; :meth:`writeall` is only useful in non-blocking mode. Has + no return value, since the amount of data written is always equal to the + amount of data supplied. + + .. versionchanged: 3.5 + Writable :term:`bytes-like object` is now accepted. + .. versionchanged:: 3.2 - Audio device objects also support the context manager protocol, i.e. they can + Audio device objects also support the context management protocol, i.e. they can be used in a :keyword:`with` statement. @@ -357,7 +366,7 @@ The mixer object provides two file-like methods: Returns the file handle number of the open mixer device file. .. versionchanged:: 3.2 - Mixer objects also support the context manager protocol. + Mixer objects also support the context management protocol. The remaining methods are specific to audio mixing: @@ -407,7 +416,7 @@ The remaining methods are specific to audio mixing: (silent) to 100 (full volume). If the control is monophonic, a 2-tuple is still returned, but both volumes are the same. - Raises :exc:`OSSAudioError` if an invalid control was is specified, or + Raises :exc:`OSSAudioError` if an invalid control is specified, or :exc:`OSError` if an unsupported control is specified. diff --git a/Doc/library/othergui.rst b/Doc/library/othergui.rst index eb49b994d89e..43721b26884a 100644 --- a/Doc/library/othergui.rst +++ b/Doc/library/othergui.rst @@ -10,7 +10,7 @@ available for Python: `PyGObject <https://live.gnome.org/PyGObject>`_ provides introspection bindings for C libraries using - `GObject <http://developer.gnome.org/gobject/stable/>`_. One of + `GObject <https://developer.gnome.org/gobject/stable/>`_. One of these libraries is the `GTK+ 3 <http://www.gtk.org/>`_ widget set. GTK+ comes with many more widgets than Tkinter provides. An online `Python GTK+ 3 Tutorial <http://python-gtk-3-tutorial.readthedocs.org/en/latest/>`_ @@ -22,7 +22,7 @@ available for Python: `GNOME <http://www.gnome.org>`_. An online `tutorial <http://www.pygtk.org/pygtk2tutorial/index.html>`_ is available. - `PyQt <http://www.riverbankcomputing.co.uk/software/pyqt/>`_ + `PyQt <http://www.riverbankcomputing.co.uk/software/pyqt/intro>`_ PyQt is a :program:`sip`\ -wrapped binding to the Qt toolkit. Qt is an extensive C++ GUI application development framework that is available for Unix, Windows and Mac OS X. :program:`sip` is a tool @@ -34,7 +34,7 @@ available for Python: with Python and Qt <http://www.qtrac.eu/pyqtbook.html>`_, by Mark Summerfield. - `PySide <http://www.pyside.org/>`_ + `PySide <http://qt-project.org/wiki/PySide>`_ is a newer binding to the Qt toolkit, provided by Nokia. Compared to PyQt, its licensing scheme is friendlier to non-open source applications. @@ -50,13 +50,13 @@ available for Python: low-level device context drawing, drag and drop, system clipboard access, an XML-based resource format and more, including an ever growing library of user-contributed modules. wxPython has a book, `wxPython in Action - <http://www.amazon.com/exec/obidos/ASIN/1932394621>`_, by Noel Rappin and + <http://www.manning.com/rappin/>`_, by Noel Rappin and Robin Dunn. PyGTK, PyQt, and wxPython, all have a modern look and feel and more widgets than Tkinter. In addition, there are many other GUI toolkits for Python, both cross-platform, and platform-specific. See the `GUI Programming -<http://wiki.python.org/moin/GuiProgramming>`_ page in the Python Wiki for a +<https://wiki.python.org/moin/GuiProgramming>`_ page in the Python Wiki for a much more complete list, and also for links to documents where the different GUI toolkits are compared. diff --git a/Doc/library/pathlib-inheritance.svg b/Doc/library/pathlib-inheritance.svg new file mode 100644 index 000000000000..9f42005e0a12 --- /dev/null +++ b/Doc/library/pathlib-inheritance.svg @@ -0,0 +1,4 @@ +<?xml version="1.0" standalone="yes"?> + +<svg version="1.1" viewBox="0.0 0.0 538.0 496.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="p.0"><path d="m0 0l538.0 0l0 496.0l-538.0 0l0 -496.0z" clip-rule="nonzero"></path></clipPath><g clip-path="url(#p.0)"><path fill="#000000" fill-opacity="0.0" d="m0 0l538.916 0l0 496.08398l-538.916 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m176.0 24.0l187.43307 0l0 80.53543l-187.43307 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m176.0 24.0l187.43307 0l0 80.53543l-187.43307 0z" fill-rule="nonzero"></path><path fill="#000000" d="m235.18527 66.877716l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm13.9296875 -2.234375l0 5.484375q0.515625 0 0.75 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.515625 0l0 -0.375q-0.6875 0.3125 -1.3125 0.46875q-0.625 0.171875 -1.1875 0.171875q-0.796875 0 -1.375 -0.328125q-0.578125 -0.34375 -0.90625 -0.9375q-0.25 -0.421875 -0.25 -1.046875l0 -3.453125l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.875 0l0 4.765625q0 0.5 0.234375 0.75q0.25 0.234375 0.765625 0.234375q0.484375 0 1.03125 -0.1875q0.5625 -0.203125 1.390625 -0.703125l0 -3.265625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm5.8671875 0l0 1.0q1.015625 -0.734375 1.59375 -0.96875q0.578125 -0.25 1.09375 -0.25q0.78125 0 1.515625 0.578125q0.5 0.390625 0.5 0.796875q0 0.34375 -0.25 0.59375q-0.234375 0.234375 -0.5625 0.234375q-0.296875 0 -0.625 -0.296875q-0.328125 -0.296875 -0.59375 -0.296875q-0.328125 0 -1.0 0.421875q-0.671875 0.421875 -1.671875 1.265625l0 2.40625l2.28125 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-4.828125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.953125 0l0 -3.890625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm13.9609375 4.359375l-6.578125 0q0.25 0.625 0.890625 1.015625q0.640625 0.375 1.71875 0.375q0.890625 0 2.375 -0.390625q0.609375 -0.15625 0.84375 -0.15625q0.3125 0 0.53125 0.234375q0.21875 0.21875 0.21875 0.5625q0 0.3125 -0.234375 0.53125q-0.3125 0.296875 -1.53125 0.5625q-1.203125 0.265625 -2.3125 0.265625q-1.921875 0 -3.078125 -1.09375q-1.15625 -1.09375 -1.15625 -2.671875q0 -1.6875 1.25 -2.75q1.25 -1.0625 2.875 -1.0625q0.96875 0 1.78125 0.34375q0.828125 0.34375 1.21875 0.75q0.5625 0.578125 0.9375 1.421875q0.25 0.59375 0.25 1.375l0 0.6875zm-1.78125 -1.609375q-0.359375 -0.6875 -0.953125 -1.015625q-0.59375 -0.34375 -1.421875 -0.34375q-0.8125 0 -1.40625 0.34375q-0.59375 0.328125 -0.96875 1.015625l4.75 0zm6.4296875 1.09375l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.9765625 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.921875l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m16.0 144.0l187.43306 0l0 80.53543l-187.43306 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m16.0 144.0l187.43306 0l0 80.53543l-187.43306 0z" fill-rule="nonzero"></path><path fill="#000000" d="m51.181374 186.87772l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm13.9296875 -2.234375l0 5.484375q0.515625 0 0.75 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.515625 0l0 -0.375q-0.6875 0.3125 -1.3125 0.46875q-0.625 0.171875 -1.1875 0.171875q-0.796875 0 -1.375 -0.328125q-0.578125 -0.34375 -0.90625 -0.9375q-0.25 -0.421875 -0.25 -1.046875l0 -3.453125l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.875 0l0 4.765625q0 0.5 0.234375 0.75q0.25 0.234375 0.765625 0.234375q0.484375 0 1.03125 -0.1875q0.5625 -0.203125 1.390625 -0.703125l0 -3.265625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm5.8671875 0l0 1.0q1.015625 -0.734375 1.59375 -0.96875q0.578125 -0.25 1.09375 -0.25q0.78125 0 1.515625 0.578125q0.5 0.390625 0.5 0.796875q0 0.34375 -0.25 0.59375q-0.234375 0.234375 -0.5625 0.234375q-0.296875 0 -0.625 -0.296875q-0.328125 -0.296875 -0.59375 -0.296875q-0.328125 0 -1.0 0.421875q-0.671875 0.421875 -1.671875 1.265625l0 2.40625l2.28125 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-4.828125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.953125 0l0 -3.890625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm13.9609375 4.359375l-6.578125 0q0.25 0.625 0.890625 1.015625q0.640625 0.375 1.71875 0.375q0.890625 0 2.375 -0.390625q0.609375 -0.15625 0.84375 -0.15625q0.3125 0 0.53125 0.234375q0.21875 0.21875 0.21875 0.5625q0 0.3125 -0.234375 0.53125q-0.3125 0.296875 -1.53125 0.5625q-1.203125 0.265625 -2.3125 0.265625q-1.921875 0 -3.078125 -1.09375q-1.15625 -1.09375 -1.15625 -2.671875q0 -1.6875 1.25 -2.75q1.25 -1.0625 2.875 -1.0625q0.96875 0 1.78125 0.34375q0.828125 0.34375 1.21875 0.75q0.5625 0.578125 0.9375 1.421875q0.25 0.59375 0.25 1.375l0 0.6875zm-1.78125 -1.609375q-0.359375 -0.6875 -0.953125 -1.015625q-0.59375 -0.34375 -1.421875 -0.34375q-0.8125 0 -1.40625 0.34375q-0.59375 0.328125 -0.96875 1.015625l4.75 0zm6.4296875 1.09375l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm14.6953125 1.4375q0 0.921875 -0.515625 1.796875q-0.515625 0.859375 -1.53125 1.375q-1.0 0.515625 -2.109375 0.515625q-1.09375 0 -2.09375 -0.5q-1.0 -0.515625 -1.53125 -1.375q-0.515625 -0.875 -0.515625 -1.828125q0 -0.953125 0.53125 -1.875q0.53125 -0.9375 1.53125 -1.46875q1.0 -0.53125 2.078125 -0.53125q1.09375 0 2.109375 0.546875q1.015625 0.546875 1.53125 1.46875q0.515625 0.90625 0.515625 1.875zm-1.609375 0.015625q0 -0.78125 -0.546875 -1.421875q-0.765625 -0.875 -2.0 -0.875q-1.078125 0 -1.8125 0.703125q-0.71875 0.6875 -0.71875 1.59375q0 0.75 0.734375 1.40625q0.734375 0.65625 1.796875 0.65625q1.078125 0 1.8125 -0.65625q0.734375 -0.65625 0.734375 -1.40625zm8.7734375 -1.8125q-0.390625 -0.25 -0.828125 -0.359375q-0.421875 -0.125 -0.890625 -0.125q-0.921875 0 -1.46875 0.296875q-0.25 0.140625 -0.25 0.296875q0 0.171875 0.328125 0.34375q0.25 0.125 1.125 0.25q1.59375 0.21875 2.21875 0.4375q0.8125 0.28125 1.25 0.859375q0.453125 0.5625 0.453125 1.203125q0 0.859375 -0.75 1.4375q-1.09375 0.84375 -2.828125 0.84375q-0.6875 0 -1.28125 -0.125q-0.59375 -0.125 -1.078125 -0.359375q-0.125 0.09375 -0.265625 0.15625q-0.125 0.046875 -0.265625 0.046875q-0.375 0 -0.59375 -0.234375q-0.21875 -0.25 -0.21875 -0.828125l0 -0.546875q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.296875 0 0.484375 0.15625q0.203125 0.15625 0.3125 0.546875q0.359375 0.3125 0.875 0.484375q0.515625 0.15625 1.1875 0.15625q1.109375 0 1.71875 -0.34375q0.28125 -0.171875 0.28125 -0.359375q0 -0.3125 -0.40625 -0.515625q-0.421875 -0.203125 -1.71875 -0.34375q-1.921875 -0.203125 -2.578125 -0.78125q-0.640625 -0.578125 -0.640625 -1.40625q0 -0.859375 0.71875 -1.4375q0.984375 -0.78125 2.578125 -0.78125q0.5625 0 1.0625 0.109375q0.515625 0.109375 0.984375 0.328125q0.15625 -0.109375 0.28125 -0.15625q0.125 -0.0625 0.234375 -0.0625q0.328125 0 0.546875 0.25q0.21875 0.234375 0.21875 0.8125l0 0.390625q0 0.53125 -0.125 0.71875q-0.25 0.359375 -0.671875 0.359375q-0.296875 0 -0.515625 -0.171875q-0.21875 -0.1875 -0.28125 -0.484375zm8.4453125 -4.921875l0 1.703125l-1.90625 0l0 -1.703125l1.90625 0zm0.21875 3.046875l0 5.484375l1.921875 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-5.4375 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.921875 0l0 -3.890625l-1.296875 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.890625 0zm10.007805 3.40625l2.4375 2.078125q0.4375 0.03125 0.65625 0.25q0.21875 0.21875 0.21875 0.5625q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.8125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.28125 0.171875 -0.5q0.1875 -0.21875 0.484375 -0.296875l-1.1875 -1.03125l-1.2187424 1.03125q0.35936737 0.09375 0.5156174 0.296875q0.171875 0.1875 0.171875 0.5q0 0.359375 -0.25 0.59375q-0.23436737 0.21875 -0.8124924 0.21875l-1.8125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.328125 0.21875 -0.546875q0.21875 -0.21875 0.65625 -0.25l2.375 -2.09375l-2.109375 -1.796875q-0.40625 -0.03125 -0.625 -0.25q-0.21875 -0.21875 -0.21875 -0.546875q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.5 0q0.578125 0 0.8124924 0.21875q0.25 0.21875 0.25 0.5625q0 0.46875 -0.43749237 0.75l0.9687424 0.8125l0.953125 -0.828125q-0.421875 -0.296875 -0.421875 -0.703125q0 -0.375 0.234375 -0.59375q0.25 -0.21875 0.828125 -0.21875l1.484375 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.328125 -0.21875 0.546875q-0.21875 0.21875 -0.640625 0.25l-2.109375 1.8125zm7.4765625 0.4375l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.9765625 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.921875l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m336.0 143.46457l187.43304 0l0 80.53543l-187.43304 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m336.0 143.46457l187.43304 0l0 80.53543l-187.43304 0z" fill-rule="nonzero"></path><path fill="#000000" d="m361.5798 186.34229l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm13.9296875 -2.234375l0 5.484375q0.515625 0 0.75 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.515625 0l0 -0.375q-0.6875 0.3125 -1.3125 0.46875q-0.625 0.171875 -1.1875 0.171875q-0.796875 0 -1.375 -0.328125q-0.578125 -0.34375 -0.90625 -0.9375q-0.25 -0.421875 -0.25 -1.046875l0 -3.453125l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.875 0l0 4.765625q0 0.5 0.234375 0.75q0.25 0.234375 0.765625 0.234375q0.484375 0 1.03125 -0.1875q0.5625 -0.203125 1.390625 -0.703125l0 -3.265625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm5.8671875 0l0 1.0q1.015625 -0.734375 1.59375 -0.96875q0.578125 -0.25 1.09375 -0.25q0.78125 0 1.515625 0.578125q0.5 0.390625 0.5 0.796875q0 0.34375 -0.25 0.59375q-0.234375 0.234375 -0.5625 0.234375q-0.296875 0 -0.625 -0.296875q-0.328125 -0.296875 -0.59375 -0.296875q-0.328125 0 -1.0 0.421875q-0.671875 0.421875 -1.671875 1.265625l0 2.40625l2.28125 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-4.828125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.953125 0l0 -3.890625l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.171875 0zm13.9609375 4.359375l-6.578125 0q0.25 0.625 0.890625 1.015625q0.640625 0.375 1.71875 0.375q0.890625 0 2.375 -0.390625q0.609375 -0.15625 0.84375 -0.15625q0.3125 0 0.53125 0.234375q0.21875 0.21875 0.21875 0.5625q0 0.3125 -0.234375 0.53125q-0.3125 0.296875 -1.53125 0.5625q-1.203125 0.265625 -2.3125 0.265625q-1.921875 0 -3.078125 -1.09375q-1.15625 -1.09375 -1.15625 -2.671875q0 -1.6875 1.25 -2.75q1.25 -1.0625 2.875 -1.0625q0.96875 0 1.78125 0.34375q0.828125 0.34375 1.21875 0.75q0.5625 0.578125 0.9375 1.421875q0.25 0.59375 0.25 1.375l0 0.6875zm-1.78125 -1.609375q-0.359375 -0.6875 -0.953125 -1.015625q-0.59375 -0.34375 -1.421875 -0.34375q-0.8125 0 -1.40625 0.34375q-0.59375 0.328125 -0.96875 1.015625l4.75 0zm7.3671875 -0.203125l-1.484375 4.546875l-1.796875 0l-0.953125 -7.875q-0.375 -0.046875 -0.5625 -0.25q-0.1875 -0.203125 -0.1875 -0.53125q0 -0.375 0.25 -0.59375q0.25 -0.234375 0.828125 -0.234375l2.125 0.015625q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-0.828125 0l0.53125 4.484375l1.25 -3.734375l1.671875 0l1.25 3.734375l0.53125 -4.484375l-0.84375 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.21875 -0.234375 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.234375 0.828125 -0.234375l2.125 0.015625q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.296875 -0.203125 0.515625q-0.1875 0.21875 -0.5625 0.28125l-0.921875 7.875l-1.765625 0l-1.53125 -4.546875zm10.1640625 -5.59375l0 1.703125l-1.90625 0l0 -1.703125l1.90625 0zm0.21875 3.046875l0 5.484375l1.921875 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-5.4375 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.921875 0l0 -3.890625l-1.296875 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.890625 0zm7.1953125 0l0 0.53125q0.4375 -0.375 0.953125 -0.5625q0.53125 -0.1875 1.15625 -0.1875q1.421875 0 2.25 0.890625q0.65625 0.703125 0.65625 1.84375l0 2.96875q0.5 0 0.734375 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.453125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.34375 0.234375 -0.5625q0.25 -0.234375 0.75 -0.234375l0 -3.015625q0 -0.53125 -0.28125 -0.765625q-0.359375 -0.3125 -1.09375 -0.3125q-0.5625 0 -0.984375 0.21875q-0.40625 0.203125 -1.046875 0.90625l0 2.96875q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -3.890625q-0.5 0 -0.75 -0.21875q-0.234375 -0.234375 -0.234375 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.53125 0zm14.8984375 -3.046875l0 8.53125l0.265625 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.875 0l0 -0.390625q-0.546875 0.3125 -1.140625 0.484375q-0.59375 0.171875 -1.234375 0.171875q-1.8125 0 -2.921875 -1.046875q-1.09375 -1.046875 -1.09375 -2.609375q0 -1.625 1.15625 -2.765625q1.15625 -1.15625 2.828125 -1.15625q0.625 0 1.21875 0.203125q0.609375 0.1875 1.1875 0.5625l0 -1.984375l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l1.875 0zm-1.609375 6.796875q0 -0.984375 -0.703125 -1.671875q-0.6875 -0.6875 -1.6875 -0.6875q-1.0 0 -1.703125 0.6875q-0.6875 0.6875 -0.6875 1.65625q0 0.875 0.625 1.453125q0.625 0.5625 1.765625 0.5625q1.125 0 1.75 -0.5625q0.640625 -0.578125 0.640625 -1.4375zm11.6953125 -0.078125q0 0.921875 -0.515625 1.796875q-0.515625 0.859375 -1.53125 1.375q-1.0 0.515625 -2.109375 0.515625q-1.09375 0 -2.09375 -0.5q-1.0 -0.515625 -1.53125 -1.375q-0.515625 -0.875 -0.515625 -1.828125q0 -0.953125 0.53125 -1.875q0.53125 -0.9375 1.53125 -1.46875q1.0 -0.53125 2.078125 -0.53125q1.09375 0 2.109375 0.546875q1.015625 0.546875 1.53125 1.46875q0.515625 0.90625 0.515625 1.875zm-1.609375 0.015625q0 -0.78125 -0.546875 -1.421875q-0.765625 -0.875 -2.0 -0.875q-1.078125 0 -1.8125 0.703125q-0.71875 0.6875 -0.71875 1.59375q0 0.75 0.734375 1.40625q0.734375 0.65625 1.796875 0.65625q1.078125 0 1.8125 -0.65625q0.734375 -0.65625 0.734375 -1.40625zm7.0546875 0.453125l-1.109375 2.953125l-1.5 0l-1.34375 -5.5q-0.4375 -0.015625 -0.671875 -0.234375q-0.21875 -0.234375 -0.21875 -0.5625q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.484375 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.28125 0.609375q-0.21875 0.1875 -0.828125 0.1875l0.609375 2.546875l0.984375 -2.609375l1.421875 0l1.0 2.609375l0.625 -2.546875q-0.59375 0 -0.78125 -0.109375q-0.375 -0.25 -0.375 -0.6875q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.5 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.328125 -0.21875 0.546875q-0.21875 0.21875 -0.640625 0.25l-1.3125 5.5l-1.484375 0l-1.171875 -2.953125zm11.3203125 -2.265625q-0.390625 -0.25 -0.828125 -0.359375q-0.421875 -0.125 -0.890625 -0.125q-0.921875 0 -1.46875 0.296875q-0.25 0.140625 -0.25 0.296875q0 0.171875 0.328125 0.34375q0.25 0.125 1.125 0.25q1.59375 0.21875 2.21875 0.4375q0.8125 0.28125 1.25 0.859375q0.453125 0.5625 0.453125 1.203125q0 0.859375 -0.75 1.4375q-1.09375 0.84375 -2.828125 0.84375q-0.6875 0 -1.28125 -0.125q-0.59375 -0.125 -1.078125 -0.359375q-0.125 0.09375 -0.265625 0.15625q-0.125 0.046875 -0.265625 0.046875q-0.375 0 -0.59375 -0.234375q-0.21875 -0.25 -0.21875 -0.828125l0 -0.546875q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.296875 0 0.484375 0.15625q0.203125 0.15625 0.3125 0.546875q0.359375 0.3125 0.875 0.484375q0.515625 0.15625 1.1875 0.15625q1.109375 0 1.71875 -0.34375q0.28125 -0.171875 0.28125 -0.359375q0 -0.3125 -0.40625 -0.515625q-0.421875 -0.203125 -1.71875 -0.34375q-1.921875 -0.203125 -2.578125 -0.78125q-0.640625 -0.578125 -0.640625 -1.40625q0 -0.859375 0.71875 -1.4375q0.984375 -0.78125 2.578125 -0.78125q0.5625 0 1.0625 0.109375q0.515625 0.109375 0.984375 0.328125q0.15625 -0.109375 0.28125 -0.15625q0.125 -0.0625 0.234375 -0.0625q0.328125 0 0.546875 0.25q0.21875 0.234375 0.21875 0.8125l0 0.390625q0 0.53125 -0.125 0.71875q-0.25 0.359375 -0.671875 0.359375q-0.296875 0 -0.515625 -0.171875q-0.21875 -0.1875 -0.28125 -0.484375zm6.9453125 1.96875l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.9765625 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.921875l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m176.0 271.46457l187.43307 0l0 80.53543l-187.43307 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m176.0 271.46457l187.43307 0l0 80.53543l-187.43307 0z" fill-rule="nonzero"></path><path fill="#000000" d="m254.3884 314.3423l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.9765625 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.921875l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m16.0 400.0l187.43306 0l0 80.53543l-187.43306 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m16.0 400.0l187.43306 0l0 80.53543l-187.43306 0z" fill-rule="nonzero"></path><path fill="#000000" d="m70.3845 442.87772l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm14.6953125 1.4375q0 0.921875 -0.515625 1.796875q-0.515625 0.859375 -1.53125 1.375q-1.0 0.515625 -2.109375 0.515625q-1.09375 0 -2.09375 -0.5q-1.0 -0.515625 -1.53125 -1.375q-0.515625 -0.875 -0.515625 -1.828125q0 -0.953125 0.53125 -1.875q0.53125 -0.9375 1.53125 -1.46875q1.0 -0.53125 2.078125 -0.53125q1.09375 0 2.109375 0.546875q1.015625 0.546875 1.53125 1.46875q0.515625 0.90625 0.515625 1.875zm-1.609375 0.015625q0 -0.78125 -0.546875 -1.421875q-0.765625 -0.875 -2.0 -0.875q-1.078125 0 -1.8125 0.703125q-0.71875 0.6875 -0.71875 1.59375q0 0.75 0.734375 1.40625q0.734375 0.65625 1.796875 0.65625q1.078125 0 1.8125 -0.65625q0.734375 -0.65625 0.734375 -1.40625zm8.7734375 -1.8125q-0.390625 -0.25 -0.828125 -0.359375q-0.421875 -0.125 -0.890625 -0.125q-0.921875 0 -1.46875 0.296875q-0.25 0.140625 -0.25 0.296875q0 0.171875 0.328125 0.34375q0.25 0.125 1.125 0.25q1.59375 0.21875 2.21875 0.4375q0.8125 0.28125 1.25 0.859375q0.453125 0.5625 0.453125 1.203125q0 0.859375 -0.75 1.4375q-1.09375 0.84375 -2.828125 0.84375q-0.6875 0 -1.28125 -0.125q-0.59375 -0.125 -1.078125 -0.359375q-0.125 0.09375 -0.265625 0.15625q-0.125 0.046875 -0.265625 0.046875q-0.375 0 -0.59375 -0.234375q-0.21875 -0.25 -0.21875 -0.828125l0 -0.546875q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.296875 0 0.484375 0.15625q0.203125 0.15625 0.3125 0.546875q0.359375 0.3125 0.875 0.484375q0.515625 0.15625 1.1875 0.15625q1.109375 0 1.71875 -0.34375q0.28125 -0.171875 0.28125 -0.359375q0 -0.3125 -0.40625 -0.515625q-0.421875 -0.203125 -1.71875 -0.34375q-1.921875 -0.203125 -2.578125 -0.78125q-0.640625 -0.578125 -0.640625 -1.40625q0 -0.859375 0.71875 -1.4375q0.984375 -0.78125 2.578125 -0.78125q0.5625 0 1.0625 0.109375q0.515625 0.109375 0.984375 0.328125q0.15625 -0.109375 0.28125 -0.15625q0.125 -0.0625 0.234375 -0.0625q0.328125 0 0.546875 0.25q0.21875 0.234375 0.21875 0.8125l0 0.390625q0 0.53125 -0.125 0.71875q-0.25 0.359375 -0.671875 0.359375q-0.296875 0 -0.515625 -0.171875q-0.21875 -0.1875 -0.28125 -0.484375zm8.4453125 -4.921875l0 1.703125l-1.90625 0l0 -1.703125l1.90625 0zm0.21875 3.046875l0 5.484375l1.921875 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-5.4375 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.921875 0l0 -3.890625l-1.296875 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.890625 0zm10.0078125 3.40625l2.4375 2.078125q0.4375 0.03125 0.65625 0.25q0.21875 0.21875 0.21875 0.5625q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.8125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.28125 0.171875 -0.5q0.1875 -0.21875 0.484375 -0.296875l-1.1875 -1.03125l-1.21875 1.03125q0.359375 0.09375 0.515625 0.296875q0.171875 0.1875 0.171875 0.5q0 0.359375 -0.25 0.59375q-0.234375 0.21875 -0.8125 0.21875l-1.8125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.328125 0.21875 -0.546875q0.21875 -0.21875 0.65625 -0.25l2.375 -2.09375l-2.109375 -1.796875q-0.40625 -0.03125 -0.625 -0.25q-0.21875 -0.21875 -0.21875 -0.546875q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.5 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.5625q0 0.46875 -0.4375 0.75l0.96875 0.8125l0.953125 -0.828125q-0.421875 -0.296875 -0.421875 -0.703125q0 -0.375 0.234375 -0.59375q0.25 -0.21875 0.828125 -0.21875l1.484375 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.328125 -0.21875 0.546875q-0.21875 0.21875 -0.640625 0.25l-2.109375 1.8125zm7.4765625 0.4375l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.976555 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3124924 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.8437424 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.8437424 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.6249924 -0.109375 1.1249924 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.9687424 0 -1.6718674 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.5781174 0 1.2968674 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.921875l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"></path><path fill="#ffffff" d="m336.0 400.0l187.43304 0l0 80.53543l-187.43304 0z" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m336.0 400.0l187.43304 0l0 80.53543l-187.43304 0z" fill-rule="nonzero"></path><path fill="#000000" d="m381.72043 441.58084l-1.484375 4.546875l-1.796875 0l-0.953125 -7.875q-0.375 -0.046875 -0.5625 -0.25q-0.1875 -0.203125 -0.1875 -0.53125q0 -0.375 0.25 -0.59375q0.25 -0.234375 0.828125 -0.234375l2.125 0.015625q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-0.828125 0l0.53125 4.484375l1.25 -3.734375l1.671875 0l1.25 3.734375l0.53125 -4.484375l-0.84375 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.21875 -0.234375 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.234375 0.828125 -0.234375l2.125 0.015625q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.296875 -0.203125 0.515625q-0.1875 0.21875 -0.5625 0.28125l-0.921875 7.875l-1.765625 0l-1.53125 -4.546875zm10.1640625 -5.59375l0 1.703125l-1.90625 0l0 -1.703125l1.90625 0zm0.21875 3.046875l0 5.484375l1.921875 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-5.4375 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.921875 0l0 -3.890625l-1.296875 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l2.890625 0zm7.1953125 0l0 0.53125q0.4375 -0.375 0.953125 -0.5625q0.53125 -0.1875 1.15625 -0.1875q1.421875 0 2.25 0.890625q0.65625 0.703125 0.65625 1.84375l0 2.96875q0.5 0 0.734375 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.453125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.34375 0.234375 -0.5625q0.25 -0.234375 0.75 -0.234375l0 -3.015625q0 -0.53125 -0.28125 -0.765625q-0.359375 -0.3125 -1.09375 -0.3125q-0.5625 0 -0.984375 0.21875q-0.40625 0.203125 -1.046875 0.90625l0 2.96875q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -3.890625q-0.5 0 -0.75 -0.21875q-0.234375 -0.234375 -0.234375 -0.578125q0 -0.359375 0.234375 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.53125 0zm14.8984375 -3.046875l0 8.53125l0.265625 0q0.578125 0 0.828125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.25 0.21875 -0.828125 0.21875l-1.875 0l0 -0.390625q-0.546875 0.3125 -1.140625 0.484375q-0.59375 0.171875 -1.234375 0.171875q-1.8125 0 -2.921875 -1.046875q-1.09375 -1.046875 -1.09375 -2.609375q0 -1.625 1.15625 -2.765625q1.15625 -1.15625 2.828125 -1.15625q0.625 0 1.21875 0.203125q0.609375 0.1875 1.1875 0.5625l0 -1.984375l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l1.875 0zm-1.609375 6.796875q0 -0.984375 -0.703125 -1.671875q-0.6875 -0.6875 -1.6875 -0.6875q-1.0 0 -1.703125 0.6875q-0.6875 0.6875 -0.6875 1.65625q0 0.875 0.625 1.453125q0.625 0.5625 1.765625 0.5625q1.125 0 1.75 -0.5625q0.640625 -0.578125 0.640625 -1.4375zm11.6953125 -0.078125q0 0.921875 -0.515625 1.796875q-0.515625 0.859375 -1.53125 1.375q-1.0 0.515625 -2.109375 0.515625q-1.09375 0 -2.09375 -0.5q-1.0 -0.515625 -1.53125 -1.375q-0.515625 -0.875 -0.515625 -1.828125q0 -0.953125 0.53125 -1.875q0.53125 -0.9375 1.53125 -1.46875q1.0 -0.53125 2.078125 -0.53125q1.09375 0 2.109375 0.546875q1.015625 0.546875 1.53125 1.46875q0.515625 0.90625 0.515625 1.875zm-1.609375 0.015625q0 -0.78125 -0.546875 -1.421875q-0.765625 -0.875 -2.0 -0.875q-1.078125 0 -1.8125 0.703125q-0.71875 0.6875 -0.71875 1.59375q0 0.75 0.734375 1.40625q0.734375 0.65625 1.796875 0.65625q1.078125 0 1.8125 -0.65625q0.734375 -0.65625 0.734375 -1.40625zm7.0546875 0.453125l-1.109375 2.953125l-1.5 0l-1.34375 -5.5q-0.4375 -0.015625 -0.671875 -0.234375q-0.21875 -0.234375 -0.21875 -0.5625q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.484375 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.28125 0.609375q-0.21875 0.1875 -0.828125 0.1875l0.609375 2.546875l0.984375 -2.609375l1.421875 0l1.0 2.609375l0.625 -2.546875q-0.59375 0 -0.78125 -0.109375q-0.375 -0.25 -0.375 -0.6875q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l1.5 0q0.578125 0 0.828125 0.21875q0.25 0.21875 0.25 0.578125q0 0.328125 -0.21875 0.546875q-0.21875 0.21875 -0.640625 0.25l-1.3125 5.5l-1.484375 0l-1.171875 -2.953125zm11.3203125 -2.265625q-0.390625 -0.25 -0.828125 -0.359375q-0.421875 -0.125 -0.890625 -0.125q-0.921875 0 -1.46875 0.296875q-0.25 0.140625 -0.25 0.296875q0 0.171875 0.328125 0.34375q0.25 0.125 1.125 0.25q1.59375 0.21875 2.21875 0.4375q0.8125 0.28125 1.25 0.859375q0.453125 0.5625 0.453125 1.203125q0 0.859375 -0.75 1.4375q-1.09375 0.84375 -2.828125 0.84375q-0.6875 0 -1.28125 -0.125q-0.59375 -0.125 -1.078125 -0.359375q-0.125 0.09375 -0.265625 0.15625q-0.125 0.046875 -0.265625 0.046875q-0.375 0 -0.59375 -0.234375q-0.21875 -0.25 -0.21875 -0.828125l0 -0.546875q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.296875 0 0.484375 0.15625q0.203125 0.15625 0.3125 0.546875q0.359375 0.3125 0.875 0.484375q0.515625 0.15625 1.1875 0.15625q1.109375 0 1.71875 -0.34375q0.28125 -0.171875 0.28125 -0.359375q0 -0.3125 -0.40625 -0.515625q-0.421875 -0.203125 -1.71875 -0.34375q-1.921875 -0.203125 -2.578125 -0.78125q-0.640625 -0.578125 -0.640625 -1.40625q0 -0.859375 0.71875 -1.4375q0.984375 -0.78125 2.578125 -0.78125q0.5625 0 1.0625 0.109375q0.515625 0.109375 0.984375 0.328125q0.15625 -0.109375 0.28125 -0.15625q0.125 -0.0625 0.234375 -0.0625q0.328125 0 0.546875 0.25q0.21875 0.234375 0.21875 0.8125l0 0.390625q0 0.53125 -0.125 0.71875q-0.25 0.359375 -0.671875 0.359375q-0.296875 0 -0.515625 -0.171875q-0.21875 -0.1875 -0.28125 -0.484375zm6.9453125 1.96875l0 1.640625l1.625 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-3.46875 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l0.25 0l0 -6.265625l-0.25 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.234375 0.828125 -0.234375l3.6875 0.015625q1.625 0 2.5625 0.890625q0.953125 0.875 0.953125 2.15625q0 0.703125 -0.3125 1.328125q-0.25 0.46875 -0.8125 0.921875q-0.5625 0.453125 -1.15625 0.6875q-0.59375 0.234375 -1.5625 0.234375l-1.515625 0zm0 -1.609375l1.484375 0q1.046875 0 1.65625 -0.46875q0.625 -0.46875 0.625 -1.140625q0 -0.5625 -0.5 -0.984375q-0.5 -0.421875 -1.421875 -0.421875l-1.84375 0l0 3.015625zm11.9765625 4.859375l0 -0.375q-0.609375 0.3125 -1.34375 0.46875q-0.71875 0.171875 -1.3125 0.171875q-1.28125 0 -2.09375 -0.6875q-0.796875 -0.6875 -0.796875 -1.515625q0 -1.0 1.015625 -1.859375q1.03125 -0.875 2.84375 -0.875q0.734375 0 1.6875 0.15625l0 -0.375q0 -0.359375 -0.3125 -0.578125q-0.3125 -0.234375 -1.171875 -0.234375q-0.71875 0 -1.84375 0.28125q-0.421875 0.09375 -0.65625 0.09375q-0.328125 0 -0.546875 -0.21875q-0.21875 -0.234375 -0.21875 -0.59375q0 -0.203125 0.078125 -0.34375q0.078125 -0.15625 0.21875 -0.25q0.140625 -0.09375 0.578125 -0.21875q0.59375 -0.15625 1.203125 -0.25q0.625 -0.109375 1.125 -0.109375q1.5 0 2.3125 0.65625q0.828125 0.640625 0.828125 1.75l0 3.296875l0.28125 0q0.578125 0 0.8125 0.234375q0.25 0.21875 0.25 0.578125q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.875 0zm0 -2.875q-0.96875 -0.1875 -1.78125 -0.1875q-0.96875 0 -1.671875 0.484375q-0.4375 0.296875 -0.4375 0.609375q0 0.234375 0.203125 0.375q0.390625 0.25 1.078125 0.25q0.578125 0 1.296875 -0.21875q0.734375 -0.234375 1.3125 -0.625l0 -0.6875zm7.7578125 -2.625l0 3.21875q0 0.515625 0.21875 0.671875q0.328125 0.265625 1.171875 0.265625q1.21875 0 2.265625 -0.53125q0.390625 -0.203125 0.625 -0.203125q0.3125 0 0.53125 0.234375q0.234375 0.234375 0.234375 0.578125q0 0.3125 -0.25 0.53125q-0.375 0.375 -1.515625 0.6875q-1.125 0.3125 -1.890625 0.3125q-1.5 0 -2.25 -0.640625q-0.734375 -0.65625 -0.734375 -1.59375l0 -3.53125l-0.578125 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.21875 -0.25 -0.578125q0 -0.359375 0.25 -0.578125q0.25 -0.21875 0.828125 -0.21875l0.578125 0l0 -1.453125q0 -0.578125 0.21875 -0.8125q0.21875 -0.25 0.578125 -0.25q0.359375 0 0.578125 0.25q0.21875 0.234375 0.21875 0.8125l0 1.453125l2.96875 0q0.578125 0 0.8125 0.21875q0.25 0.21875 0.25 0.578125q0 0.359375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-2.96875 0zm8.3515625 -4.640625l0 3.421875q0.5 -0.296875 1.0 -0.4375q0.515625 -0.15625 1.046875 -0.15625q0.828125 0 1.46875 0.28125q0.65625 0.28125 1.078125 0.890625q0.421875 0.609375 0.421875 1.53125l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.5625 0 -0.8125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.4375 0.375 -0.671875q0.203125 -0.125 0.796875 -0.125l0 -2.890625q0 -0.625 -0.28125 -0.875q-0.359375 -0.328125 -1.078125 -0.328125q-0.53125 0 -0.953125 0.203125q-0.40625 0.203125 -1.09375 0.890625l0 3.0q0.609375 0 0.796875 0.125q0.375 0.234375 0.375 0.6875q0 0.34375 -0.25 0.578125q-0.234375 0.21875 -0.8125 0.21875l-1.828125 0q-0.578125 0 -0.828125 -0.21875q-0.234375 -0.234375 -0.234375 -0.59375q0 -0.4375 0.375 -0.671875q0.1875 -0.125 0.796875 -0.125l0 -6.921875l-0.265625 0q-0.578125 0 -0.828125 -0.21875q-0.25 -0.234375 -0.25 -0.59375q0 -0.34375 0.25 -0.5625q0.25 -0.234375 0.828125 -0.234375l1.875 0z" fill-rule="nonzero"></path><path fill="#000000" fill-opacity="0.0" d="m96.0 144.0l0 -80.0l80.0 0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m96.0 144.0l0 -80.0l68.0 0" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m164.0 67.30347l9.076202 -3.3034668l-9.076202 -3.303463z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m431.5013 143.08398l0 -78.99999l-68.0 0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m431.5013 143.08398l0 -78.99999l-56.0 0" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m375.5013 60.780525l-9.076202 3.3034668l9.076202 3.3034592z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m269.71652 104.53543l0 166.92914" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m269.71652 116.53543l0 154.92914" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m273.02 116.53543l-3.3034668 -9.076195l-3.3034668 9.076195z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m65.0 223.08398l-1.0078735 176.91339" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m64.93163 235.08379l-0.93950653 164.91359" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m68.23505 235.10262l-3.2517014 -9.094864l-3.3551178 9.05722z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m471.0 224.38058l-1.0078735 176.91336" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m470.93164 236.38037l-0.93951416 164.9136" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m474.23505 236.3992l-3.251709 -9.094864l-3.3551025 9.05722z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m128.50131 400.00266l0 -86.168l47.496002 0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m128.50131 400.00266l0 -86.168l35.496002 0" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m163.99731 317.13812l9.076202 -3.3034668l-9.076202 -3.3034668z" fill-rule="evenodd"></path><path fill="#000000" fill-opacity="0.0" d="m414.71902 400.00266l0 -86.168l-51.216003 0" fill-rule="nonzero"></path><path stroke="#000000" stroke-width="2.0" stroke-linejoin="round" stroke-linecap="butt" d="m414.71902 400.00266l0 -86.168l-39.216003 0" fill-rule="evenodd"></path><path stroke="#000000" stroke-width="2.0" stroke-linecap="butt" d="m375.50302 310.5312l-9.076172 3.3034668l9.076172 3.3034668z" fill-rule="evenodd"></path></g></svg> + diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index a8c1dc9e8034..ff5196de8600 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -106,8 +106,8 @@ we also call *flavours*: >>> PurePath('setup.py') # Running on a Unix machine PurePosixPath('setup.py') - Each element of *pathsegments* can be either a string or bytes object - representing a path segment; it can also be another path object:: + Each element of *pathsegments* can be either a string representing a + path segment, or another path object:: >>> PurePath('foo', 'some/path', 'bar') PurePosixPath('foo/some/path/bar') @@ -195,7 +195,7 @@ Paths of a different flavour compare unequal and cannot be ordered:: >>> PureWindowsPath('foo') < PurePosixPath('foo') Traceback (most recent call last): File "<stdin>", line 1, in <module> - TypeError: unorderable types: PureWindowsPath() < PurePosixPath() + TypeError: '<' not supported between instances of 'PureWindowsPath' and 'PurePosixPath' Operators @@ -522,6 +522,36 @@ Pure paths provide the following methods and properties: ValueError: '/etc/passwd' does not start with '/usr' +.. method:: PurePath.with_name(name) + + Return a new path with the :attr:`name` changed. If the original path + doesn't have a name, ValueError is raised:: + + >>> p = PureWindowsPath('c:/Downloads/pathlib.tar.gz') + >>> p.with_name('setup.py') + PureWindowsPath('c:/Downloads/setup.py') + >>> p = PureWindowsPath('c:/') + >>> p.with_name('setup.py') + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + File "/home/antoine/cpython/default/Lib/pathlib.py", line 751, in with_name + raise ValueError("%r has an empty name" % (self,)) + ValueError: PureWindowsPath('c:/') has an empty name + + +.. method:: PurePath.with_suffix(suffix) + + Return a new path with the :attr:`suffix` changed. If the original path + doesn't have a suffix, the new *suffix* is appended instead:: + + >>> p = PureWindowsPath('c:/Downloads/pathlib.tar.gz') + >>> p.with_suffix('.bz2') + PureWindowsPath('c:/Downloads/pathlib.tar.bz2') + >>> p = PureWindowsPath('README') + >>> p.with_suffix('.txt') + PureWindowsPath('README.txt') + + .. _concrete-paths: @@ -598,6 +628,17 @@ call fails (for example because the path doesn't exist): PosixPath('/home/antoine/pathlib') +.. classmethod:: Path.home() + + Return a new path object representing the user's home directory (as + returned by :func:`os.path.expanduser` with ``~`` construct):: + + >>> Path.home() + PosixPath('/home/antoine') + + .. versionadded:: 3.5 + + .. method:: Path.stat() Return information about this path (similarly to :func:`os.stat`). @@ -640,6 +681,18 @@ call fails (for example because the path doesn't exist): symlink *points to* an existing file or directory. +.. method:: Path.expanduser() + + Return a new path with expanded ``~`` and ``~user`` constructs, + as returned by :meth:`os.path.expanduser`:: + + >>> p = PosixPath('~/films/Monty Python') + >>> p.expanduser() + PosixPath('/home/eric/films/Monty Python') + + .. versionadded:: 3.5 + + .. method:: Path.glob(pattern) Glob the given *pattern* in the directory represented by this path, @@ -761,15 +814,29 @@ call fails (for example because the path doesn't exist): the symbolic link's information rather than its target's. -.. method:: Path.mkdir(mode=0o777, parents=False) +.. method:: Path.mkdir(mode=0o777, parents=False, exist_ok=False) Create a new directory at this given path. If *mode* is given, it is combined with the process' ``umask`` value to determine the file mode - and access flags. If the path already exists, :exc:`OSError` is raised. + and access flags. If the path already exists, :exc:`FileExistsError` + is raised. If *parents* is true, any missing parents of this path are created - as needed. If *parents* is false (the default), a missing parent raises - :exc:`OSError`. + as needed; they are created with the default permissions without taking + *mode* into account (mimicking the POSIX ``mkdir -p`` command). + + If *parents* is false (the default), a missing parent raises + :exc:`FileNotFoundError`. + + If *exist_ok* is false (the default), an :exc:`FileExistsError` is + raised if the target directory already exists. + + If *exist_ok* is true, :exc:`FileExistsError` exceptions will be + ignored (same behavior as the POSIX ``mkdir -p`` command), but only if the + last path component is not an existing non-directory file. + + .. versionchanged:: 3.5 + The *exist_ok* parameter was added. .. method:: Path.open(mode='r', buffering=-1, encoding=None, errors=None, newline=None) @@ -790,6 +857,34 @@ call fails (for example because the path doesn't exist): if the file's uid isn't found in the system database. +.. method:: Path.read_bytes() + + Return the binary contents of the pointed-to file as a bytes object:: + + >>> p = Path('my_binary_file') + >>> p.write_bytes(b'Binary file contents') + 20 + >>> p.read_bytes() + b'Binary file contents' + + .. versionadded:: 3.5 + + +.. method:: Path.read_text(encoding=None, errors=None) + + Return the decoded contents of the pointed-to file as a string:: + + >>> p = Path('my_text_file') + >>> p.write_text('Text file contents') + 18 + >>> p.read_text() + 'Text file contents' + + The optional parameters have the same meaning as in :func:`open`. + + .. versionadded:: 3.5 + + .. method:: Path.rename(target) Rename this file or directory to the given *target*. *target* can be @@ -850,6 +945,25 @@ call fails (for example because the path doesn't exist): Remove this directory. The directory must be empty. +.. method:: Path.samefile(other_path) + + Return whether this path points to the same file as *other_path*, which + can be either a Path object, or a string. The semantics are similar + to :func:`os.path.samefile` and :func:`os.path.samestat`. + + An :exc:`OSError` can be raised if either file cannot be accessed for some + reason. + + >>> p = Path('spam') + >>> q = Path('eggs') + >>> p.samefile(q) + False + >>> p.samefile('spam') + True + + .. versionadded:: 3.5 + + .. method:: Path.symlink_to(target, target_is_directory=False) Make this path a symbolic link to *target*. Under Windows, @@ -876,10 +990,40 @@ call fails (for example because the path doesn't exist): with the process' ``umask`` value to determine the file mode and access flags. If the file already exists, the function succeeds if *exist_ok* is true (and its modification time is updated to the current time), - otherwise :exc:`OSError` is raised. + otherwise :exc:`FileExistsError` is raised. .. method:: Path.unlink() Remove this file or symbolic link. If the path points to a directory, use :func:`Path.rmdir` instead. + + +.. method:: Path.write_bytes(data) + + Open the file pointed to in bytes mode, write *data* to it, and close the + file:: + + >>> p = Path('my_binary_file') + >>> p.write_bytes(b'Binary file contents') + 20 + >>> p.read_bytes() + b'Binary file contents' + + An existing file of the same name is overwritten. + + .. versionadded:: 3.5 + + +.. method:: Path.write_text(data, encoding=None, errors=None) + + Open the file pointed to in text mode, write *data* to it, and close the + file:: + + >>> p = Path('my_text_file') + >>> p.write_text('Text file contents') + 18 + >>> p.read_text() + 'Text file contents' + + .. versionadded:: 3.5 diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index 48a8a6b72230..c144db6c1aca 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -6,6 +6,9 @@ .. module:: pdb :synopsis: The Python debugger for interactive interpreters. +**Source code:** :source:`Lib/pdb.py` + +-------------- .. index:: single: debugging @@ -153,8 +156,8 @@ access further features, you have to do this yourself: that matches one of these patterns. [1]_ By default, Pdb sets a handler for the SIGINT signal (which is sent when the - user presses Ctrl-C on the console) when you give a ``continue`` command. - This allows you to break into the debugger again by pressing Ctrl-C. If you + user presses :kbd:`Ctrl-C` on the console) when you give a ``continue`` command. + This allows you to break into the debugger again by pressing :kbd:`Ctrl-C`. If you want Pdb not to touch the SIGINT handler, set *nosigint* tot true. Example call to enable tracing with *skip*:: diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst index 14d520696c88..2aab9091801f 100644 --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -15,27 +15,27 @@ .. sectionauthor:: Barry Warsaw <barry@python.org> -The :mod:`pickle` module implements a fundamental, but powerful algorithm for -serializing and de-serializing a Python object structure. "Pickling" is the -process whereby a Python object hierarchy is converted into a byte stream, and -"unpickling" is the inverse operation, whereby a byte stream is converted back -into an object hierarchy. Pickling (and unpickling) is alternatively known as -"serialization", "marshalling," [#]_ or "flattening", however, to avoid -confusion, the terms used here are "pickling" and "unpickling".. +The :mod:`pickle` module implements binary protocols for serializing and +de-serializing a Python object structure. *"Pickling"* is the process +whereby a Python object hierarchy is converted into a byte stream, and +*"unpickling"* is the inverse operation, whereby a byte stream +(from a :term:`binary file` or :term:`bytes-like object`) is converted +back into an object hierarchy. Pickling (and unpickling) is alternatively +known as "serialization", "marshalling," [#]_ or "flattening"; however, to +avoid confusion, the terms used here are "pickling" and "unpickling". .. warning:: - The :mod:`pickle` module is not intended to be secure against erroneous or - maliciously constructed data. Never unpickle data received from an untrusted - or unauthenticated source. + The :mod:`pickle` module is not secure against erroneous or maliciously + constructed data. Never unpickle data received from an untrusted or + unauthenticated source. Relationship to other Python modules ------------------------------------ -The :mod:`pickle` module has an transparent optimizer (:mod:`_pickle`) written -in C. It is used whenever available. Otherwise the pure Python implementation is -used. +Comparison with ``marshal`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ Python has a more primitive serialization module called :mod:`marshal`, but in general :mod:`pickle` should always be the preferred way to serialize Python @@ -69,17 +69,33 @@ The :mod:`pickle` module differs from :mod:`marshal` in several significant ways The :mod:`pickle` serialization format is guaranteed to be backwards compatible across Python releases. -Note that serialization is a more primitive notion than persistence; although -:mod:`pickle` reads and writes file objects, it does not handle the issue of -naming persistent objects, nor the (even more complicated) issue of concurrent -access to persistent objects. The :mod:`pickle` module can transform a complex -object into a byte stream and it can transform the byte stream into an object -with the same internal structure. Perhaps the most obvious thing to do with -these byte streams is to write them onto a file, but it is also conceivable to -send them across a network or store them in a database. The module -:mod:`shelve` provides a simple interface to pickle and unpickle objects on -DBM-style database files. +Comparison with ``json`` +^^^^^^^^^^^^^^^^^^^^^^^^ +There are fundamental differences between the pickle protocols and +`JSON (JavaScript Object Notation) <http://json.org>`_: + +* JSON is a text serialization format (it outputs unicode text, although + most of the time it is then encoded to ``utf-8``), while pickle is + a binary serialization format; + +* JSON is human-readable, while pickle is not; + +* JSON is interoperable and widely used outside of the Python ecosystem, + while pickle is Python-specific; + +* JSON, by default, can only represent a subset of the Python built-in + types, and no custom classes; pickle can represent an extremely large + number of Python types (many of them automatically, by clever usage + of Python's introspection facilities; complex cases can be tackled by + implementing :ref:`specific object APIs <pickle-inst>`). + +.. seealso:: + The :mod:`json` module: a standard library module allowing JSON + serialization and deserialization. + + +.. _pickle-protocols: Data stream format ------------------ @@ -100,7 +116,9 @@ The module :mod:`pickletools` contains tools for analyzing data streams generated by :mod:`pickle`. :mod:`pickletools` source code has extensive comments about opcodes used by pickle protocols. -There are currently 4 different protocols which can be used for pickling. +There are currently 5 different protocols which can be used for pickling. +The higher the protocol used, the more recent the version of Python needed +to read the pickle produced. * Protocol version 0 is the original "human-readable" protocol and is backwards compatible with earlier versions of Python. @@ -112,10 +130,27 @@ There are currently 4 different protocols which can be used for pickling. efficient pickling of :term:`new-style class`\es. Refer to :pep:`307` for information about improvements brought by protocol 2. -* Protocol version 3 was added in Python 3. It has explicit support for +* Protocol version 3 was added in Python 3.0. It has explicit support for :class:`bytes` objects and cannot be unpickled by Python 2.x. This is - the default as well as the current recommended protocol; use it whenever - possible. + the default protocol, and the recommended protocol when compatibility with + other Python 3 versions is required. + +* Protocol version 4 was added in Python 3.4. It adds support for very large + objects, pickling more kinds of objects, and some data format + optimizations. Refer to :pep:`3154` for information about improvements + brought by protocol 4. + +.. note:: + Serialization is a more primitive notion than persistence; although + :mod:`pickle` reads and writes file objects, it does not handle the issue of + naming persistent objects, nor the (even more complicated) issue of concurrent + access to persistent objects. The :mod:`pickle` module can transform a complex + object into a byte stream and it can transform the byte stream into an object + with the same internal structure. Perhaps the most obvious thing to do with + these byte streams is to write them onto a file, but it is also conceivable to + send them across a network or store them in a database. The :mod:`shelve` + module provides a simple interface to pickle and unpickle objects on + DBM-style database files. Module Interface @@ -131,13 +166,16 @@ The :mod:`pickle` module provides the following constants: .. data:: HIGHEST_PROTOCOL - The highest protocol version available. This value can be passed as a - *protocol* value. + An integer, the highest :ref:`protocol version <pickle-protocols>` + available. This value can be passed as a *protocol* value to functions + :func:`dump` and :func:`dumps` as well as the :class:`Pickler` + constructor. .. data:: DEFAULT_PROTOCOL - The default protocol used for pickling. May be less than HIGHEST_PROTOCOL. - Currently the default protocol is 3, a new protocol designed for Python 3.0. + An integer, the default :ref:`protocol version <pickle-protocols>` used + for pickling. May be less than :data:`HIGHEST_PROTOCOL`. Currently the + default protocol is 3, a new protocol designed for Python 3. The :mod:`pickle` module provides the following functions to make the pickling @@ -148,13 +186,10 @@ process more convenient: Write a pickled representation of *obj* to the open :term:`file object` *file*. This is equivalent to ``Pickler(file, protocol).dump(obj)``. - The optional *protocol* argument tells the pickler to use the given protocol; - supported protocols are 0, 1, 2, 3. The default protocol is 3; a - backward-incompatible protocol designed for Python 3.0. - - 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 optional *protocol* argument, an integer, tells the pickler to use + the given protocol; supported protocols are 0 to :data:`HIGHEST_PROTOCOL`. + If not specified, the default is :data:`DEFAULT_PROTOCOL`. If a negative + number is specified, :data:`HIGHEST_PROTOCOL` is selected. The *file* argument must have a write() method that accepts a single bytes argument. It can thus be an on-disk file opened for binary writing, a @@ -162,64 +197,57 @@ process more convenient: interface. If *fix_imports* is true and *protocol* is less than 3, pickle will try to - map the new Python 3.x names to the old module names used in Python 2.x, - so that the pickle data stream is readable with Python 2.x. + 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. .. function:: dumps(obj, protocol=None, \*, fix_imports=True) - Return the pickled representation of the object as a :class:`bytes` - object, instead of writing it to a file. - - The optional *protocol* argument tells the pickler to use the given protocol; - supported protocols are 0, 1, 2, 3. The default protocol is 3; a - backward-incompatible protocol designed for Python 3.0. + Return the pickled representation of the object as a :class:`bytes` object, + instead of writing it to a file. - 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.x names to the old module names used in Python 2.x, - so that the pickle data stream is readable with Python 2.x. + Arguments *protocol* and *fix_imports* have the same meaning as in + :func:`dump`. .. function:: load(file, \*, fix_imports=True, encoding="ASCII", errors="strict") - Read a pickled object representation from the open :term:`file object` *file* - and return the reconstituted object hierarchy specified therein. This is - equivalent to ``Unpickler(file).load()``. + Read a pickled object representation from the open :term:`file object` + *file* and return the reconstituted object hierarchy specified therein. + This is equivalent to ``Unpickler(file).load()``. - 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 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 an on-disk file opened - for binary reading, a :class:`io.BytesIO` object, or any other custom object + methods should return bytes. Thus *file* can be an on-disk file opened for + binary reading, a :class:`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.x. If *fix_imports* is true, pickle will try to map the old - Python 2.x names to the new names used in Python 3.x. The *encoding* and + 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.x; these default to 'ASCII' and 'strict', respectively. + 2; these default to 'ASCII' and 'strict', respectively. The *encoding* can + be 'bytes' to read these 8-bit string instances as bytes objects. .. function:: loads(bytes_object, \*, fix_imports=True, encoding="ASCII", errors="strict") Read a pickled object hierarchy from a :class:`bytes` object and return the - reconstituted object hierarchy specified therein + reconstituted object hierarchy specified therein. - 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 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.x. If *fix_imports* is true, pickle will try to map the old - Python 2.x names to the new names used in Python 3.x. The *encoding* and + 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.x; these default to 'ASCII' and 'strict', respectively. + 2; these default to 'ASCII' and 'strict', respectively. The *encoding* can + be 'bytes' to read these 8-bit string instances as bytes objects. The :mod:`pickle` module defines three exceptions: @@ -254,21 +282,19 @@ The :mod:`pickle` module exports two classes, :class:`Pickler` and 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. The default protocol is 3; a - backward-incompatible protocol designed for Python 3.0. - - 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 optional *protocol* argument, an integer, tells the pickler to use + the given protocol; supported protocols are 0 to :data:`HIGHEST_PROTOCOL`. + If not specified, the default is :data:`DEFAULT_PROTOCOL`. If a negative + number is specified, :data:`HIGHEST_PROTOCOL` is selected. The *file* argument must have a write() method that accepts a single bytes argument. It can thus be an on-disk file opened for binary writing, a - :class:`io.BytesIO` instance, or any other custom object that meets this interface. + :class:`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.x names to the old module names used in Python 2.x, - so that the pickle data stream is readable with Python 2.x. + 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. .. method:: dump(obj) @@ -330,16 +356,17 @@ The :mod:`pickle` module exports two classes, :class:`Pickler` and 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 an on-disk file object opened - for binary reading, a :class:`io.BytesIO` object, or any other custom object - that meets this interface. + methods should return bytes. Thus *file* can be an on-disk file object + opened for binary reading, a :class:`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.x. If *fix_imports* is true, pickle will try to map the old - Python 2.x names to the new names used in Python 3.x. The *encoding* and + 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.x; these default to 'ASCII' and 'strict', respectively. + 2; these default to 'ASCII' and 'strict', respectively. The *encoding* can + be 'bytes' to read these ß8-bit string instances as bytes objects. .. method:: load() @@ -398,7 +425,7 @@ The following types can be pickled: Attempts to pickle unpicklable objects will raise the :exc:`PicklingError` exception; when this happens, an unspecified number of bytes may have already been written to the underlying file. Trying to pickle a highly recursive data -structure may exceed the maximum recursion depth, a :exc:`RuntimeError` will be +structure may exceed the maximum recursion depth, a :exc:`RecursionError` will be raised in this case. You can carefully raise this limit with :func:`sys.setrecursionlimit`. @@ -461,7 +488,7 @@ methods: .. method:: object.__getnewargs_ex__() - In protocols 4 and newer, classes that implements the + In protocols 2 and newer, classes that implements the :meth:`__getnewargs_ex__` method can dictate the values passed to the :meth:`__new__` method upon unpickling. The method must return a pair ``(args, kwargs)`` where *args* is a tuple of positional arguments @@ -473,15 +500,22 @@ methods: class requires keyword-only arguments. Otherwise, it is recommended for compatibility to implement :meth:`__getnewargs__`. + .. versionchanged:: 3.6 + :meth:`__getnewargs_ex__` is now used in protocols 2 and 3. + .. method:: object.__getnewargs__() - This method serve a similar purpose as :meth:`__getnewargs_ex__` but - for protocols 2 and newer. It must return a tuple of arguments `args` - which will be passed to the :meth:`__new__` method upon unpickling. + This method serve a similar purpose as :meth:`__getnewargs_ex__`, but + supports only positional arguments. It must return a tuple of arguments + ``args`` which will be passed to the :meth:`__new__` method upon unpickling. + + :meth:`__getnewargs__` will not be called if :meth:`__getnewargs_ex__` is + defined. - In protocols 4 and newer, :meth:`__getnewargs__` will not be called if - :meth:`__getnewargs_ex__` is defined. + .. versionchanged:: 3.6 + Before Python 3.6, :meth:`__getnewargs__` was called instead of + :meth:`__getnewargs_ex__` in protocols 2 and 3. .. method:: object.__getstate__() @@ -811,6 +845,14 @@ alternatives such as the marshalling API in :mod:`xmlrpc.client` or third-party solutions. +Performance +----------- + +Recent versions of the pickle protocol (from protocol 2 and upwards) feature +efficient binary encodings for several common features and built-in types. +Also, the :mod:`pickle` module has a transparent optimizer written in C. + + .. _pickle-example: Examples @@ -824,7 +866,7 @@ For the simplest code, use the :func:`dump` and :func:`load` functions. :: data = { 'a': [1, 2.0, 3, 4+6j], 'b': ("character string", b"byte string"), - 'c': set([None, True, False]) + 'c': {None, True, False} } with open('data.pickle', 'wb') as f: diff --git a/Doc/library/pkgutil.rst b/Doc/library/pkgutil.rst index 22d44eb9bc77..5d3295db7ef8 100644 --- a/Doc/library/pkgutil.rst +++ b/Doc/library/pkgutil.rst @@ -58,7 +58,7 @@ support. .. deprecated:: 3.3 This emulation is no longer needed, as the standard import mechanism - is now fully PEP 302 compliant and available in :mod:`importlib` + is now fully PEP 302 compliant and available in :mod:`importlib`. .. class:: ImpLoader(fullname, file, filename, etc) @@ -67,22 +67,24 @@ support. .. deprecated:: 3.3 This emulation is no longer needed, as the standard import mechanism - is now fully PEP 302 compliant and available in :mod:`importlib` + is now fully PEP 302 compliant and available in :mod:`importlib`. .. function:: find_loader(fullname) Retrieve a :pep:`302` module loader for the given *fullname*. - This is a convenience wrapper around :func:`importlib.find_loader` that - sets the *path* argument correctly when searching for submodules, and - also ensures parent packages (if any) are imported before searching for - submodules. + This is a backwards compatibility wrapper around + :func:`importlib.util.find_spec` that converts most failures to + :exc:`ImportError` and only returns the loader rather than the full + :class:`ModuleSpec`. .. versionchanged:: 3.3 Updated to be based directly on :mod:`importlib` rather than relying on the package internal PEP 302 import emulation. + .. versionchanged:: 3.4 + Updated to be based on :pep:`451` .. function:: get_importer(path_item) @@ -109,14 +111,13 @@ support. not already imported, its containing package (if any) is imported, in order to establish the package ``__path__``. - This function uses :func:`iter_importers`, and is thus subject to the same - limitations regarding platform-specific special import locations such as the - Windows registry. - .. versionchanged:: 3.3 Updated to be based directly on :mod:`importlib` rather than relying on the package internal PEP 302 import emulation. + .. versionchanged:: 3.4 + Updated to be based on :pep:`451` + .. function:: iter_importers(fullname='') @@ -146,6 +147,7 @@ support. *prefix* is a string to output on the front of every module name on output. .. note:: + Only works for a :term:`finder` which defines an ``iter_modules()`` method. This interface is non-standard, so the module also provides implementations for :class:`importlib.machinery.FileFinder` and @@ -184,6 +186,7 @@ support. walk_packages(ctypes.__path__, ctypes.__name__ + '.') .. note:: + Only works for a :term:`finder` which defines an ``iter_modules()`` method. This interface is non-standard, so the module also provides implementations for :class:`importlib.machinery.FileFinder` and diff --git a/Doc/library/platform.rst b/Doc/library/platform.rst index e27f2ad8b0ef..e679317f06f3 100644 --- a/Doc/library/platform.rst +++ b/Doc/library/platform.rst @@ -117,7 +117,7 @@ Cross Platform .. function:: python_version() - Returns the Python version as string ``'major.minor.patchlevel'`` + Returns the Python version as string ``'major.minor.patchlevel'``. Note that unlike the Python ``sys.version``, the returned value will always include the patchlevel (it defaults to 0). @@ -247,6 +247,8 @@ Unix Platforms This is another name for :func:`linux_distribution`. + .. deprecated-removed:: 3.5 3.7 + .. function:: linux_distribution(distname='', version='', id='', supported_dists=('SuSE','debian','redhat','mandrake',...), full_distribution_name=1) Tries to determine the name of the Linux OS distribution name. @@ -263,6 +265,8 @@ Unix Platforms parameters. ``id`` is the item in parentheses after the version number. It is usually the version codename. + .. deprecated-removed:: 3.5 3.7 + .. function:: libc_ver(executable=sys.executable, lib='', version='', chunksize=2048) Tries to determine the libc version against which the file executable (defaults diff --git a/Doc/library/plistlib.rst b/Doc/library/plistlib.rst index 3cf8086528c0..2c1f3dd79e1b 100644 --- a/Doc/library/plistlib.rst +++ b/Doc/library/plistlib.rst @@ -32,9 +32,12 @@ Values can be strings, integers, floats, booleans, tuples, lists, dictionaries (but only with string keys), :class:`Data`, :class:`bytes`, :class:`bytesarray` or :class:`datetime.datetime` objects. +.. versionchanged:: 3.4 + New API, old API deprecated. Support for binary format plists added. + .. seealso:: - `PList manual page <http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html>`_ + `PList manual page <https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man5/plist.5.html>`_ Apple's documentation of the file format. @@ -79,6 +82,8 @@ This module defines the following functions: Load a plist from a bytes object. See :func:`load` for an explanation of the keyword arguments. + .. versionadded:: 3.4 + .. function:: dump(value, fp, \*, fmt=FMT_XML, sort_keys=True, skipkeys=False) @@ -102,8 +107,10 @@ This module defines the following functions: A :exc:`TypeError` will be raised if the object is of an unsupported type or a container that contains objects of unsupported types. - .. versionchanged:: 3.4 - Added the *fmt*, *sort_keys* and *skipkeys* arguments. + An :exc:`OverflowError` will be raised for integer values that cannot + be represented in (binary) plist files. + + .. versionadded:: 3.4 .. function:: dumps(value, \*, fmt=FMT_XML, sort_keys=True, skipkeys=False) @@ -112,6 +119,7 @@ This module defines the following functions: the documentation for :func:`dump` for an explanation of the keyword arguments of this function. + .. versionadded:: 3.4 The following functions are deprecated: @@ -121,7 +129,7 @@ The following functions are deprecated: and binary) file object. Returns the unpacked root object (which usually is a dictionary). - This function calls :func:`load` to do the actual work, the the documentation + This function calls :func:`load` to do the actual work, see the documentation of :func:`that function <load>` for an explanation of the keyword arguments. .. note:: @@ -130,7 +138,7 @@ The following functions are deprecated: to ``__getitem_``. This means that you can use attribute access to access items of these dictionaries. - .. deprecated: 3.4 Use :func:`load` instead. + .. deprecated:: 3.4 Use :func:`load` instead. .. function:: writePlist(rootObject, pathOrFile) @@ -138,7 +146,7 @@ The following functions are deprecated: Write *rootObject* to an XML plist file. *pathOrFile* may be either a file name or a (writable and binary) file object - .. deprecated: 3.4 Use :func:`dump` instead. + .. deprecated:: 3.4 Use :func:`dump` instead. .. function:: readPlistFromBytes(data) @@ -162,9 +170,6 @@ The following functions are deprecated: .. deprecated:: 3.4 Use :func:`dumps` instead. - .. versionchanged:: 3.4 - Added the *fmt*, *sort_keys* and *skipkeys* arguments. - The following classes are available: @@ -189,10 +194,10 @@ The following classes are available: It has one attribute, :attr:`data`, that can be used to retrieve the Python bytes object stored in it. - .. deprecated:: 3.4 Use a :class:`bytes` object instead + .. deprecated:: 3.4 Use a :class:`bytes` object instead. -The following constants are avaiable: +The following constants are available: .. data:: FMT_XML diff --git a/Doc/library/poplib.rst b/Doc/library/poplib.rst index e248d6b834a5..8468f4c49885 100644 --- a/Doc/library/poplib.rst +++ b/Doc/library/poplib.rst @@ -15,7 +15,7 @@ This module defines a class, :class:`POP3`, which encapsulates a connection to a POP3 server and implements the protocol as defined in :rfc:`1939`. The :class:`POP3` class supports both the minimal and optional command sets from -:rfc:`1939`. The :class:`POP3` class also supports the `STLS` command introduced +:rfc:`1939`. The :class:`POP3` class also supports the ``STLS`` command introduced in :rfc:`2595` to enable encrypted communication on an already established connection. Additionally, this module provides a class :class:`POP3_SSL`, which provides @@ -43,16 +43,23 @@ The :mod:`poplib` module provides two classes: This is a subclass of :class:`POP3` that connects to the server over an SSL encrypted socket. If *port* is not specified, 995, the standard POP3-over-SSL - port is used. *keyfile* and *certfile* are also optional - they can contain a - PEM formatted private key and certificate chain file for the SSL connection. - *timeout* works as in the :class:`POP3` constructor. *context* parameter is a - :class:`ssl.SSLContext` object which allows bundling SSL configuration - options, certificates and private keys into a single (potentially long-lived) - structure. + port is used. *timeout* works as in the :class:`POP3` constructor. + *context* is an optional :class:`ssl.SSLContext` object which allows + bundling SSL configuration options, certificates and private keys into a + single (potentially long-lived) structure. Please read :ref:`ssl-security` + for best practices. + + *keyfile* and *certfile* are a legacy alternative to *context* - they can + point to PEM-formatted private key and certificate chain files, + respectively, for the SSL connection. .. versionchanged:: 3.2 *context* parameter added. + .. versionchanged:: 3.4 + The class now supports hostname check with + :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see + :data:`ssl.HAS_SNI`). One exception is defined as an attribute of the :mod:`poplib` module: @@ -187,6 +194,15 @@ An :class:`POP3` instance has the following methods: the unique id for that message in the form ``'response mesgnum uid``, otherwise result is list ``(response, ['mesgnum uid', ...], octets)``. + +.. method:: POP3.utf8() + + Try to switch to UTF-8 mode. Returns the server response if successful, + raises :class:`error_proto` if not. Specified in :RFC:`6856`. + + .. versionadded:: 3.5 + + .. method:: POP3.stls(context=None) Start a TLS session on the active connection as specified in :rfc:`2595`. @@ -194,7 +210,12 @@ An :class:`POP3` instance has the following methods: *context* parameter is a :class:`ssl.SSLContext` object which allows bundling SSL configuration options, certificates and private keys into - a single (potentially long-lived) structure. + a single (potentially long-lived) structure. Please read :ref:`ssl-security` + for best practices. + + This method supports hostname checking via + :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see + :data:`ssl.HAS_SNI`). .. versionadded:: 3.4 diff --git a/Doc/library/pprint.rst b/Doc/library/pprint.rst index 447f8f70606c..0b44dc865ee0 100644 --- a/Doc/library/pprint.rst +++ b/Doc/library/pprint.rst @@ -211,7 +211,7 @@ Example ------- To demonstrate several uses of the :func:`pprint` function and its parameters, -let's fetch information about a project from `PyPI <https://pypi.python.org>`_:: +let's fetch information about a project from `PyPI <https://pypi.python.org/pypi>`_:: >>> import json >>> import pprint @@ -235,10 +235,10 @@ In its basic form, :func:`pprint` shows the whole object:: 'classifiers': ['Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2 :: Only'], - 'description': 'An extensible framework for Python programming, ' - 'with special focus\r\n' - 'on event-based network programming and ' - 'multiprotocol integration.', + 'description': 'An extensible framework for Python programming, with ' + 'special focus\r\n' + 'on event-based network programming and multiprotocol ' + 'integration.', 'docs_url': '', 'download_url': 'UNKNOWN', 'home_page': 'http://twistedmatrix.com/', @@ -288,10 +288,10 @@ contents):: 'cheesecake_documentation_id': None, 'cheesecake_installability_id': None, 'classifiers': [...], - 'description': 'An extensible framework for Python programming, ' - 'with special focus\r\n' - 'on event-based network programming and ' - 'multiprotocol integration.', + 'description': 'An extensible framework for Python programming, with ' + 'special focus\r\n' + 'on event-based network programming and multiprotocol ' + 'integration.', 'docs_url': '', 'download_url': 'UNKNOWN', 'home_page': 'http://twistedmatrix.com/', @@ -323,13 +323,12 @@ cannot be split, the specified width will be exceeded:: 'cheesecake_installability_id': None, 'classifiers': [...], 'description': 'An extensible ' - 'framework for ' - 'Python programming, ' - 'with special ' - 'focus\r\n' - 'on event-based ' - 'network programming ' - 'and multiprotocol ' + 'framework for Python ' + 'programming, with ' + 'special focus\r\n' + 'on event-based network ' + 'programming and ' + 'multiprotocol ' 'integration.', 'docs_url': '', 'download_url': 'UNKNOWN', @@ -344,8 +343,8 @@ cannot be split, the specified width will be exceeded:: 'release_url': 'http://pypi.python.org/pypi/Twisted/12.3.0', 'requires_python': None, 'stable_version': None, - 'summary': 'An asynchronous ' - 'networking framework ' - 'written in Python', + 'summary': 'An asynchronous networking ' + 'framework written in ' + 'Python', 'version': '12.3.0'}, 'urls': [{...}, {...}]} diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index f2453f1f856c..959d9b98a846 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -33,7 +33,7 @@ profiling interface: 2. :mod:`profile`, a pure Python module whose interface is imitated by :mod:`cProfile`, but which adds significant overhead to profiled programs. If you're trying to extend the profiler in some way, the task might be easier - with this module. + with this module. Originally designed and written by Jim Roskind. .. note:: @@ -172,7 +172,7 @@ This will sort all the statistics by file name, and then print out statistics for only the class init methods (since they are spelled with ``__init__`` in them). As one final example, you could try:: - p.sort_stats('time', 'cum').print_stats(.5, 'init') + p.sort_stats('time', 'cumulative').print_stats(.5, 'init') This line sorts statistics with a primary key of time, and a secondary key of cumulative time, and then prints out some of the statistics. To be specific, the @@ -638,7 +638,7 @@ you are using :class:`profile.Profile` or :class:`cProfile.Profile`, pr = cProfile.Profile(your_integer_time_func, 0.001) - As the :mod:`cProfile.Profile` class cannot be calibrated, custom timer + As the :class:`cProfile.Profile` class cannot be calibrated, custom timer functions should be used with care and should be as fast as possible. For the best results with a custom timer, it might be necessary to hard-code it in the C source of the internal :mod:`_lsprof` module. diff --git a/Doc/library/pty.rst b/Doc/library/pty.rst index 90baec542fea..b8a3897ab8f7 100644 --- a/Doc/library/pty.rst +++ b/Doc/library/pty.rst @@ -58,40 +58,32 @@ The following program acts like the Unix command :manpage:`script(1)`, using a pseudo-terminal to record all input and output of a terminal session in a "typescript". :: - import sys, os, time, getopt - import pty - - mode = 'wb' - shell = 'sh' - filename = 'typescript' - if 'SHELL' in os.environ: - shell = os.environ['SHELL'] - - try: - opts, args = getopt.getopt(sys.argv[1:], 'ap') - except getopt.error as msg: - print('%s: %s' % (sys.argv[0], msg)) - sys.exit(2) - - for opt, arg in opts: - # option -a: append to typescript file - if opt == '-a': - mode = 'ab' - # option -p: use a Python shell as the terminal command - elif opt == '-p': - shell = sys.executable - if args: - filename = args[0] - - script = open(filename, mode) - - def read(fd): - data = os.read(fd, 1024) - script.write(data) - return data - - sys.stdout.write('Script started, file is %s\n' % filename) - script.write(('Script started on %s\n' % time.asctime()).encode()) - pty.spawn(shell, read) - script.write(('Script done on %s\n' % time.asctime()).encode()) - sys.stdout.write('Script done, file is %s\n' % filename) + import argparse + import os + import pty + import sys + import time + + parser = argparse.ArgumentParser() + parser.add_argument('-a', dest='append', action='http://github.com/store_true') + parser.add_argument('-p', dest='use_python', action='http://github.com/store_true') + parser.add_argument('filename', nargs='?', default='typescript') + options = parser.parse_args() + + shell = sys.executable if options.use_python else os.environ.get('SHELL', 'sh') + filename = options.filename + mode = 'ab' if options.append else 'wb' + + with open(filename, mode) as script: + def read(fd): + data = os.read(fd, 1024) + script.write(data) + return data + + print('Script started, file is', filename) + script.write(('Script started on %s\n' % time.asctime()).encode()) + + pty.spawn(shell, read) + + script.write(('Script done on %s\n' % time.asctime()).encode()) + print('Script done, file is', filename) diff --git a/Doc/library/py_compile.rst b/Doc/library/py_compile.rst index bae8450b7c92..97f2b20d2a47 100644 --- a/Doc/library/py_compile.rst +++ b/Doc/library/py_compile.rst @@ -29,9 +29,9 @@ byte-code cache files in the directory containing the source code. .. function:: compile(file, cfile=None, dfile=None, doraise=False, optimize=-1) Compile a source file to byte-code and write out the byte-code cache file. - The source code is loaded from the file name *file*. The byte-code is - written to *cfile*, which defaults to the :PEP:`3147` path, ending in - ``.pyc`` (``.pyo`` if optimization is enabled in the current interpreter). + The source code is loaded from the file name *file*. The byte-code is + written to *cfile*, which defaults to the :pep:`3147`/:pep:`488` path, ending + in ``.pyc``. For example, if *file* is ``/foo/bar/baz.py`` *cfile* will default to ``/foo/bar/__pycache__/baz.cpython-32.pyc`` for Python 3.2. If *dfile* is specified, it is used as the name of the source file in error messages when @@ -68,7 +68,7 @@ byte-code cache files in the directory containing the source code. .. function:: main(args=None) Compile several source files. The files named in *args* (or on the command - line, if *args* is ``None``) are compiled and the resulting bytecode is + line, if *args* is ``None``) are compiled and the resulting byte-code is cached in the normal manner. This function does not search a directory structure to locate source files; it only compiles files named explicitly. If ``'-'`` is the only parameter in args, the list of files is taken from @@ -86,4 +86,3 @@ could not be compiled. Module :mod:`compileall` Utilities to compile all Python source files in a directory tree. - diff --git a/Doc/library/pydoc.rst b/Doc/library/pydoc.rst index e10086551546..b5e3233619cd 100644 --- a/Doc/library/pydoc.rst +++ b/Doc/library/pydoc.rst @@ -20,6 +20,13 @@ The :mod:`pydoc` module automatically generates documentation from Python modules. The documentation can be presented as pages of text on the console, served to a Web browser, or saved to HTML files. +For modules, classes, functions and methods, the displayed documentation is +derived from the docstring (i.e. the :attr:`__doc__` attribute) of the object, +and recursively of its documentable members. If there is no docstring, +:mod:`pydoc` tries to obtain a description from the block of comment lines just +above the definition of the class, function or method in the source file, or at +the top of the module (see :func:`inspect.getcomments`). + The built-in function :func:`help` invokes the online help system in the interactive interpreter, which uses :mod:`pydoc` to generate its documentation as text on the console. The same text documentation can also be viewed from @@ -44,6 +51,10 @@ produced for that file. executed on that occasion. Use an ``if __name__ == '__main__':`` guard to only execute code when a file is invoked as a script and not just imported. +When printing output to the console, :program:`pydoc` attempts to paginate the +output for easier reading. If the :envvar:`PAGER` environment variable is set, +:program:`pydoc` will use its value as a pagination program. + Specifying a ``-w`` flag before the argument will cause HTML documentation to be written out to a file in the current directory, instead of displaying text on the console. @@ -59,11 +70,6 @@ will start a HTTP server on port 1234, allowing you to browse the documentation at ``http://localhost:1234/`` in your preferred Web browser. Specifying ``0`` as the port number will select an arbitrary unused port. -:program:`pydoc -g` will start the server and additionally bring up a -small :mod:`tkinter`\ -based graphical interface to help you search for -documentation pages. The ``-g`` option is deprecated, since the server can -now be controlled directly from HTTP clients. - :program:`pydoc -b` will start the server and additionally open a web browser to a module index page. Each served page has a navigation bar at the top where you can *Get* help on an individual item, *Search* all modules with a @@ -76,11 +82,19 @@ documents precisely the version of the module you would get if you started the Python interpreter and typed ``import spam``. Module docs for core modules are assumed to reside in -``http://docs.python.org/X.Y/library/`` where ``X`` and ``Y`` are the +``https://docs.python.org/X.Y/library/`` where ``X`` and ``Y`` are the major and minor version numbers of the Python interpreter. This can be overridden by setting the :envvar:`PYTHONDOCS` environment variable to a different URL or to a local directory containing the Library Reference Manual pages. .. versionchanged:: 3.2 - Added the ``-b`` option, deprecated the ``-g`` option. + Added the ``-b`` option. + +.. versionchanged:: 3.3 + The ``-g`` command line option was removed. + +.. versionchanged:: 3.4 + :mod:`pydoc` now uses :func:`inspect.signature` rather than + :func:`inspect.getfullargspec` to extract signature information from + callables. diff --git a/Doc/library/pyexpat.rst b/Doc/library/pyexpat.rst index b1543d8002b4..78aa99c48ee8 100644 --- a/Doc/library/pyexpat.rst +++ b/Doc/library/pyexpat.rst @@ -100,6 +100,11 @@ The :mod:`xml.parsers.expat` module contains two functions: http://www.python.org/ns/ elem1 elem2 + Due to limitations in the ``Expat`` library used by :mod:`pyexpat`, + the :class:`xmlparser` instance returned can only be used to parse a single + XML document. Call ``ParserCreate`` for each document to provide unique + parser instances. + .. seealso:: @@ -119,7 +124,9 @@ XMLParser Objects Parses the contents of the string *data*, calling the appropriate handler functions to process the parsed data. *isfinal* must be true on the final call - to this method. *data* can be the empty string at any time. + to this method; it allows the parsing of a single file in fragments, + not the submission of multiple files. + *data* can be the empty string at any time. .. method:: xmlparser.ParseFile(file) @@ -861,5 +868,5 @@ The ``errors`` module has the following attributes: .. [#] The encoding string included in XML output should conform to the appropriate standards. For example, "UTF-8" is valid, but "UTF8" is not. See http://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl - and http://www.iana.org/assignments/character-sets . + and http://www.iana.org/assignments/character-sets/character-sets.xhtml. diff --git a/Doc/library/queue.rst b/Doc/library/queue.rst index 680d6900529d..1cb09353770d 100644 --- a/Doc/library/queue.rst +++ b/Doc/library/queue.rst @@ -158,22 +158,32 @@ fully processed by daemon consumer threads. Example of how to wait for enqueued tasks to be completed:: - def worker(): - while True: - item = q.get() - do_work(item) - q.task_done() - - q = Queue() - for i in range(num_worker_threads): - t = Thread(target=worker) - t.daemon = True + def worker(): + while True: + item = q.get() + if item is None: + break + do_work(item) + q.task_done() + + q = queue.Queue() + threads = [] + for i in range(num_worker_threads): + t = threading.Thread(target=worker) t.start() + threads.append(t) - for item in source(): - q.put(item) + for item in source(): + q.put(item) - q.join() # block until all tasks are done + # block until all tasks are done + q.join() + + # stop workers + for i in range(num_worker_threads): + q.put(None) + for t in threads: + t.join() .. seealso:: diff --git a/Doc/library/quopri.rst b/Doc/library/quopri.rst index 755811adfd84..3a74cf8511b7 100644 --- a/Doc/library/quopri.rst +++ b/Doc/library/quopri.rst @@ -24,9 +24,8 @@ sending a graphics file. .. function:: decode(input, output, header=False) Decode the contents of the *input* file and write the resulting decoded binary - data to the *output* file. *input* and *output* must be :term:`file objects - <file object>`. *input* will be read until ``input.readline()`` returns an - empty string. If the optional argument *header* is present and true, underscore + data to the *output* file. *input* and *output* must be :term:`binary file objects + <file object>`. If the optional argument *header* is present and true, underscore will be decoded as space. This is used to decode "Q"-encoded headers as described in :rfc:`1522`: "MIME (Multipurpose Internet Mail Extensions) Part Two: Message Header Extensions for Non-ASCII Text". @@ -34,27 +33,28 @@ sending a graphics file. .. function:: encode(input, output, quotetabs, header=False) - Encode the contents of the *input* file and write the resulting quoted-printable - data to the *output* file. *input* and *output* must be :term:`file objects - <file object>`. *input* will be read until ``input.readline()`` returns an - empty string. *quotetabs* is a flag which controls whether to encode embedded - spaces and tabs; when true it encodes such embedded whitespace, and when - false it leaves them unencoded. Note that spaces and tabs appearing at the - end of lines are always encoded, as per :rfc:`1521`. *header* is a flag - which controls if spaces are encoded as underscores as per :rfc:`1522`. + Encode the contents of the *input* file and write the resulting quoted- + printable data to the *output* file. *input* and *output* must be + :term:`binary file objects <file object>`. *quotetabs*, a flag which controls + whether to encode embedded spaces and tabs must be provideda and when true it + encodes such embedded whitespace, and when false it leaves them unencoded. + Note that spaces and tabs appearing at the end of lines are always encoded, + as per :rfc:`1521`. *header* is a flag which controls if spaces are encoded + as underscores as per :rfc:`1522`. .. function:: decodestring(s, header=False) - Like :func:`decode`, except that it accepts a source string and returns the - corresponding decoded string. + Like :func:`decode`, except that it accepts a source :class:`bytes` and + returns the corresponding decoded :class:`bytes`. .. function:: encodestring(s, quotetabs=False, header=False) - Like :func:`encode`, except that it accepts a source string and returns the - corresponding encoded string. *quotetabs* and *header* are optional - (defaulting to ``False``), and are passed straight through to :func:`encode`. + Like :func:`encode`, except that it accepts a source :class:`bytes` and + returns the corresponding encoded :class:`bytes`. By default, it sends a + False value to *quotetabs* parameter of the :func:`encode` function. + .. seealso:: diff --git a/Doc/library/random.rst b/Doc/library/random.rst index 11dd367f8af0..f8b772749f48 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -46,8 +46,7 @@ from sources provided by the operating system. .. warning:: The pseudo-random generators of this module should not be used for - security purposes. Use :func:`os.urandom` or :class:`SystemRandom` if - you require a cryptographically secure pseudo-random number generator. + security purposes. Bookkeeping functions: diff --git a/Doc/library/re.rst b/Doc/library/re.rst index fa6a9ce71968..888458449a1f 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -38,13 +38,6 @@ module-level functions and methods on that don't require you to compile a regex object first, but miss some fine-tuning parameters. -.. seealso:: - - Mastering Regular Expressions - Book on regular expressions by Jeffrey Friedl, published by O'Reilly. The - second edition of the book no longer covers Python at all, but the first - edition covered writing good regular expression patterns in great detail. - .. _re-syntax: @@ -304,6 +297,9 @@ The special characters are: >>> m.group(0) 'egg' + .. versionchanged: 3.5 + Added support for group references of fixed length. + ``(?<!...)`` Matches if the current position in the string is not preceded by a match for ``...``. This is called a :dfn:`negative lookbehind assertion`. Similar to @@ -317,7 +313,7 @@ The special characters are: optional and can be omitted. For example, ``(<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$)`` is a poor email matching pattern, which will match with ``'<user@host.com>'`` as well as ``'user@host.com'``, but - not with ``'<user@host.com'`` nor ``'user@host.com>'`` . + not with ``'<user@host.com'`` nor ``'user@host.com>'``. The special sequences consist of ``'\'`` and a character from the list below. @@ -442,6 +438,18 @@ three digits in length. .. versionchanged:: 3.3 The ``'\u'`` and ``'\U'`` escape sequences have been added. +.. deprecated-removed:: 3.5 3.6 + Unknown escapes consist of ``'\'`` and ASCII letter now raise a + deprecation warning and will be forbidden in Python 3.6. + + +.. seealso:: + + Mastering Regular Expressions + Book on regular expressions by Jeffrey Friedl, published by O'Reilly. The + second edition of the book no longer covers Python at all, but the first + edition covered writing good regular expression patterns in great detail. + .. _contents-of-module-re: @@ -458,8 +466,8 @@ form. .. function:: compile(pattern, flags=0) Compile a regular expression pattern into a regular expression object, which - can be used for matching using its :func:`match` and :func:`search` methods, - described below. + can be used for matching using its :func:`~regex.match` and + :func:`~regex.search` methods, described below. The expression's behaviour can be modified by specifying a *flags* value. Values can be any of the following variables, combined using bitwise OR (the @@ -520,7 +528,11 @@ form. current locale. The use of this flag is discouraged as the locale mechanism is very unreliable, and it only handles one "culture" at a time anyway; you should use Unicode matching instead, which is the default in Python 3 - for Unicode (str) patterns. + for Unicode (str) patterns. This flag makes sense only with bytes patterns. + + .. deprecated-removed:: 3.5 3.6 + Deprecated the use of :const:`re.LOCALE` with string patterns or + :const:`re.ASCII`. .. data:: M @@ -563,7 +575,7 @@ form. .. function:: search(pattern, string, flags=0) - Scan through *string* looking for a location where the regular expression + Scan through *string* looking for the first location where the regular expression *pattern* produces a match, and return a corresponding :ref:`match object <match-objects>`. Return ``None`` if no position in the string matches the pattern; note that this is different from finding a zero-length match at some @@ -621,17 +633,37 @@ form. That way, separator components are always found at the same relative indices within the result list. - Note that *split* will never split a string on an empty pattern match. - For example: + .. note:: + + :func:`split` doesn't currently split a string on an empty pattern match. + For example: + + >>> re.split('x*', 'axbc') + ['a', 'bc'] + + Even though ``'x*'`` also matches 0 'x' before 'a', between 'b' and 'c', + and after 'c', currently these matches are ignored. The correct behavior + (i.e. splitting on empty matches too and returning ``['', 'a', 'b', 'c', + '']``) will be implemented in future versions of Python, but since this + is a backward incompatible change, a :exc:`FutureWarning` will be raised + in the meanwhile. + + Patterns that can only match empty strings currently never split the + string. Since this doesn't match the expected behavior, a + :exc:`ValueError` will be raised starting from Python 3.5:: - >>> re.split('x*', 'foo') - ['foo'] - >>> re.split("(?m)^$", "foo\n\nbar\n") - ['foo\n\nbar\n'] + >>> re.split("^$", "foo\n\nbar\n", flags=re.M) + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + ... + ValueError: split() requires a non-empty pattern match. .. versionchanged:: 3.1 Added the optional flags argument. + .. versionchanged:: 3.5 + Splitting on a pattern that could match an empty string now raises + a warning. Patterns that can only match empty strings are now rejected. .. function:: findall(pattern, string, flags=0) @@ -659,7 +691,7 @@ form. *string* is returned unchanged. *repl* can be a string or a function; if it is a string, any backslash escapes in it are processed. That is, ``\n`` is converted to a single newline character, ``\r`` is converted to a carriage return, and - so forth. Unknown escapes such as ``\j`` are left alone. Backreferences, such + so forth. Unknown escapes such as ``\&`` are left alone. Backreferences, such as ``\6``, are replaced with the substring matched by group 6 in the pattern. For example: @@ -701,6 +733,13 @@ form. .. versionchanged:: 3.1 Added the optional flags argument. + .. versionchanged:: 3.5 + Unmatched groups are replaced with an empty string. + + .. deprecated-removed:: 3.5 3.6 + Unknown escapes consist of ``'\'`` and ASCII letter now raise a + deprecation warning and will be forbidden in Python 3.6. + .. function:: subn(pattern, repl, string, count=0, flags=0) @@ -710,6 +749,9 @@ form. .. versionchanged:: 3.1 Added the optional flags argument. + .. versionchanged:: 3.5 + Unmatched groups are replaced with an empty string. + .. function:: escape(string) @@ -726,13 +768,36 @@ form. Clear the regular expression cache. -.. exception:: error +.. exception:: error(msg, pattern=None, pos=None) Exception raised when a string passed to one of the functions here is not a valid regular expression (for example, it might contain unmatched parentheses) or when some other error occurs during compilation or matching. It is never an - error if a string contains no match for a pattern. + error if a string contains no match for a pattern. The error instance has + the following additional attributes: + + .. attribute:: msg + + The unformatted error message. + + .. attribute:: pattern + + The regular expression pattern. + + .. attribute:: pos + + The index of *pattern* where compilation failed. + + .. attribute:: lineno + + The line corresponding to *pos*. + + .. attribute:: colno + + The column corresponding to *pos*. + .. versionchanged:: 3.5 + Added additional attributes. .. _re-objects: @@ -801,7 +866,7 @@ attributes: >>> pattern.fullmatch("dog") # No match as "o" is not at the start of "dog". >>> pattern.fullmatch("ogre") # No match as not the full string matches. >>> pattern.fullmatch("doggie", 1, 3) # Matches within given limits. - <_sre.SRE_Match object at ...> + <_sre.SRE_Match object; span=(1, 3), match='og'> .. versionadded:: 3.4 @@ -885,6 +950,8 @@ Match objects support the following methods and attributes: (``\g<1>``, ``\g<name>``) are replaced by the contents of the corresponding group. + .. versionchanged:: 3.5 + Unmatched groups are replaced with an empty string. .. method:: match.group([group1, ...]) @@ -1333,36 +1400,36 @@ successive matches:: Token = collections.namedtuple('Token', ['typ', 'value', 'line', 'column']) - def tokenize(s): + def tokenize(code): keywords = {'IF', 'THEN', 'ENDIF', 'FOR', 'NEXT', 'GOSUB', 'RETURN'} token_specification = [ ('NUMBER', r'\d+(\.\d*)?'), # Integer or decimal number ('ASSIGN', r':='), # Assignment operator ('END', r';'), # Statement terminator ('ID', r'[A-Za-z]+'), # Identifiers - ('OP', r'[+*\/\-]'), # Arithmetic operators + ('OP', r'[+\-*/]'), # Arithmetic operators ('NEWLINE', r'\n'), # Line endings - ('SKIP', r'[ \t]'), # Skip over spaces and tabs + ('SKIP', r'[ \t]+'), # Skip over spaces and tabs + ('MISMATCH',r'.'), # Any other character ] tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification) - get_token = re.compile(tok_regex).match - line = 1 - pos = line_start = 0 - mo = get_token(s) - while mo is not None: - typ = mo.lastgroup - if typ == 'NEWLINE': - line_start = pos - line += 1 - elif typ != 'SKIP': - val = mo.group(typ) - if typ == 'ID' and val in keywords: - typ = val - yield Token(typ, val, line, mo.start()-line_start) - pos = mo.end() - mo = get_token(s, pos) - if pos != len(s): - raise RuntimeError('Unexpected character %r on line %d' %(s[pos], line)) + line_num = 1 + line_start = 0 + for mo in re.finditer(tok_regex, code): + kind = mo.lastgroup + value = mo.group(kind) + if kind == 'NEWLINE': + line_start = mo.end() + line_num += 1 + elif kind == 'SKIP': + pass + elif kind == 'MISMATCH': + raise RuntimeError('%r unexpected on line %d' % (value, line_num)) + else: + if kind == 'ID' and value in keywords: + kind = value + column = mo.start() - line_start + yield Token(kind, value, line_num, column) statements = ''' IF quantity THEN @@ -1376,22 +1443,22 @@ successive matches:: The tokenizer produces the following output:: - Token(typ='IF', value='IF', line=2, column=5) - Token(typ='ID', value='quantity', line=2, column=8) - Token(typ='THEN', value='THEN', line=2, column=17) - Token(typ='ID', value='total', line=3, column=9) - Token(typ='ASSIGN', value=':=', line=3, column=15) - Token(typ='ID', value='total', line=3, column=18) - Token(typ='OP', value='+', line=3, column=24) - Token(typ='ID', value='price', line=3, column=26) - Token(typ='OP', value='*', line=3, column=32) - Token(typ='ID', value='quantity', line=3, column=34) - Token(typ='END', value=';', line=3, column=42) - Token(typ='ID', value='tax', line=4, column=9) - Token(typ='ASSIGN', value=':=', line=4, column=13) - Token(typ='ID', value='price', line=4, column=16) - Token(typ='OP', value='*', line=4, column=22) - Token(typ='NUMBER', value='0.05', line=4, column=24) - Token(typ='END', value=';', line=4, column=28) - Token(typ='ENDIF', value='ENDIF', line=5, column=5) - Token(typ='END', value=';', line=5, column=10) + Token(typ='IF', value='IF', line=2, column=4) + Token(typ='ID', value='quantity', line=2, column=7) + Token(typ='THEN', value='THEN', line=2, column=16) + Token(typ='ID', value='total', line=3, column=8) + Token(typ='ASSIGN', value=':=', line=3, column=14) + Token(typ='ID', value='total', line=3, column=17) + Token(typ='OP', value='+', line=3, column=23) + Token(typ='ID', value='price', line=3, column=25) + Token(typ='OP', value='*', line=3, column=31) + Token(typ='ID', value='quantity', line=3, column=33) + Token(typ='END', value=';', line=3, column=41) + Token(typ='ID', value='tax', line=4, column=8) + Token(typ='ASSIGN', value=':=', line=4, column=12) + Token(typ='ID', value='price', line=4, column=15) + Token(typ='OP', value='*', line=4, column=21) + Token(typ='NUMBER', value='0.05', line=4, column=23) + Token(typ='END', value=';', line=4, column=27) + Token(typ='ENDIF', value='ENDIF', line=5, column=4) + Token(typ='END', value=';', line=5, column=9) diff --git a/Doc/library/readline.rst b/Doc/library/readline.rst index 692310b941dc..3864f0d22506 100644 --- a/Doc/library/readline.rst +++ b/Doc/library/readline.rst @@ -59,6 +59,14 @@ The :mod:`readline` module defines the following functions: Save a readline history file. The default filename is :file:`~/.history`. +.. function:: append_history_file(nelements[, filename]) + + Append the last *nelements* of history to a file. The default filename is + :file:`~/.history`. The file must already exist. + + .. versionadded:: 3.5 + + .. function:: clear_history() Clear the current history. (Note: this function is not available if the @@ -209,6 +217,26 @@ from the user's :envvar:`PYTHONSTARTUP` file. :: This code is actually automatically run when Python is run in :ref:`interactive mode <tut-interactive>` (see :ref:`rlcompleter-config`). +The following example achieves the same goal but supports concurrent interactive +sessions, by only appending the new history. :: + + import atexit + import os + import realine + histfile = os.path.join(os.path.expanduser("~"), ".python_history") + + try: + readline.read_history_file(histfile) + h_len = readline.get_history_length() + except FileNotFoundError: + open(histfile, 'wb').close() + h_len = 0 + + def save(prev_h_len, histfile): + new_h_len = readline.get_history_length() + readline.append_history_file(new_h_len - prev_h_len, histfile) + atexit.register(save, h_len, histfile) + The following example extends the :class:`code.InteractiveConsole` class to support history save/restore. :: @@ -234,4 +262,3 @@ support history save/restore. :: def save_history(self, histfile): readline.write_history_file(histfile) - diff --git a/Doc/library/reprlib.rst b/Doc/library/reprlib.rst index 24a8e529e7d9..ee9a10d37e36 100644 --- a/Doc/library/reprlib.rst +++ b/Doc/library/reprlib.rst @@ -49,8 +49,8 @@ string instead. >>> class MyList(list): ... @recursive_repr() - ... def __repr__(self): - ... return '<' + '|'.join(map(repr, self)) + '>' + ... def __repr__(self): + ... return '<' + '|'.join(map(repr, self)) + '>' ... >>> m = MyList('abc') >>> m.append(m) @@ -129,9 +129,9 @@ which format specific object types. Formatting methods for specific types are implemented as methods with a name based on the type name. In the method name, **TYPE** is replaced by - ``string.join(string.split(type(obj).__name__, '_'))``. Dispatch to these - methods is handled by :meth:`repr1`. Type-specific methods which need to - recursively format a value should call ``self.repr1(subobj, level - 1)``. + ``'_'.join(type(obj).__name__.split())``. Dispatch to these methods is + handled by :meth:`repr1`. Type-specific methods which need to recursively + format a value should call ``self.repr1(subobj, level - 1)``. .. _subclassing-reprs: @@ -148,12 +148,11 @@ for file objects could be added:: import sys class MyRepr(reprlib.Repr): - def repr_file(self, obj, level): - if obj.name in ['<stdin>', '<stdout>', '<stderr>']: + + def repr_TextIOWrapper(self, obj, level): + if obj.name in {'<stdin>', '<stdout>', '<stderr>'}: return obj.name - else: - return repr(obj) + return repr(obj) aRepr = MyRepr() print(aRepr.repr(sys.stdin)) # prints '<stdin>' - diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst index 9bb5848e3a3c..7c0e4caf75ac 100644 --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -45,7 +45,7 @@ this module for those platforms. .. data:: RLIM_INFINITY - Constant used to represent the the limit for an unlimited resource. + Constant used to represent the limit for an unlimited resource. .. function:: getrlimit(resource) @@ -217,6 +217,34 @@ platform. .. versionadded:: 3.4 +.. data:: RLIMIT_SBSIZE + + The maximum size (in bytes) of socket buffer usage for this user. + This limits the amount of network memory, and hence the amount of mbufs, + that this user may hold at any time. + + Availability: FreeBSD 9 or later. + + .. versionadded:: 3.4 + +.. data:: RLIMIT_SWAP + + The maximum size (in bytes) of the swap space that may be reserved or + used by all of this user id's processes. + This limit is enforced only if bit 1 of the vm.overcommit sysctl is set. + Please see :manpage:`tuning(7)` for a complete description of this sysctl. + + Availability: FreeBSD 9 or later. + + .. versionadded:: 3.4 + +.. data:: RLIMIT_NPTS + + The maximum number of pseudo-terminals created by this user id. + + Availability: FreeBSD 9 or later. + + .. versionadded:: 3.4 Resource Usage -------------- diff --git a/Doc/library/runpy.rst b/Doc/library/runpy.rst index 6919bc0c37b7..7293f159e09a 100644 --- a/Doc/library/runpy.rst +++ b/Doc/library/runpy.rst @@ -28,6 +28,9 @@ The :mod:`runpy` module provides two functions: .. function:: run_module(mod_name, init_globals=None, run_name=None, alter_sys=False) + .. index:: + module: __main__ + Execute the code of the specified module and return the resulting module globals dictionary. The module's code is first located using the standard import mechanism (refer to :pep:`302` for details) and then executed in a @@ -44,28 +47,22 @@ The :mod:`runpy` module provides two functions: below are defined in the supplied dictionary, those definitions are overridden by :func:`run_module`. - The special global variables ``__name__``, ``__file__``, ``__cached__``, - ``__loader__`` - and ``__package__`` are set in the globals dictionary before the module - code is executed (Note that this is a minimal set of variables - other - variables may be set implicitly as an interpreter implementation detail). + The special global variables ``__name__``, ``__spec__``, ``__file__``, + ``__cached__``, ``__loader__`` and ``__package__`` are set in the globals + dictionary before the module code is executed (Note that this is a + minimal set of variables - other variables may be set implicitly as an + interpreter implementation detail). ``__name__`` is set to *run_name* if this optional argument is not :const:`None`, to ``mod_name + '.__main__'`` if the named module is a package and to the *mod_name* argument otherwise. - ``__file__`` is set to the name provided by the module loader. If the - loader does not make filename information available, this variable is set - to :const:`None`. - - ``__cached__`` will be set to ``None``. + ``__spec__`` will be set appropriately for the *actually* imported + module (that is, ``__spec__.name`` will always be *mod_name* or + ``mod_name + '.__main__``, never *run_name*). - ``__loader__`` is set to the :pep:`302` module loader used to retrieve the - code for the module (This loader may be a wrapper around the standard - import mechanism). - - ``__package__`` is set to *mod_name* if the named module is a package and - to ``mod_name.rpartition('.')[0]`` otherwise. + ``__file__``, ``__cached__``, ``__loader__`` and ``__package__`` are + :ref:`set as normal <import-mod-attrs>` based on the module spec. If the argument *alter_sys* is supplied and evaluates to :const:`True`, then ``sys.argv[0]`` is updated with the value of ``__file__`` and @@ -78,16 +75,27 @@ The :mod:`runpy` module provides two functions: arguments. It is recommended that the :mod:`sys` module be left alone when invoking this function from threaded code. + .. seealso:: + The :option:`-m` option offering equivalent functionality from the + command line. .. versionchanged:: 3.1 Added ability to execute packages by looking for a ``__main__`` submodule. .. versionchanged:: 3.2 - Added ``__cached__`` global variable (see :PEP:`3147`). + Added ``__cached__`` global variable (see :pep:`3147`). + .. versionchanged:: 3.4 + Updated to take advantage of the module spec feature added by + :pep:`451`. This allows ``__cached__`` to be set correctly for modules + run this way, as well as ensuring the real module name is always + accessible as ``__spec__.name``. .. function:: run_path(file_path, init_globals=None, run_name=None) + .. index:: + module: __main__ + Execute the code at the named filesystem location and return the resulting module globals dictionary. As with a script name supplied to the CPython command line, the supplied path may refer to a Python source file, a @@ -108,23 +116,25 @@ The :mod:`runpy` module provides two functions: below are defined in the supplied dictionary, those definitions are overridden by :func:`run_path`. - The special global variables ``__name__``, ``__file__``, ``__loader__`` - and ``__package__`` are set in the globals dictionary before the module - code is executed (Note that this is a minimal set of variables - other - variables may be set implicitly as an interpreter implementation detail). + The special global variables ``__name__``, ``__spec__``, ``__file__``, + ``__cached__``, ``__loader__`` and ``__package__`` are set in the globals + dictionary before the module code is executed (Note that this is a + minimal set of variables - other variables may be set implicitly as an + interpreter implementation detail). ``__name__`` is set to *run_name* if this optional argument is not :const:`None` and to ``'<run_path>'`` otherwise. - ``__file__`` is set to the name provided by the module loader. If the - loader does not make filename information available, this variable is set - to :const:`None`. For a simple script, this will be set to ``file_path``. + If the supplied path directly references a script file (whether as source + or as precompiled byte code), then ``__file__`` will be set to the + supplied path, and ``__spec__``, ``__cached__``, ``__loader__`` and + ``__package__`` will all be set to :const:`None`. - ``__loader__`` is set to the :pep:`302` module loader used to retrieve the - code for the module (This loader may be a wrapper around the standard - import mechanism). For a simple script, this will be set to :const:`None`. - - ``__package__`` is set to ``__name__.rpartition('.')[0]``. + If the supplied path is a reference to a valid sys.path entry, then + ``__spec__`` will be set appropriately for the imported ``__main__`` + module (that is, ``__spec__.name`` will always be ``__main__``). + ``__file__``, ``__cached__``, ``__loader__`` and ``__package__`` will be + :ref:`set as normal <import-mod-attrs>` based on the module spec. A number of alterations are also made to the :mod:`sys` module. Firstly, ``sys.path`` may be altered as described above. ``sys.argv[0]`` is updated @@ -139,16 +149,29 @@ The :mod:`runpy` module provides two functions: limitations still apply, use of this function in threaded code should be either serialised with the import lock or delegated to a separate process. + .. seealso:: + :ref:`using-on-interface-options` for equivalent functionality on the + command line (``python path/to/script``). + .. versionadded:: 3.2 + .. versionchanged:: 3.4 + Updated to take advantage of the module spec feature added by + :pep:`451`. This allows ``__cached__`` to be set correctly in the + case where ``__main__`` is imported from a valid sys.path entry rather + than being executed directly. + .. seealso:: - :pep:`338` - Executing modules as scripts + :pep:`338` -- Executing modules as scripts PEP written and implemented by Nick Coghlan. - :pep:`366` - Main module explicit relative imports + :pep:`366` -- Main module explicit relative imports PEP written and implemented by Nick Coghlan. + :pep:`451` -- A ModuleSpec Type for the Import System + PEP written and implemented by Eric Snow + :ref:`using-on-general` - CPython command line details The :func:`importlib.import_module` function diff --git a/Doc/library/select.rst b/Doc/library/select.rst index 524e411f2cc3..a62dc844e4f3 100644 --- a/Doc/library/select.rst +++ b/Doc/library/select.rst @@ -58,9 +58,14 @@ The module defines the following: which can be used as Edge or Level Triggered interface for I/O events. *sizehint* is deprecated and completely ignored. *flags* can be set to :const:`EPOLL_CLOEXEC`, which causes the epoll descriptor to be closed - automatically when :func:`os.execve` is called. See section - :ref:`epoll-objects` below for the methods supported by epolling objects. - They also support the :keyword:`with` statement. + automatically when :func:`os.execve` is called. + + See the :ref:`epoll-objects` section below for the methods supported by + epolling objects. + + ``epoll`` objects support the context management protocol: when used in a + :keyword:`with` statement, the new file descriptor is automatically closed + at the end of the block. The new file descriptor is :ref:`non-inheritable <fd_inheritance>`. @@ -140,6 +145,13 @@ The module defines the following: library, and does not handle file descriptors that don't originate from WinSock. + .. versionchanged:: 3.5 + The function is now retried with a recomputed timeout when interrupted by + a signal, except if the signal handler raises an exception (see + :pep:`475` for the rationale), instead of raising + :exc:`InterruptedError`. + + .. attribute:: PIPE_BUF The minimum number of bytes which can be written without blocking to a pipe @@ -155,10 +167,7 @@ The module defines the following: .. _devpoll-objects: ``/dev/poll`` Polling Objects ----------------------------------------------- - - http://developers.sun.com/solaris/articles/using_devpoll.html - http://developers.sun.com/solaris/articles/polling_efficient.html +----------------------------- Solaris and derivatives have ``/dev/poll``. While :c:func:`select` is O(highest file descriptor) and :c:func:`poll` is O(number of file @@ -205,7 +214,7 @@ object. .. warning:: Registering a file descriptor that's already registered is not an - error, but the result is undefined. The appropiate action is to + error, but the result is undefined. The appropriate action is to unregister or modify it first. This is an important difference compared with :c:func:`poll`. @@ -240,6 +249,12 @@ object. returning. If *timeout* is omitted, -1, or :const:`None`, the call will block until there is an event for this poll object. + .. versionchanged:: 3.5 + The function is now retried with a recomputed timeout when interrupted by + a signal, except if the signal handler raises an exception (see + :pep:`475` for the rationale), instead of raising + :exc:`InterruptedError`. + .. _epoll-objects: @@ -308,7 +323,7 @@ Edge and Level Trigger Polling (epoll) Objects .. method:: epoll.modify(fd, eventmask) - Modify a register file descriptor. + Modify a registered file descriptor. .. method:: epoll.unregister(fd) @@ -320,6 +335,12 @@ Edge and Level Trigger Polling (epoll) Objects Wait for events. timeout in seconds (float) + .. versionchanged:: 3.5 + The function is now retried with a recomputed timeout when interrupted by + a signal, except if the signal handler raises an exception (see + :pep:`475` for the rationale), instead of raising + :exc:`InterruptedError`. + .. _poll-objects: @@ -372,7 +393,7 @@ linearly scanned again. :c:func:`select` is O(highest file descriptor), while Modifies an already registered fd. This has the same effect as ``register(fd, eventmask)``. Attempting to modify a file descriptor - that was never registered causes an :exc:`IOError` exception with errno + that was never registered causes an :exc:`OSError` exception with errno :const:`ENOENT` to be raised. @@ -399,6 +420,12 @@ linearly scanned again. :c:func:`select` is O(highest file descriptor), while returning. If *timeout* is omitted, negative, or :const:`None`, the call will block until there is an event for this poll object. + .. versionchanged:: 3.5 + The function is now retried with a recomputed timeout when interrupted by + a signal, except if the signal handler raises an exception (see + :pep:`475` for the rationale), instead of raising + :exc:`InterruptedError`. + .. _kqueue-objects: @@ -433,6 +460,12 @@ Kqueue Objects - max_events must be 0 or a positive integer - timeout in seconds (floats possible) + .. versionchanged:: 3.5 + The function is now retried with a recomputed timeout when interrupted by + a signal, except if the signal handler raises an exception (see + :pep:`475` for the rationale), instead of raising + :exc:`InterruptedError`. + .. _kevent-objects: diff --git a/Doc/library/selectors.rst b/Doc/library/selectors.rst index b0b002f0e182..56cfc6bdb769 100644 --- a/Doc/library/selectors.rst +++ b/Doc/library/selectors.rst @@ -45,12 +45,13 @@ Classes hierarchy:: +-- SelectSelector +-- PollSelector +-- EpollSelector + +-- DevpollSelector +-- KqueueSelector In the following, *events* is a bitwise mask indicating which I/O events should -be waited for on a given file object. It can be a combination of the constants -below: +be waited for on a given file object. It can be a combination of the modules +constants below: +-----------------------+-----------------------------------------------+ | Constant | Meaning | @@ -102,7 +103,8 @@ below: Register a file object for selection, monitoring it for I/O events. - *fileobj* is the file object to monitor. + *fileobj* is the file object to monitor. It may either be an integer + file descriptor or an object with a ``fileno()`` method. *events* is a bitwise mask of events to monitor. *data* is an opaque object. @@ -118,7 +120,9 @@ below: *fileobj* must be a file object previously registered. This returns the associated :class:`SelectorKey` instance, or raises a - :exc:`KeyError` if the file object is not registered. + :exc:`KeyError` if *fileobj* is not registered. It will raise + :exc:`ValueError` if *fileobj* is invalid (e.g. it has no ``fileno()`` + method or its ``fileno()`` method has an invalid return value). .. method:: modify(fileobj, events, data=None) @@ -155,6 +159,12 @@ below: timeout has elapsed if the current process receives a signal: in this case, an empty list will be returned. + .. versionchanged:: 3.5 + The selector is now retried with a recomputed timeout when interrupted + by a signal if the signal handler did not raise an exception (see + :pep:`475` for the rationale), instead of returning an empty list + of events before the timeout. + .. method:: close() Close the selector. @@ -204,6 +214,16 @@ below: This returns the file descriptor used by the underlying :func:`select.epoll` object. +.. class:: DevpollSelector() + + :func:`select.devpoll`-based selector. + + .. method:: fileno() + + This returns the file descriptor used by the underlying + :func:`select.devpoll` object. + + .. versionadded:: 3.5 .. class:: KqueueSelector() diff --git a/Doc/library/shelve.rst b/Doc/library/shelve.rst index 4ba9ddc47705..22e202dace1a 100644 --- a/Doc/library/shelve.rst +++ b/Doc/library/shelve.rst @@ -121,7 +121,8 @@ Restrictions The *keyencoding* parameter is the encoding used to encode keys before they are used with the underlying dict. - :class:`Shelf` objects can also be used as context managers. + A :class:`Shelf` object can also be used as a context manager, in which + case it will be automatically closed when the :keyword:`with` block ends. .. versionchanged:: 3.2 Added the *keyencoding* parameter; previously, keys were always encoded in diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index e4f348cd82ce..bf221bfcb921 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -191,7 +191,8 @@ Directory and files operations match one of the glob-style *patterns* provided. See the example below. -.. function:: copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False) +.. function:: copytree(src, dst, symlinks=False, ignore=None, \ + copy_function=copy2, ignore_dangling_symlinks=False) Recursively copy an entire directory tree rooted at *src*, returning the destination directory. The destination @@ -282,28 +283,36 @@ Directory and files operations .. versionadded:: 3.3 -.. function:: move(src, dst) +.. function:: move(src, dst, copy_function=copy2) Recursively move a file or directory (*src*) to another location (*dst*) and return the destination. - If the destination is a directory or a symlink to a directory, then *src* is - moved inside that directory. - - The destination directory must not already exist. If the destination already - exists but is not a directory, it may be overwritten depending on - :func:`os.rename` semantics. + If the destination is an existing directory, then *src* is moved inside that + directory. If the destination already exists but is not a directory, it may + be overwritten depending on :func:`os.rename` semantics. If the destination is on the current filesystem, then :func:`os.rename` is - used. Otherwise, *src* is copied (using :func:`shutil.copy2`) to *dst* and - then removed. In case of symlinks, a new symlink pointing to the target of - *src* will be created in or as *dst* and *src* will be removed. + used. Otherwise, *src* is copied to *dst* using *copy_function* and then + removed. In case of symlinks, a new symlink pointing to the target of *src* + will be created in or as *dst* and *src* will be removed. + + If *copy_function* is given, it must be a callable that takes two arguments + *src* and *dst*, and will be used to copy *src* to *dest* if + :func:`os.rename` cannot be used. If the source is a directory, + :func:`copytree` is called, passing it the :func:`copy_function`. The + default *copy_function* is :func:`copy2`. Using :func:`copy` as the + *copy_function* allows the move to succeed when it is not possible to also + copy the metadata, at the expense of not copying any of the metadata. .. versionchanged:: 3.3 Added explicit symlink handling for foreign filesystems, thus adapting it to the behavior of GNU's :program:`mv`. Now returns *dst*. + .. versionchanged:: 3.5 + Added the *copy_function* keyword argument. + .. function:: disk_usage(path) Return disk usage statistics about the given path as a :term:`named tuple` @@ -341,7 +350,7 @@ Directory and files operations On Windows, the current directory is always prepended to the *path* whether or not you use the default or provide your own, which is the behavior the - command shell uses when finding executables. Additionaly, when finding the + command shell uses when finding executables. Additionally, when finding the *cmd* in the *path*, the ``PATHEXT`` environment variable is checked. For example, if you call ``shutil.which("python")``, :func:`which` will search ``PATHEXT`` to know that it should look for ``python.exe`` within the *path* @@ -421,6 +430,26 @@ Another example that uses the *ignore* argument to add a logging call:: copytree(source, destination, ignore=_logpath) +.. _shutil-rmtree-example: + +rmtree example +~~~~~~~~~~~~~~ + +This example shows how to remove a directory tree on Windows where some +of the files have their read-only bit set. It uses the onerror callback +to clear the readonly bit and reattempt the remove. Any subsequent failure +will propagate. :: + + import os, stat + import shutil + + def remove_readonly(func, path, _): + "Clear the readonly bit and reattempt the removal" + os.chmod(path, stat.S_IWRITE) + func(path) + + shutil.rmtree(directory, onerror=remove_readonly) + .. _archiving-operations: Archiving operations @@ -437,7 +466,8 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. *base_name* is the name of the file to create, including the path, minus any format-specific extension. *format* is the archive format: one of - "zip", "tar", "bztar" (if the :mod:`bz2` module is available) or "gztar". + "zip", "tar", "bztar" (if the :mod:`bz2` module is available), "xztar" + (if the :mod:`lzma` module is available) or "gztar". *root_dir* is a directory that will be the root directory of the archive; for example, we typically chdir into *root_dir* before creating the @@ -449,22 +479,31 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. *root_dir* and *base_dir* both default to the current directory. + If *dry_run* is true, no archive is created, but the operations that would be + executed are logged to *logger*. + *owner* and *group* are used when creating a tar archive. By default, uses the current owner and group. *logger* must be an object compatible with :pep:`282`, usually an instance of :class:`logging.Logger`. + The *verbose* argument is unused and deprecated. + + .. versionchanged:: 3.5 + Added support for the *xztar* format. + .. function:: get_archive_formats() Return a list of supported formats for archiving. - Each element of the returned sequence is a tuple ``(name, description)`` + Each element of the returned sequence is a tuple ``(name, description)``. By default :mod:`shutil` provides these formats: - *gztar*: gzip'ed tar-file - *bztar*: bzip2'ed tar-file (if the :mod:`bz2` module is available.) + - *xztar*: xz'ed tar-file (if the :mod:`lzma` module is available.) - *tar*: uncompressed tar file - *zip*: ZIP file @@ -474,14 +513,19 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. .. function:: register_archive_format(name, function, [extra_args, [description]]) - Register an archiver for the format *name*. *function* is a callable that - will be used to invoke the archiver. + Register an archiver for the format *name*. + + *function* is the callable that will be used to unpack archives. The callable + will receive the *base_name* of the file to create, followed by the + *base_dir* (which defaults to :data:`os.curdir`) to start archiving from. + Further arguments are passed as keyword arguments: *owner*, *group*, + *dry_run* and *logger* (as passed in :func:`make_archive`). If given, *extra_args* is a sequence of ``(name, value)`` pairs that will be used as extra keywords arguments when the archiver callable is used. *description* is used by :func:`get_archive_formats` which returns the - list of archivers. Defaults to an empty list. + list of archivers. Defaults to an empty string. .. function:: unregister_archive_format(name) @@ -535,6 +579,7 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. - *gztar*: gzip'ed tar-file - *bztar*: bzip2'ed tar-file (if the :mod:`bz2` module is available.) + - *xztar*: xz'ed tar-file (if the :mod:`lzma` module is available.) - *tar*: uncompressed tar file - *zip*: ZIP file diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index 84e283683d07..8f814df8bcf8 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -65,6 +65,16 @@ Besides, only the main thread is allowed to set a new signal handler. Module contents --------------- +.. versionchanged:: 3.5 + signal (SIG*), handler (:const:`SIG_DFL`, :const:`SIG_IGN`) and sigmask + (:const:`SIG_BLOCK`, :const:`SIG_UNBLOCK`, :const:`SIG_SETMASK`) + related constants listed below were turned into + :class:`enums <enum.IntEnum>`. + :func:`getsignal`, :func:`pthread_sigmask`, :func:`sigpending` and + :func:`sigwait` functions return human-readable + :class:`enums <enum.IntEnum>`. + + The variables defined in the :mod:`signal` module are: @@ -95,7 +105,7 @@ The variables defined in the :mod:`signal` module are: .. data:: CTRL_C_EVENT - The signal corresponding to the CTRL+C keystroke event. This signal can + The signal corresponding to the :kbd:`Ctrl+C` keystroke event. This signal can only be used with :func:`os.kill`. Availability: Windows. @@ -105,7 +115,7 @@ The variables defined in the :mod:`signal` module are: .. data:: CTRL_BREAK_EVENT - The signal corresponding to the CTRL+BREAK keystroke event. This signal can + The signal corresponding to the :kbd:`Ctrl+Break` keystroke event. This signal can only be used with :func:`os.kill`. Availability: Windows. @@ -209,21 +219,21 @@ The :mod:`signal` module defines the following functions: :func:`sigpending`. -.. function:: pthread_kill(thread_id, signum) +.. function:: pthread_kill(thread_id, signalnum) - Send the signal *signum* to the thread *thread_id*, another thread in the + Send the signal *signalnum* to the thread *thread_id*, another thread in the same process as the caller. The target thread can be executing any code (Python or not). However, if the target thread is executing the Python interpreter, the Python signal handlers will be :ref:`executed by the main - thread <signals-and-threads>`. Therefore, the only point of sending a signal to a particular - Python thread would be to force a running system call to fail with - :exc:`InterruptedError`. + thread <signals-and-threads>`. Therefore, the only point of sending a + signal to a particular Python thread would be to force a running system call + to fail with :exc:`InterruptedError`. Use :func:`threading.get_ident()` or the :attr:`~threading.Thread.ident` attribute of :class:`threading.Thread` objects to get a suitable value for *thread_id*. - If *signum* is 0, then no signal is sent, but error checking is still + If *signalnum* is 0, then no signal is sent, but error checking is still performed; this can be used to check if the target thread is still running. Availability: Unix (see the man page :manpage:`pthread_kill(3)` for further @@ -308,6 +318,9 @@ The :mod:`signal` module defines the following functions: attempting to call it from other threads will cause a :exc:`ValueError` exception to be raised. + .. versionchanged:: 3.5 + On Windows, the function now also supports socket handles. + .. function:: siginterrupt(signalnum, flag) @@ -395,6 +408,11 @@ The :mod:`signal` module defines the following functions: .. versionadded:: 3.3 + .. versionchanged:: 3.5 + The function is now retried if interrupted by a signal not in *sigset* + and the signal handler does not raise an exception (see :pep:`475` for + the rationale). + .. function:: sigtimedwait(sigset, timeout) @@ -409,6 +427,11 @@ The :mod:`signal` module defines the following functions: .. versionadded:: 3.3 + .. versionchanged:: 3.5 + The function is now retried with the recomputed *timeout* if interrupted + by a signal not in *sigset* and the signal handler does not raise an + exception (see :pep:`475` for the rationale). + .. _signal-example: diff --git a/Doc/library/site.rst b/Doc/library/site.rst index d93e938b5c90..43daf790b77c 100644 --- a/Doc/library/site.rst +++ b/Doc/library/site.rst @@ -26,24 +26,23 @@ additions, call the :func:`site.main` function. :option:`-S`. .. index:: - pair: site-python; directory pair: site-packages; directory It starts by constructing up to four directories from a head and a tail part. For the head part, it uses ``sys.prefix`` and ``sys.exec_prefix``; empty heads are skipped. For the tail part, it uses the empty string and then :file:`lib/site-packages` (on Windows) or -:file:`lib/python{X.Y}/site-packages` and then :file:`lib/site-python` (on -Unix and Macintosh). For each of the distinct head-tail combinations, it sees -if it refers to an existing directory, and if so, adds it to ``sys.path`` and -also inspects the newly added path for configuration files. +:file:`lib/python{X.Y}/site-packages` (on Unix and Macintosh). For each +of the distinct head-tail combinations, it sees if it refers to an existing +directory, and if so, adds it to ``sys.path`` and also inspects the newly +added path for configuration files. -.. deprecated:: 3.4 - Support for the "site-python" directory will be removed in 3.5. +.. versionchanged:: 3.5 + Support for the "site-python" directory has been removed. If a file named "pyvenv.cfg" exists one directory above sys.executable, sys.prefix and sys.exec_prefix are set to that directory and -it is also checked for site-packages and site-python (sys.base_prefix and +it is also checked for site-packages (sys.base_prefix and sys.base_exec_prefix will always be the "real" prefixes of the Python installation). If "pyvenv.cfg" (a bootstrap configuration file) contains the key "include-system-site-packages" set to anything other than "false" @@ -99,7 +98,11 @@ After these path manipulations, an attempt is made to import a module named :mod:`sitecustomize`, which can perform arbitrary site-specific customizations. It is typically created by a system administrator in the site-packages directory. If this import fails with an :exc:`ImportError` exception, it is -silently ignored. +silently ignored. If Python is started without output streams available, as +with :file:`pythonw.exe` on Windows (which is used by default to start IDLE), +attempted output from :mod:`sitecustomize` is ignored. Any exception other +than :exc:`ImportError` causes a silent and perhaps mysterious failure of the +process. .. index:: module: usercustomize @@ -123,9 +126,13 @@ On systems that support :mod:`readline`, this module will also import and configure the :mod:`rlcompleter` module, if Python is started in :ref:`interactive mode <tut-interactive>` and without the :option:`-S` option. The default behavior is enable tab-completion and to use -:file:`~/.python_history` as the history save file. To disable it, override -the :data:`sys.__interactivehook__` attribute in your :mod:`sitecustomize` -or :mod:`usercustomize` module or your :envvar:`PYTHONSTARTUP` file. +:file:`~/.python_history` as the history save file. To disable it, delete (or +override) the :data:`sys.__interactivehook__` attribute in your +:mod:`sitecustomize` or :mod:`usercustomize` module or your +:envvar:`PYTHONSTARTUP` file. + +.. versionchanged:: 3.4 + Activation of rlcompleter and history was made automatic. Module contents @@ -176,7 +183,7 @@ Module contents unless the Python interpreter was started with the :option:`-S` flag. .. versionchanged:: 3.3 - This function used to be called unconditionnally. + This function used to be called unconditionally. .. function:: addsitedir(sitedir, known_paths=None) @@ -187,8 +194,7 @@ Module contents .. function:: getsitepackages() - Return a list containing all global site-packages directories (and possibly - site-python). + Return a list containing all global site-packages directories. .. versionadded:: 3.2 diff --git a/Doc/library/smtpd.rst b/Doc/library/smtpd.rst index 3ebed0626094..977f9a874879 100644 --- a/Doc/library/smtpd.rst +++ b/Doc/library/smtpd.rst @@ -20,7 +20,8 @@ specific mail-sending strategies. Additionally the SMTPChannel may be extended to implement very specific interaction behaviour with SMTP clients. -The code supports :RFC:`5321`, plus the :rfc:`1870` SIZE extension. +The code supports :RFC:`5321`, plus the :rfc:`1870` SIZE and :rfc:`6531` +SMTPUTF8 extensions. SMTPServer Objects @@ -28,7 +29,7 @@ SMTPServer Objects .. class:: SMTPServer(localaddr, remoteaddr, data_size_limit=33554432,\ - map=None) + map=None, enable_SMTPUTF8=False, decode_data=True) Create a new :class:`SMTPServer` object, which binds to local address *localaddr*. It will treat *remoteaddr* as an upstream SMTP relayer. It @@ -39,25 +40,77 @@ SMTPServer Objects accepted in a ``DATA`` command. A value of ``None`` or ``0`` means no limit. - A dictionary can be specified in *map* to avoid using a global socket map. - - .. method:: process_message(peer, mailfrom, rcpttos, data) - - Raise :exc:`NotImplementedError` exception. Override this in subclasses to + *map* is the socket map to use for connections (an initially empty + dictionary is a suitable value). If not specified the :mod:`asyncore` + global socket map is used. + + *enable_SMTPUTF8* determins whether the ``SMTPUTF8`` extension (as defined + in :RFC:`6531`) should be enabled. The default is ``False``. If set to + ``True``, *decode_data* must be ``False`` (otherwise an error is raised). + When ``True``, ``SMTPUTF8`` is accepted as a parameter to the ``MAIL`` + command and when present is passed to :meth:`process_message` in the + ``kwargs['mail_options']`` list. + + *decode_data* specifies whether the data portion of the SMTP transaction + should be decoded using UTF-8. The default is ``True`` for backward + compatibility reasons, but will change to ``False`` in Python 3.6; specify + the keyword value explicitly to avoid the :exc:`DeprecationWarning`. When + *decode_data* is set to ``False`` the server advertises the ``8BITMIME`` + extension (:rfc:`6152`), accepts the ``BODY=8BITMIME`` parameter to + the ``MAIL`` command, and when present passes it to :meth:`process_message` + in the ``kwargs['mail_options']`` list. + + .. method:: process_message(peer, mailfrom, rcpttos, data, **kwargs) + + Raise a :exc:`NotImplementedError` exception. Override this in subclasses to do something useful with this message. Whatever was passed in the constructor as *remoteaddr* will be available as the :attr:`_remoteaddr` attribute. *peer* is the remote host's address, *mailfrom* is the envelope originator, *rcpttos* are the envelope recipients and *data* is a string - containing the contents of the e-mail (which should be in :rfc:`2822` + containing the contents of the e-mail (which should be in :rfc:`5321` format). + If the *decode_data* constructor keyword is set to ``True``, the *data* + argument will be a unicode string. If it is set to ``False``, it + will be a bytes object. + + *kwargs* is a dictionary containing additional information. It is empty + unless at least one of ``decode_data=False`` or ``enable_SMTPUTF8=True`` + was given as an init parameter, in which case it contains the following + keys: + + *mail_options*: + a list of all received parameters to the ``MAIL`` + command (the elements are uppercase strings; example: + ``['BODY=8BITMIME', 'SMTPUTF8']``). + + *rcpt_options*: + same as *mail_options* but for the ``RCPT`` command. + Currently no ``RCPT TO`` options are supported, so for now + this will always be an empty list. + + Implementations of ``process_message`` should use the ``**kwargs`` + signature to accept arbitrary keyword arguments, since future feature + enhancements may add keys to the kwargs dictionary. + + Return ``None`` to request a normal ``250 Ok`` response; otherwise + return the desired response string in :RFC:`5321` format. + .. attribute:: channel_class Override this in subclasses to use a custom :class:`SMTPChannel` for managing SMTP clients. - .. versionchanged:: 3.4 - The *map* argument was added. + .. versionadded:: 3.4 + The *map* constructor argument. + + .. versionchanged:: 3.5 + *localaddr* and *remoteaddr* may now contain IPv6 addresses. + + .. versionadded:: 3.5 + the *decode_data* and *enable_SMTPUTF8* constructor arguments, and the + *kwargs* argument to :meth:`process_message` when one or more of these is + specified. DebuggingServer Objects @@ -97,7 +150,7 @@ SMTPChannel Objects ------------------- .. class:: SMTPChannel(server, conn, addr, data_size_limit=33554432,\ - map=None)) + map=None, enable_SMTPUTF8=False, decode_data=True) Create a new :class:`SMTPChannel` object which manages the communication between the server and a single SMTP client. @@ -108,11 +161,24 @@ SMTPChannel Objects accepted in a ``DATA`` command. A value of ``None`` or ``0`` means no limit. + *enable_SMTPUTF8* determins whether the ``SMTPUTF8`` extension (as defined + in :RFC:`6531`) should be enabled. The default is ``False``. A + :exc:`ValueError` is raised if both *enable_SMTPUTF8* and *decode_data* are + set to ``True`` at the same time. + A dictionary can be specified in *map* to avoid using a global socket map. + *decode_data* specifies whether the data portion of the SMTP transaction + should be decoded using UTF-8. The default is ``True`` for backward + compatibility reasons, but will change to ``False`` in Python 3.6. Specify + the keyword value explicitly to avoid the :exc:`DeprecationWarning`. + To use a custom SMTPChannel implementation you need to override the :attr:`SMTPServer.channel_class` of your :class:`SMTPServer`. + .. versionchanged:: 3.5 + the *decode_data* and *enable_SMTPUTF8* arguments were added. + The :class:`SMTPChannel` has the following instance variables: .. attribute:: smtp_server diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst index a7d15384d09c..a71ee585a379 100644 --- a/Doc/library/smtplib.rst +++ b/Doc/library/smtplib.rst @@ -32,7 +32,8 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions). than a success code, an :exc:`SMTPConnectError` is raised. The optional *timeout* parameter specifies a timeout in seconds for blocking operations like the connection attempt (if not specified, the global default timeout - setting will be used). The optional source_address parameter allows to bind + setting will be used). If the timeout expires, :exc:`socket.timeout` is + raised. The optional source_address parameter allows to bind to some specific source address in a machine with multiple network interfaces, and/or to some specific source TCP port. It takes a 2-tuple (host, port), for the socket to bind to as its source address before @@ -60,6 +61,10 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions). .. versionchanged:: 3.3 source_address argument was added. + .. versionadded:: 3.5 + The SMTPUTF8 extension (:rfc:`6531`) is now supported. + + .. class:: SMTP_SSL(host='', port=0, local_hostname=None, keyfile=None, \ certfile=None [, timeout], context=None, \ source_address=None) @@ -69,20 +74,15 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions). required from the beginning of the connection and using :meth:`starttls` is not appropriate. If *host* is not specified, the local host is used. If *port* is zero, the standard SMTP-over-SSL port (465) is used. The optional - arguments *local_hostname* and *source_address* have the same meaning as - they do in the :class:`SMTP` class. *keyfile* and *certfile* are also - optional, and can contain a PEM formatted private key and certificate chain - file for the SSL connection. *context* also optional, can contain a - SSLContext, and is an alternative to keyfile and certfile; If it is - specified both keyfile and certfile must be None. The optional *timeout* - parameter specifies a timeout in seconds for blocking operations like the - connection attempt (if not specified, the global default timeout setting - will be used). The optional source_address parameter allows to bind to some - specific source address in a machine with multiple network interfaces, - and/or to some specific source tcp port. It takes a 2-tuple (host, port), - for the socket to bind to as its source address before connecting. If - omitted (or if host or port are ``''`` and/or 0 respectively) the OS default - behavior will be used. + arguments *local_hostname*, *timeout* and *source_address* have the same + meaning as they do in the :class:`SMTP` class. *context*, also optional, + can contain a :class:`~ssl.SSLContext` and allows to configure various + aspects of the secure connection. Please read :ref:`ssl-security` for + best practices. + + *keyfile* and *certfile* are a legacy alternative to *context*, and can + point to a PEM formatted private key and certificate chain file for the + SSL connection. .. versionchanged:: 3.3 *context* was added. @@ -90,6 +90,10 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions). .. versionchanged:: 3.3 source_address argument was added. + .. versionchanged:: 3.4 + The class now supports hostname check with + :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see + :data:`ssl.HAS_SNI`). .. class:: LMTP(host='', port=LMTP_PORT, local_hostname=None, source_address=None) @@ -113,6 +117,9 @@ A nice selection of exceptions is defined as well: Subclass of :exc:`OSError` that is the base exception class for all the other exceptions provided by this module. + .. versionchanged:: 3.4 + SMTPException became subclass of :exc:`OSError` + .. exception:: SMTPServerDisconnected @@ -158,6 +165,13 @@ A nice selection of exceptions is defined as well: The server refused our ``HELO`` message. +.. exception:: SMTPNotSupportedError + + The command or option attempted is not supported by the server. + + .. versionadded:: 3.5 + + .. exception:: SMTPAuthenticationError SMTP authentication went wrong. Most probably the server didn't accept the @@ -186,8 +200,12 @@ An :class:`SMTP` instance has the following methods: .. method:: SMTP.set_debuglevel(level) - Set the debug output level. A true value for *level* results in debug messages - for connection and for all messages sent to and received from the server. + Set the debug output level. A value of 1 or ``True`` for *level* results in + debug messages for connection and for all messages sent to and received from + the server. A value of 2 for *level* results in these messages being + timestamped. + + .. versionchanged:: 3.5 Added debuglevel 2. .. method:: SMTP.docmd(cmd, args='') @@ -237,8 +255,7 @@ An :class:`SMTP` instance has the following methods: the server is stored as the :attr:`ehlo_resp` attribute, :attr:`does_esmtp` is set to true or false depending on whether the server supports ESMTP, and :attr:`esmtp_features` will be a dictionary containing the names of the - SMTP service extensions this server supports, and their - parameters (if any). + SMTP service extensions this server supports, and their parameters (if any). Unless you wish to use :meth:`has_extn` before sending mail, it should not be necessary to call this method explicitly. It will be implicitly called by @@ -271,7 +288,7 @@ An :class:`SMTP` instance has the following methods: Many sites disable SMTP ``VRFY`` in order to foil spammers. -.. method:: SMTP.login(user, password) +.. method:: SMTP.login(user, password, *, initial_response_ok=True) Log in on an SMTP server that requires authentication. The arguments are the username and the password to authenticate with. If there has been no previous @@ -285,9 +302,68 @@ An :class:`SMTP` instance has the following methods: :exc:`SMTPAuthenticationError` The server didn't accept the username/password combination. + :exc:`SMTPNotSupportedError` + The ``AUTH`` command is not supported by the server. + :exc:`SMTPException` No suitable authentication method was found. + Each of the authentication methods supported by :mod:`smtplib` are tried in + turn if they are advertised as supported by the server. See :meth:`auth` + for a list of supported authentication methods. *initial_response_ok* is + passed through to :meth:`auth`. + + Optional keyword argument *initial_response_ok* specifies whether, for + authentication methods that support it, an "initial response" as specified + in :rfc:`4954` can be sent along with the ``AUTH`` command, rather than + requiring a challenge/response. + + .. versionchanged:: 3.5 + :exc:`SMTPNotSupportedError` may be raised, and the + *initial_response_ok* parameter was added. + + +.. method:: SMTP.auth(mechanism, authobject, *, initial_response_ok=True) + + Issue an ``SMTP`` ``AUTH`` command for the specified authentication + *mechanism*, and handle the challenge response via *authobject*. + + *mechanism* specifies which authentication mechanism is to + be used as argument to the ``AUTH`` command; the valid values are + those listed in the ``auth`` element of :attr:`esmtp_features`. + + *authobject* must be a callable object taking an optional single argument: + + data = authobject(challenge=None) + + If optional keyword argument *initial_response_ok* is true, + ``authobject()`` will be called first with no argument. It can return the + :rfc:`4954` "initial response" bytes which will be encoded and sent with + the ``AUTH`` command as below. If the ``authobject()`` does not support an + initial response (e.g. because it requires a challenge), it should return + None when called with ``challenge=None``. If *initial_response_ok* is + false, then ``authobject()`` will not be called first with None. + + If the initial response check returns None, or if *initial_response_ok* is + false, ``authobject()`` will be called to process the server's challenge + response; the *challenge* argument it is passed will be a ``bytes``. It + should return ``bytes`` *data* that will be base64 encoded and sent to the + server. + + The ``SMTP`` class provides ``authobjects`` for the ``CRAM-MD5``, ``PLAIN``, + and ``LOGIN`` mechanisms; they are named ``SMTP.auth_cram_md5``, + ``SMTP.auth_plain``, and ``SMTP.auth_login`` respectively. They all require + that the ``user`` and ``password`` properties of the ``SMTP`` instance are + set to appropriate values. + + User code does not normally need to call ``auth`` directly, but can instead + call the :meth:`login` method, which will try each of the above mechanisms + in turn, in the order listed. ``auth`` is exposed to facilitate the + implementation of authentication methods not (or not yet) supported + directly by :mod:`smtplib`. + + .. versionadded:: 3.5 + .. method:: SMTP.starttls(keyfile=None, certfile=None, context=None) @@ -307,7 +383,7 @@ An :class:`SMTP` instance has the following methods: :exc:`SMTPHeloError` The server didn't reply properly to the ``HELO`` greeting. - :exc:`SMTPException` + :exc:`SMTPNotSupportedError` The server does not support the STARTTLS extension. :exc:`RuntimeError` @@ -316,6 +392,16 @@ An :class:`SMTP` instance has the following methods: .. versionchanged:: 3.3 *context* was added. + .. versionchanged:: 3.4 + The method now supports hostname check with + :attr:`SSLContext.check_hostname` and *Server Name Indicator* (see + :data:`~ssl.HAS_SNI`). + + .. versionchanged:: 3.5 + The error raised for lack of STARTTLS support is now the + :exc:`SMTPNotSupportedError` subclass instead of the base + :exc:`SMTPException`. + .. method:: SMTP.sendmail(from_addr, to_addrs, msg, mail_options=[], rcpt_options=[]) @@ -352,6 +438,9 @@ An :class:`SMTP` instance has the following methods: recipient that was refused. Each entry contains a tuple of the SMTP error code and the accompanying error message sent by the server. + If ``SMTPUTF8`` is included in *mail_options*, and the server supports it, + *from_addr* and *to_addr* may contain non-ASCII characters. + This method may raise the following exceptions: :exc:`SMTPRecipientsRefused` @@ -370,12 +459,20 @@ An :class:`SMTP` instance has the following methods: The server replied with an unexpected error code (other than a refusal of a recipient). + :exc:`SMTPNotSupportedError` + ``SMTPUTF8`` was given in the *mail_options* but is not supported by the + server. + Unless otherwise noted, the connection will be open even after an exception is raised. .. versionchanged:: 3.2 *msg* may be a byte string. + .. versionchanged:: 3.5 + ``SMTPUTF8`` support added, and :exc:`SMTPNotSupportedError` may be + raised if ``SMTPUTF8`` is specified but the server does not support it. + .. method:: SMTP.send_message(msg, from_addr=None, to_addrs=None, \ mail_options=[], rcpt_options=[]) @@ -387,7 +484,7 @@ An :class:`SMTP` instance has the following methods: If *from_addr* is ``None`` or *to_addrs* is ``None``, ``send_message`` fills those arguments with addresses extracted from the headers of *msg* as - specified in :rfc:`2822`\: *from_addr* is set to the :mailheader:`Sender` + specified in :rfc:`5322`\: *from_addr* is set to the :mailheader:`Sender` field if it is present, and otherwise to the :mailheader:`From` field. *to_adresses* combines the values (if any) of the :mailheader:`To`, :mailheader:`Cc`, and :mailheader:`Bcc` fields from *msg*. If exactly one @@ -402,10 +499,18 @@ An :class:`SMTP` instance has the following methods: calls :meth:`sendmail` to transmit the resulting message. Regardless of the values of *from_addr* and *to_addrs*, ``send_message`` does not transmit any :mailheader:`Bcc` or :mailheader:`Resent-Bcc` headers that may appear - in *msg*. + in *msg*. If any of the addresses in *from_addr* and *to_addrs* contain + non-ASCII characters and the server does not advertise ``SMTPUTF8`` support, + an :exc:`SMTPNotSupported` error is raised. Otherwise the ``Message`` is + serialized with a clone of its :mod:`~email.policy` with the + :attr:`~email.policy.EmailPolicy.utf8` attribute set to ``True``, and + ``SMTPUTF8`` and ``BODY=8BITMIME`` are added to *mail_options*. .. versionadded:: 3.2 + .. versionadded:: 3.5 + Support for internationalized addresses (``SMTPUTF8``). + .. method:: SMTP.quit() diff --git a/Doc/library/sndhdr.rst b/Doc/library/sndhdr.rst index f36df6870347..f8b5d8b2460c 100644 --- a/Doc/library/sndhdr.rst +++ b/Doc/library/sndhdr.rst @@ -16,8 +16,9 @@ The :mod:`sndhdr` provides utility functions which attempt to determine the type of sound data which is in a file. When these functions are able to determine -what type of sound data is stored in a file, they return a tuple ``(type, -sampling_rate, channels, frames, bits_per_sample)``. The value for *type* +what type of sound data is stored in a file, they return a +:func:`~collections.namedtuple`, containing five attributes: (``filetype``, +``framerate``, ``nchannels``, ``nframes``, ``sampwidth``). The value for *type* indicates the data type and will be one of the strings ``'aifc'``, ``'aiff'``, ``'au'``, ``'hcom'``, ``'sndr'``, ``'sndt'``, ``'voc'``, ``'wav'``, ``'8svx'``, ``'sb'``, ``'ub'``, or ``'ul'``. The *sampling_rate* will be either the actual @@ -31,13 +32,19 @@ be the sample size in bits or ``'A'`` for A-LAW or ``'U'`` for u-LAW. .. function:: what(filename) Determines the type of sound data stored in the file *filename* using - :func:`whathdr`. If it succeeds, returns a tuple as described above, otherwise + :func:`whathdr`. If it succeeds, returns a namedtuple as described above, otherwise ``None`` is returned. + .. versionchanged:: 3.5 + Result changed from a tuple to a namedtuple. + .. function:: whathdr(filename) Determines the type of sound data stored in a file based on the file header. - The name of the file is given by *filename*. This function returns a tuple as + The name of the file is given by *filename*. This function returns a namedtuple as described above on success, or ``None``. + .. versionchanged:: 3.5 + Result changed from a tuple to a namedtuple. + diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index b01238c29dd4..f7b7d3d3b717 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -6,8 +6,7 @@ This module provides access to the BSD *socket* interface. It is available on -all modern Unix systems, Windows, MacOS, OS/2, and probably additional -platforms. +all modern Unix systems, Windows, MacOS, and probably additional platforms. .. note:: @@ -47,17 +46,20 @@ created. Socket addresses are represented as follows: - The address of an :const:`AF_UNIX` socket bound to a file system node is represented as a string, using the file system encoding and the ``'surrogateescape'`` error handler (see :pep:`383`). An address in - Linux's abstract namespace is returned as a :class:`bytes` object with + Linux's abstract namespace is returned as a :term:`bytes-like object` with an initial null byte; note that sockets in this namespace can communicate with normal file system sockets, so programs intended to run on Linux may need to deal with both types of address. A string or - :class:`bytes` object can be used for either type of address when + bytes-like object can be used for either type of address when passing it as an argument. .. versionchanged:: 3.3 Previously, :const:`AF_UNIX` socket paths were assumed to use UTF-8 encoding. + .. versionchanged: 3.5 + Writable :term:`bytes-like object` is now accepted. + - A pair ``(host, port)`` is used for the :const:`AF_INET` address family, where *host* is a string representing either a hostname in Internet domain notation like ``'daring.cwi.nl'`` or an IPv4 address like ``'100.50.200.5'``, @@ -91,9 +93,6 @@ created. Socket addresses are represented as follows: If *addr_type* is :const:`TIPC_ADDR_ID`, then *v1* is the node, *v2* is the reference, and *v3* should be set to 0. - If *addr_type* is :const:`TIPC_ADDR_ID`, then *v1* is the node, *v2* is the - reference, and *v3* should be set to 0. - - A tuple ``(interface, )`` is used for the :const:`AF_CAN` address family, where *interface* is a string representing a network interface name like ``'can0'``. The network interface name ``''`` can be used to receive packets @@ -107,8 +106,30 @@ created. Socket addresses are represented as follows: .. versionadded:: 3.3 -- Certain other address families (:const:`AF_BLUETOOTH`, :const:`AF_PACKET`, - :const:`AF_CAN`) support specific representations. +- :const:`AF_BLUETOOTH` supports the following protocols and address + formats: + + - :const:`BTPROTO_L2CAP` accepts ``(bdaddr, psm)`` where ``bdaddr`` is + the Bluetooth address as a string and ``psm`` is an integer. + + - :const:`BTPROTO_RFCOMM` accepts ``(bdaddr, channel)`` where ``bdaddr`` + is the Bluetooth address as a string and ``channel`` is an integer. + + - :const:`BTPROTO_HCI` accepts ``(device_id,)`` where ``device_id`` is + either an integer or a string with the Bluetooth address of the + interface. (This depends on your OS; NetBSD and DragonFlyBSD expect + a Bluetooth address while everything else expects an integer.) + + .. versionchanged:: 3.2 + NetBSD and DragonFlyBSD support added. + + - :const:`BTPROTO_SCO` accepts ``bdaddr`` where ``bdaddr`` is a + :class:`bytes` object containing the Bluetooth address in a + string format. (ex. ``b'12:23:34:45:56:67'``) This protocol is not + supported under FreeBSD. + +- Certain other address families (:const:`AF_PACKET`, :const:`AF_CAN`) + support specific representations. .. XXX document them! @@ -138,9 +159,12 @@ generalization of this based on timeouts is supported through Module contents --------------- -The module :mod:`socket` exports the following constants and functions: +The module :mod:`socket` exports the following elements. +Exceptions +^^^^^^^^^^ + .. exception:: error A deprecated alias of :exc:`OSError`. @@ -186,6 +210,15 @@ The module :mod:`socket` exports the following constants and functions: .. versionchanged:: 3.3 This class was made a subclass of :exc:`OSError`. + +Constants +^^^^^^^^^ + + The AF_* and SOCK_* constants are now :class:`AddressFamily` and + :class:`SocketKind` :class:`.IntEnum` collections. + + .. versionadded:: 3.4 + .. data:: AF_UNIX AF_INET AF_INET6 @@ -268,6 +301,18 @@ The module :mod:`socket` exports the following constants and functions: .. versionadded:: 3.4 +.. data:: CAN_RAW_FD_FRAMES + + Enables CAN FD support in a CAN_RAW socket. This is disabled by default. + This allows your application to send both CAN and CAN FD frames; however, + you one must accept both CAN and CAN FD frames when reading from the socket. + + This constant is documented in the Linux documentation. + + Availability: Linux >= 3.6. + + .. versionadded:: 3.5 + .. data:: AF_RDS PF_RDS SOL_RDS @@ -304,6 +349,79 @@ The module :mod:`socket` exports the following constants and functions: This constant contains a boolean value which indicates if IPv6 is supported on this platform. +.. data:: BDADDR_ANY + BDADDR_LOCAL + + These are string constants containing Bluetooth addresses with special + meanings. For example, :const:`BDADDR_ANY` can be used to indicate + any address when specifying the binding socket with + :const:`BTPROTO_RFCOMM`. + +.. data:: HCI_FILTER + HCI_TIME_STAMP + HCI_DATA_DIR + + For use with :const:`BTPROTO_HCI`. :const:`HCI_FILTER` is not + available for NetBSD or DragonFlyBSD. :const:`HCI_TIME_STAMP` and + :const:`HCI_DATA_DIR` are not available for FreeBSD, NetBSD, or + DragonFlyBSD. + +Functions +^^^^^^^^^ + +Creating sockets +'''''''''''''''' + +The following functions all create :ref:`socket objects <socket-objects>`. + + +.. function:: socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None) + + Create a new socket using the given address family, socket type and protocol + number. The address family should be :const:`AF_INET` (the default), + :const:`AF_INET6`, :const:`AF_UNIX`, :const:`AF_CAN` or :const:`AF_RDS`. The + socket type should be :const:`SOCK_STREAM` (the default), + :const:`SOCK_DGRAM`, :const:`SOCK_RAW` or perhaps one of the other ``SOCK_`` + constants. The protocol number is usually zero and may be omitted or in the + case where the address family is :const:`AF_CAN` the protocol should be one + of :const:`CAN_RAW` or :const:`CAN_BCM`. If *fileno* is specified, the other + arguments are ignored, causing the socket with the specified file descriptor + to return. Unlike :func:`socket.fromfd`, *fileno* will return the same + socket and not a duplicate. This may help close a detached socket using + :meth:`socket.close()`. + + The newly created socket is :ref:`non-inheritable <fd_inheritance>`. + + .. versionchanged:: 3.3 + The AF_CAN family was added. + The AF_RDS family was added. + + .. versionchanged:: 3.4 + The CAN_BCM protocol was added. + + .. versionchanged:: 3.4 + The returned socket is now non-inheritable. + + +.. function:: socketpair([family[, type[, proto]]]) + + Build a pair of connected socket objects using the given address family, socket + type, and protocol number. Address family, socket type, and protocol number are + as for the :func:`.socket` function above. The default family is :const:`AF_UNIX` + if defined on the platform; otherwise, the default is :const:`AF_INET`. + + The newly created sockets are :ref:`non-inheritable <fd_inheritance>`. + + .. versionchanged:: 3.2 + The returned socket objects now support the whole socket API, rather + than a subset. + + .. versionchanged:: 3.4 + The returned sockets are now non-inheritable. + + .. versionchanged:: 3.5 + Windows support added. + .. function:: create_connection(address[, timeout[, source_address]]) @@ -331,6 +449,45 @@ The module :mod:`socket` exports the following constants and functions: support for the :keyword:`with` statement was added. +.. function:: fromfd(fd, family, type, proto=0) + + Duplicate the file descriptor *fd* (an integer as returned by a file object's + :meth:`fileno` method) and build a socket object from the result. Address + family, socket type and protocol number are as for the :func:`.socket` function + above. The file descriptor should refer to a socket, but this is not checked --- + subsequent operations on the object may fail if the file descriptor is invalid. + This function is rarely needed, but can be used to get or set socket options on + a socket passed to a program as standard input or output (such as a server + started by the Unix inet daemon). The socket is assumed to be in blocking mode. + + The newly created socket is :ref:`non-inheritable <fd_inheritance>`. + + .. versionchanged:: 3.4 + The returned socket is now non-inheritable. + + +.. function:: fromshare(data) + + Instantiate a socket from data obtained from the :meth:`socket.share` + method. The socket is assumed to be in blocking mode. + + Availability: Windows. + + .. versionadded:: 3.3 + + +.. data:: SocketType + + This is a Python type object that represents the socket object type. It is the + same as ``type(socket(...))``. + + +Other functions +''''''''''''''' + +The :mod:`socket` module also offers various network-related services: + + .. function:: getaddrinfo(host, port, family=0, type=0, proto=0, flags=0) Translate the *host*/*port* argument into a sequence of 5-tuples that contain @@ -363,15 +520,17 @@ The module :mod:`socket` exports the following constants and functions: method. The following example fetches address information for a hypothetical TCP - connection to ``www.python.org`` on port 80 (results may differ on your + connection to ``example.org`` on port 80 (results may differ on your system if IPv6 isn't enabled):: - >>> socket.getaddrinfo("www.python.org", 80, proto=socket.SOL_TCP) - [(2, 1, 6, '', ('82.94.164.162', 80)), - (10, 1, 6, '', ('2001:888:2000:d::a2', 80, 0, 0))] + >>> socket.getaddrinfo("example.org", 80, proto=socket.IPPROTO_TCP) + [(<AddressFamily.AF_INET6: 10>, <SocketType.SOCK_STREAM: 1>, + 6, '', ('2606:2800:220:1:248:1893:25c8:1946', 80, 0, 0)), + (<AddressFamily.AF_INET: 2>, <SocketType.SOCK_STREAM: 1>, + 6, '', ('93.184.216.34', 80))] .. versionchanged:: 3.2 - parameters can now be passed as single keyword arguments. + parameters can now be passed using keyword arguments. .. function:: getfqdn([name]) @@ -415,7 +574,7 @@ The module :mod:`socket` exports the following constants and functions: always hold. Note: :func:`gethostname` doesn't always return the fully qualified domain - name; use ``getfqdn()`` (see above). + name; use :func:`getfqdn` for that. .. function:: gethostbyaddr(ip_address) @@ -460,65 +619,6 @@ The module :mod:`socket` exports the following constants and functions: ``'udp'``, otherwise any protocol will match. -.. function:: socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None) - - Create a new socket using the given address family, socket type and protocol - number. The address family should be :const:`AF_INET` (the default), - :const:`AF_INET6`, :const:`AF_UNIX`, :const:`AF_CAN` or :const:`AF_RDS`. The - socket type should be :const:`SOCK_STREAM` (the default), - :const:`SOCK_DGRAM`, :const:`SOCK_RAW` or perhaps one of the other ``SOCK_`` - constants. The protocol number is usually zero and may be omitted or in the - case where the address family is :const:`AF_CAN` the protocol should be one - of :const:`CAN_RAW` or :const:`CAN_BCM`. - - The newly created socket is :ref:`non-inheritable <fd_inheritance>`. - - .. versionchanged:: 3.3 - The AF_CAN family was added. - The AF_RDS family was added. - - .. versionchanged:: 3.4 - The CAN_BCM protocol was added. - - .. versionchanged:: 3.4 - The socket is now non-inheritable. - - -.. function:: socketpair([family[, type[, proto]]]) - - Build a pair of connected socket objects using the given address family, socket - type, and protocol number. Address family, socket type, and protocol number are - as for the :func:`.socket` function above. The default family is :const:`AF_UNIX` - if defined on the platform; otherwise, the default is :const:`AF_INET`. - Availability: Unix. - - The newly created sockets are :ref:`non-inheritable <fd_inheritance>`. - - .. versionchanged:: 3.2 - The returned socket objects now support the whole socket API, rather - than a subset. - - .. versionchanged:: 3.4 - The sockets are now non-inheritable. - - -.. function:: fromfd(fd, family, type, proto=0) - - Duplicate the file descriptor *fd* (an integer as returned by a file object's - :meth:`fileno` method) and build a socket object from the result. Address - family, socket type and protocol number are as for the :func:`.socket` function - above. The file descriptor should refer to a socket, but this is not checked --- - subsequent operations on the object may fail if the file descriptor is invalid. - This function is rarely needed, but can be used to get or set socket options on - a socket passed to a program as standard input or output (such as a server - started by the Unix inet daemon). The socket is assumed to be in blocking mode. - - The newly created socket is :ref:`non-inheritable <fd_inheritance>`. - - .. versionchanged:: 3.4 - The socket is now non-inheritable. - - .. function:: ntohl(x) Convert 32-bit positive integers from network to host byte order. On machines @@ -568,8 +668,8 @@ The module :mod:`socket` exports the following constants and functions: .. function:: inet_ntoa(packed_ip) - Convert a 32-bit packed IPv4 address (a bytes object four characters in - length) to its standard dotted-quad string representation (for example, + Convert a 32-bit packed IPv4 address (a :term:`bytes-like object` four + bytes in length) to its standard dotted-quad string representation (for example, '123.45.67.89'). This is useful when conversing with a program that uses the standard C library and needs objects of type :c:type:`struct in_addr`, which is the C type for the 32-bit packed binary data this function takes as an @@ -580,6 +680,9 @@ The module :mod:`socket` exports the following constants and functions: support IPv6, and :func:`inet_ntop` should be used instead for IPv4/v6 dual stack support. + .. versionchanged: 3.5 + Writable :term:`bytes-like object` is now accepted. + .. function:: inet_pton(address_family, ip_string) @@ -596,22 +699,32 @@ The module :mod:`socket` exports the following constants and functions: Availability: Unix (maybe not all platforms), Windows. + .. versionchanged:: 3.4 + Windows support added + .. function:: inet_ntop(address_family, packed_ip) - Convert a packed IP address (a bytes object of some number of characters) to its - standard, family-specific string representation (for example, ``'7.10.0.5'`` or - ``'5aef:2b::8'``). :func:`inet_ntop` is useful when a library or network protocol - returns an object of type :c:type:`struct in_addr` (similar to :func:`inet_ntoa`) - or :c:type:`struct in6_addr`. + Convert a packed IP address (a :term:`bytes-like object` of some number of + bytes) to its standard, family-specific string representation (for + example, ``'7.10.0.5'`` or ``'5aef:2b::8'``). + :func:`inet_ntop` is useful when a library or network protocol returns an + object of type :c:type:`struct in_addr` (similar to :func:`inet_ntoa`) or + :c:type:`struct in6_addr`. Supported values for *address_family* are currently :const:`AF_INET` and - :const:`AF_INET6`. If the string *packed_ip* is not the correct length for the - specified address family, :exc:`ValueError` will be raised. A - :exc:`OSError` is raised for errors from the call to :func:`inet_ntop`. + :const:`AF_INET6`. If the bytes object *packed_ip* is not the correct + length for the specified address family, :exc:`ValueError` will be raised. + A :exc:`OSError` is raised for errors from the call to :func:`inet_ntop`. Availability: Unix (maybe not all platforms), Windows. + .. versionchanged:: 3.4 + Windows support added + + .. versionchanged: 3.5 + Writable :term:`bytes-like object` is now accepted. + .. XXX: Are sendmsg(), recvmsg() and CMSG_*() available on any @@ -714,29 +827,14 @@ The module :mod:`socket` exports the following constants and functions: .. versionadded:: 3.3 -.. function:: fromshare(data) - - Instantiate a socket from data obtained from :meth:`~socket.share`. - The socket is assumed to be in blocking mode. - - Availability: Windows. - - .. versionadded:: 3.3 - - -.. data:: SocketType - - This is a Python type object that represents the socket object type. It is the - same as ``type(socket(...))``. - - .. _socket-objects: Socket Objects -------------- -Socket objects have the following methods. Except for :meth:`makefile` these -correspond to Unix system calls applicable to sockets. +Socket objects have the following methods. Except for +:meth:`~socket.makefile`, these correspond to Unix system calls applicable +to sockets. .. method:: socket.accept() @@ -751,6 +849,11 @@ correspond to Unix system calls applicable to sockets. .. versionchanged:: 3.4 The socket is now non-inheritable. + .. versionchanged:: 3.5 + If the system call is interrupted and the signal handler does not raise + an exception, the method now retries the system call instead of raising + an :exc:`InterruptedError` exception (see :pep:`475` for the rationale). + .. method:: socket.bind(address) @@ -760,11 +863,18 @@ correspond to Unix system calls applicable to sockets. .. method:: socket.close() - Close the socket. All future operations on the socket object will fail. The - remote end will receive no more data (after queued data is flushed). Sockets are - automatically closed when they are garbage-collected. + Mark the socket closed. The underlying system resource (e.g. a file + descriptor) is also closed when all file objects from :meth:`makefile()` + are closed. Once that happens, all future operations on the socket + object will fail. The remote end will receive no more data (after + queued data is flushed). + + Sockets are automatically closed when they are garbage-collected, but + it is recommended to :meth:`close` them explicitly, or to use a + :keyword:`with` statement around them. .. note:: + :meth:`close()` releases the resource associated with a connection but does not necessarily close the connection immediately. If you want to close the connection in a timely fashion, call :meth:`shutdown()` @@ -776,6 +886,19 @@ correspond to Unix system calls applicable to sockets. Connect to a remote socket at *address*. (The format of *address* depends on the address family --- see above.) + If the connection is interrupted by a signal, the method waits until the + connection completes, or raise a :exc:`socket.timeout` on timeout, if the + signal handler doesn't raise an exception and the socket is blocking or has + a timeout. For non-blocking sockets, the method raises an + :exc:`InterruptedError` exception if the connection is interrupted by a + signal (or the exception raised by the signal handler). + + .. versionchanged:: 3.5 + The method now waits until the connection completes instead of raising an + :exc:`InterruptedError` exception if the connection is interrupted by a + signal, the signal handler doesn't raise an exception and the socket is + blocking or has a timeout (see the :pep:`475` for the rationale). + .. method:: socket.connect_ex(address) @@ -871,12 +994,15 @@ correspond to Unix system calls applicable to sockets. On other platforms, the generic :func:`fcntl.fcntl` and :func:`fcntl.ioctl` functions may be used; they accept a socket object as their first argument. -.. method:: socket.listen(backlog) +.. method:: socket.listen([backlog]) - Listen for connections made to the socket. The *backlog* argument specifies the - maximum number of queued connections and should be at least 0; the maximum value - is system-dependent (usually 5), the minimum value is forced to 0. + Enable a server to accept connections. If *backlog* is specified, it must + be at least 0 (if it is lower, it is set to 0); it specifies the number of + unaccepted connections that the system will allow before refusing new + connections. If not specified, a default reasonable value is chosen. + .. versionchanged:: 3.5 + The *backlog* parameter is now optional. .. method:: socket.makefile(mode='r', buffering=None, *, encoding=None, \ errors=None, newline=None) @@ -887,10 +1013,13 @@ correspond to Unix system calls applicable to sockets. type depends on the arguments given to :meth:`makefile`. These arguments are interpreted the same way as by the built-in :func:`open` function. - Closing the file object won't close the socket unless there are no remaining - references to the socket. The socket must be in blocking mode; it can have - a timeout, but the file object's internal buffer may end up in a inconsistent - state if a timeout occurs. + The socket must be in blocking mode; it can have a timeout, but the file + object's internal buffer may end up in a inconsistent state if a timeout + occurs. + + Closing the file object returned by :meth:`makefile` won't close the + original socket unless all other file objects have been closed and + :meth:`socket.close` has been called on the socket object. .. note:: @@ -911,6 +1040,11 @@ correspond to Unix system calls applicable to sockets. For best match with hardware and network realities, the value of *bufsize* should be a relatively small power of 2, for example, 4096. + .. versionchanged:: 3.5 + If the system call is interrupted and the signal handler does not raise + an exception, the method now retries the system call instead of raising + an :exc:`InterruptedError` exception (see :pep:`475` for the rationale). + .. method:: socket.recvfrom(bufsize[, flags]) @@ -920,6 +1054,11 @@ correspond to Unix system calls applicable to sockets. :manpage:`recv(2)` for the meaning of the optional argument *flags*; it defaults to zero. (The format of *address* depends on the address family --- see above.) + .. versionchanged:: 3.5 + If the system call is interrupted and the signal handler does not raise + an exception, the method now retries the system call instead of raising + an :exc:`InterruptedError` exception (see :pep:`475` for the rationale). + .. method:: socket.recvmsg(bufsize[, ancbufsize[, flags]]) @@ -986,6 +1125,11 @@ correspond to Unix system calls applicable to sockets. .. versionadded:: 3.3 + .. versionchanged:: 3.5 + If the system call is interrupted and the signal handler does not raise + an exception, the method now retries the system call instead of raising + an :exc:`InterruptedError` exception (see :pep:`475` for the rationale). + .. method:: socket.recvmsg_into(buffers[, ancbufsize[, flags]]) @@ -1052,6 +1196,11 @@ correspond to Unix system calls applicable to sockets. application needs to attempt delivery of the remaining data. For further information on this topic, consult the :ref:`socket-howto`. + .. versionchanged:: 3.5 + If the system call is interrupted and the signal handler does not raise + an exception, the method now retries the system call instead of raising + an :exc:`InterruptedError` exception (see :pep:`475` for the rationale). + .. method:: socket.sendall(bytes[, flags]) @@ -1062,6 +1211,15 @@ correspond to Unix system calls applicable to sockets. success. On error, an exception is raised, and there is no way to determine how much data, if any, was successfully sent. + .. versionchanged:: 3.5 + The socket timeout is no more reset each time data is sent successfuly. + The socket timeout is now the maximum total duration to send all data. + + .. versionchanged:: 3.5 + If the system call is interrupted and the signal handler does not raise + an exception, the method now retries the system call instead of raising + an :exc:`InterruptedError` exception (see :pep:`475` for the rationale). + .. method:: socket.sendto(bytes, address) socket.sendto(bytes, flags, address) @@ -1072,13 +1230,19 @@ correspond to Unix system calls applicable to sockets. bytes sent. (The format of *address* depends on the address family --- see above.) + .. versionchanged:: 3.5 + If the system call is interrupted and the signal handler does not raise + an exception, the method now retries the system call instead of raising + an :exc:`InterruptedError` exception (see :pep:`475` for the rationale). + .. method:: socket.sendmsg(buffers[, ancdata[, flags[, address]]]) Send normal and ancillary data to the socket, gathering the non-ancillary data from a series of buffers and concatenating it into a single message. The *buffers* argument specifies the - non-ancillary data as an iterable of buffer-compatible objects + non-ancillary data as an iterable of + :term:`bytes-like objects <bytes-like object>` (e.g. :class:`bytes` objects); the operating system may set a limit (:func:`~os.sysconf` value ``SC_IOV_MAX``) on the number of buffers that can be used. The *ancdata* argument specifies the ancillary @@ -1086,7 +1250,7 @@ correspond to Unix system calls applicable to sockets. ``(cmsg_level, cmsg_type, cmsg_data)``, where *cmsg_level* and *cmsg_type* are integers specifying the protocol level and protocol-specific type respectively, and *cmsg_data* is a - buffer-compatible object holding the associated data. Note that + bytes-like object holding the associated data. Note that some systems (in particular, systems without :func:`CMSG_SPACE`) might support sending only one control message per call. The *flags* argument defaults to 0 and has the same meaning as for @@ -1107,6 +1271,26 @@ correspond to Unix system calls applicable to sockets. .. versionadded:: 3.3 + .. versionchanged:: 3.5 + If the system call is interrupted and the signal handler does not raise + an exception, the method now retries the system call instead of raising + an :exc:`InterruptedError` exception (see :pep:`475` for the rationale). + +.. method:: socket.sendfile(file, offset=0, count=None) + + Send a file until EOF is reached by using high-performance + :mod:`os.sendfile` and return the total number of bytes which were sent. + *file* must be a regular file object opened in binary mode. If + :mod:`os.sendfile` is not available (e.g. Windows) or *file* is not a + regular file :meth:`send` will be used instead. *offset* tells from where to + start reading the file. If specified, *count* is the total number of bytes + to transmit as opposed to sending the file until EOF is reached. File + position is updated on return or also in case of error in which case + :meth:`file.tell() <io.IOBase.tell>` can be used to figure out the number of + bytes which were sent. The socket must be of :const:`SOCK_STREAM` type. Non- + blocking sockets are not supported. + + .. versionadded:: 3.5 .. method:: socket.set_inheritable(inheritable) @@ -1146,11 +1330,15 @@ correspond to Unix system calls applicable to sockets. Set the value of the given socket option (see the Unix manual page :manpage:`setsockopt(2)`). The needed symbolic constants are defined in the - :mod:`socket` module (:const:`SO_\*` etc.). The value can be an integer or a - bytes object representing a buffer. In the latter case it is up to the caller to + :mod:`socket` module (:const:`SO_\*` etc.). The value can be an integer or + a :term:`bytes-like object` representing a buffer. In the latter case it is + up to the caller to ensure that the bytestring contains the proper bits (see the optional built-in module :mod:`struct` for a way to encode C structures as bytestrings). + .. versionchanged: 3.5 + Writable :term:`bytes-like object` is now accepted. + .. method:: socket.shutdown(how) @@ -1162,14 +1350,14 @@ correspond to Unix system calls applicable to sockets. .. method:: socket.share(process_id) - :platform: Windows + Duplicate a socket and prepare it for sharing with a target process. The + target process must be provided with *process_id*. The resulting bytes object + can then be passed to the target process using some form of interprocess + communication and the socket can be recreated there using :func:`fromshare`. + Once this method has been called, it is safe to close the socket since + the operating system has already duplicated it for the target process. - Duplacet a socket and prepare it for sharing with a target process. The - target process must be provided with *process_id*. The resulting bytes object - can then be passed to the target process using some form of interprocess - communication and the socket can be recreated there using :func:`fromshare`. - Once this method has been called, it is safe to close the socket since - the operating system has already duplicated it for the target process. + Availability: Windows. .. versionadded:: 3.3 @@ -1406,7 +1594,7 @@ After binding (:const:`CAN_RAW`) or connecting (:const:`CAN_BCM`) the socket, yo can use the :meth:`socket.send`, and the :meth:`socket.recv` operations (and their counterparts) on the socket object as usual. -This example might require special priviledge:: +This example might require special privileges:: import socket import struct @@ -1480,4 +1668,3 @@ the :data:`SO_REUSEADDR` flag tells the kernel to reuse a local socket in details of socket semantics. For Unix, refer to the manual pages; for Windows, see the WinSock (or Winsock 2) specification. For IPv6-ready APIs, readers may want to refer to :rfc:`3493` titled Basic Socket Interface Extensions for IPv6. - diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst index 1ec44389bf8c..18be936b08eb 100644 --- a/Doc/library/socketserver.rst +++ b/Doc/library/socketserver.rst @@ -33,9 +33,10 @@ Creating a server requires several steps. First, you must create a request handler class by subclassing the :class:`BaseRequestHandler` class and overriding its :meth:`handle` method; this method will process incoming requests. Second, you must instantiate one of the server classes, passing it -the server's address and the request handler class. Finally, call the +the server's address and the request handler class. Then call the :meth:`handle_request` or :meth:`serve_forever` method of the server object to -process one or many requests. +process one or many requests. Finally, call :meth:`~BaseServer.server_close` +to close the socket. When inheriting from :class:`ThreadingMixIn` for threaded connection behavior, you should explicitly declare how you want your threads to behave on an abrupt @@ -113,7 +114,7 @@ the request handler class :meth:`handle` method. Another approach to handling multiple simultaneous requests in an environment that supports neither threads nor :func:`~os.fork` (or where these are too expensive or inappropriate for the service) is to maintain an explicit table of -partially finished requests and to use :func:`~select.select` to decide which +partially finished requests and to use :mod:`selectors` to decide which request to work on next (or whether to handle a new incoming request). This is particularly important for stream services where each client can potentially be connected for a long time (if threads or subprocesses cannot be used). See @@ -136,7 +137,7 @@ Server Objects .. method:: BaseServer.fileno() Return an integer file descriptor for the socket on which the server is - listening. This function is most commonly passed to :func:`select.select`, to + listening. This function is most commonly passed to :mod:`selectors`, to allow monitoring multiple servers in the same process. @@ -177,6 +178,13 @@ Server Objects Tell the :meth:`serve_forever` loop to stop and wait until it does. +.. method:: BaseServer.server_close() + + Clean up the server. May be overridden. + + .. versionadded:: 2.6 + + .. attribute:: BaseServer.address_family The family of protocols to which the server's socket belongs. @@ -547,6 +555,7 @@ An example for the :class:`ThreadingMixIn` class:: client(ip, port, "Hello World 3") server.shutdown() + server.server_close() The output of the example should look something like this:: diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index bb4aab78bd0e..fc69a804d55d 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -13,8 +13,8 @@ SQLite for internal data storage. It's also possible to prototype an application using SQLite and then port the code to a larger database such as PostgreSQL or Oracle. -sqlite3 was written by Gerhard Häring and provides a SQL interface compliant -with the DB-API 2.0 specification described by :pep:`249`. +The sqlite3 module was written by Gerhard Häring. It provides a SQL interface +compliant with the DB-API 2.0 specification described by :pep:`249`. To use the module, you must first create a :class:`Connection` object that represents the database. Here the data will be stored in the @@ -31,23 +31,29 @@ and call its :meth:`~Cursor.execute` method to perform SQL commands:: c = conn.cursor() # Create table - c.execute('''create table stocks - (date text, trans text, symbol text, - qty real, price real)''') + c.execute('''CREATE TABLE stocks + (date text, trans text, symbol text, qty real, price real)''') # Insert a row of data - c.execute("""insert into stocks - values ('2006-01-05','BUY','RHAT',100,35.14)""") + c.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)") # Save (commit) the changes conn.commit() - # We can also close the cursor if we are done with it - c.close() + # We can also close the connection if we are done with it. + # Just be sure any changes have been committed or they will be lost. + conn.close() + +The data you've saved is persistent and is available in subsequent sessions:: + + import sqlite3 + conn = sqlite3.connect('example.db') + c = conn.cursor() Usually your SQL operations will need to use values from Python variables. You shouldn't assemble your query using Python's string operations because doing so -is insecure; it makes your program vulnerable to an SQL injection attack. +is insecure; it makes your program vulnerable to an SQL injection attack +(see http://xkcd.com/327/ for humorous example of what can go wrong). Instead, use the DB-API's parameter substitution. Put ``?`` as a placeholder wherever you want to use a value, and then provide a tuple of values as the @@ -56,19 +62,20 @@ modules may use a different placeholder, such as ``%s`` or ``:1``.) For example:: # Never do this -- insecure! - symbol = 'IBM' - c.execute("select * from stocks where symbol = '%s'" % symbol) + symbol = 'RHAT' + c.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol) # Do this instead - t = ('IBM',) - c.execute('select * from stocks where symbol=?', t) + t = ('RHAT',) + c.execute('SELECT * FROM stocks WHERE symbol=?', t) + print(c.fetchone()) - # Larger example - for t in [('2006-03-28', 'BUY', 'IBM', 1000, 45.00), - ('2006-04-05', 'BUY', 'MSFT', 1000, 72.00), - ('2006-04-06', 'SELL', 'IBM', 500, 53.00), - ]: - c.execute('insert into stocks values (?,?,?,?,?)', t) + # Larger example that inserts many records at a time + purchases = [('2006-03-28', 'BUY', 'IBM', 1000, 45.00), + ('2006-04-05', 'BUY', 'MSFT', 1000, 72.00), + ('2006-04-06', 'SELL', 'IBM', 500, 53.00), + ] + c.executemany('INSERT INTO stocks VALUES (?,?,?,?,?)', purchases) To retrieve data after executing a SELECT statement, you can either treat the cursor as an :term:`iterator`, call the cursor's :meth:`~Cursor.fetchone` method to @@ -77,21 +84,18 @@ matching rows. This example uses the iterator form:: - >>> c = conn.cursor() - >>> c.execute('select * from stocks order by price') - >>> for row in c: - ... print(row) - ... + >>> for row in c.execute('SELECT * FROM stocks ORDER BY price'): + print(row) + ('2006-01-05', 'BUY', 'RHAT', 100, 35.14) ('2006-03-28', 'BUY', 'IBM', 1000, 45.0) ('2006-04-06', 'SELL', 'IBM', 500, 53.0) - ('2006-04-05', 'BUY', 'MSOFT', 1000, 72.0) - >>> + ('2006-04-05', 'BUY', 'MSFT', 1000, 72.0) .. seealso:: - http://code.google.com/p/pysqlite/ + https://github.com/ghaering/pysqlite The pysqlite web page -- sqlite3 is developed externally under the name "pysqlite". @@ -99,6 +103,9 @@ This example uses the iterator form:: The SQLite web page; the documentation describes the syntax and the available data types for the supported SQL dialect. + http://www.w3schools.com/sql/ + Tutorial, reference and examples for learning SQL syntax. + :pep:`249` - Database API Specification 2.0 PEP written by Marc-André Lemburg. @@ -517,7 +524,7 @@ Cursor Objects .. method:: execute(sql, [parameters]) - Executes an SQL statement. The SQL statement may be parametrized (i. e. + Executes an SQL statement. The SQL statement may be parameterized (i. e. placeholders instead of SQL literals). The :mod:`sqlite3` module supports two kinds of placeholders: question marks (qmark style) and named placeholders (named style). @@ -639,9 +646,12 @@ Row Objects .. method:: keys - This method returns a tuple of column names. Immediately after a query, + This method returns a list of column names. Immediately after a query, it is the first member of each tuple in :attr:`Cursor.description`. + .. versionchanged:: 3.5 + Added support of slicing. + Let's assume we initialize a table as in the example given above:: conn = sqlite3.connect(":memory:") @@ -714,19 +724,20 @@ The following Python types can thus be sent to SQLite without any problem: This is how SQLite types are converted to Python types by default: -+-------------+---------------------------------------------+ -| SQLite type | Python type | -+=============+=============================================+ -| ``NULL`` | :const:`None` | -+-------------+---------------------------------------------+ -| ``INTEGER`` | :class:`int` | -+-------------+---------------------------------------------+ -| ``REAL`` | :class:`float` | -+-------------+---------------------------------------------+ -| ``TEXT`` | depends on text_factory, str by default | -+-------------+---------------------------------------------+ -| ``BLOB`` | :class:`bytes` | -+-------------+---------------------------------------------+ ++-------------+----------------------------------------------+ +| SQLite type | Python type | ++=============+==============================================+ +| ``NULL`` | :const:`None` | ++-------------+----------------------------------------------+ +| ``INTEGER`` | :class:`int` | ++-------------+----------------------------------------------+ +| ``REAL`` | :class:`float` | ++-------------+----------------------------------------------+ +| ``TEXT`` | depends on :attr:`~Connection.text_factory`, | +| | :class:`str` by default | ++-------------+----------------------------------------------+ +| ``BLOB`` | :class:`bytes` | ++-------------+----------------------------------------------+ The type system of the :mod:`sqlite3` module is extensible in two ways: you can store additional Python types in a SQLite database via object adaptation, and @@ -742,9 +753,6 @@ use other Python types with SQLite, you must **adapt** them to one of the sqlite3 module's supported types for SQLite: one of NoneType, int, float, str, bytes. -The :mod:`sqlite3` module uses Python object adaptation, as described in -:pep:`246` for this. The protocol to use is :class:`PrepareProtocol`. - There are two ways to enable the :mod:`sqlite3` module to adapt a custom Python type to one of the supported ones. @@ -800,8 +808,8 @@ and constructs a :class:`Point` object from it. .. note:: - Converter functions **always** get called with a string, no matter under which - data type you sent the value to SQLite. + Converter functions **always** get called with a :class:`bytes` object, no + matter under which data type you sent the value to SQLite. :: diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 30cb73207bbe..40751347ae7e 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -142,13 +142,16 @@ instead. Takes an instance ``sock`` of :class:`socket.socket`, and returns an instance of :class:`ssl.SSLSocket`, a subtype of :class:`socket.socket`, which wraps - the underlying socket in an SSL context. For client-side sockets, the - context construction is lazy; if the underlying socket isn't connected yet, - the context construction will be performed after :meth:`connect` is called on - the socket. For server-side sockets, if the socket has no remote peer, it is - assumed to be a listening socket, and the server-side SSL wrapping is - automatically performed on client connections accepted via the :meth:`accept` - method. :func:`wrap_socket` may raise :exc:`SSLError`. + the underlying socket in an SSL context. ``sock`` must be a + :data:`~socket.SOCK_STREAM` socket; other socket types are unsupported. + + For client-side sockets, the context construction is lazy; if the + underlying socket isn't connected yet, the context construction will be + performed after :meth:`connect` is called on the socket. For + server-side sockets, if the socket has no remote peer, it is assumed + to be a listening socket, and the server-side SSL wrapping is + automatically performed on client connections accepted via the + :meth:`accept` method. :func:`wrap_socket` may raise :exc:`SSLError`. The ``keyfile`` and ``certfile`` parameters specify optional files which contain a certificate to be used to identify the local side of the @@ -189,7 +192,7 @@ instead. ------------------------ --------- --------- ---------- --------- ----------- ----------- *SSLv2* yes no yes no no no *SSLv3* no yes yes no no no - *SSLv23* yes no yes no no no + *SSLv23* no yes yes yes yes yes *TLSv1* no no yes yes no no *TLSv1.1* no no yes no yes no *TLSv1.2* no no yes no no yes @@ -198,13 +201,8 @@ instead. .. note:: Which connections succeed will vary depending on the version of - OpenSSL. For instance, in some older versions of OpenSSL (such - as 0.9.7l on OS X 10.4), an SSLv2 client could not connect to an - SSLv23 server. Another example: beginning with OpenSSL 1.0.0, - an SSLv23 client will not actually attempt SSLv2 connections - unless you explicitly enable SSLv2 ciphers; for example, you - might specify ``"ALL"`` or ``"SSLv2"`` as the *ciphers* parameter - to enable them. + OpenSSL. For example, before OpenSSL 1.0.0, an SSLv23 client + would always attempt SSLv2 connections. The *ciphers* parameter sets the available ciphers for this SSL object. It should be a string in the `OpenSSL cipher list format @@ -247,13 +245,13 @@ purposes. :const:`None`, this function can choose to trust the system's default CA certificates instead. - The settings in Python 3.4 are: :data:`PROTOCOL_TLSv1` with high encryption - cipher suites without RC4 and without unauthenticated cipher suites. - Passing :data:`~Purpose.SERVER_AUTH` as *purpose* sets - :data:`~SSLContext.verify_mode` to :data:`CERT_REQUIRED` and either - loads CA certificates (when at least one of *cafile*, *capath* or *cadata* - is given) or uses :meth:`SSLContext.load_default_certs` to load default - CA certificates. + The settings are: :data:`PROTOCOL_SSLv23`, :data:`OP_NO_SSLv2`, and + :data:`OP_NO_SSLv3` with high encryption cipher suites without RC4 and + without unauthenticated cipher suites. Passing :data:`~Purpose.SERVER_AUTH` + as *purpose* sets :data:`~SSLContext.verify_mode` to :data:`CERT_REQUIRED` + and either loads CA certificates (when at least one of *cafile*, *capath* or + *cadata* is given) or uses :meth:`SSLContext.load_default_certs` to load + default CA certificates. .. note:: The protocol, options, cipher and other settings may change to more @@ -263,20 +261,39 @@ purposes. If your application needs specific settings, you should create a :class:`SSLContext` and apply the settings yourself. + .. note:: + If you find that when certain older clients or servers attempt to connect + with a :class:`SSLContext` created by this function that they get an error + stating "Protocol or cipher suite mismatch", it may be that they only + support SSL3.0 which this function excludes using the + :data:`OP_NO_SSLv3`. SSL3.0 is widely considered to be `completely broken + <https://en.wikipedia.org/wiki/POODLE>`_. If you still wish to continue to + use this function but still allow SSL 3.0 connections you can re-enable + them using:: + + ctx = ssl.create_default_context(Purpose.CLIENT_AUTH) + ctx.options &= ~ssl.OP_NO_SSLv3 + .. versionadded:: 3.4 + .. versionchanged:: 3.4.4 + + RC4 was dropped from the default cipher string. + Random generation ^^^^^^^^^^^^^^^^^ .. function:: RAND_bytes(num) - Returns *num* cryptographically strong pseudo-random bytes. Raises an + Return *num* cryptographically strong pseudo-random bytes. Raises an :class:`SSLError` if the PRNG has not been seeded with enough data or if the operation is not supported by the current RAND method. :func:`RAND_status` can be used to check the status of the PRNG and :func:`RAND_add` can be used to seed the PRNG. + For almost all applications :func:`os.urandom` is preferable. + Read the Wikipedia article, `Cryptographically secure pseudorandom number generator (CSPRNG) <http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator>`_, @@ -286,7 +303,7 @@ Random generation .. function:: RAND_pseudo_bytes(num) - Returns (bytes, is_cryptographic): bytes are *num* pseudo-random bytes, + Return (bytes, is_cryptographic): bytes are *num* pseudo-random bytes, is_cryptographic is ``True`` if the bytes generated are cryptographically strong. Raises an :class:`SSLError` if the operation is not supported by the current RAND method. @@ -296,14 +313,18 @@ Random generation for non-cryptographic purposes and for certain purposes in cryptographic protocols, but usually not for key generation etc. + For almost all applications :func:`os.urandom` is preferable. + + For almost all applications :func:`os.urandom` is preferable. + .. versionadded:: 3.3 .. function:: RAND_status() - Returns ``True`` if the SSL pseudo-random number generator has been seeded with - 'enough' randomness, and ``False`` otherwise. You can use :func:`ssl.RAND_egd` - and :func:`ssl.RAND_add` to increase the randomness of the pseudo-random - number generator. + Return ``True`` if the SSL pseudo-random number generator has been seeded + with 'enough' randomness, and ``False`` otherwise. You can use + :func:`ssl.RAND_egd` and :func:`ssl.RAND_add` to increase the randomness of + the pseudo-random number generator. .. function:: RAND_egd(path) @@ -316,13 +337,18 @@ Random generation See http://egd.sourceforge.net/ or http://prngd.sourceforge.net/ for sources of entropy-gathering daemons. + Availability: not available with LibreSSL. + .. function:: RAND_add(bytes, entropy) - Mixes the given *bytes* into the SSL pseudo-random number generator. The + Mix the given *bytes* into the SSL pseudo-random number generator. The parameter *entropy* (a float) is a lower bound on the entropy contained in string (so you can always use :const:`0.0`). See :rfc:`1750` for more information on sources of entropy. + .. versionchanged: 3.5 + Writable :term:`bytes-like object` is now accepted. + Certificate handling ^^^^^^^^^^^^^^^^^^^^ @@ -331,10 +357,9 @@ Certificate handling Verify that *cert* (in decoded format as returned by :meth:`SSLSocket.getpeercert`) matches the given *hostname*. The rules applied are those for checking the identity of HTTPS servers as outlined - in :rfc:`2818` and :rfc:`6125`, except that IP addresses are not currently - supported. In addition to HTTPS, this function should be suitable for - checking the identity of servers in various SSL-based protocols such as - FTPS, IMAPS, POPS and others. + in :rfc:`2818` and :rfc:`6125`. In addition to HTTPS, this function + should be suitable for checking the identity of servers in various + SSL-based protocols such as FTPS, IMAPS, POPS and others. :exc:`CertificateError` is raised on failure. On success, the function returns nothing:: @@ -356,22 +381,38 @@ Certificate handling IDN A-labels such as ``www*.xn--pthon-kva.org`` are still supported, but ``x*.python.org`` no longer matches ``xn--tda.python.org``. -.. function:: cert_time_to_seconds(timestring) + .. versionchanged:: 3.5 + Matching of IP addresses, when present in the subjectAltName field + of the certificate, is now supported. - Returns a floating-point value containing a normal seconds-after-the-epoch - time value, given the time-string representing the "notBefore" or "notAfter" - date from a certificate. +.. function:: cert_time_to_seconds(cert_time) - Here's an example:: + Return the time in seconds since the Epoch, given the ``cert_time`` + string representing the "notBefore" or "notAfter" date from a + certificate in ``"%b %d %H:%M:%S %Y %Z"`` strptime format (C + locale). - >>> import ssl - >>> ssl.cert_time_to_seconds("May 9 00:00:00 2007 GMT") - 1178694000.0 - >>> import time - >>> time.ctime(ssl.cert_time_to_seconds("May 9 00:00:00 2007 GMT")) - 'Wed May 9 00:00:00 2007' + Here's an example: -.. function:: get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None) + .. doctest:: newcontext + + >>> import ssl + >>> timestamp = ssl.cert_time_to_seconds("Jan 5 09:34:43 2018 GMT") + >>> timestamp + 1515144883 + >>> from datetime import datetime + >>> print(datetime.utcfromtimestamp(timestamp)) + 2018-01-05 09:34:43 + + "notBefore" or "notAfter" dates must use GMT (:rfc:`5280`). + + .. versionchanged:: 3.5 + Interpret the input time as a time in UTC as specified by 'GMT' + timezone in the input string. Local timezone was used + previously. Return an integer (no fractions of a second in the + input format) + +.. function:: get_server_certificate(addr, ssl_version=PROTOCOL_SSLv23, ca_certs=None) Given the address ``addr`` of an SSL-protected server, as a (*hostname*, *port-number*) pair, fetches the server's certificate, and returns it as a @@ -385,6 +426,10 @@ Certificate handling .. versionchanged:: 3.3 This function is now IPv6-compatible. + .. versionchanged:: 3.5 + The default *ssl_version* is changed from :data:`PROTOCOL_SSLv3` to + :data:`PROTOCOL_SSLv23` for maximum compatibility with modern servers. + .. function:: DER_cert_to_PEM_cert(DER_cert_bytes) Given a certificate as a DER-encoded blob of bytes, returns a PEM-encoded @@ -488,9 +533,9 @@ Constants .. data:: VERIFY_DEFAULT - Possible value for :attr:`SSLContext.verify_flags`. In this mode, - certificate revocation lists (CRLs) are not checked. By default OpenSSL - does neither require nor verify CRLs. + Possible value for :attr:`SSLContext.verify_flags`. In this mode, certificate + revocation lists (CRLs) are not checked. By default OpenSSL does neither + require nor verify CRLs. .. versionadded:: 3.4 @@ -518,28 +563,40 @@ Constants .. versionadded:: 3.4 +.. data:: VERIFY_X509_TRUSTED_FIRST + + Possible value for :attr:`SSLContext.verify_flags`. It instructs OpenSSL to + prefer trusted certificates when building the trust chain to validate a + certificate. This flag is enabled by default. + + .. versionadded:: 3.4.4 + +.. data:: PROTOCOL_SSLv23 + + Selects the highest protocol version that both the client and server support. + Despite the name, this option can select "TLS" protocols as well as "SSL". + .. data:: PROTOCOL_SSLv2 Selects SSL version 2 as the channel encryption protocol. - This protocol is not available if OpenSSL is compiled with OPENSSL_NO_SSL2 - flag. + This protocol is not available if OpenSSL is compiled with the + ``OPENSSL_NO_SSL2`` flag. .. warning:: SSL version 2 is insecure. Its use is highly discouraged. -.. data:: PROTOCOL_SSLv23 +.. data:: PROTOCOL_SSLv3 - Selects SSL version 2 or 3 as the channel encryption protocol. This is a - setting to use with servers for maximum compatibility with the other end of - an SSL connection, but it may cause the specific ciphers chosen for the - encryption to be of fairly low quality. + Selects SSL version 3 as the channel encryption protocol. -.. data:: PROTOCOL_SSLv3 + This protocol is not be available if OpenSSL is compiled with the + ``OPENSSL_NO_SSLv3`` flag. + + .. warning:: - Selects SSL version 3 as the channel encryption protocol. For clients, this - is the maximally compatible SSL variant. + SSL version 3 is insecure. Its use is highly discouraged. .. data:: PROTOCOL_TLSv1 @@ -547,7 +604,6 @@ Constants .. data:: PROTOCOL_TLSv1_1 - Selects TLS version 1.1 as the channel encryption protocol. Available only with openssl version 1.0.1+. @@ -555,11 +611,9 @@ Constants .. data:: PROTOCOL_TLSv1_2 - - Selects TLS version 1.2 as the channel encryption protocol. This is the most - modern version, and probably the best choice for maximum protection, if both - sides can speak it. - Available only with openssl version 1.0.1+. + Selects TLS version 1.2 as the channel encryption protocol. This is the + most modern version, and probably the best choice for maximum protection, + if both sides can speak it. Available only with openssl version 1.0.1+. .. versionadded:: 3.4 @@ -643,6 +697,13 @@ Constants .. versionadded:: 3.3 +.. data:: HAS_ALPN + + Whether the OpenSSL library has built-in support for the *Application-Layer + Protocol Negotiation* TLS extension as described in :rfc:`7301`. + + .. versionadded:: 3.5 + .. data:: HAS_ECDH Whether the OpenSSL library has built-in support for Elliptic Curve-based @@ -654,9 +715,7 @@ Constants .. data:: HAS_SNI Whether the OpenSSL library has built-in support for the *Server Name - Indication* extension to the SSLv3 and TLSv1 protocols (as defined in - :rfc:`4366`). When true, you can use the *server_hostname* argument to - :meth:`SSLContext.wrap_socket`. + Indication* extension (as defined in :rfc:`4366`). .. versionadded:: 3.2 @@ -742,42 +801,106 @@ Constants SSL Sockets ----------- -SSL sockets provide the following methods of :ref:`socket-objects`: - -- :meth:`~socket.socket.accept()` -- :meth:`~socket.socket.bind()` -- :meth:`~socket.socket.close()` -- :meth:`~socket.socket.connect()` -- :meth:`~socket.socket.detach()` -- :meth:`~socket.socket.fileno()` -- :meth:`~socket.socket.getpeername()`, :meth:`~socket.socket.getsockname()` -- :meth:`~socket.socket.getsockopt()`, :meth:`~socket.socket.setsockopt()` -- :meth:`~socket.socket.gettimeout()`, :meth:`~socket.socket.settimeout()`, - :meth:`~socket.socket.setblocking()` -- :meth:`~socket.socket.listen()` -- :meth:`~socket.socket.makefile()` -- :meth:`~socket.socket.recv()`, :meth:`~socket.socket.recv_into()` - (but passing a non-zero ``flags`` argument is not allowed) -- :meth:`~socket.socket.send()`, :meth:`~socket.socket.sendall()` (with - the same limitation) -- :meth:`~socket.socket.shutdown()` - -However, since the SSL (and TLS) protocol has its own framing atop -of TCP, the SSL sockets abstraction can, in certain respects, diverge from -the specification of normal, OS-level sockets. See especially the -:ref:`notes on non-blocking sockets <ssl-nonblocking>`. +.. class:: SSLSocket(socket.socket) + + SSL sockets provide the following methods of :ref:`socket-objects`: + + - :meth:`~socket.socket.accept()` + - :meth:`~socket.socket.bind()` + - :meth:`~socket.socket.close()` + - :meth:`~socket.socket.connect()` + - :meth:`~socket.socket.detach()` + - :meth:`~socket.socket.fileno()` + - :meth:`~socket.socket.getpeername()`, :meth:`~socket.socket.getsockname()` + - :meth:`~socket.socket.getsockopt()`, :meth:`~socket.socket.setsockopt()` + - :meth:`~socket.socket.gettimeout()`, :meth:`~socket.socket.settimeout()`, + :meth:`~socket.socket.setblocking()` + - :meth:`~socket.socket.listen()` + - :meth:`~socket.socket.makefile()` + - :meth:`~socket.socket.recv()`, :meth:`~socket.socket.recv_into()` + (but passing a non-zero ``flags`` argument is not allowed) + - :meth:`~socket.socket.send()`, :meth:`~socket.socket.sendall()` (with + the same limitation) + - :meth:`~socket.socket.sendfile()` (but :mod:`os.sendfile` will be used + for plain-text sockets only, else :meth:`~socket.socket.send()` will be used) + - :meth:`~socket.socket.shutdown()` + + However, since the SSL (and TLS) protocol has its own framing atop + of TCP, the SSL sockets abstraction can, in certain respects, diverge from + the specification of normal, OS-level sockets. See especially the + :ref:`notes on non-blocking sockets <ssl-nonblocking>`. + + Usually, :class:`SSLSocket` are not created directly, but using the + :func:`wrap_socket` function or the :meth:`SSLContext.wrap_socket` method. + + .. versionchanged:: 3.5 + The :meth:`sendfile` method was added. + + .. versionchanged:: 3.5 + The :meth:`shutdown` does not reset the socket timeout each time bytes + are received or sent. The socket timeout is now to maximum total duration + of the shutdown. + SSL sockets also have the following additional methods and attributes: +.. method:: SSLSocket.read(len=0, buffer=None) + + Read up to *len* bytes of data from the SSL socket and return the result as + a ``bytes`` instance. If *buffer* is specified, then read into the buffer + instead, and return the number of bytes read. + + Raise :exc:`SSLWantReadError` or :exc:`SSLWantWriteError` if the socket is + :ref:`non-blocking <ssl-nonblocking>` and the read would block. + + As at any time a re-negotiation is possible, a call to :meth:`read` can also + cause write operations. + + .. versionchanged:: 3.5 + The socket timeout is no more reset each time bytes are received or sent. + The socket timeout is now to maximum total duration to read up to *len* + bytes. + +.. method:: SSLSocket.write(buf) + + Write *buf* to the SSL socket and return the number of bytes written. The + *buf* argument must be an object supporting the buffer interface. + + Raise :exc:`SSLWantReadError` or :exc:`SSLWantWriteError` if the socket is + :ref:`non-blocking <ssl-nonblocking>` and the write would block. + + As at any time a re-negotiation is possible, a call to :meth:`write` can + also cause read operations. + + .. versionchanged:: 3.5 + The socket timeout is no more reset each time bytes are received or sent. + The socket timeout is now to maximum total duration to write *buf*. + +.. note:: + + The :meth:`~SSLSocket.read` and :meth:`~SSLSocket.write` methods are the + low-level methods that read and write unencrypted, application-level data + and and decrypt/encrypt it to encrypted, wire-level data. These methods + require an active SSL connection, i.e. the handshake was completed and + :meth:`SSLSocket.unwrap` was not called. + + Normally you should use the socket API methods like + :meth:`~socket.socket.recv` and :meth:`~socket.socket.send` instead of these + methods. + .. method:: SSLSocket.do_handshake() Perform the SSL setup handshake. .. versionchanged:: 3.4 - The handshake method also performce :func:`match_hostname` when the + The handshake method also performs :func:`match_hostname` when the :attr:`~SSLContext.check_hostname` attribute of the socket's :attr:`~SSLSocket.context` is true. + .. versionchanged:: 3.5 + The socket timeout is no more reset each time bytes are received or sent. + The socket timeout is now to maximum total duration of the handshake. + .. method:: SSLSocket.getpeercert(binary_form=False) If there is no certificate for the peer on the other end of the connection, @@ -818,6 +941,7 @@ SSL sockets also have the following additional methods and attributes: 'version': 3} .. note:: + To validate a certificate for a particular service, you can use the :func:`match_hostname` function. @@ -841,10 +965,8 @@ SSL sockets also have the following additional methods and attributes: .. versionchanged:: 3.4 :exc:`ValueError` is raised when the handshake isn't done. - - .. versionchanged:: 3.4 The returned dictionary includes additional X509v3 extension items - such as ``crlDistributionPoints``, ``caIssuers`` and ``OCSP`` URIs. + such as ``crlDistributionPoints``, ``caIssuers`` and ``OCSP`` URIs. .. method:: SSLSocket.cipher() @@ -852,6 +974,17 @@ SSL sockets also have the following additional methods and attributes: version of the SSL protocol that defines its use, and the number of secret bits being used. If no connection has been established, returns ``None``. +.. method:: SSLSocket.shared_ciphers() + + Return the list of ciphers shared by the client during the handshake. Each + entry of the returned list is a three-value tuple containing the name of the + cipher, the version of the SSL protocol that defines its use, and the number + of secret bits the cipher uses. :meth:`~SSLSocket.shared_ciphers` returns + ``None`` if no connection has been established or the socket is a client + socket. + + .. versionadded:: 3.5 + .. method:: SSLSocket.compression() Return the compression algorithm being used as a string, or ``None`` @@ -875,12 +1008,22 @@ SSL sockets also have the following additional methods and attributes: .. versionadded:: 3.3 +.. method:: SSLSocket.selected_alpn_protocol() + + Return the protocol that was selected during the TLS handshake. If + :meth:`SSLContext.set_alpn_protocols` was not called, if the other party does + not support ALPN, if this socket does not support any of the client's + proposed protocols, or if the handshake has not happened yet, ``None`` is + returned. + + .. versionadded:: 3.5 + .. method:: SSLSocket.selected_npn_protocol() - Returns the protocol that was selected during the TLS/SSL handshake. If - :meth:`SSLContext.set_npn_protocols` was not called, or if the other party - does not support NPN, or if the handshake has not yet happened, this will - return ``None``. + Return the higher-level protocol that was selected during the TLS/SSL + handshake. If :meth:`SSLContext.set_npn_protocols` was not called, or + if the other party does not support NPN, or if the handshake has not yet + happened, this will return ``None``. .. versionadded:: 3.3 @@ -892,6 +1035,21 @@ SSL sockets also have the following additional methods and attributes: returned socket should always be used for further communication with the other side of the connection, rather than the original socket. +.. method:: SSLSocket.version() + + Return the actual SSL protocol version negotiated by the connection + as a string, or ``None`` is no secure connection is established. + As of this writing, possible return values include ``"SSLv2"``, + ``"SSLv3"``, ``"TLSv1"``, ``"TLSv1.1"`` and ``"TLSv1.2"``. + Recent OpenSSL versions may define more return values. + + .. versionadded:: 3.5 + +.. method:: SSLSocket.pending() + + Returns the number of already decrypted bytes available for read, pending on + the connection. + .. attribute:: SSLSocket.context The :class:`SSLContext` object this SSL socket is tied to. If the SSL @@ -901,6 +1059,20 @@ SSL sockets also have the following additional methods and attributes: .. versionadded:: 3.2 +.. attribute:: SSLSocket.server_side + + A boolean which is ``True`` for server-side sockets and ``False`` for + client-side sockets. + + .. versionadded:: 3.2 + +.. attribute:: SSLSocket.server_hostname + + Hostname of the server: :class:`str` type, or ``None`` for server-side + socket or if the hostname was not specified in the constructor. + + .. versionadded:: 3.2 + SSL Contexts ------------ @@ -993,7 +1165,7 @@ to speed up repeated connections from the same clients. :data:`CERT_NONE`. At least one of *cafile* or *capath* must be specified. This method can also load certification revocation lists (CRLs) in PEM or - or DER format. In order to make use of CRLs, :attr:`SSLContext.verify_flags` + DER format. In order to make use of CRLs, :attr:`SSLContext.verify_flags` must be configured properly. The *cafile* string, if present, is the path to a file of concatenated @@ -1007,7 +1179,7 @@ to speed up repeated connections from the same clients. <http://www.openssl.org/docs/ssl/SSL_CTX_load_verify_locations.html>`_. The *cadata* object, if present, is either an ASCII string of one or more - PEM-encoded certificates or a bytes-like object of DER-encoded + PEM-encoded certificates or a :term:`bytes-like object` of DER-encoded certificates. Like with *capath* extra lines around PEM-encoded certificates are ignored but at least one certificate must be present. @@ -1023,6 +1195,10 @@ to speed up repeated connections from the same clients. does not contain certificates from *capath* unless a certificate was requested and loaded by a SSL connection. + .. note:: + Certificates in a capath directory aren't loaded unless they have + been used at least once. + .. versionadded:: 3.4 .. method:: SSLContext.set_default_verify_paths() @@ -1047,6 +1223,20 @@ to speed up repeated connections from the same clients. when connected, the :meth:`SSLSocket.cipher` method of SSL sockets will give the currently selected cipher. +.. method:: SSLContext.set_alpn_protocols(protocols) + + Specify which protocols the socket should advertise during the SSL/TLS + handshake. It should be a list of ASCII strings, like ``['http/1.1', + 'spdy/2']``, ordered by preference. The selection of a protocol will happen + during the handshake, and will play out according to :rfc:`7301`. After a + successful handshake, the :meth:`SSLSocket.selected_alpn_protocol` method will + return the agreed-upon protocol. + + This method will raise :exc:`NotImplementedError` if :data:`HAS_ALPN` is + False. + + .. versionadded:: 3.5 + .. method:: SSLContext.set_npn_protocols(protocols) Specify which protocols the socket should advertise during the SSL/TLS @@ -1087,7 +1277,7 @@ to speed up repeated connections from the same clients. Due to the early negotiation phase of the TLS connection, only limited methods and attributes are usable like - :meth:`SSLSocket.selected_npn_protocol` and :attr:`SSLSocket.context`. + :meth:`SSLSocket.selected_alpn_protocol` and :attr:`SSLSocket.context`. :meth:`SSLSocket.getpeercert`, :meth:`SSLSocket.getpeercert`, :meth:`SSLSocket.cipher` and :meth:`SSLSocket.compress` methods require that the TLS connection has progressed beyond the TLS Client Hello and therefore @@ -1099,7 +1289,7 @@ to speed up repeated connections from the same clients. returned. Other return values will result in a TLS fatal error with :const:`ALERT_DESCRIPTION_INTERNAL_ERROR`. - If there is a IDNA decoding error on the server name, the TLS connection + If there is an IDNA decoding error on the server name, the TLS connection will terminate with an :const:`ALERT_DESCRIPTION_INTERNAL_ERROR` fatal TLS alert message to the client. @@ -1149,7 +1339,10 @@ to speed up repeated connections from the same clients. server_hostname=None) Wrap an existing Python socket *sock* and return an :class:`SSLSocket` - object. The SSL socket is tied to the context, its settings and + object. *sock* must be a :data:`~socket.SOCK_STREAM` socket; other socket + types are unsupported. + + The returned SSL socket is tied to the context, its settings and certificates. The parameters *server_side*, *do_handshake_on_connect* and *suppress_ragged_eofs* have the same meaning as in the top-level :func:`wrap_socket` function. @@ -1157,11 +1350,22 @@ to speed up repeated connections from the same clients. On client connections, the optional parameter *server_hostname* specifies the hostname of the service which we are connecting to. This allows a single server to host multiple SSL-based services with distinct certificates, - quite similarly to HTTP virtual hosts. Specifying *server_hostname* - will raise a :exc:`ValueError` if the OpenSSL library doesn't have support - for it (that is, if :data:`HAS_SNI` is :const:`False`). Specifying - *server_hostname* will also raise a :exc:`ValueError` if *server_side* - is true. + quite similarly to HTTP virtual hosts. Specifying *server_hostname* will + raise a :exc:`ValueError` if *server_side* is true. + + .. versionchanged:: 3.5 + Always allow a server_hostname to be passed, even if OpenSSL does not + have SNI. + +.. method:: SSLContext.wrap_bio(incoming, outgoing, server_side=False, \ + server_hostname=None) + + Create a new :class:`SSLObject` instance by wrapping the BIO objects + *incoming* and *outgoing*. The SSL routines will read input data from the + incoming BIO and write data to the outgoing BIO. + + The *server_side* and *server_hostname* parameters have the same meaning as + in :meth:`SSLContext.wrap_socket`. .. method:: SSLContext.session_stats() @@ -1175,21 +1379,9 @@ to speed up repeated connections from the same clients. >>> stats['hits'], stats['misses'] (0, 0) -.. method:: SSLContext.get_ca_certs(binary_form=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. - - .. versionadded:: 3.4 - .. attribute:: SSLContext.check_hostname - Wether to match the peer cert's hostname with :func:`match_hostname` in + Whether to match the peer cert's hostname with :func:`match_hostname` in :meth:`SSLSocket.do_handshake`. The context's :attr:`~SSLContext.verify_mode` must be set to :data:`CERT_OPTIONAL` or :data:`CERT_REQUIRED`, and you must pass *server_hostname* to @@ -1205,8 +1397,8 @@ to speed up repeated connections from the same clients. context.load_default_certs() s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - ssl_sock = context.wrap_socket(s, server_hostname='www.verisign.com'): - ssl_sock.connect(('www.verisign.com', 443)) + ssl_sock = context.wrap_socket(s, server_hostname='www.verisign.com') + ssl_sock.connect(('www.verisign.com', 443)) .. versionadded:: 3.4 @@ -1324,20 +1516,9 @@ If you are going to require validation of the other side of the connection's certificate, you need to provide a "CA certs" file, filled with the certificate chains for each issuer you are willing to trust. Again, this file just contains these chains concatenated together. For validation, Python will use the first -chain it finds in the file which matches. Some "standard" root certificates are -available from various certification authorities: `CACert.org -<http://www.cacert.org/index.php?id=3>`_, `Thawte -<http://www.thawte.com/roots/>`_, `Verisign -<http://www.verisign.com/support/roots.html>`_, `Positive SSL -<http://www.PositiveSSL.com/ssl-certificate-support/cert_installation/UTN-USERFirst-Hardware.crt>`_ -(used by python.org), `Equifax and GeoTrust -<http://www.geotrust.com/resources/root_certificates/index.asp>`_. - -In general, if you are using SSL3 or TLS1, you don't need to put the full chain -in your "CA certs" file; you only need the root certificates, and the remote -peer is supposed to furnish the other certificates necessary to chain from its -certificate to a root certificate. See :rfc:`4158` for more discussion of the -way in which certification chains can be built. +chain it finds in the file which matches. The platform's certificates file can +be used by calling :meth:`SSLContext.load_default_certs`, this is done +automatically with :func:`.create_default_context`. Combined key and certificate ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1411,118 +1592,100 @@ should use the following idiom:: Client-side operation ^^^^^^^^^^^^^^^^^^^^^ -This example connects to an SSL server and prints the server's certificate:: - - import socket, ssl, pprint - - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - # require a certificate from the server - ssl_sock = ssl.wrap_socket(s, - ca_certs="/etc/ca_certs_file", - cert_reqs=ssl.CERT_REQUIRED) - ssl_sock.connect(('www.verisign.com', 443)) - - pprint.pprint(ssl_sock.getpeercert()) - # note that closing the SSLSocket will also close the underlying socket - ssl_sock.close() - -As of January 6, 2012, the certificate printed by this program looks like -this:: - - {'issuer': ((('countryName', 'US'),), - (('organizationName', 'VeriSign, Inc.'),), - (('organizationalUnitName', 'VeriSign Trust Network'),), - (('organizationalUnitName', - 'Terms of use at https://www.verisign.com/rpa (c)06'),), - (('commonName', - 'VeriSign Class 3 Extended Validation SSL SGC CA'),)), - 'notAfter': 'May 25 23:59:59 2012 GMT', - 'notBefore': 'May 26 00:00:00 2010 GMT', - 'serialNumber': '53D2BEF924A7245E83CA01E46CAA2477', - 'subject': ((('1.3.6.1.4.1.311.60.2.1.3', 'US'),), - (('1.3.6.1.4.1.311.60.2.1.2', 'Delaware'),), - (('businessCategory', 'V1.0, Clause 5.(b)'),), - (('serialNumber', '2497886'),), - (('countryName', 'US'),), - (('postalCode', '94043'),), - (('stateOrProvinceName', 'California'),), - (('localityName', 'Mountain View'),), - (('streetAddress', '487 East Middlefield Road'),), - (('organizationName', 'VeriSign, Inc.'),), - (('organizationalUnitName', ' Production Security Services'),), - (('commonName', 'www.verisign.com'),)), - 'subjectAltName': (('DNS', 'www.verisign.com'), - ('DNS', 'verisign.com'), - ('DNS', 'www.verisign.net'), - ('DNS', 'verisign.net'), - ('DNS', 'www.verisign.mobi'), - ('DNS', 'verisign.mobi'), - ('DNS', 'www.verisign.eu'), - ('DNS', 'verisign.eu')), - 'version': 3} +This example creates a SSL context with the recommended security settings +for client sockets, including automatic certificate verification:: -This other example first creates an SSL context, instructs it to verify -certificates sent by peers, and feeds it a set of recognized certificate -authorities (CA):: + >>> context = ssl.create_default_context() + +If you prefer to tune security settings yourself, you might create +a context from scratch (but beware that you might not get the settings +right):: >>> context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) >>> context.verify_mode = ssl.CERT_REQUIRED + >>> context.check_hostname = True >>> context.load_verify_locations("/etc/ssl/certs/ca-bundle.crt") -(it is assumed your operating system places a bundle of all CA certificates -in ``/etc/ssl/certs/ca-bundle.crt``; if not, you'll get an error and have -to adjust the location) +(this snippet assumes your operating system places a bundle of all CA +certificates in ``/etc/ssl/certs/ca-bundle.crt``; if not, you'll get an +error and have to adjust the location) When you use the context to connect to a server, :const:`CERT_REQUIRED` validates the server certificate: it ensures that the server certificate was signed with one of the CA certificates, and checks the signature for correctness:: - >>> conn = context.wrap_socket(socket.socket(socket.AF_INET)) - >>> conn.connect(("linuxfr.org", 443)) + >>> conn = context.wrap_socket(socket.socket(socket.AF_INET), + ... server_hostname="www.python.org") + >>> conn.connect(("www.python.org", 443)) -You should then fetch the certificate and check its fields for conformity:: +You may then fetch the certificate:: >>> cert = conn.getpeercert() - >>> ssl.match_hostname(cert, "linuxfr.org") Visual inspection shows that the certificate does identify the desired service -(that is, the HTTPS host ``linuxfr.org``):: +(that is, the HTTPS host ``www.python.org``):: >>> pprint.pprint(cert) - {'issuer': ((('organizationName', 'CAcert Inc.'),), - (('organizationalUnitName', 'http://www.cacert.org/'),), - (('commonName', 'CAcert Class 3 Root'),)), - 'notAfter': 'Jun 7 21:02:24 2013 GMT', - 'notBefore': 'Jun 8 21:02:24 2011 GMT', - 'serialNumber': 'D3E9', - 'subject': ((('commonName', 'linuxfr.org'),),), - 'subjectAltName': (('DNS', 'linuxfr.org'), - ('othername', '<unsupported>'), - ('DNS', 'linuxfr.org'), - ('othername', '<unsupported>'), - ('DNS', 'dev.linuxfr.org'), - ('othername', '<unsupported>'), - ('DNS', 'prod.linuxfr.org'), - ('othername', '<unsupported>'), - ('DNS', 'alpha.linuxfr.org'), - ('othername', '<unsupported>'), - ('DNS', '*.linuxfr.org'), - ('othername', '<unsupported>')), + {'OCSP': ('http://ocsp.digicert.com/',), + 'caIssuers': ('http://cacerts.digicert.com/DigiCertSHA2ExtendedValidationServerCA.crt',), + 'crlDistributionPoints': ('http://crl3.digicert.com/sha2-ev-server-g1.crl', + 'http://crl4.digicert.com/sha2-ev-server-g1.crl'), + 'issuer': ((('countryName', 'US'),), + (('organizationName', 'DigiCert Inc'),), + (('organizationalUnitName', 'www.digicert.com'),), + (('commonName', 'DigiCert SHA2 Extended Validation Server CA'),)), + 'notAfter': 'Sep 9 12:00:00 2016 GMT', + 'notBefore': 'Sep 5 00:00:00 2014 GMT', + 'serialNumber': '01BB6F00122B177F36CAB49CEA8B6B26', + 'subject': ((('businessCategory', 'Private Organization'),), + (('1.3.6.1.4.1.311.60.2.1.3', 'US'),), + (('1.3.6.1.4.1.311.60.2.1.2', 'Delaware'),), + (('serialNumber', '3359300'),), + (('streetAddress', '16 Allen Rd'),), + (('postalCode', '03894-4801'),), + (('countryName', 'US'),), + (('stateOrProvinceName', 'NH'),), + (('localityName', 'Wolfeboro,'),), + (('organizationName', 'Python Software Foundation'),), + (('commonName', 'www.python.org'),)), + 'subjectAltName': (('DNS', 'www.python.org'), + ('DNS', 'python.org'), + ('DNS', 'pypi.python.org'), + ('DNS', 'docs.python.org'), + ('DNS', 'testpypi.python.org'), + ('DNS', 'bugs.python.org'), + ('DNS', 'wiki.python.org'), + ('DNS', 'hg.python.org'), + ('DNS', 'mail.python.org'), + ('DNS', 'packaging.python.org'), + ('DNS', 'pythonhosted.org'), + ('DNS', 'www.pythonhosted.org'), + ('DNS', 'test.pythonhosted.org'), + ('DNS', 'us.pycon.org'), + ('DNS', 'id.python.org')), 'version': 3} -Now that you are assured of its authenticity, you can proceed to talk with -the server:: +Now the SSL channel is established and the certificate verified, you can +proceed to talk with the server:: >>> conn.sendall(b"HEAD / HTTP/1.0\r\nHost: linuxfr.org\r\n\r\n") >>> pprint.pprint(conn.recv(1024).split(b"\r\n")) - [b'HTTP/1.1 302 Found', - b'Date: Sun, 16 May 2010 13:43:28 GMT', - b'Server: Apache/2.2', - b'Location: https://linuxfr.org/pub/', - b'Vary: Accept-Encoding', + [b'HTTP/1.1 200 OK', + b'Date: Sat, 18 Oct 2014 18:27:20 GMT', + b'Server: nginx', + b'Content-Type: text/html; charset=utf-8', + b'X-Frame-Options: SAMEORIGIN', + b'Content-Length: 45679', + b'Accept-Ranges: bytes', + b'Via: 1.1 varnish', + b'Age: 2188', + b'X-Served-By: cache-lcy1134-LCY', + b'X-Cache: HIT', + b'X-Cache-Hits: 11', + b'Vary: Cookie', + b'Strict-Transport-Security: max-age=63072000; includeSubDomains', b'Connection: close', - b'Content-Type: text/html; charset=iso-8859-1', b'', b''] @@ -1540,7 +1703,7 @@ waiting for clients to connect:: import socket, ssl - context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) context.load_cert_chain(certfile="mycertfile", keyfile="mykeyfile") bindsocket = socket.socket() @@ -1576,7 +1739,7 @@ are finished with the client (or the client is finished with you):: And go back to listening for new client connections (of course, a real server would probably handle each client connection in a separate thread, or put -the sockets in non-blocking mode and use an event loop). +the sockets in :ref:`non-blocking mode <ssl-nonblocking>` and use an event loop). .. _ssl-nonblocking: @@ -1584,8 +1747,25 @@ the sockets in non-blocking mode and use an event loop). Notes on non-blocking sockets ----------------------------- -When working with non-blocking sockets, there are several things you need -to be aware of: +SSL sockets behave slightly different than regular sockets in +non-blocking mode. When working with non-blocking sockets, there are +thus several things you need to be aware of: + +- Most :class:`SSLSocket` methods will raise either + :exc:`SSLWantWriteError` or :exc:`SSLWantReadError` instead of + :exc:`BlockingIOError` if an I/O operation would + block. :exc:`SSLWantReadError` will be raised if a read operation on + the underlying socket is necessary, and :exc:`SSLWantWriteError` for + a write operation on the underlying socket. Note that attempts to + *write* to an SSL socket may require *reading* from the underlying + socket first, and attempts to *read* from the SSL socket may require + a prior *write* to the underlying socket. + + .. versionchanged:: 3.5 + + In earlier Python versions, the :meth:`!SSLSocket.send` method + returned zero instead of raising :exc:`SSLWantWriteError` or + :exc:`SSLWantReadError`. - Calling :func:`~select.select` tells you that the OS-level socket can be read from (or written to), but it does not imply that there is sufficient @@ -1594,8 +1774,14 @@ to be aware of: and :meth:`SSLSocket.send` failures, and retry after another call to :func:`~select.select`. +- Conversely, since the SSL layer has its own framing, a SSL socket may + still have data available for reading without :func:`~select.select` + being aware of it. Therefore, you should first call + :meth:`SSLSocket.recv` to drain any potentially available data, and then + only block on a :func:`~select.select` call if still necessary. + (of course, similar provisions apply when using other primitives such as - :func:`~select.poll`) + :func:`~select.poll`, or those in the :mod:`selectors` module) - The SSL handshake itself will be non-blocking: the :meth:`SSLSocket.do_handshake` method has to be retried until it returns @@ -1611,15 +1797,184 @@ to be aware of: except ssl.SSLWantWriteError: select.select([], [sock], []) +.. seealso:: + + The :mod:`asyncio` module supports :ref:`non-blocking SSL sockets + <ssl-nonblocking>` and provides a + higher level API. It polls for events using the :mod:`selectors` module and + handles :exc:`SSLWantWriteError`, :exc:`SSLWantReadError` and + :exc:`BlockingIOError` exceptions. It runs the SSL handshake asynchronously + as well. + + +Memory BIO Support +------------------ + +.. versionadded:: 3.5 + +Ever since the SSL module was introduced in Python 2.6, the :class:`SSLSocket` +class has provided two related but distinct areas of functionality: + +- SSL protocol handling +- Network IO + +The network IO API is identical to that provided by :class:`socket.socket`, +from which :class:`SSLSocket` also inherits. This allows an SSL socket to be +used as a drop-in replacement for a regular socket, making it very easy to add +SSL support to an existing application. + +Combining SSL protocol handling and network IO usually works well, but there +are some cases where it doesn't. An example is async IO frameworks that want to +use a different IO multiplexing model than the "select/poll on a file +descriptor" (readiness based) model that is assumed by :class:`socket.socket` +and by the internal OpenSSL socket IO routines. This is mostly relevant for +platforms like Windows where this model is not efficient. For this purpose, a +reduced scope variant of :class:`SSLSocket` called :class:`SSLObject` is +provided. + +.. class:: SSLObject + + A reduced-scope variant of :class:`SSLSocket` representing an SSL protocol + instance that does not contain any network IO methods. This class is + typically used by framework authors that want to implement asynchronous IO + for SSL through memory buffers. + + This class implements an interface on top of a low-level SSL object as + implemented by OpenSSL. This object captures the state of an SSL connection + but does not provide any network IO itself. IO needs to be performed through + separate "BIO" objects which are OpenSSL's IO abstraction layer. + + An :class:`SSLObject` instance can be created using the + :meth:`~SSLContext.wrap_bio` method. This method will create the + :class:`SSLObject` instance and bind it to a pair of BIOs. The *incoming* + BIO is used to pass data from Python to the SSL protocol instance, while the + *outgoing* BIO is used to pass data the other way around. + + The following methods are available: + + - :attr:`~SSLSocket.context` + - :attr:`~SSLSocket.server_side` + - :attr:`~SSLSocket.server_hostname` + - :meth:`~SSLSocket.read` + - :meth:`~SSLSocket.write` + - :meth:`~SSLSocket.getpeercert` + - :meth:`~SSLSocket.selected_npn_protocol` + - :meth:`~SSLSocket.cipher` + - :meth:`~SSLSocket.shared_ciphers` + - :meth:`~SSLSocket.compression` + - :meth:`~SSLSocket.pending` + - :meth:`~SSLSocket.do_handshake` + - :meth:`~SSLSocket.unwrap` + - :meth:`~SSLSocket.get_channel_binding` + + When compared to :class:`SSLSocket`, this object lacks the following + features: + + - Any form of network IO incluging methods such as ``recv()`` and + ``send()``. + + - There is no *do_handshake_on_connect* machinery. You must always manually + call :meth:`~SSLSocket.do_handshake` to start the handshake. + + - There is no handling of *suppress_ragged_eofs*. All end-of-file conditions + that are in violation of the protocol are reported via the + :exc:`SSLEOFError` exception. + + - The method :meth:`~SSLSocket.unwrap` call does not return anything, + unlike for an SSL socket where it returns the underlying socket. + + - The *server_name_callback* callback passed to + :meth:`SSLContext.set_servername_callback` will get an :class:`SSLObject` + instance instead of a :class:`SSLSocket` instance as its first parameter. + + Some notes related to the use of :class:`SSLObject`: + + - All IO on an :class:`SSLObject` is :ref:`non-blocking <ssl-nonblocking>`. + This means that for example :meth:`~SSLSocket.read` will raise an + :exc:`SSLWantReadError` if it needs more data than the incoming BIO has + available. + + - There is no module-level ``wrap_bio()`` call like there is for + :meth:`~SSLContext.wrap_socket`. An :class:`SSLObject` is always created + via an :class:`SSLContext`. + +An SSLObject communicates with the outside world using memory buffers. The +class :class:`MemoryBIO` provides a memory buffer that can be used for this +purpose. It wraps an OpenSSL memory BIO (Basic IO) object: + +.. class:: MemoryBIO + + A memory buffer that can be used to pass data between Python and an SSL + protocol instance. + + .. attribute:: MemoryBIO.pending + + Return the number of bytes currently in the memory buffer. + + .. attribute:: MemoryBIO.eof + + A boolean indicating whether the memory BIO is current at the end-of-file + position. + + .. method:: MemoryBIO.read(n=-1) + + Read up to *n* bytes from the memory buffer. If *n* is not specified or + negative, all bytes are returned. + + .. method:: MemoryBIO.write(buf) + + Write the bytes from *buf* to the memory BIO. The *buf* argument must be an + object supporting the buffer protocol. + + The return value is the number of bytes written, which is always equal to + the length of *buf*. + + .. method:: MemoryBIO.write_eof() + + Write an EOF marker to the memory BIO. After this method has been called, it + is illegal to call :meth:`~MemoryBIO.write`. The attribute :attr:`eof` will + become true after all data currently in the buffer has been read. + .. _ssl-security: Security considerations ----------------------- +Best defaults +^^^^^^^^^^^^^ + +For **client use**, if you don't have any special requirements for your +security policy, it is highly recommended that you use the +:func:`create_default_context` function to create your SSL context. +It will load the system's trusted CA certificates, enable certificate +validation and hostname checking, and try to choose reasonably secure +protocol and cipher settings. + +For example, here is how you would use the :class:`smtplib.SMTP` class to +create a trusted, secure connection to a SMTP server:: + + >>> import ssl, smtplib + >>> smtp = smtplib.SMTP("mail.python.org", port=587) + >>> context = ssl.create_default_context() + >>> smtp.starttls(context=context) + (220, b'2.0.0 Ready to start TLS') + +If a client certificate is needed for the connection, it can be added with +:meth:`SSLContext.load_cert_chain`. + +By contrast, if you create the SSL context by calling the :class:`SSLContext` +constructor yourself, it will not have certificate validation nor hostname +checking enabled by default. If you do so, please read the paragraphs below +to achieve a good security level. + +Manual settings +^^^^^^^^^^^^^^^ + Verifying certificates -^^^^^^^^^^^^^^^^^^^^^^ +'''''''''''''''''''''' +When calling the :class:`SSLContext` constructor directly, :const:`CERT_NONE` is the default. Since it does not authenticate the other peer, it can be insecure, especially in client mode where most of time you would like to ensure the authenticity of the server you're talking to. @@ -1643,37 +1998,32 @@ to specify :const:`CERT_REQUIRED` and similarly check the client certificate. by default). Protocol versions -^^^^^^^^^^^^^^^^^ +''''''''''''''''' -SSL version 2 is considered insecure and is therefore dangerous to use. If -you want maximum compatibility between clients and servers, it is recommended -to use :const:`PROTOCOL_SSLv23` as the protocol version and then disable -SSLv2 explicitly using the :data:`SSLContext.options` attribute:: +SSL versions 2 and 3 are considered insecure and are therefore dangerous to +use. If you want maximum compatibility between clients and servers, it is +recommended to use :const:`PROTOCOL_SSLv23` as the protocol version and then +disable SSLv2 and SSLv3 explicitly using the :data:`SSLContext.options` +attribute:: context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) context.options |= ssl.OP_NO_SSLv2 + context.options |= ssl.OP_NO_SSLv3 -The SSL context created above will allow SSLv3 and TLSv1 connections, but -not SSLv2. +The SSL context created above will only allow TLSv1 and later (if +supported by your system) connections. Cipher selection -^^^^^^^^^^^^^^^^ +'''''''''''''''' If you have advanced security requirements, fine-tuning of the ciphers enabled when negotiating a SSL session is possible through the :meth:`SSLContext.set_ciphers` method. Starting from Python 3.2.3, the ssl module disables certain weak ciphers by default, but you may want -to further restrict the cipher choice. For example:: - - context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) - context.set_ciphers('HIGH:!aNULL:!eNULL') - -The ``!aNULL:!eNULL`` part of the cipher spec is necessary to disable ciphers -which don't provide both encryption and authentication. Be sure to read -OpenSSL's documentation about the `cipher list -format <http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT>`_. -If you want to check which ciphers are enabled by a given cipher list, -use the ``openssl ciphers`` command on your system. +to further restrict the cipher choice. Be sure to read OpenSSL's documentation +about the `cipher list format <http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT>`_. +If you want to check which ciphers are enabled by a given cipher list, use the +``openssl ciphers`` command on your system. Multi-processing ^^^^^^^^^^^^^^^^ @@ -1707,10 +2057,10 @@ successful call of :func:`~ssl.RAND_add`, :func:`~ssl.RAND_bytes` or `RFC 4366: Transport Layer Security (TLS) Extensions <http://www.ietf.org/rfc/rfc4366>`_ Blake-Wilson et. al. - `RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2 <http://www.ietf.org/rfc/rfc5246>`_ + `RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2 <http://tools.ietf.org/html/rfc5246>`_ T. Dierks et. al. - `RFC 6066: Transport Layer Security (TLS) Extensions <http://www.ietf.org/rfc/rfc6066>`_ + `RFC 6066: Transport Layer Security (TLS) Extensions <http://tools.ietf.org/html/rfc6066>`_ D. Eastlake `IANA TLS: Transport Layer Security (TLS) Parameters <http://www.iana.org/assignments/tls-parameters/tls-parameters.xml>`_ diff --git a/Doc/library/stat.rst b/Doc/library/stat.rst index 24769f689321..845b2ef7daba 100644 --- a/Doc/library/stat.rst +++ b/Doc/library/stat.rst @@ -126,7 +126,7 @@ Example:: if __name__ == '__main__': walktree(sys.argv[1], visitfile) -An additional utility function is provided to covert a file's mode in a human +An additional utility function is provided to convert a file's mode in a human readable string: .. function:: filemode(mode) @@ -399,3 +399,29 @@ The following flags can be used in the *flags* argument of :func:`os.chflags`: The file is a snapshot file. See the \*BSD or Mac OS systems man page :manpage:`chflags(2)` for more information. + +On Windows, the following file attribute constants are available for use when +testing bits in the ``st_file_attributes`` member returned by :func:`os.stat`. +See the `Windows API documentation +<http://msdn.microsoft.com/en-us/library/windows/desktop/gg258117.aspx>`_ +for more detail on the meaning of these constants. + +.. data:: FILE_ATTRIBUTE_ARCHIVE + FILE_ATTRIBUTE_COMPRESSED + FILE_ATTRIBUTE_DEVICE + FILE_ATTRIBUTE_DIRECTORY + FILE_ATTRIBUTE_ENCRYPTED + FILE_ATTRIBUTE_HIDDEN + FILE_ATTRIBUTE_INTEGRITY_STREAM + FILE_ATTRIBUTE_NORMAL + FILE_ATTRIBUTE_NOT_CONTENT_INDEXED + FILE_ATTRIBUTE_NO_SCRUB_DATA + FILE_ATTRIBUTE_OFFLINE + FILE_ATTRIBUTE_READONLY + FILE_ATTRIBUTE_REPARSE_POINT + FILE_ATTRIBUTE_SPARSE_FILE + FILE_ATTRIBUTE_SYSTEM + FILE_ATTRIBUTE_TEMPORARY + FILE_ATTRIBUTE_VIRTUAL + + .. versionadded:: 3.5 diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index e6c5959d2c5d..0c9d88c8de3f 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -20,6 +20,16 @@ This module provides functions for calculating mathematical statistics of numeric (:class:`Real`-valued) data. +.. note:: + + Unless explicitly noted otherwise, these functions support :class:`int`, + :class:`float`, :class:`decimal.Decimal` and :class:`fractions.Fraction`. + Behaviour with other types (whether in the numeric tower or not) is + currently unsupported. Mixed types are also undefined and + implementation-dependent. If your input data consists of mixed types, + you may be able to use :func:`map` to ensure a consistent result, e.g. + ``map(float, input_data)``. + Averages and measures of central location ----------------------------------------- @@ -216,7 +226,7 @@ However, for reading convenience, most of the examples show sorted sequences. * Calculating the `median <http://www.ualberta.ca/~opscan/median.html>`_. * The `SSMEDIAN - <https://projects.gnome.org/gnumeric/doc/gnumeric-function-SSMEDIAN.shtml>`_ + <https://help.gnome.org/users/gnumeric/stable/gnumeric.html#gnumeric-function-SSMEDIAN>`_ function in the Gnome Gnumeric spreadsheet, including `this discussion <https://mail.gnome.org/archives/gnumeric-list/2011-April/msg00018.html>`_. diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 24c915523605..f274edb88049 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -269,8 +269,8 @@ the same rule. [2]_ The constructors :func:`int`, :func:`float`, and :func:`complex` can be used to produce numbers of a specific type. All numeric types (except complex) support the following operations, sorted by -ascending priority (operations in the same box have the same priority; all -numeric operations have a higher priority than comparison operations): +ascending priority (all numeric operations have a higher priority than +comparison operations): +---------------------+---------------------------------+---------+--------------------+ | Operation | Result | Notes | Full documentation | @@ -354,7 +354,7 @@ Notes: The numeric literals accepted include the digits ``0`` to ``9`` or any Unicode equivalent (code points with the ``Nd`` property). - See http://www.unicode.org/Public/6.0.0/ucd/extracted/DerivedNumericType.txt + See http://www.unicode.org/Public/8.0.0/ucd/extracted/DerivedNumericType.txt for a complete list of code points with the ``Nd`` property. @@ -404,8 +404,7 @@ The priorities of the binary bitwise operations are all lower than the numeric operations and higher than the comparisons; the unary operation ``~`` has the same priority as the other unary numeric operations (``+`` and ``-``). -This table lists the bitwise operations sorted in ascending priority -(operations in the same box have the same priority): +This table lists the bitwise operations sorted in ascending priority: +------------+--------------------------------+----------+ | Operation | Result | Notes | @@ -444,7 +443,7 @@ Additional Methods on Integer Types ----------------------------------- The int type implements the :class:`numbers.Integral` :term:`abstract base -class`. In addition, it provides one more method: +class`. In addition, it provides a few more methods: .. method:: int.bit_length() @@ -820,10 +819,10 @@ both mutable and immutable. The :class:`collections.abc.Sequence` ABC is provided to make it easier to correctly implement these operations on custom sequence types. -This table lists the sequence operations sorted in ascending priority -(operations in the same box have the same priority). In the table, *s* and *t* -are sequences of the same type, *n*, *i*, *j* and *k* are integers and *x* is -an arbitrary object that meets any type and value restrictions imposed by *s*. +This table lists the sequence operations sorted in ascending priority. In the +table, *s* and *t* are sequences of the same type, *n*, *i*, *j* and *k* are +integers and *x* is an arbitrary object that meets any type and value +restrictions imposed by *s*. The ``in`` and ``not in`` operations have the same priorities as the comparison operations. The ``+`` (concatenation) and ``*`` (repetition) @@ -855,8 +854,8 @@ operations have the same priority as the corresponding numeric operations. | ``s + t`` | the concatenation of *s* and | (6)(7) | | | *t* | | +--------------------------+--------------------------------+----------+ -| ``s * n`` or | *n* shallow copies of *s* | (2)(7) | -| ``n * s`` | concatenated | | +| ``s * n`` or | equivalent to adding *s* to | (2)(7) | +| ``n * s`` | itself *n* times | | +--------------------------+--------------------------------+----------+ | ``s[i]`` | *i*\ th item of *s*, origin 0 | \(3) | +--------------------------+--------------------------------+----------+ @@ -898,9 +897,9 @@ Notes: (2) Values of *n* less than ``0`` are treated as ``0`` (which yields an empty - sequence of the same type as *s*). Note also that the copies are shallow; - nested structures are not copied. This often haunts new Python programmers; - consider:: + sequence of the same type as *s*). Note that items in the sequence *s* + are not copied; they are referenced multiple times. This often haunts + new Python programmers; consider:: >>> lists = [[]] * 3 >>> lists @@ -910,7 +909,7 @@ Notes: [[3], [3], [3]] What has happened is that ``[[]]`` is a one-element list containing an empty - list, so all three elements of ``[[]] * 3`` are (pointers to) this single empty + list, so all three elements of ``[[]] * 3`` are references to this single empty list. Modifying any of the elements of ``lists`` modifies this single list. You can create a list of different lists this way:: @@ -921,6 +920,9 @@ Notes: >>> lists [[3], [5], [7]] + Further explanation is available in the FAQ entry + :ref:`faq-multidimensional-list`. + (3) If *i* or *j* is negative, the index is relative to the end of the string: ``len(s) + i`` or ``len(s) + j`` is substituted. But note that ``-0`` is @@ -1061,10 +1063,14 @@ accepts integers that meet the value restriction ``0 <= x <= 255``). | ``s.copy()`` | creates a shallow copy of ``s``| \(5) | | | (same as ``s[:]``) | | +------------------------------+--------------------------------+---------------------+ -| ``s.extend(t)`` | extends *s* with the | | -| | contents of *t* (same as | | +| ``s.extend(t)`` or | extends *s* with the | | +| ``s += t`` | contents of *t* (for the | | +| | most part the same as | | | | ``s[len(s):len(s)] = t``) | | +------------------------------+--------------------------------+---------------------+ +| ``s *= n`` | updates *s* with its contents | \(6) | +| | repeated *n* times | | ++------------------------------+--------------------------------+---------------------+ | ``s.insert(i, x)`` | inserts *x* into *s* at the | | | | index given by *i* | | | | (same as ``s[i:i] = [x]``) | | @@ -1105,6 +1111,12 @@ Notes: .. versionadded:: 3.3 :meth:`clear` and :meth:`!copy` methods. +(6) + The value *n* is an integer, or an object implementing + :meth:`~object.__index__`. Zero and negative values of *n* clear + the sequence. Items in the sequence are not copied; they are referenced + multiple times, as explained for ``s * n`` under :ref:`typesseq-common`. + .. _typesseq-list: @@ -1493,7 +1505,9 @@ expression support in the :mod:`re` module). .. method:: str.center(width[, fillchar]) Return centered in a string of length *width*. Padding is done using the - specified *fillchar* (default is a space). + specified *fillchar* (default is an ASCII space). The original string is + returned if *width* is less than or equal to ``len(s)``. + .. method:: str.count(sub[, start[, end]]) @@ -1511,7 +1525,7 @@ expression support in the :mod:`re` module). a :exc:`UnicodeError`. Other possible values are ``'ignore'``, ``'replace'``, ``'xmlcharrefreplace'``, ``'backslashreplace'`` and any other name registered via - :func:`codecs.register_error`, see section :ref:`codec-base-classes`. For a + :func:`codecs.register_error`, see section :ref:`error-handlers`. For a list of possible encodings, see section :ref:`standard-encodings`. .. versionchanged:: 3.1 @@ -1583,7 +1597,7 @@ expression support in the :mod:`re` module). .. method:: str.format_map(mapping) Similar to ``str.format(**mapping)``, except that ``mapping`` is - used directly and not copied to a :class:`dict` . This is useful + used directly and not copied to a :class:`dict`. This is useful if for example ``mapping`` is a dict subclass: >>> class Default(dict): @@ -1598,7 +1612,8 @@ expression support in the :mod:`re` module). .. method:: str.index(sub[, start[, end]]) - Like :meth:`find`, but raise :exc:`ValueError` when the substring is not found. + Like :meth:`~str.find`, but raise :exc:`ValueError` when the substring is + not found. .. method:: str.isalnum() @@ -1701,9 +1716,9 @@ expression support in the :mod:`re` module). .. method:: str.ljust(width[, fillchar]) - Return the string left justified in a string of length *width*. Padding is done - using the specified *fillchar* (default is a space). The original string is - returned if *width* is less than or equal to ``len(s)``. + Return the string left justified in a string of length *width*. Padding is + done using the specified *fillchar* (default is an ASCII space). The + original string is returned if *width* is less than or equal to ``len(s)``. .. method:: str.lower() @@ -1720,7 +1735,7 @@ expression support in the :mod:`re` module). Return a copy of the string with leading characters removed. The *chars* argument is a string specifying the set of characters to be removed. If omitted or ``None``, the *chars* argument defaults to removing whitespace. The *chars* - argument is not a prefix; rather, all combinations of its values are stripped: + argument is not a prefix; rather, all combinations of its values are stripped:: >>> ' spacious '.lstrip() 'spacious ' @@ -1773,9 +1788,9 @@ expression support in the :mod:`re` module). .. method:: str.rjust(width[, fillchar]) - Return the string right justified in a string of length *width*. Padding is done - using the specified *fillchar* (default is a space). The original string is - returned if *width* is less than or equal to ``len(s)``. + Return the string right justified in a string of length *width*. Padding is + done using the specified *fillchar* (default is an ASCII space). The + original string is returned if *width* is less than or equal to ``len(s)``. .. method:: str.rpartition(sep) @@ -1800,7 +1815,7 @@ expression support in the :mod:`re` module). Return a copy of the string with trailing characters removed. The *chars* argument is a string specifying the set of characters to be removed. If omitted or ``None``, the *chars* argument defaults to removing whitespace. The *chars* - argument is not a suffix; rather, all combinations of its values are stripped: + argument is not a suffix; rather, all combinations of its values are stripped:: >>> ' spacious '.rstrip() ' spacious' @@ -1822,6 +1837,15 @@ expression support in the :mod:`re` module). (for example, ``'1<>2<>3'.split('<>')`` returns ``['1', '2', '3']``). Splitting an empty string with a specified separator returns ``['']``. + For example:: + + >>> '1,2,3'.split(',') + ['1', '2', '3'] + >>> '1,2,3'.split(',', maxsplit=1) + ['1', '2,3'] + >>> '1,2,,3,'.split(',') + ['1', '2', '', '3', ''] + If *sep* is not specified or is ``None``, a different splitting algorithm is applied: runs of consecutive whitespace are regarded as a single separator, and the result will contain no empty strings at the start or end if the @@ -1829,8 +1853,14 @@ expression support in the :mod:`re` module). string or a string consisting of just whitespace with a ``None`` separator returns ``[]``. - For example, ``' 1 2 3 '.split()`` returns ``['1', '2', '3']``, and - ``' 1 2 3 '.split(None, 1)`` returns ``['1', '2 3 ']``. + For example:: + + >>> '1 2 3'.split() + ['1', '2', '3'] + >>> '1 2 3'.split(maxsplit=1) + ['1', '2 3'] + >>> ' 1 2 3 '.split() + ['1', '2', '3'] .. index:: @@ -1838,18 +1868,65 @@ expression support in the :mod:`re` module). .. method:: str.splitlines([keepends]) - Return a list of the lines in the string, breaking at line boundaries. - This method uses the :term:`universal newlines` approach to splitting lines. - Line breaks are not included in the resulting list unless *keepends* is - given and true. - - For example, ``'ab c\n\nde fg\rkl\r\n'.splitlines()`` returns - ``['ab c', '', 'de fg', 'kl']``, while the same call with ``splitlines(True)`` - returns ``['ab c\n', '\n', 'de fg\r', 'kl\r\n']``. + 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. + + This method splits on the following line boundaries. In particular, the + boundaries are a superset of :term:`universal newlines`. + + +-----------------------+-----------------------------+ + | Representation | Description | + +=======================+=============================+ + | ``\n`` | Line Feed | + +-----------------------+-----------------------------+ + | ``\r`` | Carriage Return | + +-----------------------+-----------------------------+ + | ``\r\n`` | Carriage Return + Line Feed | + +-----------------------+-----------------------------+ + | ``\v`` or ``\x0b`` | Line Tabulation | + +-----------------------+-----------------------------+ + | ``\f`` or ``\x0c`` | Form Feed | + +-----------------------+-----------------------------+ + | ``\x1c`` | File Separator | + +-----------------------+-----------------------------+ + | ``\x1d`` | Group Separator | + +-----------------------+-----------------------------+ + | ``\x1e`` | Record Separator | + +-----------------------+-----------------------------+ + | ``\x85`` | Next Line (C1 Control Code) | + +-----------------------+-----------------------------+ + | ``\u2028`` | Line Separator | + +-----------------------+-----------------------------+ + | ``\u2029`` | Paragraph Separator | + +-----------------------+-----------------------------+ + + .. versionchanged:: 3.2 + + ``\v`` and ``\f`` added to list of line boundaries. + + For example:: + + >>> 'ab c\n\nde fg\rkl\r\n'.splitlines() + ['ab c', '', 'de fg', 'kl'] + >>> 'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True) + ['ab c\n', '\n', 'de fg\r', 'kl\r\n'] Unlike :meth:`~str.split` when a delimiter string *sep* is given, this method returns an empty list for the empty string, and a terminal line - break does not result in an extra line. + break does not result in an extra line:: + + >>> "".splitlines() + [] + >>> "One line\n".splitlines() + ['One line'] + + For comparison, ``split('\n')`` gives:: + + >>> ''.split('\n') + [''] + >>> 'Two lines\n'.split('\n') + ['Two lines', ''] .. method:: str.startswith(prefix[, start[, end]]) @@ -1866,13 +1943,23 @@ expression support in the :mod:`re` module). The *chars* argument is a string specifying the set of characters to be removed. If omitted or ``None``, the *chars* argument defaults to removing whitespace. The *chars* argument is not a prefix or suffix; rather, all combinations of its - values are stripped: + values are stripped:: >>> ' spacious '.strip() 'spacious' >>> 'www.example.com'.strip('cmowz.') 'example' + The outermost leading and trailing *chars* argument values are stripped + from the string. Characters are removed from the leading end until + reaching a string character that is not contained in the set of + characters in *chars*. A similar action takes place on the trailing end. + For example:: + + >>> comment_string = '#....... Section 3.2.1 Issue #32 .......' + >>> comment_string.strip('.#! ') + 'Section 3.2.1 Issue #32' + .. method:: str.swapcase() @@ -1886,6 +1973,11 @@ expression support in the :mod:`re` module). Return a titlecased version of the string where words start with an uppercase character and the remaining characters are lowercase. + For example:: + + >>> 'Hello world'.title() + 'Hello World' + The algorithm uses a simple language-independent definition of a word as groups of consecutive letters. The definition works in many contexts but it means that apostrophes in contractions and possessives form word @@ -1907,21 +1999,22 @@ expression support in the :mod:`re` module). "They're Bill's Friends." -.. method:: str.translate(map) +.. method:: str.translate(table) - Return a copy of the *s* where all characters have been mapped through the - *map* which must be a dictionary of Unicode ordinals (integers) to Unicode - ordinals, strings or ``None``. Unmapped characters are left untouched. - Characters mapped to ``None`` are deleted. + Return a copy of the string in which each character has been mapped through + the given translation table. The table must be an object that implements + indexing via :meth:`__getitem__`, typically a :term:`mapping` or + :term:`sequence`. When indexed by a Unicode ordinal (an integer), the + table object can do any of the following: return a Unicode ordinal or a + string, to map the character to one or more other characters; return + ``None``, to delete the character from the return string; or raise a + :exc:`LookupError` exception, to map the character to itself. You can use :meth:`str.maketrans` to create a translation map from character-to-character mappings in different formats. - .. note:: - - An even more flexible approach is to create a custom character mapping - codec using the :mod:`codecs` module (see :mod:`encodings.cp1251` for an - example). + See also the :mod:`codecs` module for a more flexible approach to custom + character mappings. .. method:: str.upper() @@ -1938,9 +2031,18 @@ expression support in the :mod:`re` module). .. method:: str.zfill(width) - Return the numeric string left filled with zeros in a string of length - *width*. A sign prefix is handled correctly. The original string is - returned if *width* is less than or equal to ``len(s)``. + Return a copy of the string left filled with ASCII ``'0'`` digits to + make a string of length *width*. A leading sign prefix (``'+'``/``'-'``) + is handled by inserting the padding *after* the sign character rather + than before. The original string is returned if *width* is less than + or equal to ``len(s)``. + + For example:: + + >>> "42".zfill(5) + '00042' + >>> "-42".zfill(5) + '-0042' @@ -2198,16 +2300,41 @@ other ways: Also see the :ref:`bytes <func-bytes>` built-in. -Since bytes objects are sequences of integers, for a bytes object *b*, -``b[0]`` will be an integer, while ``b[0:1]`` will be a bytes object of -length 1. (This contrasts with text strings, where both indexing and -slicing will produce a string of length 1) +Since 2 hexadecimal digits correspond precisely to a single byte, hexadecimal +numbers are a commonly used format for describing binary data. Accordingly, +the bytes type has an additional class method to read data in that format: + +.. classmethod:: bytes.fromhex(string) + + This :class:`bytes` class method returns a bytes object, decoding the + given string object. The string must contain two hexadecimal digits per + byte, with ASCII spaces being ignored. + + >>> bytes.fromhex('2Ef0 F1f2 ') + b'.\xf0\xf1\xf2' + +A reverse conversion function exists to transform a bytes object into its +hexadecimal representation. + +.. method:: bytes.hex() + + Return a string object containing two hexadecimal digits for each + byte in the instance. + + >>> b'\xf0\xf1\xf2'.hex() + 'f0f1f2' + + .. versionadded:: 3.5 + +Since bytes objects are sequences of integers (akin to a tuple), for a bytes +object *b*, ``b[0]`` will be an integer, while ``b[0:1]`` will be a bytes +object of length 1. (This contrasts with text strings, where both indexing +and slicing will produce a string of length 1) The representation of bytes objects uses the literal format (``b'...'``) since it is often more useful than e.g. ``bytes([46, 46, 46])``. You can always convert a bytes object into a list of integers using ``list(b)``. - .. note:: For Python 2.x users: In the Python 2.x series, a variety of implicit conversions between 8-bit strings (the closest thing 2.x offers to a @@ -2241,6 +2368,42 @@ common bytes and bytearray operations described in :ref:`bytes-methods`. Also see the :ref:`bytearray <func-bytearray>` built-in. +Since 2 hexadecimal digits correspond precisely to a single byte, hexadecimal +numbers are a commonly used format for describing binary data. Accordingly, +the bytearray type has an additional class method to read data in that format: + +.. classmethod:: bytearray.fromhex(string) + + This :class:`bytearray` class method returns bytearray object, decoding + the given string object. The string must contain two hexadecimal digits + per byte, with ASCII spaces being ignored. + + >>> bytearray.fromhex('2Ef0 F1f2 ') + bytearray(b'.\xf0\xf1\xf2') + +A reverse conversion function exists to transform a bytearray object into its +hexadecimal representation. + +.. method:: bytearray.hex() + + Return a string object containing two hexadecimal digits for each + byte in the instance. + + >>> bytearray(b'\xf0\xf1\xf2').hex() + 'f0f1f2' + + .. versionadded:: 3.5 + +Since bytearray objects are sequences of integers (akin to a list), for a +bytearray object *b*, ``b[0]`` will be an integer, while ``b[0:1]`` will be +a bytearray object of length 1. (This contrasts with text strings, where +both indexing and slicing will produce a string of length 1) + +The representation of bytearray objects uses the bytes literal format +(``bytearray(b'...')``) since it is often more useful than e.g. +``bytearray([46, 46, 46])``. You can always convert a bytearray object into +a list of integers using ``list(b)``. + .. _bytes-methods: @@ -2252,25 +2415,10 @@ Bytes and Bytearray Operations Both bytes and bytearray objects support the :ref:`common <typesseq-common>` sequence operations. They interoperate not just with operands of the same -type, but with any object that supports the -:ref:`buffer protocol <bufferobjects>`. Due to this flexibility, they can be +type, but with any :term:`bytes-like object`. Due to this flexibility, they can be freely mixed in operations without causing errors. However, the return type of the result may depend on the order of operands. -Due to the common use of ASCII text as the basis for binary protocols, bytes -and bytearray objects provide almost all methods found on text strings, with -the exceptions of: - -* :meth:`str.encode` (which converts text strings to bytes objects) -* :meth:`str.format` and :meth:`str.format_map` (which are used to format - text for display to users) -* :meth:`str.isidentifier`, :meth:`str.isnumeric`, :meth:`str.isdecimal`, - :meth:`str.isprintable` (which are used to check various properties of - text strings which are not typically applicable to binary protocols). - -All other string methods are supported, although sometimes with slight -differences in functionality and semantics (as described below). - .. note:: The methods on bytes and bytearray objects don't accept strings as their @@ -2285,25 +2433,30 @@ differences in functionality and semantics (as described below). a = b"abc" b = a.replace(b"a", b"f") -Whenever a bytes or bytearray method needs to interpret the bytes as -characters (e.g. the :meth:`is...` methods, :meth:`split`, :meth:`strip`), -the ASCII character set is assumed (text strings use Unicode semantics). +Some bytes and bytearray operations assume the use of ASCII compatible +binary formats, and hence should be avoided when working with arbitrary +binary data. These restrictions are covered below. .. note:: - Using these ASCII based methods to manipulate binary data that is not + Using these ASCII based operations to manipulate binary data that is not stored in an ASCII based format may lead to data corruption. -The search operations (:keyword:`in`, :meth:`count`, :meth:`find`, -:meth:`index`, :meth:`rfind` and :meth:`rindex`) all accept both integers -in the range 0 to 255 (inclusive) as well as bytes and byte array sequences. +The following methods on bytes and bytearray objects can be used with +arbitrary binary data. -.. versionchanged:: 3.3 - All of the search methods also accept an integer in the range 0 to 255 - (inclusive) as their first argument. +.. method:: bytes.count(sub[, start[, end]]) + bytearray.count(sub[, start[, end]]) + + Return the number of non-overlapping occurrences of subsequence *sub* in + the range [*start*, *end*]. Optional arguments *start* and *end* are + interpreted as in slice notation. + + The subsequence to search for may be any :term:`bytes-like object` or an + integer in the range 0 to 255. + .. versionchanged:: 3.3 + Also accept an integer in the range 0 to 255 as the subsequence. -Each bytes and bytearray instance provides a :meth:`~bytes.decode` convenience -method that is the inverse of :meth:`str.encode`: .. method:: bytes.decode(encoding="utf-8", errors="strict") bytearray.decode(encoding="utf-8", errors="strict") @@ -2313,40 +2466,178 @@ method that is the inverse of :meth:`str.encode`: error handling scheme. The default for *errors* is ``'strict'``, meaning that encoding errors raise a :exc:`UnicodeError`. Other possible values are ``'ignore'``, ``'replace'`` and any other name registered via - :func:`codecs.register_error`, see section :ref:`codec-base-classes`. For a + :func:`codecs.register_error`, see section :ref:`error-handlers`. For a list of possible encodings, see section :ref:`standard-encodings`. + .. note:: + + Passing the *encoding* argument to :class:`str` allows decoding any + :term:`bytes-like object` directly, without needing to make a temporary + bytes or bytearray object. + .. versionchanged:: 3.1 Added support for keyword arguments. -Since 2 hexadecimal digits correspond precisely to a single byte, hexadecimal -numbers are a commonly used format for describing binary data. Accordingly, -the bytes and bytearray types have an additional class method to read data in -that format: -.. classmethod:: bytes.fromhex(string) - bytearray.fromhex(string) +.. method:: bytes.endswith(suffix[, start[, end]]) + bytearray.endswith(suffix[, start[, end]]) - This :class:`bytes` class method returns a bytes or bytearray object, - decoding the given string object. The string must contain two hexadecimal - digits per byte, spaces are ignored. + Return ``True`` if the binary data ends with the specified *suffix*, + otherwise return ``False``. *suffix* can also be a tuple of suffixes to + look for. With optional *start*, test beginning at that position. With + optional *end*, stop comparing at that position. - >>> bytes.fromhex('2Ef0 F1f2 ') - b'.\xf0\xf1\xf2' + The suffix(es) to search for may be any :term:`bytes-like object`. + + +.. method:: bytes.find(sub[, start[, end]]) + bytearray.find(sub[, start[, end]]) + + Return the lowest index in the data where the subsequence *sub* is found, + such that *sub* is contained in the slice ``s[start:end]``. Optional + arguments *start* and *end* are interpreted as in slice notation. Return + ``-1`` if *sub* is not found. + + The subsequence to search for may be any :term:`bytes-like object` or an + integer in the range 0 to 255. + + .. note:: + + The :meth:`~bytes.find` method should be used only if you need to know the + position of *sub*. To check if *sub* is a substring or not, use the + :keyword:`in` operator:: + + >>> b'Py' in b'Python' + True + + .. versionchanged:: 3.3 + Also accept an integer in the range 0 to 255 as the subsequence. + + +.. method:: bytes.index(sub[, start[, end]]) + bytearray.index(sub[, start[, end]]) + + Like :meth:`~bytes.find`, but raise :exc:`ValueError` when the + subsequence is not found. + + The subsequence to search for may be any :term:`bytes-like object` or an + integer in the range 0 to 255. + + .. versionchanged:: 3.3 + Also accept an integer in the range 0 to 255 as the subsequence. + + +.. method:: bytes.join(iterable) + bytearray.join(iterable) + Return a bytes or bytearray object which is the concatenation of the + binary data sequences in the :term:`iterable` *iterable*. A + :exc:`TypeError` will be raised if there are any values in *iterable* + that are not :term:`bytes-like objects <bytes-like object>`, including + :class:`str` objects. The separator between elements is the contents + of the bytes or bytearray object providing this method. + + +.. staticmethod:: bytes.maketrans(from, to) + bytearray.maketrans(from, to) + + This static method returns a translation table usable for + :meth:`bytes.translate` that will map each character in *from* into the + character at the same position in *to*; *from* and *to* must both be + :term:`bytes-like objects <bytes-like object>` and have the same length. + + .. versionadded:: 3.1 + + +.. method:: bytes.partition(sep) + bytearray.partition(sep) + + Split the sequence at the first occurrence of *sep*, and return a 3-tuple + containing the part before the separator, the separator, and the part + after the separator. If the separator is not found, return a 3-tuple + containing a copy of the original sequence, followed by two empty bytes or + bytearray objects. + + The separator to search for may be any :term:`bytes-like object`. + + +.. method:: bytes.replace(old, new[, count]) + bytearray.replace(old, new[, count]) + + Return a copy of the sequence with all occurrences of subsequence *old* + replaced by *new*. If the optional argument *count* is given, only the + first *count* occurrences are replaced. + + The subsequence to search for and its replacement may be any + :term:`bytes-like object`. + + .. note:: + + The bytearray version of this method does *not* operate in place - it + always produces a new object, even if no changes were made. + + +.. method:: bytes.rfind(sub[, start[, end]]) + bytearray.rfind(sub[, start[, end]]) + + Return the highest index in the sequence where the subsequence *sub* is + found, such that *sub* is contained within ``s[start:end]``. Optional + arguments *start* and *end* are interpreted as in slice notation. Return + ``-1`` on failure. + + The subsequence to search for may be any :term:`bytes-like object` or an + integer in the range 0 to 255. + + .. versionchanged:: 3.3 + Also accept an integer in the range 0 to 255 as the subsequence. + + +.. method:: bytes.rindex(sub[, start[, end]]) + bytearray.rindex(sub[, start[, end]]) + + Like :meth:`~bytes.rfind` but raises :exc:`ValueError` when the + subsequence *sub* is not found. + + The subsequence to search for may be any :term:`bytes-like object` or an + integer in the range 0 to 255. + + .. versionchanged:: 3.3 + Also accept an integer in the range 0 to 255 as the subsequence. + + +.. method:: bytes.rpartition(sep) + bytearray.rpartition(sep) + + Split the sequence at the last occurrence of *sep*, and return a 3-tuple + containing the part before the separator, the separator, and the part + after the separator. If the separator is not found, return a 3-tuple + containing a copy of the original sequence, followed by two empty bytes or + bytearray objects. + + The separator to search for may be any :term:`bytes-like object`. + + +.. method:: bytes.startswith(prefix[, start[, end]]) + bytearray.startswith(prefix[, start[, end]]) + + Return ``True`` if the binary data starts with the specified *prefix*, + otherwise return ``False``. *prefix* can also be a tuple of prefixes to + look for. With optional *start*, test beginning at that position. With + optional *end*, stop comparing at that position. + + The prefix(es) to search for may be any :term:`bytes-like object`. -The maketrans and translate methods differ in semantics from the versions -available on strings: .. method:: bytes.translate(table[, delete]) bytearray.translate(table[, delete]) Return a copy of the bytes or bytearray object where all bytes occurring in - the optional argument *delete* are removed, and the remaining bytes have been - mapped through the given translation table, which must be a bytes object of - length 256. + the optional argument *delete* are removed, and the remaining bytes have + been mapped through the given translation table, which must be a bytes + object of length 256. - You can use the :func:`bytes.maketrans` method to create a translation table. + You can use the :func:`bytes.maketrans` method to create a translation + table. Set the *table* argument to ``None`` for translations that only delete characters:: @@ -2355,17 +2646,696 @@ available on strings: b'rd ths shrt txt' -.. staticmethod:: bytes.maketrans(from, to) - bytearray.maketrans(from, to) +The following methods on bytes and bytearray objects have default behaviours +that assume the use of ASCII compatible binary formats, but can still be used +with arbitrary binary data by passing appropriate arguments. Note that all of +the bytearray methods in this section do *not* operate in place, and instead +produce new objects. - This static method returns a translation table usable for - :meth:`bytes.translate` that will map each character in *from* into the - character at the same position in *to*; *from* and *to* must be bytes objects - and have the same length. +.. method:: bytes.center(width[, fillbyte]) + bytearray.center(width[, fillbyte]) - .. versionadded:: 3.1 + Return a copy of the object centered in a sequence of length *width*. + Padding is done using the specified *fillbyte* (default is an ASCII + space). For :class:`bytes` objects, the original sequence is returned if + *width* is less than or equal to ``len(s)``. + + .. note:: + + The bytearray version of this method does *not* operate in place - + it always produces a new object, even if no changes were made. + + +.. method:: bytes.ljust(width[, fillbyte]) + bytearray.ljust(width[, fillbyte]) + + Return a copy of the object left justified in a sequence of length *width*. + Padding is done using the specified *fillbyte* (default is an ASCII + space). For :class:`bytes` objects, the original sequence is returned if + *width* is less than or equal to ``len(s)``. + + .. note:: + + The bytearray version of this method does *not* operate in place - + it always produces a new object, even if no changes were made. + + +.. method:: bytes.lstrip([chars]) + bytearray.lstrip([chars]) + + Return a copy of the sequence with specified leading bytes removed. The + *chars* argument is a binary sequence specifying the set of byte values to + be removed - the name refers to the fact this method is usually used with + ASCII characters. If omitted or ``None``, the *chars* argument defaults + to removing ASCII whitespace. The *chars* argument is not a prefix; + rather, all combinations of its values are stripped:: + + >>> b' spacious '.lstrip() + b'spacious ' + >>> b'www.example.com'.lstrip(b'cmowz.') + b'example.com' + + The binary sequence of byte values to remove may be any + :term:`bytes-like object`. + + .. note:: + + The bytearray version of this method does *not* operate in place - + it always produces a new object, even if no changes were made. + + +.. method:: bytes.rjust(width[, fillbyte]) + bytearray.rjust(width[, fillbyte]) + + Return a copy of the object right justified in a sequence of length *width*. + Padding is done using the specified *fillbyte* (default is an ASCII + space). For :class:`bytes` objects, the original sequence is returned if + *width* is less than or equal to ``len(s)``. + + .. note:: + + The bytearray version of this method does *not* operate in place - + it always produces a new object, even if no changes were made. + + +.. method:: bytes.rsplit(sep=None, maxsplit=-1) + bytearray.rsplit(sep=None, maxsplit=-1) + + Split the binary sequence into subsequences of the same type, using *sep* + as the delimiter string. If *maxsplit* is given, at most *maxsplit* splits + are done, the *rightmost* ones. If *sep* is not specified or ``None``, + any subsequence consisting solely of ASCII whitespace is a separator. + Except for splitting from the right, :meth:`rsplit` behaves like + :meth:`split` which is described in detail below. + + +.. method:: bytes.rstrip([chars]) + bytearray.rstrip([chars]) + + Return a copy of the sequence with specified trailing bytes removed. The + *chars* argument is a binary sequence specifying the set of byte values to + be removed - the name refers to the fact this method is usually used with + ASCII characters. If omitted or ``None``, the *chars* argument defaults to + removing ASCII whitespace. The *chars* argument is not a suffix; rather, + all combinations of its values are stripped:: + + >>> b' spacious '.rstrip() + b' spacious' + >>> b'mississippi'.rstrip(b'ipz') + b'mississ' + + The binary sequence of byte values to remove may be any + :term:`bytes-like object`. + + .. note:: + + The bytearray version of this method does *not* operate in place - + it always produces a new object, even if no changes were made. + + +.. method:: bytes.split(sep=None, maxsplit=-1) + bytearray.split(sep=None, maxsplit=-1) + + Split the binary sequence into subsequences of the same type, using *sep* + as the delimiter string. If *maxsplit* is given and non-negative, at most + *maxsplit* splits are done (thus, the list will have at most ``maxsplit+1`` + elements). If *maxsplit* is not specified or is ``-1``, then there is no + limit on the number of splits (all possible splits are made). + + If *sep* is given, consecutive delimiters are not grouped together and are + deemed to delimit empty subsequences (for example, ``b'1,,2'.split(b',')`` + returns ``[b'1', b'', b'2']``). The *sep* argument may consist of a + multibyte sequence (for example, ``b'1<>2<>3'.split(b'<>')`` returns + ``[b'1', b'2', b'3']``). Splitting an empty sequence with a specified + separator returns ``[b'']`` or ``[bytearray(b'')]`` depending on the type + of object being split. The *sep* argument may be any + :term:`bytes-like object`. + + For example:: + + >>> b'1,2,3'.split(b',') + [b'1', b'2', b'3'] + >>> b'1,2,3'.split(b',', maxsplit=1) + [b'1', b'2,3'] + >>> b'1,2,,3,'.split(b',') + [b'1', b'2', b'', b'3', b''] + + If *sep* is not specified or is ``None``, a different splitting algorithm + is applied: runs of consecutive ASCII whitespace are regarded as a single + separator, and the result will contain no empty strings at the start or + end if the sequence has leading or trailing whitespace. Consequently, + splitting an empty sequence or a sequence consisting solely of ASCII + whitespace without a specified separator returns ``[]``. + + For example:: + + + >>> b'1 2 3'.split() + [b'1', b'2', b'3'] + >>> b'1 2 3'.split(maxsplit=1) + [b'1', b'2 3'] + >>> b' 1 2 3 '.split() + [b'1', b'2', b'3'] + + +.. method:: bytes.strip([chars]) + bytearray.strip([chars]) + + Return a copy of the sequence with specified leading and trailing bytes + removed. The *chars* argument is a binary sequence specifying the set of + byte values to be removed - the name refers to the fact this method is + usually used with ASCII characters. If omitted or ``None``, the *chars* + argument defaults to removing ASCII whitespace. The *chars* argument is + not a prefix or suffix; rather, all combinations of its values are + stripped:: + + >>> b' spacious '.strip() + b'spacious' + >>> b'www.example.com'.strip(b'cmowz.') + b'example' + + The binary sequence of byte values to remove may be any + :term:`bytes-like object`. + + .. note:: + + The bytearray version of this method does *not* operate in place - + it always produces a new object, even if no changes were made. + + +The following methods on bytes and bytearray objects assume the use of ASCII +compatible binary formats and should not be applied to arbitrary binary data. +Note that all of the bytearray methods in this section do *not* operate in +place, and instead produce new objects. + +.. method:: bytes.capitalize() + bytearray.capitalize() + + Return a copy of the sequence with each byte interpreted as an ASCII + character, and the first byte capitalized and the rest lowercased. + Non-ASCII byte values are passed through unchanged. + + .. note:: + + The bytearray version of this method does *not* operate in place - it + always produces a new object, even if no changes were made. + + +.. method:: bytes.expandtabs(tabsize=8) + bytearray.expandtabs(tabsize=8) + + Return a copy of the sequence where all ASCII tab characters are replaced + by one or more ASCII spaces, depending on the current column and the given + tab size. Tab positions occur every *tabsize* bytes (default is 8, + giving tab positions at columns 0, 8, 16 and so on). To expand the + sequence, the current column is set to zero and the sequence is examined + byte by byte. If the byte is an ASCII tab character (``b'\t'``), one or + more space characters are inserted in the result until the current column + is equal to the next tab position. (The tab character itself is not + copied.) If the current byte is an ASCII newline (``b'\n'``) or + carriage return (``b'\r'``), it is copied and the current column is reset + to zero. Any other byte value is copied unchanged and the current column + is incremented by one regardless of how the byte value is represented when + printed:: + + >>> b'01\t012\t0123\t01234'.expandtabs() + b'01 012 0123 01234' + >>> b'01\t012\t0123\t01234'.expandtabs(4) + b'01 012 0123 01234' + + .. note:: + + The bytearray version of this method does *not* operate in place - it + always produces a new object, even if no changes were made. + + +.. method:: bytes.isalnum() + bytearray.isalnum() + + Return true if all bytes in the sequence are alphabetical ASCII characters + or ASCII decimal digits and the sequence is not empty, false otherwise. + Alphabetic ASCII characters are those byte values in the sequence + ``b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'``. ASCII decimal + digits are those byte values in the sequence ``b'0123456789'``. + + For example:: + + >>> b'ABCabc1'.isalnum() + True + >>> b'ABC abc1'.isalnum() + False + + +.. method:: bytes.isalpha() + bytearray.isalpha() + + Return true if all bytes in the sequence are alphabetic ASCII characters + and the sequence is not empty, false otherwise. Alphabetic ASCII + characters are those byte values in the sequence + ``b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'``. + + For example:: + + >>> b'ABCabc'.isalpha() + True + >>> b'ABCabc1'.isalpha() + False + + +.. method:: bytes.isdigit() + bytearray.isdigit() + + Return true if all bytes in the sequence are ASCII decimal digits + and the sequence is not empty, false otherwise. ASCII decimal digits are + those byte values in the sequence ``b'0123456789'``. + + For example:: + + >>> b'1234'.isdigit() + True + >>> b'1.23'.isdigit() + False + + +.. method:: bytes.islower() + bytearray.islower() + + Return true if there is at least one lowercase ASCII character + in the sequence and no uppercase ASCII characters, false otherwise. + + For example:: + + >>> b'hello world'.islower() + True + >>> b'Hello world'.islower() + False + + Lowercase ASCII characters are those byte values in the sequence + ``b'abcdefghijklmnopqrstuvwxyz'``. Uppercase ASCII characters + are those byte values in the sequence ``b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'``. + + +.. method:: bytes.isspace() + bytearray.isspace() + + Return true if all bytes in the sequence are ASCII whitespace and the + sequence is not empty, false otherwise. ASCII whitespace characters are + those byte values in the sequence b' \t\n\r\x0b\f' (space, tab, newline, + carriage return, vertical tab, form feed). + + +.. method:: bytes.istitle() + bytearray.istitle() + + Return true if the sequence is ASCII titlecase and the sequence is not + empty, false otherwise. See :meth:`bytes.title` for more details on the + definition of "titlecase". + + For example:: + + >>> b'Hello World'.istitle() + True + >>> b'Hello world'.istitle() + False + + +.. method:: bytes.isupper() + bytearray.isupper() + + Return true if there is at least one uppercase alphabetic ASCII character + in the sequence and no lowercase ASCII characters, false otherwise. + + For example:: + + >>> b'HELLO WORLD'.isupper() + True + >>> b'Hello world'.isupper() + False + + Lowercase ASCII characters are those byte values in the sequence + ``b'abcdefghijklmnopqrstuvwxyz'``. Uppercase ASCII characters + are those byte values in the sequence ``b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'``. +.. method:: bytes.lower() + bytearray.lower() + + Return a copy of the sequence with all the uppercase ASCII characters + converted to their corresponding lowercase counterpart. + + For example:: + + >>> b'Hello World'.lower() + b'hello world' + + Lowercase ASCII characters are those byte values in the sequence + ``b'abcdefghijklmnopqrstuvwxyz'``. Uppercase ASCII characters + are those byte values in the sequence ``b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'``. + + .. note:: + + The bytearray version of this method does *not* operate in place - it + always produces a new object, even if no changes were made. + + +.. index:: + single: universal newlines; bytes.splitlines method + single: universal newlines; bytearray.splitlines method + +.. method:: bytes.splitlines(keepends=False) + bytearray.splitlines(keepends=False) + + Return a list of the lines in the binary sequence, breaking at ASCII + line boundaries. This method uses the :term:`universal newlines` approach + to splitting lines. Line breaks are not included in the resulting list + unless *keepends* is given and true. + + For example:: + + >>> b'ab c\n\nde fg\rkl\r\n'.splitlines() + [b'ab c', b'', b'de fg', b'kl'] + >>> b'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True) + [b'ab c\n', b'\n', b'de fg\r', b'kl\r\n'] + + Unlike :meth:`~bytes.split` when a delimiter string *sep* is given, this + method returns an empty list for the empty string, and a terminal line + break does not result in an extra line:: + + >>> b"".split(b'\n'), b"Two lines\n".split(b'\n') + ([b''], [b'Two lines', b'']) + >>> b"".splitlines(), b"One line\n".splitlines() + ([], [b'One line']) + + +.. method:: bytes.swapcase() + bytearray.swapcase() + + Return a copy of the sequence with all the lowercase ASCII characters + converted to their corresponding uppercase counterpart and vice-versa. + + For example:: + + >>> b'Hello World'.swapcase() + b'hELLO wORLD' + + Lowercase ASCII characters are those byte values in the sequence + ``b'abcdefghijklmnopqrstuvwxyz'``. Uppercase ASCII characters + are those byte values in the sequence ``b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'``. + + Unlike :func:`str.swapcase()`, it is always the case that + ``bin.swapcase().swapcase() == bin`` for the binary versions. Case + conversions are symmetrical in ASCII, even though that is not generally + true for arbitrary Unicode code points. + + .. note:: + + The bytearray version of this method does *not* operate in place - it + always produces a new object, even if no changes were made. + + +.. method:: bytes.title() + bytearray.title() + + Return a titlecased version of the binary sequence where words start with + an uppercase ASCII character and the remaining characters are lowercase. + Uncased byte values are left unmodified. + + For example:: + + >>> b'Hello world'.title() + b'Hello World' + + Lowercase ASCII characters are those byte values in the sequence + ``b'abcdefghijklmnopqrstuvwxyz'``. Uppercase ASCII characters + are those byte values in the sequence ``b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'``. + All other byte values are uncased. + + The algorithm uses a simple language-independent definition of a word as + groups of consecutive letters. The definition works in many contexts but + it means that apostrophes in contractions and possessives form word + boundaries, which may not be the desired result:: + + >>> b"they're bill's friends from the UK".title() + b"They'Re Bill'S Friends From The Uk" + + A workaround for apostrophes can be constructed using regular expressions:: + + >>> import re + >>> def titlecase(s): + ... return re.sub(rb"[A-Za-z]+('[A-Za-z]+)?", + ... lambda mo: mo.group(0)[0:1].upper() + + ... mo.group(0)[1:].lower(), + ... s) + ... + >>> titlecase(b"they're bill's friends.") + b"They're Bill's Friends." + + .. note:: + + The bytearray version of this method does *not* operate in place - it + always produces a new object, even if no changes were made. + + +.. method:: bytes.upper() + bytearray.upper() + + Return a copy of the sequence with all the lowercase ASCII characters + converted to their corresponding uppercase counterpart. + + For example:: + + >>> b'Hello World'.upper() + b'HELLO WORLD' + + Lowercase ASCII characters are those byte values in the sequence + ``b'abcdefghijklmnopqrstuvwxyz'``. Uppercase ASCII characters + are those byte values in the sequence ``b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'``. + + .. note:: + + The bytearray version of this method does *not* operate in place - it + always produces a new object, even if no changes were made. + + +.. method:: bytes.zfill(width) + bytearray.zfill(width) + + Return a copy of the sequence left filled with ASCII ``b'0'`` digits to + make a sequence of length *width*. A leading sign prefix (``b'+'``/ + ``b'-'`` is handled by inserting the padding *after* the sign character + rather than before. For :class:`bytes` objects, the original sequence is + returned if *width* is less than or equal to ``len(seq)``. + + For example:: + + >>> b"42".zfill(5) + b'00042' + >>> b"-42".zfill(5) + b'-0042' + + .. note:: + + The bytearray version of this method does *not* operate in place - it + always produces a new object, even if no changes were made. + + +.. _bytes-formatting: + +``printf``-style Bytes Formatting +---------------------------------- + +.. index:: + single: formatting, bytes (%) + single: formatting, bytearray (%) + single: interpolation, bytes (%) + single: interpolation, bytearray (%) + single: bytes; formatting + single: bytearray; formatting + single: bytes; interpolation + single: bytearray; interpolation + single: printf-style formatting + single: sprintf-style formatting + single: % formatting + single: % interpolation + +.. note:: + + The formatting operations described here exhibit a variety of quirks that + lead to a number of common errors (such as failing to display tuples and + dictionaries correctly). If the value being printed may be a tuple or + dictionary, wrap it in a tuple. + +Bytes objects (``bytes``/``bytearray``) have one unique built-in operation: +the ``%`` operator (modulo). +This is also known as the bytes *formatting* or *interpolation* operator. +Given ``format % values`` (where *format* is a bytes object), ``%`` conversion +specifications in *format* are replaced with zero or more elements of *values*. +The effect is similar to using the :c:func:`sprintf` in the C language. + +If *format* requires a single argument, *values* may be a single non-tuple +object. [5]_ Otherwise, *values* must be a tuple with exactly the number of +items specified by the format bytes object, or a single mapping object (for +example, a dictionary). + +A conversion specifier contains two or more characters and has the following +components, which must occur in this order: + +#. The ``'%'`` character, which marks the start of the specifier. + +#. Mapping key (optional), consisting of a parenthesised sequence of characters + (for example, ``(somename)``). + +#. Conversion flags (optional), which affect the result of some conversion + types. + +#. Minimum field width (optional). If specified as an ``'*'`` (asterisk), the + actual width is read from the next element of the tuple in *values*, and the + object to convert comes after the minimum field width and optional precision. + +#. Precision (optional), given as a ``'.'`` (dot) followed by the precision. If + specified as ``'*'`` (an asterisk), the actual precision is read from the next + element of the tuple in *values*, and the value to convert comes after the + precision. + +#. Length modifier (optional). + +#. Conversion type. + +When the right argument is a dictionary (or other mapping type), then the +formats in the bytes object *must* include a parenthesised mapping key into that +dictionary inserted immediately after the ``'%'`` character. The mapping key +selects the value to be formatted from the mapping. For example: + + >>> print(b'%(language)s has %(number)03d quote types.' % + ... {b'language': b"Python", b"number": 2}) + b'Python has 002 quote types.' + +In this case no ``*`` specifiers may occur in a format (since they require a +sequential parameter list). + +The conversion flag characters are: + ++---------+---------------------------------------------------------------------+ +| Flag | Meaning | ++=========+=====================================================================+ +| ``'#'`` | The value conversion will use the "alternate form" (where defined | +| | below). | ++---------+---------------------------------------------------------------------+ +| ``'0'`` | The conversion will be zero padded for numeric values. | ++---------+---------------------------------------------------------------------+ +| ``'-'`` | The converted value is left adjusted (overrides the ``'0'`` | +| | conversion if both are given). | ++---------+---------------------------------------------------------------------+ +| ``' '`` | (a space) A blank should be left before a positive number (or empty | +| | string) produced by a signed conversion. | ++---------+---------------------------------------------------------------------+ +| ``'+'`` | A sign character (``'+'`` or ``'-'``) will precede the conversion | +| | (overrides a "space" flag). | ++---------+---------------------------------------------------------------------+ + +A length modifier (``h``, ``l``, or ``L``) may be present, but is ignored as it +is not necessary for Python -- so e.g. ``%ld`` is identical to ``%d``. + +The conversion types are: + ++------------+-----------------------------------------------------+-------+ +| Conversion | Meaning | Notes | ++============+=====================================================+=======+ +| ``'d'`` | Signed integer decimal. | | ++------------+-----------------------------------------------------+-------+ +| ``'i'`` | Signed integer decimal. | | ++------------+-----------------------------------------------------+-------+ +| ``'o'`` | Signed octal value. | \(1) | ++------------+-----------------------------------------------------+-------+ +| ``'u'`` | Obsolete type -- it is identical to ``'d'``. | \(8) | ++------------+-----------------------------------------------------+-------+ +| ``'x'`` | Signed hexadecimal (lowercase). | \(2) | ++------------+-----------------------------------------------------+-------+ +| ``'X'`` | Signed hexadecimal (uppercase). | \(2) | ++------------+-----------------------------------------------------+-------+ +| ``'e'`` | Floating point exponential format (lowercase). | \(3) | ++------------+-----------------------------------------------------+-------+ +| ``'E'`` | Floating point exponential format (uppercase). | \(3) | ++------------+-----------------------------------------------------+-------+ +| ``'f'`` | Floating point decimal format. | \(3) | ++------------+-----------------------------------------------------+-------+ +| ``'F'`` | Floating point decimal format. | \(3) | ++------------+-----------------------------------------------------+-------+ +| ``'g'`` | Floating point format. Uses lowercase exponential | \(4) | +| | format if exponent is less than -4 or not less than | | +| | precision, decimal format otherwise. | | ++------------+-----------------------------------------------------+-------+ +| ``'G'`` | Floating point format. Uses uppercase exponential | \(4) | +| | format if exponent is less than -4 or not less than | | +| | precision, decimal format otherwise. | | ++------------+-----------------------------------------------------+-------+ +| ``'c'`` | Single byte (accepts integer or single | | +| | byte objects). | | ++------------+-----------------------------------------------------+-------+ +| ``'b'`` | Bytes (any object that follows the | \(5) | +| | :ref:`buffer protocol <bufferobjects>` or has | | +| | :meth:`__bytes__`). | | ++------------+-----------------------------------------------------+-------+ +| ``'s'`` | ``'s'`` is an alias for ``'b'`` and should only | \(6) | +| | be used for Python2/3 code bases. | | ++------------+-----------------------------------------------------+-------+ +| ``'a'`` | Bytes (converts any Python object using | \(5) | +| | ``repr(obj).encode('ascii','backslashreplace)``). | | ++------------+-----------------------------------------------------+-------+ +| ``'r'`` | ``'r'`` is an alias for ``'a'`` and should only | \(7) | +| | be used for Python2/3 code bases. | | ++------------+-----------------------------------------------------+-------+ +| ``'%'`` | No argument is converted, results in a ``'%'`` | | +| | character in the result. | | ++------------+-----------------------------------------------------+-------+ + +Notes: + +(1) + The alternate form causes a leading zero (``'0'``) to be inserted between + left-hand padding and the formatting of the number if the leading character + of the result is not already a zero. + +(2) + The alternate form causes a leading ``'0x'`` or ``'0X'`` (depending on whether + the ``'x'`` or ``'X'`` format was used) to be inserted between left-hand padding + and the formatting of the number if the leading character of the result is not + already a zero. + +(3) + The alternate form causes the result to always contain a decimal point, even if + no digits follow it. + + The precision determines the number of digits after the decimal point and + defaults to 6. + +(4) + The alternate form causes the result to always contain a decimal point, and + trailing zeroes are not removed as they would otherwise be. + + The precision determines the number of significant digits before and after the + decimal point and defaults to 6. + +(5) + If precision is ``N``, the output is truncated to ``N`` characters. + +(6) + ``b'%s'`` is deprecated, but will not be removed during the 3.x series. + +(7) + ``b'%r'`` is deprecated, but will not be removed during the 3.x series. + +(8) + See :pep:`237`. + +.. note:: + + The bytearray version of this method does *not* operate in place - it + always produces a new object, even if no changes were made. + +.. seealso:: :pep:`461`. +.. versionadded:: 3.5 + .. _typememoryview: Memory Views @@ -2394,10 +3364,8 @@ copying. the view. The :class:`~memoryview.itemsize` attribute will give you the number of bytes in a single element. - A :class:`memoryview` supports slicing to expose its data. If - :class:`~memoryview.format` is one of the native format specifiers - from the :mod:`struct` module, indexing will return a single element - with the correct type. Full slicing will result in a subview:: + A :class:`memoryview` supports slicing and indexing to expose its data. + One-dimensional slicing will result in a subview:: >>> v = memoryview(b'abcefg') >>> v[1] @@ -2409,25 +3377,29 @@ copying. >>> bytes(v[1:4]) b'bce' - Other native formats:: + If :class:`~memoryview.format` is one of the native format specifiers + from the :mod:`struct` module, indexing with an integer or a tuple of + integers is also supported and returns a single *element* with + the correct type. One-dimensional memoryviews can be indexed + with an integer or a one-integer tuple. Multi-dimensional memoryviews + can be indexed with tuples of exactly *ndim* integers where *ndim* is + the number of dimensions. Zero-dimensional memoryviews can be indexed + with the empty tuple. + + Here is an example with a non-byte format:: >>> import array >>> a = array.array('l', [-11111111, 22222222, -33333333, 44444444]) - >>> a[0] + >>> m = memoryview(a) + >>> m[0] -11111111 - >>> a[-1] + >>> m[-1] 44444444 - >>> a[2:3].tolist() - [-33333333] - >>> a[::2].tolist() + >>> m[::2].tolist() [-11111111, -33333333] - >>> a[::-1].tolist() - [44444444, -33333333, 22222222, -11111111] - .. versionadded:: 3.3 - - If the underlying object is writable, the memoryview supports slice - assignment. Resizing is not allowed:: + If the underlying object is writable, the memoryview supports + one-dimensional slice assignment. Resizing is not allowed:: >>> data = bytearray(b'abcefg') >>> v = memoryview(data) @@ -2460,12 +3432,16 @@ copying. True .. versionchanged:: 3.3 + One-dimensional memoryviews can now be sliced. One-dimensional memoryviews with formats 'B', 'b' or 'c' are now hashable. .. versionchanged:: 3.4 memoryview is now registered automatically with :class:`collections.abc.Sequence` + .. versionchanged:: 3.5 + memoryviews can now be indexed with tuple of integers. + :class:`memoryview` has several methods: .. method:: __eq__(exporter) @@ -2532,6 +3508,17 @@ copying. supports all format strings, including those that are not in :mod:`struct` module syntax. + .. method:: hex() + + Return a string object containing two hexadecimal digits for each + byte in the buffer. :: + + >>> m = memoryview(b"abc") + >>> m.hex() + '616263' + + .. versionadded:: 3.5 + .. method:: tolist() Return the data in the buffer as a list of elements. :: @@ -2587,10 +3574,10 @@ copying. Cast a memoryview to a new format or shape. *shape* defaults to ``[byte_length//new_itemsize]``, which means that the result view will be one-dimensional. The return value is a new memoryview, but - the buffer itself is not copied. Supported casts are 1D -> C-contiguous + the buffer itself is not copied. Supported casts are 1D -> C-:term:`contiguous` and C-contiguous -> 1D. - Both formats are restricted to single element native formats in + The destination format is restricted to a single element native format in :mod:`struct` syntax. One of the formats must be a byte format ('B', 'b' or 'c'). The byte length of the result must be the same as the original length. @@ -2671,6 +3658,9 @@ copying. .. versionadded:: 3.3 + .. versionchanged:: 3.5 + The source format is no longer restricted when casting to a byte view. + There are also several readonly attributes available: .. attribute:: obj @@ -2775,19 +3765,19 @@ copying. .. attribute:: c_contiguous - A bool indicating whether the memory is C-contiguous. + A bool indicating whether the memory is C-:term:`contiguous`. .. versionadded:: 3.3 .. attribute:: f_contiguous - A bool indicating whether the memory is Fortran contiguous. + A bool indicating whether the memory is Fortran :term:`contiguous`. .. versionadded:: 3.3 .. attribute:: contiguous - A bool indicating whether the memory is contiguous. + A bool indicating whether the memory is :term:`contiguous`. .. versionadded:: 3.3 @@ -3031,8 +4021,8 @@ pairs within braces, for example: ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098: If no positional argument is given, an empty dictionary is created. If a positional argument is given and it is a mapping object, a dictionary is created with the same key-value pairs as the mapping object. Otherwise, - the positional argument must be an :term:`iterator` object. Each item in - the iterable must itself be an iterator with exactly two objects. The + the positional argument must be an :term:`iterable` object. Each item in + the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value. If a key occurs more than once, the last value for that key becomes the corresponding value in the new @@ -3070,11 +4060,13 @@ pairs within braces, for example: ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098: Return the item of *d* with key *key*. Raises a :exc:`KeyError` if *key* is not in the map. - If a subclass of dict defines a method :meth:`__missing__`, if the key *key* + .. index:: __missing__() + + If a subclass of dict defines a method :meth:`__missing__` and *key* is not present, the ``d[key]`` operation calls that method with the key *key* as argument. The ``d[key]`` operation then returns or raises whatever is - returned or raised by the ``__missing__(key)`` call if the key is not - present. No other operations or methods invoke :meth:`__missing__`. If + returned or raised by the ``__missing__(key)`` call. + No other operations or methods invoke :meth:`__missing__`. If :meth:`__missing__` is not defined, :exc:`KeyError` is raised. :meth:`__missing__` must be a method; it cannot be an instance variable:: @@ -3088,8 +4080,9 @@ pairs within braces, for example: ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098: >>> c['red'] 1 - See :class:`collections.Counter` for a complete implementation including - other methods helpful for accumulating and managing tallies. + The example above shows part of the implementation of + :class:`collections.Counter`. A different ``__missing__`` method is used + by :class:`collections.defaultdict`. .. describe:: d[key] = value @@ -3179,6 +4172,10 @@ pairs within braces, for example: ``{'jack': 4098, 'sjoerd': 4127}`` or ``{4098: Return a new view of the dictionary's values. See the :ref:`documentation of view objects <dict-views>`. + Dictionaries compare equal if and only if they have the same ``(key, + value)`` pairs. Order comparisons ('<', '<=', '>=', '>') raise + :exc:`TypeError`. + .. seealso:: :class:`types.MappingProxyType` can be used to create a read-only view of a :class:`dict`. @@ -3314,8 +4311,8 @@ before the statement body is executed and exited when the statement ends: The exception passed in should never be reraised explicitly - instead, this method should return a false value to indicate that the method completed successfully and does not want to suppress the raised exception. This allows - context management code (such as ``contextlib.nested``) to easily detect whether - or not an :meth:`__exit__` method has actually failed. + context management code to easily detect whether or not an :meth:`__exit__` + method has actually failed. Python defines several context managers to support easy thread synchronisation, prompt closure of files or other objects, and simpler manipulation of the active diff --git a/Doc/library/string.rst b/Doc/library/string.rst index e5bab684dfbc..2bd8dfdc960a 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -95,6 +95,10 @@ implementation as the built-in :meth:`format` method. an arbitrary set of positional and keyword arguments. :meth:`format` is just a wrapper that calls :meth:`vformat`. + .. deprecated:: 3.5 + Passing a format string as keyword argument *format_string* has been + deprecated. + .. method:: vformat(format_string, args, kwargs) This function does the actual work of formatting. It is exposed as a @@ -478,10 +482,12 @@ The available presentation types for floating point and decimal values are: | ``'%'`` | Percentage. Multiplies the number by 100 and displays | | | in fixed (``'f'``) format, followed by a percent sign. | +---------+----------------------------------------------------------+ - | None | Similar to ``'g'``, except with at least one digit past | - | | the decimal point and a default precision of 12. This is | - | | intended to match :func:`str`, except you can add the | - | | other format modifiers. | + | None | Similar to ``'g'``, except that fixed-point notation, | + | | when used, has at least one digit past the decimal point.| + | | The default precision is as high as needed to represent | + | | the particular value. The overall effect is to match the | + | | output of :func:`str` as altered by the other format | + | | modifiers. | +---------+----------------------------------------------------------+ @@ -638,12 +644,14 @@ Instead of the normal ``%``\ -based substitutions, Templates support ``$``\ * ``$$`` is an escape; it is replaced with a single ``$``. * ``$identifier`` names a substitution placeholder matching a mapping key of - ``"identifier"``. By default, ``"identifier"`` must spell a Python - identifier. The first non-identifier character after the ``$`` character - terminates this placeholder specification. - -* ``${identifier}`` is equivalent to ``$identifier``. It is required when valid - identifier characters follow the placeholder but are not part of the + ``"identifier"``. By default, ``"identifier"`` is restricted to any + case-insensitive ASCII alphanumeric string (including underscores) that + starts with an underscore or ASCII letter. The first non-identifier + character after the ``$`` character terminates this placeholder + specification. + +* ``${identifier}`` is equivalent to ``$identifier``. It is required when + valid identifier characters follow the placeholder but are not part of the placeholder, such as ``"${noun}ification"``. Any other appearance of ``$`` in the string will result in a :exc:`ValueError` diff --git a/Doc/library/stringprep.rst b/Doc/library/stringprep.rst index 47144a6adf79..fc890cb2326a 100644 --- a/Doc/library/stringprep.rst +++ b/Doc/library/stringprep.rst @@ -3,7 +3,6 @@ .. module:: stringprep :synopsis: String preparation, as per RFC 3453 - :deprecated: .. moduleauthor:: Martin v. Löwis <martin@v.loewis.de> .. sectionauthor:: Martin v. Löwis <martin@v.loewis.de> diff --git a/Doc/library/struct.rst b/Doc/library/struct.rst index ec2e1beb03cd..12d4fbcd52bc 100644 --- a/Doc/library/struct.rst +++ b/Doc/library/struct.rst @@ -24,6 +24,14 @@ structs and the intended conversion to/from Python values. or omit implicit pad bytes, use ``standard`` size and alignment instead of ``native`` size and alignment: see :ref:`struct-alignment` for details. +Several :mod:`struct` functions (and methods of :class:`Struct`) take a *buffer* +argument. This refers to objects that implement the :ref:`bufferobjects` and +provide either a readable or read-writable buffer. The most common types used +for that purpose are :class:`bytes` and :class:`bytearray`, but many other types +that can be viewed as an array of bytes implement the buffer protocol, so that +they can be read/filled without additional copying from a :class:`bytes` object. + + Functions and Exceptions ------------------------ @@ -47,7 +55,7 @@ The module defines the following exception and functions: Pack the values *v1*, *v2*, ... according to the format string *fmt* and write the packed bytes into the writable buffer *buffer* starting at - position *offset*. Note that *offset* is a required argument. + position *offset*. Note that *offset* is a required argument. .. function:: unpack(fmt, buffer) diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index 7fbe398442ee..adf99ec3623f 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -9,7 +9,7 @@ The :mod:`subprocess` module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes. This module intends to -replace several other, older modules and functions, such as:: +replace several older modules and functions:: os.system os.spawn* @@ -25,177 +25,99 @@ modules and functions can be found in the following sections. Using the :mod:`subprocess` Module ---------------------------------- -The recommended approach to invoking subprocesses is to use the following -convenience functions for all use cases they can handle. For more advanced -use cases, the underlying :class:`Popen` interface can be used directly. +The recommended approach to invoking subprocesses is to use the :func:`run` +function for all use cases it can handle. For more advanced use cases, the +underlying :class:`Popen` interface can be used directly. +The :func:`run` function was added in Python 3.5; if you need to retain +compatibility with older versions, see the :ref:`call-function-trio` section. -.. function:: call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None) + +.. function:: run(args, *, stdin=None, input=None, stdout=None, stderr=None,\ + shell=False, timeout=None, check=False) Run the command described by *args*. Wait for command to complete, then - return the :attr:`returncode` attribute. + return a :class:`CompletedProcess` instance. The arguments shown above are merely the most common ones, described below in :ref:`frequently-used-arguments` (hence the use of keyword-only notation in the abbreviated signature). The full function signature is largely the - same as that of the :class:`Popen` constructor - this function passes all - supplied arguments other than *timeout* directly through to that interface. + same as that of the :class:`Popen` constructor - apart from *timeout*, + *input* and *check*, all the arguments to this function are passed through to + that interface. - The *timeout* argument is passed to :meth:`Popen.wait`. If the timeout - expires, the child process will be killed and then waited for again. The + This does not capture stdout or stderr by default. To do so, pass + :data:`PIPE` for the *stdout* and/or *stderr* arguments. + + The *timeout* argument is passed to :meth:`Popen.communicate`. If the timeout + expires, the child process will be killed and waited for. The :exc:`TimeoutExpired` exception will be re-raised after the child process has terminated. - Examples:: - - >>> subprocess.call(["ls", "-l"]) - 0 - - >>> subprocess.call("exit 1", shell=True) - 1 - - .. warning:: - - Invoking the system shell with ``shell=True`` can be a security hazard - if combined with untrusted input. See the warning under - :ref:`frequently-used-arguments` for details. - - .. note:: - - Do not use ``stdout=PIPE`` or ``stderr=PIPE`` with this function. As - the pipes are not being read in the current process, the child - process may block if it generates enough output to a pipe to fill up - the OS pipe buffer. - - .. versionchanged:: 3.3 - *timeout* was added. - - -.. function:: check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None) - - Run command with arguments. Wait for command to complete. If the return - code was zero then return, otherwise raise :exc:`CalledProcessError`. The - :exc:`CalledProcessError` object will have the return code in the - :attr:`~CalledProcessError.returncode` attribute. - - The arguments shown above are merely the most common ones, described below - in :ref:`frequently-used-arguments` (hence the use of keyword-only notation - in the abbreviated signature). The full function signature is largely the - same as that of the :class:`Popen` constructor - this function passes all - supplied arguments other than *timeout* directly through to that interface. + The *input* argument is passed to :meth:`Popen.communicate` and thus to the + subprocess's stdin. If used it must be a byte sequence, or a string if + ``universal_newlines=True``. When used, the internal :class:`Popen` object + is automatically created with ``stdin=PIPE``, and the *stdin* argument may + not be used as well. - The *timeout* argument is passed to :meth:`Popen.wait`. If the timeout - expires, the child process will be killed and then waited for again. The - :exc:`TimeoutExpired` exception will be re-raised after the child process - has terminated. + If *check* is True, and the process exits with a non-zero exit code, a + :exc:`CalledProcessError` exception will be raised. Attributes of that + exception hold the arguments, the exit code, and stdout and stderr if they + were captured. Examples:: - >>> subprocess.check_call(["ls", "-l"]) - 0 + >>> subprocess.run(["ls", "-l"]) # doesn't capture output + CompletedProcess(args=['ls', '-l'], returncode=0) - >>> subprocess.check_call("exit 1", shell=True) + >>> subprocess.run("exit 1", shell=True, check=True) Traceback (most recent call last): - ... + ... subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1 - .. warning:: + >>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE) + CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0, + stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n') - Invoking the system shell with ``shell=True`` can be a security hazard - if combined with untrusted input. See the warning under - :ref:`frequently-used-arguments` for details. + .. versionadded:: 3.5 - .. note:: +.. class:: CompletedProcess - Do not use ``stdout=PIPE`` or ``stderr=PIPE`` with this function. As - the pipes are not being read in the current process, the child - process may block if it generates enough output to a pipe to fill up - the OS pipe buffer. + The return value from :func:`run`, representing a process that has finished. - .. versionchanged:: 3.3 - *timeout* was added. + .. attribute:: args + The arguments used to launch the process. This may be a list or a string. -.. function:: check_output(args, *, input=None, stdin=None, stderr=None, shell=False, universal_newlines=False, timeout=None) + .. attribute:: returncode - Run command with arguments and return its output. + Exit status of the child process. Typically, an exit status of 0 indicates + that it ran successfully. - If the return code was non-zero it raises a :exc:`CalledProcessError`. The - :exc:`CalledProcessError` object will have the return code in the - :attr:`~CalledProcessError.returncode` attribute and any output in the - :attr:`~CalledProcessError.output` attribute. + A negative value ``-N`` indicates that the child was terminated by signal + ``N`` (POSIX only). - The arguments shown above are merely the most common ones, described below - in :ref:`frequently-used-arguments` (hence the use of keyword-only notation - in the abbreviated signature). The full function signature is largely the - same as that of the :class:`Popen` constructor - this functions passes all - supplied arguments other than *input* and *timeout* directly through to - that interface. In addition, *stdout* is not permitted as an argument, as - it is used internally to collect the output from the subprocess. + .. attribute:: stdout - The *timeout* argument is passed to :meth:`Popen.wait`. If the timeout - expires, the child process will be killed and then waited for again. The - :exc:`TimeoutExpired` exception will be re-raised after the child process - has terminated. - - The *input* argument is passed to :meth:`Popen.communicate` and thus to the - subprocess's stdin. If used it must be a byte sequence, or a string if - ``universal_newlines=True``. When used, the internal :class:`Popen` object - is automatically created with ``stdin=PIPE``, and the *stdin* argument may - not be used as well. - - Examples:: - - >>> subprocess.check_output(["echo", "Hello World!"]) - b'Hello World!\n' - - >>> subprocess.check_output(["echo", "Hello World!"], universal_newlines=True) - 'Hello World!\n' - - >>> subprocess.check_output(["sed", "-e", "s/foo/bar/"], - ... input=b"when in the course of fooman events\n") - b'when in the course of barman events\n' - - >>> subprocess.check_output("exit 1", shell=True) - Traceback (most recent call last): - ... - subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1 - - By default, this function will return the data as encoded bytes. The actual - encoding of the output data may depend on the command being invoked, so the - decoding to text will often need to be handled at the application level. - - This behaviour may be overridden by setting *universal_newlines* to - ``True`` as described below in :ref:`frequently-used-arguments`. - - To also capture standard error in the result, use - ``stderr=subprocess.STDOUT``:: - - >>> subprocess.check_output( - ... "ls non_existent_file; exit 0", - ... stderr=subprocess.STDOUT, - ... shell=True) - 'ls: non_existent_file: No such file or directory\n' + Captured stdout from the child process. A bytes sequence, or a string if + :func:`run` was called with ``universal_newlines=True``. None if stdout + was not captured. - .. warning:: + If you ran the process with ``stderr=subprocess.STDOUT``, stdout and + stderr will be combined in this attribute, and :attr:`stderr` will be + None. - Invoking the system shell with ``shell=True`` can be a security hazard - if combined with untrusted input. See the warning under - :ref:`frequently-used-arguments` for details. + .. attribute:: stderr - .. note:: + Captured stderr from the child process. A bytes sequence, or a string if + :func:`run` was called with ``universal_newlines=True``. None if stderr + was not captured. - Do not use ``stderr=PIPE`` with this function. As the pipe is not being - read in the current process, the child process may block if it - generates enough output to the pipe to fill up the OS pipe buffer. + .. method:: check_returncode() - .. versionadded:: 3.1 - - .. versionchanged:: 3.3 - *timeout* was added. + If :attr:`returncode` is non-zero, raise a :exc:`CalledProcessError`. - .. versionchanged:: 3.4 - *input* was added. + .. versionadded:: 3.5 .. data:: DEVNULL @@ -210,7 +132,7 @@ use cases, the underlying :class:`Popen` interface can be used directly. Special value that can be used as the *stdin*, *stdout* or *stderr* argument to :class:`Popen` and indicates that a pipe to the standard stream should be - opened. + opened. Most useful with :meth:`Popen.communicate`. .. data:: STDOUT @@ -242,11 +164,22 @@ use cases, the underlying :class:`Popen` interface can be used directly. .. attribute:: output - Output of the child process if this exception is raised by + Output of the child process if it was captured by :func:`run` or :func:`check_output`. Otherwise, ``None``. + .. attribute:: stdout + + Alias for output, for symmetry with :attr:`stderr`. + + .. attribute:: stderr + + Stderr output of the child process if it was captured by :func:`run`. + Otherwise, ``None``. + .. versionadded:: 3.3 + .. versionchanged:: 3.5 + *stdout* and *stderr* attributes added .. exception:: CalledProcessError @@ -263,9 +196,20 @@ use cases, the underlying :class:`Popen` interface can be used directly. .. attribute:: output - Output of the child process if this exception is raised by + Output of the child process if it was captured by :func:`run` or :func:`check_output`. Otherwise, ``None``. + .. attribute:: stdout + + Alias for output, for symmetry with :attr:`stderr`. + + .. attribute:: stderr + + Stderr output of the child process if it was captured by :func:`run`. + Otherwise, ``None``. + + .. versionchanged:: 3.5 + *stdout* and *stderr* attributes added .. _frequently-used-arguments: @@ -336,28 +280,9 @@ default values. The arguments that are most commonly needed are: instead of ``locale.getpreferredencoding()``. See the :class:`io.TextIOWrapper` class for more information on this change. - .. warning:: - - Executing shell commands that incorporate unsanitized input from an - untrusted source makes a program vulnerable to `shell injection - <http://en.wikipedia.org/wiki/Shell_injection#Shell_injection>`_, - a serious security flaw which can result in arbitrary command execution. - For this reason, the use of ``shell=True`` is **strongly discouraged** - in cases where the command string is constructed from external input:: - - >>> from subprocess import call - >>> filename = input("What file would you like to display?\n") - What file would you like to display? - non_existent; rm -rf / # - >>> call("cat " + filename, shell=True) # Uh-oh. This will end badly... - - ``shell=False`` disables all shell based features, but does not suffer - from this vulnerability; see the Note in the :class:`Popen` constructor - documentation for helpful hints in getting ``shell=False`` to work. + .. note:: - When using ``shell=True``, :func:`shlex.quote` can be used to properly - escape whitespace and shell metacharacters in strings that are going to - be used to construct shell commands. + Read the `Security Considerations`_ section before using ``shell=True``. These options, along with all of the other options, are described in more detail in the :class:`Popen` constructor documentation. @@ -378,7 +303,7 @@ functions. startupinfo=None, creationflags=0, restore_signals=True, \ start_new_session=False, pass_fds=()) - Execute a child program in a new process. On Unix, the class uses + Execute a child program in a new process. On POSIX, the class uses :meth:`os.execvp`-like behavior to execute the child program. On Windows, the class uses the Windows ``CreateProcess()`` function. The arguments to :class:`Popen` are as follows. @@ -390,7 +315,7 @@ functions. arguments for additional differences from the default behavior. Unless otherwise stated, it is recommended to pass *args* as a sequence. - On Unix, if *args* is a string, the string is interpreted as the name or + On POSIX, if *args* is a string, the string is interpreted as the name or path of the program to execute. However, this can only be done if not passing arguments to the program. @@ -421,7 +346,7 @@ functions. the shell as the program to execute. If *shell* is *True*, it is recommended to pass *args* as a string rather than as a sequence. - On Unix with ``shell=True``, the shell defaults to :file:`/bin/sh`. If + On POSIX with ``shell=True``, the shell defaults to :file:`/bin/sh`. If *args* is a string, the string specifies the command to execute through the shell. This means that the string must be formatted exactly as it would be when typed at the shell prompt. This @@ -438,18 +363,22 @@ functions. into the shell (e.g. :command:`dir` or :command:`copy`). You do not need ``shell=True`` to run a batch file or console-based executable. - .. warning:: + .. note:: - Passing ``shell=True`` can be a security hazard if combined with - untrusted input. See the warning under :ref:`frequently-used-arguments` - for details. + Read the `Security Considerations`_ section before using ``shell=True``. - *bufsize* will be supplied as the corresponding argument to the :meth:`io.open` - function when creating the stdin/stdout/stderr pipe file objects: - :const:`0` means unbuffered (read and write are one system call and can return short), - :const:`1` means line buffered, any other positive value means use a buffer of - approximately that size. A negative bufsize (the default) means - the system default of io.DEFAULT_BUFFER_SIZE will be used. + *bufsize* will be supplied as the corresponding argument to the + :func:`open` function when creating the stdin/stdout/stderr pipe + file objects: + + - :const:`0` means unbuffered (read and write are one + system call and can return short) + - :const:`1` means line buffered + (only usable if ``universal_newlines=True`` i.e., in a text mode) + - any other positive value means use a buffer of approximately that + size + - negative bufsize (the default) means the system default of + io.DEFAULT_BUFFER_SIZE will be used. .. versionchanged:: 3.3.1 *bufsize* now defaults to -1 to enable buffering by default to match the @@ -463,9 +392,9 @@ functions. program to execute specified by *args*. However, the original *args* is still passed to the program. Most programs treat the program specified by *args* as the command name, which can then be different from the program - actually executed. On Unix, the *args* name + actually executed. On POSIX, the *args* name becomes the display name for the executable in utilities such as - :program:`ps`. If ``shell=True``, on Unix the *executable* argument + :program:`ps`. If ``shell=True``, on POSIX the *executable* argument specifies a replacement shell for the default :file:`/bin/sh`. *stdin*, *stdout* and *stderr* specify the executed program's standard input, @@ -481,7 +410,7 @@ functions. If *preexec_fn* is set to a callable object, this object will be called in the child process just before the child is executed. - (Unix only) + (POSIX only) .. warning:: @@ -499,8 +428,8 @@ functions. common use of *preexec_fn* to call os.setsid() in the child. If *close_fds* is true, all file descriptors except :const:`0`, :const:`1` and - :const:`2` will be closed before the child process is executed. (Unix only). - The default varies by platform: Always true on Unix. On Windows it is + :const:`2` will be closed before the child process is executed. (POSIX only). + The default varies by platform: Always true on POSIX. On Windows it is true when *stdin*/*stdout*/*stderr* are :const:`None`, false otherwise. On Windows, if *close_fds* is true then no handles will be inherited by the child process. Note that on Windows, you cannot set *close_fds* to true and @@ -512,7 +441,7 @@ functions. *pass_fds* is an optional sequence of file descriptors to keep open between the parent and child. Providing any *pass_fds* forces - *close_fds* to be :const:`True`. (Unix only) + *close_fds* to be :const:`True`. (POSIX only) .. versionadded:: 3.2 The *pass_fds* parameter was added. @@ -525,13 +454,13 @@ functions. If *restore_signals* is true (the default) all signals that Python has set to SIG_IGN are restored to SIG_DFL in the child process before the exec. Currently this includes the SIGPIPE, SIGXFZ and SIGXFSZ signals. - (Unix only) + (POSIX only) .. versionchanged:: 3.2 *restore_signals* was added. If *start_new_session* is true the setsid() system call will be made in the - child process prior to the execution of the subprocess. (Unix only) + child process prior to the execution of the subprocess. (POSIX only) .. versionchanged:: 3.2 *start_new_session* was added. @@ -598,14 +527,21 @@ Exceptions defined in this module all inherit from :exc:`SubprocessError`. The :exc:`SubprocessError` base class was added. -Security -^^^^^^^^ +Security Considerations +----------------------- + +Unlike some other popen functions, this implementation will never +implicitly call a system shell. This means that all characters, +including shell metacharacters, can safely be passed to child processes. +If the shell is invoked explicitly, via ``shell=True``, it is the application's +responsibility to ensure that all whitespace and metacharacters are +quoted appropriately to avoid +`shell injection <http://en.wikipedia.org/wiki/Shell_injection#Shell_injection>`_ +vulnerabilities. -Unlike some other popen functions, this implementation will never call a -system shell implicitly. This means that all characters, including shell -metacharacters, can safely be passed to child processes. Obviously, if the -shell is invoked explicitly, then it is the application's responsibility to -ensure that all whitespace and metacharacters are quoted appropriately. +When using ``shell=True``, the :func:`shlex.quote` function can be +used to properly escape whitespace and shell metacharacters in strings +that are going to be used to construct shell commands. Popen Objects @@ -629,16 +565,27 @@ Instances of the :class:`Popen` class have the following methods: :exc:`TimeoutExpired` exception. It is safe to catch this exception and retry the wait. - .. warning:: + .. note:: - This will deadlock when using ``stdout=PIPE`` and/or - ``stderr=PIPE`` and the child process generates enough output to - a pipe such that it blocks waiting for the OS pipe buffer to - accept more data. Use :meth:`communicate` to avoid that. + This will deadlock when using ``stdout=PIPE`` or ``stderr=PIPE`` + and the child process generates enough output to a pipe such that + it blocks waiting for the OS pipe buffer to accept more data. + Use :meth:`Popen.communicate` when using pipes to avoid that. + + .. note:: + + The function is implemented using a busy loop (non-blocking call and + short sleeps). Use the :mod:`asyncio` module for an asynchronous wait: + see :class:`asyncio.create_subprocess_exec`. .. versionchanged:: 3.3 *timeout* was added. + .. deprecated:: 3.4 + + Do not use the *endtime* parameter. It is was unintentionally + exposed in 3.3 but was left undocumented as it was intended to be + private for internal use. Use *timeout* instead. .. method:: Popen.communicate(input=None, timeout=None) @@ -648,7 +595,8 @@ Instances of the :class:`Popen` class have the following methods: ``None``, if no data should be sent to the child. The type of *input* must be bytes or, if *universal_newlines* was ``True``, a string. - :meth:`communicate` returns a tuple ``(stdoutdata, stderrdata)``. + :meth:`communicate` returns a tuple ``(stdout_data, stderr_data)``. + The data will be bytes or, if *universal_newlines* was ``True``, strings. Note that if you want to send data to the process's stdin, you need to create the Popen object with ``stdin=PIPE``. Similarly, to get anything other than @@ -705,31 +653,45 @@ Instances of the :class:`Popen` class have the following methods: The following attributes are also available: -.. warning:: +.. attribute:: Popen.args - Use :meth:`~Popen.communicate` rather than :attr:`.stdin.write <Popen.stdin>`, - :attr:`.stdout.read <Popen.stdout>` or :attr:`.stderr.read <Popen.stderr>` to avoid - deadlocks due to any of the other OS pipe buffers filling up and blocking the - child process. + The *args* argument as it was passed to :class:`Popen` -- a + sequence of program arguments or else a single string. + .. versionadded:: 3.3 .. attribute:: Popen.stdin - If the *stdin* argument was :data:`PIPE`, this attribute is a :term:`file - object` that provides input to the child process. Otherwise, it is ``None``. + If the *stdin* argument was :data:`PIPE`, this attribute is a writeable + stream object as returned by :func:`open`. If the *universal_newlines* + argument was ``True``, the stream is a text stream, otherwise it is a byte + stream. If the *stdin* argument was not :data:`PIPE`, this attribute is + ``None``. .. attribute:: Popen.stdout - If the *stdout* argument was :data:`PIPE`, this attribute is a :term:`file - object` that provides output from the child process. Otherwise, it is ``None``. + If the *stdout* argument was :data:`PIPE`, this attribute is a readable + stream object as returned by :func:`open`. Reading from the stream provides + output from the child process. If the *universal_newlines* argument was + ``True``, the stream is a text stream, otherwise it is a byte stream. If the + *stdout* argument was not :data:`PIPE`, this attribute is ``None``. .. attribute:: Popen.stderr - If the *stderr* argument was :data:`PIPE`, this attribute is a :term:`file - object` that provides error output from the child process. Otherwise, it is - ``None``. + If the *stderr* argument was :data:`PIPE`, this attribute is a readable + stream object as returned by :func:`open`. Reading from the stream provides + error output from the child process. If the *universal_newlines* argument was + ``True``, the stream is a text stream, otherwise it is a byte stream. If the + *stderr* argument was not :data:`PIPE`, this attribute is ``None``. + +.. warning:: + + Use :meth:`~Popen.communicate` rather than :attr:`.stdin.write <Popen.stdin>`, + :attr:`.stdout.read <Popen.stdout>` or :attr:`.stderr.read <Popen.stderr>` to avoid + deadlocks due to any of the other OS pipe buffers filling up and blocking the + child process. .. attribute:: Popen.pid @@ -747,7 +709,7 @@ The following attributes are also available: hasn't terminated yet. A negative value ``-N`` indicates that the child was terminated by signal - ``N`` (Unix only). + ``N`` (POSIX only). Windows Popen Helpers @@ -851,6 +813,112 @@ The :mod:`subprocess` module exposes the following constants. This flag is ignored if :data:`CREATE_NEW_CONSOLE` is specified. +.. _call-function-trio: + +Older high-level API +-------------------- + +Prior to Python 3.5, these three functions comprised the high level API to +subprocess. You can now use :func:`run` in many cases, but lots of existing code +calls these functions. + +.. function:: call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None) + + Run the command described by *args*. Wait for command to complete, then + return the :attr:`~Popen.returncode` attribute. + + This is equivalent to:: + + run(...).returncode + + (except that the *input* and *check* parameters are not supported) + + The arguments shown above are merely the most + common ones. The full function signature is largely the + same as that of the :class:`Popen` constructor - this function passes all + supplied arguments other than *timeout* directly through to that interface. + + .. note:: + + Do not use ``stdout=PIPE`` or ``stderr=PIPE`` with this + function. The child process will block if it generates enough + output to a pipe to fill up the OS pipe buffer as the pipes are + not being read from. + + .. versionchanged:: 3.3 + *timeout* was added. + +.. function:: check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None) + + Run command with arguments. Wait for command to complete. If the return + code was zero then return, otherwise raise :exc:`CalledProcessError`. The + :exc:`CalledProcessError` object will have the return code in the + :attr:`~CalledProcessError.returncode` attribute. + + This is equivalent to:: + + run(..., check=True) + + (except that the *input* parameter is not supported) + + The arguments shown above are merely the most + common ones. The full function signature is largely the + same as that of the :class:`Popen` constructor - this function passes all + supplied arguments other than *timeout* directly through to that interface. + + .. note:: + + Do not use ``stdout=PIPE`` or ``stderr=PIPE`` with this + function. The child process will block if it generates enough + output to a pipe to fill up the OS pipe buffer as the pipes are + not being read from. + + .. versionchanged:: 3.3 + *timeout* was added. + + +.. function:: check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False, timeout=None) + + Run command with arguments and return its output. + + If the return code was non-zero it raises a :exc:`CalledProcessError`. The + :exc:`CalledProcessError` object will have the return code in the + :attr:`~CalledProcessError.returncode` attribute and any output in the + :attr:`~CalledProcessError.output` attribute. + + This is equivalent to:: + + run(..., check=True, stdout=PIPE).stdout + + The arguments shown above are merely the most common ones. + The full function signature is largely the same as that of :func:`run` - + most arguments are passed directly through to that interface. + However, explicitly passing ``input=None`` to inherit the parent's + standard input file handle is not supported. + + By default, this function will return the data as encoded bytes. The actual + encoding of the output data may depend on the command being invoked, so the + decoding to text will often need to be handled at the application level. + + This behaviour may be overridden by setting *universal_newlines* to + ``True`` as described above in :ref:`frequently-used-arguments`. + + To also capture standard error in the result, use + ``stderr=subprocess.STDOUT``:: + + >>> subprocess.check_output( + ... "ls non_existent_file; exit 0", + ... stderr=subprocess.STDOUT, + ... shell=True) + 'ls: non_existent_file: No such file or directory\n' + + .. versionadded:: 3.1 + + .. versionchanged:: 3.3 + *timeout* was added. + + .. versionchanged:: 3.4 + Support for the *input* keyword argument was added. .. _subprocess-replacements: @@ -1000,7 +1068,7 @@ Return code handling translates as follows:: if rc is not None and rc >> 8: print("There were some errors") ==> - process = Popen(cmd, 'w', stdin=PIPE) + process = Popen(cmd, stdin=PIPE) ... process.stdin.close() if process.wait() != 0: @@ -1019,7 +1087,7 @@ Replacing functions from the :mod:`popen2` module (child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode) ==> - p = Popen(["somestring"], shell=True, bufsize=bufsize, + p = Popen("somestring", shell=True, bufsize=bufsize, stdin=PIPE, stdout=PIPE, close_fds=True) (child_stdout, child_stdin) = (p.stdout, p.stdin) @@ -1072,8 +1140,10 @@ handling consistency are valid for these functions. >>> subprocess.getstatusoutput('/bin/junk') (256, 'sh: /bin/junk: not found') - .. versionchanged:: 3.3 - Availability: Unix & Windows + Availability: POSIX & Windows + + .. versionchanged:: 3.3.4 + Windows support added .. function:: getoutput(cmd) @@ -1086,8 +1156,10 @@ handling consistency are valid for these functions. >>> subprocess.getoutput('ls /bin/ls') '/bin/ls' - .. versionchanged:: 3.3 - Availability: Unix & Windows + Availability: POSIX & Windows + + .. versionchanged:: 3.3.4 + Windows support added Notes diff --git a/Doc/library/sunau.rst b/Doc/library/sunau.rst index 15c06b561abc..a94ae08d831f 100644 --- a/Doc/library/sunau.rst +++ b/Doc/library/sunau.rst @@ -251,7 +251,7 @@ AU_write objects, as returned by :func:`.open` above, have the following methods Write audio frames, without correcting *nframes*. .. versionchanged:: 3.4 - Any :term:`bytes-like object`\ s are now accepted. + Any :term:`bytes-like object` is now accepted. .. method:: AU_write.writeframes(data) @@ -259,7 +259,7 @@ AU_write objects, as returned by :func:`.open` above, have the following methods Write audio frames and make sure *nframes* is correct. .. versionchanged:: 3.4 - Any :term:`bytes-like object`\ s are now accepted. + Any :term:`bytes-like object` is now accepted. .. method:: AU_write.close() diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst new file mode 100644 index 000000000000..50a5983236e7 --- /dev/null +++ b/Doc/library/superseded.rst @@ -0,0 +1,14 @@ +.. _superseded: + +****************** +Superseded Modules +****************** + +The modules described in this chapter are deprecated and only kept for +backwards compatibility. They have been superseded by other modules. + + +.. toctree:: + + optparse.rst + imp.rst diff --git a/Doc/library/symtable.rst b/Doc/library/symtable.rst index 472a9d6ad180..ba2caff58945 100644 --- a/Doc/library/symtable.rst +++ b/Doc/library/symtable.rst @@ -4,6 +4,10 @@ .. module:: symtable :synopsis: Interface to the compiler's internal symbol tables. +**Source code:** :source:`Lib/symtable.py` + +-------------- + .. moduleauthor:: Jeremy Hylton <jeremy@alum.mit.edu> .. sectionauthor:: Benjamin Peterson <benjamin@python.org> @@ -67,10 +71,6 @@ Examining Symbol Tables Return ``True`` if the block uses ``exec``. - .. method:: has_import_star() - - Return ``True`` if the block uses a starred from-import. - .. method:: get_identifiers() Return a list of names of symbols in this table. @@ -185,4 +185,4 @@ Examining Symbol Tables .. method:: get_namespace() Return the namespace bound to this name. If more than one namespace is - bound, a :exc:`ValueError` is raised. + bound, :exc:`ValueError` is raised. diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index ad447a2c9f0a..f6325cc8c1e6 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -12,11 +12,12 @@ always available. .. data:: abiflags - On POSIX systems where Python is build with the standard ``configure`` + On POSIX systems where Python was built with the standard ``configure`` script, this contains the ABI flags as specified by :pep:`3149`. .. versionadded:: 3.2 + .. data:: argv The list of command line arguments passed to a Python script. ``argv[0]`` is the @@ -166,7 +167,7 @@ always available. .. data:: dont_write_bytecode - If this is true, Python won't try to write ``.pyc`` or ``.pyo`` files on the + If this is true, Python won't try to write ``.pyc`` files on the import of source modules. This value is initially set to ``True`` or ``False`` depending on the :option:`-B` command line option and the :envvar:`PYTHONDONTWRITEBYTECODE` environment variable, but you can set it @@ -227,7 +228,9 @@ always available. installed in :file:`{exec_prefix}/lib/python{X.Y}/lib-dynload`, where *X.Y* is the version number of Python, for example ``3.2``. - .. note:: If a :ref:`virtual environment <venv-def>` is in effect, this + .. note:: + + If a :ref:`virtual environment <venv-def>` is in effect, this value will be changed in ``site.py`` to point to the virtual environment. The value for the Python installation will still be available, via :data:`base_exec_prefix`. @@ -573,6 +576,18 @@ always available. *service_pack_major*, *suite_mask*, and *product_type*. +.. function:: get_coroutine_wrapper() + + Returns ``None``, or a wrapper set by :func:`set_coroutine_wrapper`. + + .. versionadded:: 3.5 + See :pep:`492` for more details. + + .. note:: + This function has been added on a provisional basis (see :pep:`411` + for details.) Use it only for debugging purposes. + + .. data:: hash_info A :term:`struct sequence` giving parameters of the numeric hash @@ -604,7 +619,7 @@ always available. .. versionadded:: 3.2 - .. versionchanged: 3.4 + .. versionchanged:: 3.4 Added *algorithm*, *hash_bits* and *seed_bits* @@ -626,7 +641,7 @@ always available. :term:`struct sequence` :data:`sys.version_info` may be used for a more human-friendly encoding of the same information. - More details of ``hexversion`` can be found at :ref:`apiabiversion` + More details of ``hexversion`` can be found at :ref:`apiabiversion`. .. data:: implementation @@ -664,7 +679,7 @@ always available. an underscore, and are not described here. Regardless of its contents, :data:`sys.implementation` will not change during a run of the interpreter, nor between implementation versions. (It may change between Python - language versions, however.) See `PEP 421` for more information. + language versions, however.) See :pep:`421` for more information. .. versionadded:: 3.3 @@ -692,10 +707,11 @@ always available. .. data:: __interactivehook__ - When present, this function is automatically called (with no arguments) - when the interpreter is launched in :ref:`interactive mode <tut-interactive>`. - This is done after the :envvar:`PYTHONSTARTUP` file is read, so that you - can set this hook there. + When this attribute exists, its value is automatically called (with no + arguments) when the interpreter is launched in :ref:`interactive mode + <tut-interactive>`. This is done after the :envvar:`PYTHONSTARTUP` file is + read, so that you can set this hook there. The :mod:`site` module + :ref:`sets this <rlcompleter-config>`. .. versionadded:: 3.4 @@ -714,6 +730,14 @@ always available. value of :func:`intern` around to benefit from it. +.. function:: is_finalizing() + + Return :const:`True` if the Python interpreter is + :term:`shutting down <interpreter shutdown>`, :const:`False` otherwise. + + .. versionadded:: 3.5 + + .. data:: last_type last_value last_traceback @@ -951,6 +975,13 @@ always available. that supports a higher limit. This should be done with care, because a too-high limit can lead to a crash. + If the new limit is too low at the current recursion depth, a + :exc:`RecursionError` exception is raised. + + .. versionchanged:: 3.5.1 + A :exc:`RecursionError` exception is now raised if the new limit is too + low at the current recursion depth. + .. function:: setswitchinterval(interval) @@ -1049,6 +1080,46 @@ always available. thus not likely to be implemented elsewhere. +.. function:: set_coroutine_wrapper(wrapper) + + Allows intercepting creation of :term:`coroutine` objects (only ones that + are created by an :keyword:`async def` function; generators decorated with + :func:`types.coroutine` or :func:`asyncio.coroutine` will not be + intercepted). + + The *wrapper* argument must be either: + + * a callable that accepts one argument (a coroutine object); + * ``None``, to reset the wrapper. + + If called twice, the new wrapper replaces the previous one. The function + is thread-specific. + + The *wrapper* callable cannot define new coroutines directly or indirectly:: + + def wrapper(coro): + async def wrap(coro): + return await coro + return wrap(coro) + sys.set_coroutine_wrapper(wrapper) + + async def foo(): + pass + + # The following line will fail with a RuntimeError, because + # ``wrapper`` creates a ``wrap(coro)`` coroutine: + foo() + + See also :func:`get_coroutine_wrapper`. + + .. versionadded:: 3.5 + See :pep:`492` for more details. + + .. note:: + This function has been added on a provisional basis (see :pep:`411` + for details.) Use it only for debugging purposes. + + .. data:: stdin stdout stderr @@ -1062,8 +1133,9 @@ always available. statements and for the prompts of :func:`input`; * The interpreter's own prompts and its error messages go to ``stderr``. - By default, these streams are regular text streams as returned by the - :func:`open` function. Their parameters are chosen as follows: + These streams are regular :term:`text files <text file>` like those + returned by the :func:`open` function. Their parameters are chosen as + follows: * The character encoding is platform-dependent. Under Windows, if the stream is interactive (that is, if its :meth:`isatty` method returns ``True``), the @@ -1071,26 +1143,22 @@ always available. platforms, the locale encoding is used (see :meth:`locale.getpreferredencoding`). Under all platforms though, you can override this value by setting the - :envvar:`PYTHONIOENCODING` environment variable. + :envvar:`PYTHONIOENCODING` environment variable before starting Python. * When interactive, standard streams are line-buffered. Otherwise, they are block-buffered like regular text files. You can override this value with the :option:`-u` command-line option. - To write or read binary data from/to the standard streams, use the - underlying binary :data:`~io.TextIOBase.buffer`. For example, to write - bytes to :data:`stdout`, use ``sys.stdout.buffer.write(b'abc')``. Using - :meth:`io.TextIOBase.detach`, streams can be made binary by default. This - function sets :data:`stdin` and :data:`stdout` to binary:: + .. note:: - def make_streams_binary(): - sys.stdin = sys.stdin.detach() - sys.stdout = sys.stdout.detach() + To write or read binary data from/to the standard streams, use the + underlying binary :data:`~io.TextIOBase.buffer` object. For example, to + write bytes to :data:`stdout`, use ``sys.stdout.buffer.write(b'abc')``. - Note that the streams may be replaced with objects (like :class:`io.StringIO`) - that do not support the :attr:`~io.BufferedIOBase.buffer` attribute or the - :meth:`~io.BufferedIOBase.detach` method and can raise :exc:`AttributeError` - or :exc:`io.UnsupportedOperation`. + However, if you are writing a library (and do not control in which + context its code will be executed), be aware that the standard streams + may be replaced with file-like objects like :class:`io.StringIO` which + do not support the :attr:`~io.BufferedIOBase.buffer` attribute. .. data:: __stdin__ @@ -1221,5 +1289,4 @@ always available. .. rubric:: Citations -.. [C99] ISO/IEC 9899:1999. "Programming languages -- C." A public draft of this standard is available at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf . - +.. [C99] ISO/IEC 9899:1999. "Programming languages -- C." A public draft of this standard is available at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf\ . diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst index 59336c9788b9..adacb0ab3c9e 100644 --- a/Doc/library/tarfile.rst +++ b/Doc/library/tarfile.rst @@ -19,7 +19,8 @@ higher-level functions in :ref:`shutil <archiving-operations>`. Some facts and figures: -* reads and writes :mod:`gzip`, :mod:`bz2` and :mod:`lzma` compressed archives. +* reads and writes :mod:`gzip`, :mod:`bz2` and :mod:`lzma` compressed archives + if the respective modules are available. * read/write support for the POSIX.1-1988 (ustar) format. @@ -61,6 +62,23 @@ Some facts and figures: +------------------+---------------------------------------------+ | ``'r:xz'`` | Open for reading with lzma compression. | +------------------+---------------------------------------------+ + | ``'x'`` or | Create a tarfile exclusively without | + | ``'x:'`` | compression. | + | | Raise an :exc:`FileExistsError` exception | + | | if it is already exists. | + +------------------+---------------------------------------------+ + | ``'x:gz'`` | Create a tarfile with gzip compression. | + | | Raise an :exc:`FileExistsError` exception | + | | if it is already exists. | + +------------------+---------------------------------------------+ + | ``'x:bz2'`` | Create a tarfile with bzip2 compression. | + | | Raise an :exc:`FileExistsError` exception | + | | if it is already exists. | + +------------------+---------------------------------------------+ + | ``'x:xz'`` | Create a tarfile with lzma compression. | + | | Raise an :exc:`FileExistsError` exception | + | | if it is already exists. | + +------------------+---------------------------------------------+ | ``'a' or 'a:'`` | Open for appending with no compression. The | | | file is created if it does not exist. | +------------------+---------------------------------------------+ @@ -81,6 +99,10 @@ Some facts and figures: If *fileobj* is specified, it is used as an alternative to a :term:`file object` opened in binary mode for *name*. It is supposed to be at position 0. + For modes ``'w:gz'``, ``'r:gz'``, ``'w:bz2'``, ``'r:bz2'``, ``'x:gz'``, + ``'x:bz2'``, :func:`tarfile.open` accepts the keyword argument + *compresslevel* to specify the compression level of the file. + For special purposes, there is a second format for *mode*: ``'filemode|[compression]'``. :func:`tarfile.open` will return a :class:`TarFile` object that processes its data as a stream of blocks. No random seeking will @@ -122,6 +144,8 @@ Some facts and figures: | | writing. | +-------------+--------------------------------------------+ + .. versionchanged:: 3.5 + The ``'x'`` (exclusive creation) mode was added. .. class:: TarFile @@ -172,6 +196,13 @@ The :mod:`tarfile` module defines the following exceptions: Is raised by :meth:`TarInfo.frombuf` if the buffer it gets is invalid. +The following constants are available at the module level: + +.. data:: ENCODING + + The default character encoding: ``'utf-8'`` on Windows, the value returned by + :func:`sys.getfilesystemencoding` otherwise. + Each of the following constants defines a tar archive format that the :mod:`tarfile` module is able to create. See section :ref:`tar-formats` for @@ -198,20 +229,15 @@ details. The default format for creating archives. This is currently :const:`GNU_FORMAT`. -The following variables are available on module level: - - -.. data:: ENCODING - - The default character encoding: ``'utf-8'`` on Windows, - :func:`sys.getfilesystemencoding` otherwise. - - .. seealso:: Module :mod:`zipfile` Documentation of the :mod:`zipfile` standard module. + :ref:`archiving-operations` + Documentation of the higher-level archiving facilities provided by the + standard :mod:`shutil` module. + `GNU tar manual, Basic Tar Format <http://www.gnu.org/software/tar/manual/html_node/Standard.html>`_ Documentation for tar archive files, including GNU tar extensions. @@ -234,7 +260,7 @@ be finalized; only the internally used file object will be closed. See the :ref:`tar-examples` section for a use case. .. versionadded:: 3.2 - Added support for the context manager protocol. + Added support for the context management protocol. .. class:: TarFile(name=None, mode='r', fileobj=None, format=DEFAULT_FORMAT, tarinfo=TarInfo, dereference=False, ignore_zeros=False, encoding=ENCODING, errors='surrogateescape', pax_headers=None, debug=0, errorlevel=0) @@ -245,8 +271,8 @@ be finalized; only the internally used file object will be closed. See the In this case, the file object's :attr:`name` attribute is used if it exists. *mode* is either ``'r'`` to read from an existing archive, ``'a'`` to append - data to an existing file or ``'w'`` to create a new file overwriting an existing - one. + data to an existing file, ``'w'`` to create a new file overwriting an existing + one or ``'x'`` to create a new file only if it's not exists. If *fileobj* is given, it is used for reading or writing data. If it can be determined, *mode* is overridden by *fileobj*'s mode. *fileobj* will be used @@ -285,14 +311,16 @@ be finalized; only the internally used file object will be closed. See the to be handled. The default settings will work for most users. See section :ref:`tar-unicode` for in-depth information. - .. versionchanged:: 3.2 - Use ``'surrogateescape'`` as the default for the *errors* argument. - The *pax_headers* argument is an optional dictionary of strings which will be added as a pax global header if *format* is :const:`PAX_FORMAT`. + .. versionchanged:: 3.2 + Use ``'surrogateescape'`` as the default for the *errors* argument. -.. method:: TarFile.open(...) + .. versionchanged:: 3.5 + The ``'x'`` (exclusive creation) mode was added. + +.. classmethod:: TarFile.open(...) Alternative constructor. The :func:`tarfile.open` function is actually a shortcut to this classmethod. @@ -321,11 +349,15 @@ be finalized; only the internally used file object will be closed. See the returned by :meth:`getmembers`. -.. method:: TarFile.list(verbose=True) +.. method:: TarFile.list(verbose=True, *, members=None) Print a table of contents to ``sys.stdout``. If *verbose* is :const:`False`, only the names of the members are printed. If it is :const:`True`, output - similar to that of :program:`ls -l` is produced. + similar to that of :program:`ls -l` is produced. If optional *members* is + given, it must be a subset of the list returned by :meth:`getmembers`. + + .. versionchanged:: 3.5 + Added the *members* parameter. .. method:: TarFile.next() @@ -335,7 +367,7 @@ be finalized; only the internally used file object will be closed. See the available. -.. method:: TarFile.extractall(path=".", members=None) +.. method:: TarFile.extractall(path=".", members=None, *, numeric_owner=False) Extract all members from the archive to the current working directory or directory *path*. If optional *members* is given, it must be a subset of the @@ -345,6 +377,10 @@ be finalized; only the internally used file object will be closed. See the reset each time a file is created in it. And, if a directory's permissions do not allow writing, extracting files to it will fail. + If *numeric_owner* is :const:`True`, the uid and gid numbers from the tarfile + are used to set the owner/group for the extracted files. Otherwise, the named + values from the tarfile are used. + .. warning:: Never extract archives from untrusted sources without prior inspection. @@ -352,8 +388,11 @@ be finalized; only the internally used file object will be closed. See the that have absolute filenames starting with ``"/"`` or filenames with two dots ``".."``. + .. versionchanged:: 3.5 + Added the *numeric_only* parameter. + -.. method:: TarFile.extract(member, path="", set_attrs=True) +.. method:: TarFile.extract(member, path="", set_attrs=True, *, numeric_owner=False) Extract a member from the archive to the current working directory, using its full name. Its file information is extracted as accurately as possible. *member* @@ -361,6 +400,10 @@ be finalized; only the internally used file object will be closed. See the directory using *path*. File attributes (owner, mtime, mode) are set unless *set_attrs* is false. + If *numeric_owner* is :const:`True`, the uid and gid numbers from the tarfile + are used to set the owner/group for the extracted files. Otherwise, the named + values from the tarfile are used. + .. note:: The :meth:`extract` method does not take care of several extraction issues. @@ -373,6 +416,9 @@ be finalized; only the internally used file object will be closed. See the .. versionchanged:: 3.2 Added the *set_attrs* parameter. + .. versionchanged:: 3.5 + Added the *numeric_only* parameter. + .. method:: TarFile.extractfile(member) Extract a member from the archive as a file object. *member* may be a filename @@ -458,14 +504,14 @@ It does *not* contain the file's data itself. Create a :class:`TarInfo` object. -.. method:: TarInfo.frombuf(buf) +.. classmethod:: TarInfo.frombuf(buf, encoding, errors) Create and return a :class:`TarInfo` object from string buffer *buf*. - Raises :exc:`HeaderError` if the buffer is invalid.. + Raises :exc:`HeaderError` if the buffer is invalid. -.. method:: TarInfo.fromtarfile(tarfile) +.. classmethod:: TarInfo.fromtarfile(tarfile) Read the next member from the :class:`TarFile` object *tarfile* and return it as a :class:`TarInfo` object. @@ -509,7 +555,7 @@ A ``TarInfo`` object has the following public data attributes: :const:`AREGTYPE`, :const:`LNKTYPE`, :const:`SYMTYPE`, :const:`DIRTYPE`, :const:`FIFOTYPE`, :const:`CONTTYPE`, :const:`CHRTYPE`, :const:`BLKTYPE`, :const:`GNUTYPE_SPARSE`. To determine the type of a :class:`TarInfo` object - more conveniently, use the ``is_*()`` methods below. + more conveniently, use the ``is*()`` methods below. .. attribute:: TarInfo.linkname @@ -787,7 +833,7 @@ metadata must be either decoded or encoded. If *encoding* is not set appropriately, this conversion may fail. The *errors* argument defines how characters are treated that cannot be -converted. Possible values are listed in section :ref:`codec-base-classes`. +converted. Possible values are listed in section :ref:`error-handlers`. The default scheme is ``'surrogateescape'`` which Python also uses for its file system calls, see :ref:`os-filenames`. @@ -795,4 +841,3 @@ In case of :const:`PAX_FORMAT` archives, *encoding* is generally not needed because all the metadata is stored using *UTF-8*. *encoding* is only used in the rare cases when binary pax headers are decoded or when strings with surrogate characters are stored. - diff --git a/Doc/library/telnetlib.rst b/Doc/library/telnetlib.rst index b0e4d1d8d999..4040f72ee866 100644 --- a/Doc/library/telnetlib.rst +++ b/Doc/library/telnetlib.rst @@ -31,7 +31,7 @@ Character), EL (Erase Line), GA (Go Ahead), SB (Subnegotiation Begin). :class:`Telnet` represents a connection to a Telnet server. The instance is initially not connected by default; the :meth:`open` method must be used to establish a connection. Alternatively, the host name and optional port - number can be passed to the constructor, to, in which case the connection to + number can be passed to the constructor too, in which case the connection to the server will be established before the constructor returns. The optional *timeout* parameter specifies a timeout in seconds for blocking operations like the connection attempt (if not specified, the global default timeout @@ -205,7 +205,7 @@ Telnet Objects .. method:: Telnet.set_option_negotiation_callback(callback) Each time a telnet option is read on the input flow, this *callback* (if set) is - called with the following parameters : callback(telnet socket, command + called with the following parameters: callback(telnet socket, command (DO/DONT/WILL/WONT), option). No other action is done afterwards by telnetlib. diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst index 13b6041d04ff..83f994170a96 100644 --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -16,16 +16,18 @@ -------------- -This module generates temporary files and directories. It works on all -supported platforms. It provides three new functions, -:func:`NamedTemporaryFile`, :func:`mkstemp`, and :func:`mkdtemp`, which should -eliminate all remaining need to use the insecure :func:`mktemp` function. -Temporary file names created by this module no longer contain the process ID; -instead a string of six random characters is used. - -Also, all the user-callable functions now take additional arguments which -allow direct control over the location and name of temporary files. It is -no longer necessary to use the global *tempdir* variable. +This module creates temporary files and directories. It works on all +supported platforms. :class:`TemporaryFile`, :class:`NamedTemporaryFile`, +:class:`TemporaryDirectory`, and :class:`SpooledTemporaryFile` are high-level +interfaces which provide automatic cleanup and can be used as +context managers. :func:`mkstemp` and +:func:`mkdtemp` are lower-level functions which require manual cleanup. + +All the user-callable functions and constructors take additional arguments which +allow direct control over the location and name of temporary files and +directories. Files names used by this module include a string of +random characters which allows those files to be securely created in +shared temporary directories. To maintain backward compatibility, the argument order is somewhat odd; it is recommended to use keyword arguments for clarity. @@ -34,25 +36,37 @@ The module defines the following user-callable items: .. function:: TemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix='', prefix='tmp', dir=None) Return a :term:`file-like object` that can be used as a temporary storage area. - The file is created using :func:`mkstemp`. It will be destroyed as soon + The file is created securely, using the same rules as :func:`mkstemp`. It will be destroyed as soon as it is closed (including an implicit close when the object is garbage - collected). Under Unix, the directory entry for the file is removed + collected). Under Unix, the directory entry for the file is either not created at all or is removed immediately after the file is created. Other platforms do not support this; your code should not rely on a temporary file created using this function having or not having a visible name in the file system. + The resulting object can be used as a context manager (see + :ref:`tempfile-examples`). On completion of the context or + destruction of the file object the temporary file will be removed + from the filesystem. + The *mode* parameter defaults to ``'w+b'`` so that the file created can be read and written without being closed. Binary mode is used so that it behaves consistently on all platforms without regard for the data that is stored. *buffering*, *encoding* and *newline* are interpreted as for :func:`open`. - The *dir*, *prefix* and *suffix* parameters are passed to :func:`mkstemp`. + The *dir*, *prefix* and *suffix* parameters have the same meaning + as with :func:`mkstemp`. The returned object is a true file object on POSIX platforms. On other platforms, it is a file-like object whose :attr:`!file` attribute is the - underlying true file object. This file-like object can be used in a - :keyword:`with` statement, just like a normal file. + underlying true file object. + + The :py:data:`os.O_TMPFILE` flag is used if it is available and works + (Linux-specific, requires Linux kernel 3.11 or later). + + .. versionchanged:: 3.5 + + The :py:data:`os.O_TMPFILE` flag is now used if available. .. function:: NamedTemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix='', prefix='tmp', dir=None, delete=True) @@ -94,15 +108,16 @@ The module defines the following user-callable items: .. function:: TemporaryDirectory(suffix='', prefix='tmp', dir=None) - This function creates a temporary directory using :func:`mkdtemp` - (the supplied arguments are passed directly to the underlying function). + This function securely creates a temporary directory using the same rules as :func:`mkdtemp`. The resulting object can be used as a context manager (see - :ref:`context-managers`). On completion of the context (or destruction - of the temporary directory object), the newly created temporary directory + :ref:`tempfile-examples`). On completion of the context or destruction + of the temporary directory object the newly created temporary directory and all its contents are removed from the filesystem. - The directory name can be retrieved from the :attr:`name` attribute - of the returned object. + The directory name can be retrieved from the :attr:`name` attribute of the + returned object. When the returned object is used as a context manager, the + :attr:`name` will be assigned to the target of the :keyword:`as` clause in + the :keyword:`with` statement, if there is one. The directory can be explicitly cleaned up by calling the :func:`cleanup` method. @@ -110,7 +125,7 @@ The module defines the following user-callable items: .. versionadded:: 3.2 -.. function:: mkstemp(suffix='', prefix='tmp', dir=None, text=False) +.. function:: mkstemp(suffix=None, prefix=None, dir=None, text=False) Creates a temporary file in the most secure manner possible. There are no race conditions in the file's creation, assuming that the platform @@ -139,6 +154,16 @@ The module defines the following user-callable items: filename will have any nice properties, such as not requiring quoting when passed to external commands via ``os.popen()``. + *suffix*, *prefix*, and *dir* must all contain the same type, if specified. + If they are bytes, the returned name will be bytes instead of str. + If you want to force a bytes return value with otherwise default behavior, + pass ``suffix=b''``. + + A *prefix* value of ``None`` means use the return value of + :func:`gettempprefix` or :func:`gettempprefixb` as appropriate. + + A *suffix* value of ``None`` means use an appropriate empty value. + If *text* is specified, it indicates whether to open the file in binary mode (the default) or text mode. On some platforms, this makes no difference. @@ -147,8 +172,14 @@ The module defines the following user-callable items: file (as would be returned by :func:`os.open`) and the absolute pathname of that file, in that order. + .. versionchanged:: 3.5 + *suffix*, *prefix*, and *dir* may now be supplied in bytes in order to + obtain a bytes return value. Prior to this, only str was allowed. + *suffix* and *prefix* now accept and default to ``None`` to cause + an appropriate default value to be used. + -.. function:: mkdtemp(suffix='', prefix='tmp', dir=None) +.. function:: mkdtemp(suffix=None, prefix=None, dir=None) Creates a temporary directory in the most secure manner possible. There are no race conditions in the directory's creation. The directory is @@ -162,50 +193,21 @@ The module defines the following user-callable items: :func:`mkdtemp` returns the absolute pathname of the new directory. + .. versionchanged:: 3.5 + *suffix*, *prefix*, and *dir* may now be supplied in bytes in order to + obtain a bytes return value. Prior to this, only str was allowed. + *suffix* and *prefix* now accept and default to ``None`` to cause + an appropriate default value to be used. -.. function:: mktemp(suffix='', prefix='tmp', dir=None) - - .. deprecated:: 2.3 - Use :func:`mkstemp` instead. - - Return an absolute pathname of a file that did not exist at the time the - call is made. The *prefix*, *suffix*, and *dir* arguments are the same - as for :func:`mkstemp`. - .. warning:: - - Use of this function may introduce a security hole in your program. By - the time you get around to doing anything with the file name it returns, - someone else may have beaten you to the punch. :func:`mktemp` usage can - be replaced easily with :func:`NamedTemporaryFile`, passing it the - ``delete=False`` parameter:: - - >>> f = NamedTemporaryFile(delete=False) - >>> f.name - '/tmp/tmptjujjt' - >>> f.write(b"Hello World!\n") - 13 - >>> f.close() - >>> os.unlink(f.name) - >>> os.path.exists(f.name) - False - -The module uses two global variables that tell it how to construct a -temporary name. They are initialized at the first call to any of the -functions above. The caller may change them, but this is discouraged; use -the appropriate function arguments, instead. - - -.. data:: tempdir +.. function:: gettempdir() - When set to a value other than ``None``, this variable defines the - default value for the *dir* argument to all the functions defined in this - module. + Return the name of the directory used for temporary files. This + defines the default value for the *dir* argument to all functions + in this module. - If ``tempdir`` is unset or ``None`` at any call to any of the above - functions, Python searches a standard list of directories and sets - *tempdir* to the first one which the calling user can create files in. - The list is: + Python searches a standard list of directories to find one which + the calling user can create files in. The list is: #. The directory named by the :envvar:`TMPDIR` environment variable. @@ -223,19 +225,43 @@ the appropriate function arguments, instead. #. As a last resort, the current working directory. + The result of this search is cached, see the description of + :data:`tempdir` below. -.. function:: gettempdir() +.. function:: gettempdirb() - Return the directory currently selected to create temporary files in. If - :data:`tempdir` is not ``None``, this simply returns its contents; otherwise, - the search described above is performed, and the result returned. + Same as :func:`gettempdir` but the return value is in bytes. + .. versionadded:: 3.5 .. function:: gettempprefix() Return the filename prefix used to create temporary files. This does not contain the directory component. +.. function:: gettempprefixb() + + Same as :func:`gettempprefixb` but the return value is in bytes. + + .. versionadded:: 3.5 + +The module uses a global variable to store the name of the directory +used for temporary files returned by :func:`gettempdir`. It can be +set directly to override the selection process, but this is discouraged. +All functions in this module take a *dir* argument which can be used +to specify the directory and this is the recommend approach. + +.. data:: tempdir + + When set to a value other than ``None``, this variable defines the + default value for the *dir* argument to all the functions defined in this + module. + + If ``tempdir`` is unset or ``None`` at any call to any of the above + functions except :func:`gettempprefix` it is initalized following the + algorithm described in :func:`gettempdir`. + +.. _tempfile-examples: Examples -------- @@ -269,3 +295,42 @@ Here are some examples of typical usage of the :mod:`tempfile` module:: >>> # directory and contents have been removed + +Deprecated functions and variables +---------------------------------- + +A historical way to create temporary files was to first generate a +file name with the :func:`mktemp` function and then create a file +using this name. Unfortunately this is not secure, because a different +process may create a file with this name in the time between the call +to :func:`mktemp` and the subsequent attempt to create the file by the +first process. The solution is to combine the two steps and create the +file immediately. This approach is used by :func:`mkstemp` and the +other functions described above. + +.. function:: mktemp(suffix='', prefix='tmp', dir=None) + + .. deprecated:: 2.3 + Use :func:`mkstemp` instead. + + Return an absolute pathname of a file that did not exist at the time the + call is made. The *prefix*, *suffix*, and *dir* arguments are the same + as for :func:`mkstemp`. + + .. warning:: + + Use of this function may introduce a security hole in your program. By + the time you get around to doing anything with the file name it returns, + someone else may have beaten you to the punch. :func:`mktemp` usage can + be replaced easily with :func:`NamedTemporaryFile`, passing it the + ``delete=False`` parameter:: + + >>> f = NamedTemporaryFile(delete=False) + >>> f.name + '/tmp/tmptjujjt' + >>> f.write(b"Hello World!\n") + 13 + >>> f.close() + >>> os.unlink(f.name) + >>> os.path.exists(f.name) + False diff --git a/Doc/library/test.rst b/Doc/library/test.rst index 2c515497ca85..85cab3b22790 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -85,7 +85,7 @@ A basic boilerplate is often used:: This code pattern allows the testing suite to be run by :mod:`test.regrtest`, on its own as a script that supports the :mod:`unittest` CLI, or via the -`python -m unittest` CLI. +``python -m unittest`` CLI. The goal for regression testing is to try to break code. This leads to a few guidelines to be followed: @@ -141,9 +141,9 @@ guidelines to be followed: arg = (1, 2, 3) When using this pattern, remember that all classes that inherit from - `unittest.TestCase` are run as tests. The `Mixin` class in the example above + :class:`unittest.TestCase` are run as tests. The :class:`Mixin` class in the example above does not have any data and so can't be run by itself, thus it does not - inherit from `unittest.TestCase`. + inherit from :class:`unittest.TestCase`. .. seealso:: @@ -160,7 +160,7 @@ Running tests using the command-line interface The :mod:`test` package can be run as a script to drive Python's regression test suite, thanks to the :option:`-m` option: :program:`python -m test`. Under the hood, it uses :mod:`test.regrtest`; the call :program:`python -m -test.regrtest` used in previous Python versions still works). Running the +test.regrtest` used in previous Python versions still works. Running the script by itself automatically starts running all regression tests in the :mod:`test` package. It does this by finding all modules in the package whose name starts with ``test_``, importing them, and executing the function @@ -199,6 +199,7 @@ The :mod:`test.support` module provides support for Python's regression test suite. .. note:: + :mod:`test.support` is not a public module. It is documented here to help Python developers write tests. The API of this module is subject to change without backwards compatibility concerns between releases. @@ -460,7 +461,7 @@ The :mod:`test.support` module defines the following functions: .. function:: make_bad_fd() Create an invalid file descriptor by opening and closing a temporary file, - and returning its descripor. + and returning its descriptor. .. function:: import_module(name, deprecated=False) @@ -553,6 +554,32 @@ The :mod:`test.support` module defines the following functions: run simultaneously, which is a problem for buildbots. +.. function:: load_package_tests(pkg_dir, loader, standard_tests, pattern) + + Generic implementation of the :mod:`unittest` ``load_tests`` protocol for + use in test packages. *pkg_dir* is the root directory of the package; + *loader*, *standard_tests*, and *pattern* are the arguments expected by + ``load_tests``. In simple cases, the test package's ``__init__.py`` + can be the following:: + + import os + from test.support import load_package_tests + + def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) + +.. function:: detect_api_mismatch(ref_api, other_api, *, ignore=()): + + Returns the set of attributes, functions or methods of *ref_api* not + found on *other_api*, except for a defined list of items to be + ignored in this check specified in *ignore*. + + By default this skips private attributes beginning with '_' but + includes all magic methods, i.e. those starting and ending in '__'. + + .. versionadded:: 3.5 + + The :mod:`test.support` module defines the following classes: .. class:: TransientResource(exc, **kwargs) diff --git a/Doc/library/textwrap.rst b/Doc/library/textwrap.rst index 1ba42a3f0404..9fe7a3589a7b 100644 --- a/Doc/library/textwrap.rst +++ b/Doc/library/textwrap.rst @@ -40,13 +40,14 @@ functions should be good enough; otherwise, you should use an instance of :func:`wrap`. -.. function:: shorten(text, width=70, *, placeholder=" [...]") +.. function:: shorten(text, width, **kwargs) - Collapse and truncate the given text to fit in the given width. + Collapse and truncate the given *text* to fit in the given *width*. - The text first has its whitespace collapsed. If it then fits in - the *width*, it is returned unchanged. Otherwise, as many words - as possible are joined and then the *placeholder* is appended:: + First the whitespace in *text* is collapsed (all whitespace is replaced by + single spaces). If the result fits in the *width*, it is returned. + Otherwise, enough words are dropped from the end so that the remaining words + plus the :attr:`placeholder` fit within :attr:`width`:: >>> textwrap.shorten("Hello world!", width=12) 'Hello world!' @@ -55,6 +56,12 @@ functions should be good enough; otherwise, you should use an instance of >>> textwrap.shorten("Hello world", width=10, placeholder="...") 'Hello...' + Optional keyword arguments correspond to the instance attributes of + :class:`TextWrapper`, documented below. Note that the whitespace is + collapsed before the text is passed to the :class:`TextWrapper` :meth:`fill` + function, so changing the value of :attr:`.tabsize`, :attr:`.expand_tabs`, + :attr:`.drop_whitespace`, and :attr:`.replace_whitespace` will have no effect. + .. versionadded:: 3.4 @@ -106,12 +113,14 @@ functions should be good enough; otherwise, you should use an instance of + + world + .. versionadded:: 3.3 + :func:`wrap`, :func:`fill` and :func:`shorten` work by creating a :class:`TextWrapper` instance and calling a single method on it. That instance is not reused, so for applications that process many text -strings, it may be more efficient to create your own -:class:`TextWrapper` object. +strings using :func:`wrap` and/or :func:`fill`, it may be more efficient to +create your own :class:`TextWrapper` object. Text is preferably wrapped on whitespaces and right after the hyphens in hyphenated words; only then will long words be broken if necessary, unless @@ -252,16 +261,16 @@ hyphenated words; only then will long words be broken if necessary, unless .. attribute:: max_lines - (default: ``None``) If not ``None``, then the text be will truncated to - *max_lines* lines. + (default: ``None``) If not ``None``, then the output will contain at most + *max_lines* lines, with *placeholder* appearing at the end of the output. .. versionadded:: 3.4 .. attribute:: placeholder - (default: ``' [...]'``) String that will be appended to the last line of - text if it will be truncated. + (default: ``' [...]'``) String that will appear at the end of the output + text if it has been truncated. .. versionadded:: 3.4 diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 4a3b3ea00b21..c56d70734238 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -89,7 +89,8 @@ This module defines the following functions: Return the thread stack size used when creating new threads. The optional *size* argument specifies the stack size to be used for subsequently created threads, and must be 0 (use platform or configured default) or a positive - integer value of at least 32,768 (32 KiB). If changing the thread stack size is + integer value of at least 32,768 (32 KiB). If *size* is not specified, + 0 is used. If changing the thread stack size is unsupported, a :exc:`RuntimeError` is raised. If the specified stack size is invalid, a :exc:`ValueError` is raised and the stack size is unmodified. 32 KiB is currently the minimum supported stack size value to guarantee sufficient @@ -354,7 +355,7 @@ called in the locked state; it changes the state to unlocked and returns immediately. If an attempt is made to release an unlocked lock, a :exc:`RuntimeError` will be raised. -Locks also support the :ref:`context manager protocol <with-locks>`. +Locks also support the :ref:`context management protocol <with-locks>`. When more than one thread is blocked in :meth:`~Lock.acquire` waiting for the state to turn to unlocked, only one thread proceeds when a :meth:`~Lock.release` @@ -433,7 +434,7 @@ call pairs may be nested; only the final :meth:`~Lock.release` (the :meth:`~Lock.release` of the outermost pair) resets the lock to unlocked and allows another thread blocked in :meth:`~Lock.acquire` to proceed. -Reentrant locks also support the :ref:`context manager protocol <with-locks>`. +Reentrant locks also support the :ref:`context management protocol <with-locks>`. .. class:: RLock() @@ -501,7 +502,7 @@ passed in or one will be created by default. Passing one in is useful when several condition variables must share the same lock. The lock is part of the condition object: you don't have to track it separately. -A condition variable obeys the :ref:`context manager protocol <with-locks>`: +A condition variable obeys the :ref:`context management protocol <with-locks>`: using the ``with`` statement acquires the associated lock for the duration of the enclosed block. The :meth:`~Condition.acquire` and :meth:`~Condition.release` methods also call the corresponding methods of @@ -630,7 +631,7 @@ item to the buffer only needs to wake up one consumer thread. cv.wait() Therefore, the same rules apply as with :meth:`wait`: The lock must be - held when called and is re-aquired on return. The predicate is evaluated + held when called and is re-acquired on return. The predicate is evaluated with the lock held. .. versionadded:: 3.2 @@ -677,7 +678,7 @@ call. The counter can never go below zero; when :meth:`~Semaphore.acquire` finds that it is zero, it blocks, waiting until some other thread calls :meth:`~Semaphore.release`. -Semaphores also support the :ref:`context manager protocol <with-locks>`. +Semaphores also support the :ref:`context management protocol <with-locks>`. .. class:: Semaphore(value=1) @@ -874,7 +875,7 @@ This class provides a simple synchronization primitive for use by a fixed number of threads that need to wait for each other. Each of the threads tries to pass the barrier by calling the :meth:`~Barrier.wait` method and will block until all of the threads have made the call. At this points, the threads are released -simultanously. +simultaneously. The barrier can be reused any number of times for the same number of threads. diff --git a/Doc/library/time.rst b/Doc/library/time.rst index 64b5e0414d3b..73436ca01392 100644 --- a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -133,8 +133,7 @@ The module defines the following functions and data items: On Unix, return the current processor time as a floating point number expressed in seconds. The precision, and in fact the very definition of the meaning of - "processor time", depends on that of the C function of the same name, but in any - case, this is the function to use for benchmarking Python or timing algorithms. + "processor time", depends on that of the C function of the same name. On Windows, this function returns wall-clock seconds elapsed since the first call to this function, as a floating point number, based on the Win32 function @@ -315,9 +314,9 @@ The module defines the following functions and data items: processes running for more than 49 days. On more recent versions of Windows and on other operating systems, :func:`monotonic` is system-wide. - Availability: Windows, Mac OS X, Linux, FreeBSD, OpenBSD, Solaris. - .. versionadded:: 3.3 + .. versionchanged:: 3.5 + The function is now always available. .. function:: perf_counter() @@ -343,12 +342,18 @@ The module defines the following functions and data items: .. function:: sleep(secs) - Suspend execution for the given number of seconds. The argument may be a - floating point number to indicate a more precise sleep time. The actual - suspension time may be less than that requested because any caught signal will - terminate the :func:`sleep` following execution of that signal's catching - routine. Also, the suspension time may be longer than requested by an arbitrary - amount because of the scheduling of other activity in the system. + Suspend execution of the calling thread for the given number of seconds. + The argument may be a floating point number to indicate a more precise sleep + time. The actual suspension time may be less than that requested because any + caught signal will terminate the :func:`sleep` following execution of that + signal's catching routine. Also, the suspension time may be longer than + requested by an arbitrary amount because of the scheduling of other activity + in the system. + + .. versionchanged:: 3.5 + The function now sleeps at least *secs* even if the sleep is interrupted + by a signal, except if the signal handler raises an exception (see + :pep:`475` for the rationale). .. function:: strftime(format[, t]) @@ -629,11 +634,11 @@ The module defines the following functions and data items: it is possible to refer to February 29. :samp:`M{m}.{n}.{d}` - The *d*'th day (0 <= *d* <= 6) or week *n* of month *m* of the year (1 + The *d*'th day (0 <= *d* <= 6) of week *n* of month *m* of the year (1 <= *n* <= 5, 1 <= *m* <= 12, where week 5 means "the last *d* day in month *m*" which may occur in either the fourth or the fifth week). Week 1 is the first week in which the *d*'th day occurs. Day - zero is Sunday. + zero is a Sunday. ``time`` has the same format as ``offset`` except that no leading sign ('-' or '+') is allowed. The default, if time is not given, is 02:00:00. diff --git a/Doc/library/timeit.rst b/Doc/library/timeit.rst index 0cc15868db6a..d1051f688c9a 100644 --- a/Doc/library/timeit.rst +++ b/Doc/library/timeit.rst @@ -28,22 +28,23 @@ can be used to compare three different expressions: .. code-block:: sh - $ python -m timeit '"-".join(str(n) for n in range(100))' - 10000 loops, best of 3: 40.3 usec per loop - $ python -m timeit '"-".join([str(n) for n in range(100)])' - 10000 loops, best of 3: 33.4 usec per loop - $ python -m timeit '"-".join(map(str, range(100)))' - 10000 loops, best of 3: 25.2 usec per loop + $ python3 -m timeit '"-".join(str(n) for n in range(100))' + 10000 loops, best of 3: 30.2 usec per loop + $ python3 -m timeit '"-".join([str(n) for n in range(100)])' + 10000 loops, best of 3: 27.5 usec per loop + $ python3 -m timeit '"-".join(map(str, range(100)))' + 10000 loops, best of 3: 23.2 usec per loop This can be achieved from the :ref:`python-interface` with:: >>> import timeit >>> timeit.timeit('"-".join(str(n) for n in range(100))', number=10000) - 0.8187260627746582 + 0.3018611848820001 >>> timeit.timeit('"-".join([str(n) for n in range(100)])', number=10000) - 0.7288308143615723 + 0.2727368790656328 >>> timeit.timeit('"-".join(map(str, range(100)))', number=10000) - 0.5858950614929199 + 0.23702679807320237 + Note however that :mod:`timeit` will automatically determine the number of repetitions only when the command-line interface is used. In the @@ -58,18 +59,26 @@ Python Interface The module defines three convenience functions and a public class: -.. function:: timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000) +.. function:: timeit(stmt='pass', setup='pass', timer=<default timer>, number=1000000, globals=None) Create a :class:`Timer` instance with the given statement, *setup* code and *timer* function and run its :meth:`.timeit` method with *number* executions. + The optional *globals* argument specifies a namespace in which to execute the + code. + + .. versionchanged:: 3.5 + The optional *globals* parameter was added. -.. function:: repeat(stmt='pass', setup='pass', timer=<default timer>, repeat=3, number=1000000) +.. function:: repeat(stmt='pass', setup='pass', timer=<default timer>, repeat=3, number=1000000, globals=None) Create a :class:`Timer` instance with the given statement, *setup* code and *timer* function and run its :meth:`.repeat` method with the given *repeat* - count and *number* executions. + count and *number* executions. The optional *globals* argument specifies a + namespace in which to execute the code. + .. versionchanged:: 3.5 + The optional *globals* parameter was added. .. function:: default_timer() @@ -79,7 +88,7 @@ The module defines three convenience functions and a public class: :func:`time.perf_counter` is now the default timer. -.. class:: Timer(stmt='pass', setup='pass', timer=<timer function>) +.. class:: Timer(stmt='pass', setup='pass', timer=<timer function>, globals=None) Class for timing execution speed of small code snippets. @@ -87,17 +96,23 @@ The module defines three convenience functions and a public class: for setup, and a timer function. Both statements default to ``'pass'``; the timer function is platform-dependent (see the module doc string). *stmt* and *setup* may also contain multiple statements separated by ``;`` - or newlines, as long as they don't contain multi-line string literals. + or newlines, as long as they don't contain multi-line string literals. The + statement will by default be executed within timeit's namespace; this behavior + can be controlled by passing a namespace to *globals*. To measure the execution time of the first statement, use the :meth:`.timeit` method. The :meth:`.repeat` method is a convenience to call :meth:`.timeit` multiple times and return a list of results. + The execution time of *setup* is excluded from the overall timed execution run. + The *stmt* and *setup* parameters can also take objects that are callable without arguments. This will embed calls to them in a timer function that will then be executed by :meth:`.timeit`. Note that the timing overhead is a little larger in this case because of the extra function calls. + .. versionchanged:: 3.5 + The optional *globals* parameter was added. .. method:: Timer.timeit(number=1000000) @@ -166,7 +181,7 @@ Command-Line Interface When called as a program from the command line, the following form is used:: - python -m timeit [-n N] [-r N] [-s S] [-t] [-c] [-h] [statement ...] + python -m timeit [-n N] [-r N] [-u U] [-s S] [-t] [-c] [-h] [statement ...] Where the following options are understood: @@ -195,6 +210,12 @@ Where the following options are understood: use :func:`time.time` (deprecated) +.. cmdoption:: -u, --unit=U + + specify a time unit for timer output; can select usec, msec, or sec + + .. versionadded:: 3.5 + .. cmdoption:: -c, --clock use :func:`time.clock` (deprecated) @@ -317,3 +338,17 @@ To give the :mod:`timeit` module access to functions you define, you can pass a if __name__ == '__main__': import timeit print(timeit.timeit("test()", setup="from __main__ import test")) + +Another option is to pass :func:`globals` to the *globals* parameter, which will cause the code +to be executed within your current global namespace. This can be more convenient +than individually specifying imports:: + + def f(x): + return x**2 + def g(x): + return x**4 + def h(x): + return x**8 + + import timeit + print(timeit.timeit('[func(42) for func in (f,g,h)]', globals=globals())) diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index 83f0ed5db18c..8b738c3481f4 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -15,14 +15,14 @@ this should open a window demonstrating a simple Tk interface. .. seealso:: - `Python Tkinter Resources <http://www.python.org/topics/tkinter/>`_ + `Python Tkinter Resources <https://wiki.python.org/moin/TkInter>`_ The Python Tkinter Topic Guide provides a great deal of information on using Tk from Python and links to other sources of information on Tk. `TKDocs <http://www.tkdocs.com/>`_ Extensive tutorial plus friendlier widget pages for some of the widgets. - `Tkinter reference: a GUI for Python <http://infohost.nmt.edu/tcc/help/pubs/tkinter/>`_ + `Tkinter reference: a GUI for Python <http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/index.html>`_ On-line reference material. `Tkinter docs from effbot <http://effbot.org/tkinterbook/>`_ @@ -31,13 +31,13 @@ this should open a window demonstrating a simple Tk interface. `Tcl/Tk manual <http://www.tcl.tk/man/tcl8.5/>`_ Official manual for the latest tcl/tk version. - `Programming Python <http://www.amazon.com/Programming-Python-Mark-Lutz/dp/0596158106/>`_ + `Programming Python <http://www.rmi.net/~lutz/about-pp4e.html>`_ Book by Mark Lutz, has excellent coverage of Tkinter. `Modern Tkinter for Busy Python Developers <http://www.amazon.com/Modern-Tkinter-Python-Developers-ebook/dp/B0071QDNLO/>`_ Book by Mark Rozerman about building attractive and modern graphical user interfaces with Python and Tkinter. - `Python and Tkinter Programming <http://www.amazon.com/exec/obidos/ASIN/1884777813>`_ + `Python and Tkinter Programming <http://www.manning.com/grayson/>`_ The book by John Grayson (ISBN 1-884777-81-3). @@ -180,9 +180,9 @@ documentation that exists. Here are some hints: The Tk/Tcl development is largely taking place at ActiveState. `Tcl and the Tk Toolkit <http://www.amazon.com/exec/obidos/ASIN/020163337X>`_ - The book by John Ousterhout, the inventor of Tcl . + The book by John Ousterhout, the inventor of Tcl. - `Practical Programming in Tcl and Tk <http://www.amazon.com/exec/obidos/ASIN/0130220280>`_ + `Practical Programming in Tcl and Tk <http://www.beedub.com/book/>`_ Brent Welch's encyclopedic book. @@ -440,7 +440,7 @@ back will contain the name of the synonym and the "real" option (such as Example:: >>> print(fred.config()) - {'relief' : ('relief', 'relief', 'Relief', 'raised', 'groove')} + {'relief': ('relief', 'relief', 'Relief', 'raised', 'groove')} Of course, the dictionary printed will include all the options available and their values. This is meant only as an example. @@ -613,7 +613,7 @@ bitmap preceded with an ``@``, as in ``"@/usr/contrib/bitmap/gumby.bit"``. boolean - You can pass integers 0 or 1 or the strings ``"yes"`` or ``"no"`` . + You can pass integers 0 or 1 or the strings ``"yes"`` or ``"no"``. callback This is any Python function that takes no arguments. For example:: @@ -794,3 +794,53 @@ some widget (e.g. labels, buttons, menus). In these cases, Tk will not keep a reference to the image. When the last Python reference to the image object is deleted, the image data is deleted as well, and Tk will display an empty box wherever the image was used. + + +.. _tkinter-file-handlers: + +File Handlers +------------- + +Tk allows you to register and unregister a callback function which will be +called from the Tk mainloop when I/O is possible on a file descriptor. +Only one handler may be registered per file descriptor. Example code:: + + import tkinter + widget = tkinter.Tk() + mask = tkinter.READABLE | tkinter.WRITABLE + widget.tk.createfilehandler(file, mask, callback) + ... + widget.tk.deletefilehandler(file) + +This feature is not available on Windows. + +Since you don't know how many bytes are available for reading, you may not +want to use the :class:`~io.BufferedIOBase` or :class:`~io.TextIOBase` +:meth:`~io.BufferedIOBase.read` or :meth:`~io.IOBase.readline` methods, +since these will insist on reading a predefined number of bytes. +For sockets, the :meth:`~socket.socket.recv` or +:meth:`~socket.socket.recvfrom` methods will work fine; for other files, +use raw reads or ``os.read(file.fileno(), maxbytecount)``. + + +.. method:: Widget.tk.createfilehandler(file, mask, func) + + Registers the file handler callback function *func*. The *file* argument + may either be an object with a :meth:`~io.IOBase.fileno` method (such as + a file or socket object), or an integer file descriptor. The *mask* + argument is an ORed combination of any of the three constants below. + The callback is called as follows:: + + callback(file, mask) + + +.. method:: Widget.tk.deletefilehandler(file) + + Unregisters a file handler. + + +.. data:: READABLE + WRITABLE + EXCEPTION + + Constants used in the *mask* arguments. diff --git a/Doc/library/tkinter.ttk.rst b/Doc/library/tkinter.ttk.rst index 6f8bf1c315da..4601171b5968 100644 --- a/Doc/library/tkinter.ttk.rst +++ b/Doc/library/tkinter.ttk.rst @@ -110,8 +110,9 @@ All the :mod:`ttk` Widgets accepts the following options: | class | Specifies the window class. The class is used when querying | | | the option database for the window's other options, to | | | determine the default bindtags for the window, and to select | - | | the widget's default layout and style. This is a read-only | - | | which may only be specified when the window is created | + | | the widget's default layout and style. This option is | + | | read-only, and may only be specified when the window is | + | | created. | +-----------+--------------------------------------------------------------+ | cursor | Specifies the mouse cursor to be used for the widget. If set | | | to the empty string (the default), the cursor is inherited | @@ -554,9 +555,9 @@ ttk.Notebook This will extend the bindings for the toplevel window containing the notebook as follows: - * Control-Tab: selects the tab following the currently selected one. - * Shift-Control-Tab: selects the tab preceding the currently selected one. - * Alt-K: where K is the mnemonic (underlined) character of any tab, will + * :kbd:`Control-Tab`: selects the tab following the currently selected one. + * :kbd:`Shift-Control-Tab`: selects the tab preceding the currently selected one. + * :kbd:`Alt-K`: where *K* is the mnemonic (underlined) character of any tab, will select that tab. Multiple notebooks in a single toplevel may be enabled for traversal, @@ -1167,7 +1168,7 @@ Ttk Styling Each widget in :mod:`ttk` is assigned a style, which specifies the set of elements making up the widget and how they are arranged, along with dynamic and default settings for element options. By default the style name is the -same as the widget's class name, but it may be overriden by the widget's style +same as the widget's class name, but it may be overridden by the widget's style option. If you don't know the class name of a widget, use the method :meth:`Misc.winfo_class` (somewidget.winfo_class()). diff --git a/Doc/library/token.rst b/Doc/library/token.rst index 4cd709814c33..88fb38bc1dd1 100644 --- a/Doc/library/token.rst +++ b/Doc/library/token.rst @@ -93,6 +93,7 @@ The token constants are: DOUBLESLASH DOUBLESLASHEQUAL AT + ATEQUAL RARROW ELLIPSIS OP diff --git a/Doc/library/tokenize.rst b/Doc/library/tokenize.rst index 37d9f41cc1b2..bd6b121f8dad 100644 --- a/Doc/library/tokenize.rst +++ b/Doc/library/tokenize.rst @@ -131,6 +131,24 @@ function it uses to do this is available: .. versionadded:: 3.2 +.. exception:: TokenError + + Raised when either a docstring or expression that may be split over several + lines is not completed anywhere in the file, for example:: + + """Beginning of + docstring + + or:: + + [1, + 2, + 3 + +Note that unclosed single-quoted strings do not cause an error to be +raised. They are tokenized as ``ERRORTOKEN``, followed by the tokenization of +their contents. + .. _tokenize-cli: diff --git a/Doc/library/trace.rst b/Doc/library/trace.rst index 9b52f7d18d31..b0ac81271c5c 100644 --- a/Doc/library/trace.rst +++ b/Doc/library/trace.rst @@ -41,8 +41,8 @@ Main options At least one of the following options must be specified when invoking :mod:`trace`. The :option:`--listfuncs <-l>` option is mutually exclusive with -the :option:`--trace <-t>` and :option:`--counts <-c>` options . When -:option:`--listfuncs <-l>` is provided, neither :option:`--counts <-c>` nor +the :option:`--trace <-t>` and :option:`--count <-c>` options. When +:option:`--listfuncs <-l>` is provided, neither :option:`--count <-c>` nor :option:`--trace <-t>` are accepted, and vice versa. .. program:: trace diff --git a/Doc/library/traceback.rst b/Doc/library/traceback.rst index b68a8f1e1971..8d216d07e396 100644 --- a/Doc/library/traceback.rst +++ b/Doc/library/traceback.rst @@ -22,15 +22,20 @@ The module defines the following functions: .. function:: print_tb(traceback, limit=None, file=None) - Print up to *limit* stack trace entries from *traceback*. If *limit* is omitted - or ``None``, all entries are printed. If *file* is omitted or ``None``, the - output goes to ``sys.stderr``; otherwise it should be an open file or file-like - object to receive the output. + Print up to *limit* stack trace entries from *traceback* (starting from + the caller's frame) if *limit* is positive. Otherwise, print the last + ``abs(limit)`` entries. If *limit* is omitted or ``None``, all entries + are printed. If *file* is omitted or ``None``, the output goes to + ``sys.stderr``; otherwise it should be an open file or file-like object + to receive the output. + + .. versionchanged:: 3.5 + Added negative *limit* support. .. function:: print_exception(type, value, traceback, limit=None, file=None, chain=True) - Print exception information and up to *limit* stack trace entries from + Print exception information and stack trace entries from *traceback* to *file*. This differs from :func:`print_tb` in the following ways: @@ -41,6 +46,7 @@ The module defines the following functions: prints the line where the syntax error occurred with a caret indicating the approximate position of the error. + The optional *limit* argument has the same meaning as for :func:`print_tb`. If *chain* is true (the default), then chained exceptions (the :attr:`__cause__` or :attr:`__context__` attributes of the exception) will be printed as well, like the interpreter itself does when printing an unhandled @@ -49,33 +55,41 @@ The module defines the following functions: .. function:: print_exc(limit=None, file=None, chain=True) - This is a shorthand for ``print_exception(*sys.exc_info())``. + This is a shorthand for ``print_exception(*sys.exc_info(), limit, file, + chain)``. .. function:: print_last(limit=None, file=None, chain=True) This is a shorthand for ``print_exception(sys.last_type, sys.last_value, - sys.last_traceback, limit, file)``. In general it will work only after - an exception has reached an interactive prompt (see :data:`sys.last_type`). + sys.last_traceback, limit, file, chain)``. In general it will work only + after an exception has reached an interactive prompt (see + :data:`sys.last_type`). .. function:: print_stack(f=None, limit=None, file=None) - This function prints a stack trace from its invocation point. The optional *f* - argument can be used to specify an alternate stack frame to start. The optional - *limit* and *file* arguments have the same meaning as for - :func:`print_exception`. + Print up to *limit* stack trace entries (starting from the invocation + point) if *limit* is positive. Otherwise, print the last ``abs(limit)`` + entries. If *limit* is omitted or ``None``, all entries are printed. + The optional *f* argument can be used to specify an alternate stack frame + to start. The optional *file* argument has the same meaning as for + :func:`print_tb`. + + .. versionchanged:: 3.5 + Added negative *limit* support. .. function:: extract_tb(traceback, limit=None) - Return a list of up to *limit* "pre-processed" stack trace entries extracted - from the traceback object *traceback*. It is useful for alternate formatting of - stack traces. If *limit* is omitted or ``None``, all entries are extracted. A - "pre-processed" stack trace entry is a quadruple (*filename*, *line number*, - *function name*, *text*) representing the information that is usually printed - for a stack trace. The *text* is a string with leading and trailing whitespace - stripped; if the source is not available it is ``None``. + Return a list of "pre-processed" stack trace entries extracted from the + traceback object *traceback*. It is useful for alternate formatting of + stack traces. The optional *limit* argument has the same meaning as for + :func:`print_tb`. A "pre-processed" stack trace entry is a 4-tuple + (*filename*, *line number*, *function name*, *text*) representing the + information that is usually printed for a stack trace. The *text* is a + string with leading and trailing whitespace stripped; if the source is + not available it is ``None``. .. function:: extract_stack(f=None, limit=None) @@ -136,6 +150,162 @@ The module defines the following functions: .. versionadded:: 3.4 +.. function:: walk_stack(f) + + Walk a stack following ``f.f_back`` from the given frame, yielding the frame + and line number for each frame. If *f* is ``None``, the current stack is + used. This helper is used with :meth:`StackSummary.extract`. + + .. versionadded:: 3.5 + +.. function:: walk_tb(tb) + + Walk a traceback following ``tb_next`` yielding the frame and line number + for each frame. This helper is used with :meth:`StackSummary.extract`. + + .. versionadded:: 3.5 + +The module also defines the following classes: + +:class:`TracebackException` Objects +----------------------------------- + +.. versionadded:: 3.5 + +:class:`TracebackException` objects are created from actual exceptions to +capture data for later printing in a lightweight fashion. + +.. class:: TracebackException(exc_type, exc_value, exc_traceback, *, limit=None, lookup_lines=True, capture_locals=False) + + Capture an exception for later rendering. *limit*, *lookup_lines* and + *capture_locals* are as for the :class:`StackSummary` class. + + Note that when locals are captured, they are also shown in the traceback. + + .. attribute:: __cause__ + + A :class:`TracebackException` of the original ``__cause__``. + + .. attribute:: __context__ + + A :class:`TracebackException` of the original ``__context__``. + + .. attribute:: __suppress_context__ + + The ``__suppress_context__`` value from the original exception. + + .. attribute:: stack + + A :class:`StackSummary` representing the traceback. + + .. attribute:: exc_type + + The class of the original traceback. + + .. attribute:: filename + + For syntax errors - the file name where the error occurred. + + .. attribute:: lineno + + For syntax errors - the line number where the error occurred. + + .. attribute:: text + + For syntax errors - the text where the error occurred. + + .. attribute:: offset + + For syntax errors - the offset into the text where the error occurred. + + .. attribute:: msg + + For syntax errors - the compiler error message. + + .. classmethod:: from_exception(exc, *, limit=None, lookup_lines=True, capture_locals=False) + + Capture an exception for later rendering. *limit*, *lookup_lines* and + *capture_locals* are as for the :class:`StackSummary` class. + + Note that when locals are captured, they are also shown in the traceback. + + .. method:: format(*, chain=True) + + Format the exception. + + If *chain* is not ``True``, ``__cause__`` and ``__context__`` will not + be formatted. + + The return value is a generator of strings, each ending in a newline and + some containing internal newlines. :func:`~traceback.print_exception` + is a wrapper around this method which just prints the lines to a file. + + The message indicating which exception occurred is always the last + string in the output. + + .. method:: format_exception_only() + + Format the exception part of the traceback. + + The return value is a generator of strings, each ending in a newline. + + Normally, the generator emits a single string; however, for + :exc:`SyntaxError` exceptions, it emits several lines that (when + printed) display detailed information about where the syntax + error occurred. + + The message indicating which exception occurred is always the last + string in the output. + + +:class:`StackSummary` Objects +----------------------------- + +.. versionadded:: 3.5 + +:class:`StackSummary` objects represent a call stack ready for formatting. + +.. class:: StackSummary + + .. classmethod:: extract(frame_gen, *, limit=None, lookup_lines=True, capture_locals=False) + + Construct a :class:`StackSummary` object from a frame generator (such as + is returned by :func:`~traceback.walk_stack` or + :func:`~traceback.walk_tb`). + + If *limit* is supplied, only this many frames are taken from *frame_gen*. + If *lookup_lines* is ``False``, the returned :class:`FrameSummary` + objects will not have read their lines in yet, making the cost of + creating the :class:`StackSummary` cheaper (which may be valuable if it + may not actually get formatted). If *capture_locals* is ``True`` the + local variables in each :class:`FrameSummary` are captured as object + representations. + + .. classmethod:: from_list(a_list) + + Construct a :class:`StackSummary` object from a supplied old-style list + of tuples. Each tuple should be a 4-tuple with filename, lineno, name, + line as the elements. + + +:class:`FrameSummary` Objects +----------------------------- + +.. versionadded:: 3.5 + +:class:`FrameSummary` objects represent a single frame in a traceback. + +.. class:: FrameSummary(filename, lineno, name, lookup_line=True, locals=None, line=None) + + Represent a single frame in the traceback or stack that is being formatted + or printed. It may optionally have a stringified version of the frames + locals included in it. If *lookup_line* is ``False``, the source code is not + looked up until the :class:`FrameSummary` has the :attr:`~FrameSummary.line` + attribute accessed (which also happens when casting it to a tuple). + :attr:`~FrameSummary.line` may be directly provided, and will prevent line + lookups happening at all. *locals* is an optional local variable + dictionary, and if supplied the variable representations are stored in the + summary for later display. .. _traceback-example: diff --git a/Doc/library/tracemalloc.rst b/Doc/library/tracemalloc.rst index d4067825d223..13c81a7fedcb 100644 --- a/Doc/library/tracemalloc.rst +++ b/Doc/library/tracemalloc.rst @@ -4,6 +4,8 @@ .. module:: tracemalloc :synopsis: Trace memory allocations. +.. versionadded:: 3.4 + The tracemalloc module is a debug tool to trace memory blocks allocated by Python. It provides the following information: @@ -23,14 +25,12 @@ frame (1 frame). To store 25 frames at startup: set the :envvar:`PYTHONTRACEMALLOC` environment variable to ``25``, or use the :option:`-X` ``tracemalloc=25`` command line option. -.. versionadded:: 3.4 - Examples -======== +-------- Display the top 10 ------------------- +^^^^^^^^^^^^^^^^^^ Display the 10 files allocating the most memory:: @@ -70,7 +70,7 @@ See :meth:`Snapshot.statistics` for more options. Compute differences -------------------- +^^^^^^^^^^^^^^^^^^^ Take two snapshots and display the differences:: @@ -114,11 +114,10 @@ the :meth:`Snapshot.dump` method to analyze the snapshot offline. Then use the Get the traceback of a memory block ------------------------------------ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Code to display the traceback of the biggest memory block:: - import linecache import tracemalloc # Store 25 frames @@ -132,12 +131,8 @@ Code to display the traceback of the biggest memory block:: # pick the biggest memory block stat = top_stats[0] print("%s memory blocks: %.1f KiB" % (stat.count, stat.size / 1024)) - for frame in stat.traceback: - print(' File "%s", line %s' % (frame.filename, frame.lineno)) - line = linecache.getline(frame.filename, frame.lineno) - line = line.strip() - if line: - print(' ' + line) + for line in stat.traceback.format(): + print(line) Example of output of the Python test suite (traceback limited to 25 frames):: @@ -184,11 +179,12 @@ loaded. Pretty top ----------- +^^^^^^^^^^ Code to display the 10 lines allocating the most memory with a pretty output, ignoring ``<frozen importlib._bootstrap>`` and ``<unknown>`` files:: + import linecache import os import tracemalloc @@ -205,8 +201,10 @@ ignoring ``<frozen importlib._bootstrap>`` and ``<unknown>`` files:: # replace "/path/to/module/file.py" with "module/file.py" filename = os.sep.join(frame.filename.split(os.sep)[-2:]) print("#%s: %s:%s: %.1f KiB" - % (index, filename, frame.lineno, - stat.size / 1024)) + % (index, filename, frame.lineno, stat.size / 1024)) + line = linecache.getline(frame.filename, frame.lineno).strip() + if line: + print(' %s' % line) other = top_stats[limit:] if other: @@ -220,32 +218,41 @@ ignoring ``<frozen importlib._bootstrap>`` and ``<unknown>`` files:: # ... run your application ... snapshot = tracemalloc.take_snapshot() - display_top(snapshot, 10) + display_top(snapshot) Example of output of the Python test suite:: - 2013-11-08 14:16:58.149320: Top 10 lines - #1: collections/__init__.py:368: 291.9 KiB - #2: Lib/doctest.py:1291: 200.2 KiB - #3: unittest/case.py:571: 160.3 KiB - #4: Lib/abc.py:133: 99.8 KiB - #5: urllib/parse.py:476: 71.8 KiB - #6: <string>:5: 62.7 KiB - #7: Lib/base64.py:140: 59.8 KiB - #8: Lib/_weakrefset.py:37: 51.8 KiB - #9: collections/__init__.py:362: 50.6 KiB - #10: test/test_site.py:56: 48.0 KiB - 7496 other: 4161.9 KiB - Total allocated size: 5258.8 KiB + Top 10 lines + #1: Lib/base64.py:414: 419.8 KiB + _b85chars2 = [(a + b) for a in _b85chars for b in _b85chars] + #2: Lib/base64.py:306: 419.8 KiB + _a85chars2 = [(a + b) for a in _a85chars for b in _a85chars] + #3: collections/__init__.py:368: 293.6 KiB + exec(class_definition, namespace) + #4: Lib/abc.py:133: 115.2 KiB + cls = super().__new__(mcls, name, bases, namespace) + #5: unittest/case.py:574: 103.1 KiB + testMethod() + #6: Lib/linecache.py:127: 95.4 KiB + lines = fp.readlines() + #7: urllib/parse.py:476: 71.8 KiB + for a in _hexdig for b in _hexdig} + #8: <string>:5: 62.0 KiB + #9: Lib/_weakrefset.py:37: 60.0 KiB + self.data = set() + #10: Lib/base64.py:142: 59.8 KiB + _b32tab2 = [a + b for a in _b32tab for b in _b32tab] + 6220 other: 3602.8 KiB + Total allocated size: 5303.1 KiB See :meth:`Snapshot.statistics` for more options. API -=== +--- Functions ---------- +^^^^^^^^^ .. function:: clear_traces() @@ -343,20 +350,20 @@ Functions the *nframe* parameter of the :func:`start` function to store more frames. The :mod:`tracemalloc` module must be tracing memory allocations to take a - snapshot, see the the :func:`start` function. + snapshot, see the :func:`start` function. See also the :func:`get_object_traceback` function. Filter ------- +^^^^^^ .. class:: Filter(inclusive: bool, filename_pattern: str, lineno: int=None, all_frames: bool=False) Filter on traces of memory blocks. See the :func:`fnmatch.fnmatch` function for the syntax of - *filename_pattern*. The ``'.pyc'`` and ``'.pyo'`` file extensions are + *filename_pattern*. The ``'.pyc'`` file extension is replaced with ``'.py'``. Examples: @@ -367,6 +374,10 @@ Filter :mod:`tracemalloc` module * ``Filter(False, "<unknown>")`` excludes empty tracebacks + + .. versionchanged:: 3.5 + The ``'.pyo'`` file extension is no longer replaced with ``'.py'``. + .. attribute:: inclusive If *inclusive* is ``True`` (include), only trace memory blocks allocated @@ -397,7 +408,7 @@ Filter Frame ------ +^^^^^ .. class:: Frame @@ -415,7 +426,7 @@ Frame Snapshot --------- +^^^^^^^^ .. class:: Snapshot @@ -428,7 +439,7 @@ Snapshot Compute the differences with an old snapshot. Get statistics as a sorted list of :class:`StatisticDiff` instances grouped by *group_by*. - See the :meth:`statistics` method for *group_by* and *cumulative* + See the :meth:`Snapshot.statistics` method for *group_by* and *cumulative* parameters. The result is sorted from the biggest to the smallest by: absolute value @@ -501,7 +512,7 @@ Snapshot Statistic ---------- +^^^^^^^^^ .. class:: Statistic @@ -526,7 +537,7 @@ Statistic StatisticDiff -------------- +^^^^^^^^^^^^^ .. class:: StatisticDiff @@ -565,7 +576,7 @@ StatisticDiff Trace ------ +^^^^^ .. class:: Trace @@ -585,7 +596,7 @@ Trace Traceback ---------- +^^^^^^^^^ .. class:: Traceback @@ -602,4 +613,25 @@ Traceback The :attr:`Trace.traceback` attribute is an instance of :class:`Traceback` instance. + .. method:: format(limit=None) + + Format the traceback as a list of lines with newlines. Use the + :mod:`linecache` module to retrieve lines from the source code. If + *limit* is set, only format the *limit* most recent frames. + + Similar to the :func:`traceback.format_tb` function, except that + :meth:`format` does not include newlines. + + Example:: + + print("Traceback (most recent call first):") + for line in traceback: + print(line) + + Output:: + Traceback (most recent call first): + File "test.py", line 9 + obj = Object() + File "test.py", line 12 + tb = tracemalloc.get_object_traceback(f()) diff --git a/Doc/library/tulip_coro.dia b/Doc/library/tulip_coro.dia new file mode 100644 index 000000000000..70a33e3c00cf Binary files /dev/null and b/Doc/library/tulip_coro.dia differ diff --git a/Doc/library/tulip_coro.png b/Doc/library/tulip_coro.png new file mode 100644 index 000000000000..36ced8ddbfd9 Binary files /dev/null and b/Doc/library/tulip_coro.png differ diff --git a/Doc/library/turtle.rst b/Doc/library/turtle.rst index b015530cca5f..30dd6eff2d59 100644 --- a/Doc/library/turtle.rst +++ b/Doc/library/turtle.rst @@ -1809,7 +1809,7 @@ Input methods Pop up a dialog window for input of a number. title is the title of the dialog window, prompt is a text mostly describing what numerical information - to input. default: default value, minval: minimum value for imput, + to input. default: default value, minval: minimum value for input, maxval: maximum value for input The number input must be in the range minval .. maxval if these are given. If not, a hint is issued and the dialog remains open for @@ -1879,7 +1879,7 @@ Settings and special methods >>> cv = screen.getcanvas() >>> cv - <turtle.ScrolledCanvas object at ...> + <turtle.ScrolledCanvas object ...> .. function:: getshapes() @@ -1981,7 +1981,7 @@ Methods specific to Screen, not inherited from TurtleScreen :param startx: if positive, starting position in pixels from the left edge of the screen, if negative from the right edge, if None, center window horizontally - :param startx: if positive, starting position in pixels from the top + :param starty: if positive, starting position in pixels from the top edge of the screen, if negative from the bottom edge, if None, center window vertically @@ -2274,10 +2274,13 @@ study it as an example and see its effects when running the demos (preferably not from within the demo-viewer). -Demo scripts -============ +:mod:`turtledemo` --- Demo scripts +================================== + +.. module:: turtledemo + :synopsis: A viewer for example turtle scripts -There is a set of demo scripts in the :mod:`turtledemo` package. These +The :mod:`turtledemo` package includes a set of demo scripts. These scripts can be run and viewed using the supplied demo viewer as follows:: python -m turtledemo @@ -2288,16 +2291,13 @@ Alternatively, you can run the demo scripts individually. For example, :: The :mod:`turtledemo` package directory contains: -- a set of 15 demo scripts demonstrating different features of the new module - :mod:`turtle`; -- a demo viewer :file:`__main__.py` which can be used to view the sourcecode - of the scripts and run them at the same time. 14 of the examples can be - accessed via the Examples menu; all of them can also be run standalone. -- The example :mod:`turtledemo.two_canvases` demonstrates the simultaneous - use of two canvases with the turtle module. Therefore it only can be run - standalone. -- There is a :file:`turtle.cfg` file in this directory, which serves as an - example for how to write and use such files. +- A demo viewer :file:`__main__.py` which can be used to view the sourcecode + of the scripts and run them at the same time. +- Multiple scripts demonstrating different features of the :mod:`turtle` + module. Examples can be accessed via the Examples menu. They can also + be run standalone. +- A :file:`turtle.cfg` file which serves as an example of how to write + and use such files. The demo scripts are: @@ -2320,6 +2320,8 @@ The demo scripts are: +----------------+------------------------------+-----------------------+ | colormixer | experiment with r, g, b | :func:`ondrag` | +----------------+------------------------------+-----------------------+ +| forest | 3 breadth-first trees | randomization | ++----------------+------------------------------+-----------------------+ | fractalcurves | Hilbert & Koch curves | recursion | +----------------+------------------------------+-----------------------+ | lindenmayer | ethnomathematics | L-System | @@ -2349,9 +2351,15 @@ The demo scripts are: | | pairwise in opposite | shapesize, tilt, | | | direction | get_shapepoly, update | +----------------+------------------------------+-----------------------+ +| sorting_animate| visual demonstration of | simple alignment, | +| | different sorting methods | randomization | ++----------------+------------------------------+-----------------------+ | tree | a (graphical) breadth | :func:`clone` | | | first tree (using generators)| | +----------------+------------------------------+-----------------------+ +| two_canvases | simple design | turtles on two | +| | | canvases | ++----------------+------------------------------+-----------------------+ | wikipedia | a pattern from the wikipedia | :func:`clone`, | | | article on turtle graphics | :func:`undo` | +----------------+------------------------------+-----------------------+ @@ -2397,7 +2405,7 @@ Changes since Python 3.0 Accordingly the latter has got an alias: :meth:`Screen.onkeyrelease`. - The method :meth:`Screen.mainloop` has been added. So when working only - with Screen and Turtle objects one must not additonally import + with Screen and Turtle objects one must not additionally import :func:`mainloop` anymore. - Two input methods has been added :meth:`Screen.textinput` and diff --git a/Doc/library/types.rst b/Doc/library/types.rst index c4f57e43af31..eb27846aab2c 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -15,6 +15,9 @@ It also defines names for some object types that are used by the standard Python interpreter, but not exposed as builtins like :class:`int` or :class:`str` are. +Finally, it provides some additional type-related utility classes and functions +that are not fundamental enough to be builtins. + Dynamic Type Creation --------------------- @@ -83,8 +86,16 @@ Standard names are defined for the following types: .. data:: GeneratorType - The type of :term:`generator`-iterator objects, produced by calling a - generator function. + The type of :term:`generator`-iterator objects, created by + generator functions. + + +.. data:: CoroutineType + + The type of :term:`coroutine` objects, created by + :keyword:`async def` functions. + + .. versionadded:: 3.5 .. data:: CodeType @@ -112,6 +123,10 @@ Standard names are defined for the following types: The type of :term:`modules <module>`. Constructor takes the name of the module to be created and optionally its :term:`docstring`. + .. note:: + Use :func:`importlib.util.module_from_spec` to create a new module if you + wish to set the various import-controlled attributes. + .. attribute:: __doc__ The :term:`docstring` of the module. Defaults to ``None``. @@ -220,6 +235,9 @@ Standard names are defined for the following types: Return a new view of the underlying mapping's values. +Additional Utility Classes and Functions +---------------------------------------- + .. class:: SimpleNamespace A simple :class:`object` subclass that provides attribute access to its @@ -246,3 +264,40 @@ Standard names are defined for the following types: instead. .. versionadded:: 3.3 + + +.. function:: DynamicClassAttribute(fget=None, fset=None, fdel=None, doc=None) + + Route attribute access on a class to __getattr__. + + This is a descriptor, used to define attributes that act differently when + accessed through an instance and through a class. Instance access remains + normal, but access to an attribute through a class will be routed to the + class's __getattr__ method; this is done by raising AttributeError. + + This allows one to have properties active on an instance, and have virtual + attributes on the class with the same name (see Enum for an example). + + .. versionadded:: 3.4 + + +Coroutine Utility Functions +--------------------------- + +.. function:: coroutine(gen_func) + + This function transforms a :term:`generator` function into a + :term:`coroutine function` which returns a generator-based coroutine. + The generator-based coroutine is still a :term:`generator iterator`, + but is also considered to be a :term:`coroutine` object and is + :term:`awaitable`. However, it may not necessarily implement + the :meth:`__await__` method. + + If *gen_func* is a generator function, it will be modified in-place. + + If *gen_func* is not a generator function, it will be wrapped. If it + returns an instance of :class:`collections.abc.Generator`, the instance + will be wrapped in an *awaitable* proxy object. All other types + of objects will be returned as is. + + .. versionadded:: 3.5 diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst new file mode 100644 index 000000000000..668523b52d9b --- /dev/null +++ b/Doc/library/typing.rst @@ -0,0 +1,524 @@ +:mod:`typing` --- Support for type hints +======================================== + +.. module:: typing + :synopsis: Support for type hints (see PEP 484). + +**Source code:** :source:`Lib/typing.py` + +-------------- + +This module supports type hints as specified by :pep:`484`. The most +fundamental support consists of the type :class:`Any`, :class:`Union`, +:class:`Tuple`, :class:`Callable`, :class:`TypeVar`, and +:class:`Generic`. For full specification please see :pep:`484`. For +a simplified introduction to type hints see :pep:`483`. + + +The function below takes and returns a string and is annotated as follows:: + + def greeting(name: str) -> str: + return 'Hello ' + name + +In the function ``greeting``, the argument ``name`` is expected to by of type +:class:`str` and the return type :class:`str`. Subtypes are accepted as +arguments. + +Type aliases +------------ + +A type alias is defined by assigning the type to the alias:: + + Vector = List[float] + +Callable +-------- + +Frameworks expecting callback functions of specific signatures might be +type hinted using ``Callable[[Arg1Type, Arg2Type], ReturnType]``. + +For example:: + + from typing import Callable + + def feeder(get_next_item: Callable[[], str]) -> None: + # Body + + def async_query(on_success: Callable[[int], None], + on_error: Callable[[int, Exception], None]) -> None: + # Body + +It is possible to declare the return type of a callable without specifying +the call signature by substituting a literal ellipsis +for the list of arguments in the type hint: ``Callable[..., ReturnType]``. +``None`` as a type hint is a special case and is replaced by ``type(None)``. + +Generics +-------- + +Since type information about objects kept in containers cannot be statically +inferred in a generic way, abstract base classes have been extended to support +subscription to denote expected types for container elements. + +:: + + from typing import Mapping, Sequence + + def notify_by_email(employees: Sequence[Employee], + overrides: Mapping[str, str]) -> None: ... + +Generics can be parametrized by using a new factory available in typing +called :class:`TypeVar`. + +:: + + from typing import Sequence, TypeVar + + T = TypeVar('T') # Declare type variable + + def first(l: Sequence[T]) -> T: # Generic function + return l[0] + + +User-defined generic types +-------------------------- + +A user-defined class can be defined as a generic class. + +:: + + from typing import TypeVar, Generic + from logging import Logger + + T = TypeVar('T') + + class LoggedVar(Generic[T]): + def __init__(self, value: T, name: str, logger: Logger) -> None: + self.name = name + self.logger = logger + self.value = value + + def set(self, new: T) -> None: + self.log('Set ' + repr(self.value)) + self.value = new + + def get(self) -> T: + self.log('Get ' + repr(self.value)) + return self.value + + def log(self, message: str) -> None: + self.logger.info('{}: {}'.format(self.name, message)) + +``Generic[T]`` as a base class defines that the class ``LoggedVar`` takes a +single type parameter ``T`` . This also makes ``T`` valid as a type within the +class body. + +The :class:`Generic` base class uses a metaclass that defines +:meth:`__getitem__` so that ``LoggedVar[t]`` is valid as a type:: + + from typing import Iterable + + def zero_all_vars(vars: Iterable[LoggedVar[int]]) -> None: + for var in vars: + var.set(0) + +A generic type can have any number of type variables, and type variables may +be constrained:: + + from typing import TypeVar, Generic + ... + + T = TypeVar('T') + S = TypeVar('S', int, str) + + class StrangePair(Generic[T, S]): + ... + +Each type variable argument to :class:`Generic` must be distinct. +This is thus invalid:: + + from typing import TypeVar, Generic + ... + + T = TypeVar('T') + + class Pair(Generic[T, T]): # INVALID + ... + +You can use multiple inheritance with :class:`Generic`:: + + from typing import TypeVar, Generic, Sized + + T = TypeVar('T') + + class LinkedList(Sized, Generic[T]): + ... + +When inheriting from generic classes, some type variables could fixed:: + + from typing import TypeVar, Mapping + + T = TypeVar('T') + + class MyDict(Mapping[str, T]): + ... + +In this case ``MyDict`` has a single parameter, ``T``. + +Subclassing a generic class without specifying type parameters assumes +:class:`Any` for each position. In the following example, ``MyIterable`` is +not generic but implicitly inherits from ``Iterable[Any]``:: + + from typing import Iterable + + class MyIterable(Iterable): # Same as Iterable[Any] + +The metaclass used by :class:`Generic` is a subclass of :class:`abc.ABCMeta`. +A generic class can be an ABC by including abstract methods or properties, +and generic classes can also have ABCs as base classes without a metaclass +conflict. Generic metaclasses are not supported. + + +The :class:`Any` type +--------------------- + +A special kind of type is :class:`Any`. Every type is a subtype of +:class:`Any`. This is also true for the builtin type object. However, to the +static type checker these are completely different. + +When the type of a value is :class:`object`, the type checker will reject +almost all operations on it, and assigning it to a variable (or using it as a +return value) of a more specialized type is a type error. On the other hand, +when a value has type :class:`Any`, the type checker will allow all operations +on it, and a value of type :class:`Any` can be assigned to a variable (or used +as a return value) of a more constrained type. + + +Classes, functions, and decorators +---------------------------------- + +The module defines the following classes, functions and decorators: + +.. class:: Any + + Special type indicating an unconstrained type. + + * Any object is an instance of :class:`Any`. + * Any class is a subclass of :class:`Any`. + * As a special case, :class:`Any` and :class:`object` are subclasses of + each other. + +.. class:: TypeVar + + Type variable. + + Usage:: + + T = TypeVar('T') # Can be anything + A = TypeVar('A', str, bytes) # Must be str or bytes + + Type variables exist primarily for the benefit of static type + checkers. They serve as the parameters for generic types as well + as for generic function definitions. See class Generic for more + information on generic types. Generic functions work as follows:: + + def repeat(x: T, n: int) -> Sequence[T]: + """Return a list containing n references to x.""" + return [x]*n + + def longest(x: A, y: A) -> A: + """Return the longest of two strings.""" + return x if len(x) >= len(y) else y + + The latter example's signature is essentially the overloading + of ``(str, str) -> str`` and ``(bytes, bytes) -> bytes``. Also note + that if the arguments are instances of some subclass of :class:`str`, + the return type is still plain :class:`str`. + + At runtime, ``isinstance(x, T)`` will raise :exc:`TypeError`. In general, + :func:`isinstance` and :func:`issubclass` should not be used with types. + + Type variables may be marked covariant or contravariant by passing + ``covariant=True`` or ``contravariant=True``. See :pep:`484` for more + details. By default type variables are invariant. Alternatively, + a type variable may specify an upper bound using ``bound=<type>``. + This means that an actual type substituted (explicitly or implicitly) + for the type variable must be a subclass of the boundary type, + see :pep:`484`. + +.. class:: Union + + Union type; ``Union[X, Y]`` means either X or Y. + + To define a union, use e.g. ``Union[int, str]``. Details: + + * The arguments must be types and there must be at least one. + + * Unions of unions are flattened, e.g.:: + + Union[Union[int, str], float] == Union[int, str, float] + + * Unions of a single argument vanish, e.g.:: + + Union[int] == int # The constructor actually returns int + + * Redundant arguments are skipped, e.g.:: + + Union[int, str, int] == Union[int, str] + + * When comparing unions, the argument order is ignored, e.g.:: + + Union[int, str] == Union[str, int] + + * If :class:`Any` is present it is the sole survivor, e.g.:: + + Union[int, Any] == Any + + * You cannot subclass or instantiate a union. + + * You cannot write ``Union[X][Y]``. + + * You can use ``Optional[X]`` as a shorthand for ``Union[X, None]``. + +.. class:: Optional + + Optional type. + + ``Optional[X]`` is equivalent to ``Union[X, type(None)]``. + +.. class:: Tuple + + Tuple type; ``Tuple[X, Y]`` is the is the type of a tuple of two items + with the first item of type X and the second of type Y. + + Example: ``Tuple[T1, T2]`` is a tuple of two elements corresponding + to type variables T1 and T2. ``Tuple[int, float, str]`` is a tuple + of an int, a float and a string. + + To specify a variable-length tuple of homogeneous type, + use literal ellipsis, e.g. ``Tuple[int, ...]``. + +.. class:: Callable + + Callable type; ``Callable[[int], str]`` is a function of (int) -> str. + + The subscription syntax must always be used with exactly two + values: the argument list and the return type. The argument list + must be a list of types; the return type must be a single type. + + There is no syntax to indicate optional or keyword arguments, + such function types are rarely used as callback types. + ``Callable[..., ReturnType]`` could be used to type hint a callable + taking any number of arguments and returning ``ReturnType``. + A plain :class:`Callable` is equivalent to ``Callable[..., Any]``. + +.. class:: Generic + + Abstract base class for generic types. + + A generic type is typically declared by inheriting from an + instantiation of this class with one or more type variables. + For example, a generic mapping type might be defined as:: + + class Mapping(Generic[KT, VT]): + def __getitem__(self, key: KT) -> VT: + ... + # Etc. + + This class can then be used as follows:: + + X = TypeVar('X') + Y = TypeVar('Y') + + def lookup_name(mapping: Mapping[X, Y], key: X, default: Y) -> Y: + try: + return mapping[key] + except KeyError: + return default + +.. class:: Iterable(Generic[T_co]) + + A generic version of the :class:`collections.abc.Iterable`. + +.. class:: Iterator(Iterable[T_co]) + + A generic version of the :class:`collections.abc.Iterator`. + +.. class:: SupportsInt + + An ABC with one abstract method ``__int__``. + +.. class:: SupportsFloat + + An ABC with one abstract method ``__float__``. + +.. class:: SupportsAbs + + An ABC with one abstract method ``__abs__`` that is covariant + in its return type. + +.. class:: SupportsRound + + An ABC with one abstract method ``__round__`` + that is covariant in its return type. + +.. class:: Reversible + + An ABC with one abstract method ``__reversed__`` returning + an ``Iterator[T_co]``. + +.. class:: Container(Generic[T_co]) + + A generic version of :class:`collections.abc.Container`. + +.. class:: AbstractSet(Sized, Iterable[T_co], Container[T_co]) + + A generic version of :class:`collections.abc.Set`. + +.. class:: MutableSet(AbstractSet[T]) + + A generic version of :class:`collections.abc.MutableSet`. + +.. class:: Mapping(Sized, Iterable[KT], Container[KT], Generic[VT_co]) + + A generic version of :class:`collections.abc.Mapping`. + +.. class:: MutableMapping(Mapping[KT, VT]) + + A generic version of :class:`collections.abc.MutableMapping`. + +.. class:: Sequence(Sized, Iterable[T_co], Container[T_co]) + + A generic version of :class:`collections.abc.Sequence`. + +.. class:: MutableSequence(Sequence[T]) + + A generic version of :class:`collections.abc.MutableSequence`. + +.. class:: ByteString(Sequence[int]) + + A generic version of :class:`collections.abc.ByteString`. + + This type represents the types :class:`bytes`, :class:`bytearray`, + and :class:`memoryview`. + + As a shorthand for this type, :class:`bytes` can be used to + annotate arguments of any of the types mentioned above. + +.. class:: List(list, MutableSequence[T]) + + Generic version of :class:`list`. + Useful for annotating return types. To annotate arguments it is preferred + to use abstract collection types such as :class:`Mapping`, :class:`Sequence`, + or :class:`AbstractSet`. + + This type may be used as follows:: + + T = TypeVar('T', int, float) + + def vec2(x: T, y: T) -> List[T]: + return [x, y] + + def slice__to_4(vector: Sequence[T]) -> List[T]: + return vector[0:4] + +.. class:: AbstractSet(set, MutableSet[T]) + + A generic version of :class:`collections.abc.Set`. + +.. class:: MappingView(Sized, Iterable[T_co]) + + A generic version of :class:`collections.abc.MappingView`. + +.. class:: KeysView(MappingView[KT_co], AbstractSet[KT_co]) + + A generic version of :class:`collections.abc.KeysView`. + +.. class:: ItemsView(MappingView, Generic[KT_co, VT_co]) + + A generic version of :class:`collections.abc.ItemsView`. + +.. class:: ValuesView(MappingView[VT_co]) + + A generic version of :class:`collections.abc.ValuesView`. + +.. class:: Dict(dict, MutableMapping[KT, VT]) + + A generic version of :class:`dict`. + The usage of this type is as follows:: + + def get_position_in_index(word_list: Dict[str, int], word: str) -> int: + return word_list[word] + +.. class:: Generator(Iterator[T_co], Generic[T_co, T_contra, V_co]) + +.. class:: io + + Wrapper namespace for I/O stream types. + + This defines the generic type ``IO[AnyStr]`` and aliases ``TextIO`` + and ``BinaryIO`` for respectively ``IO[str]`` and ``IO[bytes]``. + These representing the types of I/O streams such as returned by + :func:`open`. + +.. class:: re + + Wrapper namespace for regular expression matching types. + + This defines the type aliases ``Pattern`` and ``Match`` which + correspond to the return types from :func:`re.compile` and + :func:`re.match`. These types (and the corresponding functions) + are generic in ``AnyStr`` and can be made specific by writing + ``Pattern[str]``, ``Pattern[bytes]``, ``Match[str]``, or + ``Match[bytes]``. + +.. function:: NamedTuple(typename, fields) + + Typed version of namedtuple. + + Usage:: + + Employee = typing.NamedTuple('Employee', [('name', str), 'id', int)]) + + This is equivalent to:: + + Employee = collections.namedtuple('Employee', ['name', 'id']) + + The resulting class has one extra attribute: _field_types, + giving a dict mapping field names to types. (The field names + are in the _fields attribute, which is part of the namedtuple + API.) + +.. function:: cast(typ, val) + + Cast a value to a type. + + This returns the value unchanged. To the type checker this + signals that the return value has the designated type, but at + runtime we intentionally don't check anything (we want this + to be as fast as possible). + +.. function:: get_type_hints(obj) + + Return type hints for a function or method object. + + This is often the same as ``obj.__annotations__``, but it handles + forward references encoded as string literals, and if necessary + adds ``Optional[t]`` if a default value equal to None is set. + +.. decorator:: no_type_check(arg) + + Decorator to indicate that annotations are not type hints. + + The argument must be a class or function; if it is a class, it + applies recursively to all methods defined in that class (but not + to methods defined in its superclasses or subclasses). + + This mutates the function(s) in place. + +.. decorator:: no_type_check_decorator(decorator) + + Decorator to give another decorator the :func:`no_type_check` effect. + + This wraps the decorator with something that wraps the decorated + function in :func:`no_type_check`. diff --git a/Doc/library/undoc.rst b/Doc/library/undoc.rst index 80386d240c1e..20830e296396 100644 --- a/Doc/library/undoc.rst +++ b/Doc/library/undoc.rst @@ -20,7 +20,7 @@ These modules are used to implement the :mod:`os.path` module, and are not documented beyond this mention. There's little need to document these. :mod:`ntpath` - --- Implementation of :mod:`os.path` on Win32, Win64, WinCE, and OS/2 platforms. + --- Implementation of :mod:`os.path` on Win32, Win64, and WinCE platforms. :mod:`posixpath` --- Implementation of :mod:`os.path` on POSIX. diff --git a/Doc/library/unicodedata.rst b/Doc/library/unicodedata.rst index 3b3d3a0a8f7d..1430d9b4033a 100644 --- a/Doc/library/unicodedata.rst +++ b/Doc/library/unicodedata.rst @@ -15,8 +15,8 @@ This module provides access to the Unicode Character Database (UCD) which defines character properties for all Unicode characters. The data contained in -this database is compiled from the `UCD version 6.3.0 -<http://www.unicode.org/Public/6.3.0/ucd>`_. +this database is compiled from the `UCD version 8.0.0 +<http://www.unicode.org/Public/8.0.0/ucd>`_. The module uses the same names and symbols as defined by Unicode Standard Annex #44, `"Unicode Character Database" @@ -166,6 +166,6 @@ Examples: .. rubric:: Footnotes -.. [#] http://www.unicode.org/Public/6.3.0/ucd/NameAliases.txt +.. [#] http://www.unicode.org/Public/8.0.0/ucd/NameAliases.txt -.. [#] http://www.unicode.org/Public/6.3.0/ucd/NamedSequences.txt +.. [#] http://www.unicode.org/Public/8.0.0/ucd/NamedSequences.txt diff --git a/Doc/library/unittest.mock-examples.rst b/Doc/library/unittest.mock-examples.rst index 444c20897eea..055abe0de1ce 100644 --- a/Doc/library/unittest.mock-examples.rst +++ b/Doc/library/unittest.mock-examples.rst @@ -28,22 +28,22 @@ it is called with the correct arguments by another part of the system: >>> real.method(3, 4, 5, key='value') <MagicMock name='method()' id='...'> -Once our mock has been used (`real.method` in this example) it has methods +Once our mock has been used (``real.method`` in this example) it has methods and attributes that allow you to make assertions about how it has been used. .. note:: In most of these examples the :class:`Mock` and :class:`MagicMock` classes - are interchangeable. As the `MagicMock` is the more capable class it makes + are interchangeable. As the ``MagicMock`` is the more capable class it makes a sensible one to use by default. Once the mock has been called its :attr:`~Mock.called` attribute is set to -`True`. More importantly we can use the :meth:`~Mock.assert_called_with` or +``True``. More importantly we can use the :meth:`~Mock.assert_called_with` or :meth:`~Mock.assert_called_once_with` method to check that it was called with the correct arguments. -This example tests that calling `ProductionClass().method` results in a call to -the `something` method: +This example tests that calling ``ProductionClass().method`` results in a call to +the ``something`` method: >>> class ProductionClass: ... def method(self): @@ -66,15 +66,15 @@ was called correctly. Another common use case is to pass an object into a method (or some part of the system under test) and then check that it is used in the correct way. -The simple `ProductionClass` below has a `closer` method. If it is called with -an object then it calls `close` on it. +The simple ``ProductionClass`` below has a ``closer`` method. If it is called with +an object then it calls ``close`` on it. >>> class ProductionClass: ... def closer(self, something): ... something.close() ... -So to test it we need to pass in an object with a `close` method and check +So to test it we need to pass in an object with a ``close`` method and check that it was called correctly. >>> real = ProductionClass() @@ -96,9 +96,9 @@ When you patch a class, then that class is replaced with a mock. Instances are created by *calling the class*. This means you access the "mock instance" by looking at the return value of the mocked class. -In the example below we have a function `some_function` that instantiates `Foo` -and calls a method on it. The call to `patch` replaces the class `Foo` with a -mock. The `Foo` instance is the result of calling the mock, so it is configured +In the example below we have a function ``some_function`` that instantiates ``Foo`` +and calls a method on it. The call to :func:`patch` replaces the class ``Foo`` with a +mock. The ``Foo`` instance is the result of calling the mock, so it is configured by modifying the mock :attr:`~Mock.return_value`. >>> def some_function(): @@ -141,13 +141,13 @@ to child attributes of the mock - and also to their children. >>> mock.mock_calls [call.method(), call.attribute.method(10, x=53)] -If you make an assertion about `mock_calls` and any unexpected methods +If you make an assertion about ``mock_calls`` and any unexpected methods have been called, then the assertion will fail. This is useful because as well as asserting that the calls you expected have been made, you are also checking that they were made in the right order and with no additional calls: You use the :data:`call` object to construct lists for comparing with -`mock_calls`: +``mock_calls``: >>> expected = [call.method(), call.attribute.method(10, x=53)] >>> mock.mock_calls == expected @@ -185,7 +185,7 @@ If you need an attribute setting on your mock, just do it: 3 Sometimes you want to mock up a more complex situation, like for example -`mock.connection.cursor().execute("SELECT 1")`. If we wanted this call to +``mock.connection.cursor().execute("SELECT 1")``. If we wanted this call to return a list, then we have to configure the result of the nested call. We can use :data:`call` to construct the set of calls in a "chained call" like @@ -202,7 +202,7 @@ this for easy assertion afterwards: >>> mock.mock_calls == expected True -It is the call to `.call_list()` that turns our call object into a list of +It is the call to ``.call_list()`` that turns our call object into a list of calls representing the chained calls. @@ -223,10 +223,10 @@ is called. Side effect functions and iterables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -`side_effect` can also be set to a function or an iterable. The use case for -`side_effect` as an iterable is where your mock is going to be called several +``side_effect`` can also be set to a function or an iterable. The use case for +``side_effect`` as an iterable is where your mock is going to be called several times, and you want each call to return a different value. When you set -`side_effect` to an iterable every call to the mock returns the next value +``side_effect`` to an iterable every call to the mock returns the next value from the iterable: >>> mock = MagicMock(side_effect=[4, 5, 6]) @@ -239,7 +239,7 @@ from the iterable: For more advanced use cases, like dynamically varying the return values -depending on what the mock is called with, `side_effect` can be a function. +depending on what the mock is called with, ``side_effect`` can be a function. The function will be called with the same arguments as the mock. Whatever the function returns is what the call returns: @@ -259,13 +259,13 @@ Creating a Mock from an Existing Object One problem with over use of mocking is that it couples your tests to the implementation of your mocks rather than your real code. Suppose you have a -class that implements `some_method`. In a test for another class, you -provide a mock of this object that *also* provides `some_method`. If later -you refactor the first class, so that it no longer has `some_method` - then +class that implements ``some_method``. In a test for another class, you +provide a mock of this object that *also* provides ``some_method``. If later +you refactor the first class, so that it no longer has ``some_method`` - then your tests will continue to pass even though your code is now broken! -`Mock` allows you to provide an object as a specification for the mock, -using the `spec` keyword argument. Accessing methods / attributes on the +:class:`Mock` allows you to provide an object as a specification for the mock, +using the *spec* keyword argument. Accessing methods / attributes on the mock that don't exist on your specification object will immediately raise an attribute error. If you change the implementation of your specification, then tests that use that class will start failing immediately without you having to @@ -293,7 +293,7 @@ you can use :ref:`auto-speccing <auto-speccing>`. If you want a stronger form of specification that prevents the setting of arbitrary attributes as well as the getting of them then you can use -`spec_set` instead of `spec`. +*spec_set* instead of *spec*. @@ -302,8 +302,8 @@ Patch Decorators .. note:: - With `patch` it matters that you patch objects in the namespace where they - are looked up. This is normally straightforward, but for a quick guide + With :func:`patch` it matters that you patch objects in the namespace where + they are looked up. This is normally straightforward, but for a quick guide read :ref:`where to patch <where-to-patch>`. @@ -313,15 +313,15 @@ is instantiated. Modules and classes are effectively global, so patching on them has to be undone after the test or the patch will persist into other tests and cause hard to diagnose problems. -mock provides three convenient decorators for this: `patch`, `patch.object` and -`patch.dict`. `patch` takes a single string, of the form -`package.module.Class.attribute` to specify the attribute you are patching. It +mock provides three convenient decorators for this: :func:`patch`, :func:`patch.object` and +:func:`patch.dict`. ``patch`` takes a single string, of the form +``package.module.Class.attribute`` to specify the attribute you are patching. It also optionally takes a value that you want the attribute (or class or whatever) to be replaced with. 'patch.object' takes an object and the name of the attribute you would like patched, plus optionally the value to patch it with. -`patch.object`: +``patch.object``: >>> original = SomeClass.attribute >>> @patch.object(SomeClass, 'attribute', sentinel.attribute) @@ -338,8 +338,8 @@ with. ... >>> test() -If you are patching a module (including :mod:`builtins`) then use `patch` -instead of `patch.object`: +If you are patching a module (including :mod:`builtins`) then use :func:`patch` +instead of :func:`patch.object`: >>> mock = MagicMock(return_value=sentinel.file_handle) >>> with patch('builtins.open', mock): @@ -348,7 +348,7 @@ instead of `patch.object`: >>> mock.assert_called_with('filename', 'r') >>> assert handle == sentinel.file_handle, "incorrect file handle returned" -The module name can be 'dotted', in the form `package.module` if needed: +The module name can be 'dotted', in the form ``package.module`` if needed: >>> @patch('package.module.ClassName.attribute', sentinel.attribute) ... def test(): @@ -368,8 +368,8 @@ A nice pattern is to actually decorate test methods themselves: >>> MyTest('test_something').test_something() >>> assert SomeClass.attribute == original -If you want to patch with a Mock, you can use `patch` with only one argument -(or `patch.object` with two arguments). The mock will be created for you and +If you want to patch with a Mock, you can use :func:`patch` with only one argument +(or :func:`patch.object` with two arguments). The mock will be created for you and passed into the test function / method: >>> class MyTest(unittest2.TestCase): @@ -394,7 +394,7 @@ You can stack up multiple patch decorators using this pattern: When you nest patch decorators the mocks are passed in to the decorated function in the same order they applied (the normal *python* order that decorators are applied). This means from the bottom up, so in the example -above the mock for `test_module.ClassName2` is passed in first. +above the mock for ``test_module.ClassName2`` is passed in first. There is also :func:`patch.dict` for setting values in a dictionary just during a scope and restoring the dictionary to its original state when the test @@ -407,9 +407,9 @@ ends: ... >>> assert foo == original -`patch`, `patch.object` and `patch.dict` can all be used as context managers. +``patch``, ``patch.object`` and ``patch.dict`` can all be used as context managers. -Where you use `patch` to create a mock for you, you can get a reference to the +Where you use :func:`patch` to create a mock for you, you can get a reference to the mock using the "as" form of the with statement: >>> class ProductionClass: @@ -424,9 +424,9 @@ mock using the "as" form of the with statement: >>> mock_method.assert_called_with(1, 2, 3) -As an alternative `patch`, `patch.object` and `patch.dict` can be used as +As an alternative ``patch``, ``patch.object`` and ``patch.dict`` can be used as class decorators. When used in this way it is the same as applying the -decorator indvidually to every method whose name starts with "test". +decorator individually to every method whose name starts with "test". .. _further-examples: @@ -443,11 +443,11 @@ Mocking chained calls Mocking chained calls is actually straightforward with mock once you understand the :attr:`~Mock.return_value` attribute. When a mock is called for -the first time, or you fetch its `return_value` before it has been called, a -new `Mock` is created. +the first time, or you fetch its ``return_value`` before it has been called, a +new :class:`Mock` is created. This means that you can see how the object returned from a call to a mocked -object has been used by interrogating the `return_value` mock: +object has been used by interrogating the ``return_value`` mock: >>> mock = Mock() >>> mock().foo(a=2, b=3) @@ -467,28 +467,28 @@ So, suppose we have some code that looks a little bit like this: ... response = self.backend.get_endpoint('foobar').create_call('spam', 'eggs').start_call() ... # more code -Assuming that `BackendProvider` is already well tested, how do we test -`method()`? Specifically, we want to test that the code section `# more -code` uses the response object in the correct way. +Assuming that ``BackendProvider`` is already well tested, how do we test +``method()``? Specifically, we want to test that the code section ``# more +code`` uses the response object in the correct way. As this chain of calls is made from an instance attribute we can monkey patch -the `backend` attribute on a `Something` instance. In this particular case +the ``backend`` attribute on a ``Something`` instance. In this particular case we are only interested in the return value from the final call to -`start_call` so we don't have much configuration to do. Let's assume the +``start_call`` so we don't have much configuration to do. Let's assume the object it returns is 'file-like', so we'll ensure that our response object -uses the builtin `file` as its `spec`. +uses the builtin :func:`open` as its ``spec``. To do this we create a mock instance as our mock backend and create a mock response object for it. To set the response as the return value for that final -`start_call` we could do this: +``start_call`` we could do this:: - `mock_backend.get_endpoint.return_value.create_call.return_value.start_call.return_value = mock_response`. + mock_backend.get_endpoint.return_value.create_call.return_value.start_call.return_value = mock_response We can do that in a slightly nicer way using the :meth:`~Mock.configure_mock` method to directly set the return value for us: >>> something = Something() - >>> mock_response = Mock(spec=file) + >>> mock_response = Mock(spec=open) >>> mock_backend = Mock() >>> config = {'get_endpoint.return_value.create_call.return_value.start_call.return_value': mock_response} >>> mock_backend.configure_mock(**config) @@ -501,7 +501,7 @@ call: Using :attr:`~Mock.mock_calls` we can check the chained call with a single assert. A chained call is several calls in one line of code, so there will be -several entries in `mock_calls`. We can use :meth:`call.call_list` to create +several entries in ``mock_calls``. We can use :meth:`call.call_list` to create this list of calls for us: >>> chained = call.get_endpoint('foobar').create_call('spam', 'eggs').start_call() @@ -512,21 +512,20 @@ this list of calls for us: Partial mocking ~~~~~~~~~~~~~~~ -In some tests I wanted to mock out a call to `datetime.date.today() -<http://docs.python.org/library/datetime.html#datetime.date.today>`_ to return -a known date, but I didn't want to prevent the code under test from -creating new date objects. Unfortunately `datetime.date` is written in C, and -so I couldn't just monkey-patch out the static `date.today` method. +In some tests I wanted to mock out a call to :meth:`datetime.date.today` +to return a known date, but I didn't want to prevent the code under test from +creating new date objects. Unfortunately :class:`datetime.date` is written in C, and +so I couldn't just monkey-patch out the static :meth:`date.today` method. I found a simple way of doing this that involved effectively wrapping the date class with a mock, but passing through calls to the constructor to the real class (and returning real instances). The :func:`patch decorator <patch>` is used here to -mock out the `date` class in the module under test. The :attr:`side_effect` +mock out the ``date`` class in the module under test. The :attr:`side_effect` attribute on the mock date class is then set to a lambda function that returns a real date. When the mock date class is called a real date will be -constructed and returned by `side_effect`. +constructed and returned by ``side_effect``. >>> from datetime import date >>> with patch('mymodule.date') as mock_date: @@ -537,34 +536,32 @@ constructed and returned by `side_effect`. ... assert mymodule.date(2009, 6, 8) == date(2009, 6, 8) ... -Note that we don't patch `datetime.date` globally, we patch `date` in the +Note that we don't patch :class:`datetime.date` globally, we patch ``date`` in the module that *uses* it. See :ref:`where to patch <where-to-patch>`. -When `date.today()` is called a known date is returned, but calls to the -`date(...)` constructor still return normal dates. Without this you can find +When ``date.today()`` is called a known date is returned, but calls to the +``date(...)`` constructor still return normal dates. Without this you can find yourself having to calculate an expected result using exactly the same algorithm as the code under test, which is a classic testing anti-pattern. -Calls to the date constructor are recorded in the `mock_date` attributes -(`call_count` and friends) which may also be useful for your tests. +Calls to the date constructor are recorded in the ``mock_date`` attributes +(``call_count`` and friends) which may also be useful for your tests. An alternative way of dealing with mocking dates, or other builtin classes, is discussed in `this blog entry -<http://williamjohnbert.com/2011/07/how-to-unit-testing-in-django-with-mocking-and-patching/>`_. +<http://www.williamjohnbert.com/2011/07/how-to-unit-testing-in-django-with-mocking-and-patching/>`_. Mocking a Generator Method ~~~~~~~~~~~~~~~~~~~~~~~~~~ -A Python generator is a function or method that uses the `yield statement -<http://docs.python.org/reference/simple_stmts.html#the-yield-statement>`_ to -return a series of values when iterated over [#]_. +A Python generator is a function or method that uses the :keyword:`yield` statement +to return a series of values when iterated over [#]_. A generator method / function is called to return the generator object. It is the generator object that is then iterated over. The protocol method for -iteration is `__iter__ -<http://docs.python.org/library/stdtypes.html#container.__iter__>`_, so we can -mock this using a `MagicMock`. +iteration is :meth:`~container.__iter__`, so we can +mock this using a :class:`MagicMock`. Here's an example class with an "iter" method implemented as a generator: @@ -581,7 +578,7 @@ Here's an example class with an "iter" method implemented as a generator: How would we mock this class, and in particular its "iter" method? To configure the values returned from the iteration (implicit in the call to -`list`), we need to configure the object returned by the call to `foo.iter()`. +:class:`list`), we need to configure the object returned by the call to ``foo.iter()``. >>> mock_foo = MagicMock() >>> mock_foo.iter.return_value = iter([1, 2, 3]) @@ -600,10 +597,10 @@ Applying the same patch to every test method If you want several patches in place for multiple test methods the obvious way is to apply the patch decorators to every method. This can feel like unnecessary -repetition. For Python 2.6 or more recent you can use `patch` (in all its +repetition. For Python 2.6 or more recent you can use :func:`patch` (in all its various forms) as a class decorator. This applies the patches to all test methods on the class. A test method is identified by methods whose names start -with `test`: +with ``test``: >>> @patch('mymodule.SomeClass') ... class MyTest(TestCase): @@ -623,7 +620,7 @@ with `test`: 'something' An alternative way of managing patches is to use the :ref:`start-and-stop`. -These allow you to move the patching into your `setUp` and `tearDown` methods. +These allow you to move the patching into your ``setUp`` and ``tearDown`` methods. >>> class MyTest(TestCase): ... def setUp(self): @@ -639,7 +636,7 @@ These allow you to move the patching into your `setUp` and `tearDown` methods. >>> MyTest('test_foo').run() If you use this technique you must ensure that the patching is "undone" by -calling `stop`. This can be fiddlier than you might think, because if an +calling ``stop``. This can be fiddlier than you might think, because if an exception is raised in the setUp then tearDown is not called. :meth:`unittest.TestCase.addCleanup` makes this easier: @@ -669,13 +666,13 @@ function instead. The :func:`patch` decorator makes it so simple to patch out methods with a mock that having to create a real function becomes a nuisance. -If you pass `autospec=True` to patch then it does the patching with a +If you pass ``autospec=True`` to patch then it does the patching with a *real* function object. This function object has the same signature as the one it is replacing, but delegates to a mock under the hood. You still get your mock auto-created in exactly the same way as before. What it means though, is that if you use it to patch out an unbound method on a class the mocked function will be turned into a bound method if it is fetched from an instance. -It will have `self` passed in as the first argument, which is exactly what I +It will have ``self`` passed in as the first argument, which is exactly what I wanted: >>> class Foo: @@ -690,8 +687,8 @@ wanted: 'foo' >>> mock_foo.assert_called_once_with(foo) -If we don't use `autospec=True` then the unbound method is patched out -with a Mock instance instead, and isn't called with `self`. +If we don't use ``autospec=True`` then the unbound method is patched out +with a Mock instance instead, and isn't called with ``self``. Checking multiple calls with mock @@ -715,7 +712,7 @@ If your mock is only being called once you can use the ... AssertionError: Expected to be called once. Called 2 times. -Both `assert_called_with` and `assert_called_once_with` make assertions about +Both ``assert_called_with`` and ``assert_called_once_with`` make assertions about the *most recent* call. If your mock is going to be called several times, and you want to make assertions about *all* those calls you can use :attr:`~Mock.call_args_list`: @@ -728,8 +725,8 @@ you want to make assertions about *all* those calls you can use [call(1, 2, 3), call(4, 5, 6), call()] The :data:`call` helper makes it easy to make assertions about these calls. You -can build up a list of expected calls and compare it to `call_args_list`. This -looks remarkably similar to the repr of the `call_args_list`: +can build up a list of expected calls and compare it to ``call_args_list``. This +looks remarkably similar to the repr of the ``call_args_list``: >>> expected = [call(1, 2, 3), call(4, 5, 6), call()] >>> mock.call_args_list == expected @@ -740,7 +737,7 @@ Coping with mutable arguments ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Another situation is rare, but can bite you, is when your mock is called with -mutable arguments. `call_args` and `call_args_list` store *references* to the +mutable arguments. ``call_args`` and ``call_args_list`` store *references* to the arguments. If the arguments are mutated by the code under test then you can no longer make assertions about what the values were when the mock was called. @@ -755,28 +752,28 @@ defined in 'mymodule':: frob(val) val.clear() -When we try to test that `grob` calls `frob` with the correct argument look +When we try to test that ``grob`` calls ``frob`` with the correct argument look what happens: >>> with patch('mymodule.frob') as mock_frob: - ... val = set([6]) + ... val = {6} ... mymodule.grob(val) ... >>> val - set([]) - >>> mock_frob.assert_called_with(set([6])) + set() + >>> mock_frob.assert_called_with({6}) Traceback (most recent call last): ... - AssertionError: Expected: ((set([6]),), {}) - Called with: ((set([]),), {}) + AssertionError: Expected: (({6},), {}) + Called with: ((set(),), {}) One possibility would be for mock to copy the arguments you pass in. This could then cause problems if you do assertions that rely on object identity for equality. Here's one solution that uses the :attr:`side_effect` -functionality. If you provide a `side_effect` function for a mock then -`side_effect` will be called with the same args as the mock. This gives us an +functionality. If you provide a ``side_effect`` function for a mock then +``side_effect`` will be called with the same args as the mock. This gives us an opportunity to copy the arguments and store them for later assertions. In this example I'm using *another* mock to store the arguments so that I can use the mock methods for doing the assertion. Again a helper function sets this up for @@ -796,35 +793,35 @@ me. ... >>> with patch('mymodule.frob') as mock_frob: ... new_mock = copy_call_args(mock_frob) - ... val = set([6]) + ... val = {6} ... mymodule.grob(val) ... - >>> new_mock.assert_called_with(set([6])) + >>> new_mock.assert_called_with({6}) >>> new_mock.call_args - call(set([6])) + call({6}) -`copy_call_args` is called with the mock that will be called. It returns a new -mock that we do the assertion on. The `side_effect` function makes a copy of -the args and calls our `new_mock` with the copy. +``copy_call_args`` is called with the mock that will be called. It returns a new +mock that we do the assertion on. The ``side_effect`` function makes a copy of +the args and calls our ``new_mock`` with the copy. .. note:: If your mock is only going to be used once there is an easier way of checking arguments at the point they are called. You can simply do the - checking inside a `side_effect` function. + checking inside a ``side_effect`` function. >>> def side_effect(arg): - ... assert arg == set([6]) + ... assert arg == {6} ... >>> mock = Mock(side_effect=side_effect) - >>> mock(set([6])) + >>> mock({6}) >>> mock(set()) Traceback (most recent call last): ... AssertionError -An alternative approach is to create a subclass of `Mock` or `MagicMock` that -copies (using :func:`copy.deepcopy`) the arguments. +An alternative approach is to create a subclass of :class:`Mock` or +:class:`MagicMock` that copies (using :func:`copy.deepcopy`) the arguments. Here's an example implementation: >>> from copy import deepcopy @@ -842,14 +839,14 @@ Here's an example implementation: >>> c.assert_called_with(arg) Traceback (most recent call last): ... - AssertionError: Expected call: mock(set([1])) - Actual call: mock(set([])) + AssertionError: Expected call: mock({1}) + Actual call: mock(set()) >>> c.foo <CopyingMock name='mock.foo' id='...'> -When you subclass `Mock` or `MagicMock` all dynamically created attributes, -and the `return_value` will use your subclass automatically. That means all -children of a `CopyingMock` will also have the type `CopyingMock`. +When you subclass ``Mock`` or ``MagicMock`` all dynamically created attributes, +and the ``return_value`` will use your subclass automatically. That means all +children of a ``CopyingMock`` will also have the type ``CopyingMock``. Nesting Patches @@ -873,9 +870,9 @@ right: >>> MyTest('test_foo').test_foo() >>> assert mymodule.Foo is original -With unittest `cleanup` functions and the :ref:`start-and-stop` we can +With unittest ``cleanup`` functions and the :ref:`start-and-stop` we can achieve the same effect without the nested indentation. A simple helper -method, `create_patch`, puts the patch in place and returns the created mock +method, ``create_patch``, puts the patch in place and returns the created mock for us: >>> class MyTest(TestCase): @@ -910,11 +907,11 @@ We can do this with :class:`MagicMock`, which will behave like a dictionary, and using :data:`~Mock.side_effect` to delegate dictionary access to a real underlying dictionary that is under our control. -When the `__getitem__` and `__setitem__` methods of our `MagicMock` are called -(normal dictionary access) then `side_effect` is called with the key (and in -the case of `__setitem__` the value too). We can also control what is returned. +When the :meth:`__getitem__` and :meth:`__setitem__` methods of our ``MagicMock`` are called +(normal dictionary access) then ``side_effect`` is called with the key (and in +the case of ``__setitem__`` the value too). We can also control what is returned. -After the `MagicMock` has been used we can use attributes like +After the ``MagicMock`` has been used we can use attributes like :data:`~Mock.call_args_list` to assert about how the dictionary was used: >>> my_dict = {'a': 1, 'b': 2, 'c': 3} @@ -930,23 +927,23 @@ After the `MagicMock` has been used we can use attributes like .. note:: - An alternative to using `MagicMock` is to use `Mock` and *only* provide + An alternative to using ``MagicMock`` is to use ``Mock`` and *only* provide the magic methods you specifically want: >>> mock = Mock() - >>> mock.__setitem__ = Mock(side_effect=getitem) - >>> mock.__getitem__ = Mock(side_effect=setitem) + >>> mock.__getitem__ = Mock(side_effect=getitem) + >>> mock.__setitem__ = Mock(side_effect=setitem) - A *third* option is to use `MagicMock` but passing in `dict` as the `spec` - (or `spec_set`) argument so that the `MagicMock` created only has + A *third* option is to use ``MagicMock`` but passing in ``dict`` as the *spec* + (or *spec_set*) argument so that the ``MagicMock`` created only has dictionary magic methods available: >>> mock = MagicMock(spec_set=dict) >>> mock.__getitem__.side_effect = getitem >>> mock.__setitem__.side_effect = setitem -With these side effect functions in place, the `mock` will behave like a normal -dictionary but recording the access. It even raises a `KeyError` if you try +With these side effect functions in place, the ``mock`` will behave like a normal +dictionary but recording the access. It even raises a :exc:`KeyError` if you try to access a key that doesn't exist. >>> mock['a'] @@ -978,8 +975,8 @@ mock methods and attributes: Mock subclasses and their attributes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -There are various reasons why you might want to subclass `Mock`. One reason -might be to add helper methods. Here's a silly example: +There are various reasons why you might want to subclass :class:`Mock`. One +reason might be to add helper methods. Here's a silly example: >>> class MyMock(MagicMock): ... def has_been_called(self): @@ -994,9 +991,9 @@ might be to add helper methods. Here's a silly example: >>> mymock.has_been_called() True -The standard behaviour for `Mock` instances is that attributes and the return +The standard behaviour for ``Mock`` instances is that attributes and the return value mocks are of the same type as the mock they are accessed on. This ensures -that `Mock` attributes are `Mocks` and `MagicMock` attributes are `MagicMocks` +that ``Mock`` attributes are ``Mocks`` and ``MagicMock`` attributes are ``MagicMocks`` [#]_. So if you're subclassing to add helper methods then they'll also be available on the attributes and return value mock of instances of your subclass. @@ -1016,10 +1013,10 @@ created a `Twisted adaptor <http://twistedmatrix.com/documents/11.0.0/api/twisted.python.components.html>`_. Having this applied to attributes too actually causes errors. -`Mock` (in all its flavours) uses a method called `_get_child_mock` to create +``Mock`` (in all its flavours) uses a method called ``_get_child_mock`` to create these "sub-mocks" for attributes and return values. You can prevent your subclass being used for attributes by overriding this method. The signature is -that it takes arbitrary keyword arguments (`**kwargs`) which are then passed +that it takes arbitrary keyword arguments (``**kwargs``) which are then passed onto the mock constructor: >>> class Subclass(MagicMock): @@ -1052,17 +1049,17 @@ import. This can also be solved in better ways than an unconditional local import (store the module as a class or module attribute and only do the import on first use). -That aside there is a way to use `mock` to affect the results of an import. -Importing fetches an *object* from the `sys.modules` dictionary. Note that it +That aside there is a way to use ``mock`` to affect the results of an import. +Importing fetches an *object* from the :data:`sys.modules` dictionary. Note that it fetches an *object*, which need not be a module. Importing a module for the first time results in a module object being put in `sys.modules`, so usually when you import something you get a module back. This need not be the case however. This means you can use :func:`patch.dict` to *temporarily* put a mock in place -in `sys.modules`. Any imports whilst this patch is active will fetch the mock. +in :data:`sys.modules`. Any imports whilst this patch is active will fetch the mock. When the patch is complete (the decorated function exits, the with statement -body is complete or `patcher.stop()` is called) then whatever was there +body is complete or ``patcher.stop()`` is called) then whatever was there previously will be restored safely. Here's an example that mocks out the 'fooble' module. @@ -1076,10 +1073,10 @@ Here's an example that mocks out the 'fooble' module. >>> assert 'fooble' not in sys.modules >>> mock.blob.assert_called_once_with() -As you can see the `import fooble` succeeds, but on exit there is no 'fooble' -left in `sys.modules`. +As you can see the ``import fooble`` succeeds, but on exit there is no 'fooble' +left in :data:`sys.modules`. -This also works for the `from module import name` form: +This also works for the ``from module import name`` form: >>> mock = Mock() >>> with patch.dict('sys.modules', {'fooble': mock}): @@ -1109,10 +1106,10 @@ your mock objects through the :attr:`~Mock.method_calls` attribute. This doesn't allow you to track the order of calls between separate mock objects, however we can use :attr:`~Mock.mock_calls` to achieve the same effect. -Because mocks track calls to child mocks in `mock_calls`, and accessing an +Because mocks track calls to child mocks in ``mock_calls``, and accessing an arbitrary attribute of a mock creates a child mock, we can create our separate mocks from a parent one. Calls to those child mock will then all be recorded, -in order, in the `mock_calls` of the parent: +in order, in the ``mock_calls`` of the parent: >>> manager = Mock() >>> mock_foo = manager.foo @@ -1127,15 +1124,15 @@ in order, in the `mock_calls` of the parent: [call.foo.something(), call.bar.other.thing()] We can then assert about the calls, including the order, by comparing with -the `mock_calls` attribute on the manager mock: +the ``mock_calls`` attribute on the manager mock: >>> expected_calls = [call.foo.something(), call.bar.other.thing()] >>> manager.mock_calls == expected_calls True -If `patch` is creating, and putting in place, your mocks then you can attach +If ``patch`` is creating, and putting in place, your mocks then you can attach them to a manager mock using the :meth:`~Mock.attach_mock` method. After -attaching calls will be recorded in `mock_calls` of the manager. +attaching calls will be recorded in ``mock_calls`` of the manager. >>> manager = MagicMock() >>> with patch('mymodule.Class1') as MockClass1: @@ -1167,12 +1164,12 @@ with the :data:`call` object). If that sequence of calls are in >>> calls = call.one().two().three().call_list() >>> m.assert_has_calls(calls) -Even though the chained call `m.one().two().three()` aren't the only calls that +Even though the chained call ``m.one().two().three()`` aren't the only calls that have been made to the mock, the assert still succeeds. Sometimes a mock may have several calls made to it, and you are only interested in asserting about *some* of those calls. You may not even care about the -order. In this case you can pass `any_order=True` to `assert_has_calls`: +order. In this case you can pass ``any_order=True`` to ``assert_has_calls``: >>> m = MagicMock() >>> m(1), m.two(2, 3), m.seven(7), m.fifty('50') @@ -1194,7 +1191,7 @@ in the exact same object. If we are only interested in some of the attributes of this object then we can create a matcher that will check these attributes for us. -You can see in this example how a 'standard' call to `assert_called_with` isn't +You can see in this example how a 'standard' call to ``assert_called_with`` isn't sufficient: >>> class Foo: @@ -1209,7 +1206,7 @@ sufficient: AssertionError: Expected: call(<__main__.Foo object at 0x...>) Actual call: call(<__main__.Foo object at 0x...>) -A comparison function for our `Foo` class might look something like this: +A comparison function for our ``Foo`` class might look something like this: >>> def compare(self, other): ... if not type(self) == type(other): @@ -1237,11 +1234,11 @@ Putting all this together: >>> match_foo = Matcher(compare, Foo(1, 2)) >>> mock.assert_called_with(match_foo) -The `Matcher` is instantiated with our compare function and the `Foo` object -we want to compare against. In `assert_called_with` the `Matcher` equality +The ``Matcher`` is instantiated with our compare function and the ``Foo`` object +we want to compare against. In ``assert_called_with`` the ``Matcher`` equality method will be called, which compares the object the mock was called with against the one we created our matcher with. If they match then -`assert_called_with` passes, and if they don't an `AssertionError` is raised: +``assert_called_with`` passes, and if they don't an :exc:`AssertionError` is raised: >>> match_wrong = Matcher(compare, Foo(3, 4)) >>> mock.assert_called_with(match_wrong) @@ -1251,10 +1248,10 @@ against the one we created our matcher with. If they match then Called with: ((<Foo object at 0x...>,), {}) With a bit of tweaking you could have the comparison function raise the -`AssertionError` directly and provide a more useful failure message. +:exc:`AssertionError` directly and provide a more useful failure message. As of version 1.5, the Python testing library `PyHamcrest -<http://pypi.python.org/pypi/PyHamcrest>`_ provides similar functionality, +<https://pypi.python.org/pypi/PyHamcrest>`_ provides similar functionality, that may be useful here, in the form of its equality matcher (`hamcrest.library.integration.match_equality -<http://packages.python.org/PyHamcrest/integration.html#hamcrest.library.integration.match_equality>`_). +<http://pythonhosted.org/PyHamcrest/integration.html#hamcrest.library.integration.match_equality.match_equality>`_). diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 135abeb143b8..1b271c83bdb1 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -13,7 +13,7 @@ replace parts of your system under test with mock objects and make assertions about how they have been used. -`unittest.mock` provides a core :class:`Mock` class removing the need to +:mod:`unittest.mock` provides a core :class:`Mock` class removing the need to create a host of stubs throughout your test suite. After performing an action, you can make assertions about which methods / attributes were used and arguments they were called with. You can also specify return values and @@ -26,11 +26,11 @@ some examples of how to use :class:`Mock`, :class:`MagicMock` and :func:`patch`. Mock is very easy to use and is designed for use with :mod:`unittest`. Mock -is based on the 'action -> assertion' pattern instead of `'record -> replay'` +is based on the 'action -> assertion' pattern instead of 'record -> replay' used by many mocking frameworks. -There is a backport of `unittest.mock` for earlier versions of Python, -available as `mock on PyPI <http://pypi.python.org/pypi/mock>`_. +There is a backport of :mod:`unittest.mock` for earlier versions of Python, +available as `mock on PyPI <https://pypi.python.org/pypi/mock>`_. **Source code:** :source:`Lib/unittest/mock.py` @@ -71,9 +71,9 @@ exception when a mock is called: (5, 4, 3) Mock has many other ways you can configure it and control its behaviour. For -example the `spec` argument configures the mock to take its specification +example the *spec* argument configures the mock to take its specification from another object. Attempting to access attributes or methods on the mock -that don't exist on the spec will fail with an `AttributeError`. +that don't exist on the spec will fail with an :exc:`AttributeError`. The :func:`patch` decorator / context manager makes it easy to mock classes or objects in a module under test. The object you specify will be replaced with a @@ -97,13 +97,13 @@ mock (or other object) during the test and restored when the test ends: When you nest patch decorators the mocks are passed in to the decorated function in the same order they applied (the normal *python* order that decorators are applied). This means from the bottom up, so in the example - above the mock for `module.ClassName1` is passed in first. + above the mock for ``module.ClassName1`` is passed in first. - With `patch` it matters that you patch objects in the namespace where they + With :func:`patch` it matters that you patch objects in the namespace where they are looked up. This is normally straightforward, but for a quick guide read :ref:`where to patch <where-to-patch>`. -As well as a decorator `patch` can be used as a context manager in a with +As well as a decorator :func:`patch` can be used as a context manager in a with statement: >>> with patch.object(ProductionClass, 'method', return_value=None) as mock_method: @@ -135,7 +135,7 @@ allows you to do things like: >>> mock.__str__.assert_called_with() Mock allows you to assign functions (or other Mock instances) to magic methods -and they will be called appropriately. The `MagicMock` class is just a Mock +and they will be called appropriately. The :class:`MagicMock` class is just a Mock variant that has all of the magic methods pre-created for you (well, all the useful ones anyway). @@ -149,7 +149,7 @@ class: For ensuring that the mock objects in your tests have the same api as the objects they are replacing, you can use :ref:`auto-speccing <auto-speccing>`. -Auto-speccing can be done through the `autospec` argument to patch, or the +Auto-speccing can be done through the *autospec* argument to patch, or the :func:`create_autospec` function. Auto-speccing creates mock objects that have the same attributes and methods as the objects they are replacing, and any functions and methods (including constructors) have the same call @@ -171,9 +171,9 @@ code if they are used incorrectly: ... TypeError: <lambda>() takes exactly 3 arguments (1 given) -`create_autospec` can also be used on classes, where it copies the signature of -the `__init__` method, and on callable objects where it copies the signature of -the `__call__` method. +:func:`create_autospec` can also be used on classes, where it copies the signature of +the ``__init__`` method, and on callable objects where it copies the signature of +the ``__call__`` method. @@ -181,71 +181,77 @@ The Mock Class -------------- -`Mock` is a flexible mock object intended to replace the use of stubs and +:class:`Mock` is a flexible mock object intended to replace the use of stubs and test doubles throughout your code. Mocks are callable and create attributes as new mocks when you access them [#]_. Accessing the same attribute will always return the same mock. Mocks record how you use them, allowing you to make assertions about what your code has done to them. -:class:`MagicMock` is a subclass of `Mock` with all the magic methods +:class:`MagicMock` is a subclass of :class:`Mock` with all the magic methods pre-created and ready to use. There are also non-callable variants, useful when you are mocking out objects that aren't callable: :class:`NonCallableMock` and :class:`NonCallableMagicMock` The :func:`patch` decorators makes it easy to temporarily replace classes -in a particular module with a `Mock` object. By default `patch` will create -a `MagicMock` for you. You can specify an alternative class of `Mock` using -the `new_callable` argument to `patch`. +in a particular module with a :class:`Mock` object. By default :func:`patch` will create +a :class:`MagicMock` for you. You can specify an alternative class of :class:`Mock` using +the *new_callable* argument to :func:`patch`. -.. class:: Mock(spec=None, side_effect=None, return_value=DEFAULT, wraps=None, name=None, spec_set=None, **kwargs) +.. class:: Mock(spec=None, side_effect=None, return_value=DEFAULT, wraps=None, name=None, spec_set=None, unsafe=False, **kwargs) - Create a new `Mock` object. `Mock` takes several optional arguments + Create a new :class:`Mock` object. :class:`Mock` takes several optional arguments that specify the behaviour of the Mock object: - * `spec`: This can be either a list of strings or an existing object (a + * *spec*: This can be either a list of strings or an existing object (a class or instance) that acts as the specification for the mock object. If you pass in an object then a list of strings is formed by calling dir on the object (excluding unsupported magic attributes and methods). - Accessing any attribute not in this list will raise an `AttributeError`. + Accessing any attribute not in this list will raise an :exc:`AttributeError`. - If `spec` is an object (rather than a list of strings) then + If *spec* is an object (rather than a list of strings) then :attr:`~instance.__class__` returns the class of the spec object. This - allows mocks to pass `isinstance` tests. + allows mocks to pass :func:`isinstance` tests. - * `spec_set`: A stricter variant of `spec`. If used, attempting to *set* + * *spec_set*: A stricter variant of *spec*. If used, attempting to *set* or get an attribute on the mock that isn't on the object passed as - `spec_set` will raise an `AttributeError`. + *spec_set* will raise an :exc:`AttributeError`. - * `side_effect`: A function to be called whenever the Mock is called. See + * *side_effect*: A function to be called whenever the Mock is called. See the :attr:`~Mock.side_effect` attribute. Useful for raising exceptions or dynamically changing return values. The function is called with the same arguments as the mock, and unless it returns :data:`DEFAULT`, the return value of this function is used as the return value. - Alternatively `side_effect` can be an exception class or instance. In + Alternatively *side_effect* can be an exception class or instance. In this case the exception will be raised when the mock is called. - If `side_effect` is an iterable then each call to the mock will return + If *side_effect* is an iterable then each call to the mock will return the next value from the iterable. - A `side_effect` can be cleared by setting it to `None`. + A *side_effect* can be cleared by setting it to ``None``. - * `return_value`: The value returned when the mock is called. By default + * *return_value*: The value returned when the mock is called. By default this is a new Mock (created on first access). See the :attr:`return_value` attribute. - * `wraps`: Item for the mock object to wrap. If `wraps` is not None then + * *unsafe*: By default if any attribute starts with *assert* or + *assret* will raise an :exc:`AttributeError`. Passing ``unsafe=True`` + will allow access to these attributes. + + .. versionadded:: 3.5 + + * *wraps*: Item for the mock object to wrap. If *wraps* is not None then calling the Mock will pass the call through to the wrapped object (returning the real result). Attribute access on the mock will return a Mock object that wraps the corresponding attribute of the wrapped object (so attempting to access an attribute that doesn't exist will - raise an `AttributeError`). + raise an :exc:`AttributeError`). - If the mock has an explicit `return_value` set then calls are not passed - to the wrapped object and the `return_value` is returned instead. + If the mock has an explicit *return_value* set then calls are not passed + to the wrapped object and the *return_value* is returned instead. - * `name`: If the mock has a name then it will be used in the repr of the + * *name*: If the mock has a name then it will be used in the repr of the mock. This can be useful for debugging. The name is propagated to child mocks. @@ -296,13 +302,13 @@ the `new_callable` argument to `patch`. .. method:: assert_has_calls(calls, any_order=False) assert the mock has been called with the specified calls. - The `mock_calls` list is checked for the calls. + The :attr:`mock_calls` list is checked for the calls. - If `any_order` is false (the default) then the calls must be + If *any_order* is false (the default) then the calls must be sequential. There can be extra calls before or after the specified calls. - If `any_order` is true then the calls can be in any order, but + If *any_order* is true then the calls can be in any order, but they must all appear in :attr:`mock_calls`. >>> mock = Mock(return_value=None) @@ -315,6 +321,20 @@ the `new_callable` argument to `patch`. >>> calls = [call(4), call(2), call(3)] >>> mock.assert_has_calls(calls, any_order=True) + .. method:: assert_not_called(*args, **kwargs) + + Assert the mock was never called. + + >>> m = Mock() + >>> m.hello.assert_not_called() + >>> obj = m.hello() + >>> m.hello.assert_not_called() + Traceback (most recent call last): + ... + AssertionError: Expected 'hello' to not have been called. Called 1 times. + + .. versionadded:: 3.5 + .. method:: reset_mock() @@ -329,7 +349,7 @@ the `new_callable` argument to `patch`. False This can be useful where you want to make a series of assertions that - reuse the same object. Note that `reset_mock` *doesn't* clear the + reuse the same object. Note that :meth:`reset_mock` *doesn't* clear the return value, :attr:`side_effect` or any child attributes you have set using normal assignment. Child mocks and the return value mock (if any) are reset as well. @@ -337,11 +357,11 @@ the `new_callable` argument to `patch`. .. method:: mock_add_spec(spec, spec_set=False) - Add a spec to a mock. `spec` can either be an object or a - list of strings. Only attributes on the `spec` can be fetched as + Add a spec to a mock. *spec* can either be an object or a + list of strings. Only attributes on the *spec* can be fetched as attributes from the mock. - If `spec_set` is `True` then only attributes on the spec can be set. + If *spec_set* is true then only attributes on the spec can be set. .. method:: attach_mock(mock, attribute) @@ -382,14 +402,14 @@ the `new_callable` argument to `patch`. ... KeyError - `configure_mock` exists to make it easier to do configuration + :meth:`configure_mock` exists to make it easier to do configuration after the mock has been created. .. method:: __dir__() - `Mock` objects limit the results of `dir(some_mock)` to useful results. - For mocks with a `spec` this includes all the permitted attributes + :class:`Mock` objects limit the results of ``dir(some_mock)`` to useful results. + For mocks with a *spec* this includes all the permitted attributes for the mock. See :data:`FILTER_DIR` for what this filtering does, and how to @@ -449,7 +469,7 @@ the `new_callable` argument to `patch`. <Mock name='mock()()' id='...'> >>> mock.return_value.assert_called_with() - `return_value` can also be set in the constructor: + :attr:`return_value` can also be set in the constructor: >>> mock = Mock(return_value=3) >>> mock.return_value @@ -461,7 +481,7 @@ the `new_callable` argument to `patch`. .. attribute:: side_effect This can either be a function to be called when the mock is called, - or an exception (class or instance) to be raised. + an iterable or an exception (class or instance) to be raised. If you pass in a function it will be called with same arguments as the mock and unless the function returns the :data:`DEFAULT` singleton the @@ -469,6 +489,11 @@ the `new_callable` argument to `patch`. function returns :data:`DEFAULT` then the mock will return its normal value (from the :attr:`return_value`). + If you pass in an iterable, it is used to retrieve an iterator which + must yield a value on every call. This value can either be an exception + instance to be raised, or a value to be returned from the call to the + mock (:data:`DEFAULT` handling is identical to the function case). + An example of a mock that raises an exception (to test exception handling of an API): @@ -479,18 +504,14 @@ the `new_callable` argument to `patch`. ... Exception: Boom! - Using `side_effect` to return a sequence of values: + Using :attr:`side_effect` to return a sequence of values: >>> mock = Mock() >>> mock.side_effect = [3, 2, 1] >>> mock(), mock(), mock() (3, 2, 1) - The `side_effect` function is called with the same arguments as the - mock (so it is wise for it to take arbitrary args and keyword - arguments) and whatever it returns is used as the return value for - the call. The exception is if `side_effect` returns :data:`DEFAULT`, - in which case the normal :attr:`return_value` is used. + Using a callable: >>> mock = Mock(return_value=3) >>> def side_effect(*args, **kwargs): @@ -500,7 +521,7 @@ the `new_callable` argument to `patch`. >>> mock() 3 - `side_effect` can be set in the constructor. Here's an example that + :attr:`side_effect` can be set in the constructor. Here's an example that adds one to the value the mock is called with and returns it: >>> side_effect = lambda value: value + 1 @@ -510,7 +531,7 @@ the `new_callable` argument to `patch`. >>> mock(-8) -7 - Setting `side_effect` to `None` clears it: + Setting :attr:`side_effect` to ``None`` clears it: >>> m = Mock(side_effect=KeyError, return_value=3) >>> m() @@ -524,14 +545,14 @@ the `new_callable` argument to `patch`. .. attribute:: call_args - This is either `None` (if the mock hasn't been called), or the + This is either ``None`` (if the mock hasn't been called), or the arguments that the mock was last called with. This will be in the form of a tuple: the first member is any ordered arguments the mock was called with (or an empty tuple) and the second member is any keyword arguments (or an empty dictionary). >>> mock = Mock(return_value=None) - >>> print mock.call_args + >>> print(mock.call_args) None >>> mock() >>> mock.call_args @@ -547,7 +568,7 @@ the `new_callable` argument to `patch`. >>> mock.call_args call(3, 4, 5, key='fish', next='w00t!') - `call_args`, along with members of the lists :attr:`call_args_list`, + :attr:`call_args`, along with members of the lists :attr:`call_args_list`, :attr:`method_calls` and :attr:`mock_calls` are :data:`call` objects. These are tuples, so they can be unpacked to get at the individual arguments and make more complex assertions. See @@ -560,7 +581,7 @@ the `new_callable` argument to `patch`. (so the length of the list is the number of times it has been called). Before any calls have been made it is an empty list. The :data:`call` object can be used for conveniently constructing lists of - calls to compare with `call_args_list`. + calls to compare with :attr:`call_args_list`. >>> mock = Mock(return_value=None) >>> mock() @@ -572,7 +593,7 @@ the `new_callable` argument to `patch`. >>> mock.call_args_list == expected True - Members of `call_args_list` are :data:`call` objects. These can be + Members of :attr:`call_args_list` are :data:`call` objects. These can be unpacked as tuples to get at the individual arguments. See :ref:`calls as tuples <calls-as-tuples>`. @@ -590,15 +611,15 @@ the `new_callable` argument to `patch`. >>> mock.method_calls [call.method(), call.property.method.attribute()] - Members of `method_calls` are :data:`call` objects. These can be + Members of :attr:`method_calls` are :data:`call` objects. These can be unpacked as tuples to get at the individual arguments. See :ref:`calls as tuples <calls-as-tuples>`. .. attribute:: mock_calls - `mock_calls` records *all* calls to the mock object, its methods, magic - methods *and* return value mocks. + :attr:`mock_calls` records *all* calls to the mock object, its methods, + magic methods *and* return value mocks. >>> mock = MagicMock() >>> result = mock(1, 2, 3) @@ -615,24 +636,24 @@ the `new_callable` argument to `patch`. >>> mock.mock_calls == expected True - Members of `mock_calls` are :data:`call` objects. These can be + Members of :attr:`mock_calls` are :data:`call` objects. These can be unpacked as tuples to get at the individual arguments. See :ref:`calls as tuples <calls-as-tuples>`. .. attribute:: __class__ - Normally the `__class__` attribute of an object will return its type. - For a mock object with a `spec` `__class__` returns the spec class - instead. This allows mock objects to pass `isinstance` tests for the + Normally the :attr:`__class__` attribute of an object will return its type. + For a mock object with a :attr:`spec`, ``__class__`` returns the spec class + instead. This allows mock objects to pass :func:`isinstance` tests for the object they are replacing / masquerading as: >>> mock = Mock(spec=3) >>> isinstance(mock, int) True - `__class__` is assignable to, this allows a mock to pass an - `isinstance` check without forcing you to use a spec: + :attr:`__class__` is assignable to, this allows a mock to pass an + :func:`isinstance` check without forcing you to use a spec: >>> mock = Mock() >>> mock.__class__ = dict @@ -641,12 +662,12 @@ the `new_callable` argument to `patch`. .. class:: NonCallableMock(spec=None, wraps=None, name=None, spec_set=None, **kwargs) - A non-callable version of `Mock`. The constructor parameters have the same - meaning of `Mock`, with the exception of `return_value` and `side_effect` + A non-callable version of :class:`Mock`. The constructor parameters have the same + meaning of :class:`Mock`, with the exception of *return_value* and *side_effect* which have no meaning on a non-callable mock. -Mock objects that use a class or an instance as a `spec` or `spec_set` are able -to pass `isinstance` tests: +Mock objects that use a class or an instance as a :attr:`spec` or +:attr:`spec_set` are able to pass :func:`isinstance` tests: >>> mock = Mock(spec=SomeClass) >>> isinstance(mock, SomeClass) @@ -655,11 +676,11 @@ to pass `isinstance` tests: >>> isinstance(mock, SomeClass) True -The `Mock` classes have support for mocking magic methods. See :ref:`magic +The :class:`Mock` classes have support for mocking magic methods. See :ref:`magic methods <magic-methods>` for the full details. The mock classes and the :func:`patch` decorators all take arbitrary keyword -arguments for configuration. For the `patch` decorators the keywords are +arguments for configuration. For the :func:`patch` decorators the keywords are passed to the constructor of the mock being created. The keyword arguments are for configuring attributes of the mock: @@ -671,7 +692,7 @@ are for configuring attributes of the mock: The return value and side effect of child mocks can be set in the same way, using dotted notation. As you can't use dotted names directly in a call you -have to create a dictionary and unpack it using `**`: +have to create a dictionary and unpack it using ``**``: >>> attrs = {'method.return_value': 3, 'other.side_effect': KeyError} >>> mock = Mock(some_attribute='eggs', **attrs) @@ -709,10 +730,10 @@ apply to method calls on the mock object. .. class:: PropertyMock(*args, **kwargs) A mock intended to be used as a property, or other descriptor, on a class. - `PropertyMock` provides `__get__` and `__set__` methods so you can specify - a return value when it is fetched. + :class:`PropertyMock` provides :meth:`__get__` and :meth:`__set__` methods + so you can specify a return value when it is fetched. - Fetching a `PropertyMock` instance from an object calls the mock, with + Fetching a :class:`PropertyMock` instance from an object calls the mock, with no args. Setting it calls the mock with the value being set. >>> class Foo: @@ -726,7 +747,7 @@ apply to method calls on the mock object. >>> with patch('__main__.Foo.foo', new_callable=PropertyMock) as mock_foo: ... mock_foo.return_value = 'mockity-mock' ... this_foo = Foo() - ... print this_foo.foo + ... print(this_foo.foo) ... this_foo.foo = 6 ... mockity-mock @@ -734,7 +755,7 @@ apply to method calls on the mock object. [call(), call(6)] Because of the way mock attributes are stored you can't directly attach a -`PropertyMock` to a mock object. Instead you can attach it to the mock type +:class:`PropertyMock` to a mock object. Instead you can attach it to the mock type object:: >>> m = MagicMock() @@ -758,7 +779,7 @@ Calls made to the object will be recorded in the attributes like :attr:`~Mock.call_args` and :attr:`~Mock.call_args_list`. If :attr:`~Mock.side_effect` is set then it will be called after the call has -been recorded, so if `side_effect` raises an exception the call is still +been recorded, so if :attr:`side_effect` raises an exception the call is still recorded. The simplest way to make a mock raise an exception when called is to make @@ -779,8 +800,8 @@ The simplest way to make a mock raise an exception when called is to make >>> m.mock_calls [call(1, 2, 3), call('two', 'three', 'four')] -If `side_effect` is a function then whatever that function returns is what -calls to the mock return. The `side_effect` function is called with the +If :attr:`side_effect` is a function then whatever that function returns is what +calls to the mock return. The :attr:`side_effect` function is called with the same arguments as the mock. This allows you to vary the return value of the call dynamically, based on the input: @@ -797,7 +818,7 @@ call dynamically, based on the input: If you want the mock to still return the default return value (a new mock), or any set return value, then there are two ways of doing this. Either return -`mock.return_value` from inside `side_effect`, or return :data:`DEFAULT`: +:attr:`mock.return_value` from inside :attr:`side_effect`, or return :data:`DEFAULT`: >>> m = MagicMock() >>> def side_effect(*args, **kwargs): @@ -814,8 +835,8 @@ any set return value, then there are two ways of doing this. Either return >>> m() 3 -To remove a `side_effect`, and return to the default behaviour, set the -`side_effect` to `None`: +To remove a :attr:`side_effect`, and return to the default behaviour, set the +:attr:`side_effect` to ``None``: >>> m = MagicMock(return_value=6) >>> def side_effect(*args, **kwargs): @@ -828,9 +849,9 @@ To remove a `side_effect`, and return to the default behaviour, set the >>> m() 6 -The `side_effect` can also be any iterable object. Repeated calls to the mock +The :attr:`side_effect` can also be any iterable object. Repeated calls to the mock will return values from the iterable (until the iterable is exhausted and -a `StopIteration` is raised): +a :exc:`StopIteration` is raised): >>> m = MagicMock(side_effect=[1, 2, 3]) >>> m() @@ -867,12 +888,12 @@ Deleting Attributes Mock objects create attributes on demand. This allows them to pretend to be objects of any type. -You may want a mock object to return `False` to a `hasattr` call, or raise an -`AttributeError` when an attribute is fetched. You can do this by providing -an object as a `spec` for a mock, but that isn't always convenient. +You may want a mock object to return ``False`` to a :func:`hasattr` call, or raise an +:exc:`AttributeError` when an attribute is fetched. You can do this by providing +an object as a :attr:`spec` for a mock, but that isn't always convenient. You "block" attributes by deleting them. Once deleted, accessing an attribute -will raise an `AttributeError`. +will raise an :exc:`AttributeError`. >>> mock = MagicMock() >>> hasattr(mock, 'm') @@ -958,7 +979,7 @@ method: .. [#] The only exceptions are magic methods and attributes (those that have leading and trailing double underscores). Mock doesn't create these but - instead of raises an ``AttributeError``. This is because the interpreter + instead raises an :exc:`AttributeError`. This is because the interpreter will often implicitly request these methods, and gets *very* confused to get a new Mock object when it expects a magic method. If you need magic method support see :ref:`magic methods <magic-methods>`. @@ -978,78 +999,84 @@ patch .. note:: - `patch` is straightforward to use. The key is to do the patching in the + :func:`patch` is straightforward to use. The key is to do the patching in the right namespace. See the section `where to patch`_. .. function:: patch(target, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs) - `patch` acts as a function decorator, class decorator or a context - manager. Inside the body of the function or with statement, the `target` - is patched with a `new` object. When the function/with statement exits + :func:`patch` acts as a function decorator, class decorator or a context + manager. Inside the body of the function or with statement, the *target* + is patched with a *new* object. When the function/with statement exits the patch is undone. - If `new` is omitted, then the target is replaced with a - :class:`MagicMock`. If `patch` is used as a decorator and `new` is + If *new* is omitted, then the target is replaced with a + :class:`MagicMock`. If :func:`patch` is used as a decorator and *new* is omitted, the created mock is passed in as an extra argument to the - decorated function. If `patch` is used as a context manager the created + decorated function. If :func:`patch` is used as a context manager the created mock is returned by the context manager. - `target` should be a string in the form `'package.module.ClassName'`. The - `target` is imported and the specified object replaced with the `new` - object, so the `target` must be importable from the environment you are - calling `patch` from. The target is imported when the decorated function + *target* should be a string in the form ``'package.module.ClassName'``. The + *target* is imported and the specified object replaced with the *new* + object, so the *target* must be importable from the environment you are + calling :func:`patch` from. The target is imported when the decorated function is executed, not at decoration time. - The `spec` and `spec_set` keyword arguments are passed to the `MagicMock` + The *spec* and *spec_set* keyword arguments are passed to the :class:`MagicMock` if patch is creating one for you. - In addition you can pass `spec=True` or `spec_set=True`, which causes + In addition you can pass ``spec=True`` or ``spec_set=True``, which causes patch to pass in the object being mocked as the spec/spec_set object. - `new_callable` allows you to specify a different class, or callable object, - that will be called to create the `new` object. By default `MagicMock` is + *new_callable* allows you to specify a different class, or callable object, + that will be called to create the *new* object. By default :class:`MagicMock` is used. - A more powerful form of `spec` is `autospec`. If you set `autospec=True` - then the mock with be created with a spec from the object being replaced. + A more powerful form of *spec* is *autospec*. If you set ``autospec=True`` + then the mock will be created with a spec from the object being replaced. All attributes of the mock will also have the spec of the corresponding attribute of the object being replaced. Methods and functions being mocked - will have their arguments checked and will raise a `TypeError` if they are + will have their arguments checked and will raise a :exc:`TypeError` if they are called with the wrong signature. For mocks replacing a class, their return value (the 'instance') will have the same spec as the class. See the :func:`create_autospec` function and :ref:`auto-speccing`. - Instead of `autospec=True` you can pass `autospec=some_object` to use an + Instead of ``autospec=True`` you can pass ``autospec=some_object`` to use an arbitrary object as the spec instead of the one being replaced. - By default `patch` will fail to replace attributes that don't exist. If - you pass in `create=True`, and the attribute doesn't exist, patch will + By default :func:`patch` will fail to replace attributes that don't exist. If + you pass in ``create=True``, and the attribute doesn't exist, patch will create the attribute for you when the patched function is called, and delete it again afterwards. This is useful for writing tests against attributes that your production code creates at runtime. It is off by default because it can be dangerous. With it switched on you can write passing tests against APIs that don't actually exist! - Patch can be used as a `TestCase` class decorator. It works by + .. note:: + + .. versionchanged:: 3.5 + If you are patching builtins in a module then you don't + need to pass ``create=True``, it will be added by default. + + Patch can be used as a :class:`TestCase` class decorator. It works by decorating each test method in the class. This reduces the boilerplate - code when your test methods share a common patchings set. `patch` finds - tests by looking for method names that start with `patch.TEST_PREFIX`. - By default this is `test`, which matches the way `unittest` finds tests. - You can specify an alternative prefix by setting `patch.TEST_PREFIX`. + code when your test methods share a common patchings set. :func:`patch` finds + tests by looking for method names that start with ``patch.TEST_PREFIX``. + By default this is ``'test'``, which matches the way :mod:`unittest` finds tests. + You can specify an alternative prefix by setting ``patch.TEST_PREFIX``. Patch can be used as a context manager, with the with statement. Here the patching applies to the indented block after the with statement. If you use "as" then the patched object will be bound to the name after the - "as"; very useful if `patch` is creating a mock object for you. + "as"; very useful if :func:`patch` is creating a mock object for you. - `patch` takes arbitrary keyword arguments. These will be passed to - the `Mock` (or `new_callable`) on construction. + :func:`patch` takes arbitrary keyword arguments. These will be passed to + the :class:`Mock` (or *new_callable*) on construction. - `patch.dict(...)`, `patch.multiple(...)` and `patch.object(...)` are + ``patch.dict(...)``, ``patch.multiple(...)`` and ``patch.object(...)`` are available for alternate use-cases. -`patch` as function decorator, creating the mock for you and passing it into +:func:`patch` as function decorator, creating the mock for you and passing it into the decorated function: >>> @patch('__main__.SomeClass') @@ -1059,16 +1086,16 @@ the decorated function: >>> function(None) True -Patching a class replaces the class with a `MagicMock` *instance*. If the +Patching a class replaces the class with a :class:`MagicMock` *instance*. If the class is instantiated in the code under test then it will be the :attr:`~Mock.return_value` of the mock that will be used. If the class is instantiated multiple times you could use :attr:`~Mock.side_effect` to return a new mock each time. Alternatively you -can set the `return_value` to be anything you want. +can set the *return_value* to be anything you want. To configure return values on methods of *instances* on the patched class -you must do this on the `return_value`. For example: +you must do this on the :attr:`return_value`. For example: >>> class Class: ... def method(self): @@ -1081,7 +1108,7 @@ you must do this on the `return_value`. For example: ... assert Class().method() == 'foo' ... -If you use `spec` or `spec_set` and `patch` is replacing a *class*, then the +If you use *spec* or *spec_set* and :func:`patch` is replacing a *class*, then the return value of the created mock will have the same spec. >>> Original = Class @@ -1091,7 +1118,7 @@ return value of the created mock will have the same spec. >>> assert isinstance(instance, Original) >>> patcher.stop() -The `new_callable` argument is useful where you want to use an alternative +The *new_callable* argument is useful where you want to use an alternative class to the default :class:`MagicMock` for the created mock. For example, if you wanted a :class:`NonCallableMock` to be used: @@ -1104,11 +1131,11 @@ you wanted a :class:`NonCallableMock` to be used: ... TypeError: 'NonCallableMock' object is not callable -Another use case might be to replace an object with a `io.StringIO` instance: +Another use case might be to replace an object with a :class:`io.StringIO` instance: >>> from io import StringIO >>> def foo(): - ... print 'Something' + ... print('Something') ... >>> @patch('sys.stdout', new_callable=StringIO) ... def test(mock_stdout): @@ -1117,7 +1144,7 @@ Another use case might be to replace an object with a `io.StringIO` instance: ... >>> test() -When `patch` is creating a mock for you, it is common that the first thing +When :func:`patch` is creating a mock for you, it is common that the first thing you need to do is to configure the mock. Some of that configuration can be done in the call to patch. Any arbitrary keywords you pass into the call will be used to set attributes on the created mock: @@ -1133,7 +1160,7 @@ As well as attributes on the created mock attributes, like the :attr:`~Mock.return_value` and :attr:`~Mock.side_effect`, of child mocks can also be configured. These aren't syntactically valid to pass in directly as keyword arguments, but a dictionary with these as keys can still be expanded -into a `patch` call using `**`: +into a :func:`patch` call using ``**``: >>> config = {'method.return_value': 3, 'other.side_effect': KeyError} >>> patcher = patch('__main__.thing', **config) @@ -1151,19 +1178,19 @@ patch.object .. function:: patch.object(target, attribute, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs) - patch the named member (`attribute`) on an object (`target`) with a mock + patch the named member (*attribute*) on an object (*target*) with a mock object. - `patch.object` can be used as a decorator, class decorator or a context - manager. Arguments `new`, `spec`, `create`, `spec_set`, `autospec` and - `new_callable` have the same meaning as for `patch`. Like `patch`, - `patch.object` takes arbitrary keyword arguments for configuring the mock + :func:`patch.object` can be used as a decorator, class decorator or a context + manager. Arguments *new*, *spec*, *create*, *spec_set*, *autospec* and + *new_callable* have the same meaning as for :func:`patch`. Like :func:`patch`, + :func:`patch.object` takes arbitrary keyword arguments for configuring the mock object it creates. - When used as a class decorator `patch.object` honours `patch.TEST_PREFIX` + When used as a class decorator :func:`patch.object` honours ``patch.TEST_PREFIX`` for choosing which methods to wrap. -You can either call `patch.object` with three arguments or two arguments. The +You can either call :func:`patch.object` with three arguments or two arguments. The three argument form takes the object to be patched, the attribute name and the object to replace the attribute with. @@ -1178,8 +1205,8 @@ function: ... >>> test() -`spec`, `create` and the other arguments to `patch.object` have the same -meaning as they do for `patch`. +*spec*, *create* and the other arguments to :func:`patch.object` have the same +meaning as they do for :func:`patch`. patch.dict @@ -1190,27 +1217,27 @@ patch.dict Patch a dictionary, or dictionary like object, and restore the dictionary to its original state after the test. - `in_dict` can be a dictionary or a mapping like container. If it is a + *in_dict* can be a dictionary or a mapping like container. If it is a mapping then it must at least support getting, setting and deleting items plus iterating over keys. - `in_dict` can also be a string specifying the name of the dictionary, which + *in_dict* can also be a string specifying the name of the dictionary, which will then be fetched by importing it. - `values` can be a dictionary of values to set in the dictionary. `values` - can also be an iterable of `(key, value)` pairs. + *values* can be a dictionary of values to set in the dictionary. *values* + can also be an iterable of ``(key, value)`` pairs. - If `clear` is true then the dictionary will be cleared before the new + If *clear* is true then the dictionary will be cleared before the new values are set. - `patch.dict` can also be called with arbitrary keyword arguments to set + :func:`patch.dict` can also be called with arbitrary keyword arguments to set values in the dictionary. - `patch.dict` can be used as a context manager, decorator or class - decorator. When used as a class decorator `patch.dict` honours - `patch.TEST_PREFIX` for choosing which methods to wrap. + :func:`patch.dict` can be used as a context manager, decorator or class + decorator. When used as a class decorator :func:`patch.dict` honours + ``patch.TEST_PREFIX`` for choosing which methods to wrap. -`patch.dict` can be used to add members to a dictionary, or simply let a test +:func:`patch.dict` can be used to add members to a dictionary, or simply let a test change a dictionary, and ensure the dictionary is restored when the test ends. @@ -1222,12 +1249,12 @@ ends. >>> import os >>> with patch.dict('os.environ', {'newkey': 'newvalue'}): - ... print os.environ['newkey'] + ... print(os.environ['newkey']) ... newvalue >>> assert 'newkey' not in os.environ -Keywords can be used in the `patch.dict` call to set values in the dictionary: +Keywords can be used in the :func:`patch.dict` call to set values in the dictionary: >>> mymodule = MagicMock() >>> mymodule.function.return_value = 'fish' @@ -1237,11 +1264,11 @@ Keywords can be used in the `patch.dict` call to set values in the dictionary: ... 'fish' -`patch.dict` can be used with dictionary like objects that aren't actually +:func:`patch.dict` can be used with dictionary like objects that aren't actually dictionaries. At the very minimum they must support item getting, setting, deleting and either iteration or membership test. This corresponds to the -magic methods `__getitem__`, `__setitem__`, `__delitem__` and either -`__iter__` or `__contains__`. +magic methods :meth:`__getitem__`, :meth:`__setitem__`, :meth:`__delitem__` and either +:meth:`__iter__` or :meth:`__contains__`. >>> class Container: ... def __init__(self): @@ -1277,21 +1304,21 @@ patch.multiple with patch.multiple(settings, FIRST_PATCH='one', SECOND_PATCH='two'): ... - Use :data:`DEFAULT` as the value if you want `patch.multiple` to create + Use :data:`DEFAULT` as the value if you want :func:`patch.multiple` to create mocks for you. In this case the created mocks are passed into a decorated - function by keyword, and a dictionary is returned when `patch.multiple` is + function by keyword, and a dictionary is returned when :func:`patch.multiple` is used as a context manager. - `patch.multiple` can be used as a decorator, class decorator or a context - manager. The arguments `spec`, `spec_set`, `create`, `autospec` and - `new_callable` have the same meaning as for `patch`. These arguments will - be applied to *all* patches done by `patch.multiple`. + :func:`patch.multiple` can be used as a decorator, class decorator or a context + manager. The arguments *spec*, *spec_set*, *create*, *autospec* and + *new_callable* have the same meaning as for :func:`patch`. These arguments will + be applied to *all* patches done by :func:`patch.multiple`. - When used as a class decorator `patch.multiple` honours `patch.TEST_PREFIX` + When used as a class decorator :func:`patch.multiple` honours ``patch.TEST_PREFIX`` for choosing which methods to wrap. -If you want `patch.multiple` to create mocks for you, then you can use -:data:`DEFAULT` as the value. If you use `patch.multiple` as a decorator +If you want :func:`patch.multiple` to create mocks for you, then you can use +:data:`DEFAULT` as the value. If you use :func:`patch.multiple` as a decorator then the created mocks are passed into the decorated function by keyword. >>> thing = object() @@ -1304,8 +1331,8 @@ then the created mocks are passed into the decorated function by keyword. ... >>> test_function() -`patch.multiple` can be nested with other `patch` decorators, but put arguments -passed by keyword *after* any of the standard arguments created by `patch`: +:func:`patch.multiple` can be nested with other ``patch`` decorators, but put arguments +passed by keyword *after* any of the standard arguments created by :func:`patch`: >>> @patch('sys.exit') ... @patch.multiple('__main__', thing=DEFAULT, other=DEFAULT) @@ -1316,7 +1343,7 @@ passed by keyword *after* any of the standard arguments created by `patch`: ... >>> test_function() -If `patch.multiple` is used as a context manager, the value returned by the +If :func:`patch.multiple` is used as a context manager, the value returned by the context manger is a dictionary where created mocks are keyed by name: >>> with patch.multiple('__main__', thing=DEFAULT, other=DEFAULT) as values: @@ -1332,16 +1359,16 @@ context manger is a dictionary where created mocks are keyed by name: patch methods: start and stop ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -All the patchers have `start` and `stop` methods. These make it simpler to do -patching in `setUp` methods or where you want to do multiple patches without +All the patchers have :meth:`start` and :meth:`stop` methods. These make it simpler to do +patching in ``setUp`` methods or where you want to do multiple patches without nesting decorators or with statements. -To use them call `patch`, `patch.object` or `patch.dict` as normal and keep a -reference to the returned `patcher` object. You can then call `start` to put -the patch in place and `stop` to undo it. +To use them call :func:`patch`, :func:`patch.object` or :func:`patch.dict` as +normal and keep a reference to the returned ``patcher`` object. You can then +call :meth:`start` to put the patch in place and :meth:`stop` to undo it. -If you are using `patch` to create a mock for you then it will be returned by -the call to `patcher.start`. +If you are using :func:`patch` to create a mock for you then it will be returned by +the call to ``patcher.start``. >>> patcher = patch('package.module.ClassName') >>> from package import module @@ -1354,8 +1381,8 @@ the call to `patcher.start`. >>> assert module.ClassName is not new_mock -A typical use case for this might be for doing multiple patches in the `setUp` -method of a `TestCase`: +A typical use case for this might be for doing multiple patches in the ``setUp`` +method of a :class:`TestCase`: >>> class MyTest(TestCase): ... def setUp(self): @@ -1377,7 +1404,7 @@ method of a `TestCase`: .. caution:: If you use this technique you must ensure that the patching is "undone" by - calling `stop`. This can be fiddlier than you might think, because if an + calling ``stop``. This can be fiddlier than you might think, because if an exception is raised in the ``setUp`` then ``tearDown`` is not called. :meth:`unittest.TestCase.addCleanup` makes this easier: @@ -1391,15 +1418,31 @@ method of a `TestCase`: ... assert package.module.Class is self.MockClass ... - As an added bonus you no longer need to keep a reference to the `patcher` + As an added bonus you no longer need to keep a reference to the ``patcher`` object. It is also possible to stop all patches which have been started by using -`patch.stopall`. +:func:`patch.stopall`. .. function:: patch.stopall - Stop all active patches. Only stops patches started with `start`. + Stop all active patches. Only stops patches started with ``start``. + + +.. _patch-builtins: + +patch builtins +~~~~~~~~~~~~~~ +You can patch any builtins within a module. The following example patches +builtin :func:`ord`: + + >>> @patch('__main__.ord') + ... def test(mock_ord): + ... mock_ord.return_value = 101 + ... print(ord('c')) + ... + >>> test() + 101 TEST_PREFIX @@ -1407,11 +1450,11 @@ TEST_PREFIX All of the patchers can be used as class decorators. When used in this way they wrap every test method on the class. The patchers recognise methods that -start with `test` as being test methods. This is the same way that the +start with ``'test'`` as being test methods. This is the same way that the :class:`unittest.TestLoader` finds test methods by default. It is possible that you want to use a different prefix for your tests. You can -inform the patchers of the different prefix by setting `patch.TEST_PREFIX`: +inform the patchers of the different prefix by setting ``patch.TEST_PREFIX``: >>> patch.TEST_PREFIX = 'foo' >>> value = 3 @@ -1419,9 +1462,9 @@ inform the patchers of the different prefix by setting `patch.TEST_PREFIX`: >>> @patch('__main__.value', 'not three') ... class Thing: ... def foo_one(self): - ... print value + ... print(value) ... def foo_two(self): - ... print value + ... print(value) ... >>> >>> Thing().foo_one() @@ -1464,7 +1507,7 @@ passed into your test function matches this order. Where to patch ~~~~~~~~~~~~~~ -`patch` works by (temporarily) changing the object that a *name* points to with +:func:`patch` works by (temporarily) changing the object that a *name* points to with another one. There can be many names pointing to any individual object, so for patching to work you must ensure that you patch the name used by the system under test. @@ -1482,23 +1525,23 @@ Imagine we have a project that we want to test with the following structure:: -> from a import SomeClass -> some_function instantiates SomeClass -Now we want to test `some_function` but we want to mock out `SomeClass` using -`patch`. The problem is that when we import module b, which we will have to -do then it imports `SomeClass` from module a. If we use `patch` to mock out -`a.SomeClass` then it will have no effect on our test; module b already has a -reference to the *real* `SomeClass` and it looks like our patching had no +Now we want to test ``some_function`` but we want to mock out ``SomeClass`` using +:func:`patch`. The problem is that when we import module b, which we will have to +do then it imports ``SomeClass`` from module a. If we use :func:`patch` to mock out +``a.SomeClass`` then it will have no effect on our test; module b already has a +reference to the *real* ``SomeClass`` and it looks like our patching had no effect. -The key is to patch out `SomeClass` where it is used (or where it is looked up -). In this case `some_function` will actually look up `SomeClass` in module b, +The key is to patch out ``SomeClass`` where it is used (or where it is looked up +). In this case ``some_function`` will actually look up ``SomeClass`` in module b, where we have imported it. The patching should look like:: @patch('b.SomeClass') -However, consider the alternative scenario where instead of `from a import -SomeClass` module b does `import a` and `some_function` uses `a.SomeClass`. Both +However, consider the alternative scenario where instead of ``from a import +SomeClass`` module b does ``import a`` and ``some_function`` uses ``a.SomeClass``. Both of these import forms are common. In this case the class we want to patch is -being looked up on the a module and so we have to patch `a.SomeClass` instead:: +being looked up in the module and so we have to patch ``a.SomeClass`` instead:: @patch('a.SomeClass') @@ -1509,7 +1552,7 @@ Patching Descriptors and Proxy Objects Both patch_ and patch.object_ correctly patch and restore descriptors: class methods, static methods and properties. You should patch these on the *class* rather than an instance. They also work with *some* objects -that proxy attribute access, like the `django setttings object +that proxy attribute access, like the `django settings object <http://www.voidspace.org.uk/python/weblog/arch_d7_2010_12_04.shtml#e1198>`_. @@ -1554,7 +1597,7 @@ the first argument [#]_. [] One use case for this is for mocking objects used as context managers in a -`with` statement: +:keyword:`with` statement: >>> mock = Mock() >>> mock.__enter__ = Mock(return_value='foo') @@ -1570,27 +1613,27 @@ are recorded in :attr:`~Mock.mock_calls`. .. note:: - If you use the `spec` keyword argument to create a mock then attempting to - set a magic method that isn't in the spec will raise an `AttributeError`. + If you use the *spec* keyword argument to create a mock then attempting to + set a magic method that isn't in the spec will raise an :exc:`AttributeError`. The full list of supported magic methods is: * ``__hash__``, ``__sizeof__``, ``__repr__`` and ``__str__`` * ``__dir__``, ``__format__`` and ``__subclasses__`` * ``__floor__``, ``__trunc__`` and ``__ceil__`` -* Comparisons: ``__cmp__``, ``__lt__``, ``__gt__``, ``__le__``, ``__ge__``, +* Comparisons: ``__lt__``, ``__gt__``, ``__le__``, ``__ge__``, ``__eq__`` and ``__ne__`` * Container methods: ``__getitem__``, ``__setitem__``, ``__delitem__``, - ``__contains__``, ``__len__``, ``__iter__``, ``__getslice__``, - ``__setslice__``, ``__reversed__`` and ``__missing__`` + ``__contains__``, ``__len__``, ``__iter__``, ``__reversed__`` + and ``__missing__`` * Context manager: ``__enter__`` and ``__exit__`` * Unary numeric methods: ``__neg__``, ``__pos__`` and ``__invert__`` * The numeric methods (including right hand and in-place variants): - ``__add__``, ``__sub__``, ``__mul__``, ``__div__``, + ``__add__``, ``__sub__``, ``__mul__``, ``__matmul__``, ``__div__``, ``__truediv__``, ``__floordiv__``, ``__mod__``, ``__divmod__``, ``__lshift__``, ``__rshift__``, ``__and__``, ``__xor__``, ``__or__``, and ``__pow__`` -* Numeric conversion methods: ``__complex__``, ``__int__``, ``__float__``, - ``__index__`` and ``__coerce__`` +* Numeric conversion methods: ``__complex__``, ``__int__``, ``__float__`` + and ``__index__`` * Descriptor methods: ``__get__``, ``__set__`` and ``__delete__`` * Pickling: ``__reduce__``, ``__reduce_ex__``, ``__getinitargs__``, ``__getnewargs__``, ``__getstate__`` and ``__setstate__`` @@ -1607,7 +1650,7 @@ by mock, can't be set dynamically, or can cause problems: Magic Mock ~~~~~~~~~~ -There are two `MagicMock` variants: `MagicMock` and `NonCallableMagicMock`. +There are two ``MagicMock`` variants: :class:`MagicMock` and :class:`NonCallableMagicMock`. .. class:: MagicMock(*args, **kw) @@ -1618,19 +1661,19 @@ There are two `MagicMock` variants: `MagicMock` and `NonCallableMagicMock`. The constructor parameters have the same meaning as for :class:`Mock`. - If you use the `spec` or `spec_set` arguments then *only* magic methods + If you use the *spec* or *spec_set* arguments then *only* magic methods that exist in the spec will be created. .. class:: NonCallableMagicMock(*args, **kw) - A non-callable version of `MagicMock`. + A non-callable version of :class:`MagicMock`. The constructor parameters have the same meaning as for - :class:`MagicMock`, with the exception of `return_value` and - `side_effect` which have no meaning on a non-callable mock. + :class:`MagicMock`, with the exception of *return_value* and + *side_effect* which have no meaning on a non-callable mock. -The magic methods are setup with `MagicMock` objects, so you can configure them +The magic methods are setup with :class:`MagicMock` objects, so you can configure them and use them in the usual way: >>> mock = MagicMock() @@ -1652,17 +1695,17 @@ Methods and their defaults: * ``__gt__``: NotImplemented * ``__le__``: NotImplemented * ``__ge__``: NotImplemented -* ``__int__`` : 1 -* ``__contains__`` : False -* ``__len__`` : 1 -* ``__iter__`` : iter([]) -* ``__exit__`` : False -* ``__complex__`` : 1j -* ``__float__`` : 1.0 -* ``__bool__`` : True -* ``__index__`` : 1 -* ``__hash__`` : default hash for the mock -* ``__str__`` : default str for the mock +* ``__int__``: 1 +* ``__contains__``: False +* ``__len__``: 1 +* ``__iter__``: iter([]) +* ``__exit__``: False +* ``__complex__``: 1j +* ``__float__``: 1.0 +* ``__bool__``: True +* ``__index__``: 1 +* ``__hash__``: default hash for the mock +* ``__str__``: default str for the mock * ``__sizeof__``: default sizeof for the mock For example: @@ -1677,9 +1720,10 @@ For example: >>> object() in mock False -The two equality method, `__eq__` and `__ne__`, are special. -They do the default equality comparison on identity, using a side -effect, unless you change their return value to return something else: +The two equality methods, :meth:`__eq__` and :meth:`__ne__`, are special. +They do the default equality comparison on identity, using the +:attr:`~Mock.side_effect` attribute, unless you change their return value to +return something else:: >>> MagicMock() == 3 False @@ -1690,7 +1734,7 @@ effect, unless you change their return value to return something else: >>> mock == 3 True -The return value of `MagicMock.__iter__` can be any iterable object and isn't +The return value of :meth:`MagicMock.__iter__` can be any iterable object and isn't required to be an iterator: >>> mock = MagicMock() @@ -1750,10 +1794,10 @@ sentinel Sometimes when testing you need to test that a specific object is passed as an argument to another method, or returned. It can be common to create named -sentinel objects to test this. `sentinel` provides a convenient way of +sentinel objects to test this. :data:`sentinel` provides a convenient way of creating and testing the identity of objects like this. -In this example we monkey patch `method` to return `sentinel.some_object`: +In this example we monkey patch ``method`` to return ``sentinel.some_object``: >>> real = ProductionClass() >>> real.method = Mock(name="method") @@ -1770,8 +1814,8 @@ DEFAULT .. data:: DEFAULT - The `DEFAULT` object is a pre-created sentinel (actually - `sentinel.DEFAULT`). It can be used by :attr:`~Mock.side_effect` + The :data:`DEFAULT` object is a pre-created sentinel (actually + ``sentinel.DEFAULT``). It can be used by :attr:`~Mock.side_effect` functions to indicate that the normal return value should be used. @@ -1780,9 +1824,9 @@ call .. function:: call(*args, **kwargs) - `call` is a helper object for making simpler assertions, for comparing with + :func:`call` is a helper object for making simpler assertions, for comparing with :attr:`~Mock.call_args`, :attr:`~Mock.call_args_list`, - :attr:`~Mock.mock_calls` and :attr:`~Mock.method_calls`. `call` can also be + :attr:`~Mock.mock_calls` and :attr:`~Mock.method_calls`. :func:`call` can also be used with :meth:`~Mock.assert_has_calls`. >>> m = MagicMock(return_value=None) @@ -1793,11 +1837,11 @@ call .. method:: call.call_list() - For a call object that represents multiple calls, `call_list` + For a call object that represents multiple calls, :meth:`call_list` returns a list of all the intermediate calls as well as the final call. -`call_list` is particularly useful for making assertions on "chained calls". A +``call_list`` is particularly useful for making assertions on "chained calls". A chained call is multiple calls on a single line of code. This results in multiple entries in :attr:`~Mock.mock_calls` on a mock. Manually constructing the sequence of calls can be tedious. @@ -1819,15 +1863,15 @@ chained call: .. _calls-as-tuples: -A `call` object is either a tuple of (positional args, keyword args) or +A ``call`` object is either a tuple of (positional args, keyword args) or (name, positional args, keyword args) depending on how it was constructed. When -you construct them yourself this isn't particularly interesting, but the `call` +you construct them yourself this isn't particularly interesting, but the ``call`` objects that are in the :attr:`Mock.call_args`, :attr:`Mock.call_args_list` and :attr:`Mock.mock_calls` attributes can be introspected to get at the individual arguments they contain. -The `call` objects in :attr:`Mock.call_args` and :attr:`Mock.call_args_list` -are two-tuples of (positional args, keyword args) whereas the `call` objects +The ``call`` objects in :attr:`Mock.call_args` and :attr:`Mock.call_args_list` +are two-tuples of (positional args, keyword args) whereas the ``call`` objects in :attr:`Mock.mock_calls`, along with ones you construct yourself, are three-tuples of (name, positional args, keyword args). @@ -1870,25 +1914,25 @@ create_autospec .. function:: create_autospec(spec, spec_set=False, instance=False, **kwargs) Create a mock object using another object as a spec. Attributes on the - mock will use the corresponding attribute on the `spec` object as their + mock will use the corresponding attribute on the *spec* object as their spec. Functions or methods being mocked will have their arguments checked to ensure that they are called with the correct signature. - If `spec_set` is `True` then attempting to set attributes that don't exist - on the spec object will raise an `AttributeError`. + If *spec_set* is ``True`` then attempting to set attributes that don't exist + on the spec object will raise an :exc:`AttributeError`. If a class is used as a spec then the return value of the mock (the instance of the class) will have the same spec. You can use a class as the - spec for an instance object by passing `instance=True`. The returned mock + spec for an instance object by passing ``instance=True``. The returned mock will only be callable if instances of the mock are callable. - `create_autospec` also takes arbitrary keyword arguments that are passed to + :func:`create_autospec` also takes arbitrary keyword arguments that are passed to the constructor of the created mock. See :ref:`auto-speccing` for examples of how to use auto-speccing with -`create_autospec` and the `autospec` argument to :func:`patch`. +:func:`create_autospec` and the *autospec* argument to :func:`patch`. ANY @@ -1910,7 +1954,7 @@ passed in. >>> mock('foo', bar=object()) >>> mock.assert_called_once_with('foo', bar=ANY) -`ANY` can also be used in comparisons with call lists like +:data:`ANY` can also be used in comparisons with call lists like :attr:`~Mock.mock_calls`: >>> m = MagicMock(return_value=None) @@ -1927,15 +1971,15 @@ FILTER_DIR .. data:: FILTER_DIR -`FILTER_DIR` is a module level variable that controls the way mock objects -respond to `dir` (only for Python 2.6 or more recent). The default is `True`, +:data:`FILTER_DIR` is a module level variable that controls the way mock objects +respond to :func:`dir` (only for Python 2.6 or more recent). The default is ``True``, which uses the filtering described below, to only show useful members. If you dislike this filtering, or need to switch it off for diagnostic purposes, then -set `mock.FILTER_DIR = False`. +set ``mock.FILTER_DIR = False``. -With filtering on, `dir(some_mock)` shows only useful attributes and will +With filtering on, ``dir(some_mock)`` shows only useful attributes and will include any dynamically created attributes that wouldn't normally be shown. -If the mock was created with a `spec` (or `autospec` of course) then all the +If the mock was created with a *spec* (or *autospec* of course) then all the attributes from the original are shown, even if they haven't been accessed yet: @@ -1954,11 +1998,11 @@ yet: 'BaseHandler', ... -Many of the not-very-useful (private to `Mock` rather than the thing being +Many of the not-very-useful (private to :class:`Mock` rather than the thing being mocked) underscore and double underscore prefixed attributes have been -filtered from the result of calling `dir` on a `Mock`. If you dislike this +filtered from the result of calling :func:`dir` on a :class:`Mock`. If you dislike this behaviour you can switch it off by setting the module level switch -`FILTER_DIR`: +:data:`FILTER_DIR`: >>> from unittest import mock >>> mock.FILTER_DIR = False @@ -1972,9 +2016,9 @@ behaviour you can switch it off by setting the module level switch '__class__', ... -Alternatively you can just use `vars(my_mock)` (instance members) and -`dir(type(my_mock))` (type members) to bypass the filtering irrespective of -`mock.FILTER_DIR`. +Alternatively you can just use ``vars(my_mock)`` (instance members) and +``dir(type(my_mock))`` (type members) to bypass the filtering irrespective of +:data:`mock.FILTER_DIR`. mock_open @@ -1982,36 +2026,46 @@ mock_open .. function:: mock_open(mock=None, read_data=None) - A helper function to create a mock to replace the use of `open`. It works - for `open` called directly or used as a context manager. + A helper function to create a mock to replace the use of :func:`open`. It works + for :func:`open` called directly or used as a context manager. - The `mock` argument is the mock object to configure. If `None` (the - default) then a `MagicMock` will be created for you, with the API limited + The *mock* argument is the mock object to configure. If ``None`` (the + default) then a :class:`MagicMock` will be created for you, with the API limited to methods or attributes available on standard file handles. - `read_data` is a string for the :meth:`~io.IOBase.read`, + *read_data* is a string for the :meth:`~io.IOBase.read`, :meth:`~io.IOBase.readline`, and :meth:`~io.IOBase.readlines` methods of the file handle to return. Calls to those methods will take data from - `read_data` until it is depleted. The mock of these methods is pretty - simplistic. If you need more control over the data that you are feeding to - the tested code you will need to customize this mock for yourself. - `read_data` is an empty string by default. + *read_data* until it is depleted. The mock of these methods is pretty + simplistic: every time the *mock* is called, the *read_data* is rewound to + the start. If you need more control over the data that you are feeding to + the tested code you will need to customize this mock for yourself. When that + is insufficient, one of the in-memory filesystem packages on `PyPI + <https://pypi.python.org/pypi>`_ can offer a realistic filesystem for testing. + + .. versionchanged:: 3.4 + Added :meth:`~io.IOBase.readline` and :meth:`~io.IOBase.readlines` support. + The mock of :meth:`~io.IOBase.read` changed to consume *read_data* rather + than returning it on each call. + + .. versionchanged:: 3.5 + *read_data* is now reset on each call to the *mock*. -Using `open` as a context manager is a great way to ensure your file handles +Using :func:`open` as a context manager is a great way to ensure your file handles are closed properly and is becoming common:: with open('/some/path', 'w') as f: f.write('something') -The issue is that even if you mock out the call to `open` it is the -*returned object* that is used as a context manager (and has `__enter__` and -`__exit__` called). +The issue is that even if you mock out the call to :func:`open` it is the +*returned object* that is used as a context manager (and has :meth:`__enter__` and +:meth:`__exit__` called). Mocking context managers with a :class:`MagicMock` is common enough and fiddly enough that a helper function is useful. >>> m = mock_open() - >>> with patch('__main__.open', m, create=True): + >>> with patch('__main__.open', m): ... with open('foo', 'w') as h: ... h.write('some stuff') ... @@ -2026,7 +2080,7 @@ enough that a helper function is useful. And for reading files: - >>> with patch('__main__.open', mock_open(read_data='bibble'), create=True) as m: + >>> with patch('__main__.open', mock_open(read_data='bibble')) as m: ... with open('foo') as h: ... result = h.read() ... @@ -2039,21 +2093,21 @@ And for reading files: Autospeccing ~~~~~~~~~~~~ -Autospeccing is based on the existing `spec` feature of mock. It limits the +Autospeccing is based on the existing :attr:`spec` feature of mock. It limits the api of mocks to the api of an original object (the spec), but it is recursive (implemented lazily) so that attributes of mocks only have the same api as the attributes of the spec. In addition mocked functions / methods have the -same call signature as the original so they raise a `TypeError` if they are +same call signature as the original so they raise a :exc:`TypeError` if they are called incorrectly. Before I explain how auto-speccing works, here's why it is needed. -`Mock` is a very powerful and flexible object, but it suffers from two flaws +:class:`Mock` is a very powerful and flexible object, but it suffers from two flaws when used to mock out objects from a system under test. One of these flaws is -specific to the `Mock` api and the other is a more general problem with using +specific to the :class:`Mock` api and the other is a more general problem with using mock objects. -First the problem specific to `Mock`. `Mock` has two assert methods that are +First the problem specific to :class:`Mock`. :class:`Mock` has two assert methods that are extremely handy: :meth:`~Mock.assert_called_with` and :meth:`~Mock.assert_called_once_with`. @@ -2088,8 +2142,8 @@ unit tests. Testing everything in isolation is all fine and dandy, but if you don't test how your units are "wired together" there is still lots of room for bugs that tests might have caught. -`mock` already provides a feature to help with this, called speccing. If you -use a class or instance as the `spec` for a mock then you can only access +:mod:`mock` already provides a feature to help with this, called speccing. If you +use a class or instance as the :attr:`spec` for a mock then you can only access attributes on the mock that exist on the real class: >>> from urllib import request @@ -2108,9 +2162,9 @@ with any methods on the mock: <mock.Mock object at 0x...> >>> mock.has_data.assret_called_with() -Auto-speccing solves this problem. You can either pass `autospec=True` to -`patch` / `patch.object` or use the `create_autospec` function to create a -mock with a spec. If you use the `autospec=True` argument to `patch` then the +Auto-speccing solves this problem. You can either pass ``autospec=True`` to +:func:`patch` / :func:`patch.object` or use the :func:`create_autospec` function to create a +mock with a spec. If you use the ``autospec=True`` argument to :func:`patch` then the object that is being replaced will be used as the spec object. Because the speccing is done "lazily" (the spec is created as attributes on the mock are accessed) you can use it with very complex or deeply nested objects (like @@ -2127,8 +2181,8 @@ Here's an example of it in use: >>> mock_request.Request <MagicMock name='request.Request' spec='Request' id='...'> -You can see that `request.Request` has a spec. `request.Request` takes two -arguments in the constructor (one of which is `self`). Here's what happens if +You can see that :class:`request.Request` has a spec. :class:`request.Request` takes two +arguments in the constructor (one of which is *self*). Here's what happens if we try to call it incorrectly: >>> req = request.Request() @@ -2143,8 +2197,8 @@ specced mocks): >>> req <NonCallableMagicMock name='request.Request()' spec='Request' id='...'> -`Request` objects are not callable, so the return value of instantiating our -mocked out `request.Request` is a non-callable mock. With the spec in place +:class:`Request` objects are not callable, so the return value of instantiating our +mocked out :class:`request.Request` is a non-callable mock. With the spec in place any typos in our asserts will raise the correct error: >>> req.add_header('spam', 'eggs') @@ -2155,11 +2209,11 @@ any typos in our asserts will raise the correct error: AttributeError: Mock object has no attribute 'assret_called_with' >>> req.add_header.assert_called_with('spam', 'eggs') -In many cases you will just be able to add `autospec=True` to your existing -`patch` calls and then be protected against bugs due to typos and api +In many cases you will just be able to add ``autospec=True`` to your existing +:func:`patch` calls and then be protected against bugs due to typos and api changes. -As well as using `autospec` through `patch` there is a +As well as using *autospec* through :func:`patch` there is a :func:`create_autospec` for creating autospecced mocks directly: >>> from urllib import request @@ -2177,8 +2231,8 @@ able to use autospec. On the other hand it is much better to design your objects so that introspection is safe [#]_. A more serious problem is that it is common for instance attributes to be -created in the `__init__` method and not to exist on the class at all. -`autospec` can't know about any dynamically created attributes and restricts +created in the :meth:`__init__` method and not to exist on the class at all. +*autospec* can't know about any dynamically created attributes and restricts the api to visible attributes. >>> class Something: @@ -2195,7 +2249,7 @@ the api to visible attributes. There are a few different ways of resolving this problem. The easiest, but not necessarily the least annoying, way is to simply set the required -attributes on the mock after creation. Just because `autospec` doesn't allow +attributes on the mock after creation. Just because *autospec* doesn't allow you to fetch attributes that don't exist on the spec it doesn't prevent you setting them: @@ -2204,7 +2258,7 @@ setting them: ... thing.a = 33 ... -There is a more aggressive version of both `spec` and `autospec` that *does* +There is a more aggressive version of both *spec* and *autospec* that *does* prevent you setting non-existent attributes. This is useful if you want to ensure your code only *sets* valid attributes too, but obviously it prevents this particular scenario: @@ -2218,8 +2272,8 @@ this particular scenario: AttributeError: Mock object has no attribute 'a' Probably the best way of solving the problem is to add class attributes as -default values for instance members initialised in `__init__`. Note that if -you are only setting default attributes in `__init__` then providing them via +default values for instance members initialised in :meth:`__init__`. Note that if +you are only setting default attributes in :meth:`__init__` then providing them via class attributes (shared between instances of course) is faster too. e.g. .. code-block:: python @@ -2228,12 +2282,12 @@ class attributes (shared between instances of course) is faster too. e.g. a = 33 This brings up another issue. It is relatively common to provide a default -value of `None` for members that will later be an object of a different type. -`None` would be useless as a spec because it wouldn't let you access *any* -attributes or methods on it. As `None` is *never* going to be useful as a +value of ``None`` for members that will later be an object of a different type. +``None`` would be useless as a spec because it wouldn't let you access *any* +attributes or methods on it. As ``None`` is *never* going to be useful as a spec, and probably indicates a member that will normally of some other type, -`autospec` doesn't use a spec for members that are set to `None`. These will -just be ordinary mocks (well - `MagicMocks`): +autospec doesn't use a spec for members that are set to ``None``. These will +just be ordinary mocks (well - MagicMocks): >>> class Something: ... member = None @@ -2247,8 +2301,8 @@ then there are more options. One of these is simply to use an instance as the spec rather than the class. The other is to create a subclass of the production class and add the defaults to the subclass without affecting the production class. Both of these require you to use an alternative object as -the spec. Thankfully `patch` supports this - you can simply pass the -alternative object as the `autospec` argument: +the spec. Thankfully :func:`patch` supports this - you can simply pass the +alternative object as the *autospec* argument: >>> class Something: ... def __init__(self): @@ -2265,5 +2319,5 @@ alternative object as the `autospec` argument: .. [#] This only applies to classes or already instantiated objects. Calling a mocked class to create a mock instance *does not* create a real instance. - It is only attribute lookups - along with calls to `dir` - that are done. + It is only attribute lookups - along with calls to :func:`dir` - that are done. diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index 63106242129f..d3a3649f840f 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -47,15 +47,15 @@ test runner Module :mod:`doctest` Another test-support module with a very different flavor. - `Simple Smalltalk Testing: With Patterns <http://www.XProgramming.com/testfram.htm>`_ + `Simple Smalltalk Testing: With Patterns <https://web.archive.org/web/20150315073817/http://www.xprogramming.com/testfram.htm>`_ Kent Beck's original paper on testing frameworks using the pattern shared by :mod:`unittest`. - `Nose <http://code.google.com/p/python-nose/>`_ and `py.test <http://pytest.org>`_ + `Nose <https://nose.readthedocs.org/en/latest/>`_ and `py.test <http://pytest.org>`_ Third-party unittest frameworks with a lighter-weight syntax for writing tests. For example, ``assert func(10) == 42``. - `The Python Testing Tools Taxonomy <http://wiki.python.org/moin/PythonTestingToolsTaxonomy>`_ + `The Python Testing Tools Taxonomy <https://wiki.python.org/moin/PythonTestingToolsTaxonomy>`_ An extensive list of Python testing tools including functional testing frameworks and mock object libraries. @@ -67,7 +67,7 @@ test runner a GUI tool for test discovery and execution. This is intended largely for ease of use for those new to unit testing. For production environments it is recommended that tests be driven by a continuous integration system such as - `Buildbot <http://buildbot.net/trac>`_, `Jenkins <http://jenkins-ci.org>`_ + `Buildbot <http://buildbot.net/>`_, `Jenkins <http://jenkins-ci.org/>`_ or `Hudson <http://hudson-ci.org/>`_. @@ -80,37 +80,29 @@ The :mod:`unittest` module provides a rich set of tools for constructing and running tests. This section demonstrates that a small subset of the tools suffice to meet the needs of most users. -Here is a short script to test three functions from the :mod:`random` module:: +Here is a short script to test three string methods:: - import random - import unittest - - class TestSequenceFunctions(unittest.TestCase): + import unittest - def setUp(self): - self.seq = list(range(10)) + class TestStringMethods(unittest.TestCase): - def test_shuffle(self): - # make sure the shuffled sequence does not lose any elements - random.shuffle(self.seq) - self.seq.sort() - self.assertEqual(self.seq, list(range(10))) + def test_upper(self): + self.assertEqual('foo'.upper(), 'FOO') - # should raise an exception for an immutable sequence - self.assertRaises(TypeError, random.shuffle, (1,2,3)) + def test_isupper(self): + self.assertTrue('FOO'.isupper()) + self.assertFalse('Foo'.isupper()) - def test_choice(self): - element = random.choice(self.seq) - self.assertTrue(element in self.seq) + def test_split(self): + s = 'hello world' + self.assertEqual(s.split(), ['hello', 'world']) + # check that s.split fails when the separator is not a string + with self.assertRaises(TypeError): + s.split(2) - def test_sample(self): - with self.assertRaises(ValueError): - random.sample(self.seq, 20) - for element in random.sample(self.seq, 5): - self.assertTrue(element in self.seq) + if __name__ == '__main__': + unittest.main() - if __name__ == '__main__': - unittest.main() A testcase is created by subclassing :class:`unittest.TestCase`. The three individual tests are defined with methods whose names start with the letters @@ -118,16 +110,15 @@ individual tests are defined with methods whose names start with the letters represent tests. The crux of each test is a call to :meth:`~TestCase.assertEqual` to check for an -expected result; :meth:`~TestCase.assertTrue` to verify a condition; or -:meth:`~TestCase.assertRaises` to verify that an expected exception gets raised. -These methods are used instead of the :keyword:`assert` statement so the test -runner can accumulate all test results and produce a report. +expected result; :meth:`~TestCase.assertTrue` or :meth:`~TestCase.assertFalse` +to verify a condition; or :meth:`~TestCase.assertRaises` to verify that a +specific exception gets raised. These methods are used instead of the +:keyword:`assert` statement so the test runner can accumulate all test results +and produce a report. -When a :meth:`~TestCase.setUp` method is defined, the test runner will run that -method prior to each test. Likewise, if a :meth:`~TestCase.tearDown` method is -defined, the test runner will invoke that method after each test. In the -example, :meth:`~TestCase.setUp` was used to create a fresh sequence for each -test. +The :meth:`~TestCase.setUp` and :meth:`~TestCase.tearDown` methods allow you +to define instructions that will be executed before and after each test method. +They are covered in more details in the section :ref:`organizing-tests`. The final block shows a simple way to run the tests. :func:`unittest.main` provides a command-line interface to the test script. When run from the command @@ -142,12 +133,12 @@ line, the above script produces an output that looks like this:: Passing the ``-v`` option to your test script will instruct :func:`unittest.main` to enable a higher level of verbosity, and produce the following output:: - test_choice (__main__.TestSequenceFunctions) ... ok - test_sample (__main__.TestSequenceFunctions) ... ok - test_shuffle (__main__.TestSequenceFunctions) ... ok + test_isupper (__main__.TestStringMethods) ... ok + test_split (__main__.TestStringMethods) ... ok + test_upper (__main__.TestStringMethods) ... ok ---------------------------------------------------------------------- - Ran 3 tests in 0.110s + Ran 3 tests in 0.001s OK @@ -213,8 +204,8 @@ Command-line options .. cmdoption:: -c, --catch - Control-C during the test run waits for the current test to end and then - reports all the results so far. A second control-C raises the normal + :kbd:`Control-C` during the test run waits for the current test to end and then + reports all the results so far. A second :kbd:`Control-C` raises the normal :exc:`KeyboardInterrupt` exception. See `Signal Handling`_ for the functions that provide this functionality. @@ -223,9 +214,16 @@ Command-line options Stop the test run on the first error or failure. +.. cmdoption:: --locals + + Show local variables in tracebacks. + .. versionadded:: 3.2 The command-line options ``-b``, ``-c`` and ``-f`` were added. +.. versionadded:: 3.5 + The command-line option ``--locals``. + The command line can also be used for test discovery, for running all of the tests in a project or just a subset. @@ -239,9 +237,10 @@ Test Discovery Unittest supports simple test discovery. In order to be compatible with test discovery, all of the test files must be :ref:`modules <tut-modules>` or -:ref:`packages <tut-packages>` importable from the top-level directory of -the project (this means that their filenames must be valid -:ref:`identifiers <identifiers>`). +:ref:`packages <tut-packages>` (including :term:`namespace packages +<namespace package>`) importable from the top-level directory of +the project (this means that their filenames must be valid :ref:`identifiers +<identifiers>`). Test discovery is implemented in :meth:`TestLoader.discover`, but can also be used from the command line. The basic command-line usage is:: @@ -279,8 +278,8 @@ The :option:`-s`, :option:`-p`, and :option:`-t` options can be passed in as positional arguments in that order. The following two command lines are equivalent:: - python -m unittest discover -s project_directory -p '*_test.py' - python -m unittest discover project_directory '*_test.py' + python -m unittest discover -s project_directory -p "*_test.py" + python -m unittest discover project_directory "*_test.py" As well as being a path it is possible to pass a package name, for example ``myproject.subpackage.test``, as the start directory. The package name you @@ -306,6 +305,9 @@ as the start directory. Test modules and packages can customize test loading and discovery by through the `load_tests protocol`_. +.. versionchanged:: 3.4 + Test discovery supports :term:`namespace packages <namespace package>`. + .. _organizing-tests: @@ -559,8 +561,9 @@ The following decorators implement test skipping and expected failures: Usually you can use :meth:`TestCase.skipTest` or one of the skipping decorators instead of raising this directly. -Skipped tests will not have :meth:`setUp` or :meth:`tearDown` run around them. -Skipped classes will not have :meth:`setUpClass` or :meth:`tearDownClass` run. +Skipped tests will not have :meth:`~TestCase.setUp` or :meth:`~TestCase.tearDown` run around them. +Skipped classes will not have :meth:`~TestCase.setUpClass` or :meth:`~TestCase.tearDownClass` run. +Skipped modules will not have :func:`setUpModule` or :func:`tearDownModule` run. .. _subtests: @@ -648,10 +651,8 @@ Test cases kinds of failure. Each instance of :class:`TestCase` will run a single base method: the method - named *methodName*. However, the standard implementation of the default - *methodName*, ``runTest()``, will run every method starting with ``test`` - as an individual test, and count successes and failures accordingly. - Therefore, in most uses of :class:`TestCase`, you will neither change + named *methodName*. + In most uses of :class:`TestCase`, you will neither change the *methodName* nor reimplement the default ``runTest()`` method. .. versionchanged:: 3.2 @@ -669,9 +670,9 @@ Test cases .. method:: setUp() Method called to prepare the test fixture. This is called immediately - before calling the test method; any exception raised by this method will - be considered an error rather than a test failure. The default - implementation does nothing. + before calling the test method; other than :exc:`AssertionError` or :exc:`SkipTest`, + any exception raised by this method will be considered an error rather than + a test failure. The default implementation does nothing. .. method:: tearDown() @@ -679,10 +680,10 @@ Test cases Method called immediately after the test method has been called and the result recorded. This is called even if the test method raised an exception, so the implementation in subclasses may need to be particularly - careful about checking internal state. Any exception raised by this - method will be considered an error rather than a test failure. This - method will only be called if the :meth:`setUp` succeeds, regardless of - the outcome of the test method. The default implementation does nothing. + careful about checking internal state. Any exception, other than :exc:`AssertionError` + or :exc:`SkipTest`, raised by this method will be considered an error rather than a + test failure. This method will only be called if the :meth:`setUp` succeeds, + regardless of the outcome of the test method. The default implementation does nothing. .. method:: setUpClass() @@ -1547,6 +1548,20 @@ Loading and running tests :data:`unittest.defaultTestLoader`. Using a subclass or instance, however, allows customization of some configurable properties. + :class:`TestLoader` objects have the following attributes: + + + .. attribute:: errors + + A list of the non-fatal errors encountered while loading tests. Not reset + by the loader at any point. Fatal errors are signalled by the relevant + a method raising an exception to the caller. Non-fatal errors are also + indicated by a synthetic test that will raise the original error when + run. + + .. versionadded:: 3.5 + + :class:`TestLoader` objects have the following methods: @@ -1555,8 +1570,14 @@ Loading and running tests Return a suite of all tests cases contained in the :class:`TestCase`\ -derived :class:`testCaseClass`. + A test case instance is created for each method named by + :meth:`getTestCaseNames`. By default these are the method names + beginning with ``test``. If :meth:`getTestCaseNames` returns no + methods, but the :meth:`runTest` method is implemented, a single test + case is created for that method instead. + - .. method:: loadTestsFromModule(module) + .. method:: loadTestsFromModule(module, pattern=None) Return a suite of all tests cases contained in the given module. This method searches *module* for classes derived from :class:`TestCase` and @@ -1573,11 +1594,18 @@ Loading and running tests If a module provides a ``load_tests`` function it will be called to load the tests. This allows modules to customize test loading. - This is the `load_tests protocol`_. + This is the `load_tests protocol`_. The *pattern* argument is passed as + the third argument to ``load_tests``. .. versionchanged:: 3.2 Support for ``load_tests`` added. + .. versionchanged:: 3.5 + The undocumented and unofficial *use_load_tests* default argument is + deprecated and ignored, although it is still accepted for backward + compatibility. The method also now accepts a keyword-only argument + *pattern* which is passed to ``load_tests`` as the third argument. + .. method:: loadTestsFromName(name, module=None) @@ -1603,6 +1631,12 @@ Loading and running tests The method optionally resolves *name* relative to the given *module*. + .. versionchanged:: 3.5 + If an :exc:`ImportError` or :exc:`AttributeError` occurs while traversing + *name* then a synthetic test that raises that error when run will be + returned. These errors are included in the errors accumulated by + self.errors. + .. method:: loadTestsFromNames(names, module=None) @@ -1619,28 +1653,32 @@ Loading and running tests .. method:: discover(start_dir, pattern='test*.py', top_level_dir=None) - Find and return all test modules from the specified start directory, - recursing into subdirectories to find them. Only test files that match - *pattern* will be loaded. (Using shell style pattern matching.) Only - module names that are importable (i.e. are valid Python identifiers) will - be loaded. + Find all the test modules by recursing into subdirectories from the + specified start directory, and return a TestSuite object containing them. + Only test files that match *pattern* will be loaded. (Using shell style + pattern matching.) Only module names that are importable (i.e. are valid + Python identifiers) will be loaded. All test modules must be importable from the top level of the project. If the start directory is not the top level directory then the top level directory must be specified separately. - If importing a module fails, for example due to a syntax error, then this - will be recorded as a single error and discovery will continue. If the - import failure is due to :exc:`SkipTest` being raised, it will be recorded - as a skip instead of an error. + If importing a module fails, for example due to a syntax error, then + this will be recorded as a single error and discovery will continue. If + the import failure is due to :exc:`SkipTest` being raised, it will be + recorded as a skip instead of an error. - If a test package name (directory with :file:`__init__.py`) matches the - pattern then the package will be checked for a ``load_tests`` - function. If this exists then it will be called with *loader*, *tests*, - *pattern*. + If a package (a directory containing a file named :file:`__init__.py`) is + found, the package will be checked for a ``load_tests`` function. If this + exists then it will be called + ``package.load_tests(loader, tests, pattern)``. Test discovery takes care + to ensure that a package is only checked for tests once during an + invocation, even if the load_tests function itself calls + ``loader.discover``. - If load_tests exists then discovery does *not* recurse into the package, - ``load_tests`` is responsible for loading all tests in the package. + If ``load_tests`` exists then discovery does *not* recurse into the + package, ``load_tests`` is responsible for loading all tests in the + package. The pattern is deliberately not stored as a loader attribute so that packages can continue discovery themselves. *top_level_dir* is stored so @@ -1653,12 +1691,16 @@ Loading and running tests .. versionchanged:: 3.4 Modules that raise :exc:`SkipTest` on import are recorded as skips, - not errors. + not errors. + Discovery works for :term:`namespace packages <namespace package>`. + Paths are sorted before being imported so that execution order is + the same even if the underlying file system's ordering is not + dependent on file name. - .. versionchanged:: 3.4 - Paths are sorted before being imported to ensure execution order for a - given test suite is the same even if the underlying file system's ordering - is not dependent on file name like in ext3/4. + .. versionchanged:: 3.5 + Found packages are now checked for ``load_tests`` regardless of + whether their path matches *pattern*, because it is impossible for + a package name to match the default pattern. The following attributes of a :class:`TestLoader` can be configured either by @@ -1742,12 +1784,10 @@ Loading and running tests Set to ``True`` when the execution of tests should stop by :meth:`stop`. - .. attribute:: testsRun The total number of tests run so far. - .. attribute:: buffer If set to true, ``sys.stdout`` and ``sys.stderr`` will be buffered in between @@ -1757,7 +1797,6 @@ Loading and running tests .. versionadded:: 3.2 - .. attribute:: failfast If set to true :meth:`stop` will be called on the first failure or error, @@ -1765,12 +1804,20 @@ Loading and running tests .. versionadded:: 3.2 + .. attribute:: tb_locals + + If set to true then local variables will be shown in tracebacks. + + .. versionadded:: 3.5 .. method:: wasSuccessful() Return ``True`` if all tests run so far have passed, otherwise returns ``False``. + .. versionchanged:: 3.4 + Returns ``False`` if there were any :attr:`unexpectedSuccesses` + from tests marked with the :func:`expectedFailure` decorator. .. method:: stop() @@ -1799,14 +1846,14 @@ Loading and running tests Called after the test case *test* has been executed, regardless of the outcome. - .. method:: startTestRun(test) + .. method:: startTestRun() Called once before any tests are executed. .. versionadded:: 3.1 - .. method:: stopTestRun(test) + .. method:: stopTestRun() Called once after all tests are executed. @@ -1903,21 +1950,24 @@ Loading and running tests .. class:: TextTestRunner(stream=None, descriptions=True, verbosity=1, failfast=False, \ - buffer=False, resultclass=None, warnings=None) + buffer=False, resultclass=None, warnings=None, *, tb_locals=False) A basic test runner implementation that outputs results to a stream. If *stream* is ``None``, the default, :data:`sys.stderr` is used as the output stream. This class has a few configurable parameters, but is essentially very simple. Graphical - applications which run test suites should provide alternate implementations. + applications which run test suites should provide alternate implementations. Such + implementations should accept ``**kwargs`` as the interface to construct runners + changes when features are added to unittest. By default this runner shows :exc:`DeprecationWarning`, - :exc:`PendingDeprecationWarning`, and :exc:`ImportWarning` even if they are - :ref:`ignored by default <warning-ignored>`. Deprecation warnings caused by - :ref:`deprecated unittest methods <deprecated-aliases>` are also - special-cased and, when the warning filters are ``'default'`` or ``'always'``, - they will appear only once per-module, in order to avoid too many warning - messages. This behavior can be overridden using the :option:`-Wd` or - :option:`-Wa` options and leaving *warnings* to ``None``. + :exc:`PendingDeprecationWarning`, :exc:`ResourceWarning` and + :exc:`ImportWarning` even if they are :ref:`ignored by default + <warning-ignored>`. Deprecation warnings caused by :ref:`deprecated unittest + methods <deprecated-aliases>` are also special-cased and, when the warning + filters are ``'default'`` or ``'always'``, they will appear only once + per-module, in order to avoid too many warning messages. This behavior can + be overridden using the :option:`-Wd` or :option:`-Wa` options and leaving + *warnings* to ``None``. .. versionchanged:: 3.2 Added the ``warnings`` argument. @@ -1926,6 +1976,9 @@ Loading and running tests The default stream is set to :data:`sys.stderr` at instantiation time rather than import time. + .. versionchanged:: 3.5 + Added the tb_locals parameter. + .. method:: _makeResult() This method returns the instance of ``TestResult`` used by :meth:`run`. @@ -1939,6 +1992,14 @@ Loading and running tests stream, descriptions, verbosity + .. method:: run(test) + + This method is the main public interface to the `TextTestRunner`. This + method takes a :class:`TestSuite` or :class:`TestCase` instance. A + :class:`TestResult` is created by calling + :func:`_makeResult` and the test(s) are run and the + results printed to stdout. + .. function:: main(module='__main__', defaultTest=None, argv=None, testRunner=None, \ testLoader=unittest.defaultTestLoader, exit=True, verbosity=1, \ @@ -1958,6 +2019,11 @@ Loading and running tests if __name__ == '__main__': unittest.main(verbosity=2) + The *defaultTest* argument is either the name of a single test or an + iterable of test names to run if no test names are specified via *argv*. If + not specified or ``None`` and no test names are provided via *argv*, all + tests found in *module* are run. + The *argv* argument can be a list of options passed to the program, with the first element being the program name. If not specified or ``None``, the values of :data:`sys.argv` are used. @@ -2010,7 +2076,10 @@ test runs or test discovery by implementing a function called ``load_tests``. If a test module defines ``load_tests`` it will be called by :meth:`TestLoader.loadTestsFromModule` with the following arguments:: - load_tests(loader, standard_tests, None) + load_tests(loader, standard_tests, pattern) + +where *pattern* is passed straight through from ``loadTestsFromModule``. It +defaults to ``None``. It should return a :class:`TestSuite`. @@ -2032,21 +2101,12 @@ A typical ``load_tests`` function that loads tests from a specific set of suite.addTests(tests) return suite -If discovery is started, either from the command line or by calling -:meth:`TestLoader.discover`, with a pattern that matches a package -name then the package :file:`__init__.py` will be checked for ``load_tests``. - -.. note:: - - The default pattern is ``'test*.py'``. This matches all Python files - that start with ``'test'`` but *won't* match any test directories. - - A pattern like ``'test*'`` will match test packages as well as - modules. - -If the package :file:`__init__.py` defines ``load_tests`` then it will be -called and discovery not continued into the package. ``load_tests`` -is called with the following arguments:: +If discovery is started in a directory containing a package, either from the +command line or by calling :meth:`TestLoader.discover`, then the package +:file:`__init__.py` will be checked for ``load_tests``. If that function does +not exist, discovery will recurse into the package as though it were just +another directory. Otherwise, discovery of the package's tests will be left up +to ``load_tests`` which is called with the following arguments:: load_tests(loader, standard_tests, pattern) @@ -2065,6 +2125,11 @@ continue (and potentially modify) test discovery. A 'do nothing' standard_tests.addTests(package_tests) return standard_tests +.. versionchanged:: 3.5 + Discovery no longer checks package names for matching *pattern* due to the + impossibility of package names matching the default pattern. + + Class and Module Fixtures ------------------------- diff --git a/Doc/library/urllib.error.rst b/Doc/library/urllib.error.rst index 9fb58f508358..f7f0c9739d8c 100644 --- a/Doc/library/urllib.error.rst +++ b/Doc/library/urllib.error.rst @@ -48,7 +48,7 @@ The following exceptions are raised by :mod:`urllib.error` as appropriate: .. attribute:: headers - The HTTP response headers for the HTTP request that cause the + The HTTP response headers for the HTTP request that caused the :exc:`HTTPError`. .. versionadded:: 3.4 diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst index b95142042d87..7c075adf2afa 100644 --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -76,12 +76,15 @@ or on combining URL components into a URL string. ParseResult(scheme='', netloc='', path='help/Python.html', params='', query='', fragment='') - If the *scheme* argument is specified, it gives the default addressing - scheme, to be used only if the URL does not specify one. The default value for - this argument is the empty string. + The *scheme* argument gives the default addressing scheme, to be + used only if the URL does not specify one. It should be the same type + (text or bytes) as *urlstring*, except that the default value ``''`` is + always allowed, and is automatically converted to ``b''`` if appropriate. If the *allow_fragments* argument is false, fragment identifiers are not - allowed. The default value for this argument is :const:`True`. + recognized. Instead, they are parsed as part of the path, parameters + or query component, and :attr:`fragment` is set to the empty string in + the return value. The return value is actually an instance of a subclass of :class:`tuple`. This class has the following additional read-only convenience attributes: @@ -89,7 +92,7 @@ or on combining URL components into a URL string. +------------------+-------+--------------------------+----------------------+ | Attribute | Index | Value | Value if not present | +==================+=======+==========================+======================+ - | :attr:`scheme` | 0 | URL scheme specifier | empty string | + | :attr:`scheme` | 0 | URL scheme specifier | *scheme* parameter | +------------------+-------+--------------------------+----------------------+ | :attr:`netloc` | 1 | Network location part | empty string | +------------------+-------+--------------------------+----------------------+ @@ -112,8 +115,9 @@ or on combining URL components into a URL string. | | | if present | | +------------------+-------+--------------------------+----------------------+ - See section :ref:`urlparse-result-object` for more information on the result - object. + Reading the :attr:`port` attribute will raise a :exc:`ValueError` if + an invalid port is specified in the URL. See section + :ref:`urlparse-result-object` for more information on the result object. .. versionchanged:: 3.2 Added IPv6 URL parsing capabilities. @@ -123,6 +127,10 @@ or on combining URL components into a URL string. false), in accordance with :rfc:`3986`. Previously, a whitelist of schemes that support fragments existed. + .. versionchanged:: 3.6 + Out-of-range port numbers now raise :exc:`ValueError`, instead of + returning :const:`None`. + .. function:: parse_qs(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace') @@ -205,7 +213,7 @@ or on combining URL components into a URL string. +------------------+-------+-------------------------+----------------------+ | Attribute | Index | Value | Value if not present | +==================+=======+=========================+======================+ - | :attr:`scheme` | 0 | URL scheme specifier | empty string | + | :attr:`scheme` | 0 | URL scheme specifier | *scheme* parameter | +------------------+-------+-------------------------+----------------------+ | :attr:`netloc` | 1 | Network location part | empty string | +------------------+-------+-------------------------+----------------------+ @@ -225,8 +233,13 @@ or on combining URL components into a URL string. | | | if present | | +------------------+-------+-------------------------+----------------------+ - See section :ref:`urlparse-result-object` for more information on the result - object. + Reading the :attr:`port` attribute will raise a :exc:`ValueError` if + an invalid port is specified in the URL. See section + :ref:`urlparse-result-object` for more information on the result object. + + .. versionchanged:: 3.6 + Out-of-range port numbers now raise :exc:`ValueError`, instead of + returning :const:`None`. .. function:: urlunsplit(parts) @@ -267,6 +280,11 @@ or on combining URL components into a URL string. :func:`urlunsplit`, removing possible *scheme* and *netloc* parts. + .. versionchanged:: 3.5 + + Behaviour updated to match the semantics defined in :rfc:`3986`. + + .. function:: urldefrag(url) If *url* contains a fragment identifier, return a modified version of *url* @@ -513,17 +531,26 @@ task isn't already covered by the URL parsing functions above. Example: ``unquote_to_bytes('a%26%EF')`` yields ``b'a&\xef'``. -.. function:: urlencode(query, doseq=False, safe='', encoding=None, errors=None) +.. function:: urlencode(query, doseq=False, safe='', encoding=None, \ + errors=None, quote_via=quote_plus) Convert a mapping object or a sequence of two-element tuples, which may - either be a :class:`str` or a :class:`bytes`, to a "percent-encoded" + contain :class:`str` or :class:`bytes` objects, to a "percent-encoded" string. If the resultant string is to be used as a *data* for POST operation with :func:`~urllib.request.urlopen` function, then it should be properly encoded to bytes, otherwise it would result in a :exc:`TypeError`. The resulting string is a series of ``key=value`` pairs separated by ``'&'`` - characters, where both *key* and *value* are quoted using :func:`quote_plus` - above. When a sequence of two-element tuples is used as the *query* + characters, where both *key* and *value* are quoted using the *quote_via* + function. By default, :func:`quote_plus` is used to quote the values, which + means spaces are quoted as a ``'+'`` character and '/' characters are + encoded as ``%2F``, which follows the standard for GET requests + (``application/x-www-form-urlencoded``). An alternate function that can be + passed as *quote_via* is :func:`quote`, which will encode spaces as ``%20`` + and not encode '/' characters. For maximum control of what is quoted, use + ``quote`` and specify a value for *safe*. + + When a sequence of two-element tuples is used as the *query* argument, the first element of each tuple is a key and the second is a value. The value element in itself can be a sequence and in that case, if the optional parameter *doseq* is evaluates to *True*, individual @@ -531,8 +558,9 @@ task isn't already covered by the URL parsing functions above. the value sequence for the key. The order of parameters in the encoded string will match the order of parameter tuples in the sequence. - When *query* parameter is a :class:`str`, the *safe*, *encoding* and *error* - parameters are passed down to :func:`quote_plus` for encoding. + The *safe*, *encoding*, and *errors* parameters are passed down to + *quote_via* (the *encoding* and *errors* parameters are only passed + when a query element is a :class:`str`). To reverse this encoding process, :func:`parse_qs` and :func:`parse_qsl` are provided in this module to parse query strings into Python data structures. @@ -543,6 +571,9 @@ task isn't already covered by the URL parsing functions above. .. versionchanged:: 3.2 Query parameter supports bytes and string objects. + .. versionadded:: 3.5 + *quote_via* parameter. + .. seealso:: diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index c4dd7e3b33f0..18df07888e2a 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -12,11 +12,16 @@ The :mod:`urllib.request` module defines functions and classes which help in opening URLs (mostly HTTP) in a complex world --- basic and digest authentication, redirections, cookies and more. +.. seealso:: + + The `Requests package <http://requests.readthedocs.org/>`_ + is recommended for a higher-level http client interface. + The :mod:`urllib.request` module defines the following functions: -.. function:: urlopen(url, data=None[, timeout], *, cafile=None, capath=None, cadefault=False) +.. function:: urlopen(url, data=None[, timeout], *, cafile=None, capath=None, cadefault=False, context=None) Open the URL *url*, which can be either a string or a :class:`Request` object. @@ -47,27 +52,23 @@ The :mod:`urllib.request` module defines the following functions: the global default timeout setting will be used). This actually only works for HTTP, HTTPS and FTP connections. + If *context* is specified, it must be a :class:`ssl.SSLContext` instance + describing the various SSL options. See :class:`~http.client.HTTPSConnection` + for more details. + The optional *cafile* and *capath* parameters specify a set of trusted CA certificates for HTTPS requests. *cafile* should point to a single file containing a bundle of CA certificates, whereas *capath* should point to a directory of hashed certificate files. More information can be found in :meth:`ssl.SSLContext.load_verify_locations`. - The *cadefault* parameter specifies whether to fall back to loading a - default certificate store defined by the underlying OpenSSL library if the - *cafile* and *capath* parameters are omitted. This will only work on - some non-Windows platforms. - - .. warning:: - If neither *cafile* nor *capath* is specified, and *cadefault* is ``False``, - an HTTPS request will not do any verification of the server's - certificate. + The *cadefault* parameter is ignored. For http and https urls, this function returns a :class:`http.client.HTTPResponse` object which has the following :ref:`httpresponse-objects` methods. - For ftp, file, and data urls and requests explicity handled by legacy + For ftp, file, and data urls and requests explicitly handled by legacy :class:`URLopener` and :class:`FancyURLopener` classes, this function returns a :class:`urllib.response.addinfourl` object which can work as :term:`context manager` and has methods such as @@ -111,6 +112,10 @@ The :mod:`urllib.request` module defines the following functions: .. versionchanged:: 3.3 *cadefault* was added. + .. versionchanged:: 3.4.3 + *context* was added. + + .. function:: install_opener(opener) Install an :class:`OpenerDirector` instance as the default global opener. @@ -197,7 +202,7 @@ The following classes are provided: ``"Python-urllib/2.6"`` (on Python 2.6). An example of using ``Content-Type`` header with *data* argument would be - sending a dictionary like ``{"Content-Type":" application/x-www-form-urlencoded;charset=utf-8"}`` + sending a dictionary like ``{"Content-Type":" application/x-www-form-urlencoded;charset=utf-8"}``. The final two arguments are only of interest for correct handling of third-party HTTP cookies: @@ -218,7 +223,7 @@ The following classes are provided: fetching of the image, this should be true. *method* should be a string that indicates the HTTP request method that - will be used (e.g. ``'HEAD'``). Its value is stored in the + will be used (e.g. ``'HEAD'``). If provided, its value is stored in the :attr:`~Request.method` attribute and is used by :meth:`get_method()`. Subclasses may indicate a default method by setting the :attr:`~Request.method` attribute in the class itself. @@ -283,13 +288,37 @@ The following classes are provided: fits. +.. class:: HTTPPasswordMgrWithPriorAuth() + + A variant of :class:`HTTPPasswordMgrWithDefaultRealm` that also has a + database of ``uri -> is_authenticated`` mappings. Can be used by a + BasicAuth handler to determine when to send authentication credentials + immediately instead of waiting for a ``401`` response first. + + .. versionadded:: 3.5 + + .. class:: AbstractBasicAuthHandler(password_mgr=None) This is a mixin class that helps with HTTP authentication, both to the remote host and to a proxy. *password_mgr*, if given, should be something that is compatible with :class:`HTTPPasswordMgr`; refer to section :ref:`http-password-mgr` for information on the interface that must be - supported. + supported. If *passwd_mgr* also provides ``is_authenticated`` and + ``update_authenticated`` methods (see + :ref:`http-password-mgr-with-prior-auth`), then the handler will use the + ``is_authenticated`` result for a given URI to determine whether or not to + send authentication credentials with the request. If ``is_authenticated`` + returns ``True`` for the URI, credentials are sent. If ``is_authenticated`` + is ``False``, credentials are not sent, and then if a ``401`` response is + received the request is re-sent with the authentication credentials. If + authentication succeeds, ``update_authenticated`` is called to set + ``is_authenticated`` ``True`` for the URI, so that subsequent requests to + the URI or any of its super-URIs will automatically include the + authentication credentials. + + .. versionadded:: 3.5 + Added ``is_authenticated`` support. .. class:: HTTPBasicAuthHandler(password_mgr=None) @@ -440,13 +469,20 @@ request. .. attribute:: Request.method - The HTTP request method to use. This value is used by - :meth:`~Request.get_method` to override the computed HTTP request - method that would otherwise be returned. This attribute is initialized with - the value of the *method* argument passed to the constructor. + The HTTP request method to use. By default its value is :const:`None`, + which means that :meth:`~Request.get_method` will do its normal computation + of the method to be used. Its value can be set (thus overriding the default + computation in :meth:`~Request.get_method`) either by providing a default + value by setting it at the class level in a :class:`Request` subclass, or by + passing a value in to the :class:`Request` constructor via the *method* + argument. .. versionadded:: 3.3 + .. versionchanged:: 3.4 + A default value can now be set in subclasses; previously it could only + be set via the constructor argument. + .. method:: Request.get_method() @@ -516,9 +552,10 @@ request. Return a list of tuples (header_name, header_value) of the Request headers. .. versionchanged:: 3.4 - Request methods add_data, has_data, get_data, get_type, get_host, - get_selector, get_origin_req_host and is_unverifiable deprecated since 3.3 - have been removed. + The request methods add_data, has_data, get_data, get_type, get_host, + get_selector, get_origin_req_host and is_unverifiable that were deprecated + since 3.3 have been removed. + .. _opener-director-objects: @@ -833,6 +870,42 @@ These methods are available on :class:`HTTPPasswordMgr` and searched if the given *realm* has no matching user/password. +.. _http-password-mgr-with-prior-auth: + +HTTPPasswordMgrWithPriorAuth Objects +------------------------------------ + +This password manager extends :class:`HTTPPasswordMgrWithDefaultRealm` to support +tracking URIs for which authentication credentials should always be sent. + + +.. method:: HTTPPasswordMgrWithPriorAuth.add_password(realm, uri, user, \ + passwd, is_authenticated=False) + + *realm*, *uri*, *user*, *passwd* are as for + :meth:`HTTPPasswordMgr.add_password`. *is_authenticated* sets the initial + value of the ``is_authenticated`` flag for the given URI or list of URIs. + If *is_authenticated* is specified as ``True``, *realm* is ignored. + + +.. method:: HTTPPasswordMgr.find_user_password(realm, authuri) + + Same as for :class:`HTTPPasswordMgrWithDefaultRealm` objects + + +.. method:: HTTPPasswordMgrWithPriorAuth.update_authenticated(self, uri, \ + is_authenticated=False) + + Update the ``is_authenticated`` flag for the given *uri* or list + of URIs. + + +.. method:: HTTPPasswordMgrWithPriorAuth.is_authenticated(self, authuri) + + Returns the current state of the ``is_authenticated`` flag for + the given URI. + + .. _abstract-basic-auth-handler: AbstractBasicAuthHandler Objects @@ -1041,8 +1114,9 @@ This example gets the python.org main page and displays the first 300 bytes of it. :: >>> import urllib.request - >>> f = urllib.request.urlopen('http://www.python.org/') - >>> print(f.read(300)) + >>> with urllib.request.urlopen('http://www.python.org/') as f: + ... print(f.read(300)) + ... b'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n\n\n<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n\n<head>\n @@ -1055,11 +1129,11 @@ it receives from the http server. In general, a program will decode the returned bytes object to string once it determines or guesses the appropriate encoding. -The following W3C document, http://www.w3.org/International/O-charset , lists +The following W3C document, http://www.w3.org/International/O-charset\ , lists the various ways in which a (X)HTML or a XML document could have specified its encoding information. -As the python.org website uses *utf-8* encoding as specified in it's meta tag, we +As the python.org website uses *utf-8* encoding as specified in its meta tag, we will use the same for decoding the bytes object. :: >>> with urllib.request.urlopen('http://www.python.org/') as f: @@ -1084,8 +1158,9 @@ when the Python installation supports SSL. :: >>> import urllib.request >>> req = urllib.request.Request(url='https://localhost/cgi-bin/test.cgi', ... data=b'This data is passed to stdin of the CGI') - >>> f = urllib.request.urlopen(req) - >>> print(f.read().decode('utf-8')) + >>> with urllib.request.urlopen(req) as f: + ... print(f.read().decode('utf-8')) + ... Got Data: "This data is passed to stdin of the CGI" The code for the sample CGI used in the above example is:: @@ -1100,7 +1175,8 @@ Here is an example of doing a ``PUT`` request using :class:`Request`:: import urllib.request DATA=b'some data' req = urllib.request.Request(url='http://localhost:8080/', data=DATA,method='PUT') - f = urllib.request.urlopen(req) + with urllib.request.urlopen(req) as f: + pass print(f.status) print(f.reason) @@ -1166,8 +1242,10 @@ containing parameters:: >>> import urllib.request >>> import urllib.parse >>> params = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0}) - >>> f = urllib.request.urlopen("http://www.musi-cal.com/cgi-bin/query?%s" % params) - >>> print(f.read().decode('utf-8')) + >>> url = "http://www.musi-cal.com/cgi-bin/query?%s" % params + >>> with urllib.request.urlopen(url) as f: + ... print(f.read().decode('utf-8')) + ... The following example uses the ``POST`` method instead. Note that params output from urlencode is encoded to bytes before it is sent to urlopen as data:: @@ -1179,8 +1257,9 @@ from urlencode is encoded to bytes before it is sent to urlopen as data:: >>> request = urllib.request.Request("http://requestb.in/xrbl82xr") >>> # adding charset parameter to the Content-Type header. >>> request.add_header("Content-Type","application/x-www-form-urlencoded;charset=utf-8") - >>> f = urllib.request.urlopen(request, data) - >>> print(f.read().decode('utf-8')) + >>> with urllib.request.urlopen(request, data) as f: + ... print(f.read().decode('utf-8')) + ... The following example uses an explicitly specified HTTP proxy, overriding environment settings:: @@ -1188,15 +1267,17 @@ environment settings:: >>> import urllib.request >>> proxies = {'http': 'http://proxy.example.com:8080/'} >>> opener = urllib.request.FancyURLopener(proxies) - >>> f = opener.open("http://www.python.org/") - >>> f.read().decode('utf-8') + >>> with opener.open("http://www.python.org/") as f: + ... f.read().decode('utf-8') + ... The following example uses no proxies at all, overriding environment settings:: >>> import urllib.request >>> opener = urllib.request.FancyURLopener({}) - >>> f = opener.open("http://www.python.org/") - >>> f.read().decode('utf-8') + >>> with opener.open("http://www.python.org/") as f: + ... f.read().decode('utf-8') + ... Legacy interface diff --git a/Doc/library/urllib.robotparser.rst b/Doc/library/urllib.robotparser.rst index f179de2f9263..c2e1bef8bbc3 100644 --- a/Doc/library/urllib.robotparser.rst +++ b/Doc/library/urllib.robotparser.rst @@ -53,15 +53,41 @@ structure of :file:`robots.txt` files, see http://www.robotstxt.org/orig.html. Sets the time the ``robots.txt`` file was last fetched to the current time. + .. method:: crawl_delay(useragent) -The following example demonstrates basic use of the RobotFileParser class. + Returns the value of the ``Crawl-delay`` parameter from ``robots.txt`` + for the *useragent* in question. If there is no such parameter or it + doesn't apply to the *useragent* specified or the ``robots.txt`` entry + for this parameter has invalid syntax, return ``None``. + + .. versionadded:: 3.6 + + .. method:: request_rate(useragent) + + Returns the contents of the ``Request-rate`` parameter from + ``robots.txt`` in the form of a :func:`~collections.namedtuple` + ``(requests, seconds)``. If there is no such parameter or it doesn't + apply to the *useragent* specified or the ``robots.txt`` entry for this + parameter has invalid syntax, return ``None``. + + .. versionadded:: 3.6 + + +The following example demonstrates basic use of the :class:`RobotFileParser` +class:: >>> import urllib.robotparser >>> rp = urllib.robotparser.RobotFileParser() >>> rp.set_url("http://www.musi-cal.com/robots.txt") >>> rp.read() + >>> rrate = rp.request_rate("*") + >>> rrate.requests + 3 + >>> rrate.seconds + 20 + >>> rp.crawl_delay("*") + 6 >>> rp.can_fetch("http://github.com/*", "http://www.musi-cal.com/cgi-bin/search?city=San+Francisco") False >>> rp.can_fetch("http://github.com/*", "http://www.musi-cal.com/") True - diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst index 461c9e170e47..e9ede8b415f9 100644 --- a/Doc/library/venv.rst +++ b/Doc/library/venv.rst @@ -40,11 +40,11 @@ Creating virtual environments A venv is a directory tree which contains Python executable files and other files which indicate that it is a venv. - Common installation tools such as ``Distribute`` and ``pip`` work as + Common installation tools such as ``Setuptools`` and ``pip`` work as expected with venvs - i.e. when a venv is active, they install Python packages into the venv without needing to be told to do so explicitly. Of course, you need to install them into the venv first: this could be - done by running ``distribute_setup.py`` with the venv activated, + done by running ``ez_setup.py`` with the venv activated, followed by running ``easy_install pip``. Alternatively, you could download the source tarballs and run ``python setup.py install`` after unpacking, with the venv activated. @@ -76,6 +76,8 @@ Creating virtual environments without there needing to be any reference to its venv in ``PATH``. +.. _venv-api: + API --- @@ -107,7 +109,8 @@ creation according to their needs, the :class:`EnvBuilder` class. upgraded in-place (defaults to ``False``). * ``with_pip`` -- a Boolean value which, if true, ensures pip is - installed in the virtual environment + installed in the virtual environment. This uses :mod:`ensurepip` with + the ``--default-pip`` option. .. versionchanged:: 3.4 Added the ``with_pip`` parameter diff --git a/Doc/library/wave.rst b/Doc/library/wave.rst index c32e1fcd857a..ab64978cfde3 100644 --- a/Doc/library/wave.rst +++ b/Doc/library/wave.rst @@ -150,14 +150,30 @@ them, and is otherwise implementation dependent. Wave_write Objects ------------------ +For seekable output streams, the ``wave`` header will automatically be updated +to reflect the number of frames actually written. For unseekable streams, the +*nframes* value must be accurate when the first frame data is written. An +accurate *nframes* value can be achieved either by calling +:meth:`~Wave_write.setnframes` or :meth:`~Wave_write.setparams` with the number +of frames that will be written before :meth:`~Wave_write.close` is called and +then using :meth:`~Wave_write.writeframesraw` to write the frame data, or by +calling :meth:`~Wave_write.writeframes` with all of the frame data to be +written. In the latter case :meth:`~Wave_write.writeframes` will calculate +the number of frames in the data and set *nframes* accordingly before writing +the frame data. + Wave_write objects, as returned by :func:`.open`, have the following methods: +.. versionchanged:: 3.4 + Added support for unseekable files. + .. method:: Wave_write.close() Make sure *nframes* is correct, and close the file if it was opened by - :mod:`wave`. This method is called upon object collection. Can raise an - exception if *nframes* is not correct and a file is not seekable. + :mod:`wave`. This method is called upon object collection. It will raise + an exception if the output stream is not seekable and *nframes* does not + match the number of frames actually written. .. method:: Wave_write.setnchannels(n) @@ -181,8 +197,9 @@ Wave_write objects, as returned by :func:`.open`, have the following methods: .. method:: Wave_write.setnframes(n) - Set the number of frames to *n*. This will be changed later if more frames are - written. + Set the number of frames to *n*. This will be changed later if the number + of frames actually written is different (this update attempt will + raise an error if the output stream is not seekable). .. method:: Wave_write.setcomptype(type, name) @@ -209,16 +226,18 @@ Wave_write objects, as returned by :func:`.open`, have the following methods: Write audio frames, without correcting *nframes*. .. versionchanged:: 3.4 - Any :term:`bytes-like object`\ s are now accepted. + Any :term:`bytes-like object` is now accepted. .. method:: Wave_write.writeframes(data) - Write audio frames and make sure *nframes* is correct. Can raise an - exception if a file is not seekable. + Write audio frames and make sure *nframes* is correct. It will raise an + error if the output stream is not seekable and the total number of frames + that have been written after *data* has been written does not match the + previously set value for *nframes*. .. versionchanged:: 3.4 - Any :term:`bytes-like object`\ s are now accepted. + Any :term:`bytes-like object` is now accepted. Note that it is invalid to set any parameters after calling :meth:`writeframes` diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index e84ac2bc0a46..2e16077b8a6a 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -123,15 +123,6 @@ Extension types can easily be made to support weak references; see weakref. If there is no callback or if the referent of the weakref is no longer alive then this attribute will have value ``None``. - .. note:: - - Like :meth:`__del__` methods, weak reference callbacks can be - called during interpreter shutdown when module globals have been - overwritten with :const:`None`. This can make writing robust - weak reference callbacks a challenge. Callbacks registered - using :class:`finalize` do not have to worry about this issue - because they will not be run after module teardown has begun. - .. versionchanged:: 3.4 Added the :attr:`__callback__` attribute. @@ -247,7 +238,7 @@ These method have the same issues as the and :meth:`keyrefs` method of .. class:: finalize(obj, func, *args, **kwargs) Return a callable finalizer object which will be called when *obj* - is garbage collected. Unlike an ordinary weak reference, a finalizer is + is garbage collected. Unlike an ordinary weak reference, a finalizer will always survive until the reference object is collected, greatly simplifying lifecycle management. @@ -267,7 +258,7 @@ These method have the same issues as the and :meth:`keyrefs` method of are called in reverse order of creation. A finalizer will never invoke its callback during the later part of - the interpreter shutdown when module globals are liable to have + the :term:`interpreter shutdown` when module globals are liable to have been replaced by :const:`None`. .. method:: __call__() @@ -536,8 +527,8 @@ follows:: Starting with Python 3.4, :meth:`__del__` methods no longer prevent reference cycles from being garbage collected, and module globals are -no longer forced to :const:`None` during interpreter shutdown. So this -code should work without any issues on CPython. +no longer forced to :const:`None` during :term:`interpreter shutdown`. +So this code should work without any issues on CPython. However, handling of :meth:`__del__` methods is notoriously implementation specific, since it depends on internal details of the interpreter's garbage @@ -575,8 +566,8 @@ third party, such as running code when a module is unloaded:: .. note:: - If you create a finalizer object in a daemonic thread just as the - the program exits then there is the possibility that the finalizer + If you create a finalizer object in a daemonic thread just as the program + exits then there is the possibility that the finalizer does not get called at exit. However, in a daemonic thread :func:`atexit.register`, ``try: ... finally: ...`` and ``with: ...`` do not guarantee that cleanup occurs either. diff --git a/Doc/library/webbrowser.rst b/Doc/library/webbrowser.rst index 9c2b3abb6923..aa5e4ad15d76 100644 --- a/Doc/library/webbrowser.rst +++ b/Doc/library/webbrowser.rst @@ -19,12 +19,12 @@ will be used if graphical browsers are not available or an X11 display isn't available. If text-mode browsers are used, the calling process will block until the user exits the browser. -If the environment variable :envvar:`BROWSER` exists, it is interpreted to -override the platform default list of browsers, as a :data:`os.pathsep`-separated -list of browsers to try in order. When the value of a list part contains the -string ``%s``, then it is interpreted as a literal browser command line to be -used with the argument URL substituted for ``%s``; if the part does not contain -``%s``, it is simply interpreted as the name of the browser to launch. [1]_ +If the environment variable :envvar:`BROWSER` exists, it is interpreted as the +:data:`os.pathsep`-separated list of browsers to try ahead of the platform +defaults. When the value of a list part contains the string ``%s``, then it is +interpreted as a literal browser command line to be used with the argument URL +substituted for ``%s``; if the part does not contain ``%s``, it is simply +interpreted as the name of the browser to launch. [1]_ For non-Unix platforms, or when a remote browser is available on Unix, the controlling process will not wait for the user to finish with the browser, but diff --git a/Doc/library/winreg.rst b/Doc/library/winreg.rst index 60f3bd91f132..6c920b4882d5 100644 --- a/Doc/library/winreg.rst +++ b/Doc/library/winreg.rst @@ -146,7 +146,7 @@ This module offers the following functions: *reserved* is a reserved integer, and must be zero. The default is zero. *access* is an integer that specifies an access mask that describes the desired - security access for the key. Default is :const:`KEY_ALL_ACCESS`. See + security access for the key. Default is :const:`KEY_WOW64_64KEY`. See :ref:`Access Rights <access-rights>` for other allowed values. *This method can not delete keys with subkeys.* @@ -322,7 +322,7 @@ This module offers the following functions: +-------+---------------------------------------------+ | ``2`` | An integer giving when the key was last | | | modified (if available) as 100's of | - | | nanoseconds since Jan 1, 1600. | + | | nanoseconds since Jan 1, 1601. | +-------+---------------------------------------------+ diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst index 1cef2e9464e2..8c091f6bc080 100644 --- a/Doc/library/wsgiref.rst +++ b/Doc/library/wsgiref.rst @@ -184,10 +184,11 @@ This module provides a single class, :class:`Headers`, for convenient manipulation of WSGI response headers using a mapping-like interface. -.. class:: Headers(headers) +.. class:: Headers([headers]) Create a mapping-like object wrapping *headers*, which must be a list of header - name/value tuples as described in :pep:`3333`. + name/value tuples as described in :pep:`3333`. The default value of *headers* is + an empty list. :class:`Headers` objects support typical mapping operations including :meth:`__getitem__`, :meth:`get`, :meth:`__setitem__`, :meth:`setdefault`, @@ -251,6 +252,10 @@ manipulation of WSGI response headers using a mapping-like interface. Content-Disposition: attachment; filename="bud.gif" + .. versionchanged:: 3.5 + *headers* parameter is optional. + + :mod:`wsgiref.simple_server` -- a simple WSGI HTTP server --------------------------------------------------------- @@ -501,7 +506,7 @@ input, output, and error streams. Similar to :class:`BaseCGIHandler`, but designed for use with HTTP origin servers. If you are writing an HTTP server implementation, you will probably - want to subclass this instead of :class:`BaseCGIHandler` + want to subclass this instead of :class:`BaseCGIHandler`. This class is a subclass of :class:`BaseHandler`. It overrides the :meth:`__init__`, :meth:`get_stdin`, :meth:`get_stderr`, :meth:`add_cgi_vars`, @@ -754,7 +759,7 @@ This is a working "Hello World" WSGI application:: # object that accepts two arguments. For that purpose, we're going to # use a function (note that you're not limited to a function, you can # use a class for example). The first argument passed to the function - # is a dictionary containing CGI-style envrironment variables and the + # is a dictionary containing CGI-style environment variables and the # second variable is the callable object (see PEP 333). def hello_world_app(environ, start_response): status = '200 OK' # HTTP Status diff --git a/Doc/library/xml.dom.minidom.rst b/Doc/library/xml.dom.minidom.rst index 5d821f17d0b3..dcd030cc1222 100644 --- a/Doc/library/xml.dom.minidom.rst +++ b/Doc/library/xml.dom.minidom.rst @@ -15,7 +15,7 @@ Model interface, with an API similar to that in other languages. It is intended to be simpler than the full DOM and also significantly smaller. Users who are not already proficient with the DOM should consider using the -:mod:`xml.etree.ElementTree` module for their XML processing instead +:mod:`xml.etree.ElementTree` module for their XML processing instead. .. warning:: @@ -252,4 +252,4 @@ utility to most DOM users. "UTF8" is not valid in an XML document's declaration, even though Python accepts it as an encoding name. See http://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl - and http://www.iana.org/assignments/character-sets . + and http://www.iana.org/assignments/character-sets/character-sets.xhtml. diff --git a/Doc/library/xml.dom.rst b/Doc/library/xml.dom.rst index 19512ed3f764..a432202ec0e9 100644 --- a/Doc/library/xml.dom.rst +++ b/Doc/library/xml.dom.rst @@ -304,7 +304,7 @@ All of the components of an XML document are subclasses of :class:`Node`. .. attribute:: Node.prefix The part of the :attr:`tagName` preceding the colon if there is one, else the - empty string. The value is a string, or ``None`` + empty string. The value is a string, or ``None``. .. attribute:: Node.namespaceURI @@ -412,7 +412,7 @@ objects: .. method:: NodeList.item(i) Return the *i*'th item from the sequence, if there is one, or ``None``. The - index *i* is not allowed to be less then zero or greater than or equal to the + index *i* is not allowed to be less than zero or greater than or equal to the length of the sequence. diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 4c89dc34ea9e..dc0274eb0bfe 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -105,12 +105,28 @@ Children are nested, and we can access specific child nodes by index:: >>> root[0][1].text '2008' + +.. note:: + + Not all elements of the XML input will end up as elements of the + parsed tree. Currently, this module skips over any XML comments, + processing instructions, and document type declarations in the + input. Nevertheless, trees built using this module's API rather + than parsing from XML text can have comments and processing + instructions in them; they will be included when generating XML + output. A document type declaration may be accessed by passing a + custom :class:`TreeBuilder` instance to the :class:`XMLParser` + constructor. + + +.. _elementtree-pull-parsing: + Pull API for non-blocking parsing ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Most parsing functions provided by this module require to read the whole -document at once before returning any result. It is possible to use a -:class:`XMLParser` and feed data into it incrementally, but it's a push API that +Most parsing functions provided by this module require the whole document +to be read at once before returning any result. It is possible to use an +:class:`XMLParser` and feed data into it incrementally, but it is a push API that calls methods on a callback target, which is too low-level and inconvenient for most needs. Sometimes what the user really wants is to be able to parse XML incrementally, without blocking operations, while enjoying the convenience of @@ -119,7 +135,7 @@ fully constructed :class:`Element` objects. The most powerful tool for doing this is :class:`XMLPullParser`. It does not require a blocking read to obtain the XML data, and is instead fed with data incrementally with :meth:`XMLPullParser.feed` calls. To get the parsed XML -elements, call :meth:`XMLPullParser.read_events`. Here's an example:: +elements, call :meth:`XMLPullParser.read_events`. Here is an example:: >>> parser = ET.XMLPullParser(['start', 'end']) >>> parser.feed('<mytag>sometext') @@ -268,6 +284,72 @@ sub-elements for a given element:: >>> ET.dump(a) <a><b /><c><d /></c></a> +Parsing XML with Namespaces +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If the XML input has `namespaces +<https://en.wikipedia.org/wiki/XML_namespace>`__, tags and attributes +with prefixes in the form ``prefix:sometag`` get expanded to +``{uri}sometag`` where the *prefix* is replaced by the full *URI*. +Also, if there is a `default namespace +<http://www.w3.org/TR/2006/REC-xml-names-20060816/#defaulting>`__, +that full URI gets prepended to all of the non-prefixed tags. + +Here is an XML example that incorporates two namespaces, one with the +prefix "fictional" and the other serving as the default namespace: + +.. code-block:: xml + + <?xml version="1.0"?> + <actors xmlns:fictional="http://characters.example.com/" + xmlns="http://people.example.com/"> + <actor> + <name>John Cleese</name> + <fictional:character>Lancelot</fictional:character> + <fictional:character>Archie Leach</fictional:character> + </actor> + <actor> + <name>Eric Idle</name> + <fictional:character>Sir Robin</fictional:character> + <fictional:character>Gunther</fictional:character> + <fictional:character>Commander Clement</fictional:character> + </actor> + </actors> + +One way to search and explore this XML example is to manually add the +URI to every tag or attribute in the xpath of a +:meth:`~Element.find` or :meth:`~Element.findall`:: + + root = fromstring(xml_text) + for actor in root.findall('{http://people.example.com}actor'): + name = actor.find('{http://people.example.com}name') + print(name.text) + for char in actor.findall('{http://characters.example.com}character'): + print(' |-->', char.text) + +A better way to search the namespaced XML example is to create a +dictionary with your own prefixes and use those in the search functions:: + + ns = {'real_person': 'http://people.example.com/', + 'role': 'http://characters.example.com/'} + + for actor in root.findall('real_person:actor', ns): + name = actor.find('real_person:name', ns) + print(name.text) + for char in actor.findall('role:character', ns): + print(' |-->', char.text) + +These two approaches both output:: + + John Cleese + |--> Lancelot + |--> Archie Leach + Eric Idle + |--> Sir Robin + |--> Gunther + |--> Commander Clement + + Additional resources ^^^^^^^^^^^^^^^^^^^^ @@ -322,7 +404,7 @@ Supported XPath syntax +=======================+======================================================+ | ``tag`` | Selects all child elements with the given tag. | | | For example, ``spam`` selects all child elements | -| | named ``spam``, ``spam/egg`` selects all | +| | named ``spam``, and ``spam/egg`` selects all | | | grandchildren named ``egg`` in all children named | | | ``spam``. | +-----------------------+------------------------------------------------------+ @@ -350,6 +432,10 @@ Supported XPath syntax | ``[tag]`` | Selects all elements that have a child named | | | ``tag``. Only immediate children are supported. | +-----------------------+------------------------------------------------------+ +| ``[tag='text']`` | Selects all elements that have a child named | +| | ``tag`` whose complete text content, including | +| | descendants, equals the given ``text``. | ++-----------------------+------------------------------------------------------+ | ``[position]`` | Selects all elements that are located at the given | | | position. The position can be either an integer | | | (1 is the first position), the expression ``last()`` | @@ -378,6 +464,10 @@ Functions string containing the comment string. Returns an element instance representing a comment. + Note that :class:`XMLParser` skips over comments in the input + instead of creating comment objects for them. An :class:`ElementTree` will + only contain comment nodes if they have been inserted into to + the tree using one of the :class:`Element` methods. .. function:: dump(elem) @@ -458,6 +548,11 @@ Functions containing the PI target. *text* is a string containing the PI contents, if given. Returns an element instance, representing a processing instruction. + Note that :class:`XMLParser` skips over processing instructions + in the input instead of creating comment objects for them. An + :class:`ElementTree` will only contain processing instruction nodes if + they have been inserted into to the tree using one of the + :class:`Element` methods. .. function:: register_namespace(prefix, uri) @@ -508,7 +603,7 @@ Functions *short_empty_elements* has the same meaning as in :meth:`ElementTree.write`. Returns a list of (optionally) encoded strings containing the XML data. It does not guarantee any specific sequence, except that - ``"".join(tostringlist(element)) == tostring(element)``. + ``b"".join(tostringlist(element)) == tostring(element)``. .. versionadded:: 3.2 @@ -556,21 +651,29 @@ Element Objects .. attribute:: text + tail - The *text* attribute can be used to hold additional data associated with - the element. As the name implies this attribute is usually a string but - may be any application-specific object. If the element is created from - an XML file the attribute will contain any text found between the element - tags. + These attributes can be used to hold additional data associated with + the element. Their values are usually strings but may be any + application-specific object. If the element is created from + an XML file, the *text* attribute holds either the text between + the element's start tag and its first child or end tag, or ``None``, and + the *tail* attribute holds either the text between the element's + end tag and the next tag, or ``None``. For the XML data + .. code-block:: xml - .. attribute:: tail + <a><b>1<c>2<d/>3</c></b>4</a> - The *tail* attribute can be used to hold additional data associated with - the element. This attribute is usually a string but may be any - application-specific object. If the element is created from an XML file - the attribute will contain any text found after the element's end tag and - before the next tag. + the *a* element has ``None`` for both *text* and *tail* attributes, + the *b* element has *text* ``"1"`` and *tail* ``"4"``, + the *c* element has *text* ``"2"`` and *tail* ``None``, + and the *d* element has *text* ``None`` and *tail* ``"3"``. + + To collect the inner text of an element, see :meth:`itertext`, for + example ``"".join(element.itertext())``. + + Applications may store arbitrary objects in these attributes. .. attribute:: attrib @@ -788,7 +891,7 @@ ElementTree Objects Creates and returns a tree iterator for the root element. The iterator loops over all elements in this tree, in section order. *tag* is the tag - to look for (default is to return all elements) + to look for (default is to return all elements). .. method:: iterfind(match, namespaces=None) @@ -831,8 +934,8 @@ ElementTree Objects :term:`file object`; make sure you do not try to write a string to a binary stream and vice versa. - .. versionadded:: 3.4 - The *short_empty_elements* parameter. + .. versionadded:: 3.4 + The *short_empty_elements* parameter. This is the XML file that is going to be manipulated:: @@ -949,7 +1052,8 @@ XMLParser Objects specified in the XML file. .. deprecated:: 3.4 - The *html* argument. + The *html* argument. The remaining arguments should be passed via + keywword to prepare for the removal of the *html* argument. .. method:: close() @@ -1038,15 +1142,17 @@ XMLPullParser Objects .. method:: read_events() - Iterate over the events which have been encountered in the data fed to the - parser. This method yields ``(event, elem)`` pairs, where *event* is a + Return an iterator over the events which have been encountered in the + data fed to the + parser. The iterator yields ``(event, elem)`` pairs, where *event* is a string representing the type of event (e.g. ``"end"``) and *elem* is the encountered :class:`Element` object. Events provided in a previous call to :meth:`read_events` will not be - yielded again. As events are consumed from the internal queue only as - they are retrieved from the iterator, multiple readers calling - :meth:`read_events` in parallel will have unpredictable results. + yielded again. Events are consumed from the internal queue only when + they are retrieved from the iterator, so multiple readers iterating in + parallel over iterators obtained from :meth:`read_events` will have + unpredictable results. .. note:: @@ -1084,4 +1190,4 @@ Exceptions .. [#] The encoding string included in XML output should conform to the appropriate standards. For example, "UTF-8" is valid, but "UTF8" is not. See http://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl - and http://www.iana.org/assignments/character-sets. + and http://www.iana.org/assignments/character-sets/character-sets.xhtml. diff --git a/Doc/library/xml.rst b/Doc/library/xml.rst index d796d828ab8d..018821909201 100644 --- a/Doc/library/xml.rst +++ b/Doc/library/xml.rst @@ -14,9 +14,9 @@ Python's interfaces for processing XML are grouped in the ``xml`` package. .. warning:: The XML modules are not secure against erroneous or maliciously - constructed data. If you need to parse untrusted or unauthenticated data see - :ref:`xml-vulnerabilities`. - + constructed data. If you need to parse untrusted or + unauthenticated data see the :ref:`xml-vulnerabilities` and + :ref:`defused-packages` sections. It is important to note that modules in the :mod:`xml` package require that there be at least one SAX-compliant XML parser available. The Expat parser is @@ -29,11 +29,12 @@ definition of the Python bindings for the DOM and SAX interfaces. The XML handling submodules are: * :mod:`xml.etree.ElementTree`: the ElementTree API, a simple and lightweight + XML processor .. * :mod:`xml.dom`: the DOM API definition -* :mod:`xml.dom.minidom`: a lightweight DOM implementation +* :mod:`xml.dom.minidom`: a minimal DOM implementation * :mod:`xml.dom.pulldom`: support for building partial DOM trees .. @@ -45,16 +46,15 @@ The XML handling submodules are: .. _xml-vulnerabilities: XML vulnerabilities -=================== +------------------- The XML processing modules are not secure against maliciously constructed data. -An attacker can abuse vulnerabilities for e.g. denial of service attacks, to -access local files, to generate network connections to other machines, or -to or circumvent firewalls. The attacks on XML abuse unfamiliar features -like inline `DTD`_ (document type definition) with entities. +An attacker can abuse XML features to carry out denial of service attacks, +access local files, generate network connections to other machines, or +circumvent firewalls. -The following table gives an overview of the known attacks and if the various -modules are vulnerable to them. +The following table gives an overview of the known attacks and whether +the various modules are vulnerable to them. ========================= ======== ========= ========= ======== ========= kind sax etree minidom pulldom xmlrpc @@ -67,7 +67,7 @@ decompression bomb No No No No **Yes** ========================= ======== ========= ========= ======== ========= 1. :mod:`xml.etree.ElementTree` doesn't expand external entities and raises a - ParserError when an entity occurs. + :exc:`ParserError` when an entity occurs. 2. :mod:`xml.dom.minidom` doesn't expand external entities and simply returns the unexpanded entity verbatim. 3. :mod:`xmlrpclib` doesn't expand external entities and omits them. @@ -76,55 +76,54 @@ decompression bomb No No No No **Yes** billion laughs / exponential entity expansion The `Billion Laughs`_ attack -- also known as exponential entity expansion -- uses multiple levels of nested entities. Each entity refers to another entity - several times, the final entity definition contains a small string. Eventually - the small string is expanded to several gigabytes. The exponential expansion - consumes lots of CPU time, too. + several times, and the final entity definition contains a small string. + The exponential expansion results in several gigabytes of text and + consumes lots of memory and CPU time. quadratic blowup entity expansion A quadratic blowup attack is similar to a `Billion Laughs`_ attack; it abuses entity expansion, too. Instead of nested entities it repeats one large entity with a couple of thousand chars over and over again. The attack isn't as - efficient as the exponential case but it avoids triggering countermeasures of - parsers against heavily nested entities. + efficient as the exponential case but it avoids triggering parser countermeasures + that forbid deeply-nested entities. external entity expansion Entity declarations can contain more than just text for replacement. They can - also point to external resources by public identifiers or system identifiers. - System identifiers are standard URIs or can refer to local files. The XML - parser retrieves the resource with e.g. HTTP or FTP requests and embeds the - content into the XML document. + also point to external resources or local files. The XML + parser accesses the resource and embeds the content into the XML document. DTD retrieval - Some XML libraries like Python's mod:'xml.dom.pulldom' retrieve document type + Some XML libraries like Python's :mod:`xml.dom.pulldom` retrieve document type definitions from remote or local locations. The feature has similar implications as the external entity expansion issue. decompression bomb - The issue of decompression bombs (aka `ZIP bomb`_) apply to all XML libraries - that can parse compressed XML stream like gzipped HTTP streams or LZMA-ed + Decompression bombs (aka `ZIP bomb`_) apply to all XML libraries + that can parse compressed XML streams such as gzipped HTTP streams or + LZMA-compressed files. For an attacker it can reduce the amount of transmitted data by three magnitudes or more. -The documentation of `defusedxml`_ on PyPI has further information about +The documentation for `defusedxml`_ on PyPI has further information about all known attack vectors with examples and references. -defused packages ----------------- +.. _defused-packages: -`defusedxml`_ is a pure Python package with modified subclasses of all stdlib -XML parsers that prevent any potentially malicious operation. The courses of -action are recommended for any server code that parses untrusted XML data. The -package also ships with example exploits and an extended documentation on more -XML exploits like xpath injection. +The :mod:`defusedxml` and :mod:`defusedexpat` Packages +------------------------------------------------------ -`defusedexpat`_ provides a modified libexpat and patched replacment -:mod:`pyexpat` extension module with countermeasures against entity expansion -DoS attacks. Defusedexpat still allows a sane and configurable amount of entity -expansions. The modifications will be merged into future releases of Python. +`defusedxml`_ is a pure Python package with modified subclasses of all stdlib +XML parsers that prevent any potentially malicious operation. Use of this +package is recommended for any server code that parses untrusted XML data. The +package also ships with example exploits and extended documentation on more +XML exploits such as XPath injection. -The workarounds and modifications are not included in patch releases as they -break backward compatibility. After all inline DTD and entity expansion are -well-definied XML features. +`defusedexpat`_ provides a modified libexpat and a patched +:mod:`pyexpat` module that have countermeasures against entity expansion +DoS attacks. The :mod:`defusedexpat` module still allows a sane and configurable amount of entity +expansions. The modifications may be included in some future release of Python, +but will not be included in any bugfix releases of +Python because they break backward compatibility. .. _defusedxml: https://pypi.python.org/pypi/defusedxml/ @@ -132,4 +131,3 @@ well-definied XML features. .. _Billion Laughs: http://en.wikipedia.org/wiki/Billion_laughs .. _ZIP bomb: http://en.wikipedia.org/wiki/Zip_bomb .. _DTD: http://en.wikipedia.org/wiki/Document_Type_Definition - diff --git a/Doc/library/xml.sax.reader.rst b/Doc/library/xml.sax.reader.rst index 3ab60636c5ec..31ca260f7ce7 100644 --- a/Doc/library/xml.sax.reader.rst +++ b/Doc/library/xml.sax.reader.rst @@ -100,8 +100,10 @@ The :class:`XMLReader` interface supports the following methods: system identifier (a string identifying the input source -- typically a file name or an URL), a file-like object, or an :class:`InputSource` object. When :meth:`parse` returns, the input is completely processed, and the parser object - can be discarded or reset. As a limitation, the current implementation only - accepts byte streams; processing of character streams is for further study. + can be discarded or reset. + + .. versionchanged:: 3.5 + Added support of character streams. .. method:: XMLReader.getContentHandler() @@ -288,8 +290,7 @@ InputSource Objects .. method:: InputSource.setByteStream(bytefile) - Set the byte stream (a Python file-like object which does not perform - byte-to-character conversion) for this input source. + Set the byte stream (a :term:`binary file`) for this input source. The SAX parser will ignore this if there is also a character stream specified, but it will use a byte stream in preference to opening a URI connection itself. @@ -308,8 +309,7 @@ InputSource Objects .. method:: InputSource.setCharacterStream(charfile) - Set the character stream for this input source. (The stream must be a Python 1.6 - Unicode-wrapped file-like that performs conversion to strings.) + Set the character stream (a :term:`text file`) for this input source. If there is a character stream specified, the SAX parser will ignore any byte stream and will not attempt to open a URI connection to the system identifier. diff --git a/Doc/library/xml.sax.rst b/Doc/library/xml.sax.rst index e95d6b0f853a..55f97999defe 100644 --- a/Doc/library/xml.sax.rst +++ b/Doc/library/xml.sax.rst @@ -47,7 +47,11 @@ The convenience functions are: .. function:: parseString(string, handler, error_handler=handler.ErrorHandler()) Similar to :func:`parse`, but parses from a buffer *string* received as a - parameter. + parameter. *string* must be a :class:`str` instance or a + :term:`bytes-like object`. + + .. versionchanged:: 3.5 + Added support of :class:`str` instances. A typical SAX application uses three kinds of objects: readers, handlers and input sources. "Reader" in this context is another term for parser, i.e. some diff --git a/Doc/library/xmlrpc.client.rst b/Doc/library/xmlrpc.client.rst index 3cb19d186267..e199931b55bd 100644 --- a/Doc/library/xmlrpc.client.rst +++ b/Doc/library/xmlrpc.client.rst @@ -27,10 +27,14 @@ between conformable Python objects and XML on the wire. constructed data. If you need to parse untrusted or unauthenticated data see :ref:`xml-vulnerabilities`. +.. versionchanged:: 3.5 + + For https URIs, :mod:`xmlrpc.client` now performs all the necessary + certificate and hostname checks by default .. class:: ServerProxy(uri, transport=None, encoding=None, verbose=False, \ allow_none=False, use_datetime=False, \ - use_builtin_types=False) + use_builtin_types=False, *, context=None) .. versionchanged:: 3.3 The *use_builtin_types* flag was added. @@ -59,7 +63,9 @@ between conformable Python objects and XML on the wire. portion will be base64-encoded as an HTTP 'Authorization' header, and sent to the remote server as part of the connection process when invoking an XML-RPC method. You only need to use this if the remote server requires a Basic - Authentication user and password. + Authentication user and password. If an HTTPS url is provided, *context* may + be :class:`ssl.SSLContext` and configures the SSL settings of the underlying + HTTPS connection. The returned instance is a proxy object with methods that can be used to invoke corresponding RPC calls on the remote server. If the remote server supports the @@ -123,6 +129,9 @@ between conformable Python objects and XML on the wire. :class:`Server` is retained as an alias for :class:`ServerProxy` for backwards compatibility. New code should use :class:`ServerProxy`. + .. versionchanged:: 3.5 + Added the *context* argument. + .. seealso:: @@ -191,6 +200,11 @@ grouped under the reserved :attr:`system` attribute: no such string is available, an empty string is returned. The documentation string may contain HTML markup. +.. versionchanged:: 3.5 + + Instances of :class:`ServerProxy` support the :term:`context manager` protocol + for closing the underlying transport. + A working example follows. The server code:: @@ -208,9 +222,9 @@ The client code for the preceding server:: import xmlrpc.client - proxy = xmlrpc.client.ServerProxy("http://localhost:8000/") - print("3 is even: %s" % str(proxy.is_even(3))) - print("100 is even: %s" % str(proxy.is_even(100))) + with xmlrpc.client.ServerProxy("http://localhost:8000/") as proxy: + print("3 is even: %s" % str(proxy.is_even(3))) + print("100 is even: %s" % str(proxy.is_even(100))) .. _datetime-objects: @@ -518,14 +532,14 @@ Example of Client Usage from xmlrpc.client import ServerProxy, Error # server = ServerProxy("http://localhost:8000/") # local server - server = ServerProxy("http://betty.userland.com/") + with ServerProxy("http://betty.userland.com/") as proxy: - print(server) + print(proxy) - try: - print(server.examples.getStateName(41)) - except Error as v: - print("ERROR", v) + try: + print(proxy.examples.getStateName(41)) + except Error as v: + print("ERROR", v) To access an XML-RPC server through a proxy, you need to define a custom transport. The following example shows how: diff --git a/Doc/library/xmlrpc.server.rst b/Doc/library/xmlrpc.server.rst index 18fee2fc1d36..37d1393eff03 100644 --- a/Doc/library/xmlrpc.server.rst +++ b/Doc/library/xmlrpc.server.rst @@ -184,6 +184,70 @@ server:: # Print list of available methods print(s.system.listMethods()) +The following example included in the :file:`Lib/xmlrpc/server.py` module shows +a server allowing dotted names and registering a multicall function. + +.. warning:: + + Enabling the *allow_dotted_names* option allows intruders to access your + module's global variables and may allow intruders to execute arbitrary code on + your machine. Only use this example only within a secure, closed network. + +:: + + import datetime + + class ExampleService: + def getData(self): + return '42' + + class currentTime: + @staticmethod + def getCurrentTime(): + return datetime.datetime.now() + + server = SimpleXMLRPCServer(("localhost", 8000)) + server.register_function(pow) + server.register_function(lambda x,y: x+y, 'add') + server.register_instance(ExampleService(), allow_dotted_names=True) + server.register_multicall_functions() + print('Serving XML-RPC on localhost port 8000') + try: + server.serve_forever() + except KeyboardInterrupt: + print("\nKeyboard interrupt received, exiting.") + server.server_close() + sys.exit(0) + +This ExampleService demo can be invoked from the command line:: + + python -m xmlrpc.server + + +The client that interacts with the above server is included in +`Lib/xmlrpc/client.py`:: + + server = ServerProxy("http://localhost:8000/") + + try: + print(server.currentTime.getCurrentTime()) + except Error as v: + print("ERROR", v) + + multi = MultiCall(server) + multi.getData() + multi.pow(2,9) + multi.add(1,2) + try: + for response in multi(): + print(response) + except Error as v: + print("ERROR", v) + +This client which interacts with the demo XMLRPC server can be invoked as:: + + python -m xmlrpc.client + CGIXMLRPCRequestHandler ----------------------- diff --git a/Doc/library/zipapp.rst b/Doc/library/zipapp.rst new file mode 100644 index 000000000000..b4484c87d030 --- /dev/null +++ b/Doc/library/zipapp.rst @@ -0,0 +1,259 @@ +:mod:`zipapp` --- Manage executable python zip archives +======================================================= + +.. module:: zipapp + :synopsis: Manage executable python zip archives + + +.. index:: + single: Executable Zip Files + +.. versionadded:: 3.5 + +**Source code:** :source:`Lib/zipapp.py` + +-------------- + +This module provides tools to manage the creation of zip files containing +Python code, which can be :ref:`executed directly by the Python interpreter +<using-on-interface-options>`. The module provides both a +:ref:`zipapp-command-line-interface` and a :ref:`zipapp-python-api`. + + +Basic Example +------------- + +The following example shows how the :ref:`command-line-interface` +can be used to create an executable archive from a directory containing +Python code. When run, the archive will execute the ``main`` function from +the module ``myapp`` in the archive. + +.. code-block:: sh + + $ python -m zipapp myapp -m "myapp:main" + $ python myapp.pyz + <output from myapp> + + +.. _zipapp-command-line-interface: + +Command-Line Interface +---------------------- + +When called as a program from the command line, the following form is used: + +.. code-block:: sh + + $ python -m zipapp source [options] + +If *source* is a directory, this will create an archive from the contents of +*source*. If *source* is a file, it should be an archive, and it will be +copied to the target archive (or the contents of its shebang line will be +displayed if the --info option is specified). + +The following options are understood: + +.. program:: zipapp + +.. cmdoption:: -o <output>, --output=<output> + + Write the output to a file named *output*. If this option is not specified, + the output filename will be the same as the input *source*, with the + extension ``.pyz`` added. If an explicit filename is given, it is used as + is (so a ``.pyz`` extension should be included if required). + + An output filename must be specified if the *source* is an archive (and in + that case, *output* must not be the same as *source*). + +.. cmdoption:: -p <interpreter>, --python=<interpreter> + + Add a ``#!`` line to the archive specifying *interpreter* as the command + to run. Also, on POSIX, make the archive executable. The default is to + write no ``#!`` line, and not make the file executable. + +.. cmdoption:: -m <mainfn>, --main=<mainfn> + + Write a ``__main__.py`` file to the archive that executes *mainfn*. The + *mainfn* argument should have the form "pkg.mod:fn", where "pkg.mod" is a + package/module in the archive, and "fn" is a callable in the given module. + The ``__main__.py`` file will execute that callable. + + :option:`--main` cannot be specified when copying an archive. + +.. cmdoption:: --info + + Display the interpreter embedded in the archive, for diagnostic purposes. In + this case, any other options are ignored and SOURCE must be an archive, not a + directory. + +.. cmdoption:: -h, --help + + Print a short usage message and exit. + + +.. _zipapp-python-api: + +Python API +---------- + +The module defines two convenience functions: + + +.. function:: create_archive(source, target=None, interpreter=None, main=None) + + Create an application archive from *source*. The source can be any + of the following: + + * The name of a directory, or a :class:`pathlib.Path` object referring + to a directory, in which case a new application archive will be + created from the content of that directory. + * The name of an existing application archive file, or a :class:`pathlib.Path` + object referring to such a file, in which case the file is copied to + the target (modifying it to reflect the value given for the *interpreter* + argument). The file name should include the ``.pyz`` extension, if required. + * A file object open for reading in bytes mode. The content of the + file should be an application archive, and the file object is + assumed to be positioned at the start of the archive. + + The *target* argument determines where the resulting archive will be + written: + + * If it is the name of a file, or a :class:`pathlb.Path` object, + the archive will be written to that file. + * If it is an open file object, the archive will be written to that + file object, which must be open for writing in bytes mode. + * If the target is omitted (or None), the source must be a directory + and the target will be a file with the same name as the source, with + a ``.pyz`` extension added. + + The *interpreter* argument specifies the name of the Python + interpreter with which the archive will be executed. It is written as + a "shebang" line at the start of the archive. On POSIX, this will be + interpreted by the OS, and on Windows it will be handled by the Python + launcher. Omitting the *interpreter* results in no shebang line being + written. If an interpreter is specified, and the target is a + filename, the executable bit of the target file will be set. + + The *main* argument specifies the name of a callable which will be + used as the main program for the archive. It can only be specified if + the source is a directory, and the source does not already contain a + ``__main__.py`` file. The *main* argument should take the form + "pkg.module:callable" and the archive will be run by importing + "pkg.module" and executing the given callable with no arguments. It + is an error to omit *main* if the source is a directory and does not + contain a ``__main__.py`` file, as otherwise the resulting archive + would not be executable. + + If a file object is specified for *source* or *target*, it is the + caller's responsibility to close it after calling create_archive. + + When copying an existing archive, file objects supplied only need + ``read`` and ``readline``, or ``write`` methods. When creating an + archive from a directory, if the target is a file object it will be + passed to the ``zipfile.ZipFile`` class, and must supply the methods + needed by that class. + +.. function:: get_interpreter(archive) + + Return the interpreter specified in the ``#!`` line at the start of the + archive. If there is no ``#!`` line, return :const:`None`. + The *archive* argument can be a filename or a file-like object open + for reading in bytes mode. It is assumed to be at the start of the archive. + + +.. _zipapp-examples: + +Examples +-------- + +Pack up a directory into an archive, and run it. + +.. code-block:: sh + + $ python -m zipapp myapp + $ python myapp.pyz + <output from myapp> + +The same can be done using the :func:`create_archive` functon:: + + >>> import zipapp + >>> zipapp.create_archive('myapp.pyz', 'myapp') + +To make the application directly executable on POSIX, specify an interpreter +to use. + +.. code-block:: sh + + $ python -m zipapp myapp -p "/usr/bin/env python" + $ ./myapp.pyz + <output from myapp> + +To replace the shebang line on an existing archive, create a modified archive +using the :func:`create_archive` function:: + + >>> import zipapp + >>> zipapp.create_archive('old_archive.pyz', 'new_archive.pyz', '/usr/bin/python3') + +To update the file in place, do the replacement in memory using a :class:`BytesIO` +object, and then overwrite the source afterwards. Note that there is a risk +when overwriting a file in place that an error will result in the loss of +the original file. This code does not protect against such errors, but +production code should do so. Also, this method will only work if the archive +fits in memory:: + + >>> import zipapp + >>> import io + >>> temp = io.BytesIO() + >>> zipapp.create_archive('myapp.pyz', temp, '/usr/bin/python2') + >>> with open('myapp.pyz', 'wb') as f: + >>> f.write(temp.getvalue()) + +Note that if you specify an interpreter and then distribute your application +archive, you need to ensure that the interpreter used is portable. The Python +launcher for Windows supports most common forms of POSIX ``#!`` line, but there +are other issues to consider: + +* If you use "/usr/bin/env python" (or other forms of the "python" command, + such as "/usr/bin/python"), you need to consider that your users may have + either Python 2 or Python 3 as their default, and write your code to work + under both versions. +* If you use an explicit version, for example "/usr/bin/env python3" your + application will not work for users who do not have that version. (This + may be what you want if you have not made your code Python 2 compatible). +* There is no way to say "python X.Y or later", so be careful of using an + exact version like "/usr/bin/env python3.4" as you will need to change your + shebang line for users of Python 3.5, for example. + +The Python Zip Application Archive Format +----------------------------------------- + +Python has been able to execute zip files which contain a ``__main__.py`` file +since version 2.6. In order to be executed by Python, an application archive +simply has to be a standard zip file containing a ``__main__.py`` file which +will be run as the entry point for the application. As usual for any Python +script, the parent of the script (in this case the zip file) will be placed on +:data:`sys.path` and thus further modules can be imported from the zip file. + +The zip file format allows arbitrary data to be prepended to a zip file. The +zip application format uses this ability to prepend a standard POSIX "shebang" +line to the file (``#!/path/to/interpreter``). + +Formally, the Python zip application format is therefore: + +1. An optional shebang line, containing the characters ``b'#!'`` followed by an + interpreter name, and then a newline (``b'\n'``) character. The interpreter + name can be anything acceptable to the OS "shebang" processing, or the Python + launcher on Windows. The interpreter should be encoded in UTF-8 on Windows, + and in :func:`sys.getfilesystemencoding()` on POSIX. +2. Standard zipfile data, as generated by the :mod:`zipfile` module. The + zipfile content *must* include a file called ``__main__.py`` (which must be + in the "root" of the zipfile - i.e., it cannot be in a subdirectory). The + zipfile data can be compressed or uncompressed. + +If an application archive has a shebang line, it may have the executable bit set +on POSIX systems, to allow it to be executed directly. + +There is no requirement that the tools in this module are used to create +application archives - the module is a convenience, but archives in the above +format created by any means are acceptable to Python. + diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst index 969a5363be5a..d40315eaf899 100644 --- a/Doc/library/zipfile.rst +++ b/Doc/library/zipfile.rst @@ -134,12 +134,16 @@ ZipFile Objects Open a ZIP file, where *file* can be either a path to a file (a string) or a file-like object. The *mode* parameter should be ``'r'`` to read an existing - file, ``'w'`` to truncate and write a new file, or ``'a'`` to append to an - existing file. If *mode* is ``'a'`` and *file* refers to an existing ZIP + file, ``'w'`` to truncate and write a new file, ``'x'`` to exclusive create + and write a new file, or ``'a'`` to append to an existing file. + If *mode* is ``'x'`` and *file* refers to an existing file, + a :exc:`FileExistsError` will be raised. + If *mode* is ``'a'`` and *file* refers to an existing ZIP file, then additional files are added to it. If *file* does not refer to a ZIP file, then a new ZIP archive is appended to the file. This is meant for adding a ZIP archive to another file (such as :file:`python.exe`). If *mode* is ``a`` and the file does not exist at all, it is created. + If *mode* is ``r`` or ``a``, the file should be seekable. *compression* is the ZIP compression method to use when writing the archive, and should be :const:`ZIP_STORED`, :const:`ZIP_DEFLATED`, :const:`ZIP_BZIP2` or :const:`ZIP_LZMA`; unrecognized @@ -151,7 +155,7 @@ ZipFile Objects extensions when the zipfile is larger than 2 GiB. If it is false :mod:`zipfile` will raise an exception when the ZIP file would require ZIP64 extensions. - If the file is created with mode ``'a'`` or ``'w'`` and then + If the file is created with mode ``'w'``, ``'x'`` or ``'a'`` and then :meth:`closed <close>` without adding any files to the archive, the appropriate ZIP structures for an empty archive will be written to the file. @@ -171,6 +175,10 @@ ZipFile Objects .. versionchanged:: 3.4 ZIP64 extensions are enabled by default. + .. versionchanged:: 3.5 + Added support for writing to unseekable streams. + Added support for the ``'x'`` mode. + .. method:: ZipFile.close() @@ -210,6 +218,13 @@ ZipFile Objects password used for encrypted files. Calling :meth:`.open` on a closed ZipFile will raise a :exc:`RuntimeError`. + :meth:`~ZipFile.open` is also a context manager and therefore supports the + :keyword:`with` statement:: + + with ZipFile('spam.zip') as myzip: + with myzip.open('eggs.txt') as myfile: + print(myfile.read()) + .. note:: The file-like object is read-only and provides the following methods: @@ -219,14 +234,8 @@ ZipFile Objects .. note:: - If the ZipFile was created by passing in a file-like object as the first - argument to the constructor, then the object returned by :meth:`.open` shares the - ZipFile's file pointer. Under these circumstances, the object returned by - :meth:`.open` should not be used after any additional operations are performed - on the ZipFile object. If the ZipFile was created by passing in a string (the - filename) as the first argument to the constructor, then :meth:`.open` will - create a new file object that will be held by the ZipExtFile, allowing it to - operate independently of the ZipFile. + Objects returned by :meth:`.open` can operate independently of the + ZipFile. .. note:: @@ -246,6 +255,8 @@ ZipFile Objects to extract to. *member* can be a filename or a :class:`ZipInfo` object. *pwd* is the password used for encrypted files. + Returns the normalized path created (a directory or new file). + .. note:: If a member filename is an absolute path, a drive/UNC sharepoint and @@ -289,7 +300,11 @@ ZipFile Objects file in the archive, or a :class:`ZipInfo` object. The archive must be open for read or append. *pwd* is the password used for encrypted files and, if specified, it will override the default password set with :meth:`setpassword`. Calling - :meth:`read` on a closed ZipFile will raise a :exc:`RuntimeError`. + :meth:`read` on a closed ZipFile will raise a :exc:`RuntimeError`. Calling + :meth:`read` on a ZipFile that uses a compression method other than + :const:`ZIP_STORED`, :const:`ZIP_DEFLATED`, :const:`ZIP_BZIP2` or + :const:`ZIP_LZMA` will raise a :exc:`NotImplementedError`. An error will also + be raised if the corresponding compression module is not available. .. method:: ZipFile.testzip() @@ -305,7 +320,8 @@ ZipFile Objects *arcname* (by default, this will be the same as *filename*, but without a drive letter and with leading path separators removed). If given, *compress_type* overrides the value given for the *compression* parameter to the constructor for - the new entry. The archive must be open with mode ``'w'`` or ``'a'`` -- calling + the new entry. + The archive must be open with mode ``'w'``, ``'x'`` or ``'a'`` -- calling :meth:`write` on a ZipFile created with mode ``'r'`` will raise a :exc:`RuntimeError`. Calling :meth:`write` on a closed ZipFile will raise a :exc:`RuntimeError`. @@ -327,16 +343,16 @@ ZipFile Objects If ``arcname`` (or ``filename``, if ``arcname`` is not given) contains a null byte, the name of the file in the archive will be truncated at the null byte. - .. method:: ZipFile.writestr(zinfo_or_arcname, bytes[, compress_type]) Write the string *bytes* to the archive; *zinfo_or_arcname* is either the file name it will be given in the archive, or a :class:`ZipInfo` instance. If it's an instance, at least the filename, date, and time must be given. If it's a - name, the date and time is set to the current date and time. The archive must be - opened with mode ``'w'`` or ``'a'`` -- calling :meth:`writestr` on a ZipFile - created with mode ``'r'`` will raise a :exc:`RuntimeError`. Calling - :meth:`writestr` on a closed ZipFile will raise a :exc:`RuntimeError`. + name, the date and time is set to the current date and time. + The archive must be opened with mode ``'w'``, ``'x'`` or ``'a'`` -- calling + :meth:`writestr` on a ZipFile created with mode ``'r'`` will raise a + :exc:`RuntimeError`. Calling :meth:`writestr` on a closed ZipFile will + raise a :exc:`RuntimeError`. If given, *compress_type* overrides the value given for the *compression* parameter to the constructor for the new entry, or in the *zinfo_or_arcname* @@ -364,7 +380,8 @@ The following data attributes are also available: .. attribute:: ZipFile.comment The comment text associated with the ZIP file. If assigning a comment to a - :class:`ZipFile` instance created with mode 'a' or 'w', this should be a + :class:`ZipFile` instance created with mode ``'w'``, ``'x'`` or ``'a'``, + this should be a string no longer than 65535 bytes. Comments longer than this will be truncated in the written archive when :meth:`close` is called. @@ -394,25 +411,38 @@ The :class:`PyZipFile` constructor takes the same parameters as the archive. If the *optimize* parameter to :class:`PyZipFile` was not given or ``-1``, - the corresponding file is a :file:`\*.pyo` file if available, else a - :file:`\*.pyc` file, compiling if necessary. + the corresponding file is a :file:`\*.pyc` file, compiling if necessary. If the *optimize* parameter to :class:`PyZipFile` was ``0``, ``1`` or ``2``, only files with that optimization level (see :func:`compile`) are added to the archive, compiling if necessary. - If the pathname is a file, the filename must end with :file:`.py`, and + If *pathname* is a file, the filename must end with :file:`.py`, and just the (corresponding :file:`\*.py[co]`) file is added at the top level - (no path information). If the pathname is a file that does not end with + (no path information). If *pathname* is a file that does not end with :file:`.py`, a :exc:`RuntimeError` will be raised. If it is a directory, and the directory is not a package directory, then all the files :file:`\*.py[co]` are added at the top level. If the directory is a package directory, then all :file:`\*.py[co]` are added under the package name as a file path, and if any subdirectories are package directories, - all of these are added recursively. *basename* is intended for internal - use only. When *filterfunc(pathname)* is given, it will be called for every - invocation. When it returns a false value, that path and its subpaths will - be ignored. + all of these are added recursively. + + *basename* is intended for internal use only. + + *filterfunc*, if given, must be a function taking a single string + argument. It will be passed each path (including each individual full + file path) before it is added to the archive. If *filterfunc* returns a + false value, the path will not be added, and if it is a directory its + contents will be ignored. For example, if our test files are all either + in ``test`` directories or start with the string ``test_``, we can use a + *filterfunc* to exclude them:: + + >>> zf = PyZipFile('myprog.zip') + >>> def notests(s): + ... fn = os.path.basename(s) + ... return (not (fn == 'test' or fn.startswith('test_'))) + >>> zf.writepy('myprog', filterfunc=notests) + The :meth:`writepy` method makes archives with file names like this:: @@ -544,4 +574,3 @@ Instances have the following attributes: .. attribute:: ZipInfo.file_size Size of the uncompressed file. - diff --git a/Doc/library/zipimport.rst b/Doc/library/zipimport.rst index 2cf508b85c14..8a5d5d19dfed 100644 --- a/Doc/library/zipimport.rst +++ b/Doc/library/zipimport.rst @@ -20,10 +20,10 @@ subdirectory. For example, the path :file:`example.zip/lib/` would only import from the :file:`lib/` subdirectory within the archive. Any files may be present in the ZIP archive, but only files :file:`.py` and -:file:`.py[co]` are available for import. ZIP import of dynamic modules +:file:`.pyc` are available for import. ZIP import of dynamic modules (:file:`.pyd`, :file:`.so`) is disallowed. Note that if an archive only contains :file:`.py` files, Python will not attempt to modify the archive by adding the -corresponding :file:`.pyc` or :file:`.pyo` file, meaning that if a ZIP archive +corresponding :file:`.pyc` file, meaning that if a ZIP archive doesn't contain :file:`.pyc` files, importing may be rather slow. ZIP archives with an archive comment are currently not supported. @@ -161,4 +161,3 @@ Here is an example that imports a module from a ZIP archive - note that the >>> import jwzthreading >>> jwzthreading.__file__ 'example.zip/jwzthreading.py' - diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst index d9a29a8814e7..aea0e79b8b3f 100644 --- a/Doc/library/zlib.rst +++ b/Doc/library/zlib.rst @@ -58,7 +58,7 @@ The available exception and functions in this module are: Raises the :exc:`error` exception if any error occurs. -.. function:: compressobj(level=-1, method=DEFLATED, wbits=15, memlevel=8, strategy=Z_DEFAULT_STRATEGY[, zdict]) +.. function:: compressobj(level=-1, method=DEFLATED, wbits=15, memLevel=8, strategy=Z_DEFAULT_STRATEGY[, zdict]) Returns a compression object, to be used for compressing data streams that won't fit into memory at once. @@ -75,9 +75,9 @@ The available exception and functions in this module are: should be an integer from ``8`` to ``15``. Higher values give better compression, but use more memory. - *memlevel* controls the amount of memory used for internal compression state. - Valid values range from ``1`` to ``9``. Higher values using more memory, - but are faster and produce smaller output. + The *memLevel* argument controls the amount of memory used for the + internal compression state. Valid values range from ``1`` to ``9``. + Higher values use more memory, but are faster and produce smaller output. *strategy* is used to tune the compression algorithm. Possible values are ``Z_DEFAULT_STRATEGY``, ``Z_FILTERED``, and ``Z_HUFFMAN_ONLY``. @@ -197,7 +197,7 @@ Decompression objects support the following methods and attributes: .. attribute:: Decompress.unused_data A bytes object which contains any bytes past the end of the compressed data. That is, - this remains ``""`` until the last byte that contains compression data is + this remains ``b""`` until the last byte that contains compression data is available. If the whole bytestring turned out to contain compressed data, this is ``b""``, an empty bytes object. diff --git a/Doc/license.rst b/Doc/license.rst index ddc69b839d71..53a1c4d57ec4 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -23,11 +23,11 @@ In May 2000, Guido and the Python core development team moved to BeOpen.com to form the BeOpen PythonLabs team. In October of the same year, the PythonLabs team moved to Digital Creations (now Zope Corporation; see http://www.zope.com/). In 2001, the Python Software Foundation (PSF, see -http://www.python.org/psf/) was formed, a non-profit organization created +https://www.python.org/psf/) was formed, a non-profit organization created specifically to own Python-related Intellectual Property. Zope Corporation is a sponsoring member of the PSF. -All Python releases are Open Source (see http://www.opensource.org/ for the Open +All Python releases are Open Source (see http://opensource.org/ for the Open Source Definition). Historically, most, but not all, Python releases have also been GPL-compatible; the table below summarizes the various releases. @@ -84,9 +84,9 @@ Terms and conditions for accessing or otherwise using Python analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python |release| alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of - copyright, i.e., "Copyright © 2001-2013 Python Software Foundation; All Rights - Reserved" are retained in Python |release| alone or in any derivative version - prepared by Licensee. + copyright, i.e., "Copyright © 2001-2015 Python Software Foundation; All + Rights Reserved" are retained in Python |release| alone or in any derivative + version prepared by Licensee. #. In the event Licensee prepares a derivative work that is based on or incorporates Python |release| or any part thereof, and wants to make the @@ -590,25 +590,6 @@ The :mod:`select` and contains the following notice for the kqueue interface:: SUCH DAMAGE. -SHA-3 ------ - -The module :mod:`_sha3` and :mod:`hashlib` are using the reference -implementation of Keccak. The files at :file:`Modules/_sha3/keccak/` contain -the following note:: - - The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, - Michaël Peeters and Gilles Van Assche. For more information, feedback or - questions, please refer to our website: http://keccak.noekeon.org/ - - Implementation by the designers, - hereby denoted as "the implementer". - - 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/ - - SipHash24 --------- @@ -673,9 +654,9 @@ OpenSSL The modules :mod:`hashlib`, :mod:`posix`, :mod:`ssl`, :mod:`crypt` use the OpenSSL library for added performance if made available by the -operating system. Additionally, the Windows installers for Python -include a copy of the OpenSSL libraries, so we include a copy of the -OpenSSL license here:: +operating system. Additionally, the Windows and Mac OS X installers for +Python may include a copy of the OpenSSL libraries, so we include a copy +of the OpenSSL license here:: LICENSE ISSUES @@ -897,7 +878,7 @@ used for the build:: cfuhash ------- -The implementtation of the hash table used by the :mod:`tracemalloc` is based +The implementation of the hash table used by the :mod:`tracemalloc` is based on the cfuhash project:: Copyright (c) 2005 Don Owens @@ -934,3 +915,36 @@ on the cfuhash project:: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +libmpdec +-------- + +The :mod:`_decimal` Module is built using an included copy of the libmpdec +library unless the build is configured ``--with-system-libmpdec``:: + + 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. + + diff --git a/Doc/make.bat b/Doc/make.bat index 675e79300b06..5ab80850a310 100644 --- a/Doc/make.bat +++ b/Doc/make.bat @@ -1,59 +1,130 @@ -@@echo off -setlocal - -set SVNROOT=http://svn.python.org/projects -if "%PYTHON%" EQU "" set PYTHON=py -2 -if "%HTMLHELP%" EQU "" set HTMLHELP=%ProgramFiles%\HTML Help Workshop\hhc.exe -if "%DISTVERSION%" EQU "" for /f "usebackq" %%v in (`%PYTHON% tools/sphinxext/patchlevel.py`) do set DISTVERSION=%%v - -if "%1" EQU "" goto help -if "%1" EQU "html" goto build -if "%1" EQU "htmlhelp" goto build -if "%1" EQU "latex" goto build -if "%1" EQU "text" goto build -if "%1" EQU "suspicious" goto build -if "%1" EQU "linkcheck" goto build -if "%1" EQU "changes" goto build -if "%1" EQU "checkout" goto checkout -if "%1" EQU "update" goto update - -:help -set this=%~n0 -echo HELP -echo. -echo %this% checkout -echo %this% update -echo %this% html -echo %this% htmlhelp -echo %this% latex -echo %this% text -echo %this% suspicious -echo %this% linkcheck -echo %this% changes -echo. -goto end - -:checkout -svn co %SVNROOT%/external/Sphinx-1.0.7/sphinx tools/sphinx -svn co %SVNROOT%/external/docutils-0.6/docutils tools/docutils -svn co %SVNROOT%/external/Jinja-2.3.1/jinja2 tools/jinja2 -svn co %SVNROOT%/external/Pygments-1.5dev-20120930/pygments tools/pygments -goto end - -:update -svn update tools/sphinx -svn update tools/docutils -svn update tools/jinja2 -svn update tools/pygments -goto end - -:build -if not exist build mkdir build -if not exist build\%1 mkdir build\%1 -if not exist build\doctrees mkdir build\doctrees -cmd /C %PYTHON% --version -cmd /C %PYTHON% tools\sphinx-build.py -b%1 -dbuild\doctrees . build\%* -if "%1" EQU "htmlhelp" "%HTMLHELP%" build\htmlhelp\python%DISTVERSION:.=%.hhp -goto end - -:end +@echo off +setlocal + +pushd %~dp0 + +set this=%~n0 + +if "%SPHINXBUILD%" EQU "" set SPHINXBUILD=sphinx-build +if "%PYTHON%" EQU "" set PYTHON=py + +if "%1" NEQ "htmlhelp" goto :skiphhcsearch +if exist "%HTMLHELP%" goto :skiphhcsearch + +rem Search for HHC in likely places +set HTMLHELP= +where hhc /q && set HTMLHELP=hhc && goto :skiphhcsearch +where /R ..\externals hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" +if not exist "%HTMLHELP%" where /R "%ProgramFiles(x86)%" hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" +if not exist "%HTMLHELP%" where /R "%ProgramFiles%" hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" +if not exist "%HTMLHELP%" ( + echo. + echo.The HTML Help Workshop was not found. Set the HTMLHELP variable + echo.to the path to hhc.exe or download and install it from + echo.http://msdn.microsoft.com/en-us/library/ms669985 + exit /B 1 +) +:skiphhcsearch + +if "%DISTVERSION%" EQU "" for /f "usebackq" %%v in (`%PYTHON% tools/extensions/patchlevel.py`) do set DISTVERSION=%%v + +if "%BUILDDIR%" EQU "" set BUILDDIR=build + +rem Targets that don't require sphinx-build +if "%1" EQU "" goto help +if "%1" EQU "help" goto help +if "%1" EQU "check" goto check +if "%1" EQU "serve" goto serve +if "%1" == "clean" ( + rmdir /q /s %BUILDDIR% + goto end +) + +%SPHINXBUILD% 2> nul +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + popd + exit /B 1 +) + +rem Targets that do require sphinx-build and have their own label +if "%1" EQU "htmlview" goto htmlview + +rem Everything else +goto build + +:help +echo.usage: %this% BUILDER [filename ...] +echo. +echo.Call %this% with the desired Sphinx builder as the first argument, e.g. +echo.``%this% html`` or ``%this% doctest``. Interesting targets that are +echo.always available include: +echo. +echo. Provided by Sphinx: +echo. html, htmlhelp, latex, text +echo. suspicious, linkcheck, changes, doctest +echo. Provided by this script: +echo. clean, check, serve, htmlview +echo. +echo.All arguments past the first one are passed through to sphinx-build as +echo.filenames to build or are ignored. See README.txt in this directory or +echo.the documentation for your version of Sphinx for more exhaustive lists +echo.of available targets and descriptions of each. +echo. +echo.This script assumes that the SPHINXBUILD environment variable contains +echo.a legitimate command for calling sphinx-build, or that sphinx-build is +echo.on your PATH if SPHINXBUILD is not set. Options for sphinx-build can +echo.be passed by setting the SPHINXOPTS environment variable. +goto end + +:build +if NOT "%PAPER%" == "" ( + set SPHINXOPTS=-D latex_paper_size=%PAPER% %SPHINXOPTS% +) +cmd /C %SPHINXBUILD% %SPHINXOPTS% -b%1 -dbuild\doctrees . %BUILDDIR%\%* + +if "%1" EQU "htmlhelp" ( + cmd /C "%HTMLHELP%" build\htmlhelp\python%DISTVERSION:.=%.hhp + rem hhc.exe seems to always exit with code 1, reset to 0 for less than 2 + if not errorlevel 2 cmd /C exit /b 0 +) + +echo. +if errorlevel 1 ( + echo.Build failed (exit code %ERRORLEVEL%^), check for error messages + echo.above. Any output will be found in %BUILDDIR%\%1 +) else ( + echo.Build succeeded. All output should be in %BUILDDIR%\%1 +) +goto end + +:htmlview +if NOT "%2" EQU "" ( + echo.Can't specify filenames to build with htmlview target, ignoring. +) +cmd /C %this% html + +if EXIST %BUILDDIR%\html\index.html ( + echo.Opening %BUILDDIR%\html\index.html in the default web browser... + start %BUILDDIR%\html\index.html +) + +goto end + +:check +cmd /C %PYTHON% tools\rstlint.py -i tools +goto end + +:serve +cmd /C %PYTHON% ..\Tools\scripts\serve.py %BUILDDIR%\html +goto end + +:end +popd diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index e35aa9f74058..00e64763a0e7 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -22,14 +22,14 @@ also syntactically compound statements. single: clause single: suite -Compound statements consist of one or more 'clauses.' A clause consists of a +A compound statement consists of one or more 'clauses.' A clause consists of a header and a 'suite.' The clause headers of a particular compound statement are all at the same indentation level. Each clause header begins with a uniquely identifying keyword and ends with a colon. A suite is a group of statements controlled by a clause. A suite can be one or more semicolon-separated simple statements on the same line as the header, following the header's colon, or it can be one or more indented statements on subsequent lines. Only the latter -form of suite can contain nested compound statements; the following is illegal, +form of a suite can contain nested compound statements; the following is illegal, mostly because it wouldn't be clear to which :keyword:`if` clause a following :keyword:`else` clause would belong:: @@ -51,6 +51,9 @@ Summarizing: : | `with_stmt` : | `funcdef` : | `classdef` + : | `async_with_stmt` + : | `async_for_stmt` + : | `async_funcdef` suite: `stmt_list` NEWLINE | NEWLINE INDENT `statement`+ DEDENT statement: `stmt_list` NEWLINE | `compound_stmt` stmt_list: `simple_stmt` (";" `simple_stmt`)* [";"] @@ -156,8 +159,8 @@ The :keyword:`for` statement is used to iterate over the elements of a sequence The expression list is evaluated once; it should yield an iterable object. An iterator is created for the result of the ``expression_list``. The suite is -then executed once for each item provided by the iterator, in the order of -ascending indices. Each item in turn is assigned to the target list using the +then executed once for each item provided by the iterator, in the order returned +by the iterator. Each item in turn is assigned to the target list using the standard rules for assignments (see :ref:`assignment`), and then the suite is executed. When the items are exhausted (which is immediately when the sequence is empty or an iterator raises a :exc:`StopIteration` exception), the suite in @@ -170,17 +173,25 @@ the :keyword:`else` clause, if present, is executed, and the loop terminates. A :keyword:`break` statement executed in the first suite terminates the loop without executing the :keyword:`else` clause's suite. A :keyword:`continue` statement executed in the first suite skips the rest of the suite and continues -with the next item, or with the :keyword:`else` clause if there was no next +with the next item, or with the :keyword:`else` clause if there is no next item. -The suite may assign to the variable(s) in the target list; this does not affect -the next item assigned to it. +The for-loop makes assignments to the variables(s) in the target list. +This overwrites all previous assignments to those variables including +those made in the suite of the for-loop:: + + for i in range(10): + print(i) + i = 5 # this will not affect the for-loop + # because i will be overwritten with the next + # index in the range + .. index:: builtin: range Names in the target list are not deleted when the loop is finished, but if the -sequence is empty, it will not have been assigned to at all by the loop. Hint: +sequence is empty, they will not have been assigned to at all by the loop. Hint: the built-in function :func:`range` returns an iterator of integers suitable to emulate the effect of Pascal's ``for i := a to b do``; e.g., ``list(range(3))`` returns the list ``[0, 1, 2]``. @@ -226,7 +237,7 @@ for a group of statements: .. productionlist:: try_stmt: try1_stmt | try2_stmt try1_stmt: "try" ":" `suite` - : ("except" [`expression` ["as" `target`]] ":" `suite`)+ + : ("except" [`expression` ["as" `identifier`]] ":" `suite`)+ : ["else" ":" `suite`] : ["finally" ":" `suite`] try2_stmt: "try" ":" `suite` @@ -284,7 +295,7 @@ keeping all locals in that frame alive until the next garbage collection occurs. object: traceback Before an except clause's suite is executed, details about the exception are -stored in the :mod:`sys` module and can be access via :func:`sys.exc_info`. +stored in the :mod:`sys` module and can be accessed via :func:`sys.exc_info`. :func:`sys.exc_info` returns a 3-tuple consisting of the exception class, the exception instance and a traceback object (see section :ref:`types`) identifying the point in the program where the exception occurred. :func:`sys.exc_info` @@ -313,14 +324,14 @@ exception, the saved exception is set as the context of the new exception. If the :keyword:`finally` clause executes a :keyword:`return` or :keyword:`break` statement, the saved exception is discarded:: - def f(): - try: - 1/0 - finally: - return 42 - - >>> f() - 42 + >>> def f(): + ... try: + ... 1/0 + ... finally: + ... return 42 + ... + >>> f() + 42 The exception information is not available to the program during execution of the :keyword:`finally` clause. @@ -337,6 +348,20 @@ statement, the :keyword:`finally` clause is also executed 'on the way out.' A reason is a problem with the current implementation --- this restriction may be lifted in the future). +The return value of a function is determined by the last :keyword:`return` +statement executed. Since the :keyword:`finally` clause always executes, a +:keyword:`return` statement executed in the :keyword:`finally` clause will +always be the last one executed:: + + >>> def foo(): + ... try: + ... return 'try' + ... finally: + ... return 'finally' + ... + >>> foo() + 'finally' + Additional information on exceptions can be found in section :ref:`exceptions`, and information on using the :keyword:`raise` statement to generate exceptions may be found in section :ref:`raise`. @@ -348,7 +373,9 @@ may be found in section :ref:`raise`. The :keyword:`with` statement ============================= -.. index:: statement: with +.. index:: + statement: with + single: as; with statement The :keyword:`with` statement is used to wrap the execution of a block with methods defined by a context manager (see section :ref:`context-managers`). @@ -444,10 +471,10 @@ A function definition defines a user-defined function object (see section decorators: `decorator`+ decorator: "@" `dotted_name` ["(" [`parameter_list` [","]] ")"] NEWLINE dotted_name: `identifier` ("." `identifier`)* - parameter_list: (`defparameter` ",")* - : ( "*" [`parameter`] ("," `defparameter`)* ["," "**" `parameter`] - : | "**" `parameter` - : | `defparameter` [","] ) + parameter_list: `defparameter` ("," `defparameter`)* ["," [`parameter_list_starargs`]] + : | `parameter_list_starargs` + parameter_list_starargs: "*" [`parameter`] ("," `defparameter`)* ["," ["**" `parameter` [","]]] + : | "**" `parameter` [","] parameter: `identifier` [":" `expression`] defparameter: `parameter` ["=" `expression`] funcname: `identifier` @@ -636,6 +663,130 @@ can be used to create instance variables with different implementation details. :pep:`3129` - Class Decorators +Coroutines +========== + +.. versionadded:: 3.5 + +.. index:: statement: async def +.. _`async def`: + +Coroutine function definition +----------------------------- + +.. productionlist:: + async_funcdef: [`decorators`] "async" "def" `funcname` "(" [`parameter_list`] ")" ["->" `expression`] ":" `suite` + +.. index:: + keyword: async + keyword: await + +Execution of Python coroutines can be suspended and resumed at many points +(see :term:`coroutine`). In the body of a coroutine, any ``await`` and +``async`` identifiers become reserved keywords; :keyword:`await` expressions, +:keyword:`async for` and :keyword:`async with` can only be used in +coroutine bodies. + +Functions defined with ``async def`` syntax are always coroutine functions, +even if they do not contain ``await`` or ``async`` keywords. + +It is a :exc:`SyntaxError` to use :keyword:`yield` expressions in +``async def`` coroutines. + +An example of a coroutine function:: + + async def func(param1, param2): + do_stuff() + await some_coroutine() + + +.. index:: statement: async for +.. _`async for`: + +The :keyword:`async for` statement +---------------------------------- + +.. productionlist:: + async_for_stmt: "async" `for_stmt` + +An :term:`asynchronous iterable` is able to call asynchronous code in its +*iter* implementation, and :term:`asynchronous iterator` can call asynchronous +code in its *next* method. + +The ``async for`` statement allows convenient iteration over asynchronous +iterators. + +The following code:: + + async for TARGET in ITER: + BLOCK + else: + BLOCK2 + +Is semantically equivalent to:: + + iter = (ITER) + iter = await type(iter).__aiter__(iter) + running = True + while running: + try: + TARGET = await type(iter).__anext__(iter) + except StopAsyncIteration: + running = False + else: + BLOCK + else: + BLOCK2 + +See also :meth:`__aiter__` and :meth:`__anext__` for details. + +It is a :exc:`SyntaxError` to use ``async for`` statement outside of an +:keyword:`async def` function. + + +.. index:: statement: async with +.. _`async with`: + +The :keyword:`async with` statement +----------------------------------- + +.. productionlist:: + async_with_stmt: "async" `with_stmt` + +An :term:`asynchronous context manager` is a :term:`context manager` that is +able to suspend execution in its *enter* and *exit* methods. + +The following code:: + + async with EXPR as VAR: + BLOCK + +Is semantically equivalent to:: + + mgr = (EXPR) + aexit = type(mgr).__aexit__ + aenter = type(mgr).__aenter__(mgr) + exc = True + + VAR = await aenter + try: + BLOCK + except: + if not await aexit(mgr, *sys.exc_info()): + raise + else: + await aexit(mgr, None, None, None) + +See also :meth:`__aenter__` and :meth:`__aexit__` for details. + +It is a :exc:`SyntaxError` to use ``async with`` statement outside of an +:keyword:`async def` function. + +.. seealso:: + + :pep:`492` - Coroutines with async and await syntax + + .. rubric:: Footnotes .. [#] The exception is propagated to the invocation stack unless diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 0e936c68c02a..3032dc8d91f3 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -77,7 +77,7 @@ are still reachable. module for information on controlling the collection of cyclic garbage. Other implementations act differently and CPython may change. Do not depend on immediate finalization of objects when they become - unreachable (ex: always close files). + unreachable (so you should always close files explicitly). Note that the use of the implementation's tracing or debugging facilities may keep objects alive that would normally be collectable. Also note that catching @@ -154,11 +154,16 @@ NotImplemented This type has a single value. There is a single object with this value. This object is accessed through the built-in name ``NotImplemented``. Numeric methods - and rich comparison methods may return this value if they do not implement the + and rich comparison methods should return this value if they do not implement the operation for the operands provided. (The interpreter will then try the reflected operation, or some other fallback, depending on the operator.) Its truth value is true. + See + :ref:`implementing-the-arithmetic-operations` + for more details. + + Ellipsis .. index:: object: Ellipsis @@ -222,7 +227,7 @@ Ellipsis at the mercy of the underlying machine architecture (and C or Java implementation) for the accepted range and handling of overflow. Python does not support single-precision floating point numbers; the savings in processor and - memory usage that are usually the reason for using these is dwarfed by the + memory usage that are usually the reason for using these are dwarfed by the overhead of using objects in Python, so there is no reason to complicate the language with two kinds of floating point numbers. @@ -285,16 +290,17 @@ Sequences single: integer single: Unicode - A string is a sequence of values that represent Unicode codepoints. - All the codepoints in range ``U+0000 - U+10FFFF`` can be represented - in a string. Python doesn't have a :c:type:`chr` type, and - every character in the string is represented as a string object - with length ``1``. The built-in function :func:`ord` converts a - character to its codepoint (as an integer); :func:`chr` converts - an integer in range ``0 - 10FFFF`` to the corresponding character. + A string is a sequence of values that represent Unicode code points. + All the code points in the range ``U+0000 - U+10FFFF`` can be + represented in a string. Python doesn't have a :c:type:`char` type; + instead, every code point in the string is represented as a string + object with length ``1``. The built-in function :func:`ord` + converts a code point from its string form to an integer in the + range ``0 - 10FFFF``; :func:`chr` converts an integer in the range + ``0 - 10FFFF`` to the corresponding length ``1`` string object. :meth:`str.encode` can be used to convert a :class:`str` to - :class:`bytes` using the given encoding, and :meth:`bytes.decode` can - be used to achieve the opposite. + :class:`bytes` using the given text encoding, and + :meth:`bytes.decode` can be used to achieve the opposite. Tuples .. index:: @@ -323,8 +329,6 @@ Sequences object: mutable sequence object: mutable pair: assignment; statement - single: delete - statement: del single: subscription single: slicing @@ -455,7 +459,8 @@ Callable types +=========================+===============================+===========+ | :attr:`__doc__` | The function's documentation | Writable | | | string, or ``None`` if | | - | | unavailable | | + | | unavailable; not inherited by | | + | | subclasses | | +-------------------------+-------------------------------+-----------+ | :attr:`__name__` | The function's name | Writable | +-------------------------+-------------------------------+-----------+ @@ -495,7 +500,7 @@ Callable types | :attr:`__annotations__` | A dict containing annotations | Writable | | | of parameters. The keys of | | | | the dict are the parameter | | - | | names, or ``'return'`` for | | + | | names, and ``'return'`` for | | | | the return annotation, if | | | | provided. | | +-------------------------+-------------------------------+-----------+ @@ -611,6 +616,16 @@ Callable types exception is raised and the iterator will have reached the end of the set of values to be returned. + Coroutine functions + .. index:: + single: coroutine; function + + A function or method which is defined using :keyword:`async def` is called + a :dfn:`coroutine function`. Such a function, when called, returns a + :term:`coroutine` object. It may contain :keyword:`await` expressions, + as well as :keyword:`async with` and :keyword:`async for` statements. See + also the :ref:`coroutine-objects` section. + Built-in functions .. index:: object: built-in function @@ -709,7 +724,7 @@ Custom classes where there are multiple inheritance paths leading back to a common ancestor. Additional details on the C3 MRO used by Python can be found in the documentation accompanying the 2.3 release at - http://www.python.org/download/releases/2.3/mro/. + https://www.python.org/download/releases/2.3/mro/. .. XXX: Could we add that MRO doc as an appendix to the language ref? @@ -1095,13 +1110,17 @@ Basic customization .. index:: pair: class; constructor - Called when the instance is created. The arguments are those passed to the - class constructor expression. If a base class has an :meth:`__init__` method, - the derived class's :meth:`__init__` method, if any, must explicitly call it to - ensure proper initialization of the base class part of the instance; for - example: ``BaseClass.__init__(self, [args...])``. As a special constraint on - constructors, no value may be returned; doing so will cause a :exc:`TypeError` - to be raised at runtime. + Called after the instance has been created (by :meth:`__new__`), but before + it is returned to the caller. The arguments are those passed to the + class constructor expression. If a base class has an :meth:`__init__` + method, the derived class's :meth:`__init__` method, if any, must explicitly + call it to ensure proper initialization of the base class part of the + instance; for example: ``BaseClass.__init__(self, [args...])``. + + Because :meth:`__new__` and :meth:`__init__` work together in constructing + objects (:meth:`__new__` to create it, and :meth:`__init__` to customise it), + no non-``None`` value may be returned by :meth:`__init__`; doing so will + cause a :exc:`TypeError` to be raised at runtime. .. method:: object.__del__(self) @@ -1133,8 +1152,10 @@ Basic customization reference to the object on the stack frame that raised an unhandled exception in interactive mode (the traceback stored in ``sys.last_traceback`` keeps the stack frame alive). The first situation - can only be remedied by explicitly breaking the cycles; the latter two - situations can be resolved by storing ``None`` in ``sys.last_traceback``. + can only be remedied by explicitly breaking the cycles; the second can be + resolved by freeing the reference to the traceback object when it is no + longer useful, and the third can be resolved by storing ``None`` in + ``sys.last_traceback``. Circular references which are garbage are detected and cleaned up when the cyclic garbage collector is enabled (it's on by default). Refer to the documentation for the :mod:`gc` module for more information about this @@ -1226,6 +1247,10 @@ Basic customization The return value must be a string object. + .. versionchanged:: 3.4 + The __format__ method of ``object`` itself raises a :exc:`TypeError` + if passed any non-empty string. + .. _richcmpfuncs: .. method:: object.__lt__(self, other) @@ -1251,10 +1276,14 @@ Basic customization context (e.g., in the condition of an ``if`` statement), Python will call :func:`bool` on the value to determine if the result is true or false. - There are no implied relationships among the comparison operators. The truth - of ``x==y`` does not imply that ``x!=y`` is false. Accordingly, when - defining :meth:`__eq__`, one should also define :meth:`__ne__` so that the - operators will behave as expected. See the paragraph on :meth:`__hash__` for + By default, :meth:`__ne__` delegates to :meth:`__eq__` and + inverts the result unless it is ``NotImplemented``. There are no other + implied relationships among the comparison operators, for example, + the truth of ``(x<y or x==y)`` does not imply ``x<=y``. + To automatically generate ordering operations from a single root operation, + see :func:`functools.total_ordering`. + + See the paragraph on :meth:`__hash__` for some important notes on creating :term:`hashable` objects which support custom comparison operations and are usable as dictionary keys. @@ -1263,11 +1292,11 @@ Basic customization rather, :meth:`__lt__` and :meth:`__gt__` are each other's reflection, :meth:`__le__` and :meth:`__ge__` are each other's reflection, and :meth:`__eq__` and :meth:`__ne__` are their own reflection. - - Arguments to rich comparison methods are never coerced. - - To automatically generate ordering operations from a single root operation, - see :func:`functools.total_ordering`. + If the operands are of different types, and right operand's type is + a direct or indirect subclass of the left operand's type, + the reflected method of the right operand has priority, otherwise + the left operand's method has priority. Virtual subclassing is + not considered. .. method:: object.__hash__(self) @@ -1291,7 +1320,7 @@ Basic customization object's :meth:`__hash__` must interoperate on builds of different bit sizes, be sure to check the width on all supported builds. An easy way to do this is with - ``python -c "import sys; print(sys.hash_info.width)"`` + ``python -c "import sys; print(sys.hash_info.width)"``. If a class does not define an :meth:`__eq__` method it should not define a :meth:`__hash__` operation either; if it defines :meth:`__eq__` but not @@ -1312,7 +1341,7 @@ Basic customization :meth:`__hash__` method of a class is ``None``, instances of the class will raise an appropriate :exc:`TypeError` when a program attempts to retrieve their hash value, and will also be correctly identified as unhashable when - checking ``isinstance(obj, collections.Hashable``). + checking ``isinstance(obj, collections.Hashable)``. If a class that overrides :meth:`__eq__` needs to retain the implementation of :meth:`__hash__` from a parent class, the interpreter must be told this @@ -1463,6 +1492,14 @@ class' :attr:`__dict__`. Called to delete the attribute on an instance *instance* of the owner class. +The attribute :attr:`__objclass__` is interpreted by the :mod:`inspect` module +as specifying the class where this object was defined (setting this +appropriately can assist in runtime introspection of dynamic class attributes). +For callables, it may indicate that an instance of the given type (or a +subclass) is expected or required as the first positional argument (for example, +CPython sets this attribute for unbound methods that are implemented in C). + + .. _descriptor-invocation: Invoking Descriptors @@ -1544,9 +1581,9 @@ saved because *__dict__* is not created for each instance. .. data:: object.__slots__ This class variable can be assigned a string, iterable, or sequence of - strings with variable names used by instances. If defined in a - class, *__slots__* reserves space for the declared variables and prevents the - automatic creation of *__dict__* and *__weakref__* for each instance. + strings with variable names used by instances. *__slots__* reserves space + for the declared variables and prevents the automatic creation of *__dict__* + and *__weakref__* for each instance. Notes on using *__slots__* @@ -1583,7 +1620,7 @@ Notes on using *__slots__* program undefined. In the future, a check may be added to prevent this. * Nonempty *__slots__* does not work for classes derived from "variable-length" - built-in types such as :class:`int`, :class:`str` and :class:`tuple`. + built-in types such as :class:`int`, :class:`bytes` and :class:`tuple`. * Any non-string iterable may be assigned to *__slots__*. Mappings may also be used; however, in the future, special meaning may be assigned to the values @@ -1643,6 +1680,8 @@ of these candidate metaclasses. If none of the candidate metaclasses meets that criterion, then the class definition will fail with ``TypeError``. +.. _prepare: + Preparing the class namespace ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1710,7 +1749,7 @@ property creation, proxies, frameworks, and automatic resource locking/synchronization. Here is an example of a metaclass that uses an :class:`collections.OrderedDict` -to remember the order that class members were defined:: +to remember the order that class variables are defined:: class OrderedClass(type): @@ -1883,6 +1922,12 @@ through the container; for mappings, :meth:`__iter__` should be the same as indexes to allow proper detection of the end of the sequence. +.. method:: object.__missing__(self, key) + + Called by :class:`dict`\ .\ :meth:`__getitem__` to implement ``self[key]`` for dict subclasses + when key is not in the dictionary. + + .. method:: object.__setitem__(self, key, value) Called to implement assignment to ``self[key]``. Same note as for @@ -1905,8 +1950,7 @@ through the container; for mappings, :meth:`__iter__` should be the same as This method is called when an iterator is required for a container. This method should return a new iterator object that can iterate over all the objects in the - container. For mappings, it should iterate over the keys of the container, and - should also be made available as the method :meth:`keys`. + container. For mappings, it should iterate over the keys of the container. Iterator objects also need to implement this method; they are required to return themselves. For more information on iterator objects, see :ref:`typeiter`. @@ -1956,6 +2000,7 @@ left undefined. .. method:: object.__add__(self, other) object.__sub__(self, other) object.__mul__(self, other) + object.__matmul__(self, other) object.__truediv__(self, other) object.__floordiv__(self, other) object.__mod__(self, other) @@ -1972,15 +2017,16 @@ left undefined. builtin: pow builtin: pow - These methods are called to implement the binary arithmetic operations (``+``, - ``-``, ``*``, ``/``, ``//``, ``%``, :func:`divmod`, :func:`pow`, ``**``, ``<<``, - ``>>``, ``&``, ``^``, ``|``). For instance, to evaluate the expression - ``x + y``, where *x* is an instance of a class that has an :meth:`__add__` - method, ``x.__add__(y)`` is called. The :meth:`__divmod__` method should be the - equivalent to using :meth:`__floordiv__` and :meth:`__mod__`; it should not be - related to :meth:`__truediv__`. Note that :meth:`__pow__` should be defined - to accept an optional third argument if the ternary version of the built-in - :func:`pow` function is to be supported. + These methods are called to implement the binary arithmetic operations + (``+``, ``-``, ``*``, ``@``, ``/``, ``//``, ``%``, :func:`divmod`, + :func:`pow`, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``). For instance, to + evaluate the expression ``x + y``, where *x* is an instance of a class that + has an :meth:`__add__` method, ``x.__add__(y)`` is called. The + :meth:`__divmod__` method should be the equivalent to using + :meth:`__floordiv__` and :meth:`__mod__`; it should not be related to + :meth:`__truediv__`. Note that :meth:`__pow__` should be defined to accept + an optional third argument if the ternary version of the built-in :func:`pow` + function is to be supported. If one of those methods does not support the operation with the supplied arguments, it should return ``NotImplemented``. @@ -1989,6 +2035,7 @@ left undefined. .. method:: object.__radd__(self, other) object.__rsub__(self, other) object.__rmul__(self, other) + object.__rmatmul__(self, other) object.__rtruediv__(self, other) object.__rfloordiv__(self, other) object.__rmod__(self, other) @@ -2004,14 +2051,14 @@ left undefined. builtin: divmod builtin: pow - These methods are called to implement the binary arithmetic operations (``+``, - ``-``, ``*``, ``/``, ``//``, ``%``, :func:`divmod`, :func:`pow`, ``**``, - ``<<``, ``>>``, ``&``, ``^``, ``|``) with reflected (swapped) operands. - These functions are only called if the left operand does not support the - corresponding operation and the operands are of different types. [#]_ For - instance, to evaluate the expression ``x - y``, where *y* is an instance of - a class that has an :meth:`__rsub__` method, ``y.__rsub__(x)`` is called if - ``x.__sub__(y)`` returns *NotImplemented*. + These methods are called to implement the binary arithmetic operations + (``+``, ``-``, ``*``, ``@``, ``/``, ``//``, ``%``, :func:`divmod`, + :func:`pow`, ``**``, ``<<``, ``>>``, ``&``, ``^``, ``|``) with reflected + (swapped) operands. These functions are only called if the left operand does + not support the corresponding operation and the operands are of different + types. [#]_ For instance, to evaluate the expression ``x - y``, where *y* is + an instance of a class that has an :meth:`__rsub__` method, ``y.__rsub__(x)`` + is called if ``x.__sub__(y)`` returns *NotImplemented*. .. index:: builtin: pow @@ -2029,6 +2076,7 @@ left undefined. .. method:: object.__iadd__(self, other) object.__isub__(self, other) object.__imul__(self, other) + object.__imatmul__(self, other) object.__itruediv__(self, other) object.__ifloordiv__(self, other) object.__imod__(self, other) @@ -2040,15 +2088,17 @@ left undefined. object.__ior__(self, other) These methods are called to implement the augmented arithmetic assignments - (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``, ``**=``, ``<<=``, ``>>=``, - ``&=``, ``^=``, ``|=``). These methods should attempt to do the operation - in-place (modifying *self*) and return the result (which could be, but does - not have to be, *self*). If a specific method is not defined, the augmented - assignment falls back to the normal methods. For instance, to execute the - statement ``x += y``, where *x* is an instance of a class that has an - :meth:`__iadd__` method, ``x.__iadd__(y)`` is called. If *x* is an instance - of a class that does not define a :meth:`__iadd__` method, ``x.__add__(y)`` - and ``y.__radd__(x)`` are considered, as with the evaluation of ``x + y``. + (``+=``, ``-=``, ``*=``, ``@=``, ``/=``, ``//=``, ``%=``, ``**=``, ``<<=``, + ``>>=``, ``&=``, ``^=``, ``|=``). These methods should attempt to do the + operation in-place (modifying *self*) and return the result (which could be, + but does not have to be, *self*). If a specific method is not defined, the + augmented assignment falls back to the normal methods. For instance, if *x* + is an instance of a class with an :meth:`__iadd__` method, ``x += y`` is + equivalent to ``x = x.__iadd__(y)`` . Otherwise, ``x.__add__(y)`` and + ``y.__radd__(x)`` are considered, as with the evaluation of ``x + y``. In + certain situations, augmented assignment can result in unexpected errors (see + :ref:`faq-augmented-assignment-tuple-error`), but this behavior is in fact + part of the data model. .. method:: object.__neg__(self) @@ -2080,9 +2130,17 @@ left undefined. .. method:: object.__index__(self) - Called to implement :func:`operator.index`. Also called whenever Python needs - an integer object (such as in slicing, or in the built-in :func:`bin`, - :func:`hex` and :func:`oct` functions). Must return an integer. + Called to implement :func:`operator.index`, and whenever Python needs to + losslessly convert the numeric object to an integer object (such as in + slicing, or in the built-in :func:`bin`, :func:`hex` and :func:`oct` + functions). Presence of this method indicates that the numeric object is + an integer type. Must return an integer. + + .. note:: + + In order to have a coherent integer type class, when :meth:`__index__` is + defined :meth:`__int__` should also be defined, and both should return + the same value. .. _context-managers: @@ -2182,9 +2240,9 @@ correctness, implicit special method lookup generally also bypasses the :meth:`__getattribute__` method even of the object's metaclass:: >>> class Meta(type): - ... def __getattribute__(*args): - ... print("Metaclass getattribute invoked") - ... return type.__getattribute__(*args) + ... def __getattribute__(*args): + ... print("Metaclass getattribute invoked") + ... return type.__getattribute__(*args) ... >>> class C(object, metaclass=Meta): ... def __len__(self): @@ -2210,6 +2268,155 @@ special methods (the special method *must* be set on the class object itself in order to be consistently invoked by the interpreter). +.. index:: + single: coroutine + +Coroutines +========== + + +Awaitable Objects +----------------- + +An :term:`awaitable` object generally implements an :meth:`__await__` method. +:term:`Coroutine` objects returned from :keyword:`async def` functions +are awaitable. + +.. note:: + + The :term:`generator iterator` objects returned from generators + decorated with :func:`types.coroutine` or :func:`asyncio.coroutine` + are also awaitable, but they do not implement :meth:`__await__`. + +.. method:: object.__await__(self) + + Must return an :term:`iterator`. Should be used to implement + :term:`awaitable` objects. For instance, :class:`asyncio.Future` implements + this method to be compatible with the :keyword:`await` expression. + +.. versionadded:: 3.5 + +.. seealso:: :pep:`492` for additional information about awaitable objects. + + +.. _coroutine-objects: + +Coroutine Objects +----------------- + +:term:`Coroutine` objects are :term:`awaitable` objects. +A coroutine's execution can be controlled by calling :meth:`__await__` and +iterating over the result. When the coroutine has finished executing and +returns, the iterator raises :exc:`StopIteration`, and the exception's +:attr:`~StopIteration.value` attribute holds the return value. If the +coroutine raises an exception, it is propagated by the iterator. Coroutines +should not directly raise unhandled :exc:`StopIteration` exceptions. + +Coroutines also have the methods listed below, which are analogous to +those of generators (see :ref:`generator-methods`). However, unlike +generators, coroutines do not directly support iteration. + +.. method:: coroutine.send(value) + + Starts or resumes execution of the coroutine. If *value* is ``None``, + this is equivalent to advancing the iterator returned by + :meth:`__await__`. If *value* is not ``None``, this method delegates + to the :meth:`~generator.send` method of the iterator that caused + the coroutine to suspend. The result (return value, + :exc:`StopIteration`, or other exception) is the same as when + iterating over the :meth:`__await__` return value, described above. + +.. method:: coroutine.throw(type[, value[, traceback]]) + + Raises the specified exception in the coroutine. This method delegates + to the :meth:`~generator.throw` method of the iterator that caused + the coroutine to suspend, if it has such a method. Otherwise, + the exception is raised at the suspension point. The result + (return value, :exc:`StopIteration`, or other exception) is the same as + when iterating over the :meth:`__await__` return value, described + above. If the exception is not caught in the coroutine, it propagates + back to the caller. + +.. method:: coroutine.close() + + Causes the coroutine to clean itself up and exit. If the coroutine + is suspended, this method first delegates to the :meth:`~generator.close` + method of the iterator that caused the coroutine to suspend, if it + has such a method. Then it raises :exc:`GeneratorExit` at the + suspension point, causing the coroutine to immediately clean itself up. + Finally, the coroutine is marked as having finished executing, even if + it was never started. + + Coroutine objects are automatically closed using the above process when + they are about to be destroyed. + + +Asynchronous Iterators +---------------------- + +An *asynchronous iterable* is able to call asynchronous code in its +``__aiter__`` implementation, and an *asynchronous iterator* can call +asynchronous code in its ``__anext__`` method. + +Asynchronous iterators can be used in a :keyword:`async for` statement. + +.. method:: object.__aiter__(self) + + Must return an *awaitable* resulting in an *asynchronous iterator* object. + +.. method:: object.__anext__(self) + + Must return an *awaitable* resulting in a next value of the iterator. Should + raise a :exc:`StopAsyncIteration` error when the iteration is over. + +An example of an asynchronous iterable object:: + + class Reader: + async def readline(self): + ... + + async def __aiter__(self): + return self + + async def __anext__(self): + val = await self.readline() + if val == b'': + raise StopAsyncIteration + return val + +.. versionadded:: 3.5 + + +Asynchronous Context Managers +----------------------------- + +An *asynchronous context manager* is a *context manager* that is able to +suspend execution in its ``__aenter__`` and ``__aexit__`` methods. + +Asynchronous context managers can be used in a :keyword:`async with` statement. + +.. method:: object.__aenter__(self) + + This method is semantically similar to the :meth:`__enter__`, with only + difference that it must return an *awaitable*. + +.. method:: object.__aexit__(self, exc_type, exc_value, traceback) + + This method is semantically similar to the :meth:`__exit__`, with only + difference that it must return an *awaitable*. + +An example of an asynchronous context manager class:: + + class AsyncContextManager: + async def __aenter__(self): + await log('entering context') + + async def __aexit__(self, exc_type, exc, tb): + await log('exiting context') + +.. versionadded:: 3.5 + + .. rubric:: Footnotes .. [#] It *is* possible in some cases to change an object's type, under certain diff --git a/Doc/reference/executionmodel.rst b/Doc/reference/executionmodel.rst index 82e37a21fab5..5dfa0d2eb287 100644 --- a/Doc/reference/executionmodel.rst +++ b/Doc/reference/executionmodel.rst @@ -5,37 +5,26 @@ Execution model *************** -.. index:: single: execution model - - -.. _naming: - -Naming and binding -================== - .. index:: + single: execution model pair: code; block - single: namespace - single: scope -.. index:: - single: name - pair: binding; name +.. _prog_structure: -:dfn:`Names` refer to objects. Names are introduced by name binding operations. -Each occurrence of a name in the program text refers to the :dfn:`binding` of -that name established in the innermost function block containing the use. +Structure of a programm +======================= .. index:: block +A Python program is constructed from code blocks. A :dfn:`block` is a piece of Python program text that is executed as a unit. The following are blocks: a module, a function body, and a class definition. Each command typed interactively is a block. A script file (a file given as -standard input to the interpreter or specified on the interpreter command line -the first argument) is a code block. A script command (a command specified on -the interpreter command line with the '**-c**' option) is a code block. The -string argument passed to the built-in functions :func:`eval` and :func:`exec` -is a code block. +standard input to the interpreter or specified as a command line argument to the +interpreter) is a code block. A script command (a command specified on the +interpreter command line with the '**-c**' option) is a code block. The string +argument passed to the built-in functions :func:`eval` and :func:`exec` is a +code block. .. index:: pair: execution; frame @@ -43,43 +32,25 @@ A code block is executed in an :dfn:`execution frame`. A frame contains some administrative information (used for debugging) and determines where and how execution continues after the code block's execution has completed. -.. index:: scope - -A :dfn:`scope` defines the visibility of a name within a block. If a local -variable is defined in a block, its scope includes that block. If the -definition occurs in a function block, the scope extends to any blocks contained -within the defining one, unless a contained block introduces a different binding -for the name. The scope of names defined in a class block is limited to the -class block; it does not extend to the code blocks of methods -- this includes -comprehensions and generator expressions since they are implemented using a -function scope. This means that the following will fail:: - - class A: - a = 42 - b = list(a + i for i in range(10)) +.. _naming: -.. index:: single: environment +Naming and binding +================== -When a name is used in a code block, it is resolved using the nearest enclosing -scope. The set of all such scopes visible to a code block is called the block's -:dfn:`environment`. +.. index:: + single: namespace + single: scope -.. index:: pair: free; variable +.. _bind_names: -If a name is bound in a block, it is a local variable of that block, unless -declared as :keyword:`nonlocal`. If a name is bound at the module level, it is -a global variable. (The variables of the module code block are local and -global.) If a variable is used in a code block but not defined there, it is a -:dfn:`free variable`. +Binding of names +---------------- .. index:: - single: NameError (built-in exception) - single: UnboundLocalError + single: name + pair: binding; name -When a name is not found at all, a :exc:`NameError` exception is raised. If the -name refers to a local variable that has not been bound, a -:exc:`UnboundLocalError` exception is raised. :exc:`UnboundLocalError` is a -subclass of :exc:`NameError`. +:dfn:`Names` refer to objects. Names are introduced by name binding operations. .. index:: statement: from @@ -99,6 +70,46 @@ this purpose (though the actual semantics are to unbind the name). Each assignment or import statement occurs within a block defined by a class or function definition or at the module level (the top-level code block). +.. index:: pair: free; variable + +If a name is bound in a block, it is a local variable of that block, unless +declared as :keyword:`nonlocal` or :keyword:`global`. If a name is bound at +the module level, it is a global variable. (The variables of the module code +block are local and global.) If a variable is used in a code block but not +defined there, it is a :dfn:`free variable`. + +Each occurrence of a name in the program text refers to the :dfn:`binding` of +that name established by the following name resolution rules. + +.. _resolve_names: + +Resolution of names +------------------- + +.. index:: scope + +A :dfn:`scope` defines the visibility of a name within a block. If a local +variable is defined in a block, its scope includes that block. If the +definition occurs in a function block, the scope extends to any blocks contained +within the defining one, unless a contained block introduces a different binding +for the name. + +.. index:: single: environment + +When a name is used in a code block, it is resolved using the nearest enclosing +scope. The set of all such scopes visible to a code block is called the block's +:dfn:`environment`. + +.. index:: + single: NameError (built-in exception) + single: UnboundLocalError + +When a name is not found at all, a :exc:`NameError` exception is raised. +If the current scope is a function scope, and the name refers to a local +variable that has not yet been bound to a value at the point where the name is +used, an :exc:`UnboundLocalError` exception is raised. +:exc:`UnboundLocalError` is a subclass of :exc:`NameError`. + If a name binding operation occurs anywhere within a code block, all uses of the name within the block are treated as references to the current block. This can lead to errors when a name is used within a block before it is bound. This rule @@ -111,10 +122,45 @@ specified in the statement refer to the binding of that name in the top-level namespace. Names are resolved in the top-level namespace by searching the global namespace, i.e. the namespace of the module containing the code block, and the builtins namespace, the namespace of the module :mod:`builtins`. The -global namespace is searched first. If the name is not found there, the builtins -namespace is searched. The global statement must precede all uses of the name. +global namespace is searched first. If the name is not found there, the +builtins namespace is searched. The :keyword:`global` statement must precede +all uses of the name. + +The :keyword:`global` statement has the same scope as a name binding operation +in the same block. If the nearest enclosing scope for a free variable contains +a global statement, the free variable is treated as a global. + +.. XXX say more about "nonlocal" semantics here -.. XXX document "nonlocal" semantics here +The :keyword:`nonlocal` statement causes corresponding names to refer +to previously bound variables in the nearest enclosing function scope. +:exc:`SyntaxError` is raised at compile time if the given name does not +exist in any enclosing function scope. + +.. index:: module: __main__ + +The namespace for a module is automatically created the first time a module is +imported. The main module for a script is always called :mod:`__main__`. + +Class definition blocks and arguments to :func:`exec` and :func:`eval` are +special in the context of name resolution. +A class definition is an executable statement that may use and define names. +These references follow the normal rules for name resolution with an exception +that unbound local variables are looked up in the global namespace. +The namespace of the class definition becomes the attribute dictionary of +the class. The scope of names defined in a class block is limited to the +class block; it does not extend to the code blocks of methods -- this includes +comprehensions and generator expressions since they are implemented using a +function scope. This means that the following will fail:: + + class A: + a = 42 + b = list(a + i for i in range(10)) + +.. _restrict_exec: + +Builtins and restricted execution +--------------------------------- .. index:: pair: restricted; execution @@ -134,36 +180,26 @@ weak form of restricted execution. :keyword:`import` the :mod:`builtins` module and modify its attributes appropriately. -.. index:: module: __main__ - -The namespace for a module is automatically created the first time a module is -imported. The main module for a script is always called :mod:`__main__`. - -The :keyword:`global` statement has the same scope as a name binding operation -in the same block. If the nearest enclosing scope for a free variable contains -a global statement, the free variable is treated as a global. - -A class definition is an executable statement that may use and define names. -These references follow the normal rules for name resolution. The namespace of -the class definition becomes the attribute dictionary of the class. Names -defined at the class scope are not visible in methods. - - .. _dynamic-features: Interaction with dynamic features --------------------------------- +Name resolution of free variables occurs at runtime, not at compile time. +This means that the following code will print 42:: + + i = 10 + def f(): + print(i) + i = 42 + f() + There are several cases where Python statements are illegal when used in conjunction with nested scopes that contain free variables. If a variable is referenced in an enclosing scope, it is illegal to delete the name. An error will be reported at compile time. -If the wild card form of import --- ``import *`` --- is used in a function and -the function contains or is a nested block with free variables, the compiler -will raise a :exc:`SyntaxError`. - .. XXX from * also invalid with relative imports (at least currently) The :func:`eval` and :func:`exec` functions do not have access to the full diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 66358c877db4..99fa037bf6e4 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -29,7 +29,7 @@ Arithmetic conversions When a description of an arithmetic operator below uses the phrase "the numeric arguments are converted to a common type," this means that the operator -implementation for built-in types works that way: +implementation for built-in types works as follows: * If either argument is a complex number, the other is converted to complex; @@ -38,8 +38,9 @@ implementation for built-in types works that way: * otherwise, both must be integers and no conversion is necessary. -Some additional rules apply for certain operators (e.g., a string left argument -to the '%' operator). Extensions must define their own conversion behavior. +Some additional rules apply for certain operators (e.g., a string as a left +argument to the '%' operator). Extensions must define their own conversion +behavior. .. _atoms: @@ -183,7 +184,7 @@ nesting from left to right, and evaluating the expression to produce an element each time the innermost block is reached. Note that the comprehension is executed in a separate scope, so names assigned -to in the target list don't "leak" in the enclosing scope. +to in the target list don't "leak" into the enclosing scope. .. _lists: @@ -293,7 +294,7 @@ for comprehensions, except that it is enclosed in parentheses instead of brackets or curly braces. Variables used in the generator expression are evaluated lazily when the -:meth:`~generator.__next__` method is called for generator object (in the same +:meth:`~generator.__next__` method is called for the generator object (in the same fashion as normal generators). However, the leftmost :keyword:`for` clause is immediately evaluated, so that an error produced by it can be seen before any other possible error in the code that handles the generator expression. @@ -302,7 +303,7 @@ may depend on the previous :keyword:`for` loop. For example: ``(x*y for x in range(10) for y in bar(x))``. The parentheses can be omitted on calls with only one argument. See section -:ref:`calls` for the detail. +:ref:`calls` for details. .. _yieldexpr: @@ -319,41 +320,40 @@ Yield expressions yield_atom: "(" `yield_expression` ")" yield_expression: "yield" [`expression_list` | "from" `expression`] -The :keyword:`yield` expression is only used when defining a :term:`generator` -function, -and can only be used in the body of a function definition. Using a -:keyword:`yield` expression in a function definition is sufficient to cause that -definition to create a generator function instead of a normal function. +The yield expression is only used when defining a :term:`generator` function and +thus can only be used in the body of a function definition. Using a yield +expression in a function's body causes that function to be a generator. When a generator function is called, it returns an iterator known as a -generator. That generator then controls the execution of a generator function. +generator. That generator then controls the execution of the generator function. The execution starts when one of the generator's methods is called. At that -time, the execution proceeds to the first :keyword:`yield` expression, where it -is suspended again, returning the value of :token:`expression_list` to -generator's caller. By suspended we mean that all local state is retained, -including the current bindings of local variables, the instruction pointer, and -the internal evaluation stack. When the execution is resumed by calling one of -the generator's methods, the function can proceed exactly as if the -:keyword:`yield` expression was just another external call. The value of the -:keyword:`yield` expression after resuming depends on the method which resumed -the execution. If :meth:`~generator.__next__` is used (typically via either a -:keyword:`for` or the :func:`next` builtin) then the result is :const:`None`, -otherwise, if :meth:`~generator.send` is used, then the result will be the -value passed in to that method. +time, the execution proceeds to the first yield expression, where it is +suspended again, returning the value of :token:`expression_list` to the generator's +caller. By suspended, we mean that all local state is retained, including the +current bindings of local variables, the instruction pointer, the internal +evaluation stack, and the state of any exception handling. When the execution +is resumed by calling one of the +generator's methods, the function can proceed exactly as if the yield expression +were just another external call. The value of the yield expression after +resuming depends on the method which resumed the execution. If +:meth:`~generator.__next__` is used (typically via either a :keyword:`for` or +the :func:`next` builtin) then the result is :const:`None`. Otherwise, if +:meth:`~generator.send` is used, then the result will be the value passed in to +that method. .. index:: single: coroutine All of this makes generator functions quite similar to coroutines; they yield multiple times, they have more than one entry point and their execution can be suspended. The only difference is that a generator function cannot control -where should the execution continue after it yields; the control is always +where the execution should continue after it yields; the control is always transferred to the generator's caller. -:keyword:`yield` expressions are allowed in the :keyword:`try` clause of a -:keyword:`try` ... :keyword:`finally` construct. If the generator is not -resumed before it is finalized (by reaching a zero reference count or by being -garbage collected), the generator-iterator's :meth:`~generator.close` method -will be called, allowing any pending :keyword:`finally` clauses to execute. +Yield expressions are allowed anywhere in a :keyword:`try` construct. If the +generator is not resumed before it is +finalized (by reaching a zero reference count or by being garbage collected), +the generator-iterator's :meth:`~generator.close` method will be called, +allowing any pending :keyword:`finally` clauses to execute. When ``yield from <expr>`` is used, it treats the supplied expression as a subiterator. All values produced by that subiterator are passed directly @@ -371,13 +371,26 @@ the yield expression. It can be either set explicitly when raising (by returning a value from the sub-generator). .. versionchanged:: 3.3 - Added ``yield from <expr>`` to delegate control flow to a subiterator + Added ``yield from <expr>`` to delegate control flow to a subiterator. -The parentheses can be omitted when the :keyword:`yield` expression is the -sole expression on the right hand side of an assignment statement. +The parentheses may be omitted when the yield expression is the sole expression +on the right hand side of an assignment statement. -.. index:: object: generator +.. seealso:: + + :pep:`0255` - Simple Generators + The proposal for adding generators and the :keyword:`yield` statement to Python. + + :pep:`0342` - Coroutines via Enhanced Generators + The proposal to enhance the API and syntax of generators, making them + usable as simple coroutines. + :pep:`0380` - Syntax for Delegating to a Subgenerator + The proposal to introduce the :token:`yield_from` syntax, making delegation + to sub-generators easy. + +.. index:: object: generator +.. _generator-methods: Generator-iterator methods ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -389,19 +402,17 @@ Note that calling any of the generator methods below when the generator is already executing raises a :exc:`ValueError` exception. .. index:: exception: StopIteration -.. class:: generator .. method:: generator.__next__() Starts the execution of a generator function or resumes it at the last - executed :keyword:`yield` expression. When a generator function is resumed - with a :meth:`~generator.__next__` method, the current :keyword:`yield` - expression always evaluates to :const:`None`. The execution then continues - to the next :keyword:`yield` expression, where the generator is suspended - again, and the value of the :token:`expression_list` is returned to - :meth:`next`'s caller. - If the generator exits without yielding another value, a :exc:`StopIteration` + executed yield expression. When a generator function is resumed with a + :meth:`~generator.__next__` method, the current yield expression always + evaluates to :const:`None`. The execution then continues to the next yield + expression, where the generator is suspended again, and the value of the + :token:`expression_list` is returned to :meth:`__next__`'s caller. If the + generator exits without yielding another value, a :exc:`StopIteration` exception is raised. This method is normally called implicitly, e.g. by a :keyword:`for` loop, or @@ -411,17 +422,17 @@ is already executing raises a :exc:`ValueError` exception. .. method:: generator.send(value) Resumes the execution and "sends" a value into the generator function. The - ``value`` argument becomes the result of the current :keyword:`yield` - expression. The :meth:`send` method returns the next value yielded by the - generator, or raises :exc:`StopIteration` if the generator exits without - yielding another value. When :meth:`send` is called to start the generator, - it must be called with :const:`None` as the argument, because there is no - :keyword:`yield` expression that could receive the value. + *value* argument becomes the result of the current yield expression. The + :meth:`send` method returns the next value yielded by the generator, or + raises :exc:`StopIteration` if the generator exits without yielding another + value. When :meth:`send` is called to start the generator, it must be called + with :const:`None` as the argument, because there is no yield expression that + could receive the value. .. method:: generator.throw(type[, value[, traceback]]) - Raises an exception of type ``type`` at the point where generator was paused, + Raises an exception of type ``type`` at the point where the generator was paused, and returns the next value yielded by the generator function. If the generator exits without yielding another value, a :exc:`StopIteration` exception is raised. If the generator function does not catch the passed-in exception, or @@ -433,14 +444,12 @@ is already executing raises a :exc:`ValueError` exception. .. method:: generator.close() Raises a :exc:`GeneratorExit` at the point where the generator function was - paused. If the generator function then raises :exc:`StopIteration` (by - exiting normally, or due to already being closed) or :exc:`GeneratorExit` (by - not catching the exception), close returns to its caller. If the generator - yields a value, a :exc:`RuntimeError` is raised. If the generator raises any - other exception, it is propagated to the caller. :meth:`close` does nothing - if the generator has already exited due to an exception or normal exit. - -.. class:: . + paused. If the generator function then exits gracefully, is already closed, + or raises :exc:`GeneratorExit` (by not catching the exception), close + returns to its caller. If the generator yields a value, a + :exc:`RuntimeError` is raised. If the generator raises any other exception, + it is propagated to the caller. :meth:`close` does nothing if the generator + has already exited due to an exception or normal exit. .. index:: single: yield; examples @@ -478,20 +487,6 @@ For examples using ``yield from``, see :ref:`pep-380` in "What's New in Python." -.. seealso:: - - :pep:`0255` - Simple Generators - The proposal for adding generators and the :keyword:`yield` statement to Python. - - :pep:`0342` - Coroutines via Enhanced Generators - The proposal to enhance the API and syntax of generators, making them - usable as simple coroutines. - - :pep:`0380` - Syntax for Delegating to a Subgenerator - The proposal to introduce the :token:`yield_from` syntax, making delegation - to sub-generators easy. - - .. _primaries: Primaries @@ -525,11 +520,11 @@ An attribute reference is a primary followed by a period and a name: The primary must evaluate to an object of a type that supports attribute references, which most objects do. This object is then asked to produce the -attribute whose name is the identifier (which can be customized by overriding -the :meth:`__getattr__` method). If this attribute is not available, the -exception :exc:`AttributeError` is raised. Otherwise, the type and value of the -object produced is determined by the object. Multiple evaluations of the same -attribute reference may yield different objects. +attribute whose name is the identifier. This production can be customized by +overriding the :meth:`__getattr__` method. If this attribute is not available, +the exception :exc:`AttributeError` is raised. Otherwise, the type and value of +the object produced is determined by the object. Multiple evaluations of the +same attribute reference may yield different objects. .. _subscriptions: @@ -554,9 +549,9 @@ A subscription selects an item of a sequence (string, tuple or list) or mapping .. productionlist:: subscription: `primary` "[" `expression_list` "]" -The primary must evaluate to an object that supports subscription, e.g. a list -or dictionary. User-defined objects can support subscription by defining a -:meth:`__getitem__` method. +The primary must evaluate to an object that supports subscription (lists or +dictionaries for example). User-defined objects can support subscription by +defining a :meth:`__getitem__` method. For built-in objects, there are two types of objects that support subscription: @@ -626,8 +621,8 @@ slice list contains no proper slice). single: stop (slice object attribute) single: step (slice object attribute) -The semantics for a slicing are as follows. The primary must evaluate to a -mapping object, and it is indexed (using the same :meth:`__getitem__` method as +The semantics for a slicing are as follows. The primary is indexed (using the +same :meth:`__getitem__` method as normal subscription) with a key that is constructed from the slice list, as follows. If the slice list contains at least one comma, the key is a tuple containing the conversion of the slice items; otherwise, the conversion of the @@ -665,8 +660,8 @@ series of :term:`arguments <argument>`: keyword_arguments: `keyword_item` ("," `keyword_item`)* keyword_item: `identifier` "=" `expression` -A trailing comma may be present after the positional and keyword arguments but -does not affect the semantics. +An optional trailing comma may be present after the positional and keyword arguments +but does not affect the semantics. .. index:: single: parameter; call semantics @@ -817,6 +812,20 @@ a class instance: if that method was called. +.. _await: + +Await expression +================ + +Suspend the execution of :term:`coroutine` on an :term:`awaitable` object. +Can only be used inside a :term:`coroutine function`. + +.. productionlist:: + await: ["await"] `primary` + +.. versionadded:: 3.5 + + .. _power: The power operator @@ -826,7 +835,7 @@ The power operator binds more tightly than unary operators on its left; it binds less tightly than unary operators on its right. The syntax is: .. productionlist:: - power: `primary` ["**" `u_expr`] + power: `await` ["**" `u_expr`] Thus, in an unparenthesized sequence of power and unary operators, the operators are evaluated from right to left (this does not constrain the evaluation order @@ -897,8 +906,9 @@ from the power operator, there are only two levels, one for multiplicative operators and one for additive operators: .. productionlist:: - m_expr: `u_expr` | `m_expr` "*" `u_expr` | `m_expr` "//" `u_expr` | `m_expr` "/" `u_expr` - : | `m_expr` "%" `u_expr` + m_expr: `u_expr` | `m_expr` "*" `u_expr` | `m_expr` "@" `m_expr` | + : `m_expr` "//" `u_expr`| `m_expr` "/" `u_expr` | + : `m_expr` "%" `u_expr` a_expr: `m_expr` | `a_expr` "+" `m_expr` | `a_expr` "-" `m_expr` .. index:: single: multiplication @@ -909,6 +919,13 @@ the other must be a sequence. In the former case, the numbers are converted to a common type and then multiplied together. In the latter case, sequence repetition is performed; a negative repetition factor yields an empty sequence. +.. index:: single: matrix multiplication + +The ``@`` (at) operator is intended to be used for matrix multiplication. No +builtin Python types implement this operator. + +.. versionadded:: 3.5 + .. index:: exception: ZeroDivisionError single: division @@ -948,9 +965,9 @@ point number using the :func:`abs` function if appropriate. .. index:: single: addition The ``+`` (addition) operator yields the sum of its arguments. The arguments -must either both be numbers or both sequences of the same type. In the former -case, the numbers are converted to a common type and then added together. In -the latter case, the sequences are concatenated. +must either both be numbers or both be sequences of the same type. In the +former case, the numbers are converted to a common type and then added together. +In the latter case, the sequences are concatenated. .. index:: single: subtraction @@ -1019,10 +1036,6 @@ must be integers. .. _comparisons: -.. _is: -.. _is not: -.. _in: -.. _not in: Comparisons =========== @@ -1058,70 +1071,187 @@ Note that ``a op1 b op2 c`` doesn't imply any kind of comparison between *a* and *c*, so that, e.g., ``x < y > z`` is perfectly legal (though perhaps not pretty). +Value comparisons +----------------- + The operators ``<``, ``>``, ``==``, ``>=``, ``<=``, and ``!=`` compare the -values of two objects. The objects need not have the same type. If both are -numbers, they are converted to a common type. Otherwise, the ``==`` and ``!=`` -operators *always* consider objects of different types to be unequal, while the -``<``, ``>``, ``>=`` and ``<=`` operators raise a :exc:`TypeError` when -comparing objects of different types that do not implement these operators for -the given pair of types. You can control comparison behavior of objects of -non-built-in types by defining rich comparison methods like :meth:`__gt__`, -described in section :ref:`customization`. - -Comparison of objects of the same type depends on the type: - -* Numbers are compared arithmetically. - -* The values :const:`float('NaN')` and :const:`Decimal('NaN')` are special. - The are identical to themselves, ``x is x`` but are not equal to themselves, - ``x != x``. Additionally, comparing any value to a not-a-number value +values of two objects. The objects do not need to have the same type. + +Chapter :ref:`objects` states that objects have a value (in addition to type +and identity). The value of an object is a rather abstract notion in Python: +For example, there is no canonical access method for an object's value. Also, +there is no requirement that the value of an object should be constructed in a +particular way, e.g. comprised of all its data attributes. Comparison operators +implement a particular notion of what the value of an object is. One can think +of them as defining the value of an object indirectly, by means of their +comparison implementation. + +Because all types are (direct or indirect) subtypes of :class:`object`, they +inherit the default comparison behavior from :class:`object`. Types can +customize their comparison behavior by implementing +:dfn:`rich comparison methods` like :meth:`__lt__`, described in +:ref:`customization`. + +The default behavior for equality comparison (``==`` and ``!=``) is based on +the identity of the objects. Hence, equality comparison of instances with the +same identity results in equality, and equality comparison of instances with +different identities results in inequality. A motivation for this default +behavior is the desire that all objects should be reflexive (i.e. ``x is y`` +implies ``x == y``). + +A default order comparison (``<``, ``>``, ``<=``, and ``>=``) is not provided; +an attempt raises :exc:`TypeError`. A motivation for this default behavior is +the lack of a similar invariant as for equality. + +The behavior of the default equality comparison, that instances with different +identities are always unequal, may be in contrast to what types will need that +have a sensible definition of object value and value-based equality. Such +types will need to customize their comparison behavior, and in fact, a number +of built-in types have done that. + +The following list describes the comparison behavior of the most important +built-in types. + +* Numbers of built-in numeric types (:ref:`typesnumeric`) and of the standard + library types :class:`fractions.Fraction` and :class:`decimal.Decimal` can be + compared within and across their types, with the restriction that complex + numbers do not support order comparison. Within the limits of the types + involved, they compare mathematically (algorithmically) correct without loss + of precision. + + The not-a-number values :const:`float('NaN')` and :const:`Decimal('NaN')` + are special. They are identical to themselves (``x is x`` is true) but + are not equal to themselves (``x == x`` is false). Additionally, + comparing any number to a not-a-number value will return ``False``. For example, both ``3 < float('NaN')`` and ``float('NaN') < 3`` will return ``False``. -* Bytes objects are compared lexicographically using the numeric values of their - elements. +* Binary sequences (instances of :class:`bytes` or :class:`bytearray`) can be + compared within and across their types. They compare lexicographically using + the numeric values of their elements. + +* Strings (instances of :class:`str`) compare lexicographically using the + numerical Unicode code points (the result of the built-in function + :func:`ord`) of their characters. [#]_ + + Strings and binary sequences cannot be directly compared. + +* Sequences (instances of :class:`tuple`, :class:`list`, or :class:`range`) can + be compared only within each of their types, with the restriction that ranges + do not support order comparison. Equality comparison across these types + results in unequality, and ordering comparison across these types raises + :exc:`TypeError`. + + Sequences compare lexicographically using comparison of corresponding + elements, whereby reflexivity of the elements is enforced. + + In enforcing reflexivity of elements, the comparison of collections assumes + that for a collection element ``x``, ``x == x`` is always true. Based on + that assumption, element identity is compared first, and element comparison + is performed only for distinct elements. This approach yields the same + result as a strict element comparison would, if the compared elements are + reflexive. For non-reflexive elements, the result is different than for + strict element comparison, and may be surprising: The non-reflexive + not-a-number values for example result in the following comparison behavior + when used in a list:: + + >>> nan = float('NaN') + >>> nan is nan + True + >>> nan == nan + False <-- the defined non-reflexive behavior of NaN + >>> [nan] == [nan] + True <-- list enforces reflexivity and tests identity first + + Lexicographical comparison between built-in collections works as follows: + + - For two collections to compare equal, they must be of the same type, have + the same length, and each pair of corresponding elements must compare + equal (for example, ``[1,2] == (1,2)`` is false because the type is not the + same). + + - Collections that support order comparison are ordered the same as their + first unequal elements (for example, ``[1,2,x] <= [1,2,y]`` has the same + value as ``x <= y``). If a corresponding element does not exist, the + shorter collection is ordered first (for example, ``[1,2] < [1,2,3]`` is + true). + +* Mappings (instances of :class:`dict`) compare equal if and only if they have + equal `(key, value)` pairs. Equality comparison of the keys and elements + enforces reflexivity. + + Order comparisons (``<``, ``>``, ``<=``, and ``>=``) raise :exc:`TypeError`. + +* Sets (instances of :class:`set` or :class:`frozenset`) can be compared within + and across their types. + + They define order + comparison operators to mean subset and superset tests. Those relations do + not define total orderings (for example, the two sets ``{1,2}`` and ``{2,3}`` + are not equal, nor subsets of one another, nor supersets of one + another). Accordingly, sets are not appropriate arguments for functions + which depend on total ordering (for example, :func:`min`, :func:`max`, and + :func:`sorted` produce undefined results given a list of sets as inputs). -* Strings are compared lexicographically using the numeric equivalents (the - result of the built-in function :func:`ord`) of their characters. [#]_ String - and bytes object can't be compared! + Comparison of sets enforces reflexivity of its elements. -* Tuples and lists are compared lexicographically using comparison of - corresponding elements. This means that to compare equal, each element must - compare equal and the two sequences must be of the same type and have the same - length. +* Most other built-in types have no comparison methods implemented, so they + inherit the default comparison behavior. - If not equal, the sequences are ordered the same as their first differing - elements. For example, ``[1,2,x] <= [1,2,y]`` has the same value as - ``x <= y``. If the corresponding element does not exist, the shorter - sequence is ordered first (for example, ``[1,2] < [1,2,3]``). +User-defined classes that customize their comparison behavior should follow +some consistency rules, if possible: -* Mappings (dictionaries) compare equal if and only if they have the same - ``(key, value)`` pairs. Order comparisons ``('<', '<=', '>=', '>')`` - raise :exc:`TypeError`. +* Equality comparison should be reflexive. + In other words, identical objects should compare equal: -* Sets and frozensets define comparison operators to mean subset and superset - tests. Those relations do not define total orderings (the two sets ``{1,2}`` - and {2,3} are not equal, nor subsets of one another, nor supersets of one - another). Accordingly, sets are not appropriate arguments for functions - which depend on total ordering. For example, :func:`min`, :func:`max`, and - :func:`sorted` produce undefined results given a list of sets as inputs. + ``x is y`` implies ``x == y`` + +* Comparison should be symmetric. + In other words, the following expressions should have the same result: + + ``x == y`` and ``y == x`` + + ``x != y`` and ``y != x`` + + ``x < y`` and ``y > x`` + + ``x <= y`` and ``y >= x`` + +* Comparison should be transitive. + The following (non-exhaustive) examples illustrate that: -* Most other objects of built-in types compare unequal unless they are the same - object; the choice whether one object is considered smaller or larger than - another one is made arbitrarily but consistently within one execution of a - program. + ``x > y and y > z`` implies ``x > z`` -Comparison of objects of the differing types depends on whether either of the -types provide explicit support for the comparison. Most numeric types can be -compared with one another. When cross-type comparison is not supported, the -comparison method returns ``NotImplemented``. + ``x < y and y <= z`` implies ``x < z`` +* Inverse comparison should result in the boolean negation. + In other words, the following expressions should have the same result: + + ``x == y`` and ``not x != y`` + + ``x < y`` and ``not x >= y`` (for total ordering) + + ``x > y`` and ``not x <= y`` (for total ordering) + + The last two expressions apply to totally ordered collections (e.g. to + sequences, but not to sets or mappings). See also the + :func:`~functools.total_ordering` decorator. + +Python does not enforce these consistency rules. In fact, the not-a-number +values are an example for not following these rules. + + +.. _in: +.. _not in: .. _membership-test-details: +Membership test operations +-------------------------- + The operators :keyword:`in` and :keyword:`not in` test for membership. ``x in s`` evaluates to true if *x* is a member of *s*, and false otherwise. ``x not in s`` returns the negation of ``x in s``. All built-in sequences and set types -support this as well as dictionary, for which :keyword:`in` tests whether a the +support this as well as dictionary, for which :keyword:`in` tests whether the dictionary has a given key. For container types such as list, tuple, set, frozenset, dict, or collections.deque, the expression ``x in y`` is equivalent to ``any(x is e or x == e for e in y)``. @@ -1159,6 +1289,13 @@ The operator :keyword:`not in` is defined to have the inverse true value of operator: is not pair: identity; test + +.. _is: +.. _is not: + +Identity comparisons +-------------------- + The operators :keyword:`is` and :keyword:`is not` test for object identity: ``x is y`` is true if and only if *x* and *y* are the same object. ``x is not y`` yields the inverse truth value. [#]_ @@ -1207,9 +1344,9 @@ returned; otherwise, *y* is evaluated and the resulting value is returned. they return to ``False`` and ``True``, but rather return the last evaluated argument. This is sometimes useful, e.g., if ``s`` is a string that should be replaced by a default value if it is empty, the expression ``s or 'foo'`` yields -the desired value. Because :keyword:`not` has to invent a value anyway, it does -not bother to return a value of the same type as its argument, so e.g., ``not -'foo'`` yields ``False``, not ``''``.) +the desired value. Because :keyword:`not` has to create a new value, it +returns a boolean value regardless of the type of its argument +(for example, ``not 'foo'`` produces ``False`` rather than ``''``.) Conditional expressions @@ -1227,8 +1364,8 @@ Conditional expressions Conditional expressions (sometimes called a "ternary operator") have the lowest priority of all Python operations. -The expression ``x if C else y`` first evaluates the condition, *C* (*not* *x*); -if *C* is true, *x* is evaluated and its value is returned; otherwise, *y* is +The expression ``x if C else y`` first evaluates the condition, *C* rather than *x*. +If *C* is true, *x* is evaluated and its value is returned; otherwise, *y* is evaluated and its value is returned. See :pep:`308` for more details about conditional expressions. @@ -1249,10 +1386,9 @@ Lambdas lambda_expr: "lambda" [`parameter_list`]: `expression` lambda_expr_nocond: "lambda" [`parameter_list`]: `expression_nocond` -Lambda expressions (sometimes called lambda forms) have the same syntactic position as -expressions. They are a shorthand to create anonymous functions; the expression -``lambda arguments: expression`` yields a function object. The unnamed object -behaves like a function object defined with :: +Lambda expressions (sometimes called lambda forms) are used to create anonymous +functions. The expression ``lambda arguments: expression`` yields a function +object. The unnamed object behaves like a function object defined with :: def <lambda>(arguments): return expression @@ -1315,13 +1451,15 @@ Operator precedence .. index:: pair: operator; precedence -The following table summarizes the operator precedences in Python, from lowest +The following table summarizes the operator precedence in Python, from lowest precedence (least binding) to highest precedence (most binding). Operators in the same box have the same precedence. Unless the syntax is explicitly given, operators are binary. Operators in the same box group left to right (except for -comparisons, including tests, which all have the same precedence and chain from -left to right --- see section :ref:`comparisons` --- and exponentiation, which -groups from right to left). +exponentiation, which groups from right to left). + +Note that comparisons, membership tests, and identity tests, all have the same +precedence and have a left-to-right chaining feature as described in the +:ref:`comparisons` section. +-----------------------------------------------+-------------------------------------+ @@ -1351,13 +1489,16 @@ groups from right to left). +-----------------------------------------------+-------------------------------------+ | ``+``, ``-`` | Addition and subtraction | +-----------------------------------------------+-------------------------------------+ -| ``*``, ``/``, ``//``, ``%`` | Multiplication, division, remainder | -| | [#]_ | +| ``*``, ``@``, ``/``, ``//``, ``%`` | Multiplication, matrix | +| | multiplication division, | +| | remainder [#]_ | +-----------------------------------------------+-------------------------------------+ | ``+x``, ``-x``, ``~x`` | Positive, negative, bitwise NOT | +-----------------------------------------------+-------------------------------------+ | ``**`` | Exponentiation [#]_ | +-----------------------------------------------+-------------------------------------+ +| ``await`` ``x`` | Await expression | ++-----------------------------------------------+-------------------------------------+ | ``x[index]``, ``x[index:index]``, | Subscription, slicing, | | ``x(arguments...)``, ``x.attribute`` | call, attribute reference | +-----------------------------------------------+-------------------------------------+ @@ -1384,12 +1525,24 @@ groups from right to left). cases, Python returns the latter result, in order to preserve that ``divmod(x,y)[0] * y + x % y`` be very close to ``x``. -.. [#] While comparisons between strings make sense at the byte level, they may - be counter-intuitive to users. For example, the strings ``"\u00C7"`` and - ``"\u0327\u0043"`` compare differently, even though they both represent the - same unicode character (LATIN CAPITAL LETTER C WITH CEDILLA). To compare - strings in a human recognizable way, compare using - :func:`unicodedata.normalize`. +.. [#] The Unicode standard distinguishes between :dfn:`code points` + (e.g. U+0041) and :dfn:`abstract characters` (e.g. "LATIN CAPITAL LETTER A"). + While most abstract characters in Unicode are only represented using one + code point, there is a number of abstract characters that can in addition be + represented using a sequence of more than one code point. For example, the + abstract character "LATIN CAPITAL LETTER C WITH CEDILLA" can be represented + as a single :dfn:`precomposed character` at code position U+00C7, or as a + sequence of a :dfn:`base character` at code position U+0043 (LATIN CAPITAL + LETTER C), followed by a :dfn:`combining character` at code position U+0327 + (COMBINING CEDILLA). + + The comparison operators on strings compare at the level of Unicode code + points. This may be counter-intuitive to humans. For example, + ``"\u00C7" == "\u0043\u0327"`` is ``False``, even though both strings + represent the same abstract character "LATIN CAPITAL LETTER C WITH CEDILLA". + + To compare strings at the level of abstract characters (that is, in a way + intuitive to humans), use :func:`unicodedata.normalize`. .. [#] Due to automatic garbage-collection, free lists, and the dynamic nature of descriptors, you may notice seemingly unusual behaviour in certain uses of diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index be79b99ffc13..d549b2674e85 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -200,7 +200,7 @@ of the module to result in an :exc:`ImportError`. Beware though, as if you keep a reference to the module object, invalidate its cache entry in :data:`sys.modules`, and then re-import the named module, the two module objects will *not* be the same. By contrast, -:func:`imp.reload` will reuse the *same* module object, and simply +:func:`importlib.reload` will reuse the *same* module object, and simply reinitialise the module contents by rerunning the module's code. @@ -281,9 +281,10 @@ When the named module is not found in :data:`sys.modules`, Python next searches :data:`sys.meta_path`, which contains a list of meta path finder objects. These finders are queried in order to see if they know how to handle the named module. Meta path finders must implement a method called -:meth:`find_spec()` which takes two arguments, a name and an import path. -The meta path finder can use any strategy it wants to determine whether it can -handle the named module or not. +:meth:`~importlib.abc.MetaPathFinder.find_spec()` which takes three arguments: +a name, an import path, and (optionally) a target module. The meta path +finder can use any strategy it wants to determine whether it can handle +the named module or not. If the meta path finder knows how to handle the named module, it returns a spec object. If it cannot handle the named module, it returns ``None``. If @@ -291,24 +292,26 @@ spec object. If it cannot handle the named module, it returns ``None``. If a spec, then an :exc:`ImportError` is raised. Any other exceptions raised are simply propagated up, aborting the import process. -The :meth:`find_spec()` method of meta path finders is called with two -arguments. The first is the fully qualified name of the module being -imported, for example ``foo.bar.baz``. The second argument is the path -entries to use for the module search. For top-level modules, the second -argument is ``None``, but for submodules or subpackages, the second -argument is the value of the parent package's ``__path__`` attribute. If -the appropriate ``__path__`` attribute cannot be accessed, an -:exc:`ImportError` is raised. +The :meth:`~importlib.abc.MetaPathFinder.find_spec()` method of meta path +finders is called with two or three arguments. The first is the fully +qualified name of the module being imported, for example ``foo.bar.baz``. +The second argument is the path entries to use for the module search. For +top-level modules, the second argument is ``None``, but for submodules or +subpackages, the second argument is the value of the parent package's +``__path__`` attribute. If the appropriate ``__path__`` attribute cannot +be accessed, an :exc:`ImportError` is raised. The third argument is an +existing module object that will be the target of loading later. The +import system passes in a target module only during reload. The meta path may be traversed multiple times for a single import request. For example, assuming none of the modules involved has already been cached, importing ``foo.bar.baz`` will first perform a top level import, calling -``mpf.find_spec("foo", None)`` on each meta path finder (``mpf``). After +``mpf.find_spec("foo", None, None)`` on each meta path finder (``mpf``). After ``foo`` has been imported, ``foo.bar`` will be imported by traversing the meta path a second time, calling -``mpf.find_spec("foo.bar", foo.__path__)``. Once ``foo.bar`` has been +``mpf.find_spec("foo.bar", foo.__path__, None)``. Once ``foo.bar`` has been imported, the final traversal will call -``mpf.find_spec("foo.bar.baz", foo.bar.__path__)``. +``mpf.find_spec("foo.bar.baz", foo.bar.__path__, None)``. Some meta path finders only support top level imports. These importers will always return ``None`` when anything other than ``None`` is passed as the @@ -320,10 +323,11 @@ modules, and one that knows how to import modules from an :term:`import path` (i.e. the :term:`path based finder`). .. versionchanged:: 3.4 - The find_spec() method of meta path finders replaced :meth:`find_module()`. - which is now deprecated. While it will continue to work without change, - the import machinery will try it only if the finder does not implement - find_spec(). + The :meth:`~importlib.abc.MetaPathFinder.find_spec` method of meta path + finders replaced :meth:`~importlib.abc.MetaPathFinder.find_module`, which + is now deprecated. While it will continue to work without change, the + import machinery will try it only if the finder does not implement + ``find_spec()``. Loading @@ -335,6 +339,7 @@ of what happens during the loading portion of import:: module = None if spec.loader is not None and hasattr(spec.loader, 'create_module'): + # It is assumed 'exec_module' will also be defined on the loader. module = spec.loader.create_module(spec) if module is None: module = ModuleType(spec.name) @@ -350,6 +355,7 @@ of what happens during the loading portion of import:: raise ImportError elif not hasattr(spec.loader, 'exec_module'): module = spec.loader.load_module(spec.name) + # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: @@ -360,7 +366,7 @@ of what happens during the loading portion of import:: except KeyError: pass raise - module_to_return = sys.modules[spec.name] + return sys.modules[spec.name] Note the following details: @@ -380,8 +386,9 @@ Note the following details: reloading where even the failing module is left in :data:`sys.modules`. * After the module is created but before execution, the import machinery - sets the import-related module attributes ("init_module_attrs"), as - summarized in a :ref:`later section <import-mod-attrs>`. + sets the import-related module attributes ("_init_module_attrs" in + the pseudo-code example above), as summarized in a + :ref:`later section <import-mod-attrs>`. * Module execution is the key moment of loading in which the module's namespace gets populated. Execution is entirely delegated to the @@ -392,16 +399,16 @@ Note the following details: .. versionchanged:: 3.4 The import system has taken over the boilerplate responsibilities of - loaders. These were previously performed by the :meth:`load_module()` - method. + loaders. These were previously performed by the + :meth:`importlib.abc.Loader.load_module` method. Loaders ------- Module loaders provide the critical function of loading: module execution. -The import machinery calls the :meth:`~importlib.abc.Loader.exec_module()` +The import machinery calls the :meth:`importlib.abc.Loader.exec_module` method with a single argument, the module object to execute. Any value -returned from exec_module() is ignored. +returned from :meth:`~importlib.abc.Loader.exec_module` is ignored. Loaders must satisfy the following requirements: @@ -409,41 +416,41 @@ Loaders must satisfy the following requirements: dynamically loaded extension), the loader should execute the module's code in the module's global name space (``module.__dict__``). - * If loader cannot execute the module, it should raise an + * If the loader cannot execute the module, it should raise an :exc:`ImportError`, although any other exception raised during - :meth:`exec_module()` will be propagated. + :meth:`~importlib.abc.Loader.exec_module` will be propagated. In many cases, the finder and loader can be the same object; in such cases the -:meth:`finder.find_spec()` would just return a spec with the loader set -to ``self``. +:meth:`~importlib.abc.MetaPathFinder.find_spec` method would just return a +spec with the loader set to ``self``. Module loaders may opt in to creating the module object during loading -by implementing a :meth:`create_module()` method. It takes one argument, -the module spec, and returns the new module object to use during loading. -create_module() does not need to set any attributes on the module object. -If the loader does not define create_module(), the import machinery will -create the new module itself. +by implementing a :meth:`~importlib.abc.Loader.create_module` method. +It takes one argument, the module spec, and returns the new module object +to use during loading. ``create_module()`` does not need to set any attributes +on the module object. If the method returns ``None``, the +import machinery will create the new module itself. .. versionadded:: 3.4 The create_module() method of loaders. .. versionchanged:: 3.4 - The load_module() method was replaced by exec_module() and the import + The :meth:`~importlib.abc.Loader.load_module` method was replaced by + :meth:`~importlib.abc.Loader.exec_module` and the import machinery assumed all the boilerplate responsibilities of loading. For compatibility with existing loaders, the import machinery will use - the :meth:`~importlib.abc.Loader.load_module()` method of loaders if it - exists and the loader does not also implement exec_module(). However, - load_module() has been deprecated and loaders should implement - exec_module() instead. + the ``load_module()`` method of loaders if it exists and the loader does + not also implement ``exec_module()``. However, ``load_module()`` has been + deprecated and loaders should implement ``exec_module()`` instead. - The load_module() method must implement all the boilerplate loading + The ``load_module()`` method must implement all the boilerplate loading functionality described above in addition to executing the module. All the same constraints apply, with some additional clarification: * If there is an existing module object with the given name in :data:`sys.modules`, the loader must use that existing module. - (Otherwise, :func:`imp.reload` will not work correctly.) If the + (Otherwise, :func:`importlib.reload` will not work correctly.) If the named module does not exist in :data:`sys.modules`, the loader must create a new module object and add it to :data:`sys.modules`. @@ -453,7 +460,48 @@ create the new module itself. * If loading fails, the loader must remove any modules it has inserted into :data:`sys.modules`, but it must remove **only** the failing - module, and only if the loader itself has loaded it explicitly. + module(s), and only if the loader itself has loaded the module(s) + explicitly. + +.. versionchanged:: 3.5 + A :exc:`DeprecationWarning` is raised when ``exec_module()`` is defined but + ``create_module()`` is not. Starting in Python 3.6 it will be an error to not + define ``create_module()`` on a loader attached to a ModuleSpec. + +Submodules +---------- + +When a submodule is loaded using any mechanism (e.g. ``importlib`` APIs, the +``import`` or ``import-from`` statements, or built-in ``__import__()``) a +binding is placed in the parent module's namespace to the submodule object. +For example, if package ``spam`` has a submodule ``foo``, after importing +``spam.foo``, ``spam`` will have an attribute ``foo`` which is bound to the +submodule. Let's say you have the following directory structure:: + + spam/ + __init__.py + foo.py + bar.py + +and ``spam/__init__.py`` has the following lines in it:: + + from .foo import Foo + from .bar import Bar + +then executing the following puts a name binding to ``foo`` and ``bar`` in the +``spam`` module:: + + >>> import spam + >>> spam.foo + <module 'spam.foo' from '/tmp/imports/spam/foo.py'> + >>> spam.bar + <module 'spam.bar' from '/tmp/imports/spam/bar.py'> + +Given Python's familiar name binding rules this might seem surprising, but +it's actually a fundamental feature of the import system. The invariant +holding is that if you have ``sys.modules['spam']`` and +``sys.modules['spam.foo']`` (as you would after the above import), the latter +must appear as the ``foo`` attribute of the former. Module spec ----------- @@ -513,7 +561,12 @@ the module. The ``__spec__`` attribute must be set to the module spec that was used when importing the module. This is used primarily for - introspection and during reloading. + introspection and during reloading. Setting ``__spec__`` + appropriately applies equally to :ref:`modules initialized during + interpreter startup <programs>`. The one exception is ``__main__``, + where ``__spec__`` is :ref:`set to None in some cases <main_spec>`. + + .. versionadded:: 3.4 .. attribute:: __path__ @@ -600,13 +653,14 @@ Here are the exact rules used: * Otherwise, just use the module's ``__name__`` in the repr. .. versionchanged:: 3.4 - Use of loader.module_repr() has been deprecated and the module spec - is now used by the import machinery to generate a module repr. + Use of :meth:`loader.module_repr() <importlib.abc.Loader.module_repr>` + has been deprecated and the module spec is now used by the import + machinery to generate a module repr. For backward compatibility with Python 3.3, the module repr will be - generated by calling the loader's :meth:`module_repr()` method, if - defined, before trying either approach described above. However, the - method is deprecated. + generated by calling the loader's + :meth:`~importlib.abc.Loader.module_repr` method, if defined, before + trying either approach described above. However, the method is deprecated. The Path Based Finder @@ -616,8 +670,9 @@ The Path Based Finder single: path based finder As mentioned previously, Python comes with several default meta path finders. -One of these, called the :term:`path based finder`, searches an :term:`import -path`, which contains a list of :term:`path entries <path entry>`. Each path +One of these, called the :term:`path based finder` +(:class:`~importlib.machinery.PathFinder`), searches an :term:`import path`, +which contains a list of :term:`path entries <path entry>`. Each path entry names a location to search for modules. The path based finder itself doesn't know how to import anything. Instead, it @@ -626,7 +681,7 @@ path entry finder that knows how to handle that particular kind of path. The default set of path entry finders implement all the semantics for finding modules on the file system, handling special file types such as Python source -code (``.py`` files), Python byte code (``.pyc`` and ``.pyo`` files) and +code (``.py`` files), Python byte code (``.pyc`` files) and shared libraries (e.g. ``.so`` files). When supported by the :mod:`zipimport` module in the standard library, the default path entry finders also handle loading all of these file types (other than shared libraries) from zipfiles. @@ -666,15 +721,15 @@ Path entry finders single: sys.path_importer_cache single: PYTHONPATH -The :term:`path based finder` is responsible for finding and loading Python -modules and packages whose location is specified with a string :term:`path -entry`. Most path entries name locations in the file system, but they need -not be limited to this. +The :term:`path based finder` is responsible for finding and loading +Python modules and packages whose location is specified with a string +:term:`path entry`. Most path entries name locations in the file system, +but they need not be limited to this. As a meta path finder, the :term:`path based finder` implements the -:meth:`find_spec()` protocol previously described, however it exposes -additional hooks that can be used to customize how modules are found and -loaded from the :term:`import path`. +:meth:`~importlib.abc.MetaPathFinder.find_spec` protocol previously +described, however it exposes additional hooks that can be used to +customize how modules are found and loaded from the :term:`import path`. Three variables are used by the :term:`path based finder`, :data:`sys.path`, :data:`sys.path_hooks` and :data:`sys.path_importer_cache`. The ``__path__`` @@ -694,14 +749,16 @@ finder>`. The :term:`path based finder` is a :term:`meta path finder`, so the import machinery begins the :term:`import path` search by calling the path -based finder's :meth:`find_spec()` method as described previously. When -the ``path`` argument to :meth:`find_spec()` is given, it will be a +based finder's :meth:`~importlib.machinery.PathFinder.find_spec` method as +described previously. When the ``path`` argument to +:meth:`~importlib.machinery.PathFinder.find_spec` is given, it will be a list of string paths to traverse - typically a package's ``__path__`` -attribute for an import within that package. If the ``path`` argument -is ``None``, this indicates a top level import and :data:`sys.path` is used. +attribute for an import within that package. If the ``path`` argument is +``None``, this indicates a top level import and :data:`sys.path` is used. The path based finder iterates over every entry in the search path, and -for each of these, looks for an appropriate :term:`path entry finder` for the +for each of these, looks for an appropriate :term:`path entry finder` +(:class:`~importlib.abc.PathEntryFinder`) for the path entry. Because this can be an expensive operation (e.g. there may be `stat()` call overheads for this search), the path based finder maintains a cache mapping path entries to path entry finders. This cache is maintained @@ -718,35 +775,46 @@ hooks <path entry hook>` in this list is called with a single argument, the path entry to be searched. This callable may either return a :term:`path entry finder` that can handle the path entry, or it may raise :exc:`ImportError`. An :exc:`ImportError` is used by the path based finder to -signal that the hook cannot find a :term:`path entry finder` for that -:term:`path entry`. The exception is ignored and :term:`import path` -iteration continues. The hook should expect either a string or bytes object; -the encoding of bytes objects is up to the hook (e.g. it may be a file system -encoding, UTF-8, or something else), and if the hook cannot decode the -argument, it should raise :exc:`ImportError`. +signal that the hook cannot find a :term:`path entry finder`. +for that :term:`path entry`. The +exception is ignored and :term:`import path` iteration continues. The hook +should expect either a string or bytes object; the encoding of bytes objects +is up to the hook (e.g. it may be a file system encoding, UTF-8, or something +else), and if the hook cannot decode the argument, it should raise +:exc:`ImportError`. If :data:`sys.path_hooks` iteration ends with no :term:`path entry finder` -being returned, then the path based finder's :meth:`find_spec()` method -will store ``None`` in :data:`sys.path_importer_cache` (to indicate that -there is no finder for this path entry) and return ``None``, indicating that -this :term:`meta path finder` could not find the module. +being returned, then the path based finder's +:meth:`~importlib.machinery.PathFinder.find_spec` method will store ``None`` +in :data:`sys.path_importer_cache` (to indicate that there is no finder for +this path entry) and return ``None``, indicating that this +:term:`meta path finder` could not find the module. If a :term:`path entry finder` *is* returned by one of the :term:`path entry hook` callables on :data:`sys.path_hooks`, then the following protocol is used to ask the finder for a module spec, which is then used when loading the module. +The current working directory -- denoted by an empty string -- is handled +slightly differently from other entries on :data:`sys.path`. First, if the +current working directory is found to not exist, no value is stored in +:data:`sys.path_importer_cache`. Second, the value for the current working +directory is looked up fresh for each module lookup. Third, the path used for +:data:`sys.path_importer_cache` and returned by +:meth:`importlib.machinery.PathFinder.find_spec` will be the actual current +working directory and not the empty string. + Path entry finder protocol -------------------------- In order to support imports of modules and initialized packages and also to contribute portions to namespace packages, path entry finders must implement -the :meth:`find_spec()` method. +the :meth:`~importlib.abc.PathEntryFinder.find_spec` method. -:meth:`find_spec()` takes one argument, the fully qualified name of the -module being imported. :meth:`find_spec()` returns a fully populated -spec for the module. This spec will always have "loader" set (with one -exception). +:meth:`~importlib.abc.PathEntryFinder.find_spec` takes two argument, the +fully qualified name of the module being imported, and the (optional) target +module. ``find_spec()`` returns a fully populated spec for the module. +This spec will always have "loader" set (with one exception). To indicate to the import machinery that the spec represents a namespace :term:`portion`. the path entry finder sets "loader" on the spec to @@ -754,42 +822,44 @@ To indicate to the import machinery that the spec represents a namespace portion. .. versionchanged:: 3.4 - find_spec() replaced find_loader() and find_module(), but of which - are now deprecated, but will be used if find_spec() is not defined. + :meth:`~importlib.abc.PathEntryFinder.find_spec` replaced + :meth:`~importlib.abc.PathEntryFinder.find_loader` and + :meth:`~importlib.abc.PathEntryFinder.find_module`, both of which + are now deprecated, but will be used if ``find_spec()`` is not defined. Older path entry finders may implement one of these two deprecated methods - instead of :meth:`find_spec()`. The methods are still respected for the - sake of backward compatibility. Howevever, if find_spec() is implemented - on the path entry finder, the legacy methods are ignored. - - :meth:`find_loader()` takes one argument, the fully qualified name of the - module being imported. :meth:`find_loader()` returns a 2-tuple where the - first item is the loader and the second item is a namespace :term:`portion`. - When the first item (i.e. the loader) is ``None``, this means that while the - path entry finder does not have a loader for the named module, it knows that - the path entry contributes to a namespace portion for the named module. - This will almost always be the case where Python is asked to import a - namespace package that has no physical presence on the file system. - When a path entry finder returns ``None`` for the loader, the second - item of the 2-tuple return value must be a sequence, although it can be - empty. - - If :meth:`find_loader()` returns a non-``None`` loader value, the portion is + instead of ``find_spec()``. The methods are still respected for the + sake of backward compatibility. Howevever, if ``find_spec()`` is + implemented on the path entry finder, the legacy methods are ignored. + + :meth:`~importlib.abc.PathEntryFinder.find_loader` takes one argument, the + fully qualified name of the module being imported. ``find_loader()`` + returns a 2-tuple where the first item is the loader and the second item + is a namespace :term:`portion`. When the first item (i.e. the loader) is + ``None``, this means that while the path entry finder does not have a + loader for the named module, it knows that the path entry contributes to + a namespace portion for the named module. This will almost always be the + case where Python is asked to import a namespace package that has no + physical presence on the file system. When a path entry finder returns + ``None`` for the loader, the second item of the 2-tuple return value must + be a sequence, although it can be empty. + + If ``find_loader()`` returns a non-``None`` loader value, the portion is ignored and the loader is returned from the path based finder, terminating the search through the path entries. For backwards compatibility with other implementations of the import protocol, many path entry finders also support the same, - traditional :meth:`find_module()` method that meta path finders support. - However path entry finder :meth:`find_module()` methods are never called + traditional ``find_module()`` method that meta path finders support. + However path entry finder ``find_module()`` methods are never called with a ``path`` argument (they are expected to record the appropriate path information from the initial call to the path hook). - The :meth:`find_module()` method on path entry finders is deprecated, + The ``find_module()`` method on path entry finders is deprecated, as it does not allow the path entry finder to contribute portions to - namespace packages. If both :meth:`find_loader()` and :meth:`find_module()` + namespace packages. If both ``find_loader()`` and ``find_module()`` exist on a path entry finder, the import system will always call - :meth:`find_loader()` in preference to :meth:`find_module()`. + ``find_loader()`` in preference to ``find_module()``. Replacing the standard import system @@ -808,9 +878,54 @@ import statements within that module. To selectively prevent import of some modules from a hook early on the meta path (rather than disabling the standard import system entirely), it is sufficient to raise :exc:`ImportError` directly from -:meth:`find_spec` instead of returning ``None``. The latter indicates -that the meta path search should continue. while raising an exception -terminates it immediately. +:meth:`~importlib.abc.MetaPathFinder.find_spec` instead of returning +``None``. The latter indicates that the meta path search should continue, +while raising an exception terminates it immediately. + + +Special considerations for __main__ +=================================== + +The :mod:`__main__` module is a special case relative to Python's import +system. As noted :ref:`elsewhere <programs>`, the ``__main__`` module +is directly initialized at interpreter startup, much like :mod:`sys` and +:mod:`builtins`. However, unlike those two, it doesn't strictly +qualify as a built-in module. This is because the manner in which +``__main__`` is initialized depends on the flags and other options with +which the interpreter is invoked. + +.. _main_spec: + +__main__.__spec__ +----------------- + +Depending on how :mod:`__main__` is initialized, ``__main__.__spec__`` +gets set appropriately or to ``None``. + +When Python is started with the :option:`-m` option, ``__spec__`` is set +to the module spec of the corresponding module or package. ``__spec__`` is +also populated when the ``__main__`` module is loaded as part of executing a +directory, zipfile or other :data:`sys.path` entry. + +In :ref:`the remaining cases <using-on-interface-options>` +``__main__.__spec__`` is set to ``None``, as the code used to populate the +:mod:`__main__` does not correspond directly with an importable module: + +- interactive prompt +- -c switch +- running from stdin +- running directly from a source or bytecode file + +Note that ``__main__.__spec__`` is always ``None`` in the last case, +*even if* the file could technically be imported directly as a module +instead. Use the :option:`-m` switch if valid module metadata is desired +in :mod:`__main__`. + +Note also that even when ``__main__`` corresponds with an importable module +and ``__main__.__spec__`` is set accordingly, they're still considered +*distinct* modules. This is due to the fact that blocks guarded by +``if __name__ == "__main__":`` checks only execute when the module is used +to populate the ``__main__`` namespace, and not during normal import. Open issues @@ -825,13 +940,19 @@ related entries in the data model reference page? XXX runpy, pkgutil, et al in the library manual should all get "See Also" links at the top pointing to the new import system section. +XXX Add more explanation regarding the different ways in which +``__main__`` is initialized? + +XXX Add more info on ``__main__`` quirks/pitfalls (i.e. copy from +:pep:`395`). + References ========== The import machinery has evolved considerably since Python's early days. The original `specification for packages -<http://www.python.org/doc/essays/packages.html>`_ is still available to read, +<http://legacy.python.org/doc/essays/packages.html>`_ is still available to read, although some details have changed since the writing of that document. The original specification for :data:`sys.meta_path` was :pep:`302`, with diff --git a/Doc/reference/introduction.rst b/Doc/reference/introduction.rst index 0ac57945db18..5633ae3eb1cf 100644 --- a/Doc/reference/introduction.rst +++ b/Doc/reference/introduction.rst @@ -66,7 +66,7 @@ IronPython An alternate Python for .NET. Unlike Python.NET, this is a complete Python implementation that generates IL, and compiles Python code directly to .NET assemblies. It was created by Jim Hugunin, the original creator of Jython. For - more information, see `the IronPython website <http://www.ironpython.net/>`_. + more information, see `the IronPython website <http://ironpython.net/>`_. PyPy An implementation of Python written completely in Python. It supports several diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index 0ed3d3b9a700..8ad975f71f02 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -76,12 +76,14 @@ are ignored by the syntax; they are not tokens. Encoding declarations --------------------- -.. index:: source character set, encodings +.. index:: source character set, encoding declarations (source file) If a comment in the first or second line of the Python script matches the regular expression ``coding[=:]\s*([-\w.]+)``, this comment is processed as an encoding declaration; the first group of this expression names the encoding of -the source code file. The recommended forms of this expression are :: +the source code file. The encoding declaration must appear on a line of its +own. If it is the second line, the first line must also be a comment-only line. +The recommended forms of an encoding expression are :: # -*- coding: <encoding-name> -*- @@ -98,7 +100,7 @@ among others, by Microsoft's :program:`notepad`). If an encoding is declared, the encoding name must be recognized by Python. The encoding is used for all lexical analysis, including string literals, comments -and identifiers. The encoding declaration must appear on a line of its own. +and identifiers. .. XXX there should be a list of supported encodings. @@ -310,7 +312,9 @@ The Unicode category codes mentioned above stand for: * *Mc* - spacing combining marks * *Nd* - decimal numbers * *Pc* - connector punctuations -* *Other_ID_Start* - explicit list of characters in `PropList.txt <http://unicode.org/Public/UNIDATA/PropList.txt>`_ to support backwards compatibility +* *Other_ID_Start* - explicit list of characters in `PropList.txt + <http://www.unicode.org/Public/8.0.0/ucd/PropList.txt>`_ to support backwards + compatibility * *Other_ID_Continue* - likewise All identifiers are converted into the normal form NFKC while parsing; comparison @@ -441,7 +445,7 @@ instance of the :class:`bytes` type instead of the :class:`str` type. They may only contain ASCII characters; bytes with a numeric value of 128 or greater must be expressed with escapes. -As of Python 3.3 it is possible again to prefix unicode strings with a +As of Python 3.3 it is possible again to prefix string literals with a ``u`` prefix to simplify maintenance of dual 2.x and 3.x codebases. Both string and bytes literals may optionally be prefixed with a letter ``'r'`` @@ -451,24 +455,24 @@ escapes in raw strings are not treated specially. Given that Python 2.x's raw unicode literals behave differently than Python 3.x's the ``'ur'`` syntax is not supported. - .. versionadded:: 3.3 - The ``'rb'`` prefix of raw bytes literals has been added as a synonym - of ``'br'``. +.. versionadded:: 3.3 + The ``'rb'`` prefix of raw bytes literals has been added as a synonym + of ``'br'``. - .. versionadded:: 3.3 - Support for the unicode legacy literal (``u'value'``) was reintroduced - to simplify the maintenance of dual Python 2.x and 3.x codebases. - See :pep:`414` for more information. +.. versionadded:: 3.3 + Support for the unicode legacy literal (``u'value'``) was reintroduced + to simplify the maintenance of dual Python 2.x and 3.x codebases. + See :pep:`414` for more information. -In triple-quoted strings, unescaped newlines and quotes are allowed (and are -retained), except that three unescaped quotes in a row terminate the string. (A -"quote" is the character used to open the string, i.e. either ``'`` or ``"``.) +In triple-quoted literals, unescaped newlines and quotes are allowed (and are +retained), except that three unescaped quotes in a row terminate the literal. (A +"quote" is the character used to open the literal, i.e. either ``'`` or ``"``.) .. index:: physical line, escape sequence, Standard C, C -Unless an ``'r'`` or ``'R'`` prefix is present, escape sequences in strings are -interpreted according to rules similar to those used by Standard C. The -recognized escape sequences are: +Unless an ``'r'`` or ``'R'`` prefix is present, escape sequences in string and +bytes literals are interpreted according to rules similar to those used by +Standard C. The recognized escape sequences are: +-----------------+---------------------------------+-------+ | Escape Sequence | Meaning | Notes | @@ -545,20 +549,20 @@ Notes: .. index:: unrecognized escape sequence Unlike Standard C, all unrecognized escape sequences are left in the string -unchanged, i.e., *the backslash is left in the string*. (This behavior is +unchanged, i.e., *the backslash is left in the result*. (This behavior is useful when debugging: if an escape sequence is mistyped, the resulting output is more easily recognized as broken.) It is also important to note that the escape sequences only recognized in string literals fall into the category of unrecognized escapes for bytes literals. -Even in a raw string, string quotes can be escaped with a backslash, but the -backslash remains in the string; for example, ``r"\""`` is a valid string +Even in a raw literal, quotes can be escaped with a backslash, but the +backslash remains in the result; for example, ``r"\""`` is a valid string literal consisting of two characters: a backslash and a double quote; ``r"\"`` is not a valid string literal (even a raw string cannot end in an odd number of -backslashes). Specifically, *a raw string cannot end in a single backslash* +backslashes). Specifically, *a raw literal cannot end in a single backslash* (since the backslash would escape the following quote character). Note also that a single backslash followed by a newline is interpreted as those two -characters as part of the string, *not* as a line continuation. +characters as part of the literal, *not* as a line continuation. .. _string-catenation: @@ -630,8 +634,7 @@ for disambiguation with C-style octal literals, which Python used before version Some examples of integer literals:: 7 2147483647 0o177 0b100110111 - 3 79228162514264337593543950336 0o377 0x100000000 - 79228162514264337593543950336 0xdeadbeef + 3 79228162514264337593543950336 0o377 0xdeadbeef .. _floating: @@ -689,7 +692,7 @@ Operators The following tokens are operators:: - + - * ** / // % + + - * ** / // % @ << >> & | ^ ~ < > <= >= == != @@ -705,7 +708,7 @@ The following tokens serve as delimiters in the grammar:: ( ) [ ] { } , : . ; @ = -> - += -= *= /= //= %= + += -= *= /= //= %= @= &= |= ^= >>= <<= **= The period can also occur in floating-point and imaginary literals. A sequence @@ -726,4 +729,4 @@ occurrence outside string literals and comments is an unconditional error:: .. rubric:: Footnotes -.. [#] http://www.unicode.org/Public/6.1.0/ucd/NameAliases.txt +.. [#] http://www.unicode.org/Public/8.0.0/ucd/NameAliases.txt diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index b9ebaaa554c7..5f605408b7dd 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -7,7 +7,7 @@ Simple statements .. index:: pair: simple; statement -Simple statements are comprised within a single logical line. Several simple +A simple statement is comprised within a single logical line. Several simple statements may occur on a single line separated by semicolons. The syntax for simple statements is: @@ -70,6 +70,7 @@ Assignment statements ===================== .. index:: + single: =; assignment statement pair: assignment; statement pair: binding; name pair: rebinding; name @@ -90,8 +91,8 @@ attributes or items of mutable objects: : | `slicing` : | "*" `target` -(See section :ref:`primaries` for the syntax definitions for the last three -symbols.) +(See section :ref:`primaries` for the syntax definitions for *attributeref*, +*subscription*, and *slicing*.) An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and @@ -227,7 +228,7 @@ Assignment of an object to a single target is recursively defined as follows. inclusive. Finally, the sequence object is asked to replace the slice with the items of the assigned sequence. The length of the slice may be different from the length of the assigned sequence, thus changing the length of the - target sequence, if the object allows it. + target sequence, if the target sequence allows it. .. impl-detail:: @@ -235,14 +236,15 @@ Assignment of an object to a single target is recursively defined as follows. as for expressions, and invalid syntax is rejected during the code generation phase, causing less detailed error messages. -WARNING: Although the definition of assignment implies that overlaps between the -left-hand side and the right-hand side are 'safe' (for example ``a, b = b, a`` -swaps two variables), overlaps *within* the collection of assigned-to variables -are not safe! For instance, the following program prints ``[0, 2]``:: +Although the definition of assignment implies that overlaps between the +left-hand side and the right-hand side are 'simultanenous' (for example ``a, b = +b, a`` swaps two variables), overlaps *within* the collection of assigned-to +variables occur left-to-right, sometimes resulting in confusion. For instance, +the following program prints ``[0, 2]``:: x = [0, 1] i = 0 - i, x[i] = 1, 2 + i, x[i] = 1, 2 # i is updated, then x[i] is updated print(x) @@ -260,6 +262,18 @@ Augmented assignment statements .. index:: pair: augmented; assignment single: statement; assignment, augmented + single: +=; augmented assignment + single: -=; augmented assignment + single: *=; augmented assignment + single: /=; augmented assignment + single: %=; augmented assignment + single: &=; augmented assignment + single: ^=; augmented assignment + single: |=; augmented assignment + single: **=; augmented assignment + single: //=; augmented assignment + single: >>=; augmented assignment + single: <<=; augmented assignment Augmented assignment is the combination, in a single statement, of a binary operation and an assignment statement: @@ -267,10 +281,10 @@ operation and an assignment statement: .. productionlist:: augmented_assignment_stmt: `augtarget` `augop` (`expression_list` | `yield_expression`) augtarget: `identifier` | `attributeref` | `subscription` | `slicing` - augop: "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**=" + augop: "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**=" : | ">>=" | "<<=" | "&=" | "^=" | "|=" -(See section :ref:`primaries` for the syntax definitions for the last three +(See section :ref:`primaries` for the syntax definitions of the last three symbols.) An augmented assignment evaluates the target (which, unlike normal assignment @@ -284,6 +298,11 @@ version, ``x`` is only evaluated once. Also, when possible, the actual operation is performed *in-place*, meaning that rather than creating a new object and assigning that to the target, the old object is modified instead. +Unlike normal assignments, augmented assignments evaluate the left-hand side +*before* evaluating the right-hand side. For example, ``a[i] += f(x)`` first +looks-up ``a[i]``, then it evaluates ``f(x)`` and performs the addition, and +lastly, it writes the result back to ``a[i]``. + With the exception of assigning to tuples and multiple targets in a single statement, the assignment done by augmented assignment statements is handled the same way as normal assignments. Similarly, with the exception of the possible @@ -445,53 +464,26 @@ The :keyword:`yield` statement .. productionlist:: yield_stmt: `yield_expression` -The :keyword:`yield` statement is only used when defining a generator function, -and is only used in the body of the generator function. Using a :keyword:`yield` -statement in a function definition is sufficient to cause that definition to -create a generator function instead of a normal function. - -When a generator function is called, it returns an iterator known as a generator -iterator, or more commonly, a generator. The body of the generator function is -executed by calling the :func:`next` function on the generator repeatedly until -it raises an exception. +A :keyword:`yield` statement is semantically equivalent to a :ref:`yield +expression <yieldexpr>`. The yield statement can be used to omit the parentheses +that would otherwise be required in the equivalent yield expression +statement. For example, the yield statements :: -When a :keyword:`yield` statement is executed, the state of the generator is -frozen and the value of :token:`expression_list` is returned to :meth:`next`'s -caller. By "frozen" we mean that all local state is retained, including the -current bindings of local variables, the instruction pointer, and the internal -evaluation stack: enough information is saved so that the next time :func:`next` -is invoked, the function can proceed exactly as if the :keyword:`yield` -statement were just another external call. + yield <expr> + yield from <expr> -The :keyword:`yield` statement is allowed in the :keyword:`try` clause of a -:keyword:`try` ... :keyword:`finally` construct. If the generator is not -resumed before it is finalized (by reaching a zero reference count or by being -garbage collected), the generator-iterator's :meth:`close` method will be -called, allowing any pending :keyword:`finally` clauses to execute. +are equivalent to the yield expression statements :: -When ``yield from <expr>`` is used, it treats the supplied expression as -a subiterator, producing values from it until the underlying iterator is -exhausted. + (yield <expr>) + (yield from <expr>) - .. versionchanged:: 3.3 - Added ``yield from <expr>`` to delegate control flow to a subiterator - -For full details of :keyword:`yield` semantics, refer to the :ref:`yieldexpr` -section. - -.. seealso:: - - :pep:`0255` - Simple Generators - The proposal for adding generators and the :keyword:`yield` statement to Python. - - :pep:`0342` - Coroutines via Enhanced Generators - The proposal to enhance the API and syntax of generators, making them - usable as simple coroutines. - - :pep:`0380` - Syntax for Delegating to a Subgenerator - The proposal to introduce the :token:`yield_from` syntax, making delegation - to sub-generators easy. +Yield expressions and statements are only used when defining a :term:`generator` +function, and are only used in the body of the generator function. Using yield +in a function definition is sufficient to cause that definition to create a +generator function instead of a normal function. +For full details of :keyword:`yield` semantics, refer to the +:ref:`yieldexpr` section. .. _raise: @@ -556,8 +548,8 @@ printed:: RuntimeError: Something bad happened A similar mechanism works implicitly if an exception is raised inside an -exception handler: the previous exception is then attached as the new -exception's :attr:`__context__` attribute:: +exception handler or a :keyword:`finally` clause: the previous exception is then +attached as the new exception's :attr:`__context__` attribute:: >>> try: ... print(1 / 0) @@ -672,7 +664,7 @@ commas) the two steps are carried out separately for each clause, just as though the clauses had been separated out into individiual import statements. -The details of the first step, finding and loading modules is described in +The details of the first step, finding and loading modules are described in greater detail in the section on the :ref:`import system <importsystem>`, which also describes the various types of packages and modules that can be imported, as well as all the hooks that can be used to customize @@ -683,6 +675,8 @@ initializing the module, which includes execution of the module's code. If the requested module is retrieved successfully, it will be made available in the local namespace in one of three ways: +.. index:: single: as; import statement + * If the module name is followed by :keyword:`as`, then the name following :keyword:`as` is bound directly to the imported module. * If no other name is specified, and the module being imported is a top @@ -701,7 +695,7 @@ available in the local namespace in one of three ways: The :keyword:`from` form uses a slightly more complex process: -#. find the module specified in the :keyword:`from` clause loading and +#. find the module specified in the :keyword:`from` clause, loading and initializing it if necessary; #. for each of the identifiers specified in the :keyword:`import` clauses: @@ -709,7 +703,7 @@ The :keyword:`from` form uses a slightly more complex process: #. if not, attempt to import a submodule with that name and then check the imported module again for that attribute #. if the attribute is not found, :exc:`ImportError` is raised. - #. otherwise, a reference to that value is bound in the local namespace, + #. otherwise, a reference to that value is stored in the local namespace, using the name in the :keyword:`as` clause if it is present, otherwise using the attribute name @@ -737,10 +731,9 @@ in the module's namespace which do not begin with an underscore character to avoid accidentally exporting items that are not part of the API (such as library modules which were imported and used within the module). -The :keyword:`from` form with ``*`` may only occur in a module scope. The wild -card form of import --- ``import *`` --- is only allowed at the module level. -Attempting to use it in class or function definitions will raise a -:exc:`SyntaxError`. +The wild card form of import --- ``from module import *`` --- is only allowed at +the module level. Attempting to use it in class or function definitions will +raise a :exc:`SyntaxError`. .. index:: single: relative; import @@ -759,7 +752,7 @@ import mod`` from within ``pkg.subpkg1`` you will import ``pkg.subpkg2.mod``. The specification for relative imports is contained within :pep:`328`. :func:`importlib.import_module` is provided to support applications that -determine which modules need to be loaded dynamically. +determine dynamically the modules to be loaded. .. _future: @@ -771,10 +764,12 @@ Future statements A :dfn:`future statement` is a directive to the compiler that a particular module should be compiled using syntax or semantics that will be available in a -specified future release of Python. The future statement is intended to ease -migration to future versions of Python that introduce incompatible changes to -the language. It allows use of the new features on a per-module basis before -the release in which the feature becomes standard. +specified future release of Python where the feature becomes standard. + +The future statement is intended to ease migration to future versions of Python +that introduce incompatible changes to the language. It allows use of the new +features on a per-module basis before the release in which the feature becomes +standard. .. productionlist:: * future_statement: "from" "__future__" "import" feature ["as" name] @@ -869,7 +864,7 @@ definition, function definition, or :keyword:`import` statement. .. impl-detail:: - The current implementation does not enforce the latter two restrictions, but + The current implementation does not enforce the two restrictions, but programs should not abuse this freedom, as future implementations may enforce them or silently change the meaning of the program. @@ -902,16 +897,16 @@ The :keyword:`nonlocal` statement : | "nonlocal" identifier augop expression_list The :keyword:`nonlocal` statement causes the listed identifiers to refer to -previously bound variables in the nearest enclosing scope. This is important -because the default behavior for binding is to search the local namespace -first. The statement allows encapsulated code to rebind variables outside of -the local scope besides the global (module) scope. +previously bound variables in the nearest enclosing scope excluding globals. +This is important because the default behavior for binding is to search the +local namespace first. The statement allows encapsulated code to rebind +variables outside of the local scope besides the global (module) scope. .. XXX not implemented The :keyword:`nonlocal` statement may prepend an assignment or augmented assignment, but not an expression. -Names listed in a :keyword:`nonlocal` statement, unlike to those listed in a +Names listed in a :keyword:`nonlocal` statement, unlike those listed in a :keyword:`global` statement, must refer to pre-existing bindings in an enclosing scope (the scope in which a new binding should be created cannot be determined unambiguously). diff --git a/Doc/reference/toplevel_components.rst b/Doc/reference/toplevel_components.rst index f4bc71f07b0c..e1687ff04d32 100644 --- a/Doc/reference/toplevel_components.rst +++ b/Doc/reference/toplevel_components.rst @@ -97,20 +97,10 @@ Expression input ================ .. index:: single: input - .. index:: builtin: eval -There are two forms of expression input. Both ignore leading whitespace. The +:func:`eval` is used for expression input. It ignores leading whitespace. The string argument to :func:`eval` must have the following form: .. productionlist:: eval_input: `expression_list` NEWLINE* - -.. index:: - object: file - single: input; raw - single: readline() (file method) - -Note: to read 'raw' input line without interpretation, you can use the -:meth:`readline` method of file objects, including ``sys.stdin``. - diff --git a/Doc/tools/sphinxext/c_annotations.py b/Doc/tools/extensions/c_annotations.py similarity index 93% rename from Doc/tools/sphinxext/c_annotations.py rename to Doc/tools/extensions/c_annotations.py index 8b5167ac906e..baa39f3b4464 100644 --- a/Doc/tools/sphinxext/c_annotations.py +++ b/Doc/tools/extensions/c_annotations.py @@ -13,7 +13,7 @@ Usage: Set the `refcount_file` config value to the path to the reference count data file. - :copyright: Copyright 2007-2013 by Georg Brandl. + :copyright: Copyright 2007-2014 by Georg Brandl. :license: Python license. """ @@ -81,7 +81,10 @@ def add_annotations(self, app, doctree): continue if not par[0].has_key('names') or not par[0]['names']: continue - entry = self.get(par[0]['names'][0]) + name = par[0]['names'][0] + if name.startswith("c."): + name = name[2:] + entry = self.get(name) if not entry: continue elif entry.result_type not in ("PyObject*", "PyVarObject*"): @@ -115,3 +118,4 @@ def new_handle_signature(self, sig, signode): signode.parent['stableabi'] = 'stableabi' in self.options return old_handle_signature(self, sig, signode) CObject.handle_signature = new_handle_signature + return {'version': '1.0', 'parallel_read_safe': True} diff --git a/Doc/tools/sphinxext/patchlevel.py b/Doc/tools/extensions/patchlevel.py similarity index 100% rename from Doc/tools/sphinxext/patchlevel.py rename to Doc/tools/extensions/patchlevel.py diff --git a/Doc/tools/sphinxext/pyspecific.py b/Doc/tools/extensions/pyspecific.py similarity index 81% rename from Doc/tools/sphinxext/pyspecific.py rename to Doc/tools/extensions/pyspecific.py index 2b5de1421e73..9b78184d6745 100644 --- a/Doc/tools/sphinxext/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -5,20 +5,36 @@ Sphinx extension with Python doc-specific markup. - :copyright: 2008-2013 by Georg Brandl. + :copyright: 2008-2014 by Georg Brandl. :license: Python license. """ -ISSUE_URI = 'http://bugs.python.org/issue%s' -SOURCE_URI = 'http://hg.python.org/cpython/file/default/%s' +import re +import codecs +from os import path +from time import asctime +from pprint import pformat +from docutils.io import StringOutput +from docutils.utils import new_document from docutils import nodes, utils -import sphinx +from sphinx import addnodes +from sphinx.builders import Builder from sphinx.util.nodes import split_explicit_title +from sphinx.util.compat import Directive from sphinx.writers.html import HTMLTranslator +from sphinx.writers.text import TextWriter from sphinx.writers.latex import LaTeXTranslator -from sphinx.locale import versionlabels +from sphinx.domains.python import PyModulelevel, PyClassmember + +# Support for checking for suspicious markup + +import suspicious + + +ISSUE_URI = 'https://bugs.python.org/issue%s' +SOURCE_URI = 'https://hg.python.org/cpython/file/default/%s' # monkey-patch reST parser to disable alphabetic and roman enumerated lists from docutils.parsers.rst.states import Body @@ -27,21 +43,12 @@ Body.enum.converters['lowerroman'] = \ Body.enum.converters['upperroman'] = lambda x: None -if sphinx.__version__[:3] < '1.2': - # monkey-patch HTML translator to give versionmodified paragraphs a class - def new_visit_versionmodified(self, node): - self.body.append(self.starttag(node, 'p', CLASS=node['type'])) - text = versionlabels[node['type']] % node['version'] - if len(node): - text += ':' - else: - text += '.' - self.body.append('<span class="versionmodified">%s</span> ' % text) - HTMLTranslator.visit_versionmodified = new_visit_versionmodified - # monkey-patch HTML and LaTeX translators to keep doctest blocks in the # doctest docs themselves orig_visit_literal_block = HTMLTranslator.visit_literal_block +orig_depart_literal_block = LaTeXTranslator.depart_literal_block + + def new_visit_literal_block(self, node): meta = self.builder.env.metadata[self.builder.current_docname] old_trim_doctest_flags = self.highlighter.trim_doctest_flags @@ -52,9 +59,7 @@ def new_visit_literal_block(self, node): finally: self.highlighter.trim_doctest_flags = old_trim_doctest_flags -HTMLTranslator.visit_literal_block = new_visit_literal_block -orig_depart_literal_block = LaTeXTranslator.depart_literal_block def new_depart_literal_block(self, node): meta = self.builder.env.metadata[self.curfilestack[-1]] old_trim_doctest_flags = self.highlighter.trim_doctest_flags @@ -65,8 +70,11 @@ def new_depart_literal_block(self, node): finally: self.highlighter.trim_doctest_flags = old_trim_doctest_flags + +HTMLTranslator.visit_literal_block = new_visit_literal_block LaTeXTranslator.depart_literal_block = new_depart_literal_block + # Support for marking up and linking to bugs.python.org issues def issue_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): @@ -88,8 +96,6 @@ def source_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): # Support for marking up implementation details -from sphinx.util.compat import Directive - class ImplementationDetail(Directive): has_content = True @@ -116,9 +122,6 @@ def run(self): # Support for documenting decorators -from sphinx import addnodes -from sphinx.domains.python import PyModulelevel, PyClassmember - class PyDecoratorMixin(object): def handle_signature(self, sig, signode): ret = super(PyDecoratorMixin, self).handle_signature(sig, signode) @@ -128,25 +131,40 @@ def handle_signature(self, sig, signode): def needs_arglist(self): return False + class PyDecoratorFunction(PyDecoratorMixin, PyModulelevel): def run(self): # a decorator function is a function after all self.name = 'py:function' return PyModulelevel.run(self) + class PyDecoratorMethod(PyDecoratorMixin, PyClassmember): def run(self): self.name = 'py:method' return PyClassmember.run(self) -# Support for documenting version of removal in deprecations +class PyCoroutineMixin(object): + def handle_signature(self, sig, signode): + ret = super(PyCoroutineMixin, self).handle_signature(sig, signode) + signode.insert(0, addnodes.desc_annotation('coroutine ', 'coroutine ')) + return ret -from sphinx.locale import versionlabels -from sphinx.util.compat import Directive -versionlabels['deprecated-removed'] = \ - 'Deprecated since version %s, will be removed in version %s' +class PyCoroutineFunction(PyCoroutineMixin, PyModulelevel): + def run(self): + self.name = 'py:function' + return PyModulelevel.run(self) + + +class PyCoroutineMethod(PyCoroutineMixin, PyClassmember): + def run(self): + self.name = 'py:method' + return PyClassmember.run(self) + + +# Support for documenting version of removal in deprecations class DeprecatedRemoved(Directive): has_content = True @@ -155,34 +173,49 @@ class DeprecatedRemoved(Directive): final_argument_whitespace = True option_spec = {} + _label = 'Deprecated since version %s, will be removed in version %s' + def run(self): node = addnodes.versionmodified() node.document = self.state.document node['type'] = 'deprecated-removed' version = (self.arguments[0], self.arguments[1]) node['version'] = version + text = self._label % version if len(self.arguments) == 3: inodes, messages = self.state.inline_text(self.arguments[2], self.lineno+1) - node.extend(inodes) - if self.content: - self.state.nested_parse(self.content, self.content_offset, node) - ret = [node] + messages + para = nodes.paragraph(self.arguments[2], '', *inodes) + node.append(para) + else: + messages = [] + if self.content: + self.state.nested_parse(self.content, self.content_offset, node) + if len(node): + if isinstance(node[0], nodes.paragraph) and node[0].rawsource: + content = nodes.inline(node[0].rawsource, translatable=True) + content.source = node[0].source + content.line = node[0].line + content += node[0].children + node[0].replace_self(nodes.paragraph('', '', content)) + node[0].insert(0, nodes.inline('', '%s: ' % text, + classes=['versionmodified'])) else: - ret = [node] + para = nodes.paragraph('', '', + nodes.inline('', '%s.' % text, + classes=['versionmodified'])) + node.append(para) env = self.state.document.settings.env env.note_versionchange('deprecated', version[0], node, self.lineno) - return ret + return [node] + messages # Support for including Misc/NEWS -import re -import codecs - issue_re = re.compile('([Ii])ssue #([0-9]+)') whatsnew_re = re.compile(r"(?im)^what's new in (.*?)\??$") + class MiscNews(Directive): has_content = False required_arguments = 1 @@ -207,7 +240,7 @@ def run(self): text = 'The NEWS file is not available.' node = nodes.strong(text, text) return [node] - content = issue_re.sub(r'`\1ssue #\2 <http://bugs.python.org/\2>`__', + content = issue_re.sub(r'`\1ssue #\2 <https://bugs.python.org/\2>`__', content) content = whatsnew_re.sub(r'\1', content) # remove first 3 lines as they are the main heading @@ -236,15 +269,6 @@ def run(self): 'typesseq', 'typesseq-mutable', 'unary', 'while', 'with', 'yield' ] -from os import path -from time import asctime -from pprint import pformat -from docutils.io import StringOutput -from docutils.utils import new_document - -from sphinx.builders import Builder -from sphinx.writers.text import TextWriter - class PydocTopicsBuilder(Builder): name = 'pydoc-topics' @@ -272,29 +296,23 @@ def write(self, *ignored): document.append(doctree.ids[labelid]) destination = StringOutput(encoding='utf-8') writer.write(document, destination) - self.topics[label] = writer.output.encode('utf-8') + self.topics[label] = writer.output def finish(self): - f = open(path.join(self.outdir, 'topics.py'), 'w') + f = open(path.join(self.outdir, 'topics.py'), 'wb') try: - f.write('# -*- coding: utf-8 -*-\n') - f.write('# Autogenerated by Sphinx on %s\n' % asctime()) - f.write('topics = ' + pformat(self.topics) + '\n') + f.write('# -*- coding: utf-8 -*-\n'.encode('utf-8')) + f.write(('# Autogenerated by Sphinx on %s\n' % asctime()).encode('utf-8')) + f.write(('topics = ' + pformat(self.topics) + '\n').encode('utf-8')) finally: f.close() -# Support for checking for suspicious markup - -import suspicious - - # Support for documenting Opcodes -import re - opcode_sig_re = re.compile(r'(\w+(?:\+\d)?)(?:\s*\((.*)\))?') + def parse_opcode_signature(env, sig, signode): """Transform an opcode signature into RST nodes.""" m = opcode_sig_re.match(sig) @@ -314,12 +332,13 @@ def parse_opcode_signature(env, sig, signode): pdbcmd_sig_re = re.compile(r'([a-z()!]+)\s*(.*)') # later... -#pdbargs_tokens_re = re.compile(r'''[a-zA-Z]+ | # identifiers +# pdbargs_tokens_re = re.compile(r'''[a-zA-Z]+ | # identifiers # [.,:]+ | # punctuation # [\[\]()] | # parens # \s+ # whitespace # ''', re.X) + def parse_pdb_command(env, sig, signode): """Transform a pdb command signature into RST nodes.""" m = pdbcmd_sig_re.match(sig) @@ -347,4 +366,7 @@ def setup(app): app.add_description_unit('2to3fixer', '2to3fixer', '%s (2to3 fixer)') app.add_directive_to_domain('py', 'decorator', PyDecoratorFunction) app.add_directive_to_domain('py', 'decoratormethod', PyDecoratorMethod) + app.add_directive_to_domain('py', 'coroutinefunction', PyCoroutineFunction) + app.add_directive_to_domain('py', 'coroutinemethod', PyCoroutineMethod) app.add_directive('miscnews', MiscNews) + return {'version': '1.0', 'parallel_read_safe': True} diff --git a/Doc/tools/sphinxext/suspicious.py b/Doc/tools/extensions/suspicious.py similarity index 99% rename from Doc/tools/sphinxext/suspicious.py rename to Doc/tools/extensions/suspicious.py index ee877336f676..d3ed849157f0 100644 --- a/Doc/tools/sphinxext/suspicious.py +++ b/Doc/tools/extensions/suspicious.py @@ -91,7 +91,7 @@ def init(self): self.log_file_name = os.path.join(self.outdir, 'suspicious.csv') open(self.log_file_name, 'w').close() # load database of previously ignored issues - self.load_rules(os.path.join(os.path.dirname(__file__), + self.load_rules(os.path.join(os.path.dirname(__file__), '..', 'susp-ignored.csv')) def get_outdated_docs(self): diff --git a/Doc/tools/sphinxext/pydoctheme/static/pydoctheme.css b/Doc/tools/pydoctheme/static/pydoctheme.css similarity index 92% rename from Doc/tools/sphinxext/pydoctheme/static/pydoctheme.css rename to Doc/tools/pydoctheme/static/pydoctheme.css index 3d995d81b1fe..50835bb92ca6 100644 --- a/Doc/tools/sphinxext/pydoctheme/static/pydoctheme.css +++ b/Doc/tools/pydoctheme/static/pydoctheme.css @@ -94,31 +94,31 @@ div.body div.seealso { } div.body a { - color: #00608f; + color: #0072aa; } div.body a:visited { - color: #30306f; + color: #6363bb; } div.body a:hover { color: #00B0E4; } -tt, pre { +tt, code, pre { font-family: monospace, sans-serif; font-size: 96.5%; } -div.body tt { +div.body tt, div.body code { border-radius: 3px; } -div.body tt.descname { +div.body tt.descname, div.body code.descname { font-size: 120%; } -div.body tt.xref, div.body a tt { +div.body tt.xref, div.body a tt, div.body code.xref, div.body a code { font-weight: normal; } diff --git a/Doc/tools/sphinxext/pydoctheme/theme.conf b/Doc/tools/pydoctheme/theme.conf similarity index 100% rename from Doc/tools/sphinxext/pydoctheme/theme.conf rename to Doc/tools/pydoctheme/theme.conf diff --git a/Doc/tools/roman.py b/Doc/tools/roman.py deleted file mode 100644 index 89ef617e6e71..000000000000 --- a/Doc/tools/roman.py +++ /dev/null @@ -1,80 +0,0 @@ -"""Convert to and from Roman numerals""" - -__author__ = "Mark Pilgrim (f8dy@diveintopython.org)" -__version__ = "1.4" -__date__ = "8 August 2001" -__copyright__ = """Copyright (c) 2001 Mark Pilgrim - -This program is part of "Dive Into Python", a free Python tutorial for -experienced programmers. Visit http://diveintopython.org/ for the -latest version. - -This program is free software; you can redistribute it and/or modify -it under the terms of the Python 2.1.1 license, available at -http://www.python.org/2.1.1/license.html -""" - -import re - -#Define exceptions -class RomanError(Exception): pass -class OutOfRangeError(RomanError): pass -class NotIntegerError(RomanError): pass -class InvalidRomanNumeralError(RomanError): pass - -#Define digit mapping -romanNumeralMap = (('M', 1000), - ('CM', 900), - ('D', 500), - ('CD', 400), - ('C', 100), - ('XC', 90), - ('L', 50), - ('XL', 40), - ('X', 10), - ('IX', 9), - ('V', 5), - ('IV', 4), - ('I', 1)) - -def toRoman(n): - """convert integer to Roman numeral""" - if not (0 < n < 5000): - raise OutOfRangeError("number out of range (must be 1..4999)") - if int(n) != n: - raise NotIntegerError("decimals can not be converted") - - result = "" - for numeral, integer in romanNumeralMap: - while n >= integer: - result += numeral - n -= integer - return result - -#Define pattern to detect valid Roman numerals -romanNumeralPattern = re.compile(""" - ^ # beginning of string - M{0,4} # thousands - 0 to 4 M's - (CM|CD|D?C{0,3}) # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's), - # or 500-800 (D, followed by 0 to 3 C's) - (XC|XL|L?X{0,3}) # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's), - # or 50-80 (L, followed by 0 to 3 X's) - (IX|IV|V?I{0,3}) # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's), - # or 5-8 (V, followed by 0 to 3 I's) - $ # end of string - """ ,re.VERBOSE) - -def fromRoman(s): - """convert Roman numeral to integer""" - if not s: - raise InvalidRomanNumeralError('Input can not be blank') - if not romanNumeralPattern.search(s): - raise InvalidRomanNumeralError('Invalid Roman numeral: %s' % s) - - result = 0 - index = 0 - for numeral, integer in romanNumeralMap: - while s[index:index+len(numeral)] == numeral: - result += integer - index += len(numeral) - return result diff --git a/Doc/tools/rstlint.py b/Doc/tools/rstlint.py index 2cc3d1277ca0..7dccf72f99cb 100755 --- a/Doc/tools/rstlint.py +++ b/Doc/tools/rstlint.py @@ -15,7 +15,6 @@ import re import sys import getopt -import subprocess from os.path import join, splitext, abspath, exists from collections import defaultdict @@ -28,14 +27,16 @@ 'parsed-literal', 'pull-quote', 'raw', 'replace', 'restructuredtext-test-directive', 'role', 'rubric', 'sectnum', 'sidebar', 'table', 'target-notes', 'tip', 'title', 'topic', 'unicode', 'warning', - # Sphinx custom ones + # Sphinx and Python docs custom ones 'acks', 'attribute', 'autoattribute', 'autoclass', 'autodata', 'autoexception', 'autofunction', 'automethod', 'automodule', 'centered', 'cfunction', 'class', 'classmethod', 'cmacro', 'cmdoption', 'cmember', 'code-block', 'confval', 'cssclass', 'ctype', 'currentmodule', 'cvar', - 'data', 'deprecated', 'describe', 'directive', 'doctest', 'envvar', 'event', - 'exception', 'function', 'glossary', 'highlight', 'highlightlang', 'index', - 'literalinclude', 'method', 'module', 'moduleauthor', 'productionlist', + 'data', 'decorator', 'decoratormethod', 'deprecated-removed', + 'deprecated(?!-removed)', 'describe', 'directive', 'doctest', 'envvar', + 'event', 'exception', 'function', 'glossary', 'highlight', 'highlightlang', + 'impl-detail', 'index', 'literalinclude', 'method', 'miscnews', 'module', + 'moduleauthor', 'opcode', 'pdbcommand', 'productionlist', 'program', 'role', 'sectionauthor', 'seealso', 'sourcecode', 'staticmethod', 'tabularcolumns', 'testcode', 'testoutput', 'testsetup', 'toctree', 'todo', 'todolist', 'versionadded', 'versionchanged' @@ -44,13 +45,14 @@ all_directives = '(' + '|'.join(directives) + ')' seems_directive_re = re.compile(r'\.\. %s([^a-z:]|:(?!:))' % all_directives) default_role_re = re.compile(r'(^| )`\w([^`]*?\w)?`($| )') -leaked_markup_re = re.compile(r'[a-z]::[^=]|:[a-z]+:|`|\.\.\s*\w+:') +leaked_markup_re = re.compile(r'[a-z]::\s|`|\.\.\s*\w+:') checkers = {} checker_props = {'severity': 1, 'falsepositives': False} + def checker(*suffixes, **kwds): """Decorator to register a function as a checker.""" def deco(func): @@ -171,10 +173,6 @@ def main(argv): count = defaultdict(int) for root, dirs, files in os.walk(path): - # ignore subdirs controlled by svn - if '.svn' in dirs: - dirs.remove('.svn') - # ignore subdirs in ignore list if abspath(root) in ignore: del dirs[:] @@ -198,7 +196,7 @@ def main(argv): print('Checking %s...' % fn) try: - with open(fn, 'r') as f: + with open(fn, 'r', encoding='utf-8') as f: lines = list(f) except (IOError, OSError) as err: print('%s: cannot open: %s' % (fn, err)) diff --git a/Doc/tools/sphinx-build.py b/Doc/tools/sphinx-build.py deleted file mode 100644 index a446dfa8e18c..000000000000 --- a/Doc/tools/sphinx-build.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -""" - Sphinx - Python documentation toolchain - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - :copyright: 2007-2010 by Georg Brandl. - :license: Python license. -""" - -import sys -import warnings - -# Get rid of UserWarnings reported by pkg_resources. -warnings.filterwarnings('ignore', category=UserWarning, module='jinja2') - -if __name__ == '__main__': - - if sys.version_info[:3] < (2, 4, 0) or sys.version_info[:3] > (3, 0, 0): - sys.stderr.write("""\ -Error: Sphinx needs to be executed with Python 2.4 or newer (not 3.0 though). -(If you run this from the Makefile, you can set the PYTHON variable -to the path of an alternative interpreter executable, e.g., -``make html PYTHON=python2.5``). -""") - sys.exit(1) - - from sphinx import main - sys.exit(main(sys.argv)) diff --git a/Doc/tools/sphinxext/indexsidebar.html b/Doc/tools/sphinxext/indexsidebar.html deleted file mode 100644 index ed5da0cd31f4..000000000000 --- a/Doc/tools/sphinxext/indexsidebar.html +++ /dev/null @@ -1,17 +0,0 @@ - <h3>Download</h3> - <p><a href="http://github.com/%7B%7B%20pathto('download') }}">Download these documents</a></p> - <h3>Docs for other versions</h3> - <ul> - <li><a href="http://docs.python.org/2.7/">Python 2.7 (stable)</a></li> - <li><a href="http://docs.python.org/3.3/">Python 3.3 (stable)</a></li> - <li><a href="http://www.python.org/doc/versions/">Old versions</a></li> - </ul> - - <h3>Other resources</h3> - <ul> - {# XXX: many of these should probably be merged in the main docs #} - <li><a href="http://www.python.org/dev/peps/">PEP Index</a></li> - <li><a href="http://wiki.python.org/moin/BeginnersGuide">Beginner's Guide</a></li> - <li><a href="http://wiki.python.org/moin/PythonBooks">Book List</a></li> - <li><a href="http://www.python.org/doc/av/">Audio/Visual Talks</a></li> - </ul> diff --git a/Doc/tools/sphinxext/opensearch.xml b/Doc/tools/sphinxext/opensearch.xml deleted file mode 100644 index 69cec804cd0e..000000000000 --- a/Doc/tools/sphinxext/opensearch.xml +++ /dev/null @@ -1,4 +0,0 @@ -{% extends "!opensearch.xml" %} -{% block extra -%} -<Image height="16" width="16" type="image/x-icon">http://www.python.org/images/favicon16x16.ico</Image> -{%- endblock %} diff --git a/Doc/tools/sphinxext/static/basic.css b/Doc/tools/sphinxext/static/basic.css deleted file mode 100644 index 2058b05f941e..000000000000 --- a/Doc/tools/sphinxext/static/basic.css +++ /dev/null @@ -1,445 +0,0 @@ -/** - * Sphinx stylesheet -- basic theme - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -/* -- main layout ----------------------------------------------------------- */ - -div.clearer { - clear: both; -} - -/* -- relbar ---------------------------------------------------------------- */ - -div.related { - width: 100%; - font-size: 90%; -} - -div.related h3 { - display: none; -} - -div.related ul { - margin: 0; - padding: 0 0 0 10px; - list-style: none; -} - -div.related li { - display: inline; -} - -div.related li.right { - float: right; - margin-right: 5px; -} - -/* -- sidebar --------------------------------------------------------------- */ - -div.sphinxsidebarwrapper { - position: relative; - top: 0; - padding: 10px 5px 0 10px; - word-wrap: break-word; -} - -div.sphinxsidebar { - float: left; - width: 230px; - margin-left: -100%; - font-size: 90%; -} - -div.sphinxsidebar ul { - list-style: none; -} - -div.sphinxsidebar ul ul, -div.sphinxsidebar ul.want-points { - margin-left: 20px; - list-style: square; -} - -div.sphinxsidebar ul ul { - margin-top: 0; - margin-bottom: 0; -} - -div.sphinxsidebar form { - margin-top: 10px; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - -img { - border: 0; -} - -/* -- search page ----------------------------------------------------------- */ - -ul.search { - margin: 10px 0 0 20px; - padding: 0; -} - -ul.search li { - padding: 5px 0 5px 20px; - background-image: url(http://github.com/file.png); - background-repeat: no-repeat; - background-position: 0 7px; -} - -ul.search li a { - font-weight: bold; -} - -ul.search li div.context { - color: #888; - margin: 2px 0 0 30px; - text-align: left; -} - -ul.keywordmatches li.goodmatch a { - font-weight: bold; -} - -/* -- index page ------------------------------------------------------------ */ - -table.contentstable { - width: 90%; -} - -table.contentstable p.biglink { - line-height: 150%; -} - -a.biglink { - font-size: 1.3em; -} - -span.linkdescr { - font-style: italic; - padding-top: 5px; - font-size: 90%; -} - -/* -- general index --------------------------------------------------------- */ - -table.indextable td { - text-align: left; - vertical-align: top; -} - -table.indextable dl, table.indextable dd { - margin-top: 0; - margin-bottom: 0; -} - -table.indextable tr.pcap { - height: 10px; -} - -table.indextable tr.cap { - margin-top: 10px; - background-color: #f2f2f2; -} - -img.toggler { - margin-right: 3px; - margin-top: 3px; - cursor: pointer; -} - -/* -- general body styles --------------------------------------------------- */ - -a.headerlink { - visibility: hidden; -} - -h1:hover > a.headerlink, -h2:hover > a.headerlink, -h3:hover > a.headerlink, -h4:hover > a.headerlink, -h5:hover > a.headerlink, -h6:hover > a.headerlink, -dt:hover > a.headerlink { - visibility: visible; -} - -div.body p.caption { - text-align: inherit; -} - -div.body td { - text-align: left; -} - -.field-list ul { - padding-left: 1em; -} - -.first { - margin-top: 0 !important; -} - -p.rubric { - margin-top: 30px; - font-weight: bold; -} - -/* -- sidebars -------------------------------------------------------------- */ - -div.sidebar { - margin: 0 0 0.5em 1em; - border: 1px solid #ddb; - padding: 7px 7px 0 7px; - background-color: #ffe; - width: 40%; - float: right; -} - -p.sidebar-title { - font-weight: bold; -} - -/* -- topics ---------------------------------------------------------------- */ - -div.topic { - border: 1px solid #ccc; - padding: 7px 7px 0 7px; - margin: 10px 0 10px 0; -} - -p.topic-title { - font-size: 1.1em; - font-weight: bold; - margin-top: 10px; -} - -/* -- admonitions ----------------------------------------------------------- */ - -div.admonition { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; -} - -div.admonition dt { - font-weight: bold; -} - -div.admonition dl { - margin-bottom: 0; -} - -p.admonition-title { - margin: 0px 10px 5px 0px; - font-weight: bold; -} - -div.body p.centered { - text-align: center; - margin-top: 25px; -} - -/* -- tables ---------------------------------------------------------------- */ - -table.docutils { - border: 0 solid #dce; - border-collapse: collapse; -} - -table.docutils td, table.docutils th { - padding: 2px 5px 2px 5px; - border-left: 0; - background-color: #eef; -} - -table.docutils td p.last, table.docutils th p.last { - margin-bottom: 0; -} - -table.field-list td, table.field-list th { - border: 0 !important; -} - -table.footnote td, table.footnote th { - border: 0 !important; -} - -table.docutils th { - border-top: 1px solid #cac; - background-color: #ede; -} - -th { - text-align: left; - padding-right: 5px; -} - -th.head { - text-align: center; -} - -/* -- other body styles ----------------------------------------------------- */ - -dl { - margin-bottom: 15px; -} - -dd p { - margin-top: 0px; -} - -dd ul, dd table { - margin-bottom: 10px; -} - -dd { - margin-top: 3px; - margin-bottom: 10px; - margin-left: 30px; -} - -dt:target, .highlight { - background-color: #fbe54e; -} - -dl.glossary dt { - font-weight: bold; - font-size: 1.1em; -} - -.field-list ul { - margin: 0; - padding-left: 1em; -} - -.field-list p { - margin: 0; -} - -.refcount { - color: #060; -} - -.optional { - font-size: 1.3em; -} - -.versionmodified { - font-style: italic; -} - -.deprecated, .deprecated-removed { - background-color: #ffe4e4; - border: 1px solid #f66; - padding: 7px; -} - -div.deprecated p { - margin-bottom: 0; -} - -.system-message { - background-color: #fda; - padding: 5px; - border: 3px solid red; -} - -.footnote:target { - background-color: #ffa; -} - -.impl-detail { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; - border: 1px solid #ccc; -} - -.impl-detail .compound-first { - margin-top: 0; -} - -.impl-detail .compound-last { - margin-bottom: 0; -} - -/* -- code displays --------------------------------------------------------- */ - -pre { - overflow: auto; - overflow-y: hidden; -} - -td.linenos pre { - padding: 5px 0px; - border: 0; - background-color: transparent; - color: #aaa; -} - -table.highlighttable { - margin-left: 0.5em; -} - -table.highlighttable td { - padding: 0 0.5em 0 0.5em; -} - -tt.descname { - background-color: transparent; - font-weight: bold; - font-size: 1.2em; -} - -tt.descclassname { - background-color: transparent; -} - -tt.xref, a tt { - background-color: transparent; - font-weight: bold; -} - -h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { - background-color: transparent; -} - -/* -- math display ---------------------------------------------------------- */ - -img.math { - vertical-align: middle; -} - -div.body div.math p { - text-align: center; -} - -span.eqno { - float: right; -} - -/* -- printout stylesheet --------------------------------------------------- */ - -@media print { - div.document, - div.documentwrapper, - div.bodywrapper { - margin: 0 !important; - width: 100%; - } - - div.sphinxsidebar, - div.related, - div.footer, - #top-link { - display: none; - } -} diff --git a/Doc/tools/sphinxext/static/copybutton.js b/Doc/tools/static/copybutton.js similarity index 100% rename from Doc/tools/sphinxext/static/copybutton.js rename to Doc/tools/static/copybutton.js diff --git a/Doc/tools/sphinxext/static/py.png b/Doc/tools/static/py.png similarity index 100% rename from Doc/tools/sphinxext/static/py.png rename to Doc/tools/static/py.png diff --git a/Doc/tools/sphinxext/static/sidebar.js b/Doc/tools/static/sidebar.js similarity index 100% rename from Doc/tools/sphinxext/static/sidebar.js rename to Doc/tools/static/sidebar.js diff --git a/Doc/tools/sphinxext/static/version_switch.js b/Doc/tools/static/version_switch.js similarity index 92% rename from Doc/tools/sphinxext/static/version_switch.js rename to Doc/tools/static/version_switch.js index cc7be1c539d2..7289a4d01ea2 100644 --- a/Doc/tools/sphinxext/static/version_switch.js +++ b/Doc/tools/static/version_switch.js @@ -2,7 +2,9 @@ 'use strict'; var all_versions = { - '3.4': 'dev (3.4)', + '3.6': 'dev (3.6)', + '3.5': '3.5', + '3.4': '3.4', '3.3': '3.3', '3.2': '3.2', '2.7': '2.7', @@ -49,7 +51,7 @@ window.location.href = new_url; }, error: function() { - window.location.href = 'http://docs.python.org/' + selected; + window.location.href = 'https://docs.python.org/' + selected; } }); } diff --git a/Doc/tools/sphinxext/susp-ignored.csv b/Doc/tools/susp-ignored.csv similarity index 85% rename from Doc/tools/sphinxext/susp-ignored.csv rename to Doc/tools/susp-ignored.csv index 67ad01f63b2a..2a95fca3135f 100644 --- a/Doc/tools/sphinxext/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -10,7 +10,6 @@ extending/embedding,,:numargs,"if(!PyArg_ParseTuple(args, "":numargs""))" extending/extending,,:myfunction,"PyArg_ParseTuple(args, ""D:myfunction"", &c);" extending/extending,,:set,"if (PyArg_ParseTuple(args, ""O:set_callback"", &temp)) {" extending/newtypes,,:call,"if (!PyArg_ParseTuple(args, ""sss:call"", &arg1, &arg2, &arg3)) {" -extending/windows,,:initspam,/export:initspam faq/programming,,:chr,">=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f):f(xc,yc,x,y,k,f):chr(" faq/programming,,::,for x in sequence[::-1]: faq/programming,,:reduce,"print((lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y," @@ -79,9 +78,8 @@ howto/logging,,:Started,INFO:root:Started howto/logging,,:This,DEBUG:root:This message should go to the log file howto/logging,,:This,DEBUG:This message should appear on the console howto/logging,,:Watch,WARNING:root:Watch out! -howto/pyporting,75,::,# make sure to use :: Python *and* :: Python :: 3 so -howto/pyporting,75,::,"'Programming Language :: Python'," -howto/pyporting,75,::,'Programming Language :: Python :: 3' +howto/pyporting,,::,Programming Language :: Python :: 2 +howto/pyporting,,::,Programming Language :: Python :: 3 howto/regex,,::, howto/regex,,:foo,(?:foo) howto/urllib2,,:example,"for example ""joe@password:example.com""" @@ -123,6 +121,8 @@ library/ipaddress,,:db8,>>> ipaddress.IPv6Address('2001:db8::1000') library/ipaddress,,::,>>> ipaddress.IPv6Address('2001:db8::1000') library/ipaddress,,:db8,IPv6Address('2001:db8::1000') library/ipaddress,,::,IPv6Address('2001:db8::1000') +library/ipaddress,,:db8,">>> ipaddress.ip_address(""2001:db8::1"").reverse_pointer" +library/ipaddress,,::,">>> ipaddress.ip_address(""2001:db8::1"").reverse_pointer" library/ipaddress,,::,"""::abc:7:def""" library/ipaddress,,:def,"""::abc:7:def""" library/ipaddress,,::,::FFFF/96 @@ -137,12 +137,9 @@ library/ipaddress,,:db00,2001:db00::0/ffff:ff00:: library/ipaddress,,::,2001:db00::0/ffff:ff00:: library/itertools,,:step,elements from seq[start:stop:step] library/itertools,,:stop,elements from seq[start:stop:step] -library/linecache,,:sys,"sys:x:3:3:sys:/dev:/bin/sh" library/logging.handlers,,:port,host:port library/mmap,,:i2,obj[i1:i2] library/multiprocessing,,`,# Add more tasks using `put()` -library/multiprocessing,,`,">>> l._callmethod('__getitem__', (20,)) # equiv to `l[20]`" -library/multiprocessing,,`,">>> l._callmethod('__getslice__', (2, 7)) # equiv to `l[2:7]`" library/multiprocessing,,:queue,">>> QueueManager.register('get_queue', callable=lambda:queue)" library/multiprocessing,,`,# register the Foo class; make `f()` and `g()` accessible via proxy library/multiprocessing,,`,# register the Foo class; make `g()` and `_h()` accessible via proxy @@ -165,7 +162,6 @@ library/profile,,:lineno,filename:lineno(function) library/pyexpat,,:elem1,<py:elem1 /> library/pyexpat,,:py,"xmlns:py = ""http://www.python.org/ns/"">" library/smtplib,,:port,method must support that as well as a regular host:port -library/socket,,::,"(10, 1, 6, '', ('2001:888:2000:d::a2', 80, 0, 0))]" library/socket,,::,'5aef:2b::8' library/socket,,:can,"return (can_id, can_dlc, data[:can_dlc])" library/socket,,:len,fds.fromstring(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) @@ -180,8 +176,6 @@ library/ssl,,:MyState,State or Province Name (full name) [Some-State]:MyState library/ssl,,:ops,Email Address []:ops@myserver.mygroup.myorganization.com library/ssl,,:Some,"Locality Name (eg, city) []:Some City" library/ssl,,:US,Country Name (2 letter code) [AU]:US -library/stdtypes,,::,>>> a[::-1].tolist() -library/stdtypes,,::,>>> a[::2].tolist() library/stdtypes,,:end,s[start:end] library/stdtypes,,::,>>> hash(v[::-2]) == hash(b'abcefg'[::-2]) library/stdtypes,,:len,s[len(s):len(s)] @@ -199,10 +193,10 @@ library/time,,:mm, library/time,,:ss, library/tracemalloc,,:limit,"for index, stat in enumerate(top_stats[:limit], 1):" library/turtle,,::,Example:: -library/unittest,1412,:foo,"self.assertEqual(cm.output, ['INFO:foo:first message'," -library/unittest,1412,:first,"self.assertEqual(cm.output, ['INFO:foo:first message'," -library/unittest,1412,:foo,'ERROR:foo.bar:second message']) -library/unittest,1412,:second,'ERROR:foo.bar:second message']) +library/unittest,,:foo,"self.assertEqual(cm.output, ['INFO:foo:first message'," +library/unittest,,:first,"self.assertEqual(cm.output, ['INFO:foo:first message'," +library/unittest,,:foo,'ERROR:foo.bar:second message']) +library/unittest,,:second,'ERROR:foo.bar:second message']) library/urllib.request,,:close,Connection:close library/urllib.request,,:lang,"xmlns=""http://www.w3.org/1999/xhtml"" xml:lang=""en"" lang=""en"">\n\n<head>\n" library/urllib.request,,:password,"""joe:password@python.org""" @@ -257,11 +251,11 @@ whatsnew/2.4,,:System, whatsnew/2.5,,:memory,:memory: whatsnew/2.5,,:step,[start:stop:step] whatsnew/2.5,,:stop,[start:stop:step] -whatsnew/2.7,1619,::,"ParseResult(scheme='http', netloc='[1080::8:800:200C:417A]'," -whatsnew/2.7,1619,::,>>> urlparse.urlparse('http://[1080::8:800:200c:417a]/foo') -whatsnew/2.7,735,:Sunday,'2009:4:Sunday' -whatsnew/2.7,862,:Cookie,"export PYTHONWARNINGS=all,error:::Cookie:0" -whatsnew/2.7,862,::,"export PYTHONWARNINGS=all,error:::Cookie:0" +whatsnew/2.7,,::,"ParseResult(scheme='http', netloc='[1080::8:800:200C:417A]'," +whatsnew/2.7,,::,>>> urlparse.urlparse('http://[1080::8:800:200c:417a]/foo') +whatsnew/2.7,,:Sunday,'2009:4:Sunday' +whatsnew/2.7,,:Cookie,"export PYTHONWARNINGS=all,error:::Cookie:0" +whatsnew/2.7,,::,"export PYTHONWARNINGS=all,error:::Cookie:0" whatsnew/3.2,,:affe,"netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]'," whatsnew/3.2,,:affe,>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8fa3:deaf:feed]/foo/') whatsnew/3.2,,:beef,"netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]'," @@ -277,8 +271,27 @@ whatsnew/3.2,,:feed,>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe: whatsnew/3.2,,:gz,">>> with tarfile.open(name='myarchive.tar.gz', mode='w:gz') as tf:" whatsnew/3.2,,:location,zope9-location = ${zope9:location} whatsnew/3.2,,:prefix,zope-conf = ${custom:prefix}/etc/zope.conf -whatsnew/changelog,,:platform,:platform: -whatsnew/changelog,,:PythonCmd,"With Tk < 8.5 _tkinter.c:PythonCmd() raised UnicodeDecodeError, caused" -whatsnew/changelog,,::,": Fix FTP tests for IPv6, bind to ""::1"" instead of ""localhost""." +whatsnew/changelog,,:gz,": TarFile opened with external fileobj and ""w:gz"" mode didn't" whatsnew/changelog,,::,": Use ""127.0.0.1"" or ""::1"" instead of ""localhost"" as much as" -whatsnew/changelog,,:password,user:password +library/tarfile,149,:xz,'x:xz' +library/xml.etree.elementtree,290,:sometag,prefix:sometag +library/xml.etree.elementtree,301,:fictional,"<actors xmlns:fictional=""http://characters.example.com/""" +library/xml.etree.elementtree,301,:character,<fictional:character>Lancelot</fictional:character> +library/xml.etree.elementtree,301,:character,<fictional:character>Archie Leach</fictional:character> +library/xml.etree.elementtree,301,:character,<fictional:character>Sir Robin</fictional:character> +library/xml.etree.elementtree,301,:character,<fictional:character>Gunther</fictional:character> +library/xml.etree.elementtree,301,:character,<fictional:character>Commander Clement</fictional:character> +library/xml.etree.elementtree,332,:actor,"for actor in root.findall('real_person:actor', ns):" +library/xml.etree.elementtree,332,:name,"name = actor.find('real_person:name', ns)" +library/xml.etree.elementtree,332,:character,"for char in actor.findall('role:character', ns):" +library/zipapp,31,:main,"$ python -m zipapp myapp -m ""myapp:main""" +library/zipapp,82,:fn,"argument should have the form ""pkg.mod:fn"", where ""pkg.mod"" is a" +library/zipapp,155,:callable,"""pkg.module:callable"" and the archive will be run by importing" +library/stdtypes,,::,>>> m[::2].tolist() +library/sys,,`,# ``wrapper`` creates a ``wrap(coro)`` coroutine: +tutorial/venv,77,:c7b9645a6f35,"Python 3.4.3+ (3.4:c7b9645a6f35+, May 22 2015, 09:31:25)" +whatsnew/3.5,,:root,'WARNING:root:warning\n' +whatsnew/3.5,,:warning,'WARNING:root:warning\n' +whatsnew/3.5,,::,>>> addr6 = ipaddress.IPv6Address('::1') +whatsnew/3.5,,:root,ERROR:root:exception +whatsnew/3.5,,:exception,ERROR:root:exception diff --git a/Doc/tools/sphinxext/download.html b/Doc/tools/templates/download.html similarity index 87% rename from Doc/tools/sphinxext/download.html rename to Doc/tools/templates/download.html index 31a53cfb3996..de84ae3abc81 100644 --- a/Doc/tools/sphinxext/download.html +++ b/Doc/tools/templates/download.html @@ -3,7 +3,7 @@ {% if daily is defined %} {% set dlbase = pathto('archives', 1) %} {% else %} - {% set dlbase = 'http://docs.python.org/ftp/python/doc/' + release %} + {% set dlbase = 'https://docs.python.org/ftp/python/doc/' + release %} {% endif %} {% block body %} @@ -34,15 +34,15 @@ <h1>Download Python {{ release }} Documentation</h1> <td><a href="http://github.com/%7B%7B%20dlbase%20%7D%7D/python-%7B%7B%20release%20%7D%7D-docs-text.tar.bz2">Download</a> (ca. 1.5 MB)</td> </tr> <tr><td>EPUB</td> - <td><a href="http://github.com/%7B%7B%20dlbase%20%7D%7D/python-%7B%7B%20release%20%7D%7D-docs-epub.zip">Download</a> (ca. 3.5 MB)</td> - <td><a href="http://github.com/%7B%7B%20dlbase%20%7D%7D/python-%7B%7B%20release%20%7D%7D-docs-epub.tar.bz2">Download</a> (ca. 3.5 MB)</td> + <td><a href="http://github.com/%7B%7B%20dlbase%20%7D%7D/python-%7B%7B%20release%20%7D%7D-docs.epub">Download</a> (ca. 4.5 MB)</td> + <td></td> </tr> </table> <p>These archives contain all the content in the documentation.</p> <p>HTML Help (<tt>.chm</tt>) files are made available in the "Windows" section -on the <a href="http://python.org/download/releases/%7B%7B%20release[:5]%20%7D%7D/">Python +on the <a href="https://www.python.org/download/releases/%7B%7B%20release[:5]%20%7D%7D/">Python download page</a>.</p> diff --git a/Doc/tools/sphinxext/indexcontent.html b/Doc/tools/templates/indexcontent.html similarity index 92% rename from Doc/tools/sphinxext/indexcontent.html rename to Doc/tools/templates/indexcontent.html index 7f8547020f1b..969099a00697 100644 --- a/Doc/tools/sphinxext/indexcontent.html +++ b/Doc/tools/templates/indexcontent.html @@ -16,14 +16,14 @@ <p class="biglink"><a class="biglink" href="http://github.com/%7B%7B%20pathto("howto/index") }}">Python HOWTOs</a><br/> <span class="linkdescr">in-depth documents on specific topics</span></p> </td><td width="50%"> + <p class="biglink"><a class="biglink" href="http://github.com/%7B%7B%20pathto("installing/index") }}">Installing Python Modules</a><br/> + <span class="linkdescr">installing from the Python Package Index & other sources</span></p> + <p class="biglink"><a class="biglink" href="http://github.com/%7B%7B%20pathto("distributing/index") }}">Distributing Python Modules</a><br/> + <span class="linkdescr">publishing modules for installation by others</span></p> <p class="biglink"><a class="biglink" href="http://github.com/%7B%7B%20pathto("extending/index") }}">Extending and Embedding</a><br/> <span class="linkdescr">tutorial for C/C++ programmers</span></p> <p class="biglink"><a class="biglink" href="http://github.com/%7B%7B%20pathto("c-api/index") }}">Python/C API</a><br/> <span class="linkdescr">reference for C/C++ programmers</span></p> - <p class="biglink"><a class="biglink" href="http://github.com/%7B%7B%20pathto("install/index") }}">Installing Python Modules</a><br/> - <span class="linkdescr">information for installers & sys-admins</span></p> - <p class="biglink"><a class="biglink" href="http://github.com/%7B%7B%20pathto("distutils/index") }}">Distributing Python Modules</a><br/> - <span class="linkdescr">sharing modules with others</span></p> <p class="biglink"><a class="biglink" href="http://github.com/%7B%7B%20pathto("faq/index") }}">FAQs</a><br/> <span class="linkdescr">frequently asked questions (with answers!)</span></p> </td></tr> diff --git a/Doc/tools/templates/indexsidebar.html b/Doc/tools/templates/indexsidebar.html new file mode 100644 index 000000000000..78e9c4f99ef0 --- /dev/null +++ b/Doc/tools/templates/indexsidebar.html @@ -0,0 +1,17 @@ +<h3>Download</h3> +<p><a href="http://github.com/%7B%7B%20pathto('download') }}">Download these documents</a></p> +<h3>Docs for other versions</h3> +<ul> + <li><a href="https://docs.python.org/2.7/">Python 2.7 (stable)</a></li> + <li><a href="https://docs.python.org/3.4/">Python 3.4 (stable)</a></li> + <li><a href="https://www.python.org/doc/versions/">Old versions</a></li> +</ul> + +<h3>Other resources</h3> +<ul> + {# XXX: many of these should probably be merged in the main docs #} + <li><a href="https://www.python.org/dev/peps/">PEP Index</a></li> + <li><a href="https://wiki.python.org/moin/BeginnersGuide">Beginner's Guide</a></li> + <li><a href="https://wiki.python.org/moin/PythonBooks">Book List</a></li> + <li><a href="https://www.python.org/doc/av/">Audio/Visual Talks</a></li> +</ul> diff --git a/Doc/tools/sphinxext/layout.html b/Doc/tools/templates/layout.html similarity index 92% rename from Doc/tools/sphinxext/layout.html rename to Doc/tools/templates/layout.html index 16a92128d8ec..5abff1b3989f 100644 --- a/Doc/tools/sphinxext/layout.html +++ b/Doc/tools/templates/layout.html @@ -2,7 +2,7 @@ {% block rootrellink %} <li><img src="http://github.com/%7B%7B%20pathto('_static/py.png', 1) }}" alt="" style="vertical-align: middle; margin-top: -1px"/></li> - <li><a href="http://www.python.org/">Python</a>{{ reldelim1 }}</li> + <li><a href="https://www.python.org/">Python</a>{{ reldelim1 }}</li> <li> {%- if versionswitcher is defined %} <span class="version_switcher_placeholder">{{ release }}</span> @@ -12,6 +12,8 @@ {%- endif %} </li> {% endblock %} +{% block relbar1 %} {% if builder != 'qthelp' %} {{ relbar() }} {% endif %} {% endblock %} +{% block relbar2 %} {% if builder != 'qthelp' %} {{ relbar() }} {% endif %} {% endblock %} {% block extrahead %} <link rel="shortcut icon" type="image/png" href="http://github.com/%7B%7B%20pathto('_static/py.png', 1) }}" /> {% if not embedded %}<script type="text/javascript" src="http://github.com/%7B%7B%20pathto('_static/copybutton.js', 1) }}"></script>{% endif %} @@ -80,7 +82,7 @@ © <a href="http://github.com/%7B%7B%20pathto('copyright') }}">Copyright</a> {{ copyright|e }}. <br /> The Python Software Foundation is a non-profit corporation. - <a href="http://www.python.org/psf/donations/">Please donate.</a> + <a href="https://www.python.org/psf/donations/">Please donate.</a> <br /> Last updated on {{ last_updated|e }}. <a href="http://github.com/%7B%7B%20pathto('bugs') }}">Found a bug</a>? diff --git a/Doc/tools/templates/opensearch.xml b/Doc/tools/templates/opensearch.xml new file mode 100644 index 000000000000..7a5cdddd2771 --- /dev/null +++ b/Doc/tools/templates/opensearch.xml @@ -0,0 +1,4 @@ +{% extends "!opensearch.xml" %} +{% block extra -%} +<Image height="16" width="16" type="image/x-icon">https://www.python.org/images/favicon16x16.ico</Image> +{%- endblock %} diff --git a/Doc/tutorial/appendix.rst b/Doc/tutorial/appendix.rst new file mode 100644 index 000000000000..e04459b2d990 --- /dev/null +++ b/Doc/tutorial/appendix.rst @@ -0,0 +1,124 @@ +.. _tut-appendix: + +******** +Appendix +******** + + +.. _tut-interac: + +Interactive Mode +================ + +.. _tut-error: + +Error Handling +-------------- + +When an error occurs, the interpreter prints an error message and a stack trace. +In interactive mode, it then returns to the primary prompt; when input came from +a file, it exits with a nonzero exit status after printing the stack trace. +(Exceptions handled by an :keyword:`except` clause in a :keyword:`try` statement +are not errors in this context.) Some errors are unconditionally fatal and +cause an exit with a nonzero exit; this applies to internal inconsistencies and +some cases of running out of memory. All error messages are written to the +standard error stream; normal output from executed commands is written to +standard output. + +Typing the interrupt character (usually :kbd:`Control-C` or :kbd:`Delete`) to the primary or +secondary prompt cancels the input and returns to the primary prompt. [#]_ +Typing an interrupt while a command is executing raises the +:exc:`KeyboardInterrupt` exception, which may be handled by a :keyword:`try` +statement. + + +.. _tut-scripts: + +Executable Python Scripts +------------------------- + +On BSD'ish Unix systems, Python scripts can be made directly executable, like +shell scripts, by putting the line :: + + #!/usr/bin/env python3.5 + +(assuming that the interpreter is on the user's :envvar:`PATH`) at the beginning +of the script and giving the file an executable mode. The ``#!`` must be the +first two characters of the file. On some platforms, this first line must end +with a Unix-style line ending (``'\n'``), not a Windows (``'\r\n'``) line +ending. Note that the hash, or pound, character, ``'#'``, is used to start a +comment in Python. + +The script can be given an executable mode, or permission, using the +:program:`chmod` command. + +.. code-block:: bash + + $ chmod +x myscript.py + +On Windows systems, there is no notion of an "executable mode". The Python +installer automatically associates ``.py`` files with ``python.exe`` so that +a double-click on a Python file will run it as a script. The extension can +also be ``.pyw``, in that case, the console window that normally appears is +suppressed. + + +.. _tut-startup: + +The Interactive Startup File +---------------------------- + +When you use Python interactively, it is frequently handy to have some standard +commands executed every time the interpreter is started. You can do this by +setting an environment variable named :envvar:`PYTHONSTARTUP` to the name of a +file containing your start-up commands. This is similar to the :file:`.profile` +feature of the Unix shells. + +This file is only read in interactive sessions, not when Python reads commands +from a script, and not when :file:`/dev/tty` is given as the explicit source of +commands (which otherwise behaves like an interactive session). It is executed +in the same namespace where interactive commands are executed, so that objects +that it defines or imports can be used without qualification in the interactive +session. You can also change the prompts ``sys.ps1`` and ``sys.ps2`` in this +file. + +If you want to read an additional start-up file from the current directory, you +can program this in the global start-up file using code like ``if +os.path.isfile('.pythonrc.py'): exec(open('.pythonrc.py').read())``. +If you want to use the startup file in a script, you must do this explicitly +in the script:: + + import os + filename = os.environ.get('PYTHONSTARTUP') + if filename and os.path.isfile(filename): + with open(filename) as fobj: + startup_file = fobj.read() + exec(startup_file) + + +.. _tut-customize: + +The Customization Modules +------------------------- + +Python provides two hooks to let you customize it: :mod:`sitecustomize` and +:mod:`usercustomize`. To see how it works, you need first to find the location +of your user site-packages directory. Start Python and run this code:: + + >>> import site + >>> site.getusersitepackages() + '/home/user/.local/lib/python3.5/site-packages' + +Now you can create a file named :file:`usercustomize.py` in that directory and +put anything you want in it. It will affect every invocation of Python, unless +it is started with the :option:`-s` option to disable the automatic import. + +:mod:`sitecustomize` works in the same way, but is typically created by an +administrator of the computer in the global site-packages directory, and is +imported before :mod:`usercustomize`. See the documentation of the :mod:`site` +module for more details. + + +.. rubric:: Footnotes + +.. [#] A problem with the GNU Readline package may prevent this. diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst index 08072a31a129..7e014eff38f3 100644 --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -387,6 +387,77 @@ object and the argument list, and the function object is called with this new argument list. +.. _tut-class-and-instance-variables: + +Class and Instance Variables +---------------------------- + +Generally speaking, instance variables are for data unique to each instance +and class variables are for attributes and methods shared by all instances +of the class:: + + class Dog: + + kind = 'canine' # class variable shared by all instances + + def __init__(self, name): + self.name = name # instance variable unique to each instance + + >>> d = Dog('Fido') + >>> e = Dog('Buddy') + >>> d.kind # shared by all dogs + 'canine' + >>> e.kind # shared by all dogs + 'canine' + >>> d.name # unique to d + 'Fido' + >>> e.name # unique to e + 'Buddy' + +As discussed in :ref:`tut-object`, shared data can have possibly surprising +effects with involving :term:`mutable` objects such as lists and dictionaries. +For example, the *tricks* list in the following code should not be used as a +class variable because just a single list would be shared by all *Dog* +instances:: + + class Dog: + + tricks = [] # mistaken use of a class variable + + def __init__(self, name): + self.name = name + + def add_trick(self, trick): + self.tricks.append(trick) + + >>> d = Dog('Fido') + >>> e = Dog('Buddy') + >>> d.add_trick('roll over') + >>> e.add_trick('play dead') + >>> d.tricks # unexpectedly shared by all dogs + ['roll over', 'play dead'] + +Correct design of the class should use an instance variable instead:: + + class Dog: + + def __init__(self, name): + self.name = name + self.tricks = [] # creates a new empty list for each dog + + def add_trick(self, trick): + self.tricks.append(trick) + + >>> d = Dog('Fido') + >>> e = Dog('Buddy') + >>> d.add_trick('roll over') + >>> e.add_trick('play dead') + >>> d.tricks + ['roll over'] + >>> e.tricks + ['play dead'] + + .. _tut-remarks: Random Remarks @@ -572,7 +643,7 @@ class, that calls each parent only once, and that is monotonic (meaning that a class can be subclassed without affecting the precedence order of its parents). Taken together, these properties make it possible to design reliable and extensible classes with multiple inheritance. For more detail, see -http://www.python.org/download/releases/2.3/mro/. +https://www.python.org/download/releases/2.3/mro/. .. _tut-private: @@ -731,7 +802,7 @@ using a :keyword:`for` statement:: for char in "123": print(char) for line in open("myfile.txt"): - print(line) + print(line, end='') This style of access is clear, concise, and convenient. The use of iterators pervades and unifies Python. Behind the scenes, the :keyword:`for` statement @@ -798,7 +869,7 @@ Generators :term:`Generator`\s are a simple and powerful tool for creating iterators. They are written like regular functions but use the :keyword:`yield` statement whenever they want to return data. Each time :func:`next` is called on it, the -generator resumes where it left-off (it remembers all the data values and which +generator resumes where it left off (it remembers all the data values and which statement was last executed). An example shows that generators can be trivially easy to create:: @@ -816,7 +887,7 @@ easy to create:: o g -Anything that can be done with generators can also be done with class based +Anything that can be done with generators can also be done with class-based iterators as described in the previous section. What makes generators so compact is that the :meth:`__iter__` and :meth:`~generator.__next__` methods are created automatically. diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index b1456ae57f9f..813c8285f850 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -370,7 +370,7 @@ defined to allow. For example:: return False retries = retries - 1 if retries < 0: - raise IOError('refusenik user') + raise OSError('uncooperative user') print(complaint) This function can be called in several ways: @@ -673,11 +673,9 @@ Function Annotations pair: function; annotations single: -> (return annotation assignment) -:ref:`Function annotations <function>` are completely optional, -arbitrary metadata information about user-defined functions. Neither Python -itself nor the standard library use function annotations in any way; this -section just shows the syntax. Third-party projects are free to use function -annotations for documentation, type checking, and other uses. +:ref:`Function annotations <function>` are completely optional metadata +information about the types used by user-defined functions (see :pep:`484` +for more information). Annotations are stored in the :attr:`__annotations__` attribute of the function as a dictionary and have no effect on any other part of the function. Parameter @@ -686,16 +684,17 @@ expression evaluating to the value of the annotation. Return annotations are defined by a literal ``->``, followed by an expression, between the parameter list and the colon denoting the end of the :keyword:`def` statement. The following example has a positional argument, a keyword argument, and the return -value annotated with nonsense:: +value annotated:: - >>> def f(ham: 42, eggs: int = 'spam') -> "Nothing to see here": + >>> def f(ham: str, eggs: str = 'eggs') -> str: ... print("Annotations:", f.__annotations__) ... print("Arguments:", ham, eggs) + ... return ham + ' and ' + eggs ... - >>> f('wonderful') - Annotations: {'eggs': <class 'int'>, 'return': 'Nothing to see here', 'ham': 42} - Arguments: wonderful spam - + >>> f('spam') + Annotations: {'ham': <class 'str'>, 'return': <class 'str'>, 'eggs': <class 'str'>} + Arguments: spam eggs + 'spam and eggs' .. _tut-codingstyle: @@ -756,4 +755,3 @@ extracted for you: .. [#] Actually, *call by object reference* would be a better description, since if a mutable object is passed, the caller will see any changes the callee makes to it (items inserted into a list). - diff --git a/Doc/tutorial/datastructures.rst b/Doc/tutorial/datastructures.rst index 24d2d2ec3aa3..0d51480177d8 100644 --- a/Doc/tutorial/datastructures.rst +++ b/Doc/tutorial/datastructures.rst @@ -73,10 +73,11 @@ objects: Return the number of times *x* appears in the list. -.. method:: list.sort() +.. method:: list.sort(key=None, reverse=False) :noindex: - Sort the items of the list in place. + Sort the items of the list in place (the arguments can be used for sort + customization, see :func:`sorted` for their explanation). .. method:: list.reverse() @@ -111,10 +112,15 @@ An example that uses most of the list methods:: >>> a.sort() >>> a [-1, 1, 66.25, 333, 333, 1234.5] + >>> a.pop() + 1234.5 + >>> a + [-1, 1, 66.25, 333, 333] You might have noticed that methods like ``insert``, ``remove`` or ``sort`` that -modify the list have no return value printed -- they return ``None``. [1]_ This -is a design principle for all mutable data structures in Python. +only modify the list have no return value printed -- they return the default +``None``. [1]_ This is a design principle for all mutable data structures in +Python. .. _tut-lists-as-stacks: @@ -194,12 +200,17 @@ For example, assume we want to create a list of squares, like:: >>> squares [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] -We can obtain the same result with:: +Note that this creates (or overwrites) a variable named ``x`` that still exists +after the loop completes. We can calculate the list of squares without any +side effects using:: + + squares = list(map(lambda x: x**2, range(10))) + +or, equivalently:: squares = [x**2 for x in range(10)] -This is also equivalent to ``squares = list(map(lambda x: x**2, range(10)))``, -but it's more concise and readable. +which is more concise and readable. A list comprehension consists of brackets containing an expression followed by a :keyword:`for` clause, then zero or more :keyword:`for` or :keyword:`if` @@ -601,18 +612,18 @@ returns a new sorted list while leaving the source unaltered. :: orange pear -To change a sequence you are iterating over while inside the loop (for -example to duplicate certain items), it is recommended that you first make -a copy. Looping over a sequence does not implicitly make a copy. The slice -notation makes this especially convenient:: +It is sometimes tempting to change a list while you are looping over it; +however, it is often simpler and safer to create a new list instead. :: - >>> words = ['cat', 'window', 'defenestrate'] - >>> for w in words[:]: # Loop over a slice copy of the entire list. - ... if len(w) > 6: - ... words.insert(0, w) + >>> import math + >>> raw_data = [56.2, float('NaN'), 51.7, 55.3, 52.5, float('NaN'), 47.8] + >>> filtered_data = [] + >>> for value in raw_data: + ... if not math.isnan(value): + ... filtered_data.append(value) ... - >>> words - ['defenestrate', 'cat', 'window', 'defenestrate'] + >>> filtered_data + [56.2, 51.7, 55.3, 52.5, 47.8] .. _tut-conditions: @@ -674,7 +685,7 @@ the same type, the lexicographical comparison is carried out recursively. If all items of two sequences compare equal, the sequences are considered equal. If one sequence is an initial sub-sequence of the other, the shorter sequence is the smaller (lesser) one. Lexicographical ordering for strings uses the Unicode -codepoint number to order individual characters. Some examples of comparisons +code point number to order individual characters. Some examples of comparisons between sequences of the same type:: (1, 2, 3) < (1, 2, 4) diff --git a/Doc/tutorial/errors.rst b/Doc/tutorial/errors.rst index 4282151589a0..d048ae9e1090 100644 --- a/Doc/tutorial/errors.rst +++ b/Doc/tutorial/errors.rst @@ -131,8 +131,8 @@ the exception (allowing a caller to handle the exception as well):: f = open('myfile.txt') s = f.readline() i = int(s.strip()) - except IOError as err: - print("I/O error: {0}".format(err)) + except OSError as err: + print("OS error: {0}".format(err)) except ValueError: print("Could not convert data to an integer.") except: diff --git a/Doc/tutorial/index.rst b/Doc/tutorial/index.rst index 604cff8af874..8ee011e2827e 100644 --- a/Doc/tutorial/index.rst +++ b/Doc/tutorial/index.rst @@ -12,7 +12,7 @@ and rapid application development in many areas on most platforms. The Python interpreter and the extensive standard library are freely available in source or binary form for all major platforms from the Python Web site, -http://www.python.org/, and may be freely distributed. The same site also +https://www.python.org/, and may be freely distributed. The same site also contains distributions of and pointers to many free third party Python modules, programs and tools, and additional documentation. @@ -53,6 +53,8 @@ The :ref:`glossary` is also worth going through. classes.rst stdlib.rst stdlib2.rst + venv.rst whatnow.rst interactive.rst floatingpoint.rst + appendix.rst diff --git a/Doc/tutorial/inputoutput.rst b/Doc/tutorial/inputoutput.rst index 7daf89b79bf0..c157f22e6c3e 100644 --- a/Doc/tutorial/inputoutput.rst +++ b/Doc/tutorial/inputoutput.rst @@ -247,8 +247,9 @@ writing. The *mode* argument is optional; ``'r'`` will be assumed if it's omitted. Normally, files are opened in :dfn:`text mode`, that means, you read and write -strings from and to the file, which are encoded in a specific encoding (the -default being UTF-8). ``'b'`` appended to the mode opens the file in +strings from and to the file, which are encoded in a specific encoding. If +encoding is not specified, the default is platform dependent (see +:func:`open`). ``'b'`` appended to the mode opens the file in :dfn:`binary mode`: now the data is read and written in the form of bytes objects. This mode should be used for all files that don't contain text. @@ -323,8 +324,8 @@ first:: 18 ``f.tell()`` returns an integer giving the file object's current position in the file -represented as number of bytes from the beginning of the file when in `binary mode` and -an opaque number when in `text mode`. +represented as number of bytes from the beginning of the file when in binary mode and +an opaque number when in text mode. To change the file object's position, use ``f.seek(offset, from_what)``. The position is computed from adding *offset* to a reference point; the reference point is selected by @@ -377,47 +378,63 @@ File objects have some additional methods, such as :meth:`~file.isatty` and Reference for a complete guide to file objects. -.. _tut-pickle: +.. _tut-json: -The :mod:`pickle` Module ------------------------- +Saving structured data with :mod:`json` +--------------------------------------- -.. index:: module: pickle +.. index:: module: json -Strings can easily be written to and read from a file. Numbers take a bit more +Strings can easily be written to and read from a file. Numbers take a bit more effort, since the :meth:`read` method only returns strings, which will have to be passed to a function like :func:`int`, which takes a string like ``'123'`` -and returns its numeric value 123. However, when you want to save more complex -data types like lists, dictionaries, or class instances, things get a lot more -complicated. - -Rather than have users be constantly writing and debugging code to save -complicated data types, Python provides a standard module called :mod:`pickle`. -This is an amazing module that can take almost any Python object (even some -forms of Python code!), and convert it to a string representation; this process -is called :dfn:`pickling`. Reconstructing the object from the string -representation is called :dfn:`unpickling`. Between pickling and unpickling, -the string representing the object may have been stored in a file or data, or +and returns its numeric value 123. When you want to save more complex data +types like nested lists and dictionaries, parsing and serializing by hand +becomes complicated. + +Rather than having users constantly writing and debugging code to save +complicated data types to files, Python allows you to use the popular data +interchange format called `JSON (JavaScript Object Notation) +<http://json.org>`_. The standard module called :mod:`json` can take Python +data hierarchies, and convert them to string representations; this process is +called :dfn:`serializing`. Reconstructing the data from the string representation +is called :dfn:`deserializing`. Between serializing and deserializing, the +string representing the object may have been stored in a file or data, or sent over a network connection to some distant machine. -If you have an object ``x``, and a file object ``f`` that's been opened for -writing, the simplest way to pickle the object takes only one line of code:: +.. note:: + The JSON format is commonly used by modern applications to allow for data + exchange. Many programmers are already familiar with it, which makes + it a good choice for interoperability. - pickle.dump(x, f) +If you have an object ``x``, you can view its JSON string representation with a +simple line of code:: -To unpickle the object again, if ``f`` is a file object which has been opened -for reading:: + >>> json.dumps([1, 'simple', 'list']) + '[1, "simple", "list"]' - x = pickle.load(f) +Another variant of the :func:`~json.dumps` function, called :func:`~json.dump`, +simply serializes the object to a :term:`text file`. So if ``f`` is a +:term:`text file` object opened for writing, we can do this:: -(There are other variants of this, used when pickling many objects or when you -don't want to write the pickled data to a file; consult the complete -documentation for :mod:`pickle` in the Python Library Reference.) + json.dump(x, f) -:mod:`pickle` is the standard way to make Python objects which can be stored and -reused by other programs or by a future invocation of the same program; the -technical term for this is a :dfn:`persistent` object. Because :mod:`pickle` is -so widely used, many authors who write Python extensions take care to ensure -that new data types such as matrices can be properly pickled and unpickled. +To decode the object again, if ``f`` is a :term:`text file` object which has +been opened for reading:: + x = json.load(f) +This simple serialization technique can handle lists and dictionaries, but +serializing arbitrary class instances in JSON requires a bit of extra effort. +The reference for the :mod:`json` module contains an explanation of this. + +.. seealso:: + + :mod:`pickle` - the pickle module + + Contrary to :ref:`JSON <tut-json>`, *pickle* is a protocol which allows + the serialization of arbitrarily complex Python objects. As such, it is + specific to Python and cannot be used to communicate with applications + written in other languages. It is also insecure by default: + deserializing pickle data coming from an untrusted source can execute + arbitrary code, if the data was crafted by a skilled attacker. diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst index c182511ada3b..215af037da3e 100644 --- a/Doc/tutorial/interpreter.rst +++ b/Doc/tutorial/interpreter.rst @@ -1,4 +1,4 @@ -.. _tut-using: +3.6.. _tut-using: **************************** Using the Python Interpreter @@ -10,13 +10,13 @@ Using the Python Interpreter Invoking the Interpreter ======================== -The Python interpreter is usually installed as :file:`/usr/local/bin/python3.4` +The Python interpreter is usually installed as :file:`/usr/local/bin/python3.6` on those machines where it is available; putting :file:`/usr/local/bin` in your Unix shell's search path makes it possible to start it by typing the command: .. code-block:: text - python3.4 + python3.6 to the shell. [#]_ Since the choice of the directory where the interpreter lives is an installation option, other places are possible; check with your local @@ -24,26 +24,25 @@ Python guru or system administrator. (E.g., :file:`/usr/local/python` is a popular alternative location.) On Windows machines, the Python installation is usually placed in -:file:`C:\\Python34`, though you can change this when you're running the +:file:`C:\\Python36`, though you can change this when you're running the installer. To add this directory to your path, you can type the following command into the command prompt in a DOS box:: - set path=%path%;C:\python34 + set path=%path%;C:\python36 Typing an end-of-file character (:kbd:`Control-D` on Unix, :kbd:`Control-Z` on Windows) at the primary prompt causes the interpreter to exit with a zero exit status. If that doesn't work, you can exit the interpreter by typing the following command: ``quit()``. -The interpreter's line-editing features usually aren't very sophisticated. On -Unix, whoever installed the interpreter may have enabled support for the GNU -readline library, which adds more elaborate interactive editing and history -features. Perhaps the quickest check to see whether command line editing is -supported is typing Control-P to the first Python prompt you get. If it beeps, -you have command line editing; see Appendix :ref:`tut-interacting` for an -introduction to the keys. If nothing appears to happen, or if ``^P`` is echoed, -command line editing isn't available; you'll only be able to use backspace to -remove characters from the current line. +The interpreter's line-editing features include interactive editing, history +substitution and code completion on systems that support readline. Perhaps the +quickest check to see whether command line editing is supported is typing +:kbd:`Control-P` to the first Python prompt you get. If it beeps, you have command +line editing; see Appendix :ref:`tut-interacting` for an introduction to the +keys. If nothing appears to happen, or if ``^P`` is echoed, command line +editing isn't available; you'll only be able to use backspace to remove +characters from the current line. The interpreter operates somewhat like the Unix shell: when called with standard input connected to a tty device, it reads and executes commands interactively; @@ -64,6 +63,8 @@ When a script file is used, it is sometimes useful to be able to run the script and enter interactive mode afterwards. This can be done by passing :option:`-i` before the script. +All command line options are described in :ref:`using-on-general`. + .. _tut-argpassing: @@ -95,9 +96,9 @@ with the *secondary prompt*, by default three dots (``...``). The interpreter prints a welcome message stating its version number and a copyright notice before printing the first prompt:: - $ python3.4 - Python 3.4 (default, Sep 24 2012, 09:25:04) - [GCC 4.6.3] on linux2 + $ python3.6 + Python 3.6 (default, Sep 16 2015, 09:25:04) + [GCC 4.8.2] on linux Type "help", "copyright", "credits" or "license" for more information. >>> @@ -106,70 +107,22 @@ before printing the first prompt:: Continuation lines are needed when entering a multi-line construct. As an example, take a look at this :keyword:`if` statement:: - >>> the_world_is_flat = 1 + >>> the_world_is_flat = True >>> if the_world_is_flat: ... print("Be careful not to fall off!") ... Be careful not to fall off! +For more on interactive mode, see :ref:`tut-interac`. + + .. _tut-interp: The Interpreter and Its Environment =================================== -.. _tut-error: - -Error Handling --------------- - -When an error occurs, the interpreter prints an error message and a stack trace. -In interactive mode, it then returns to the primary prompt; when input came from -a file, it exits with a nonzero exit status after printing the stack trace. -(Exceptions handled by an :keyword:`except` clause in a :keyword:`try` statement -are not errors in this context.) Some errors are unconditionally fatal and -cause an exit with a nonzero exit; this applies to internal inconsistencies and -some cases of running out of memory. All error messages are written to the -standard error stream; normal output from executed commands is written to -standard output. - -Typing the interrupt character (usually Control-C or DEL) to the primary or -secondary prompt cancels the input and returns to the primary prompt. [#]_ -Typing an interrupt while a command is executing raises the -:exc:`KeyboardInterrupt` exception, which may be handled by a :keyword:`try` -statement. - - -.. _tut-scripts: - -Executable Python Scripts -------------------------- - -On BSD'ish Unix systems, Python scripts can be made directly executable, like -shell scripts, by putting the line :: - - #! /usr/bin/env python3.4 - -(assuming that the interpreter is on the user's :envvar:`PATH`) at the beginning -of the script and giving the file an executable mode. The ``#!`` must be the -first two characters of the file. On some platforms, this first line must end -with a Unix-style line ending (``'\n'``), not a Windows (``'\r\n'``) line -ending. Note that the hash, or pound, character, ``'#'``, is used to start a -comment in Python. - -The script can be given an executable mode, or permission, using the -:program:`chmod` command:: - - $ chmod +x myscript.py - -On Windows systems, there is no notion of an "executable mode". The Python -installer automatically associates ``.py`` files with ``python.exe`` so that -a double-click on a Python file will run it as a script. The extension can -also be ``.pyw``, in that case, the console window that normally appears is -suppressed. - - .. _tut-source-encoding: Source Code Encoding @@ -203,67 +156,8 @@ files. The special encoding comment must be in the *first or second* line within the file. -.. _tut-startup: - -The Interactive Startup File ----------------------------- - -When you use Python interactively, it is frequently handy to have some standard -commands executed every time the interpreter is started. You can do this by -setting an environment variable named :envvar:`PYTHONSTARTUP` to the name of a -file containing your start-up commands. This is similar to the :file:`.profile` -feature of the Unix shells. - -.. XXX This should probably be dumped in an appendix, since most people - don't use Python interactively in non-trivial ways. - -This file is only read in interactive sessions, not when Python reads commands -from a script, and not when :file:`/dev/tty` is given as the explicit source of -commands (which otherwise behaves like an interactive session). It is executed -in the same namespace where interactive commands are executed, so that objects -that it defines or imports can be used without qualification in the interactive -session. You can also change the prompts ``sys.ps1`` and ``sys.ps2`` in this -file. - -If you want to read an additional start-up file from the current directory, you -can program this in the global start-up file using code like ``if -os.path.isfile('.pythonrc.py'): exec(open('.pythonrc.py').read())``. -If you want to use the startup file in a script, you must do this explicitly -in the script:: - - import os - filename = os.environ.get('PYTHONSTARTUP') - if filename and os.path.isfile(filename): - exec(open(filename).read()) - - -.. _tut-customize: - -The Customization Modules -------------------------- - -Python provides two hooks to let you customize it: :mod:`sitecustomize` and -:mod:`usercustomize`. To see how it works, you need first to find the location -of your user site-packages directory. Start Python and run this code: - - >>> import site - >>> site.getusersitepackages() - '/home/user/.local/lib/python3.2/site-packages' - -Now you can create a file named :file:`usercustomize.py` in that directory and -put anything you want in it. It will affect every invocation of Python, unless -it is started with the :option:`-s` option to disable the automatic import. - -:mod:`sitecustomize` works in the same way, but is typically created by an -administrator of the computer in the global site-packages directory, and is -imported before :mod:`usercustomize`. See the documentation of the :mod:`site` -module for more details. - - .. rubric:: Footnotes .. [#] On Unix, the Python 3.x interpreter is by default not installed with the executable named ``python``, so that it does not conflict with a simultaneously installed Python 2.x executable. - -.. [#] A problem with the GNU Readline package may prevent this. diff --git a/Doc/tutorial/introduction.rst b/Doc/tutorial/introduction.rst index 4101cdc777e0..531d06b4cb22 100644 --- a/Doc/tutorial/introduction.rst +++ b/Doc/tutorial/introduction.rst @@ -1,4 +1,4 @@ -.. _tut-informal: +.. _tut-informal: ********************************** An Informal Introduction to Python @@ -58,7 +58,7 @@ For example:: The integer numbers (e.g. ``2``, ``4``, ``20``) have type :class:`int`, the ones with a fractional part (e.g. ``5.0``, ``1.6``) have type -:class:`float`. We will see more about numberic types later in the tutorial. +:class:`float`. We will see more about numeric types later in the tutorial. Division (``/``) always returns a float. To do :term:`floor division` and get an integer result (discarding any fractional result) you can use the ``//`` @@ -74,7 +74,7 @@ operator; to calculate the remainder you can use ``%``:: >>> 5 * 3 + 2 # result * divisor + remainder 17 -With Python is possible to use the ``**`` operator to calculate powers [#]_:: +With Python, it is possible to use the ``**`` operator to calculate powers [#]_:: >>> 5 ** 2 # 5 squared 25 @@ -305,7 +305,7 @@ indices, if both are within bounds. For example, the length of ``word[1:3]`` is Attempting to use a index that is too large will result in an error:: - >>> word[42] # the word only has 7 characters + >>> word[42] # the word only has 6 characters Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: string index out of range @@ -371,9 +371,9 @@ values. The most versatile is the *list*, which can be written as a list of comma-separated values (items) between square brackets. Lists might contain items of different types, but usually the items all have the same type. :: - >>> squares = [1, 2, 4, 9, 16, 25] + >>> squares = [1, 4, 9, 16, 25] >>> squares - [1, 2, 4, 9, 16, 25] + [1, 4, 9, 16, 25] Like strings (and all other built-in :term:`sequence` type), lists can be indexed and sliced:: @@ -389,12 +389,12 @@ All slice operations return a new list containing the requested elements. This means that the following slice returns a new (shallow) copy of the list:: >>> squares[:] - [1, 2, 4, 9, 16, 25] + [1, 4, 9, 16, 25] -Lists also supports operations like concatenation:: +Lists also support operations like concatenation:: >>> squares + [36, 49, 64, 81, 100] - [1, 2, 4, 9, 16, 25, 36, 49, 64, 81, 100] + [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] Unlike strings, which are :term:`immutable`, lists are a :term:`mutable` type, i.e. it is possible to change their content:: diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst index 94a66ac698d7..9ae64b0cf7e2 100644 --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -165,10 +165,16 @@ a built-in module with that name. If not found, it then searches for a file named :file:`spam.py` in a list of directories given by the variable :data:`sys.path`. :data:`sys.path` is initialized from these locations: -* the directory containing the input script (or the current directory). +* The directory containing the input script (or the current directory when no + file is specified). * :envvar:`PYTHONPATH` (a list of directory names, with the same syntax as the shell variable :envvar:`PATH`). -* the installation-dependent default. +* The installation-dependent default. + +.. note:: + On file systems which support symlinks, the directory containing the input + script is calculated after the symlink is followed. In other words the + directory containing the symlink is **not** added to the module search path. After initialization, Python programs can modify :data:`sys.path`. The directory containing the script being run is placed at the beginning of the @@ -210,15 +216,15 @@ Some tips for experts: statements, the ``-OO`` switch removes both assert statements and __doc__ strings. Since some programs may rely on having these available, you should only use this option if you know what you're doing. "Optimized" modules have - a .pyo rather than a .pyc suffix and are usually smaller. Future releases may + an ``opt-`` tag and are usually smaller. Future releases may change the effects of optimization. -* A program doesn't run any faster when it is read from a ``.pyc`` or ``.pyo`` +* A program doesn't run any faster when it is read from a ``.pyc`` file than when it is read from a ``.py`` file; the only thing that's faster - about ``.pyc`` or ``.pyo`` files is the speed with which they are loaded. + about ``.pyc`` files is the speed with which they are loaded. -* The module :mod:`compileall` can create .pyc files (or .pyo files when - :option:`-O` is used) for all modules in a directory. +* The module :mod:`compileall` can create .pyc files for all modules in a + directory. * There is more detail on this process, including a flow chart of the decisions, in PEP 3147. @@ -542,4 +548,3 @@ modules found in a package. .. [#] In fact function definitions are also 'statements' that are 'executed'; the execution of a module-level function definition enters the function name in the module's global symbol table. - diff --git a/Doc/tutorial/stdlib.rst b/Doc/tutorial/stdlib.rst index 2e3ed181d0e4..f9ed46d72d3d 100644 --- a/Doc/tutorial/stdlib.rst +++ b/Doc/tutorial/stdlib.rst @@ -15,7 +15,7 @@ operating system:: >>> import os >>> os.getcwd() # Return the current working directory - 'C:\\Python34' + 'C:\\Python36' >>> os.chdir('/server/accesslogs') # Change current working directory >>> os.system('mkdir today') # Run the command mkdir in the system shell 0 @@ -40,7 +40,9 @@ a higher level interface that is easier to use:: >>> import shutil >>> shutil.copyfile('data.db', 'archive.db') + 'archive.db' >>> shutil.move('/build/executables', 'installdir') + 'installdir' .. _tut-file-wildcards: @@ -138,6 +140,18 @@ The :mod:`random` module provides tools for making random selections:: >>> random.randrange(6) # random integer chosen from range(6) 4 +The :mod:`statistics` module calculates basic statistical properties +(the mean, median, variance, etc.) of numeric data:: + + >>> import statistics + >>> data = [2.75, 1.75, 1.25, 0.25, 0.5, 1.25, 3.5] + >>> statistics.mean(data) + 1.6071428571428572 + >>> statistics.median(data) + 1.25 + >>> statistics.variance(data) + 1.3720238095238095 + The SciPy project <http://scipy.org> has many other modules for numerical computations. @@ -151,10 +165,11 @@ protocols. Two of the simplest are :mod:`urllib.request` for retrieving data from URLs and :mod:`smtplib` for sending mail:: >>> from urllib.request import urlopen - >>> for line in urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'): - ... line = line.decode('utf-8') # Decoding the binary data to text. - ... if 'EST' in line or 'EDT' in line: # look for Eastern Time - ... print(line) + >>> with urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl') as response: + ... for line in response: + ... line = line.decode('utf-8') # Decoding the binary data to text. + ... if 'EST' in line or 'EDT' in line: # look for Eastern Time + ... print(line) <BR>Nov. 25, 09:43:32 PM EST @@ -308,13 +323,18 @@ sophisticated and robust capabilities of its larger packages. For example: (including attachments) and for implementing internet encoding and header protocols. -* The :mod:`xml.dom` and :mod:`xml.sax` packages provide robust support for - parsing this popular data interchange format. Likewise, the :mod:`csv` module - supports direct reads and writes in a common database format. Together, these - modules and packages greatly simplify data interchange between Python - applications and other tools. +* The :mod:`json` package provides robust support for parsing this + popular data interchange format. The :mod:`csv` module supports + direct reading and writing of files in Comma-Separated Value format, + commonly supported by databases and spreadsheets. XML processing is + supported by the :mod:`xml.etree.ElementTree`, :mod:`xml.dom` and + :mod:`xml.sax` packages. Together, these modules and packages + greatly simplify data interchange between Python applications and + other tools. + +* The :mod:`sqlite3` module is a wrapper for the SQLite database + library, providing a persistent database that can be updated and + accessed using slightly nonstandard SQL syntax. * Internationalization is supported by a number of modules including :mod:`gettext`, :mod:`locale`, and the :mod:`codecs` package. - - diff --git a/Doc/tutorial/stdlib2.rst b/Doc/tutorial/stdlib2.rst index c0197ea5ef8c..71194b04769f 100644 --- a/Doc/tutorial/stdlib2.rst +++ b/Doc/tutorial/stdlib2.rst @@ -18,7 +18,7 @@ abbreviated displays of large or deeply nested containers:: >>> import reprlib >>> reprlib.repr(set('supercalifragilisticexpialidocious')) - "set(['a', 'c', 'd', 'e', 'f', 'g', ...])" + "{'a', 'c', 'd', 'e', 'f', 'g', ...}" The :mod:`pprint` module offers more sophisticated control over printing both built-in and user defined objects in a way that is readable by the interpreter. @@ -277,7 +277,7 @@ applications include caching objects that are expensive to create:: Traceback (most recent call last): File "<stdin>", line 1, in <module> d['primary'] # entry was automatically removed - File "C:/python34/lib/weakref.py", line 46, in __getitem__ + File "C:/python36/lib/weakref.py", line 46, in __getitem__ o = self.data[key]() KeyError: 'primary' diff --git a/Doc/tutorial/venv.rst b/Doc/tutorial/venv.rst new file mode 100644 index 000000000000..3b2ee2e24c8d --- /dev/null +++ b/Doc/tutorial/venv.rst @@ -0,0 +1,197 @@ + +.. _tut-venv: + +********************************* +Virtual Environments and Packages +********************************* + +Introduction +============ + +Python applications will often use packages and modules that don't +come as part of the standard library. Applications will sometimes +need a specific version of a library, because the application may +require that a particular bug has been fixed or the application may be +written using an obsolete version of the library's interface. + +This means it may not be possible for one Python installation to meet +the requirements of every application. If application A needs version +1.0 of a particular module but application B needs version 2.0, then +the requirements are in conflict and installing either version 1.0 or 2.0 +will leave one application unable to run. + +The solution for this problem is to create a :term:`virtual +environment` (often shortened to "virtualenv"), a self-contained +directory tree that contains a Python installation for a particular +version of Python, plus a number of additional packages. + +Different applications can then use different virtual environments. +To resolve the earlier example of conflicting requirements, +application A can have its own virtual environment with version 1.0 +installed while application B has another virtualenv with version 2.0. +If application B requires a library be upgraded to version 3.0, this will +not affect application A's environment. + + +Creating Virtual Environments +============================= + +The script used to create and manage virtual environments is called +:program:`pyvenv`. :program:`pyvenv` will usually install the most +recent version of Python that you have available; the script is also +installed with a version number, so if you have multiple versions of +Python on your system you can select a specific Python version by +running ``pyvenv-3.4`` or whichever version you want. + +To create a virtualenv, decide upon a directory +where you want to place it and run :program:`pyvenv` with the +directory path:: + + pyvenv tutorial-env + +This will create the ``tutorial-env`` directory if it doesn't exist, +and also create directories inside it containing a copy of the Python +interpreter, the standard library, and various supporting files. + +Once you've created a virtual environment, you need to +activate it. + +On Windows, run:: + + tutorial-env/Scripts/activate + +On Unix or MacOS, run:: + + source tutorial-env/bin/activate + +(This script is written for the bash shell. If you use the +:program:`csh` or :program:`fish` shells, there are alternate +``activate.csh`` and ``activate.fish`` scripts you should use +instead.) + +Activating the virtualenv will change your shell's prompt to show what +virtualenv you're using, and modify the environment so that running +``python`` will get you that particular version and installation of +Python. For example:: + + -> source ~/envs/tutorial-env/bin/activate + (tutorial-env) -> python + Python 3.4.3+ (3.4:c7b9645a6f35+, May 22 2015, 09:31:25) + ... + >>> import sys + >>> sys.path + ['', '/usr/local/lib/python34.zip', ..., + '~/envs/tutorial-env/lib/python3.4/site-packages'] + >>> + + +Managing Packages with pip +========================== + +Once you've activated a virtual environment, you can install, upgrade, +and remove packages using a program called :program:`pip`. By default +``pip`` will install packages from the Python Package Index, +<https://pypi.python.org/pypi>. You can browse the Python Package Index +by going to it in your web browser, or you can use ``pip``'s +limited search feature:: + + (tutorial-env) -> pip search astronomy + skyfield - Elegant astronomy for Python + gary - Galactic astronomy and gravitational dynamics. + novas - The United States Naval Observatory NOVAS astronomy library + astroobs - Provides astronomy ephemeris to plan telescope observations + PyAstronomy - A collection of astronomy related tools for Python. + ... + +``pip`` has a number of subcommands: "search", "install", "uninstall", +"freeze", etc. (Consult the :ref:`installing-index` guide for +complete documentation for ``pip``.) + +You can install the latest version of a package by specifying a package's name:: + + -> pip install novas + Collecting novas + Downloading novas-3.1.1.3.tar.gz (136kB) + Installing collected packages: novas + Running setup.py install for novas + Successfully installed novas-3.1.1.3 + +You can also install a specific version of a package by giving the +package name followed by ``==`` and the version number:: + + -> pip install requests==2.6.0 + Collecting requests==2.6.0 + Using cached requests-2.6.0-py2.py3-none-any.whl + Installing collected packages: requests + Successfully installed requests-2.6.0 + +If you re-run this command, ``pip`` will notice that the requested +version is already installed and do nothing. You can supply a +different version number to get that version, or you can run ``pip +install --upgrade`` to upgrade the package to the latest version:: + + -> pip install --upgrade requests + Collecting requests + Installing collected packages: requests + Found existing installation: requests 2.6.0 + Uninstalling requests-2.6.0: + Successfully uninstalled requests-2.6.0 + Successfully installed requests-2.7.0 + +``pip uninstall`` followed by one or more package names will remove the +packages from the virtual environment. + +``pip show`` will display information about a particular package:: + + (tutorial-env) -> pip show requests + --- + Metadata-Version: 2.0 + Name: requests + Version: 2.7.0 + Summary: Python HTTP for Humans. + Home-page: http://python-requests.org + Author: Kenneth Reitz + Author-email: me@kennethreitz.com + License: Apache 2.0 + Location: /Users/akuchling/envs/tutorial-env/lib/python3.4/site-packages + Requires: + +``pip list`` will display all of the packages installed in the virtual +environment:: + + (tutorial-env) -> pip list + novas (3.1.1.3) + numpy (1.9.2) + pip (7.0.3) + requests (2.7.0) + setuptools (16.0) + +``pip freeze`` will produce a similar list of the installed packages, +but the output uses the format that ``pip install`` expects. +A common convention is to put this list in a ``requirements.txt`` file:: + + (tutorial-env) -> pip freeze > requirements.txt + (tutorial-env) -> cat requirements.txt + novas==3.1.1.3 + numpy==1.9.2 + requests==2.7.0 + +The ``requirements.txt`` can then be committed to version control and +shipped as part of an application. Users can then install all the +necessary packages with ``install -r``:: + + -> pip install -r requirements.txt + Collecting novas==3.1.1.3 (from -r requirements.txt (line 1)) + ... + Collecting numpy==1.9.2 (from -r requirements.txt (line 2)) + ... + Collecting requests==2.7.0 (from -r requirements.txt (line 3)) + ... + Installing collected packages: novas, numpy, requests + Running setup.py install for novas + Successfully installed novas-3.1.1.3 numpy-1.9.2 requests-2.7.0 + +``pip`` has many more options. Consult the :ref:`installing-index` +guide for complete documentation for ``pip``. When you've written +a package and want to make it available on the Python Package Index, +consult the :ref:`distributing-index` guide. diff --git a/Doc/tutorial/whatnow.rst b/Doc/tutorial/whatnow.rst index 7fcbdc3f4486..479542c17298 100644 --- a/Doc/tutorial/whatnow.rst +++ b/Doc/tutorial/whatnow.rst @@ -21,8 +21,8 @@ the set are: and many other tasks. Skimming through the Library Reference will give you an idea of what's available. -* :ref:`install-index` explains how to install external modules written by other - Python users. +* :ref:`installing-index` explains how to install additional modules written + by other Python users. * :ref:`reference-index`: A detailed explanation of Python's syntax and semantics. It's heavy reading, but is useful as a complete guide to the @@ -30,24 +30,27 @@ the set are: More Python resources: -* http://www.python.org: The major Python Web site. It contains code, +* https://www.python.org: The major Python Web site. It contains code, documentation, and pointers to Python-related pages around the Web. This Web site is mirrored in various places around the world, such as Europe, Japan, and Australia; a mirror may be faster than the main site, depending on your geographical location. -* http://docs.python.org: Fast access to Python's documentation. +* https://docs.python.org: Fast access to Python's documentation. -* http://pypi.python.org: The Python Package Index, previously also nicknamed +* https://pypi.python.org/pypi: The Python Package Index, previously also nicknamed the Cheese Shop, is an index of user-created Python modules that are available for download. Once you begin releasing code, you can register it here so that others can find it. -* http://aspn.activestate.com/ASPN/Python/Cookbook/: The Python Cookbook is a +* http://code.activestate.com/recipes/langs/python/: The Python Cookbook is a sizable collection of code examples, larger modules, and useful scripts. Particularly notable contributions are collected in a book also titled Python Cookbook (O'Reilly & Associates, ISBN 0-596-00797-3.) +* http://www.pyvideo.org collects links to Python-related videos from + conferences and user-group meetings. + * http://scipy.org: The Scientific Python project includes modules for fast array computations and manipulations plus a host of packages for such things as linear algebra, Fourier transforms, non-linear solvers, @@ -57,14 +60,11 @@ For Python-related questions and problem reports, you can post to the newsgroup :newsgroup:`comp.lang.python`, or send them to the mailing list at python-list@python.org. The newsgroup and mailing list are gatewayed, so messages posted to one will automatically be forwarded to the other. There are -around 120 postings a day (with peaks up to several hundred), asking (and +hundreds of postings a day, asking (and answering) questions, suggesting new features, and announcing new modules. -Before posting, be sure to check the list of :ref:`Frequently Asked Questions -<faq-index>` (also called the FAQ). -Mailing list archives are available at http://mail.python.org/pipermail/. -The FAQ answers many of the questions that come up again and again, -and may already contain the solution for your problem. - -.. Postings figure based on average of last six months activity as - reported by www.egroups.com; Jan. 2000 - June 2000: 21272 msgs / 182 - days = 116.9 msgs / day and steadily increasing. (XXX up to date figures?) +Mailing list archives are available at https://mail.python.org/pipermail/. + +Before posting, be sure to check the list of +:ref:`Frequently Asked Questions <faq-index>` (also called the FAQ). The +FAQ answers many of the questions that come up again and again, and may +already contain the solution for your problem. diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index d1822fb2da62..c7210a01346b 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -1,7 +1,7 @@ -.. highlightlang:: none +.. highlightlang:: sh .. ATTENTION: You probably should update Misc/python.man, too, if you modify -.. this file. + this file. .. _using-on-general: @@ -41,7 +41,7 @@ additional methods of invocation: * When called with standard input connected to a tty device, it prompts for commands and executes them until an EOF (an end-of-file character, you can - produce that with *Ctrl-D* on UNIX or *Ctrl-Z, Enter* on Windows) is read. + produce that with :kbd:`Ctrl-D` on UNIX or :kbd:`Ctrl-Z, Enter` on Windows) is read. * When called with a file name argument or with a file as standard input, it reads and executes a script from that file. * When called with a directory name argument, it reads and executes an @@ -81,7 +81,8 @@ source. the implementation may not always enforce this (e.g. it may allow you to use a name that includes a hyphen). - Package names are also permitted. When a package name is supplied instead + Package names (including namespace packages) are also permitted. When a + package name is supplied instead of a normal module, the interpreter will execute ``<pkg>.__main__`` as the main module. This behaviour is deliberately similar to the handling of directories and zipfiles that are passed to the interpreter as the @@ -115,6 +116,9 @@ source. .. versionchanged:: 3.1 Supply the package name to run a ``__main__`` submodule. + .. versionchanged:: 3.4 + namespace packages are also supported + .. describe:: - @@ -144,6 +148,10 @@ source. added to the start of :data:`sys.path` and the ``__main__.py`` file in that location is executed as the :mod:`__main__` module. + .. seealso:: + :func:`runpy.run_path` + Equivalent functionality directly available to Python code + If no interface option is given, :option:`-i` is implied, ``sys.argv[0]`` is an empty string (``""``) and the current directory will be added to the @@ -151,11 +159,11 @@ start of :data:`sys.path`. Also, tab-completion and history editing is automatically enabled, if available on your platform (see :ref:`rlcompleter-config`). +.. seealso:: :ref:`tut-invoking` + .. versionchanged:: 3.4 Automatic enabling of tab-completion and history editing. -.. seealso:: :ref:`tut-invoking` - Generic options ~~~~~~~~~~~~~~~ @@ -182,13 +190,16 @@ Miscellaneous options .. cmdoption:: -b - Issue a warning when comparing str and bytes. Issue an error when the + Issue a warning when comparing :class:`bytes` or :class:`bytearray` with + :class:`str` or :class:`bytes` with :class:`int`. Issue an error when the option is given twice (:option:`-bb`). + .. versionchanged: 3.5 + Affects comparisons of :class:`bytes` with :class:`int`. .. cmdoption:: -B - If given, Python won't try to write ``.pyc`` or ``.pyo`` files on the + If given, Python won't try to write ``.pyc`` files on the import of source modules. See also :envvar:`PYTHONDONTWRITEBYTECODE`. @@ -407,7 +418,7 @@ Options you shouldn't use Reserved for use by Jython_. -.. _Jython: http://jython.org +.. _Jython: http://www.jython.org/ .. _using-on-envvars: @@ -464,14 +475,6 @@ conflict. :data:`sys.ps2` and the hook :data:`sys.__interactivehook__` in this file. -.. envvar:: PYTHONY2K - - Set this to a non-empty string to cause the :mod:`time` module to require - dates specified as strings to include 4-digit years, otherwise 2-digit years - are converted based on rules described in the :mod:`time` module - documentation. - - .. envvar:: PYTHONOPTIMIZE If this is set to a non-empty string it is equivalent to specifying the @@ -610,6 +613,14 @@ conflict. .. versionadded:: 3.4 +.. envvar:: PYTHONASYNCIODEBUG + + If this environment variable is set to a non-empty string, enable the + :ref:`debug mode <asyncio-debug-mode>` of the :mod:`asyncio` module. + + .. versionadded:: 3.4 + + Debug-mode variables ~~~~~~~~~~~~~~~~~~~~ diff --git a/Doc/using/mac.rst b/Doc/using/mac.rst index 5be439f3d615..ef091e527547 100644 --- a/Doc/using/mac.rst +++ b/Doc/using/mac.rst @@ -19,7 +19,7 @@ Getting and Installing MacPython Mac OS X 10.8 comes with Python 2.7 pre-installed by Apple. If you wish, you are invited to install the most recent version of Python 3 from the Python -website (http://www.python.org). A current "universal binary" build of Python, +website (https://www.python.org). A current "universal binary" build of Python, which runs natively on the Mac's new Intel and legacy PPC CPU's, is available there. @@ -64,7 +64,7 @@ the Finder you first need an editor to create your script. Mac OS X comes with a number of standard Unix command line editors, :program:`vim` and :program:`emacs` among them. If you want a more Mac-like editor, :program:`BBEdit` or :program:`TextWrangler` from Bare Bones Software (see -http://www.barebones.com/products/bbedit/index.shtml) are good choices, as is +http://www.barebones.com/products/bbedit/index.html) are good choices, as is :program:`TextMate` (see http://macromates.com/). Other editors include :program:`Gvim` (http://macvim.org) and :program:`Aquamacs` (http://aquamacs.org/). @@ -102,8 +102,9 @@ Configuration Python on OS X honors all standard Unix environment variables such as :envvar:`PYTHONPATH`, but setting these variables for programs started from the Finder is non-standard as the Finder does not read your :file:`.profile` or -:file:`.cshrc` at startup. You need to create a file :file:`~ -/.MacOSX/environment.plist`. See Apple's Technical Document QA1067 for details. +:file:`.cshrc` at startup. You need to create a file +:file:`~/.MacOSX/environment.plist`. See Apple's Technical Document QA1067 for +details. For more information on installation Python packages in MacPython, see section :ref:`mac-package-manager`. @@ -116,7 +117,7 @@ The IDE MacPython ships with the standard IDLE development environment. A good introduction to using IDLE can be found at -http://hkn.eecs.berkeley.edu/~dyoo/python/idle_intro/index.html. +https://hkn.eecs.berkeley.edu/~dyoo/python/idle_intro/index.html. .. _mac-package-manager: @@ -130,7 +131,7 @@ There are several methods to install additional Python packages: setup.py install``). * Many packages can also be installed via the :program:`setuptools` extension - or :program:`pip` wrapper, see http://www.pip-installer.org/. + or :program:`pip` wrapper, see https://pip.pypa.io/. GUI Programming on the Mac @@ -140,7 +141,7 @@ There are several options for building GUI applications on the Mac with Python. *PyObjC* is a Python binding to Apple's Objective-C/Cocoa framework, which is the foundation of most modern Mac development. Information on PyObjC is -available from http://pyobjc.sourceforge.net. +available from https://pythonhosted.org/pyobjc/. The standard Python GUI toolkit is :mod:`tkinter`, based on the cross-platform Tk toolkit (http://www.tcl.tk). An Aqua-native version of Tk is bundled with OS @@ -174,9 +175,9 @@ Other Resources The MacPython mailing list is an excellent support resource for Python users and developers on the Mac: -http://www.python.org/community/sigs/current/pythonmac-sig/ +https://www.python.org/community/sigs/current/pythonmac-sig/ Another useful resource is the MacPython wiki: -http://wiki.python.org/moin/MacPython +https://wiki.python.org/moin/MacPython diff --git a/Doc/using/unix.rst b/Doc/using/unix.rst index 40635c6111ca..5da1f233466a 100644 --- a/Doc/using/unix.rst +++ b/Doc/using/unix.rst @@ -55,18 +55,19 @@ On FreeBSD and OpenBSD On OpenSolaris -------------- -To install the newest Python versions on OpenSolaris, install `blastwave -<http://www.blastwave.org/howto.html>`_ and type ``pkg_get -i python`` at the -prompt. +You can get Python from `OpenCSW <http://www.opencsw.org/>`_. Various versions +of Python are available and can be installed with e.g. ``pkgutil -i python27``. +.. _building-python-on-unix: + Building Python =============== If you want to compile CPython yourself, first thing you should do is get the -`source <http://python.org/download/source/>`_. You can download either the +`source <https://www.python.org/download/source/>`_. You can download either the latest release's source or just grab a fresh `clone -<http://docs.python.org/devguide/setup#getting-the-source-code>`_. (If you want +<https://docs.python.org/devguide/setup.html#getting-the-source-code>`_. (If you want to contribute patches, you will need a clone.) The build process consists in the usual :: @@ -144,5 +145,4 @@ Geany is an excellent IDE with support for a lot of languages. For more information, read: http://www.geany.org/ Komodo edit is another extremely good IDE. It also has support for a lot of -languages. For more information, read: -http://www.activestate.com/store/productdetail.aspx?prdGuid=20f4ed15-6684-4118-a78b-d37ff4058c5f +languages. For more information, read http://komodoide.com/. diff --git a/Doc/using/venv-create.inc b/Doc/using/venv-create.inc index 868bbc827be8..02bcbeeb7f2b 100644 --- a/Doc/using/venv-create.inc +++ b/Doc/using/venv-create.inc @@ -11,21 +11,26 @@ containing a copy of the ``python`` binary (or binaries, in the case of Windows). It also creates an (initially empty) ``lib/pythonX.Y/site-packages`` subdirectory (on Windows, this is ``Lib\site-packages``). +.. seealso:: + + `Python Packaging User Guide: Creating and using virtual environments + <https://packaging.python.org/en/latest/installing.html#virtual-environments>`__ + .. highlight:: none On Windows, you may have to invoke the ``pyvenv`` script as follows, if you don't have the relevant PATH and PATHEXT settings:: - c:\Temp>c:\Python33\python c:\Python33\Tools\Scripts\pyvenv.py myenv + c:\Temp>c:\Python35\python c:\Python35\Tools\Scripts\pyvenv.py myenv or equivalently:: - c:\Temp>c:\Python33\python -m venv myenv + c:\Temp>c:\Python35\python -m venv myenv The command, if run with ``-h``, will show the available options:: - usage: pyvenv [-h] [--system-site-packages] [--symlinks] [--clear] - [--upgrade] [--without-pip] ENV_DIR [ENV_DIR ...] + usage: venv [-h] [--system-site-packages] [--symlinks] [--clear] + [--upgrade] [--without-pip] ENV_DIR [ENV_DIR ...] Creates virtual Python environments in one or more target directories. @@ -38,6 +43,8 @@ The command, if run with ``-h``, will show the available options:: virtual environment. --symlinks Try to use symlinks rather than copies, when symlinks are not the default for the platform. + --copies Try to use copies rather than symlinks, even when + symlinks are the default for the platform. --clear Delete the environment directory if it already exists. If not specified and the directory exists, an error is raised. @@ -46,11 +53,18 @@ The command, if run with ``-h``, will show the available options:: --without-pip Skips installing or upgrading pip in the virtual environment (pip is bootstrapped by default) +Depending on how the ``venv`` functionality has been invoked, the usage message +may vary slightly, e.g. referencing ``pyvenv`` rather than ``venv``. + .. versionchanged:: 3.4 - Installs pip by default, added the ``--without-pip`` option + Installs pip by default, added the ``--without-pip`` and ``--copies`` + options -If the target directory already exists an error will be raised, unless -the ``--clear`` or ``--upgrade`` option was provided. +.. versionchanged:: 3.4 + In earlier versions, if the target directory already existed, an error was + raised, unless the ``--clear`` or ``--upgrade`` option was provided. Now, + if an existing directory is specified, its contents are removed and + the directory is processed as if it had been newly created. The created ``pyvenv.cfg`` file also includes the ``include-system-site-packages`` key, set to ``true`` if ``venv`` is @@ -92,3 +106,5 @@ a "deactivate" function, whereas on Windows there are separate scripts called ``deactivate.bat`` and ``Deactivate.ps1`` which are installed when the venv is created. +.. versionadded:: 3.4 + ``fish`` and ``csh`` activation scripts. diff --git a/Doc/using/win_installer.png b/Doc/using/win_installer.png new file mode 100644 index 000000000000..00c88a830feb Binary files /dev/null and b/Doc/using/win_installer.png differ diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 4dfe47b1c43f..2116c106dea3 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -7,37 +7,227 @@ ************************* .. sectionauthor:: Robert Lehmann <lehmannro@gmail.com> +.. sectionauthor:: Steve Dower <steve.dower@microsoft.com> This document aims to give an overview of Windows-specific behaviour you should know about when using Python on Microsoft Windows. - Installing Python ================= -Unlike most Unix systems and services, Windows does not require Python natively -and thus does not pre-install a version of Python. However, the CPython team +Unlike most Unix systems and services, Windows does not include a system +supported installation of Python. To make Python available, the CPython team has compiled Windows installers (MSI packages) with every `release -<http://www.python.org/download/releases/>`_ for many years. +<https://www.python.org/download/releases/>`_ for many years. These installers +are primarily intended to add a per-user installation of Python, with the +core interpreter and library being used by a single user. The installer is also +able to install for all users of a single machine, and a separate ZIP file is +available for application-local distributions. + +Installation Steps +------------------ + +Four Python 3.5 installers are available for download - two each for the 32-bit +and 64-bit versions of the interpreter. The *web installer* is a small initial +download, and it will automatically download the required components as +necessary. The *offline installer* includes the components necessary for a +default installation and only requires an internet connection for optional +features. See :ref:`install-layout-option` for other ways to avoid downloading +during installation. + +After starting the installer, one of two options may be selected: + +.. image:: win_installer.png + +If you select "Install Now": + +* You will *not* need to be an administrator (unless a system update for the + C Runtime Library is required or you install the :ref:`launcher` for all + users) +* Python will be installed into your user directory +* The :ref:`launcher` will be installed according to the option at the bottom + of the first pace +* The standard library, test suite, launcher and pip will be installed +* If selected, the install directory will be added to your :envvar:`PATH` +* Shortcuts will only be visible for the current user + +Selecting "Customize installation" will allow you to select the features to +install, the installation location and other options or post-install actions. +To install debugging symbols or binaries, you will need to use this option. + +To perform an all-users installation, you should select "Customize +installation". In this case: + +* You may be required to provide administrative credentials or approval +* Python will be installed into the Program Files directory +* The :ref:`launcher` will be installed into the Windows directory +* Optional features may be selected during installation +* The standard library can be pre-compiled to bytecode +* If selected, the install directory will be added to the system :envvar:`PATH` +* Shortcuts are available for all users + +.. _install-quiet-option: + +Installing Without UI +--------------------- + +All of the options available in the installer UI can also be specified from the +command line, allowing scripted installers to replicate an installation on many +machines without user interaction. These options may also be set without +suppressing the UI in order to change some of the defaults. + +To completely hide the installer UI and install Python silently, pass the +``/quiet`` option. To skip past the user interaction but still display +progress and errors, pass the ``/passive`` option. The ``/uninstall`` +option may be passed to immediately begin removing Python - no prompt will be +displayed. + +All other options are passed as ``name=value``, where the value is usually +``0`` to disable a feature, ``1`` to enable a feature, or a path. The full list +of available options is shown below. + ++---------------------------+--------------------------------------+--------------------------+ +| Name | Description | Default | ++===========================+======================================+==========================+ +| InstallAllUsers | Perform a system-wide installation. | 0 | ++---------------------------+--------------------------------------+--------------------------+ +| TargetDir | The installation directory | Selected based on | +| | | InstallAllUsers | ++---------------------------+--------------------------------------+--------------------------+ +| DefaultAllUsersTargetDir | The default installation directory | :file:`%ProgramFiles%\\\ | +| | for all-user installs | Python X.Y` or :file:`\ | +| | | %ProgramFiles(x86)%\\\ | +| | | Python X.Y` | ++---------------------------+--------------------------------------+--------------------------+ +| DefaultJustForMeTargetDir | The default install directory for | :file:`%LocalAppData%\\\ | +| | just-for-me installs | Programs\\PythonXY` or | +| | | :file:`%LocalAppData%\\\ | +| | | Programs\\PythonXY-32` | ++---------------------------+--------------------------------------+--------------------------+ +| DefaultCustomTargetDir | The default custom install directory | (empty) | +| | displayed in the UI | | ++---------------------------+--------------------------------------+--------------------------+ +| AssociateFiles | Create file associations if the | 1 | +| | launcher is also installed. | | ++---------------------------+--------------------------------------+--------------------------+ +| CompileAll | Compile all ``.py`` files to | 0 | +| | ``.pyc``. | | ++---------------------------+--------------------------------------+--------------------------+ +| PrependPath | Add install and Scripts directories | 0 | +| | tho :envvar:`PATH` and ``.PY`` to | | +| | :envvar:`PATHEXT` | | ++---------------------------+--------------------------------------+--------------------------+ +| Shortcuts | Create shortcuts for the interpreter,| 1 | +| | documentation and IDLE if installed. | | ++---------------------------+--------------------------------------+--------------------------+ +| Include_doc | Install Python manual | 1 | ++---------------------------+--------------------------------------+--------------------------+ +| Include_debug | Install debug binaries | 0 | ++---------------------------+--------------------------------------+--------------------------+ +| Include_dev | Install developer headers and | 1 | +| | libraries | | ++---------------------------+--------------------------------------+--------------------------+ +| Include_exe | Install :file:`python.exe` and | 1 | +| | related files | | ++---------------------------+--------------------------------------+--------------------------+ +| Include_launcher | Install :ref:`launcher`. | 1 | ++---------------------------+--------------------------------------+--------------------------+ +| InstallLauncherAllUsers | Installs :ref:`launcher` for all | 1 | +| | users. | | ++---------------------------+--------------------------------------+--------------------------+ +| Include_lib | Install standard library and | 1 | +| | extension modules | | ++---------------------------+--------------------------------------+--------------------------+ +| Include_pip | Install bundled pip and setuptools | 1 | ++---------------------------+--------------------------------------+--------------------------+ +| Include_symbols | Install debugging symbols (`*`.pdb) | 0 | ++---------------------------+--------------------------------------+--------------------------+ +| Include_tcltk | Install Tcl/Tk support and IDLE | 1 | ++---------------------------+--------------------------------------+--------------------------+ +| Include_test | Install standard library test suite | 1 | ++---------------------------+--------------------------------------+--------------------------+ +| Include_tools | Install utility scripts | 1 | ++---------------------------+--------------------------------------+--------------------------+ +| LauncherOnly | Only installs the launcher. This | 0 | +| | will override most other options. | | ++---------------------------+--------------------------------------+--------------------------+ +| SimpleInstall | Disable most install UI | 0 | ++---------------------------+--------------------------------------+--------------------------+ +| SimpleInstallDescription | A custom message to display when the | (empty) | +| | simplified install UI is used. | | ++---------------------------+--------------------------------------+--------------------------+ + +For example, to silently install a default, system-wide Python installation, +you could use the following command (from an elevated command prompt):: + + python-3.5.0.exe /quiet InstallAllUsers=1 PrependPath=1 Include_test=0 + +To allow users to easily install a personal copy of Python without the test +suite, you could provide a shortcut with the following command. This will +display a simplified initial page and disallow customization:: + + python-3.5.0.exe InstallAllUsers=0 Include_launcher=0 Include_test=0 + SimpleInstall=1 SimpleInstallDescription="Just for me, no test suite." + +(Note that omitting the launcher also omits file associations, and is only +recommended for per-user installs when there is also a system-wide installation +that included the launcher.) + +The options listed above can also be provided in a file named ``unattend.xml`` +alongside the executable. This file specifies a list of options and values. +When a value is provided as an attribute, it will be converted to a number if +possible. Values provided as element text are always left as strings. This +example file sets the same options and the previous example:: + + <Options> + <Option Name="InstallAllUsers" Value="no" /> + <Option Name="Include_launcher" Value="0" /> + <Option Name="Include_test" Value="no" /> + <Option Name="SimpleInstall" Value="yes" /> + <Option Name="SimpleInstallDescription">Just for me, no test suite</Option> + </Options> + +.. _install-layout-option: + +Installing Without Downloading +------------------------------ + +As some features of Python are not included in the initial installer download, +selecting those features may require an internet connection. To avoid this +need, all possible components may be downloaded on-demand to create a complete +*layout* that will no longer require an internet connection regardless of the +selected features. Note that this download may be bigger than required, but +where a large number of installations are going to be performed it is very +useful to have a locally cached copy. + +Execute the following command from Command Prompt to download all possible +required files. Remember to substitute ``python-3.5.0.exe`` for the actual +name of your installer, and to create layouts in their own directories to +avoid collisions between files with the same name. + +:: + + python-3.5.0.exe /layout [optional target directory] + +You may also specify the ``/quiet`` option to hide the progress display. + + +Other Platforms +--------------- With ongoing development of Python, some platforms that used to be supported earlier are no longer supported (due to the lack of users or developers). Check :pep:`11` for details on all unsupported platforms. -* Up to 2.5, Python was still compatible with Windows 95, 98 and ME (but already - raised a deprecation warning on installation). For Python 2.6 (and all - following releases), this support was dropped and new releases are just - expected to work on the Windows NT family. * `Windows CE <http://pythonce.sourceforge.net/>`_ is still supported. -* The `Cygwin <http://cygwin.com/>`_ installer offers to install the `Python - interpreter <http://cygwin.com/packages/python>`_ as well; it is located under - "Interpreters." (cf. `Cygwin package source +* The `Cygwin <http://cygwin.com/>`_ installer offers to install the Python + interpreter as well (cf. `Cygwin package source <ftp://ftp.uni-erlangen.de/pub/pc/gnuwin32/cygwin/mirrors/cygnus/ release/python>`_, `Maintainer releases <http://www.tishler.net/jason/software/python/>`_) -See `Python for Windows (and DOS) <http://www.python.org/download/windows/>`_ -for detailed information about platforms with precompiled installers. +See `Python for Windows <https://www.python.org/download/windows/>`_ +for detailed information about platforms with pre-compiled installers. .. seealso:: @@ -45,15 +235,15 @@ for detailed information about platforms with precompiled installers. "7 Minutes to "Hello World!"" by Richard Dooling, 2006 - `Installing on Windows <http://diveintopython.net/installing_python/windows.html>`_ + `Installing on Windows <http://www.diveintopython.net/installing_python/windows.html>`_ in "`Dive into Python: Python from novice to pro - <http://diveintopython.net/index.html>`_" + <http://www.diveintopython.net/>`_" by Mark Pilgrim, 2004, ISBN 1-59059-356-1 - `For Windows users <http://swaroopch.com/text/Byte_of_Python:Installing_Python#For_Windows_users>`_ + `For Windows users <http://www.swaroopch.com/notes/python/#install_windows>`_ in "Installing Python" - in "`A Byte of Python <http://www.byteofpython.info>`_" + in "`A Byte of Python <http://www.swaroopch.com/notes/python/>`_" by Swaroop C H, 2003 @@ -64,22 +254,34 @@ Besides the standard CPython distribution, there are modified packages including additional functionality. The following is a list of popular versions and their key features: -`ActivePython <http://www.activestate.com/Products/activepython/>`_ +`ActivePython <http://www.activestate.com/activepython/>`_ Installer with multi-platform compatibility, documentation, PyWin32 -`Enthought Python Distribution <http://www.enthought.com/products/epd.php>`_ - Popular modules (such as PyWin32) with their respective documentation, tool - suite for building extensible Python applications +`Anaconda <http://www.continuum.io/downloads/>`_ + Popular scientific modules (such as numpy, scipy and pandas) and the + ``conda`` package manager. + +`Canopy <https://www.enthought.com/products/canopy/>`_ + A "comprehensive Python analysis environment" with editors and other + development tools. -Notice that these packages are likely to install *older* versions of Python. +`WinPython <https://winpython.github.io/>`_ + Windows-specific distribution with prebuilt scientific packages and + tools for building packages. + +Note that these packages may not include the latest versions of Python or +other libraries, and are not maintained or supported by the core Python team. Configuring Python ================== -In order to run Python flawlessly, you might have to change certain environment -settings in Windows. +To run Python conveniently from a command prompt, you might consider changing +some default environment variables in Windows. While the installer provides an +option to configure the PATH and PATHEXT variables for you, this is only +reliable for a single, system-wide installation. If you regularly use multiple +versions of Python, consider using the :ref:`launcher`. .. _setting-envvars: @@ -87,163 +289,86 @@ settings in Windows. Excursus: Setting environment variables --------------------------------------- -Windows has a built-in dialog for changing environment variables (following -guide applies to XP classical view): Right-click the icon for your machine -(usually located on your Desktop and called "My Computer") and choose -:menuselection:`Properties` there. Then, open the :guilabel:`Advanced` tab -and click the :guilabel:`Environment Variables` button. +Windows allows environment variables to be configured permanently at both the +User level and the System level, or temporarily in a command prompt. + +To temporarily set environment variables, open Command Prompt and use the +:command:`set` command:: -In short, your path is: + C:\>set PATH=C:\Program Files\Python 3.5;%PATH% + C:\>set PYTHONPATH=%PYTHONPATH%;C:\My_python_lib + C:\>python - :menuselection:`My Computer - --> Properties - --> Advanced - --> Environment Variables` +These changes will apply to any further commands executed in that console, and +will be inherited by any applications started from the console. +Including the variable name within percent signs will expand to the existing +value, allowing you to add your new value at either the start or the end. +Modifying :envvar:`PATH` by adding the directory containing +:program:`python.exe` to the start is a common way to ensure the correct version +of Python is launched. + +To permanently modify the default environment variables, click Start and search +for 'edit environment variables', or open System properties, :guilabel:`Advanced +system settings` and click the :guilabel:`Environment Variables` button. In this dialog, you can add or modify User and System variables. To change System variables, you need non-restricted access to your machine (i.e. Administrator rights). -Another way of adding variables to your environment is using the :command:`set` -command:: - - set PYTHONPATH=%PYTHONPATH%;C:\My_python_lib - -To make this setting permanent, you could add the corresponding command line to -your :file:`autoexec.bat`. :program:`msconfig` is a graphical interface to this -file. +.. note:: -Viewing environment variables can also be done more straight-forward: The -command prompt will expand strings wrapped into percent signs automatically:: + Windows will concatenate User variables *after* System variables, which may + cause unexpected results when modifying :envvar:`PATH`. - echo %PATH% - -Consult :command:`set /?` for details on this behaviour. + The :envvar:`PYTHONPATH` variable is used by all versions of Python 2 and + Python 3, so you should not permanently configure this variable unless it + only includes code that is compatible with all of your installed Python + versions. .. seealso:: - http://support.microsoft.com/kb/100843 + http://support.microsoft.com/kb/100843 Environment variables in Windows NT - http://support.microsoft.com/kb/310519 + http://technet.microsoft.com/en-us/library/cc754250.aspx + The SET command, for temporarily modifying environment variables + + http://technet.microsoft.com/en-us/library/cc755104.aspx + The SETX command, for permanently modifying environment variables + + http://support.microsoft.com/kb/310519 How To Manage Environment Variables in Windows XP - http://www.chem.gla.ac.uk/~louis/software/faq/q1.html + http://www.chem.gla.ac.uk/~louis/software/faq/q1.html Setting Environment variables, Louis J. Farrugia - .. _windows-path-mod: Finding the Python executable ----------------------------- -.. versionchanged:: 3.3 +.. versionchanged:: 3.5 Besides using the automatically created start menu entry for the Python -interpreter, you might want to start Python in the command prompt. As of -Python 3.3, the installer has an option to set that up for you. - -At the "Customize Python 3.3" screen, an option called -"Add python.exe to search path" can be enabled to have the installer place -your installation into the :envvar:`%PATH%`. This allows you to type -:command:`python` to run the interpreter. Thus, you can also execute your +interpreter, you might want to start Python in the command prompt. The +installer for Python 3.5 and later has an option to set that up for you. + +On the first page of the installer, an option labelled "Add Python 3.5 to +PATH" can be selected to have the installer add the install location into the +:envvar:`PATH`. The location of the :file:`Scripts\\` folder is also added. +This allows you to type :command:`python` to run the interpreter, and +:command:`pip` or . Thus, you can also execute your scripts with command line options, see :ref:`using-on-cmdline` documentation. If you don't enable this option at install time, you can always re-run the -installer to choose it. - -The alternative is manually modifying the :envvar:`%PATH%` using the -directions in :ref:`setting-envvars`. You need to set your :envvar:`%PATH%` -environment variable to include the directory of your Python distribution, -delimited by a semicolon from other entries. An example variable could look -like this (assuming the first two entries are Windows' default):: - - C:\WINDOWS\system32;C:\WINDOWS;C:\Python33 - - -Finding modules ---------------- - -Python usually stores its library (and thereby your site-packages folder) in the -installation directory. So, if you had installed Python to -:file:`C:\\Python\\`, the default library would reside in -:file:`C:\\Python\\Lib\\` and third-party modules should be stored in -:file:`C:\\Python\\Lib\\site-packages\\`. - -This is how :data:`sys.path` is populated on Windows: - -* An empty entry is added at the start, which corresponds to the current - directory. - -* If the environment variable :envvar:`PYTHONPATH` exists, as described in - :ref:`using-on-envvars`, its entries are added next. Note that on Windows, - paths in this variable must be separated by semicolons, to distinguish them - from the colon used in drive identifiers (``C:\`` etc.). - -* Additional "application paths" can be added in the registry as subkeys of - :samp:`\\SOFTWARE\\Python\\PythonCore\\{version}\\PythonPath` under both the - ``HKEY_CURRENT_USER`` and ``HKEY_LOCAL_MACHINE`` hives. Subkeys which have - semicolon-delimited path strings as their default value will cause each path - to be added to :data:`sys.path`. (Note that all known installers only use - HKLM, so HKCU is typically empty.) - -* If the environment variable :envvar:`PYTHONHOME` is set, it is assumed as - "Python Home". Otherwise, the path of the main Python executable is used to - locate a "landmark file" (``Lib\os.py``) to deduce the "Python Home". If a - Python home is found, the relevant sub-directories added to :data:`sys.path` - (``Lib``, ``plat-win``, etc) are based on that folder. Otherwise, the core - Python path is constructed from the PythonPath stored in the registry. - -* If the Python Home cannot be located, no :envvar:`PYTHONPATH` is specified in - the environment, and no registry entries can be found, a default path with - relative entries is used (e.g. ``.\Lib;.\plat-win``, etc). - -The end result of all this is: - -* When running :file:`python.exe`, or any other .exe in the main Python - directory (either an installed version, or directly from the PCbuild - directory), the core path is deduced, and the core paths in the registry are - ignored. Other "application paths" in the registry are always read. - -* When Python is hosted in another .exe (different directory, embedded via COM, - etc), the "Python Home" will not be deduced, so the core path from the - registry is used. Other "application paths" in the registry are always read. - -* If Python can't find its home and there is no registry (eg, frozen .exe, some - very strange installation setup) you get a path with some default, but - relative, paths. - - -Executing scripts ------------------ - -As of Python 3.3, Python includes a launcher which facilitates running Python -scripts. See :ref:`launcher` for more information. - -Executing scripts without the Python launcher ---------------------------------------------- - -Without the Python launcher installed, Python scripts (files with the extension -``.py``) will be executed by :program:`python.exe` by default. This executable -opens a terminal, which stays open even if the program uses a GUI. If you do -not want this to happen, use the extension ``.pyw`` which will cause the script -to be executed by :program:`pythonw.exe` by default (both executables are -located in the top-level of your Python installation directory). This -suppresses the terminal window on startup. - -You can also make all ``.py`` scripts execute with :program:`pythonw.exe`, -setting this through the usual facilities, for example (might require -administrative rights): - -#. Launch a command prompt. -#. Associate the correct file group with ``.py`` scripts:: - - assoc .py=Python.File - -#. Redirect all Python files to the new executable:: - - ftype Python.File=C:\Path\to\pythonw.exe "%1" %* +installer, select Modify, and enable it. Alternatively, you can manually +modify the :envvar:`PATH` using the directions in :ref:`setting-envvars`. You +need to set your :envvar:`PATH` environment variable to include the directory +of your Python installation, delimited by a semicolon from other entries. An +example variable could look like this (assuming the first two entries already +existed):: + C:\WINDOWS\system32;C:\WINDOWS;C:\Program Files\Python 3.5 .. _launcher: @@ -252,21 +377,26 @@ Python Launcher for Windows .. versionadded:: 3.3 -The Python launcher for Windows is a utility which aids in the location and -execution of different Python versions. It allows scripts (or the +The Python launcher for Windows is a utility which aids in locating and +executing of different Python versions. It allows scripts (or the command-line) to indicate a preference for a specific Python version, and will locate and execute that version. +Unlike the :envvar:`PATH` variable, the launcher will correctly select the most +appropriate version of Python. It will prefer per-user installations over +system-wide ones, and orders by language version rather than using the most +recently installed version. + Getting started --------------- From the command-line ^^^^^^^^^^^^^^^^^^^^^ -You should ensure the launcher is on your PATH - depending on how it was -installed it may already be there, but check just in case it is not. - -From a command-prompt, execute the following command: +System-wide installations of Python 3.3 and later will put the launcher on your +:envvar:`PATH`. The launcher is compatible with all available versions of +Python, so it does not matter which version is installed. To check that the +launcher is available, execute the following command in Command Prompt: :: @@ -292,6 +422,28 @@ If you have a Python 3.x installed, try the command: You should find the latest version of Python 3.x starts. +If you see the following error, you do not have the launcher installed: + +:: + + 'py' is not recognized as an internal or external command, + operable program or batch file. + +Per-user installations of Python do not add the launcher to :envvar:`PATH` +unless the option was selected on installation. + +Virtual environments +^^^^^^^^^^^^^^^^^^^^ + +.. versionadded:: 3.5 + +If the launcher is run with no explicit Python version specification, and a +virtual environment (created with the standard library :mod:`venv` module or +the external ``virtualenv`` tool) active, the launcher will run the virtual +environment's interpreter rather than the global one. To run the global +interpreter, either deactivate the virtual environment, or explicitly specify +the global Python version. + From a script ^^^^^^^^^^^^^ @@ -327,7 +479,7 @@ From file associations ^^^^^^^^^^^^^^^^^^^^^^ The launcher should have been associated with Python files (i.e. ``.py``, -``.pyw``, ``.pyc``, ``.pyo`` files) when it was installed. This means that +``.pyw``, ``.pyc`` files) when it was installed. This means that when you double-click on one of these files from Windows explorer the launcher will be used, and therefore you can use the same facilities described above to have the script specify the version which should be used. @@ -366,6 +518,16 @@ be used by the launcher without modification. If you are writing a new script on Windows which you hope will be useful on Unix, you should use one of the shebang lines starting with ``/usr``. +Any of the above virtual commands can be suffixed with an explicit version +(either just the major version, or the major and minor version) - for example +``/usr/bin/python2.7`` - which will cause that specific version to be located +and used. + +The ``/usr/bin/env`` form of shebang line has one further special property. +Before looking for installed Python interpreters, this form will search the +executable :envvar:`PATH` for a Python executable. This corresponds to the +behaviour of the Unix ``env`` program, which performs a :envvar:`PATH` search. + Arguments in shebang lines -------------------------- @@ -384,17 +546,16 @@ Customization Customization via INI files ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Two .ini files will be searched by the launcher - ``py.ini`` in the - current user's "application data" directory (i.e. the directory returned - by calling the Windows function SHGetFolderPath with CSIDL_LOCAL_APPDATA) - and ``py.ini`` in the same directory as the launcher. The same .ini - files are used for both the 'console' version of the launcher (i.e. - py.exe) and for the 'windows' version (i.e. pyw.exe) +Two .ini files will be searched by the launcher - ``py.ini`` in the current +user's "application data" directory (i.e. the directory returned by calling the +Windows function SHGetFolderPath with CSIDL_LOCAL_APPDATA) and ``py.ini`` in the +same directory as the launcher. The same .ini files are used for both the +'console' version of the launcher (i.e. py.exe) and for the 'windows' version +(i.e. pyw.exe) - Customization specified in the "application directory" will have - precedence over the one next to the executable, so a user, who may not - have write access to the .ini file next to the launcher, can override - commands in that global .ini file) +Customization specified in the "application directory" will have precedence over +the one next to the executable, so a user, who may not have write access to the +.ini file next to the launcher, can override commands in that global .ini file) Customizing default Python versions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -489,6 +650,99 @@ particular version was chosen and the exact command-line used to execute the target Python. + +.. finding_modules: + +Finding modules +=============== + +Python usually stores its library (and thereby your site-packages folder) in the +installation directory. So, if you had installed Python to +:file:`C:\\Python\\`, the default library would reside in +:file:`C:\\Python\\Lib\\` and third-party modules should be stored in +:file:`C:\\Python\\Lib\\site-packages\\`. + +This is how :data:`sys.path` is populated on Windows: + +* An empty entry is added at the start, which corresponds to the current + directory. + +* If the environment variable :envvar:`PYTHONPATH` exists, as described in + :ref:`using-on-envvars`, its entries are added next. Note that on Windows, + paths in this variable must be separated by semicolons, to distinguish them + from the colon used in drive identifiers (``C:\`` etc.). + +* Additional "application paths" can be added in the registry as subkeys of + :samp:`\\SOFTWARE\\Python\\PythonCore\\{version}\\PythonPath` under both the + ``HKEY_CURRENT_USER`` and ``HKEY_LOCAL_MACHINE`` hives. Subkeys which have + semicolon-delimited path strings as their default value will cause each path + to be added to :data:`sys.path`. (Note that all known installers only use + HKLM, so HKCU is typically empty.) + +* If the environment variable :envvar:`PYTHONHOME` is set, it is assumed as + "Python Home". Otherwise, the path of the main Python executable is used to + locate a "landmark file" (``Lib\os.py``) to deduce the "Python Home". If a + Python home is found, the relevant sub-directories added to :data:`sys.path` + (``Lib``, ``plat-win``, etc) are based on that folder. Otherwise, the core + Python path is constructed from the PythonPath stored in the registry. + +* If the Python Home cannot be located, no :envvar:`PYTHONPATH` is specified in + the environment, and no registry entries can be found, a default path with + relative entries is used (e.g. ``.\Lib;.\plat-win``, etc). + +If a ``pyvenv.cfg`` file is found alongside the main executable or in the +directory one level above the executable, the following variations apply: + +* If ``home`` is an absolute path and :envvar:`PYTHONHOME` is not set, this + path is used instead of the path to the main executable when deducing the + home location. + +* If ``applocal`` is set to true, the ``home`` property or the main executable + is always used as the home path, and all environment variables or registry + values affecting the path are ignored. The landmark file is not checked. + +The end result of all this is: + +* When running :file:`python.exe`, or any other .exe in the main Python + directory (either an installed version, or directly from the PCbuild + directory), the core path is deduced, and the core paths in the registry are + ignored. Other "application paths" in the registry are always read. + +* When Python is hosted in another .exe (different directory, embedded via COM, + etc), the "Python Home" will not be deduced, so the core path from the + registry is used. Other "application paths" in the registry are always read. + +* If Python can't find its home and there are no registry value (frozen .exe, + some very strange installation setup) you get a path with some default, but + relative, paths. + +For those who want to bundle Python into their application or distribution, the +following advice will prevent conflicts with other installations: + +* Include a ``pyvenv.cfg`` file alongside your executable containing + ``applocal = true``. This will ensure that your own directory will be used to + resolve paths even if you have included the standard library in a ZIP file. + It will also ignore user site-packages and other paths listed in the + registry. + +* If you are loading :file:`python3.dll` or :file:`python35.dll` in your own + executable, explicitly call :c:func:`Py_SetPath` or (at least) + :c:func:`Py_SetProgramName` before :c:func:`Py_Initialize`. + +* Clear and/or overwrite :envvar:`PYTHONPATH` and set :envvar:`PYTHONHOME` + before launching :file:`python.exe` from your application. + +* If you cannot use the previous suggestions (for example, you are a + distribution that allows people to run :file:`python.exe` directly), ensure + that the landmark file (:file:`Lib\\os.py`) exists in your install directory. + (Note that it will not be detected inside a ZIP file.) + +These will ensure that the files in a system-wide installation will not take +precedence over the copy of the standard library bundled with your application. +Otherwise, your users may experience problems using your application. Note that +the first suggestion is the best, as the other may still be susceptible to +non-standard paths in the registry and user site-packages. + Additional modules ================== @@ -499,7 +753,6 @@ and external, and snippets exist to use these features. The Windows-specific standard modules are documented in :ref:`mswin-specific-services`. - PyWin32 ------- @@ -515,7 +768,7 @@ utilities for: user interfaces `PythonWin <http://web.archive.org/web/20060524042422/ -http://www.python.org/windows/pythonwin/>`_ is a sample MFC application +https://www.python.org/windows/pythonwin/>`_ is a sample MFC application shipped with PyWin32. It is an embeddable IDE with a built-in debugger. .. seealso:: @@ -527,13 +780,14 @@ shipped with PyWin32. It is an embeddable IDE with a built-in debugger. by David and Paul Boddie -Py2exe ------- +cx_Freeze +--------- -`Py2exe <http://www.py2exe.org/>`_ is a :mod:`distutils` extension (see -:ref:`extending-distutils`) which wraps Python scripts into executable Windows -programs (:file:`{*}.exe` files). When you have done this, you can distribute -your application without requiring your users to install Python. +`cx_Freeze <http://cx-freeze.sourceforge.net/>`_ is a :mod:`distutils` +extension (see :ref:`extending-distutils`) which wraps Python scripts into +executable Windows programs (:file:`{*}.exe` files). When you have done this, +you can distribute your application without requiring your users to install +Python. WConio @@ -552,25 +806,13 @@ Compiling Python on Windows =========================== If you want to compile CPython yourself, first thing you should do is get the -`source <http://python.org/download/source/>`_. You can download either the +`source <https://www.python.org/download/source/>`_. You can download either the latest release's source or just grab a fresh `checkout -<http://docs.python.org/devguide/setup#checking-out-the-code>`_. +<https://docs.python.org/devguide/setup.html#getting-the-source-code>`_. The source tree contains a build solution and project files for Microsoft -Visual C++, which is the compiler used to build the official Python releases. -View the :file:`readme.txt` in their respective directories: - -+--------------------+--------------+-----------------------+ -| Directory | MSVC version | Visual Studio version | -+====================+==============+=======================+ -| :file:`PC/VS9.0/` | 9.0 | 2008 | -+--------------------+--------------+-----------------------+ -| :file:`PCbuild/` | 10.0 | 2010 | -+--------------------+--------------+-----------------------+ - -Note that any build directories within the :file:`PC` directory are not -necessarily fully supported. The :file:`PCbuild` directory contains the files -for the compiler used to build the official release. +Visual Studio 2015, which is the compiler used to build the official Python +releases. These files are in the :file:`PCbuild` directory. Check :file:`PCbuild/readme.txt` for general information on the build process. @@ -588,12 +830,89 @@ For extension modules, consult :ref:`building-on-windows`. by Trent Apted et al, 2007 +Embedded Distribution +===================== + +.. versionadded:: 3.5 + +The embedded distribution is a ZIP file containing a minimal Python environment. +It is intended for acting as part of another application, rather than being +directly accessed by end-users. + +When extracted, the embedded distribution is (almost) fully isolated from the +user's system, including environment variables, system registry settings, and +installed packages. The standard library is included as pre-compiled and +optimized ``.pyc`` files in a ZIP, and ``python3.dll``, ``python35.dll``, +``python.exe`` and ``pythonw.exe`` are all provided. Tcl/tk (including all +dependants, such as Idle), pip and the Python documentation are not included. + +.. note:: + + The embedded distribution does not include the `Microsoft C Runtime + <http://www.microsoft.com/en-us/download/details.aspx?id=48145>`_ and it is + the responsibility of the application installer to provide this. The + runtime may have already been installed on a user's system previously or + automatically via Windows Update, and can be detected by finding + ``ucrtbase.dll`` in the system directory. + +Third-party packages should be installed by the application installer alongside +the embedded distribution. Using pip to manage dependencies as for a regular +Python installation is not supported with this distribution, though with some +care it may be possible to include and use pip for automatic updates. In +general, third-party packages should be treated as part of the application +("vendoring") so that the developer can ensure compatibility with newer +versions before providing updates to users. + +The two recommended use cases for this distribution are described below. + +Python Application +------------------ + +An application written in Python does not necessarily require users to be aware +of that fact. The embedded distribution may be used in this case to include a +private version of Python in an install package. Depending on how transparent it +should be (or conversely, how professional it should appear), there are two +options. + +Using a specialized executable as a launcher requires some coding, but provides +the most transparent experience for users. With a customized launcher, there are +no obvious indications that the program is running on Python: icons can be +customized, company and version information can be specified, and file +associations behave properly. In most cases, a custom launcher should simply be +able to call ``Py_Main`` with a hard-coded command line. + +The simpler approach is to provide a batch file or generated shortcut that +directly calls the ``python.exe`` or ``pythonw.exe`` with the required +command-line arguments. In this case, the application will appear to be Python +and not its actual name, and users may have trouble distinguishing it from other +running Python processes or file associations. + +With the latter approach, packages should be installed as directories alongside +the Python executable to ensure they are available on the path. With the +specialized launcher, packages can be located in other locations as there is an +opportunity to specify the search path before launching the application. + +Embedding Python +---------------- + +Applications written in native code often require some form of scripting +language, and the embedded Python distribution can be used for this purpose. In +general, the majority of the application is in native code, and some part will +either invoke ``python.exe`` or directly use ``python3.dll``. For either case, +extracting the embedded distribution to a subdirectory of the application +installation is sufficient to provide a loadable Python interpreter. + +As with the application use, packages can be installed to any location as there +is an opportunity to specify search paths before initializing the interpreter. +Otherwise, there is no fundamental differences between using the embedded +distribution and a regular installation. + Other resources =============== .. seealso:: - `Python Programming On Win32 <http://www.oreilly.com/catalog/pythonwin32/>`_ + `Python Programming On Win32 <http://shop.oreilly.com/product/9781565926219.do>`_ "Help for Windows Programmers" by Mark Hammond and Andy Robinson, O'Reilly Media, 2000, ISBN 1-56592-621-8 @@ -603,5 +922,3 @@ Other resources :pep:`397` - Python launcher for Windows The proposal for the launcher to be included in the Python distribution. - - diff --git a/Doc/whatsnew/2.0.rst b/Doc/whatsnew/2.0.rst index 64b908b6e5dc..10bb29ee8a0e 100644 --- a/Doc/whatsnew/2.0.rst +++ b/Doc/whatsnew/2.0.rst @@ -130,7 +130,7 @@ Guidelines": Read the rest of PEP 1 for the details of the PEP editorial process, style, and format. PEPs are kept in the Python CVS tree on SourceForge, though they're not part of the Python 2.0 distribution, and are also available in HTML form from -http://www.python.org/peps/. As of September 2000, there are 25 PEPS, ranging +https://www.python.org/peps/. As of September 2000, there are 25 PEPS, ranging from PEP 201, "Lockstep Iteration", to PEP 225, "Elementwise/Objectwise Operators". @@ -566,7 +566,7 @@ such as ``cmp(a,b)`` would always produce an answer, even if a user-defined simply be silently swallowed. .. Starting URL: -.. http://www.python.org/pipermail/python-dev/2000-April/004834.html +.. https://www.python.org/pipermail/python-dev/2000-April/004834.html Work has been done on porting Python to 64-bit Windows on the Itanium processor, mostly by Trent Mick of ActiveState. (Confusingly, ``sys.platform`` is still @@ -1003,7 +1003,7 @@ Relationship to PyXML The XML Special Interest Group has been working on XML-related Python code for a while. Its code distribution, called PyXML, is available from the SIG's Web -pages at http://www.python.org/sigs/xml-sig/. The PyXML distribution also used +pages at https://www.python.org/community/sigs/current/xml-sig. The PyXML distribution also used the package name ``xml``. If you've written programs that used PyXML, you're probably wondering about its compatibility with the 2.0 :mod:`xml` package. @@ -1174,8 +1174,8 @@ partial list: * In the editor window, there is now a line/column bar at the bottom. -* Three new keystroke commands: Check module (Alt-F5), Import module (F5) and - Run script (Ctrl-F5). +* Three new keystroke commands: Check module (:kbd:`Alt-F5`), Import module (:kbd:`F5`) and + Run script (:kbd:`Ctrl-F5`). .. ====================================================================== diff --git a/Doc/whatsnew/2.1.rst b/Doc/whatsnew/2.1.rst index b1ab48e7f4bf..ff1566226d05 100644 --- a/Doc/whatsnew/2.1.rst +++ b/Doc/whatsnew/2.1.rst @@ -219,7 +219,7 @@ comparison. I won't cover the C API here, but will refer you to PEP 207, or to .. seealso:: - :pep:`207` - Rich Comparisions + :pep:`207` - Rich Comparisons Written by Guido van Rossum, heavily based on earlier work by David Ascher, and implemented by Guido van Rossum. @@ -555,14 +555,14 @@ will include metadata, making it possible to build automated cataloguing systems and experiment with them. With the result experience, perhaps it'll be possible to design a really good catalog and then build support for it into Python 2.2. For example, the Distutils :command:`sdist` and :command:`bdist_\*` commands -could support a :option:`upload` option that would automatically upload your +could support a ``upload`` option that would automatically upload your package to a catalog server. You can start creating packages containing :file:`PKG-INFO` even if you're not using Python 2.1, since a new release of the Distutils will be made for users of earlier Python versions. Version 1.0.2 of the Distutils includes the changes described in PEP 241, as well as various bugfixes and enhancements. It will be -available from the Distutils SIG at http://www.python.org/sigs/distutils-sig/. +available from the Distutils SIG at https://www.python.org/sigs/distutils-sig/. .. seealso:: @@ -731,7 +731,7 @@ of the more notable changes are: ... For a fuller discussion of the line I/O changes, see the python-dev summary for - January 1-15, 2001 at http://www.python.org/dev/summary/2001-01-1/. + January 1-15, 2001 at https://www.python.org/dev/summary/2001-01-1/. * A new method, :meth:`popitem`, was added to dictionaries to enable destructively iterating through the contents of a dictionary; this can be faster diff --git a/Doc/whatsnew/2.2.rst b/Doc/whatsnew/2.2.rst index 31b6df439c69..f3c4a9134693 100644 --- a/Doc/whatsnew/2.2.rst +++ b/Doc/whatsnew/2.2.rst @@ -24,8 +24,8 @@ up irregularities and dark corners of the language design. This article doesn't attempt to provide a complete specification of the new features, but instead provides a convenient overview. For full details, you should refer to the documentation for Python 2.2, such as the `Python Library -Reference <http://www.python.org/doc/2.2/lib/lib.html>`_ and the `Python -Reference Manual <http://www.python.org/doc/2.2/ref/ref.html>`_. If you want to +Reference <https://www.python.org/doc/2.2/lib/lib.html>`_ and the `Python +Reference Manual <https://www.python.org/doc/2.2/ref/ref.html>`_. If you want to understand the complete implementation and design rationale for a change, refer to the PEP for a particular new feature. @@ -395,7 +395,7 @@ This section has just been a quick overview of the new features, giving enough of an explanation to start you programming, but many details have been simplified or ignored. Where should you go to get a more complete picture? -http://www.python.org/2.2/descrintro.html is a lengthy tutorial introduction to +https://www.python.org/2.2/descrintro.html is a lengthy tutorial introduction to the descriptor features, written by Guido van Rossum. If my description has whetted your appetite, go read this tutorial next, because it goes into much more detail about the new features while still remaining quite easy to read. diff --git a/Doc/whatsnew/2.3.rst b/Doc/whatsnew/2.3.rst index f0e48d972249..f478c090b135 100644 --- a/Doc/whatsnew/2.3.rst +++ b/Doc/whatsnew/2.3.rst @@ -657,7 +657,7 @@ The heart of the catalog is the new Distutils :command:`register` command. Running ``python setup.py register`` will collect the metadata describing a package, such as its name, version, maintainer, description, &c., and send it to a central catalog server. The resulting catalog is available from -http://www.python.org/pypi. +https://pypi.python.org/pypi. To make the catalog a bit more useful, a new optional *classifiers* keyword argument has been added to the Distutils :func:`setup` function. A list of @@ -1082,9 +1082,9 @@ Here are all of the changes that Python 2.3 makes to the core Python language. C3 algorithm as described in the paper `"A Monotonic Superclass Linearization for Dylan" <http://www.webcom.com/haahr/dylan/linearization-oopsla96.html>`_. To understand the motivation for this change, read Michele Simionato's article - `"Python 2.3 Method Resolution Order" <http://www.python.org/2.3/mro.html>`_, or + `"Python 2.3 Method Resolution Order" <https://www.python.org/2.3/mro.html>`_, or read the thread on python-dev starting with the message at - http://mail.python.org/pipermail/python-dev/2002-October/029035.html. Samuele + https://mail.python.org/pipermail/python-dev/2002-October/029035.html. Samuele Pedroni first pointed out the problem and also implemented the fix by coding the C3 algorithm. @@ -1330,7 +1330,7 @@ complete list of changes, or look through the CVS logs for all the details. (Contributed by Kevin O'Connor.) * The IDLE integrated development environment has been updated using the code - from the IDLEfork project (http://idlefork.sf.net). The most notable feature is + from the IDLEfork project (http://idlefork.sourceforge.net). The most notable feature is that the code being developed is now executed in a subprocess, meaning that there's no longer any need for manual ``reload()`` operations. IDLE's core code has been incorporated into the standard library as the :mod:`idlelib` package. @@ -1564,7 +1564,7 @@ complete list of changes, or look through the CVS logs for all the details. to the correct thread, and waiting for the results. Other interfaces can't be handled automatically but :mod:`Tkinter` will now raise an exception on such an access so that you can at least find out about the problem. See - http://mail.python.org/pipermail/python-dev/2002-December/031107.html for a more + https://mail.python.org/pipermail/python-dev/2002-December/031107.html for a more detailed explanation of this change. (Implemented by Martin von Löwis.) * Calling Tcl methods through :mod:`_tkinter` no longer returns only strings. @@ -1858,7 +1858,7 @@ and bundle it with the source of your extension. .. seealso:: - http://svn.python.org/view/python/trunk/Objects/obmalloc.c + https://svn.python.org/view/python/trunk/Objects/obmalloc.c For the full details of the pymalloc implementation, see the comments at the top of the file :file:`Objects/obmalloc.c` in the Python source code. The above link points to the file within the python.org SVN browser. diff --git a/Doc/whatsnew/2.4.rst b/Doc/whatsnew/2.4.rst index 5a28f891acdb..569e5e925fa9 100644 --- a/Doc/whatsnew/2.4.rst +++ b/Doc/whatsnew/2.4.rst @@ -337,7 +337,7 @@ returned. wrote patches implementing function decorators, but the one that was actually checked in was patch #979728, written by Mark Russell. - http://www.python.org/moin/PythonDecoratorLibrary + https://www.python.org/moin/PythonDecoratorLibrary This Wiki page contains several examples of decorators. .. ====================================================================== @@ -846,7 +846,7 @@ Here are all of the changes that Python 2.4 makes to the core Python language. ['A', 'b', 'c', 'D'] Finally, the *reverse* parameter takes a Boolean value. If the value is true, - the list will be sorted into reverse order. Instead of ``L.sort() ; + the list will be sorted into reverse order. Instead of ``L.sort(); L.reverse()``, you can now write ``L.sort(reverse=True)``. The results of sorting are now guaranteed to be stable. This means that two diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst index b91e6479e412..cb92e08d6f84 100644 --- a/Doc/whatsnew/2.5.rst +++ b/Doc/whatsnew/2.5.rst @@ -39,7 +39,7 @@ finds there were 353 patches applied and 458 bugs fixed between Python 2.4 and This article doesn't try to be a complete specification of the new features; instead changes are briefly introduced using helpful examples. For full details, you should always refer to the documentation for Python 2.5 at -http://docs.python.org. If you want to understand the complete implementation +https://docs.python.org. If you want to understand the complete implementation and design rationale, refer to the PEP for a particular new feature. Comments, suggestions, and error reports for this document are welcome; please @@ -229,7 +229,7 @@ required packages. :: ) Another new enhancement to the Python package index at -http://cheeseshop.python.org is storing source and binary archives for a +https://pypi.python.org is storing source and binary archives for a package. The new :command:`upload` Distutils command will upload a package to the repository. @@ -286,7 +286,7 @@ Python's standard :mod:`string` module? There's no clean way to ignore :mod:`pkg.string` and look for the standard module; generally you had to look at the contents of ``sys.modules``, which is slightly unclean. Holger Krekel's :mod:`py.std` package provides a tidier way to perform imports from the standard -library, ``import py ; py.std.string.join()``, but that package isn't available +library, ``import py; py.std.string.join()``, but that package isn't available on all Python installations. Reading code which relies on relative imports is also less clear, because a @@ -827,7 +827,7 @@ inheritance relationships are:: This rearrangement was done because people often want to catch all exceptions that indicate program errors. :exc:`KeyboardInterrupt` and :exc:`SystemExit` aren't errors, though, and usually represent an explicit action such as the user -hitting Control-C or code calling :func:`sys.exit`. A bare ``except:`` will +hitting :kbd:`Control-C` or code calling :func:`sys.exit`. A bare ``except:`` will catch all exceptions, so you commonly need to list :exc:`KeyboardInterrupt` and :exc:`SystemExit` in order to re-raise them. The usual pattern is:: @@ -2130,7 +2130,7 @@ Changes to Python's build process and to the C API include: such as PyCon. .. List of names taken from Jeremy's python-dev post at - .. http://mail.python.org/pipermail/python-dev/2005-October/057500.html + .. https://mail.python.org/pipermail/python-dev/2005-October/057500.html * Evan Jones's patch to obmalloc, first described in a talk at PyCon DC 2005, was applied. Python 2.4 allocated small objects in 256K-sized arenas, but never diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst index bdd7ff7d8166..e7632652693b 100644 --- a/Doc/whatsnew/2.6.rst +++ b/Doc/whatsnew/2.6.rst @@ -164,7 +164,7 @@ is an open-source project that requires volunteers to administer it and a server to host it. After posting a call for volunteers, a new Roundup installation was -set up at http://bugs.python.org. One installation of Roundup can +set up at https://bugs.python.org. One installation of Roundup can host multiple trackers, and this server now also hosts issue trackers for Jython and for the Python web site. It will surely find other uses in the future. Where possible, @@ -181,7 +181,7 @@ other projects wishing to move from SourceForge to Roundup. .. seealso:: - http://bugs.python.org + https://bugs.python.org The Python bug tracker. http://bugs.jython.org: @@ -227,18 +227,18 @@ the Python community. Sphinx is a standalone package that can be used for writing, and almost two dozen other projects -(`listed on the Sphinx web site <http://sphinx.pocoo.org/examples.html>`__) +(`listed on the Sphinx web site <http://sphinx-doc.org/examples.html>`__) have adopted Sphinx as their documentation tool. .. seealso:: - `Documenting Python <http://docs.python.org/devguide/documenting.html>`__ + `Documenting Python <https://docs.python.org/devguide/documenting.html>`__ Describes how to write for Python's documentation. - `Sphinx <http://sphinx.pocoo.org/>`__ + `Sphinx <http://sphinx-doc.org/>`__ Documentation and code for the Sphinx toolchain. - `Docutils <http://docutils.sf.net>`__ + `Docutils <http://docutils.sourceforge.net>`__ The underlying reStructuredText parser and toolset. @@ -1891,7 +1891,7 @@ changes, or look through the Subversion logs for all the details. >>> dq=deque(maxlen=3) >>> dq deque([], maxlen=3) - >>> dq.append(1) ; dq.append(2) ; dq.append(3) + >>> dq.append(1); dq.append(2); dq.append(3) >>> dq deque([1, 2, 3], maxlen=3) >>> dq.append(4) @@ -2363,7 +2363,7 @@ changes, or look through the Subversion logs for all the details. negotiation itself. (Patch contributed by Bill Fenner; :issue:`829951`.) -* The :mod:`socket` module now supports TIPC (http://tipc.sf.net), +* The :mod:`socket` module now supports TIPC (http://tipc.sourceforge.net/), a high-performance non-IP-based protocol designed for use in clustered environments. TIPC addresses are 4- or 5-tuples. (Contributed by Alberto Bertogli; :issue:`1646`.) @@ -2783,12 +2783,12 @@ http://www.json.org. types. The following example encodes and decodes a dictionary:: >>> import json - >>> data = {"spam" : "foo", "parrot" : 42} + >>> data = {"spam": "foo", "parrot": 42} >>> in_json = json.dumps(data) # Encode the data >>> in_json '{"parrot": 42, "spam": "foo"}' >>> json.loads(in_json) # Decode into a Python object - {"spam" : "foo", "parrot" : 42} + {"spam": "foo", "parrot": 42} It's also possible to write your own decoders and encoders to support more types. Pretty-printing of the JSON strings is also supported. diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst index b26c9b27bedf..fb0551e1add8 100644 --- a/Doc/whatsnew/2.7.rst +++ b/Doc/whatsnew/2.7.rst @@ -7,7 +7,6 @@ .. hyperlink all the methods & functions. .. T_STRING_INPLACE not described in main docs -.. "Format String Syntax" in string.rst could use many more examples. .. $Id$ Rules for maintenance: @@ -50,17 +49,16 @@ This saves the maintainer some effort going through the SVN logs when researching a change. -This article explains the new features in Python 2.7. The final -release of 2.7 is currently scheduled for July 2010; the detailed -schedule is described in :pep:`373`. +This article explains the new features in Python 2.7. Python 2.7 was released +on July 3, 2010. Numeric handling has been improved in many ways, for both -floating-point numbers and for the :class:`Decimal` class. There are -some useful additions to the standard library, such as a greatly -enhanced :mod:`unittest` module, the :mod:`argparse` module for -parsing command-line options, convenient ordered-dictionary and -:class:`Counter` classes in the :mod:`collections` module, and many -other improvements. +floating-point numbers and for the :class:`~decimal.Decimal` class. +There are some useful additions to the standard library, such as a +greatly enhanced :mod:`unittest` module, the :mod:`argparse` module +for parsing command-line options, convenient :class:`~collections.OrderedDict` +and :class:`~collections.Counter` classes in the :mod:`collections` module, +and many other improvements. Python 2.7 is planned to be the last of the 2.x releases, so we worked on making it a good release for the long term. To help with porting @@ -70,9 +68,9 @@ included in 2.7. This article doesn't attempt to provide a complete specification of the new features, but instead provides a convenient overview. For full details, you should refer to the documentation for Python 2.7 at -http://docs.python.org. If you want to understand the rationale for +https://docs.python.org. If you want to understand the rationale for the design and implementation, refer to the PEP for a particular new -feature or the issue on http://bugs.python.org in which a change was +feature or the issue on https://bugs.python.org in which a change was discussed. Whenever possible, "What's New in Python" links to the bug/patch item for each change. @@ -81,45 +79,91 @@ bug/patch item for each change. The Future for Python 2.x ========================= -Python 2.7 is intended to be the last major release in the 2.x series. -The Python maintainers are planning to focus their future efforts on -the Python 3.x series. - -This means that 2.7 will remain in place for a long time, running -production systems that have not been ported to Python 3.x. -Two consequences of the long-term significance of 2.7 are: - -* It's very likely the 2.7 release will have a longer period of - maintenance compared to earlier 2.x versions. Python 2.7 will - continue to be maintained while the transition to 3.x continues, and - the developers are planning to support Python 2.7 with bug-fix - releases beyond the typical two years. - -* A policy decision was made to silence warnings only of interest to - developers. :exc:`DeprecationWarning` and its - descendants are now ignored unless otherwise requested, preventing - users from seeing warnings triggered by an application. This change - was also made in the branch that will become Python 3.2. (Discussed - on stdlib-sig and carried out in :issue:`7319`.) - - In previous releases, :exc:`DeprecationWarning` messages were - enabled by default, providing Python developers with a clear - indication of where their code may break in a future major version - of Python. - - However, there are increasingly many users of Python-based - applications who are not directly involved in the development of - those applications. :exc:`DeprecationWarning` messages are - irrelevant to such users, making them worry about an application - that's actually working correctly and burdening application developers - with responding to these concerns. - - You can re-enable display of :exc:`DeprecationWarning` messages by - running Python with the :option:`-Wdefault` (short form: - :option:`-Wd`) switch, or by setting the :envvar:`PYTHONWARNINGS` - environment variable to ``"default"`` (or ``"d"``) before running - Python. Python code can also re-enable them - by calling ``warnings.simplefilter('default')``. +Python 2.7 is the last major release in the 2.x series, as the Python +maintainers have shifted the focus of their new feature development efforts +to the Python 3.x series. This means that while Python 2 continues to +receive bug fixes, and to be updated to build correctly on new hardware and +versions of supported operated systems, there will be no new full feature +releases for the language or standard library. + +However, while there is a large common subset between Python 2.7 and Python +3, and many of the changes involved in migrating to that common subset, or +directly to Python 3, can be safely automated, some other changes (notably +those associated with Unicode handling) may require careful consideration, +and preferably robust automated regression test suites, to migrate +effectively. + +This means that Python 2.7 will remain in place for a long time, providing a +stable and supported base platform for production systems that have not yet +been ported to Python 3. The full expected lifecycle of the Python 2.7 +series is detailed in :pep:`373`. + +Some key consequences of the long-term significance of 2.7 are: + +* As noted above, the 2.7 release has a much longer period of maintenance + when compared to earlier 2.x versions. Python 2.7 is currently expected to + remain supported by the core development team (receiving security updates + and other bug fixes) until at least 2020 (10 years after its initial + release, compared to the more typical support period of 18-24 months). + +* As the Python 2.7 standard library ages, making effective use of the + Python Package Index (either directly or via a redistributor) becomes + more important for Python 2 users. In addition to a wide variety of third + party packages for various tasks, the available packages include backports + of new modules and features from the Python 3 standard library that are + compatible with Python 2, as well as various tools and libraries that can + make it easier to migrate to Python 3. The `Python Packaging User Guide + <https://packaging.python.org>`__ provides guidance on downloading and + installing software from the Python Package Index. + +* While the preferred approach to enhancing Python 2 is now the publication + of new packages on the Python Package Index, this approach doesn't + necessarily work in all cases, especially those related to network + security. In exceptional cases that cannot be handled adequately by + publishing new or updated packages on PyPI, the Python Enhancement + Proposal process may be used to make the case for adding new features + directly to the Python 2 standard library. Any such additions, and the + maintenance releases where they were added, will be noted in the + :ref:`py27-maintenance-enhancements` section below. + +For projects wishing to migrate from Python 2 to Python 3, or for library +and framework developers wishing to support users on both Python 2 and +Python 3, there are a variety of tools and guides available to help decide +on a suitable approach and manage some of the technical details involved. +The recommended starting point is the :ref:`pyporting-howto` HOWTO guide. + + +Changes to the Handling of Deprecation Warnings +=============================================== + +For Python 2.7, a policy decision was made to silence warnings only of +interest to developers by default. :exc:`DeprecationWarning` and its +descendants are now ignored unless otherwise requested, preventing +users from seeing warnings triggered by an application. This change +was also made in the branch that became Python 3.2. (Discussed +on stdlib-sig and carried out in :issue:`7319`.) + +In previous releases, :exc:`DeprecationWarning` messages were +enabled by default, providing Python developers with a clear +indication of where their code may break in a future major version +of Python. + +However, there are increasingly many users of Python-based +applications who are not directly involved in the development of +those applications. :exc:`DeprecationWarning` messages are +irrelevant to such users, making them worry about an application +that's actually working correctly and burdening application developers +with responding to these concerns. + +You can re-enable display of :exc:`DeprecationWarning` messages by +running Python with the :option:`-Wdefault <-W>` (short form: +:option:`-Wd <-W>`) switch, or by setting the :envvar:`PYTHONWARNINGS` +environment variable to ``"default"`` (or ``"d"``) before running +Python. Python code can also re-enable them +by calling ``warnings.simplefilter('default')``. + +The ``unittest`` module also automatically reenables deprecation warnings +when running tests. Python 3.1 Features @@ -133,7 +177,7 @@ for migrating to the 3.x series. A partial list of 3.1 features that were backported to 2.7: * The syntax for set literals (``{1,2,3}`` is a mutable set). -* Dictionary and set comprehensions (``{ i: i*2 for i in range(3)}``). +* Dictionary and set comprehensions (``{i: i*2 for i in range(3)}``). * Multiple context managers in a single :keyword:`with` statement. * A new version of the :mod:`io` library, rewritten in C for performance. * The ordered-dictionary type described in :ref:`pep-0372`. @@ -155,7 +199,7 @@ Other new Python3-mode warnings include: * :func:`operator.isCallable` and :func:`operator.sequenceIncludes`, which are not supported in 3.x, now trigger warnings. * The :option:`-3` switch now automatically - enables the :option:`-Qwarn` switch that causes warnings + enables the :option:`-Qwarn <-Q>` switch that causes warnings about using classic division with integers and long integers. @@ -390,9 +434,10 @@ standard input or output. .. seealso:: - `argparse module documentation <http://docs.python.org/dev/library/argparse.html>`__ + :mod:`argparse` documentation + The documentation page of the argparse module. - `Upgrading optparse code to use argparse <http://docs.python.org/dev/library/argparse.html#upgrading-optparse-code>`__ + :ref:`upgrading-optparse-code` Part of the Python documentation, describing how to convert code that uses :mod:`optparse`. @@ -402,8 +447,6 @@ standard input or output. PEP 391: Dictionary-Based Configuration For Logging ==================================================== -.. XXX not documented in library reference yet; add link here once it's added. - The :mod:`logging` module is very flexible; applications can define a tree of logging subsystems, and each logger in this tree can filter out certain messages, format them differently, and direct messages to @@ -412,21 +455,21 @@ a varying number of handlers. All this flexibility can require a lot of configuration. You can write Python statements to create objects and set their properties, but a complex set-up requires verbose but boring code. -:mod:`logging` also supports a :func:`~logging.config.fileConfig` +:mod:`logging` also supports a :func:`~logging.fileConfig` function that parses a file, but the file format doesn't support configuring filters, and it's messier to generate programmatically. -Python 2.7 adds a :func:`~logging.config.dictConfig` function that +Python 2.7 adds a :func:`~logging.dictConfig` function that uses a dictionary to configure logging. There are many ways to produce a dictionary from different sources: construct one with code; parse a file containing JSON; or use a YAML parsing library if one is -installed. +installed. For more information see :ref:`logging-config-api`. The following example configures two loggers, the root logger and a -logger named "network". Messages sent to the root logger will be +logger named "network". Messages sent to the root logger will be sent to the system log using the syslog protocol, and messages to the "network" logger will be written to a :file:`network.log` file -that will be rotated once the log reaches 1Mb. +that will be rotated once the log reaches 1MB. :: @@ -445,7 +488,7 @@ that will be rotated once the log reaches 1Mb. 'filename': '/logs/network.log', 'formatter': 'standard', 'level': 'INFO', - 'maxBytes': 1024*1024}, + 'maxBytes': 1000000}, 'syslog': {'class': 'logging.handlers.SysLogHandler', 'formatter': 'standard', 'level': 'ERROR'}}, @@ -483,16 +526,19 @@ implemented by Vinay Sajip, are: for UDP or :const:`socket.SOCK_STREAM` for TCP. The default protocol remains UDP. -* :class:`Logger` instances gained a :meth:`getChild` method that retrieves a - descendant logger using a relative path. For example, - once you retrieve a logger by doing ``log = getLogger('app')``, +* :class:`~logging.Logger` instances gained a :meth:`~logging.Logger.getChild` + method that retrieves a descendant logger using a relative path. + For example, once you retrieve a logger by doing ``log = getLogger('app')``, calling ``log.getChild('network.listen')`` is equivalent to ``getLogger('app.network.listen')``. -* The :class:`LoggerAdapter` class gained a :meth:`isEnabledFor` method - that takes a *level* and returns whether the underlying logger would +* The :class:`~logging.LoggerAdapter` class gained a + :meth:`~logging.LoggerAdapter.isEnabledFor` method that takes a + *level* and returns whether the underlying logger would process a message of that level of importance. +.. XXX: Logger objects don't have a class declaration so the link don't work + .. seealso:: :pep:`391` - Dictionary-Based Configuration For Logging @@ -501,14 +547,15 @@ implemented by Vinay Sajip, are: PEP 3106: Dictionary Views ==================================================== -The dictionary methods :meth:`keys`, :meth:`values`, and :meth:`items` -are different in Python 3.x. They return an object called a :dfn:`view` -instead of a fully materialized list. +The dictionary methods :meth:`~dict.keys`, :meth:`~dict.values`, and +:meth:`~dict.items` are different in Python 3.x. They return an object +called a :dfn:`view` instead of a fully materialized list. -It's not possible to change the return values of :meth:`keys`, -:meth:`values`, and :meth:`items` in Python 2.7 because too much code -would break. Instead the 3.x versions were added under the new names -:meth:`viewkeys`, :meth:`viewvalues`, and :meth:`viewitems`. +It's not possible to change the return values of :meth:`~dict.keys`, +:meth:`~dict.values`, and :meth:`~dict.items` in Python 2.7 because +too much code would break. Instead the 3.x versions were added +under the new names :meth:`~dict.viewkeys`, :meth:`~dict.viewvalues`, +and :meth:`~dict.viewitems`. :: @@ -550,8 +597,8 @@ over the view:: RuntimeError: dictionary changed size during iteration You can use the view methods in Python 2.x code, and the 2to3 -converter will change them to the standard :meth:`keys`, -:meth:`values`, and :meth:`items` methods. +converter will change them to the standard :meth:`~dict.keys`, +:meth:`~dict.values`, and :meth:`~dict.items` methods. .. seealso:: @@ -624,7 +671,7 @@ Some smaller changes made to the core Python language are: ``{}`` continues to represent an empty dictionary; use ``set()`` for an empty set. - >>> {1,2,3,4,5} + >>> {1, 2, 3, 4, 5} set([1, 2, 3, 4, 5]) >>> set() # empty set set([]) @@ -661,7 +708,7 @@ Some smaller changes made to the core Python language are: The :func:`contextlib.nested` function provides a very similar function, so it's no longer necessary and has been deprecated. - (Proposed in http://codereview.appspot.com/53094; implemented by + (Proposed in https://codereview.appspot.com/53094; implemented by Georg Brandl.) * Conversions between floating-point numbers and strings are @@ -794,7 +841,7 @@ Some smaller changes made to the core Python language are: ``None`` as its first argument. (Fixed by Georg Brandl; :issue:`4759`.) - .. bytearray doesn't seem to be documented + .. XXX bytearray doesn't seem to be documented * When using ``@classmethod`` and ``@staticmethod`` to wrap methods as class or static methods, the wrapper object now @@ -867,12 +914,6 @@ Optimizations Several performance enhancements have been added: -.. * A new :program:`configure` option, :option:`--with-computed-gotos`, - compiles the main bytecode interpreter loop using a new dispatch - mechanism that gives speedups of up to 20%, depending on the system - and benchmark. The new mechanism is only supported on certain - compilers, such as gcc, SunPro, and icc. - * A new opcode was added to perform the initial setup for :keyword:`with` statements, looking up the :meth:`__enter__` and :meth:`__exit__` methods. (Contributed by Benjamin Peterson.) @@ -1054,7 +1095,7 @@ changes, or look through the Subversion logs for all the details. :meth:`~collections.deque.count` method that returns the number of contained elements equal to the supplied argument *x*, and a :meth:`~collections.deque.reverse` method that reverses the elements - of the deque in-place. :class:`deque` also exposes its maximum + of the deque in-place. :class:`~collections.deque` also exposes its maximum length as the read-only :attr:`~collections.deque.maxlen` attribute. (Both features added by Raymond Hettinger.) @@ -1135,15 +1176,14 @@ changes, or look through the Subversion logs for all the details. ``Decimal('0.1000000000000000055511151231257827021181583404541015625')``. (Implemented by Raymond Hettinger; :issue:`4796`.) - Comparing instances of :class:`Decimal` with floating-point + Comparing instances of :class:`~decimal.Decimal` with floating-point numbers now produces sensible results based on the numeric values of the operands. Previously such comparisons would fall back to Python's default rules for comparing objects, which produced arbitrary results based on their type. Note that you still cannot combine :class:`Decimal` and floating-point in other operations such as addition, since you should be explicitly choosing how to convert between float and - :class:`Decimal`. - (Fixed by Mark Dickinson; :issue:`2531`.) + :class:`~decimal.Decimal`. (Fixed by Mark Dickinson; :issue:`2531`.) The constructor for :class:`~decimal.Decimal` now accepts floating-point numbers (added by Raymond Hettinger; :issue:`8257`) @@ -1195,8 +1235,8 @@ changes, or look through the Subversion logs for all the details. Ordering comparisons (``<``, ``<=``, ``>``, ``>=``) between fractions and complex numbers now raise a :exc:`TypeError`. - This fixes an oversight, making the :class:`Fraction` match the other - numeric types. + This fixes an oversight, making the :class:`~fractions.Fraction` + match the other numeric types. .. revision 79455 @@ -1210,7 +1250,7 @@ changes, or look through the Subversion logs for all the details. uploads thanks to an added *rest* parameter (patch by Pablo Mouzo; :issue:`6845`.) -* New class decorator: :func:`total_ordering` in the :mod:`functools` +* New class decorator: :func:`~functools.total_ordering` in the :mod:`functools` module takes a class that defines an :meth:`__eq__` method and one of :meth:`__lt__`, :meth:`__le__`, :meth:`__gt__`, or :meth:`__ge__`, and generates the missing comparison methods. Since the @@ -1218,7 +1258,7 @@ changes, or look through the Subversion logs for all the details. this decorator makes it easier to define ordered classes. (Added by Raymond Hettinger; :issue:`5479`.) - New function: :func:`cmp_to_key` will take an old-style comparison + New function: :func:`~functools.cmp_to_key` will take an old-style comparison function that expects two arguments and return a new callable that can be used as the *key* parameter to functions such as :func:`sorted`, :func:`min` and :func:`max`, etc. The primary @@ -1345,7 +1385,7 @@ changes, or look through the Subversion logs for all the details. with any object literal that decodes to a list of pairs. (Contributed by Raymond Hettinger; :issue:`5381`.) -* The :mod:`mailbox` module's :class:`Maildir` class now records the +* The :mod:`mailbox` module's :class:`~mailbox.Maildir` class now records the timestamp on the directories it reads, and only re-reads them if the modification time has subsequently changed. This improves performance by avoiding unneeded directory scans. (Fixed by @@ -1432,7 +1472,7 @@ changes, or look through the Subversion logs for all the details. * The :mod:`signal` module no longer re-installs the signal handler unless this is truly necessary, which fixes a bug that could make it impossible to catch the EINTR signal robustly. (Fixed by - Charles-François Natali; :issue:`8354`.) + Charles-Francois Natali; :issue:`8354`.) * New functions: in the :mod:`site` module, three new functions return various site- and user-specific paths. @@ -1466,10 +1506,10 @@ changes, or look through the Subversion logs for all the details. defaults to False; if overridden to be True, new request connections will have the TCP_NODELAY option set to prevent buffering many small sends into a single TCP packet. - The :attr:`~SocketServer.TCPServer.timeout` class attribute can hold + The :attr:`~SocketServer.BaseServer.timeout` class attribute can hold a timeout in seconds that will be applied to the request socket; if - no request is received within that time, :meth:`handle_timeout` - will be called and :meth:`handle_request` will return. + no request is received within that time, :meth:`~SocketServer.BaseServer.handle_timeout` + will be called and :meth:`~SocketServer.BaseServer.handle_request` will return. (Contributed by Kristján Valur Jónsson; :issue:`6192` and :issue:`6267`.) * Updated module: the :mod:`sqlite3` module has been updated to @@ -1479,7 +1519,7 @@ changes, or look through the Subversion logs for all the details. and then call :meth:`~sqlite3.Connection.load_extension` to load a particular shared library. (Updated by Gerhard Häring.) -* The :mod:`ssl` module's :class:`ssl.SSLSocket` objects now support the +* The :mod:`ssl` module's :class:`~ssl.SSLSocket` objects now support the buffer API, which fixed a test suite failure (fix by Antoine Pitrou; :issue:`7133`) and automatically set OpenSSL's :c:macro:`SSL_MODE_AUTO_RETRY`, which will prevent an error @@ -1535,7 +1575,7 @@ changes, or look through the Subversion logs for all the details. on receiving an :const:`EINTR` signal. (Reported by several people; final patch by Gregory P. Smith in :issue:`1068268`.) -* New function: :func:`~symtable.is_declared_global` in the :mod:`symtable` module +* New function: :func:`~symtable.Symbol.is_declared_global` in the :mod:`symtable` module returns true for variables that are explicitly declared to be global, false for ones that are implicitly global. (Contributed by Jeremy Hylton.) @@ -1572,7 +1612,7 @@ changes, or look through the Subversion logs for all the details. resulting archive. This is more powerful than the existing *exclude* argument, which has therefore been deprecated. (Added by Lars Gustäbel; :issue:`6856`.) - The :class:`~tarfile.TarFile` class also now supports the context manager protocol. + The :class:`~tarfile.TarFile` class also now supports the context management protocol. (Added by Lars Gustäbel; :issue:`7232`.) * The :meth:`~threading.Event.wait` method of the :class:`threading.Event` class @@ -1716,7 +1756,7 @@ Some of the functions in the module are: Makefile and the :file:`pyconfig.h` file. * :func:`~sysconfig.get_config_vars` returns a dictionary containing all of the configuration variables. -* :func:`~sysconfig.getpath` returns the configured path for +* :func:`~sysconfig.get_path` returns the configured path for a particular type of module: the standard library, site-specific modules, platform-specific modules, etc. * :func:`~sysconfig.is_python_build` returns true if you're running a @@ -1727,7 +1767,7 @@ a complete list of functions. The Distutils package and :mod:`sysconfig` are now maintained by Tarek Ziadé, who has also started a Distutils2 package (source repository at -http://hg.python.org/distutils2/) for developing a next-generation +https://hg.python.org/distutils2/) for developing a next-generation version of Distutils. @@ -1764,7 +1804,7 @@ new features were added. Most of these features were implemented by Michael Foord, unless otherwise noted. The enhanced version of the module is downloadable separately for use with Python versions 2.4 to 2.6, packaged as the :mod:`unittest2` package, from -http://pypi.python.org/pypi/unittest2. +https://pypi.python.org/pypi/unittest2. When used from the command line, the module can automatically discover tests. It's not as fancy as `py.test <http://pytest.org>`__ or @@ -1778,7 +1818,7 @@ any importable test files named ``test*.py``:: Consult the :mod:`unittest` module documentation for more details. (Developed in :issue:`6001`.) -The :func:`main` function supports some other new options: +The :func:`~unittest.main` function supports some other new options: * :option:`-b` or :option:`--buffer` will buffer the standard output and standard error streams during each test. If the test passes, @@ -1796,7 +1836,7 @@ The :func:`main` function supports some other new options: being tested or the tests being run have defined a signal handler of their own, by noticing that a signal handler was already set and calling it. If this doesn't work for you, there's a - :func:`removeHandler` decorator that can be used to mark tests that + :func:`~unittest.removeHandler` decorator that can be used to mark tests that should have the control-C handling disabled. * :option:`-f` or :option:`--failfast` makes @@ -1923,7 +1963,7 @@ GvR worked on merging them into Python's version of :mod:`unittest`. :func:`unittest.main` now takes an optional ``exit`` argument. If False, :func:`~unittest.main` doesn't call :func:`sys.exit`, allowing -:func:`main` to be used from the interactive interpreter. +:func:`~unittest.main` to be used from the interactive interpreter. (Contributed by J. Pablo Fernández; :issue:`3379`.) :class:`~unittest.TestResult` has new :meth:`~unittest.TestResult.startTestRun` and @@ -2120,7 +2160,7 @@ Changes to Python's build process and to the C API include: :c:macro:`Py_ISSPACE`, :c:macro:`Py_ISUPPER`, :c:macro:`Py_ISXDIGIT`, - and :c:macro:`Py_TOLOWER`, :c:macro:`Py_TOUPPER`. + :c:macro:`Py_TOLOWER`, and :c:macro:`Py_TOUPPER`. All of these functions are analogous to the C standard macros for classifying characters, but ignore the current locale setting, because in @@ -2266,11 +2306,11 @@ Port-Specific Changes: Windows (Contributed by David Cournapeau; :issue:`4365`.) * The :mod:`_winreg` module for accessing the registry now implements - the :func:`CreateKeyEx` and :func:`DeleteKeyEx` functions, extended - versions of previously-supported functions that take several extra - arguments. The :func:`DisableReflectionKey`, - :func:`EnableReflectionKey`, and :func:`QueryReflectionKey` were also - tested and documented. + the :func:`~_winreg.CreateKeyEx` and :func:`~_winreg.DeleteKeyEx` + functions, extended versions of previously-supported functions that + take several extra arguments. The :func:`~_winreg.DisableReflectionKey`, + :func:`~_winreg.EnableReflectionKey`, and :func:`~_winreg.QueryReflectionKey` + were also tested and documented. (Implemented by Brian Curtin: :issue:`7347`.) * The new :c:func:`_beginthreadex` API is used to start threads, and @@ -2280,7 +2320,7 @@ Port-Specific Changes: Windows * The :func:`os.kill` function now works on Windows. The signal value can be the constants :const:`CTRL_C_EVENT`, :const:`CTRL_BREAK_EVENT`, or any integer. The first two constants - will send Control-C and Control-Break keystroke events to + will send :kbd:`Control-C` and :kbd:`Control-Break` keystroke events to subprocesses; any other value will use the :c:func:`TerminateProcess` API. (Contributed by Miki Tebeka; :issue:`1220212`.) @@ -2329,7 +2369,7 @@ Other Changes and Fixes attributes of the resulting code objects are overwritten when the original filename is obsolete. This can happen if the file has been renamed, moved, or is accessed through different paths. (Patch by - Žiga Seilnacht and Jean-Paul Calderone; :issue:`1180193`.) + Ziga Seilnacht and Jean-Paul Calderone; :issue:`1180193`.) * The :file:`regrtest.py` script now takes a :option:`--randseed=` switch that takes an integer that will be used as the random seed @@ -2387,20 +2427,20 @@ that may require changes to your code: In the standard library: -* Operations with :class:`datetime` instances that resulted in a year +* Operations with :class:`~datetime.datetime` instances that resulted in a year falling outside the supported range didn't always raise :exc:`OverflowError`. Such errors are now checked more carefully and will now raise the exception. (Reported by Mark Leander, patch by Anand B. Pillai and Alexander Belopolsky; :issue:`7150`.) -* When using :class:`Decimal` instances with a string's +* When using :class:`~decimal.Decimal` instances with a string's :meth:`format` method, the default alignment was previously left-alignment. This has been changed to right-alignment, which might change the output of your programs. (Changed by Mark Dickinson; :issue:`6857`.) Comparisons involving a signaling NaN value (or ``sNAN``) now signal - :const:`InvalidOperation` instead of silently returning a true or + :const:`~decimal.InvalidOperation` instead of silently returning a true or false value depending on the comparison operator. Quiet NaN values (or ``NaN``) are now hashable. (Fixed by Mark Dickinson; :issue:`7279`.) @@ -2411,7 +2451,7 @@ In the standard library: or comment (which looks like `<!-- comment -->`). (Patch by Neil Muller; :issue:`2746`.) -* The :meth:`readline` method of :class:`StringIO` objects now does +* The :meth:`~StringIO.StringIO.readline` method of :class:`~StringIO.StringIO` objects now does nothing when a negative length is requested, as other file-like objects do. (:issue:`7348`). @@ -2470,6 +2510,73 @@ For applications that embed Python: .. ====================================================================== +.. _py27-maintenance-enhancements: + +New Features Added to Python 2.7 Maintenance Releases +===================================================== + +New features may be added to Python 2.7 maintenance releases when the +situation genuinely calls for it. Any such additions must go through +the Python Enhancement Proposal process, and make a compelling case for why +they can't be adequately addressed by either adding the new feature solely to +Python 3, or else by publishing it on the Python Package Index. + +In addition to the specific proposals listed below, there is a general +exemption allowing new ``-3`` warnings to be added in any Python 2.7 +maintenance release. + + +PEP 434: IDLE Enhancement Exception for All Branches +---------------------------------------------------- + +:pep:`434` describes a general exemption for changes made to the IDLE +development environment shipped along with Python. This exemption makes it +possible for the IDLE developers to provide a more consistent user +experience across all supported versions of Python 2 and 3. + +For details of any IDLE changes, refer to the NEWS file for the specific +release. + + +PEP 466: Network Security Enhancements for Python 2.7 +----------------------------------------------------- + +:pep:`466` describes a number of network security enhancement proposals +that have been approved for inclusion in Python 2.7 maintenance releases, +with the first of those changes appearing in the Python 2.7.7 release. + +:pep:`466` related features added in Python 2.7.7: + +* :func:`hmac.compare_digest` was backported from Python 3 to make a timing + attack resistant comparison operation available to Python 2 applications. + (Contributed by Alex Gaynor; :issue:`21306`.) + +* OpenSSL 1.0.1g was upgraded in the official Windows installers published on + python.org. (Contributed by Zachary Ware; :issue:`21462`.) + +:pep:`466` related features added in Python 2.7.8: + +* :func:`hashlib.pbkdf2_hmac` was backported from Python 3 to make a hashing + algorithm suitable for secure password storage broadly available to Python + 2 applications. (Contributed by Alex Gaynor; :issue:`21304`.) + +* OpenSSL 1.0.1h was upgraded for the official Windows installers published on + python.org. (contributed by Zachary Ware in :issue:`21671` for CVE-2014-0224) + +:pep:`466` related features added in Python 2.7.9: + +* Most of Python 3.4's :mod:`ssl` module was backported. This means :mod:`ssl` + now supports Server Name Indication, TLS1.x settings, access to the platform + certificate store, the :class:`~ssl.SSLContext` class, and other + features. (Contributed by Alex Gaynor and David Reid; :issue:`21308`.) + +* :func:`os.urandom` was changed to cache a file descriptor to ``/dev/urandom`` + instead of reopening ``/dev/urandom`` on every call. (Contributed by Alex + Gaynor; :issue:`21305`.) + + +.. ====================================================================== + .. _acks27: Acknowledgements diff --git a/Doc/whatsnew/3.0.rst b/Doc/whatsnew/3.0.rst index 71b87b827e90..99411305a59f 100644 --- a/Doc/whatsnew/3.0.rst +++ b/Doc/whatsnew/3.0.rst @@ -164,7 +164,7 @@ Some well-known APIs no longer return lists: If the input sequences are not of equal length, :func:`map` will stop at the termination of the shortest of the sequences. For full - compatibility with `map` from Python 2.x, also wrap the sequences in + compatibility with :func:`map` from Python 2.x, also wrap the sequences in :func:`itertools.zip_longest`, e.g. ``map(func, *sequences)`` becomes ``list(map(func, itertools.zip_longest(*sequences)))``. diff --git a/Doc/whatsnew/3.1.rst b/Doc/whatsnew/3.1.rst index ab327f5fb1c8..f272da4de961 100644 --- a/Doc/whatsnew/3.1.rst +++ b/Doc/whatsnew/3.1.rst @@ -172,7 +172,7 @@ Some smaller changes made to the core Python language are: needed and is now deprecated. (Contributed by Georg Brandl and Mattias Brändström; - `appspot issue 53094 <http://codereview.appspot.com/53094>`_.) + `appspot issue 53094 <https://codereview.appspot.com/53094>`_.) * ``round(x, n)`` now returns an integer if *x* is an integer. Previously it returned a float:: @@ -238,7 +238,7 @@ New, Improved, and Deprecated Modules (Contributed by Guilherme Polo; :issue:`2983`.) * The :class:`gzip.GzipFile` and :class:`bz2.BZ2File` classes now support - the context manager protocol:: + the context management protocol:: >>> # Automatically close file after writing >>> with gzip.GzipFile(filename, "wb") as f: diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst index 5059f4830509..5171f3c1a528 100644 --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -50,7 +50,7 @@ This article explains the new features in Python 3.2 as compared to 3.1. It focuses on a few highlights and gives a few examples. For full details, see the -`Misc/NEWS <http://hg.python.org/cpython/file/3.2/Misc/NEWS>`_ file. +`Misc/NEWS <https://hg.python.org/cpython/file/3.2/Misc/NEWS>`_ file. .. seealso:: @@ -522,7 +522,7 @@ Some smaller changes made to the core Python language are: (Proposed and implemented by Mark Dickinson; :issue:`9337`.) * :class:`memoryview` objects now have a :meth:`~memoryview.release()` method - and they also now support the context manager protocol. This allows timely + and they also now support the context management protocol. This allows timely release of any resources that were acquired when requesting a buffer from the original object. @@ -816,7 +816,7 @@ functools >>> sorted(iterable, key=cmp_to_key(locale.strcoll)) For sorting examples and a brief sorting tutorial, see the `Sorting HowTo - <http://wiki.python.org/moin/HowTo/Sorting/>`_ tutorial. + <https://wiki.python.org/moin/HowTo/Sorting/>`_ tutorial. (Contributed by Raymond Hettinger.) @@ -1020,7 +1020,7 @@ datetime and time :issue:`5094`, :issue:`6641`, :issue:`2706`, :issue:`1777412`, :issue:`8013`, and :issue:`10827`.) -.. XXX http://bugs.python.org/issue?%40search_text=datetime&%40sort=-activity +.. XXX https://bugs.python.org/issue?%40search_text=datetime&%40sort=-activity math ---- @@ -1315,7 +1315,7 @@ contexts that correspond to the decimal interchange formats specified in IEEE ftp --- -The :class:`ftplib.FTP` class now supports the context manager protocol to +The :class:`ftplib.FTP` class now supports the context management protocol to unconditionally consume :exc:`socket.error` exceptions and to close the FTP connection when done:: @@ -1595,7 +1595,7 @@ The :mod:`socket` module has two new improvements. descriptor. The latter can then be reused for other purposes. (Added by Antoine Pitrou; :issue:`8524`.) -* :func:`socket.create_connection` now supports the context manager protocol +* :func:`socket.create_connection` now supports the context management protocol to unconditionally consume :exc:`socket.error` exceptions and to close the socket when done. (Contributed by Giampaolo Rodolà; :issue:`9794`.) @@ -2283,7 +2283,7 @@ Multi-threading Additional details about the implementation can be read from a `python-dev mailing-list message - <http://mail.python.org/pipermail/python-dev/2009-October/093321.html>`_ + <https://mail.python.org/pipermail/python-dev/2009-October/093321.html>`_ (however, "priority requests" as exposed in this message have not been kept for inclusion). @@ -2469,7 +2469,7 @@ Code Repository In addition to the existing Subversion code repository at http://svn.python.org there is now a `Mercurial <http://mercurial.selenic.com/>`_ repository at -http://hg.python.org/ . +https://hg.python.org/\ . After the 3.2 release, there are plans to switch to Mercurial as the primary repository. This distributed version control system should make it easier for @@ -2478,7 +2478,7 @@ members of the community to create and share external changesets. See To learn to use the new version control system, see the `tutorial by Joel Spolsky <http://hginit.com>`_ or the `Guide to Mercurial Workflows -<http://mercurial.selenic.com/guide/>`_. +<http://mercurial.selenic.com/guide>`_. Build and C API Changes @@ -2560,7 +2560,7 @@ Also, there were a number of updates to the Mac OS X build, see build, there is a known problem with the default Tcl/Tk on Mac OS X 10.6. Accordingly, we recommend installing an updated alternative such as `ActiveState Tcl/Tk 8.5.9 <http://www.activestate.com/activetcl/downloads>`_\. -See http://www.python.org/download/mac/tcltk/ for additional details. +See https://www.python.org/download/mac/tcltk/ for additional details. Porting to Python 3.2 ===================== @@ -2649,7 +2649,7 @@ require changes to your code: outfile.write(line) (Contributed by Georg Brandl and Mattias Brändström; - `appspot issue 53094 <http://codereview.appspot.com/53094>`_.) + `appspot issue 53094 <https://codereview.appspot.com/53094>`_.) * :func:`struct.pack` now only allows bytes for the ``s`` string pack code. Formerly, it would accept text arguments and implicitly encode them to bytes diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst index 6e0746adbfd2..1d4ce7236f33 100644 --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -44,7 +44,7 @@ This article explains the new features in Python 3.3, compared to 3.2. Python 3.3 was released on September 29, 2012. For full details, -see the `changelog <http://docs.python.org/3.3/whatsnew/changelog.html>`_. +see the `changelog <https://docs.python.org/3.3/whatsnew/changelog.html>`_. .. seealso:: @@ -171,7 +171,7 @@ Features * Multi-dimensional comparisons are supported for any array type. * One-dimensional memoryviews of hashable (read-only) types with formats B, - b or c are now hashable. (Contributed by Antoine Pitrou in :issue:`13411`) + b or c are now hashable. (Contributed by Antoine Pitrou in :issue:`13411`.) * Arbitrary slicing of any 1-D arrays type is supported. For example, it is now possible to reverse a memoryview in O(1) by using a negative step. @@ -194,9 +194,9 @@ API changes are still permitted, but will always compare as unequal, regardless of view contents. -* For further changes see `Build and C API Changes`_ and `Porting C code`_ . +* For further changes see `Build and C API Changes`_ and `Porting C code`_. -(Contributed by Stefan Krah in :issue:`10181`) +(Contributed by Stefan Krah in :issue:`10181`.) .. seealso:: @@ -228,7 +228,7 @@ Functionality Changes introduced by :pep:`393` are the following: -* Python now always supports the full range of Unicode codepoints, including +* Python now always supports the full range of Unicode code points, including non-BMP ones (i.e. from ``U+0000`` to ``U+10FFFF``). The distinction between narrow and wide builds no longer exists and Python now behaves like a wide build, even under Windows. @@ -246,7 +246,7 @@ Changes introduced by :pep:`393` are the following: so ``'\U0010FFFF'[0]`` now returns ``'\U0010FFFF'`` and not ``'\uDBFF'``; * all other functions in the standard library now correctly handle - non-BMP codepoints. + non-BMP code points. * The value of :data:`sys.maxunicode` is now always ``1114111`` (``0x10FFFF`` in hexadecimal). The :c:func:`PyUnicode_GetMax` function still returns @@ -258,13 +258,13 @@ Changes introduced by :pep:`393` are the following: Performance and resource usage ------------------------------ -The storage of Unicode strings now depends on the highest codepoint in the string: +The storage of Unicode strings now depends on the highest code point in the string: -* pure ASCII and Latin1 strings (``U+0000-U+00FF``) use 1 byte per codepoint; +* pure ASCII and Latin1 strings (``U+0000-U+00FF``) use 1 byte per code point; -* BMP strings (``U+0000-U+FFFF``) use 2 bytes per codepoint; +* BMP strings (``U+0000-U+FFFF``) use 2 bytes per code point; -* non-BMP strings (``U+10000-U+10FFFF``) use 4 bytes per codepoint. +* non-BMP strings (``U+10000-U+10FFFF``) use 4 bytes per code point. The net effect is that for most applications, memory usage of string storage should decrease significantly - especially compared to former @@ -307,8 +307,8 @@ Python 2 is also installed, or ``-2.6`` to specifclly request an earlier Python version when a more recent version is installed). In addition to the launcher, the Windows installer now includes an -option to add the newly installed Python to the system PATH (contributed -by Brian Curtin in :issue:`3561`). +option to add the newly installed Python to the system PATH. (Contributed +by Brian Curtin in :issue:`3561`.) .. seealso:: @@ -781,7 +781,7 @@ Some smaller changes made to the core Python language are: Both :func:`unicodedata.lookup()` and ``'\N{...}'`` now resolve name aliases, and :func:`unicodedata.lookup()` resolves named sequences too. - (Contributed by Ezio Melotti in :issue:`12753`) + (Contributed by Ezio Melotti in :issue:`12753`.) * Unicode database updated to UCD version 6.1.0 @@ -793,7 +793,7 @@ Some smaller changes made to the core Python language are: methods of :class:`bytes` and :class:`bytearray` objects now accept an integer between 0 and 255 as their first argument. - (Contributed by Petri Lehtinen in :issue:`12170`) + (Contributed by Petri Lehtinen in :issue:`12170`.) * The ``rjust()``, ``ljust()``, and ``center()`` methods of :class:`bytes` and :class:`bytearray` now accept a :class:`bytearray` for the ``fill`` @@ -854,7 +854,7 @@ Builtin functions and types * The sequence documentation has been substantially rewritten to better explain the binary/text sequence distinction and to provide specific documentation sections for the individual builtin sequence types - (:issue:`4966`) + (:issue:`4966`). New Modules @@ -891,7 +891,7 @@ The new :mod:`ipaddress` module provides tools for creating and manipulating objects representing IPv4 and IPv6 addresses, networks and interfaces (i.e. an IP address associated with a specific IP subnet). -(Contributed by Google and Peter Moody in :pep:`3144`) +(Contributed by Google and Peter Moody in :pep:`3144`.) lzma ---- @@ -900,7 +900,7 @@ The newly-added :mod:`lzma` module provides data compression and decompression using the LZMA algorithm, including support for the ``.xz`` and ``.lzma`` file formats. -(Contributed by Nadeem Vawda and Per Øyvind Karlsen in :issue:`6715`) +(Contributed by Nadeem Vawda and Per Øyvind Karlsen in :issue:`6715`.) Improved Modules @@ -921,7 +921,7 @@ property. The built-in descriptors have been updated accordingly. * :class:`abc.abstractstaticmethod` has been deprecated, use :class:`staticmethod` with :func:`abc.abstractmethod` instead. -(Contributed by Darren Dale in :issue:`11610`) +(Contributed by Darren Dale in :issue:`11610`.) :meth:`abc.ABCMeta.register` now returns the registered subclass, which means it can now be used as a class decorator (:issue:`10868`). @@ -933,7 +933,7 @@ array The :mod:`array` module supports the :c:type:`long long` type using ``q`` and ``Q`` type codes. -(Contributed by Oren Tirosh and Hirokazu Yamamoto in :issue:`1172711`) +(Contributed by Oren Tirosh and Hirokazu Yamamoto in :issue:`1172711`.) base64 @@ -964,14 +964,14 @@ new features have been added: * :class:`bz2.BZ2File` can now read from and write to arbitrary file-like objects, by means of its constructor's *fileobj* argument. - (Contributed by Nadeem Vawda in :issue:`5863`) + (Contributed by Nadeem Vawda in :issue:`5863`.) * :class:`bz2.BZ2File` and :func:`bz2.decompress` can now decompress multi-stream inputs (such as those produced by the :program:`pbzip2` tool). :class:`bz2.BZ2File` can now also be used to create this type of file, using the ``'a'`` (append) mode. - (Contributed by Nir Aides in :issue:`1625`) + (Contributed by Nir Aides in :issue:`1625`.) * :class:`bz2.BZ2File` now implements all of the :class:`io.BufferedIOBase` API, except for the :meth:`detach` and :meth:`truncate` methods. @@ -1018,7 +1018,7 @@ collections Addition of a new :class:`~collections.ChainMap` class to allow treating a number of mappings as a single unit. (Written by Raymond Hettinger for -:issue:`11089`, made public in :issue:`11297`) +:issue:`11089`, made public in :issue:`11297`.) The abstract base classes have been moved in a new :mod:`collections.abc` module, to better differentiate between the abstract and the concrete @@ -1069,7 +1069,7 @@ curses push a wide character so the next :meth:`~curses.window.get_wch` will return it -(Contributed by Iñigo Serna in :issue:`6755`) +(Contributed by Iñigo Serna in :issue:`6755`.) datetime -------- @@ -1376,11 +1376,11 @@ ftplib :func:`~ftplib.FTP_TLS.ccc` function to revert control channel back to plaintext. This can be useful to take advantage of firewalls that know how to handle NAT with non-secure FTP without opening fixed ports. (Contributed - by Giampaolo Rodolà in :issue:`12139`) + by Giampaolo Rodolà in :issue:`12139`.) * Added :meth:`ftplib.FTP.mlsd` method which provides a parsable directory listing format and deprecates :meth:`ftplib.FTP.nlst` and - :meth:`ftplib.FTP.dir`. (Contributed by Giampaolo Rodolà in :issue:`11072`) + :meth:`ftplib.FTP.dir`. (Contributed by Giampaolo Rodolà in :issue:`11072`.) functools @@ -1404,7 +1404,7 @@ hmac A new :func:`~hmac.compare_digest` function has been added to prevent side channel attacks on digests through timing analysis. (Contributed by Nick -Coghlan and Christian Heimes in :issue:`15061`) +Coghlan and Christian Heimes in :issue:`15061`.) http @@ -1436,13 +1436,13 @@ are also available on the latest bug fix releases of Python 2.7/3.2. (Contributed by Ezio Melotti in :issue:`15114`, and :issue:`14538`, :issue:`13993`, :issue:`13960`, :issue:`13358`, :issue:`1745761`, :issue:`755670`, :issue:`13357`, :issue:`12629`, :issue:`1200313`, -:issue:`670664`, :issue:`13273`, :issue:`12888`, :issue:`7311`) +:issue:`670664`, :issue:`13273`, :issue:`12888`, :issue:`7311`.) A new :data:`~html.entities.html5` dictionary that maps HTML5 named character references to the equivalent Unicode character(s) (e.g. ``html5['gt;'] == '>'``) has been added to the :mod:`html.entities` module. The dictionary is now also used by :class:`~html.parser.HTMLParser`. (Contributed by Ezio -Melotti in :issue:`11113` and :issue:`15156`) +Melotti in :issue:`11113` and :issue:`15156`.) imaplib @@ -1451,7 +1451,7 @@ imaplib The :class:`~imaplib.IMAP4_SSL` constructor now accepts an SSLContext parameter to control parameters of the secure channel. -(Contributed by Sijin Joseph in :issue:`8808`) +(Contributed by Sijin Joseph in :issue:`8808`.) inspect @@ -1462,14 +1462,14 @@ reports the current binding of all names referenced from the function body and where those names were resolved, making it easier to verify correct internal state when testing code that relies on stateful closures. -(Contributed by Meador Inge and Nick Coghlan in :issue:`13062`) +(Contributed by Meador Inge and Nick Coghlan in :issue:`13062`.) A new :func:`~inspect.getgeneratorlocals` function has been added. This function reports the current binding of local variables in the generator's stack frame, making it easier to verify correct internal state when testing generators. -(Contributed by Meador Inge in :issue:`15153`) +(Contributed by Meador Inge in :issue:`15153`.) io -- @@ -1478,7 +1478,7 @@ The :func:`~io.open` function has a new ``'x'`` mode that can be used to exclusively create a new file, and raise a :exc:`FileExistsError` if the file already exists. It is based on the C11 'x' mode to fopen(). -(Contributed by David Townshend in :issue:`12760`) +(Contributed by David Townshend in :issue:`12760`.) The constructor of the :class:`~io.TextIOWrapper` class has a new *write_through* optional argument. If *write_through* is ``True``, calls to @@ -1513,7 +1513,7 @@ math The :mod:`math` module has a new function, :func:`~math.log2`, which returns the base-2 logarithm of *x*. -(Written by Mark Dickinson in :issue:`11888`). +(Written by Mark Dickinson in :issue:`11888`.) mmap @@ -1540,7 +1540,7 @@ multiprocessing connections. to override the default behavior of inheriting the ``daemon`` flag from the parent process (:issue:`6064`). -New attribute attribute :data:`multiprocessing.Process.sentinel` allows a +New attribute :data:`multiprocessing.Process.sentinel` allows a program to wait on multiple :class:`~multiprocessing.Process` objects at one time using the appropriate OS primitives (for example, :mod:`select` on posix systems). @@ -1556,7 +1556,7 @@ Schlawack in :issue:`12708`.) nntplib ------- -The :class:`nntplib.NNTP` class now supports the context manager protocol to +The :class:`nntplib.NNTP` class now supports the context management protocol to unconditionally consume :exc:`socket.error` exceptions and to close the NNTP connection when done:: @@ -1567,7 +1567,7 @@ connection when done:: ('211 1755 1 1755 gmane.comp.python.committers', 1755, 1, 1755, 'gmane.comp.python.committers') >>> -(Contributed by Giampaolo Rodolà in :issue:`9795`) +(Contributed by Giampaolo Rodolà in :issue:`9795`.) os @@ -1579,7 +1579,7 @@ os avoid race conditions in multi-threaded programs. * The :mod:`os` module has a new :func:`~os.sendfile` function which provides - an efficent "zero-copy" way for copying data from one file (or socket) + an efficient "zero-copy" way for copying data from one file (or socket) descriptor to another. The phrase "zero-copy" refers to the fact that all of the copying of data between the two descriptors is done entirely by the kernel, with no copying of data into userspace buffers. :func:`~os.sendfile` @@ -1744,30 +1744,30 @@ sched set to False makes the method execute the scheduled events due to expire soonest (if any) and then return immediately. This is useful in case you want to use the :class:`~sched.scheduler` in - non-blocking applications. (Contributed by Giampaolo Rodolà in :issue:`13449`) + non-blocking applications. (Contributed by Giampaolo Rodolà in :issue:`13449`.) * :class:`~sched.scheduler` class can now be safely used in multi-threaded environments. (Contributed by Josiah Carlson and Giampaolo Rodolà in - :issue:`8684`) + :issue:`8684`.) * *timefunc* and *delayfunct* parameters of :class:`~sched.scheduler` class constructor are now optional and defaults to :func:`time.time` and :func:`time.sleep` respectively. (Contributed by Chris Clark in - :issue:`13245`) + :issue:`13245`.) * :meth:`~sched.scheduler.enter` and :meth:`~sched.scheduler.enterabs` *argument* parameter is now optional. (Contributed by Chris Clark in - :issue:`13245`) + :issue:`13245`.) * :meth:`~sched.scheduler.enter` and :meth:`~sched.scheduler.enterabs` now accept a *kwargs* parameter. (Contributed by Chris Clark in - :issue:`13245`) + :issue:`13245`.) select ------ -Solaris and derivatives platforms have a new class :class:`select.devpoll` +Solaris and derivative platforms have a new class :class:`select.devpoll` for high performance asynchronous sockets via :file:`/dev/poll`. (Contributed by Jesús Cea Avión in :issue:`6397`.) @@ -1787,10 +1787,10 @@ shutil * New functions: * :func:`~shutil.disk_usage`: provides total, used and free disk space - statistics. (Contributed by Giampaolo Rodolà in :issue:`12442`) + statistics. (Contributed by Giampaolo Rodolà in :issue:`12442`.) * :func:`~shutil.chown`: allows one to change user and/or group of the given path also specifying the user/group names and not only their numeric - ids. (Contributed by Sandro Tosi in :issue:`12191`) + ids. (Contributed by Sandro Tosi in :issue:`12191`.) * :func:`shutil.get_terminal_size`: returns the size of the terminal window to which the interpreter is attached. (Contributed by Zbigniew Jędrzejewski-Szmek in :issue:`13609`.) @@ -1813,7 +1813,7 @@ shutil * :func:`~shutil.rmtree` is now resistant to symlink attacks on platforms which support the new ``dir_fd`` parameter in :func:`os.open` and - :func:`os.unlink`. (Contributed by Martin von Löwis and Hynek Schlawack + :func:`os.unlink`. (Contributed by Martin von Löwis and Hynek Schlawack in :issue:`4489`.) @@ -1823,12 +1823,12 @@ signal * The :mod:`signal` module has new functions: * :func:`~signal.pthread_sigmask`: fetch and/or change the signal mask of the - calling thread (Contributed by Jean-Paul Calderone in :issue:`8407`) ; - * :func:`~signal.pthread_kill`: send a signal to a thread ; - * :func:`~signal.sigpending`: examine pending functions ; - * :func:`~signal.sigwait`: wait a signal. + calling thread (Contributed by Jean-Paul Calderone in :issue:`8407`); + * :func:`~signal.pthread_kill`: send a signal to a thread; + * :func:`~signal.sigpending`: examine pending functions; + * :func:`~signal.sigwait`: wait a signal; * :func:`~signal.sigwaitinfo`: wait for a signal, returning detailed - information about it. + information about it; * :func:`~signal.sigtimedwait`: like :func:`~signal.sigwaitinfo` but with a timeout. @@ -1861,13 +1861,13 @@ to specify the ``(host, port)`` to use as the source address in the bind call when creating the outgoing socket. (Contributed by Paulo Scardine in :issue:`11281`.) -:class:`~smtplib.SMTP` now supports the context manager protocol, allowing an +:class:`~smtplib.SMTP` now supports the context management protocol, allowing an ``SMTP`` instance to be used in a ``with`` statement. (Contributed by Giampaolo Rodolà in :issue:`11289`.) The :class:`~smtplib.SMTP_SSL` constructor and the :meth:`~smtplib.SMTP.starttls` method now accept an SSLContext parameter to control parameters of the secure -channel. (Contributed by Kasun Herath in :issue:`8809`) +channel. (Contributed by Kasun Herath in :issue:`8809`.) socket @@ -1887,11 +1887,11 @@ socket (http://en.wikipedia.org/wiki/Socketcan), on Linux (http://lwn.net/Articles/253425). - (Contributed by Matthias Fuchs, updated by Tiago Gonçalves in :issue:`10141`) + (Contributed by Matthias Fuchs, updated by Tiago Gonçalves in :issue:`10141`.) * The :class:`~socket.socket` class now supports the PF_RDS protocol family (http://en.wikipedia.org/wiki/Reliable_Datagram_Sockets and - http://oss.oracle.com/projects/rds/). + https://oss.oracle.com/projects/rds/). * The :class:`~socket.socket` class now supports the ``PF_SYSTEM`` protocol family on OS X. (Contributed by Michael Goderbauer in :issue:`13777`.) @@ -1908,7 +1908,7 @@ socketserver :meth:`~socketserver.BaseServer.service_actions` that is called by the :meth:`~socketserver.BaseServer.serve_forever` method in the service loop. :class:`~socketserver.ForkingMixIn` now uses this to clean up zombie -child proceses. (Contributed by Justin Warkentin in :issue:`11109`.) +child processes. (Contributed by Justin Warkentin in :issue:`11109`.) sqlite3 @@ -1929,37 +1929,37 @@ ssl pseudo-random bytes. * :func:`~ssl.RAND_pseudo_bytes`: generate pseudo-random bytes. - (Contributed by Victor Stinner in :issue:`12049`) + (Contributed by Victor Stinner in :issue:`12049`.) * The :mod:`ssl` module now exposes a finer-grained exception hierarchy in order to make it easier to inspect the various kinds of errors. - (Contributed by Antoine Pitrou in :issue:`11183`) + (Contributed by Antoine Pitrou in :issue:`11183`.) * :meth:`~ssl.SSLContext.load_cert_chain` now accepts a *password* argument to be used if the private key is encrypted. - (Contributed by Adam Simpkins in :issue:`12803`) + (Contributed by Adam Simpkins in :issue:`12803`.) * Diffie-Hellman key exchange, both regular and Elliptic Curve-based, is now supported through the :meth:`~ssl.SSLContext.load_dh_params` and :meth:`~ssl.SSLContext.set_ecdh_curve` methods. - (Contributed by Antoine Pitrou in :issue:`13626` and :issue:`13627`) + (Contributed by Antoine Pitrou in :issue:`13626` and :issue:`13627`.) * SSL sockets have a new :meth:`~ssl.SSLSocket.get_channel_binding` method allowing the implementation of certain authentication mechanisms such as - SCRAM-SHA-1-PLUS. (Contributed by Jacek Konieczny in :issue:`12551`) + SCRAM-SHA-1-PLUS. (Contributed by Jacek Konieczny in :issue:`12551`.) * You can query the SSL compression algorithm used by an SSL socket, thanks to its new :meth:`~ssl.SSLSocket.compression` method. The new attribute :attr:`~ssl.OP_NO_COMPRESSION` can be used to disable compression. - (Contributed by Antoine Pitrou in :issue:`13634`) + (Contributed by Antoine Pitrou in :issue:`13634`.) * Support has been added for the Next Procotol Negotiation extension using the :meth:`ssl.SSLContext.set_npn_protocols` method. - (Contributed by Colin Marc in :issue:`14204`) + (Contributed by Colin Marc in :issue:`14204`.) * SSL errors can now be introspected more easily thanks to :attr:`~ssl.SSLError.library` and :attr:`~ssl.SSLError.reason` attributes. - (Contributed by Antoine Pitrou in :issue:`14837`) + (Contributed by Antoine Pitrou in :issue:`14837`.) * The :func:`~ssl.get_server_certificate` function now supports IPv6. (Contributed by Charles-François Natali in :issue:`11811`.) @@ -1976,7 +1976,7 @@ The undocumented tarfile.filemode function has been moved to :func:`stat.filemode`. It can be used to convert a file's mode to a string of the form '-rwxrwxrwx'. -(Contributed by Giampaolo Rodolà in :issue:`14807`) +(Contributed by Giampaolo Rodolà in :issue:`14807`.) struct @@ -2035,8 +2035,8 @@ threading :class:`threading.Condition`, :class:`threading.Semaphore`, :class:`threading.BoundedSemaphore`, :class:`threading.Event`, and :class:`threading.Timer`, all of which used to be factory functions returning a -class instance, are now classes and may be subclassed. (Contributed by Éric -Araujo in :issue:`10968`). +class instance, are now classes and may be subclassed. (Contributed by Éric +Araujo in :issue:`10968`.) The :class:`threading.Thread` constructor now accepts a ``daemon`` keyword argument to override the default behavior of inheriting the ``deamon`` flag @@ -2066,7 +2066,7 @@ Other new functions: * :func:`~time.clock_getres`, :func:`~time.clock_gettime` and :func:`~time.clock_settime` functions with ``CLOCK_xxx`` constants. - (Contributed by Victor Stinner in :issue:`10278`) + (Contributed by Victor Stinner in :issue:`10278`.) To improve cross platform consistency, :func:`~time.sleep` now raises a :exc:`ValueError` when passed a negative sleep value. Previously this was an @@ -2080,7 +2080,7 @@ Add a new :class:`types.MappingProxyType` class: Read-only proxy of a mapping. (:issue:`14386`) -The new functions `types.new_class` and `types.prepare_class` provide support +The new functions :func:`types.new_class` and :func:`types.prepare_class` provide support for PEP 3115 compliant dynamic type creation. (:issue:`14588`) @@ -2090,7 +2090,7 @@ unittest :meth:`.assertRaises`, :meth:`.assertRaisesRegex`, :meth:`.assertWarns`, and :meth:`.assertWarnsRegex` now accept a keyword argument *msg* when used as context managers. (Contributed by Ezio Melotti and Winston Ewert in -:issue:`10775`) +:issue:`10775`.) :meth:`unittest.TestCase.run` now returns the :class:`~unittest.TestResult` object. @@ -2103,7 +2103,7 @@ The :class:`~urllib.request.Request` class, now accepts a *method* argument used by :meth:`~urllib.request.Request.get_method` to determine what HTTP method should be used. For example, this will send a ``'HEAD'`` request:: - >>> urlopen(Request('http://www.python.org/', method='HEAD')) + >>> urlopen(Request('https://www.python.org/', method='HEAD')) (:issue:`1673007`) @@ -2117,7 +2117,7 @@ The :mod:`webbrowser` module supports more "browsers": Google Chrome (named and the generic launchers :program:`xdg-open`, from the FreeDesktop.org project, and :program:`gvfs-open`, which is the default URI handler for GNOME 3. (The former contributed by Arnaud Calmettes in :issue:`13620`, the latter -by Matthias Klose in :issue:`14493`) +by Matthias Klose in :issue:`14493`.) xml.etree.ElementTree @@ -2160,7 +2160,7 @@ Major performance enhancements have been added: * UTF-8 is now 2x to 4x faster. UTF-16 encoding is now up to 10x faster. - (contributed by Serhiy Storchaka, :issue:`14624`, :issue:`14738` and + (Contributed by Serhiy Storchaka, :issue:`14624`, :issue:`14738` and :issue:`15026`.) @@ -2360,7 +2360,7 @@ Porting Python code bytecode file, make sure to call :func:`importlib.invalidate_caches` to clear out the cache for the finders to notice the new file. -* :exc:`ImportError` now uses the full name of the module that was attemped to +* :exc:`ImportError` now uses the full name of the module that was attempted to be imported. Doctests that check ImportErrors' message will need to be updated to use the full name of the module instead of just the tail of the name. diff --git a/Doc/whatsnew/3.4.rst b/Doc/whatsnew/3.4.rst index 301ab8f1653b..7faea321919a 100644 --- a/Doc/whatsnew/3.4.rst +++ b/Doc/whatsnew/3.4.rst @@ -2,8 +2,7 @@ What's New In Python 3.4 **************************** -.. :Author: Someone <email> - (uncomment if there is a principal author) +:Author: R. David Murray <rdmurray@bitdance.com> (Editor) .. Rules for maintenance: @@ -18,7 +17,7 @@ time of the original release will remain largely unknown to the community for years, even if they're added later. We also know from experience that other priorities can arise, and the maintainer will run out of time to do - updates - in such cases, end users will be much better served by partial + updates -- in such cases, end users will be much better served by partial notifications that at least give a hint about new features to investigate. @@ -53,7 +52,7 @@ * It's helpful to add the bug/patch number as a comment: The :ref:`~socket.transmogrify()` function was added to the - :mod:`socket` module. (Contributed by P.Y. Developer in :issue:`12345`.) + :mod:`socket` module. (Contributed by P.Y. Developer in :issue:`12345`.) This saves the maintainer the effort of going through the Mercurial log when researching a change. @@ -62,23 +61,17 @@ while :ref:`~mod.attr` will display as ``attr``. This article explains the new features in Python 3.4, compared to 3.3. - -.. Python 3.4 was released on TBD. - -For full details, see the -`changelog <http://docs.python.org/3.4/whatsnew/changelog.html>`_. - -.. note:: Prerelease users should be aware that this document is currently in - draft form. It will be updated substantially as Python 3.4 moves towards - release, so it's worth checking back even after reading earlier versions. +Python 3.4 was released on March 16, 2014. For full details, see the +`changelog <https://docs.python.org/3.4/whatsnew/changelog.html>`_. .. seealso:: - :pep:`429` - Python 3.4 Release Schedule + :pep:`429` -- Python 3.4 Release Schedule -Summary -- Release highlights + +Summary -- Release Highlights ============================= .. This section singles out the most important changes in Python 3.4. @@ -86,94 +79,196 @@ Summary -- Release highlights New syntax features: -* No new syntax features are planned for Python 3.4. +* No new syntax features were added in Python 3.4. -New library modules: +Other new features: -* :mod:`asyncio`: New provisonal API for asynchronous IO (:pep:`3156`). -* :mod:`enum`: Support for enumeration types (:pep:`435`). -* :mod:`ensurepip`: Bootstrapping the pip installer (:pep:`453`). -* :mod:`pathlib`: Object-oriented filesystem paths (:pep:`428`). -* :mod:`selectors`: High-level and efficient I/O multiplexing, built upon the - :mod:`select` module primitives. -* :mod:`statistics`: A basic numerically stable statistics library (:pep:`450`). -* :mod:`tracemalloc`: Trace Python memory allocations (:pep:`454`). +* :ref:`pip should always be available <whatsnew-pep-453>` (:pep:`453`). +* :ref:`Newly created file descriptors are non-inheritable <whatsnew-pep-446>` + (:pep:`446`). +* command line option for :ref:`isolated mode <whatsnew-isolated-mode>` + (:issue:`16499`). +* :ref:`improvements in the handling of codecs <codec-handling-improvements>` + that are not text encodings (multiple issues). +* :ref:`A ModuleSpec Type <whatsnew-pep-451>` for the Import System + (:pep:`451`). (Affects importer authors.) +* The :mod:`marshal` format has been made :ref:`more compact and efficient + <whatsnew-marshal-3>` (:issue:`16475`). -New expected features for Python implementations: +New library modules: -* :ref:`PEP 446: Make newly created file descriptors non-inheritable <pep-446>`. -* command line option for :ref:`isolated mode <using-on-misc-options>`, +* :mod:`asyncio`: :ref:`New provisional API for asynchronous IO + <whatsnew-asyncio>` (:pep:`3156`). +* :mod:`ensurepip`: :ref:`Bootstrapping the pip installer <whatsnew-ensurepip>` + (:pep:`453`). +* :mod:`enum`: :ref:`Support for enumeration types <whatsnew-enum>` + (:pep:`435`). +* :mod:`pathlib`: :ref:`Object-oriented filesystem paths <whatsnew-pathlib>` + (:pep:`428`). +* :mod:`selectors`: :ref:`High-level and efficient I/O multiplexing + <whatsnew-selectors>`, built upon the :mod:`select` module primitives (part + of :pep:`3156`). +* :mod:`statistics`: A basic :ref:`numerically stable statistics library + <whatsnew-statistics>` (:pep:`450`). +* :mod:`tracemalloc`: :ref:`Trace Python memory allocations + <whatsnew-tracemalloc>` (:pep:`454`). + +Significantly improved library modules: + +* :ref:`Single-dispatch generic functions <whatsnew-singledispatch>` in + :mod:`functools` (:pep:`443`). +* New :mod:`pickle` :ref:`protocol 4 <whatsnew-protocol-4>` (:pep:`3154`). +* :mod:`multiprocessing` now has :ref:`an option to avoid using os.fork + on Unix <whatsnew-multiprocessing-no-fork>` (:issue:`8713`). +* :mod:`email` has a new submodule, :mod:`~email.contentmanager`, and + a new :mod:`~email.message.Message` subclass + (:class:`~email.contentmanager.EmailMessage`) that :ref:`simplify MIME + handling <whatsnew_email_contentmanager>` (:issue:`18891`). +* The :mod:`inspect` and :mod:`pydoc` modules are now capable of + correct introspection of a much wider variety of callable objects, + which improves the output of the Python :func:`help` system. +* The :mod:`ipaddress` module API has been declared stable + +Security improvements: + +* :ref:`Secure and interchangeable hash algorithm <whatsnew-pep-456>` + (:pep:`456`). +* :ref:`Make newly created file descriptors non-inheritable <whatsnew-pep-446>` + (:pep:`446`) to avoid leaking file descriptors to child processes. +* New command line option for :ref:`isolated mode <whatsnew-isolated-mode>`, (:issue:`16499`). -* :ref:`improvements <codec-handling-improvements>` in the handling of - codecs that are not text encodings +* :mod:`multiprocessing` now has :ref:`an option to avoid using os.fork + on Unix <whatsnew-multiprocessing-no-fork>`. *spawn* and *forkserver* are + more secure because they avoid sharing data with child processes. +* :mod:`multiprocessing` child processes on Windows no longer inherit + all of the parent's inheritable handles, only the necessary ones. +* A new :func:`hashlib.pbkdf2_hmac` function provides + the `PKCS#5 password-based key derivation function 2 + <http://en.wikipedia.org/wiki/PBKDF2>`_. +* :ref:`TLSv1.1 and TLSv1.2 support <whatsnew-tls-11-12>` for :mod:`ssl`. +* :ref:`Retrieving certificates from the Windows system cert store support + <whatsnew34-win-cert-store>` for :mod:`ssl`. +* :ref:`Server-side SNI (Server Name Indication) support + <whatsnew34-sni>` for :mod:`ssl`. +* The :class:`ssl.SSLContext` class has a :ref:`lot of improvements + <whatsnew34-sslcontext>`. +* All modules in the standard library that support SSL now support server + certificate verification, including hostname matching + (:func:`ssl.match_hostname`) and CRLs (Certificate Revocation lists, see + :func:`ssl.SSLContext.load_verify_locations`). -Significantly Improved Library Modules: +CPython implementation improvements: -* Single-dispatch generic functions in :mod:`functoools` (:pep:`443`) -* New :mod:`pickle` protocol 4 (:pep:`3154`) -* SHA-3 (Keccak) support for :mod:`hashlib`. -* TLSv1.1 and TLSv1.2 support for :mod:`ssl`. -* :mod:`multiprocessing` now has option to avoid using :func:`os.fork` - on Unix (:issue:`8713`). +* :ref:`Safe object finalization <whatsnew-pep-442>` (:pep:`442`). +* Leveraging :pep:`442`, in most cases :ref:`module globals are no longer set + to None during finalization <whatsnew-pep-442>` (:issue:`18214`). +* :ref:`Configurable memory allocators <whatsnew-pep-445>` (:pep:`445`). +* :ref:`Argument Clinic <whatsnew-pep-436>` (:pep:`436`). -CPython implementation improvements: +Please read on for a comprehensive list of user-facing changes, including many +other smaller improvements, CPython optimizations, deprecations, and potential +porting issues. -* :ref:`PEP 442: Safe object finalization <pep-442>` -* :ref:`PEP 445: Configurable memory allocators <pep-445>` -* :pep:`456` Secure and interchangeable hash algorithm -* Improve finalization of Python modules to avoid setting their globals - to None, in most cases (:issue:`18214`). -* A more efficient :mod:`marshal` format (:issue:`16475`). -* "Argument Clinic", an initial step towards providing improved introspection - support for builtin and standard library extension types implemented in C - (:pep:`436`) -Please read on for a comprehensive list of user-facing changes. +New Features +============ -PEP 453: Explicit bootstrapping of pip in Python installations -============================================================== +.. _whatsnew-pep-453: + +PEP 453: Explicit Bootstrapping of PIP in Python Installations +-------------------------------------------------------------- + +Bootstrapping pip By Default +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The new :mod:`ensurepip` module (defined in :pep:`453`) provides a standard -cross-platform mechanism to boostrap the pip installer into Python -installations and virtual environments. +cross-platform mechanism to bootstrap the pip installer into Python +installations and virtual environments. The version of ``pip`` included +with Python 3.4.0 is ``pip`` 1.5.4, and future 3.4.x maintenance releases +will update the bundled version to the latest version of ``pip`` that is +available at the time of creating the release candidate. + +By default, the commands ``pipX`` and ``pipX.Y`` will be installed on all +platforms (where X.Y stands for the version of the Python installation), +along with the ``pip`` Python package and its dependencies. On Windows and +in virtual environments on all platforms, the unversioned ``pip`` command +will also be installed. On other platforms, the system wide unversioned +``pip`` command typically refers to the separately installed Python 2 +version. + +The :ref:`pyvenv <scripts-pyvenv>` command line utility and the :mod:`venv` +module make use of the :mod:`ensurepip` module to make ``pip`` readily +available in virtual environments. When using the command line utility, +``pip`` is installed by default, while when using the :mod:`venv` module +:ref:`venv-api` installation of ``pip`` must be requested explicitly. + +For CPython :ref:`source builds on POSIX systems <building-python-on-unix>`, +the ``make install`` and ``make altinstall`` commands bootstrap ``pip`` by +default. This behaviour can be controlled through configure options, and +overridden through Makefile options. + +On Windows and Mac OS X, the CPython installers now default to installing +``pip`` along with CPython itself (users may opt out of installing it +during the installation process). Window users will need to opt in to the +automatic ``PATH`` modifications to have ``pip`` available from the command +line by default, otherwise it can still be accessed through the Python +launcher for Windows as ``py -m pip``. + +As `discussed in the PEP`__, platform packagers may choose not to install +these commands by default, as long as, when invoked, they provide clear and +simple directions on how to install them on that platform (usually using +the system package manager). + +__ https://www.python.org/dev/peps/pep-0453/#recommendations-for-downstream-distributors -The :mod:`venv` module and the :command:`pyvenv` utility make use of this -module to make ``pip`` readily available in virtual environments. When -using the command line interface, ``pip`` is installed by default, while -for the module API installation of ``pip`` must be requested explicitly. +.. note:: -For CPython source builds on POSIX systems, the ``make install`` and -``make altinstall`` commands bootstrap ``pip`` by default. This behaviour -can be controlled through configure options, and overridden through -Makefile options. + To avoid conflicts between parallel Python 2 and Python 3 installations, + only the versioned ``pip3`` and ``pip3.4`` commands are bootstrapped by + default when ``ensurepip`` is invoked directly - the ``--default-pip`` + option is needed to also request the unversioned ``pip`` command. + ``pyvenv`` and the Windows installer ensure that the unqualified ``pip`` + command is made available in those environments, and ``pip`` can always be + invoked via the ``-m`` switch rather than directly to avoid ambiguity on + systems with multiple Python installations. -On Windows and Mac OS X, the CPython installers now offer the option to -install ``pip`` along with CPython itself. -.. note:: +Documentation Changes +~~~~~~~~~~~~~~~~~~~~~ - The implementation of PEP 453 is still a work in progress. Refer to - :issue:`19347` for the progress on additional steps: +As part of this change, the :ref:`installing-index` and +:ref:`distributing-index` sections of the documentation have been +completely redesigned as short getting started and FAQ documents. Most +packaging documentation has now been moved out to the Python Packaging +Authority maintained `Python Packaging User Guide +<https://packaging.python.org>`__ and the documentation of the individual +projects. - * Having the binary installers install ``pip`` by default - * Recommending the use of ``pip`` in the "Installing Python Module" - documentation. +However, as this migration is currently still incomplete, the legacy +versions of those guides remaining available as :ref:`install-index` +and :ref:`distutils-index`. .. seealso:: - :pep:`453` - Explicit bootstrapping of pip in Python installations + :pep:`453` -- Explicit bootstrapping of pip in Python installations PEP written by Donald Stufft and Nick Coghlan, implemented by Donald Stufft, Nick Coghlan, Martin von Löwis and Ned Deily. -.. _pep-446: +.. _whatsnew-pep-446: -PEP 446: Make newly created file descriptors non-inheritable -============================================================ +PEP 446: Newly Created File Descriptors Are Non-Inheritable +----------------------------------------------------------- :pep:`446` makes newly created file descriptors :ref:`non-inheritable -<fd_inheritance>`. New functions and methods: +<fd_inheritance>`. In general, this is the behavior an application will +want: when launching a new process, having currently open files also +open in the new process can lead to all sorts of hard to find bugs, +and potentially to security issues. + +However, there are occasions when inheritance is desired. To support +these cases, the following new functions and methods are available: * :func:`os.get_inheritable`, :func:`os.set_inheritable` * :func:`os.get_handle_inheritable`, :func:`os.set_handle_inheritable` @@ -181,14 +276,14 @@ PEP 446: Make newly created file descriptors non-inheritable .. seealso:: - :pep:`446` - Make newly created file descriptors non-inheritable + :pep:`446` -- Make newly created file descriptors non-inheritable PEP written and implemented by Victor Stinner. .. _codec-handling-improvements: -Improvements to codec handling -============================== +Improvements to Codec Handling +------------------------------ Since it was first introduced, the :mod:`codecs` module has always been intended to operate as a type-neutral dynamic encoding and decoding @@ -204,10 +299,10 @@ module (and have been covered by the regression test suite) since Python 2.4, but were previously only discoverable through runtime introspection. Unlike the convenience methods on :class:`str`, :class:`bytes` and -:class:`bytearray`, these convenience functions support arbitrary codecs -in both Python 2 and Python 3, rather than being limited to Unicode text -encodings (in Python 3) or ``basestring`` <-> ``basestring`` conversions -(in Python 2). +:class:`bytearray`, the :mod:`codecs` convenience functions support arbitrary +codecs in both Python 2 and Python 3, rather than being limited to Unicode text +encodings (in Python 3) or ``basestring`` <-> ``basestring`` conversions (in +Python 2). In Python 3.4, the interpreter is able to identify the known non-text encodings provided in the standard library and direct users towards these @@ -223,14 +318,22 @@ general purpose convenience functions when appropriate:: File "<stdin>", line 1, in <module> LookupError: 'rot13' is not a text encoding; use codecs.encode() to handle arbitrary codecs + >>> open("foo.txt", encoding="hex") + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + LookupError: 'hex' is not a text encoding; use codecs.open() to handle arbitrary codecs + In a related change, whenever it is feasible without breaking backwards compatibility, exceptions raised during encoding and decoding operations -will be wrapped in a chained exception of the same type that mentions the +are wrapped in a chained exception of the same type that mentions the name of the codec responsible for producing the error:: >>> import codecs >>> codecs.decode(b"abcdefgh", "hex") + Traceback (most recent call last): + File "/usr/lib/python3.4/encodings/hex_codec.py", line 20, in hex_decode + return (binascii.a2b_hex(input), len(input)) binascii.Error: Non-hexadecimal digit found The above exception was the direct cause of the following exception: @@ -240,6 +343,11 @@ name of the codec responsible for producing the error:: binascii.Error: decoding with 'hex' codec failed (Error: Non-hexadecimal digit found) >>> codecs.encode("hello", "bz2") + Traceback (most recent call last): + File "/usr/lib/python3.4/encodings/bz2_codec.py", line 17, in bz2_encode + return (bz2.compress(input), len(input)) + File "/usr/lib/python3.4/bz2.py", line 498, in compress + return comp.compress(data) + comp.flush() TypeError: 'str' does not support the buffer interface The above exception was the direct cause of the following exception: @@ -263,74 +371,95 @@ as:: The binary and text transforms provided in the standard library are detailed in :ref:`binary-transforms` and :ref:`text-transforms`. -(Contributed by Nick Coghlan in :issue:`7475`, , :issue:`17827`, -:issue:`17828` and :issue:`19619`) +(Contributed by Nick Coghlan in :issue:`7475`, :issue:`17827`, +:issue:`17828` and :issue:`19619`.) + -.. _pep-451: +.. _whatsnew-pep-451: PEP 451: A ModuleSpec Type for the Import System -================================================ +------------------------------------------------ -:pep:`451` provides an encapsulation of the information about a module -that the import machinery will use to load it, (i.e. a module spec). -This helps simplify both the import implementation and several -import-related APIs. The change is also a stepping stone for several -future import-related improvements. +:pep:`451` provides an encapsulation of the information about a module that the +import machinery will use to load it (that is, a module specification). This +helps simplify both the import implementation and several import-related APIs. +The change is also a stepping stone for `several future import-related +improvements`__. -https://mail.python.org/pipermail/python-dev/2013-November/130111.html +__ https://mail.python.org/pipermail/python-dev/2013-November/130111.html The public-facing changes from the PEP are entirely backward-compatible. -Furthermore, they should be transparent to everyone but importer -authors. Key finder and loader methods have been deprecated, but they -will continue working. New importers should use the new methods -described in the PEP. Existing importers should be updated to implement -the new methods. - - -Pickle protocol 4 -================= - -The new :mod:`pickle` protocol addresses a number of issues that were present -in previous protocols, such as the serialization of nested classes, very -large strings and containers, or classes whose :meth:`__new__` method takes -keyword-only arguments. It also brings a couple efficiency improvements. - -.. seealso:: - - :pep:`3154` - Pickle protocol 4 - PEP written by Antoine Pitrou and implemented by Alexandre Vassalotti. +Furthermore, they should be transparent to everyone but importer authors. Key +finder and loader methods have been deprecated, but they will continue working. +New importers should use the new methods described in the PEP. Existing +importers should be updated to implement the new methods. See the +:ref:`deprecated-3.4` section for a list of methods that should be replaced and +their replacements. Other Language Changes -====================== +---------------------- Some smaller changes made to the core Python language are: * Unicode database updated to UCD version 6.3. -* :func:`min` and :func:`max` now accept a *default* argument that can be used - to specify the value they return if the iterable they are evaluating has no - elements. Contributed by Julian Berman in :issue:`18111`. +* :func:`min` and :func:`max` now accept a *default* keyword-only argument that + can be used to specify the value they return if the iterable they are + evaluating has no elements. (Contributed by Julian Berman in + :issue:`18111`.) * Module objects are now :mod:`weakref`'able. * Module ``__file__`` attributes (and related values) should now always contain absolute paths by default, with the sole exception of ``__main__.__file__`` when a script has been executed directly using - a relative path (Contributed by Brett Cannon in :issue:`18416`). + a relative path. (Contributed by Brett Cannon in :issue:`18416`.) -* Now all the UTF-\* codecs (except UTF-7) reject surrogates during both +* All the UTF-\* codecs (except UTF-7) now reject surrogates during both encoding and decoding unless the ``surrogatepass`` error handler is used, - with the exception of the UTF-16 decoder that accepts valid surrogate pairs, - and the UTF-16 encoder that produces them while encoding non-BMP characters. - Contributed by Victor Stinner, Kang-Hao (Kenny) Lu and Serhiy Storchaka in - :issue:`12892`. + with the exception of the UTF-16 decoder (which accepts valid surrogate pairs) + and the UTF-16 encoder (which produces them while encoding non-BMP characters). + (Contributed by Victor Stinner, Kang-Hao (Kenny) Lu and Serhiy Storchaka in + :issue:`12892`.) + +* New German EBCDIC :ref:`codec <standard-encodings>` ``cp273``. (Contributed + by Michael Bierenfeld and Andrew Kuchling in :issue:`1097797`.) + +* New Ukrainian :ref:`codec <standard-encodings>` ``cp1125``. (Contributed by + Serhiy Storchaka in :issue:`19668`.) + +* :class:`bytes`.join() and :class:`bytearray`.join() now accept arbitrary + buffer objects as arguments. (Contributed by Antoine Pitrou in + :issue:`15958`.) + +* The :class:`int` constructor now accepts any object that has an ``__index__`` + method for its *base* argument. (Contributed by Mark Dickinson in + :issue:`16772`.) + +* Frame objects now have a :func:`~frame.clear` method that clears all + references to local variables from the frame. (Contributed by Antoine Pitrou + in :issue:`17934`.) + +* :class:`memoryview` is now registered as a :class:`Sequence <collections.abc>`, + and supports the :func:`reversed` builtin. (Contributed by Nick Coghlan + and Claudiu Popa in :issue:`18690` and :issue:`19078`.) + +* Signatures reported by :func:`help` have been modified and improved in + several cases as a result of the introduction of Argument Clinic and other + changes to the :mod:`inspect` and :mod:`pydoc` modules. + +* :meth:`~object.__length_hint__` is now part of the formal language + specification (see :pep:`424`). (Contributed by Armin Ronacher in + :issue:`16148`.) New Modules =========== +.. _whatsnew-asyncio: + asyncio ------- @@ -343,9 +472,38 @@ For Python 3.4, this module is considered a :term:`provisional API`. .. seealso:: - :pep:`3156` - Asynchronous IO Support Rebooted: the "asyncio" Module + :pep:`3156` -- Asynchronous IO Support Rebooted: the "asyncio" Module PEP written and implementation led by Guido van Rossum. + +.. _whatsnew-ensurepip: + +ensurepip +--------- + +The new :mod:`ensurepip` module is the primary infrastructure for the +:pep:`453` implementation. In the normal course of events end users will not +need to interact with this module, but it can be used to manually bootstrap +``pip`` if the automated bootstrapping into an installation or virtual +environment was declined. + +:mod:`ensurepip` includes a bundled copy of ``pip``, up-to-date as of the first +release candidate of the release of CPython with which it ships (this applies +to both maintenance releases and feature releases). ``ensurepip`` does not +access the internet. If the installation has Internet access, after +``ensurepip`` is run the bundled ``pip`` can be used to upgrade ``pip`` to a +more recent release than the bundled one. (Note that such an upgraded version +of ``pip`` is considered to be a separately installed package and will not be +removed if Python is uninstalled.) + +The module is named *ensure*\ pip because if called when ``pip`` is already +installed, it does nothing. It also has an ``--upgrade`` option that will +cause it to install the bundled copy of ``pip`` if the existing installed +version of ``pip`` is older than the bundled copy. + + +.. _whatsnew-enum: + enum ---- @@ -357,11 +515,13 @@ compatible enumeration values. .. seealso:: - :pep:`435` - Adding an Enum type to the Python standard library + :pep:`435` -- Adding an Enum type to the Python standard library PEP written by Barry Warsaw, Eli Bendersky and Ethan Furman, implemented by Ethan Furman. +.. _whatsnew-pathlib: + pathlib ------- @@ -375,10 +535,12 @@ For Python 3.4, this module is considered a :term:`provisional API`. .. seealso:: - :pep:`428` - The pathlib module -- object-oriented filesystem paths + :pep:`428` -- The pathlib module -- object-oriented filesystem paths PEP written and implemented by Antoine Pitrou. +.. _whatsnew-selectors: + selectors --------- @@ -387,6 +549,8 @@ allows high-level and efficient I/O multiplexing, built upon the :mod:`select` module primitives. +.. _whatsnew-statistics: + statistics ---------- @@ -397,9 +561,11 @@ deviation of a data series. .. seealso:: - :pep:`450` - Adding A Statistics Module To The Standard Library + :pep:`450` -- Adding A Statistics Module To The Standard Library PEP written and implemented by Steven D'Aprano +.. _whatsnew-tracemalloc: + tracemalloc ----------- @@ -407,34 +573,72 @@ tracemalloc The new :mod:`tracemalloc` module (defined in :pep:`454`) is a debug tool to trace memory blocks allocated by Python. It provides the following information: -* Traceback where an object was allocated +* Trace where an object was allocated * Statistics on allocated memory blocks per filename and per line number: total size, number and average size of allocated memory blocks * Compute the differences between two snapshots to detect memory leaks .. seealso:: - :pep:`454` - Add a new tracemalloc module to trace Python memory allocations + :pep:`454` -- Add a new tracemalloc module to trace Python memory allocations PEP written and implemented by Victor Stinner + Improved Modules ================ + +abc +--- + +New function :func:`abc.get_cache_token` can be used to know when to invalidate +caches that are affected by changes in the object graph. (Contributed +by Łukasz Langa in :issue:`16832`.) + +New class :class:`~abc.ABC` has :class:`~abc.ABCMeta` as its meta class. +Using ``ABC`` as a base class has essentially the same effect as specifying +``metaclass=abc.ABCMeta``, but is simpler to type and easier to read. +(Contributed by Bruno Dupuis in :issue:`16049`.) + + aifc ---- -The :meth:`~aifc.getparams` method now returns a namedtuple rather than a +The :meth:`~aifc.aifc.getparams` method now returns a namedtuple rather than a plain tuple. (Contributed by Claudiu Popa in :issue:`17818`.) +:func:`aifc.open` now supports the context management protocol: when used in a +:keyword:`with` block, the :meth:`~aifc.aifc.close` method of the returned +object will be called automatically at the end of the block. (Contributed by +Serhiy Storchacha in :issue:`16486`.) + +The :meth:`~aifc.aifc.writeframesraw` and :meth:`~aifc.aifc.writeframes` +methods now accept any :term:`bytes-like object`. (Contributed by Serhiy +Storchaka in :issue:`8311`.) + + +argparse +-------- + +The :class:`~argparse.FileType` class now accepts *encoding* and +*errors* arguments, which are passed through to :func:`open`. (Contributed +by Lucas Maystre in :issue:`11175`.) + audioop ------- -Added support for 24-bit samples (:issue:`12866`). +:mod:`audioop` now supports 24-bit samples. (Contributed by Serhiy Storchaka +in :issue:`12866`.) + +New :func:`~audioop.byteswap` function converts big-endian samples to +little-endian and vice versa. (Contributed by Serhiy Storchaka in +:issue:`19641`.) -Added the :func:`~audioop.byteswap` function to convert big-endian samples -to little-endian and vice versa (:issue:`19641`). +All :mod:`audioop` functions now accept any :term:`bytes-like object`. Strings +are not accepted: they didn't work before, now they raise an error right away. +(Contributed by Serhiy Storchaka in :issue:`16685`.) base64 @@ -442,7 +646,25 @@ base64 The encoding and decoding functions in :mod:`base64` now accept any :term:`bytes-like object` in cases where it previously required a -:class:`bytes` or :class:`bytearray` instance (:issue:`17839`). +:class:`bytes` or :class:`bytearray` instance. (Contributed by Nick Coghlan in +:issue:`17839`.) + +New functions :func:`~base64.a85encode`, :func:`~base64.a85decode`, +:func:`~base64.b85encode`, and :func:`~base64.b85decode` provide the ability to +encode and decode binary data from and to ``Ascii85`` and the git/mercurial +``Base85`` formats, respectively. The ``a85`` functions have options that can +be used to make them compatible with the variants of the ``Ascii85`` encoding, +including the Adobe variant. (Contributed by Martin Morrison, the Mercurial +project, Serhiy Storchaka, and Antoine Pitrou in :issue:`17618`.) + + +collections +----------- + +The :meth:`.ChainMap.new_child` method now accepts an *m* argument specifying +the child map to add to the chain. This allows an existing mapping and/or a +custom mapping type to be used for the child. (Contributed by Vinay Sajip in +:issue:`16613`.) colorsys @@ -451,6 +673,7 @@ colorsys The number of digits in the coefficients for the RGB --- YIQ conversions have been expanded so that they match the FCC NTSC versions. The change in results should be less than 1% and may better match results found elsewhere. +(Contributed by Brian Landers and Serhiy Storchaka in :issue:`14323`.) contextlib @@ -458,50 +681,112 @@ contextlib The new :class:`contextlib.suppress` context manager helps to clarify the intent of code that deliberately suppresses exceptions from a single -statement. (Contributed by Raymond Hettinger in :issue:`15806` and -Zero Piraeus in :issue:`19266`) +statement. (Contributed by Raymond Hettinger in :issue:`15806` and +Zero Piraeus in :issue:`19266`.) The new :func:`contextlib.redirect_stdout` context manager makes it easier -for utility scripts to handle inflexible APIs that don't provide any -options to retrieve their output as a string or direct it to somewhere -other than :data:`sys.stdout`. In conjunction with :class:`io.StringIO`, -this context manager is also useful for checking expected output from -command line utilities. (Contribute by Raymond Hettinger in :issue:`15805`) +for utility scripts to handle inflexible APIs that write their output to +:data:`sys.stdout` and don't provide any options to redirect it. Using the +context manager, the :data:`sys.stdout` output can be redirected to any +other stream or, in conjunction with :class:`io.StringIO`, to a string. +The latter can be especially useful, for example, to capture output +from a function that was written to implement a command line interface. +It is recommended only for utility scripts because it affects the +global state of :data:`sys.stdout`. (Contributed by Raymond Hettinger +in :issue:`15805`.) The :mod:`contextlib` documentation has also been updated to include a :ref:`discussion <single-use-reusable-and-reentrant-cms>` of the differences between single use, reusable and reentrant context managers. +dbm +--- + +:func:`dbm.open` objects now support the context management protocol. When +used in a :keyword:`with` statement, the ``close`` method of the database +object will be called automatically at the end of the block. (Contributed by +Claudiu Popa and Nick Coghlan in :issue:`19282`.) + + dis --- -The :mod:`dis` module is now built around an :class:`~dis.Instruction` class -that provides details of individual bytecode operations and a -:func:`~dis.get_instructions` iterator that emits the Instruction stream for a -given piece of Python code. The various display tools in the :mod:`dis` -module have been updated to be based on these new components. +Functions :func:`~dis.show_code`, :func:`~dis.dis`, :func:`~dis.distb`, and +:func:`~dis.disassemble` now accept a keyword-only *file* argument that +controls where they write their output. -The new :class:`dis.Bytecode` class provides an object-oriented API for -inspecting bytecode, both in human-readable form and for iterating over -instructions. +The :mod:`dis` module is now built around an :class:`~dis.Instruction` class +that provides object oriented access to the details of each individual bytecode +operation. + +A new method, :func:`~dis.get_instructions`, provides an iterator that emits +the Instruction stream for a given piece of Python code. Thus it is now +possible to write a program that inspects and manipulates a bytecode +object in ways different from those provided by the :mod:`~dis` module +itself. For example:: + + >>> import dis + >>> for instr in dis.get_instructions(lambda x: x + 1): + ... print(instr.opname) + LOAD_FAST + LOAD_CONST + BINARY_ADD + RETURN_VALUE + +The various display tools in the :mod:`dis` module have been rewritten to use +these new components. + +In addition, a new application-friendly class :class:`~dis.Bytecode` provides +an object-oriented API for inspecting bytecode in both in human-readable form +and for iterating over instructions. The :class:`~dis.Bytecode` constructor +takes the same arguments that :func:`~dis.get_instruction` does (plus an +optional *current_offset*), and the resulting object can be iterated to produce +:class:`~dis.Instruction` objects. But it also has a :mod:`~dis.Bytecode.dis` +method, equivalent to calling :mod:`~dis.dis` on the constructor argument, but +returned as a multi-line string:: + + >>> bytecode = dis.Bytecode(lambda x: x +1, current_offset=3) + >>> for instr in bytecode: + ... print('{} ({})'.format(instr.opname, instr.opcode)) + LOAD_FAST (124) + LOAD_CONST (100) + BINARY_ADD (23) + RETURN_VALUE (83) + >>> bytecode.dis().splitlines() # doctest: +NORMALIZE_WHITESPACE + [' 1 0 LOAD_FAST 0 (x)', + ' --> 3 LOAD_CONST 1 (1)', + ' 6 BINARY_ADD', + ' 7 RETURN_VALUE'] + +:class:`~dis.Bytecode` also has a class method, +:meth:`~dis.Bytecode.from_traceback`, that provides the ability to manipulate a +traceback (that is, ``print(Bytecode.from_traceback(tb).dis())`` is equivalent +to ``distb(tb)``). (Contributed by Nick Coghlan, Ryan Kelly and Thomas Kluyver in :issue:`11816` -and Claudiu Popa in :issue:`17916`) +and Claudiu Popa in :issue:`17916`.) + +New function :func:`~dis.stack_effect` computes the effect on the Python stack +of a given opcode and argument, information that is not otherwise available. +(Contributed by Larry Hastings in :issue:`19722`.) doctest ------- -Added :data:`~doctest.FAIL_FAST` flag to halt test running as soon as the first -failure is detected. (Contributed by R. David Murray and Daniel Urban in -:issue:`16522`.) +A new :ref:`option flag <doctest-options>`, :data:`~doctest.FAIL_FAST`, halts +test running as soon as the first failure is detected. (Contributed by R. +David Murray and Daniel Urban in :issue:`16522`.) + +The :mod:`doctest` command line interface now uses :mod:`argparse`, and has two +new options, ``-o`` and ``-f``. ``-o`` allows :ref:`doctest options +<doctest-options>` to be specified on the command line, and ``-f`` is a +shorthand for ``-o FAIL_FAST`` (to parallel the similar option supported by the +:mod:`unittest` CLI). (Contributed by R. David Murray in :issue:`11390`.) -Updated the doctest command line interface to use :mod:`argparse`, and added -``-o`` and ``-f`` options to the interface. ``-o`` allows doctest options to -be specified on the command line, and ``-f`` is a shorthand for ``-o -FAIL_FAST`` (to parallel the similar option supported by the :mod:`unittest` -CLI). (Contributed by R. David Murray in :issue:`11390`.) +:mod:`doctest` will now find doctests in extension module ``__doc__`` strings. +(Contributed by Zachary Ware in :issue:`3158`.) email @@ -511,7 +796,8 @@ email override the default policy of the message when generating a string representation of it. This means that ``as_string`` can now be used in more circumstances, instead of having to create and use a :mod:`~email.generator` in -order to pass formatting parameters to its ``flatten`` method. +order to pass formatting parameters to its ``flatten`` method. (Contributed by +R. David Murray in :issue:`18600`.) New method :meth:`~email.message.Message.as_bytes` added to produce a bytes representation of the message in a fashion similar to how ``as_string`` @@ -519,36 +805,59 @@ produces a string representation. It does not accept the *maxheaderlen* argument, but does accept the *unixfrom* and *policy* arguments. The :class:`~email.message.Message` :meth:`~email.message.Message.__bytes__` method calls it, meaning that ``bytes(mymsg)`` will now produce the intuitive -result: a bytes object containing the fully formatted message. +result: a bytes object containing the fully formatted message. (Contributed +by R. David Murray in :issue:`18600`.) -(Contributed by R. David Murray in :issue:`18600`.) +The :meth:`.Message.set_param` message now accepts a *replace* keyword argument. +When specified, the associated header will be updated without changing +its location in the list of headers. For backward compatibility, the default +is ``False``. (Contributed by R. David Murray in :issue:`18891`.) -A pair of new subclasses of :class:`~email.message.Message` have been added, -along with a new sub-module, :mod:`~email.contentmanager`. All documentation -is currently in the new module, which is being added as part of the new -:term:`provisional <provisional package>` email API. These classes provide a -number of new methods that make extracting content from and inserting content -into email messages much easier. See the :mod:`~email.contentmanager` -documentation for details. -These API additions complete the bulk of the work that was planned as part of -the email6 project. The currently provisional API is scheduled to become final -in Python 3.5 (possibly with a few minor additions in the area of error -handling). +.. _whatsnew_email_contentmanager: -(Contributed by R. David Murray in :issue:`18891`.) +A pair of new subclasses of :class:`~email.message.Message` have been added +(:class:`.EmailMessage` and :class:`.MIMEPart`), along with a new sub-module, +:mod:`~email.contentmanager` and a new :mod:`~email.policy` attribute +:attr:`~email.policy.EmailPolicy.content_manager`. All documentation is +currently in the new module, which is being added as part of email's new +:term:`provisional API`. These classes provide a number of new methods that +make extracting content from and inserting content into email messages much +easier. For details, see the :mod:`~email.contentmanager` documentation and +the :ref:`email-contentmanager-api-examples`. These API additions complete the +bulk of the work that was planned as part of the email6 project. The currently +provisional API is scheduled to become final in Python 3.5 (possibly with a few +minor additions in the area of error handling). (Contributed by R. David +Murray in :issue:`18891`.) + + +filecmp +------- + +A new :func:`~filecmp.clear_cache` function provides the ability to clear the +:mod:`filecmp` comparison cache, which uses :func:`os.stat` information to +determine if the file has changed since the last compare. This can be used, +for example, if the file might have been changed and re-checked in less time +than the resolution of a particular filesystem's file modification time field. +(Contributed by Mark Levitt in :issue:`18149`.) + +New module attribute :data:`~filecmp.DEFAULT_IGNORES` provides the list of +directories that are used as the default value for the *ignore* parameter of +the :func:`~filecmp.dircmp` function. (Contributed by Eli Bendersky in +:issue:`15442`.) functools --------- -The new :func:`~functools.partialmethod` descriptor bring partial argument +The new :func:`~functools.partialmethod` descriptor brings partial argument application to descriptors, just as :func:`~functools.partial` provides for normal callables. The new descriptor also makes it easier to get arbitrary callables (including :func:`~functools.partial` instances) to behave like normal instance methods when included in a class definition. +(Contributed by Alon Horev and Nick Coghlan in :issue:`4331`.) -(Contributed by Alon Horev and Nick Coghlan in :issue:`4331`) +.. _whatsnew-singledispatch: The new :func:`~functools.singledispatch` decorator brings support for single-dispatch generic functions to the Python standard library. Where @@ -559,152 +868,513 @@ multiple implementations of an operation that allows it to work with .. seealso:: - :pep:`443` - Single-dispatch generic functions + :pep:`443` -- Single-dispatch generic functions PEP written and implemented by Łukasz Langa. +:func:`~functools.total_ordering` now supports a return value of +:const:`NotImplemented` from the underlying comparison function. (Contributed +by Katie Miller in :issue:`10042`.) + +A pure-python version of the :func:`~functools.partial` function is now in the +stdlib; in CPython it is overridden by the C accelerated version, but it is +available for other implementations to use. (Contributed by Brian Thorne in +:issue:`12428`.) + + +gc +-- + +New function :func:`~gc.get_stats` returns a list of three per-generation +dictionaries containing the collections statistics since interpreter startup. +(Contributed by Antoine Pitrou in :issue:`16351`.) + + +glob +---- + +A new function :func:`~glob.escape` provides a way to escape special characters +in a filename so that they do not become part of the globbing expansion but are +instead matched literally. (Contributed by Serhiy Storchaka in :issue:`8402`.) + hashlib ------- -New :func:`hashlib.pbkdf2_hmac` function. +A new :func:`hashlib.pbkdf2_hmac` function provides +the `PKCS#5 password-based key derivation function 2 +<http://en.wikipedia.org/wiki/PBKDF2>`_. (Contributed by Christian +Heimes in :issue:`18582`.) -(Contributed by Christian Heimes in :issue:`18582`) +The :attr:`~hashlib.hash.name` attribute of :mod:`hashlib` hash objects is now +a formally supported interface. It has always existed in CPython's +:mod:`hashlib` (although it did not return lower case names for all supported +hashes), but it was not a public interface and so some other Python +implementations have not previously supported it. (Contributed by Jason R. +Coombs in :issue:`18532`.) -html +hmac ---- -Added a new :func:`html.unescape` function that converts HTML5 character -references to the corresponding Unicode characters. +:mod:`hmac` now accepts ``bytearray`` as well as ``bytes`` for the *key* +argument to the :func:`~hmac.new` function, and the *msg* parameter to both the +:func:`~hmac.new` function and the :meth:`~hmac.HMAC.update` method now +accepts any type supported by the :mod:`hashlib` module. (Contributed +by Jonas Borgström in :issue:`18240`.) -(Contributed by Ezio Melotti in :issue:`2927`) +The *digestmod* argument to the :func:`hmac.new` function may now be any hash +digest name recognized by :mod:`hashlib`. In addition, the current behavior in +which the value of *digestmod* defaults to ``MD5`` is deprecated: in a +future version of Python there will be no default value. (Contributed by +Christian Heimes in :issue:`17276`.) -Added a new *convert_charrefs* keyword argument to -:class:`~html.parser.HTMLParser` that, when ``True``, automatically converts -all character references. For backward-compatibility, its value defaults -to ``False``, but it will change to ``True`` in future versions, so you -are invited to set it explicitly and update your code to use this new feature. +With the addition of :attr:`~hmac.HMAC.block_size` and :attr:`~hmac.HMAC.name` +attributes (and the formal documentation of the :attr:`~hmac.HMAC.digest_size` +attribute), the :mod:`hmac` module now conforms fully to the :pep:`247` API. +(Contributed by Christian Heimes in :issue:`18775`.) -(Contributed by Ezio Melotti in :issue:`13633`) + +html +---- + +New function :func:`~html.unescape` function converts HTML5 character references to +the corresponding Unicode characters. (Contributed by Ezio Melotti in +:issue:`2927`.) + +:class:`~html.parser.HTMLParser` accepts a new keyword argument +*convert_charrefs* that, when ``True``, automatically converts all character +references. For backward-compatibility, its value defaults to ``False``, but +it will change to ``True`` in a future version of Python, so you are invited to +set it explicitly and update your code to use this new feature. (Contributed +by Ezio Melotti in :issue:`13633`.) The *strict* argument of :class:`~html.parser.HTMLParser` is now deprecated. +(Contributed by Ezio Melotti in :issue:`15114`.) + + +http +---- + +:meth:`~http.server.BaseHTTPRequestHandler.send_error` now accepts an +optional additional *explain* parameter which can be used to provide an +extended error description, overriding the hardcoded default if there is one. +This extended error description will be formatted using the +:attr:`~http.server.HTTP.error_message_format` attribute and sent as the body +of the error response. (Contributed by Karl Cow in :issue:`12921`.) + +The :mod:`http.server` :ref:`command line interface <http-server-cli>` now has +a ``-b/--bind`` option that causes the server to listen on a specific address. +(Contributed by Malte Swart in :issue:`17764`.) + + +idlelib and IDLE +---------------- + +Since idlelib implements the IDLE shell and editor and is not intended for +import by other programs, it gets improvements with every release. See +:file:`Lib/idlelib/NEWS.txt` for a cumulative list of changes since 3.3.0, +as well as changes made in future 3.4.x releases. This file is also available +from the IDLE :menuselection:`Help --> About IDLE` dialog. -(Contributed by Ezio Melotti in :issue:`15114`) + +importlib +--------- + +The :class:`~importlib.abc.InspectLoader` ABC defines a new method, +:meth:`~importlib.abc.InspectLoader.source_to_code` that accepts source +data and a path and returns a code object. The default implementation +is equivalent to ``compile(data, path, 'exec', dont_inherit=True)``. +(Contributed by Eric Snow and Brett Cannon in :issue:`15627`.) + +:class:`~importlib.abc.InspectLoader` also now has a default implementation +for the :meth:`~importlib.abc.InspectLoader.get_code` method. However, +it will normally be desirable to override the default implementation +for performance reasons. (Contributed by Brett Cannon in :issue:`18072`.) + +The :func:`~importlib.reload` function has been moved from :mod:`imp` to +:mod:`importlib` as part of the :mod:`imp` module deprecation. (Contributed by +Berker Peksag in :issue:`18193`.) + +:mod:`importlib.util` now has a :data:`~importlib.util.MAGIC_NUMBER` attribute +providing access to the bytecode version number. This replaces the +:func:`~imp.get_magic` function in the deprecated :mod:`imp` module. +(Contributed by Brett Cannon in :issue:`18192`.) + +New :mod:`importlib.util` functions :func:`~importlib.util.cache_from_source` +and :func:`~importlib.util.source_from_cache` replace the same-named functions +in the deprecated :mod:`imp` module. (Contributed by Brett Cannon in +:issue:`18194`.) + +The :mod:`importlib` bootstrap :class:`.NamespaceLoader` now conforms to +the :class:`.InspectLoader` ABC, which means that ``runpy`` and +``python -m`` can now be used with namespace packages. (Contributed +by Brett Cannon in :issue:`18058`.) + +:mod:`importlib.util` has a new function :func:`~importlib.util.decode_source` +that decodes source from bytes using universal newline processing. This is +useful for implementing :meth:`.InspectLoader.get_source` methods. + +:class:`importlib.machinery.ExtensionFileLoader` now has a +:meth:`~importlib.machinery.ExtensionFileLoader.get_filename` method. This was +inadvertently omitted in the original implementation. (Contributed by Eric +Snow in :issue:`19152`.) inspect ------- - -The inspect module now offers a basic :ref:`command line interface +The :mod:`inspect` module now offers a basic :ref:`command line interface <inspect-module-cli>` to quickly display source code and other -information for modules, classes and functions. (Contributed by Claudiu Popa -and Nick Coghlan in :issue:`18626`) +information for modules, classes and functions. (Contributed by Claudiu Popa +and Nick Coghlan in :issue:`18626`.) :func:`~inspect.unwrap` makes it easy to unravel wrapper function chains created by :func:`functools.wraps` (and any other API that sets the -``__wrapped__`` attribute on a wrapper function). (Contributed by -Daniel Urban, Aaron Iles and Nick Coghlan in :issue:`13266`) +``__wrapped__`` attribute on a wrapper function). (Contributed by +Daniel Urban, Aaron Iles and Nick Coghlan in :issue:`13266`.) As part of the implementation of the new :mod:`enum` module, the :mod:`inspect` module now has substantially better support for custom ``__dir__`` methods and dynamic class attributes provided through -metaclasses (Contributed by Ethan Furman in :issue:`18929` and -:issue:`19030`) +metaclasses. (Contributed by Ethan Furman in :issue:`18929` and +:issue:`19030`.) + +:func:`~inspect.getfullargspec` and :func:`~inspect.getargspec` +now use the :func:`~inspect.signature` API. This allows them to +support a much broader range of callables, including those with +``__signature__`` attributes, those with metadata provided by argument +clinic, :func:`functools.partial` objects and more. Note that, unlike +:func:`~inspect.signature`, these functions still ignore ``__wrapped__`` +attributes, and report the already bound first argument for bound methods, +so it is still necessary to update your code to use +:func:`~inspect.signature` directly if those features are desired. +(Contributed by Yury Selivanov in :issue:`17481`.) + +:func:`~inspect.signature` now supports duck types of CPython functions, +which adds support for functions compiled with Cython. (Contributed +by Stefan Behnel and Yury Selivanov in :issue:`17159`.) + + +ipaddress +--------- + +:mod:`ipaddress` was added to the standard library in Python 3.3 as a +:term:`provisional API`. With the release of Python 3.4, this qualification +has been removed: :mod:`ipaddress` is now considered a stable API, covered +by the normal standard library requirements to maintain backwards +compatibility. + +A new :attr:`~ipaddress.IPv4Address.is_global` property is ``True`` if +an address is globally routeable. (Contributed by Peter Moody in +:issue:`17400`.) + + +logging +------- + +The :class:`~logging.handlers.TimedRotatingFileHandler` has a new *atTime* +parameter that can be used to specify the time of day when rollover should +happen. (Contributed by Ronald Oussoren in :issue:`9556`.) + +:class:`~logging.handlers.SocketHandler` and +:class:`~logging.handlers.DatagramHandler` now support Unix domain sockets (by +setting *port* to ``None``). (Contributed by Vinay Sajip in commit +ce46195b56a9.) + +:func:`~logging.config.fileConfig` now accepts a +:class:`configparser.RawConfigParser` subclass instance for the *fname* +parameter. This facilitates using a configuration file when logging +configuration is just a part of the overall application configuration, or where +the application modifies the configuration before passing it to +:func:`~logging.config.fileConfig`. (Contributed by Vinay Sajip in +:issue:`16110`.) + +Logging configuration data received from a socket via the +:func:`logging.config.listen` function can now be validated before being +processed by supplying a verification function as the argument to the new +*verify* keyword argument. (Contributed by Vinay Sajip in :issue:`15452`.) + + +.. _whatsnew-marshal-3: + +marshal +------- + +The default :mod:`marshal` version has been bumped to 3. The code implementing +the new version restores the Python2 behavior of recording only one copy of +interned strings and preserving the interning on deserialization, and extends +this "one copy" ability to any object type (including handling recursive +references). This reduces both the size of ``.pyc`` files and the amount of +memory a module occupies in memory when it is loaded from a ``.pyc`` (or +``.pyo``) file. (Contributed by Kristján Valur Jónsson in :issue:`16475`, +with additional speedups by Antoine Pitrou in :issue:`19219`.) mmap ---- -mmap objects can now be weakref'ed. - -(Contributed by Valerie Lambert in :issue:`4885`.) +mmap objects can now be :mod:`weakref`\ ed. (Contributed by Valerie Lambert in +:issue:`4885`.) multiprocessing --------------- -On Unix two new *start methods* have been added for starting processes -using :mod:`multiprocessing`. These make the mixing of processes with -threads more robust. See :issue:`8713`. +.. _whatsnew-multiprocessing-no-fork: + +On Unix two new :ref:`start methods <multiprocessing-start-methods>`, +``spawn`` and ``forkserver``, have been added for starting processes using +:mod:`multiprocessing`. These make the mixing of processes with threads more +robust, and the ``spawn`` method matches the semantics that multiprocessing has +always used on Windows. New function +:func:`~multiprocessing.get_all_start_methods` reports all start methods +available on the platform, :func:`~multiprocessing.get_start_method` reports +the current start method, and :func:`~multiprocessing.set_start_method` sets +the start method. (Contributed by Richard Oudkerk in :issue:`8713`.) + +:mod:`multiprocessing` also now has the concept of a ``context``, which +determines how child processes are created. New function +:func:`~multiprocessing.get_context` returns a context that uses a specified +start method. It has the same API as the :mod:`multiprocessing` module itself, +so you can use it to create :class:`~multiprocessing.pool.Pool`\ s and other +objects that will operate within that context. This allows a framework and an +application or different parts of the same application to use multiprocessing +without interfering with each other. (Contributed by Richard Oudkerk in +:issue:`18999`.) + +Except when using the old *fork* start method, child processes no longer +inherit unneeded handles/file descriptors from their parents (part of +:issue:`8713`). + +:mod:`multiprocessing` now relies on :mod:`runpy` (which implements the +``-m`` switch) to initialise ``__main__`` appropriately in child processes +when using the ``spawn`` or ``forkserver`` start methods. This resolves some +edge cases where combining multiprocessing, the ``-m`` command line switch, +and explicit relative imports could cause obscure failures in child +processes. (Contributed by Nick Coghlan in :issue:`19946`.) + + +operator +-------- + +New function :func:`~operator.length_hint` provides an implementation of the +specification for how the :meth:`~object.__length_hint__` special method should +be used, as part of the :pep:`424` formal specification of this language +feature. (Contributed by Armin Ronacher in :issue:`16148`.) -Also, except when using the old *fork* start method, child processes -will no longer inherit unneeded handles/file descriptors from their parents. +There is now a pure-python version of the :mod:`operator` module available for +reference and for use by alternate implementations of Python. (Contributed by +Zachary Ware in :issue:`16694`.) os -- -New functions to get and set the :ref:`inheritable flag <fd_inheritance>` of a file -descriptors or a Windows handle: +There are new functions to get and set the :ref:`inheritable flag +<fd_inheritance>` of a file descriptor (:func:`os.get_inheritable`, +:func:`os.set_inheritable`) or a Windows handle +(:func:`os.get_handle_inheritable`, :func:`os.set_handle_inheritable`). -* :func:`os.get_inheritable`, :func:`os.set_inheritable` -* :func:`os.get_handle_inheritable`, :func:`os.set_handle_inheritable` +New function :func:`~os.cpu_count` reports the number of CPUs available on the +platform on which Python is running (or ``None`` if the count can't be +determined). The :func:`multiprocessing.cpu_count` function is now implemented +in terms of this function). (Contributed by Trent Nelson, Yogesh Chaudhari, +Victor Stinner, and Charles-François Natali in :issue:`17914`.) + +:func:`os.path.samestat` is now available on the Windows platform (and the +:func:`os.path.samefile` implementation is now shared between Unix and +Windows). (Contributed by Brian Curtin in :issue:`11939`.) + +:func:`os.path.ismount` now recognizes volumes mounted below a drive +root on Windows. (Contributed by Tim Golden in :issue:`9035`.) + +:func:`os.open` supports two new flags on platforms that provide them, +:data:`~os.O_PATH` (un-opened file descriptor), and :data:`~os.O_TMPFILE` +(unnamed temporary file; as of 3.4.0 release available only on Linux systems +with a kernel version of 3.11 or newer that have uapi headers). (Contributed +by Christian Heimes in :issue:`18673` and Benjamin Peterson, respectively.) pdb --- -The ``print`` command has been removed from :mod:`pdb`, restoring access to the -``print`` function. +:mod:`pdb` has been enhanced to handle generators, :keyword:`yield`, and +``yield from`` in a more useful fashion. This is especially helpful when +debugging :mod:`asyncio` based programs. (Contributed by Andrew Svetlov and +Xavier de Gaye in :issue:`16596`.) -Rationale: Python2's ``pdb`` did not have a ``print`` command; instead, -entering ``print`` executed the ``print`` statement. In Python3 ``print`` was -mistakenly made an alias for the pdb :pdbcmd:`p` command. ``p``, however, -prints the ``repr`` of its argument, not the ``str`` like the Python2 ``print`` -command did. Worse, the Python3 ``pdb print`` command shadowed the Python3 -``print`` function, making it inaccessible at the ``pdb`` prompt. +The ``print`` command has been removed from :mod:`pdb`, restoring access to the +Python :func:`print` function from the pdb command line. Python2's ``pdb`` did +not have a ``print`` command; instead, entering ``print`` executed the +``print`` statement. In Python3 ``print`` was mistakenly made an alias for the +pdb :pdbcmd:`p` command. ``p``, however, prints the ``repr`` of its argument, +not the ``str`` like the Python2 ``print`` command did. Worse, the Python3 +``pdb print`` command shadowed the Python3 ``print`` function, making it +inaccessible at the ``pdb`` prompt. (Contributed by Connor Osborn in +:issue:`18764`.) -(Contributed by Connor Osborn in :issue:`18764`.) +.. _whatsnew-protocol-4: -poplib +pickle ------ -New :meth:`~poplib.POP3.stls` method to switch a clear-text POP3 session into -an encrypted POP3 session. +:mod:`pickle` now supports (but does not use by default) a new pickle protocol, +protocol 4. This new protocol addresses a number of issues that were present +in previous protocols, such as the serialization of nested classes, very large +strings and containers, and classes whose :meth:`__new__` method takes +keyword-only arguments. It also provides some efficiency improvements. + +.. seealso:: + + :pep:`3154` -- Pickle protocol 4 + PEP written by Antoine Pitrou and implemented by Alexandre Vassalotti. + + +plistlib +-------- + +:mod:`plistlib` now has an API that is similar to the standard pattern for +stdlib serialization protocols, with new :func:`~plistlib.load`, +:func:`~plistlib.dump`, :func:`~plistlib.loads`, and :func:`~plistlib.dumps` +functions. (The older API is now deprecated.) In addition to the already +supported XML plist format (:data:`~plistlib.FMT_XML`), it also now supports +the binary plist format (:data:`~plistlib.FMT_BINARY`). (Contributed by Ronald +Oussoren and others in :issue:`14455`.) + -New :meth:`~poplib.POP3.capa` method to query the capabilities advertised by the -POP3 server. +poplib +------ -(Contributed by Lorenzo Catucci in :issue:`4473`.) +Two new methods have been added to :mod:`poplib`: :meth:`~poplib.POP3.capa`, +which returns the list of capabilities advertised by the POP server, and +:meth:`~poplib.POP3.stls`, which switches a clear-text POP3 session into an +encrypted POP3 session if the POP server supports it. (Contributed by Lorenzo +Catucci in :issue:`4473`.) pprint ------ -The :mod:`pprint` module now supports *compact* mode for formatting long -sequences (:issue:`19132`). +The :mod:`pprint` module's :class:`~pprint.PrettyPrinter` class and its +:func:`~pprint.pformat`, and :func:`~pprint.pprint` functions have a new +option, *compact*, that controls how the output is formatted. Currently +setting *compact* to ``True`` means that sequences will be printed with as many +sequence elements as will fit within *width* on each (indented) line. +(Contributed by Serhiy Storchaka in :issue:`19132`.) + +Long strings are now wrapped using Python's normal line continuation +syntax. (Contributed by Antoine Pitrou in :issue:`17150`.) + + +pty +--- + +:func:`pty.spawn` now returns the status value from :func:`os.waitpid` on +the child process, instead of ``None``. (Contributed by Gregory P. Smith.) pydoc ----- -While significant changes have not been made to :mod:`pydoc` directly, +The :mod:`pydoc` module is now based directly on the :func:`inspect.signature` +introspection API, allowing it to provide signature information for a wider +variety of callable objects. This change also means that ``__wrapped__`` +attributes are now taken into account when displaying help information. +(Contributed by Larry Hastings in :issue:`19674`.) + +The :mod:`pydoc` module no longer displays the ``self`` parameter for +already bound methods. Instead, it aims to always display the exact current +signature of the supplied callable. (Contributed by Larry Hastings in +:issue:`20710`.) + +In addition to the changes that have been made to :mod:`pydoc` directly, its handling of custom ``__dir__`` methods and various descriptor -behaviours has been improved substantially by the underlying changes in +behaviours has also been improved substantially by the underlying changes in the :mod:`inspect` module. +As the :func:`help` builtin is based on :mod:`pydoc`, the above changes also +affect the behaviour of :func:`help`. + re -- -Added :func:`re.fullmatch` function and :meth:`regex.fullmatch` method, -which anchor the pattern at both ends of the string to match. -(Contributed by Matthew Barnett in :issue:`16203`.) +New :func:`~re.fullmatch` function and :meth:`.regex.fullmatch` method anchor +the pattern at both ends of the string to match. This provides a way to be +explicit about the goal of the match, which avoids a class of subtle bugs where +``$`` characters get lost during code changes or the addition of alternatives +to an existing regular expression. (Contributed by Matthew Barnett in +:issue:`16203`.) The repr of :ref:`regex objects <re-objects>` now includes the pattern and the flags; the repr of :ref:`match objects <match-objects>` now -includes the start, end, and the part of the string that matched. - -(Contributed by Serhiy Storchaka in :issue:`13592` and :issue:`17087`.) +includes the start, end, and the part of the string that matched. (Contributed +by Hugo Lopes Tavares and Serhiy Storchaka in :issue:`13592` and +:issue:`17087`.) resource -------- -New :func:`resource.prlimit` function and Linux specific constants. -(Contributed by Christian Heimes in :issue:`16595` and :issue:`19324`.) +New :func:`~resource.prlimit` function, available on Linux platforms with a +kernel version of 2.6.36 or later and glibc of 2.13 or later, provides the +ability to query or set the resource limits for processes other than the one +making the call. (Contributed by Christian Heimes in :issue:`16595`.) + +On Linux kernel version 2.6.36 or later, there are there are also some new +Linux specific constants: :attr:`~resource.RLIMIT_MSGQUEUE`, +:attr:`~resource.RLIMIT_NICE`, :attr:`~resource.RLIMIT_RTPRIO`, +:attr:`~resource.RLIMIT_RTTIME`, and :attr:`~resource.RLIMIT_SIGPENDING`. +(Contributed by Christian Heimes in :issue:`19324`.) + +On FreeBSD version 9 and later, there some new FreeBSD specific constants: +:attr:`~resource.RLIMIT_SBSIZE`, :attr:`~resource.RLIMIT_SWAP`, and +:attr:`~resource.RLIMIT_NPTS`. (Contributed by Claudiu Popa in +:issue:`19343`.) + + +select +------ + +:class:`~select.epoll` objects now support the context management protocol. +When used in a :keyword:`with` statement, the :meth:`~select.epoll.close` +method will be called automatically at the end of the block. (Contributed +by Serhiy Storchaka in :issue:`16488`.) + +:class:`~select.devpoll` objects now have :meth:`~select.devpoll.fileno` and +:meth:`~select.devpoll.close` methods, as well as a new attribute +:attr:`~select.devpoll.closed`. (Contributed by Victor Stinner in +:issue:`18794`.) + + +shelve +------ + +:class:`~shelve.Shelf` instances may now be used in :keyword:`with` statements, +and will be automatically closed at the end of the :keyword:`with` block. +(Contributed by Filip Gruszczyński in :issue:`13896`.) + + +shutil +------ + +:func:`~shutil.copyfile` now raises a specific :exc:`~shutil.Error` subclass, +:exc:`~shutil.SameFileError`, when the source and destination are the same +file, which allows an application to take appropriate action on this specific +error. (Contributed by Atsuo Ishimoto and Hynek Schlawack in +:issue:`1492704`.) + + +smtpd +----- + +The :class:`~smtpd.SMTPServer` and :class:`~smtpd.SMTPChannel` classes now +accept a *map* keyword argument which, if specified, is passed in to +:class:`asynchat.async_chat` as its *map* argument. This allows an application +to avoid affecting the global socket map. (Contributed by Vinay Sajip in +:issue:`11959`.) + smtplib ------- @@ -712,69 +1382,222 @@ smtplib :exc:`~smtplib.SMTPException` is now a subclass of :exc:`OSError`, which allows both socket level errors and SMTP protocol level errors to be caught in one try/except statement by code that only cares whether or not an error occurred. -(:issue:`2118`). +(Contributed by Ned Jackson Lovely in :issue:`2118`.) socket ------ +The socket module now supports the :data:`~socket.CAN_BCM` protocol on +platforms that support it. (Contributed by Brian Thorne in :issue:`15359`.) + Socket objects have new methods to get or set their :ref:`inheritable flag -<fd_inheritance>`: +<fd_inheritance>`, :meth:`~socket.socket.get_inheritable` and +:meth:`~socket.socket.set_inheritable`. -* :meth:`socket.socket.get_inheritable`, :meth:`socket.socket.set_inheritable` +The ``socket.AF_*`` and ``socket.SOCK_*`` constants are now enumeration values +using the new :mod:`enum` module. This allows meaningful names to be printed +during debugging, instead of integer "magic numbers". -The ``socket.AF_*`` and ``socket.SOCK_*`` constants are enumeration values, -using the new :mod:`enum` module. This allows descriptive reporting during -debugging, instead of seeing integer "magic numbers". +The :data:`~socket.AF_LINK` constant is now available on BSD and OSX. -ssl ---- +:func:`~socket.inet_pton` and :func:`~socket.inet_ntop` are now supported +on Windows. (Contributed by Atsuo Ishimoto in :issue:`7171`.) -TLSv1.1 and TLSv1.2 support. -(Contributed by Michele Orrù and Antoine Pitrou in :issue:`16692`) +sqlite3 +------- -* New diagnostic functions :func:`~ssl.get_default_verify_paths`, - :meth:`~ssl.SSLContext.cert_store_stats` and - :meth:`~ssl.SSLContext.get_ca_certs` +A new boolean parameter to the :func:`~sqlite3.connect` function, *uri*, can be +used to indicate that the *database* parameter is a ``uri`` (see the `SQLite +URI documentation <http://www.sqlite.org/uri.html>`_). (Contributed by poq in +:issue:`13773`.) -* Add :func:`ssl.enum_cert_store` to retrieve certificates and CRL from Windows' - cert store. -(Contributed by Christian Heimes in :issue:`18143`, :issue:`18147` and - :issue:`17134`.) +ssl +--- -Support for server-side SNI using the new +.. _whatsnew-tls-11-12: + +:data:`~ssl.PROTOCOL_TLSv1_1` and :data:`~ssl.PROTOCOL_TLSv1_2` (TLSv1.1 and +TLSv1.2 support) have been added; support for these protocols is only available if +Python is linked with OpenSSL 1.0.1 or later. (Contributed by Michele Orrù and +Antoine Pitrou in :issue:`16692`.) + +.. _whatsnew34-sslcontext: + +New function :func:`~ssl.create_default_context` provides a standard way to +obtain an :class:`~ssl.SSLContext` whose settings are intended to be a +reasonable balance between compatibility and security. These settings are +more stringent than the defaults provided by the :class:`~ssl.SSLContext` +constructor, and may be adjusted in the future, without prior deprecation, if +best-practice security requirements change. The new recommended best +practice for using stdlib libraries that support SSL is to use +:func:`~ssl.create_default_context` to obtain an :class:`~ssl.SSLContext` +object, modify it if needed, and then pass it as the *context* argument +of the appropriate stdlib API. (Contributed by Christian Heimes +in :issue:`19689`.) + +:class:`~ssl.SSLContext` method :meth:`~ssl.SSLContext.load_verify_locations` +accepts a new optional argument *cadata*, which can be used to provide PEM or +DER encoded certificates directly via strings or bytes, respectively. +(Contributed by Christian Heimes in :issue:`18138`.) + +New function :func:`~ssl.get_default_verify_paths` returns +a named tuple of the paths and environment variables that the +:meth:`~ssl.SSLContext.set_default_verify_paths` method uses to set +OpenSSL's default ``cafile`` and ``capath``. This can be an aid in +debugging default verification issues. (Contributed by Christian Heimes +in :issue:`18143`.) + +:class:`~ssl.SSLContext` has a new method, +:meth:`~ssl.SSLContext.cert_store_stats`, that reports the number of loaded +``X.509`` certs, ``X.509 CA`` certs, and certificate revocation lists (``crl``\ +s), as well as a :meth:`~ssl.SSLContext.get_ca_certs` method that returns a +list of the loaded ``CA`` certificates. (Contributed by Christian Heimes in +:issue:`18147`.) + +If OpenSSL 0.9.8 or later is available, :class:`~ssl.SSLContext` has an new +attribute :attr:`~ssl.SSLContext.verify_flags` that can be used to control the +certificate verification process by setting it to some combination of the new +constants :data:`~ssl.VERIFY_DEFAULT`, :data:`~ssl.VERIFY_CRL_CHECK_LEAF`, +:data:`~ssl.VERIFY_CRL_CHECK_CHAIN`, or :data:`~ssl.VERIFY_X509_STRICT`. +OpenSSL does not do any CRL verification by default. (Contributed by +Christien Heimes in :issue:`8813`.) + +New :class:`~ssl.SSLContext` method :meth:`~ssl.SSLContext.load_default_certs` +loads a set of default "certificate authority" (CA) certificates from default +locations, which vary according to the platform. It can be used to load both +TLS web server authentication certificates +(``purpose=``:data:`~ssl.Purpose.SERVER_AUTH`) for a client to use to verify a +server, and certificates for a server to use in verifying client certificates +(``purpose=``:data:`~ssl.Purpose.CLIENT_AUTH`). (Contributed by Christian +Heimes in :issue:`19292`.) + +.. _whatsnew34-win-cert-store: + +Two new windows-only functions, :func:`~ssl.enum_certificates` and +:func:`~ssl.enum_crls` provide the ability to retrieve certificates, +certificate information, and CRLs from the Windows cert store. (Contributed +by Christian Heimes in :issue:`17134`.) + +.. _whatsnew34-sni: + +Support for server-side SNI (Server Name Indication) using the new :meth:`ssl.SSLContext.set_servername_callback` method. - (Contributed by Daniel Black in :issue:`8109`.) +The dictionary returned by :meth:`.SSLSocket.getpeercert` contains additional +``X509v3`` extension items: ``crlDistributionPoints``, ``calIssuers``, and +``OCSP`` URIs. (Contributed by Christian Heimes in :issue:`18379`.) + stat ---- The :mod:`stat` module is now backed by a C implementation in :mod:`_stat`. A C implementation is required as most of the values aren't standardized and -platform-dependent. (Contributed by Christian Heimes in :issue:`11016`.) +are platform-dependent. (Contributed by Christian Heimes in :issue:`11016`.) -The module supports new file types: door, event port and whiteout. +The module supports new :mod:`~stat.ST_MODE` flags, :mod:`~stat.S_IFDOOR`, +:attr:`~stat.S_IFPORT`, and :attr:`~stat.S_IFWHT`. (Contributed by +Christian Hiemes in :issue:`11016`.) struct ------ -Streaming struct unpacking using :func:`struct.iter_unpack`. - +New function :mod:`~struct.iter_unpack` and a new +:meth:`struct.Struct.iter_unpack` method on compiled formats provide streamed +unpacking of a buffer containing repeated instances of a given format of data. (Contributed by Antoine Pitrou in :issue:`17804`.) +subprocess +---------- + +:func:`~subprocess.check_output` now accepts an *input* argument that can +be used to provide the contents of ``stdin`` for the command that is run. +(Contributed by Zack Weinberg in :issue:`16624`.) + +:func:`~subprocess.getstatus` and :func:`~subprocess.getstatusoutput` now +work on Windows. This change was actually inadvertently made in 3.3.4. +(Contributed by Tim Golden in :issue:`10197`.) + + sunau ----- The :meth:`~sunau.getparams` method now returns a namedtuple rather than a plain tuple. (Contributed by Claudiu Popa in :issue:`18901`.) -:meth:`sunau.open` now supports the context manager protocol (:issue:`18878`). +:meth:`sunau.open` now supports the context management protocol: when used in a +:keyword:`with` block, the ``close`` method of the returned object will be +called automatically at the end of the block. (Contributed by Serhiy Storchaka +in :issue:`18878`.) + +:meth:`.AU_write.setsampwidth` now supports 24 bit samples, thus adding +support for writing 24 sample using the module. (Contributed by +Serhiy Storchaka in :issue:`19261`.) + +The :meth:`~sunau.AU_write.writeframesraw` and +:meth:`~sunau.AU_write.writeframes` methods now accept any :term:`bytes-like +object`. (Contributed by Serhiy Storchaka in :issue:`8311`.) + + +sys +--- + +New function :func:`sys.getallocatedblocks` returns the current number of +blocks allocated by the interpreter. (In CPython with the default +``--with-pymalloc`` setting, this is allocations made through the +:c:func:`PyObject_Malloc` API.) This can be useful for tracking memory leaks, +especially if automated via a test suite. (Contributed by Antoine Pitrou +in :issue:`13390`.) + +When the Python interpreter starts in :ref:`interactive mode +<tut-interactive>`, it checks for an :data:`~sys.__interactivehook__` attribute +on the :mod:`sys` module. If the attribute exists, its value is called with no +arguments just before interactive mode is started. The check is made after the +:envvar:`PYTHONSTARTUP` file is read, so it can be set there. The :mod:`site` +module :ref:`sets it <rlcompleter-config>` to a function that enables tab +completion and history saving (in :file:`~/.python-history`) if the platform +supports :mod:`readline`. If you do not want this (new) behavior, you can +override it in :envvar:`PYTHONSTARTUP`, :mod:`sitecustomize`, or +:mod:`usercustomize` by deleting this attribute from :mod:`sys` (or setting it +to some other callable). (Contributed by Éric Araujo and Antoine Pitrou in +:issue:`5845`.) + + +tarfile +------- + +The :mod:`tarfile` module now supports a simple :ref:`tarfile-commandline` when +called as a script directly or via ``-m``. This can be used to create and +extract tarfile archives. (Contributed by Berker Peksag in :issue:`13477`.) + + +textwrap +-------- + +The :class:`~textwrap.TextWrapper` class has two new attributes/constructor +arguments: :attr:`~textwrap.TextWrapper.max_lines`, which limits the number of +lines in the output, and :attr:`~textwrap.TextWrapper.placeholder`, which is a +string that will appear at the end of the output if it has been truncated +because of *max_lines*. Building on these capabilities, a new convenience +function :func:`~textwrap.shorten` collapses all of the whitespace in the input +to single spaces and produces a single line of a given *width* that ends with +the *placeholder* (by default, ``[...]``). (Contributed by Antoine Pitrou and +Serhiy Storchaka in :issue:`18585` and :issue:`18725`.) + + +threading +--------- + +The :class:`~threading.Thread` object representing the main thread can be +obtained from the new :func:`~threading.main_thread` function. In normal +conditions this will be the thread from which the Python interpreter was +started. (Contributed by Andrew Svetlov in :issue:`18882`.) traceback @@ -782,24 +1605,126 @@ traceback A new :func:`traceback.clear_frames` function takes a traceback object and clears the local variables in all of the frames it references, -reducing the amount of memory consumed (:issue:`1565525`). +reducing the amount of memory consumed. (Contributed by Andrew Kuchling in +:issue:`1565525`.) + + +types +----- + +A new :func:`~types.DynamicClassAttribute` descriptor provides a way to define +an attribute that acts normally when looked up through an instance object, but +which is routed to the *class* ``__getattr__`` when looked up through the +class. This allows one to have properties active on a class, and have virtual +attributes on the class with the same name (see :mod:`Enum` for an example). +(Contributed by Ethan Furman in :issue:`19030`.) urllib ------ -Add support.for ``data:`` URLs in :mod:`urllib.request`. - -(Contributed by Mathias Panzenböck in :issue:`16423`.) +:mod:`urllib.request` now supports ``data:`` URLs via the +:class:`~urllib.request.DataHandler` class. (Contributed by Mathias Panzenböck +in :issue:`16423`.) + +The http method that will be used by a :class:`~urllib.request.Request` class +can now be specified by setting a :class:`~urllib.request.Request.method` +class attribute on the subclass. (Contributed by Jason R Coombs in +:issue:`18978`.) + +:class:`~urllib.request.Request` objects are now reusable: if the +:attr:`~urllib.request.Request.full_url` or :attr:`~urllib.request.Request.data` +attributes are modified, all relevant internal properties are updated. This +means, for example, that it is now possible to use the same +:class:`~urllib.request.Request` object in more than one +:meth:`.OpenerDirector.open` call with different *data* arguments, or to +modify a :class:`~urllib.request.Request`\ 's ``url`` rather than recomputing it +from scratch. There is also a new +:meth:`~urllib.request.Request.remove_header` method that can be used to remove +headers from a :class:`~urllib.request.Request`. (Contributed by Alexey +Kachayev in :issue:`16464`, Daniel Wozniak in :issue:`17485`, and Damien Brecht +and Senthil Kumaran in :issue:`17272`.) + +:class:`~urllib.error.HTTPError` objects now have a +:attr:`~urllib.error.HTTPError.headers` attribute that provides access to the +HTTP response headers associated with the error. (Contributed by +Berker Peksag in :issue:`15701`.) unittest -------- -Support for easy dynamically-generated subtests using the -:meth:`~unittest.TestCase.subTest` context manager. +The :class:`~unittest.TestCase` class has a new method, +:meth:`~unittest.TestCase.subTest`, that produces a context manager whose +:keyword:`with` block becomes a "sub-test". This context manager allows a test +method to dynamically generate subtests by, say, calling the ``subTest`` +context manager inside a loop. A single test method can thereby produce an +indefinite number of separately-identified and separately-counted tests, all of +which will run even if one or more of them fail. For example:: + + class NumbersTest(unittest.TestCase): + def test_even(self): + for i in range(6): + with self.subTest(i=i): + self.assertEqual(i % 2, 0) + +will result in six subtests, each identified in the unittest verbose output +with a label consisting of the variable name ``i`` and a particular value for +that variable (``i=0``, ``i=1``, etc). See :ref:`subtests` for the full +version of this example. (Contributed by Antoine Pitrou in :issue:`16997`.) + +:func:`unittest.main` now accepts an iterable of test names for +*defaultTest*, where previously it only accepted a single test name as a +string. (Contributed by Jyrki Pulliainen in :issue:`15132`.) + +If :class:`~unittest.SkipTest` is raised during test discovery (that is, at the +module level in the test file), it is now reported as a skip instead of an +error. (Contributed by Zach Ware in :issue:`16935`.) + +:meth:`~unittest.TestLoader.discover` now sorts the discovered files to provide +consistent test ordering. (Contributed by Martin Melin and Jeff Ramnani in +:issue:`16709`.) + +:class:`~unittest.TestSuite` now drops references to tests as soon as the test +has been run, if the test is successful. On Python interpreters that do +garbage collection, this allows the tests to be garbage collected if nothing +else is holding a reference to the test. It is possible to override this +behavior by creating a :class:`~unittest.TestSuite` subclass that defines a +custom ``_removeTestAtIndex`` method. (Contributed by Tom Wardill, Matt +McClure, and Andrew Svetlov in :issue:`11798`.) + +A new test assertion context-manager, :meth:`~unittest.TestCase.assertLogs`, +will ensure that a given block of code emits a log message using the +:mod:`logging` module. By default the message can come from any logger and +have a priority of ``INFO`` or higher, but both the logger name and an +alternative minimum logging level may be specified. The object returned by the +context manager can be queried for the :class:`~logging.LogRecord`\ s and/or +formatted messages that were logged. (Contributed by Antoine Pitrou in +:issue:`18937`.) + +Test discovery now works with namespace packages (Contributed by Claudiu Popa +in :issue:`17457`.) + +:mod:`unittest.mock` objects now inspect their specification signatures when +matching calls, which means an argument can now be matched by either position +or name, instead of only by position. (Contributed by Antoine Pitrou in +:issue:`17015`.) + +:func:`~mock.mock_open` objects now have ``readline`` and ``readlines`` +methods. (Contributed by Toshio Kuratomi in :issue:`17467`.) + + +venv +---- + +:mod:`venv` now includes activation scripts for the ``csh`` and ``fish`` +shells. (Contributed by Andrew Svetlov in :issue:`15417`.) -(Contributed by Antoine Pitrou in :issue:`16997`.) +:class:`~venv.EnvBuilder` and the :func:`~venv.create` convenience function +take a new keyword argument *with_pip*, which defaults to ``False``, that +controls whether or not :class:`~venv.EnvBuilder` ensures that ``pip`` is +installed in the virtual environment. (Contributed by Nick Coghlan in +:issue:`19552` as part of the :pep:`453` implementation.) wave @@ -808,93 +1733,74 @@ wave The :meth:`~wave.getparams` method now returns a namedtuple rather than a plain tuple. (Contributed by Claudiu Popa in :issue:`17487`.) -:meth:`wave.open` now supports the context manager protocol. (Contributed +:meth:`wave.open` now supports the context management protocol. (Contributed by Claudiu Popa in :issue:`17616`.) +:mod:`wave` can now :ref:`write output to unseekable files +<wave-write-objects>`. (Contributed by David Jones, Guilherme Polo, and Serhiy +Storchaka in :issue:`5202`.) + +The :meth:`~wave.Wave_write.writeframesraw` and +:meth:`~wave.Wave_write.writeframes` methods now accept any :term:`bytes-like +object`. (Contributed by Serhiy Storchaka in :issue:`8311`.) + weakref ------- New :class:`~weakref.WeakMethod` class simulates weak references to bound -methods. (Contributed by Antoine Pitrou in :issue:`14631`.) +methods. (Contributed by Antoine Pitrou in :issue:`14631`.) New :class:`~weakref.finalize` class makes it possible to register a callback to be invoked when an object is garbage collected, without needing to -carefully manage the lifecycle of the weak reference itself. (Contributed by -Richard Oudkerk in :issue:`15528`) +carefully manage the lifecycle of the weak reference itself. (Contributed by +Richard Oudkerk in :issue:`15528`.) + +The callback, if any, associated with a :class:`~weakref.ref` is now +exposed via the :attr:`~weakref.ref.__callback__` attribute. (Contributed +by Mark Dickinson in :issue:`17643`.) xml.etree --------- -Add an event-driven parser for non-blocking applications, -:class:`~xml.etree.ElementTree.XMLPullParser`. +A new parser, :class:`~xml.etree.ElementTree.XMLPullParser`, allows a +non-blocking applications to parse XML documents. An example can be +seen at :ref:`elementtree-pull-parsing`. (Contributed by Antoine +Pitrou in :issue:`17741`.) -(Contributed by Antoine Pitrou in :issue:`17741`.) +The :mod:`xml.etree.ElementTree` :func:`~xml.etree.ElementTree.tostring` and +:func:`~xml.etree.ElementTree.tostringlist` functions, and the +:class:`~xml.etree.ElementTree.ElementTree` +:meth:`~xml.etree.ElementTree.ElementTree.write` method, now have a +*short_empty_elements* :ref:`keyword-only parameter <keyword-only_parameter>` +providing control over whether elements with no content are written in +abbreviated (``<tag />``) or expanded (``<tag></tag>``) form. (Contributed by +Ariel Poliak and Serhiy Storchaka in :issue:`14377`.) -zipfile.PyZipfile ------------------ - -Add a filter function to ignore some packages (tests for instance), -:meth:`~zipfile.PyZipFile.writepy`. +zipfile +------- +The :meth:`~zipfile.PyZipFile.writepy` method of the +:class:`~zipfile.PyZipFile` class has a new *filterfunc* option that can be +used to control which directories and files are added to the archive. For +example, this could be used to exclude test files from the archive. (Contributed by Christian Tismer in :issue:`19274`.) +The *allowZip64* parameter to :class:`~zipfile.ZipFile` and +:class:`~zipfile.PyZipfile` is now ``True`` by default. (Contributed by +William Mallard in :issue:`17201`.) -Other improvements -================== - -Tab-completion is now enabled by default in the interactive interpreter. - -(Contributed by Antoine Pitrou and Éric Araujo in :issue:`5845`.) - -Python invocation changes -========================= - -Invoking the Python interpreter with ``--version`` now outputs the version to -standard output instead of standard error (:issue:`18338`). Similar changes -were made to :mod:`argparse` (:issue:`18920`) and other modules that have -script-like invocation capabilities (:issue:`18922`). - -Optimizations -============= - -Major performance enhancements have been added: - -* The UTF-32 decoder is now 3x to 4x faster. - -* The cost of hash collisions for sets is now reduced. Each hash table - probe now checks a series of consecutive, adjacent key/hash pairs before - continuing to make random probes through the hash table. This exploits - cache locality to make collision resolution less expensive. - - The collision resolution scheme can be described as a hybrid of linear - probing and open addressing. The number of additional linear probes - defaults to nine. This can be changed at compile-time by defining - LINEAR_PROBES to be any value. Set LINEAR_PROBES=0 to turn-off - linear probing entirely. - - (Contributed by Raymond Hettinger in :issue:`18771`.) - -* The interpreter starts about 30% faster. A couple of measures lead to the - speedup. The interpreter loads fewer modules on startup, e.g. the :mod:`re`, - :mod:`collections` and :mod:`locale` modules and their dependencies are no - longer imported by default. The marshal module has been improved to load - compiled Python code faster. - - (Contributed by Antoine Pitrou, Christian Heimes and Victor Stinner in - :issue:`19219`, :issue:`19218`, :issue:`19209`, :issue:`19205` and - :issue:`9548`) CPython Implementation Changes ============================== -.. _pep-445: +.. _whatsnew-pep-445: -PEP 445: Customization of CPython memory allocators +PEP 445: Customization of CPython Memory Allocators --------------------------------------------------- :pep:`445` adds new C level interfaces to customize memory allocation in @@ -902,13 +1808,13 @@ the CPython interpreter. .. seealso:: - :pep:`445` - Add new APIs to customize Python memory allocators + :pep:`445` -- Add new APIs to customize Python memory allocators PEP written and implemented by Victor Stinner. -.. _pep-442: +.. _whatsnew-pep-442: -PEP 442: Safe object finalization +PEP 442: Safe Object Finalization --------------------------------- :pep:`442` removes the current limitations and quirks of object finalization @@ -918,61 +1824,282 @@ part of a reference cycle. As part of this change, module globals are no longer forcibly set to :const:`None` during interpreter shutdown in most cases, instead relying -on the normal operation of the cyclic garbage collector. +on the normal operation of the cyclic garbage collector. This avoids a +whole class of interpreter-shutdown-time errors, usually involving +``__del__`` methods, that have plagued Python since the cyclic GC +was first introduced. .. seealso:: - :pep:`442` - Safe object finalization + :pep:`442` -- Safe object finalization PEP written and implemented by Antoine Pitrou. -Other build and C API changes +.. _whatsnew-pep-456: + +PEP 456: Secure and Interchangeable Hash Algorithm +-------------------------------------------------- + +:pep:`456` follows up on earlier security fix work done on Python's hash +algorithm to address certain DOS attacks to which public facing APIs backed by +dictionary lookups may be subject. (See :issue:`14621` for the start of the +current round of improvements.) The PEP unifies CPython's hash code to make it +easier for a packager to substitute a different hash algorithm, and switches +Python's default implementation to a SipHash implementation on platforms that +have a 64 bit data type. Any performance differences in comparison with the +older FNV algorithm are trivial. + +The PEP adds additional fields to the :attr:`sys.hash_info` struct sequence to +describe the hash algorithm in use by the currently executing binary. Otherwise, +the PEP does not alter any existing CPython APIs. + + +.. _whatsnew-pep-436: + +PEP 436: Argument Clinic +------------------------ + +"Argument Clinic" (:pep:`436`) is now part of the CPython build process +and can be used to simplify the process of defining and maintaining +accurate signatures for builtins and standard library extension modules +implemented in C. + +Some standard library extension modules have been converted to use Argument +Clinic in Python 3.4, and :mod:`pydoc` and :mod:`inspect` have been updated +accordingly. + +It is expected that signature metadata for programmatic introspection will +be added to additional callables implemented in C as part of Python 3.4 +maintenance releases. + +.. note:: + The Argument Clinic PEP is not fully up to date with the state of the + implementation. This has been deemed acceptable by the release manager + and core development team in this case, as Argument Clinic will not + be made available as a public API for third party use in Python 3.4. + +.. seealso:: + + :pep:`436` -- The Argument Clinic DSL + PEP written and implemented by Larry Hastings. + + +Other Build and C API Changes ----------------------------- -Changes to Python's build process and to the C API include: +* The new :c:func:`PyType_GetSlot` function has been added to the stable ABI, + allowing retrieval of function pointers from named type slots when using + the limited API. (Contributed by Martin von Löwis in :issue:`17162`.) * The new :c:func:`Py_SetStandardStreamEncoding` pre-initialization API allows applications embedding the CPython interpreter to reliably force - a particular encoding and error handler for the standard streams - (Contributed by Bastien Montagne and Nick Coghlan in :issue:`16129`) + a particular encoding and error handler for the standard streams. + (Contributed by Bastien Montagne and Nick Coghlan in :issue:`16129`.) * Most Python C APIs that don't mutate string arguments are now correctly - marked as accepting ``const char *`` rather than ``char *`` (Contributed - by Serhiy Storchaka in :issue:`1772673`). + marked as accepting ``const char *`` rather than ``char *``. (Contributed + by Serhiy Storchaka in :issue:`1772673`.) + +* A new shell version of ``python-config`` can be used even when a python + interpreter is not available (for example, in cross compilation scenarios). + +* :c:func:`PyUnicode_FromFormat` now supports width and precision + specifications for ``%s``, ``%A``, ``%U``, ``%V``, ``%S``, and ``%R``. + (Contributed by Ysj Ray and Victor Stinner in :issue:`7330`.) + +* New function :c:func:`PyStructSequence_InitType2` supplements the + existing :c:func:`PyStructSequence_InitType` function. The difference + is that it returns ``0`` on success and ``-1`` on failure. -* "Argument Clinic" (:pep:`436`) is now part of the CPython build process - and can be used to simplify the process of defining and maintaining - accurate signatures for builtins and standard library extension modules - implemented in C. +* The CPython source can now be compiled using the address sanity checking + features of recent versions of GCC and clang: the false alarms in the small + object allocator have been silenced. (Contributed by Dhiru Kholia in + :issue:`18596`.) - .. note:: - The Argument Clinic PEP is not fully up to date with the state of the - implementation. This has been deemed acceptable by the release manager - and core development team in this case, as Argument Clinic will not - be made available as a public API for third party use in Python 3.4. +* The Windows build now uses `Address Space Layout Randomization + <http://en.wikipedia.org/wiki/ASLR>`_ and `Data Execution Prevention + <http://en.wikipedia.org/wiki/Data_Execution_Prevention>`_. (Contributed by + Christian Heimes in :issue:`16632`.) +* New function :c:func:`PyObject_LengthHint` is the C API equivalent + of :func:`operator.length_hint`. (Contributed by Armin Ronacher in + :issue:`16148`.) -Deprecated -========== -Unsupported Operating Systems ------------------------------ +.. _other-improvements-3.4: -* OS/2 -* Windows 2000 +Other Improvements +------------------ +.. _whatsnew-isolated-mode: -Deprecated Python modules, functions and methods ------------------------------------------------- +* The :ref:`python <using-on-cmdline>` command has a new :ref:`option + <using-on-misc-options>`, ``-I``, which causes it to run in "isolated mode", + which means that :data:`sys.path` contains neither the script's directory nor + the user's ``site-packages`` directory, and all :envvar:`PYTHON*` environment + variables are ignored (it implies both ``-s`` and ``-E``). Other + restrictions may also be applied in the future, with the goal being to + isolate the execution of a script from the user's environment. This is + appropriate, for example, when Python is used to run a system script. On + most POSIX systems it can and should be used in the ``#!`` line of system + scripts. (Contributed by Christian Heimes in :issue:`16499`.) -* :meth:`difflib.SequenceMatcher.isbjunk` and - :meth:`difflib.SequenceMatcher.isbpopular` were removed: use ``x in sm.bjunk`` and - ``x in sm.bpopular``, where *sm* is a :class:`~difflib.SequenceMatcher` object. +* Tab-completion is now enabled by default in the interactive interpreter + on systems that support :mod:`readline`. History is also enabled by default, + and is written to (and read from) the file :file:`~/.python-history`. + (Contributed by Antoine Pitrou and Éric Araujo in :issue:`5845`.) + +* Invoking the Python interpreter with ``--version`` now outputs the version to + standard output instead of standard error (:issue:`18338`). Similar changes + were made to :mod:`argparse` (:issue:`18920`) and other modules that have + script-like invocation capabilities (:issue:`18922`). + +* The CPython Windows installer now adds ``.py`` to the :envvar:`PATHEXT` + variable when extensions are registered, allowing users to run a python + script at the windows command prompt by just typing its name without the + ``.py`` extension. (Contributed by Paul Moore in :issue:`18569`.) + +* A new ``make`` target `coverage-report + <https://docs.python.org/devguide/coverage.html#measuring-coverage-of-c-code-with-gcov-and-lcov>`_ + will build python, run the test suite, and generate an HTML coverage report + for the C codebase using ``gcov`` and `lcov + <http://ltp.sourceforge.net/coverage/lcov.php>`_. + +* The ``-R`` option to the :ref:`python regression test suite <regrtest>` now + also checks for memory allocation leaks, using + :func:`sys.getallocatedblocks()`. (Contributed by Antoine Pitrou in + :issue:`13390`.) + +* ``python -m`` now works with namespace packages. + +* The :mod:`stat` module is now implemented in C, which means it gets the + values for its constants from the C header files, instead of having the + values hard-coded in the python module as was previously the case. + +* Loading multiple python modules from a single OS module (``.so``, ``.dll``) + now works correctly (previously it silently returned the first python + module in the file). (Contributed by Václav Šmilauer in :issue:`16421`.) + +* A new opcode, :opcode:`LOAD_CLASSDEREF`, has been added to fix a bug in the + loading of free variables in class bodies that could be triggered by certain + uses of :ref:`__prepare__ <prepare>`. (Contributed by Benjamin Peterson in + :issue:`17853`.) + +* A number of MemoryError-related crashes were identified and fixed by Victor + Stinner using his :pep:`445`-based ``pyfailmalloc`` tool (:issue:`18408`, + :issue:`18520`). + +* The :ref:`pyvenv <scripts-pyvenv>` command now accepts a ``--copies`` option + to use copies rather than symlinks even on systems where symlinks are the + default. (Contributed by Vinay Sajip in :issue:`18807`.) + +* The :ref:`pyvenv <scripts-pyvenv>` command also accepts a ``--without-pip`` + option to suppress the otherwise-automatic bootstrapping of pip into + the virtual environment. (Contributed by Nick Coghlan in :issue:`19552` + as part of the :pep:`453` implementation.) + +* The encoding name is now optional in the value set for the + :envvar:`PYTHONIOENCODING` environment variable. This makes it possible to + set just the error handler, without changing the default encoding. + (Contributed by Serhiy Storchaka in :issue:`18818`.) -* :func:`importlib.util.module_for_loader` is pending deprecation. Using - :func:`importlib.util.module_to_load` and - :meth:`importlib.abc.Loader.init_module_attrs` allows subclasses of a loader - to more easily customize module loading. +* The :mod:`bz2`, :mod:`lzma`, and :mod:`gzip` module ``open`` functions now + support ``x`` (exclusive creation) mode. (Contributed by Tim Heaney and + Vajrasky Kok in :issue:`19201`, :issue:`19222`, and :issue:`19223`.) + + +Significant Optimizations +------------------------- + +* The UTF-32 decoder is now 3x to 4x faster. (Contributed by Serhiy Storchaka + in :issue:`14625`.) + +* The cost of hash collisions for sets is now reduced. Each hash table + probe now checks a series of consecutive, adjacent key/hash pairs before + continuing to make random probes through the hash table. This exploits + cache locality to make collision resolution less expensive. + The collision resolution scheme can be described as a hybrid of linear + probing and open addressing. The number of additional linear probes + defaults to nine. This can be changed at compile-time by defining + LINEAR_PROBES to be any value. Set LINEAR_PROBES=0 to turn-off + linear probing entirely. (Contributed by Raymond Hettinger in + :issue:`18771`.) + +* The interpreter starts about 30% faster. A couple of measures lead to the + speedup. The interpreter loads fewer modules on startup, e.g. the :mod:`re`, + :mod:`collections` and :mod:`locale` modules and their dependencies are no + longer imported by default. The marshal module has been improved to load + compiled Python code faster. (Contributed by Antoine Pitrou, Christian + Heimes and Victor Stinner in :issue:`19219`, :issue:`19218`, :issue:`19209`, + :issue:`19205` and :issue:`9548`.) + +* :class:`bz2.BZ2File` is now as fast or faster than the Python2 version for + most cases. :class:`lzma.LZMAFile` has also been optimized. (Contributed by + Serhiy Storchaka and Nadeem Vawda in :issue:`16034`.) + +* :func:`random.getrandbits` is 20%-40% faster for small integers (the most + common use case). (Contributed by Serhiy Storchaka in :issue:`16674`.) + +* By taking advantage of the new storage format for strings, pickling of + strings is now significantly faster. (Contributed by Victor Stinner and + Antoine Pitrou in :issue:`15596`.) + +* A performance issue in :meth:`io.FileIO.readall` has been solved. This + particularly affects Windows, and significantly speeds up the case of piping + significant amounts of data through :mod:`subprocess`. (Contributed + by Richard Oudkerk in :issue:`15758`.) + +* :func:`html.escape` is now 10x faster. (Contributed by Matt Bryant in + :issue:`18020`.) + +* On Windows, the native ``VirtualAlloc`` is now used instead of the CRT + ``malloc`` in ``obmalloc``. Artificial benchmarks show about a 3% memory + savings. + +* :func:`os.urandom` now uses a lazily-opened persistent file descriptor + so as to avoid using many file descriptors when run in parallel from + multiple threads. (Contributed by Antoine Pitrou in :issue:`18756`.) + + +.. _deprecated-3.4: + +Deprecated +========== + +This section covers various APIs and other features that have been deprecated +in Python 3.4, and will be removed in Python 3.5 or later. In most (but not +all) cases, using the deprecated APIs will produce a :exc:`DeprecationWarning` +when the interpreter is run with deprecation warnings enabled (for example, by +using ``-Wd``). + + +Deprecations in the Python API +------------------------------ + +* As mentioned in :ref:`whatsnew-pep-451`, a number of :mod:`importilb` + methods and functions are deprecated: :meth:`importlib.find_loader` is + replaced by :func:`importlib.util.find_spec`; + :meth:`importlib.machinery.PathFinder.find_module` is replaced by + :meth:`importlib.machinery.PathFinder.find_spec`; + :meth:`importlib.abc.MetaPathFinder.find_module` is replaced by + :meth:`importlib.abc.MetaPathFinder.find_spec`; + :meth:`importlib.abc.PathEntryFinder.find_loader` and + :meth:`~importlib.abc.PathEntryFinder.find_module` are replaced by + :meth:`importlib.abc.PathEntryFinder.find_spec`; all of the ``xxxLoader`` ABC + ``load_module`` methods (:meth:`importlib.abc.Loader.load_module`, + :meth:`importlib.abc.InspectLoader.load_module`, + :meth:`importlib.abc.FileLoader.load_module`, + :meth:`importlib.abc.SourceLoader.load_module`) should no longer be + implemented, instead loaders should implement an + ``exec_module`` method + (:meth:`importlib.abc.Loader.exec_module`, + :meth:`importlib.abc.InspectLoader.exec_module` + :meth:`importlib.abc.SourceLoader.exec_module`) and let the import system + take care of the rest; and + :meth:`importlib.abc.Loader.module_repr`, + :meth:`importlib.util.module_for_loader`, :meth:`importlib.util.set_loader`, + and :meth:`importlib.util.set_package` are no longer needed because their + functions are now handled automatically by the import system. * The :mod:`imp` module is pending deprecation. To keep compatibility with Python 2/3 code bases, the module's removal is currently not scheduled. @@ -980,30 +2107,165 @@ Deprecated Python modules, functions and methods * The :mod:`formatter` module is pending deprecation and is slated for removal in Python 3.6. -* MD5 as default digestmod for :mod:`hmac` is deprecated. Python 3.6 will - require an explicit digest name or constructor as *digestmod* argument. +* ``MD5`` as the default *digestmod* for the :func:`hmac.new` function is + deprecated. Python 3.6 will require an explicit digest name or constructor as + *digestmod* argument. +* The internal ``Netrc`` class in the :mod:`ftplib` module has been documented + as deprecated in its docstring for quite some time. It now emits a + :exc:`DeprecationWarning` and will be removed completely in Python 3.5. -Deprecated functions and types of the C API -------------------------------------------- +* The undocumented *endtime* argument to :meth:`subprocess.Popen.wait` should + not have been exposed and is hopefully not in use; it is deprecated and + will mostly likely be removed in Python 3.5. -* The ``PyThreadState.tick_counter`` field has been removed: its value was - meaningless since Python 3.2 ("new GIL"). +* The *strict* argument of :class:`~html.parser.HTMLParser` is deprecated. +* The :mod:`plistlib` :func:`~plistlib.readPlist`, + :func:`~plistlib.writePlist`, :func:`~plistlib.readPlistFromBytes`, and + :func:`~plistlib.writePlistToBytes` functions are deprecated in favor of the + corresponding new functions :func:`~plistlib.load`, :func:`~plistlib.dump`, + :func:`~plistlib.loads`, and :func:`~plistlib.dumps`. :func:`~plistlib.Data` + is deprecated in favor of just using the :class:`bytes` constructor. -Deprecated features +* The :mod:`sysconfig` key ``SO`` is deprecated, it has been replaced by + ``EXT_SUFFIX``. + +* The ``U`` mode accepted by various ``open`` functions is deprecated. + In Python3 it does not do anything useful, and should be replaced by + appropriate uses of :class:`io.TextIOWrapper` (if needed) and its *newline* + argument. + +* The *parser* argument of :func:`xml.etree.ElementTree.iterparse` has + been deprecated, as has the *html* argument of + :func:`~xml.etree.ElementTree.XMLParser`. To prepare for the removal of the + latter, all arguments to ``XMLParser`` should be passed by keyword. + + +Deprecated Features ------------------- +* Running :ref:`idle` with the ``-n`` flag (no subprocess) is deprecated. + However, the feature will not be removed until :issue:`18823` is resolved. + * The site module adding a "site-python" directory to sys.path, if it exists, is deprecated (:issue:`19375`). + +Removed +======= + + +Operating Systems No Longer Supported +------------------------------------- + +Support for the following operating systems has been removed from the source +and build tools: + +* OS/2 (:issue:`16135`). +* Windows 2000 (changeset e52df05b496a). +* Windows systems where ``COMSPEC`` points to ``command.com`` (:issue:`14470`). +* VMS (:issue:`16136`). + + +API and Feature Removals +------------------------ + +The following obsolete and previously deprecated APIs and features have been +removed: + +* The unmaintained ``Misc/TextMate`` and ``Misc/vim`` directories have been + removed (see the `devguide <https://docs.python.org/devguide>`_ + for suggestions on what to use instead). + +* The ``SO`` makefile macro is removed (it was replaced by the + ``SHLIB_SUFFIX`` and ``EXT_SUFFIX`` macros) (:issue:`16754`). + +* The ``PyThreadState.tick_counter`` field has been removed; its value has + been meaningless since Python 3.2, when the "new GIL" was introduced + (:issue:`19199`). + +* ``PyLoader`` and ``PyPycLoader`` have been removed from :mod:`importlib`. + (Contributed by Taras Lyapun in :issue:`15641`.) + +* The *strict* argument to :class:`~http.client.HTTPConnection` and + :class:`~http.client.HTTPSConnection` has been removed. HTTP 0.9-style + "Simple Responses" are no longer supported. + +* The deprecated :mod:`urllib.request.Request` getter and setter methods + ``add_data``, ``has_data``, ``get_data``, ``get_type``, ``get_host``, + ``get_selector``, ``set_proxy``, ``get_origin_req_host``, and + ``is_unverifiable`` have been removed (use direct attribute access instead). + +* Support for loading the deprecated ``TYPE_INT64`` has been removed from + :mod:`marshal`. (Contributed by Dan Riti in :issue:`15480`.) + +* :class:`inspect.Signature`: positional-only parameters are now required + to have a valid name. + +* :meth:`object.__format__` no longer accepts non-empty format strings, it now + raises a :exc:`TypeError` instead. Using a non-empty string has been + deprecated since Python 3.2. This change has been made to prevent a + situation where previously working (but incorrect) code would start failing + if an object gained a __format__ method, which means that your code may now + raise a :exc:`TypeError` if you are using an ``'s'`` format code with objects + that do not have a __format__ method that handles it. See :issue:`7994` for + background. + +* :meth:`difflib.SequenceMatcher.isbjunk` and + :meth:`difflib.SequenceMatcher.isbpopular` were deprecated in 3.2, and have + now been removed: use ``x in sm.bjunk`` and + ``x in sm.bpopular``, where *sm* is a :class:`~difflib.SequenceMatcher` object + (:issue:`13248`). + + +Code Cleanups +------------- + +* The unused and undocumented internal ``Scanner`` class has been removed from + the :mod:`pydoc` module. + +* The private and effectively unused ``_gestalt`` module has been removed, + along with the private :mod:`platform` functions ``_mac_ver_lookup``, + ``_mac_ver_gstalt``, and ``_bcd2str``, which would only have ever been called + on badly broken OSX systems (see :issue:`18393`). + +* The hardcoded copies of certain :mod:`stat` constants that were included in + the :mod:`tarfile` module namespace have been removed. + + + Porting to Python 3.4 ===================== This section lists previously described changes and other bugfixes that may require changes to your code. + +Changes in 'python' Command Behavior +------------------------------------ + +* In a posix shell, setting the :envvar:`PATH` environment variable to + an empty value is equivalent to not setting it at all. However, setting + :envvar:`PYTHONPATH` to an empty value was *not* equivalent to not setting it + at all: setting :envvar:`PYTHONPATH` to an empty value was equivalent to + setting it to ``.``, which leads to confusion when reasoning by analogy to + how :envvar:`PATH` works. The behavior now conforms to the posix convention + for :envvar:`PATH`. + +* The [X refs, Y blocks] output of a debug (``--with-pydebug``) build of the + CPython interpreter is now off by default. It can be re-enabled using the + ``-X showrefcount`` option. (Contributed by Ezio Melotti in :issue:`17323`.) + +* The python command and most stdlib scripts (as well as :mod:`argparse`) now + output ``--version`` information to ``stdout`` instead of ``stderr`` (for + issue list see :ref:`other-improvements-3.4` above). + + +Changes in the Python API +------------------------- + * The ABCs defined in :mod:`importlib.abc` now either raise the appropriate exception or return a default value instead of raising :exc:`NotImplementedError` blindly. This will only affect code calling @@ -1013,7 +2275,7 @@ that may require changes to your code. * The module type now initializes the :attr:`__package__` and :attr:`__loader__` attributes to ``None`` by default. To determine if these attributes were set in a backwards-compatible fashion, use e.g. - ``getattr(module, '__loader__', None) is not None``. + ``getattr(module, '__loader__', None) is not None``. (:issue:`17115`.) * :meth:`importlib.util.module_for_loader` now sets ``__loader__`` and ``__package__`` unconditionally to properly support reloading. If this is not @@ -1022,14 +2284,23 @@ that may require changes to your code. * Import now resets relevant attributes (e.g. ``__name__``, ``__loader__``, ``__package__``, ``__file__``, ``__cached__``) unconditionally when reloading. + Note that this restores a pre-3.3 behavior in that it means a module is + re-found when re-loaded (:issue:`19413`). * Frozen packages no longer set ``__path__`` to a list containing the package - name but an empty list instead. Determing if a module is a package should be - done using ``hasattr(module, '__path__')``. - -* :c:func:`PyErr_SetImportError` now sets :exc:`TypeError` when its **msg** - argument is not set. Previously only ``NULL`` was returned with no exception - set. + name, they now set it to an empty list. The previous behavior could cause + the import system to do the wrong thing on submodule imports if there was + also a directory with the same name as the frozen package. The correct way + to determine if a module is a package or not is to use ``hasattr(module, + '__path__')`` (:issue:`18065`). + +* Frozen modules no longer define a ``__file__`` attribute. It's semantically + incorrect for frozen modules to set the attribute as they are not loaded from + any explicit location. If you must know that a module comes from frozen code + then you can see if the module's ``__spec__.location`` is set to ``'frozen'``, + check if the loader is a subclass of + :class:`importlib.machinery.FrozenImporter`, + or if Python 2 compatibility is necessary you can use :func:`imp.is_frozen`. * :func:`py_compile.compile` now raises :exc:`FileExistsError` if the file path it would write to is a symlink or a non-regular file. This is to act as a @@ -1046,7 +2317,7 @@ that may require changes to your code. exceptions now. * :func:`functools.update_wrapper` and :func:`functools.wraps` now correctly - set the ``__wrapped__`` attribute to the function being wrapper, even if + set the ``__wrapped__`` attribute to the function being wrapped, even if that function also had its ``__wrapped__`` attribute set. This means ``__wrapped__`` attributes now correctly link a stack of decorated functions rather than every ``__wrapped__`` attribute in the chain @@ -1055,10 +2326,13 @@ that may require changes to your code. :func:`inspect.unwrap` to access the first function in the chain that has no ``__wrapped__`` attribute. -* (C API) The result of the :c:data:`PyOS_ReadlineFunctionPointer` callback must - now be a string allocated by :c:func:`PyMem_RawMalloc` or - :c:func:`PyMem_RawRealloc`, or *NULL* if an error occurred, instead of a - string allocated by :c:func:`PyMem_Malloc` or :c:func:`PyMem_Realloc`. +* :func:`inspect.getfullargspec` has been reimplemented on top of + :func:`inspect.signature` and hence handles a much wider variety of callable + objects than it did in the past. It is expected that additional builtin and + extension module callables will gain signature metadata over the course of + the Python 3.4 series. Code that assumes that + :func:`inspect.getfullargspec` will fail on non-Python callables may need + to be adjusted accordingly. * :class:`importlib.machinery.PathFinder` now passes on the current working directory to objects in :data:`sys.path_hooks` for the empty string. This @@ -1066,5 +2340,206 @@ that may require changes to your code. iterating through :data:`sys.path_importer_cache` based on :data:`sys.path` will not find all keys. A module's ``__file__`` when imported in the current working directory will also now have an absolute path, including when using - ``-m`` with the interpreter (this does not influence when the path to a file - is specified on the command-line). + ``-m`` with the interpreter (except for ``__main__.__file__`` when a script + has been executed directly using a relative path) (Contributed by Brett + Cannon in :issue:`18416`). is specified on the command-line) + (:issue:`18416`). + +* The removal of the *strict* argument to :class:`~http.client.HTTPConnection` + and :class:`~http.client.HTTPSConnection` changes the meaning of the + remaining arguments if you are specifying them positionally rather than by + keyword. If you've been paying attention to deprecation warnings your code + should already be specifying any additional arguments via keywords. + +* Strings between ``from __future__ import ...`` statements now *always* raise + a :exc:`SyntaxError`. Previously if there was no leading docstring, an + interstitial string would sometimes be ignored. This brings CPython into + compliance with the language spec; Jython and PyPy already were. + (:issue:`17434`). + +* :meth:`ssl.SSLSocket.getpeercert` and :meth:`ssl.SSLSocket.do_handshake` + now raise an :exc:`OSError` with ``ENOTCONN`` when the ``SSLSocket`` is not + connected, instead of the previous behavior of raising an + :exc:`AttributeError`. In addition, :meth:`~ssl.SSLSocket.getpeercert` + will raise a :exc:`ValueError` if the handshake has not yet been done. + +* :func:`base64.b32decode` now raises a :exc:`binascii.Error` when the + input string contains non-b32-alphabet characters, instead of a + :exc:`TypeError`. This particular :exc:`TypeError` was missed when the other + :exc:`TypeError`\ s were converted. (Contributed by Serhiy Storchaka in + :issue:`18011`.) Note: this change was also inadvertently applied in Python + 3.3.3. + +* The :attr:`~cgi.FieldStorage.file` attribute is now automatically closed when + the creating :class:`cgi.FieldStorage` instance is garbage collected. If you + were pulling the file object out separately from the :class:`cgi.FieldStorage` + instance and not keeping the instance alive, then you should either store the + entire :class:`cgi.FieldStorage` instance or read the contents of the file + before the :class:`cgi.FieldStorage` instance is garbage collected. + +* Calling ``read`` or ``write`` on a closed SSL socket now raises an + informative :exc:`ValueError` rather than the previous more mysterious + :exc:`AttributeError` (:issue:`9177`). + +* :meth:`slice.indices` no longer produces an :exc:`OverflowError` for huge + values. As a consequence of this fix, :meth:`slice.indices` now raises a + :exc:`ValueError` if given a negative length; previously it returned nonsense + values (:issue:`14794`). + +* The :class:`complex` constructor, unlike the :mod:`cmath` functions, was + incorrectly accepting :class:`float` values if an object's ``__complex__`` + special method returned one. This now raises a :exc:`TypeError`. + (:issue:`16290`.) + +* The :class:`int` constructor in 3.2 and 3.3 erroneously accepts :class:`float` + values for the *base* parameter. It is unlikely anyone was doing this, but + if so, it will now raise a :exc:`TypeError` (:issue:`16772`). + +* Defaults for keyword-only arguments are now evaluated *after* defaults for + regular keyword arguments, instead of before. Hopefully no one wrote any + code that depends on the previous buggy behavior (:issue:`16967`). + +* Stale thread states are now cleared after :func:`~os.fork`. This may cause + some system resources to be released that previously were incorrectly kept + perpetually alive (for example, database connections kept in thread-local + storage). (:issue:`17094`.) + +* Parameter names in ``__annotations__`` dicts are now mangled properly, + similarly to ``__kwdefaults__``. (Contributed by Yury Selivanov in + :issue:`20625`.) + +* :attr:`hashlib.hash.name` now always returns the identifier in lower case. + Previously some builtin hashes had uppercase names, but now that it is a + formal public interface the naming has been made consistent (:issue:`18532`). + +* Because :mod:`unittest.TestSuite` now drops references to tests after they + are run, test harnesses that re-use a :class:`~unittest.TestSuite` to re-run + a set of tests may fail. Test suites should not be re-used in this fashion + since it means state is retained between test runs, breaking the test + isolation that :mod:`unittest` is designed to provide. However, if the lack + of isolation is considered acceptable, the old behavior can be restored by + creating a :mod:`~unittest.TestSuite` subclass that defines a + ``_removeTestAtIndex`` method that does nothing (see + :meth:`.TestSuite.__iter__`) (:issue:`11798`). + +* :mod:`unittest` now uses :mod:`argparse` for command line parsing. There are + certain invalid command forms that used to work that are no longer allowed; + in theory this should not cause backward compatibility issues since the + disallowed command forms didn't make any sense and are unlikely to be in use. + +* The :func:`re.split`, :func:`re.findall`, and :func:`re.sub` functions, and + the :meth:`~re.match.group` and :meth:`~re.match.groups` methods of + ``match`` objects now always return a *bytes* object when the string + to be matched is a :term:`bytes-like object`. Previously the return type + matched the input type, so if your code was depending on the return value + being, say, a ``bytearray``, you will need to change your code. + +* :mod:`audioop` functions now raise an error immediately if passed string + input, instead of failing randomly later on (:issue:`16685`). + +* The new *convert_charrefs* argument to :class:`~html.parser.HTMLParser` + currently defaults to ``False`` for backward compatibility, but will + eventually be changed to default to ``True``. It is recommended that you add + this keyword, with the appropriate value, to any + :class:`~html.parser.HTMLParser` calls in your code (:issue:`13633`). + +* Since the *digestmod* argument to the :func:`hmac.new` function will in the + future have no default, all calls to :func:`hmac.new` should be changed to + explicitly specify a *digestmod* (:issue:`17276`). + +* Calling :func:`sysconfig.get_config_var` with the ``SO`` key, or looking + ``SO`` up in the results of a call to :func:`sysconfig.get_config_vars` + is deprecated. This key should be replaced by ``EXT_SUFFIX`` or + ``SHLIB_SUFFIX``, depending on the context (:issue:`19555`). + +* Any calls to ``open`` functions that specify ``U`` should be modified. + ``U`` is ineffective in Python3 and will eventually raise an error if used. + Depending on the function, the equivalent of its old Python2 behavior can be + achieved using either a *newline* argument, or if necessary by wrapping the + stream in :mod:`~io.TextIOWrapper` to use its *newline* argument + (:issue:`15204`). + +* If you use :ref:`pyvenv <scripts-pyvenv>` in a script and desire that pip + *not* be installed, you must add ``--without-pip`` to your command + invocation. + +* The default behavior of :func:`json.dump` and :func:`json.dumps` when + an indent is specified has changed: it no longer produces trailing + spaces after the item separating commas at the ends of lines. This + will matter only if you have tests that are doing white-space-sensitive + comparisons of such output (:issue:`16333`). + +* :mod:`doctest` now looks for doctests in extension module ``__doc__`` + strings, so if your doctest test discovery includes extension modules that + have things that look like doctests in them you may see test failures you've + never seen before when running your tests (:issue:`3158`). + +* The :mod:`collections.abc` module has been slightly refactored as + part of the Python startup improvements. As a consequence of this, it is no + longer the case that importing :mod:`collections` automatically imports + :mod:`collections.abc`. If your program depended on the (undocumented) + implicit import, you will need to add an explicit ``import collections.abc`` + (:issue:`20784`). + + +Changes in the C API +-------------------- + +* :c:func:`PyEval_EvalFrameEx`, :c:func:`PyObject_Repr`, and + :c:func:`PyObject_Str`, along with some other internal C APIs, now include + a debugging assertion that ensures they are not used in situations where + they may silently discard a currently active exception. In cases where + discarding the active exception is expected and desired (for example, + because it has already been saved locally with :c:func:`PyErr_Fetch` or + is being deliberately replaced with a different exception), an explicit + :c:func:`PyErr_Clear` call will be needed to avoid triggering the + assertion when invoking these operations (directly or indirectly) and + running against a version of Python that is compiled with assertions + enabled. + +* :c:func:`PyErr_SetImportError` now sets :exc:`TypeError` when its **msg** + argument is not set. Previously only ``NULL`` was returned with no exception + set. + +* The result of the :c:data:`PyOS_ReadlineFunctionPointer` callback must + now be a string allocated by :c:func:`PyMem_RawMalloc` or + :c:func:`PyMem_RawRealloc`, or *NULL* if an error occurred, instead of a + string allocated by :c:func:`PyMem_Malloc` or :c:func:`PyMem_Realloc` + (:issue:`16742`) + +* :c:func:`PyThread_set_key_value` now always set the value. In Python + 3.3, the function did nothing if the key already exists (if the current + value is a non-NULL pointer). + +* The ``f_tstate`` (thread state) field of the :c:type:`PyFrameObject` + structure has been removed to fix a bug: see :issue:`14432` for the + rationale. + +Changed in 3.4.3 +================ + +.. _pep-476: + +PEP 476: Enabling certificate verification by default for stdlib http clients +----------------------------------------------------------------------------- + +:mod:`http.client` and modules which use it, such as :mod:`urllib.request` and +:mod:`xmlrpc.client`, will now verify that the server presents a certificate +which is signed by a CA in the platform trust store and whose hostname matches +the hostname being requested by default, significantly improving security for +many applications. + +For applications which require the old previous behavior, they can pass an +alternate context:: + + import urllib.request + import ssl + + # This disables all verification + context = ssl._create_unverified_context() + + # This allows using a specific certificate for the host, which doesn't need + # to be in the trust store + context = ssl.create_default_context(cafile="/path/to/file.crt") + + urllib.request.urlopen("https://invalid-cert/", context=context) diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst new file mode 100644 index 000000000000..c82066650c35 --- /dev/null +++ b/Doc/whatsnew/3.5.rst @@ -0,0 +1,2482 @@ +**************************** + What's New In Python 3.5 +**************************** + +:Editors: Elvis Pranskevichus <elvis@magic.io>, Yury Selivanov <yury@magic.io> + +.. Rules for maintenance: + + * Anyone can add text to this document. Do not spend very much time + on the wording of your changes, because your text will probably + get rewritten to some degree. + + * The maintainer will go through Misc/NEWS periodically and add + changes; it's therefore more important to add your changes to + Misc/NEWS than to this file. + + * This is not a complete list of every single change; completeness + is the purpose of Misc/NEWS. Some changes I consider too small + or esoteric to include. If such a change is added to the text, + I'll just remove it. (This is another reason you shouldn't spend + too much time on writing your addition.) + + * If you want to draw your new text to the attention of the + maintainer, add 'XXX' to the beginning of the paragraph or + section. + + * It's OK to just add a fragmentary note about a change. For + example: "XXX Describe the transmogrify() function added to the + socket module." The maintainer will research the change and + write the necessary text. + + * You can comment out your additions if you like, but it's not + necessary (especially when a final release is some months away). + + * Credit the author of a patch or bugfix. Just the name is + sufficient; the e-mail address isn't necessary. + + * It's helpful to add the bug/patch number as a comment: + + XXX Describe the transmogrify() function added to the socket + module. + (Contributed by P.Y. Developer in :issue:`12345`.) + + This saves the maintainer the effort of going through the Mercurial log + when researching a change. + +This article explains the new features in Python 3.5, compared to 3.4. +Python 3.5 was released on September 13, 2015.  See the +`changelog <https://docs.python.org/3.5/whatsnew/changelog.html>`_ for a full +list of changes. + +.. seealso:: + + :pep:`478` - Python 3.5 Release Schedule + + +Summary -- Release highlights +============================= + +New syntax features: + +* :ref:`PEP 492 <whatsnew-pep-492>`, coroutines with async and await syntax. +* :ref:`PEP 465 <whatsnew-pep-465>`, a new matrix multiplication operator: ``a @ b``. +* :ref:`PEP 448 <whatsnew-pep-448>`, additional unpacking generalizations. + + +New library modules: + +* :mod:`typing`: :ref:`PEP 484 -- Type Hints <whatsnew-pep-484>`. +* :mod:`zipapp`: :ref:`PEP 441 Improving Python ZIP Application Support + <whatsnew-zipapp>`. + + +New built-in features: + +* ``bytes % args``, ``bytearray % args``: :ref:`PEP 461 <whatsnew-pep-461>` -- + Adding ``%`` formatting to bytes and bytearray. + +* New :meth:`bytes.hex`, :meth:`bytearray.hex` and :meth:`memoryview.hex` + methods. (Contributed by Arnon Yaari in :issue:`9951`.) + +* :class:`memoryview` now supports tuple indexing (including multi-dimensional). + (Contributed by Antoine Pitrou in :issue:`23632`.) + +* Generators have a new ``gi_yieldfrom`` attribute, which returns the + object being iterated by ``yield from`` expressions. (Contributed + by Benno Leslie and Yury Selivanov in :issue:`24450`.) + +* A new :exc:`RecursionError` exception is now raised when maximum + recursion depth is reached. (Contributed by Georg Brandl + in :issue:`19235`.) + + +CPython implementation improvements: + +* When the ``LC_TYPE`` locale is the POSIX locale (``C`` locale), + :py:data:`sys.stdin` and :py:data:`sys.stdout` now use the + ``surrogateescape`` error handler, instead of the ``strict`` error handler. + (Contributed by Victor Stinner in :issue:`19977`.) + +* ``.pyo`` files are no longer used and have been replaced by a more flexible + scheme that includes the optimization level explicitly in ``.pyc`` name. + (See :ref:`PEP 488 overview <whatsnew-pep-488>`.) + +* Builtin and extension modules are now initialized in a multi-phase process, + which is similar to how Python modules are loaded. + (See :ref:`PEP 489 overview <whatsnew-pep-489>`.) + + +Significant improvements in the standard library: + +* :class:`collections.OrderedDict` is now + :ref:`implemented in C <whatsnew-ordereddict>`, which makes it + 4 to 100 times faster. + +* :mod:`ssl` module gained + :ref:`support for Memory BIO <whatsnew-sslmemorybio>`, which decouples SSL + protocol handling from network IO. + +* The new :func:`os.scandir` function provides a + :ref:`better and significantly faster way <whatsnew-pep-471>` + of directory traversal. + +* :func:`functools.lru_cache` has been mostly + :ref:`reimplemented in C <whatsnew-lrucache>`, yielding much better + performance. + +* The new :func:`subprocess.run` function provides a + :ref:`streamlined way to run subprocesses <whatsnew-subprocess>`. + +* The :mod:`traceback` module has been significantly + :ref:`enhanced <whatsnew-traceback>` for improved + performance and developer convenience. + + +Security improvements: + +* SSLv3 is now disabled throughout the standard library. + It can still be enabled by instantiating a :class:`ssl.SSLContext` + manually. (See :issue:`22638` for more details; this change was + backported to CPython 3.4 and 2.7.) + +* HTTP cookie parsing is now stricter, in order to protect + against potential injection attacks. (Contributed by Antoine Pitrou + in :issue:`22796`.) + + +Windows improvements: + +* A new installer for Windows has replaced the old MSI. + See :ref:`using-on-windows` for more information. + +* Windows builds now use Microsoft Visual C++ 14.0, and extension modules + should use the same. + + +Please read on for a comprehensive list of user-facing changes, including many +other smaller improvements, CPython optimizations, deprecations, and potential +porting issues. + + +New Features +============ + +.. _whatsnew-pep-492: + +PEP 492 - Coroutines with async and await syntax +------------------------------------------------ + +:pep:`492` greatly improves support for asynchronous programming in Python +by adding :term:`awaitable objects <awaitable>`, +:term:`coroutine functions <coroutine function>`, +:term:`asynchronous iteration <asynchronous iterable>`, +and :term:`asynchronous context managers <asynchronous context manager>`. + +Coroutine functions are declared using the new :keyword:`async def` syntax:: + + >>> async def coro(): + ... return 'spam' + +Inside a coroutine function, the new :keyword:`await` expression can be used +to suspend coroutine execution until the result is available. Any object +can be *awaited*, as long as it implements the :term:`awaitable` protocol by +defining the :meth:`__await__` method. + +PEP 492 also adds :keyword:`async for` statement for convenient iteration +over asynchronous iterables. + +An example of a rudimentary HTTP client written using the new syntax:: + + import asyncio + + async def http_get(domain): + reader, writer = await asyncio.open_connection(domain, 80) + + writer.write(b'\r\n'.join([ + b'GET / HTTP/1.1', + b'Host: %b' % domain.encode('latin-1'), + b'Connection: close', + b'', b'' + ])) + + async for line in reader: + print('>>>', line) + + writer.close() + + loop = asyncio.get_event_loop() + try: + loop.run_until_complete(http_get('example.com')) + finally: + loop.close() + + +Similarly to asynchronous iteration, there is a new syntax for asynchronous +context managers. The following script:: + + import asyncio + + async def coro(name, lock): + print('coro {}: waiting for lock'.format(name)) + async with lock: + print('coro {}: holding the lock'.format(name)) + await asyncio.sleep(1) + print('coro {}: releasing the lock'.format(name)) + + loop = asyncio.get_event_loop() + lock = asyncio.Lock() + coros = asyncio.gather(coro(1, lock), coro(2, lock)) + try: + loop.run_until_complete(coros) + finally: + loop.close() + +will output:: + + coro 2: waiting for lock + coro 2: holding the lock + coro 1: waiting for lock + coro 2: releasing the lock + coro 1: holding the lock + coro 1: releasing the lock + +Note that both :keyword:`async for` and :keyword:`async with` can only +be used inside a coroutine function declared with :keyword:`async def`. + +Coroutine functions are intended to be run inside a compatible event loop, +such as the :ref:`asyncio loop <asyncio-event-loop>`. + +.. seealso:: + + :pep:`492` -- Coroutines with async and await syntax + PEP written and implemented by Yury Selivanov. + + +.. _whatsnew-pep-465: + +PEP 465 - A dedicated infix operator for matrix multiplication +-------------------------------------------------------------- + +:pep:`465` adds the ``@`` infix operator for matrix multiplication. +Currently, no builtin Python types implement the new operator, however, it +can be implemented by defining :meth:`__matmul__`, :meth:`__rmatmul__`, +and :meth:`__imatmul__` for regular, reflected, and in-place matrix +multiplication. The semantics of these methods is similar to that of +methods defining other infix arithmetic operators. + +Matrix multiplication is a notably common operation in many fields of +mathematics, science, engineering, and the addition of ``@`` allows writing +cleaner code:: + + S = (H @ beta - r).T @ inv(H @ V @ H.T) @ (H @ beta - r) + +instead of:: + + S = dot((dot(H, beta) - r).T, + dot(inv(dot(dot(H, V), H.T)), dot(H, beta) - r)) + +An upcoming release of NumPy 1.10 will add support for the new operator:: + + >>> import numpy + + >>> x = numpy.ones(3) + >>> x + array([ 1., 1., 1.]) + + >>> m = numpy.eye(3) + >>> m + array([[ 1., 0., 0.], + [ 0., 1., 0.], + [ 0., 0., 1.]]) + + >>> x @ m + array([ 1., 1., 1.]) + + +.. seealso:: + + :pep:`465` -- A dedicated infix operator for matrix multiplication + PEP written by Nathaniel J. Smith; implemented by Benjamin Peterson. + + +.. _whatsnew-pep-448: + +PEP 448 - Additional Unpacking Generalizations +---------------------------------------------- + +:pep:`448` extends the allowed uses of the ``*`` iterable unpacking +operator and ``**`` dictionary unpacking operator. It is now possible +to use an arbitrary number of unpackings in function calls:: + + >>> print(*[1], *[2], 3, *[4, 5]) + 1 2 3 4 5 + + >>> def fn(a, b, c, d): + ... print(a, b, c, d) + ... + + >>> fn(**{'a': 1, 'c': 3}, **{'b': 2, 'd': 4}) + 1 2 3 4 + +Similarly, tuple, list, set, and dictionary displays allow multiple +unpackings:: + + >>> *range(4), 4 + (0, 1, 2, 3, 4) + + >>> [*range(4), 4] + [0, 1, 2, 3, 4] + + >>> {*range(4), 4, *(5, 6, 7)} + {0, 1, 2, 3, 4, 5, 6, 7} + + >>> {'x': 1, **{'y': 2}} + {'x': 1, 'y': 2} + +.. seealso:: + + :pep:`448` -- Additional Unpacking Generalizations + PEP written by Joshua Landau; implemented by Neil Girdhar, + Thomas Wouters, and Joshua Landau. + + +.. _whatsnew-pep-461: + +PEP 461 - % formatting support for bytes and bytearray +------------------------------------------------------ + +:pep:`461` adds support for ``%`` +:ref:`interpolation operator <bytes-formatting>` to :class:`bytes` +and :class:`bytearray`. + +While interpolation is usually thought of as a string operation, there are +cases where interpolation on ``bytes`` or ``bytearrays`` makes sense, and the +work needed to make up for this missing functionality detracts from the +overall readability of the code. This issue is particularly important when +dealing with wire format protocols, which are often a mixture of binary +and ASCII compatible text. + +Examples:: + + >>> b'Hello %b!' % b'World' + b'Hello World!' + + >>> b'x=%i y=%f' % (1, 2.5) + b'x=1 y=2.500000' + +Unicode is not allowed for ``%b``, but it is accepted by ``%a`` (equivalent of +``repr(obj).encode('ascii', 'backslashreplace')``):: + + >>> b'Hello %b!' % 'World' + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + TypeError: %b requires bytes, or an object that implements __bytes__, not 'str' + + >>> b'price: %a' % '10€' + b"price: '10\\u20ac'" + +Note that ``%s`` and ``%r`` conversion types, although supported, should +only be used in codebases that need compatibility with Python 2. + +.. seealso:: + + :pep:`461` -- Adding % formatting to bytes and bytearray + PEP written by Ethan Furman; implemented by Neil Schemenauer and + Ethan Furman. + + +.. _whatsnew-pep-484: + +PEP 484 - Type Hints +-------------------- + +Function annotation syntax has been a Python feature since version 3.0 +(:pep:`3107`), however the semantics of annotations has been left undefined. + +Experience has shown that the majority of function annotation +uses were to provide type hints to function parameters and return values. It +became evident that it would be beneficial for Python users, if the +standard library included the base definitions and tools for type annotations. + +:pep:`484` introduces a :term:`provisional module <provisional api>` to +provide these standard definitions and tools, along with some conventions +for situations where annotations are not available. + +For example, here is a simple function whose argument and return type +are declared in the annotations:: + + def greeting(name: str) -> str: + return 'Hello ' + name + +While these annotations are available at runtime through the usual +:attr:`__annotations__` attribute, *no automatic type checking happens at +runtime*. Instead, it is assumed that a separate off-line type checker +(e.g. `mypy <http://mypy-lang.org>`_) will be used for on-demand +source code analysis. + +The type system supports unions, generic types, and a special type +named :class:`~typing.Any` which is consistent with (i.e. assignable to +and from) all types. + +.. seealso:: + + * :mod:`typing` module documentation + * :pep:`484` -- Type Hints + PEP written by Guido van Rossum, Jukka Lehtosalo, and Łukasz Langa; + implemented by Guido van Rossum. + * :pep:`483` -- The Theory of Type Hints + PEP written by Guido van Rossum + + +.. _whatsnew-pep-471: + +PEP 471 - os.scandir() function -- a better and faster directory iterator +------------------------------------------------------------------------- + +:pep:`471` adds a new directory iteration function, :func:`os.scandir`, +to the standard library. Additionally, :func:`os.walk` is now +implemented using ``scandir``, which makes it 3 to 5 times faster +on POSIX systems and 7 to 20 times faster on Windows systems. This is +largely achieved by greatly reducing the number of calls to :func:`os.stat` +required to walk a directory tree. + +Additionally, ``scandir`` returns an iterator, as opposed to returning +a list of file names, which improves memory efficiency when iterating +over very large directories. + +The following example shows a simple use of :func:`os.scandir` to display all +the files (excluding directories) in the given *path* that don't start with +``'.'``. The :meth:`entry.is_file() <os.DirEntry.is_file>` call will generally +not make an additional system call:: + + for entry in os.scandir(path): + if not entry.name.startswith('.') and entry.is_file(): + print(entry.name) + +.. seealso:: + + :pep:`471` -- os.scandir() function -- a better and faster directory iterator + PEP written and implemented by Ben Hoyt with the help of Victor Stinner. + + +.. _whatsnew-pep-475: + +PEP 475: Retry system calls failing with EINTR +---------------------------------------------- + +A :py:data:`errno.EINTR` error code is returned whenever a system call, that +is waiting for I/O, is interrupted by a signal. Previously, Python would +raise :exc:`InterruptedError` in such case. This meant that, when writing a +Python application, the developer had two choices: + +#. Ignore the ``InterruptedError``. +#. Handle the ``InterruptedError`` and attempt to restart the interrupted + system call at every call site. + +The first option makes an application fail intermittently. +The second option adds a large amount of boilerplate that makes the +code nearly unreadable. Compare:: + + print("Hello World") + +and:: + + while True: + try: + print("Hello World") + break + except InterruptedError: + continue + +:pep:`475` implements automatic retry of system calls on +``EINTR``. This removes the burden of dealing with ``EINTR`` +or :exc:`InterruptedError` in user code in most situations and makes +Python programs, including the standard library, more robust. Note that +the system call is only retried if the signal handler does not raise an +exception. + +Below is a list of functions which are now retried when interrupted +by a signal: + +* :func:`open` and :func:`io.open`; + +* functions of the :mod:`faulthandler` module; + +* :mod:`os` functions: :func:`~os.fchdir`, :func:`~os.fchmod`, + :func:`~os.fchown`, :func:`~os.fdatasync`, :func:`~os.fstat`, + :func:`~os.fstatvfs`, :func:`~os.fsync`, :func:`~os.ftruncate`, + :func:`~os.mkfifo`, :func:`~os.mknod`, :func:`~os.open`, + :func:`~os.posix_fadvise`, :func:`~os.posix_fallocate`, :func:`~os.pread`, + :func:`~os.pwrite`, :func:`~os.read`, :func:`~os.readv`, :func:`~os.sendfile`, + :func:`~os.wait3`, :func:`~os.wait4`, :func:`~os.wait`, + :func:`~os.waitid`, :func:`~os.waitpid`, :func:`~os.write`, + :func:`~os.writev`; + +* special cases: :func:`os.close` and :func:`os.dup2` now ignore + :py:data:`~errno.EINTR` error, the syscall is not retried (see the PEP + for the rationale); + +* :mod:`select` functions: :func:`devpoll.poll() <select.devpoll.poll>`, + :func:`epoll.poll() <select.epoll.poll>`, + :func:`kqueue.control() <select.kqueue.control>`, + :func:`poll.poll() <select.poll.poll>`, :func:`~select.select`; + +* methods of the :class:`~socket.socket` class: :meth:`~socket.socket.accept`, + :meth:`~socket.socket.connect` (except for non-blocking sockets), + :meth:`~socket.socket.recv`, :meth:`~socket.socket.recvfrom`, + :meth:`~socket.socket.recvmsg`, :meth:`~socket.socket.send`, + :meth:`~socket.socket.sendall`, :meth:`~socket.socket.sendmsg`, + :meth:`~socket.socket.sendto`; + +* :func:`signal.sigtimedwait` and :func:`signal.sigwaitinfo`; + +* :func:`time.sleep`. + +.. seealso:: + + :pep:`475` -- Retry system calls failing with EINTR + PEP and implementation written by Charles-François Natali and + Victor Stinner, with the help of Antoine Pitrou (the French connection). + + +.. _whatsnew-pep-479: + +PEP 479: Change StopIteration handling inside generators +-------------------------------------------------------- + +The interaction of generators and :exc:`StopIteration` in Python 3.4 and +earlier was sometimes surprising, and could conceal obscure bugs. Previously, +``StopIteration`` raised accidentally inside a generator function was +interpreted as the end of the iteration by the loop construct driving the +generator. + +:pep:`479` changes the behavior of generators: when a ``StopIteration`` +exception is raised inside a generator, it is replaced with a +:exc:`RuntimeError` before it exits the generator frame. The main goal of +this change is to ease debugging in the situation where an unguarded +:func:`next` call raises ``StopIteration`` and causes the iteration controlled +by the generator to terminate silently. This is particularly pernicious in +combination with the ``yield from`` construct. + +This is a backwards incompatible change, so to enable the new behavior, +a :term:`__future__` import is necessary:: + + >>> from __future__ import generator_stop + + >>> def gen(): + ... next(iter([])) + ... yield + ... + >>> next(gen()) + Traceback (most recent call last): + File "<stdin>", line 2, in gen + StopIteration + + The above exception was the direct cause of the following exception: + + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + RuntimeError: generator raised StopIteration + +Without a ``__future__`` import, a :exc:`PendingDeprecationWarning` will be +raised whenever a ``StopIteration`` exception is raised inside a generator. + +.. seealso:: + + :pep:`479` -- Change StopIteration handling inside generators + PEP written by Chris Angelico and Guido van Rossum. Implemented by + Chris Angelico, Yury Selivanov and Nick Coghlan. + + +.. _whatsnew-pep-485: + +PEP 485: A function for testing approximate equality +---------------------------------------------------- + +:pep:`485` adds the :func:`math.isclose` and :func:`cmath.isclose` +functions which tell whether two values are approximately equal or +"close" to each other. Whether or not two values are considered +close is determined according to given absolute and relative tolerances. +Relative tolerance is the maximum allowed difference between ``isclose`` +arguments, relative to the larger absolute value:: + + >>> import math + >>> a = 5.0 + >>> b = 4.99998 + >>> math.isclose(a, b, rel_tol=1e-5) + True + >>> math.isclose(a, b, rel_tol=1e-6) + False + +It is also possible to compare two values using absolute tolerance, which +must be a non-negative value:: + + >>> import math + >>> a = 5.0 + >>> b = 4.99998 + >>> math.isclose(a, b, abs_tol=0.00003) + True + >>> math.isclose(a, b, abs_tol=0.00001) + False + +.. seealso:: + + :pep:`485` -- A function for testing approximate equality + PEP written by Christopher Barker; implemented by Chris Barker and + Tal Einat. + + +.. _whatsnew-pep-486: + +PEP 486: Make the Python Launcher aware of virtual environments +--------------------------------------------------------------- + +:pep:`486` makes the Windows launcher (see :pep:`397`) aware of an active +virtual environment. When the default interpreter would be used and the +``VIRTUAL_ENV`` environment variable is set, the interpreter in the virtual +environment will be used. + +.. seealso:: + + :pep:`486` -- Make the Python Launcher aware of virtual environments + PEP written and implemented by Paul Moore. + + +.. _whatsnew-pep-488: + +PEP 488: Elimination of PYO files +--------------------------------- + +:pep:`488` does away with the concept of ``.pyo`` files. This means that +``.pyc`` files represent both unoptimized and optimized bytecode. To prevent the +need to constantly regenerate bytecode files, ``.pyc`` files now have an +optional ``opt-`` tag in their name when the bytecode is optimized. This has the +side-effect of no more bytecode file name clashes when running under either +:option:`-O` or :option:`-OO`. Consequently, bytecode files generated from +:option:`-O`, and :option:`-OO` may now exist simultaneously. +:func:`importlib.util.cache_from_source` has an updated API to help with +this change. + +.. seealso:: + + :pep:`488` -- Elimination of PYO files + PEP written and implemented by Brett Cannon. + + +.. _whatsnew-pep-489: + +PEP 489: Multi-phase extension module initialization +---------------------------------------------------- + +:pep:`489` updates extension module initialization to take advantage of the +two step module loading mechanism introduced by :pep:`451` in Python 3.4. + +This change brings the import semantics of extension modules that opt-in to +using the new mechanism much closer to those of Python source and bytecode +modules, including the ability to use any valid identifier as a module name, +rather than being restricted to ASCII. + +.. seealso:: + + :pep:`489` -- Multi-phase extension module initialization + PEP written by Petr Viktorin, Stefan Behnel, and Nick Coghlan; + implemented by Petr Viktorin. + + +Other Language Changes +====================== + +Some smaller changes made to the core Python language are: + +* Added the ``"namereplace"`` error handlers. The ``"backslashreplace"`` + error handlers now work with decoding and translating. + (Contributed by Serhiy Storchaka in :issue:`19676` and :issue:`22286`.) + +* The :option:`-b` option now affects comparisons of :class:`bytes` with + :class:`int`. (Contributed by Serhiy Storchaka in :issue:`23681`.) + +* New Kazakh ``kz1048`` and Tajik ``koi8_t`` :ref:`codecs <standard-encodings>`. + (Contributed by Serhiy Storchaka in :issue:`22682` and :issue:`22681`.) + +* Property docstrings are now writable. This is especially useful for + :func:`collections.namedtuple` docstrings. + (Contributed by Berker Peksag in :issue:`24064`.) + +* Circular imports involving relative imports are now supported. + (Contributed by Brett Cannon and Antoine Pitrou in :issue:`17636`.) + + +New Modules +=========== + +typing +------ + +The new :mod:`typing` :term:`provisional <provisional api>` module +provides standard definitions and tools for function type annotations. +See :ref:`Type Hints <whatsnew-pep-484>` for more information. + +.. _whatsnew-zipapp: + +zipapp +------ + +The new :mod:`zipapp` module (specified in :pep:`441`) provides an API and +command line tool for creating executable Python Zip Applications, which +were introduced in Python 2.6 in :issue:`1739468`, but which were not well +publicized, either at the time or since. + +With the new module, bundling your application is as simple as putting all +the files, including a ``__main__.py`` file, into a directory ``myapp`` +and running:: + + $ python -m zipapp myapp + $ python myapp.pyz + +The module implementation has been contributed by Paul Moore in +:issue:`23491`. + +.. seealso:: + + :pep:`441` -- Improving Python ZIP Application Support + + +Improved Modules +================ + +argparse +-------- + +The :class:`~argparse.ArgumentParser` class now allows to disable +:ref:`abbreviated usage <prefix-matching>` of long options by setting +:ref:`allow_abbrev` to ``False``. (Contributed by Jonathan Paugh, +Steven Bethard, paul j3 and Daniel Eriksson in :issue:`14910`.) + + +asyncio +------- + +Since :mod:`asyncio` module is :term:`provisional <provisional api>`, +all changes introduced in Python 3.5 have also been backported to Python 3.4.x. + +Notable changes in the :mod:`asyncio` module since Python 3.4.0: + +* New debugging APIs: :meth:`loop.set_debug() <asyncio.BaseEventLoop.set_debug>` + and :meth:`loop.get_debug() <asyncio.BaseEventLoop.get_debug>` methods. + (Contributed by Victor Stinner.) + +* The proactor event loop now supports SSL. + (Contributed by Antoine Pitrou and Victor Stinner in :issue:`22560`.) + +* A new :meth:`loop.is_closed() <asyncio.BaseEventLoop.is_closed>` method to + check if the event loop is closed. + (Contributed by Victor Stinner in :issue:`21326`.) + +* A new :meth:`loop.create_task() <asyncio.BaseEventLoop.create_task>` + to conveniently create and schedule a new :class:`~asyncio.Task` + for a coroutine. The ``create_task`` method is also used by all + asyncio functions that wrap coroutines into tasks, such as + :func:`asyncio.wait`, :func:`asyncio.gather`, etc. + (Contributed by Victor Stinner.) + +* A new :meth:`transport.get_write_buffer_limits() <asyncio.WriteTransport.get_write_buffer_limits>` + method to inquire for *high-* and *low-* water limits of the flow + control. + (Contributed by Victor Stinner.) + +* The :func:`~asyncio.async` function is deprecated in favor of + :func:`~asyncio.ensure_future`. + (Contributed by Yury Selivanov.) + +* New :meth:`loop.set_task_factory() <asyncio.BaseEventLoop.set_task_factory>` + and :meth:`loop.set_task_factory() <asyncio.BaseEventLoop.get_task_factory>` + methods to customize the task factory that + :meth:`loop.create_task() <asyncio.BaseEventLoop.create_task>` method uses. + (Contributed by Yury Selivanov.) + +* New :meth:`Queue.join() <asyncio.Queue.join>` and + :meth:`Queue.task_done() <asyncio.Queue.task_done>` queue methods. + (Contributed by Victor Stinner.) + +* The ``JoinableQueue`` class was removed, in favor of the + :class:`asyncio.Queue` class. + (Contributed by Victor Stinner.) + +Updates in 3.5.1: + +* The :func:`~asyncio.ensure_future` function and all functions that + use it, such as :meth:`loop.run_until_complete() <asyncio.BaseEventLoop.run_until_complete>`, + now accept all kinds of :term:`awaitable objects <awaitable>`. + (Contributed by Yury Selivanov.) + + +bz2 +--- + +The :meth:`BZ2Decompressor.decompress <bz2.BZ2Decompressor.decompress>` +method now accepts an optional *max_length* argument to limit the maximum +size of decompressed data. (Contributed by Nikolaus Rath in :issue:`15955`.) + + +cgi +--- + +The :class:`~cgi.FieldStorage` class now supports the :term:`context manager` +protocol. (Contributed by Berker Peksag in :issue:`20289`.) + + +cmath +----- + +A new function :func:`~cmath.isclose` provides a way to test for approximate +equality. (Contributed by Chris Barker and Tal Einat in :issue:`24270`.) + + +code +---- + +The :func:`InteractiveInterpreter.showtraceback() <code.InteractiveInterpreter.showtraceback>` +method now prints the full chained traceback, just like the interactive +interpreter. (Contributed by Claudiu Popa in :issue:`17442`.) + + +collections +----------- + +.. _whatsnew-ordereddict: + +The :class:`~collections.OrderedDict` class is now implemented in C, which +makes it 4 to 100 times faster. (Contributed by Eric Snow in :issue:`16991`.) + +:meth:`OrderedDict.items() <collections.OrderedDict.items>`, +:meth:`OrderedDict.keys() <collections.OrderedDict.keys>`, +:meth:`OrderedDict.values() <collections.OrderedDict.values>` views now support +:func:`reversed` iteration. +(Contributed by Serhiy Storchaka in :issue:`19505`.) + +The :class:`~collections.deque` class now defines +:meth:`~collections.deque.index`, :meth:`~collections.deque.insert`, and +:meth:`~collections.deque.copy`, as well as supports ``+`` and ``*`` operators. +This allows deques to be recognized as a :class:`~collections.abc.MutableSequence` +and improves their substitutability for lists. +(Contributed by Raymond Hettinger :issue:`23704`.) + +Docstrings produced by :func:`~collections.namedtuple` can now be updated:: + + Point = namedtuple('Point', ['x', 'y']) + Point.__doc__ = 'ordered pair' + Point.x.__doc__ = 'abscissa' + Point.y.__doc__ = 'ordinate' + +(Contributed by Berker Peksag in :issue:`24064`.) + +The :class:`~collections.UserString` class now implements +:meth:`__getnewargs__`, :meth:`__rmod__`, :meth:`~str.casefold`, +:meth:`~str.format_map`, :meth:`~str.isprintable`, and :meth:`~str.maketrans` +methods to match the corresponding methods of :class:`str`. +(Contributed by Joe Jevnik in :issue:`22189`.) + + +collections.abc +--------------- + +The :meth:`Sequence.index() <collections.abc.Sequence.index>` method now +accepts *start* and *stop* arguments to match the corresponding methods +of :class:`tuple`, :class:`list`, etc. +(Contributed by Devin Jeanpierre in :issue:`23086`.) + +A new :class:`~collections.abc.Generator` abstract base class. (Contributed +by Stefan Behnel in :issue:`24018`.) + +New :class:`~collections.abc.Awaitable` :class:`~collections.abc.Coroutine`, +:class:`~collections.abc.AsyncIterator`, and +:class:`~collections.abc.AsyncIterable` abstract base classes. +(Contributed by Yury Selivanov in :issue:`24184`.) + +For earlier Python versions, a backport of the new ABCs is available in an +external `PyPI package <https://pypi.python.org/pypi/backports_abc>`_. + + +compileall +---------- + +A new :mod:`compileall` option, :samp:`-j {N}`, allows to run *N* workers +sumultaneously to perform parallel bytecode compilation. +The :func:`~compileall.compile_dir` function has a corresponding ``workers`` +parameter. (Contributed by Claudiu Popa in :issue:`16104`.) + +Another new option, ``-r``, allows to control the maximum recursion +level for subdirectories. (Contributed by Claudiu Popa in :issue:`19628`.) + +The ``-q`` command line option can now be specified more than once, in +which case all output, including errors, will be suppressed. The corresponding +``quiet`` parameter in :func:`~compileall.compile_dir`, +:func:`~compileall.compile_file`, and :func:`~compileall.compile_path` can now +accept an integer value indicating the level of output suppression. +(Contributed by Thomas Kluyver in :issue:`21338`.) + + +concurrent.futures +------------------ + +The :meth:`Executor.map() <concurrent.futures.Executor.map>` method now accepts a +*chunksize* argument to allow batching of tasks to improve performance when +:meth:`~concurrent.futures.ProcessPoolExecutor` is used. +(Contributed by Dan O'Reilly in :issue:`11271`.) + +A number of workers in :class:`~concurrent.futures.ThreadPoolExecutor` constructor is +optional now. The default value equals to 5 times the number of CPUs. +(Contributed by Claudiu Popa in :issue:`21527`.) + + +configparser +------------ + +:mod:`configparser` now provides a way to customize the conversion +of values by specifying a dictionary of converters in +:class:`~configparser.ConfigParser` constructor, or by defining them +as methods in ``ConfigParser`` subclasses. Converters defined in +parser instance are inherited by its section proxies. + +Example:: + + >>> import configparser + >>> conv = {} + >>> conv['list'] = lambda v: [e.strip() for e in v.split() if e.strip()] + >>> cfg = configparser.ConfigParser(converters=conv) + >>> cfg.read_string(""" + ... [s] + ... list = a b c d e f g + ... """) + >>> cfg.get('s', 'list') + 'a b c d e f g' + >>> cfg.getlist('s', 'list') + ['a', 'b', 'c', 'd', 'e', 'f', 'g'] + >>> section = cfg['s'] + >>> section.getlist('list') + ['a', 'b', 'c', 'd', 'e', 'f', 'g'] + +(Contributed by Łukasz Langa in :issue:`18159`.) + + +contextlib +---------- + +The new :func:`~contextlib.redirect_stderr` :term:`context manager` (similar to +:func:`~contextlib.redirect_stdout`) makes it easier for utility scripts to +handle inflexible APIs that write their output to :data:`sys.stderr` and +don't provide any options to redirect it:: + + >>> import contextlib, io, logging + >>> f = io.StringIO() + >>> with contextlib.redirect_stderr(f): + ... logging.warning('warning') + ... + >>> f.getvalue() + 'WARNING:root:warning\n' + +(Contributed by Berker Peksag in :issue:`22389`.) + + +csv +--- + +The :meth:`~csv.csvwriter.writerow` method now supports arbitrary iterables, +not just sequences. (Contributed by Serhiy Storchaka in :issue:`23171`.) + + +curses +------ + +The new :func:`~curses.update_lines_cols` function updates :envvar:`LINES` +and :envvar:`COLS` environment variables. This is useful for detecting +manual screen resize. (Contributed by Arnon Yaari in :issue:`4254`.) + + +dbm +--- + +:func:`dumb.open <dbm.dumb.open>` always creates a new database when the flag +has the value ``"n"``. (Contributed by Claudiu Popa in :issue:`18039`.) + + +difflib +------- + +The charset of HTML documents generated by +:meth:`HtmlDiff.make_file() <difflib.HtmlDiff.make_file>` +can now be customized by using a new *charset* keyword-only argument. +The default charset of HTML document changed from ``"ISO-8859-1"`` +to ``"utf-8"``. +(Contributed by Berker Peksag in :issue:`2052`.) + +The :func:`~difflib.diff_bytes` function can now compare lists of byte +strings. This fixes a regression from Python 2. +(Contributed by Terry J. Reedy and Greg Ward in :issue:`17445`.) + + +distutils +--------- + +Both ``build`` and ``build_ext`` commands now accept a ``-j`` option to +enable parallel building of extension modules. +(Contributed by Antoine Pitrou in :issue:`5309`.) + +The :mod:`distutils` module now supports ``xz`` compression, and can be +enabled by passing ``xztar`` as an argument to ``bdist --format``. +(Contributed by Serhiy Storchaka in :issue:`16314`.) + + +doctest +------- + +The :func:`~doctest.DocTestSuite` function returns an empty +:class:`unittest.TestSuite` if *module* contains no docstrings instead of +raising :exc:`ValueError`. (Contributed by Glenn Jones in :issue:`15916`.) + + +email +----- + +A new policy option :attr:`Policy.mangle_from_ <email.policy.Policy.mangle_from_>` +controls whether or not lines that start with ``"From "`` in email bodies are +prefixed with a ``">"`` character by generators. The default is ``True`` for +:attr:`~email.policy.compat32` and ``False`` for all other policies. +(Contributed by Milan Oberkirch in :issue:`20098`.) + +A new +:meth:`Message.get_content_disposition() <email.message.Message.get_content_disposition>` +method provides easy access to a canonical value for the +:mailheader:`Content-Disposition` header. +(Contributed by Abhilash Raj in :issue:`21083`.) + +A new policy option :attr:`EmailPolicy.utf8 <email.policy.EmailPolicy.utf8>` +can be set to ``True`` to encode email headers using the UTF-8 charset instead +of using encoded words. This allows ``Messages`` to be formatted according to +:rfc:`6532` and used with an SMTP server that supports the :rfc:`6531` +``SMTPUTF8`` extension. (Contributed by R. David Murray in +:issue:`24211`.) + +The :class:`mime.text.MIMEText <email.mime.text.MIMEText>` constructor now +accepts a :class:`charset.Charset <email.charset.Charset>` instance. +(Contributed by Claude Paroz and Berker Peksag in :issue:`16324`.) + + +enum +---- + +The :class:`~enum.Enum` callable has a new parameter *start* to +specify the initial number of enum values if only *names* are provided:: + + >>> Animal = enum.Enum('Animal', 'cat dog', start=10) + >>> Animal.cat + <Animal.cat: 10> + >>> Animal.dog + <Animal.dog: 11> + +(Contributed by Ethan Furman in :issue:`21706`.) + + +faulthandler +------------ + +:func:`~faulthandler.enable`, :func:`~faulthandler.register`, +:func:`~faulthandler.dump_traceback` and +:func:`~faulthandler.dump_traceback_later` functions now accept file +descriptors in addition to file-like objects. +(Contributed by Wei Wu in :issue:`23566`.) + + +functools +--------- + +.. _whatsnew-lrucache: + +Most of :func:`~functools.lru_cache` machinery is now implemented in C, making +it significantly faster. (Contributed by Matt Joiner, Alexey Kachayev, and +Serhiy Storchaka in :issue:`14373`.) + + +glob +---- + +:func:`~glob.iglob` and :func:`~glob.glob` functions now support recursive +search in subdirectories using the ``"**"`` pattern. +(Contributed by Serhiy Storchaka in :issue:`13968`.) + + +gzip +---- + +The *mode* argument of :class:`~gzip.GzipFile` constructor now +accepts ``"x"`` to request exclusive creation. +(Contributed by Tim Heaney in :issue:`19222`.) + + +heapq +----- + +Element comparison in :func:`~heapq.merge` can now be customized by +passing a :term:`key function` in a new optional *key* keyword argument, +and a new optional *reverse* keyword argument can be used to reverse element +comparison:: + + >>> import heapq + >>> a = ['9', '777', '55555'] + >>> b = ['88', '6666'] + >>> list(heapq.merge(a, b, key=len)) + ['9', '88', '777', '6666', '55555'] + >>> list(heapq.merge(reversed(a), reversed(b), key=len, reverse=True)) + ['55555', '6666', '777', '88', '9'] + +(Contributed by Raymond Hettinger in :issue:`13742`.) + + +http +---- + +A new :class:`HTTPStatus <http.HTTPStatus>` enum that defines a set of +HTTP status codes, reason phrases and long descriptions written in English. +(Contributed by Demian Brecht in :issue:`21793`.) + + +http.client +----------- + +:meth:`HTTPConnection.getresponse() <http.client.HTTPConnection.getresponse>` +now raises a :exc:`~http.client.RemoteDisconnected` exception when a +remote server connection is closed unexpectedly. Additionally, if a +:exc:`ConnectionError` (of which ``RemoteDisconnected`` +is a subclass) is raised, the client socket is now closed automatically, +and will reconnect on the next request:: + + import http.client + conn = http.client.HTTPConnection('www.python.org') + for retries in range(3): + try: + conn.request('GET', '/') + resp = conn.getresponse() + except http.client.RemoteDisconnected: + pass + +(Contributed by Martin Panter in :issue:`3566`.) + + +idlelib and IDLE +---------------- + +Since idlelib implements the IDLE shell and editor and is not intended for +import by other programs, it gets improvements with every release. See +:file:`Lib/idlelib/NEWS.txt` for a cumulative list of changes since 3.4.0, +as well as changes made in future 3.5.x releases. This file is also available +from the IDLE :menuselection:`Help --> About IDLE` dialog. + + +imaplib +------- + +The :class:`~imaplib.IMAP4` class now supports :term:`context manager` protocol. +When used in a :keyword:`with` statement, the IMAP4 ``LOGOUT`` +command will be called automatically at the end of the block. +(Contributed by Tarek Ziadé and Serhiy Storchaka in :issue:`4972`.) + +The :mod:`imaplib` module now supports :rfc:`5161` (ENABLE Extension) +and :rfc:`6855` (UTF-8 Support) via the :meth:`IMAP4.enable() <imaplib.IMAP4.enable>` +method. A new :attr:`IMAP4.utf8_enabled <imaplib.IMAP4.utf8_enabled>` +attribute, tracks whether or not :rfc:`6855` support is enabled. +(Contributed by Milan Oberkirch, R. David Murray, and Maciej Szulik in +:issue:`21800`.) + +The :mod:`imaplib` module now automatically encodes non-ASCII string usernames +and passwords using UTF-8, as recommended by the RFCs. (Contributed by Milan +Oberkirch in :issue:`21800`.) + + +imghdr +------ + +The :func:`~imghdr.what` function now recognizes the +`OpenEXR <http://www.openexr.com>`_ format +(contributed by Martin Vignali and Claudiu Popa in :issue:`20295`), +and the `WebP <https://en.wikipedia.org/wiki/WebP>`_ format +(contributed by Fabrice Aneche and Claudiu Popa in :issue:`20197`.) + + +importlib +--------- + +The :class:`util.LazyLoader <importlib.util.LazyLoader>` class allows for +lazy loading of modules in applications where startup time is important. +(Contributed by Brett Cannon in :issue:`17621`.) + +The :func:`abc.InspectLoader.source_to_code() <importlib.abc.InspectLoader.source_to_code>` +method is now a static method. This makes it easier to initialize a module +object with code compiled from a string by running +``exec(code, module.__dict__)``. +(Contributed by Brett Cannon in :issue:`21156`.) + +The new :func:`util.module_from_spec() <importlib.util.module_from_spec>` +function is now the preferred way to create a new module. As opposed to +creating a :class:`types.ModuleType` instance directly, this new function +will set the various import-controlled attributes based on the passed-in +spec object. (Contributed by Brett Cannon in :issue:`20383`.) + + +inspect +------- + +Both :class:`~inspect.Signature` and :class:`~inspect.Parameter` classes are +now picklable and hashable. (Contributed by Yury Selivanov in :issue:`20726` +and :issue:`20334`.) + +A new +:meth:`BoundArguments.apply_defaults() <inspect.BoundArguments.apply_defaults>` +method provides a way to set default values for missing arguments:: + + >>> def foo(a, b='ham', *args): pass + >>> ba = inspect.signature(foo).bind('spam') + >>> ba.apply_defaults() + >>> ba.arguments + OrderedDict([('a', 'spam'), ('b', 'ham'), ('args', ())]) + +(Contributed by Yury Selivanov in :issue:`24190`.) + +A new class method +:meth:`Signature.from_callable() <inspect.Signature.from_callable>` makes +subclassing of :class:`~inspect.Signature` easier. (Contributed +by Yury Selivanov and Eric Snow in :issue:`17373`.) + +The :func:`~inspect.signature` function now accepts a *follow_wrapped* +optional keyword argument, which, when set to ``False``, disables automatic +following of ``__wrapped__`` links. +(Contributed by Yury Selivanov in :issue:`20691`.) + +A set of new functions to inspect +:term:`coroutine functions <coroutine function>` and +:term:`coroutine objects <coroutine>` has been added: +:func:`~inspect.iscoroutine`, :func:`~inspect.iscoroutinefunction`, +:func:`~inspect.isawaitable`, :func:`~inspect.getcoroutinelocals`, +and :func:`~inspect.getcoroutinestate`. +(Contributed by Yury Selivanov in :issue:`24017` and :issue:`24400`.) + +:func:`~inspect.stack`, :func:`~inspect.trace`, +:func:`~inspect.getouterframes`, and :func:`~inspect.getinnerframes` +functions now return a list of named tuples. +(Contributed by Daniel Shahaf in :issue:`16808`.) + + +io +-- + +A new :meth:`BufferedIOBase.readinto1() <io.BufferedIOBase.readinto1>` +method, that uses at most one call to the underlying raw stream's +:meth:`RawIOBase.read() <io.RawIOBase.read>` or +:meth:`RawIOBase.readinto() <io.RawIOBase.readinto>` methods. +(Contributed by Nikolaus Rath in :issue:`20578`.) + + +ipaddress +--------- + +Both :class:`~ipaddress.IPv4Network` and :class:`~ipaddress.IPv6Network` classes +now accept an ``(address, netmask)`` tuple argument, so as to easily construct +network objects from existing addresses:: + + >>> import ipaddress + >>> ipaddress.IPv4Network(('127.0.0.0', 8)) + IPv4Network('127.0.0.0/8') + >>> ipaddress.IPv4Network(('127.0.0.0', '255.0.0.0')) + IPv4Network('127.0.0.0/8') + +(Contributed by Peter Moody and Antoine Pitrou in :issue:`16531`.) + +A new :attr:`~ipaddress.IPv4Network.reverse_pointer` attribute for +:class:`~ipaddress.IPv4Network` and :class:`~ipaddress.IPv6Network` classes +returns the name of the reverse DNS PTR record:: + + >>> import ipaddress + >>> addr = ipaddress.IPv4Address('127.0.0.1') + >>> addr.reverse_pointer + '1.0.0.127.in-addr.arpa' + >>> addr6 = ipaddress.IPv6Address('::1') + >>> addr6.reverse_pointer + '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.ip6.arpa' + +(Contributed by Leon Weber in :issue:`20480`.) + + +json +---- + +The :mod:`json.tool` command line interface now preserves the order of keys in +JSON objects passed in input. The new ``--sort-keys`` option can be used +to sort the keys alphabetically. (Contributed by Berker Peksag +in :issue:`21650`.) + +JSON decoder now raises :exc:`~json.JSONDecodeError` instead of +:exc:`ValueError` to provide better context information about the error. +(Contributed by Serhiy Storchaka in :issue:`19361`.) + + +linecache +--------- + +A new :func:`~linecache.lazycache` function can be used to capture information +about a non-file based module to permit getting its lines later via +:func:`~linecache.getline`. This avoids doing I/O until a line is actually +needed, without having to carry the module globals around indefinitely. +(Contributed by Robert Collins in :issue:`17911`.) + + +locale +------ + +A new :func:`~locale.delocalize` function can be used to convert a string into +a normalized number string, taking the ``LC_NUMERIC`` settings into account:: + + >>> import locale + >>> locale.setlocale(locale.LC_NUMERIC, 'de_DE.UTF-8') + 'de_DE.UTF-8' + >>> locale.delocalize('1.234,56') + '1234.56' + >>> locale.setlocale(locale.LC_NUMERIC, 'en_US.UTF-8') + 'en_US.UTF-8' + >>> locale.delocalize('1,234.56') + '1234.56' + +(Contributed by Cédric Krier in :issue:`13918`.) + + +logging +------- + +All logging methods (:class:`~logging.Logger` :meth:`~logging.Logger.log`, +:meth:`~logging.Logger.exception`, :meth:`~logging.Logger.critical`, +:meth:`~logging.Logger.debug`, etc.), now accept exception instances +as an *exc_info* argument, in addition to boolean values and exception +tuples:: + + >>> import logging + >>> try: + ... 1/0 + ... except ZeroDivisionError as ex: + ... logging.error('exception', exc_info=ex) + ERROR:root:exception + +(Contributed by Yury Selivanov in :issue:`20537`.) + +The :class:`handlers.HTTPHandler <logging.handlers.HTTPHandler>` class now +accepts an optional :class:`ssl.SSLContext` instance to configure SSL +settings used in an HTTP connection. +(Contributed by Alex Gaynor in :issue:`22788`.) + +The :class:`handlers.QueueListener <logging.handlers.QueueListener>` class now +takes a *respect_handler_level* keyword argument which, if set to ``True``, +will pass messages to handlers taking handler levels into account. +(Contributed by Vinay Sajip.) + + +lzma +---- + +The :meth:`LZMADecompressor.decompress() <lzma.LZMADecompressor.decompress>` +method now accepts an optional *max_length* argument to limit the maximum +size of decompressed data. +(Contributed by Martin Panter in :issue:`15955`.) + + +math +---- + +Two new constants have been added to the :mod:`math` module: :data:`~math.inf` +and :data:`~math.nan`. (Contributed by Mark Dickinson in :issue:`23185`.) + +A new function :func:`~math.isclose` provides a way to test for approximate +equality. (Contributed by Chris Barker and Tal Einat in :issue:`24270`.) + +A new :func:`~math.gcd` function has been added. The :func:`fractions.gcd` +function is now deprecated. (Contributed by Mark Dickinson and Serhiy +Storchaka in :issue:`22486`.) + + +multiprocessing +--------------- + +:func:`sharedctypes.synchronized() <multiprocessing.sharedctypes.synchronized>` +objects now support the :term:`context manager` protocol. +(Contributed by Charles-François Natali in :issue:`21565`.) + + +operator +-------- + +:func:`~operator.attrgetter`, :func:`~operator.itemgetter`, +and :func:`~operator.methodcaller` objects now support pickling. +(Contributed by Josh Rosenberg and Serhiy Storchaka in :issue:`22955`.) + +New :func:`~operator.matmul` and :func:`~operator.imatmul` functions +to perform matrix multiplication. +(Contributed by Benjamin Peterson in :issue:`21176`.) + + +os +-- + +The new :func:`~os.scandir` function returning an iterator of +:class:`~os.DirEntry` objects has been added. If possible, :func:`~os.scandir` +extracts file attributes while scanning a directory, removing the need to +perform subsequent system calls to determine file type or attributes, which may +significantly improve performance. (Contributed by Ben Hoyt with the help +of Victor Stinner in :issue:`22524`.) + +On Windows, a new +:attr:`stat_result.st_file_attributes <os.stat_result.st_file_attributes>` +attribute is now available. It corresponds to the ``dwFileAttributes`` member +of the ``BY_HANDLE_FILE_INFORMATION`` structure returned by +``GetFileInformationByHandle()``. (Contributed by Ben Hoyt in :issue:`21719`.) + +The :func:`~os.urandom` function now uses ``getrandom()`` syscall on Linux 3.17 +or newer, and ``getentropy()`` on OpenBSD 5.6 and newer, removing the need to +use ``/dev/urandom`` and avoiding failures due to potential file descriptor +exhaustion. (Contributed by Victor Stinner in :issue:`22181`.) + +New :func:`~os.get_blocking` and :func:`~os.set_blocking` functions allow to +get and set a file descriptor blocking mode (:data:`~os.O_NONBLOCK`.) +(Contributed by Victor Stinner in :issue:`22054`.) + +The :func:`~os.truncate` and :func:`~os.ftruncate` functions are now supported +on Windows. (Contributed by Steve Dower in :issue:`23668`.) + +There is a new :func:`os.path.commonpath` function returning the longest +common sub-path of each passed pathname. Unlike the +:func:`os.path.commonprefix` function, it always returns a valid +path:: + + >>> os.path.commonprefix(['/usr/lib', '/usr/local/lib']) + '/usr/l' + + >>> os.path.commonpath(['/usr/lib', '/usr/local/lib']) + '/usr' + +(Contributed by Rafik Draoui and Serhiy Storchaka in :issue:`10395`.) + + +pathlib +------- + +The new :meth:`Path.samefile() <pathlib.Path.samefile>` method can be used +to check whether the path points to the same file as other path, which can be +either an another :class:`~pathlib.Path` object, or a string:: + + >>> import pathlib + >>> p1 = pathlib.Path('/etc/hosts') + >>> p2 = pathlib.Path('/etc/../etc/hosts') + >>> p1.samefile(p2) + True + +(Contributed by Vajrasky Kok and Antoine Pitrou in :issue:`19775`.) + +The :meth:`Path.mkdir() <pathlib.Path.mkdir>` method now accepts a new optional +*exist_ok* argument to match ``mkdir -p`` and :func:`os.makedirs` +functionality. (Contributed by Berker Peksag in :issue:`21539`.) + +There is a new :meth:`Path.expanduser() <pathlib.Path.expanduser>` method to +expand ``~`` and ``~user`` prefixes. (Contributed by Serhiy Storchaka and +Claudiu Popa in :issue:`19776`.) + +A new :meth:`Path.home() <pathlib.Path.home>` class method can be used to get +an instance of :class:`~pathlib.Path` object representing the user’s home +directory. +(Contributed by Victor Salgado and Mayank Tripathi in :issue:`19777`.) + +New :meth:`Path.write_text() <pathlib.Path.write_text>`, +:meth:`Path.read_text() <pathlib.Path.read_text>`, +:meth:`Path.write_bytes() <pathlib.Path.write_bytes>`, +:meth:`Path.read_bytes() <pathlib.Path.read_bytes>` methods to simplify +read/write operations on files. + +The following code snippet will create or rewrite existing file +``~/spam42``:: + + >>> import pathlib + >>> p = pathlib.Path('~/spam42') + >>> p.expanduser().write_text('ham') + 3 + +(Contributed by Christopher Welborn in :issue:`20218`.) + + +pickle +------ + +Nested objects, such as unbound methods or nested classes, can now be pickled +using :ref:`pickle protocols <pickle-protocols>` older than protocol version 4. +Protocol version 4 already supports these cases. (Contributed by Serhiy +Storchaka in :issue:`23611`.) + + +poplib +------ + +A new :meth:`POP3.utf8() <poplib.POP3.utf8>` command enables :rfc:`6856` +(Internationalized Email) support, if a POP server supports it. +(Contributed by Milan OberKirch in :issue:`21804`.) + + +re +-- + +References and conditional references to groups with fixed length are now +allowed in lookbehind assertions:: + + >>> import re + >>> pat = re.compile(r'(a|b).(?<=\1)c') + >>> pat.match('aac') + <_sre.SRE_Match object; span=(0, 3), match='aac'> + >>> pat.match('bbc') + <_sre.SRE_Match object; span=(0, 3), match='bbc'> + +(Contributed by Serhiy Storchaka in :issue:`9179`.) + +The number of capturing groups in regular expression is no longer limited by +100. (Contributed by Serhiy Storchaka in :issue:`22437`.) + +The :func:`~re.sub` and :func:`~re.subn` functions now replace unmatched +groups with empty strings instead of raising an exception. +(Contributed by Serhiy Storchaka in :issue:`1519638`.) + +The :class:`re.error` exceptions have new attributes: +:attr:`~re.error.msg`, :attr:`~re.error.pattern`, +:attr:`~re.error.pos`, :attr:`~re.error.lineno`, +and :attr:`~re.error.colno` that provide better context +information about the error:: + + >>> re.compile(""" + ... (?x) + ... .++ + ... """) + Traceback (most recent call last): + ... + sre_constants.error: multiple repeat at position 16 (line 3, column 7) + +(Contributed by Serhiy Storchaka in :issue:`22578`.) + + +readline +-------- + +A new :func:`~readline.append_history_file` function can be used to append +the specified number of trailing elements in history to the given file. +(Contributed by Bruno Cauet in :issue:`22940`.) + + +selectors +--------- + +The new :class:`~selectors.DevpollSelector` supports efficient +``/dev/poll`` polling on Solaris. +(Contributed by Giampaolo Rodola' in :issue:`18931`.) + + +shutil +------ + +The :func:`~shutil.move` function now accepts a *copy_function* argument, +allowing, for example, the :func:`~shutil.copy` function to be used instead of +the default :func:`~shutil.copy2` if there is a need to ignore file metadata +when moving. +(Contributed by Claudiu Popa in :issue:`19840`.) + +The :func:`~shutil.make_archive` function now supports the *xztar* format. +(Contributed by Serhiy Storchaka in :issue:`5411`.) + + +signal +------ + +On Windows, the :func:`~signal.set_wakeup_fd` function now also supports +socket handles. (Contributed by Victor Stinner in :issue:`22018`.) + +Various ``SIG*`` constants in the :mod:`signal` module have been converted into +:mod:`Enums <enum>`. This allows meaningful names to be printed +during debugging, instead of integer "magic numbers". +(Contributed by Giampaolo Rodola' in :issue:`21076`.) + + +smtpd +----- + +Both :class:`~smtpd.SMTPServer` and :class:`~smtpd.SMTPChannel` classes now +accept a *decode_data* keyword argument to determine if the ``DATA`` portion of +the SMTP transaction is decoded using the ``"utf-8"`` codec or is instead +provided to the +:meth:`SMTPServer.process_message() <smtpd.SMTPServer.process_message>` +method as a byte string. The default is ``True`` for backward compatibility +reasons, but will change to ``False`` in Python 3.6. If *decode_data* is set +to ``False``, the ``process_message`` method must be prepared to accept keyword +arguments. +(Contributed by Maciej Szulik in :issue:`19662`.) + +The :class:`~smtpd.SMTPServer` class now advertises the ``8BITMIME`` extension +(:rfc:`6152`) if *decode_data* has been set ``True``. If the client +specifies ``BODY=8BITMIME`` on the ``MAIL`` command, it is passed to +:meth:`SMTPServer.process_message() <smtpd.SMTPServer.process_message>` +via the *mail_options* keyword. +(Contributed by Milan Oberkirch and R. David Murray in :issue:`21795`.) + +The :class:`~smtpd.SMTPServer` class now also supports the ``SMTPUTF8`` +extension (:rfc:`6531`: Internationalized Email). If the client specified +``SMTPUTF8 BODY=8BITMIME`` on the ``MAIL`` command, they are passed to +:meth:`SMTPServer.process_message() <smtpd.SMTPServer.process_message>` +via the *mail_options* keyword. It is the responsibility of the +``process_message`` method to correctly handle the ``SMTPUTF8`` data. +(Contributed by Milan Oberkirch in :issue:`21725`.) + +It is now possible to provide, directly or via name resolution, IPv6 +addresses in the :class:`~smtpd.SMTPServer` constructor, and have it +successfully connect. (Contributed by Milan Oberkirch in :issue:`14758`.) + + +smtplib +------- + +A new :meth:`SMTP.auth() <smtplib.SMTP.auth>` method provides a convenient way to +implement custom authentication mechanisms. (Contributed by Milan +Oberkirch in :issue:`15014`.) + +The :meth:`SMTP.set_debuglevel() <smtplib.SMTP.set_debuglevel>` method now +accepts an additional debuglevel (2), which enables timestamps in debug +messages. (Contributed by Gavin Chappell and Maciej Szulik in :issue:`16914`.) + +Both :meth:`SMTP.sendmail() <smtplib.SMTP.sendmail>` and +:meth:`SMTP.send_message() <smtplib.SMTP.send_message>` methods now +support support :rfc:`6531` (SMTPUTF8). +(Contributed by Milan Oberkirch and R. David Murray in :issue:`22027`.) + + +sndhdr +------ + +:func:`~sndhdr.what` and :func:`~sndhdr.whathdr` functions now return +a :func:`~collections.namedtuple`. (Contributed by Claudiu Popa in +:issue:`18615`.) + + +socket +------ + +Functions with timeouts now use a monotonic clock, instead of a system clock. +(Contributed by Victor Stinner in :issue:`22043`.) + +A new :meth:`socket.sendfile() <socket.socket.sendfile>` method allows to +send a file over a socket by using the high-performance :func:`os.sendfile` +function on UNIX resulting in uploads being from 2 to 3 times faster than when +using plain :meth:`socket.send() <socket.socket.send>`. +(Contributed by Giampaolo Rodola' in :issue:`17552`.) + +The :meth:`socket.sendall() <socket.socket.sendall>` method no longer resets the +socket timeout every time bytes are received or sent. The socket timeout is +now the maximum total duration to send all data. +(Contributed by Victor Stinner in :issue:`23853`.) + +The *backlog* argument of the :meth:`socket.listen() <socket.socket.listen>` +method is now optional. By default it is set to +:data:`SOMAXCONN <socket.SOMAXCONN>` or to ``128`` whichever is less. +(Contributed by Charles-François Natali in :issue:`21455`.) + + +ssl +--- + +.. _whatsnew-sslmemorybio: + +Memory BIO Support +~~~~~~~~~~~~~~~~~~ + +(Contributed by Geert Jansen in :issue:`21965`.) + +The new :class:`~ssl.SSLObject` class has been added to provide SSL protocol +support for cases when the network I/O capabilities of :class:`~ssl.SSLSocket` +are not necessary or suboptimal. ``SSLObject`` represents +an SSL protocol instance, but does not implement any network I/O methods, and +instead provides a memory buffer interface. The new :class:`~ssl.MemoryBIO` +class can be used to pass data between Python and an SSL protocol instance. + +The memory BIO SSL support is primarily intended to be used in frameworks +implementing asynchronous I/O for which :class:`~ssl.SSLSocket`'s readiness +model ("select/poll") is inefficient. + +A new :meth:`SSLContext.wrap_bio() <ssl.SSLContext.wrap_bio>` method can be used +to create a new ``SSLObject`` instance. + + +Application-Layer Protocol Negotiation Support +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(Contributed by Benjamin Peterson in :issue:`20188`.) + +Where OpenSSL support is present, :mod:`ssl` module now implements +*Application-Layer Protocol Negotiation* TLS extension as described +in :rfc:`7301`. + +The new :meth:`SSLContext.set_alpn_protocols() <ssl.SSLContext.set_alpn_protocols>` +can be used to specify which protocols a socket should advertise during +the TLS handshake. + +The new +:meth:`SSLSocket.selected_alpn_protocol() <ssl.SSLSocket.selected_alpn_protocol>` +returns the protocol that was selected during the TLS handshake. +:data:`~ssl.HAS_ALPN` flag indicates whether APLN support is present. + + +Other Changes +~~~~~~~~~~~~~ + +There is a new :meth:`SSLSocket.version() <ssl.SSLSocket.version>` method to +query the actual protocol version in use. +(Contributed by Antoine Pitrou in :issue:`20421`.) + +The :class:`~ssl.SSLSocket` class now implements +a :meth:`SSLSocket.sendfile() <ssl.SSLSocket.sendfile>` method. +(Contributed by Giampaolo Rodola' in :issue:`17552`.) + +The :meth:`SSLSocket.send() <ssl.SSLSocket.send>` method now raises either +:exc:`ssl.SSLWantReadError` or :exc:`ssl.SSLWantWriteError` exception on a +non-blocking socket if the operation would block. Previously, it would return +``0``. (Contributed by Nikolaus Rath in :issue:`20951`.) + +The :func:`~ssl.cert_time_to_seconds` function now interprets the input time +as UTC and not as local time, per :rfc:`5280`. Additionally, the return +value is always an :class:`int`. (Contributed by Akira Li in :issue:`19940`.) + +New :meth:`SSLObject.shared_ciphers() <ssl.SSLObject.shared_ciphers>` and +:meth:`SSLSocket.shared_ciphers() <ssl.SSLSocket.shared_ciphers>` methods return +the list of ciphers sent by the client during the handshake. +(Contributed by Benjamin Peterson in :issue:`23186`.) + +The :meth:`SSLSocket.do_handshake() <ssl.SSLSocket.do_handshake>`, +:meth:`SSLSocket.read() <ssl.SSLSocket.read>`, +:meth:`SSLSocket.shutdown() <ssl.SSLSocket.shutdown>`, and +:meth:`SSLSocket.write() <ssl.SSLSocket.write>` methods of :class:`~ssl.SSLSocket` +class no longer reset the socket timeout every time bytes are received or sent. +The socket timeout is now the maximum total duration of the method. +(Contributed by Victor Stinner in :issue:`23853`.) + +The :func:`~ssl.match_hostname` function now supports matching of IP addresses. +(Contributed by Antoine Pitrou in :issue:`23239`.) + + +sqlite3 +------- + +The :class:`~sqlite3.Row` class now fully supports sequence protocol, +in particular :func:`reversed` iteration and slice indexing. +(Contributed by Claudiu Popa in :issue:`10203`; by Lucas Sinclair, +Jessica McKellar, and Serhiy Storchaka in :issue:`13583`.) + + +.. _whatsnew-subprocess: + +subprocess +---------- + +The new :func:`~subprocess.run` function has been added. +It runs the specified command and and returns a +:class:`~subprocess.CompletedProcess` object, which describes a finished +process. The new API is more consistent and is the recommended approach +to invoking subprocesses in Python code that does not need to maintain +compatibility with earlier Python versions. +(Contributed by Thomas Kluyver in :issue:`23342`.) + +Examples:: + + >>> subprocess.run(["ls", "-l"]) # doesn't capture output + CompletedProcess(args=['ls', '-l'], returncode=0) + + >>> subprocess.run("exit 1", shell=True, check=True) + Traceback (most recent call last): + ... + subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1 + + >>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE) + CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0, + stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n') + + +sys +--- + +A new :func:`~sys.set_coroutine_wrapper` function allows setting a global +hook that will be called whenever a :term:`coroutine object <coroutine>` +is created by an :keyword:`async def` function. A corresponding +:func:`~sys.get_coroutine_wrapper` can be used to obtain a currently set +wrapper. Both functions are :term:`provisional <provisional api>`, +and are intended for debugging purposes only. (Contributed by Yury Selivanov +in :issue:`24017`.) + +A new :func:`~sys.is_finalizing` function can be used to check if the Python +interpreter is :term:`shutting down <interpreter shutdown>`. +(Contributed by Antoine Pitrou in :issue:`22696`.) + + +sysconfig +--------- + +The name of the user scripts directory on Windows now includes the first +two components of Python version. (Contributed by Paul Moore +in :issue:`23437`.) + + +tarfile +------- + +The *mode* argument of the :func:`~tarfile.open` function now accepts ``"x"`` +to request exclusive creation. (Contributed by Berker Peksag in :issue:`21717`.) + +:meth:`TarFile.extractall() <tarfile.TarFile.extractall>` and +:meth:`TarFile.extract() <tarfile.TarFile.extract>` methods now take a keyword +argument *numeric_only*. If set to ``True``, the extracted files and +directories will be owned by the numeric ``uid`` and ``gid`` from the tarfile. +If set to ``False`` (the default, and the behavior in versions prior to 3.5), +they will be owned by the named user and group in the tarfile. +(Contributed by Michael Vogt and Eric Smith in :issue:`23193`.) + +The :meth:`TarFile.list() <tarfile.TarFile.list>` now accepts an optional +*members* keyword argument that can be set to a subset of the list returned +by :meth:`TarFile.getmembers() <tarfile.TarFile.getmembers>`. +(Contributed by Serhiy Storchaka in :issue:`21549`.) + + +threading +--------- + +Both :meth:`Lock.acquire() <threading.Lock.acquire>` and +:meth:`RLock.acquire() <threading.RLock.acquire>` methods +now use a monotonic clock for timeout management. +(Contributed by Victor Stinner in :issue:`22043`.) + + +time +---- + +The :func:`~time.monotonic` function is now always available. +(Contributed by Victor Stinner in :issue:`22043`.) + + +timeit +------ + +A new command line option ``-u`` or :samp:`--unit={U}` can be used to specify the time +unit for the timer output. Supported options are ``usec``, ``msec``, +or ``sec``. (Contributed by Julian Gindi in :issue:`18983`.) + +The :func:`~timeit.timeit` function has a new *globals* parameter for +specifying the namespace in which the code will be running. +(Contributed by Ben Roberts in :issue:`2527`.) + + +tkinter +------- + +The :mod:`tkinter._fix` module used for setting up the Tcl/Tk environment +on Windows has been replaced by a private function in the :mod:`_tkinter` +module which makes no permanent changes to environment variables. +(Contributed by Zachary Ware in :issue:`20035`.) + + +.. _whatsnew-traceback: + +traceback +--------- + +New :func:`~traceback.walk_stack` and :func:`~traceback.walk_tb` +functions to conveniently traverse frame and traceback objects. +(Contributed by Robert Collins in :issue:`17911`.) + +New lightweight classes: :class:`~traceback.TracebackException`, +:class:`~traceback.StackSummary`, and :class:`~traceback.FrameSummary`. +(Contributed by Robert Collins in :issue:`17911`.) + +Both :func:`~traceback.print_tb` and :func:`~traceback.print_stack` functions +now support negative values for the *limit* argument. +(Contributed by Dmitry Kazakov in :issue:`22619`.) + + +types +----- + +A new :func:`~types.coroutine` function to transform +:term:`generator <generator iterator>` and +:class:`generator-like <collections.abc.Generator>` objects into +:term:`awaitables <awaitable>`. +(Contributed by Yury Selivanov in :issue:`24017`.) + +A new :class:`~types.CoroutineType` is the type of :term:`coroutine` objects +created by :keyword:`async def` functions. +(Contributed by Yury Selivanov in :issue:`24400`.) + + +unicodedata +----------- + +The :mod:`unicodedata` module now uses data from `Unicode 8.0.0 +<http://unicode.org/versions/Unicode8.0.0/>`_. + + +unittest +-------- + +The :meth:`TestLoader.loadTestsFromModule() <unittest.TestLoader.loadTestsFromModule>` +method now accepts a keyword-only argument *pattern* which is passed to +``load_tests`` as the third argument. Found packages are now checked for +``load_tests`` regardless of whether their path matches *pattern*, because it +is impossible for a package name to match the default pattern. +(Contributed by Robert Collins and Barry A. Warsaw in :issue:`16662`.) + +Unittest discovery errors now are exposed in +:data:`TestLoader.errors <unittest.TestLoader.errors>` attribute of the +:class:`~unittest.TestLoader` instance. +(Contributed by Robert Collins in :issue:`19746`.) + +A new command line option ``--locals`` to show local variables in +tracebacks. (Contributed by Robert Collins in :issue:`22936`.) + + +unittest.mock +------------- + +The :class:`~unittest.mock.Mock` class has the following improvements: + +* Class constructor has a new *unsafe* parameter, which causes mock + objects to raise :exc:`AttributeError` on attribute names starting + with ``"assert"``. + (Contributed by Kushal Das in :issue:`21238`.) + +* A new :meth:`Mock.assert_not_called() <unittest.mock.Mock.assert_not_called>` + method to check if the mock object was called. + (Contributed by Kushal Das in :issue:`21262`.) + +The :class:`~unittest.mock.MagicMock` class now supports :meth:`__truediv__`, +:meth:`__divmod__` and :meth:`__matmul__` operators. +(Contributed by Johannes Baiter in :issue:`20968`, and Håkan Lövdahl +in :issue:`23581` and :issue:`23568`.) + +It is no longer necessary to explicitly pass ``create=True`` to the +:func:`~unittest.mock.patch` function when patching builtin names. +(Contributed by Kushal Das in :issue:`17660`.) + + +urllib +------ + +A new +:class:`request.HTTPPasswordMgrWithPriorAuth <urllib.request.HTTPPasswordMgrWithPriorAuth>` +class allows HTTP Basic Authentication credentials to be managed so as to +eliminate unnecessary ``401`` response handling, or to unconditionally send +credentials on the first request in order to communicate with servers that +return a ``404`` response instead of a ``401`` if the ``Authorization`` header +is not sent. (Contributed by Matej Cepl in :issue:`19494` and Akshit Khurana in +:issue:`7159`.) + +A new *quote_via* argument for the +:func:`parse.urlencode() <urllib.parse.urlencode>` +function provides a way to control the encoding of query parts if needed. +(Contributed by Samwyse and Arnon Yaari in :issue:`13866`.) + +The :func:`request.urlopen() <urllib.request.urlopen>` function accepts an +:class:`ssl.SSLContext` object as a *context* argument, which will be used for +the HTTPS connection. (Contributed by Alex Gaynor in :issue:`22366`.) + +The :func:`parse.urljoin() <urllib.parse.urljoin>` was updated to use the +:rfc:`3986` semantics for the resolution of relative URLs, rather than +:rfc:`1808` and :rfc:`2396`. +(Contributed by Demian Brecht and Senthil Kumaran in :issue:`22118`.) + + +wsgiref +------- + +The *headers* argument of the :class:`headers.Headers <wsgiref.headers.Headers>` +class constructor is now optional. +(Contributed by Pablo Torres Navarrete and SilentGhost in :issue:`5800`.) + + +xmlrpc +------ + +The :class:`client.ServerProxy <xmlrpc.client.ServerProxy>` class now supports +:term:`context manager` protocol. +(Contributed by Claudiu Popa in :issue:`20627`.) + +:class:`client.ServerProxy <xmlrpc.client.ServerProxy>` constructor now accepts +an optional :class:`ssl.SSLContext` instance. +(Contributed by Alex Gaynor in :issue:`22960`.) + + +xml.sax +------- + +SAX parsers now support a character stream of the +:class:`xmlreader.InputSource <xml.sax.xmlreader.InputSource>` object. +(Contributed by Serhiy Storchaka in :issue:`2175`.) + +:func:`~xml.sax.parseString` now accepts a :class:`str` instance. +(Contributed by Serhiy Storchaka in :issue:`10590`.) + + +zipfile +------- + +ZIP output can now be written to unseekable streams. +(Contributed by Serhiy Storchaka in :issue:`23252`.) + +The *mode* argument of :meth:`ZipFile.open() <zipfile.ZipFile.open>` method now +accepts ``"x"`` to request exclusive creation. +(Contributed by Serhiy Storchaka in :issue:`21717`.) + + +Other module-level changes +========================== + +Many functions in :mod:`mmap`, :mod:`ossaudiodev`, :mod:`socket`, +:mod:`ssl`, and :mod:`codecs` modules now accept writable +:term:`bytes-like objects <bytes-like object>`. +(Contributed by Serhiy Storchaka in :issue:`23001`.) + + +Optimizations +============= + +The :func:`os.walk` function has been sped up by 3 to 5 times on POSIX systems, +and by 7 to 20 times on Windows. This was done using the new :func:`os.scandir` +function, which exposes file information from the underlying ``readdir`` or +``FindFirstFile``/``FindNextFile`` system calls. (Contributed by +Ben Hoyt with help from Victor Stinner in :issue:`23605`.) + +Construction of ``bytes(int)`` (filled by zero bytes) is faster and uses less +memory for large objects. ``calloc()`` is used instead of ``malloc()`` to +allocate memory for these objects. +(Contributed by Victor Stinner in :issue:`21233`.) + +Some operations on :mod:`ipaddress` :class:`~ipaddress.IPv4Network` and +:class:`~ipaddress.IPv6Network` have been massively sped up, such as +:meth:`~ipaddress.IPv4Network.subnets`, :meth:`~ipaddress.IPv4Network.supernet`, +:func:`~ipaddress.summarize_address_range`, :func:`~ipaddress.collapse_addresses`. +The speed up can range from 3 to 15 times. +(Contributed by Antoine Pitrou, Michel Albert, and Markus in +:issue:`21486`, :issue:`21487`, :issue:`20826`, :issue:`23266`.) + +Pickling of :mod:`ipaddress` objects was optimized to produce significantly +smaller output. (Contributed by Serhiy Storchaka in :issue:`23133`.) + +Many operations on :class:`io.BytesIO` are now 50% to 100% faster. +(Contributed by Serhiy Storchaka in :issue:`15381` and David Wilson in +:issue:`22003`.) + +The :func:`marshal.dumps` function is now faster: 65-85% with versions 3 +and 4, 20-25% with versions 0 to 2 on typical data, and up to 5 times in +best cases. +(Contributed by Serhiy Storchaka in :issue:`20416` and :issue:`23344`.) + +The UTF-32 encoder is now 3 to 7 times faster. +(Contributed by Serhiy Storchaka in :issue:`15027`.) + +Regular expressions are now parsed up to 10% faster. +(Contributed by Serhiy Storchaka in :issue:`19380`.) + +The :func:`json.dumps` function was optimized to run with +``ensure_ascii=False`` as fast as with ``ensure_ascii=True``. +(Contributed by Naoki Inada in :issue:`23206`.) + +The :c:func:`PyObject_IsInstance` and :c:func:`PyObject_IsSubclass` +functions have been sped up in the common case that the second argument +has :class:`type` as its metaclass. +(Contributed Georg Brandl by in :issue:`22540`.) + +Method caching was slightly improved, yielding up to 5% performance +improvement in some benchmarks. +(Contributed by Antoine Pitrou in :issue:`22847`.) + +Objects from :mod:`random` module now use two times less memory on 64-bit +builds. (Contributed by Serhiy Storchaka in :issue:`23488`.) + +The :func:`property` getter calls are up to 25% faster. +(Contributed by Joe Jevnik in :issue:`23910`.) + +Instantiation of :class:`fractions.Fraction` is now up to 30% faster. +(Contributed by Stefan Behnel in :issue:`22464`.) + +String methods :meth:`~str.find`, :meth:`~str.rfind`, :meth:`~str.split`, +:meth:`~str.partition` and :keyword:`in` string operator are now significantly +faster for searching 1-character substrings. +(Contributed by Serhiy Storchaka in :issue:`23573`.) + + +Build and C API Changes +======================= + +New ``calloc`` functions were added: + +* :c:func:`PyMem_RawCalloc`, +* :c:func:`PyMem_Calloc`, +* :c:func:`PyObject_Calloc`, +* :c:func:`_PyObject_GC_Calloc`. + +(Contributed by Victor Stinner in :issue:`21233`.) + +New encoding/decoding helper functions: + +* :c:func:`Py_DecodeLocale` (replaced ``_Py_char2wchar()``), +* :c:func:`Py_EncodeLocale` (replaced ``_Py_wchar2char()``). + +(Contributed by Victor Stinner in :issue:`18395`.) + +A new :c:func:`PyCodec_NameReplaceErrors` function to replace the unicode +encode error with ``\N{...}`` escapes. +(Contributed by Serhiy Storchaka in :issue:`19676`.) + +A new :c:func:`PyErr_FormatV` function similar to :c:func:`PyErr_Format`, +but accepts a ``va_list`` argument. +(Contributed by Antoine Pitrou in :issue:`18711`.) + +A new :c:data:`PyExc_RecursionError` exception. +(Contributed by Georg Brandl in :issue:`19235`.) + +New :c:func:`PyModule_FromDefAndSpec`, :c:func:`PyModule_FromDefAndSpec2`, +and :c:func:`PyModule_ExecDef` functions introduced by :pep:`489` -- +multi-phase extension module initialization. +(Contributed by Petr Viktorin in :issue:`24268`.) + +New :c:func:`PyNumber_MatrixMultiply` and +:c:func:`PyNumber_InPlaceMatrixMultiply` functions to perform matrix +multiplication. +(Contributed by Benjamin Peterson in :issue:`21176`. See also :pep:`465` +for details.) + +The :c:member:`PyTypeObject.tp_finalize` slot is now part of stable ABI. + +Windows builds now require Microsoft Visual C++ 14.0, which +is available as part of `Visual Studio 2015 <http://www.visualstudio.com>`_. + +Extension modules now include platform information tag in their filename on +some platforms (the tag is optional, and CPython will import extensions without +it; although if the tag is present and mismatched, the extension won't be +loaded): + +* On Linux, extension module filenames end with + ``.cpython-<major><minor>m-<architecture>-<os>.pyd``: + + * ``<major>`` is the major number of the Python version; + for Python 3.5 this is ``3``. + + * ``<minor>`` is the minor number of the Python version; + for Python 3.5 this is ``5``. + + * ``<architecture>`` is the hardware architecture the extension module + was built to run on. It's most commonly either ``i386`` for 32-bit Intel + platforms or ``x86_64`` for 64-bit Intel (and AMD) platforms. + + * ``<os>`` is always ``linux-gnu``, except for extensions built to + talk to the 32-bit ABI on 64-bit platforms, in which case it is + ``linux-gnu32`` (and ``<architecture>`` will be ``x86_64``). + +* On Windows, extension module filenames end with + ``<debug>.cp<major><minor>-<platform>.pyd``: + + * ``<major>`` is the major number of the Python version; + for Python 3.5 this is ``3``. + + * ``<minor>`` is the minor number of the Python version; + for Python 3.5 this is ``5``. + + * ``<platform>`` is the platform the extension module was built for, + either ``win32`` for Win32, ``win_amd64`` for Win64, ``win_ia64`` for + Windows Itanium 64, and ``win_arm`` for Windows on ARM. + + * If built in debug mode, ``<debug>`` will be ``_d``, + otherwise it will be blank. + +* On OS X platforms, extension module filenames now end with ``-darwin.so``. + +* On all other platforms, extension module filenames are the same as they were + with Python 3.4. + + +Deprecated +========== + +New Keywords +------------ + +``async`` and ``await`` are not recommended to be used as variable, class, +function or module names. Introduced by :pep:`492` in Python 3.5, they will +become proper keywords in Python 3.7. + + +Deprecated Python Behavior +-------------------------- + +Raising :exc:`StopIteration` exception inside a generator will now generate a silent +:exc:`PendingDeprecationWarning`, which will become a non-silent deprecation +warning in Python 3.6 and will trigger a :exc:`RuntimeError` in Python 3.7. +See :ref:`PEP 479: Change StopIteration handling inside generators <whatsnew-pep-479>` +for details. + + +Unsupported Operating Systems +----------------------------- + +Windows XP is no longer supported by Microsoft, thus, per :PEP:`11`, CPython +3.5 is no longer officially supported on this OS. + + +Deprecated Python modules, functions and methods +------------------------------------------------ + +The :mod:`formatter` module has now graduated to full deprecation and is still +slated for removal in Python 3.6. + +The :func:`asyncio.async` function is deprecated in favor of +:func:`~asyncio.ensure_future`. + +The :mod:`smtpd` module has in the past always decoded the DATA portion of +email messages using the ``utf-8`` codec. This can now be controlled by the +new *decode_data* keyword to :class:`~smtpd.SMTPServer`. The default value is +``True``, but this default is deprecated. Specify the *decode_data* keyword +with an appropriate value to avoid the deprecation warning. + +Directly assigning values to the :attr:`~http.cookies.Morsel.key`, +:attr:`~http.cookies.Morsel.value` and +:attr:`~http.cookies.Morsel.coded_value` of :class:`http.cookies.Morsel` +objects is deprecated. Use the :meth:`~http.cookies.Morsel.set` method +instead. In addition, the undocumented *LegalChars* parameter of +:meth:`~http.cookies.Morsel.set` is deprecated, and is now ignored. + +Passing a format string as keyword argument *format_string* to the +:meth:`~string.Formatter.format` method of the :class:`string.Formatter` +class has been deprecated. +(Contributed by Serhiy Storchaka in :issue:`23671`.) + +The :func:`platform.dist` and :func:`platform.linux_distribution` functions +are now deprecated and will be removed in Python 3.7. Linux distributions use +too many different ways of describing themselves, so the functionality is +left to a package. +(Contributed by Vajrasky Kok and Berker Peksag in :issue:`1322`.) + +The previously undocumented ``from_function`` and ``from_builtin`` methods of +:class:`inspect.Signature` are deprecated. Use the new +:meth:`Signature.from_callable() <inspect.Signature.from_callable>` +method instead. (Contributed by Yury Selivanov in :issue:`24248`.) + +The :func:`inspect.getargspec` function is deprecated and scheduled to be +removed in Python 3.6. (See :issue:`20438` for details.) + +The :mod:`inspect` :func:`~inspect.getfullargspec`, +:func:`~inspect.getargvalues`, :func:`~inspect.getcallargs`, +:func:`~inspect.getargvalues`, :func:`~inspect.formatargspec`, and +:func:`~inspect.formatargvalues` functions are deprecated in favor of +:func:`inspect.signature` API. +(Contributed by Yury Selivanov in :issue:`20438`.) + +Use of :const:`re.LOCALE` flag with str patterns or :const:`re.ASCII` is now +deprecated. (Contributed by Serhiy Storchaka in :issue:`22407`.) + +Use of unrecognized special sequences consisting of ``'\'`` and an ASCII letter +in regular expression patterns and replacement patterns now raises a +deprecation warning and will be forbidden in Python 3.6. +(Contributed by Serhiy Storchaka in :issue:`23622`.) + +The undocumented and unofficial *use_load_tests* default argument of the +:meth:`unittest.TestLoader.loadTestsFromModule` method now is +deprecated and ignored. +(Contributed by Robert Collins and Barry A. Warsaw in :issue:`16662`.) + + +Removed +======= + +API and Feature Removals +------------------------ + +The following obsolete and previously deprecated APIs and features have been +removed: + +* The ``__version__`` attribute has been dropped from the email package. The + email code hasn't been shipped separately from the stdlib for a long time, + and the ``__version__`` string was not updated in the last few releases. + +* The internal ``Netrc`` class in the :mod:`ftplib` module was deprecated in + 3.4, and has now been removed. + (Contributed by Matt Chaput in :issue:`6623`.) + +* The concept of ``.pyo`` files has been removed. + +* The JoinableQueue class in the provisional :mod:`asyncio` module was + deprecated in 3.4.4 and is now removed. + (Contributed by A. Jesse Jiryu Davis in :issue:`23464`.) + + +Porting to Python 3.5 +===================== + +This section lists previously described changes and other bugfixes +that may require changes to your code. + + +Changes in Python behavior +-------------------------- + +* Due to an oversight, earlier Python versions erroneously accepted the + following syntax:: + + f(1 for x in [1], *args) + f(1 for x in [1], **kwargs) + + Python 3.5 now correctly raises a :exc:`SyntaxError`, as generator + expressions must be put in parentheses if not a sole argument to a function. + + +Changes in the Python API +------------------------- + +* :pep:`475`: System calls are now retried when interrupted by a signal instead + of raising :exc:`InterruptedError` if the Python signal handler does not + raise an exception. + +* Before Python 3.5, a :class:`datetime.time` object was considered to be false + if it represented midnight in UTC. This behavior was considered obscure and + error-prone and has been removed in Python 3.5. See :issue:`13936` for full + details. + +* The :meth:`ssl.SSLSocket.send()` method now raises either + :exc:`ssl.SSLWantReadError` or :exc:`ssl.SSLWantWriteError` + on a non-blocking socket if the operation would block. Previously, + it would return ``0``. (Contributed by Nikolaus Rath in :issue:`20951`.) + +* The ``__name__`` attribute of generator is now set from the function name, + instead of being set from the code name. Use ``gen.gi_code.co_name`` to + retrieve the code name. Generators also have a new ``__qualname__`` + attribute, the qualified name, which is now used for the representation + of a generator (``repr(gen)``). + (Contributed by Victor Stinner in :issue:`21205`.) + +* The deprecated "strict" mode and argument of :class:`~html.parser.HTMLParser`, + :meth:`HTMLParser.error`, and the :exc:`HTMLParserError` exception have been + removed. (Contributed by Ezio Melotti in :issue:`15114`.) + The *convert_charrefs* argument of :class:`~html.parser.HTMLParser` is + now ``True`` by default. (Contributed by Berker Peksag in :issue:`21047`.) + +* Although it is not formally part of the API, it is worth noting for porting + purposes (ie: fixing tests) that error messages that were previously of the + form "'sometype' does not support the buffer protocol" are now of the form "a + :term:`bytes-like object` is required, not 'sometype'". + (Contributed by Ezio Melotti in :issue:`16518`.) + +* If the current directory is set to a directory that no longer exists then + :exc:`FileNotFoundError` will no longer be raised and instead + :meth:`~importlib.machinery.FileFinder.find_spec` will return ``None`` + **without** caching ``None`` in :data:`sys.path_importer_cache` which is + different than the typical case (:issue:`22834`). + +* HTTP status code and messages from :mod:`http.client` and :mod:`http.server` + were refactored into a common :class:`~http.HTTPStatus` enum. The values in + :mod:`http.client` and :mod:`http.server` remain available for backwards + compatibility. (Contributed by Demian Brecht in :issue:`21793`.) + +* When an import loader defines :meth:`importlib.machinery.Loader.exec_module` + it is now expected to also define + :meth:`~importlib.machinery.Loader.create_module` (raises a + :exc:`DeprecationWarning` now, will be an error in Python 3.6). If the loader + inherits from :class:`importlib.abc.Loader` then there is nothing to do, else + simply define :meth:`~importlib.machinery.Loader.create_module` to return + ``None``. (Contributed by Brett Cannon in :issue:`23014`.) + +* The :func:`re.split` function always ignored empty pattern matches, so the + ``"x*"`` pattern worked the same as ``"x+"``, and the ``"\b"`` pattern never + worked. Now :func:`re.split` raises a warning if the pattern could match + an empty string. For compatibility use patterns that never match an empty + string (e.g. ``"x+"`` instead of ``"x*"``). Patterns that could only match + an empty string (such as ``"\b"``) now raise an error. + (Contributed by Serhiy Storchaka in :issue:`22818`.) + +* The :class:`http.cookies.Morsel` dict-like interface has been made self + consistent: morsel comparison now takes the :attr:`~http.cookies.Morsel.key` + and :attr:`~http.cookies.Morsel.value` into account, + :meth:`~http.cookies.Morsel.copy` now results in a + :class:`~http.cookies.Morsel` instance rather than a :class:`dict`, and + :meth:`~http.cookies.Morsel.update` will now raise an exception if any of the + keys in the update dictionary are invalid. In addition, the undocumented + *LegalChars* parameter of :func:`~http.cookies.Morsel.set` is deprecated and + is now ignored. (Contributed by Demian Brecht in :issue:`2211`.) + +* :pep:`488` has removed ``.pyo`` files from Python and introduced the optional + ``opt-`` tag in ``.pyc`` file names. The + :func:`importlib.util.cache_from_source` has gained an *optimization* + parameter to help control the ``opt-`` tag. Because of this, the + *debug_override* parameter of the function is now deprecated. `.pyo` files + are also no longer supported as a file argument to the Python interpreter and + thus serve no purpose when distributed on their own (i.e. sourcless code + distribution). Due to the fact that the magic number for bytecode has changed + in Python 3.5, all old `.pyo` files from previous versions of Python are + invalid regardless of this PEP. + +* The :mod:`socket` module now exports the :data:`~socket.CAN_RAW_FD_FRAMES` + constant on linux 3.6 and greater. + +* The :func:`ssl.cert_time_to_seconds` function now interprets the input time + as UTC and not as local time, per :rfc:`5280`. Additionally, the return + value is always an :class:`int`. (Contributed by Akira Li in :issue:`19940`.) + +* The ``pygettext.py`` Tool now uses the standard +NNNN format for timezones in + the POT-Creation-Date header. + +* The :mod:`smtplib` module now uses :data:`sys.stderr` instead of previous + module level :data:`stderr` variable for debug output. If your (test) + program depends on patching the module level variable to capture the debug + output, you will need to update it to capture sys.stderr instead. + +* The :meth:`str.startswith` and :meth:`str.endswith` methods no longer return + ``True`` when finding the empty string and the indexes are completely out of + range. (Contributed by Serhiy Storchaka in :issue:`24284`.) + +* The :func:`inspect.getdoc` function now returns documentation strings + inherited from base classes. Documentation strings no longer need to be + duplicated if the inherited documentation is appropriate. To suppress an + inherited string, an empty string must be specified (or the documentation + may be filled in). This change affects the output of the :mod:`pydoc` + module and the :func:`help` function. + (Contributed by Serhiy Storchaka in :issue:`15582`.) + +* Nested :func:`functools.partial` calls are now flattened. If you were + relying on the previous behavior, you can now either add an attribute to a + :func:`functools.partial` object or you can create a subclass of + :func:`functools.partial`. + (Contributed by Alexander Belopolsky in :issue:`7830`.) + +Changes in the C API +-------------------- + +* The undocumented :c:member:`~PyMemoryViewObject.format` member of the + (non-public) :c:type:`PyMemoryViewObject` structure has been removed. + All extensions relying on the relevant parts in ``memoryobject.h`` + must be rebuilt. + +* The :c:type:`PyMemAllocator` structure was renamed to + :c:type:`PyMemAllocatorEx` and a new ``calloc`` field was added. + +* Removed non-documented macro :c:macro:`PyObject_REPR` which leaked references. + Use format character ``%R`` in :c:func:`PyUnicode_FromFormat`-like functions + to format the :func:`repr` of the object. + (Contributed by Serhiy Storchaka in :issue:`22453`.) + +* Because the lack of the :attr:`__module__` attribute breaks pickling and + introspection, a deprecation warning now is raised for builtin type without + the :attr:`__module__` attribute. Would be an AttributeError in future. + (Contributed by Serhiy Storchaka in :issue:`20204`.) + +* As part of :pep:`492` implementation, ``tp_reserved`` slot of + :c:type:`PyTypeObject` was replaced with a + :c:member:`tp_as_async` slot. Refer to :ref:`coro-objects` for + new types, structures and functions. + diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst new file mode 100644 index 000000000000..b500550c22b7 --- /dev/null +++ b/Doc/whatsnew/3.6.rst @@ -0,0 +1,241 @@ +**************************** + What's New In Python 3.6 +**************************** + +:Release: |release| +:Date: |today| + +.. Rules for maintenance: + + * Anyone can add text to this document. Do not spend very much time + on the wording of your changes, because your text will probably + get rewritten to some degree. + + * The maintainer will go through Misc/NEWS periodically and add + changes; it's therefore more important to add your changes to + Misc/NEWS than to this file. + + * This is not a complete list of every single change; completeness + is the purpose of Misc/NEWS. Some changes I consider too small + or esoteric to include. If such a change is added to the text, + I'll just remove it. (This is another reason you shouldn't spend + too much time on writing your addition.) + + * If you want to draw your new text to the attention of the + maintainer, add 'XXX' to the beginning of the paragraph or + section. + + * It's OK to just add a fragmentary note about a change. For + example: "XXX Describe the transmogrify() function added to the + socket module." The maintainer will research the change and + write the necessary text. + + * You can comment out your additions if you like, but it's not + necessary (especially when a final release is some months away). + + * Credit the author of a patch or bugfix. Just the name is + sufficient; the e-mail address isn't necessary. + + * It's helpful to add the bug/patch number as a comment: + + XXX Describe the transmogrify() function added to the socket + module. + (Contributed by P.Y. Developer in :issue:`12345`.) + + This saves the maintainer the effort of going through the Mercurial log + when researching a change. + +This article explains the new features in Python 3.6, compared to 3.5. + +For full details, see the :source:`Misc/NEWS` file. + +.. note:: + + Prerelease users should be aware that this document is currently in draft + form. It will be updated substantially as Python 3.6 moves towards release, + so it's worth checking back even after reading earlier versions. + + +Summary -- Release highlights +============================= + +.. This section singles out the most important changes in Python 3.6. + Brevity is key. + +* None yet. + +.. PEP-sized items next. + +.. _pep-4XX: + +.. PEP 4XX: Virtual Environments +.. ============================= + + +.. (Implemented by Foo Bar.) + +.. .. seealso:: + + :pep:`4XX` - Python Virtual Environments + PEP written by Carl Meyer + + +Other Language Changes +====================== + +* None yet. + + +New Modules +=========== + +* None yet. + + +Improved Modules +================ + +datetime +-------- + +:meth:`datetime.stftime <datetime.datetime.stftime>` and +:meth:`date.stftime <datetime.date.stftime>` methods now support ISO 8601 date +directives ``%G``, ``%u`` and ``%V``. +(Contributed by Ashley Anderson in :issue:`12006`.) + + +operator +-------- + +New object :data:`operator.subscript` makes it easier to create complex +indexers. For example: ``subscript[0:10:2] == slice(0, 10, 2)`` +(Contributed by Joe Jevnik in :issue:`24379`.) + + +pickle +------ + +Objects that need calling ``__new__`` with keyword arguments, can now be pickled +using :ref:`pickle protocols <pickle-protocols>` older than protocol version 4. +Protocol version 4 already supports this case. (Contributed by Serhiy +Storchaka in :issue:`24164`.) + + +rlcomplete +---------- + +Private and special attribute names now are omitted unless the prefix starts +with underscores. A space or a colon can be added after completed keyword. +(Contributed by Serhiy Storchaka in :issue:`25011` and :issue:`25209`.) + + +urllib.robotparser +------------------ + +:class:`~urllib.robotparser.RobotFileParser` now supports ``Crawl-delay`` and +``Request-rate`` extensions. +(Contributed by Nikolay Bogoychev in :issue:`16099`.) + + +Optimizations +============= + +* The ASCII decoder is now up to 60 times as fast for error handlers: + ``surrogateescape``, ``ignore`` and ``replace`` (Contributed + by Victor Stinner in :issue:`24870`). + +* The ASCII and the Latin1 encoders are now up to 3 times as fast for the + error ``surrogateescape`` (Contributed by Victor Stinner in :issue:`25227`). + +* The UTF-8 encoder is now up to 75 times as fast for error handlers: + ``ignore``, ``replace``, ``surrogateescape``, ``surrogatepass`` (Contributed + by Victor Stinner in :issue:`25267`). + +* The UTF-8 decoder is now up to 15 times as fast for error handlers: + ``ignore``, ``replace`` and ``surrogateescape`` (Contributed + by Victor Stinner in :issue:`25301`). + +* ``bytes % args`` is now up to 2 times faster. (Contributed by Victor Stinner + in :issue:`25349`). + +* ``bytearray % args`` is now between 2.5 and 5 times faster. (Contributed by + Victor Stinner in :issue:`25399`). + +* Optimize :meth:`bytes.fromhex` and :meth:`bytearray.fromhex`: they are now + between 2x and 3.5x faster. (Contributed by Victor Stinner in :issue:`25401`). + + +Build and C API Changes +======================= + +* None yet. + + +Deprecated +========== + +New Keywords +------------ + +``async`` and ``await`` are not recommended to be used as variable, class, +function or module names. Introduced by :pep:`492` in Python 3.5, they will +become proper keywords in Python 3.7. + + +Deprecated Python modules, functions and methods +------------------------------------------------ + +* None yet. + + +Deprecated functions and types of the C API +------------------------------------------- + +* None yet. + + +Deprecated features +------------------- + +* The ``pyvenv`` script has been deprecated in favour of ``python3 -m venv``. + This prevents confusion as to what Python interpreter ``pyvenv`` is + connected to and thus what Python interpreter will be used by the virtual + environment. See :issue:`25154`. + + +Removed +======= + +API and Feature Removals +------------------------ + +* ``inspect.getargspec()`` was removed (was deprecated since CPython 3.0). + :func:`inspect.getfullargspec` is an almost drop in replacement. + +* ``inspect.getmoduleinfo()`` was removed (was deprecated since CPython 3.3). + :func:`inspect.getmodulename` should be used for obtaining the module + name for a given path. + + +Porting to Python 3.6 +===================== + +This section lists previously described changes and other bugfixes +that may require changes to your code. + +Changes in the Python API +------------------------- + +* Reading the :attr:`~urllib.parse.SplitResult.port` attribute of + :func:`urllib.parse.urlsplit` and :func:`~urllib.parse.urlparse` results + now raises :exc:`ValueError` for out-of-range values, rather than + returning :const:`None`. See :issue:`20059`. + +* The :mod:`imp` module now raises a :exc:`DeprecationWarning` instead of + :exc:`PendingDeprecationWarning`. + + +Changes in the C API +-------------------- + +* None yet. diff --git a/Doc/whatsnew/changelog.rst b/Doc/whatsnew/changelog.rst index 57e2dabffaa3..07f90948bd0a 100644 --- a/Doc/whatsnew/changelog.rst +++ b/Doc/whatsnew/changelog.rst @@ -3,4 +3,3 @@ Changelog +++++++++ .. miscnews:: ../../Misc/NEWS - diff --git a/Doc/whatsnew/index.rst b/Doc/whatsnew/index.rst index 29902e407c8f..7c9252401eff 100644 --- a/Doc/whatsnew/index.rst +++ b/Doc/whatsnew/index.rst @@ -11,6 +11,8 @@ anyone wishing to stay up-to-date after a new release. .. toctree:: :maxdepth: 2 + 3.6.rst + 3.5.rst 3.4.rst 3.3.rst 3.2.rst diff --git a/Grammar/Grammar b/Grammar/Grammar index d7aaffd60e14..14bdecd0e25d 100644 --- a/Grammar/Grammar +++ b/Grammar/Grammar @@ -7,8 +7,8 @@ # with someone who can; ask around on python-dev for help. Fred # Drake <fdrake@acm.org> will probably be listening there. -# NOTE WELL: You should also follow all the steps listed in PEP 306, -# "How to Change Python's Grammar" +# NOTE WELL: You should also follow all the steps listed at +# https://docs.python.org/devguide/grammar.html # Start symbols for the grammar: # single_input is a single interactive statement; @@ -21,16 +21,24 @@ eval_input: testlist NEWLINE* ENDMARKER decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE decorators: decorator+ -decorated: decorators (classdef | funcdef) +decorated: decorators (classdef | funcdef | async_funcdef) + +async_funcdef: ASYNC funcdef funcdef: 'def' NAME parameters ['->' test] ':' suite + parameters: '(' [typedargslist] ')' -typedargslist: (tfpdef ['=' test] (',' tfpdef ['=' test])* [',' - ['*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef]] - | '*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] | '**' tfpdef) +typedargslist: (tfpdef ['=' test] (',' tfpdef ['=' test])* [',' [ + '*' [tfpdef] (',' tfpdef ['=' test])* [',' ['**' tfpdef [',']]] + | '**' tfpdef [',']]] + | '*' [tfpdef] (',' tfpdef ['=' test])* [',' ['**' tfpdef [',']]] + | '**' tfpdef [',']) tfpdef: NAME [':' test] -varargslist: (vfpdef ['=' test] (',' vfpdef ['=' test])* [',' - ['*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef]] - | '*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] | '**' vfpdef) +varargslist: (vfpdef ['=' test] (',' vfpdef ['=' test])* [',' [ + '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]] + | '**' vfpdef [',']]] + | '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]] + | '**' vfpdef [','] +) vfpdef: NAME stmt: simple_stmt | compound_stmt @@ -40,7 +48,7 @@ small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt | expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) | ('=' (yield_expr|testlist_star_expr))*) testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [','] -augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | +augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=') # For normal assignments, additional restrictions enforced by the interpreter del_stmt: 'del' exprlist @@ -65,7 +73,8 @@ global_stmt: 'global' NAME (',' NAME)* nonlocal_stmt: 'nonlocal' NAME (',' NAME)* assert_stmt: 'assert' test [',' test] -compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated +compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated | async_stmt +async_stmt: ASYNC (funcdef | with_stmt | for_stmt) if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] while_stmt: 'while' test ':' suite ['else' ':' suite] for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] @@ -89,7 +98,7 @@ and_test: not_test ('and' not_test)* not_test: 'not' not_test | comparison comparison: expr (comp_op expr)* # <> isn't actually a valid comparison operator in Python. It's here for the -# sake of a __future__ import described in PEP 401 +# sake of a __future__ import described in PEP 401 (which really works :-) comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' star_expr: '*' expr expr: xor_expr ('|' xor_expr)* @@ -97,9 +106,10 @@ 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)* +term: factor (('*'|'@'|'/'|'%'|'//') factor)* factor: ('+'|'-'|'~') factor | power -power: atom trailer* ['**' factor] +power: atom_expr ['**' factor] +atom_expr: [AWAIT] atom trailer* atom: ('(' [yield_expr|testlist_comp] ')' | '[' [testlist_comp] ']' | '{' [dictorsetmaker] '}' | @@ -111,17 +121,29 @@ subscript: test | [test] ':' [test] [sliceop] sliceop: ':' [test] exprlist: (expr|star_expr) (',' (expr|star_expr))* [','] testlist: test (',' test)* [','] -dictorsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) | - (test (comp_for | (',' test)* [','])) ) +dictorsetmaker: ( ((test ':' test | '**' expr) + (comp_for | (',' (test ':' test | '**' expr))* [','])) | + ((test | star_expr) + (comp_for | (',' (test | star_expr))* [','])) ) classdef: 'class' NAME ['(' [arglist] ')'] ':' suite -arglist: (argument ',')* (argument [','] - |'*' test (',' argument)* [',' '**' test] - |'**' test) +arglist: argument (',' argument)* [','] + # The reason that keywords are test nodes instead of NAME is that using NAME # results in an ambiguity. ast.c makes sure it's a NAME. -argument: test [comp_for] | test '=' test # Really [keyword '='] test +# "test '=' test" is really "keyword '=' test", but we have no such token. +# These need to be in a single rule to avoid grammar that is ambiguous +# to our LL(1) parser. Even though 'test' includes '*expr' in star_expr, +# we explicitly match '*' here, too, to give it proper precedence. +# Illegal combinations and orderings are blocked in ast.c: +# multiple (test comp_for) arguements are blocked; keyword unpackings +# that precede iterable unpackings are blocked; etc. +argument: ( test [comp_for] | + test '=' test | + '**' test | + '*' test ) + comp_iter: comp_for | comp_if comp_for: 'for' exprlist 'in' or_test [comp_iter] comp_if: 'if' test_nocond [comp_iter] diff --git a/Include/Python-ast.h b/Include/Python-ast.h index 67d677b233b8..ea6679cdebd3 100644 --- a/Include/Python-ast.h +++ b/Include/Python-ast.h @@ -15,9 +15,9 @@ typedef struct _slice *slice_ty; typedef enum _boolop { And=1, Or=2 } boolop_ty; -typedef enum _operator { Add=1, Sub=2, Mult=3, Div=4, Mod=5, Pow=6, LShift=7, - RShift=8, BitOr=9, BitXor=10, BitAnd=11, FloorDiv=12 } - operator_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; @@ -63,12 +63,13 @@ struct _mod { } v; }; -enum _stmt_kind {FunctionDef_kind=1, ClassDef_kind=2, Return_kind=3, - Delete_kind=4, Assign_kind=5, AugAssign_kind=6, For_kind=7, - While_kind=8, If_kind=9, With_kind=10, Raise_kind=11, - Try_kind=12, Assert_kind=13, Import_kind=14, - ImportFrom_kind=15, Global_kind=16, Nonlocal_kind=17, - Expr_kind=18, Pass_kind=19, Break_kind=20, Continue_kind=21}; +enum _stmt_kind {FunctionDef_kind=1, AsyncFunctionDef_kind=2, ClassDef_kind=3, + Return_kind=4, Delete_kind=5, Assign_kind=6, + AugAssign_kind=7, For_kind=8, AsyncFor_kind=9, While_kind=10, + If_kind=11, With_kind=12, AsyncWith_kind=13, Raise_kind=14, + Try_kind=15, Assert_kind=16, Import_kind=17, + ImportFrom_kind=18, Global_kind=19, Nonlocal_kind=20, + Expr_kind=21, Pass_kind=22, Break_kind=23, Continue_kind=24}; struct _stmt { enum _stmt_kind kind; union { @@ -80,12 +81,18 @@ struct _stmt { expr_ty returns; } FunctionDef; + struct { + identifier name; + arguments_ty args; + asdl_seq *body; + asdl_seq *decorator_list; + expr_ty returns; + } AsyncFunctionDef; + struct { identifier name; asdl_seq *bases; asdl_seq *keywords; - expr_ty starargs; - expr_ty kwargs; asdl_seq *body; asdl_seq *decorator_list; } ClassDef; @@ -116,6 +123,13 @@ struct _stmt { asdl_seq *orelse; } For; + struct { + expr_ty target; + expr_ty iter; + asdl_seq *body; + asdl_seq *orelse; + } AsyncFor; + struct { expr_ty test; asdl_seq *body; @@ -133,6 +147,11 @@ struct _stmt { asdl_seq *body; } With; + struct { + asdl_seq *items; + asdl_seq *body; + } AsyncWith; + struct { expr_ty exc; expr_ty cause; @@ -180,11 +199,12 @@ struct _stmt { enum _expr_kind {BoolOp_kind=1, BinOp_kind=2, UnaryOp_kind=3, Lambda_kind=4, IfExp_kind=5, Dict_kind=6, Set_kind=7, ListComp_kind=8, SetComp_kind=9, DictComp_kind=10, GeneratorExp_kind=11, - Yield_kind=12, YieldFrom_kind=13, Compare_kind=14, - Call_kind=15, Num_kind=16, Str_kind=17, Bytes_kind=18, - NameConstant_kind=19, Ellipsis_kind=20, Attribute_kind=21, - Subscript_kind=22, Starred_kind=23, Name_kind=24, - List_kind=25, Tuple_kind=26}; + Await_kind=12, Yield_kind=13, YieldFrom_kind=14, + Compare_kind=15, Call_kind=16, Num_kind=17, Str_kind=18, + FormattedValue_kind=19, JoinedStr_kind=20, Bytes_kind=21, + NameConstant_kind=22, Ellipsis_kind=23, Attribute_kind=24, + Subscript_kind=25, Starred_kind=26, Name_kind=27, + List_kind=28, Tuple_kind=29}; struct _expr { enum _expr_kind kind; union { @@ -245,6 +265,10 @@ struct _expr { asdl_seq *generators; } GeneratorExp; + struct { + expr_ty value; + } Await; + struct { expr_ty value; } Yield; @@ -263,8 +287,6 @@ struct _expr { expr_ty func; asdl_seq *args; asdl_seq *keywords; - expr_ty starargs; - expr_ty kwargs; } Call; struct { @@ -275,6 +297,16 @@ struct _expr { string s; } Str; + struct { + expr_ty value; + int conversion; + expr_ty format_spec; + } FormattedValue; + + struct { + asdl_seq *values; + } JoinedStr; + struct { bytes s; } Bytes; @@ -406,11 +438,14 @@ mod_ty _Py_Suite(asdl_seq * body, PyArena *arena); stmt_ty _Py_FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq * decorator_list, expr_ty returns, int lineno, int 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) +#define AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7) _Py_AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7) +stmt_ty _Py_AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq * + body, asdl_seq * decorator_list, expr_ty returns, + int lineno, int col_offset, PyArena *arena); +#define ClassDef(a0, a1, a2, a3, a4, a5, a6, a7) _Py_ClassDef(a0, a1, a2, a3, a4, a5, a6, a7) stmt_ty _Py_ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, - expr_ty starargs, expr_ty kwargs, asdl_seq * body, - asdl_seq * decorator_list, int lineno, int col_offset, - PyArena *arena); + asdl_seq * body, asdl_seq * decorator_list, int lineno, + int col_offset, PyArena *arena); #define Return(a0, a1, a2, a3) _Py_Return(a0, a1, a2, a3) stmt_ty _Py_Return(expr_ty value, int lineno, int col_offset, PyArena *arena); #define Delete(a0, a1, a2, a3) _Py_Delete(a0, a1, a2, a3) @@ -425,6 +460,9 @@ stmt_ty _Py_AugAssign(expr_ty target, operator_ty op, expr_ty value, int #define For(a0, a1, a2, a3, a4, a5, a6) _Py_For(a0, a1, a2, a3, a4, a5, a6) stmt_ty _Py_For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, int lineno, int col_offset, PyArena *arena); +#define AsyncFor(a0, a1, a2, a3, a4, a5, a6) _Py_AsyncFor(a0, a1, a2, a3, a4, a5, a6) +stmt_ty _Py_AsyncFor(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * + orelse, int lineno, int col_offset, PyArena *arena); #define While(a0, a1, a2, a3, a4, a5) _Py_While(a0, a1, a2, a3, a4, a5) stmt_ty _Py_While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int col_offset, PyArena *arena); @@ -434,6 +472,9 @@ stmt_ty _Py_If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, #define With(a0, a1, a2, a3, a4) _Py_With(a0, a1, a2, a3, a4) stmt_ty _Py_With(asdl_seq * items, asdl_seq * body, int lineno, int col_offset, PyArena *arena); +#define AsyncWith(a0, a1, a2, a3, a4) _Py_AsyncWith(a0, a1, a2, a3, a4) +stmt_ty _Py_AsyncWith(asdl_seq * items, asdl_seq * body, int lineno, int + col_offset, PyArena *arena); #define Raise(a0, a1, a2, a3, a4) _Py_Raise(a0, a1, a2, a3, a4) stmt_ty _Py_Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, PyArena *arena); @@ -496,6 +537,8 @@ expr_ty _Py_DictComp(expr_ty key, expr_ty value, asdl_seq * generators, int #define GeneratorExp(a0, a1, a2, a3, a4) _Py_GeneratorExp(a0, a1, a2, a3, a4) expr_ty _Py_GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, PyArena *arena); +#define Await(a0, a1, a2, a3) _Py_Await(a0, a1, a2, a3) +expr_ty _Py_Await(expr_ty value, int lineno, int col_offset, PyArena *arena); #define Yield(a0, a1, a2, a3) _Py_Yield(a0, a1, a2, a3) expr_ty _Py_Yield(expr_ty value, int lineno, int col_offset, PyArena *arena); #define YieldFrom(a0, a1, a2, a3) _Py_YieldFrom(a0, a1, a2, a3) @@ -504,14 +547,19 @@ expr_ty _Py_YieldFrom(expr_ty value, int lineno, int col_offset, PyArena #define Compare(a0, a1, a2, a3, a4, a5) _Py_Compare(a0, a1, a2, a3, a4, a5) expr_ty _Py_Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, int lineno, int 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, expr_ty - starargs, expr_ty kwargs, int lineno, int col_offset, PyArena - *arena); +#define Call(a0, a1, a2, a3, a4, a5) _Py_Call(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int + lineno, int col_offset, PyArena *arena); #define Num(a0, a1, a2, a3) _Py_Num(a0, a1, a2, a3) expr_ty _Py_Num(object n, int lineno, int col_offset, PyArena *arena); #define Str(a0, a1, a2, a3) _Py_Str(a0, a1, a2, a3) expr_ty _Py_Str(string s, int lineno, int col_offset, PyArena *arena); +#define FormattedValue(a0, a1, a2, a3, a4, a5) _Py_FormattedValue(a0, a1, a2, a3, a4, a5) +expr_ty _Py_FormattedValue(expr_ty value, int conversion, expr_ty format_spec, + int lineno, int col_offset, PyArena *arena); +#define JoinedStr(a0, a1, a2, a3) _Py_JoinedStr(a0, a1, a2, a3) +expr_ty _Py_JoinedStr(asdl_seq * values, int lineno, int col_offset, PyArena + *arena); #define Bytes(a0, a1, a2, a3) _Py_Bytes(a0, a1, a2, a3) expr_ty _Py_Bytes(bytes s, int lineno, int col_offset, PyArena *arena); #define NameConstant(a0, a1, a2, a3) _Py_NameConstant(a0, a1, a2, a3) diff --git a/Include/Python.h b/Include/Python.h index 2dd82903bcda..858dbd1a66a4 100644 --- a/Include/Python.h +++ b/Include/Python.h @@ -85,6 +85,7 @@ #include "tupleobject.h" #include "listobject.h" #include "dictobject.h" +#include "odictobject.h" #include "enumobject.h" #include "setobject.h" #include "methodobject.h" @@ -112,6 +113,7 @@ #include "pyarena.h" #include "modsupport.h" #include "pythonrun.h" +#include "pylifecycle.h" #include "ceval.h" #include "sysmodule.h" #include "intrcheck.h" diff --git a/Include/abstract.h b/Include/abstract.h index d258ad556875..83dbf94f6b90 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -266,6 +266,12 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ PyAPI_FUNC(PyObject *) PyObject_Call(PyObject *callable_object, PyObject *args, PyObject *kw); +#ifndef Py_LIMITED_API + PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult(PyObject *func, + PyObject *result, + const char *where); +#endif + /* Call a callable Python object, callable_object, with arguments and keywords arguments. The 'args' argument can not be @@ -409,8 +415,8 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ #ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o); + PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); #endif -PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); /* Guess the size of object o using len(o) or o.__length_hint__(). @@ -658,6 +664,12 @@ PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); o1*o2. */ + PyAPI_FUNC(PyObject *) PyNumber_MatrixMultiply(PyObject *o1, PyObject *o2); + + /* + This is the equivalent of the Python expression: o1 @ o2. + */ + PyAPI_FUNC(PyObject *) PyNumber_FloorDivide(PyObject *o1, PyObject *o2); /* @@ -832,6 +844,12 @@ PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); o1 *= o2. */ + PyAPI_FUNC(PyObject *) PyNumber_InPlaceMatrixMultiply(PyObject *o1, PyObject *o2); + + /* + This is the equivalent of the Python expression: o1 @= o2. + */ + PyAPI_FUNC(PyObject *) PyNumber_InPlaceFloorDivide(PyObject *o1, PyObject *o2); @@ -1021,7 +1039,7 @@ PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); PyAPI_FUNC(PyObject *) PySequence_Fast(PyObject *o, const char* m); /* - Returns the sequence, o, as a list, unless it's already a + 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. diff --git a/Include/bytes_methods.h b/Include/bytes_methods.h index 1498b8f83c2b..11d5f4275231 100644 --- a/Include/bytes_methods.h +++ b/Include/bytes_methods.h @@ -21,8 +21,8 @@ extern void _Py_bytes_title(char *result, char *s, Py_ssize_t len); extern void _Py_bytes_capitalize(char *result, char *s, Py_ssize_t len); extern void _Py_bytes_swapcase(char *result, char *s, Py_ssize_t len); -/* This one gets the raw argument list. */ -extern PyObject* _Py_bytes_maketrans(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__[]; diff --git a/Include/bytesobject.h b/Include/bytesobject.h index 0ee8d366d4ab..846911295960 100644 --- a/Include/bytesobject.h +++ b/Include/bytesobject.h @@ -62,6 +62,14 @@ 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, @@ -122,6 +130,87 @@ PyAPI_FUNC(Py_ssize_t) _PyBytes_InsertThousandsGrouping(char *buffer, #define F_ALT (1<<3) #define F_ZERO (1<<4) +#ifndef Py_LIMITED_API +/* The _PyBytesWriter structure is big: it contains an embeded "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 diff --git a/Include/ceval.h b/Include/ceval.h index 6811367d7625..b5373a9cc474 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -23,6 +23,8 @@ PyAPI_FUNC(PyObject *) PyEval_CallMethod(PyObject *obj, #ifndef Py_LIMITED_API PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); +PyAPI_FUNC(void) _PyEval_SetCoroutineWrapper(PyObject *); +PyAPI_FUNC(PyObject *) _PyEval_GetCoroutineWrapper(void); #endif struct _frame; /* Avoid including frameobject.h */ @@ -46,16 +48,16 @@ PyAPI_FUNC(int) Py_MakePendingCalls(void); 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 RuntimeError, and sets + 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 - RuntimeError. + 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 - RuntimeError has been mistakingly ignored. When this protection is + 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 @@ -77,7 +79,7 @@ PyAPI_FUNC(int) Py_GetRecursionLimit(void); do{ if(_Py_MakeEndRecCheck(PyThreadState_GET()->recursion_depth)) \ PyThreadState_GET()->overflowed = 0; \ } while(0) -PyAPI_FUNC(int) _Py_CheckRecursiveCall(char *where); +PyAPI_FUNC(int) _Py_CheckRecursiveCall(const char *where); PyAPI_DATA(int) _Py_CheckRecursionLimit; #ifdef USE_STACKCHECK @@ -92,10 +94,16 @@ PyAPI_DATA(int) _Py_CheckRecursionLimit; # 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_CheckRecursionLimit > 100) \ - ? (_Py_CheckRecursionLimit - 50) \ - : (3 * (_Py_CheckRecursionLimit >> 2)))) + (--(x) < _Py_RecursionLimitLowerWaterMark(_Py_CheckRecursionLimit)) #define Py_ALLOW_RECURSION \ do { unsigned char _old = PyThreadState_GET()->recursion_critical;\ diff --git a/Include/code.h b/Include/code.h index 7c7e5bf8dc73..56e6ec18afea 100644 --- a/Include/code.h +++ b/Include/code.h @@ -21,7 +21,12 @@ typedef struct { 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 doesn't count for hash or comparisons */ + /* The rest aren't used in either hash or comparisons, except for + co_name (used in both) and co_firstlineno (used only in + comparisons). 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. + */ unsigned char *co_cell2arg; /* Maps cell vars which are arguments. */ PyObject *co_filename; /* unicode (where it was loaded from) */ PyObject *co_name; /* unicode (name, for reference) */ @@ -46,6 +51,11 @@ typedef struct { */ #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 + /* These are no longer used. */ #if 0 #define CO_GENERATOR_ALLOWED 0x1000 @@ -57,6 +67,7 @@ typedef struct { #define CO_FUTURE_UNICODE_LITERALS 0x20000 #define CO_FUTURE_BARRY_AS_BDFL 0x40000 +#define CO_FUTURE_GENERATOR_STOP 0x80000 /* This value is found in the co_cell2arg array when the associated cell variable does not correspond to an argument. The maximum number of diff --git a/Include/codecs.h b/Include/codecs.h index 5ca505fbd5ec..9e4f3050952d 100644 --- a/Include/codecs.h +++ b/Include/codecs.h @@ -49,6 +49,10 @@ PyAPI_FUNC(int) PyCodec_Register( PyAPI_FUNC(PyObject *) _PyCodec_Lookup( const char *encoding ); + +PyAPI_FUNC(int) _PyCodec_Forget( + const char *encoding + ); #endif /* Codec registry encoding check API. @@ -67,7 +71,7 @@ PyAPI_FUNC(int) PyCodec_KnownEncoding( 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. */ @@ -83,7 +87,7 @@ PyAPI_FUNC(PyObject *) PyCodec_Encode( 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. */ @@ -94,7 +98,7 @@ PyAPI_FUNC(PyObject *) PyCodec_Decode( const char *errors ); -#ifndef PY_LIMITED_API +#ifndef Py_LIMITED_API /* Text codec specific encoding and decoding API. Checks the encoding against a list of codecs which do not @@ -104,7 +108,14 @@ PyAPI_FUNC(PyObject *) PyCodec_Decode( 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, @@ -117,11 +128,24 @@ PyAPI_FUNC(PyObject *) _PyCodec_DecodeText( 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 -------------------------------------------------- +/* --- 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 @@ -201,6 +225,9 @@ 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); +/* replace the unicode encode error with backslash escapes (\N, \x, \u and \U) */ +PyAPI_FUNC(PyObject *) PyCodec_NameReplaceErrors(PyObject *exc); + PyAPI_DATA(const char *) Py_hexdigits; #ifdef __cplusplus diff --git a/Include/compile.h b/Include/compile.h index c6650d7f7768..ecd8dc1d1042 100644 --- a/Include/compile.h +++ b/Include/compile.h @@ -27,6 +27,7 @@ typedef struct { #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" struct _mod; /* Declare the existence of this type */ #define PyAST_Compile(mod, s, f, ar) PyAST_CompileEx(mod, s, f, -1, ar) diff --git a/Include/complexobject.h b/Include/complexobject.h index 1934f3b38078..cb8c52c58008 100644 --- a/Include/complexobject.h +++ b/Include/complexobject.h @@ -14,21 +14,13 @@ typedef struct { /* Operations on complex numbers from complexmodule.c */ -#define c_sum _Py_c_sum -#define c_diff _Py_c_diff -#define c_neg _Py_c_neg -#define c_prod _Py_c_prod -#define c_quot _Py_c_quot -#define c_pow _Py_c_pow -#define c_abs _Py_c_abs - -PyAPI_FUNC(Py_complex) c_sum(Py_complex, Py_complex); -PyAPI_FUNC(Py_complex) c_diff(Py_complex, Py_complex); -PyAPI_FUNC(Py_complex) c_neg(Py_complex); -PyAPI_FUNC(Py_complex) c_prod(Py_complex, Py_complex); -PyAPI_FUNC(Py_complex) c_quot(Py_complex, Py_complex); -PyAPI_FUNC(Py_complex) c_pow(Py_complex, Py_complex); -PyAPI_FUNC(double) c_abs(Py_complex); +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 */ diff --git a/Include/dictobject.h b/Include/dictobject.h index 285966963c3e..80bd33029491 100644 --- a/Include/dictobject.h +++ b/Include/dictobject.h @@ -27,6 +27,11 @@ typedef struct { PyObject **ma_values; } PyDictObject; +typedef struct { + PyObject_HEAD + PyDictObject *dv_dict; +} _PyDictViewObject; + #endif /* Py_LIMITED_API */ PyAPI_DATA(PyTypeObject) PyDict_Type; @@ -40,9 +45,9 @@ PyAPI_DATA(PyTypeObject) PyDictValues_Type; #define PyDict_Check(op) \ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS) #define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type) -#define PyDictKeys_Check(op) (Py_TYPE(op) == &PyDictKeys_Type) -#define PyDictItems_Check(op) (Py_TYPE(op) == &PyDictItems_Type) -#define PyDictValues_Check(op) (Py_TYPE(op) == &PyDictValues_Type) +#define PyDictKeys_Check(op) PyObject_TypeCheck(op, &PyDictKeys_Type) +#define PyDictItems_Check(op) PyObject_TypeCheck(op, &PyDictItems_Type) +#define PyDictValues_Check(op) PyObject_TypeCheck(op, &PyDictValues_Type) /* This excludes Values, since they are not sets. */ # define PyDictViewSet_Check(op) \ (PyDictKeys_Check(op) || PyDictItems_Check(op)) @@ -50,13 +55,27 @@ PyAPI_DATA(PyTypeObject) PyDictValues_Type; PyAPI_FUNC(PyObject *) PyDict_New(void); PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key, + Py_hash_t hash); +#endif PyAPI_FUNC(PyObject *) PyDict_GetItemWithError(PyObject *mp, PyObject *key); PyAPI_FUNC(PyObject *) _PyDict_GetItemIdWithError(PyObject *dp, struct _Py_Identifier *key); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) PyDict_SetDefault( PyObject *mp, PyObject *key, PyObject *defaultobj); +#endif PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item); +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key, + PyObject *item, Py_hash_t hash); +#endif PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key); +#ifndef Py_LIMITED_API +PyAPI_FUNC(int) _PyDict_DelItem_KnownHash(PyObject *mp, PyObject *key, + Py_hash_t hash); +#endif PyAPI_FUNC(void) PyDict_Clear(PyObject *mp); PyAPI_FUNC(int) PyDict_Next( PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value); @@ -65,6 +84,7 @@ 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); +PyObject *_PyDictView_New(PyObject *, PyTypeObject *); #endif PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp); PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp); @@ -78,6 +98,9 @@ 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); +PyObject *_PyDict_SizeOf(PyDictObject *); +PyObject *_PyDict_Pop(PyDictObject *, PyObject *, PyObject *); +PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *); #define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL) PyAPI_FUNC(int) PyDict_ClearFreeList(void); @@ -95,6 +118,10 @@ PyAPI_FUNC(int) PyDict_Merge(PyObject *mp, PyObject *other, int override); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other); +#endif + /* 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) diff --git a/Include/dynamic_annotations.h b/Include/dynamic_annotations.h index d63c5db08576..0bd1a833c2e5 100644 --- a/Include/dynamic_annotations.h +++ b/Include/dynamic_annotations.h @@ -150,7 +150,7 @@ /* 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 a the locking discipline for a variable + 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) diff --git a/Include/fileobject.h b/Include/fileobject.h index 0939744e6d32..03155d3da789 100644 --- a/Include/fileobject.h +++ b/Include/fileobject.h @@ -32,17 +32,6 @@ PyAPI_DATA(int) Py_HasFileSystemDefaultEncoding; #ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) PyFile_NewStdPrinter(int); PyAPI_DATA(PyTypeObject) PyStdPrinter_Type; - -#if defined _MSC_VER && _MSC_VER >= 1400 -/* A routine to check if a file descriptor is valid on Windows. Returns 0 - * and sets errno to EBADF if it isn't. This is to avoid Assertions - * from various functions in the Windows CRT beginning with - * Visual Studio 2005 - */ -int _PyVerify_fd(int fd); -#else -#define _PyVerify_fd(A) (1) /* dummy */ -#endif #endif /* Py_LIMITED_API */ /* A routine to check if a file descriptor can be select()-ed. */ diff --git a/Include/fileutils.h b/Include/fileutils.h index 5466e3c7e0d7..b4a683c176c0 100644 --- a/Include/fileutils.h +++ b/Include/fileutils.h @@ -7,30 +7,61 @@ extern "C" { PyAPI_FUNC(PyObject *) _Py_device_encoding(int); -PyAPI_FUNC(wchar_t *) _Py_char2wchar( +PyAPI_FUNC(wchar_t *) Py_DecodeLocale( const char *arg, size_t *size); -PyAPI_FUNC(char*) _Py_wchar2char( +PyAPI_FUNC(char*) Py_EncodeLocale( const wchar_t *text, size_t *error_pos); -#if defined(HAVE_STAT) && !defined(MS_WINDOWS) -PyAPI_FUNC(int) _Py_wstat( - const wchar_t* path, - struct stat *buf); +#ifndef Py_LIMITED_API + +#ifdef MS_WINDOWS +struct _Py_stat_struct { + unsigned long st_dev; + __int64 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; +}; +#else +# define _Py_stat_struct stat #endif -#ifdef HAVE_STAT +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); +#endif /* Py_LIMITED_API */ + PyAPI_FUNC(int) _Py_stat( PyObject *path, - struct stat *statbuf); -#endif + struct stat *status); +#ifndef Py_LIMITED_API PyAPI_FUNC(int) _Py_open( const char *pathname, int flags); +PyAPI_FUNC(int) _Py_open_noraise( + const char *pathname, + int flags); +#endif + PyAPI_FUNC(FILE *) _Py_wfopen( const wchar_t *path, const wchar_t *mode); @@ -43,6 +74,21 @@ 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, @@ -61,6 +107,7 @@ PyAPI_FUNC(wchar_t*) _Py_wgetcwd( wchar_t *buf, size_t size); +#ifndef Py_LIMITED_API PyAPI_FUNC(int) _Py_get_inheritable(int fd); PyAPI_FUNC(int) _Py_set_inheritable(int fd, int inheritable, @@ -68,6 +115,26 @@ PyAPI_FUNC(int) _Py_set_inheritable(int fd, int inheritable, 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 */ + +#if defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900 +/* A routine to check if a file descriptor is valid on Windows. Returns 0 + * and sets errno to EBADF if it isn't. This is to avoid Assertions + * from various functions in the Windows CRT beginning with + * Visual Studio 2005 + */ +int _PyVerify_fd(int fd); + +#else +#define _PyVerify_fd(A) (1) /* dummy */ +#endif + +#endif /* Py_LIMITED_API */ + #ifdef __cplusplus } #endif diff --git a/Include/frameobject.h b/Include/frameobject.h index b41bea684a5f..966ff1f6e6e3 100644 --- a/Include/frameobject.h +++ b/Include/frameobject.h @@ -39,7 +39,6 @@ typedef struct _frame { /* Borrowed reference to a generator, or NULL */ PyObject *f_gen; - PyThreadState *f_tstate; 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 diff --git a/Include/genobject.h b/Include/genobject.h index 65f1ecfd5495..4c7186172321 100644 --- a/Include/genobject.h +++ b/Include/genobject.h @@ -10,21 +10,26 @@ extern "C" { 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; + typedef struct { - PyObject_HEAD /* The gi_ prefix is intended to remind of generator-iterator. */ - - /* Note: gi_frame can be NULL if the generator is "finished" */ - struct _frame *gi_frame; - - /* True if generator is being executed. */ - char gi_running; - - /* The code object backing the generator */ - PyObject *gi_code; - - /* List of weak reference. */ - PyObject *gi_weakreflist; + _PyGenObject_HEAD(gi) } PyGenObject; PyAPI_DATA(PyTypeObject) PyGen_Type; @@ -33,11 +38,28 @@ PyAPI_DATA(PyTypeObject) 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_FetchStopIterationValue(PyObject **); PyObject *_PyGen_Send(PyGenObject *, PyObject *); PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self); +#ifndef Py_LIMITED_API +typedef struct { + _PyGenObject_HEAD(cr) +} PyCoroObject; + +PyAPI_DATA(PyTypeObject) PyCoro_Type; +PyAPI_DATA(PyTypeObject) _PyCoroWrapper_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); +#endif + +#undef _PyGenObject_HEAD #ifdef __cplusplus } diff --git a/Include/graminit.h b/Include/graminit.h index 3ec949ab462c..d030bc3d293b 100644 --- a/Include/graminit.h +++ b/Include/graminit.h @@ -6,79 +6,82 @@ #define decorator 259 #define decorators 260 #define decorated 261 -#define funcdef 262 -#define parameters 263 -#define typedargslist 264 -#define tfpdef 265 -#define varargslist 266 -#define vfpdef 267 -#define stmt 268 -#define simple_stmt 269 -#define small_stmt 270 -#define expr_stmt 271 -#define testlist_star_expr 272 -#define augassign 273 -#define del_stmt 274 -#define pass_stmt 275 -#define flow_stmt 276 -#define break_stmt 277 -#define continue_stmt 278 -#define return_stmt 279 -#define yield_stmt 280 -#define raise_stmt 281 -#define import_stmt 282 -#define import_name 283 -#define import_from 284 -#define import_as_name 285 -#define dotted_as_name 286 -#define import_as_names 287 -#define dotted_as_names 288 -#define dotted_name 289 -#define global_stmt 290 -#define nonlocal_stmt 291 -#define assert_stmt 292 -#define compound_stmt 293 -#define if_stmt 294 -#define while_stmt 295 -#define for_stmt 296 -#define try_stmt 297 -#define with_stmt 298 -#define with_item 299 -#define except_clause 300 -#define suite 301 -#define test 302 -#define test_nocond 303 -#define lambdef 304 -#define lambdef_nocond 305 -#define or_test 306 -#define and_test 307 -#define not_test 308 -#define comparison 309 -#define comp_op 310 -#define star_expr 311 -#define expr 312 -#define xor_expr 313 -#define and_expr 314 -#define shift_expr 315 -#define arith_expr 316 -#define term 317 -#define factor 318 -#define power 319 -#define atom 320 -#define testlist_comp 321 -#define trailer 322 -#define subscriptlist 323 -#define subscript 324 -#define sliceop 325 -#define exprlist 326 -#define testlist 327 -#define dictorsetmaker 328 -#define classdef 329 -#define arglist 330 -#define argument 331 -#define comp_iter 332 -#define comp_for 333 -#define comp_if 334 -#define encoding_decl 335 -#define yield_expr 336 -#define yield_arg 337 +#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 testlist_star_expr 273 +#define augassign 274 +#define del_stmt 275 +#define pass_stmt 276 +#define flow_stmt 277 +#define break_stmt 278 +#define continue_stmt 279 +#define return_stmt 280 +#define yield_stmt 281 +#define raise_stmt 282 +#define import_stmt 283 +#define import_name 284 +#define import_from 285 +#define import_as_name 286 +#define dotted_as_name 287 +#define import_as_names 288 +#define dotted_as_names 289 +#define dotted_name 290 +#define global_stmt 291 +#define nonlocal_stmt 292 +#define assert_stmt 293 +#define compound_stmt 294 +#define async_stmt 295 +#define if_stmt 296 +#define while_stmt 297 +#define for_stmt 298 +#define try_stmt 299 +#define with_stmt 300 +#define with_item 301 +#define except_clause 302 +#define suite 303 +#define test 304 +#define test_nocond 305 +#define lambdef 306 +#define lambdef_nocond 307 +#define or_test 308 +#define and_test 309 +#define not_test 310 +#define comparison 311 +#define comp_op 312 +#define star_expr 313 +#define expr 314 +#define xor_expr 315 +#define and_expr 316 +#define shift_expr 317 +#define arith_expr 318 +#define term 319 +#define factor 320 +#define power 321 +#define atom_expr 322 +#define atom 323 +#define testlist_comp 324 +#define trailer 325 +#define subscriptlist 326 +#define subscript 327 +#define sliceop 328 +#define exprlist 329 +#define testlist 330 +#define dictorsetmaker 331 +#define classdef 332 +#define arglist 333 +#define argument 334 +#define comp_iter 335 +#define comp_for 336 +#define comp_if 337 +#define encoding_decl 338 +#define yield_expr 339 +#define yield_arg 340 diff --git a/Include/grammar.h b/Include/grammar.h index ba7d19d821b6..85120b9be963 100644 --- a/Include/grammar.h +++ b/Include/grammar.h @@ -37,7 +37,7 @@ typedef struct { typedef struct { int s_narcs; arc *s_arc; /* Array of arcs */ - + /* Optional accelerators */ int s_lower; /* Lowest label index */ int s_upper; /* Highest label index */ diff --git a/Include/import.h b/Include/import.h index 4a515d5b6be9..afdfac2a938f 100644 --- a/Include/import.h +++ b/Include/import.h @@ -86,15 +86,15 @@ PyAPI_FUNC(int) _PyImport_ReleaseLock(void); PyAPI_FUNC(void) _PyImport_ReInitLock(void); -PyAPI_FUNC(PyObject *)_PyImport_FindBuiltin( +PyAPI_FUNC(PyObject *) _PyImport_FindBuiltin( const char *name /* UTF-8 encoded string */ ); -PyAPI_FUNC(PyObject *)_PyImport_FindExtensionObject(PyObject *, PyObject *); -PyAPI_FUNC(int)_PyImport_FixupBuiltin( +PyAPI_FUNC(PyObject *) _PyImport_FindExtensionObject(PyObject *, PyObject *); +PyAPI_FUNC(int) _PyImport_FixupBuiltin( PyObject *mod, const char *name /* UTF-8 encoded string */ ); -PyAPI_FUNC(int)_PyImport_FixupExtensionObject(PyObject*, PyObject *, PyObject *); +PyAPI_FUNC(int) _PyImport_FixupExtensionObject(PyObject*, PyObject *, PyObject *); struct _inittab { const char *name; /* ASCII encoded string */ diff --git a/Include/listobject.h b/Include/listobject.h index dc62aee91a59..daa513f1514b 100644 --- a/Include/listobject.h +++ b/Include/listobject.h @@ -46,7 +46,7 @@ PyAPI_DATA(PyTypeObject) PyListRevIter_Type; PyAPI_DATA(PyTypeObject) PySortWrapper_Type; #define PyList_Check(op) \ - PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS) + 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); @@ -72,6 +72,7 @@ PyAPI_FUNC(void) _PyList_DebugMallocStats(FILE *out); #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) Py_SIZE(op) +#define _PyList_ITEMS(op) (((PyListObject *)(op))->ob_item) #endif #ifdef __cplusplus diff --git a/Include/longobject.h b/Include/longobject.h index 7c3f6d02d5c7..eaf7a7edfc1a 100644 --- a/Include/longobject.h +++ b/Include/longobject.h @@ -65,7 +65,8 @@ PyAPI_FUNC(PyObject *) PyLong_GetInfo(void); # error "void* different in size from int, long and long long" #endif /* SIZEOF_VOID_P */ -/* Used by Python/mystrtoul.c. */ +/* Used by Python/mystrtoul.c, _PyBytes_FromHex(), + _PyBytes_DecodeEscapeRecode(), etc. */ #ifndef Py_LIMITED_API PyAPI_DATA(unsigned char) _PyLong_DigitValue[256]; #endif @@ -165,6 +166,12 @@ 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(PyLongObject *)_PyLong_FromNbInt(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. */ @@ -176,6 +183,13 @@ PyAPI_FUNC(int) _PyLong_FormatWriter( 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( @@ -192,6 +206,9 @@ PyAPI_FUNC(int) _PyLong_FormatAdvancedWriter( PyAPI_FUNC(unsigned long) PyOS_strtoul(const char *, char **, int); PyAPI_FUNC(long) PyOS_strtol(const char *, char **, int); +/* For use by the gcd function in mathmodule.c */ +PyAPI_FUNC(PyObject *) _PyLong_GCD(PyObject *, PyObject *); + #ifdef __cplusplus } #endif diff --git a/Include/memoryobject.h b/Include/memoryobject.h index c2e11944467b..ab5ee0956c6e 100644 --- a/Include/memoryobject.h +++ b/Include/memoryobject.h @@ -45,9 +45,6 @@ typedef struct { } _PyManagedBufferObject; -/* static storage used for casting between formats */ -#define _Py_MEMORYVIEW_MAX_FORMAT 3 /* must be >= 3 */ - /* memoryview state flags */ #define _Py_MEMORYVIEW_RELEASED 0x001 /* access to master buffer blocked */ #define _Py_MEMORYVIEW_C 0x002 /* C-contiguous layout */ @@ -62,7 +59,6 @@ typedef struct { int flags; /* state flags */ Py_ssize_t exports; /* number of buffer re-exports */ Py_buffer view; /* private copy of the exporter's view */ - char format[_Py_MEMORYVIEW_MAX_FORMAT]; /* used for casting */ PyObject *weakreflist; Py_ssize_t ob_array[1]; /* shape, strides, suboffsets */ } PyMemoryViewObject; diff --git a/Include/methodobject.h b/Include/methodobject.h index 3cc2ea9308f5..e2ad80440b0e 100644 --- a/Include/methodobject.h +++ b/Include/methodobject.h @@ -47,7 +47,7 @@ struct PyMethodDef { typedef struct PyMethodDef PyMethodDef; #define PyCFunction_New(ML, SELF) PyCFunction_NewEx((ML), (SELF), NULL) -PyAPI_FUNC(PyObject *) PyCFunction_NewEx(PyMethodDef *, PyObject *, +PyAPI_FUNC(PyObject *) PyCFunction_NewEx(PyMethodDef *, PyObject *, PyObject *); /* Flag passed to newmethodobject */ @@ -66,7 +66,7 @@ PyAPI_FUNC(PyObject *) PyCFunction_NewEx(PyMethodDef *, PyObject *, /* 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 + method, "__contains__" for example, to coexist with a defined slot like sq_contains. */ #define METH_COEXIST 0x0040 @@ -77,6 +77,7 @@ typedef struct { 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 */ } PyCFunctionObject; #endif diff --git a/Include/modsupport.h b/Include/modsupport.h index ab725f612aca..829aaf859683 100644 --- a/Include/modsupport.h +++ b/Include/modsupport.h @@ -12,13 +12,13 @@ extern "C" { /* 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 +#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 #else PyAPI_FUNC(PyObject *) _Py_VaBuildValue_SizeT(const char *, va_list); #endif @@ -36,6 +36,7 @@ PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...); #endif #ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyArg_NoKeywords(const char *funcname, PyObject *kw); +PyAPI_FUNC(int) _PyArg_NoPositional(const char *funcname, PyObject *args); PyAPI_FUNC(int) PyArg_VaParse(PyObject *, const char *, va_list); PyAPI_FUNC(int) PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *, @@ -49,6 +50,13 @@ 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 @@ -66,35 +74,35 @@ PyAPI_FUNC(int) PyModule_AddStringConstant(PyObject *, const char *, const char 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 + 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. + 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 + 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-Jan-1999 GvR 1007 Decided to change back! (Don't reuse 1008!) - 3-Dec-1998 GvR 1008 Python 1.5.2b1 + 3-Dec-1998 GvR 1008 Python 1.5.2b1 - 18-Jan-1997 GvR 1007 string interning and other speedups + 18-Jan-1997 GvR 1007 string interning and other speedups - 11-Oct-1996 GvR renamed Py_Ellipses to Py_Ellipsis :-( + 11-Oct-1996 GvR renamed Py_Ellipses to Py_Ellipsis :-( - 30-Jul-1996 GvR Slice and ellipses syntax added + 30-Jul-1996 GvR Slice and ellipses syntax added - 23-Jul-1996 GvR For 1.4 -- better safe than sorry this time :-) + 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 :-( ) + 7-Nov-1995 GvR Keyword arguments (should've been done at 1.3 :-( ) - 10-Jan-1995 GvR Renamed globals to new naming scheme + 10-Jan-1995 GvR Renamed globals to new naming scheme - 9-Jan-1995 GvR Initial version (incompatible with older API) + 9-Jan-1995 GvR Initial version (incompatible with older API) */ /* The PYTHON_ABI_VERSION is introduced in PEP 384. For the lifetime of @@ -104,10 +112,11 @@ PyAPI_FUNC(int) PyModule_AddStringConstant(PyObject *, const char *, const char #define PYTHON_ABI_STRING "3" #ifdef Py_TRACE_REFS - /* When we are tracing reference counts, rename PyModule_Create2 so + /* 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*, @@ -115,12 +124,27 @@ PyAPI_FUNC(PyObject *) PyModule_Create2(struct PyModuleDef*, #ifdef Py_LIMITED_API #define PyModule_Create(module) \ - PyModule_Create2(module, PYTHON_ABI_VERSION) + PyModule_Create2(module, PYTHON_ABI_VERSION) #else #define PyModule_Create(module) \ - PyModule_Create2(module, PYTHON_API_VERSION) + 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(char *) _Py_PackageContext; #endif diff --git a/Include/moduleobject.h b/Include/moduleobject.h index 8013dd9b484a..229d7fadc244 100644 --- a/Include/moduleobject.h +++ b/Include/moduleobject.h @@ -25,10 +25,17 @@ 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 *); #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); @@ -43,19 +50,35 @@ typedef struct PyModuleDef_Base { 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; - inquiry m_reload; + struct PyModuleDef_Slot* m_slots; traverseproc m_traverse; inquiry m_clear; freefunc m_free; }PyModuleDef; - #ifdef __cplusplus } #endif diff --git a/Include/node.h b/Include/node.h index 99c13f7dc906..654ad8582301 100644 --- a/Include/node.h +++ b/Include/node.h @@ -21,12 +21,12 @@ PyAPI_FUNC(int) PyNode_AddChild(node *n, int type, char *str, int lineno, int col_offset); PyAPI_FUNC(void) PyNode_Free(node *n); #ifndef Py_LIMITED_API -Py_ssize_t _PyNode_SizeOf(node *n); +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) diff --git a/Include/object.h b/Include/object.h index f5396524c00f..4d286efe34de 100644 --- a/Include/object.h +++ b/Include/object.h @@ -65,6 +65,7 @@ whose size is determined when the object is allocated. #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 \ @@ -275,6 +276,9 @@ typedef struct { binaryfunc nb_inplace_true_divide; unaryfunc nb_index; + + binaryfunc nb_matrix_multiply; + binaryfunc nb_inplace_matrix_multiply; } PyNumberMethods; typedef struct { @@ -297,6 +301,11 @@ typedef struct { objobjargproc mp_ass_subscript; } PyMappingMethods; +typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; +} PyAsyncMethods; typedef struct { getbufferproc bf_getbuffer; @@ -342,7 +351,8 @@ typedef struct _typeobject { printfunc tp_print; getattrfunc tp_getattr; setattrfunc tp_setattr; - void *tp_reserved; /* formerly known as tp_compare */ + PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2) + or tp_reserved (Python 3) */ reprfunc tp_repr; /* Method suites for standard classes */ @@ -439,6 +449,9 @@ 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(PyTypeObject*, int); +#endif #ifndef Py_LIMITED_API /* The *real* layout of a type object when allocated on the heap */ @@ -446,6 +459,7 @@ 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, @@ -492,6 +506,11 @@ PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject * PyAPI_FUNC(unsigned int) PyType_ClearCache(void); PyAPI_FUNC(void) PyType_Modified(PyTypeObject *); +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyType_GetDocFromInternalDoc(const char *, const char *); +PyAPI_FUNC(PyObject *) _PyType_GetTextSignatureFromInternalDoc(const char *, const char *); +#endif + /* Generic operations on objects */ struct _Py_Identifier; #ifndef Py_LIMITED_API @@ -533,8 +552,10 @@ PyAPI_FUNC(int) PyObject_Not(PyObject *); PyAPI_FUNC(int) PyCallable_Check(PyObject *); PyAPI_FUNC(void) PyObject_ClearWeakRefs(PyObject *); +#ifndef Py_LIMITED_API PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *); PyAPI_FUNC(int) PyObject_CallFinalizerFromDealloc(PyObject *); +#endif /* Same as PyObject_Generic{Get,Set}Attr, but passing the attributes dict as the last parameter. */ @@ -562,9 +583,6 @@ PyAPI_FUNC(PyObject *) PyObject_Dir(PyObject *); PyAPI_FUNC(int) Py_ReprEnter(PyObject *); PyAPI_FUNC(void) Py_ReprLeave(PyObject *); -/* Helper for passing objects to printf and the like */ -#define PyObject_REPR(obj) _PyUnicode_AsString(PyObject_Repr(obj)) - /* Flag bits for printing: */ #define Py_PRINT_RAW 1 /* No string quotes etc. */ @@ -700,11 +718,17 @@ PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void); _Py_NegativeRefcount(__FILE__, __LINE__, \ (PyObject *)(OP)); \ } +/* 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); +#define _PY_DEBUG_PRINT_TOTAL_REFS() _PyDebug_PrintTotalRefs() #else #define _Py_INC_REFTOTAL #define _Py_DEC_REFTOTAL #define _Py_REF_DEBUG_COMMA #define _Py_CHECK_REFCNT(OP) /* a semicolon */; +#define _PY_DEBUG_PRINT_TOTAL_REFS() #endif /* Py_REF_DEBUG */ #ifdef COUNT_ALLOCS @@ -765,7 +789,7 @@ PyAPI_FUNC(void) _Py_Dealloc(PyObject *); } while (0) /* Safely decref `op` and set `op` to NULL, especially useful in tp_clear - * and tp_dealloc implementatons. + * and tp_dealloc implementations. * * Note that "the obvious" code can be deadly: * diff --git a/Include/objimpl.h b/Include/objimpl.h index 9a27ec384f9f..65b6d91c36ca 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -95,6 +95,7 @@ PyObject_{New, NewVar, Del}. the raw memory. */ PyAPI_FUNC(void *) PyObject_Malloc(size_t size); +PyAPI_FUNC(void *) PyObject_Calloc(size_t nelem, size_t elsize); PyAPI_FUNC(void *) PyObject_Realloc(void *ptr, size_t new_size); PyAPI_FUNC(void) PyObject_Free(void *ptr); @@ -265,7 +266,7 @@ extern PyGC_Head *_PyGC_generation0; #define _PyGCHead_REFS(g) ((g)->gc.gc_refs >> _PyGC_REFS_SHIFT) #define _PyGCHead_SET_REFS(g, v) do { \ (g)->gc.gc_refs = ((g)->gc.gc_refs & ~_PyGC_REFS_MASK) \ - | (v << _PyGC_REFS_SHIFT); \ + | (((size_t)(v)) << _PyGC_REFS_SHIFT); \ } while (0) #define _PyGCHead_DECREF(g) ((g)->gc.gc_refs -= 1 << _PyGC_REFS_SHIFT) @@ -321,7 +322,8 @@ extern PyGC_Head *_PyGC_generation0; (!PyTuple_CheckExact(obj) || _PyObject_GC_IS_TRACKED(obj))) #endif /* Py_LIMITED_API */ -PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t); +PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t size); +PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size); PyAPI_FUNC(PyObject *) _PyObject_GC_New(PyTypeObject *); PyAPI_FUNC(PyVarObject *) _PyObject_GC_NewVar(PyTypeObject *, Py_ssize_t); PyAPI_FUNC(void) PyObject_GC_Track(void *); diff --git a/Include/odictobject.h b/Include/odictobject.h new file mode 100644 index 000000000000..c1d9592a1db8 --- /dev/null +++ b/Include/odictobject.h @@ -0,0 +1,43 @@ +#ifndef Py_ODICTOBJECT_H +#define Py_ODICTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* OrderedDict */ + +#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; + +#endif /* Py_LIMITED_API */ + +#define PyODict_Check(op) PyObject_TypeCheck(op, &PyODict_Type) +#define PyODict_CheckExact(op) (Py_TYPE(op) == &PyODict_Type) +#define PyODict_SIZE(op) ((PyDictObject *)op)->ma_used +#define PyODict_HasKey(od, key) (PyMapping_HasKey(PyObject *)od, key) + +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 *)od, key) +#define PyODict_GetItemWithError(od, key) \ + PyDict_GetItemWithError((PyObject *)od, key) +#define PyODict_Contains(od, key) PyDict_Contains((PyObject *)od, key) +#define PyODict_Size(od) PyDict_Size((PyObject *)od) +#define PyODict_GetItemString(od, key) \ + PyDict_GetItemString((PyObject *)od, key) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_ODICTOBJECT_H */ diff --git a/Include/opcode.h b/Include/opcode.h index 0936f2d9f421..3f917fb6ee50 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -1,3 +1,4 @@ +/* Auto-generated by Tools/scripts/generate_opcode_h.py */ #ifndef Py_OPCODE_H #define Py_OPCODE_H #ifdef __cplusplus @@ -5,141 +6,122 @@ 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 NOP 9 - -#define UNARY_POSITIVE 10 -#define UNARY_NEGATIVE 11 -#define UNARY_NOT 12 - -#define UNARY_INVERT 15 - -#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 STORE_MAP 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 PRINT_EXPR 70 -#define LOAD_BUILD_CLASS 71 -#define YIELD_FROM 72 - -#define INPLACE_LSHIFT 75 -#define INPLACE_RSHIFT 76 -#define INPLACE_AND 77 -#define INPLACE_XOR 78 -#define INPLACE_OR 79 -#define BREAK_LOOP 80 -#define WITH_CLEANUP 81 - -#define RETURN_VALUE 83 -#define IMPORT_STAR 84 - -#define YIELD_VALUE 86 -#define POP_BLOCK 87 -#define END_FINALLY 88 -#define POP_EXCEPT 89 - -#define HAVE_ARGUMENT 90 /* Opcodes from here have an argument: */ - -#define STORE_NAME 90 /* Index in name list */ -#define DELETE_NAME 91 /* "" */ -#define UNPACK_SEQUENCE 92 /* Number of sequence items */ -#define FOR_ITER 93 -#define UNPACK_EX 94 /* Num items before variable part + - (Num items after variable part << 8) */ - -#define STORE_ATTR 95 /* Index in name list */ -#define DELETE_ATTR 96 /* "" */ -#define STORE_GLOBAL 97 /* "" */ -#define DELETE_GLOBAL 98 /* "" */ - -#define LOAD_CONST 100 /* Index in const list */ -#define LOAD_NAME 101 /* Index in name list */ -#define BUILD_TUPLE 102 /* Number of tuple items */ -#define BUILD_LIST 103 /* Number of list items */ -#define BUILD_SET 104 /* Number of set items */ -#define BUILD_MAP 105 /* Always zero for now */ -#define LOAD_ATTR 106 /* Index in name list */ -#define COMPARE_OP 107 /* Comparison operator */ -#define IMPORT_NAME 108 /* Index in name list */ -#define IMPORT_FROM 109 /* Index in name list */ - -#define JUMP_FORWARD 110 /* Number of bytes to skip */ -#define JUMP_IF_FALSE_OR_POP 111 /* Target byte offset from beginning of code */ -#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 /* Index in name list */ - -#define CONTINUE_LOOP 119 /* Start of loop (absolute) */ -#define SETUP_LOOP 120 /* Target address (relative) */ -#define SETUP_EXCEPT 121 /* "" */ -#define SETUP_FINALLY 122 /* "" */ - -#define LOAD_FAST 124 /* Local variable number */ -#define STORE_FAST 125 /* Local variable number */ -#define DELETE_FAST 126 /* Local variable number */ - -#define RAISE_VARARGS 130 /* Number of raise arguments (1, 2 or 3) */ -/* CALL_FUNCTION_XXX opcodes defined below depend on this definition */ -#define CALL_FUNCTION 131 /* #args + (#kwargs<<8) */ -#define MAKE_FUNCTION 132 /* #defaults + #kwdefaults<<8 + #annotations<<16 */ -#define BUILD_SLICE 133 /* Number of items */ - -#define MAKE_CLOSURE 134 /* same as MAKE_FUNCTION */ -#define LOAD_CLOSURE 135 /* Load free variable from closure */ -#define LOAD_DEREF 136 /* Load and dereference from closure cell */ -#define STORE_DEREF 137 /* Store into cell */ -#define DELETE_DEREF 138 /* Delete closure cell */ - -/* The next 3 opcodes must be contiguous and satisfy - (CALL_FUNCTION_VAR - CALL_FUNCTION) & 3 == 1 */ -#define CALL_FUNCTION_VAR 140 /* #args + (#kwargs<<8) */ -#define CALL_FUNCTION_KW 141 /* #args + (#kwargs<<8) */ -#define CALL_FUNCTION_VAR_KW 142 /* #args + (#kwargs<<8) */ - -#define SETUP_WITH 143 - -/* Support for opargs more than 16 bits long */ -#define EXTENDED_ARG 144 - -#define LIST_APPEND 145 -#define SET_ADD 146 -#define MAP_ADD 147 - -#define LOAD_CLASSDEREF 148 + /* 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 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 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 BREAK_LOOP 80 +#define WITH_CLEANUP_START 81 +#define WITH_CLEANUP_FINISH 82 +#define RETURN_VALUE 83 +#define IMPORT_STAR 84 +#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 CONTINUE_LOOP 119 +#define SETUP_LOOP 120 +#define SETUP_EXCEPT 121 +#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 MAKE_CLOSURE 134 +#define LOAD_CLOSURE 135 +#define LOAD_DEREF 136 +#define STORE_DEREF 137 +#define DELETE_DEREF 138 +#define CALL_FUNCTION_VAR 140 +#define CALL_FUNCTION_KW 141 +#define CALL_FUNCTION_VAR_KW 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 /* 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 @@ -148,8 +130,9 @@ extern "C" { #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}; +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) diff --git a/Include/osdefs.h b/Include/osdefs.h index 0c2e34b87957..bd84c1c12c19 100644 --- a/Include/osdefs.h +++ b/Include/osdefs.h @@ -7,15 +7,12 @@ extern "C" { /* Operating system dependencies */ -/* Mod by chrish: QNX has WATCOM, but isn't DOS */ -#if !defined(__QNX__) -#if defined(MS_WINDOWS) || defined(__BORLANDC__) || defined(__WATCOMC__) || defined(__DJGPP__) +#ifdef MS_WINDOWS #define SEP L'\\' #define ALTSEP L'/' #define MAXPATHLEN 256 #define DELIM L';' #endif -#endif /* Filename separator */ #ifndef SEP diff --git a/Include/patchlevel.h b/Include/patchlevel.h index e6c98e4ae5d2..246eba8c97a2 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -17,13 +17,13 @@ /* Version parsed out into numeric values */ /*--start constants--*/ #define PY_MAJOR_VERSION 3 -#define PY_MINOR_VERSION 4 +#define PY_MINOR_VERSION 6 #define PY_MICRO_VERSION 0 -#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_BETA -#define PY_RELEASE_SERIAL 1 +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA +#define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.4.0b1" +#define PY_VERSION "3.6.0a0" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Include/pyatomic.h b/Include/pyatomic.h index d4e19e0070be..892a217d3489 100644 --- a/Include/pyatomic.h +++ b/Include/pyatomic.h @@ -1,14 +1,13 @@ -#ifndef Py_LIMITED_API #ifndef Py_ATOMIC_H #define Py_ATOMIC_H -/* XXX: When compilers start offering a stdatomic.h with lock-free - atomic_int and atomic_address types, include that here and rewrite - the atomic operations in terms of it. */ +#ifdef Py_BUILD_CORE #include "dynamic_annotations.h" -#ifdef __cplusplus -extern "C" { +#include "pyconfig.h" + +#if defined(HAVE_STD_ATOMIC) +#include <stdatomic.h> #endif /* This is modeled after the atomics interface from C1x, according to @@ -20,6 +19,76 @@ extern "C" { * 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 void *_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 { + void *_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)) + +#else + typedef enum _Py_memory_order { _Py_memory_order_relaxed, _Py_memory_order_acquire, @@ -162,6 +231,7 @@ _Py_ANNOTATE_MEMORY_ORDER(const volatile void *address, _Py_memory_order order) ((ATOMIC_VAL)->_value) #endif /* !gcc x86 */ +#endif /* Standardized shortcuts. */ #define _Py_atomic_store(ATOMIC_VAL, NEW_VAL) \ @@ -176,9 +246,5 @@ _Py_ANNOTATE_MEMORY_ORDER(const volatile void *address, _Py_memory_order order) #define _Py_atomic_load_relaxed(ATOMIC_VAL) \ _Py_atomic_load_explicit(ATOMIC_VAL, _Py_memory_order_relaxed) -#ifdef __cplusplus -} -#endif - +#endif /* Py_BUILD_CORE */ #endif /* Py_ATOMIC_H */ -#endif /* Py_LIMITED_API */ diff --git a/Include/pydebug.h b/Include/pydebug.h index 8fe98183f9ef..19bec2bd81bc 100644 --- a/Include/pydebug.h +++ b/Include/pydebug.h @@ -5,6 +5,8 @@ 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; diff --git a/Include/pyerrors.h b/Include/pyerrors.h index 6a8e0e810e36..35aedb734920 100644 --- a/Include/pyerrors.h +++ b/Include/pyerrors.h @@ -53,6 +53,7 @@ typedef struct { PyObject *myerrno; PyObject *strerror; PyObject *filename; + PyObject *filename2; #ifdef MS_WINDOWS PyObject *winerror; #endif @@ -75,7 +76,9 @@ typedef PyOSErrorObject PyWindowsErrorObject; PyAPI_FUNC(void) PyErr_SetNone(PyObject *); PyAPI_FUNC(void) PyErr_SetObject(PyObject *, PyObject *); +#ifndef Py_LIMITED_API PyAPI_FUNC(void) _PyErr_SetKeyError(PyObject *); +#endif PyAPI_FUNC(void) PyErr_SetString( PyObject *exception, const char *string /* decoded from utf-8 */ @@ -96,6 +99,7 @@ PyAPI_FUNC(void) PyErr_SetExcInfo(PyObject *, PyObject *, PyObject *); #define _Py_NO_RETURN #endif +/* Defined in Python/pylifecycle.c */ PyAPI_FUNC(void) Py_FatalError(const char *message) _Py_NO_RETURN; #if defined(Py_DEBUG) || defined(Py_LIMITED_API) @@ -120,7 +124,9 @@ PyAPI_FUNC(void) PyException_SetCause(PyObject *, PyObject *); /* Context manipulation (PEP 3134) */ PyAPI_FUNC(PyObject *) PyException_GetContext(PyObject *); PyAPI_FUNC(void) PyException_SetContext(PyObject *, PyObject *); - +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *); +#endif /* */ @@ -141,6 +147,7 @@ PyAPI_FUNC(void) PyException_SetContext(PyObject *, PyObject *); PyAPI_DATA(PyObject *) PyExc_BaseException; PyAPI_DATA(PyObject *) PyExc_Exception; +PyAPI_DATA(PyObject *) PyExc_StopAsyncIteration; PyAPI_DATA(PyObject *) PyExc_StopIteration; PyAPI_DATA(PyObject *) PyExc_GeneratorExit; PyAPI_DATA(PyObject *) PyExc_ArithmeticError; @@ -160,6 +167,7 @@ PyAPI_DATA(PyObject *) PyExc_MemoryError; PyAPI_DATA(PyObject *) PyExc_NameError; PyAPI_DATA(PyObject *) PyExc_OverflowError; PyAPI_DATA(PyObject *) PyExc_RuntimeError; +PyAPI_DATA(PyObject *) PyExc_RecursionError; PyAPI_DATA(PyObject *) PyExc_NotImplementedError; PyAPI_DATA(PyObject *) PyExc_SyntaxError; PyAPI_DATA(PyObject *) PyExc_IndentationError; @@ -199,9 +207,6 @@ PyAPI_DATA(PyObject *) PyExc_IOError; #ifdef MS_WINDOWS PyAPI_DATA(PyObject *) PyExc_WindowsError; #endif -#ifdef __VMS -PyAPI_DATA(PyObject *) PyExc_VMSError; -#endif PyAPI_DATA(PyObject *) PyExc_RecursionErrorInst; @@ -226,6 +231,8 @@ PyAPI_FUNC(PyObject *) PyErr_NoMemory(void); PyAPI_FUNC(PyObject *) PyErr_SetFromErrno(PyObject *); PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilenameObject( PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilenameObjects( + PyObject *, PyObject *, PyObject *); PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilename( PyObject *exc, const char *filename /* decoded from the filesystem encoding */ @@ -240,6 +247,12 @@ PyAPI_FUNC(PyObject *) PyErr_Format( 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( @@ -254,6 +267,8 @@ PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithUnicodeFilename( PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErr(int); PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilenameObject( PyObject *,int, PyObject *); +PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilenameObjects( + PyObject *,int, PyObject *, PyObject *); PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilename( PyObject *exc, int ierr, @@ -324,16 +339,20 @@ PyAPI_FUNC(void) PyErr_SyntaxLocationEx( const char *filename, /* decoded from the filesystem encoding */ int lineno, int col_offset); +#ifndef Py_LIMITED_API PyAPI_FUNC(void) PyErr_SyntaxLocationObject( PyObject *filename, int lineno, int col_offset); +#endif PyAPI_FUNC(PyObject *) PyErr_ProgramText( const char *filename, /* decoded from the filesystem encoding */ int lineno); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) PyErr_ProgramTextObject( PyObject *filename, int lineno); +#endif /* The following functions are used to create and modify unicode exceptions from C */ diff --git a/Include/pyhash.h b/Include/pyhash.h index 83c928137baf..a7ca93758c35 100644 --- a/Include/pyhash.h +++ b/Include/pyhash.h @@ -50,6 +50,7 @@ PyAPI_FUNC(Py_hash_t) _Py_HashBytes(const void*, Py_ssize_t); * (*) 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]; @@ -76,6 +77,7 @@ typedef union { } expat; } _Py_HashSecret_t; PyAPI_DATA(_Py_HashSecret_t) _Py_HashSecret; +#endif #ifdef Py_DEBUG PyAPI_DATA(int) _Py_HashSecret_Initialized; diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h new file mode 100644 index 000000000000..ccdebe26a488 --- /dev/null +++ b/Include/pylifecycle.h @@ -0,0 +1,124 @@ + +/* Interfaces to configure, query, create & destroy the Python runtime */ + +#ifndef Py_PYLIFECYCLE_H +#define Py_PYLIFECYCLE_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(void) Py_SetProgramName(wchar_t *); +PyAPI_FUNC(wchar_t *) Py_GetProgramName(void); + +PyAPI_FUNC(void) Py_SetPythonHome(wchar_t *); +PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void); + +#ifndef Py_LIMITED_API +/* 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); +#endif + +PyAPI_FUNC(void) Py_Initialize(void); +PyAPI_FUNC(void) Py_InitializeEx(int); +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _Py_InitializeEx_Private(int, int); +#endif +PyAPI_FUNC(void) Py_Finalize(void); +PyAPI_FUNC(int) Py_IsInitialized(void); +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. + */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _Py_PyAtExit(void (*func)(void)); +#endif +PyAPI_FUNC(int) Py_AtExit(void (*func)(void)); + +PyAPI_FUNC(void) Py_Exit(int); + +/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _Py_RestoreSignals(void); + +PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *); +#endif + +/* Bootstrap __main__ (defined in Modules/main.c) */ +PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv); + +/* In getpath.c */ +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(); +#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); +#ifndef Py_LIMITED_API +PyAPI_FUNC(const char *) _Py_hgidentifier(void); +PyAPI_FUNC(const char *) _Py_hgversion(void); +#endif + +/* Internal -- various one-time initializations */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(PyObject *) _PyBuiltin_Init(void); +PyAPI_FUNC(PyObject *) _PySys_Init(void); +PyAPI_FUNC(void) _PyImport_Init(void); +PyAPI_FUNC(void) _PyExc_Init(PyObject * bltinmod); +PyAPI_FUNC(void) _PyImportHooks_Init(void); +PyAPI_FUNC(int) _PyFrame_Init(void); +PyAPI_FUNC(int) _PyFloat_Init(void); +PyAPI_FUNC(int) PyByteArray_Init(void); +PyAPI_FUNC(void) _PyRandom_Init(void); +#endif + +/* Various internal finalizers */ +#ifndef Py_LIMITED_API +PyAPI_FUNC(void) _PyExc_Fini(void); +PyAPI_FUNC(void) _PyImport_Fini(void); +PyAPI_FUNC(void) PyMethod_Fini(void); +PyAPI_FUNC(void) PyFrame_Fini(void); +PyAPI_FUNC(void) PyCFunction_Fini(void); +PyAPI_FUNC(void) PyDict_Fini(void); +PyAPI_FUNC(void) PyTuple_Fini(void); +PyAPI_FUNC(void) PyList_Fini(void); +PyAPI_FUNC(void) PySet_Fini(void); +PyAPI_FUNC(void) PyBytes_Fini(void); +PyAPI_FUNC(void) PyByteArray_Fini(void); +PyAPI_FUNC(void) PyFloat_Fini(void); +PyAPI_FUNC(void) PyOS_FiniInterrupts(void); +PyAPI_FUNC(void) _PyGC_DumpShutdownStats(void); +PyAPI_FUNC(void) _PyGC_Fini(void); +PyAPI_FUNC(void) PySlice_Fini(void); +PyAPI_FUNC(void) _PyType_Fini(void); +PyAPI_FUNC(void) _PyRandom_Fini(void); + +PyAPI_DATA(PyThreadState *) _Py_Finalizing; +#endif + +/* 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); + +/* Random */ +PyAPI_FUNC(int) _PyOS_URandom (void *buffer, Py_ssize_t size); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYLIFECYCLE_H */ diff --git a/Include/pymacro.h b/Include/pymacro.h index 793f67dce9c6..3f6f5dce6128 100644 --- a/Include/pymacro.h +++ b/Include/pymacro.h @@ -1,13 +1,26 @@ #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) + /* 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 @@ -69,4 +82,10 @@ /* Check if pointer "p" is aligned to "a"-bytes boundary. */ #define _Py_IS_ALIGNED(p, a) (!((Py_uintptr_t)(p) & (Py_uintptr_t)((a) - 1))) +#ifdef __GNUC__ +#define Py_UNUSED(name) _unused_ ## name __attribute__((unused)) +#else +#define Py_UNUSED(name) _unused_ ## name +#endif + #endif /* Py_PYMACRO_H */ diff --git a/Include/pymath.h b/Include/pymath.h index 62a6c42bbf07..1ea9ac1437a0 100644 --- a/Include/pymath.h +++ b/Include/pymath.h @@ -150,7 +150,29 @@ PyAPI_FUNC(void) _Py_set_387controlword(unsigned short); * doesn't support NaNs. */ #if !defined(Py_NAN) && !defined(Py_NO_NAN) -#define Py_NAN (Py_HUGE_VAL * 0.) +#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 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) diff --git a/Include/pymem.h b/Include/pymem.h index 83f1537f3f55..043db64deb89 100644 --- a/Include/pymem.h +++ b/Include/pymem.h @@ -11,9 +11,12 @@ extern "C" { #endif +#ifndef Py_LIMITED_API 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); +#endif /* BEWARE: @@ -55,11 +58,14 @@ PyAPI_FUNC(void) PyMem_RawFree(void *ptr); */ PyAPI_FUNC(void *) PyMem_Malloc(size_t size); +PyAPI_FUNC(void *) PyMem_Calloc(size_t nelem, size_t elsize); PyAPI_FUNC(void *) PyMem_Realloc(void *ptr, size_t new_size); PyAPI_FUNC(void) PyMem_Free(void *ptr); +#ifndef Py_LIMITED_API PyAPI_FUNC(char *) _PyMem_RawStrdup(const char *str); PyAPI_FUNC(char *) _PyMem_Strdup(const char *str); +#endif /* Macros. */ @@ -122,22 +128,25 @@ typedef enum { } PyMemAllocatorDomain; typedef struct { - /* user context passed as the first argument to the 3 functions */ + /* 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); -} PyMemAllocator; +} PyMemAllocatorEx; /* Get the memory block allocator of the specified domain. */ PyAPI_FUNC(void) PyMem_GetAllocator(PyMemAllocatorDomain domain, - PyMemAllocator *allocator); + PyMemAllocatorEx *allocator); /* Set the memory block allocator of the specified domain. @@ -151,7 +160,7 @@ PyAPI_FUNC(void) PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMem_SetupDebugHooks() function must be called to reinstall the debug hooks on top on the new allocator. */ PyAPI_FUNC(void) PyMem_SetAllocator(PyMemAllocatorDomain domain, - PyMemAllocator *allocator); + PyMemAllocatorEx *allocator); /* Setup hooks to detect bugs in the following Python memory allocator functions: diff --git a/Include/pyport.h b/Include/pyport.h index c706213c87c5..66e00d4e6dd0 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -270,7 +270,7 @@ typedef int Py_ssize_clean_t; * for platforms that support that. * * If PY_LOCAL_AGGRESSIVE is defined before python.h is included, more - * "aggressive" inlining/optimizaion is enabled for the entire module. This + * "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. @@ -357,28 +357,6 @@ typedef int Py_ssize_clean_t; * stat() and fstat() fiddling * *******************************/ -/* We expect that stat and fstat exist on most systems. - * It's confirmed on Unix, Mac and Windows. - * If you don't have them, add - * #define DONT_HAVE_STAT - * and/or - * #define DONT_HAVE_FSTAT - * to your pyconfig.h. Python code beyond this should check HAVE_STAT and - * HAVE_FSTAT instead. - * Also - * #define HAVE_SYS_STAT_H - * if <sys/stat.h> exists on your platform, and - * #define HAVE_STAT_H - * if <stat.h> does. - */ -#ifndef DONT_HAVE_STAT -#define HAVE_STAT -#endif - -#ifndef DONT_HAVE_FSTAT -#define HAVE_FSTAT -#endif - #ifdef HAVE_SYS_STAT_H #include <sys/stat.h> #elif defined(HAVE_STAT_H) @@ -588,6 +566,25 @@ extern "C" { } 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 @@ -880,4 +877,24 @@ extern pid_t forkpty(int *, char *, struct termios *, struct winsize *); #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 */ + #endif /* Py_PYPORT_H */ diff --git a/Include/pystate.h b/Include/pystate.h index 06af80844437..6000b81ae460 100644 --- a/Include/pystate.h +++ b/Include/pystate.h @@ -33,7 +33,6 @@ typedef struct _is { int codecs_initialized; int fscodec_initialized; - #ifdef HAVE_DLOPEN int dlopenflags; #endif @@ -41,6 +40,7 @@ typedef struct _is { int tscdump; #endif + PyObject *builtins_copy; } PyInterpreterState; #endif @@ -134,6 +134,9 @@ typedef struct _ts { void (*on_delete)(void *); void *on_delete_data; + PyObject *coroutine_wrapper; + int in_coroutine_wrapper; + /* XXX signal handlers should also be here */ } PyThreadState; @@ -175,15 +178,12 @@ PyAPI_FUNC(int) PyThreadState_SetAsyncExc(long, PyObject *); /* Assuming the current thread holds the GIL, this is the PyThreadState for the current thread. */ -#ifndef Py_LIMITED_API +#ifdef Py_BUILD_CORE PyAPI_DATA(_Py_atomic_address) _PyThreadState_Current; -#endif - -#if defined(Py_DEBUG) || defined(Py_LIMITED_API) -#define PyThreadState_GET() PyThreadState_Get() +# define PyThreadState_GET() \ + ((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)) #else -#define PyThreadState_GET() \ - ((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)) +# define PyThreadState_GET() PyThreadState_Get() #endif typedef @@ -236,7 +236,9 @@ PyAPI_FUNC(PyThreadState *) PyGILState_GetThisThreadState(void); /* Helper/diagnostic function - return 1 if the current thread * currently holds the GIL, 0 otherwise */ +#ifndef Py_LIMITED_API PyAPI_FUNC(int) PyGILState_Check(void); +#endif #endif /* #ifdef WITH_THREAD */ diff --git a/Include/pystrhex.h b/Include/pystrhex.h new file mode 100644 index 000000000000..1dc125575b67 --- /dev/null +++ b/Include/pystrhex.h @@ -0,0 +1,17 @@ +#ifndef Py_STRHEX_H +#define Py_STRHEX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* 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); + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_STRHEX_H */ diff --git a/Include/pythonrun.h b/Include/pythonrun.h index c36494768517..f92148da0707 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -9,7 +9,8 @@ extern "C" { #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_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL | \ + CO_FUTURE_GENERATOR_STOP) #define PyCF_MASK_OBSOLETE (CO_NESTED) #define PyCF_SOURCE_IS_UTF8 0x0100 #define PyCF_DONT_IMPLY_DEDENT 0x0200 @@ -22,30 +23,6 @@ typedef struct { } PyCompilerFlags; #endif -PyAPI_FUNC(void) Py_SetProgramName(wchar_t *); -PyAPI_FUNC(wchar_t *) Py_GetProgramName(void); - -PyAPI_FUNC(void) Py_SetPythonHome(wchar_t *); -PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void); - -#ifndef Py_LIMITED_API -/* 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); -#endif - -PyAPI_FUNC(void) Py_Initialize(void); -PyAPI_FUNC(void) Py_InitializeEx(int); -#ifndef Py_LIMITED_API -PyAPI_FUNC(void) _Py_InitializeEx_Private(int, int); -#endif -PyAPI_FUNC(void) Py_Finalize(void); -PyAPI_FUNC(int) Py_IsInitialized(void); -PyAPI_FUNC(PyThreadState *) Py_NewInterpreter(void); -PyAPI_FUNC(void) Py_EndInterpreter(PyThreadState *); - #ifndef Py_LIMITED_API PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *); PyAPI_FUNC(int) PyRun_AnyFileFlags(FILE *, const char *, PyCompilerFlags *); @@ -155,35 +132,17 @@ 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(struct symtable *) Py_SymtableStringObject( const char *str, PyObject *filename, int start); +#endif PyAPI_FUNC(void) PyErr_Print(void); PyAPI_FUNC(void) PyErr_PrintEx(int); PyAPI_FUNC(void) PyErr_Display(PyObject *, PyObject *, PyObject *); -/* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level - * exit functions. - */ -#ifndef Py_LIMITED_API -PyAPI_FUNC(void) _Py_PyAtExit(void (*func)(void)); -#endif -PyAPI_FUNC(int) Py_AtExit(void (*func)(void)); - -PyAPI_FUNC(void) Py_Exit(int); - -/* Restore signals that the interpreter has called SIG_IGN on to SIG_DFL. */ -#ifndef Py_LIMITED_API -PyAPI_FUNC(void) _Py_RestoreSignals(void); - -PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *); -#endif - -/* Bootstrap */ -PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv); - #ifndef Py_LIMITED_API /* Use macros for a bunch of old variants */ #define PyRun_String(str, s, g, l) PyRun_StringFlags(str, s, g, l, NULL) @@ -205,64 +164,6 @@ PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv); PyRun_FileExFlags(fp, p, s, g, l, 0, flags) #endif -/* In getpath.c */ -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(); -#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); -#ifndef Py_LIMITED_API -PyAPI_FUNC(const char *) _Py_hgidentifier(void); -PyAPI_FUNC(const char *) _Py_hgversion(void); -#endif - -/* Internal -- various one-time initializations */ -#ifndef Py_LIMITED_API -PyAPI_FUNC(PyObject *) _PyBuiltin_Init(void); -PyAPI_FUNC(PyObject *) _PySys_Init(void); -PyAPI_FUNC(void) _PyImport_Init(void); -PyAPI_FUNC(void) _PyExc_Init(PyObject * bltinmod); -PyAPI_FUNC(void) _PyImportHooks_Init(void); -PyAPI_FUNC(int) _PyFrame_Init(void); -PyAPI_FUNC(int) _PyFloat_Init(void); -PyAPI_FUNC(int) PyByteArray_Init(void); -PyAPI_FUNC(void) _PyRandom_Init(void); -#endif - -/* Various internal finalizers */ -#ifndef Py_LIMITED_API -PyAPI_FUNC(void) _PyExc_Fini(void); -PyAPI_FUNC(void) _PyImport_Fini(void); -PyAPI_FUNC(void) PyMethod_Fini(void); -PyAPI_FUNC(void) PyFrame_Fini(void); -PyAPI_FUNC(void) PyCFunction_Fini(void); -PyAPI_FUNC(void) PyDict_Fini(void); -PyAPI_FUNC(void) PyTuple_Fini(void); -PyAPI_FUNC(void) PyList_Fini(void); -PyAPI_FUNC(void) PySet_Fini(void); -PyAPI_FUNC(void) PyBytes_Fini(void); -PyAPI_FUNC(void) PyByteArray_Fini(void); -PyAPI_FUNC(void) PyFloat_Fini(void); -PyAPI_FUNC(void) PyOS_FiniInterrupts(void); -PyAPI_FUNC(void) _PyGC_DumpShutdownStats(void); -PyAPI_FUNC(void) _PyGC_Fini(void); -PyAPI_FUNC(void) PySlice_Fini(void); -PyAPI_FUNC(void) _PyType_Fini(void); -PyAPI_FUNC(void) _PyRandom_Fini(void); - -PyAPI_DATA(PyThreadState *) _Py_Finalizing; -#endif - /* Stuff with no proper home (yet) */ #ifndef Py_LIMITED_API PyAPI_FUNC(char *) PyOS_Readline(FILE *, FILE *, const char *); @@ -288,14 +189,6 @@ PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState; PyAPI_FUNC(int) PyOS_CheckStack(void); #endif -/* 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); - -/* Random */ -PyAPI_FUNC(int) _PyOS_URandom (void *buffer, Py_ssize_t size); - #ifdef __cplusplus } #endif diff --git a/Include/pytime.h b/Include/pytime.h index 52902f5e3ac2..98612e130785 100644 --- a/Include/pytime.h +++ b/Include/pytime.h @@ -13,50 +13,28 @@ functions and constants extern "C" { #endif -#ifdef HAVE_GETTIMEOFDAY -typedef struct timeval _PyTime_timeval; +#ifdef PY_INT64_T +/* _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 PY_INT64_T _PyTime_t; +#define _PyTime_MIN PY_LLONG_MIN +#define _PyTime_MAX PY_LLONG_MAX #else -typedef struct { - time_t tv_sec; /* seconds since Jan. 1, 1970 */ - long tv_usec; /* and microseconds */ -} _PyTime_timeval; +# error "_PyTime_t need signed 64-bit integer type" #endif -/* Structure used by time.get_clock_info() */ -typedef struct { - const char *implementation; - int monotonic; - int adjustable; - double resolution; -} _Py_clock_info_t; - -/* Similar to POSIX gettimeofday but cannot fail. If system gettimeofday - * fails or is not available, fall back to lower resolution clocks. - */ -PyAPI_FUNC(void) _PyTime_gettimeofday(_PyTime_timeval *tp); - -/* Similar to _PyTime_gettimeofday() but retrieve also information on the - * clock used to get the current time. */ -PyAPI_FUNC(void) _PyTime_gettimeofday_info( - _PyTime_timeval *tp, - _Py_clock_info_t *info); - -#define _PyTime_ADD_SECONDS(tv, interval) \ -do { \ - tv.tv_usec += (long) (((long) interval - interval) * 1000000); \ - tv.tv_sec += (time_t) interval + (time_t) (tv.tv_usec / 1000000); \ - tv.tv_usec %= 1000000; \ -} while (0) - -#define _PyTime_INTERVAL(tv_start, tv_end) \ - ((tv_end.tv_sec - tv_start.tv_sec) + \ - (tv_end.tv_usec - tv_start.tv_usec) * 0.000001) - -#ifndef Py_LIMITED_API -/* Convert a number of seconds, int or float, to time_t. */ -PyAPI_FUNC(int) _PyTime_ObjectToTime_t( - PyObject *obj, - time_t *sec); +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 +} _PyTime_round_t; /* Convert a time_t to a PyLong. */ PyAPI_FUNC(PyObject *) _PyLong_FromTime_t( @@ -66,13 +44,20 @@ PyAPI_FUNC(PyObject *) _PyLong_FromTime_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); + 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. @@ -80,11 +65,128 @@ PyAPI_FUNC(int) _PyTime_ObjectToTimeval( PyAPI_FUNC(int) _PyTime_ObjectToTimespec( PyObject *obj, time_t *sec, - long *nsec); + 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(PY_LONG_LONG ns); + +/* 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); + +/* 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) +/* 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 -/* Dummy to force linking. */ -PyAPI_FUNC(void) _PyTime_Init(void); +/* 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); #ifdef __cplusplus } diff --git a/Include/setobject.h b/Include/setobject.h index ae3f556365dd..87ec1c8afc00 100644 --- a/Include/setobject.h +++ b/Include/setobject.h @@ -6,38 +6,44 @@ extern "C" { #endif +#ifndef Py_LIMITED_API + +/* There are three kinds of entries in the table: -/* -There are three kinds of slots 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 -1. Unused: key == NULL -2. Active: key != NULL and key != dummy -3. Dummy: key == dummy +The hash field of Unused slots is always zero. -Note: .pop() abuses the hash field of an Unused or Dummy slot to -hold a search finger. The hash field of Unused or Dummy slots has -no meaning otherwise. +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. */ -#ifndef Py_LIMITED_API + #define PySet_MINSIZE 8 typedef struct { - /* Cached hash code of the key. */ PyObject *key; - Py_hash_t hash; + 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. -/* -This data structure is shared by set and frozenset objects. */ -typedef struct _setobject PySetObject; -struct _setobject { +typedef struct { PyObject_HEAD - Py_ssize_t fill; /* # Active + # Dummy */ - Py_ssize_t used; /* # Active */ + 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 @@ -45,33 +51,42 @@ struct _setobject { */ Py_ssize_t mask; - /* table points to smalltable for small tables, else to - * additional malloc'ed memory. table is never NULL! This rule - * saves repeated runtime null-tests. + /* 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; - setentry *(*lookup)(PySetObject *so, PyObject *key, Py_hash_t hash); - Py_hash_t hash; /* only used by frozenset objects */ - setentry smalltable[PySet_MINSIZE]; + 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 */ -}; -#endif /* Py_LIMITED_API */ +} PySetObject; + +#define PySet_GET_SIZE(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; -#ifndef Py_LIMITED_API -PyAPI_DATA(PyObject *) _PySet_Dummy; -#endif +PyAPI_FUNC(PyObject *) PySet_New(PyObject *); +PyAPI_FUNC(PyObject *) PyFrozenSet_New(PyObject *); -/* Invariants for frozensets: - * data is immutable. - * hash is the hash of the frozenset or -1 if not computed yet. - * Invariants for sets: - * hash is -1 - */ +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) \ @@ -87,26 +102,6 @@ PyAPI_DATA(PyObject *) _PySet_Dummy; (Py_TYPE(ob) == &PyFrozenSet_Type || \ PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) -PyAPI_FUNC(PyObject *) PySet_New(PyObject *); -PyAPI_FUNC(PyObject *) PyFrozenSet_New(PyObject *); -PyAPI_FUNC(Py_ssize_t) PySet_Size(PyObject *anyset); -#ifndef Py_LIMITED_API -#define PySet_GET_SIZE(so) (((PySetObject *)(so))->used) -#endif -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(int) PySet_Add(PyObject *set, PyObject *key); -#ifndef Py_LIMITED_API -PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, Py_hash_t *hash); -#endif -PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set); -#ifndef Py_LIMITED_API -PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable); - -PyAPI_FUNC(int) PySet_ClearFreeList(void); -#endif - #ifdef __cplusplus } #endif diff --git a/Include/sliceobject.h b/Include/sliceobject.h index f7ee90c3cc84..26370e017571 100644 --- a/Include/sliceobject.h +++ b/Include/sliceobject.h @@ -41,7 +41,7 @@ PyAPI_FUNC(int) _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, PyAPI_FUNC(int) PySlice_GetIndices(PyObject *r, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step); PyAPI_FUNC(int) PySlice_GetIndicesEx(PyObject *r, Py_ssize_t length, - Py_ssize_t *start, Py_ssize_t *stop, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength); #ifdef __cplusplus diff --git a/Include/symtable.h b/Include/symtable.h index 1cfd8844e5af..1409cd91ce6a 100644 --- a/Include/symtable.h +++ b/Include/symtable.h @@ -43,7 +43,6 @@ typedef struct _symtable_entry { 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_unoptimized; /* false if namespace is optimized */ 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, @@ -108,10 +107,6 @@ PyAPI_FUNC(void) PySymtable_Free(struct symtable *); #define FREE 4 #define CELL 5 -/* The following two names are used for the ste_unoptimized bit field */ -#define OPT_IMPORT_STAR 1 -#define OPT_TOPLEVEL 2 /* top-level names, including eval and exec */ - #define GENERATOR 1 #define GENERATOR_EXPRESSION 2 diff --git a/Include/sysmodule.h b/Include/sysmodule.h index 925c2a34f476..cde10ac4cafa 100644 --- a/Include/sysmodule.h +++ b/Include/sysmodule.h @@ -8,7 +8,9 @@ extern "C" { #endif PyAPI_FUNC(PyObject *) PySys_GetObject(const char *); +#ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PySys_GetObjectId(_Py_Identifier *key); +#endif PyAPI_FUNC(int) PySys_SetObject(const char *, PyObject *); PyAPI_FUNC(int) _PySys_SetObjectId(_Py_Identifier *key, PyObject *); @@ -31,6 +33,10 @@ PyAPI_FUNC(int) PySys_HasWarnOptions(void); PyAPI_FUNC(void) PySys_AddXOption(const wchar_t *); PyAPI_FUNC(PyObject *) PySys_GetXOptions(void); +#ifndef Py_LIMITED_API +PyAPI_FUNC(size_t) _PySys_GetSizeOf(PyObject *); +#endif + #ifdef __cplusplus } #endif diff --git a/Include/token.h b/Include/token.h index 905022b8d2c7..595afa015808 100644 --- a/Include/token.h +++ b/Include/token.h @@ -58,13 +58,16 @@ extern "C" { #define DOUBLESTAREQUAL 46 #define DOUBLESLASH 47 #define DOUBLESLASHEQUAL 48 -#define AT 49 -#define RARROW 50 -#define ELLIPSIS 51 +#define AT 49 +#define ATEQUAL 50 +#define RARROW 51 +#define ELLIPSIS 52 /* Don't forget to update the table _PyParser_TokenNames in tokenizer.c! */ -#define OP 52 -#define ERRORTOKEN 53 -#define N_TOKENS 54 +#define OP 53 +#define AWAIT 54 +#define ASYNC 55 +#define ERRORTOKEN 56 +#define N_TOKENS 57 /* Special definitions for cooperation with parser */ diff --git a/Include/traceback.h b/Include/traceback.h index 77347077e91a..891000c8fe27 100644 --- a/Include/traceback.h +++ b/Include/traceback.h @@ -24,6 +24,7 @@ PyAPI_FUNC(int) PyTraceBack_Here(struct _frame *); PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *); #ifndef Py_LIMITED_API PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, PyObject *, int, int); +PyAPI_FUNC(void) _PyTraceback_Add(const char *, const char *, int); #endif /* Reveal traceback type so we can typecheck traceback objects */ diff --git a/Include/typeslots.h b/Include/typeslots.h index ad3cdfb19ad4..0ce6a377dcfb 100644 --- a/Include/typeslots.h +++ b/Include/typeslots.h @@ -74,3 +74,12 @@ #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/Include/ucnhash.h b/Include/ucnhash.h index 8de9ba0cff76..45362e997dfa 100644 --- a/Include/ucnhash.h +++ b/Include/ucnhash.h @@ -16,7 +16,7 @@ typedef struct { int size; /* Get name for a given character code. Returns non-zero if - success, zero if not. Does not set Python exceptions. + 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, diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index b6d331bb8d3d..adcb64c350f8 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -343,6 +343,9 @@ typedef struct { 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; @@ -602,7 +605,7 @@ PyAPI_FUNC(PyObject*) PyUnicode_New( ); #endif -/* Initializes the canonical string representation from a the deprecated +/* 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. @@ -846,7 +849,7 @@ PyAPI_FUNC(int) PyUnicode_Resize( Coercion is done in the following way: - 1. bytes, bytearray and other char buffer compatible objects are decoded + 1. bytes, bytearray and other bytes-like objects are decoded under the assumptions that they contain data using the UTF-8 encoding. Decoding is done in "strict" mode. @@ -905,7 +908,7 @@ typedef struct { /* minimum character (default: 127, ASCII) */ Py_UCS4 min_char; - /* If non-zero, overallocate the buffer by 25% (default: 0). */ + /* If non-zero, overallocate the buffer (default: 0). */ unsigned char overallocate; /* If readonly is 1, buffer is a shared string (cannot be modified) @@ -939,6 +942,23 @@ 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) @@ -1049,7 +1069,7 @@ PyAPI_FUNC(Py_ssize_t) PyUnicode_AsWideChar( 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_Alloc() (use PyMem_Free() to free it) + 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. */ @@ -2004,10 +2024,12 @@ PyAPI_FUNC(int) PyUnicode_Compare( PyObject *right /* Right string */ ); +#ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyUnicode_CompareWithId( PyObject *left, /* Left string */ _Py_Identifier *right /* Right identifier */ ); +#endif PyAPI_FUNC(int) PyUnicode_CompareWithASCIIString( PyObject *left, @@ -2055,12 +2077,6 @@ PyAPI_FUNC(int) PyUnicode_Contains( PyObject *element /* Element string */ ); -/* Checks whether the string contains any NUL characters. */ - -#ifndef Py_LIMITED_API -PyAPI_FUNC(int) _PyUnicode_HasNULChars(PyObject *); -#endif - /* Checks whether argument is a valid identifier. */ PyAPI_FUNC(int) PyUnicode_IsIdentifier(PyObject *s); @@ -2240,6 +2256,8 @@ PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strrchr( 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). */ @@ -2260,6 +2278,10 @@ 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/Include/warnings.h b/Include/warnings.h index 217c06a66567..effb9fad7196 100644 --- a/Include/warnings.h +++ b/Include/warnings.h @@ -17,6 +17,7 @@ PyAPI_FUNC(int) PyErr_WarnFormat( Py_ssize_t stack_level, const char *format, /* ASCII-encoded string */ ...); +#ifndef Py_LIMITED_API PyAPI_FUNC(int) PyErr_WarnExplicitObject( PyObject *category, PyObject *message, @@ -24,6 +25,7 @@ PyAPI_FUNC(int) PyErr_WarnExplicitObject( int lineno, PyObject *module, PyObject *registry); +#endif PyAPI_FUNC(int) PyErr_WarnExplicit( PyObject *category, const char *message, /* UTF-8 encoded string */ @@ -32,11 +34,13 @@ PyAPI_FUNC(int) PyErr_WarnExplicit( 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 diff --git a/LICENSE b/LICENSE index 56a5d5cc7f13..88251f5b6e8b 100644 --- a/LICENSE +++ b/LICENSE @@ -74,8 +74,8 @@ analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -2011, 2012, 2013 Python Software Foundation; All Rights Reserved" are retained -in Python alone or in any derivative version prepared by Licensee. +2011, 2012, 2013, 2014, 2015 Python Software Foundation; All Rights Reserved" +are retained in Python alone or in any derivative version prepared by Licensee. 3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and wants to make diff --git a/Lib/__future__.py b/Lib/__future__.py index 3b2d5ecb92ab..63b2be3524fc 100644 --- a/Lib/__future__.py +++ b/Lib/__future__.py @@ -56,6 +56,7 @@ "print_function", "unicode_literals", "barry_as_FLUFL", + "generator_stop", ] __all__ = ["all_feature_names"] + all_feature_names @@ -72,6 +73,7 @@ CO_FUTURE_PRINT_FUNCTION = 0x10000 # print function CO_FUTURE_UNICODE_LITERALS = 0x20000 # unicode string literals CO_FUTURE_BARRY_AS_BDFL = 0x40000 +CO_FUTURE_GENERATOR_STOP = 0x80000 # StopIteration becomes RuntimeError in generators class _Feature: def __init__(self, optionalRelease, mandatoryRelease, compiler_flag): @@ -132,3 +134,7 @@ def __repr__(self): barry_as_FLUFL = _Feature((3, 1, 0, "alpha", 2), (3, 9, 0, "alpha", 0), CO_FUTURE_BARRY_AS_BDFL) + +generator_stop = _Feature((3, 5, 0, "beta", 1), + (3, 7, 0, "alpha", 0), + CO_FUTURE_GENERATOR_STOP) diff --git a/Lib/_collections_abc.py b/Lib/_collections_abc.py index faa1ff22ff40..f89bb6f04b5b 100644 --- a/Lib/_collections_abc.py +++ b/Lib/_collections_abc.py @@ -9,7 +9,8 @@ from abc import ABCMeta, abstractmethod import sys -__all__ = ["Hashable", "Iterable", "Iterator", +__all__ = ["Awaitable", "Coroutine", "AsyncIterable", "AsyncIterator", + "Hashable", "Iterable", "Iterator", "Generator", "Sized", "Container", "Callable", "Set", "MutableSet", "Mapping", "MutableMapping", @@ -50,6 +51,13 @@ dict_items = type({}.items()) ## misc ## mappingproxy = type(type.__dict__) +generator = type((lambda: (yield))()) +## coroutine ## +async def _coro(): pass +_coro = _coro() +coroutine = type(_coro) +_coro.close() # Prevent ResourceWarning +del _coro ### ONE-TRICK PONIES ### @@ -73,6 +81,113 @@ def __subclasshook__(cls, C): return NotImplemented +class Awaitable(metaclass=ABCMeta): + + __slots__ = () + + @abstractmethod + def __await__(self): + yield + + @classmethod + def __subclasshook__(cls, C): + if cls is Awaitable: + for B in C.__mro__: + if "__await__" in B.__dict__: + if B.__dict__["__await__"]: + return True + break + return NotImplemented + + +class Coroutine(Awaitable): + + __slots__ = () + + @abstractmethod + def send(self, value): + """Send a value into the coroutine. + Return next yielded value or raise StopIteration. + """ + raise StopIteration + + @abstractmethod + def throw(self, typ, val=None, tb=None): + """Raise an exception in the coroutine. + Return next yielded value or raise StopIteration. + """ + if val is None: + if tb is None: + raise typ + val = typ() + if tb is not None: + val = val.with_traceback(tb) + raise val + + def close(self): + """Raise GeneratorExit inside coroutine. + """ + try: + self.throw(GeneratorExit) + except (GeneratorExit, StopIteration): + pass + else: + raise RuntimeError("coroutine ignored GeneratorExit") + + @classmethod + def __subclasshook__(cls, C): + if cls is Coroutine: + mro = C.__mro__ + for method in ('__await__', 'send', 'throw', 'close'): + for base in mro: + if method in base.__dict__: + break + else: + return NotImplemented + return True + return NotImplemented + + +Coroutine.register(coroutine) + + +class AsyncIterable(metaclass=ABCMeta): + + __slots__ = () + + @abstractmethod + async def __aiter__(self): + return AsyncIterator() + + @classmethod + def __subclasshook__(cls, C): + if cls is AsyncIterable: + if any("__aiter__" in B.__dict__ for B in C.__mro__): + return True + return NotImplemented + + +class AsyncIterator(AsyncIterable): + + __slots__ = () + + @abstractmethod + async def __anext__(self): + """Return the next item or raise StopAsyncIteration when exhausted.""" + raise StopAsyncIteration + + async def __aiter__(self): + return self + + @classmethod + def __subclasshook__(cls, C): + if cls is AsyncIterator: + if (any("__anext__" in B.__dict__ for B in C.__mro__) and + any("__aiter__" in B.__dict__ for B in C.__mro__)): + return True + return NotImplemented + + class Iterable(metaclass=ABCMeta): __slots__ = () @@ -124,6 +239,64 @@ def __subclasshook__(cls, C): Iterator.register(tuple_iterator) Iterator.register(zip_iterator) + +class Generator(Iterator): + + __slots__ = () + + def __next__(self): + """Return the next item from the generator. + When exhausted, raise StopIteration. + """ + return self.send(None) + + @abstractmethod + def send(self, value): + """Send a value into the generator. + Return next yielded value or raise StopIteration. + """ + raise StopIteration + + @abstractmethod + def throw(self, typ, val=None, tb=None): + """Raise an exception in the generator. + Return next yielded value or raise StopIteration. + """ + if val is None: + if tb is None: + raise typ + val = typ() + if tb is not None: + val = val.with_traceback(tb) + raise val + + def close(self): + """Raise GeneratorExit inside generator. + """ + try: + self.throw(GeneratorExit) + except (GeneratorExit, StopIteration): + pass + else: + raise RuntimeError("generator ignored GeneratorExit") + + @classmethod + def __subclasshook__(cls, C): + if cls is Generator: + mro = C.__mro__ + for method in ('__iter__', '__next__', 'send', 'throw', 'close'): + for base in mro: + if method in base.__dict__: + break + else: + return NotImplemented + return True + return NotImplemented + + +Generator.register(generator) + + class Sized(metaclass=ABCMeta): __slots__ = () @@ -183,7 +356,7 @@ class Set(Sized, Iterable, Container): methods except for __contains__, __iter__ and __len__. To override the comparisons (presumably for speed, as the - semantics are fixed), all you have to do is redefine __le__ and + semantics are fixed), redefine __le__ and __ge__, then the other operations will automatically follow suit. """ @@ -207,21 +380,23 @@ def __lt__(self, other): def __gt__(self, other): if not isinstance(other, Set): return NotImplemented - return other.__lt__(self) + return len(self) > len(other) and self.__ge__(other) def __ge__(self, other): if not isinstance(other, Set): return NotImplemented - return other.__le__(self) + if len(self) < len(other): + return False + for elem in other: + if elem not in self: + return False + return True def __eq__(self, other): if not isinstance(other, Set): return NotImplemented return len(self) == len(other) and self.__le__(other) - def __ne__(self, other): - return not (self == other) - @classmethod def _from_iterable(cls, it): '''Construct an instance of the class from any iterable input. @@ -236,6 +411,8 @@ def __and__(self, other): return NotImplemented return self._from_iterable(value for value in other if value in self) + __rand__ = __and__ + def isdisjoint(self, other): 'Return True if two sets have a null intersection.' for value in other: @@ -249,6 +426,8 @@ def __or__(self, other): chain = (e for s in (self, other) for e in s) return self._from_iterable(chain) + __ror__ = __or__ + def __sub__(self, other): if not isinstance(other, Set): if not isinstance(other, Iterable): @@ -257,6 +436,14 @@ def __sub__(self, other): return self._from_iterable(value for value in self if value not in other) + def __rsub__(self, other): + if not isinstance(other, Set): + if not isinstance(other, Iterable): + return NotImplemented + other = self._from_iterable(other) + return self._from_iterable(value for value in other + if value not in self) + def __xor__(self, other): if not isinstance(other, Set): if not isinstance(other, Iterable): @@ -264,6 +451,8 @@ def __xor__(self, other): other = self._from_iterable(other) return (self - other) | (other - self) + __rxor__ = __xor__ + def _hash(self): """Compute the hash value of a set. @@ -432,14 +621,13 @@ def __eq__(self, other): return NotImplemented return dict(self.items()) == dict(other.items()) - def __ne__(self, other): - return not (self == other) - Mapping.register(mappingproxy) class MappingView(Sized): + __slots__ = '_mapping', + def __init__(self, mapping): self._mapping = mapping @@ -452,6 +640,8 @@ def __repr__(self): class KeysView(MappingView, Set): + __slots__ = () + @classmethod def _from_iterable(self, it): return set(it) @@ -467,6 +657,8 @@ def __iter__(self): class ItemsView(MappingView, Set): + __slots__ = () + @classmethod def _from_iterable(self, it): return set(it) @@ -489,6 +681,8 @@ def __iter__(self): class ValuesView(MappingView): + __slots__ = () + def __contains__(self, value): for key in self._mapping: if value == self._mapping[key]: @@ -565,23 +759,24 @@ def update(*args, **kwds): If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v In either case, this is followed by: for k, v in F.items(): D[k] = v ''' - if len(args) > 2: - raise TypeError("update() takes at most 2 positional " - "arguments ({} given)".format(len(args))) - elif not args: - raise TypeError("update() takes at least 1 argument (0 given)") - self = args[0] - other = args[1] if len(args) >= 2 else () - - if isinstance(other, Mapping): - for key in other: - self[key] = other[key] - elif hasattr(other, "keys"): - for key in other.keys(): - self[key] = other[key] - else: - for key, value in other: - self[key] = value + if not args: + raise TypeError("descriptor 'update' of 'MutableMapping' object " + "needs an argument") + self, *args = args + if len(args) > 1: + raise TypeError('update expected at most 1 arguments, got %d' % + len(args)) + if args: + other = args[0] + if isinstance(other, Mapping): + for key in other: + self[key] = other[key] + elif hasattr(other, "keys"): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value for key, value in kwds.items(): self[key] = value @@ -633,13 +828,23 @@ def __reversed__(self): for i in reversed(range(len(self))): yield self[i] - def index(self, value): - '''S.index(value) -> integer -- return first index of value. + def index(self, value, start=0, stop=None): + '''S.index(value, [start, [stop]]) -> integer -- return first index of value. Raises ValueError if the value is not present. ''' - for i, v in enumerate(self): - if v == value: - return i + if start is not None and start < 0: + start = max(len(self) + start, 0) + if stop is not None and stop < 0: + stop += len(self) + + i = start + while stop is None or i < stop: + try: + if self[i] == value: + return i + except IndexError: + break + i += 1 raise ValueError def count(self, value): diff --git a/Lib/_compat_pickle.py b/Lib/_compat_pickle.py index 978c01e8ef4f..6e39d4aee3e8 100644 --- a/Lib/_compat_pickle.py +++ b/Lib/_compat_pickle.py @@ -6,18 +6,13 @@ # lib2to3 and use the mapping defined there, because lib2to3 uses pickle. # Thus, this could cause the module to be imported recursively. IMPORT_MAPPING = { - 'StringIO': 'io', - 'cStringIO': 'io', - 'cPickle': 'pickle', '__builtin__' : 'builtins', 'copy_reg': 'copyreg', 'Queue': 'queue', 'SocketServer': 'socketserver', 'ConfigParser': 'configparser', 'repr': 'reprlib', - 'FileDialog': 'tkinter.filedialog', 'tkFileDialog': 'tkinter.filedialog', - 'SimpleDialog': 'tkinter.simpledialog', 'tkSimpleDialog': 'tkinter.simpledialog', 'tkColorChooser': 'tkinter.colorchooser', 'tkCommonDialog': 'tkinter.commondialog', @@ -39,7 +34,6 @@ 'dbm': 'dbm.ndbm', 'gdbm': 'dbm.gnu', 'xmlrpclib': 'xmlrpc.client', - 'DocXMLRPCServer': 'xmlrpc.server', 'SimpleXMLRPCServer': 'xmlrpc.server', 'httplib': 'http.client', 'htmlentitydefs' : 'html.entities', @@ -47,16 +41,13 @@ 'Cookie': 'http.cookies', 'cookielib': 'http.cookiejar', 'BaseHTTPServer': 'http.server', - 'SimpleHTTPServer': 'http.server', - 'CGIHTTPServer': 'http.server', 'test.test_support': 'test.support', 'commands': 'subprocess', - 'UserString' : 'collections', - 'UserList' : 'collections', 'urlparse' : 'urllib.parse', 'robotparser' : 'urllib.robotparser', - 'whichdb': 'dbm', - 'anydbm': 'dbm' + 'urllib2': 'urllib.request', + 'anydbm': 'dbm', + '_abcoll' : 'collections.abc', } @@ -68,12 +59,35 @@ ('__builtin__', 'reduce'): ('functools', 'reduce'), ('__builtin__', 'intern'): ('sys', 'intern'), ('__builtin__', 'unichr'): ('builtins', 'chr'), - ('__builtin__', 'basestring'): ('builtins', 'str'), + ('__builtin__', 'unicode'): ('builtins', 'str'), ('__builtin__', 'long'): ('builtins', 'int'), ('itertools', 'izip'): ('builtins', 'zip'), ('itertools', 'imap'): ('builtins', 'map'), ('itertools', 'ifilter'): ('builtins', 'filter'), ('itertools', 'ifilterfalse'): ('itertools', 'filterfalse'), + ('itertools', 'izip_longest'): ('itertools', 'zip_longest'), + ('UserDict', 'IterableUserDict'): ('collections', 'UserDict'), + ('UserList', 'UserList'): ('collections', 'UserList'), + ('UserString', 'UserString'): ('collections', 'UserString'), + ('whichdb', 'whichdb'): ('dbm', 'whichdb'), + ('_socket', 'fromfd'): ('socket', 'fromfd'), + ('_multiprocessing', 'Connection'): ('multiprocessing.connection', 'Connection'), + ('multiprocessing.process', 'Process'): ('multiprocessing.context', 'Process'), + ('multiprocessing.forking', 'Popen'): ('multiprocessing.popen_fork', 'Popen'), + ('urllib', 'ContentTooShortError'): ('urllib.error', 'ContentTooShortError'), + ('urllib', 'getproxies'): ('urllib.request', 'getproxies'), + ('urllib', 'pathname2url'): ('urllib.request', 'pathname2url'), + ('urllib', 'quote_plus'): ('urllib.parse', 'quote_plus'), + ('urllib', 'quote'): ('urllib.parse', 'quote'), + ('urllib', 'unquote_plus'): ('urllib.parse', 'unquote_plus'), + ('urllib', 'unquote'): ('urllib.parse', 'unquote'), + ('urllib', 'url2pathname'): ('urllib.request', 'url2pathname'), + ('urllib', 'urlcleanup'): ('urllib.request', 'urlcleanup'), + ('urllib', 'urlencode'): ('urllib.parse', 'urlencode'), + ('urllib', 'urlopen'): ('urllib.request', 'urlopen'), + ('urllib', 'urlretrieve'): ('urllib.request', 'urlretrieve'), + ('urllib2', 'HTTPError'): ('urllib.error', 'HTTPError'), + ('urllib2', 'URLError'): ('urllib.error', 'URLError'), } PYTHON2_EXCEPTIONS = ( @@ -127,11 +141,97 @@ "ZeroDivisionError", ) +try: + WindowsError +except NameError: + pass +else: + PYTHON2_EXCEPTIONS += ("WindowsError",) + for excname in PYTHON2_EXCEPTIONS: NAME_MAPPING[("exceptions", excname)] = ("builtins", excname) -NAME_MAPPING[("exceptions", "StandardError")] = ("builtins", "Exception") +MULTIPROCESSING_EXCEPTIONS = ( + 'AuthenticationError', + 'BufferTooShort', + 'ProcessError', + 'TimeoutError', +) + +for excname in MULTIPROCESSING_EXCEPTIONS: + NAME_MAPPING[("multiprocessing", excname)] = ("multiprocessing.context", excname) # Same, but for 3.x to 2.x REVERSE_IMPORT_MAPPING = dict((v, k) for (k, v) in IMPORT_MAPPING.items()) +assert len(REVERSE_IMPORT_MAPPING) == len(IMPORT_MAPPING) REVERSE_NAME_MAPPING = dict((v, k) for (k, v) in NAME_MAPPING.items()) +assert len(REVERSE_NAME_MAPPING) == len(NAME_MAPPING) + +# Non-mutual mappings. + +IMPORT_MAPPING.update({ + 'cPickle': 'pickle', + '_elementtree': 'xml.etree.ElementTree', + 'FileDialog': 'tkinter.filedialog', + 'SimpleDialog': 'tkinter.simpledialog', + 'DocXMLRPCServer': 'xmlrpc.server', + 'SimpleHTTPServer': 'http.server', + 'CGIHTTPServer': 'http.server', +}) + +REVERSE_IMPORT_MAPPING.update({ + '_bz2': 'bz2', + '_dbm': 'dbm', + '_functools': 'functools', + '_gdbm': 'gdbm', + '_pickle': 'pickle', +}) + +NAME_MAPPING.update({ + ('__builtin__', 'basestring'): ('builtins', 'str'), + ('exceptions', 'StandardError'): ('builtins', 'Exception'), + ('UserDict', 'UserDict'): ('collections', 'UserDict'), + ('socket', '_socketobject'): ('socket', 'SocketType'), +}) + +REVERSE_NAME_MAPPING.update({ + ('_functools', 'reduce'): ('__builtin__', 'reduce'), + ('tkinter.filedialog', 'FileDialog'): ('FileDialog', 'FileDialog'), + ('tkinter.filedialog', 'LoadFileDialog'): ('FileDialog', 'LoadFileDialog'), + ('tkinter.filedialog', 'SaveFileDialog'): ('FileDialog', 'SaveFileDialog'), + ('tkinter.simpledialog', 'SimpleDialog'): ('SimpleDialog', 'SimpleDialog'), + ('xmlrpc.server', 'ServerHTMLDoc'): ('DocXMLRPCServer', 'ServerHTMLDoc'), + ('xmlrpc.server', 'XMLRPCDocGenerator'): + ('DocXMLRPCServer', 'XMLRPCDocGenerator'), + ('xmlrpc.server', 'DocXMLRPCRequestHandler'): + ('DocXMLRPCServer', 'DocXMLRPCRequestHandler'), + ('xmlrpc.server', 'DocXMLRPCServer'): + ('DocXMLRPCServer', 'DocXMLRPCServer'), + ('xmlrpc.server', 'DocCGIXMLRPCRequestHandler'): + ('DocXMLRPCServer', 'DocCGIXMLRPCRequestHandler'), + ('http.server', 'SimpleHTTPRequestHandler'): + ('SimpleHTTPServer', 'SimpleHTTPRequestHandler'), + ('http.server', 'CGIHTTPRequestHandler'): + ('CGIHTTPServer', 'CGIHTTPRequestHandler'), + ('_socket', 'socket'): ('socket', '_socketobject'), +}) + +PYTHON3_OSERROR_EXCEPTIONS = ( + 'BrokenPipeError', + 'ChildProcessError', + 'ConnectionAbortedError', + 'ConnectionError', + 'ConnectionRefusedError', + 'ConnectionResetError', + 'FileExistsError', + 'FileNotFoundError', + 'InterruptedError', + 'IsADirectoryError', + 'NotADirectoryError', + 'PermissionError', + 'ProcessLookupError', + 'TimeoutError', +) + +for excname in PYTHON3_OSERROR_EXCEPTIONS: + REVERSE_NAME_MAPPING[('builtins', excname)] = ('exceptions', 'OSError') diff --git a/Lib/_compression.py b/Lib/_compression.py new file mode 100644 index 000000000000..b00f31b400c3 --- /dev/null +++ b/Lib/_compression.py @@ -0,0 +1,152 @@ +"""Internal classes used by the gzip, lzma and bz2 modules""" + +import io + + +BUFFER_SIZE = io.DEFAULT_BUFFER_SIZE # Compressed data read chunk size + + +class BaseStream(io.BufferedIOBase): + """Mode-checking helper functions.""" + + def _check_not_closed(self): + if self.closed: + raise ValueError("I/O operation on closed file") + + def _check_can_read(self): + if not self.readable(): + raise io.UnsupportedOperation("File not open for reading") + + def _check_can_write(self): + if not self.writable(): + raise io.UnsupportedOperation("File not open for writing") + + def _check_can_seek(self): + if not self.readable(): + raise io.UnsupportedOperation("Seeking is only supported " + "on files open for reading") + if not self.seekable(): + raise io.UnsupportedOperation("The underlying file object " + "does not support seeking") + + +class DecompressReader(io.RawIOBase): + """Adapts the decompressor API to a RawIOBase reader API""" + + def readable(self): + return True + + def __init__(self, fp, decomp_factory, trailing_error=(), **decomp_args): + self._fp = fp + self._eof = False + self._pos = 0 # Current offset in decompressed stream + + # Set to size of decompressed stream once it is known, for SEEK_END + self._size = -1 + + # Save the decompressor factory and arguments. + # If the file contains multiple compressed streams, each + # stream will need a separate decompressor object. A new decompressor + # object is also needed when implementing a backwards seek(). + self._decomp_factory = decomp_factory + self._decomp_args = decomp_args + self._decompressor = self._decomp_factory(**self._decomp_args) + + # Exception class to catch from decompressor signifying invalid + # trailing data to ignore + self._trailing_error = trailing_error + + def close(self): + self._decompressor = None + return super().close() + + def seekable(self): + return self._fp.seekable() + + def readinto(self, b): + with memoryview(b) as view, view.cast("B") as byte_view: + data = self.read(len(byte_view)) + byte_view[:len(data)] = data + return len(data) + + def read(self, size=-1): + if size < 0: + return self.readall() + + if not size or self._eof: + return b"" + data = None # Default if EOF is encountered + # Depending on the input data, our call to the decompressor may not + # return any data. In this case, try again after reading another block. + while True: + if self._decompressor.eof: + rawblock = (self._decompressor.unused_data or + self._fp.read(BUFFER_SIZE)) + if not rawblock: + break + # Continue to next stream. + self._decompressor = self._decomp_factory( + **self._decomp_args) + try: + data = self._decompressor.decompress(rawblock, size) + except self._trailing_error: + # Trailing data isn't a valid compressed stream; ignore it. + break + else: + if self._decompressor.needs_input: + rawblock = self._fp.read(BUFFER_SIZE) + if not rawblock: + raise EOFError("Compressed file ended before the " + "end-of-stream marker was reached") + else: + rawblock = b"" + data = self._decompressor.decompress(rawblock, size) + if data: + break + if not data: + self._eof = True + self._size = self._pos + return b"" + self._pos += len(data) + return data + + # Rewind the file to the beginning of the data stream. + def _rewind(self): + self._fp.seek(0) + self._eof = False + self._pos = 0 + self._decompressor = self._decomp_factory(**self._decomp_args) + + def seek(self, offset, whence=io.SEEK_SET): + # Recalculate offset as an absolute file position. + if whence == io.SEEK_SET: + pass + elif whence == io.SEEK_CUR: + offset = self._pos + offset + elif whence == io.SEEK_END: + # Seeking relative to EOF - we need to know the file's size. + if self._size < 0: + while self.read(io.DEFAULT_BUFFER_SIZE): + pass + offset = self._size + offset + else: + raise ValueError("Invalid value for whence: {}".format(whence)) + + # Make it so that offset is the number of bytes to skip forward. + if offset < self._pos: + self._rewind() + else: + offset -= self._pos + + # Read and discard data until we reach the desired position. + while offset > 0: + data = self.read(min(io.DEFAULT_BUFFER_SIZE, offset)) + if not data: + break + offset -= len(data) + + return self._pos + + def tell(self): + """Return the current file position.""" + return self._pos diff --git a/Lib/_dummy_thread.py b/Lib/_dummy_thread.py index b67cfb95be8e..36e5f38ae0e8 100644 --- a/Lib/_dummy_thread.py +++ b/Lib/_dummy_thread.py @@ -140,6 +140,14 @@ def release(self): def locked(self): return self.locked_status + def __repr__(self): + return "<%s %s.%s object at %s>" % ( + "locked" if self.locked_status else "unlocked", + self.__class__.__module__, + self.__class__.__qualname__, + hex(id(self)) + ) + # Used to signal that interrupt_main was called in a "thread" _interrupt = False # True when not executing in a "thread" diff --git a/Lib/_osx_support.py b/Lib/_osx_support.py index 40fc78b6984b..b07e75d0e8cb 100644 --- a/Lib/_osx_support.py +++ b/Lib/_osx_support.py @@ -182,7 +182,7 @@ def _find_appropriate_compiler(_config_vars): # Compiler is GCC, check if it is LLVM-GCC data = _read_output("'%s' --version" % (cc.replace("'", "'\"'\"'"),)) - if 'llvm-gcc' in data: + if data and 'llvm-gcc' in data: # Found LLVM-GCC, fall back to clang cc = _find_build_tool('clang') @@ -450,8 +450,16 @@ def get_platform_osx(_config_vars, osname, release, machine): # case and disallow installs. cflags = _config_vars.get(_INITPRE+'CFLAGS', _config_vars.get('CFLAGS', '')) - if ((macrelease + '.') >= '10.4.' and - '-arch' in cflags.strip()): + if macrelease: + try: + macrelease = tuple(int(i) for i in macrelease.split('.')[0:2]) + except ValueError: + macrelease = (10, 0) + else: + # assume no universal support + macrelease = (10, 0) + + if (macrelease >= (10, 4)) and '-arch' in cflags.strip(): # The universal build will build fat binaries, but not on # systems before 10.4 diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py new file mode 100644 index 000000000000..05ba4eeee3a5 --- /dev/null +++ b/Lib/_pydecimal.py @@ -0,0 +1,6380 @@ +# Copyright (c) 2004 Python Software Foundation. +# All rights reserved. + +# Written by Eric Price <eprice at tjhsst.edu> +# and Facundo Batista <facundo at taniquetil.com.ar> +# and Raymond Hettinger <python at rcn.com> +# and Aahz <aahz at pobox.com> +# and Tim Peters + +# This module should be kept in sync with the latest updates of the +# IBM specification as it evolves. Those updates will be treated +# as bug fixes (deviation from the spec is a compatibility, usability +# bug) and will be backported. At this point the spec is stabilizing +# and the updates are becoming fewer, smaller, and less significant. + +""" +This is an implementation of decimal floating point arithmetic based on +the General Decimal Arithmetic Specification: + + http://speleotrove.com/decimal/decarith.html + +and IEEE standard 854-1987: + + http://en.wikipedia.org/wiki/IEEE_854-1987 + +Decimal floating point has finite precision with arbitrarily large bounds. + +The purpose of this module is to support arithmetic using familiar +"schoolhouse" rules and to avoid some of the tricky representation +issues associated with binary floating point. The package is especially +useful for financial applications or for contexts where users have +expectations that are at odds with binary floating point (for instance, +in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead +of 0.0; Decimal('1.00') % Decimal('0.1') returns the expected +Decimal('0.00')). + +Here are some examples of using the decimal module: + +>>> from decimal import * +>>> setcontext(ExtendedContext) +>>> Decimal(0) +Decimal('0') +>>> Decimal('1') +Decimal('1') +>>> Decimal('-.0123') +Decimal('-0.0123') +>>> Decimal(123456) +Decimal('123456') +>>> Decimal('123.45e12345678') +Decimal('1.2345E+12345680') +>>> Decimal('1.33') + Decimal('1.27') +Decimal('2.60') +>>> Decimal('12.34') + Decimal('3.87') - Decimal('18.41') +Decimal('-2.20') +>>> dig = Decimal(1) +>>> print(dig / Decimal(3)) +0.333333333 +>>> getcontext().prec = 18 +>>> print(dig / Decimal(3)) +0.333333333333333333 +>>> print(dig.sqrt()) +1 +>>> print(Decimal(3).sqrt()) +1.73205080756887729 +>>> print(Decimal(3) ** 123) +4.85192780976896427E+58 +>>> inf = Decimal(1) / Decimal(0) +>>> print(inf) +Infinity +>>> neginf = Decimal(-1) / Decimal(0) +>>> print(neginf) +-Infinity +>>> print(neginf + inf) +NaN +>>> print(neginf * inf) +-Infinity +>>> print(dig / 0) +Infinity +>>> getcontext().traps[DivisionByZero] = 1 +>>> print(dig / 0) +Traceback (most recent call last): + ... + ... + ... +decimal.DivisionByZero: x / 0 +>>> c = Context() +>>> c.traps[InvalidOperation] = 0 +>>> print(c.flags[InvalidOperation]) +0 +>>> c.divide(Decimal(0), Decimal(0)) +Decimal('NaN') +>>> c.traps[InvalidOperation] = 1 +>>> print(c.flags[InvalidOperation]) +1 +>>> c.flags[InvalidOperation] = 0 +>>> print(c.flags[InvalidOperation]) +0 +>>> print(c.divide(Decimal(0), Decimal(0))) +Traceback (most recent call last): + ... + ... + ... +decimal.InvalidOperation: 0 / 0 +>>> print(c.flags[InvalidOperation]) +1 +>>> c.flags[InvalidOperation] = 0 +>>> c.traps[InvalidOperation] = 0 +>>> print(c.divide(Decimal(0), Decimal(0))) +NaN +>>> print(c.flags[InvalidOperation]) +1 +>>> +""" + +__all__ = [ + # Two major classes + 'Decimal', 'Context', + + # Named tuple representation + 'DecimalTuple', + + # Contexts + 'DefaultContext', 'BasicContext', 'ExtendedContext', + + # Exceptions + 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero', + 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow', + 'FloatOperation', + + # Exceptional conditions that trigger InvalidOperation + 'DivisionImpossible', 'InvalidContext', 'ConversionSyntax', 'DivisionUndefined', + + # Constants for use in setting up contexts + 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING', + 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN', 'ROUND_05UP', + + # Functions for manipulating contexts + 'setcontext', 'getcontext', 'localcontext', + + # Limits for the C version for compatibility + 'MAX_PREC', 'MAX_EMAX', 'MIN_EMIN', 'MIN_ETINY', + + # C version: compile time choice that enables the thread local context + 'HAVE_THREADS' +] + +__xname__ = __name__ # sys.modules lookup (--without-threads) +__name__ = 'decimal' # For pickling +__version__ = '1.70' # Highest version of the spec this complies with + # See http://speleotrove.com/decimal/ +__libmpdec_version__ = "2.4.1" # compatible libmpdec version + +import math as _math +import numbers as _numbers +import sys + +try: + from collections import namedtuple as _namedtuple + DecimalTuple = _namedtuple('DecimalTuple', 'sign digits exponent') +except ImportError: + DecimalTuple = lambda *args: args + +# Rounding +ROUND_DOWN = 'ROUND_DOWN' +ROUND_HALF_UP = 'ROUND_HALF_UP' +ROUND_HALF_EVEN = 'ROUND_HALF_EVEN' +ROUND_CEILING = 'ROUND_CEILING' +ROUND_FLOOR = 'ROUND_FLOOR' +ROUND_UP = 'ROUND_UP' +ROUND_HALF_DOWN = 'ROUND_HALF_DOWN' +ROUND_05UP = 'ROUND_05UP' + +# Compatibility with the C version +HAVE_THREADS = True +if sys.maxsize == 2**63-1: + MAX_PREC = 999999999999999999 + MAX_EMAX = 999999999999999999 + MIN_EMIN = -999999999999999999 +else: + MAX_PREC = 425000000 + MAX_EMAX = 425000000 + MIN_EMIN = -425000000 + +MIN_ETINY = MIN_EMIN - (MAX_PREC-1) + +# Errors + +class DecimalException(ArithmeticError): + """Base exception class. + + Used exceptions derive from this. + If an exception derives from another exception besides this (such as + Underflow (Inexact, Rounded, Subnormal) that indicates that it is only + called if the others are present. This isn't actually used for + anything, though. + + handle -- Called when context._raise_error is called and the + trap_enabler is not set. First argument is self, second is the + context. More arguments can be given, those being after + the explanation in _raise_error (For example, + context._raise_error(NewError, '(-x)!', self._sign) would + call NewError().handle(context, self._sign).) + + To define a new exception, it should be sufficient to have it derive + from DecimalException. + """ + def handle(self, context, *args): + pass + + +class Clamped(DecimalException): + """Exponent of a 0 changed to fit bounds. + + This occurs and signals clamped if the exponent of a result has been + altered in order to fit the constraints of a specific concrete + representation. This may occur when the exponent of a zero result would + be outside the bounds of a representation, or when a large normal + number would have an encoded exponent that cannot be represented. In + this latter case, the exponent is reduced to fit and the corresponding + number of zero digits are appended to the coefficient ("fold-down"). + """ + +class InvalidOperation(DecimalException): + """An invalid operation was performed. + + Various bad things cause this: + + Something creates a signaling NaN + -INF + INF + 0 * (+-)INF + (+-)INF / (+-)INF + x % 0 + (+-)INF % x + x._rescale( non-integer ) + sqrt(-x) , x > 0 + 0 ** 0 + x ** (non-integer) + x ** (+-)INF + An operand is invalid + + The result of the operation after these is a quiet positive NaN, + except when the cause is a signaling NaN, in which case the result is + also a quiet NaN, but with the original sign, and an optional + diagnostic information. + """ + def handle(self, context, *args): + if args: + ans = _dec_from_triple(args[0]._sign, args[0]._int, 'n', True) + return ans._fix_nan(context) + return _NaN + +class ConversionSyntax(InvalidOperation): + """Trying to convert badly formed string. + + This occurs and signals invalid-operation if an string is being + converted to a number and it does not conform to the numeric string + syntax. The result is [0,qNaN]. + """ + def handle(self, context, *args): + return _NaN + +class DivisionByZero(DecimalException, ZeroDivisionError): + """Division by 0. + + This occurs and signals division-by-zero if division of a finite number + by zero was attempted (during a divide-integer or divide operation, or a + power operation with negative right-hand operand), and the dividend was + not zero. + + The result of the operation is [sign,inf], where sign is the exclusive + or of the signs of the operands for divide, or is 1 for an odd power of + -0, for power. + """ + + def handle(self, context, sign, *args): + return _SignedInfinity[sign] + +class DivisionImpossible(InvalidOperation): + """Cannot perform the division adequately. + + This occurs and signals invalid-operation if the integer result of a + divide-integer or remainder operation had too many digits (would be + longer than precision). The result is [0,qNaN]. + """ + + def handle(self, context, *args): + return _NaN + +class DivisionUndefined(InvalidOperation, ZeroDivisionError): + """Undefined result of division. + + This occurs and signals invalid-operation if division by zero was + attempted (during a divide-integer, divide, or remainder operation), and + the dividend is also zero. The result is [0,qNaN]. + """ + + def handle(self, context, *args): + return _NaN + +class Inexact(DecimalException): + """Had to round, losing information. + + This occurs and signals inexact whenever the result of an operation is + not exact (that is, it needed to be rounded and any discarded digits + were non-zero), or if an overflow or underflow condition occurs. The + result in all cases is unchanged. + + The inexact signal may be tested (or trapped) to determine if a given + operation (or sequence of operations) was inexact. + """ + +class InvalidContext(InvalidOperation): + """Invalid context. Unknown rounding, for example. + + This occurs and signals invalid-operation if an invalid context was + detected during an operation. This can occur if contexts are not checked + on creation and either the precision exceeds the capability of the + underlying concrete representation or an unknown or unsupported rounding + was specified. These aspects of the context need only be checked when + the values are required to be used. The result is [0,qNaN]. + """ + + def handle(self, context, *args): + return _NaN + +class Rounded(DecimalException): + """Number got rounded (not necessarily changed during rounding). + + This occurs and signals rounded whenever the result of an operation is + rounded (that is, some zero or non-zero digits were discarded from the + coefficient), or if an overflow or underflow condition occurs. The + result in all cases is unchanged. + + The rounded signal may be tested (or trapped) to determine if a given + operation (or sequence of operations) caused a loss of precision. + """ + +class Subnormal(DecimalException): + """Exponent < Emin before rounding. + + This occurs and signals subnormal whenever the result of a conversion or + operation is subnormal (that is, its adjusted exponent is less than + Emin, before any rounding). The result in all cases is unchanged. + + The subnormal signal may be tested (or trapped) to determine if a given + or operation (or sequence of operations) yielded a subnormal result. + """ + +class Overflow(Inexact, Rounded): + """Numerical overflow. + + This occurs and signals overflow if the adjusted exponent of a result + (from a conversion or from an operation that is not an attempt to divide + by zero), after rounding, would be greater than the largest value that + can be handled by the implementation (the value Emax). + + The result depends on the rounding mode: + + For round-half-up and round-half-even (and for round-half-down and + round-up, if implemented), the result of the operation is [sign,inf], + where sign is the sign of the intermediate result. For round-down, the + result is the largest finite number that can be represented in the + current precision, with the sign of the intermediate result. For + round-ceiling, the result is the same as for round-down if the sign of + the intermediate result is 1, or is [0,inf] otherwise. For round-floor, + the result is the same as for round-down if the sign of the intermediate + result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded + will also be raised. + """ + + def handle(self, context, sign, *args): + if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN, + ROUND_HALF_DOWN, ROUND_UP): + return _SignedInfinity[sign] + if sign == 0: + if context.rounding == ROUND_CEILING: + return _SignedInfinity[sign] + return _dec_from_triple(sign, '9'*context.prec, + context.Emax-context.prec+1) + if sign == 1: + if context.rounding == ROUND_FLOOR: + return _SignedInfinity[sign] + return _dec_from_triple(sign, '9'*context.prec, + context.Emax-context.prec+1) + + +class Underflow(Inexact, Rounded, Subnormal): + """Numerical underflow with result rounded to 0. + + This occurs and signals underflow if a result is inexact and the + adjusted exponent of the result would be smaller (more negative) than + the smallest value that can be handled by the implementation (the value + Emin). That is, the result is both inexact and subnormal. + + The result after an underflow will be a subnormal number rounded, if + necessary, so that its exponent is not less than Etiny. This may result + in 0 with the sign of the intermediate result and an exponent of Etiny. + + In all cases, Inexact, Rounded, and Subnormal will also be raised. + """ + +class FloatOperation(DecimalException, TypeError): + """Enable stricter semantics for mixing floats and Decimals. + + If the signal is not trapped (default), mixing floats and Decimals is + permitted in the Decimal() constructor, context.create_decimal() and + all comparison operators. Both conversion and comparisons are exact. + Any occurrence of a mixed operation is silently recorded by setting + FloatOperation in the context flags. Explicit conversions with + Decimal.from_float() or context.create_decimal_from_float() do not + set the flag. + + Otherwise (the signal is trapped), only equality comparisons and explicit + conversions are silent. All other mixed operations raise FloatOperation. + """ + +# List of public traps and flags +_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded, + Underflow, InvalidOperation, Subnormal, FloatOperation] + +# Map conditions (per the spec) to signals +_condition_map = {ConversionSyntax:InvalidOperation, + DivisionImpossible:InvalidOperation, + DivisionUndefined:InvalidOperation, + InvalidContext:InvalidOperation} + +# Valid rounding modes +_rounding_modes = (ROUND_DOWN, ROUND_HALF_UP, ROUND_HALF_EVEN, ROUND_CEILING, + ROUND_FLOOR, ROUND_UP, ROUND_HALF_DOWN, ROUND_05UP) + +##### Context Functions ################################################## + +# The getcontext() and setcontext() function manage access to a thread-local +# current context. Py2.4 offers direct support for thread locals. If that +# is not available, use threading.current_thread() which is slower but will +# work for older Pythons. If threads are not part of the build, create a +# mock threading object with threading.local() returning the module namespace. + +try: + import threading +except ImportError: + # Python was compiled without threads; create a mock object instead + class MockThreading(object): + def local(self, sys=sys): + return sys.modules[__xname__] + threading = MockThreading() + del MockThreading + +try: + threading.local + +except AttributeError: + + # To fix reloading, force it to create a new context + # Old contexts have different exceptions in their dicts, making problems. + if hasattr(threading.current_thread(), '__decimal_context__'): + del threading.current_thread().__decimal_context__ + + def setcontext(context): + """Set this thread's context to context.""" + if context in (DefaultContext, BasicContext, ExtendedContext): + context = context.copy() + context.clear_flags() + threading.current_thread().__decimal_context__ = context + + def getcontext(): + """Returns this thread's context. + + If this thread does not yet have a context, returns + a new context and sets this thread's context. + New contexts are copies of DefaultContext. + """ + try: + return threading.current_thread().__decimal_context__ + except AttributeError: + context = Context() + threading.current_thread().__decimal_context__ = context + return context + +else: + + local = threading.local() + if hasattr(local, '__decimal_context__'): + del local.__decimal_context__ + + def getcontext(_local=local): + """Returns this thread's context. + + If this thread does not yet have a context, returns + a new context and sets this thread's context. + New contexts are copies of DefaultContext. + """ + try: + return _local.__decimal_context__ + except AttributeError: + context = Context() + _local.__decimal_context__ = context + return context + + def setcontext(context, _local=local): + """Set this thread's context to context.""" + if context in (DefaultContext, BasicContext, ExtendedContext): + context = context.copy() + context.clear_flags() + _local.__decimal_context__ = context + + del threading, local # Don't contaminate the namespace + +def localcontext(ctx=None): + """Return a context manager for a copy of the supplied context + + Uses a copy of the current context if no context is specified + The returned context manager creates a local decimal context + in a with statement: + def sin(x): + with localcontext() as ctx: + ctx.prec += 2 + # Rest of sin calculation algorithm + # uses a precision 2 greater than normal + return +s # Convert result to normal precision + + def sin(x): + with localcontext(ExtendedContext): + # Rest of sin calculation algorithm + # uses the Extended Context from the + # General Decimal Arithmetic Specification + return +s # Convert result to normal context + + >>> setcontext(DefaultContext) + >>> print(getcontext().prec) + 28 + >>> with localcontext(): + ... ctx = getcontext() + ... ctx.prec += 2 + ... print(ctx.prec) + ... + 30 + >>> with localcontext(ExtendedContext): + ... print(getcontext().prec) + ... + 9 + >>> print(getcontext().prec) + 28 + """ + if ctx is None: ctx = getcontext() + return _ContextManager(ctx) + + +##### Decimal class ####################################################### + +# Do not subclass Decimal from numbers.Real and do not register it as such +# (because Decimals are not interoperable with floats). See the notes in +# numbers.py for more detail. + +class Decimal(object): + """Floating point class for decimal arithmetic.""" + + __slots__ = ('_exp','_int','_sign', '_is_special') + # Generally, the value of the Decimal instance is given by + # (-1)**_sign * _int * 10**_exp + # Special values are signified by _is_special == True + + # We're immutable, so use __new__ not __init__ + def __new__(cls, value="0", context=None): + """Create a decimal point instance. + + >>> Decimal('3.14') # string input + Decimal('3.14') + >>> Decimal((0, (3, 1, 4), -2)) # tuple (sign, digit_tuple, exponent) + Decimal('3.14') + >>> Decimal(314) # int + Decimal('314') + >>> Decimal(Decimal(314)) # another decimal instance + Decimal('314') + >>> Decimal(' 3.14 \\n') # leading and trailing whitespace okay + Decimal('3.14') + """ + + # Note that the coefficient, self._int, is actually stored as + # a string rather than as a tuple of digits. This speeds up + # the "digits to integer" and "integer to digits" conversions + # that are used in almost every arithmetic operation on + # Decimals. This is an internal detail: the as_tuple function + # and the Decimal constructor still deal with tuples of + # digits. + + self = object.__new__(cls) + + # From a string + # REs insist on real strings, so we can too. + if isinstance(value, str): + m = _parser(value.strip()) + if m is None: + if context is None: + context = getcontext() + return context._raise_error(ConversionSyntax, + "Invalid literal for Decimal: %r" % value) + + if m.group('sign') == "-": + self._sign = 1 + else: + self._sign = 0 + intpart = m.group('int') + if intpart is not None: + # finite number + fracpart = m.group('frac') or '' + exp = int(m.group('exp') or '0') + self._int = str(int(intpart+fracpart)) + self._exp = exp - len(fracpart) + self._is_special = False + else: + diag = m.group('diag') + if diag is not None: + # NaN + self._int = str(int(diag or '0')).lstrip('0') + if m.group('signal'): + self._exp = 'N' + else: + self._exp = 'n' + else: + # infinity + self._int = '0' + self._exp = 'F' + self._is_special = True + return self + + # From an integer + if isinstance(value, int): + if value >= 0: + self._sign = 0 + else: + self._sign = 1 + self._exp = 0 + self._int = str(abs(value)) + self._is_special = False + return self + + # From another decimal + if isinstance(value, Decimal): + self._exp = value._exp + self._sign = value._sign + self._int = value._int + self._is_special = value._is_special + return self + + # From an internal working value + if isinstance(value, _WorkRep): + self._sign = value.sign + self._int = str(value.int) + self._exp = int(value.exp) + self._is_special = False + return self + + # tuple/list conversion (possibly from as_tuple()) + if isinstance(value, (list,tuple)): + if len(value) != 3: + raise ValueError('Invalid tuple size in creation of Decimal ' + 'from list or tuple. The list or tuple ' + 'should have exactly three elements.') + # process sign. The isinstance test rejects floats + if not (isinstance(value[0], int) and value[0] in (0,1)): + raise ValueError("Invalid sign. The first value in the tuple " + "should be an integer; either 0 for a " + "positive number or 1 for a negative number.") + self._sign = value[0] + if value[2] == 'F': + # infinity: value[1] is ignored + self._int = '0' + self._exp = value[2] + self._is_special = True + else: + # process and validate the digits in value[1] + digits = [] + for digit in value[1]: + if isinstance(digit, int) and 0 <= digit <= 9: + # skip leading zeros + if digits or digit != 0: + digits.append(digit) + else: + raise ValueError("The second value in the tuple must " + "be composed of integers in the range " + "0 through 9.") + if value[2] in ('n', 'N'): + # NaN: digits form the diagnostic + self._int = ''.join(map(str, digits)) + self._exp = value[2] + self._is_special = True + elif isinstance(value[2], int): + # finite number: digits give the coefficient + self._int = ''.join(map(str, digits or [0])) + self._exp = value[2] + self._is_special = False + else: + raise ValueError("The third value in the tuple must " + "be an integer, or one of the " + "strings 'F', 'n', 'N'.") + return self + + if isinstance(value, float): + if context is None: + context = getcontext() + context._raise_error(FloatOperation, + "strict semantics for mixing floats and Decimals are " + "enabled") + value = Decimal.from_float(value) + self._exp = value._exp + self._sign = value._sign + self._int = value._int + self._is_special = value._is_special + return self + + raise TypeError("Cannot convert %r to Decimal" % value) + + @classmethod + def from_float(cls, f): + """Converts a float to a decimal number, exactly. + + Note that Decimal.from_float(0.1) is not the same as Decimal('0.1'). + Since 0.1 is not exactly representable in binary floating point, the + value is stored as the nearest representable value which is + 0x1.999999999999ap-4. The exact equivalent of the value in decimal + is 0.1000000000000000055511151231257827021181583404541015625. + + >>> Decimal.from_float(0.1) + Decimal('0.1000000000000000055511151231257827021181583404541015625') + >>> Decimal.from_float(float('nan')) + Decimal('NaN') + >>> Decimal.from_float(float('inf')) + Decimal('Infinity') + >>> Decimal.from_float(-float('inf')) + Decimal('-Infinity') + >>> Decimal.from_float(-0.0) + Decimal('-0') + + """ + if isinstance(f, int): # handle integer inputs + return cls(f) + if not isinstance(f, float): + raise TypeError("argument must be int or float.") + if _math.isinf(f) or _math.isnan(f): + return cls(repr(f)) + if _math.copysign(1.0, f) == 1.0: + sign = 0 + else: + sign = 1 + n, d = abs(f).as_integer_ratio() + k = d.bit_length() - 1 + result = _dec_from_triple(sign, str(n*5**k), -k) + if cls is Decimal: + return result + else: + return cls(result) + + def _isnan(self): + """Returns whether the number is not actually one. + + 0 if a number + 1 if NaN + 2 if sNaN + """ + if self._is_special: + exp = self._exp + if exp == 'n': + return 1 + elif exp == 'N': + return 2 + return 0 + + def _isinfinity(self): + """Returns whether the number is infinite + + 0 if finite or not a number + 1 if +INF + -1 if -INF + """ + if self._exp == 'F': + if self._sign: + return -1 + return 1 + return 0 + + def _check_nans(self, other=None, context=None): + """Returns whether the number is not actually one. + + if self, other are sNaN, signal + if self, other are NaN return nan + return 0 + + Done before operations. + """ + + self_is_nan = self._isnan() + if other is None: + other_is_nan = False + else: + other_is_nan = other._isnan() + + if self_is_nan or other_is_nan: + if context is None: + context = getcontext() + + if self_is_nan == 2: + return context._raise_error(InvalidOperation, 'sNaN', + self) + if other_is_nan == 2: + return context._raise_error(InvalidOperation, 'sNaN', + other) + if self_is_nan: + return self._fix_nan(context) + + return other._fix_nan(context) + return 0 + + def _compare_check_nans(self, other, context): + """Version of _check_nans used for the signaling comparisons + compare_signal, __le__, __lt__, __ge__, __gt__. + + Signal InvalidOperation if either self or other is a (quiet + or signaling) NaN. Signaling NaNs take precedence over quiet + NaNs. + + Return 0 if neither operand is a NaN. + + """ + if context is None: + context = getcontext() + + if self._is_special or other._is_special: + if self.is_snan(): + return context._raise_error(InvalidOperation, + 'comparison involving sNaN', + self) + elif other.is_snan(): + return context._raise_error(InvalidOperation, + 'comparison involving sNaN', + other) + elif self.is_qnan(): + return context._raise_error(InvalidOperation, + 'comparison involving NaN', + self) + elif other.is_qnan(): + return context._raise_error(InvalidOperation, + 'comparison involving NaN', + other) + return 0 + + def __bool__(self): + """Return True if self is nonzero; otherwise return False. + + NaNs and infinities are considered nonzero. + """ + return self._is_special or self._int != '0' + + def _cmp(self, other): + """Compare the two non-NaN decimal instances self and other. + + Returns -1 if self < other, 0 if self == other and 1 + if self > other. This routine is for internal use only.""" + + if self._is_special or other._is_special: + self_inf = self._isinfinity() + other_inf = other._isinfinity() + if self_inf == other_inf: + return 0 + elif self_inf < other_inf: + return -1 + else: + return 1 + + # check for zeros; Decimal('0') == Decimal('-0') + if not self: + if not other: + return 0 + else: + return -((-1)**other._sign) + if not other: + return (-1)**self._sign + + # If different signs, neg one is less + if other._sign < self._sign: + return -1 + if self._sign < other._sign: + return 1 + + self_adjusted = self.adjusted() + other_adjusted = other.adjusted() + if self_adjusted == other_adjusted: + self_padded = self._int + '0'*(self._exp - other._exp) + other_padded = other._int + '0'*(other._exp - self._exp) + if self_padded == other_padded: + return 0 + elif self_padded < other_padded: + return -(-1)**self._sign + else: + return (-1)**self._sign + elif self_adjusted > other_adjusted: + return (-1)**self._sign + else: # self_adjusted < other_adjusted + return -((-1)**self._sign) + + # Note: The Decimal standard doesn't cover rich comparisons for + # Decimals. In particular, the specification is silent on the + # subject of what should happen for a comparison involving a NaN. + # We take the following approach: + # + # == comparisons involving a quiet NaN always return False + # != comparisons involving a quiet NaN always return True + # == or != comparisons involving a signaling NaN signal + # InvalidOperation, and return False or True as above if the + # InvalidOperation is not trapped. + # <, >, <= and >= comparisons involving a (quiet or signaling) + # NaN signal InvalidOperation, and return False if the + # InvalidOperation is not trapped. + # + # This behavior is designed to conform as closely as possible to + # that specified by IEEE 754. + + def __eq__(self, other, context=None): + self, other = _convert_for_comparison(self, other, equality_op=True) + if other is NotImplemented: + return other + if self._check_nans(other, context): + return False + return self._cmp(other) == 0 + + def __lt__(self, other, context=None): + self, other = _convert_for_comparison(self, other) + if other is NotImplemented: + return other + ans = self._compare_check_nans(other, context) + if ans: + return False + return self._cmp(other) < 0 + + def __le__(self, other, context=None): + self, other = _convert_for_comparison(self, other) + if other is NotImplemented: + return other + ans = self._compare_check_nans(other, context) + if ans: + return False + return self._cmp(other) <= 0 + + def __gt__(self, other, context=None): + self, other = _convert_for_comparison(self, other) + if other is NotImplemented: + return other + ans = self._compare_check_nans(other, context) + if ans: + return False + return self._cmp(other) > 0 + + def __ge__(self, other, context=None): + self, other = _convert_for_comparison(self, other) + if other is NotImplemented: + return other + ans = self._compare_check_nans(other, context) + if ans: + return False + return self._cmp(other) >= 0 + + def compare(self, other, context=None): + """Compare self to other. Return a decimal value: + + a or b is a NaN ==> Decimal('NaN') + a < b ==> Decimal('-1') + a == b ==> Decimal('0') + a > b ==> Decimal('1') + """ + other = _convert_other(other, raiseit=True) + + # Compare(NaN, NaN) = NaN + if (self._is_special or other and other._is_special): + ans = self._check_nans(other, context) + if ans: + return ans + + return Decimal(self._cmp(other)) + + def __hash__(self): + """x.__hash__() <==> hash(x)""" + + # In order to make sure that the hash of a Decimal instance + # agrees with the hash of a numerically equal integer, float + # or Fraction, we follow the rules for numeric hashes outlined + # in the documentation. (See library docs, 'Built-in Types'). + if self._is_special: + if self.is_snan(): + raise TypeError('Cannot hash a signaling NaN value.') + elif self.is_nan(): + return _PyHASH_NAN + else: + if self._sign: + return -_PyHASH_INF + else: + return _PyHASH_INF + + if self._exp >= 0: + exp_hash = pow(10, self._exp, _PyHASH_MODULUS) + else: + exp_hash = pow(_PyHASH_10INV, -self._exp, _PyHASH_MODULUS) + hash_ = int(self._int) * exp_hash % _PyHASH_MODULUS + ans = hash_ if self >= 0 else -hash_ + return -2 if ans == -1 else ans + + def as_tuple(self): + """Represents the number as a triple tuple. + + To show the internals exactly as they are. + """ + return DecimalTuple(self._sign, tuple(map(int, self._int)), self._exp) + + def __repr__(self): + """Represents the number as an instance of Decimal.""" + # Invariant: eval(repr(d)) == d + return "Decimal('%s')" % str(self) + + def __str__(self, eng=False, context=None): + """Return string representation of the number in scientific notation. + + Captures all of the information in the underlying representation. + """ + + sign = ['', '-'][self._sign] + if self._is_special: + if self._exp == 'F': + return sign + 'Infinity' + elif self._exp == 'n': + return sign + 'NaN' + self._int + else: # self._exp == 'N' + return sign + 'sNaN' + self._int + + # number of digits of self._int to left of decimal point + leftdigits = self._exp + len(self._int) + + # dotplace is number of digits of self._int to the left of the + # decimal point in the mantissa of the output string (that is, + # after adjusting the exponent) + if self._exp <= 0 and leftdigits > -6: + # no exponent required + dotplace = leftdigits + elif not eng: + # usual scientific notation: 1 digit on left of the point + dotplace = 1 + elif self._int == '0': + # engineering notation, zero + dotplace = (leftdigits + 1) % 3 - 1 + else: + # engineering notation, nonzero + dotplace = (leftdigits - 1) % 3 + 1 + + if dotplace <= 0: + intpart = '0' + fracpart = '.' + '0'*(-dotplace) + self._int + elif dotplace >= len(self._int): + intpart = self._int+'0'*(dotplace-len(self._int)) + fracpart = '' + else: + intpart = self._int[:dotplace] + fracpart = '.' + self._int[dotplace:] + if leftdigits == dotplace: + exp = '' + else: + if context is None: + context = getcontext() + exp = ['e', 'E'][context.capitals] + "%+d" % (leftdigits-dotplace) + + return sign + intpart + fracpart + exp + + def to_eng_string(self, context=None): + """Convert to engineering-type string. + + Engineering notation has an exponent which is a multiple of 3, so there + are up to 3 digits left of the decimal place. + + Same rules for when in exponential and when as a value as in __str__. + """ + return self.__str__(eng=True, context=context) + + def __neg__(self, context=None): + """Returns a copy with the sign switched. + + Rounds, if it has reason. + """ + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + + if context is None: + context = getcontext() + + if not self and context.rounding != ROUND_FLOOR: + # -Decimal('0') is Decimal('0'), not Decimal('-0'), except + # in ROUND_FLOOR rounding mode. + ans = self.copy_abs() + else: + ans = self.copy_negate() + + return ans._fix(context) + + def __pos__(self, context=None): + """Returns a copy, unless it is a sNaN. + + Rounds the number (if more then precision digits) + """ + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + + if context is None: + context = getcontext() + + if not self and context.rounding != ROUND_FLOOR: + # + (-0) = 0, except in ROUND_FLOOR rounding mode. + ans = self.copy_abs() + else: + ans = Decimal(self) + + return ans._fix(context) + + def __abs__(self, round=True, context=None): + """Returns the absolute value of self. + + If the keyword argument 'round' is false, do not round. The + expression self.__abs__(round=False) is equivalent to + self.copy_abs(). + """ + if not round: + return self.copy_abs() + + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + + if self._sign: + ans = self.__neg__(context=context) + else: + ans = self.__pos__(context=context) + + return ans + + def __add__(self, other, context=None): + """Returns self + other. + + -INF + INF (or the reverse) cause InvalidOperation errors. + """ + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + if self._is_special or other._is_special: + ans = self._check_nans(other, context) + if ans: + return ans + + if self._isinfinity(): + # If both INF, same sign => same as both, opposite => error. + if self._sign != other._sign and other._isinfinity(): + return context._raise_error(InvalidOperation, '-INF + INF') + return Decimal(self) + if other._isinfinity(): + return Decimal(other) # Can't both be infinity here + + exp = min(self._exp, other._exp) + negativezero = 0 + if context.rounding == ROUND_FLOOR and self._sign != other._sign: + # If the answer is 0, the sign should be negative, in this case. + negativezero = 1 + + if not self and not other: + sign = min(self._sign, other._sign) + if negativezero: + sign = 1 + ans = _dec_from_triple(sign, '0', exp) + ans = ans._fix(context) + return ans + if not self: + exp = max(exp, other._exp - context.prec-1) + ans = other._rescale(exp, context.rounding) + ans = ans._fix(context) + return ans + if not other: + exp = max(exp, self._exp - context.prec-1) + ans = self._rescale(exp, context.rounding) + ans = ans._fix(context) + return ans + + op1 = _WorkRep(self) + op2 = _WorkRep(other) + op1, op2 = _normalize(op1, op2, context.prec) + + result = _WorkRep() + if op1.sign != op2.sign: + # Equal and opposite + if op1.int == op2.int: + ans = _dec_from_triple(negativezero, '0', exp) + ans = ans._fix(context) + return ans + if op1.int < op2.int: + op1, op2 = op2, op1 + # OK, now abs(op1) > abs(op2) + if op1.sign == 1: + result.sign = 1 + op1.sign, op2.sign = op2.sign, op1.sign + else: + result.sign = 0 + # So we know the sign, and op1 > 0. + elif op1.sign == 1: + result.sign = 1 + op1.sign, op2.sign = (0, 0) + else: + result.sign = 0 + # Now, op1 > abs(op2) > 0 + + if op2.sign == 0: + result.int = op1.int + op2.int + else: + result.int = op1.int - op2.int + + result.exp = op1.exp + ans = Decimal(result) + ans = ans._fix(context) + return ans + + __radd__ = __add__ + + def __sub__(self, other, context=None): + """Return self - other""" + other = _convert_other(other) + if other is NotImplemented: + return other + + if self._is_special or other._is_special: + ans = self._check_nans(other, context=context) + if ans: + return ans + + # self - other is computed as self + other.copy_negate() + return self.__add__(other.copy_negate(), context=context) + + def __rsub__(self, other, context=None): + """Return other - self""" + other = _convert_other(other) + if other is NotImplemented: + return other + + return other.__sub__(self, context=context) + + def __mul__(self, other, context=None): + """Return self * other. + + (+-) INF * 0 (or its reverse) raise InvalidOperation. + """ + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + resultsign = self._sign ^ other._sign + + if self._is_special or other._is_special: + ans = self._check_nans(other, context) + if ans: + return ans + + if self._isinfinity(): + if not other: + return context._raise_error(InvalidOperation, '(+-)INF * 0') + return _SignedInfinity[resultsign] + + if other._isinfinity(): + if not self: + return context._raise_error(InvalidOperation, '0 * (+-)INF') + return _SignedInfinity[resultsign] + + resultexp = self._exp + other._exp + + # Special case for multiplying by zero + if not self or not other: + ans = _dec_from_triple(resultsign, '0', resultexp) + # Fixing in case the exponent is out of bounds + ans = ans._fix(context) + return ans + + # Special case for multiplying by power of 10 + if self._int == '1': + ans = _dec_from_triple(resultsign, other._int, resultexp) + ans = ans._fix(context) + return ans + if other._int == '1': + ans = _dec_from_triple(resultsign, self._int, resultexp) + ans = ans._fix(context) + return ans + + op1 = _WorkRep(self) + op2 = _WorkRep(other) + + ans = _dec_from_triple(resultsign, str(op1.int * op2.int), resultexp) + ans = ans._fix(context) + + return ans + __rmul__ = __mul__ + + def __truediv__(self, other, context=None): + """Return self / other.""" + other = _convert_other(other) + if other is NotImplemented: + return NotImplemented + + if context is None: + context = getcontext() + + sign = self._sign ^ other._sign + + if self._is_special or other._is_special: + ans = self._check_nans(other, context) + if ans: + return ans + + if self._isinfinity() and other._isinfinity(): + return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF') + + if self._isinfinity(): + return _SignedInfinity[sign] + + if other._isinfinity(): + context._raise_error(Clamped, 'Division by infinity') + return _dec_from_triple(sign, '0', context.Etiny()) + + # Special cases for zeroes + if not other: + if not self: + return context._raise_error(DivisionUndefined, '0 / 0') + return context._raise_error(DivisionByZero, 'x / 0', sign) + + if not self: + exp = self._exp - other._exp + coeff = 0 + else: + # OK, so neither = 0, INF or NaN + shift = len(other._int) - len(self._int) + context.prec + 1 + exp = self._exp - other._exp - shift + op1 = _WorkRep(self) + op2 = _WorkRep(other) + if shift >= 0: + coeff, remainder = divmod(op1.int * 10**shift, op2.int) + else: + coeff, remainder = divmod(op1.int, op2.int * 10**-shift) + if remainder: + # result is not exact; adjust to ensure correct rounding + if coeff % 5 == 0: + coeff += 1 + else: + # result is exact; get as close to ideal exponent as possible + ideal_exp = self._exp - other._exp + while exp < ideal_exp and coeff % 10 == 0: + coeff //= 10 + exp += 1 + + ans = _dec_from_triple(sign, str(coeff), exp) + return ans._fix(context) + + def _divide(self, other, context): + """Return (self // other, self % other), to context.prec precision. + + Assumes that neither self nor other is a NaN, that self is not + infinite and that other is nonzero. + """ + sign = self._sign ^ other._sign + if other._isinfinity(): + ideal_exp = self._exp + else: + ideal_exp = min(self._exp, other._exp) + + expdiff = self.adjusted() - other.adjusted() + if not self or other._isinfinity() or expdiff <= -2: + return (_dec_from_triple(sign, '0', 0), + self._rescale(ideal_exp, context.rounding)) + if expdiff <= context.prec: + op1 = _WorkRep(self) + op2 = _WorkRep(other) + if op1.exp >= op2.exp: + op1.int *= 10**(op1.exp - op2.exp) + else: + op2.int *= 10**(op2.exp - op1.exp) + q, r = divmod(op1.int, op2.int) + if q < 10**context.prec: + return (_dec_from_triple(sign, str(q), 0), + _dec_from_triple(self._sign, str(r), ideal_exp)) + + # Here the quotient is too large to be representable + ans = context._raise_error(DivisionImpossible, + 'quotient too large in //, % or divmod') + return ans, ans + + def __rtruediv__(self, other, context=None): + """Swaps self/other and returns __truediv__.""" + other = _convert_other(other) + if other is NotImplemented: + return other + return other.__truediv__(self, context=context) + + def __divmod__(self, other, context=None): + """ + Return (self // other, self % other) + """ + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + ans = self._check_nans(other, context) + if ans: + return (ans, ans) + + sign = self._sign ^ other._sign + if self._isinfinity(): + if other._isinfinity(): + ans = context._raise_error(InvalidOperation, 'divmod(INF, INF)') + return ans, ans + else: + return (_SignedInfinity[sign], + context._raise_error(InvalidOperation, 'INF % x')) + + if not other: + if not self: + ans = context._raise_error(DivisionUndefined, 'divmod(0, 0)') + return ans, ans + else: + return (context._raise_error(DivisionByZero, 'x // 0', sign), + context._raise_error(InvalidOperation, 'x % 0')) + + quotient, remainder = self._divide(other, context) + remainder = remainder._fix(context) + return quotient, remainder + + def __rdivmod__(self, other, context=None): + """Swaps self/other and returns __divmod__.""" + other = _convert_other(other) + if other is NotImplemented: + return other + return other.__divmod__(self, context=context) + + def __mod__(self, other, context=None): + """ + self % other + """ + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + ans = self._check_nans(other, context) + if ans: + return ans + + if self._isinfinity(): + return context._raise_error(InvalidOperation, 'INF % x') + elif not other: + if self: + return context._raise_error(InvalidOperation, 'x % 0') + else: + return context._raise_error(DivisionUndefined, '0 % 0') + + remainder = self._divide(other, context)[1] + remainder = remainder._fix(context) + return remainder + + def __rmod__(self, other, context=None): + """Swaps self/other and returns __mod__.""" + other = _convert_other(other) + if other is NotImplemented: + return other + return other.__mod__(self, context=context) + + def remainder_near(self, other, context=None): + """ + Remainder nearest to 0- abs(remainder-near) <= other/2 + """ + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + ans = self._check_nans(other, context) + if ans: + return ans + + # self == +/-infinity -> InvalidOperation + if self._isinfinity(): + return context._raise_error(InvalidOperation, + 'remainder_near(infinity, x)') + + # other == 0 -> either InvalidOperation or DivisionUndefined + if not other: + if self: + return context._raise_error(InvalidOperation, + 'remainder_near(x, 0)') + else: + return context._raise_error(DivisionUndefined, + 'remainder_near(0, 0)') + + # other = +/-infinity -> remainder = self + if other._isinfinity(): + ans = Decimal(self) + return ans._fix(context) + + # self = 0 -> remainder = self, with ideal exponent + ideal_exponent = min(self._exp, other._exp) + if not self: + ans = _dec_from_triple(self._sign, '0', ideal_exponent) + return ans._fix(context) + + # catch most cases of large or small quotient + expdiff = self.adjusted() - other.adjusted() + if expdiff >= context.prec + 1: + # expdiff >= prec+1 => abs(self/other) > 10**prec + return context._raise_error(DivisionImpossible) + if expdiff <= -2: + # expdiff <= -2 => abs(self/other) < 0.1 + ans = self._rescale(ideal_exponent, context.rounding) + return ans._fix(context) + + # adjust both arguments to have the same exponent, then divide + op1 = _WorkRep(self) + op2 = _WorkRep(other) + if op1.exp >= op2.exp: + op1.int *= 10**(op1.exp - op2.exp) + else: + op2.int *= 10**(op2.exp - op1.exp) + q, r = divmod(op1.int, op2.int) + # remainder is r*10**ideal_exponent; other is +/-op2.int * + # 10**ideal_exponent. Apply correction to ensure that + # abs(remainder) <= abs(other)/2 + if 2*r + (q&1) > op2.int: + r -= op2.int + q += 1 + + if q >= 10**context.prec: + return context._raise_error(DivisionImpossible) + + # result has same sign as self unless r is negative + sign = self._sign + if r < 0: + sign = 1-sign + r = -r + + ans = _dec_from_triple(sign, str(r), ideal_exponent) + return ans._fix(context) + + def __floordiv__(self, other, context=None): + """self // other""" + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + ans = self._check_nans(other, context) + if ans: + return ans + + if self._isinfinity(): + if other._isinfinity(): + return context._raise_error(InvalidOperation, 'INF // INF') + else: + return _SignedInfinity[self._sign ^ other._sign] + + if not other: + if self: + return context._raise_error(DivisionByZero, 'x // 0', + self._sign ^ other._sign) + else: + return context._raise_error(DivisionUndefined, '0 // 0') + + return self._divide(other, context)[0] + + def __rfloordiv__(self, other, context=None): + """Swaps self/other and returns __floordiv__.""" + other = _convert_other(other) + if other is NotImplemented: + return other + return other.__floordiv__(self, context=context) + + def __float__(self): + """Float representation.""" + if self._isnan(): + if self.is_snan(): + raise ValueError("Cannot convert signaling NaN to float") + s = "-nan" if self._sign else "nan" + else: + s = str(self) + return float(s) + + def __int__(self): + """Converts self to an int, truncating if necessary.""" + if self._is_special: + if self._isnan(): + raise ValueError("Cannot convert NaN to integer") + elif self._isinfinity(): + raise OverflowError("Cannot convert infinity to integer") + s = (-1)**self._sign + if self._exp >= 0: + return s*int(self._int)*10**self._exp + else: + return s*int(self._int[:self._exp] or '0') + + __trunc__ = __int__ + + def real(self): + return self + real = property(real) + + def imag(self): + return Decimal(0) + imag = property(imag) + + def conjugate(self): + return self + + def __complex__(self): + return complex(float(self)) + + def _fix_nan(self, context): + """Decapitate the payload of a NaN to fit the context""" + payload = self._int + + # maximum length of payload is precision if clamp=0, + # precision-1 if clamp=1. + max_payload_len = context.prec - context.clamp + if len(payload) > max_payload_len: + payload = payload[len(payload)-max_payload_len:].lstrip('0') + return _dec_from_triple(self._sign, payload, self._exp, True) + return Decimal(self) + + def _fix(self, context): + """Round if it is necessary to keep self within prec precision. + + Rounds and fixes the exponent. Does not raise on a sNaN. + + Arguments: + self - Decimal instance + context - context used. + """ + + if self._is_special: + if self._isnan(): + # decapitate payload if necessary + return self._fix_nan(context) + else: + # self is +/-Infinity; return unaltered + return Decimal(self) + + # if self is zero then exponent should be between Etiny and + # Emax if clamp==0, and between Etiny and Etop if clamp==1. + Etiny = context.Etiny() + Etop = context.Etop() + if not self: + exp_max = [context.Emax, Etop][context.clamp] + new_exp = min(max(self._exp, Etiny), exp_max) + if new_exp != self._exp: + context._raise_error(Clamped) + return _dec_from_triple(self._sign, '0', new_exp) + else: + return Decimal(self) + + # exp_min is the smallest allowable exponent of the result, + # equal to max(self.adjusted()-context.prec+1, Etiny) + exp_min = len(self._int) + self._exp - context.prec + if exp_min > Etop: + # overflow: exp_min > Etop iff self.adjusted() > Emax + ans = context._raise_error(Overflow, 'above Emax', self._sign) + context._raise_error(Inexact) + context._raise_error(Rounded) + return ans + + self_is_subnormal = exp_min < Etiny + if self_is_subnormal: + exp_min = Etiny + + # round if self has too many digits + if self._exp < exp_min: + digits = len(self._int) + self._exp - exp_min + if digits < 0: + self = _dec_from_triple(self._sign, '1', exp_min-1) + digits = 0 + rounding_method = self._pick_rounding_function[context.rounding] + changed = rounding_method(self, digits) + coeff = self._int[:digits] or '0' + if changed > 0: + coeff = str(int(coeff)+1) + if len(coeff) > context.prec: + coeff = coeff[:-1] + exp_min += 1 + + # check whether the rounding pushed the exponent out of range + if exp_min > Etop: + ans = context._raise_error(Overflow, 'above Emax', self._sign) + else: + ans = _dec_from_triple(self._sign, coeff, exp_min) + + # raise the appropriate signals, taking care to respect + # the precedence described in the specification + if changed and self_is_subnormal: + context._raise_error(Underflow) + if self_is_subnormal: + context._raise_error(Subnormal) + if changed: + context._raise_error(Inexact) + context._raise_error(Rounded) + if not ans: + # raise Clamped on underflow to 0 + context._raise_error(Clamped) + return ans + + if self_is_subnormal: + context._raise_error(Subnormal) + + # fold down if clamp == 1 and self has too few digits + if context.clamp == 1 and self._exp > Etop: + context._raise_error(Clamped) + self_padded = self._int + '0'*(self._exp - Etop) + return _dec_from_triple(self._sign, self_padded, Etop) + + # here self was representable to begin with; return unchanged + return Decimal(self) + + # for each of the rounding functions below: + # self is a finite, nonzero Decimal + # prec is an integer satisfying 0 <= prec < len(self._int) + # + # each function returns either -1, 0, or 1, as follows: + # 1 indicates that self should be rounded up (away from zero) + # 0 indicates that self should be truncated, and that all the + # digits to be truncated are zeros (so the value is unchanged) + # -1 indicates that there are nonzero digits to be truncated + + def _round_down(self, prec): + """Also known as round-towards-0, truncate.""" + if _all_zeros(self._int, prec): + return 0 + else: + return -1 + + def _round_up(self, prec): + """Rounds away from 0.""" + return -self._round_down(prec) + + def _round_half_up(self, prec): + """Rounds 5 up (away from 0)""" + if self._int[prec] in '56789': + return 1 + elif _all_zeros(self._int, prec): + return 0 + else: + return -1 + + def _round_half_down(self, prec): + """Round 5 down""" + if _exact_half(self._int, prec): + return -1 + else: + return self._round_half_up(prec) + + def _round_half_even(self, prec): + """Round 5 to even, rest to nearest.""" + if _exact_half(self._int, prec) and \ + (prec == 0 or self._int[prec-1] in '02468'): + return -1 + else: + return self._round_half_up(prec) + + def _round_ceiling(self, prec): + """Rounds up (not away from 0 if negative.)""" + if self._sign: + return self._round_down(prec) + else: + return -self._round_down(prec) + + def _round_floor(self, prec): + """Rounds down (not towards 0 if negative)""" + if not self._sign: + return self._round_down(prec) + else: + return -self._round_down(prec) + + def _round_05up(self, prec): + """Round down unless digit prec-1 is 0 or 5.""" + if prec and self._int[prec-1] not in '05': + return self._round_down(prec) + else: + return -self._round_down(prec) + + _pick_rounding_function = dict( + ROUND_DOWN = _round_down, + ROUND_UP = _round_up, + ROUND_HALF_UP = _round_half_up, + ROUND_HALF_DOWN = _round_half_down, + ROUND_HALF_EVEN = _round_half_even, + ROUND_CEILING = _round_ceiling, + ROUND_FLOOR = _round_floor, + ROUND_05UP = _round_05up, + ) + + def __round__(self, n=None): + """Round self to the nearest integer, or to a given precision. + + If only one argument is supplied, round a finite Decimal + instance self to the nearest integer. If self is infinite or + a NaN then a Python exception is raised. If self is finite + and lies exactly halfway between two integers then it is + rounded to the integer with even last digit. + + >>> round(Decimal('123.456')) + 123 + >>> round(Decimal('-456.789')) + -457 + >>> round(Decimal('-3.0')) + -3 + >>> round(Decimal('2.5')) + 2 + >>> round(Decimal('3.5')) + 4 + >>> round(Decimal('Inf')) + Traceback (most recent call last): + ... + OverflowError: cannot round an infinity + >>> round(Decimal('NaN')) + Traceback (most recent call last): + ... + ValueError: cannot round a NaN + + If a second argument n is supplied, self is rounded to n + decimal places using the rounding mode for the current + context. + + For an integer n, round(self, -n) is exactly equivalent to + self.quantize(Decimal('1En')). + + >>> round(Decimal('123.456'), 0) + Decimal('123') + >>> round(Decimal('123.456'), 2) + Decimal('123.46') + >>> round(Decimal('123.456'), -2) + Decimal('1E+2') + >>> round(Decimal('-Infinity'), 37) + Decimal('NaN') + >>> round(Decimal('sNaN123'), 0) + Decimal('NaN123') + + """ + if n is not None: + # two-argument form: use the equivalent quantize call + if not isinstance(n, int): + raise TypeError('Second argument to round should be integral') + exp = _dec_from_triple(0, '1', -n) + return self.quantize(exp) + + # one-argument form + if self._is_special: + if self.is_nan(): + raise ValueError("cannot round a NaN") + else: + raise OverflowError("cannot round an infinity") + return int(self._rescale(0, ROUND_HALF_EVEN)) + + def __floor__(self): + """Return the floor of self, as an integer. + + For a finite Decimal instance self, return the greatest + integer n such that n <= self. If self is infinite or a NaN + then a Python exception is raised. + + """ + if self._is_special: + if self.is_nan(): + raise ValueError("cannot round a NaN") + else: + raise OverflowError("cannot round an infinity") + return int(self._rescale(0, ROUND_FLOOR)) + + def __ceil__(self): + """Return the ceiling of self, as an integer. + + For a finite Decimal instance self, return the least integer n + such that n >= self. If self is infinite or a NaN then a + Python exception is raised. + + """ + if self._is_special: + if self.is_nan(): + raise ValueError("cannot round a NaN") + else: + raise OverflowError("cannot round an infinity") + return int(self._rescale(0, ROUND_CEILING)) + + def fma(self, other, third, context=None): + """Fused multiply-add. + + Returns self*other+third with no rounding of the intermediate + product self*other. + + self and other are multiplied together, with no rounding of + the result. The third operand is then added to the result, + and a single final rounding is performed. + """ + + other = _convert_other(other, raiseit=True) + third = _convert_other(third, raiseit=True) + + # compute product; raise InvalidOperation if either operand is + # a signaling NaN or if the product is zero times infinity. + if self._is_special or other._is_special: + if context is None: + context = getcontext() + if self._exp == 'N': + return context._raise_error(InvalidOperation, 'sNaN', self) + if other._exp == 'N': + return context._raise_error(InvalidOperation, 'sNaN', other) + if self._exp == 'n': + product = self + elif other._exp == 'n': + product = other + elif self._exp == 'F': + if not other: + return context._raise_error(InvalidOperation, + 'INF * 0 in fma') + product = _SignedInfinity[self._sign ^ other._sign] + elif other._exp == 'F': + if not self: + return context._raise_error(InvalidOperation, + '0 * INF in fma') + product = _SignedInfinity[self._sign ^ other._sign] + else: + product = _dec_from_triple(self._sign ^ other._sign, + str(int(self._int) * int(other._int)), + self._exp + other._exp) + + return product.__add__(third, context) + + def _power_modulo(self, other, modulo, context=None): + """Three argument version of __pow__""" + + other = _convert_other(other) + if other is NotImplemented: + return other + modulo = _convert_other(modulo) + if modulo is NotImplemented: + return modulo + + if context is None: + context = getcontext() + + # deal with NaNs: if there are any sNaNs then first one wins, + # (i.e. behaviour for NaNs is identical to that of fma) + self_is_nan = self._isnan() + other_is_nan = other._isnan() + modulo_is_nan = modulo._isnan() + if self_is_nan or other_is_nan or modulo_is_nan: + if self_is_nan == 2: + return context._raise_error(InvalidOperation, 'sNaN', + self) + if other_is_nan == 2: + return context._raise_error(InvalidOperation, 'sNaN', + other) + if modulo_is_nan == 2: + return context._raise_error(InvalidOperation, 'sNaN', + modulo) + if self_is_nan: + return self._fix_nan(context) + if other_is_nan: + return other._fix_nan(context) + return modulo._fix_nan(context) + + # check inputs: we apply same restrictions as Python's pow() + if not (self._isinteger() and + other._isinteger() and + modulo._isinteger()): + return context._raise_error(InvalidOperation, + 'pow() 3rd argument not allowed ' + 'unless all arguments are integers') + if other < 0: + return context._raise_error(InvalidOperation, + 'pow() 2nd argument cannot be ' + 'negative when 3rd argument specified') + if not modulo: + return context._raise_error(InvalidOperation, + 'pow() 3rd argument cannot be 0') + + # additional restriction for decimal: the modulus must be less + # than 10**prec in absolute value + if modulo.adjusted() >= context.prec: + return context._raise_error(InvalidOperation, + 'insufficient precision: pow() 3rd ' + 'argument must not have more than ' + 'precision digits') + + # define 0**0 == NaN, for consistency with two-argument pow + # (even though it hurts!) + if not other and not self: + return context._raise_error(InvalidOperation, + 'at least one of pow() 1st argument ' + 'and 2nd argument must be nonzero ;' + '0**0 is not defined') + + # compute sign of result + if other._iseven(): + sign = 0 + else: + sign = self._sign + + # convert modulo to a Python integer, and self and other to + # Decimal integers (i.e. force their exponents to be >= 0) + modulo = abs(int(modulo)) + base = _WorkRep(self.to_integral_value()) + exponent = _WorkRep(other.to_integral_value()) + + # compute result using integer pow() + base = (base.int % modulo * pow(10, base.exp, modulo)) % modulo + for i in range(exponent.exp): + base = pow(base, 10, modulo) + base = pow(base, exponent.int, modulo) + + return _dec_from_triple(sign, str(base), 0) + + def _power_exact(self, other, p): + """Attempt to compute self**other exactly. + + Given Decimals self and other and an integer p, attempt to + compute an exact result for the power self**other, with p + digits of precision. Return None if self**other is not + exactly representable in p digits. + + Assumes that elimination of special cases has already been + performed: self and other must both be nonspecial; self must + be positive and not numerically equal to 1; other must be + nonzero. For efficiency, other._exp should not be too large, + so that 10**abs(other._exp) is a feasible calculation.""" + + # In the comments below, we write x for the value of self and y for the + # value of other. Write x = xc*10**xe and abs(y) = yc*10**ye, with xc + # and yc positive integers not divisible by 10. + + # The main purpose of this method is to identify the *failure* + # of x**y to be exactly representable with as little effort as + # possible. So we look for cheap and easy tests that + # eliminate the possibility of x**y being exact. Only if all + # these tests are passed do we go on to actually compute x**y. + + # Here's the main idea. Express y as a rational number m/n, with m and + # n relatively prime and n>0. Then for x**y to be exactly + # representable (at *any* precision), xc must be the nth power of a + # positive integer and xe must be divisible by n. If y is negative + # then additionally xc must be a power of either 2 or 5, hence a power + # of 2**n or 5**n. + # + # There's a limit to how small |y| can be: if y=m/n as above + # then: + # + # (1) if xc != 1 then for the result to be representable we + # need xc**(1/n) >= 2, and hence also xc**|y| >= 2. So + # if |y| <= 1/nbits(xc) then xc < 2**nbits(xc) <= + # 2**(1/|y|), hence xc**|y| < 2 and the result is not + # representable. + # + # (2) if xe != 0, |xe|*(1/n) >= 1, so |xe|*|y| >= 1. Hence if + # |y| < 1/|xe| then the result is not representable. + # + # Note that since x is not equal to 1, at least one of (1) and + # (2) must apply. Now |y| < 1/nbits(xc) iff |yc|*nbits(xc) < + # 10**-ye iff len(str(|yc|*nbits(xc)) <= -ye. + # + # There's also a limit to how large y can be, at least if it's + # positive: the normalized result will have coefficient xc**y, + # so if it's representable then xc**y < 10**p, and y < + # p/log10(xc). Hence if y*log10(xc) >= p then the result is + # not exactly representable. + + # if len(str(abs(yc*xe)) <= -ye then abs(yc*xe) < 10**-ye, + # so |y| < 1/xe and the result is not representable. + # Similarly, len(str(abs(yc)*xc_bits)) <= -ye implies |y| + # < 1/nbits(xc). + + x = _WorkRep(self) + xc, xe = x.int, x.exp + while xc % 10 == 0: + xc //= 10 + xe += 1 + + y = _WorkRep(other) + yc, ye = y.int, y.exp + while yc % 10 == 0: + yc //= 10 + ye += 1 + + # case where xc == 1: result is 10**(xe*y), with xe*y + # required to be an integer + if xc == 1: + xe *= yc + # result is now 10**(xe * 10**ye); xe * 10**ye must be integral + while xe % 10 == 0: + xe //= 10 + ye += 1 + if ye < 0: + return None + exponent = xe * 10**ye + if y.sign == 1: + exponent = -exponent + # if other is a nonnegative integer, use ideal exponent + if other._isinteger() and other._sign == 0: + ideal_exponent = self._exp*int(other) + zeros = min(exponent-ideal_exponent, p-1) + else: + zeros = 0 + return _dec_from_triple(0, '1' + '0'*zeros, exponent-zeros) + + # case where y is negative: xc must be either a power + # of 2 or a power of 5. + if y.sign == 1: + last_digit = xc % 10 + if last_digit in (2,4,6,8): + # quick test for power of 2 + if xc & -xc != xc: + return None + # now xc is a power of 2; e is its exponent + e = _nbits(xc)-1 + + # We now have: + # + # x = 2**e * 10**xe, e > 0, and y < 0. + # + # The exact result is: + # + # x**y = 5**(-e*y) * 10**(e*y + xe*y) + # + # provided that both e*y and xe*y are integers. Note that if + # 5**(-e*y) >= 10**p, then the result can't be expressed + # exactly with p digits of precision. + # + # Using the above, we can guard against large values of ye. + # 93/65 is an upper bound for log(10)/log(5), so if + # + # ye >= len(str(93*p//65)) + # + # then + # + # -e*y >= -y >= 10**ye > 93*p/65 > p*log(10)/log(5), + # + # so 5**(-e*y) >= 10**p, and the coefficient of the result + # can't be expressed in p digits. + + # emax >= largest e such that 5**e < 10**p. + emax = p*93//65 + if ye >= len(str(emax)): + return None + + # Find -e*y and -xe*y; both must be integers + e = _decimal_lshift_exact(e * yc, ye) + xe = _decimal_lshift_exact(xe * yc, ye) + if e is None or xe is None: + return None + + if e > emax: + return None + xc = 5**e + + elif last_digit == 5: + # e >= log_5(xc) if xc is a power of 5; we have + # equality all the way up to xc=5**2658 + e = _nbits(xc)*28//65 + xc, remainder = divmod(5**e, xc) + if remainder: + return None + while xc % 5 == 0: + xc //= 5 + e -= 1 + + # Guard against large values of ye, using the same logic as in + # the 'xc is a power of 2' branch. 10/3 is an upper bound for + # log(10)/log(2). + emax = p*10//3 + if ye >= len(str(emax)): + return None + + e = _decimal_lshift_exact(e * yc, ye) + xe = _decimal_lshift_exact(xe * yc, ye) + if e is None or xe is None: + return None + + if e > emax: + return None + xc = 2**e + else: + return None + + if xc >= 10**p: + return None + xe = -e-xe + return _dec_from_triple(0, str(xc), xe) + + # now y is positive; find m and n such that y = m/n + if ye >= 0: + m, n = yc*10**ye, 1 + else: + if xe != 0 and len(str(abs(yc*xe))) <= -ye: + return None + xc_bits = _nbits(xc) + if xc != 1 and len(str(abs(yc)*xc_bits)) <= -ye: + return None + m, n = yc, 10**(-ye) + while m % 2 == n % 2 == 0: + m //= 2 + n //= 2 + while m % 5 == n % 5 == 0: + m //= 5 + n //= 5 + + # compute nth root of xc*10**xe + if n > 1: + # if 1 < xc < 2**n then xc isn't an nth power + if xc != 1 and xc_bits <= n: + return None + + xe, rem = divmod(xe, n) + if rem != 0: + return None + + # compute nth root of xc using Newton's method + a = 1 << -(-_nbits(xc)//n) # initial estimate + while True: + q, r = divmod(xc, a**(n-1)) + if a <= q: + break + else: + a = (a*(n-1) + q)//n + if not (a == q and r == 0): + return None + xc = a + + # now xc*10**xe is the nth root of the original xc*10**xe + # compute mth power of xc*10**xe + + # if m > p*100//_log10_lb(xc) then m > p/log10(xc), hence xc**m > + # 10**p and the result is not representable. + if xc > 1 and m > p*100//_log10_lb(xc): + return None + xc = xc**m + xe *= m + if xc > 10**p: + return None + + # by this point the result *is* exactly representable + # adjust the exponent to get as close as possible to the ideal + # exponent, if necessary + str_xc = str(xc) + if other._isinteger() and other._sign == 0: + ideal_exponent = self._exp*int(other) + zeros = min(xe-ideal_exponent, p-len(str_xc)) + else: + zeros = 0 + return _dec_from_triple(0, str_xc+'0'*zeros, xe-zeros) + + def __pow__(self, other, modulo=None, context=None): + """Return self ** other [ % modulo]. + + With two arguments, compute self**other. + + With three arguments, compute (self**other) % modulo. For the + three argument form, the following restrictions on the + arguments hold: + + - all three arguments must be integral + - other must be nonnegative + - either self or other (or both) must be nonzero + - modulo must be nonzero and must have at most p digits, + where p is the context precision. + + If any of these restrictions is violated the InvalidOperation + flag is raised. + + The result of pow(self, other, modulo) is identical to the + result that would be obtained by computing (self**other) % + modulo with unbounded precision, but is computed more + efficiently. It is always exact. + """ + + if modulo is not None: + return self._power_modulo(other, modulo, context) + + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + # either argument is a NaN => result is NaN + ans = self._check_nans(other, context) + if ans: + return ans + + # 0**0 = NaN (!), x**0 = 1 for nonzero x (including +/-Infinity) + if not other: + if not self: + return context._raise_error(InvalidOperation, '0 ** 0') + else: + return _One + + # result has sign 1 iff self._sign is 1 and other is an odd integer + result_sign = 0 + if self._sign == 1: + if other._isinteger(): + if not other._iseven(): + result_sign = 1 + else: + # -ve**noninteger = NaN + # (-0)**noninteger = 0**noninteger + if self: + return context._raise_error(InvalidOperation, + 'x ** y with x negative and y not an integer') + # negate self, without doing any unwanted rounding + self = self.copy_negate() + + # 0**(+ve or Inf)= 0; 0**(-ve or -Inf) = Infinity + if not self: + if other._sign == 0: + return _dec_from_triple(result_sign, '0', 0) + else: + return _SignedInfinity[result_sign] + + # Inf**(+ve or Inf) = Inf; Inf**(-ve or -Inf) = 0 + if self._isinfinity(): + if other._sign == 0: + return _SignedInfinity[result_sign] + else: + return _dec_from_triple(result_sign, '0', 0) + + # 1**other = 1, but the choice of exponent and the flags + # depend on the exponent of self, and on whether other is a + # positive integer, a negative integer, or neither + if self == _One: + if other._isinteger(): + # exp = max(self._exp*max(int(other), 0), + # 1-context.prec) but evaluating int(other) directly + # is dangerous until we know other is small (other + # could be 1e999999999) + if other._sign == 1: + multiplier = 0 + elif other > context.prec: + multiplier = context.prec + else: + multiplier = int(other) + + exp = self._exp * multiplier + if exp < 1-context.prec: + exp = 1-context.prec + context._raise_error(Rounded) + else: + context._raise_error(Inexact) + context._raise_error(Rounded) + exp = 1-context.prec + + return _dec_from_triple(result_sign, '1'+'0'*-exp, exp) + + # compute adjusted exponent of self + self_adj = self.adjusted() + + # self ** infinity is infinity if self > 1, 0 if self < 1 + # self ** -infinity is infinity if self < 1, 0 if self > 1 + if other._isinfinity(): + if (other._sign == 0) == (self_adj < 0): + return _dec_from_triple(result_sign, '0', 0) + else: + return _SignedInfinity[result_sign] + + # from here on, the result always goes through the call + # to _fix at the end of this function. + ans = None + exact = False + + # crude test to catch cases of extreme overflow/underflow. If + # log10(self)*other >= 10**bound and bound >= len(str(Emax)) + # then 10**bound >= 10**len(str(Emax)) >= Emax+1 and hence + # self**other >= 10**(Emax+1), so overflow occurs. The test + # for underflow is similar. + bound = self._log10_exp_bound() + other.adjusted() + if (self_adj >= 0) == (other._sign == 0): + # self > 1 and other +ve, or self < 1 and other -ve + # possibility of overflow + if bound >= len(str(context.Emax)): + ans = _dec_from_triple(result_sign, '1', context.Emax+1) + else: + # self > 1 and other -ve, or self < 1 and other +ve + # possibility of underflow to 0 + Etiny = context.Etiny() + if bound >= len(str(-Etiny)): + ans = _dec_from_triple(result_sign, '1', Etiny-1) + + # try for an exact result with precision +1 + if ans is None: + ans = self._power_exact(other, context.prec + 1) + if ans is not None: + if result_sign == 1: + ans = _dec_from_triple(1, ans._int, ans._exp) + exact = True + + # usual case: inexact result, x**y computed directly as exp(y*log(x)) + if ans is None: + p = context.prec + x = _WorkRep(self) + xc, xe = x.int, x.exp + y = _WorkRep(other) + yc, ye = y.int, y.exp + if y.sign == 1: + yc = -yc + + # compute correctly rounded result: start with precision +3, + # then increase precision until result is unambiguously roundable + extra = 3 + while True: + coeff, exp = _dpower(xc, xe, yc, ye, p+extra) + if coeff % (5*10**(len(str(coeff))-p-1)): + break + extra += 3 + + ans = _dec_from_triple(result_sign, str(coeff), exp) + + # unlike exp, ln and log10, the power function respects the + # rounding mode; no need to switch to ROUND_HALF_EVEN here + + # There's a difficulty here when 'other' is not an integer and + # the result is exact. In this case, the specification + # requires that the Inexact flag be raised (in spite of + # exactness), but since the result is exact _fix won't do this + # for us. (Correspondingly, the Underflow signal should also + # be raised for subnormal results.) We can't directly raise + # these signals either before or after calling _fix, since + # that would violate the precedence for signals. So we wrap + # the ._fix call in a temporary context, and reraise + # afterwards. + if exact and not other._isinteger(): + # pad with zeros up to length context.prec+1 if necessary; this + # ensures that the Rounded signal will be raised. + if len(ans._int) <= context.prec: + expdiff = context.prec + 1 - len(ans._int) + ans = _dec_from_triple(ans._sign, ans._int+'0'*expdiff, + ans._exp-expdiff) + + # create a copy of the current context, with cleared flags/traps + newcontext = context.copy() + newcontext.clear_flags() + for exception in _signals: + newcontext.traps[exception] = 0 + + # round in the new context + ans = ans._fix(newcontext) + + # raise Inexact, and if necessary, Underflow + newcontext._raise_error(Inexact) + if newcontext.flags[Subnormal]: + newcontext._raise_error(Underflow) + + # propagate signals to the original context; _fix could + # have raised any of Overflow, Underflow, Subnormal, + # Inexact, Rounded, Clamped. Overflow needs the correct + # arguments. Note that the order of the exceptions is + # important here. + if newcontext.flags[Overflow]: + context._raise_error(Overflow, 'above Emax', ans._sign) + for exception in Underflow, Subnormal, Inexact, Rounded, Clamped: + if newcontext.flags[exception]: + context._raise_error(exception) + + else: + ans = ans._fix(context) + + return ans + + def __rpow__(self, other, context=None): + """Swaps self/other and returns __pow__.""" + other = _convert_other(other) + if other is NotImplemented: + return other + return other.__pow__(self, context=context) + + def normalize(self, context=None): + """Normalize- strip trailing 0s, change anything equal to 0 to 0e0""" + + if context is None: + context = getcontext() + + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + + dup = self._fix(context) + if dup._isinfinity(): + return dup + + if not dup: + return _dec_from_triple(dup._sign, '0', 0) + exp_max = [context.Emax, context.Etop()][context.clamp] + end = len(dup._int) + exp = dup._exp + while dup._int[end-1] == '0' and exp < exp_max: + exp += 1 + end -= 1 + return _dec_from_triple(dup._sign, dup._int[:end], exp) + + def quantize(self, exp, rounding=None, context=None): + """Quantize self so its exponent is the same as that of exp. + + Similar to self._rescale(exp._exp) but with error checking. + """ + exp = _convert_other(exp, raiseit=True) + + if context is None: + context = getcontext() + if rounding is None: + rounding = context.rounding + + if self._is_special or exp._is_special: + ans = self._check_nans(exp, context) + if ans: + return ans + + if exp._isinfinity() or self._isinfinity(): + if exp._isinfinity() and self._isinfinity(): + return Decimal(self) # if both are inf, it is OK + return context._raise_error(InvalidOperation, + 'quantize with one INF') + + # exp._exp should be between Etiny and Emax + if not (context.Etiny() <= exp._exp <= context.Emax): + return context._raise_error(InvalidOperation, + 'target exponent out of bounds in quantize') + + if not self: + ans = _dec_from_triple(self._sign, '0', exp._exp) + return ans._fix(context) + + self_adjusted = self.adjusted() + if self_adjusted > context.Emax: + return context._raise_error(InvalidOperation, + 'exponent of quantize result too large for current context') + if self_adjusted - exp._exp + 1 > context.prec: + return context._raise_error(InvalidOperation, + 'quantize result has too many digits for current context') + + ans = self._rescale(exp._exp, rounding) + if ans.adjusted() > context.Emax: + return context._raise_error(InvalidOperation, + 'exponent of quantize result too large for current context') + if len(ans._int) > context.prec: + return context._raise_error(InvalidOperation, + 'quantize result has too many digits for current context') + + # raise appropriate flags + if ans and ans.adjusted() < context.Emin: + context._raise_error(Subnormal) + if ans._exp > self._exp: + if ans != self: + context._raise_error(Inexact) + context._raise_error(Rounded) + + # call to fix takes care of any necessary folddown, and + # signals Clamped if necessary + ans = ans._fix(context) + return ans + + def same_quantum(self, other, context=None): + """Return True if self and other have the same exponent; otherwise + return False. + + If either operand is a special value, the following rules are used: + * return True if both operands are infinities + * return True if both operands are NaNs + * otherwise, return False. + """ + other = _convert_other(other, raiseit=True) + if self._is_special or other._is_special: + return (self.is_nan() and other.is_nan() or + self.is_infinite() and other.is_infinite()) + return self._exp == other._exp + + def _rescale(self, exp, rounding): + """Rescale self so that the exponent is exp, either by padding with zeros + or by truncating digits, using the given rounding mode. + + Specials are returned without change. This operation is + quiet: it raises no flags, and uses no information from the + context. + + exp = exp to scale to (an integer) + rounding = rounding mode + """ + if self._is_special: + return Decimal(self) + if not self: + return _dec_from_triple(self._sign, '0', exp) + + if self._exp >= exp: + # pad answer with zeros if necessary + return _dec_from_triple(self._sign, + self._int + '0'*(self._exp - exp), exp) + + # too many digits; round and lose data. If self.adjusted() < + # exp-1, replace self by 10**(exp-1) before rounding + digits = len(self._int) + self._exp - exp + if digits < 0: + self = _dec_from_triple(self._sign, '1', exp-1) + digits = 0 + this_function = self._pick_rounding_function[rounding] + changed = this_function(self, digits) + coeff = self._int[:digits] or '0' + if changed == 1: + coeff = str(int(coeff)+1) + return _dec_from_triple(self._sign, coeff, exp) + + def _round(self, places, rounding): + """Round a nonzero, nonspecial Decimal to a fixed number of + significant figures, using the given rounding mode. + + Infinities, NaNs and zeros are returned unaltered. + + This operation is quiet: it raises no flags, and uses no + information from the context. + + """ + if places <= 0: + raise ValueError("argument should be at least 1 in _round") + if self._is_special or not self: + return Decimal(self) + ans = self._rescale(self.adjusted()+1-places, rounding) + # it can happen that the rescale alters the adjusted exponent; + # for example when rounding 99.97 to 3 significant figures. + # When this happens we end up with an extra 0 at the end of + # the number; a second rescale fixes this. + if ans.adjusted() != self.adjusted(): + ans = ans._rescale(ans.adjusted()+1-places, rounding) + return ans + + def to_integral_exact(self, rounding=None, context=None): + """Rounds to a nearby integer. + + If no rounding mode is specified, take the rounding mode from + the context. This method raises the Rounded and Inexact flags + when appropriate. + + See also: to_integral_value, which does exactly the same as + this method except that it doesn't raise Inexact or Rounded. + """ + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + return Decimal(self) + if self._exp >= 0: + return Decimal(self) + if not self: + return _dec_from_triple(self._sign, '0', 0) + if context is None: + context = getcontext() + if rounding is None: + rounding = context.rounding + ans = self._rescale(0, rounding) + if ans != self: + context._raise_error(Inexact) + context._raise_error(Rounded) + return ans + + def to_integral_value(self, rounding=None, context=None): + """Rounds to the nearest integer, without raising inexact, rounded.""" + if context is None: + context = getcontext() + if rounding is None: + rounding = context.rounding + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + return Decimal(self) + if self._exp >= 0: + return Decimal(self) + else: + return self._rescale(0, rounding) + + # the method name changed, but we provide also the old one, for compatibility + to_integral = to_integral_value + + def sqrt(self, context=None): + """Return the square root of self.""" + if context is None: + context = getcontext() + + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + + if self._isinfinity() and self._sign == 0: + return Decimal(self) + + if not self: + # exponent = self._exp // 2. sqrt(-0) = -0 + ans = _dec_from_triple(self._sign, '0', self._exp // 2) + return ans._fix(context) + + if self._sign == 1: + return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0') + + # At this point self represents a positive number. Let p be + # the desired precision and express self in the form c*100**e + # with c a positive real number and e an integer, c and e + # being chosen so that 100**(p-1) <= c < 100**p. Then the + # (exact) square root of self is sqrt(c)*10**e, and 10**(p-1) + # <= sqrt(c) < 10**p, so the closest representable Decimal at + # precision p is n*10**e where n = round_half_even(sqrt(c)), + # the closest integer to sqrt(c) with the even integer chosen + # in the case of a tie. + # + # To ensure correct rounding in all cases, we use the + # following trick: we compute the square root to an extra + # place (precision p+1 instead of precision p), rounding down. + # Then, if the result is inexact and its last digit is 0 or 5, + # we increase the last digit to 1 or 6 respectively; if it's + # exact we leave the last digit alone. Now the final round to + # p places (or fewer in the case of underflow) will round + # correctly and raise the appropriate flags. + + # use an extra digit of precision + prec = context.prec+1 + + # write argument in the form c*100**e where e = self._exp//2 + # is the 'ideal' exponent, to be used if the square root is + # exactly representable. l is the number of 'digits' of c in + # base 100, so that 100**(l-1) <= c < 100**l. + op = _WorkRep(self) + e = op.exp >> 1 + if op.exp & 1: + c = op.int * 10 + l = (len(self._int) >> 1) + 1 + else: + c = op.int + l = len(self._int)+1 >> 1 + + # rescale so that c has exactly prec base 100 'digits' + shift = prec-l + if shift >= 0: + c *= 100**shift + exact = True + else: + c, remainder = divmod(c, 100**-shift) + exact = not remainder + e -= shift + + # find n = floor(sqrt(c)) using Newton's method + n = 10**prec + while True: + q = c//n + if n <= q: + break + else: + n = n + q >> 1 + exact = exact and n*n == c + + if exact: + # result is exact; rescale to use ideal exponent e + if shift >= 0: + # assert n % 10**shift == 0 + n //= 10**shift + else: + n *= 10**-shift + e += shift + else: + # result is not exact; fix last digit as described above + if n % 5 == 0: + n += 1 + + ans = _dec_from_triple(0, str(n), e) + + # round, and fit to current context + context = context._shallow_copy() + rounding = context._set_rounding(ROUND_HALF_EVEN) + ans = ans._fix(context) + context.rounding = rounding + + return ans + + def max(self, other, context=None): + """Returns the larger value. + + Like max(self, other) except if one is not a number, returns + NaN (and signals if one is sNaN). Also rounds. + """ + other = _convert_other(other, raiseit=True) + + if context is None: + context = getcontext() + + if self._is_special or other._is_special: + # If one operand is a quiet NaN and the other is number, then the + # number is always returned + sn = self._isnan() + on = other._isnan() + if sn or on: + if on == 1 and sn == 0: + return self._fix(context) + if sn == 1 and on == 0: + return other._fix(context) + return self._check_nans(other, context) + + c = self._cmp(other) + if c == 0: + # If both operands are finite and equal in numerical value + # then an ordering is applied: + # + # If the signs differ then max returns the operand with the + # positive sign and min returns the operand with the negative sign + # + # If the signs are the same then the exponent is used to select + # the result. This is exactly the ordering used in compare_total. + c = self.compare_total(other) + + if c == -1: + ans = other + else: + ans = self + + return ans._fix(context) + + def min(self, other, context=None): + """Returns the smaller value. + + Like min(self, other) except if one is not a number, returns + NaN (and signals if one is sNaN). Also rounds. + """ + other = _convert_other(other, raiseit=True) + + if context is None: + context = getcontext() + + if self._is_special or other._is_special: + # If one operand is a quiet NaN and the other is number, then the + # number is always returned + sn = self._isnan() + on = other._isnan() + if sn or on: + if on == 1 and sn == 0: + return self._fix(context) + if sn == 1 and on == 0: + return other._fix(context) + return self._check_nans(other, context) + + c = self._cmp(other) + if c == 0: + c = self.compare_total(other) + + if c == -1: + ans = self + else: + ans = other + + return ans._fix(context) + + def _isinteger(self): + """Returns whether self is an integer""" + if self._is_special: + return False + if self._exp >= 0: + return True + rest = self._int[self._exp:] + return rest == '0'*len(rest) + + def _iseven(self): + """Returns True if self is even. Assumes self is an integer.""" + if not self or self._exp > 0: + return True + return self._int[-1+self._exp] in '02468' + + def adjusted(self): + """Return the adjusted exponent of self""" + try: + return self._exp + len(self._int) - 1 + # If NaN or Infinity, self._exp is string + except TypeError: + return 0 + + def canonical(self): + """Returns the same Decimal object. + + As we do not have different encodings for the same number, the + received object already is in its canonical form. + """ + return self + + def compare_signal(self, other, context=None): + """Compares self to the other operand numerically. + + It's pretty much like compare(), but all NaNs signal, with signaling + NaNs taking precedence over quiet NaNs. + """ + other = _convert_other(other, raiseit = True) + ans = self._compare_check_nans(other, context) + if ans: + return ans + return self.compare(other, context=context) + + def compare_total(self, other, context=None): + """Compares self to other using the abstract representations. + + This is not like the standard compare, which use their numerical + value. Note that a total ordering is defined for all possible abstract + representations. + """ + other = _convert_other(other, raiseit=True) + + # if one is negative and the other is positive, it's easy + if self._sign and not other._sign: + return _NegativeOne + if not self._sign and other._sign: + return _One + sign = self._sign + + # let's handle both NaN types + self_nan = self._isnan() + other_nan = other._isnan() + if self_nan or other_nan: + if self_nan == other_nan: + # compare payloads as though they're integers + self_key = len(self._int), self._int + other_key = len(other._int), other._int + if self_key < other_key: + if sign: + return _One + else: + return _NegativeOne + if self_key > other_key: + if sign: + return _NegativeOne + else: + return _One + return _Zero + + if sign: + if self_nan == 1: + return _NegativeOne + if other_nan == 1: + return _One + if self_nan == 2: + return _NegativeOne + if other_nan == 2: + return _One + else: + if self_nan == 1: + return _One + if other_nan == 1: + return _NegativeOne + if self_nan == 2: + return _One + if other_nan == 2: + return _NegativeOne + + if self < other: + return _NegativeOne + if self > other: + return _One + + if self._exp < other._exp: + if sign: + return _One + else: + return _NegativeOne + if self._exp > other._exp: + if sign: + return _NegativeOne + else: + return _One + return _Zero + + + def compare_total_mag(self, other, context=None): + """Compares self to other using abstract repr., ignoring sign. + + Like compare_total, but with operand's sign ignored and assumed to be 0. + """ + other = _convert_other(other, raiseit=True) + + s = self.copy_abs() + o = other.copy_abs() + return s.compare_total(o) + + def copy_abs(self): + """Returns a copy with the sign set to 0. """ + return _dec_from_triple(0, self._int, self._exp, self._is_special) + + def copy_negate(self): + """Returns a copy with the sign inverted.""" + if self._sign: + return _dec_from_triple(0, self._int, self._exp, self._is_special) + else: + return _dec_from_triple(1, self._int, self._exp, self._is_special) + + def copy_sign(self, other, context=None): + """Returns self with the sign of other.""" + other = _convert_other(other, raiseit=True) + return _dec_from_triple(other._sign, self._int, + self._exp, self._is_special) + + def exp(self, context=None): + """Returns e ** self.""" + + if context is None: + context = getcontext() + + # exp(NaN) = NaN + ans = self._check_nans(context=context) + if ans: + return ans + + # exp(-Infinity) = 0 + if self._isinfinity() == -1: + return _Zero + + # exp(0) = 1 + if not self: + return _One + + # exp(Infinity) = Infinity + if self._isinfinity() == 1: + return Decimal(self) + + # the result is now guaranteed to be inexact (the true + # mathematical result is transcendental). There's no need to + # raise Rounded and Inexact here---they'll always be raised as + # a result of the call to _fix. + p = context.prec + adj = self.adjusted() + + # we only need to do any computation for quite a small range + # of adjusted exponents---for example, -29 <= adj <= 10 for + # the default context. For smaller exponent the result is + # indistinguishable from 1 at the given precision, while for + # larger exponent the result either overflows or underflows. + if self._sign == 0 and adj > len(str((context.Emax+1)*3)): + # overflow + ans = _dec_from_triple(0, '1', context.Emax+1) + elif self._sign == 1 and adj > len(str((-context.Etiny()+1)*3)): + # underflow to 0 + ans = _dec_from_triple(0, '1', context.Etiny()-1) + elif self._sign == 0 and adj < -p: + # p+1 digits; final round will raise correct flags + ans = _dec_from_triple(0, '1' + '0'*(p-1) + '1', -p) + elif self._sign == 1 and adj < -p-1: + # p+1 digits; final round will raise correct flags + ans = _dec_from_triple(0, '9'*(p+1), -p-1) + # general case + else: + op = _WorkRep(self) + c, e = op.int, op.exp + if op.sign == 1: + c = -c + + # compute correctly rounded result: increase precision by + # 3 digits at a time until we get an unambiguously + # roundable result + extra = 3 + while True: + coeff, exp = _dexp(c, e, p+extra) + if coeff % (5*10**(len(str(coeff))-p-1)): + break + extra += 3 + + ans = _dec_from_triple(0, str(coeff), exp) + + # at this stage, ans should round correctly with *any* + # rounding mode, not just with ROUND_HALF_EVEN + context = context._shallow_copy() + rounding = context._set_rounding(ROUND_HALF_EVEN) + ans = ans._fix(context) + context.rounding = rounding + + return ans + + def is_canonical(self): + """Return True if self is canonical; otherwise return False. + + Currently, the encoding of a Decimal instance is always + canonical, so this method returns True for any Decimal. + """ + return True + + def is_finite(self): + """Return True if self is finite; otherwise return False. + + A Decimal instance is considered finite if it is neither + infinite nor a NaN. + """ + return not self._is_special + + def is_infinite(self): + """Return True if self is infinite; otherwise return False.""" + return self._exp == 'F' + + def is_nan(self): + """Return True if self is a qNaN or sNaN; otherwise return False.""" + return self._exp in ('n', 'N') + + def is_normal(self, context=None): + """Return True if self is a normal number; otherwise return False.""" + if self._is_special or not self: + return False + if context is None: + context = getcontext() + return context.Emin <= self.adjusted() + + def is_qnan(self): + """Return True if self is a quiet NaN; otherwise return False.""" + return self._exp == 'n' + + def is_signed(self): + """Return True if self is negative; otherwise return False.""" + return self._sign == 1 + + def is_snan(self): + """Return True if self is a signaling NaN; otherwise return False.""" + return self._exp == 'N' + + def is_subnormal(self, context=None): + """Return True if self is subnormal; otherwise return False.""" + if self._is_special or not self: + return False + if context is None: + context = getcontext() + return self.adjusted() < context.Emin + + def is_zero(self): + """Return True if self is a zero; otherwise return False.""" + return not self._is_special and self._int == '0' + + def _ln_exp_bound(self): + """Compute a lower bound for the adjusted exponent of self.ln(). + In other words, compute r such that self.ln() >= 10**r. Assumes + that self is finite and positive and that self != 1. + """ + + # for 0.1 <= x <= 10 we use the inequalities 1-1/x <= ln(x) <= x-1 + adj = self._exp + len(self._int) - 1 + if adj >= 1: + # argument >= 10; we use 23/10 = 2.3 as a lower bound for ln(10) + return len(str(adj*23//10)) - 1 + if adj <= -2: + # argument <= 0.1 + return len(str((-1-adj)*23//10)) - 1 + op = _WorkRep(self) + c, e = op.int, op.exp + if adj == 0: + # 1 < self < 10 + num = str(c-10**-e) + den = str(c) + return len(num) - len(den) - (num < den) + # adj == -1, 0.1 <= self < 1 + return e + len(str(10**-e - c)) - 1 + + + def ln(self, context=None): + """Returns the natural (base e) logarithm of self.""" + + if context is None: + context = getcontext() + + # ln(NaN) = NaN + ans = self._check_nans(context=context) + if ans: + return ans + + # ln(0.0) == -Infinity + if not self: + return _NegativeInfinity + + # ln(Infinity) = Infinity + if self._isinfinity() == 1: + return _Infinity + + # ln(1.0) == 0.0 + if self == _One: + return _Zero + + # ln(negative) raises InvalidOperation + if self._sign == 1: + return context._raise_error(InvalidOperation, + 'ln of a negative value') + + # result is irrational, so necessarily inexact + op = _WorkRep(self) + c, e = op.int, op.exp + p = context.prec + + # correctly rounded result: repeatedly increase precision by 3 + # until we get an unambiguously roundable result + places = p - self._ln_exp_bound() + 2 # at least p+3 places + while True: + coeff = _dlog(c, e, places) + # assert len(str(abs(coeff)))-p >= 1 + if coeff % (5*10**(len(str(abs(coeff)))-p-1)): + break + places += 3 + ans = _dec_from_triple(int(coeff<0), str(abs(coeff)), -places) + + context = context._shallow_copy() + rounding = context._set_rounding(ROUND_HALF_EVEN) + ans = ans._fix(context) + context.rounding = rounding + return ans + + def _log10_exp_bound(self): + """Compute a lower bound for the adjusted exponent of self.log10(). + In other words, find r such that self.log10() >= 10**r. + Assumes that self is finite and positive and that self != 1. + """ + + # For x >= 10 or x < 0.1 we only need a bound on the integer + # part of log10(self), and this comes directly from the + # exponent of x. For 0.1 <= x <= 10 we use the inequalities + # 1-1/x <= log(x) <= x-1. If x > 1 we have |log10(x)| > + # (1-1/x)/2.31 > 0. If x < 1 then |log10(x)| > (1-x)/2.31 > 0 + + adj = self._exp + len(self._int) - 1 + if adj >= 1: + # self >= 10 + return len(str(adj))-1 + if adj <= -2: + # self < 0.1 + return len(str(-1-adj))-1 + op = _WorkRep(self) + c, e = op.int, op.exp + if adj == 0: + # 1 < self < 10 + num = str(c-10**-e) + den = str(231*c) + return len(num) - len(den) - (num < den) + 2 + # adj == -1, 0.1 <= self < 1 + num = str(10**-e-c) + return len(num) + e - (num < "231") - 1 + + def log10(self, context=None): + """Returns the base 10 logarithm of self.""" + + if context is None: + context = getcontext() + + # log10(NaN) = NaN + ans = self._check_nans(context=context) + if ans: + return ans + + # log10(0.0) == -Infinity + if not self: + return _NegativeInfinity + + # log10(Infinity) = Infinity + if self._isinfinity() == 1: + return _Infinity + + # log10(negative or -Infinity) raises InvalidOperation + if self._sign == 1: + return context._raise_error(InvalidOperation, + 'log10 of a negative value') + + # log10(10**n) = n + if self._int[0] == '1' and self._int[1:] == '0'*(len(self._int) - 1): + # answer may need rounding + ans = Decimal(self._exp + len(self._int) - 1) + else: + # result is irrational, so necessarily inexact + op = _WorkRep(self) + c, e = op.int, op.exp + p = context.prec + + # correctly rounded result: repeatedly increase precision + # until result is unambiguously roundable + places = p-self._log10_exp_bound()+2 + while True: + coeff = _dlog10(c, e, places) + # assert len(str(abs(coeff)))-p >= 1 + if coeff % (5*10**(len(str(abs(coeff)))-p-1)): + break + places += 3 + ans = _dec_from_triple(int(coeff<0), str(abs(coeff)), -places) + + context = context._shallow_copy() + rounding = context._set_rounding(ROUND_HALF_EVEN) + ans = ans._fix(context) + context.rounding = rounding + return ans + + def logb(self, context=None): + """ Returns the exponent of the magnitude of self's MSD. + + The result is the integer which is the exponent of the magnitude + of the most significant digit of self (as though it were truncated + to a single digit while maintaining the value of that digit and + without limiting the resulting exponent). + """ + # logb(NaN) = NaN + ans = self._check_nans(context=context) + if ans: + return ans + + if context is None: + context = getcontext() + + # logb(+/-Inf) = +Inf + if self._isinfinity(): + return _Infinity + + # logb(0) = -Inf, DivisionByZero + if not self: + return context._raise_error(DivisionByZero, 'logb(0)', 1) + + # otherwise, simply return the adjusted exponent of self, as a + # Decimal. Note that no attempt is made to fit the result + # into the current context. + ans = Decimal(self.adjusted()) + return ans._fix(context) + + def _islogical(self): + """Return True if self is a logical operand. + + For being logical, it must be a finite number with a sign of 0, + an exponent of 0, and a coefficient whose digits must all be + either 0 or 1. + """ + if self._sign != 0 or self._exp != 0: + return False + for dig in self._int: + if dig not in '01': + return False + return True + + def _fill_logical(self, context, opa, opb): + dif = context.prec - len(opa) + if dif > 0: + opa = '0'*dif + opa + elif dif < 0: + opa = opa[-context.prec:] + dif = context.prec - len(opb) + if dif > 0: + opb = '0'*dif + opb + elif dif < 0: + opb = opb[-context.prec:] + return opa, opb + + def logical_and(self, other, context=None): + """Applies an 'and' operation between self and other's digits.""" + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + if not self._islogical() or not other._islogical(): + return context._raise_error(InvalidOperation) + + # fill to context.prec + (opa, opb) = self._fill_logical(context, self._int, other._int) + + # make the operation, and clean starting zeroes + result = "".join([str(int(a)&int(b)) for a,b in zip(opa,opb)]) + return _dec_from_triple(0, result.lstrip('0') or '0', 0) + + def logical_invert(self, context=None): + """Invert all its digits.""" + if context is None: + context = getcontext() + return self.logical_xor(_dec_from_triple(0,'1'*context.prec,0), + context) + + def logical_or(self, other, context=None): + """Applies an 'or' operation between self and other's digits.""" + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + if not self._islogical() or not other._islogical(): + return context._raise_error(InvalidOperation) + + # fill to context.prec + (opa, opb) = self._fill_logical(context, self._int, other._int) + + # make the operation, and clean starting zeroes + result = "".join([str(int(a)|int(b)) for a,b in zip(opa,opb)]) + return _dec_from_triple(0, result.lstrip('0') or '0', 0) + + def logical_xor(self, other, context=None): + """Applies an 'xor' operation between self and other's digits.""" + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + if not self._islogical() or not other._islogical(): + return context._raise_error(InvalidOperation) + + # fill to context.prec + (opa, opb) = self._fill_logical(context, self._int, other._int) + + # make the operation, and clean starting zeroes + result = "".join([str(int(a)^int(b)) for a,b in zip(opa,opb)]) + return _dec_from_triple(0, result.lstrip('0') or '0', 0) + + def max_mag(self, other, context=None): + """Compares the values numerically with their sign ignored.""" + other = _convert_other(other, raiseit=True) + + if context is None: + context = getcontext() + + if self._is_special or other._is_special: + # If one operand is a quiet NaN and the other is number, then the + # number is always returned + sn = self._isnan() + on = other._isnan() + if sn or on: + if on == 1 and sn == 0: + return self._fix(context) + if sn == 1 and on == 0: + return other._fix(context) + return self._check_nans(other, context) + + c = self.copy_abs()._cmp(other.copy_abs()) + if c == 0: + c = self.compare_total(other) + + if c == -1: + ans = other + else: + ans = self + + return ans._fix(context) + + def min_mag(self, other, context=None): + """Compares the values numerically with their sign ignored.""" + other = _convert_other(other, raiseit=True) + + if context is None: + context = getcontext() + + if self._is_special or other._is_special: + # If one operand is a quiet NaN and the other is number, then the + # number is always returned + sn = self._isnan() + on = other._isnan() + if sn or on: + if on == 1 and sn == 0: + return self._fix(context) + if sn == 1 and on == 0: + return other._fix(context) + return self._check_nans(other, context) + + c = self.copy_abs()._cmp(other.copy_abs()) + if c == 0: + c = self.compare_total(other) + + if c == -1: + ans = self + else: + ans = other + + return ans._fix(context) + + def next_minus(self, context=None): + """Returns the largest representable number smaller than itself.""" + if context is None: + context = getcontext() + + ans = self._check_nans(context=context) + if ans: + return ans + + if self._isinfinity() == -1: + return _NegativeInfinity + if self._isinfinity() == 1: + return _dec_from_triple(0, '9'*context.prec, context.Etop()) + + context = context.copy() + context._set_rounding(ROUND_FLOOR) + context._ignore_all_flags() + new_self = self._fix(context) + if new_self != self: + return new_self + return self.__sub__(_dec_from_triple(0, '1', context.Etiny()-1), + context) + + def next_plus(self, context=None): + """Returns the smallest representable number larger than itself.""" + if context is None: + context = getcontext() + + ans = self._check_nans(context=context) + if ans: + return ans + + if self._isinfinity() == 1: + return _Infinity + if self._isinfinity() == -1: + return _dec_from_triple(1, '9'*context.prec, context.Etop()) + + context = context.copy() + context._set_rounding(ROUND_CEILING) + context._ignore_all_flags() + new_self = self._fix(context) + if new_self != self: + return new_self + return self.__add__(_dec_from_triple(0, '1', context.Etiny()-1), + context) + + def next_toward(self, other, context=None): + """Returns the number closest to self, in the direction towards other. + + The result is the closest representable number to self + (excluding self) that is in the direction towards other, + unless both have the same value. If the two operands are + numerically equal, then the result is a copy of self with the + sign set to be the same as the sign of other. + """ + other = _convert_other(other, raiseit=True) + + if context is None: + context = getcontext() + + ans = self._check_nans(other, context) + if ans: + return ans + + comparison = self._cmp(other) + if comparison == 0: + return self.copy_sign(other) + + if comparison == -1: + ans = self.next_plus(context) + else: # comparison == 1 + ans = self.next_minus(context) + + # decide which flags to raise using value of ans + if ans._isinfinity(): + context._raise_error(Overflow, + 'Infinite result from next_toward', + ans._sign) + context._raise_error(Inexact) + context._raise_error(Rounded) + elif ans.adjusted() < context.Emin: + context._raise_error(Underflow) + context._raise_error(Subnormal) + context._raise_error(Inexact) + context._raise_error(Rounded) + # if precision == 1 then we don't raise Clamped for a + # result 0E-Etiny. + if not ans: + context._raise_error(Clamped) + + return ans + + def number_class(self, context=None): + """Returns an indication of the class of self. + + The class is one of the following strings: + sNaN + NaN + -Infinity + -Normal + -Subnormal + -Zero + +Zero + +Subnormal + +Normal + +Infinity + """ + if self.is_snan(): + return "sNaN" + if self.is_qnan(): + return "NaN" + inf = self._isinfinity() + if inf == 1: + return "+Infinity" + if inf == -1: + return "-Infinity" + if self.is_zero(): + if self._sign: + return "-Zero" + else: + return "+Zero" + if context is None: + context = getcontext() + if self.is_subnormal(context=context): + if self._sign: + return "-Subnormal" + else: + return "+Subnormal" + # just a normal, regular, boring number, :) + if self._sign: + return "-Normal" + else: + return "+Normal" + + def radix(self): + """Just returns 10, as this is Decimal, :)""" + return Decimal(10) + + def rotate(self, other, context=None): + """Returns a rotated copy of self, value-of-other times.""" + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + ans = self._check_nans(other, context) + if ans: + return ans + + if other._exp != 0: + return context._raise_error(InvalidOperation) + if not (-context.prec <= int(other) <= context.prec): + return context._raise_error(InvalidOperation) + + if self._isinfinity(): + return Decimal(self) + + # get values, pad if necessary + torot = int(other) + rotdig = self._int + topad = context.prec - len(rotdig) + if topad > 0: + rotdig = '0'*topad + rotdig + elif topad < 0: + rotdig = rotdig[-topad:] + + # let's rotate! + rotated = rotdig[torot:] + rotdig[:torot] + return _dec_from_triple(self._sign, + rotated.lstrip('0') or '0', self._exp) + + def scaleb(self, other, context=None): + """Returns self operand after adding the second value to its exp.""" + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + ans = self._check_nans(other, context) + if ans: + return ans + + if other._exp != 0: + return context._raise_error(InvalidOperation) + liminf = -2 * (context.Emax + context.prec) + limsup = 2 * (context.Emax + context.prec) + if not (liminf <= int(other) <= limsup): + return context._raise_error(InvalidOperation) + + if self._isinfinity(): + return Decimal(self) + + d = _dec_from_triple(self._sign, self._int, self._exp + int(other)) + d = d._fix(context) + return d + + def shift(self, other, context=None): + """Returns a shifted copy of self, value-of-other times.""" + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + ans = self._check_nans(other, context) + if ans: + return ans + + if other._exp != 0: + return context._raise_error(InvalidOperation) + if not (-context.prec <= int(other) <= context.prec): + return context._raise_error(InvalidOperation) + + if self._isinfinity(): + return Decimal(self) + + # get values, pad if necessary + torot = int(other) + rotdig = self._int + topad = context.prec - len(rotdig) + if topad > 0: + rotdig = '0'*topad + rotdig + elif topad < 0: + rotdig = rotdig[-topad:] + + # let's shift! + if torot < 0: + shifted = rotdig[:torot] + else: + shifted = rotdig + '0'*torot + shifted = shifted[-context.prec:] + + return _dec_from_triple(self._sign, + shifted.lstrip('0') or '0', self._exp) + + # Support for pickling, copy, and deepcopy + def __reduce__(self): + return (self.__class__, (str(self),)) + + def __copy__(self): + if type(self) is Decimal: + return self # I'm immutable; therefore I am my own clone + return self.__class__(str(self)) + + def __deepcopy__(self, memo): + if type(self) is Decimal: + return self # My components are also immutable + return self.__class__(str(self)) + + # PEP 3101 support. the _localeconv keyword argument should be + # considered private: it's provided for ease of testing only. + def __format__(self, specifier, context=None, _localeconv=None): + """Format a Decimal instance according to the given specifier. + + The specifier should be a standard format specifier, with the + form described in PEP 3101. Formatting types 'e', 'E', 'f', + 'F', 'g', 'G', 'n' and '%' are supported. If the formatting + type is omitted it defaults to 'g' or 'G', depending on the + value of context.capitals. + """ + + # Note: PEP 3101 says that if the type is not present then + # there should be at least one digit after the decimal point. + # We take the liberty of ignoring this requirement for + # Decimal---it's presumably there to make sure that + # format(float, '') behaves similarly to str(float). + if context is None: + context = getcontext() + + spec = _parse_format_specifier(specifier, _localeconv=_localeconv) + + # special values don't care about the type or precision + if self._is_special: + sign = _format_sign(self._sign, spec) + body = str(self.copy_abs()) + if spec['type'] == '%': + body += '%' + return _format_align(sign, body, spec) + + # a type of None defaults to 'g' or 'G', depending on context + if spec['type'] is None: + spec['type'] = ['g', 'G'][context.capitals] + + # if type is '%', adjust exponent of self accordingly + if spec['type'] == '%': + self = _dec_from_triple(self._sign, self._int, self._exp+2) + + # round if necessary, taking rounding mode from the context + rounding = context.rounding + precision = spec['precision'] + if precision is not None: + if spec['type'] in 'eE': + self = self._round(precision+1, rounding) + elif spec['type'] in 'fF%': + self = self._rescale(-precision, rounding) + elif spec['type'] in 'gG' and len(self._int) > precision: + self = self._round(precision, rounding) + # special case: zeros with a positive exponent can't be + # represented in fixed point; rescale them to 0e0. + if not self and self._exp > 0 and spec['type'] in 'fF%': + self = self._rescale(0, rounding) + + # figure out placement of the decimal point + leftdigits = self._exp + len(self._int) + if spec['type'] in 'eE': + if not self and precision is not None: + dotplace = 1 - precision + else: + dotplace = 1 + elif spec['type'] in 'fF%': + dotplace = leftdigits + elif spec['type'] in 'gG': + if self._exp <= 0 and leftdigits > -6: + dotplace = leftdigits + else: + dotplace = 1 + + # find digits before and after decimal point, and get exponent + if dotplace < 0: + intpart = '0' + fracpart = '0'*(-dotplace) + self._int + elif dotplace > len(self._int): + intpart = self._int + '0'*(dotplace-len(self._int)) + fracpart = '' + else: + intpart = self._int[:dotplace] or '0' + fracpart = self._int[dotplace:] + exp = leftdigits-dotplace + + # done with the decimal-specific stuff; hand over the rest + # of the formatting to the _format_number function + return _format_number(self._sign, intpart, fracpart, exp, spec) + +def _dec_from_triple(sign, coefficient, exponent, special=False): + """Create a decimal instance directly, without any validation, + normalization (e.g. removal of leading zeros) or argument + conversion. + + This function is for *internal use only*. + """ + + self = object.__new__(Decimal) + self._sign = sign + self._int = coefficient + self._exp = exponent + self._is_special = special + + return self + +# Register Decimal as a kind of Number (an abstract base class). +# However, do not register it as Real (because Decimals are not +# interoperable with floats). +_numbers.Number.register(Decimal) + + +##### Context class ####################################################### + +class _ContextManager(object): + """Context manager class to support localcontext(). + + Sets a copy of the supplied context in __enter__() and restores + the previous decimal context in __exit__() + """ + def __init__(self, new_context): + self.new_context = new_context.copy() + def __enter__(self): + self.saved_context = getcontext() + setcontext(self.new_context) + return self.new_context + def __exit__(self, t, v, tb): + setcontext(self.saved_context) + +class Context(object): + """Contains the context for a Decimal instance. + + Contains: + prec - precision (for use in rounding, division, square roots..) + rounding - rounding type (how you round) + traps - If traps[exception] = 1, then the exception is + raised when it is caused. Otherwise, a value is + substituted in. + flags - When an exception is caused, flags[exception] is set. + (Whether or not the trap_enabler is set) + Should be reset by user of Decimal instance. + Emin - Minimum exponent + Emax - Maximum exponent + capitals - If 1, 1*10^1 is printed as 1E+1. + If 0, printed as 1e1 + clamp - If 1, change exponents if too high (Default 0) + """ + + def __init__(self, prec=None, rounding=None, Emin=None, Emax=None, + capitals=None, clamp=None, flags=None, traps=None, + _ignored_flags=None): + # Set defaults; for everything except flags and _ignored_flags, + # inherit from DefaultContext. + try: + dc = DefaultContext + except NameError: + pass + + self.prec = prec if prec is not None else dc.prec + self.rounding = rounding if rounding is not None else dc.rounding + self.Emin = Emin if Emin is not None else dc.Emin + self.Emax = Emax if Emax is not None else dc.Emax + self.capitals = capitals if capitals is not None else dc.capitals + self.clamp = clamp if clamp is not None else dc.clamp + + if _ignored_flags is None: + self._ignored_flags = [] + else: + self._ignored_flags = _ignored_flags + + if traps is None: + self.traps = dc.traps.copy() + elif not isinstance(traps, dict): + self.traps = dict((s, int(s in traps)) for s in _signals + traps) + else: + self.traps = traps + + if flags is None: + self.flags = dict.fromkeys(_signals, 0) + elif not isinstance(flags, dict): + self.flags = dict((s, int(s in flags)) for s in _signals + flags) + else: + self.flags = flags + + def _set_integer_check(self, name, value, vmin, vmax): + if not isinstance(value, int): + raise TypeError("%s must be an integer" % name) + if vmin == '-inf': + if value > vmax: + raise ValueError("%s must be in [%s, %d]. got: %s" % (name, vmin, vmax, value)) + elif vmax == 'inf': + if value < vmin: + raise ValueError("%s must be in [%d, %s]. got: %s" % (name, vmin, vmax, value)) + else: + if value < vmin or value > vmax: + raise ValueError("%s must be in [%d, %d]. got %s" % (name, vmin, vmax, value)) + return object.__setattr__(self, name, value) + + def _set_signal_dict(self, name, d): + if not isinstance(d, dict): + raise TypeError("%s must be a signal dict" % d) + for key in d: + if not key in _signals: + raise KeyError("%s is not a valid signal dict" % d) + for key in _signals: + if not key in d: + raise KeyError("%s is not a valid signal dict" % d) + return object.__setattr__(self, name, d) + + def __setattr__(self, name, value): + if name == 'prec': + return self._set_integer_check(name, value, 1, 'inf') + elif name == 'Emin': + return self._set_integer_check(name, value, '-inf', 0) + elif name == 'Emax': + return self._set_integer_check(name, value, 0, 'inf') + elif name == 'capitals': + return self._set_integer_check(name, value, 0, 1) + elif name == 'clamp': + return self._set_integer_check(name, value, 0, 1) + elif name == 'rounding': + if not value in _rounding_modes: + # raise TypeError even for strings to have consistency + # among various implementations. + raise TypeError("%s: invalid rounding mode" % value) + return object.__setattr__(self, name, value) + elif name == 'flags' or name == 'traps': + return self._set_signal_dict(name, value) + elif name == '_ignored_flags': + return object.__setattr__(self, name, value) + else: + raise AttributeError( + "'decimal.Context' object has no attribute '%s'" % name) + + def __delattr__(self, name): + raise AttributeError("%s cannot be deleted" % name) + + # Support for pickling, copy, and deepcopy + def __reduce__(self): + flags = [sig for sig, v in self.flags.items() if v] + traps = [sig for sig, v in self.traps.items() if v] + return (self.__class__, + (self.prec, self.rounding, self.Emin, self.Emax, + self.capitals, self.clamp, flags, traps)) + + def __repr__(self): + """Show the current context.""" + s = [] + s.append('Context(prec=%(prec)d, rounding=%(rounding)s, ' + 'Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d, ' + 'clamp=%(clamp)d' + % vars(self)) + names = [f.__name__ for f, v in self.flags.items() if v] + s.append('flags=[' + ', '.join(names) + ']') + names = [t.__name__ for t, v in self.traps.items() if v] + s.append('traps=[' + ', '.join(names) + ']') + return ', '.join(s) + ')' + + def clear_flags(self): + """Reset all flags to zero""" + for flag in self.flags: + self.flags[flag] = 0 + + def clear_traps(self): + """Reset all traps to zero""" + for flag in self.traps: + self.traps[flag] = 0 + + def _shallow_copy(self): + """Returns a shallow copy from self.""" + nc = Context(self.prec, self.rounding, self.Emin, self.Emax, + self.capitals, self.clamp, self.flags, self.traps, + self._ignored_flags) + return nc + + def copy(self): + """Returns a deep copy from self.""" + nc = Context(self.prec, self.rounding, self.Emin, self.Emax, + self.capitals, self.clamp, + self.flags.copy(), self.traps.copy(), + self._ignored_flags) + return nc + __copy__ = copy + + def _raise_error(self, condition, explanation = None, *args): + """Handles an error + + If the flag is in _ignored_flags, returns the default response. + Otherwise, it sets the flag, then, if the corresponding + trap_enabler is set, it reraises the exception. Otherwise, it returns + the default value after setting the flag. + """ + error = _condition_map.get(condition, condition) + if error in self._ignored_flags: + # Don't touch the flag + return error().handle(self, *args) + + self.flags[error] = 1 + if not self.traps[error]: + # The errors define how to handle themselves. + return condition().handle(self, *args) + + # Errors should only be risked on copies of the context + # self._ignored_flags = [] + raise error(explanation) + + def _ignore_all_flags(self): + """Ignore all flags, if they are raised""" + return self._ignore_flags(*_signals) + + def _ignore_flags(self, *flags): + """Ignore the flags, if they are raised""" + # Do not mutate-- This way, copies of a context leave the original + # alone. + self._ignored_flags = (self._ignored_flags + list(flags)) + return list(flags) + + def _regard_flags(self, *flags): + """Stop ignoring the flags, if they are raised""" + if flags and isinstance(flags[0], (tuple,list)): + flags = flags[0] + for flag in flags: + self._ignored_flags.remove(flag) + + # We inherit object.__hash__, so we must deny this explicitly + __hash__ = None + + def Etiny(self): + """Returns Etiny (= Emin - prec + 1)""" + return int(self.Emin - self.prec + 1) + + def Etop(self): + """Returns maximum exponent (= Emax - prec + 1)""" + return int(self.Emax - self.prec + 1) + + def _set_rounding(self, type): + """Sets the rounding type. + + Sets the rounding type, and returns the current (previous) + rounding type. Often used like: + + context = context.copy() + # so you don't change the calling context + # if an error occurs in the middle. + rounding = context._set_rounding(ROUND_UP) + val = self.__sub__(other, context=context) + context._set_rounding(rounding) + + This will make it round up for that operation. + """ + rounding = self.rounding + self.rounding= type + return rounding + + def create_decimal(self, num='0'): + """Creates a new Decimal instance but using self as context. + + This method implements the to-number operation of the + IBM Decimal specification.""" + + if isinstance(num, str) and num != num.strip(): + return self._raise_error(ConversionSyntax, + "no trailing or leading whitespace is " + "permitted.") + + d = Decimal(num, context=self) + if d._isnan() and len(d._int) > self.prec - self.clamp: + return self._raise_error(ConversionSyntax, + "diagnostic info too long in NaN") + return d._fix(self) + + def create_decimal_from_float(self, f): + """Creates a new Decimal instance from a float but rounding using self + as the context. + + >>> context = Context(prec=5, rounding=ROUND_DOWN) + >>> context.create_decimal_from_float(3.1415926535897932) + Decimal('3.1415') + >>> context = Context(prec=5, traps=[Inexact]) + >>> context.create_decimal_from_float(3.1415926535897932) + Traceback (most recent call last): + ... + decimal.Inexact + + """ + d = Decimal.from_float(f) # An exact conversion + return d._fix(self) # Apply the context rounding + + # Methods + def abs(self, a): + """Returns the absolute value of the operand. + + If the operand is negative, the result is the same as using the minus + operation on the operand. Otherwise, the result is the same as using + the plus operation on the operand. + + >>> ExtendedContext.abs(Decimal('2.1')) + Decimal('2.1') + >>> ExtendedContext.abs(Decimal('-100')) + Decimal('100') + >>> ExtendedContext.abs(Decimal('101.5')) + Decimal('101.5') + >>> ExtendedContext.abs(Decimal('-101.5')) + Decimal('101.5') + >>> ExtendedContext.abs(-1) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + return a.__abs__(context=self) + + def add(self, a, b): + """Return the sum of the two operands. + + >>> ExtendedContext.add(Decimal('12'), Decimal('7.00')) + Decimal('19.00') + >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4')) + Decimal('1.02E+4') + >>> ExtendedContext.add(1, Decimal(2)) + Decimal('3') + >>> ExtendedContext.add(Decimal(8), 5) + Decimal('13') + >>> ExtendedContext.add(5, 5) + Decimal('10') + """ + a = _convert_other(a, raiseit=True) + r = a.__add__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def _apply(self, a): + return str(a._fix(self)) + + def canonical(self, a): + """Returns the same Decimal object. + + As we do not have different encodings for the same number, the + received object already is in its canonical form. + + >>> ExtendedContext.canonical(Decimal('2.50')) + Decimal('2.50') + """ + if not isinstance(a, Decimal): + raise TypeError("canonical requires a Decimal as an argument.") + return a.canonical() + + def compare(self, a, b): + """Compares values numerically. + + If the signs of the operands differ, a value representing each operand + ('-1' if the operand is less than zero, '0' if the operand is zero or + negative zero, or '1' if the operand is greater than zero) is used in + place of that operand for the comparison instead of the actual + operand. + + The comparison is then effected by subtracting the second operand from + the first and then returning a value according to the result of the + subtraction: '-1' if the result is less than zero, '0' if the result is + zero or negative zero, or '1' if the result is greater than zero. + + >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3')) + Decimal('-1') + >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1')) + Decimal('0') + >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10')) + Decimal('0') + >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1')) + Decimal('1') + >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3')) + Decimal('1') + >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1')) + Decimal('-1') + >>> ExtendedContext.compare(1, 2) + Decimal('-1') + >>> ExtendedContext.compare(Decimal(1), 2) + Decimal('-1') + >>> ExtendedContext.compare(1, Decimal(2)) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.compare(b, context=self) + + def compare_signal(self, a, b): + """Compares the values of the two operands numerically. + + It's pretty much like compare(), but all NaNs signal, with signaling + NaNs taking precedence over quiet NaNs. + + >>> c = ExtendedContext + >>> c.compare_signal(Decimal('2.1'), Decimal('3')) + Decimal('-1') + >>> c.compare_signal(Decimal('2.1'), Decimal('2.1')) + Decimal('0') + >>> c.flags[InvalidOperation] = 0 + >>> print(c.flags[InvalidOperation]) + 0 + >>> c.compare_signal(Decimal('NaN'), Decimal('2.1')) + Decimal('NaN') + >>> print(c.flags[InvalidOperation]) + 1 + >>> c.flags[InvalidOperation] = 0 + >>> print(c.flags[InvalidOperation]) + 0 + >>> c.compare_signal(Decimal('sNaN'), Decimal('2.1')) + Decimal('NaN') + >>> print(c.flags[InvalidOperation]) + 1 + >>> c.compare_signal(-1, 2) + Decimal('-1') + >>> c.compare_signal(Decimal(-1), 2) + Decimal('-1') + >>> c.compare_signal(-1, Decimal(2)) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.compare_signal(b, context=self) + + def compare_total(self, a, b): + """Compares two operands using their abstract representation. + + This is not like the standard compare, which use their numerical + value. Note that a total ordering is defined for all possible abstract + representations. + + >>> ExtendedContext.compare_total(Decimal('12.73'), Decimal('127.9')) + Decimal('-1') + >>> ExtendedContext.compare_total(Decimal('-127'), Decimal('12')) + Decimal('-1') + >>> ExtendedContext.compare_total(Decimal('12.30'), Decimal('12.3')) + Decimal('-1') + >>> ExtendedContext.compare_total(Decimal('12.30'), Decimal('12.30')) + Decimal('0') + >>> ExtendedContext.compare_total(Decimal('12.3'), Decimal('12.300')) + Decimal('1') + >>> ExtendedContext.compare_total(Decimal('12.3'), Decimal('NaN')) + Decimal('-1') + >>> ExtendedContext.compare_total(1, 2) + Decimal('-1') + >>> ExtendedContext.compare_total(Decimal(1), 2) + Decimal('-1') + >>> ExtendedContext.compare_total(1, Decimal(2)) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.compare_total(b) + + def compare_total_mag(self, a, b): + """Compares two operands using their abstract representation ignoring sign. + + Like compare_total, but with operand's sign ignored and assumed to be 0. + """ + a = _convert_other(a, raiseit=True) + return a.compare_total_mag(b) + + def copy_abs(self, a): + """Returns a copy of the operand with the sign set to 0. + + >>> ExtendedContext.copy_abs(Decimal('2.1')) + Decimal('2.1') + >>> ExtendedContext.copy_abs(Decimal('-100')) + Decimal('100') + >>> ExtendedContext.copy_abs(-1) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + return a.copy_abs() + + def copy_decimal(self, a): + """Returns a copy of the decimal object. + + >>> ExtendedContext.copy_decimal(Decimal('2.1')) + Decimal('2.1') + >>> ExtendedContext.copy_decimal(Decimal('-1.00')) + Decimal('-1.00') + >>> ExtendedContext.copy_decimal(1) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + return Decimal(a) + + def copy_negate(self, a): + """Returns a copy of the operand with the sign inverted. + + >>> ExtendedContext.copy_negate(Decimal('101.5')) + Decimal('-101.5') + >>> ExtendedContext.copy_negate(Decimal('-101.5')) + Decimal('101.5') + >>> ExtendedContext.copy_negate(1) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.copy_negate() + + def copy_sign(self, a, b): + """Copies the second operand's sign to the first one. + + In detail, it returns a copy of the first operand with the sign + equal to the sign of the second operand. + + >>> ExtendedContext.copy_sign(Decimal( '1.50'), Decimal('7.33')) + Decimal('1.50') + >>> ExtendedContext.copy_sign(Decimal('-1.50'), Decimal('7.33')) + Decimal('1.50') + >>> ExtendedContext.copy_sign(Decimal( '1.50'), Decimal('-7.33')) + Decimal('-1.50') + >>> ExtendedContext.copy_sign(Decimal('-1.50'), Decimal('-7.33')) + Decimal('-1.50') + >>> ExtendedContext.copy_sign(1, -2) + Decimal('-1') + >>> ExtendedContext.copy_sign(Decimal(1), -2) + Decimal('-1') + >>> ExtendedContext.copy_sign(1, Decimal(-2)) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.copy_sign(b) + + def divide(self, a, b): + """Decimal division in a specified context. + + >>> ExtendedContext.divide(Decimal('1'), Decimal('3')) + Decimal('0.333333333') + >>> ExtendedContext.divide(Decimal('2'), Decimal('3')) + Decimal('0.666666667') + >>> ExtendedContext.divide(Decimal('5'), Decimal('2')) + Decimal('2.5') + >>> ExtendedContext.divide(Decimal('1'), Decimal('10')) + Decimal('0.1') + >>> ExtendedContext.divide(Decimal('12'), Decimal('12')) + Decimal('1') + >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2')) + Decimal('4.00') + >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0')) + Decimal('1.20') + >>> ExtendedContext.divide(Decimal('1000'), Decimal('100')) + Decimal('10') + >>> ExtendedContext.divide(Decimal('1000'), Decimal('1')) + Decimal('1000') + >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2')) + Decimal('1.20E+6') + >>> ExtendedContext.divide(5, 5) + Decimal('1') + >>> ExtendedContext.divide(Decimal(5), 5) + Decimal('1') + >>> ExtendedContext.divide(5, Decimal(5)) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + r = a.__truediv__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def divide_int(self, a, b): + """Divides two numbers and returns the integer part of the result. + + >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3')) + Decimal('0') + >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3')) + Decimal('3') + >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3')) + Decimal('3') + >>> ExtendedContext.divide_int(10, 3) + Decimal('3') + >>> ExtendedContext.divide_int(Decimal(10), 3) + Decimal('3') + >>> ExtendedContext.divide_int(10, Decimal(3)) + Decimal('3') + """ + a = _convert_other(a, raiseit=True) + r = a.__floordiv__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def divmod(self, a, b): + """Return (a // b, a % b). + + >>> ExtendedContext.divmod(Decimal(8), Decimal(3)) + (Decimal('2'), Decimal('2')) + >>> ExtendedContext.divmod(Decimal(8), Decimal(4)) + (Decimal('2'), Decimal('0')) + >>> ExtendedContext.divmod(8, 4) + (Decimal('2'), Decimal('0')) + >>> ExtendedContext.divmod(Decimal(8), 4) + (Decimal('2'), Decimal('0')) + >>> ExtendedContext.divmod(8, Decimal(4)) + (Decimal('2'), Decimal('0')) + """ + a = _convert_other(a, raiseit=True) + r = a.__divmod__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def exp(self, a): + """Returns e ** a. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.exp(Decimal('-Infinity')) + Decimal('0') + >>> c.exp(Decimal('-1')) + Decimal('0.367879441') + >>> c.exp(Decimal('0')) + Decimal('1') + >>> c.exp(Decimal('1')) + Decimal('2.71828183') + >>> c.exp(Decimal('0.693147181')) + Decimal('2.00000000') + >>> c.exp(Decimal('+Infinity')) + Decimal('Infinity') + >>> c.exp(10) + Decimal('22026.4658') + """ + a =_convert_other(a, raiseit=True) + return a.exp(context=self) + + def fma(self, a, b, c): + """Returns a multiplied by b, plus c. + + The first two operands are multiplied together, using multiply, + the third operand is then added to the result of that + multiplication, using add, all with only one final rounding. + + >>> ExtendedContext.fma(Decimal('3'), Decimal('5'), Decimal('7')) + Decimal('22') + >>> ExtendedContext.fma(Decimal('3'), Decimal('-5'), Decimal('7')) + Decimal('-8') + >>> ExtendedContext.fma(Decimal('888565290'), Decimal('1557.96930'), Decimal('-86087.7578')) + Decimal('1.38435736E+12') + >>> ExtendedContext.fma(1, 3, 4) + Decimal('7') + >>> ExtendedContext.fma(1, Decimal(3), 4) + Decimal('7') + >>> ExtendedContext.fma(1, 3, Decimal(4)) + Decimal('7') + """ + a = _convert_other(a, raiseit=True) + return a.fma(b, c, context=self) + + def is_canonical(self, a): + """Return True if the operand is canonical; otherwise return False. + + Currently, the encoding of a Decimal instance is always + canonical, so this method returns True for any Decimal. + + >>> ExtendedContext.is_canonical(Decimal('2.50')) + True + """ + if not isinstance(a, Decimal): + raise TypeError("is_canonical requires a Decimal as an argument.") + return a.is_canonical() + + def is_finite(self, a): + """Return True if the operand is finite; otherwise return False. + + A Decimal instance is considered finite if it is neither + infinite nor a NaN. + + >>> ExtendedContext.is_finite(Decimal('2.50')) + True + >>> ExtendedContext.is_finite(Decimal('-0.3')) + True + >>> ExtendedContext.is_finite(Decimal('0')) + True + >>> ExtendedContext.is_finite(Decimal('Inf')) + False + >>> ExtendedContext.is_finite(Decimal('NaN')) + False + >>> ExtendedContext.is_finite(1) + True + """ + a = _convert_other(a, raiseit=True) + return a.is_finite() + + def is_infinite(self, a): + """Return True if the operand is infinite; otherwise return False. + + >>> ExtendedContext.is_infinite(Decimal('2.50')) + False + >>> ExtendedContext.is_infinite(Decimal('-Inf')) + True + >>> ExtendedContext.is_infinite(Decimal('NaN')) + False + >>> ExtendedContext.is_infinite(1) + False + """ + a = _convert_other(a, raiseit=True) + return a.is_infinite() + + def is_nan(self, a): + """Return True if the operand is a qNaN or sNaN; + otherwise return False. + + >>> ExtendedContext.is_nan(Decimal('2.50')) + False + >>> ExtendedContext.is_nan(Decimal('NaN')) + True + >>> ExtendedContext.is_nan(Decimal('-sNaN')) + True + >>> ExtendedContext.is_nan(1) + False + """ + a = _convert_other(a, raiseit=True) + return a.is_nan() + + def is_normal(self, a): + """Return True if the operand is a normal number; + otherwise return False. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.is_normal(Decimal('2.50')) + True + >>> c.is_normal(Decimal('0.1E-999')) + False + >>> c.is_normal(Decimal('0.00')) + False + >>> c.is_normal(Decimal('-Inf')) + False + >>> c.is_normal(Decimal('NaN')) + False + >>> c.is_normal(1) + True + """ + a = _convert_other(a, raiseit=True) + return a.is_normal(context=self) + + def is_qnan(self, a): + """Return True if the operand is a quiet NaN; otherwise return False. + + >>> ExtendedContext.is_qnan(Decimal('2.50')) + False + >>> ExtendedContext.is_qnan(Decimal('NaN')) + True + >>> ExtendedContext.is_qnan(Decimal('sNaN')) + False + >>> ExtendedContext.is_qnan(1) + False + """ + a = _convert_other(a, raiseit=True) + return a.is_qnan() + + def is_signed(self, a): + """Return True if the operand is negative; otherwise return False. + + >>> ExtendedContext.is_signed(Decimal('2.50')) + False + >>> ExtendedContext.is_signed(Decimal('-12')) + True + >>> ExtendedContext.is_signed(Decimal('-0')) + True + >>> ExtendedContext.is_signed(8) + False + >>> ExtendedContext.is_signed(-8) + True + """ + a = _convert_other(a, raiseit=True) + return a.is_signed() + + def is_snan(self, a): + """Return True if the operand is a signaling NaN; + otherwise return False. + + >>> ExtendedContext.is_snan(Decimal('2.50')) + False + >>> ExtendedContext.is_snan(Decimal('NaN')) + False + >>> ExtendedContext.is_snan(Decimal('sNaN')) + True + >>> ExtendedContext.is_snan(1) + False + """ + a = _convert_other(a, raiseit=True) + return a.is_snan() + + def is_subnormal(self, a): + """Return True if the operand is subnormal; otherwise return False. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.is_subnormal(Decimal('2.50')) + False + >>> c.is_subnormal(Decimal('0.1E-999')) + True + >>> c.is_subnormal(Decimal('0.00')) + False + >>> c.is_subnormal(Decimal('-Inf')) + False + >>> c.is_subnormal(Decimal('NaN')) + False + >>> c.is_subnormal(1) + False + """ + a = _convert_other(a, raiseit=True) + return a.is_subnormal(context=self) + + def is_zero(self, a): + """Return True if the operand is a zero; otherwise return False. + + >>> ExtendedContext.is_zero(Decimal('0')) + True + >>> ExtendedContext.is_zero(Decimal('2.50')) + False + >>> ExtendedContext.is_zero(Decimal('-0E+2')) + True + >>> ExtendedContext.is_zero(1) + False + >>> ExtendedContext.is_zero(0) + True + """ + a = _convert_other(a, raiseit=True) + return a.is_zero() + + def ln(self, a): + """Returns the natural (base e) logarithm of the operand. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.ln(Decimal('0')) + Decimal('-Infinity') + >>> c.ln(Decimal('1.000')) + Decimal('0') + >>> c.ln(Decimal('2.71828183')) + Decimal('1.00000000') + >>> c.ln(Decimal('10')) + Decimal('2.30258509') + >>> c.ln(Decimal('+Infinity')) + Decimal('Infinity') + >>> c.ln(1) + Decimal('0') + """ + a = _convert_other(a, raiseit=True) + return a.ln(context=self) + + def log10(self, a): + """Returns the base 10 logarithm of the operand. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.log10(Decimal('0')) + Decimal('-Infinity') + >>> c.log10(Decimal('0.001')) + Decimal('-3') + >>> c.log10(Decimal('1.000')) + Decimal('0') + >>> c.log10(Decimal('2')) + Decimal('0.301029996') + >>> c.log10(Decimal('10')) + Decimal('1') + >>> c.log10(Decimal('70')) + Decimal('1.84509804') + >>> c.log10(Decimal('+Infinity')) + Decimal('Infinity') + >>> c.log10(0) + Decimal('-Infinity') + >>> c.log10(1) + Decimal('0') + """ + a = _convert_other(a, raiseit=True) + return a.log10(context=self) + + def logb(self, a): + """ Returns the exponent of the magnitude of the operand's MSD. + + The result is the integer which is the exponent of the magnitude + of the most significant digit of the operand (as though the + operand were truncated to a single digit while maintaining the + value of that digit and without limiting the resulting exponent). + + >>> ExtendedContext.logb(Decimal('250')) + Decimal('2') + >>> ExtendedContext.logb(Decimal('2.50')) + Decimal('0') + >>> ExtendedContext.logb(Decimal('0.03')) + Decimal('-2') + >>> ExtendedContext.logb(Decimal('0')) + Decimal('-Infinity') + >>> ExtendedContext.logb(1) + Decimal('0') + >>> ExtendedContext.logb(10) + Decimal('1') + >>> ExtendedContext.logb(100) + Decimal('2') + """ + a = _convert_other(a, raiseit=True) + return a.logb(context=self) + + def logical_and(self, a, b): + """Applies the logical operation 'and' between each operand's digits. + + The operands must be both logical numbers. + + >>> ExtendedContext.logical_and(Decimal('0'), Decimal('0')) + Decimal('0') + >>> ExtendedContext.logical_and(Decimal('0'), Decimal('1')) + Decimal('0') + >>> ExtendedContext.logical_and(Decimal('1'), Decimal('0')) + Decimal('0') + >>> ExtendedContext.logical_and(Decimal('1'), Decimal('1')) + Decimal('1') + >>> ExtendedContext.logical_and(Decimal('1100'), Decimal('1010')) + Decimal('1000') + >>> ExtendedContext.logical_and(Decimal('1111'), Decimal('10')) + Decimal('10') + >>> ExtendedContext.logical_and(110, 1101) + Decimal('100') + >>> ExtendedContext.logical_and(Decimal(110), 1101) + Decimal('100') + >>> ExtendedContext.logical_and(110, Decimal(1101)) + Decimal('100') + """ + a = _convert_other(a, raiseit=True) + return a.logical_and(b, context=self) + + def logical_invert(self, a): + """Invert all the digits in the operand. + + The operand must be a logical number. + + >>> ExtendedContext.logical_invert(Decimal('0')) + Decimal('111111111') + >>> ExtendedContext.logical_invert(Decimal('1')) + Decimal('111111110') + >>> ExtendedContext.logical_invert(Decimal('111111111')) + Decimal('0') + >>> ExtendedContext.logical_invert(Decimal('101010101')) + Decimal('10101010') + >>> ExtendedContext.logical_invert(1101) + Decimal('111110010') + """ + a = _convert_other(a, raiseit=True) + return a.logical_invert(context=self) + + def logical_or(self, a, b): + """Applies the logical operation 'or' between each operand's digits. + + The operands must be both logical numbers. + + >>> ExtendedContext.logical_or(Decimal('0'), Decimal('0')) + Decimal('0') + >>> ExtendedContext.logical_or(Decimal('0'), Decimal('1')) + Decimal('1') + >>> ExtendedContext.logical_or(Decimal('1'), Decimal('0')) + Decimal('1') + >>> ExtendedContext.logical_or(Decimal('1'), Decimal('1')) + Decimal('1') + >>> ExtendedContext.logical_or(Decimal('1100'), Decimal('1010')) + Decimal('1110') + >>> ExtendedContext.logical_or(Decimal('1110'), Decimal('10')) + Decimal('1110') + >>> ExtendedContext.logical_or(110, 1101) + Decimal('1111') + >>> ExtendedContext.logical_or(Decimal(110), 1101) + Decimal('1111') + >>> ExtendedContext.logical_or(110, Decimal(1101)) + Decimal('1111') + """ + a = _convert_other(a, raiseit=True) + return a.logical_or(b, context=self) + + def logical_xor(self, a, b): + """Applies the logical operation 'xor' between each operand's digits. + + The operands must be both logical numbers. + + >>> ExtendedContext.logical_xor(Decimal('0'), Decimal('0')) + Decimal('0') + >>> ExtendedContext.logical_xor(Decimal('0'), Decimal('1')) + Decimal('1') + >>> ExtendedContext.logical_xor(Decimal('1'), Decimal('0')) + Decimal('1') + >>> ExtendedContext.logical_xor(Decimal('1'), Decimal('1')) + Decimal('0') + >>> ExtendedContext.logical_xor(Decimal('1100'), Decimal('1010')) + Decimal('110') + >>> ExtendedContext.logical_xor(Decimal('1111'), Decimal('10')) + Decimal('1101') + >>> ExtendedContext.logical_xor(110, 1101) + Decimal('1011') + >>> ExtendedContext.logical_xor(Decimal(110), 1101) + Decimal('1011') + >>> ExtendedContext.logical_xor(110, Decimal(1101)) + Decimal('1011') + """ + a = _convert_other(a, raiseit=True) + return a.logical_xor(b, context=self) + + def max(self, a, b): + """max compares two values numerically and returns the maximum. + + If either operand is a NaN then the general rules apply. + Otherwise, the operands are compared as though by the compare + operation. If they are numerically equal then the left-hand operand + is chosen as the result. Otherwise the maximum (closer to positive + infinity) of the two operands is chosen as the result. + + >>> ExtendedContext.max(Decimal('3'), Decimal('2')) + Decimal('3') + >>> ExtendedContext.max(Decimal('-10'), Decimal('3')) + Decimal('3') + >>> ExtendedContext.max(Decimal('1.0'), Decimal('1')) + Decimal('1') + >>> ExtendedContext.max(Decimal('7'), Decimal('NaN')) + Decimal('7') + >>> ExtendedContext.max(1, 2) + Decimal('2') + >>> ExtendedContext.max(Decimal(1), 2) + Decimal('2') + >>> ExtendedContext.max(1, Decimal(2)) + Decimal('2') + """ + a = _convert_other(a, raiseit=True) + return a.max(b, context=self) + + def max_mag(self, a, b): + """Compares the values numerically with their sign ignored. + + >>> ExtendedContext.max_mag(Decimal('7'), Decimal('NaN')) + Decimal('7') + >>> ExtendedContext.max_mag(Decimal('7'), Decimal('-10')) + Decimal('-10') + >>> ExtendedContext.max_mag(1, -2) + Decimal('-2') + >>> ExtendedContext.max_mag(Decimal(1), -2) + Decimal('-2') + >>> ExtendedContext.max_mag(1, Decimal(-2)) + Decimal('-2') + """ + a = _convert_other(a, raiseit=True) + return a.max_mag(b, context=self) + + def min(self, a, b): + """min compares two values numerically and returns the minimum. + + If either operand is a NaN then the general rules apply. + Otherwise, the operands are compared as though by the compare + operation. If they are numerically equal then the left-hand operand + is chosen as the result. Otherwise the minimum (closer to negative + infinity) of the two operands is chosen as the result. + + >>> ExtendedContext.min(Decimal('3'), Decimal('2')) + Decimal('2') + >>> ExtendedContext.min(Decimal('-10'), Decimal('3')) + Decimal('-10') + >>> ExtendedContext.min(Decimal('1.0'), Decimal('1')) + Decimal('1.0') + >>> ExtendedContext.min(Decimal('7'), Decimal('NaN')) + Decimal('7') + >>> ExtendedContext.min(1, 2) + Decimal('1') + >>> ExtendedContext.min(Decimal(1), 2) + Decimal('1') + >>> ExtendedContext.min(1, Decimal(29)) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + return a.min(b, context=self) + + def min_mag(self, a, b): + """Compares the values numerically with their sign ignored. + + >>> ExtendedContext.min_mag(Decimal('3'), Decimal('-2')) + Decimal('-2') + >>> ExtendedContext.min_mag(Decimal('-3'), Decimal('NaN')) + Decimal('-3') + >>> ExtendedContext.min_mag(1, -2) + Decimal('1') + >>> ExtendedContext.min_mag(Decimal(1), -2) + Decimal('1') + >>> ExtendedContext.min_mag(1, Decimal(-2)) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + return a.min_mag(b, context=self) + + def minus(self, a): + """Minus corresponds to unary prefix minus in Python. + + The operation is evaluated using the same rules as subtract; the + operation minus(a) is calculated as subtract('0', a) where the '0' + has the same exponent as the operand. + + >>> ExtendedContext.minus(Decimal('1.3')) + Decimal('-1.3') + >>> ExtendedContext.minus(Decimal('-1.3')) + Decimal('1.3') + >>> ExtendedContext.minus(1) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.__neg__(context=self) + + def multiply(self, a, b): + """multiply multiplies two operands. + + If either operand is a special value then the general rules apply. + Otherwise, the operands are multiplied together + ('long multiplication'), resulting in a number which may be as long as + the sum of the lengths of the two operands. + + >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3')) + Decimal('3.60') + >>> ExtendedContext.multiply(Decimal('7'), Decimal('3')) + Decimal('21') + >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8')) + Decimal('0.72') + >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0')) + Decimal('-0.0') + >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321')) + Decimal('4.28135971E+11') + >>> ExtendedContext.multiply(7, 7) + Decimal('49') + >>> ExtendedContext.multiply(Decimal(7), 7) + Decimal('49') + >>> ExtendedContext.multiply(7, Decimal(7)) + Decimal('49') + """ + a = _convert_other(a, raiseit=True) + r = a.__mul__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def next_minus(self, a): + """Returns the largest representable number smaller than a. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> ExtendedContext.next_minus(Decimal('1')) + Decimal('0.999999999') + >>> c.next_minus(Decimal('1E-1007')) + Decimal('0E-1007') + >>> ExtendedContext.next_minus(Decimal('-1.00000003')) + Decimal('-1.00000004') + >>> c.next_minus(Decimal('Infinity')) + Decimal('9.99999999E+999') + >>> c.next_minus(1) + Decimal('0.999999999') + """ + a = _convert_other(a, raiseit=True) + return a.next_minus(context=self) + + def next_plus(self, a): + """Returns the smallest representable number larger than a. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> ExtendedContext.next_plus(Decimal('1')) + Decimal('1.00000001') + >>> c.next_plus(Decimal('-1E-1007')) + Decimal('-0E-1007') + >>> ExtendedContext.next_plus(Decimal('-1.00000003')) + Decimal('-1.00000002') + >>> c.next_plus(Decimal('-Infinity')) + Decimal('-9.99999999E+999') + >>> c.next_plus(1) + Decimal('1.00000001') + """ + a = _convert_other(a, raiseit=True) + return a.next_plus(context=self) + + def next_toward(self, a, b): + """Returns the number closest to a, in direction towards b. + + The result is the closest representable number from the first + operand (but not the first operand) that is in the direction + towards the second operand, unless the operands have the same + value. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.next_toward(Decimal('1'), Decimal('2')) + Decimal('1.00000001') + >>> c.next_toward(Decimal('-1E-1007'), Decimal('1')) + Decimal('-0E-1007') + >>> c.next_toward(Decimal('-1.00000003'), Decimal('0')) + Decimal('-1.00000002') + >>> c.next_toward(Decimal('1'), Decimal('0')) + Decimal('0.999999999') + >>> c.next_toward(Decimal('1E-1007'), Decimal('-100')) + Decimal('0E-1007') + >>> c.next_toward(Decimal('-1.00000003'), Decimal('-10')) + Decimal('-1.00000004') + >>> c.next_toward(Decimal('0.00'), Decimal('-0.0000')) + Decimal('-0.00') + >>> c.next_toward(0, 1) + Decimal('1E-1007') + >>> c.next_toward(Decimal(0), 1) + Decimal('1E-1007') + >>> c.next_toward(0, Decimal(1)) + Decimal('1E-1007') + """ + a = _convert_other(a, raiseit=True) + return a.next_toward(b, context=self) + + def normalize(self, a): + """normalize reduces an operand to its simplest form. + + Essentially a plus operation with all trailing zeros removed from the + result. + + >>> ExtendedContext.normalize(Decimal('2.1')) + Decimal('2.1') + >>> ExtendedContext.normalize(Decimal('-2.0')) + Decimal('-2') + >>> ExtendedContext.normalize(Decimal('1.200')) + Decimal('1.2') + >>> ExtendedContext.normalize(Decimal('-120')) + Decimal('-1.2E+2') + >>> ExtendedContext.normalize(Decimal('120.00')) + Decimal('1.2E+2') + >>> ExtendedContext.normalize(Decimal('0.00')) + Decimal('0') + >>> ExtendedContext.normalize(6) + Decimal('6') + """ + a = _convert_other(a, raiseit=True) + return a.normalize(context=self) + + def number_class(self, a): + """Returns an indication of the class of the operand. + + The class is one of the following strings: + -sNaN + -NaN + -Infinity + -Normal + -Subnormal + -Zero + +Zero + +Subnormal + +Normal + +Infinity + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.number_class(Decimal('Infinity')) + '+Infinity' + >>> c.number_class(Decimal('1E-10')) + '+Normal' + >>> c.number_class(Decimal('2.50')) + '+Normal' + >>> c.number_class(Decimal('0.1E-999')) + '+Subnormal' + >>> c.number_class(Decimal('0')) + '+Zero' + >>> c.number_class(Decimal('-0')) + '-Zero' + >>> c.number_class(Decimal('-0.1E-999')) + '-Subnormal' + >>> c.number_class(Decimal('-1E-10')) + '-Normal' + >>> c.number_class(Decimal('-2.50')) + '-Normal' + >>> c.number_class(Decimal('-Infinity')) + '-Infinity' + >>> c.number_class(Decimal('NaN')) + 'NaN' + >>> c.number_class(Decimal('-NaN')) + 'NaN' + >>> c.number_class(Decimal('sNaN')) + 'sNaN' + >>> c.number_class(123) + '+Normal' + """ + a = _convert_other(a, raiseit=True) + return a.number_class(context=self) + + def plus(self, a): + """Plus corresponds to unary prefix plus in Python. + + The operation is evaluated using the same rules as add; the + operation plus(a) is calculated as add('0', a) where the '0' + has the same exponent as the operand. + + >>> ExtendedContext.plus(Decimal('1.3')) + Decimal('1.3') + >>> ExtendedContext.plus(Decimal('-1.3')) + Decimal('-1.3') + >>> ExtendedContext.plus(-1) + Decimal('-1') + """ + a = _convert_other(a, raiseit=True) + return a.__pos__(context=self) + + def power(self, a, b, modulo=None): + """Raises a to the power of b, to modulo if given. + + With two arguments, compute a**b. If a is negative then b + must be integral. The result will be inexact unless b is + integral and the result is finite and can be expressed exactly + in 'precision' digits. + + With three arguments, compute (a**b) % modulo. For the + three argument form, the following restrictions on the + arguments hold: + + - all three arguments must be integral + - b must be nonnegative + - at least one of a or b must be nonzero + - modulo must be nonzero and have at most 'precision' digits + + The result of pow(a, b, modulo) is identical to the result + that would be obtained by computing (a**b) % modulo with + unbounded precision, but is computed more efficiently. It is + always exact. + + >>> c = ExtendedContext.copy() + >>> c.Emin = -999 + >>> c.Emax = 999 + >>> c.power(Decimal('2'), Decimal('3')) + Decimal('8') + >>> c.power(Decimal('-2'), Decimal('3')) + Decimal('-8') + >>> c.power(Decimal('2'), Decimal('-3')) + Decimal('0.125') + >>> c.power(Decimal('1.7'), Decimal('8')) + Decimal('69.7575744') + >>> c.power(Decimal('10'), Decimal('0.301029996')) + Decimal('2.00000000') + >>> c.power(Decimal('Infinity'), Decimal('-1')) + Decimal('0') + >>> c.power(Decimal('Infinity'), Decimal('0')) + Decimal('1') + >>> c.power(Decimal('Infinity'), Decimal('1')) + Decimal('Infinity') + >>> c.power(Decimal('-Infinity'), Decimal('-1')) + Decimal('-0') + >>> c.power(Decimal('-Infinity'), Decimal('0')) + Decimal('1') + >>> c.power(Decimal('-Infinity'), Decimal('1')) + Decimal('-Infinity') + >>> c.power(Decimal('-Infinity'), Decimal('2')) + Decimal('Infinity') + >>> c.power(Decimal('0'), Decimal('0')) + Decimal('NaN') + + >>> c.power(Decimal('3'), Decimal('7'), Decimal('16')) + Decimal('11') + >>> c.power(Decimal('-3'), Decimal('7'), Decimal('16')) + Decimal('-11') + >>> c.power(Decimal('-3'), Decimal('8'), Decimal('16')) + Decimal('1') + >>> c.power(Decimal('3'), Decimal('7'), Decimal('-16')) + Decimal('11') + >>> c.power(Decimal('23E12345'), Decimal('67E189'), Decimal('123456789')) + Decimal('11729830') + >>> c.power(Decimal('-0'), Decimal('17'), Decimal('1729')) + Decimal('-0') + >>> c.power(Decimal('-23'), Decimal('0'), Decimal('65537')) + Decimal('1') + >>> ExtendedContext.power(7, 7) + Decimal('823543') + >>> ExtendedContext.power(Decimal(7), 7) + Decimal('823543') + >>> ExtendedContext.power(7, Decimal(7), 2) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + r = a.__pow__(b, modulo, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def quantize(self, a, b): + """Returns a value equal to 'a' (rounded), having the exponent of 'b'. + + The coefficient of the result is derived from that of the left-hand + operand. It may be rounded using the current rounding setting (if the + exponent is being increased), multiplied by a positive power of ten (if + the exponent is being decreased), or is unchanged (if the exponent is + already equal to that of the right-hand operand). + + Unlike other operations, if the length of the coefficient after the + quantize operation would be greater than precision then an Invalid + operation condition is raised. This guarantees that, unless there is + an error condition, the exponent of the result of a quantize is always + equal to that of the right-hand operand. + + Also unlike other operations, quantize will never raise Underflow, even + if the result is subnormal and inexact. + + >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001')) + Decimal('2.170') + >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01')) + Decimal('2.17') + >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1')) + Decimal('2.2') + >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0')) + Decimal('2') + >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1')) + Decimal('0E+1') + >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity')) + Decimal('-Infinity') + >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity')) + Decimal('NaN') + >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1')) + Decimal('-0') + >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5')) + Decimal('-0E+5') + >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2')) + Decimal('NaN') + >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2')) + Decimal('NaN') + >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1')) + Decimal('217.0') + >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0')) + Decimal('217') + >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1')) + Decimal('2.2E+2') + >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2')) + Decimal('2E+2') + >>> ExtendedContext.quantize(1, 2) + Decimal('1') + >>> ExtendedContext.quantize(Decimal(1), 2) + Decimal('1') + >>> ExtendedContext.quantize(1, Decimal(2)) + Decimal('1') + """ + a = _convert_other(a, raiseit=True) + return a.quantize(b, context=self) + + def radix(self): + """Just returns 10, as this is Decimal, :) + + >>> ExtendedContext.radix() + Decimal('10') + """ + return Decimal(10) + + def remainder(self, a, b): + """Returns the remainder from integer division. + + The result is the residue of the dividend after the operation of + calculating integer division as described for divide-integer, rounded + to precision digits if necessary. The sign of the result, if + non-zero, is the same as that of the original dividend. + + This operation will fail under the same conditions as integer division + (that is, if integer division on the same two operands would fail, the + remainder cannot be calculated). + + >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3')) + Decimal('2.1') + >>> ExtendedContext.remainder(Decimal('10'), Decimal('3')) + Decimal('1') + >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3')) + Decimal('-1') + >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1')) + Decimal('0.2') + >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3')) + Decimal('0.1') + >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3')) + Decimal('1.0') + >>> ExtendedContext.remainder(22, 6) + Decimal('4') + >>> ExtendedContext.remainder(Decimal(22), 6) + Decimal('4') + >>> ExtendedContext.remainder(22, Decimal(6)) + Decimal('4') + """ + a = _convert_other(a, raiseit=True) + r = a.__mod__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def remainder_near(self, a, b): + """Returns to be "a - b * n", where n is the integer nearest the exact + value of "x / b" (if two integers are equally near then the even one + is chosen). If the result is equal to 0 then its sign will be the + sign of a. + + This operation will fail under the same conditions as integer division + (that is, if integer division on the same two operands would fail, the + remainder cannot be calculated). + + >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3')) + Decimal('-0.9') + >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6')) + Decimal('-2') + >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3')) + Decimal('1') + >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3')) + Decimal('-1') + >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1')) + Decimal('0.2') + >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3')) + Decimal('0.1') + >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3')) + Decimal('-0.3') + >>> ExtendedContext.remainder_near(3, 11) + Decimal('3') + >>> ExtendedContext.remainder_near(Decimal(3), 11) + Decimal('3') + >>> ExtendedContext.remainder_near(3, Decimal(11)) + Decimal('3') + """ + a = _convert_other(a, raiseit=True) + return a.remainder_near(b, context=self) + + def rotate(self, a, b): + """Returns a rotated copy of a, b times. + + The coefficient of the result is a rotated copy of the digits in + the coefficient of the first operand. The number of places of + rotation is taken from the absolute value of the second operand, + with the rotation being to the left if the second operand is + positive or to the right otherwise. + + >>> ExtendedContext.rotate(Decimal('34'), Decimal('8')) + Decimal('400000003') + >>> ExtendedContext.rotate(Decimal('12'), Decimal('9')) + Decimal('12') + >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('-2')) + Decimal('891234567') + >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('0')) + Decimal('123456789') + >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('+2')) + Decimal('345678912') + >>> ExtendedContext.rotate(1333333, 1) + Decimal('13333330') + >>> ExtendedContext.rotate(Decimal(1333333), 1) + Decimal('13333330') + >>> ExtendedContext.rotate(1333333, Decimal(1)) + Decimal('13333330') + """ + a = _convert_other(a, raiseit=True) + return a.rotate(b, context=self) + + def same_quantum(self, a, b): + """Returns True if the two operands have the same exponent. + + The result is never affected by either the sign or the coefficient of + either operand. + + >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001')) + False + >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01')) + True + >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1')) + False + >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf')) + True + >>> ExtendedContext.same_quantum(10000, -1) + True + >>> ExtendedContext.same_quantum(Decimal(10000), -1) + True + >>> ExtendedContext.same_quantum(10000, Decimal(-1)) + True + """ + a = _convert_other(a, raiseit=True) + return a.same_quantum(b) + + def scaleb (self, a, b): + """Returns the first operand after adding the second value its exp. + + >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('-2')) + Decimal('0.0750') + >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('0')) + Decimal('7.50') + >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('3')) + Decimal('7.50E+3') + >>> ExtendedContext.scaleb(1, 4) + Decimal('1E+4') + >>> ExtendedContext.scaleb(Decimal(1), 4) + Decimal('1E+4') + >>> ExtendedContext.scaleb(1, Decimal(4)) + Decimal('1E+4') + """ + a = _convert_other(a, raiseit=True) + return a.scaleb(b, context=self) + + def shift(self, a, b): + """Returns a shifted copy of a, b times. + + The coefficient of the result is a shifted copy of the digits + in the coefficient of the first operand. The number of places + to shift is taken from the absolute value of the second operand, + with the shift being to the left if the second operand is + positive or to the right otherwise. Digits shifted into the + coefficient are zeros. + + >>> ExtendedContext.shift(Decimal('34'), Decimal('8')) + Decimal('400000000') + >>> ExtendedContext.shift(Decimal('12'), Decimal('9')) + Decimal('0') + >>> ExtendedContext.shift(Decimal('123456789'), Decimal('-2')) + Decimal('1234567') + >>> ExtendedContext.shift(Decimal('123456789'), Decimal('0')) + Decimal('123456789') + >>> ExtendedContext.shift(Decimal('123456789'), Decimal('+2')) + Decimal('345678900') + >>> ExtendedContext.shift(88888888, 2) + Decimal('888888800') + >>> ExtendedContext.shift(Decimal(88888888), 2) + Decimal('888888800') + >>> ExtendedContext.shift(88888888, Decimal(2)) + Decimal('888888800') + """ + a = _convert_other(a, raiseit=True) + return a.shift(b, context=self) + + def sqrt(self, a): + """Square root of a non-negative number to context precision. + + If the result must be inexact, it is rounded using the round-half-even + algorithm. + + >>> ExtendedContext.sqrt(Decimal('0')) + Decimal('0') + >>> ExtendedContext.sqrt(Decimal('-0')) + Decimal('-0') + >>> ExtendedContext.sqrt(Decimal('0.39')) + Decimal('0.624499800') + >>> ExtendedContext.sqrt(Decimal('100')) + Decimal('10') + >>> ExtendedContext.sqrt(Decimal('1')) + Decimal('1') + >>> ExtendedContext.sqrt(Decimal('1.0')) + Decimal('1.0') + >>> ExtendedContext.sqrt(Decimal('1.00')) + Decimal('1.0') + >>> ExtendedContext.sqrt(Decimal('7')) + Decimal('2.64575131') + >>> ExtendedContext.sqrt(Decimal('10')) + Decimal('3.16227766') + >>> ExtendedContext.sqrt(2) + Decimal('1.41421356') + >>> ExtendedContext.prec + 9 + """ + a = _convert_other(a, raiseit=True) + return a.sqrt(context=self) + + def subtract(self, a, b): + """Return the difference between the two operands. + + >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07')) + Decimal('0.23') + >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30')) + Decimal('0.00') + >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07')) + Decimal('-0.77') + >>> ExtendedContext.subtract(8, 5) + Decimal('3') + >>> ExtendedContext.subtract(Decimal(8), 5) + Decimal('3') + >>> ExtendedContext.subtract(8, Decimal(5)) + Decimal('3') + """ + a = _convert_other(a, raiseit=True) + r = a.__sub__(b, context=self) + if r is NotImplemented: + raise TypeError("Unable to convert %s to Decimal" % b) + else: + return r + + def to_eng_string(self, a): + """Converts a number to a string, using scientific notation. + + The operation is not affected by the context. + """ + a = _convert_other(a, raiseit=True) + return a.to_eng_string(context=self) + + def to_sci_string(self, a): + """Converts a number to a string, using scientific notation. + + The operation is not affected by the context. + """ + a = _convert_other(a, raiseit=True) + return a.__str__(context=self) + + def to_integral_exact(self, a): + """Rounds to an integer. + + When the operand has a negative exponent, the result is the same + as using the quantize() operation using the given operand as the + left-hand-operand, 1E+0 as the right-hand-operand, and the precision + of the operand as the precision setting; Inexact and Rounded flags + are allowed in this operation. The rounding mode is taken from the + context. + + >>> ExtendedContext.to_integral_exact(Decimal('2.1')) + Decimal('2') + >>> ExtendedContext.to_integral_exact(Decimal('100')) + Decimal('100') + >>> ExtendedContext.to_integral_exact(Decimal('100.0')) + Decimal('100') + >>> ExtendedContext.to_integral_exact(Decimal('101.5')) + Decimal('102') + >>> ExtendedContext.to_integral_exact(Decimal('-101.5')) + Decimal('-102') + >>> ExtendedContext.to_integral_exact(Decimal('10E+5')) + Decimal('1.0E+6') + >>> ExtendedContext.to_integral_exact(Decimal('7.89E+77')) + Decimal('7.89E+77') + >>> ExtendedContext.to_integral_exact(Decimal('-Inf')) + Decimal('-Infinity') + """ + a = _convert_other(a, raiseit=True) + return a.to_integral_exact(context=self) + + def to_integral_value(self, a): + """Rounds to an integer. + + When the operand has a negative exponent, the result is the same + as using the quantize() operation using the given operand as the + left-hand-operand, 1E+0 as the right-hand-operand, and the precision + of the operand as the precision setting, except that no flags will + be set. The rounding mode is taken from the context. + + >>> ExtendedContext.to_integral_value(Decimal('2.1')) + Decimal('2') + >>> ExtendedContext.to_integral_value(Decimal('100')) + Decimal('100') + >>> ExtendedContext.to_integral_value(Decimal('100.0')) + Decimal('100') + >>> ExtendedContext.to_integral_value(Decimal('101.5')) + Decimal('102') + >>> ExtendedContext.to_integral_value(Decimal('-101.5')) + Decimal('-102') + >>> ExtendedContext.to_integral_value(Decimal('10E+5')) + Decimal('1.0E+6') + >>> ExtendedContext.to_integral_value(Decimal('7.89E+77')) + Decimal('7.89E+77') + >>> ExtendedContext.to_integral_value(Decimal('-Inf')) + Decimal('-Infinity') + """ + a = _convert_other(a, raiseit=True) + return a.to_integral_value(context=self) + + # the method name changed, but we provide also the old one, for compatibility + to_integral = to_integral_value + +class _WorkRep(object): + __slots__ = ('sign','int','exp') + # sign: 0 or 1 + # int: int + # exp: None, int, or string + + def __init__(self, value=None): + if value is None: + self.sign = None + self.int = 0 + self.exp = None + elif isinstance(value, Decimal): + self.sign = value._sign + self.int = int(value._int) + self.exp = value._exp + else: + # assert isinstance(value, tuple) + self.sign = value[0] + self.int = value[1] + self.exp = value[2] + + def __repr__(self): + return "(%r, %r, %r)" % (self.sign, self.int, self.exp) + + __str__ = __repr__ + + + +def _normalize(op1, op2, prec = 0): + """Normalizes op1, op2 to have the same exp and length of coefficient. + + Done during addition. + """ + if op1.exp < op2.exp: + tmp = op2 + other = op1 + else: + tmp = op1 + other = op2 + + # Let exp = min(tmp.exp - 1, tmp.adjusted() - precision - 1). + # Then adding 10**exp to tmp has the same effect (after rounding) + # as adding any positive quantity smaller than 10**exp; similarly + # for subtraction. So if other is smaller than 10**exp we replace + # it with 10**exp. This avoids tmp.exp - other.exp getting too large. + tmp_len = len(str(tmp.int)) + other_len = len(str(other.int)) + exp = tmp.exp + min(-1, tmp_len - prec - 2) + if other_len + other.exp - 1 < exp: + other.int = 1 + other.exp = exp + + tmp.int *= 10 ** (tmp.exp - other.exp) + tmp.exp = other.exp + return op1, op2 + +##### Integer arithmetic functions used by ln, log10, exp and __pow__ ##### + +_nbits = int.bit_length + +def _decimal_lshift_exact(n, e): + """ Given integers n and e, return n * 10**e if it's an integer, else None. + + The computation is designed to avoid computing large powers of 10 + unnecessarily. + + >>> _decimal_lshift_exact(3, 4) + 30000 + >>> _decimal_lshift_exact(300, -999999999) # returns None + + """ + if n == 0: + return 0 + elif e >= 0: + return n * 10**e + else: + # val_n = largest power of 10 dividing n. + str_n = str(abs(n)) + val_n = len(str_n) - len(str_n.rstrip('0')) + return None if val_n < -e else n // 10**-e + +def _sqrt_nearest(n, a): + """Closest integer to the square root of the positive integer n. a is + an initial approximation to the square root. Any positive integer + will do for a, but the closer a is to the square root of n the + faster convergence will be. + + """ + if n <= 0 or a <= 0: + raise ValueError("Both arguments to _sqrt_nearest should be positive.") + + b=0 + while a != b: + b, a = a, a--n//a>>1 + return a + +def _rshift_nearest(x, shift): + """Given an integer x and a nonnegative integer shift, return closest + integer to x / 2**shift; use round-to-even in case of a tie. + + """ + b, q = 1 << shift, x >> shift + return q + (2*(x & (b-1)) + (q&1) > b) + +def _div_nearest(a, b): + """Closest integer to a/b, a and b positive integers; rounds to even + in the case of a tie. + + """ + q, r = divmod(a, b) + return q + (2*r + (q&1) > b) + +def _ilog(x, M, L = 8): + """Integer approximation to M*log(x/M), with absolute error boundable + in terms only of x/M. + + Given positive integers x and M, return an integer approximation to + M * log(x/M). For L = 8 and 0.1 <= x/M <= 10 the difference + between the approximation and the exact result is at most 22. For + L = 8 and 1.0 <= x/M <= 10.0 the difference is at most 15. In + both cases these are upper bounds on the error; it will usually be + much smaller.""" + + # The basic algorithm is the following: let log1p be the function + # log1p(x) = log(1+x). Then log(x/M) = log1p((x-M)/M). We use + # the reduction + # + # log1p(y) = 2*log1p(y/(1+sqrt(1+y))) + # + # repeatedly until the argument to log1p is small (< 2**-L in + # absolute value). For small y we can use the Taylor series + # expansion + # + # log1p(y) ~ y - y**2/2 + y**3/3 - ... - (-y)**T/T + # + # truncating at T such that y**T is small enough. The whole + # computation is carried out in a form of fixed-point arithmetic, + # with a real number z being represented by an integer + # approximation to z*M. To avoid loss of precision, the y below + # is actually an integer approximation to 2**R*y*M, where R is the + # number of reductions performed so far. + + y = x-M + # argument reduction; R = number of reductions performed + R = 0 + while (R <= L and abs(y) << L-R >= M or + R > L and abs(y) >> R-L >= M): + y = _div_nearest((M*y) << 1, + M + _sqrt_nearest(M*(M+_rshift_nearest(y, R)), M)) + R += 1 + + # Taylor series with T terms + T = -int(-10*len(str(M))//(3*L)) + yshift = _rshift_nearest(y, R) + w = _div_nearest(M, T) + for k in range(T-1, 0, -1): + w = _div_nearest(M, k) - _div_nearest(yshift*w, M) + + return _div_nearest(w*y, M) + +def _dlog10(c, e, p): + """Given integers c, e and p with c > 0, p >= 0, compute an integer + approximation to 10**p * log10(c*10**e), with an absolute error of + at most 1. Assumes that c*10**e is not exactly 1.""" + + # increase precision by 2; compensate for this by dividing + # final result by 100 + p += 2 + + # write c*10**e as d*10**f with either: + # f >= 0 and 1 <= d <= 10, or + # f <= 0 and 0.1 <= d <= 1. + # Thus for c*10**e close to 1, f = 0 + l = len(str(c)) + f = e+l - (e+l >= 1) + + if p > 0: + M = 10**p + k = e+p-f + if k >= 0: + c *= 10**k + else: + c = _div_nearest(c, 10**-k) + + log_d = _ilog(c, M) # error < 5 + 22 = 27 + log_10 = _log10_digits(p) # error < 1 + log_d = _div_nearest(log_d*M, log_10) + log_tenpower = f*M # exact + else: + log_d = 0 # error < 2.31 + log_tenpower = _div_nearest(f, 10**-p) # error < 0.5 + + return _div_nearest(log_tenpower+log_d, 100) + +def _dlog(c, e, p): + """Given integers c, e and p with c > 0, compute an integer + approximation to 10**p * log(c*10**e), with an absolute error of + at most 1. Assumes that c*10**e is not exactly 1.""" + + # Increase precision by 2. The precision increase is compensated + # for at the end with a division by 100. + p += 2 + + # rewrite c*10**e as d*10**f with either f >= 0 and 1 <= d <= 10, + # or f <= 0 and 0.1 <= d <= 1. Then we can compute 10**p * log(c*10**e) + # as 10**p * log(d) + 10**p*f * log(10). + l = len(str(c)) + f = e+l - (e+l >= 1) + + # compute approximation to 10**p*log(d), with error < 27 + if p > 0: + k = e+p-f + if k >= 0: + c *= 10**k + else: + c = _div_nearest(c, 10**-k) # error of <= 0.5 in c + + # _ilog magnifies existing error in c by a factor of at most 10 + log_d = _ilog(c, 10**p) # error < 5 + 22 = 27 + else: + # p <= 0: just approximate the whole thing by 0; error < 2.31 + log_d = 0 + + # compute approximation to f*10**p*log(10), with error < 11. + if f: + extra = len(str(abs(f)))-1 + if p + extra >= 0: + # error in f * _log10_digits(p+extra) < |f| * 1 = |f| + # after division, error < |f|/10**extra + 0.5 < 10 + 0.5 < 11 + f_log_ten = _div_nearest(f*_log10_digits(p+extra), 10**extra) + else: + f_log_ten = 0 + else: + f_log_ten = 0 + + # error in sum < 11+27 = 38; error after division < 0.38 + 0.5 < 1 + return _div_nearest(f_log_ten + log_d, 100) + +class _Log10Memoize(object): + """Class to compute, store, and allow retrieval of, digits of the + constant log(10) = 2.302585.... This constant is needed by + Decimal.ln, Decimal.log10, Decimal.exp and Decimal.__pow__.""" + def __init__(self): + self.digits = "23025850929940456840179914546843642076011014886" + + def getdigits(self, p): + """Given an integer p >= 0, return floor(10**p)*log(10). + + For example, self.getdigits(3) returns 2302. + """ + # digits are stored as a string, for quick conversion to + # integer in the case that we've already computed enough + # digits; the stored digits should always be correct + # (truncated, not rounded to nearest). + if p < 0: + raise ValueError("p should be nonnegative") + + if p >= len(self.digits): + # compute p+3, p+6, p+9, ... digits; continue until at + # least one of the extra digits is nonzero + extra = 3 + while True: + # compute p+extra digits, correct to within 1ulp + M = 10**(p+extra+2) + digits = str(_div_nearest(_ilog(10*M, M), 100)) + if digits[-extra:] != '0'*extra: + break + extra += 3 + # keep all reliable digits so far; remove trailing zeros + # and next nonzero digit + self.digits = digits.rstrip('0')[:-1] + return int(self.digits[:p+1]) + +_log10_digits = _Log10Memoize().getdigits + +def _iexp(x, M, L=8): + """Given integers x and M, M > 0, such that x/M is small in absolute + value, compute an integer approximation to M*exp(x/M). For 0 <= + x/M <= 2.4, the absolute error in the result is bounded by 60 (and + is usually much smaller).""" + + # Algorithm: to compute exp(z) for a real number z, first divide z + # by a suitable power R of 2 so that |z/2**R| < 2**-L. Then + # compute expm1(z/2**R) = exp(z/2**R) - 1 using the usual Taylor + # series + # + # expm1(x) = x + x**2/2! + x**3/3! + ... + # + # Now use the identity + # + # expm1(2x) = expm1(x)*(expm1(x)+2) + # + # R times to compute the sequence expm1(z/2**R), + # expm1(z/2**(R-1)), ... , exp(z/2), exp(z). + + # Find R such that x/2**R/M <= 2**-L + R = _nbits((x<<L)//M) + + # Taylor series. (2**L)**T > M + T = -int(-10*len(str(M))//(3*L)) + y = _div_nearest(x, T) + Mshift = M<<R + for i in range(T-1, 0, -1): + y = _div_nearest(x*(Mshift + y), Mshift * i) + + # Expansion + for k in range(R-1, -1, -1): + Mshift = M<<(k+2) + y = _div_nearest(y*(y+Mshift), Mshift) + + return M+y + +def _dexp(c, e, p): + """Compute an approximation to exp(c*10**e), with p decimal places of + precision. + + Returns integers d, f such that: + + 10**(p-1) <= d <= 10**p, and + (d-1)*10**f < exp(c*10**e) < (d+1)*10**f + + In other words, d*10**f is an approximation to exp(c*10**e) with p + digits of precision, and with an error in d of at most 1. This is + almost, but not quite, the same as the error being < 1ulp: when d + = 10**(p-1) the error could be up to 10 ulp.""" + + # we'll call iexp with M = 10**(p+2), giving p+3 digits of precision + p += 2 + + # compute log(10) with extra precision = adjusted exponent of c*10**e + extra = max(0, e + len(str(c)) - 1) + q = p + extra + + # compute quotient c*10**e/(log(10)) = c*10**(e+q)/(log(10)*10**q), + # rounding down + shift = e+q + if shift >= 0: + cshift = c*10**shift + else: + cshift = c//10**-shift + quot, rem = divmod(cshift, _log10_digits(q)) + + # reduce remainder back to original precision + rem = _div_nearest(rem, 10**extra) + + # error in result of _iexp < 120; error after division < 0.62 + return _div_nearest(_iexp(rem, 10**p), 1000), quot - p + 3 + +def _dpower(xc, xe, yc, ye, p): + """Given integers xc, xe, yc and ye representing Decimals x = xc*10**xe and + y = yc*10**ye, compute x**y. Returns a pair of integers (c, e) such that: + + 10**(p-1) <= c <= 10**p, and + (c-1)*10**e < x**y < (c+1)*10**e + + in other words, c*10**e is an approximation to x**y with p digits + of precision, and with an error in c of at most 1. (This is + almost, but not quite, the same as the error being < 1ulp: when c + == 10**(p-1) we can only guarantee error < 10ulp.) + + We assume that: x is positive and not equal to 1, and y is nonzero. + """ + + # Find b such that 10**(b-1) <= |y| <= 10**b + b = len(str(abs(yc))) + ye + + # log(x) = lxc*10**(-p-b-1), to p+b+1 places after the decimal point + lxc = _dlog(xc, xe, p+b+1) + + # compute product y*log(x) = yc*lxc*10**(-p-b-1+ye) = pc*10**(-p-1) + shift = ye-b + if shift >= 0: + pc = lxc*yc*10**shift + else: + pc = _div_nearest(lxc*yc, 10**-shift) + + if pc == 0: + # we prefer a result that isn't exactly 1; this makes it + # easier to compute a correctly rounded result in __pow__ + if ((len(str(xc)) + xe >= 1) == (yc > 0)): # if x**y > 1: + coeff, exp = 10**(p-1)+1, 1-p + else: + coeff, exp = 10**p-1, -p + else: + coeff, exp = _dexp(pc, -(p+1), p+1) + coeff = _div_nearest(coeff, 10) + exp += 1 + + return coeff, exp + +def _log10_lb(c, correction = { + '1': 100, '2': 70, '3': 53, '4': 40, '5': 31, + '6': 23, '7': 16, '8': 10, '9': 5}): + """Compute a lower bound for 100*log10(c) for a positive integer c.""" + if c <= 0: + raise ValueError("The argument to _log10_lb should be nonnegative.") + str_c = str(c) + return 100*len(str_c) - correction[str_c[0]] + +##### Helper Functions #################################################### + +def _convert_other(other, raiseit=False, allow_float=False): + """Convert other to Decimal. + + Verifies that it's ok to use in an implicit construction. + If allow_float is true, allow conversion from float; this + is used in the comparison methods (__eq__ and friends). + + """ + if isinstance(other, Decimal): + return other + if isinstance(other, int): + return Decimal(other) + if allow_float and isinstance(other, float): + return Decimal.from_float(other) + + if raiseit: + raise TypeError("Unable to convert %s to Decimal" % other) + return NotImplemented + +def _convert_for_comparison(self, other, equality_op=False): + """Given a Decimal instance self and a Python object other, return + a pair (s, o) of Decimal instances such that "s op o" is + equivalent to "self op other" for any of the 6 comparison + operators "op". + + """ + if isinstance(other, Decimal): + return self, other + + # Comparison with a Rational instance (also includes integers): + # self op n/d <=> self*d op n (for n and d integers, d positive). + # A NaN or infinity can be left unchanged without affecting the + # comparison result. + if isinstance(other, _numbers.Rational): + if not self._is_special: + self = _dec_from_triple(self._sign, + str(int(self._int) * other.denominator), + self._exp) + return self, Decimal(other.numerator) + + # Comparisons with float and complex types. == and != comparisons + # with complex numbers should succeed, returning either True or False + # as appropriate. Other comparisons return NotImplemented. + if equality_op and isinstance(other, _numbers.Complex) and other.imag == 0: + other = other.real + if isinstance(other, float): + context = getcontext() + if equality_op: + context.flags[FloatOperation] = 1 + else: + context._raise_error(FloatOperation, + "strict semantics for mixing floats and Decimals are enabled") + return self, Decimal.from_float(other) + return NotImplemented, NotImplemented + + +##### Setup Specific Contexts ############################################ + +# The default context prototype used by Context() +# Is mutable, so that new contexts can have different default values + +DefaultContext = Context( + prec=28, rounding=ROUND_HALF_EVEN, + traps=[DivisionByZero, Overflow, InvalidOperation], + flags=[], + Emax=999999, + Emin=-999999, + capitals=1, + clamp=0 +) + +# Pre-made alternate contexts offered by the specification +# Don't change these; the user should be able to select these +# contexts and be able to reproduce results from other implementations +# of the spec. + +BasicContext = Context( + prec=9, rounding=ROUND_HALF_UP, + traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow], + flags=[], +) + +ExtendedContext = Context( + prec=9, rounding=ROUND_HALF_EVEN, + traps=[], + flags=[], +) + + +##### crud for parsing strings ############################################# +# +# Regular expression used for parsing numeric strings. Additional +# comments: +# +# 1. Uncomment the two '\s*' lines to allow leading and/or trailing +# whitespace. But note that the specification disallows whitespace in +# a numeric string. +# +# 2. For finite numbers (not infinities and NaNs) the body of the +# number between the optional sign and the optional exponent must have +# at least one decimal digit, possibly after the decimal point. The +# lookahead expression '(?=\d|\.\d)' checks this. + +import re +_parser = re.compile(r""" # A numeric string consists of: +# \s* + (?P<sign>[-+])? # an optional sign, followed by either... + ( + (?=\d|\.\d) # ...a number (with at least one digit) + (?P<int>\d*) # having a (possibly empty) integer part + (\.(?P<frac>\d*))? # followed by an optional fractional part + (E(?P<exp>[-+]?\d+))? # followed by an optional exponent, or... + | + Inf(inity)? # ...an infinity, or... + | + (?P<signal>s)? # ...an (optionally signaling) + NaN # NaN + (?P<diag>\d*) # with (possibly empty) diagnostic info. + ) +# \s* + \Z +""", re.VERBOSE | re.IGNORECASE).match + +_all_zeros = re.compile('0*$').match +_exact_half = re.compile('50*$').match + +##### PEP3101 support functions ############################################## +# The functions in this section have little to do with the Decimal +# class, and could potentially be reused or adapted for other pure +# Python numeric classes that want to implement __format__ +# +# A format specifier for Decimal looks like: +# +# [[fill]align][sign][#][0][minimumwidth][,][.precision][type] + +_parse_format_specifier_regex = re.compile(r"""\A +(?: + (?P<fill>.)? + (?P<align>[<>=^]) +)? +(?P<sign>[-+ ])? +(?P<alt>\#)? +(?P<zeropad>0)? +(?P<minimumwidth>(?!0)\d+)? +(?P<thousands_sep>,)? +(?:\.(?P<precision>0|(?!0)\d+))? +(?P<type>[eEfFgGn%])? +\Z +""", re.VERBOSE|re.DOTALL) + +del re + +# The locale module is only needed for the 'n' format specifier. The +# rest of the PEP 3101 code functions quite happily without it, so we +# don't care too much if locale isn't present. +try: + import locale as _locale +except ImportError: + pass + +def _parse_format_specifier(format_spec, _localeconv=None): + """Parse and validate a format specifier. + + Turns a standard numeric format specifier into a dict, with the + following entries: + + fill: fill character to pad field to minimum width + align: alignment type, either '<', '>', '=' or '^' + sign: either '+', '-' or ' ' + minimumwidth: nonnegative integer giving minimum width + zeropad: boolean, indicating whether to pad with zeros + thousands_sep: string to use as thousands separator, or '' + grouping: grouping for thousands separators, in format + used by localeconv + decimal_point: string to use for decimal point + precision: nonnegative integer giving precision, or None + type: one of the characters 'eEfFgG%', or None + + """ + m = _parse_format_specifier_regex.match(format_spec) + if m is None: + raise ValueError("Invalid format specifier: " + format_spec) + + # get the dictionary + format_dict = m.groupdict() + + # zeropad; defaults for fill and alignment. If zero padding + # is requested, the fill and align fields should be absent. + fill = format_dict['fill'] + align = format_dict['align'] + format_dict['zeropad'] = (format_dict['zeropad'] is not None) + if format_dict['zeropad']: + if fill is not None: + raise ValueError("Fill character conflicts with '0'" + " in format specifier: " + format_spec) + if align is not None: + raise ValueError("Alignment conflicts with '0' in " + "format specifier: " + format_spec) + format_dict['fill'] = fill or ' ' + # PEP 3101 originally specified that the default alignment should + # be left; it was later agreed that right-aligned makes more sense + # for numeric types. See http://bugs.python.org/issue6857. + format_dict['align'] = align or '>' + + # default sign handling: '-' for negative, '' for positive + if format_dict['sign'] is None: + format_dict['sign'] = '-' + + # minimumwidth defaults to 0; precision remains None if not given + format_dict['minimumwidth'] = int(format_dict['minimumwidth'] or '0') + if format_dict['precision'] is not None: + format_dict['precision'] = int(format_dict['precision']) + + # if format type is 'g' or 'G' then a precision of 0 makes little + # sense; convert it to 1. Same if format type is unspecified. + if format_dict['precision'] == 0: + if format_dict['type'] is None or format_dict['type'] in 'gGn': + format_dict['precision'] = 1 + + # determine thousands separator, grouping, and decimal separator, and + # add appropriate entries to format_dict + if format_dict['type'] == 'n': + # apart from separators, 'n' behaves just like 'g' + format_dict['type'] = 'g' + if _localeconv is None: + _localeconv = _locale.localeconv() + if format_dict['thousands_sep'] is not None: + raise ValueError("Explicit thousands separator conflicts with " + "'n' type in format specifier: " + format_spec) + format_dict['thousands_sep'] = _localeconv['thousands_sep'] + format_dict['grouping'] = _localeconv['grouping'] + format_dict['decimal_point'] = _localeconv['decimal_point'] + else: + if format_dict['thousands_sep'] is None: + format_dict['thousands_sep'] = '' + format_dict['grouping'] = [3, 0] + format_dict['decimal_point'] = '.' + + return format_dict + +def _format_align(sign, body, spec): + """Given an unpadded, non-aligned numeric string 'body' and sign + string 'sign', add padding and alignment conforming to the given + format specifier dictionary 'spec' (as produced by + parse_format_specifier). + + """ + # how much extra space do we have to play with? + minimumwidth = spec['minimumwidth'] + fill = spec['fill'] + padding = fill*(minimumwidth - len(sign) - len(body)) + + align = spec['align'] + if align == '<': + result = sign + body + padding + elif align == '>': + result = padding + sign + body + elif align == '=': + result = sign + padding + body + elif align == '^': + half = len(padding)//2 + result = padding[:half] + sign + body + padding[half:] + else: + raise ValueError('Unrecognised alignment field') + + return result + +def _group_lengths(grouping): + """Convert a localeconv-style grouping into a (possibly infinite) + iterable of integers representing group lengths. + + """ + # The result from localeconv()['grouping'], and the input to this + # function, should be a list of integers in one of the + # following three forms: + # + # (1) an empty list, or + # (2) nonempty list of positive integers + [0] + # (3) list of positive integers + [locale.CHAR_MAX], or + + from itertools import chain, repeat + if not grouping: + return [] + elif grouping[-1] == 0 and len(grouping) >= 2: + return chain(grouping[:-1], repeat(grouping[-2])) + elif grouping[-1] == _locale.CHAR_MAX: + return grouping[:-1] + else: + raise ValueError('unrecognised format for grouping') + +def _insert_thousands_sep(digits, spec, min_width=1): + """Insert thousands separators into a digit string. + + spec is a dictionary whose keys should include 'thousands_sep' and + 'grouping'; typically it's the result of parsing the format + specifier using _parse_format_specifier. + + The min_width keyword argument gives the minimum length of the + result, which will be padded on the left with zeros if necessary. + + If necessary, the zero padding adds an extra '0' on the left to + avoid a leading thousands separator. For example, inserting + commas every three digits in '123456', with min_width=8, gives + '0,123,456', even though that has length 9. + + """ + + sep = spec['thousands_sep'] + grouping = spec['grouping'] + + groups = [] + for l in _group_lengths(grouping): + if l <= 0: + raise ValueError("group length should be positive") + # max(..., 1) forces at least 1 digit to the left of a separator + l = min(max(len(digits), min_width, 1), l) + groups.append('0'*(l - len(digits)) + digits[-l:]) + digits = digits[:-l] + min_width -= l + if not digits and min_width <= 0: + break + min_width -= len(sep) + else: + l = max(len(digits), min_width, 1) + groups.append('0'*(l - len(digits)) + digits[-l:]) + return sep.join(reversed(groups)) + +def _format_sign(is_negative, spec): + """Determine sign character.""" + + if is_negative: + return '-' + elif spec['sign'] in ' +': + return spec['sign'] + else: + return '' + +def _format_number(is_negative, intpart, fracpart, exp, spec): + """Format a number, given the following data: + + is_negative: true if the number is negative, else false + intpart: string of digits that must appear before the decimal point + fracpart: string of digits that must come after the point + exp: exponent, as an integer + spec: dictionary resulting from parsing the format specifier + + This function uses the information in spec to: + insert separators (decimal separator and thousands separators) + format the sign + format the exponent + add trailing '%' for the '%' type + zero-pad if necessary + fill and align if necessary + """ + + sign = _format_sign(is_negative, spec) + + if fracpart or spec['alt']: + fracpart = spec['decimal_point'] + fracpart + + if exp != 0 or spec['type'] in 'eE': + echar = {'E': 'E', 'e': 'e', 'G': 'E', 'g': 'e'}[spec['type']] + fracpart += "{0}{1:+}".format(echar, exp) + if spec['type'] == '%': + fracpart += '%' + + if spec['zeropad']: + min_width = spec['minimumwidth'] - len(fracpart) - len(sign) + else: + min_width = 0 + intpart = _insert_thousands_sep(intpart, spec, min_width) + + return _format_align(sign, intpart+fracpart, spec) + + +##### Useful Constants (internal use only) ################################ + +# Reusable defaults +_Infinity = Decimal('Inf') +_NegativeInfinity = Decimal('-Inf') +_NaN = Decimal('NaN') +_Zero = Decimal(0) +_One = Decimal(1) +_NegativeOne = Decimal(-1) + +# _SignedInfinity[sign] is infinity w/ that sign +_SignedInfinity = (_Infinity, _NegativeInfinity) + +# Constants related to the hash implementation; hash(x) is based +# on the reduction of x modulo _PyHASH_MODULUS +_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) +del sys diff --git a/Lib/_pyio.py b/Lib/_pyio.py index d6eee79e016b..f4722561fb95 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -6,11 +6,18 @@ import abc import codecs import errno +import array +import stat +import sys # Import _thread instead of threading to reduce startup cost try: from _thread import allocate_lock as Lock except ImportError: from _dummy_thread import allocate_lock as Lock +if sys.platform in {'win32', 'cygwin'}: + from msvcrt import setmode as _setmode +else: + _setmode = None import io from io import (__all__, SEEK_SET, SEEK_CUR, SEEK_END) @@ -24,8 +31,8 @@ DEFAULT_BUFFER_SIZE = 8 * 1024 # bytes # NOTE: Base classes defined here are registered with the "official" ABCs -# defined in io.py. We don't use real inheritance though, because we don't -# want to inherit the C implementations. +# defined in io.py. We don't use real inheritance though, because we don't want +# to inherit the C implementations. # Rebind for compatibility BlockingIOError = BlockingIOError @@ -175,8 +182,8 @@ def open(file, mode="r", buffering=-1, encoding=None, errors=None, text = "t" in modes binary = "b" in modes if "U" in modes: - if creating or writing or appending: - raise ValueError("can't use U and writing mode at once") + if creating or writing or appending or updating: + raise ValueError("mode U cannot be combined with 'x', 'w', 'a', or '+'") import warnings warnings.warn("'U' mode is deprecated", DeprecationWarning, 2) @@ -200,38 +207,45 @@ def open(file, mode="r", buffering=-1, encoding=None, errors=None, (appending and "a" or "") + (updating and "+" or ""), closefd, opener=opener) - line_buffering = False - if buffering == 1 or buffering < 0 and raw.isatty(): - buffering = -1 - line_buffering = True - if buffering < 0: - buffering = DEFAULT_BUFFER_SIZE - try: - bs = os.fstat(raw.fileno()).st_blksize - except (OSError, AttributeError): - pass + result = raw + try: + line_buffering = False + if buffering == 1 or buffering < 0 and raw.isatty(): + buffering = -1 + line_buffering = True + if buffering < 0: + buffering = DEFAULT_BUFFER_SIZE + try: + bs = os.fstat(raw.fileno()).st_blksize + except (OSError, AttributeError): + pass + else: + if bs > 1: + buffering = bs + if buffering < 0: + raise ValueError("invalid buffering size") + if buffering == 0: + if binary: + return result + raise ValueError("can't have unbuffered text I/O") + if updating: + buffer = BufferedRandom(raw, buffering) + elif creating or writing or appending: + buffer = BufferedWriter(raw, buffering) + elif reading: + buffer = BufferedReader(raw, buffering) else: - if bs > 1: - buffering = bs - if buffering < 0: - raise ValueError("invalid buffering size") - if buffering == 0: + raise ValueError("unknown mode: %r" % mode) + result = buffer if binary: - return raw - raise ValueError("can't have unbuffered text I/O") - if updating: - buffer = BufferedRandom(raw, buffering) - elif creating or writing or appending: - buffer = BufferedWriter(raw, buffering) - elif reading: - buffer = BufferedReader(raw, buffering) - else: - raise ValueError("unknown mode: %r" % mode) - if binary: - return buffer - text = TextIOWrapper(buffer, encoding, errors, newline, line_buffering) - text.mode = mode - return text + return result + text = TextIOWrapper(buffer, encoding, errors, newline, line_buffering) + result = text + text.mode = mode + return result + except: + result.close() + raise class DocDescriptor: @@ -249,7 +263,7 @@ class OpenWrapper: Trick so that open won't become a bound method when stored as a class variable (as dbm.dumb does). - See initstdio() in Python/pythonrun.c. + See initstdio() in Python/pylifecycle.c. """ __doc__ = DocDescriptor() @@ -655,16 +669,33 @@ def readinto(self, b): Raises BlockingIOError if the underlying raw stream has no data at the moment. """ - # XXX This ought to work with anything that supports the buffer API - data = self.read(len(b)) + + return self._readinto(b, read1=False) + + def readinto1(self, b): + """Read up to len(b) bytes into *b*, using at most one system call + + Returns an int representing the number of bytes read (0 for EOF). + + Raises BlockingIOError if the underlying raw stream has no + data at the moment. + """ + + return self._readinto(b, read1=True) + + def _readinto(self, b, read1): + if not isinstance(b, memoryview): + b = memoryview(b) + b = b.cast('B') + + if read1: + data = self.read1(len(b)) + else: + data = self.read(len(b)) n = len(data) - try: - b[:n] = data - except TypeError as err: - import array - if not isinstance(b, array.array): - raise err - b[:n] = array.array('b', data) + + b[:n] = data + return n def write(self, b): @@ -783,13 +814,14 @@ def __getstate__(self): .format(self.__class__.__name__)) def __repr__(self): - clsname = self.__class__.__name__ + modname = self.__class__.__module__ + clsname = self.__class__.__qualname__ try: name = self.name - except AttributeError: - return "<_pyio.{0}>".format(clsname) + except Exception: + return "<{}.{}>".format(modname, clsname) else: - return "<_pyio.{0} name={1!r}>".format(clsname, name) + return "<{}.{} name={!r}>".format(modname, clsname, name) ### Lower-level APIs ### @@ -826,8 +858,14 @@ def getvalue(self): def getbuffer(self): """Return a readable and writable view of the buffer. """ + if self.closed: + raise ValueError("getbuffer on closed file") return memoryview(self._buffer) + def close(self): + self._buffer.clear() + super().close() + def read(self, size=None): if self.closed: raise ValueError("read from closed file") @@ -980,10 +1018,7 @@ def _read_unlocked(self, n=None): current_size = 0 while True: # Read until EOF or until read() would block. - try: - chunk = self.raw.read() - except InterruptedError: - continue + chunk = self.raw.read() if chunk in empty_values: nodata_val = chunk break @@ -1002,10 +1037,7 @@ def _read_unlocked(self, n=None): chunks = [buf[pos:]] wanted = max(self.buffer_size, n) while avail < n: - try: - chunk = self.raw.read(wanted) - except InterruptedError: - continue + chunk = self.raw.read(wanted) if chunk in empty_values: nodata_val = chunk break @@ -1034,12 +1066,7 @@ def _peek_unlocked(self, n=0): have = len(self._read_buf) - self._read_pos if have < want or have <= 0: to_read = self.buffer_size - have - while True: - try: - current = self.raw.read(to_read) - except InterruptedError: - continue - break + current = self.raw.read(to_read) if current: self._read_buf = self._read_buf[self._read_pos:] + current self._read_pos = 0 @@ -1058,6 +1085,58 @@ def read1(self, size): return self._read_unlocked( min(size, len(self._read_buf) - self._read_pos)) + # Implementing readinto() and readinto1() is not strictly necessary (we + # could rely on the base class that provides an implementation in terms of + # read() and read1()). We do it anyway to keep the _pyio implementation + # similar to the io implementation (which implements the methods for + # performance reasons). + def _readinto(self, buf, read1): + """Read data into *buf* with at most one system call.""" + + if len(buf) == 0: + return 0 + + # Need to create a memoryview object of type 'b', otherwise + # we may not be able to assign bytes to it, and slicing it + # would create a new object. + if not isinstance(buf, memoryview): + buf = memoryview(buf) + buf = buf.cast('B') + + written = 0 + with self._read_lock: + while written < len(buf): + + # First try to read from internal buffer + avail = min(len(self._read_buf) - self._read_pos, len(buf)) + if avail: + buf[written:written+avail] = \ + self._read_buf[self._read_pos:self._read_pos+avail] + self._read_pos += avail + written += avail + if written == len(buf): + break + + # If remaining space in callers buffer is larger than + # internal buffer, read directly into callers buffer + if len(buf) - written > self.buffer_size: + n = self.raw.readinto(buf[written:]) + if not n: + break # eof + written += n + + # Otherwise refill internal buffer - unless we're + # in read1 mode and already got some data + elif not (read1 and written): + if not self._peek_unlocked(1): + break # eof + + # In readinto1 mode, return as soon as we have some data + if read1 and written: + break + + return written + def tell(self): return _BufferedIOMixin.tell(self) - len(self._read_buf) + self._read_pos @@ -1136,8 +1215,6 @@ def _flush_unlocked(self): while self._write_buf: try: n = self.raw.write(self._write_buf) - except InterruptedError: - continue except BlockingIOError: raise RuntimeError("self.raw should implement RawIOBase: it " "should not raise BlockingIOError") @@ -1207,6 +1284,9 @@ def peek(self, size=0): def read1(self, size): return self.reader.read1(size) + def readinto1(self, b): + return self.reader.readinto1(b) + def readable(self): return self.reader.readable() @@ -1217,8 +1297,10 @@ def flush(self): return self.writer.flush() def close(self): - self.writer.close() - self.reader.close() + try: + self.writer.close() + finally: + self.reader.close() def isatty(self): return self.reader.isatty() or self.writer.isatty() @@ -1289,6 +1371,10 @@ def read1(self, size): self.flush() return BufferedReader.read1(self, size) + def readinto1(self, b): + self.flush() + return BufferedReader.readinto1(self, b) + def write(self, b): if self._read_buf: # Undo readahead @@ -1298,6 +1384,345 @@ def write(self, b): return BufferedWriter.write(self, b) +class FileIO(RawIOBase): + _fd = -1 + _created = False + _readable = False + _writable = False + _appending = False + _seekable = None + _closefd = True + + def __init__(self, file, mode='r', closefd=True, opener=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). + """ + if self._fd >= 0: + # Have to close the existing file first. + try: + if self._closefd: + os.close(self._fd) + finally: + self._fd = -1 + + if isinstance(file, float): + raise TypeError('integer argument expected, got float') + if isinstance(file, int): + fd = file + if fd < 0: + raise ValueError('negative file descriptor') + else: + fd = -1 + + if not isinstance(mode, str): + raise TypeError('invalid mode: %s' % (mode,)) + if not set(mode) <= set('xrwab+'): + raise ValueError('invalid mode: %s' % (mode,)) + if sum(c in 'rwax' for c in mode) != 1 or mode.count('+') > 1: + raise ValueError('Must have exactly one of create/read/write/append ' + 'mode and at most one plus') + + if 'x' in mode: + self._created = True + self._writable = True + flags = os.O_EXCL | os.O_CREAT + elif 'r' in mode: + self._readable = True + flags = 0 + elif 'w' in mode: + self._writable = True + flags = os.O_CREAT | os.O_TRUNC + elif 'a' in mode: + self._writable = True + self._appending = True + flags = os.O_APPEND | os.O_CREAT + + if '+' in mode: + self._readable = True + self._writable = True + + if self._readable and self._writable: + flags |= os.O_RDWR + elif self._readable: + flags |= os.O_RDONLY + else: + flags |= os.O_WRONLY + + flags |= getattr(os, 'O_BINARY', 0) + + noinherit_flag = (getattr(os, 'O_NOINHERIT', 0) or + getattr(os, 'O_CLOEXEC', 0)) + flags |= noinherit_flag + + owned_fd = None + try: + if fd < 0: + if not closefd: + raise ValueError('Cannot use closefd=False with file name') + if opener is None: + fd = os.open(file, flags, 0o666) + else: + fd = opener(file, flags) + if not isinstance(fd, int): + raise TypeError('expected integer from opener') + if fd < 0: + raise OSError('Negative file descriptor') + owned_fd = fd + if not noinherit_flag: + os.set_inheritable(fd, False) + + self._closefd = closefd + fdfstat = os.fstat(fd) + try: + if stat.S_ISDIR(fdfstat.st_mode): + raise IsADirectoryError(errno.EISDIR, + os.strerror(errno.EISDIR), file) + except AttributeError: + # Ignore the AttribueError if stat.S_ISDIR or errno.EISDIR + # don't exist. + pass + self._blksize = getattr(fdfstat, 'st_blksize', 0) + if self._blksize <= 1: + self._blksize = DEFAULT_BUFFER_SIZE + + if _setmode: + # don't translate newlines (\r\n <=> \n) + _setmode(fd, os.O_BINARY) + + self.name = file + if self._appending: + # For consistent behaviour, we explicitly seek to the + # end of file (otherwise, it might be done only on the + # first write()). + os.lseek(fd, 0, SEEK_END) + except: + if owned_fd is not None: + os.close(owned_fd) + raise + self._fd = fd + + def __del__(self): + if self._fd >= 0 and self._closefd and not self.closed: + import warnings + warnings.warn('unclosed file %r' % (self,), ResourceWarning, + stacklevel=2) + self.close() + + def __getstate__(self): + raise TypeError("cannot serialize '%s' object", self.__class__.__name__) + + def __repr__(self): + class_name = '%s.%s' % (self.__class__.__module__, + self.__class__.__qualname__) + if self.closed: + return '<%s [closed]>' % class_name + try: + name = self.name + except AttributeError: + return ('<%s fd=%d mode=%r closefd=%r>' % + (class_name, self._fd, self.mode, self._closefd)) + else: + return ('<%s name=%r mode=%r closefd=%r>' % + (class_name, name, self.mode, self._closefd)) + + def _checkReadable(self): + if not self._readable: + raise UnsupportedOperation('File not open for reading') + + def _checkWritable(self, msg=None): + if not self._writable: + raise UnsupportedOperation('File not open for writing') + + def read(self, size=None): + """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. + """ + self._checkClosed() + self._checkReadable() + if size is None or size < 0: + return self.readall() + try: + return os.read(self._fd, size) + except BlockingIOError: + return None + + def readall(self): + """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. + """ + self._checkClosed() + self._checkReadable() + bufsize = DEFAULT_BUFFER_SIZE + try: + pos = os.lseek(self._fd, 0, SEEK_CUR) + end = os.fstat(self._fd).st_size + if end >= pos: + bufsize = end - pos + 1 + except OSError: + pass + + result = bytearray() + while True: + if len(result) >= bufsize: + bufsize = len(result) + bufsize += max(bufsize, DEFAULT_BUFFER_SIZE) + n = bufsize - len(result) + try: + chunk = os.read(self._fd, n) + except BlockingIOError: + if result: + break + return None + if not chunk: # reached the end of the file + break + result += chunk + + return bytes(result) + + def readinto(self, b): + """Same as RawIOBase.readinto().""" + m = memoryview(b).cast('B') + data = self.read(len(m)) + n = len(data) + m[:n] = data + return n + + def write(self, b): + """Write bytes b to file, return number 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. + """ + self._checkClosed() + self._checkWritable() + try: + return os.write(self._fd, b) + except BlockingIOError: + return None + + def seek(self, pos, whence=SEEK_SET): + """Move to new 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. + """ + if isinstance(pos, float): + raise TypeError('an integer is required') + self._checkClosed() + return os.lseek(self._fd, pos, whence) + + def tell(self): + """tell() -> int. Current file position. + + Can raise OSError for non seekable files.""" + self._checkClosed() + return os.lseek(self._fd, 0, SEEK_CUR) + + def truncate(self, size=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 changed to the value of size. + """ + self._checkClosed() + self._checkWritable() + if size is None: + size = self.tell() + os.ftruncate(self._fd, size) + return size + + def close(self): + """Close the file. + + A closed file cannot be used for further I/O operations. close() may be + called more than once without error. + """ + if not self.closed: + try: + if self._closefd: + os.close(self._fd) + finally: + super().close() + + def seekable(self): + """True if file supports random-access.""" + self._checkClosed() + if self._seekable is None: + try: + self.tell() + except OSError: + self._seekable = False + else: + self._seekable = True + return self._seekable + + def readable(self): + """True if file was opened in a read mode.""" + self._checkClosed() + return self._readable + + def writable(self): + """True if file was opened in a write mode.""" + self._checkClosed() + return self._writable + + def fileno(self): + """Return the underlying file descriptor (an integer).""" + self._checkClosed() + return self._fd + + def isatty(self): + """True if the file is connected to a TTY device.""" + self._checkClosed() + return os.isatty(self._fd) + + @property + def closefd(self): + """True if the file descriptor will be closed by close().""" + return self._closefd + + @property + def mode(self): + """String giving the file mode""" + if self._created: + if self._readable: + return 'xb+' + else: + return 'xb' + elif self._appending: + if self._readable: + return 'ab+' + else: + return 'ab' + elif self._readable: + if self._writable: + return 'rb+' + else: + return 'rb' + else: + return 'wb' + + class TextIOBase(IOBase): """Base class for text I/O. @@ -1503,6 +1928,11 @@ def __init__(self, buffer, encoding=None, errors=None, newline=None, if not isinstance(encoding, str): raise ValueError("invalid encoding: %r" % encoding) + if not codecs.lookup(encoding)._is_text_encoding: + msg = ("%r is not a text encoding; " + "use codecs.open() to handle arbitrary codecs") + raise LookupError(msg % encoding) + if errors is None: errors = "strict" else: @@ -1546,16 +1976,17 @@ def __init__(self, buffer, encoding=None, errors=None, newline=None, # - "chars_..." for integer variables that count decoded characters def __repr__(self): - result = "<_pyio.TextIOWrapper" + result = "<{}.{}".format(self.__class__.__module__, + self.__class__.__qualname__) try: name = self.name - except AttributeError: + except Exception: pass else: result += " name={0!r}".format(name) try: mode = self.mode - except AttributeError: + except Exception: pass else: result += " mode={0!r}".format(mode) @@ -1845,6 +2276,19 @@ def detach(self): return buffer def seek(self, cookie, whence=0): + def _reset_encoder(position): + """Reset the encoder (merely useful for proper BOM handling)""" + try: + encoder = self._encoder or self._get_encoder() + except LookupError: + # Sometimes the encoder doesn't exist + pass + else: + if position != 0: + encoder.setstate(0) + else: + encoder.reset() + if self.closed: raise ValueError("tell on closed file") if not self._seekable: @@ -1865,6 +2309,7 @@ def seek(self, cookie, whence=0): self._snapshot = None if self._decoder: self._decoder.reset() + _reset_encoder(position) return position if whence != 0: raise ValueError("unsupported whence (%r)" % (whence,)) @@ -1902,17 +2347,7 @@ def seek(self, cookie, whence=0): raise OSError("can't restore logical file position") self._decoded_chars_used = chars_to_skip - # Finally, reset the encoder (merely useful for proper BOM handling) - try: - encoder = self._encoder or self._get_encoder() - except LookupError: - # Sometimes the encoder doesn't exist - pass - else: - if cookie != 0: - encoder.setstate(0) - else: - encoder.reset() + _reset_encoder(cookie) return cookie def read(self, size=None): @@ -2052,7 +2487,7 @@ class StringIO(TextIOWrapper): def __init__(self, initial_value="", newline="\n"): super(StringIO, self).__init__(BytesIO(), encoding="utf-8", - errors="strict", + errors="surrogatepass", newline=newline) # Issue #5645: make universal newlines semantics the same as in the # C version, even under Windows. @@ -2067,7 +2502,13 @@ def __init__(self, initial_value="", newline="\n"): def getvalue(self): self.flush() - return self.buffer.getvalue().decode(self._encoding, self._errors) + decoder = self._decoder or self._get_decoder() + old_state = decoder.getstate() + decoder.reset() + try: + return decoder.decode(self.buffer.getvalue(), final=True) + finally: + decoder.setstate(old_state) def __repr__(self): # TextIOWrapper tells the encoding in its repr. In StringIO, diff --git a/Lib/_sitebuiltins.py b/Lib/_sitebuiltins.py index 1f21358e2685..c29cf4bf8fe4 100644 --- a/Lib/_sitebuiltins.py +++ b/Lib/_sitebuiltins.py @@ -87,8 +87,12 @@ def __call__(self): class _Helper(object): """Define the builtin 'help'. - This is a wrapper around pydoc.help (with a twist). + This is a wrapper around pydoc.help that provides a helpful message + when 'help' is typed at the Python interactive prompt. + + Calling help() at the Python prompt starts an interactive help session. + Calling help(thing) prints help for the python object 'thing'. """ def __repr__(self): diff --git a/Lib/_strptime.py b/Lib/_strptime.py index d101c6de05db..fe5b046a3c94 100644 --- a/Lib/_strptime.py +++ b/Lib/_strptime.py @@ -14,7 +14,7 @@ import locale import calendar from re import compile as re_compile -from re import IGNORECASE, ASCII +from re import IGNORECASE from re import escape as re_escape from datetime import (date as datetime_date, timedelta as datetime_timedelta, @@ -167,9 +167,9 @@ def __calc_timezone(self): time.tzset() except AttributeError: pass - no_saving = frozenset(["utc", "gmt", time.tzname[0].lower()]) + no_saving = frozenset({"utc", "gmt", time.tzname[0].lower()}) if time.daylight: - has_saving = frozenset([time.tzname[1].lower()]) + has_saving = frozenset({time.tzname[1].lower()}) else: has_saving = frozenset() self.timezone = (no_saving, has_saving) @@ -195,12 +195,15 @@ def __init__(self, locale_time=None): 'f': r"(?P<f>[0-9]{1,6})", 'H': r"(?P<H>2[0-3]|[0-1]\d|\d)", 'I': r"(?P<I>1[0-2]|0[1-9]|[1-9])", + 'G': r"(?P<G>\d\d\d\d)", 'j': r"(?P<j>36[0-6]|3[0-5]\d|[1-2]\d\d|0[1-9]\d|00[1-9]|[1-9]\d|0[1-9]|[1-9])", 'm': r"(?P<m>1[0-2]|0[1-9]|[1-9])", 'M': r"(?P<M>[0-5]\d|\d)", 'S': r"(?P<S>6[0-1]|[0-5]\d|\d)", 'U': r"(?P<U>5[0-3]|[0-4]\d|\d)", 'w': r"(?P<w>[0-6])", + 'u': r"(?P<u>[1-7])", + 'V': r"(?P<V>5[0-3]|0[1-9]|[1-4]\d|\d)", # W is set below by using 'U' 'y': r"(?P<y>\d\d)", #XXX: Does 'Y' need to worry about having less or more than @@ -253,8 +256,8 @@ def pattern(self, format): # format directives (%m, etc.). regex_chars = re_compile(r"([\\.^$*+?\(\){}\[\]|])") format = regex_chars.sub(r"\\\1", format) - whitespace_replacement = re_compile('\s+') - format = whitespace_replacement.sub('\s+', format) + whitespace_replacement = re_compile(r'\s+') + format = whitespace_replacement.sub(r'\\s+', format) while '%' in format: directive_index = format.index('%')+1 processed_format = "%s%s%s" % (processed_format, @@ -295,6 +298,22 @@ def _calc_julian_from_U_or_W(year, week_of_year, day_of_week, week_starts_Mon): return 1 + days_to_week + day_of_week +def _calc_julian_from_V(iso_year, iso_week, iso_weekday): + """Calculate the Julian day based on the ISO 8601 year, week, and weekday. + ISO weeks start on Mondays, with week 01 being the week containing 4 Jan. + ISO week days range from 1 (Monday) to 7 (Sunday). + """ + correction = datetime_date(iso_year, 1, 4).isoweekday() + 3 + ordinal = (iso_week * 7) + iso_weekday - correction + # ordinal may be negative or 0 now, which means the date is in the previous + # calendar year + if ordinal < 1: + ordinal += datetime_date(iso_year, 1, 1).toordinal() + iso_year -= 1 + ordinal -= datetime_date(iso_year, 1, 1).toordinal() + return iso_year, ordinal + + def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"): """Return a 2-tuple consisting of a time struct and an int containing the number of microseconds based on the input string and the @@ -339,18 +358,18 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"): raise ValueError("unconverted data remains: %s" % data_string[found.end():]) - year = None + iso_year = year = None month = day = 1 hour = minute = second = fraction = 0 tz = -1 tzoffset = None # Default to -1 to signify that values not known; not critical to have, # though - week_of_year = -1 - week_of_year_start = -1 - # weekday and julian defaulted to -1 so as to signal need to calculate + iso_week = week_of_year = None + week_of_year_start = None + # weekday and julian defaulted to None so as to signal need to calculate # values - weekday = julian = -1 + weekday = julian = None found_dict = found.groupdict() for group_key in found_dict.keys(): # Directives not explicitly handled below: @@ -369,6 +388,8 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"): year += 1900 elif group_key == 'Y': year = int(found_dict['Y']) + elif group_key == 'G': + iso_year = int(found_dict['G']) elif group_key == 'm': month = int(found_dict['m']) elif group_key == 'B': @@ -414,6 +435,9 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"): weekday = 6 else: weekday -= 1 + elif group_key == 'u': + weekday = int(found_dict['u']) + weekday -= 1 elif group_key == 'j': julian = int(found_dict['j']) elif group_key in ('U', 'W'): @@ -424,6 +448,8 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"): else: # W starts week on Monday. week_of_year_start = 0 + elif group_key == 'V': + iso_week = int(found_dict['V']) elif group_key == 'z': z = found_dict['z'] tzoffset = int(z[1:3]) * 60 + int(z[3:5]) @@ -444,32 +470,61 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"): else: tz = value break + # Deal with the cases where ambiguities arize + # don't assume default values for ISO week/year + if year is None and iso_year is not None: + if iso_week is None or weekday is None: + raise ValueError("ISO year directive '%G' must be used with " + "the ISO week directive '%V' and a weekday " + "directive ('%A', '%a', '%w', or '%u').") + if julian is not None: + raise ValueError("Day of the year directive '%j' is not " + "compatible with ISO year directive '%G'. " + "Use '%Y' instead.") + elif week_of_year is None and iso_week is not None: + if weekday is None: + raise ValueError("ISO week directive '%V' must be used with " + "the ISO year directive '%G' and a weekday " + "directive ('%A', '%a', '%w', or '%u').") + else: + raise ValueError("ISO week directive '%V' is incompatible with " + "the year directive '%Y'. Use the ISO year '%G' " + "instead.") + leap_year_fix = False if year is None and month == 2 and day == 29: year = 1904 # 1904 is first leap year of 20th century leap_year_fix = True elif year is None: year = 1900 + + # If we know the week of the year and what day of that week, we can figure # out the Julian day of the year. - if julian == -1 and week_of_year != -1 and weekday != -1: - week_starts_Mon = True if week_of_year_start == 0 else False - julian = _calc_julian_from_U_or_W(year, week_of_year, weekday, - week_starts_Mon) - # Cannot pre-calculate datetime_date() since can change in Julian - # calculation and thus could have different value for the day of the week - # calculation. - if julian == -1: + if julian is None and weekday is not None: + if week_of_year is not None: + week_starts_Mon = True if week_of_year_start == 0 else False + julian = _calc_julian_from_U_or_W(year, week_of_year, weekday, + week_starts_Mon) + elif iso_year is not None and iso_week is not None: + year, julian = _calc_julian_from_V(iso_year, iso_week, weekday + 1) + + if julian is None: + # Cannot pre-calculate datetime_date() since can change in Julian + # calculation and thus could have different value for the day of + # the week calculation. # Need to add 1 to result since first day of the year is 1, not 0. julian = datetime_date(year, month, day).toordinal() - \ datetime_date(year, 1, 1).toordinal() + 1 - else: # Assume that if they bothered to include Julian day it will - # be accurate. - datetime_result = datetime_date.fromordinal((julian - 1) + datetime_date(year, 1, 1).toordinal()) + else: # Assume that if they bothered to include Julian day (or if it was + # calculated above with year/week/weekday) it will be accurate. + datetime_result = datetime_date.fromordinal( + (julian - 1) + + datetime_date(year, 1, 1).toordinal()) year = datetime_result.year month = datetime_result.month day = datetime_result.day - if weekday == -1: + if weekday is None: weekday = datetime_date(year, month, day).weekday() # Add timezone info tzname = found_dict.get("Z") diff --git a/Lib/_weakrefset.py b/Lib/_weakrefset.py index 6a98b88e3355..7f9923c6341a 100644 --- a/Lib/_weakrefset.py +++ b/Lib/_weakrefset.py @@ -60,6 +60,8 @@ def __iter__(self): for itemref in self.data: item = itemref() if item is not None: + # Caveat: the iterator will keep a strong reference to + # `item` until it is resumed or closed. yield item def __len__(self): diff --git a/Lib/abc.py b/Lib/abc.py index 264c60c428b4..1cbf96a61f23 100644 --- a/Lib/abc.py +++ b/Lib/abc.py @@ -168,7 +168,7 @@ def register(cls, subclass): def _dump_registry(cls, file=None): """Debug helper to print the ABC registry.""" - print("Class: %s.%s" % (cls.__module__, cls.__name__), file=file) + print("Class: %s.%s" % (cls.__module__, cls.__qualname__), file=file) print("Inv.counter: %s" % ABCMeta._abc_invalidation_counter, file=file) for name in sorted(cls.__dict__.keys()): if name.startswith("_abc_"): @@ -241,8 +241,8 @@ class ABC(metaclass=ABCMeta): def get_cache_token(): """Returns the current ABC cache token. - The token is an opaque integer identifying the current version of - the ABC cache for virtual subclasses. This number changes with - every call to ``register()`` on any ABC. + 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. """ return ABCMeta._abc_invalidation_counter diff --git a/Lib/aifc.py b/Lib/aifc.py index c1c8ea705570..692d0bfd272b 100644 --- a/Lib/aifc.py +++ b/Lib/aifc.py @@ -121,7 +121,7 @@ be patched up. It is best to first set all parameters, perhaps possibly the compression type, and then write audio frames using writeframesraw. -When all frames have been written, either call writeframes('') or +When all frames have been written, either call writeframes(b'') or close() to patch up the sizes in the header. Marks can be added anytime. If there are any marks, you must call close() after all frames have been written. @@ -257,6 +257,15 @@ def _write_float(f, x): _aifc_params = namedtuple('_aifc_params', 'nchannels sampwidth framerate nframes comptype compname') +_aifc_params.nchannels.__doc__ = 'Number of audio channels (1 for mono, 2 for stereo)' +_aifc_params.sampwidth.__doc__ = 'Sample width in bytes' +_aifc_params.framerate.__doc__ = 'Sampling frequency' +_aifc_params.nframes.__doc__ = 'Number of audio frames' +_aifc_params.comptype.__doc__ = 'Compression type ("NONE" for AIFF files)' +_aifc_params.compname.__doc__ = ("""\ +A human-readable version of the compression type +('not compressed' for AIFF files)""") + class Aifc_read: # Variables used in this class: @@ -356,7 +365,10 @@ def rewind(self): self._soundpos = 0 def close(self): - self._file.close() + file = self._file + if file is not None: + self._file = None + file.close() def tell(self): return self._soundpos @@ -790,7 +802,10 @@ def _write_header(self, initlength): self._datalength = (self._datalength + 3) // 4 if self._datalength & 1: self._datalength = self._datalength + 1 - self._form_length_pos = self._file.tell() + try: + self._form_length_pos = self._file.tell() + except (AttributeError, OSError): + self._form_length_pos = None commlength = self._write_form_length(self._datalength) if self._aifc: self._file.write(b'AIFC') @@ -802,7 +817,8 @@ def _write_header(self, initlength): self._file.write(b'COMM') _write_ulong(self._file, commlength) _write_short(self._file, self._nchannels) - self._nframes_pos = self._file.tell() + if self._form_length_pos is not None: + self._nframes_pos = self._file.tell() _write_ulong(self._file, self._nframes) if self._comptype in (b'ULAW', b'ulaw', b'ALAW', b'alaw', b'G722'): _write_short(self._file, 8) @@ -813,7 +829,8 @@ def _write_header(self, initlength): self._file.write(self._comptype) _write_string(self._file, self._compname) self._file.write(b'SSND') - self._ssnd_length_pos = self._file.tell() + if self._form_length_pos is not None: + self._ssnd_length_pos = self._file.tell() _write_ulong(self._file, self._datalength + 8) _write_ulong(self._file, 0) _write_ulong(self._file, 0) diff --git a/Lib/argparse.py b/Lib/argparse.py index 9520e0ea7c67..cc538415d234 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -118,10 +118,16 @@ class _AttributeHolder(object): def __repr__(self): type_name = type(self).__name__ arg_strings = [] + star_args = {} for arg in self._get_args(): arg_strings.append(repr(arg)) for name, value in self._get_kwargs(): - arg_strings.append('%s=%r' % (name, value)) + if name.isidentifier(): + arg_strings.append('%s=%r' % (name, value)) + else: + star_args[name] = value + if star_args: + arg_strings.append('**%s' % repr(star_args)) return '%s(%s)' % (type_name, ', '.join(arg_strings)) def _get_kwargs(self): @@ -165,6 +171,8 @@ def __init__(self, self._prog = prog self._indent_increment = indent_increment self._max_help_position = max_help_position + self._max_help_position = min(max_help_position, + max(width - 20, indent_increment * 2)) self._width = width self._current_indent = 0 @@ -336,7 +344,7 @@ def get_lines(parts, indent, prefix=None): else: line_len = len(indent) - 1 for part in parts: - if line_len + 1 + len(part) > text_width: + if line_len + 1 + len(part) > text_width and line: lines.append(indent + ' '.join(line)) line = [] line_len = len(indent) - 1 @@ -476,7 +484,7 @@ def _format_actions_usage(self, actions, groups): def _format_text(self, text): if '%(prog)' in text: text = text % dict(prog=self._prog) - text_width = self._width - self._current_indent + text_width = max(self._width - self._current_indent, 11) indent = ' ' * self._current_indent return self._fill_text(text, text_width, indent) + '\n\n' @@ -484,11 +492,11 @@ def _format_action(self, action): # determine the required width and the entry label help_position = min(self._action_max_length + 2, self._max_help_position) - help_width = self._width - help_position + help_width = max(self._width - help_position, 11) action_width = help_position - self._current_indent - 2 action_header = self._format_action_invocation(action) - # ho nelp; start on same line and add a final newline + # no help; start on same line and add a final newline if not action.help: tup = self._current_indent, '', action_header action_header = '%*s%s\n' % tup @@ -1120,7 +1128,14 @@ def __call__(self, parser, namespace, values, option_string=None): # parse all the remaining options into the namespace # store any unrecognized options on the object, so that the top # level parser can decide what to do with them - namespace, arg_strings = parser.parse_known_args(arg_strings, namespace) + + # In case this subparser defines new defaults, we parse them + # in a new namespace object and then update the original + # namespace for the relevant parts. + subnamespace, arg_strings = parser.parse_known_args(arg_strings, None) + for key, value in vars(subnamespace).items(): + setattr(namespace, key, value) + if arg_strings: vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, []) getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings) @@ -1196,11 +1211,10 @@ def __init__(self, **kwargs): setattr(self, name, kwargs[name]) def __eq__(self, other): + if not isinstance(other, Namespace): + return NotImplemented return vars(self) == vars(other) - def __ne__(self, other): - return not (self == other) - def __contains__(self, key): return key in self.__dict__ @@ -1582,6 +1596,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): - argument_default -- The default value for all arguments - conflict_handler -- String indicating how to handle conflicts - add_help -- Add a -h/-help option + - allow_abbrev -- Allow long options to be abbreviated unambiguously """ def __init__(self, @@ -1595,7 +1610,8 @@ def __init__(self, fromfile_prefix_chars=None, argument_default=None, conflict_handler='error', - add_help=True): + add_help=True, + allow_abbrev=True): superinit = super(ArgumentParser, self).__init__ superinit(description=description, @@ -1613,6 +1629,7 @@ def __init__(self, self.formatter_class = formatter_class self.fromfile_prefix_chars = fromfile_prefix_chars self.add_help = add_help + self.allow_abbrev = allow_abbrev add_group = self.add_argument_group self._positionals = add_group(_('positional arguments')) @@ -2090,23 +2107,24 @@ def _parse_optional(self, arg_string): action = self._option_string_actions[option_string] return action, option_string, explicit_arg - # search through all possible prefixes of the option string - # and all actions in the parser for possible interpretations - option_tuples = self._get_option_tuples(arg_string) - - # if multiple actions match, the option string was ambiguous - if len(option_tuples) > 1: - options = ', '.join([option_string - for action, option_string, explicit_arg in option_tuples]) - args = {'option': arg_string, 'matches': options} - msg = _('ambiguous option: %(option)s could match %(matches)s') - self.error(msg % args) - - # if exactly one action matched, this segmentation is good, - # so return the parsed action - elif len(option_tuples) == 1: - option_tuple, = option_tuples - return option_tuple + if self.allow_abbrev: + # search through all possible prefixes of the option string + # and all actions in the parser for possible interpretations + option_tuples = self._get_option_tuples(arg_string) + + # if multiple actions match, the option string was ambiguous + if len(option_tuples) > 1: + options = ', '.join([option_string + for action, option_string, explicit_arg in option_tuples]) + args = {'option': arg_string, 'matches': options} + msg = _('ambiguous option: %(option)s could match %(matches)s') + self.error(msg % args) + + # if exactly one action matched, this segmentation is good, + # so return the parsed action + elif len(option_tuples) == 1: + option_tuple, = option_tuples + return option_tuple # if it was not found as an option, but it looks like a negative # number, it was meant to be positional diff --git a/Lib/ast.py b/Lib/ast.py index 02c3b2867fa8..03c30f66e915 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -194,7 +194,7 @@ def get_docstring(node, clean=True): be found. If the node provided does not have docstrings a TypeError will be raised. """ - if not isinstance(node, (FunctionDef, ClassDef, Module)): + if not isinstance(node, (AsyncFunctionDef, FunctionDef, ClassDef, Module)): raise TypeError("%r can't have docstrings" % node.__class__.__name__) if node.body and isinstance(node.body[0], Expr) and \ isinstance(node.body[0].value, Str): diff --git a/Lib/asynchat.py b/Lib/asynchat.py index 0378fa70697a..f728d1b47053 100644 --- a/Lib/asynchat.py +++ b/Lib/asynchat.py @@ -45,27 +45,26 @@ method) up to the terminator, and then control will be returned to you - by calling your self.found_terminator() method. """ -import socket import asyncore from collections import deque -class async_chat (asyncore.dispatcher): +class async_chat(asyncore.dispatcher): """This is an abstract class. You must derive from this class, and add the two methods collect_incoming_data() and found_terminator()""" # these are overridable defaults - ac_in_buffer_size = 65536 - ac_out_buffer_size = 65536 + ac_in_buffer_size = 65536 + ac_out_buffer_size = 65536 # we don't want to enable the use of encoding by default, because that is a # sign of an application bug that we don't want to pass silently - use_encoding = 0 - encoding = 'latin-1' + use_encoding = 0 + encoding = 'latin-1' - def __init__ (self, sock=None, map=None): + def __init__(self, sock=None, map=None): # for string terminator matching self.ac_in_buffer = b'' @@ -77,7 +76,7 @@ def __init__ (self, sock=None, map=None): # we toss the use of the "simple producer" and replace it with # a pure deque, which the original fifo was a wrapping of self.producer_fifo = deque() - asyncore.dispatcher.__init__ (self, sock, map) + asyncore.dispatcher.__init__(self, sock, map) def collect_incoming_data(self, data): raise NotImplementedError("must be implemented in subclass") @@ -93,13 +92,18 @@ def _get_data(self): def found_terminator(self): raise NotImplementedError("must be implemented in subclass") - def set_terminator (self, term): - "Set the input delimiter. Can be a fixed string of any length, an integer, or None" + def set_terminator(self, term): + """Set the input delimiter. + + Can be a fixed string of any length, an integer, or None. + """ if isinstance(term, str) and self.use_encoding: term = bytes(term, self.encoding) + elif isinstance(term, int) and term < 0: + raise ValueError('the number of received bytes must be positive') self.terminator = term - def get_terminator (self): + def get_terminator(self): return self.terminator # grab some more data from the socket, @@ -107,10 +111,12 @@ def get_terminator (self): # check for the terminator, # if found, transition to the next state. - def handle_read (self): + def handle_read(self): try: - data = self.recv (self.ac_in_buffer_size) + data = self.recv(self.ac_in_buffer_size) + except BlockingIOError: + return except OSError as why: self.handle_error() return @@ -129,17 +135,17 @@ def handle_read (self): terminator = self.get_terminator() if not terminator: # no terminator, collect it all - self.collect_incoming_data (self.ac_in_buffer) + self.collect_incoming_data(self.ac_in_buffer) self.ac_in_buffer = b'' elif isinstance(terminator, int): # numeric terminator n = terminator if lb < n: - self.collect_incoming_data (self.ac_in_buffer) + self.collect_incoming_data(self.ac_in_buffer) self.ac_in_buffer = b'' self.terminator = self.terminator - lb else: - self.collect_incoming_data (self.ac_in_buffer[:n]) + self.collect_incoming_data(self.ac_in_buffer[:n]) self.ac_in_buffer = self.ac_in_buffer[n:] self.terminator = 0 self.found_terminator() @@ -156,32 +162,37 @@ def handle_read (self): if index != -1: # we found the terminator if index > 0: - # don't bother reporting the empty string (source of subtle bugs) - self.collect_incoming_data (self.ac_in_buffer[:index]) + # don't bother reporting the empty string + # (source of subtle bugs) + self.collect_incoming_data(self.ac_in_buffer[:index]) self.ac_in_buffer = self.ac_in_buffer[index+terminator_len:] - # This does the Right Thing if the terminator is changed here. + # This does the Right Thing if the terminator + # is changed here. self.found_terminator() else: # check for a prefix of the terminator - index = find_prefix_at_end (self.ac_in_buffer, terminator) + index = find_prefix_at_end(self.ac_in_buffer, terminator) if index: if index != lb: # we found a prefix, collect up to the prefix - self.collect_incoming_data (self.ac_in_buffer[:-index]) + self.collect_incoming_data(self.ac_in_buffer[:-index]) self.ac_in_buffer = self.ac_in_buffer[-index:] break else: # no prefix, collect it all - self.collect_incoming_data (self.ac_in_buffer) + self.collect_incoming_data(self.ac_in_buffer) self.ac_in_buffer = b'' - def handle_write (self): + def handle_write(self): self.initiate_send() - def handle_close (self): + def handle_close(self): self.close() - def push (self, data): + def push(self, data): + if not isinstance(data, (bytes, bytearray, memoryview)): + raise TypeError('data argument must be byte-ish (%r)', + type(data)) sabs = self.ac_out_buffer_size if len(data) > sabs: for i in range(0, len(data), sabs): @@ -190,11 +201,11 @@ def push (self, data): self.producer_fifo.append(data) self.initiate_send() - def push_with_producer (self, producer): + def push_with_producer(self, producer): self.producer_fifo.append(producer) self.initiate_send() - def readable (self): + def readable(self): "predicate for inclusion in the readable for select()" # cannot use the old predicate, it violates the claim of the # set_terminator method. @@ -202,11 +213,11 @@ def readable (self): # return (len(self.ac_in_buffer) <= self.ac_in_buffer_size) return 1 - def writable (self): + def writable(self): "predicate for inclusion in the writable for select()" return self.producer_fifo or (not self.connected) - def close_when_done (self): + def close_when_done(self): "automatically close this channel once the outgoing queue is empty" self.producer_fifo.append(None) @@ -217,10 +228,8 @@ def initiate_send(self): if not first: del self.producer_fifo[0] if first is None: - ## print("first is None") self.handle_close() return - ## print("first is not None") # handle classic producer behavior obs = self.ac_out_buffer_size @@ -252,20 +261,21 @@ def initiate_send(self): # we tried to send some actual data return - def discard_buffers (self): + def discard_buffers(self): # Emergencies only! self.ac_in_buffer = b'' del self.incoming[:] self.producer_fifo.clear() + class simple_producer: - def __init__ (self, data, buffer_size=512): + def __init__(self, data, buffer_size=512): self.data = data self.buffer_size = buffer_size - def more (self): - if len (self.data) > self.buffer_size: + def more(self): + if len(self.data) > self.buffer_size: result = self.data[:self.buffer_size] self.data = self.data[self.buffer_size:] return result @@ -274,38 +284,43 @@ def more (self): self.data = b'' return result + class fifo: - def __init__ (self, list=None): + def __init__(self, list=None): + import warnings + warnings.warn('fifo class will be removed in Python 3.6', + DeprecationWarning, stacklevel=2) if not list: self.list = deque() else: self.list = deque(list) - def __len__ (self): + def __len__(self): return len(self.list) - def is_empty (self): + def is_empty(self): return not self.list - def first (self): + def first(self): return self.list[0] - def push (self, data): + def push(self, data): self.list.append(data) - def pop (self): + def pop(self): if self.list: return (1, self.list.popleft()) else: return (0, None) + # Given 'haystack', see if any prefix of 'needle' is at its end. This # assumes an exact match has already been checked. Return the number of # characters matched. # for example: -# f_p_a_e ("qwerty\r", "\r\n") => 1 -# f_p_a_e ("qwertydkjf", "\r\n") => 0 -# f_p_a_e ("qwerty\r\n", "\r\n") => <undefined> +# f_p_a_e("qwerty\r", "\r\n") => 1 +# f_p_a_e("qwertydkjf", "\r\n") => 0 +# f_p_a_e("qwerty\r\n", "\r\n") => <undefined> # this could maybe be made faster with a computed regex? # [answer: no; circa Python-2.0, Jan 2001] @@ -314,7 +329,7 @@ def pop (self): # re: 12820/s # regex: 14035/s -def find_prefix_at_end (haystack, needle): +def find_prefix_at_end(haystack, needle): l = len(needle) - 1 while l and not haystack.endswith(needle[:l]): l -= 1 diff --git a/Lib/asyncio/__init__.py b/Lib/asyncio/__init__.py index 0d288d5a0202..011466b3e0dc 100644 --- a/Lib/asyncio/__init__.py +++ b/Lib/asyncio/__init__.py @@ -18,24 +18,33 @@ import _overlapped # Will also be exported. # This relies on each of the submodules having an __all__ variable. -from .futures import * +from .base_events import * +from .coroutines import * from .events import * +from .futures import * from .locks import * -from .transports import * from .protocols import * +from .queues import * from .streams import * +from .subprocess import * from .tasks import * +from .transports import * -if sys.platform == 'win32': # pragma: no cover - from .windows_events import * -else: - from .unix_events import * # pragma: no cover - - -__all__ = (futures.__all__ + +__all__ = (base_events.__all__ + + coroutines.__all__ + events.__all__ + + futures.__all__ + locks.__all__ + - transports.__all__ + protocols.__all__ + + queues.__all__ + streams.__all__ + - tasks.__all__) + subprocess.__all__ + + tasks.__all__ + + transports.__all__) + +if sys.platform == 'win32': # pragma: no cover + from .windows_events import * + __all__ += windows_events.__all__ +else: + from .unix_events import * # pragma: no cover + __all__ += unix_events.__all__ diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index f2d117bdbd2a..af9c8811bb41 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -1,7 +1,7 @@ """Base implementation of event loop. The event loop can be broken up into a multiplexer (the part -responsible for notifying us of IO events) and the event loop proper, +responsible for notifying us of I/O events) and the event loop proper, which wraps a multiplexer with functionality for scheduling callbacks, immediately or at a given time in the future. @@ -17,99 +17,241 @@ import collections import concurrent.futures import heapq +import inspect +import itertools import logging +import os import socket import subprocess +import threading import time -import os +import traceback import sys +import warnings +from . import compat +from . import coroutines from . import events from . import futures from . import tasks +from .coroutines import coroutine from .log import logger -__all__ = ['BaseEventLoop', 'Server'] +__all__ = ['BaseEventLoop'] # Argument for default thread pool executor creation. _MAX_WORKERS = 5 +# Minimum number of _scheduled timer handles before cleanup of +# cancelled handles is performed. +_MIN_SCHEDULED_TIMER_HANDLES = 100 + +# Minimum fraction of _scheduled timer handles that are cancelled +# before cleanup of cancelled handles is performed. +_MIN_CANCELLED_TIMER_HANDLES_FRACTION = 0.5 + +def _format_handle(handle): + cb = handle._callback + if inspect.ismethod(cb) and isinstance(cb.__self__, tasks.Task): + # format the task + return repr(cb.__self__) + else: + return str(handle) + + +def _format_pipe(fd): + if fd == subprocess.PIPE: + return '<pipe>' + elif fd == subprocess.STDOUT: + return '<stdout>' + else: + return repr(fd) + class _StopError(BaseException): """Raised to stop the event loop.""" +def _check_resolved_address(sock, address): + # Ensure that the address is already resolved to avoid the trap of hanging + # the entire event loop when the address requires doing a DNS lookup. + # + # getaddrinfo() is slow (around 10 us per call): this function should only + # be called in debug mode + family = sock.family + + if family == socket.AF_INET: + host, port = address + elif family == socket.AF_INET6: + host, port = address[:2] + else: + return + + # On Windows, socket.inet_pton() is only available since Python 3.4 + if hasattr(socket, 'inet_pton'): + # getaddrinfo() is slow and has known issue: prefer inet_pton() + # if available + try: + socket.inet_pton(family, host) + except OSError as exc: + raise ValueError("address must be resolved (IP address), " + "got host %r: %s" + % (host, exc)) + else: + # Use getaddrinfo(flags=AI_NUMERICHOST) to ensure that the address is + # already resolved. + type_mask = 0 + if hasattr(socket, 'SOCK_NONBLOCK'): + type_mask |= socket.SOCK_NONBLOCK + if hasattr(socket, 'SOCK_CLOEXEC'): + type_mask |= socket.SOCK_CLOEXEC + try: + socket.getaddrinfo(host, port, + family=family, + type=(sock.type & ~type_mask), + proto=sock.proto, + flags=socket.AI_NUMERICHOST) + except socket.gaierror as err: + raise ValueError("address must be resolved (IP address), " + "got host %r: %s" + % (host, err)) + def _raise_stop_error(*args): raise _StopError +def _run_until_complete_cb(fut): + exc = fut._exception + if (isinstance(exc, BaseException) + and not isinstance(exc, Exception)): + # Issue #22429: run_forever() already finished, no need to + # stop it. + return + _raise_stop_error() + + class Server(events.AbstractServer): def __init__(self, loop, sockets): - self.loop = loop + self._loop = loop self.sockets = sockets - self.active_count = 0 - self.waiters = [] + self._active_count = 0 + self._waiters = [] + + def __repr__(self): + return '<%s sockets=%r>' % (self.__class__.__name__, self.sockets) - def attach(self, transport): + def _attach(self): assert self.sockets is not None - self.active_count += 1 + self._active_count += 1 - def detach(self, transport): - assert self.active_count > 0 - self.active_count -= 1 - if self.active_count == 0 and self.sockets is None: + def _detach(self): + assert self._active_count > 0 + self._active_count -= 1 + if self._active_count == 0 and self.sockets is None: self._wakeup() def close(self): sockets = self.sockets - if sockets is not None: - self.sockets = None - for sock in sockets: - self.loop._stop_serving(sock) - if self.active_count == 0: - self._wakeup() + if sockets is None: + return + self.sockets = None + for sock in sockets: + self._loop._stop_serving(sock) + if self._active_count == 0: + self._wakeup() def _wakeup(self): - waiters = self.waiters - self.waiters = None + waiters = self._waiters + self._waiters = None for waiter in waiters: if not waiter.done(): waiter.set_result(waiter) - @tasks.coroutine + @coroutine def wait_closed(self): - if self.sockets is None or self.waiters is None: + if self.sockets is None or self._waiters is None: return - waiter = futures.Future(loop=self.loop) - self.waiters.append(waiter) + waiter = futures.Future(loop=self._loop) + self._waiters.append(waiter) yield from waiter class BaseEventLoop(events.AbstractEventLoop): def __init__(self): + self._timer_cancelled_count = 0 + self._closed = False self._ready = collections.deque() self._scheduled = [] self._default_executor = None self._internal_fds = 0 - self._running = False + # Identifier of the thread running the event loop, or None if the + # event loop is not running + self._thread_id = None + self._clock_resolution = time.get_clock_info('monotonic').resolution + self._exception_handler = None + self.set_debug((not sys.flags.ignore_environment + and bool(os.environ.get('PYTHONASYNCIODEBUG')))) + # In debug mode, if the execution of a callback or a step of a task + # exceed this duration in seconds, the slow callback/task is logged. + self.slow_callback_duration = 0.1 + self._current_handle = None + self._task_factory = None + self._coroutine_wrapper_set = False + + def __repr__(self): + return ('<%s running=%s closed=%s debug=%s>' + % (self.__class__.__name__, self.is_running(), + self.is_closed(), self.get_debug())) + + def create_task(self, coro): + """Schedule a coroutine object. + + Return a task object. + """ + self._check_closed() + if self._task_factory is None: + task = tasks.Task(coro, loop=self) + if task._source_traceback: + del task._source_traceback[-1] + else: + task = self._task_factory(self, coro) + return task + + def set_task_factory(self, factory): + """Set a task factory that will be used by loop.create_task(). + + If factory is None the default task factory will be set. + + If factory is a callable, it should have a signature matching + '(loop, coro)', where 'loop' will be a reference to the active + event loop, 'coro' will be a coroutine object. The callable + must return a Future. + """ + if factory is not None and not callable(factory): + raise TypeError('task factory must be a callable or None') + self._task_factory = factory + + def get_task_factory(self): + """Return a task factory, or None if the default one is in use.""" + return self._task_factory def _make_socket_transport(self, sock, protocol, waiter=None, *, extra=None, server=None): """Create socket transport.""" raise NotImplementedError - def _make_ssl_transport(self, rawsock, protocol, sslcontext, waiter, *, - server_side=False, server_hostname=None, + def _make_ssl_transport(self, rawsock, protocol, sslcontext, waiter=None, + *, server_side=False, server_hostname=None, extra=None, server=None): """Create SSL transport.""" raise NotImplementedError def _make_datagram_transport(self, sock, protocol, - address=None, extra=None): + address=None, waiter=None, extra=None): """Create datagram transport.""" raise NotImplementedError @@ -123,30 +265,37 @@ def _make_write_pipe_transport(self, pipe, protocol, waiter=None, """Create write pipe transport.""" raise NotImplementedError - @tasks.coroutine + @coroutine def _make_subprocess_transport(self, protocol, args, shell, stdin, stdout, stderr, bufsize, extra=None, **kwargs): """Create subprocess transport.""" raise NotImplementedError - def _read_from_self(self): - """XXX""" - raise NotImplementedError - def _write_to_self(self): - """XXX""" + """Write a byte to self-pipe, to wake up the event loop. + + This may be called from a different thread. + + The subclass is responsible for implementing the self-pipe. + """ raise NotImplementedError def _process_events(self, event_list): """Process selector events.""" raise NotImplementedError + def _check_closed(self): + if self._closed: + raise RuntimeError('Event loop is closed') + def run_forever(self): """Run until stop() is called.""" - if self._running: + self._check_closed() + if self.is_running(): raise RuntimeError('Event loop is running.') - self._running = True + self._set_coroutine_wrapper(self._debug) + self._thread_id = threading.get_ident() try: while True: try: @@ -154,23 +303,40 @@ def run_forever(self): except _StopError: break finally: - self._running = False + self._thread_id = None + self._set_coroutine_wrapper(False) def run_until_complete(self, future): """Run until the Future is done. If the argument is a coroutine, it is wrapped in a Task. - XXX TBD: It would be disastrous to call run_until_complete() + WARNING: It would be disastrous to call run_until_complete() with the same coroutine twice -- it would wrap it in two different Tasks and that can't be good. Return the Future's result, or raise its exception. """ - future = tasks.async(future, loop=self) - future.add_done_callback(_raise_stop_error) - self.run_forever() - future.remove_done_callback(_raise_stop_error) + self._check_closed() + + new_task = not isinstance(future, futures.Future) + future = tasks.ensure_future(future, loop=self) + if new_task: + # An exception is raised if the future didn't complete, so there + # is no need to log the "destroy pending task" message + future._log_destroy_pending = False + + future.add_done_callback(_run_until_complete_cb) + try: + self.run_forever() + except: + if new_task and future.done() and not future.cancelled(): + # The coroutine raised a BaseException. Consume the exception + # to not log a warning, the caller doesn't have access to the + # local task. + future.exception() + raise + future.remove_done_callback(_run_until_complete_cb) if not future.done(): raise RuntimeError('Event loop stopped before Future completed.') @@ -179,9 +345,9 @@ def run_until_complete(self, future): def stop(self): """Stop running the event loop. - Every callback scheduled before stop() is called will run. - Callback scheduled after stop() is called won't. However, - those callbacks will run if run() is called again later. + Every callback scheduled before stop() is called will run. Callbacks + scheduled after stop() is called will not run. However, those callbacks + will run if run_forever is called again later. """ self.call_soon(_raise_stop_error) @@ -190,7 +356,16 @@ def close(self): This clears the queues and shuts down the executor, but does not wait for the executor to finish. + + The event loop must not be running. """ + if self.is_running(): + raise RuntimeError("Cannot close a running event loop") + if self._closed: + return + if self._debug: + logger.debug("Close %r", self) + self._closed = True self._ready.clear() self._scheduled.clear() executor = self._default_executor @@ -198,12 +373,31 @@ def close(self): self._default_executor = None executor.shutdown(wait=False) + def is_closed(self): + """Returns True if the event loop was closed.""" + return self._closed + + # On Python 3.3 and older, objects with a destructor part of a reference + # cycle are never destroyed. It's not more the case on Python 3.4 thanks + # to the PEP 442. + if compat.PY34: + def __del__(self): + if not self.is_closed(): + warnings.warn("unclosed event loop %r" % self, ResourceWarning) + if not self.is_running(): + self.close() + def is_running(self): - """Returns running status of event loop.""" - return self._running + """Returns True if the event loop is running.""" + return (self._thread_id is not None) def time(self): - """Return the time according to the event loop's clock.""" + """Return the time according to the event loop's clock. + + This is a float expressed in seconds since an epoch, but the + epoch, precision, accuracy and drift are unspecified and may + differ per event loop. + """ return time.monotonic() def call_later(self, delay, callback, *args): @@ -213,7 +407,7 @@ def call_later(self, delay, callback, *args): can be used to cancel the call. The delay can be an int or float, expressed in seconds. It is - always a relative time. + always relative to the current time. Each callback will be called exactly once. If two callbacks are scheduled for exactly the same time, it undefined which @@ -222,66 +416,157 @@ def call_later(self, delay, callback, *args): Any positional arguments after the callback will be passed to the callback when it is called. """ - return self.call_at(self.time() + delay, callback, *args) + timer = self.call_at(self.time() + delay, callback, *args) + if timer._source_traceback: + del timer._source_traceback[-1] + return timer def call_at(self, when, callback, *args): - """Like call_later(), but uses an absolute time.""" - timer = events.TimerHandle(when, callback, args) + """Like call_later(), but uses an absolute time. + + Absolute time corresponds to the event loop's time() method. + """ + if (coroutines.iscoroutine(callback) + or coroutines.iscoroutinefunction(callback)): + raise TypeError("coroutines cannot be used with call_at()") + self._check_closed() + if self._debug: + self._check_thread() + timer = events.TimerHandle(when, callback, args, self) + if timer._source_traceback: + del timer._source_traceback[-1] heapq.heappush(self._scheduled, timer) + timer._scheduled = True return timer def call_soon(self, callback, *args): """Arrange for a callback to be called as soon as possible. - This operates as a FIFO queue, callbacks are called in the + This operates as a FIFO queue: callbacks are called in the order in which they are registered. Each callback will be called exactly once. Any positional arguments after the callback will be passed to the callback when it is called. """ - handle = events.make_handle(callback, args) + if self._debug: + self._check_thread() + handle = self._call_soon(callback, args) + if handle._source_traceback: + del handle._source_traceback[-1] + return handle + + def _call_soon(self, callback, args): + if (coroutines.iscoroutine(callback) + or coroutines.iscoroutinefunction(callback)): + raise TypeError("coroutines cannot be used with call_soon()") + self._check_closed() + handle = events.Handle(callback, args, self) + if handle._source_traceback: + del handle._source_traceback[-1] self._ready.append(handle) return handle + def _check_thread(self): + """Check that the current thread is the thread running the event loop. + + Non-thread-safe methods of this class make this assumption and will + likely behave incorrectly when the assumption is violated. + + Should only be called when (self._debug == True). The caller is + responsible for checking this condition for performance reasons. + """ + if self._thread_id is None: + return + thread_id = threading.get_ident() + if thread_id != self._thread_id: + raise RuntimeError( + "Non-thread-safe operation invoked on an event loop other " + "than the current one") + def call_soon_threadsafe(self, callback, *args): - """XXX""" - handle = self.call_soon(callback, *args) + """Like call_soon(), but thread-safe.""" + handle = self._call_soon(callback, args) + if handle._source_traceback: + del handle._source_traceback[-1] self._write_to_self() return handle - def run_in_executor(self, executor, callback, *args): - if isinstance(callback, events.Handle): + def run_in_executor(self, executor, func, *args): + if (coroutines.iscoroutine(func) + or coroutines.iscoroutinefunction(func)): + raise TypeError("coroutines cannot be used with run_in_executor()") + self._check_closed() + if isinstance(func, events.Handle): assert not args - assert not isinstance(callback, events.TimerHandle) - if callback._cancelled: + assert not isinstance(func, events.TimerHandle) + if func._cancelled: f = futures.Future(loop=self) f.set_result(None) return f - callback, args = callback._callback, callback._args + func, args = func._callback, func._args if executor is None: executor = self._default_executor if executor is None: executor = concurrent.futures.ThreadPoolExecutor(_MAX_WORKERS) self._default_executor = executor - return futures.wrap_future(executor.submit(callback, *args), loop=self) + return futures.wrap_future(executor.submit(func, *args), loop=self) def set_default_executor(self, executor): self._default_executor = executor + def _getaddrinfo_debug(self, host, port, family, type, proto, flags): + msg = ["%s:%r" % (host, port)] + if family: + msg.append('family=%r' % family) + if type: + msg.append('type=%r' % type) + if proto: + msg.append('proto=%r' % proto) + if flags: + msg.append('flags=%r' % flags) + msg = ', '.join(msg) + logger.debug('Get address info %s', msg) + + t0 = self.time() + addrinfo = socket.getaddrinfo(host, port, family, type, proto, flags) + dt = self.time() - t0 + + msg = ('Getting address info %s took %.3f ms: %r' + % (msg, dt * 1e3, addrinfo)) + if dt >= self.slow_callback_duration: + logger.info(msg) + else: + logger.debug(msg) + return addrinfo + def getaddrinfo(self, host, port, *, family=0, type=0, proto=0, flags=0): - return self.run_in_executor(None, socket.getaddrinfo, - host, port, family, type, proto, flags) + if self._debug: + return self.run_in_executor(None, self._getaddrinfo_debug, + host, port, family, type, proto, flags) + else: + return self.run_in_executor(None, socket.getaddrinfo, + host, port, family, type, proto, flags) def getnameinfo(self, sockaddr, flags=0): return self.run_in_executor(None, socket.getnameinfo, sockaddr, flags) - @tasks.coroutine + @coroutine def create_connection(self, protocol_factory, host=None, port=None, *, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None): - """XXX""" + """Connect to a TCP server. + + Create a streaming transport connection to a given Internet host and + port: socket family AF_INET or socket.AF_INET6 depending on host (or + family if specified), socket type SOCK_STREAM. protocol_factory must be + a callable returning a protocol instance. + + This method is a coroutine which will try to establish the connection + in the background. When successful, the coroutine returns a + (transport, protocol) pair. + """ if server_hostname is not None and not ssl: raise ValueError('server_hostname is only meaningful with ssl') @@ -349,11 +634,17 @@ def create_connection(self, protocol_factory, host=None, port=None, *, sock.close() sock = None continue + if self._debug: + logger.debug("connect %r to %r", sock, address) yield from self.sock_connect(sock, address) except OSError as exc: if sock is not None: sock.close() exceptions.append(exc) + except: + if sock is not None: + sock.close() + raise else: break else: @@ -375,6 +666,19 @@ def create_connection(self, protocol_factory, host=None, port=None, *, sock.setblocking(False) + transport, protocol = yield from self._create_connection_transport( + sock, protocol_factory, ssl, server_hostname) + if self._debug: + # Get the socket from the transport because SSL transport closes + # the old socket and creates a new SSL socket + sock = transport.get_extra_info('socket') + logger.debug("%r connected to %s:%r: (%r, %r)", + sock, host, port, transport, protocol) + return transport, protocol + + @coroutine + def _create_connection_transport(self, sock, protocol_factory, ssl, + server_hostname): protocol = protocol_factory() waiter = futures.Future(loop=self) if ssl: @@ -385,78 +689,148 @@ def create_connection(self, protocol_factory, host=None, port=None, *, else: transport = self._make_socket_transport(sock, protocol, waiter) - yield from waiter + try: + yield from waiter + except: + transport.close() + raise + return transport, protocol - @tasks.coroutine + @coroutine def create_datagram_endpoint(self, protocol_factory, local_addr=None, remote_addr=None, *, - family=0, proto=0, flags=0): + family=0, proto=0, flags=0, + reuse_address=None, reuse_port=None, + allow_broadcast=None, sock=None): """Create datagram connection.""" - if not (local_addr or remote_addr): - if family == 0: - raise ValueError('unexpected address family') - addr_pairs_info = (((family, proto), (None, None)),) - else: - # join addresss by (family, protocol) - addr_infos = collections.OrderedDict() - for idx, addr in ((0, local_addr), (1, remote_addr)): - if addr is not None: - assert isinstance(addr, tuple) and len(addr) == 2, ( - '2-tuple is expected') - - infos = yield from self.getaddrinfo( - *addr, family=family, type=socket.SOCK_DGRAM, - proto=proto, flags=flags) - if not infos: - raise OSError('getaddrinfo() returned empty list') - - for fam, _, pro, _, address in infos: - key = (fam, pro) - if key not in addr_infos: - addr_infos[key] = [None, None] - addr_infos[key][idx] = address - - # each addr has to have info for each (family, proto) pair - addr_pairs_info = [ - (key, addr_pair) for key, addr_pair in addr_infos.items() - if not ((local_addr and addr_pair[0] is None) or - (remote_addr and addr_pair[1] is None))] - - if not addr_pairs_info: - raise ValueError('can not get address information') - - exceptions = [] - - for ((family, proto), - (local_address, remote_address)) in addr_pairs_info: - sock = None + if sock is not None: + if (local_addr or remote_addr or + family or proto or flags or + reuse_address or reuse_port or allow_broadcast): + # show the problematic kwargs in exception msg + opts = dict(local_addr=local_addr, remote_addr=remote_addr, + family=family, proto=proto, flags=flags, + reuse_address=reuse_address, reuse_port=reuse_port, + allow_broadcast=allow_broadcast) + problems = ', '.join( + '{}={}'.format(k, v) for k, v in opts.items() if v) + raise ValueError( + 'socket modifier keyword arguments can not be used ' + 'when sock is specified. ({})'.format(problems)) + sock.setblocking(False) r_addr = None - try: - sock = socket.socket( - family=family, type=socket.SOCK_DGRAM, proto=proto) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - sock.setblocking(False) - - if local_addr: - sock.bind(local_address) - if remote_addr: - yield from self.sock_connect(sock, remote_address) - r_addr = remote_address - except OSError as exc: - if sock is not None: - sock.close() - exceptions.append(exc) - else: - break else: - raise exceptions[0] + if not (local_addr or remote_addr): + if family == 0: + raise ValueError('unexpected address family') + addr_pairs_info = (((family, proto), (None, None)),) + else: + # join address by (family, protocol) + addr_infos = collections.OrderedDict() + for idx, addr in ((0, local_addr), (1, remote_addr)): + if addr is not None: + assert isinstance(addr, tuple) and len(addr) == 2, ( + '2-tuple is expected') + + infos = yield from self.getaddrinfo( + *addr, family=family, type=socket.SOCK_DGRAM, + proto=proto, flags=flags) + if not infos: + raise OSError('getaddrinfo() returned empty list') + + for fam, _, pro, _, address in infos: + key = (fam, pro) + if key not in addr_infos: + addr_infos[key] = [None, None] + addr_infos[key][idx] = address + + # each addr has to have info for each (family, proto) pair + addr_pairs_info = [ + (key, addr_pair) for key, addr_pair in addr_infos.items() + if not ((local_addr and addr_pair[0] is None) or + (remote_addr and addr_pair[1] is None))] + + if not addr_pairs_info: + raise ValueError('can not get address information') + + exceptions = [] + + if reuse_address is None: + reuse_address = os.name == 'posix' and sys.platform != 'cygwin' + + for ((family, proto), + (local_address, remote_address)) in addr_pairs_info: + sock = None + r_addr = None + try: + sock = socket.socket( + family=family, type=socket.SOCK_DGRAM, proto=proto) + if reuse_address: + sock.setsockopt( + socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + if reuse_port: + if not hasattr(socket, 'SO_REUSEPORT'): + raise ValueError( + 'reuse_port not supported by socket module') + else: + sock.setsockopt( + socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) + if allow_broadcast: + sock.setsockopt( + socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + sock.setblocking(False) + + if local_addr: + sock.bind(local_address) + if remote_addr: + yield from self.sock_connect(sock, remote_address) + r_addr = remote_address + except OSError as exc: + if sock is not None: + sock.close() + exceptions.append(exc) + except: + if sock is not None: + sock.close() + raise + else: + break + else: + raise exceptions[0] protocol = protocol_factory() - transport = self._make_datagram_transport(sock, protocol, r_addr) + waiter = futures.Future(loop=self) + transport = self._make_datagram_transport( + sock, protocol, r_addr, waiter) + if self._debug: + if local_addr: + logger.info("Datagram endpoint local_addr=%r remote_addr=%r " + "created: (%r, %r)", + local_addr, remote_addr, transport, protocol) + else: + logger.debug("Datagram endpoint remote_addr=%r created: " + "(%r, %r)", + remote_addr, transport, protocol) + + try: + yield from waiter + except: + transport.close() + raise + return transport, protocol - @tasks.coroutine + @coroutine + def _create_server_getaddrinfo(self, host, port, family, flags): + infos = yield from self.getaddrinfo(host, port, family=family, + type=socket.SOCK_STREAM, + flags=flags) + if not infos: + raise OSError('getaddrinfo({!r}) returned empty list'.format(host)) + return infos + + @coroutine def create_server(self, protocol_factory, host=None, port=None, *, family=socket.AF_UNSPEC, @@ -464,8 +838,20 @@ def create_server(self, protocol_factory, host=None, port=None, sock=None, backlog=100, ssl=None, - reuse_address=None): - """XXX""" + reuse_address=None, + reuse_port=None): + """Create a TCP server. + + The host parameter can be a string, in that case the TCP server is bound + to host and port. + + The host parameter can also be a sequence of strings and in that case + the TCP server is bound to all hosts of the sequence. + + Return a Server object which can be used to stop the service. + + This method is a coroutine. + """ if isinstance(ssl, bool): raise TypeError('ssl argument must be an SSLContext or None') if host is not None or port is not None: @@ -478,13 +864,18 @@ def create_server(self, protocol_factory, host=None, port=None, reuse_address = os.name == 'posix' and sys.platform != 'cygwin' sockets = [] if host == '': - host = None + hosts = [None] + elif (isinstance(host, str) or + not isinstance(host, collections.Iterable)): + hosts = [host] + else: + hosts = host - infos = yield from self.getaddrinfo( - host, port, family=family, - type=socket.SOCK_STREAM, proto=0, flags=flags) - if not infos: - raise OSError('getaddrinfo() returned empty list') + fs = [self._create_server_getaddrinfo(host, port, family=family, + flags=flags) + for host in hosts] + infos = yield from tasks.gather(*fs, loop=self) + infos = itertools.chain.from_iterable(infos) completed = False try: @@ -494,11 +885,22 @@ def create_server(self, protocol_factory, host=None, port=None, sock = socket.socket(af, socktype, proto) except socket.error: # Assume it's a bad family/type/protocol combination. + if self._debug: + logger.warning('create_server() failed to create ' + 'socket.socket(%r, %r, %r)', + af, socktype, proto, exc_info=True) continue sockets.append(sock) if reuse_address: - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, - True) + sock.setsockopt( + socket.SOL_SOCKET, socket.SO_REUSEADDR, True) + if reuse_port: + if not hasattr(socket, 'SO_REUSEPORT'): + raise ValueError( + 'reuse_port not supported by socket module') + else: + sock.setsockopt( + socket.SOL_SOCKET, socket.SO_REUSEPORT, True) # Disable IPv4/IPv6 dual stack support (enabled by # default on Linux) which makes a single socket # listen on both address families. @@ -519,8 +921,7 @@ def create_server(self, protocol_factory, host=None, port=None, sock.close() else: if sock is None: - raise ValueError( - 'host and port was not specified and no sock specified') + raise ValueError('Neither host/port nor sock were specified') sockets = [sock] server = Server(self, sockets) @@ -528,64 +929,239 @@ def create_server(self, protocol_factory, host=None, port=None, sock.listen(backlog) sock.setblocking(False) self._start_serving(protocol_factory, sock, ssl, server) + if self._debug: + logger.info("%r is serving", server) return server - @tasks.coroutine + @coroutine def connect_read_pipe(self, protocol_factory, pipe): protocol = protocol_factory() waiter = futures.Future(loop=self) transport = self._make_read_pipe_transport(pipe, protocol, waiter) - yield from waiter + + try: + yield from waiter + except: + transport.close() + raise + + if self._debug: + logger.debug('Read pipe %r connected: (%r, %r)', + pipe.fileno(), transport, protocol) return transport, protocol - @tasks.coroutine + @coroutine def connect_write_pipe(self, protocol_factory, pipe): protocol = protocol_factory() waiter = futures.Future(loop=self) transport = self._make_write_pipe_transport(pipe, protocol, waiter) - yield from waiter + + try: + yield from waiter + except: + transport.close() + raise + + if self._debug: + logger.debug('Write pipe %r connected: (%r, %r)', + pipe.fileno(), transport, protocol) return transport, protocol - @tasks.coroutine + def _log_subprocess(self, msg, stdin, stdout, stderr): + info = [msg] + if stdin is not None: + info.append('stdin=%s' % _format_pipe(stdin)) + if stdout is not None and stderr == subprocess.STDOUT: + info.append('stdout=stderr=%s' % _format_pipe(stdout)) + else: + if stdout is not None: + info.append('stdout=%s' % _format_pipe(stdout)) + if stderr is not None: + info.append('stderr=%s' % _format_pipe(stderr)) + logger.debug(' '.join(info)) + + @coroutine def subprocess_shell(self, protocol_factory, cmd, *, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=False, shell=True, bufsize=0, **kwargs): - assert not universal_newlines, "universal_newlines must be False" - assert shell, "shell must be True" - assert isinstance(cmd, str), cmd + if not isinstance(cmd, (bytes, str)): + raise ValueError("cmd must be a string") + if universal_newlines: + raise ValueError("universal_newlines must be False") + if not shell: + raise ValueError("shell must be True") + if bufsize != 0: + raise ValueError("bufsize must be 0") protocol = protocol_factory() + if self._debug: + # don't log parameters: they may contain sensitive information + # (password) and may be too long + debug_log = 'run shell command %r' % cmd + self._log_subprocess(debug_log, stdin, stdout, stderr) transport = yield from self._make_subprocess_transport( protocol, cmd, True, stdin, stdout, stderr, bufsize, **kwargs) + if self._debug: + logger.info('%s: %r' % (debug_log, transport)) return transport, protocol - @tasks.coroutine - def subprocess_exec(self, protocol_factory, *args, stdin=subprocess.PIPE, - stdout=subprocess.PIPE, stderr=subprocess.PIPE, - universal_newlines=False, shell=False, bufsize=0, - **kwargs): - assert not universal_newlines, "universal_newlines must be False" - assert not shell, "shell must be False" + @coroutine + def subprocess_exec(self, protocol_factory, program, *args, + stdin=subprocess.PIPE, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, universal_newlines=False, + shell=False, bufsize=0, **kwargs): + if universal_newlines: + raise ValueError("universal_newlines must be False") + if shell: + raise ValueError("shell must be False") + if bufsize != 0: + raise ValueError("bufsize must be 0") + popen_args = (program,) + args + for arg in popen_args: + if not isinstance(arg, (str, bytes)): + raise TypeError("program arguments must be " + "a bytes or text string, not %s" + % type(arg).__name__) protocol = protocol_factory() + if self._debug: + # don't log parameters: they may contain sensitive information + # (password) and may be too long + debug_log = 'execute program %r' % program + self._log_subprocess(debug_log, stdin, stdout, stderr) transport = yield from self._make_subprocess_transport( - protocol, args, False, stdin, stdout, stderr, bufsize, **kwargs) + protocol, popen_args, False, stdin, stdout, stderr, + bufsize, **kwargs) + if self._debug: + logger.info('%s: %r' % (debug_log, transport)) return transport, protocol + def set_exception_handler(self, handler): + """Set handler as the new event loop exception handler. + + If handler is None, the default exception handler will + be set. + + If handler is a callable object, it should have a + signature matching '(loop, context)', where 'loop' + will be a reference to the active event loop, 'context' + will be a dict object (see `call_exception_handler()` + documentation for details about context). + """ + if handler is not None and not callable(handler): + raise TypeError('A callable object or None is expected, ' + 'got {!r}'.format(handler)) + self._exception_handler = handler + + def default_exception_handler(self, context): + """Default exception handler. + + This is called when an exception occurs and no exception + handler is set, and can be called by a custom exception + handler that wants to defer to the default behavior. + + The context parameter has the same meaning as in + `call_exception_handler()`. + """ + message = context.get('message') + if not message: + message = 'Unhandled exception in event loop' + + exception = context.get('exception') + if exception is not None: + exc_info = (type(exception), exception, exception.__traceback__) + else: + exc_info = False + + if ('source_traceback' not in context + and self._current_handle is not None + and self._current_handle._source_traceback): + context['handle_traceback'] = self._current_handle._source_traceback + + log_lines = [message] + for key in sorted(context): + if key in {'message', 'exception'}: + continue + value = context[key] + if key == 'source_traceback': + tb = ''.join(traceback.format_list(value)) + value = 'Object created at (most recent call last):\n' + value += tb.rstrip() + elif key == 'handle_traceback': + tb = ''.join(traceback.format_list(value)) + value = 'Handle created at (most recent call last):\n' + value += tb.rstrip() + else: + value = repr(value) + log_lines.append('{}: {}'.format(key, value)) + + logger.error('\n'.join(log_lines), exc_info=exc_info) + + def call_exception_handler(self, context): + """Call the current event loop's exception handler. + + The context argument is a dict containing the following keys: + + - 'message': Error message; + - 'exception' (optional): Exception object; + - 'future' (optional): Future instance; + - 'handle' (optional): Handle instance; + - 'protocol' (optional): Protocol instance; + - 'transport' (optional): Transport instance; + - 'socket' (optional): Socket instance. + + New keys maybe introduced in the future. + + Note: do not overload this method in an event loop subclass. + For custom exception handling, use the + `set_exception_handler()` method. + """ + if self._exception_handler is None: + try: + self.default_exception_handler(context) + except Exception: + # Second protection layer for unexpected errors + # in the default implementation, as well as for subclassed + # event loops with overloaded "default_exception_handler". + logger.error('Exception in default exception handler', + exc_info=True) + else: + try: + self._exception_handler(self, context) + except Exception as exc: + # Exception in the user set custom exception handler. + try: + # Let's try default handler. + self.default_exception_handler({ + 'message': 'Unhandled error in exception handler', + 'exception': exc, + 'context': context, + }) + except Exception: + # Guard 'default_exception_handler' in case it is + # overloaded. + logger.error('Exception in default exception handler ' + 'while handling an unexpected error ' + 'in custom exception handler', + exc_info=True) + def _add_callback(self, handle): - """Add a Handle to ready or scheduled.""" + """Add a Handle to _scheduled (TimerHandle) or _ready.""" assert isinstance(handle, events.Handle), 'A Handle is required here' if handle._cancelled: return - if isinstance(handle, events.TimerHandle): - heapq.heappush(self._scheduled, handle) - else: - self._ready.append(handle) + assert not isinstance(handle, events.TimerHandle) + self._ready.append(handle) def _add_callback_signalsafe(self, handle): """Like _add_callback() but called from a signal handler.""" self._add_callback(handle) self._write_to_self() + def _timer_handle_cancelled(self, handle): + """Notification that a TimerHandle has been cancelled.""" + if handle._scheduled: + self._timer_cancelled_count += 1 + def _run_once(self): """Run one full iteration of the event loop. @@ -593,9 +1169,29 @@ def _run_once(self): schedules the resulting callbacks, and finally schedules 'call_later' callbacks. """ - # Remove delayed calls that were cancelled from head of queue. - while self._scheduled and self._scheduled[0]._cancelled: - heapq.heappop(self._scheduled) + + sched_count = len(self._scheduled) + if (sched_count > _MIN_SCHEDULED_TIMER_HANDLES and + self._timer_cancelled_count / sched_count > + _MIN_CANCELLED_TIMER_HANDLES_FRACTION): + # Remove delayed calls that were cancelled if their number + # is too high + new_scheduled = [] + for handle in self._scheduled: + if handle._cancelled: + handle._scheduled = False + else: + new_scheduled.append(handle) + + heapq.heapify(new_scheduled) + self._scheduled = new_scheduled + self._timer_cancelled_count = 0 + else: + # Remove delayed calls that were cancelled from head of queue. + while self._scheduled and self._scheduled[0]._cancelled: + self._timer_cancelled_count -= 1 + handle = heapq.heappop(self._scheduled) + handle._scheduled = False timeout = None if self._ready: @@ -603,31 +1199,40 @@ def _run_once(self): elif self._scheduled: # Compute the desired timeout. when = self._scheduled[0]._when - deadline = max(0, when - self.time()) - if timeout is None: - timeout = deadline + timeout = max(0, when - self.time()) + + if self._debug and timeout != 0: + t0 = self.time() + event_list = self._selector.select(timeout) + dt = self.time() - t0 + if dt >= 1.0: + level = logging.INFO else: - timeout = min(timeout, deadline) - - # TODO: Instrumentation only in debug mode? - t0 = self.time() - event_list = self._selector.select(timeout) - t1 = self.time() - argstr = '' if timeout is None else '{:.3f}'.format(timeout) - if t1-t0 >= 1: - level = logging.INFO + level = logging.DEBUG + nevent = len(event_list) + if timeout is None: + logger.log(level, 'poll took %.3f ms: %s events', + dt * 1e3, nevent) + elif nevent: + logger.log(level, + 'poll %.3f ms took %.3f ms: %s events', + timeout * 1e3, dt * 1e3, nevent) + elif dt >= 1.0: + logger.log(level, + 'poll %.3f ms took %.3f ms: timeout', + timeout * 1e3, dt * 1e3) else: - level = logging.DEBUG - logger.log(level, 'poll%s took %.3f seconds', argstr, t1-t0) + event_list = self._selector.select(timeout) self._process_events(event_list) # Handle 'later' callbacks that are ready. - now = self.time() + end_time = self.time() + self._clock_resolution while self._scheduled: handle = self._scheduled[0] - if handle._when > now: + if handle._when >= end_time: break handle = heapq.heappop(self._scheduled) + handle._scheduled = False self._ready.append(handle) # This is the only place where callbacks are actually *called*. @@ -635,10 +1240,65 @@ def _run_once(self): # Note: We run all currently scheduled callbacks, but not any # callbacks scheduled by callbacks run this time around -- # they will be run the next time (after another I/O poll). - # Use an idiom that is threadsafe without using locks. + # Use an idiom that is thread-safe without using locks. ntodo = len(self._ready) for i in range(ntodo): handle = self._ready.popleft() - if not handle._cancelled: + if handle._cancelled: + continue + if self._debug: + try: + self._current_handle = handle + t0 = self.time() + handle._run() + dt = self.time() - t0 + if dt >= self.slow_callback_duration: + logger.warning('Executing %s took %.3f seconds', + _format_handle(handle), dt) + finally: + self._current_handle = None + else: handle._run() handle = None # Needed to break cycles when an exception occurs. + + def _set_coroutine_wrapper(self, enabled): + try: + set_wrapper = sys.set_coroutine_wrapper + get_wrapper = sys.get_coroutine_wrapper + except AttributeError: + return + + enabled = bool(enabled) + if self._coroutine_wrapper_set == enabled: + return + + wrapper = coroutines.debug_wrapper + current_wrapper = get_wrapper() + + if enabled: + if current_wrapper not in (None, wrapper): + warnings.warn( + "loop.set_debug(True): cannot set debug coroutine " + "wrapper; another wrapper is already set %r" % + current_wrapper, RuntimeWarning) + else: + set_wrapper(wrapper) + self._coroutine_wrapper_set = True + else: + if current_wrapper not in (None, wrapper): + warnings.warn( + "loop.set_debug(False): cannot unset debug coroutine " + "wrapper; another wrapper was set %r" % + current_wrapper, RuntimeWarning) + else: + set_wrapper(None) + self._coroutine_wrapper_set = False + + def get_debug(self): + return self._debug + + def set_debug(self, enabled): + self._debug = enabled + + if self.is_running(): + self._set_coroutine_wrapper(enabled) diff --git a/Lib/asyncio/base_subprocess.py b/Lib/asyncio/base_subprocess.py index d15fb159d90a..6851cd2b88e3 100644 --- a/Lib/asyncio/base_subprocess.py +++ b/Lib/asyncio/base_subprocess.py @@ -1,56 +1,129 @@ import collections import subprocess +import warnings +from . import compat +from . import futures from . import protocols -from . import tasks from . import transports - - -STDIN = 0 -STDOUT = 1 -STDERR = 2 +from .coroutines import coroutine +from .log import logger class BaseSubprocessTransport(transports.SubprocessTransport): def __init__(self, loop, protocol, args, shell, stdin, stdout, stderr, bufsize, - extra=None, **kwargs): + waiter=None, extra=None, **kwargs): super().__init__(extra) + self._closed = False self._protocol = protocol self._loop = loop - + self._proc = None + self._pid = None + self._returncode = None + self._exit_waiters = [] + self._pending_calls = collections.deque() self._pipes = {} + self._finished = False + if stdin == subprocess.PIPE: - self._pipes[STDIN] = None + self._pipes[0] = None if stdout == subprocess.PIPE: - self._pipes[STDOUT] = None + self._pipes[1] = None if stderr == subprocess.PIPE: - self._pipes[STDERR] = None - self._pending_calls = collections.deque() - self._finished = False - self._returncode = None - self._start(args=args, shell=shell, stdin=stdin, stdout=stdout, - stderr=stderr, bufsize=bufsize, **kwargs) + self._pipes[2] = None + + # Create the child process: set the _proc attribute + try: + self._start(args=args, shell=shell, stdin=stdin, stdout=stdout, + stderr=stderr, bufsize=bufsize, **kwargs) + except: + self.close() + raise + + self._pid = self._proc.pid self._extra['subprocess'] = self._proc - def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs): - raise NotImplementedError + if self._loop.get_debug(): + if isinstance(args, (bytes, str)): + program = args + else: + program = args[0] + logger.debug('process %r created: pid %s', + program, self._pid) + + self._loop.create_task(self._connect_pipes(waiter)) + + def __repr__(self): + info = [self.__class__.__name__] + if self._closed: + info.append('closed') + if self._pid is not None: + info.append('pid=%s' % self._pid) + if self._returncode is not None: + info.append('returncode=%s' % self._returncode) + elif self._pid is not None: + info.append('running') + else: + info.append('not started') - def _make_write_subprocess_pipe_proto(self, fd): - raise NotImplementedError + stdin = self._pipes.get(0) + if stdin is not None: + info.append('stdin=%s' % stdin.pipe) + + stdout = self._pipes.get(1) + stderr = self._pipes.get(2) + if stdout is not None and stderr is stdout: + info.append('stdout=stderr=%s' % stdout.pipe) + else: + if stdout is not None: + info.append('stdout=%s' % stdout.pipe) + if stderr is not None: + info.append('stderr=%s' % stderr.pipe) - def _make_read_subprocess_pipe_proto(self, fd): + return '<%s>' % ' '.join(info) + + def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs): raise NotImplementedError def close(self): + if self._closed: + return + self._closed = True + for proto in self._pipes.values(): + if proto is None: + continue proto.pipe.close() - if self._returncode is None: - self.terminate() + + if (self._proc is not None + # the child process finished? + and self._returncode is None + # the child process finished but the transport was not notified yet? + and self._proc.poll() is None + ): + if self._loop.get_debug(): + logger.warning('Close running child process: kill %r', self) + + try: + self._proc.kill() + except ProcessLookupError: + pass + + # Don't clear the _proc reference yet: _post_init() may still run + + # On Python 3.3 and older, objects with a destructor part of a reference + # cycle are never destroyed. It's not more the case on Python 3.4 thanks + # to the PEP 442. + if compat.PY34: + def __del__(self): + if not self._closed: + warnings.warn("unclosed transport %r" % self, ResourceWarning) + self.close() def get_pid(self): - return self._proc.pid + return self._pid def get_returncode(self): return self._returncode @@ -61,33 +134,58 @@ def get_pipe_transport(self, fd): else: return None + def _check_proc(self): + if self._proc is None: + raise ProcessLookupError() + def send_signal(self, signal): + self._check_proc() self._proc.send_signal(signal) def terminate(self): + self._check_proc() self._proc.terminate() def kill(self): + self._check_proc() self._proc.kill() - @tasks.coroutine - def _post_init(self): - proc = self._proc - loop = self._loop - if proc.stdin is not None: - transp, proto = yield from loop.connect_write_pipe( - lambda: WriteSubprocessPipeProto(self, STDIN), - proc.stdin) - if proc.stdout is not None: - transp, proto = yield from loop.connect_read_pipe( - lambda: ReadSubprocessPipeProto(self, STDOUT), - proc.stdout) - if proc.stderr is not None: - transp, proto = yield from loop.connect_read_pipe( - lambda: ReadSubprocessPipeProto(self, STDERR), - proc.stderr) - if not self._pipes: - self._try_connected() + @coroutine + def _connect_pipes(self, waiter): + try: + proc = self._proc + loop = self._loop + + if proc.stdin is not None: + _, pipe = yield from loop.connect_write_pipe( + lambda: WriteSubprocessPipeProto(self, 0), + proc.stdin) + self._pipes[0] = pipe + + if proc.stdout is not None: + _, pipe = yield from loop.connect_read_pipe( + lambda: ReadSubprocessPipeProto(self, 1), + proc.stdout) + self._pipes[1] = pipe + + if proc.stderr is not None: + _, pipe = yield from loop.connect_read_pipe( + lambda: ReadSubprocessPipeProto(self, 2), + proc.stderr) + self._pipes[2] = pipe + + assert self._pending_calls is not None + + loop.call_soon(self._protocol.connection_made, self) + for callback, data in self._pending_calls: + loop.call_soon(callback, *data) + self._pending_calls = None + except Exception as exc: + if waiter is not None and not waiter.cancelled(): + waiter.set_exception(exc) + else: + if waiter is not None and not waiter.cancelled(): + waiter.set_result(None) def _call(self, cb, *data): if self._pending_calls is not None: @@ -95,14 +193,6 @@ def _call(self, cb, *data): else: self._loop.call_soon(cb, *data) - def _try_connected(self): - assert self._pending_calls is not None - if all(p is not None and p.connected for p in self._pipes.values()): - self._loop.call_soon(self._protocol.connection_made, self) - for callback, data in self._pending_calls: - self._loop.call_soon(callback, *data) - self._pending_calls = None - def _pipe_connection_lost(self, fd, exc): self._call(self._protocol.pipe_connection_lost, fd, exc) self._try_finish() @@ -113,11 +203,31 @@ def _pipe_data_received(self, fd, data): def _process_exited(self, returncode): assert returncode is not None, returncode assert self._returncode is None, self._returncode + if self._loop.get_debug(): + logger.info('%r exited with return code %r', + self, returncode) self._returncode = returncode - self._loop._subprocess_closed(self) self._call(self._protocol.process_exited) self._try_finish() + # wake up futures waiting for wait() + for waiter in self._exit_waiters: + if not waiter.cancelled(): + waiter.set_result(returncode) + self._exit_waiters = None + + @coroutine + def _wait(self): + """Wait until the process exit and return the process return code. + + This method is a coroutine.""" + if self._returncode is not None: + return self._returncode + + waiter = futures.Future(loop=self._loop) + self._exit_waiters.append(waiter) + return (yield from waiter) + def _try_finish(self): assert not self._finished if self._returncode is None: @@ -125,38 +235,42 @@ def _try_finish(self): if all(p is not None and p.disconnected for p in self._pipes.values()): self._finished = True - self._loop.call_soon(self._call_connection_lost, None) + self._call(self._call_connection_lost, None) def _call_connection_lost(self, exc): try: self._protocol.connection_lost(exc) finally: + self._loop = None self._proc = None self._protocol = None - self._loop = None class WriteSubprocessPipeProto(protocols.BaseProtocol): - pipe = None def __init__(self, proc, fd): self.proc = proc self.fd = fd - self.connected = False + self.pipe = None self.disconnected = False - proc._pipes[fd] = self def connection_made(self, transport): - self.connected = True self.pipe = transport - self.proc._try_connected() + + def __repr__(self): + return ('<%s fd=%s pipe=%r>' + % (self.__class__.__name__, self.fd, self.pipe)) def connection_lost(self, exc): self.disconnected = True self.proc._pipe_connection_lost(self.fd, exc) + self.proc = None + + def pause_writing(self): + self.proc._protocol.pause_writing() - def eof_received(self): - pass + def resume_writing(self): + self.proc._protocol.resume_writing() class ReadSubprocessPipeProto(WriteSubprocessPipeProto, diff --git a/Lib/asyncio/compat.py b/Lib/asyncio/compat.py new file mode 100644 index 000000000000..660b7e7e6c9a --- /dev/null +++ b/Lib/asyncio/compat.py @@ -0,0 +1,17 @@ +"""Compatibility helpers for the different Python versions.""" + +import sys + +PY34 = sys.version_info >= (3, 4) +PY35 = sys.version_info >= (3, 5) + + +def flatten_list_bytes(list_of_data): + """Concatenate a sequence of bytes-like objects.""" + if not PY34: + # On Python 3.3 and older, bytes.join() doesn't handle + # memoryview. + list_of_data = ( + bytes(data) if isinstance(data, memoryview) else data + for data in list_of_data) + return b''.join(list_of_data) diff --git a/Lib/asyncio/coroutines.py b/Lib/asyncio/coroutines.py new file mode 100644 index 000000000000..e11b21b09754 --- /dev/null +++ b/Lib/asyncio/coroutines.py @@ -0,0 +1,299 @@ +__all__ = ['coroutine', + 'iscoroutinefunction', 'iscoroutine'] + +import functools +import inspect +import opcode +import os +import sys +import traceback +import types + +from . import compat +from . import events +from . import futures +from .log import logger + + +# Opcode of "yield from" instruction +_YIELD_FROM = opcode.opmap['YIELD_FROM'] + +# If you set _DEBUG to true, @coroutine will wrap the resulting +# generator objects in a CoroWrapper instance (defined below). That +# instance will log a message when the generator is never iterated +# over, which may happen when you forget to use "yield from" with a +# coroutine call. Note that the value of the _DEBUG flag is taken +# when the decorator is used, so to be of any use it must be set +# before you define your coroutines. A downside of using this feature +# is that tracebacks show entries for the CoroWrapper.__next__ method +# when _DEBUG is true. +_DEBUG = (not sys.flags.ignore_environment + and bool(os.environ.get('PYTHONASYNCIODEBUG'))) + + +try: + _types_coroutine = types.coroutine +except AttributeError: + _types_coroutine = None + +try: + _inspect_iscoroutinefunction = inspect.iscoroutinefunction +except AttributeError: + _inspect_iscoroutinefunction = lambda func: False + +try: + from collections.abc import Coroutine as _CoroutineABC, \ + Awaitable as _AwaitableABC +except ImportError: + _CoroutineABC = _AwaitableABC = None + + +# Check for CPython issue #21209 +def has_yield_from_bug(): + class MyGen: + def __init__(self): + self.send_args = None + def __iter__(self): + return self + def __next__(self): + return 42 + def send(self, *what): + self.send_args = what + return None + def yield_from_gen(gen): + yield from gen + value = (1, 2, 3) + gen = MyGen() + coro = yield_from_gen(gen) + next(coro) + coro.send(value) + return gen.send_args != (value,) +_YIELD_FROM_BUG = has_yield_from_bug() +del has_yield_from_bug + + +def debug_wrapper(gen): + # This function is called from 'sys.set_coroutine_wrapper'. + # We only wrap here coroutines defined via 'async def' syntax. + # Generator-based coroutines are wrapped in @coroutine + # decorator. + return CoroWrapper(gen, None) + + +class CoroWrapper: + # Wrapper for coroutine object in _DEBUG mode. + + def __init__(self, gen, func=None): + assert inspect.isgenerator(gen) or inspect.iscoroutine(gen), gen + self.gen = gen + self.func = func # Used to unwrap @coroutine decorator + self._source_traceback = traceback.extract_stack(sys._getframe(1)) + self.__name__ = getattr(gen, '__name__', None) + self.__qualname__ = getattr(gen, '__qualname__', None) + + def __repr__(self): + coro_repr = _format_coroutine(self) + if self._source_traceback: + frame = self._source_traceback[-1] + coro_repr += ', created at %s:%s' % (frame[0], frame[1]) + return '<%s %s>' % (self.__class__.__name__, coro_repr) + + def __iter__(self): + return self + + def __next__(self): + return self.gen.send(None) + + if _YIELD_FROM_BUG: + # For for CPython issue #21209: using "yield from" and a custom + # generator, generator.send(tuple) unpacks the tuple instead of passing + # the tuple unchanged. Check if the caller is a generator using "yield + # from" to decide if the parameter should be unpacked or not. + def send(self, *value): + frame = sys._getframe() + caller = frame.f_back + assert caller.f_lasti >= 0 + if caller.f_code.co_code[caller.f_lasti] != _YIELD_FROM: + value = value[0] + return self.gen.send(value) + else: + def send(self, value): + return self.gen.send(value) + + def throw(self, exc): + return self.gen.throw(exc) + + def close(self): + return self.gen.close() + + @property + def gi_frame(self): + return self.gen.gi_frame + + @property + def gi_running(self): + return self.gen.gi_running + + @property + def gi_code(self): + return self.gen.gi_code + + if compat.PY35: + + __await__ = __iter__ # make compatible with 'await' expression + + @property + def gi_yieldfrom(self): + return self.gen.gi_yieldfrom + + @property + def cr_await(self): + return self.gen.cr_await + + @property + def cr_running(self): + return self.gen.cr_running + + @property + def cr_code(self): + return self.gen.cr_code + + @property + def cr_frame(self): + return self.gen.cr_frame + + def __del__(self): + # Be careful accessing self.gen.frame -- self.gen might not exist. + gen = getattr(self, 'gen', None) + frame = getattr(gen, 'gi_frame', None) + if frame is None: + frame = getattr(gen, 'cr_frame', None) + if frame is not None and frame.f_lasti == -1: + msg = '%r was never yielded from' % self + tb = getattr(self, '_source_traceback', ()) + if tb: + tb = ''.join(traceback.format_list(tb)) + msg += ('\nCoroutine object created at ' + '(most recent call last):\n') + msg += tb.rstrip() + logger.error(msg) + + +def coroutine(func): + """Decorator to mark coroutines. + + If the coroutine is not yielded from before it is destroyed, + an error message is logged. + """ + if _inspect_iscoroutinefunction(func): + # In Python 3.5 that's all we need to do for coroutines + # defiend with "async def". + # Wrapping in CoroWrapper will happen via + # 'sys.set_coroutine_wrapper' function. + return func + + if inspect.isgeneratorfunction(func): + coro = func + else: + @functools.wraps(func) + def coro(*args, **kw): + res = func(*args, **kw) + if isinstance(res, futures.Future) or inspect.isgenerator(res): + res = yield from res + elif _AwaitableABC is not None: + # If 'func' returns an Awaitable (new in 3.5) we + # want to run it. + try: + await_meth = res.__await__ + except AttributeError: + pass + else: + if isinstance(res, _AwaitableABC): + res = yield from await_meth() + return res + + if not _DEBUG: + if _types_coroutine is None: + wrapper = coro + else: + wrapper = _types_coroutine(coro) + else: + @functools.wraps(func) + def wrapper(*args, **kwds): + w = CoroWrapper(coro(*args, **kwds), func=func) + if w._source_traceback: + del w._source_traceback[-1] + # Python < 3.5 does not implement __qualname__ + # on generator objects, so we set it manually. + # We use getattr as some callables (such as + # functools.partial may lack __qualname__). + w.__name__ = getattr(func, '__name__', None) + w.__qualname__ = getattr(func, '__qualname__', None) + return w + + wrapper._is_coroutine = True # For iscoroutinefunction(). + return wrapper + + +def iscoroutinefunction(func): + """Return True if func is a decorated coroutine function.""" + return (getattr(func, '_is_coroutine', False) or + _inspect_iscoroutinefunction(func)) + + +_COROUTINE_TYPES = (types.GeneratorType, CoroWrapper) +if _CoroutineABC is not None: + _COROUTINE_TYPES += (_CoroutineABC,) + + +def iscoroutine(obj): + """Return True if obj is a coroutine object.""" + return isinstance(obj, _COROUTINE_TYPES) + + +def _format_coroutine(coro): + assert iscoroutine(coro) + + coro_name = None + if isinstance(coro, CoroWrapper): + func = coro.func + coro_name = coro.__qualname__ + if coro_name is not None: + coro_name = '{}()'.format(coro_name) + else: + func = coro + + if coro_name is None: + coro_name = events._format_callback(func, ()) + + try: + coro_code = coro.gi_code + except AttributeError: + coro_code = coro.cr_code + + try: + coro_frame = coro.gi_frame + except AttributeError: + coro_frame = coro.cr_frame + + filename = coro_code.co_filename + if (isinstance(coro, CoroWrapper) + and not inspect.isgeneratorfunction(coro.func) + and coro.func is not None): + filename, lineno = events._get_function_source(coro.func) + if coro_frame is None: + coro_repr = ('%s done, defined at %s:%s' + % (coro_name, filename, lineno)) + else: + coro_repr = ('%s running, defined at %s:%s' + % (coro_name, filename, lineno)) + elif coro_frame is not None: + lineno = coro_frame.f_lineno + coro_repr = ('%s running at %s:%s' + % (coro_name, filename, lineno)) + else: + lineno = coro_code.co_firstlineno + coro_repr = ('%s done, defined at %s:%s' + % (coro_name, filename, lineno)) + + return coro_repr diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py index c10faa75b066..176a84669844 100644 --- a/Lib/asyncio/events.py +++ b/Lib/asyncio/events.py @@ -8,63 +8,153 @@ 'get_child_watcher', 'set_child_watcher', ] +import functools +import inspect +import reprlib +import socket import subprocess import sys import threading -import socket +import traceback + +from asyncio import compat + + +def _get_function_source(func): + if compat.PY34: + func = inspect.unwrap(func) + elif hasattr(func, '__wrapped__'): + func = func.__wrapped__ + if inspect.isfunction(func): + code = func.__code__ + return (code.co_filename, code.co_firstlineno) + if isinstance(func, functools.partial): + return _get_function_source(func.func) + if compat.PY34 and isinstance(func, functools.partialmethod): + return _get_function_source(func.func) + return None -from .log import logger + +def _format_args(args): + """Format function arguments. + + Special case for a single parameter: ('hello',) is formatted as ('hello'). + """ + # use reprlib to limit the length of the output + args_repr = reprlib.repr(args) + if len(args) == 1 and args_repr.endswith(',)'): + args_repr = args_repr[:-2] + ')' + return args_repr + + +def _format_callback(func, args, suffix=''): + if isinstance(func, functools.partial): + if args is not None: + suffix = _format_args(args) + suffix + return _format_callback(func.func, func.args, suffix) + + if hasattr(func, '__qualname__'): + func_repr = getattr(func, '__qualname__') + elif hasattr(func, '__name__'): + func_repr = getattr(func, '__name__') + else: + func_repr = repr(func) + + if args is not None: + func_repr += _format_args(args) + if suffix: + func_repr += suffix + return func_repr + +def _format_callback_source(func, args): + func_repr = _format_callback(func, args) + source = _get_function_source(func) + if source: + func_repr += ' at %s:%s' % source + return func_repr class Handle: """Object returned by callback registration methods.""" - def __init__(self, callback, args): + __slots__ = ('_callback', '_args', '_cancelled', '_loop', + '_source_traceback', '_repr', '__weakref__') + + def __init__(self, callback, args, loop): + assert not isinstance(callback, Handle), 'A Handle is not a callback' + self._loop = loop self._callback = callback self._args = args self._cancelled = False + self._repr = None + if self._loop.get_debug(): + self._source_traceback = traceback.extract_stack(sys._getframe(1)) + else: + self._source_traceback = None + + def _repr_info(self): + info = [self.__class__.__name__] + if self._cancelled: + info.append('cancelled') + if self._callback is not None: + info.append(_format_callback_source(self._callback, self._args)) + if self._source_traceback: + frame = self._source_traceback[-1] + info.append('created at %s:%s' % (frame[0], frame[1])) + return info def __repr__(self): - res = 'Handle({}, {})'.format(self._callback, self._args) - if self._cancelled: - res += '<cancelled>' - return res + if self._repr is not None: + return self._repr + info = self._repr_info() + return '<%s>' % ' '.join(info) def cancel(self): - self._cancelled = True + if not self._cancelled: + self._cancelled = True + if self._loop.get_debug(): + # Keep a representation in debug mode to keep callback and + # parameters. For example, to log the warning + # "Executing <Handle...> took 2.5 second" + self._repr = repr(self) + self._callback = None + self._args = None def _run(self): try: self._callback(*self._args) - except Exception: - logger.exception('Exception in callback %s %r', - self._callback, self._args) + except Exception as exc: + cb = _format_callback_source(self._callback, self._args) + msg = 'Exception in callback {}'.format(cb) + context = { + 'message': msg, + 'exception': exc, + 'handle': self, + } + if self._source_traceback: + context['source_traceback'] = self._source_traceback + self._loop.call_exception_handler(context) self = None # Needed to break cycles when an exception occurs. -def make_handle(callback, args): - # TODO: Inline this? Or make it a private EventLoop method? - assert not isinstance(callback, Handle), 'A Handle is not a callback' - return Handle(callback, args) - - class TimerHandle(Handle): """Object returned by timed callback registration methods.""" - def __init__(self, when, callback, args): - assert when is not None - super().__init__(callback, args) + __slots__ = ['_scheduled', '_when'] + def __init__(self, when, callback, args, loop): + assert when is not None + super().__init__(callback, args, loop) + if self._source_traceback: + del self._source_traceback[-1] self._when = when + self._scheduled = False - def __repr__(self): - res = 'TimerHandle({}, {}, {})'.format(self._when, - self._callback, - self._args) - if self._cancelled: - res += '<cancelled>' - - return res + def _repr_info(self): + info = super()._repr_info() + pos = 2 if self._cancelled else 1 + info.insert(pos, 'when=%s' % self._when) + return info def __hash__(self): return hash(self._when) @@ -97,9 +187,14 @@ def __ne__(self, other): equal = self.__eq__(other) return NotImplemented if equal is NotImplemented else not equal + def cancel(self): + if not self._cancelled: + self._loop._timer_handle_cancelled(self) + super().cancel() + class AbstractServer: - """Abstract server returned by create_service().""" + """Abstract server returned by create_server().""" def close(self): """Stop serving. This leaves existing connections open.""" @@ -138,6 +233,10 @@ def is_running(self): """Return whether the event loop is currently running.""" raise NotImplementedError + def is_closed(self): + """Returns True if the event loop was closed.""" + raise NotImplementedError + def close(self): """Close the loop. @@ -151,6 +250,10 @@ def close(self): # Methods scheduling callbacks. All these return Handles. + def _timer_handle_cancelled(self, handle): + """Notification that a TimerHandle has been cancelled.""" + raise NotImplementedError + def call_soon(self, callback, *args): return self.call_later(0, callback, *args) @@ -163,12 +266,17 @@ def call_at(self, when, callback, *args): def time(self): raise NotImplementedError + # Method scheduling a coroutine object: create a task. + + def create_task(self, coro): + raise NotImplementedError + # Methods for interacting with threads. def call_soon_threadsafe(self, callback, *args): raise NotImplementedError - def run_in_executor(self, executor, callback, *args): + def run_in_executor(self, executor, func, *args): raise NotImplementedError def set_default_executor(self, executor): @@ -189,7 +297,8 @@ def create_connection(self, protocol_factory, host=None, port=None, *, def create_server(self, protocol_factory, host=None, port=None, *, family=socket.AF_UNSPEC, flags=socket.AI_PASSIVE, - sock=None, backlog=100, ssl=None, reuse_address=None): + sock=None, backlog=100, ssl=None, reuse_address=None, + reuse_port=None): """A coroutine which creates a TCP server bound to host and port. The return value is a Server object which can be used to stop @@ -197,7 +306,8 @@ def create_server(self, protocol_factory, host=None, port=None, *, If host is an empty string or None all interfaces are assumed and a list of multiple sockets will be returned (most likely - one for IPv4 and another one for IPv6). + one for IPv4 and another one for IPv6). The host parameter can also be a + sequence (e.g. list) of hosts to bind to. family can be set to either AF_INET or AF_INET6 to force the socket to use IPv4 or IPv6. If not set it will be determined @@ -218,22 +328,83 @@ def create_server(self, protocol_factory, host=None, port=None, *, TIME_WAIT state, without waiting for its natural timeout to expire. If not specified will automatically be set to True on UNIX. + + reuse_port tells the kernel to allow this endpoint to be bound to + the same port as other existing endpoints are bound to, so long as + they all set this flag when being created. This option is not + supported on Windows. + """ + raise NotImplementedError + + def create_unix_connection(self, protocol_factory, path, *, + ssl=None, sock=None, + server_hostname=None): + raise NotImplementedError + + def create_unix_server(self, protocol_factory, path, *, + sock=None, backlog=100, ssl=None): + """A coroutine which creates a UNIX Domain Socket server. + + The return value is a Server object, which can be used to stop + the service. + + path is a str, representing a file systsem path to bind the + server socket to. + + sock can optionally be specified in order to use a preexisting + socket object. + + backlog is the maximum number of queued connections passed to + listen() (defaults to 100). + + ssl can be set to an SSLContext to enable SSL over the + accepted connections. """ raise NotImplementedError def create_datagram_endpoint(self, protocol_factory, local_addr=None, remote_addr=None, *, - family=0, proto=0, flags=0): + family=0, proto=0, flags=0, + reuse_address=None, reuse_port=None, + allow_broadcast=None, sock=None): + """A coroutine which creates a datagram endpoint. + + This method will try to establish the endpoint in the background. + When successful, the coroutine returns a (transport, protocol) pair. + + protocol_factory must be a callable returning a protocol instance. + + socket family AF_INET or socket.AF_INET6 depending on host (or + family if specified), socket type SOCK_DGRAM. + + reuse_address tells the kernel to reuse a local socket in + TIME_WAIT state, without waiting for its natural timeout to + expire. If not specified it will automatically be set to True on + UNIX. + + reuse_port tells the kernel to allow this endpoint to be bound to + the same port as other existing endpoints are bound to, so long as + they all set this flag when being created. This option is not + supported on Windows and some UNIX's. If the + :py:data:`~socket.SO_REUSEPORT` constant is not defined then this + capability is unsupported. + + allow_broadcast tells the kernel to allow this endpoint to send + messages to the broadcast address. + + sock can optionally be specified in order to use a preexisting + socket object. + """ raise NotImplementedError # Pipes and subprocesses. def connect_read_pipe(self, protocol_factory, pipe): - """Register read pipe in eventloop. + """Register read pipe in event loop. Set the pipe to non-blocking mode. protocol_factory should instantiate object with Protocol interface. - pipe is file-like object already switched to nonblocking. - Return pair (transport, protocol), where transport support + pipe is a file-like object. + Return pair (transport, protocol), where transport supports the ReadTransport interface.""" # The reason to accept file-like object instead of just file descriptor # is: we need to own pipe and close it at transport finishing @@ -242,7 +413,7 @@ def connect_read_pipe(self, protocol_factory, pipe): raise NotImplementedError def connect_write_pipe(self, protocol_factory, pipe): - """Register write pipe in eventloop. + """Register write pipe in event loop. protocol_factory should instantiate object with BaseProtocol interface. Pipe is file-like object already switched to nonblocking. @@ -303,30 +474,65 @@ def add_signal_handler(self, sig, callback, *args): def remove_signal_handler(self, sig): raise NotImplementedError + # Task factory. + + def set_task_factory(self, factory): + raise NotImplementedError + + def get_task_factory(self): + raise NotImplementedError + + # Error handlers. + + def set_exception_handler(self, handler): + raise NotImplementedError + + def default_exception_handler(self, context): + raise NotImplementedError + + def call_exception_handler(self, context): + raise NotImplementedError + + # Debug flag management. + + def get_debug(self): + raise NotImplementedError + + def set_debug(self, enabled): + raise NotImplementedError + class AbstractEventLoopPolicy: """Abstract policy for accessing the event loop.""" def get_event_loop(self): - """XXX""" + """Get the event loop for the current context. + + Returns an event loop object implementing the BaseEventLoop interface, + or raises an exception in case no event loop has been set for the + current context and the current policy does not specify to create one. + + It should never return None.""" raise NotImplementedError def set_event_loop(self, loop): - """XXX""" + """Set the event loop for the current context to loop.""" raise NotImplementedError def new_event_loop(self): - """XXX""" + """Create and return a new event loop object according to this + policy's rules. If there's need to set this loop as the event loop for + the current context, set_event_loop must be called explicitly.""" raise NotImplementedError # Child processes handling (Unix only). def get_child_watcher(self): - """XXX""" + "Get the watcher for child processes." raise NotImplementedError def set_child_watcher(self, watcher): - """XXX""" + """Set the watcher for child processes.""" raise NotImplementedError @@ -361,9 +567,9 @@ def get_event_loop(self): not self._local._set_called and isinstance(threading.current_thread(), threading._MainThread)): self.set_event_loop(self.new_event_loop()) - assert self._local._loop is not None, \ - ('There is no current event loop in thread %r.' % - threading.current_thread().name) + if self._local._loop is None: + raise RuntimeError('There is no current event loop in thread %r.' + % threading.current_thread().name) return self._local._loop def set_event_loop(self, loop): @@ -400,39 +606,42 @@ def _init_event_loop_policy(): def get_event_loop_policy(): - """XXX""" + """Get the current event loop policy.""" if _event_loop_policy is None: _init_event_loop_policy() return _event_loop_policy def set_event_loop_policy(policy): - """XXX""" + """Set the current event loop policy. + + If policy is None, the default policy is restored.""" global _event_loop_policy assert policy is None or isinstance(policy, AbstractEventLoopPolicy) _event_loop_policy = policy def get_event_loop(): - """XXX""" + """Equivalent to calling get_event_loop_policy().get_event_loop().""" return get_event_loop_policy().get_event_loop() def set_event_loop(loop): - """XXX""" + """Equivalent to calling get_event_loop_policy().set_event_loop(loop).""" get_event_loop_policy().set_event_loop(loop) def new_event_loop(): - """XXX""" + """Equivalent to calling get_event_loop_policy().new_event_loop().""" return get_event_loop_policy().new_event_loop() def get_child_watcher(): - """XXX""" + """Equivalent to calling get_event_loop_policy().get_child_watcher().""" return get_event_loop_policy().get_child_watcher() def set_child_watcher(watcher): - """XXX""" + """Equivalent to calling + get_event_loop_policy().set_child_watcher(watcher).""" return get_event_loop_policy().set_child_watcher(watcher) diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py index dd3e718d9a50..166bc8047bfb 100644 --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -7,17 +7,18 @@ import concurrent.futures._base import logging +import reprlib +import sys import traceback +from . import compat from . import events -from .log import logger # States for Future. _PENDING = 'PENDING' _CANCELLED = 'CANCELLED' _FINISHED = 'FINISHED' -# TODO: Do we really want to depend on concurrent.futures internals? Error = concurrent.futures._base.Error CancelledError = concurrent.futures.CancelledError TimeoutError = concurrent.futures.TimeoutError @@ -27,7 +28,6 @@ class InvalidStateError(Error): """The operation is not allowed in this state.""" - # TODO: Show the future, its state, the method, and the required state. class _TracebackLogger: @@ -58,7 +58,7 @@ class itself, but instead to have a reference to a helper object the Future is collected, and the helper is present, the helper object is also collected, and its __del__() method will log the traceback. When the Future's result() or exception() method is - called (and a helper object is present), it removes the the helper + called (and a helper object is present), it removes the helper object, after calling its clear() method to prevent it from logging. @@ -80,9 +80,11 @@ class itself, but instead to have a reference to a helper object in a discussion about closing files when they are collected. """ - __slots__ = ['exc', 'tb'] + __slots__ = ('loop', 'source_traceback', 'exc', 'tb') - def __init__(self, exc): + def __init__(self, future, exc): + self.loop = future._loop + self.source_traceback = future._source_traceback self.exc = exc self.tb = None @@ -99,8 +101,13 @@ def clear(self): def __del__(self): if self.tb: - logger.error('Future/Task exception was never retrieved:\n%s', - ''.join(self.tb)) + msg = 'Future/Task exception was never retrieved\n' + if self.source_traceback: + src = ''.join(traceback.format_list(self.source_traceback)) + msg += 'Future/Task created at (most recent call last):\n' + msg += '%s\n' % src.rstrip() + msg += ''.join(self.tb).rstrip() + self.loop.call_exception_handler({'message': msg}) class Future: @@ -125,10 +132,12 @@ class Future: _result = None _exception = None _loop = None + _source_traceback = None _blocking = False # proper use of future (yield vs yield from) - _tb_logger = None + _log_traceback = False # Used for Python 3.4 and later + _tb_logger = None # Used for Python 3.3 only def __init__(self, *, loop=None): """Initialize the future. @@ -142,25 +151,68 @@ def __init__(self, *, loop=None): else: self._loop = loop self._callbacks = [] - - def __repr__(self): - res = self.__class__.__name__ + if self._loop.get_debug(): + self._source_traceback = traceback.extract_stack(sys._getframe(1)) + + def _format_callbacks(self): + cb = self._callbacks + size = len(cb) + if not size: + cb = '' + + def format_cb(callback): + return events._format_callback_source(callback, ()) + + if size == 1: + cb = format_cb(cb[0]) + elif size == 2: + cb = '{}, {}'.format(format_cb(cb[0]), format_cb(cb[1])) + elif size > 2: + cb = '{}, <{} more>, {}'.format(format_cb(cb[0]), + size-2, + format_cb(cb[-1])) + return 'cb=[%s]' % cb + + def _repr_info(self): + info = [self._state.lower()] if self._state == _FINISHED: if self._exception is not None: - res += '<exception={!r}>'.format(self._exception) + info.append('exception={!r}'.format(self._exception)) else: - res += '<result={!r}>'.format(self._result) - elif self._callbacks: - size = len(self._callbacks) - if size > 2: - res += '<{}, [{}, <{} more>, {}]>'.format( - self._state, self._callbacks[0], - size-2, self._callbacks[-1]) - else: - res += '<{}, {}>'.format(self._state, self._callbacks) - else: - res += '<{}>'.format(self._state) - return res + # use reprlib to limit the length of the output, especially + # for very long strings + result = reprlib.repr(self._result) + info.append('result={}'.format(result)) + if self._callbacks: + info.append(self._format_callbacks()) + if self._source_traceback: + frame = self._source_traceback[-1] + info.append('created at %s:%s' % (frame[0], frame[1])) + return info + + def __repr__(self): + info = self._repr_info() + return '<%s %s>' % (self.__class__.__name__, ' '.join(info)) + + # On Python 3.3 and older, objects with a destructor part of a reference + # cycle are never destroyed. It's not more the case on Python 3.4 thanks + # to the PEP 442. + if compat.PY34: + def __del__(self): + if not self._log_traceback: + # set_exception() was not called, or result() or exception() + # has consumed the exception + return + exc = self._exception + context = { + 'message': ('%s exception was never retrieved' + % self.__class__.__name__), + 'exception': exc, + 'future': self, + } + if self._source_traceback: + context['source_traceback'] = self._source_traceback + self._loop.call_exception_handler(context) def cancel(self): """Cancel the future and schedule callbacks. @@ -214,6 +266,7 @@ def result(self): raise CancelledError if self._state != _FINISHED: raise InvalidStateError('Result is not ready.') + self._log_traceback = False if self._tb_logger is not None: self._tb_logger.clear() self._tb_logger = None @@ -233,6 +286,7 @@ def exception(self): raise CancelledError if self._state != _FINISHED: raise InvalidStateError('Exception is not set.') + self._log_traceback = False if self._tb_logger is not None: self._tb_logger.clear() self._tb_logger = None @@ -265,6 +319,12 @@ def remove_done_callback(self, fn): # So-called internal methods (note: no set_running_or_notify_cancel()). + def _set_result_unless_cancelled(self, result): + """Helper setting the result only if the future was not cancelled.""" + if self.cancelled(): + return + self.set_result(result) + def set_result(self, result): """Mark the future done and set its result. @@ -285,13 +345,18 @@ def set_exception(self, exception): """ if self._state != _PENDING: raise InvalidStateError('{}: {!r}'.format(self._state, self)) + if isinstance(exception, type): + exception = exception() self._exception = exception - self._tb_logger = _TracebackLogger(exception) self._state = _FINISHED self._schedule_callbacks() - # Arrange for the logger to be activated after all callbacks - # have had a chance to call result() or exception(). - self._loop.call_soon(self._tb_logger.activate) + if compat.PY34: + self._log_traceback = True + else: + self._tb_logger = _TracebackLogger(self, exception) + # Arrange for the logger to be activated after all callbacks + # have had a chance to call result() or exception(). + self._loop.call_soon(self._tb_logger.activate) # Truly internal methods. @@ -321,23 +386,68 @@ def __iter__(self): assert self.done(), "yield from wasn't used with future" return self.result() # May raise too. + if compat.PY35: + __await__ = __iter__ # make compatible with 'await' expression -def wrap_future(fut, *, loop=None): - """Wrap concurrent.futures.Future object.""" - if isinstance(fut, Future): - return fut - assert isinstance(fut, concurrent.futures.Future), \ - 'concurrent.futures.Future is expected, got {!r}'.format(fut) - if loop is None: - loop = events.get_event_loop() - new_future = Future(loop=loop) - def _check_cancel_other(f): - if f.cancelled(): - fut.cancel() +def _set_concurrent_future_state(concurrent, source): + """Copy state from a future to a concurrent.futures.Future.""" + assert source.done() + if source.cancelled(): + concurrent.cancel() + if not concurrent.set_running_or_notify_cancel(): + return + exception = source.exception() + if exception is not None: + concurrent.set_exception(exception) + else: + result = source.result() + concurrent.set_result(result) + - new_future.add_done_callback(_check_cancel_other) - fut.add_done_callback( - lambda future: loop.call_soon_threadsafe( - new_future._copy_state, fut)) +def _chain_future(source, destination): + """Chain two futures so that when one completes, so does the other. + + The result (or exception) of source will be copied to destination. + If destination is cancelled, source gets cancelled too. + Compatible with both asyncio.Future and concurrent.futures.Future. + """ + if not isinstance(source, (Future, concurrent.futures.Future)): + raise TypeError('A future is required for source argument') + if not isinstance(destination, (Future, concurrent.futures.Future)): + raise TypeError('A future is required for destination argument') + source_loop = source._loop if isinstance(source, Future) else None + dest_loop = destination._loop if isinstance(destination, Future) else None + + def _set_state(future, other): + if isinstance(future, Future): + future._copy_state(other) + else: + _set_concurrent_future_state(future, other) + + def _call_check_cancel(destination): + if destination.cancelled(): + if source_loop is None or source_loop is dest_loop: + source.cancel() + else: + source_loop.call_soon_threadsafe(source.cancel) + + def _call_set_state(source): + if dest_loop is None or dest_loop is source_loop: + _set_state(destination, source) + else: + dest_loop.call_soon_threadsafe(_set_state, destination, source) + + destination.add_done_callback(_call_check_cancel) + source.add_done_callback(_call_set_state) + + +def wrap_future(future, *, loop=None): + """Wrap concurrent.futures.Future object.""" + if isinstance(future, Future): + return future + assert isinstance(future, concurrent.futures.Future), \ + 'concurrent.futures.Future is expected, got {!r}'.format(future) + new_future = Future(loop=loop) + _chain_future(future, new_future) return new_future diff --git a/Lib/asyncio/locks.py b/Lib/asyncio/locks.py index 6cd6779e48f4..34f6bc16ad87 100644 --- a/Lib/asyncio/locks.py +++ b/Lib/asyncio/locks.py @@ -4,12 +4,89 @@ import collections +from . import compat from . import events from . import futures -from . import tasks +from .coroutines import coroutine -class Lock: +class _ContextManager: + """Context manager. + + This enables the following idiom for acquiring and releasing a + lock around a block: + + with (yield from lock): + <block> + + while failing loudly when accidentally using: + + with lock: + <block> + """ + + def __init__(self, lock): + self._lock = lock + + def __enter__(self): + # We have no use for the "as ..." clause in the with + # statement for locks. + return None + + def __exit__(self, *args): + try: + self._lock.release() + finally: + self._lock = None # Crudely prevent reuse. + + +class _ContextManagerMixin: + def __enter__(self): + raise RuntimeError( + '"yield from" should be used as context manager expression') + + def __exit__(self, *args): + # This must exist because __enter__ exists, even though that + # always raises; that's how the with-statement works. + pass + + @coroutine + def __iter__(self): + # This is not a coroutine. It is meant to enable the idiom: + # + # with (yield from lock): + # <block> + # + # as an alternative to: + # + # yield from lock.acquire() + # try: + # <block> + # finally: + # lock.release() + yield from self.acquire() + return _ContextManager(self) + + if compat.PY35: + + def __await__(self): + # To make "with await lock" work. + yield from self.acquire() + return _ContextManager(self) + + @coroutine + def __aenter__(self): + yield from self.acquire() + # We have no use for the "as ..." clause in the with + # statement for locks. + return None + + @coroutine + def __aexit__(self, exc_type, exc, tb): + self.release() + + +class Lock(_ContextManagerMixin): """Primitive lock objects. A primitive lock is a synchronization primitive that is not owned @@ -33,7 +110,7 @@ class Lock: acquire() is a coroutine and should be called with 'yield from'. - Locks also support the context manager protocol. '(yield from lock)' + Locks also support the context management protocol. '(yield from lock)' should be used as context manager expression. Usage: @@ -82,7 +159,7 @@ def locked(self): """Return True if lock is acquired.""" return self._locked - @tasks.coroutine + @coroutine def acquire(self): """Acquire a lock. @@ -123,22 +200,9 @@ def release(self): else: raise RuntimeError('Lock is not acquired.') - def __enter__(self): - if not self._locked: - raise RuntimeError( - '"yield from" should be used as context manager expression') - return True - - def __exit__(self, *args): - self.release() - - def __iter__(self): - yield from self.acquire() - return self - class Event: - """An Event implementation, asynchronous equivalent to threading.Event. + """Asynchronous equivalent to threading.Event. Class implementing event objects. An event manages a flag that can be set to true with the set() method and reset to false with the clear() method. @@ -183,7 +247,7 @@ def clear(self): to true again.""" self._value = False - @tasks.coroutine + @coroutine def wait(self): """Block until the internal flag is true. @@ -203,8 +267,8 @@ def wait(self): self._waiters.remove(fut) -class Condition: - """A Condition implementation, asynchronous equivalent to threading.Condition. +class Condition(_ContextManagerMixin): + """Asynchronous equivalent to threading.Condition. This class implements condition variable objects. A condition variable allows one or more coroutines to wait until they are notified by another @@ -213,14 +277,17 @@ class Condition: A new Lock object is created and used as the underlying lock. """ - def __init__(self, *, loop=None): + def __init__(self, lock=None, *, loop=None): if loop is not None: self._loop = loop else: self._loop = events.get_event_loop() - # Lock as an attribute as in threading.Condition. - lock = Lock(loop=self._loop) + if lock is None: + lock = Lock(loop=self._loop) + elif lock._loop is not self._loop: + raise ValueError("loop argument must agree with lock") + self._lock = lock # Export the lock's locked(), acquire() and release() methods. self.locked = lock.locked @@ -236,7 +303,7 @@ def __repr__(self): extra = '{},waiters:{}'.format(extra, len(self._waiters)) return '<{} [{}]>'.format(res[1:-1], extra) - @tasks.coroutine + @coroutine def wait(self): """Wait until notified. @@ -251,7 +318,6 @@ def wait(self): if not self.locked(): raise RuntimeError('cannot wait on un-acquired lock') - keep_lock = True self.release() try: fut = futures.Future(loop=self._loop) @@ -262,14 +328,10 @@ def wait(self): finally: self._waiters.remove(fut) - except GeneratorExit: - keep_lock = False # Prevent yield in finally clause. - raise finally: - if keep_lock: - yield from self.acquire() + yield from self.acquire() - @tasks.coroutine + @coroutine def wait_for(self, predicate): """Wait until a predicate becomes true. @@ -315,18 +377,8 @@ def notify_all(self): """ self.notify(len(self._waiters)) - def __enter__(self): - return self._lock.__enter__() - - def __exit__(self, *args): - return self._lock.__exit__(*args) - - def __iter__(self): - yield from self.acquire() - return self - -class Semaphore: +class Semaphore(_ContextManagerMixin): """A Semaphore implementation. A semaphore manages an internal counter which is decremented by each @@ -334,7 +386,7 @@ class Semaphore: can never go below zero; when acquire() finds that it is zero, it blocks, waiting until some other thread calls release(). - Semaphores also support the context manager protocol. + Semaphores also support the context management protocol. The optional argument gives the initial value for the internal counter; it defaults to 1. If the value given is less than 0, @@ -346,7 +398,6 @@ def __init__(self, value=1, *, loop=None): raise ValueError("Semaphore initial value must be >= 0") self._value = value self._waiters = collections.deque() - self._locked = (value == 0) if loop is not None: self._loop = loop else: @@ -354,17 +405,24 @@ def __init__(self, value=1, *, loop=None): def __repr__(self): res = super().__repr__() - extra = 'locked' if self._locked else 'unlocked,value:{}'.format( + extra = 'locked' if self.locked() else 'unlocked,value:{}'.format( self._value) if self._waiters: extra = '{},waiters:{}'.format(extra, len(self._waiters)) return '<{} [{}]>'.format(res[1:-1], extra) + def _wake_up_next(self): + while self._waiters: + waiter = self._waiters.popleft() + if not waiter.done(): + waiter.set_result(None) + return + def locked(self): """Returns True if semaphore can not be acquired immediately.""" - return self._locked + return self._value == 0 - @tasks.coroutine + @coroutine def acquire(self): """Acquire a semaphore. @@ -374,22 +432,19 @@ def acquire(self): called release() to make it larger than 0, and then return True. """ - if not self._waiters and self._value > 0: - self._value -= 1 - if self._value == 0: - self._locked = True - return True - - fut = futures.Future(loop=self._loop) - self._waiters.append(fut) - try: - yield from fut - self._value -= 1 - if self._value == 0: - self._locked = True - return True - finally: - self._waiters.remove(fut) + while self._value <= 0: + fut = futures.Future(loop=self._loop) + self._waiters.append(fut) + try: + yield from fut + except: + # See the similar code in Queue.get. + fut.cancel() + if self._value > 0 and not fut.cancelled(): + self._wake_up_next() + raise + self._value -= 1 + return True def release(self): """Release a semaphore, incrementing the internal counter by one. @@ -397,23 +452,7 @@ def release(self): become larger than zero again, wake up that coroutine. """ self._value += 1 - self._locked = False - for waiter in self._waiters: - if not waiter.done(): - waiter.set_result(True) - break - - def __enter__(self): - # TODO: This is questionable. How do we know the user actually - # wrote "with (yield from sema)" instead of "with sema"? - return True - - def __exit__(self, *args): - self.release() - - def __iter__(self): - yield from self.acquire() - return self + self._wake_up_next() class BoundedSemaphore(Semaphore): diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index ce226b9ba50d..abe4c129c9bd 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -4,37 +4,63 @@ proactor is only implemented on Windows with IOCP. """ +__all__ = ['BaseProactorEventLoop'] + import socket +import warnings from . import base_events +from . import compat from . import constants from . import futures +from . import sslproto from . import transports from .log import logger -class _ProactorBasePipeTransport(transports.BaseTransport): +class _ProactorBasePipeTransport(transports._FlowControlMixin, + transports.BaseTransport): """Base class for pipe and socket transports.""" def __init__(self, loop, sock, protocol, waiter=None, extra=None, server=None): - super().__init__(extra) + super().__init__(extra, loop) self._set_extra(sock) - self._loop = loop self._sock = sock self._protocol = protocol self._server = server - self._buffer = [] + self._buffer = None # None or bytearray. self._read_fut = None self._write_fut = None + self._pending_write = 0 self._conn_lost = 0 self._closing = False # Set when close() called. self._eof_written = False if self._server is not None: - self._server.attach(self) + self._server._attach() self._loop.call_soon(self._protocol.connection_made, self) if waiter is not None: - self._loop.call_soon(waiter.set_result, None) + # only wake up the waiter when connection_made() has been called + self._loop.call_soon(waiter._set_result_unless_cancelled, None) + + def __repr__(self): + info = [self.__class__.__name__] + if self._sock is None: + info.append('closed') + elif self._closing: + info.append('closing') + if self._sock is not None: + info.append('fd=%s' % self._sock.fileno()) + if self._read_fut is not None: + info.append('read=%s' % self._read_fut) + if self._write_fut is not None: + info.append("write=%r" % self._write_fut) + if self._buffer: + bufsize = len(self._buffer) + info.append('write_bufsize=%s' % bufsize) + if self._eof_written: + info.append('EOF written') + return '<%s>' % ' '.join(info) def _set_extra(self, sock): self._extra['pipe'] = sock @@ -48,9 +74,28 @@ def close(self): self._loop.call_soon(self._call_connection_lost, None) if self._read_fut is not None: self._read_fut.cancel() - - def _fatal_error(self, exc): - logger.exception('Fatal error for %s', self) + self._read_fut = None + + # On Python 3.3 and older, objects with a destructor part of a reference + # cycle are never destroyed. It's not more the case on Python 3.4 thanks + # to the PEP 442. + if compat.PY34: + def __del__(self): + if self._sock is not None: + warnings.warn("unclosed transport %r" % self, ResourceWarning) + self.close() + + def _fatal_error(self, exc, message='Fatal error on pipe transport'): + if isinstance(exc, (BrokenPipeError, ConnectionResetError)): + if self._loop.get_debug(): + logger.debug("%r: %s", self, message, exc_info=True) + else: + self._loop.call_exception_handler({ + 'message': message, + 'exception': exc, + 'transport': self, + 'protocol': self._protocol, + }) self._force_close(exc) def _force_close(self, exc): @@ -60,10 +105,12 @@ def _force_close(self, exc): self._conn_lost += 1 if self._write_fut: self._write_fut.cancel() + self._write_fut = None if self._read_fut: self._read_fut.cancel() - self._write_fut = self._read_fut = None - self._buffer = [] + self._read_fut = None + self._pending_write = 0 + self._buffer = None self._loop.call_soon(self._call_connection_lost, exc) def _call_connection_lost(self, exc): @@ -77,11 +124,18 @@ def _call_connection_lost(self, exc): if hasattr(self._sock, 'shutdown'): self._sock.shutdown(socket.SHUT_RDWR) self._sock.close() + self._sock = None server = self._server if server is not None: - server.detach(self) + server._detach() self._server = None + def get_write_buffer_size(self): + size = self._pending_write + if self._buffer is not None: + size += len(self._buffer) + return size + class _ProactorReadPipeTransport(_ProactorBasePipeTransport, transports.ReadTransport): @@ -90,21 +144,27 @@ class _ProactorReadPipeTransport(_ProactorBasePipeTransport, def __init__(self, loop, sock, protocol, waiter=None, extra=None, server=None): super().__init__(loop, sock, protocol, waiter, extra, server) - self._read_fut = None self._paused = False self._loop.call_soon(self._loop_reading) def pause_reading(self): - assert not self._closing, 'Cannot pause_reading() when closing' - assert not self._paused, 'Already paused' + if self._closing: + raise RuntimeError('Cannot pause_reading() when closing') + if self._paused: + raise RuntimeError('Already paused') self._paused = True + if self._loop.get_debug(): + logger.debug("%r pauses reading", self) def resume_reading(self): - assert self._paused, 'Not paused' + if not self._paused: + raise RuntimeError('Not paused') self._paused = False if self._closing: return self._loop.call_soon(self._loop_reading, self._read_fut) + if self._loop.get_debug(): + logger.debug("%r resumes reading", self) def _loop_reading(self, fut=None): if self._paused: @@ -131,11 +191,14 @@ def _loop_reading(self, fut=None): self._read_fut = self._loop._proactor.recv(self._sock, 4096) except ConnectionAbortedError as exc: if not self._closing: - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal read error on pipe transport') + elif self._loop.get_debug(): + logger.debug("Read error on pipe transport while closing", + exc_info=True) except ConnectionResetError as exc: self._force_close(exc) except OSError as exc: - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal read error on pipe transport') except futures.CancelledError: if not self._closing: raise @@ -145,19 +208,23 @@ def _loop_reading(self, fut=None): if data: self._protocol.data_received(data) elif data is not None: + if self._loop.get_debug(): + logger.debug("%r received EOF", self) keep_open = self._protocol.eof_received() if not keep_open: self.close() -class _ProactorWritePipeTransport(_ProactorBasePipeTransport, - transports.WriteTransport): +class _ProactorBaseWritePipeTransport(_ProactorBasePipeTransport, + transports.WriteTransport): """Transport for write pipes.""" def write(self, data): - assert isinstance(data, bytes), repr(data) + if not isinstance(data, (bytes, bytearray, memoryview)): + raise TypeError('data argument must be byte-ish (%r)', + type(data)) if self._eof_written: - raise IOError('write_eof() already called') + raise RuntimeError('write_eof() already called') if not data: return @@ -167,30 +234,60 @@ def write(self, data): logger.warning('socket.send() raised exception.') self._conn_lost += 1 return - self._buffer.append(data) - if self._write_fut is None: - self._loop_writing() - def _loop_writing(self, f=None): + # Observable states: + # 1. IDLE: _write_fut and _buffer both None + # 2. WRITING: _write_fut set; _buffer None + # 3. BACKED UP: _write_fut set; _buffer a bytearray + # We always copy the data, so the caller can't modify it + # while we're still waiting for the I/O to happen. + if self._write_fut is None: # IDLE -> WRITING + assert self._buffer is None + # Pass a copy, except if it's already immutable. + self._loop_writing(data=bytes(data)) + elif not self._buffer: # WRITING -> BACKED UP + # Make a mutable copy which we can extend. + self._buffer = bytearray(data) + self._maybe_pause_protocol() + else: # BACKED UP + # Append to buffer (also copies). + self._buffer.extend(data) + self._maybe_pause_protocol() + + def _loop_writing(self, f=None, data=None): try: assert f is self._write_fut self._write_fut = None + self._pending_write = 0 if f: f.result() - data = b''.join(self._buffer) - self._buffer = [] + if data is None: + data = self._buffer + self._buffer = None if not data: if self._closing: self._loop.call_soon(self._call_connection_lost, None) if self._eof_written: self._sock.shutdown(socket.SHUT_WR) - return - self._write_fut = self._loop._proactor.send(self._sock, data) - self._write_fut.add_done_callback(self._loop_writing) + # Now that we've reduced the buffer size, tell the + # protocol to resume writing if it was paused. Note that + # we do this last since the callback is called immediately + # and it may add more data to the buffer (even causing the + # protocol to be paused again). + self._maybe_resume_protocol() + else: + self._write_fut = self._loop._proactor.send(self._sock, data) + if not self._write_fut.done(): + assert self._pending_write == 0 + self._pending_write = len(data) + self._write_fut.add_done_callback(self._loop_writing) + self._maybe_pause_protocol() + else: + self._write_fut.add_done_callback(self._loop_writing) except ConnectionResetError as exc: self._force_close(exc) except OSError as exc: - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal write error on pipe transport') def can_write_eof(self): return True @@ -202,8 +299,30 @@ def abort(self): self._force_close(None) +class _ProactorWritePipeTransport(_ProactorBaseWritePipeTransport): + def __init__(self, *args, **kw): + super().__init__(*args, **kw) + self._read_fut = self._loop._proactor.recv(self._sock, 16) + self._read_fut.add_done_callback(self._pipe_closed) + + def _pipe_closed(self, fut): + if fut.cancelled(): + # the transport has been closed + return + assert fut.result() == b'' + if self._closing: + assert self._read_fut is None + return + assert fut is self._read_fut, (fut, self._read_fut) + self._read_fut = None + if self._write_fut is not None: + self._force_close(BrokenPipeError()) + else: + self.close() + + class _ProactorDuplexPipeTransport(_ProactorReadPipeTransport, - _ProactorWritePipeTransport, + _ProactorBaseWritePipeTransport, transports.Transport): """Transport for duplex pipes.""" @@ -215,7 +334,7 @@ def write_eof(self): class _ProactorSocketTransport(_ProactorReadPipeTransport, - _ProactorWritePipeTransport, + _ProactorBaseWritePipeTransport, transports.Transport): """Transport for connected sockets.""" @@ -224,12 +343,16 @@ def _set_extra(self, sock): try: self._extra['sockname'] = sock.getsockname() except (socket.error, AttributeError): - pass + if self._loop.get_debug(): + logger.warning("getsockname() failed on %r", + sock, exc_info=True) if 'peername' not in self._extra: try: self._extra['peername'] = sock.getpeername() except (socket.error, AttributeError): - pass + if self._loop.get_debug(): + logger.warning("getpeername() failed on %r", + sock, exc_info=True) def can_write_eof(self): return True @@ -249,6 +372,8 @@ def __init__(self, proactor): logger.debug('Using proactor: %s', proactor.__class__.__name__) self._proactor = proactor self._selector = proactor # convenient alias + self._self_reading_future = None + self._accept_futures = {} # socket file descriptor => Future proactor.set_loop(self) self._make_self_pipe() @@ -257,6 +382,20 @@ def _make_socket_transport(self, sock, protocol, waiter=None, return _ProactorSocketTransport(self, sock, protocol, waiter, extra, server) + def _make_ssl_transport(self, rawsock, protocol, sslcontext, waiter=None, + *, server_side=False, server_hostname=None, + extra=None, server=None): + if not sslproto._is_sslproto_available(): + raise NotImplementedError("Proactor event loop requires Python 3.5" + " or newer (ssl.MemoryBIO) to support " + "SSL") + + ssl_protocol = sslproto.SSLProtocol(self, protocol, sslcontext, waiter, + server_side, server_hostname) + _ProactorSocketTransport(self, rawsock, ssl_protocol, + extra=extra, server=server) + return ssl_protocol._app_transport + def _make_duplex_pipe_transport(self, sock, protocol, waiter=None, extra=None): return _ProactorDuplexPipeTransport(self, @@ -267,23 +406,28 @@ def _make_read_pipe_transport(self, sock, protocol, waiter=None, return _ProactorReadPipeTransport(self, sock, protocol, waiter, extra) def _make_write_pipe_transport(self, sock, protocol, waiter=None, - extra=None, check_for_hangup=True): - if check_for_hangup: - # We want connection_lost() to be called when other end closes - return _ProactorDuplexPipeTransport(self, - sock, protocol, waiter, extra) - else: - # If other end closes we may not notice for a long time - return _ProactorWritePipeTransport(self, sock, protocol, waiter, - extra) + extra=None): + # We want connection_lost() to be called when other end closes + return _ProactorWritePipeTransport(self, + sock, protocol, waiter, extra) def close(self): - if self._proactor is not None: - self._close_self_pipe() - self._proactor.close() - self._proactor = None - self._selector = None - super().close() + if self.is_running(): + raise RuntimeError("Cannot close a running event loop") + if self.is_closed(): + return + + # Call these methods before closing the event loop (before calling + # BaseEventLoop.close), because they can schedule callbacks with + # call_soon(), which is forbidden when the event loop is closed. + self._stop_accept_futures() + self._close_self_pipe() + self._proactor.close() + self._proactor = None + self._selector = None + + # Close the event loop + super().close() def sock_recv(self, sock, n): return self._proactor.recv(sock, n) @@ -292,7 +436,15 @@ def sock_sendall(self, sock, data): return self._proactor.send(sock, data) def sock_connect(self, sock, address): - return self._proactor.connect(sock, address) + try: + if self._debug: + base_events._check_resolved_address(sock, address) + except ValueError as err: + fut = futures.Future(loop=self) + fut.set_exception(err) + return fut + else: + return self._proactor.connect(sock, address) def sock_accept(self, sock): return self._proactor.accept(sock) @@ -301,6 +453,9 @@ def _socketpair(self): raise NotImplementedError def _close_self_pipe(self): + if self._self_reading_future is not None: + self._self_reading_future.cancel() + self._self_reading_future = None self._ssock.close() self._ssock = None self._csock.close() @@ -320,41 +475,73 @@ def _loop_self_reading(self, f=None): if f is not None: f.result() # may raise f = self._proactor.recv(self._ssock, 4096) - except: - self.close() - raise + except futures.CancelledError: + # _close_self_pipe() has been called, stop waiting for data + return + except Exception as exc: + self.call_exception_handler({ + 'message': 'Error on reading from the event loop self pipe', + 'exception': exc, + 'loop': self, + }) else: + self._self_reading_future = f f.add_done_callback(self._loop_self_reading) def _write_to_self(self): - self._csock.send(b'x') + self._csock.send(b'\0') - def _start_serving(self, protocol_factory, sock, ssl=None, server=None): - assert not ssl, 'IocpEventLoop is incompatible with SSL.' + def _start_serving(self, protocol_factory, sock, + sslcontext=None, server=None): def loop(f=None): try: if f is not None: conn, addr = f.result() + if self._debug: + logger.debug("%r got a new connection from %r: %r", + server, addr, conn) protocol = protocol_factory() - self._make_socket_transport( - conn, protocol, - extra={'peername': addr}, server=server) + if sslcontext is not None: + self._make_ssl_transport( + conn, protocol, sslcontext, server_side=True, + extra={'peername': addr}, server=server) + else: + self._make_socket_transport( + conn, protocol, + extra={'peername': addr}, server=server) + if self.is_closed(): + return f = self._proactor.accept(sock) - except OSError: + except OSError as exc: if sock.fileno() != -1: - logger.exception('Accept failed') + self.call_exception_handler({ + 'message': 'Accept failed on a socket', + 'exception': exc, + 'socket': sock, + }) sock.close() + elif self._debug: + logger.debug("Accept failed on socket %r", + sock, exc_info=True) except futures.CancelledError: sock.close() else: + self._accept_futures[sock.fileno()] = f f.add_done_callback(loop) self.call_soon(loop) def _process_events(self, event_list): - pass # XXX hard work currently done in poll + # Events are processed in the IocpProactor._poll() method + pass + + def _stop_accept_futures(self): + for future in self._accept_futures.values(): + future.cancel() + self._accept_futures.clear() def _stop_serving(self, sock): + self._stop_accept_futures() self._proactor._stop_serving(sock) sock.close() diff --git a/Lib/asyncio/protocols.py b/Lib/asyncio/protocols.py index 1b8870c6d551..80fcac9a82df 100644 --- a/Lib/asyncio/protocols.py +++ b/Lib/asyncio/protocols.py @@ -1,6 +1,7 @@ """Abstract Protocol class.""" -__all__ = ['Protocol', 'DatagramProtocol'] +__all__ = ['BaseProtocol', 'Protocol', 'DatagramProtocol', + 'SubprocessProtocol'] class BaseProtocol: @@ -77,6 +78,11 @@ class Protocol(BaseProtocol): State machine of calls: start -> CM [-> DR*] [-> ER?] -> CL -> end + + * CM: connection_made() + * DR: data_received() + * ER: eof_received() + * CL: connection_lost() """ def data_received(self, data): @@ -113,7 +119,7 @@ class SubprocessProtocol(BaseProtocol): def pipe_data_received(self, fd, data): """Called when the subprocess writes data into stdout/stderr pipe. - fd is int file dascriptor. + fd is int file descriptor. data is bytes object. """ diff --git a/Lib/asyncio/queues.py b/Lib/asyncio/queues.py index 3f5bf4479e60..e3a1d5ed60e3 100644 --- a/Lib/asyncio/queues.py +++ b/Lib/asyncio/queues.py @@ -1,21 +1,29 @@ """Queues""" -__all__ = ['Queue', 'PriorityQueue', 'LifoQueue', 'JoinableQueue', - 'Full', 'Empty'] +__all__ = ['Queue', 'PriorityQueue', 'LifoQueue', 'QueueFull', 'QueueEmpty'] import collections import heapq -import queue +from . import compat from . import events from . import futures from . import locks -from .tasks import coroutine +from .coroutines import coroutine -# Re-export queue.Full and .Empty exceptions. -Full = queue.Full -Empty = queue.Empty +class QueueEmpty(Exception): + """Exception raised when Queue.get_nowait() is called on a Queue object + which is empty. + """ + pass + + +class QueueFull(Exception): + """Exception raised when the Queue.put_nowait() method is called on a Queue + object which is full. + """ + pass class Queue: @@ -26,7 +34,7 @@ class Queue: queue reaches maxsize, until an item is removed by get(). Unlike the standard library Queue, you can reliably know this Queue's size - with qsize(), since your single-threaded Tulip application won't be + with qsize(), since your single-threaded asyncio application won't be interrupted between calling qsize() and doing an operation on the Queue. """ @@ -39,10 +47,15 @@ def __init__(self, maxsize=0, *, loop=None): # Futures. self._getters = collections.deque() - # Pairs of (item, Future). + # Futures. self._putters = collections.deque() + self._unfinished_tasks = 0 + self._finished = locks.Event(loop=self._loop) + self._finished.set() self._init(maxsize) + # These three are overridable in subclasses. + def _init(self, maxsize): self._queue = collections.deque() @@ -52,6 +65,16 @@ def _get(self): def _put(self, item): self._queue.append(item) + # End of the overridable methods. + + def _wakeup_next(self, waiters): + # Wake up the next waiter (if any) that isn't cancelled. + while waiters: + waiter = waiters.popleft() + if not waiter.done(): + waiter.set_result(None) + break + def __repr__(self): return '<{} at {:#x} {}>'.format( type(self).__name__, id(self), self._format()) @@ -67,18 +90,10 @@ def _format(self): result += ' _getters[{}]'.format(len(self._getters)) if self._putters: result += ' _putters[{}]'.format(len(self._putters)) + if self._unfinished_tasks: + result += ' tasks={}'.format(self._unfinished_tasks) return result - def _consume_done_getters(self): - # Delete waiters at the head of the get() queue who've timed out. - while self._getters and self._getters[0].done(): - self._getters.popleft() - - def _consume_done_putters(self): - # Delete waiters at the head of the put() queue who've timed out. - while self._putters and self._putters[0][1].done(): - self._putters.popleft() - def qsize(self): """Number of items in the queue.""" return len(self._queue) @@ -101,105 +116,107 @@ def full(self): if self._maxsize <= 0: return False else: - return self.qsize() == self._maxsize + return self.qsize() >= self._maxsize @coroutine def put(self, item): """Put an item into the queue. - If you yield from put(), wait until a free slot is available - before adding item. - """ - self._consume_done_getters() - if self._getters: - assert not self._queue, ( - 'queue non-empty, why are getters waiting?') - - getter = self._getters.popleft() - - # Use _put and _get instead of passing item straight to getter, in - # case a subclass has logic that must run (e.g. JoinableQueue). - self._put(item) - getter.set_result(self._get()) - - elif self._maxsize > 0 and self._maxsize == self.qsize(): - waiter = futures.Future(loop=self._loop) - - self._putters.append((item, waiter)) - yield from waiter + Put an item into the queue. If the queue is full, wait until a free + slot is available before adding item. - else: - self._put(item) + This method is a coroutine. + """ + while self.full(): + putter = futures.Future(loop=self._loop) + self._putters.append(putter) + try: + yield from putter + except: + putter.cancel() # Just in case putter is not done yet. + if not self.full() and not putter.cancelled(): + # We were woken up by get_nowait(), but can't take + # the call. Wake up the next in line. + self._wakeup_next(self._putters) + raise + return self.put_nowait(item) def put_nowait(self, item): """Put an item into the queue without blocking. - If no free slot is immediately available, raise Full. + If no free slot is immediately available, raise QueueFull. """ - self._consume_done_getters() - if self._getters: - assert not self._queue, ( - 'queue non-empty, why are getters waiting?') - - getter = self._getters.popleft() - - # Use _put and _get instead of passing item straight to getter, in - # case a subclass has logic that must run (e.g. JoinableQueue). - self._put(item) - getter.set_result(self._get()) - - elif self._maxsize > 0 and self._maxsize == self.qsize(): - raise Full - else: - self._put(item) + if self.full(): + raise QueueFull + self._put(item) + self._unfinished_tasks += 1 + self._finished.clear() + self._wakeup_next(self._getters) @coroutine def get(self): """Remove and return an item from the queue. - If you yield from get(), wait until a item is available. + If queue is empty, wait until an item is available. + + This method is a coroutine. """ - self._consume_done_putters() - if self._putters: - assert self.full(), 'queue not full, why are putters waiting?' - item, putter = self._putters.popleft() - self._put(item) + while self.empty(): + getter = futures.Future(loop=self._loop) + self._getters.append(getter) + try: + yield from getter + except: + getter.cancel() # Just in case getter is not done yet. + if not self.empty() and not getter.cancelled(): + # We were woken up by put_nowait(), but can't take + # the call. Wake up the next in line. + self._wakeup_next(self._getters) + raise + return self.get_nowait() - # When a getter runs and frees up a slot so this putter can - # run, we need to defer the put for a tick to ensure that - # getters and putters alternate perfectly. See - # ChannelTest.test_wait. - self._loop.call_soon(putter.set_result, None) + def get_nowait(self): + """Remove and return an item from the queue. - return self._get() + Return an item if one is immediately available, else raise QueueEmpty. + """ + if self.empty(): + raise QueueEmpty + item = self._get() + self._wakeup_next(self._putters) + return item - elif self.qsize(): - return self._get() - else: - waiter = futures.Future(loop=self._loop) + def task_done(self): + """Indicate that a formerly enqueued task is complete. - self._getters.append(waiter) - return (yield from waiter) + Used by queue consumers. For each get() used to fetch a task, + a subsequent call to task_done() tells the queue that the processing + on the task is complete. - def get_nowait(self): - """Remove and return an item from the queue. + If a join() is currently blocking, it will resume when all items have + been processed (meaning that a task_done() call was received for every + item that had been put() into the queue). - Return an item if one is immediately available, else raise Empty. + Raises ValueError if called more times than there were items placed in + the queue. """ - self._consume_done_putters() - if self._putters: - assert self.full(), 'queue not full, why are putters waiting?' - item, putter = self._putters.popleft() - self._put(item) - # Wake putter on next tick. - putter.set_result(None) + if self._unfinished_tasks <= 0: + raise ValueError('task_done() called too many times') + self._unfinished_tasks -= 1 + if self._unfinished_tasks == 0: + self._finished.set() - return self._get() + @coroutine + def join(self): + """Block until all items in the queue have been gotten and processed. - elif self.qsize(): - return self._get() - else: - raise Empty + The count of unfinished tasks goes up whenever an item is added to the + queue. The count goes down whenever a consumer calls task_done() to + indicate that the item was retrieved and all work on it is complete. + When the count of unfinished tasks drops to zero, join() unblocks. + """ + if self._unfinished_tasks > 0: + yield from self._finished.wait() class PriorityQueue(Queue): @@ -231,54 +248,7 @@ def _get(self): return self._queue.pop() -class JoinableQueue(Queue): - """A subclass of Queue with task_done() and join() methods.""" - - def __init__(self, maxsize=0, *, loop=None): - super().__init__(maxsize=maxsize, loop=loop) - self._unfinished_tasks = 0 - self._finished = locks.Event(loop=self._loop) - self._finished.set() - - def _format(self): - result = Queue._format(self) - if self._unfinished_tasks: - result += ' tasks={}'.format(self._unfinished_tasks) - return result - - def _put(self, item): - super()._put(item) - self._unfinished_tasks += 1 - self._finished.clear() - - def task_done(self): - """Indicate that a formerly enqueued task is complete. - - Used by queue consumers. For each get() used to fetch a task, - a subsequent call to task_done() tells the queue that the processing - on the task is complete. - - If a join() is currently blocking, it will resume when all items have - been processed (meaning that a task_done() call was received for every - item that had been put() into the queue). - - Raises ValueError if called more times than there were items placed in - the queue. - """ - if self._unfinished_tasks <= 0: - raise ValueError('task_done() called too many times') - self._unfinished_tasks -= 1 - if self._unfinished_tasks == 0: - self._finished.set() - - @coroutine - def join(self): - """Block until all items in the queue have been gotten and processed. - - The count of unfinished tasks goes up whenever an item is added to the - queue. The count goes down whenever a consumer thread calls task_done() - to indicate that the item was retrieved and all work on it is complete. - When the count of unfinished tasks drops to zero, join() unblocks. - """ - if self._unfinished_tasks > 0: - yield from self._finished.wait() +if not compat.PY35: + JoinableQueue = Queue + """Deprecated alias for Queue.""" + __all__.append('JoinableQueue') diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index 93efddc95a39..0060912219e9 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -4,23 +4,41 @@ also includes support for signal handling, see the unix_events sub-module. """ +__all__ = ['BaseSelectorEventLoop'] + import collections import errno +import functools import socket +import warnings try: import ssl except ImportError: # pragma: no cover ssl = None from . import base_events +from . import compat from . import constants from . import events from . import futures from . import selectors from . import transports +from . import sslproto +from .coroutines import coroutine from .log import logger +def _test_selector_event(selector, fd, event): + # Test if the selector is monitoring 'event' events + # for the file descriptor 'fd'. + try: + key = selector.get_key(fd) + except KeyError: + return False + else: + return bool(key.events & event) + + class BaseSelectorEventLoop(base_events.BaseEventLoop): """Selector event loop. @@ -41,23 +59,46 @@ def _make_socket_transport(self, sock, protocol, waiter=None, *, return _SelectorSocketTransport(self, sock, protocol, waiter, extra, server) - def _make_ssl_transport(self, rawsock, protocol, sslcontext, waiter, *, - server_side=False, server_hostname=None, + def _make_ssl_transport(self, rawsock, protocol, sslcontext, waiter=None, + *, server_side=False, server_hostname=None, extra=None, server=None): + if not sslproto._is_sslproto_available(): + return self._make_legacy_ssl_transport( + rawsock, protocol, sslcontext, waiter, + server_side=server_side, server_hostname=server_hostname, + extra=extra, server=server) + + ssl_protocol = sslproto.SSLProtocol(self, protocol, sslcontext, waiter, + server_side, server_hostname) + _SelectorSocketTransport(self, rawsock, ssl_protocol, + extra=extra, server=server) + return ssl_protocol._app_transport + + def _make_legacy_ssl_transport(self, rawsock, protocol, sslcontext, + waiter, *, + server_side=False, server_hostname=None, + extra=None, server=None): + # Use the legacy API: SSL_write, SSL_read, etc. The legacy API is used + # on Python 3.4 and older, when ssl.MemoryBIO is not available. return _SelectorSslTransport( self, rawsock, protocol, sslcontext, waiter, server_side, server_hostname, extra, server) def _make_datagram_transport(self, sock, protocol, - address=None, extra=None): - return _SelectorDatagramTransport(self, sock, protocol, address, extra) + address=None, waiter=None, extra=None): + return _SelectorDatagramTransport(self, sock, protocol, + address, waiter, extra) def close(self): + if self.is_running(): + raise RuntimeError("Cannot close a running event loop") + if self.is_closed(): + return + self._close_self_pipe() + super().close() if self._selector is not None: - self._close_self_pipe() self._selector.close() self._selector = None - super().close() def _socketpair(self): raise NotImplementedError @@ -78,17 +119,36 @@ def _make_self_pipe(self): self._internal_fds += 1 self.add_reader(self._ssock.fileno(), self._read_from_self) + def _process_self_data(self, data): + pass + def _read_from_self(self): - try: - self._ssock.recv(1) - except (BlockingIOError, InterruptedError): - pass + while True: + try: + data = self._ssock.recv(4096) + if not data: + break + self._process_self_data(data) + except InterruptedError: + continue + except BlockingIOError: + break def _write_to_self(self): - try: - self._csock.send(b'x') - except (BlockingIOError, InterruptedError): - pass + # This may be called from a different thread, possibly after + # _close_self_pipe() has been called or even while it is + # running. Guard for self._csock being None or closed. When + # a socket is closed, send() raises OSError (with errno set to + # EBADF, but let's not rely on the exact error code). + csock = self._csock + if csock is not None: + try: + csock.send(b'\0') + except OSError: + if self._debug: + logger.debug("Fail to write a null byte into the " + "self-pipe socket", + exc_info=True) def _start_serving(self, protocol_factory, sock, sslcontext=None, server=None): @@ -99,18 +159,24 @@ def _accept_connection(self, protocol_factory, sock, sslcontext=None, server=None): try: conn, addr = sock.accept() + if self._debug: + logger.debug("%r got a new connection from %r: %r", + server, addr, conn) conn.setblocking(False) except (BlockingIOError, InterruptedError, ConnectionAbortedError): pass # False alarm. except OSError as exc: # There's nowhere to send the error, so just log it. - # TODO: Someone will want an error handler for this. if exc.errno in (errno.EMFILE, errno.ENFILE, errno.ENOBUFS, errno.ENOMEM): # Some platforms (e.g. Linux keep reporting the FD as # ready, so we remove the read handler temporarily. # We'll try again in a while. - logger.exception('Accept out of system resource (%s)', exc) + self.call_exception_handler({ + 'message': 'socket.accept() out of system resource', + 'exception': exc, + 'socket': sock, + }) self.remove_reader(sock.fileno()) self.call_later(constants.ACCEPT_RETRY_DELAY, self._start_serving, @@ -118,19 +184,52 @@ def _accept_connection(self, protocol_factory, sock, else: raise # The event loop will catch, log and ignore it. else: + extra = {'peername': addr} + accept = self._accept_connection2(protocol_factory, conn, extra, + sslcontext, server) + self.create_task(accept) + + @coroutine + def _accept_connection2(self, protocol_factory, conn, extra, + sslcontext=None, server=None): + protocol = None + transport = None + try: + protocol = protocol_factory() + waiter = futures.Future(loop=self) if sslcontext: - self._make_ssl_transport( - conn, protocol_factory(), sslcontext, None, - server_side=True, extra={'peername': addr}, server=server) + transport = self._make_ssl_transport( + conn, protocol, sslcontext, waiter=waiter, + server_side=True, extra=extra, server=server) else: - self._make_socket_transport( - conn, protocol_factory(), extra={'peername': addr}, + transport = self._make_socket_transport( + conn, protocol, waiter=waiter, extra=extra, server=server) - # It's now up to the protocol to handle the connection. + + try: + yield from waiter + except: + transport.close() + raise + + # It's now up to the protocol to handle the connection. + except Exception as exc: + if self._debug: + context = { + 'message': ('Error on transport creation ' + 'for incoming connection'), + 'exception': exc, + } + if protocol is not None: + context['protocol'] = protocol + if transport is not None: + context['transport'] = transport + self.call_exception_handler(context) def add_reader(self, fd, callback, *args): """Add a reader callback.""" - handle = events.make_handle(callback, args) + self._check_closed() + handle = events.Handle(callback, args, self) try: key = self._selector.get_key(fd) except KeyError: @@ -145,6 +244,8 @@ def add_reader(self, fd, callback, *args): def remove_reader(self, fd): """Remove a reader callback.""" + if self.is_closed(): + return False try: key = self._selector.get_key(fd) except KeyError: @@ -165,7 +266,8 @@ def remove_reader(self, fd): def add_writer(self, fd, callback, *args): """Add a writer callback..""" - handle = events.make_handle(callback, args) + self._check_closed() + handle = events.Handle(callback, args, self) try: key = self._selector.get_key(fd) except KeyError: @@ -180,6 +282,8 @@ def add_writer(self, fd, callback, *args): def remove_writer(self, fd): """Remove a writer callback.""" + if self.is_closed(): + return False try: key = self._selector.get_key(fd) except KeyError: @@ -200,12 +304,23 @@ def remove_writer(self, fd): return False def sock_recv(self, sock, n): - """XXX""" + """Receive data from the socket. + + The return value is a bytes object representing the data received. + The maximum amount of data to be received at once is specified by + nbytes. + + This method is a coroutine. + """ + if self._debug and sock.gettimeout() != 0: + raise ValueError("the socket must be non-blocking") fut = futures.Future(loop=self) self._sock_recv(fut, False, sock, n) return fut def _sock_recv(self, fut, registered, sock, n): + # _sock_recv() can add itself as an I/O callback if the operation can't + # be done immediately. Don't use it directly, call sock_recv(). fd = sock.fileno() if registered: # Remove the callback early. It should be rare that the @@ -225,7 +340,18 @@ def _sock_recv(self, fut, registered, sock, n): fut.set_result(data) def sock_sendall(self, sock, data): - """XXX""" + """Send data to the socket. + + The socket must be connected to a remote socket. This method continues + to send data from data until either all data has been sent or an + error occurs. None is returned on success. On error, an exception is + raised, and there is no way to determine how much data, if any, was + successfully processed by the receiving end of the connection. + + This method is a coroutine. + """ + if self._debug and sock.gettimeout() != 0: + raise ValueError("the socket must be non-blocking") fut = futures.Future(loop=self) if data: self._sock_sendall(fut, False, sock, data) @@ -257,46 +383,77 @@ def _sock_sendall(self, fut, registered, sock, data): self.add_writer(fd, self._sock_sendall, fut, True, sock, data) def sock_connect(self, sock, address): - """XXX""" - # That address better not require a lookup! We're not calling - # self.getaddrinfo() for you here. But verifying this is - # complicated; the socket module doesn't have a pattern for - # IPv6 addresses (there are too many forms, apparently). + """Connect to a remote socket at address. + + The address must be already resolved to avoid the trap of hanging the + entire event loop when the address requires doing a DNS lookup. For + example, it must be an IP address, not an hostname, for AF_INET and + AF_INET6 address families. Use getaddrinfo() to resolve the hostname + asynchronously. + + This method is a coroutine. + """ + if self._debug and sock.gettimeout() != 0: + raise ValueError("the socket must be non-blocking") fut = futures.Future(loop=self) - self._sock_connect(fut, False, sock, address) + try: + if self._debug: + base_events._check_resolved_address(sock, address) + except ValueError as err: + fut.set_exception(err) + else: + self._sock_connect(fut, sock, address) return fut - def _sock_connect(self, fut, registered, sock, address): - # TODO: Use getaddrinfo() to look up the address, to avoid the - # trap of hanging the entire event loop when the address - # requires doing a DNS lookup. (OTOH, the caller should - # already have done this, so it would be nice if we could - # easily tell whether the address needs looking up or not. I - # know how to do this for IPv4, but IPv6 addresses have many - # syntaxes.) + def _sock_connect(self, fut, sock, address): fd = sock.fileno() - if registered: - self.remove_writer(fd) + try: + sock.connect(address) + except (BlockingIOError, InterruptedError): + # Issue #23618: When the C function connect() fails with EINTR, the + # connection runs in background. We have to wait until the socket + # becomes writable to be notified when the connection succeed or + # fails. + fut.add_done_callback(functools.partial(self._sock_connect_done, + fd)) + self.add_writer(fd, self._sock_connect_cb, fut, sock, address) + except Exception as exc: + fut.set_exception(exc) + else: + fut.set_result(None) + + def _sock_connect_done(self, fd, fut): + self.remove_writer(fd) + + def _sock_connect_cb(self, fut, sock, address): if fut.cancelled(): return + try: - if not registered: - # First time around. - sock.connect(address) - else: - err = sock.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) - if err != 0: - # Jump to the except clause below. - raise OSError(err, 'Connect call failed %s' % (address,)) + err = sock.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) + if err != 0: + # Jump to any except clause below. + raise OSError(err, 'Connect call failed %s' % (address,)) except (BlockingIOError, InterruptedError): - self.add_writer(fd, self._sock_connect, fut, True, sock, address) + # socket is still registered, the callback will be retried later + pass except Exception as exc: fut.set_exception(exc) else: fut.set_result(None) def sock_accept(self, sock): - """XXX""" + """Accept a connection. + + The socket must be bound to an address and listening for connections. + The return value is a pair (conn, address) where conn is a new socket + object usable to send and receive data on the connection, and address + is the address bound to the socket on the other end of the connection. + + This method is a coroutine. + """ + if self._debug and sock.gettimeout() != 0: + raise ValueError("the socket must be non-blocking") fut = futures.Future(loop=self) self._sock_accept(fut, False, sock) return fut @@ -336,14 +493,20 @@ def _stop_serving(self, sock): sock.close() -class _SelectorTransport(transports.Transport): +class _SelectorTransport(transports._FlowControlMixin, + transports.Transport): max_size = 256 * 1024 # Buffer size passed to recv(). _buffer_factory = bytearray # Constructs initial value for self._buffer. - def __init__(self, loop, sock, protocol, extra, server=None): - super().__init__(extra) + # Attribute used in the destructor: it must be set even if the constructor + # is not called (see _SelectorSslTransport which may start by raising an + # exception) + _sock = None + + def __init__(self, loop, sock, protocol, extra=None, server=None): + super().__init__(extra, loop) self._extra['socket'] = sock self._extra['sockname'] = sock.getsockname() if 'peername' not in self._extra: @@ -351,18 +514,44 @@ def __init__(self, loop, sock, protocol, extra, server=None): self._extra['peername'] = sock.getpeername() except socket.error: self._extra['peername'] = None - self._loop = loop self._sock = sock self._sock_fd = sock.fileno() self._protocol = protocol + self._protocol_connected = True self._server = server self._buffer = self._buffer_factory() self._conn_lost = 0 # Set when call to connection_lost scheduled. self._closing = False # Set when close() called. - self._protocol_paused = False - self.set_write_buffer_limits() if self._server is not None: - self._server.attach(self) + self._server._attach() + + def __repr__(self): + info = [self.__class__.__name__] + if self._sock is None: + info.append('closed') + elif self._closing: + info.append('closing') + info.append('fd=%s' % self._sock_fd) + # test if the transport was closed + if self._loop is not None and not self._loop.is_closed(): + polling = _test_selector_event(self._loop._selector, + self._sock_fd, selectors.EVENT_READ) + if polling: + info.append('read=polling') + else: + info.append('read=idle') + + polling = _test_selector_event(self._loop._selector, + self._sock_fd, + selectors.EVENT_WRITE) + if polling: + state = 'polling' + else: + state = 'idle' + + bufsize = self.get_write_buffer_size() + info.append('write=<%s, bufsize=%s>' % (state, bufsize)) + return '<%s>' % ' '.join(info) def abort(self): self._force_close(None) @@ -376,10 +565,28 @@ def close(self): self._conn_lost += 1 self._loop.call_soon(self._call_connection_lost, None) - def _fatal_error(self, exc): + # On Python 3.3 and older, objects with a destructor part of a reference + # cycle are never destroyed. It's not more the case on Python 3.4 thanks + # to the PEP 442. + if compat.PY34: + def __del__(self): + if self._sock is not None: + warnings.warn("unclosed transport %r" % self, ResourceWarning) + self._sock.close() + + def _fatal_error(self, exc, message='Fatal error on transport'): # Should be called from exception handler only. - if not isinstance(exc, (BrokenPipeError, ConnectionResetError)): - logger.exception('Fatal error for %s', self) + if isinstance(exc, (BrokenPipeError, + ConnectionResetError, ConnectionAbortedError)): + if self._loop.get_debug(): + logger.debug("%r: %s", self, message, exc_info=True) + else: + self._loop.call_exception_handler({ + 'message': message, + 'exception': exc, + 'transport': self, + 'protocol': self._protocol, + }) self._force_close(exc) def _force_close(self, exc): @@ -396,7 +603,8 @@ def _force_close(self, exc): def _call_connection_lost(self, exc): try: - self._protocol.connection_lost(exc) + if self._protocol_connected: + self._protocol.connection_lost(exc) finally: self._sock.close() self._sock = None @@ -404,43 +612,9 @@ def _call_connection_lost(self, exc): self._loop = None server = self._server if server is not None: - server.detach(self) + server._detach() self._server = None - def _maybe_pause_protocol(self): - size = self.get_write_buffer_size() - if size <= self._high_water: - return - if not self._protocol_paused: - self._protocol_paused = True - try: - self._protocol.pause_writing() - except Exception: - logger.exception('pause_writing() failed') - - def _maybe_resume_protocol(self): - if (self._protocol_paused and - self.get_write_buffer_size() <= self._low_water): - self._protocol_paused = False - try: - self._protocol.resume_writing() - except Exception: - logger.exception('resume_writing() failed') - - def set_write_buffer_limits(self, high=None, low=None): - if high is None: - if low is None: - high = 64*1024 - else: - high = 4*low - if low is None: - low = high // 4 - if not high >= low >= 0: - raise ValueError('high (%r) must be >= low (%r) must be >= 0' % - (high, low)) - self._high_water = high - self._low_water = low - def get_write_buffer_size(self): return len(self._buffer) @@ -453,10 +627,13 @@ def __init__(self, loop, sock, protocol, waiter=None, self._eof = False self._paused = False - self._loop.add_reader(self._sock_fd, self._read_ready) self._loop.call_soon(self._protocol.connection_made, self) + # only start reading when connection_made() has been called + self._loop.call_soon(self._loop.add_reader, + self._sock_fd, self._read_ready) if waiter is not None: - self._loop.call_soon(waiter.set_result, None) + # only wake up the waiter when connection_made() has been called + self._loop.call_soon(waiter._set_result_unless_cancelled, None) def pause_reading(self): if self._closing: @@ -465,6 +642,8 @@ def pause_reading(self): raise RuntimeError('Already paused') self._paused = True self._loop.remove_reader(self._sock_fd) + if self._loop.get_debug(): + logger.debug("%r pauses reading", self) def resume_reading(self): if not self._paused: @@ -473,6 +652,8 @@ def resume_reading(self): if self._closing: return self._loop.add_reader(self._sock_fd, self._read_ready) + if self._loop.get_debug(): + logger.debug("%r resumes reading", self) def _read_ready(self): try: @@ -480,11 +661,13 @@ def _read_ready(self): except (BlockingIOError, InterruptedError): pass except Exception as exc: - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal read error on socket transport') else: if data: self._protocol.data_received(data) else: + if self._loop.get_debug(): + logger.debug("%r received EOF", self) keep_open = self._protocol.eof_received() if keep_open: # We're keeping the connection open so the @@ -516,7 +699,7 @@ def write(self, data): except (BlockingIOError, InterruptedError): pass except Exception as exc: - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal write error on socket transport') return else: data = data[n:] @@ -539,7 +722,7 @@ def _write_ready(self): except Exception as exc: self._loop.remove_writer(self._sock_fd) self._buffer.clear() - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal write error on socket transport') else: if n: del self._buffer[:n] @@ -572,97 +755,108 @@ def __init__(self, loop, rawsock, protocol, sslcontext, waiter=None, if ssl is None: raise RuntimeError('stdlib ssl module not available') - if server_side: - if not sslcontext: - raise ValueError('Server side ssl needs a valid SSLContext') - else: - if not sslcontext: - # Client side may pass ssl=True to use a default - # context; in that case the sslcontext passed is None. - # The default is the same as used by urllib with - # cadefault=True. - if hasattr(ssl, '_create_stdlib_context'): - sslcontext = ssl._create_stdlib_context( - cert_reqs=ssl.CERT_REQUIRED) - else: - # Fallback for Python 3.3. - sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) - sslcontext.options |= ssl.OP_NO_SSLv2 - sslcontext.set_default_verify_paths() - sslcontext.verify_mode = ssl.CERT_REQUIRED + if not sslcontext: + sslcontext = sslproto._create_transport_context(server_side, server_hostname) wrap_kwargs = { 'server_side': server_side, 'do_handshake_on_connect': False, } - if server_hostname and not server_side and ssl.HAS_SNI: + if server_hostname and not server_side: wrap_kwargs['server_hostname'] = server_hostname sslsock = sslcontext.wrap_socket(rawsock, **wrap_kwargs) super().__init__(loop, sslsock, protocol, extra, server) + # the protocol connection is only made after the SSL handshake + self._protocol_connected = False self._server_hostname = server_hostname self._waiter = waiter - self._rawsock = rawsock self._sslcontext = sslcontext self._paused = False # SSL-specific extra info. (peercert is set later) self._extra.update(sslcontext=sslcontext) - self._on_handshake() + if self._loop.get_debug(): + logger.debug("%r starts SSL handshake", self) + start_time = self._loop.time() + else: + start_time = None + self._on_handshake(start_time) - def _on_handshake(self): + def _wakeup_waiter(self, exc=None): + if self._waiter is None: + return + if not self._waiter.cancelled(): + if exc is not None: + self._waiter.set_exception(exc) + else: + self._waiter.set_result(None) + self._waiter = None + + def _on_handshake(self, start_time): try: self._sock.do_handshake() except ssl.SSLWantReadError: - self._loop.add_reader(self._sock_fd, self._on_handshake) + self._loop.add_reader(self._sock_fd, + self._on_handshake, start_time) return except ssl.SSLWantWriteError: - self._loop.add_writer(self._sock_fd, self._on_handshake) - return - except Exception as exc: - self._loop.remove_reader(self._sock_fd) - self._loop.remove_writer(self._sock_fd) - self._sock.close() - if self._waiter is not None: - self._waiter.set_exception(exc) + self._loop.add_writer(self._sock_fd, + self._on_handshake, start_time) return except BaseException as exc: + if self._loop.get_debug(): + logger.warning("%r: SSL handshake failed", + self, exc_info=True) self._loop.remove_reader(self._sock_fd) self._loop.remove_writer(self._sock_fd) self._sock.close() - if self._waiter is not None: - self._waiter.set_exception(exc) - raise + self._wakeup_waiter(exc) + if isinstance(exc, Exception): + return + else: + raise self._loop.remove_reader(self._sock_fd) self._loop.remove_writer(self._sock_fd) - # Verify hostname if requested. peercert = self._sock.getpeercert() - if (self._server_hostname and - self._sslcontext.verify_mode != ssl.CERT_NONE): - try: - ssl.match_hostname(peercert, self._server_hostname) - except Exception as exc: - self._sock.close() - if self._waiter is not None: - self._waiter.set_exception(exc) - return + if not hasattr(self._sslcontext, 'check_hostname'): + # Verify hostname if requested, Python 3.4+ uses check_hostname + # and checks the hostname in do_handshake() + if (self._server_hostname and + self._sslcontext.verify_mode != ssl.CERT_NONE): + try: + ssl.match_hostname(peercert, self._server_hostname) + except Exception as exc: + if self._loop.get_debug(): + logger.warning("%r: SSL handshake failed " + "on matching the hostname", + self, exc_info=True) + self._sock.close() + self._wakeup_waiter(exc) + return # Add extra info that becomes available after handshake. self._extra.update(peercert=peercert, cipher=self._sock.cipher(), compression=self._sock.compression(), + ssl_object=self._sock, ) self._read_wants_write = False self._write_wants_read = False self._loop.add_reader(self._sock_fd, self._read_ready) + self._protocol_connected = True self._loop.call_soon(self._protocol.connection_made, self) - if self._waiter is not None: - self._loop.call_soon(self._waiter.set_result, None) + # only wake up the waiter when connection_made() has been called + self._loop.call_soon(self._wakeup_waiter) + + if self._loop.get_debug(): + dt = self._loop.time() - start_time + logger.debug("%r: SSL handshake took %.1f ms", self, dt * 1e3) def pause_reading(self): # XXX This is a bit icky, given the comment at the top of @@ -677,14 +871,18 @@ def pause_reading(self): raise RuntimeError('Already paused') self._paused = True self._loop.remove_reader(self._sock_fd) + if self._loop.get_debug(): + logger.debug("%r pauses reading", self) def resume_reading(self): if not self._paused: - raise ('Not paused') + raise RuntimeError('Not paused') self._paused = False if self._closing: return self._loop.add_reader(self._sock_fd, self._read_ready) + if self._loop.get_debug(): + logger.debug("%r resumes reading", self) def _read_ready(self): if self._write_wants_read: @@ -703,12 +901,14 @@ def _read_ready(self): self._loop.remove_reader(self._sock_fd) self._loop.add_writer(self._sock_fd, self._write_ready) except Exception as exc: - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal read error on SSL transport') else: if data: self._protocol.data_received(data) else: try: + if self._loop.get_debug(): + logger.debug("%r received EOF", self) keep_open = self._protocol.eof_received() if keep_open: logger.warning('returning true from eof_received() ' @@ -727,8 +927,7 @@ def _write_ready(self): if self._buffer: try: n = self._sock.send(self._buffer) - except (BlockingIOError, InterruptedError, - ssl.SSLWantWriteError): + except (BlockingIOError, InterruptedError, ssl.SSLWantWriteError): n = 0 except ssl.SSLWantReadError: n = 0 @@ -737,7 +936,7 @@ def _write_ready(self): except Exception as exc: self._loop.remove_writer(self._sock_fd) self._buffer.clear() - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal write error on SSL transport') return if n: @@ -778,11 +977,17 @@ class _SelectorDatagramTransport(_SelectorTransport): _buffer_factory = collections.deque - def __init__(self, loop, sock, protocol, address=None, extra=None): + def __init__(self, loop, sock, protocol, address=None, + waiter=None, extra=None): super().__init__(loop, sock, protocol, extra) self._address = address - self._loop.add_reader(self._sock_fd, self._read_ready) self._loop.call_soon(self._protocol.connection_made, self) + # only start reading when connection_made() has been called + self._loop.call_soon(self._loop.add_reader, + self._sock_fd, self._read_ready) + if waiter is not None: + # only wake up the waiter when connection_made() has been called + self._loop.call_soon(waiter._set_result_unless_cancelled, None) def get_write_buffer_size(self): return sum(len(data) for data, _ in self._buffer) @@ -795,7 +1000,7 @@ def _read_ready(self): except OSError as exc: self._protocol.error_received(exc) except Exception as exc: - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal read error on datagram transport') else: self._protocol.datagram_received(data, addr) @@ -830,7 +1035,8 @@ def sendto(self, data, addr=None): self._protocol.error_received(exc) return except Exception as exc: - self._fatal_error(exc) + self._fatal_error(exc, + 'Fatal write error on datagram transport') return # Ensure that what we buffer is immutable. @@ -852,7 +1058,8 @@ def _sendto_ready(self): self._protocol.error_received(exc) return except Exception as exc: - self._fatal_error(exc) + self._fatal_error(exc, + 'Fatal write error on datagram transport') return self._maybe_resume_protocol() # May append to buffer. diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py new file mode 100644 index 000000000000..0a8c0900f81f --- /dev/null +++ b/Lib/asyncio/sslproto.py @@ -0,0 +1,677 @@ +import collections +import warnings +try: + import ssl +except ImportError: # pragma: no cover + ssl = None + +from . import compat +from . import protocols +from . import transports +from .log import logger + + +def _create_transport_context(server_side, server_hostname): + if server_side: + raise ValueError('Server side SSL needs a valid SSLContext') + + # Client side may pass ssl=True to use a default + # context; in that case the sslcontext passed is None. + # The default is secure for client connections. + if hasattr(ssl, 'create_default_context'): + # Python 3.4+: use up-to-date strong settings. + sslcontext = ssl.create_default_context() + if not server_hostname: + sslcontext.check_hostname = False + else: + # Fallback for Python 3.3. + sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + sslcontext.options |= ssl.OP_NO_SSLv2 + sslcontext.options |= ssl.OP_NO_SSLv3 + sslcontext.set_default_verify_paths() + sslcontext.verify_mode = ssl.CERT_REQUIRED + return sslcontext + + +def _is_sslproto_available(): + return hasattr(ssl, "MemoryBIO") + + +# States of an _SSLPipe. +_UNWRAPPED = "UNWRAPPED" +_DO_HANDSHAKE = "DO_HANDSHAKE" +_WRAPPED = "WRAPPED" +_SHUTDOWN = "SHUTDOWN" + + +class _SSLPipe(object): + """An SSL "Pipe". + + An SSL pipe allows you to communicate with an SSL/TLS protocol instance + through memory buffers. It can be used to implement a security layer for an + existing connection where you don't have access to the connection's file + descriptor, or for some reason you don't want to use it. + + An SSL pipe can be in "wrapped" and "unwrapped" mode. In unwrapped mode, + data is passed through untransformed. In wrapped mode, application level + data is encrypted to SSL record level data and vice versa. The SSL record + level is the lowest level in the SSL protocol suite and is what travels + as-is over the wire. + + An SslPipe initially is in "unwrapped" mode. To start SSL, call + do_handshake(). To shutdown SSL again, call unwrap(). + """ + + max_size = 256 * 1024 # Buffer size passed to read() + + def __init__(self, context, server_side, server_hostname=None): + """ + The *context* argument specifies the ssl.SSLContext to use. + + The *server_side* argument indicates whether this is a server side or + client side transport. + + The optional *server_hostname* argument can be used to specify the + hostname you are connecting to. You may only specify this parameter if + the _ssl module supports Server Name Indication (SNI). + """ + self._context = context + self._server_side = server_side + self._server_hostname = server_hostname + self._state = _UNWRAPPED + self._incoming = ssl.MemoryBIO() + self._outgoing = ssl.MemoryBIO() + self._sslobj = None + self._need_ssldata = False + self._handshake_cb = None + self._shutdown_cb = None + + @property + def context(self): + """The SSL context passed to the constructor.""" + return self._context + + @property + def ssl_object(self): + """The internal ssl.SSLObject instance. + + Return None if the pipe is not wrapped. + """ + return self._sslobj + + @property + def need_ssldata(self): + """Whether more record level data is needed to complete a handshake + that is currently in progress.""" + return self._need_ssldata + + @property + def wrapped(self): + """ + Whether a security layer is currently in effect. + + Return False during handshake. + """ + return self._state == _WRAPPED + + def do_handshake(self, callback=None): + """Start the SSL handshake. + + Return a list of ssldata. A ssldata element is a list of buffers + + The optional *callback* argument can be used to install a callback that + will be called when the handshake is complete. The callback will be + called with None if successful, else an exception instance. + """ + if self._state != _UNWRAPPED: + raise RuntimeError('handshake in progress or completed') + self._sslobj = self._context.wrap_bio( + self._incoming, self._outgoing, + server_side=self._server_side, + server_hostname=self._server_hostname) + self._state = _DO_HANDSHAKE + self._handshake_cb = callback + ssldata, appdata = self.feed_ssldata(b'', only_handshake=True) + assert len(appdata) == 0 + return ssldata + + def shutdown(self, callback=None): + """Start the SSL shutdown sequence. + + Return a list of ssldata. A ssldata element is a list of buffers + + The optional *callback* argument can be used to install a callback that + will be called when the shutdown is complete. The callback will be + called without arguments. + """ + if self._state == _UNWRAPPED: + raise RuntimeError('no security layer present') + if self._state == _SHUTDOWN: + raise RuntimeError('shutdown in progress') + assert self._state in (_WRAPPED, _DO_HANDSHAKE) + self._state = _SHUTDOWN + self._shutdown_cb = callback + ssldata, appdata = self.feed_ssldata(b'') + assert appdata == [] or appdata == [b''] + return ssldata + + def feed_eof(self): + """Send a potentially "ragged" EOF. + + This method will raise an SSL_ERROR_EOF exception if the EOF is + unexpected. + """ + self._incoming.write_eof() + ssldata, appdata = self.feed_ssldata(b'') + assert appdata == [] or appdata == [b''] + + def feed_ssldata(self, data, only_handshake=False): + """Feed SSL record level data into the pipe. + + The data must be a bytes instance. It is OK to send an empty bytes + instance. This can be used to get ssldata for a handshake initiated by + this endpoint. + + Return a (ssldata, appdata) tuple. The ssldata element is a list of + buffers containing SSL data that needs to be sent to the remote SSL. + + The appdata element is a list of buffers containing plaintext data that + needs to be forwarded to the application. The appdata list may contain + an empty buffer indicating an SSL "close_notify" alert. This alert must + be acknowledged by calling shutdown(). + """ + if self._state == _UNWRAPPED: + # If unwrapped, pass plaintext data straight through. + if data: + appdata = [data] + else: + appdata = [] + return ([], appdata) + + self._need_ssldata = False + if data: + self._incoming.write(data) + + ssldata = [] + appdata = [] + try: + if self._state == _DO_HANDSHAKE: + # Call do_handshake() until it doesn't raise anymore. + self._sslobj.do_handshake() + self._state = _WRAPPED + if self._handshake_cb: + self._handshake_cb(None) + if only_handshake: + return (ssldata, appdata) + # Handshake done: execute the wrapped block + + if self._state == _WRAPPED: + # Main state: read data from SSL until close_notify + while True: + chunk = self._sslobj.read(self.max_size) + appdata.append(chunk) + if not chunk: # close_notify + break + + elif self._state == _SHUTDOWN: + # Call shutdown() until it doesn't raise anymore. + self._sslobj.unwrap() + self._sslobj = None + self._state = _UNWRAPPED + if self._shutdown_cb: + self._shutdown_cb() + + elif self._state == _UNWRAPPED: + # Drain possible plaintext data after close_notify. + appdata.append(self._incoming.read()) + except (ssl.SSLError, ssl.CertificateError) as exc: + if getattr(exc, 'errno', None) not in ( + ssl.SSL_ERROR_WANT_READ, ssl.SSL_ERROR_WANT_WRITE, + ssl.SSL_ERROR_SYSCALL): + if self._state == _DO_HANDSHAKE and self._handshake_cb: + self._handshake_cb(exc) + raise + self._need_ssldata = (exc.errno == ssl.SSL_ERROR_WANT_READ) + + # Check for record level data that needs to be sent back. + # Happens for the initial handshake and renegotiations. + if self._outgoing.pending: + ssldata.append(self._outgoing.read()) + return (ssldata, appdata) + + def feed_appdata(self, data, offset=0): + """Feed plaintext data into the pipe. + + Return an (ssldata, offset) tuple. The ssldata element is a list of + buffers containing record level data that needs to be sent to the + remote SSL instance. The offset is the number of plaintext bytes that + were processed, which may be less than the length of data. + + NOTE: In case of short writes, this call MUST be retried with the SAME + buffer passed into the *data* argument (i.e. the id() must be the + same). This is an OpenSSL requirement. A further particularity is that + a short write will always have offset == 0, because the _ssl module + does not enable partial writes. And even though the offset is zero, + there will still be encrypted data in ssldata. + """ + assert 0 <= offset <= len(data) + if self._state == _UNWRAPPED: + # pass through data in unwrapped mode + if offset < len(data): + ssldata = [data[offset:]] + else: + ssldata = [] + return (ssldata, len(data)) + + ssldata = [] + view = memoryview(data) + while True: + self._need_ssldata = False + try: + if offset < len(view): + offset += self._sslobj.write(view[offset:]) + except ssl.SSLError as exc: + # It is not allowed to call write() after unwrap() until the + # close_notify is acknowledged. We return the condition to the + # caller as a short write. + if exc.reason == 'PROTOCOL_IS_SHUTDOWN': + exc.errno = ssl.SSL_ERROR_WANT_READ + if exc.errno not in (ssl.SSL_ERROR_WANT_READ, + ssl.SSL_ERROR_WANT_WRITE, + ssl.SSL_ERROR_SYSCALL): + raise + self._need_ssldata = (exc.errno == ssl.SSL_ERROR_WANT_READ) + + # See if there's any record level data back for us. + if self._outgoing.pending: + ssldata.append(self._outgoing.read()) + if offset == len(view) or self._need_ssldata: + break + return (ssldata, offset) + + +class _SSLProtocolTransport(transports._FlowControlMixin, + transports.Transport): + + def __init__(self, loop, ssl_protocol, app_protocol): + self._loop = loop + # SSLProtocol instance + self._ssl_protocol = ssl_protocol + self._app_protocol = app_protocol + self._closed = False + + def get_extra_info(self, name, default=None): + """Get optional transport information.""" + return self._ssl_protocol._get_extra_info(name, default) + + def close(self): + """Close the transport. + + Buffered data will be flushed asynchronously. No more data + will be received. After all buffered data is flushed, the + protocol's connection_lost() method will (eventually) called + with None as its argument. + """ + self._closed = True + self._ssl_protocol._start_shutdown() + + # On Python 3.3 and older, objects with a destructor part of a reference + # cycle are never destroyed. It's not more the case on Python 3.4 thanks + # to the PEP 442. + if compat.PY34: + def __del__(self): + if not self._closed: + warnings.warn("unclosed transport %r" % self, ResourceWarning) + self.close() + + def pause_reading(self): + """Pause the receiving end. + + No data will be passed to the protocol's data_received() + method until resume_reading() is called. + """ + self._ssl_protocol._transport.pause_reading() + + def resume_reading(self): + """Resume the receiving end. + + Data received will once again be passed to the protocol's + data_received() method. + """ + self._ssl_protocol._transport.resume_reading() + + def set_write_buffer_limits(self, high=None, low=None): + """Set the high- and low-water limits for write flow control. + + These two values control when to call the protocol's + pause_writing() and resume_writing() methods. If specified, + the low-water limit must be less than or equal to the + high-water limit. Neither value can be negative. + + The defaults are implementation-specific. If only the + high-water limit is given, the low-water limit defaults to a + implementation-specific value less than or equal to the + high-water limit. Setting high to zero forces low to zero as + well, and causes pause_writing() to be called whenever the + buffer becomes non-empty. Setting low to zero causes + resume_writing() to be called only once the buffer is empty. + Use of zero for either limit is generally sub-optimal as it + reduces opportunities for doing I/O and computation + concurrently. + """ + self._ssl_protocol._transport.set_write_buffer_limits(high, low) + + def get_write_buffer_size(self): + """Return the current size of the write buffer.""" + return self._ssl_protocol._transport.get_write_buffer_size() + + def write(self, data): + """Write some data bytes to the transport. + + This does not block; it buffers the data and arranges for it + to be sent out asynchronously. + """ + if not isinstance(data, (bytes, bytearray, memoryview)): + raise TypeError("data: expecting a bytes-like instance, got {!r}" + .format(type(data).__name__)) + if not data: + return + self._ssl_protocol._write_appdata(data) + + def can_write_eof(self): + """Return True if this transport supports write_eof(), False if not.""" + return False + + def abort(self): + """Close the transport immediately. + + Buffered data will be lost. No more data will be received. + The protocol's connection_lost() method will (eventually) be + called with None as its argument. + """ + self._ssl_protocol._abort() + + +class SSLProtocol(protocols.Protocol): + """SSL protocol. + + Implementation of SSL on top of a socket using incoming and outgoing + buffers which are ssl.MemoryBIO objects. + """ + + def __init__(self, loop, app_protocol, sslcontext, waiter, + server_side=False, server_hostname=None): + if ssl is None: + raise RuntimeError('stdlib ssl module not available') + + if not sslcontext: + sslcontext = _create_transport_context(server_side, server_hostname) + + self._server_side = server_side + if server_hostname and not server_side: + self._server_hostname = server_hostname + else: + self._server_hostname = None + self._sslcontext = sslcontext + # SSL-specific extra info. More info are set when the handshake + # completes. + self._extra = dict(sslcontext=sslcontext) + + # App data write buffering + self._write_backlog = collections.deque() + self._write_buffer_size = 0 + + self._waiter = waiter + self._loop = loop + self._app_protocol = app_protocol + self._app_transport = _SSLProtocolTransport(self._loop, + self, self._app_protocol) + # _SSLPipe instance (None until the connection is made) + self._sslpipe = None + self._session_established = False + self._in_handshake = False + self._in_shutdown = False + # transport, ex: SelectorSocketTransport + self._transport = None + + def _wakeup_waiter(self, exc=None): + if self._waiter is None: + return + if not self._waiter.cancelled(): + if exc is not None: + self._waiter.set_exception(exc) + else: + self._waiter.set_result(None) + self._waiter = None + + def connection_made(self, transport): + """Called when the low-level connection is made. + + Start the SSL handshake. + """ + self._transport = transport + self._sslpipe = _SSLPipe(self._sslcontext, + self._server_side, + self._server_hostname) + self._start_handshake() + + def connection_lost(self, exc): + """Called when the low-level connection is lost or closed. + + The argument is an exception object or None (the latter + meaning a regular EOF is received or the connection was + aborted or closed). + """ + if self._session_established: + self._session_established = False + self._loop.call_soon(self._app_protocol.connection_lost, exc) + self._transport = None + self._app_transport = None + + def pause_writing(self): + """Called when the low-level transport's buffer goes over + the high-water mark. + """ + self._app_protocol.pause_writing() + + def resume_writing(self): + """Called when the low-level transport's buffer drains below + the low-water mark. + """ + self._app_protocol.resume_writing() + + def data_received(self, data): + """Called when some SSL data is received. + + The argument is a bytes object. + """ + try: + ssldata, appdata = self._sslpipe.feed_ssldata(data) + except ssl.SSLError as e: + if self._loop.get_debug(): + logger.warning('%r: SSL error %s (reason %s)', + self, e.errno, e.reason) + self._abort() + return + + for chunk in ssldata: + self._transport.write(chunk) + + for chunk in appdata: + if chunk: + self._app_protocol.data_received(chunk) + else: + self._start_shutdown() + break + + def eof_received(self): + """Called when the other end of the low-level stream + is half-closed. + + If this returns a false value (including None), the transport + will close itself. If it returns a true value, closing the + transport is up to the protocol. + """ + try: + if self._loop.get_debug(): + logger.debug("%r received EOF", self) + + self._wakeup_waiter(ConnectionResetError) + + if not self._in_handshake: + keep_open = self._app_protocol.eof_received() + if keep_open: + logger.warning('returning true from eof_received() ' + 'has no effect when using ssl') + finally: + self._transport.close() + + def _get_extra_info(self, name, default=None): + if name in self._extra: + return self._extra[name] + else: + return self._transport.get_extra_info(name, default) + + def _start_shutdown(self): + if self._in_shutdown: + return + self._in_shutdown = True + self._write_appdata(b'') + + def _write_appdata(self, data): + self._write_backlog.append((data, 0)) + self._write_buffer_size += len(data) + self._process_write_backlog() + + def _start_handshake(self): + if self._loop.get_debug(): + logger.debug("%r starts SSL handshake", self) + self._handshake_start_time = self._loop.time() + else: + self._handshake_start_time = None + self._in_handshake = True + # (b'', 1) is a special value in _process_write_backlog() to do + # the SSL handshake + self._write_backlog.append((b'', 1)) + self._loop.call_soon(self._process_write_backlog) + + def _on_handshake_complete(self, handshake_exc): + self._in_handshake = False + + sslobj = self._sslpipe.ssl_object + try: + if handshake_exc is not None: + raise handshake_exc + + peercert = sslobj.getpeercert() + if not hasattr(self._sslcontext, 'check_hostname'): + # Verify hostname if requested, Python 3.4+ uses check_hostname + # and checks the hostname in do_handshake() + if (self._server_hostname + and self._sslcontext.verify_mode != ssl.CERT_NONE): + ssl.match_hostname(peercert, self._server_hostname) + except BaseException as exc: + if self._loop.get_debug(): + if isinstance(exc, ssl.CertificateError): + logger.warning("%r: SSL handshake failed " + "on verifying the certificate", + self, exc_info=True) + else: + logger.warning("%r: SSL handshake failed", + self, exc_info=True) + self._transport.close() + if isinstance(exc, Exception): + self._wakeup_waiter(exc) + return + else: + raise + + if self._loop.get_debug(): + dt = self._loop.time() - self._handshake_start_time + logger.debug("%r: SSL handshake took %.1f ms", self, dt * 1e3) + + # Add extra info that becomes available after handshake. + self._extra.update(peercert=peercert, + cipher=sslobj.cipher(), + compression=sslobj.compression(), + ssl_object=sslobj, + ) + self._app_protocol.connection_made(self._app_transport) + self._wakeup_waiter() + self._session_established = True + # In case transport.write() was already called. Don't call + # immediatly _process_write_backlog(), but schedule it: + # _on_handshake_complete() can be called indirectly from + # _process_write_backlog(), and _process_write_backlog() is not + # reentrant. + self._loop.call_soon(self._process_write_backlog) + + def _process_write_backlog(self): + # Try to make progress on the write backlog. + if self._transport is None: + return + + try: + for i in range(len(self._write_backlog)): + data, offset = self._write_backlog[0] + if data: + ssldata, offset = self._sslpipe.feed_appdata(data, offset) + elif offset: + ssldata = self._sslpipe.do_handshake( + self._on_handshake_complete) + offset = 1 + else: + ssldata = self._sslpipe.shutdown(self._finalize) + offset = 1 + + for chunk in ssldata: + self._transport.write(chunk) + + if offset < len(data): + self._write_backlog[0] = (data, offset) + # A short write means that a write is blocked on a read + # We need to enable reading if it is paused! + assert self._sslpipe.need_ssldata + if self._transport._paused: + self._transport.resume_reading() + break + + # An entire chunk from the backlog was processed. We can + # delete it and reduce the outstanding buffer size. + del self._write_backlog[0] + self._write_buffer_size -= len(data) + except BaseException as exc: + if self._in_handshake: + # BaseExceptions will be re-raised in _on_handshake_complete. + self._on_handshake_complete(exc) + else: + self._fatal_error(exc, 'Fatal error on SSL transport') + if not isinstance(exc, Exception): + # BaseException + raise + + def _fatal_error(self, exc, message='Fatal error on transport'): + # Should be called from exception handler only. + if isinstance(exc, (BrokenPipeError, ConnectionResetError)): + if self._loop.get_debug(): + logger.debug("%r: %s", self, message, exc_info=True) + else: + self._loop.call_exception_handler({ + 'message': message, + 'exception': exc, + 'transport': self._transport, + 'protocol': self, + }) + if self._transport: + self._transport._force_close(exc) + + def _finalize(self): + if self._transport is not None: + self._transport.close() + + def _abort(self): + if self._transport is not None: + try: + self._transport.abort() + finally: + self._finalize() diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py index 50c4c5d1c2ec..fb786ed8645f 100644 --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -2,26 +2,47 @@ __all__ = ['StreamReader', 'StreamWriter', 'StreamReaderProtocol', 'open_connection', 'start_server', + 'IncompleteReadError', ] -import collections +import socket +if hasattr(socket, 'AF_UNIX'): + __all__.extend(['open_unix_connection', 'start_unix_server']) + +from . import coroutines +from . import compat from . import events from . import futures from . import protocols -from . import tasks +from .coroutines import coroutine +from .log import logger _DEFAULT_LIMIT = 2**16 -@tasks.coroutine +class IncompleteReadError(EOFError): + """ + Incomplete read error. Attributes: + + - partial: read bytes string before the end of stream was reached + - expected: total number of expected bytes + """ + def __init__(self, partial, expected): + EOFError.__init__(self, "%s bytes read on a total of %s expected bytes" + % (len(partial), expected)) + self.partial = partial + self.expected = expected + + +@coroutine def open_connection(host=None, port=None, *, loop=None, limit=_DEFAULT_LIMIT, **kwds): """A wrapper for create_connection() returning a (reader, writer) pair. The reader returned is a StreamReader instance; the writer is a - Transport. + StreamWriter instance. The arguments are all the usual arguments to create_connection() except protocol_factory; most common are positional host and port, @@ -38,14 +59,14 @@ def open_connection(host=None, port=None, *, if loop is None: loop = events.get_event_loop() reader = StreamReader(limit=limit, loop=loop) - protocol = StreamReaderProtocol(reader) + protocol = StreamReaderProtocol(reader, loop=loop) transport, _ = yield from loop.create_connection( lambda: protocol, host, port, **kwds) writer = StreamWriter(transport, protocol, reader, loop) return reader, writer -@tasks.coroutine +@coroutine def start_server(client_connected_cb, host=None, port=None, *, loop=None, limit=_DEFAULT_LIMIT, **kwds): """Start a socket server, call back for each client connected. @@ -81,8 +102,107 @@ def factory(): return (yield from loop.create_server(factory, host, port, **kwds)) -class StreamReaderProtocol(protocols.Protocol): - """Trivial helper class to adapt between Protocol and StreamReader. +if hasattr(socket, 'AF_UNIX'): + # UNIX Domain Sockets are supported on this platform + + @coroutine + def open_unix_connection(path=None, *, + loop=None, limit=_DEFAULT_LIMIT, **kwds): + """Similar to `open_connection` but works with UNIX Domain Sockets.""" + if loop is None: + loop = events.get_event_loop() + reader = StreamReader(limit=limit, loop=loop) + protocol = StreamReaderProtocol(reader, loop=loop) + transport, _ = yield from loop.create_unix_connection( + lambda: protocol, path, **kwds) + writer = StreamWriter(transport, protocol, reader, loop) + return reader, writer + + + @coroutine + def start_unix_server(client_connected_cb, path=None, *, + loop=None, limit=_DEFAULT_LIMIT, **kwds): + """Similar to `start_server` but works with UNIX Domain Sockets.""" + if loop is None: + loop = events.get_event_loop() + + def factory(): + reader = StreamReader(limit=limit, loop=loop) + protocol = StreamReaderProtocol(reader, client_connected_cb, + loop=loop) + return protocol + + return (yield from loop.create_unix_server(factory, path, **kwds)) + + +class FlowControlMixin(protocols.Protocol): + """Reusable flow control logic for StreamWriter.drain(). + + This implements the protocol methods pause_writing(), + resume_reading() and connection_lost(). If the subclass overrides + these it must call the super methods. + + StreamWriter.drain() must wait for _drain_helper() coroutine. + """ + + def __init__(self, loop=None): + if loop is None: + self._loop = events.get_event_loop() + else: + self._loop = loop + self._paused = False + self._drain_waiter = None + self._connection_lost = False + + def pause_writing(self): + assert not self._paused + self._paused = True + if self._loop.get_debug(): + logger.debug("%r pauses writing", self) + + def resume_writing(self): + assert self._paused + self._paused = False + if self._loop.get_debug(): + logger.debug("%r resumes writing", self) + + waiter = self._drain_waiter + if waiter is not None: + self._drain_waiter = None + if not waiter.done(): + waiter.set_result(None) + + def connection_lost(self, exc): + self._connection_lost = True + # Wake up the writer if currently paused. + if not self._paused: + return + waiter = self._drain_waiter + if waiter is None: + return + self._drain_waiter = None + if waiter.done(): + return + if exc is None: + waiter.set_result(None) + else: + waiter.set_exception(exc) + + @coroutine + def _drain_helper(self): + if self._connection_lost: + raise ConnectionResetError('Connection lost') + if not self._paused: + return + waiter = self._drain_waiter + assert waiter is None or waiter.cancelled() + waiter = futures.Future(loop=self._loop) + self._drain_waiter = waiter + yield from waiter + + +class StreamReaderProtocol(FlowControlMixin, protocols.Protocol): + """Helper class to adapt between Protocol and StreamReader. (This is a helper class instead of making StreamReader itself a Protocol subclass, because the StreamReader has other potential @@ -91,12 +211,10 @@ class StreamReaderProtocol(protocols.Protocol): """ def __init__(self, stream_reader, client_connected_cb=None, loop=None): + super().__init__(loop=loop) self._stream_reader = stream_reader self._stream_writer = None - self._drain_waiter = None - self._paused = False self._client_connected_cb = client_connected_cb - self._loop = loop # May be None; we may never need it. def connection_made(self, transport): self._stream_reader.set_transport(transport) @@ -106,43 +224,22 @@ def connection_made(self, transport): self._loop) res = self._client_connected_cb(self._stream_reader, self._stream_writer) - if tasks.iscoroutine(res): - tasks.Task(res, loop=self._loop) + if coroutines.iscoroutine(res): + self._loop.create_task(res) def connection_lost(self, exc): if exc is None: self._stream_reader.feed_eof() else: self._stream_reader.set_exception(exc) - # Also wake up the writing side. - if self._paused: - waiter = self._drain_waiter - if waiter is not None: - self._drain_waiter = None - if not waiter.done(): - if exc is None: - waiter.set_result(None) - else: - waiter.set_exception(exc) + super().connection_lost(exc) def data_received(self, data): self._stream_reader.feed_data(data) def eof_received(self): self._stream_reader.feed_eof() - - def pause_writing(self): - assert not self._paused - self._paused = True - - def resume_writing(self): - assert self._paused - self._paused = False - waiter = self._drain_waiter - if waiter is not None: - self._drain_waiter = None - if not waiter.done(): - waiter.set_result(None) + return True class StreamWriter: @@ -151,16 +248,24 @@ class StreamWriter: This exposes write(), writelines(), [can_]write_eof(), get_extra_info() and close(). It adds drain() which returns an optional Future on which you can wait for flow control. It also - adds a transport attribute which references the Transport + adds a transport property which references the Transport directly. """ def __init__(self, transport, protocol, reader, loop): self._transport = transport self._protocol = protocol + # drain() expects that the reader has a exception() method + assert reader is None or isinstance(reader, StreamReader) self._reader = reader self._loop = loop + def __repr__(self): + info = [self.__class__.__name__, 'transport=%r' % self._transport] + if self._reader is not None: + info.append('reader=%r' % self._reader) + return '<%s>' % ' '.join(info) + @property def transport(self): return self._transport @@ -183,32 +288,29 @@ def close(self): def get_extra_info(self, name, default=None): return self._transport.get_extra_info(name, default) + @coroutine def drain(self): - """This method has an unusual return value. + """Flush the write buffer. The intended use is to write w.write(data) yield from w.drain() - - When there's nothing to wait for, drain() returns (), and the - yield-from continues immediately. When the transport buffer - is full (the protocol is paused), drain() creates and returns - a Future and the yield-from will block until that Future is - completed, which will happen when the buffer is (partially) - drained and the protocol is resumed. """ - if self._reader._exception is not None: - raise self._writer._exception - if self._transport._conn_lost: # Uses private variable. - raise ConnectionResetError('Connection lost') - if not self._protocol._paused: - return () - waiter = self._protocol._drain_waiter - assert waiter is None or waiter.cancelled() - waiter = futures.Future(loop=self._loop) - self._protocol._drain_waiter = waiter - return waiter + if self._reader is not None: + exc = self._reader.exception() + if exc is not None: + raise exc + if self._transport is not None: + if self._transport._closing: + # Yield to the event loop so connection_lost() may be + # called. Without this, _drain_helper() would return + # immediately, and code that calls + # write(...); yield from drain() + # in a loop would never call connection_lost(), so it + # would not see an error when the socket is closed. + yield + yield from self._protocol._drain_helper() class StreamReader: @@ -218,16 +320,34 @@ def __init__(self, limit=_DEFAULT_LIMIT, loop=None): # it also doubles as half the buffer limit. self._limit = limit if loop is None: - loop = events.get_event_loop() - self._loop = loop - self._buffer = collections.deque() # Deque of bytes objects. - self._byte_count = 0 # Bytes in buffer. - self._eof = False # Whether we're done. - self._waiter = None # A future. + self._loop = events.get_event_loop() + else: + self._loop = loop + self._buffer = bytearray() + self._eof = False # Whether we're done. + self._waiter = None # A future used by _wait_for_data() self._exception = None self._transport = None self._paused = False + def __repr__(self): + info = ['StreamReader'] + if self._buffer: + info.append('%d bytes' % len(self._buffer)) + if self._eof: + info.append('eof') + if self._limit != _DEFAULT_LIMIT: + info.append('l=%d' % self._limit) + if self._waiter: + info.append('w=%r' % self._waiter) + if self._exception: + info.append('e=%r' % self._exception) + if self._transport: + info.append('t=%r' % self._transport) + if self._paused: + info.append('paused') + return '<%s>' % ' '.join(info) + def exception(self): return self._exception @@ -240,39 +360,43 @@ def set_exception(self, exc): if not waiter.cancelled(): waiter.set_exception(exc) + def _wakeup_waiter(self): + """Wakeup read() or readline() function waiting for data or EOF.""" + waiter = self._waiter + if waiter is not None: + self._waiter = None + if not waiter.cancelled(): + waiter.set_result(None) + def set_transport(self, transport): assert self._transport is None, 'Transport already set' self._transport = transport def _maybe_resume_transport(self): - if self._paused and self._byte_count <= self._limit: + if self._paused and len(self._buffer) <= self._limit: self._paused = False self._transport.resume_reading() def feed_eof(self): self._eof = True - waiter = self._waiter - if waiter is not None: - self._waiter = None - if not waiter.cancelled(): - waiter.set_result(True) + self._wakeup_waiter() + + def at_eof(self): + """Return True if the buffer is empty and 'feed_eof' was called.""" + return self._eof and not self._buffer def feed_data(self, data): + assert not self._eof, 'feed_data after feed_eof' + if not data: return - self._buffer.append(data) - self._byte_count += len(data) - - waiter = self._waiter - if waiter is not None: - self._waiter = None - if not waiter.cancelled(): - waiter.set_result(False) + self._buffer.extend(data) + self._wakeup_waiter() if (self._transport is not None and not self._paused and - self._byte_count > 2*self._limit): + len(self._buffer) > 2*self._limit): try: self._transport.pause_reading() except NotImplementedError: @@ -283,33 +407,44 @@ def feed_data(self, data): else: self._paused = True - @tasks.coroutine + @coroutine + def _wait_for_data(self, func_name): + """Wait until feed_data() or feed_eof() is called.""" + # StreamReader uses a future to link the protocol feed_data() method + # to a read coroutine. Running two read coroutines at the same time + # would have an unexpected behaviour. It would not possible to know + # which coroutine would get the next data. + if self._waiter is not None: + raise RuntimeError('%s() called while another coroutine is ' + 'already waiting for incoming data' % func_name) + + self._waiter = futures.Future(loop=self._loop) + try: + yield from self._waiter + finally: + self._waiter = None + + @coroutine def readline(self): if self._exception is not None: raise self._exception - parts = [] - parts_size = 0 + line = bytearray() not_enough = True while not_enough: while self._buffer and not_enough: - data = self._buffer.popleft() - ichar = data.find(b'\n') + ichar = self._buffer.find(b'\n') if ichar < 0: - parts.append(data) - parts_size += len(data) + line.extend(self._buffer) + self._buffer.clear() else: ichar += 1 - head, tail = data[:ichar], data[ichar:] - if tail: - self._buffer.appendleft(tail) + line.extend(self._buffer[:ichar]) + del self._buffer[:ichar] not_enough = False - parts.append(head) - parts_size += len(head) - if parts_size > self._limit: - self._byte_count -= parts_size + if len(line) > self._limit: self._maybe_resume_transport() raise ValueError('Line is too long') @@ -317,20 +452,12 @@ def readline(self): break if not_enough: - assert self._waiter is None - self._waiter = futures.Future(loop=self._loop) - try: - yield from self._waiter - finally: - self._waiter = None - - line = b''.join(parts) - self._byte_count -= parts_size - self._maybe_resume_transport() + yield from self._wait_for_data('readline') - return line + self._maybe_resume_transport() + return bytes(line) - @tasks.coroutine + @coroutine def read(self, n=-1): if self._exception is not None: raise self._exception @@ -339,60 +466,63 @@ def read(self, n=-1): return b'' if n < 0: - while not self._eof: - assert not self._waiter - self._waiter = futures.Future(loop=self._loop) - try: - yield from self._waiter - finally: - self._waiter = None + # This used to just loop creating a new waiter hoping to + # collect everything in self._buffer, but that would + # deadlock if the subprocess sends more than self.limit + # bytes. So just call self.read(self._limit) until EOF. + blocks = [] + while True: + block = yield from self.read(self._limit) + if not block: + break + blocks.append(block) + return b''.join(blocks) else: - if not self._byte_count and not self._eof: - assert not self._waiter - self._waiter = futures.Future(loop=self._loop) - try: - yield from self._waiter - finally: - self._waiter = None - - if n < 0 or self._byte_count <= n: - data = b''.join(self._buffer) + if not self._buffer and not self._eof: + yield from self._wait_for_data('read') + + if n < 0 or len(self._buffer) <= n: + data = bytes(self._buffer) self._buffer.clear() - self._byte_count = 0 - self._maybe_resume_transport() - return data - - parts = [] - parts_bytes = 0 - while self._buffer and parts_bytes < n: - data = self._buffer.popleft() - data_bytes = len(data) - if n < parts_bytes + data_bytes: - data_bytes = n - parts_bytes - data, rest = data[:data_bytes], data[data_bytes:] - self._buffer.appendleft(rest) - - parts.append(data) - parts_bytes += data_bytes - self._byte_count -= data_bytes - self._maybe_resume_transport() - - return b''.join(parts) - - @tasks.coroutine + else: + # n > 0 and len(self._buffer) > n + data = bytes(self._buffer[:n]) + del self._buffer[:n] + + self._maybe_resume_transport() + return data + + @coroutine def readexactly(self, n): if self._exception is not None: raise self._exception - if n <= 0: - return b'' - - while self._byte_count < n and not self._eof: - assert not self._waiter - self._waiter = futures.Future(loop=self._loop) - try: - yield from self._waiter - finally: - self._waiter = None - - return (yield from self.read(n)) + # There used to be "optimized" code here. It created its own + # Future and waited until self._buffer had at least the n + # bytes, then called read(n). Unfortunately, this could pause + # the transport if the argument was larger than the pause + # limit (which is twice self._limit). So now we just read() + # into a local buffer. + + blocks = [] + while n > 0: + block = yield from self.read(n) + if not block: + partial = b''.join(blocks) + raise IncompleteReadError(partial, len(partial) + n) + blocks.append(block) + n -= len(block) + + return b''.join(blocks) + + if compat.PY35: + @coroutine + def __aiter__(self): + return self + + @coroutine + def __anext__(self): + val = yield from self.readline() + if val == b'': + raise StopAsyncIteration + return val diff --git a/Lib/asyncio/subprocess.py b/Lib/asyncio/subprocess.py new file mode 100644 index 000000000000..ead4039b2f7d --- /dev/null +++ b/Lib/asyncio/subprocess.py @@ -0,0 +1,213 @@ +__all__ = ['create_subprocess_exec', 'create_subprocess_shell'] + +import subprocess + +from . import events +from . import protocols +from . import streams +from . import tasks +from .coroutines import coroutine +from .log import logger + + +PIPE = subprocess.PIPE +STDOUT = subprocess.STDOUT +DEVNULL = subprocess.DEVNULL + + +class SubprocessStreamProtocol(streams.FlowControlMixin, + protocols.SubprocessProtocol): + """Like StreamReaderProtocol, but for a subprocess.""" + + def __init__(self, limit, loop): + super().__init__(loop=loop) + self._limit = limit + self.stdin = self.stdout = self.stderr = None + self._transport = None + + def __repr__(self): + info = [self.__class__.__name__] + if self.stdin is not None: + info.append('stdin=%r' % self.stdin) + if self.stdout is not None: + info.append('stdout=%r' % self.stdout) + if self.stderr is not None: + info.append('stderr=%r' % self.stderr) + return '<%s>' % ' '.join(info) + + def connection_made(self, transport): + self._transport = transport + + stdout_transport = transport.get_pipe_transport(1) + if stdout_transport is not None: + self.stdout = streams.StreamReader(limit=self._limit, + loop=self._loop) + self.stdout.set_transport(stdout_transport) + + stderr_transport = transport.get_pipe_transport(2) + if stderr_transport is not None: + self.stderr = streams.StreamReader(limit=self._limit, + loop=self._loop) + self.stderr.set_transport(stderr_transport) + + stdin_transport = transport.get_pipe_transport(0) + if stdin_transport is not None: + self.stdin = streams.StreamWriter(stdin_transport, + protocol=self, + reader=None, + loop=self._loop) + + def pipe_data_received(self, fd, data): + if fd == 1: + reader = self.stdout + elif fd == 2: + reader = self.stderr + else: + reader = None + if reader is not None: + reader.feed_data(data) + + def pipe_connection_lost(self, fd, exc): + if fd == 0: + pipe = self.stdin + if pipe is not None: + pipe.close() + self.connection_lost(exc) + return + if fd == 1: + reader = self.stdout + elif fd == 2: + reader = self.stderr + else: + reader = None + if reader != None: + if exc is None: + reader.feed_eof() + else: + reader.set_exception(exc) + + def process_exited(self): + self._transport.close() + self._transport = None + + +class Process: + def __init__(self, transport, protocol, loop): + self._transport = transport + self._protocol = protocol + self._loop = loop + self.stdin = protocol.stdin + self.stdout = protocol.stdout + self.stderr = protocol.stderr + self.pid = transport.get_pid() + + def __repr__(self): + return '<%s %s>' % (self.__class__.__name__, self.pid) + + @property + def returncode(self): + return self._transport.get_returncode() + + @coroutine + def wait(self): + """Wait until the process exit and return the process return code. + + This method is a coroutine.""" + return (yield from self._transport._wait()) + + def send_signal(self, signal): + self._transport.send_signal(signal) + + def terminate(self): + self._transport.terminate() + + def kill(self): + self._transport.kill() + + @coroutine + def _feed_stdin(self, input): + debug = self._loop.get_debug() + self.stdin.write(input) + if debug: + logger.debug('%r communicate: feed stdin (%s bytes)', + self, len(input)) + try: + yield from self.stdin.drain() + except (BrokenPipeError, ConnectionResetError) as exc: + # communicate() ignores BrokenPipeError and ConnectionResetError + if debug: + logger.debug('%r communicate: stdin got %r', self, exc) + + if debug: + logger.debug('%r communicate: close stdin', self) + self.stdin.close() + + @coroutine + def _noop(self): + return None + + @coroutine + def _read_stream(self, fd): + transport = self._transport.get_pipe_transport(fd) + if fd == 2: + stream = self.stderr + else: + assert fd == 1 + stream = self.stdout + if self._loop.get_debug(): + name = 'stdout' if fd == 1 else 'stderr' + logger.debug('%r communicate: read %s', self, name) + output = yield from stream.read() + if self._loop.get_debug(): + name = 'stdout' if fd == 1 else 'stderr' + logger.debug('%r communicate: close %s', self, name) + transport.close() + return output + + @coroutine + def communicate(self, input=None): + if input: + stdin = self._feed_stdin(input) + else: + stdin = self._noop() + if self.stdout is not None: + stdout = self._read_stream(1) + else: + stdout = self._noop() + if self.stderr is not None: + stderr = self._read_stream(2) + else: + stderr = self._noop() + stdin, stdout, stderr = yield from tasks.gather(stdin, stdout, stderr, + loop=self._loop) + yield from self.wait() + return (stdout, stderr) + + +@coroutine +def create_subprocess_shell(cmd, stdin=None, stdout=None, stderr=None, + loop=None, limit=streams._DEFAULT_LIMIT, **kwds): + if loop is None: + loop = events.get_event_loop() + protocol_factory = lambda: SubprocessStreamProtocol(limit=limit, + loop=loop) + transport, protocol = yield from loop.subprocess_shell( + protocol_factory, + cmd, stdin=stdin, stdout=stdout, + stderr=stderr, **kwds) + return Process(transport, protocol, loop) + +@coroutine +def create_subprocess_exec(program, *args, stdin=None, stdout=None, + stderr=None, loop=None, + limit=streams._DEFAULT_LIMIT, **kwds): + if loop is None: + loop = events.get_event_loop() + protocol_factory = lambda: SubprocessStreamProtocol(limit=limit, + loop=loop) + transport, protocol = yield from loop.subprocess_exec( + protocol_factory, + program, *args, + stdin=stdin, stdout=stdout, + stderr=stderr, **kwds) + return Process(transport, protocol, loop) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 999e9629bc69..b887d88934f2 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -1,110 +1,24 @@ """Support for tasks, coroutines and the scheduler.""" -__all__ = ['coroutine', 'Task', +__all__ = ['Task', 'FIRST_COMPLETED', 'FIRST_EXCEPTION', 'ALL_COMPLETED', 'wait', 'wait_for', 'as_completed', 'sleep', 'async', - 'gather', 'shield', + 'gather', 'shield', 'ensure_future', 'run_coroutine_threadsafe', ] -import collections import concurrent.futures import functools import inspect import linecache import traceback +import warnings import weakref +from . import compat +from . import coroutines from . import events from . import futures -from .log import logger - -# If you set _DEBUG to true, @coroutine will wrap the resulting -# generator objects in a CoroWrapper instance (defined below). That -# instance will log a message when the generator is never iterated -# over, which may happen when you forget to use "yield from" with a -# coroutine call. Note that the value of the _DEBUG flag is taken -# when the decorator is used, so to be of any use it must be set -# before you define your coroutines. A downside of using this feature -# is that tracebacks show entries for the CoroWrapper.__next__ method -# when _DEBUG is true. -_DEBUG = False - - -class CoroWrapper: - """Wrapper for coroutine in _DEBUG mode.""" - - __slot__ = ['gen', 'func'] - - def __init__(self, gen, func): - assert inspect.isgenerator(gen), gen - self.gen = gen - self.func = func - - def __iter__(self): - return self - - def __next__(self): - return next(self.gen) - - def send(self, value): - return self.gen.send(value) - - def throw(self, exc): - return self.gen.throw(exc) - - def close(self): - return self.gen.close() - - def __del__(self): - frame = self.gen.gi_frame - if frame is not None and frame.f_lasti == -1: - func = self.func - code = func.__code__ - filename = code.co_filename - lineno = code.co_firstlineno - logger.error( - 'Coroutine %r defined at %s:%s was never yielded from', - func.__name__, filename, lineno) - - -def coroutine(func): - """Decorator to mark coroutines. - - If the coroutine is not yielded from before it is destroyed, - an error message is logged. - """ - if inspect.isgeneratorfunction(func): - coro = func - else: - @functools.wraps(func) - def coro(*args, **kw): - res = func(*args, **kw) - if isinstance(res, futures.Future) or inspect.isgenerator(res): - res = yield from res - return res - - if not _DEBUG: - wrapper = coro - else: - @functools.wraps(func) - def wrapper(*args, **kwds): - w = CoroWrapper(coro(*args, **kwds), func) - w.__name__ = coro.__name__ - w.__doc__ = coro.__doc__ - return w - - wrapper._is_coroutine = True # For iscoroutinefunction(). - return wrapper - - -def iscoroutinefunction(func): - """Return True if func is a decorated coroutine function.""" - return getattr(func, '_is_coroutine', False) - - -def iscoroutine(obj): - """Return True if obj is a coroutine object.""" - return isinstance(obj, CoroWrapper) or inspect.isgenerator(obj) +from .coroutines import coroutine class Task(futures.Future): @@ -122,6 +36,26 @@ class Task(futures.Future): # Weak set containing all tasks alive. _all_tasks = weakref.WeakSet() + # Dictionary containing tasks that are currently active in + # all running event loops. {EventLoop: Task} + _current_tasks = {} + + # If False, don't log a message if the task is destroyed whereas its + # status is still pending + _log_destroy_pending = True + + @classmethod + def current_task(cls, loop=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. + """ + if loop is None: + loop = events.get_event_loop() + return cls._current_tasks.get(loop) + @classmethod def all_tasks(cls, loop=None): """Return a set of all tasks for an event loop. @@ -133,30 +67,49 @@ def all_tasks(cls, loop=None): return {t for t in cls._all_tasks if t._loop is loop} def __init__(self, coro, *, loop=None): - assert iscoroutine(coro), repr(coro) # Not a coroutine function! + assert coroutines.iscoroutine(coro), repr(coro) super().__init__(loop=loop) - self._coro = iter(coro) # Use the iterator just in case. + if self._source_traceback: + del self._source_traceback[-1] + self._coro = coro self._fut_waiter = None self._must_cancel = False self._loop.call_soon(self._step) self.__class__._all_tasks.add(self) - def __repr__(self): - res = super().__repr__() - if (self._must_cancel and - self._state == futures._PENDING and - '<PENDING' in res): - res = res.replace('<PENDING', '<CANCELLING', 1) - i = res.find('<') - if i < 0: - i = len(res) - res = res[:i] + '(<{}>)'.format(self._coro.__name__) + res[i:] - return res + # On Python 3.3 or older, objects with a destructor that are part of a + # reference cycle are never destroyed. That's not the case any more on + # Python 3.4 thanks to the PEP 442. + if compat.PY34: + def __del__(self): + if self._state == futures._PENDING and self._log_destroy_pending: + context = { + 'task': self, + 'message': 'Task was destroyed but it is pending!', + } + if self._source_traceback: + context['source_traceback'] = self._source_traceback + self._loop.call_exception_handler(context) + futures.Future.__del__(self) + + def _repr_info(self): + info = super()._repr_info() + + if self._must_cancel: + # replace status + info[0] = 'cancelling' + + coro = coroutines._format_coroutine(self._coro) + info.insert(1, 'coro=<%s>' % coro) + + if self._fut_waiter is not None: + info.insert(2, 'wait_for=%r' % self._fut_waiter) + return info def get_stack(self, *, limit=None): """Return the list of stack frames for this task's coroutine. - If the coroutine is active, this returns the stack where it is + 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 @@ -164,7 +117,7 @@ def get_stack(self, *, limit=None): The frames are always ordered from oldest to newest. - The optional limit gives the maximum nummber of frames to + 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 @@ -175,7 +128,11 @@ def get_stack(self, *, limit=None): returned for a suspended coroutine. """ frames = [] - f = self._coro.gi_frame + try: + # 'async def' coroutines + f = self._coro.cr_frame + except AttributeError: + f = self._coro.gi_frame if f is not None: while f is not None: if limit is not None: @@ -202,7 +159,8 @@ def print_stack(self, *, limit=None, file=None): 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 goes; by default it goes to sys.stderr. + to which the output is written; by default output is written + to sys.stderr. """ extracted_list = [] checked = set() @@ -231,6 +189,25 @@ def print_stack(self, *, limit=None, file=None): print(line, file=file, end='') def cancel(self): + """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). + """ if self.done(): return False if self._fut_waiter is not None: @@ -252,14 +229,14 @@ def _step(self, value=None, exc=None): self._must_cancel = False coro = self._coro self._fut_waiter = None + + self.__class__._current_tasks[self._loop] = self # Call either coro.throw(exc) or coro.send(value). try: if exc is not None: result = coro.throw(exc) - elif value is not None: - result = coro.send(value) else: - result = next(coro) + result = coro.send(value) except StopIteration as exc: self.set_result(exc.value) except futures.CancelledError as exc: @@ -302,7 +279,9 @@ def _step(self, value=None, exc=None): self._step, None, RuntimeError( 'Task got bad yield: {!r}'.format(result))) - self = None + finally: + self.__class__._current_tasks.pop(self._loop) + self = None # Needed to break cycles when an exception occurs. def _wakeup(self, future): try: @@ -326,6 +305,8 @@ def _wakeup(self, future): def wait(fs, *, loop=None, timeout=None, return_when=ALL_COMPLETED): """Wait for the Futures and coroutines given by fs to complete. + The sequence futures must not be empty. + Coroutines will be wrapped in Tasks. Returns two sets of Future: (done, pending). @@ -337,22 +318,24 @@ def wait(fs, *, loop=None, timeout=None, return_when=ALL_COMPLETED): Note: This does not raise TimeoutError! Futures that aren't done when the timeout occurs are returned in the second set. """ + if isinstance(fs, futures.Future) or coroutines.iscoroutine(fs): + raise TypeError("expect a list of futures, not %s" % type(fs).__name__) if not fs: raise ValueError('Set of coroutines/Futures is empty.') + if return_when not in (FIRST_COMPLETED, FIRST_EXCEPTION, ALL_COMPLETED): + raise ValueError('Invalid return_when value: {}'.format(return_when)) if loop is None: loop = events.get_event_loop() - fs = set(async(f, loop=loop) for f in fs) + fs = {ensure_future(f, loop=loop) for f in set(fs)} - if return_when not in (FIRST_COMPLETED, FIRST_EXCEPTION, ALL_COMPLETED): - raise ValueError('Invalid return_when value: {}'.format(return_when)) return (yield from _wait(fs, timeout, return_when, loop)) -def _release_waiter(waiter, value=True, *args): +def _release_waiter(waiter, *args): if not waiter.done(): - waiter.set_result(value) + waiter.set_result(None) @coroutine @@ -361,29 +344,41 @@ def wait_for(fut, timeout, *, loop=None): Coroutine will be wrapped in Task. - Returns result of the Future or coroutine. Raises TimeoutError when - timeout occurs. - - Usage: + Returns result of the Future or coroutine. When a timeout occurs, + it cancels the task and raises TimeoutError. To avoid the task + cancellation, wrap it in shield(). - result = yield from asyncio.wait_for(fut, 10.0) + If the wait is cancelled, the task is also cancelled. + This function is a coroutine. """ if loop is None: loop = events.get_event_loop() + if timeout is None: + return (yield from fut) + waiter = futures.Future(loop=loop) - timeout_handle = loop.call_later(timeout, _release_waiter, waiter, False) - cb = functools.partial(_release_waiter, waiter, True) + timeout_handle = loop.call_later(timeout, _release_waiter, waiter) + cb = functools.partial(_release_waiter, waiter) - fut = async(fut, loop=loop) + fut = ensure_future(fut, loop=loop) fut.add_done_callback(cb) try: - if (yield from waiter): + # wait until the future completes or the timeout + try: + yield from waiter + except futures.CancelledError: + fut.remove_done_callback(cb) + fut.cancel() + raise + + if fut.done(): return fut.result() else: fut.remove_done_callback(cb) + fut.cancel() raise futures.TimeoutError() finally: timeout_handle.cancel() @@ -412,7 +407,7 @@ def _on_completion(f): if timeout_handle is not None: timeout_handle.cancel() if not waiter.done(): - waiter.set_result(False) + waiter.set_result(None) for f in fs: f.add_done_callback(_on_completion) @@ -435,7 +430,11 @@ def _on_completion(f): # This is *not* a @coroutine! It is just an iterator (yielding Futures). def as_completed(fs, *, loop=None, timeout=None): - """Return an iterator whose values, when waited for, are Futures. + """Return an iterator whose values are coroutines. + + When waiting for the yielded coroutines you'll get the results (or + exceptions!) of the original Futures (or coroutines), in the order + in which and as soon as they complete. This differs from PEP 3148; the proper way to use this is: @@ -443,35 +442,45 @@ def as_completed(fs, *, loop=None, timeout=None): result = yield from f # The 'yield from' may raise. # Use result. - Raises TimeoutError if the timeout occurs before all Futures are - done. + If a timeout is specified, the 'yield from' will raise + TimeoutError when the timeout occurs before all Futures are done. Note: The futures 'f' are not necessarily members of fs. """ + if isinstance(fs, futures.Future) or coroutines.iscoroutine(fs): + raise TypeError("expect a list of futures, not %s" % type(fs).__name__) loop = loop if loop is not None else events.get_event_loop() - deadline = None if timeout is None else loop.time() + timeout - todo = set(async(f, loop=loop) for f in fs) - completed = collections.deque() + todo = {ensure_future(f, loop=loop) for f in set(fs)} + from .queues import Queue # Import here to avoid circular import problem. + done = Queue(loop=loop) + timeout_handle = None + + def _on_timeout(): + for f in todo: + f.remove_done_callback(_on_completion) + done.put_nowait(None) # Queue a dummy value for _wait_for_one(). + todo.clear() # Can't do todo.remove(f) in the loop. + + def _on_completion(f): + if not todo: + return # _on_timeout() was here first. + todo.remove(f) + done.put_nowait(f) + if not todo and timeout_handle is not None: + timeout_handle.cancel() @coroutine def _wait_for_one(): - while not completed: - timeout = None - if deadline is not None: - timeout = deadline - loop.time() - if timeout < 0: - raise futures.TimeoutError() - done, pending = yield from _wait( - todo, timeout, FIRST_COMPLETED, loop) - # Multiple callers might be waiting for the same events - # and getting the same outcome. Dedupe by updating todo. - for f in done: - if f in todo: - todo.remove(f) - completed.append(f) - f = completed.popleft() - return f.result() # May raise. + f = yield from done.get() + if f is None: + # Dummy value from _on_timeout(). + raise futures.TimeoutError + return f.result() # May raise f.exception(). + for f in todo: + f.add_done_callback(_on_completion) + if todo and timeout is not None: + timeout_handle = loop.call_later(timeout, _on_timeout) for _ in range(len(todo)): yield _wait_for_one() @@ -480,7 +489,8 @@ def _wait_for_one(): def sleep(delay, result=None, *, loop=None): """Coroutine that completes after a given time (in seconds).""" future = futures.Future(loop=loop) - h = future._loop.call_later(delay, future.set_result, result) + h = future._loop.call_later(delay, + future._set_result_unless_cancelled, result) try: return (yield from future) finally: @@ -490,16 +500,47 @@ def sleep(delay, result=None, *, loop=None): def async(coro_or_future, *, loop=None): """Wrap a coroutine in a future. + If the argument is a Future, it is returned directly. + + This function is deprecated in 3.5. Use asyncio.ensure_future() instead. + """ + + warnings.warn("asyncio.async() function is deprecated, use ensure_future()", + DeprecationWarning) + + return ensure_future(coro_or_future, loop=loop) + + +def ensure_future(coro_or_future, *, loop=None): + """Wrap a coroutine or an awaitable in a future. + If the argument is a Future, it is returned directly. """ if isinstance(coro_or_future, futures.Future): if loop is not None and loop is not coro_or_future._loop: raise ValueError('loop argument must agree with Future') return coro_or_future - elif iscoroutine(coro_or_future): - return Task(coro_or_future, loop=loop) + elif coroutines.iscoroutine(coro_or_future): + if loop is None: + loop = events.get_event_loop() + task = loop.create_task(coro_or_future) + if task._source_traceback: + del task._source_traceback[-1] + return task + elif compat.PY35 and inspect.isawaitable(coro_or_future): + return ensure_future(_wrap_awaitable(coro_or_future), loop=loop) else: - raise TypeError('A Future or coroutine is required') + raise TypeError('A Future, a coroutine or an awaitable is required') + + +@coroutine +def _wrap_awaitable(awaitable): + """Helper for asyncio.ensure_future(). + + Wraps awaitable (an object with __await__) into a coroutine + that will later be wrapped in a Task by ensure_future(). + """ + return (yield from awaitable.__await__()) class _GatheringFuture(futures.Future): @@ -529,7 +570,7 @@ def gather(*coros_or_futures, loop=None, return_exceptions=False): All futures must share the same event loop. If all the tasks are done successfully, the returned future's result is the list of results (in the order of the original sequence, not necessarily - the order of results arrival). If *result_exception* is True, + the order of results arrival). If *return_exceptions* is True, exceptions in the tasks are treated the same as successful results, and gathered in the result list; otherwise, the first raised exception will be immediately propagated to the returned @@ -542,29 +583,43 @@ def gather(*coros_or_futures, loop=None, return_exceptions=False): prevent the cancellation of one child to cause other children to be cancelled.) """ - children = [async(fut, loop=loop) for fut in coros_or_futures] - n = len(children) - if n == 0: + if not coros_or_futures: outer = futures.Future(loop=loop) outer.set_result([]) return outer - if loop is None: - loop = children[0]._loop - for fut in children: - if fut._loop is not loop: - raise ValueError("futures are tied to different event loops") + + arg_to_fut = {} + for arg in set(coros_or_futures): + if not isinstance(arg, futures.Future): + fut = ensure_future(arg, loop=loop) + if loop is None: + loop = fut._loop + # The caller cannot control this future, the "destroy pending task" + # warning should not be emitted. + fut._log_destroy_pending = False + else: + fut = arg + if loop is None: + loop = fut._loop + elif fut._loop is not loop: + raise ValueError("futures are tied to different event loops") + arg_to_fut[arg] = fut + + children = [arg_to_fut[arg] for arg in coros_or_futures] + nchildren = len(children) outer = _GatheringFuture(children, loop=loop) nfinished = 0 - results = [None] * n + results = [None] * nchildren def _done_callback(i, fut): nonlocal nfinished - if outer._state != futures._PENDING: - if fut._exception is not None: + if outer.done(): + if not fut.cancelled(): # Mark exception retrieved. fut.exception() return - if fut._state == futures._CANCELLED: + + if fut.cancelled(): res = futures.CancelledError() if not return_exceptions: outer.set_exception(res) @@ -578,7 +633,7 @@ def _done_callback(i, fut): res = fut._result results[i] = res nfinished += 1 - if nfinished == n: + if nfinished == nchildren: outer.set_result(results) for i, fut in enumerate(children): @@ -612,7 +667,7 @@ def shield(arg, *, loop=None): except CancelledError: res = None """ - inner = async(arg, loop=loop) + inner = ensure_future(arg, loop=loop) if inner.done(): # Shortcut. return inner @@ -621,9 +676,11 @@ def shield(arg, *, loop=None): def _done_callback(inner): if outer.cancelled(): - # Mark inner's result as retrieved. - inner.cancelled() or inner.exception() + if not inner.cancelled(): + # Mark inner's result as retrieved. + inner.exception() return + if inner.cancelled(): outer.cancel() else: @@ -635,3 +692,24 @@ def _done_callback(inner): inner.add_done_callback(_done_callback) return outer + + +def run_coroutine_threadsafe(coro, loop): + """Submit a coroutine object to a given event loop. + + Return a concurrent.futures.Future to access the result. + """ + if not coroutines.iscoroutine(coro): + raise TypeError('A coroutine object is required') + future = concurrent.futures.Future() + + def callback(): + try: + futures._chain_future(ensure_future(coro, loop=loop), future) + except Exception as exc: + if future.set_running_or_notify_cancel(): + future.set_exception(exc) + raise + + loop.call_soon_threadsafe(callback) + return future diff --git a/Lib/asyncio/test_utils.py b/Lib/asyncio/test_utils.py index d7d844249c4f..8cee95b84f95 100644 --- a/Lib/asyncio/test_utils.py +++ b/Lib/asyncio/test_utils.py @@ -3,23 +3,33 @@ import collections import contextlib import io -import unittest.mock +import logging import os +import re +import socket +import socketserver import sys +import tempfile import threading import time import unittest -import unittest.mock -from wsgiref.simple_server import make_server, WSGIRequestHandler, WSGIServer +from unittest import mock + +from http.server import HTTPServer +from wsgiref.simple_server import WSGIRequestHandler, WSGIServer + try: import ssl except ImportError: # pragma: no cover ssl = None -from . import tasks from . import base_events from . import events +from . import futures from . import selectors +from . import tasks +from .coroutines import coroutine +from .log import logger if sys.platform == 'win32': # pragma: no cover @@ -36,29 +46,28 @@ def dummy_ssl_context(): def run_briefly(loop): - @tasks.coroutine + @coroutine def once(): pass gen = once() - t = tasks.Task(gen, loop=loop) + t = loop.create_task(gen) + # Don't log a warning if the task is not done after run_until_complete(). + # It occurs if the loop is stopped or if a task raises a BaseException. + t._log_destroy_pending = False try: loop.run_until_complete(t) finally: gen.close() -def run_until(loop, pred, timeout=None): - if timeout is not None: - deadline = time.time() + timeout +def run_until(loop, pred, timeout=30): + deadline = time.time() + timeout while not pred(): if timeout is not None: timeout = deadline - time.time() if timeout <= 0: - return False - loop.run_until_complete(tasks.sleep(timeout, loop=loop)) - else: - run_briefly(loop) - return True + raise futures.TimeoutError() + loop.run_until_complete(tasks.sleep(0.001, loop=loop)) def run_once(loop): @@ -71,42 +80,58 @@ def run_once(loop): loop.run_forever() -@contextlib.contextmanager -def run_test_server(*, host='127.0.0.1', port=0, use_ssl=False): +class SilentWSGIRequestHandler(WSGIRequestHandler): - class SilentWSGIRequestHandler(WSGIRequestHandler): - def get_stderr(self): - return io.StringIO() + def get_stderr(self): + return io.StringIO() - def log_message(self, format, *args): - pass + def log_message(self, format, *args): + pass - class SilentWSGIServer(WSGIServer): - def handle_error(self, request, client_address): + +class SilentWSGIServer(WSGIServer): + + request_timeout = 2 + + def get_request(self): + request, client_addr = super().get_request() + request.settimeout(self.request_timeout) + return request, client_addr + + def handle_error(self, request, client_address): + pass + + +class SSLWSGIServerMixin: + + def finish_request(self, request, client_address): + # The relative location of our test directory (which + # contains the ssl key and certificate files) differs + # between the stdlib and stand-alone asyncio. + # Prefer our own if we can find it. + here = os.path.join(os.path.dirname(__file__), '..', 'tests') + if not os.path.isdir(here): + here = os.path.join(os.path.dirname(os.__file__), + 'test', 'test_asyncio') + keyfile = os.path.join(here, 'ssl_key.pem') + certfile = os.path.join(here, 'ssl_cert.pem') + ssock = ssl.wrap_socket(request, + keyfile=keyfile, + certfile=certfile, + server_side=True) + try: + self.RequestHandlerClass(ssock, client_address, self) + ssock.close() + except OSError: + # maybe socket has been closed by peer pass - class SSLWSGIServer(SilentWSGIServer): - def finish_request(self, request, client_address): - # The relative location of our test directory (which - # contains the sample key and certificate files) differs - # between the stdlib and stand-alone Tulip/asyncio. - # Prefer our own if we can find it. - here = os.path.join(os.path.dirname(__file__), '..', 'tests') - if not os.path.isdir(here): - here = os.path.join(os.path.dirname(os.__file__), - 'test', 'test_asyncio') - keyfile = os.path.join(here, 'sample.key') - certfile = os.path.join(here, 'sample.crt') - ssock = ssl.wrap_socket(request, - keyfile=keyfile, - certfile=certfile, - server_side=True) - try: - self.RequestHandlerClass(ssock, client_address, self) - ssock.close() - except OSError: - # maybe socket has been closed by peer - pass + +class SSLWSGIServer(SSLWSGIServerMixin, SilentWSGIServer): + pass + + +def _run_test_server(*, address, use_ssl=False, server_cls, server_ssl_cls): def app(environ, start_response): status = '200 OK' @@ -116,11 +141,12 @@ def app(environ, start_response): # Run the test WSGI server in a separate thread in order not to # interfere with event handling in the main thread - server_class = SSLWSGIServer if use_ssl else SilentWSGIServer - httpd = make_server(host, port, app, - server_class, SilentWSGIRequestHandler) + server_class = server_ssl_cls if use_ssl else server_cls + httpd = server_class(address, SilentWSGIRequestHandler) + httpd.set_app(app) httpd.address = httpd.server_address - server_thread = threading.Thread(target=httpd.serve_forever) + server_thread = threading.Thread( + target=lambda: httpd.serve_forever(poll_interval=0.05)) server_thread.start() try: yield httpd @@ -130,13 +156,85 @@ def app(environ, start_response): server_thread.join() +if hasattr(socket, 'AF_UNIX'): + + class UnixHTTPServer(socketserver.UnixStreamServer, HTTPServer): + + def server_bind(self): + socketserver.UnixStreamServer.server_bind(self) + self.server_name = '127.0.0.1' + self.server_port = 80 + + + class UnixWSGIServer(UnixHTTPServer, WSGIServer): + + request_timeout = 2 + + def server_bind(self): + UnixHTTPServer.server_bind(self) + self.setup_environ() + + def get_request(self): + request, client_addr = super().get_request() + request.settimeout(self.request_timeout) + # Code in the stdlib expects that get_request + # will return a socket and a tuple (host, port). + # However, this isn't true for UNIX sockets, + # as the second return value will be a path; + # hence we return some fake data sufficient + # to get the tests going + return request, ('127.0.0.1', '') + + + class SilentUnixWSGIServer(UnixWSGIServer): + + def handle_error(self, request, client_address): + pass + + + class UnixSSLWSGIServer(SSLWSGIServerMixin, SilentUnixWSGIServer): + pass + + + def gen_unix_socket_path(): + with tempfile.NamedTemporaryFile() as file: + return file.name + + + @contextlib.contextmanager + def unix_socket_path(): + path = gen_unix_socket_path() + try: + yield path + finally: + try: + os.unlink(path) + except OSError: + pass + + + @contextlib.contextmanager + def run_test_unix_server(*, use_ssl=False): + with unix_socket_path() as path: + yield from _run_test_server(address=path, use_ssl=use_ssl, + server_cls=SilentUnixWSGIServer, + server_ssl_cls=UnixSSLWSGIServer) + + +@contextlib.contextmanager +def run_test_server(*, host='127.0.0.1', port=0, use_ssl=False): + yield from _run_test_server(address=(host, port), use_ssl=use_ssl, + server_cls=SilentWSGIServer, + server_ssl_cls=SSLWSGIServer) + + def make_test_protocol(base): dct = {} for name in dir(base): if name.startswith('__') and name.endswith('__'): # skip magic names continue - dct[name] = unittest.mock.Mock(return_value=None) + dct[name] = MockCallback(return_value=None) return type('TestProtocol', (base,) + base.__bases__, dct)() @@ -175,7 +273,7 @@ def gen(): when = yield ... ... = yield time_advance - Value retuned by yield is absolute time of next scheduled handler. + Value returned by yield is absolute time of next scheduled handler. Value passed to yield is time advance to move loop's time forward. """ @@ -192,6 +290,7 @@ def gen(): self._gen = gen() next(self._gen) self._time = 0 + self._clock_resolution = 1e-9 self._timers = [] self._selector = TestSelector() @@ -208,6 +307,7 @@ def advance_time(self, advance): self._time += advance def close(self): + super().close() if self._check_on_close: try: self._gen.send(0) @@ -217,7 +317,7 @@ def close(self): raise AssertionError("Time generator is not finished") def add_reader(self, fd, callback, *args): - self.readers[fd] = events.make_handle(callback, args) + self.readers[fd] = events.Handle(callback, args, self) def remove_reader(self, fd): self.remove_reader_count[fd] += 1 @@ -236,7 +336,7 @@ def assert_reader(self, fd, callback, *args): handle._args, args) def add_writer(self, fd, callback, *args): - self.writers[fd] = events.make_handle(callback, args) + self.writers[fd] = events.Handle(callback, args, self) def remove_writer(self, fd): self.remove_writer_count[fd] += 1 @@ -274,3 +374,73 @@ def _process_events(self, event_list): def _write_to_self(self): pass + + +def MockCallback(**kwargs): + return mock.Mock(spec=['__call__'], **kwargs) + + +class MockPattern(str): + """A regex based str with a fuzzy __eq__. + + Use this helper with 'mock.assert_called_with', or anywhere + where a regex comparison between strings is needed. + + For instance: + mock_call.assert_called_with(MockPattern('spam.*ham')) + """ + def __eq__(self, other): + return bool(re.search(str(self), other, re.S)) + + +def get_function_source(func): + source = events._get_function_source(func) + if source is None: + raise ValueError("unable to get the source of %r" % (func,)) + return source + + +class TestCase(unittest.TestCase): + def set_event_loop(self, loop, *, cleanup=True): + assert loop is not None + # ensure that the event loop is passed explicitly in asyncio + events.set_event_loop(None) + if cleanup: + self.addCleanup(loop.close) + + def new_test_loop(self, gen=None): + loop = TestLoop(gen) + self.set_event_loop(loop) + return loop + + def tearDown(self): + events.set_event_loop(None) + + # Detect CPython bug #23353: ensure that yield/yield-from is not used + # in an except block of a generator + self.assertEqual(sys.exc_info(), (None, None, None)) + + +@contextlib.contextmanager +def disable_logger(): + """Context manager to disable asyncio logger. + + For example, it can be used to ignore warnings in debug mode. + """ + old_level = logger.level + try: + logger.setLevel(logging.CRITICAL+1) + yield + finally: + logger.setLevel(old_level) + +def mock_nonblocking_socket(): + """Create a mock of a non-blocking socket.""" + sock = mock.Mock(socket.socket) + sock.gettimeout.return_value = 0.0 + return sock + + +def force_legacy_ssl_support(): + return mock.patch('asyncio.sslproto._is_sslproto_available', + return_value=False) diff --git a/Lib/asyncio/transports.py b/Lib/asyncio/transports.py index 86b850e918a9..70b323f2db98 100644 --- a/Lib/asyncio/transports.py +++ b/Lib/asyncio/transports.py @@ -1,6 +1,10 @@ """Abstract Transport class.""" -__all__ = ['ReadTransport', 'WriteTransport', 'Transport'] +from asyncio import compat + +__all__ = ['BaseTransport', 'ReadTransport', 'WriteTransport', + 'Transport', 'DatagramTransport', 'SubprocessTransport', + ] class BaseTransport: @@ -85,11 +89,11 @@ def write(self, data): def writelines(self, list_of_data): """Write a list (or any iterable) of data bytes to the transport. - The default implementation just calls write() for each item in - the list/iterable. + The default implementation concatenates the arguments and + calls write() on the result. """ - for data in list_of_data: - self.write(data) + data = compat.flatten_list_bytes(list_of_data) + self.write(data) def write_eof(self): """Close the write end after flushing buffered data. @@ -209,3 +213,82 @@ def kill(self): http://docs.python.org/3/library/subprocess#subprocess.Popen.kill """ raise NotImplementedError + + +class _FlowControlMixin(Transport): + """All the logic for (write) flow control in a mix-in base class. + + The subclass must implement get_write_buffer_size(). It must call + _maybe_pause_protocol() whenever the write buffer size increases, + and _maybe_resume_protocol() whenever it decreases. It may also + override set_write_buffer_limits() (e.g. to specify different + defaults). + + The subclass constructor must call super().__init__(extra). This + will call set_write_buffer_limits(). + + The user may call set_write_buffer_limits() and + get_write_buffer_size(), and their protocol's pause_writing() and + resume_writing() may be called. + """ + + def __init__(self, extra=None, loop=None): + super().__init__(extra) + assert loop is not None + self._loop = loop + self._protocol_paused = False + self._set_write_buffer_limits() + + def _maybe_pause_protocol(self): + size = self.get_write_buffer_size() + if size <= self._high_water: + return + if not self._protocol_paused: + self._protocol_paused = True + try: + self._protocol.pause_writing() + except Exception as exc: + self._loop.call_exception_handler({ + 'message': 'protocol.pause_writing() failed', + 'exception': exc, + 'transport': self, + 'protocol': self._protocol, + }) + + def _maybe_resume_protocol(self): + if (self._protocol_paused and + self.get_write_buffer_size() <= self._low_water): + self._protocol_paused = False + try: + self._protocol.resume_writing() + except Exception as exc: + self._loop.call_exception_handler({ + 'message': 'protocol.resume_writing() failed', + 'exception': exc, + 'transport': self, + 'protocol': self._protocol, + }) + + def get_write_buffer_limits(self): + return (self._low_water, self._high_water) + + def _set_write_buffer_limits(self, high=None, low=None): + if high is None: + if low is None: + high = 64*1024 + else: + high = 4*low + if low is None: + low = high // 4 + if not high >= low >= 0: + raise ValueError('high (%r) must be >= low (%r) must be >= 0' % + (high, low)) + self._high_water = high + self._low_water = low + + def set_write_buffer_limits(self, high=None, low=None): + self._set_write_buffer_limits(high=high, low=low) + self._maybe_pause_protocol() + + def get_write_buffer_size(self): + raise NotImplementedError diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index b611efd17d14..bf3b0844fda8 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -1,7 +1,6 @@ -"""Selector eventloop for Unix with signal handling.""" +"""Selector event loop for Unix with signal handling.""" import errno -import fcntl import os import signal import socket @@ -9,36 +8,41 @@ import subprocess import sys import threading +import warnings +from . import base_events from . import base_subprocess +from . import compat from . import constants +from . import coroutines from . import events -from . import protocols +from . import futures from . import selector_events -from . import tasks +from . import selectors from . import transports +from .coroutines import coroutine from .log import logger -__all__ = ['SelectorEventLoop', 'STDIN', 'STDOUT', 'STDERR', +__all__ = ['SelectorEventLoop', 'AbstractChildWatcher', 'SafeChildWatcher', 'FastChildWatcher', 'DefaultEventLoopPolicy', ] -STDIN = 0 -STDOUT = 1 -STDERR = 2 - - if sys.platform == 'win32': # pragma: no cover raise ImportError('Signals are not really supported on Windows') +def _sighandler_noop(signum, frame): + """Dummy signal handler.""" + pass + + class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop): - """Unix event loop + """Unix event loop. - Adds signal handling to SelectorEventLoop + Adds signal handling and UNIX Domain Socket support to SelectorEventLoop. """ def __init__(self, selector=None): @@ -49,9 +53,16 @@ def _socketpair(self): return socket.socketpair() def close(self): + super().close() for sig in list(self._signal_handlers): self.remove_signal_handler(sig) - super().close() + + def _process_self_data(self, data): + for signum in data: + if not signum: + # ignore null bytes written by _write_to_self() + continue + self._handle_signal(signum) def add_signal_handler(self, sig, callback, *args): """Add a handler for a signal. UNIX only. @@ -59,27 +70,38 @@ def add_signal_handler(self, sig, callback, *args): Raise ValueError if the signal number is invalid or uncatchable. Raise RuntimeError if there is a problem setting up the handler. """ + if (coroutines.iscoroutine(callback) + or coroutines.iscoroutinefunction(callback)): + raise TypeError("coroutines cannot be used " + "with add_signal_handler()") self._check_signal(sig) + self._check_closed() try: # set_wakeup_fd() raises ValueError if this is not the # main thread. By calling it early we ensure that an # event loop running in another thread cannot add a signal # handler. signal.set_wakeup_fd(self._csock.fileno()) - except ValueError as exc: + except (ValueError, OSError) as exc: raise RuntimeError(str(exc)) - handle = events.make_handle(callback, args) + handle = events.Handle(callback, args, self) self._signal_handlers[sig] = handle try: - signal.signal(sig, self._handle_signal) + # Register a dummy signal handler to ask Python to write the signal + # number in the wakup file descriptor. _process_self_data() will + # read signal numbers from this file descriptor to handle signals. + signal.signal(sig, _sighandler_noop) + + # Set SA_RESTART to limit EINTR occurrences. + signal.siginterrupt(sig, False) except OSError as exc: del self._signal_handlers[sig] if not self._signal_handlers: try: signal.set_wakeup_fd(-1) - except ValueError as nexc: + except (ValueError, OSError) as nexc: logger.info('set_wakeup_fd(-1) failed: %s', nexc) if exc.errno == errno.EINVAL: @@ -87,7 +109,7 @@ def add_signal_handler(self, sig, callback, *args): else: raise - def _handle_signal(self, sig, arg): + def _handle_signal(self, sig): """Internal helper that is the actual signal handler.""" handle = self._signal_handlers.get(sig) if handle is None: @@ -124,7 +146,7 @@ def remove_signal_handler(self, sig): if not self._signal_handlers: try: signal.set_wakeup_fd(-1) - except ValueError as exc: + except (ValueError, OSError) as exc: logger.info('set_wakeup_fd(-1) failed: %s', exc) return True @@ -150,35 +172,132 @@ def _make_write_pipe_transport(self, pipe, protocol, waiter=None, extra=None): return _UnixWritePipeTransport(self, pipe, protocol, waiter, extra) - @tasks.coroutine + @coroutine def _make_subprocess_transport(self, protocol, args, shell, stdin, stdout, stderr, bufsize, extra=None, **kwargs): with events.get_child_watcher() as watcher: + waiter = futures.Future(loop=self) transp = _UnixSubprocessTransport(self, protocol, args, shell, stdin, stdout, stderr, bufsize, - extra=None, **kwargs) + waiter=waiter, extra=extra, + **kwargs) + watcher.add_child_handler(transp.get_pid(), self._child_watcher_callback, transp) - yield from transp._post_init() + try: + yield from waiter + except Exception as exc: + # Workaround CPython bug #23353: using yield/yield-from in an + # except block of a generator doesn't clear properly + # sys.exc_info() + err = exc + else: + err = None + + if err is not None: + transp.close() + yield from transp._wait() + raise err + return transp def _child_watcher_callback(self, pid, returncode, transp): self.call_soon_threadsafe(transp._process_exited, returncode) - def _subprocess_closed(self, transp): - pass + @coroutine + def create_unix_connection(self, protocol_factory, path, *, + ssl=None, sock=None, + server_hostname=None): + assert server_hostname is None or isinstance(server_hostname, str) + if ssl: + if server_hostname is None: + raise ValueError( + 'you have to pass server_hostname when using ssl') + else: + if server_hostname is not None: + raise ValueError('server_hostname is only meaningful with ssl') + if path is not None: + if sock is not None: + raise ValueError( + 'path and sock can not be specified at the same time') -def _set_nonblocking(fd): - flags = fcntl.fcntl(fd, fcntl.F_GETFL) - flags = flags | os.O_NONBLOCK - fcntl.fcntl(fd, fcntl.F_SETFL, flags) + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0) + try: + sock.setblocking(False) + yield from self.sock_connect(sock, path) + except: + sock.close() + raise + + else: + if sock is None: + raise ValueError('no path and sock were specified') + sock.setblocking(False) + + transport, protocol = yield from self._create_connection_transport( + sock, protocol_factory, ssl, server_hostname) + return transport, protocol + + @coroutine + def create_unix_server(self, protocol_factory, path=None, *, + sock=None, backlog=100, ssl=None): + if isinstance(ssl, bool): + raise TypeError('ssl argument must be an SSLContext or None') + + if path is not None: + if sock is not None: + raise ValueError( + 'path and sock can not be specified at the same time') + + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + + try: + sock.bind(path) + except OSError as exc: + sock.close() + if exc.errno == errno.EADDRINUSE: + # Let's improve the error message by adding + # with what exact address it occurs. + msg = 'Address {!r} is already in use'.format(path) + raise OSError(errno.EADDRINUSE, msg) from None + else: + raise + except: + sock.close() + raise + else: + if sock is None: + raise ValueError( + 'path was not specified, and no sock specified') + + if sock.family != socket.AF_UNIX: + raise ValueError( + 'A UNIX Domain Socket was expected, got {!r}'.format(sock)) + + server = base_events.Server(self, [sock]) + sock.listen(backlog) + sock.setblocking(False) + self._start_serving(protocol_factory, sock, ssl, server) + return server + + +if hasattr(os, 'set_blocking'): + def _set_nonblocking(fd): + os.set_blocking(fd, False) +else: + import fcntl + + def _set_nonblocking(fd): + flags = fcntl.fcntl(fd, fcntl.F_GETFL) + flags = flags | os.O_NONBLOCK + fcntl.fcntl(fd, fcntl.F_SETFL, flags) class _UnixReadPipeTransport(transports.ReadTransport): - max_size = 256 * 1024 # max bytes we read in one eventloop iteration + max_size = 256 * 1024 # max bytes we read in one event loop iteration def __init__(self, loop, pipe, protocol, waiter=None, extra=None): super().__init__(extra) @@ -187,15 +306,39 @@ def __init__(self, loop, pipe, protocol, waiter=None, extra=None): self._pipe = pipe self._fileno = pipe.fileno() mode = os.fstat(self._fileno).st_mode - if not (stat.S_ISFIFO(mode) or stat.S_ISSOCK(mode)): + if not (stat.S_ISFIFO(mode) or + stat.S_ISSOCK(mode) or + stat.S_ISCHR(mode)): raise ValueError("Pipe transport is for pipes/sockets only.") _set_nonblocking(self._fileno) self._protocol = protocol self._closing = False - self._loop.add_reader(self._fileno, self._read_ready) self._loop.call_soon(self._protocol.connection_made, self) + # only start reading when connection_made() has been called + self._loop.call_soon(self._loop.add_reader, + self._fileno, self._read_ready) if waiter is not None: - self._loop.call_soon(waiter.set_result, None) + # only wake up the waiter when connection_made() has been called + self._loop.call_soon(waiter._set_result_unless_cancelled, None) + + def __repr__(self): + info = [self.__class__.__name__] + if self._pipe is None: + info.append('closed') + elif self._closing: + info.append('closing') + info.append('fd=%s' % self._fileno) + if self._pipe is not None: + polling = selector_events._test_selector_event( + self._loop._selector, + self._fileno, selectors.EVENT_READ) + if polling: + info.append('polling') + else: + info.append('idle') + else: + info.append('closed') + return '<%s>' % ' '.join(info) def _read_ready(self): try: @@ -203,11 +346,13 @@ def _read_ready(self): except (BlockingIOError, InterruptedError): pass except OSError as exc: - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal read error on pipe transport') else: if data: self._protocol.data_received(data) else: + if self._loop.get_debug(): + logger.info("%r was closed by peer", self) self._closing = True self._loop.remove_reader(self._fileno) self._loop.call_soon(self._protocol.eof_received) @@ -223,9 +368,27 @@ def close(self): if not self._closing: self._close(None) - def _fatal_error(self, exc): + # On Python 3.3 and older, objects with a destructor part of a reference + # cycle are never destroyed. It's not more the case on Python 3.4 thanks + # to the PEP 442. + if compat.PY34: + def __del__(self): + if self._pipe is not None: + warnings.warn("unclosed transport %r" % self, ResourceWarning) + self._pipe.close() + + def _fatal_error(self, exc, message='Fatal error on pipe transport'): # should be called by exception handler only - logger.exception('Fatal error for %s', self) + if (isinstance(exc, OSError) and exc.errno == errno.EIO): + if self._loop.get_debug(): + logger.debug("%r: %s", self, message, exc_info=True) + else: + self._loop.call_exception_handler({ + 'message': message, + 'exception': exc, + 'transport': self, + 'protocol': self._protocol, + }) self._close(exc) def _close(self, exc): @@ -243,41 +406,79 @@ def _call_connection_lost(self, exc): self._loop = None -class _UnixWritePipeTransport(transports.WriteTransport): +class _UnixWritePipeTransport(transports._FlowControlMixin, + transports.WriteTransport): def __init__(self, loop, pipe, protocol, waiter=None, extra=None): - super().__init__(extra) + super().__init__(extra, loop) self._extra['pipe'] = pipe - self._loop = loop self._pipe = pipe self._fileno = pipe.fileno() mode = os.fstat(self._fileno).st_mode is_socket = stat.S_ISSOCK(mode) - is_pipe = stat.S_ISFIFO(mode) - if not (is_socket or is_pipe): - raise ValueError("Pipe transport is for pipes/sockets only.") + if not (is_socket or + stat.S_ISFIFO(mode) or + stat.S_ISCHR(mode)): + raise ValueError("Pipe transport is only for " + "pipes, sockets and character devices") _set_nonblocking(self._fileno) self._protocol = protocol self._buffer = [] self._conn_lost = 0 self._closing = False # Set when close() or write_eof() called. - # On AIX, the reader trick only works for sockets. - # On other platforms it works for pipes and sockets. - # (Exception: OS X 10.4? Issue #19294.) + self._loop.call_soon(self._protocol.connection_made, self) + + # On AIX, the reader trick (to be notified when the read end of the + # socket is closed) only works for sockets. On other platforms it + # works for pipes and sockets. (Exception: OS X 10.4? Issue #19294.) if is_socket or not sys.platform.startswith("aix"): - self._loop.add_reader(self._fileno, self._read_ready) + # only start reading when connection_made() has been called + self._loop.call_soon(self._loop.add_reader, + self._fileno, self._read_ready) - self._loop.call_soon(self._protocol.connection_made, self) if waiter is not None: - self._loop.call_soon(waiter.set_result, None) + # only wake up the waiter when connection_made() has been called + self._loop.call_soon(waiter._set_result_unless_cancelled, None) + + def __repr__(self): + info = [self.__class__.__name__] + if self._pipe is None: + info.append('closed') + elif self._closing: + info.append('closing') + info.append('fd=%s' % self._fileno) + if self._pipe is not None: + polling = selector_events._test_selector_event( + self._loop._selector, + self._fileno, selectors.EVENT_WRITE) + if polling: + info.append('polling') + else: + info.append('idle') + + bufsize = self.get_write_buffer_size() + info.append('bufsize=%s' % bufsize) + else: + info.append('closed') + return '<%s>' % ' '.join(info) + + def get_write_buffer_size(self): + return sum(len(data) for data in self._buffer) def _read_ready(self): # Pipe was closed by peer. - self._close() + if self._loop.get_debug(): + logger.info("%r was closed by peer", self) + if self._buffer: + self._close(BrokenPipeError()) + else: + self._close() def write(self, data): - assert isinstance(data, bytes), repr(data) + assert isinstance(data, (bytes, bytearray, memoryview)), repr(data) + if isinstance(data, bytearray): + data = memoryview(data) if not data: return @@ -296,7 +497,7 @@ def write(self, data): n = 0 except Exception as exc: self._conn_lost += 1 - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal write error on pipe transport') return if n == len(data): return @@ -305,6 +506,7 @@ def write(self, data): self._loop.add_writer(self._fileno, self._write_ready) self._buffer.append(data) + self._maybe_pause_protocol() def _write_ready(self): data = b''.join(self._buffer) @@ -320,11 +522,12 @@ def _write_ready(self): # Remove writer here, _fatal_error() doesn't it # because _buffer is empty. self._loop.remove_writer(self._fileno) - self._fatal_error(exc) + self._fatal_error(exc, 'Fatal write error on pipe transport') else: if n == len(data): self._loop.remove_writer(self._fileno) - if self._closing: + self._maybe_resume_protocol() # May append to buffer. + if not self._buffer and self._closing: self._loop.remove_reader(self._fileno) self._call_connection_lost(None) return @@ -336,9 +539,6 @@ def _write_ready(self): def can_write_eof(self): return True - # TODO: Make the relationships between write_eof(), close(), - # abort(), _fatal_error() and _close() more straightforward. - def write_eof(self): if self._closing: return @@ -349,16 +549,34 @@ def write_eof(self): self._loop.call_soon(self._call_connection_lost, None) def close(self): - if not self._closing: + if self._pipe is not None and not self._closing: # write_eof is all what we needed to close the write pipe self.write_eof() + # On Python 3.3 and older, objects with a destructor part of a reference + # cycle are never destroyed. It's not more the case on Python 3.4 thanks + # to the PEP 442. + if compat.PY34: + def __del__(self): + if self._pipe is not None: + warnings.warn("unclosed transport %r" % self, ResourceWarning) + self._pipe.close() + def abort(self): self._close(None) - def _fatal_error(self, exc): + def _fatal_error(self, exc, message='Fatal error on pipe transport'): # should be called by exception handler only - logger.exception('Fatal error for %s', self) + if isinstance(exc, (BrokenPipeError, ConnectionResetError)): + if self._loop.get_debug(): + logger.debug("%r: %s", self, message, exc_info=True) + else: + self._loop.call_exception_handler({ + 'message': message, + 'exception': exc, + 'transport': self, + 'protocol': self._protocol, + }) self._close(exc) def _close(self, exc=None): @@ -379,6 +597,22 @@ def _call_connection_lost(self, exc): self._loop = None +if hasattr(os, 'set_inheritable'): + # Python 3.4 and newer + _set_inheritable = os.set_inheritable +else: + import fcntl + + def _set_inheritable(fd, inheritable): + cloexec_flag = getattr(fcntl, 'FD_CLOEXEC', 1) + + old = fcntl.fcntl(fd, fcntl.F_GETFD) + if not inheritable: + fcntl.fcntl(fd, fcntl.F_SETFD, old | cloexec_flag) + else: + fcntl.fcntl(fd, fcntl.F_SETFD, old & ~cloexec_flag) + + class _UnixSubprocessTransport(base_subprocess.BaseSubprocessTransport): def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs): @@ -390,12 +624,18 @@ def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs): # other end). Notably this is needed on AIX, and works # just fine on other platforms. stdin, stdin_w = self._loop._socketpair() + + # Mark the write end of the stdin pipe as non-inheritable, + # needed by close_fds=False on Python 3.3 and older + # (Python 3.4 implements the PEP 446, socketpair returns + # non-inheritable sockets) + _set_inheritable(stdin_w.fileno(), False) self._proc = subprocess.Popen( args, shell=shell, stdin=stdin, stdout=stdout, stderr=stderr, universal_newlines=False, bufsize=bufsize, **kwargs) if stdin_w is not None: stdin.close() - self._proc.stdin = open(stdin_w.detach(), 'rb', buffering=bufsize) + self._proc.stdin = open(stdin_w.detach(), 'wb', buffering=bufsize) class AbstractChildWatcher: @@ -428,7 +668,7 @@ def add_child_handler(self, pid, callback, *args): process 'pid' terminates. Specifying another callback for the same process replaces the previous handler. - Note: callback() must be thread-safe + Note: callback() must be thread-safe. """ raise NotImplementedError() @@ -499,8 +739,14 @@ def attach_loop(self, loop): def _sig_chld(self): try: self._do_waitpid_all() - except Exception: - logger.exception('Unknown exception in SIGCHLD handler') + except Exception as exc: + # self._loop should always be available here + # as '_sig_chld' is added as a signal handler + # in 'attach_loop' + self._loop.call_exception_handler({ + 'message': 'Unknown exception in SIGCHLD handler', + 'exception': exc, + }) def _compute_returncode(self, status): if os.WIFSIGNALED(status): @@ -542,7 +788,7 @@ def __exit__(self, a, b, c): pass def add_child_handler(self, pid, callback, *args): - self._callbacks[pid] = callback, args + self._callbacks[pid] = (callback, args) # Prevent a race condition in case the child is already terminated. self._do_waitpid(pid) @@ -578,13 +824,18 @@ def _do_waitpid(self, expected_pid): return returncode = self._compute_returncode(status) + if self._loop.get_debug(): + logger.debug('process %s exited with returncode %s', + expected_pid, returncode) try: callback, args = self._callbacks.pop(pid) except KeyError: # pragma: no cover # May happen if .remove_child_handler() is called # after os.waitpid() returns. - pass + if self._loop.get_debug(): + logger.warning("Child watcher got an unexpected pid: %r", + pid, exc_info=True) else: callback(pid, returncode, *args) @@ -633,22 +884,16 @@ def __exit__(self, a, b, c): def add_child_handler(self, pid, callback, *args): assert self._forks, "Must use the context manager" + with self._lock: + try: + returncode = self._zombies.pop(pid) + except KeyError: + # The child is running. + self._callbacks[pid] = callback, args + return - self._callbacks[pid] = callback, args - - try: - # Ensure that the child is not already terminated. - # (raise KeyError if still alive) - returncode = self._zombies.pop(pid) - - # Child is dead, therefore we can fire the callback immediately. - # First we remove it from the dict. - # (raise KeyError if .remove_child_handler() was called in-between) - del self._callbacks[pid] - except KeyError: - pass - else: - callback(pid, returncode, *args) + # The child is dead already. We can fire the callback. + callback(pid, returncode, *args) def remove_child_handler(self, pid): try: @@ -673,16 +918,26 @@ def _do_waitpid_all(self): returncode = self._compute_returncode(status) - try: - callback, args = self._callbacks.pop(pid) - except KeyError: - # unknown child - with self._lock: + with self._lock: + try: + callback, args = self._callbacks.pop(pid) + except KeyError: + # unknown child if self._forks: # It may not be registered yet. self._zombies[pid] = returncode + if self._loop.get_debug(): + logger.debug('unknown process %s exited ' + 'with returncode %s', + pid, returncode) continue + callback = None + else: + if self._loop.get_debug(): + logger.debug('process %s exited with returncode %s', + pid, returncode) + if callback is None: logger.warning( "Caught subprocess termination from unknown pid: " "%d -> %d", pid, returncode) @@ -691,7 +946,7 @@ def _do_waitpid_all(self): class _UnixDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy): - """XXX""" + """UNIX event loop policy with a watcher for child processes.""" _loop_factory = _UnixSelectorEventLoop def __init__(self): @@ -721,7 +976,7 @@ def set_event_loop(self, loop): self._watcher.attach_loop(loop) def get_child_watcher(self): - """Get the child watcher + """Get the watcher for child processes. If not yet set, a SafeChildWatcher object is automatically created. """ @@ -731,7 +986,7 @@ def get_child_watcher(self): return self._watcher def set_child_watcher(self, watcher): - """Set the child watcher""" + """Set the watcher for child processes.""" assert watcher is None or isinstance(watcher, AbstractChildWatcher) diff --git a/Lib/asyncio/windows_events.py b/Lib/asyncio/windows_events.py index b2ed2415e4ba..922594f17243 100644 --- a/Lib/asyncio/windows_events.py +++ b/Lib/asyncio/windows_events.py @@ -1,11 +1,11 @@ -"""Selector and proactor eventloops for Windows.""" +"""Selector and proactor event loops for Windows.""" +import _winapi import errno +import math import socket -import subprocess -import weakref import struct -import _winapi +import weakref from . import events from . import base_subprocess @@ -14,8 +14,9 @@ from . import selector_events from . import tasks from . import windows_utils -from .log import logger from . import _overlapped +from .coroutines import coroutine +from .log import logger __all__ = ['SelectorEventLoop', 'ProactorEventLoop', 'IocpProactor', @@ -28,6 +29,12 @@ ERROR_CONNECTION_REFUSED = 1225 ERROR_CONNECTION_ABORTED = 1236 +# Initial delay in seconds for connect_pipe() before retrying to connect +CONNECT_PIPE_INIT_DELAY = 0.001 + +# Maximum delay in seconds for connect_pipe() before retrying to connect +CONNECT_PIPE_MAX_DELAY = 0.100 + class _OverlappedFuture(futures.Future): """Subclass of Future which represents an overlapped operation. @@ -37,30 +44,189 @@ class _OverlappedFuture(futures.Future): def __init__(self, ov, *, loop=None): super().__init__(loop=loop) - self.ov = ov + if self._source_traceback: + del self._source_traceback[-1] + self._ov = ov + + def _repr_info(self): + info = super()._repr_info() + if self._ov is not None: + state = 'pending' if self._ov.pending else 'completed' + info.insert(1, 'overlapped=<%s, %#x>' % (state, self._ov.address)) + return info + + def _cancel_overlapped(self): + if self._ov is None: + return + try: + self._ov.cancel() + except OSError as exc: + context = { + 'message': 'Cancelling an overlapped future failed', + 'exception': exc, + 'future': self, + } + if self._source_traceback: + context['source_traceback'] = self._source_traceback + self._loop.call_exception_handler(context) + self._ov = None def cancel(self): - try: - self.ov.cancel() - except OSError: - pass + self._cancel_overlapped() return super().cancel() + def set_exception(self, exception): + super().set_exception(exception) + self._cancel_overlapped() -class _WaitHandleFuture(futures.Future): + def set_result(self, result): + super().set_result(result) + self._ov = None + + +class _BaseWaitHandleFuture(futures.Future): """Subclass of Future which represents a wait handle.""" - def __init__(self, wait_handle, *, loop=None): + def __init__(self, ov, handle, wait_handle, *, loop=None): super().__init__(loop=loop) + if self._source_traceback: + del self._source_traceback[-1] + # Keep a reference to the Overlapped object to keep it alive until the + # wait is unregistered + self._ov = ov + self._handle = handle self._wait_handle = wait_handle + # Should we call UnregisterWaitEx() if the wait completes + # or is cancelled? + self._registered = True + + def _poll(self): + # non-blocking wait: use a timeout of 0 millisecond + return (_winapi.WaitForSingleObject(self._handle, 0) == + _winapi.WAIT_OBJECT_0) + + def _repr_info(self): + info = super()._repr_info() + info.append('handle=%#x' % self._handle) + if self._handle is not None: + state = 'signaled' if self._poll() else 'waiting' + info.append(state) + if self._wait_handle is not None: + info.append('wait_handle=%#x' % self._wait_handle) + return info + + def _unregister_wait_cb(self, fut): + # The wait was unregistered: it's not safe to destroy the Overlapped + # object + self._ov = None + + def _unregister_wait(self): + if not self._registered: + return + self._registered = False + + wait_handle = self._wait_handle + self._wait_handle = None + try: + _overlapped.UnregisterWait(wait_handle) + except OSError as exc: + if exc.winerror != _overlapped.ERROR_IO_PENDING: + context = { + 'message': 'Failed to unregister the wait handle', + 'exception': exc, + 'future': self, + } + if self._source_traceback: + context['source_traceback'] = self._source_traceback + self._loop.call_exception_handler(context) + return + # ERROR_IO_PENDING means that the unregister is pending + + self._unregister_wait_cb(None) + def cancel(self): - super().cancel() + self._unregister_wait() + return super().cancel() + + def set_exception(self, exception): + self._unregister_wait() + super().set_exception(exception) + + def set_result(self, result): + self._unregister_wait() + super().set_result(result) + + +class _WaitCancelFuture(_BaseWaitHandleFuture): + """Subclass of Future which represents a wait for the cancellation of a + _WaitHandleFuture using an event. + """ + + def __init__(self, ov, event, wait_handle, *, loop=None): + super().__init__(ov, event, wait_handle, loop=loop) + + self._done_callback = None + + def cancel(self): + raise RuntimeError("_WaitCancelFuture must not be cancelled") + + def _schedule_callbacks(self): + super(_WaitCancelFuture, self)._schedule_callbacks() + if self._done_callback is not None: + self._done_callback(self) + + +class _WaitHandleFuture(_BaseWaitHandleFuture): + def __init__(self, ov, handle, wait_handle, proactor, *, loop=None): + super().__init__(ov, handle, wait_handle, loop=loop) + self._proactor = proactor + self._unregister_proactor = True + self._event = _overlapped.CreateEvent(None, True, False, None) + self._event_fut = None + + def _unregister_wait_cb(self, fut): + if self._event is not None: + _winapi.CloseHandle(self._event) + self._event = None + self._event_fut = None + + # If the wait was cancelled, the wait may never be signalled, so + # it's required to unregister it. Otherwise, IocpProactor.close() will + # wait forever for an event which will never come. + # + # If the IocpProactor already received the event, it's safe to call + # _unregister() because we kept a reference to the Overlapped object + # which is used as an unique key. + self._proactor._unregister(self._ov) + self._proactor = None + + super()._unregister_wait_cb(fut) + + def _unregister_wait(self): + if not self._registered: + return + self._registered = False + + wait_handle = self._wait_handle + self._wait_handle = None try: - _overlapped.UnregisterWait(self._wait_handle) - except OSError as e: - if e.winerror != _overlapped.ERROR_IO_PENDING: - raise + _overlapped.UnregisterWaitEx(wait_handle, self._event) + except OSError as exc: + if exc.winerror != _overlapped.ERROR_IO_PENDING: + context = { + 'message': 'Failed to unregister the wait handle', + 'exception': exc, + 'future': self, + } + if self._source_traceback: + context['source_traceback'] = self._source_traceback + self._loop.call_exception_handler(context) + return + # ERROR_IO_PENDING is not an error, the wait was unregistered + + self._event_fut = self._proactor._wait_cancel(self._event, + self._unregister_wait_cb) class PipeServer(object): @@ -71,6 +237,11 @@ class PipeServer(object): def __init__(self, address): self._address = address self._free_instances = weakref.WeakSet() + # initialize the pipe attribute before calling _server_pipe_handle() + # because this function can raise an exception and the destructor calls + # the close() method + self._pipe = None + self._accept_pipe_future = None self._pipe = self._server_pipe_handle(True) def _get_unconnected_pipe(self): @@ -83,7 +254,7 @@ def _get_unconnected_pipe(self): def _server_pipe_handle(self, first): # Return a wrapper for a new pipe handle. - if self._address is None: + if self.closed(): return None flags = _winapi.PIPE_ACCESS_DUPLEX | _winapi.FILE_FLAG_OVERLAPPED if first: @@ -99,7 +270,13 @@ def _server_pipe_handle(self, first): self._free_instances.add(pipe) return pipe + def closed(self): + return (self._address is None) + def close(self): + if self._accept_pipe_future is not None: + self._accept_pipe_future.cancel() + self._accept_pipe_future = None # Close all instances which have not been connected to by a client. if self._address is not None: for pipe in self._free_instances: @@ -129,7 +306,7 @@ def __init__(self, proactor=None): def _socketpair(self): return windows_utils.socketpair() - @tasks.coroutine + @coroutine def create_pipe_connection(self, protocol_factory, address): f = self._proactor.connect_pipe(address) pipe = yield from f @@ -138,51 +315,77 @@ def create_pipe_connection(self, protocol_factory, address): extra={'addr': address}) return trans, protocol - @tasks.coroutine + @coroutine def start_serving_pipe(self, protocol_factory, address): server = PipeServer(address) - def loop(f=None): + def loop_accept_pipe(f=None): pipe = None try: if f: pipe = f.result() server._free_instances.discard(pipe) + + if server.closed(): + # A client connected before the server was closed: + # drop the client (close the pipe) and exit + pipe.close() + return + protocol = protocol_factory() self._make_duplex_pipe_transport( pipe, protocol, extra={'addr': address}) + pipe = server._get_unconnected_pipe() if pipe is None: return + f = self._proactor.accept_pipe(pipe) - except OSError: + except OSError as exc: if pipe and pipe.fileno() != -1: - logger.exception('Pipe accept failed') + self.call_exception_handler({ + 'message': 'Pipe accept failed', + 'exception': exc, + 'pipe': pipe, + }) pipe.close() + elif self._debug: + logger.warning("Accept pipe failed on pipe %r", + pipe, exc_info=True) except futures.CancelledError: if pipe: pipe.close() else: - f.add_done_callback(loop) + server._accept_pipe_future = f + f.add_done_callback(loop_accept_pipe) - self.call_soon(loop) + self.call_soon(loop_accept_pipe) return [server] - def _stop_serving(self, server): - server.close() - - @tasks.coroutine + @coroutine def _make_subprocess_transport(self, protocol, args, shell, stdin, stdout, stderr, bufsize, extra=None, **kwargs): + waiter = futures.Future(loop=self) transp = _WindowsSubprocessTransport(self, protocol, args, shell, stdin, stdout, stderr, bufsize, - extra=None, **kwargs) - yield from transp._post_init() - return transp + waiter=waiter, extra=extra, + **kwargs) + try: + yield from waiter + except Exception as exc: + # Workaround CPython bug #23353: using yield/yield-from in an + # except block of a generator doesn't clear properly sys.exc_info() + err = exc + else: + err = None + + if err is not None: + transp.close() + yield from transp._wait() + raise err - def _subprocess_closed(self, transport): - pass + return transp class IocpProactor: @@ -195,8 +398,14 @@ def __init__(self, concurrency=0xffffffff): _overlapped.INVALID_HANDLE_VALUE, NULL, 0, concurrency) self._cache = {} self._registered = weakref.WeakSet() + self._unregistered = [] self._stopped_serving = weakref.WeakSet() + def __repr__(self): + return ('<%s overlapped#=%s result#=%s>' + % (self.__class__.__name__, len(self._cache), + len(self._results))) + def set_loop(self, loop): self._loop = loop @@ -207,15 +416,23 @@ def select(self, timeout=None): self._results = [] return tmp + def _result(self, value): + fut = futures.Future(loop=self._loop) + fut.set_result(value) + return fut + def recv(self, conn, nbytes, flags=0): self._register_with_iocp(conn) ov = _overlapped.Overlapped(NULL) - if isinstance(conn, socket.socket): - ov.WSARecv(conn.fileno(), nbytes, flags) - else: - ov.ReadFile(conn.fileno(), nbytes) + try: + if isinstance(conn, socket.socket): + ov.WSARecv(conn.fileno(), nbytes, flags) + else: + ov.ReadFile(conn.fileno(), nbytes) + except BrokenPipeError: + return self._result(b'') - def finish(trans, key, ov): + def finish_recv(trans, key, ov): try: return ov.getresult() except OSError as exc: @@ -224,7 +441,7 @@ def finish(trans, key, ov): else: raise - return self._register(ov, conn, finish) + return self._register(ov, conn, finish_recv) def send(self, conn, buf, flags=0): self._register_with_iocp(conn) @@ -234,7 +451,7 @@ def send(self, conn, buf, flags=0): else: ov.WriteFile(conn.fileno(), buf) - def finish(trans, key, ov): + def finish_send(trans, key, ov): try: return ov.getresult() except OSError as exc: @@ -243,7 +460,7 @@ def finish(trans, key, ov): else: raise - return self._register(ov, conn, finish) + return self._register(ov, conn, finish_send) def accept(self, listener): self._register_with_iocp(listener) @@ -260,7 +477,19 @@ def finish_accept(trans, key, ov): conn.settimeout(listener.gettimeout()) return conn, conn.getpeername() - return self._register(ov, listener, finish_accept) + @coroutine + def accept_coro(future, conn): + # Coroutine closing the accept socket if the future is cancelled + try: + yield from future + except futures.CancelledError: + conn.close() + raise + + future = self._register(ov, listener, finish_accept) + coro = accept_coro(future, conn) + tasks.ensure_future(coro, loop=self._loop) + return future def connect(self, conn, address): self._register_with_iocp(conn) @@ -288,62 +517,85 @@ def finish_connect(trans, key, ov): def accept_pipe(self, pipe): self._register_with_iocp(pipe) ov = _overlapped.Overlapped(NULL) - ov.ConnectNamedPipe(pipe.fileno()) + connected = ov.ConnectNamedPipe(pipe.fileno()) - def finish(trans, key, ov): + if connected: + # ConnectNamePipe() failed with ERROR_PIPE_CONNECTED which means + # that the pipe is connected. There is no need to wait for the + # completion of the connection. + return self._result(pipe) + + def finish_accept_pipe(trans, key, ov): ov.getresult() return pipe - return self._register(ov, pipe, finish) + return self._register(ov, pipe, finish_accept_pipe) + @coroutine def connect_pipe(self, address): - ov = _overlapped.Overlapped(NULL) - ov.WaitNamedPipeAndConnect(address, self._iocp, ov.address) - - def finish(err, handle, ov): - # err, handle were arguments passed to PostQueuedCompletionStatus() - # in a function run in a thread pool. - if err == _overlapped.ERROR_SEM_TIMEOUT: - # Connection did not succeed within time limit. - msg = _overlapped.FormatMessage(err) - raise ConnectionRefusedError(0, msg, None, err) - elif err != 0: - msg = _overlapped.FormatMessage(err) - raise OSError(0, msg, None, err) - else: - return windows_utils.PipeHandle(handle) + delay = CONNECT_PIPE_INIT_DELAY + while True: + # Unfortunately there is no way to do an overlapped connect to a pipe. + # Call CreateFile() in a loop until it doesn't fail with + # ERROR_PIPE_BUSY + try: + handle = _overlapped.ConnectPipe(address) + break + except OSError as exc: + if exc.winerror != _overlapped.ERROR_PIPE_BUSY: + raise - return self._register(ov, None, finish, wait_for_post=True) + # ConnectPipe() failed with ERROR_PIPE_BUSY: retry later + delay = min(delay * 2, CONNECT_PIPE_MAX_DELAY) + yield from tasks.sleep(delay, loop=self._loop) + + return windows_utils.PipeHandle(handle) def wait_for_handle(self, handle, timeout=None): + """Wait for a handle. + + Return a Future object. The result of the future is True if the wait + completed, or False if the wait did not complete (on timeout). + """ + return self._wait_for_handle(handle, timeout, False) + + def _wait_cancel(self, event, done_callback): + fut = self._wait_for_handle(event, None, True) + # add_done_callback() cannot be used because the wait may only complete + # in IocpProactor.close(), while the event loop is not running. + fut._done_callback = done_callback + return fut + + def _wait_for_handle(self, handle, timeout, _is_cancel): if timeout is None: ms = _winapi.INFINITE else: - ms = int(timeout * 1000 + 0.5) + # RegisterWaitForSingleObject() has a resolution of 1 millisecond, + # round away from zero to wait *at least* timeout seconds. + ms = math.ceil(timeout * 1e3) # We only create ov so we can use ov.address as a key for the cache. ov = _overlapped.Overlapped(NULL) - wh = _overlapped.RegisterWaitWithQueue( + wait_handle = _overlapped.RegisterWaitWithQueue( handle, self._iocp, ov.address, ms) - f = _WaitHandleFuture(wh, loop=self._loop) + if _is_cancel: + f = _WaitCancelFuture(ov, handle, wait_handle, loop=self._loop) + else: + f = _WaitHandleFuture(ov, handle, wait_handle, self, + loop=self._loop) + if f._source_traceback: + del f._source_traceback[-1] - def finish(trans, key, ov): - if not f.cancelled(): - try: - _overlapped.UnregisterWait(wh) - except OSError as e: - if e.winerror != _overlapped.ERROR_IO_PENDING: - raise + def finish_wait_for_handle(trans, key, ov): # Note that this second wait means that we should only use # this with handles types where a successful wait has no # effect. So events or processes are all right, but locks # or semaphores are not. Also note if the handle is # signalled and then quickly reset, then we may return # False even though we have not timed out. - return (_winapi.WaitForSingleObject(handle, 0) == - _winapi.WAIT_OBJECT_0) + return f._poll() - self._cache[ov.address] = (f, ov, None, finish) + self._cache[ov.address] = (f, ov, 0, finish_wait_for_handle) return f def _register_with_iocp(self, obj): @@ -356,17 +608,14 @@ def _register_with_iocp(self, obj): # to avoid sending notifications to completion port of ops # that succeed immediately. - def _register(self, ov, obj, callback, wait_for_post=False): + def _register(self, ov, obj, callback): # Return a future which will be set with the result of the # operation when it completes. The future's value is actually # the value returned by callback(). f = _OverlappedFuture(ov, loop=self._loop) - if ov.pending or wait_for_post: - # Register the overlapped operation for later. Note that - # we only store obj to prevent it from being garbage - # collected too early. - self._cache[ov.address] = (f, ov, obj, callback) - else: + if f._source_traceback: + del f._source_traceback[-1] + if not ov.pending: # The operation has completed, so no need to postpone the # work. We cannot take this short cut if we need the # NumberOfBytes, CompletionKey values returned by @@ -377,8 +626,27 @@ def _register(self, ov, obj, callback, wait_for_post=False): f.set_exception(e) else: f.set_result(value) + # Even if GetOverlappedResult() was called, we have to wait for the + # notification of the completion in GetQueuedCompletionStatus(). + # Register the overlapped operation to keep a reference to the + # OVERLAPPED object, otherwise the memory is freed and Windows may + # read uninitialized memory. + + # Register the overlapped operation for later. Note that + # we only store obj to prevent it from being garbage + # collected too early. + self._cache[ov.address] = (f, ov, obj, callback) return f + def _unregister(self, ov): + """Unregister an overlapped object. + + Call this method when its future has been cancelled. The event can + already be signalled (pending in the proactor event queue). It is also + safe if the event is never signalled (because it was cancelled). + """ + self._unregistered.append(ov) + def _get_accept_socket(self, family): s = socket.socket(family) s.settimeout(0) @@ -390,26 +658,41 @@ def _poll(self, timeout=None): elif timeout < 0: raise ValueError("negative timeout") else: - ms = int(timeout * 1000 + 0.5) + # GetQueuedCompletionStatus() has a resolution of 1 millisecond, + # round away from zero to wait *at least* timeout seconds. + ms = math.ceil(timeout * 1e3) if ms >= INFINITE: raise ValueError("timeout too big") + while True: status = _overlapped.GetQueuedCompletionStatus(self._iocp, ms) if status is None: - return + break + ms = 0 + err, transferred, key, address = status try: f, ov, obj, callback = self._cache.pop(address) except KeyError: + if self._loop.get_debug(): + self._loop.call_exception_handler({ + 'message': ('GetQueuedCompletionStatus() returned an ' + 'unexpected event'), + 'status': ('err=%s transferred=%s key=%#x address=%#x' + % (err, transferred, key, address)), + }) + # key is either zero, or it is used to return a pipe # handle which should be closed to avoid a leak. if key not in (0, _overlapped.INVALID_HANDLE_VALUE): _winapi.CloseHandle(key) - ms = 0 continue + if obj in self._stopped_serving: f.cancel() - elif not f.cancelled(): + # Don't call the callback if _register() already read the result or + # if the overlapped has been cancelled + elif not f.done(): try: value = callback(transferred, key, ov) except OSError as e: @@ -418,7 +701,11 @@ def _poll(self, timeout=None): else: f.set_result(value) self._results.append(f) - ms = 0 + + # Remove unregisted futures + for ov in self._unregistered: + self._cache.pop(ov.address, None) + self._unregistered.clear() def _stop_serving(self, obj): # obj is a socket or pipe handle. It will be closed in @@ -428,17 +715,26 @@ def _stop_serving(self, obj): def close(self): # Cancel remaining registered operations. - for address, (f, ov, obj, callback) in list(self._cache.items()): - if obj is None: - # The operation was started with connect_pipe() which - # queues a task to Windows' thread pool. This cannot - # be cancelled, so just forget it. - del self._cache[address] + for address, (fut, ov, obj, callback) in list(self._cache.items()): + if fut.cancelled(): + # Nothing to do with cancelled futures + pass + elif isinstance(fut, _WaitCancelFuture): + # _WaitCancelFuture must not be cancelled + pass else: try: - ov.cancel() - except OSError: - pass + fut.cancel() + except OSError as exc: + if self._loop is not None: + context = { + 'message': 'Cancelling a future failed', + 'exception': exc, + 'future': fut, + } + if fut._source_traceback: + context['source_traceback'] = fut._source_traceback + self._loop.call_exception_handler(context) while self._cache: if not self._poll(1): @@ -449,6 +745,9 @@ def close(self): _winapi.CloseHandle(self._iocp) self._iocp = None + def __del__(self): + self.close() + class _WindowsSubprocessTransport(base_subprocess.BaseSubprocessTransport): diff --git a/Lib/asyncio/windows_utils.py b/Lib/asyncio/windows_utils.py index aa1c06480673..870cd13abe6c 100644 --- a/Lib/asyncio/windows_utils.py +++ b/Lib/asyncio/windows_utils.py @@ -7,13 +7,14 @@ if sys.platform != 'win32': # pragma: no cover raise ImportError('win32 only') -import socket +import _winapi import itertools import msvcrt import os +import socket import subprocess import tempfile -import _winapi +import warnings __all__ = ['socketpair', 'pipe', 'Popen', 'PIPE', 'PipeHandle'] @@ -28,34 +29,52 @@ _mmap_counter = itertools.count() -# Replacement for socket.socketpair() - - -def socketpair(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0): - """A socket pair usable as a self-pipe, for Windows. - - Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain. - """ - # We create a connected TCP socket. Note the trick with setblocking(0) - # that prevents us from having to create a thread. - lsock = socket.socket(family, type, proto) - lsock.bind(('localhost', 0)) - lsock.listen(1) - addr, port = lsock.getsockname() - csock = socket.socket(family, type, proto) - csock.setblocking(False) - try: - csock.connect((addr, port)) - except (BlockingIOError, InterruptedError): - pass - except Exception: - lsock.close() - csock.close() - raise - ssock, _ = lsock.accept() - csock.setblocking(True) - lsock.close() - return (ssock, csock) +if hasattr(socket, 'socketpair'): + # Since Python 3.5, socket.socketpair() is now also available on Windows + socketpair = socket.socketpair +else: + # Replacement for socket.socketpair() + def socketpair(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0): + """A socket pair usable as a self-pipe, for Windows. + + Origin: https://gist.github.com/4325783, by Geert Jansen. + Public domain. + """ + if family == socket.AF_INET: + host = '127.0.0.1' + elif family == socket.AF_INET6: + host = '::1' + else: + raise ValueError("Only AF_INET and AF_INET6 socket address " + "families are supported") + if type != socket.SOCK_STREAM: + raise ValueError("Only SOCK_STREAM socket type is supported") + if proto != 0: + raise ValueError("Only protocol zero is supported") + + # We create a connected TCP socket. Note the trick with setblocking(0) + # that prevents us from having to create a thread. + lsock = socket.socket(family, type, proto) + try: + lsock.bind((host, 0)) + lsock.listen(1) + # On IPv6, ignore flow_info and scope_id + addr, port = lsock.getsockname()[:2] + csock = socket.socket(family, type, proto) + try: + csock.setblocking(False) + try: + csock.connect((addr, port)) + except (BlockingIOError, InterruptedError): + pass + csock.setblocking(True) + ssock, _ = lsock.accept() + except: + csock.close() + raise + finally: + lsock.close() + return (ssock, csock) # Replacement for os.pipe() using handles instead of fds @@ -117,19 +136,31 @@ class PipeHandle: def __init__(self, handle): self._handle = handle + def __repr__(self): + if self._handle is not None: + handle = 'handle=%r' % self._handle + else: + handle = 'closed' + return '<%s %s>' % (self.__class__.__name__, handle) + @property def handle(self): return self._handle def fileno(self): + if self._handle is None: + raise ValueError("I/O operatioon on closed pipe") return self._handle def close(self, *, CloseHandle=_winapi.CloseHandle): - if self._handle != -1: + if self._handle is not None: CloseHandle(self._handle) - self._handle = -1 + self._handle = None - __del__ = close + def __del__(self): + if self._handle is not None: + warnings.warn("unclosed %r" % self, ResourceWarning) + self.close() def __enter__(self): return self diff --git a/Lib/asyncore.py b/Lib/asyncore.py index 75481ddde059..3b51f0f337fe 100644 --- a/Lib/asyncore.py +++ b/Lib/asyncore.py @@ -57,8 +57,8 @@ ENOTCONN, ESHUTDOWN, EISCONN, EBADF, ECONNABORTED, EPIPE, EAGAIN, \ errorcode -_DISCONNECTED = frozenset((ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED, EPIPE, - EBADF)) +_DISCONNECTED = frozenset({ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED, EPIPE, + EBADF}) try: socket_map @@ -141,10 +141,7 @@ def poll(timeout=0.0, map=None): time.sleep(timeout) return - try: - r, w, e = select.select(r, w, e, timeout) - except InterruptedError: - return + r, w, e = select.select(r, w, e, timeout) for fd in r: obj = map.get(fd) @@ -182,10 +179,8 @@ def poll2(timeout=0.0, map=None): flags |= select.POLLOUT if flags: pollster.register(fd, flags) - try: - r = pollster.poll(timeout) - except InterruptedError: - r = [] + + r = pollster.poll(timeout) for fd, flags in r: obj = map.get(fd) if obj is None: @@ -220,7 +215,7 @@ class dispatcher: connecting = False closing = False addr = None - ignore_log_types = frozenset(['warning']) + ignore_log_types = frozenset({'warning'}) def __init__(self, sock=None, map=None): if map is None: @@ -255,7 +250,7 @@ def __init__(self, sock=None, map=None): self.socket = None def __repr__(self): - status = [self.__class__.__module__+"."+self.__class__.__name__] + status = [self.__class__.__module__+"."+self.__class__.__qualname__] if self.accepting and self.addr: status.append('listening') elif self.connected: @@ -404,20 +399,6 @@ def close(self): if why.args[0] not in (ENOTCONN, EBADF): raise - # cheap inheritance, used to pass all other attribute - # references to the underlying socket object. - def __getattr__(self, attr): - try: - retattr = getattr(self.socket, attr) - except AttributeError: - raise AttributeError("%s instance has no attribute '%s'" - %(self.__class__.__name__, attr)) - else: - msg = "%(me)s.%(attr)s is deprecated; use %(me)s.socket.%(attr)s " \ - "instead" % {'me' : self.__class__.__name__, 'attr' : attr} - warnings.warn(msg, DeprecationWarning, stacklevel=2) - return retattr - # log and log_info may be overridden to provide more sophisticated # logging and warning methods. In general, log is for 'hit' logging # and 'log_info' is for informational, warning and error logging. @@ -604,8 +585,6 @@ def close_all(map=None, ignore_all=False): # Regardless, this is useful for pipes, and stdin/stdout... if os.name == 'posix': - import fcntl - class file_wrapper: # Here we override just enough to make a file # look like a socket for the purposes of asyncore. @@ -614,6 +593,11 @@ class file_wrapper: def __init__(self, fd): self.fd = os.dup(fd) + def __del__(self): + if self.fd >= 0: + warnings.warn("unclosed file %r" % self, ResourceWarning) + self.close() + def recv(self, *args): return os.read(self.fd, *args) @@ -632,7 +616,10 @@ def getsockopt(self, level, optname, buflen=None): write = send def close(self): + if self.fd < 0: + return os.close(self.fd) + self.fd = -1 def fileno(self): return self.fd @@ -648,9 +635,7 @@ def __init__(self, fd, map=None): pass self.set_file(fd) # set it to non-blocking mode - flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0) - flags = flags | os.O_NONBLOCK - fcntl.fcntl(fd, fcntl.F_SETFL, flags) + os.set_blocking(fd, False) def set_file(self, fd): self.socket = file_wrapper(fd) diff --git a/Lib/base64.py b/Lib/base64.py index 84818cf078bc..eb925cd4c55b 100755 --- a/Lib/base64.py +++ b/Lib/base64.py @@ -9,7 +9,6 @@ import re import struct import binascii -import itertools __all__ = [ @@ -59,8 +58,7 @@ def b64encode(s, altchars=None): The encoded byte string is returned. """ - # Strip off the trailing newline - encoded = binascii.b2a_base64(s)[:-1] + encoded = binascii.b2a_base64(s, newline=False) if altchars is not None: assert len(altchars) == 2, repr(altchars) return encoded.translate(bytes.maketrans(b'+/', altchars)) @@ -139,15 +137,22 @@ def urlsafe_b64decode(s): # Base32 encoding/decoding must be done in Python _b32alphabet = b'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567' -_b32tab = [bytes([i]) for i in _b32alphabet] -_b32tab2 = [a + b for a in _b32tab for b in _b32tab] -_b32rev = {v: k for k, v in enumerate(_b32alphabet)} +_b32tab2 = None +_b32rev = None def b32encode(s): """Encode a byte string using Base32. s is the byte string to encode. The encoded byte string is returned. """ + global _b32tab2 + # Delay the initialization of the table to not waste memory + # if the function is never called + if _b32tab2 is None: + b32tab = [bytes((i,)) for i in _b32alphabet] + _b32tab2 = [a + b for a in b32tab for b in b32tab] + b32tab = None + if not isinstance(s, bytes_types): s = memoryview(s).tobytes() leftover = len(s) % 5 @@ -194,6 +199,11 @@ def b32decode(s, casefold=False, map01=None): the input is incorrectly padded or if there are non-alphabet characters present in the input. """ + global _b32rev + # Delay the initialization of the table to not waste memory + # if the function is never called + if _b32rev is None: + _b32rev = {v: k for k, v in enumerate(_b32alphabet)} s = _bytes_from_decode_data(s) if len(s) % 8: raise binascii.Error('Incorrect padding') @@ -275,6 +285,11 @@ def b16decode(s, casefold=False): # Ascii85 encoding/decoding # +_a85chars = None +_a85chars2 = None +_A85START = b"<~" +_A85END = b"~>" + def _85encode(b, chars, chars2, pad=False, foldnuls=False, foldspaces=False): # Helper function for a85encode and b85encode if not isinstance(b, bytes_types): @@ -285,8 +300,6 @@ def _85encode(b, chars, chars2, pad=False, foldnuls=False, foldspaces=False): b = b + b'\0' * padding words = struct.Struct('!%dI' % (len(b) // 4)).unpack(b) - a85chars2 = _a85chars2 - a85chars = _a85chars chunks = [b'z' if foldnuls and not word else b'y' if foldspaces and word == 0x20202020 else (chars2[word // 614125] + @@ -301,11 +314,6 @@ def _85encode(b, chars, chars2, pad=False, foldnuls=False, foldspaces=False): return b''.join(chunks) -_A85START = b"<~" -_A85END = b"~>" -_a85chars = [bytes([i]) for i in range(33, 118)] -_a85chars2 = [(a + b) for a in _a85chars for b in _a85chars] - def a85encode(b, *, foldspaces=False, wrapcol=0, pad=False, adobe=False): """Encode a byte string using Ascii85. @@ -315,7 +323,7 @@ def a85encode(b, *, foldspaces=False, wrapcol=0, pad=False, adobe=False): instead of 4 consecutive spaces (ASCII 0x20) as supported by 'btoa'. This feature is not supported by the "standard" Adobe encoding. - wrapcol controls whether the output should have newline ('\n') characters + wrapcol controls whether the output should have newline ('\\n') characters added to it. If this is non-zero, each output line will be at most this many characters long. @@ -325,6 +333,13 @@ def a85encode(b, *, foldspaces=False, wrapcol=0, pad=False, adobe=False): adobe controls whether the encoded byte sequence is framed with <~ and ~>, which is used by the Adobe implementation. """ + global _a85chars, _a85chars2 + # Delay the initialization of tables to not waste memory + # if the function is never called + if _a85chars is None: + _a85chars = [bytes((i,)) for i in range(33, 118)] + _a85chars2 = [(a + b) for a in _a85chars for b in _a85chars] + result = _85encode(b, _a85chars, _a85chars2, pad, True, foldspaces) if adobe: @@ -362,7 +377,7 @@ def a85decode(b, *, foldspaces=False, adobe=False, ignorechars=b' \t\n\r\v'): if adobe: if not (b.startswith(_A85START) and b.endswith(_A85END)): raise ValueError("Ascii85 encoded byte sequences must be bracketed " - "by {} and {}".format(_A85START, _A85END)) + "by {!r} and {!r}".format(_A85START, _A85END)) b = b[2:-2] # Strip off start/end markers # # We have to go through this stepwise, so as to ignore spaces and handle @@ -409,29 +424,37 @@ def a85decode(b, *, foldspaces=False, adobe=False, ignorechars=b' \t\n\r\v'): # The following code is originally taken (with permission) from Mercurial -_b85chars = b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ - b"abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~" -_b85chars = [bytes([i]) for i in _b85chars] -_b85chars2 = [(a + b) for a in _b85chars for b in _b85chars] +_b85alphabet = (b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + b"abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~") +_b85chars = None +_b85chars2 = None _b85dec = None def b85encode(b, pad=False): """Encode an ASCII-encoded byte array in base85 format. - If pad is true, the input is padded with "\0" so its length is a multiple of + If pad is true, the input is padded with "\\0" so its length is a multiple of 4 characters before encoding. """ + global _b85chars, _b85chars2 + # Delay the initialization of tables to not waste memory + # if the function is never called + if _b85chars is None: + _b85chars = [bytes((i,)) for i in _b85alphabet] + _b85chars2 = [(a + b) for a in _b85chars for b in _b85chars] return _85encode(b, _b85chars, _b85chars2, pad) def b85decode(b): """Decode base85-encoded byte array""" - b = _bytes_from_decode_data(b) global _b85dec + # Delay the initialization of tables to not waste memory + # if the function is never called if _b85dec is None: _b85dec = [None] * 256 - for i, c in enumerate(_b85chars): - _b85dec[c[0]] = i + for i, c in enumerate(_b85alphabet): + _b85dec[c] = i + b = _bytes_from_decode_data(b) padding = (-len(b)) % 5 b = b + b'~' * padding out = [] diff --git a/Lib/binhex.py b/Lib/binhex.py index 7bf9278430fb..56b5f852c003 100644 --- a/Lib/binhex.py +++ b/Lib/binhex.py @@ -32,7 +32,8 @@ class Error(Exception): pass # States (what have we written) -[_DID_HEADER, _DID_DATA, _DID_RSRC] = range(3) +_DID_HEADER = 0 +_DID_DATA = 1 # Various constants REASONABLY_LARGE = 32768 # Minimal amount we pass the rle-coder @@ -213,30 +214,34 @@ def write_rsrc(self, data): self._write(data) def close(self): - if self.state < _DID_DATA: - self.close_data() - if self.state != _DID_DATA: - raise Error('Close at the wrong time') - if self.rlen != 0: - raise Error("Incorrect resource-datasize, diff=%r" % (self.rlen,)) - self._writecrc() - self.ofp.close() - self.state = None - del self.ofp + if self.state is None: + return + try: + if self.state < _DID_DATA: + self.close_data() + if self.state != _DID_DATA: + raise Error('Close at the wrong time') + if self.rlen != 0: + raise Error("Incorrect resource-datasize, diff=%r" % (self.rlen,)) + self._writecrc() + finally: + self.state = None + ofp = self.ofp + del self.ofp + ofp.close() def binhex(inp, out): """binhex(infilename, outfilename): create binhex-encoded copy of a file""" finfo = getfileinfo(inp) ofp = BinHex(finfo, out) - ifp = io.open(inp, 'rb') - # XXXX Do textfile translation on non-mac systems - while True: - d = ifp.read(128000) - if not d: break - ofp.write(d) - ofp.close_data() - ifp.close() + with io.open(inp, 'rb') as ifp: + # XXXX Do textfile translation on non-mac systems + while True: + d = ifp.read(128000) + if not d: break + ofp.write(d) + ofp.close_data() ifp = openrsrc(inp, 'rb') while True: @@ -436,11 +441,15 @@ def read_rsrc(self, *n): return self._read(n) def close(self): - if self.rlen: - dummy = self.read_rsrc(self.rlen) - self._checkcrc() - self.state = _DID_RSRC - self.ifp.close() + if self.state is None: + return + try: + if self.rlen: + dummy = self.read_rsrc(self.rlen) + self._checkcrc() + finally: + self.state = None + self.ifp.close() def hexbin(inp, out): """hexbin(infilename, outfilename) - Decode binhexed file""" @@ -449,13 +458,12 @@ def hexbin(inp, out): if not out: out = ifp.FName - ofp = io.open(out, 'wb') - # XXXX Do translation on non-mac systems - while True: - d = ifp.read(128000) - if not d: break - ofp.write(d) - ofp.close() + with io.open(out, 'wb') as ofp: + # XXXX Do translation on non-mac systems + while True: + d = ifp.read(128000) + if not d: break + ofp.write(d) ifp.close_data() d = ifp.read_rsrc(128000) diff --git a/Lib/bz2.py b/Lib/bz2.py index 6bc611e71fc7..bc78c5448512 100644 --- a/Lib/bz2.py +++ b/Lib/bz2.py @@ -9,8 +9,10 @@ __author__ = "Nadeem Vawda <nadeem.vawda@gmail.com>" +from builtins import open as _builtin_open import io import warnings +import _compression try: from threading import RLock @@ -22,15 +24,11 @@ _MODE_CLOSED = 0 _MODE_READ = 1 -_MODE_READ_EOF = 2 +# Value 2 no longer used _MODE_WRITE = 3 -_BUFFER_SIZE = 8192 -_builtin_open = open - - -class BZ2File(io.BufferedIOBase): +class BZ2File(_compression.BaseStream): """A file object providing transparent bzip2 (de)compression. @@ -62,13 +60,11 @@ def __init__(self, filename, mode="r", buffering=None, compresslevel=9): multiple compressed streams. """ # This lock must be recursive, so that BufferedIOBase's - # readline(), readlines() and writelines() don't deadlock. + # writelines() does not deadlock. self._lock = RLock() self._fp = None self._closefp = False self._mode = _MODE_CLOSED - self._pos = 0 - self._size = -1 if buffering is not None: warnings.warn("Use of 'buffering' argument is deprecated", @@ -80,9 +76,6 @@ def __init__(self, filename, mode="r", buffering=None, compresslevel=9): if mode in ("", "r", "rb"): mode = "rb" mode_code = _MODE_READ - self._decompressor = BZ2Decompressor() - self._buffer = b"" - self._buffer_offset = 0 elif mode in ("w", "wb"): mode = "wb" mode_code = _MODE_WRITE @@ -108,6 +101,13 @@ def __init__(self, filename, mode="r", buffering=None, compresslevel=9): else: raise TypeError("filename must be a str or bytes object, or a file") + if self._mode == _MODE_READ: + raw = _compression.DecompressReader(self._fp, + BZ2Decompressor, trailing_error=OSError) + self._buffer = io.BufferedReader(raw) + else: + self._pos = 0 + def close(self): """Flush and close the file. @@ -118,8 +118,8 @@ def close(self): if self._mode == _MODE_CLOSED: return try: - if self._mode in (_MODE_READ, _MODE_READ_EOF): - self._decompressor = None + if self._mode == _MODE_READ: + self._buffer.close() elif self._mode == _MODE_WRITE: self._fp.write(self._compressor.flush()) self._compressor = None @@ -131,8 +131,7 @@ def close(self): self._fp = None self._closefp = False self._mode = _MODE_CLOSED - self._buffer = b"" - self._buffer_offset = 0 + self._buffer = None @property def closed(self): @@ -146,118 +145,18 @@ def fileno(self): def seekable(self): """Return whether the file supports seeking.""" - return self.readable() and self._fp.seekable() + return self.readable() and self._buffer.seekable() def readable(self): """Return whether the file was opened for reading.""" self._check_not_closed() - return self._mode in (_MODE_READ, _MODE_READ_EOF) + return self._mode == _MODE_READ def writable(self): """Return whether the file was opened for writing.""" self._check_not_closed() return self._mode == _MODE_WRITE - # Mode-checking helper functions. - - def _check_not_closed(self): - if self.closed: - raise ValueError("I/O operation on closed file") - - def _check_can_read(self): - if self._mode not in (_MODE_READ, _MODE_READ_EOF): - self._check_not_closed() - raise io.UnsupportedOperation("File not open for reading") - - def _check_can_write(self): - if self._mode != _MODE_WRITE: - self._check_not_closed() - raise io.UnsupportedOperation("File not open for writing") - - def _check_can_seek(self): - if self._mode not in (_MODE_READ, _MODE_READ_EOF): - self._check_not_closed() - raise io.UnsupportedOperation("Seeking is only supported " - "on files open for reading") - if not self._fp.seekable(): - raise io.UnsupportedOperation("The underlying file object " - "does not support seeking") - - # Fill the readahead buffer if it is empty. Returns False on EOF. - def _fill_buffer(self): - if self._mode == _MODE_READ_EOF: - return False - # Depending on the input data, our call to the decompressor may not - # return any data. In this case, try again after reading another block. - while self._buffer_offset == len(self._buffer): - rawblock = (self._decompressor.unused_data or - self._fp.read(_BUFFER_SIZE)) - - if not rawblock: - if self._decompressor.eof: - # End-of-stream marker and end of file. We're good. - self._mode = _MODE_READ_EOF - self._size = self._pos - return False - else: - # Problem - we were expecting more compressed data. - raise EOFError("Compressed file ended before the " - "end-of-stream marker was reached") - - if self._decompressor.eof: - # Continue to next stream. - self._decompressor = BZ2Decompressor() - - self._buffer = self._decompressor.decompress(rawblock) - self._buffer_offset = 0 - return True - - # Read data until EOF. - # If return_data is false, consume the data without returning it. - def _read_all(self, return_data=True): - # The loop assumes that _buffer_offset is 0. Ensure that this is true. - self._buffer = self._buffer[self._buffer_offset:] - self._buffer_offset = 0 - - blocks = [] - while self._fill_buffer(): - if return_data: - blocks.append(self._buffer) - self._pos += len(self._buffer) - self._buffer = b"" - if return_data: - return b"".join(blocks) - - # Read a block of up to n bytes. - # If return_data is false, consume the data without returning it. - def _read_block(self, n, return_data=True): - # If we have enough data buffered, return immediately. - end = self._buffer_offset + n - if end <= len(self._buffer): - data = self._buffer[self._buffer_offset : end] - self._buffer_offset = end - self._pos += len(data) - return data if return_data else None - - # The loop assumes that _buffer_offset is 0. Ensure that this is true. - self._buffer = self._buffer[self._buffer_offset:] - self._buffer_offset = 0 - - blocks = [] - while n > 0 and self._fill_buffer(): - if n < len(self._buffer): - data = self._buffer[:n] - self._buffer_offset = n - else: - data = self._buffer - self._buffer = b"" - if return_data: - blocks.append(data) - self._pos += len(data) - n -= len(data) - if return_data: - return b"".join(blocks) - def peek(self, n=0): """Return buffered data without advancing the file position. @@ -266,9 +165,10 @@ def peek(self, n=0): """ with self._lock: self._check_can_read() - if not self._fill_buffer(): - return b"" - return self._buffer[self._buffer_offset:] + # Relies on the undocumented fact that BufferedReader.peek() + # always returns at least one byte (except at EOF), independent + # of the value of n + return self._buffer.peek(n) def read(self, size=-1): """Read up to size uncompressed bytes from the file. @@ -278,47 +178,29 @@ def read(self, size=-1): """ with self._lock: self._check_can_read() - if size == 0: - return b"" - elif size < 0: - return self._read_all() - else: - return self._read_block(size) + return self._buffer.read(size) def read1(self, size=-1): """Read up to size uncompressed bytes, while trying to avoid - making multiple reads from the underlying stream. + making multiple reads from the underlying stream. Reads up to a + buffer's worth of data if size is negative. Returns b'' if the file is at EOF. """ - # Usually, read1() calls _fp.read() at most once. However, sometimes - # this does not give enough data for the decompressor to make progress. - # In this case we make multiple reads, to avoid returning b"". with self._lock: self._check_can_read() - if (size == 0 or - # Only call _fill_buffer() if the buffer is actually empty. - # This gives a significant speedup if *size* is small. - (self._buffer_offset == len(self._buffer) and not self._fill_buffer())): - return b"" - if size > 0: - data = self._buffer[self._buffer_offset : - self._buffer_offset + size] - self._buffer_offset += len(data) - else: - data = self._buffer[self._buffer_offset:] - self._buffer = b"" - self._buffer_offset = 0 - self._pos += len(data) - return data + if size < 0: + size = io.DEFAULT_BUFFER_SIZE + return self._buffer.read1(size) def readinto(self, b): - """Read up to len(b) bytes into b. + """Read bytes into b. Returns the number of bytes read (0 for EOF). """ with self._lock: - return io.BufferedIOBase.readinto(self, b) + self._check_can_read() + return self._buffer.readinto(b) def readline(self, size=-1): """Read a line of uncompressed bytes from the file. @@ -333,15 +215,7 @@ def readline(self, size=-1): size = size.__index__() with self._lock: self._check_can_read() - # Shortcut for the common case - the whole line is in the buffer. - if size < 0: - end = self._buffer.find(b"\n", self._buffer_offset) + 1 - if end > 0: - line = self._buffer[self._buffer_offset : end] - self._buffer_offset = end - self._pos += len(line) - return line - return io.BufferedIOBase.readline(self, size) + return self._buffer.readline(size) def readlines(self, size=-1): """Read a list of lines of uncompressed bytes from the file. @@ -355,7 +229,8 @@ def readlines(self, size=-1): raise TypeError("Integer argument expected") size = size.__index__() with self._lock: - return io.BufferedIOBase.readlines(self, size) + self._check_can_read() + return self._buffer.readlines(size) def write(self, data): """Write a byte string to the file. @@ -380,18 +255,9 @@ def writelines(self, seq): Line separators are not added between the written byte strings. """ with self._lock: - return io.BufferedIOBase.writelines(self, seq) - - # Rewind the file to the beginning of the data stream. - def _rewind(self): - self._fp.seek(0, 0) - self._mode = _MODE_READ - self._pos = 0 - self._decompressor = BZ2Decompressor() - self._buffer = b"" - self._buffer_offset = 0 - - def seek(self, offset, whence=0): + return _compression.BaseStream.writelines(self, seq) + + def seek(self, offset, whence=io.SEEK_SET): """Change the file position. The new position is specified by offset, relative to the @@ -408,35 +274,14 @@ def seek(self, offset, whence=0): """ with self._lock: self._check_can_seek() - - # Recalculate offset as an absolute file position. - if whence == 0: - pass - elif whence == 1: - offset = self._pos + offset - elif whence == 2: - # Seeking relative to EOF - we need to know the file's size. - if self._size < 0: - self._read_all(return_data=False) - offset = self._size + offset - else: - raise ValueError("Invalid value for whence: %s" % (whence,)) - - # Make it so that offset is the number of bytes to skip forward. - if offset < self._pos: - self._rewind() - else: - offset -= self._pos - - # Read and discard data until we reach the desired position. - self._read_block(offset, return_data=False) - - return self._pos + return self._buffer.seek(offset, whence) def tell(self): """Return the current file position.""" with self._lock: self._check_not_closed() + if self._mode == _MODE_READ: + return self._buffer.tell() return self._pos @@ -496,17 +341,19 @@ def decompress(data): For incremental decompression, use a BZ2Decompressor object instead. """ - if len(data) == 0: - return b"" - results = [] - while True: + while data: decomp = BZ2Decompressor() - results.append(decomp.decompress(data)) + try: + res = decomp.decompress(data) + except OSError: + if results: + break # Leftover data is not a valid bzip2 stream; ignore it. + else: + raise # Error on the first iteration; bail out. + results.append(res) if not decomp.eof: raise ValueError("Compressed data ended before the " "end-of-stream marker was reached") - if not decomp.unused_data: - return b"".join(results) - # There is unused data left over. Proceed to next stream. data = decomp.unused_data + return b"".join(results) diff --git a/Lib/cgi.py b/Lib/cgi.py index 1d8040cc7ab9..26d25444080d 100755 --- a/Lib/cgi.py +++ b/Lib/cgi.py @@ -32,10 +32,12 @@ # ======= from io import StringIO, BytesIO, TextIOWrapper +from collections import Mapping import sys import os import urllib.parse from email.parser import FeedParser +from email.message import Message from warnings import warn import html import locale @@ -472,18 +474,24 @@ def __init__(self, fp=None, headers=None, outerboundary=b'', self.qs_on_post = environ['QUERY_STRING'] if 'CONTENT_LENGTH' in environ: headers['content-length'] = environ['CONTENT_LENGTH'] + else: + if not (isinstance(headers, (Mapping, Message))): + raise TypeError("headers must be mapping or an instance of " + "email.message.Message") + self.headers = headers if fp is None: self.fp = sys.stdin.buffer # self.fp.read() must return bytes elif isinstance(fp, TextIOWrapper): self.fp = fp.buffer else: + if not (hasattr(fp, 'read') and hasattr(fp, 'readline')): + raise TypeError("fp must be file pointer") self.fp = fp self.encoding = encoding self.errors = errors - self.headers = headers if not isinstance(outerboundary, bytes): raise TypeError('outerboundary must be bytes, not %s' % type(outerboundary).__name__) @@ -558,6 +566,12 @@ def __del__(self): except AttributeError: pass + def __enter__(self): + return self + + def __exit__(self, *args): + self.file.close() + def __repr__(self): """Return a printable representation.""" return "FieldStorage(%r, %r, %r)" % ( @@ -642,7 +656,9 @@ def __len__(self): """Dictionary style len(x) support.""" return len(self.keys()) - def __nonzero__(self): + def __bool__(self): + if self.list is None: + raise TypeError("Cannot be converted to bool.") return bool(self.list) def read_urlencoded(self): @@ -683,8 +699,13 @@ def read_multi(self, environ, keep_blank_values, strict_parsing): raise ValueError("%s should return bytes, got %s" \ % (self.fp, type(first_line).__name__)) self.bytes_read += len(first_line) - # first line holds boundary ; ignore it, or check that - # b"--" + ib == first_line.strip() ? + + # Ensure that we consume the file until we've hit our inner boundary + while (first_line.strip() != (b"--" + self.innerboundary) and + first_line): + first_line = self.fp.readline() + self.bytes_read += len(first_line) + while True: parser = FeedParser() hdr_text = b"" @@ -699,6 +720,11 @@ def read_multi(self, environ, keep_blank_values, strict_parsing): self.bytes_read += len(hdr_text) parser.feed(hdr_text.decode(self.encoding, self.errors)) headers = parser.close() + + # Some clients add Content-Length for part headers, ignore them + if 'content-length' in headers: + del headers['content-length'] + part = klass(self.fp, headers, ib, environ, keep_blank_values, strict_parsing,self.limit-self.bytes_read, self.encoding, self.errors) @@ -1035,7 +1061,7 @@ def escape(s, quote=None): return s -def valid_boundary(s, _vb_pattern=None): +def valid_boundary(s): import re if isinstance(s, bytes): _vb_pattern = b"^[ -~]{0,200}[!-~]$" diff --git a/Lib/cgitb.py b/Lib/cgitb.py index 6eb52e764eef..b29110018cd1 100644 --- a/Lib/cgitb.py +++ b/Lib/cgitb.py @@ -294,9 +294,8 @@ def handle(self, info=None): (fd, path) = tempfile.mkstemp(suffix=suffix, dir=self.logdir) try: - file = os.fdopen(fd, 'w') - file.write(doc) - file.close() + with os.fdopen(fd, 'w') as file: + file.write(doc) msg = '%s contains the description of this error.' % path except: msg = 'Tried to save traceback to %s, but failed.' % path diff --git a/Lib/chunk.py b/Lib/chunk.py index dc90a7522e3c..84b77cc8202f 100644 --- a/Lib/chunk.py +++ b/Lib/chunk.py @@ -85,8 +85,10 @@ def getsize(self): def close(self): if not self.closed: - self.skip() - self.closed = True + try: + self.skip() + finally: + self.closed = True def isatty(self): if self.closed: @@ -126,7 +128,7 @@ def read(self, size=-1): if self.closed: raise ValueError("I/O operation on closed file") if self.size_read >= self.chunksize: - return '' + return b'' if size < 0: size = self.chunksize - self.size_read if size > self.chunksize - self.size_read: diff --git a/Lib/code.py b/Lib/code.py index f8184b6c22e5..53244e32ad68 100644 --- a/Lib/code.py +++ b/Lib/code.py @@ -7,6 +7,7 @@ import sys import traceback +import argparse from codeop import CommandCompiler, compile_command __all__ = ["InteractiveInterpreter", "InteractiveConsole", "interact", @@ -136,25 +137,18 @@ def showtraceback(self): The output is written by self.write(), below. """ + sys.last_type, sys.last_value, last_tb = ei = sys.exc_info() + sys.last_traceback = last_tb try: - type, value, tb = sys.exc_info() - sys.last_type = type - sys.last_value = value - sys.last_traceback = tb - tblist = traceback.extract_tb(tb) - del tblist[:1] - lines = traceback.format_list(tblist) - if lines: - lines.insert(0, "Traceback (most recent call last):\n") - lines.extend(traceback.format_exception_only(type, value)) + lines = traceback.format_exception(ei[0], ei[1], last_tb.tb_next) + if sys.excepthook is sys.__excepthook__: + self.write(''.join(lines)) + else: + # If someone has set sys.excepthook, we let that take precedence + # over self.write + sys.excepthook(ei[0], ei[1], last_tb) finally: - tblist = tb = None - if sys.excepthook is sys.__excepthook__: - self.write(''.join(lines)) - else: - # If someone has set sys.excepthook, we let that take precedence - # over self.write - sys.excepthook(type, value, tb) + last_tb = ei = None def write(self, data): """Write a string. @@ -299,4 +293,12 @@ def interact(banner=None, readfunc=None, local=None): if __name__ == "__main__": - interact() + parser = argparse.ArgumentParser() + parser.add_argument('-q', action='http://github.com/store_true', + help="don't print version and copyright messages") + args = parser.parse_args() + if args.q or sys.flags.quiet: + banner = '' + else: + banner = None + interact(banner) diff --git a/Lib/codecs.py b/Lib/codecs.py index 2e2e7555a482..22d5f82afe5a 100644 --- a/Lib/codecs.py +++ b/Lib/codecs.py @@ -20,8 +20,15 @@ "BOM_LE", "BOM32_BE", "BOM32_LE", "BOM64_BE", "BOM64_LE", "BOM_UTF8", "BOM_UTF16", "BOM_UTF16_LE", "BOM_UTF16_BE", "BOM_UTF32", "BOM_UTF32_LE", "BOM_UTF32_BE", + "CodecInfo", "Codec", "IncrementalEncoder", "IncrementalDecoder", + "StreamReader", "StreamWriter", + "StreamReaderWriter", "StreamRecoder", + "getencoder", "getdecoder", "getincrementalencoder", + "getincrementaldecoder", "getreader", "getwriter", + "encode", "decode", "iterencode", "iterdecode", "strict_errors", "ignore_errors", "replace_errors", "xmlcharrefreplace_errors", + "backslashreplace_errors", "namereplace_errors", "register_error", "lookup_error"] ### Constants @@ -99,8 +106,8 @@ def __new__(cls, encode, decode, streamreader=None, streamwriter=None, return self def __repr__(self): - return "<%s.%s object for encoding %s at 0x%x>" % \ - (self.__class__.__module__, self.__class__.__name__, + return "<%s.%s object for encoding %s at %#x>" % \ + (self.__class__.__module__, self.__class__.__qualname__, self.name, id(self)) class Codec: @@ -117,10 +124,11 @@ class Codec: Python will use the official U+FFFD REPLACEMENT CHARACTER for the builtin Unicode codecs on decoding and '?' on encoding. - 'surrogateescape' - replace with private codepoints U+DCnn. + 'surrogateescape' - replace with private code points U+DCnn. 'xmlcharrefreplace' - Replace with the appropriate XML character reference (only for encoding). - 'backslashreplace' - Replace with backslashed escape sequences + 'backslashreplace' - Replace with backslashed escape sequences. + 'namereplace' - Replace with \\N{...} escape sequences (only for encoding). The set of allowed values can be extended via register_error. @@ -135,8 +143,8 @@ def encode(self, input, errors='strict'): 'strict' handling. The method may not store state in the Codec instance. Use - StreamCodec for codecs which have to keep state in order to - make encoding/decoding efficient. + StreamWriter for codecs which have to keep state in order to + make encoding efficient. The encoder must be able to handle zero length input and return an empty object of the output object type in this @@ -158,8 +166,8 @@ def decode(self, input, errors='strict'): 'strict' handling. The method may not store state in the Codec instance. Use - StreamCodec for codecs which have to keep state in order to - make encoding/decoding efficient. + StreamReader for codecs which have to keep state in order to + make decoding efficient. The decoder must be able to handle zero length input and return an empty object of the output object type in this @@ -340,8 +348,7 @@ def __init__(self, stream, errors='strict'): """ Creates a StreamWriter instance. - stream must be a file-like object open for writing - (binary) data. + stream must be a file-like object open for writing. The StreamWriter may use different error handling schemes by providing the errors keyword argument. These @@ -353,7 +360,8 @@ def __init__(self, stream, errors='strict'): 'xmlcharrefreplace' - Replace with the appropriate XML character reference. 'backslashreplace' - Replace with backslashed escape - sequences (only for encoding). + sequences. + 'namereplace' - Replace with \\N{...} escape sequences. The set of allowed parameter values can be extended via register_error. @@ -415,8 +423,7 @@ def __init__(self, stream, errors='strict'): """ Creates a StreamReader instance. - stream must be a file-like object open for reading - (binary) data. + stream must be a file-like object open for reading. The StreamReader may use different error handling schemes by providing the errors keyword argument. These @@ -424,7 +431,8 @@ def __init__(self, stream, errors='strict'): 'strict' - raise a ValueError (or a subclass) 'ignore' - ignore the character and continue with the next - 'replace'- replace with a suitable replacement character; + 'replace'- replace with a suitable replacement character + 'backslashreplace' - Replace with backslashed escape sequences; The set of allowed parameter values can be extended via register_error. @@ -444,13 +452,12 @@ def read(self, size=-1, chars=-1, firstline=False): """ Decodes data from the stream self.stream and returns the resulting object. - chars indicates the number of characters to read from the - stream. read() will never return more than chars - characters, but it might return less, if there are not enough - characters available. + chars indicates the number of decoded code points or bytes to + return. read() will never return more data than requested, + but it might return less, if there is not enough available. - size indicates the approximate maximum number of bytes to - read from the stream for decoding purposes. The decoder + size indicates the approximate maximum number of decoded + bytes or code points to read for decoding. The decoder can modify this setting as appropriate. The default value -1 indicates to read and decode as much as possible. size is intended to prevent having to decode huge files in one @@ -461,7 +468,7 @@ def read(self, size=-1, chars=-1, firstline=False): will be returned, the rest of the input will be kept until the next call to read(). - The method should use a greedy read strategy meaning that + The method should use a greedy read strategy, meaning that it should read as much data as is allowed within the definition of the encoding and the given size, e.g. if optional encoding endings or state markers are available @@ -475,15 +482,12 @@ def read(self, size=-1, chars=-1, firstline=False): # read until we get the required number of characters (if available) while True: # can the request be satisfied from the character buffer? - if chars < 0: - if size < 0: - if self.charbuffer: - break - elif len(self.charbuffer) >= size: - break - else: + if chars >= 0: if len(self.charbuffer) >= chars: break + elif size >= 0: + if len(self.charbuffer) >= size: + break # we need more data if size < 0: newdata = self.stream.read() @@ -491,6 +495,8 @@ def read(self, size=-1, chars=-1, firstline=False): newdata = self.stream.read(size) # decode bytes (those remaining from the last call included) data = self.bytebuffer + newdata + if not data: + break try: newchars, decodedbytes = self.decode(data, self.errors) except UnicodeDecodeError as exc: @@ -597,7 +603,7 @@ def readline(self, size=None, keepends=True): def readlines(self, sizehint=None, keepends=True): """ Read all lines available on the input stream - and return them as list of lines. + and return them as a list. Line breaks are implemented using the codec's decoder method and are included in the list entries. @@ -745,19 +751,18 @@ def __exit__(self, type, value, tb): class StreamRecoder: - """ StreamRecoder instances provide a frontend - backend - view of encoding data. + """ StreamRecoder instances translate data from one encoding to another. They use the complete set of APIs returned by the codecs.lookup() function to implement their task. - Data written to the stream is first decoded into an - intermediate format (which is dependent on the given codec - combination) and then written to the stream using an instance - of the provided Writer class. + Data written to the StreamRecoder is first decoded into an + intermediate format (depending on the "decode" codec) and then + written to the underlying stream using an instance of the provided + Writer class. - In the other direction, data is read from the stream using a - Reader instance and then return encoded data to the caller. + In the other direction, data is read from the underlying stream using + a Reader instance and then encoded and returned to the caller. """ # Optional attributes set by the file wrappers below @@ -769,22 +774,17 @@ def __init__(self, stream, encode, decode, Reader, Writer, """ Creates a StreamRecoder instance which implements a two-way conversion: encode and decode work on the frontend (the - input to .read() and output of .write()) while - Reader and Writer work on the backend (reading and - writing to the stream). + data visible to .read() and .write()) while Reader and Writer + work on the backend (the data in stream). - You can use these objects to do transparent direct - recodings from e.g. latin-1 to utf-8 and back. + You can use these objects to do transparent + transcodings from e.g. latin-1 to utf-8 and back. stream must be a file-like object. - encode, decode must adhere to the Codec interface, Reader, + encode and decode must adhere to the Codec interface; Reader and Writer must be factory functions or classes providing the - StreamReader, StreamWriter interface resp. - - encode and decode are needed for the frontend translation, - Reader and Writer for the backend translation. Unicode is - used as intermediate encoding. + StreamReader and StreamWriter interfaces resp. Error handling is done in the same way as defined for the StreamWriter/Readers. @@ -859,7 +859,7 @@ def __exit__(self, type, value, tb): ### Shortcuts -def open(filename, mode='rb', encoding=None, errors='strict', buffering=1): +def open(filename, mode='r', encoding=None, errors='strict', buffering=1): """ Open an encoded file using the given mode and return a wrapped version providing transparent encoding/decoding. @@ -869,10 +869,8 @@ def open(filename, mode='rb', encoding=None, errors='strict', buffering=1): codecs. Output is also codec dependent and will usually be Unicode as well. - Files are always opened in binary mode, even if no binary mode - was specified. This is done to avoid data loss due to encodings - using 8-bit values. The default file mode is 'rb' meaning to - open the file in binary read mode. + Underlying encoded files are always opened in binary mode. + The default file mode is 'r', meaning to open the file in read mode. encoding specifies the encoding which is to be used for the file. @@ -908,13 +906,13 @@ def EncodedFile(file, data_encoding, file_encoding=None, errors='strict'): """ Return a wrapped version of file which provides transparent encoding translation. - Strings written to the wrapped file are interpreted according - to the given data_encoding and then written to the original - file as string using file_encoding. The intermediate encoding + Data written to the wrapped file is decoded according + to the given data_encoding and then encoded to the underlying + file using file_encoding. The intermediate data type will usually be Unicode but depends on the specified codecs. - Strings are read from the file using file_encoding and then - passed back to the caller as string using data_encoding. + Bytes read from the file are decoded using file_encoding and then + passed back to the caller encoded using data_encoding. If file_encoding is not given, it defaults to data_encoding. @@ -1067,7 +1065,7 @@ def make_encoding_map(decoding_map): during translation. One example where this happens is cp875.py which decodes - multiple character to \u001a. + multiple character to \\u001a. """ m = {} @@ -1086,6 +1084,7 @@ def make_encoding_map(decoding_map): replace_errors = lookup_error("replace") xmlcharrefreplace_errors = lookup_error("xmlcharrefreplace") backslashreplace_errors = lookup_error("backslashreplace") + namereplace_errors = lookup_error("namereplace") except LookupError: # In --disable-unicode builds, these error handler are missing strict_errors = None @@ -1093,6 +1092,7 @@ def make_encoding_map(decoding_map): replace_errors = None xmlcharrefreplace_errors = None backslashreplace_errors = None + namereplace_errors = None # Tell modulefinder that using codecs probably needs the encodings # package diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 02bdc57c9fee..638a4ca1eb30 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -7,7 +7,6 @@ import _collections_abc __all__ += _collections_abc.__all__ -from _collections import deque, defaultdict from operator import itemgetter as _itemgetter, eq as _eq from keyword import iskeyword as _iskeyword import sys as _sys @@ -16,10 +15,40 @@ from itertools import repeat as _repeat, chain as _chain, starmap as _starmap from reprlib import recursive_repr as _recursive_repr +try: + from _collections import deque +except ImportError: + pass +else: + MutableSequence.register(deque) + +try: + from _collections import defaultdict +except ImportError: + pass + + ################################################################################ ### OrderedDict ################################################################################ +class _OrderedDictKeysView(KeysView): + + def __reversed__(self): + yield from reversed(self._mapping) + +class _OrderedDictItemsView(ItemsView): + + def __reversed__(self): + for key in reversed(self._mapping): + yield (key, self._mapping[key]) + +class _OrderedDictValuesView(ValuesView): + + def __reversed__(self): + for key in reversed(self._mapping): + yield self._mapping[key] + class _Link(object): __slots__ = 'prev', 'next', 'key', '__weakref__' @@ -38,12 +67,16 @@ class OrderedDict(dict): # Individual links are kept alive by the hard reference in self.__map. # Those hard references disappear when a key is deleted from an OrderedDict. - def __init__(self, *args, **kwds): + def __init__(*args, **kwds): '''Initialize an ordered dictionary. The signature is the same as regular dictionaries, but keyword arguments are not recommended because their insertion order is arbitrary. ''' + if not args: + raise TypeError("descriptor '__init__' of 'OrderedDict' object " + "needs an argument") + self, *args = args if len(args) > 1: raise TypeError('expected at most 1 arguments, got %d' % len(args)) try: @@ -79,6 +112,8 @@ def __delitem__(self, key, dict_delitem=dict.__delitem__): link_next = link.next link_prev.next = link_next link_next.prev = link_prev + link.prev = None + link.next = None def __iter__(self): 'od.__iter__() <==> iter(od)' @@ -162,9 +197,19 @@ def __sizeof__(self): return size update = __update = MutableMapping.update - keys = MutableMapping.keys - values = MutableMapping.values - items = MutableMapping.items + + def keys(self): + "D.keys() -> a set-like object providing a view on D's keys" + return _OrderedDictKeysView(self) + + def items(self): + "D.items() -> a set-like object providing a view on D's items" + return _OrderedDictItemsView(self) + + def values(self): + "D.values() -> an object providing a view on D's values" + return _OrderedDictValuesView(self) + __ne__ = MutableMapping.__ne__ __marker = object() @@ -229,6 +274,13 @@ def __eq__(self, other): return dict.__eq__(self, other) +try: + from _collections import OrderedDict +except ImportError: + # Leave the pure Python version in place. + pass + + ################################################################################ ### namedtuple ################################################################################ @@ -268,25 +320,14 @@ def __repr__(self): 'Return a nicely formatted representation string' return self.__class__.__name__ + '({repr_fmt})' % self - @property - def __dict__(self): - 'A new OrderedDict mapping field names to their values' - return OrderedDict(zip(self._fields, self)) - def _asdict(self): - '''Return a new OrderedDict which maps field names to their values. - This method is obsolete. Use vars(nt) or nt.__dict__ instead. - ''' - return self.__dict__ + 'Return a new OrderedDict which maps field names to their values.' + return OrderedDict(zip(self._fields, self)) def __getnewargs__(self): 'Return self as a plain tuple. Used by copy and pickle.' return tuple(self) - def __getstate__(self): - 'Exclude the OrderedDict from pickling' - return None - {field_defs} """ @@ -325,6 +366,7 @@ def namedtuple(typename, field_names, verbose=False, rename=False): if isinstance(field_names, str): field_names = field_names.replace(',', ' ').split() field_names = list(map(str, field_names)) + typename = str(typename) if rename: seen = set() for index, name in enumerate(field_names): @@ -335,6 +377,8 @@ def namedtuple(typename, field_names, verbose=False, rename=False): field_names[index] = '_%d' % index seen.add(name) for name in [typename] + field_names: + if type(name) != str: + raise TypeError('Type names and field names must be strings') if not name.isidentifier(): raise ValueError('Type names and field names must be valid ' 'identifiers: %r' % name) @@ -449,7 +493,7 @@ class Counter(dict): # http://code.activestate.com/recipes/259174/ # Knuth, TAOCP Vol. II section 4.6.3 - def __init__(self, iterable=None, **kwds): + def __init__(*args, **kwds): '''Create a new, empty Counter object. And if given, count elements from an input iterable. Or, initialize the count from another mapping of elements to their counts. @@ -460,8 +504,14 @@ def __init__(self, iterable=None, **kwds): >>> c = Counter(a=4, b=2) # a new counter from keyword args ''' - super().__init__() - self.update(iterable, **kwds) + if not args: + raise TypeError("descriptor '__init__' of 'Counter' object " + "needs an argument") + self, *args = args + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + super(Counter, self).__init__() + self.update(*args, **kwds) def __missing__(self, key): 'The count of elements not in the Counter is zero.' @@ -512,7 +562,7 @@ def fromkeys(cls, iterable, v=None): raise NotImplementedError( 'Counter.fromkeys() is undefined. Use Counter(iterable) instead.') - def update(self, iterable=None, **kwds): + def update(*args, **kwds): '''Like dict.update() but add counts instead of replacing them. Source can be an iterable, a dictionary, or another Counter instance. @@ -532,6 +582,13 @@ def update(self, iterable=None, **kwds): # contexts. Instead, we implement straight-addition. Both the inputs # and outputs are allowed to contain zero and negative counts. + if not args: + raise TypeError("descriptor 'update' of 'Counter' object " + "needs an argument") + self, *args = args + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + iterable = args[0] if args else None if iterable is not None: if isinstance(iterable, Mapping): if self: @@ -539,13 +596,13 @@ def update(self, iterable=None, **kwds): for elem, count in iterable.items(): self[elem] = count + self_get(elem, 0) else: - super().update(iterable) # fast path when counter is empty + super(Counter, self).update(iterable) # fast path when counter is empty else: _count_elements(self, iterable) if kwds: self.update(kwds) - def subtract(self, iterable=None, **kwds): + def subtract(*args, **kwds): '''Like dict.update() but subtracts counts instead of replacing them. Counts can be reduced below zero. Both the inputs and outputs are allowed to contain zero and negative counts. @@ -561,6 +618,13 @@ def subtract(self, iterable=None, **kwds): -1 ''' + if not args: + raise TypeError("descriptor 'subtract' of 'Counter' object " + "needs an argument") + self, *args = args + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + iterable = args[0] if args else None if iterable is not None: self_get = self.get if isinstance(iterable, Mapping): @@ -680,14 +744,22 @@ def __and__(self, other): def __pos__(self): 'Adds an empty counter, effectively stripping negative and zero counts' - return self + Counter() + result = Counter() + for elem, count in self.items(): + if count > 0: + result[elem] = count + return result def __neg__(self): '''Subtracts from an empty counter. Strips positive and zero counts, and flips the sign on negative counts. ''' - return Counter() - self + result = Counter() + for elem, count in self.items(): + if count < 0: + result[elem] = 0 - count + return result def _keep_positive(self): '''Internal method to strip elements with a negative or zero count''' @@ -820,9 +892,8 @@ def copy(self): __copy__ = copy def new_child(self, m=None): # like Django's Context.push() - ''' - New ChainMap with a new map followed by all previous maps. If no - map is provided, an empty dict is used. + '''New ChainMap with a new map followed by all previous maps. + If no map is provided, an empty dict is used. ''' if m is None: m = {} @@ -868,7 +939,22 @@ def clear(self): class UserDict(MutableMapping): # Start by filling-out the abstract methods - def __init__(self, dict=None, **kwargs): + def __init__(*args, **kwargs): + if not args: + raise TypeError("descriptor '__init__' of 'UserDict' object " + "needs an argument") + self, *args = args + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + if args: + dict = args[0] + elif 'dict' in kwargs: + dict = kwargs.pop('dict') + import warnings + warnings.warn("Passing 'dict' as keyword argument is deprecated", + DeprecationWarning, stacklevel=2) + else: + dict = None self.data = {} if dict is not None: self.update(dict) @@ -933,7 +1019,6 @@ def __repr__(self): return repr(self.data) def __lt__(self, other): return self.data < self.__cast(other) def __le__(self, other): return self.data <= self.__cast(other) def __eq__(self, other): return self.data == self.__cast(other) - def __ne__(self, other): return self.data != self.__cast(other) def __gt__(self, other): return self.data > self.__cast(other) def __ge__(self, other): return self.data >= self.__cast(other) def __cast(self, other): @@ -1005,15 +1090,13 @@ def __int__(self): return int(self.data) def __float__(self): return float(self.data) def __complex__(self): return complex(self.data) def __hash__(self): return hash(self.data) + def __getnewargs__(self): + return (self.data[:],) def __eq__(self, string): if isinstance(string, UserString): return self.data == string.data return self.data == string - def __ne__(self, string): - if isinstance(string, UserString): - return self.data != string.data - return self.data != string def __lt__(self, string): if isinstance(string, UserString): return self.data < string.data @@ -1053,9 +1136,13 @@ def __mul__(self, n): __rmul__ = __mul__ def __mod__(self, args): return self.__class__(self.data % args) + def __rmod__(self, format): + return self.__class__(format % args) # the following methods are defined in alphabetical order: def capitalize(self): return self.__class__(self.data.capitalize()) + def casefold(self): + return self.__class__(self.data.casefold()) def center(self, width, *args): return self.__class__(self.data.center(width, *args)) def count(self, sub, start=0, end=_sys.maxsize): @@ -1078,6 +1165,8 @@ def find(self, sub, start=0, end=_sys.maxsize): return self.data.find(sub, start, end) def format(self, *args, **kwds): return self.data.format(*args, **kwds) + def format_map(self, mapping): + return self.data.format_map(mapping) def index(self, sub, start=0, end=_sys.maxsize): return self.data.index(sub, start, end) def isalpha(self): return self.data.isalpha() @@ -1087,6 +1176,7 @@ def isdigit(self): return self.data.isdigit() def isidentifier(self): return self.data.isidentifier() def islower(self): return self.data.islower() def isnumeric(self): return self.data.isnumeric() + def isprintable(self): return self.data.isprintable() def isspace(self): return self.data.isspace() def istitle(self): return self.data.istitle() def isupper(self): return self.data.isupper() @@ -1095,6 +1185,7 @@ def ljust(self, width, *args): return self.__class__(self.data.ljust(width, *args)) def lower(self): return self.__class__(self.data.lower()) def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars)) + maketrans = str.maketrans def partition(self, sep): return self.data.partition(sep) def replace(self, old, new, maxsplit=-1): diff --git a/Lib/compileall.py b/Lib/compileall.py index 475dc1c8a0ad..64c0a9abdb67 100644 --- a/Lib/compileall.py +++ b/Lib/compileall.py @@ -1,4 +1,4 @@ -"""Module/script to byte-compile all .py files to .pyc (or .pyo) files. +"""Module/script to byte-compile all .py files to .pyc files. When called as a script with arguments, this compiles the directories given as arguments recursively; the -l option prevents it from @@ -12,37 +12,28 @@ """ import os import sys -import errno import importlib.util import py_compile import struct -__all__ = ["compile_dir","compile_file","compile_path"] - -def compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, - quiet=False, legacy=False, optimize=-1): - """Byte-compile all modules in the given directory tree. +try: + from concurrent.futures import ProcessPoolExecutor +except ImportError: + ProcessPoolExecutor = None +from functools import partial - Arguments (only dir is required): +__all__ = ["compile_dir","compile_file","compile_path"] - dir: the directory to byte-compile - maxlevels: maximum recursion level (default 10) - ddir: the directory that will be prepended to the path to the - file as it is compiled into each byte-code file. - force: if True, force compilation, even if timestamps are up-to-date - quiet: if True, be quiet during compilation - legacy: if True, produce legacy pyc paths instead of PEP 3147 paths - optimize: optimization level or -1 for level of the interpreter - """ +def _walk_dir(dir, ddir=None, maxlevels=10, quiet=0): if not quiet: print('Listing {!r}...'.format(dir)) try: names = os.listdir(dir) except OSError: - print("Can't list {!r}".format(dir)) + if quiet < 2: + print("Can't list {!r}".format(dir)) names = [] names.sort() - success = 1 for name in names: if name == '__pycache__': continue @@ -52,17 +43,53 @@ def compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, else: dfile = None if not os.path.isdir(fullname): - if not compile_file(fullname, ddir, force, rx, quiet, - legacy, optimize): - success = 0 + yield fullname elif (maxlevels > 0 and name != os.curdir and name != os.pardir and os.path.isdir(fullname) and not os.path.islink(fullname)): - if not compile_dir(fullname, maxlevels - 1, dfile, force, rx, - quiet, legacy, optimize): + yield from _walk_dir(fullname, ddir=dfile, + maxlevels=maxlevels - 1, quiet=quiet) + +def compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, + quiet=0, legacy=False, optimize=-1, workers=1): + """Byte-compile all modules in the given directory tree. + + Arguments (only dir is required): + + dir: the directory to byte-compile + maxlevels: maximum recursion level (default 10) + ddir: the directory that will be prepended to the path to the + file as it is compiled into each byte-code file. + force: if True, force compilation, even if timestamps are up-to-date + quiet: full output with False or 0, errors only with 1, + no output with 2 + legacy: if True, produce legacy pyc paths instead of PEP 3147 paths + optimize: optimization level or -1 for level of the interpreter + workers: maximum number of parallel workers + """ + files = _walk_dir(dir, quiet=quiet, maxlevels=maxlevels, + ddir=ddir) + success = 1 + if workers is not None and workers != 1 and ProcessPoolExecutor is not None: + if workers < 0: + raise ValueError('workers must be greater or equal to 0') + + workers = workers or None + with ProcessPoolExecutor(max_workers=workers) as executor: + results = executor.map(partial(compile_file, + ddir=ddir, force=force, + rx=rx, quiet=quiet, + legacy=legacy, + optimize=optimize), + files) + success = min(results, default=1) + else: + for file in files: + if not compile_file(file, ddir, force, rx, quiet, + legacy, optimize): success = 0 return success -def compile_file(fullname, ddir=None, force=False, rx=None, quiet=False, +def compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1): """Byte-compile one file. @@ -72,7 +99,8 @@ def compile_file(fullname, ddir=None, force=False, rx=None, quiet=False, ddir: if given, the directory name compiled in to the byte-code file. force: if True, force compilation, even if timestamps are up-to-date - quiet: if True, be quiet during compilation + quiet: full output with False or 0, errors only with 1, + no output with 2 legacy: if True, produce legacy pyc paths instead of PEP 3147 paths optimize: optimization level or -1 for level of the interpreter """ @@ -88,11 +116,12 @@ def compile_file(fullname, ddir=None, force=False, rx=None, quiet=False, return success if os.path.isfile(fullname): if legacy: - cfile = fullname + ('c' if __debug__ else 'o') + cfile = fullname + 'c' else: if optimize >= 0: + opt = optimize if optimize >= 1 else '' cfile = importlib.util.cache_from_source( - fullname, debug_override=not optimize) + fullname, optimization=opt) else: cfile = importlib.util.cache_from_source(fullname) cache_dir = os.path.dirname(cfile) @@ -115,7 +144,10 @@ def compile_file(fullname, ddir=None, force=False, rx=None, quiet=False, ok = py_compile.compile(fullname, cfile, dfile, True, optimize=optimize) except py_compile.PyCompileError as err: - if quiet: + success = 0 + if quiet >= 2: + return success + elif quiet: print('*** Error compiling {!r}...'.format(fullname)) else: print('*** ', end='') @@ -124,20 +156,21 @@ def compile_file(fullname, ddir=None, force=False, rx=None, quiet=False, errors='backslashreplace') msg = msg.decode(sys.stdout.encoding) print(msg) - success = 0 except (SyntaxError, UnicodeError, OSError) as e: - if quiet: + success = 0 + if quiet >= 2: + return success + elif quiet: print('*** Error compiling {!r}...'.format(fullname)) else: print('*** ', end='') print(e.__class__.__name__ + ':', e) - success = 0 else: if ok == 0: success = 0 return success -def compile_path(skip_curdir=1, maxlevels=0, force=False, quiet=False, +def compile_path(skip_curdir=1, maxlevels=0, force=False, quiet=0, legacy=False, optimize=-1): """Byte-compile all module on sys.path. @@ -146,14 +179,15 @@ def compile_path(skip_curdir=1, maxlevels=0, force=False, quiet=False, skip_curdir: if true, skip current directory (default True) maxlevels: max recursion level (default 0) force: as for compile_dir() (default False) - quiet: as for compile_dir() (default False) + quiet: as for compile_dir() (default 0) legacy: as for compile_dir() (default False) optimize: as for compile_dir() (default -1) """ success = 1 for dir in sys.path: if (not dir or dir == os.curdir) and skip_curdir: - print('Skipping current directory') + if quiet < 2: + print('Skipping current directory') else: success = success and compile_dir(dir, maxlevels, None, force, quiet=quiet, @@ -170,10 +204,15 @@ def main(): parser.add_argument('-l', action='http://github.com/store_const', const=0, default=10, dest='maxlevels', help="don't recurse into subdirectories") + parser.add_argument('-r', type=int, dest='recursion', + help=('control the maximum recursion level. ' + 'if `-l` and `-r` options are specified, ' + 'then `-r` takes precedence.')) parser.add_argument('-f', action='http://github.com/store_true', dest='force', help='force rebuild even if timestamps are up to date') - parser.add_argument('-q', action='http://github.com/store_true', dest='quiet', - help='output only error messages') + parser.add_argument('-q', action='http://github.com/count', dest='quiet', default=0, + help='output only error messages; -qq will suppress ' + 'the error messages as well.') parser.add_argument('-b', action='http://github.com/store_true', dest='legacy', help='use legacy (pre-PEP3147) compiled file locations') parser.add_argument('-d', metavar='DESTDIR', dest='ddir', default=None, @@ -193,8 +232,10 @@ def main(): help=('zero or more file and directory names ' 'to compile; if no arguments given, defaults ' 'to the equivalent of -l sys.path')) - args = parser.parse_args() + parser.add_argument('-j', '--workers', default=1, + type=int, help='Run compileall concurrently') + args = parser.parse_args() compile_dests = args.compile_dest if (args.ddir and (len(compile_dests) != 1 @@ -204,6 +245,12 @@ def main(): import re args.rx = re.compile(args.rx) + + if args.recursion is not None: + maxlevels = args.recursion + else: + maxlevels = args.maxlevels + # if flist is provided then load it if args.flist: try: @@ -211,9 +258,13 @@ def main(): for line in f: compile_dests.append(line.strip()) except OSError: - print("Error reading file list {}".format(args.flist)) + if args.quiet < 2: + print("Error reading file list {}".format(args.flist)) return False + if args.workers is not None: + args.workers = args.workers or None + success = True try: if compile_dests: @@ -223,15 +274,17 @@ def main(): args.quiet, args.legacy): success = False else: - if not compile_dir(dest, args.maxlevels, args.ddir, + if not compile_dir(dest, maxlevels, args.ddir, args.force, args.rx, args.quiet, - args.legacy): + args.legacy, workers=args.workers): success = False return success else: - return compile_path(legacy=args.legacy) + return compile_path(legacy=args.legacy, force=args.force, + quiet=args.quiet) except KeyboardInterrupt: - print("\n[interrupted]") + if args.quiet < 2: + print("\n[interrupted]") return False return True diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py index 3d0328049fef..9e447137adce 100644 --- a/Lib/concurrent/futures/_base.py +++ b/Lib/concurrent/futures/_base.py @@ -181,7 +181,8 @@ def as_completed(fs, timeout=None): Returns: An iterator that yields the given Futures as they complete (finished or - cancelled). + cancelled). If any given Futures are duplicated, they will be returned + once. Raises: TimeoutError: If the entire result iterator could not be generated @@ -190,11 +191,12 @@ def as_completed(fs, timeout=None): if timeout is not None: end_time = timeout + time.time() + fs = set(fs) with _AcquireFutures(fs): finished = set( f for f in fs if f._state in [CANCELLED_AND_NOTIFIED, FINISHED]) - pending = set(fs) - finished + pending = fs - finished waiter = _create_and_install_waiters(fs, _AS_COMPLETED) try: @@ -223,7 +225,8 @@ def as_completed(fs, timeout=None): finally: for f in fs: - f._waiters.remove(waiter) + with f._condition: + f._waiters.remove(waiter) DoneAndNotDoneFutures = collections.namedtuple( 'DoneAndNotDoneFutures', 'done not_done') @@ -270,7 +273,8 @@ def wait(fs, timeout=None, return_when=ALL_COMPLETED): waiter.event.wait(timeout) for f in fs: - f._waiters.remove(waiter) + with f._condition: + f._waiters.remove(waiter) done.update(waiter.finished_futures) return DoneAndNotDoneFutures(done, set(fs) - done) @@ -298,17 +302,20 @@ def __repr__(self): with self._condition: if self._state == FINISHED: if self._exception: - return '<Future at %s state=%s raised %s>' % ( - hex(id(self)), + return '<%s at %#x state=%s raised %s>' % ( + self.__class__.__name__, + id(self), _STATE_TO_DESCRIPTION_MAP[self._state], self._exception.__class__.__name__) else: - return '<Future at %s state=%s returned %s>' % ( - hex(id(self)), + return '<%s at %#x state=%s returned %s>' % ( + self.__class__.__name__, + id(self), _STATE_TO_DESCRIPTION_MAP[self._state], self._result.__class__.__name__) - return '<Future at %s state=%s>' % ( - hex(id(self)), + return '<%s at %#x state=%s>' % ( + self.__class__.__name__, + id(self), _STATE_TO_DESCRIPTION_MAP[self._state]) def cancel(self): @@ -513,7 +520,7 @@ def submit(self, fn, *args, **kwargs): """ raise NotImplementedError() - def map(self, fn, *iterables, timeout=None): + def map(self, fn, *iterables, timeout=None, chunksize=1): """Returns a iterator equivalent to map(fn, iter). Args: @@ -521,6 +528,10 @@ def map(self, fn, *iterables, timeout=None): passed iterables. timeout: The maximum number of seconds to wait. If None, then there is no limit on the wait time. + chunksize: The size of the chunks the iterable will be broken into + before being passed to a child process. This argument is only + used by ProcessPoolExecutor; it is ignored by + ThreadPoolExecutor. Returns: An iterator equivalent to: map(func, *iterables) but the calls may diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py index 07b5225d1dab..3dd6da1f0c11 100644 --- a/Lib/concurrent/futures/process.py +++ b/Lib/concurrent/futures/process.py @@ -55,6 +55,9 @@ from multiprocessing.connection import wait import threading import weakref +from functools import partial +import itertools +import traceback # Workers are created as daemon threads and processes. This is done to allow the # interpreter to exit when there are still idle processes in a @@ -88,6 +91,27 @@ def _python_exit(): # (Futures in the call queue cannot be cancelled). EXTRA_QUEUED_CALLS = 1 +# Hack to embed stringification of remote traceback in local traceback + +class _RemoteTraceback(Exception): + def __init__(self, tb): + self.tb = tb + def __str__(self): + return self.tb + +class _ExceptionWithTraceback: + def __init__(self, exc, tb): + tb = traceback.format_exception(type(exc), exc, tb) + tb = ''.join(tb) + self.exc = exc + self.tb = '\n"""\n%s"""' % tb + def __reduce__(self): + return _rebuild_exc, (self.exc, self.tb) + +def _rebuild_exc(exc, tb): + exc.__cause__ = _RemoteTraceback(tb) + return exc + class _WorkItem(object): def __init__(self, future, fn, args, kwargs): self.future = future @@ -108,6 +132,26 @@ def __init__(self, work_id, fn, args, kwargs): self.args = args self.kwargs = kwargs +def _get_chunks(*iterables, chunksize): + """ Iterates over zip()ed iterables in chunks. """ + it = zip(*iterables) + while True: + chunk = tuple(itertools.islice(it, chunksize)) + if not chunk: + return + yield chunk + +def _process_chunk(fn, chunk): + """ Processes a chunk of an iterable passed to map. + + Runs the function passed to map() on a chunk of the + iterable passed to map. + + This function is run in a separate process. + + """ + return [fn(*args) for args in chunk] + def _process_worker(call_queue, result_queue): """Evaluates calls from call_queue and places the results in result_queue. @@ -130,8 +174,8 @@ def _process_worker(call_queue, result_queue): try: r = call_item.fn(*call_item.args, **call_item.kwargs) except BaseException as e: - result_queue.put(_ResultItem(call_item.work_id, - exception=e)) + exc = _ExceptionWithTraceback(e, e.__traceback__) + result_queue.put(_ResultItem(call_item.work_id, exception=exc)) else: result_queue.put(_ResultItem(call_item.work_id, result=r)) @@ -334,6 +378,9 @@ def __init__(self, max_workers=None): if max_workers is None: self._max_workers = os.cpu_count() or 1 else: + if max_workers <= 0: + raise ValueError("max_workers must be greater than 0") + self._max_workers = max_workers # Make the call queue slightly larger than the number of processes to @@ -408,6 +455,35 @@ def submit(self, fn, *args, **kwargs): return f submit.__doc__ = _base.Executor.submit.__doc__ + def map(self, fn, *iterables, timeout=None, chunksize=1): + """Returns a iterator equivalent to map(fn, iter). + + Args: + fn: A callable that will take as many arguments as there are + passed iterables. + timeout: The maximum number of seconds to wait. If None, then there + is no limit on the wait time. + chunksize: If greater than one, the iterables will be chopped into + chunks of size chunksize and submitted to the process pool. + If set to one, the items in the list will be sent one at a time. + + Returns: + An iterator equivalent to: map(func, *iterables) but the calls may + be evaluated out-of-order. + + Raises: + TimeoutError: If the entire result iterator could not be generated + before the given timeout. + Exception: If fn(*args) raises for any values. + """ + if chunksize < 1: + raise ValueError("chunksize must be >= 1.") + + results = super().map(partial(_process_chunk, fn), + _get_chunks(*iterables, chunksize=chunksize), + timeout=timeout) + return itertools.chain.from_iterable(results) + def shutdown(self, wait=True): with self._shutdown_lock: self._shutdown_thread = True diff --git a/Lib/concurrent/futures/thread.py b/Lib/concurrent/futures/thread.py index f9beb0f7f7ed..3ae442d98703 100644 --- a/Lib/concurrent/futures/thread.py +++ b/Lib/concurrent/futures/thread.py @@ -10,6 +10,7 @@ import queue import threading import weakref +import os # Workers are created as daemon threads. This is done to allow the interpreter # to exit when there are still idle threads in a ThreadPoolExecutor's thread @@ -80,13 +81,20 @@ def _worker(executor_reference, work_queue): _base.LOGGER.critical('Exception in worker', exc_info=True) class ThreadPoolExecutor(_base.Executor): - def __init__(self, max_workers): + def __init__(self, max_workers=None): """Initializes a new ThreadPoolExecutor instance. Args: max_workers: The maximum number of threads that can be used to execute the given calls. """ + if max_workers is None: + # Use this number because ThreadPoolExecutor is often + # used to overlap I/O instead of CPU work. + max_workers = (os.cpu_count() or 1) * 5 + if max_workers <= 0: + raise ValueError("max_workers must be greater than 0") + self._max_workers = max_workers self._work_queue = queue.Queue() self._threads = set() diff --git a/Lib/configparser.py b/Lib/configparser.py index 794f857c3f6e..3a9fb56dc632 100644 --- a/Lib/configparser.py +++ b/Lib/configparser.py @@ -17,7 +17,8 @@ __init__(defaults=None, dict_type=_default_dict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, - empty_lines_in_values=True): + empty_lines_in_values=True, default_section='DEFAULT', + interpolation=<unset>, converters=<unset>): Create the parser. When `defaults' is given, it is initialized into the dictionary or intrinsic defaults. The keys must be strings, the values must be appropriate for %()s string interpolation. @@ -47,6 +48,25 @@ When `allow_no_value' is True (default: False), options without values are accepted; the value presented for these is None. + When `default_section' is given, the name of the special section is + named accordingly. By default it is called ``"DEFAULT"`` but this can + be customized to point to any other valid section name. Its current + value can be retrieved using the ``parser_instance.default_section`` + attribute and may be modified at runtime. + + When `interpolation` is given, it should be an Interpolation subclass + instance. It will be used as the handler for option value + pre-processing when using getters. RawConfigParser object s don't do + any sort of interpolation, whereas ConfigParser uses an instance of + BasicInterpolation. The library also provides a ``zc.buildbot`` + inspired ExtendedInterpolation implementation. + + When `converters` is given, it should be a dictionary where each key + represents the name of a type converter and each value is a callable + implementing the conversion from string to the desired datatype. Every + converter gets its corresponding get*() method on the parser object and + section proxies. + sections() Return all the configuration section names, sans DEFAULT. @@ -129,9 +149,11 @@ __all__ = ["NoSectionError", "DuplicateOptionError", "DuplicateSectionError", "NoOptionError", "InterpolationError", "InterpolationDepthError", - "InterpolationSyntaxError", "ParsingError", - "MissingSectionHeaderError", + "InterpolationMissingOptionError", "InterpolationSyntaxError", + "ParsingError", "MissingSectionHeaderError", "ConfigParser", "SafeConfigParser", "RawConfigParser", + "Interpolation", "BasicInterpolation", "ExtendedInterpolation", + "LegacyInterpolation", "SectionProxy", "ConverterMapping", "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"] DEFAULTSECT = "DEFAULT" @@ -144,23 +166,6 @@ class Error(Exception): """Base class for ConfigParser exceptions.""" - def _get_message(self): - """Getter for 'message'; needed only to override deprecation in - BaseException. - """ - return self.__message - - def _set_message(self, value): - """Setter for 'message'; needed only to override deprecation in - BaseException. - """ - self.__message = value - - # BaseException.message has been deprecated since Python 2.6. To prevent - # DeprecationWarning from popping up over this pre-existing attribute, use - # a new property that takes lookup precedence. - message = property(_get_message, _set_message) - def __init__(self, msg=''): self.message = msg Exception.__init__(self, msg) @@ -258,12 +263,9 @@ class InterpolationMissingOptionError(InterpolationError): """A string substitution required a setting which was not available.""" def __init__(self, option, section, rawval, reference): - msg = ("Bad value substitution:\n" - "\tsection: [%s]\n" - "\toption : %s\n" - "\tkey : %s\n" - "\trawval : %s\n" - % (section, option, reference, rawval)) + msg = ("Bad value substitution: option {!r} in section {!r} contains " + "an interpolation key {!r} which is not a valid option name. " + "Raw value: {!r}".format(option, section, reference, rawval)) InterpolationError.__init__(self, option, section, msg) self.reference = reference self.args = (option, section, rawval, reference) @@ -281,11 +283,11 @@ class InterpolationDepthError(InterpolationError): """Raised when substitutions are nested too deeply.""" def __init__(self, option, section, rawval): - msg = ("Value interpolation too deeply recursive:\n" - "\tsection: [%s]\n" - "\toption : %s\n" - "\trawval : %s\n" - % (section, option, rawval)) + msg = ("Recursion limit exceeded in value substitution: option {!r} " + "in section {!r} contains an interpolation key which " + "cannot be substituted in {} steps. Raw value: {!r}" + "".format(option, section, MAX_INTERPOLATION_DEPTH, + rawval)) InterpolationError.__init__(self, option, section, msg) self.args = (option, section, rawval) @@ -303,7 +305,7 @@ def __init__(self, source=None, filename=None): raise ValueError("Required argument `source' not given.") elif filename: source = filename - Error.__init__(self, 'Source contains parsing errors: %s' % source) + Error.__init__(self, 'Source contains parsing errors: %r' % source) self.source = source self.errors = [] self.args = (source, ) @@ -339,7 +341,7 @@ class MissingSectionHeaderError(ParsingError): def __init__(self, filename, lineno, line): Error.__init__( self, - 'File contains no section headers.\nfile: %s, line: %d\n%r' % + 'File contains no section headers.\nfile: %r, line: %d\n%r' % (filename, lineno, line)) self.source = filename self.lineno = lineno @@ -401,8 +403,9 @@ def before_set(self, parser, section, option, value): def _interpolate_some(self, parser, option, accum, rest, section, map, depth): + rawval = parser.get(section, option, raw=True, fallback=rest) if depth > MAX_INTERPOLATION_DEPTH: - raise InterpolationDepthError(option, section, rest) + raise InterpolationDepthError(option, section, rawval) while rest: p = rest.find("%") if p < 0: @@ -427,7 +430,7 @@ def _interpolate_some(self, parser, option, accum, rest, section, map, v = map[var] except KeyError: raise InterpolationMissingOptionError( - option, section, rest, var) + option, section, rawval, var) from None if "%" in v: self._interpolate_some(parser, option, accum, v, section, map, depth + 1) @@ -461,8 +464,9 @@ def before_set(self, parser, section, option, value): def _interpolate_some(self, parser, option, accum, rest, section, map, depth): + rawval = parser.get(section, option, raw=True, fallback=rest) if depth > MAX_INTERPOLATION_DEPTH: - raise InterpolationDepthError(option, section, rest) + raise InterpolationDepthError(option, section, rawval) while rest: p = rest.find("$") if p < 0: @@ -499,7 +503,7 @@ def _interpolate_some(self, parser, option, accum, rest, section, map, "More than one ':' found: %r" % (rest,)) except (KeyError, NoSectionError, NoOptionError): raise InterpolationMissingOptionError( - option, section, rest, ":".join(path)) + option, section, rawval, ":".join(path)) from None if "$" in v: self._interpolate_some(parser, opt, accum, v, sect, dict(parser.items(sect, raw=True)), @@ -532,7 +536,7 @@ def before_get(self, parser, section, option, value, vars): value = value % vars except KeyError as e: raise InterpolationMissingOptionError( - option, section, rawval, e.args[0]) + option, section, rawval, e.args[0]) from None else: break if value and "%(" in value: @@ -597,11 +601,12 @@ def __init__(self, defaults=None, dict_type=_default_dict, comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, empty_lines_in_values=True, default_section=DEFAULTSECT, - interpolation=_UNSET): + interpolation=_UNSET, converters=_UNSET): self._dict = dict_type self._sections = self._dict() self._defaults = self._dict() + self._converters = ConverterMapping(self) self._proxies = self._dict() self._proxies[default_section] = SectionProxy(self, default_section) if defaults: @@ -629,6 +634,8 @@ def __init__(self, defaults=None, dict_type=_default_dict, self._interpolation = self._DEFAULT_INTERPOLATION if self._interpolation is None: self._interpolation = Interpolation() + if converters is not _UNSET: + self._converters.update(converters) def defaults(self): return self._defaults @@ -664,7 +671,7 @@ def options(self, section): try: opts = self._sections[section].copy() except KeyError: - raise NoSectionError(section) + raise NoSectionError(section) from None opts.update(self._defaults) return list(opts.keys()) @@ -792,36 +799,31 @@ def get(self, section, option, *, raw=False, vars=None, fallback=_UNSET): def _get(self, section, conv, option, **kwargs): return conv(self.get(section, option, **kwargs)) - def getint(self, section, option, *, raw=False, vars=None, - fallback=_UNSET): + def _get_conv(self, section, option, conv, *, raw=False, vars=None, + fallback=_UNSET, **kwargs): try: - return self._get(section, int, option, raw=raw, vars=vars) + return self._get(section, conv, option, raw=raw, vars=vars, + **kwargs) except (NoSectionError, NoOptionError): if fallback is _UNSET: raise - else: - return fallback + return fallback + + # getint, getfloat and getboolean provided directly for backwards compat + def getint(self, section, option, *, raw=False, vars=None, + fallback=_UNSET, **kwargs): + return self._get_conv(section, option, int, raw=raw, vars=vars, + fallback=fallback, **kwargs) def getfloat(self, section, option, *, raw=False, vars=None, - fallback=_UNSET): - try: - return self._get(section, float, option, raw=raw, vars=vars) - except (NoSectionError, NoOptionError): - if fallback is _UNSET: - raise - else: - return fallback + fallback=_UNSET, **kwargs): + return self._get_conv(section, option, float, raw=raw, vars=vars, + fallback=fallback, **kwargs) def getboolean(self, section, option, *, raw=False, vars=None, - fallback=_UNSET): - try: - return self._get(section, self._convert_to_boolean, option, - raw=raw, vars=vars) - except (NoSectionError, NoOptionError): - if fallback is _UNSET: - raise - else: - return fallback + fallback=_UNSET, **kwargs): + return self._get_conv(section, option, self._convert_to_boolean, + raw=raw, vars=vars, fallback=fallback, **kwargs) def items(self, section=_UNSET, raw=False, vars=None): """Return a list of (name, value) tuples for each option in a section. @@ -893,7 +895,7 @@ def set(self, section, option, value=None): try: sectdict = self._sections[section] except KeyError: - raise NoSectionError(section) + raise NoSectionError(section) from None sectdict[self.optionxform(option)] = value def write(self, fp, space_around_delimiters=True): @@ -934,7 +936,7 @@ def remove_option(self, section, option): try: sectdict = self._sections[section] except KeyError: - raise NoSectionError(section) + raise NoSectionError(section) from None option = self.optionxform(option) existed = option in sectdict if existed: @@ -1171,6 +1173,10 @@ def _validate_value_types(self, *, section="", option="", value=""): if not isinstance(value, str): raise TypeError("option values must be strings") + @property + def converters(self): + return self._converters + class ConfigParser(RawConfigParser): """ConfigParser implementing interpolation.""" @@ -1211,6 +1217,10 @@ def __init__(self, parser, name): """Creates a view on a section of the specified `name` in `parser`.""" self._parser = parser self._name = name + for conv in parser.converters: + key = 'get' + conv + getter = functools.partial(self.get, _impl=getattr(parser, key)) + setattr(self, key, getter) def __repr__(self): return '<Section: {}>'.format(self._name) @@ -1244,22 +1254,6 @@ def _options(self): else: return self._parser.defaults() - def get(self, option, fallback=None, *, raw=False, vars=None): - return self._parser.get(self._name, option, raw=raw, vars=vars, - fallback=fallback) - - def getint(self, option, fallback=None, *, raw=False, vars=None): - return self._parser.getint(self._name, option, raw=raw, vars=vars, - fallback=fallback) - - def getfloat(self, option, fallback=None, *, raw=False, vars=None): - return self._parser.getfloat(self._name, option, raw=raw, vars=vars, - fallback=fallback) - - def getboolean(self, option, fallback=None, *, raw=False, vars=None): - return self._parser.getboolean(self._name, option, raw=raw, vars=vars, - fallback=fallback) - @property def parser(self): # The parser object of the proxy is read-only. @@ -1269,3 +1263,77 @@ def parser(self): def name(self): # The name of the section on a proxy is read-only. return self._name + + def get(self, option, fallback=None, *, raw=False, vars=None, + _impl=None, **kwargs): + """Get an option value. + + Unless `fallback` is provided, `None` will be returned if the option + is not found. + + """ + # If `_impl` is provided, it should be a getter method on the parser + # object that provides the desired type conversion. + if not _impl: + _impl = self._parser.get + return _impl(self._name, option, raw=raw, vars=vars, + fallback=fallback, **kwargs) + + +class ConverterMapping(MutableMapping): + """Enables reuse of get*() methods between the parser and section proxies. + + If a parser class implements a getter directly, the value for the given + key will be ``None``. The presence of the converter name here enables + section proxies to find and use the implementation on the parser class. + """ + + GETTERCRE = re.compile(r"^get(?P<name>.+)$") + + def __init__(self, parser): + self._parser = parser + self._data = {} + for getter in dir(self._parser): + m = self.GETTERCRE.match(getter) + if not m or not callable(getattr(self._parser, getter)): + continue + self._data[m.group('name')] = None # See class docstring. + + def __getitem__(self, key): + return self._data[key] + + def __setitem__(self, key, value): + try: + k = 'get' + key + except TypeError: + raise ValueError('Incompatible key: {} (type: {})' + ''.format(key, type(key))) + if k == 'get': + raise ValueError('Incompatible key: cannot use "" as a name') + self._data[key] = value + func = functools.partial(self._parser._get_conv, conv=value) + func.converter = value + setattr(self._parser, k, func) + for proxy in self._parser.values(): + getter = functools.partial(proxy.get, _impl=func) + setattr(proxy, k, getter) + + def __delitem__(self, key): + try: + k = 'get' + (key or None) + except TypeError: + raise KeyError(key) + del self._data[key] + for inst in itertools.chain((self._parser,), self._parser.values()): + try: + delattr(inst, k) + except AttributeError: + # don't raise since the entry was present in _data, silently + # clean up + continue + + def __iter__(self): + return iter(self._data) + + def __len__(self): + return len(self._data) diff --git a/Lib/contextlib.py b/Lib/contextlib.py index d3219f6c1502..5377987ddfe1 100644 --- a/Lib/contextlib.py +++ b/Lib/contextlib.py @@ -5,7 +5,7 @@ from functools import wraps __all__ = ["contextmanager", "closing", "ContextDecorator", "ExitStack", - "redirect_stdout", "suppress"] + "redirect_stdout", "redirect_stderr", "suppress"] class ContextDecorator(object): @@ -34,7 +34,7 @@ def inner(*args, **kwds): class _GeneratorContextManager(ContextDecorator): """Helper for @contextmanager decorator.""" - def __init__(self, func, *args, **kwds): + def __init__(self, func, args, kwds): self.gen = func(*args, **kwds) self.func, self.args, self.kwds = func, args, kwds # Issue 19330: ensure context manager instances have good docstrings @@ -52,7 +52,7 @@ def _recreate_cm(self): # _GCM instances are one-shot context managers, so the # CM must be recreated each time a decorated function is # called - return self.__class__(self.func, *self.args, **self.kwds) + return self.__class__(self.func, self.args, self.kwds) def __enter__(self): try: @@ -77,10 +77,17 @@ def __exit__(self, type, value, traceback): self.gen.throw(type, value, traceback) raise RuntimeError("generator didn't stop after throw()") except StopIteration as exc: - # Suppress the exception *unless* it's the same exception that + # Suppress StopIteration *unless* it's the same exception that # was passed to throw(). This prevents a StopIteration - # raised inside the "with" statement from being suppressed + # raised inside the "with" statement from being suppressed. return exc is not value + except RuntimeError as exc: + # Likewise, avoid suppressing if a StopIteration exception + # was passed to throw() and later wrapped into a RuntimeError + # (see PEP 479). + if exc.__cause__ is value: + return False + raise except: # only re-raise if it's *not* the exception that was # passed to throw(), because __exit__() must not raise @@ -123,7 +130,7 @@ def some_generator(<arguments>): """ @wraps(func) def helper(*args, **kwds): - return _GeneratorContextManager(func, *args, **kwds) + return _GeneratorContextManager(func, args, kwds) return helper @@ -151,8 +158,27 @@ def __enter__(self): def __exit__(self, *exc_info): self.thing.close() -class redirect_stdout: - """Context manager for temporarily redirecting stdout to another file + +class _RedirectStream: + + _stream = None + + def __init__(self, new_target): + self._new_target = new_target + # We use a list of old targets to make this CM re-entrant + self._old_targets = [] + + def __enter__(self): + self._old_targets.append(getattr(sys, self._stream)) + setattr(sys, self._stream, self._new_target) + return self._new_target + + def __exit__(self, exctype, excinst, exctb): + setattr(sys, self._stream, self._old_targets.pop()) + + +class redirect_stdout(_RedirectStream): + """Context manager for temporarily redirecting stdout to another file. # How to send help() to stderr with redirect_stdout(sys.stderr): @@ -164,18 +190,13 @@ class redirect_stdout: help(pow) """ - def __init__(self, new_target): - self._new_target = new_target - # We use a list of old targets to make this CM re-entrant - self._old_targets = [] + _stream = "stdout" - def __enter__(self): - self._old_targets.append(sys.stdout) - sys.stdout = self._new_target - return self._new_target - def __exit__(self, exctype, excinst, exctb): - sys.stdout = self._old_targets.pop() +class redirect_stderr(_RedirectStream): + """Context manager for temporarily redirecting stderr to another file.""" + + _stream = "stderr" class suppress: @@ -298,11 +319,17 @@ def __exit__(self, *exc_details): # we were actually nesting multiple with statements frame_exc = sys.exc_info()[1] def _fix_exception_context(new_exc, old_exc): + # Context may not be correct, so find the end of the chain while 1: exc_context = new_exc.__context__ - if exc_context in (None, frame_exc): + if exc_context is old_exc: + # Context is already set correctly (see issue 20317) + return + if exc_context is None or exc_context is frame_exc: break new_exc = exc_context + # Change the end of the chain to point to the exception + # we expect it to reference new_exc.__context__ = old_exc # Callbacks are invoked in LIFO order to match the behaviour of diff --git a/Lib/copy.py b/Lib/copy.py index d26bcdbff6ae..3a45fdf49b23 100644 --- a/Lib/copy.py +++ b/Lib/copy.py @@ -94,7 +94,7 @@ def copy(x): else: reductor = getattr(x, "__reduce_ex__", None) if reductor: - rv = reductor(2) + rv = reductor(4) else: reductor = getattr(x, "__reduce__", None) if reductor: @@ -110,7 +110,7 @@ def copy(x): def _copy_immutable(x): return x for t in (type(None), int, float, bool, str, tuple, - frozenset, type, range, + bytes, frozenset, type, range, types.BuiltinFunctionType, type(Ellipsis), types.FunctionType, weakref.ref): d[t] = _copy_immutable @@ -171,7 +171,7 @@ def deepcopy(x, memo=None, _nil=[]): else: reductor = getattr(x, "__reduce_ex__", None) if reductor: - rv = reductor(2) + rv = reductor(4) else: reductor = getattr(x, "__reduce__", None) if reductor: @@ -221,17 +221,15 @@ def _deepcopy_list(x, memo): d[list] = _deepcopy_list def _deepcopy_tuple(x, memo): - y = [] - for a in x: - y.append(deepcopy(a, memo)) + y = [deepcopy(a, memo) for a in x] # We're not going to put the tuple in the memo, but it's still important we # check for it, in case the tuple contains recursive mutable structures. try: return memo[id(x)] except KeyError: pass - for i in range(len(x)): - if x[i] is not y[i]: + for k, j in zip(x, y): + if k is not j: y = tuple(y) break else: diff --git a/Lib/crypt.py b/Lib/crypt.py index 49ab96e1400b..fbc5f4cc355c 100644 --- a/Lib/crypt.py +++ b/Lib/crypt.py @@ -54,9 +54,8 @@ def crypt(word, salt=None): METHOD_SHA512 = _Method('SHA512', '6', 16, 106) methods = [] -for _method in (METHOD_SHA512, METHOD_SHA256, METHOD_MD5): +for _method in (METHOD_SHA512, METHOD_SHA256, METHOD_MD5, METHOD_CRYPT): _result = crypt('', _method) if _result and len(_result) == _method.total_size: methods.append(_method) -methods.append(METHOD_CRYPT) del _result, _method diff --git a/Lib/csv.py b/Lib/csv.py index a56eed88c862..ca40e5e0efc4 100644 --- a/Lib/csv.py +++ b/Lib/csv.py @@ -147,16 +147,13 @@ def _dict_to_list(self, rowdict): if wrong_fields: raise ValueError("dict contains fields not in fieldnames: " + ", ".join([repr(x) for x in wrong_fields])) - return [rowdict.get(key, self.restval) for key in self.fieldnames] + return (rowdict.get(key, self.restval) for key in self.fieldnames) def writerow(self, rowdict): return self.writer.writerow(self._dict_to_list(rowdict)) def writerows(self, rowdicts): - rows = [] - for rowdict in rowdicts: - rows.append(self._dict_to_list(rowdict)) - return self.writer.writerows(rows) + return self.writer.writerows(map(self._dict_to_list, rowdicts)) # Guard Sniffer's type checking against builds that exclude complex() try: @@ -231,20 +228,21 @@ def _guess_quote_and_delimiter(self, data, delimiters): quotes = {} delims = {} spaces = 0 + groupindex = regexp.groupindex for m in matches: - n = regexp.groupindex['quote'] - 1 + n = groupindex['quote'] - 1 key = m[n] if key: quotes[key] = quotes.get(key, 0) + 1 try: - n = regexp.groupindex['delim'] - 1 + n = groupindex['delim'] - 1 key = m[n] except KeyError: continue if key and (delimiters is None or key in delimiters): delims[key] = delims.get(key, 0) + 1 try: - n = regexp.groupindex['space'] - 1 + n = groupindex['space'] - 1 except KeyError: continue if m[n]: diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py index e34c646e2d11..4cb6d0de2710 100644 --- a/Lib/ctypes/__init__.py +++ b/Lib/ctypes/__init__.py @@ -49,7 +49,7 @@ def create_string_buffer(init, size=None): create_string_buffer(anInteger) -> character array create_string_buffer(aString, anInteger) -> character array """ - if isinstance(init, (str, bytes)): + if isinstance(init, bytes): if size is None: size = len(init)+1 buftype = c_char * size @@ -237,14 +237,8 @@ class c_char(_SimpleCData): class c_char_p(_SimpleCData): _type_ = "z" - if _os.name == "nt": - def __repr__(self): - if not windll.kernel32.IsBadStringPtrA(self, -1): - return "%s(%r)" % (self.__class__.__name__, self.value) - return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value) - else: - def __repr__(self): - return "%s(%s)" % (self.__class__.__name__, cast(self, c_void_p).value) + def __repr__(self): + return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value) _check_size(c_char_p, "P") class c_void_p(_SimpleCData): @@ -259,6 +253,8 @@ class c_bool(_SimpleCData): class c_wchar_p(_SimpleCData): _type_ = "Z" + def __repr__(self): + return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value) class c_wchar(_SimpleCData): _type_ = "u" @@ -284,7 +280,7 @@ def create_unicode_buffer(init, size=None): create_unicode_buffer(anInteger) -> character array create_unicode_buffer(aString, anInteger) -> character array """ - if isinstance(init, (str, bytes)): + if isinstance(init, str): if size is None: size = len(init)+1 buftype = c_wchar * size @@ -353,7 +349,7 @@ class _FuncPtr(_CFuncPtr): self._handle = handle def __repr__(self): - return "<%s '%s', handle %x at %x>" % \ + return "<%s '%s', handle %x at %#x>" % \ (self.__class__.__name__, self._name, (self._handle & (_sys.maxsize*2 + 1)), id(self) & (_sys.maxsize*2 + 1)) diff --git a/Lib/ctypes/_endian.py b/Lib/ctypes/_endian.py index dae65fc2152d..37444bd6a7dd 100644 --- a/Lib/ctypes/_endian.py +++ b/Lib/ctypes/_endian.py @@ -45,6 +45,7 @@ def __setattr__(self, attrname, value): class BigEndianStructure(Structure, metaclass=_swapped_meta): """Structure with big endian byte order""" + __slots__ = () _swappedbytes_ = None elif sys.byteorder == "big": @@ -53,6 +54,7 @@ class BigEndianStructure(Structure, metaclass=_swapped_meta): BigEndianStructure = Structure class LittleEndianStructure(Structure, metaclass=_swapped_meta): """Structure with little endian byte order""" + __slots__ = () _swappedbytes_ = None else: diff --git a/Lib/ctypes/macholib/fetch_macholib.bat b/Lib/ctypes/macholib/fetch_macholib.bat index f9e1c0dc96c3..f474d5cd0a26 100644 --- a/Lib/ctypes/macholib/fetch_macholib.bat +++ b/Lib/ctypes/macholib/fetch_macholib.bat @@ -1 +1 @@ -svn export --force http://svn.red-bean.com/bob/macholib/trunk/macholib/ . +svn export --force http://svn.red-bean.com/bob/macholib/trunk/macholib/ . diff --git a/Lib/ctypes/test/__init__.py b/Lib/ctypes/test/__init__.py index 7c72210496e4..26a70b769634 100644 --- a/Lib/ctypes/test/__init__.py +++ b/Lib/ctypes/test/__init__.py @@ -1,208 +1,14 @@ -import os, sys, unittest, getopt, time +import os +import unittest +from test import support -use_resources = [] +# skip tests if _ctypes was not built +ctypes = support.import_module('ctypes') +ctypes_symbols = dir(ctypes) -class ResourceDenied(Exception): - """Test skipped because it requested a disallowed resource. +def need_symbol(name): + return unittest.skipUnless(name in ctypes_symbols, + '{!r} is required'.format(name)) - This is raised when a test calls requires() for a resource that - has not be enabled. Resources are defined by test modules. - """ - -def is_resource_enabled(resource): - """Test whether a resource is enabled. - - If the caller's module is __main__ then automatically return True.""" - if sys._getframe().f_back.f_globals.get("__name__") == "__main__": - return True - result = use_resources is not None and \ - (resource in use_resources or "*" in use_resources) - if not result: - _unavail[resource] = None - return result - -_unavail = {} -def requires(resource, msg=None): - """Raise ResourceDenied if the specified resource is not available. - - If the caller's module is __main__ then automatically return True.""" - # see if the caller's module is __main__ - if so, treat as if - # the resource was set - if sys._getframe().f_back.f_globals.get("__name__") == "__main__": - return - if not is_resource_enabled(resource): - if msg is None: - msg = "Use of the `%s' resource not enabled" % resource - raise ResourceDenied(msg) - -def find_package_modules(package, mask): - import fnmatch - if (package.__loader__ is not None and - hasattr(package.__loader__, '_files')): - path = package.__name__.replace(".", os.path.sep) - mask = os.path.join(path, mask) - for fnm in package.__loader__._files.keys(): - if fnmatch.fnmatchcase(fnm, mask): - yield os.path.splitext(fnm)[0].replace(os.path.sep, ".") - else: - path = package.__path__[0] - for fnm in os.listdir(path): - if fnmatch.fnmatchcase(fnm, mask): - yield "%s.%s" % (package.__name__, os.path.splitext(fnm)[0]) - -def get_tests(package, mask, verbosity, exclude=()): - """Return a list of skipped test modules, and a list of test cases.""" - tests = [] - skipped = [] - for modname in find_package_modules(package, mask): - if modname.split(".")[-1] in exclude: - skipped.append(modname) - if verbosity > 1: - print("Skipped %s: excluded" % modname, file=sys.stderr) - continue - try: - mod = __import__(modname, globals(), locals(), ['*']) - except (ResourceDenied, unittest.SkipTest) as detail: - skipped.append(modname) - if verbosity > 1: - print("Skipped %s: %s" % (modname, detail), file=sys.stderr) - continue - for name in dir(mod): - if name.startswith("_"): - continue - o = getattr(mod, name) - if type(o) is type(unittest.TestCase) and issubclass(o, unittest.TestCase): - tests.append(o) - return skipped, tests - -def usage(): - print(__doc__) - return 1 - -def test_with_refcounts(runner, verbosity, testcase): - """Run testcase several times, tracking reference counts.""" - import gc - import ctypes - ptc = ctypes._pointer_type_cache.copy() - cfc = ctypes._c_functype_cache.copy() - wfc = ctypes._win_functype_cache.copy() - - # when searching for refcount leaks, we have to manually reset any - # caches that ctypes has. - def cleanup(): - ctypes._pointer_type_cache = ptc.copy() - ctypes._c_functype_cache = cfc.copy() - ctypes._win_functype_cache = wfc.copy() - gc.collect() - - test = unittest.makeSuite(testcase) - for i in range(5): - rc = sys.gettotalrefcount() - runner.run(test) - cleanup() - COUNT = 5 - refcounts = [None] * COUNT - for i in range(COUNT): - rc = sys.gettotalrefcount() - runner.run(test) - cleanup() - refcounts[i] = sys.gettotalrefcount() - rc - if filter(None, refcounts): - print("%s leaks:\n\t" % testcase, refcounts) - elif verbosity: - print("%s: ok." % testcase) - -class TestRunner(unittest.TextTestRunner): - def run(self, test, skipped): - "Run the given test case or test suite." - # Same as unittest.TextTestRunner.run, except that it reports - # skipped tests. - result = self._makeResult() - startTime = time.time() - test(result) - stopTime = time.time() - timeTaken = stopTime - startTime - result.printErrors() - self.stream.writeln(result.separator2) - run = result.testsRun - if _unavail: #skipped: - requested = list(_unavail.keys()) - requested.sort() - self.stream.writeln("Ran %d test%s in %.3fs (%s module%s skipped)" % - (run, run != 1 and "s" or "", timeTaken, - len(skipped), - len(skipped) != 1 and "s" or "")) - self.stream.writeln("Unavailable resources: %s" % ", ".join(requested)) - else: - self.stream.writeln("Ran %d test%s in %.3fs" % - (run, run != 1 and "s" or "", timeTaken)) - self.stream.writeln() - if not result.wasSuccessful(): - self.stream.write("FAILED (") - failed, errored = map(len, (result.failures, result.errors)) - if failed: - self.stream.write("failures=%d" % failed) - if errored: - if failed: self.stream.write(", ") - self.stream.write("errors=%d" % errored) - self.stream.writeln(")") - else: - self.stream.writeln("OK") - return result - - -def main(*packages): - try: - opts, args = getopt.getopt(sys.argv[1:], "rqvu:x:") - except getopt.error: - return usage() - - verbosity = 1 - search_leaks = False - exclude = [] - for flag, value in opts: - if flag == "-q": - verbosity -= 1 - elif flag == "-v": - verbosity += 1 - elif flag == "-r": - try: - sys.gettotalrefcount - except AttributeError: - print("-r flag requires Python debug build", file=sys.stderr) - return -1 - search_leaks = True - elif flag == "-u": - use_resources.extend(value.split(",")) - elif flag == "-x": - exclude.extend(value.split(",")) - - mask = "test_*.py" - if args: - mask = args[0] - - for package in packages: - run_tests(package, mask, verbosity, search_leaks, exclude) - - -def run_tests(package, mask, verbosity, search_leaks, exclude): - skipped, testcases = get_tests(package, mask, verbosity, exclude) - runner = TestRunner(verbosity=verbosity) - - suites = [unittest.makeSuite(o) for o in testcases] - suite = unittest.TestSuite(suites) - result = runner.run(suite, skipped) - - if search_leaks: - # hunt for refcount leaks - runner = BasicTestRunner() - for t in testcases: - test_with_refcounts(runner, verbosity, t) - - return bool(result.errors) - -class BasicTestRunner: - def run(self, test): - result = unittest.TestResult() - test(result) - return result +def load_tests(*args): + return support.load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/ctypes/test/__main__.py b/Lib/ctypes/test/__main__.py new file mode 100644 index 000000000000..362a9ec8cff6 --- /dev/null +++ b/Lib/ctypes/test/__main__.py @@ -0,0 +1,4 @@ +from ctypes.test import load_tests +import unittest + +unittest.main() diff --git a/Lib/ctypes/test/runtests.py b/Lib/ctypes/test/runtests.py deleted file mode 100644 index b7a2b264721e..000000000000 --- a/Lib/ctypes/test/runtests.py +++ /dev/null @@ -1,19 +0,0 @@ -"""Usage: runtests.py [-q] [-r] [-v] [-u resources] [mask] - -Run all tests found in this directory, and print a summary of the results. -Command line flags: - -q quiet mode: don't print anything while the tests are running - -r run tests repeatedly, look for refcount leaks - -u<resources> - Add resources to the lits of allowed resources. '*' allows all - resources. - -v verbose mode: print the test currently executed - -x<test1[,test2...]> - Exclude specified tests. - mask mask to select filenames containing testcases, wildcards allowed -""" -import sys -import ctypes.test - -if __name__ == "__main__": - sys.exit(ctypes.test.main(ctypes.test)) diff --git a/Lib/ctypes/test/test_arrays.py b/Lib/ctypes/test/test_arrays.py index 99b97aa7d8a1..8ca77e0f308a 100644 --- a/Lib/ctypes/test/test_arrays.py +++ b/Lib/ctypes/test/test_arrays.py @@ -1,6 +1,8 @@ import unittest from ctypes import * +from ctypes.test import need_symbol + formats = "bBhHiIlLqQfd" formats = c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint, \ @@ -98,20 +100,16 @@ def test_from_address(self): self.assertEqual(sz[1:4:2], b"o") self.assertEqual(sz.value, b"foo") - try: - create_unicode_buffer - except NameError: - pass - else: - def test_from_addressW(self): - p = create_unicode_buffer("foo") - sz = (c_wchar * 3).from_address(addressof(p)) - self.assertEqual(sz[:], "foo") - self.assertEqual(sz[::], "foo") - self.assertEqual(sz[::-1], "oof") - self.assertEqual(sz[::3], "f") - self.assertEqual(sz[1:4:2], "o") - self.assertEqual(sz.value, "foo") + @need_symbol('create_unicode_buffer') + def test_from_addressW(self): + p = create_unicode_buffer("foo") + sz = (c_wchar * 3).from_address(addressof(p)) + self.assertEqual(sz[:], "foo") + self.assertEqual(sz[::], "foo") + self.assertEqual(sz[::-1], "oof") + self.assertEqual(sz[::3], "f") + self.assertEqual(sz[1:4:2], "o") + self.assertEqual(sz.value, "foo") def test_cache(self): # Array types are cached internally in the _ctypes extension, diff --git a/Lib/ctypes/test/test_as_parameter.py b/Lib/ctypes/test/test_as_parameter.py index 43703e3b6ea3..2a3484bec01b 100644 --- a/Lib/ctypes/test/test_as_parameter.py +++ b/Lib/ctypes/test/test_as_parameter.py @@ -1,5 +1,6 @@ import unittest from ctypes import * +from ctypes.test import need_symbol import _ctypes_test dll = CDLL(_ctypes_test.__file__) @@ -17,11 +18,8 @@ class BasicWrapTestCase(unittest.TestCase): def wrap(self, param): return param + @need_symbol('c_wchar') def test_wchar_parm(self): - try: - c_wchar - except NameError: - return f = dll._testfunc_i_bhilfd f.argtypes = [c_byte, c_wchar, c_int, c_long, c_float, c_double] result = f(self.wrap(1), self.wrap("x"), self.wrap(3), self.wrap(4), self.wrap(5.0), self.wrap(6.0)) @@ -196,7 +194,7 @@ class A(object): a = A() a._as_parameter_ = a - with self.assertRaises(RuntimeError): + with self.assertRaises(RecursionError): c_int.from_param(a) diff --git a/Lib/ctypes/test/test_bitfields.py b/Lib/ctypes/test/test_bitfields.py index c89ee345ee8f..b39d82cc0b14 100644 --- a/Lib/ctypes/test/test_bitfields.py +++ b/Lib/ctypes/test/test_bitfields.py @@ -1,4 +1,5 @@ from ctypes import * +from ctypes.test import need_symbol import unittest import os @@ -127,20 +128,18 @@ def test_nonint_types(self): result = self.fail_fields(("a", c_char, 1)) self.assertEqual(result, (TypeError, 'bit fields not allowed for type c_char')) - try: - c_wchar - except NameError: - pass - else: - result = self.fail_fields(("a", c_wchar, 1)) - self.assertEqual(result, (TypeError, 'bit fields not allowed for type c_wchar')) - class Dummy(Structure): _fields_ = [] result = self.fail_fields(("a", Dummy, 1)) self.assertEqual(result, (TypeError, 'bit fields not allowed for type Dummy')) + @need_symbol('c_wchar') + def test_c_wchar(self): + result = self.fail_fields(("a", c_wchar, 1)) + self.assertEqual(result, + (TypeError, 'bit fields not allowed for type c_wchar')) + def test_single_bitfield_size(self): for c_typ in int_types: result = self.fail_fields(("a", c_typ, -1)) @@ -207,7 +206,7 @@ def test_mixed_2(self): class X(Structure): _fields_ = [("a", c_byte, 4), ("b", c_int, 32)] - self.assertEqual(sizeof(X), sizeof(c_int)*2) + self.assertEqual(sizeof(X), alignment(c_int)+sizeof(c_int)) def test_mixed_3(self): class X(Structure): @@ -240,7 +239,7 @@ class Y(Structure): _anonymous_ = ["_"] _fields_ = [("_", X)] - @unittest.skipUnless(hasattr(ctypes, "c_uint32"), "c_int32 is required") + @need_symbol('c_uint32') def test_uint32(self): class X(Structure): _fields_ = [("a", c_uint32, 32)] @@ -250,7 +249,7 @@ class X(Structure): x.a = 0xFDCBA987 self.assertEqual(x.a, 0xFDCBA987) - @unittest.skipUnless(hasattr(ctypes, "c_uint64"), "c_int64 is required") + @need_symbol('c_uint64') def test_uint64(self): class X(Structure): _fields_ = [("a", c_uint64, 64)] @@ -260,5 +259,33 @@ class X(Structure): x.a = 0xFEDCBA9876543211 self.assertEqual(x.a, 0xFEDCBA9876543211) + @need_symbol('c_uint32') + def test_uint32_swap_little_endian(self): + # Issue #23319 + class Little(LittleEndianStructure): + _fields_ = [("a", c_uint32, 24), + ("b", c_uint32, 4), + ("c", c_uint32, 4)] + b = bytearray(4) + x = Little.from_buffer(b) + x.a = 0xabcdef + x.b = 1 + x.c = 2 + self.assertEqual(b, b'\xef\xcd\xab\x21') + + @need_symbol('c_uint32') + def test_uint32_swap_big_endian(self): + # Issue #23319 + class Big(BigEndianStructure): + _fields_ = [("a", c_uint32, 24), + ("b", c_uint32, 4), + ("c", c_uint32, 4)] + b = bytearray(4) + x = Big.from_buffer(b) + x.a = 0xabcdef + x.b = 1 + x.c = 2 + self.assertEqual(b, b'\xab\xcd\xef\x12') + if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_buffers.py b/Lib/ctypes/test/test_buffers.py index 0d12f47afef1..166faaf4e4b8 100644 --- a/Lib/ctypes/test/test_buffers.py +++ b/Lib/ctypes/test/test_buffers.py @@ -1,4 +1,5 @@ from ctypes import * +from ctypes.test import need_symbol import unittest class StringBufferTestCase(unittest.TestCase): @@ -20,43 +21,44 @@ def test_buffer(self): self.assertEqual(b[::2], b"ac") self.assertEqual(b[::5], b"a") + self.assertRaises(TypeError, create_string_buffer, "abc") + def test_buffer_interface(self): self.assertEqual(len(bytearray(create_string_buffer(0))), 0) self.assertEqual(len(bytearray(create_string_buffer(1))), 1) - try: - c_wchar - except NameError: - pass - else: - def test_unicode_buffer(self): - b = create_unicode_buffer(32) - self.assertEqual(len(b), 32) - self.assertEqual(sizeof(b), 32 * sizeof(c_wchar)) - self.assertIs(type(b[0]), str) - - b = create_unicode_buffer("abc") - self.assertEqual(len(b), 4) # trailing nul char - self.assertEqual(sizeof(b), 4 * sizeof(c_wchar)) - self.assertIs(type(b[0]), str) - self.assertEqual(b[0], "a") - self.assertEqual(b[:], "abc\0") - self.assertEqual(b[::], "abc\0") - self.assertEqual(b[::-1], "\0cba") - self.assertEqual(b[::2], "ac") - self.assertEqual(b[::5], "a") - - def test_unicode_conversion(self): - b = create_unicode_buffer("abc") - self.assertEqual(len(b), 4) # trailing nul char - self.assertEqual(sizeof(b), 4 * sizeof(c_wchar)) - self.assertIs(type(b[0]), str) - self.assertEqual(b[0], "a") - self.assertEqual(b[:], "abc\0") - self.assertEqual(b[::], "abc\0") - self.assertEqual(b[::-1], "\0cba") - self.assertEqual(b[::2], "ac") - self.assertEqual(b[::5], "a") + @need_symbol('c_wchar') + def test_unicode_buffer(self): + b = create_unicode_buffer(32) + self.assertEqual(len(b), 32) + self.assertEqual(sizeof(b), 32 * sizeof(c_wchar)) + self.assertIs(type(b[0]), str) + + b = create_unicode_buffer("abc") + self.assertEqual(len(b), 4) # trailing nul char + self.assertEqual(sizeof(b), 4 * sizeof(c_wchar)) + self.assertIs(type(b[0]), str) + self.assertEqual(b[0], "a") + self.assertEqual(b[:], "abc\0") + self.assertEqual(b[::], "abc\0") + self.assertEqual(b[::-1], "\0cba") + self.assertEqual(b[::2], "ac") + self.assertEqual(b[::5], "a") + + self.assertRaises(TypeError, create_unicode_buffer, b"abc") + + @need_symbol('c_wchar') + def test_unicode_conversion(self): + b = create_unicode_buffer("abc") + self.assertEqual(len(b), 4) # trailing nul char + self.assertEqual(sizeof(b), 4 * sizeof(c_wchar)) + self.assertIs(type(b[0]), str) + self.assertEqual(b[0], "a") + self.assertEqual(b[:], "abc\0") + self.assertEqual(b[::], "abc\0") + self.assertEqual(b[::-1], "\0cba") + self.assertEqual(b[::2], "ac") + self.assertEqual(b[::5], "a") if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_bytes.py b/Lib/ctypes/test/test_bytes.py index ee49c456e8ed..20fa05650340 100644 --- a/Lib/ctypes/test/test_bytes.py +++ b/Lib/ctypes/test/test_bytes.py @@ -6,27 +6,40 @@ class BytesTest(unittest.TestCase): def test_c_char(self): x = c_char(b"x") + self.assertRaises(TypeError, c_char, "x") x.value = b"y" + with self.assertRaises(TypeError): + x.value = "y" c_char.from_param(b"x") + self.assertRaises(TypeError, c_char.from_param, "x") (c_char * 3)(b"a", b"b", b"c") + self.assertRaises(TypeError, c_char * 3, "a", "b", "c") def test_c_wchar(self): x = c_wchar("x") + self.assertRaises(TypeError, c_wchar, b"x") x.value = "y" + with self.assertRaises(TypeError): + x.value = b"y" c_wchar.from_param("x") + self.assertRaises(TypeError, c_wchar.from_param, b"x") (c_wchar * 3)("a", "b", "c") + self.assertRaises(TypeError, c_wchar * 3, b"a", b"b", b"c") def test_c_char_p(self): c_char_p(b"foo bar") + self.assertRaises(TypeError, c_char_p, "foo bar") def test_c_wchar_p(self): c_wchar_p("foo bar") + self.assertRaises(TypeError, c_wchar_p, b"foo bar") def test_struct(self): class X(Structure): _fields_ = [("a", c_char * 3)] x = X(b"abc") + self.assertRaises(TypeError, X, "abc") self.assertEqual(x.a, b"abc") self.assertEqual(type(x.a), bytes) @@ -35,16 +48,18 @@ class X(Structure): _fields_ = [("a", c_wchar * 3)] x = X("abc") + self.assertRaises(TypeError, X, b"abc") self.assertEqual(x.a, "abc") self.assertEqual(type(x.a), str) - if sys.platform == "win32": - def test_BSTR(self): - from _ctypes import _SimpleCData - class BSTR(_SimpleCData): - _type_ = "X" + @unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') + def test_BSTR(self): + from _ctypes import _SimpleCData + class BSTR(_SimpleCData): + _type_ = "X" + + BSTR("abc") - BSTR("abc") if __name__ == '__main__': unittest.main() diff --git a/Lib/ctypes/test/test_byteswap.py b/Lib/ctypes/test/test_byteswap.py index 63dde135192d..01c97e83ca7a 100644 --- a/Lib/ctypes/test/test_byteswap.py +++ b/Lib/ctypes/test/test_byteswap.py @@ -14,13 +14,34 @@ def bin(s): # For Structures and Unions, these types are created on demand. class Test(unittest.TestCase): - def X_test(self): + @unittest.skip('test disabled') + def test_X(self): print(sys.byteorder, file=sys.stderr) for i in range(32): bits = BITS() setattr(bits, "i%s" % i, 1) dump(bits) + def test_slots(self): + class BigPoint(BigEndianStructure): + __slots__ = () + _fields_ = [("x", c_int), ("y", c_int)] + + class LowPoint(LittleEndianStructure): + __slots__ = () + _fields_ = [("x", c_int), ("y", c_int)] + + big = BigPoint() + little = LowPoint() + big.x = 4 + big.y = 2 + little.x = 2 + little.y = 4 + with self.assertRaises(AttributeError): + big.z = 42 + with self.assertRaises(AttributeError): + little.z = 24 + def test_endian_short(self): if sys.byteorder == "little": self.assertIs(c_short.__ctype_le__, c_short) diff --git a/Lib/ctypes/test/test_callbacks.py b/Lib/ctypes/test/test_callbacks.py index 5600b437c1f5..3824f7c9fd9e 100644 --- a/Lib/ctypes/test/test_callbacks.py +++ b/Lib/ctypes/test/test_callbacks.py @@ -1,5 +1,6 @@ import unittest from ctypes import * +from ctypes.test import need_symbol import _ctypes_test class Callbacks(unittest.TestCase): @@ -88,9 +89,10 @@ def test_char(self): # disabled: would now (correctly) raise a RuntimeWarning about # a memory leak. A callback function cannot return a non-integral # C type without causing a memory leak. -## def test_char_p(self): -## self.check_type(c_char_p, "abc") -## self.check_type(c_char_p, "def") + @unittest.skip('test disabled') + def test_char_p(self): + self.check_type(c_char_p, "abc") + self.check_type(c_char_p, "def") def test_pyobject(self): o = () @@ -142,13 +144,12 @@ def __del__(self): CFUNCTYPE(None)(lambda x=Nasty(): None) -try: - WINFUNCTYPE -except NameError: - pass -else: - class StdcallCallbacks(Callbacks): +@need_symbol('WINFUNCTYPE') +class StdcallCallbacks(Callbacks): + try: functype = WINFUNCTYPE + except NameError: + pass ################################################################ @@ -178,7 +179,7 @@ def test_issue_8959_a(self): from ctypes.util import find_library libc_path = find_library("c") if not libc_path: - return # cannot test + self.skipTest('could not find libc') libc = CDLL(libc_path) @CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int)) @@ -190,23 +191,19 @@ def cmp_func(a, b): libc.qsort(array, len(array), sizeof(c_int), cmp_func) self.assertEqual(array[:], [1, 5, 7, 33, 99]) - try: - WINFUNCTYPE - except NameError: - pass - else: - def test_issue_8959_b(self): - from ctypes.wintypes import BOOL, HWND, LPARAM - global windowCount - windowCount = 0 + @need_symbol('WINFUNCTYPE') + def test_issue_8959_b(self): + from ctypes.wintypes import BOOL, HWND, LPARAM + global windowCount + windowCount = 0 - @WINFUNCTYPE(BOOL, HWND, LPARAM) - def EnumWindowsCallbackFunc(hwnd, lParam): - global windowCount - windowCount += 1 - return True #Allow windows to keep enumerating + @WINFUNCTYPE(BOOL, HWND, LPARAM) + def EnumWindowsCallbackFunc(hwnd, lParam): + global windowCount + windowCount += 1 + return True #Allow windows to keep enumerating - windll.user32.EnumWindows(EnumWindowsCallbackFunc, 0) + windll.user32.EnumWindows(EnumWindowsCallbackFunc, 0) def test_callback_register_int(self): # Issue #8275: buggy handling of callback args under Win64 diff --git a/Lib/ctypes/test/test_cast.py b/Lib/ctypes/test/test_cast.py index 32496f686365..187d2bde143d 100644 --- a/Lib/ctypes/test/test_cast.py +++ b/Lib/ctypes/test/test_cast.py @@ -1,4 +1,5 @@ from ctypes import * +from ctypes.test import need_symbol import unittest import sys @@ -75,15 +76,11 @@ def test_char_p(self): self.assertEqual(cast(cast(s, c_void_p), c_char_p).value, b"hiho") - try: - c_wchar_p - except NameError: - pass - else: - def test_wchar_p(self): - s = c_wchar_p("hiho") - self.assertEqual(cast(cast(s, c_void_p), c_wchar_p).value, - "hiho") + @need_symbol('c_wchar_p') + def test_wchar_p(self): + s = c_wchar_p("hiho") + self.assertEqual(cast(cast(s, c_void_p), c_wchar_p).value, + "hiho") if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_cfuncs.py b/Lib/ctypes/test/test_cfuncs.py index a080496713ab..ac2240fa197d 100644 --- a/Lib/ctypes/test/test_cfuncs.py +++ b/Lib/ctypes/test/test_cfuncs.py @@ -3,6 +3,7 @@ import unittest from ctypes import * +from ctypes.test import need_symbol import _ctypes_test @@ -193,7 +194,7 @@ def test_void(self): try: WinDLL except NameError: - pass + def stdcall_dll(*_): pass else: class stdcall_dll(WinDLL): def __getattr__(self, name): @@ -203,9 +204,9 @@ def __getattr__(self, name): setattr(self, name, func) return func - class stdcallCFunctions(CFunctions): - _dll = stdcall_dll(_ctypes_test.__file__) - pass +@need_symbol('WinDLL') +class stdcallCFunctions(CFunctions): + _dll = stdcall_dll(_ctypes_test.__file__) if __name__ == '__main__': unittest.main() diff --git a/Lib/ctypes/test/test_checkretval.py b/Lib/ctypes/test/test_checkretval.py index 19bb8135b3b6..e9567dc39125 100644 --- a/Lib/ctypes/test/test_checkretval.py +++ b/Lib/ctypes/test/test_checkretval.py @@ -1,6 +1,7 @@ import unittest from ctypes import * +from ctypes.test import need_symbol class CHECKED(c_int): def _check_retval_(value): @@ -25,15 +26,11 @@ def test_checkretval(self): del dll._testfunc_p_p.restype self.assertEqual(42, dll._testfunc_p_p(42)) - try: - oledll - except NameError: - pass - else: - def test_oledll(self): - self.assertRaises(OSError, - oledll.oleaut32.CreateTypeLib2, - 0, None, None) + @need_symbol('oledll') + def test_oledll(self): + self.assertRaises(OSError, + oledll.oleaut32.CreateTypeLib2, + 0, None, None) if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_errcheck.py b/Lib/ctypes/test/test_errcheck.py deleted file mode 100644 index a4913f920ddc..000000000000 --- a/Lib/ctypes/test/test_errcheck.py +++ /dev/null @@ -1,19 +0,0 @@ -import sys -from ctypes import * - -##class HMODULE(Structure): -## _fields_ = [("value", c_void_p)] - -## def __repr__(self): -## return "<HMODULE %s>" % self.value - -##windll.kernel32.GetModuleHandleA.restype = HMODULE - -##print windll.kernel32.GetModuleHandleA("python23.dll") -##print hex(sys.dllhandle) - -##def nonzero(handle): -## return (GetLastError(), handle) - -##windll.kernel32.GetModuleHandleA.errcheck = nonzero -##print windll.kernel32.GetModuleHandleA("spam") diff --git a/Lib/ctypes/test/test_find.py b/Lib/ctypes/test/test_find.py index c54b69bbc3fb..e6bc19d7dddf 100644 --- a/Lib/ctypes/test/test_find.py +++ b/Lib/ctypes/test/test_find.py @@ -1,82 +1,91 @@ import unittest +import os import sys +import test.support from ctypes import * from ctypes.util import find_library -from ctypes.test import is_resource_enabled - -if sys.platform == "win32": - lib_gl = find_library("OpenGL32") - lib_glu = find_library("Glu32") - lib_gle = None -elif sys.platform == "darwin": - lib_gl = lib_glu = find_library("OpenGL") - lib_gle = None -else: - lib_gl = find_library("GL") - lib_glu = find_library("GLU") - lib_gle = find_library("gle") - -## print, for debugging -if is_resource_enabled("printing"): - if lib_gl or lib_glu or lib_gle: - print("OpenGL libraries:") - for item in (("GL", lib_gl), - ("GLU", lib_glu), - ("gle", lib_gle)): - print("\t", item) - # On some systems, loading the OpenGL libraries needs the RTLD_GLOBAL mode. class Test_OpenGL_libs(unittest.TestCase): - def setUp(self): - self.gl = self.glu = self.gle = None + @classmethod + def setUpClass(cls): + lib_gl = lib_glu = lib_gle = None + if sys.platform == "win32": + lib_gl = find_library("OpenGL32") + lib_glu = find_library("Glu32") + elif sys.platform == "darwin": + lib_gl = lib_glu = find_library("OpenGL") + else: + lib_gl = find_library("GL") + lib_glu = find_library("GLU") + lib_gle = find_library("gle") + + ## print, for debugging + if test.support.verbose: + print("OpenGL libraries:") + for item in (("GL", lib_gl), + ("GLU", lib_glu), + ("gle", lib_gle)): + print("\t", item) + + cls.gl = cls.glu = cls.gle = None if lib_gl: - self.gl = CDLL(lib_gl, mode=RTLD_GLOBAL) + try: + cls.gl = CDLL(lib_gl, mode=RTLD_GLOBAL) + except OSError: + pass if lib_glu: - self.glu = CDLL(lib_glu, RTLD_GLOBAL) + try: + cls.glu = CDLL(lib_glu, RTLD_GLOBAL) + except OSError: + pass if lib_gle: try: - self.gle = CDLL(lib_gle) + cls.gle = CDLL(lib_gle) except OSError: pass - if lib_gl: - def test_gl(self): - if self.gl: - self.gl.glClearIndex - - if lib_glu: - def test_glu(self): - if self.glu: - self.glu.gluBeginCurve + @classmethod + def tearDownClass(cls): + cls.gl = cls.glu = cls.gle = None - if lib_gle: - def test_gle(self): - if self.gle: - self.gle.gleGetJoinStyle + def test_gl(self): + if self.gl is None: + self.skipTest('lib_gl not available') + self.gl.glClearIndex -##if os.name == "posix" and sys.platform != "darwin": + def test_glu(self): + if self.glu is None: + self.skipTest('lib_glu not available') + self.glu.gluBeginCurve -## # On platforms where the default shared library suffix is '.so', -## # at least some libraries can be loaded as attributes of the cdll -## # object, since ctypes now tries loading the lib again -## # with '.so' appended of the first try fails. -## # -## # Won't work for libc, unfortunately. OTOH, it isn't -## # needed for libc since this is already mapped into the current -## # process (?) -## # -## # On MAC OSX, it won't work either, because dlopen() needs a full path, -## # and the default suffix is either none or '.dylib'. + def test_gle(self): + if self.gle is None: + self.skipTest('lib_gle not available') + self.gle.gleGetJoinStyle -## class LoadLibs(unittest.TestCase): -## def test_libm(self): -## import math -## libm = cdll.libm -## sqrt = libm.sqrt -## sqrt.argtypes = (c_double,) -## sqrt.restype = c_double -## self.assertEqual(sqrt(2), math.sqrt(2)) +# On platforms where the default shared library suffix is '.so', +# at least some libraries can be loaded as attributes of the cdll +# object, since ctypes now tries loading the lib again +# with '.so' appended of the first try fails. +# +# Won't work for libc, unfortunately. OTOH, it isn't +# needed for libc since this is already mapped into the current +# process (?) +# +# On MAC OSX, it won't work either, because dlopen() needs a full path, +# and the default suffix is either none or '.dylib'. +@unittest.skip('test disabled') +@unittest.skipUnless(os.name=="posix" and sys.platform != "darwin", + 'test not suitable for this platform') +class LoadLibs(unittest.TestCase): + def test_libm(self): + import math + libm = cdll.libm + sqrt = libm.sqrt + sqrt.argtypes = (c_double,) + sqrt.restype = c_double + self.assertEqual(sqrt(2), math.sqrt(2)) if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_frombuffer.py b/Lib/ctypes/test/test_frombuffer.py index ffb27a6ea3d7..6aa2d1c5917b 100644 --- a/Lib/ctypes/test/test_frombuffer.py +++ b/Lib/ctypes/test/test_frombuffer.py @@ -10,7 +10,7 @@ def __init__(self): self._init_called = True class Test(unittest.TestCase): - def test_fom_buffer(self): + def test_from_buffer(self): a = array.array("i", range(16)) x = (c_int * 16).from_buffer(a) @@ -23,25 +23,37 @@ def test_fom_buffer(self): a[0], a[-1] = 200, -200 self.assertEqual(x[:], a.tolist()) - self.assertIn(a, x._objects.values()) + self.assertRaises(BufferError, a.append, 100) + self.assertRaises(BufferError, a.pop) - self.assertRaises(ValueError, - c_int.from_buffer, a, -1) + del x; del y; gc.collect(); gc.collect(); gc.collect() + a.append(100) + a.pop() + x = (c_int * 16).from_buffer(a) + + self.assertIn(a, [obj.obj if isinstance(obj, memoryview) else obj + for obj in x._objects.values()]) expected = x[:] del a; gc.collect(); gc.collect(); gc.collect() self.assertEqual(x[:], expected) - self.assertRaises(TypeError, - (c_char * 16).from_buffer, "a" * 16) + with self.assertRaises(TypeError): + (c_char * 16).from_buffer(b"a" * 16) + with self.assertRaises(TypeError): + (c_char * 16).from_buffer("a" * 16) - def test_fom_buffer_with_offset(self): + def test_from_buffer_with_offset(self): a = array.array("i", range(16)) x = (c_int * 15).from_buffer(a, sizeof(c_int)) self.assertEqual(x[:], a.tolist()[1:]) - self.assertRaises(ValueError, lambda: (c_int * 16).from_buffer(a, sizeof(c_int))) - self.assertRaises(ValueError, lambda: (c_int * 1).from_buffer(a, 16 * sizeof(c_int))) + with self.assertRaises(ValueError): + c_int.from_buffer(a, -1) + with self.assertRaises(ValueError): + (c_int * 16).from_buffer(a, sizeof(c_int)) + with self.assertRaises(ValueError): + (c_int * 1).from_buffer(a, 16 * sizeof(c_int)) def test_from_buffer_copy(self): a = array.array("i", range(16)) @@ -56,26 +68,30 @@ def test_from_buffer_copy(self): a[0], a[-1] = 200, -200 self.assertEqual(x[:], list(range(16))) - self.assertEqual(x._objects, None) + a.append(100) + self.assertEqual(x[:], list(range(16))) - self.assertRaises(ValueError, - c_int.from_buffer, a, -1) + self.assertEqual(x._objects, None) del a; gc.collect(); gc.collect(); gc.collect() self.assertEqual(x[:], list(range(16))) x = (c_char * 16).from_buffer_copy(b"a" * 16) self.assertEqual(x[:], b"a" * 16) + with self.assertRaises(TypeError): + (c_char * 16).from_buffer_copy("a" * 16) - def test_fom_buffer_copy_with_offset(self): + def test_from_buffer_copy_with_offset(self): a = array.array("i", range(16)) x = (c_int * 15).from_buffer_copy(a, sizeof(c_int)) self.assertEqual(x[:], a.tolist()[1:]) - self.assertRaises(ValueError, - (c_int * 16).from_buffer_copy, a, sizeof(c_int)) - self.assertRaises(ValueError, - (c_int * 1).from_buffer_copy, a, 16 * sizeof(c_int)) + with self.assertRaises(ValueError): + c_int.from_buffer_copy(a, -1) + with self.assertRaises(ValueError): + (c_int * 16).from_buffer_copy(a, sizeof(c_int)) + with self.assertRaises(ValueError): + (c_int * 1).from_buffer_copy(a, 16 * sizeof(c_int)) if __name__ == '__main__': unittest.main() diff --git a/Lib/ctypes/test/test_functions.py b/Lib/ctypes/test/test_functions.py index 07eeb6892461..75628924206b 100644 --- a/Lib/ctypes/test/test_functions.py +++ b/Lib/ctypes/test/test_functions.py @@ -6,6 +6,7 @@ """ from ctypes import * +from ctypes.test import need_symbol import sys, unittest try: @@ -63,22 +64,16 @@ class X(object, Structure): pass + @need_symbol('c_wchar') def test_wchar_parm(self): - try: - c_wchar - except NameError: - return f = dll._testfunc_i_bhilfd f.argtypes = [c_byte, c_wchar, c_int, c_long, c_float, c_double] result = f(1, "x", 3, 4, 5.0, 6.0) self.assertEqual(result, 139) self.assertEqual(type(result), int) + @need_symbol('c_wchar') def test_wchar_result(self): - try: - c_wchar - except NameError: - return f = dll._testfunc_i_bhilfd f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double] f.restype = c_wchar @@ -155,11 +150,8 @@ def test_longdoubleresult(self): self.assertEqual(result, -21) self.assertEqual(type(result), float) + @need_symbol('c_longlong') def test_longlongresult(self): - try: - c_longlong - except NameError: - return f = dll._testfunc_q_bhilfd f.restype = c_longlong f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double] @@ -296,6 +288,7 @@ def callback(value): result = f(-10, cb) self.assertEqual(result, -18) + @need_symbol('c_longlong') def test_longlong_callbacks(self): f = dll._testfunc_callback_q_qf @@ -348,16 +341,16 @@ class S2H(Structure): s2h = dll.ret_2h_func(inp) self.assertEqual((s2h.x, s2h.y), (99*2, 88*3)) - if sys.platform == "win32": - def test_struct_return_2H_stdcall(self): - class S2H(Structure): - _fields_ = [("x", c_short), - ("y", c_short)] + @unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') + def test_struct_return_2H_stdcall(self): + class S2H(Structure): + _fields_ = [("x", c_short), + ("y", c_short)] - windll.s_ret_2h_func.restype = S2H - windll.s_ret_2h_func.argtypes = [S2H] - s2h = windll.s_ret_2h_func(S2H(99, 88)) - self.assertEqual((s2h.x, s2h.y), (99*2, 88*3)) + windll.s_ret_2h_func.restype = S2H + windll.s_ret_2h_func.argtypes = [S2H] + s2h = windll.s_ret_2h_func(S2H(99, 88)) + self.assertEqual((s2h.x, s2h.y), (99*2, 88*3)) def test_struct_return_8H(self): class S8I(Structure): @@ -376,23 +369,24 @@ class S8I(Structure): self.assertEqual((s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h), (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9)) - if sys.platform == "win32": - def test_struct_return_8H_stdcall(self): - class S8I(Structure): - _fields_ = [("a", c_int), - ("b", c_int), - ("c", c_int), - ("d", c_int), - ("e", c_int), - ("f", c_int), - ("g", c_int), - ("h", c_int)] - windll.s_ret_8i_func.restype = S8I - windll.s_ret_8i_func.argtypes = [S8I] - inp = S8I(9, 8, 7, 6, 5, 4, 3, 2) - s8i = windll.s_ret_8i_func(inp) - self.assertEqual((s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h), - (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9)) + @unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') + def test_struct_return_8H_stdcall(self): + class S8I(Structure): + _fields_ = [("a", c_int), + ("b", c_int), + ("c", c_int), + ("d", c_int), + ("e", c_int), + ("f", c_int), + ("g", c_int), + ("h", c_int)] + windll.s_ret_8i_func.restype = S8I + windll.s_ret_8i_func.argtypes = [S8I] + inp = S8I(9, 8, 7, 6, 5, 4, 3, 2) + s8i = windll.s_ret_8i_func(inp) + self.assertEqual( + (s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h), + (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9)) def test_sf1651235(self): # see http://www.python.org/sf/1651235 diff --git a/Lib/ctypes/test/test_integers.py b/Lib/ctypes/test/test_integers.py deleted file mode 100644 index 62e4b08a2b64..000000000000 --- a/Lib/ctypes/test/test_integers.py +++ /dev/null @@ -1,5 +0,0 @@ -# superseded by test_numbers.py -import unittest - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/ctypes/test/test_keeprefs.py b/Lib/ctypes/test/test_keeprefs.py index db8adfb4cac0..94c02573fa19 100644 --- a/Lib/ctypes/test/test_keeprefs.py +++ b/Lib/ctypes/test/test_keeprefs.py @@ -94,7 +94,8 @@ def test_p_cint(self): self.assertEqual(x._objects, {'1': i}) class DeletePointerTestCase(unittest.TestCase): - def X_test(self): + @unittest.skip('test disabled') + def test_X(self): class X(Structure): _fields_ = [("p", POINTER(c_char_p))] x = X() diff --git a/Lib/ctypes/test/test_loading.py b/Lib/ctypes/test/test_loading.py index 414363d8c82f..28468c1cd3d5 100644 --- a/Lib/ctypes/test/test_loading.py +++ b/Lib/ctypes/test/test_loading.py @@ -1,38 +1,46 @@ from ctypes import * -import sys, unittest import os +import sys +import unittest +import test.support from ctypes.util import find_library -from ctypes.test import is_resource_enabled libc_name = None -if os.name == "nt": - libc_name = find_library("c") -elif os.name == "ce": - libc_name = "coredll" -elif sys.platform == "cygwin": - libc_name = "cygwin1.dll" -else: - libc_name = find_library("c") - -if is_resource_enabled("printing"): - print("libc_name is", libc_name) + +def setUpModule(): + global libc_name + if os.name == "nt": + libc_name = find_library("c") + elif os.name == "ce": + libc_name = "coredll" + elif sys.platform == "cygwin": + libc_name = "cygwin1.dll" + else: + libc_name = find_library("c") + + if test.support.verbose: + print("libc_name is", libc_name) class LoaderTest(unittest.TestCase): unknowndll = "xxrandomnamexx" - if libc_name is not None: - def test_load(self): - CDLL(libc_name) - CDLL(os.path.basename(libc_name)) - self.assertRaises(OSError, CDLL, self.unknowndll) + def test_load(self): + if libc_name is None: + self.skipTest('could not find libc') + CDLL(libc_name) + CDLL(os.path.basename(libc_name)) + self.assertRaises(OSError, CDLL, self.unknowndll) - if libc_name is not None and os.path.basename(libc_name) == "libc.so.6": - def test_load_version(self): - cdll.LoadLibrary("libc.so.6") - # linux uses version, libc 9 should not exist - self.assertRaises(OSError, cdll.LoadLibrary, "libc.so.9") - self.assertRaises(OSError, cdll.LoadLibrary, self.unknowndll) + def test_load_version(self): + if libc_name is None: + self.skipTest('could not find libc') + if os.path.basename(libc_name) != 'libc.so.6': + self.skipTest('wrong libc path for test') + cdll.LoadLibrary("libc.so.6") + # linux uses version, libc 9 should not exist + self.assertRaises(OSError, cdll.LoadLibrary, "libc.so.9") + self.assertRaises(OSError, cdll.LoadLibrary, self.unknowndll) def test_find(self): for name in ("c", "m"): @@ -41,66 +49,73 @@ def test_find(self): cdll.LoadLibrary(lib) CDLL(lib) - if os.name in ("nt", "ce"): - def test_load_library(self): - self.assertIsNotNone(libc_name) - if is_resource_enabled("printing"): - print(find_library("kernel32")) - print(find_library("user32")) - - if os.name == "nt": - windll.kernel32.GetModuleHandleW - windll["kernel32"].GetModuleHandleW - windll.LoadLibrary("kernel32").GetModuleHandleW - WinDLL("kernel32").GetModuleHandleW - elif os.name == "ce": - windll.coredll.GetModuleHandleW - windll["coredll"].GetModuleHandleW - windll.LoadLibrary("coredll").GetModuleHandleW - WinDLL("coredll").GetModuleHandleW - - def test_load_ordinal_functions(self): - import _ctypes_test - dll = WinDLL(_ctypes_test.__file__) - # We load the same function both via ordinal and name - func_ord = dll[2] - func_name = dll.GetString - # addressof gets the address where the function pointer is stored - a_ord = addressof(func_ord) - a_name = addressof(func_name) - f_ord_addr = c_void_p.from_address(a_ord).value - f_name_addr = c_void_p.from_address(a_name).value - self.assertEqual(hex(f_ord_addr), hex(f_name_addr)) - - self.assertRaises(AttributeError, dll.__getitem__, 1234) + @unittest.skipUnless(os.name in ("nt", "ce"), + 'test specific to Windows (NT/CE)') + def test_load_library(self): + # CRT is no longer directly loadable. See issue23606 for the + # discussion about alternative approaches. + #self.assertIsNotNone(libc_name) + if test.support.verbose: + print(find_library("kernel32")) + print(find_library("user32")) - if os.name == "nt": - def test_1703286_A(self): - from _ctypes import LoadLibrary, FreeLibrary - # On winXP 64-bit, advapi32 loads at an address that does - # NOT fit into a 32-bit integer. FreeLibrary must be able - # to accept this address. - - # These are tests for http://www.python.org/sf/1703286 - handle = LoadLibrary("advapi32") - FreeLibrary(handle) - - def test_1703286_B(self): - # Since on winXP 64-bit advapi32 loads like described - # above, the (arbitrarily selected) CloseEventLog function - # also has a high address. 'call_function' should accept - # addresses so large. - from _ctypes import call_function - advapi32 = windll.advapi32 - # Calling CloseEventLog with a NULL argument should fail, - # but the call should not segfault or so. - self.assertEqual(0, advapi32.CloseEventLog(None)) - windll.kernel32.GetProcAddress.argtypes = c_void_p, c_char_p - windll.kernel32.GetProcAddress.restype = c_void_p - proc = windll.kernel32.GetProcAddress(advapi32._handle, b"CloseEventLog") - self.assertTrue(proc) - # This is the real test: call the function via 'call_function' - self.assertEqual(0, call_function(proc, (None,))) + if os.name == "nt": + windll.kernel32.GetModuleHandleW + windll["kernel32"].GetModuleHandleW + windll.LoadLibrary("kernel32").GetModuleHandleW + WinDLL("kernel32").GetModuleHandleW + elif os.name == "ce": + windll.coredll.GetModuleHandleW + windll["coredll"].GetModuleHandleW + windll.LoadLibrary("coredll").GetModuleHandleW + WinDLL("coredll").GetModuleHandleW + + @unittest.skipUnless(os.name in ("nt", "ce"), + 'test specific to Windows (NT/CE)') + def test_load_ordinal_functions(self): + import _ctypes_test + dll = WinDLL(_ctypes_test.__file__) + # We load the same function both via ordinal and name + func_ord = dll[2] + func_name = dll.GetString + # addressof gets the address where the function pointer is stored + a_ord = addressof(func_ord) + a_name = addressof(func_name) + f_ord_addr = c_void_p.from_address(a_ord).value + f_name_addr = c_void_p.from_address(a_name).value + self.assertEqual(hex(f_ord_addr), hex(f_name_addr)) + + self.assertRaises(AttributeError, dll.__getitem__, 1234) + + @unittest.skipUnless(os.name == "nt", 'Windows-specific test') + def test_1703286_A(self): + from _ctypes import LoadLibrary, FreeLibrary + # On winXP 64-bit, advapi32 loads at an address that does + # NOT fit into a 32-bit integer. FreeLibrary must be able + # to accept this address. + + # These are tests for http://www.python.org/sf/1703286 + handle = LoadLibrary("advapi32") + FreeLibrary(handle) + + @unittest.skipUnless(os.name == "nt", 'Windows-specific test') + def test_1703286_B(self): + # Since on winXP 64-bit advapi32 loads like described + # above, the (arbitrarily selected) CloseEventLog function + # also has a high address. 'call_function' should accept + # addresses so large. + from _ctypes import call_function + advapi32 = windll.advapi32 + # Calling CloseEventLog with a NULL argument should fail, + # but the call should not segfault or so. + self.assertEqual(0, advapi32.CloseEventLog(None)) + windll.kernel32.GetProcAddress.argtypes = c_void_p, c_char_p + windll.kernel32.GetProcAddress.restype = c_void_p + proc = windll.kernel32.GetProcAddress(advapi32._handle, + b"CloseEventLog") + self.assertTrue(proc) + # This is the real test: call the function via 'call_function' + self.assertEqual(0, call_function(proc, (None,))) if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_macholib.py b/Lib/ctypes/test/test_macholib.py index fd2683764c79..6b3526951acf 100644 --- a/Lib/ctypes/test/test_macholib.py +++ b/Lib/ctypes/test/test_macholib.py @@ -43,18 +43,21 @@ def find_lib(name): raise ValueError("%s not found" % (name,)) class MachOTest(unittest.TestCase): - if sys.platform == "darwin": - def test_find(self): + @unittest.skipUnless(sys.platform == "darwin", 'OSX-specific test') + def test_find(self): - self.assertEqual(find_lib('pthread'), - '/usr/lib/libSystem.B.dylib') + self.assertEqual(find_lib('pthread'), + '/usr/lib/libSystem.B.dylib') - result = find_lib('z') - self.assertTrue(result.startswith('/usr/lib/libz.1')) - self.assertTrue(result.endswith('.dylib')) + result = find_lib('z') + # Issue #21093: dyld default search path includes $HOME/lib and + # /usr/local/lib before /usr/lib, which caused test failures if + # a local copy of libz exists in one of them. Now ignore the head + # of the path. + self.assertRegex(result, r".*/lib/libz\..*.*\.dylib") - self.assertEqual(find_lib('IOKit'), - '/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit') + self.assertEqual(find_lib('IOKit'), + '/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit') if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_memfunctions.py b/Lib/ctypes/test/test_memfunctions.py index aec4aaadac11..e784b9a70684 100644 --- a/Lib/ctypes/test/test_memfunctions.py +++ b/Lib/ctypes/test/test_memfunctions.py @@ -2,17 +2,19 @@ from test import support import unittest from ctypes import * +from ctypes.test import need_symbol class MemFunctionsTest(unittest.TestCase): -## def test_overflow(self): -## # string_at and wstring_at must use the Python calling -## # convention (which acquires the GIL and checks the Python -## # error flag). Provoke an error and catch it; see also issue -## # #3554: <http://bugs.python.org/issue3554> -## self.assertRaises((OverflowError, MemoryError, SystemError), -## lambda: wstring_at(u"foo", sys.maxint - 1)) -## self.assertRaises((OverflowError, MemoryError, SystemError), -## lambda: string_at("foo", sys.maxint - 1)) + @unittest.skip('test disabled') + def test_overflow(self): + # string_at and wstring_at must use the Python calling + # convention (which acquires the GIL and checks the Python + # error flag). Provoke an error and catch it; see also issue + # #3554: <http://bugs.python.org/issue3554> + self.assertRaises((OverflowError, MemoryError, SystemError), + lambda: wstring_at(u"foo", sys.maxint - 1)) + self.assertRaises((OverflowError, MemoryError, SystemError), + lambda: string_at("foo", sys.maxint - 1)) def test_memmove(self): # large buffers apparently increase the chance that the memory @@ -61,21 +63,17 @@ def test_string_at(self): self.assertEqual(string_at(b"foo bar", 7), b"foo bar") self.assertEqual(string_at(b"foo bar", 3), b"foo") - try: - create_unicode_buffer - except NameError: - pass - else: - def test_wstring_at(self): - p = create_unicode_buffer("Hello, World") - a = create_unicode_buffer(1000000) - result = memmove(a, p, len(p) * sizeof(c_wchar)) - self.assertEqual(a.value, "Hello, World") + @need_symbol('create_unicode_buffer') + def test_wstring_at(self): + p = create_unicode_buffer("Hello, World") + a = create_unicode_buffer(1000000) + result = memmove(a, p, len(p) * sizeof(c_wchar)) + self.assertEqual(a.value, "Hello, World") - self.assertEqual(wstring_at(a), "Hello, World") - self.assertEqual(wstring_at(a, 5), "Hello") - self.assertEqual(wstring_at(a, 16), "Hello, World\0\0\0\0") - self.assertEqual(wstring_at(a, 0), "") + self.assertEqual(wstring_at(a), "Hello, World") + self.assertEqual(wstring_at(a, 5), "Hello") + self.assertEqual(wstring_at(a, 16), "Hello, World\0\0\0\0") + self.assertEqual(wstring_at(a, 0), "") if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_numbers.py b/Lib/ctypes/test/test_numbers.py index 3b7194f31c23..2afca2662f42 100644 --- a/Lib/ctypes/test/test_numbers.py +++ b/Lib/ctypes/test/test_numbers.py @@ -82,12 +82,13 @@ def test_typeerror(self): self.assertRaises(TypeError, t, "") self.assertRaises(TypeError, t, None) -## def test_valid_ranges(self): -## # invalid values of the correct type -## # raise ValueError (not OverflowError) -## for t, (l, h) in zip(unsigned_types, unsigned_ranges): -## self.assertRaises(ValueError, t, l-1) -## self.assertRaises(ValueError, t, h+1) + @unittest.skip('test disabled') + def test_valid_ranges(self): + # invalid values of the correct type + # raise ValueError (not OverflowError) + for t, (l, h) in zip(unsigned_types, unsigned_ranges): + self.assertRaises(ValueError, t, l-1) + self.assertRaises(ValueError, t, h+1) def test_from_param(self): # the from_param class method attribute always @@ -200,16 +201,17 @@ def test_char_from_address(self): self.assertEqual(v.value, b'?') # array does not support c_bool / 't' - # def test_bool_from_address(self): - # from ctypes import c_bool - # from array import array - # a = array(c_bool._type_, [True]) - # v = t.from_address(a.buffer_info()[0]) - # self.assertEqual(v.value, a[0]) - # self.assertEqual(type(v) is t) - # a[0] = False - # self.assertEqual(v.value, a[0]) - # self.assertEqual(type(v) is t) + @unittest.skip('test disabled') + def test_bool_from_address(self): + from ctypes import c_bool + from array import array + a = array(c_bool._type_, [True]) + v = t.from_address(a.buffer_info()[0]) + self.assertEqual(v.value, a[0]) + self.assertEqual(type(v) is t) + a[0] = False + self.assertEqual(v.value, a[0]) + self.assertEqual(type(v) is t) def test_init(self): # c_int() can be initialized from Python's int, and c_int. @@ -227,8 +229,9 @@ def test_float_overflow(self): if (hasattr(t, "__ctype_le__")): self.assertRaises(OverflowError, t.__ctype_le__, big_int) -## def test_perf(self): -## check_perf() + @unittest.skip('test disabled') + def test_perf(self): + check_perf() from ctypes import _SimpleCData class c_int_S(_SimpleCData): diff --git a/Lib/ctypes/test/test_objects.py b/Lib/ctypes/test/test_objects.py index f075c2089396..ef7b20b000d4 100644 --- a/Lib/ctypes/test/test_objects.py +++ b/Lib/ctypes/test/test_objects.py @@ -59,12 +59,9 @@ import ctypes.test.test_objects class TestCase(unittest.TestCase): - if sys.hexversion > 0x02040000: - # Python 2.3 has no ELLIPSIS flag, so we don't test with this - # version: - def test(self): - doctest.testmod(ctypes.test.test_objects) + def test(self): + failures, tests = doctest.testmod(ctypes.test.test_objects) + self.assertFalse(failures, 'doctests failed, see output above') if __name__ == '__main__': - if sys.hexversion > 0x02040000: - doctest.testmod(ctypes.test.test_objects) + doctest.testmod(ctypes.test.test_objects) diff --git a/Lib/ctypes/test/test_parameters.py b/Lib/ctypes/test/test_parameters.py index 12b5bd5fba1f..e56bccf999be 100644 --- a/Lib/ctypes/test/test_parameters.py +++ b/Lib/ctypes/test/test_parameters.py @@ -1,4 +1,5 @@ import unittest, sys +from ctypes.test import need_symbol class SimpleTypesTestCase(unittest.TestCase): @@ -35,10 +36,9 @@ def from_param(cls, value): self.assertEqual(CVOIDP.from_param("abc"), "abcabc") self.assertEqual(CCHARP.from_param("abc"), "abcabcabcabc") - try: - from ctypes import c_wchar_p - except ImportError: - return + @need_symbol('c_wchar_p') + def test_subclasses_c_wchar_p(self): + from ctypes import c_wchar_p class CWCHARP(c_wchar_p): def from_param(cls, value): @@ -66,13 +66,9 @@ def test_cstrings(self): a = c_char_p(b"123") self.assertIs(c_char_p.from_param(a), a) + @need_symbol('c_wchar_p') def test_cw_strings(self): - from ctypes import byref - try: - from ctypes import c_wchar_p - except ImportError: -## print "(No c_wchar_p)" - return + from ctypes import byref, c_wchar_p c_wchar_p.from_param("123") @@ -139,9 +135,6 @@ def test_array_pointers(self): self.assertRaises(TypeError, LPINT.from_param, c_long*3) self.assertRaises(TypeError, LPINT.from_param, c_uint*3) -## def test_performance(self): -## check_perf() - def test_noctypes_argtype(self): import _ctypes_test from ctypes import CDLL, c_void_p, ArgumentError diff --git a/Lib/ctypes/test/test_pep3118.py b/Lib/ctypes/test/test_pep3118.py index ad13b016e762..32f802c86158 100644 --- a/Lib/ctypes/test/test_pep3118.py +++ b/Lib/ctypes/test/test_pep3118.py @@ -96,6 +96,9 @@ class EmptyStruct(Structure): class aUnion(Union): _fields_ = [("a", c_int)] +class StructWithArrays(Structure): + _fields_ = [("x", c_long * 3 * 2), ("y", Point * 4)] + class Incomplete(Structure): pass @@ -145,10 +148,10 @@ class Complete(Structure): ## arrays and pointers - (c_double * 4, "(4)<d", (4,), c_double), - (c_float * 4 * 3 * 2, "(2,3,4)<f", (2,3,4), c_float), - (POINTER(c_short) * 2, "(2)&<h", (2,), POINTER(c_short)), - (POINTER(c_short) * 2 * 3, "(3,2)&<h", (3,2,), POINTER(c_short)), + (c_double * 4, "<d", (4,), c_double), + (c_float * 4 * 3 * 2, "<f", (2,3,4), c_float), + (POINTER(c_short) * 2, "&<h", (2,), POINTER(c_short)), + (POINTER(c_short) * 2 * 3, "&<h", (3,2,), POINTER(c_short)), (POINTER(c_short * 2), "&(2)<h", (), POINTER(c_short)), ## structures and unions @@ -160,6 +163,9 @@ class Complete(Structure): (EmptyStruct, "T{}", (), EmptyStruct), # the pep does't support unions (aUnion, "B", (), aUnion), + # structure with sub-arrays + (StructWithArrays, "T{(2,3)<l:x:(4)T{<l:x:<l:y:}:y:}", (), StructWithArrays), + (StructWithArrays * 3, "T{(2,3)<l:x:(4)T{<l:x:<l:y:}:y:}", (3,), StructWithArrays), ## pointer to incomplete structure (Incomplete, "B", (), Incomplete), diff --git a/Lib/ctypes/test/test_pickling.py b/Lib/ctypes/test/test_pickling.py index 8c9122269447..c4a79b977931 100644 --- a/Lib/ctypes/test/test_pickling.py +++ b/Lib/ctypes/test/test_pickling.py @@ -14,9 +14,9 @@ def __init__(self, *args, **kw): class Y(X): _fields_ = [("str", c_char_p)] -class PickleTest(unittest.TestCase): +class PickleTest: def dumps(self, item): - return pickle.dumps(item) + return pickle.dumps(item, self.proto) def loads(self, item): return pickle.loads(item) @@ -67,17 +67,15 @@ def test_unpickable(self): self.assertRaises(ValueError, lambda: self.dumps(item)) def test_wchar(self): - pickle.dumps(c_char(b"x")) + self.dumps(c_char(b"x")) # Issue 5049 - pickle.dumps(c_wchar("x")) + self.dumps(c_wchar("x")) -class PickleTest_1(PickleTest): - def dumps(self, item): - return pickle.dumps(item, 1) - -class PickleTest_2(PickleTest): - def dumps(self, item): - return pickle.dumps(item, 2) +for proto in range(pickle.HIGHEST_PROTOCOL + 1): + name = 'PickleTest_%s' % proto + globals()[name] = type(name, + (PickleTest, unittest.TestCase), + {'proto': proto}) if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_pointers.py b/Lib/ctypes/test/test_pointers.py index f8ef0ab830c4..40738f78d9bb 100644 --- a/Lib/ctypes/test/test_pointers.py +++ b/Lib/ctypes/test/test_pointers.py @@ -22,7 +22,10 @@ class A(POINTER(c_ulong)): def test_pass_pointers(self): dll = CDLL(_ctypes_test.__file__) func = dll._testfunc_p_p - func.restype = c_long + if sizeof(c_longlong) == sizeof(c_void_p): + func.restype = c_longlong + else: + func.restype = c_long i = c_int(12345678) ## func.argtypes = (POINTER(c_int),) @@ -188,5 +191,13 @@ def test_pointers_bool(self): mth = WINFUNCTYPE(None)(42, "name", (), None) self.assertEqual(bool(mth), True) + def test_pointer_type_name(self): + LargeNamedType = type('T' * 2 ** 25, (Structure,), {}) + self.assertTrue(POINTER(LargeNamedType)) + + def test_pointer_type_str_name(self): + large_string = 'T' * 2 ** 25 + self.assertTrue(POINTER(large_string)) + if __name__ == '__main__': unittest.main() diff --git a/Lib/ctypes/test/test_prototypes.py b/Lib/ctypes/test/test_prototypes.py index 6ef1b1bcaff8..cd0c649de3e3 100644 --- a/Lib/ctypes/test/test_prototypes.py +++ b/Lib/ctypes/test/test_prototypes.py @@ -1,4 +1,5 @@ from ctypes import * +from ctypes.test import need_symbol import unittest # IMPORTANT INFO: @@ -68,7 +69,10 @@ def test_paramflags(self): def test_int_pointer_arg(self): func = testdll._testfunc_p_p - func.restype = c_long + if sizeof(c_longlong) == sizeof(c_void_p): + func.restype = c_longlong + else: + func.restype = c_long self.assertEqual(0, func(0)) ci = c_int(0) @@ -135,13 +139,14 @@ def test_c_void_p_arg(self): func(pointer(c_int())) func((c_int * 3)()) - try: - func.restype = c_wchar_p - except NameError: - pass - else: - self.assertEqual(None, func(c_wchar_p(None))) - self.assertEqual("123", func(c_wchar_p("123"))) + @need_symbol('c_wchar_p') + def test_c_void_p_arg_with_c_wchar_p(self): + func = testdll._testfunc_p_p + func.restype = c_wchar_p + func.argtypes = c_void_p, + + self.assertEqual(None, func(c_wchar_p(None))) + self.assertEqual("123", func(c_wchar_p("123"))) def test_instance(self): func = testdll._testfunc_p_p @@ -156,51 +161,47 @@ class X: func.argtypes = None self.assertEqual(None, func(X())) -try: - c_wchar -except NameError: - pass -else: - class WCharPointersTestCase(unittest.TestCase): - - def setUp(self): - func = testdll._testfunc_p_p - func.restype = c_int - func.argtypes = None - - - def test_POINTER_c_wchar_arg(self): - func = testdll._testfunc_p_p - func.restype = c_wchar_p - func.argtypes = POINTER(c_wchar), - - self.assertEqual(None, func(None)) - self.assertEqual("123", func("123")) - self.assertEqual(None, func(c_wchar_p(None))) - self.assertEqual("123", func(c_wchar_p("123"))) - - self.assertEqual("123", func(c_wbuffer("123"))) - ca = c_wchar("a") - self.assertEqual("a", func(pointer(ca))[0]) - self.assertEqual("a", func(byref(ca))[0]) - - def test_c_wchar_p_arg(self): - func = testdll._testfunc_p_p - func.restype = c_wchar_p - func.argtypes = c_wchar_p, - - c_wchar_p.from_param("123") - - self.assertEqual(None, func(None)) - self.assertEqual("123", func("123")) - self.assertEqual(None, func(c_wchar_p(None))) - self.assertEqual("123", func(c_wchar_p("123"))) - - # XXX Currently, these raise TypeErrors, although they shouldn't: - self.assertEqual("123", func(c_wbuffer("123"))) - ca = c_wchar("a") - self.assertEqual("a", func(pointer(ca))[0]) - self.assertEqual("a", func(byref(ca))[0]) +@need_symbol('c_wchar') +class WCharPointersTestCase(unittest.TestCase): + + def setUp(self): + func = testdll._testfunc_p_p + func.restype = c_int + func.argtypes = None + + + def test_POINTER_c_wchar_arg(self): + func = testdll._testfunc_p_p + func.restype = c_wchar_p + func.argtypes = POINTER(c_wchar), + + self.assertEqual(None, func(None)) + self.assertEqual("123", func("123")) + self.assertEqual(None, func(c_wchar_p(None))) + self.assertEqual("123", func(c_wchar_p("123"))) + + self.assertEqual("123", func(c_wbuffer("123"))) + ca = c_wchar("a") + self.assertEqual("a", func(pointer(ca))[0]) + self.assertEqual("a", func(byref(ca))[0]) + + def test_c_wchar_p_arg(self): + func = testdll._testfunc_p_p + func.restype = c_wchar_p + func.argtypes = c_wchar_p, + + c_wchar_p.from_param("123") + + self.assertEqual(None, func(None)) + self.assertEqual("123", func("123")) + self.assertEqual(None, func(c_wchar_p(None))) + self.assertEqual("123", func(c_wchar_p("123"))) + + # XXX Currently, these raise TypeErrors, although they shouldn't: + self.assertEqual("123", func(c_wbuffer("123"))) + ca = c_wchar("a") + self.assertEqual("a", func(pointer(ca))[0]) + self.assertEqual("a", func(byref(ca))[0]) class ArrayTest(unittest.TestCase): def test(self): diff --git a/Lib/ctypes/test/test_python_api.py b/Lib/ctypes/test/test_python_api.py index 5eb882af5eb1..9c137469c3b5 100644 --- a/Lib/ctypes/test/test_python_api.py +++ b/Lib/ctypes/test/test_python_api.py @@ -1,7 +1,6 @@ from ctypes import * import unittest, sys from test import support -from ctypes.test import is_resource_enabled ################################################################ # This section should be moved into ctypes\__init__.py, when it's ready. @@ -39,24 +38,21 @@ def test_PyString_FromString(self): del pyob self.assertEqual(grc(s), refcnt) - if is_resource_enabled("refcount"): - # This test is unreliable, because it is possible that code in - # unittest changes the refcount of the '42' integer. So, it - # is disabled by default. - def test_PyLong_Long(self): - ref42 = grc(42) - pythonapi.PyLong_FromLong.restype = py_object - self.assertEqual(pythonapi.PyLong_FromLong(42), 42) + @support.refcount_test + def test_PyLong_Long(self): + ref42 = grc(42) + pythonapi.PyLong_FromLong.restype = py_object + self.assertEqual(pythonapi.PyLong_FromLong(42), 42) - self.assertEqual(grc(42), ref42) + self.assertEqual(grc(42), ref42) - pythonapi.PyLong_AsLong.argtypes = (py_object,) - pythonapi.PyLong_AsLong.restype = c_long + pythonapi.PyLong_AsLong.argtypes = (py_object,) + pythonapi.PyLong_AsLong.restype = c_long - res = pythonapi.PyLong_AsLong(42) - self.assertEqual(grc(res), ref42 + 1) - del res - self.assertEqual(grc(42), ref42) + res = pythonapi.PyLong_AsLong(42) + self.assertEqual(grc(res), ref42 + 1) + del res + self.assertEqual(grc(42), ref42) @support.refcount_test def test_PyObj_FromPtr(self): diff --git a/Lib/ctypes/test/test_random_things.py b/Lib/ctypes/test/test_random_things.py index 515acf509a66..4555ecd8b8a6 100644 --- a/Lib/ctypes/test/test_random_things.py +++ b/Lib/ctypes/test/test_random_things.py @@ -5,23 +5,22 @@ def callback_func(arg): 42 / arg raise ValueError(arg) -if sys.platform == "win32": +@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') +class call_function_TestCase(unittest.TestCase): + # _ctypes.call_function is deprecated and private, but used by + # Gary Bishp's readline module. If we have it, we must test it as well. - class call_function_TestCase(unittest.TestCase): - # _ctypes.call_function is deprecated and private, but used by - # Gary Bishp's readline module. If we have it, we must test it as well. + def test(self): + from _ctypes import call_function + windll.kernel32.LoadLibraryA.restype = c_void_p + windll.kernel32.GetProcAddress.argtypes = c_void_p, c_char_p + windll.kernel32.GetProcAddress.restype = c_void_p - def test(self): - from _ctypes import call_function - windll.kernel32.LoadLibraryA.restype = c_void_p - windll.kernel32.GetProcAddress.argtypes = c_void_p, c_char_p - windll.kernel32.GetProcAddress.restype = c_void_p + hdll = windll.kernel32.LoadLibraryA(b"kernel32") + funcaddr = windll.kernel32.GetProcAddress(hdll, b"GetModuleHandleA") - hdll = windll.kernel32.LoadLibraryA(b"kernel32") - funcaddr = windll.kernel32.GetProcAddress(hdll, b"GetModuleHandleA") - - self.assertEqual(call_function(funcaddr, (None,)), - windll.kernel32.GetModuleHandleA(None)) + self.assertEqual(call_function(funcaddr, (None,)), + windll.kernel32.GetModuleHandleA(None)) class CallbackTracbackTestCase(unittest.TestCase): # When an exception is raised in a ctypes callback function, the C diff --git a/Lib/ctypes/test/test_slicing.py b/Lib/ctypes/test/test_slicing.py index 82fee96823f9..240dc0cdda24 100644 --- a/Lib/ctypes/test/test_slicing.py +++ b/Lib/ctypes/test/test_slicing.py @@ -1,5 +1,6 @@ import unittest from ctypes import * +from ctypes.test import need_symbol import _ctypes_test @@ -125,44 +126,40 @@ def test_char_array(self): self.assertEqual(p[2:5:-3], s[2:5:-3]) - try: - c_wchar - except NameError: - pass - else: - def test_wchar_ptr(self): - s = "abcdefghijklmnopqrstuvwxyz\0" - - dll = CDLL(_ctypes_test.__file__) - dll.my_wcsdup.restype = POINTER(c_wchar) - dll.my_wcsdup.argtypes = POINTER(c_wchar), - dll.my_free.restype = None - res = dll.my_wcsdup(s) - self.assertEqual(res[:len(s)], s) - self.assertEqual(res[:len(s):], s) - self.assertEqual(res[len(s)-1:-1:-1], s[::-1]) - self.assertEqual(res[len(s)-1:5:-7], s[:5:-7]) - - import operator - self.assertRaises(TypeError, operator.setitem, - res, slice(0, 5), "abcde") - dll.my_free(res) - - if sizeof(c_wchar) == sizeof(c_short): - dll.my_wcsdup.restype = POINTER(c_short) - elif sizeof(c_wchar) == sizeof(c_int): - dll.my_wcsdup.restype = POINTER(c_int) - elif sizeof(c_wchar) == sizeof(c_long): - dll.my_wcsdup.restype = POINTER(c_long) - else: - return - res = dll.my_wcsdup(s) - tmpl = list(range(ord("a"), ord("z")+1)) - self.assertEqual(res[:len(s)-1], tmpl) - self.assertEqual(res[:len(s)-1:], tmpl) - self.assertEqual(res[len(s)-2:-1:-1], tmpl[::-1]) - self.assertEqual(res[len(s)-2:5:-7], tmpl[:5:-7]) - dll.my_free(res) + @need_symbol('c_wchar') + def test_wchar_ptr(self): + s = "abcdefghijklmnopqrstuvwxyz\0" + + dll = CDLL(_ctypes_test.__file__) + dll.my_wcsdup.restype = POINTER(c_wchar) + dll.my_wcsdup.argtypes = POINTER(c_wchar), + dll.my_free.restype = None + res = dll.my_wcsdup(s) + self.assertEqual(res[:len(s)], s) + self.assertEqual(res[:len(s):], s) + self.assertEqual(res[len(s)-1:-1:-1], s[::-1]) + self.assertEqual(res[len(s)-1:5:-7], s[:5:-7]) + + import operator + self.assertRaises(TypeError, operator.setitem, + res, slice(0, 5), "abcde") + dll.my_free(res) + + if sizeof(c_wchar) == sizeof(c_short): + dll.my_wcsdup.restype = POINTER(c_short) + elif sizeof(c_wchar) == sizeof(c_int): + dll.my_wcsdup.restype = POINTER(c_int) + elif sizeof(c_wchar) == sizeof(c_long): + dll.my_wcsdup.restype = POINTER(c_long) + else: + self.skipTest('Pointers to c_wchar are not supported') + res = dll.my_wcsdup(s) + tmpl = list(range(ord("a"), ord("z")+1)) + self.assertEqual(res[:len(s)-1], tmpl) + self.assertEqual(res[:len(s)-1:], tmpl) + self.assertEqual(res[len(s)-2:-1:-1], tmpl[::-1]) + self.assertEqual(res[len(s)-2:5:-7], tmpl[:5:-7]) + dll.my_free(res) ################################################################ diff --git a/Lib/ctypes/test/test_strings.py b/Lib/ctypes/test/test_strings.py index 9dc2a291a7df..c7bfbda73d54 100644 --- a/Lib/ctypes/test/test_strings.py +++ b/Lib/ctypes/test/test_strings.py @@ -1,5 +1,6 @@ import unittest from ctypes import * +from ctypes.test import need_symbol class StringArrayTestCase(unittest.TestCase): def test(self): @@ -53,36 +54,33 @@ def test_param_2(self): ## print BUF.from_param(c_char_p("python")) ## print BUF.from_param(BUF(*"pyth")) -try: - c_wchar -except NameError: - pass -else: - class WStringArrayTestCase(unittest.TestCase): - def test(self): - BUF = c_wchar * 4 +@need_symbol('c_wchar') +class WStringArrayTestCase(unittest.TestCase): + def test(self): + BUF = c_wchar * 4 - buf = BUF("a", "b", "c") - self.assertEqual(buf.value, "abc") + buf = BUF("a", "b", "c") + self.assertEqual(buf.value, "abc") - buf.value = "ABCD" - self.assertEqual(buf.value, "ABCD") + buf.value = "ABCD" + self.assertEqual(buf.value, "ABCD") - buf.value = "x" - self.assertEqual(buf.value, "x") + buf.value = "x" + self.assertEqual(buf.value, "x") - buf[1] = "Z" - self.assertEqual(buf.value, "xZCD") + buf[1] = "Z" + self.assertEqual(buf.value, "xZCD") - @unittest.skipIf(sizeof(c_wchar) < 4, - "sizeof(wchar_t) is smaller than 4 bytes") - def test_nonbmp(self): - u = chr(0x10ffff) - w = c_wchar(u) - self.assertEqual(w.value, u) + @unittest.skipIf(sizeof(c_wchar) < 4, + "sizeof(wchar_t) is smaller than 4 bytes") + def test_nonbmp(self): + u = chr(0x10ffff) + w = c_wchar(u) + self.assertEqual(w.value, u) class StringTestCase(unittest.TestCase): - def XX_test_basic_strings(self): + @unittest.skip('test disabled') + def test_basic_strings(self): cs = c_string("abcdef") # Cannot call len on a c_string any longer @@ -108,7 +106,8 @@ def XX_test_basic_strings(self): self.assertRaises(TypeError, c_string, "123") - def XX_test_sized_strings(self): + @unittest.skip('test disabled') + def test_sized_strings(self): # New in releases later than 0.4.0: self.assertRaises(TypeError, c_string, None) @@ -125,7 +124,8 @@ def XX_test_sized_strings(self): self.assertEqual(c_string(2).raw[-1], "\000") self.assertEqual(len(c_string(2).raw), 2) - def XX_test_initialized_strings(self): + @unittest.skip('test disabled') + def test_initialized_strings(self): self.assertEqual(c_string("ab", 4).raw[:2], "ab") self.assertEqual(c_string("ab", 4).raw[:2:], "ab") @@ -134,7 +134,8 @@ def XX_test_initialized_strings(self): self.assertEqual(c_string("ab", 4).raw[-1], "\000") self.assertEqual(c_string("ab", 2).raw, "a\000") - def XX_test_toolong(self): + @unittest.skip('test disabled') + def test_toolong(self): cs = c_string("abcdef") # Much too long string: self.assertRaises(ValueError, setattr, cs, "value", "123456789012345") @@ -142,54 +143,53 @@ def XX_test_toolong(self): # One char too long values: self.assertRaises(ValueError, setattr, cs, "value", "1234567") -## def test_perf(self): -## check_perf() + @unittest.skip('test disabled') + def test_perf(self): + check_perf() -try: - c_wchar -except NameError: - pass -else: - class WStringTestCase(unittest.TestCase): - def test_wchar(self): - c_wchar("x") - repr(byref(c_wchar("x"))) - c_wchar("x") +@need_symbol('c_wchar') +class WStringTestCase(unittest.TestCase): + def test_wchar(self): + c_wchar("x") + repr(byref(c_wchar("x"))) + c_wchar("x") - def X_test_basic_wstrings(self): - cs = c_wstring("abcdef") + @unittest.skip('test disabled') + def test_basic_wstrings(self): + cs = c_wstring("abcdef") - # XXX This behaviour is about to change: - # len returns the size of the internal buffer in bytes. - # This includes the terminating NUL character. - self.assertEqual(sizeof(cs), 14) + # XXX This behaviour is about to change: + # len returns the size of the internal buffer in bytes. + # This includes the terminating NUL character. + self.assertEqual(sizeof(cs), 14) - # The value property is the string up to the first terminating NUL. - self.assertEqual(cs.value, "abcdef") - self.assertEqual(c_wstring("abc\000def").value, "abc") + # The value property is the string up to the first terminating NUL. + self.assertEqual(cs.value, "abcdef") + self.assertEqual(c_wstring("abc\000def").value, "abc") - self.assertEqual(c_wstring("abc\000def").value, "abc") + self.assertEqual(c_wstring("abc\000def").value, "abc") - # The raw property is the total buffer contents: - self.assertEqual(cs.raw, "abcdef\000") - self.assertEqual(c_wstring("abc\000def").raw, "abc\000def\000") + # The raw property is the total buffer contents: + self.assertEqual(cs.raw, "abcdef\000") + self.assertEqual(c_wstring("abc\000def").raw, "abc\000def\000") - # We can change the value: - cs.value = "ab" - self.assertEqual(cs.value, "ab") - self.assertEqual(cs.raw, "ab\000\000\000\000\000") + # We can change the value: + cs.value = "ab" + self.assertEqual(cs.value, "ab") + self.assertEqual(cs.raw, "ab\000\000\000\000\000") - self.assertRaises(TypeError, c_wstring, "123") - self.assertRaises(ValueError, c_wstring, 0) + self.assertRaises(TypeError, c_wstring, "123") + self.assertRaises(ValueError, c_wstring, 0) - def X_test_toolong(self): - cs = c_wstring("abcdef") - # Much too long string: - self.assertRaises(ValueError, setattr, cs, "value", "123456789012345") + @unittest.skip('test disabled') + def test_toolong(self): + cs = c_wstring("abcdef") + # Much too long string: + self.assertRaises(ValueError, setattr, cs, "value", "123456789012345") - # One char too long values: - self.assertRaises(ValueError, setattr, cs, "value", "1234567") + # One char too long values: + self.assertRaises(ValueError, setattr, cs, "value", "1234567") def run_test(rep, msg, func, arg): diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py index 61b9fe7c1813..84d456c3cc38 100644 --- a/Lib/ctypes/test/test_structures.py +++ b/Lib/ctypes/test/test_structures.py @@ -1,5 +1,6 @@ import unittest from ctypes import * +from ctypes.test import need_symbol from struct import calcsize import _testcapi @@ -83,7 +84,7 @@ class X(Structure): class Y(Structure): _fields_ = [("x", c_char * 3), ("y", c_int)] - self.assertEqual(alignment(Y), calcsize("i")) + self.assertEqual(alignment(Y), alignment(c_int)) self.assertEqual(sizeof(Y), calcsize("3si")) class SI(Structure): @@ -175,23 +176,23 @@ class X(Structure): self.assertEqual(sizeof(X), 10) self.assertEqual(X.b.offset, 2) + import struct + longlong_size = struct.calcsize("q") + longlong_align = struct.calcsize("bq") - longlong_size + class X(Structure): _fields_ = [("a", c_byte), ("b", c_longlong)] _pack_ = 4 - self.assertEqual(sizeof(X), 12) - self.assertEqual(X.b.offset, 4) - - import struct - longlong_size = struct.calcsize("q") - longlong_align = struct.calcsize("bq") - longlong_size + self.assertEqual(sizeof(X), min(4, longlong_align) + longlong_size) + self.assertEqual(X.b.offset, min(4, longlong_align)) class X(Structure): _fields_ = [("a", c_byte), ("b", c_longlong)] _pack_ = 8 - self.assertEqual(sizeof(X), longlong_align + longlong_size) + self.assertEqual(sizeof(X), min(8, longlong_align) + longlong_size) self.assertEqual(X.b.offset, min(8, longlong_align)) @@ -291,12 +292,8 @@ class Person(Structure): self.assertEqual(p.phone.number, b"5678") self.assertEqual(p.age, 5) + @need_symbol('c_wchar') def test_structures_with_wchar(self): - try: - c_wchar - except NameError: - return # no unicode - class PersonW(Structure): _fields_ = [("name", c_wchar * 12), ("age", c_int)] @@ -325,7 +322,7 @@ class Person(Structure): self.assertEqual(cls, RuntimeError) self.assertEqual(msg, "(Phone) <class 'TypeError'>: " - "expected string, int found") + "expected bytes, int found") cls, msg = self.get_except(Person, b"Someone", (b"a", b"b", b"c")) self.assertEqual(cls, RuntimeError) @@ -354,14 +351,14 @@ def get_except(self, func, *args): except Exception as detail: return detail.__class__, str(detail) - -## def test_subclass_creation(self): -## meta = type(Structure) -## # same as 'class X(Structure): pass' -## # fails, since we need either a _fields_ or a _abstract_ attribute -## cls, msg = self.get_except(meta, "X", (Structure,), {}) -## self.assertEqual((cls, msg), -## (AttributeError, "class must define a '_fields_' attribute")) + @unittest.skip('test disabled') + def test_subclass_creation(self): + meta = type(Structure) + # same as 'class X(Structure): pass' + # fails, since we need either a _fields_ or a _abstract_ attribute + cls, msg = self.get_except(meta, "X", (Structure,), {}) + self.assertEqual((cls, msg), + (AttributeError, "class must define a '_fields_' attribute")) def test_abstract_class(self): class X(Structure): diff --git a/Lib/ctypes/test/test_unicode.py b/Lib/ctypes/test/test_unicode.py index c3b2d4877121..c200af7b6506 100644 --- a/Lib/ctypes/test/test_unicode.py +++ b/Lib/ctypes/test/test_unicode.py @@ -1,58 +1,55 @@ import unittest import ctypes - -try: - ctypes.c_wchar -except AttributeError: - pass -else: - import _ctypes_test - - class UnicodeTestCase(unittest.TestCase): - def test_wcslen(self): - dll = ctypes.CDLL(_ctypes_test.__file__) - wcslen = dll.my_wcslen - wcslen.argtypes = [ctypes.c_wchar_p] - - self.assertEqual(wcslen("abc"), 3) - self.assertEqual(wcslen("ab\u2070"), 3) - self.assertRaises(ctypes.ArgumentError, wcslen, b"ab\xe4") - - def test_buffers(self): - buf = ctypes.create_unicode_buffer("abc") - self.assertEqual(len(buf), 3+1) - - buf = ctypes.create_unicode_buffer("ab\xe4\xf6\xfc") - self.assertEqual(buf[:], "ab\xe4\xf6\xfc\0") - self.assertEqual(buf[::], "ab\xe4\xf6\xfc\0") - self.assertEqual(buf[::-1], '\x00\xfc\xf6\xe4ba') - self.assertEqual(buf[::2], 'a\xe4\xfc') - self.assertEqual(buf[6:5:-1], "") - - func = ctypes.CDLL(_ctypes_test.__file__)._testfunc_p_p - - class StringTestCase(UnicodeTestCase): - def setUp(self): - func.argtypes = [ctypes.c_char_p] - func.restype = ctypes.c_char_p - - def tearDown(self): - func.argtypes = None - func.restype = ctypes.c_int - - def test_func(self): - self.assertEqual(func(b"abc\xe4"), b"abc\xe4") - - def test_buffers(self): - buf = ctypes.create_string_buffer(b"abc") - self.assertEqual(len(buf), 3+1) - - buf = ctypes.create_string_buffer(b"ab\xe4\xf6\xfc") - self.assertEqual(buf[:], b"ab\xe4\xf6\xfc\0") - self.assertEqual(buf[::], b"ab\xe4\xf6\xfc\0") - self.assertEqual(buf[::-1], b'\x00\xfc\xf6\xe4ba') - self.assertEqual(buf[::2], b'a\xe4\xfc') - self.assertEqual(buf[6:5:-1], b"") +from ctypes.test import need_symbol + +import _ctypes_test + +@need_symbol('c_wchar') +class UnicodeTestCase(unittest.TestCase): + def test_wcslen(self): + dll = ctypes.CDLL(_ctypes_test.__file__) + wcslen = dll.my_wcslen + wcslen.argtypes = [ctypes.c_wchar_p] + + self.assertEqual(wcslen("abc"), 3) + self.assertEqual(wcslen("ab\u2070"), 3) + self.assertRaises(ctypes.ArgumentError, wcslen, b"ab\xe4") + + def test_buffers(self): + buf = ctypes.create_unicode_buffer("abc") + self.assertEqual(len(buf), 3+1) + + buf = ctypes.create_unicode_buffer("ab\xe4\xf6\xfc") + self.assertEqual(buf[:], "ab\xe4\xf6\xfc\0") + self.assertEqual(buf[::], "ab\xe4\xf6\xfc\0") + self.assertEqual(buf[::-1], '\x00\xfc\xf6\xe4ba') + self.assertEqual(buf[::2], 'a\xe4\xfc') + self.assertEqual(buf[6:5:-1], "") + +func = ctypes.CDLL(_ctypes_test.__file__)._testfunc_p_p + +class StringTestCase(UnicodeTestCase): + def setUp(self): + func.argtypes = [ctypes.c_char_p] + func.restype = ctypes.c_char_p + + def tearDown(self): + func.argtypes = None + func.restype = ctypes.c_int + + def test_func(self): + self.assertEqual(func(b"abc\xe4"), b"abc\xe4") + + def test_buffers(self): + buf = ctypes.create_string_buffer(b"abc") + self.assertEqual(len(buf), 3+1) + + buf = ctypes.create_string_buffer(b"ab\xe4\xf6\xfc") + self.assertEqual(buf[:], b"ab\xe4\xf6\xfc\0") + self.assertEqual(buf[::], b"ab\xe4\xf6\xfc\0") + self.assertEqual(buf[::-1], b'\x00\xfc\xf6\xe4ba') + self.assertEqual(buf[::2], b'a\xe4\xfc') + self.assertEqual(buf[6:5:-1], b"") if __name__ == '__main__': diff --git a/Lib/ctypes/test/test_values.py b/Lib/ctypes/test/test_values.py index e46410208f79..9551e7ae9f67 100644 --- a/Lib/ctypes/test/test_values.py +++ b/Lib/ctypes/test/test_values.py @@ -3,6 +3,7 @@ """ import unittest +import sys from ctypes import * import _ctypes_test @@ -27,62 +28,73 @@ def test_undefined(self): ctdll = CDLL(_ctypes_test.__file__) self.assertRaises(ValueError, c_int.in_dll, ctdll, "Undefined_Symbol") - class Win_ValuesTestCase(unittest.TestCase): - """This test only works when python itself is a dll/shared library""" - - def test_optimizeflag(self): - # This test accesses the Py_OptimizeFlag intger, which is - # exported by the Python dll. - - # It's value is set depending on the -O and -OO flags: - # if not given, it is 0 and __debug__ is 1. - # If -O is given, the flag is 1, for -OO it is 2. - # docstrings are also removed in the latter case. - opt = c_int.in_dll(pydll, "Py_OptimizeFlag").value - if __debug__: - self.assertEqual(opt, 0) - elif ValuesTestCase.__doc__ is not None: - self.assertEqual(opt, 1) - else: - self.assertEqual(opt, 2) - - def test_frozentable(self): - # Python exports a PyImport_FrozenModules symbol. This is a - # pointer to an array of struct _frozen entries. The end of the - # array is marked by an entry containing a NULL name and zero - # size. - - # In standard Python, this table contains a __hello__ - # module, and a __phello__ package containing a spam - # module. - class struct_frozen(Structure): - _fields_ = [("name", c_char_p), - ("code", POINTER(c_ubyte)), - ("size", c_int)] - FrozenTable = POINTER(struct_frozen) - - ft = FrozenTable.in_dll(pydll, "PyImport_FrozenModules") - # ft is a pointer to the struct_frozen entries: - items = [] - for entry in ft: - # This is dangerous. We *can* iterate over a pointer, but - # the loop will not terminate (maybe with an access - # violation;-) because the pointer instance has no size. - if entry.name is None: - break - items.append((entry.name, entry.size)) - import sys - if sys.version_info[:2] >= (2, 3): - expected = [("__hello__", 104), ("__phello__", -104), ("__phello__.spam", 104)] - else: - expected = [("__hello__", 100), ("__phello__", -100), ("__phello__.spam", 100)] - self.assertEqual(items, expected) - - from ctypes import _pointer_type_cache - del _pointer_type_cache[struct_frozen] - - def test_undefined(self): - self.assertRaises(ValueError, c_int.in_dll, pydll, "Undefined_Symbol") +@unittest.skipUnless(sys.platform == 'win32', 'Windows-specific test') +class Win_ValuesTestCase(unittest.TestCase): + """This test only works when python itself is a dll/shared library""" + + def test_optimizeflag(self): + # This test accesses the Py_OptimizeFlag integer, which is + # exported by the Python dll and should match the sys.flags value + + opt = c_int.in_dll(pythonapi, "Py_OptimizeFlag").value + self.assertEqual(opt, sys.flags.optimize) + + def test_frozentable(self): + # Python exports a PyImport_FrozenModules symbol. This is a + # pointer to an array of struct _frozen entries. The end of the + # array is marked by an entry containing a NULL name and zero + # size. + + # In standard Python, this table contains a __hello__ + # module, and a __phello__ package containing a spam + # module. + class struct_frozen(Structure): + _fields_ = [("name", c_char_p), + ("code", POINTER(c_ubyte)), + ("size", c_int)] + FrozenTable = POINTER(struct_frozen) + + ft = FrozenTable.in_dll(pythonapi, "PyImport_FrozenModules") + # ft is a pointer to the struct_frozen entries: + items = [] + # _frozen_importlib changes size whenever importlib._bootstrap + # changes, so it gets a special case. We should make sure it's + # found, but don't worry about its size too much. The same + # applies to _frozen_importlib_external. + bootstrap_seen = [] + bootstrap_expected = [ + b'_frozen_importlib', + b'_frozen_importlib_external', + ] + for entry in ft: + # This is dangerous. We *can* iterate over a pointer, but + # the loop will not terminate (maybe with an access + # violation;-) because the pointer instance has no size. + if entry.name is None: + break + + if entry.name in bootstrap_expected: + bootstrap_seen.append(entry.name) + self.assertTrue(entry.size, + "{} was reported as having no size".format(entry.name)) + continue + items.append((entry.name, entry.size)) + + expected = [(b"__hello__", 161), + (b"__phello__", -161), + (b"__phello__.spam", 161), + ] + self.assertEqual(items, expected) + + self.assertEqual(sorted(bootstrap_seen), bootstrap_expected, + "frozen bootstrap modules did not match PyImport_FrozenModules") + + from ctypes import _pointer_type_cache + del _pointer_type_cache[struct_frozen] + + def test_undefined(self): + self.assertRaises(ValueError, c_int.in_dll, pythonapi, + "Undefined_Symbol") if __name__ == '__main__': unittest.main() diff --git a/Lib/ctypes/test/test_win32.py b/Lib/ctypes/test/test_win32.py index 91ad3149a775..5867b0592924 100644 --- a/Lib/ctypes/test/test_win32.py +++ b/Lib/ctypes/test/test_win32.py @@ -1,99 +1,103 @@ # Windows specific tests from ctypes import * -from ctypes.test import is_resource_enabled import unittest, sys from test import support import _ctypes_test -if sys.platform == "win32" and sizeof(c_void_p) == sizeof(c_int): - # Only windows 32-bit has different calling conventions. - - class WindowsTestCase(unittest.TestCase): - def test_callconv_1(self): - # Testing stdcall function - - IsWindow = windll.user32.IsWindow - # ValueError: Procedure probably called with not enough arguments (4 bytes missing) - self.assertRaises(ValueError, IsWindow) - - # This one should succeed... - self.assertEqual(0, IsWindow(0)) - - # ValueError: Procedure probably called with too many arguments (8 bytes in excess) - self.assertRaises(ValueError, IsWindow, 0, 0, 0) - - def test_callconv_2(self): - # Calling stdcall function as cdecl - - IsWindow = cdll.user32.IsWindow - - # ValueError: Procedure called with not enough arguments (4 bytes missing) - # or wrong calling convention - self.assertRaises(ValueError, IsWindow, None) - -if sys.platform == "win32": - class FunctionCallTestCase(unittest.TestCase): - - if is_resource_enabled("SEH"): - def test_SEH(self): - # Call functions with invalid arguments, and make sure - # that access violations are trapped and raise an - # exception. - self.assertRaises(OSError, windll.kernel32.GetModuleHandleA, 32) - - def test_noargs(self): - # This is a special case on win32 x64 - windll.user32.GetDesktopWindow() - - class TestWintypes(unittest.TestCase): - def test_HWND(self): - from ctypes import wintypes - self.assertEqual(sizeof(wintypes.HWND), sizeof(c_void_p)) - - def test_PARAM(self): - from ctypes import wintypes - self.assertEqual(sizeof(wintypes.WPARAM), - sizeof(c_void_p)) - self.assertEqual(sizeof(wintypes.LPARAM), - sizeof(c_void_p)) - - def test_COMError(self): - from _ctypes import COMError - if support.HAVE_DOCSTRINGS: - self.assertEqual(COMError.__doc__, - "Raised when a COM method call failed.") - - ex = COMError(-1, "text", ("details",)) - self.assertEqual(ex.hresult, -1) - self.assertEqual(ex.text, "text") - self.assertEqual(ex.details, ("details",)) - - class TestWinError(unittest.TestCase): - def test_winerror(self): - # see Issue 16169 - import errno - ERROR_INVALID_PARAMETER = 87 - msg = FormatError(ERROR_INVALID_PARAMETER).strip() - args = (errno.EINVAL, msg, None, ERROR_INVALID_PARAMETER) - - e = WinError(ERROR_INVALID_PARAMETER) - self.assertEqual(e.args, args) - self.assertEqual(e.errno, errno.EINVAL) - self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER) - - windll.kernel32.SetLastError(ERROR_INVALID_PARAMETER) - try: - raise WinError() - except OSError as exc: - e = exc - self.assertEqual(e.args, args) - self.assertEqual(e.errno, errno.EINVAL) - self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER) +# Only windows 32-bit has different calling conventions. +@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') +@unittest.skipUnless(sizeof(c_void_p) == sizeof(c_int), + "sizeof c_void_p and c_int differ") +class WindowsTestCase(unittest.TestCase): + def test_callconv_1(self): + # Testing stdcall function + + IsWindow = windll.user32.IsWindow + # ValueError: Procedure probably called with not enough arguments + # (4 bytes missing) + self.assertRaises(ValueError, IsWindow) + + # This one should succeed... + self.assertEqual(0, IsWindow(0)) + + # ValueError: Procedure probably called with too many arguments + # (8 bytes in excess) + self.assertRaises(ValueError, IsWindow, 0, 0, 0) + + def test_callconv_2(self): + # Calling stdcall function as cdecl + + IsWindow = cdll.user32.IsWindow + + # ValueError: Procedure called with not enough arguments + # (4 bytes missing) or wrong calling convention + self.assertRaises(ValueError, IsWindow, None) + +@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') +class FunctionCallTestCase(unittest.TestCase): + @unittest.skipUnless('MSC' in sys.version, "SEH only supported by MSC") + @unittest.skipIf(sys.executable.lower().endswith('_d.exe'), + "SEH not enabled in debug builds") + def test_SEH(self): + # Call functions with invalid arguments, and make sure + # that access violations are trapped and raise an + # exception. + self.assertRaises(OSError, windll.kernel32.GetModuleHandleA, 32) + + def test_noargs(self): + # This is a special case on win32 x64 + windll.user32.GetDesktopWindow() + +@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') +class TestWintypes(unittest.TestCase): + def test_HWND(self): + from ctypes import wintypes + self.assertEqual(sizeof(wintypes.HWND), sizeof(c_void_p)) + + def test_PARAM(self): + from ctypes import wintypes + self.assertEqual(sizeof(wintypes.WPARAM), + sizeof(c_void_p)) + self.assertEqual(sizeof(wintypes.LPARAM), + sizeof(c_void_p)) + + def test_COMError(self): + from _ctypes import COMError + if support.HAVE_DOCSTRINGS: + self.assertEqual(COMError.__doc__, + "Raised when a COM method call failed.") + + ex = COMError(-1, "text", ("details",)) + self.assertEqual(ex.hresult, -1) + self.assertEqual(ex.text, "text") + self.assertEqual(ex.details, ("details",)) + +@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') +class TestWinError(unittest.TestCase): + def test_winerror(self): + # see Issue 16169 + import errno + ERROR_INVALID_PARAMETER = 87 + msg = FormatError(ERROR_INVALID_PARAMETER).strip() + args = (errno.EINVAL, msg, None, ERROR_INVALID_PARAMETER) + + e = WinError(ERROR_INVALID_PARAMETER) + self.assertEqual(e.args, args) + self.assertEqual(e.errno, errno.EINVAL) + self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER) + + windll.kernel32.SetLastError(ERROR_INVALID_PARAMETER) + try: + raise WinError() + except OSError as exc: + e = exc + self.assertEqual(e.args, args) + self.assertEqual(e.errno, errno.EINVAL) + self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER) class Structures(unittest.TestCase): - def test_struct_by_value(self): class POINT(Structure): _fields_ = [("x", c_long), @@ -107,9 +111,29 @@ class RECT(Structure): dll = CDLL(_ctypes_test.__file__) - pt = POINT(10, 10) - rect = RECT(0, 0, 20, 20) - self.assertEqual(1, dll.PointInRect(byref(rect), pt)) + pt = POINT(15, 25) + left = c_long.in_dll(dll, 'left') + top = c_long.in_dll(dll, 'top') + right = c_long.in_dll(dll, 'right') + bottom = c_long.in_dll(dll, 'bottom') + rect = RECT(left, top, right, bottom) + PointInRect = dll.PointInRect + PointInRect.argtypes = [POINTER(RECT), POINT] + self.assertEqual(1, PointInRect(byref(rect), pt)) + + ReturnRect = dll.ReturnRect + ReturnRect.argtypes = [c_int, RECT, POINTER(RECT), POINT, RECT, + POINTER(RECT), POINT, RECT] + ReturnRect.restype = RECT + for i in range(4): + ret = ReturnRect(i, rect, pointer(rect), pt, rect, + byref(rect), pt, rect) + # the c function will check and modify ret if something is + # passed in improperly + self.assertEqual(ret.left, left.value) + self.assertEqual(ret.right, right.value) + self.assertEqual(ret.top, top.value) + self.assertEqual(ret.bottom, bottom.value) if __name__ == '__main__': unittest.main() diff --git a/Lib/ctypes/test/test_wintypes.py b/Lib/ctypes/test/test_wintypes.py index 806fccef812f..71442df8301a 100644 --- a/Lib/ctypes/test/test_wintypes.py +++ b/Lib/ctypes/test/test_wintypes.py @@ -1,14 +1,12 @@ import sys import unittest -if not sys.platform.startswith('win'): - raise unittest.SkipTest('Windows-only test') - from ctypes import * -from ctypes import wintypes +@unittest.skipUnless(sys.platform.startswith('win'), 'Windows-only test') class WinTypesTest(unittest.TestCase): def test_variant_bool(self): + from ctypes import wintypes # reads 16-bits from memory, anything non-zero is True for true_value in (1, 32767, 32768, 65535, 65537): true = POINTER(c_int16)(c_int16(true_value)) diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py index 0cf20766ccac..9e74ccdbcf40 100644 --- a/Lib/ctypes/util.py +++ b/Lib/ctypes/util.py @@ -19,6 +19,8 @@ def _get_build_version(): i = i + len(prefix) s, rest = sys.version[i:].split(" ", 1) majorVersion = int(s[:-2]) - 6 + if majorVersion >= 13: + majorVersion += 1 minorVersion = int(s[2:3]) / 10.0 # I don't think paths are affected by minor version in version 6 if majorVersion == 6: @@ -36,8 +38,12 @@ def find_msvcrt(): return None if version <= 6: clibname = 'msvcrt' - else: + elif version <= 13: clibname = 'msvcr%d' % (version * 10) + else: + # CRT is no longer directly loadable. See issue23606 for the + # discussion about alternative approaches. + return None # If python was built with in debug mode import importlib.machinery @@ -85,7 +91,7 @@ def find_library(name): elif os.name == "posix": # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump - import re, tempfile, errno + import re, tempfile def _findLib_gcc(name): expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) diff --git a/Lib/datetime.py b/Lib/datetime.py index 1789714034c9..b734a743d0d1 100644 --- a/Lib/datetime.py +++ b/Lib/datetime.py @@ -12,7 +12,7 @@ def _cmp(x, y): MINYEAR = 1 MAXYEAR = 9999 -_MAXORDINAL = 3652059 # date.max.toordinal() +_MAXORDINAL = 3652059 # date.max.toordinal() # Utility functions, adapted from Python's Demo/classes/Dates.py, which # also assumes the current Gregorian calendar indefinitely extended in @@ -26,7 +26,7 @@ def _cmp(x, y): # -1 is a placeholder for indexing purposes. _DAYS_IN_MONTH = [-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] -_DAYS_BEFORE_MONTH = [-1] # -1 is a placeholder for indexing purposes. +_DAYS_BEFORE_MONTH = [-1] # -1 is a placeholder for indexing purposes. dbm = 0 for dim in _DAYS_IN_MONTH[1:]: _DAYS_BEFORE_MONTH.append(dbm) @@ -162,9 +162,9 @@ def _format_time(hh, mm, ss, us): # Correctly substitute for %z and %Z escapes in strftime formats. def _wrap_strftime(object, format, timetuple): # Don't call utcoffset() or tzname() unless actually needed. - freplace = None # the string to use for %f - zreplace = None # the string to use for %z - Zreplace = None # the string to use for %Z + freplace = None # the string to use for %f + zreplace = None # the string to use for %z + Zreplace = None # the string to use for %Z # Scan format for %z and %Z escapes, replacing as needed. newformat = [] @@ -217,11 +217,6 @@ def _wrap_strftime(object, format, timetuple): newformat = "".join(newformat) return _time.strftime(newformat, timetuple) -def _call_tzinfo_method(tzinfo, methname, tzinfoarg): - if tzinfo is None: - return None - return getattr(tzinfo, methname)(tzinfoarg) - # Just raise TypeError if the arg isn't None or a string. def _check_tzname(name): if name is not None and not isinstance(name, str): @@ -245,13 +240,31 @@ def _check_utc_offset(name, offset): raise ValueError("tzinfo.%s() must return a whole number " "of minutes, got %s" % (name, offset)) if not -timedelta(1) < offset < timedelta(1): - raise ValueError("%s()=%s, must be must be strictly between" - " -timedelta(hours=24) and timedelta(hours=24)" - % (name, offset)) + raise ValueError("%s()=%s, must be must be strictly between " + "-timedelta(hours=24) and timedelta(hours=24)" % + (name, offset)) + +def _check_int_field(value): + if isinstance(value, int): + return value + if not isinstance(value, float): + try: + value = value.__int__() + except AttributeError: + pass + else: + if isinstance(value, int): + return value + raise TypeError('__int__ returned non-int (type %s)' % + type(value).__name__) + raise TypeError('an integer is required (got type %s)' % + type(value).__name__) + raise TypeError('integer argument expected, got float') def _check_date_fields(year, month, day): - if not isinstance(year, int): - raise TypeError('int expected') + year = _check_int_field(year) + month = _check_int_field(month) + day = _check_int_field(day) if not MINYEAR <= year <= MAXYEAR: raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year) if not 1 <= month <= 12: @@ -259,10 +272,13 @@ def _check_date_fields(year, month, day): dim = _days_in_month(year, month) if not 1 <= day <= dim: raise ValueError('day must be in 1..%d' % dim, day) + return year, month, day def _check_time_fields(hour, minute, second, microsecond): - if not isinstance(hour, int): - raise TypeError('int expected') + hour = _check_int_field(hour) + minute = _check_int_field(minute) + second = _check_int_field(second) + microsecond = _check_int_field(microsecond) if not 0 <= hour <= 23: raise ValueError('hour must be in 0..23', hour) if not 0 <= minute <= 59: @@ -271,6 +287,7 @@ def _check_time_fields(hour, minute, second, microsecond): raise ValueError('second must be in 0..59', second) if not 0 <= microsecond <= 999999: raise ValueError('microsecond must be in 0..999999', microsecond) + return hour, minute, second, microsecond def _check_tzinfo_arg(tz): if tz is not None and not isinstance(tz, tzinfo): @@ -280,6 +297,26 @@ def _cmperror(x, y): raise TypeError("can't compare '%s' to '%s'" % ( type(x).__name__, type(y).__name__)) +def _divide_and_round(a, b): + """divide a by b and round result to the nearest integer + + When the ratio is exactly half-way between two integers, + the even integer is returned. + """ + # Based on the reference implementation for divmod_near + # in Objects/longobject.c. + 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. + r *= 2 + greater_than_half = r > b if b > 0 else r < b + if greater_than_half or r == b and q % 2 == 1: + q += 1 + + return q + + class timedelta: """Represent the difference between two datetime objects. @@ -297,7 +334,7 @@ class timedelta: Representation: (days, seconds, microseconds). Why? Because I felt like it. """ - __slots__ = '_days', '_seconds', '_microseconds' + __slots__ = '_days', '_seconds', '_microseconds', '_hashcode' def __new__(cls, days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0): @@ -363,38 +400,26 @@ def __new__(cls, days=0, seconds=0, microseconds=0, # secondsfrac isn't referenced again if isinstance(microseconds, float): - microseconds += usdouble - microseconds = round(microseconds, 0) - seconds, microseconds = divmod(microseconds, 1e6) - assert microseconds == int(microseconds) - assert seconds == int(seconds) - days, seconds = divmod(seconds, 24.*3600.) - assert days == int(days) - assert seconds == int(seconds) - d += int(days) - s += int(seconds) # can't overflow - assert isinstance(s, int) - assert abs(s) <= 3 * 24 * 3600 + microseconds = round(microseconds + usdouble) + seconds, microseconds = divmod(microseconds, 1000000) + days, seconds = divmod(seconds, 24*3600) + d += days + s += seconds else: + microseconds = int(microseconds) seconds, microseconds = divmod(microseconds, 1000000) days, seconds = divmod(seconds, 24*3600) d += days - s += int(seconds) # can't overflow - assert isinstance(s, int) - assert abs(s) <= 3 * 24 * 3600 - microseconds = float(microseconds) - microseconds += usdouble - microseconds = round(microseconds, 0) + s += seconds + microseconds = round(microseconds + usdouble) + assert isinstance(s, int) + assert isinstance(microseconds, int) assert abs(s) <= 3 * 24 * 3600 assert abs(microseconds) < 3.1e6 # Just a little bit of carrying possible for microseconds and seconds. - assert isinstance(microseconds, float) - assert int(microseconds) == microseconds - us = int(microseconds) - seconds, us = divmod(us, 1000000) - s += seconds # cant't overflow - assert isinstance(s, int) + seconds, us = divmod(microseconds, 1000000) + s += seconds days, s = divmod(s, 24*3600) d += days @@ -402,27 +427,31 @@ def __new__(cls, days=0, seconds=0, microseconds=0, assert isinstance(s, int) and 0 <= s < 24*3600 assert isinstance(us, int) and 0 <= us < 1000000 - self = object.__new__(cls) + if abs(d) > 999999999: + raise OverflowError("timedelta # of days is too large: %d" % d) + self = object.__new__(cls) self._days = d self._seconds = s self._microseconds = us - if abs(d) > 999999999: - raise OverflowError("timedelta # of days is too large: %d" % d) - + self._hashcode = -1 return self def __repr__(self): if self._microseconds: - return "%s(%d, %d, %d)" % ('datetime.' + self.__class__.__name__, - self._days, - self._seconds, - self._microseconds) + return "%s.%s(%d, %d, %d)" % (self.__class__.__module__, + self.__class__.__qualname__, + self._days, + self._seconds, + self._microseconds) if self._seconds: - return "%s(%d, %d)" % ('datetime.' + self.__class__.__name__, - self._days, - self._seconds) - return "%s(%d)" % ('datetime.' + self.__class__.__name__, self._days) + return "%s.%s(%d, %d)" % (self.__class__.__module__, + self.__class__.__qualname__, + self._days, + self._seconds) + return "%s.%s(%d)" % (self.__class__.__module__, + self.__class__.__qualname__, + self._days) def __str__(self): mm, ss = divmod(self._seconds, 60) @@ -438,7 +467,7 @@ def plural(n): def total_seconds(self): """Total seconds in the duration.""" - return ((self.days * 86400 + self.seconds)*10**6 + + return ((self.days * 86400 + self.seconds) * 10**6 + self.microseconds) / 10**6 # Read-only field accessors @@ -506,8 +535,9 @@ def __mul__(self, other): self._seconds * other, self._microseconds * other) if isinstance(other, float): + usec = self._to_microseconds() a, b = other.as_integer_ratio() - return self * a / b + return timedelta(0, 0, _divide_and_round(usec * a, b)) return NotImplemented __rmul__ = __mul__ @@ -532,10 +562,10 @@ def __truediv__(self, other): if isinstance(other, timedelta): return usec / other._to_microseconds() if isinstance(other, int): - return timedelta(0, 0, usec / other) + return timedelta(0, 0, _divide_and_round(usec, other)) if isinstance(other, float): a, b = other.as_integer_ratio() - return timedelta(0, 0, b * usec / a) + return timedelta(0, 0, _divide_and_round(b * usec, a)) def __mod__(self, other): if isinstance(other, timedelta): @@ -558,12 +588,6 @@ def __eq__(self, other): else: return False - def __ne__(self, other): - if isinstance(other, timedelta): - return self._cmp(other) != 0 - else: - return True - def __le__(self, other): if isinstance(other, timedelta): return self._cmp(other) <= 0 @@ -593,7 +617,9 @@ def _cmp(self, other): return _cmp(self._getstate(), other._getstate()) def __hash__(self): - return hash(self._getstate()) + if self._hashcode == -1: + self._hashcode = hash(self._getstate()) + return self._hashcode def __bool__(self): return (self._days != 0 or @@ -626,7 +652,7 @@ class date: Operators: __repr__, __str__ - __cmp__, __hash__ + __eq__, __le__, __lt__, __ge__, __gt__, __hash__ __add__, __radd__, __sub__ (add/radd only with timedelta arg) Methods: @@ -641,7 +667,7 @@ class date: Properties (readonly): year, month, day """ - __slots__ = '_year', '_month', '_day' + __slots__ = '_year', '_month', '_day', '_hashcode' def __new__(cls, year, month=None, day=None): """Constructor. @@ -650,17 +676,19 @@ def __new__(cls, year, month=None, day=None): year, month, day (required, base 1) """ - if (isinstance(year, bytes) and len(year) == 4 and - 1 <= year[2] <= 12 and month is None): # Month is sane + if month is None and isinstance(year, bytes) and len(year) == 4 and \ + 1 <= year[2] <= 12: # Pickle support self = object.__new__(cls) self.__setstate(year) + self._hashcode = -1 return self - _check_date_fields(year, month, day) + year, month, day = _check_date_fields(year, month, day) self = object.__new__(cls) self._year = year self._month = month self._day = day + self._hashcode = -1 return self # Additional constructors @@ -700,10 +728,11 @@ def __repr__(self): >>> repr(dt) 'datetime.datetime(2010, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)' """ - return "%s(%d, %d, %d)" % ('datetime.' + self.__class__.__name__, - self._year, - self._month, - self._day) + return "%s.%s(%d, %d, %d)" % (self.__class__.__module__, + self.__class__.__qualname__, + self._year, + self._month, + self._day) # XXX These shouldn't depend on time.localtime(), because that # clips the usable dates to [1970 .. 2038). At least ctime() is # easily done without using strftime() -- that's better too because @@ -723,6 +752,8 @@ def strftime(self, fmt): return _wrap_strftime(self, fmt, self.timetuple()) def __format__(self, fmt): + if not isinstance(fmt, str): + raise TypeError("must be str, not %s" % type(fmt).__name__) if len(fmt) != 0: return self.strftime(fmt) return str(self) @@ -756,7 +787,8 @@ def day(self): """day (1-31)""" return self._day - # Standard conversions, __cmp__, __hash__ (and helpers) + # Standard conversions, __eq__, __le__, __lt__, __ge__, __gt__, + # __hash__ (and helpers) def timetuple(self): "Return local time tuple compatible with time.localtime()." @@ -779,7 +811,6 @@ def replace(self, year=None, month=None, day=None): month = self._month if day is None: day = self._day - _check_date_fields(year, month, day) return date(year, month, day) # Comparisons of date objects with other. @@ -789,11 +820,6 @@ def __eq__(self, other): return self._cmp(other) == 0 return NotImplemented - def __ne__(self, other): - if isinstance(other, date): - return self._cmp(other) != 0 - return NotImplemented - def __le__(self, other): if isinstance(other, date): return self._cmp(other) <= 0 @@ -822,7 +848,9 @@ def _cmp(self, other): def __hash__(self): "Hash." - return hash(self._getstate()) + if self._hashcode == -1: + self._hashcode = hash(self._getstate()) + return self._hashcode # Computations @@ -892,8 +920,6 @@ def _getstate(self): return bytes([yhi, ylo, self._month, self._day]), def __setstate(self, string): - if len(string) != 4 or not (1 <= string[2] <= 12): - raise TypeError("not enough arguments") yhi, ylo, self._month, self._day = string self._year = yhi * 256 + ylo @@ -912,6 +938,7 @@ class tzinfo: Subclasses must override the name(), utcoffset() and dst() methods. """ __slots__ = () + def tzname(self, dt): "datetime -> string name of time zone." raise NotImplementedError("tzinfo subclass must override tzname()") @@ -985,7 +1012,7 @@ class time: Operators: __repr__, __str__ - __cmp__, __hash__ + __eq__, __le__, __lt__, __ge__, __gt__, __hash__ Methods: @@ -998,6 +1025,7 @@ class time: Properties (readonly): hour, minute, second, microsecond, tzinfo """ + __slots__ = '_hour', '_minute', '_second', '_microsecond', '_tzinfo', '_hashcode' def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): """Constructor. @@ -1008,18 +1036,22 @@ def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): second, microsecond (default to zero) tzinfo (default to None) """ - self = object.__new__(cls) - if isinstance(hour, bytes) and len(hour) == 6: + if isinstance(hour, bytes) and len(hour) == 6 and hour[0] < 24: # Pickle support + self = object.__new__(cls) self.__setstate(hour, minute or None) + self._hashcode = -1 return self + hour, minute, second, microsecond = _check_time_fields( + hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - _check_time_fields(hour, minute, second, microsecond) + self = object.__new__(cls) self._hour = hour self._minute = minute self._second = second self._microsecond = microsecond self._tzinfo = tzinfo + self._hashcode = -1 return self # Read-only field accessors @@ -1058,12 +1090,6 @@ def __eq__(self, other): else: return False - def __ne__(self, other): - if isinstance(other, time): - return self._cmp(other, allow_mixed=True) != 0 - else: - return True - def __le__(self, other): if isinstance(other, time): return self._cmp(other) <= 0 @@ -1104,8 +1130,8 @@ def _cmp(self, other, allow_mixed=False): if base_compare: return _cmp((self._hour, self._minute, self._second, self._microsecond), - (other._hour, other._minute, other._second, - other._microsecond)) + (other._hour, other._minute, other._second, + other._microsecond)) if myoff is None or otoff is None: if allow_mixed: return 2 # arbitrary non-zero value @@ -1118,16 +1144,20 @@ def _cmp(self, other, allow_mixed=False): def __hash__(self): """Hash.""" - tzoff = self.utcoffset() - if not tzoff: # zero or None - return hash(self._getstate()[0]) - h, m = divmod(timedelta(hours=self.hour, minutes=self.minute) - tzoff, - timedelta(hours=1)) - assert not m % timedelta(minutes=1), "whole minute" - m //= timedelta(minutes=1) - if 0 <= h < 24: - return hash(time(h, m, self.second, self.microsecond)) - return hash((h, m, self.second, self.microsecond)) + if self._hashcode == -1: + tzoff = self.utcoffset() + if not tzoff: # zero or None + self._hashcode = hash(self._getstate()[0]) + else: + h, m = divmod(timedelta(hours=self.hour, minutes=self.minute) - tzoff, + timedelta(hours=1)) + assert not m % timedelta(minutes=1), "whole minute" + m //= timedelta(minutes=1) + if 0 <= h < 24: + self._hashcode = hash(time(h, m, self.second, self.microsecond)) + else: + self._hashcode = hash((h, m, self.second, self.microsecond)) + return self._hashcode # Conversion to string @@ -1155,8 +1185,9 @@ def __repr__(self): s = ", %d" % self._second else: s = "" - s= "%s(%d, %d%s)" % ('datetime.' + self.__class__.__name__, - self._hour, self._minute, s) + s= "%s.%s(%d, %d%s)" % (self.__class__.__module__, + self.__class__.__qualname__, + self._hour, self._minute, s) if self._tzinfo is not None: assert s[-1:] == ")" s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")" @@ -1189,6 +1220,8 @@ def strftime(self, fmt): return _wrap_strftime(self, fmt, timetuple) def __format__(self, fmt): + if not isinstance(fmt, str): + raise TypeError("must be str, not %s" % type(fmt).__name__) if len(fmt) != 0: return self.strftime(fmt) return str(self) @@ -1245,16 +1278,8 @@ def replace(self, hour=None, minute=None, second=None, microsecond=None, microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - _check_time_fields(hour, minute, second, microsecond) - _check_tzinfo_arg(tzinfo) return time(hour, minute, second, microsecond, tzinfo) - def __bool__(self): - if self.second or self.microsecond: - return True - offset = self.utcoffset() or timedelta(0) - return timedelta(hours=self.hour, minutes=self.minute) != offset - # Pickle support. def _getstate(self): @@ -1268,15 +1293,11 @@ def _getstate(self): return (basestate, self._tzinfo) def __setstate(self, string, tzinfo): - if len(string) != 6 or string[0] >= 24: - raise TypeError("an integer is required") - (self._hour, self._minute, self._second, - us1, us2, us3) = string + if tzinfo is not None and not isinstance(tzinfo, _tzinfo_class): + raise TypeError("bad tzinfo state arg") + self._hour, self._minute, self._second, us1, us2, us3 = string self._microsecond = (((us1 << 8) | us2) << 8) | us3 - if tzinfo is None or isinstance(tzinfo, _tzinfo_class): - self._tzinfo = tzinfo - else: - raise TypeError("bad tzinfo state arg %r" % tzinfo) + self._tzinfo = tzinfo def __reduce__(self): return (time, self._getstate()) @@ -1293,25 +1314,30 @@ class datetime(date): The year, month and day arguments are required. tzinfo may be None, or an instance of a tzinfo subclass. The remaining arguments may be ints. """ + __slots__ = date.__slots__ + time.__slots__ - __slots__ = date.__slots__ + ( - '_hour', '_minute', '_second', - '_microsecond', '_tzinfo') def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, microsecond=0, tzinfo=None): - if isinstance(year, bytes) and len(year) == 10: + if isinstance(year, bytes) and len(year) == 10 and 1 <= year[2] <= 12: # Pickle support - self = date.__new__(cls, year[:4]) + self = object.__new__(cls) self.__setstate(year, month) + self._hashcode = -1 return self + year, month, day = _check_date_fields(year, month, day) + hour, minute, second, microsecond = _check_time_fields( + hour, minute, second, microsecond) _check_tzinfo_arg(tzinfo) - _check_time_fields(hour, minute, second, microsecond) - self = date.__new__(cls, year, month, day) + self = object.__new__(cls) + self._year = year + self._month = month + self._day = day self._hour = hour self._minute = minute self._second = second self._microsecond = microsecond self._tzinfo = tzinfo + self._hashcode = -1 return self # Read-only field accessors @@ -1341,55 +1367,43 @@ def tzinfo(self): return self._tzinfo @classmethod - def fromtimestamp(cls, t, tz=None): + def _fromtimestamp(cls, t, utc, tz): """Construct a datetime from a POSIX timestamp (like time.time()). A timezone info object may be passed in as well. """ + frac, t = _math.modf(t) + us = round(frac * 1e6) + if us >= 1000000: + t += 1 + us -= 1000000 + elif us < 0: + t -= 1 + us += 1000000 - _check_tzinfo_arg(tz) + converter = _time.gmtime if utc else _time.localtime + y, m, d, hh, mm, ss, weekday, jday, dst = converter(t) + ss = min(ss, 59) # clamp out leap seconds if the platform has them + return cls(y, m, d, hh, mm, ss, us, tz) - converter = _time.localtime if tz is None else _time.gmtime + @classmethod + def fromtimestamp(cls, t, tz=None): + """Construct a datetime from a POSIX timestamp (like time.time()). - t, frac = divmod(t, 1.0) - us = int(frac * 1e6) + A timezone info object may be passed in as well. + """ + _check_tzinfo_arg(tz) - # If timestamp is less than one microsecond smaller than a - # full second, us can be rounded up to 1000000. In this case, - # roll over to seconds, otherwise, ValueError is raised - # by the constructor. - if us == 1000000: - t += 1 - us = 0 - y, m, d, hh, mm, ss, weekday, jday, dst = converter(t) - ss = min(ss, 59) # clamp out leap seconds if the platform has them - result = cls(y, m, d, hh, mm, ss, us, tz) + result = cls._fromtimestamp(t, tz is not None, tz) if tz is not None: result = tz.fromutc(result) return result @classmethod def utcfromtimestamp(cls, t): - "Construct a UTC datetime from a POSIX timestamp (like time.time())." - t, frac = divmod(t, 1.0) - us = int(frac * 1e6) - - # If timestamp is less than one microsecond smaller than a - # full second, us can be rounded up to 1000000. In this case, - # roll over to seconds, otherwise, ValueError is raised - # by the constructor. - if us == 1000000: - t += 1 - us = 0 - y, m, d, hh, mm, ss, weekday, jday, dst = _time.gmtime(t) - ss = min(ss, 59) # clamp out leap seconds if the platform has them - return cls(y, m, d, hh, mm, ss, us) + """Construct a naive UTC datetime from a POSIX timestamp.""" + return cls._fromtimestamp(t, True, None) - # XXX This is supposed to do better than we *can* do by using time.time(), - # XXX if the platform supports a more accurate way. The C implementation - # XXX uses gettimeofday on platforms that have it, but that isn't - # XXX available from Python. So now() may return different results - # XXX across the implementations. @classmethod def now(cls, tz=None): "Construct a datetime from time.time() and optional time zone info." @@ -1476,11 +1490,8 @@ def replace(self, year=None, month=None, day=None, hour=None, microsecond = self.microsecond if tzinfo is True: tzinfo = self.tzinfo - _check_date_fields(year, month, day) - _check_time_fields(hour, minute, second, microsecond) - _check_tzinfo_arg(tzinfo) - return datetime(year, month, day, hour, minute, second, - microsecond, tzinfo) + return datetime(year, month, day, hour, minute, second, microsecond, + tzinfo) def astimezone(self, tz=None): if tz is None: @@ -1550,10 +1561,9 @@ def isoformat(self, sep='T'): Optional argument sep specifies the separator between date and time, default 'T'. """ - s = ("%04d-%02d-%02d%c" % (self._year, self._month, self._day, - sep) + - _format_time(self._hour, self._minute, self._second, - self._microsecond)) + s = ("%04d-%02d-%02d%c" % (self._year, self._month, self._day, sep) + + _format_time(self._hour, self._minute, self._second, + self._microsecond)) off = self.utcoffset() if off is not None: if off.days < 0: @@ -1569,14 +1579,15 @@ def isoformat(self, sep='T'): def __repr__(self): """Convert to formal string, for repr().""" - L = [self._year, self._month, self._day, # These are never zero + L = [self._year, self._month, self._day, # These are never zero self._hour, self._minute, self._second, self._microsecond] if L[-1] == 0: del L[-1] if L[-1] == 0: del L[-1] - s = ", ".join(map(str, L)) - s = "%s(%s)" % ('datetime.' + self.__class__.__name__, s) + s = "%s.%s(%s)" % (self.__class__.__module__, + self.__class__.__qualname__, + ", ".join(map(str, L))) if self._tzinfo is not None: assert s[-1:] == ")" s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")" @@ -1608,7 +1619,9 @@ def tzname(self): it mean anything in particular. For example, "GMT", "UTC", "-500", "-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies. """ - name = _call_tzinfo_method(self._tzinfo, "tzname", self) + if self._tzinfo is None: + return None + name = self._tzinfo.tzname(self) _check_tzname(name) return name @@ -1637,14 +1650,6 @@ def __eq__(self, other): else: return False - def __ne__(self, other): - if isinstance(other, datetime): - return self._cmp(other, allow_mixed=True) != 0 - elif not isinstance(other, date): - return NotImplemented - else: - return True - def __le__(self, other): if isinstance(other, datetime): return self._cmp(other) <= 0 @@ -1694,9 +1699,9 @@ def _cmp(self, other, allow_mixed=False): return _cmp((self._year, self._month, self._day, self._hour, self._minute, self._second, self._microsecond), - (other._year, other._month, other._day, - other._hour, other._minute, other._second, - other._microsecond)) + (other._year, other._month, other._day, + other._hour, other._minute, other._second, + other._microsecond)) if myoff is None or otoff is None: if allow_mixed: return 2 # arbitrary non-zero value @@ -1754,12 +1759,15 @@ def __sub__(self, other): return base + otoff - myoff def __hash__(self): - tzoff = self.utcoffset() - if tzoff is None: - return hash(self._getstate()[0]) - days = _ymd2ord(self.year, self.month, self.day) - seconds = self.hour * 3600 + self.minute * 60 + self.second - return hash(timedelta(days, seconds, self.microsecond) - tzoff) + if self._hashcode == -1: + tzoff = self.utcoffset() + if tzoff is None: + self._hashcode = hash(self._getstate()[0]) + else: + days = _ymd2ord(self.year, self.month, self.day) + seconds = self.hour * 3600 + self.minute * 60 + self.second + self._hashcode = hash(timedelta(days, seconds, self.microsecond) - tzoff) + return self._hashcode # Pickle support. @@ -1776,14 +1784,13 @@ def _getstate(self): return (basestate, self._tzinfo) def __setstate(self, string, tzinfo): + if tzinfo is not None and not isinstance(tzinfo, _tzinfo_class): + raise TypeError("bad tzinfo state arg") (yhi, ylo, self._month, self._day, self._hour, self._minute, self._second, us1, us2, us3) = string self._year = yhi * 256 + ylo self._microsecond = (((us1 << 8) | us2) << 8) | us3 - if tzinfo is None or isinstance(tzinfo, _tzinfo_class): - self._tzinfo = tzinfo - else: - raise TypeError("bad tzinfo state arg %r" % tzinfo) + self._tzinfo = tzinfo def __reduce__(self): return (self.__class__, self._getstate()) @@ -1799,7 +1806,7 @@ def _isoweek1monday(year): # XXX This could be done more efficiently THURSDAY = 3 firstday = _ymd2ord(year, 1, 1) - firstweekday = (firstday + 6) % 7 # See weekday() above + firstweekday = (firstday + 6) % 7 # See weekday() above week1monday = firstday - firstweekday if firstweekday > THURSDAY: week1monday += 7 @@ -1820,13 +1827,12 @@ def __new__(cls, offset, name=_Omitted): elif not isinstance(name, str): raise TypeError("name must be a string") if not cls._minoffset <= offset <= cls._maxoffset: - raise ValueError("offset must be a timedelta" - " strictly between -timedelta(hours=24) and" - " timedelta(hours=24).") - if (offset.microseconds != 0 or - offset.seconds % 60 != 0): - raise ValueError("offset must be a timedelta" - " representing a whole number of minutes") + raise ValueError("offset must be a timedelta " + "strictly between -timedelta(hours=24) and " + "timedelta(hours=24).") + if (offset.microseconds != 0 or offset.seconds % 60 != 0): + raise ValueError("offset must be a timedelta " + "representing a whole number of minutes") return cls._create(offset, name) @classmethod @@ -1863,10 +1869,12 @@ def __repr__(self): if self is self.utc: return 'datetime.timezone.utc' if self._name is None: - return "%s(%r)" % ('datetime.' + self.__class__.__name__, - self._offset) - return "%s(%r, %r)" % ('datetime.' + self.__class__.__name__, - self._offset, self._name) + return "%s.%s(%r)" % (self.__class__.__module__, + self.__class__.__qualname__, + self._offset) + return "%s.%s(%r, %r)" % (self.__class__.__module__, + self.__class__.__qualname__, + self._offset, self._name) def __str__(self): return self.tzname(None) @@ -1905,6 +1913,8 @@ def fromutc(self, dt): @staticmethod def _name_from_offset(delta): + if not delta: + return 'UTC' if delta < timedelta(0): sign = '-' delta = -delta @@ -2121,14 +2131,13 @@ def _name_from_offset(delta): pass else: # Clean up unused names - del (_DAYNAMES, _DAYS_BEFORE_MONTH, _DAYS_IN_MONTH, - _DI100Y, _DI400Y, _DI4Y, _MAXORDINAL, _MONTHNAMES, - _build_struct_time, _call_tzinfo_method, _check_date_fields, - _check_time_fields, _check_tzinfo_arg, _check_tzname, - _check_utc_offset, _cmp, _cmperror, _date_class, _days_before_month, - _days_before_year, _days_in_month, _format_time, _is_leap, - _isoweek1monday, _math, _ord2ymd, _time, _time_class, _tzinfo_class, - _wrap_strftime, _ymd2ord) + del (_DAYNAMES, _DAYS_BEFORE_MONTH, _DAYS_IN_MONTH, _DI100Y, _DI400Y, + _DI4Y, _EPOCH, _MAXORDINAL, _MONTHNAMES, _build_struct_time, + _check_date_fields, _check_int_field, _check_time_fields, + _check_tzinfo_arg, _check_tzname, _check_utc_offset, _cmp, _cmperror, + _date_class, _days_before_month, _days_before_year, _days_in_month, + _format_time, _is_leap, _isoweek1monday, _math, _ord2ymd, + _time, _time_class, _tzinfo_class, _wrap_strftime, _ymd2ord) # XXX Since import * above excludes names that start with _, # docstring does not get overwritten. In the future, it may be # appropriate to maintain a single module level docstring and diff --git a/Lib/dbm/__init__.py b/Lib/dbm/__init__.py index 5f4664a7c652..6831a8440737 100644 --- a/Lib/dbm/__init__.py +++ b/Lib/dbm/__init__.py @@ -153,9 +153,9 @@ def whichdb(filename): except OSError: return None - # Read the start of the file -- the magic number - s16 = f.read(16) - f.close() + with f: + # Read the start of the file -- the magic number + s16 = f.read(16) s = s16[0:4] # Return "" if not at least 4 bytes diff --git a/Lib/dbm/dumb.py b/Lib/dbm/dumb.py index ba6a20d0c9ac..7777a7cae67d 100644 --- a/Lib/dbm/dumb.py +++ b/Lib/dbm/dumb.py @@ -21,6 +21,7 @@ """ +import ast as _ast import io as _io import os as _os import collections @@ -44,7 +45,7 @@ class _Database(collections.MutableMapping): _os = _os # for _commit() _io = _io # for _commit() - def __init__(self, filebasename, mode): + def __init__(self, filebasename, mode, flag='c'): self._mode = mode # The directory file is a text file. Each line looks like @@ -64,14 +65,25 @@ def __init__(self, filebasename, mode): # The index is an in-memory dict, mirroring the directory file. self._index = None # maps keys to (pos, siz) pairs + # Handle the creation + self._create(flag) + self._update() + + def _create(self, flag): + if flag == 'n': + for filename in (self._datfile, self._bakfile, self._dirfile): + try: + _os.remove(filename) + except OSError: + pass # Mod by Jack: create data file if needed try: f = _io.open(self._datfile, 'r', encoding="Latin-1") except OSError: - f = _io.open(self._datfile, 'w', encoding="Latin-1") - self._chmod(self._datfile) - f.close() - self._update() + with _io.open(self._datfile, 'w', encoding="Latin-1") as f: + self._chmod(self._datfile) + else: + f.close() # Read directory file into the in-memory index dict. def _update(self): @@ -81,12 +93,12 @@ def _update(self): except OSError: pass else: - for line in f: - line = line.rstrip() - key, pos_and_siz_pair = eval(line) - key = key.encode('Latin-1') - self._index[key] = pos_and_siz_pair - f.close() + with f: + for line in f: + line = line.rstrip() + key, pos_and_siz_pair = _ast.literal_eval(line) + key = key.encode('Latin-1') + self._index[key] = pos_and_siz_pair # Write the index dict to the directory file. The original directory # file (if any) is renamed with a .bak extension first. If a .bak @@ -108,24 +120,28 @@ def _commit(self): except OSError: pass - f = self._io.open(self._dirfile, 'w', encoding="Latin-1") - self._chmod(self._dirfile) - for key, pos_and_siz_pair in self._index.items(): - # Use Latin-1 since it has no qualms with any value in any - # position; UTF-8, though, does care sometimes. - f.write("%r, %r\n" % (key.decode('Latin-1'), pos_and_siz_pair)) - f.close() + with self._io.open(self._dirfile, 'w', encoding="Latin-1") as f: + self._chmod(self._dirfile) + for key, pos_and_siz_pair in self._index.items(): + # Use Latin-1 since it has no qualms with any value in any + # position; UTF-8, though, does care sometimes. + entry = "%r, %r\n" % (key.decode('Latin-1'), pos_and_siz_pair) + f.write(entry) sync = _commit + def _verify_open(self): + if self._index is None: + raise error('DBM object has already been closed') + def __getitem__(self, key): if isinstance(key, str): key = key.encode('utf-8') + self._verify_open() pos, siz = self._index[key] # may raise KeyError - f = _io.open(self._datfile, 'rb') - f.seek(pos) - dat = f.read(siz) - f.close() + with _io.open(self._datfile, 'rb') as f: + f.seek(pos) + dat = f.read(siz) return dat # Append val to the data file, starting at a _BLOCKSIZE-aligned @@ -133,14 +149,13 @@ def __getitem__(self, key): # to get to an aligned offset. Return pair # (starting offset of val, len(val)) def _addval(self, val): - f = _io.open(self._datfile, 'rb+') - f.seek(0, 2) - pos = int(f.tell()) - npos = ((pos + _BLOCKSIZE - 1) // _BLOCKSIZE) * _BLOCKSIZE - f.write(b'\0'*(npos-pos)) - pos = npos - f.write(val) - f.close() + with _io.open(self._datfile, 'rb+') as f: + f.seek(0, 2) + pos = int(f.tell()) + npos = ((pos + _BLOCKSIZE - 1) // _BLOCKSIZE) * _BLOCKSIZE + f.write(b'\0'*(npos-pos)) + pos = npos + f.write(val) return (pos, len(val)) # Write val to the data file, starting at offset pos. The caller @@ -148,10 +163,9 @@ def _addval(self, val): # pos to hold val, without overwriting some other value. Return # pair (pos, len(val)). def _setval(self, pos, val): - f = _io.open(self._datfile, 'rb+') - f.seek(pos) - f.write(val) - f.close() + with _io.open(self._datfile, 'rb+') as f: + f.seek(pos) + f.write(val) return (pos, len(val)) # key is a new key whose associated value starts in the data file @@ -159,10 +173,9 @@ def _setval(self, pos, val): # the in-memory index dict, and append one to the directory file. def _addkey(self, key, pos_and_siz_pair): self._index[key] = pos_and_siz_pair - f = _io.open(self._dirfile, 'a', encoding="Latin-1") - self._chmod(self._dirfile) - f.write("%r, %r\n" % (key.decode("Latin-1"), pos_and_siz_pair)) - f.close() + with _io.open(self._dirfile, 'a', encoding="Latin-1") as f: + self._chmod(self._dirfile) + f.write("%r, %r\n" % (key.decode("Latin-1"), pos_and_siz_pair)) def __setitem__(self, key, val): if isinstance(key, str): @@ -173,6 +186,7 @@ def __setitem__(self, key, val): val = val.encode('utf-8') elif not isinstance(val, (bytes, bytearray)): raise TypeError("values must be bytes or strings") + self._verify_open() if key not in self._index: self._addkey(key, self._addval(val)) else: @@ -200,6 +214,7 @@ def __setitem__(self, key, val): def __delitem__(self, key): if isinstance(key, str): key = key.encode('utf-8') + self._verify_open() # The blocks used by the associated value are lost. del self._index[key] # XXX It's unclear why we do a _commit() here (the code always @@ -209,26 +224,44 @@ def __delitem__(self, key): self._commit() def keys(self): - return list(self._index.keys()) + try: + return list(self._index) + except TypeError: + raise error('DBM object has already been closed') from None def items(self): + self._verify_open() return [(key, self[key]) for key in self._index.keys()] def __contains__(self, key): if isinstance(key, str): key = key.encode('utf-8') - return key in self._index + try: + return key in self._index + except TypeError: + if self._index is None: + raise error('DBM object has already been closed') from None + else: + raise def iterkeys(self): - return iter(self._index.keys()) + try: + return iter(self._index) + except TypeError: + raise error('DBM object has already been closed') from None __iter__ = iterkeys def __len__(self): - return len(self._index) + try: + return len(self._index) + except TypeError: + raise error('DBM object has already been closed') from None def close(self): - self._commit() - self._index = self._datfile = self._dirfile = self._bakfile = None + try: + self._commit() + finally: + self._index = self._datfile = self._dirfile = self._bakfile = None __del__ = close @@ -243,20 +276,20 @@ def __exit__(self, *args): self.close() -def open(file, flag=None, mode=0o666): +def open(file, flag='c', mode=0o666): """Open the database file, filename, and return corresponding object. The flag argument, used to control how the database is opened in the - other DBM implementations, is ignored in the dbm.dumb module; the - database is always opened for update, and will be created if it does - not exist. + other DBM implementations, supports only the semantics of 'c' and 'n' + values. Other values will default to the semantics of 'c' value: + the database will always opened for update and will be created if it + does not exist. The optional mode argument is the UNIX mode of the file, used only when the database has to be created. It defaults to octal code 0o666 (and will be modified by the prevailing umask). """ - # flag argument is currently ignored # Modify mode depending on the umask try: @@ -267,5 +300,4 @@ def open(file, flag=None, mode=0o666): else: # Turn off any bits that are set in the umask mode = mode & (~um) - - return _Database(file, mode) + return _Database(file, mode, flag=flag) diff --git a/Lib/decimal.py b/Lib/decimal.py index 7bc1c943b5b0..7746ea260102 100644 --- a/Lib/decimal.py +++ b/Lib/decimal.py @@ -1,6407 +1,11 @@ -# Copyright (c) 2004 Python Software Foundation. -# All rights reserved. - -# Written by Eric Price <eprice at tjhsst.edu> -# and Facundo Batista <facundo at taniquetil.com.ar> -# and Raymond Hettinger <python at rcn.com> -# and Aahz <aahz at pobox.com> -# and Tim Peters - -# This module should be kept in sync with the latest updates of the -# IBM specification as it evolves. Those updates will be treated -# as bug fixes (deviation from the spec is a compatibility, usability -# bug) and will be backported. At this point the spec is stabilizing -# and the updates are becoming fewer, smaller, and less significant. - -""" -This is an implementation of decimal floating point arithmetic based on -the General Decimal Arithmetic Specification: - - http://speleotrove.com/decimal/decarith.html - -and IEEE standard 854-1987: - - http://en.wikipedia.org/wiki/IEEE_854-1987 - -Decimal floating point has finite precision with arbitrarily large bounds. - -The purpose of this module is to support arithmetic using familiar -"schoolhouse" rules and to avoid some of the tricky representation -issues associated with binary floating point. The package is especially -useful for financial applications or for contexts where users have -expectations that are at odds with binary floating point (for instance, -in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead -of 0.0; Decimal('1.00') % Decimal('0.1') returns the expected -Decimal('0.00')). - -Here are some examples of using the decimal module: - ->>> from decimal import * ->>> setcontext(ExtendedContext) ->>> Decimal(0) -Decimal('0') ->>> Decimal('1') -Decimal('1') ->>> Decimal('-.0123') -Decimal('-0.0123') ->>> Decimal(123456) -Decimal('123456') ->>> Decimal('123.45e12345678') -Decimal('1.2345E+12345680') ->>> Decimal('1.33') + Decimal('1.27') -Decimal('2.60') ->>> Decimal('12.34') + Decimal('3.87') - Decimal('18.41') -Decimal('-2.20') ->>> dig = Decimal(1) ->>> print(dig / Decimal(3)) -0.333333333 ->>> getcontext().prec = 18 ->>> print(dig / Decimal(3)) -0.333333333333333333 ->>> print(dig.sqrt()) -1 ->>> print(Decimal(3).sqrt()) -1.73205080756887729 ->>> print(Decimal(3) ** 123) -4.85192780976896427E+58 ->>> inf = Decimal(1) / Decimal(0) ->>> print(inf) -Infinity ->>> neginf = Decimal(-1) / Decimal(0) ->>> print(neginf) --Infinity ->>> print(neginf + inf) -NaN ->>> print(neginf * inf) --Infinity ->>> print(dig / 0) -Infinity ->>> getcontext().traps[DivisionByZero] = 1 ->>> print(dig / 0) -Traceback (most recent call last): - ... - ... - ... -decimal.DivisionByZero: x / 0 ->>> c = Context() ->>> c.traps[InvalidOperation] = 0 ->>> print(c.flags[InvalidOperation]) -0 ->>> c.divide(Decimal(0), Decimal(0)) -Decimal('NaN') ->>> c.traps[InvalidOperation] = 1 ->>> print(c.flags[InvalidOperation]) -1 ->>> c.flags[InvalidOperation] = 0 ->>> print(c.flags[InvalidOperation]) -0 ->>> print(c.divide(Decimal(0), Decimal(0))) -Traceback (most recent call last): - ... - ... - ... -decimal.InvalidOperation: 0 / 0 ->>> print(c.flags[InvalidOperation]) -1 ->>> c.flags[InvalidOperation] = 0 ->>> c.traps[InvalidOperation] = 0 ->>> print(c.divide(Decimal(0), Decimal(0))) -NaN ->>> print(c.flags[InvalidOperation]) -1 ->>> -""" - -__all__ = [ - # Two major classes - 'Decimal', 'Context', - - # Contexts - 'DefaultContext', 'BasicContext', 'ExtendedContext', - - # Exceptions - 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero', - 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow', - 'FloatOperation', - - # Constants for use in setting up contexts - 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING', - 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN', 'ROUND_05UP', - - # Functions for manipulating contexts - 'setcontext', 'getcontext', 'localcontext', - - # Limits for the C version for compatibility - 'MAX_PREC', 'MAX_EMAX', 'MIN_EMIN', 'MIN_ETINY', - - # C version: compile time choice that enables the thread local context - 'HAVE_THREADS' -] - -__version__ = '1.70' # Highest version of the spec this complies with - # See http://speleotrove.com/decimal/ -__libmpdec_version__ = "2.4.0" # compatible libmpdec version - -import copy as _copy -import math as _math -import numbers as _numbers -import sys - -try: - from collections import namedtuple as _namedtuple - DecimalTuple = _namedtuple('DecimalTuple', 'sign digits exponent') -except ImportError: - DecimalTuple = lambda *args: args - -# Rounding -ROUND_DOWN = 'ROUND_DOWN' -ROUND_HALF_UP = 'ROUND_HALF_UP' -ROUND_HALF_EVEN = 'ROUND_HALF_EVEN' -ROUND_CEILING = 'ROUND_CEILING' -ROUND_FLOOR = 'ROUND_FLOOR' -ROUND_UP = 'ROUND_UP' -ROUND_HALF_DOWN = 'ROUND_HALF_DOWN' -ROUND_05UP = 'ROUND_05UP' - -# Compatibility with the C version -HAVE_THREADS = True -if sys.maxsize == 2**63-1: - MAX_PREC = 999999999999999999 - MAX_EMAX = 999999999999999999 - MIN_EMIN = -999999999999999999 -else: - MAX_PREC = 425000000 - MAX_EMAX = 425000000 - MIN_EMIN = -425000000 - -MIN_ETINY = MIN_EMIN - (MAX_PREC-1) - -# Errors - -class DecimalException(ArithmeticError): - """Base exception class. - - Used exceptions derive from this. - If an exception derives from another exception besides this (such as - Underflow (Inexact, Rounded, Subnormal) that indicates that it is only - called if the others are present. This isn't actually used for - anything, though. - - handle -- Called when context._raise_error is called and the - trap_enabler is not set. First argument is self, second is the - context. More arguments can be given, those being after - the explanation in _raise_error (For example, - context._raise_error(NewError, '(-x)!', self._sign) would - call NewError().handle(context, self._sign).) - - To define a new exception, it should be sufficient to have it derive - from DecimalException. - """ - def handle(self, context, *args): - pass - - -class Clamped(DecimalException): - """Exponent of a 0 changed to fit bounds. - - This occurs and signals clamped if the exponent of a result has been - altered in order to fit the constraints of a specific concrete - representation. This may occur when the exponent of a zero result would - be outside the bounds of a representation, or when a large normal - number would have an encoded exponent that cannot be represented. In - this latter case, the exponent is reduced to fit and the corresponding - number of zero digits are appended to the coefficient ("fold-down"). - """ - -class InvalidOperation(DecimalException): - """An invalid operation was performed. - - Various bad things cause this: - - Something creates a signaling NaN - -INF + INF - 0 * (+-)INF - (+-)INF / (+-)INF - x % 0 - (+-)INF % x - x._rescale( non-integer ) - sqrt(-x) , x > 0 - 0 ** 0 - x ** (non-integer) - x ** (+-)INF - An operand is invalid - - The result of the operation after these is a quiet positive NaN, - except when the cause is a signaling NaN, in which case the result is - also a quiet NaN, but with the original sign, and an optional - diagnostic information. - """ - def handle(self, context, *args): - if args: - ans = _dec_from_triple(args[0]._sign, args[0]._int, 'n', True) - return ans._fix_nan(context) - return _NaN - -class ConversionSyntax(InvalidOperation): - """Trying to convert badly formed string. - - This occurs and signals invalid-operation if an string is being - converted to a number and it does not conform to the numeric string - syntax. The result is [0,qNaN]. - """ - def handle(self, context, *args): - return _NaN - -class DivisionByZero(DecimalException, ZeroDivisionError): - """Division by 0. - - This occurs and signals division-by-zero if division of a finite number - by zero was attempted (during a divide-integer or divide operation, or a - power operation with negative right-hand operand), and the dividend was - not zero. - - The result of the operation is [sign,inf], where sign is the exclusive - or of the signs of the operands for divide, or is 1 for an odd power of - -0, for power. - """ - - def handle(self, context, sign, *args): - return _SignedInfinity[sign] - -class DivisionImpossible(InvalidOperation): - """Cannot perform the division adequately. - - This occurs and signals invalid-operation if the integer result of a - divide-integer or remainder operation had too many digits (would be - longer than precision). The result is [0,qNaN]. - """ - - def handle(self, context, *args): - return _NaN - -class DivisionUndefined(InvalidOperation, ZeroDivisionError): - """Undefined result of division. - - This occurs and signals invalid-operation if division by zero was - attempted (during a divide-integer, divide, or remainder operation), and - the dividend is also zero. The result is [0,qNaN]. - """ - - def handle(self, context, *args): - return _NaN - -class Inexact(DecimalException): - """Had to round, losing information. - - This occurs and signals inexact whenever the result of an operation is - not exact (that is, it needed to be rounded and any discarded digits - were non-zero), or if an overflow or underflow condition occurs. The - result in all cases is unchanged. - - The inexact signal may be tested (or trapped) to determine if a given - operation (or sequence of operations) was inexact. - """ - -class InvalidContext(InvalidOperation): - """Invalid context. Unknown rounding, for example. - - This occurs and signals invalid-operation if an invalid context was - detected during an operation. This can occur if contexts are not checked - on creation and either the precision exceeds the capability of the - underlying concrete representation or an unknown or unsupported rounding - was specified. These aspects of the context need only be checked when - the values are required to be used. The result is [0,qNaN]. - """ - - def handle(self, context, *args): - return _NaN - -class Rounded(DecimalException): - """Number got rounded (not necessarily changed during rounding). - - This occurs and signals rounded whenever the result of an operation is - rounded (that is, some zero or non-zero digits were discarded from the - coefficient), or if an overflow or underflow condition occurs. The - result in all cases is unchanged. - - The rounded signal may be tested (or trapped) to determine if a given - operation (or sequence of operations) caused a loss of precision. - """ - -class Subnormal(DecimalException): - """Exponent < Emin before rounding. - - This occurs and signals subnormal whenever the result of a conversion or - operation is subnormal (that is, its adjusted exponent is less than - Emin, before any rounding). The result in all cases is unchanged. - - The subnormal signal may be tested (or trapped) to determine if a given - or operation (or sequence of operations) yielded a subnormal result. - """ - -class Overflow(Inexact, Rounded): - """Numerical overflow. - - This occurs and signals overflow if the adjusted exponent of a result - (from a conversion or from an operation that is not an attempt to divide - by zero), after rounding, would be greater than the largest value that - can be handled by the implementation (the value Emax). - - The result depends on the rounding mode: - - For round-half-up and round-half-even (and for round-half-down and - round-up, if implemented), the result of the operation is [sign,inf], - where sign is the sign of the intermediate result. For round-down, the - result is the largest finite number that can be represented in the - current precision, with the sign of the intermediate result. For - round-ceiling, the result is the same as for round-down if the sign of - the intermediate result is 1, or is [0,inf] otherwise. For round-floor, - the result is the same as for round-down if the sign of the intermediate - result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded - will also be raised. - """ - - def handle(self, context, sign, *args): - if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN, - ROUND_HALF_DOWN, ROUND_UP): - return _SignedInfinity[sign] - if sign == 0: - if context.rounding == ROUND_CEILING: - return _SignedInfinity[sign] - return _dec_from_triple(sign, '9'*context.prec, - context.Emax-context.prec+1) - if sign == 1: - if context.rounding == ROUND_FLOOR: - return _SignedInfinity[sign] - return _dec_from_triple(sign, '9'*context.prec, - context.Emax-context.prec+1) - - -class Underflow(Inexact, Rounded, Subnormal): - """Numerical underflow with result rounded to 0. - - This occurs and signals underflow if a result is inexact and the - adjusted exponent of the result would be smaller (more negative) than - the smallest value that can be handled by the implementation (the value - Emin). That is, the result is both inexact and subnormal. - - The result after an underflow will be a subnormal number rounded, if - necessary, so that its exponent is not less than Etiny. This may result - in 0 with the sign of the intermediate result and an exponent of Etiny. - - In all cases, Inexact, Rounded, and Subnormal will also be raised. - """ - -class FloatOperation(DecimalException, TypeError): - """Enable stricter semantics for mixing floats and Decimals. - - If the signal is not trapped (default), mixing floats and Decimals is - permitted in the Decimal() constructor, context.create_decimal() and - all comparison operators. Both conversion and comparisons are exact. - Any occurrence of a mixed operation is silently recorded by setting - FloatOperation in the context flags. Explicit conversions with - Decimal.from_float() or context.create_decimal_from_float() do not - set the flag. - - Otherwise (the signal is trapped), only equality comparisons and explicit - conversions are silent. All other mixed operations raise FloatOperation. - """ - -# List of public traps and flags -_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded, - Underflow, InvalidOperation, Subnormal, FloatOperation] - -# Map conditions (per the spec) to signals -_condition_map = {ConversionSyntax:InvalidOperation, - DivisionImpossible:InvalidOperation, - DivisionUndefined:InvalidOperation, - InvalidContext:InvalidOperation} - -# Valid rounding modes -_rounding_modes = (ROUND_DOWN, ROUND_HALF_UP, ROUND_HALF_EVEN, ROUND_CEILING, - ROUND_FLOOR, ROUND_UP, ROUND_HALF_DOWN, ROUND_05UP) - -##### Context Functions ################################################## - -# The getcontext() and setcontext() function manage access to a thread-local -# current context. Py2.4 offers direct support for thread locals. If that -# is not available, use threading.current_thread() which is slower but will -# work for older Pythons. If threads are not part of the build, create a -# mock threading object with threading.local() returning the module namespace. - -try: - import threading -except ImportError: - # Python was compiled without threads; create a mock object instead - class MockThreading(object): - def local(self, sys=sys): - return sys.modules[__name__] - threading = MockThreading() - del MockThreading - -try: - threading.local - -except AttributeError: - - # To fix reloading, force it to create a new context - # Old contexts have different exceptions in their dicts, making problems. - if hasattr(threading.current_thread(), '__decimal_context__'): - del threading.current_thread().__decimal_context__ - - def setcontext(context): - """Set this thread's context to context.""" - if context in (DefaultContext, BasicContext, ExtendedContext): - context = context.copy() - context.clear_flags() - threading.current_thread().__decimal_context__ = context - - def getcontext(): - """Returns this thread's context. - - If this thread does not yet have a context, returns - a new context and sets this thread's context. - New contexts are copies of DefaultContext. - """ - try: - return threading.current_thread().__decimal_context__ - except AttributeError: - context = Context() - threading.current_thread().__decimal_context__ = context - return context - -else: - - local = threading.local() - if hasattr(local, '__decimal_context__'): - del local.__decimal_context__ - - def getcontext(_local=local): - """Returns this thread's context. - - If this thread does not yet have a context, returns - a new context and sets this thread's context. - New contexts are copies of DefaultContext. - """ - try: - return _local.__decimal_context__ - except AttributeError: - context = Context() - _local.__decimal_context__ = context - return context - - def setcontext(context, _local=local): - """Set this thread's context to context.""" - if context in (DefaultContext, BasicContext, ExtendedContext): - context = context.copy() - context.clear_flags() - _local.__decimal_context__ = context - - del threading, local # Don't contaminate the namespace - -def localcontext(ctx=None): - """Return a context manager for a copy of the supplied context - - Uses a copy of the current context if no context is specified - The returned context manager creates a local decimal context - in a with statement: - def sin(x): - with localcontext() as ctx: - ctx.prec += 2 - # Rest of sin calculation algorithm - # uses a precision 2 greater than normal - return +s # Convert result to normal precision - - def sin(x): - with localcontext(ExtendedContext): - # Rest of sin calculation algorithm - # uses the Extended Context from the - # General Decimal Arithmetic Specification - return +s # Convert result to normal context - - >>> setcontext(DefaultContext) - >>> print(getcontext().prec) - 28 - >>> with localcontext(): - ... ctx = getcontext() - ... ctx.prec += 2 - ... print(ctx.prec) - ... - 30 - >>> with localcontext(ExtendedContext): - ... print(getcontext().prec) - ... - 9 - >>> print(getcontext().prec) - 28 - """ - if ctx is None: ctx = getcontext() - return _ContextManager(ctx) - - -##### Decimal class ####################################################### - -# Do not subclass Decimal from numbers.Real and do not register it as such -# (because Decimals are not interoperable with floats). See the notes in -# numbers.py for more detail. - -class Decimal(object): - """Floating point class for decimal arithmetic.""" - - __slots__ = ('_exp','_int','_sign', '_is_special') - # Generally, the value of the Decimal instance is given by - # (-1)**_sign * _int * 10**_exp - # Special values are signified by _is_special == True - - # We're immutable, so use __new__ not __init__ - def __new__(cls, value="0", context=None): - """Create a decimal point instance. - - >>> Decimal('3.14') # string input - Decimal('3.14') - >>> Decimal((0, (3, 1, 4), -2)) # tuple (sign, digit_tuple, exponent) - Decimal('3.14') - >>> Decimal(314) # int - Decimal('314') - >>> Decimal(Decimal(314)) # another decimal instance - Decimal('314') - >>> Decimal(' 3.14 \\n') # leading and trailing whitespace okay - Decimal('3.14') - """ - - # Note that the coefficient, self._int, is actually stored as - # a string rather than as a tuple of digits. This speeds up - # the "digits to integer" and "integer to digits" conversions - # that are used in almost every arithmetic operation on - # Decimals. This is an internal detail: the as_tuple function - # and the Decimal constructor still deal with tuples of - # digits. - - self = object.__new__(cls) - - # From a string - # REs insist on real strings, so we can too. - if isinstance(value, str): - m = _parser(value.strip()) - if m is None: - if context is None: - context = getcontext() - return context._raise_error(ConversionSyntax, - "Invalid literal for Decimal: %r" % value) - - if m.group('sign') == "-": - self._sign = 1 - else: - self._sign = 0 - intpart = m.group('int') - if intpart is not None: - # finite number - fracpart = m.group('frac') or '' - exp = int(m.group('exp') or '0') - self._int = str(int(intpart+fracpart)) - self._exp = exp - len(fracpart) - self._is_special = False - else: - diag = m.group('diag') - if diag is not None: - # NaN - self._int = str(int(diag or '0')).lstrip('0') - if m.group('signal'): - self._exp = 'N' - else: - self._exp = 'n' - else: - # infinity - self._int = '0' - self._exp = 'F' - self._is_special = True - return self - - # From an integer - if isinstance(value, int): - if value >= 0: - self._sign = 0 - else: - self._sign = 1 - self._exp = 0 - self._int = str(abs(value)) - self._is_special = False - return self - - # From another decimal - if isinstance(value, Decimal): - self._exp = value._exp - self._sign = value._sign - self._int = value._int - self._is_special = value._is_special - return self - - # From an internal working value - if isinstance(value, _WorkRep): - self._sign = value.sign - self._int = str(value.int) - self._exp = int(value.exp) - self._is_special = False - return self - - # tuple/list conversion (possibly from as_tuple()) - if isinstance(value, (list,tuple)): - if len(value) != 3: - raise ValueError('Invalid tuple size in creation of Decimal ' - 'from list or tuple. The list or tuple ' - 'should have exactly three elements.') - # process sign. The isinstance test rejects floats - if not (isinstance(value[0], int) and value[0] in (0,1)): - raise ValueError("Invalid sign. The first value in the tuple " - "should be an integer; either 0 for a " - "positive number or 1 for a negative number.") - self._sign = value[0] - if value[2] == 'F': - # infinity: value[1] is ignored - self._int = '0' - self._exp = value[2] - self._is_special = True - else: - # process and validate the digits in value[1] - digits = [] - for digit in value[1]: - if isinstance(digit, int) and 0 <= digit <= 9: - # skip leading zeros - if digits or digit != 0: - digits.append(digit) - else: - raise ValueError("The second value in the tuple must " - "be composed of integers in the range " - "0 through 9.") - if value[2] in ('n', 'N'): - # NaN: digits form the diagnostic - self._int = ''.join(map(str, digits)) - self._exp = value[2] - self._is_special = True - elif isinstance(value[2], int): - # finite number: digits give the coefficient - self._int = ''.join(map(str, digits or [0])) - self._exp = value[2] - self._is_special = False - else: - raise ValueError("The third value in the tuple must " - "be an integer, or one of the " - "strings 'F', 'n', 'N'.") - return self - - if isinstance(value, float): - if context is None: - context = getcontext() - context._raise_error(FloatOperation, - "strict semantics for mixing floats and Decimals are " - "enabled") - value = Decimal.from_float(value) - self._exp = value._exp - self._sign = value._sign - self._int = value._int - self._is_special = value._is_special - return self - - raise TypeError("Cannot convert %r to Decimal" % value) - - @classmethod - def from_float(cls, f): - """Converts a float to a decimal number, exactly. - - Note that Decimal.from_float(0.1) is not the same as Decimal('0.1'). - Since 0.1 is not exactly representable in binary floating point, the - value is stored as the nearest representable value which is - 0x1.999999999999ap-4. The exact equivalent of the value in decimal - is 0.1000000000000000055511151231257827021181583404541015625. - - >>> Decimal.from_float(0.1) - Decimal('0.1000000000000000055511151231257827021181583404541015625') - >>> Decimal.from_float(float('nan')) - Decimal('NaN') - >>> Decimal.from_float(float('inf')) - Decimal('Infinity') - >>> Decimal.from_float(-float('inf')) - Decimal('-Infinity') - >>> Decimal.from_float(-0.0) - Decimal('-0') - - """ - if isinstance(f, int): # handle integer inputs - return cls(f) - if not isinstance(f, float): - raise TypeError("argument must be int or float.") - if _math.isinf(f) or _math.isnan(f): - return cls(repr(f)) - if _math.copysign(1.0, f) == 1.0: - sign = 0 - else: - sign = 1 - n, d = abs(f).as_integer_ratio() - k = d.bit_length() - 1 - result = _dec_from_triple(sign, str(n*5**k), -k) - if cls is Decimal: - return result - else: - return cls(result) - - def _isnan(self): - """Returns whether the number is not actually one. - - 0 if a number - 1 if NaN - 2 if sNaN - """ - if self._is_special: - exp = self._exp - if exp == 'n': - return 1 - elif exp == 'N': - return 2 - return 0 - - def _isinfinity(self): - """Returns whether the number is infinite - - 0 if finite or not a number - 1 if +INF - -1 if -INF - """ - if self._exp == 'F': - if self._sign: - return -1 - return 1 - return 0 - - def _check_nans(self, other=None, context=None): - """Returns whether the number is not actually one. - - if self, other are sNaN, signal - if self, other are NaN return nan - return 0 - - Done before operations. - """ - - self_is_nan = self._isnan() - if other is None: - other_is_nan = False - else: - other_is_nan = other._isnan() - - if self_is_nan or other_is_nan: - if context is None: - context = getcontext() - - if self_is_nan == 2: - return context._raise_error(InvalidOperation, 'sNaN', - self) - if other_is_nan == 2: - return context._raise_error(InvalidOperation, 'sNaN', - other) - if self_is_nan: - return self._fix_nan(context) - - return other._fix_nan(context) - return 0 - - def _compare_check_nans(self, other, context): - """Version of _check_nans used for the signaling comparisons - compare_signal, __le__, __lt__, __ge__, __gt__. - - Signal InvalidOperation if either self or other is a (quiet - or signaling) NaN. Signaling NaNs take precedence over quiet - NaNs. - - Return 0 if neither operand is a NaN. - - """ - if context is None: - context = getcontext() - - if self._is_special or other._is_special: - if self.is_snan(): - return context._raise_error(InvalidOperation, - 'comparison involving sNaN', - self) - elif other.is_snan(): - return context._raise_error(InvalidOperation, - 'comparison involving sNaN', - other) - elif self.is_qnan(): - return context._raise_error(InvalidOperation, - 'comparison involving NaN', - self) - elif other.is_qnan(): - return context._raise_error(InvalidOperation, - 'comparison involving NaN', - other) - return 0 - - def __bool__(self): - """Return True if self is nonzero; otherwise return False. - - NaNs and infinities are considered nonzero. - """ - return self._is_special or self._int != '0' - - def _cmp(self, other): - """Compare the two non-NaN decimal instances self and other. - - Returns -1 if self < other, 0 if self == other and 1 - if self > other. This routine is for internal use only.""" - - if self._is_special or other._is_special: - self_inf = self._isinfinity() - other_inf = other._isinfinity() - if self_inf == other_inf: - return 0 - elif self_inf < other_inf: - return -1 - else: - return 1 - - # check for zeros; Decimal('0') == Decimal('-0') - if not self: - if not other: - return 0 - else: - return -((-1)**other._sign) - if not other: - return (-1)**self._sign - - # If different signs, neg one is less - if other._sign < self._sign: - return -1 - if self._sign < other._sign: - return 1 - - self_adjusted = self.adjusted() - other_adjusted = other.adjusted() - if self_adjusted == other_adjusted: - self_padded = self._int + '0'*(self._exp - other._exp) - other_padded = other._int + '0'*(other._exp - self._exp) - if self_padded == other_padded: - return 0 - elif self_padded < other_padded: - return -(-1)**self._sign - else: - return (-1)**self._sign - elif self_adjusted > other_adjusted: - return (-1)**self._sign - else: # self_adjusted < other_adjusted - return -((-1)**self._sign) - - # Note: The Decimal standard doesn't cover rich comparisons for - # Decimals. In particular, the specification is silent on the - # subject of what should happen for a comparison involving a NaN. - # We take the following approach: - # - # == comparisons involving a quiet NaN always return False - # != comparisons involving a quiet NaN always return True - # == or != comparisons involving a signaling NaN signal - # InvalidOperation, and return False or True as above if the - # InvalidOperation is not trapped. - # <, >, <= and >= comparisons involving a (quiet or signaling) - # NaN signal InvalidOperation, and return False if the - # InvalidOperation is not trapped. - # - # This behavior is designed to conform as closely as possible to - # that specified by IEEE 754. - - def __eq__(self, other, context=None): - self, other = _convert_for_comparison(self, other, equality_op=True) - if other is NotImplemented: - return other - if self._check_nans(other, context): - return False - return self._cmp(other) == 0 - - def __ne__(self, other, context=None): - self, other = _convert_for_comparison(self, other, equality_op=True) - if other is NotImplemented: - return other - if self._check_nans(other, context): - return True - return self._cmp(other) != 0 - - - def __lt__(self, other, context=None): - self, other = _convert_for_comparison(self, other) - if other is NotImplemented: - return other - ans = self._compare_check_nans(other, context) - if ans: - return False - return self._cmp(other) < 0 - - def __le__(self, other, context=None): - self, other = _convert_for_comparison(self, other) - if other is NotImplemented: - return other - ans = self._compare_check_nans(other, context) - if ans: - return False - return self._cmp(other) <= 0 - - def __gt__(self, other, context=None): - self, other = _convert_for_comparison(self, other) - if other is NotImplemented: - return other - ans = self._compare_check_nans(other, context) - if ans: - return False - return self._cmp(other) > 0 - - def __ge__(self, other, context=None): - self, other = _convert_for_comparison(self, other) - if other is NotImplemented: - return other - ans = self._compare_check_nans(other, context) - if ans: - return False - return self._cmp(other) >= 0 - - def compare(self, other, context=None): - """Compares one to another. - - -1 => a < b - 0 => a = b - 1 => a > b - NaN => one is NaN - Like __cmp__, but returns Decimal instances. - """ - other = _convert_other(other, raiseit=True) - - # Compare(NaN, NaN) = NaN - if (self._is_special or other and other._is_special): - ans = self._check_nans(other, context) - if ans: - return ans - - return Decimal(self._cmp(other)) - - def __hash__(self): - """x.__hash__() <==> hash(x)""" - - # In order to make sure that the hash of a Decimal instance - # agrees with the hash of a numerically equal integer, float - # or Fraction, we follow the rules for numeric hashes outlined - # in the documentation. (See library docs, 'Built-in Types'). - if self._is_special: - if self.is_snan(): - raise TypeError('Cannot hash a signaling NaN value.') - elif self.is_nan(): - return _PyHASH_NAN - else: - if self._sign: - return -_PyHASH_INF - else: - return _PyHASH_INF - - if self._exp >= 0: - exp_hash = pow(10, self._exp, _PyHASH_MODULUS) - else: - exp_hash = pow(_PyHASH_10INV, -self._exp, _PyHASH_MODULUS) - hash_ = int(self._int) * exp_hash % _PyHASH_MODULUS - ans = hash_ if self >= 0 else -hash_ - return -2 if ans == -1 else ans - - def as_tuple(self): - """Represents the number as a triple tuple. - - To show the internals exactly as they are. - """ - return DecimalTuple(self._sign, tuple(map(int, self._int)), self._exp) - - def __repr__(self): - """Represents the number as an instance of Decimal.""" - # Invariant: eval(repr(d)) == d - return "Decimal('%s')" % str(self) - - def __str__(self, eng=False, context=None): - """Return string representation of the number in scientific notation. - - Captures all of the information in the underlying representation. - """ - - sign = ['', '-'][self._sign] - if self._is_special: - if self._exp == 'F': - return sign + 'Infinity' - elif self._exp == 'n': - return sign + 'NaN' + self._int - else: # self._exp == 'N' - return sign + 'sNaN' + self._int - - # number of digits of self._int to left of decimal point - leftdigits = self._exp + len(self._int) - - # dotplace is number of digits of self._int to the left of the - # decimal point in the mantissa of the output string (that is, - # after adjusting the exponent) - if self._exp <= 0 and leftdigits > -6: - # no exponent required - dotplace = leftdigits - elif not eng: - # usual scientific notation: 1 digit on left of the point - dotplace = 1 - elif self._int == '0': - # engineering notation, zero - dotplace = (leftdigits + 1) % 3 - 1 - else: - # engineering notation, nonzero - dotplace = (leftdigits - 1) % 3 + 1 - - if dotplace <= 0: - intpart = '0' - fracpart = '.' + '0'*(-dotplace) + self._int - elif dotplace >= len(self._int): - intpart = self._int+'0'*(dotplace-len(self._int)) - fracpart = '' - else: - intpart = self._int[:dotplace] - fracpart = '.' + self._int[dotplace:] - if leftdigits == dotplace: - exp = '' - else: - if context is None: - context = getcontext() - exp = ['e', 'E'][context.capitals] + "%+d" % (leftdigits-dotplace) - - return sign + intpart + fracpart + exp - - def to_eng_string(self, context=None): - """Convert to engineering-type string. - - Engineering notation has an exponent which is a multiple of 3, so there - are up to 3 digits left of the decimal place. - - Same rules for when in exponential and when as a value as in __str__. - """ - return self.__str__(eng=True, context=context) - - def __neg__(self, context=None): - """Returns a copy with the sign switched. - - Rounds, if it has reason. - """ - if self._is_special: - ans = self._check_nans(context=context) - if ans: - return ans - - if context is None: - context = getcontext() - - if not self and context.rounding != ROUND_FLOOR: - # -Decimal('0') is Decimal('0'), not Decimal('-0'), except - # in ROUND_FLOOR rounding mode. - ans = self.copy_abs() - else: - ans = self.copy_negate() - - return ans._fix(context) - - def __pos__(self, context=None): - """Returns a copy, unless it is a sNaN. - - Rounds the number (if more then precision digits) - """ - if self._is_special: - ans = self._check_nans(context=context) - if ans: - return ans - - if context is None: - context = getcontext() - - if not self and context.rounding != ROUND_FLOOR: - # + (-0) = 0, except in ROUND_FLOOR rounding mode. - ans = self.copy_abs() - else: - ans = Decimal(self) - - return ans._fix(context) - - def __abs__(self, round=True, context=None): - """Returns the absolute value of self. - - If the keyword argument 'round' is false, do not round. The - expression self.__abs__(round=False) is equivalent to - self.copy_abs(). - """ - if not round: - return self.copy_abs() - - if self._is_special: - ans = self._check_nans(context=context) - if ans: - return ans - - if self._sign: - ans = self.__neg__(context=context) - else: - ans = self.__pos__(context=context) - - return ans - - def __add__(self, other, context=None): - """Returns self + other. - - -INF + INF (or the reverse) cause InvalidOperation errors. - """ - other = _convert_other(other) - if other is NotImplemented: - return other - - if context is None: - context = getcontext() - - if self._is_special or other._is_special: - ans = self._check_nans(other, context) - if ans: - return ans - - if self._isinfinity(): - # If both INF, same sign => same as both, opposite => error. - if self._sign != other._sign and other._isinfinity(): - return context._raise_error(InvalidOperation, '-INF + INF') - return Decimal(self) - if other._isinfinity(): - return Decimal(other) # Can't both be infinity here - - exp = min(self._exp, other._exp) - negativezero = 0 - if context.rounding == ROUND_FLOOR and self._sign != other._sign: - # If the answer is 0, the sign should be negative, in this case. - negativezero = 1 - - if not self and not other: - sign = min(self._sign, other._sign) - if negativezero: - sign = 1 - ans = _dec_from_triple(sign, '0', exp) - ans = ans._fix(context) - return ans - if not self: - exp = max(exp, other._exp - context.prec-1) - ans = other._rescale(exp, context.rounding) - ans = ans._fix(context) - return ans - if not other: - exp = max(exp, self._exp - context.prec-1) - ans = self._rescale(exp, context.rounding) - ans = ans._fix(context) - return ans - - op1 = _WorkRep(self) - op2 = _WorkRep(other) - op1, op2 = _normalize(op1, op2, context.prec) - - result = _WorkRep() - if op1.sign != op2.sign: - # Equal and opposite - if op1.int == op2.int: - ans = _dec_from_triple(negativezero, '0', exp) - ans = ans._fix(context) - return ans - if op1.int < op2.int: - op1, op2 = op2, op1 - # OK, now abs(op1) > abs(op2) - if op1.sign == 1: - result.sign = 1 - op1.sign, op2.sign = op2.sign, op1.sign - else: - result.sign = 0 - # So we know the sign, and op1 > 0. - elif op1.sign == 1: - result.sign = 1 - op1.sign, op2.sign = (0, 0) - else: - result.sign = 0 - # Now, op1 > abs(op2) > 0 - - if op2.sign == 0: - result.int = op1.int + op2.int - else: - result.int = op1.int - op2.int - - result.exp = op1.exp - ans = Decimal(result) - ans = ans._fix(context) - return ans - - __radd__ = __add__ - - def __sub__(self, other, context=None): - """Return self - other""" - other = _convert_other(other) - if other is NotImplemented: - return other - - if self._is_special or other._is_special: - ans = self._check_nans(other, context=context) - if ans: - return ans - - # self - other is computed as self + other.copy_negate() - return self.__add__(other.copy_negate(), context=context) - - def __rsub__(self, other, context=None): - """Return other - self""" - other = _convert_other(other) - if other is NotImplemented: - return other - - return other.__sub__(self, context=context) - - def __mul__(self, other, context=None): - """Return self * other. - - (+-) INF * 0 (or its reverse) raise InvalidOperation. - """ - other = _convert_other(other) - if other is NotImplemented: - return other - - if context is None: - context = getcontext() - - resultsign = self._sign ^ other._sign - - if self._is_special or other._is_special: - ans = self._check_nans(other, context) - if ans: - return ans - - if self._isinfinity(): - if not other: - return context._raise_error(InvalidOperation, '(+-)INF * 0') - return _SignedInfinity[resultsign] - - if other._isinfinity(): - if not self: - return context._raise_error(InvalidOperation, '0 * (+-)INF') - return _SignedInfinity[resultsign] - - resultexp = self._exp + other._exp - - # Special case for multiplying by zero - if not self or not other: - ans = _dec_from_triple(resultsign, '0', resultexp) - # Fixing in case the exponent is out of bounds - ans = ans._fix(context) - return ans - - # Special case for multiplying by power of 10 - if self._int == '1': - ans = _dec_from_triple(resultsign, other._int, resultexp) - ans = ans._fix(context) - return ans - if other._int == '1': - ans = _dec_from_triple(resultsign, self._int, resultexp) - ans = ans._fix(context) - return ans - - op1 = _WorkRep(self) - op2 = _WorkRep(other) - - ans = _dec_from_triple(resultsign, str(op1.int * op2.int), resultexp) - ans = ans._fix(context) - - return ans - __rmul__ = __mul__ - - def __truediv__(self, other, context=None): - """Return self / other.""" - other = _convert_other(other) - if other is NotImplemented: - return NotImplemented - - if context is None: - context = getcontext() - - sign = self._sign ^ other._sign - - if self._is_special or other._is_special: - ans = self._check_nans(other, context) - if ans: - return ans - - if self._isinfinity() and other._isinfinity(): - return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF') - - if self._isinfinity(): - return _SignedInfinity[sign] - - if other._isinfinity(): - context._raise_error(Clamped, 'Division by infinity') - return _dec_from_triple(sign, '0', context.Etiny()) - - # Special cases for zeroes - if not other: - if not self: - return context._raise_error(DivisionUndefined, '0 / 0') - return context._raise_error(DivisionByZero, 'x / 0', sign) - - if not self: - exp = self._exp - other._exp - coeff = 0 - else: - # OK, so neither = 0, INF or NaN - shift = len(other._int) - len(self._int) + context.prec + 1 - exp = self._exp - other._exp - shift - op1 = _WorkRep(self) - op2 = _WorkRep(other) - if shift >= 0: - coeff, remainder = divmod(op1.int * 10**shift, op2.int) - else: - coeff, remainder = divmod(op1.int, op2.int * 10**-shift) - if remainder: - # result is not exact; adjust to ensure correct rounding - if coeff % 5 == 0: - coeff += 1 - else: - # result is exact; get as close to ideal exponent as possible - ideal_exp = self._exp - other._exp - while exp < ideal_exp and coeff % 10 == 0: - coeff //= 10 - exp += 1 - - ans = _dec_from_triple(sign, str(coeff), exp) - return ans._fix(context) - - def _divide(self, other, context): - """Return (self // other, self % other), to context.prec precision. - - Assumes that neither self nor other is a NaN, that self is not - infinite and that other is nonzero. - """ - sign = self._sign ^ other._sign - if other._isinfinity(): - ideal_exp = self._exp - else: - ideal_exp = min(self._exp, other._exp) - - expdiff = self.adjusted() - other.adjusted() - if not self or other._isinfinity() or expdiff <= -2: - return (_dec_from_triple(sign, '0', 0), - self._rescale(ideal_exp, context.rounding)) - if expdiff <= context.prec: - op1 = _WorkRep(self) - op2 = _WorkRep(other) - if op1.exp >= op2.exp: - op1.int *= 10**(op1.exp - op2.exp) - else: - op2.int *= 10**(op2.exp - op1.exp) - q, r = divmod(op1.int, op2.int) - if q < 10**context.prec: - return (_dec_from_triple(sign, str(q), 0), - _dec_from_triple(self._sign, str(r), ideal_exp)) - - # Here the quotient is too large to be representable - ans = context._raise_error(DivisionImpossible, - 'quotient too large in //, % or divmod') - return ans, ans - - def __rtruediv__(self, other, context=None): - """Swaps self/other and returns __truediv__.""" - other = _convert_other(other) - if other is NotImplemented: - return other - return other.__truediv__(self, context=context) - - def __divmod__(self, other, context=None): - """ - Return (self // other, self % other) - """ - other = _convert_other(other) - if other is NotImplemented: - return other - - if context is None: - context = getcontext() - - ans = self._check_nans(other, context) - if ans: - return (ans, ans) - - sign = self._sign ^ other._sign - if self._isinfinity(): - if other._isinfinity(): - ans = context._raise_error(InvalidOperation, 'divmod(INF, INF)') - return ans, ans - else: - return (_SignedInfinity[sign], - context._raise_error(InvalidOperation, 'INF % x')) - - if not other: - if not self: - ans = context._raise_error(DivisionUndefined, 'divmod(0, 0)') - return ans, ans - else: - return (context._raise_error(DivisionByZero, 'x // 0', sign), - context._raise_error(InvalidOperation, 'x % 0')) - - quotient, remainder = self._divide(other, context) - remainder = remainder._fix(context) - return quotient, remainder - - def __rdivmod__(self, other, context=None): - """Swaps self/other and returns __divmod__.""" - other = _convert_other(other) - if other is NotImplemented: - return other - return other.__divmod__(self, context=context) - - def __mod__(self, other, context=None): - """ - self % other - """ - other = _convert_other(other) - if other is NotImplemented: - return other - - if context is None: - context = getcontext() - - ans = self._check_nans(other, context) - if ans: - return ans - - if self._isinfinity(): - return context._raise_error(InvalidOperation, 'INF % x') - elif not other: - if self: - return context._raise_error(InvalidOperation, 'x % 0') - else: - return context._raise_error(DivisionUndefined, '0 % 0') - - remainder = self._divide(other, context)[1] - remainder = remainder._fix(context) - return remainder - - def __rmod__(self, other, context=None): - """Swaps self/other and returns __mod__.""" - other = _convert_other(other) - if other is NotImplemented: - return other - return other.__mod__(self, context=context) - - def remainder_near(self, other, context=None): - """ - Remainder nearest to 0- abs(remainder-near) <= other/2 - """ - if context is None: - context = getcontext() - - other = _convert_other(other, raiseit=True) - - ans = self._check_nans(other, context) - if ans: - return ans - - # self == +/-infinity -> InvalidOperation - if self._isinfinity(): - return context._raise_error(InvalidOperation, - 'remainder_near(infinity, x)') - - # other == 0 -> either InvalidOperation or DivisionUndefined - if not other: - if self: - return context._raise_error(InvalidOperation, - 'remainder_near(x, 0)') - else: - return context._raise_error(DivisionUndefined, - 'remainder_near(0, 0)') - - # other = +/-infinity -> remainder = self - if other._isinfinity(): - ans = Decimal(self) - return ans._fix(context) - - # self = 0 -> remainder = self, with ideal exponent - ideal_exponent = min(self._exp, other._exp) - if not self: - ans = _dec_from_triple(self._sign, '0', ideal_exponent) - return ans._fix(context) - - # catch most cases of large or small quotient - expdiff = self.adjusted() - other.adjusted() - if expdiff >= context.prec + 1: - # expdiff >= prec+1 => abs(self/other) > 10**prec - return context._raise_error(DivisionImpossible) - if expdiff <= -2: - # expdiff <= -2 => abs(self/other) < 0.1 - ans = self._rescale(ideal_exponent, context.rounding) - return ans._fix(context) - - # adjust both arguments to have the same exponent, then divide - op1 = _WorkRep(self) - op2 = _WorkRep(other) - if op1.exp >= op2.exp: - op1.int *= 10**(op1.exp - op2.exp) - else: - op2.int *= 10**(op2.exp - op1.exp) - q, r = divmod(op1.int, op2.int) - # remainder is r*10**ideal_exponent; other is +/-op2.int * - # 10**ideal_exponent. Apply correction to ensure that - # abs(remainder) <= abs(other)/2 - if 2*r + (q&1) > op2.int: - r -= op2.int - q += 1 - - if q >= 10**context.prec: - return context._raise_error(DivisionImpossible) - - # result has same sign as self unless r is negative - sign = self._sign - if r < 0: - sign = 1-sign - r = -r - - ans = _dec_from_triple(sign, str(r), ideal_exponent) - return ans._fix(context) - - def __floordiv__(self, other, context=None): - """self // other""" - other = _convert_other(other) - if other is NotImplemented: - return other - - if context is None: - context = getcontext() - - ans = self._check_nans(other, context) - if ans: - return ans - - if self._isinfinity(): - if other._isinfinity(): - return context._raise_error(InvalidOperation, 'INF // INF') - else: - return _SignedInfinity[self._sign ^ other._sign] - - if not other: - if self: - return context._raise_error(DivisionByZero, 'x // 0', - self._sign ^ other._sign) - else: - return context._raise_error(DivisionUndefined, '0 // 0') - - return self._divide(other, context)[0] - - def __rfloordiv__(self, other, context=None): - """Swaps self/other and returns __floordiv__.""" - other = _convert_other(other) - if other is NotImplemented: - return other - return other.__floordiv__(self, context=context) - - def __float__(self): - """Float representation.""" - if self._isnan(): - if self.is_snan(): - raise ValueError("Cannot convert signaling NaN to float") - s = "-nan" if self._sign else "nan" - else: - s = str(self) - return float(s) - - def __int__(self): - """Converts self to an int, truncating if necessary.""" - if self._is_special: - if self._isnan(): - raise ValueError("Cannot convert NaN to integer") - elif self._isinfinity(): - raise OverflowError("Cannot convert infinity to integer") - s = (-1)**self._sign - if self._exp >= 0: - return s*int(self._int)*10**self._exp - else: - return s*int(self._int[:self._exp] or '0') - - __trunc__ = __int__ - - def real(self): - return self - real = property(real) - - def imag(self): - return Decimal(0) - imag = property(imag) - - def conjugate(self): - return self - - def __complex__(self): - return complex(float(self)) - - def _fix_nan(self, context): - """Decapitate the payload of a NaN to fit the context""" - payload = self._int - - # maximum length of payload is precision if clamp=0, - # precision-1 if clamp=1. - max_payload_len = context.prec - context.clamp - if len(payload) > max_payload_len: - payload = payload[len(payload)-max_payload_len:].lstrip('0') - return _dec_from_triple(self._sign, payload, self._exp, True) - return Decimal(self) - - def _fix(self, context): - """Round if it is necessary to keep self within prec precision. - - Rounds and fixes the exponent. Does not raise on a sNaN. - - Arguments: - self - Decimal instance - context - context used. - """ - - if self._is_special: - if self._isnan(): - # decapitate payload if necessary - return self._fix_nan(context) - else: - # self is +/-Infinity; return unaltered - return Decimal(self) - - # if self is zero then exponent should be between Etiny and - # Emax if clamp==0, and between Etiny and Etop if clamp==1. - Etiny = context.Etiny() - Etop = context.Etop() - if not self: - exp_max = [context.Emax, Etop][context.clamp] - new_exp = min(max(self._exp, Etiny), exp_max) - if new_exp != self._exp: - context._raise_error(Clamped) - return _dec_from_triple(self._sign, '0', new_exp) - else: - return Decimal(self) - - # exp_min is the smallest allowable exponent of the result, - # equal to max(self.adjusted()-context.prec+1, Etiny) - exp_min = len(self._int) + self._exp - context.prec - if exp_min > Etop: - # overflow: exp_min > Etop iff self.adjusted() > Emax - ans = context._raise_error(Overflow, 'above Emax', self._sign) - context._raise_error(Inexact) - context._raise_error(Rounded) - return ans - - self_is_subnormal = exp_min < Etiny - if self_is_subnormal: - exp_min = Etiny - - # round if self has too many digits - if self._exp < exp_min: - digits = len(self._int) + self._exp - exp_min - if digits < 0: - self = _dec_from_triple(self._sign, '1', exp_min-1) - digits = 0 - rounding_method = self._pick_rounding_function[context.rounding] - changed = rounding_method(self, digits) - coeff = self._int[:digits] or '0' - if changed > 0: - coeff = str(int(coeff)+1) - if len(coeff) > context.prec: - coeff = coeff[:-1] - exp_min += 1 - - # check whether the rounding pushed the exponent out of range - if exp_min > Etop: - ans = context._raise_error(Overflow, 'above Emax', self._sign) - else: - ans = _dec_from_triple(self._sign, coeff, exp_min) - - # raise the appropriate signals, taking care to respect - # the precedence described in the specification - if changed and self_is_subnormal: - context._raise_error(Underflow) - if self_is_subnormal: - context._raise_error(Subnormal) - if changed: - context._raise_error(Inexact) - context._raise_error(Rounded) - if not ans: - # raise Clamped on underflow to 0 - context._raise_error(Clamped) - return ans - - if self_is_subnormal: - context._raise_error(Subnormal) - - # fold down if clamp == 1 and self has too few digits - if context.clamp == 1 and self._exp > Etop: - context._raise_error(Clamped) - self_padded = self._int + '0'*(self._exp - Etop) - return _dec_from_triple(self._sign, self_padded, Etop) - - # here self was representable to begin with; return unchanged - return Decimal(self) - - # for each of the rounding functions below: - # self is a finite, nonzero Decimal - # prec is an integer satisfying 0 <= prec < len(self._int) - # - # each function returns either -1, 0, or 1, as follows: - # 1 indicates that self should be rounded up (away from zero) - # 0 indicates that self should be truncated, and that all the - # digits to be truncated are zeros (so the value is unchanged) - # -1 indicates that there are nonzero digits to be truncated - - def _round_down(self, prec): - """Also known as round-towards-0, truncate.""" - if _all_zeros(self._int, prec): - return 0 - else: - return -1 - - def _round_up(self, prec): - """Rounds away from 0.""" - return -self._round_down(prec) - - def _round_half_up(self, prec): - """Rounds 5 up (away from 0)""" - if self._int[prec] in '56789': - return 1 - elif _all_zeros(self._int, prec): - return 0 - else: - return -1 - - def _round_half_down(self, prec): - """Round 5 down""" - if _exact_half(self._int, prec): - return -1 - else: - return self._round_half_up(prec) - - def _round_half_even(self, prec): - """Round 5 to even, rest to nearest.""" - if _exact_half(self._int, prec) and \ - (prec == 0 or self._int[prec-1] in '02468'): - return -1 - else: - return self._round_half_up(prec) - - def _round_ceiling(self, prec): - """Rounds up (not away from 0 if negative.)""" - if self._sign: - return self._round_down(prec) - else: - return -self._round_down(prec) - - def _round_floor(self, prec): - """Rounds down (not towards 0 if negative)""" - if not self._sign: - return self._round_down(prec) - else: - return -self._round_down(prec) - - def _round_05up(self, prec): - """Round down unless digit prec-1 is 0 or 5.""" - if prec and self._int[prec-1] not in '05': - return self._round_down(prec) - else: - return -self._round_down(prec) - - _pick_rounding_function = dict( - ROUND_DOWN = _round_down, - ROUND_UP = _round_up, - ROUND_HALF_UP = _round_half_up, - ROUND_HALF_DOWN = _round_half_down, - ROUND_HALF_EVEN = _round_half_even, - ROUND_CEILING = _round_ceiling, - ROUND_FLOOR = _round_floor, - ROUND_05UP = _round_05up, - ) - - def __round__(self, n=None): - """Round self to the nearest integer, or to a given precision. - - If only one argument is supplied, round a finite Decimal - instance self to the nearest integer. If self is infinite or - a NaN then a Python exception is raised. If self is finite - and lies exactly halfway between two integers then it is - rounded to the integer with even last digit. - - >>> round(Decimal('123.456')) - 123 - >>> round(Decimal('-456.789')) - -457 - >>> round(Decimal('-3.0')) - -3 - >>> round(Decimal('2.5')) - 2 - >>> round(Decimal('3.5')) - 4 - >>> round(Decimal('Inf')) - Traceback (most recent call last): - ... - OverflowError: cannot round an infinity - >>> round(Decimal('NaN')) - Traceback (most recent call last): - ... - ValueError: cannot round a NaN - - If a second argument n is supplied, self is rounded to n - decimal places using the rounding mode for the current - context. - - For an integer n, round(self, -n) is exactly equivalent to - self.quantize(Decimal('1En')). - - >>> round(Decimal('123.456'), 0) - Decimal('123') - >>> round(Decimal('123.456'), 2) - Decimal('123.46') - >>> round(Decimal('123.456'), -2) - Decimal('1E+2') - >>> round(Decimal('-Infinity'), 37) - Decimal('NaN') - >>> round(Decimal('sNaN123'), 0) - Decimal('NaN123') - - """ - if n is not None: - # two-argument form: use the equivalent quantize call - if not isinstance(n, int): - raise TypeError('Second argument to round should be integral') - exp = _dec_from_triple(0, '1', -n) - return self.quantize(exp) - - # one-argument form - if self._is_special: - if self.is_nan(): - raise ValueError("cannot round a NaN") - else: - raise OverflowError("cannot round an infinity") - return int(self._rescale(0, ROUND_HALF_EVEN)) - - def __floor__(self): - """Return the floor of self, as an integer. - - For a finite Decimal instance self, return the greatest - integer n such that n <= self. If self is infinite or a NaN - then a Python exception is raised. - - """ - if self._is_special: - if self.is_nan(): - raise ValueError("cannot round a NaN") - else: - raise OverflowError("cannot round an infinity") - return int(self._rescale(0, ROUND_FLOOR)) - - def __ceil__(self): - """Return the ceiling of self, as an integer. - - For a finite Decimal instance self, return the least integer n - such that n >= self. If self is infinite or a NaN then a - Python exception is raised. - - """ - if self._is_special: - if self.is_nan(): - raise ValueError("cannot round a NaN") - else: - raise OverflowError("cannot round an infinity") - return int(self._rescale(0, ROUND_CEILING)) - - def fma(self, other, third, context=None): - """Fused multiply-add. - - Returns self*other+third with no rounding of the intermediate - product self*other. - - self and other are multiplied together, with no rounding of - the result. The third operand is then added to the result, - and a single final rounding is performed. - """ - - other = _convert_other(other, raiseit=True) - third = _convert_other(third, raiseit=True) - - # compute product; raise InvalidOperation if either operand is - # a signaling NaN or if the product is zero times infinity. - if self._is_special or other._is_special: - if context is None: - context = getcontext() - if self._exp == 'N': - return context._raise_error(InvalidOperation, 'sNaN', self) - if other._exp == 'N': - return context._raise_error(InvalidOperation, 'sNaN', other) - if self._exp == 'n': - product = self - elif other._exp == 'n': - product = other - elif self._exp == 'F': - if not other: - return context._raise_error(InvalidOperation, - 'INF * 0 in fma') - product = _SignedInfinity[self._sign ^ other._sign] - elif other._exp == 'F': - if not self: - return context._raise_error(InvalidOperation, - '0 * INF in fma') - product = _SignedInfinity[self._sign ^ other._sign] - else: - product = _dec_from_triple(self._sign ^ other._sign, - str(int(self._int) * int(other._int)), - self._exp + other._exp) - - return product.__add__(third, context) - - def _power_modulo(self, other, modulo, context=None): - """Three argument version of __pow__""" - - other = _convert_other(other) - if other is NotImplemented: - return other - modulo = _convert_other(modulo) - if modulo is NotImplemented: - return modulo - - if context is None: - context = getcontext() - - # deal with NaNs: if there are any sNaNs then first one wins, - # (i.e. behaviour for NaNs is identical to that of fma) - self_is_nan = self._isnan() - other_is_nan = other._isnan() - modulo_is_nan = modulo._isnan() - if self_is_nan or other_is_nan or modulo_is_nan: - if self_is_nan == 2: - return context._raise_error(InvalidOperation, 'sNaN', - self) - if other_is_nan == 2: - return context._raise_error(InvalidOperation, 'sNaN', - other) - if modulo_is_nan == 2: - return context._raise_error(InvalidOperation, 'sNaN', - modulo) - if self_is_nan: - return self._fix_nan(context) - if other_is_nan: - return other._fix_nan(context) - return modulo._fix_nan(context) - - # check inputs: we apply same restrictions as Python's pow() - if not (self._isinteger() and - other._isinteger() and - modulo._isinteger()): - return context._raise_error(InvalidOperation, - 'pow() 3rd argument not allowed ' - 'unless all arguments are integers') - if other < 0: - return context._raise_error(InvalidOperation, - 'pow() 2nd argument cannot be ' - 'negative when 3rd argument specified') - if not modulo: - return context._raise_error(InvalidOperation, - 'pow() 3rd argument cannot be 0') - - # additional restriction for decimal: the modulus must be less - # than 10**prec in absolute value - if modulo.adjusted() >= context.prec: - return context._raise_error(InvalidOperation, - 'insufficient precision: pow() 3rd ' - 'argument must not have more than ' - 'precision digits') - - # define 0**0 == NaN, for consistency with two-argument pow - # (even though it hurts!) - if not other and not self: - return context._raise_error(InvalidOperation, - 'at least one of pow() 1st argument ' - 'and 2nd argument must be nonzero ;' - '0**0 is not defined') - - # compute sign of result - if other._iseven(): - sign = 0 - else: - sign = self._sign - - # convert modulo to a Python integer, and self and other to - # Decimal integers (i.e. force their exponents to be >= 0) - modulo = abs(int(modulo)) - base = _WorkRep(self.to_integral_value()) - exponent = _WorkRep(other.to_integral_value()) - - # compute result using integer pow() - base = (base.int % modulo * pow(10, base.exp, modulo)) % modulo - for i in range(exponent.exp): - base = pow(base, 10, modulo) - base = pow(base, exponent.int, modulo) - - return _dec_from_triple(sign, str(base), 0) - - def _power_exact(self, other, p): - """Attempt to compute self**other exactly. - - Given Decimals self and other and an integer p, attempt to - compute an exact result for the power self**other, with p - digits of precision. Return None if self**other is not - exactly representable in p digits. - - Assumes that elimination of special cases has already been - performed: self and other must both be nonspecial; self must - be positive and not numerically equal to 1; other must be - nonzero. For efficiency, other._exp should not be too large, - so that 10**abs(other._exp) is a feasible calculation.""" - - # In the comments below, we write x for the value of self and y for the - # value of other. Write x = xc*10**xe and abs(y) = yc*10**ye, with xc - # and yc positive integers not divisible by 10. - - # The main purpose of this method is to identify the *failure* - # of x**y to be exactly representable with as little effort as - # possible. So we look for cheap and easy tests that - # eliminate the possibility of x**y being exact. Only if all - # these tests are passed do we go on to actually compute x**y. - - # Here's the main idea. Express y as a rational number m/n, with m and - # n relatively prime and n>0. Then for x**y to be exactly - # representable (at *any* precision), xc must be the nth power of a - # positive integer and xe must be divisible by n. If y is negative - # then additionally xc must be a power of either 2 or 5, hence a power - # of 2**n or 5**n. - # - # There's a limit to how small |y| can be: if y=m/n as above - # then: - # - # (1) if xc != 1 then for the result to be representable we - # need xc**(1/n) >= 2, and hence also xc**|y| >= 2. So - # if |y| <= 1/nbits(xc) then xc < 2**nbits(xc) <= - # 2**(1/|y|), hence xc**|y| < 2 and the result is not - # representable. - # - # (2) if xe != 0, |xe|*(1/n) >= 1, so |xe|*|y| >= 1. Hence if - # |y| < 1/|xe| then the result is not representable. - # - # Note that since x is not equal to 1, at least one of (1) and - # (2) must apply. Now |y| < 1/nbits(xc) iff |yc|*nbits(xc) < - # 10**-ye iff len(str(|yc|*nbits(xc)) <= -ye. - # - # There's also a limit to how large y can be, at least if it's - # positive: the normalized result will have coefficient xc**y, - # so if it's representable then xc**y < 10**p, and y < - # p/log10(xc). Hence if y*log10(xc) >= p then the result is - # not exactly representable. - - # if len(str(abs(yc*xe)) <= -ye then abs(yc*xe) < 10**-ye, - # so |y| < 1/xe and the result is not representable. - # Similarly, len(str(abs(yc)*xc_bits)) <= -ye implies |y| - # < 1/nbits(xc). - - x = _WorkRep(self) - xc, xe = x.int, x.exp - while xc % 10 == 0: - xc //= 10 - xe += 1 - - y = _WorkRep(other) - yc, ye = y.int, y.exp - while yc % 10 == 0: - yc //= 10 - ye += 1 - - # case where xc == 1: result is 10**(xe*y), with xe*y - # required to be an integer - if xc == 1: - xe *= yc - # result is now 10**(xe * 10**ye); xe * 10**ye must be integral - while xe % 10 == 0: - xe //= 10 - ye += 1 - if ye < 0: - return None - exponent = xe * 10**ye - if y.sign == 1: - exponent = -exponent - # if other is a nonnegative integer, use ideal exponent - if other._isinteger() and other._sign == 0: - ideal_exponent = self._exp*int(other) - zeros = min(exponent-ideal_exponent, p-1) - else: - zeros = 0 - return _dec_from_triple(0, '1' + '0'*zeros, exponent-zeros) - - # case where y is negative: xc must be either a power - # of 2 or a power of 5. - if y.sign == 1: - last_digit = xc % 10 - if last_digit in (2,4,6,8): - # quick test for power of 2 - if xc & -xc != xc: - return None - # now xc is a power of 2; e is its exponent - e = _nbits(xc)-1 - - # We now have: - # - # x = 2**e * 10**xe, e > 0, and y < 0. - # - # The exact result is: - # - # x**y = 5**(-e*y) * 10**(e*y + xe*y) - # - # provided that both e*y and xe*y are integers. Note that if - # 5**(-e*y) >= 10**p, then the result can't be expressed - # exactly with p digits of precision. - # - # Using the above, we can guard against large values of ye. - # 93/65 is an upper bound for log(10)/log(5), so if - # - # ye >= len(str(93*p//65)) - # - # then - # - # -e*y >= -y >= 10**ye > 93*p/65 > p*log(10)/log(5), - # - # so 5**(-e*y) >= 10**p, and the coefficient of the result - # can't be expressed in p digits. - - # emax >= largest e such that 5**e < 10**p. - emax = p*93//65 - if ye >= len(str(emax)): - return None - - # Find -e*y and -xe*y; both must be integers - e = _decimal_lshift_exact(e * yc, ye) - xe = _decimal_lshift_exact(xe * yc, ye) - if e is None or xe is None: - return None - - if e > emax: - return None - xc = 5**e - - elif last_digit == 5: - # e >= log_5(xc) if xc is a power of 5; we have - # equality all the way up to xc=5**2658 - e = _nbits(xc)*28//65 - xc, remainder = divmod(5**e, xc) - if remainder: - return None - while xc % 5 == 0: - xc //= 5 - e -= 1 - - # Guard against large values of ye, using the same logic as in - # the 'xc is a power of 2' branch. 10/3 is an upper bound for - # log(10)/log(2). - emax = p*10//3 - if ye >= len(str(emax)): - return None - - e = _decimal_lshift_exact(e * yc, ye) - xe = _decimal_lshift_exact(xe * yc, ye) - if e is None or xe is None: - return None - - if e > emax: - return None - xc = 2**e - else: - return None - - if xc >= 10**p: - return None - xe = -e-xe - return _dec_from_triple(0, str(xc), xe) - - # now y is positive; find m and n such that y = m/n - if ye >= 0: - m, n = yc*10**ye, 1 - else: - if xe != 0 and len(str(abs(yc*xe))) <= -ye: - return None - xc_bits = _nbits(xc) - if xc != 1 and len(str(abs(yc)*xc_bits)) <= -ye: - return None - m, n = yc, 10**(-ye) - while m % 2 == n % 2 == 0: - m //= 2 - n //= 2 - while m % 5 == n % 5 == 0: - m //= 5 - n //= 5 - - # compute nth root of xc*10**xe - if n > 1: - # if 1 < xc < 2**n then xc isn't an nth power - if xc != 1 and xc_bits <= n: - return None - - xe, rem = divmod(xe, n) - if rem != 0: - return None - - # compute nth root of xc using Newton's method - a = 1 << -(-_nbits(xc)//n) # initial estimate - while True: - q, r = divmod(xc, a**(n-1)) - if a <= q: - break - else: - a = (a*(n-1) + q)//n - if not (a == q and r == 0): - return None - xc = a - - # now xc*10**xe is the nth root of the original xc*10**xe - # compute mth power of xc*10**xe - - # if m > p*100//_log10_lb(xc) then m > p/log10(xc), hence xc**m > - # 10**p and the result is not representable. - if xc > 1 and m > p*100//_log10_lb(xc): - return None - xc = xc**m - xe *= m - if xc > 10**p: - return None - - # by this point the result *is* exactly representable - # adjust the exponent to get as close as possible to the ideal - # exponent, if necessary - str_xc = str(xc) - if other._isinteger() and other._sign == 0: - ideal_exponent = self._exp*int(other) - zeros = min(xe-ideal_exponent, p-len(str_xc)) - else: - zeros = 0 - return _dec_from_triple(0, str_xc+'0'*zeros, xe-zeros) - - def __pow__(self, other, modulo=None, context=None): - """Return self ** other [ % modulo]. - - With two arguments, compute self**other. - - With three arguments, compute (self**other) % modulo. For the - three argument form, the following restrictions on the - arguments hold: - - - all three arguments must be integral - - other must be nonnegative - - either self or other (or both) must be nonzero - - modulo must be nonzero and must have at most p digits, - where p is the context precision. - - If any of these restrictions is violated the InvalidOperation - flag is raised. - - The result of pow(self, other, modulo) is identical to the - result that would be obtained by computing (self**other) % - modulo with unbounded precision, but is computed more - efficiently. It is always exact. - """ - - if modulo is not None: - return self._power_modulo(other, modulo, context) - - other = _convert_other(other) - if other is NotImplemented: - return other - - if context is None: - context = getcontext() - - # either argument is a NaN => result is NaN - ans = self._check_nans(other, context) - if ans: - return ans - - # 0**0 = NaN (!), x**0 = 1 for nonzero x (including +/-Infinity) - if not other: - if not self: - return context._raise_error(InvalidOperation, '0 ** 0') - else: - return _One - - # result has sign 1 iff self._sign is 1 and other is an odd integer - result_sign = 0 - if self._sign == 1: - if other._isinteger(): - if not other._iseven(): - result_sign = 1 - else: - # -ve**noninteger = NaN - # (-0)**noninteger = 0**noninteger - if self: - return context._raise_error(InvalidOperation, - 'x ** y with x negative and y not an integer') - # negate self, without doing any unwanted rounding - self = self.copy_negate() - - # 0**(+ve or Inf)= 0; 0**(-ve or -Inf) = Infinity - if not self: - if other._sign == 0: - return _dec_from_triple(result_sign, '0', 0) - else: - return _SignedInfinity[result_sign] - - # Inf**(+ve or Inf) = Inf; Inf**(-ve or -Inf) = 0 - if self._isinfinity(): - if other._sign == 0: - return _SignedInfinity[result_sign] - else: - return _dec_from_triple(result_sign, '0', 0) - - # 1**other = 1, but the choice of exponent and the flags - # depend on the exponent of self, and on whether other is a - # positive integer, a negative integer, or neither - if self == _One: - if other._isinteger(): - # exp = max(self._exp*max(int(other), 0), - # 1-context.prec) but evaluating int(other) directly - # is dangerous until we know other is small (other - # could be 1e999999999) - if other._sign == 1: - multiplier = 0 - elif other > context.prec: - multiplier = context.prec - else: - multiplier = int(other) - - exp = self._exp * multiplier - if exp < 1-context.prec: - exp = 1-context.prec - context._raise_error(Rounded) - else: - context._raise_error(Inexact) - context._raise_error(Rounded) - exp = 1-context.prec - - return _dec_from_triple(result_sign, '1'+'0'*-exp, exp) - - # compute adjusted exponent of self - self_adj = self.adjusted() - - # self ** infinity is infinity if self > 1, 0 if self < 1 - # self ** -infinity is infinity if self < 1, 0 if self > 1 - if other._isinfinity(): - if (other._sign == 0) == (self_adj < 0): - return _dec_from_triple(result_sign, '0', 0) - else: - return _SignedInfinity[result_sign] - - # from here on, the result always goes through the call - # to _fix at the end of this function. - ans = None - exact = False - - # crude test to catch cases of extreme overflow/underflow. If - # log10(self)*other >= 10**bound and bound >= len(str(Emax)) - # then 10**bound >= 10**len(str(Emax)) >= Emax+1 and hence - # self**other >= 10**(Emax+1), so overflow occurs. The test - # for underflow is similar. - bound = self._log10_exp_bound() + other.adjusted() - if (self_adj >= 0) == (other._sign == 0): - # self > 1 and other +ve, or self < 1 and other -ve - # possibility of overflow - if bound >= len(str(context.Emax)): - ans = _dec_from_triple(result_sign, '1', context.Emax+1) - else: - # self > 1 and other -ve, or self < 1 and other +ve - # possibility of underflow to 0 - Etiny = context.Etiny() - if bound >= len(str(-Etiny)): - ans = _dec_from_triple(result_sign, '1', Etiny-1) - - # try for an exact result with precision +1 - if ans is None: - ans = self._power_exact(other, context.prec + 1) - if ans is not None: - if result_sign == 1: - ans = _dec_from_triple(1, ans._int, ans._exp) - exact = True - - # usual case: inexact result, x**y computed directly as exp(y*log(x)) - if ans is None: - p = context.prec - x = _WorkRep(self) - xc, xe = x.int, x.exp - y = _WorkRep(other) - yc, ye = y.int, y.exp - if y.sign == 1: - yc = -yc - - # compute correctly rounded result: start with precision +3, - # then increase precision until result is unambiguously roundable - extra = 3 - while True: - coeff, exp = _dpower(xc, xe, yc, ye, p+extra) - if coeff % (5*10**(len(str(coeff))-p-1)): - break - extra += 3 - - ans = _dec_from_triple(result_sign, str(coeff), exp) - - # unlike exp, ln and log10, the power function respects the - # rounding mode; no need to switch to ROUND_HALF_EVEN here - - # There's a difficulty here when 'other' is not an integer and - # the result is exact. In this case, the specification - # requires that the Inexact flag be raised (in spite of - # exactness), but since the result is exact _fix won't do this - # for us. (Correspondingly, the Underflow signal should also - # be raised for subnormal results.) We can't directly raise - # these signals either before or after calling _fix, since - # that would violate the precedence for signals. So we wrap - # the ._fix call in a temporary context, and reraise - # afterwards. - if exact and not other._isinteger(): - # pad with zeros up to length context.prec+1 if necessary; this - # ensures that the Rounded signal will be raised. - if len(ans._int) <= context.prec: - expdiff = context.prec + 1 - len(ans._int) - ans = _dec_from_triple(ans._sign, ans._int+'0'*expdiff, - ans._exp-expdiff) - - # create a copy of the current context, with cleared flags/traps - newcontext = context.copy() - newcontext.clear_flags() - for exception in _signals: - newcontext.traps[exception] = 0 - - # round in the new context - ans = ans._fix(newcontext) - - # raise Inexact, and if necessary, Underflow - newcontext._raise_error(Inexact) - if newcontext.flags[Subnormal]: - newcontext._raise_error(Underflow) - - # propagate signals to the original context; _fix could - # have raised any of Overflow, Underflow, Subnormal, - # Inexact, Rounded, Clamped. Overflow needs the correct - # arguments. Note that the order of the exceptions is - # important here. - if newcontext.flags[Overflow]: - context._raise_error(Overflow, 'above Emax', ans._sign) - for exception in Underflow, Subnormal, Inexact, Rounded, Clamped: - if newcontext.flags[exception]: - context._raise_error(exception) - - else: - ans = ans._fix(context) - - return ans - - def __rpow__(self, other, context=None): - """Swaps self/other and returns __pow__.""" - other = _convert_other(other) - if other is NotImplemented: - return other - return other.__pow__(self, context=context) - - def normalize(self, context=None): - """Normalize- strip trailing 0s, change anything equal to 0 to 0e0""" - - if context is None: - context = getcontext() - - if self._is_special: - ans = self._check_nans(context=context) - if ans: - return ans - - dup = self._fix(context) - if dup._isinfinity(): - return dup - - if not dup: - return _dec_from_triple(dup._sign, '0', 0) - exp_max = [context.Emax, context.Etop()][context.clamp] - end = len(dup._int) - exp = dup._exp - while dup._int[end-1] == '0' and exp < exp_max: - exp += 1 - end -= 1 - return _dec_from_triple(dup._sign, dup._int[:end], exp) - - def quantize(self, exp, rounding=None, context=None, watchexp=True): - """Quantize self so its exponent is the same as that of exp. - - Similar to self._rescale(exp._exp) but with error checking. - """ - exp = _convert_other(exp, raiseit=True) - - if context is None: - context = getcontext() - if rounding is None: - rounding = context.rounding - - if self._is_special or exp._is_special: - ans = self._check_nans(exp, context) - if ans: - return ans - - if exp._isinfinity() or self._isinfinity(): - if exp._isinfinity() and self._isinfinity(): - return Decimal(self) # if both are inf, it is OK - return context._raise_error(InvalidOperation, - 'quantize with one INF') - - # if we're not watching exponents, do a simple rescale - if not watchexp: - ans = self._rescale(exp._exp, rounding) - # raise Inexact and Rounded where appropriate - if ans._exp > self._exp: - context._raise_error(Rounded) - if ans != self: - context._raise_error(Inexact) - return ans - - # exp._exp should be between Etiny and Emax - if not (context.Etiny() <= exp._exp <= context.Emax): - return context._raise_error(InvalidOperation, - 'target exponent out of bounds in quantize') - - if not self: - ans = _dec_from_triple(self._sign, '0', exp._exp) - return ans._fix(context) - - self_adjusted = self.adjusted() - if self_adjusted > context.Emax: - return context._raise_error(InvalidOperation, - 'exponent of quantize result too large for current context') - if self_adjusted - exp._exp + 1 > context.prec: - return context._raise_error(InvalidOperation, - 'quantize result has too many digits for current context') - - ans = self._rescale(exp._exp, rounding) - if ans.adjusted() > context.Emax: - return context._raise_error(InvalidOperation, - 'exponent of quantize result too large for current context') - if len(ans._int) > context.prec: - return context._raise_error(InvalidOperation, - 'quantize result has too many digits for current context') - - # raise appropriate flags - if ans and ans.adjusted() < context.Emin: - context._raise_error(Subnormal) - if ans._exp > self._exp: - if ans != self: - context._raise_error(Inexact) - context._raise_error(Rounded) - - # call to fix takes care of any necessary folddown, and - # signals Clamped if necessary - ans = ans._fix(context) - return ans - - def same_quantum(self, other, context=None): - """Return True if self and other have the same exponent; otherwise - return False. - - If either operand is a special value, the following rules are used: - * return True if both operands are infinities - * return True if both operands are NaNs - * otherwise, return False. - """ - other = _convert_other(other, raiseit=True) - if self._is_special or other._is_special: - return (self.is_nan() and other.is_nan() or - self.is_infinite() and other.is_infinite()) - return self._exp == other._exp - - def _rescale(self, exp, rounding): - """Rescale self so that the exponent is exp, either by padding with zeros - or by truncating digits, using the given rounding mode. - - Specials are returned without change. This operation is - quiet: it raises no flags, and uses no information from the - context. - - exp = exp to scale to (an integer) - rounding = rounding mode - """ - if self._is_special: - return Decimal(self) - if not self: - return _dec_from_triple(self._sign, '0', exp) - - if self._exp >= exp: - # pad answer with zeros if necessary - return _dec_from_triple(self._sign, - self._int + '0'*(self._exp - exp), exp) - - # too many digits; round and lose data. If self.adjusted() < - # exp-1, replace self by 10**(exp-1) before rounding - digits = len(self._int) + self._exp - exp - if digits < 0: - self = _dec_from_triple(self._sign, '1', exp-1) - digits = 0 - this_function = self._pick_rounding_function[rounding] - changed = this_function(self, digits) - coeff = self._int[:digits] or '0' - if changed == 1: - coeff = str(int(coeff)+1) - return _dec_from_triple(self._sign, coeff, exp) - - def _round(self, places, rounding): - """Round a nonzero, nonspecial Decimal to a fixed number of - significant figures, using the given rounding mode. - - Infinities, NaNs and zeros are returned unaltered. - - This operation is quiet: it raises no flags, and uses no - information from the context. - - """ - if places <= 0: - raise ValueError("argument should be at least 1 in _round") - if self._is_special or not self: - return Decimal(self) - ans = self._rescale(self.adjusted()+1-places, rounding) - # it can happen that the rescale alters the adjusted exponent; - # for example when rounding 99.97 to 3 significant figures. - # When this happens we end up with an extra 0 at the end of - # the number; a second rescale fixes this. - if ans.adjusted() != self.adjusted(): - ans = ans._rescale(ans.adjusted()+1-places, rounding) - return ans - - def to_integral_exact(self, rounding=None, context=None): - """Rounds to a nearby integer. - - If no rounding mode is specified, take the rounding mode from - the context. This method raises the Rounded and Inexact flags - when appropriate. - - See also: to_integral_value, which does exactly the same as - this method except that it doesn't raise Inexact or Rounded. - """ - if self._is_special: - ans = self._check_nans(context=context) - if ans: - return ans - return Decimal(self) - if self._exp >= 0: - return Decimal(self) - if not self: - return _dec_from_triple(self._sign, '0', 0) - if context is None: - context = getcontext() - if rounding is None: - rounding = context.rounding - ans = self._rescale(0, rounding) - if ans != self: - context._raise_error(Inexact) - context._raise_error(Rounded) - return ans - - def to_integral_value(self, rounding=None, context=None): - """Rounds to the nearest integer, without raising inexact, rounded.""" - if context is None: - context = getcontext() - if rounding is None: - rounding = context.rounding - if self._is_special: - ans = self._check_nans(context=context) - if ans: - return ans - return Decimal(self) - if self._exp >= 0: - return Decimal(self) - else: - return self._rescale(0, rounding) - - # the method name changed, but we provide also the old one, for compatibility - to_integral = to_integral_value - - def sqrt(self, context=None): - """Return the square root of self.""" - if context is None: - context = getcontext() - - if self._is_special: - ans = self._check_nans(context=context) - if ans: - return ans - - if self._isinfinity() and self._sign == 0: - return Decimal(self) - - if not self: - # exponent = self._exp // 2. sqrt(-0) = -0 - ans = _dec_from_triple(self._sign, '0', self._exp // 2) - return ans._fix(context) - - if self._sign == 1: - return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0') - - # At this point self represents a positive number. Let p be - # the desired precision and express self in the form c*100**e - # with c a positive real number and e an integer, c and e - # being chosen so that 100**(p-1) <= c < 100**p. Then the - # (exact) square root of self is sqrt(c)*10**e, and 10**(p-1) - # <= sqrt(c) < 10**p, so the closest representable Decimal at - # precision p is n*10**e where n = round_half_even(sqrt(c)), - # the closest integer to sqrt(c) with the even integer chosen - # in the case of a tie. - # - # To ensure correct rounding in all cases, we use the - # following trick: we compute the square root to an extra - # place (precision p+1 instead of precision p), rounding down. - # Then, if the result is inexact and its last digit is 0 or 5, - # we increase the last digit to 1 or 6 respectively; if it's - # exact we leave the last digit alone. Now the final round to - # p places (or fewer in the case of underflow) will round - # correctly and raise the appropriate flags. - - # use an extra digit of precision - prec = context.prec+1 - - # write argument in the form c*100**e where e = self._exp//2 - # is the 'ideal' exponent, to be used if the square root is - # exactly representable. l is the number of 'digits' of c in - # base 100, so that 100**(l-1) <= c < 100**l. - op = _WorkRep(self) - e = op.exp >> 1 - if op.exp & 1: - c = op.int * 10 - l = (len(self._int) >> 1) + 1 - else: - c = op.int - l = len(self._int)+1 >> 1 - - # rescale so that c has exactly prec base 100 'digits' - shift = prec-l - if shift >= 0: - c *= 100**shift - exact = True - else: - c, remainder = divmod(c, 100**-shift) - exact = not remainder - e -= shift - - # find n = floor(sqrt(c)) using Newton's method - n = 10**prec - while True: - q = c//n - if n <= q: - break - else: - n = n + q >> 1 - exact = exact and n*n == c - - if exact: - # result is exact; rescale to use ideal exponent e - if shift >= 0: - # assert n % 10**shift == 0 - n //= 10**shift - else: - n *= 10**-shift - e += shift - else: - # result is not exact; fix last digit as described above - if n % 5 == 0: - n += 1 - - ans = _dec_from_triple(0, str(n), e) - - # round, and fit to current context - context = context._shallow_copy() - rounding = context._set_rounding(ROUND_HALF_EVEN) - ans = ans._fix(context) - context.rounding = rounding - - return ans - - def max(self, other, context=None): - """Returns the larger value. - - Like max(self, other) except if one is not a number, returns - NaN (and signals if one is sNaN). Also rounds. - """ - other = _convert_other(other, raiseit=True) - - if context is None: - context = getcontext() - - if self._is_special or other._is_special: - # If one operand is a quiet NaN and the other is number, then the - # number is always returned - sn = self._isnan() - on = other._isnan() - if sn or on: - if on == 1 and sn == 0: - return self._fix(context) - if sn == 1 and on == 0: - return other._fix(context) - return self._check_nans(other, context) - - c = self._cmp(other) - if c == 0: - # If both operands are finite and equal in numerical value - # then an ordering is applied: - # - # If the signs differ then max returns the operand with the - # positive sign and min returns the operand with the negative sign - # - # If the signs are the same then the exponent is used to select - # the result. This is exactly the ordering used in compare_total. - c = self.compare_total(other) - - if c == -1: - ans = other - else: - ans = self - - return ans._fix(context) - - def min(self, other, context=None): - """Returns the smaller value. - - Like min(self, other) except if one is not a number, returns - NaN (and signals if one is sNaN). Also rounds. - """ - other = _convert_other(other, raiseit=True) - - if context is None: - context = getcontext() - - if self._is_special or other._is_special: - # If one operand is a quiet NaN and the other is number, then the - # number is always returned - sn = self._isnan() - on = other._isnan() - if sn or on: - if on == 1 and sn == 0: - return self._fix(context) - if sn == 1 and on == 0: - return other._fix(context) - return self._check_nans(other, context) - - c = self._cmp(other) - if c == 0: - c = self.compare_total(other) - - if c == -1: - ans = self - else: - ans = other - - return ans._fix(context) - - def _isinteger(self): - """Returns whether self is an integer""" - if self._is_special: - return False - if self._exp >= 0: - return True - rest = self._int[self._exp:] - return rest == '0'*len(rest) - - def _iseven(self): - """Returns True if self is even. Assumes self is an integer.""" - if not self or self._exp > 0: - return True - return self._int[-1+self._exp] in '02468' - - def adjusted(self): - """Return the adjusted exponent of self""" - try: - return self._exp + len(self._int) - 1 - # If NaN or Infinity, self._exp is string - except TypeError: - return 0 - - def canonical(self): - """Returns the same Decimal object. - - As we do not have different encodings for the same number, the - received object already is in its canonical form. - """ - return self - - def compare_signal(self, other, context=None): - """Compares self to the other operand numerically. - - It's pretty much like compare(), but all NaNs signal, with signaling - NaNs taking precedence over quiet NaNs. - """ - other = _convert_other(other, raiseit = True) - ans = self._compare_check_nans(other, context) - if ans: - return ans - return self.compare(other, context=context) - - def compare_total(self, other, context=None): - """Compares self to other using the abstract representations. - - This is not like the standard compare, which use their numerical - value. Note that a total ordering is defined for all possible abstract - representations. - """ - other = _convert_other(other, raiseit=True) - - # if one is negative and the other is positive, it's easy - if self._sign and not other._sign: - return _NegativeOne - if not self._sign and other._sign: - return _One - sign = self._sign - - # let's handle both NaN types - self_nan = self._isnan() - other_nan = other._isnan() - if self_nan or other_nan: - if self_nan == other_nan: - # compare payloads as though they're integers - self_key = len(self._int), self._int - other_key = len(other._int), other._int - if self_key < other_key: - if sign: - return _One - else: - return _NegativeOne - if self_key > other_key: - if sign: - return _NegativeOne - else: - return _One - return _Zero - - if sign: - if self_nan == 1: - return _NegativeOne - if other_nan == 1: - return _One - if self_nan == 2: - return _NegativeOne - if other_nan == 2: - return _One - else: - if self_nan == 1: - return _One - if other_nan == 1: - return _NegativeOne - if self_nan == 2: - return _One - if other_nan == 2: - return _NegativeOne - - if self < other: - return _NegativeOne - if self > other: - return _One - - if self._exp < other._exp: - if sign: - return _One - else: - return _NegativeOne - if self._exp > other._exp: - if sign: - return _NegativeOne - else: - return _One - return _Zero - - - def compare_total_mag(self, other, context=None): - """Compares self to other using abstract repr., ignoring sign. - - Like compare_total, but with operand's sign ignored and assumed to be 0. - """ - other = _convert_other(other, raiseit=True) - - s = self.copy_abs() - o = other.copy_abs() - return s.compare_total(o) - - def copy_abs(self): - """Returns a copy with the sign set to 0. """ - return _dec_from_triple(0, self._int, self._exp, self._is_special) - - def copy_negate(self): - """Returns a copy with the sign inverted.""" - if self._sign: - return _dec_from_triple(0, self._int, self._exp, self._is_special) - else: - return _dec_from_triple(1, self._int, self._exp, self._is_special) - - def copy_sign(self, other, context=None): - """Returns self with the sign of other.""" - other = _convert_other(other, raiseit=True) - return _dec_from_triple(other._sign, self._int, - self._exp, self._is_special) - - def exp(self, context=None): - """Returns e ** self.""" - - if context is None: - context = getcontext() - - # exp(NaN) = NaN - ans = self._check_nans(context=context) - if ans: - return ans - - # exp(-Infinity) = 0 - if self._isinfinity() == -1: - return _Zero - - # exp(0) = 1 - if not self: - return _One - - # exp(Infinity) = Infinity - if self._isinfinity() == 1: - return Decimal(self) - - # the result is now guaranteed to be inexact (the true - # mathematical result is transcendental). There's no need to - # raise Rounded and Inexact here---they'll always be raised as - # a result of the call to _fix. - p = context.prec - adj = self.adjusted() - - # we only need to do any computation for quite a small range - # of adjusted exponents---for example, -29 <= adj <= 10 for - # the default context. For smaller exponent the result is - # indistinguishable from 1 at the given precision, while for - # larger exponent the result either overflows or underflows. - if self._sign == 0 and adj > len(str((context.Emax+1)*3)): - # overflow - ans = _dec_from_triple(0, '1', context.Emax+1) - elif self._sign == 1 and adj > len(str((-context.Etiny()+1)*3)): - # underflow to 0 - ans = _dec_from_triple(0, '1', context.Etiny()-1) - elif self._sign == 0 and adj < -p: - # p+1 digits; final round will raise correct flags - ans = _dec_from_triple(0, '1' + '0'*(p-1) + '1', -p) - elif self._sign == 1 and adj < -p-1: - # p+1 digits; final round will raise correct flags - ans = _dec_from_triple(0, '9'*(p+1), -p-1) - # general case - else: - op = _WorkRep(self) - c, e = op.int, op.exp - if op.sign == 1: - c = -c - - # compute correctly rounded result: increase precision by - # 3 digits at a time until we get an unambiguously - # roundable result - extra = 3 - while True: - coeff, exp = _dexp(c, e, p+extra) - if coeff % (5*10**(len(str(coeff))-p-1)): - break - extra += 3 - - ans = _dec_from_triple(0, str(coeff), exp) - - # at this stage, ans should round correctly with *any* - # rounding mode, not just with ROUND_HALF_EVEN - context = context._shallow_copy() - rounding = context._set_rounding(ROUND_HALF_EVEN) - ans = ans._fix(context) - context.rounding = rounding - - return ans - - def is_canonical(self): - """Return True if self is canonical; otherwise return False. - - Currently, the encoding of a Decimal instance is always - canonical, so this method returns True for any Decimal. - """ - return True - - def is_finite(self): - """Return True if self is finite; otherwise return False. - - A Decimal instance is considered finite if it is neither - infinite nor a NaN. - """ - return not self._is_special - - def is_infinite(self): - """Return True if self is infinite; otherwise return False.""" - return self._exp == 'F' - - def is_nan(self): - """Return True if self is a qNaN or sNaN; otherwise return False.""" - return self._exp in ('n', 'N') - - def is_normal(self, context=None): - """Return True if self is a normal number; otherwise return False.""" - if self._is_special or not self: - return False - if context is None: - context = getcontext() - return context.Emin <= self.adjusted() - - def is_qnan(self): - """Return True if self is a quiet NaN; otherwise return False.""" - return self._exp == 'n' - - def is_signed(self): - """Return True if self is negative; otherwise return False.""" - return self._sign == 1 - - def is_snan(self): - """Return True if self is a signaling NaN; otherwise return False.""" - return self._exp == 'N' - - def is_subnormal(self, context=None): - """Return True if self is subnormal; otherwise return False.""" - if self._is_special or not self: - return False - if context is None: - context = getcontext() - return self.adjusted() < context.Emin - - def is_zero(self): - """Return True if self is a zero; otherwise return False.""" - return not self._is_special and self._int == '0' - - def _ln_exp_bound(self): - """Compute a lower bound for the adjusted exponent of self.ln(). - In other words, compute r such that self.ln() >= 10**r. Assumes - that self is finite and positive and that self != 1. - """ - - # for 0.1 <= x <= 10 we use the inequalities 1-1/x <= ln(x) <= x-1 - adj = self._exp + len(self._int) - 1 - if adj >= 1: - # argument >= 10; we use 23/10 = 2.3 as a lower bound for ln(10) - return len(str(adj*23//10)) - 1 - if adj <= -2: - # argument <= 0.1 - return len(str((-1-adj)*23//10)) - 1 - op = _WorkRep(self) - c, e = op.int, op.exp - if adj == 0: - # 1 < self < 10 - num = str(c-10**-e) - den = str(c) - return len(num) - len(den) - (num < den) - # adj == -1, 0.1 <= self < 1 - return e + len(str(10**-e - c)) - 1 - - - def ln(self, context=None): - """Returns the natural (base e) logarithm of self.""" - - if context is None: - context = getcontext() - - # ln(NaN) = NaN - ans = self._check_nans(context=context) - if ans: - return ans - - # ln(0.0) == -Infinity - if not self: - return _NegativeInfinity - - # ln(Infinity) = Infinity - if self._isinfinity() == 1: - return _Infinity - - # ln(1.0) == 0.0 - if self == _One: - return _Zero - - # ln(negative) raises InvalidOperation - if self._sign == 1: - return context._raise_error(InvalidOperation, - 'ln of a negative value') - - # result is irrational, so necessarily inexact - op = _WorkRep(self) - c, e = op.int, op.exp - p = context.prec - - # correctly rounded result: repeatedly increase precision by 3 - # until we get an unambiguously roundable result - places = p - self._ln_exp_bound() + 2 # at least p+3 places - while True: - coeff = _dlog(c, e, places) - # assert len(str(abs(coeff)))-p >= 1 - if coeff % (5*10**(len(str(abs(coeff)))-p-1)): - break - places += 3 - ans = _dec_from_triple(int(coeff<0), str(abs(coeff)), -places) - - context = context._shallow_copy() - rounding = context._set_rounding(ROUND_HALF_EVEN) - ans = ans._fix(context) - context.rounding = rounding - return ans - - def _log10_exp_bound(self): - """Compute a lower bound for the adjusted exponent of self.log10(). - In other words, find r such that self.log10() >= 10**r. - Assumes that self is finite and positive and that self != 1. - """ - - # For x >= 10 or x < 0.1 we only need a bound on the integer - # part of log10(self), and this comes directly from the - # exponent of x. For 0.1 <= x <= 10 we use the inequalities - # 1-1/x <= log(x) <= x-1. If x > 1 we have |log10(x)| > - # (1-1/x)/2.31 > 0. If x < 1 then |log10(x)| > (1-x)/2.31 > 0 - - adj = self._exp + len(self._int) - 1 - if adj >= 1: - # self >= 10 - return len(str(adj))-1 - if adj <= -2: - # self < 0.1 - return len(str(-1-adj))-1 - op = _WorkRep(self) - c, e = op.int, op.exp - if adj == 0: - # 1 < self < 10 - num = str(c-10**-e) - den = str(231*c) - return len(num) - len(den) - (num < den) + 2 - # adj == -1, 0.1 <= self < 1 - num = str(10**-e-c) - return len(num) + e - (num < "231") - 1 - - def log10(self, context=None): - """Returns the base 10 logarithm of self.""" - - if context is None: - context = getcontext() - - # log10(NaN) = NaN - ans = self._check_nans(context=context) - if ans: - return ans - - # log10(0.0) == -Infinity - if not self: - return _NegativeInfinity - - # log10(Infinity) = Infinity - if self._isinfinity() == 1: - return _Infinity - - # log10(negative or -Infinity) raises InvalidOperation - if self._sign == 1: - return context._raise_error(InvalidOperation, - 'log10 of a negative value') - - # log10(10**n) = n - if self._int[0] == '1' and self._int[1:] == '0'*(len(self._int) - 1): - # answer may need rounding - ans = Decimal(self._exp + len(self._int) - 1) - else: - # result is irrational, so necessarily inexact - op = _WorkRep(self) - c, e = op.int, op.exp - p = context.prec - - # correctly rounded result: repeatedly increase precision - # until result is unambiguously roundable - places = p-self._log10_exp_bound()+2 - while True: - coeff = _dlog10(c, e, places) - # assert len(str(abs(coeff)))-p >= 1 - if coeff % (5*10**(len(str(abs(coeff)))-p-1)): - break - places += 3 - ans = _dec_from_triple(int(coeff<0), str(abs(coeff)), -places) - - context = context._shallow_copy() - rounding = context._set_rounding(ROUND_HALF_EVEN) - ans = ans._fix(context) - context.rounding = rounding - return ans - - def logb(self, context=None): - """ Returns the exponent of the magnitude of self's MSD. - - The result is the integer which is the exponent of the magnitude - of the most significant digit of self (as though it were truncated - to a single digit while maintaining the value of that digit and - without limiting the resulting exponent). - """ - # logb(NaN) = NaN - ans = self._check_nans(context=context) - if ans: - return ans - - if context is None: - context = getcontext() - - # logb(+/-Inf) = +Inf - if self._isinfinity(): - return _Infinity - - # logb(0) = -Inf, DivisionByZero - if not self: - return context._raise_error(DivisionByZero, 'logb(0)', 1) - - # otherwise, simply return the adjusted exponent of self, as a - # Decimal. Note that no attempt is made to fit the result - # into the current context. - ans = Decimal(self.adjusted()) - return ans._fix(context) - - def _islogical(self): - """Return True if self is a logical operand. - - For being logical, it must be a finite number with a sign of 0, - an exponent of 0, and a coefficient whose digits must all be - either 0 or 1. - """ - if self._sign != 0 or self._exp != 0: - return False - for dig in self._int: - if dig not in '01': - return False - return True - - def _fill_logical(self, context, opa, opb): - dif = context.prec - len(opa) - if dif > 0: - opa = '0'*dif + opa - elif dif < 0: - opa = opa[-context.prec:] - dif = context.prec - len(opb) - if dif > 0: - opb = '0'*dif + opb - elif dif < 0: - opb = opb[-context.prec:] - return opa, opb - - def logical_and(self, other, context=None): - """Applies an 'and' operation between self and other's digits.""" - if context is None: - context = getcontext() - - other = _convert_other(other, raiseit=True) - - if not self._islogical() or not other._islogical(): - return context._raise_error(InvalidOperation) - - # fill to context.prec - (opa, opb) = self._fill_logical(context, self._int, other._int) - - # make the operation, and clean starting zeroes - result = "".join([str(int(a)&int(b)) for a,b in zip(opa,opb)]) - return _dec_from_triple(0, result.lstrip('0') or '0', 0) - - def logical_invert(self, context=None): - """Invert all its digits.""" - if context is None: - context = getcontext() - return self.logical_xor(_dec_from_triple(0,'1'*context.prec,0), - context) - - def logical_or(self, other, context=None): - """Applies an 'or' operation between self and other's digits.""" - if context is None: - context = getcontext() - - other = _convert_other(other, raiseit=True) - - if not self._islogical() or not other._islogical(): - return context._raise_error(InvalidOperation) - - # fill to context.prec - (opa, opb) = self._fill_logical(context, self._int, other._int) - - # make the operation, and clean starting zeroes - result = "".join([str(int(a)|int(b)) for a,b in zip(opa,opb)]) - return _dec_from_triple(0, result.lstrip('0') or '0', 0) - - def logical_xor(self, other, context=None): - """Applies an 'xor' operation between self and other's digits.""" - if context is None: - context = getcontext() - - other = _convert_other(other, raiseit=True) - - if not self._islogical() or not other._islogical(): - return context._raise_error(InvalidOperation) - - # fill to context.prec - (opa, opb) = self._fill_logical(context, self._int, other._int) - - # make the operation, and clean starting zeroes - result = "".join([str(int(a)^int(b)) for a,b in zip(opa,opb)]) - return _dec_from_triple(0, result.lstrip('0') or '0', 0) - - def max_mag(self, other, context=None): - """Compares the values numerically with their sign ignored.""" - other = _convert_other(other, raiseit=True) - - if context is None: - context = getcontext() - - if self._is_special or other._is_special: - # If one operand is a quiet NaN and the other is number, then the - # number is always returned - sn = self._isnan() - on = other._isnan() - if sn or on: - if on == 1 and sn == 0: - return self._fix(context) - if sn == 1 and on == 0: - return other._fix(context) - return self._check_nans(other, context) - - c = self.copy_abs()._cmp(other.copy_abs()) - if c == 0: - c = self.compare_total(other) - - if c == -1: - ans = other - else: - ans = self - - return ans._fix(context) - - def min_mag(self, other, context=None): - """Compares the values numerically with their sign ignored.""" - other = _convert_other(other, raiseit=True) - - if context is None: - context = getcontext() - - if self._is_special or other._is_special: - # If one operand is a quiet NaN and the other is number, then the - # number is always returned - sn = self._isnan() - on = other._isnan() - if sn or on: - if on == 1 and sn == 0: - return self._fix(context) - if sn == 1 and on == 0: - return other._fix(context) - return self._check_nans(other, context) - - c = self.copy_abs()._cmp(other.copy_abs()) - if c == 0: - c = self.compare_total(other) - - if c == -1: - ans = self - else: - ans = other - - return ans._fix(context) - - def next_minus(self, context=None): - """Returns the largest representable number smaller than itself.""" - if context is None: - context = getcontext() - - ans = self._check_nans(context=context) - if ans: - return ans - - if self._isinfinity() == -1: - return _NegativeInfinity - if self._isinfinity() == 1: - return _dec_from_triple(0, '9'*context.prec, context.Etop()) - - context = context.copy() - context._set_rounding(ROUND_FLOOR) - context._ignore_all_flags() - new_self = self._fix(context) - if new_self != self: - return new_self - return self.__sub__(_dec_from_triple(0, '1', context.Etiny()-1), - context) - - def next_plus(self, context=None): - """Returns the smallest representable number larger than itself.""" - if context is None: - context = getcontext() - - ans = self._check_nans(context=context) - if ans: - return ans - - if self._isinfinity() == 1: - return _Infinity - if self._isinfinity() == -1: - return _dec_from_triple(1, '9'*context.prec, context.Etop()) - - context = context.copy() - context._set_rounding(ROUND_CEILING) - context._ignore_all_flags() - new_self = self._fix(context) - if new_self != self: - return new_self - return self.__add__(_dec_from_triple(0, '1', context.Etiny()-1), - context) - - def next_toward(self, other, context=None): - """Returns the number closest to self, in the direction towards other. - - The result is the closest representable number to self - (excluding self) that is in the direction towards other, - unless both have the same value. If the two operands are - numerically equal, then the result is a copy of self with the - sign set to be the same as the sign of other. - """ - other = _convert_other(other, raiseit=True) - - if context is None: - context = getcontext() - - ans = self._check_nans(other, context) - if ans: - return ans - - comparison = self._cmp(other) - if comparison == 0: - return self.copy_sign(other) - - if comparison == -1: - ans = self.next_plus(context) - else: # comparison == 1 - ans = self.next_minus(context) - - # decide which flags to raise using value of ans - if ans._isinfinity(): - context._raise_error(Overflow, - 'Infinite result from next_toward', - ans._sign) - context._raise_error(Inexact) - context._raise_error(Rounded) - elif ans.adjusted() < context.Emin: - context._raise_error(Underflow) - context._raise_error(Subnormal) - context._raise_error(Inexact) - context._raise_error(Rounded) - # if precision == 1 then we don't raise Clamped for a - # result 0E-Etiny. - if not ans: - context._raise_error(Clamped) - - return ans - - def number_class(self, context=None): - """Returns an indication of the class of self. - - The class is one of the following strings: - sNaN - NaN - -Infinity - -Normal - -Subnormal - -Zero - +Zero - +Subnormal - +Normal - +Infinity - """ - if self.is_snan(): - return "sNaN" - if self.is_qnan(): - return "NaN" - inf = self._isinfinity() - if inf == 1: - return "+Infinity" - if inf == -1: - return "-Infinity" - if self.is_zero(): - if self._sign: - return "-Zero" - else: - return "+Zero" - if context is None: - context = getcontext() - if self.is_subnormal(context=context): - if self._sign: - return "-Subnormal" - else: - return "+Subnormal" - # just a normal, regular, boring number, :) - if self._sign: - return "-Normal" - else: - return "+Normal" - - def radix(self): - """Just returns 10, as this is Decimal, :)""" - return Decimal(10) - - def rotate(self, other, context=None): - """Returns a rotated copy of self, value-of-other times.""" - if context is None: - context = getcontext() - - other = _convert_other(other, raiseit=True) - - ans = self._check_nans(other, context) - if ans: - return ans - - if other._exp != 0: - return context._raise_error(InvalidOperation) - if not (-context.prec <= int(other) <= context.prec): - return context._raise_error(InvalidOperation) - - if self._isinfinity(): - return Decimal(self) - - # get values, pad if necessary - torot = int(other) - rotdig = self._int - topad = context.prec - len(rotdig) - if topad > 0: - rotdig = '0'*topad + rotdig - elif topad < 0: - rotdig = rotdig[-topad:] - - # let's rotate! - rotated = rotdig[torot:] + rotdig[:torot] - return _dec_from_triple(self._sign, - rotated.lstrip('0') or '0', self._exp) - - def scaleb(self, other, context=None): - """Returns self operand after adding the second value to its exp.""" - if context is None: - context = getcontext() - - other = _convert_other(other, raiseit=True) - - ans = self._check_nans(other, context) - if ans: - return ans - - if other._exp != 0: - return context._raise_error(InvalidOperation) - liminf = -2 * (context.Emax + context.prec) - limsup = 2 * (context.Emax + context.prec) - if not (liminf <= int(other) <= limsup): - return context._raise_error(InvalidOperation) - - if self._isinfinity(): - return Decimal(self) - - d = _dec_from_triple(self._sign, self._int, self._exp + int(other)) - d = d._fix(context) - return d - - def shift(self, other, context=None): - """Returns a shifted copy of self, value-of-other times.""" - if context is None: - context = getcontext() - - other = _convert_other(other, raiseit=True) - - ans = self._check_nans(other, context) - if ans: - return ans - - if other._exp != 0: - return context._raise_error(InvalidOperation) - if not (-context.prec <= int(other) <= context.prec): - return context._raise_error(InvalidOperation) - - if self._isinfinity(): - return Decimal(self) - - # get values, pad if necessary - torot = int(other) - rotdig = self._int - topad = context.prec - len(rotdig) - if topad > 0: - rotdig = '0'*topad + rotdig - elif topad < 0: - rotdig = rotdig[-topad:] - - # let's shift! - if torot < 0: - shifted = rotdig[:torot] - else: - shifted = rotdig + '0'*torot - shifted = shifted[-context.prec:] - - return _dec_from_triple(self._sign, - shifted.lstrip('0') or '0', self._exp) - - # Support for pickling, copy, and deepcopy - def __reduce__(self): - return (self.__class__, (str(self),)) - - def __copy__(self): - if type(self) is Decimal: - return self # I'm immutable; therefore I am my own clone - return self.__class__(str(self)) - - def __deepcopy__(self, memo): - if type(self) is Decimal: - return self # My components are also immutable - return self.__class__(str(self)) - - # PEP 3101 support. the _localeconv keyword argument should be - # considered private: it's provided for ease of testing only. - def __format__(self, specifier, context=None, _localeconv=None): - """Format a Decimal instance according to the given specifier. - - The specifier should be a standard format specifier, with the - form described in PEP 3101. Formatting types 'e', 'E', 'f', - 'F', 'g', 'G', 'n' and '%' are supported. If the formatting - type is omitted it defaults to 'g' or 'G', depending on the - value of context.capitals. - """ - - # Note: PEP 3101 says that if the type is not present then - # there should be at least one digit after the decimal point. - # We take the liberty of ignoring this requirement for - # Decimal---it's presumably there to make sure that - # format(float, '') behaves similarly to str(float). - if context is None: - context = getcontext() - - spec = _parse_format_specifier(specifier, _localeconv=_localeconv) - - # special values don't care about the type or precision - if self._is_special: - sign = _format_sign(self._sign, spec) - body = str(self.copy_abs()) - return _format_align(sign, body, spec) - - # a type of None defaults to 'g' or 'G', depending on context - if spec['type'] is None: - spec['type'] = ['g', 'G'][context.capitals] - - # if type is '%', adjust exponent of self accordingly - if spec['type'] == '%': - self = _dec_from_triple(self._sign, self._int, self._exp+2) - - # round if necessary, taking rounding mode from the context - rounding = context.rounding - precision = spec['precision'] - if precision is not None: - if spec['type'] in 'eE': - self = self._round(precision+1, rounding) - elif spec['type'] in 'fF%': - self = self._rescale(-precision, rounding) - elif spec['type'] in 'gG' and len(self._int) > precision: - self = self._round(precision, rounding) - # special case: zeros with a positive exponent can't be - # represented in fixed point; rescale them to 0e0. - if not self and self._exp > 0 and spec['type'] in 'fF%': - self = self._rescale(0, rounding) - - # figure out placement of the decimal point - leftdigits = self._exp + len(self._int) - if spec['type'] in 'eE': - if not self and precision is not None: - dotplace = 1 - precision - else: - dotplace = 1 - elif spec['type'] in 'fF%': - dotplace = leftdigits - elif spec['type'] in 'gG': - if self._exp <= 0 and leftdigits > -6: - dotplace = leftdigits - else: - dotplace = 1 - - # find digits before and after decimal point, and get exponent - if dotplace < 0: - intpart = '0' - fracpart = '0'*(-dotplace) + self._int - elif dotplace > len(self._int): - intpart = self._int + '0'*(dotplace-len(self._int)) - fracpart = '' - else: - intpart = self._int[:dotplace] or '0' - fracpart = self._int[dotplace:] - exp = leftdigits-dotplace - - # done with the decimal-specific stuff; hand over the rest - # of the formatting to the _format_number function - return _format_number(self._sign, intpart, fracpart, exp, spec) - -def _dec_from_triple(sign, coefficient, exponent, special=False): - """Create a decimal instance directly, without any validation, - normalization (e.g. removal of leading zeros) or argument - conversion. - - This function is for *internal use only*. - """ - - self = object.__new__(Decimal) - self._sign = sign - self._int = coefficient - self._exp = exponent - self._is_special = special - - return self - -# Register Decimal as a kind of Number (an abstract base class). -# However, do not register it as Real (because Decimals are not -# interoperable with floats). -_numbers.Number.register(Decimal) - - -##### Context class ####################################################### - -class _ContextManager(object): - """Context manager class to support localcontext(). - - Sets a copy of the supplied context in __enter__() and restores - the previous decimal context in __exit__() - """ - def __init__(self, new_context): - self.new_context = new_context.copy() - def __enter__(self): - self.saved_context = getcontext() - setcontext(self.new_context) - return self.new_context - def __exit__(self, t, v, tb): - setcontext(self.saved_context) - -class Context(object): - """Contains the context for a Decimal instance. - - Contains: - prec - precision (for use in rounding, division, square roots..) - rounding - rounding type (how you round) - traps - If traps[exception] = 1, then the exception is - raised when it is caused. Otherwise, a value is - substituted in. - flags - When an exception is caused, flags[exception] is set. - (Whether or not the trap_enabler is set) - Should be reset by user of Decimal instance. - Emin - Minimum exponent - Emax - Maximum exponent - capitals - If 1, 1*10^1 is printed as 1E+1. - If 0, printed as 1e1 - clamp - If 1, change exponents if too high (Default 0) - """ - - def __init__(self, prec=None, rounding=None, Emin=None, Emax=None, - capitals=None, clamp=None, flags=None, traps=None, - _ignored_flags=None): - # Set defaults; for everything except flags and _ignored_flags, - # inherit from DefaultContext. - try: - dc = DefaultContext - except NameError: - pass - - self.prec = prec if prec is not None else dc.prec - self.rounding = rounding if rounding is not None else dc.rounding - self.Emin = Emin if Emin is not None else dc.Emin - self.Emax = Emax if Emax is not None else dc.Emax - self.capitals = capitals if capitals is not None else dc.capitals - self.clamp = clamp if clamp is not None else dc.clamp - - if _ignored_flags is None: - self._ignored_flags = [] - else: - self._ignored_flags = _ignored_flags - - if traps is None: - self.traps = dc.traps.copy() - elif not isinstance(traps, dict): - self.traps = dict((s, int(s in traps)) for s in _signals + traps) - else: - self.traps = traps - - if flags is None: - self.flags = dict.fromkeys(_signals, 0) - elif not isinstance(flags, dict): - self.flags = dict((s, int(s in flags)) for s in _signals + flags) - else: - self.flags = flags - - def _set_integer_check(self, name, value, vmin, vmax): - if not isinstance(value, int): - raise TypeError("%s must be an integer" % name) - if vmin == '-inf': - if value > vmax: - raise ValueError("%s must be in [%s, %d]. got: %s" % (name, vmin, vmax, value)) - elif vmax == 'inf': - if value < vmin: - raise ValueError("%s must be in [%d, %s]. got: %s" % (name, vmin, vmax, value)) - else: - if value < vmin or value > vmax: - raise ValueError("%s must be in [%d, %d]. got %s" % (name, vmin, vmax, value)) - return object.__setattr__(self, name, value) - - def _set_signal_dict(self, name, d): - if not isinstance(d, dict): - raise TypeError("%s must be a signal dict" % d) - for key in d: - if not key in _signals: - raise KeyError("%s is not a valid signal dict" % d) - for key in _signals: - if not key in d: - raise KeyError("%s is not a valid signal dict" % d) - return object.__setattr__(self, name, d) - - def __setattr__(self, name, value): - if name == 'prec': - return self._set_integer_check(name, value, 1, 'inf') - elif name == 'Emin': - return self._set_integer_check(name, value, '-inf', 0) - elif name == 'Emax': - return self._set_integer_check(name, value, 0, 'inf') - elif name == 'capitals': - return self._set_integer_check(name, value, 0, 1) - elif name == 'clamp': - return self._set_integer_check(name, value, 0, 1) - elif name == 'rounding': - if not value in _rounding_modes: - # raise TypeError even for strings to have consistency - # among various implementations. - raise TypeError("%s: invalid rounding mode" % value) - return object.__setattr__(self, name, value) - elif name == 'flags' or name == 'traps': - return self._set_signal_dict(name, value) - elif name == '_ignored_flags': - return object.__setattr__(self, name, value) - else: - raise AttributeError( - "'decimal.Context' object has no attribute '%s'" % name) - - def __delattr__(self, name): - raise AttributeError("%s cannot be deleted" % name) - - # Support for pickling, copy, and deepcopy - def __reduce__(self): - flags = [sig for sig, v in self.flags.items() if v] - traps = [sig for sig, v in self.traps.items() if v] - return (self.__class__, - (self.prec, self.rounding, self.Emin, self.Emax, - self.capitals, self.clamp, flags, traps)) - - def __repr__(self): - """Show the current context.""" - s = [] - s.append('Context(prec=%(prec)d, rounding=%(rounding)s, ' - 'Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d, ' - 'clamp=%(clamp)d' - % vars(self)) - names = [f.__name__ for f, v in self.flags.items() if v] - s.append('flags=[' + ', '.join(names) + ']') - names = [t.__name__ for t, v in self.traps.items() if v] - s.append('traps=[' + ', '.join(names) + ']') - return ', '.join(s) + ')' - - def clear_flags(self): - """Reset all flags to zero""" - for flag in self.flags: - self.flags[flag] = 0 - - def clear_traps(self): - """Reset all traps to zero""" - for flag in self.traps: - self.traps[flag] = 0 - - def _shallow_copy(self): - """Returns a shallow copy from self.""" - nc = Context(self.prec, self.rounding, self.Emin, self.Emax, - self.capitals, self.clamp, self.flags, self.traps, - self._ignored_flags) - return nc - - def copy(self): - """Returns a deep copy from self.""" - nc = Context(self.prec, self.rounding, self.Emin, self.Emax, - self.capitals, self.clamp, - self.flags.copy(), self.traps.copy(), - self._ignored_flags) - return nc - __copy__ = copy - - def _raise_error(self, condition, explanation = None, *args): - """Handles an error - - If the flag is in _ignored_flags, returns the default response. - Otherwise, it sets the flag, then, if the corresponding - trap_enabler is set, it reraises the exception. Otherwise, it returns - the default value after setting the flag. - """ - error = _condition_map.get(condition, condition) - if error in self._ignored_flags: - # Don't touch the flag - return error().handle(self, *args) - - self.flags[error] = 1 - if not self.traps[error]: - # The errors define how to handle themselves. - return condition().handle(self, *args) - - # Errors should only be risked on copies of the context - # self._ignored_flags = [] - raise error(explanation) - - def _ignore_all_flags(self): - """Ignore all flags, if they are raised""" - return self._ignore_flags(*_signals) - - def _ignore_flags(self, *flags): - """Ignore the flags, if they are raised""" - # Do not mutate-- This way, copies of a context leave the original - # alone. - self._ignored_flags = (self._ignored_flags + list(flags)) - return list(flags) - - def _regard_flags(self, *flags): - """Stop ignoring the flags, if they are raised""" - if flags and isinstance(flags[0], (tuple,list)): - flags = flags[0] - for flag in flags: - self._ignored_flags.remove(flag) - - # We inherit object.__hash__, so we must deny this explicitly - __hash__ = None - - def Etiny(self): - """Returns Etiny (= Emin - prec + 1)""" - return int(self.Emin - self.prec + 1) - - def Etop(self): - """Returns maximum exponent (= Emax - prec + 1)""" - return int(self.Emax - self.prec + 1) - - def _set_rounding(self, type): - """Sets the rounding type. - - Sets the rounding type, and returns the current (previous) - rounding type. Often used like: - - context = context.copy() - # so you don't change the calling context - # if an error occurs in the middle. - rounding = context._set_rounding(ROUND_UP) - val = self.__sub__(other, context=context) - context._set_rounding(rounding) - - This will make it round up for that operation. - """ - rounding = self.rounding - self.rounding= type - return rounding - - def create_decimal(self, num='0'): - """Creates a new Decimal instance but using self as context. - - This method implements the to-number operation of the - IBM Decimal specification.""" - - if isinstance(num, str) and num != num.strip(): - return self._raise_error(ConversionSyntax, - "no trailing or leading whitespace is " - "permitted.") - - d = Decimal(num, context=self) - if d._isnan() and len(d._int) > self.prec - self.clamp: - return self._raise_error(ConversionSyntax, - "diagnostic info too long in NaN") - return d._fix(self) - - def create_decimal_from_float(self, f): - """Creates a new Decimal instance from a float but rounding using self - as the context. - - >>> context = Context(prec=5, rounding=ROUND_DOWN) - >>> context.create_decimal_from_float(3.1415926535897932) - Decimal('3.1415') - >>> context = Context(prec=5, traps=[Inexact]) - >>> context.create_decimal_from_float(3.1415926535897932) - Traceback (most recent call last): - ... - decimal.Inexact: None - - """ - d = Decimal.from_float(f) # An exact conversion - return d._fix(self) # Apply the context rounding - - # Methods - def abs(self, a): - """Returns the absolute value of the operand. - - If the operand is negative, the result is the same as using the minus - operation on the operand. Otherwise, the result is the same as using - the plus operation on the operand. - - >>> ExtendedContext.abs(Decimal('2.1')) - Decimal('2.1') - >>> ExtendedContext.abs(Decimal('-100')) - Decimal('100') - >>> ExtendedContext.abs(Decimal('101.5')) - Decimal('101.5') - >>> ExtendedContext.abs(Decimal('-101.5')) - Decimal('101.5') - >>> ExtendedContext.abs(-1) - Decimal('1') - """ - a = _convert_other(a, raiseit=True) - return a.__abs__(context=self) - - def add(self, a, b): - """Return the sum of the two operands. - - >>> ExtendedContext.add(Decimal('12'), Decimal('7.00')) - Decimal('19.00') - >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4')) - Decimal('1.02E+4') - >>> ExtendedContext.add(1, Decimal(2)) - Decimal('3') - >>> ExtendedContext.add(Decimal(8), 5) - Decimal('13') - >>> ExtendedContext.add(5, 5) - Decimal('10') - """ - a = _convert_other(a, raiseit=True) - r = a.__add__(b, context=self) - if r is NotImplemented: - raise TypeError("Unable to convert %s to Decimal" % b) - else: - return r - - def _apply(self, a): - return str(a._fix(self)) - - def canonical(self, a): - """Returns the same Decimal object. - - As we do not have different encodings for the same number, the - received object already is in its canonical form. - - >>> ExtendedContext.canonical(Decimal('2.50')) - Decimal('2.50') - """ - if not isinstance(a, Decimal): - raise TypeError("canonical requires a Decimal as an argument.") - return a.canonical() - - def compare(self, a, b): - """Compares values numerically. - - If the signs of the operands differ, a value representing each operand - ('-1' if the operand is less than zero, '0' if the operand is zero or - negative zero, or '1' if the operand is greater than zero) is used in - place of that operand for the comparison instead of the actual - operand. - - The comparison is then effected by subtracting the second operand from - the first and then returning a value according to the result of the - subtraction: '-1' if the result is less than zero, '0' if the result is - zero or negative zero, or '1' if the result is greater than zero. - - >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3')) - Decimal('-1') - >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1')) - Decimal('0') - >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10')) - Decimal('0') - >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1')) - Decimal('1') - >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3')) - Decimal('1') - >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1')) - Decimal('-1') - >>> ExtendedContext.compare(1, 2) - Decimal('-1') - >>> ExtendedContext.compare(Decimal(1), 2) - Decimal('-1') - >>> ExtendedContext.compare(1, Decimal(2)) - Decimal('-1') - """ - a = _convert_other(a, raiseit=True) - return a.compare(b, context=self) - - def compare_signal(self, a, b): - """Compares the values of the two operands numerically. - - It's pretty much like compare(), but all NaNs signal, with signaling - NaNs taking precedence over quiet NaNs. - - >>> c = ExtendedContext - >>> c.compare_signal(Decimal('2.1'), Decimal('3')) - Decimal('-1') - >>> c.compare_signal(Decimal('2.1'), Decimal('2.1')) - Decimal('0') - >>> c.flags[InvalidOperation] = 0 - >>> print(c.flags[InvalidOperation]) - 0 - >>> c.compare_signal(Decimal('NaN'), Decimal('2.1')) - Decimal('NaN') - >>> print(c.flags[InvalidOperation]) - 1 - >>> c.flags[InvalidOperation] = 0 - >>> print(c.flags[InvalidOperation]) - 0 - >>> c.compare_signal(Decimal('sNaN'), Decimal('2.1')) - Decimal('NaN') - >>> print(c.flags[InvalidOperation]) - 1 - >>> c.compare_signal(-1, 2) - Decimal('-1') - >>> c.compare_signal(Decimal(-1), 2) - Decimal('-1') - >>> c.compare_signal(-1, Decimal(2)) - Decimal('-1') - """ - a = _convert_other(a, raiseit=True) - return a.compare_signal(b, context=self) - - def compare_total(self, a, b): - """Compares two operands using their abstract representation. - - This is not like the standard compare, which use their numerical - value. Note that a total ordering is defined for all possible abstract - representations. - - >>> ExtendedContext.compare_total(Decimal('12.73'), Decimal('127.9')) - Decimal('-1') - >>> ExtendedContext.compare_total(Decimal('-127'), Decimal('12')) - Decimal('-1') - >>> ExtendedContext.compare_total(Decimal('12.30'), Decimal('12.3')) - Decimal('-1') - >>> ExtendedContext.compare_total(Decimal('12.30'), Decimal('12.30')) - Decimal('0') - >>> ExtendedContext.compare_total(Decimal('12.3'), Decimal('12.300')) - Decimal('1') - >>> ExtendedContext.compare_total(Decimal('12.3'), Decimal('NaN')) - Decimal('-1') - >>> ExtendedContext.compare_total(1, 2) - Decimal('-1') - >>> ExtendedContext.compare_total(Decimal(1), 2) - Decimal('-1') - >>> ExtendedContext.compare_total(1, Decimal(2)) - Decimal('-1') - """ - a = _convert_other(a, raiseit=True) - return a.compare_total(b) - - def compare_total_mag(self, a, b): - """Compares two operands using their abstract representation ignoring sign. - - Like compare_total, but with operand's sign ignored and assumed to be 0. - """ - a = _convert_other(a, raiseit=True) - return a.compare_total_mag(b) - - def copy_abs(self, a): - """Returns a copy of the operand with the sign set to 0. - - >>> ExtendedContext.copy_abs(Decimal('2.1')) - Decimal('2.1') - >>> ExtendedContext.copy_abs(Decimal('-100')) - Decimal('100') - >>> ExtendedContext.copy_abs(-1) - Decimal('1') - """ - a = _convert_other(a, raiseit=True) - return a.copy_abs() - - def copy_decimal(self, a): - """Returns a copy of the decimal object. - - >>> ExtendedContext.copy_decimal(Decimal('2.1')) - Decimal('2.1') - >>> ExtendedContext.copy_decimal(Decimal('-1.00')) - Decimal('-1.00') - >>> ExtendedContext.copy_decimal(1) - Decimal('1') - """ - a = _convert_other(a, raiseit=True) - return Decimal(a) - - def copy_negate(self, a): - """Returns a copy of the operand with the sign inverted. - - >>> ExtendedContext.copy_negate(Decimal('101.5')) - Decimal('-101.5') - >>> ExtendedContext.copy_negate(Decimal('-101.5')) - Decimal('101.5') - >>> ExtendedContext.copy_negate(1) - Decimal('-1') - """ - a = _convert_other(a, raiseit=True) - return a.copy_negate() - - def copy_sign(self, a, b): - """Copies the second operand's sign to the first one. - - In detail, it returns a copy of the first operand with the sign - equal to the sign of the second operand. - - >>> ExtendedContext.copy_sign(Decimal( '1.50'), Decimal('7.33')) - Decimal('1.50') - >>> ExtendedContext.copy_sign(Decimal('-1.50'), Decimal('7.33')) - Decimal('1.50') - >>> ExtendedContext.copy_sign(Decimal( '1.50'), Decimal('-7.33')) - Decimal('-1.50') - >>> ExtendedContext.copy_sign(Decimal('-1.50'), Decimal('-7.33')) - Decimal('-1.50') - >>> ExtendedContext.copy_sign(1, -2) - Decimal('-1') - >>> ExtendedContext.copy_sign(Decimal(1), -2) - Decimal('-1') - >>> ExtendedContext.copy_sign(1, Decimal(-2)) - Decimal('-1') - """ - a = _convert_other(a, raiseit=True) - return a.copy_sign(b) - - def divide(self, a, b): - """Decimal division in a specified context. - - >>> ExtendedContext.divide(Decimal('1'), Decimal('3')) - Decimal('0.333333333') - >>> ExtendedContext.divide(Decimal('2'), Decimal('3')) - Decimal('0.666666667') - >>> ExtendedContext.divide(Decimal('5'), Decimal('2')) - Decimal('2.5') - >>> ExtendedContext.divide(Decimal('1'), Decimal('10')) - Decimal('0.1') - >>> ExtendedContext.divide(Decimal('12'), Decimal('12')) - Decimal('1') - >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2')) - Decimal('4.00') - >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0')) - Decimal('1.20') - >>> ExtendedContext.divide(Decimal('1000'), Decimal('100')) - Decimal('10') - >>> ExtendedContext.divide(Decimal('1000'), Decimal('1')) - Decimal('1000') - >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2')) - Decimal('1.20E+6') - >>> ExtendedContext.divide(5, 5) - Decimal('1') - >>> ExtendedContext.divide(Decimal(5), 5) - Decimal('1') - >>> ExtendedContext.divide(5, Decimal(5)) - Decimal('1') - """ - a = _convert_other(a, raiseit=True) - r = a.__truediv__(b, context=self) - if r is NotImplemented: - raise TypeError("Unable to convert %s to Decimal" % b) - else: - return r - - def divide_int(self, a, b): - """Divides two numbers and returns the integer part of the result. - - >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3')) - Decimal('0') - >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3')) - Decimal('3') - >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3')) - Decimal('3') - >>> ExtendedContext.divide_int(10, 3) - Decimal('3') - >>> ExtendedContext.divide_int(Decimal(10), 3) - Decimal('3') - >>> ExtendedContext.divide_int(10, Decimal(3)) - Decimal('3') - """ - a = _convert_other(a, raiseit=True) - r = a.__floordiv__(b, context=self) - if r is NotImplemented: - raise TypeError("Unable to convert %s to Decimal" % b) - else: - return r - - def divmod(self, a, b): - """Return (a // b, a % b). - - >>> ExtendedContext.divmod(Decimal(8), Decimal(3)) - (Decimal('2'), Decimal('2')) - >>> ExtendedContext.divmod(Decimal(8), Decimal(4)) - (Decimal('2'), Decimal('0')) - >>> ExtendedContext.divmod(8, 4) - (Decimal('2'), Decimal('0')) - >>> ExtendedContext.divmod(Decimal(8), 4) - (Decimal('2'), Decimal('0')) - >>> ExtendedContext.divmod(8, Decimal(4)) - (Decimal('2'), Decimal('0')) - """ - a = _convert_other(a, raiseit=True) - r = a.__divmod__(b, context=self) - if r is NotImplemented: - raise TypeError("Unable to convert %s to Decimal" % b) - else: - return r - - def exp(self, a): - """Returns e ** a. - - >>> c = ExtendedContext.copy() - >>> c.Emin = -999 - >>> c.Emax = 999 - >>> c.exp(Decimal('-Infinity')) - Decimal('0') - >>> c.exp(Decimal('-1')) - Decimal('0.367879441') - >>> c.exp(Decimal('0')) - Decimal('1') - >>> c.exp(Decimal('1')) - Decimal('2.71828183') - >>> c.exp(Decimal('0.693147181')) - Decimal('2.00000000') - >>> c.exp(Decimal('+Infinity')) - Decimal('Infinity') - >>> c.exp(10) - Decimal('22026.4658') - """ - a =_convert_other(a, raiseit=True) - return a.exp(context=self) - - def fma(self, a, b, c): - """Returns a multiplied by b, plus c. - - The first two operands are multiplied together, using multiply, - the third operand is then added to the result of that - multiplication, using add, all with only one final rounding. - - >>> ExtendedContext.fma(Decimal('3'), Decimal('5'), Decimal('7')) - Decimal('22') - >>> ExtendedContext.fma(Decimal('3'), Decimal('-5'), Decimal('7')) - Decimal('-8') - >>> ExtendedContext.fma(Decimal('888565290'), Decimal('1557.96930'), Decimal('-86087.7578')) - Decimal('1.38435736E+12') - >>> ExtendedContext.fma(1, 3, 4) - Decimal('7') - >>> ExtendedContext.fma(1, Decimal(3), 4) - Decimal('7') - >>> ExtendedContext.fma(1, 3, Decimal(4)) - Decimal('7') - """ - a = _convert_other(a, raiseit=True) - return a.fma(b, c, context=self) - - def is_canonical(self, a): - """Return True if the operand is canonical; otherwise return False. - - Currently, the encoding of a Decimal instance is always - canonical, so this method returns True for any Decimal. - - >>> ExtendedContext.is_canonical(Decimal('2.50')) - True - """ - if not isinstance(a, Decimal): - raise TypeError("is_canonical requires a Decimal as an argument.") - return a.is_canonical() - - def is_finite(self, a): - """Return True if the operand is finite; otherwise return False. - - A Decimal instance is considered finite if it is neither - infinite nor a NaN. - - >>> ExtendedContext.is_finite(Decimal('2.50')) - True - >>> ExtendedContext.is_finite(Decimal('-0.3')) - True - >>> ExtendedContext.is_finite(Decimal('0')) - True - >>> ExtendedContext.is_finite(Decimal('Inf')) - False - >>> ExtendedContext.is_finite(Decimal('NaN')) - False - >>> ExtendedContext.is_finite(1) - True - """ - a = _convert_other(a, raiseit=True) - return a.is_finite() - - def is_infinite(self, a): - """Return True if the operand is infinite; otherwise return False. - - >>> ExtendedContext.is_infinite(Decimal('2.50')) - False - >>> ExtendedContext.is_infinite(Decimal('-Inf')) - True - >>> ExtendedContext.is_infinite(Decimal('NaN')) - False - >>> ExtendedContext.is_infinite(1) - False - """ - a = _convert_other(a, raiseit=True) - return a.is_infinite() - - def is_nan(self, a): - """Return True if the operand is a qNaN or sNaN; - otherwise return False. - - >>> ExtendedContext.is_nan(Decimal('2.50')) - False - >>> ExtendedContext.is_nan(Decimal('NaN')) - True - >>> ExtendedContext.is_nan(Decimal('-sNaN')) - True - >>> ExtendedContext.is_nan(1) - False - """ - a = _convert_other(a, raiseit=True) - return a.is_nan() - - def is_normal(self, a): - """Return True if the operand is a normal number; - otherwise return False. - - >>> c = ExtendedContext.copy() - >>> c.Emin = -999 - >>> c.Emax = 999 - >>> c.is_normal(Decimal('2.50')) - True - >>> c.is_normal(Decimal('0.1E-999')) - False - >>> c.is_normal(Decimal('0.00')) - False - >>> c.is_normal(Decimal('-Inf')) - False - >>> c.is_normal(Decimal('NaN')) - False - >>> c.is_normal(1) - True - """ - a = _convert_other(a, raiseit=True) - return a.is_normal(context=self) - - def is_qnan(self, a): - """Return True if the operand is a quiet NaN; otherwise return False. - - >>> ExtendedContext.is_qnan(Decimal('2.50')) - False - >>> ExtendedContext.is_qnan(Decimal('NaN')) - True - >>> ExtendedContext.is_qnan(Decimal('sNaN')) - False - >>> ExtendedContext.is_qnan(1) - False - """ - a = _convert_other(a, raiseit=True) - return a.is_qnan() - - def is_signed(self, a): - """Return True if the operand is negative; otherwise return False. - - >>> ExtendedContext.is_signed(Decimal('2.50')) - False - >>> ExtendedContext.is_signed(Decimal('-12')) - True - >>> ExtendedContext.is_signed(Decimal('-0')) - True - >>> ExtendedContext.is_signed(8) - False - >>> ExtendedContext.is_signed(-8) - True - """ - a = _convert_other(a, raiseit=True) - return a.is_signed() - - def is_snan(self, a): - """Return True if the operand is a signaling NaN; - otherwise return False. - - >>> ExtendedContext.is_snan(Decimal('2.50')) - False - >>> ExtendedContext.is_snan(Decimal('NaN')) - False - >>> ExtendedContext.is_snan(Decimal('sNaN')) - True - >>> ExtendedContext.is_snan(1) - False - """ - a = _convert_other(a, raiseit=True) - return a.is_snan() - - def is_subnormal(self, a): - """Return True if the operand is subnormal; otherwise return False. - - >>> c = ExtendedContext.copy() - >>> c.Emin = -999 - >>> c.Emax = 999 - >>> c.is_subnormal(Decimal('2.50')) - False - >>> c.is_subnormal(Decimal('0.1E-999')) - True - >>> c.is_subnormal(Decimal('0.00')) - False - >>> c.is_subnormal(Decimal('-Inf')) - False - >>> c.is_subnormal(Decimal('NaN')) - False - >>> c.is_subnormal(1) - False - """ - a = _convert_other(a, raiseit=True) - return a.is_subnormal(context=self) - - def is_zero(self, a): - """Return True if the operand is a zero; otherwise return False. - - >>> ExtendedContext.is_zero(Decimal('0')) - True - >>> ExtendedContext.is_zero(Decimal('2.50')) - False - >>> ExtendedContext.is_zero(Decimal('-0E+2')) - True - >>> ExtendedContext.is_zero(1) - False - >>> ExtendedContext.is_zero(0) - True - """ - a = _convert_other(a, raiseit=True) - return a.is_zero() - - def ln(self, a): - """Returns the natural (base e) logarithm of the operand. - - >>> c = ExtendedContext.copy() - >>> c.Emin = -999 - >>> c.Emax = 999 - >>> c.ln(Decimal('0')) - Decimal('-Infinity') - >>> c.ln(Decimal('1.000')) - Decimal('0') - >>> c.ln(Decimal('2.71828183')) - Decimal('1.00000000') - >>> c.ln(Decimal('10')) - Decimal('2.30258509') - >>> c.ln(Decimal('+Infinity')) - Decimal('Infinity') - >>> c.ln(1) - Decimal('0') - """ - a = _convert_other(a, raiseit=True) - return a.ln(context=self) - - def log10(self, a): - """Returns the base 10 logarithm of the operand. - - >>> c = ExtendedContext.copy() - >>> c.Emin = -999 - >>> c.Emax = 999 - >>> c.log10(Decimal('0')) - Decimal('-Infinity') - >>> c.log10(Decimal('0.001')) - Decimal('-3') - >>> c.log10(Decimal('1.000')) - Decimal('0') - >>> c.log10(Decimal('2')) - Decimal('0.301029996') - >>> c.log10(Decimal('10')) - Decimal('1') - >>> c.log10(Decimal('70')) - Decimal('1.84509804') - >>> c.log10(Decimal('+Infinity')) - Decimal('Infinity') - >>> c.log10(0) - Decimal('-Infinity') - >>> c.log10(1) - Decimal('0') - """ - a = _convert_other(a, raiseit=True) - return a.log10(context=self) - - def logb(self, a): - """ Returns the exponent of the magnitude of the operand's MSD. - - The result is the integer which is the exponent of the magnitude - of the most significant digit of the operand (as though the - operand were truncated to a single digit while maintaining the - value of that digit and without limiting the resulting exponent). - - >>> ExtendedContext.logb(Decimal('250')) - Decimal('2') - >>> ExtendedContext.logb(Decimal('2.50')) - Decimal('0') - >>> ExtendedContext.logb(Decimal('0.03')) - Decimal('-2') - >>> ExtendedContext.logb(Decimal('0')) - Decimal('-Infinity') - >>> ExtendedContext.logb(1) - Decimal('0') - >>> ExtendedContext.logb(10) - Decimal('1') - >>> ExtendedContext.logb(100) - Decimal('2') - """ - a = _convert_other(a, raiseit=True) - return a.logb(context=self) - - def logical_and(self, a, b): - """Applies the logical operation 'and' between each operand's digits. - - The operands must be both logical numbers. - - >>> ExtendedContext.logical_and(Decimal('0'), Decimal('0')) - Decimal('0') - >>> ExtendedContext.logical_and(Decimal('0'), Decimal('1')) - Decimal('0') - >>> ExtendedContext.logical_and(Decimal('1'), Decimal('0')) - Decimal('0') - >>> ExtendedContext.logical_and(Decimal('1'), Decimal('1')) - Decimal('1') - >>> ExtendedContext.logical_and(Decimal('1100'), Decimal('1010')) - Decimal('1000') - >>> ExtendedContext.logical_and(Decimal('1111'), Decimal('10')) - Decimal('10') - >>> ExtendedContext.logical_and(110, 1101) - Decimal('100') - >>> ExtendedContext.logical_and(Decimal(110), 1101) - Decimal('100') - >>> ExtendedContext.logical_and(110, Decimal(1101)) - Decimal('100') - """ - a = _convert_other(a, raiseit=True) - return a.logical_and(b, context=self) - - def logical_invert(self, a): - """Invert all the digits in the operand. - - The operand must be a logical number. - - >>> ExtendedContext.logical_invert(Decimal('0')) - Decimal('111111111') - >>> ExtendedContext.logical_invert(Decimal('1')) - Decimal('111111110') - >>> ExtendedContext.logical_invert(Decimal('111111111')) - Decimal('0') - >>> ExtendedContext.logical_invert(Decimal('101010101')) - Decimal('10101010') - >>> ExtendedContext.logical_invert(1101) - Decimal('111110010') - """ - a = _convert_other(a, raiseit=True) - return a.logical_invert(context=self) - - def logical_or(self, a, b): - """Applies the logical operation 'or' between each operand's digits. - - The operands must be both logical numbers. - - >>> ExtendedContext.logical_or(Decimal('0'), Decimal('0')) - Decimal('0') - >>> ExtendedContext.logical_or(Decimal('0'), Decimal('1')) - Decimal('1') - >>> ExtendedContext.logical_or(Decimal('1'), Decimal('0')) - Decimal('1') - >>> ExtendedContext.logical_or(Decimal('1'), Decimal('1')) - Decimal('1') - >>> ExtendedContext.logical_or(Decimal('1100'), Decimal('1010')) - Decimal('1110') - >>> ExtendedContext.logical_or(Decimal('1110'), Decimal('10')) - Decimal('1110') - >>> ExtendedContext.logical_or(110, 1101) - Decimal('1111') - >>> ExtendedContext.logical_or(Decimal(110), 1101) - Decimal('1111') - >>> ExtendedContext.logical_or(110, Decimal(1101)) - Decimal('1111') - """ - a = _convert_other(a, raiseit=True) - return a.logical_or(b, context=self) - - def logical_xor(self, a, b): - """Applies the logical operation 'xor' between each operand's digits. - - The operands must be both logical numbers. - - >>> ExtendedContext.logical_xor(Decimal('0'), Decimal('0')) - Decimal('0') - >>> ExtendedContext.logical_xor(Decimal('0'), Decimal('1')) - Decimal('1') - >>> ExtendedContext.logical_xor(Decimal('1'), Decimal('0')) - Decimal('1') - >>> ExtendedContext.logical_xor(Decimal('1'), Decimal('1')) - Decimal('0') - >>> ExtendedContext.logical_xor(Decimal('1100'), Decimal('1010')) - Decimal('110') - >>> ExtendedContext.logical_xor(Decimal('1111'), Decimal('10')) - Decimal('1101') - >>> ExtendedContext.logical_xor(110, 1101) - Decimal('1011') - >>> ExtendedContext.logical_xor(Decimal(110), 1101) - Decimal('1011') - >>> ExtendedContext.logical_xor(110, Decimal(1101)) - Decimal('1011') - """ - a = _convert_other(a, raiseit=True) - return a.logical_xor(b, context=self) - - def max(self, a, b): - """max compares two values numerically and returns the maximum. - - If either operand is a NaN then the general rules apply. - Otherwise, the operands are compared as though by the compare - operation. If they are numerically equal then the left-hand operand - is chosen as the result. Otherwise the maximum (closer to positive - infinity) of the two operands is chosen as the result. - - >>> ExtendedContext.max(Decimal('3'), Decimal('2')) - Decimal('3') - >>> ExtendedContext.max(Decimal('-10'), Decimal('3')) - Decimal('3') - >>> ExtendedContext.max(Decimal('1.0'), Decimal('1')) - Decimal('1') - >>> ExtendedContext.max(Decimal('7'), Decimal('NaN')) - Decimal('7') - >>> ExtendedContext.max(1, 2) - Decimal('2') - >>> ExtendedContext.max(Decimal(1), 2) - Decimal('2') - >>> ExtendedContext.max(1, Decimal(2)) - Decimal('2') - """ - a = _convert_other(a, raiseit=True) - return a.max(b, context=self) - - def max_mag(self, a, b): - """Compares the values numerically with their sign ignored. - - >>> ExtendedContext.max_mag(Decimal('7'), Decimal('NaN')) - Decimal('7') - >>> ExtendedContext.max_mag(Decimal('7'), Decimal('-10')) - Decimal('-10') - >>> ExtendedContext.max_mag(1, -2) - Decimal('-2') - >>> ExtendedContext.max_mag(Decimal(1), -2) - Decimal('-2') - >>> ExtendedContext.max_mag(1, Decimal(-2)) - Decimal('-2') - """ - a = _convert_other(a, raiseit=True) - return a.max_mag(b, context=self) - - def min(self, a, b): - """min compares two values numerically and returns the minimum. - - If either operand is a NaN then the general rules apply. - Otherwise, the operands are compared as though by the compare - operation. If they are numerically equal then the left-hand operand - is chosen as the result. Otherwise the minimum (closer to negative - infinity) of the two operands is chosen as the result. - - >>> ExtendedContext.min(Decimal('3'), Decimal('2')) - Decimal('2') - >>> ExtendedContext.min(Decimal('-10'), Decimal('3')) - Decimal('-10') - >>> ExtendedContext.min(Decimal('1.0'), Decimal('1')) - Decimal('1.0') - >>> ExtendedContext.min(Decimal('7'), Decimal('NaN')) - Decimal('7') - >>> ExtendedContext.min(1, 2) - Decimal('1') - >>> ExtendedContext.min(Decimal(1), 2) - Decimal('1') - >>> ExtendedContext.min(1, Decimal(29)) - Decimal('1') - """ - a = _convert_other(a, raiseit=True) - return a.min(b, context=self) - - def min_mag(self, a, b): - """Compares the values numerically with their sign ignored. - - >>> ExtendedContext.min_mag(Decimal('3'), Decimal('-2')) - Decimal('-2') - >>> ExtendedContext.min_mag(Decimal('-3'), Decimal('NaN')) - Decimal('-3') - >>> ExtendedContext.min_mag(1, -2) - Decimal('1') - >>> ExtendedContext.min_mag(Decimal(1), -2) - Decimal('1') - >>> ExtendedContext.min_mag(1, Decimal(-2)) - Decimal('1') - """ - a = _convert_other(a, raiseit=True) - return a.min_mag(b, context=self) - - def minus(self, a): - """Minus corresponds to unary prefix minus in Python. - - The operation is evaluated using the same rules as subtract; the - operation minus(a) is calculated as subtract('0', a) where the '0' - has the same exponent as the operand. - - >>> ExtendedContext.minus(Decimal('1.3')) - Decimal('-1.3') - >>> ExtendedContext.minus(Decimal('-1.3')) - Decimal('1.3') - >>> ExtendedContext.minus(1) - Decimal('-1') - """ - a = _convert_other(a, raiseit=True) - return a.__neg__(context=self) - - def multiply(self, a, b): - """multiply multiplies two operands. - - If either operand is a special value then the general rules apply. - Otherwise, the operands are multiplied together - ('long multiplication'), resulting in a number which may be as long as - the sum of the lengths of the two operands. - - >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3')) - Decimal('3.60') - >>> ExtendedContext.multiply(Decimal('7'), Decimal('3')) - Decimal('21') - >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8')) - Decimal('0.72') - >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0')) - Decimal('-0.0') - >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321')) - Decimal('4.28135971E+11') - >>> ExtendedContext.multiply(7, 7) - Decimal('49') - >>> ExtendedContext.multiply(Decimal(7), 7) - Decimal('49') - >>> ExtendedContext.multiply(7, Decimal(7)) - Decimal('49') - """ - a = _convert_other(a, raiseit=True) - r = a.__mul__(b, context=self) - if r is NotImplemented: - raise TypeError("Unable to convert %s to Decimal" % b) - else: - return r - - def next_minus(self, a): - """Returns the largest representable number smaller than a. - - >>> c = ExtendedContext.copy() - >>> c.Emin = -999 - >>> c.Emax = 999 - >>> ExtendedContext.next_minus(Decimal('1')) - Decimal('0.999999999') - >>> c.next_minus(Decimal('1E-1007')) - Decimal('0E-1007') - >>> ExtendedContext.next_minus(Decimal('-1.00000003')) - Decimal('-1.00000004') - >>> c.next_minus(Decimal('Infinity')) - Decimal('9.99999999E+999') - >>> c.next_minus(1) - Decimal('0.999999999') - """ - a = _convert_other(a, raiseit=True) - return a.next_minus(context=self) - - def next_plus(self, a): - """Returns the smallest representable number larger than a. - - >>> c = ExtendedContext.copy() - >>> c.Emin = -999 - >>> c.Emax = 999 - >>> ExtendedContext.next_plus(Decimal('1')) - Decimal('1.00000001') - >>> c.next_plus(Decimal('-1E-1007')) - Decimal('-0E-1007') - >>> ExtendedContext.next_plus(Decimal('-1.00000003')) - Decimal('-1.00000002') - >>> c.next_plus(Decimal('-Infinity')) - Decimal('-9.99999999E+999') - >>> c.next_plus(1) - Decimal('1.00000001') - """ - a = _convert_other(a, raiseit=True) - return a.next_plus(context=self) - - def next_toward(self, a, b): - """Returns the number closest to a, in direction towards b. - - The result is the closest representable number from the first - operand (but not the first operand) that is in the direction - towards the second operand, unless the operands have the same - value. - - >>> c = ExtendedContext.copy() - >>> c.Emin = -999 - >>> c.Emax = 999 - >>> c.next_toward(Decimal('1'), Decimal('2')) - Decimal('1.00000001') - >>> c.next_toward(Decimal('-1E-1007'), Decimal('1')) - Decimal('-0E-1007') - >>> c.next_toward(Decimal('-1.00000003'), Decimal('0')) - Decimal('-1.00000002') - >>> c.next_toward(Decimal('1'), Decimal('0')) - Decimal('0.999999999') - >>> c.next_toward(Decimal('1E-1007'), Decimal('-100')) - Decimal('0E-1007') - >>> c.next_toward(Decimal('-1.00000003'), Decimal('-10')) - Decimal('-1.00000004') - >>> c.next_toward(Decimal('0.00'), Decimal('-0.0000')) - Decimal('-0.00') - >>> c.next_toward(0, 1) - Decimal('1E-1007') - >>> c.next_toward(Decimal(0), 1) - Decimal('1E-1007') - >>> c.next_toward(0, Decimal(1)) - Decimal('1E-1007') - """ - a = _convert_other(a, raiseit=True) - return a.next_toward(b, context=self) - - def normalize(self, a): - """normalize reduces an operand to its simplest form. - - Essentially a plus operation with all trailing zeros removed from the - result. - - >>> ExtendedContext.normalize(Decimal('2.1')) - Decimal('2.1') - >>> ExtendedContext.normalize(Decimal('-2.0')) - Decimal('-2') - >>> ExtendedContext.normalize(Decimal('1.200')) - Decimal('1.2') - >>> ExtendedContext.normalize(Decimal('-120')) - Decimal('-1.2E+2') - >>> ExtendedContext.normalize(Decimal('120.00')) - Decimal('1.2E+2') - >>> ExtendedContext.normalize(Decimal('0.00')) - Decimal('0') - >>> ExtendedContext.normalize(6) - Decimal('6') - """ - a = _convert_other(a, raiseit=True) - return a.normalize(context=self) - - def number_class(self, a): - """Returns an indication of the class of the operand. - - The class is one of the following strings: - -sNaN - -NaN - -Infinity - -Normal - -Subnormal - -Zero - +Zero - +Subnormal - +Normal - +Infinity - - >>> c = ExtendedContext.copy() - >>> c.Emin = -999 - >>> c.Emax = 999 - >>> c.number_class(Decimal('Infinity')) - '+Infinity' - >>> c.number_class(Decimal('1E-10')) - '+Normal' - >>> c.number_class(Decimal('2.50')) - '+Normal' - >>> c.number_class(Decimal('0.1E-999')) - '+Subnormal' - >>> c.number_class(Decimal('0')) - '+Zero' - >>> c.number_class(Decimal('-0')) - '-Zero' - >>> c.number_class(Decimal('-0.1E-999')) - '-Subnormal' - >>> c.number_class(Decimal('-1E-10')) - '-Normal' - >>> c.number_class(Decimal('-2.50')) - '-Normal' - >>> c.number_class(Decimal('-Infinity')) - '-Infinity' - >>> c.number_class(Decimal('NaN')) - 'NaN' - >>> c.number_class(Decimal('-NaN')) - 'NaN' - >>> c.number_class(Decimal('sNaN')) - 'sNaN' - >>> c.number_class(123) - '+Normal' - """ - a = _convert_other(a, raiseit=True) - return a.number_class(context=self) - - def plus(self, a): - """Plus corresponds to unary prefix plus in Python. - - The operation is evaluated using the same rules as add; the - operation plus(a) is calculated as add('0', a) where the '0' - has the same exponent as the operand. - - >>> ExtendedContext.plus(Decimal('1.3')) - Decimal('1.3') - >>> ExtendedContext.plus(Decimal('-1.3')) - Decimal('-1.3') - >>> ExtendedContext.plus(-1) - Decimal('-1') - """ - a = _convert_other(a, raiseit=True) - return a.__pos__(context=self) - - def power(self, a, b, modulo=None): - """Raises a to the power of b, to modulo if given. - - With two arguments, compute a**b. If a is negative then b - must be integral. The result will be inexact unless b is - integral and the result is finite and can be expressed exactly - in 'precision' digits. - - With three arguments, compute (a**b) % modulo. For the - three argument form, the following restrictions on the - arguments hold: - - - all three arguments must be integral - - b must be nonnegative - - at least one of a or b must be nonzero - - modulo must be nonzero and have at most 'precision' digits - - The result of pow(a, b, modulo) is identical to the result - that would be obtained by computing (a**b) % modulo with - unbounded precision, but is computed more efficiently. It is - always exact. - - >>> c = ExtendedContext.copy() - >>> c.Emin = -999 - >>> c.Emax = 999 - >>> c.power(Decimal('2'), Decimal('3')) - Decimal('8') - >>> c.power(Decimal('-2'), Decimal('3')) - Decimal('-8') - >>> c.power(Decimal('2'), Decimal('-3')) - Decimal('0.125') - >>> c.power(Decimal('1.7'), Decimal('8')) - Decimal('69.7575744') - >>> c.power(Decimal('10'), Decimal('0.301029996')) - Decimal('2.00000000') - >>> c.power(Decimal('Infinity'), Decimal('-1')) - Decimal('0') - >>> c.power(Decimal('Infinity'), Decimal('0')) - Decimal('1') - >>> c.power(Decimal('Infinity'), Decimal('1')) - Decimal('Infinity') - >>> c.power(Decimal('-Infinity'), Decimal('-1')) - Decimal('-0') - >>> c.power(Decimal('-Infinity'), Decimal('0')) - Decimal('1') - >>> c.power(Decimal('-Infinity'), Decimal('1')) - Decimal('-Infinity') - >>> c.power(Decimal('-Infinity'), Decimal('2')) - Decimal('Infinity') - >>> c.power(Decimal('0'), Decimal('0')) - Decimal('NaN') - - >>> c.power(Decimal('3'), Decimal('7'), Decimal('16')) - Decimal('11') - >>> c.power(Decimal('-3'), Decimal('7'), Decimal('16')) - Decimal('-11') - >>> c.power(Decimal('-3'), Decimal('8'), Decimal('16')) - Decimal('1') - >>> c.power(Decimal('3'), Decimal('7'), Decimal('-16')) - Decimal('11') - >>> c.power(Decimal('23E12345'), Decimal('67E189'), Decimal('123456789')) - Decimal('11729830') - >>> c.power(Decimal('-0'), Decimal('17'), Decimal('1729')) - Decimal('-0') - >>> c.power(Decimal('-23'), Decimal('0'), Decimal('65537')) - Decimal('1') - >>> ExtendedContext.power(7, 7) - Decimal('823543') - >>> ExtendedContext.power(Decimal(7), 7) - Decimal('823543') - >>> ExtendedContext.power(7, Decimal(7), 2) - Decimal('1') - """ - a = _convert_other(a, raiseit=True) - r = a.__pow__(b, modulo, context=self) - if r is NotImplemented: - raise TypeError("Unable to convert %s to Decimal" % b) - else: - return r - - def quantize(self, a, b): - """Returns a value equal to 'a' (rounded), having the exponent of 'b'. - - The coefficient of the result is derived from that of the left-hand - operand. It may be rounded using the current rounding setting (if the - exponent is being increased), multiplied by a positive power of ten (if - the exponent is being decreased), or is unchanged (if the exponent is - already equal to that of the right-hand operand). - - Unlike other operations, if the length of the coefficient after the - quantize operation would be greater than precision then an Invalid - operation condition is raised. This guarantees that, unless there is - an error condition, the exponent of the result of a quantize is always - equal to that of the right-hand operand. - - Also unlike other operations, quantize will never raise Underflow, even - if the result is subnormal and inexact. - - >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001')) - Decimal('2.170') - >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01')) - Decimal('2.17') - >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1')) - Decimal('2.2') - >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0')) - Decimal('2') - >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1')) - Decimal('0E+1') - >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity')) - Decimal('-Infinity') - >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity')) - Decimal('NaN') - >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1')) - Decimal('-0') - >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5')) - Decimal('-0E+5') - >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2')) - Decimal('NaN') - >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2')) - Decimal('NaN') - >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1')) - Decimal('217.0') - >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0')) - Decimal('217') - >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1')) - Decimal('2.2E+2') - >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2')) - Decimal('2E+2') - >>> ExtendedContext.quantize(1, 2) - Decimal('1') - >>> ExtendedContext.quantize(Decimal(1), 2) - Decimal('1') - >>> ExtendedContext.quantize(1, Decimal(2)) - Decimal('1') - """ - a = _convert_other(a, raiseit=True) - return a.quantize(b, context=self) - - def radix(self): - """Just returns 10, as this is Decimal, :) - - >>> ExtendedContext.radix() - Decimal('10') - """ - return Decimal(10) - - def remainder(self, a, b): - """Returns the remainder from integer division. - - The result is the residue of the dividend after the operation of - calculating integer division as described for divide-integer, rounded - to precision digits if necessary. The sign of the result, if - non-zero, is the same as that of the original dividend. - - This operation will fail under the same conditions as integer division - (that is, if integer division on the same two operands would fail, the - remainder cannot be calculated). - - >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3')) - Decimal('2.1') - >>> ExtendedContext.remainder(Decimal('10'), Decimal('3')) - Decimal('1') - >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3')) - Decimal('-1') - >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1')) - Decimal('0.2') - >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3')) - Decimal('0.1') - >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3')) - Decimal('1.0') - >>> ExtendedContext.remainder(22, 6) - Decimal('4') - >>> ExtendedContext.remainder(Decimal(22), 6) - Decimal('4') - >>> ExtendedContext.remainder(22, Decimal(6)) - Decimal('4') - """ - a = _convert_other(a, raiseit=True) - r = a.__mod__(b, context=self) - if r is NotImplemented: - raise TypeError("Unable to convert %s to Decimal" % b) - else: - return r - - def remainder_near(self, a, b): - """Returns to be "a - b * n", where n is the integer nearest the exact - value of "x / b" (if two integers are equally near then the even one - is chosen). If the result is equal to 0 then its sign will be the - sign of a. - - This operation will fail under the same conditions as integer division - (that is, if integer division on the same two operands would fail, the - remainder cannot be calculated). - - >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3')) - Decimal('-0.9') - >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6')) - Decimal('-2') - >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3')) - Decimal('1') - >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3')) - Decimal('-1') - >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1')) - Decimal('0.2') - >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3')) - Decimal('0.1') - >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3')) - Decimal('-0.3') - >>> ExtendedContext.remainder_near(3, 11) - Decimal('3') - >>> ExtendedContext.remainder_near(Decimal(3), 11) - Decimal('3') - >>> ExtendedContext.remainder_near(3, Decimal(11)) - Decimal('3') - """ - a = _convert_other(a, raiseit=True) - return a.remainder_near(b, context=self) - - def rotate(self, a, b): - """Returns a rotated copy of a, b times. - - The coefficient of the result is a rotated copy of the digits in - the coefficient of the first operand. The number of places of - rotation is taken from the absolute value of the second operand, - with the rotation being to the left if the second operand is - positive or to the right otherwise. - - >>> ExtendedContext.rotate(Decimal('34'), Decimal('8')) - Decimal('400000003') - >>> ExtendedContext.rotate(Decimal('12'), Decimal('9')) - Decimal('12') - >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('-2')) - Decimal('891234567') - >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('0')) - Decimal('123456789') - >>> ExtendedContext.rotate(Decimal('123456789'), Decimal('+2')) - Decimal('345678912') - >>> ExtendedContext.rotate(1333333, 1) - Decimal('13333330') - >>> ExtendedContext.rotate(Decimal(1333333), 1) - Decimal('13333330') - >>> ExtendedContext.rotate(1333333, Decimal(1)) - Decimal('13333330') - """ - a = _convert_other(a, raiseit=True) - return a.rotate(b, context=self) - - def same_quantum(self, a, b): - """Returns True if the two operands have the same exponent. - - The result is never affected by either the sign or the coefficient of - either operand. - - >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001')) - False - >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01')) - True - >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1')) - False - >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf')) - True - >>> ExtendedContext.same_quantum(10000, -1) - True - >>> ExtendedContext.same_quantum(Decimal(10000), -1) - True - >>> ExtendedContext.same_quantum(10000, Decimal(-1)) - True - """ - a = _convert_other(a, raiseit=True) - return a.same_quantum(b) - - def scaleb (self, a, b): - """Returns the first operand after adding the second value its exp. - - >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('-2')) - Decimal('0.0750') - >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('0')) - Decimal('7.50') - >>> ExtendedContext.scaleb(Decimal('7.50'), Decimal('3')) - Decimal('7.50E+3') - >>> ExtendedContext.scaleb(1, 4) - Decimal('1E+4') - >>> ExtendedContext.scaleb(Decimal(1), 4) - Decimal('1E+4') - >>> ExtendedContext.scaleb(1, Decimal(4)) - Decimal('1E+4') - """ - a = _convert_other(a, raiseit=True) - return a.scaleb(b, context=self) - - def shift(self, a, b): - """Returns a shifted copy of a, b times. - - The coefficient of the result is a shifted copy of the digits - in the coefficient of the first operand. The number of places - to shift is taken from the absolute value of the second operand, - with the shift being to the left if the second operand is - positive or to the right otherwise. Digits shifted into the - coefficient are zeros. - - >>> ExtendedContext.shift(Decimal('34'), Decimal('8')) - Decimal('400000000') - >>> ExtendedContext.shift(Decimal('12'), Decimal('9')) - Decimal('0') - >>> ExtendedContext.shift(Decimal('123456789'), Decimal('-2')) - Decimal('1234567') - >>> ExtendedContext.shift(Decimal('123456789'), Decimal('0')) - Decimal('123456789') - >>> ExtendedContext.shift(Decimal('123456789'), Decimal('+2')) - Decimal('345678900') - >>> ExtendedContext.shift(88888888, 2) - Decimal('888888800') - >>> ExtendedContext.shift(Decimal(88888888), 2) - Decimal('888888800') - >>> ExtendedContext.shift(88888888, Decimal(2)) - Decimal('888888800') - """ - a = _convert_other(a, raiseit=True) - return a.shift(b, context=self) - - def sqrt(self, a): - """Square root of a non-negative number to context precision. - - If the result must be inexact, it is rounded using the round-half-even - algorithm. - - >>> ExtendedContext.sqrt(Decimal('0')) - Decimal('0') - >>> ExtendedContext.sqrt(Decimal('-0')) - Decimal('-0') - >>> ExtendedContext.sqrt(Decimal('0.39')) - Decimal('0.624499800') - >>> ExtendedContext.sqrt(Decimal('100')) - Decimal('10') - >>> ExtendedContext.sqrt(Decimal('1')) - Decimal('1') - >>> ExtendedContext.sqrt(Decimal('1.0')) - Decimal('1.0') - >>> ExtendedContext.sqrt(Decimal('1.00')) - Decimal('1.0') - >>> ExtendedContext.sqrt(Decimal('7')) - Decimal('2.64575131') - >>> ExtendedContext.sqrt(Decimal('10')) - Decimal('3.16227766') - >>> ExtendedContext.sqrt(2) - Decimal('1.41421356') - >>> ExtendedContext.prec - 9 - """ - a = _convert_other(a, raiseit=True) - return a.sqrt(context=self) - - def subtract(self, a, b): - """Return the difference between the two operands. - - >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07')) - Decimal('0.23') - >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30')) - Decimal('0.00') - >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07')) - Decimal('-0.77') - >>> ExtendedContext.subtract(8, 5) - Decimal('3') - >>> ExtendedContext.subtract(Decimal(8), 5) - Decimal('3') - >>> ExtendedContext.subtract(8, Decimal(5)) - Decimal('3') - """ - a = _convert_other(a, raiseit=True) - r = a.__sub__(b, context=self) - if r is NotImplemented: - raise TypeError("Unable to convert %s to Decimal" % b) - else: - return r - - def to_eng_string(self, a): - """Converts a number to a string, using scientific notation. - - The operation is not affected by the context. - """ - a = _convert_other(a, raiseit=True) - return a.to_eng_string(context=self) - - def to_sci_string(self, a): - """Converts a number to a string, using scientific notation. - - The operation is not affected by the context. - """ - a = _convert_other(a, raiseit=True) - return a.__str__(context=self) - - def to_integral_exact(self, a): - """Rounds to an integer. - - When the operand has a negative exponent, the result is the same - as using the quantize() operation using the given operand as the - left-hand-operand, 1E+0 as the right-hand-operand, and the precision - of the operand as the precision setting; Inexact and Rounded flags - are allowed in this operation. The rounding mode is taken from the - context. - - >>> ExtendedContext.to_integral_exact(Decimal('2.1')) - Decimal('2') - >>> ExtendedContext.to_integral_exact(Decimal('100')) - Decimal('100') - >>> ExtendedContext.to_integral_exact(Decimal('100.0')) - Decimal('100') - >>> ExtendedContext.to_integral_exact(Decimal('101.5')) - Decimal('102') - >>> ExtendedContext.to_integral_exact(Decimal('-101.5')) - Decimal('-102') - >>> ExtendedContext.to_integral_exact(Decimal('10E+5')) - Decimal('1.0E+6') - >>> ExtendedContext.to_integral_exact(Decimal('7.89E+77')) - Decimal('7.89E+77') - >>> ExtendedContext.to_integral_exact(Decimal('-Inf')) - Decimal('-Infinity') - """ - a = _convert_other(a, raiseit=True) - return a.to_integral_exact(context=self) - - def to_integral_value(self, a): - """Rounds to an integer. - - When the operand has a negative exponent, the result is the same - as using the quantize() operation using the given operand as the - left-hand-operand, 1E+0 as the right-hand-operand, and the precision - of the operand as the precision setting, except that no flags will - be set. The rounding mode is taken from the context. - - >>> ExtendedContext.to_integral_value(Decimal('2.1')) - Decimal('2') - >>> ExtendedContext.to_integral_value(Decimal('100')) - Decimal('100') - >>> ExtendedContext.to_integral_value(Decimal('100.0')) - Decimal('100') - >>> ExtendedContext.to_integral_value(Decimal('101.5')) - Decimal('102') - >>> ExtendedContext.to_integral_value(Decimal('-101.5')) - Decimal('-102') - >>> ExtendedContext.to_integral_value(Decimal('10E+5')) - Decimal('1.0E+6') - >>> ExtendedContext.to_integral_value(Decimal('7.89E+77')) - Decimal('7.89E+77') - >>> ExtendedContext.to_integral_value(Decimal('-Inf')) - Decimal('-Infinity') - """ - a = _convert_other(a, raiseit=True) - return a.to_integral_value(context=self) - - # the method name changed, but we provide also the old one, for compatibility - to_integral = to_integral_value - -class _WorkRep(object): - __slots__ = ('sign','int','exp') - # sign: 0 or 1 - # int: int - # exp: None, int, or string - - def __init__(self, value=None): - if value is None: - self.sign = None - self.int = 0 - self.exp = None - elif isinstance(value, Decimal): - self.sign = value._sign - self.int = int(value._int) - self.exp = value._exp - else: - # assert isinstance(value, tuple) - self.sign = value[0] - self.int = value[1] - self.exp = value[2] - - def __repr__(self): - return "(%r, %r, %r)" % (self.sign, self.int, self.exp) - - __str__ = __repr__ - - - -def _normalize(op1, op2, prec = 0): - """Normalizes op1, op2 to have the same exp and length of coefficient. - - Done during addition. - """ - if op1.exp < op2.exp: - tmp = op2 - other = op1 - else: - tmp = op1 - other = op2 - - # Let exp = min(tmp.exp - 1, tmp.adjusted() - precision - 1). - # Then adding 10**exp to tmp has the same effect (after rounding) - # as adding any positive quantity smaller than 10**exp; similarly - # for subtraction. So if other is smaller than 10**exp we replace - # it with 10**exp. This avoids tmp.exp - other.exp getting too large. - tmp_len = len(str(tmp.int)) - other_len = len(str(other.int)) - exp = tmp.exp + min(-1, tmp_len - prec - 2) - if other_len + other.exp - 1 < exp: - other.int = 1 - other.exp = exp - - tmp.int *= 10 ** (tmp.exp - other.exp) - tmp.exp = other.exp - return op1, op2 - -##### Integer arithmetic functions used by ln, log10, exp and __pow__ ##### - -_nbits = int.bit_length - -def _decimal_lshift_exact(n, e): - """ Given integers n and e, return n * 10**e if it's an integer, else None. - - The computation is designed to avoid computing large powers of 10 - unnecessarily. - - >>> _decimal_lshift_exact(3, 4) - 30000 - >>> _decimal_lshift_exact(300, -999999999) # returns None - - """ - if n == 0: - return 0 - elif e >= 0: - return n * 10**e - else: - # val_n = largest power of 10 dividing n. - str_n = str(abs(n)) - val_n = len(str_n) - len(str_n.rstrip('0')) - return None if val_n < -e else n // 10**-e - -def _sqrt_nearest(n, a): - """Closest integer to the square root of the positive integer n. a is - an initial approximation to the square root. Any positive integer - will do for a, but the closer a is to the square root of n the - faster convergence will be. - - """ - if n <= 0 or a <= 0: - raise ValueError("Both arguments to _sqrt_nearest should be positive.") - - b=0 - while a != b: - b, a = a, a--n//a>>1 - return a - -def _rshift_nearest(x, shift): - """Given an integer x and a nonnegative integer shift, return closest - integer to x / 2**shift; use round-to-even in case of a tie. - - """ - b, q = 1 << shift, x >> shift - return q + (2*(x & (b-1)) + (q&1) > b) - -def _div_nearest(a, b): - """Closest integer to a/b, a and b positive integers; rounds to even - in the case of a tie. - - """ - q, r = divmod(a, b) - return q + (2*r + (q&1) > b) - -def _ilog(x, M, L = 8): - """Integer approximation to M*log(x/M), with absolute error boundable - in terms only of x/M. - - Given positive integers x and M, return an integer approximation to - M * log(x/M). For L = 8 and 0.1 <= x/M <= 10 the difference - between the approximation and the exact result is at most 22. For - L = 8 and 1.0 <= x/M <= 10.0 the difference is at most 15. In - both cases these are upper bounds on the error; it will usually be - much smaller.""" - - # The basic algorithm is the following: let log1p be the function - # log1p(x) = log(1+x). Then log(x/M) = log1p((x-M)/M). We use - # the reduction - # - # log1p(y) = 2*log1p(y/(1+sqrt(1+y))) - # - # repeatedly until the argument to log1p is small (< 2**-L in - # absolute value). For small y we can use the Taylor series - # expansion - # - # log1p(y) ~ y - y**2/2 + y**3/3 - ... - (-y)**T/T - # - # truncating at T such that y**T is small enough. The whole - # computation is carried out in a form of fixed-point arithmetic, - # with a real number z being represented by an integer - # approximation to z*M. To avoid loss of precision, the y below - # is actually an integer approximation to 2**R*y*M, where R is the - # number of reductions performed so far. - - y = x-M - # argument reduction; R = number of reductions performed - R = 0 - while (R <= L and abs(y) << L-R >= M or - R > L and abs(y) >> R-L >= M): - y = _div_nearest((M*y) << 1, - M + _sqrt_nearest(M*(M+_rshift_nearest(y, R)), M)) - R += 1 - - # Taylor series with T terms - T = -int(-10*len(str(M))//(3*L)) - yshift = _rshift_nearest(y, R) - w = _div_nearest(M, T) - for k in range(T-1, 0, -1): - w = _div_nearest(M, k) - _div_nearest(yshift*w, M) - - return _div_nearest(w*y, M) - -def _dlog10(c, e, p): - """Given integers c, e and p with c > 0, p >= 0, compute an integer - approximation to 10**p * log10(c*10**e), with an absolute error of - at most 1. Assumes that c*10**e is not exactly 1.""" - - # increase precision by 2; compensate for this by dividing - # final result by 100 - p += 2 - - # write c*10**e as d*10**f with either: - # f >= 0 and 1 <= d <= 10, or - # f <= 0 and 0.1 <= d <= 1. - # Thus for c*10**e close to 1, f = 0 - l = len(str(c)) - f = e+l - (e+l >= 1) - - if p > 0: - M = 10**p - k = e+p-f - if k >= 0: - c *= 10**k - else: - c = _div_nearest(c, 10**-k) - - log_d = _ilog(c, M) # error < 5 + 22 = 27 - log_10 = _log10_digits(p) # error < 1 - log_d = _div_nearest(log_d*M, log_10) - log_tenpower = f*M # exact - else: - log_d = 0 # error < 2.31 - log_tenpower = _div_nearest(f, 10**-p) # error < 0.5 - - return _div_nearest(log_tenpower+log_d, 100) - -def _dlog(c, e, p): - """Given integers c, e and p with c > 0, compute an integer - approximation to 10**p * log(c*10**e), with an absolute error of - at most 1. Assumes that c*10**e is not exactly 1.""" - - # Increase precision by 2. The precision increase is compensated - # for at the end with a division by 100. - p += 2 - - # rewrite c*10**e as d*10**f with either f >= 0 and 1 <= d <= 10, - # or f <= 0 and 0.1 <= d <= 1. Then we can compute 10**p * log(c*10**e) - # as 10**p * log(d) + 10**p*f * log(10). - l = len(str(c)) - f = e+l - (e+l >= 1) - - # compute approximation to 10**p*log(d), with error < 27 - if p > 0: - k = e+p-f - if k >= 0: - c *= 10**k - else: - c = _div_nearest(c, 10**-k) # error of <= 0.5 in c - - # _ilog magnifies existing error in c by a factor of at most 10 - log_d = _ilog(c, 10**p) # error < 5 + 22 = 27 - else: - # p <= 0: just approximate the whole thing by 0; error < 2.31 - log_d = 0 - - # compute approximation to f*10**p*log(10), with error < 11. - if f: - extra = len(str(abs(f)))-1 - if p + extra >= 0: - # error in f * _log10_digits(p+extra) < |f| * 1 = |f| - # after division, error < |f|/10**extra + 0.5 < 10 + 0.5 < 11 - f_log_ten = _div_nearest(f*_log10_digits(p+extra), 10**extra) - else: - f_log_ten = 0 - else: - f_log_ten = 0 - - # error in sum < 11+27 = 38; error after division < 0.38 + 0.5 < 1 - return _div_nearest(f_log_ten + log_d, 100) - -class _Log10Memoize(object): - """Class to compute, store, and allow retrieval of, digits of the - constant log(10) = 2.302585.... This constant is needed by - Decimal.ln, Decimal.log10, Decimal.exp and Decimal.__pow__.""" - def __init__(self): - self.digits = "23025850929940456840179914546843642076011014886" - - def getdigits(self, p): - """Given an integer p >= 0, return floor(10**p)*log(10). - - For example, self.getdigits(3) returns 2302. - """ - # digits are stored as a string, for quick conversion to - # integer in the case that we've already computed enough - # digits; the stored digits should always be correct - # (truncated, not rounded to nearest). - if p < 0: - raise ValueError("p should be nonnegative") - - if p >= len(self.digits): - # compute p+3, p+6, p+9, ... digits; continue until at - # least one of the extra digits is nonzero - extra = 3 - while True: - # compute p+extra digits, correct to within 1ulp - M = 10**(p+extra+2) - digits = str(_div_nearest(_ilog(10*M, M), 100)) - if digits[-extra:] != '0'*extra: - break - extra += 3 - # keep all reliable digits so far; remove trailing zeros - # and next nonzero digit - self.digits = digits.rstrip('0')[:-1] - return int(self.digits[:p+1]) - -_log10_digits = _Log10Memoize().getdigits - -def _iexp(x, M, L=8): - """Given integers x and M, M > 0, such that x/M is small in absolute - value, compute an integer approximation to M*exp(x/M). For 0 <= - x/M <= 2.4, the absolute error in the result is bounded by 60 (and - is usually much smaller).""" - - # Algorithm: to compute exp(z) for a real number z, first divide z - # by a suitable power R of 2 so that |z/2**R| < 2**-L. Then - # compute expm1(z/2**R) = exp(z/2**R) - 1 using the usual Taylor - # series - # - # expm1(x) = x + x**2/2! + x**3/3! + ... - # - # Now use the identity - # - # expm1(2x) = expm1(x)*(expm1(x)+2) - # - # R times to compute the sequence expm1(z/2**R), - # expm1(z/2**(R-1)), ... , exp(z/2), exp(z). - - # Find R such that x/2**R/M <= 2**-L - R = _nbits((x<<L)//M) - - # Taylor series. (2**L)**T > M - T = -int(-10*len(str(M))//(3*L)) - y = _div_nearest(x, T) - Mshift = M<<R - for i in range(T-1, 0, -1): - y = _div_nearest(x*(Mshift + y), Mshift * i) - - # Expansion - for k in range(R-1, -1, -1): - Mshift = M<<(k+2) - y = _div_nearest(y*(y+Mshift), Mshift) - - return M+y - -def _dexp(c, e, p): - """Compute an approximation to exp(c*10**e), with p decimal places of - precision. - - Returns integers d, f such that: - - 10**(p-1) <= d <= 10**p, and - (d-1)*10**f < exp(c*10**e) < (d+1)*10**f - - In other words, d*10**f is an approximation to exp(c*10**e) with p - digits of precision, and with an error in d of at most 1. This is - almost, but not quite, the same as the error being < 1ulp: when d - = 10**(p-1) the error could be up to 10 ulp.""" - - # we'll call iexp with M = 10**(p+2), giving p+3 digits of precision - p += 2 - - # compute log(10) with extra precision = adjusted exponent of c*10**e - extra = max(0, e + len(str(c)) - 1) - q = p + extra - - # compute quotient c*10**e/(log(10)) = c*10**(e+q)/(log(10)*10**q), - # rounding down - shift = e+q - if shift >= 0: - cshift = c*10**shift - else: - cshift = c//10**-shift - quot, rem = divmod(cshift, _log10_digits(q)) - - # reduce remainder back to original precision - rem = _div_nearest(rem, 10**extra) - - # error in result of _iexp < 120; error after division < 0.62 - return _div_nearest(_iexp(rem, 10**p), 1000), quot - p + 3 - -def _dpower(xc, xe, yc, ye, p): - """Given integers xc, xe, yc and ye representing Decimals x = xc*10**xe and - y = yc*10**ye, compute x**y. Returns a pair of integers (c, e) such that: - - 10**(p-1) <= c <= 10**p, and - (c-1)*10**e < x**y < (c+1)*10**e - - in other words, c*10**e is an approximation to x**y with p digits - of precision, and with an error in c of at most 1. (This is - almost, but not quite, the same as the error being < 1ulp: when c - == 10**(p-1) we can only guarantee error < 10ulp.) - - We assume that: x is positive and not equal to 1, and y is nonzero. - """ - - # Find b such that 10**(b-1) <= |y| <= 10**b - b = len(str(abs(yc))) + ye - - # log(x) = lxc*10**(-p-b-1), to p+b+1 places after the decimal point - lxc = _dlog(xc, xe, p+b+1) - - # compute product y*log(x) = yc*lxc*10**(-p-b-1+ye) = pc*10**(-p-1) - shift = ye-b - if shift >= 0: - pc = lxc*yc*10**shift - else: - pc = _div_nearest(lxc*yc, 10**-shift) - - if pc == 0: - # we prefer a result that isn't exactly 1; this makes it - # easier to compute a correctly rounded result in __pow__ - if ((len(str(xc)) + xe >= 1) == (yc > 0)): # if x**y > 1: - coeff, exp = 10**(p-1)+1, 1-p - else: - coeff, exp = 10**p-1, -p - else: - coeff, exp = _dexp(pc, -(p+1), p+1) - coeff = _div_nearest(coeff, 10) - exp += 1 - - return coeff, exp - -def _log10_lb(c, correction = { - '1': 100, '2': 70, '3': 53, '4': 40, '5': 31, - '6': 23, '7': 16, '8': 10, '9': 5}): - """Compute a lower bound for 100*log10(c) for a positive integer c.""" - if c <= 0: - raise ValueError("The argument to _log10_lb should be nonnegative.") - str_c = str(c) - return 100*len(str_c) - correction[str_c[0]] - -##### Helper Functions #################################################### - -def _convert_other(other, raiseit=False, allow_float=False): - """Convert other to Decimal. - - Verifies that it's ok to use in an implicit construction. - If allow_float is true, allow conversion from float; this - is used in the comparison methods (__eq__ and friends). - - """ - if isinstance(other, Decimal): - return other - if isinstance(other, int): - return Decimal(other) - if allow_float and isinstance(other, float): - return Decimal.from_float(other) - - if raiseit: - raise TypeError("Unable to convert %s to Decimal" % other) - return NotImplemented - -def _convert_for_comparison(self, other, equality_op=False): - """Given a Decimal instance self and a Python object other, return - a pair (s, o) of Decimal instances such that "s op o" is - equivalent to "self op other" for any of the 6 comparison - operators "op". - - """ - if isinstance(other, Decimal): - return self, other - - # Comparison with a Rational instance (also includes integers): - # self op n/d <=> self*d op n (for n and d integers, d positive). - # A NaN or infinity can be left unchanged without affecting the - # comparison result. - if isinstance(other, _numbers.Rational): - if not self._is_special: - self = _dec_from_triple(self._sign, - str(int(self._int) * other.denominator), - self._exp) - return self, Decimal(other.numerator) - - # Comparisons with float and complex types. == and != comparisons - # with complex numbers should succeed, returning either True or False - # as appropriate. Other comparisons return NotImplemented. - if equality_op and isinstance(other, _numbers.Complex) and other.imag == 0: - other = other.real - if isinstance(other, float): - context = getcontext() - if equality_op: - context.flags[FloatOperation] = 1 - else: - context._raise_error(FloatOperation, - "strict semantics for mixing floats and Decimals are enabled") - return self, Decimal.from_float(other) - return NotImplemented, NotImplemented - - -##### Setup Specific Contexts ############################################ - -# The default context prototype used by Context() -# Is mutable, so that new contexts can have different default values - -DefaultContext = Context( - prec=28, rounding=ROUND_HALF_EVEN, - traps=[DivisionByZero, Overflow, InvalidOperation], - flags=[], - Emax=999999, - Emin=-999999, - capitals=1, - clamp=0 -) - -# Pre-made alternate contexts offered by the specification -# Don't change these; the user should be able to select these -# contexts and be able to reproduce results from other implementations -# of the spec. - -BasicContext = Context( - prec=9, rounding=ROUND_HALF_UP, - traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow], - flags=[], -) - -ExtendedContext = Context( - prec=9, rounding=ROUND_HALF_EVEN, - traps=[], - flags=[], -) - - -##### crud for parsing strings ############################################# -# -# Regular expression used for parsing numeric strings. Additional -# comments: -# -# 1. Uncomment the two '\s*' lines to allow leading and/or trailing -# whitespace. But note that the specification disallows whitespace in -# a numeric string. -# -# 2. For finite numbers (not infinities and NaNs) the body of the -# number between the optional sign and the optional exponent must have -# at least one decimal digit, possibly after the decimal point. The -# lookahead expression '(?=\d|\.\d)' checks this. - -import re -_parser = re.compile(r""" # A numeric string consists of: -# \s* - (?P<sign>[-+])? # an optional sign, followed by either... - ( - (?=\d|\.\d) # ...a number (with at least one digit) - (?P<int>\d*) # having a (possibly empty) integer part - (\.(?P<frac>\d*))? # followed by an optional fractional part - (E(?P<exp>[-+]?\d+))? # followed by an optional exponent, or... - | - Inf(inity)? # ...an infinity, or... - | - (?P<signal>s)? # ...an (optionally signaling) - NaN # NaN - (?P<diag>\d*) # with (possibly empty) diagnostic info. - ) -# \s* - \Z -""", re.VERBOSE | re.IGNORECASE).match - -_all_zeros = re.compile('0*$').match -_exact_half = re.compile('50*$').match - -##### PEP3101 support functions ############################################## -# The functions in this section have little to do with the Decimal -# class, and could potentially be reused or adapted for other pure -# Python numeric classes that want to implement __format__ -# -# A format specifier for Decimal looks like: -# -# [[fill]align][sign][#][0][minimumwidth][,][.precision][type] - -_parse_format_specifier_regex = re.compile(r"""\A -(?: - (?P<fill>.)? - (?P<align>[<>=^]) -)? -(?P<sign>[-+ ])? -(?P<alt>\#)? -(?P<zeropad>0)? -(?P<minimumwidth>(?!0)\d+)? -(?P<thousands_sep>,)? -(?:\.(?P<precision>0|(?!0)\d+))? -(?P<type>[eEfFgGn%])? -\Z -""", re.VERBOSE|re.DOTALL) - -del re - -# The locale module is only needed for the 'n' format specifier. The -# rest of the PEP 3101 code functions quite happily without it, so we -# don't care too much if locale isn't present. -try: - import locale as _locale -except ImportError: - pass - -def _parse_format_specifier(format_spec, _localeconv=None): - """Parse and validate a format specifier. - - Turns a standard numeric format specifier into a dict, with the - following entries: - - fill: fill character to pad field to minimum width - align: alignment type, either '<', '>', '=' or '^' - sign: either '+', '-' or ' ' - minimumwidth: nonnegative integer giving minimum width - zeropad: boolean, indicating whether to pad with zeros - thousands_sep: string to use as thousands separator, or '' - grouping: grouping for thousands separators, in format - used by localeconv - decimal_point: string to use for decimal point - precision: nonnegative integer giving precision, or None - type: one of the characters 'eEfFgG%', or None - - """ - m = _parse_format_specifier_regex.match(format_spec) - if m is None: - raise ValueError("Invalid format specifier: " + format_spec) - - # get the dictionary - format_dict = m.groupdict() - - # zeropad; defaults for fill and alignment. If zero padding - # is requested, the fill and align fields should be absent. - fill = format_dict['fill'] - align = format_dict['align'] - format_dict['zeropad'] = (format_dict['zeropad'] is not None) - if format_dict['zeropad']: - if fill is not None: - raise ValueError("Fill character conflicts with '0'" - " in format specifier: " + format_spec) - if align is not None: - raise ValueError("Alignment conflicts with '0' in " - "format specifier: " + format_spec) - format_dict['fill'] = fill or ' ' - # PEP 3101 originally specified that the default alignment should - # be left; it was later agreed that right-aligned makes more sense - # for numeric types. See http://bugs.python.org/issue6857. - format_dict['align'] = align or '>' - - # default sign handling: '-' for negative, '' for positive - if format_dict['sign'] is None: - format_dict['sign'] = '-' - - # minimumwidth defaults to 0; precision remains None if not given - format_dict['minimumwidth'] = int(format_dict['minimumwidth'] or '0') - if format_dict['precision'] is not None: - format_dict['precision'] = int(format_dict['precision']) - - # if format type is 'g' or 'G' then a precision of 0 makes little - # sense; convert it to 1. Same if format type is unspecified. - if format_dict['precision'] == 0: - if format_dict['type'] is None or format_dict['type'] in 'gGn': - format_dict['precision'] = 1 - - # determine thousands separator, grouping, and decimal separator, and - # add appropriate entries to format_dict - if format_dict['type'] == 'n': - # apart from separators, 'n' behaves just like 'g' - format_dict['type'] = 'g' - if _localeconv is None: - _localeconv = _locale.localeconv() - if format_dict['thousands_sep'] is not None: - raise ValueError("Explicit thousands separator conflicts with " - "'n' type in format specifier: " + format_spec) - format_dict['thousands_sep'] = _localeconv['thousands_sep'] - format_dict['grouping'] = _localeconv['grouping'] - format_dict['decimal_point'] = _localeconv['decimal_point'] - else: - if format_dict['thousands_sep'] is None: - format_dict['thousands_sep'] = '' - format_dict['grouping'] = [3, 0] - format_dict['decimal_point'] = '.' - - return format_dict - -def _format_align(sign, body, spec): - """Given an unpadded, non-aligned numeric string 'body' and sign - string 'sign', add padding and alignment conforming to the given - format specifier dictionary 'spec' (as produced by - parse_format_specifier). - - """ - # how much extra space do we have to play with? - minimumwidth = spec['minimumwidth'] - fill = spec['fill'] - padding = fill*(minimumwidth - len(sign) - len(body)) - - align = spec['align'] - if align == '<': - result = sign + body + padding - elif align == '>': - result = padding + sign + body - elif align == '=': - result = sign + padding + body - elif align == '^': - half = len(padding)//2 - result = padding[:half] + sign + body + padding[half:] - else: - raise ValueError('Unrecognised alignment field') - - return result - -def _group_lengths(grouping): - """Convert a localeconv-style grouping into a (possibly infinite) - iterable of integers representing group lengths. - - """ - # The result from localeconv()['grouping'], and the input to this - # function, should be a list of integers in one of the - # following three forms: - # - # (1) an empty list, or - # (2) nonempty list of positive integers + [0] - # (3) list of positive integers + [locale.CHAR_MAX], or - - from itertools import chain, repeat - if not grouping: - return [] - elif grouping[-1] == 0 and len(grouping) >= 2: - return chain(grouping[:-1], repeat(grouping[-2])) - elif grouping[-1] == _locale.CHAR_MAX: - return grouping[:-1] - else: - raise ValueError('unrecognised format for grouping') - -def _insert_thousands_sep(digits, spec, min_width=1): - """Insert thousands separators into a digit string. - - spec is a dictionary whose keys should include 'thousands_sep' and - 'grouping'; typically it's the result of parsing the format - specifier using _parse_format_specifier. - - The min_width keyword argument gives the minimum length of the - result, which will be padded on the left with zeros if necessary. - - If necessary, the zero padding adds an extra '0' on the left to - avoid a leading thousands separator. For example, inserting - commas every three digits in '123456', with min_width=8, gives - '0,123,456', even though that has length 9. - - """ - - sep = spec['thousands_sep'] - grouping = spec['grouping'] - - groups = [] - for l in _group_lengths(grouping): - if l <= 0: - raise ValueError("group length should be positive") - # max(..., 1) forces at least 1 digit to the left of a separator - l = min(max(len(digits), min_width, 1), l) - groups.append('0'*(l - len(digits)) + digits[-l:]) - digits = digits[:-l] - min_width -= l - if not digits and min_width <= 0: - break - min_width -= len(sep) - else: - l = max(len(digits), min_width, 1) - groups.append('0'*(l - len(digits)) + digits[-l:]) - return sep.join(reversed(groups)) - -def _format_sign(is_negative, spec): - """Determine sign character.""" - - if is_negative: - return '-' - elif spec['sign'] in ' +': - return spec['sign'] - else: - return '' - -def _format_number(is_negative, intpart, fracpart, exp, spec): - """Format a number, given the following data: - - is_negative: true if the number is negative, else false - intpart: string of digits that must appear before the decimal point - fracpart: string of digits that must come after the point - exp: exponent, as an integer - spec: dictionary resulting from parsing the format specifier - - This function uses the information in spec to: - insert separators (decimal separator and thousands separators) - format the sign - format the exponent - add trailing '%' for the '%' type - zero-pad if necessary - fill and align if necessary - """ - - sign = _format_sign(is_negative, spec) - - if fracpart or spec['alt']: - fracpart = spec['decimal_point'] + fracpart - - if exp != 0 or spec['type'] in 'eE': - echar = {'E': 'E', 'e': 'e', 'G': 'E', 'g': 'e'}[spec['type']] - fracpart += "{0}{1:+}".format(echar, exp) - if spec['type'] == '%': - fracpart += '%' - - if spec['zeropad']: - min_width = spec['minimumwidth'] - len(fracpart) - len(sign) - else: - min_width = 0 - intpart = _insert_thousands_sep(intpart, spec, min_width) - - return _format_align(sign, intpart+fracpart, spec) - - -##### Useful Constants (internal use only) ################################ - -# Reusable defaults -_Infinity = Decimal('Inf') -_NegativeInfinity = Decimal('-Inf') -_NaN = Decimal('NaN') -_Zero = Decimal(0) -_One = Decimal(1) -_NegativeOne = Decimal(-1) - -# _SignedInfinity[sign] is infinity w/ that sign -_SignedInfinity = (_Infinity, _NegativeInfinity) - -# Constants related to the hash implementation; hash(x) is based -# on the reduction of x modulo _PyHASH_MODULUS -_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) -del sys try: - import _decimal -except ImportError: - pass -else: - s1 = set(dir()) - s2 = set(dir(_decimal)) - for name in s1 - s2: - del globals()[name] - del s1, s2, name from _decimal import * - -if __name__ == '__main__': - import doctest, decimal - doctest.testmod(decimal) + from _decimal import __doc__ + from _decimal import __version__ + from _decimal import __libmpdec_version__ +except ImportError: + from _pydecimal import * + from _pydecimal import __doc__ + from _pydecimal import __version__ + from _pydecimal import __libmpdec_version__ diff --git a/Lib/difflib.py b/Lib/difflib.py index 159cbe4dfdd9..22d9145a07c6 100644 --- a/Lib/difflib.py +++ b/Lib/difflib.py @@ -1,5 +1,3 @@ -#! /usr/bin/env python3 - """ Module difflib -- helpers for computing deltas between objects. @@ -30,10 +28,9 @@ __all__ = ['get_close_matches', 'ndiff', 'restore', 'SequenceMatcher', 'Differ','IS_CHARACTER_JUNK', 'IS_LINE_JUNK', 'context_diff', - 'unified_diff', 'HtmlDiff', 'Match'] + 'unified_diff', 'diff_bytes', 'HtmlDiff', 'Match'] -import warnings -import heapq +from heapq import nlargest as _nlargest from collections import namedtuple as _namedtuple Match = _namedtuple('Match', 'a b size') @@ -514,8 +511,8 @@ def get_matching_blocks(self): non_adjacent.append((i1, j1, k1)) non_adjacent.append( (la, lb, 0) ) - self.matching_blocks = non_adjacent - return map(Match._make, self.matching_blocks) + self.matching_blocks = list(map(Match._make, non_adjacent)) + return self.matching_blocks def get_opcodes(self): """Return list of 5-tuples describing how to turn a into b. @@ -732,7 +729,7 @@ def get_close_matches(word, possibilities, n=3, cutoff=0.6): result.append((s.ratio(), x)) # Move the best scorers to head of list - result = heapq.nlargest(n, result) + result = _nlargest(n, result) # Strip scores for the best n matches return [x for score, x in result] @@ -855,10 +852,9 @@ def __init__(self, linejunk=None, charjunk=None): and return true iff the string is junk. The module-level function `IS_LINE_JUNK` may be used to filter out lines without visible characters, except for at most one splat ('#'). It is recommended - to leave linejunk None; as of Python 2.3, the underlying - SequenceMatcher class has grown an adaptive notion of "noise" lines - that's better than any static definition the author has ever been - able to craft. + to leave linejunk None; the underlying SequenceMatcher class has + an adaptive notion of "noise" lines that's better than any static + definition the author has ever been able to craft. - `charjunk`: A function that should accept a string of length 1. The module-level function `IS_CHARACTER_JUNK` may be used to filter out @@ -1178,6 +1174,7 @@ def unified_diff(a, b, fromfile='', tofile='', fromfiledate='', four """ + _check_types(a, b, fromfile, tofile, fromfiledate, tofiledate, lineterm) started = False for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n): if not started: @@ -1265,6 +1262,7 @@ def context_diff(a, b, fromfile='', tofile='', four """ + _check_types(a, b, fromfile, tofile, fromfiledate, tofiledate, lineterm) prefix = dict(insert='+ ', delete='- ', replace='! ', equal=' ') started = False for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n): @@ -1296,22 +1294,70 @@ def context_diff(a, b, fromfile='', tofile='', for line in b[j1:j2]: yield prefix[tag] + line +def _check_types(a, b, *args): + # Checking types is weird, but the alternative is garbled output when + # someone passes mixed bytes and str to {unified,context}_diff(). E.g. + # without this check, passing filenames as bytes results in output like + # --- b'oldfile.txt' + # +++ b'newfile.txt' + # because of how str.format() incorporates bytes objects. + if a and not isinstance(a[0], str): + raise TypeError('lines to compare must be str, not %s (%r)' % + (type(a[0]).__name__, a[0])) + if b and not isinstance(b[0], str): + raise TypeError('lines to compare must be str, not %s (%r)' % + (type(b[0]).__name__, b[0])) + for arg in args: + if not isinstance(arg, str): + raise TypeError('all arguments must be str, not: %r' % (arg,)) + +def diff_bytes(dfunc, a, b, fromfile=b'', tofile=b'', + fromfiledate=b'', tofiledate=b'', n=3, lineterm=b'\n'): + r""" + Compare `a` and `b`, two sequences of lines represented as bytes rather + than str. This is a wrapper for `dfunc`, which is typically either + unified_diff() or context_diff(). Inputs are losslessly converted to + strings so that `dfunc` only has to worry about strings, and encoded + back to bytes on return. This is necessary to compare files with + unknown or inconsistent encoding. All other inputs (except `n`) must be + bytes rather than str. + """ + def decode(s): + try: + return s.decode('ascii', 'surrogateescape') + except AttributeError as err: + msg = ('all arguments must be bytes, not %s (%r)' % + (type(s).__name__, s)) + raise TypeError(msg) from err + a = list(map(decode, a)) + b = list(map(decode, b)) + fromfile = decode(fromfile) + tofile = decode(tofile) + fromfiledate = decode(fromfiledate) + tofiledate = decode(tofiledate) + lineterm = decode(lineterm) + + lines = dfunc(a, b, fromfile, tofile, fromfiledate, tofiledate, n, lineterm) + for line in lines: + yield line.encode('ascii', 'surrogateescape') + def ndiff(a, b, linejunk=None, charjunk=IS_CHARACTER_JUNK): r""" Compare `a` and `b` (lists of strings); return a `Differ`-style delta. Optional keyword parameters `linejunk` and `charjunk` are for filter - functions (or None): + functions, or can be None: - - linejunk: A function that should accept a single string argument, and + - linejunk: A function that should accept a single string argument and return true iff the string is junk. The default is None, and is - recommended; as of Python 2.3, an adaptive notion of "noise" lines is - used that does a good job on its own. + recommended; the underlying SequenceMatcher class has an adaptive + notion of "noise" lines. - - charjunk: A function that should accept a string of length 1. The - default is module-level function IS_CHARACTER_JUNK, which filters out - whitespace characters (a blank or tab; note: bad idea to include newline - in this!). + - charjunk: A function that accepts a character (string of length + 1), and returns true iff the character is junk. The default is + the module-level function IS_CHARACTER_JUNK, which filters out + whitespace characters (a blank or tab; note: it's a bad idea to + include newline in this!). Tools/scripts/ndiff.py is a command-line front-end to this function. @@ -1413,7 +1459,7 @@ def record_sub_info(match_object,sub_info=sub_info): change_re.sub(record_sub_info,markers) # process each tuple inserting our special marks that won't be # noticed by an xml/html escaper. - for key,(begin,end) in sub_info[::-1]: + for key,(begin,end) in reversed(sub_info): text = text[0:begin]+'\0'+key+text[begin:end]+'\1'+text[end:] text = text[2:] # Handle case of add/delete entire line @@ -1451,10 +1497,7 @@ def _line_iterator(): # are a concatenation of the first character of each of the 4 lines # so we can do some very readable comparisons. while len(lines) < 4: - try: - lines.append(next(diff_lines_iterator)) - except StopIteration: - lines.append('X') + lines.append(next(diff_lines_iterator, 'X')) s = ''.join([line[0] for line in lines]) if s.startswith('X'): # When no more lines, pump out any remaining blank lines so the @@ -1517,7 +1560,7 @@ def _line_iterator(): num_blanks_to_yield -= 1 yield ('','\n'),None,True if s.startswith('X'): - raise StopIteration + return else: yield from_line,to_line,True @@ -1539,7 +1582,10 @@ def _line_pair_iterator(): while True: # Collecting lines of text until we have a from/to pair while (len(fromlines)==0 or len(tolines)==0): - from_line, to_line, found_diff = next(line_iterator) + try: + from_line, to_line, found_diff = next(line_iterator) + except StopIteration: + return if from_line is not None: fromlines.append((from_line,found_diff)) if to_line is not None: @@ -1553,8 +1599,7 @@ def _line_pair_iterator(): # them up without doing anything else with them. line_pair_iterator = _line_pair_iterator() if context is None: - while True: - yield next(line_pair_iterator) + yield from line_pair_iterator # Handle case where user wants context differencing. We must do some # storage of lines until we know for sure that they are to be yielded. else: @@ -1567,7 +1612,10 @@ def _line_pair_iterator(): index, contextLines = 0, [None]*(context) found_diff = False while(found_diff is False): - from_line, to_line, found_diff = next(line_pair_iterator) + try: + from_line, to_line, found_diff = next(line_pair_iterator) + except StopIteration: + return i = index % context contextLines[i] = (from_line, to_line, found_diff) index += 1 @@ -1604,7 +1652,7 @@ def _line_pair_iterator(): <head> <meta http-equiv="Content-Type" - content="text/html; charset=ISO-8859-1" /> + content="text/html; charset=%(charset)s" /> <title> @@ -1682,7 +1730,7 @@ def __init__(self,tabsize=8,wrapcolumn=None,linejunk=None, tabsize -- tab stop spacing, defaults to 8. wrapcolumn -- column number where lines are broken and wrapped, defaults to None where lines are not wrapped. - linejunk,charjunk -- keyword arguments passed into ndiff() (used to by + linejunk,charjunk -- keyword arguments passed into ndiff() (used by HtmlDiff() to generate the side by side HTML differences). See ndiff() documentation for argument default values and descriptions. """ @@ -1691,8 +1739,8 @@ def __init__(self,tabsize=8,wrapcolumn=None,linejunk=None, self._linejunk = linejunk self._charjunk = charjunk - def make_file(self,fromlines,tolines,fromdesc='',todesc='',context=False, - numlines=5): + def make_file(self, fromlines, tolines, fromdesc='', todesc='', + context=False, numlines=5, *, charset='utf-8'): """Returns HTML file of side by side comparison with change highlights Arguments: @@ -1707,13 +1755,16 @@ def make_file(self,fromlines,tolines,fromdesc='',todesc='',context=False, When context is False, controls the number of lines to place the "next" link anchors before the next change (so click of "next" link jumps to just before the change). + charset -- charset of the HTML document """ - return self._file_template % dict( - styles = self._styles, - legend = self._legend, - table = self.make_table(fromlines,tolines,fromdesc,todesc, - context=context,numlines=numlines)) + return (self._file_template % dict( + styles=self._styles, + legend=self._legend, + table=self.make_table(fromlines, tolines, fromdesc, todesc, + context=context, numlines=numlines), + charset=charset + )).encode(charset, 'xmlcharrefreplace').decode(charset) def _tab_newline_replace(self,fromlines,tolines): """Returns from/to line lists with tabs expanded and newlines removed. diff --git a/Lib/dis.py b/Lib/dis.py index 81cbe7f4f993..3540b4714d9a 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -29,7 +29,7 @@ def _try_compile(source, name): return c def dis(x=None, *, file=None): - """Disassemble classes, methods, functions, or code. + """Disassemble classes, methods, functions, generators, or code. With no argument, disassemble the last traceback. @@ -41,6 +41,8 @@ def dis(x=None, *, file=None): x = x.__func__ if hasattr(x, '__code__'): # Function x = x.__code__ + if hasattr(x, 'gi_code'): # Generator + x = x.gi_code if hasattr(x, '__dict__'): # Class or module items = sorted(x.__dict__.items()) for name, x1 in items: @@ -82,6 +84,8 @@ def distb(tb=None, *, file=None): 16: "NESTED", 32: "GENERATOR", 64: "NOFREE", + 128: "COROUTINE", + 256: "ITERABLE_COROUTINE", } def pretty_flags(flags): @@ -99,11 +103,13 @@ def pretty_flags(flags): return ", ".join(names) def _get_code_object(x): - """Helper to handle methods, functions, strings and raw code objects""" + """Helper to handle methods, functions, generators, strings and raw code objects""" if hasattr(x, '__func__'): # Method x = x.__func__ if hasattr(x, '__code__'): # Function x = x.__code__ + if hasattr(x, 'gi_code'): # Generator + x = x.gi_code if isinstance(x, str): # Source code x = _try_compile(x, "") if hasattr(x, 'co_code'): # Code object @@ -156,6 +162,15 @@ def show_code(co, *, file=None): _Instruction = collections.namedtuple("_Instruction", "opname opcode arg argval argrepr offset starts_line is_jump_target") +_Instruction.opname.__doc__ = "Human readable name for operation" +_Instruction.opcode.__doc__ = "Numeric code for operation" +_Instruction.arg.__doc__ = "Numeric argument to operation (if any), otherwise None" +_Instruction.argval.__doc__ = "Resolved arg value (if known), otherwise same as arg" +_Instruction.argrepr.__doc__ = "Human readable description of operation argument" +_Instruction.offset.__doc__ = "Start index of operation within bytecode sequence" +_Instruction.starts_line.__doc__ = "Line started by this opcode (if any), otherwise None" +_Instruction.is_jump_target.__doc__ = "True if other code jumps to here, otherwise False" + class Instruction(_Instruction): """Details for a bytecode operation diff --git a/Lib/distutils/__init__.py b/Lib/distutils/__init__.py index 38a50869ea6e..d823d040a1c1 100644 --- a/Lib/distutils/__init__.py +++ b/Lib/distutils/__init__.py @@ -8,10 +8,6 @@ setup (...) """ -# Distutils version -# -# Updated automatically by the Python release process. -# -#--start constants-- -__version__ = "3.4.0b1" -#--end constants-- +import sys + +__version__ = sys.version[:sys.version.index(' ')] diff --git a/Lib/distutils/_msvccompiler.py b/Lib/distutils/_msvccompiler.py new file mode 100644 index 000000000000..10a9ffda24a2 --- /dev/null +++ b/Lib/distutils/_msvccompiler.py @@ -0,0 +1,546 @@ +"""distutils._msvccompiler + +Contains MSVCCompiler, an implementation of the abstract CCompiler class +for Microsoft Visual Studio 2015. + +The module is compatible with VS 2015 and later. You can find legacy support +for older versions in distutils.msvc9compiler and distutils.msvccompiler. +""" + +# Written by Perry Stoll +# hacked by Robin Becker and Thomas Heller to do a better job of +# finding DevStudio (through the registry) +# ported to VS 2005 and VS 2008 by Christian Heimes +# ported to VS 2015 by Steve Dower + +import os +import shutil +import stat +import subprocess + +from distutils.errors import DistutilsExecError, DistutilsPlatformError, \ + CompileError, LibError, LinkError +from distutils.ccompiler import CCompiler, gen_lib_options +from distutils import log +from distutils.util import get_platform + +import winreg +from itertools import count + +def _find_vcvarsall(plat_spec): + try: + key = winreg.OpenKeyEx( + winreg.HKEY_LOCAL_MACHINE, + r"Software\Microsoft\VisualStudio\SxS\VC7", + access=winreg.KEY_READ | winreg.KEY_WOW64_32KEY + ) + except OSError: + log.debug("Visual C++ is not registered") + return None, None + + with key: + best_version = 0 + best_dir = None + for i in count(): + try: + v, vc_dir, vt = winreg.EnumValue(key, i) + except OSError: + break + if v and vt == winreg.REG_SZ and os.path.isdir(vc_dir): + try: + version = int(float(v)) + except (ValueError, TypeError): + continue + if version >= 14 and version > best_version: + best_version, best_dir = version, vc_dir + if not best_version: + log.debug("No suitable Visual C++ version found") + return None, None + + vcvarsall = os.path.join(best_dir, "vcvarsall.bat") + if not os.path.isfile(vcvarsall): + log.debug("%s cannot be found", vcvarsall) + return None, None + + vcruntime = None + vcruntime_spec = _VCVARS_PLAT_TO_VCRUNTIME_REDIST.get(plat_spec) + if vcruntime_spec: + vcruntime = os.path.join(best_dir, + vcruntime_spec.format(best_version)) + if not os.path.isfile(vcruntime): + log.debug("%s cannot be found", vcruntime) + vcruntime = None + + return vcvarsall, vcruntime + +def _get_vc_env(plat_spec): + if os.getenv("DISTUTILS_USE_SDK"): + return { + key.lower(): value + for key, value in os.environ.items() + } + + vcvarsall, vcruntime = _find_vcvarsall(plat_spec) + if not vcvarsall: + raise DistutilsPlatformError("Unable to find vcvarsall.bat") + + try: + out = subprocess.check_output( + '"{}" {} && set'.format(vcvarsall, plat_spec), + shell=True, + stderr=subprocess.STDOUT, + universal_newlines=True, + ) + except subprocess.CalledProcessError as exc: + log.error(exc.output) + raise DistutilsPlatformError("Error executing {}" + .format(exc.cmd)) + + env = { + key.lower(): value + for key, _, value in + (line.partition('=') for line in out.splitlines()) + if key and value + } + + if vcruntime: + env['py_vcruntime_redist'] = vcruntime + return env + +def _find_exe(exe, paths=None): + """Return path to an MSVC executable program. + + Tries to find the program in several places: first, one of the + MSVC program search paths from the registry; next, the directories + in the PATH environment variable. If any of those work, return an + absolute path that is known to exist. If none of them work, just + return the original program name, 'exe'. + """ + if not paths: + paths = os.getenv('path').split(os.pathsep) + for p in paths: + fn = os.path.join(os.path.abspath(p), exe) + if os.path.isfile(fn): + return fn + return exe + +# A map keyed by get_platform() return values to values accepted by +# 'vcvarsall.bat'. Note a cross-compile may combine these (eg, 'x86_amd64' is +# the param to cross-compile on x86 targetting amd64.) +PLAT_TO_VCVARS = { + 'win32' : 'x86', + 'win-amd64' : 'amd64', +} + +# A map keyed by get_platform() return values to the file under +# the VC install directory containing the vcruntime redistributable. +_VCVARS_PLAT_TO_VCRUNTIME_REDIST = { + 'x86' : 'redist\\x86\\Microsoft.VC{0}0.CRT\\vcruntime{0}0.dll', + 'amd64' : 'redist\\x64\\Microsoft.VC{0}0.CRT\\vcruntime{0}0.dll', + 'x86_amd64' : 'redist\\x64\\Microsoft.VC{0}0.CRT\\vcruntime{0}0.dll', +} + +# A set containing the DLLs that are guaranteed to be available for +# all micro versions of this Python version. Known extension +# dependencies that are not in this set will be copied to the output +# path. +_BUNDLED_DLLS = frozenset(['vcruntime140.dll']) + +class MSVCCompiler(CCompiler) : + """Concrete class that implements an interface to Microsoft Visual C++, + as defined by the CCompiler abstract class.""" + + compiler_type = 'msvc' + + # Just set this so CCompiler's constructor doesn't barf. We currently + # don't use the 'set_executables()' bureaucracy provided by CCompiler, + # as it really isn't necessary for this sort of single-compiler class. + # Would be nice to have a consistent interface with UnixCCompiler, + # though, so it's worth thinking about. + executables = {} + + # Private class data (need to distinguish C from C++ source for compiler) + _c_extensions = ['.c'] + _cpp_extensions = ['.cc', '.cpp', '.cxx'] + _rc_extensions = ['.rc'] + _mc_extensions = ['.mc'] + + # Needed for the filename generation methods provided by the + # base class, CCompiler. + src_extensions = (_c_extensions + _cpp_extensions + + _rc_extensions + _mc_extensions) + res_extension = '.res' + obj_extension = '.obj' + static_lib_extension = '.lib' + shared_lib_extension = '.dll' + static_lib_format = shared_lib_format = '%s%s' + exe_extension = '.exe' + + + def __init__(self, verbose=0, dry_run=0, force=0): + CCompiler.__init__ (self, verbose, dry_run, force) + # target platform (.plat_name is consistent with 'bdist') + self.plat_name = None + self.initialized = False + + def initialize(self, plat_name=None): + # multi-init means we would need to check platform same each time... + assert not self.initialized, "don't init multiple times" + if plat_name is None: + plat_name = get_platform() + # sanity check for platforms to prevent obscure errors later. + if plat_name not in PLAT_TO_VCVARS: + raise DistutilsPlatformError("--plat-name must be one of {}" + .format(tuple(PLAT_TO_VCVARS))) + + # On x86, 'vcvarsall.bat amd64' creates an env that doesn't work; + # to cross compile, you use 'x86_amd64'. + # On AMD64, 'vcvarsall.bat amd64' is a native build env; to cross + # compile use 'x86' (ie, it runs the x86 compiler directly) + if plat_name == get_platform() or plat_name == 'win32': + # native build or cross-compile to win32 + plat_spec = PLAT_TO_VCVARS[plat_name] + else: + # cross compile from win32 -> some 64bit + plat_spec = '{}_{}'.format( + PLAT_TO_VCVARS[get_platform()], + PLAT_TO_VCVARS[plat_name] + ) + + vc_env = _get_vc_env(plat_spec) + if not vc_env: + raise DistutilsPlatformError("Unable to find a compatible " + "Visual Studio installation.") + + self._paths = vc_env.get('path', '') + paths = self._paths.split(os.pathsep) + self.cc = _find_exe("cl.exe", paths) + self.linker = _find_exe("link.exe", paths) + self.lib = _find_exe("lib.exe", paths) + self.rc = _find_exe("rc.exe", paths) # resource compiler + self.mc = _find_exe("mc.exe", paths) # message compiler + self.mt = _find_exe("mt.exe", paths) # message compiler + self._vcruntime_redist = vc_env.get('py_vcruntime_redist', '') + + for dir in vc_env.get('include', '').split(os.pathsep): + if dir: + self.add_include_dir(dir) + + for dir in vc_env.get('lib', '').split(os.pathsep): + if dir: + self.add_library_dir(dir) + + self.preprocess_options = None + # If vcruntime_redist is available, link against it dynamically. Otherwise, + # use /MT[d] to build statically, then switch from libucrt[d].lib to ucrt[d].lib + # later to dynamically link to ucrtbase but not vcruntime. + self.compile_options = [ + '/nologo', '/Ox', '/W3', '/GL', '/DNDEBUG' + ] + self.compile_options.append('/MD' if self._vcruntime_redist else '/MT') + + self.compile_options_debug = [ + '/nologo', '/Od', '/MDd', '/Zi', '/W3', '/D_DEBUG' + ] + + ldflags = [ + '/nologo', '/INCREMENTAL:NO', '/LTCG' + ] + if not self._vcruntime_redist: + ldflags.extend(('/nodefaultlib:libucrt.lib', 'ucrt.lib')) + + ldflags_debug = [ + '/nologo', '/INCREMENTAL:NO', '/LTCG', '/DEBUG:FULL' + ] + + self.ldflags_exe = [*ldflags, '/MANIFEST:EMBED,ID=1'] + self.ldflags_exe_debug = [*ldflags_debug, '/MANIFEST:EMBED,ID=1'] + self.ldflags_shared = [*ldflags, '/DLL', '/MANIFEST:EMBED,ID=2', '/MANIFESTUAC:NO'] + self.ldflags_shared_debug = [*ldflags_debug, '/DLL', '/MANIFEST:EMBED,ID=2', '/MANIFESTUAC:NO'] + self.ldflags_static = [*ldflags] + self.ldflags_static_debug = [*ldflags_debug] + + self._ldflags = { + (CCompiler.EXECUTABLE, None): self.ldflags_exe, + (CCompiler.EXECUTABLE, False): self.ldflags_exe, + (CCompiler.EXECUTABLE, True): self.ldflags_exe_debug, + (CCompiler.SHARED_OBJECT, None): self.ldflags_shared, + (CCompiler.SHARED_OBJECT, False): self.ldflags_shared, + (CCompiler.SHARED_OBJECT, True): self.ldflags_shared_debug, + (CCompiler.SHARED_LIBRARY, None): self.ldflags_static, + (CCompiler.SHARED_LIBRARY, False): self.ldflags_static, + (CCompiler.SHARED_LIBRARY, True): self.ldflags_static_debug, + } + + self.initialized = True + + # -- Worker methods ------------------------------------------------ + + def object_filenames(self, + source_filenames, + strip_dir=0, + output_dir=''): + ext_map = { + **{ext: self.obj_extension for ext in self.src_extensions}, + **{ext: self.res_extension for ext in self._rc_extensions + self._mc_extensions}, + } + + output_dir = output_dir or '' + + def make_out_path(p): + base, ext = os.path.splitext(p) + if strip_dir: + base = os.path.basename(base) + else: + _, base = os.path.splitdrive(base) + if base.startswith((os.path.sep, os.path.altsep)): + base = base[1:] + try: + # XXX: This may produce absurdly long paths. We should check + # the length of the result and trim base until we fit within + # 260 characters. + return os.path.join(output_dir, base + ext_map[ext]) + except LookupError: + # Better to raise an exception instead of silently continuing + # and later complain about sources and targets having + # different lengths + raise CompileError("Don't know how to compile {}".format(p)) + + return list(map(make_out_path, source_filenames)) + + + def compile(self, sources, + output_dir=None, macros=None, include_dirs=None, debug=0, + extra_preargs=None, extra_postargs=None, depends=None): + + if not self.initialized: + self.initialize() + compile_info = self._setup_compile(output_dir, macros, include_dirs, + sources, depends, extra_postargs) + macros, objects, extra_postargs, pp_opts, build = compile_info + + compile_opts = extra_preargs or [] + compile_opts.append('/c') + if debug: + compile_opts.extend(self.compile_options_debug) + else: + compile_opts.extend(self.compile_options) + + + add_cpp_opts = False + + for obj in objects: + try: + src, ext = build[obj] + except KeyError: + continue + if debug: + # pass the full pathname to MSVC in debug mode, + # this allows the debugger to find the source file + # without asking the user to browse for it + src = os.path.abspath(src) + + if ext in self._c_extensions: + input_opt = "/Tc" + src + elif ext in self._cpp_extensions: + input_opt = "/Tp" + src + add_cpp_opts = True + elif ext in self._rc_extensions: + # compile .RC to .RES file + input_opt = src + output_opt = "/fo" + obj + try: + self.spawn([self.rc] + pp_opts + [output_opt, input_opt]) + except DistutilsExecError as msg: + raise CompileError(msg) + continue + elif ext in self._mc_extensions: + # Compile .MC to .RC file to .RES file. + # * '-h dir' specifies the directory for the + # generated include file + # * '-r dir' specifies the target directory of the + # generated RC file and the binary message resource + # it includes + # + # For now (since there are no options to change this), + # we use the source-directory for the include file and + # the build directory for the RC file and message + # resources. This works at least for win32all. + h_dir = os.path.dirname(src) + rc_dir = os.path.dirname(obj) + try: + # first compile .MC to .RC and .H file + self.spawn([self.mc, '-h', h_dir, '-r', rc_dir, src]) + base, _ = os.path.splitext(os.path.basename (src)) + rc_file = os.path.join(rc_dir, base + '.rc') + # then compile .RC to .RES file + self.spawn([self.rc, "/fo" + obj, rc_file]) + + except DistutilsExecError as msg: + raise CompileError(msg) + continue + else: + # how to handle this file? + raise CompileError("Don't know how to compile {} to {}" + .format(src, obj)) + + args = [self.cc] + compile_opts + pp_opts + if add_cpp_opts: + args.append('/EHsc') + args.append(input_opt) + args.append("/Fo" + obj) + args.extend(extra_postargs) + + try: + self.spawn(args) + except DistutilsExecError as msg: + raise CompileError(msg) + + return objects + + + def create_static_lib(self, + objects, + output_libname, + output_dir=None, + debug=0, + target_lang=None): + + if not self.initialized: + self.initialize() + objects, output_dir = self._fix_object_args(objects, output_dir) + output_filename = self.library_filename(output_libname, + output_dir=output_dir) + + if self._need_link(objects, output_filename): + lib_args = objects + ['/OUT:' + output_filename] + if debug: + pass # XXX what goes here? + try: + log.debug('Executing "%s" %s', self.lib, ' '.join(lib_args)) + self.spawn([self.lib] + lib_args) + except DistutilsExecError as msg: + raise LibError(msg) + else: + log.debug("skipping %s (up-to-date)", output_filename) + + + def link(self, + target_desc, + objects, + output_filename, + output_dir=None, + libraries=None, + library_dirs=None, + runtime_library_dirs=None, + export_symbols=None, + debug=0, + extra_preargs=None, + extra_postargs=None, + build_temp=None, + target_lang=None): + + if not self.initialized: + self.initialize() + objects, output_dir = self._fix_object_args(objects, output_dir) + fixed_args = self._fix_lib_args(libraries, library_dirs, + runtime_library_dirs) + libraries, library_dirs, runtime_library_dirs = fixed_args + + if runtime_library_dirs: + self.warn("I don't know what to do with 'runtime_library_dirs': " + + str(runtime_library_dirs)) + + lib_opts = gen_lib_options(self, + library_dirs, runtime_library_dirs, + libraries) + if output_dir is not None: + output_filename = os.path.join(output_dir, output_filename) + + if self._need_link(objects, output_filename): + ldflags = self._ldflags[target_desc, debug] + + export_opts = ["/EXPORT:" + sym for sym in (export_symbols or [])] + + ld_args = (ldflags + lib_opts + export_opts + + objects + ['/OUT:' + output_filename]) + + # The MSVC linker generates .lib and .exp files, which cannot be + # suppressed by any linker switches. The .lib files may even be + # needed! Make sure they are generated in the temporary build + # directory. Since they have different names for debug and release + # builds, they can go into the same directory. + build_temp = os.path.dirname(objects[0]) + if export_symbols is not None: + (dll_name, dll_ext) = os.path.splitext( + os.path.basename(output_filename)) + implib_file = os.path.join( + build_temp, + self.library_filename(dll_name)) + ld_args.append ('/IMPLIB:' + implib_file) + + if extra_preargs: + ld_args[:0] = extra_preargs + if extra_postargs: + ld_args.extend(extra_postargs) + + output_dir = os.path.dirname(os.path.abspath(output_filename)) + self.mkpath(output_dir) + try: + log.debug('Executing "%s" %s', self.linker, ' '.join(ld_args)) + self.spawn([self.linker] + ld_args) + self._copy_vcruntime(output_dir) + except DistutilsExecError as msg: + raise LinkError(msg) + else: + log.debug("skipping %s (up-to-date)", output_filename) + + def _copy_vcruntime(self, output_dir): + vcruntime = self._vcruntime_redist + if not vcruntime or not os.path.isfile(vcruntime): + return + + if os.path.basename(vcruntime).lower() in _BUNDLED_DLLS: + return + + log.debug('Copying "%s"', vcruntime) + vcruntime = shutil.copy(vcruntime, output_dir) + os.chmod(vcruntime, stat.S_IWRITE) + + def spawn(self, cmd): + old_path = os.getenv('path') + try: + os.environ['path'] = self._paths + return super().spawn(cmd) + finally: + os.environ['path'] = old_path + + # -- Miscellaneous methods ----------------------------------------- + # These are all used by the 'gen_lib_options() function, in + # ccompiler.py. + + def library_dir_option(self, dir): + return "/LIBPATH:" + dir + + def runtime_library_dir_option(self, dir): + raise DistutilsPlatformError( + "don't know how to set runtime library search path for MSVC") + + def library_option(self, lib): + return self.library_filename(lib) + + def find_library_file(self, dirs, lib, debug=0): + # Prefer a debugging library if found (and requested), but deal + # with it if we don't have one. + if debug: + try_names = [lib + "_d", lib] + else: + try_names = [lib] + for dir in dirs: + for name in try_names: + libfile = os.path.join(dir, self.library_filename(name)) + if os.path.isfile(libfile): + return libfile + else: + # Oops, didn't find it in *any* of 'dirs' + return None diff --git a/Lib/distutils/archive_util.py b/Lib/distutils/archive_util.py index 4470bb022255..bed1384900b1 100644 --- a/Lib/distutils/archive_util.py +++ b/Lib/distutils/archive_util.py @@ -57,26 +57,28 @@ def make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, """Create a (possibly compressed) tar file from all the files under 'base_dir'. - 'compress' must be "gzip" (the default), "compress", "bzip2", or None. - (compress will be deprecated in Python 3.2) + 'compress' must be "gzip" (the default), "bzip2", "xz", "compress", or + None. ("compress" will be deprecated in Python 3.2) 'owner' and 'group' can be used to define an owner and a group for the archive that is being built. If not provided, the current owner and group will be used. The output tar file will be named 'base_dir' + ".tar", possibly plus - the appropriate compression extension (".gz", ".bz2" or ".Z"). + the appropriate compression extension (".gz", ".bz2", ".xz" or ".Z"). Returns the output filename. """ - tar_compression = {'gzip': 'gz', 'bzip2': 'bz2', None: '', 'compress': ''} - compress_ext = {'gzip': '.gz', 'bzip2': '.bz2', 'compress': '.Z'} + tar_compression = {'gzip': 'gz', 'bzip2': 'bz2', 'xz': 'xz', None: '', + 'compress': ''} + compress_ext = {'gzip': '.gz', 'bzip2': '.bz2', 'xz': '.xz', + 'compress': '.Z'} # flags for compression program, each element of list will be an argument if compress is not None and compress not in compress_ext.keys(): raise ValueError( - "bad value for 'compress': must be None, 'gzip', 'bzip2' " - "or 'compress'") + "bad value for 'compress': must be None, 'gzip', 'bzip2', " + "'xz' or 'compress'") archive_name = base_name + '.tar' if compress != 'compress': @@ -177,6 +179,7 @@ def make_zipfile(base_name, base_dir, verbose=0, dry_run=0): ARCHIVE_FORMATS = { 'gztar': (make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"), 'bztar': (make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"), + 'xztar': (make_tarball, [('compress', 'xz')], "xz'ed tar-file"), 'ztar': (make_tarball, [('compress', 'compress')], "compressed tar file"), 'tar': (make_tarball, [('compress', None)], "uncompressed tar file"), 'zip': (make_zipfile, [],"ZIP file") @@ -197,8 +200,8 @@ def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, """Create an archive file (eg. zip or tar). 'base_name' is the name of the file to create, minus any format-specific - extension; 'format' is the archive format: one of "zip", "tar", "ztar", - or "gztar". + extension; 'format' is the archive format: one of "zip", "tar", "gztar", + "bztar", "xztar", or "ztar". 'root_dir' is a directory that will be the root directory of the archive; ie. we typically chdir into 'root_dir' before creating the diff --git a/Lib/distutils/ccompiler.py b/Lib/distutils/ccompiler.py index 911e84dd3b3f..82fd7d5c4da2 100644 --- a/Lib/distutils/ccompiler.py +++ b/Lib/distutils/ccompiler.py @@ -752,7 +752,7 @@ def runtime_library_dir_option(self, dir): raise NotImplementedError def library_option(self, lib): - """Return the compiler option to add 'dir' to the list of libraries + """Return the compiler option to add 'lib' to the list of libraries linked into the shared library or executable. """ raise NotImplementedError @@ -959,7 +959,7 @@ def get_default_compiler(osname=None, platform=None): # is assumed to be in the 'distutils' package.) compiler_class = { 'unix': ('unixccompiler', 'UnixCCompiler', "standard UNIX-style compiler"), - 'msvc': ('msvccompiler', 'MSVCCompiler', + 'msvc': ('_msvccompiler', 'MSVCCompiler', "Microsoft Visual C++"), 'cygwin': ('cygwinccompiler', 'CygwinCCompiler', "Cygwin port of GNU C Compiler for Win32"), diff --git a/Lib/distutils/command/bdist.py b/Lib/distutils/command/bdist.py index 6814a1c38200..014871d280ed 100644 --- a/Lib/distutils/command/bdist.py +++ b/Lib/distutils/command/bdist.py @@ -61,13 +61,14 @@ class bdist(Command): 'nt': 'zip'} # Establish the preferred order (for the --help-formats option). - format_commands = ['rpm', 'gztar', 'bztar', 'ztar', 'tar', + format_commands = ['rpm', 'gztar', 'bztar', 'xztar', 'ztar', 'tar', 'wininst', 'zip', 'msi'] # And the real information. format_command = {'rpm': ('bdist_rpm', "RPM distribution"), 'gztar': ('bdist_dumb', "gzip'ed tar file"), 'bztar': ('bdist_dumb', "bzip2'ed tar file"), + 'xztar': ('bdist_dumb', "xz'ed tar file"), 'ztar': ('bdist_dumb', "compressed tar file"), 'tar': ('bdist_dumb', "tar file"), 'wininst': ('bdist_wininst', diff --git a/Lib/distutils/command/bdist_dumb.py b/Lib/distutils/command/bdist_dumb.py index 4405d12c058f..f1bfb2492357 100644 --- a/Lib/distutils/command/bdist_dumb.py +++ b/Lib/distutils/command/bdist_dumb.py @@ -22,7 +22,8 @@ class bdist_dumb(Command): "platform name to embed in generated filenames " "(default: %s)" % get_platform()), ('format=', 'f', - "archive format to create (tar, ztar, gztar, zip)"), + "archive format to create (tar, gztar, bztar, xztar, " + "ztar, zip)"), ('keep-temp', 'k', "keep the pseudo-installation tree around after " + "creating the distribution archive"), diff --git a/Lib/distutils/command/bdist_wininst.py b/Lib/distutils/command/bdist_wininst.py index 959a8bf62ece..0c0e2c1a2649 100644 --- a/Lib/distutils/command/bdist_wininst.py +++ b/Lib/distutils/command/bdist_wininst.py @@ -303,7 +303,6 @@ def get_installer_filename(self, fullname): return installer_name def get_exe_bytes(self): - from distutils.msvccompiler import get_build_version # If a target-version other than the current version has been # specified, then using the MSVC version from *this* build is no good. # Without actually finding and executing the target version and parsing @@ -313,20 +312,33 @@ def get_exe_bytes(self): # We can then execute this program to obtain any info we need, such # as the real sys.version string for the build. cur_version = get_python_version() - if self.target_version and self.target_version != cur_version: - # If the target version is *later* than us, then we assume they - # use what we use - # string compares seem wrong, but are what sysconfig.py itself uses - if self.target_version > cur_version: - bv = get_build_version() + + # If the target version is *later* than us, then we assume they + # use what we use + # string compares seem wrong, but are what sysconfig.py itself uses + if self.target_version and self.target_version < cur_version: + if self.target_version < "2.4": + bv = 6.0 + elif self.target_version == "2.4": + bv = 7.1 + elif self.target_version == "2.5": + bv = 8.0 + elif self.target_version <= "3.2": + bv = 9.0 + elif self.target_version <= "3.4": + bv = 10.0 else: - if self.target_version < "2.4": - bv = 6.0 - else: - bv = 7.1 + bv = 14.0 else: # for current version - use authoritative check. - bv = get_build_version() + try: + from msvcrt import CRT_ASSEMBLY_VERSION + except ImportError: + # cross-building, so assume the latest version + bv = 14.0 + else: + bv = float('.'.join(CRT_ASSEMBLY_VERSION.split('.', 2)[:2])) + # wininst-x.y.exe is in the same directory as this file directory = os.path.dirname(__file__) diff --git a/Lib/distutils/command/build.py b/Lib/distutils/command/build.py index cfc15cf0ddc5..337dd0bfc1e2 100644 --- a/Lib/distutils/command/build.py +++ b/Lib/distutils/command/build.py @@ -36,6 +36,8 @@ class build(Command): "(default: %s)" % get_platform()), ('compiler=', 'c', "specify the compiler type"), + ('parallel=', 'j', + "number of parallel build jobs"), ('debug', 'g', "compile extensions and libraries with debugging information"), ('force', 'f', @@ -65,6 +67,7 @@ def initialize_options(self): self.debug = None self.force = 0 self.executable = None + self.parallel = None def finalize_options(self): if self.plat_name is None: @@ -116,6 +119,12 @@ def finalize_options(self): if self.executable is None: self.executable = os.path.normpath(sys.executable) + if isinstance(self.parallel, str): + try: + self.parallel = int(self.parallel) + except ValueError: + raise DistutilsOptionError("parallel should be an integer") + def run(self): # Run all relevant sub-commands. This will be some subset of: # - build_py - pure Python modules diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py index 80689b63578d..d4cb11e6dbd7 100644 --- a/Lib/distutils/command/build_ext.py +++ b/Lib/distutils/command/build_ext.py @@ -4,7 +4,10 @@ modules (currently limited to C extensions, should accommodate C++ extensions ASAP).""" -import sys, os, re +import contextlib +import os +import re +import sys from distutils.core import Command from distutils.errors import * from distutils.sysconfig import customize_compiler, get_python_version @@ -14,17 +17,7 @@ from distutils.util import get_platform from distutils import log -# this keeps compatibility from 2.3 to 2.5 -if sys.version < "2.6": - USER_BASE = None - HAS_USER_SITE = False -else: - from site import USER_BASE - HAS_USER_SITE = True - -if os.name == 'nt': - from distutils.msvccompiler import get_build_version - MSVC_VERSION = int(get_build_version()) +from site import USER_BASE # An extension name is just a dot-separated list of Python NAMEs (ie. # the same as a fully-qualified module name). @@ -91,20 +84,19 @@ class build_ext(Command): "forcibly build everything (ignore file timestamps)"), ('compiler=', 'c', "specify the compiler type"), + ('parallel=', 'j', + "number of parallel build jobs"), ('swig-cpp', None, "make SWIG create C++ files (default is C)"), ('swig-opts=', None, "list of SWIG command line options"), ('swig=', None, "path to the SWIG executable"), + ('user', None, + "add user include, library and rpath") ] - boolean_options = ['inplace', 'debug', 'force', 'swig-cpp'] - - if HAS_USER_SITE: - user_options.append(('user', None, - "add user include, library and rpath")) - boolean_options.append('user') + boolean_options = ['inplace', 'debug', 'force', 'swig-cpp', 'user'] help_options = [ ('help-compiler', None, @@ -133,6 +125,7 @@ def initialize_options(self): self.swig_cpp = None self.swig_opts = None self.user = None + self.parallel = None def finalize_options(self): from distutils import sysconfig @@ -143,6 +136,7 @@ def finalize_options(self): ('compiler', 'compiler'), ('debug', 'debug'), ('force', 'force'), + ('parallel', 'parallel'), ('plat_name', 'plat_name'), ) @@ -208,27 +202,17 @@ def finalize_options(self): _sys_home = getattr(sys, '_home', None) if _sys_home: self.library_dirs.append(_sys_home) - if MSVC_VERSION >= 9: - # Use the .lib files for the correct architecture - if self.plat_name == 'win32': - suffix = '' - else: - # win-amd64 or win-ia64 - suffix = self.plat_name[4:] - new_lib = os.path.join(sys.exec_prefix, 'PCbuild') - if suffix: - new_lib = os.path.join(new_lib, suffix) - self.library_dirs.append(new_lib) - - elif MSVC_VERSION == 8: - self.library_dirs.append(os.path.join(sys.exec_prefix, - 'PC', 'VS8.0')) - elif MSVC_VERSION == 7: - self.library_dirs.append(os.path.join(sys.exec_prefix, - 'PC', 'VS7.1')) + + # Use the .lib files for the correct architecture + if self.plat_name == 'win32': + suffix = 'win32' else: - self.library_dirs.append(os.path.join(sys.exec_prefix, - 'PC', 'VC6')) + # win-amd64 or win-ia64 + suffix = self.plat_name[4:] + new_lib = os.path.join(sys.exec_prefix, 'PCbuild') + if suffix: + new_lib = os.path.join(new_lib, suffix) + self.library_dirs.append(new_lib) # for extensions under Cygwin and AtheOS Python's library directory must be # appended to library_dirs @@ -246,7 +230,7 @@ def finalize_options(self): # Python's library directory must be appended to library_dirs # See Issues: #1600860, #4366 if (sysconfig.get_config_var('Py_ENABLE_SHARED')): - if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")): + if not sysconfig.python_build: # building third party extensions self.library_dirs.append(sysconfig.get_config_var('LIBDIR')) else: @@ -283,6 +267,12 @@ def finalize_options(self): self.library_dirs.append(user_lib) self.rpath.append(user_lib) + if isinstance(self.parallel, str): + try: + self.parallel = int(self.parallel) + except ValueError: + raise DistutilsOptionError("parallel should be an integer") + def run(self): from distutils.ccompiler import new_compiler @@ -451,15 +441,45 @@ def get_outputs(self): def build_extensions(self): # First, sanity-check the 'extensions' list self.check_extensions_list(self.extensions) + if self.parallel: + self._build_extensions_parallel() + else: + self._build_extensions_serial() + + def _build_extensions_parallel(self): + workers = self.parallel + if self.parallel is True: + workers = os.cpu_count() # may return None + try: + from concurrent.futures import ThreadPoolExecutor + except ImportError: + workers = None + + if workers is None: + self._build_extensions_serial() + return + with ThreadPoolExecutor(max_workers=workers) as executor: + futures = [executor.submit(self.build_extension, ext) + for ext in self.extensions] + for ext, fut in zip(self.extensions, futures): + with self._filter_build_errors(ext): + fut.result() + + def _build_extensions_serial(self): for ext in self.extensions: - try: + with self._filter_build_errors(ext): self.build_extension(ext) - except (CCompilerError, DistutilsError, CompileError) as e: - if not ext.optional: - raise - self.warn('building extension "%s" failed: %s' % - (ext.name, e)) + + @contextlib.contextmanager + def _filter_build_errors(self, ext): + try: + yield + except (CCompilerError, DistutilsError, CompileError) as e: + if not ext.optional: + raise + self.warn('building extension "%s" failed: %s' % + (ext.name, e)) def build_extension(self, ext): sources = ext.sources @@ -511,15 +531,8 @@ def build_extension(self, ext): extra_postargs=extra_args, depends=ext.depends) - # XXX -- this is a Vile HACK! - # - # The setup.py script for Python on Unix needs to be able to - # get this list so it can perform all the clean up needed to - # avoid keeping object files around when cleaning out a failed - # build of an extension module. Since Distutils does not - # track dependencies, we have to get rid of intermediates to - # ensure all the intermediates will be properly re-built. - # + # XXX outdated variable, kept here in case third-part code + # needs it. self._built_objects = objects[:] # Now link the object files together into a "shared object" -- @@ -664,10 +677,7 @@ def get_ext_filename(self, ext_name): """ from distutils.sysconfig import get_config_var ext_path = ext_name.split('.') - # extensions in debug_mode are named 'module_d.pyd' under windows ext_suffix = get_config_var('EXT_SUFFIX') - if os.name == 'nt' and self.debug: - return os.path.join(*ext_path) + '_d' + ext_suffix return os.path.join(*ext_path) + ext_suffix def get_export_symbols(self, ext): @@ -692,7 +702,7 @@ def get_libraries(self, ext): # to need it mentioned explicitly, though, so that's what we do. # Append '_d' to the python import library on debug builds. if sys.platform == "win32": - from distutils.msvccompiler import MSVCCompiler + from distutils._msvccompiler import MSVCCompiler if not isinstance(self.compiler, MSVCCompiler): template = "python%d%d" if self.debug: diff --git a/Lib/distutils/command/build_py.py b/Lib/distutils/command/build_py.py index 9100b96a2abc..cf0ca57c3204 100644 --- a/Lib/distutils/command/build_py.py +++ b/Lib/distutils/command/build_py.py @@ -314,10 +314,10 @@ def get_outputs(self, include_bytecode=1): if include_bytecode: if self.compile: outputs.append(importlib.util.cache_from_source( - filename, debug_override=True)) + filename, optimization='')) if self.optimize > 0: outputs.append(importlib.util.cache_from_source( - filename, debug_override=False)) + filename, optimization=self.optimize)) outputs += [ os.path.join(build_dir, filename) diff --git a/Lib/distutils/command/check.py b/Lib/distutils/command/check.py index 22b9349dd605..7ebe707cff49 100644 --- a/Lib/distutils/command/check.py +++ b/Lib/distutils/command/check.py @@ -122,7 +122,7 @@ def _check_rst_data(self, data): """Returns warnings when the provided data doesn't compile.""" source_path = StringIO() parser = Parser() - settings = frontend.OptionParser().get_default_values() + settings = frontend.OptionParser(components=(Parser,)).get_default_values() settings.tab_width = 4 settings.pep_references = None settings.rfc_references = None @@ -138,8 +138,8 @@ def _check_rst_data(self, data): document.note_source(source_path, -1) try: parser.parse(data, document) - except AttributeError: - reporter.messages.append((-1, 'Could not finish the parsing.', - '', {})) + except AttributeError as e: + reporter.messages.append( + (-1, 'Could not finish the parsing: %s.' % e, '', {})) return reporter.messages diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py index 456511cdfbc4..67db007a0247 100644 --- a/Lib/distutils/command/install.py +++ b/Lib/distutils/command/install.py @@ -15,32 +15,17 @@ from distutils.util import get_platform from distutils.errors import DistutilsOptionError -# this keeps compatibility from 2.3 to 2.5 -if sys.version < "2.6": - USER_BASE = None - USER_SITE = None - HAS_USER_SITE = False -else: - from site import USER_BASE - from site import USER_SITE - HAS_USER_SITE = True - -if sys.version < "2.2": - WINDOWS_SCHEME = { - 'purelib': '$base', - 'platlib': '$base', - 'headers': '$base/Include/$dist_name', - 'scripts': '$base/Scripts', - 'data' : '$base', - } -else: - WINDOWS_SCHEME = { - 'purelib': '$base/Lib/site-packages', - 'platlib': '$base/Lib/site-packages', - 'headers': '$base/Include/$dist_name', - 'scripts': '$base/Scripts', - 'data' : '$base', - } +from site import USER_BASE +from site import USER_SITE +HAS_USER_SITE = True + +WINDOWS_SCHEME = { + 'purelib': '$base/Lib/site-packages', + 'platlib': '$base/Lib/site-packages', + 'headers': '$base/Include/$dist_name', + 'scripts': '$base/Scripts', + 'data' : '$base', +} INSTALL_SCHEMES = { 'unix_prefix': { @@ -66,7 +51,7 @@ 'purelib': '$usersite', 'platlib': '$usersite', 'headers': '$userbase/Python$py_version_nodot/Include/$dist_name', - 'scripts': '$userbase/Scripts', + 'scripts': '$userbase/Python$py_version_nodot/Scripts', 'data' : '$userbase', } diff --git a/Lib/distutils/command/install_lib.py b/Lib/distutils/command/install_lib.py index 215813ba97b8..6154cf09431f 100644 --- a/Lib/distutils/command/install_lib.py +++ b/Lib/distutils/command/install_lib.py @@ -22,15 +22,15 @@ class install_lib(Command): # possible scenarios: # 1) no compilation at all (--no-compile --no-optimize) # 2) compile .pyc only (--compile --no-optimize; default) - # 3) compile .pyc and "level 1" .pyo (--compile --optimize) - # 4) compile "level 1" .pyo only (--no-compile --optimize) - # 5) compile .pyc and "level 2" .pyo (--compile --optimize-more) - # 6) compile "level 2" .pyo only (--no-compile --optimize-more) + # 3) compile .pyc and "opt-1" .pyc (--compile --optimize) + # 4) compile "opt-1" .pyc only (--no-compile --optimize) + # 5) compile .pyc and "opt-2" .pyc (--compile --optimize-more) + # 6) compile "opt-2" .pyc only (--no-compile --optimize-more) # - # The UI for this is two option, 'compile' and 'optimize'. + # The UI for this is two options, 'compile' and 'optimize'. # 'compile' is strictly boolean, and only decides whether to # generate .pyc files. 'optimize' is three-way (0, 1, or 2), and - # decides both whether to generate .pyo files and what level of + # decides both whether to generate .pyc files and what level of # optimization to use. user_options = [ @@ -166,10 +166,10 @@ def _bytecode_filenames(self, py_filenames): continue if self.compile: bytecode_files.append(importlib.util.cache_from_source( - py_file, debug_override=True)) + py_file, optimization='')) if self.optimize > 0: bytecode_files.append(importlib.util.cache_from_source( - py_file, debug_override=False)) + py_file, optimization=self.optimize)) return bytecode_files diff --git a/Lib/distutils/command/register.py b/Lib/distutils/command/register.py index 99545affa4a8..b49f86fe5814 100644 --- a/Lib/distutils/command/register.py +++ b/Lib/distutils/command/register.py @@ -87,7 +87,7 @@ def classifiers(self): ''' url = self.repository+'?:action=list_classifiers' response = urllib.request.urlopen(url) - log.info(response.read()) + log.info(self._read_pypi_response(response)) def verify_metadata(self): ''' Send the metadata to the package index server to be checked. @@ -300,5 +300,5 @@ def post_to_server(self, data, auth=None): result = 200, 'OK' if self.show_response: dashes = '-' * 75 - self.announce('%s%s%s' % (dashes, data, dashes)) + self.announce('%s%r%s' % (dashes, data, dashes)) return result diff --git a/Lib/distutils/command/upload.py b/Lib/distutils/command/upload.py index 287158343b8b..1c4fc48a1293 100644 --- a/Lib/distutils/command/upload.py +++ b/Lib/distutils/command/upload.py @@ -1,24 +1,21 @@ -"""distutils.command.upload +""" +distutils.command.upload -Implements the Distutils 'upload' subcommand (upload package to PyPI).""" +Implements the Distutils 'upload' subcommand (upload package to a package +index). +""" -from distutils.errors import * -from distutils.core import PyPIRCCommand -from distutils.spawn import spawn -from distutils import log -import sys -import os, io -import socket +import os +import io import platform +import hashlib from base64 import standard_b64encode from urllib.request import urlopen, Request, HTTPError from urllib.parse import urlparse - -# this keeps compatibility for 2.3 and 2.4 -if sys.version < "2.5": - from md5 import md5 -else: - from hashlib import md5 +from distutils.errors import DistutilsError, DistutilsOptionError +from distutils.core import PyPIRCCommand +from distutils.spawn import spawn +from distutils import log class upload(PyPIRCCommand): @@ -60,7 +57,8 @@ def finalize_options(self): def run(self): if not self.distribution.dist_files: - raise DistutilsOptionError("No dist file created in earlier command") + msg = "No dist file created in earlier command" + raise DistutilsOptionError(msg) for command, pyversion, filename in self.distribution.dist_files: self.upload_file(command, pyversion, filename) @@ -103,10 +101,10 @@ def upload_file(self, command, pyversion, filename): 'content': (os.path.basename(filename),content), 'filetype': command, 'pyversion': pyversion, - 'md5_digest': md5(content).hexdigest(), + 'md5_digest': hashlib.md5(content).hexdigest(), # additional meta-data - 'metadata_version' : '1.0', + 'metadata_version': '1.0', 'summary': meta.get_description(), 'home_page': meta.get_url(), 'author': meta.get_contact(), @@ -143,13 +141,13 @@ def upload_file(self, command, pyversion, filename): # Build up the MIME payload for the POST data boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' - sep_boundary = b'\n--' + boundary.encode('ascii') - end_boundary = sep_boundary + b'--' + sep_boundary = b'\r\n--' + boundary.encode('ascii') + end_boundary = sep_boundary + b'--\r\n' body = io.BytesIO() for key, value in data.items(): - title = '\nContent-Disposition: form-data; name="%s"' % key + title = '\r\nContent-Disposition: form-data; name="%s"' % key # handle multiple entries for the same name - if type(value) != type([]): + if not isinstance(value, list): value = [value] for value in value: if type(value) is tuple: @@ -159,21 +157,22 @@ def upload_file(self, command, pyversion, filename): value = str(value).encode('utf-8') body.write(sep_boundary) body.write(title.encode('utf-8')) - body.write(b"\n\n") + body.write(b"\r\n\r\n") body.write(value) if value and value[-1:] == b'\r': body.write(b'\n') # write an extra newline (lurve Macs) body.write(end_boundary) - body.write(b"\n") body = body.getvalue() - self.announce("Submitting %s to %s" % (filename, self.repository), log.INFO) + msg = "Submitting %s to %s" % (filename, self.repository) + self.announce(msg, log.INFO) # build the Request - headers = {'Content-type': - 'multipart/form-data; boundary=%s' % boundary, - 'Content-length': str(len(body)), - 'Authorization': auth} + headers = { + 'Content-type': 'multipart/form-data; boundary=%s' % boundary, + 'Content-length': str(len(body)), + 'Authorization': auth, + } request = Request(self.repository, data=body, headers=headers) @@ -184,7 +183,7 @@ def upload_file(self, command, pyversion, filename): reason = result.msg except OSError as e: self.announce(str(e), log.ERROR) - return + raise except HTTPError as e: status = e.code reason = e.msg @@ -193,8 +192,10 @@ def upload_file(self, command, pyversion, filename): self.announce('Server response (%s): %s' % (status, reason), log.INFO) else: - self.announce('Upload failed (%s): %s' % (status, reason), - log.ERROR) + msg = 'Upload failed (%s): %s' % (status, reason) + self.announce(msg, log.ERROR) + raise DistutilsError(msg) if self.show_response: - msg = '\n'.join(('-' * 75, result.read(), '-' * 75)) + text = self._read_pypi_response(result) + msg = '\n'.join(('-' * 75, text, '-' * 75)) self.announce(msg, log.INFO) diff --git a/Lib/distutils/command/wininst-14.0-amd64.exe b/Lib/distutils/command/wininst-14.0-amd64.exe new file mode 100644 index 000000000000..7a5e78d52bcc Binary files /dev/null and b/Lib/distutils/command/wininst-14.0-amd64.exe differ diff --git a/Lib/distutils/command/wininst-14.0.exe b/Lib/distutils/command/wininst-14.0.exe new file mode 100644 index 000000000000..cc43296b677a Binary files /dev/null and b/Lib/distutils/command/wininst-14.0.exe differ diff --git a/Lib/distutils/config.py b/Lib/distutils/config.py index 7439a83a4f0d..382aca8fc12e 100644 --- a/Lib/distutils/config.py +++ b/Lib/distutils/config.py @@ -110,6 +110,13 @@ def _read_pypirc(self): return {} + def _read_pypi_response(self, response): + """Read and decode a PyPI HTTP response.""" + import cgi + content_type = response.getheader('content-type', 'text/plain') + encoding = cgi.parse_header(content_type)[1].get('charset', 'ascii') + return response.read().decode(encoding) + def initialize_options(self): """Initialize options.""" self.repository = None diff --git a/Lib/distutils/core.py b/Lib/distutils/core.py index c811d5bd9c46..d603d4a45a73 100644 --- a/Lib/distutils/core.py +++ b/Lib/distutils/core.py @@ -11,7 +11,6 @@ from distutils.debug import DEBUG from distutils.errors import * -from distutils.util import grok_environment_error # Mainly import these so setup scripts can "from distutils.core import" them. from distutils.dist import Distribution @@ -150,13 +149,11 @@ class found in 'cmdclass' is used in place of the default, which is except KeyboardInterrupt: raise SystemExit("interrupted") except OSError as exc: - error = grok_environment_error(exc) - if DEBUG: - sys.stderr.write(error + "\n") + sys.stderr.write("error: %s\n" % (exc,)) raise else: - raise SystemExit(error) + raise SystemExit("error: %s" % (exc,)) except (DistutilsError, CCompilerError) as msg: @@ -207,16 +204,15 @@ def run_setup (script_name, script_args=None, stop_after="run"): global _setup_stop_after, _setup_distribution _setup_stop_after = stop_after - save_argv = sys.argv + save_argv = sys.argv.copy() g = {'__file__': script_name} - l = {} try: try: sys.argv[0] = script_name if script_args is not None: sys.argv[1:] = script_args with open(script_name, 'rb') as f: - exec(f.read(), g, l) + exec(f.read(), g) finally: sys.argv = save_argv _setup_stop_after = None @@ -224,8 +220,6 @@ def run_setup (script_name, script_args=None, stop_after="run"): # Hmm, should we do something if exiting with a non-zero code # (ie. error)? pass - except: - raise if _setup_distribution is None: raise RuntimeError(("'distutils.core.setup()' was never called -- " diff --git a/Lib/distutils/dir_util.py b/Lib/distutils/dir_util.py index 2b35aa318e05..d5cd8e3e24f4 100644 --- a/Lib/distutils/dir_util.py +++ b/Lib/distutils/dir_util.py @@ -2,7 +2,7 @@ Utility functions for manipulating directories and directory trees.""" -import os, sys +import os import errno from distutils.errors import DistutilsFileError, DistutilsInternalError from distutils import log @@ -81,7 +81,7 @@ def create_tree(base_dir, files, mode=0o777, verbose=1, dry_run=0): """Create all the empty directories under 'base_dir' needed to put 'files' there. - 'base_dir' is just the a name of a directory which doesn't necessarily + 'base_dir' is just the name of a directory which doesn't necessarily exist yet; 'files' is a list of filenames to be interpreted relative to 'base_dir'. 'base_dir' + the directory portion of every file in 'files' will be created if it doesn't already exist. 'mode', 'verbose' and @@ -125,12 +125,11 @@ def copy_tree(src, dst, preserve_mode=1, preserve_times=1, try: names = os.listdir(src) except OSError as e: - (errno, errstr) = e if dry_run: names = [] else: raise DistutilsFileError( - "error listing files in '%s': %s" % (src, errstr)) + "error listing files in '%s': %s" % (src, e.strerror)) if not dry_run: mkpath(dst, verbose=verbose) @@ -182,7 +181,6 @@ def remove_tree(directory, verbose=1, dry_run=0): Any errors are ignored (apart from being reported to stdout if 'verbose' is true). """ - from distutils.util import grok_environment_error global _path_created if verbose >= 1: @@ -199,8 +197,7 @@ def remove_tree(directory, verbose=1, dry_run=0): if abspath in _path_created: del _path_created[abspath] except OSError as exc: - log.warn(grok_environment_error( - exc, "error removing %s: " % directory)) + log.warn("error removing %s: %s", directory, exc) def ensure_relative(path): """Take the full path 'path', and make it a relative path. diff --git a/Lib/distutils/dist.py b/Lib/distutils/dist.py index 7eb04bc3f598..ffb33ff645a8 100644 --- a/Lib/distutils/dist.py +++ b/Lib/distutils/dist.py @@ -4,7 +4,9 @@ being built/installed/distributed. """ -import sys, os, re +import sys +import os +import re from email import message_from_file try: @@ -22,7 +24,7 @@ # the same as a Python NAME -- I don't allow leading underscores. The fact # that they're very similar is no coincidence; the default naming scheme is # to look for a Python module named after the command. -command_re = re.compile (r'^[a-zA-Z]([a-zA-Z0-9_]*)$') +command_re = re.compile(r'^[a-zA-Z]([a-zA-Z0-9_]*)$') class Distribution: @@ -39,7 +41,6 @@ class Distribution: See the code for 'setup()', in core.py, for details. """ - # 'global_options' describes the command-line options that may be # supplied to the setup script prior to any actual commands. # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of @@ -48,12 +49,13 @@ class Distribution: # don't want to pollute the commands with too many options that they # have minimal control over. # The fourth entry for verbose means that it can be repeated. - global_options = [('verbose', 'v', "run verbosely (default)", 1), - ('quiet', 'q', "run quietly (turns verbosity off)"), - ('dry-run', 'n', "don't actually do anything"), - ('help', 'h', "show detailed help message"), - ('no-user-cfg', None, - 'ignore pydistutils.cfg in your home directory'), + global_options = [ + ('verbose', 'v', "run verbosely (default)", 1), + ('quiet', 'q', "run quietly (turns verbosity off)"), + ('dry-run', 'n', "don't actually do anything"), + ('help', 'h', "show detailed help message"), + ('no-user-cfg', None, + 'ignore pydistutils.cfg in your home directory'), ] # 'common_usage' is a short (2-3 line) string describing the common @@ -115,10 +117,9 @@ class Distribution: # negative options are options that exclude other options negative_opt = {'quiet': 'verbose'} - # -- Creation/initialization methods ------------------------------- - def __init__ (self, attrs=None): + def __init__(self, attrs=None): """Construct a new Distribution instance: initialize all the attributes of a Distribution, and then use 'attrs' (a dictionary mapping attribute names to values) to assign some of those @@ -532,15 +533,15 @@ def _parse_command_opts(self, parser, args): # to be sure that the basic "command" interface is implemented. if not issubclass(cmd_class, Command): raise DistutilsClassError( - "command class %s must subclass Command" % cmd_class) + "command class %s must subclass Command" % cmd_class) # Also make sure that the command object provides a list of its # known options. if not (hasattr(cmd_class, 'user_options') and isinstance(cmd_class.user_options, list)): - raise DistutilsClassError(("command class %s must provide " + - "'user_options' attribute (a list of tuples)") % \ - cmd_class) + msg = ("command class %s must provide " + "'user_options' attribute (a list of tuples)") + raise DistutilsClassError(msg % cmd_class) # If the command class has a list of negative alias options, # merge it in with the global negative aliases. @@ -552,12 +553,11 @@ def _parse_command_opts(self, parser, args): # Check for help_options in command class. They have a different # format (tuple of four) so we need to preprocess them here. if (hasattr(cmd_class, 'help_options') and - isinstance(cmd_class.help_options, list)): + isinstance(cmd_class.help_options, list)): help_options = fix_help_options(cmd_class.help_options) else: help_options = [] - # All commands support the global options too, just by adding # in 'global_options'. parser.set_option_table(self.global_options + @@ -570,7 +570,7 @@ def _parse_command_opts(self, parser, args): return if (hasattr(cmd_class, 'help_options') and - isinstance(cmd_class.help_options, list)): + isinstance(cmd_class.help_options, list)): help_option_found=0 for (help_option, short, desc, func) in cmd_class.help_options: if hasattr(opts, parser.get_attr_name(help_option)): @@ -647,7 +647,7 @@ def _show_help(self, parser, global_options=1, display_options=1, else: klass = self.get_command_class(command) if (hasattr(klass, 'help_options') and - isinstance(klass.help_options, list)): + isinstance(klass.help_options, list)): parser.set_option_table(klass.user_options + fix_help_options(klass.help_options)) else: @@ -814,7 +814,7 @@ def get_command_class(self, command): klass_name = command try: - __import__ (module_name) + __import__(module_name) module = sys.modules[module_name] except ImportError: continue @@ -823,8 +823,8 @@ def get_command_class(self, command): klass = getattr(module, klass_name) except AttributeError: raise DistutilsModuleError( - "invalid command '%s' (no class '%s' in module '%s')" - % (command, klass_name, module_name)) + "invalid command '%s' (no class '%s' in module '%s')" + % (command, klass_name, module_name)) self.cmdclass[command] = klass return klass @@ -840,7 +840,7 @@ def get_command_obj(self, command, create=1): cmd_obj = self.command_obj.get(command) if not cmd_obj and create: if DEBUG: - self.announce("Distribution.get_command_obj(): " \ + self.announce("Distribution.get_command_obj(): " "creating '%s' command object" % command) klass = self.get_command_class(command) @@ -897,8 +897,8 @@ def _set_command_options(self, command_obj, option_dict=None): setattr(command_obj, option, value) else: raise DistutilsOptionError( - "error in %s: command '%s' has no such option '%s'" - % (source, command_name, option)) + "error in %s: command '%s' has no such option '%s'" + % (source, command_name, option)) except ValueError as msg: raise DistutilsOptionError(msg) @@ -974,7 +974,6 @@ def run_command(self, command): cmd_obj.run() self.have_run[command] = 1 - # -- Distribution query methods ------------------------------------ def has_pure_modules(self): @@ -1112,17 +1111,17 @@ def write_pkg_file(self, file): """ version = '1.0' if (self.provides or self.requires or self.obsoletes or - self.classifiers or self.download_url): + self.classifiers or self.download_url): version = '1.1' file.write('Metadata-Version: %s\n' % version) - file.write('Name: %s\n' % self.get_name() ) - file.write('Version: %s\n' % self.get_version() ) - file.write('Summary: %s\n' % self.get_description() ) - file.write('Home-page: %s\n' % self.get_url() ) - file.write('Author: %s\n' % self.get_contact() ) - file.write('Author-email: %s\n' % self.get_contact_email() ) - file.write('License: %s\n' % self.get_license() ) + file.write('Name: %s\n' % self.get_name()) + file.write('Version: %s\n' % self.get_version()) + file.write('Summary: %s\n' % self.get_description()) + file.write('Home-page: %s\n' % self.get_url()) + file.write('Author: %s\n' % self.get_contact()) + file.write('Author-email: %s\n' % self.get_contact_email()) + file.write('License: %s\n' % self.get_license()) if self.download_url: file.write('Download-URL: %s\n' % self.download_url) @@ -1131,7 +1130,7 @@ def write_pkg_file(self, file): keywords = ','.join(self.get_keywords()) if keywords: - file.write('Keywords: %s\n' % keywords ) + file.write('Keywords: %s\n' % keywords) self._write_list(file, 'Platform', self.get_platforms()) self._write_list(file, 'Classifier', self.get_classifiers()) diff --git a/Lib/distutils/extension.py b/Lib/distutils/extension.py index a93655af2cf8..7efbb74f8953 100644 --- a/Lib/distutils/extension.py +++ b/Lib/distutils/extension.py @@ -131,6 +131,14 @@ def __init__(self, name, sources, msg = "Unknown Extension options: %s" % options warnings.warn(msg) + def __repr__(self): + return '<%s.%s(%r) at %#x>' % ( + self.__class__.__module__, + self.__class__.__qualname__, + self.name, + id(self)) + + def read_setup_file(filename): """Reads a Setup file and returns Extension instances.""" from distutils.sysconfig import (parse_makefile, expand_makefile_vars, diff --git a/Lib/distutils/file_util.py b/Lib/distutils/file_util.py index f6ed290f137d..b3fee35a6cce 100644 --- a/Lib/distutils/file_util.py +++ b/Lib/distutils/file_util.py @@ -80,7 +80,8 @@ def copy_file(src, dst, preserve_mode=1, preserve_times=1, update=0, (os.symlink) instead of copying: set it to "hard" or "sym"; if it is None (the default), files are copied. Don't set 'link' on systems that don't support it: 'copy_file()' doesn't check if hard or symbolic - linking is available. + linking is available. If hardlink fails, falls back to + _copy_file_contents(). Under Mac OS, uses the native file copy function in macostools; on other systems, uses '_copy_file_contents()' to copy file contents. @@ -132,24 +133,31 @@ def copy_file(src, dst, preserve_mode=1, preserve_times=1, update=0, # (Unix only, of course, but that's the caller's responsibility) elif link == 'hard': if not (os.path.exists(dst) and os.path.samefile(src, dst)): - os.link(src, dst) + try: + os.link(src, dst) + return (dst, 1) + except OSError: + # If hard linking fails, fall back on copying file + # (some special filesystems don't support hard linking + # even under Unix, see issue #8876). + pass elif link == 'sym': if not (os.path.exists(dst) and os.path.samefile(src, dst)): os.symlink(src, dst) + return (dst, 1) # Otherwise (non-Mac, not linking), copy the file contents and # (optionally) copy the times and mode. - else: - _copy_file_contents(src, dst) - if preserve_mode or preserve_times: - st = os.stat(src) + _copy_file_contents(src, dst) + if preserve_mode or preserve_times: + st = os.stat(src) - # According to David Ascher , utime() should be done - # before chmod() (at least under NT). - if preserve_times: - os.utime(dst, (st[ST_ATIME], st[ST_MTIME])) - if preserve_mode: - os.chmod(dst, S_IMODE(st[ST_MODE])) + # According to David Ascher , utime() should be done + # before chmod() (at least under NT). + if preserve_times: + os.utime(dst, (st[ST_ATIME], st[ST_MTIME])) + if preserve_mode: + os.chmod(dst, S_IMODE(st[ST_MODE])) return (dst, 1) @@ -194,7 +202,7 @@ def move_file (src, dst, try: os.rename(src, dst) except OSError as e: - (num, msg) = e + (num, msg) = e.args if num == errno.EXDEV: copy_it = True else: @@ -206,7 +214,7 @@ def move_file (src, dst, try: os.unlink(src) except OSError as e: - (num, msg) = e + (num, msg) = e.args try: os.unlink(dst) except OSError: diff --git a/Lib/distutils/msvc9compiler.py b/Lib/distutils/msvc9compiler.py index 9688f20019c8..da4b21d22a9a 100644 --- a/Lib/distutils/msvc9compiler.py +++ b/Lib/distutils/msvc9compiler.py @@ -179,6 +179,9 @@ def get_build_version(): i = i + len(prefix) s, rest = sys.version[i:].split(" ", 1) majorVersion = int(s[:-2]) - 6 + if majorVersion >= 13: + # v13 was skipped and should be v14 + majorVersion += 1 minorVersion = int(s[2:3]) / 10.0 # I don't think paths are affected by minor version in version 6 if majorVersion == 6: @@ -413,7 +416,7 @@ def initialize(self, plat_name=None): self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO'] if self.__version >= 7: self.ldflags_shared_debug = [ - '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG', '/pdb:None' + '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG' ] self.ldflags_static = [ '/nologo'] diff --git a/Lib/distutils/msvccompiler.py b/Lib/distutils/msvccompiler.py index 81166569619b..1048cd415939 100644 --- a/Lib/distutils/msvccompiler.py +++ b/Lib/distutils/msvccompiler.py @@ -157,6 +157,9 @@ def get_build_version(): i = i + len(prefix) s, rest = sys.version[i:].split(" ", 1) majorVersion = int(s[:-2]) - 6 + if majorVersion >= 13: + # v13 was skipped and should be v14 + majorVersion += 1 minorVersion = int(s[2:3]) / 10.0 # I don't think paths are affected by minor version in version 6 if majorVersion == 6: diff --git a/Lib/distutils/spawn.py b/Lib/distutils/spawn.py index b1c5a442a5da..5dd415a283d1 100644 --- a/Lib/distutils/spawn.py +++ b/Lib/distutils/spawn.py @@ -10,6 +10,7 @@ import os from distutils.errors import DistutilsPlatformError, DistutilsExecError +from distutils.debug import DEBUG from distutils import log def spawn(cmd, search_path=1, verbose=0, dry_run=0): @@ -28,6 +29,9 @@ def spawn(cmd, search_path=1, verbose=0, dry_run=0): Raise DistutilsExecError if running the program fails in any way; just return on success. """ + # cmd is documented as a list, but just in case some code passes a tuple + # in, protect our %-formatting code against horrible death + cmd = list(cmd) if os.name == 'posix': _spawn_posix(cmd, search_path, dry_run=dry_run) elif os.name == 'nt': @@ -65,12 +69,16 @@ def _spawn_nt(cmd, search_path=1, verbose=0, dry_run=0): rc = os.spawnv(os.P_WAIT, executable, cmd) except OSError as exc: # this seems to happen when the command isn't found + if not DEBUG: + cmd = executable raise DistutilsExecError( - "command '%s' failed: %s" % (cmd[0], exc.args[-1])) + "command %r failed: %s" % (cmd, exc.args[-1])) if rc != 0: # and this reflects the command running but failing + if not DEBUG: + cmd = executable raise DistutilsExecError( - "command '%s' failed with exit status %d" % (cmd[0], rc)) + "command %r failed with exit status %d" % (cmd, rc)) if sys.platform == 'darwin': from distutils import sysconfig @@ -81,8 +89,9 @@ def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0): log.info(' '.join(cmd)) if dry_run: return + executable = cmd[0] exec_fn = search_path and os.execvp or os.execv - exec_args = [cmd[0], cmd] + env = None if sys.platform == 'darwin': global _cfg_target, _cfg_target_split if _cfg_target is None: @@ -103,17 +112,23 @@ def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0): env = dict(os.environ, MACOSX_DEPLOYMENT_TARGET=cur_target) exec_fn = search_path and os.execvpe or os.execve - exec_args.append(env) pid = os.fork() if pid == 0: # in the child try: - exec_fn(*exec_args) + if env is None: + exec_fn(executable, cmd) + else: + exec_fn(executable, cmd, env) except OSError as e: - sys.stderr.write("unable to execute %s: %s\n" - % (cmd[0], e.strerror)) + if not DEBUG: + cmd = executable + sys.stderr.write("unable to execute %r: %s\n" + % (cmd, e.strerror)) os._exit(1) - sys.stderr.write("unable to execute %s for unknown reasons" % cmd[0]) + if not DEBUG: + cmd = executable + sys.stderr.write("unable to execute %r for unknown reasons" % cmd) os._exit(1) else: # in the parent # Loop until the child either exits or is terminated by a signal @@ -122,29 +137,34 @@ def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0): try: pid, status = os.waitpid(pid, 0) except OSError as exc: - import errno - if exc.errno == errno.EINTR: - continue + if not DEBUG: + cmd = executable raise DistutilsExecError( - "command '%s' failed: %s" % (cmd[0], exc.args[-1])) + "command %r failed: %s" % (cmd, exc.args[-1])) if os.WIFSIGNALED(status): + if not DEBUG: + cmd = executable raise DistutilsExecError( - "command '%s' terminated by signal %d" - % (cmd[0], os.WTERMSIG(status))) + "command %r terminated by signal %d" + % (cmd, os.WTERMSIG(status))) elif os.WIFEXITED(status): exit_status = os.WEXITSTATUS(status) if exit_status == 0: return # hey, it succeeded! else: + if not DEBUG: + cmd = executable raise DistutilsExecError( - "command '%s' failed with exit status %d" - % (cmd[0], exit_status)) + "command %r failed with exit status %d" + % (cmd, exit_status)) elif os.WIFSTOPPED(status): continue else: + if not DEBUG: + cmd = executable raise DistutilsExecError( - "unknown error executing '%s': termination status %d" - % (cmd[0], status)) + "unknown error executing %r: termination status %d" + % (cmd, status)) def find_executable(executable, path=None): """Tries to find 'executable' in the directories listed in 'path'. diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py index 75537db8d06d..573724ddd778 100644 --- a/Lib/distutils/sysconfig.py +++ b/Lib/distutils/sysconfig.py @@ -9,6 +9,7 @@ Email: """ +import _imp import os import re import sys @@ -22,23 +23,15 @@ BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix) # Path to the base directory of the project. On Windows the binary may -# live in project/PCBuild9. If we're dealing with an x64 Windows build, -# it'll live in project/PCbuild/amd64. +# live in project/PCBuild/win32 or project/PCBuild/amd64. # set for cross builds if "_PYTHON_PROJECT_BASE" in os.environ: project_base = os.path.abspath(os.environ["_PYTHON_PROJECT_BASE"]) else: project_base = os.path.dirname(os.path.abspath(sys.executable)) -if os.name == "nt" and "pcbuild" in project_base[-8:].lower(): - project_base = os.path.abspath(os.path.join(project_base, os.path.pardir)) -# PC/VS7.1 -if os.name == "nt" and "\\pc\\v" in project_base[-10:].lower(): - project_base = os.path.abspath(os.path.join(project_base, os.path.pardir, - os.path.pardir)) -# PC/AMD64 -if os.name == "nt" and "\\pcbuild\\amd64" in project_base[-14:].lower(): - project_base = os.path.abspath(os.path.join(project_base, os.path.pardir, - os.path.pardir)) +if (os.name == 'nt' and + project_base.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))): + project_base = os.path.dirname(os.path.dirname(project_base)) # python_build: (Boolean) if true, we're either building Python or # building an extension with an un-installed Python, so we use @@ -51,11 +44,9 @@ def _is_python_source_dir(d): return True return False _sys_home = getattr(sys, '_home', None) -if _sys_home and os.name == 'nt' and \ - _sys_home.lower().endswith(('pcbuild', 'pcbuild\\amd64')): - _sys_home = os.path.dirname(_sys_home) - if _sys_home.endswith('pcbuild'): # must be amd64 - _sys_home = os.path.dirname(_sys_home) +if (_sys_home and os.name == 'nt' and + _sys_home.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))): + _sys_home = os.path.dirname(os.path.dirname(_sys_home)) def _python_build(): if _sys_home: return _is_python_source_dir(_sys_home) @@ -151,10 +142,7 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): if standard_lib: return os.path.join(prefix, "Lib") else: - if get_python_version() < "2.2": - return prefix - else: - return os.path.join(prefix, "Lib", "site-packages") + return os.path.join(prefix, "Lib", "site-packages") else: raise DistutilsPlatformError( "I don't know where Python installs its library " @@ -179,7 +167,8 @@ def customize_compiler(compiler): # version and build tools may not support the same set # of CPU architectures for universal builds. global _config_vars - if not _config_vars.get('CUSTOMIZED_OSX_COMPILER', ''): + # Use get_config_var() to ensure _config_vars is initialized. + if not get_config_var('CUSTOMIZED_OSX_COMPILER'): import _osx_support _osx_support.customize_compiler(_config_vars) _config_vars['CUSTOMIZED_OSX_COMPILER'] = 'True' @@ -243,12 +232,8 @@ def get_config_h_filename(): inc_dir = _sys_home or project_base else: inc_dir = get_python_inc(plat_specific=1) - if get_python_version() < '2.2': - config_h = 'config.h' - else: - # The name of the config.h file changed in 2.2 - config_h = 'pyconfig.h' - return os.path.join(inc_dir, config_h) + + return os.path.join(inc_dir, 'pyconfig.h') def get_makefile_filename(): @@ -460,17 +445,6 @@ def _init_posix(): if python_build: g['LDSHARED'] = g['BLDSHARED'] - elif get_python_version() < '2.1': - # The following two branches are for 1.5.2 compatibility. - if sys.platform == 'aix4': # what about AIX 3.x ? - # Linker script is in the config directory, not in Modules as the - # Makefile says. - python_lib = get_python_lib(standard_lib=1) - ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix') - python_exp = os.path.join(python_lib, 'config', 'python.exp') - - g['LDSHARED'] = "%s %s -bI:%s" % (ld_so_aix, g['CC'], python_exp) - global _config_vars _config_vars = g @@ -485,7 +459,7 @@ def _init_nt(): # XXX hmmm.. a normal install puts include files here g['INCLUDEPY'] = get_python_inc(plat_specific=0) - g['EXT_SUFFIX'] = '.pyd' + g['EXT_SUFFIX'] = _imp.extension_suffixes()[0] g['EXE'] = ".exe" g['VERSION'] = get_python_version().replace(".", "") g['BINDIR'] = os.path.dirname(os.path.abspath(sys.executable)) diff --git a/Lib/distutils/tests/support.py b/Lib/distutils/tests/support.py index 84d92323284f..7385c6bbf671 100644 --- a/Lib/distutils/tests/support.py +++ b/Lib/distutils/tests/support.py @@ -32,14 +32,15 @@ def tearDown(self): def _log(self, level, msg, args): if level not in (DEBUG, INFO, WARN, ERROR, FATAL): raise ValueError('%s wrong log level' % str(level)) + if not isinstance(msg, str): + raise TypeError("msg should be str, not '%.200s'" + % (type(msg).__name__)) self.logs.append((level, msg, args)) def get_logs(self, *levels): def _format(msg, args): - if len(args) == 0: - return msg return msg % args - return [_format(msg, args) for level, msg, args + return [msg % args for level, msg, args in self.logs if level in levels] def clear_logs(self): @@ -206,4 +207,4 @@ def fixup_build_ext(cmd): cmd.library_dirs = [] else: name, equals, value = runshared.partition('=') - cmd.library_dirs = value.split(os.pathsep) + cmd.library_dirs = [d for d in value.split(os.pathsep) if d] diff --git a/Lib/distutils/tests/test_archive_util.py b/Lib/distutils/tests/test_archive_util.py index 6b42c5a213a5..02fa1e27a47f 100644 --- a/Lib/distutils/tests/test_archive_util.py +++ b/Lib/distutils/tests/test_archive_util.py @@ -13,7 +13,7 @@ ARCHIVE_FORMATS) from distutils.spawn import find_executable, spawn from distutils.tests import support -from test.support import check_warnings, run_unittest, patch +from test.support import check_warnings, run_unittest, patch, change_cwd try: import grp @@ -34,6 +34,16 @@ except ImportError: ZLIB_SUPPORT = False +try: + import bz2 +except ImportError: + bz2 = None + +try: + import lzma +except ImportError: + lzma = None + def can_fs_encode(filename): """ Return True if the filename can be saved in the file system. @@ -52,19 +62,36 @@ class ArchiveUtilTestCase(support.TempdirManager, unittest.TestCase): @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_make_tarball(self): - self._make_tarball('archive') + def test_make_tarball(self, name='archive'): + # creating something to tar + tmpdir = self._create_files() + self._make_tarball(tmpdir, name, '.tar.gz') + # trying an uncompressed one + self._make_tarball(tmpdir, name, '.tar', compress=None) @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') + def test_make_tarball_gzip(self): + tmpdir = self._create_files() + self._make_tarball(tmpdir, 'archive', '.tar.gz', compress='gzip') + + @unittest.skipUnless(bz2, 'Need bz2 support to run') + def test_make_tarball_bzip2(self): + tmpdir = self._create_files() + self._make_tarball(tmpdir, 'archive', '.tar.bz2', compress='bzip2') + + @unittest.skipUnless(lzma, 'Need lzma support to run') + def test_make_tarball_xz(self): + tmpdir = self._create_files() + self._make_tarball(tmpdir, 'archive', '.tar.xz', compress='xz') + @unittest.skipUnless(can_fs_encode('årchiv'), 'File system cannot handle this filename') def test_make_tarball_latin1(self): """ Mirror test_make_tarball, except filename contains latin characters. """ - self._make_tarball('årchiv') # note this isn't a real word + self.test_make_tarball('årchiv') # note this isn't a real word - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') @unittest.skipUnless(can_fs_encode('のアーカイブ'), 'File system cannot handle this filename') def test_make_tarball_extended(self): @@ -72,16 +99,9 @@ def test_make_tarball_extended(self): Mirror test_make_tarball, except filename contains extended characters outside the latin charset. """ - self._make_tarball('のアーカイブ') # japanese for archive - - def _make_tarball(self, target_name): - # creating something to tar - tmpdir = self.mkdtemp() - self.write_file([tmpdir, 'file1'], 'xxx') - self.write_file([tmpdir, 'file2'], 'xxx') - os.mkdir(os.path.join(tmpdir, 'sub')) - self.write_file([tmpdir, 'sub', 'file3'], 'xxx') + self.test_make_tarball('のアーカイブ') # japanese for archive + def _make_tarball(self, tmpdir, target_name, suffix, **kwargs): tmpdir2 = self.mkdtemp() unittest.skipUnless(splitdrive(tmpdir)[0] == splitdrive(tmpdir2)[0], "source and target should be on same drive") @@ -89,27 +109,13 @@ def _make_tarball(self, target_name): base_name = os.path.join(tmpdir2, target_name) # working with relative paths to avoid tar warnings - old_dir = os.getcwd() - os.chdir(tmpdir) - try: - make_tarball(splitdrive(base_name)[1], '.') - finally: - os.chdir(old_dir) + with change_cwd(tmpdir): + make_tarball(splitdrive(base_name)[1], 'dist', **kwargs) # check if the compressed tarball was created - tarball = base_name + '.tar.gz' - self.assertTrue(os.path.exists(tarball)) - - # trying an uncompressed one - base_name = os.path.join(tmpdir2, target_name) - old_dir = os.getcwd() - os.chdir(tmpdir) - try: - make_tarball(splitdrive(base_name)[1], '.', compress=None) - finally: - os.chdir(old_dir) - tarball = base_name + '.tar' + tarball = base_name + suffix self.assertTrue(os.path.exists(tarball)) + self.assertEqual(self._tarinfo(tarball), self._created_files) def _tarinfo(self, path): tar = tarfile.open(path) @@ -120,6 +126,9 @@ def _tarinfo(self, path): finally: tar.close() + _created_files = ('dist', 'dist/file1', 'dist/file2', + 'dist/sub', 'dist/sub/file3', 'dist/sub2') + def _create_files(self): # creating something to tar tmpdir = self.mkdtemp() @@ -130,15 +139,15 @@ def _create_files(self): os.mkdir(os.path.join(dist, 'sub')) self.write_file([dist, 'sub', 'file3'], 'xxx') os.mkdir(os.path.join(dist, 'sub2')) - tmpdir2 = self.mkdtemp() - base_name = os.path.join(tmpdir2, 'archive') - return tmpdir, tmpdir2, base_name + return tmpdir @unittest.skipUnless(find_executable('tar') and find_executable('gzip') and ZLIB_SUPPORT, 'Need the tar, gzip and zlib command to run') def test_tarfile_vs_tar(self): - tmpdir, tmpdir2, base_name = self._create_files() + tmpdir = self._create_files() + tmpdir2 = self.mkdtemp() + base_name = os.path.join(tmpdir2, 'archive') old_dir = os.getcwd() os.chdir(tmpdir) try: @@ -164,7 +173,8 @@ def test_tarfile_vs_tar(self): self.assertTrue(os.path.exists(tarball2)) # let's compare both tarballs - self.assertEqual(self._tarinfo(tarball), self._tarinfo(tarball2)) + self.assertEqual(self._tarinfo(tarball), self._created_files) + self.assertEqual(self._tarinfo(tarball2), self._created_files) # trying an uncompressed one base_name = os.path.join(tmpdir2, 'archive') @@ -191,7 +201,8 @@ def test_tarfile_vs_tar(self): @unittest.skipUnless(find_executable('compress'), 'The compress program is required') def test_compress_deprecated(self): - tmpdir, tmpdir2, base_name = self._create_files() + tmpdir = self._create_files() + base_name = os.path.join(self.mkdtemp(), 'archive') # using compress and testing the PendingDeprecationWarning old_dir = os.getcwd() @@ -224,17 +235,17 @@ def test_compress_deprecated(self): 'Need zip and zlib support to run') def test_make_zipfile(self): # creating something to tar - tmpdir = self.mkdtemp() - self.write_file([tmpdir, 'file1'], 'xxx') - self.write_file([tmpdir, 'file2'], 'xxx') - - tmpdir2 = self.mkdtemp() - base_name = os.path.join(tmpdir2, 'archive') - make_zipfile(base_name, tmpdir) + tmpdir = self._create_files() + base_name = os.path.join(self.mkdtemp(), 'archive') + with change_cwd(tmpdir): + make_zipfile(base_name, 'dist') # check if the compressed tarball was created tarball = base_name + '.zip' self.assertTrue(os.path.exists(tarball)) + with zipfile.ZipFile(tarball) as zf: + self.assertEqual(sorted(zf.namelist()), + ['dist/file1', 'dist/file2', 'dist/sub/file3']) @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run') def test_make_zipfile_no_zlib(self): @@ -250,18 +261,24 @@ def fake_zipfile(*a, **kw): patch(self, archive_util.zipfile, 'ZipFile', fake_zipfile) # create something to tar and compress - tmpdir, tmpdir2, base_name = self._create_files() - make_zipfile(base_name, tmpdir) + tmpdir = self._create_files() + base_name = os.path.join(self.mkdtemp(), 'archive') + with change_cwd(tmpdir): + make_zipfile(base_name, 'dist') tarball = base_name + '.zip' self.assertEqual(called, [((tarball, "w"), {'compression': zipfile.ZIP_STORED})]) self.assertTrue(os.path.exists(tarball)) + with zipfile.ZipFile(tarball) as zf: + self.assertEqual(sorted(zf.namelist()), + ['dist/file1', 'dist/file2', 'dist/sub/file3']) def test_check_archive_formats(self): self.assertEqual(check_archive_formats(['gztar', 'xxx', 'zip']), 'xxx') - self.assertEqual(check_archive_formats(['gztar', 'zip']), None) + self.assertIsNone(check_archive_formats(['gztar', 'bztar', 'xztar', + 'ztar', 'tar', 'zip'])) def test_make_archive(self): tmpdir = self.mkdtemp() @@ -282,6 +299,41 @@ def _breaks(*args, **kw): finally: del ARCHIVE_FORMATS['xxx'] + def test_make_archive_tar(self): + base_dir = self._create_files() + base_name = os.path.join(self.mkdtemp() , 'archive') + res = make_archive(base_name, 'tar', base_dir, 'dist') + self.assertTrue(os.path.exists(res)) + self.assertEqual(os.path.basename(res), 'archive.tar') + self.assertEqual(self._tarinfo(res), self._created_files) + + @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') + def test_make_archive_gztar(self): + base_dir = self._create_files() + base_name = os.path.join(self.mkdtemp() , 'archive') + res = make_archive(base_name, 'gztar', base_dir, 'dist') + self.assertTrue(os.path.exists(res)) + self.assertEqual(os.path.basename(res), 'archive.tar.gz') + self.assertEqual(self._tarinfo(res), self._created_files) + + @unittest.skipUnless(bz2, 'Need bz2 support to run') + def test_make_archive_bztar(self): + base_dir = self._create_files() + base_name = os.path.join(self.mkdtemp() , 'archive') + res = make_archive(base_name, 'bztar', base_dir, 'dist') + self.assertTrue(os.path.exists(res)) + self.assertEqual(os.path.basename(res), 'archive.tar.bz2') + self.assertEqual(self._tarinfo(res), self._created_files) + + @unittest.skipUnless(lzma, 'Need xz support to run') + def test_make_archive_xztar(self): + base_dir = self._create_files() + base_name = os.path.join(self.mkdtemp() , 'archive') + res = make_archive(base_name, 'xztar', base_dir, 'dist') + self.assertTrue(os.path.exists(res)) + self.assertEqual(os.path.basename(res), 'archive.tar.xz') + self.assertEqual(self._tarinfo(res), self._created_files) + def test_make_archive_owner_group(self): # testing make_archive with owner and group, with various combinations # this works even if there's not gid/uid support @@ -291,7 +343,8 @@ def test_make_archive_owner_group(self): else: group = owner = 'root' - base_dir, root_dir, base_name = self._create_files() + base_dir = self._create_files() + root_dir = self.mkdtemp() base_name = os.path.join(self.mkdtemp() , 'archive') res = make_archive(base_name, 'zip', root_dir, base_dir, owner=owner, group=group) @@ -308,10 +361,11 @@ def test_make_archive_owner_group(self): owner='kjhkjhkjg', group='oihohoh') self.assertTrue(os.path.exists(res)) - @unittest.skipUnless(zlib, "Requires zlib") + @unittest.skipUnless(ZLIB_SUPPORT, "Requires zlib") @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support") def test_tarfile_root_owner(self): - tmpdir, tmpdir2, base_name = self._create_files() + tmpdir = self._create_files() + base_name = os.path.join(self.mkdtemp(), 'archive') old_dir = os.getcwd() os.chdir(tmpdir) group = grp.getgrgid(0)[0] diff --git a/Lib/distutils/tests/test_bdist.py b/Lib/distutils/tests/test_bdist.py index 503a6e857dfc..f762f5d98730 100644 --- a/Lib/distutils/tests/test_bdist.py +++ b/Lib/distutils/tests/test_bdist.py @@ -21,7 +21,7 @@ def test_formats(self): # what formats does bdist offer? formats = ['bztar', 'gztar', 'msi', 'rpm', 'tar', - 'wininst', 'zip', 'ztar'] + 'wininst', 'xztar', 'zip', 'ztar'] found = sorted(cmd.format_command) self.assertEqual(found, formats) diff --git a/Lib/distutils/tests/test_bdist_rpm.py b/Lib/distutils/tests/test_bdist_rpm.py index aa1445d10aa5..25c14abd322c 100644 --- a/Lib/distutils/tests/test_bdist_rpm.py +++ b/Lib/distutils/tests/test_bdist_rpm.py @@ -24,6 +24,7 @@ """ class BuildRpmTestCase(support.TempdirManager, + support.EnvironGuard, support.LoggingSilencer, unittest.TestCase): @@ -43,20 +44,18 @@ def tearDown(self): sys.argv[:] = self.old_sys_argv[1] super(BuildRpmTestCase, self).tearDown() + # XXX I am unable yet to make this test work without + # spurious sdtout/stderr output under Mac OS X + @unittest.skipUnless(sys.platform.startswith('linux'), + 'spurious sdtout/stderr output under Mac OS X') + @unittest.skipIf(find_executable('rpm') is None, + 'the rpm command is not found') + @unittest.skipIf(find_executable('rpmbuild') is None, + 'the rpmbuild command is not found') def test_quiet(self): - - # XXX I am unable yet to make this test work without - # spurious sdtout/stderr output under Mac OS X - if not sys.platform.startswith('linux'): - return - - # this test will run only if the rpm commands are found - if (find_executable('rpm') is None or - find_executable('rpmbuild') is None): - return - # let's create a package tmp_dir = self.mkdtemp() + os.environ['HOME'] = tmp_dir # to confine dir '.rpmdb' creation pkg_dir = os.path.join(tmp_dir, 'foo') os.mkdir(pkg_dir) self.write_file((pkg_dir, 'setup.py'), SETUP_PY) @@ -87,21 +86,19 @@ def test_quiet(self): self.assertIn(('bdist_rpm', 'any', 'dist/foo-0.1-1.src.rpm'), dist.dist_files) self.assertIn(('bdist_rpm', 'any', 'dist/foo-0.1-1.noarch.rpm'), dist.dist_files) + # XXX I am unable yet to make this test work without + # spurious sdtout/stderr output under Mac OS X + @unittest.skipUnless(sys.platform.startswith('linux'), + 'spurious sdtout/stderr output under Mac OS X') + # http://bugs.python.org/issue1533164 + @unittest.skipIf(find_executable('rpm') is None, + 'the rpm command is not found') + @unittest.skipIf(find_executable('rpmbuild') is None, + 'the rpmbuild command is not found') def test_no_optimize_flag(self): - - # XXX I am unable yet to make this test work without - # spurious sdtout/stderr output under Mac OS X - if not sys.platform.startswith('linux'): - return - - # http://bugs.python.org/issue1533164 - # this test will run only if the rpm command is found - if (find_executable('rpm') is None or - find_executable('rpmbuild') is None): - return - # let's create a package that brakes bdist_rpm tmp_dir = self.mkdtemp() + os.environ['HOME'] = tmp_dir # to confine dir '.rpmdb' creation pkg_dir = os.path.join(tmp_dir, 'foo') os.mkdir(pkg_dir) self.write_file((pkg_dir, 'setup.py'), SETUP_PY) diff --git a/Lib/distutils/tests/test_build_clib.py b/Lib/distutils/tests/test_build_clib.py index c2b981f20eb9..acc99e78c18f 100644 --- a/Lib/distutils/tests/test_build_clib.py +++ b/Lib/distutils/tests/test_build_clib.py @@ -102,11 +102,8 @@ def test_finalize_options(self): cmd.distribution.libraries = 'WONTWORK' self.assertRaises(DistutilsSetupError, cmd.finalize_options) + @unittest.skipIf(sys.platform == 'win32', "can't test on Windows") def test_run(self): - # can't test on windows - if sys.platform == 'win32': - return - pkg_dir, dist = self.create_dist() cmd = build_clib(dist) @@ -131,7 +128,7 @@ def test_run(self): if ccmd is None: continue if find_executable(ccmd[0]) is None: - return # can't test + self.skipTest('The %r command is not found' % ccmd[0]) # this should work cmd.run() diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py index 3cfaa2c6928d..366ffbec9f81 100644 --- a/Lib/distutils/tests/test_build_ext.py +++ b/Lib/distutils/tests/test_build_ext.py @@ -31,12 +31,14 @@ def setUp(self): self.tmp_dir = self.mkdtemp() self.sys_path = sys.path, sys.path[:] sys.path.append(self.tmp_dir) - if sys.version > "2.6": - import site - self.old_user_base = site.USER_BASE - site.USER_BASE = self.mkdtemp() - from distutils.command import build_ext - build_ext.USER_BASE = site.USER_BASE + import site + self.old_user_base = site.USER_BASE + site.USER_BASE = self.mkdtemp() + from distutils.command import build_ext + build_ext.USER_BASE = site.USER_BASE + + def build_ext(self, *args, **kwargs): + return build_ext(*args, **kwargs) def test_build_ext(self): global ALREADY_TESTED @@ -45,7 +47,7 @@ def test_build_ext(self): xx_ext = Extension('xx', [xx_c]) dist = Distribution({'name': 'xx', 'ext_modules': [xx_ext]}) dist.package_dir = self.tmp_dir - cmd = build_ext(dist) + cmd = self.build_ext(dist) fixup_build_ext(cmd) cmd.build_lib = self.tmp_dir cmd.build_temp = self.tmp_dir @@ -61,9 +63,9 @@ def test_build_ext(self): sys.stdout = old_stdout if ALREADY_TESTED: - return + self.skipTest('Already tested in %s' % ALREADY_TESTED) else: - ALREADY_TESTED = True + ALREADY_TESTED = type(self).__name__ import xx @@ -84,16 +86,15 @@ def tearDown(self): support.unload('xx') sys.path = self.sys_path[0] sys.path[:] = self.sys_path[1] - if sys.version > "2.6": - import site - site.USER_BASE = self.old_user_base - from distutils.command import build_ext - build_ext.USER_BASE = self.old_user_base + import site + site.USER_BASE = self.old_user_base + from distutils.command import build_ext + build_ext.USER_BASE = self.old_user_base super(BuildExtTestCase, self).tearDown() def test_solaris_enable_shared(self): dist = Distribution({'name': 'xx'}) - cmd = build_ext(dist) + cmd = self.build_ext(dist) old = sys.platform sys.platform = 'sunos' # fooling finalize_options @@ -113,13 +114,9 @@ def test_solaris_enable_shared(self): self.assertGreater(len(cmd.library_dirs), 0) def test_user_site(self): - # site.USER_SITE was introduced in 2.6 - if sys.version < '2.6': - return - import site dist = Distribution({'name': 'xx'}) - cmd = build_ext(dist) + cmd = self.build_ext(dist) # making sure the user option is there options = [name for name, short, lable in @@ -150,14 +147,14 @@ def test_optional_extension(self): # with the optional argument. modules = [Extension('foo', ['xxx'], optional=False)] dist = Distribution({'name': 'xx', 'ext_modules': modules}) - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.ensure_finalized() self.assertRaises((UnknownFileError, CompileError), cmd.run) # should raise an error modules = [Extension('foo', ['xxx'], optional=True)] dist = Distribution({'name': 'xx', 'ext_modules': modules}) - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.ensure_finalized() cmd.run() # should pass @@ -166,7 +163,7 @@ def test_finalize_options(self): # etc.) are in the include search path. modules = [Extension('foo', ['xxx'], optional=False)] dist = Distribution({'name': 'xx', 'ext_modules': modules}) - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.finalize_options() from distutils import sysconfig @@ -178,14 +175,14 @@ def test_finalize_options(self): # make sure cmd.libraries is turned into a list # if it's a string - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.libraries = 'my_lib, other_lib lastlib' cmd.finalize_options() self.assertEqual(cmd.libraries, ['my_lib', 'other_lib', 'lastlib']) # make sure cmd.library_dirs is turned into a list # if it's a string - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.library_dirs = 'my_lib_dir%sother_lib_dir' % os.pathsep cmd.finalize_options() self.assertIn('my_lib_dir', cmd.library_dirs) @@ -193,7 +190,7 @@ def test_finalize_options(self): # make sure rpath is turned into a list # if it's a string - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.rpath = 'one%stwo' % os.pathsep cmd.finalize_options() self.assertEqual(cmd.rpath, ['one', 'two']) @@ -202,32 +199,32 @@ def test_finalize_options(self): # make sure define is turned into 2-tuples # strings if they are ','-separated strings - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.define = 'one,two' cmd.finalize_options() self.assertEqual(cmd.define, [('one', '1'), ('two', '1')]) # make sure undef is turned into a list of # strings if they are ','-separated strings - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.undef = 'one,two' cmd.finalize_options() self.assertEqual(cmd.undef, ['one', 'two']) # make sure swig_opts is turned into a list - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.swig_opts = None cmd.finalize_options() self.assertEqual(cmd.swig_opts, []) - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.swig_opts = '1 2' cmd.finalize_options() self.assertEqual(cmd.swig_opts, ['1', '2']) def test_check_extensions_list(self): dist = Distribution() - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.finalize_options() #'extensions' option must be a list of Extension instances @@ -276,7 +273,7 @@ def test_check_extensions_list(self): def test_get_source_files(self): modules = [Extension('foo', ['xxx'], optional=False)] dist = Distribution({'name': 'xx', 'ext_modules': modules}) - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.ensure_finalized() self.assertEqual(cmd.get_source_files(), ['xxx']) @@ -285,7 +282,7 @@ def test_compiler_option(self): # should not be overriden by a compiler instance # when the command is run dist = Distribution() - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.compiler = 'unix' cmd.ensure_finalized() cmd.run() @@ -298,7 +295,7 @@ def test_get_outputs(self): ext = Extension('foo', [c_file], optional=False) dist = Distribution({'name': 'xx', 'ext_modules': [ext]}) - cmd = build_ext(dist) + cmd = self.build_ext(dist) fixup_build_ext(cmd) cmd.ensure_finalized() self.assertEqual(len(cmd.get_outputs()), 1) @@ -361,7 +358,7 @@ def test_ext_fullpath(self): #etree_ext = Extension('lxml.etree', [etree_c]) #dist = Distribution({'name': 'lxml', 'ext_modules': [etree_ext]}) dist = Distribution() - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.inplace = 1 cmd.distribution.package_dir = {'': 'src'} cmd.distribution.packages = ['lxml', 'lxml.html'] @@ -448,8 +445,16 @@ def _try_compile_deployment_target(self, operator, target): # get the deployment target that the interpreter was built with target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') - target = tuple(map(int, target.split('.'))) - target = '%02d%01d0' % target + target = tuple(map(int, target.split('.')[0:2])) + # format the target value as defined in the Apple + # Availability Macros. We can't use the macro names since + # at least one value we test with will not exist yet. + if target[1] < 10: + # for 10.1 through 10.9.x -> "10n0" + target = '%02d%01d0' % target + else: + # for 10.10 and beyond -> "10nn00" + target = '%02d%02d00' % target deptarget_ext = Extension( 'deptarget', [deptarget_c], @@ -460,7 +465,7 @@ def _try_compile_deployment_target(self, operator, target): 'ext_modules': [deptarget_ext] }) dist.package_dir = self.tmp_dir - cmd = build_ext(dist) + cmd = self.build_ext(dist) cmd.build_lib = self.tmp_dir cmd.build_temp = self.tmp_dir @@ -479,8 +484,19 @@ def _try_compile_deployment_target(self, operator, target): self.fail("Wrong deployment target during compilation") +class ParallelBuildExtTestCase(BuildExtTestCase): + + def build_ext(self, *args, **kwargs): + build_ext = super().build_ext(*args, **kwargs) + build_ext.parallel = True + return build_ext + + def test_suite(): - return unittest.makeSuite(BuildExtTestCase) + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(BuildExtTestCase)) + suite.addTest(unittest.makeSuite(ParallelBuildExtTestCase)) + return suite if __name__ == '__main__': - support.run_unittest(test_suite()) + support.run_unittest(__name__) diff --git a/Lib/distutils/tests/test_build_py.py b/Lib/distutils/tests/test_build_py.py index c8f6b8991996..18283dc72206 100644 --- a/Lib/distutils/tests/test_build_py.py +++ b/Lib/distutils/tests/test_build_py.py @@ -120,8 +120,8 @@ def test_byte_compile_optimized(self): found = os.listdir(cmd.build_lib) self.assertEqual(sorted(found), ['__pycache__', 'boiledeggs.py']) found = os.listdir(os.path.join(cmd.build_lib, '__pycache__')) - self.assertEqual(sorted(found), - ['boiledeggs.%s.pyo' % sys.implementation.cache_tag]) + expect = 'boiledeggs.{}.opt-1.pyc'.format(sys.implementation.cache_tag) + self.assertEqual(sorted(found), [expect]) def test_dir_in_package_data(self): """ diff --git a/Lib/distutils/tests/test_check.py b/Lib/distutils/tests/test_check.py index 4de64734c4c7..959fa9085cf5 100644 --- a/Lib/distutils/tests/test_check.py +++ b/Lib/distutils/tests/test_check.py @@ -1,4 +1,5 @@ """Tests for distutils.command.check.""" +import textwrap import unittest from test.support import run_unittest @@ -55,9 +56,8 @@ def test_check_metadata(self): cmd = self._run(metadata) self.assertEqual(cmd._warnings, 0) + @unittest.skipUnless(HAS_DOCUTILS, "won't test without docutils") def test_check_document(self): - if not HAS_DOCUTILS: # won't test without docutils - return pkg_info, dist = self.create_dist() cmd = check(dist) @@ -71,9 +71,8 @@ def test_check_document(self): msgs = cmd._check_rst_data(rest) self.assertEqual(len(msgs), 0) + @unittest.skipUnless(HAS_DOCUTILS, "won't test without docutils") def test_check_restructuredtext(self): - if not HAS_DOCUTILS: # won't test without docutils - return # let's see if it detects broken rest in long_description broken_rest = 'title\n===\n\ntest' pkg_info, dist = self.create_dist(long_description=broken_rest) @@ -94,6 +93,36 @@ def test_check_restructuredtext(self): cmd = self._run(metadata, strict=1, restructuredtext=1) self.assertEqual(cmd._warnings, 0) + @unittest.skipUnless(HAS_DOCUTILS, "won't test without docutils") + def test_check_restructuredtext_with_syntax_highlight(self): + # Don't fail if there is a `code` or `code-block` directive + + example_rst_docs = [] + example_rst_docs.append(textwrap.dedent("""\ + Here's some code: + + .. code:: python + + def foo(): + pass + """)) + example_rst_docs.append(textwrap.dedent("""\ + Here's some code: + + .. code-block:: python + + def foo(): + pass + """)) + + for rest_with_code in example_rst_docs: + pkg_info, dist = self.create_dist(long_description=rest_with_code) + cmd = check(dist) + cmd.check_restructuredtext() + self.assertEqual(cmd._warnings, 0) + msgs = cmd._check_rst_data(rest_with_code) + self.assertEqual(len(msgs), 0) + def test_check_all(self): metadata = {'url': 'xxx', 'author': 'xxx'} diff --git a/Lib/distutils/tests/test_config_cmd.py b/Lib/distutils/tests/test_config_cmd.py index 79894c78d35a..0c8dbd8269be 100644 --- a/Lib/distutils/tests/test_config_cmd.py +++ b/Lib/distutils/tests/test_config_cmd.py @@ -37,9 +37,8 @@ def test_dump_file(self): dump_file(this_file, 'I am the header') self.assertEqual(len(self._logs), numlines+1) + @unittest.skipIf(sys.platform == 'win32', "can't test on Windows") def test_search_cpp(self): - if sys.platform == 'win32': - return pkg_dir, dist = self.create_dist() cmd = config(dist) diff --git a/Lib/distutils/tests/test_core.py b/Lib/distutils/tests/test_core.py index 41321f7db4ee..57856f19b654 100644 --- a/Lib/distutils/tests/test_core.py +++ b/Lib/distutils/tests/test_core.py @@ -28,6 +28,21 @@ setup() """ +setup_does_nothing = """\ +from distutils.core import setup +setup() +""" + + +setup_defines_subclass = """\ +from distutils.core import setup +from distutils.command.install import install as _install + +class install(_install): + sub_commands = _install.sub_commands + ['cmd'] + +setup(cmdclass={'install': install}) +""" class CoreTestCase(support.EnvironGuard, unittest.TestCase): @@ -65,6 +80,21 @@ def test_run_setup_provides_file(self): distutils.core.run_setup( self.write_setup(setup_using___file__)) + def test_run_setup_preserves_sys_argv(self): + # Make sure run_setup does not clobber sys.argv + argv_copy = sys.argv.copy() + distutils.core.run_setup( + self.write_setup(setup_does_nothing)) + self.assertEqual(sys.argv, argv_copy) + + def test_run_setup_defines_subclass(self): + # Make sure the script can use __file__; if that's missing, the test + # setup.py script will raise NameError. + dist = distutils.core.run_setup( + self.write_setup(setup_defines_subclass)) + install = dist.get_command_obj('install') + self.assertIn('cmd', install.sub_commands) + def test_run_setup_uses_current_dir(self): # This tests that the setup script is run with the current directory # as its own current directory; this was temporarily broken by a diff --git a/Lib/distutils/tests/test_dir_util.py b/Lib/distutils/tests/test_dir_util.py index 1589f1297db2..d436cf831917 100644 --- a/Lib/distutils/tests/test_dir_util.py +++ b/Lib/distutils/tests/test_dir_util.py @@ -2,9 +2,10 @@ import unittest import os import stat -import shutil import sys +from unittest.mock import patch +from distutils import dir_util, errors from distutils.dir_util import (mkpath, remove_tree, create_tree, copy_tree, ensure_relative) @@ -12,6 +13,7 @@ from distutils.tests import support from test.support import run_unittest + class DirUtilTestCase(support.TempdirManager, unittest.TestCase): def _log(self, msg, *args): @@ -52,7 +54,7 @@ def test_mkpath_remove_tree_verbosity(self): self.assertEqual(self._logs, wanted) @unittest.skipIf(sys.platform.startswith('win'), - "This test is only appropriate for POSIX-like systems.") + "This test is only appropriate for POSIX-like systems.") def test_mkpath_with_custom_mode(self): # Get and set the current umask value for testing mode bits. umask = os.umask(0o002) @@ -120,6 +122,16 @@ def test_ensure_relative(self): self.assertEqual(ensure_relative('c:\\home\\foo'), 'c:home\\foo') self.assertEqual(ensure_relative('home\\foo'), 'home\\foo') + def test_copy_tree_exception_in_listdir(self): + """ + An exception in listdir should raise a DistutilsFileError + """ + with patch("os.listdir", side_effect=OSError()), \ + self.assertRaises(errors.DistutilsFileError): + src = self.tempdirs[-1] + dir_util.copy_tree(src, None) + + def test_suite(): return unittest.makeSuite(DirUtilTestCase) diff --git a/Lib/distutils/tests/test_file_util.py b/Lib/distutils/tests/test_file_util.py index 3c3e3dcb3bff..a6d04f065d98 100644 --- a/Lib/distutils/tests/test_file_util.py +++ b/Lib/distutils/tests/test_file_util.py @@ -2,10 +2,13 @@ import unittest import os import shutil +import errno +from unittest.mock import patch -from distutils.file_util import move_file +from distutils.file_util import move_file, copy_file from distutils import log from distutils.tests import support +from distutils.errors import DistutilsFileError from test.support import run_unittest class FileUtilTestCase(support.TempdirManager, unittest.TestCase): @@ -58,6 +61,52 @@ def test_move_file_verbosity(self): wanted = ['moving %s -> %s' % (self.source, self.target_dir)] self.assertEqual(self._logs, wanted) + def test_move_file_exception_unpacking_rename(self): + # see issue 22182 + with patch("os.rename", side_effect=OSError("wrong", 1)), \ + self.assertRaises(DistutilsFileError): + with open(self.source, 'w') as fobj: + fobj.write('spam eggs') + move_file(self.source, self.target, verbose=0) + + def test_move_file_exception_unpacking_unlink(self): + # see issue 22182 + with patch("os.rename", side_effect=OSError(errno.EXDEV, "wrong")), \ + patch("os.unlink", side_effect=OSError("wrong", 1)), \ + self.assertRaises(DistutilsFileError): + with open(self.source, 'w') as fobj: + fobj.write('spam eggs') + move_file(self.source, self.target, verbose=0) + + def test_copy_file_hard_link(self): + with open(self.source, 'w') as f: + f.write('some content') + st = os.stat(self.source) + copy_file(self.source, self.target, link='hard') + st2 = os.stat(self.source) + st3 = os.stat(self.target) + self.assertTrue(os.path.samestat(st, st2), (st, st2)) + self.assertTrue(os.path.samestat(st2, st3), (st2, st3)) + with open(self.source, 'r') as f: + self.assertEqual(f.read(), 'some content') + + def test_copy_file_hard_link_failure(self): + # If hard linking fails, copy_file() falls back on copying file + # (some special filesystems don't support hard linking even under + # Unix, see issue #8876). + with open(self.source, 'w') as f: + f.write('some content') + st = os.stat(self.source) + with patch("os.link", side_effect=OSError(0, "linking unsupported")): + copy_file(self.source, self.target, link='hard') + st2 = os.stat(self.source) + st3 = os.stat(self.target) + self.assertTrue(os.path.samestat(st, st2), (st, st2)) + self.assertFalse(os.path.samestat(st2, st3), (st2, st3)) + for fn in (self.source, self.target): + with open(fn, 'r') as f: + self.assertEqual(f.read(), 'some content') + def test_suite(): return unittest.makeSuite(FileUtilTestCase) diff --git a/Lib/distutils/tests/test_install.py b/Lib/distutils/tests/test_install.py index 18e1e575054f..9313330e2b72 100644 --- a/Lib/distutils/tests/test_install.py +++ b/Lib/distutils/tests/test_install.py @@ -20,8 +20,6 @@ def _make_ext_name(modname): - if os.name == 'nt' and sys.executable.endswith('_d.exe'): - modname += '_d' return modname + sysconfig.get_config_var('EXT_SUFFIX') diff --git a/Lib/distutils/tests/test_install_lib.py b/Lib/distutils/tests/test_install_lib.py index 40dd1a95a65e..5378aa82495b 100644 --- a/Lib/distutils/tests/test_install_lib.py +++ b/Lib/distutils/tests/test_install_lib.py @@ -44,12 +44,11 @@ def test_byte_compile(self): f = os.path.join(project_dir, 'foo.py') self.write_file(f, '# python file') cmd.byte_compile([f]) - pyc_file = importlib.util.cache_from_source('foo.py', - debug_override=True) - pyo_file = importlib.util.cache_from_source('foo.py', - debug_override=False) + pyc_file = importlib.util.cache_from_source('foo.py', optimization='') + pyc_opt_file = importlib.util.cache_from_source('foo.py', + optimization=cmd.optimize) self.assertTrue(os.path.exists(pyc_file)) - self.assertTrue(os.path.exists(pyo_file)) + self.assertTrue(os.path.exists(pyc_opt_file)) def test_get_outputs(self): project_dir, dist = self.create_dist() @@ -66,8 +65,8 @@ def test_get_outputs(self): cmd.distribution.packages = ['spam'] cmd.distribution.script_name = 'setup.py' - # get_outputs should return 4 elements: spam/__init__.py, .pyc and - # .pyo, foo.import-tag-abiflags.so / foo.pyd + # get_outputs should return 4 elements: spam/__init__.py and .pyc, + # foo.import-tag-abiflags.so / foo.pyd outputs = cmd.get_outputs() self.assertEqual(len(outputs), 4, outputs) diff --git a/Lib/distutils/tests/test_msvccompiler.py b/Lib/distutils/tests/test_msvccompiler.py new file mode 100644 index 000000000000..c4d911ff8380 --- /dev/null +++ b/Lib/distutils/tests/test_msvccompiler.py @@ -0,0 +1,90 @@ +"""Tests for distutils._msvccompiler.""" +import sys +import unittest +import os + +from distutils.errors import DistutilsPlatformError +from distutils.tests import support +from test.support import run_unittest + + +SKIP_MESSAGE = (None if sys.platform == "win32" else + "These tests are only for win32") + +@unittest.skipUnless(SKIP_MESSAGE is None, SKIP_MESSAGE) +class msvccompilerTestCase(support.TempdirManager, + unittest.TestCase): + + def test_no_compiler(self): + import distutils._msvccompiler as _msvccompiler + # makes sure query_vcvarsall raises + # a DistutilsPlatformError if the compiler + # is not found + def _find_vcvarsall(plat_spec): + return None, None + + old_find_vcvarsall = _msvccompiler._find_vcvarsall + _msvccompiler._find_vcvarsall = _find_vcvarsall + try: + self.assertRaises(DistutilsPlatformError, + _msvccompiler._get_vc_env, + 'wont find this version') + finally: + _msvccompiler._find_vcvarsall = old_find_vcvarsall + + def test_compiler_options(self): + import distutils._msvccompiler as _msvccompiler + # suppress path to vcruntime from _find_vcvarsall to + # check that /MT is added to compile options + old_find_vcvarsall = _msvccompiler._find_vcvarsall + def _find_vcvarsall(plat_spec): + return old_find_vcvarsall(plat_spec)[0], None + _msvccompiler._find_vcvarsall = _find_vcvarsall + try: + compiler = _msvccompiler.MSVCCompiler() + compiler.initialize() + + self.assertIn('/MT', compiler.compile_options) + self.assertNotIn('/MD', compiler.compile_options) + finally: + _msvccompiler._find_vcvarsall = old_find_vcvarsall + + def test_vcruntime_copy(self): + import distutils._msvccompiler as _msvccompiler + # force path to a known file - it doesn't matter + # what we copy as long as its name is not in + # _msvccompiler._BUNDLED_DLLS + old_find_vcvarsall = _msvccompiler._find_vcvarsall + def _find_vcvarsall(plat_spec): + return old_find_vcvarsall(plat_spec)[0], __file__ + _msvccompiler._find_vcvarsall = _find_vcvarsall + try: + tempdir = self.mkdtemp() + compiler = _msvccompiler.MSVCCompiler() + compiler.initialize() + compiler._copy_vcruntime(tempdir) + + self.assertTrue(os.path.isfile(os.path.join( + tempdir, os.path.basename(__file__)))) + finally: + _msvccompiler._find_vcvarsall = old_find_vcvarsall + + def test_vcruntime_skip_copy(self): + import distutils._msvccompiler as _msvccompiler + + tempdir = self.mkdtemp() + compiler = _msvccompiler.MSVCCompiler() + compiler.initialize() + dll = compiler._vcruntime_redist + self.assertTrue(os.path.isfile(dll)) + + compiler._copy_vcruntime(tempdir) + + self.assertFalse(os.path.isfile(os.path.join( + tempdir, os.path.basename(dll)))) + +def test_suite(): + return unittest.makeSuite(msvccompilerTestCase) + +if __name__ == "__main__": + run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_register.py b/Lib/distutils/tests/test_register.py index f4efa13d789d..6180133994f8 100644 --- a/Lib/distutils/tests/test_register.py +++ b/Lib/distutils/tests/test_register.py @@ -10,6 +10,7 @@ from distutils.command import register as register_module from distutils.command.register import register from distutils.errors import DistutilsSetupError +from distutils.log import INFO from distutils.tests.test_config import PyPIRCCommandTestCase @@ -58,12 +59,18 @@ def __init__(self): def __call__(self, *args): return self - def open(self, req): + def open(self, req, data=None, timeout=None): self.reqs.append(req) return self def read(self): - return 'xxx' + return b'xxx' + + def getheader(self, name, default=None): + return { + 'content-type': 'text/plain; charset=utf-8', + }.get(name.lower(), default) + class RegisterTestCase(PyPIRCCommandTestCase): @@ -74,11 +81,13 @@ def setUp(self): def _getpass(prompt): return 'password' getpass.getpass = _getpass + urllib.request._opener = None self.old_opener = urllib.request.build_opener self.conn = urllib.request.build_opener = FakeOpener() def tearDown(self): getpass.getpass = self._old_getpass + urllib.request._opener = None urllib.request.build_opener = self.old_opener super(RegisterTestCase, self).tearDown() @@ -285,6 +294,14 @@ def test_check_metadata_deprecated(self): cmd.check_metadata() self.assertEqual(len(w.warnings), 1) + def test_list_classifiers(self): + cmd = self._get_cmd() + cmd.list_classifiers = 1 + cmd.run() + results = self.get_logs(INFO) + self.assertEqual(results, ['running check', 'xxx']) + + def test_suite(): return unittest.makeSuite(RegisterTestCase) diff --git a/Lib/distutils/tests/test_sdist.py b/Lib/distutils/tests/test_sdist.py index 164586b7846c..5a04e0ddd0fd 100644 --- a/Lib/distutils/tests/test_sdist.py +++ b/Lib/distutils/tests/test_sdist.py @@ -131,13 +131,11 @@ def test_prune_file_list(self): self.assertEqual(len(content), 4) @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') + @unittest.skipIf(find_executable('tar') is None, + "The tar command is not found") + @unittest.skipIf(find_executable('gzip') is None, + "The gzip command is not found") def test_make_distribution(self): - - # check if tar and gzip are installed - if (find_executable('tar') is None or - find_executable('gzip') is None): - return - # now building a sdist dist, cmd = self.get_cmd() @@ -431,15 +429,13 @@ def test_manual_manifest(self): self.assertEqual(sorted(filenames), ['fake-1.0', 'fake-1.0/PKG-INFO', 'fake-1.0/README.manual']) - @unittest.skipUnless(zlib, "requires zlib") + @unittest.skipUnless(ZLIB_SUPPORT, "requires zlib") @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support") + @unittest.skipIf(find_executable('tar') is None, + "The tar command is not found") + @unittest.skipIf(find_executable('gzip') is None, + "The gzip command is not found") def test_make_distribution_owner_group(self): - - # check if tar and gzip are installed - if (find_executable('tar') is None or - find_executable('gzip') is None): - return - # now building a sdist dist, cmd = self.get_cmd() diff --git a/Lib/distutils/tests/test_sysconfig.py b/Lib/distutils/tests/test_sysconfig.py index b5fdc98dc97f..fc4d1de185cf 100644 --- a/Lib/distutils/tests/test_sysconfig.py +++ b/Lib/distutils/tests/test_sysconfig.py @@ -1,6 +1,9 @@ """Tests for distutils.sysconfig.""" import os import shutil +import subprocess +import sys +import textwrap import unittest from distutils import sysconfig @@ -80,12 +83,9 @@ def test_srcdir_independent_of_cwd(self): os.chdir(cwd) self.assertEqual(srcdir, srcdir2) + @unittest.skipUnless(get_default_compiler() == 'unix', + 'not testing if default compiler is not unix') def test_customize_compiler(self): - - # not testing if default compiler is not unix - if get_default_compiler() != 'unix': - return - os.environ['AR'] = 'my_ar' os.environ['ARFLAGS'] = '-arflags' @@ -151,7 +151,7 @@ def test_sysconfig_compiler_vars(self): import sysconfig as global_sysconfig if sysconfig.get_config_var('CUSTOMIZED_OSX_COMPILER'): - return + self.skipTest('compiler flags customized') self.assertEqual(global_sysconfig.get_config_var('LDSHARED'), sysconfig.get_config_var('LDSHARED')) self.assertEqual(global_sysconfig.get_config_var('CC'), @@ -177,6 +177,25 @@ def test_SO_in_vars(self): self.assertIsNotNone(vars['SO']) self.assertEqual(vars['SO'], vars['EXT_SUFFIX']) + def test_customize_compiler_before_get_config_vars(self): + # Issue #21923: test that a Distribution compiler + # instance can be called without an explicit call to + # get_config_vars(). + with open(TESTFN, 'w') as f: + f.writelines(textwrap.dedent('''\ + from distutils.core import Distribution + config = Distribution().get_command_obj('config') + # try_compile may pass or it may fail if no compiler + # is found but it should not raise an exception. + rc = config.try_compile('int x;') + ''')) + p = subprocess.Popen([str(sys.executable), TESTFN], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + universal_newlines=True) + outs, errs = p.communicate() + self.assertEqual(0, p.returncode, "Subprocess failed: " + outs) + def test_suite(): suite = unittest.TestSuite() diff --git a/Lib/distutils/tests/test_unixccompiler.py b/Lib/distutils/tests/test_unixccompiler.py index a5a63fdde336..3d14e12aa9f6 100644 --- a/Lib/distutils/tests/test_unixccompiler.py +++ b/Lib/distutils/tests/test_unixccompiler.py @@ -21,12 +21,8 @@ def tearDown(self): sys.platform = self._backup_platform sysconfig.get_config_var = self._backup_get_config_var + @unittest.skipIf(sys.platform == 'win32', "can't test on Windows") def test_runtime_libdir_option(self): - - # not tested under windows - if sys.platform == 'win32': - return - # Issue#5900 # # Ensure RUNPATH is added to extension modules with RPATH if diff --git a/Lib/distutils/tests/test_upload.py b/Lib/distutils/tests/test_upload.py index 1fcba889b29c..dccaf77e3e18 100644 --- a/Lib/distutils/tests/test_upload.py +++ b/Lib/distutils/tests/test_upload.py @@ -6,6 +6,8 @@ from distutils.command import upload as upload_mod from distutils.command.upload import upload from distutils.core import Distribution +from distutils.errors import DistutilsError +from distutils.log import INFO from distutils.tests.test_config import PYPIRC, PyPIRCCommandTestCase @@ -40,16 +42,25 @@ class FakeOpen(object): - def __init__(self, url): + def __init__(self, url, msg=None, code=None): self.url = url if not isinstance(url, str): self.req = url else: self.req = None - self.msg = 'OK' + self.msg = msg or 'OK' + self.code = code or 200 + + def getheader(self, name, default=None): + return { + 'content-type': 'text/plain; charset=utf-8', + }.get(name.lower(), default) + + def read(self): + return b'xyzzy' def getcode(self): - return 200 + return self.code class uploadTestCase(PyPIRCCommandTestCase): @@ -59,13 +70,15 @@ def setUp(self): self.old_open = upload_mod.urlopen upload_mod.urlopen = self._urlopen self.last_open = None + self.next_msg = None + self.next_code = None def tearDown(self): upload_mod.urlopen = self.old_open super(uploadTestCase, self).tearDown() def _urlopen(self, url): - self.last_open = FakeOpen(url) + self.last_open = FakeOpen(url, msg=self.next_msg, code=self.next_code) return self.last_open def test_finalize_options(self): @@ -108,12 +121,13 @@ def test_upload(self): # lets run it pkg_dir, dist = self.create_dist(dist_files=dist_files) cmd = upload(dist) + cmd.show_response = 1 cmd.ensure_finalized() cmd.run() - # what did we send ? + # what did we send ? headers = dict(self.last_open.req.headers) - self.assertEqual(headers['Content-length'], '2087') + self.assertEqual(headers['Content-length'], '2161') content_type = headers['Content-type'] self.assertTrue(content_type.startswith('multipart/form-data')) self.assertEqual(self.last_open.req.get_method(), 'POST') @@ -121,6 +135,15 @@ def test_upload(self): self.assertEqual(self.last_open.req.get_full_url(), expected_url) self.assertTrue(b'xxx' in self.last_open.req.data) + # The PyPI response body was echoed + results = self.get_logs(INFO) + self.assertIn('xyzzy\n', results[-1]) + + def test_upload_fails(self): + self.next_msg = "Not Found" + self.next_code = 404 + self.assertRaises(DistutilsError, self.test_upload) + def test_suite(): return unittest.makeSuite(uploadTestCase) diff --git a/Lib/distutils/tests/test_util.py b/Lib/distutils/tests/test_util.py index 548865c02b24..4e9d79b7c6cb 100644 --- a/Lib/distutils/tests/test_util.py +++ b/Lib/distutils/tests/test_util.py @@ -8,7 +8,8 @@ from distutils.errors import DistutilsPlatformError, DistutilsByteCompileError from distutils.util import (get_platform, convert_path, change_root, check_environ, split_quoted, strtobool, - rfc822_escape, byte_compile) + rfc822_escape, byte_compile, + grok_environment_error) from distutils import util # used to patch _environ_checked from distutils.sysconfig import get_config_vars from distutils import sysconfig @@ -285,6 +286,13 @@ def test_dont_write_bytecode(self): finally: sys.dont_write_bytecode = old_dont_write_bytecode + def test_grok_environment_error(self): + # test obsolete function to ensure backward compat (#4931) + exc = IOError("Unable to find batch file") + msg = grok_environment_error(exc) + self.assertEqual(msg, "error: Unable to find batch file") + + def test_suite(): return unittest.makeSuite(UtilTestCase) diff --git a/Lib/distutils/text_file.py b/Lib/distutils/text_file.py index 40b8484a685d..478336f0d2b8 100644 --- a/Lib/distutils/text_file.py +++ b/Lib/distutils/text_file.py @@ -118,10 +118,11 @@ def open(self, filename): def close(self): """Close the current file and forget everything we know about it (filename, current line number).""" - self.file.close() + file = self.file self.file = None self.filename = None self.current_line = None + file.close() def gen_error(self, msg, line=None): outmsg = [] diff --git a/Lib/distutils/util.py b/Lib/distutils/util.py index efb3834cf53b..e423325de430 100644 --- a/Lib/distutils/util.py +++ b/Lib/distutils/util.py @@ -207,25 +207,10 @@ def _subst (match, local_vars=local_vars): def grok_environment_error (exc, prefix="error: "): - """Generate a useful error message from an OSError - exception object. Handles Python 1.5.1 and 1.5.2 styles, and - does what it can to deal with exception objects that don't have a - filename (which happens when the error is due to a two-file operation, - such as 'rename()' or 'link()'. Returns the error message as a string - prefixed with 'prefix'. - """ - # check for Python 1.5.2-style {IO,OS}Error exception objects - if hasattr(exc, 'filename') and hasattr(exc, 'strerror'): - if exc.filename: - error = prefix + "%s: %s" % (exc.filename, exc.strerror) - else: - # two-argument functions in posix module don't - # include the filename in the exception object! - error = prefix + "%s" % exc.strerror - else: - error = prefix + str(exc.args[-1]) - - return error + # Function kept for backward compatibility. + # Used to try clever things with EnvironmentErrors, + # but nowadays str(exception) produces good messages. + return prefix + str(exc) # Needed by 'split_quoted()' @@ -337,11 +322,11 @@ def byte_compile (py_files, prefix=None, base_dir=None, verbose=1, dry_run=0, direct=None): - """Byte-compile a collection of Python source files to either .pyc - or .pyo files in a __pycache__ subdirectory. 'py_files' is a list + """Byte-compile a collection of Python source files to .pyc + files in a __pycache__ subdirectory. 'py_files' is a list of files to compile; any files that don't end in ".py" are silently skipped. 'optimize' must be one of the following: - 0 - don't optimize (generate .pyc) + 0 - don't optimize 1 - normal optimization (like "python -O") 2 - extra optimization (like "python -OO") If 'force' is true, all files are recompiled regardless of @@ -453,8 +438,9 @@ def byte_compile (py_files, # cfile - byte-compiled file # dfile - purported source filename (same as 'file' by default) if optimize >= 0: + opt = '' if optimize == 0 else optimize cfile = importlib.util.cache_from_source( - file, debug_override=not optimize) + file, optimization=opt) else: cfile = importlib.util.cache_from_source(file) dfile = file diff --git a/Lib/distutils/version.py b/Lib/distutils/version.py index ebcab84e4e23..af14cc134814 100644 --- a/Lib/distutils/version.py +++ b/Lib/distutils/version.py @@ -48,12 +48,6 @@ def __eq__(self, other): return c return c == 0 - def __ne__(self, other): - c = self._cmp(other) - if c is NotImplemented: - return c - return c != 0 - def __lt__(self, other): c = self._cmp(other) if c is NotImplemented: diff --git a/Lib/doctest.py b/Lib/doctest.py index ee4e0687844a..96ab0c403bcf 100644 --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -318,6 +318,32 @@ def _comment_line(line): else: return '#' +def _strip_exception_details(msg): + # Support for IGNORE_EXCEPTION_DETAIL. + # Get rid of everything except the exception name; in particular, drop + # the possibly dotted module path (if any) and the exception message (if + # any). We assume that a colon is never part of a dotted name, or of an + # exception name. + # E.g., given + # "foo.bar.MyError: la di da" + # return "MyError" + # Or for "abc.def" or "abc.def:\n" return "def". + + start, end = 0, len(msg) + # The exception name must appear on the first line. + i = msg.find("\n") + if i >= 0: + end = i + # retain up to the first colon (if any) + i = msg.find(':', 0, end) + if i >= 0: + end = i + # retain just the exception name + i = msg.rfind('.', 0, end) + if i >= 0: + start = i+1 + return msg[start: end] + class _OutputRedirectingPdb(pdb.Pdb): """ A specialized version of the python debugger that redirects stdout @@ -455,9 +481,6 @@ def __eq__(self, other): self.options == other.options and \ self.exc_msg == other.exc_msg - def __ne__(self, other): - return not self == other - def __hash__(self): return hash((self.source, self.want, self.lineno, self.indent, self.exc_msg)) @@ -507,8 +530,9 @@ def __repr__(self): examples = '1 example' else: examples = '%d examples' % len(self.examples) - return ('' % - (self.name, self.filename, self.lineno, examples)) + return ('<%s %s from %s:%s (%s)>' % + (self.__class__.__name__, + self.name, self.filename, self.lineno, examples)) def __eq__(self, other): if type(self) is not type(other): @@ -521,9 +545,6 @@ def __eq__(self, other): self.filename == other.filename and \ self.lineno == other.lineno - def __ne__(self, other): - return not self == other - def __hash__(self): return hash((self.docstring, self.name, self.filename, self.lineno)) @@ -919,7 +940,13 @@ def _from_module(self, module, object): elif inspect.isfunction(object): return module.__dict__ is object.__globals__ elif inspect.ismethoddescriptor(object): - return module.__name__ == object.__objclass__.__module__ + if hasattr(object, '__objclass__'): + obj_mod = object.__objclass__.__module__ + elif hasattr(object, '__module__'): + obj_mod = object.__module__ + else: + return True # [XX] no easy way to tell otherwise + return module.__name__ == obj_mod elif inspect.isclass(object): return module.__name__ == object.__module__ elif hasattr(object, '__module__'): @@ -952,7 +979,8 @@ def _find(self, tests, obj, name, module, source_lines, globs, seen): for valname, val in obj.__dict__.items(): valname = '%s.%s' % (name, valname) # Recurse to functions & classes. - if ((inspect.isroutine(val) or inspect.isclass(val)) and + if ((inspect.isroutine(inspect.unwrap(val)) + or inspect.isclass(val)) and self._from_module(module, val)): self._find(tests, val, valname, module, source_lines, globs, seen) @@ -1023,7 +1051,7 @@ def _get_test(self, obj, name, module, globs, source_lines): filename = None else: filename = getattr(module, '__file__', module.__name__) - if filename[-4:] in (".pyc", ".pyo"): + if filename[-4:] == ".pyc": filename = filename[:-1] return self._parser.get_doctest(docstring, globs, name, filename, lineno) @@ -1325,10 +1353,9 @@ def __run(self, test, compileflags, out): # Another chance if they didn't care about the detail. elif self.optionflags & IGNORE_EXCEPTION_DETAIL: - m1 = re.match(r'(?:[^:]*\.)?([^:]*:)', example.exc_msg) - m2 = re.match(r'(?:[^:]*\.)?([^:]*:)', exc_msg) - if m1 and m2 and check(m1.group(1), m2.group(1), - self.optionflags): + if check(_strip_exception_details(example.exc_msg), + _strip_exception_details(exc_msg), + self.optionflags): outcome = SUCCESS # Report the outcome. @@ -2258,9 +2285,6 @@ def __eq__(self, other): self._dt_tearDown == other._dt_tearDown and \ self._dt_checker == other._dt_checker - def __ne__(self, other): - return not self == other - def __hash__(self): return hash((self._dt_optionflags, self._dt_setUp, self._dt_tearDown, self._dt_checker)) @@ -2345,15 +2369,6 @@ def DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None, suite = _DocTestSuite() suite.addTest(SkipDocTestCase(module)) return suite - elif not tests: - # Why do we want to do this? Because it reveals a bug that might - # otherwise be hidden. - # It is probably a bug that this exception is not also raised if the - # number of doctest examples in tests is zero (i.e. if no doctest - # examples were found). However, we should probably not be raising - # an exception at all here, though it is too late to make this change - # for a maintenance release. See also issue #14649. - raise ValueError(module, "has no docstrings") tests.sort() suite = _DocTestSuite() @@ -2363,7 +2378,7 @@ def DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None, continue if not test.filename: filename = module.__file__ - if filename[-4:] in (".pyc", ".pyo"): + if filename[-4:] == ".pyc": filename = filename[:-1] test.filename = filename suite.addTest(DocTestCase(test, **options)) diff --git a/Lib/email/__init__.py b/Lib/email/__init__.py index ff16f6af3f35..fae872439edc 100644 --- a/Lib/email/__init__.py +++ b/Lib/email/__init__.py @@ -4,8 +4,6 @@ """A package for parsing, handling, and generating email messages.""" -__version__ = '5.1.0' - __all__ = [ 'base64mime', 'charset', diff --git a/Lib/email/_encoded_words.py b/Lib/email/_encoded_words.py index 9e0cc75b0196..5eaab36ed0a6 100644 --- a/Lib/email/_encoded_words.py +++ b/Lib/email/_encoded_words.py @@ -152,7 +152,7 @@ def decode(ew): then from the resulting bytes into unicode using the specified charset. If the cte-decoded string does not successfully decode using the specified character set, a defect is added to the defects list and the unknown octets - are replaced by the unicode 'unknown' character \uFDFF. + are replaced by the unicode 'unknown' character \\uFDFF. The specified charset and language are returned. The default for language, which is rarely if ever encountered, is the empty string. diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py index 039237936c6b..f264191dc4a4 100644 --- a/Lib/email/_header_value_parser.py +++ b/Lib/email/_header_value_parser.py @@ -70,7 +70,8 @@ import re import urllib # For urllib.parse.unquote from string import hexdigits -from collections import namedtuple, OrderedDict +from collections import OrderedDict +from operator import itemgetter from email import _encoded_words as _ew from email import errors from email import utils @@ -319,17 +320,18 @@ def cte_encode(self, charset, policy): return ''.join(res) def _fold(self, folded): + encoding = 'utf-8' if folded.policy.utf8 else 'ascii' for part in self.parts: tstr = str(part) tlen = len(tstr) try: - str(part).encode('us-ascii') + str(part).encode(encoding) except UnicodeEncodeError: if any(isinstance(x, errors.UndecodableBytesDefect) for x in part.all_defects): charset = 'unknown-8bit' else: - # XXX: this should be a policy setting + # XXX: this should be a policy setting when utf8 is False. charset = 'utf-8' tstr = part.cte_encode(charset, folded.policy) tlen = len(tstr) @@ -393,11 +395,12 @@ class UnstructuredTokenList(TokenList): def _fold(self, folded): last_ew = None + encoding = 'utf-8' if folded.policy.utf8 else 'ascii' for part in self.parts: tstr = str(part) is_ew = False try: - str(part).encode('us-ascii') + str(part).encode(encoding) except UnicodeEncodeError: if any(isinstance(x, errors.UndecodableBytesDefect) for x in part.all_defects): @@ -474,12 +477,13 @@ def _fold(self, folded): # comment that becomes a barrier across which we can't compose encoded # words. last_ew = None + encoding = 'utf-8' if folded.policy.utf8 else 'ascii' for part in self.parts: tstr = str(part) tlen = len(tstr) has_ew = False try: - str(part).encode('us-ascii') + str(part).encode(encoding) except UnicodeEncodeError: if any(isinstance(x, errors.UndecodableBytesDefect) for x in part.all_defects): @@ -1098,15 +1102,34 @@ def params(self): params[name] = [] params[name].append((token.section_number, token)) for name, parts in params.items(): - parts = sorted(parts) - # XXX: there might be more recovery we could do here if, for - # example, this is really a case of a duplicate attribute name. + parts = sorted(parts, key=itemgetter(0)) + first_param = parts[0][1] + charset = first_param.charset + # Our arbitrary error recovery is to ignore duplicate parameters, + # to use appearance order if there are duplicate rfc 2231 parts, + # and to ignore gaps. This mimics the error recovery of get_param. + if not first_param.extended and len(parts) > 1: + if parts[1][0] == 0: + parts[1][1].defects.append(errors.InvalidHeaderDefect( + 'duplicate parameter name; duplicate(s) ignored')) + parts = parts[:1] + # Else assume the *0* was missing...note that this is different + # from get_param, but we registered a defect for this earlier. value_parts = [] - charset = parts[0][1].charset - for i, (section_number, param) in enumerate(parts): + i = 0 + for section_number, param in parts: if section_number != i: - param.defects.append(errors.InvalidHeaderDefect( - "inconsistent multipart parameter numbering")) + # We could get fancier here and look for a complete + # duplicate extended parameter and ignore the second one + # seen. But we're not doing that. The old code didn't. + if not param.extended: + param.defects.append(errors.InvalidHeaderDefect( + 'duplicate parameter name; duplicate ignored')) + continue + else: + param.defects.append(errors.InvalidHeaderDefect( + "inconsistent RFC2231 parameter numbering")) + i += 1 value = param.param_value if param.extended: try: @@ -1556,6 +1579,13 @@ def get_bare_quoted_string(value): while value and value[0] != '"': if value[0] in WSP: token, value = get_fws(value) + elif value[:2] == '=?': + try: + token, value = get_encoded_word(value) + bare_quoted_string.defects.append(errors.InvalidHeaderDefect( + "encoded word inside quoted string")) + except errors.HeaderParseError: + token, value = get_qcontent(value) else: token, value = get_qcontent(value) bare_quoted_string.append(token) @@ -2890,7 +2920,7 @@ def parse_content_disposition_header(value): try: token, value = get_token(value) except errors.HeaderParseError: - ctype.defects.append(errors.InvalidHeaderDefect( + disp_header.defects.append(errors.InvalidHeaderDefect( "Expected content disposition but found {!r}".format(value))) _find_mime_parameters(disp_header, value) return disp_header @@ -2921,8 +2951,8 @@ def parse_content_transfer_encoding_header(value): try: token, value = get_token(value) except errors.HeaderParseError: - ctype.defects.append(errors.InvalidHeaderDefect( - "Expected content trnasfer encoding but found {!r}".format(value))) + cte_header.defects.append(errors.InvalidHeaderDefect( + "Expected content transfer encoding but found {!r}".format(value))) else: cte_header.append(token) cte_header.cte = token.value.strip().lower() diff --git a/Lib/email/_policybase.py b/Lib/email/_policybase.py index 81061149c3cd..c0d98a4f5429 100644 --- a/Lib/email/_policybase.py +++ b/Lib/email/_policybase.py @@ -149,12 +149,18 @@ class Policy(_PolicyBase, metaclass=abc.ABCMeta): during serialization. None or 0 means no line wrapping is done. Default is 78. + mangle_from_ -- a flag that, when True escapes From_ lines in the + body of the message by putting a `>' in front of + them. This is used when the message is being + serialized by a generator. Default: True. + """ raise_on_defect = False linesep = '\n' cte_type = '8bit' max_line_length = 78 + mangle_from_ = False def handle_defect(self, obj, defect): """Based on policy, either raise defect or call register_defect. @@ -266,6 +272,8 @@ class Compat32(Policy): replicates the behavior of the email package version 5.1. """ + mangle_from_ = True + def _sanitize_header(self, name, value): # If the header value contains surrogates, return a Header using # the unknown-8bit charset to encode the bytes as encoded words. diff --git a/Lib/email/charset.py b/Lib/email/charset.py index 892bab54a485..ee564040c68f 100644 --- a/Lib/email/charset.py +++ b/Lib/email/charset.py @@ -249,9 +249,6 @@ def __str__(self): def __eq__(self, other): return str(self) == str(other).lower() - def __ne__(self, other): - return not self.__eq__(other) - def get_body_encoding(self): """Return the content-transfer-encoding used for body encoding. @@ -386,7 +383,8 @@ def body_encode(self, string): string using the ascii codec produces the correct string version of the content. """ - # 7bit/8bit encodings return the string unchanged (module conversions) + if not string: + return string if self.body_encoding is BASE64: if isinstance(string, str): string = string.encode(self.output_charset) @@ -398,13 +396,9 @@ def body_encode(self, string): # character set, then, we must turn it into pseudo bytes via the # latin1 charset, which will encode any byte as a single code point # between 0 and 255, which is what body_encode is expecting. - # - # Note that this clause doesn't handle the case of a _payload that - # is already bytes. It never did, and the semantics of _payload - # being bytes has never been nailed down, so fixing that is a - # longer term TODO. if isinstance(string, str): - string = string.encode(self.output_charset).decode('latin1') + string = string.encode(self.output_charset) + string = string.decode('latin1') return email.quoprimime.body_encode(string) else: if isinstance(string, str): diff --git a/Lib/email/encoders.py b/Lib/email/encoders.py index f9657f0a255d..0a66acb6240b 100644 --- a/Lib/email/encoders.py +++ b/Lib/email/encoders.py @@ -54,21 +54,12 @@ def encode_7or8bit(msg): # There's no payload. For backwards compatibility we use 7bit msg['Content-Transfer-Encoding'] = '7bit' return - # We play a trick to make this go fast. If encoding/decode to ASCII - # succeeds, we know the data must be 7bit, otherwise treat it as 8bit. + # We play a trick to make this go fast. If decoding from ASCII succeeds, + # we know the data must be 7bit, otherwise treat it as 8bit. try: - if isinstance(orig, str): - orig.encode('ascii') - else: - orig.decode('ascii') + orig.decode('ascii') except UnicodeError: - charset = msg.get_charset() - output_cset = charset and charset.output_charset - # iso-2022-* is non-ASCII but encodes to a 7-bit representation - if output_cset and output_cset.lower().startswith('iso-2022-'): - msg['Content-Transfer-Encoding'] = '7bit' - else: - msg['Content-Transfer-Encoding'] = '8bit' + msg['Content-Transfer-Encoding'] = '8bit' else: msg['Content-Transfer-Encoding'] = '7bit' diff --git a/Lib/email/feedparser.py b/Lib/email/feedparser.py index eb75fe35793a..e2e3e96a1509 100644 --- a/Lib/email/feedparser.py +++ b/Lib/email/feedparser.py @@ -26,6 +26,7 @@ from email import errors from email import message from email._policybase import compat32 +from collections import deque NLCRE = re.compile('\r\n|\r|\n') NLCRE_bol = re.compile('(\r\n|\r|\n)') @@ -33,7 +34,7 @@ NLCRE_crack = re.compile('(\r\n|\r|\n)') # RFC 2822 $3.6.8 Optional fields. ftext is %d33-57 / %d59-126, Any character # except controls, SP, and ":". -headerRE = re.compile(r'^(From |[\041-\071\073-\176]{1,}:|[\t ])') +headerRE = re.compile(r'^(From |[\041-\071\073-\176]*:|[\t ])') EMPTYSTRING = '' NL = '\n' @@ -50,10 +51,10 @@ class BufferedSubFile(object): simple abstraction -- it parses until EOF closes the current message. """ def __init__(self): - # The last partial line pushed into this object. - self._partial = '' - # The list of full, pushed lines, in reverse order - self._lines = [] + # Chunks of the last partial line pushed into this object. + self._partial = [] + # A deque of full, pushed lines + self._lines = deque() # The stack of false-EOF checking predicates. self._eofstack = [] # A flag indicating whether the file has been closed or not. @@ -67,8 +68,8 @@ def pop_eof_matcher(self): def close(self): # Don't forget any trailing partial line. - self._lines.append(self._partial) - self._partial = '' + self.pushlines(''.join(self._partial).splitlines(True)) + self._partial = [] self._closed = True def readline(self): @@ -78,39 +79,48 @@ def readline(self): return NeedMoreData # Pop the line off the stack and see if it matches the current # false-EOF predicate. - line = self._lines.pop() + line = self._lines.popleft() # RFC 2046, section 5.1.2 requires us to recognize outer level # boundaries at any level of inner nesting. Do this, but be sure it's # in the order of most to least nested. - for ateof in self._eofstack[::-1]: + for ateof in reversed(self._eofstack): if ateof(line): # We're at the false EOF. But push the last line back first. - self._lines.append(line) + self._lines.appendleft(line) return '' return line def unreadline(self, line): # Let the consumer push a line back into the buffer. assert line is not NeedMoreData - self._lines.append(line) + self._lines.appendleft(line) def push(self, data): """Push some new data into this object.""" - # Handle any previous leftovers - data, self._partial = self._partial + data, '' # Crack into lines, but preserve the linesep characters on the end of each parts = data.splitlines(True) + + if not parts or not parts[0].endswith(('\n', '\r')): + # No new complete lines, so just accumulate partials + self._partial += parts + return + + if self._partial: + # If there are previous leftovers, complete them now + self._partial.append(parts[0]) + parts[0:1] = ''.join(self._partial).splitlines(True) + del self._partial[:] + # If the last element of the list does not end in a newline, then treat # it as a partial line. We only check for '\n' here because a line # ending with '\r' might be a line that was split in the middle of a # '\r\n' sequence (see bugs 1555570 and 1721862). - if parts and not parts[-1].endswith('\n'): - self._partial = parts.pop() + if not parts[-1].endswith('\n'): + self._partial = [parts.pop()] self.pushlines(parts) def pushlines(self, lines): - # Reverse and insert at the front of the lines. - self._lines[:0] = lines[::-1] + self._lines.extend(lines) def __iter__(self): return self @@ -126,7 +136,7 @@ def __next__(self): class FeedParser: """A feed-style parser of email.""" - def __init__(self, _factory=message.Message, *, policy=compat32): + def __init__(self, _factory=None, *, policy=compat32): """_factory is called with no arguments to create a new message obj The policy keyword specifies a policy object that controls a number of @@ -134,14 +144,23 @@ def __init__(self, _factory=message.Message, *, policy=compat32): backward compatibility. """ - self._factory = _factory self.policy = policy - try: - _factory(policy=self.policy) - self._factory_kwds = lambda: {'policy': self.policy} - except TypeError: - # Assume this is an old-style factory - self._factory_kwds = lambda: {} + self._factory_kwds = lambda: {'policy': self.policy} + if _factory is None: + # What this should be: + #self._factory = policy.default_message_factory + # but, because we are post 3.4 feature freeze, fix with temp hack: + if self.policy is compat32: + self._factory = message.Message + else: + self._factory = message.EmailMessage + else: + self._factory = _factory + try: + _factory(policy=self.policy) + except TypeError: + # Assume this is an old-style factory + self._factory_kwds = lambda: {} self._input = BufferedSubFile() self._msgstack = [] self._parse = self._parsegen().__next__ @@ -492,6 +511,15 @@ def _parse_headers(self, lines): # There will always be a colon, because if there wasn't the part of # the parser that calls us would have started parsing the body. i = line.find(':') + + # If the colon is on the start of the line the header is clearly + # malformed, but we might be able to salvage the rest of the + # message. Track the error but keep going. + if i == 0: + defect = errors.InvalidHeaderDefect("Missing header name.") + self._cur.defects.append(defect) + continue + assert i>0, "_parse_headers fed line with no : and no leading WS" lastheader = line[:i] lastvalue = [line] diff --git a/Lib/email/generator.py b/Lib/email/generator.py index 4ea0b559b997..11ff16df9a16 100644 --- a/Lib/email/generator.py +++ b/Lib/email/generator.py @@ -10,13 +10,10 @@ import sys import time import random -import warnings +from copy import deepcopy from io import StringIO, BytesIO -from email._policybase import compat32 -from email.header import Header from email.utils import _has_surrogates -import email.charset as _charset UNDERSCORE = '_' NL = '\n' # XXX: no longer used by the code below. @@ -35,16 +32,16 @@ class Generator: # Public interface # - def __init__(self, outfp, mangle_from_=True, maxheaderlen=None, *, + def __init__(self, outfp, mangle_from_=None, maxheaderlen=None, *, policy=None): """Create the generator for message flattening. outfp is the output file-like object for writing the message to. It must have a write() method. - Optional mangle_from_ is a flag that, when True (the default), escapes - From_ lines in the body of the message by putting a `>' in front of - them. + Optional mangle_from_ is a flag that, when True (the default if policy + is not set), escapes From_ lines in the body of the message by putting + a `>' in front of them. Optional maxheaderlen specifies the longest length for a non-continued header. When a header line is longer (in characters, with tabs @@ -54,10 +51,14 @@ def __init__(self, outfp, mangle_from_=True, maxheaderlen=None, *, by RFC 2822. The policy keyword specifies a policy object that controls a number of - aspects of the generator's operation. The default policy maintains - backward compatibility. + aspects of the generator's operation. If no policy is specified, + the policy associated with the Message object passed to the + flatten method is used. """ + + if mangle_from_ is None: + mangle_from_ = True if policy is None else policy.mangle_from_ self._fp = outfp self._mangle_from_ = mangle_from_ self.maxheaderlen = maxheaderlen @@ -79,7 +80,9 @@ def flatten(self, msg, unixfrom=False, linesep=None): Note that for subobjects, no From_ line is printed. linesep specifies the characters used to indicate a new line in - the output. The default value is determined by the policy. + the output. The default value is determined by the policy specified + when the Generator instance was created or, if none was specified, + from the policy associated with the msg. """ # We use the _XXX constants for operating on data that comes directly @@ -173,10 +176,18 @@ def _write(self, msg): # necessary. oldfp = self._fp try: + self._munge_cte = None self._fp = sfp = self._new_buffer() self._dispatch(msg) finally: self._fp = oldfp + munge_cte = self._munge_cte + del self._munge_cte + # If we munged the cte, copy the message again and re-fix the CTE. + if munge_cte: + msg = deepcopy(msg) + msg.replace_header('content-transfer-encoding', munge_cte[0]) + msg.replace_header('content-type', munge_cte[1]) # Write the headers. First we see if the message object wants to # handle that itself. If not, we'll do it generically. meth = getattr(msg, '_write_headers', None) @@ -225,9 +236,14 @@ def _handle_text(self, msg): if _has_surrogates(msg._payload): charset = msg.get_param('charset') if charset is not None: + # XXX: This copy stuff is an ugly hack to avoid modifying the + # existing message. + msg = deepcopy(msg) del msg['content-transfer-encoding'] msg.set_payload(payload, charset) payload = msg.get_payload() + self._munge_cte = (msg['content-transfer-encoding'], + msg['content-type']) if self._mangle_from_: payload = fcre.sub('>From ', payload) self._write_lines(payload) @@ -285,9 +301,8 @@ def _handle_multipart(self, msg): # body-part self._fp.write(body_part) # close-delimiter transport-padding - self.write(self._NL + '--' + boundary + '--') + self.write(self._NL + '--' + boundary + '--' + self._NL) if msg.epilogue is not None: - self.write(self._NL) if self._mangle_from_: epilogue = fcre.sub('>From ', msg.epilogue) else: @@ -437,7 +452,7 @@ class DecodedGenerator(Generator): Like the Generator base class, except that non-text parts are substituted with a format string representing the part. """ - def __init__(self, outfp, mangle_from_=True, maxheaderlen=78, fmt=None): + def __init__(self, outfp, mangle_from_=None, maxheaderlen=78, fmt=None): """Like Generator.__init__() except that an additional optional argument is allowed. diff --git a/Lib/email/header.py b/Lib/email/header.py index 5bd06380ceef..6820ea16baf3 100644 --- a/Lib/email/header.py +++ b/Lib/email/header.py @@ -100,7 +100,6 @@ def decode_header(header): words.append((encoded, encoding, charset)) # Now loop over words and remove words that consist of whitespace # between two encoded strings. - import sys droplist = [] for n, w in enumerate(words): if n>1 and w[1] and words[n-2][1] and words[n-1][0].isspace(): @@ -263,9 +262,6 @@ def __eq__(self, other): # args and do another comparison. return other == str(self) - def __ne__(self, other): - return not self == other - def append(self, s, charset=None, errors='strict'): """Append a string to the MIME header. @@ -362,7 +358,6 @@ def encode(self, splitchars=';, \t', maxlinelen=None, linesep='\n'): for string, charset in self._chunks: if hasspace is not None: hasspace = string and self._nonctext(string[0]) - import sys if lastcs not in (None, 'us-ascii'): if not hasspace or charset not in (None, 'us-ascii'): formatter.add_transition() diff --git a/Lib/email/headerregistry.py b/Lib/email/headerregistry.py index 1fae950820a7..468ca9e3a068 100644 --- a/Lib/email/headerregistry.py +++ b/Lib/email/headerregistry.py @@ -7,6 +7,7 @@ and will probably change some before that happens. """ +from types import MappingProxyType from email import utils from email import errors @@ -80,7 +81,8 @@ def addr_spec(self): return lp def __repr__(self): - return "Address(display_name={!r}, username={!r}, domain={!r})".format( + return "{}(display_name={!r}, username={!r}, domain={!r})".format( + self.__class__.__name__, self.display_name, self.username, self.domain) def __str__(self): @@ -131,7 +133,8 @@ def addresses(self): return self._addresses def __repr__(self): - return "Group(display_name={!r}, addresses={!r}".format( + return "{}(display_name={!r}, addresses={!r}".format( + self.__class__.__name__, self.display_name, self.addresses) def __str__(self): @@ -454,7 +457,7 @@ def init(self, *args, **kw): @property def params(self): - return self._params.copy() + return MappingProxyType(self._params) class ContentTypeHeader(ParameterizedMIMEHeader): diff --git a/Lib/email/message.py b/Lib/email/message.py index ce673b0b92f0..a892012c3fcc 100644 --- a/Lib/email/message.py +++ b/Lib/email/message.py @@ -8,6 +8,8 @@ import re import uu +import quopri +import warnings from io import BytesIO, StringIO # Intrapackage imports @@ -203,7 +205,11 @@ def attach(self, payload): if self._payload is None: self._payload = [payload] else: - self._payload.append(payload) + try: + self._payload.append(payload) + except AttributeError: + raise TypeError("Attach is not valid on a message with a" + " non-multipart payload") def get_payload(self, i=None, decode=False): """Return a reference to the payload. @@ -267,14 +273,14 @@ def get_payload(self, i=None, decode=False): bpayload = payload.encode('ascii') except UnicodeError: # This won't happen for RFC compliant messages (messages - # containing only ASCII codepoints in the unicode input). + # containing only ASCII code points in the unicode input). # If it does happen, turn the string into bytes in a way # guaranteed not to fail. bpayload = payload.encode('raw-unicode-escape') if not decode: return payload if cte == 'quoted-printable': - return utils._qdecode(bpayload) + return quopri.decodestring(bpayload) elif cte == 'base64': # XXX: this is a bit of a hack; decode_b should probably be factored # out somewhere, but I haven't figured out where yet. @@ -301,9 +307,17 @@ def set_payload(self, payload, charset=None): Optional charset sets the message's default character set. See set_charset() for details. """ - if isinstance(payload, bytes): - payload = payload.decode('ascii', 'surrogateescape') - self._payload = payload + if hasattr(payload, 'encode'): + if charset is None: + self._payload = payload + return + if not isinstance(charset, Charset): + charset = Charset(charset) + payload = payload.encode(charset.output_charset) + if hasattr(payload, 'decode'): + self._payload = payload.decode('ascii', 'surrogateescape') + else: + self._payload = payload if charset is not None: self.set_charset(charset) @@ -342,7 +356,16 @@ def set_charset(self, charset): try: cte(self) except TypeError: - self._payload = charset.body_encode(self._payload) + # This 'if' is for backward compatibility, it allows unicode + # through even though that won't work correctly if the + # message is serialized. + payload = self._payload + if payload: + try: + payload = payload.encode('ascii', 'surrogateescape') + except UnicodeError: + payload = payload.encode(charset.output_charset) + self._payload = charset.body_encode(payload) self.add_header('Content-Transfer-Encoding', cte) def get_charset(self): @@ -904,6 +927,18 @@ def get_charsets(self, failobj=None): """ return [part.get_content_charset(failobj) for part in self.walk()] + def get_content_disposition(self): + """Return the message's content-disposition if it exists, or None. + + The return values can be either 'inline', 'attachment' or None + according to the rfc2183. + """ + value = self.get('content-disposition') + if value is None: + return None + c_d = _splitparam(value)[0].lower() + return c_d + # I.e. def walk(self): ... from email.iterators import walk @@ -916,15 +951,12 @@ def __init__(self, policy=None): policy = default Message.__init__(self, policy) - @property def is_attachment(self): c_d = self.get('content-disposition') - if c_d is None: - return False - return c_d.lower() == 'attachment' + return False if c_d is None else c_d.content_disposition == 'attachment' def _find_body(self, part, preferencelist): - if part.is_attachment: + if part.is_attachment(): return maintype, subtype = part.get_content_type().split('/') if maintype == 'text': @@ -1017,7 +1049,7 @@ def iter_attachments(self): for part in parts: maintype, subtype = part.get_content_type().split('/') if ((maintype, subtype) in self._body_types and - not part.is_attachment and subtype not in seen): + not part.is_attachment() and subtype not in seen): seen.append(subtype) continue yield part diff --git a/Lib/email/mime/nonmultipart.py b/Lib/email/mime/nonmultipart.py index fc3b9eb4dcfb..e1f51968b59e 100644 --- a/Lib/email/mime/nonmultipart.py +++ b/Lib/email/mime/nonmultipart.py @@ -12,7 +12,7 @@ class MIMENonMultipart(MIMEBase): - """Base class for MIME multipart/* type messages.""" + """Base class for MIME non-multipart type messages.""" def attach(self, payload): # The public API prohibits attaching multiple subparts to MIMEBase diff --git a/Lib/email/mime/text.py b/Lib/email/mime/text.py index 3b5b09f1907f..479928ec945d 100644 --- a/Lib/email/mime/text.py +++ b/Lib/email/mime/text.py @@ -6,7 +6,7 @@ __all__ = ['MIMEText'] -from email.encoders import encode_7or8bit +from email.charset import Charset from email.mime.nonmultipart import MIMENonMultipart @@ -35,6 +35,8 @@ def __init__(self, _text, _subtype='plain', _charset=None): _charset = 'us-ascii' except UnicodeEncodeError: _charset = 'utf-8' + if isinstance(_charset, Charset): + _charset = str(_charset) MIMENonMultipart.__init__(self, 'text', _subtype, **{'charset': _charset}) diff --git a/Lib/email/parser.py b/Lib/email/parser.py index f49d31d43dfc..8c9bc9e44e24 100644 --- a/Lib/email/parser.py +++ b/Lib/email/parser.py @@ -7,17 +7,15 @@ __all__ = ['Parser', 'HeaderParser', 'BytesParser', 'BytesHeaderParser', 'FeedParser', 'BytesFeedParser'] -import warnings from io import StringIO, TextIOWrapper from email.feedparser import FeedParser, BytesFeedParser -from email.message import Message from email._policybase import compat32 class Parser: - def __init__(self, _class=Message, *, policy=compat32): + def __init__(self, _class=None, *, policy=compat32): """Parser of RFC 2822 and MIME email messages. Creates an in-memory object tree representing the email message, which @@ -108,8 +106,10 @@ def parse(self, fp, headersonly=False): meaning it parses the entire contents of the file. """ fp = TextIOWrapper(fp, encoding='ascii', errors='surrogateescape') - with fp: + try: return self.parser.parse(fp, headersonly) + finally: + fp.detach() def parsebytes(self, text, headersonly=False): diff --git a/Lib/email/policy.py b/Lib/email/policy.py index f0b20f4b198a..6ac64a56831d 100644 --- a/Lib/email/policy.py +++ b/Lib/email/policy.py @@ -35,6 +35,13 @@ class EmailPolicy(Policy): In addition to the settable attributes listed above that apply to all Policies, this policy adds the following additional attributes: + utf8 -- if False (the default) message headers will be + serialized as ASCII, using encoded words to encode + any non-ASCII characters in the source strings. If + True, the message headers will be serialized using + utf8 and will not contain encoded words (see RFC + 6532 for more on this serialization format). + refold_source -- if the value for a header in the Message object came from the parsing of some source, this attribute indicates whether or not a generator should refold @@ -72,6 +79,7 @@ class EmailPolicy(Policy): """ + utf8 = False refold_source = 'long' header_factory = HeaderRegistry() content_manager = raw_data_manager @@ -175,9 +183,13 @@ def fold_binary(self, name, value): refold_header setting, since there is no way to know whether the binary data consists of single byte characters or multibyte characters. + If utf8 is true, headers are encoded to utf8, otherwise to ascii with + non-ASCII unicode rendered as encoded words. + """ folded = self._fold(name, value, refold_binary=self.cte_type=='7bit') - return folded.encode('ascii', 'surrogateescape') + charset = 'utf8' if self.utf8 else 'ascii' + return folded.encode(charset, 'surrogateescape') def _fold(self, name, value, refold_binary=False): if hasattr(value, 'name'): @@ -199,3 +211,4 @@ def _fold(self, name, value, refold_binary=False): strict = default.clone(raise_on_defect=True) SMTP = default.clone(linesep='\r\n') HTTP = default.clone(linesep='\r\n', max_line_length=None) +SMTPUTF8 = SMTP.clone(utf8=True) diff --git a/Lib/email/quoprimime.py b/Lib/email/quoprimime.py index bc02281b1d7f..c1fe2b469400 100644 --- a/Lib/email/quoprimime.py +++ b/Lib/email/quoprimime.py @@ -40,7 +40,6 @@ ] import re -import io from string import ascii_letters, digits, hexdigits @@ -53,8 +52,9 @@ # space-wise. Remember that headers and bodies have different sets of safe # characters. Initialize both maps with the full expansion, and then override # the safe bytes with the more compact form. -_QUOPRI_HEADER_MAP = dict((c, '=%02X' % c) for c in range(256)) -_QUOPRI_BODY_MAP = _QUOPRI_HEADER_MAP.copy() +_QUOPRI_MAP = ['=%02X' % c for c in range(256)] +_QUOPRI_HEADER_MAP = _QUOPRI_MAP[:] +_QUOPRI_BODY_MAP = _QUOPRI_MAP[:] # Safe header bytes which need no encoding. for c in b'-!*+/' + ascii_letters.encode('ascii') + digits.encode('ascii'): @@ -121,8 +121,7 @@ def unquote(s): def quote(c): - return '=%02X' % ord(c) - + return _QUOPRI_MAP[ord(c)] def header_encode(header_bytes, charset='iso-8859-1'): @@ -140,68 +139,16 @@ def header_encode(header_bytes, charset='iso-8859-1'): if not header_bytes: return '' # Iterate over every byte, encoding if necessary. - encoded = [] - for octet in header_bytes: - encoded.append(_QUOPRI_HEADER_MAP[octet]) + encoded = header_bytes.decode('latin1').translate(_QUOPRI_HEADER_MAP) # Now add the RFC chrome to each encoded chunk and glue the chunks # together. - return '=?%s?q?%s?=' % (charset, EMPTYSTRING.join(encoded)) - - -class _body_accumulator(io.StringIO): - - def __init__(self, maxlinelen, eol, *args, **kw): - super().__init__(*args, **kw) - self.eol = eol - self.maxlinelen = self.room = maxlinelen - - def write_str(self, s): - """Add string s to the accumulated body.""" - self.write(s) - self.room -= len(s) - - def newline(self): - """Write eol, then start new line.""" - self.write_str(self.eol) - self.room = self.maxlinelen - - def write_soft_break(self): - """Write a soft break, then start a new line.""" - self.write_str('=') - self.newline() - - def write_wrapped(self, s, extra_room=0): - """Add a soft line break if needed, then write s.""" - if self.room < len(s) + extra_room: - self.write_soft_break() - self.write_str(s) - - def write_char(self, c, is_last_char): - if not is_last_char: - # Another character follows on this line, so we must leave - # extra room, either for it or a soft break, and whitespace - # need not be quoted. - self.write_wrapped(c, extra_room=1) - elif c not in ' \t': - # For this and remaining cases, no more characters follow, - # so there is no need to reserve extra room (since a hard - # break will immediately follow). - self.write_wrapped(c) - elif self.room >= 3: - # It's a whitespace character at end-of-line, and we have room - # for the three-character quoted encoding. - self.write(quote(c)) - elif self.room == 2: - # There's room for the whitespace character and a soft break. - self.write(c) - self.write_soft_break() - else: - # There's room only for a soft break. The quoted whitespace - # will be the only content on the subsequent line. - self.write_soft_break() - self.write(quote(c)) + return '=?%s?q?%s?=' % (charset, encoded) +_QUOPRI_BODY_ENCODE_MAP = _QUOPRI_BODY_MAP[:] +for c in b'\r\n': + _QUOPRI_BODY_ENCODE_MAP[c] = chr(c) + def body_encode(body, maxlinelen=76, eol=NL): """Encode with quoted-printable, wrapping at maxlinelen characters. @@ -226,26 +173,56 @@ def body_encode(body, maxlinelen=76, eol=NL): if not body: return body - # The last line may or may not end in eol, but all other lines do. - last_has_eol = (body[-1] in '\r\n') - - # This accumulator will make it easier to build the encoded body. - encoded_body = _body_accumulator(maxlinelen, eol) - - lines = body.splitlines() - last_line_no = len(lines) - 1 - for line_no, line in enumerate(lines): - last_char_index = len(line) - 1 - for i, c in enumerate(line): - if body_check(ord(c)): - c = quote(c) - encoded_body.write_char(c, i==last_char_index) - # Add an eol if input line had eol. All input lines have eol except - # possibly the last one. - if line_no < last_line_no or last_has_eol: - encoded_body.newline() - - return encoded_body.getvalue() + # quote speacial characters + body = body.translate(_QUOPRI_BODY_ENCODE_MAP) + + soft_break = '=' + eol + # leave space for the '=' at the end of a line + maxlinelen1 = maxlinelen - 1 + + encoded_body = [] + append = encoded_body.append + + for line in body.splitlines(): + # break up the line into pieces no longer than maxlinelen - 1 + start = 0 + laststart = len(line) - 1 - maxlinelen + while start <= laststart: + stop = start + maxlinelen1 + # make sure we don't break up an escape sequence + if line[stop - 2] == '=': + append(line[start:stop - 1]) + start = stop - 2 + elif line[stop - 1] == '=': + append(line[start:stop]) + start = stop - 1 + else: + append(line[start:stop] + '=') + start = stop + + # handle rest of line, special case if line ends in whitespace + if line and line[-1] in ' \t': + room = start - laststart + if room >= 3: + # It's a whitespace character at end-of-line, and we have room + # for the three-character quoted encoding. + q = quote(line[-1]) + elif room == 2: + # There's room for the whitespace character and a soft break. + q = line[-1] + soft_break + else: + # There's room only for a soft break. The quoted whitespace + # will be the only content on the subsequent line. + q = soft_break + quote(line[-1]) + append(line[start:-1] + q) + else: + append(line[start:]) + + # add back final newline if present + if body[-1] in CRLF: + append('') + + return eol.join(encoded_body) diff --git a/Lib/email/utils.py b/Lib/email/utils.py index 25b0d561f49b..5080d81909bb 100644 --- a/Lib/email/utils.py +++ b/Lib/email/utils.py @@ -25,13 +25,10 @@ import os import re import time -import base64 import random import socket import datetime import urllib.parse -import warnings -from io import StringIO from email._parseaddr import quote from email._parseaddr import AddressList as _AddressList @@ -39,10 +36,7 @@ from email._parseaddr import parsedate, parsedate_tz, _parsedate_tz -from quopri import decodestring as _qdecode - # Intrapackage imports -from email.encoders import _bencode, _qencode from email.charset import Charset COMMASPACE = ', ' @@ -161,30 +155,14 @@ def formatdate(timeval=None, localtime=False, usegmt=False): # 2822 requires that day and month names be the English abbreviations. if timeval is None: timeval = time.time() - if localtime: - now = time.localtime(timeval) - # Calculate timezone offset, based on whether the local zone has - # daylight savings time, and whether DST is in effect. - if time.daylight and now[-1]: - offset = time.altzone - else: - offset = time.timezone - hours, minutes = divmod(abs(offset), 3600) - # Remember offset is in seconds west of UTC, but the timezone is in - # minutes east of UTC, so the signs differ. - if offset > 0: - sign = '-' - else: - sign = '+' - zone = '%s%02d%02d' % (sign, hours, minutes // 60) + if localtime or usegmt: + dt = datetime.datetime.fromtimestamp(timeval, datetime.timezone.utc) else: - now = time.gmtime(timeval) - # Timezone offset is always -0000 - if usegmt: - zone = 'GMT' - else: - zone = '-0000' - return _format_timetuple_and_zone(now, zone) + dt = datetime.datetime.utcfromtimestamp(timeval) + if localtime: + dt = dt.astimezone() + usegmt = False + return format_datetime(dt, usegmt) def format_datetime(dt, usegmt=False): """Turn a datetime into a date string as specified in RFC 2822. @@ -208,24 +186,23 @@ def format_datetime(dt, usegmt=False): def make_msgid(idstring=None, domain=None): """Returns a string suitable for RFC 2822 compliant Message-ID, e.g: - <20020201195627.33539.96671@nightshade.la.mastaler.com> + <142480216486.20800.16526388040877946887@nightshade.la.mastaler.com> Optional idstring if given is a string used to strengthen the uniqueness of the message id. Optional domain if given provides the portion of the message id after the '@'. It defaults to the locally defined hostname. """ - timeval = time.time() - utcdate = time.strftime('%Y%m%d%H%M%S', time.gmtime(timeval)) + timeval = int(time.time()*100) pid = os.getpid() - randint = random.randrange(100000) + randint = random.getrandbits(64) if idstring is None: idstring = '' else: idstring = '.' + idstring if domain is None: domain = socket.getfqdn() - msgid = '<%s.%s.%s%s@%s>' % (utcdate, pid, randint, idstring, domain) + msgid = '<%d.%d.%d%s@%s>' % (timeval, pid, randint, idstring, domain) return msgid @@ -347,6 +324,10 @@ def collapse_rfc2231_value(value, errors='replace', # object. We do not want bytes() normal utf-8 decoder, we want a straight # interpretation of the string as character bytes. charset, language, text = value + if charset is None: + # Issue 17369: if charset/lang is None, decode_rfc2231 couldn't parse + # the value, so use the fallback_charset. + charset = fallback_charset rawbytes = bytes(text, 'raw-unicode-escape') try: return str(rawbytes, charset, errors) diff --git a/Lib/encodings/aliases.py b/Lib/encodings/aliases.py index 5461aa053a4a..67c828d639e0 100644 --- a/Lib/encodings/aliases.py +++ b/Lib/encodings/aliases.py @@ -109,6 +109,11 @@ '1258' : 'cp1258', 'windows_1258' : 'cp1258', + # cp273 codec + '273' : 'cp273', + 'ibm273' : 'cp273', + 'csibm273' : 'cp273', + # cp424 codec '424' : 'cp424', 'csibm424' : 'cp424', @@ -407,6 +412,11 @@ # koi8_r codec 'cskoi8r' : 'koi8_r', + # kz1048 codec + 'kz_1048' : 'kz1048', + 'rk1048' : 'kz1048', + 'strk1048_2002' : 'kz1048', + # latin_1 codec # # Note that the latin_1 codec is implemented internally in C and a diff --git a/Lib/encodings/base64_codec.py b/Lib/encodings/base64_codec.py index 881d1ba0beeb..8e7703b3b607 100644 --- a/Lib/encodings/base64_codec.py +++ b/Lib/encodings/base64_codec.py @@ -1,7 +1,6 @@ """Python 'base64_codec' Codec - base64 content transfer encoding. -This codec de/encodes from bytes to bytes and is therefore usable with -bytes.transform() and bytes.untransform(). +This codec de/encodes from bytes to bytes. Written by Marc-Andre Lemburg (mal@lemburg.com). """ diff --git a/Lib/encodings/cp65001.py b/Lib/encodings/cp65001.py index 287eb877feff..95cb2aecf0cc 100644 --- a/Lib/encodings/cp65001.py +++ b/Lib/encodings/cp65001.py @@ -11,20 +11,23 @@ ### Codec APIs encode = functools.partial(codecs.code_page_encode, 65001) -decode = functools.partial(codecs.code_page_decode, 65001) +_decode = functools.partial(codecs.code_page_decode, 65001) + +def decode(input, errors='strict'): + return codecs.code_page_decode(65001, input, errors, True) class IncrementalEncoder(codecs.IncrementalEncoder): def encode(self, input, final=False): return encode(input, self.errors)[0] class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - _buffer_decode = decode + _buffer_decode = _decode class StreamWriter(codecs.StreamWriter): encode = encode class StreamReader(codecs.StreamReader): - decode = decode + decode = _decode ### encodings module API diff --git a/Lib/encodings/hex_codec.py b/Lib/encodings/hex_codec.py index f2ed0a7658e2..9fb107280445 100644 --- a/Lib/encodings/hex_codec.py +++ b/Lib/encodings/hex_codec.py @@ -1,7 +1,6 @@ """Python 'hex_codec' Codec - 2-digit hex content transfer encoding. -This codec de/encodes from bytes to bytes and is therefore usable with -bytes.transform() and bytes.untransform(). +This codec de/encodes from bytes to bytes. Written by Marc-Andre Lemburg (mal@lemburg.com). """ diff --git a/Lib/encodings/koi8_t.py b/Lib/encodings/koi8_t.py new file mode 100644 index 000000000000..b5415ba36658 --- /dev/null +++ b/Lib/encodings/koi8_t.py @@ -0,0 +1,308 @@ +""" Python Character Mapping Codec koi8_t +""" +# http://ru.wikipedia.org/wiki/КОИ-8 +# http://www.opensource.apple.com/source/libiconv/libiconv-4/libiconv/tests/KOI8-T.TXT + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='koi8-t', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u049b' # 0x80 -> CYRILLIC SMALL LETTER KA WITH DESCENDER + '\u0493' # 0x81 -> CYRILLIC SMALL LETTER GHE WITH STROKE + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0492' # 0x83 -> CYRILLIC CAPITAL LETTER GHE WITH STROKE + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\ufffe' # 0x88 -> UNDEFINED + '\u2030' # 0x89 -> PER MILLE SIGN + '\u04b3' # 0x8A -> CYRILLIC SMALL LETTER HA WITH DESCENDER + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u04b2' # 0x8C -> CYRILLIC CAPITAL LETTER HA WITH DESCENDER + '\u04b7' # 0x8D -> CYRILLIC SMALL LETTER CHE WITH DESCENDER + '\u04b6' # 0x8E -> CYRILLIC CAPITAL LETTER CHE WITH DESCENDER + '\ufffe' # 0x8F -> UNDEFINED + '\u049a' # 0x90 -> CYRILLIC CAPITAL LETTER KA WITH DESCENDER + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\ufffe' # 0x98 -> UNDEFINED + '\u2122' # 0x99 -> TRADE MARK SIGN + '\ufffe' # 0x9A -> UNDEFINED + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\ufffe' # 0x9C -> UNDEFINED + '\ufffe' # 0x9D -> UNDEFINED + '\ufffe' # 0x9E -> UNDEFINED + '\ufffe' # 0x9F -> UNDEFINED + '\ufffe' # 0xA0 -> UNDEFINED + '\u04ef' # 0xA1 -> CYRILLIC SMALL LETTER U WITH MACRON + '\u04ee' # 0xA2 -> CYRILLIC CAPITAL LETTER U WITH MACRON + '\u0451' # 0xA3 -> CYRILLIC SMALL LETTER IO + '\xa4' # 0xA4 -> CURRENCY SIGN + '\u04e3' # 0xA5 -> CYRILLIC SMALL LETTER I WITH MACRON + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\ufffe' # 0xA8 -> UNDEFINED + '\ufffe' # 0xA9 -> UNDEFINED + '\ufffe' # 0xAA -> UNDEFINED + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\ufffe' # 0xAF -> UNDEFINED + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\u0401' # 0xB3 -> CYRILLIC CAPITAL LETTER IO + '\ufffe' # 0xB4 -> UNDEFINED + '\u04e2' # 0xB5 -> CYRILLIC CAPITAL LETTER I WITH MACRON + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\ufffe' # 0xB8 -> UNDEFINED + '\u2116' # 0xB9 -> NUMERO SIGN + '\ufffe' # 0xBA -> UNDEFINED + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\ufffe' # 0xBC -> UNDEFINED + '\ufffe' # 0xBD -> UNDEFINED + '\ufffe' # 0xBE -> UNDEFINED + '\xa9' # 0xBF -> COPYRIGHT SIGN + '\u044e' # 0xC0 -> CYRILLIC SMALL LETTER YU + '\u0430' # 0xC1 -> CYRILLIC SMALL LETTER A + '\u0431' # 0xC2 -> CYRILLIC SMALL LETTER BE + '\u0446' # 0xC3 -> CYRILLIC SMALL LETTER TSE + '\u0434' # 0xC4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0xC5 -> CYRILLIC SMALL LETTER IE + '\u0444' # 0xC6 -> CYRILLIC SMALL LETTER EF + '\u0433' # 0xC7 -> CYRILLIC SMALL LETTER GHE + '\u0445' # 0xC8 -> CYRILLIC SMALL LETTER HA + '\u0438' # 0xC9 -> CYRILLIC SMALL LETTER I + '\u0439' # 0xCA -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0xCB -> CYRILLIC SMALL LETTER KA + '\u043b' # 0xCC -> CYRILLIC SMALL LETTER EL + '\u043c' # 0xCD -> CYRILLIC SMALL LETTER EM + '\u043d' # 0xCE -> CYRILLIC SMALL LETTER EN + '\u043e' # 0xCF -> CYRILLIC SMALL LETTER O + '\u043f' # 0xD0 -> CYRILLIC SMALL LETTER PE + '\u044f' # 0xD1 -> CYRILLIC SMALL LETTER YA + '\u0440' # 0xD2 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0xD3 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0xD4 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0xD5 -> CYRILLIC SMALL LETTER U + '\u0436' # 0xD6 -> CYRILLIC SMALL LETTER ZHE + '\u0432' # 0xD7 -> CYRILLIC SMALL LETTER VE + '\u044c' # 0xD8 -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044b' # 0xD9 -> CYRILLIC SMALL LETTER YERU + '\u0437' # 0xDA -> CYRILLIC SMALL LETTER ZE + '\u0448' # 0xDB -> CYRILLIC SMALL LETTER SHA + '\u044d' # 0xDC -> CYRILLIC SMALL LETTER E + '\u0449' # 0xDD -> CYRILLIC SMALL LETTER SHCHA + '\u0447' # 0xDE -> CYRILLIC SMALL LETTER CHE + '\u044a' # 0xDF -> CYRILLIC SMALL LETTER HARD SIGN + '\u042e' # 0xE0 -> CYRILLIC CAPITAL LETTER YU + '\u0410' # 0xE1 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0xE2 -> CYRILLIC CAPITAL LETTER BE + '\u0426' # 0xE3 -> CYRILLIC CAPITAL LETTER TSE + '\u0414' # 0xE4 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0xE5 -> CYRILLIC CAPITAL LETTER IE + '\u0424' # 0xE6 -> CYRILLIC CAPITAL LETTER EF + '\u0413' # 0xE7 -> CYRILLIC CAPITAL LETTER GHE + '\u0425' # 0xE8 -> CYRILLIC CAPITAL LETTER HA + '\u0418' # 0xE9 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0xEA -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0xEB -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0xEC -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0xED -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0xEE -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0xEF -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0xF0 -> CYRILLIC CAPITAL LETTER PE + '\u042f' # 0xF1 -> CYRILLIC CAPITAL LETTER YA + '\u0420' # 0xF2 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0xF3 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0xF4 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0xF5 -> CYRILLIC CAPITAL LETTER U + '\u0416' # 0xF6 -> CYRILLIC CAPITAL LETTER ZHE + '\u0412' # 0xF7 -> CYRILLIC CAPITAL LETTER VE + '\u042c' # 0xF8 -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042b' # 0xF9 -> CYRILLIC CAPITAL LETTER YERU + '\u0417' # 0xFA -> CYRILLIC CAPITAL LETTER ZE + '\u0428' # 0xFB -> CYRILLIC CAPITAL LETTER SHA + '\u042d' # 0xFC -> CYRILLIC CAPITAL LETTER E + '\u0429' # 0xFD -> CYRILLIC CAPITAL LETTER SHCHA + '\u0427' # 0xFE -> CYRILLIC CAPITAL LETTER CHE + '\u042a' # 0xFF -> CYRILLIC CAPITAL LETTER HARD SIGN +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/kz1048.py b/Lib/encodings/kz1048.py new file mode 100644 index 000000000000..712aee6e9308 --- /dev/null +++ b/Lib/encodings/kz1048.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec kz1048 generated from 'MAPPINGS/VENDORS/MISC/KZ1048.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self, input, errors='strict'): + return codecs.charmap_encode(input, errors, encoding_table) + + def decode(self, input, errors='strict'): + return codecs.charmap_decode(input, errors, decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input, self.errors, encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input, self.errors, decoding_table)[0] + +class StreamWriter(Codec, codecs.StreamWriter): + pass + +class StreamReader(Codec, codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='kz1048', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u0402' # 0x80 -> CYRILLIC CAPITAL LETTER DJE + '\u0403' # 0x81 -> CYRILLIC CAPITAL LETTER GJE + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0453' # 0x83 -> CYRILLIC SMALL LETTER GJE + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\u20ac' # 0x88 -> EURO SIGN + '\u2030' # 0x89 -> PER MILLE SIGN + '\u0409' # 0x8A -> CYRILLIC CAPITAL LETTER LJE + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u040a' # 0x8C -> CYRILLIC CAPITAL LETTER NJE + '\u049a' # 0x8D -> CYRILLIC CAPITAL LETTER KA WITH DESCENDER + '\u04ba' # 0x8E -> CYRILLIC CAPITAL LETTER SHHA + '\u040f' # 0x8F -> CYRILLIC CAPITAL LETTER DZHE + '\u0452' # 0x90 -> CYRILLIC SMALL LETTER DJE + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\ufffe' # 0x98 -> UNDEFINED + '\u2122' # 0x99 -> TRADE MARK SIGN + '\u0459' # 0x9A -> CYRILLIC SMALL LETTER LJE + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u045a' # 0x9C -> CYRILLIC SMALL LETTER NJE + '\u049b' # 0x9D -> CYRILLIC SMALL LETTER KA WITH DESCENDER + '\u04bb' # 0x9E -> CYRILLIC SMALL LETTER SHHA + '\u045f' # 0x9F -> CYRILLIC SMALL LETTER DZHE + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u04b0' # 0xA1 -> CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE + '\u04b1' # 0xA2 -> CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE + '\u04d8' # 0xA3 -> CYRILLIC CAPITAL LETTER SCHWA + '\xa4' # 0xA4 -> CURRENCY SIGN + '\u04e8' # 0xA5 -> CYRILLIC CAPITAL LETTER BARRED O + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\u0401' # 0xA8 -> CYRILLIC CAPITAL LETTER IO + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u0492' # 0xAA -> CYRILLIC CAPITAL LETTER GHE WITH STROKE + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\u04ae' # 0xAF -> CYRILLIC CAPITAL LETTER STRAIGHT U + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u0406' # 0xB2 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0456' # 0xB3 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + '\u04e9' # 0xB4 -> CYRILLIC SMALL LETTER BARRED O + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\u0451' # 0xB8 -> CYRILLIC SMALL LETTER IO + '\u2116' # 0xB9 -> NUMERO SIGN + '\u0493' # 0xBA -> CYRILLIC SMALL LETTER GHE WITH STROKE + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u04d9' # 0xBC -> CYRILLIC SMALL LETTER SCHWA + '\u04a2' # 0xBD -> CYRILLIC CAPITAL LETTER EN WITH DESCENDER + '\u04a3' # 0xBE -> CYRILLIC SMALL LETTER EN WITH DESCENDER + '\u04af' # 0xBF -> CYRILLIC SMALL LETTER STRAIGHT U + '\u0410' # 0xC0 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0xC1 -> CYRILLIC CAPITAL LETTER BE + '\u0412' # 0xC2 -> CYRILLIC CAPITAL LETTER VE + '\u0413' # 0xC3 -> CYRILLIC CAPITAL LETTER GHE + '\u0414' # 0xC4 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0xC5 -> CYRILLIC CAPITAL LETTER IE + '\u0416' # 0xC6 -> CYRILLIC CAPITAL LETTER ZHE + '\u0417' # 0xC7 -> CYRILLIC CAPITAL LETTER ZE + '\u0418' # 0xC8 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0xC9 -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0xCA -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0xCB -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0xCC -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0xCD -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0xCE -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0xCF -> CYRILLIC CAPITAL LETTER PE + '\u0420' # 0xD0 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0xD1 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0xD2 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0xD3 -> CYRILLIC CAPITAL LETTER U + '\u0424' # 0xD4 -> CYRILLIC CAPITAL LETTER EF + '\u0425' # 0xD5 -> CYRILLIC CAPITAL LETTER HA + '\u0426' # 0xD6 -> CYRILLIC CAPITAL LETTER TSE + '\u0427' # 0xD7 -> CYRILLIC CAPITAL LETTER CHE + '\u0428' # 0xD8 -> CYRILLIC CAPITAL LETTER SHA + '\u0429' # 0xD9 -> CYRILLIC CAPITAL LETTER SHCHA + '\u042a' # 0xDA -> CYRILLIC CAPITAL LETTER HARD SIGN + '\u042b' # 0xDB -> CYRILLIC CAPITAL LETTER YERU + '\u042c' # 0xDC -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042d' # 0xDD -> CYRILLIC CAPITAL LETTER E + '\u042e' # 0xDE -> CYRILLIC CAPITAL LETTER YU + '\u042f' # 0xDF -> CYRILLIC CAPITAL LETTER YA + '\u0430' # 0xE0 -> CYRILLIC SMALL LETTER A + '\u0431' # 0xE1 -> CYRILLIC SMALL LETTER BE + '\u0432' # 0xE2 -> CYRILLIC SMALL LETTER VE + '\u0433' # 0xE3 -> CYRILLIC SMALL LETTER GHE + '\u0434' # 0xE4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0xE5 -> CYRILLIC SMALL LETTER IE + '\u0436' # 0xE6 -> CYRILLIC SMALL LETTER ZHE + '\u0437' # 0xE7 -> CYRILLIC SMALL LETTER ZE + '\u0438' # 0xE8 -> CYRILLIC SMALL LETTER I + '\u0439' # 0xE9 -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0xEA -> CYRILLIC SMALL LETTER KA + '\u043b' # 0xEB -> CYRILLIC SMALL LETTER EL + '\u043c' # 0xEC -> CYRILLIC SMALL LETTER EM + '\u043d' # 0xED -> CYRILLIC SMALL LETTER EN + '\u043e' # 0xEE -> CYRILLIC SMALL LETTER O + '\u043f' # 0xEF -> CYRILLIC SMALL LETTER PE + '\u0440' # 0xF0 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0xF1 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0xF2 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0xF3 -> CYRILLIC SMALL LETTER U + '\u0444' # 0xF4 -> CYRILLIC SMALL LETTER EF + '\u0445' # 0xF5 -> CYRILLIC SMALL LETTER HA + '\u0446' # 0xF6 -> CYRILLIC SMALL LETTER TSE + '\u0447' # 0xF7 -> CYRILLIC SMALL LETTER CHE + '\u0448' # 0xF8 -> CYRILLIC SMALL LETTER SHA + '\u0449' # 0xF9 -> CYRILLIC SMALL LETTER SHCHA + '\u044a' # 0xFA -> CYRILLIC SMALL LETTER HARD SIGN + '\u044b' # 0xFB -> CYRILLIC SMALL LETTER YERU + '\u044c' # 0xFC -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044d' # 0xFD -> CYRILLIC SMALL LETTER E + '\u044e' # 0xFE -> CYRILLIC SMALL LETTER YU + '\u044f' # 0xFF -> CYRILLIC SMALL LETTER YA +) + +### Encoding table +encoding_table = codecs.charmap_build(decoding_table) diff --git a/Lib/encodings/quopri_codec.py b/Lib/encodings/quopri_codec.py index 70f708379381..496cb7655d03 100644 --- a/Lib/encodings/quopri_codec.py +++ b/Lib/encodings/quopri_codec.py @@ -1,7 +1,6 @@ """Codec for quoted-printable encoding. -This codec de/encodes from bytes to bytes and is therefore usable with -bytes.transform() and bytes.untransform(). +This codec de/encodes from bytes to bytes. """ import codecs @@ -12,7 +11,7 @@ def quopri_encode(input, errors='strict'): assert errors == 'strict' f = BytesIO(input) g = BytesIO() - quopri.encode(f, g, 1) + quopri.encode(f, g, quotetabs=True) return (g.getvalue(), len(input)) def quopri_decode(input, errors='strict'): diff --git a/Lib/encodings/rot_13.py b/Lib/encodings/rot_13.py index fff9153b4c63..f0b4186dc877 100755 --- a/Lib/encodings/rot_13.py +++ b/Lib/encodings/rot_13.py @@ -1,8 +1,7 @@ #!/usr/bin/env python """ Python Character Mapping Codec for ROT13. -This codec de/encodes from str to str and is therefore usable with -str.transform() and str.untransform(). +This codec de/encodes from str to str. Written by Marc-Andre Lemburg (mal@lemburg.com). """ @@ -107,7 +106,7 @@ def getregentry(): ### Filter API def rot13(infile, outfile): - outfile.write(infile.read().encode('rot-13')) + outfile.write(codecs.encode(infile.read(), 'rot-13')) if __name__ == '__main__': import sys diff --git a/Lib/encodings/uu_codec.py b/Lib/encodings/uu_codec.py index e3269e40cd30..2a5728fb5b74 100644 --- a/Lib/encodings/uu_codec.py +++ b/Lib/encodings/uu_codec.py @@ -1,7 +1,6 @@ """Python 'uu_codec' Codec - UU content transfer encoding. -This codec de/encodes from bytes to bytes and is therefore usable with -bytes.transform() and bytes.untransform(). +This codec de/encodes from bytes to bytes. Written by Marc-Andre Lemburg (mal@lemburg.com). Some details were adapted from uu.py which was written by Lance Ellinghouse and @@ -55,7 +54,7 @@ def uu_decode(input, errors='strict'): data = binascii.a2b_uu(s) except binascii.Error as v: # Workaround for broken uuencoders by /Fredrik Lundh - nbytes = (((ord(s[0])-32) & 63) * 4 + 5) / 3 + nbytes = (((s[0]-32) & 63) * 4 + 5) // 3 data = binascii.a2b_uu(s[:nbytes]) #sys.stderr.write("Warning: %s\n" % str(v)) write(data) diff --git a/Lib/encodings/zlib_codec.py b/Lib/encodings/zlib_codec.py index 4c81ca115a7b..95908a4b4a13 100644 --- a/Lib/encodings/zlib_codec.py +++ b/Lib/encodings/zlib_codec.py @@ -1,7 +1,6 @@ """Python 'zlib_codec' Codec - zlib compression encoding. -This codec de/encodes from bytes to bytes and is therefore usable with -bytes.transform() and bytes.untransform(). +This codec de/encodes from bytes to bytes. Written by Marc-Andre Lemburg (mal@lemburg.com). """ diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 63013aec3db2..12588335d943 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -4,15 +4,26 @@ import sys import tempfile -# TODO: Remove the --pre flag when a pip 1.5 final copy is available - __all__ = ["version", "bootstrap"] -_SETUPTOOLS_VERSION = "1.3.2" +_SETUPTOOLS_VERSION = "18.2" + +_PIP_VERSION = "7.1.2" -_PIP_VERSION = "1.5rc1" +# pip currently requires ssl support, so we try to provide a nicer +# error message when that is missing (http://bugs.python.org/issue19744) +_MISSING_SSL_MESSAGE = ("pip {} requires SSL/TLS".format(_PIP_VERSION)) +try: + import ssl +except ImportError: + ssl = None + def _require_ssl_for_pip(): + raise RuntimeError(_MISSING_SSL_MESSAGE) +else: + def _require_ssl_for_pip(): + pass _PROJECTS = [ ("setuptools", _SETUPTOOLS_VERSION), @@ -36,6 +47,17 @@ def version(): """ return _PIP_VERSION +def _disable_pip_configuration_settings(): + # We deliberately ignore all pip environment variables + # when invoking pip + # See http://bugs.python.org/issue19734 for details + keys_to_remove = [k for k in os.environ if k.startswith("PIP_")] + for k in keys_to_remove: + del os.environ[k] + # We also ignore the settings in the default pip configuration file + # See http://bugs.python.org/issue20053 for details + os.environ['PIP_CONFIG_FILE'] = os.devnull + def bootstrap(*, root=None, upgrade=False, user=False, altinstall=False, default_pip=False, @@ -43,10 +65,15 @@ def bootstrap(*, root=None, upgrade=False, user=False, """ Bootstrap pip into the current Python installation (or the given root directory). + + Note that calling this function will alter both sys.path and os.environ. """ if altinstall and default_pip: raise ValueError("Cannot use altinstall and default_pip together") + _require_ssl_for_pip() + _disable_pip_configuration_settings() + # By default, installing pip and setuptools installs all of the # following scripts (X.Y == running Python version): # @@ -76,11 +103,7 @@ def bootstrap(*, root=None, upgrade=False, user=False, additional_paths.append(os.path.join(tmpdir, wheel_name)) # Construct the arguments to be passed to the pip command - args = [ - "install", "--no-index", "--find-links", tmpdir, - # Temporary until pip 1.5 is final - "--pre", - ] + args = ["install", "--no-index", "--find-links", tmpdir] if root: args += ["--root", root] if upgrade: @@ -92,8 +115,11 @@ def bootstrap(*, root=None, upgrade=False, user=False, _run_pip(args + [p[0] for p in _PROJECTS], additional_paths) -def _uninstall(*, verbosity=0): - """Helper to support a clean default uninstall process on Windows""" +def _uninstall_helper(*, verbosity=0): + """Helper to support a clean default uninstall process on Windows + + Note that calling this function may alter os.environ. + """ # Nothing to do if pip was never installed, or has been removed try: import pip @@ -102,13 +128,83 @@ def _uninstall(*, verbosity=0): # If the pip version doesn't match the bundled one, leave it alone if pip.__version__ != _PIP_VERSION: - msg = ("ensurepip will only uninstall a matching pip " + msg = ("ensurepip will only uninstall a matching version " "({!r} installed, {!r} bundled)") - raise RuntimeError(msg.format(pip.__version__, _PIP_VERSION)) + print(msg.format(pip.__version__, _PIP_VERSION), file=sys.stderr) + return + + _require_ssl_for_pip() + _disable_pip_configuration_settings() # Construct the arguments to be passed to the pip command - args = ["uninstall", "-y"] + args = ["uninstall", "-y", "--disable-pip-version-check"] if verbosity: args += ["-" + "v" * verbosity] _run_pip(args + [p[0] for p in reversed(_PROJECTS)]) + + +def _main(argv=None): + if ssl is None: + print("Ignoring ensurepip failure: {}".format(_MISSING_SSL_MESSAGE), + file=sys.stderr) + return + + import argparse + parser = argparse.ArgumentParser(prog="python -m ensurepip") + parser.add_argument( + "--version", + action="http://github.com/version", + version="pip {}".format(version()), + help="Show the version of pip that is bundled with this Python.", + ) + parser.add_argument( + "-v", "--verbose", + action="http://github.com/count", + default=0, + dest="verbosity", + help=("Give more output. Option is additive, and can be used up to 3 " + "times."), + ) + parser.add_argument( + "-U", "--upgrade", + action="http://github.com/store_true", + default=False, + help="Upgrade pip and dependencies, even if already installed.", + ) + parser.add_argument( + "--user", + action="http://github.com/store_true", + default=False, + help="Install using the user scheme.", + ) + parser.add_argument( + "--root", + default=None, + help="Install everything relative to this alternate root directory.", + ) + parser.add_argument( + "--altinstall", + action="http://github.com/store_true", + default=False, + help=("Make an alternate install, installing only the X.Y versioned" + "scripts (Default: pipX, pipX.Y, easy_install-X.Y)"), + ) + parser.add_argument( + "--default-pip", + action="http://github.com/store_true", + default=False, + help=("Make a default pip install, installing the unqualified pip " + "and easy_install in addition to the versioned scripts"), + ) + + args = parser.parse_args(argv) + + bootstrap( + root=args.root, + upgrade=args.upgrade, + user=args.user, + verbosity=args.verbosity, + altinstall=args.altinstall, + default_pip=args.default_pip, + ) diff --git a/Lib/ensurepip/__main__.py b/Lib/ensurepip/__main__.py index 53e84595b38c..77527d7a3513 100644 --- a/Lib/ensurepip/__main__.py +++ b/Lib/ensurepip/__main__.py @@ -1,66 +1,4 @@ -import argparse import ensurepip - -def main(): - parser = argparse.ArgumentParser(prog="python -m ensurepip") - parser.add_argument( - "--version", - action="http://github.com/version", - version="pip {}".format(ensurepip.version()), - help="Show the version of pip that is bundled with this Python.", - ) - parser.add_argument( - "-v", "--verbose", - action="http://github.com/count", - default=0, - dest="verbosity", - help=("Give more output. Option is additive, and can be used up to 3 " - "times."), - ) - parser.add_argument( - "-U", "--upgrade", - action="http://github.com/store_true", - default=False, - help="Upgrade pip and dependencies, even if already installed.", - ) - parser.add_argument( - "--user", - action="http://github.com/store_true", - default=False, - help="Install using the user scheme.", - ) - parser.add_argument( - "--root", - default=None, - help="Install everything relative to this alternate root directory.", - ) - parser.add_argument( - "--altinstall", - action="http://github.com/store_true", - default=False, - help=("Make an alternate install, installing only the X.Y versioned" - "scripts (Default: pipX, pipX.Y, easy_install-X.Y)"), - ) - parser.add_argument( - "--default-pip", - action="http://github.com/store_true", - default=False, - help=("Make a default pip install, installing the unqualified pip " - "and easy_install in addition to the versioned scripts"), - ) - - args = parser.parse_args() - - ensurepip.bootstrap( - root=args.root, - upgrade=args.upgrade, - user=args.user, - verbosity=args.verbosity, - altinstall=args.altinstall, - default_pip=args.default_pip, - ) - - if __name__ == "__main__": - main() + ensurepip._main() diff --git a/Lib/ensurepip/_bundled/pip-1.5rc1-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/pip-1.5rc1-py2.py3-none-any.whl deleted file mode 100644 index 6418895a582a..000000000000 Binary files a/Lib/ensurepip/_bundled/pip-1.5rc1-py2.py3-none-any.whl and /dev/null differ diff --git a/Lib/ensurepip/_bundled/pip-7.1.2-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/pip-7.1.2-py2.py3-none-any.whl new file mode 100644 index 000000000000..5e490155f0ca Binary files /dev/null and b/Lib/ensurepip/_bundled/pip-7.1.2-py2.py3-none-any.whl differ diff --git a/Lib/ensurepip/_bundled/setuptools-1.3.2-py2.py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-18.2-py2.py3-none-any.whl similarity index 55% rename from Lib/ensurepip/_bundled/setuptools-1.3.2-py2.py3-none-any.whl rename to Lib/ensurepip/_bundled/setuptools-18.2-py2.py3-none-any.whl index 81962b10814b..f4288d68e074 100644 Binary files a/Lib/ensurepip/_bundled/setuptools-1.3.2-py2.py3-none-any.whl and b/Lib/ensurepip/_bundled/setuptools-18.2-py2.py3-none-any.whl differ diff --git a/Lib/ensurepip/_uninstall.py b/Lib/ensurepip/_uninstall.py index 38c486b0a2a1..750365ec4d04 100644 --- a/Lib/ensurepip/_uninstall.py +++ b/Lib/ensurepip/_uninstall.py @@ -4,7 +4,7 @@ import ensurepip -def main(): +def _main(argv=None): parser = argparse.ArgumentParser(prog="python -m ensurepip._uninstall") parser.add_argument( "--version", @@ -21,10 +21,10 @@ def main(): "times."), ) - args = parser.parse_args() + args = parser.parse_args(argv) - ensurepip._uninstall(verbosity=args.verbosity) + ensurepip._uninstall_helper(verbosity=args.verbosity) if __name__ == "__main__": - main() + _main() diff --git a/Lib/enum.py b/Lib/enum.py index 7d58f8d17a6e..8d04e2d71861 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -1,7 +1,13 @@ import sys -from collections import OrderedDict from types import MappingProxyType, DynamicClassAttribute +# try _collections first to reduce startup cost +try: + from _collections import OrderedDict +except ImportError: + from collections import OrderedDict + + __all__ = ['Enum', 'IntEnum', 'unique'] @@ -31,9 +37,9 @@ def _is_sunder(name): def _make_class_unpicklable(cls): """Make the given class un-picklable.""" - def _break_on_call_reduce(self): + def _break_on_call_reduce(self, proto): raise TypeError('%r cannot be pickled' % self) - cls.__reduce__ = _break_on_call_reduce + cls.__reduce_ex__ = _break_on_call_reduce cls.__module__ = '' @@ -106,21 +112,39 @@ def __new__(metacls, cls, bases, classdict): raise ValueError('Invalid enum member name: {0}'.format( ','.join(invalid_names))) + # create a default docstring if one has not been provided + if '__doc__' not in classdict: + classdict['__doc__'] = 'An enumeration.' + # create our new Enum type enum_class = super().__new__(metacls, cls, bases, classdict) enum_class._member_names_ = [] # names in definition order enum_class._member_map_ = OrderedDict() # name->value map enum_class._member_type_ = member_type + # save attributes from super classes so we know if we can take + # the shortcut of storing members in the class dict + base_attributes = {a for b in bases for a in b.__dict__} + # Reverse value->name map for hashable values. enum_class._value2member_map_ = {} - # check for a __getnewargs__, and if not present sabotage - # pickling, since it won't work anyway - if (member_type is not object and - member_type.__dict__.get('__getnewargs__') is None - ): - _make_class_unpicklable(enum_class) + # If a custom type is mixed into the Enum, and it does not know how + # to pickle itself, pickle.dumps will succeed but pickle.loads will + # fail. Rather than have the error show up later and possibly far + # from the source, sabotage the pickle protocol for this class so + # that pickle.dumps also fails. + # + # However, if the new class implements its own __reduce_ex__, do not + # sabotage -- it's on them to make sure it works correctly. We use + # __reduce_ex__ instead of any of the others as it is preferred by + # pickle over __reduce__, and it handles all pickle protocols. + if '__reduce_ex__' not in classdict: + if member_type is not object: + methods = ('__getnewargs_ex__', '__getnewargs__', + '__reduce_ex__', '__reduce__') + if not any(m in member_type.__dict__ for m in methods): + _make_class_unpicklable(enum_class) # instantiate them, checking for duplicates as we go # we instantiate first instead of checking for duplicates first in case @@ -149,12 +173,17 @@ def __new__(metacls, cls, bases, classdict): # If another member with the same value was already defined, the # new member becomes an alias to the existing one. for name, canonical_member in enum_class._member_map_.items(): - if canonical_member.value == enum_member._value_: + if canonical_member._value_ == enum_member._value_: enum_member = canonical_member break else: # Aliases don't appear in member names (only in __members__). enum_class._member_names_.append(member_name) + # performance boost for any member that would not shadow + # a DynamicClassAttribute + if member_name not in base_attributes: + setattr(enum_class, member_name, enum_member) + # now add to _member_map_ enum_class._member_map_[member_name] = enum_member try: # This may fail if value is not hashable. We can't add the value @@ -166,7 +195,7 @@ def __new__(metacls, cls, bases, classdict): # double check that repr and friends are not the mixin's or various # things break (such as pickle) - for name in ('__repr__', '__str__', '__format__', '__getnewargs__'): + for name in ('__repr__', '__str__', '__format__', '__reduce_ex__'): class_method = getattr(enum_class, name) obj_method = getattr(member_type, name, None) enum_method = getattr(first_enum, name, None) @@ -183,29 +212,38 @@ def __new__(metacls, cls, bases, classdict): enum_class.__new__ = Enum.__new__ return enum_class - def __call__(cls, value, names=None, *, module=None, type=None): + def __call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1): """Either returns an existing member, or creates a new enum class. This method is used both when an enum class is given a value to match to an enumeration member (i.e. Color(3)) and for the functional API (i.e. Color = Enum('Color', names='red green blue')). - When used for the functional API: `module`, if set, will be stored in - the new class' __module__ attribute; `type`, if set, will be mixed in - as the first base class. + When used for the functional API: + + `value` will be the name of the new class. + + `names` should be either a string of white-space/comma delimited names + (values will start at `start`), or an iterator/mapping of name, value pairs. + + `module` should be set to the module this class is being created in; + if it is not set, an attempt to find that module will be made, but if + it fails the class will not be picklable. + + `qualname` should be set to the actual location this class can be found + at in its module; by default it is set to the global scope. If this is + not correct, unpickling will fail in some circumstances. - Note: if `module` is not set this routine will attempt to discover the - calling module by walking the frame stack; if this is unsuccessful - the resulting class will not be pickleable. + `type`, if set, will be mixed in as the first base class. """ if names is None: # simple value lookup return cls.__new__(cls, value) # otherwise, functional API: we're creating a new Enum type - return cls._create_(value, names, module=module, type=type) + return cls._create_(value, names, module=module, qualname=qualname, type=type, start=start) def __contains__(cls, member): - return isinstance(member, cls) and member.name in cls._member_map_ + return isinstance(member, cls) and member._name_ in cls._member_map_ def __delattr__(cls, attr): # nicer error message when someone tries to delete an attribute @@ -273,16 +311,16 @@ def __setattr__(cls, name, value): raise AttributeError('Cannot reassign members.') super().__setattr__(name, value) - def _create_(cls, class_name, names=None, *, module=None, type=None): + def _create_(cls, class_name, names=None, *, module=None, qualname=None, type=None, start=1): """Convenience method to create a new Enum class. `names` can be: * A string containing member names, separated either with spaces or - commas. Values are auto-numbered from 1. - * An iterable of member names. Values are auto-numbered from 1. + commas. Values are incremented by 1 from `start`. + * An iterable of member names. Values are incremented by 1 from `start`. * An iterable of (member name, value) pairs. - * A mapping of member name -> value. + * A mapping of member name -> value pairs. """ metacls = cls.__class__ @@ -293,7 +331,7 @@ def _create_(cls, class_name, names=None, *, module=None, type=None): if isinstance(names, str): names = names.replace(',', ' ').split() if isinstance(names, (tuple, list)) and isinstance(names[0], str): - names = [(e, i) for (i, e) in enumerate(names, 1)] + names = [(e, i) for (i, e) in enumerate(names, start)] # Here, names is either an iterable of (name, value) or a mapping. for item in names: @@ -315,6 +353,8 @@ def _create_(cls, class_name, names=None, *, module=None, type=None): _make_class_unpicklable(enum_class) else: enum_class.__module__ = module + if qualname is not None: + enum_class.__qualname__ = qualname return enum_class @@ -431,9 +471,9 @@ def __new__(cls, value): except TypeError: # not there, now do long search -- O(n) behavior for member in cls._member_map_.values(): - if member.value == value: + if member._value_ == value: return member - raise ValueError("%s is not a valid %s" % (value, cls.__name__)) + raise ValueError("%r is not a valid %s" % (value, cls.__name__)) def __repr__(self): return "<%s.%s: %r>" % ( @@ -442,10 +482,17 @@ def __repr__(self): def __str__(self): return "%s.%s" % (self.__class__.__name__, self._name_) + def __bool__(self): + return bool(self._value_) + def __dir__(self): - added_behavior = [m for m in self.__class__.__dict__ if m[0] != '_'] - return (['__class__', '__doc__', '__module__', 'name', 'value'] + - added_behavior) + added_behavior = [ + m + for cls in self.__class__.mro() + for m in cls.__dict__ + if m[0] != '_' and m not in self._member_map_ + ] + return (['__class__', '__doc__', '__module__'] + added_behavior) def __format__(self, format_spec): # mixed-in Enums should use the mixed-in type's __format__, otherwise @@ -459,15 +506,15 @@ def __format__(self, format_spec): # mix-in branch else: cls = self._member_type_ - val = self.value + val = self._value_ return cls.__format__(val, format_spec) - def __getnewargs__(self): - return (self._value_, ) - def __hash__(self): return hash(self._name_) + def __reduce_ex__(self, proto): + return self.__class__, (self._value_, ) + # DynamicClassAttribute is used to provide access to the `name` and # `value` properties of enum members while keeping some measure of # protection from modification, while still allowing for an enumeration @@ -485,11 +532,37 @@ def value(self): """The value of the Enum member.""" return self._value_ + @classmethod + def _convert(cls, name, module, filter, source=None): + """ + Create a new Enum subclass that replaces a collection of global constants + """ + # convert all constants from source (or module) that pass filter() to + # a new Enum called name, and export the enum and its members back to + # module; + # also, replace the __reduce_ex__ method so unpickling works in + # previous Python versions + module_globals = vars(sys.modules[module]) + if source: + source = vars(source) + else: + source = module_globals + members = {name: value for name, value in source.items() + if filter(name)} + cls = cls(name, members, module=module) + cls.__reduce_ex__ = _reduce_ex_by_name + module_globals.update(cls.__members__) + module_globals[name] = cls + return cls + class IntEnum(int, Enum): """Enum where members are also (and must be) ints""" +def _reduce_ex_by_name(self, proto): + return self.name + def unique(enumeration): """Class decorator for enumerations ensuring unique member values.""" duplicates = [] diff --git a/Lib/filecmp.py b/Lib/filecmp.py index 328528871ade..e5ad8397e4c5 100644 --- a/Lib/filecmp.py +++ b/Lib/filecmp.py @@ -36,15 +36,15 @@ def cmp(f1, f2, shallow=True): f2 -- Second file name shallow -- Just check stat signature (do not read the files). - defaults to 1. + defaults to True. Return value: True if the files are the same, False otherwise. This function uses a cache for past comparisons and the results, - with a cache invalidation mechanism relying on stale signatures - or by explicitly calling clear_cache(). + with cache entries invalidated if their stat information + changes. The cache may be cleared by calling clear_cache(). """ diff --git a/Lib/fileinput.py b/Lib/fileinput.py index de2951844aef..af810d1d732e 100644 --- a/Lib/fileinput.py +++ b/Lib/fileinput.py @@ -238,8 +238,10 @@ def __del__(self): self.close() def close(self): - self.nextfile() - self._files = () + try: + self.nextfile() + finally: + self._files = () def __enter__(self): return self @@ -275,29 +277,31 @@ def __getitem__(self, i): def nextfile(self): savestdout = self._savestdout - self._savestdout = 0 + self._savestdout = None if savestdout: sys.stdout = savestdout output = self._output - self._output = 0 - if output: - output.close() - - file = self._file - self._file = 0 - if file and not self._isstdin: - file.close() - - backupfilename = self._backupfilename - self._backupfilename = 0 - if backupfilename and not self._backup: - try: os.unlink(backupfilename) - except OSError: pass - - self._isstdin = False - self._buffer = [] - self._bufindex = 0 + self._output = None + try: + if output: + output.close() + finally: + file = self._file + self._file = None + try: + if file and not self._isstdin: + file.close() + finally: + backupfilename = self._backupfilename + self._backupfilename = None + if backupfilename and not self._backup: + try: os.unlink(backupfilename) + except OSError: pass + + self._isstdin = False + self._buffer = [] + self._bufindex = 0 def readline(self): try: @@ -320,7 +324,10 @@ def readline(self): self._backupfilename = 0 if self._filename == '-': self._filename = '' - self._file = sys.stdin + if 'b' in self._mode: + self._file = sys.stdin.buffer + else: + self._file = sys.stdin self._isstdin = True else: if self._inplace: diff --git a/Lib/formatter.py b/Lib/formatter.py index d8cca52e307f..e2394de8c291 100644 --- a/Lib/formatter.py +++ b/Lib/formatter.py @@ -20,8 +20,8 @@ import sys import warnings -warnings.warn('the formatter module is deprecated and will be removed in ' - 'Python 3.6', PendingDeprecationWarning) +warnings.warn('the formatter module is deprecated', DeprecationWarning, + stacklevel=2) AS_IS = None @@ -436,11 +436,15 @@ def test(file = None): fp = open(sys.argv[1]) else: fp = sys.stdin - for line in fp: - if line == '\n': - f.end_paragraph(1) - else: - f.add_flowing_data(line) + try: + for line in fp: + if line == '\n': + f.end_paragraph(1) + else: + f.add_flowing_data(line) + finally: + if fp is not sys.stdin: + fp.close() f.end_paragraph(0) diff --git a/Lib/fractions.py b/Lib/fractions.py index 79e83ff2c00d..60b072880703 100644 --- a/Lib/fractions.py +++ b/Lib/fractions.py @@ -20,6 +20,17 @@ def gcd(a, b): Unless b==0, the result will have the same sign as b (so that when b is divided by it, the result comes out positive). """ + import warnings + warnings.warn('fractions.gcd() is deprecated. Use math.gcd() instead.', + DeprecationWarning, 2) + if type(a) is int is type(b): + if (b or a) < 0: + return -math.gcd(a, b) + return math.gcd(a, b) + return _gcd(a, b) + +def _gcd(a, b): + # Supports non-integers for backward compatibility. while b: a, b = b, a%b return a @@ -70,7 +81,7 @@ class Fraction(numbers.Rational): __slots__ = ('_numerator', '_denominator') # We're immutable, so use __new__ not __init__ - def __new__(cls, numerator=0, denominator=None): + def __new__(cls, numerator=0, denominator=None, _normalize=True): """Constructs a Rational. Takes a string like '3/2' or '1.5', another Rational instance, a @@ -104,7 +115,12 @@ def __new__(cls, numerator=0, denominator=None): self = super(Fraction, cls).__new__(cls) if denominator is None: - if isinstance(numerator, numbers.Rational): + if type(numerator) is int: + self._numerator = numerator + self._denominator = 1 + return self + + elif isinstance(numerator, numbers.Rational): self._numerator = numerator.numerator self._denominator = numerator.denominator return self @@ -153,6 +169,9 @@ def __new__(cls, numerator=0, denominator=None): raise TypeError("argument should be a string " "or a Rational instance") + elif type(numerator) is int is type(denominator): + pass # *very* normal case + elif (isinstance(numerator, numbers.Rational) and isinstance(denominator, numbers.Rational)): numerator, denominator = ( @@ -165,9 +184,18 @@ def __new__(cls, numerator=0, denominator=None): if denominator == 0: raise ZeroDivisionError('Fraction(%s, 0)' % numerator) - g = gcd(numerator, denominator) - self._numerator = numerator // g - self._denominator = denominator // g + if _normalize: + if type(numerator) is int is type(denominator): + # *very* normal case + g = math.gcd(numerator, denominator) + if denominator < 0: + g = -g + else: + g = _gcd(numerator, denominator) + numerator //= g + denominator //= g + self._numerator = numerator + self._denominator = denominator return self @classmethod @@ -277,7 +305,8 @@ def denominator(a): def __repr__(self): """repr(self)""" - return ('Fraction(%s, %s)' % (self._numerator, self._denominator)) + return '%s(%s, %s)' % (self.__class__.__name__, + self._numerator, self._denominator) def __str__(self): """str(self)""" @@ -395,17 +424,17 @@ def reverse(b, a): def _add(a, b): """a + b""" - return Fraction(a.numerator * b.denominator + - b.numerator * a.denominator, - a.denominator * b.denominator) + da, db = a.denominator, b.denominator + return Fraction(a.numerator * db + b.numerator * da, + da * db) __add__, __radd__ = _operator_fallbacks(_add, operator.add) def _sub(a, b): """a - b""" - return Fraction(a.numerator * b.denominator - - b.numerator * a.denominator, - a.denominator * b.denominator) + da, db = a.denominator, b.denominator + return Fraction(a.numerator * db - b.numerator * da, + da * db) __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub) @@ -453,10 +482,12 @@ def __pow__(a, b): power = b.numerator if power >= 0: return Fraction(a._numerator ** power, - a._denominator ** power) + a._denominator ** power, + _normalize=False) else: return Fraction(a._denominator ** -power, - a._numerator ** -power) + a._numerator ** -power, + _normalize=False) else: # A fractional power will generally produce an # irrational number. @@ -480,15 +511,15 @@ def __rpow__(b, a): def __pos__(a): """+a: Coerces a subclass instance to Fraction""" - return Fraction(a._numerator, a._denominator) + return Fraction(a._numerator, a._denominator, _normalize=False) def __neg__(a): """-a""" - return Fraction(-a._numerator, a._denominator) + return Fraction(-a._numerator, a._denominator, _normalize=False) def __abs__(a): """abs(a)""" - return Fraction(abs(a._numerator), a._denominator) + return Fraction(abs(a._numerator), a._denominator, _normalize=False) def __trunc__(a): """trunc(a)""" @@ -555,6 +586,8 @@ def __hash__(self): def __eq__(a, b): """a == b""" + if type(b) is int: + return a._numerator == b and a._denominator == 1 if isinstance(b, numbers.Rational): return (a._numerator == b.numerator and a._denominator == b.denominator) diff --git a/Lib/ftplib.py b/Lib/ftplib.py index 2cc470258e18..54b0e2cfcb33 100644 --- a/Lib/ftplib.py +++ b/Lib/ftplib.py @@ -42,7 +42,7 @@ import warnings from socket import _GLOBAL_DEFAULT_TIMEOUT -__all__ = ["FTP", "Netrc"] +__all__ = ["FTP"] # Magic number from MSG_OOB = 0x1 # Process data out of band @@ -320,7 +320,6 @@ def makeport(self): raise err else: raise OSError("getaddrinfo returns an empty list") - raise OSError(msg) sock.listen(1) port = sock.getsockname()[1] # Get proper port host = self.sock.getsockname()[0] # Get proper host @@ -668,11 +667,16 @@ def quit(self): def close(self): '''Close the connection without assuming anything about it.''' - if self.file is not None: - self.file.close() - if self.sock is not None: - self.sock.close() - self.file = self.sock = None + try: + file = self.file + self.file = None + if file is not None: + file.close() + finally: + sock = self.sock + self.sock = None + if sock is not None: + sock.close() try: import ssl @@ -714,7 +718,7 @@ class FTP_TLS(FTP): '221 Goodbye.' >>> ''' - ssl_version = ssl.PROTOCOL_TLSv1 + ssl_version = ssl.PROTOCOL_SSLv23 def __init__(self, host='', user='', passwd='', acct='', keyfile=None, certfile=None, context=None, @@ -744,13 +748,12 @@ def auth(self): '''Set up secure control connection by using TLS/SSL.''' if isinstance(self.sock, ssl.SSLSocket): raise ValueError("Already using TLS") - if self.ssl_version == ssl.PROTOCOL_TLSv1: + if self.ssl_version >= ssl.PROTOCOL_SSLv23: resp = self.voidcmd('AUTH TLS') else: resp = self.voidcmd('AUTH SSL') - server_hostname = self.host if ssl.HAS_SNI else None self.sock = self.context.wrap_socket(self.sock, - server_hostname=server_hostname) + server_hostname=self.host) self.file = self.sock.makefile(mode='r', encoding=self.encoding) return resp @@ -789,9 +792,8 @@ def prot_c(self): def ntransfercmd(self, cmd, rest=None): conn, size = FTP.ntransfercmd(self, cmd, rest) if self._prot_p: - server_hostname = self.host if ssl.HAS_SNI else None conn = self.context.wrap_socket(conn, - server_hostname=server_hostname) + server_hostname=self.host) return conn, size def abort(self): @@ -921,115 +923,6 @@ def ftpcp(source, sourcename, target, targetname = '', type = 'I'): target.voidresp() -class Netrc: - """Class to parse & provide access to 'netrc' format files. - - See the netrc(4) man page for information on the file format. - - WARNING: This class is obsolete -- use module netrc instead. - - """ - __defuser = None - __defpasswd = None - __defacct = None - - def __init__(self, filename=None): - warnings.warn("This class is deprecated, use the netrc module instead", - DeprecationWarning, 2) - if filename is None: - if "HOME" in os.environ: - filename = os.path.join(os.environ["HOME"], - ".netrc") - else: - raise OSError("specify file to load or set $HOME") - self.__hosts = {} - self.__macros = {} - fp = open(filename, "r") - in_macro = 0 - while 1: - line = fp.readline() - if not line: - break - if in_macro and line.strip(): - macro_lines.append(line) - continue - elif in_macro: - self.__macros[macro_name] = tuple(macro_lines) - in_macro = 0 - words = line.split() - host = user = passwd = acct = None - default = 0 - i = 0 - while i < len(words): - w1 = words[i] - if i+1 < len(words): - w2 = words[i + 1] - else: - w2 = None - if w1 == 'default': - default = 1 - elif w1 == 'machine' and w2: - host = w2.lower() - i = i + 1 - elif w1 == 'login' and w2: - user = w2 - i = i + 1 - elif w1 == 'password' and w2: - passwd = w2 - i = i + 1 - elif w1 == 'account' and w2: - acct = w2 - i = i + 1 - elif w1 == 'macdef' and w2: - macro_name = w2 - macro_lines = [] - in_macro = 1 - break - i = i + 1 - if default: - self.__defuser = user or self.__defuser - self.__defpasswd = passwd or self.__defpasswd - self.__defacct = acct or self.__defacct - if host: - if host in self.__hosts: - ouser, opasswd, oacct = \ - self.__hosts[host] - user = user or ouser - passwd = passwd or opasswd - acct = acct or oacct - self.__hosts[host] = user, passwd, acct - fp.close() - - def get_hosts(self): - """Return a list of hosts mentioned in the .netrc file.""" - return self.__hosts.keys() - - def get_account(self, host): - """Returns login information for the named host. - - The return value is a triple containing userid, - password, and the accounting field. - - """ - host = host.lower() - user = passwd = acct = None - if host in self.__hosts: - user, passwd, acct = self.__hosts[host] - user = user or self.__defuser - passwd = passwd or self.__defpasswd - acct = acct or self.__defacct - return user, passwd, acct - - def get_macros(self): - """Return a list of all defined macro names.""" - return self.__macros.keys() - - def get_macro(self, macro): - """Return a sequence of lines which define a named macro.""" - return self.__macros[macro] - - - def test(): '''Test program. Usage: ftp [-d] [-r[file]] host [-l[dir]] [-d[dir]] [-p] [file] ... @@ -1043,6 +936,8 @@ def test(): print(test.__doc__) sys.exit(0) + import netrc + debugging = 0 rcfile = None while sys.argv[1] == '-d': @@ -1057,14 +952,14 @@ def test(): ftp.set_debuglevel(debugging) userid = passwd = acct = '' try: - netrc = Netrc(rcfile) + netrcobj = netrc.netrc(rcfile) except OSError: if rcfile is not None: sys.stderr.write("Could not open account file" " -- using anonymous login.") else: try: - userid, passwd, acct = netrc.get_account(host) + userid, acct, passwd = netrcobj.authenticators(host) except KeyError: # no account for host sys.stderr.write( diff --git a/Lib/functools.py b/Lib/functools.py index 1e79b31140b9..06a4ff13664d 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -19,11 +19,11 @@ pass from abc import get_cache_token from collections import namedtuple -from types import MappingProxyType, MethodType +from types import MappingProxyType from weakref import WeakKeyDictionary try: from _thread import RLock -except: +except ImportError: class RLock: 'Dummy reentrant lock for builds without threads' def __enter__(self): pass @@ -89,101 +89,116 @@ def wraps(wrapped, ### total_ordering class decorator ################################################################################ -# The correct way to indicate that a comparison operation doesn't -# recognise the other type is to return NotImplemented and let the -# interpreter handle raising TypeError if both operands return -# NotImplemented from their respective comparison methods -# -# This makes the implementation of total_ordering more complicated, since -# we need to be careful not to trigger infinite recursion when two -# different types that both use this decorator encounter each other. -# -# For example, if a type implements __lt__, it's natural to define -# __gt__ as something like: -# -# lambda self, other: not self < other and not self == other -# -# However, using the operator syntax like that ends up invoking the full -# type checking machinery again and means we can end up bouncing back and -# forth between the two operands until we run out of stack space. -# -# The solution is to define helper functions that invoke the appropriate -# magic methods directly, ensuring we only try each operand once, and -# return NotImplemented immediately if it is returned from the -# underlying user provided method. Using this scheme, the __gt__ derived -# from a user provided __lt__ becomes: -# -# lambda self, other: _not_op_and_not_eq(self.__lt__, self, other)) - -def _not_op(op, other): - # "not a < b" handles "a >= b" - # "not a <= b" handles "a > b" - # "not a >= b" handles "a < b" - # "not a > b" handles "a <= b" - op_result = op(other) +# The total ordering functions all invoke the root magic method directly +# rather than using the corresponding operator. This avoids possible +# infinite recursion that could occur when the operator dispatch logic +# detects a NotImplemented result and then calls a reflected method. + +def _gt_from_lt(self, other, NotImplemented=NotImplemented): + 'Return a > b. Computed by @total_ordering from (not a < b) and (a != b).' + op_result = self.__lt__(other) + if op_result is NotImplemented: + return op_result + return not op_result and self != other + +def _le_from_lt(self, other, NotImplemented=NotImplemented): + 'Return a <= b. Computed by @total_ordering from (a < b) or (a == b).' + op_result = self.__lt__(other) + return op_result or self == other + +def _ge_from_lt(self, other, NotImplemented=NotImplemented): + 'Return a >= b. Computed by @total_ordering from (not a < b).' + op_result = self.__lt__(other) if op_result is NotImplemented: - return NotImplemented + return op_result return not op_result -def _op_or_eq(op, self, other): - # "a < b or a == b" handles "a <= b" - # "a > b or a == b" handles "a >= b" - op_result = op(other) +def _ge_from_le(self, other, NotImplemented=NotImplemented): + 'Return a >= b. Computed by @total_ordering from (not a <= b) or (a == b).' + op_result = self.__le__(other) if op_result is NotImplemented: - return NotImplemented - return op_result or self == other + return op_result + return not op_result or self == other -def _not_op_and_not_eq(op, self, other): - # "not (a < b or a == b)" handles "a > b" - # "not a < b and a != b" is equivalent - # "not (a > b or a == b)" handles "a < b" - # "not a > b and a != b" is equivalent - op_result = op(other) +def _lt_from_le(self, other, NotImplemented=NotImplemented): + 'Return a < b. Computed by @total_ordering from (a <= b) and (a != b).' + op_result = self.__le__(other) if op_result is NotImplemented: - return NotImplemented + return op_result + return op_result and self != other + +def _gt_from_le(self, other, NotImplemented=NotImplemented): + 'Return a > b. Computed by @total_ordering from (not a <= b).' + op_result = self.__le__(other) + if op_result is NotImplemented: + return op_result + return not op_result + +def _lt_from_gt(self, other, NotImplemented=NotImplemented): + 'Return a < b. Computed by @total_ordering from (not a > b) and (a != b).' + op_result = self.__gt__(other) + if op_result is NotImplemented: + return op_result return not op_result and self != other -def _not_op_or_eq(op, self, other): - # "not a <= b or a == b" handles "a >= b" - # "not a >= b or a == b" handles "a <= b" - op_result = op(other) +def _ge_from_gt(self, other, NotImplemented=NotImplemented): + 'Return a >= b. Computed by @total_ordering from (a > b) or (a == b).' + op_result = self.__gt__(other) + return op_result or self == other + +def _le_from_gt(self, other, NotImplemented=NotImplemented): + 'Return a <= b. Computed by @total_ordering from (not a > b).' + op_result = self.__gt__(other) if op_result is NotImplemented: - return NotImplemented + return op_result + return not op_result + +def _le_from_ge(self, other, NotImplemented=NotImplemented): + 'Return a <= b. Computed by @total_ordering from (not a >= b) or (a == b).' + op_result = self.__ge__(other) + if op_result is NotImplemented: + return op_result return not op_result or self == other -def _op_and_not_eq(op, self, other): - # "a <= b and not a == b" handles "a < b" - # "a >= b and not a == b" handles "a > b" - op_result = op(other) +def _gt_from_ge(self, other, NotImplemented=NotImplemented): + 'Return a > b. Computed by @total_ordering from (a >= b) and (a != b).' + op_result = self.__ge__(other) if op_result is NotImplemented: - return NotImplemented + return op_result return op_result and self != other +def _lt_from_ge(self, other, NotImplemented=NotImplemented): + 'Return a < b. Computed by @total_ordering from (not a >= b).' + op_result = self.__ge__(other) + if op_result is NotImplemented: + return op_result + return not op_result + +_convert = { + '__lt__': [('__gt__', _gt_from_lt), + ('__le__', _le_from_lt), + ('__ge__', _ge_from_lt)], + '__le__': [('__ge__', _ge_from_le), + ('__lt__', _lt_from_le), + ('__gt__', _gt_from_le)], + '__gt__': [('__lt__', _lt_from_gt), + ('__ge__', _ge_from_gt), + ('__le__', _le_from_gt)], + '__ge__': [('__le__', _le_from_ge), + ('__gt__', _gt_from_ge), + ('__lt__', _lt_from_ge)] +} + def total_ordering(cls): """Class decorator that fills in missing ordering methods""" - convert = { - '__lt__': [('__gt__', lambda self, other: _not_op_and_not_eq(self.__lt__, self, other)), - ('__le__', lambda self, other: _op_or_eq(self.__lt__, self, other)), - ('__ge__', lambda self, other: _not_op(self.__lt__, other))], - '__le__': [('__ge__', lambda self, other: _not_op_or_eq(self.__le__, self, other)), - ('__lt__', lambda self, other: _op_and_not_eq(self.__le__, self, other)), - ('__gt__', lambda self, other: _not_op(self.__le__, other))], - '__gt__': [('__lt__', lambda self, other: _not_op_and_not_eq(self.__gt__, self, other)), - ('__ge__', lambda self, other: _op_or_eq(self.__gt__, self, other)), - ('__le__', lambda self, other: _not_op(self.__gt__, other))], - '__ge__': [('__le__', lambda self, other: _not_op_or_eq(self.__ge__, self, other)), - ('__gt__', lambda self, other: _op_and_not_eq(self.__ge__, self, other)), - ('__lt__', lambda self, other: _not_op(self.__ge__, other))] - } # Find user-defined comparisons (not those inherited from object). - roots = [op for op in convert if getattr(cls, op, None) is not getattr(object, op, None)] + roots = [op for op in _convert if getattr(cls, op, None) is not getattr(object, op, None)] if not roots: raise ValueError('must define at least one ordering operation: < > <= >=') root = max(roots) # prefer __lt__ to __le__ to __gt__ to __ge__ - for opname, opfunc in convert[root]: + for opname, opfunc in _convert[root]: if opname not in roots: opfunc.__name__ = opname - opfunc.__doc__ = getattr(int, opname).__doc__ setattr(cls, opname, opfunc) return cls @@ -208,8 +223,6 @@ def __le__(self, other): return mycmp(self.obj, other.obj) <= 0 def __ge__(self, other): return mycmp(self.obj, other.obj) >= 0 - def __ne__(self, other): - return mycmp(self.obj, other.obj) != 0 __hash__ = None return K @@ -228,6 +241,14 @@ def partial(func, *args, **keywords): """New function with partial application of the given arguments and keywords. """ + if hasattr(func, 'func'): + args = func.args + args + tmpkw = func.keywords.copy() + tmpkw.update(keywords) + keywords = tmpkw + del tmpkw + func = func.func + def newfunc(*fargs, **fkeywords): newkeywords = keywords.copy() newkeywords.update(fkeywords) @@ -277,7 +298,7 @@ def __repr__(self): for k, v in self.keywords.items()) format_string = "{module}.{cls}({func}, {args}, {keywords})" return format_string.format(module=self.__class__.__module__, - cls=self.__class__.__name__, + cls=self.__class__.__qualname__, func=self.func, args=args, keywords=keywords) @@ -290,6 +311,7 @@ def _method(*args, **keywords): call_args = (cls_or_self,) + self.args + tuple(rest) return self.func(*call_args, **call_keywords) _method.__isabstractmethod__ = self.__isabstractmethod__ + _method._partialmethod = self return _method def __get__(self, obj, cls): @@ -391,120 +413,135 @@ def lru_cache(maxsize=128, typed=False): # The internals of the lru_cache are encapsulated for thread safety and # to allow the implementation to change (including a possible C version). + # Early detection of an erroneous call to @lru_cache without any arguments + # resulting in the inner function being passed to maxsize instead of an + # integer or None. + if maxsize is not None and not isinstance(maxsize, int): + raise TypeError('Expected maxsize to be an integer or None') + + def decorating_function(user_function): + wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo) + return update_wrapper(wrapper, user_function) + + return decorating_function + +def _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo): # Constants shared by all lru cache instances: sentinel = object() # unique object used to signal cache misses make_key = _make_key # build a key from the function arguments PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names for the link fields - def decorating_function(user_function): - cache = {} - hits = misses = 0 - full = False - cache_get = cache.get # bound method to lookup a key or return None - lock = RLock() # because linkedlist updates aren't threadsafe - root = [] # root of the circular doubly linked list - root[:] = [root, root, None, None] # initialize by pointing to self - - if maxsize == 0: - - def wrapper(*args, **kwds): - # No caching -- just a statistics update after a successful call - nonlocal misses - result = user_function(*args, **kwds) - misses += 1 + cache = {} + hits = misses = 0 + full = False + cache_get = cache.get # bound method to lookup a key or return None + lock = RLock() # because linkedlist updates aren't threadsafe + root = [] # root of the circular doubly linked list + root[:] = [root, root, None, None] # initialize by pointing to self + + if maxsize == 0: + + def wrapper(*args, **kwds): + # No caching -- just a statistics update after a successful call + nonlocal misses + result = user_function(*args, **kwds) + misses += 1 + return result + + elif maxsize is None: + + def wrapper(*args, **kwds): + # Simple caching without ordering or size limit + nonlocal hits, misses + key = make_key(args, kwds, typed) + result = cache_get(key, sentinel) + if result is not sentinel: + hits += 1 return result + result = user_function(*args, **kwds) + cache[key] = result + misses += 1 + return result - elif maxsize is None: + else: - def wrapper(*args, **kwds): - # Simple caching without ordering or size limit - nonlocal hits, misses - key = make_key(args, kwds, typed) - result = cache_get(key, sentinel) - if result is not sentinel: + def wrapper(*args, **kwds): + # Size limited caching that tracks accesses by recency + nonlocal root, hits, misses, full + key = make_key(args, kwds, typed) + with lock: + link = cache_get(key) + if link is not None: + # Move the link to the front of the circular queue + link_prev, link_next, _key, result = link + link_prev[NEXT] = link_next + link_next[PREV] = link_prev + last = root[PREV] + last[NEXT] = root[PREV] = link + link[PREV] = last + link[NEXT] = root hits += 1 return result - result = user_function(*args, **kwds) - cache[key] = result + result = user_function(*args, **kwds) + with lock: + if key in cache: + # Getting here means that this same key was added to the + # cache while the lock was released. Since the link + # update is already done, we need only return the + # computed result and update the count of misses. + pass + elif full: + # Use the old root to store the new key and result. + oldroot = root + oldroot[KEY] = key + oldroot[RESULT] = result + # Empty the oldest link and make it the new root. + # 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. + root = oldroot[NEXT] + oldkey = root[KEY] + oldresult = root[RESULT] + root[KEY] = root[RESULT] = None + # Now update the cache dictionary. + del cache[oldkey] + # Save the potentially reentrant cache[key] assignment + # for last, after the root and links have been put in + # a consistent state. + cache[key] = oldroot + else: + # Put result in a new link at the front of the queue. + last = root[PREV] + link = [last, root, key, result] + last[NEXT] = root[PREV] = cache[key] = link + full = (len(cache) >= maxsize) misses += 1 - return result + return result - else: + def cache_info(): + """Report cache statistics""" + with lock: + return _CacheInfo(hits, misses, maxsize, len(cache)) - def wrapper(*args, **kwds): - # Size limited caching that tracks accesses by recency - nonlocal root, hits, misses, full - key = make_key(args, kwds, typed) - with lock: - link = cache_get(key) - if link is not None: - # Move the link to the front of the circular queue - link_prev, link_next, _key, result = link - link_prev[NEXT] = link_next - link_next[PREV] = link_prev - last = root[PREV] - last[NEXT] = root[PREV] = link - link[PREV] = last - link[NEXT] = root - hits += 1 - return result - result = user_function(*args, **kwds) - with lock: - if key in cache: - # Getting here means that this same key was added to the - # cache while the lock was released. Since the link - # update is already done, we need only return the - # computed result and update the count of misses. - pass - elif full: - # Use the old root to store the new key and result. - oldroot = root - oldroot[KEY] = key - oldroot[RESULT] = result - # Empty the oldest link and make it the new root. - # 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. - root = oldroot[NEXT] - oldkey = root[KEY] - oldresult = root[RESULT] - root[KEY] = root[RESULT] = None - # Now update the cache dictionary. - del cache[oldkey] - # Save the potentially reentrant cache[key] assignment - # for last, after the root and links have been put in - # a consistent state. - cache[key] = oldroot - else: - # Put result in a new link at the front of the queue. - last = root[PREV] - link = [last, root, key, result] - last[NEXT] = root[PREV] = cache[key] = link - full = (len(cache) >= maxsize) - misses += 1 - return result + def cache_clear(): + """Clear the cache and cache statistics""" + nonlocal hits, misses, full + with lock: + cache.clear() + root[:] = [root, root, None, None] + hits = misses = 0 + full = False - def cache_info(): - """Report cache statistics""" - with lock: - return _CacheInfo(hits, misses, maxsize, len(cache)) - - def cache_clear(): - """Clear the cache and cache statistics""" - nonlocal hits, misses, full - with lock: - cache.clear() - root[:] = [root, root, None, None] - hits = misses = 0 - full = False + wrapper.cache_info = cache_info + wrapper.cache_clear = cache_clear + return update_wrapper(wrapper, user_function) - wrapper.cache_info = cache_info - wrapper.cache_clear = cache_clear - return update_wrapper(wrapper, user_function) - - return decorating_function +try: + from _functools import _lru_cache_wrapper +except ImportError: + pass ################################################################################ @@ -530,7 +567,7 @@ def _c3_merge(sequences): break # reject the current head, it appears later else: break - if not candidate: + if candidate is None: raise RuntimeError("Inconsistent hierarchy") result.append(candidate) # remove the chosen candidate diff --git a/Lib/genericpath.py b/Lib/genericpath.py index ca4a5108fd42..671406197a7f 100644 --- a/Lib/genericpath.py +++ b/Lib/genericpath.py @@ -130,3 +130,16 @@ def _splitext(p, sep, altsep, extsep): filenameIndex += 1 return p, p[:0] + +def _check_arg_types(funcname, *args): + hasstr = hasbytes = False + for s in args: + if isinstance(s, str): + hasstr = True + elif isinstance(s, bytes): + hasbytes = True + else: + raise TypeError('%s() argument must be str or bytes, not %r' % + (funcname, s.__class__.__name__)) from None + if hasstr and hasbytes: + raise TypeError("Can't mix strings and bytes in path components") from None diff --git a/Lib/getpass.py b/Lib/getpass.py index 53c38b889756..7c4e976174ab 100644 --- a/Lib/getpass.py +++ b/Lib/getpass.py @@ -135,7 +135,13 @@ def _raw_input(prompt="", stream=None, input=None): input = sys.stdin prompt = str(prompt) if prompt: - stream.write(prompt) + try: + stream.write(prompt) + except UnicodeEncodeError: + # Use replace error handler to get as much as possible printed. + prompt = prompt.encode(stream.encoding, 'replace') + prompt = prompt.decode(stream.encoding) + stream.write(prompt) stream.flush() # NOTE: The Python C API calls flockfile() (and unlock) during readline. line = input.readline() diff --git a/Lib/gettext.py b/Lib/gettext.py index 05d9c1e5a3dd..101378fefa51 100644 --- a/Lib/gettext.py +++ b/Lib/gettext.py @@ -52,7 +52,9 @@ __all__ = ['NullTranslations', 'GNUTranslations', 'Catalog', 'find', 'translation', 'install', 'textdomain', 'bindtextdomain', - 'dgettext', 'dngettext', 'gettext', 'ngettext', + 'bind_textdomain_codeset', + 'dgettext', 'dngettext', 'gettext', 'lgettext', 'ldgettext', + 'ldngettext', 'lngettext', 'ngettext', ] _default_localedir = os.path.join(sys.base_prefix, 'share', 'locale') @@ -225,6 +227,13 @@ class GNUTranslations(NullTranslations): LE_MAGIC = 0x950412de BE_MAGIC = 0xde120495 + # Acceptable .mo versions + VERSIONS = (0, 1) + + def _get_versions(self, version): + """Returns a tuple of major version, minor version""" + return (version >> 16, version & 0xffff) + def _parse(self, fp): """Override this method to support alternative .mo formats.""" unpack = struct.unpack @@ -245,6 +254,12 @@ def _parse(self, fp): ii = '>II' else: raise OSError(0, 'Bad magic number', filename) + + major_version, minor_version = self._get_versions(version) + + if major_version not in self.VERSIONS: + raise OSError(0, 'Bad version number ' + str(major_version), filename) + # Now put all messages from the .mo file buffer into the catalog # dictionary. for i in range(0, msgcount): @@ -260,11 +275,12 @@ def _parse(self, fp): # See if we're looking at GNU .mo conventions for metadata if mlen == 0: # Catalog description - lastk = k = None + lastk = None for b_item in tmsg.split('\n'.encode("ascii")): item = b_item.decode().strip() if not item: continue + k = v = None if ':' in item: k, v = item.split(':', 1) k = k.strip().lower() diff --git a/Lib/glob.py b/Lib/glob.py index e388b5f9c0dd..56d670419a68 100644 --- a/Lib/glob.py +++ b/Lib/glob.py @@ -6,7 +6,7 @@ __all__ = ["glob", "iglob"] -def glob(pathname): +def glob(pathname, *, recursive=False): """Return a list of paths matching a pathname pattern. The pattern may contain simple shell-style wildcards a la @@ -14,10 +14,12 @@ def glob(pathname): dot are special cases that are not matched by '*' and '?' patterns. + If recursive is true, the pattern '**' will match any files and + zero or more directories and subdirectories. """ - return list(iglob(pathname)) + return list(iglob(pathname, recursive=recursive)) -def iglob(pathname): +def iglob(pathname, *, recursive=False): """Return an iterator which yields the paths matching a pathname pattern. The pattern may contain simple shell-style wildcards a la @@ -25,24 +27,37 @@ def iglob(pathname): dot are special cases that are not matched by '*' and '?' patterns. + If recursive is true, the pattern '**' will match any files and + zero or more directories and subdirectories. """ + dirname, basename = os.path.split(pathname) if not has_magic(pathname): - if os.path.lexists(pathname): - yield pathname + if basename: + if os.path.lexists(pathname): + yield pathname + else: + # Patterns ending with a slash should match only directories + if os.path.isdir(dirname): + yield pathname return - dirname, basename = os.path.split(pathname) if not dirname: - yield from glob1(None, basename) + if recursive and _isrecursive(basename): + yield from glob2(dirname, basename) + else: + yield from glob1(dirname, basename) return # `os.path.split()` returns the argument itself as a dirname if it is a # drive or UNC path. Prevent an infinite recursion if a drive or UNC path # contains magic characters (i.e. r'\\?\C:'). if dirname != pathname and has_magic(dirname): - dirs = iglob(dirname) + dirs = iglob(dirname, recursive=recursive) else: dirs = [dirname] if has_magic(basename): - glob_in_dir = glob1 + if recursive and _isrecursive(basename): + glob_in_dir = glob2 + else: + glob_in_dir = glob1 else: glob_in_dir = glob0 for dirname in dirs: @@ -78,6 +93,34 @@ def glob0(dirname, basename): return [basename] return [] +# This helper function recursively yields relative pathnames inside a literal +# directory. + +def glob2(dirname, pattern): + assert _isrecursive(pattern) + if dirname: + yield pattern[:0] + yield from _rlistdir(dirname) + +# Recursively yields relative pathnames inside a literal directory. + +def _rlistdir(dirname): + if not dirname: + if isinstance(dirname, bytes): + dirname = bytes(os.curdir, 'ASCII') + else: + dirname = os.curdir + try: + names = os.listdir(dirname) + except os.error: + return + for x in names: + if not _ishidden(x): + yield x + path = os.path.join(dirname, x) if dirname else x + for y in _rlistdir(path): + yield os.path.join(x, y) + magic_check = re.compile('([*?[])') magic_check_bytes = re.compile(b'([*?[])') @@ -92,6 +135,12 @@ def has_magic(s): def _ishidden(path): return path[0] in ('.', b'.'[0]) +def _isrecursive(pattern): + if isinstance(pattern, bytes): + return pattern == b'**' + else: + return pattern == '**' + def escape(pathname): """Escape all special characters. """ diff --git a/Lib/gzip.py b/Lib/gzip.py index 8d21fe4bc24e..45152e440d52 100644 --- a/Lib/gzip.py +++ b/Lib/gzip.py @@ -9,6 +9,7 @@ import zlib import builtins import io +import _compression __all__ = ["GzipFile", "open", "compress", "decompress"] @@ -89,49 +90,35 @@ def read(self, size): return self._buffer[read:] + \ self.file.read(size-self._length+read) - def prepend(self, prepend=b'', readprevious=False): + def prepend(self, prepend=b''): if self._read is None: self._buffer = prepend - elif readprevious and len(prepend) <= self._read: + else: # Assume data was read since the last prepend() call self._read -= len(prepend) return - else: - self._buffer = self._buffer[read:] + prepend self._length = len(self._buffer) self._read = 0 - def unused(self): - if self._read is None: - return b'' - return self._buffer[self._read:] - - def seek(self, offset, whence=0): - # This is only ever called with offset=whence=0 - if whence == 1 and self._read is not None: - if 0 <= offset + self._read <= self._length: - self._read += offset - return - else: - offset += self._length - self._read + def seek(self, off): self._read = None self._buffer = None - return self.file.seek(offset, whence) - - def __getattr__(self, name): - return getattr(self.file, name) + return self.file.seek(off) + def seekable(self): + return True # Allows fast-forwarding even in unseekable streams -class GzipFile(io.BufferedIOBase): +class GzipFile(_compression.BaseStream): """The GzipFile class simulates most of the methods of a file object with - the exception of the readinto() and truncate() methods. + the exception of the truncate() method. This class only supports opening files in binary mode. If you need to open a compressed file in text mode, use the gzip.open() function. """ + # Overridden with internal file object to be closed, if only a filename + # is passed in myfileobj = None - max_read_chunk = 10 * 1024 * 1024 # 10Mb def __init__(self, filename=None, mode=None, compresslevel=9, fileobj=None, mtime=None): @@ -163,13 +150,8 @@ def __init__(self, filename=None, mode=None, at all. The default is 9. The mtime argument is an optional numeric timestamp to be written - to the stream when compressing. All gzip compressed streams - are required to contain a timestamp. If omitted or None, the - current time is used. This module ignores the timestamp when - decompressing; however, some programs, such as gunzip, make use - of it. The format of the timestamp is the same as that of the - return value of time.time() and of the st_mtime member of the - object returned by os.stat(). + to the last modification time field in the stream when compressing. + If omitted or None, the current time is used. """ @@ -188,18 +170,9 @@ def __init__(self, filename=None, mode=None, if mode.startswith('r'): self.mode = READ - # Set flag indicating start of a new member - self._new_member = True - # Buffer data read from gzip file. extrastart is offset in - # stream where buffer starts. extrasize is number of - # bytes remaining in buffer from current stream position. - self.extrabuf = b"" - self.extrasize = 0 - self.extrastart = 0 + raw = _GzipReader(fileobj) + self._buffer = io.BufferedReader(raw) self.name = filename - # Starts small, scales exponentially - self.min_readsize = 100 - fileobj = _PaddedFile(fileobj) elif mode.startswith(('w', 'a', 'x')): self.mode = WRITE @@ -209,12 +182,11 @@ def __init__(self, filename=None, mode=None, -zlib.MAX_WBITS, zlib.DEF_MEM_LEVEL, 0) + self._write_mtime = mtime else: raise ValueError("Invalid mode: {!r}".format(mode)) self.fileobj = fileobj - self.offset = 0 - self.mtime = mtime if self.mode == WRITE: self._write_gzip_header() @@ -227,26 +199,22 @@ def filename(self): return self.name + ".gz" return self.name + @property + def mtime(self): + """Last modification time read from stream, or None""" + return self._buffer.raw._last_mtime + def __repr__(self): - fileobj = self.fileobj - if isinstance(fileobj, _PaddedFile): - fileobj = fileobj.file - s = repr(fileobj) + s = repr(self.fileobj) return '' - def _check_closed(self): - """Raises a ValueError if the underlying file object has been closed. - - """ - if self.closed: - raise ValueError('I/O operation on closed file.') - def _init_write(self, filename): self.name = filename self.crc = zlib.crc32(b"") & 0xffffffff self.size = 0 self.writebuf = [] self.bufsize = 0 + self.offset = 0 # Current file offset for seek(), tell(), etc def _write_gzip_header(self): self.fileobj.write(b'\037\213') # magic header @@ -265,7 +233,7 @@ def _write_gzip_header(self): if fname: flags = FNAME self.fileobj.write(chr(flags).encode('latin-1')) - mtime = self.mtime + mtime = self._write_mtime if mtime is None: mtime = time.time() write32u(self.fileobj, int(mtime)) @@ -274,59 +242,8 @@ def _write_gzip_header(self): if fname: self.fileobj.write(fname + b'\000') - def _init_read(self): - self.crc = zlib.crc32(b"") & 0xffffffff - self.size = 0 - - def _read_exact(self, n): - data = self.fileobj.read(n) - while len(data) < n: - b = self.fileobj.read(n - len(data)) - if not b: - raise EOFError("Compressed file ended before the " - "end-of-stream marker was reached") - data += b - return data - - def _read_gzip_header(self): - magic = self.fileobj.read(2) - if magic == b'': - return False - - if magic != b'\037\213': - raise OSError('Not a gzipped file') - - method, flag, self.mtime = struct.unpack(" 0: - self.size = self.size + len(data) + if length > 0: + self.fileobj.write(self.compress.compress(data)) + self.size += length self.crc = zlib.crc32(data, self.crc) & 0xffffffff - self.fileobj.write( self.compress.compress(data) ) - self.offset += len(data) + self.offset += length - return len(data) + return length def read(self, size=-1): - self._check_closed() + self._check_not_closed() if self.mode != READ: import errno raise OSError(errno.EBADF, "read() on write-only GzipFile object") - - if self.extrasize <= 0 and self.fileobj is None: - return b'' - - readsize = 1024 - if size < 0: # get the whole thing - while self._read(readsize): - readsize = min(self.max_read_chunk, readsize * 2) - size = self.extrasize - else: # just get some more of it - while size > self.extrasize: - if not self._read(readsize): - if size > self.extrasize: - size = self.extrasize - break - readsize = min(self.max_read_chunk, readsize * 2) - - offset = self.offset - self.extrastart - chunk = self.extrabuf[offset: offset + size] - self.extrasize = self.extrasize - size - - self.offset += size - return chunk + return self._buffer.read(size) def read1(self, size=-1): - self._check_closed() + """Implements BufferedIOBase.read1() + + Reads up to a buffer's worth of data is size is negative.""" + self._check_not_closed() if self.mode != READ: import errno raise OSError(errno.EBADF, "read1() on write-only GzipFile object") - if self.extrasize <= 0 and self.fileobj is None: - return b'' - - # For certain input data, a single call to _read() may not return - # any data. In this case, retry until we get some data or reach EOF. - while self.extrasize <= 0 and self._read(): - pass - if size < 0 or size > self.extrasize: - size = self.extrasize - - offset = self.offset - self.extrastart - chunk = self.extrabuf[offset: offset + size] - self.extrasize -= size - self.offset += size - return chunk + if size < 0: + size = io.DEFAULT_BUFFER_SIZE + return self._buffer.read1(size) def peek(self, n): + self._check_not_closed() if self.mode != READ: import errno raise OSError(errno.EBADF, "peek() on write-only GzipFile object") - - # Do not return ridiculously small buffers, for one common idiom - # is to call peek(1) and expect more bytes in return. - if n < 100: - n = 100 - if self.extrasize == 0: - if self.fileobj is None: - return b'' - # Ensure that we don't return b"" if we haven't reached EOF. - # 1024 is the same buffering heuristic used in read() - while self.extrasize == 0 and self._read(max(n, 1024)): - pass - offset = self.offset - self.extrastart - remaining = self.extrasize - assert remaining == len(self.extrabuf) - offset - return self.extrabuf[offset:offset + n] - - def _unread(self, buf): - self.extrasize = len(buf) + self.extrasize - self.offset -= len(buf) - - def _read(self, size=1024): - if self.fileobj is None: - return False - - if self._new_member: - # If the _new_member flag is set, we have to - # jump to the next member, if there is one. - self._init_read() - if not self._read_gzip_header(): - return False - self.decompress = zlib.decompressobj(-zlib.MAX_WBITS) - self._new_member = False - - # Read a chunk of data from the file - buf = self.fileobj.read(size) - - # If the EOF has been reached, flush the decompression object - # and mark this object as finished. - - if buf == b"": - uncompress = self.decompress.flush() - # Prepend the already read bytes to the fileobj to they can be - # seen by _read_eof() - self.fileobj.prepend(self.decompress.unused_data, True) - self._read_eof() - self._add_read_data( uncompress ) - return False - - uncompress = self.decompress.decompress(buf) - self._add_read_data( uncompress ) - - if self.decompress.unused_data != b"": - # Ending case: we've come to the end of a member in the file, - # so seek back to the start of the unused data, finish up - # this member, and read a new gzip header. - # Prepend the already read bytes to the fileobj to they can be - # seen by _read_eof() and _read_gzip_header() - self.fileobj.prepend(self.decompress.unused_data, True) - # Check the CRC and file size, and set the flag so we read - # a new member on the next call - self._read_eof() - self._new_member = True - return True - - def _add_read_data(self, data): - self.crc = zlib.crc32(data, self.crc) & 0xffffffff - offset = self.offset - self.extrastart - self.extrabuf = self.extrabuf[offset:] + data - self.extrasize = self.extrasize + len(data) - self.extrastart = self.offset - self.size = self.size + len(data) - - def _read_eof(self): - # We've read to the end of the file - # We check the that the computed CRC and size of the - # uncompressed data matches the stored values. Note that the size - # stored is the true file size mod 2**32. - crc32, isize = struct.unpack(" 0: - self.extrasize -= i - offset - self.offset += i - offset - return self.extrabuf[offset: i] - - size = sys.maxsize - readsize = self.min_readsize - else: - readsize = size - bufs = [] - while size != 0: - c = self.read(readsize) - i = c.find(b'\n') - - # We set i=size to break out of the loop under two - # conditions: 1) there's no newline, and the chunk is - # larger than size, or 2) there is a newline, but the - # resulting line would be longer than 'size'. - if (size <= i) or (i == -1 and len(c) > size): - i = size - 1 - - if i >= 0 or c == b'': - bufs.append(c[:i + 1]) # Add portion of last chunk - self._unread(c[i + 1:]) # Push back rest of chunk + return self.readall() + # size=0 is special because decompress(max_length=0) is not supported + if not size: + return b"" + + # For certain input data, a single + # call to decompress() may not return + # any data. In this case, retry until we get some data or reach EOF. + while True: + if self._decompressor.eof: + # Ending case: we've come to the end of a member in the file, + # so finish up this member, and read a new gzip header. + # Check the CRC and file size, and set the flag so we read + # a new member + self._read_eof() + self._new_member = True + self._decompressor = self._decomp_factory( + **self._decomp_args) + + if self._new_member: + # If the _new_member flag is set, we have to + # jump to the next member, if there is one. + self._init_read() + if not self._read_gzip_header(): + self._size = self._pos + return b"" + self._new_member = False + + # Read a chunk of data from the file + buf = self._fp.read(io.DEFAULT_BUFFER_SIZE) + + uncompress = self._decompressor.decompress(buf, size) + if self._decompressor.unconsumed_tail != b"": + self._fp.prepend(self._decompressor.unconsumed_tail) + elif self._decompressor.unused_data != b"": + # Prepend the already read bytes to the fileobj so they can + # be seen by _read_eof() and _read_gzip_header() + self._fp.prepend(self._decompressor.unused_data) + + if uncompress != b"": break + if buf == b"": + raise EOFError("Compressed file ended before the " + "end-of-stream marker was reached") + + self._add_read_data( uncompress ) + self._pos += len(uncompress) + return uncompress - # Append chunk to list, decrease 'size', - bufs.append(c) - size = size - len(c) - readsize = min(size, readsize * 2) - if readsize > self.min_readsize: - self.min_readsize = min(readsize, self.min_readsize * 2, 512) - return b''.join(bufs) # Return resulting line + def _add_read_data(self, data): + self._crc = zlib.crc32(data, self._crc) & 0xffffffff + self._stream_size = self._stream_size + len(data) + def _read_eof(self): + # We've read to the end of the file + # We check the that the computed CRC and size of the + # uncompressed data matches the stored values. Note that the size + # stored is the true file size mod 2**32. + crc32, isize = struct.unpack("= startpos, except possibly for pos. pos # is the index of a leaf with a possibly out-of-order value. Restore the # heap invariant. @@ -340,13 +311,7 @@ def _siftup_max(heap, pos): heap[pos] = newitem _siftdown_max(heap, startpos, pos) -# If available, use C implementation -try: - from _heapq import * -except ImportError: - pass - -def merge(*iterables): +def merge(*iterables, key=None, reverse=False): '''Merge multiple sorted inputs into a single sorted output. Similar to sorted(itertools.chain(*iterables)) but returns a generator, @@ -356,51 +321,158 @@ def merge(*iterables): >>> list(merge([1,3,5,7], [0,2,4,8], [5,10,15,20], [], [25])) [0, 1, 2, 3, 4, 5, 5, 7, 8, 10, 15, 20, 25] + If *key* is not None, applies a key function to each element to determine + its sort order. + + >>> list(merge(['dog', 'horse'], ['cat', 'fish', 'kangaroo'], key=len)) + ['dog', 'cat', 'fish', 'horse', 'kangaroo'] + ''' - _heappop, _heapreplace, _StopIteration = heappop, heapreplace, StopIteration - _len = len h = [] h_append = h.append - for itnum, it in enumerate(map(iter, iterables)): + + if reverse: + _heapify = _heapify_max + _heappop = _heappop_max + _heapreplace = _heapreplace_max + direction = -1 + else: + _heapify = heapify + _heappop = heappop + _heapreplace = heapreplace + direction = 1 + + if key is None: + for order, it in enumerate(map(iter, iterables)): + try: + next = it.__next__ + h_append([next(), order * direction, next]) + except StopIteration: + pass + _heapify(h) + while len(h) > 1: + try: + while True: + value, order, next = s = h[0] + yield value + s[0] = next() # raises StopIteration when exhausted + _heapreplace(h, s) # restore heap condition + except StopIteration: + _heappop(h) # remove empty iterator + if h: + # fast case when only a single iterator remains + value, order, next = h[0] + yield value + yield from next.__self__ + return + + for order, it in enumerate(map(iter, iterables)): try: next = it.__next__ - h_append([next(), itnum, next]) - except _StopIteration: + value = next() + h_append([key(value), order * direction, value, next]) + except StopIteration: pass - heapify(h) - - while _len(h) > 1: + _heapify(h) + while len(h) > 1: try: while True: - v, itnum, next = s = h[0] - yield v - s[0] = next() # raises StopIteration when exhausted - _heapreplace(h, s) # restore heap condition - except _StopIteration: - _heappop(h) # remove empty iterator + key_value, order, value, next = s = h[0] + yield value + value = next() + s[0] = key(value) + s[2] = value + _heapreplace(h, s) + except StopIteration: + _heappop(h) if h: - # fast case when only a single iterator remains - v, itnum, next = h[0] - yield v + key_value, order, value, next = h[0] + yield value yield from next.__self__ -# Extend the implementations of nsmallest and nlargest to use a key= argument -_nsmallest = nsmallest + +# Algorithm notes for nlargest() and nsmallest() +# ============================================== +# +# Make a single pass over the data while keeping the k most extreme values +# in a heap. Memory consumption is limited to keeping k values in a list. +# +# Measured performance for random inputs: +# +# number of comparisons +# n inputs k-extreme values (average of 5 trials) % more than min() +# ------------- ---------------- --------------------- ----------------- +# 1,000 100 3,317 231.7% +# 10,000 100 14,046 40.5% +# 100,000 100 105,749 5.7% +# 1,000,000 100 1,007,751 0.8% +# 10,000,000 100 10,009,401 0.1% +# +# Theoretical number of comparisons for k smallest of n random inputs: +# +# Step Comparisons Action +# ---- -------------------------- --------------------------- +# 1 1.66 * k heapify the first k-inputs +# 2 n - k compare remaining elements to top of heap +# 3 k * (1 + lg2(k)) * ln(n/k) replace the topmost value on the heap +# 4 k * lg2(k) - (k/2) final sort of the k most extreme values +# +# Combining and simplifying for a rough estimate gives: +# +# comparisons = n + k * (log(k, 2) * log(n/k) + log(k, 2) + log(n/k)) +# +# Computing the number of comparisons for step 3: +# ----------------------------------------------- +# * For the i-th new value from the iterable, the probability of being in the +# k most extreme values is k/i. For example, the probability of the 101st +# value seen being in the 100 most extreme values is 100/101. +# * If the value is a new extreme value, the cost of inserting it into the +# heap is 1 + log(k, 2). +# * The probability times the cost gives: +# (k/i) * (1 + log(k, 2)) +# * Summing across the remaining n-k elements gives: +# sum((k/i) * (1 + log(k, 2)) for i in range(k+1, n+1)) +# * This reduces to: +# (H(n) - H(k)) * k * (1 + log(k, 2)) +# * Where H(n) is the n-th harmonic number estimated by: +# gamma = 0.5772156649 +# H(n) = log(n, e) + gamma + 1 / (2 * n) +# http://en.wikipedia.org/wiki/Harmonic_series_(mathematics)#Rate_of_divergence +# * Substituting the H(n) formula: +# comparisons = k * (1 + log(k, 2)) * (log(n/k, e) + (1/n - 1/k) / 2) +# +# Worst-case for step 3: +# ---------------------- +# In the worst case, the input data is reversed sorted so that every new element +# must be inserted in the heap: +# +# comparisons = 1.66 * k + log(k, 2) * (n - k) +# +# Alternative Algorithms +# ---------------------- +# Other algorithms were not used because they: +# 1) Took much more auxiliary memory, +# 2) Made multiple passes over the data. +# 3) Made more comparisons in common cases (small k, large n, semi-random input). +# See the more detailed comparison of approach at: +# http://code.activestate.com/recipes/577573-compare-algorithms-for-heapqsmallest + def nsmallest(n, iterable, key=None): """Find the n smallest elements in a dataset. Equivalent to: sorted(iterable, key=key)[:n] """ - # Short-cut for n==1 is to use min() when len(iterable)>0 + + # Short-cut for n==1 is to use min() if n == 1: it = iter(iterable) - head = list(islice(it, 1)) - if not head: - return [] + sentinel = object() if key is None: - return [min(chain(head, it))] - return [min(chain(head, it), key=key)] + result = min(it, default=sentinel) + else: + result = min(it, default=sentinel, key=key) + return [] if result is sentinel else [result] # When n>=size, it's faster to use sorted() try: @@ -413,32 +485,57 @@ def nsmallest(n, iterable, key=None): # When key is none, use simpler decoration if key is None: - it = zip(iterable, count()) # decorate - result = _nsmallest(n, it) - return [r[0] for r in result] # undecorate + it = iter(iterable) + # put the range(n) first so that zip() doesn't + # consume one too many elements from the iterator + result = [(elem, i) for i, elem in zip(range(n), it)] + if not result: + return result + _heapify_max(result) + top = result[0][0] + order = n + _heapreplace = _heapreplace_max + for elem in it: + if elem < top: + _heapreplace(result, (elem, order)) + top = result[0][0] + order += 1 + result.sort() + return [r[0] for r in result] # General case, slowest method - in1, in2 = tee(iterable) - it = zip(map(key, in1), count(), in2) # decorate - result = _nsmallest(n, it) - return [r[2] for r in result] # undecorate + it = iter(iterable) + result = [(key(elem), i, elem) for i, elem in zip(range(n), it)] + if not result: + return result + _heapify_max(result) + top = result[0][0] + order = n + _heapreplace = _heapreplace_max + for elem in it: + k = key(elem) + if k < top: + _heapreplace(result, (k, order, elem)) + top = result[0][0] + order += 1 + result.sort() + return [r[2] for r in result] -_nlargest = nlargest def nlargest(n, iterable, key=None): """Find the n largest elements in a dataset. Equivalent to: sorted(iterable, key=key, reverse=True)[:n] """ - # Short-cut for n==1 is to use max() when len(iterable)>0 + # Short-cut for n==1 is to use max() if n == 1: it = iter(iterable) - head = list(islice(it, 1)) - if not head: - return [] + sentinel = object() if key is None: - return [max(chain(head, it))] - return [max(chain(head, it), key=key)] + result = max(it, default=sentinel) + else: + result = max(it, default=sentinel, key=key) + return [] if result is sentinel else [result] # When n>=size, it's faster to use sorted() try: @@ -451,26 +548,60 @@ def nlargest(n, iterable, key=None): # When key is none, use simpler decoration if key is None: - it = zip(iterable, count(0,-1)) # decorate - result = _nlargest(n, it) - return [r[0] for r in result] # undecorate + it = iter(iterable) + result = [(elem, i) for i, elem in zip(range(0, -n, -1), it)] + if not result: + return result + heapify(result) + top = result[0][0] + order = -n + _heapreplace = heapreplace + for elem in it: + if top < elem: + _heapreplace(result, (elem, order)) + top = result[0][0] + order -= 1 + result.sort(reverse=True) + return [r[0] for r in result] # General case, slowest method - in1, in2 = tee(iterable) - it = zip(map(key, in1), count(0,-1), in2) # decorate - result = _nlargest(n, it) - return [r[2] for r in result] # undecorate + it = iter(iterable) + result = [(key(elem), i, elem) for i, elem in zip(range(0, -n, -1), it)] + if not result: + return result + heapify(result) + top = result[0][0] + order = -n + _heapreplace = heapreplace + for elem in it: + k = key(elem) + if top < k: + _heapreplace(result, (k, order, elem)) + top = result[0][0] + order -= 1 + result.sort(reverse=True) + return [r[2] for r in result] + +# If available, use C implementation +try: + from _heapq import * +except ImportError: + pass +try: + from _heapq import _heapreplace_max +except ImportError: + pass +try: + from _heapq import _heapify_max +except ImportError: + pass +try: + from _heapq import _heappop_max +except ImportError: + pass + if __name__ == "__main__": - # Simple sanity test - heap = [] - data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0] - for item in data: - heappush(heap, item) - sort = [] - while heap: - sort.append(heappop(heap)) - print(sort) import doctest - doctest.testmod() + print(doctest.testmod()) diff --git a/Lib/html/entities.py b/Lib/html/entities.py index e891ad659901..3e1778b768ce 100644 --- a/Lib/html/entities.py +++ b/Lib/html/entities.py @@ -1,6 +1,9 @@ """HTML character entity references.""" -# maps the HTML entity name to the Unicode codepoint +__all__ = ['html5', 'name2codepoint', 'codepoint2name', 'entitydefs'] + + +# maps the HTML entity name to the Unicode code point name2codepoint = { 'AElig': 0x00c6, # latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1 'Aacute': 0x00c1, # latin capital letter A with acute, U+00C1 ISOlat1 @@ -2492,7 +2495,7 @@ 'zwnj;': '\u200c', } -# maps the Unicode codepoint to the HTML entity name +# maps the Unicode code point to the HTML entity name codepoint2name = {} # maps the HTML entity name to the character diff --git a/Lib/html/parser.py b/Lib/html/parser.py index 12c28b8339ff..43e6411b735c 100644 --- a/Lib/html/parser.py +++ b/Lib/html/parser.py @@ -29,35 +29,15 @@ piclose = re.compile('>') commentclose = re.compile(r'--\s*>') # Note: -# 1) the strict attrfind isn't really strict, but we can't make it -# correctly strict without breaking backward compatibility; -# 2) if you change tagfind/attrfind remember to update locatestarttagend too; -# 3) if you change tagfind/attrfind and/or locatestarttagend the parser will +# 1) if you change tagfind/attrfind remember to update locatestarttagend too; +# 2) if you change tagfind/attrfind and/or locatestarttagend the parser will # explode, so don't do it. -tagfind = re.compile('([a-zA-Z][-.a-zA-Z0-9:_]*)(?:\s|/(?!>))*') # see http://www.w3.org/TR/html5/tokenization.html#tag-open-state # and http://www.w3.org/TR/html5/tokenization.html#tag-name-state tagfind_tolerant = re.compile('([a-zA-Z][^\t\n\r\f />\x00]*)(?:\s|/(?!>))*') -attrfind = re.compile( - r'\s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(\s*=\s*' - r'(\'[^\']*\'|"[^"]*"|[^\s"\'=<>`]*))?') attrfind_tolerant = re.compile( r'((?<=[\'"\s/])[^\s/>][^\s/=>]*)(\s*=+\s*' r'(\'[^\']*\'|"[^"]*"|(?![\'"])[^>\s]*))?(?:\s|/(?!>))*') -locatestarttagend = re.compile(r""" - <[a-zA-Z][-.a-zA-Z0-9:_]* # tag name - (?:\s+ # whitespace before attribute name - (?:[a-zA-Z_][-.:a-zA-Z0-9_]* # attribute name - (?:\s*=\s* # value indicator - (?:'[^']*' # LITA-enclosed value - |\"[^\"]*\" # LIT-enclosed value - |[^'\">\s]+ # bare value - ) - )? - ) - )* - \s* # trailing whitespace -""", re.VERBOSE) locatestarttagend_tolerant = re.compile(r""" <[a-zA-Z][^\t\n\r\f />\x00]* # tag name (?:[\s/]* # optional whitespace before attribute name @@ -79,25 +59,6 @@ endtagfind = re.compile('') -class HTMLParseError(Exception): - """Exception raised for all parse errors.""" - - def __init__(self, msg, position=(None, None)): - assert msg - self.msg = msg - self.lineno = position[0] - self.offset = position[1] - - def __str__(self): - result = self.msg - if self.lineno is not None: - result = result + ", at line %d" % self.lineno - if self.offset is not None: - result = result + ", column %d" % (self.offset + 1) - return result - - -_default_sentinel = object() class HTMLParser(_markupbase.ParserBase): """Find tags and other markup and call handler functions. @@ -123,27 +84,12 @@ class HTMLParser(_markupbase.ParserBase): CDATA_CONTENT_ELEMENTS = ("script", "style") - def __init__(self, strict=_default_sentinel, *, - convert_charrefs=_default_sentinel): + def __init__(self, *, convert_charrefs=True): """Initialize and reset this instance. - If convert_charrefs is True (default: False), all character references + If convert_charrefs is True (the default), all character references are automatically converted to the corresponding Unicode characters. - If strict is set to False (the default) the parser will parse invalid - markup, otherwise it will raise an error. Note that the strict mode - and argument are deprecated. """ - if strict is not _default_sentinel: - warnings.warn("The strict argument and mode are deprecated.", - DeprecationWarning, stacklevel=2) - else: - strict = False # default - self.strict = strict - if convert_charrefs is _default_sentinel: - convert_charrefs = False # default - warnings.warn("The value of convert_charrefs will become True in " - "3.5. You are encouraged to set the value explicitly.", - DeprecationWarning, stacklevel=2) self.convert_charrefs = convert_charrefs self.reset() @@ -168,11 +114,6 @@ def close(self): """Handle any buffered data.""" self.goahead(1) - def error(self, message): - warnings.warn("The 'error' method is deprecated.", - DeprecationWarning, stacklevel=2) - raise HTMLParseError(message, self.getpos()) - __starttag_text = None def get_starttag_text(self): @@ -198,7 +139,15 @@ def goahead(self, end): if self.convert_charrefs and not self.cdata_elem: j = rawdata.find('<', i) if j < 0: - if not end: + # if we can't find the next <, either we are at the end + # or there's more text incoming. If the latter is True, + # we can't pass the text to handle_data in case we have + # a charref cut in half at end. Try to determine if + # this is the case before proceding by looking for an + # & near the end and see if it's followed by a space or ;. + amppos = rawdata.rfind('&', max(i, n-34)) + if (amppos >= 0 and + not re.compile(r'[\s;]').search(rawdata, amppos)): break # wait till we get all the text j = n else: @@ -227,10 +176,7 @@ def goahead(self, end): elif startswith("', i + 1) if k < 0: k = rawdata.find('<', i + 1) @@ -264,9 +208,9 @@ def goahead(self, end): i = self.updatepos(i, k) continue else: - if ";" in rawdata[i:]: #bail by consuming &# - self.handle_data(rawdata[0:2]) - i = self.updatepos(i, 2) + if ";" in rawdata[i:]: # bail by consuming &# + self.handle_data(rawdata[i:i+2]) + i = self.updatepos(i, i+2) break elif startswith('&', i): match = entityref.match(rawdata, i) @@ -282,13 +226,10 @@ def goahead(self, end): if match: # match.group() will contain at least 2 chars if end and match.group() == rawdata[i:]: - if self.strict: - self.error("EOF in middle of entity or char ref") - else: - k = match.end() - if k <= i: - k = n - i = self.updatepos(i, i + 1) + k = match.end() + if k <= i: + k = n + i = self.updatepos(i, i + 1) # incomplete break elif (i + 1) < n: @@ -367,18 +308,12 @@ def parse_starttag(self, i): # Now parse the data between i+1 and j into a tag and attrs attrs = [] - if self.strict: - match = tagfind.match(rawdata, i+1) - else: - match = tagfind_tolerant.match(rawdata, i+1) + match = tagfind_tolerant.match(rawdata, i+1) assert match, 'unexpected call to parse_starttag()' k = match.end() self.lasttag = tag = match.group(1).lower() while k < endpos: - if self.strict: - m = attrfind.match(rawdata, k) - else: - m = attrfind_tolerant.match(rawdata, k) + m = attrfind_tolerant.match(rawdata, k) if not m: break attrname, rest, attrvalue = m.group(1, 2, 3) @@ -401,9 +336,6 @@ def parse_starttag(self, i): - self.__starttag_text.rfind("\n") else: offset = offset + len(self.__starttag_text) - if self.strict: - self.error("junk characters in start tag: %r" - % (rawdata[k:endpos][:20],)) self.handle_data(rawdata[i:endpos]) return endpos if end.endswith('/>'): @@ -419,10 +351,7 @@ def parse_starttag(self, i): # or -1 if incomplete. def check_for_whole_start_tag(self, i): rawdata = self.rawdata - if self.strict: - m = locatestarttagend.match(rawdata, i) - else: - m = locatestarttagend_tolerant.match(rawdata, i) + m = locatestarttagend_tolerant.match(rawdata, i) if m: j = m.end() next = rawdata[j:j+1] @@ -435,9 +364,6 @@ def check_for_whole_start_tag(self, i): # buffer boundary return -1 # else bogus input - if self.strict: - self.updatepos(i, j + 1) - self.error("malformed empty start tag") if j > i: return j else: @@ -450,9 +376,6 @@ def check_for_whole_start_tag(self, i): # end of input in or before attribute value, or we have the # '/' from a '/>' ending return -1 - if self.strict: - self.updatepos(i, j) - self.error("malformed start tag") if j > i: return j else: @@ -472,8 +395,6 @@ def parse_endtag(self, i): if self.cdata_elem is not None: self.handle_data(rawdata[i:gtpos]) return gtpos - if self.strict: - self.error("bad end tag: %r" % (rawdata[i:gtpos],)) # find the name: w3.org/TR/html5/tokenization.html#tag-name-state namematch = tagfind_tolerant.match(rawdata, i+2) if not namematch: @@ -539,8 +460,7 @@ def handle_pi(self, data): pass def unknown_decl(self, data): - if self.strict: - self.error("unknown declaration: %r" % (data,)) + pass # Internal -- helper to remove special character quoting def unescape(self, s): diff --git a/Lib/http/__init__.py b/Lib/http/__init__.py index 196d37885759..d4334cc88f9f 100644 --- a/Lib/http/__init__.py +++ b/Lib/http/__init__.py @@ -1 +1,134 @@ -# This directory is a Python package. +from enum import IntEnum + +__all__ = ['HTTPStatus'] + +class HTTPStatus(IntEnum): + """HTTP status codes and reason phrases + + Status codes from the following RFCs are all observed: + + * RFC 7231: Hypertext Transfer Protocol (HTTP/1.1), obsoletes 2616 + * RFC 6585: Additional HTTP Status Codes + * RFC 3229: Delta encoding in HTTP + * RFC 4918: HTTP Extensions for WebDAV, obsoletes 2518 + * RFC 5842: Binding Extensions to WebDAV + * RFC 7238: Permanent Redirect + * RFC 2295: Transparent Content Negotiation in HTTP + * RFC 2774: An HTTP Extension Framework + """ + def __new__(cls, value, phrase, description=''): + obj = int.__new__(cls, value) + obj._value_ = value + + obj.phrase = phrase + obj.description = description + return obj + + # informational + CONTINUE = 100, 'Continue', 'Request received, please continue' + SWITCHING_PROTOCOLS = (101, 'Switching Protocols', + 'Switching to new protocol; obey Upgrade header') + PROCESSING = 102, 'Processing' + + # success + OK = 200, 'OK', 'Request fulfilled, document follows' + CREATED = 201, 'Created', 'Document created, URL follows' + ACCEPTED = (202, 'Accepted', + 'Request accepted, processing continues off-line') + NON_AUTHORITATIVE_INFORMATION = (203, + 'Non-Authoritative Information', 'Request fulfilled from cache') + NO_CONTENT = 204, 'No Content', 'Request fulfilled, nothing follows' + RESET_CONTENT = 205, 'Reset Content', 'Clear input form for further input' + PARTIAL_CONTENT = 206, 'Partial Content', 'Partial content follows' + MULTI_STATUS = 207, 'Multi-Status' + ALREADY_REPORTED = 208, 'Already Reported' + IM_USED = 226, 'IM Used' + + # redirection + MULTIPLE_CHOICES = (300, 'Multiple Choices', + 'Object has several resources -- see URI list') + MOVED_PERMANENTLY = (301, 'Moved Permanently', + 'Object moved permanently -- see URI list') + FOUND = 302, 'Found', 'Object moved temporarily -- see URI list' + SEE_OTHER = 303, 'See Other', 'Object moved -- see Method and URL list' + NOT_MODIFIED = (304, 'Not Modified', + 'Document has not changed since given time') + USE_PROXY = (305, 'Use Proxy', + 'You must use proxy specified in Location to access this resource') + TEMPORARY_REDIRECT = (307, 'Temporary Redirect', + 'Object moved temporarily -- see URI list') + PERMANENT_REDIRECT = (308, 'Permanent Redirect', + 'Object moved temporarily -- see URI list') + + # client error + BAD_REQUEST = (400, 'Bad Request', + 'Bad request syntax or unsupported method') + UNAUTHORIZED = (401, 'Unauthorized', + 'No permission -- see authorization schemes') + PAYMENT_REQUIRED = (402, 'Payment Required', + 'No payment -- see charging schemes') + FORBIDDEN = (403, 'Forbidden', + 'Request forbidden -- authorization will not help') + NOT_FOUND = (404, 'Not Found', + 'Nothing matches the given URI') + METHOD_NOT_ALLOWED = (405, 'Method Not Allowed', + 'Specified method is invalid for this resource') + NOT_ACCEPTABLE = (406, 'Not Acceptable', + 'URI not available in preferred format') + PROXY_AUTHENTICATION_REQUIRED = (407, + 'Proxy Authentication Required', + 'You must authenticate with this proxy before proceeding') + REQUEST_TIMEOUT = (408, 'Request Timeout', + 'Request timed out; try again later') + CONFLICT = 409, 'Conflict', 'Request conflict' + GONE = (410, 'Gone', + 'URI no longer exists and has been permanently removed') + LENGTH_REQUIRED = (411, 'Length Required', + 'Client must specify Content-Length') + PRECONDITION_FAILED = (412, 'Precondition Failed', + 'Precondition in headers is false') + REQUEST_ENTITY_TOO_LARGE = (413, 'Request Entity Too Large', + 'Entity is too large') + REQUEST_URI_TOO_LONG = (414, 'Request-URI Too Long', + 'URI is too long') + UNSUPPORTED_MEDIA_TYPE = (415, 'Unsupported Media Type', + 'Entity body in unsupported format') + REQUESTED_RANGE_NOT_SATISFIABLE = (416, + 'Requested Range Not Satisfiable', + 'Cannot satisfy request range') + EXPECTATION_FAILED = (417, 'Expectation Failed', + 'Expect condition could not be satisfied') + UNPROCESSABLE_ENTITY = 422, 'Unprocessable Entity' + LOCKED = 423, 'Locked' + FAILED_DEPENDENCY = 424, 'Failed Dependency' + UPGRADE_REQUIRED = 426, 'Upgrade Required' + PRECONDITION_REQUIRED = (428, 'Precondition Required', + 'The origin server requires the request to be conditional') + TOO_MANY_REQUESTS = (429, 'Too Many Requests', + 'The user has sent too many requests in ' + 'a given amount of time ("rate limiting")') + REQUEST_HEADER_FIELDS_TOO_LARGE = (431, + 'Request Header Fields Too Large', + 'The server is unwilling to process the request because its header ' + 'fields are too large') + + # server errors + INTERNAL_SERVER_ERROR = (500, 'Internal Server Error', + 'Server got itself in trouble') + NOT_IMPLEMENTED = (501, 'Not Implemented', + 'Server does not support this operation') + BAD_GATEWAY = (502, 'Bad Gateway', + 'Invalid responses from another server/proxy') + SERVICE_UNAVAILABLE = (503, 'Service Unavailable', + 'The server cannot process the request due to a high load') + GATEWAY_TIMEOUT = (504, 'Gateway Timeout', + 'The gateway server did not receive a timely response') + HTTP_VERSION_NOT_SUPPORTED = (505, 'HTTP Version Not Supported', + 'Cannot fulfill request') + VARIANT_ALSO_NEGOTIATES = 506, 'Variant Also Negotiates' + INSUFFICIENT_STORAGE = 507, 'Insufficient Storage' + LOOP_DETECTED = 508, 'Loop Detected' + NOT_EXTENDED = 510, 'Not Extended' + NETWORK_AUTHENTICATION_REQUIRED = (511, + 'Network Authentication Required', + 'The client needs to authenticate to gain network access') diff --git a/Lib/http/client.py b/Lib/http/client.py index 5c52ba349ac0..155c2e3ec4fe 100644 --- a/Lib/http/client.py +++ b/Lib/http/client.py @@ -20,10 +20,12 @@ | ( putheader() )* endheaders() v Request-sent - | - | response = getresponse() - v - Unread-response [Response-headers-read] + |\_____________________________ + | | getresponse() raises + | response = getresponse() | ConnectionError + v v + Unread-response Idle + [Response-headers-read] |\____________________ | | | response.read() | putrequest() @@ -68,19 +70,23 @@ import email.parser import email.message +import http import io import os +import re import socket import collections from urllib.parse import urlsplit -import warnings +# HTTPMessage, parse_headers(), and the HTTP status code constants are +# intentionally omitted for simplicity __all__ = ["HTTPResponse", "HTTPConnection", "HTTPException", "NotConnected", "UnknownProtocol", "UnknownTransferEncoding", "UnimplementedFileMode", "IncompleteRead", "InvalidURL", "ImproperConnectionState", "CannotSendRequest", "CannotSendHeader", "ResponseNotReady", - "BadStatusLine", "error", "responses"] + "BadStatusLine", "LineTooLong", "RemoteDisconnected", "error", + "responses"] HTTP_PORT = 80 HTTPS_PORT = 443 @@ -92,122 +98,13 @@ _CS_REQ_STARTED = 'Request-started' _CS_REQ_SENT = 'Request-sent' -# status codes -# informational -CONTINUE = 100 -SWITCHING_PROTOCOLS = 101 -PROCESSING = 102 - -# successful -OK = 200 -CREATED = 201 -ACCEPTED = 202 -NON_AUTHORITATIVE_INFORMATION = 203 -NO_CONTENT = 204 -RESET_CONTENT = 205 -PARTIAL_CONTENT = 206 -MULTI_STATUS = 207 -IM_USED = 226 - -# redirection -MULTIPLE_CHOICES = 300 -MOVED_PERMANENTLY = 301 -FOUND = 302 -SEE_OTHER = 303 -NOT_MODIFIED = 304 -USE_PROXY = 305 -TEMPORARY_REDIRECT = 307 - -# client error -BAD_REQUEST = 400 -UNAUTHORIZED = 401 -PAYMENT_REQUIRED = 402 -FORBIDDEN = 403 -NOT_FOUND = 404 -METHOD_NOT_ALLOWED = 405 -NOT_ACCEPTABLE = 406 -PROXY_AUTHENTICATION_REQUIRED = 407 -REQUEST_TIMEOUT = 408 -CONFLICT = 409 -GONE = 410 -LENGTH_REQUIRED = 411 -PRECONDITION_FAILED = 412 -REQUEST_ENTITY_TOO_LARGE = 413 -REQUEST_URI_TOO_LONG = 414 -UNSUPPORTED_MEDIA_TYPE = 415 -REQUESTED_RANGE_NOT_SATISFIABLE = 416 -EXPECTATION_FAILED = 417 -UNPROCESSABLE_ENTITY = 422 -LOCKED = 423 -FAILED_DEPENDENCY = 424 -UPGRADE_REQUIRED = 426 -PRECONDITION_REQUIRED = 428 -TOO_MANY_REQUESTS = 429 -REQUEST_HEADER_FIELDS_TOO_LARGE = 431 - -# server error -INTERNAL_SERVER_ERROR = 500 -NOT_IMPLEMENTED = 501 -BAD_GATEWAY = 502 -SERVICE_UNAVAILABLE = 503 -GATEWAY_TIMEOUT = 504 -HTTP_VERSION_NOT_SUPPORTED = 505 -INSUFFICIENT_STORAGE = 507 -NOT_EXTENDED = 510 -NETWORK_AUTHENTICATION_REQUIRED = 511 +# hack to maintain backwards compatibility +globals().update(http.HTTPStatus.__members__) + +# another hack to maintain backwards compatibility # Mapping status codes to official W3C names -responses = { - 100: 'Continue', - 101: 'Switching Protocols', - - 200: 'OK', - 201: 'Created', - 202: 'Accepted', - 203: 'Non-Authoritative Information', - 204: 'No Content', - 205: 'Reset Content', - 206: 'Partial Content', - - 300: 'Multiple Choices', - 301: 'Moved Permanently', - 302: 'Found', - 303: 'See Other', - 304: 'Not Modified', - 305: 'Use Proxy', - 306: '(Unused)', - 307: 'Temporary Redirect', - - 400: 'Bad Request', - 401: 'Unauthorized', - 402: 'Payment Required', - 403: 'Forbidden', - 404: 'Not Found', - 405: 'Method Not Allowed', - 406: 'Not Acceptable', - 407: 'Proxy Authentication Required', - 408: 'Request Timeout', - 409: 'Conflict', - 410: 'Gone', - 411: 'Length Required', - 412: 'Precondition Failed', - 413: 'Request Entity Too Large', - 414: 'Request-URI Too Long', - 415: 'Unsupported Media Type', - 416: 'Requested Range Not Satisfiable', - 417: 'Expectation Failed', - 428: 'Precondition Required', - 429: 'Too Many Requests', - 431: 'Request Header Fields Too Large', - - 500: 'Internal Server Error', - 501: 'Not Implemented', - 502: 'Bad Gateway', - 503: 'Service Unavailable', - 504: 'Gateway Timeout', - 505: 'HTTP Version Not Supported', - 511: 'Network Authentication Required', -} +responses = {v: v.phrase for v in http.HTTPStatus.__members__.values()} # maximal amount of data to read at one time in _safe_read MAXAMOUNT = 1048576 @@ -216,6 +113,38 @@ _MAXLINE = 65536 _MAXHEADERS = 100 +# Header name/value ABNF (http://tools.ietf.org/html/rfc7230#section-3.2) +# +# VCHAR = %x21-7E +# obs-text = %x80-FF +# header-field = field-name ":" OWS field-value OWS +# field-name = token +# field-value = *( field-content / obs-fold ) +# field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] +# field-vchar = VCHAR / obs-text +# +# obs-fold = CRLF 1*( SP / HTAB ) +# ; obsolete line folding +# ; see Section 3.2.4 + +# token = 1*tchar +# +# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" +# / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" +# / DIGIT / ALPHA +# ; any VCHAR, except delimiters +# +# VCHAR defined in http://tools.ietf.org/html/rfc5234#appendix-B.1 + +# the patterns for both name and value are more leniant than RFC +# definitions to allow for backwards compatibility +_is_legal_header_name = re.compile(rb'[^:\s][^:\r\n]*').fullmatch +_is_illegal_header_value = re.compile(rb'\n(?![ \t])|\r(?![ \t\n])').search + +# We always set the Content-Length header for these methods because some +# servers will otherwise respond with a 411 +_METHODS_EXPECTING_BODY = {'PATCH', 'POST', 'PUT'} + class HTTPMessage(email.message.Message): # XXX The only usage of this method is in @@ -271,7 +200,7 @@ def parse_headers(fp, _class=HTTPMessage): return email.parser.Parser(_class=_class).parsestr(hstring) -class HTTPResponse(io.RawIOBase): +class HTTPResponse(io.BufferedIOBase): # See RFC 2616 sec 19.6 and RFC 1945 sec 6 for details. @@ -319,7 +248,8 @@ def _read_status(self): if not line: # Presumably, the server closed the connection before # sending a valid response. - raise BadStatusLine(line) + raise RemoteDisconnected("Remote end closed connection without" + " response") try: version, status, reason = line.split(None, 2) except ValueError: @@ -458,9 +388,11 @@ def _close_conn(self): fp.close() def close(self): - super().close() # set "closed" flag - if self.fp: - self._close_conn() + try: + super().close() # set "closed" flag + finally: + if self.fp: + self._close_conn() # These implementations are for the benefit of io.BufferedReader. @@ -473,6 +405,7 @@ def flush(self): self.fp.flush() def readable(self): + """Always returns True""" return True # End of "raw stream" methods @@ -496,9 +429,10 @@ def read(self, amt=None): return b"" if amt is not None: - # Amount is given, so call base class version - # (which is implemented in terms of self.readinto) - return super(HTTPResponse, self).read(amt) + # Amount is given, implement using readinto + b = bytearray(amt) + n = self.readinto(b) + return memoryview(b)[:n].tobytes() else: # Amount is not given (unbounded read) so we must check self.length # and self.chunked @@ -519,6 +453,10 @@ def read(self, amt=None): return s def readinto(self, b): + """Read up to len(b) bytes into bytearray b and return the number + of bytes read. + """ + if self.fp is None: return 0 @@ -538,7 +476,7 @@ def readinto(self, b): # connection, and the user is reading more bytes than will be provided # (for example, reading in 1k chunks) n = self.fp.readinto(b) - if not n: + if not n and b: # Ideally, we would raise IncompleteRead if the content-length # wasn't satisfied, but it might break compatibility. self._close_conn() @@ -578,71 +516,67 @@ def _read_and_discard_trailer(self): if line in (b'\r\n', b'\n', b''): break + def _get_chunk_left(self): + # return self.chunk_left, reading a new chunk if necessary. + # chunk_left == 0: at the end of the current chunk, need to close it + # chunk_left == None: No current chunk, should read next. + # This function returns non-zero or None if the last chunk has + # been read. + chunk_left = self.chunk_left + if not chunk_left: # Can be 0 or None + if chunk_left is not None: + # We are at the end of chunk. dicard chunk end + self._safe_read(2) # toss the CRLF at the end of the chunk + try: + chunk_left = self._read_next_chunk_size() + except ValueError: + raise IncompleteRead(b'') + if chunk_left == 0: + # last chunk: 1*("0") [ chunk-extension ] CRLF + self._read_and_discard_trailer() + # we read everything; close the "file" + self._close_conn() + chunk_left = None + self.chunk_left = chunk_left + return chunk_left + def _readall_chunked(self): assert self.chunked != _UNKNOWN - chunk_left = self.chunk_left value = [] - while True: - if chunk_left is None: - try: - chunk_left = self._read_next_chunk_size() - if chunk_left == 0: - break - except ValueError: - raise IncompleteRead(b''.join(value)) - value.append(self._safe_read(chunk_left)) - - # we read the whole chunk, get another - self._safe_read(2) # toss the CRLF at the end of the chunk - chunk_left = None - - self._read_and_discard_trailer() - - # we read everything; close the "file" - self._close_conn() - - return b''.join(value) + try: + while True: + chunk_left = self._get_chunk_left() + if chunk_left is None: + break + value.append(self._safe_read(chunk_left)) + self.chunk_left = 0 + return b''.join(value) + except IncompleteRead: + raise IncompleteRead(b''.join(value)) def _readinto_chunked(self, b): assert self.chunked != _UNKNOWN - chunk_left = self.chunk_left - total_bytes = 0 mvb = memoryview(b) - while True: - if chunk_left is None: - try: - chunk_left = self._read_next_chunk_size() - if chunk_left == 0: - break - except ValueError: - raise IncompleteRead(bytes(b[0:total_bytes])) - - if len(mvb) < chunk_left: - n = self._safe_readinto(mvb) - self.chunk_left = chunk_left - n - return total_bytes + n - elif len(mvb) == chunk_left: - n = self._safe_readinto(mvb) - self._safe_read(2) # toss the CRLF at the end of the chunk - self.chunk_left = None - return total_bytes + n - else: - temp_mvb = mvb[0:chunk_left] + try: + while True: + chunk_left = self._get_chunk_left() + if chunk_left is None: + return total_bytes + + if len(mvb) <= chunk_left: + n = self._safe_readinto(mvb) + self.chunk_left = chunk_left - n + return total_bytes + n + + temp_mvb = mvb[:chunk_left] n = self._safe_readinto(temp_mvb) mvb = mvb[n:] total_bytes += n + self.chunk_left = 0 - # we read the whole chunk, get another - self._safe_read(2) # toss the CRLF at the end of the chunk - chunk_left = None - - self._read_and_discard_trailer() - - # we read everything; close the "file" - self._close_conn() - - return total_bytes + except IncompleteRead: + raise IncompleteRead(bytes(b[0:total_bytes])) def _safe_read(self, amt): """Read the number of bytes requested, compensating for partial reads. @@ -683,10 +617,88 @@ def _safe_readinto(self, b): total_bytes += n return total_bytes + def read1(self, n=-1): + """Read with at most one underlying system call. If at least one + byte is buffered, return that instead. + """ + if self.fp is None or self._method == "HEAD": + return b"" + if self.chunked: + return self._read1_chunked(n) + try: + result = self.fp.read1(n) + except ValueError: + if n >= 0: + raise + # some implementations, like BufferedReader, don't support -1 + # Read an arbitrarily selected largeish chunk. + result = self.fp.read1(16*1024) + if not result and n: + self._close_conn() + return result + + def peek(self, n=-1): + # Having this enables IOBase.readline() to read more than one + # byte at a time + if self.fp is None or self._method == "HEAD": + return b"" + if self.chunked: + return self._peek_chunked(n) + return self.fp.peek(n) + + def readline(self, limit=-1): + if self.fp is None or self._method == "HEAD": + return b"" + if self.chunked: + # Fallback to IOBase readline which uses peek() and read() + return super().readline(limit) + result = self.fp.readline(limit) + if not result and limit: + self._close_conn() + return result + + def _read1_chunked(self, n): + # Strictly speaking, _get_chunk_left() may cause more than one read, + # but that is ok, since that is to satisfy the chunked protocol. + chunk_left = self._get_chunk_left() + if chunk_left is None or n == 0: + return b'' + if not (0 <= n <= chunk_left): + n = chunk_left # if n is negative or larger than chunk_left + read = self.fp.read1(n) + self.chunk_left -= len(read) + if not read: + raise IncompleteRead(b"") + return read + + def _peek_chunked(self, n): + # Strictly speaking, _get_chunk_left() may cause more than one read, + # but that is ok, since that is to satisfy the chunked protocol. + try: + chunk_left = self._get_chunk_left() + except IncompleteRead: + return b'' # peek doesn't worry about protocol + if chunk_left is None: + return b'' # eof + # peek is allowed to return more than requested. Just request the + # entire chunk, and truncate what we get. + return self.fp.peek(chunk_left)[:chunk_left] + def fileno(self): return self.fp.fileno() def getheader(self, name, default=None): + '''Returns the value of the header matching *name*. + + If there are multiple matching headers, the values are + combined into a single string separated by commas and spaces. + + If no matching header is found, returns *default* or None if + the *default* is not specified. + + If the headers are unknown, raises http.client.ResponseNotReady. + + ''' if self.headers is None: raise ResponseNotReady() headers = self.headers.get_all(name) or default @@ -709,12 +721,45 @@ def __iter__(self): # For compatibility with old-style urllib responses. def info(self): + '''Returns an instance of the class mimetools.Message containing + meta-information associated with the URL. + + When the method is HTTP, these headers are those returned by + the server at the head of the retrieved HTML page (including + Content-Length and Content-Type). + + When the method is FTP, a Content-Length header will be + present if (as is now usual) the server passed back a file + length in response to the FTP retrieval request. A + Content-Type header will be present if the MIME type can be + guessed. + + When the method is local-file, returned headers will include + a Date representing the file’s last-modified time, a + Content-Length giving file size, and a Content-Type + containing a guess at the file’s type. See also the + description of the mimetools module. + + ''' return self.headers def geturl(http://github.com/self): + '''Return the real URL of the page. + + In some cases, the HTTP server redirects a client to another + URL. The urlopen() function handles this transparently, but in + some cases the caller needs to know which URL the client was + redirected to. The geturl() method can be used to get at this + redirected URL. + + ''' return self.url def getcode(self): + '''Return the HTTP status code that was sent with the response, + or None if the URL is not an HTTP URL. + + ''' return self.status class HTTPConnection: @@ -726,14 +771,6 @@ class HTTPConnection: default_port = HTTP_PORT auto_open = 1 debuglevel = 0 - # TCP Maximum Segment Size (MSS) is determined by the TCP stack on - # a per-connection basis. There is no simple and efficient - # platform independent mechanism for determining the MSS, so - # instead a reasonable estimate is chosen. The getsockopt() - # interface using the TCP_MAXSEG parameter may be a suitable - # approach on some operating systems. A value of 16KiB is chosen - # as a reasonable estimate of the maximum MSS. - mss = 16384 def __init__(self, host, port=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, source_address=None): @@ -748,22 +785,37 @@ def __init__(self, host, port=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, self._tunnel_port = None self._tunnel_headers = {} - self._set_hostport(host, port) + (self.host, self.port) = self._get_hostport(host, port) + + # This is stored as an instance variable to allow unit + # tests to replace it with a suitable mockup + self._create_connection = socket.create_connection def set_tunnel(self, host, port=None, headers=None): - """ Sets up the host and the port for the HTTP CONNECT Tunnelling. + """Set up host and port for HTTP CONNECT tunnelling. + + In a connection that uses HTTP CONNECT tunneling, the host passed to the + constructor is used as a proxy server that relays all communication to + the endpoint passed to `set_tunnel`. This done by sending an HTTP + CONNECT request to the proxy server when the connection is established. - The headers argument should be a mapping of extra HTTP headers - to send with the CONNECT request. + This method must be called before the HTML connection has been + established. + + The headers argument should be a mapping of extra HTTP headers to send + with the CONNECT request. """ - self._tunnel_host = host - self._tunnel_port = port + + if self.sock: + raise RuntimeError("Can't set up tunnel for established connection") + + self._tunnel_host, self._tunnel_port = self._get_hostport(host, port) if headers: self._tunnel_headers = headers else: self._tunnel_headers.clear() - def _set_hostport(self, host, port): + def _get_hostport(self, host, port): if port is None: i = host.rfind(':') j = host.rfind(']') # ipv6 addresses have [...] @@ -780,15 +832,15 @@ def _set_hostport(self, host, port): port = self.default_port if host and host[0] == '[' and host[-1] == ']': host = host[1:-1] - self.host = host - self.port = port + + return (host, port) def set_debuglevel(self, level): self.debuglevel = level def _tunnel(self): - self._set_hostport(self._tunnel_host, self._tunnel_port) - connect_str = "CONNECT %s:%d HTTP/1.0\r\n" % (self.host, self.port) + connect_str = "CONNECT %s:%d HTTP/1.0\r\n" % (self._tunnel_host, + self._tunnel_port) connect_bytes = connect_str.encode("ascii") self.send(connect_bytes) for header, value in self._tunnel_headers.items(): @@ -800,7 +852,7 @@ def _tunnel(self): response = self.response_class(self.sock, method=self._method) (version, code, message) = response._read_status() - if code != 200: + if code != http.HTTPStatus.OK: self.close() raise OSError("Tunnel connection failed: %d %s" % (code, message.strip())) @@ -814,22 +866,31 @@ def _tunnel(self): if line in (b'\r\n', b'\n', b''): break + if self.debuglevel > 0: + print('header:', line.decode()) + def connect(self): """Connect to the host and port specified in __init__.""" - self.sock = socket.create_connection((self.host,self.port), - self.timeout, self.source_address) + self.sock = self._create_connection( + (self.host,self.port), self.timeout, self.source_address) + self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + if self._tunnel_host: self._tunnel() def close(self): """Close the connection to the HTTP server.""" - if self.sock: - self.sock.close() # close it manually... there may be other refs - self.sock = None - if self.__response: - self.__response.close() - self.__response = None self.__state = _CS_IDLE + try: + sock = self.sock + if sock: + self.sock = None + sock.close() # close it manually... there may be other refs + finally: + response = self.__response + if response: + self.__response = None + response.close() def send(self, data): """Send `data' to the server. @@ -895,19 +956,9 @@ def _send_output(self, message_body=None): self._buffer.extend((b"", b"")) msg = b"\r\n".join(self._buffer) del self._buffer[:] - # If msg and message_body are sent in a single send() call, - # it will avoid performance problems caused by the interaction - # between delayed ack and the Nagle algorithm. However, - # there is no performance gain if the message is larger - # than MSS (and there is a memory penalty for the message - # copy). - if isinstance(message_body, bytes) and len(message_body) < self.mss: - msg += message_body - message_body = None + self.send(msg) if message_body is not None: - # message_body was not a string (i.e. it is a file), and - # we must run the risk of Nagle. self.send(message_body) def putrequest(self, method, url, skip_host=0, skip_accept_encoding=0): @@ -986,22 +1037,29 @@ def putrequest(self, method, url, skip_host=0, skip_accept_encoding=0): netloc_enc = netloc.encode("idna") self.putheader('Host', netloc_enc) else: + if self._tunnel_host: + host = self._tunnel_host + port = self._tunnel_port + else: + host = self.host + port = self.port + try: - host_enc = self.host.encode("ascii") + host_enc = host.encode("ascii") except UnicodeEncodeError: - host_enc = self.host.encode("idna") + host_enc = host.encode("idna") # As per RFC 273, IPv6 address should be wrapped with [] # when used as Host header - if self.host.find(':') >= 0: + if host.find(':') >= 0: host_enc = b'[' + host_enc + b']' - if self.port == self.default_port: + if port == self.default_port: self.putheader('Host', host_enc) else: host_enc = host_enc.decode("ascii") - self.putheader('Host', "%s:%s" % (host_enc, self.port)) + self.putheader('Host', "%s:%s" % (host_enc, port)) # note: we are assuming that clients will not attempt to set these # headers since *this* library must deal with the @@ -1036,12 +1094,20 @@ def putheader(self, header, *values): if hasattr(header, 'encode'): header = header.encode('ascii') + + if not _is_legal_header_name(header): + raise ValueError('Invalid header name %r' % (header,)) + values = list(values) for i, one_value in enumerate(values): if hasattr(one_value, 'encode'): values[i] = one_value.encode('latin-1') elif isinstance(one_value, int): values[i] = str(one_value).encode('ascii') + + if _is_illegal_header_value(values[i]): + raise ValueError('Invalid header value %r' % (values[i],)) + value = b'\r\n\t'.join(values) header = header + b': ' + value self._output(header) @@ -1065,19 +1131,26 @@ def request(self, method, url, body=None, headers={}): """Send a complete request to the server.""" self._send_request(method, url, body, headers) - def _set_content_length(self, body): - # Set the content-length based on the body. + def _set_content_length(self, body, method): + # Set the content-length based on the body. If the body is "empty", we + # set Content-Length: 0 for methods that expect a body (RFC 7230, + # Section 3.3.2). If the body is set for other methods, we set the + # header provided we can figure out what the length is. thelen = None - try: - thelen = str(len(body)) - except TypeError as te: - # If this is a file-like object, try to - # fstat its file descriptor + method_expects_body = method.upper() in _METHODS_EXPECTING_BODY + if body is None and method_expects_body: + thelen = '0' + elif body is not None: try: - thelen = str(os.fstat(body.fileno()).st_size) - except (AttributeError, OSError): - # Don't send a length if this failed - if self.debuglevel > 0: print("Cannot stat!!") + thelen = str(len(body)) + except TypeError: + # If this is a file-like object, try to + # fstat its file descriptor + try: + thelen = str(os.fstat(body.fileno()).st_size) + except (AttributeError, OSError): + # Don't send a length if this failed + if self.debuglevel > 0: print("Cannot stat!!") if thelen is not None: self.putheader('Content-Length', thelen) @@ -1093,8 +1166,8 @@ def _send_request(self, method, url, body, headers): self.putrequest(method, url, **skips) - if body is not None and ('content-length' not in header_names): - self._set_content_length(body) + if 'content-length' not in header_names: + self._set_content_length(body, method) for hdr, value in headers.items(): self.putheader(hdr, value) if isinstance(body, str): @@ -1145,18 +1218,26 @@ class the response_class variable. else: response = self.response_class(self.sock, method=self._method) - response.begin() - assert response.will_close != _UNKNOWN - self.__state = _CS_IDLE + try: + try: + response.begin() + except ConnectionError: + self.close() + raise + assert response.will_close != _UNKNOWN + self.__state = _CS_IDLE - if response.will_close: - # this effectively passes the connection to the response - self.close() - else: - # remember this, so we can tell when it is complete - self.__response = response + if response.will_close: + # this effectively passes the connection to the response + self.close() + else: + # remember this, so we can tell when it is complete + self.__response = response - return response + return response + except: + response.close() + raise try: import ssl @@ -1179,11 +1260,11 @@ def __init__(self, host, port=None, key_file=None, cert_file=None, self.key_file = key_file self.cert_file = cert_file if context is None: - context = ssl._create_stdlib_context() + context = ssl._create_default_https_context() will_verify = context.verify_mode != ssl.CERT_NONE if check_hostname is None: - check_hostname = will_verify - elif check_hostname and not will_verify: + check_hostname = context.check_hostname + if check_hostname and not will_verify: raise ValueError("check_hostname needs a SSL context with " "either CERT_OPTIONAL or CERT_REQUIRED") if key_file or cert_file: @@ -1194,23 +1275,22 @@ def __init__(self, host, port=None, key_file=None, cert_file=None, def connect(self): "Connect to a host on a given (SSL) port." - sock = socket.create_connection((self.host, self.port), - self.timeout, self.source_address) + super().connect() if self._tunnel_host: - self.sock = sock - self._tunnel() + server_hostname = self._tunnel_host + else: + server_hostname = self.host - server_hostname = self.host if ssl.HAS_SNI else None - self.sock = self._context.wrap_socket(sock, + self.sock = self._context.wrap_socket(self.sock, server_hostname=server_hostname) - try: - if self._check_hostname: - ssl.match_hostname(self.sock.getpeercert(), self.host) - except Exception: - self.sock.shutdown(socket.SHUT_RDWR) - self.sock.close() - raise + if not self._context.check_hostname and self._check_hostname: + try: + ssl.match_hostname(self.sock.getpeercert(), server_hostname) + except Exception: + self.sock.shutdown(socket.SHUT_RDWR) + self.sock.close() + raise __all__.append("HTTPSConnection") @@ -1246,7 +1326,8 @@ def __repr__(self): e = ', %i more expected' % self.expected else: e = '' - return 'IncompleteRead(%i bytes read%s)' % (len(self.partial), e) + return '%s(%i bytes read%s)' % (self.__class__.__name__, + len(self.partial), e) def __str__(self): return repr(self) @@ -1274,5 +1355,10 @@ def __init__(self, line_type): HTTPException.__init__(self, "got more than %d bytes when reading %s" % (_MAXLINE, line_type)) +class RemoteDisconnected(ConnectionResetError, BadStatusLine): + def __init__(self, *pos, **kw): + BadStatusLine.__init__(self, "") + ConnectionResetError.__init__(self, *pos, **kw) + # for backwards compatibility error = HTTPException diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py index be828eba6987..b1ba72ec55a7 100644 --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -472,26 +472,42 @@ def parse_ns_headers(ns_headers): for ns_header in ns_headers: pairs = [] version_set = False - for ii, param in enumerate(re.split(r";\s*", ns_header)): - param = param.rstrip() - if param == "": continue - if "=" not in param: - k, v = param, None - else: - k, v = re.split(r"\s*=\s*", param, 1) - k = k.lstrip() + + # XXX: The following does not strictly adhere to RFCs in that empty + # names and values are legal (the former will only appear once and will + # be overwritten if multiple occurrences are present). This is + # mostly to deal with backwards compatibility. + for ii, param in enumerate(ns_header.split(';')): + param = param.strip() + + key, sep, val = param.partition('=') + key = key.strip() + + if not key: + if ii == 0: + break + else: + continue + + # allow for a distinction between present and empty and missing + # altogether + val = val.strip() if sep else None + if ii != 0: - lc = k.lower() + lc = key.lower() if lc in known_attrs: - k = lc - if k == "version": + key = lc + + if key == "version": # This is an RFC 2109 cookie. - v = strip_quotes(v) + if val is not None: + val = strip_quotes(val) version_set = True - if k == "expires": + elif key == "expires": # convert expires date to seconds since epoch - v = http2time(strip_quotes(v)) # None if invalid - pairs.append((k, v)) + if val is not None: + val = http2time(strip_quotes(val)) # None if invalid + pairs.append((key, val)) if pairs: if not version_set: @@ -742,7 +758,7 @@ def __init__(self, version, name, value, ): if version is not None: version = int(version) - if expires is not None: expires = int(expires) + if expires is not None: expires = int(float(expires)) if port is None and port_specified is True: raise ValueError("if port is None, port_specified must be false") @@ -805,7 +821,7 @@ def __repr__(self): args.append("%s=%s" % (name, repr(attr))) args.append("rest=%s" % repr(self._rest)) args.append("rfc2109=%s" % repr(self.rfc2109)) - return "Cookie(%s)" % ", ".join(args) + return "%s(%s)" % (self.__class__.__name__, ", ".join(args)) class CookiePolicy: @@ -1722,12 +1738,12 @@ def __len__(self): def __repr__(self): r = [] for cookie in self: r.append(repr(cookie)) - return "<%s[%s]>" % (self.__class__, ", ".join(r)) + return "<%s[%s]>" % (self.__class__.__name__, ", ".join(r)) def __str__(self): r = [] for cookie in self: r.append(str(cookie)) - return "<%s[%s]>" % (self.__class__, ", ".join(r)) + return "<%s[%s]>" % (self.__class__.__name__, ", ".join(r)) # derives from OSError for backwards-compatibility with Python 2.4.0 @@ -1792,7 +1808,7 @@ def revert(self, filename=None, def lwp_cookie_str(cookie): - """Return string representation of Cookie in an the LWP cookie file format. + """Return string representation of Cookie in the LWP cookie file format. Actually, the format is extended a bit -- see module docstring. @@ -1973,7 +1989,7 @@ class MozillaCookieJar(FileCookieJar): magic_re = re.compile("#( Netscape)? HTTP Cookie File") header = """\ # Netscape HTTP Cookie File -# http://www.netscape.com/newsref/std/cookie_spec.html +# http://curl.haxx.se/rfc/cookie_spec.html # This is a generated file! Do not edit. """ @@ -1983,7 +1999,6 @@ def _really_load(self, f, filename, ignore_discard, ignore_expires): magic = f.readline() if not self.magic_re.search(magic): - f.close() raise LoadError( "%r does not look like a Netscape format cookies file" % filename) diff --git a/Lib/http/cookies.py b/Lib/http/cookies.py index dc3c74a8db24..fda02b7016bc 100644 --- a/Lib/http/cookies.py +++ b/Lib/http/cookies.py @@ -1,6 +1,3 @@ -#!/usr/bin/env python3 -# - #### # Copyright 2000 by Timothy O'Malley # @@ -141,6 +138,12 @@ _semispacejoin = '; '.join _spacejoin = ' '.join +def _warn_deprecated_setter(setter): + import warnings + msg = ('The .%s setter is deprecated. The attribute will be read-only in ' + 'future releases. Please use the set() method instead.' % setter) + warnings.warn(msg, DeprecationWarning, stacklevel=3) + # # Define an exception visible to External modules # @@ -154,88 +157,36 @@ class CookieError(Exception): # into a 4 character sequence: a forward-slash followed by the # three-digit octal equivalent of the character. Any '\' or '"' is # quoted with a preceeding '\' slash. +# Because of the way browsers really handle cookies (as opposed to what +# the RFC says) we also encode "," and ";". # # These are taken from RFC2068 and RFC2109. # _LegalChars is the list of chars which don't require "'s # _Translator hash-table for fast quoting # -_LegalChars = string.ascii_letters + string.digits + "!#$%&'*+-.^_`|~:" -_Translator = { - '\000' : '\\000', '\001' : '\\001', '\002' : '\\002', - '\003' : '\\003', '\004' : '\\004', '\005' : '\\005', - '\006' : '\\006', '\007' : '\\007', '\010' : '\\010', - '\011' : '\\011', '\012' : '\\012', '\013' : '\\013', - '\014' : '\\014', '\015' : '\\015', '\016' : '\\016', - '\017' : '\\017', '\020' : '\\020', '\021' : '\\021', - '\022' : '\\022', '\023' : '\\023', '\024' : '\\024', - '\025' : '\\025', '\026' : '\\026', '\027' : '\\027', - '\030' : '\\030', '\031' : '\\031', '\032' : '\\032', - '\033' : '\\033', '\034' : '\\034', '\035' : '\\035', - '\036' : '\\036', '\037' : '\\037', - - # Because of the way browsers really handle cookies (as opposed - # to what the RFC says) we also encode , and ; - - ',' : '\\054', ';' : '\\073', - - '"' : '\\"', '\\' : '\\\\', - - '\177' : '\\177', '\200' : '\\200', '\201' : '\\201', - '\202' : '\\202', '\203' : '\\203', '\204' : '\\204', - '\205' : '\\205', '\206' : '\\206', '\207' : '\\207', - '\210' : '\\210', '\211' : '\\211', '\212' : '\\212', - '\213' : '\\213', '\214' : '\\214', '\215' : '\\215', - '\216' : '\\216', '\217' : '\\217', '\220' : '\\220', - '\221' : '\\221', '\222' : '\\222', '\223' : '\\223', - '\224' : '\\224', '\225' : '\\225', '\226' : '\\226', - '\227' : '\\227', '\230' : '\\230', '\231' : '\\231', - '\232' : '\\232', '\233' : '\\233', '\234' : '\\234', - '\235' : '\\235', '\236' : '\\236', '\237' : '\\237', - '\240' : '\\240', '\241' : '\\241', '\242' : '\\242', - '\243' : '\\243', '\244' : '\\244', '\245' : '\\245', - '\246' : '\\246', '\247' : '\\247', '\250' : '\\250', - '\251' : '\\251', '\252' : '\\252', '\253' : '\\253', - '\254' : '\\254', '\255' : '\\255', '\256' : '\\256', - '\257' : '\\257', '\260' : '\\260', '\261' : '\\261', - '\262' : '\\262', '\263' : '\\263', '\264' : '\\264', - '\265' : '\\265', '\266' : '\\266', '\267' : '\\267', - '\270' : '\\270', '\271' : '\\271', '\272' : '\\272', - '\273' : '\\273', '\274' : '\\274', '\275' : '\\275', - '\276' : '\\276', '\277' : '\\277', '\300' : '\\300', - '\301' : '\\301', '\302' : '\\302', '\303' : '\\303', - '\304' : '\\304', '\305' : '\\305', '\306' : '\\306', - '\307' : '\\307', '\310' : '\\310', '\311' : '\\311', - '\312' : '\\312', '\313' : '\\313', '\314' : '\\314', - '\315' : '\\315', '\316' : '\\316', '\317' : '\\317', - '\320' : '\\320', '\321' : '\\321', '\322' : '\\322', - '\323' : '\\323', '\324' : '\\324', '\325' : '\\325', - '\326' : '\\326', '\327' : '\\327', '\330' : '\\330', - '\331' : '\\331', '\332' : '\\332', '\333' : '\\333', - '\334' : '\\334', '\335' : '\\335', '\336' : '\\336', - '\337' : '\\337', '\340' : '\\340', '\341' : '\\341', - '\342' : '\\342', '\343' : '\\343', '\344' : '\\344', - '\345' : '\\345', '\346' : '\\346', '\347' : '\\347', - '\350' : '\\350', '\351' : '\\351', '\352' : '\\352', - '\353' : '\\353', '\354' : '\\354', '\355' : '\\355', - '\356' : '\\356', '\357' : '\\357', '\360' : '\\360', - '\361' : '\\361', '\362' : '\\362', '\363' : '\\363', - '\364' : '\\364', '\365' : '\\365', '\366' : '\\366', - '\367' : '\\367', '\370' : '\\370', '\371' : '\\371', - '\372' : '\\372', '\373' : '\\373', '\374' : '\\374', - '\375' : '\\375', '\376' : '\\376', '\377' : '\\377' - } +_LegalChars = string.ascii_letters + string.digits + "!#$%&'*+-.^_`|~:" +_UnescapedChars = _LegalChars + ' ()/<=>?@[]{}' + +_Translator = {n: '\\%03o' % n + for n in set(range(256)) - set(map(ord, _UnescapedChars))} +_Translator.update({ + ord('"'): '\\"', + ord('\\'): '\\\\', +}) + +_is_legal_key = re.compile('[%s]+' % _LegalChars).fullmatch -def _quote(str, LegalChars=_LegalChars): +def _quote(str): r"""Quote a string for use in a cookie header. If the string does not need to be double-quoted, then just return the string. Otherwise, surround the string in doublequotes and quote (with a \) special characters. """ - if all(c in LegalChars for c in str): + if str is None or _is_legal_key(str): return str else: - return '"' + _nulljoin(_Translator.get(s, s) for s in str) + '"' + return '"' + str.translate(_Translator) + '"' _OctalPatt = re.compile(r"\\[0-3][0-7][0-7]") @@ -244,7 +195,7 @@ def _quote(str, LegalChars=_LegalChars): def _unquote(str): # If there aren't any doublequotes, # then there can't be any special characters. See RFC 2109. - if len(str) < 2: + if str is None or len(str) < 2: return str if str[0] != '"' or str[-1] != '"': return str @@ -333,8 +284,8 @@ class Morsel(dict): "comment" : "Comment", "domain" : "Domain", "max-age" : "Max-Age", - "secure" : "secure", - "httponly" : "httponly", + "secure" : "Secure", + "httponly" : "HttpOnly", "version" : "Version", } @@ -342,33 +293,108 @@ class Morsel(dict): def __init__(self): # Set defaults - self.key = self.value = self.coded_value = None + self._key = self._value = self._coded_value = None # Set default attributes for key in self._reserved: dict.__setitem__(self, key, "") + @property + def key(self): + return self._key + + @key.setter + def key(self, key): + _warn_deprecated_setter('key') + self._key = key + + @property + def value(self): + return self._value + + @value.setter + def value(self, value): + _warn_deprecated_setter('value') + self._value = value + + @property + def coded_value(self): + return self._coded_value + + @coded_value.setter + def coded_value(self, coded_value): + _warn_deprecated_setter('coded_value') + self._coded_value = coded_value + def __setitem__(self, K, V): K = K.lower() if not K in self._reserved: - raise CookieError("Invalid Attribute %s" % K) + raise CookieError("Invalid attribute %r" % (K,)) dict.__setitem__(self, K, V) + def setdefault(self, key, val=None): + key = key.lower() + if key not in self._reserved: + raise CookieError("Invalid attribute %r" % (key,)) + return dict.setdefault(self, key, val) + + def __eq__(self, morsel): + if not isinstance(morsel, Morsel): + return NotImplemented + return (dict.__eq__(self, morsel) and + self._value == morsel._value and + self._key == morsel._key and + self._coded_value == morsel._coded_value) + + __ne__ = object.__ne__ + + def copy(self): + morsel = Morsel() + dict.update(morsel, self) + morsel.__dict__.update(self.__dict__) + return morsel + + def update(self, values): + data = {} + for key, val in dict(values).items(): + key = key.lower() + if key not in self._reserved: + raise CookieError("Invalid attribute %r" % (key,)) + data[key] = val + dict.update(self, data) + def isReservedKey(self, K): return K.lower() in self._reserved def set(self, key, val, coded_val, LegalChars=_LegalChars): - # First we verify that the key isn't a reserved word - # Second we make sure it only contains legal characters + if LegalChars != _LegalChars: + import warnings + warnings.warn( + 'LegalChars parameter is deprecated, ignored and will ' + 'be removed in future versions.', DeprecationWarning, + stacklevel=2) + if key.lower() in self._reserved: - raise CookieError("Attempt to set a reserved key: %s" % key) - if any(c not in LegalChars for c in key): - raise CookieError("Illegal key value: %s" % key) + raise CookieError('Attempt to set a reserved key %r' % (key,)) + if not _is_legal_key(key): + raise CookieError('Illegal key %r' % (key,)) # It's a good key, so save it. - self.key = key - self.value = val - self.coded_value = coded_val + self._key = key + self._value = val + self._coded_value = coded_val + + def __getstate__(self): + return { + 'key': self._key, + 'value': self._value, + 'coded_value': self._coded_value, + } + + def __setstate__(self, state): + self._key = state['key'] + self._value = state['value'] + self._coded_value = state['coded_value'] def output(self, attrs=None, header="Set-Cookie:"): return "%s %s" % (header, self.OutputString(attrs)) @@ -376,8 +402,7 @@ def output(self, attrs=None, header="Set-Cookie:"): __str__ = output def __repr__(self): - return '<%s: %s=%s>' % (self.__class__.__name__, - self.key, repr(self.value)) + return '<%s: %s>' % (self.__class__.__name__, self.OutputString()) def js_output(self, attrs=None): # Print javascript @@ -411,10 +436,9 @@ def OutputString(self, attrs=None): append("%s=%s" % (self._reserved[key], _getdate(value))) elif key == "max-age" and isinstance(value, int): append("%s=%d" % (self._reserved[key], value)) - elif key == "secure": - append(str(self._reserved[key])) - elif key == "httponly": - append(str(self._reserved[key])) + elif key in self._flags: + if value: + append(str(self._reserved[key])) else: append("%s=%s" % (self._reserved[key], value)) @@ -431,11 +455,13 @@ def OutputString(self, attrs=None): # result, the parsing rules here are less strict. # -_LegalCharsPatt = r"[\w\d!#%&'~_`><@,:/\$\*\+\-\.\^\|\)\(\?\}\{\=]" +_LegalKeyChars = r"\w\d!#%&'~_`><@,:/\$\*\+\-\.\^\|\)\(\?\}\{\=" +_LegalValueChars = _LegalKeyChars + '\[\]' _CookiePattern = re.compile(r""" (?x) # This is a verbose pattern + \s* # Optional whitespace at start of cookie (?P # Start of group 'key' - """ + _LegalCharsPatt + r"""+? # Any word of at least one letter + [""" + _LegalKeyChars + r"""]+? # Any word of at least one letter ) # End of group 'key' ( # Optional group: there may not be a value. \s*=\s* # Equal Sign @@ -444,7 +470,7 @@ def OutputString(self, attrs=None): | # or \w{3},\s[\w\d\s-]{9,11}\s[\d:]{8}\sGMT # Special case for "expires" attr | # or - """ + _LegalCharsPatt + r"""* # Any word or empty string + [""" + _LegalValueChars + r"""]* # Any word or empty string ) # End of group 'val' )? # End of optional value group \s* # Any number of spaces. @@ -488,8 +514,12 @@ def __set(self, key, real_value, coded_value): def __setitem__(self, key, value): """Dictionary style assignment.""" - rval, cval = self.value_encode(value) - self.__set(key, rval, cval) + if isinstance(value, Morsel): + # allow assignment of constructed Morsels (e.g. for pickling) + dict.__setitem__(self, key, value) + else: + rval, cval = self.value_encode(value) + self.__set(key, rval, cval) def output(self, attrs=None, header="Set-Cookie:", sep="\015\012"): """Return a string suitable for HTTP.""" @@ -531,13 +561,20 @@ def load(self, rawdata): return def __parse_string(self, str, patt=_CookiePattern): - i = 0 # Our starting point - n = len(str) # Length of string - M = None # current morsel + i = 0 # Our starting point + n = len(str) # Length of string + parsed_items = [] # Parsed (type, key, value) triples + morsel_seen = False # A key=value pair was previously encountered + TYPE_ATTRIBUTE = 1 + TYPE_KEYVALUE = 2 + + # We first parse the whole cookie string and reject it if it's + # syntactically invalid (this helps avoid some classes of injection + # attacks). while 0 <= i < n: # Start looking for a cookie - match = patt.search(str, i) + match = patt.match(str, i) if not match: # No more cookies break @@ -545,22 +582,41 @@ def __parse_string(self, str, patt=_CookiePattern): key, value = match.group("key"), match.group("val") i = match.end(0) - # Parse the key, value in case it's metainfo if key[0] == "$": - # We ignore attributes which pertain to the cookie - # mechanism as a whole. See RFC 2109. - # (Does anyone care?) - if M: - M[key[1:]] = value + if not morsel_seen: + # We ignore attributes which pertain to the cookie + # mechanism as a whole, such as "$Version". + # See RFC 2965. (Does anyone care?) + continue + parsed_items.append((TYPE_ATTRIBUTE, key[1:], value)) elif key.lower() in Morsel._reserved: - if M: - if value is None: - if key.lower() in Morsel._flags: - M[key] = True + if not morsel_seen: + # Invalid cookie string + return + if value is None: + if key.lower() in Morsel._flags: + parsed_items.append((TYPE_ATTRIBUTE, key, True)) else: - M[key] = _unquote(value) + # Invalid cookie string + return + else: + parsed_items.append((TYPE_ATTRIBUTE, key, _unquote(value))) elif value is not None: - rval, cval = self.value_decode(value) + parsed_items.append((TYPE_KEYVALUE, key, self.value_decode(value))) + morsel_seen = True + else: + # Invalid cookie string + return + + # The cookie string is valid, apply it. + M = None # current morsel + for tp, key, value in parsed_items: + if tp == TYPE_ATTRIBUTE: + assert M is not None + M[key] = value + else: + assert tp == TYPE_KEYVALUE + rval, cval = value self.__set(key, rval, cval) M = self[key] diff --git a/Lib/http/server.py b/Lib/http/server.py index 7b577b49ac10..e1b71abf3742 100644 --- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -82,11 +82,12 @@ __version__ = "0.6" -__all__ = ["HTTPServer", "BaseHTTPRequestHandler"] +__all__ = [ + "HTTPServer", "BaseHTTPRequestHandler", + "SimpleHTTPRequestHandler", "CGIHTTPRequestHandler", +] import html -import email.message -import email.parser import http.client import io import mimetypes @@ -102,6 +103,8 @@ import copy import argparse +from http import HTTPStatus + # Default error message template DEFAULT_ERROR_MESSAGE = """\ @@ -272,7 +275,7 @@ def parse_request(self): """ self.command = None # set in case of error on the first line self.request_version = version = self.default_request_version - self.close_connection = 1 + self.close_connection = True requestline = str(self.raw_requestline, 'iso-8859-1') requestline = requestline.rstrip('\r\n') self.requestline = requestline @@ -280,7 +283,9 @@ def parse_request(self): if len(words) == 3: command, path, version = words if version[:5] != 'HTTP/': - self.send_error(400, "Bad request version (%r)" % version) + self.send_error( + HTTPStatus.BAD_REQUEST, + "Bad request version (%r)" % version) return False try: base_version_number = version.split('/', 1)[1] @@ -295,25 +300,31 @@ def parse_request(self): raise ValueError version_number = int(version_number[0]), int(version_number[1]) except (ValueError, IndexError): - self.send_error(400, "Bad request version (%r)" % version) + self.send_error( + HTTPStatus.BAD_REQUEST, + "Bad request version (%r)" % version) return False if version_number >= (1, 1) and self.protocol_version >= "HTTP/1.1": - self.close_connection = 0 + self.close_connection = False if version_number >= (2, 0): - self.send_error(505, - "Invalid HTTP Version (%s)" % base_version_number) + self.send_error( + HTTPStatus.HTTP_VERSION_NOT_SUPPORTED, + "Invalid HTTP Version (%s)" % base_version_number) return False elif len(words) == 2: command, path = words - self.close_connection = 1 + self.close_connection = True if command != 'GET': - self.send_error(400, - "Bad HTTP/0.9 request type (%r)" % command) + self.send_error( + HTTPStatus.BAD_REQUEST, + "Bad HTTP/0.9 request type (%r)" % command) return False elif not words: return False else: - self.send_error(400, "Bad request syntax (%r)" % requestline) + self.send_error( + HTTPStatus.BAD_REQUEST, + "Bad request syntax (%r)" % requestline) return False self.command, self.path, self.request_version = command, path, version @@ -322,15 +333,17 @@ def parse_request(self): self.headers = http.client.parse_headers(self.rfile, _class=self.MessageClass) except http.client.LineTooLong: - self.send_error(400, "Line too long") + self.send_error( + HTTPStatus.BAD_REQUEST, + "Line too long") return False conntype = self.headers.get('Connection', "") if conntype.lower() == 'close': - self.close_connection = 1 + self.close_connection = True elif (conntype.lower() == 'keep-alive' and self.protocol_version >= "HTTP/1.1"): - self.close_connection = 0 + self.close_connection = False # Examine the headers and look for an Expect directive expect = self.headers.get('Expect', "") if (expect.lower() == "100-continue" and @@ -354,8 +367,8 @@ def handle_expect_100(self): False. """ - self.send_response_only(100) - self.flush_headers() + self.send_response_only(HTTPStatus.CONTINUE) + self.end_headers() return True def handle_one_request(self): @@ -372,17 +385,19 @@ def handle_one_request(self): self.requestline = '' self.request_version = '' self.command = '' - self.send_error(414) + self.send_error(HTTPStatus.REQUEST_URI_TOO_LONG) return if not self.raw_requestline: - self.close_connection = 1 + self.close_connection = True return if not self.parse_request(): # An error code has been sent, just exit return mname = 'do_' + self.command if not hasattr(self, mname): - self.send_error(501, "Unsupported method (%r)" % self.command) + self.send_error( + HTTPStatus.NOT_IMPLEMENTED, + "Unsupported method (%r)" % self.command) return method = getattr(self, mname) method() @@ -390,12 +405,12 @@ def handle_one_request(self): except socket.timeout as e: #a read or a write timed out. Discard this connection self.log_error("Request timed out: %r", e) - self.close_connection = 1 + self.close_connection = True return def handle(self): """Handle multiple requests if necessary.""" - self.close_connection = 1 + self.close_connection = True self.handle_one_request() while not self.close_connection: @@ -437,7 +452,11 @@ def send_error(self, code, message=None, explain=None): self.send_header('Connection', 'close') self.send_header('Content-Length', int(len(body))) self.end_headers() - if self.command != 'HEAD' and code >= 200 and code not in (204, 304): + + if (self.command != 'HEAD' and + code >= 200 and + code not in ( + HTTPStatus.NO_CONTENT, HTTPStatus.NOT_MODIFIED)): self.wfile.write(body) def send_response(self, code, message=None): @@ -477,9 +496,9 @@ def send_header(self, keyword, value): if keyword.lower() == 'connection': if value.lower() == 'close': - self.close_connection = 1 + self.close_connection = True elif value.lower() == 'keep-alive': - self.close_connection = 0 + self.close_connection = False def end_headers(self): """Send the blank line ending the MIME headers.""" @@ -498,7 +517,8 @@ def log_request(self, code='-', size='-'): This is called by send_response(). """ - + if isinstance(code, HTTPStatus): + code = code.value self.log_message('"%s" %s %s', self.requestline, str(code), str(size)) @@ -581,82 +601,11 @@ def address_string(self): # MessageClass used to parse headers MessageClass = http.client.HTTPMessage - # Table mapping response codes to messages; entries have the - # form {code: (shortmessage, longmessage)}. - # See RFC 2616 and 6585. + # hack to maintain backwards compatibility responses = { - 100: ('Continue', 'Request received, please continue'), - 101: ('Switching Protocols', - 'Switching to new protocol; obey Upgrade header'), - - 200: ('OK', 'Request fulfilled, document follows'), - 201: ('Created', 'Document created, URL follows'), - 202: ('Accepted', - 'Request accepted, processing continues off-line'), - 203: ('Non-Authoritative Information', 'Request fulfilled from cache'), - 204: ('No Content', 'Request fulfilled, nothing follows'), - 205: ('Reset Content', 'Clear input form for further input.'), - 206: ('Partial Content', 'Partial content follows.'), - - 300: ('Multiple Choices', - 'Object has several resources -- see URI list'), - 301: ('Moved Permanently', 'Object moved permanently -- see URI list'), - 302: ('Found', 'Object moved temporarily -- see URI list'), - 303: ('See Other', 'Object moved -- see Method and URL list'), - 304: ('Not Modified', - 'Document has not changed since given time'), - 305: ('Use Proxy', - 'You must use proxy specified in Location to access this ' - 'resource.'), - 307: ('Temporary Redirect', - 'Object moved temporarily -- see URI list'), - - 400: ('Bad Request', - 'Bad request syntax or unsupported method'), - 401: ('Unauthorized', - 'No permission -- see authorization schemes'), - 402: ('Payment Required', - 'No payment -- see charging schemes'), - 403: ('Forbidden', - 'Request forbidden -- authorization will not help'), - 404: ('Not Found', 'Nothing matches the given URI'), - 405: ('Method Not Allowed', - 'Specified method is invalid for this resource.'), - 406: ('Not Acceptable', 'URI not available in preferred format.'), - 407: ('Proxy Authentication Required', 'You must authenticate with ' - 'this proxy before proceeding.'), - 408: ('Request Timeout', 'Request timed out; try again later.'), - 409: ('Conflict', 'Request conflict.'), - 410: ('Gone', - 'URI no longer exists and has been permanently removed.'), - 411: ('Length Required', 'Client must specify Content-Length.'), - 412: ('Precondition Failed', 'Precondition in headers is false.'), - 413: ('Request Entity Too Large', 'Entity is too large.'), - 414: ('Request-URI Too Long', 'URI is too long.'), - 415: ('Unsupported Media Type', 'Entity body in unsupported format.'), - 416: ('Requested Range Not Satisfiable', - 'Cannot satisfy request range.'), - 417: ('Expectation Failed', - 'Expect condition could not be satisfied.'), - 428: ('Precondition Required', - 'The origin server requires the request to be conditional.'), - 429: ('Too Many Requests', 'The user has sent too many requests ' - 'in a given amount of time ("rate limiting").'), - 431: ('Request Header Fields Too Large', 'The server is unwilling to ' - 'process the request because its header fields are too large.'), - - 500: ('Internal Server Error', 'Server got itself in trouble'), - 501: ('Not Implemented', - 'Server does not support this operation'), - 502: ('Bad Gateway', 'Invalid responses from another server/proxy.'), - 503: ('Service Unavailable', - 'The server cannot process the request due to a high load'), - 504: ('Gateway Timeout', - 'The gateway server did not receive a timely response'), - 505: ('HTTP Version Not Supported', 'Cannot fulfill request.'), - 511: ('Network Authentication Required', - 'The client needs to authenticate to gain network access.'), - } + v: (v.phrase, v.description) + for v in HTTPStatus.__members__.values() + } class SimpleHTTPRequestHandler(BaseHTTPRequestHandler): @@ -678,8 +627,10 @@ def do_GET(self): """Serve a GET request.""" f = self.send_head() if f: - self.copyfile(f, self.wfile) - f.close() + try: + self.copyfile(f, self.wfile) + finally: + f.close() def do_HEAD(self): """Serve a HEAD request.""" @@ -701,10 +652,14 @@ def send_head(self): path = self.translate_path(self.path) f = None if os.path.isdir(path): - if not self.path.endswith('/'): + parts = urllib.parse.urlsplit(self.path) + if not parts.path.endswith('/'): # redirect browser - doing basically what apache does - self.send_response(301) - self.send_header("Location", self.path + "/") + self.send_response(HTTPStatus.MOVED_PERMANENTLY) + new_parts = (parts[0], parts[1], parts[2] + '/', + parts[3], parts[4]) + new_url = urllib.parse.urlunsplit(new_parts) + self.send_header("Location", new_url) self.end_headers() return None for index in "index.html", "index.htm": @@ -718,15 +673,19 @@ def send_head(self): try: f = open(path, 'rb') except OSError: - self.send_error(404, "File not found") + self.send_error(HTTPStatus.NOT_FOUND, "File not found") return None - self.send_response(200) - self.send_header("Content-type", ctype) - fs = os.fstat(f.fileno()) - self.send_header("Content-Length", str(fs[6])) - self.send_header("Last-Modified", self.date_time_string(fs.st_mtime)) - self.end_headers() - return f + try: + self.send_response(HTTPStatus.OK) + self.send_header("Content-type", ctype) + fs = os.fstat(f.fileno()) + self.send_header("Content-Length", str(fs[6])) + self.send_header("Last-Modified", self.date_time_string(fs.st_mtime)) + self.end_headers() + return f + except: + f.close() + raise def list_directory(self, path): """Helper to produce a directory listing (absent index.html). @@ -739,11 +698,18 @@ def list_directory(self, path): try: list = os.listdir(path) except OSError: - self.send_error(404, "No permission to list directory") + self.send_error( + HTTPStatus.NOT_FOUND, + "No permission to list directory") return None list.sort(key=lambda a: a.lower()) r = [] - displaypath = html.escape(urllib.parse.unquote(self.path)) + try: + displaypath = urllib.parse.unquote(self.path, + errors='surrogatepass') + except UnicodeDecodeError: + displaypath = urllib.parse.unquote(path) + displaypath = html.escape(displaypath) enc = sys.getfilesystemencoding() title = 'Directory listing for %s' % displaypath r.append('%s' - % (urllib.parse.quote(linkname), html.escape(displayname))) + % (urllib.parse.quote(linkname, + errors='surrogatepass'), + html.escape(displayname))) r.append('\n
\n\n\n') - encoded = '\n'.join(r).encode(enc) + encoded = '\n'.join(r).encode(enc, 'surrogateescape') f = io.BytesIO() f.write(encoded) f.seek(0) - self.send_response(200) + self.send_response(HTTPStatus.OK) self.send_header("Content-type", "text/html; charset=%s" % enc) self.send_header("Content-Length", str(len(encoded))) self.end_headers() @@ -790,7 +758,11 @@ def translate_path(self, path): path = path.split('#',1)[0] # Don't forget explicit trailing slash when normalizing. Issue17324 trailing_slash = path.rstrip().endswith('/') - path = posixpath.normpath(urllib.parse.unquote(path)) + try: + path = urllib.parse.unquote(path, errors='surrogatepass') + except UnicodeDecodeError: + path = urllib.parse.unquote(path) + path = posixpath.normpath(path) words = path.split('/') words = filter(None, words) path = os.getcwd() @@ -859,19 +831,21 @@ def guess_type(self, path): def _url_collapse_path(path): """ Given a URL path, remove extra '/'s and '.' path elements and collapse - any '..' references and returns a colllapsed path. + any '..' references and returns a collapsed path. Implements something akin to RFC-2396 5.2 step 6 to parse relative paths. The utility of this function is limited to is_cgi method and helps preventing some security attacks. - Returns: A tuple of (head, tail) where tail is everything after the final / - and head is everything before it. Head will always start with a '/' and, - if it contains anything else, never have a trailing '/'. + Returns: The reconstituted URL, which will always start with a '/'. Raises: IndexError if too many '..' occur within the path. """ + # Query component should not be involved. + path, _, query = path.partition('?') + path = urllib.parse.unquote(path) + # Similar to os.path.split(os.path.normpath(path)) but specific to URL # path semantics rather than local operating system semantics. path_parts = path.split('/') @@ -892,6 +866,9 @@ def _url_collapse_path(path): else: tail_part = '' + if query: + tail_part = '?'.join((tail_part, query)) + splitpath = ('/' + '/'.join(head_parts), tail_part) collapsed_path = "/".join(splitpath) @@ -949,7 +926,9 @@ def do_POST(self): if self.is_cgi(): self.run_cgi() else: - self.send_error(501, "Can only POST to CGI scripts") + self.send_error( + HTTPStatus.NOT_IMPLEMENTED, + "Can only POST to CGI scripts") def send_head(self): """Version of send_head that support CGI scripts""" @@ -996,25 +975,21 @@ def is_python(self, path): def run_cgi(self): """Execute a CGI script.""" dir, rest = self.cgi_info - - i = rest.find('/') + path = dir + '/' + rest + i = path.find('/', len(dir)+1) while i >= 0: - nextdir = rest[:i] - nextrest = rest[i+1:] + nextdir = path[:i] + nextrest = path[i+1:] scriptdir = self.translate_path(nextdir) if os.path.isdir(scriptdir): dir, rest = nextdir, nextrest - i = rest.find('/') + i = path.find('/', len(dir)+1) else: break # find an explicit query string, if present. - i = rest.rfind('?') - if i >= 0: - rest, query = rest[:i], rest[i+1:] - else: - query = '' + rest, _, query = rest.partition('?') # dissect the part after the directory name into a script name & # a possible additional path, to be stored in PATH_INFO. @@ -1027,17 +1002,21 @@ def run_cgi(self): scriptname = dir + '/' + script scriptfile = self.translate_path(scriptname) if not os.path.exists(scriptfile): - self.send_error(404, "No such CGI script (%r)" % scriptname) + self.send_error( + HTTPStatus.NOT_FOUND, + "No such CGI script (%r)" % scriptname) return if not os.path.isfile(scriptfile): - self.send_error(403, "CGI script is not a plain file (%r)" % - scriptname) + self.send_error( + HTTPStatus.FORBIDDEN, + "CGI script is not a plain file (%r)" % scriptname) return ispy = self.is_python(scriptname) if self.have_fork or not ispy: if not self.is_executable(scriptfile): - self.send_error(403, "CGI script is not executable (%r)" % - scriptname) + self.send_error( + HTTPStatus.FORBIDDEN, + "CGI script is not executable (%r)" % scriptname) return # Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html @@ -1105,7 +1084,7 @@ def run_cgi(self): 'HTTP_USER_AGENT', 'HTTP_COOKIE', 'HTTP_REFERER'): env.setdefault(k, "") - self.send_response(200, "Script output follows") + self.send_response(HTTPStatus.OK, "Script output follows") self.flush_headers() decoded_query = query.replace('+', ' ') @@ -1189,8 +1168,7 @@ def test(HandlerClass=BaseHTTPRequestHandler, ServerClass=HTTPServer, protocol="HTTP/1.0", port=8000, bind=""): """Test the HTTP request handler class. - This runs an HTTP server on port 8000 (or the first command line - argument). + This runs an HTTP server on port 8000 (or the port argument). """ server_address = (bind, port) diff --git a/Lib/idlelib/AutoComplete.py b/Lib/idlelib/AutoComplete.py index f3660307d35d..b20512dfa0f3 100644 --- a/Lib/idlelib/AutoComplete.py +++ b/Lib/idlelib/AutoComplete.py @@ -226,3 +226,8 @@ def get_entity(self, name): namespace = sys.modules.copy() namespace.update(__main__.__dict__) return eval(name, namespace) + + +if __name__ == '__main__': + from unittest import main + main('idlelib.idle_test.test_autocomplete', verbosity=2) diff --git a/Lib/idlelib/AutoCompleteWindow.py b/Lib/idlelib/AutoCompleteWindow.py index f666ea628bb5..2ee6878396d1 100644 --- a/Lib/idlelib/AutoCompleteWindow.py +++ b/Lib/idlelib/AutoCompleteWindow.py @@ -192,6 +192,7 @@ def show_window(self, comp_lists, index, complete, mode, userWantsWin): scrollbar.config(command=listbox.yview) scrollbar.pack(side=RIGHT, fill=Y) listbox.pack(side=LEFT, fill=BOTH, expand=True) + acw.lift() # work around bug in Tk 8.5.18+ (issue #24570) # Initialize the listbox selection self.listbox.select_set(self._binary_search(self.start)) diff --git a/Lib/idlelib/AutoExpand.py b/Lib/idlelib/AutoExpand.py index 9e93d57d6520..705905428181 100644 --- a/Lib/idlelib/AutoExpand.py +++ b/Lib/idlelib/AutoExpand.py @@ -1,3 +1,17 @@ +'''Complete the current word before the cursor with words in the editor. + +Each menu selection or shortcut key selection replaces the word with a +different word with the same prefix. The search for matches begins +before the target and moves toward the top of the editor. It then starts +after the cursor and moves down. It then returns to the original word and +the cycle starts again. + +Changing the current text line or leaving the cursor in a different +place before requesting the next selection causes AutoExpand to reset +its state. + +This is an extension file and there is only one instance of AutoExpand. +''' import string import re @@ -20,6 +34,7 @@ def __init__(self, editwin): self.state = None def expand_word_event(self, event): + "Replace the current word with the next expansion." curinsert = self.text.index("insert") curline = self.text.get("insert linestart", "insert lineend") if not self.state: @@ -46,6 +61,7 @@ def expand_word_event(self, event): return "break" def getwords(self): + "Return a list of words that match the prefix before the cursor." word = self.getprevword() if not word: return [] @@ -76,8 +92,13 @@ def getwords(self): return words def getprevword(self): + "Return the word prefix before the cursor." line = self.text.get("insert linestart", "insert") i = len(line) while i > 0 and line[i-1] in self.wordchars: i = i-1 return line[i:] + +if __name__ == '__main__': + import unittest + unittest.main('idlelib.idle_test.test_autoexpand', verbosity=2) diff --git a/Lib/idlelib/Bindings.py b/Lib/idlelib/Bindings.py index 65c0317e60cc..ab25ff18b6c3 100644 --- a/Lib/idlelib/Bindings.py +++ b/Lib/idlelib/Bindings.py @@ -8,9 +8,16 @@ windows. """ -import sys +from importlib.util import find_spec + from idlelib.configHandler import idleConf -from idlelib import macosxSupport + +# Warning: menudefs is altered in macosxSupport.overrideRootMenu() +# after it is determined that an OS X Aqua Tk is in use, +# which cannot be done until after Tk() is first called. +# Do not alter the 'file', 'options', or 'help' cascades here +# without altering overrideRootMenu() as well. +# TODO: Make this more robust menudefs = [ # underscore prefixes character to underscore @@ -70,7 +77,7 @@ ('!_Auto-open Stack Viewer', '<>'), ]), ('options', [ - ('_Configure IDLE...', '<>'), + ('Configure _IDLE', '<>'), None, ]), ('help', [ @@ -81,27 +88,7 @@ ]), ] -if macosxSupport.runningAsOSXApp(): - # Running as a proper MacOS application bundle. This block restructures - # the menus a little to make them conform better to the HIG. - - quitItem = menudefs[0][1][-1] - closeItem = menudefs[0][1][-2] - - # Remove the last 3 items of the file menu: a separator, close window and - # quit. Close window will be reinserted just above the save item, where - # it should be according to the HIG. Quit is in the application menu. - del menudefs[0][1][-3:] - menudefs[0][1].insert(6, closeItem) - - # Remove the 'About' entry from the help menu, it is in the application - # menu - del menudefs[-1][1][0:2] - - # Remove the 'Configure' entry from the options menu, it is in the - # application menu as 'Preferences' - del menudefs[-2][1][0:2] +if find_spec('turtledemo'): + menudefs[-1][1].append(('Turtle Demo', '<>')) default_keydefs = idleConf.GetCurrentKeySet() - -del sys diff --git a/Lib/idlelib/CallTipWindow.py b/Lib/idlelib/CallTipWindow.py index a2431f8eff30..8e68a76b2a8a 100644 --- a/Lib/idlelib/CallTipWindow.py +++ b/Lib/idlelib/CallTipWindow.py @@ -2,9 +2,8 @@ After ToolTip.py, which uses ideas gleaned from PySol Used by the CallTips IDLE extension. - """ -from tkinter import * +from tkinter import Toplevel, Label, LEFT, SOLID, TclError HIDE_VIRTUAL_EVENT_NAME = "<>" HIDE_SEQUENCES = ("", "") @@ -48,13 +47,7 @@ def position_window(self): def showtip(self, text, parenleft, parenright): """Show the calltip, bind events which will close it and reposition it. """ - # truncate overly long calltip - if len(text) >= 79: - textlines = text.splitlines() - for i, line in enumerate(textlines): - if len(line) > 79: - textlines[i] = line[:75] + ' ...' - text = '\n'.join(textlines) + # Only called in CallTips, where lines are truncated self.text = text if self.tipwindow or not self.text: return @@ -79,6 +72,7 @@ def showtip(self, text, parenleft, parenright): background="#ffffe0", relief=SOLID, borderwidth=1, font = self.widget['font']) self.label.pack() + tw.lift() # work around bug in Tk 8.5.18+ (issue #24570) self.checkhideid = self.widget.bind(CHECKHIDE_VIRTUAL_EVENT_NAME, self.checkhide_event) @@ -139,37 +133,29 @@ def is_active(self): return bool(self.tipwindow) - -############################### -# -# Test Code -# -class container: # Conceptually an editor_window - def __init__(self): - root = Tk() - text = self.text = Text(root) - text.pack(side=LEFT, fill=BOTH, expand=1) - text.insert("insert", "string.split") - root.update() - self.calltip = CallTip(text) - - text.event_add("<>", "(") - text.event_add("<>", ")") - text.bind("<>", self.calltip_show) - text.bind("<>", self.calltip_hide) - - text.focus_set() - root.mainloop() - - def calltip_show(self, event): - self.calltip.showtip("Hello world") - - def calltip_hide(self, event): - self.calltip.hidetip() - -def main(): - # Test code - c=container() +def _calltip_window(parent): # htest # + from tkinter import Toplevel, Text, LEFT, BOTH + + top = Toplevel(parent) + top.title("Test calltips") + top.geometry("200x100+%d+%d" % (parent.winfo_rootx() + 200, + parent.winfo_rooty() + 150)) + text = Text(top) + text.pack(side=LEFT, fill=BOTH, expand=1) + text.insert("insert", "string.split") + top.update() + calltip = CallTip(text) + + def calltip_show(event): + calltip.showtip("(s=Hello world)", "insert", "end") + def calltip_hide(event): + calltip.hidetip() + text.event_add("<>", "(") + text.event_add("<>", ")") + text.bind("<>", calltip_show) + text.bind("<>", calltip_hide) + text.focus_set() if __name__=='__main__': - main() + from idlelib.idle_test.htest import run + run(_calltip_window) diff --git a/Lib/idlelib/CallTips.py b/Lib/idlelib/CallTips.py index 41de756fa560..81bd5f1890e0 100644 --- a/Lib/idlelib/CallTips.py +++ b/Lib/idlelib/CallTips.py @@ -5,16 +5,16 @@ which disappear when you type a closing parenthesis. """ +import __main__ +import inspect import re import sys +import textwrap import types -import inspect from idlelib import CallTipWindow from idlelib.HyperParser import HyperParser -import __main__ - class CallTips: menudefs = [ @@ -116,154 +116,60 @@ def get_entity(expression): # exception, especially if user classes are involved. return None -# The following are used in both get_argspec and tests +# The following are used in get_argspec and some in tests +_MAX_COLS = 85 +_MAX_LINES = 5 # enough for bytes +_INDENT = ' '*4 # for wrapped signatures _first_param = re.compile('(?<=\()\w*\,?\s*') -_default_callable_argspec = "No docstring, see docs." +_default_callable_argspec = "See source or doc" + def get_argspec(ob): - '''Return a string describing the arguments and return of a callable object. + '''Return a string describing the signature of a callable object, or ''. For Python-coded functions and methods, the first line is introspected. Delete 'self' parameter for classes (.__init__) and bound methods. - The last line is the first line of the doc string. For builtins, this typically - includes the arguments in addition to the return value. - + The next lines are the first lines of the doc string up to the first + empty line or _MAX_LINES. For builtins, this typically includes + the arguments in addition to the return value. ''' argspec = "" - if hasattr(ob, '__call__'): - if isinstance(ob, type): - fob = getattr(ob, '__init__', None) - elif isinstance(ob.__call__, types.MethodType): - fob = ob.__call__ - else: - fob = ob - if isinstance(fob, (types.FunctionType, types.MethodType)): - argspec = inspect.formatargspec(*inspect.getfullargspec(fob)) - if (isinstance(ob, (type, types.MethodType)) or - isinstance(ob.__call__, types.MethodType)): - argspec = _first_param.sub("", argspec) - - if isinstance(ob.__call__, types.MethodType): - doc = ob.__call__.__doc__ - else: - doc = getattr(ob, "__doc__", "") - if doc: - doc = doc.lstrip() - pos = doc.find("\n") - if pos < 0 or pos > 70: - pos = 70 - if argspec: - argspec += "\n" - argspec += doc[:pos] - if not argspec: - argspec = _default_callable_argspec + try: + ob_call = ob.__call__ + except BaseException: + return argspec + if isinstance(ob, type): + fob = ob.__init__ + elif isinstance(ob_call, types.MethodType): + fob = ob_call + else: + fob = ob + if isinstance(fob, (types.FunctionType, types.MethodType)): + argspec = inspect.formatargspec(*inspect.getfullargspec(fob)) + if (isinstance(ob, (type, types.MethodType)) or + isinstance(ob_call, types.MethodType)): + argspec = _first_param.sub("", argspec) + + lines = (textwrap.wrap(argspec, _MAX_COLS, subsequent_indent=_INDENT) + if len(argspec) > _MAX_COLS else [argspec] if argspec else []) + + if isinstance(ob_call, types.MethodType): + doc = ob_call.__doc__ + else: + doc = getattr(ob, "__doc__", "") + if doc: + for line in doc.split('\n', _MAX_LINES)[:_MAX_LINES]: + line = line.strip() + if not line: + break + if len(line) > _MAX_COLS: + line = line[: _MAX_COLS - 3] + '...' + lines.append(line) + argspec = '\n'.join(lines) + if not argspec: + argspec = _default_callable_argspec return argspec -################################################# -# -# Test code tests CallTips.fetch_tip, get_entity, and get_argspec - -def main(): - # Putting expected in docstrings results in doubled tips for test - def t1(): "()" - def t2(a, b=None): "(a, b=None)" - def t3(a, *args): "(a, *args)" - def t4(*args): "(*args)" - def t5(a, b=None, *args, **kw): "(a, b=None, *args, **kw)" - - class TC(object): - "(ai=None, *b)" - def __init__(self, ai=None, *b): "(self, ai=None, *b)" - def t1(self): "(self)" - def t2(self, ai, b=None): "(self, ai, b=None)" - def t3(self, ai, *args): "(self, ai, *args)" - def t4(self, *args): "(self, *args)" - def t5(self, ai, b=None, *args, **kw): "(self, ai, b=None, *args, **kw)" - def t6(no, self): "(no, self)" - @classmethod - def cm(cls, a): "(cls, a)" - @staticmethod - def sm(b): "(b)" - def __call__(self, ci): "(self, ci)" - - tc = TC() - - # Python classes that inherit builtin methods - class Int(int): "Int(x[, base]) -> integer" - class List(list): "List() -> new empty list" - # Simulate builtin with no docstring for default argspec test - class SB: __call__ = None - - __main__.__dict__.update(locals()) # required for get_entity eval() - - num_tests = num_fail = 0 - tip = CallTips().fetch_tip - - def test(expression, expected): - nonlocal num_tests, num_fail - num_tests += 1 - argspec = tip(expression) - if argspec != expected: - num_fail += 1 - fmt = "%s - expected\n%r\n - but got\n%r" - print(fmt % (expression, expected, argspec)) - - def test_builtins(): - # if first line of a possibly multiline compiled docstring changes, - # must change corresponding test string - test('int', "int(x=0) -> integer") - test('Int', Int.__doc__) - test('types.MethodType', "method(function, instance)") - test('list', "list() -> new empty list") - test('List', List.__doc__) - test('list.__new__', - 'T.__new__(S, ...) -> a new object with type S, a subtype of T') - test('list.__init__', - 'x.__init__(...) initializes x; see help(type(x)) for signature') - append_doc = "L.append(object) -> None -- append object to end" - test('list.append', append_doc) - test('[].append', append_doc) - test('List.append', append_doc) - test('SB()', _default_callable_argspec) - - def test_funcs(): - for func in (t1, t2, t3, t4, t5, TC,): - fdoc = func.__doc__ - test(func.__name__, fdoc + "\n" + fdoc) - for func in (TC.t1, TC.t2, TC.t3, TC.t4, TC.t5, TC.t6, TC.sm, - TC.__call__): - fdoc = func.__doc__ - test('TC.'+func.__name__, fdoc + "\n" + fdoc) - fdoc = TC.cm.__func__.__doc__ - test('TC.cm.__func__', fdoc + "\n" + fdoc) - - def test_methods(): - # test that first parameter is correctly removed from argspec - # using _first_param re to calculate expected masks re errors - for meth, mdoc in ((tc.t1, "()"), (tc.t4, "(*args)"), (tc.t6, "(self)"), - (TC.cm, "(a)"),): - test('tc.'+meth.__name__, mdoc + "\n" + meth.__doc__) - test('tc', "(ci)" + "\n" + tc.__call__.__doc__) - # directly test that re works to delete unicode parameter name - uni = "(A\u0391\u0410\u05d0\u0627\u0905\u1e00\u3042, a)" # various As - assert _first_param.sub('', uni) == '(a)' - - def test_non_callables(): - # expression evaluates, but not to a callable - for expr in ('0', '0.0' 'num_tests', b'num_tests', '[]', '{}'): - test(expr, '') - # expression does not evaluate, but raises an exception - for expr in ('1a', 'xyx', 'num_tests.xyz', '[int][1]', '{0:int}[1]'): - test(expr, '') - - test_builtins() - test_funcs() - test_non_callables() - test_methods() - - print("%d of %d tests failed" % (num_fail, num_tests)) - if __name__ == '__main__': - #main() from unittest import main - main('idlelib.idle_test.test_calltips', verbosity=2, exit=False) + main('idlelib.idle_test.test_calltips', verbosity=2) diff --git a/Lib/idlelib/ChangeLog b/Lib/idlelib/ChangeLog index 985871bee7c2..90e02f6400ec 100644 --- a/Lib/idlelib/ChangeLog +++ b/Lib/idlelib/ChangeLog @@ -20,7 +20,7 @@ IDLEfork ChangeLog 2001-07-19 14:49 elguavas * ChangeLog, EditorWindow.py, INSTALLATION, NEWS.txt, README.txt, - TODO.txt, idlever.py: + TODO.txt, idlever.py: minor tidy-ups ready for 0.8.1 alpha tarball release 2001-07-17 15:12 kbk @@ -172,7 +172,7 @@ IDLEfork ChangeLog all this work w/ a future-stmt just looks harder and harder." --tim_one - (From Rel 1.8: "Hack to make this still work with Python 1.5.2. + (From Rel 1.8: "Hack to make this still work with Python 1.5.2. ;-( " --fdrake) 2001-07-14 14:51 kbk @@ -193,7 +193,7 @@ IDLEfork ChangeLog test() to _test()." --GvR This was an interesting merge. The join completely missed removing - goodname(), which was adjacent, but outside of, a small conflict. + goodname(), which was adjacent, but outside of, a small conflict. I only caught it by comparing the 1.1.3.2/1.1.3.3 diff. CVS ain't infallible. @@ -516,12 +516,12 @@ IDLEfork ChangeLog 2000-08-15 22:51 nowonder - * IDLEFORK.html: + * IDLEFORK.html: corrected email address 2000-08-15 22:47 nowonder - * IDLEFORK.html: + * IDLEFORK.html: added .html file for http://idlefork.sourceforge.net 2000-08-15 11:13 dscherer diff --git a/Lib/idlelib/ClassBrowser.py b/Lib/idlelib/ClassBrowser.py index 71176cd70154..5be65efb9bc0 100644 --- a/Lib/idlelib/ClassBrowser.py +++ b/Lib/idlelib/ClassBrowser.py @@ -19,13 +19,23 @@ from idlelib.TreeWidget import TreeNode, TreeItem, ScrolledCanvas from idlelib.configHandler import idleConf +file_open = None # Method...Item and Class...Item use this. +# Normally PyShell.flist.open, but there is no PyShell.flist for htest. + class ClassBrowser: - def __init__(self, flist, name, path): + def __init__(self, flist, name, path, _htest=False): # XXX This API should change, if the file doesn't end in ".py" # XXX the code here is bogus! + """ + _htest - bool, change box when location running htest. + """ + global file_open + if not _htest: + file_open = PyShell.flist.open self.name = name self.file = os.path.join(path[0], self.name + ".py") + self._htest = _htest self.init(flist) def close(self, event=None): @@ -40,6 +50,9 @@ def init(self, flist): self.top = top = ListedToplevel(flist.root) top.protocol("WM_DELETE_WINDOW", self.close) top.bind("", self.close) + if self._htest: # place dialog below parent if running htest + top.geometry("+%d+%d" % + (flist.root.winfo_rootx(), flist.root.winfo_rooty() + 200)) self.settitle() top.focus_set() # create scrolled canvas @@ -94,7 +107,7 @@ def listclasses(self): return [] try: dict = pyclbr.readmodule_ex(name, [dir] + sys.path) - except ImportError as msg: + except ImportError: return [] items = [] self.classes = {} @@ -163,7 +176,7 @@ def GetSubList(self): def OnDoubleClick(self): if not os.path.exists(self.file): return - edit = PyShell.flist.open(self.file) + edit = file_open(self.file) if hasattr(self.cl, 'lineno'): lineno = self.cl.lineno edit.gotoline(lineno) @@ -199,10 +212,10 @@ def IsExpandable(self): def OnDoubleClick(self): if not os.path.exists(self.file): return - edit = PyShell.flist.open(self.file) + edit = file_open(self.file) edit.gotoline(self.cl.methods[self.name]) -def main(): +def _class_browser(parent): #Wrapper for htest try: file = __file__ except NameError: @@ -213,9 +226,11 @@ def main(): file = sys.argv[0] dir, file = os.path.split(file) name = os.path.splitext(file)[0] - ClassBrowser(PyShell.flist, name, [dir]) - if sys.stdin is sys.__stdin__: - mainloop() + flist = PyShell.PyShellFileList(parent) + global file_open + file_open = flist.open + ClassBrowser(flist, name, [dir], _htest=True) if __name__ == "__main__": - main() + from idlelib.idle_test.htest import run + run(_class_browser) diff --git a/Lib/idlelib/CodeContext.py b/Lib/idlelib/CodeContext.py index 84491d5a9d1e..7d25adaa4ce3 100644 --- a/Lib/idlelib/CodeContext.py +++ b/Lib/idlelib/CodeContext.py @@ -15,8 +15,8 @@ from sys import maxsize as INFINITY from idlelib.configHandler import idleConf -BLOCKOPENERS = set(["class", "def", "elif", "else", "except", "finally", "for", - "if", "try", "while", "with"]) +BLOCKOPENERS = {"class", "def", "elif", "else", "except", "finally", "for", + "if", "try", "while", "with"} UPDATEINTERVAL = 100 # millisec FONTUPDATEINTERVAL = 1000 # millisec @@ -57,18 +57,18 @@ def toggle_code_context_event(self, event=None): # Calculate the border width and horizontal padding required to # align the context with the text in the main Text widget. # - # All values are passed through int(str()), since some + # All values are passed through getint(), since some # values may be pixel objects, which can't simply be added to ints. widgets = self.editwin.text, self.editwin.text_frame # Calculate the required vertical padding padx = 0 for widget in widgets: - padx += int(str( widget.pack_info()['padx'] )) - padx += int(str( widget.cget('padx') )) + padx += widget.tk.getint(widget.pack_info()['padx']) + padx += widget.tk.getint(widget.cget('padx')) # Calculate the required border width border = 0 for widget in widgets: - border += int(str( widget.cget('border') )) + border += widget.tk.getint(widget.cget('border')) self.label = tkinter.Label(self.editwin.top, text="\n" * (self.context_depth - 1), anchor=W, justify=LEFT, diff --git a/Lib/idlelib/ColorDelegator.py b/Lib/idlelib/ColorDelegator.py index 61e2be47c7e7..13a90103134d 100644 --- a/Lib/idlelib/ColorDelegator.py +++ b/Lib/idlelib/ColorDelegator.py @@ -2,7 +2,6 @@ import re import keyword import builtins -from tkinter import * from idlelib.Delegator import Delegator from idlelib.configHandler import idleConf @@ -32,7 +31,6 @@ def make_pat(): prog = re.compile(make_pat(), re.S) idprog = re.compile(r"\s+(\w+)", re.S) -asprog = re.compile(r".*?\b(as)\b") class ColorDelegator(Delegator): @@ -40,7 +38,6 @@ def __init__(self): Delegator.__init__(self) self.prog = prog self.idprog = idprog - self.asprog = asprog self.LoadTagDefs() def setdelegate(self, delegate): @@ -72,7 +69,6 @@ def LoadTagDefs(self): "DEFINITION": idleConf.GetHighlight(theme, "definition"), "SYNC": {'background':None,'foreground':None}, "TODO": {'background':None,'foreground':None}, - "BREAK": idleConf.GetHighlight(theme, "break"), "ERROR": idleConf.GetHighlight(theme, "error"), # The following is used by ReplaceDialog: "hit": idleConf.GetHighlight(theme, "hit"), @@ -214,22 +210,6 @@ def recolorize_main(self): self.tag_add("DEFINITION", head + "+%dc" % a, head + "+%dc" % b) - elif value == "import": - # color all the "as" words on same line, except - # if in a comment; cheap approximation to the - # truth - if '#' in chars: - endpos = chars.index('#') - else: - endpos = len(chars) - while True: - m1 = self.asprog.match(chars, b, endpos) - if not m1: - break - a, b = m1.span(1) - self.tag_add("KEYWORD", - head + "+%dc" % a, - head + "+%dc" % b) m = self.prog.search(chars, m.end()) if "SYNC" in self.tag_names(next + "-1c"): head = next @@ -253,17 +233,24 @@ def removecolors(self): for tag in self.tagdefs: self.tag_remove(tag, "1.0", "end") -def main(): +def _color_delegator(parent): # htest # + from tkinter import Toplevel, Text from idlelib.Percolator import Percolator - root = Tk() - root.wm_protocol("WM_DELETE_WINDOW", root.quit) - text = Text(background="white") + + top = Toplevel(parent) + top.title("Test ColorDelegator") + top.geometry("200x100+%d+%d" % (parent.winfo_rootx() + 200, + parent.winfo_rooty() + 150)) + source = "if somename: x = 'abc' # comment\nprint\n" + text = Text(top, background="white") text.pack(expand=1, fill="both") + text.insert("insert", source) text.focus_set() + p = Percolator(text) d = ColorDelegator() p.insertfilter(d) - root.mainloop() if __name__ == "__main__": - main() + from idlelib.idle_test.htest import run + run(_color_delegator) diff --git a/Lib/idlelib/Debugger.py b/Lib/idlelib/Debugger.py index ed66084e91c6..6875197874eb 100644 --- a/Lib/idlelib/Debugger.py +++ b/Lib/idlelib/Debugger.py @@ -1,6 +1,5 @@ import os import bdb -import types from tkinter import * from idlelib.WindowList import ListedToplevel from idlelib.ScrolledList import ScrolledList @@ -254,8 +253,7 @@ def show_source(self): self.sync_source_line() def show_frame(self, stackitem): - frame, lineno = stackitem - self.frame = frame + self.frame = stackitem[0] # lineno is stackitem[1] self.show_variables() localsviewer = None @@ -323,7 +321,7 @@ def load_breakpoints(self): class StackViewer(ScrolledList): def __init__(self, master, flist, gui): - if macosxSupport.runningAsOSXApp(): + if macosxSupport.isAquaTk(): # At least on with the stock AquaTk version on OSX 10.4 you'll # get an shaking GUI that eventually kills IDLE if the width # argument is specified. diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py index eaf68cb75411..0196344d8dcd 100644 --- a/Lib/idlelib/EditorWindow.py +++ b/Lib/idlelib/EditorWindow.py @@ -1,6 +1,8 @@ import importlib import importlib.abc +import importlib.util import os +import platform import re import string import sys @@ -11,7 +13,6 @@ import webbrowser from idlelib.MultiCall import MultiCallCreator -from idlelib import idlever from idlelib import WindowList from idlelib import SearchDialog from idlelib import GrepDialog @@ -20,10 +21,13 @@ from idlelib.configHandler import idleConf from idlelib import aboutDialog, textView, configDialog from idlelib import macosxSupport +from idlelib import help # The default tab setting for a Text widget, in average-width characters. TK_TABWIDTH_DEFAULT = 8 +_py_version = ' (%s)' % platform.python_version() + def _sphinx_version(): "Format sys.version_info to produce the Sphinx version string used to install the chm docs" major, minor, micro, level, serial = sys.version_info @@ -50,6 +54,11 @@ def display(self, parent, near=None): near - a Toplevel widget (e.g. EditorWindow or PyShell) to use as a reference for placing the help window """ + import warnings as w + w.warn("EditorWindow.HelpDialog is no longer used by Idle.\n" + "It will be removed in 3.6 or later.\n" + "It has been replaced by private help.HelpWindow\n", + DeprecationWarning, stacklevel=2) if self.dlg is None: self.show_dialog(parent) if near: @@ -76,7 +85,7 @@ def destroy(self, ev=None): self.dlg = None self.parent = None -helpDialog = HelpDialog() # singleton instance +helpDialog = HelpDialog() # singleton instance, no longer used class EditorWindow(object): @@ -107,8 +116,8 @@ def __init__(self, flist=None, filename=None, key=None, root=None): 'Python%s.chm' % _sphinx_version()) if os.path.isfile(chmfile): dochome = chmfile - elif macosxSupport.runningAsOSXApp(): - # documentation is stored inside the python framework + elif sys.platform == 'darwin': + # documentation may be stored inside a python framework dochome = os.path.join(sys.base_prefix, 'Resources/English.lproj/Documentation/index.html') dochome = os.path.normpath(dochome) @@ -118,8 +127,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None): # Safari requires real file:-URLs EditorWindow.help_url = 'file://' + EditorWindow.help_url else: - EditorWindow.help_url = "http://docs.python.org/%d.%d" % sys.version_info[:2] - currentTheme=idleConf.CurrentTheme() + EditorWindow.help_url = "https://docs.python.org/%d.%d/" % sys.version_info[:2] self.flist = flist root = root or flist.root self.root = root @@ -164,16 +172,16 @@ def __init__(self, flist=None, filename=None, key=None, root=None): self.top.protocol("WM_DELETE_WINDOW", self.close) self.top.bind("<>", self.close_event) - if macosxSupport.runningAsOSXApp(): + if macosxSupport.isAquaTk(): # Command-W on editorwindows doesn't work without this. text.bind('<>', self.close_event) - # Some OS X systems have only one mouse button, - # so use control-click for pulldown menus there. - # (Note, AquaTk defines <2> as the right button if - # present and the Tk Text widget already binds <2>.) + # Some OS X systems have only one mouse button, so use + # control-click for popup context menus there. For two + # buttons, AquaTk defines <2> as the right button, not <3>. text.bind("",self.right_menu_event) + text.bind("<2>", self.right_menu_event) else: - # Elsewhere, use right-click for pulldown menus. + # Elsewhere, use right-click for popup menus. text.bind("<3>",self.right_menu_event) text.bind("<>", self.cut) text.bind("<>", self.copy) @@ -218,18 +226,13 @@ def __init__(self, flist=None, filename=None, key=None, root=None): text.bind("<>", self.flist.close_all_callback) text.bind("<>", self.open_class_browser) text.bind("<>", self.open_path_browser) + text.bind("<>", self.open_turtle_demo) self.set_status_bar() vbar['command'] = text.yview vbar.pack(side=RIGHT, fill=Y) text['yscrollcommand'] = vbar.set - fontWeight = 'normal' - if idleConf.GetOption('main', 'EditorWindow', 'font-bold', type='bool'): - fontWeight='bold' - text.config(font=(idleConf.GetOption('main', 'EditorWindow', 'font'), - idleConf.GetOption('main', 'EditorWindow', - 'font-size', type='int'), - fontWeight)) + text['font'] = idleConf.GetFont(self.root, 'main', 'EditorWindow') text_frame.pack(side=LEFT, fill=BOTH, expand=1) text.pack(side=TOP, fill=BOTH, expand=1) text.focus_set() @@ -312,50 +315,20 @@ def __init__(self, flist=None, filename=None, key=None, root=None): self.askinteger = tkSimpleDialog.askinteger self.showerror = tkMessageBox.showerror - self._highlight_workaround() # Fix selection tags on Windows - - def _highlight_workaround(self): - # On Windows, Tk removes painting of the selection - # tags which is different behavior than on Linux and Mac. - # See issue14146 for more information. - if not sys.platform.startswith('win'): - return - - text = self.text - text.event_add("<>", "") - text.event_add("<>", "") - def highlight_fix(focus): - sel_range = text.tag_ranges("sel") - if sel_range: - if focus == 'out': - HILITE_CONFIG = idleConf.GetHighlight( - idleConf.CurrentTheme(), 'hilite') - text.tag_config("sel_fix", HILITE_CONFIG) - text.tag_raise("sel_fix") - text.tag_add("sel_fix", *sel_range) - elif focus == 'in': - text.tag_remove("sel_fix", "1.0", "end") - - text.bind("<>", - lambda ev: highlight_fix("out")) - text.bind("<>", - lambda ev: highlight_fix("in")) - - def _filename_to_unicode(self, filename): - """convert filename to unicode in order to display it in Tk""" - if isinstance(filename, str) or not filename: - return filename - else: + """Return filename as BMP unicode so diplayable in Tk.""" + # Decode bytes to unicode. + if isinstance(filename, bytes): try: - return filename.decode(self.filesystemencoding) + filename = filename.decode(self.filesystemencoding) except UnicodeDecodeError: - # XXX try: - return filename.decode(self.encoding) + filename = filename.decode(self.encoding) except UnicodeDecodeError: # byte-to-byte conversion - return filename.decode('iso8859-1') + filename = filename.decode('iso8859-1') + # Replace non-BMP char with diamond questionmark. + return re.sub('[\U00010000-\U0010FFFF]', '\ufffd', filename) def new_callback(self, event): dirname, basename = self.io.defaultfilename() @@ -407,7 +380,7 @@ def home_callback(self, event): def set_status_bar(self): self.status_bar = self.MultiStatusBar(self.top) - if macosxSupport.runningAsOSXApp(): + if sys.platform == "darwin": # Insert some padding to avoid obscuring some of the statusbar # by the resize widget. self.status_bar.set_label('_padding1', ' ', side=RIGHT) @@ -430,27 +403,25 @@ def set_line_and_column(self, event=None): ("format", "F_ormat"), ("run", "_Run"), ("options", "_Options"), - ("windows", "_Windows"), + ("windows", "_Window"), ("help", "_Help"), ] - if macosxSupport.runningAsOSXApp(): - menu_specs[-2] = ("windows", "_Window") - def createmenubar(self): mbar = self.menubar self.menudict = menudict = {} for name, label in self.menu_specs: underline, label = prepstr(label) - menudict[name] = menu = Menu(mbar, name=name) + menudict[name] = menu = Menu(mbar, name=name, tearoff=0) mbar.add_cascade(label=label, menu=menu, underline=underline) - if macosxSupport.isCarbonAquaTk(self.root): + if macosxSupport.isCarbonTk(): # Insert the application menu - menudict['application'] = menu = Menu(mbar, name='apple') + menudict['application'] = menu = Menu(mbar, name='apple', + tearoff=0) mbar.add_cascade(label='IDLE', menu=menu) self.fill_menus() - self.recent_files_menu = Menu(self.menubar) + self.recent_files_menu = Menu(self.menubar, tearoff=0) self.menudict['file'].insert_cascade(3, label='Recent Files', underline=0, menu=self.recent_files_menu) @@ -532,17 +503,23 @@ def rmenu_check_paste(self): return 'normal' def about_dialog(self, event=None): + "Handle Help 'About IDLE' event." + # Synchronize with macosxSupport.overrideRootMenu.about_dialog. aboutDialog.AboutDialog(self.top,'About IDLE') def config_dialog(self, event=None): + "Handle Options 'Configure IDLE' event." + # Synchronize with macosxSupport.overrideRootMenu.config_dialog. configDialog.ConfigDialog(self.top,'Settings') def help_dialog(self, event=None): + "Handle Help 'IDLE Help' event." + # Synchronize with macosxSupport.overrideRootMenu.help_dialog. if self.root: parent = self.root else: parent = self.top - helpDialog.display(parent, near=self.top) + help.show_idlehelp(parent) def python_docs(self, event=None): if sys.platform[:3] == 'win': @@ -659,20 +636,20 @@ def open_module(self, event=None): return # XXX Ought to insert current file's directory in front of path try: - loader = importlib.find_loader(name) + spec = importlib.util.find_spec(name) except (ValueError, ImportError) as msg: tkMessageBox.showerror("Import error", str(msg), parent=self.text) return - if loader is None: + if spec is None: tkMessageBox.showerror("Import error", "module not found", parent=self.text) return - if not isinstance(loader, importlib.abc.SourceLoader): + if not isinstance(spec.loader, importlib.abc.SourceLoader): tkMessageBox.showerror("Import error", "not a source-based module", parent=self.text) return try: - file_path = loader.get_filename(name) + file_path = spec.loader.get_filename(name) except AttributeError: tkMessageBox.showerror("Import error", "loader does not support get_filename", @@ -682,16 +659,15 @@ def open_module(self, event=None): self.flist.open(file_path) else: self.io.loadfile(file_path) + return file_path def open_class_browser(self, event=None): filename = self.io.filename - if not filename: - tkMessageBox.showerror( - "No filename", - "This buffer has no associated filename", - master=self.text) - self.text.focus_set() - return None + if not (self.__class__.__name__ == 'PyShellEditorWindow' + and filename): + filename = self.open_module() + if filename is None: + return head, tail = os.path.split(filename) base, ext = os.path.splitext(tail) from idlelib import ClassBrowser @@ -701,6 +677,14 @@ def open_path_browser(self, event=None): from idlelib import PathBrowser PathBrowser.PathBrowser(self.flist) + def open_turtle_demo(self, event = None): + import subprocess + + cmd = [sys.executable, + '-c', + 'from turtledemo.__main__ import main; main()'] + subprocess.Popen(cmd, shell=False) + def gotoline(self, lineno): if lineno is not None and lineno > 0: self.text.mark_set("insert", "%d.0" % lineno) @@ -751,7 +735,7 @@ def _rmcolorizer(self): self.color = None def ResetColorizer(self): - "Update the colour theme" + "Update the color theme" # Called from self.filename_change_hook and from configDialog.py self._rmcolorizer() self._addcolorizer() @@ -766,6 +750,9 @@ def ResetColorizer(self): selectforeground=select_colors['foreground'], selectbackground=select_colors['background'], ) + if TkVersion >= 8.5: + self.text.config( + inactiveselectbackground=select_colors['background']) IDENTCHARS = string.ascii_letters + string.digits + "_" @@ -783,13 +770,8 @@ def colorize_syntax_error(self, text, pos): def ResetFont(self): "Update the text widgets' font if it is changed" # Called from configDialog.py - fontWeight='normal' - if idleConf.GetOption('main','EditorWindow','font-bold',type='bool'): - fontWeight='bold' - self.text.config(font=(idleConf.GetOption('main','EditorWindow','font'), - idleConf.GetOption('main','EditorWindow','font-size', - type='int'), - fontWeight)) + + self.text['font'] = idleConf.GetFont(self.root, 'main','EditorWindow') def RemoveKeybindings(self): "Remove the keybindings before they are changed." @@ -931,7 +913,7 @@ def saved_change_hook(self): short = self.short_title() long = self.long_title() if short and long: - title = short + " - " + long + title = short + " - " + long + _py_version elif short: title = short elif long: @@ -958,6 +940,8 @@ def short_title(self): filename = self.io.filename if filename: filename = os.path.basename(filename) + else: + filename = "Untitled" # return unicode string to display non-ASCII chars correctly return self._filename_to_unicode(filename) @@ -1059,7 +1043,7 @@ def load_extension(self, name): try: try: mod = importlib.import_module('.' + name, package=__package__) - except ImportError: + except (ImportError, TypeError): mod = importlib.import_module(name) except ImportError: print("\nFailed to import extension: ", name) @@ -1668,7 +1652,7 @@ def get_accelerator(keydefs, eventname): keylist = keydefs.get(eventname) # issue10940: temporary workaround to prevent hang with OS X Cocoa Tk 8.5 # if not keylist: - if (not keylist) or (macosxSupport.runningAsOSXApp() and eventname in { + if (not keylist) or (macosxSupport.isCocoaTk() and eventname in { "<>", "<>", "<>"}): @@ -1695,19 +1679,20 @@ def fixwordbreaks(root): tk.call('set', 'tcl_nonwordchars', '[^a-zA-Z0-9_]') -def test(): - root = Tk() +def _editor_window(parent): # htest # + # error if close master window first - timer event, after script + root = parent fixwordbreaks(root) - root.withdraw() if sys.argv[1:]: filename = sys.argv[1] else: filename = None + macosxSupport.setupApp(root, None) edit = EditorWindow(root=root, filename=filename) - edit.set_close_hook(root.quit) edit.text.bind("<>", edit.close_event) - root.mainloop() - root.destroy() + # Does not stop error, neither does following + # edit.text.bind("<>", edit.close_event) if __name__ == '__main__': - test() + from idlelib.idle_test.htest import run + run(_editor_window) diff --git a/Lib/idlelib/FormatParagraph.py b/Lib/idlelib/FormatParagraph.py index ae4e6e7b9115..7a9d185042e6 100644 --- a/Lib/idlelib/FormatParagraph.py +++ b/Lib/idlelib/FormatParagraph.py @@ -32,7 +32,7 @@ def __init__(self, editwin): def close(self): self.editwin = None - def format_paragraph_event(self, event): + def format_paragraph_event(self, event, limit=None): """Formats paragraph to a max width specified in idleConf. If text is selected, format_paragraph_event will start breaking lines @@ -41,9 +41,14 @@ def format_paragraph_event(self, event): If no text is selected, format_paragraph_event uses the current cursor location to determine the paragraph (lines of text surrounded by blank lines) and formats it. + + The length limit parameter is for testing with a known value. """ - maxformatwidth = idleConf.GetOption( - 'main', 'FormatParagraph', 'paragraph', type='int') + if limit is None: + # The default length limit is that defined by pep8 + limit = idleConf.GetOption( + 'extensions', 'FormatParagraph', 'max-width', + type='int', default=72) text = self.editwin.text first, last = self.editwin.get_selection_indices() if first and last: @@ -53,9 +58,9 @@ def format_paragraph_event(self, event): first, last, comment_header, data = \ find_paragraph(text, text.index("insert")) if comment_header: - newdata = reformat_comment(data, maxformatwidth, comment_header) + newdata = reformat_comment(data, limit, comment_header) else: - newdata = reformat_paragraph(data, maxformatwidth) + newdata = reformat_paragraph(data, limit) text.tag_remove("sel", "1.0", "end") if newdata != data: @@ -185,7 +190,6 @@ def get_comment_header(line): return m.group(1) if __name__ == "__main__": - from test import support; support.use_resources = ['gui'] import unittest unittest.main('idlelib.idle_test.test_formatparagraph', verbosity=2, exit=False) diff --git a/Lib/idlelib/GrepDialog.py b/Lib/idlelib/GrepDialog.py index c0074e24f68e..721b231a9e86 100644 --- a/Lib/idlelib/GrepDialog.py +++ b/Lib/idlelib/GrepDialog.py @@ -1,9 +1,13 @@ import os import fnmatch +import re # for htest import sys -from tkinter import * +from tkinter import StringVar, BooleanVar, Checkbutton # for GrepDialog +from tkinter import Tk, Text, Button, SEL, END # for htest from idlelib import SearchEngine from idlelib.SearchDialogBase import SearchDialogBase +# Importing OutputWindow fails due to import loop +# EditorWindow -> GrepDialop -> OutputWindow -> EditorWindow def grep(text, io=None, flist=None): root = text._root() @@ -40,10 +44,10 @@ def open(self, text, searchphrase, io=None): def create_entries(self): SearchDialogBase.create_entries(self) - self.globent = self.make_entry("In files:", self.globvar) + self.globent = self.make_entry("In files:", self.globvar)[0] def create_other_buttons(self): - f = self.make_frame() + f = self.make_frame()[0] btn = Checkbutton(f, anchor="w", variable=self.recvar, @@ -63,7 +67,7 @@ def default_command(self, event=None): if not path: self.top.bell() return - from idlelib.OutputWindow import OutputWindow + from idlelib.OutputWindow import OutputWindow # leave here! save = sys.stdout try: sys.stdout = OutputWindow(self.flist) @@ -79,26 +83,31 @@ def grep_it(self, prog, path): pat = self.engine.getpat() print("Searching %r in %s ..." % (pat, path)) hits = 0 - for fn in list: - try: - with open(fn, errors='replace') as f: - for lineno, line in enumerate(f, 1): - if line[-1:] == '\n': - line = line[:-1] - if prog.search(line): - sys.stdout.write("%s: %s: %s\n" % - (fn, lineno, line)) - hits += 1 - except OSError as msg: - print(msg) - print(("Hits found: %s\n" - "(Hint: right-click to open locations.)" - % hits) if hits else "No hits.") + try: + for fn in list: + try: + with open(fn, errors='replace') as f: + for lineno, line in enumerate(f, 1): + if line[-1:] == '\n': + line = line[:-1] + if prog.search(line): + sys.stdout.write("%s: %s: %s\n" % + (fn, lineno, line)) + hits += 1 + except OSError as msg: + print(msg) + print(("Hits found: %s\n" + "(Hint: right-click to open locations.)" + % hits) if hits else "No hits.") + except AttributeError: + # Tk window has been closed, OutputWindow.text = None, + # so in OW.write, OW.text.insert fails. + pass def findfiles(self, dir, base, rec): try: names = os.listdir(dir or os.curdir) - except OSerror as msg: + except OSError as msg: print(msg) return [] list = [] @@ -120,8 +129,30 @@ def close(self, event=None): self.top.grab_release() self.top.withdraw() + +def _grep_dialog(parent): # htest # + from idlelib.PyShell import PyShellFileList + root = Tk() + root.title("Test GrepDialog") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + + flist = PyShellFileList(root) + text = Text(root, height=5) + text.pack() + + def show_grep_dialog(): + text.tag_add(SEL, "1.0", END) + grep(text, flist=flist) + text.tag_remove(SEL, "1.0", END) + + button = Button(root, text="Show GrepDialog", command=show_grep_dialog) + button.pack() + root.mainloop() + if __name__ == "__main__": - # A human test is a bit tricky since EditorWindow() imports this module. - # Hence Idle must be restarted after editing this file for a live test. import unittest unittest.main('idlelib.idle_test.test_grep', verbosity=2, exit=False) + + from idlelib.idle_test.htest import run + run(_grep_dialog) diff --git a/Lib/idlelib/HISTORY.txt b/Lib/idlelib/HISTORY.txt index 01d73ed2ba99..731fabd185fb 100644 --- a/Lib/idlelib/HISTORY.txt +++ b/Lib/idlelib/HISTORY.txt @@ -11,7 +11,7 @@ What's New in IDLEfork 0.8.1? *Release date: 22-Jul-2001* - New tarball released as a result of the 'revitalisation' of the IDLEfork - project. + project. - This release requires python 2.1 or better. Compatibility with earlier versions of python (especially ancient ones like 1.5x) is no longer a @@ -26,8 +26,8 @@ What's New in IDLEfork 0.8.1? not working, but I believe this was the case with the previous IDLE fork release (0.7.1) as well. -- This release is being made now to mark the point at which IDLEfork is - launching into a new stage of development. +- This release is being made now to mark the point at which IDLEfork is + launching into a new stage of development. - IDLEfork CVS will now be branched to enable further development and exploration of the two "execution in a remote process" patches submitted by @@ -96,7 +96,7 @@ IDLEfork 0.7.1 - 29 May 2000 instead of the IDLE help; shift-TAB is now a synonym for unindent. - New modules: - + ExecBinding.py Executes program through loader loader.py Bootstraps user program protocol.py RPC protocol diff --git a/Lib/idlelib/HyperParser.py b/Lib/idlelib/HyperParser.py index 4af4b085c7c0..77cb057ce21f 100644 --- a/Lib/idlelib/HyperParser.py +++ b/Lib/idlelib/HyperParser.py @@ -1,23 +1,31 @@ -""" -HyperParser -=========== -This module defines the HyperParser class, which provides advanced parsing -abilities for the ParenMatch and other extensions. -The HyperParser uses PyParser. PyParser is intended mostly to give information -on the proper indentation of code. HyperParser gives some information on the -structure of code, used by extensions to help the user. +"""Provide advanced parsing abilities for ParenMatch and other extensions. + +HyperParser uses PyParser. PyParser mostly gives information on the +proper indentation of code. HyperParser gives additional information on +the structure of code. """ import string -import keyword +from keyword import iskeyword from idlelib import PyParse -class HyperParser: +# all ASCII chars that may be in an identifier +_ASCII_ID_CHARS = frozenset(string.ascii_letters + string.digits + "_") +# all ASCII chars that may be the first char of an identifier +_ASCII_ID_FIRST_CHARS = frozenset(string.ascii_letters + "_") + +# lookup table for whether 7-bit ASCII chars are valid in a Python identifier +_IS_ASCII_ID_CHAR = [(chr(x) in _ASCII_ID_CHARS) for x in range(128)] +# lookup table for whether 7-bit ASCII chars are valid as the first +# char in a Python identifier +_IS_ASCII_ID_FIRST_CHAR = \ + [(chr(x) in _ASCII_ID_FIRST_CHARS) for x in range(128)] + + +class HyperParser: def __init__(self, editwin, index): - """Initialize the HyperParser to analyze the surroundings of the given - index. - """ + "To initialize, analyze the surroundings of the given index." self.editwin = editwin self.text = text = editwin.text @@ -33,9 +41,10 @@ def index2line(index): startat = max(lno - context, 1) startatindex = repr(startat) + ".0" stopatindex = "%d.end" % lno - # We add the newline because PyParse requires a newline at end. - # We add a space so that index won't be at end of line, so that - # its status will be the same as the char before it, if should. + # We add the newline because PyParse requires a newline + # at end. We add a space so that index won't be at end + # of line, so that its status will be the same as the + # char before it, if should. parser.set_str(text.get(startatindex, stopatindex)+' \n') bod = parser.find_good_parse_start( editwin._build_char_in_string_func(startatindex)) @@ -49,122 +58,175 @@ def index2line(index): else: startatindex = "1.0" stopatindex = "%d.end" % lno - # We add the newline because PyParse requires a newline at end. - # We add a space so that index won't be at end of line, so that - # its status will be the same as the char before it, if should. + # We add the newline because PyParse requires it. We add a + # space so that index won't be at end of line, so that its + # status will be the same as the char before it, if should. parser.set_str(text.get(startatindex, stopatindex)+' \n') parser.set_lo(0) - # We want what the parser has, except for the last newline and space. + # We want what the parser has, minus the last newline and space. self.rawtext = parser.str[:-2] - # As far as I can see, parser.str preserves the statement we are in, - # so that stopatindex can be used to synchronize the string with the - # text box indices. + # Parser.str apparently preserves the statement we are in, so + # that stopatindex can be used to synchronize the string with + # the text box indices. self.stopatindex = stopatindex self.bracketing = parser.get_last_stmt_bracketing() - # find which pairs of bracketing are openers. These always correspond - # to a character of rawtext. - self.isopener = [i>0 and self.bracketing[i][1] > self.bracketing[i-1][1] + # find which pairs of bracketing are openers. These always + # correspond to a character of rawtext. + self.isopener = [i>0 and self.bracketing[i][1] > + self.bracketing[i-1][1] for i in range(len(self.bracketing))] self.set_index(index) def set_index(self, index): - """Set the index to which the functions relate. Note that it must be - in the same statement. + """Set the index to which the functions relate. + + The index must be in the same statement. """ - indexinrawtext = \ - len(self.rawtext) - len(self.text.get(index, self.stopatindex)) + indexinrawtext = (len(self.rawtext) - + len(self.text.get(index, self.stopatindex))) if indexinrawtext < 0: - raise ValueError("The index given is before the analyzed statement") + raise ValueError("Index %s precedes the analyzed statement" + % index) self.indexinrawtext = indexinrawtext # find the rightmost bracket to which index belongs self.indexbracket = 0 - while self.indexbracket < len(self.bracketing)-1 and \ - self.bracketing[self.indexbracket+1][0] < self.indexinrawtext: + while (self.indexbracket < len(self.bracketing)-1 and + self.bracketing[self.indexbracket+1][0] < self.indexinrawtext): self.indexbracket += 1 - if self.indexbracket < len(self.bracketing)-1 and \ - self.bracketing[self.indexbracket+1][0] == self.indexinrawtext and \ - not self.isopener[self.indexbracket+1]: + if (self.indexbracket < len(self.bracketing)-1 and + self.bracketing[self.indexbracket+1][0] == self.indexinrawtext and + not self.isopener[self.indexbracket+1]): self.indexbracket += 1 def is_in_string(self): - """Is the index given to the HyperParser is in a string?""" + """Is the index given to the HyperParser in a string?""" # The bracket to which we belong should be an opener. # If it's an opener, it has to have a character. - return self.isopener[self.indexbracket] and \ - self.rawtext[self.bracketing[self.indexbracket][0]] in ('"', "'") + return (self.isopener[self.indexbracket] and + self.rawtext[self.bracketing[self.indexbracket][0]] + in ('"', "'")) def is_in_code(self): - """Is the index given to the HyperParser is in a normal code?""" - return not self.isopener[self.indexbracket] or \ - self.rawtext[self.bracketing[self.indexbracket][0]] not in \ - ('#', '"', "'") + """Is the index given to the HyperParser in normal code?""" + return (not self.isopener[self.indexbracket] or + self.rawtext[self.bracketing[self.indexbracket][0]] + not in ('#', '"', "'")) def get_surrounding_brackets(self, openers='([{', mustclose=False): - """If the index given to the HyperParser is surrounded by a bracket - defined in openers (or at least has one before it), return the - indices of the opening bracket and the closing bracket (or the - end of line, whichever comes first). - If it is not surrounded by brackets, or the end of line comes before - the closing bracket and mustclose is True, returns None. + """Return bracket indexes or None. + + If the index given to the HyperParser is surrounded by a + bracket defined in openers (or at least has one before it), + return the indices of the opening bracket and the closing + bracket (or the end of line, whichever comes first). + + If it is not surrounded by brackets, or the end of line comes + before the closing bracket and mustclose is True, returns None. """ + bracketinglevel = self.bracketing[self.indexbracket][1] before = self.indexbracket - while not self.isopener[before] or \ - self.rawtext[self.bracketing[before][0]] not in openers or \ - self.bracketing[before][1] > bracketinglevel: + while (not self.isopener[before] or + self.rawtext[self.bracketing[before][0]] not in openers or + self.bracketing[before][1] > bracketinglevel): before -= 1 if before < 0: return None bracketinglevel = min(bracketinglevel, self.bracketing[before][1]) after = self.indexbracket + 1 - while after < len(self.bracketing) and \ - self.bracketing[after][1] >= bracketinglevel: + while (after < len(self.bracketing) and + self.bracketing[after][1] >= bracketinglevel): after += 1 beforeindex = self.text.index("%s-%dc" % (self.stopatindex, len(self.rawtext)-self.bracketing[before][0])) - if after >= len(self.bracketing) or \ - self.bracketing[after][0] > len(self.rawtext): + if (after >= len(self.bracketing) or + self.bracketing[after][0] > len(self.rawtext)): if mustclose: return None afterindex = self.stopatindex else: - # We are after a real char, so it is a ')' and we give the index - # before it. - afterindex = self.text.index("%s-%dc" % - (self.stopatindex, + # We are after a real char, so it is a ')' and we give the + # index before it. + afterindex = self.text.index( + "%s-%dc" % (self.stopatindex, len(self.rawtext)-(self.bracketing[after][0]-1))) return beforeindex, afterindex - # This string includes all chars that may be in a white space - _whitespace_chars = " \t\n\\" - # This string includes all chars that may be in an identifier - _id_chars = string.ascii_letters + string.digits + "_" - # This string includes all chars that may be the first char of an identifier - _id_first_chars = string.ascii_letters + "_" - - # Given a string and pos, return the number of chars in the identifier - # which ends at pos, or 0 if there is no such one. Saved words are not - # identifiers. - def _eat_identifier(self, str, limit, pos): + # the set of built-in identifiers which are also keywords, + # i.e. keyword.iskeyword() returns True for them + _ID_KEYWORDS = frozenset({"True", "False", "None"}) + + @classmethod + def _eat_identifier(cls, str, limit, pos): + """Given a string and pos, return the number of chars in the + identifier which ends at pos, or 0 if there is no such one. + + This ignores non-identifier eywords are not identifiers. + """ + is_ascii_id_char = _IS_ASCII_ID_CHAR + + # Start at the end (pos) and work backwards. i = pos - while i > limit and str[i-1] in self._id_chars: + + # Go backwards as long as the characters are valid ASCII + # identifier characters. This is an optimization, since it + # is faster in the common case where most of the characters + # are ASCII. + while i > limit and ( + ord(str[i - 1]) < 128 and + is_ascii_id_char[ord(str[i - 1])] + ): i -= 1 - if i < pos and (str[i] not in self._id_first_chars or \ - keyword.iskeyword(str[i:pos])): - i = pos + + # If the above loop ended due to reaching a non-ASCII + # character, continue going backwards using the most generic + # test for whether a string contains only valid identifier + # characters. + if i > limit and ord(str[i - 1]) >= 128: + while i - 4 >= limit and ('a' + str[i - 4:pos]).isidentifier(): + i -= 4 + if i - 2 >= limit and ('a' + str[i - 2:pos]).isidentifier(): + i -= 2 + if i - 1 >= limit and ('a' + str[i - 1:pos]).isidentifier(): + i -= 1 + + # The identifier candidate starts here. If it isn't a valid + # identifier, don't eat anything. At this point that is only + # possible if the first character isn't a valid first + # character for an identifier. + if not str[i:pos].isidentifier(): + return 0 + elif i < pos: + # All characters in str[i:pos] are valid ASCII identifier + # characters, so it is enough to check that the first is + # valid as the first character of an identifier. + if not _IS_ASCII_ID_FIRST_CHAR[ord(str[i])]: + return 0 + + # All keywords are valid identifiers, but should not be + # considered identifiers here, except for True, False and None. + if i < pos and ( + iskeyword(str[i:pos]) and + str[i:pos] not in cls._ID_KEYWORDS + ): + return 0 + return pos - i + # This string includes all chars that may be in a white space + _whitespace_chars = " \t\n\\" + def get_expression(self): - """Return a string with the Python expression which ends at the given - index, which is empty if there is no real one. + """Return a string with the Python expression which ends at the + given index, which is empty if there is no real one. """ if not self.is_in_code(): - raise ValueError("get_expression should only be called if index "\ - "is inside a code.") + raise ValueError("get_expression should only be called" + "if index is inside a code.") rawtext = self.rawtext bracketing = self.bracketing @@ -177,20 +239,20 @@ def get_expression(self): postdot_phase = True while 1: - # Eat whitespaces, comments, and if postdot_phase is False - one dot + # Eat whitespaces, comments, and if postdot_phase is False - a dot while 1: if pos>brck_limit and rawtext[pos-1] in self._whitespace_chars: # Eat a whitespace pos -= 1 - elif not postdot_phase and \ - pos > brck_limit and rawtext[pos-1] == '.': + elif (not postdot_phase and + pos > brck_limit and rawtext[pos-1] == '.'): # Eat a dot pos -= 1 postdot_phase = True - # The next line will fail if we are *inside* a comment, but we - # shouldn't be. - elif pos == brck_limit and brck_index > 0 and \ - rawtext[bracketing[brck_index-1][0]] == '#': + # The next line will fail if we are *inside* a comment, + # but we shouldn't be. + elif (pos == brck_limit and brck_index > 0 and + rawtext[bracketing[brck_index-1][0]] == '#'): # Eat a comment brck_index -= 2 brck_limit = bracketing[brck_index][0] @@ -200,8 +262,8 @@ def get_expression(self): break if not postdot_phase: - # We didn't find a dot, so the expression end at the last - # identifier pos. + # We didn't find a dot, so the expression end at the + # last identifier pos. break ret = self._eat_identifier(rawtext, brck_limit, pos) @@ -209,13 +271,13 @@ def get_expression(self): # There is an identifier to eat pos = pos - ret last_identifier_pos = pos - # Now, in order to continue the search, we must find a dot. + # Now, to continue the search, we must find a dot. postdot_phase = False # (the loop continues now) elif pos == brck_limit: - # We are at a bracketing limit. If it is a closing bracket, - # eat the bracket, otherwise, stop the search. + # We are at a bracketing limit. If it is a closing + # bracket, eat the bracket, otherwise, stop the search. level = bracketing[brck_index][1] while brck_index > 0 and bracketing[brck_index-1][1] > level: brck_index -= 1 @@ -244,3 +306,8 @@ def get_expression(self): break return rawtext[last_identifier_pos:self.indexinrawtext] + + +if __name__ == '__main__': + import unittest + unittest.main('idlelib.idle_test.test_hyperparser', verbosity=2) diff --git a/Lib/idlelib/IOBinding.py b/Lib/idlelib/IOBinding.py index 7589ab805a7e..1e9398750fed 100644 --- a/Lib/idlelib/IOBinding.py +++ b/Lib/idlelib/IOBinding.py @@ -1,5 +1,4 @@ import os -import types import shlex import sys import codecs @@ -64,6 +63,7 @@ ### 'encoding' is used below in encode(), check! coding_re = re.compile(r'^[ \t\f]*#.*coding[:=][ \t]*([-\w.]+)', re.ASCII) +blank_re = re.compile(r'^[ \t\f]*(?:[#\r\n]|$)', re.ASCII) def coding_spec(data): """Return the encoding declaration according to PEP 263. @@ -93,6 +93,8 @@ def coding_spec(data): match = coding_re.match(line) if match is not None: break + if not blank_re.match(line): + return None else: return None name = match.group(1) @@ -215,7 +217,7 @@ def loadfile(self, filename): f.seek(0) bytes = f.read() except OSError as msg: - tkMessageBox.showerror("I/O Error", str(msg), master=self.text) + tkMessageBox.showerror("I/O Error", str(msg), parent=self.text) return False chars, converted = self._decode(two_lines, bytes) if chars is None: @@ -264,7 +266,7 @@ def _decode(self, two_lines, bytes): title="Error loading the file", message="The encoding '%s' is not known to this Python "\ "installation. The file may not display correctly" % name, - master = self.text) + parent = self.text) enc = None except UnicodeDecodeError: return None, False @@ -319,7 +321,7 @@ def maybesave(self): title="Save On Close", message=message, default=tkMessageBox.YES, - master=self.text) + parent=self.text) if confirm: reply = "yes" self.save(None) @@ -379,7 +381,7 @@ def writefile(self, filename): return True except OSError as msg: tkMessageBox.showerror("I/O Error", str(msg), - master=self.text) + parent=self.text) return False def encode(self, chars): @@ -416,7 +418,7 @@ def encode(self, chars): tkMessageBox.showerror( "I/O Error", "%s.\nSaving as UTF-8" % failed, - master = self.text) + parent = self.text) # Fallback: save as UTF-8, with BOM - ignoring the incorrect # declared encoding return BOM_UTF8 + chars.encode("utf-8") @@ -431,7 +433,7 @@ def print_window(self, event): title="Print", message="Print to Default Printer", default=tkMessageBox.OK, - master=self.text) + parent=self.text) if not confirm: self.text.focus_set() return "break" @@ -468,10 +470,10 @@ def print_window(self, event): status + output if output: output = "Printing command: %s\n" % repr(command) + output - tkMessageBox.showerror("Print status", output, master=self.text) + tkMessageBox.showerror("Print status", output, parent=self.text) else: #no printing for this platform message = "Printing is not enabled for this platform: %s" % platform - tkMessageBox.showinfo("Print status", message, master=self.text) + tkMessageBox.showinfo("Print status", message, parent=self.text) if tempfilename: os.unlink(tempfilename) return "break" @@ -490,7 +492,7 @@ def print_window(self, event): def askopenfile(self): dir, base = self.defaultfilename("open") if not self.opendialog: - self.opendialog = tkFileDialog.Open(master=self.text, + self.opendialog = tkFileDialog.Open(parent=self.text, filetypes=self.filetypes) filename = self.opendialog.show(initialdir=dir, initialfile=base) return filename @@ -511,7 +513,7 @@ def asksavefile(self): dir, base = self.defaultfilename("save") if not self.savedialog: self.savedialog = tkFileDialog.SaveAs( - master=self.text, + parent=self.text, filetypes=self.filetypes, defaultextension=self.defaultextension) filename = self.savedialog.show(initialdir=dir, initialfile=base) @@ -522,16 +524,17 @@ def updaterecentfileslist(self,filename): if self.editwin.flist: self.editwin.update_recent_files_list(filename) -def test(): +def _io_binding(parent): # htest # root = Tk() + root.title("Test IOBinding") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) class MyEditWin: def __init__(self, text): self.text = text self.flist = None self.text.bind("", self.open) self.text.bind("", self.save) - self.text.bind("", self.save_as) - self.text.bind("", self.save_a_copy) def get_saved(self): return 0 def set_saved(self, flag): pass def reset_undo(self): pass @@ -539,16 +542,13 @@ def open(self, event): self.text.event_generate("<>") def save(self, event): self.text.event_generate("<>") - def save_as(self, event): - self.text.event_generate("<>") - def save_a_copy(self, event): - self.text.event_generate("<>") + text = Text(root) text.pack() text.focus_set() editwin = MyEditWin(text) - io = IOBinding(editwin) - root.mainloop() + IOBinding(editwin) if __name__ == "__main__": - test() + from idlelib.idle_test.htest import run + run(_io_binding) diff --git a/Lib/idlelib/Icons/idle.ico b/Lib/idlelib/Icons/idle.ico new file mode 100644 index 000000000000..3357aef14888 Binary files /dev/null and b/Lib/idlelib/Icons/idle.ico differ diff --git a/Lib/idlelib/Icons/idle_16.gif b/Lib/idlelib/Icons/idle_16.gif new file mode 100644 index 000000000000..9f001b1d79cf Binary files /dev/null and b/Lib/idlelib/Icons/idle_16.gif differ diff --git a/Lib/idlelib/Icons/idle_16.png b/Lib/idlelib/Icons/idle_16.png new file mode 100644 index 000000000000..6abde0af90cb Binary files /dev/null and b/Lib/idlelib/Icons/idle_16.png differ diff --git a/Lib/idlelib/Icons/idle_32.gif b/Lib/idlelib/Icons/idle_32.gif new file mode 100644 index 000000000000..af5b2d52cce8 Binary files /dev/null and b/Lib/idlelib/Icons/idle_32.gif differ diff --git a/Lib/idlelib/Icons/idle_32.png b/Lib/idlelib/Icons/idle_32.png new file mode 100644 index 000000000000..41b70dbc3776 Binary files /dev/null and b/Lib/idlelib/Icons/idle_32.png differ diff --git a/Lib/idlelib/Icons/idle_48.gif b/Lib/idlelib/Icons/idle_48.gif new file mode 100644 index 000000000000..fc5304f31eed Binary files /dev/null and b/Lib/idlelib/Icons/idle_48.gif differ diff --git a/Lib/idlelib/Icons/idle_48.png b/Lib/idlelib/Icons/idle_48.png new file mode 100644 index 000000000000..e5fa9280e21f Binary files /dev/null and b/Lib/idlelib/Icons/idle_48.png differ diff --git a/Lib/idlelib/Icons/python.gif b/Lib/idlelib/Icons/python.gif index 58271edec493..b189c2c2d22c 100644 Binary files a/Lib/idlelib/Icons/python.gif and b/Lib/idlelib/Icons/python.gif differ diff --git a/Lib/idlelib/IdleHistory.py b/Lib/idlelib/IdleHistory.py index d6cb16272bc2..078af2905325 100644 --- a/Lib/idlelib/IdleHistory.py +++ b/Lib/idlelib/IdleHistory.py @@ -100,7 +100,5 @@ def store(self, source): self.prefix = None if __name__ == "__main__": - from test import support - support.use_resources = ['gui'] from unittest import main main('idlelib.idle_test.test_idlehistory', verbosity=2, exit=False) diff --git a/Lib/idlelib/MultiCall.py b/Lib/idlelib/MultiCall.py index 64729eab8ca4..251a84d083f6 100644 --- a/Lib/idlelib/MultiCall.py +++ b/Lib/idlelib/MultiCall.py @@ -32,7 +32,6 @@ import sys import re import tkinter -from idlelib import macosxSupport # the event type constants, which define the meaning of mc_type MC_KEYPRESS=0; MC_KEYRELEASE=1; MC_BUTTONPRESS=2; MC_BUTTONRELEASE=3; @@ -45,7 +44,7 @@ MC_OPTION = 1<<6; MC_COMMAND = 1<<7 # define the list of modifiers, to be used in complex event types. -if macosxSupport.runningAsOSXApp(): +if sys.platform == "darwin": _modifiers = (("Shift",), ("Control",), ("Option",), ("Command",)) _modifier_masks = (MC_SHIFT, MC_CONTROL, MC_OPTION, MC_COMMAND) else: @@ -57,6 +56,12 @@ for number in range(len(_modifiers)) for name in _modifiers[number]]) +# In 3.4, if no shell window is ever open, the underlying Tk widget is +# destroyed before .__del__ methods here are called. The following +# is used to selectively ignore shutdown exceptions to avoid +# 'Exception ignored' messages. See http://bugs.python.org/issue20167 +APPLICATION_GONE = "application has been destroyed" + # A binder is a class which binds functions to one type of event. It has two # methods: bind and unbind, which get a function and a parsed sequence, as # returned by _parse_sequence(). There are two types of binders: @@ -98,7 +103,12 @@ def unbind(self, triplet, func): def __del__(self): if self.handlerid: - self.widget.unbind(self.widgetinst, self.sequence, self.handlerid) + try: + self.widget.unbind(self.widgetinst, self.sequence, + self.handlerid) + except tkinter.TclError as e: + if not APPLICATION_GONE in e.args[0]: + raise # An int in range(1 << len(_modifiers)) represents a combination of modifiers # (if the least significent bit is on, _modifiers[0] is on, and so on). @@ -227,7 +237,11 @@ def unbind(self, triplet, func): def __del__(self): for seq, id in self.handlerids: - self.widget.unbind(self.widgetinst, seq, id) + try: + self.widget.unbind(self.widgetinst, seq, id) + except tkinter.TclError as e: + if not APPLICATION_GONE in e.args[0]: + raise # define the list of event types to be handled by MultiEvent. the order is # compatible with the definition of event type constants. @@ -390,15 +404,21 @@ def __del__(self): func, triplets = self.__eventinfo[virtual] if func: for triplet in triplets: - self.__binders[triplet[1]].unbind(triplet, func) - + try: + self.__binders[triplet[1]].unbind(triplet, func) + except tkinter.TclError as e: + if not APPLICATION_GONE in e.args[0]: + raise _multicall_dict[widget] = MultiCall return MultiCall -if __name__ == "__main__": - # Test + +def _multi_call(parent): root = tkinter.Tk() + root.title("Test MultiCall") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) text = MultiCallCreator(tkinter.Text)(root) text.pack() def bindseq(seq, n=[0]): @@ -414,8 +434,13 @@ def handler(event): bindseq("") bindseq("") bindseq("") + bindseq("") bindseq("") bindseq("") bindseq("") bindseq("") root.mainloop() + +if __name__ == "__main__": + from idlelib.idle_test.htest import run + run(_multi_call) diff --git a/Lib/idlelib/MultiStatusBar.py b/Lib/idlelib/MultiStatusBar.py index 4fc8dcf94ba3..f44b6a860221 100644 --- a/Lib/idlelib/MultiStatusBar.py +++ b/Lib/idlelib/MultiStatusBar.py @@ -17,16 +17,29 @@ def set_label(self, name, text='', side=LEFT): label = self.labels[name] label.config(text=text) -def _test(): - b = Frame() - c = Text(b) - c.pack(side=TOP) - a = MultiStatusBar(b) - a.set_label("one", "hello") - a.set_label("two", "world") - a.pack(side=BOTTOM, fill=X) - b.pack() - b.mainloop() +def _multistatus_bar(parent): + root = Tk() + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d" %(x, y + 150)) + root.title("Test multistatus bar") + frame = Frame(root) + text = Text(frame) + text.pack() + msb = MultiStatusBar(frame) + msb.set_label("one", "hello") + msb.set_label("two", "world") + msb.pack(side=BOTTOM, fill=X) + + def change(): + msb.set_label("one", "foo") + msb.set_label("two", "bar") + + button = Button(root, text="Update status", command=change) + button.pack(side=BOTTOM) + frame.pack() + frame.mainloop() + root.mainloop() if __name__ == '__main__': - _test() + from idlelib.idle_test.htest import run + run(_multistatus_bar) diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 478c18337ee5..2df89ecb80db 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -1,5 +1,179 @@ +What's New in IDLE 3.6.0a1? +=========================== +*Release date: 2017?* + +- Issue #24820: IDLE now has an 'IDLE Dark' built-in text color theme. + It is more or less IDLE Classic inverted, with a cobalt blue background. + Strings, comments, keywords, ... are still green, red, orange, ... . + Selecting it displays the following warning and solution. + "IDLE Dark is new in October, 2015. Trying to run earlier versions + of IDLE with it selected will disable colorizing, or worse. + If you might ever run an earlier release of IDLE, then before + exiting this version, either switch to another theme or hit the + 'Save as New Custom Theme' button. The latter requires a new name, + such as 'Custom Dark', but the custom theme will work with any IDLE + release, and can be modified." + +- Issue #25224: README.txt is now an idlelib index for IDLE developers and + curious users. The previous user content is now in the IDLE doc and is + redundant. IDLE now means 'Integrated Development and Learning Environment'. + +- Issue #24820: Users can now set breakpoint colors in + Settings -> Custom Highlighting. Original patch by Mark Roseman. + +- Issue #24972: Inactive selection background now matches active selection + background, as configured by user, on all systems. Found items are now + always highlighted on Windows. Initial patch by Mark Roseman. + +- Issue #24570: Idle: make calltip and completion boxes appear on Macs + affected by a tk regression. Initial patch by Mark Roseman. + +- Issue #24988: Idle ScrolledList context menus (used in debugger) + now work on Mac Aqua. Patch by Mark Roseman. + +- Issue #24801: Make right-click for context menu work on Mac Aqua. + Patch by Mark Roseman. + +- Issue #25173: Associate tkinter messageboxes with a specific widget. + For Mac OSX, make them a 'sheet'. Patch by Mark Roseman. + +- Issue #25198: Enhance the initial html viewer now used for Idle Help. + * Properly indent fixed-pitch text (patch by Mark Roseman). + * Give code snippet a very Sphinx-like light blueish-gray background. + * Re-use initial width and height set by users for shell and editor. + * When the Table of Contents (TOC) menu is used, put the section header + at the top of the screen. + +- Issue #25225: Condense and rewrite Idle doc section on text colors. + +- Issue #21995: Explain some differences between IDLE and console Python. + +- Issue #22820: Explain need for *print* when running file from Idle editor. + +- Issue #25224: Doc: augment Idle feature list and no-subprocess section. + +- Issue #25219: Update doc for Idle command line options. + Some were missing and notes were not correct. + +- Issue #24861: Most of idlelib is private and subject to change. + Use idleib.idle.* to start Idle. See idlelib.__init__.__doc__. + +- Issue #25199: Idle: add synchronization comments for future maintainers. + +- Issue #16893: Replace help.txt with help.html for Idle doc display. + The new idlelib/help.html is rstripped Doc/build/html/library/idle.html. + It looks better than help.txt and will better document Idle as released. + The tkinter html viewer that works for this file was written by Mark Roseman. + The now unused EditorWindow.HelpDialog class and helt.txt file are deprecated. + +- Issue #24199: Deprecate unused idlelib.idlever with possible removal in 3.6. + +- Issue #24782: In Idle extension config dialog, replace tabs with sorted list. + Patch by Mark Roseman. + +- Issue #24790: Remove extraneous code (which also create 2 & 3 conflicts). + + +What's New in IDLE 3.5.0? +========================= +*Release date: 2015-09-13* + +- Issue #23672: Allow Idle to edit and run files with astral chars in name. + Patch by Mohd Sanad Zaki Rizvi. + +- Issue 24745: Idle editor default font. Switch from Courier to + platform-sensitive TkFixedFont. This should not affect current customized + font selections. If there is a problem, edit $HOME/.idlerc/config-main.cfg + and remove 'fontxxx' entries from [Editor Window]. Patch by Mark Roseman. + +- Issue #21192: Idle editor. When a file is run, put its name in the restart bar. + Do not print false prompts. Original patch by Adnan Umer. + +- Issue #13884: Idle menus. Remove tearoff lines. Patch by Roger Serwy. + +- Issue #23184: remove unused names and imports in idlelib. + Initial patch by Al Sweigart. + +- Issue #20577: Configuration of the max line length for the FormatParagraph + extension has been moved from the General tab of the Idle preferences dialog + to the FormatParagraph tab of the Config Extensions dialog. + Patch by Tal Einat. + +- Issue #16893: Update Idle doc chapter to match current Idle and add new + information. + +- Issue #3068: Add Idle extension configuration dialog to Options menu. + Changes are written to HOME/.idlerc/config-extensions.cfg. + Original patch by Tal Einat. + +- Issue #16233: A module browser (File : Class Browser, Alt+C) requires a + editor window with a filename. When Class Browser is requested otherwise, + from a shell, output window, or 'Untitled' editor, Idle no longer displays + an error box. It now pops up an Open Module box (Alt+M). If a valid name + is entered and a module is opened, a corresponding browser is also opened. + +- Issue #4832: Save As to type Python files automatically adds .py to the + name you enter (even if your system does not display it). Some systems + automatically add .txt when type is Text files. + +- Issue #21986: Code objects are not normally pickled by the pickle module. + To match this, they are no longer pickled when running under Idle. + +- Issue #23180: Rename IDLE "Windows" menu item to "Window". + Patch by Al Sweigart. + +- Issue #17390: Adjust Editor window title; remove 'Python', + move version to end. + +- Issue #14105: Idle debugger breakpoints no longer disappear + when inseting or deleting lines. + +- Issue #17172: Turtledemo can now be run from Idle. + Currently, the entry is on the Help menu, but it may move to Run. + Patch by Ramchandra Apt and Lita Cho. + +- Issue #21765: Add support for non-ascii identifiers to HyperParser. + +- Issue #21940: Add unittest for WidgetRedirector. Initial patch by Saimadhav + Heblikar. + +- Issue #18592: Add unittest for SearchDialogBase. Patch by Phil Webster. + +- Issue #21694: Add unittest for ParenMatch. Patch by Saimadhav Heblikar. + +- Issue #21686: add unittest for HyperParser. Original patch by Saimadhav + Heblikar. + +- Issue #12387: Add missing upper(lower)case versions of default Windows key + bindings for Idle so Caps Lock does not disable them. Patch by Roger Serwy. + +- Issue #21695: Closing a Find-in-files output window while the search is + still in progress no longer closes Idle. + +- Issue #18910: Add unittest for textView. Patch by Phil Webster. + +- Issue #18292: Add unittest for AutoExpand. Patch by Saihadhav Heblikar. + +- Issue #18409: Add unittest for AutoComplete. Patch by Phil Webster. + +- Issue #21477: htest.py - Improve framework, complete set of tests. + Patches by Saimadhav Heblikar + +- Issue #18104: Add idlelib/idle_test/htest.py with a few sample tests to begin + consolidating and improving human-validated tests of Idle. Change other files + as needed to work with htest. Running the module as __main__ runs all tests. + +- Issue #21139: Change default paragraph width to 72, the PEP 8 recommendation. + +- Issue #21284: Paragraph reformat test passes after user changes reformat width. + +- Issue #17654: Ensure IDLE menus are customized properly on OS X for + non-framework builds and for all variants of Tk. + + What's New in IDLE 3.4.0? ========================= +*Release date: 2014-03-16* - Issue #17390: Display Python version on Idle title bar. Initial patch by Edmond Burnett. @@ -17,6 +191,7 @@ What's New in IDLE 3.4.0? What's New in IDLE 3.3.0? ========================= +*Release date: 2012-09-29* - Issue #17625: Close the replace dialog after it is used. @@ -59,7 +234,6 @@ What's New in IDLE 3.3.0? What's New in IDLE 3.2.1? ========================= - *Release date: 15-May-11* - Issue #6378: Further adjust idle.bat to start associated Python @@ -77,7 +251,6 @@ What's New in IDLE 3.2.1? What's New in IDLE 3.1b1? ========================= - *Release date: 06-May-09* - Use of 'filter' in keybindingDialog.py was causing custom key assignment to @@ -86,7 +259,6 @@ What's New in IDLE 3.1b1? What's New in IDLE 3.1a1? ========================= - *Release date: 07-Mar-09* - Issue #4815: Offer conversion to UTF-8 if source files have @@ -102,9 +274,9 @@ What's New in IDLE 3.1a1? - Issue #2665: On Windows, an IDLE installation upgraded from an old version would not start if a custom theme was defined. + What's New in IDLE 2.7? (UNRELEASED, but merged into 3.1 releases above.) ======================= - *Release date: XX-XXX-2010* - idle.py modified and simplified to better support developing experimental @@ -128,9 +300,9 @@ What's New in IDLE 2.7? (UNRELEASED, but merged into 3.1 releases above.) - Issue #3549: On MacOS the preferences menu was not present -What's New in IDLE 3.0 final? -============================= +What's New in IDLE 3.0? +======================= *Release date: 03-Dec-2008* - IDLE would print a "Unhandled server exception!" message when internal @@ -142,12 +314,6 @@ What's New in IDLE 3.0 final? - Issue #4383: When IDLE cannot make the connection to its subprocess, it would fail to properly display the error message. - -What's New in IDLE 3.0a3? -========================= - -*Release date: 29-Feb-2008* - - help() was not paging to the shell. Issue1650. - CodeContext was not importing. @@ -159,21 +325,9 @@ What's New in IDLE 3.0a3? - Issue #1585: IDLE uses non-existent xrange() function. - -What's New in IDLE 3.0a2? -========================= - -*Release date: 06-Dec-2007* - - Windows EOL sequence not converted correctly, encoding error. Caused file save to fail. Bug 1130. - -What's New in IDLE 3.0a1? -========================= - -*Release date: 31-Aug-2007* - - IDLE converted to Python 3000 syntax. - Strings became Unicode. @@ -187,9 +341,8 @@ What's New in IDLE 3.0a1? be cleared before IDLE exits. -What's New in IDLE 2.6 final? -============================= - +What's New in IDLE 2.6 +====================== *Release date: 01-Oct-2008*, merged into 3.0 releases detailed above (3.0rc2) - Issue #2665: On Windows, an IDLE installation upgraded from an old version @@ -274,15 +427,8 @@ What's New in IDLE 2.6 final? What's New in IDLE 1.2? ======================= - *Release date: 19-SEP-2006* - -What's New in IDLE 1.2c1? -========================= - -*Release date: 17-AUG-2006* - - File menu hotkeys: there were three 'p' assignments. Reassign the 'Save Copy As' and 'Print' hotkeys to 'y' and 't'. Change the Shell hotkey from 's' to 'l'. @@ -303,11 +449,6 @@ What's New in IDLE 1.2c1? - When used w/o subprocess, all exceptions were preceded by an error message claiming they were IDLE internal errors (since 1.2a1). -What's New in IDLE 1.2b3? -========================= - -*Release date: 03-AUG-2006* - - Bug #1525817: Don't truncate short lines in IDLE's tool tips. - Bug #1517990: IDLE keybindings on MacOS X now work correctly @@ -331,26 +472,6 @@ What's New in IDLE 1.2b3? 'as' keyword in comment directly following import command. Closes 1325071. Patch 1479219 Tal Einat -What's New in IDLE 1.2b2? -========================= - -*Release date: 11-JUL-2006* - -What's New in IDLE 1.2b1? -========================= - -*Release date: 20-JUN-2006* - -What's New in IDLE 1.2a2? -========================= - -*Release date: 27-APR-2006* - -What's New in IDLE 1.2a1? -========================= - -*Release date: 05-APR-2006* - - Patch #1162825: Support non-ASCII characters in IDLE window titles. - Source file f.flush() after writing; trying to avoid lossage if user @@ -430,19 +551,14 @@ What's New in IDLE 1.2a1? - The remote procedure call module rpc.py can now access data attributes of remote registered objects. Changes to these attributes are local, however. + What's New in IDLE 1.1? ======================= - *Release date: 30-NOV-2004* - On OpenBSD, terminating IDLE with ctrl-c from the command line caused a stuck subprocess MainThread because only the SocketThread was exiting. -What's New in IDLE 1.1b3/rc1? -============================= - -*Release date: 18-NOV-2004* - - Saving a Keyset w/o making changes (by using the "Save as New Custom Key Set" button) caused IDLE to fail on restart (no new keyset was created in config-keys.cfg). Also true for Theme/highlights. Python Bug 1064535. @@ -450,28 +566,12 @@ What's New in IDLE 1.1b3/rc1? - A change to the linecache.py API caused IDLE to exit when an exception was raised while running without the subprocess (-n switch). Python Bug 1063840. -What's New in IDLE 1.1b2? -========================= - -*Release date: 03-NOV-2004* - - When paragraph reformat width was made configurable, a bug was introduced that caused reformatting of comment blocks to ignore how far the block was indented, effectively adding the indentation width to the reformat width. This has been repaired, and the reformat width is again a bound on the total width of reformatted lines. -What's New in IDLE 1.1b1? -========================= - -*Release date: 15-OCT-2004* - - -What's New in IDLE 1.1a3? -========================= - -*Release date: 02-SEP-2004* - - Improve keyboard focus binding, especially in Windows menu. Improve window raising, especially in the Windows menu and in the debugger. IDLEfork 763524. @@ -479,24 +579,12 @@ What's New in IDLE 1.1a3? - If user passes a non-existent filename on the commandline, just open a new file, don't raise a dialog. IDLEfork 854928. - -What's New in IDLE 1.1a2? -========================= - -*Release date: 05-AUG-2004* - - EditorWindow.py was not finding the .chm help file on Windows. Typo at Rev 1.54. Python Bug 990954 - checking sys.platform for substring 'win' was breaking IDLE docs on Mac (darwin). Also, Mac Safari browser requires full file:// URIs. SF 900580. - -What's New in IDLE 1.1a1? -========================= - -*Release date: 08-JUL-2004* - - Redirect the warning stream to the shell during the ScriptBinding check of user code and format the warning similarly to an exception for both that check and for runtime warnings raised in the subprocess. @@ -559,26 +647,13 @@ What's New in IDLE 1.1a1? What's New in IDLE 1.0? ======================= - *Release date: 29-Jul-2003* - Added a banner to the shell discussing warnings possibly raised by personal firewall software. Added same comment to README.txt. - -What's New in IDLE 1.0 release candidate 2? -=========================================== - -*Release date: 24-Jul-2003* - - Calltip error when docstring was None Python Bug 775541 - -What's New in IDLE 1.0 release candidate 1? -=========================================== - -*Release date: 18-Jul-2003* - - Updated extend.txt, help.txt, and config-extensions.def to correctly reflect the current status of the configuration system. Python Bug 768469 @@ -594,12 +669,6 @@ What's New in IDLE 1.0 release candidate 1? sys.std{in|out|err}.encoding, for both the local and the subprocess case. SF IDLEfork patch 682347. - -What's New in IDLE 1.0b2? -========================= - -*Release date: 29-Jun-2003* - - Extend AboutDialog.ViewFile() to support file encodings. Make the CREDITS file Latin-1. @@ -638,7 +707,6 @@ What's New in IDLE 1.0b2? What's New in IDLEfork 0.9b1? ============================= - *Release date: 02-Jun-2003* - The current working directory of the execution environment (and shell @@ -740,10 +808,8 @@ What's New in IDLEfork 0.9b1? exception formatting to the subprocess. - What's New in IDLEfork 0.9 Alpha 2? =================================== - *Release date: 27-Jan-2003* - Updated INSTALL.txt to claify use of the python2 rpm. @@ -847,7 +913,6 @@ What's New in IDLEfork 0.9 Alpha 2? What's New in IDLEfork 0.9 Alpha 1? =================================== - *Release date: 31-Dec-2002* - First release of major new functionality. For further details refer to @@ -875,4 +940,3 @@ What's New in IDLEfork 0.9 Alpha 1? -------------------------------------------------------------------- Refer to HISTORY.txt for additional information on earlier releases. -------------------------------------------------------------------- - diff --git a/Lib/idlelib/ObjectBrowser.py b/Lib/idlelib/ObjectBrowser.py index b359efc1b4ee..7b57aa4c684b 100644 --- a/Lib/idlelib/ObjectBrowser.py +++ b/Lib/idlelib/ObjectBrowser.py @@ -9,6 +9,8 @@ # XXX TO DO: # - for classes/modules, add "open source" to object browser +import re + from idlelib.TreeWidget import TreeItem, TreeNode, ScrolledCanvas from reprlib import Repr @@ -119,12 +121,14 @@ def make_objecttreeitem(labeltext, object, setfunction=None): c = ObjectTreeItem return c(labeltext, object, setfunction) -# Test script -def _test(): +def _object_browser(parent): import sys from tkinter import Tk root = Tk() + root.title("Test ObjectBrowser") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) root.configure(bd=0, bg="yellow") root.focus_set() sc = ScrolledCanvas(root, bg="white", highlightthickness=0, takefocus=1) @@ -135,4 +139,5 @@ def _test(): root.mainloop() if __name__ == '__main__': - _test() + from idlelib.idle_test.htest import run + run(_object_browser) diff --git a/Lib/idlelib/OutputWindow.py b/Lib/idlelib/OutputWindow.py index 9dacc492b599..e614f9b2bb7b 100644 --- a/Lib/idlelib/OutputWindow.py +++ b/Lib/idlelib/OutputWindow.py @@ -91,7 +91,7 @@ def goto_file_line(self, event=None): "No special line", "The line you point at doesn't look like " "a valid file name followed by a line number.", - master=self.text) + parent=self.text) return filename, lineno = result edit = self.flist.open(filename) diff --git a/Lib/idlelib/ParenMatch.py b/Lib/idlelib/ParenMatch.py index 6d91b390d16a..19bad8ce3856 100644 --- a/Lib/idlelib/ParenMatch.py +++ b/Lib/idlelib/ParenMatch.py @@ -90,7 +90,8 @@ def set_style(self, style): self.set_timeout = self.set_timeout_none def flash_paren_event(self, event): - indices = HyperParser(self.editwin, "insert").get_surrounding_brackets() + indices = (HyperParser(self.editwin, "insert") + .get_surrounding_brackets()) if indices is None: self.warn_mismatched() return @@ -167,6 +168,11 @@ def set_timeout_last(self): # associate a counter with an event; only disable the "paren" # tag if the event is for the most recent timer. self.counter += 1 - self.editwin.text_frame.after(self.FLASH_DELAY, - lambda self=self, c=self.counter: \ - self.handle_restore_timer(c)) + self.editwin.text_frame.after( + self.FLASH_DELAY, + lambda self=self, c=self.counter: self.handle_restore_timer(c)) + + +if __name__ == '__main__': + import unittest + unittest.main('idlelib.idle_test.test_parenmatch', verbosity=2) diff --git a/Lib/idlelib/PathBrowser.py b/Lib/idlelib/PathBrowser.py index 5e5c6be98d29..9ab7632f4db4 100644 --- a/Lib/idlelib/PathBrowser.py +++ b/Lib/idlelib/PathBrowser.py @@ -4,13 +4,20 @@ from idlelib.TreeWidget import TreeItem from idlelib.ClassBrowser import ClassBrowser, ModuleBrowserTreeItem +from idlelib.PyShell import PyShellFileList + class PathBrowser(ClassBrowser): - def __init__(self, flist): + def __init__(self, flist, _htest=False): + """ + _htest - bool, change box location when running htest + """ + self._htest = _htest self.init(flist) def settitle(self): + "Set window titles." self.top.wm_title("Path Browser") self.top.wm_iconname("Path Browser") @@ -63,16 +70,17 @@ def GetSubList(self): return sublist def ispackagedir(self, file): + " Return true for directories that are packages." if not os.path.isdir(file): - return 0 + return False init = os.path.join(file, "__init__.py") return os.path.exists(init) def listmodules(self, allnames): modules = {} suffixes = importlib.machinery.EXTENSION_SUFFIXES[:] - suffixes += importlib.machinery.SOURCE_SUFFIXES[:] - suffixes += importlib.machinery.BYTECODE_SUFFIXES[:] + suffixes += importlib.machinery.SOURCE_SUFFIXES + suffixes += importlib.machinery.BYTECODE_SUFFIXES sorted = [] for suff in suffixes: i = -len(suff) @@ -87,12 +95,14 @@ def listmodules(self, allnames): sorted.sort() return sorted -def main(): - from idlelib import PyShell - PathBrowser(PyShell.flist) - if sys.stdin is sys.__stdin__: - mainloop() +def _path_browser(parent): # htest # + flist = PyShellFileList(parent) + PathBrowser(flist, _htest=True) + parent.mainloop() if __name__ == "__main__": from unittest import main main('idlelib.idle_test.test_pathbrowser', verbosity=2, exit=False) + + from idlelib.idle_test.htest import run + run(_path_browser) diff --git a/Lib/idlelib/Percolator.py b/Lib/idlelib/Percolator.py index c91de3812962..9e9331940f72 100644 --- a/Lib/idlelib/Percolator.py +++ b/Lib/idlelib/Percolator.py @@ -51,8 +51,9 @@ def removefilter(self, filter): f.setdelegate(filter.delegate) filter.setdelegate(None) -def main(): - import tkinter as Tk +def _percolator(parent): + import tkinter as tk + import re class Tracer(Delegator): def __init__(self, name): self.name = name @@ -63,22 +64,41 @@ def insert(self, *args): def delete(self, *args): print(self.name, ": delete", args) self.delegate.delete(*args) - root = Tk.Tk() - root.wm_protocol("WM_DELETE_WINDOW", root.quit) - text = Tk.Text() - text.pack() - text.focus_set() + root = tk.Tk() + root.title("Test Percolator") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + text = tk.Text(root) p = Percolator(text) t1 = Tracer("t1") t2 = Tracer("t2") - p.insertfilter(t1) - p.insertfilter(t2) - root.mainloop() # click close widget to continue... - p.removefilter(t2) - root.mainloop() - p.insertfilter(t2) - p.removefilter(t1) + + def toggle1(): + if var1.get() == 0: + var1.set(1) + p.insertfilter(t1) + elif var1.get() == 1: + var1.set(0) + p.removefilter(t1) + + def toggle2(): + if var2.get() == 0: + var2.set(1) + p.insertfilter(t2) + elif var2.get() == 1: + var2.set(0) + p.removefilter(t2) + + text.pack() + var1 = tk.IntVar() + cb1 = tk.Checkbutton(root, text="Tracer1", command=toggle1, variable=var1) + cb1.pack() + var2 = tk.IntVar() + cb2 = tk.Checkbutton(root, text="Tracer2", command=toggle2, variable=var2) + cb2.pack() + root.mainloop() if __name__ == "__main__": - main() + from idlelib.idle_test.htest import run + run(_percolator) diff --git a/Lib/idlelib/PyParse.py b/Lib/idlelib/PyParse.py index 61a0003ce5ae..9ccbb250761e 100644 --- a/Lib/idlelib/PyParse.py +++ b/Lib/idlelib/PyParse.py @@ -1,5 +1,6 @@ import re import sys +from collections import Mapping # Reason last stmt is continued (or C_NONE if it's not). (C_NONE, C_BACKSLASH, C_STRING_FIRST_LINE, @@ -91,19 +92,48 @@ def dump(*stuff): [^[\](){}#'"\\]+ """, re.VERBOSE).match -# Build translation table to map uninteresting chars to "x", open -# brackets to "(", and close brackets to ")". -_tran = {} -for i in range(256): - _tran[i] = 'x' -for ch in "({[": - _tran[ord(ch)] = '(' -for ch in ")}]": - _tran[ord(ch)] = ')' -for ch in "\"'\\\n#": - _tran[ord(ch)] = ch -del i, ch +class StringTranslatePseudoMapping(Mapping): + r"""Utility class to be used with str.translate() + + This Mapping class wraps a given dict. When a value for a key is + requested via __getitem__() or get(), the key is looked up in the + given dict. If found there, the value from the dict is returned. + Otherwise, the default value given upon initialization is returned. + + This allows using str.translate() to make some replacements, and to + replace all characters for which no replacement was specified with + a given character instead of leaving them as-is. + + For example, to replace everything except whitespace with 'x': + + >>> whitespace_chars = ' \t\n\r' + >>> preserve_dict = {ord(c): ord(c) for c in whitespace_chars} + >>> mapping = StringTranslatePseudoMapping(preserve_dict, ord('x')) + >>> text = "a + b\tc\nd" + >>> text.translate(mapping) + 'x x x\tx\nx' + """ + def __init__(self, non_defaults, default_value): + self._non_defaults = non_defaults + self._default_value = default_value + + def _get(key, _get=non_defaults.get, _default=default_value): + return _get(key, _default) + self._get = _get + + def __getitem__(self, item): + return self._get(item) + + def __len__(self): + return len(self._non_defaults) + + def __iter__(self): + return iter(self._non_defaults) + + def get(self, key, default=None): + return self._get(key) + class Parser: @@ -113,19 +143,6 @@ def __init__(self, indentwidth, tabwidth): def set_str(self, s): assert len(s) == 0 or s[-1] == '\n' - if isinstance(s, str): - # The parse functions have no idea what to do with Unicode, so - # replace all Unicode characters with "x". This is "safe" - # so long as the only characters germane to parsing the structure - # of Python are 7-bit ASCII. It's *necessary* because Unicode - # strings don't have a .translate() method that supports - # deletechars. - uniphooey = s - s = [] - push = s.append - for raw in map(ord, uniphooey): - push(raw < 127 and chr(raw) or "x") - s = "".join(s) self.str = s self.study_level = 0 @@ -197,6 +214,16 @@ def set_lo(self, lo): if lo > 0: self.str = self.str[lo:] + # Build a translation table to map uninteresting chars to 'x', open + # brackets to '(', close brackets to ')' while preserving quotes, + # backslashes, newlines and hashes. This is to be passed to + # str.translate() in _study1(). + _tran = {} + _tran.update((ord(c), ord('(')) for c in "({[") + _tran.update((ord(c), ord(')')) for c in ")}]") + _tran.update((ord(c), ord(c)) for c in "\"'\\\n#") + _tran = StringTranslatePseudoMapping(_tran, default_value=ord('x')) + # As quickly as humanly possible , find the line numbers (0- # based) of the non-continuation lines. # Creates self.{goodlines, continuation}. @@ -211,7 +238,7 @@ def _study1(self): # uninteresting characters. This can cut the number of chars # by a factor of 10-40, and so greatly speed the following loop. str = self.str - str = str.translate(_tran) + str = str.translate(self._tran) str = str.replace('xxxxxxxx', 'x') str = str.replace('xxxx', 'x') str = str.replace('xx', 'x') diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py old mode 100644 new mode 100755 index 36aff92d2c47..57aa6dae2edb --- a/Lib/idlelib/PyShell.py +++ b/Lib/idlelib/PyShell.py @@ -10,18 +10,16 @@ import threading import time import tokenize -import traceback -import types import io import linecache from code import InteractiveInterpreter -from platform import python_version +from platform import python_version, system try: from tkinter import * except ImportError: - print("** IDLE can't import Tkinter. " \ + print("** IDLE can't import Tkinter.\n" "Your Python may not be configured for Tk. **", file=sys.__stderr__) sys.exit(1) import tkinter.messagebox as tkMessageBox @@ -32,7 +30,6 @@ from idlelib.UndoDelegator import UndoDelegator from idlelib.OutputWindow import OutputWindow from idlelib.configHandler import idleConf -from idlelib import idlever from idlelib import rpc from idlelib import Debugger from idlelib import RemoteDebugger @@ -138,6 +135,7 @@ def filename_changed_hook(old_hook=self.io.filename_change_hook, self.io.set_filename_change_hook(filename_changed_hook) if self.io.filename: self.restore_file_breaks() + self.color_breakpoint_text() rmenu_specs = [ ("Cut", "<>", "rmenu_check_cut"), @@ -148,12 +146,24 @@ def filename_changed_hook(old_hook=self.io.filename_change_hook, ("Clear Breakpoint", "<>", None) ] + def color_breakpoint_text(self, color=True): + "Turn colorizing of breakpoint text on or off" + if self.io is None: + # possible due to update in restore_file_breaks + return + if color: + theme = idleConf.GetOption('main','Theme','name') + cfg = idleConf.GetHighlight(theme, "break") + else: + cfg = {'foreground': '', 'background': ''} + self.text.tag_config('BREAK', cfg) + def set_breakpoint(self, lineno): text = self.text filename = self.io.filename text.tag_add("BREAK", "%d.0" % lineno, "%d.0" % (lineno+1)) try: - i = self.breakpoints.index(lineno) + self.breakpoints.index(lineno) except ValueError: # only add if missing, i.e. do once self.breakpoints.append(lineno) try: # update the subprocess debugger @@ -217,13 +227,8 @@ def store_file_breaks(self): # This is necessary to keep the saved breaks synched with the # saved file. # - # Breakpoints are set as tagged ranges in the text. Certain - # kinds of edits cause these ranges to be deleted: Inserting - # or deleting a line just before a breakpoint, and certain - # deletions prior to a breakpoint. These issues need to be - # investigated and understood. It's not clear if they are - # Tk issues or IDLE issues, or whether they can actually - # be fixed. Since a modified file has to be saved before it is + # Breakpoints are set as tagged ranges in the text. + # Since a modified file has to be saved before it is # run, and since self.breakpoints (from which the subprocess # debugger is loaded) is updated during the save, the visible # breaks stay synched with the subprocess even if one of these @@ -419,7 +424,7 @@ def start_subprocess(self): try: self.rpcclt = MyRPCClient(addr) break - except OSError as err: + except OSError: pass else: self.display_port_binding_error() @@ -440,7 +445,7 @@ def start_subprocess(self): self.rpcclt.listening_sock.settimeout(10) try: self.rpcclt.accept() - except socket.timeout as err: + except socket.timeout: self.display_no_subprocess_error() return None self.rpcclt.register("console", self.tkconsole) @@ -454,7 +459,7 @@ def start_subprocess(self): self.poll_subprocess() return self.rpcclt - def restart_subprocess(self, with_cwd=False): + def restart_subprocess(self, with_cwd=False, filename=''): if self.restarting: return self.rpcclt self.restarting = True @@ -475,25 +480,24 @@ def restart_subprocess(self, with_cwd=False): self.spawn_subprocess() try: self.rpcclt.accept() - except socket.timeout as err: + except socket.timeout: self.display_no_subprocess_error() return None self.transfer_path(with_cwd=with_cwd) console.stop_readline() # annotate restart in shell window and mark it console.text.delete("iomark", "end-1c") - if was_executing: - console.write('\n') - console.showprompt() - halfbar = ((int(console.width) - 16) // 2) * '=' - console.write(halfbar + ' RESTART ' + halfbar) + tag = 'RESTART: ' + (filename if filename else 'Shell') + halfbar = ((int(console.width) -len(tag) - 4) // 2) * '=' + console.write("\n{0} {1} {0}".format(halfbar, tag)) console.text.mark_set("restart", "end-1c") console.text.mark_gravity("restart", "left") - console.showprompt() + if not filename: + console.showprompt() # restart subprocess debugger if debug: # Restarted debugger connects to current instance of debug GUI - gui = RemoteDebugger.restart_subprocess_debugger(self.rpcclt) + RemoteDebugger.restart_subprocess_debugger(self.rpcclt) # reload remote debugger breakpoints for all PyShellEditWindows debug.load_breakpoints() self.compile.compiler.flags = self.original_compiler_flags @@ -641,9 +645,9 @@ def execfile(self, filename, source=None): code = compile(source, filename, "exec") except (OverflowError, SyntaxError): self.tkconsole.resetoutput() - tkerr = self.tkconsole.stderr - print('*** Error in script or command!\n', file=tkerr) - print('Traceback (most recent call last):', file=tkerr) + print('*** Error in script or command!\n' + 'Traceback (most recent call last):', + file=self.tkconsole.stderr) InteractiveInterpreter.showsyntaxerror(self, filename) self.tkconsole.showprompt() else: @@ -770,7 +774,7 @@ def runcode(self, code): "Exit?", "Do you want to exit altogether?", default="yes", - master=self.tkconsole.text): + parent=self.tkconsole.text): raise else: self.showtraceback() @@ -808,7 +812,7 @@ def display_port_binding_error(self): "Run IDLE with the -n command line switch to start without a " "subprocess and refer to Help/IDLE Help 'Running without a " "subprocess' for further details.", - master=self.tkconsole.text) + parent=self.tkconsole.text) def display_no_subprocess_error(self): tkMessageBox.showerror( @@ -816,14 +820,14 @@ def display_no_subprocess_error(self): "IDLE's subprocess didn't make connection. Either IDLE can't " "start a subprocess or personal firewall software is blocking " "the connection.", - master=self.tkconsole.text) + parent=self.tkconsole.text) def display_executing_dialog(self): tkMessageBox.showerror( "Already executing", "The Python Shell window is already executing a command; " "please wait until it is finished.", - master=self.tkconsole.text) + parent=self.tkconsole.text) class PyShell(OutputWindow): @@ -840,13 +844,10 @@ class PyShell(OutputWindow): ("edit", "_Edit"), ("debug", "_Debug"), ("options", "_Options"), - ("windows", "_Windows"), + ("windows", "_Window"), ("help", "_Help"), ] - if macosxSupport.runningAsOSXApp(): - menu_specs[-2] = ("windows", "_Window") - # New classes from idlelib.IdleHistory import History @@ -930,7 +931,7 @@ def toggle_debugger(self, event=None): if self.executing: tkMessageBox.showerror("Don't debug now", "You can only toggle the debugger when idle", - master=self.text) + parent=self.text) self.set_debugger_indicator() return "break" else: @@ -1042,6 +1043,7 @@ def begin(self): self.write("Python %s on %s\n%s\n%s" % (sys.version, sys.platform, self.COPYRIGHT, nosub)) + self.text.focus_force() self.showprompt() import tkinter tkinter._default_root = None # 03Jan04 KBK What's this? @@ -1226,7 +1228,7 @@ def runit(self): while i > 0 and line[i-1] in " \t": i = i-1 line = line[:i] - more = self.interp.runsource(line) + self.interp.runsource(line) def open_stack_viewer(self, event=None): if self.interp.rpcclt: @@ -1237,10 +1239,10 @@ def open_stack_viewer(self, event=None): tkMessageBox.showerror("No stack trace", "There is no stack trace yet.\n" "(sys.last_traceback is not defined)", - master=self.text) + parent=self.text) return from idlelib.StackViewer import StackBrowser - sv = StackBrowser(self.root, self.flist) + StackBrowser(self.root, self.flist) def view_restart_mark(self, event=None): self.text.see("iomark") @@ -1334,8 +1336,11 @@ def writable(self): def write(self, s): if self.closed: raise ValueError("write to closed file") - if not isinstance(s, str): - raise TypeError('must be str, not ' + type(s).__name__) + if type(s) is not str: + if not isinstance(s, str): + raise TypeError('must be str, not ' + type(s).__name__) + # See issue #19481 + s = str.__str__(s) return self.shell.write(s, self.tags) @@ -1381,6 +1386,9 @@ def readline(self, size=-1): line = self._line_buffer or self.shell.readline() if size < 0: size = len(line) + eol = line.find('\n', 0, size) + if eol >= 0: + size = eol + 1 self._line_buffer = line[size:] return line[:size] @@ -1456,8 +1464,7 @@ def main(): try: opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:") except getopt.error as msg: - sys.stderr.write("Error: %s\n" % str(msg)) - sys.stderr.write(usage_msg) + print("Error: %s\n%s" % (msg, usage_msg), file=sys.stderr) sys.exit(2) for o, a in opts: if o == '-c': @@ -1524,11 +1531,31 @@ def main(): # start editor and/or shell windows: root = Tk(className="Idle") + # set application icon + icondir = os.path.join(os.path.dirname(__file__), 'Icons') + if system() == 'Windows': + iconfile = os.path.join(icondir, 'idle.ico') + root.wm_iconbitmap(default=iconfile) + elif TkVersion >= 8.5: + ext = '.png' if TkVersion >= 8.6 else '.gif' + iconfiles = [os.path.join(icondir, 'idle_%d%s' % (size, ext)) + for size in (16, 32, 48)] + icons = [PhotoImage(file=iconfile) for iconfile in iconfiles] + root.wm_iconphoto(True, *icons) + fixwordbreaks(root) root.withdraw() flist = PyShellFileList(root) macosxSupport.setupApp(root, flist) + if macosxSupport.isAquaTk(): + # There are some screwed up <2> class bindings for text + # widgets defined in Tk which we need to do away with. + # See issue #24801. + root.unbind_class('Text', '') + root.unbind_class('Text', '') + root.unbind_class('Text', '<>') + if enable_edit: if not (cmd or script): for filename in args[:]: @@ -1537,20 +1564,22 @@ def main(): args.remove(filename) if not args: flist.new() + if enable_shell: shell = flist.open_shell() if not shell: return # couldn't open shell - - if macosxSupport.runningAsOSXApp() and flist.dict: + if macosxSupport.isAquaTk() and flist.dict: # On OSX: when the user has double-clicked on a file that causes # IDLE to be launched the shell window will open just in front of # the file she wants to see. Lower the interpreter window when # there are open files. shell.top.lower() + else: + shell = flist.pyshell - shell = flist.pyshell - # handle remaining options: + # Handle remaining options. If any of these are set, enable_shell + # was set also, so shell must be true to reach here. if debug: shell.open_debugger() if startup: @@ -1558,7 +1587,7 @@ def main(): os.environ.get("PYTHONSTARTUP") if filename and os.path.isfile(filename): shell.interp.execfile(filename) - if shell and cmd or script: + if cmd or script: shell.interp.runcommand("""if 1: import sys as _sys _sys.argv = %r @@ -1569,13 +1598,14 @@ def main(): elif script: shell.interp.prepend_syspath(script) shell.interp.execfile(script) - - # Check for problematic OS X Tk versions and print a warning message - # in the IDLE shell window; this is less intrusive than always opening - # a separate window. - tkversionwarning = macosxSupport.tkVersionWarning(root) - if tkversionwarning: - shell.interp.runcommand(''.join(("print('", tkversionwarning, "')"))) + elif shell: + # If there is a shell window and no cmd or script in progress, + # check for problematic OS X Tk versions and print a warning + # message in the IDLE shell window; this is less intrusive + # than always opening a separate window. + tkversionwarning = macosxSupport.tkVersionWarning(root) + if tkversionwarning: + shell.interp.runcommand("print('%s')" % tkversionwarning) while flist.inversedict: # keep IDLE running while files are open. root.mainloop() diff --git a/Lib/idlelib/README.txt b/Lib/idlelib/README.txt index b2bb73b06515..b5663c25cfeb 100644 --- a/Lib/idlelib/README.txt +++ b/Lib/idlelib/README.txt @@ -1,60 +1,229 @@ -IDLE is Python's Tkinter-based Integrated DeveLopment Environment. - -IDLE emphasizes a lightweight, clean design with a simple user interface. -Although it is suitable for beginners, even advanced users will find that -IDLE has everything they really need to develop pure Python code. - -IDLE features a multi-window text editor with multiple undo, Python colorizing, -and many other capabilities, e.g. smart indent, call tips, and autocompletion. - -The editor has comprehensive search functions, including searching through -multiple files. Class browsers and path browsers provide fast access to -code objects from a top level viewpoint without dealing with code folding. - -There is a Python Shell window which features colorizing and command recall. - -IDLE executes Python code in a separate process, which is restarted for each -Run (F5) initiated from an editor window. The environment can also be -restarted from the Shell window without restarting IDLE. - -This enhancement has often been requested, and is now finally available. The -magic "reload/import *" incantations are no longer required when editing and -testing a module two or three steps down the import chain. - -(Personal firewall software may warn about the connection IDLE makes to its -subprocess using this computer's internal loopback interface. This connection -is not visible on any external interface and no data is sent to or received -from the Internet.) - -It is possible to interrupt tightly looping user code, even on Windows. - -Applications which cannot support subprocesses and/or sockets can still run -IDLE in a single process. - -IDLE has an integrated debugger with stepping, persistent breakpoints, and call -stack visibility. - -There is a GUI configuration manager which makes it easy to select fonts, -colors, keybindings, and startup options. This facility includes a feature -which allows the user to specify additional help sources, either locally or on -the web. - -IDLE is coded in 100% pure Python, using the Tkinter GUI toolkit (Tk/Tcl) -and is cross-platform, working on Unix, Mac, and Windows. - -IDLE accepts command line arguments. Try idle -h to see the options. - - -If you find bugs or have suggestions or patches, let us know about -them by using the Python issue tracker: - -http://bugs.python.org - -For further details and links, read the Help files and check the IDLE home -page at - -http://www.python.org/idle/ - -There is a mail list for IDLE: idle-dev@python.org. You can join at - -http://mail.python.org/mailman/listinfo/idle-dev +README.txt: an index to idlelib files and the IDLE menu. + +IDLE is Python�s Integrated Development and Learning +Environment. The user documentation is part of the Library Reference and +is available in IDLE by selecting Help => IDLE Help. This README documents +idlelib for IDLE developers and curious users. + +IDLELIB FILES lists files alphabetically by category, +with a short description of each. + +IDLE MENU show the menu tree, annotated with the module +or module object that implements the corresponding function. + +This file is descriptive, not prescriptive, and may have errors +and omissions and lag behind changes in idlelib. + + +IDLELIB FILES +Implemetation files not in IDLE MENU are marked (nim). +Deprecated files and objects are listed separately as the end. + +Startup +------- +__init__.py # import, does nothing +__main__.py # -m, starts IDLE +idle.bat +idle.py +idle.pyw + +Implementation +-------------- +AutoComplete.py # Complete attribute names or filenames. +AutoCompleteWindow.py # Display completions. +AutoExpand.py # Expand word with previous word in file. +Bindings.py # Define most of IDLE menu. +CallTipWindow.py # Display calltip. +CallTips.py # Create calltip text. +ClassBrowser.py # Create module browser window. +CodeContext.py # Show compound statement headers otherwise not visible. +ColorDelegator.py # Colorize text (nim). +Debugger.py # Debug code run from editor; show window. +Delegator.py # Define base class for delegators (nim). +EditorWindow.py # Define most of editor and utility functions. +FileList.py # Open files and manage list of open windows (nim). +FormatParagraph.py# Re-wrap multiline strings and comments. +GrepDialog.py # Find all occurrences of pattern in multiple files. +HyperParser.py # Parse code around a given index. +IOBinding.py # Open, read, and write files +IdleHistory.py # Get previous or next user input in shell (nim) +MultiCall.py # Wrap tk widget to allow multiple calls per event (nim). +MultiStatusBar.py # Define status bar for windows (nim). +ObjectBrowser.py # Define class used in StackViewer (nim). +OutputWindow.py # Create window for grep output. +ParenMatch.py # Match fenceposts: (), [], and {}. +PathBrowser.py # Create path browser window. +Percolator.py # Manage delegator stack (nim). +PyParse.py # Give information on code indentation +PyShell.py # Start IDLE, manage shell, complete editor window +RemoteDebugger.py # Debug code run in remote process. +RemoteObjectBrowser.py # Communicate objects between processes with rpc (nim). +ReplaceDialog.py # Search and replace pattern in text. +RstripExtension.py# Strip trailing whitespace +ScriptBinding.py # Check and run user code. +ScrolledList.py # Define ScrolledList widget for IDLE (nim). +SearchDialog.py # Search for pattern in text. +SearchDialogBase.py # Define base for search, replace, and grep dialogs. +SearchEngine.py # Define engine for all 3 search dialogs. +StackViewer.py # View stack after exception. +TreeWidget.py # Define tree widger, used in browsers (nim). +UndoDelegator.py # Manage undo stack. +WidgetRedirector.py # Intercept widget subcommands (for percolator) (nim). +WindowList.py # Manage window list and define listed top level. +ZoomHeight.py # Zoom window to full height of screen. +aboutDialog.py # Display About IDLE dialog. +configDialog.py # Display user configuration dialogs. +configHandler.py # Load, fetch, and save configuration (nim). +configHelpSourceEdit.py # Specify help source. +configSectionNameDialog.py # Spefify user config section name +dynOptionMenuWidget.py # define mutable OptionMenu widget (nim). +help.py # Display IDLE's html doc. +keybindingDialog.py # Change keybindings. +macosxSupport.py # Help IDLE run on Macs (nim). +rpc.py # Commuicate between idle and user processes (nim). +run.py # Manage user code execution subprocess. +tabbedpages.py # Define tabbed pages widget (nim). +textView.py # Define read-only text widget (nim). + +Configuration +------------- +config-extensions.def # Defaults for extensions +config-highlight.def # Defaults for colorizing +config-keys.def # Defaults for key bindings +config-main.def # Defai;ts fpr font and geneal + +Text +---- +CREDITS.txt # not maintained, displayed by About IDLE +HISTORY.txt # NEWS up to July 2001 +NEWS.txt # commits, displayed by About IDLE +README.txt # this file, displeyed by About IDLE +TODO.txt # needs review +extend.txt # about writing extensions +help.html # copy of idle.html in docs, displayed by IDLE Help + +Subdirectories +-------------- +Icons # small image files +idle_test # files for human test and automated unit tests + +Unused and Deprecated files and objects (nim) +--------------------------------------------- +EditorWindow.py: Helpdialog and helpDialog +ToolTip.py: unused. +help.txt +idlever.py + + +IDLE MENUS +Top level items and most submenu items are defined in Bindings. +Extenstions add submenu items when active. The names given are +found, quoted, in one of these modules, paired with a '<>'. +Each pseudoevent is bound to an event handler. Some event handlers +call another function that does the actual work. The annotations below +are intended to at least give the module where the actual work is done. + +File # IOBindig except as noted + New File + Open... # IOBinding.open + Open Module + Recent Files + Class Browser # Class Browser + Path Browser # Path Browser + --- + Save # IDBinding.save + Save As... # IOBinding.save_as + Save Copy As... # IOBindling.save_a_copy + --- + Print Window # IOBinding.print_window + --- + Close + Exit + +Edit + Undo # undoDelegator + Redo # undoDelegator + --- + Cut + Copy + Paste + Select All + --- # Next 5 items use SearchEngine; dialogs use SearchDialogBase + Find # Search Dialog + Find Again + Find Selection + Find in Files... # GrepDialog + Replace... # ReplaceDialog + Go to Line + Show Completions # AutoComplete extension and AutoCompleteWidow (&HP) + Expand Word # AutoExpand extension + Show call tip # Calltips extension and CalltipWindow (& Hyperparser) + Show surrounding parens # ParenMatch (& Hyperparser) + +Shell # PyShell + View Last Restart # PyShell.? + Restart Shell # PyShell.? + +Debug (Shell only) + Go to File/Line + Debugger # Debugger, RemoteDebugger + Stack Viewer # StackViewer + Auto-open Stack Viewer # StackViewer + +Format (Editor only) + Indent Region + Dedent Region + Comment Out Region + Uncomment Region + Tabify Region + Untabify Region + Toggle Tabs + New Indent Width + Format Paragraph # FormatParagraph extension + --- + Strip tailing whitespace # RstripExtension extension + +Run (Editor only) + Python Shell # PyShell + --- + Check Module # ScriptBinding + Run Module # ScriptBinding + +Options + Configure IDLE # configDialog + (tabs in the dialog) + Font tab # onfig-main.def + Highlight tab # configSectionNameDialog, config-highlight.def + Keys tab # keybindingDialog, configSectionNameDialog, onfig-keus.def + General tab # configHelpSourceEdit, config-main.def + Configure Extensions # configDialog + Xyz tab # xyz.py, config-extensions.def + --- + Code Context (editor only) # CodeContext extension + +Window + Zoomheight # ZoomHeight extension + --- + # WindowList + +Help + About IDLE # aboutDialog + --- + IDLE Help # help + Python Doc + Turtle Demo + --- + + + (right click) +Defined in EditorWindow, PyShell, Output + Cut + Copy + Paste + --- + Go to file/line (shell and output only) + Set Breakpoint (editor only) + Clear Breakpoint (editor only) + Defined in Debugger + Go to source line + Show stack frame diff --git a/Lib/idlelib/RemoteDebugger.py b/Lib/idlelib/RemoteDebugger.py index d8662bbd96eb..be2262f080c1 100644 --- a/Lib/idlelib/RemoteDebugger.py +++ b/Lib/idlelib/RemoteDebugger.py @@ -21,7 +21,6 @@ """ import types -from idlelib import rpc from idlelib import Debugger debugging = 0 @@ -99,7 +98,7 @@ def get_stack(self, fid, tbid): else: tb = tracebacktable[tbid] stack, i = self.idb.get_stack(frame, tb) - stack = [(wrap_frame(frame), k) for frame, k in stack] + stack = [(wrap_frame(frame2), k) for frame2, k in stack] return stack, i def run(self, cmd): diff --git a/Lib/idlelib/ReplaceDialog.py b/Lib/idlelib/ReplaceDialog.py index e73f2c503965..fc8b80f171e9 100644 --- a/Lib/idlelib/ReplaceDialog.py +++ b/Lib/idlelib/ReplaceDialog.py @@ -40,7 +40,7 @@ def open(self, text): def create_entries(self): SearchDialogBase.create_entries(self) - self.replent = self.make_entry("Replace with:", self.replvar) + self.replent = self.make_entry("Replace with:", self.replvar)[0] def create_command_buttons(self): SearchDialogBase.create_command_buttons(self) @@ -188,3 +188,34 @@ def show_hit(self, first, last): def close(self, event=None): SearchDialogBase.close(self, event) self.text.tag_remove("hit", "1.0", "end") + +def _replace_dialog(parent): + root = Tk() + root.title("Test ReplaceDialog") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + + # mock undo delegator methods + def undo_block_start(): + pass + + def undo_block_stop(): + pass + + text = Text(root) + text.undo_block_start = undo_block_start + text.undo_block_stop = undo_block_stop + text.pack() + text.insert("insert","This is a sample string.\n"*10) + + def show_replace(): + text.tag_add(SEL, "1.0", END) + replace(text) + text.tag_remove(SEL, "1.0", END) + + button = Button(root, text="Replace", command=show_replace) + button.pack() + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(_replace_dialog) diff --git a/Lib/idlelib/ScriptBinding.py b/Lib/idlelib/ScriptBinding.py index 6bfe128e3ce8..5cb818d833ba 100644 --- a/Lib/idlelib/ScriptBinding.py +++ b/Lib/idlelib/ScriptBinding.py @@ -18,13 +18,10 @@ """ import os -import re -import string import tabnanny import tokenize import tkinter.messagebox as tkMessageBox -from idlelib.EditorWindow import EditorWindow -from idlelib import PyShell, IOBinding +from idlelib import PyShell from idlelib.configHandler import idleConf from idlelib import macosxSupport @@ -39,6 +36,7 @@ by Format->Untabify Region and specify the number of columns used by each tab. """ + class ScriptBinding: menudefs = [ @@ -53,7 +51,7 @@ def __init__(self, editwin): self.flist = self.editwin.flist self.root = self.editwin.root - if macosxSupport.runningAsOSXApp(): + if macosxSupport.isCocoaTk(): self.editwin.text_frame.bind('<>', self._run_module_event) def check_module_event(self, event): @@ -71,7 +69,7 @@ def tabnanny(self, filename): try: tabnanny.process_tokens(tokenize.generate_tokens(f.readline)) except tokenize.TokenError as msg: - msgtxt, (lineno, start) = msg + msgtxt, (lineno, start) = msg.args self.editwin.gotoline(lineno) self.errorbox("Tabnanny Tokenizing Error", "Token Error: %s" % msgtxt) @@ -114,7 +112,7 @@ def checksyntax(self, filename): shell.set_warning_stream(saved_stream) def run_module_event(self, event): - if macosxSupport.runningAsOSXApp(): + if macosxSupport.isCocoaTk(): # Tk-Cocoa in MacOSX is broken until at least # Tk 8.5.9, and without this rather # crude workaround IDLE would hang when a user @@ -145,7 +143,8 @@ def _run_module_event(self, event): return 'break' interp = self.shell.interp if PyShell.use_subprocess: - interp.restart_subprocess(with_cwd=False) + interp.restart_subprocess(with_cwd=False, filename= + self.editwin._filename_to_unicode(filename)) dirname = os.path.dirname(filename) # XXX Too often this discards arguments the user just set... interp.runcommand("""if 1: @@ -198,10 +197,10 @@ def ask_save_dialog(self): confirm = tkMessageBox.askokcancel(title="Save Before Run or Check", message=msg, default=tkMessageBox.OK, - master=self.editwin.text) + parent=self.editwin.text) return confirm def errorbox(self, title, message): # XXX This should really be a function of EditorWindow... - tkMessageBox.showerror(title, message, master=self.editwin.text) + tkMessageBox.showerror(title, message, parent=self.editwin.text) self.editwin.text.focus_set() diff --git a/Lib/idlelib/ScrolledList.py b/Lib/idlelib/ScrolledList.py index 0255a0a23f9a..53576b5f82eb 100644 --- a/Lib/idlelib/ScrolledList.py +++ b/Lib/idlelib/ScrolledList.py @@ -1,4 +1,5 @@ from tkinter import * +from idlelib import macosxSupport class ScrolledList: @@ -22,7 +23,11 @@ def __init__(self, master, **options): # Bind events to the list box listbox.bind("", self.click_event) listbox.bind("", self.double_click_event) - listbox.bind("", self.popup_event) + if macosxSupport.isAquaTk(): + listbox.bind("", self.popup_event) + listbox.bind("", self.popup_event) + else: + listbox.bind("", self.popup_event) listbox.bind("", self.up_event) listbox.bind("", self.down_event) # Mark as empty @@ -119,21 +124,22 @@ def on_double(self, index): pass -def test(): +def _scrolled_list(parent): root = Tk() - root.protocol("WM_DELETE_WINDOW", root.destroy) + root.title("Test ScrolledList") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) class MyScrolledList(ScrolledList): - def fill_menu(self): self.menu.add_command(label="pass") + def fill_menu(self): self.menu.add_command(label="right click") def on_select(self, index): print("select", self.get(index)) def on_double(self, index): print("double", self.get(index)) - s = MyScrolledList(root) + + scrolled_list = MyScrolledList(root) for i in range(30): - s.append("item %02d" % i) - return root + scrolled_list.append("Item %02d" % i) -def main(): - root = test() root.mainloop() if __name__ == '__main__': - main() + from idlelib.idle_test.htest import run + run(_scrolled_list) diff --git a/Lib/idlelib/SearchDialog.py b/Lib/idlelib/SearchDialog.py index bf76c419ac33..77ef7b9a82c3 100644 --- a/Lib/idlelib/SearchDialog.py +++ b/Lib/idlelib/SearchDialog.py @@ -23,7 +23,7 @@ def find_selection(text): class SearchDialog(SearchDialogBase): def create_widgets(self): - f = SearchDialogBase.create_widgets(self) + SearchDialogBase.create_widgets(self) self.make_button("Find Next", self.default_command, 1) def default_command(self, event=None): @@ -65,3 +65,25 @@ def find_selection(self, text): if pat: self.engine.setcookedpat(pat) return self.find_again(text) + +def _search_dialog(parent): + root = Tk() + root.title("Test SearchDialog") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + text = Text(root) + text.pack() + text.insert("insert","This is a sample string.\n"*10) + + def show_find(): + text.tag_add(SEL, "1.0", END) + s = _setup(text) + s.open(text) + text.tag_remove(SEL, "1.0", END) + + button = Button(root, text="Search", command=show_find) + button.pack() + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(_search_dialog) diff --git a/Lib/idlelib/SearchDialogBase.py b/Lib/idlelib/SearchDialogBase.py index b8b49b2a1e3d..5fa84e238b16 100644 --- a/Lib/idlelib/SearchDialogBase.py +++ b/Lib/idlelib/SearchDialogBase.py @@ -1,34 +1,51 @@ '''Define SearchDialogBase used by Search, Replace, and Grep dialogs.''' -from tkinter import * + +from tkinter import (Toplevel, Frame, Entry, Label, Button, + Checkbutton, Radiobutton) class SearchDialogBase: - '''Create most of a modal search dialog (make_frame, create_widgets). + '''Create most of a 3 or 4 row, 3 column search dialog. - The wide left column contains: - 1 or 2 text entry lines (create_entries, make_entry); - a row of standard radiobuttons (create_option_buttons); - a row of dialog specific radiobuttons (create_other_buttons). + The left and wide middle column contain: + 1 or 2 labeled text entry lines (make_entry, create_entries); + a row of standard Checkbuttons (make_frame, create_option_buttons), + each of which corresponds to a search engine Variable; + a row of dialog-specific Check/Radiobuttons (create_other_buttons). The narrow right column contains command buttons - (create_command_buttons, make_button). + (make_button, create_command_buttons). These are bound to functions that execute the command. - Except for command buttons, this base class is not limited to - items common to all three subclasses. Rather, it is the Find dialog - minus the "Find Next" command and its execution function. - The other dialogs override methods to replace and add widgets. + Except for command buttons, this base class is not limited to items + common to all three subclasses. Rather, it is the Find dialog minus + the "Find Next" command, its execution function, and the + default_command attribute needed in create_widgets. The other + dialogs override attributes and methods, the latter to replace and + add widgets. ''' - title = "Search Dialog" + title = "Search Dialog" # replace in subclasses icon = "Search" - needwrapbutton = 1 + needwrapbutton = 1 # not in Find in Files def __init__(self, root, engine): + '''Initialize root, engine, and top attributes. + + top (level widget): set in create_widgets() called from open(). + text (Text searched): set in open(), only used in subclasses(). + ent (ry): created in make_entry() called from create_entry(). + row (of grid): 0 in create_widgets(), +1 in make_entry/frame(). + default_command: set in subclasses, used in create_widgers(). + + title (of dialog): class attribute, override in subclasses. + icon (of dialog): ditto, use unclear if cannot minimize dialog. + ''' self.root = root self.engine = engine self.top = None def open(self, text, searchphrase=None): + "Make dialog visible on top of others and ready to use." self.text = text if not self.top: self.create_widgets() @@ -44,11 +61,17 @@ def open(self, text, searchphrase=None): self.top.grab_set() def close(self, event=None): + "Put dialog away for later use." if self.top: self.top.grab_release() self.top.withdraw() def create_widgets(self): + '''Create basic 3 row x 3 col search (find) dialog. + + Other dialogs override subsidiary create_x methods as needed. + Replace and Find-in-Files add another entry row. + ''' top = Toplevel(self.root) top.bind("", self.default_command) top.bind("", self.close) @@ -61,29 +84,84 @@ def create_widgets(self): self.top.grid_columnconfigure(0, pad=2, weight=0) self.top.grid_columnconfigure(1, pad=2, minsize=100, weight=100) - self.create_entries() - self.create_option_buttons() - self.create_other_buttons() - return self.create_command_buttons() - - def make_entry(self, label, var): - l = Label(self.top, text=label) - l.grid(row=self.row, column=0, sticky="nw") - e = Entry(self.top, textvariable=var, exportselection=0) - e.grid(row=self.row, column=1, sticky="nwe") + self.create_entries() # row 0 (and maybe 1), cols 0, 1 + self.create_option_buttons() # next row, cols 0, 1 + self.create_other_buttons() # next row, cols 0, 1 + self.create_command_buttons() # col 2, all rows + + def make_entry(self, label_text, var): + '''Return (entry, label), . + + entry - gridded labeled Entry for text entry. + label - Label widget, returned for testing. + ''' + label = Label(self.top, text=label_text) + label.grid(row=self.row, column=0, sticky="nw") + entry = Entry(self.top, textvariable=var, exportselection=0) + entry.grid(row=self.row, column=1, sticky="nwe") self.row = self.row + 1 - return e + return entry, label + + def create_entries(self): + "Create one or more entry lines with make_entry." + self.ent = self.make_entry("Find:", self.engine.patvar)[0] def make_frame(self,labeltext=None): + '''Return (frame, label). + + frame - gridded labeled Frame for option or other buttons. + label - Label widget, returned for testing. + ''' if labeltext: - l = Label(self.top, text=labeltext) - l.grid(row=self.row, column=0, sticky="nw") - f = Frame(self.top) - f.grid(row=self.row, column=1, columnspan=1, sticky="nwe") + label = Label(self.top, text=labeltext) + label.grid(row=self.row, column=0, sticky="nw") + else: + label = '' + frame = Frame(self.top) + frame.grid(row=self.row, column=1, columnspan=1, sticky="nwe") self.row = self.row + 1 - return f + return frame, label + + def create_option_buttons(self): + '''Return (filled frame, options) for testing. + + Options is a list of SearchEngine booleanvar, label pairs. + A gridded frame from make_frame is filled with a Checkbutton + for each pair, bound to the var, with the corresponding label. + ''' + frame = self.make_frame("Options")[0] + engine = self.engine + options = [(engine.revar, "Regular expression"), + (engine.casevar, "Match case"), + (engine.wordvar, "Whole word")] + if self.needwrapbutton: + options.append((engine.wrapvar, "Wrap around")) + for var, label in options: + btn = Checkbutton(frame, anchor="w", variable=var, text=label) + btn.pack(side="left", fill="both") + if var.get(): + btn.select() + return frame, options + + def create_other_buttons(self): + '''Return (frame, others) for testing. + + Others is a list of value, label pairs. + A gridded frame from make_frame is filled with radio buttons. + ''' + frame = self.make_frame("Direction")[0] + var = self.engine.backvar + others = [(1, 'Up'), (0, 'Down')] + for val, label in others: + btn = Radiobutton(frame, anchor="w", + variable=var, value=val, text=label) + btn.pack(side="left", fill="both") + if var.get() == val: + btn.select() + return frame, others def make_button(self, label, command, isdef=0): + "Return command button gridded in command frame." b = Button(self.buttonframe, text=label, command=command, default=isdef and "active" or "normal") @@ -92,66 +170,15 @@ def make_button(self, label, command, isdef=0): self.buttonframe.grid(rowspan=rows+1) return b - def create_entries(self): - self.ent = self.make_entry("Find:", self.engine.patvar) - - def create_option_buttons(self): - f = self.make_frame("Options") - - btn = Checkbutton(f, anchor="w", - variable=self.engine.revar, - text="Regular expression") - btn.pack(side="left", fill="both") - if self.engine.isre(): - btn.select() - - btn = Checkbutton(f, anchor="w", - variable=self.engine.casevar, - text="Match case") - btn.pack(side="left", fill="both") - if self.engine.iscase(): - btn.select() - - btn = Checkbutton(f, anchor="w", - variable=self.engine.wordvar, - text="Whole word") - btn.pack(side="left", fill="both") - if self.engine.isword(): - btn.select() - - if self.needwrapbutton: - btn = Checkbutton(f, anchor="w", - variable=self.engine.wrapvar, - text="Wrap around") - btn.pack(side="left", fill="both") - if self.engine.iswrap(): - btn.select() - - def create_other_buttons(self): - f = self.make_frame("Direction") - - #lbl = Label(f, text="Direction: ") - #lbl.pack(side="left") - - btn = Radiobutton(f, anchor="w", - variable=self.engine.backvar, value=1, - text="Up") - btn.pack(side="left", fill="both") - if self.engine.isback(): - btn.select() - - btn = Radiobutton(f, anchor="w", - variable=self.engine.backvar, value=0, - text="Down") - btn.pack(side="left", fill="both") - if not self.engine.isback(): - btn.select() - def create_command_buttons(self): - # - # place button frame on the right + "Place buttons in vertical command frame gridded on right." f = self.buttonframe = Frame(self.top) f.grid(row=0,column=2,padx=2,pady=2,ipadx=2,ipady=2) b = self.make_button("close", self.close) b.lower() + +if __name__ == '__main__': + import unittest + unittest.main( + 'idlelib.idle_test.test_searchdialogbase', verbosity=2) diff --git a/Lib/idlelib/SearchEngine.py b/Lib/idlelib/SearchEngine.py index bbd221dec224..37883bf687c7 100644 --- a/Lib/idlelib/SearchEngine.py +++ b/Lib/idlelib/SearchEngine.py @@ -83,11 +83,9 @@ def getprog(self): try: prog = re.compile(pat, flags) except re.error as what: - try: - msg, col = what - except: - msg = str(what) - col = -1 + args = what.args + msg = args[0] + col = args[1] if len(args) >= 2 else -1 self.report_error(pat, msg, col) return None return prog @@ -109,7 +107,7 @@ def search_text(self, text, prog=None, ok=0): It directly return the result of that call. Text is a text widget. Prog is a precompiled pattern. - The ok parameteris a bit complicated as it has two effects. + The ok parameter is a bit complicated as it has two effects. If there is a selection, the search begin at either end, depending on the direction setting and ok, with ok meaning that @@ -193,7 +191,7 @@ def search_reverse(prog, chars, col): This is done by searching forwards until there is no match. Prog: compiled re object with a search method returning a match. - Chars: line of text, without \n. + Chars: line of text, without \\n. Col: stop index for the search; the limit for match.end(). ''' m = prog.search(chars) @@ -231,6 +229,5 @@ def get_line_col(index): return line, col if __name__ == "__main__": - from test import support; support.use_resources = ['gui'] import unittest unittest.main('idlelib.idle_test.test_searchengine', verbosity=2, exit=False) diff --git a/Lib/idlelib/StackViewer.py b/Lib/idlelib/StackViewer.py index 4ef2d31699eb..ccc755ce31b6 100644 --- a/Lib/idlelib/StackViewer.py +++ b/Lib/idlelib/StackViewer.py @@ -1,14 +1,16 @@ import os import sys import linecache +import re +import tkinter as tk from idlelib.TreeWidget import TreeNode, TreeItem, ScrolledCanvas from idlelib.ObjectBrowser import ObjectTreeItem, make_objecttreeitem +from idlelib.PyShell import PyShellFileList def StackBrowser(root, flist=None, tb=None, top=None): if top is None: - from tkinter import Toplevel - top = Toplevel(root) + top = tk.Toplevel(root) sc = ScrolledCanvas(top, bg="white", highlightthickness=0) sc.frame.pack(expand=1, fill="both") item = StackTreeItem(flist, tb) @@ -105,12 +107,9 @@ def GetLabelText(self): def IsExpandable(self): return len(self.object) > 0 - def keys(self): - return list(self.object.keys()) - def GetSubList(self): sublist = [] - for key in self.keys(): + for key in self.object.keys(): try: value = self.object[key] except KeyError: @@ -120,3 +119,33 @@ def setfunction(value, key=key, object=self.object): item = make_objecttreeitem(key + " =", value, setfunction) sublist.append(item) return sublist + + def keys(self): # unused, left for possible 3rd party use + return list(self.object.keys()) + +def _stack_viewer(parent): + root = tk.Tk() + root.title("Test StackViewer") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + flist = PyShellFileList(root) + try: # to obtain a traceback object + intentional_name_error + except NameError: + exc_type, exc_value, exc_tb = sys.exc_info() + + # inject stack trace to sys + sys.last_type = exc_type + sys.last_value = exc_value + sys.last_traceback = exc_tb + + StackBrowser(root, flist=flist, top=root, tb=exc_tb) + + # restore sys to original state + del sys.last_type + del sys.last_value + del sys.last_traceback + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(_stack_viewer) diff --git a/Lib/idlelib/ToolTip.py b/Lib/idlelib/ToolTip.py index b178803b02fe..964107e1176d 100644 --- a/Lib/idlelib/ToolTip.py +++ b/Lib/idlelib/ToolTip.py @@ -76,14 +76,22 @@ def showcontents(self): for item in self.items: listbox.insert(END, item) -def main(): - # Test code +def _tooltip(parent): root = Tk() - b = Button(root, text="Hello", command=root.destroy) - b.pack() - root.update() - tip = ListboxToolTip(b, ["Hello", "world"]) + root.title("Test tooltip") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + label = Label(root, text="Place your mouse over buttons") + label.pack() + button1 = Button(root, text="Button 1") + button2 = Button(root, text="Button 2") + button1.pack() + button2.pack() + ToolTip(button1, "This is tooltip text for button1.") + ListboxToolTip(button2, ["This is","multiple line", + "tooltip text","for button2"]) root.mainloop() if __name__ == '__main__': - main() + from idlelib.idle_test.htest import run + run(_tooltip) diff --git a/Lib/idlelib/TreeWidget.py b/Lib/idlelib/TreeWidget.py index 1f4854ddc42d..4844a695ad23 100644 --- a/Lib/idlelib/TreeWidget.py +++ b/Lib/idlelib/TreeWidget.py @@ -173,11 +173,12 @@ def update(self): def draw(self, x, y): # XXX This hard-codes too many geometry constants! + dy = 20 self.x, self.y = x, y self.drawicon() self.drawtext() if self.state != 'expanded': - return y+17 + return y + dy # draw children if not self.children: sublist = self.item._GetSubList() @@ -188,7 +189,7 @@ def draw(self, x, y): child = self.__class__(self.canvas, self, item) self.children.append(child) cx = x+20 - cy = y+17 + cy = y + dy cylast = 0 for child in self.children: cylast = cy @@ -227,7 +228,7 @@ def drawicon(self): def drawtext(self): textx = self.x+20-1 - texty = self.y-1 + texty = self.y-4 labeltext = self.item.GetLabelText() if labeltext: id = self.canvas.create_text(textx, texty, anchor="nw", @@ -244,7 +245,7 @@ def drawtext(self): else: self.edit_finish() try: - label = self.label + self.label except AttributeError: # padding carefully selected (on Windows) to match Entry widget: self.label = Label(self.canvas, text=text, bd=0, padx=2, pady=2) @@ -448,29 +449,18 @@ def zoom_height(self, event): return "break" -# Testing functions - -def test(): - from idlelib import PyShell - root = Toplevel(PyShell.root) - root.configure(bd=0, bg="yellow") - root.focus_set() +def _tree_widget(parent): + root = Tk() + root.title("Test TreeWidget") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) sc = ScrolledCanvas(root, bg="white", highlightthickness=0, takefocus=1) - sc.frame.pack(expand=1, fill="both") - item = FileTreeItem("C:/windows/desktop") + sc.frame.pack(expand=1, fill="both", side=LEFT) + item = FileTreeItem(os.getcwd()) node = TreeNode(sc.canvas, None, item) node.expand() - -def test2(): - # test w/o scrolling canvas - root = Tk() - root.configure(bd=0) - canvas = Canvas(root, bg="white", highlightthickness=0) - canvas.pack(expand=1, fill="both") - item = FileTreeItem(os.curdir) - node = TreeNode(canvas, None, item) - node.update() - canvas.focus_set() + root.mainloop() if __name__ == '__main__': - test() + from idlelib.idle_test.htest import run + run(_tree_widget) diff --git a/Lib/idlelib/UndoDelegator.py b/Lib/idlelib/UndoDelegator.py index d2ef638ad244..04c1cf5a2738 100644 --- a/Lib/idlelib/UndoDelegator.py +++ b/Lib/idlelib/UndoDelegator.py @@ -336,17 +336,30 @@ def bump_depth(self, incr=1): self.depth = self.depth + incr return self.depth -def main(): +def _undo_delegator(parent): from idlelib.Percolator import Percolator root = Tk() - root.wm_protocol("WM_DELETE_WINDOW", root.quit) - text = Text() + root.title("Test UndoDelegator") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + + text = Text(root) + text.config(height=10) text.pack() text.focus_set() p = Percolator(text) d = UndoDelegator() p.insertfilter(d) + + undo = Button(root, text="Undo", command=lambda:d.undo_event(None)) + undo.pack(side='left') + redo = Button(root, text="Redo", command=lambda:d.redo_event(None)) + redo.pack(side='left') + dump = Button(root, text="Dump", command=lambda:d.dump_event(None)) + dump.pack(side='left') + root.mainloop() if __name__ == "__main__": - main() + from idlelib.idle_test.htest import run + run(_undo_delegator) diff --git a/Lib/idlelib/WidgetRedirector.py b/Lib/idlelib/WidgetRedirector.py index ba5251ff71f4..67d7f61e623b 100644 --- a/Lib/idlelib/WidgetRedirector.py +++ b/Lib/idlelib/WidgetRedirector.py @@ -1,29 +1,40 @@ -from tkinter import * +from tkinter import TclError class WidgetRedirector: - """Support for redirecting arbitrary widget subcommands. - Some Tk operations don't normally pass through Tkinter. For example, if a + Some Tk operations don't normally pass through tkinter. For example, if a character is inserted into a Text widget by pressing a key, a default Tk binding to the widget's 'insert' operation is activated, and the Tk library - processes the insert without calling back into Tkinter. + processes the insert without calling back into tkinter. - Although a binding to could be made via Tkinter, what we really want - to do is to hook the Tk 'insert' operation itself. + Although a binding to could be made via tkinter, what we really want + to do is to hook the Tk 'insert' operation itself. For one thing, we want + a text.insert call in idle code to have the same effect as a key press. When a widget is instantiated, a Tcl command is created whose name is the same as the pathname widget._w. This command is used to invoke the various widget operations, e.g. insert (for a Text widget). We are going to hook this command and provide a facility ('register') to intercept the widget - operation. - - In IDLE, the function being registered provides access to the top of a - Percolator chain. At the bottom of the chain is a call to the original - Tk widget operation. + operation. We will also intercept method calls on the tkinter class + instance that represents the tk widget. + In IDLE, WidgetRedirector is used in Percolator to intercept Text + commands. The function being registered provides access to the top + of a Percolator chain. At the bottom of the chain is a call to the + original Tk widget operation. """ def __init__(self, widget): + '''Initialize attributes and setup redirection. + + _operations: dict mapping operation name to new function. + widget: the widget whose tcl command is to be intercepted. + tk: widget.tk, a convenience attribute, probably not needed. + orig: new name of the original tcl command. + + Since renaming to orig fails with TclError when orig already + exists, only one WidgetDirector can exist for a given widget. + ''' self._operations = {} self.widget = widget # widget instance self.tk = tk = widget.tk # widget's root @@ -36,31 +47,50 @@ def __init__(self, widget): tk.createcommand(w, self.dispatch) def __repr__(self): - return "WidgetRedirector(%s<%s>)" % (self.widget.__class__.__name__, - self.widget._w) + return "%s(%s<%s>)" % (self.__class__.__name__, + self.widget.__class__.__name__, + self.widget._w) def close(self): + "Unregister operations and revert redirection created by .__init__." for operation in list(self._operations): self.unregister(operation) - widget = self.widget; del self.widget - orig = self.orig; del self.orig + widget = self.widget tk = widget.tk w = widget._w + # Restore the original widget Tcl command. tk.deletecommand(w) - # restore the original widget Tcl command: - tk.call("rename", orig, w) + tk.call("rename", self.orig, w) + del self.widget, self.tk # Should not be needed + # if instance is deleted after close, as in Percolator. def register(self, operation, function): + '''Return OriginalCommand(operation) after registering function. + + Registration adds an operation: function pair to ._operations. + It also adds an widget function attribute that masks the tkinter + class instance method. Method masking operates independently + from command dispatch. + + If a second function is registered for the same operation, the + first function is replaced in both places. + ''' self._operations[operation] = function setattr(self.widget, operation, function) return OriginalCommand(self, operation) def unregister(self, operation): + '''Return the function for the operation, or None. + + Deleting the instance attribute unmasks the class attribute. + ''' if operation in self._operations: function = self._operations[operation] del self._operations[operation] - if hasattr(self.widget, operation): + try: delattr(self.widget, operation) + except AttributeError: + pass return function else: return None @@ -88,39 +118,59 @@ def dispatch(self, operation, *args): class OriginalCommand: + '''Callable for original tk command that has been redirected. + + Returned by .register; can be used in the function registered. + redir = WidgetRedirector(text) + def my_insert(*args): + print("insert", args) + original_insert(*args) + original_insert = redir.register("insert", my_insert) + ''' def __init__(self, redir, operation): + '''Create .tk_call and .orig_and_operation for .__call__ method. + + .redir and .operation store the input args for __repr__. + .tk and .orig copy attributes of .redir (probably not needed). + ''' self.redir = redir self.operation = operation - self.tk = redir.tk - self.orig = redir.orig - self.tk_call = self.tk.call - self.orig_and_operation = (self.orig, self.operation) + self.tk = redir.tk # redundant with self.redir + self.orig = redir.orig # redundant with self.redir + # These two could be deleted after checking recipient code. + self.tk_call = redir.tk.call + self.orig_and_operation = (redir.orig, operation) def __repr__(self): - return "OriginalCommand(%r, %r)" % (self.redir, self.operation) + return "%s(%r, %r)" % (self.__class__.__name__, + self.redir, self.operation) def __call__(self, *args): return self.tk_call(self.orig_and_operation + args) -def main(): +def _widget_redirector(parent): # htest # + from tkinter import Tk, Text + import re + root = Tk() - root.wm_protocol("WM_DELETE_WINDOW", root.quit) - text = Text() + root.title("Test WidgetRedirector") + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 150)) + text = Text(root) text.pack() text.focus_set() redir = WidgetRedirector(text) - global previous_tcl_fcn def my_insert(*args): print("insert", args) - previous_tcl_fcn(*args) - previous_tcl_fcn = redir.register("insert", my_insert) - root.mainloop() - redir.unregister("insert") # runs after first 'close window' - redir.close() + original_insert(*args) + original_insert = redir.register("insert", my_insert) root.mainloop() - root.destroy() if __name__ == "__main__": - main() + import unittest + unittest.main('idlelib.idle_test.test_widgetredir', + verbosity=2, exit=False) + from idlelib.idle_test.htest import run + run(_widget_redirector) diff --git a/Lib/idlelib/ZoomHeight.py b/Lib/idlelib/ZoomHeight.py index e8d171075106..a5d679e49912 100644 --- a/Lib/idlelib/ZoomHeight.py +++ b/Lib/idlelib/ZoomHeight.py @@ -32,7 +32,7 @@ def zoom_height(top): newy = 0 newheight = newheight - 72 - elif macosxSupport.runningAsOSXApp(): + elif macosxSupport.isAquaTk(): # The '88' below is a magic number that avoids placing the bottom # of the window below the panel on my machine. I don't know how # to calculate the correct value for this with tkinter. diff --git a/Lib/idlelib/__init__.py b/Lib/idlelib/__init__.py index 7a83ddea76ca..711f61bb6928 100644 --- a/Lib/idlelib/__init__.py +++ b/Lib/idlelib/__init__.py @@ -1 +1,8 @@ -# Dummy file to make this a package. +"""The idlelib package implements the Idle application. + +Idle includes an interactive shell and editor. +Use the files named idle.* to start Idle. + +The other files are private implementations. Their details are subject to +change. See PEP 434 for more. Import them at your own risk. +""" diff --git a/Lib/idlelib/__main__.py b/Lib/idlelib/__main__.py index 0666f2fd1b36..2edf5f7dc142 100644 --- a/Lib/idlelib/__main__.py +++ b/Lib/idlelib/__main__.py @@ -3,7 +3,6 @@ Run IDLE as python -m idlelib """ - - import idlelib.PyShell idlelib.PyShell.main() +# This file does not work for 2.7; See issue 24212. diff --git a/Lib/idlelib/aboutDialog.py b/Lib/idlelib/aboutDialog.py index 7fe1ab81ee53..d876a97115ae 100644 --- a/Lib/idlelib/aboutDialog.py +++ b/Lib/idlelib/aboutDialog.py @@ -2,21 +2,25 @@ """ -from tkinter import * import os - +from sys import version +from tkinter import * from idlelib import textView -from idlelib import idlever class AboutDialog(Toplevel): """Modal about dialog for idle """ - def __init__(self,parent,title): + def __init__(self, parent, title, _htest=False): + """ + _htest - bool, change box location when running htest + """ Toplevel.__init__(self, parent) self.configure(borderwidth=5) - self.geometry("+%d+%d" % (parent.winfo_rootx()+30, - parent.winfo_rooty()+30)) + # place dialog below parent if running htest + self.geometry("+%d+%d" % ( + parent.winfo_rootx()+30, + parent.winfo_rooty()+(30 if not _htest else 100))) self.bg = "#707070" self.fg = "#ffffff" self.CreateWidgets() @@ -32,6 +36,7 @@ def __init__(self,parent,title): self.wait_window() def CreateWidgets(self): + release = version[:version.index(' ')] frameMain = Frame(self, borderwidth=2, relief=SUNKEN) frameButtons = Frame(self) frameButtons.pack(side=BOTTOM, fill=X) @@ -57,14 +62,15 @@ def CreateWidgets(self): justify=LEFT, fg=self.fg, bg=self.bg) labelEmail.grid(row=6, column=0, columnspan=2, sticky=W, padx=10, pady=0) - labelWWW = Label(frameBg, text='www: http://www.python.org/idle/', + labelWWW = Label(frameBg, text='https://docs.python.org/' + + version[:3] + '/library/idle.html', justify=LEFT, fg=self.fg, bg=self.bg) labelWWW.grid(row=7, column=0, columnspan=2, sticky=W, padx=10, pady=0) Frame(frameBg, borderwidth=1, relief=SUNKEN, height=2, bg=self.bg).grid(row=8, column=0, sticky=EW, columnspan=3, padx=5, pady=5) - labelPythonVer = Label(frameBg, text='Python version: ' + \ - sys.version.split()[0], fg=self.fg, bg=self.bg) + labelPythonVer = Label(frameBg, text='Python version: ' + + release, fg=self.fg, bg=self.bg) labelPythonVer.grid(row=9, column=0, sticky=W, padx=10, pady=0) tkVer = self.tk.call('info', 'patchlevel') labelTkVer = Label(frameBg, text='Tk version: '+ @@ -87,7 +93,7 @@ def CreateWidgets(self): Frame(frameBg, borderwidth=1, relief=SUNKEN, height=2, bg=self.bg).grid(row=11, column=0, sticky=EW, columnspan=3, padx=5, pady=5) - idle_v = Label(frameBg, text='IDLE version: ' + idlever.IDLE_VERSION, + idle_v = Label(frameBg, text='IDLE version: ' + release, fg=self.fg, bg=self.bg) idle_v.grid(row=12, column=0, sticky=W, padx=10, pady=0) idle_button_f = Frame(frameBg, bg=self.bg) @@ -136,10 +142,5 @@ def Ok(self, event=None): self.destroy() if __name__ == '__main__': - # test the dialog - root = Tk() - def run(): - from idlelib import aboutDialog - aboutDialog.AboutDialog(root, 'About') - Button(root, text='Dialog', command=run).pack() - root.mainloop() + from idlelib.idle_test.htest import run + run(AboutDialog) diff --git a/Lib/idlelib/config-extensions.def b/Lib/idlelib/config-extensions.def index 39e69ce20d4f..a24b8c9316ba 100644 --- a/Lib/idlelib/config-extensions.def +++ b/Lib/idlelib/config-extensions.def @@ -3,94 +3,97 @@ # IDLE reads several config files to determine user preferences. This # file is the default configuration file for IDLE extensions settings. # -# Each extension must have at least one section, named after the extension -# module. This section must contain an 'enable' item (=1 to enable the -# extension, =0 to disable it), it may contain 'enable_editor' or 'enable_shell' -# items, to apply it only to editor/shell windows, and may also contain any -# other general configuration items for the extension. +# Each extension must have at least one section, named after the +# extension module. This section must contain an 'enable' item (=True to +# enable the extension, =False to disable it), it may contain +# 'enable_editor' or 'enable_shell' items, to apply it only to editor ir +# shell windows, and may also contain any other general configuration +# items for the extension. Other True/False values will also be +# recognized as boolean by the Extension Configuration dialog. # -# Each extension must define at least one section named ExtensionName_bindings -# or ExtensionName_cfgBindings. If present, ExtensionName_bindings defines -# virtual event bindings for the extension that are not user re-configurable. -# If present, ExtensionName_cfgBindings defines virtual event bindings for the +# Each extension must define at least one section named +# ExtensionName_bindings or ExtensionName_cfgBindings. If present, +# ExtensionName_bindings defines virtual event bindings for the +# extension that are not user re-configurable. If present, +# ExtensionName_cfgBindings defines virtual event bindings for the # extension that may be sensibly re-configured. # -# If there are no keybindings for a menus' virtual events, include lines like -# <>= (See [CodeContext], below.) +# If there are no keybindings for a menus' virtual events, include lines +# like <>= (See [CodeContext], below.) # -# Currently it is necessary to manually modify this file to change extension -# key bindings and default values. To customize, create +# Currently it is necessary to manually modify this file to change +# extension key bindings and default values. To customize, create # ~/.idlerc/config-extensions.cfg and append the appropriate customized # section(s). Those sections will override the defaults in this file. # -# Note: If a keybinding is already in use when the extension is -# loaded, the extension's virtual event's keybinding will be set to ''. +# Note: If a keybinding is already in use when the extension is loaded, +# the extension's virtual event's keybinding will be set to ''. # # See config-keys.def for notes on specifying keys and extend.txt for # information on creating IDLE extensions. -[FormatParagraph] -enable=1 -[FormatParagraph_cfgBindings] -format-paragraph= +[AutoComplete] +enable=True +popupwait=2000 +[AutoComplete_cfgBindings] +force-open-completions= +[AutoComplete_bindings] +autocomplete= +try-open-completions= [AutoExpand] -enable=1 +enable=True [AutoExpand_cfgBindings] expand-word= -[ZoomHeight] -enable=1 -[ZoomHeight_cfgBindings] -zoom-height= - -[ScriptBinding] -enable=1 -enable_shell=0 -enable_editor=1 -[ScriptBinding_cfgBindings] -run-module= -check-module= - [CallTips] -enable=1 +enable=True [CallTips_cfgBindings] force-open-calltip= [CallTips_bindings] try-open-calltip= refresh-calltip= +[CodeContext] +enable=True +enable_shell=False +numlines=3 +visible=False +bgcolor=LightGray +fgcolor=Black +[CodeContext_bindings] +toggle-code-context= + +[FormatParagraph] +enable=True +max-width=72 +[FormatParagraph_cfgBindings] +format-paragraph= + [ParenMatch] -enable=1 +enable=True style= expression flash-delay= 500 -bell= 1 +bell=True [ParenMatch_cfgBindings] flash-paren= [ParenMatch_bindings] paren-closed= -[AutoComplete] -enable=1 -popupwait=2000 -[AutoComplete_cfgBindings] -force-open-completions= -[AutoComplete_bindings] -autocomplete= -try-open-completions= - -[CodeContext] -enable=1 -enable_shell=0 -numlines=3 -visible=0 -bgcolor=LightGray -fgcolor=Black -[CodeContext_bindings] -toggle-code-context= - [RstripExtension] -enable=1 -enable_shell=0 -enable_editor=1 +enable=True +enable_shell=False +enable_editor=True +[ScriptBinding] +enable=True +enable_shell=False +enable_editor=True +[ScriptBinding_cfgBindings] +run-module= +check-module= + +[ZoomHeight] +enable=True +[ZoomHeight_cfgBindings] +zoom-height= diff --git a/Lib/idlelib/config-highlight.def b/Lib/idlelib/config-highlight.def index 7d20f7824077..4146e28c4eda 100644 --- a/Lib/idlelib/config-highlight.def +++ b/Lib/idlelib/config-highlight.def @@ -62,3 +62,32 @@ stderr-foreground= red stderr-background= #ffffff console-foreground= #770000 console-background= #ffffff + +[IDLE Dark] +comment-foreground = #dd0000 +console-foreground = #ff4d4d +error-foreground = #FFFFFF +hilite-background = #7e7e7e +string-foreground = #02ff02 +stderr-background = #002240 +stderr-foreground = #ffb3b3 +console-background = #002240 +hit-background = #fbfbfb +string-background = #002240 +normal-background = #002240 +hilite-foreground = #FFFFFF +keyword-foreground = #ff8000 +error-background = #c86464 +keyword-background = #002240 +builtin-background = #002240 +break-background = #808000 +builtin-foreground = #ff00ff +definition-foreground = #5e5eff +stdout-foreground = #c2d1fa +definition-background = #002240 +normal-foreground = #FFFFFF +cursor-foreground = #ffffff +stdout-background = #002240 +hit-foreground = #002240 +comment-background = #002240 +break-foreground = #FFFFFF diff --git a/Lib/idlelib/config-keys.def b/Lib/idlelib/config-keys.def index fdc35ba7b5ac..3bfcb690153c 100644 --- a/Lib/idlelib/config-keys.def +++ b/Lib/idlelib/config-keys.def @@ -13,37 +13,37 @@ cut= paste= beginning-of-line= center-insert= -close-all-windows= +close-all-windows= close-window= do-nothing= end-of-file= python-docs= python-context-help= -history-next= -history-previous= +history-next= +history-previous= interrupt-execution= view-restart= restart-shell= -open-class-browser= -open-module= +open-class-browser= +open-module= open-new-window= open-window-from-file= plain-newline-and-indent= print-window= -redo= +redo= remove-selection= -save-copy-of-window-as-file= -save-window-as-file= -save-window= -select-all= +save-copy-of-window-as-file= +save-window-as-file= +save-window= +select-all= toggle-auto-coloring= undo= find= -find-again= +find-again= find-in-files= find-selection= replace= -goto-line= +goto-line= smart-backspace= newline-and-indent= smart-indent= @@ -53,8 +53,8 @@ comment-region= uncomment-region= tabify-region= untabify-region= -toggle-tabs= -change-indentwidth= +toggle-tabs= +change-indentwidth= del-word-left= del-word-right= diff --git a/Lib/idlelib/config-main.def b/Lib/idlelib/config-main.def index 9546e2bf1287..3622cb2a30f4 100644 --- a/Lib/idlelib/config-main.def +++ b/Lib/idlelib/config-main.def @@ -53,14 +53,11 @@ delete-exitfunc= 1 [EditorWindow] width= 80 height= 40 -font= courier +font= TkFixedFont font-size= 10 font-bold= 0 encoding= none -[FormatParagraph] -paragraph=70 - [Indent] use-spaces= 1 num-spaces= 4 diff --git a/Lib/idlelib/configDialog.py b/Lib/idlelib/configDialog.py index 1f4a3a576891..f5388178e0ec 100644 --- a/Lib/idlelib/configDialog.py +++ b/Lib/idlelib/configDialog.py @@ -13,533 +13,579 @@ import tkinter.messagebox as tkMessageBox import tkinter.colorchooser as tkColorChooser import tkinter.font as tkFont -import copy from idlelib.configHandler import idleConf from idlelib.dynOptionMenuWidget import DynOptionMenu -from idlelib.tabbedpages import TabbedPageSet from idlelib.keybindingDialog import GetKeysDialog from idlelib.configSectionNameDialog import GetCfgSectionNameDialog from idlelib.configHelpSourceEdit import GetHelpSourceDialog +from idlelib.tabbedpages import TabbedPageSet +from idlelib.textView import view_text from idlelib import macosxSupport class ConfigDialog(Toplevel): - def __init__(self,parent,title): + def __init__(self, parent, title='', _htest=False, _utest=False): + """ + _htest - bool, change box location when running htest + _utest - bool, don't wait_window when running unittest + """ Toplevel.__init__(self, parent) + self.parent = parent + if _htest: + parent.instance_dict = {} self.wm_withdraw() self.configure(borderwidth=5) - self.title('IDLE Preferences') - self.geometry("+%d+%d" % (parent.winfo_rootx()+20, - parent.winfo_rooty()+30)) + self.title(title or 'IDLE Preferences') + self.geometry( + "+%d+%d" % (parent.winfo_rootx() + 20, + parent.winfo_rooty() + (30 if not _htest else 150))) #Theme Elements. Each theme element key is its display name. #The first value of the tuple is the sample area tag name. #The second value is the display name list sort index. - self.themeElements={'Normal Text':('normal','00'), - 'Python Keywords':('keyword','01'), - 'Python Definitions':('definition','02'), - 'Python Builtins':('builtin', '03'), - 'Python Comments':('comment','04'), - 'Python Strings':('string','05'), - 'Selected Text':('hilite','06'), - 'Found Text':('hit','07'), - 'Cursor':('cursor','08'), - 'Error Text':('error','09'), - 'Shell Normal Text':('console','10'), - 'Shell Stdout Text':('stdout','11'), - 'Shell Stderr Text':('stderr','12'), + self.themeElements={ + 'Normal Text': ('normal', '00'), + 'Python Keywords': ('keyword', '01'), + 'Python Definitions': ('definition', '02'), + 'Python Builtins': ('builtin', '03'), + 'Python Comments': ('comment', '04'), + 'Python Strings': ('string', '05'), + 'Selected Text': ('hilite', '06'), + 'Found Text': ('hit', '07'), + 'Cursor': ('cursor', '08'), + 'Editor Breakpoint': ('break', '09'), + 'Shell Normal Text': ('console', '10'), + 'Shell Error Text': ('error', '11'), + 'Shell Stdout Text': ('stdout', '12'), + 'Shell Stderr Text': ('stderr', '13'), } self.ResetChangedItems() #load initial values in changed items dict self.CreateWidgets() - self.resizable(height=FALSE,width=FALSE) + self.resizable(height=FALSE, width=FALSE) self.transient(parent) self.grab_set() self.protocol("WM_DELETE_WINDOW", self.Cancel) - self.parent = parent self.tabPages.focus_set() #key bindings for this dialog - #self.bind('',self.Cancel) #dismiss dialog, no save - #self.bind('',self.Apply) #apply changes, save - #self.bind('',self.Help) #context help + #self.bind('', self.Cancel) #dismiss dialog, no save + #self.bind('', self.Apply) #apply changes, save + #self.bind('', self.Help) #context help self.LoadConfigs() self.AttachVarCallbacks() #avoid callbacks during LoadConfigs - self.wm_deiconify() - self.wait_window() + if not _utest: + self.wm_deiconify() + self.wait_window() def CreateWidgets(self): self.tabPages = TabbedPageSet(self, - page_names=['Fonts/Tabs','Highlighting','Keys','General']) - frameActionButtons = Frame(self,pady=2) - #action buttons - - if macosxSupport.runningAsOSXApp(): - # Surpress the padx and pady arguments when - # running as IDLE.app, otherwise the text - # on these buttons will not be readable. - extraKwds={} - else: - extraKwds=dict(padx=6, pady=3) - - self.buttonHelp = Button(frameActionButtons,text='Help', - command=self.Help,takefocus=FALSE, - **extraKwds) - self.buttonOk = Button(frameActionButtons,text='Ok', - command=self.Ok,takefocus=FALSE, - **extraKwds) - self.buttonApply = Button(frameActionButtons,text='Apply', - command=self.Apply,takefocus=FALSE, - **extraKwds) - self.buttonCancel = Button(frameActionButtons,text='Cancel', - command=self.Cancel,takefocus=FALSE, - **extraKwds) + page_names=['Fonts/Tabs', 'Highlighting', 'Keys', 'General', + 'Extensions']) + self.tabPages.pack(side=TOP, expand=TRUE, fill=BOTH) self.CreatePageFontTab() self.CreatePageHighlight() self.CreatePageKeys() self.CreatePageGeneral() - self.buttonHelp.pack(side=RIGHT,padx=5) - self.buttonOk.pack(side=LEFT,padx=5) - self.buttonApply.pack(side=LEFT,padx=5) - self.buttonCancel.pack(side=LEFT,padx=5) - frameActionButtons.pack(side=BOTTOM) - Frame(self, height=2, borderwidth=0).pack(side=BOTTOM) - self.tabPages.pack(side=TOP,expand=TRUE,fill=BOTH) + self.CreatePageExtensions() + self.create_action_buttons().pack(side=BOTTOM) + + def create_action_buttons(self): + if macosxSupport.isAquaTk(): + # Changing the default padding on OSX results in unreadable + # text in the buttons + paddingArgs = {} + else: + paddingArgs = {'padx':6, 'pady':3} + outer = Frame(self, pady=2) + buttons = Frame(outer, pady=2) + for txt, cmd in ( + ('Ok', self.Ok), + ('Apply', self.Apply), + ('Cancel', self.Cancel), + ('Help', self.Help)): + Button(buttons, text=txt, command=cmd, takefocus=FALSE, + **paddingArgs).pack(side=LEFT, padx=5) + # add space above buttons + Frame(outer, height=2, borderwidth=0).pack(side=TOP) + buttons.pack(side=BOTTOM) + return outer def CreatePageFontTab(self): - #tkVars - self.fontSize=StringVar(self) - self.fontBold=BooleanVar(self) - self.fontName=StringVar(self) - self.spaceNum=IntVar(self) - self.editFont=tkFont.Font(self,('courier',10,'normal')) + parent = self.parent + self.fontSize = StringVar(parent) + self.fontBold = BooleanVar(parent) + self.fontName = StringVar(parent) + self.spaceNum = IntVar(parent) + self.editFont = tkFont.Font(parent, ('courier', 10, 'normal')) + ##widget creation #body frame - frame=self.tabPages.pages['Fonts/Tabs'].frame + frame = self.tabPages.pages['Fonts/Tabs'].frame #body section frames - frameFont=LabelFrame(frame,borderwidth=2,relief=GROOVE, - text=' Base Editor Font ') - frameIndent=LabelFrame(frame,borderwidth=2,relief=GROOVE, - text=' Indentation Width ') + frameFont = LabelFrame( + frame, borderwidth=2, relief=GROOVE, text=' Base Editor Font ') + frameIndent = LabelFrame( + frame, borderwidth=2, relief=GROOVE, text=' Indentation Width ') #frameFont - frameFontName=Frame(frameFont) - frameFontParam=Frame(frameFont) - labelFontNameTitle=Label(frameFontName,justify=LEFT, - text='Font Face :') - self.listFontName=Listbox(frameFontName,height=5,takefocus=FALSE, - exportselection=FALSE) - self.listFontName.bind('',self.OnListFontButtonRelease) - scrollFont=Scrollbar(frameFontName) + frameFontName = Frame(frameFont) + frameFontParam = Frame(frameFont) + labelFontNameTitle = Label( + frameFontName, justify=LEFT, text='Font Face :') + self.listFontName = Listbox( + frameFontName, height=5, takefocus=FALSE, exportselection=FALSE) + self.listFontName.bind( + '', self.OnListFontButtonRelease) + scrollFont = Scrollbar(frameFontName) scrollFont.config(command=self.listFontName.yview) self.listFontName.config(yscrollcommand=scrollFont.set) - labelFontSizeTitle=Label(frameFontParam,text='Size :') - self.optMenuFontSize=DynOptionMenu(frameFontParam,self.fontSize,None, - command=self.SetFontSample) - checkFontBold=Checkbutton(frameFontParam,variable=self.fontBold, - onvalue=1,offvalue=0,text='Bold',command=self.SetFontSample) - frameFontSample=Frame(frameFont,relief=SOLID,borderwidth=1) - self.labelFontSample=Label(frameFontSample, - text='AaBbCcDdEe\nFfGgHhIiJjK\n1234567890\n#:+=(){}[]', - justify=LEFT,font=self.editFont) + labelFontSizeTitle = Label(frameFontParam, text='Size :') + self.optMenuFontSize = DynOptionMenu( + frameFontParam, self.fontSize, None, command=self.SetFontSample) + checkFontBold = Checkbutton( + frameFontParam, variable=self.fontBold, onvalue=1, + offvalue=0, text='Bold', command=self.SetFontSample) + frameFontSample = Frame(frameFont, relief=SOLID, borderwidth=1) + self.labelFontSample = Label( + frameFontSample, justify=LEFT, font=self.editFont, + text='AaBbCcDdEe\nFfGgHhIiJjK\n1234567890\n#:+=(){}[]') #frameIndent - frameIndentSize=Frame(frameIndent) - labelSpaceNumTitle=Label(frameIndentSize, justify=LEFT, - text='Python Standard: 4 Spaces!') - self.scaleSpaceNum=Scale(frameIndentSize, variable=self.spaceNum, - orient='horizontal', - tickinterval=2, from_=2, to=16) + frameIndentSize = Frame(frameIndent) + labelSpaceNumTitle = Label( + frameIndentSize, justify=LEFT, + text='Python Standard: 4 Spaces!') + self.scaleSpaceNum = Scale( + frameIndentSize, variable=self.spaceNum, + orient='horizontal', tickinterval=2, from_=2, to=16) + #widget packing #body - frameFont.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH) - frameIndent.pack(side=LEFT,padx=5,pady=5,fill=Y) + frameFont.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH) + frameIndent.pack(side=LEFT, padx=5, pady=5, fill=Y) #frameFont - frameFontName.pack(side=TOP,padx=5,pady=5,fill=X) - frameFontParam.pack(side=TOP,padx=5,pady=5,fill=X) - labelFontNameTitle.pack(side=TOP,anchor=W) - self.listFontName.pack(side=LEFT,expand=TRUE,fill=X) - scrollFont.pack(side=LEFT,fill=Y) - labelFontSizeTitle.pack(side=LEFT,anchor=W) - self.optMenuFontSize.pack(side=LEFT,anchor=W) - checkFontBold.pack(side=LEFT,anchor=W,padx=20) - frameFontSample.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH) - self.labelFontSample.pack(expand=TRUE,fill=BOTH) + frameFontName.pack(side=TOP, padx=5, pady=5, fill=X) + frameFontParam.pack(side=TOP, padx=5, pady=5, fill=X) + labelFontNameTitle.pack(side=TOP, anchor=W) + self.listFontName.pack(side=LEFT, expand=TRUE, fill=X) + scrollFont.pack(side=LEFT, fill=Y) + labelFontSizeTitle.pack(side=LEFT, anchor=W) + self.optMenuFontSize.pack(side=LEFT, anchor=W) + checkFontBold.pack(side=LEFT, anchor=W, padx=20) + frameFontSample.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH) + self.labelFontSample.pack(expand=TRUE, fill=BOTH) #frameIndent - frameIndentSize.pack(side=TOP,fill=X) - labelSpaceNumTitle.pack(side=TOP,anchor=W,padx=5) - self.scaleSpaceNum.pack(side=TOP,padx=5,fill=X) + frameIndentSize.pack(side=TOP, fill=X) + labelSpaceNumTitle.pack(side=TOP, anchor=W, padx=5) + self.scaleSpaceNum.pack(side=TOP, padx=5, fill=X) return frame def CreatePageHighlight(self): - self.builtinTheme=StringVar(self) - self.customTheme=StringVar(self) - self.fgHilite=BooleanVar(self) - self.colour=StringVar(self) - self.fontName=StringVar(self) - self.themeIsBuiltin=BooleanVar(self) - self.highlightTarget=StringVar(self) + parent = self.parent + self.builtinTheme = StringVar(parent) + self.customTheme = StringVar(parent) + self.fgHilite = BooleanVar(parent) + self.colour = StringVar(parent) + self.fontName = StringVar(parent) + self.themeIsBuiltin = BooleanVar(parent) + self.highlightTarget = StringVar(parent) + ##widget creation #body frame - frame=self.tabPages.pages['Highlighting'].frame + frame = self.tabPages.pages['Highlighting'].frame #body section frames - frameCustom=LabelFrame(frame,borderwidth=2,relief=GROOVE, - text=' Custom Highlighting ') - frameTheme=LabelFrame(frame,borderwidth=2,relief=GROOVE, - text=' Highlighting Theme ') + frameCustom = LabelFrame(frame, borderwidth=2, relief=GROOVE, + text=' Custom Highlighting ') + frameTheme = LabelFrame(frame, borderwidth=2, relief=GROOVE, + text=' Highlighting Theme ') #frameCustom - self.textHighlightSample=Text(frameCustom,relief=SOLID,borderwidth=1, - font=('courier',12,''),cursor='hand2',width=21,height=11, - takefocus=FALSE,highlightthickness=0,wrap=NONE) + self.textHighlightSample=Text( + frameCustom, relief=SOLID, borderwidth=1, + font=('courier', 12, ''), cursor='hand2', width=21, height=11, + takefocus=FALSE, highlightthickness=0, wrap=NONE) text=self.textHighlightSample - text.bind('',lambda e: 'break') - text.bind('',lambda e: 'break') - textAndTags=(('#you can click here','comment'),('\n','normal'), - ('#to choose items','comment'),('\n','normal'),('def','keyword'), - (' ','normal'),('func','definition'),('(param):','normal'), - ('\n ','normal'),('"""string"""','string'),('\n var0 = ','normal'), - ("'string'",'string'),('\n var1 = ','normal'),("'selected'",'hilite'), - ('\n var2 = ','normal'),("'found'",'hit'), - ('\n var3 = ','normal'),('list', 'builtin'), ('(','normal'), - ('None', 'keyword'),(')\n\n','normal'), - (' error ','error'),(' ','normal'),('cursor |','cursor'), - ('\n ','normal'),('shell','console'),(' ','normal'),('stdout','stdout'), - (' ','normal'),('stderr','stderr'),('\n','normal')) + text.bind('', lambda e: 'break') + text.bind('', lambda e: 'break') + textAndTags=( + ('#you can click here', 'comment'), ('\n', 'normal'), + ('#to choose items', 'comment'), ('\n', 'normal'), + ('def', 'keyword'), (' ', 'normal'), + ('func', 'definition'), ('(param):\n ', 'normal'), + ('"""string"""', 'string'), ('\n var0 = ', 'normal'), + ("'string'", 'string'), ('\n var1 = ', 'normal'), + ("'selected'", 'hilite'), ('\n var2 = ', 'normal'), + ("'found'", 'hit'), ('\n var3 = ', 'normal'), + ('list', 'builtin'), ('(', 'normal'), + ('None', 'keyword'), (')\n', 'normal'), + (' breakpoint("line")', 'break'), ('\n\n', 'normal'), + (' error ', 'error'), (' ', 'normal'), + ('cursor |', 'cursor'), ('\n ', 'normal'), + ('shell', 'console'), (' ', 'normal'), + ('stdout', 'stdout'), (' ', 'normal'), + ('stderr', 'stderr'), ('\n', 'normal')) for txTa in textAndTags: - text.insert(END,txTa[0],txTa[1]) + text.insert(END, txTa[0], txTa[1]) for element in self.themeElements: - text.tag_bind(self.themeElements[element][0],'', - lambda event,elem=element: event.widget.winfo_toplevel() - .highlightTarget.set(elem)) + def tem(event, elem=element): + event.widget.winfo_toplevel().highlightTarget.set(elem) + text.tag_bind( + self.themeElements[element][0], '', tem) text.config(state=DISABLED) - self.frameColourSet=Frame(frameCustom,relief=SOLID,borderwidth=1) - frameFgBg=Frame(frameCustom) - buttonSetColour=Button(self.frameColourSet,text='Choose Colour for :', - command=self.GetColour,highlightthickness=0) - self.optMenuHighlightTarget=DynOptionMenu(self.frameColourSet, - self.highlightTarget,None,highlightthickness=0)#,command=self.SetHighlightTargetBinding - self.radioFg=Radiobutton(frameFgBg,variable=self.fgHilite, - value=1,text='Foreground',command=self.SetColourSampleBinding) - self.radioBg=Radiobutton(frameFgBg,variable=self.fgHilite, - value=0,text='Background',command=self.SetColourSampleBinding) + self.frameColourSet = Frame(frameCustom, relief=SOLID, borderwidth=1) + frameFgBg = Frame(frameCustom) + buttonSetColour = Button( + self.frameColourSet, text='Choose Colour for :', + command=self.GetColour, highlightthickness=0) + self.optMenuHighlightTarget = DynOptionMenu( + self.frameColourSet, self.highlightTarget, None, + highlightthickness=0) #, command=self.SetHighlightTargetBinding + self.radioFg = Radiobutton( + frameFgBg, variable=self.fgHilite, value=1, + text='Foreground', command=self.SetColourSampleBinding) + self.radioBg=Radiobutton( + frameFgBg, variable=self.fgHilite, value=0, + text='Background', command=self.SetColourSampleBinding) self.fgHilite.set(1) - buttonSaveCustomTheme=Button(frameCustom, - text='Save as New Custom Theme',command=self.SaveAsNewTheme) + buttonSaveCustomTheme = Button( + frameCustom, text='Save as New Custom Theme', + command=self.SaveAsNewTheme) #frameTheme - labelTypeTitle=Label(frameTheme,text='Select : ') - self.radioThemeBuiltin=Radiobutton(frameTheme,variable=self.themeIsBuiltin, - value=1,command=self.SetThemeType,text='a Built-in Theme') - self.radioThemeCustom=Radiobutton(frameTheme,variable=self.themeIsBuiltin, - value=0,command=self.SetThemeType,text='a Custom Theme') - self.optMenuThemeBuiltin=DynOptionMenu(frameTheme, - self.builtinTheme,None,command=None) - self.optMenuThemeCustom=DynOptionMenu(frameTheme, - self.customTheme,None,command=None) - self.buttonDeleteCustomTheme=Button(frameTheme,text='Delete Custom Theme', + labelTypeTitle = Label(frameTheme, text='Select : ') + self.radioThemeBuiltin = Radiobutton( + frameTheme, variable=self.themeIsBuiltin, value=1, + command=self.SetThemeType, text='a Built-in Theme') + self.radioThemeCustom = Radiobutton( + frameTheme, variable=self.themeIsBuiltin, value=0, + command=self.SetThemeType, text='a Custom Theme') + self.optMenuThemeBuiltin = DynOptionMenu( + frameTheme, self.builtinTheme, None, command=None) + self.optMenuThemeCustom=DynOptionMenu( + frameTheme, self.customTheme, None, command=None) + self.buttonDeleteCustomTheme=Button( + frameTheme, text='Delete Custom Theme', command=self.DeleteCustomTheme) + ##widget packing #body - frameCustom.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH) - frameTheme.pack(side=LEFT,padx=5,pady=5,fill=Y) + frameCustom.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH) + frameTheme.pack(side=LEFT, padx=5, pady=5, fill=Y) #frameCustom - self.frameColourSet.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=X) - frameFgBg.pack(side=TOP,padx=5,pady=0) - self.textHighlightSample.pack(side=TOP,padx=5,pady=5,expand=TRUE, - fill=BOTH) - buttonSetColour.pack(side=TOP,expand=TRUE,fill=X,padx=8,pady=4) - self.optMenuHighlightTarget.pack(side=TOP,expand=TRUE,fill=X,padx=8,pady=3) - self.radioFg.pack(side=LEFT,anchor=E) - self.radioBg.pack(side=RIGHT,anchor=W) - buttonSaveCustomTheme.pack(side=BOTTOM,fill=X,padx=5,pady=5) + self.frameColourSet.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=X) + frameFgBg.pack(side=TOP, padx=5, pady=0) + self.textHighlightSample.pack( + side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH) + buttonSetColour.pack(side=TOP, expand=TRUE, fill=X, padx=8, pady=4) + self.optMenuHighlightTarget.pack( + side=TOP, expand=TRUE, fill=X, padx=8, pady=3) + self.radioFg.pack(side=LEFT, anchor=E) + self.radioBg.pack(side=RIGHT, anchor=W) + buttonSaveCustomTheme.pack(side=BOTTOM, fill=X, padx=5, pady=5) #frameTheme - labelTypeTitle.pack(side=TOP,anchor=W,padx=5,pady=5) - self.radioThemeBuiltin.pack(side=TOP,anchor=W,padx=5) - self.radioThemeCustom.pack(side=TOP,anchor=W,padx=5,pady=2) - self.optMenuThemeBuiltin.pack(side=TOP,fill=X,padx=5,pady=5) - self.optMenuThemeCustom.pack(side=TOP,fill=X,anchor=W,padx=5,pady=5) - self.buttonDeleteCustomTheme.pack(side=TOP,fill=X,padx=5,pady=5) + labelTypeTitle.pack(side=TOP, anchor=W, padx=5, pady=5) + self.radioThemeBuiltin.pack(side=TOP, anchor=W, padx=5) + self.radioThemeCustom.pack(side=TOP, anchor=W, padx=5, pady=2) + self.optMenuThemeBuiltin.pack(side=TOP, fill=X, padx=5, pady=5) + self.optMenuThemeCustom.pack(side=TOP, fill=X, anchor=W, padx=5, pady=5) + self.buttonDeleteCustomTheme.pack(side=TOP, fill=X, padx=5, pady=5) return frame def CreatePageKeys(self): - #tkVars - self.bindingTarget=StringVar(self) - self.builtinKeys=StringVar(self) - self.customKeys=StringVar(self) - self.keysAreBuiltin=BooleanVar(self) - self.keyBinding=StringVar(self) + parent = self.parent + self.bindingTarget = StringVar(parent) + self.builtinKeys = StringVar(parent) + self.customKeys = StringVar(parent) + self.keysAreBuiltin = BooleanVar(parent) + self.keyBinding = StringVar(parent) + ##widget creation #body frame - frame=self.tabPages.pages['Keys'].frame + frame = self.tabPages.pages['Keys'].frame #body section frames - frameCustom=LabelFrame(frame,borderwidth=2,relief=GROOVE, - text=' Custom Key Bindings ') - frameKeySets=LabelFrame(frame,borderwidth=2,relief=GROOVE, - text=' Key Set ') + frameCustom = LabelFrame( + frame, borderwidth=2, relief=GROOVE, + text=' Custom Key Bindings ') + frameKeySets = LabelFrame( + frame, borderwidth=2, relief=GROOVE, text=' Key Set ') #frameCustom - frameTarget=Frame(frameCustom) - labelTargetTitle=Label(frameTarget,text='Action - Key(s)') - scrollTargetY=Scrollbar(frameTarget) - scrollTargetX=Scrollbar(frameTarget,orient=HORIZONTAL) - self.listBindings=Listbox(frameTarget,takefocus=FALSE, - exportselection=FALSE) - self.listBindings.bind('',self.KeyBindingSelected) + frameTarget = Frame(frameCustom) + labelTargetTitle = Label(frameTarget, text='Action - Key(s)') + scrollTargetY = Scrollbar(frameTarget) + scrollTargetX = Scrollbar(frameTarget, orient=HORIZONTAL) + self.listBindings = Listbox( + frameTarget, takefocus=FALSE, exportselection=FALSE) + self.listBindings.bind('', self.KeyBindingSelected) scrollTargetY.config(command=self.listBindings.yview) scrollTargetX.config(command=self.listBindings.xview) self.listBindings.config(yscrollcommand=scrollTargetY.set) self.listBindings.config(xscrollcommand=scrollTargetX.set) - self.buttonNewKeys=Button(frameCustom,text='Get New Keys for Selection', - command=self.GetNewKeys,state=DISABLED) + self.buttonNewKeys = Button( + frameCustom, text='Get New Keys for Selection', + command=self.GetNewKeys, state=DISABLED) #frameKeySets frames = [Frame(frameKeySets, padx=2, pady=2, borderwidth=0) for i in range(2)] - self.radioKeysBuiltin=Radiobutton(frames[0],variable=self.keysAreBuiltin, - value=1,command=self.SetKeysType,text='Use a Built-in Key Set') - self.radioKeysCustom=Radiobutton(frames[0],variable=self.keysAreBuiltin, - value=0,command=self.SetKeysType,text='Use a Custom Key Set') - self.optMenuKeysBuiltin=DynOptionMenu(frames[0], - self.builtinKeys,None,command=None) - self.optMenuKeysCustom=DynOptionMenu(frames[0], - self.customKeys,None,command=None) - self.buttonDeleteCustomKeys=Button(frames[1],text='Delete Custom Key Set', + self.radioKeysBuiltin = Radiobutton( + frames[0], variable=self.keysAreBuiltin, value=1, + command=self.SetKeysType, text='Use a Built-in Key Set') + self.radioKeysCustom = Radiobutton( + frames[0], variable=self.keysAreBuiltin, value=0, + command=self.SetKeysType, text='Use a Custom Key Set') + self.optMenuKeysBuiltin = DynOptionMenu( + frames[0], self.builtinKeys, None, command=None) + self.optMenuKeysCustom = DynOptionMenu( + frames[0], self.customKeys, None, command=None) + self.buttonDeleteCustomKeys = Button( + frames[1], text='Delete Custom Key Set', command=self.DeleteCustomKeys) - buttonSaveCustomKeys=Button(frames[1], - text='Save as New Custom Key Set',command=self.SaveAsNewKeySet) + buttonSaveCustomKeys = Button( + frames[1], text='Save as New Custom Key Set', + command=self.SaveAsNewKeySet) + ##widget packing #body - frameCustom.pack(side=BOTTOM,padx=5,pady=5,expand=TRUE,fill=BOTH) - frameKeySets.pack(side=BOTTOM,padx=5,pady=5,fill=BOTH) + frameCustom.pack(side=BOTTOM, padx=5, pady=5, expand=TRUE, fill=BOTH) + frameKeySets.pack(side=BOTTOM, padx=5, pady=5, fill=BOTH) #frameCustom - self.buttonNewKeys.pack(side=BOTTOM,fill=X,padx=5,pady=5) - frameTarget.pack(side=LEFT,padx=5,pady=5,expand=TRUE,fill=BOTH) + self.buttonNewKeys.pack(side=BOTTOM, fill=X, padx=5, pady=5) + frameTarget.pack(side=LEFT, padx=5, pady=5, expand=TRUE, fill=BOTH) #frame target - frameTarget.columnconfigure(0,weight=1) - frameTarget.rowconfigure(1,weight=1) - labelTargetTitle.grid(row=0,column=0,columnspan=2,sticky=W) - self.listBindings.grid(row=1,column=0,sticky=NSEW) - scrollTargetY.grid(row=1,column=1,sticky=NS) - scrollTargetX.grid(row=2,column=0,sticky=EW) + frameTarget.columnconfigure(0, weight=1) + frameTarget.rowconfigure(1, weight=1) + labelTargetTitle.grid(row=0, column=0, columnspan=2, sticky=W) + self.listBindings.grid(row=1, column=0, sticky=NSEW) + scrollTargetY.grid(row=1, column=1, sticky=NS) + scrollTargetX.grid(row=2, column=0, sticky=EW) #frameKeySets self.radioKeysBuiltin.grid(row=0, column=0, sticky=W+NS) self.radioKeysCustom.grid(row=1, column=0, sticky=W+NS) self.optMenuKeysBuiltin.grid(row=0, column=1, sticky=NSEW) self.optMenuKeysCustom.grid(row=1, column=1, sticky=NSEW) - self.buttonDeleteCustomKeys.pack(side=LEFT,fill=X,expand=True,padx=2) - buttonSaveCustomKeys.pack(side=LEFT,fill=X,expand=True,padx=2) + self.buttonDeleteCustomKeys.pack(side=LEFT, fill=X, expand=True, padx=2) + buttonSaveCustomKeys.pack(side=LEFT, fill=X, expand=True, padx=2) frames[0].pack(side=TOP, fill=BOTH, expand=True) frames[1].pack(side=TOP, fill=X, expand=True, pady=2) return frame def CreatePageGeneral(self): - #tkVars - self.winWidth=StringVar(self) - self.winHeight=StringVar(self) - self.paraWidth=StringVar(self) - self.startupEdit=IntVar(self) - self.autoSave=IntVar(self) - self.encoding=StringVar(self) - self.userHelpBrowser=BooleanVar(self) - self.helpBrowser=StringVar(self) + parent = self.parent + self.winWidth = StringVar(parent) + self.winHeight = StringVar(parent) + self.startupEdit = IntVar(parent) + self.autoSave = IntVar(parent) + self.encoding = StringVar(parent) + self.userHelpBrowser = BooleanVar(parent) + self.helpBrowser = StringVar(parent) + #widget creation #body - frame=self.tabPages.pages['General'].frame + frame = self.tabPages.pages['General'].frame #body section frames - frameRun=LabelFrame(frame,borderwidth=2,relief=GROOVE, - text=' Startup Preferences ') - frameSave=LabelFrame(frame,borderwidth=2,relief=GROOVE, - text=' Autosave Preferences ') - frameWinSize=Frame(frame,borderwidth=2,relief=GROOVE) - frameParaSize=Frame(frame,borderwidth=2,relief=GROOVE) - frameHelp=LabelFrame(frame,borderwidth=2,relief=GROOVE, - text=' Additional Help Sources ') + frameRun = LabelFrame(frame, borderwidth=2, relief=GROOVE, + text=' Startup Preferences ') + frameSave = LabelFrame(frame, borderwidth=2, relief=GROOVE, + text=' Autosave Preferences ') + frameWinSize = Frame(frame, borderwidth=2, relief=GROOVE) + frameHelp = LabelFrame(frame, borderwidth=2, relief=GROOVE, + text=' Additional Help Sources ') #frameRun - labelRunChoiceTitle=Label(frameRun,text='At Startup') - radioStartupEdit=Radiobutton(frameRun,variable=self.startupEdit, - value=1,command=self.SetKeysType,text="Open Edit Window") - radioStartupShell=Radiobutton(frameRun,variable=self.startupEdit, - value=0,command=self.SetKeysType,text='Open Shell Window') + labelRunChoiceTitle = Label(frameRun, text='At Startup') + radioStartupEdit = Radiobutton( + frameRun, variable=self.startupEdit, value=1, + command=self.SetKeysType, text="Open Edit Window") + radioStartupShell = Radiobutton( + frameRun, variable=self.startupEdit, value=0, + command=self.SetKeysType, text='Open Shell Window') #frameSave - labelRunSaveTitle=Label(frameSave,text='At Start of Run (F5) ') - radioSaveAsk=Radiobutton(frameSave,variable=self.autoSave, - value=0,command=self.SetKeysType,text="Prompt to Save") - radioSaveAuto=Radiobutton(frameSave,variable=self.autoSave, - value=1,command=self.SetKeysType,text='No Prompt') + labelRunSaveTitle = Label(frameSave, text='At Start of Run (F5) ') + radioSaveAsk = Radiobutton( + frameSave, variable=self.autoSave, value=0, + command=self.SetKeysType, text="Prompt to Save") + radioSaveAuto = Radiobutton( + frameSave, variable=self.autoSave, value=1, + command=self.SetKeysType, text='No Prompt') #frameWinSize - labelWinSizeTitle=Label(frameWinSize,text='Initial Window Size'+ - ' (in characters)') - labelWinWidthTitle=Label(frameWinSize,text='Width') - entryWinWidth=Entry(frameWinSize,textvariable=self.winWidth, - width=3) - labelWinHeightTitle=Label(frameWinSize,text='Height') - entryWinHeight=Entry(frameWinSize,textvariable=self.winHeight, - width=3) - #paragraphFormatWidth - labelParaWidthTitle=Label(frameParaSize,text='Paragraph reformat'+ - ' width (in characters)') - entryParaWidth=Entry(frameParaSize,textvariable=self.paraWidth, - width=3) + labelWinSizeTitle = Label( + frameWinSize, text='Initial Window Size (in characters)') + labelWinWidthTitle = Label(frameWinSize, text='Width') + entryWinWidth = Entry( + frameWinSize, textvariable=self.winWidth, width=3) + labelWinHeightTitle = Label(frameWinSize, text='Height') + entryWinHeight = Entry( + frameWinSize, textvariable=self.winHeight, width=3) #frameHelp - frameHelpList=Frame(frameHelp) - frameHelpListButtons=Frame(frameHelpList) - scrollHelpList=Scrollbar(frameHelpList) - self.listHelp=Listbox(frameHelpList,height=5,takefocus=FALSE, + frameHelpList = Frame(frameHelp) + frameHelpListButtons = Frame(frameHelpList) + scrollHelpList = Scrollbar(frameHelpList) + self.listHelp = Listbox( + frameHelpList, height=5, takefocus=FALSE, exportselection=FALSE) scrollHelpList.config(command=self.listHelp.yview) self.listHelp.config(yscrollcommand=scrollHelpList.set) - self.listHelp.bind('',self.HelpSourceSelected) - self.buttonHelpListEdit=Button(frameHelpListButtons,text='Edit', - state=DISABLED,width=8,command=self.HelpListItemEdit) - self.buttonHelpListAdd=Button(frameHelpListButtons,text='Add', - width=8,command=self.HelpListItemAdd) - self.buttonHelpListRemove=Button(frameHelpListButtons,text='Remove', - state=DISABLED,width=8,command=self.HelpListItemRemove) + self.listHelp.bind('', self.HelpSourceSelected) + self.buttonHelpListEdit = Button( + frameHelpListButtons, text='Edit', state=DISABLED, + width=8, command=self.HelpListItemEdit) + self.buttonHelpListAdd = Button( + frameHelpListButtons, text='Add', + width=8, command=self.HelpListItemAdd) + self.buttonHelpListRemove = Button( + frameHelpListButtons, text='Remove', state=DISABLED, + width=8, command=self.HelpListItemRemove) + #widget packing #body - frameRun.pack(side=TOP,padx=5,pady=5,fill=X) - frameSave.pack(side=TOP,padx=5,pady=5,fill=X) - frameWinSize.pack(side=TOP,padx=5,pady=5,fill=X) - frameParaSize.pack(side=TOP,padx=5,pady=5,fill=X) - frameHelp.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH) + frameRun.pack(side=TOP, padx=5, pady=5, fill=X) + frameSave.pack(side=TOP, padx=5, pady=5, fill=X) + frameWinSize.pack(side=TOP, padx=5, pady=5, fill=X) + frameHelp.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH) #frameRun - labelRunChoiceTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) - radioStartupShell.pack(side=RIGHT,anchor=W,padx=5,pady=5) - radioStartupEdit.pack(side=RIGHT,anchor=W,padx=5,pady=5) + labelRunChoiceTitle.pack(side=LEFT, anchor=W, padx=5, pady=5) + radioStartupShell.pack(side=RIGHT, anchor=W, padx=5, pady=5) + radioStartupEdit.pack(side=RIGHT, anchor=W, padx=5, pady=5) #frameSave - labelRunSaveTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) - radioSaveAuto.pack(side=RIGHT,anchor=W,padx=5,pady=5) - radioSaveAsk.pack(side=RIGHT,anchor=W,padx=5,pady=5) + labelRunSaveTitle.pack(side=LEFT, anchor=W, padx=5, pady=5) + radioSaveAuto.pack(side=RIGHT, anchor=W, padx=5, pady=5) + radioSaveAsk.pack(side=RIGHT, anchor=W, padx=5, pady=5) #frameWinSize - labelWinSizeTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) - entryWinHeight.pack(side=RIGHT,anchor=E,padx=10,pady=5) - labelWinHeightTitle.pack(side=RIGHT,anchor=E,pady=5) - entryWinWidth.pack(side=RIGHT,anchor=E,padx=10,pady=5) - labelWinWidthTitle.pack(side=RIGHT,anchor=E,pady=5) - #paragraphFormatWidth - labelParaWidthTitle.pack(side=LEFT,anchor=W,padx=5,pady=5) - entryParaWidth.pack(side=RIGHT,anchor=E,padx=10,pady=5) + labelWinSizeTitle.pack(side=LEFT, anchor=W, padx=5, pady=5) + entryWinHeight.pack(side=RIGHT, anchor=E, padx=10, pady=5) + labelWinHeightTitle.pack(side=RIGHT, anchor=E, pady=5) + entryWinWidth.pack(side=RIGHT, anchor=E, padx=10, pady=5) + labelWinWidthTitle.pack(side=RIGHT, anchor=E, pady=5) #frameHelp - frameHelpListButtons.pack(side=RIGHT,padx=5,pady=5,fill=Y) - frameHelpList.pack(side=TOP,padx=5,pady=5,expand=TRUE,fill=BOTH) - scrollHelpList.pack(side=RIGHT,anchor=W,fill=Y) - self.listHelp.pack(side=LEFT,anchor=E,expand=TRUE,fill=BOTH) - self.buttonHelpListEdit.pack(side=TOP,anchor=W,pady=5) - self.buttonHelpListAdd.pack(side=TOP,anchor=W) - self.buttonHelpListRemove.pack(side=TOP,anchor=W,pady=5) + frameHelpListButtons.pack(side=RIGHT, padx=5, pady=5, fill=Y) + frameHelpList.pack(side=TOP, padx=5, pady=5, expand=TRUE, fill=BOTH) + scrollHelpList.pack(side=RIGHT, anchor=W, fill=Y) + self.listHelp.pack(side=LEFT, anchor=E, expand=TRUE, fill=BOTH) + self.buttonHelpListEdit.pack(side=TOP, anchor=W, pady=5) + self.buttonHelpListAdd.pack(side=TOP, anchor=W) + self.buttonHelpListRemove.pack(side=TOP, anchor=W, pady=5) return frame def AttachVarCallbacks(self): - self.fontSize.trace_variable('w',self.VarChanged_fontSize) - self.fontName.trace_variable('w',self.VarChanged_fontName) - self.fontBold.trace_variable('w',self.VarChanged_fontBold) - self.spaceNum.trace_variable('w',self.VarChanged_spaceNum) - self.colour.trace_variable('w',self.VarChanged_colour) - self.builtinTheme.trace_variable('w',self.VarChanged_builtinTheme) - self.customTheme.trace_variable('w',self.VarChanged_customTheme) - self.themeIsBuiltin.trace_variable('w',self.VarChanged_themeIsBuiltin) - self.highlightTarget.trace_variable('w',self.VarChanged_highlightTarget) - self.keyBinding.trace_variable('w',self.VarChanged_keyBinding) - self.builtinKeys.trace_variable('w',self.VarChanged_builtinKeys) - self.customKeys.trace_variable('w',self.VarChanged_customKeys) - self.keysAreBuiltin.trace_variable('w',self.VarChanged_keysAreBuiltin) - self.winWidth.trace_variable('w',self.VarChanged_winWidth) - self.winHeight.trace_variable('w',self.VarChanged_winHeight) - self.paraWidth.trace_variable('w',self.VarChanged_paraWidth) - self.startupEdit.trace_variable('w',self.VarChanged_startupEdit) - self.autoSave.trace_variable('w',self.VarChanged_autoSave) - self.encoding.trace_variable('w',self.VarChanged_encoding) - - def VarChanged_fontSize(self,*params): - value=self.fontSize.get() - self.AddChangedItem('main','EditorWindow','font-size',value) - - def VarChanged_fontName(self,*params): - value=self.fontName.get() - self.AddChangedItem('main','EditorWindow','font',value) - - def VarChanged_fontBold(self,*params): - value=self.fontBold.get() - self.AddChangedItem('main','EditorWindow','font-bold',value) - - def VarChanged_spaceNum(self,*params): - value=self.spaceNum.get() - self.AddChangedItem('main','Indent','num-spaces',value) - - def VarChanged_colour(self,*params): + self.fontSize.trace_variable('w', self.VarChanged_font) + self.fontName.trace_variable('w', self.VarChanged_font) + self.fontBold.trace_variable('w', self.VarChanged_font) + self.spaceNum.trace_variable('w', self.VarChanged_spaceNum) + self.colour.trace_variable('w', self.VarChanged_colour) + self.builtinTheme.trace_variable('w', self.VarChanged_builtinTheme) + self.customTheme.trace_variable('w', self.VarChanged_customTheme) + self.themeIsBuiltin.trace_variable('w', self.VarChanged_themeIsBuiltin) + self.highlightTarget.trace_variable('w', self.VarChanged_highlightTarget) + self.keyBinding.trace_variable('w', self.VarChanged_keyBinding) + self.builtinKeys.trace_variable('w', self.VarChanged_builtinKeys) + self.customKeys.trace_variable('w', self.VarChanged_customKeys) + self.keysAreBuiltin.trace_variable('w', self.VarChanged_keysAreBuiltin) + self.winWidth.trace_variable('w', self.VarChanged_winWidth) + self.winHeight.trace_variable('w', self.VarChanged_winHeight) + self.startupEdit.trace_variable('w', self.VarChanged_startupEdit) + self.autoSave.trace_variable('w', self.VarChanged_autoSave) + self.encoding.trace_variable('w', self.VarChanged_encoding) + + def VarChanged_font(self, *params): + '''When one font attribute changes, save them all, as they are + not independent from each other. In particular, when we are + overriding the default font, we need to write out everything. + ''' + value = self.fontName.get() + self.AddChangedItem('main', 'EditorWindow', 'font', value) + value = self.fontSize.get() + self.AddChangedItem('main', 'EditorWindow', 'font-size', value) + value = self.fontBold.get() + self.AddChangedItem('main', 'EditorWindow', 'font-bold', value) + + def VarChanged_spaceNum(self, *params): + value = self.spaceNum.get() + self.AddChangedItem('main', 'Indent', 'num-spaces', value) + + def VarChanged_colour(self, *params): self.OnNewColourSet() - def VarChanged_builtinTheme(self,*params): - value=self.builtinTheme.get() - self.AddChangedItem('main','Theme','name',value) + def VarChanged_builtinTheme(self, *params): + value = self.builtinTheme.get() + if value == 'IDLE Dark': + tkMessageBox.showwarning( + title="The 'IDLE Dark' Text Color Theme", + message="IDLE Dark is new in October, 2015. Trying to " + "run earlier versions of IDLE with it selected " + "will disable colorizing, or worse.\n\n" + "If you might ever run an earlier release of IDLE, " + "then before exiting this version, " + "either switch to another theme or " + "hit the 'Save as New Custom Theme' button. " + "The latter requires a new name, such as " + "'Custom Dark', but the custom theme will work " + "with any IDLE release, and can be modified.", + parent=self) + self.AddChangedItem('main', 'Theme', 'name', value) self.PaintThemeSample() - def VarChanged_customTheme(self,*params): - value=self.customTheme.get() + def VarChanged_customTheme(self, *params): + value = self.customTheme.get() if value != '- no custom themes -': - self.AddChangedItem('main','Theme','name',value) + self.AddChangedItem('main', 'Theme', 'name', value) self.PaintThemeSample() - def VarChanged_themeIsBuiltin(self,*params): - value=self.themeIsBuiltin.get() - self.AddChangedItem('main','Theme','default',value) + def VarChanged_themeIsBuiltin(self, *params): + value = self.themeIsBuiltin.get() + self.AddChangedItem('main', 'Theme', 'default', value) if value: self.VarChanged_builtinTheme() else: self.VarChanged_customTheme() - def VarChanged_highlightTarget(self,*params): + def VarChanged_highlightTarget(self, *params): self.SetHighlightTarget() - def VarChanged_keyBinding(self,*params): - value=self.keyBinding.get() - keySet=self.customKeys.get() - event=self.listBindings.get(ANCHOR).split()[0] + def VarChanged_keyBinding(self, *params): + value = self.keyBinding.get() + keySet = self.customKeys.get() + event = self.listBindings.get(ANCHOR).split()[0] if idleConf.IsCoreBinding(event): #this is a core keybinding - self.AddChangedItem('keys',keySet,event,value) + self.AddChangedItem('keys', keySet, event, value) else: #this is an extension key binding - extName=idleConf.GetExtnNameForEvent(event) - extKeybindSection=extName+'_cfgBindings' - self.AddChangedItem('extensions',extKeybindSection,event,value) + extName = idleConf.GetExtnNameForEvent(event) + extKeybindSection = extName + '_cfgBindings' + self.AddChangedItem('extensions', extKeybindSection, event, value) - def VarChanged_builtinKeys(self,*params): - value=self.builtinKeys.get() - self.AddChangedItem('main','Keys','name',value) + def VarChanged_builtinKeys(self, *params): + value = self.builtinKeys.get() + self.AddChangedItem('main', 'Keys', 'name', value) self.LoadKeysList(value) - def VarChanged_customKeys(self,*params): - value=self.customKeys.get() + def VarChanged_customKeys(self, *params): + value = self.customKeys.get() if value != '- no custom keys -': - self.AddChangedItem('main','Keys','name',value) + self.AddChangedItem('main', 'Keys', 'name', value) self.LoadKeysList(value) - def VarChanged_keysAreBuiltin(self,*params): - value=self.keysAreBuiltin.get() - self.AddChangedItem('main','Keys','default',value) + def VarChanged_keysAreBuiltin(self, *params): + value = self.keysAreBuiltin.get() + self.AddChangedItem('main', 'Keys', 'default', value) if value: self.VarChanged_builtinKeys() else: self.VarChanged_customKeys() - def VarChanged_winWidth(self,*params): - value=self.winWidth.get() - self.AddChangedItem('main','EditorWindow','width',value) - - def VarChanged_winHeight(self,*params): - value=self.winHeight.get() - self.AddChangedItem('main','EditorWindow','height',value) + def VarChanged_winWidth(self, *params): + value = self.winWidth.get() + self.AddChangedItem('main', 'EditorWindow', 'width', value) - def VarChanged_paraWidth(self,*params): - value=self.paraWidth.get() - self.AddChangedItem('main','FormatParagraph','paragraph',value) + def VarChanged_winHeight(self, *params): + value = self.winHeight.get() + self.AddChangedItem('main', 'EditorWindow', 'height', value) - def VarChanged_startupEdit(self,*params): - value=self.startupEdit.get() - self.AddChangedItem('main','General','editor-on-startup',value) + def VarChanged_startupEdit(self, *params): + value = self.startupEdit.get() + self.AddChangedItem('main', 'General', 'editor-on-startup', value) - def VarChanged_autoSave(self,*params): - value=self.autoSave.get() - self.AddChangedItem('main','General','autosave',value) + def VarChanged_autoSave(self, *params): + value = self.autoSave.get() + self.AddChangedItem('main', 'General', 'autosave', value) - def VarChanged_encoding(self,*params): - value=self.encoding.get() - self.AddChangedItem('main','EditorWindow','encoding',value) + def VarChanged_encoding(self, *params): + value = self.encoding.get() + self.AddChangedItem('main', 'EditorWindow', 'encoding', value) def ResetChangedItems(self): #When any config item is changed in this dialog, an entry @@ -547,24 +593,25 @@ def ResetChangedItems(self): #dictionary. The key should be the config file section name and the #value a dictionary, whose key:value pairs are item=value pairs for #that config file section. - self.changedItems={'main':{},'highlight':{},'keys':{},'extensions':{}} + self.changedItems = {'main':{}, 'highlight':{}, 'keys':{}, + 'extensions':{}} - def AddChangedItem(self,type,section,item,value): - value=str(value) #make sure we use a string - if section not in self.changedItems[type]: - self.changedItems[type][section]={} - self.changedItems[type][section][item]=value + def AddChangedItem(self, typ, section, item, value): + value = str(value) #make sure we use a string + if section not in self.changedItems[typ]: + self.changedItems[typ][section] = {} + self.changedItems[typ][section][item] = value def GetDefaultItems(self): - dItems={'main':{},'highlight':{},'keys':{},'extensions':{}} + dItems={'main':{}, 'highlight':{}, 'keys':{}, 'extensions':{}} for configType in dItems: - sections=idleConf.GetSectionList('default',configType) + sections = idleConf.GetSectionList('default', configType) for section in sections: - dItems[configType][section]={} - options=idleConf.defaultCfg[configType].GetOptionList(section) + dItems[configType][section] = {} + options = idleConf.defaultCfg[configType].GetOptionList(section) for option in options: - dItems[configType][section][option]=( - idleConf.defaultCfg[configType].Get(section,option)) + dItems[configType][section][option] = ( + idleConf.defaultCfg[configType].Get(section, option)) return dItems def SetThemeType(self): @@ -590,26 +637,26 @@ def SetKeysType(self): self.buttonDeleteCustomKeys.config(state=NORMAL) def GetNewKeys(self): - listIndex=self.listBindings.index(ANCHOR) - binding=self.listBindings.get(listIndex) - bindName=binding.split()[0] #first part, up to first space + listIndex = self.listBindings.index(ANCHOR) + binding = self.listBindings.get(listIndex) + bindName = binding.split()[0] #first part, up to first space if self.keysAreBuiltin.get(): - currentKeySetName=self.builtinKeys.get() + currentKeySetName = self.builtinKeys.get() else: - currentKeySetName=self.customKeys.get() - currentBindings=idleConf.GetCurrentKeySet() + currentKeySetName = self.customKeys.get() + currentBindings = idleConf.GetCurrentKeySet() if currentKeySetName in self.changedItems['keys']: #unsaved changes - keySetChanges=self.changedItems['keys'][currentKeySetName] + keySetChanges = self.changedItems['keys'][currentKeySetName] for event in keySetChanges: - currentBindings[event]=keySetChanges[event].split() + currentBindings[event] = keySetChanges[event].split() currentKeySequences = list(currentBindings.values()) - newKeys=GetKeysDialog(self,'Get New Keys',bindName, + newKeys = GetKeysDialog(self, 'Get New Keys', bindName, currentKeySequences).result if newKeys: #new keys were specified if self.keysAreBuiltin.get(): #current key set is a built-in - message=('Your changes will be saved as a new Custom Key Set. '+ - 'Enter a name for your new Custom Key Set below.') - newKeySet=self.GetNewKeysName(message) + message = ('Your changes will be saved as a new Custom Key Set.' + ' Enter a name for your new Custom Key Set below.') + newKeySet = self.GetNewKeysName(message) if not newKeySet: #user cancelled custom key set creation self.listBindings.select_set(listIndex) self.listBindings.select_anchor(listIndex) @@ -617,7 +664,7 @@ def GetNewKeys(self): else: #create new custom key set based on previously active key set self.CreateNewKeySet(newKeySet) self.listBindings.delete(listIndex) - self.listBindings.insert(listIndex,bindName+' - '+newKeys) + self.listBindings.insert(listIndex, bindName+' - '+newKeys) self.listBindings.select_set(listIndex) self.listBindings.select_anchor(listIndex) self.keyBinding.set(newKeys) @@ -625,65 +672,65 @@ def GetNewKeys(self): self.listBindings.select_set(listIndex) self.listBindings.select_anchor(listIndex) - def GetNewKeysName(self,message): - usedNames=(idleConf.GetSectionList('user','keys')+ - idleConf.GetSectionList('default','keys')) - newKeySet=GetCfgSectionNameDialog(self,'New Custom Key Set', - message,usedNames).result + def GetNewKeysName(self, message): + usedNames = (idleConf.GetSectionList('user', 'keys') + + idleConf.GetSectionList('default', 'keys')) + newKeySet = GetCfgSectionNameDialog( + self, 'New Custom Key Set', message, usedNames).result return newKeySet def SaveAsNewKeySet(self): - newKeysName=self.GetNewKeysName('New Key Set Name:') + newKeysName = self.GetNewKeysName('New Key Set Name:') if newKeysName: self.CreateNewKeySet(newKeysName) - def KeyBindingSelected(self,event): + def KeyBindingSelected(self, event): self.buttonNewKeys.config(state=NORMAL) - def CreateNewKeySet(self,newKeySetName): + def CreateNewKeySet(self, newKeySetName): #creates new custom key set based on the previously active key set, #and makes the new key set active if self.keysAreBuiltin.get(): - prevKeySetName=self.builtinKeys.get() + prevKeySetName = self.builtinKeys.get() else: - prevKeySetName=self.customKeys.get() - prevKeys=idleConf.GetCoreKeys(prevKeySetName) - newKeys={} + prevKeySetName = self.customKeys.get() + prevKeys = idleConf.GetCoreKeys(prevKeySetName) + newKeys = {} for event in prevKeys: #add key set to changed items - eventName=event[2:-2] #trim off the angle brackets - binding=' '.join(prevKeys[event]) - newKeys[eventName]=binding + eventName = event[2:-2] #trim off the angle brackets + binding = ' '.join(prevKeys[event]) + newKeys[eventName] = binding #handle any unsaved changes to prev key set if prevKeySetName in self.changedItems['keys']: - keySetChanges=self.changedItems['keys'][prevKeySetName] + keySetChanges = self.changedItems['keys'][prevKeySetName] for event in keySetChanges: - newKeys[event]=keySetChanges[event] + newKeys[event] = keySetChanges[event] #save the new theme - self.SaveNewKeySet(newKeySetName,newKeys) + self.SaveNewKeySet(newKeySetName, newKeys) #change gui over to the new key set - customKeyList=idleConf.GetSectionList('user','keys') + customKeyList = idleConf.GetSectionList('user', 'keys') customKeyList.sort() - self.optMenuKeysCustom.SetMenu(customKeyList,newKeySetName) + self.optMenuKeysCustom.SetMenu(customKeyList, newKeySetName) self.keysAreBuiltin.set(0) self.SetKeysType() - def LoadKeysList(self,keySetName): - reselect=0 - newKeySet=0 + def LoadKeysList(self, keySetName): + reselect = 0 + newKeySet = 0 if self.listBindings.curselection(): - reselect=1 - listIndex=self.listBindings.index(ANCHOR) - keySet=idleConf.GetKeySet(keySetName) + reselect = 1 + listIndex = self.listBindings.index(ANCHOR) + keySet = idleConf.GetKeySet(keySetName) bindNames = list(keySet.keys()) bindNames.sort() - self.listBindings.delete(0,END) + self.listBindings.delete(0, END) for bindName in bindNames: - key=' '.join(keySet[bindName]) #make key(s) into a string - bindName=bindName[2:-2] #trim off the angle brackets + key = ' '.join(keySet[bindName]) #make key(s) into a string + bindName = bindName[2:-2] #trim off the angle brackets if keySetName in self.changedItems['keys']: #handle any unsaved changes to this key set if bindName in self.changedItems['keys'][keySetName]: - key=self.changedItems['keys'][keySetName][bindName] + key = self.changedItems['keys'][keySetName][bindName] self.listBindings.insert(END, bindName+' - '+key) if reselect: self.listBindings.see(listIndex) @@ -692,9 +739,9 @@ def LoadKeysList(self,keySetName): def DeleteCustomKeys(self): keySetName=self.customKeys.get() - if not tkMessageBox.askyesno('Delete Key Set','Are you sure you wish '+ - 'to delete the key set %r ?' % (keySetName), - parent=self): + delmsg = 'Are you sure you wish to delete the key set %r ?' + if not tkMessageBox.askyesno( + 'Delete Key Set', delmsg % keySetName, parent=self): return #remove key set from config idleConf.userCfg['keys'].remove_section(keySetName) @@ -703,25 +750,25 @@ def DeleteCustomKeys(self): #write changes idleConf.userCfg['keys'].Save() #reload user key set list - itemList=idleConf.GetSectionList('user','keys') + itemList = idleConf.GetSectionList('user', 'keys') itemList.sort() if not itemList: self.radioKeysCustom.config(state=DISABLED) - self.optMenuKeysCustom.SetMenu(itemList,'- no custom keys -') + self.optMenuKeysCustom.SetMenu(itemList, '- no custom keys -') else: - self.optMenuKeysCustom.SetMenu(itemList,itemList[0]) + self.optMenuKeysCustom.SetMenu(itemList, itemList[0]) #revert to default key set - self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys','default')) - self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys','name')) + self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys', 'default')) + self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys', 'name')) #user can't back out of these changes, they must be applied now self.Apply() self.SetKeysType() def DeleteCustomTheme(self): - themeName=self.customTheme.get() - if not tkMessageBox.askyesno('Delete Theme','Are you sure you wish '+ - 'to delete the theme %r ?' % (themeName,), - parent=self): + themeName = self.customTheme.get() + delmsg = 'Are you sure you wish to delete the theme %r ?' + if not tkMessageBox.askyesno( + 'Delete Theme', delmsg % themeName, parent=self): return #remove theme from config idleConf.userCfg['highlight'].remove_section(themeName) @@ -730,153 +777,149 @@ def DeleteCustomTheme(self): #write changes idleConf.userCfg['highlight'].Save() #reload user theme list - itemList=idleConf.GetSectionList('user','highlight') + itemList = idleConf.GetSectionList('user', 'highlight') itemList.sort() if not itemList: self.radioThemeCustom.config(state=DISABLED) - self.optMenuThemeCustom.SetMenu(itemList,'- no custom themes -') + self.optMenuThemeCustom.SetMenu(itemList, '- no custom themes -') else: - self.optMenuThemeCustom.SetMenu(itemList,itemList[0]) + self.optMenuThemeCustom.SetMenu(itemList, itemList[0]) #revert to default theme - self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme','default')) - self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme','name')) + self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme', 'default')) + self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme', 'name')) #user can't back out of these changes, they must be applied now self.Apply() self.SetThemeType() def GetColour(self): - target=self.highlightTarget.get() - prevColour=self.frameColourSet.cget('bg') - rgbTuplet, colourString = tkColorChooser.askcolor(parent=self, - title='Pick new colour for : '+target,initialcolor=prevColour) - if colourString and (colourString!=prevColour): + target = self.highlightTarget.get() + prevColour = self.frameColourSet.cget('bg') + rgbTuplet, colourString = tkColorChooser.askcolor( + parent=self, title='Pick new colour for : '+target, + initialcolor=prevColour) + if colourString and (colourString != prevColour): #user didn't cancel, and they chose a new colour - if self.themeIsBuiltin.get(): #current theme is a built-in - message=('Your changes will be saved as a new Custom Theme. '+ - 'Enter a name for your new Custom Theme below.') - newTheme=self.GetNewThemeName(message) - if not newTheme: #user cancelled custom theme creation + if self.themeIsBuiltin.get(): #current theme is a built-in + message = ('Your changes will be saved as a new Custom Theme. ' + 'Enter a name for your new Custom Theme below.') + newTheme = self.GetNewThemeName(message) + if not newTheme: #user cancelled custom theme creation return - else: #create new custom theme based on previously active theme + else: #create new custom theme based on previously active theme self.CreateNewTheme(newTheme) self.colour.set(colourString) - else: #current theme is user defined + else: #current theme is user defined self.colour.set(colourString) def OnNewColourSet(self): newColour=self.colour.get() - self.frameColourSet.config(bg=newColour)#set sample - if self.fgHilite.get(): plane='foreground' - else: plane='background' - sampleElement=self.themeElements[self.highlightTarget.get()][0] + self.frameColourSet.config(bg=newColour) #set sample + plane ='foreground' if self.fgHilite.get() else 'background' + sampleElement = self.themeElements[self.highlightTarget.get()][0] self.textHighlightSample.tag_config(sampleElement, **{plane:newColour}) - theme=self.customTheme.get() - themeElement=sampleElement+'-'+plane - self.AddChangedItem('highlight',theme,themeElement,newColour) - - def GetNewThemeName(self,message): - usedNames=(idleConf.GetSectionList('user','highlight')+ - idleConf.GetSectionList('default','highlight')) - newTheme=GetCfgSectionNameDialog(self,'New Custom Theme', - message,usedNames).result + theme = self.customTheme.get() + themeElement = sampleElement + '-' + plane + self.AddChangedItem('highlight', theme, themeElement, newColour) + + def GetNewThemeName(self, message): + usedNames = (idleConf.GetSectionList('user', 'highlight') + + idleConf.GetSectionList('default', 'highlight')) + newTheme = GetCfgSectionNameDialog( + self, 'New Custom Theme', message, usedNames).result return newTheme def SaveAsNewTheme(self): - newThemeName=self.GetNewThemeName('New Theme Name:') + newThemeName = self.GetNewThemeName('New Theme Name:') if newThemeName: self.CreateNewTheme(newThemeName) - def CreateNewTheme(self,newThemeName): + def CreateNewTheme(self, newThemeName): #creates new custom theme based on the previously active theme, #and makes the new theme active if self.themeIsBuiltin.get(): - themeType='default' - themeName=self.builtinTheme.get() + themeType = 'default' + themeName = self.builtinTheme.get() else: - themeType='user' - themeName=self.customTheme.get() - newTheme=idleConf.GetThemeDict(themeType,themeName) + themeType = 'user' + themeName = self.customTheme.get() + newTheme = idleConf.GetThemeDict(themeType, themeName) #apply any of the old theme's unsaved changes to the new theme if themeName in self.changedItems['highlight']: - themeChanges=self.changedItems['highlight'][themeName] + themeChanges = self.changedItems['highlight'][themeName] for element in themeChanges: - newTheme[element]=themeChanges[element] + newTheme[element] = themeChanges[element] #save the new theme - self.SaveNewTheme(newThemeName,newTheme) + self.SaveNewTheme(newThemeName, newTheme) #change gui over to the new theme - customThemeList=idleConf.GetSectionList('user','highlight') + customThemeList = idleConf.GetSectionList('user', 'highlight') customThemeList.sort() - self.optMenuThemeCustom.SetMenu(customThemeList,newThemeName) + self.optMenuThemeCustom.SetMenu(customThemeList, newThemeName) self.themeIsBuiltin.set(0) self.SetThemeType() - def OnListFontButtonRelease(self,event): + def OnListFontButtonRelease(self, event): font = self.listFontName.get(ANCHOR) self.fontName.set(font.lower()) self.SetFontSample() - def SetFontSample(self,event=None): - fontName=self.fontName.get() - if self.fontBold.get(): - fontWeight=tkFont.BOLD - else: - fontWeight=tkFont.NORMAL + def SetFontSample(self, event=None): + fontName = self.fontName.get() + fontWeight = tkFont.BOLD if self.fontBold.get() else tkFont.NORMAL newFont = (fontName, self.fontSize.get(), fontWeight) self.labelFontSample.config(font=newFont) self.textHighlightSample.configure(font=newFont) def SetHighlightTarget(self): - if self.highlightTarget.get()=='Cursor': #bg not possible + if self.highlightTarget.get() == 'Cursor': #bg not possible self.radioFg.config(state=DISABLED) self.radioBg.config(state=DISABLED) self.fgHilite.set(1) - else: #both fg and bg can be set + else: #both fg and bg can be set self.radioFg.config(state=NORMAL) self.radioBg.config(state=NORMAL) self.fgHilite.set(1) self.SetColourSample() - def SetColourSampleBinding(self,*args): + def SetColourSampleBinding(self, *args): self.SetColourSample() def SetColourSample(self): #set the colour smaple area - tag=self.themeElements[self.highlightTarget.get()][0] - if self.fgHilite.get(): plane='foreground' - else: plane='background' - colour=self.textHighlightSample.tag_cget(tag,plane) + tag = self.themeElements[self.highlightTarget.get()][0] + plane = 'foreground' if self.fgHilite.get() else 'background' + colour = self.textHighlightSample.tag_cget(tag, plane) self.frameColourSet.config(bg=colour) def PaintThemeSample(self): - if self.themeIsBuiltin.get(): #a default theme - theme=self.builtinTheme.get() - else: #a user theme - theme=self.customTheme.get() + if self.themeIsBuiltin.get(): #a default theme + theme = self.builtinTheme.get() + else: #a user theme + theme = self.customTheme.get() for elementTitle in self.themeElements: - element=self.themeElements[elementTitle][0] - colours=idleConf.GetHighlight(theme,element) - if element=='cursor': #cursor sample needs special painting - colours['background']=idleConf.GetHighlight(theme, - 'normal', fgBg='bg') + element = self.themeElements[elementTitle][0] + colours = idleConf.GetHighlight(theme, element) + if element == 'cursor': #cursor sample needs special painting + colours['background'] = idleConf.GetHighlight( + theme, 'normal', fgBg='bg') #handle any unsaved changes to this theme if theme in self.changedItems['highlight']: - themeDict=self.changedItems['highlight'][theme] - if element+'-foreground' in themeDict: - colours['foreground']=themeDict[element+'-foreground'] - if element+'-background' in themeDict: - colours['background']=themeDict[element+'-background'] + themeDict = self.changedItems['highlight'][theme] + if element + '-foreground' in themeDict: + colours['foreground'] = themeDict[element + '-foreground'] + if element + '-background' in themeDict: + colours['background'] = themeDict[element + '-background'] self.textHighlightSample.tag_config(element, **colours) self.SetColourSample() - def HelpSourceSelected(self,event): + def HelpSourceSelected(self, event): self.SetHelpListButtonStates() def SetHelpListButtonStates(self): - if self.listHelp.size()<1: #no entries in list + if self.listHelp.size() < 1: #no entries in list self.buttonHelpListEdit.config(state=DISABLED) self.buttonHelpListRemove.config(state=DISABLED) else: #there are some entries - if self.listHelp.curselection(): #there currently is a selection + if self.listHelp.curselection(): #there currently is a selection self.buttonHelpListEdit.config(state=NORMAL) self.buttonHelpListRemove.config(state=NORMAL) else: #there currently is not a selection @@ -884,28 +927,29 @@ def SetHelpListButtonStates(self): self.buttonHelpListRemove.config(state=DISABLED) def HelpListItemAdd(self): - helpSource=GetHelpSourceDialog(self,'New Help Source').result + helpSource = GetHelpSourceDialog(self, 'New Help Source').result if helpSource: - self.userHelpList.append( (helpSource[0],helpSource[1]) ) - self.listHelp.insert(END,helpSource[0]) + self.userHelpList.append((helpSource[0], helpSource[1])) + self.listHelp.insert(END, helpSource[0]) self.UpdateUserHelpChangedItems() self.SetHelpListButtonStates() def HelpListItemEdit(self): - itemIndex=self.listHelp.index(ANCHOR) - helpSource=self.userHelpList[itemIndex] - newHelpSource=GetHelpSourceDialog(self,'Edit Help Source', - menuItem=helpSource[0],filePath=helpSource[1]).result - if (not newHelpSource) or (newHelpSource==helpSource): + itemIndex = self.listHelp.index(ANCHOR) + helpSource = self.userHelpList[itemIndex] + newHelpSource = GetHelpSourceDialog( + self, 'Edit Help Source', menuItem=helpSource[0], + filePath=helpSource[1]).result + if (not newHelpSource) or (newHelpSource == helpSource): return #no changes - self.userHelpList[itemIndex]=newHelpSource + self.userHelpList[itemIndex] = newHelpSource self.listHelp.delete(itemIndex) - self.listHelp.insert(itemIndex,newHelpSource[0]) + self.listHelp.insert(itemIndex, newHelpSource[0]) self.UpdateUserHelpChangedItems() self.SetHelpListButtonStates() def HelpListItemRemove(self): - itemIndex=self.listHelp.index(ANCHOR) + itemIndex = self.listHelp.index(ANCHOR) del(self.userHelpList[itemIndex]) self.listHelp.delete(itemIndex) self.UpdateUserHelpChangedItems() @@ -914,128 +958,126 @@ def HelpListItemRemove(self): def UpdateUserHelpChangedItems(self): "Clear and rebuild the HelpFiles section in self.changedItems" self.changedItems['main']['HelpFiles'] = {} - for num in range(1,len(self.userHelpList)+1): - self.AddChangedItem('main','HelpFiles',str(num), + for num in range(1, len(self.userHelpList) + 1): + self.AddChangedItem( + 'main', 'HelpFiles', str(num), ';'.join(self.userHelpList[num-1][:2])) def LoadFontCfg(self): ##base editor font selection list - fonts=list(tkFont.families(self)) + fonts = list(tkFont.families(self)) fonts.sort() for font in fonts: - self.listFontName.insert(END,font) - configuredFont=idleConf.GetOption('main','EditorWindow','font', - default='courier') - lc_configuredFont = configuredFont.lower() - self.fontName.set(lc_configuredFont) + self.listFontName.insert(END, font) + configuredFont = idleConf.GetFont(self, 'main', 'EditorWindow') + fontName = configuredFont[0].lower() + fontSize = configuredFont[1] + fontBold = configuredFont[2]=='bold' + self.fontName.set(fontName) lc_fonts = [s.lower() for s in fonts] - if lc_configuredFont in lc_fonts: - currentFontIndex = lc_fonts.index(lc_configuredFont) + try: + currentFontIndex = lc_fonts.index(fontName) self.listFontName.see(currentFontIndex) self.listFontName.select_set(currentFontIndex) self.listFontName.select_anchor(currentFontIndex) + except ValueError: + pass ##font size dropdown - fontSize=idleConf.GetOption('main', 'EditorWindow', 'font-size', - type='int', default='10') - self.optMenuFontSize.SetMenu(('7','8','9','10','11','12','13','14', - '16','18','20','22'), fontSize ) + self.optMenuFontSize.SetMenu(('7', '8', '9', '10', '11', '12', '13', + '14', '16', '18', '20', '22'), fontSize ) ##fontWeight - self.fontBold.set(idleConf.GetOption('main','EditorWindow', - 'font-bold',default=0,type='bool')) + self.fontBold.set(fontBold) ##font sample self.SetFontSample() def LoadTabCfg(self): ##indent sizes - spaceNum=idleConf.GetOption('main','Indent','num-spaces', - default=4,type='int') + spaceNum = idleConf.GetOption( + 'main', 'Indent', 'num-spaces', default=4, type='int') self.spaceNum.set(spaceNum) def LoadThemeCfg(self): ##current theme type radiobutton - self.themeIsBuiltin.set(idleConf.GetOption('main','Theme','default', - type='bool',default=1)) + self.themeIsBuiltin.set(idleConf.GetOption( + 'main', 'Theme', 'default', type='bool', default=1)) ##currently set theme - currentOption=idleConf.CurrentTheme() + currentOption = idleConf.CurrentTheme() ##load available theme option menus if self.themeIsBuiltin.get(): #default theme selected - itemList=idleConf.GetSectionList('default','highlight') + itemList = idleConf.GetSectionList('default', 'highlight') itemList.sort() - self.optMenuThemeBuiltin.SetMenu(itemList,currentOption) - itemList=idleConf.GetSectionList('user','highlight') + self.optMenuThemeBuiltin.SetMenu(itemList, currentOption) + itemList = idleConf.GetSectionList('user', 'highlight') itemList.sort() if not itemList: self.radioThemeCustom.config(state=DISABLED) self.customTheme.set('- no custom themes -') else: - self.optMenuThemeCustom.SetMenu(itemList,itemList[0]) + self.optMenuThemeCustom.SetMenu(itemList, itemList[0]) else: #user theme selected - itemList=idleConf.GetSectionList('user','highlight') + itemList = idleConf.GetSectionList('user', 'highlight') itemList.sort() - self.optMenuThemeCustom.SetMenu(itemList,currentOption) - itemList=idleConf.GetSectionList('default','highlight') + self.optMenuThemeCustom.SetMenu(itemList, currentOption) + itemList = idleConf.GetSectionList('default', 'highlight') itemList.sort() - self.optMenuThemeBuiltin.SetMenu(itemList,itemList[0]) + self.optMenuThemeBuiltin.SetMenu(itemList, itemList[0]) self.SetThemeType() ##load theme element option menu themeNames = list(self.themeElements.keys()) themeNames.sort(key=lambda x: self.themeElements[x][1]) - self.optMenuHighlightTarget.SetMenu(themeNames,themeNames[0]) + self.optMenuHighlightTarget.SetMenu(themeNames, themeNames[0]) self.PaintThemeSample() self.SetHighlightTarget() def LoadKeyCfg(self): ##current keys type radiobutton - self.keysAreBuiltin.set(idleConf.GetOption('main','Keys','default', - type='bool',default=1)) + self.keysAreBuiltin.set(idleConf.GetOption( + 'main', 'Keys', 'default', type='bool', default=1)) ##currently set keys - currentOption=idleConf.CurrentKeys() + currentOption = idleConf.CurrentKeys() ##load available keyset option menus if self.keysAreBuiltin.get(): #default theme selected - itemList=idleConf.GetSectionList('default','keys') + itemList = idleConf.GetSectionList('default', 'keys') itemList.sort() - self.optMenuKeysBuiltin.SetMenu(itemList,currentOption) - itemList=idleConf.GetSectionList('user','keys') + self.optMenuKeysBuiltin.SetMenu(itemList, currentOption) + itemList = idleConf.GetSectionList('user', 'keys') itemList.sort() if not itemList: self.radioKeysCustom.config(state=DISABLED) self.customKeys.set('- no custom keys -') else: - self.optMenuKeysCustom.SetMenu(itemList,itemList[0]) + self.optMenuKeysCustom.SetMenu(itemList, itemList[0]) else: #user key set selected - itemList=idleConf.GetSectionList('user','keys') + itemList = idleConf.GetSectionList('user', 'keys') itemList.sort() - self.optMenuKeysCustom.SetMenu(itemList,currentOption) - itemList=idleConf.GetSectionList('default','keys') + self.optMenuKeysCustom.SetMenu(itemList, currentOption) + itemList = idleConf.GetSectionList('default', 'keys') itemList.sort() - self.optMenuKeysBuiltin.SetMenu(itemList,itemList[0]) + self.optMenuKeysBuiltin.SetMenu(itemList, itemList[0]) self.SetKeysType() ##load keyset element list - keySetName=idleConf.CurrentKeys() + keySetName = idleConf.CurrentKeys() self.LoadKeysList(keySetName) def LoadGeneralCfg(self): #startup state - self.startupEdit.set(idleConf.GetOption('main','General', - 'editor-on-startup',default=1,type='bool')) + self.startupEdit.set(idleConf.GetOption( + 'main', 'General', 'editor-on-startup', default=1, type='bool')) #autosave state - self.autoSave.set(idleConf.GetOption('main', 'General', 'autosave', - default=0, type='bool')) + self.autoSave.set(idleConf.GetOption( + 'main', 'General', 'autosave', default=0, type='bool')) #initial window size - self.winWidth.set(idleConf.GetOption('main','EditorWindow','width', - type='int')) - self.winHeight.set(idleConf.GetOption('main','EditorWindow','height', - type='int')) - #initial paragraph reformat size - self.paraWidth.set(idleConf.GetOption('main','FormatParagraph','paragraph', - type='int')) + self.winWidth.set(idleConf.GetOption( + 'main', 'EditorWindow', 'width', type='int')) + self.winHeight.set(idleConf.GetOption( + 'main', 'EditorWindow', 'height', type='int')) # default source encoding - self.encoding.set(idleConf.GetOption('main', 'EditorWindow', - 'encoding', default='none')) + self.encoding.set(idleConf.GetOption( + 'main', 'EditorWindow', 'encoding', default='none')) # additional help sources self.userHelpList = idleConf.GetAllExtraHelpSourcesList() for helpItem in self.userHelpList: - self.listHelp.insert(END,helpItem[0]) + self.listHelp.insert(END, helpItem[0]) self.SetHelpListButtonStates() def LoadConfigs(self): @@ -1052,8 +1094,9 @@ def LoadConfigs(self): self.LoadKeyCfg() ### general page self.LoadGeneralCfg() + # note: extension page handled separately - def SaveNewKeySet(self,keySetName,keySet): + def SaveNewKeySet(self, keySetName, keySet): """ save a newly created core key set. keySetName - string, the name of the new key set @@ -1062,10 +1105,10 @@ def SaveNewKeySet(self,keySetName,keySet): if not idleConf.userCfg['keys'].has_section(keySetName): idleConf.userCfg['keys'].add_section(keySetName) for event in keySet: - value=keySet[event] - idleConf.userCfg['keys'].SetOption(keySetName,event,value) + value = keySet[event] + idleConf.userCfg['keys'].SetOption(keySetName, event, value) - def SaveNewTheme(self,themeName,theme): + def SaveNewTheme(self, themeName, theme): """ save a newly created theme. themeName - string, the name of the new theme @@ -1074,16 +1117,16 @@ def SaveNewTheme(self,themeName,theme): if not idleConf.userCfg['highlight'].has_section(themeName): idleConf.userCfg['highlight'].add_section(themeName) for element in theme: - value=theme[element] - idleConf.userCfg['highlight'].SetOption(themeName,element,value) + value = theme[element] + idleConf.userCfg['highlight'].SetOption(themeName, element, value) - def SetUserValue(self,configType,section,item,value): - if idleConf.defaultCfg[configType].has_option(section,item): - if idleConf.defaultCfg[configType].Get(section,item)==value: + def SetUserValue(self, configType, section, item, value): + if idleConf.defaultCfg[configType].has_option(section, item): + if idleConf.defaultCfg[configType].Get(section, item) == value: #the setting equals a default setting, remove it from user cfg - return idleConf.userCfg[configType].RemoveOption(section,item) + return idleConf.userCfg[configType].RemoveOption(section, item) #if we got here set the option - return idleConf.userCfg[configType].SetOption(section,item,value) + return idleConf.userCfg[configType].SetOption(section, item, value) def SaveAllChangedConfigs(self): "Save configuration changes to the user config file." @@ -1097,7 +1140,7 @@ def SaveAllChangedConfigs(self): cfgTypeHasChanges = True for item in self.changedItems[configType][section]: value = self.changedItems[configType][section][item] - if self.SetUserValue(configType,section,item,value): + if self.SetUserValue(configType, section, item, value): cfgTypeHasChanges = True if cfgTypeHasChanges: idleConf.userCfg[configType].Save() @@ -1105,6 +1148,7 @@ def SaveAllChangedConfigs(self): # save these even if unchanged! idleConf.userCfg[configType].Save() self.ResetChangedItems() #clear the changed items dict + self.save_all_changed_extensions() # uses a different mechanism def DeactivateCurrentConfig(self): #Before a config is saved, some cleanup of current @@ -1136,12 +1180,247 @@ def Apply(self): self.ActivateConfigChanges() def Help(self): - pass + page = self.tabPages._current_page + view_text(self, title='Help for IDLE preferences', + text=help_common+help_pages.get(page, '')) + + def CreatePageExtensions(self): + """Part of the config dialog used for configuring IDLE extensions. + + This code is generic - it works for any and all IDLE extensions. + + IDLE extensions save their configuration options using idleConf. + This code reads the current configuration using idleConf, supplies a + GUI interface to change the configuration values, and saves the + changes using idleConf. + + Not all changes take effect immediately - some may require restarting IDLE. + This depends on each extension's implementation. + + All values are treated as text, and it is up to the user to supply + reasonable values. The only exception to this are the 'enable*' options, + which are boolean, and can be toggled with an True/False button. + """ + parent = self.parent + frame = self.tabPages.pages['Extensions'].frame + self.ext_defaultCfg = idleConf.defaultCfg['extensions'] + self.ext_userCfg = idleConf.userCfg['extensions'] + self.is_int = self.register(is_int) + self.load_extensions() + # create widgets - a listbox shows all available extensions, with the + # controls for the extension selected in the listbox to the right + self.extension_names = StringVar(self) + frame.rowconfigure(0, weight=1) + frame.columnconfigure(2, weight=1) + self.extension_list = Listbox(frame, listvariable=self.extension_names, + selectmode='browse') + self.extension_list.bind('<>', self.extension_selected) + scroll = Scrollbar(frame, command=self.extension_list.yview) + self.extension_list.yscrollcommand=scroll.set + self.details_frame = LabelFrame(frame, width=250, height=250) + self.extension_list.grid(column=0, row=0, sticky='nws') + scroll.grid(column=1, row=0, sticky='ns') + self.details_frame.grid(column=2, row=0, sticky='nsew', padx=[10, 0]) + frame.configure(padx=10, pady=10) + self.config_frame = {} + self.current_extension = None + + self.outerframe = self # TEMPORARY + self.tabbed_page_set = self.extension_list # TEMPORARY + + # create the frame holding controls for each extension + ext_names = '' + for ext_name in sorted(self.extensions): + self.create_extension_frame(ext_name) + ext_names = ext_names + '{' + ext_name + '} ' + self.extension_names.set(ext_names) + self.extension_list.selection_set(0) + self.extension_selected(None) + + def load_extensions(self): + "Fill self.extensions with data from the default and user configs." + self.extensions = {} + for ext_name in idleConf.GetExtensions(active_only=False): + self.extensions[ext_name] = [] + + for ext_name in self.extensions: + opt_list = sorted(self.ext_defaultCfg.GetOptionList(ext_name)) + + # bring 'enable' options to the beginning of the list + enables = [opt_name for opt_name in opt_list + if opt_name.startswith('enable')] + for opt_name in enables: + opt_list.remove(opt_name) + opt_list = enables + opt_list + + for opt_name in opt_list: + def_str = self.ext_defaultCfg.Get( + ext_name, opt_name, raw=True) + try: + def_obj = {'True':True, 'False':False}[def_str] + opt_type = 'bool' + except KeyError: + try: + def_obj = int(def_str) + opt_type = 'int' + except ValueError: + def_obj = def_str + opt_type = None + try: + value = self.ext_userCfg.Get( + ext_name, opt_name, type=opt_type, raw=True, + default=def_obj) + except ValueError: # Need this until .Get fixed + value = def_obj # bad values overwritten by entry + var = StringVar(self) + var.set(str(value)) + + self.extensions[ext_name].append({'name': opt_name, + 'type': opt_type, + 'default': def_str, + 'value': value, + 'var': var, + }) + + def extension_selected(self, event): + newsel = self.extension_list.curselection() + if newsel: + newsel = self.extension_list.get(newsel) + if newsel is None or newsel != self.current_extension: + if self.current_extension: + self.details_frame.config(text='') + self.config_frame[self.current_extension].grid_forget() + self.current_extension = None + if newsel: + self.details_frame.config(text=newsel) + self.config_frame[newsel].grid(column=0, row=0, sticky='nsew') + self.current_extension = newsel + + def create_extension_frame(self, ext_name): + """Create a frame holding the widgets to configure one extension""" + f = VerticalScrolledFrame(self.details_frame, height=250, width=250) + self.config_frame[ext_name] = f + entry_area = f.interior + # create an entry for each configuration option + for row, opt in enumerate(self.extensions[ext_name]): + # create a row with a label and entry/checkbutton + label = Label(entry_area, text=opt['name']) + label.grid(row=row, column=0, sticky=NW) + var = opt['var'] + if opt['type'] == 'bool': + Checkbutton(entry_area, textvariable=var, variable=var, + onvalue='True', offvalue='False', + indicatoron=FALSE, selectcolor='', width=8 + ).grid(row=row, column=1, sticky=W, padx=7) + elif opt['type'] == 'int': + Entry(entry_area, textvariable=var, validate='key', + validatecommand=(self.is_int, '%P') + ).grid(row=row, column=1, sticky=NSEW, padx=7) + + else: + Entry(entry_area, textvariable=var + ).grid(row=row, column=1, sticky=NSEW, padx=7) + return + + def set_extension_value(self, section, opt): + name = opt['name'] + default = opt['default'] + value = opt['var'].get().strip() or default + opt['var'].set(value) + # if self.defaultCfg.has_section(section): + # Currently, always true; if not, indent to return + if (value == default): + return self.ext_userCfg.RemoveOption(section, name) + # set the option + return self.ext_userCfg.SetOption(section, name, value) + + def save_all_changed_extensions(self): + """Save configuration changes to the user config file.""" + has_changes = False + for ext_name in self.extensions: + options = self.extensions[ext_name] + for opt in options: + if self.set_extension_value(ext_name, opt): + has_changes = True + if has_changes: + self.ext_userCfg.Save() + + +help_common = '''\ +When you click either the Apply or Ok buttons, settings in this +dialog that are different from IDLE's default are saved in +a .idlerc directory in your home directory. Except as noted, +hese changes apply to all versions of IDLE installed on this +machine. Some do not take affect until IDLE is restarted. +[Cancel] only cancels changes made since the last save. +''' +help_pages = { + 'Highlighting':''' +Highlighting: +The IDLE Dark color theme is new in Octover 2015. It can only +be used with older IDLE releases if it is saved as a custom +theme, with a different name. +''' +} + + +def is_int(s): + "Return 's is blank or represents an int'" + if not s: + return True + try: + int(s) + return True + except ValueError: + return False + + +class VerticalScrolledFrame(Frame): + """A pure Tkinter vertically scrollable frame. + + * Use the 'interior' attribute to place widgets inside the scrollable frame + * Construct and pack/place/grid normally + * This frame only allows vertical scrolling + """ + def __init__(self, parent, *args, **kw): + Frame.__init__(self, parent, *args, **kw) + + # create a canvas object and a vertical scrollbar for scrolling it + vscrollbar = Scrollbar(self, orient=VERTICAL) + vscrollbar.pack(fill=Y, side=RIGHT, expand=FALSE) + canvas = Canvas(self, bd=0, highlightthickness=0, + yscrollcommand=vscrollbar.set, width=240) + canvas.pack(side=LEFT, fill=BOTH, expand=TRUE) + vscrollbar.config(command=canvas.yview) + + # reset the view + canvas.xview_moveto(0) + canvas.yview_moveto(0) + + # create a frame inside the canvas which will be scrolled with it + self.interior = interior = Frame(canvas) + interior_id = canvas.create_window(0, 0, window=interior, anchor=NW) + + # track changes to the canvas and frame width and sync them, + # also updating the scrollbar + def _configure_interior(event): + # update the scrollbars to match the size of the inner frame + size = (interior.winfo_reqwidth(), interior.winfo_reqheight()) + canvas.config(scrollregion="0 0 %s %s" % size) + interior.bind('', _configure_interior) + + def _configure_canvas(event): + if interior.winfo_reqwidth() != canvas.winfo_width(): + # update the inner frame's width to fill the canvas + canvas.itemconfigure(interior_id, width=canvas.winfo_width()) + canvas.bind('', _configure_canvas) + + return + if __name__ == '__main__': - #test the dialog - root=Tk() - Button(root,text='Dialog', - command=lambda:ConfigDialog(root,'Settings')).pack() - root.instance_dict={} - root.mainloop() + import unittest + unittest.main('idlelib.idle_test.test_configdialog', + verbosity=2, exit=False) + from idlelib.idle_test.htest import run + run(ConfigDialog) diff --git a/Lib/idlelib/configHandler.py b/Lib/idlelib/configHandler.py index ea2010edeca2..83abad7847c1 100644 --- a/Lib/idlelib/configHandler.py +++ b/Lib/idlelib/configHandler.py @@ -15,13 +15,15 @@ the retrieval of config information. When a default is returned instead of a requested config value, a message is printed to stderr to aid in configuration problem notification and resolution. - """ +# TODOs added Oct 2014, tjr + import os import sys -from idlelib import macosxSupport -from configparser import ConfigParser, NoOptionError, NoSectionError +from configparser import ConfigParser +from tkinter import TkVersion +from tkinter.font import Font, nametofont class InvalidConfigType(Exception): pass class InvalidConfigSet(Exception): pass @@ -36,7 +38,7 @@ def __init__(self, cfgFile, cfgDefaults=None): """ cfgFile - string, fully specified configuration file name """ - self.file=cfgFile + self.file = cfgFile ConfigParser.__init__(self, defaults=cfgDefaults, strict=False) def Get(self, section, option, type=None, default=None, raw=False): @@ -44,28 +46,27 @@ def Get(self, section, option, type=None, default=None, raw=False): Get an option value for given section/option or return default. If type is specified, return as type. """ + # TODO Use default as fallback, at least if not None + # Should also print Warning(file, section, option). + # Currently may raise ValueError if not self.has_option(section, option): return default - if type=='bool': + if type == 'bool': return self.getboolean(section, option) - elif type=='int': + elif type == 'int': return self.getint(section, option) else: return self.get(section, option, raw=raw) - def GetOptionList(self,section): - """ - Get an option list for given section - """ + def GetOptionList(self, section): + "Return a list of options for given section, else []." if self.has_section(section): return self.options(section) else: #return a default value return [] def Load(self): - """ - Load the configuration file from disk - """ + "Load the configuration file from disk." self.read(self.file) class IdleUserConfParser(IdleConfParser): @@ -73,61 +74,50 @@ class IdleUserConfParser(IdleConfParser): IdleConfigParser specialised for user configuration handling. """ - def AddSection(self,section): - """ - if section doesn't exist, add it - """ + def AddSection(self, section): + "If section doesn't exist, add it." if not self.has_section(section): self.add_section(section) def RemoveEmptySections(self): - """ - remove any sections that have no options - """ + "Remove any sections that have no options." for section in self.sections(): if not self.GetOptionList(section): self.remove_section(section) def IsEmpty(self): - """ - Remove empty sections and then return 1 if parser has no sections - left, else return 0. - """ + "Return True if no sections after removing empty sections." self.RemoveEmptySections() - if self.sections(): - return 0 - else: - return 1 + return not self.sections() - def RemoveOption(self,section,option): - """ - If section/option exists, remove it. - Returns 1 if option was removed, 0 otherwise. + def RemoveOption(self, section, option): + """Return True if option is removed from section, else False. + + False if either section does not exist or did not have option. """ if self.has_section(section): - return self.remove_option(section,option) + return self.remove_option(section, option) + return False - def SetOption(self,section,option,value): - """ - Sets option to value, adding section if required. - Returns 1 if option was added or changed, otherwise 0. + def SetOption(self, section, option, value): + """Return True if option is added or changed to value, else False. + + Add section if required. False means option already had value. """ - if self.has_option(section,option): - if self.get(section,option)==value: - return 0 + if self.has_option(section, option): + if self.get(section, option) == value: + return False else: - self.set(section,option,value) - return 1 + self.set(section, option, value) + return True else: if not self.has_section(section): self.add_section(section) - self.set(section,option,value) - return 1 + self.set(section, option, value) + return True def RemoveFile(self): - """ - Removes the user config file from disk if it exists. - """ + "Remove user config file self.file from disk if it exists." if os.path.exists(self.file): os.remove(self.file) @@ -151,62 +141,59 @@ def Save(self): self.RemoveFile() class IdleConf: - """ - holds config parsers for all idle config files: - default config files - (idle install dir)/config-main.def - (idle install dir)/config-extensions.def - (idle install dir)/config-highlight.def - (idle install dir)/config-keys.def - user config files - (user home dir)/.idlerc/config-main.cfg - (user home dir)/.idlerc/config-extensions.cfg - (user home dir)/.idlerc/config-highlight.cfg - (user home dir)/.idlerc/config-keys.cfg + """Hold config parsers for all idle config files in singleton instance. + + Default config files, self.defaultCfg -- + for config_type in self.config_types: + (idle install dir)/config-{config-type}.def + + User config files, self.userCfg -- + for config_type in self.config_types: + (user home dir)/.idlerc/config-{config-type}.cfg """ def __init__(self): - self.defaultCfg={} - self.userCfg={} - self.cfg={} + self.config_types = ('main', 'extensions', 'highlight', 'keys') + self.defaultCfg = {} + self.userCfg = {} + self.cfg = {} # TODO use to select userCfg vs defaultCfg self.CreateConfigHandlers() self.LoadCfgFiles() - #self.LoadCfg() + def CreateConfigHandlers(self): - """ - set up a dictionary of config parsers for default and user - configurations respectively - """ + "Populate default and user config parser dictionaries." #build idle install path if __name__ != '__main__': # we were imported idleDir=os.path.dirname(__file__) else: # we were exec'ed (for testing only) idleDir=os.path.abspath(sys.path[0]) userDir=self.GetUserCfgDir() - configTypes=('main','extensions','highlight','keys') - defCfgFiles={} - usrCfgFiles={} - for cfgType in configTypes: #build config file names - defCfgFiles[cfgType]=os.path.join(idleDir,'config-'+cfgType+'.def') - usrCfgFiles[cfgType]=os.path.join(userDir,'config-'+cfgType+'.cfg') - for cfgType in configTypes: #create config parsers - self.defaultCfg[cfgType]=IdleConfParser(defCfgFiles[cfgType]) - self.userCfg[cfgType]=IdleUserConfParser(usrCfgFiles[cfgType]) + + defCfgFiles = {} + usrCfgFiles = {} + # TODO eliminate these temporaries by combining loops + for cfgType in self.config_types: #build config file names + defCfgFiles[cfgType] = os.path.join( + idleDir, 'config-' + cfgType + '.def') + usrCfgFiles[cfgType] = os.path.join( + userDir, 'config-' + cfgType + '.cfg') + for cfgType in self.config_types: #create config parsers + self.defaultCfg[cfgType] = IdleConfParser(defCfgFiles[cfgType]) + self.userCfg[cfgType] = IdleUserConfParser(usrCfgFiles[cfgType]) def GetUserCfgDir(self): - """ - Creates (if required) and returns a filesystem directory for storing - user config files. + """Return a filesystem directory for storing user config files. + Creates it if required. """ cfgDir = '.idlerc' userDir = os.path.expanduser('~') if userDir != '~': # expanduser() found user home dir if not os.path.exists(userDir): - warn = ('\n Warning: os.path.expanduser("~") points to\n '+ - userDir+',\n but the path does not exist.\n') + warn = ('\n Warning: os.path.expanduser("~") points to\n ' + + userDir + ',\n but the path does not exist.') try: - sys.stderr.write(warn) + print(warn, file=sys.stderr) except OSError: pass userDir = '~' @@ -218,45 +205,44 @@ def GetUserCfgDir(self): try: os.mkdir(userDir) except OSError: - warn = ('\n Warning: unable to create user config directory\n'+ - userDir+'\n Check path and permissions.\n Exiting!\n\n') - sys.stderr.write(warn) + warn = ('\n Warning: unable to create user config directory\n' + + userDir + '\n Check path and permissions.\n Exiting!\n') + print(warn, file=sys.stderr) raise SystemExit + # TODO continue without userDIr instead of exit return userDir def GetOption(self, configType, section, option, default=None, type=None, warn_on_default=True, raw=False): - """ - Get an option value for given config type and given general - configuration section/option or return a default. If type is specified, - return as type. Firstly the user configuration is checked, with a - fallback to the default configuration, and a final 'catch all' - fallback to a useable passed-in default if the option isn't present in - either the user or the default configuration. - configType must be one of ('main','extensions','highlight','keys') - If a default is returned, and warn_on_default is True, a warning is - printed to stderr. + """Return a value for configType section option, or default. + + If type is not None, return a value of that type. Also pass raw + to the config parser. First try to return a valid value + (including type) from a user configuration. If that fails, try + the default configuration. If that fails, return default, with a + default of None. + Warn if either user or default configurations have an invalid value. + Warn if default is returned and warn_on_default is True. """ try: - if self.userCfg[configType].has_option(section,option): + if self.userCfg[configType].has_option(section, option): return self.userCfg[configType].Get(section, option, type=type, raw=raw) except ValueError: warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n' ' invalid %r value for configuration option %r\n' - ' from section %r: %r\n' % + ' from section %r: %r' % (type, option, section, - self.userCfg[configType].Get(section, option, - raw=raw))) + self.userCfg[configType].Get(section, option, raw=raw))) try: - sys.stderr.write(warning) + print(warning, file=sys.stderr) except OSError: pass try: if self.defaultCfg[configType].has_option(section,option): - return self.defaultCfg[configType].Get(section, option, - type=type, raw=raw) + return self.defaultCfg[configType].Get( + section, option, type=type, raw=raw) except ValueError: pass #returning default, print warning @@ -264,31 +250,28 @@ def GetOption(self, configType, section, option, default=None, type=None, warning = ('\n Warning: configHandler.py - IdleConf.GetOption -\n' ' problem retrieving configuration option %r\n' ' from section %r.\n' - ' returning default value: %r\n' % + ' returning default value: %r' % (option, section, default)) try: - sys.stderr.write(warning) + print(warning, file=sys.stderr) except OSError: pass return default def SetOption(self, configType, section, option, value): - """In user's config file, set section's option to value. - - """ + """Set section option to value in user config file.""" self.userCfg[configType].SetOption(section, option, value) def GetSectionList(self, configSet, configType): - """ - Get a list of sections from either the user or default config for - the given config type. + """Return sections for configSet configType configuration. + configSet must be either 'user' or 'default' - configType must be one of ('main','extensions','highlight','keys') + configType must be in self.config_types. """ - if not (configType in ('main','extensions','highlight','keys')): + if not (configType in self.config_types): raise InvalidConfigType('Invalid configType specified') if configSet == 'user': - cfgParser=self.userCfg[configType] + cfgParser = self.userCfg[configType] elif configSet == 'default': cfgParser=self.defaultCfg[configType] else: @@ -296,25 +279,27 @@ def GetSectionList(self, configSet, configType): return cfgParser.sections() def GetHighlight(self, theme, element, fgBg=None): - """ - return individual highlighting theme elements. - fgBg - string ('fg'or'bg') or None, if None return a dictionary - containing fg and bg colours (appropriate for passing to Tkinter in, - e.g., a tag_config call), otherwise fg or bg colour only as specified. + """Return individual theme element highlight color(s). + + fgBg - string ('fg' or 'bg') or None. + If None, return a dictionary containing fg and bg colors with + keys 'foreground' and 'background'. Otherwise, only return + fg or bg color, as specified. Colors are intended to be + appropriate for passing to Tkinter in, e.g., a tag_config call). """ if self.defaultCfg['highlight'].has_section(theme): - themeDict=self.GetThemeDict('default',theme) + themeDict = self.GetThemeDict('default', theme) else: - themeDict=self.GetThemeDict('user',theme) - fore=themeDict[element+'-foreground'] - if element=='cursor': #there is no config value for cursor bg - back=themeDict['normal-background'] + themeDict = self.GetThemeDict('user', theme) + fore = themeDict[element + '-foreground'] + if element == 'cursor': # There is no config value for cursor bg + back = themeDict['normal-background'] else: - back=themeDict[element+'-background'] - highlight={"foreground": fore,"background": back} - if not fgBg: #return dict of both colours + back = themeDict[element + '-background'] + highlight = {"foreground": fore, "background": back} + if not fgBg: # Return dict of both colors return highlight - else: #return specified colour only + else: # Return specified color only if fgBg == 'fg': return highlight["foreground"] if fgBg == 'bg': @@ -322,26 +307,26 @@ def GetHighlight(self, theme, element, fgBg=None): else: raise InvalidFgBg('Invalid fgBg specified') - def GetThemeDict(self,type,themeName): - """ + def GetThemeDict(self, type, themeName): + """Return {option:value} dict for elements in themeName. + type - string, 'default' or 'user' theme type themeName - string, theme name - Returns a dictionary which holds {option:value} for each element - in the specified theme. Values are loaded over a set of ultimate last - fallback defaults to guarantee that all theme elements are present in - a newly created theme. + Values are loaded over ultimate fallback defaults to guarantee + that all theme elements are present in a newly created theme. """ if type == 'user': - cfgParser=self.userCfg['highlight'] + cfgParser = self.userCfg['highlight'] elif type == 'default': - cfgParser=self.defaultCfg['highlight'] + cfgParser = self.defaultCfg['highlight'] else: raise InvalidTheme('Invalid theme type specified') - #foreground and background values are provded for each theme element - #(apart from cursor) even though all these values are not yet used - #by idle, to allow for their use in the future. Default values are - #generally black and white. - theme={ 'normal-foreground':'#000000', + # Provide foreground and background colors for each theme + # element (other than cursor) even though some values are not + # yet used by idle, to allow for their use in the future. + # Default values are generally black and white. + # TODO copy theme from a class attribute. + theme ={'normal-foreground':'#000000', 'normal-background':'#ffffff', 'keyword-foreground':'#000000', 'keyword-background':'#ffffff', @@ -371,52 +356,50 @@ def GetThemeDict(self,type,themeName): 'console-foreground':'#000000', 'console-background':'#ffffff' } for element in theme: - if not cfgParser.has_option(themeName,element): - #we are going to return a default, print warning - warning=('\n Warning: configHandler.py - IdleConf.GetThemeDict' + if not cfgParser.has_option(themeName, element): + # Print warning that will return a default color + warning = ('\n Warning: configHandler.IdleConf.GetThemeDict' ' -\n problem retrieving theme element %r' '\n from theme %r.\n' - ' returning default value: %r\n' % + ' returning default color: %r' % (element, themeName, theme[element])) try: - sys.stderr.write(warning) + print(warning, file=sys.stderr) except OSError: pass - colour=cfgParser.Get(themeName,element,default=theme[element]) - theme[element]=colour + theme[element] = cfgParser.Get( + themeName, element, default=theme[element]) return theme def CurrentTheme(self): - """ - Returns the name of the currently active theme - """ - return self.GetOption('main','Theme','name',default='') + "Return the name of the currently active theme." + return self.GetOption('main', 'Theme', 'name', default='') def CurrentKeys(self): - """ - Returns the name of the currently active key set - """ - return self.GetOption('main','Keys','name',default='') + "Return the name of the currently active key set." + return self.GetOption('main', 'Keys', 'name', default='') def GetExtensions(self, active_only=True, editor_only=False, shell_only=False): + """Return extensions in default and user config-extensions files. + + If active_only True, only return active (enabled) extensions + and optionally only editor or shell extensions. + If active_only False, return all extensions. """ - Gets a list of all idle extensions declared in the config files. - active_only - boolean, if true only return active (enabled) extensions - """ - extns=self.RemoveKeyBindNames( - self.GetSectionList('default','extensions')) - userExtns=self.RemoveKeyBindNames( - self.GetSectionList('user','extensions')) + extns = self.RemoveKeyBindNames( + self.GetSectionList('default', 'extensions')) + userExtns = self.RemoveKeyBindNames( + self.GetSectionList('user', 'extensions')) for extn in userExtns: if extn not in extns: #user has added own extension extns.append(extn) if active_only: - activeExtns=[] + activeExtns = [] for extn in extns: if self.GetOption('extensions', extn, 'enable', default=True, type='bool'): #the extension is enabled - if editor_only or shell_only: + if editor_only or shell_only: # TODO if both, contradictory if editor_only: option = "enable_editor" else: @@ -431,106 +414,110 @@ def GetExtensions(self, active_only=True, editor_only=False, shell_only=False): else: return extns - def RemoveKeyBindNames(self,extnNameList): - #get rid of keybinding section names - names=extnNameList - kbNameIndicies=[] + def RemoveKeyBindNames(self, extnNameList): + "Return extnNameList with keybinding section names removed." + # TODO Easier to return filtered copy with list comp + names = extnNameList + kbNameIndicies = [] for name in names: if name.endswith(('_bindings', '_cfgBindings')): kbNameIndicies.append(names.index(name)) - kbNameIndicies.sort() - kbNameIndicies.reverse() + kbNameIndicies.sort(reverse=True) for index in kbNameIndicies: #delete each keybinding section name del(names[index]) return names - def GetExtnNameForEvent(self,virtualEvent): - """ - Returns the name of the extension that virtualEvent is bound in, or - None if not bound in any extension. - virtualEvent - string, name of the virtual event to test for, without - the enclosing '<< >>' + def GetExtnNameForEvent(self, virtualEvent): + """Return the name of the extension binding virtualEvent, or None. + + virtualEvent - string, name of the virtual event to test for, + without the enclosing '<< >>' """ - extName=None - vEvent='<<'+virtualEvent+'>>' + extName = None + vEvent = '<<' + virtualEvent + '>>' for extn in self.GetExtensions(active_only=0): for event in self.GetExtensionKeys(extn): if event == vEvent: - extName=extn + extName = extn # TODO return here? return extName - def GetExtensionKeys(self,extensionName): - """ - returns a dictionary of the configurable keybindings for a particular - extension,as they exist in the dictionary returned by GetCurrentKeySet; - that is, where previously used bindings are disabled. + def GetExtensionKeys(self, extensionName): + """Return dict: {configurable extensionName event : active keybinding}. + + Events come from default config extension_cfgBindings section. + Keybindings come from GetCurrentKeySet() active key dict, + where previously used bindings are disabled. """ - keysName=extensionName+'_cfgBindings' - activeKeys=self.GetCurrentKeySet() - extKeys={} + keysName = extensionName + '_cfgBindings' + activeKeys = self.GetCurrentKeySet() + extKeys = {} if self.defaultCfg['extensions'].has_section(keysName): - eventNames=self.defaultCfg['extensions'].GetOptionList(keysName) + eventNames = self.defaultCfg['extensions'].GetOptionList(keysName) for eventName in eventNames: - event='<<'+eventName+'>>' - binding=activeKeys[event] - extKeys[event]=binding + event = '<<' + eventName + '>>' + binding = activeKeys[event] + extKeys[event] = binding return extKeys def __GetRawExtensionKeys(self,extensionName): + """Return dict {configurable extensionName event : keybinding list}. + + Events come from default config extension_cfgBindings section. + Keybindings list come from the splitting of GetOption, which + tries user config before default config. """ - returns a dictionary of the configurable keybindings for a particular - extension, as defined in the configuration files, or an empty dictionary - if no bindings are found - """ - keysName=extensionName+'_cfgBindings' - extKeys={} + keysName = extensionName+'_cfgBindings' + extKeys = {} if self.defaultCfg['extensions'].has_section(keysName): - eventNames=self.defaultCfg['extensions'].GetOptionList(keysName) + eventNames = self.defaultCfg['extensions'].GetOptionList(keysName) for eventName in eventNames: - binding=self.GetOption('extensions',keysName, - eventName,default='').split() - event='<<'+eventName+'>>' - extKeys[event]=binding + binding = self.GetOption( + 'extensions', keysName, eventName, default='').split() + event = '<<' + eventName + '>>' + extKeys[event] = binding return extKeys - def GetExtensionBindings(self,extensionName): - """ - Returns a dictionary of all the event bindings for a particular - extension. The configurable keybindings are returned as they exist in - the dictionary returned by GetCurrentKeySet; that is, where re-used - keybindings are disabled. + def GetExtensionBindings(self, extensionName): + """Return dict {extensionName event : active or defined keybinding}. + + Augment self.GetExtensionKeys(extensionName) with mapping of non- + configurable events (from default config) to GetOption splits, + as in self.__GetRawExtensionKeys. """ - bindsName=extensionName+'_bindings' - extBinds=self.GetExtensionKeys(extensionName) + bindsName = extensionName + '_bindings' + extBinds = self.GetExtensionKeys(extensionName) #add the non-configurable bindings if self.defaultCfg['extensions'].has_section(bindsName): - eventNames=self.defaultCfg['extensions'].GetOptionList(bindsName) + eventNames = self.defaultCfg['extensions'].GetOptionList(bindsName) for eventName in eventNames: - binding=self.GetOption('extensions',bindsName, - eventName,default='').split() - event='<<'+eventName+'>>' - extBinds[event]=binding + binding = self.GetOption( + 'extensions', bindsName, eventName, default='').split() + event = '<<' + eventName + '>>' + extBinds[event] = binding return extBinds def GetKeyBinding(self, keySetName, eventStr): + """Return the keybinding list for keySetName eventStr. + + keySetName - name of key binding set (config-keys section). + eventStr - virtual event, including brackets, as in '<>'. """ - returns the keybinding for a specific event. - keySetName - string, name of key binding set - eventStr - string, the virtual event we want the binding for, - represented as a string, eg. '<>' - """ - eventName=eventStr[2:-2] #trim off the angle brackets - binding=self.GetOption('keys',keySetName,eventName,default='').split() + eventName = eventStr[2:-2] #trim off the angle brackets + binding = self.GetOption('keys', keySetName, eventName, default='').split() return binding def GetCurrentKeySet(self): + "Return CurrentKeys with 'darwin' modifications." result = self.GetKeySet(self.CurrentKeys()) - if macosxSupport.runningAsOSXApp(): - # We're using AquaTk, replace all keybingings that use the - # Alt key by ones that use the Option key because the former - # don't work reliably. + if sys.platform == "darwin": + # OS X Tk variants do not support the "Alt" keyboard modifier. + # So replace all keybingings that use "Alt" with ones that + # use the "Option" keyboard modifier. + # TODO (Ned?): the "Option" modifier does not work properly for + # Cocoa Tk and XQuartz Tk so we should not use it + # in default OS X KeySets. for k, v in result.items(): v2 = [ x.replace('>' + def IsCoreBinding(self, virtualEvent): + """Return True if the virtual event is one of the core idle key events. + + virtualEvent - string, name of the virtual event to test for, + without the enclosing '<< >>' """ return ('<<'+virtualEvent+'>>') in self.GetCoreKeys() +# TODO make keyBindins a file or class attribute used for test above +# and copied in function below + def GetCoreKeys(self, keySetName=None): - """ - returns the requested set of core keybindings, with fallbacks if - required. - Keybindings loaded from the config file(s) are loaded _over_ these - defaults, so if there is a problem getting any core binding there will - be an 'ultimate last resort fallback' to the CUA-ish bindings - defined here. + """Return dict of core virtual-key keybindings for keySetName. + + The default keySetName None corresponds to the keyBindings base + dict. If keySetName is not None, bindings from the config + file(s) are loaded _over_ these defaults, so if there is a + problem getting any core binding there will be an 'ultimate last + resort fallback' to the CUA-ish bindings defined here. """ keyBindings={ '<>': ['', ''], @@ -626,23 +616,23 @@ def GetCoreKeys(self, keySetName=None): } if keySetName: for event in keyBindings: - binding=self.GetKeyBinding(keySetName,event) + binding = self.GetKeyBinding(keySetName, event) if binding: - keyBindings[event]=binding + keyBindings[event] = binding else: #we are going to return a default, print warning warning=('\n Warning: configHandler.py - IdleConf.GetCoreKeys' ' -\n problem retrieving key binding for event %r' '\n from key set %r.\n' - ' returning default value: %r\n' % + ' returning default value: %r' % (event, keySetName, keyBindings[event])) try: - sys.stderr.write(warning) + print(warning, file=sys.stderr) except OSError: pass return keyBindings - def GetExtraHelpSourceList(self,configSet): - """Fetch list of extra help sources from a given configSet. + def GetExtraHelpSourceList(self, configSet): + """Return list of extra help sources from a given configSet. Valid configSets are 'user' or 'default'. Return a list of tuples of the form (menu_item , path_to_help_file , option), or return the empty @@ -651,19 +641,19 @@ def GetExtraHelpSourceList(self,configSet): therefore the returned list must be sorted by 'option'. """ - helpSources=[] - if configSet=='user': - cfgParser=self.userCfg['main'] - elif configSet=='default': - cfgParser=self.defaultCfg['main'] + helpSources = [] + if configSet == 'user': + cfgParser = self.userCfg['main'] + elif configSet == 'default': + cfgParser = self.defaultCfg['main'] else: raise InvalidConfigSet('Invalid configSet specified') options=cfgParser.GetOptionList('HelpFiles') for option in options: - value=cfgParser.Get('HelpFiles',option,default=';') - if value.find(';')==-1: #malformed config entry with no ';' - menuItem='' #make these empty - helpPath='' #so value won't be added to list + value=cfgParser.Get('HelpFiles', option, default=';') + if value.find(';') == -1: #malformed config entry with no ';' + menuItem = '' #make these empty + helpPath = '' #so value won't be added to list else: #config entry contains ';' as expected value=value.split(';') menuItem=value[0].strip() @@ -674,47 +664,73 @@ def GetExtraHelpSourceList(self,configSet): return helpSources def GetAllExtraHelpSourcesList(self): + """Return a list of the details of all additional help sources. + + Tuples in the list are those of GetExtraHelpSourceList. """ - Returns a list of tuples containing the details of all additional help - sources configured, or an empty list if there are none. Tuples are of - the format returned by GetExtraHelpSourceList. - """ - allHelpSources=( self.GetExtraHelpSourceList('default')+ + allHelpSources = (self.GetExtraHelpSourceList('default') + self.GetExtraHelpSourceList('user') ) return allHelpSources + def GetFont(self, root, configType, section): + """Retrieve a font from configuration (font, font-size, font-bold) + Intercept the special value 'TkFixedFont' and substitute + the actual font, factoring in some tweaks if needed for + appearance sakes. + + The 'root' parameter can normally be any valid Tkinter widget. + + Return a tuple (family, size, weight) suitable for passing + to tkinter.Font + """ + family = self.GetOption(configType, section, 'font', default='courier') + size = self.GetOption(configType, section, 'font-size', type='int', + default='10') + bold = self.GetOption(configType, section, 'font-bold', default=0, + type='bool') + if (family == 'TkFixedFont'): + if TkVersion < 8.5: + family = 'Courier' + else: + f = Font(name='TkFixedFont', exists=True, root=root) + actualFont = Font.actual(f) + family = actualFont['family'] + size = actualFont['size'] + if size < 0: + size = 10 # if font in pixels, ignore actual size + bold = actualFont['weight']=='bold' + return (family, size, 'bold' if bold else 'normal') + def LoadCfgFiles(self): - """ - load all configuration files. - """ + "Load all configuration files." for key in self.defaultCfg: self.defaultCfg[key].Load() self.userCfg[key].Load() #same keys def SaveUserCfgFiles(self): - """ - write all loaded user configuration files back to disk - """ + "Write all loaded user configuration files to disk." for key in self.userCfg: self.userCfg[key].Save() -idleConf=IdleConf() +idleConf = IdleConf() + +# TODO Revise test output, write expanded unittest ### module test if __name__ == '__main__': def dumpCfg(cfg): - print('\n',cfg,'\n') + print('\n', cfg, '\n') for key in cfg: - sections=cfg[key].sections() + sections = cfg[key].sections() print(key) print(sections) for section in sections: - options=cfg[key].options(section) + options = cfg[key].options(section) print(section) print(options) for option in options: - print(option, '=', cfg[key].Get(section,option)) + print(option, '=', cfg[key].Get(section, option)) dumpCfg(idleConf.defaultCfg) dumpCfg(idleConf.userCfg) - print(idleConf.userCfg['main'].Get('Theme','name')) + print(idleConf.userCfg['main'].Get('Theme', 'name')) #print idleConf.userCfg['highlight'].GetDefHighlight('Foo','normal') diff --git a/Lib/idlelib/configHelpSourceEdit.py b/Lib/idlelib/configHelpSourceEdit.py index 2ccb40057500..242b08db56ad 100644 --- a/Lib/idlelib/configHelpSourceEdit.py +++ b/Lib/idlelib/configHelpSourceEdit.py @@ -8,13 +8,14 @@ import tkinter.filedialog as tkFileDialog class GetHelpSourceDialog(Toplevel): - def __init__(self, parent, title, menuItem='', filePath=''): + def __init__(self, parent, title, menuItem='', filePath='', _htest=False): """Get menu entry and url/ local file location for Additional Help User selects a name for the Help resource and provides a web url or a local file as its source. The user can enter a url or browse for the file. + _htest - bool, change box location when running htest """ Toplevel.__init__(self, parent) self.configure(borderwidth=5) @@ -31,12 +32,14 @@ def __init__(self, parent, title, menuItem='', filePath=''): self.withdraw() #hide while setting geometry #needs to be done here so that the winfo_reqwidth is valid self.update_idletasks() - #centre dialog over parent: - self.geometry("+%d+%d" % - ((parent.winfo_rootx() + ((parent.winfo_width()/2) - -(self.winfo_reqwidth()/2)), - parent.winfo_rooty() + ((parent.winfo_height()/2) - -(self.winfo_reqheight()/2))))) + #centre dialog over parent. below parent if running htest. + self.geometry( + "+%d+%d" % ( + parent.winfo_rootx() + + (parent.winfo_width()/2 - self.winfo_reqwidth()/2), + parent.winfo_rooty() + + ((parent.winfo_height()/2 - self.winfo_reqheight()/2) + if not _htest else 150))) self.deiconify() #geometry set, unhide self.bind('', self.Ok) self.wait_window() @@ -159,11 +162,5 @@ def Cancel(self, event=None): self.destroy() if __name__ == '__main__': - #test the dialog - root = Tk() - def run(): - keySeq = '' - dlg = GetHelpSourceDialog(root, 'Get Help Source') - print(dlg.result) - Button(root,text='Dialog', command=run).pack() - root.mainloop() + from idlelib.idle_test.htest import run + run(GetHelpSourceDialog) diff --git a/Lib/idlelib/configSectionNameDialog.py b/Lib/idlelib/configSectionNameDialog.py index b05e38e9d345..5137836981ec 100644 --- a/Lib/idlelib/configSectionNameDialog.py +++ b/Lib/idlelib/configSectionNameDialog.py @@ -8,10 +8,11 @@ import tkinter.messagebox as tkMessageBox class GetCfgSectionNameDialog(Toplevel): - def __init__(self, parent, title, message, used_names): + def __init__(self, parent, title, message, used_names, _htest=False): """ message - string, informational message to display used_names - string collection, names already in use for validity check + _htest - bool, change box location when running htest """ Toplevel.__init__(self, parent) self.configure(borderwidth=5) @@ -30,11 +31,12 @@ def __init__(self, parent, title, message, used_names): self.messageInfo.config(width=self.frameMain.winfo_reqwidth()) self.geometry( "+%d+%d" % ( - parent.winfo_rootx() + - (parent.winfo_width()/2 - self.winfo_reqwidth()/2), - parent.winfo_rooty() + - (parent.winfo_height()/2 - self.winfo_reqheight()/2) - ) ) #centre dialog over parent + parent.winfo_rootx() + + (parent.winfo_width()/2 - self.winfo_reqwidth()/2), + parent.winfo_rooty() + + ((parent.winfo_height()/2 - self.winfo_reqheight()/2) + if not _htest else 100) + ) ) #centre dialog over parent (or below htest box) self.deiconify() #geometry set, unhide self.wait_window() @@ -92,15 +94,5 @@ def Cancel(self, event=None): import unittest unittest.main('idlelib.idle_test.test_config_name', verbosity=2, exit=False) - # also human test the dialog - root = Tk() - def run(): - dlg=GetCfgSectionNameDialog(root,'Get Name', - "After the text entered with [Ok] is stripped, , " - "'abc', or more that 30 chars are errors. " - "Close with a valid entry (printed), [Cancel], or [X]", - {'abc'}) - print(dlg.result) - Message(root, text='').pack() # will be needed for oher dialog tests - Button(root, text='Click to begin dialog test', command=run).pack() - root.mainloop() + from idlelib.idle_test.htest import run + run(GetCfgSectionNameDialog) diff --git a/Lib/idlelib/dynOptionMenuWidget.py b/Lib/idlelib/dynOptionMenuWidget.py index 922de96ceac6..515b4bafc2c4 100644 --- a/Lib/idlelib/dynOptionMenuWidget.py +++ b/Lib/idlelib/dynOptionMenuWidget.py @@ -2,16 +2,15 @@ OptionMenu widget modified to allow dynamic menu reconfiguration and setting of highlightthickness """ -from tkinter import OptionMenu -from tkinter import _setit import copy +from tkinter import OptionMenu, _setit, StringVar, Button class DynOptionMenu(OptionMenu): """ unlike OptionMenu, our kwargs can include highlightthickness """ def __init__(self, master, variable, value, *values, **kwargs): - #get a copy of kwargs before OptionMenu.__init__ munges them + # TODO copy value instead of whole dict kwargsCopy=copy.copy(kwargs) if 'highlightthickness' in list(kwargs.keys()): del(kwargs['highlightthickness']) @@ -33,3 +32,26 @@ def SetMenu(self,valueList,value=None): command=_setit(self.variable,item,self.command)) if value: self.variable.set(value) + +def _dyn_option_menu(parent): # htest # + from tkinter import Toplevel + + top = Toplevel() + top.title("Tets dynamic option menu") + top.geometry("200x100+%d+%d" % (parent.winfo_rootx() + 200, + parent.winfo_rooty() + 150)) + top.focus_set() + + var = StringVar(top) + var.set("Old option set") #Set the default value + dyn = DynOptionMenu(top,var, "old1","old2","old3","old4") + dyn.pack() + + def update(): + dyn.SetMenu(["new1","new2","new3","new4"], value="new option set") + button = Button(top, text="Change option set", command=update) + button.pack() + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(_dyn_option_menu) diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html new file mode 100644 index 000000000000..2189fd4cf0cc --- /dev/null +++ b/Lib/idlelib/help.html @@ -0,0 +1,709 @@ + + + + + + + + 25.5. IDLE — Python 3.4.3 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

25.5. IDLE

+

IDLE is Python’s Integrated Development and Learning Environment.

+

IDLE has the following features:

+
    +
  • coded in 100% pure Python, using the tkinter GUI toolkit
  • +
  • cross-platform: works mostly the same on Windows, Unix, and Mac OS X
  • +
  • Python shell window (interactive interpreter) with colorizing +of code input, output, and error messages
  • +
  • multi-window text editor with multiple undo, Python colorizing, +smart indent, call tips, auto completion, and other features
  • +
  • search within any window, replace within editor windows, and search +through multiple files (grep)
  • +
  • debugger with persistent breakpoints, stepping, and viewing +of global and local namespaces
  • +
  • configuration, browsers, and other dialogs
  • +
+ +
+

25.5.2. Editing and navigation

+

In this section, ‘C’ refers to the Control key on Windows and Unix and +the Command key on Mac OSX.

+
    +
  • Backspace deletes to the left; Del deletes to the right

    +
  • +
  • C-Backspace delete word left; C-Del delete word to the right

    +
  • +
  • Arrow keys and Page Up/Page Down to move around

    +
  • +
  • C-LeftArrow and C-RightArrow moves by words

    +
  • +
  • Home/End go to begin/end of line

    +
  • +
  • C-Home/C-End go to begin/end of file

    +
  • +
  • Some useful Emacs bindings are inherited from Tcl/Tk:

    +
    +
      +
    • C-a beginning of line
    • +
    • C-e end of line
    • +
    • C-k kill line (but doesn’t put it in clipboard)
    • +
    • C-l center window around the insertion point
    • +
    • C-b go backwards one character without deleting (usually you can +also use the cursor key for this)
    • +
    • C-f go forward one character without deleting (usually you can +also use the cursor key for this)
    • +
    • C-p go up one line (usually you can also use the cursor key for +this)
    • +
    • C-d delete next character
    • +
    +
    +
  • +
+

Standard keybindings (like C-c to copy and C-v to paste) +may work. Keybindings are selected in the Configure IDLE dialog.

+
+

25.5.2.1. Automatic indentation

+

After a block-opening statement, the next line is indented by 4 spaces (in the +Python Shell window by one tab). After certain keywords (break, return etc.) +the next line is dedented. In leading indentation, Backspace deletes up +to 4 spaces if they are there. Tab inserts spaces (in the Python +Shell window one tab), number depends on Indent width. Currently tabs +are restricted to four spaces due to Tcl/Tk limitations.

+

See also the indent/dedent region commands in the edit menu.

+
+
+

25.5.2.2. Completions

+

Completions are supplied for functions, classes, and attributes of classes, +both built-in and user-defined. Completions are also provided for +filenames.

+

The AutoCompleteWindow (ACW) will open after a predefined delay (default is +two seconds) after a ‘.’ or (in a string) an os.sep is typed. If after one +of those characters (plus zero or more other characters) a tab is typed +the ACW will open immediately if a possible continuation is found.

+

If there is only one possible completion for the characters entered, a +Tab will supply that completion without opening the ACW.

+

‘Show Completions’ will force open a completions window, by default the +C-space will open a completions window. In an empty +string, this will contain the files in the current directory. On a +blank line, it will contain the built-in and user-defined functions and +classes in the current name spaces, plus any modules imported. If some +characters have been entered, the ACW will attempt to be more specific.

+

If a string of characters is typed, the ACW selection will jump to the +entry most closely matching those characters. Entering a tab will +cause the longest non-ambiguous match to be entered in the Editor window or +Shell. Two tab in a row will supply the current ACW selection, as +will return or a double click. Cursor keys, Page Up/Down, mouse selection, +and the scroll wheel all operate on the ACW.

+

“Hidden” attributes can be accessed by typing the beginning of hidden +name after a ‘.’, e.g. ‘_’. This allows access to modules with +__all__ set, or to class-private attributes.

+

Completions and the ‘Expand Word’ facility can save a lot of typing!

+

Completions are currently limited to those in the namespaces. Names in +an Editor window which are not via __main__ and sys.modules will +not be found. Run the module once with your imports to correct this situation. +Note that IDLE itself places quite a few modules in sys.modules, so +much can be found by default, e.g. the re module.

+

If you don’t like the ACW popping up unbidden, simply make the delay +longer or disable the extension.

+
+
+

25.5.2.3. Calltips

+

A calltip is shown when one types ( after the name of an acccessible +function. A name expression may include dots and subscripts. A calltip +remains until it is clicked, the cursor is moved out of the argument area, +or ) is typed. When the cursor is in the argument part of a definition, +the menu or shortcut display a calltip.

+

A calltip consists of the function signature and the first line of the +docstring. For builtins without an accessible signature, the calltip +consists of all lines up the fifth line or the first blank line. These +details may change.

+

The set of accessible functions depends on what modules have been imported +into the user process, including those imported by Idle itself, +and what definitions have been run, all since the last restart.

+

For example, restart the Shell and enter itertools.count(. A calltip +appears because Idle imports itertools into the user process for its own use. +(This could change.) Enter turtle.write( and nothing appears. Idle does +not import turtle. The menu or shortcut do nothing either. Enter +import turtle and then turtle.write( will work.

+

In an editor, import statements have no effect until one runs the file. One +might want to run a file after writing the import statements at the top, +or immediately run an existing file before editing.

+
+
+

25.5.2.4. Python Shell window

+
    +
  • C-c interrupts executing command

    +
  • +
  • C-d sends end-of-file; closes window if typed at a >>> prompt

    +
  • +
  • Alt-/ (Expand word) is also useful to reduce typing

    +

    Command history

    +
      +
    • Alt-p retrieves previous command matching what you have typed. On +OS X use C-p.
    • +
    • Alt-n retrieves next. On OS X use C-n.
    • +
    • Return while on any previous command retrieves that command
    • +
    +
  • +
+
+
+

25.5.2.5. Text colors

+

Idle defaults to black on white text, but colors text with special meanings. +For the shell, these are shell output, shell error, user output, and +user error. For Python code, at the shell prompt or in an editor, these are +keywords, builtin class and function names, names following class and +def, strings, and comments. For any text window, these are the cursor (when +present), found text (when possible), and selected text.

+

Text coloring is done in the background, so uncolorized text is occasionally +visible. To change the color scheme, use the Configure IDLE dialog +Highlighting tab. The marking of debugger breakpoint lines in the editor and +text in popups and dialogs is not user-configurable.

+
+
+
+

25.5.3. Startup and code execution

+

Upon startup with the -s option, IDLE will execute the file referenced by +the environment variables IDLESTARTUP or PYTHONSTARTUP. +IDLE first checks for IDLESTARTUP; if IDLESTARTUP is present the file +referenced is run. If IDLESTARTUP is not present, IDLE checks for +PYTHONSTARTUP. Files referenced by these environment variables are +convenient places to store functions that are used frequently from the IDLE +shell, or for executing import statements to import common modules.

+

In addition, Tk also loads a startup file if it is present. Note that the +Tk file is loaded unconditionally. This additional file is .Idle.py and is +looked for in the user’s home directory. Statements in this file will be +executed in the Tk namespace, so this file is not useful for importing +functions to be used from IDLE’s Python shell.

+
+

25.5.3.1. Command line usage

+
idle.py [-c command] [-d] [-e] [-h] [-i] [-r file] [-s] [-t title] [-] [arg] ...
+
+-c command  run command in the shell window
+-d          enable debugger and open shell window
+-e          open editor window
+-h          print help message with legal combinatios and exit
+-i          open shell window
+-r file     run file in shell window
+-s          run $IDLESTARTUP or $PYTHONSTARTUP first, in shell window
+-t title    set title of shell window
+-           run stdin in shell (- must be last option before args)
+
+
+

If there are arguments:

+
    +
  • If -, -c, or r is used, all arguments are placed in +sys.argv[1:...] and sys.argv[0] is set to '', '-c', +or '-r'. No editor window is opened, even if that is the default +set in the Options dialog.
  • +
  • Otherwise, arguments are files opened for editing and +sys.argv reflects the arguments passed to IDLE itself.
  • +
+
+
+

25.5.3.2. IDLE-console differences

+

As much as possible, the result of executing Python code with IDLE is the +same as executing the same code in a console window. However, the different +interface and operation occasionally affects results.

+

For instance, IDLE normally executes user code in a separate process from +the IDLE GUI itself. The IDLE versions of sys.stdin, .stdout, and .stderr in the +execution process get input from and send output to the GUI process, +which keeps control of the keyboard and screen. This is normally transparent, +but code that access these object will see different attribute values. +Also, functions that directly access the keyboard and screen will not work.

+

With IDLE’s Shell, one enters, edits, and recalls complete statements. +Some consoles only work with a single physical line at a time.

+
+
+

25.5.3.3. Running without a subprocess

+

By default, IDLE executes user code in a separate subprocess via a socket, +which uses the internal loopback interface. This connection is not +externally visible and no data is sent to or received from the Internet. +If firewall software complains anyway, you can ignore it.

+

If the attempt to make the socket connection fails, Idle will notify you. +Such failures are sometimes transient, but if persistent, the problem +may be either a firewall blocking the connecton or misconfiguration of +a particular system. Until the problem is fixed, one can run Idle with +the -n command line switch.

+

If IDLE is started with the -n command line switch it will run in a +single process and will not create the subprocess which runs the RPC +Python execution server. This can be useful if Python cannot create +the subprocess or the RPC socket interface on your platform. However, +in this mode user code is not isolated from IDLE itself. Also, the +environment is not restarted when Run/Run Module (F5) is selected. If +your code has been modified, you must reload() the affected modules and +re-import any specific items (e.g. from foo import baz) if the changes +are to take effect. For these reasons, it is preferable to run IDLE +with the default subprocess if at all possible.

+
+

Deprecated since version 3.4.

+
+
+
+
+

25.5.4. Help and preferences

+
+

25.5.4.1. Additional help sources

+

IDLE includes a help menu entry called “Python Docs” that will open the +extensive sources of help, including tutorials, available at docs.python.org. +Selected URLs can be added or removed from the help menu at any time using the +Configure IDLE dialog. See the IDLE help option in the help menu of IDLE for +more information.

+
+
+

25.5.4.2. Setting preferences

+

The font preferences, highlighting, keys, and general preferences can be +changed via Configure IDLE on the Option menu. Keys can be user defined; +IDLE ships with four built in key sets. In addition a user can create a +custom key set in the Configure IDLE dialog under the keys tab.

+
+
+

25.5.4.3. Extensions

+

IDLE contains an extension facility. Peferences for extensions can be +changed with Configure Extensions. See the beginning of config-extensions.def +in the idlelib directory for further information. The default extensions +are currently:

+
    +
  • FormatParagraph
  • +
  • AutoExpand
  • +
  • ZoomHeight
  • +
  • ScriptBinding
  • +
  • CallTips
  • +
  • ParenMatch
  • +
  • AutoComplete
  • +
  • CodeContext
  • +
  • RstripExtension
  • +
+
+
+
+ + +
+
+
+ +
+
+ + + + + diff --git a/Lib/idlelib/help.py b/Lib/idlelib/help.py new file mode 100644 index 000000000000..b31596c2eb60 --- /dev/null +++ b/Lib/idlelib/help.py @@ -0,0 +1,249 @@ +""" help.py: Implement the Idle help menu. +Contents are subject to revision at any time, without notice. + + +Help => About IDLE: diplay About Idle dialog + + + + +Help => IDLE Help: Display help.html with proper formatting. +Doc/library/idle.rst (Sphinx)=> Doc/build/html/library/idle.html +(help.copy_strip)=> Lib/idlelib/help.html + +HelpParser - Parse help.html and and render to tk Text. + +HelpText - Display formatted help.html. + +HelpFrame - Contain text, scrollbar, and table-of-contents. +(This will be needed for display in a future tabbed window.) + +HelpWindow - Display HelpFrame in a standalone window. + +copy_strip - Copy idle.html to help.html, rstripping each line. + +show_idlehelp - Create HelpWindow. Called in EditorWindow.help_dialog. +""" +from html.parser import HTMLParser +from os.path import abspath, dirname, isdir, isfile, join +from tkinter import Tk, Toplevel, Frame, Text, Scrollbar, Menu, Menubutton +from tkinter import font as tkfont +from idlelib.configHandler import idleConf + +use_ttk = False # until available to import +if use_ttk: + from tkinter.ttk import Menubutton + +## About IDLE ## + + +## IDLE Help ## + +class HelpParser(HTMLParser): + """Render help.html into a text widget. + + The overridden handle_xyz methods handle a subset of html tags. + The supplied text should have the needed tag configurations. + The behavior for unsupported tags, such as table, is undefined. + """ + def __init__(self, text): + HTMLParser.__init__(self, convert_charrefs=True) + self.text = text # text widget we're rendering into + self.tags = '' # current block level text tags to apply + self.chartags = '' # current character level text tags + self.show = False # used so we exclude page navigation + self.hdrlink = False # used so we don't show header links + self.level = 0 # indentation level + self.pre = False # displaying preformatted text + self.hprefix = '' # prefix such as '25.5' to strip from headings + self.nested_dl = False # if we're in a nested
+ self.simplelist = False # simple list (no double spacing) + self.toc = [] # pair headers with text indexes for toc + self.header = '' # text within header tags for toc + + def indent(self, amt=1): + self.level += amt + self.tags = '' if self.level == 0 else 'l'+str(self.level) + + def handle_starttag(self, tag, attrs): + "Handle starttags in help.html." + class_ = '' + for a, v in attrs: + if a == 'class': + class_ = v + s = '' + if tag == 'div' and class_ == 'section': + self.show = True # start of main content + elif tag == 'div' and class_ == 'sphinxsidebar': + self.show = False # end of main content + elif tag == 'p' and class_ != 'first': + s = '\n\n' + elif tag == 'span' and class_ == 'pre': + self.chartags = 'pre' + elif tag == 'span' and class_ == 'versionmodified': + self.chartags = 'em' + elif tag == 'em': + self.chartags = 'em' + elif tag in ['ul', 'ol']: + if class_.find('simple') != -1: + s = '\n' + self.simplelist = True + else: + self.simplelist = False + self.indent() + elif tag == 'dl': + if self.level > 0: + self.nested_dl = True + elif tag == 'li': + s = '\n* ' if self.simplelist else '\n\n* ' + elif tag == 'dt': + s = '\n\n' if not self.nested_dl else '\n' # avoid extra line + self.nested_dl = False + elif tag == 'dd': + self.indent() + s = '\n' + elif tag == 'pre': + self.pre = True + if self.show: + self.text.insert('end', '\n\n') + self.tags = 'preblock' + elif tag == 'a' and class_ == 'headerlink': + self.hdrlink = True + elif tag == 'h1': + self.tags = tag + elif tag in ['h2', 'h3']: + if self.show: + self.header = '' + self.text.insert('end', '\n\n') + self.tags = tag + if self.show: + self.text.insert('end', s, (self.tags, self.chartags)) + + def handle_endtag(self, tag): + "Handle endtags in help.html." + if tag in ['h1', 'h2', 'h3']: + self.indent(0) # clear tag, reset indent + if self.show: + self.toc.append((self.header, self.text.index('insert'))) + elif tag in ['span', 'em']: + self.chartags = '' + elif tag == 'a': + self.hdrlink = False + elif tag == 'pre': + self.pre = False + self.tags = '' + elif tag in ['ul', 'dd', 'ol']: + self.indent(amt=-1) + + def handle_data(self, data): + "Handle date segments in help.html." + if self.show and not self.hdrlink: + d = data if self.pre else data.replace('\n', ' ') + if self.tags == 'h1': + self.hprefix = d[0:d.index(' ')] + if self.tags in ['h1', 'h2', 'h3'] and self.hprefix != '': + if d[0:len(self.hprefix)] == self.hprefix: + d = d[len(self.hprefix):].strip() + self.header += d + self.text.insert('end', d, (self.tags, self.chartags)) + + +class HelpText(Text): + "Display help.html." + def __init__(self, parent, filename): + "Configure tags and feed file to parser." + uwide = idleConf.GetOption('main', 'EditorWindow', 'width', type='int') + uhigh = idleConf.GetOption('main', 'EditorWindow', 'height', type='int') + uhigh = 3 * uhigh // 4 # lines average 4/3 of editor line height + Text.__init__(self, parent, wrap='word', highlightthickness=0, + padx=5, borderwidth=0, width=uwide, height=uhigh) + + normalfont = self.findfont(['TkDefaultFont', 'arial', 'helvetica']) + fixedfont = self.findfont(['TkFixedFont', 'monaco', 'courier']) + self['font'] = (normalfont, 12) + self.tag_configure('em', font=(normalfont, 12, 'italic')) + self.tag_configure('h1', font=(normalfont, 20, 'bold')) + self.tag_configure('h2', font=(normalfont, 18, 'bold')) + self.tag_configure('h3', font=(normalfont, 15, 'bold')) + self.tag_configure('pre', font=(fixedfont, 12), background='#f6f6ff') + self.tag_configure('preblock', font=(fixedfont, 10), lmargin1=25, + borderwidth=1, relief='solid', background='#eeffcc') + self.tag_configure('l1', lmargin1=25, lmargin2=25) + self.tag_configure('l2', lmargin1=50, lmargin2=50) + self.tag_configure('l3', lmargin1=75, lmargin2=75) + self.tag_configure('l4', lmargin1=100, lmargin2=100) + + self.parser = HelpParser(self) + with open(filename, encoding='utf-8') as f: + contents = f.read() + self.parser.feed(contents) + self['state'] = 'disabled' + + def findfont(self, names): + "Return name of first font family derived from names." + for name in names: + if name.lower() in (x.lower() for x in tkfont.names(root=self)): + font = tkfont.Font(name=name, exists=True, root=self) + return font.actual()['family'] + elif name.lower() in (x.lower() + for x in tkfont.families(root=self)): + return name + + +class HelpFrame(Frame): + "Display html text, scrollbar, and toc." + def __init__(self, parent, filename): + Frame.__init__(self, parent) + text = HelpText(self, filename) + self['background'] = text['background'] + scroll = Scrollbar(self, command=text.yview) + text['yscrollcommand'] = scroll.set + self.rowconfigure(0, weight=1) + self.columnconfigure(1, weight=1) # text + self.toc_menu(text).grid(column=0, row=0, sticky='nw') + text.grid(column=1, row=0, sticky='nsew') + scroll.grid(column=2, row=0, sticky='ns') + + def toc_menu(self, text): + "Create table of contents as drop-down menu." + toc = Menubutton(self, text='TOC') + drop = Menu(toc, tearoff=False) + for lbl, dex in text.parser.toc: + drop.add_command(label=lbl, command=lambda dex=dex:text.yview(dex)) + toc['menu'] = drop + return toc + + +class HelpWindow(Toplevel): + "Display frame with rendered html." + def __init__(self, parent, filename, title): + Toplevel.__init__(self, parent) + self.wm_title(title) + self.protocol("WM_DELETE_WINDOW", self.destroy) + HelpFrame(self, filename).grid(column=0, row=0, sticky='nsew') + self.grid_columnconfigure(0, weight=1) + self.grid_rowconfigure(0, weight=1) + + +def copy_strip(): + "Copy idle.html to idlelib/help.html, stripping trailing whitespace." + src = join(abspath(dirname(dirname(dirname(__file__)))), + 'Doc', 'build', 'html', 'library', 'idle.html') + dst = join(abspath(dirname(__file__)), 'help.html') + with open(src, 'rb') as inn,\ + open(dst, 'wb') as out: + for line in inn: + out.write(line.rstrip() + b'\n') + print('idle.html copied to help.html') + +def show_idlehelp(parent): + "Create HelpWindow; called from Idle Help event handler." + filename = join(abspath(dirname(__file__)), 'help.html') + if not isfile(filename): + # try copy_strip, present message + return + HelpWindow(parent, filename, 'IDLE Help') + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(show_idlehelp) diff --git a/Lib/idlelib/help.txt b/Lib/idlelib/help.txt index 6378a2e7226b..89fbe0b41ec5 100644 --- a/Lib/idlelib/help.txt +++ b/Lib/idlelib/help.txt @@ -1,3 +1,7 @@ +This file, idlelib/help.txt is out-of-date and no longer used by Idle. +It is deprecated and will be removed in the future, possibly in 3.6 +---------------------------------------------------------------------- + [See the end of this file for ** TIPS ** on using IDLE !!] IDLE is the Python IDE built with the tkinter GUI toolkit. @@ -15,9 +19,7 @@ Menus: IDLE has two window types the Shell window and the Editor window. It is possible to have multiple editor windows simultaneously. IDLE's menus dynamically change based on which window is currently selected. Each menu -documented below indicates which window type it is associated with. Click on -the dotted line at the top of a menu to "tear it off": a separate window -containing the menu is created (for Unix and Windows only). +documented below indicates which window type it is associated with. File Menu (Shell and Editor): @@ -129,7 +131,9 @@ Options Menu (Shell and Editor): Configure IDLE -- Open a configuration dialog. Fonts, indentation, keybindings, and color themes may be altered. Startup Preferences may be set, and additional Help - sources can be specified. + sources can be specified. On OS X, open the + configuration dialog by selecting Preferences + in the application menu. --- Code Context (toggle) -- Open a pane at the top of the edit window @@ -138,7 +142,7 @@ Options Menu (Shell and Editor): window. This is not present in the Shell window only the Editor window. -Windows Menu (Shell and Editor): +Window Menu (Shell and Editor): Zoom Height -- Toggles the window between normal size (40x80 initial setting) and maximum height. The initial size is in the Configure diff --git a/Lib/idlelib/idle.bat b/Lib/idlelib/idle.bat index e77b96e9b514..3d619a37eed3 100755 --- a/Lib/idlelib/idle.bat +++ b/Lib/idlelib/idle.bat @@ -1,4 +1,4 @@ -@echo off -rem Start IDLE using the appropriate Python interpreter -set CURRDIR=%~dp0 -start "IDLE" "%CURRDIR%..\..\pythonw.exe" "%CURRDIR%idle.pyw" %1 %2 %3 %4 %5 %6 %7 %8 %9 +@echo off +rem Start IDLE using the appropriate Python interpreter +set CURRDIR=%~dp0 +start "IDLE" "%CURRDIR%..\..\pythonw.exe" "%CURRDIR%idle.pyw" %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/Lib/idlelib/idle.pyw b/Lib/idlelib/idle.pyw index 0db5fd426e7b..142cb322ac24 100644 --- a/Lib/idlelib/idle.pyw +++ b/Lib/idlelib/idle.pyw @@ -2,20 +2,16 @@ try: import idlelib.PyShell except ImportError: # IDLE is not installed, but maybe PyShell is on sys.path: - try: - from . import PyShell - except ImportError: - raise - else: - import os - idledir = os.path.dirname(os.path.abspath(PyShell.__file__)) - if idledir != os.getcwd(): - # We're not in the IDLE directory, help the subprocess find run.py - pypath = os.environ.get('PYTHONPATH', '') - if pypath: - os.environ['PYTHONPATH'] = pypath + ':' + idledir - else: - os.environ['PYTHONPATH'] = idledir - PyShell.main() + from . import PyShell + import os + idledir = os.path.dirname(os.path.abspath(PyShell.__file__)) + if idledir != os.getcwd(): + # We're not in the IDLE directory, help the subprocess find run.py + pypath = os.environ.get('PYTHONPATH', '') + if pypath: + os.environ['PYTHONPATH'] = pypath + ':' + idledir + else: + os.environ['PYTHONPATH'] = idledir + PyShell.main() else: idlelib.PyShell.main() diff --git a/Lib/idlelib/idle_test/README.txt b/Lib/idlelib/idle_test/README.txt index a8d4dcb9922a..2339926ef337 100644 --- a/Lib/idlelib/idle_test/README.txt +++ b/Lib/idlelib/idle_test/README.txt @@ -1,14 +1,24 @@ README FOR IDLE TESTS IN IDLELIB.IDLE_TEST +0. Quick Start + +Automated unit tests were added in 2.7 for Python 2.x and 3.3 for Python 3.x. +To run the tests from a command line: + +python -m test.test_idle + +Human-mediated tests were added later in 2.7 and in 3.4. + +python -m idlelib.idle_test.htest + 1. Test Files The idle directory, idlelib, has over 60 xyz.py files. The idle_test -subdirectory should contain a test_xyy.py for each. (For test modules, make -'xyz' lower case, and possibly shorten it.) Each file should start with the -something like the following template, with the blanks after after '.' and 'as', -and before and after '_' filled in. ---- +subdirectory should contain a test_xyz.py for each, where 'xyz' is lowercased +even if xyz.py is not. Here is a possible template, with the blanks after after +'.' and 'as', and before and after '_' to be filled in. + import unittest from test.support import requires import idlelib. as @@ -18,33 +28,33 @@ class _Test(unittest.TestCase): def test_(self): if __name__ == '__main__': - unittest.main(verbosity=2, exit=2) ---- -Idle tests are run with unittest; do not use regrtest's test_main. + unittest.main(verbosity=2) + +Add the following at the end of xyy.py, with the appropriate name added after +'test_'. Some files already have something like this for htest. If so, insert +the import and unittest.main lines before the htest lines. -Once test_xyy is written, the following should go at the end of xyy.py, -with xyz (lowercased) added after 'test_'. ---- if __name__ == "__main__": - from test import support; support.use_resources = ['gui'] import unittest unittest.main('idlelib.idle_test.test_', verbosity=2, exit=False) ---- -2. Gui Tests -Gui tests need 'requires' and 'use_resources' from test.support -(test.test_support in 2.7). A test is a gui test if it creates a Tk root or -master object either directly or indirectly by instantiating a tkinter or -idle class. For the benefit of buildbot machines that do not have a graphics -screen, gui tests must be 'guarded' by "requires('gui')" in a setUp -function or method. This will typically be setUpClass. +2. GUI Tests + +When run as part of the Python test suite, Idle gui tests need to run +test.support.requires('gui') (test.test_support in 2.7). A test is a gui test +if it creates a Tk root or master object either directly or indirectly by +instantiating a tkinter or idle class. For the benefit of test processes that +either have no graphical environment available or are not allowed to use it, gui +tests must be 'guarded' by "requires('gui')" in a setUp function or method. +This will typically be setUpClass. + +To avoid interfering with other gui tests, all gui objects must be destroyed and +deleted by the end of the test. Widgets, such as a Tk root, created in a setUpX +function, should be destroyed in the corresponding tearDownX. Module and class +widget attributes should also be deleted.. -All gui objects must be destroyed by the end of the test, perhaps in a tearDown -function. Creating the Tk root directly in a setUp allows a reference to be saved -so it can be properly destroyed in the corresponding tearDown. ---- @classmethod def setUpClass(cls): requires('gui') @@ -53,56 +63,81 @@ so it can be properly destroyed in the corresponding tearDown. @classmethod def tearDownClass(cls): cls.root.destroy() ---- - -Support.requires('gui') returns true if it is either called in a main module -(which never happens on buildbots) or if use_resources contains 'gui'. -Use_resources is set by test.regrtest but not by unittest. So when running -tests in another module with unittest, we set it ourselves, as in the xyz.py -template above. - -Since non-gui tests always run, but gui tests only sometimes, tests of non-gui -operations should best avoid needing a gui. Methods that make incidental use of -tkinter (tk) variables and messageboxes can do this by using the mock classes in -idle_test/mock_tk.py. There is also a mock text that will handle some uses of the -tk Text widget. - - -3. Running Tests - -Assume that xyz.py and test_xyz.py end with the "if __name__" statements given -above. In Idle, pressing F5 in an editor window with either loaded will run all -tests in the test_xyz file with the version of Python running Idle. The test -report and any tracebacks will appear in the Shell window. The options in these -"if __name__" statements are appropriate for developers running (as opposed to -importing) either of the files during development: verbosity=2 lists all test -methods in the file; exit=False avoids a spurious sys.exit traceback that would -otherwise occur when running in Idle. The following command lines also run -all test methods, including gui tests, in test_xyz.py. (The exceptions are that -idlelib and idlelib.idle start Idle and idlelib.PyShell should (issue 18330).) - -python -m idlelib.xyz # With the capitalization of the xyz module + del cls.root + + +Requires('gui') causes the test(s) it guards to be skipped if any of +a few conditions are met: + + - The tests are being run by regrtest.py, and it was started without enabling + the "gui" resource with the "-u" command line option. + + - The tests are being run on Windows by a service that is not allowed to + interact with the graphical environment. + + - The tests are being run on Mac OSX in a process that cannot make a window + manager connection. + + - tkinter.Tk cannot be successfully instantiated for some reason. + + - test.support.use_resources has been set by something other than + regrtest.py and does not contain "gui". + +Tests of non-gui operations should avoid creating tk widgets. Incidental uses of +tk variables and messageboxes can be replaced by the mock classes in +idle_test/mock_tk.py. The mock text handles some uses of the tk Text widget. + + +3. Running Unit Tests + +Assume that xyz.py and test_xyz.py both end with a unittest.main() call. +Running either from an Idle editor runs all tests in the test_xyz file with the +version of Python running Idle. Test output appears in the Shell window. The +'verbosity=2' option lists all test methods in the file, which is appropriate +when developing tests. The 'exit=False' option is needed in xyx.py files when an +htest follows. + +The following command lines also run all test methods, including +gui tests, in test_xyz.py. (Both '-m idlelib' and '-m idlelib.idle' start +Idle and so cannot run tests.) + +python -m idlelib.xyz python -m idlelib.idle_test.test_xyz -To run all idle_test/test_*.py tests, either interactively -('>>>', with unittest imported) or from a command line, use one of the -following. (Notes: unittest does not run gui tests; in 2.7, 'test ' (with the -space) is 'test.regrtest '; where present, -v and -ugui can be omitted.) +The following runs all idle_test/test_*.py tests interactively. + +>>> import unittest +>>> unittest.main('idlelib.idle_test', verbosity=2) + +The following run all Idle tests at a command line. Option '-v' is the same as +'verbosity=2'. (For 2.7, replace 'test' in the second line with +'test.regrtest'.) ->>> unittest.main('idlelib.idle_test', verbosity=2, exit=False) python -m unittest -v idlelib.idle_test python -m test -v -ugui test_idle python -m test.test_idle The idle tests are 'discovered' by idlelib.idle_test.__init__.load_tests, which is also imported into test.test_idle. Normally, neither file should be -changed when working on individual test modules. The third command runs runs +changed when working on individual test modules. The third command runs unittest indirectly through regrtest. The same happens when the entire test suite is run with 'python -m test'. So that command must work for buildbots to stay green. Idle tests must not disturb the environment in a way that makes other tests fail (issue 18081). To run an individual Testcase or test method, extend the dotted name given to -unittest on the command line. (But gui tests will not this way.) +unittest on the command line. + +python -m unittest -v idlelib.idle_test.test_xyz.Test_case.test_meth + + +4. Human-mediated Tests + +Human-mediated tests are widget tests that cannot be automated but need human +verification. They are contained in idlelib/idle_test/htest.py, which has +instructions. (Some modules need an auxiliary function, identified with # htest +# on the header line.) The set is about complete, though some tests need +improvement. To run all htests, run the htest file from an editor or from the +command line with: -python -m unittest -v idlelib.idle_test.text_xyz.Test_case.test_meth +python -m idlelib.idle_test.htest diff --git a/Lib/idlelib/idle_test/htest.py b/Lib/idlelib/idle_test/htest.py new file mode 100644 index 000000000000..b0f434046bfd --- /dev/null +++ b/Lib/idlelib/idle_test/htest.py @@ -0,0 +1,399 @@ +'''Run human tests of Idle's window, dialog, and popup widgets. + +run(*tests) +Create a master Tk window. Within that, run each callable in tests +after finding the matching test spec in this file. If tests is empty, +run an htest for each spec dict in this file after finding the matching +callable in the module named in the spec. Close the window to skip or +end the test. + +In a tested module, let X be a global name bound to a callable (class +or function) whose .__name__ attrubute is also X (the usual situation). +The first parameter of X must be 'parent'. When called, the parent +argument will be the root window. X must create a child Toplevel +window (or subclass thereof). The Toplevel may be a test widget or +dialog, in which case the callable is the corresonding class. Or the +Toplevel may contain the widget to be tested or set up a context in +which a test widget is invoked. In this latter case, the callable is a +wrapper function that sets up the Toplevel and other objects. Wrapper +function names, such as _editor_window', should start with '_'. + + +End the module with + +if __name__ == '__main__': + + from idlelib.idle_test.htest import run + run(X) + +To have wrapper functions and test invocation code ignored by coveragepy +reports, put '# htest #' on the def statement header line. + +def _wrapper(parent): # htest # + +Also make sure that the 'if __name__' line matches the above. Then have +make sure that .coveragerc includes the following. + +[report] +exclude_lines = + .*# htest # + if __name__ == .__main__.: + +(The "." instead of "'" is intentional and necessary.) + + +To run any X, this file must contain a matching instance of the +following template, with X.__name__ prepended to '_spec'. +When all tests are run, the prefix is use to get X. + +_spec = { + 'file': '', + 'kwds': {'title': ''}, + 'msg': "" + } + +file (no .py): run() imports file.py. +kwds: augmented with {'parent':root} and passed to X as **kwds. +title: an example kwd; some widgets need this, delete if not. +msg: master window hints about testing the widget. + + +Modules and classes not being tested at the moment: +PyShell.PyShellEditorWindow +Debugger.Debugger +AutoCompleteWindow.AutoCompleteWindow +OutputWindow.OutputWindow (indirectly being tested with grep test) +''' + +from importlib import import_module +from idlelib.macosxSupport import _initializeTkVariantTests +import tkinter as tk + +AboutDialog_spec = { + 'file': 'aboutDialog', + 'kwds': {'title': 'aboutDialog test', + '_htest': True, + }, + 'msg': "Test every button. Ensure Python, TK and IDLE versions " + "are correctly displayed.\n [Close] to exit.", + } + +_calltip_window_spec = { + 'file': 'CallTipWindow', + 'kwds': {}, + 'msg': "Typing '(' should display a calltip.\n" + "Typing ') should hide the calltip.\n" + } + +_class_browser_spec = { + 'file': 'ClassBrowser', + 'kwds': {}, + 'msg': "Inspect names of module, class(with superclass if " + "applicable), methods and functions.\nToggle nested items.\n" + "Double clicking on items prints a traceback for an exception " + "that is ignored." + } + +_color_delegator_spec = { + 'file': 'ColorDelegator', + 'kwds': {}, + 'msg': "The text is sample Python code.\n" + "Ensure components like comments, keywords, builtins,\n" + "string, definitions, and break are correctly colored.\n" + "The default color scheme is in idlelib/config-highlight.def" + } + +ConfigDialog_spec = { + 'file': 'configDialog', + 'kwds': {'title': 'ConfigDialogTest', + '_htest': True,}, + 'msg': "IDLE preferences dialog.\n" + "In the 'Fonts/Tabs' tab, changing font face, should update the " + "font face of the text in the area below it.\nIn the " + "'Highlighting' tab, try different color schemes. Clicking " + "items in the sample program should update the choices above it." + "\nIn the 'Keys', 'General' and 'Extensions' tabs, test settings" + "of interest." + "\n[Ok] to close the dialog.[Apply] to apply the settings and " + "and [Cancel] to revert all changes.\nRe-run the test to ensure " + "changes made have persisted." + } + +# TODO Improve message +_dyn_option_menu_spec = { + 'file': 'dynOptionMenuWidget', + 'kwds': {}, + 'msg': "Select one of the many options in the 'old option set'.\n" + "Click the button to change the option set.\n" + "Select one of the many options in the 'new option set'." + } + +# TODO edit wrapper +_editor_window_spec = { + 'file': 'EditorWindow', + 'kwds': {}, + 'msg': "Test editor functions of interest.\n" + "Best to close editor first." + } + +GetCfgSectionNameDialog_spec = { + 'file': 'configSectionNameDialog', + 'kwds': {'title':'Get Name', + 'message':'Enter something', + 'used_names': {'abc'}, + '_htest': True}, + 'msg': "After the text entered with [Ok] is stripped, , " + "'abc', or more that 30 chars are errors.\n" + "Close 'Get Name' with a valid entry (printed to Shell), " + "[Cancel], or [X]", + } + +GetHelpSourceDialog_spec = { + 'file': 'configHelpSourceEdit', + 'kwds': {'title': 'Get helpsource', + '_htest': True}, + 'msg': "Enter menu item name and help file path\n " + " and more than 30 chars are invalid menu item names.\n" + ", file does not exist are invalid path items.\n" + "Test for incomplete web address for help file path.\n" + "A valid entry will be printed to shell with [0k].\n" + "[Cancel] will print None to shell", + } + +# Update once issue21519 is resolved. +GetKeysDialog_spec = { + 'file': 'keybindingDialog', + 'kwds': {'title': 'Test keybindings', + 'action': 'find-again', + 'currentKeySequences': [''] , + '_htest': True, + }, + 'msg': "Test for different key modifier sequences.\n" + " is invalid.\n" + "No modifier key is invalid.\n" + "Shift key with [a-z],[0-9], function key, move key, tab, space" + "is invalid.\nNo validity checking if advanced key binding " + "entry is used." + } + +_grep_dialog_spec = { + 'file': 'GrepDialog', + 'kwds': {}, + 'msg': "Click the 'Show GrepDialog' button.\n" + "Test the various 'Find-in-files' functions.\n" + "The results should be displayed in a new '*Output*' window.\n" + "'Right-click'->'Goto file/line' anywhere in the search results " + "should open that file \nin a new EditorWindow." + } + +_io_binding_spec = { + 'file': 'IOBinding', + 'kwds': {}, + 'msg': "Test the following bindings\n" + " to display open window from file dialog.\n" + " to save the file\n" + } + +_multi_call_spec = { + 'file': 'MultiCall', + 'kwds': {}, + 'msg': "The following actions should trigger a print to console or IDLE" + " Shell.\nEntering and leaving the text area, key entry, " + ",\n, , " + ", \n, and " + "focusing out of the window\nare sequences to be tested." + } + +_multistatus_bar_spec = { + 'file': 'MultiStatusBar', + 'kwds': {}, + 'msg': "Ensure presence of multi-status bar below text area.\n" + "Click 'Update Status' to change the multi-status text" + } + +_object_browser_spec = { + 'file': 'ObjectBrowser', + 'kwds': {}, + 'msg': "Double click on items upto the lowest level.\n" + "Attributes of the objects and related information " + "will be displayed side-by-side at each level." + } + +_path_browser_spec = { + 'file': 'PathBrowser', + 'kwds': {}, + 'msg': "Test for correct display of all paths in sys.path.\n" + "Toggle nested items upto the lowest level.\n" + "Double clicking on an item prints a traceback\n" + "for an exception that is ignored." + } + +_percolator_spec = { + 'file': 'Percolator', + 'kwds': {}, + 'msg': "There are two tracers which can be toggled using a checkbox.\n" + "Toggling a tracer 'on' by checking it should print tracer" + "output to the console or to the IDLE shell.\n" + "If both the tracers are 'on', the output from the tracer which " + "was switched 'on' later, should be printed first\n" + "Test for actions like text entry, and removal." + } + +_replace_dialog_spec = { + 'file': 'ReplaceDialog', + 'kwds': {}, + 'msg': "Click the 'Replace' button.\n" + "Test various replace options in the 'Replace dialog'.\n" + "Click [Close] or [X] to close the 'Replace Dialog'." + } + +_search_dialog_spec = { + 'file': 'SearchDialog', + 'kwds': {}, + 'msg': "Click the 'Search' button.\n" + "Test various search options in the 'Search dialog'.\n" + "Click [Close] or [X] to close the 'Search Dialog'." + } + +_scrolled_list_spec = { + 'file': 'ScrolledList', + 'kwds': {}, + 'msg': "You should see a scrollable list of items\n" + "Selecting (clicking) or double clicking an item " + "prints the name to the console or Idle shell.\n" + "Right clicking an item will display a popup." + } + +show_idlehelp_spec = { + 'file': 'help', + 'kwds': {}, + 'msg': "If the help text displays, this works.\n" + "Text is selectable. Window is scrollable." + } + +_stack_viewer_spec = { + 'file': 'StackViewer', + 'kwds': {}, + 'msg': "A stacktrace for a NameError exception.\n" + "Expand 'idlelib ...' and ''.\n" + "Check that exc_value, exc_tb, and exc_type are correct.\n" + } + +_tabbed_pages_spec = { + 'file': 'tabbedpages', + 'kwds': {}, + 'msg': "Toggle between the two tabs 'foo' and 'bar'\n" + "Add a tab by entering a suitable name for it.\n" + "Remove an existing tab by entering its name.\n" + "Remove all existing tabs.\n" + " is an invalid add page and remove page name.\n" + } + +TextViewer_spec = { + 'file': 'textView', + 'kwds': {'title': 'Test textView', + 'text':'The quick brown fox jumps over the lazy dog.\n'*35, + '_htest': True}, + 'msg': "Test for read-only property of text.\n" + "Text is selectable. Window is scrollable.", + } + +_tooltip_spec = { + 'file': 'ToolTip', + 'kwds': {}, + 'msg': "Place mouse cursor over both the buttons\n" + "A tooltip should appear with some text." + } + +_tree_widget_spec = { + 'file': 'TreeWidget', + 'kwds': {}, + 'msg': "The canvas is scrollable.\n" + "Click on folders upto to the lowest level." + } + +_undo_delegator_spec = { + 'file': 'UndoDelegator', + 'kwds': {}, + 'msg': "Click [Undo] to undo any action.\n" + "Click [Redo] to redo any action.\n" + "Click [Dump] to dump the current state " + "by printing to the console or the IDLE shell.\n" + } + +_widget_redirector_spec = { + 'file': 'WidgetRedirector', + 'kwds': {}, + 'msg': "Every text insert should be printed to the console." + "or the IDLE shell." + } + +def run(*tests): + root = tk.Tk() + root.title('IDLE htest') + root.resizable(0, 0) + _initializeTkVariantTests(root) + + # a scrollable Label like constant width text widget. + frameLabel = tk.Frame(root, padx=10) + frameLabel.pack() + text = tk.Text(frameLabel, wrap='word') + text.configure(bg=root.cget('bg'), relief='flat', height=4, width=70) + scrollbar = tk.Scrollbar(frameLabel, command=text.yview) + text.config(yscrollcommand=scrollbar.set) + scrollbar.pack(side='right', fill='y', expand=False) + text.pack(side='left', fill='both', expand=True) + + test_list = [] # List of tuples of the form (spec, callable widget) + if tests: + for test in tests: + test_spec = globals()[test.__name__ + '_spec'] + test_spec['name'] = test.__name__ + test_list.append((test_spec, test)) + else: + for k, d in globals().items(): + if k.endswith('_spec'): + test_name = k[:-5] + test_spec = d + test_spec['name'] = test_name + mod = import_module('idlelib.' + test_spec['file']) + test = getattr(mod, test_name) + test_list.append((test_spec, test)) + + test_name = tk.StringVar('') + callable_object = None + test_kwds = None + + def next(): + + nonlocal test_name, callable_object, test_kwds + if len(test_list) == 1: + next_button.pack_forget() + test_spec, callable_object = test_list.pop() + test_kwds = test_spec['kwds'] + test_kwds['parent'] = root + test_name.set('Test ' + test_spec['name']) + + text.configure(state='normal') # enable text editing + text.delete('1.0','end') + text.insert("1.0",test_spec['msg']) + text.configure(state='disabled') # preserve read-only property + + def run_test(): + widget = callable_object(**test_kwds) + try: + print(widget.result) + except AttributeError: + pass + + button = tk.Button(root, textvariable=test_name, command=run_test) + button.pack() + next_button = tk.Button(root, text="Next", command=next) + next_button.pack() + + next() + + root.mainloop() + +if __name__ == '__main__': + run() diff --git a/Lib/idlelib/idle_test/mock_idle.py b/Lib/idlelib/idle_test/mock_idle.py index c364a24dacbf..1672a3413e78 100644 --- a/Lib/idlelib/idle_test/mock_idle.py +++ b/Lib/idlelib/idle_test/mock_idle.py @@ -5,6 +5,33 @@ from idlelib.idle_test.mock_tk import Text +class Func: + '''Mock function captures args and returns result set by test. + + Attributes: + self.called - records call even if no args, kwds passed. + self.result - set by init, returned by call. + self.args - captures positional arguments. + self.kwds - captures keyword arguments. + + Most common use will probably be to mock methods. + Mock_tk.Var and Mbox_func are special variants of this. + ''' + def __init__(self, result=None): + self.called = False + self.result = result + self.args = None + self.kwds = None + def __call__(self, *args, **kwds): + self.called = True + self.args = args + self.kwds = kwds + if isinstance(self.result, BaseException): + raise self.result + else: + return self.result + + class Editor: '''Minimally imitate EditorWindow.EditorWindow class. ''' @@ -17,6 +44,7 @@ def get_selection_indices(self): last = self.text.index('end') return first, last + class UndoDelegator: '''Minimally imitate UndoDelegator,UndoDelegator class. ''' diff --git a/Lib/idlelib/idle_test/mock_tk.py b/Lib/idlelib/idle_test/mock_tk.py index 762bbc905db9..86fe84884fba 100644 --- a/Lib/idlelib/idle_test/mock_tk.py +++ b/Lib/idlelib/idle_test/mock_tk.py @@ -1,9 +1,27 @@ """Classes that replace tkinter gui objects used by an object being tested. -A gui object is anything with a master or parent paramenter, which is typically -required in spite of what the doc strings say. +A gui object is anything with a master or parent parameter, which is +typically required in spite of what the doc strings say. """ +class Event: + '''Minimal mock with attributes for testing event handlers. + + This is not a gui object, but is used as an argument for callbacks + that access attributes of the event passed. If a callback ignores + the event, other than the fact that is happened, pass 'event'. + + Keyboard, mouse, window, and other sources generate Event instances. + Event instances have the following attributes: serial (number of + event), time (of event), type (of event as number), widget (in which + event occurred), and x,y (position of mouse). There are other + attributes for specific events, such as keycode for key events. + tkinter.Event.__doc__ has more but is still not complete. + ''' + def __init__(self, **kwds): + "Create event with attributes needed for test" + self.__dict__.update(kwds) + class Var: "Use for String/Int/BooleanVar: incomplete" def __init__(self, master=None, value=None, name=None): @@ -20,9 +38,10 @@ class Mbox_func: Instead of displaying a message box, the mock's call method saves the arguments as instance attributes, which test functions can then examime. + The test can set the result returned to ask function """ - def __init__(self): - self.result = None # The return for all show funcs + def __init__(self, result=None): + self.result = result # Return None for all show funcs def __call__(self, title, message, *args, **kwds): # Save all args for possible examination by tester self.title = title @@ -97,7 +116,7 @@ def _decode(self, index, endflag=0): """Return a (line, char) tuple of int indexes into self.data. This implements .index without converting the result back to a string. - The result is contrained by the number of lines and linelengths of + The result is constrained by the number of lines and linelengths of self.data. For many indexes, the result is initially (1, 0). The input index may have any of several possible forms: diff --git a/Lib/idlelib/idle_test/test_autocomplete.py b/Lib/idlelib/idle_test/test_autocomplete.py new file mode 100644 index 000000000000..3a2192e8afce --- /dev/null +++ b/Lib/idlelib/idle_test/test_autocomplete.py @@ -0,0 +1,143 @@ +import unittest +from test.support import requires +from tkinter import Tk, Text + +import idlelib.AutoComplete as ac +import idlelib.AutoCompleteWindow as acw +import idlelib.macosxSupport as mac +from idlelib.idle_test.mock_idle import Func +from idlelib.idle_test.mock_tk import Event + +class AutoCompleteWindow: + def complete(): + return + +class DummyEditwin: + def __init__(self, root, text): + self.root = root + self.text = text + self.indentwidth = 8 + self.tabwidth = 8 + self.context_use_ps1 = True + + +class AutoCompleteTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + mac.setupApp(cls.root, None) + cls.text = Text(cls.root) + cls.editor = DummyEditwin(cls.root, cls.text) + + @classmethod + def tearDownClass(cls): + cls.root.destroy() + del cls.text + del cls.editor + del cls.root + + def setUp(self): + self.editor.text.delete('1.0', 'end') + self.autocomplete = ac.AutoComplete(self.editor) + + def test_init(self): + self.assertEqual(self.autocomplete.editwin, self.editor) + + def test_make_autocomplete_window(self): + testwin = self.autocomplete._make_autocomplete_window() + self.assertIsInstance(testwin, acw.AutoCompleteWindow) + + def test_remove_autocomplete_window(self): + self.autocomplete.autocompletewindow = ( + self.autocomplete._make_autocomplete_window()) + self.autocomplete._remove_autocomplete_window() + self.assertIsNone(self.autocomplete.autocompletewindow) + + def test_force_open_completions_event(self): + # Test that force_open_completions_event calls _open_completions + o_cs = Func() + self.autocomplete.open_completions = o_cs + self.autocomplete.force_open_completions_event('event') + self.assertEqual(o_cs.args, (True, False, True)) + + def test_try_open_completions_event(self): + Equal = self.assertEqual + autocomplete = self.autocomplete + trycompletions = self.autocomplete.try_open_completions_event + o_c_l = Func() + autocomplete._open_completions_later = o_c_l + + # _open_completions_later should not be called with no text in editor + trycompletions('event') + Equal(o_c_l.args, None) + + # _open_completions_later should be called with COMPLETE_ATTRIBUTES (1) + self.text.insert('1.0', 're.') + trycompletions('event') + Equal(o_c_l.args, (False, False, False, 1)) + + # _open_completions_later should be called with COMPLETE_FILES (2) + self.text.delete('1.0', 'end') + self.text.insert('1.0', '"./Lib/') + trycompletions('event') + Equal(o_c_l.args, (False, False, False, 2)) + + def test_autocomplete_event(self): + Equal = self.assertEqual + autocomplete = self.autocomplete + + # Test that the autocomplete event is ignored if user is pressing a + # modifier key in addition to the tab key + ev = Event(mc_state=True) + self.assertIsNone(autocomplete.autocomplete_event(ev)) + del ev.mc_state + + # If autocomplete window is open, complete() method is called + self.text.insert('1.0', 're.') + # This must call autocomplete._make_autocomplete_window() + Equal(self.autocomplete.autocomplete_event(ev), 'break') + + # If autocomplete window is not active or does not exist, + # open_completions is called. Return depends on its return. + autocomplete._remove_autocomplete_window() + o_cs = Func() # .result = None + autocomplete.open_completions = o_cs + Equal(self.autocomplete.autocomplete_event(ev), None) + Equal(o_cs.args, (False, True, True)) + o_cs.result = True + Equal(self.autocomplete.autocomplete_event(ev), 'break') + Equal(o_cs.args, (False, True, True)) + + def test_open_completions_later(self): + # Test that autocomplete._delayed_completion_id is set + pass + + def test_delayed_open_completions(self): + # Test that autocomplete._delayed_completion_id set to None and that + # open_completions only called if insertion index is the same as + # _delayed_completion_index + pass + + def test_open_completions(self): + # Test completions of files and attributes as well as non-completion + # of errors + pass + + def test_fetch_completions(self): + # Test that fetch_completions returns 2 lists: + # For attribute completion, a large list containing all variables, and + # a small list containing non-private variables. + # For file completion, a large list containing all files in the path, + # and a small list containing files that do not start with '.' + pass + + def test_get_entity(self): + # Test that a name is in the namespace of sys.modules and + # __main__.__dict__ + pass + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_autoexpand.py b/Lib/idlelib/idle_test/test_autoexpand.py new file mode 100644 index 000000000000..7ca941ec2902 --- /dev/null +++ b/Lib/idlelib/idle_test/test_autoexpand.py @@ -0,0 +1,141 @@ +"""Unit tests for idlelib.AutoExpand""" +import unittest +from test.support import requires +from tkinter import Text, Tk +#from idlelib.idle_test.mock_tk import Text +from idlelib.AutoExpand import AutoExpand + + +class Dummy_Editwin: + # AutoExpand.__init__ only needs .text + def __init__(self, text): + self.text = text + +class AutoExpandTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + if 'tkinter' in str(Text): + requires('gui') + cls.tk = Tk() + cls.text = Text(cls.tk) + else: + cls.text = Text() + cls.auto_expand = AutoExpand(Dummy_Editwin(cls.text)) + + @classmethod + def tearDownClass(cls): + if hasattr(cls, 'tk'): + cls.tk.destroy() + del cls.tk + del cls.text, cls.auto_expand + + def tearDown(self): + self.text.delete('1.0', 'end') + + def test_get_prevword(self): + text = self.text + previous = self.auto_expand.getprevword + equal = self.assertEqual + + equal(previous(), '') + + text.insert('insert', 't') + equal(previous(), 't') + + text.insert('insert', 'his') + equal(previous(), 'this') + + text.insert('insert', ' ') + equal(previous(), '') + + text.insert('insert', 'is') + equal(previous(), 'is') + + text.insert('insert', '\nsample\nstring') + equal(previous(), 'string') + + text.delete('3.0', 'insert') + equal(previous(), '') + + text.delete('1.0', 'end') + equal(previous(), '') + + def test_before_only(self): + previous = self.auto_expand.getprevword + expand = self.auto_expand.expand_word_event + equal = self.assertEqual + + self.text.insert('insert', 'ab ac bx ad ab a') + equal(self.auto_expand.getwords(), ['ab', 'ad', 'ac', 'a']) + expand('event') + equal(previous(), 'ab') + expand('event') + equal(previous(), 'ad') + expand('event') + equal(previous(), 'ac') + expand('event') + equal(previous(), 'a') + + def test_after_only(self): + # Also add punctuation 'noise' that should be ignored. + text = self.text + previous = self.auto_expand.getprevword + expand = self.auto_expand.expand_word_event + equal = self.assertEqual + + text.insert('insert', 'a, [ab] ac: () bx"" cd ac= ad ya') + text.mark_set('insert', '1.1') + equal(self.auto_expand.getwords(), ['ab', 'ac', 'ad', 'a']) + expand('event') + equal(previous(), 'ab') + expand('event') + equal(previous(), 'ac') + expand('event') + equal(previous(), 'ad') + expand('event') + equal(previous(), 'a') + + def test_both_before_after(self): + text = self.text + previous = self.auto_expand.getprevword + expand = self.auto_expand.expand_word_event + equal = self.assertEqual + + text.insert('insert', 'ab xy yz\n') + text.insert('insert', 'a ac by ac') + + text.mark_set('insert', '2.1') + equal(self.auto_expand.getwords(), ['ab', 'ac', 'a']) + expand('event') + equal(previous(), 'ab') + expand('event') + equal(previous(), 'ac') + expand('event') + equal(previous(), 'a') + + def test_other_expand_cases(self): + text = self.text + expand = self.auto_expand.expand_word_event + equal = self.assertEqual + + # no expansion candidate found + equal(self.auto_expand.getwords(), []) + equal(expand('event'), 'break') + + text.insert('insert', 'bx cy dz a') + equal(self.auto_expand.getwords(), []) + + # reset state by successfully expanding once + # move cursor to another position and expand again + text.insert('insert', 'ac xy a ac ad a') + text.mark_set('insert', '1.7') + expand('event') + initial_state = self.auto_expand.state + text.mark_set('insert', '1.end') + expand('event') + new_state = self.auto_expand.state + self.assertNotEqual(initial_state, new_state) + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_calltips.py b/Lib/idlelib/idle_test/test_calltips.py index ed28a21abb49..b2a733cc0d5f 100644 --- a/Lib/idlelib/idle_test/test_calltips.py +++ b/Lib/idlelib/idle_test/test_calltips.py @@ -1,5 +1,171 @@ import unittest import idlelib.CallTips as ct +import textwrap +import types + +default_tip = ct._default_callable_argspec + +# Test Class TC is used in multiple get_argspec test methods +class TC(): + 'doc' + tip = "(ai=None, *b)" + def __init__(self, ai=None, *b): 'doc' + __init__.tip = "(self, ai=None, *b)" + def t1(self): 'doc' + t1.tip = "(self)" + def t2(self, ai, b=None): 'doc' + t2.tip = "(self, ai, b=None)" + def t3(self, ai, *args): 'doc' + t3.tip = "(self, ai, *args)" + def t4(self, *args): 'doc' + t4.tip = "(self, *args)" + def t5(self, ai, b=None, *args, **kw): 'doc' + t5.tip = "(self, ai, b=None, *args, **kw)" + def t6(no, self): 'doc' + t6.tip = "(no, self)" + def __call__(self, ci): 'doc' + __call__.tip = "(self, ci)" + # attaching .tip to wrapped methods does not work + @classmethod + def cm(cls, a): 'doc' + @staticmethod + def sm(b): 'doc' + +tc = TC() + +signature = ct.get_argspec # 2.7 and 3.x use different functions +class Get_signatureTest(unittest.TestCase): + # The signature function must return a string, even if blank. + # Test a variety of objects to be sure that none cause it to raise + # (quite aside from getting as correct an answer as possible). + # The tests of builtins may break if inspect or the docstrings change, + # but a red buildbot is better than a user crash (as has happened). + # For a simple mismatch, change the expected output to the actual. + + def test_builtins(self): + + # Python class that inherits builtin methods + class List(list): "List() doc" + # Simulate builtin with no docstring for default tip test + class SB: __call__ = None + + def gtest(obj, out): + self.assertEqual(signature(obj), out) + + if List.__doc__ is not None: + gtest(List, List.__doc__) + gtest(list.__new__, + 'Create and return a new object. See help(type) for accurate signature.') + gtest(list.__init__, + 'Initialize self. See help(type(self)) for accurate signature.') + append_doc = "L.append(object) -> None -- append object to end" + gtest(list.append, append_doc) + gtest([].append, append_doc) + gtest(List.append, append_doc) + + gtest(types.MethodType, "method(function, instance)") + gtest(SB(), default_tip) + + def test_signature_wrap(self): + if textwrap.TextWrapper.__doc__ is not None: + self.assertEqual(signature(textwrap.TextWrapper), '''\ +(width=70, initial_indent='', subsequent_indent='', expand_tabs=True, + replace_whitespace=True, fix_sentence_endings=False, break_long_words=True, + drop_whitespace=True, break_on_hyphens=True, tabsize=8, *, max_lines=None, + placeholder=' [...]')''') + + def test_docline_truncation(self): + def f(): pass + f.__doc__ = 'a'*300 + self.assertEqual(signature(f), '()\n' + 'a' * (ct._MAX_COLS-3) + '...') + + def test_multiline_docstring(self): + # Test fewer lines than max. + self.assertEqual(signature(list), + "list() -> new empty list\n" + "list(iterable) -> new list initialized from iterable's items") + + # Test max lines + self.assertEqual(signature(bytes), '''\ +bytes(iterable_of_ints) -> bytes +bytes(string, encoding[, errors]) -> bytes +bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer +bytes(int) -> bytes object of size given by the parameter initialized with null bytes +bytes() -> empty bytes object''') + + # Test more than max lines + def f(): pass + f.__doc__ = 'a\n' * 15 + self.assertEqual(signature(f), '()' + '\na' * ct._MAX_LINES) + + def test_functions(self): + def t1(): 'doc' + t1.tip = "()" + def t2(a, b=None): 'doc' + t2.tip = "(a, b=None)" + def t3(a, *args): 'doc' + t3.tip = "(a, *args)" + def t4(*args): 'doc' + t4.tip = "(*args)" + def t5(a, b=None, *args, **kw): 'doc' + t5.tip = "(a, b=None, *args, **kw)" + + doc = '\ndoc' if t1.__doc__ is not None else '' + for func in (t1, t2, t3, t4, t5, TC): + self.assertEqual(signature(func), func.tip + doc) + + def test_methods(self): + doc = '\ndoc' if TC.__doc__ is not None else '' + for meth in (TC.t1, TC.t2, TC.t3, TC.t4, TC.t5, TC.t6, TC.__call__): + self.assertEqual(signature(meth), meth.tip + doc) + self.assertEqual(signature(TC.cm), "(a)" + doc) + self.assertEqual(signature(TC.sm), "(b)" + doc) + + def test_bound_methods(self): + # test that first parameter is correctly removed from argspec + doc = '\ndoc' if TC.__doc__ is not None else '' + for meth, mtip in ((tc.t1, "()"), (tc.t4, "(*args)"), (tc.t6, "(self)"), + (tc.__call__, '(ci)'), (tc, '(ci)'), (TC.cm, "(a)"),): + self.assertEqual(signature(meth), mtip + doc) + + def test_starred_parameter(self): + # test that starred first parameter is *not* removed from argspec + class C: + def m1(*args): pass + def m2(**kwds): pass + c = C() + for meth, mtip in ((C.m1, '(*args)'), (c.m1, "(*args)"), + (C.m2, "(**kwds)"), (c.m2, "(**kwds)"),): + self.assertEqual(signature(meth), mtip) + + def test_non_ascii_name(self): + # test that re works to delete a first parameter name that + # includes non-ascii chars, such as various forms of A. + uni = "(A\u0391\u0410\u05d0\u0627\u0905\u1e00\u3042, a)" + assert ct._first_param.sub('', uni) == '(a)' + + def test_no_docstring(self): + def nd(s): + pass + TC.nd = nd + self.assertEqual(signature(nd), "(s)") + self.assertEqual(signature(TC.nd), "(s)") + self.assertEqual(signature(tc.nd), "()") + + def test_attribute_exception(self): + class NoCall: + def __getattr__(self, name): + raise BaseException + class Call(NoCall): + def __call__(self, ci): + pass + for meth, mtip in ((NoCall, default_tip), (Call, default_tip), + (NoCall(), ''), (Call(), '(ci)')): + self.assertEqual(signature(meth), mtip) + + def test_non_callables(self): + for obj in (0, 0.0, '0', b'0', [], {}): + self.assertEqual(signature(obj), '') class Get_entityTest(unittest.TestCase): def test_bad_entity(self): diff --git a/Lib/idlelib/idle_test/test_configdialog.py b/Lib/idlelib/idle_test/test_configdialog.py new file mode 100644 index 000000000000..68831236b76b --- /dev/null +++ b/Lib/idlelib/idle_test/test_configdialog.py @@ -0,0 +1,32 @@ +'''Unittests for idlelib/configHandler.py + +Coverage: 46% just by creating dialog. The other half is change code. + +''' +import unittest +from test.support import requires +from tkinter import Tk +from idlelib.configDialog import ConfigDialog +from idlelib.macosxSupport import _initializeTkVariantTests + + +class ConfigDialogTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + _initializeTkVariantTests(cls.root) + + @classmethod + def tearDownClass(cls): + cls.root.destroy() + del cls.root + + def test_dialog(self): + d=ConfigDialog(self.root, 'Test', _utest=True) + d.destroy() + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_editor.py b/Lib/idlelib/idle_test/test_editor.py new file mode 100644 index 000000000000..a31d26d25d64 --- /dev/null +++ b/Lib/idlelib/idle_test/test_editor.py @@ -0,0 +1,16 @@ +import unittest +from tkinter import Tk, Text +from idlelib.EditorWindow import EditorWindow +from test.support import requires + +class Editor_func_test(unittest.TestCase): + def test_filename_to_unicode(self): + func = EditorWindow._filename_to_unicode + class dummy(): filesystemencoding = 'utf-8' + pairs = (('abc', 'abc'), ('a\U00011111c', 'a\ufffdc'), + (b'abc', 'abc'), (b'a\xf0\x91\x84\x91c', 'a\ufffdc')) + for inp, out in pairs: + self.assertEqual(func(dummy, inp), out) + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_formatparagraph.py b/Lib/idlelib/idle_test/test_formatparagraph.py index 818c9d4b674b..f6039e6ab4b8 100644 --- a/Lib/idlelib/idle_test/test_formatparagraph.py +++ b/Lib/idlelib/idle_test/test_formatparagraph.py @@ -2,7 +2,7 @@ import unittest from idlelib import FormatParagraph as fp from idlelib.EditorWindow import EditorWindow -from tkinter import Tk, Text, TclError +from tkinter import Tk, Text from test.support import requires @@ -277,6 +277,9 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): cls.root.destroy() + del cls.root + del cls.text + del cls.formatter def test_short_line(self): self.text.insert('1.0', "Short line\n") @@ -290,7 +293,7 @@ def test_long_line(self): # Set cursor ('insert' mark) to '1.0', within text. text.insert('1.0', self.test_string) text.mark_set('insert', '1.0') - self.formatter('ParameterDoesNothing') + self.formatter('ParameterDoesNothing', limit=70) result = text.get('1.0', 'insert') # find function includes \n expected = ( @@ -302,7 +305,7 @@ def test_long_line(self): # Select from 1.11 to line end. text.insert('1.0', self.test_string) text.tag_add('sel', '1.11', '1.end') - self.formatter('ParameterDoesNothing') + self.formatter('ParameterDoesNothing', limit=70) result = text.get('1.0', 'insert') # selection excludes \n expected = ( @@ -316,7 +319,7 @@ def test_multiple_lines(self): # Select 2 long lines. text.insert('1.0', self.multiline_test_string) text.tag_add('sel', '2.0', '4.0') - self.formatter('ParameterDoesNothing') + self.formatter('ParameterDoesNothing', limit=70) result = text.get('2.0', 'insert') expected = ( " The second line's length is way over the max width. It goes on and\n" @@ -331,7 +334,7 @@ def test_comment_block(self): # Set cursor ('insert') to '1.0', within block. text.insert('1.0', self.multiline_test_comment) - self.formatter('ParameterDoesNothing') + self.formatter('ParameterDoesNothing', limit=70) result = text.get('1.0', 'insert') expected = ( "# The first line is under the max width. The second line's length is\n" @@ -345,7 +348,7 @@ def test_comment_block(self): # Select line 2, verify line 1 unaffected. text.insert('1.0', self.multiline_test_comment) text.tag_add('sel', '2.0', '3.0') - self.formatter('ParameterDoesNothing') + self.formatter('ParameterDoesNothing', limit=70) result = text.get('1.0', 'insert') expected = ( "# The first line is under the max width.\n" diff --git a/Lib/idlelib/idle_test/test_hyperparser.py b/Lib/idlelib/idle_test/test_hyperparser.py new file mode 100644 index 000000000000..edfc783fe8da --- /dev/null +++ b/Lib/idlelib/idle_test/test_hyperparser.py @@ -0,0 +1,273 @@ +"""Unittest for idlelib.HyperParser""" +import unittest +from test.support import requires +from tkinter import Tk, Text +from idlelib.EditorWindow import EditorWindow +from idlelib.HyperParser import HyperParser + +class DummyEditwin: + def __init__(self, text): + self.text = text + self.indentwidth = 8 + self.tabwidth = 8 + self.context_use_ps1 = True + self.num_context_lines = 50, 500, 1000 + + _build_char_in_string_func = EditorWindow._build_char_in_string_func + is_char_in_string = EditorWindow.is_char_in_string + + +class HyperParserTest(unittest.TestCase): + code = ( + '"""This is a module docstring"""\n' + '# this line is a comment\n' + 'x = "this is a string"\n' + "y = 'this is also a string'\n" + 'l = [i for i in range(10)]\n' + 'm = [py*py for # comment\n' + ' py in l]\n' + 'x.__len__\n' + "z = ((r'asdf')+('a')))\n" + '[x for x in\n' + 'for = False\n' + 'cliché = "this is a string with unicode, what a cliché"' + ) + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.text = Text(cls.root) + cls.editwin = DummyEditwin(cls.text) + + @classmethod + def tearDownClass(cls): + del cls.text, cls.editwin + cls.root.destroy() + del cls.root + + def setUp(self): + self.text.insert('insert', self.code) + + def tearDown(self): + self.text.delete('1.0', 'end') + self.editwin.context_use_ps1 = True + + def get_parser(self, index): + """ + Return a parser object with index at 'index' + """ + return HyperParser(self.editwin, index) + + def test_init(self): + """ + test corner cases in the init method + """ + with self.assertRaises(ValueError) as ve: + self.text.tag_add('console', '1.0', '1.end') + p = self.get_parser('1.5') + self.assertIn('precedes', str(ve.exception)) + + # test without ps1 + self.editwin.context_use_ps1 = False + + # number of lines lesser than 50 + p = self.get_parser('end') + self.assertEqual(p.rawtext, self.text.get('1.0', 'end')) + + # number of lines greater than 50 + self.text.insert('end', self.text.get('1.0', 'end')*4) + p = self.get_parser('54.5') + + def test_is_in_string(self): + get = self.get_parser + + p = get('1.0') + self.assertFalse(p.is_in_string()) + p = get('1.4') + self.assertTrue(p.is_in_string()) + p = get('2.3') + self.assertFalse(p.is_in_string()) + p = get('3.3') + self.assertFalse(p.is_in_string()) + p = get('3.7') + self.assertTrue(p.is_in_string()) + p = get('4.6') + self.assertTrue(p.is_in_string()) + p = get('12.54') + self.assertTrue(p.is_in_string()) + + def test_is_in_code(self): + get = self.get_parser + + p = get('1.0') + self.assertTrue(p.is_in_code()) + p = get('1.1') + self.assertFalse(p.is_in_code()) + p = get('2.5') + self.assertFalse(p.is_in_code()) + p = get('3.4') + self.assertTrue(p.is_in_code()) + p = get('3.6') + self.assertFalse(p.is_in_code()) + p = get('4.14') + self.assertFalse(p.is_in_code()) + + def test_get_surrounding_bracket(self): + get = self.get_parser + + def without_mustclose(parser): + # a utility function to get surrounding bracket + # with mustclose=False + return parser.get_surrounding_brackets(mustclose=False) + + def with_mustclose(parser): + # a utility function to get surrounding bracket + # with mustclose=True + return parser.get_surrounding_brackets(mustclose=True) + + p = get('3.2') + self.assertIsNone(with_mustclose(p)) + self.assertIsNone(without_mustclose(p)) + + p = get('5.6') + self.assertTupleEqual(without_mustclose(p), ('5.4', '5.25')) + self.assertTupleEqual(without_mustclose(p), with_mustclose(p)) + + p = get('5.23') + self.assertTupleEqual(without_mustclose(p), ('5.21', '5.24')) + self.assertTupleEqual(without_mustclose(p), with_mustclose(p)) + + p = get('6.15') + self.assertTupleEqual(without_mustclose(p), ('6.4', '6.end')) + self.assertIsNone(with_mustclose(p)) + + p = get('9.end') + self.assertIsNone(with_mustclose(p)) + self.assertIsNone(without_mustclose(p)) + + def test_get_expression(self): + get = self.get_parser + + p = get('4.2') + self.assertEqual(p.get_expression(), 'y ') + + p = get('4.7') + with self.assertRaises(ValueError) as ve: + p.get_expression() + self.assertIn('is inside a code', str(ve.exception)) + + p = get('5.25') + self.assertEqual(p.get_expression(), 'range(10)') + + p = get('6.7') + self.assertEqual(p.get_expression(), 'py') + + p = get('6.8') + self.assertEqual(p.get_expression(), '') + + p = get('7.9') + self.assertEqual(p.get_expression(), 'py') + + p = get('8.end') + self.assertEqual(p.get_expression(), 'x.__len__') + + p = get('9.13') + self.assertEqual(p.get_expression(), "r'asdf'") + + p = get('9.17') + with self.assertRaises(ValueError) as ve: + p.get_expression() + self.assertIn('is inside a code', str(ve.exception)) + + p = get('10.0') + self.assertEqual(p.get_expression(), '') + + p = get('10.6') + self.assertEqual(p.get_expression(), '') + + p = get('10.11') + self.assertEqual(p.get_expression(), '') + + p = get('11.3') + self.assertEqual(p.get_expression(), '') + + p = get('11.11') + self.assertEqual(p.get_expression(), 'False') + + p = get('12.6') + self.assertEqual(p.get_expression(), 'cliché') + + def test_eat_identifier(self): + def is_valid_id(candidate): + result = HyperParser._eat_identifier(candidate, 0, len(candidate)) + if result == len(candidate): + return True + elif result == 0: + return False + else: + err_msg = "Unexpected result: {} (expected 0 or {}".format( + result, len(candidate) + ) + raise Exception(err_msg) + + # invalid first character which is valid elsewhere in an identifier + self.assertFalse(is_valid_id('2notid')) + + # ASCII-only valid identifiers + self.assertTrue(is_valid_id('valid_id')) + self.assertTrue(is_valid_id('_valid_id')) + self.assertTrue(is_valid_id('valid_id_')) + self.assertTrue(is_valid_id('_2valid_id')) + + # keywords which should be "eaten" + self.assertTrue(is_valid_id('True')) + self.assertTrue(is_valid_id('False')) + self.assertTrue(is_valid_id('None')) + + # keywords which should not be "eaten" + self.assertFalse(is_valid_id('for')) + self.assertFalse(is_valid_id('import')) + self.assertFalse(is_valid_id('return')) + + # valid unicode identifiers + self.assertTrue(is_valid_id('cliche')) + self.assertTrue(is_valid_id('cliché')) + self.assertTrue(is_valid_id('a٢')) + + # invalid unicode identifiers + self.assertFalse(is_valid_id('2a')) + self.assertFalse(is_valid_id('٢a')) + self.assertFalse(is_valid_id('a²')) + + # valid identifier after "punctuation" + self.assertEqual(HyperParser._eat_identifier('+ var', 0, 5), len('var')) + self.assertEqual(HyperParser._eat_identifier('+var', 0, 4), len('var')) + self.assertEqual(HyperParser._eat_identifier('.var', 0, 4), len('var')) + + # invalid identifiers + self.assertFalse(is_valid_id('+')) + self.assertFalse(is_valid_id(' ')) + self.assertFalse(is_valid_id(':')) + self.assertFalse(is_valid_id('?')) + self.assertFalse(is_valid_id('^')) + self.assertFalse(is_valid_id('\\')) + self.assertFalse(is_valid_id('"')) + self.assertFalse(is_valid_id('"a string"')) + + def test_eat_identifier_various_lengths(self): + eat_id = HyperParser._eat_identifier + + for length in range(1, 21): + self.assertEqual(eat_id('a' * length, 0, length), length) + self.assertEqual(eat_id('é' * length, 0, length), length) + self.assertEqual(eat_id('a' + '2' * (length - 1), 0, length), length) + self.assertEqual(eat_id('é' + '2' * (length - 1), 0, length), length) + self.assertEqual(eat_id('é' + 'a' * (length - 1), 0, length), length) + self.assertEqual(eat_id('é' * (length - 1) + 'a', 0, length), length) + self.assertEqual(eat_id('+' * length, 0, length), 0) + self.assertEqual(eat_id('2' + 'a' * (length - 1), 0, length), 0) + self.assertEqual(eat_id('2' + 'é' * (length - 1), 0, length), 0) + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_idlehistory.py b/Lib/idlelib/idle_test/test_idlehistory.py index b27db9191d0b..d7c3d7039388 100644 --- a/Lib/idlelib/idle_test/test_idlehistory.py +++ b/Lib/idlelib/idle_test/test_idlehistory.py @@ -80,6 +80,7 @@ def setUp(self): @classmethod def tearDownClass(cls): cls.root.destroy() + del cls.root def fetch_test(self, reverse, line, prefix, index, *, bell=False): # Perform one fetch as invoked by Alt-N or Alt-P diff --git a/Lib/idlelib/idle_test/test_io.py b/Lib/idlelib/idle_test/test_io.py new file mode 100644 index 000000000000..e0e3b985e227 --- /dev/null +++ b/Lib/idlelib/idle_test/test_io.py @@ -0,0 +1,233 @@ +import unittest +import io +from idlelib.PyShell import PseudoInputFile, PseudoOutputFile + + +class S(str): + def __str__(self): + return '%s:str' % type(self).__name__ + def __unicode__(self): + return '%s:unicode' % type(self).__name__ + def __len__(self): + return 3 + def __iter__(self): + return iter('abc') + def __getitem__(self, *args): + return '%s:item' % type(self).__name__ + def __getslice__(self, *args): + return '%s:slice' % type(self).__name__ + +class MockShell: + def __init__(self): + self.reset() + + def write(self, *args): + self.written.append(args) + + def readline(self): + return self.lines.pop() + + def close(self): + pass + + def reset(self): + self.written = [] + + def push(self, lines): + self.lines = list(lines)[::-1] + + +class PseudeOutputFilesTest(unittest.TestCase): + def test_misc(self): + shell = MockShell() + f = PseudoOutputFile(shell, 'stdout', 'utf-8') + self.assertIsInstance(f, io.TextIOBase) + self.assertEqual(f.encoding, 'utf-8') + self.assertIsNone(f.errors) + self.assertIsNone(f.newlines) + self.assertEqual(f.name, '') + self.assertFalse(f.closed) + self.assertTrue(f.isatty()) + self.assertFalse(f.readable()) + self.assertTrue(f.writable()) + self.assertFalse(f.seekable()) + + def test_unsupported(self): + shell = MockShell() + f = PseudoOutputFile(shell, 'stdout', 'utf-8') + self.assertRaises(OSError, f.fileno) + self.assertRaises(OSError, f.tell) + self.assertRaises(OSError, f.seek, 0) + self.assertRaises(OSError, f.read, 0) + self.assertRaises(OSError, f.readline, 0) + + def test_write(self): + shell = MockShell() + f = PseudoOutputFile(shell, 'stdout', 'utf-8') + f.write('test') + self.assertEqual(shell.written, [('test', 'stdout')]) + shell.reset() + f.write('t\xe8st') + self.assertEqual(shell.written, [('t\xe8st', 'stdout')]) + shell.reset() + + f.write(S('t\xe8st')) + self.assertEqual(shell.written, [('t\xe8st', 'stdout')]) + self.assertEqual(type(shell.written[0][0]), str) + shell.reset() + + self.assertRaises(TypeError, f.write) + self.assertEqual(shell.written, []) + self.assertRaises(TypeError, f.write, b'test') + self.assertRaises(TypeError, f.write, 123) + self.assertEqual(shell.written, []) + self.assertRaises(TypeError, f.write, 'test', 'spam') + self.assertEqual(shell.written, []) + + def test_writelines(self): + shell = MockShell() + f = PseudoOutputFile(shell, 'stdout', 'utf-8') + f.writelines([]) + self.assertEqual(shell.written, []) + shell.reset() + f.writelines(['one\n', 'two']) + self.assertEqual(shell.written, + [('one\n', 'stdout'), ('two', 'stdout')]) + shell.reset() + f.writelines(['on\xe8\n', 'tw\xf2']) + self.assertEqual(shell.written, + [('on\xe8\n', 'stdout'), ('tw\xf2', 'stdout')]) + shell.reset() + + f.writelines([S('t\xe8st')]) + self.assertEqual(shell.written, [('t\xe8st', 'stdout')]) + self.assertEqual(type(shell.written[0][0]), str) + shell.reset() + + self.assertRaises(TypeError, f.writelines) + self.assertEqual(shell.written, []) + self.assertRaises(TypeError, f.writelines, 123) + self.assertEqual(shell.written, []) + self.assertRaises(TypeError, f.writelines, [b'test']) + self.assertRaises(TypeError, f.writelines, [123]) + self.assertEqual(shell.written, []) + self.assertRaises(TypeError, f.writelines, [], []) + self.assertEqual(shell.written, []) + + def test_close(self): + shell = MockShell() + f = PseudoOutputFile(shell, 'stdout', 'utf-8') + self.assertFalse(f.closed) + f.write('test') + f.close() + self.assertTrue(f.closed) + self.assertRaises(ValueError, f.write, 'x') + self.assertEqual(shell.written, [('test', 'stdout')]) + f.close() + self.assertRaises(TypeError, f.close, 1) + + +class PseudeInputFilesTest(unittest.TestCase): + def test_misc(self): + shell = MockShell() + f = PseudoInputFile(shell, 'stdin', 'utf-8') + self.assertIsInstance(f, io.TextIOBase) + self.assertEqual(f.encoding, 'utf-8') + self.assertIsNone(f.errors) + self.assertIsNone(f.newlines) + self.assertEqual(f.name, '') + self.assertFalse(f.closed) + self.assertTrue(f.isatty()) + self.assertTrue(f.readable()) + self.assertFalse(f.writable()) + self.assertFalse(f.seekable()) + + def test_unsupported(self): + shell = MockShell() + f = PseudoInputFile(shell, 'stdin', 'utf-8') + self.assertRaises(OSError, f.fileno) + self.assertRaises(OSError, f.tell) + self.assertRaises(OSError, f.seek, 0) + self.assertRaises(OSError, f.write, 'x') + self.assertRaises(OSError, f.writelines, ['x']) + + def test_read(self): + shell = MockShell() + f = PseudoInputFile(shell, 'stdin', 'utf-8') + shell.push(['one\n', 'two\n', '']) + self.assertEqual(f.read(), 'one\ntwo\n') + shell.push(['one\n', 'two\n', '']) + self.assertEqual(f.read(-1), 'one\ntwo\n') + shell.push(['one\n', 'two\n', '']) + self.assertEqual(f.read(None), 'one\ntwo\n') + shell.push(['one\n', 'two\n', 'three\n', '']) + self.assertEqual(f.read(2), 'on') + self.assertEqual(f.read(3), 'e\nt') + self.assertEqual(f.read(10), 'wo\nthree\n') + + shell.push(['one\n', 'two\n']) + self.assertEqual(f.read(0), '') + self.assertRaises(TypeError, f.read, 1.5) + self.assertRaises(TypeError, f.read, '1') + self.assertRaises(TypeError, f.read, 1, 1) + + def test_readline(self): + shell = MockShell() + f = PseudoInputFile(shell, 'stdin', 'utf-8') + shell.push(['one\n', 'two\n', 'three\n', 'four\n']) + self.assertEqual(f.readline(), 'one\n') + self.assertEqual(f.readline(-1), 'two\n') + self.assertEqual(f.readline(None), 'three\n') + shell.push(['one\ntwo\n']) + self.assertEqual(f.readline(), 'one\n') + self.assertEqual(f.readline(), 'two\n') + shell.push(['one', 'two', 'three']) + self.assertEqual(f.readline(), 'one') + self.assertEqual(f.readline(), 'two') + shell.push(['one\n', 'two\n', 'three\n']) + self.assertEqual(f.readline(2), 'on') + self.assertEqual(f.readline(1), 'e') + self.assertEqual(f.readline(1), '\n') + self.assertEqual(f.readline(10), 'two\n') + + shell.push(['one\n', 'two\n']) + self.assertEqual(f.readline(0), '') + self.assertRaises(TypeError, f.readlines, 1.5) + self.assertRaises(TypeError, f.readlines, '1') + self.assertRaises(TypeError, f.readlines, 1, 1) + + def test_readlines(self): + shell = MockShell() + f = PseudoInputFile(shell, 'stdin', 'utf-8') + shell.push(['one\n', 'two\n', '']) + self.assertEqual(f.readlines(), ['one\n', 'two\n']) + shell.push(['one\n', 'two\n', '']) + self.assertEqual(f.readlines(-1), ['one\n', 'two\n']) + shell.push(['one\n', 'two\n', '']) + self.assertEqual(f.readlines(None), ['one\n', 'two\n']) + shell.push(['one\n', 'two\n', '']) + self.assertEqual(f.readlines(0), ['one\n', 'two\n']) + shell.push(['one\n', 'two\n', '']) + self.assertEqual(f.readlines(3), ['one\n']) + shell.push(['one\n', 'two\n', '']) + self.assertEqual(f.readlines(4), ['one\n', 'two\n']) + + shell.push(['one\n', 'two\n', '']) + self.assertRaises(TypeError, f.readlines, 1.5) + self.assertRaises(TypeError, f.readlines, '1') + self.assertRaises(TypeError, f.readlines, 1, 1) + + def test_close(self): + shell = MockShell() + f = PseudoInputFile(shell, 'stdin', 'utf-8') + shell.push(['one\n', 'two\n', '']) + self.assertFalse(f.closed) + self.assertEqual(f.readline(), 'one\n') + f.close() + self.assertFalse(f.closed) + self.assertEqual(f.readline(), 'two\n') + self.assertRaises(TypeError, f.close, 1) + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/idlelib/idle_test/test_parenmatch.py b/Lib/idlelib/idle_test/test_parenmatch.py new file mode 100644 index 000000000000..9aba4bec9366 --- /dev/null +++ b/Lib/idlelib/idle_test/test_parenmatch.py @@ -0,0 +1,109 @@ +"""Test idlelib.ParenMatch.""" +# This must currently be a gui test because ParenMatch methods use +# several text methods not defined on idlelib.idle_test.mock_tk.Text. + +import unittest +from unittest.mock import Mock +from test.support import requires +from tkinter import Tk, Text +from idlelib.ParenMatch import ParenMatch + +class DummyEditwin: + def __init__(self, text): + self.text = text + self.indentwidth = 8 + self.tabwidth = 8 + self.context_use_ps1 = True + + +class ParenMatchTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.text = Text(cls.root) + cls.editwin = DummyEditwin(cls.text) + cls.editwin.text_frame = Mock() + + @classmethod + def tearDownClass(cls): + del cls.text, cls.editwin + cls.root.destroy() + del cls.root + + def tearDown(self): + self.text.delete('1.0', 'end') + + def test_paren_expression(self): + """ + Test ParenMatch with 'expression' style. + """ + text = self.text + pm = ParenMatch(self.editwin) + pm.set_style('expression') + + text.insert('insert', 'def foobar(a, b') + pm.flash_paren_event('event') + self.assertIn('<>', text.event_info()) + self.assertTupleEqual(text.tag_prevrange('paren', 'end'), + ('1.10', '1.15')) + text.insert('insert', ')') + pm.restore_event() + self.assertNotIn('<>', text.event_info()) + self.assertEqual(text.tag_prevrange('paren', 'end'), ()) + + # paren_closed_event can only be tested as below + pm.paren_closed_event('event') + self.assertTupleEqual(text.tag_prevrange('paren', 'end'), + ('1.10', '1.16')) + + def test_paren_default(self): + """ + Test ParenMatch with 'default' style. + """ + text = self.text + pm = ParenMatch(self.editwin) + pm.set_style('default') + + text.insert('insert', 'def foobar(a, b') + pm.flash_paren_event('event') + self.assertIn('<>', text.event_info()) + self.assertTupleEqual(text.tag_prevrange('paren', 'end'), + ('1.10', '1.11')) + text.insert('insert', ')') + pm.restore_event() + self.assertNotIn('<>', text.event_info()) + self.assertEqual(text.tag_prevrange('paren', 'end'), ()) + + def test_paren_corner(self): + """ + Test corner cases in flash_paren_event and paren_closed_event. + + These cases force conditional expression and alternate paths. + """ + text = self.text + pm = ParenMatch(self.editwin) + + text.insert('insert', '# this is a commen)') + self.assertIsNone(pm.paren_closed_event('event')) + + text.insert('insert', '\ndef') + self.assertIsNone(pm.flash_paren_event('event')) + self.assertIsNone(pm.paren_closed_event('event')) + + text.insert('insert', ' a, *arg)') + self.assertIsNone(pm.paren_closed_event('event')) + + def test_handle_restore_timer(self): + pm = ParenMatch(self.editwin) + pm.restore_event = Mock() + pm.handle_restore_timer(0) + self.assertTrue(pm.restore_event.called) + pm.restore_event.reset_mock() + pm.handle_restore_timer(1) + self.assertFalse(pm.restore_event.called) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_pathbrowser.py b/Lib/idlelib/idle_test/test_pathbrowser.py index 7ad7c97a79e8..afb886fa3305 100644 --- a/Lib/idlelib/idle_test/test_pathbrowser.py +++ b/Lib/idlelib/idle_test/test_pathbrowser.py @@ -1,5 +1,8 @@ import unittest -import idlelib.PathBrowser as PathBrowser +import os +import sys +import idlelib +from idlelib import PathBrowser class PathBrowserTest(unittest.TestCase): @@ -7,6 +10,18 @@ def test_DirBrowserTreeItem(self): # Issue16226 - make sure that getting a sublist works d = PathBrowser.DirBrowserTreeItem('') d.GetSubList() + self.assertEqual('', d.GetText()) + + dir = os.path.split(os.path.abspath(idlelib.__file__))[0] + self.assertEqual(d.ispackagedir(dir), True) + self.assertEqual(d.ispackagedir(dir + '/Icons'), False) + + def test_PathBrowserTreeItem(self): + p = PathBrowser.PathBrowserTreeItem() + self.assertEqual(p.GetText(), 'sys.path') + sub = p.GetSubList() + self.assertEqual(len(sub), len(sys.path)) + self.assertEqual(type(sub[0]), PathBrowser.DirBrowserTreeItem) if __name__ == '__main__': unittest.main(verbosity=2, exit=False) diff --git a/Lib/idlelib/idle_test/test_searchdialogbase.py b/Lib/idlelib/idle_test/test_searchdialogbase.py new file mode 100644 index 000000000000..8036b918c593 --- /dev/null +++ b/Lib/idlelib/idle_test/test_searchdialogbase.py @@ -0,0 +1,165 @@ +'''Unittests for idlelib/SearchDialogBase.py + +Coverage: 99%. The only thing not covered is inconsequential -- +testing skipping of suite when self.needwrapbutton is false. + +''' +import unittest +from test.support import requires +from tkinter import Tk, Toplevel, Frame ##, BooleanVar, StringVar +from idlelib import SearchEngine as se +from idlelib import SearchDialogBase as sdb +from idlelib.idle_test.mock_idle import Func +## from idlelib.idle_test.mock_tk import Var + +# The ## imports above & following could help make some tests gui-free. +# However, they currently make radiobutton tests fail. +##def setUpModule(): +## # Replace tk objects used to initialize se.SearchEngine. +## se.BooleanVar = Var +## se.StringVar = Var +## +##def tearDownModule(): +## se.BooleanVar = BooleanVar +## se.StringVar = StringVar + +class SearchDialogBaseTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + + @classmethod + def tearDownClass(cls): + cls.root.destroy() + del cls.root + + def setUp(self): + self.engine = se.SearchEngine(self.root) # None also seems to work + self.dialog = sdb.SearchDialogBase(root=self.root, engine=self.engine) + + def tearDown(self): + self.dialog.close() + + def test_open_and_close(self): + # open calls create_widgets, which needs default_command + self.dialog.default_command = None + + # Since text parameter of .open is not used in base class, + # pass dummy 'text' instead of tk.Text(). + self.dialog.open('text') + self.assertEqual(self.dialog.top.state(), 'normal') + self.dialog.close() + self.assertEqual(self.dialog.top.state(), 'withdrawn') + + self.dialog.open('text', searchphrase="hello") + self.assertEqual(self.dialog.ent.get(), 'hello') + self.dialog.close() + + def test_create_widgets(self): + self.dialog.create_entries = Func() + self.dialog.create_option_buttons = Func() + self.dialog.create_other_buttons = Func() + self.dialog.create_command_buttons = Func() + + self.dialog.default_command = None + self.dialog.create_widgets() + + self.assertTrue(self.dialog.create_entries.called) + self.assertTrue(self.dialog.create_option_buttons.called) + self.assertTrue(self.dialog.create_other_buttons.called) + self.assertTrue(self.dialog.create_command_buttons.called) + + def test_make_entry(self): + equal = self.assertEqual + self.dialog.row = 0 + self.dialog.top = Toplevel(self.root) + entry, label = self.dialog.make_entry("Test:", 'hello') + equal(label['text'], 'Test:') + + self.assertIn(entry.get(), 'hello') + egi = entry.grid_info() + equal(int(egi['row']), 0) + equal(int(egi['column']), 1) + equal(int(egi['rowspan']), 1) + equal(int(egi['columnspan']), 1) + equal(self.dialog.row, 1) + + def test_create_entries(self): + self.dialog.row = 0 + self.engine.setpat('hello') + self.dialog.create_entries() + self.assertIn(self.dialog.ent.get(), 'hello') + + def test_make_frame(self): + self.dialog.row = 0 + self.dialog.top = Toplevel(self.root) + frame, label = self.dialog.make_frame() + self.assertEqual(label, '') + self.assertIsInstance(frame, Frame) + + frame, label = self.dialog.make_frame('testlabel') + self.assertEqual(label['text'], 'testlabel') + self.assertIsInstance(frame, Frame) + + def btn_test_setup(self, meth): + self.dialog.top = Toplevel(self.root) + self.dialog.row = 0 + return meth() + + def test_create_option_buttons(self): + e = self.engine + for state in (0, 1): + for var in (e.revar, e.casevar, e.wordvar, e.wrapvar): + var.set(state) + frame, options = self.btn_test_setup( + self.dialog.create_option_buttons) + for spec, button in zip (options, frame.pack_slaves()): + var, label = spec + self.assertEqual(button['text'], label) + self.assertEqual(var.get(), state) + if state == 1: + button.deselect() + else: + button.select() + self.assertEqual(var.get(), 1 - state) + + def test_create_other_buttons(self): + for state in (False, True): + var = self.engine.backvar + var.set(state) + frame, others = self.btn_test_setup( + self.dialog.create_other_buttons) + buttons = frame.pack_slaves() + for spec, button in zip(others, buttons): + val, label = spec + self.assertEqual(button['text'], label) + if val == state: + # hit other button, then this one + # indexes depend on button order + self.assertEqual(var.get(), state) + buttons[val].select() + self.assertEqual(var.get(), 1 - state) + buttons[1-val].select() + self.assertEqual(var.get(), state) + + def test_make_button(self): + self.dialog.top = Toplevel(self.root) + self.dialog.buttonframe = Frame(self.dialog.top) + btn = self.dialog.make_button('Test', self.dialog.close) + self.assertEqual(btn['text'], 'Test') + + def test_create_command_buttons(self): + self.dialog.create_command_buttons() + # Look for close button command in buttonframe + closebuttoncommand = '' + for child in self.dialog.buttonframe.winfo_children(): + if child['text'] == 'close': + closebuttoncommand = child['command'] + self.assertIn('close', closebuttoncommand) + + + +if __name__ == '__main__': + unittest.main(verbosity=2, exit=2) diff --git a/Lib/idlelib/idle_test/test_searchengine.py b/Lib/idlelib/idle_test/test_searchengine.py index fdf38bd0ba2a..edbd55813396 100644 --- a/Lib/idlelib/idle_test/test_searchengine.py +++ b/Lib/idlelib/idle_test/test_searchengine.py @@ -7,7 +7,7 @@ import re import unittest -from test.support import requires +# from test.support import requires from tkinter import BooleanVar, StringVar, TclError # ,Tk, Text import tkinter.messagebox as tkMessageBox from idlelib import SearchEngine as se @@ -64,6 +64,7 @@ class GetSelectionTest(unittest.TestCase): ## @classmethod ## def tearDownClass(cls): ## cls.root.destroy() +## del cls.root def test_get_selection(self): # text = Text(master=self.root) @@ -177,7 +178,7 @@ def test_getprog(self): engine.revar.set(1) Equal(engine.getprog(), None) self.assertEqual(Mbox.showerror.message, - 'Error: nothing to repeat\nPattern: +') + 'Error: nothing to repeat at position 0\nPattern: +') def test_report_error(self): showerror = Mbox.showerror @@ -219,6 +220,7 @@ def setUpClass(cls): ## @classmethod ## def tearDownClass(cls): ## cls.root.destroy() +## del cls.root def test_search(self): Equal = self.assertEqual @@ -261,6 +263,7 @@ class ForwardBackwardTest(unittest.TestCase): ## @classmethod ## def tearDownClass(cls): ## cls.root.destroy() +## del cls.root @classmethod def setUpClass(cls): diff --git a/Lib/idlelib/idle_test/test_text.py b/Lib/idlelib/idle_test/test_text.py index 367bf3849863..7e823df3db8a 100644 --- a/Lib/idlelib/idle_test/test_text.py +++ b/Lib/idlelib/idle_test/test_text.py @@ -3,7 +3,6 @@ from test.support import requires from _tkinter import TclError -import tkinter as tk class TextTest(object): @@ -221,6 +220,7 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): cls.root.destroy() + del cls.root if __name__ == '__main__': diff --git a/Lib/idlelib/idle_test/test_textview.py b/Lib/idlelib/idle_test/test_textview.py new file mode 100644 index 000000000000..68e5b82ad912 --- /dev/null +++ b/Lib/idlelib/idle_test/test_textview.py @@ -0,0 +1,97 @@ +'''Test the functions and main class method of textView.py. + +Since all methods and functions create (or destroy) a TextViewer, which +is a widget containing multiple widgets, all tests must be gui tests. +Using mock Text would not change this. Other mocks are used to retrieve +information about calls. + +The coverage is essentially 100%. +''' +from test.support import requires +requires('gui') + +import unittest +import os +from tkinter import Tk +from idlelib import textView as tv +from idlelib.idle_test.mock_idle import Func +from idlelib.idle_test.mock_tk import Mbox + +def setUpModule(): + global root + root = Tk() + +def tearDownModule(): + global root + root.destroy() # pyflakes falsely sees root as undefined + del root + + +class TV(tv.TextViewer): # used by TextViewTest + transient = Func() + grab_set = Func() + wait_window = Func() + +class TextViewTest(unittest.TestCase): + + def setUp(self): + TV.transient.__init__() + TV.grab_set.__init__() + TV.wait_window.__init__() + + def test_init_modal(self): + view = TV(root, 'Title', 'test text') + self.assertTrue(TV.transient.called) + self.assertTrue(TV.grab_set.called) + self.assertTrue(TV.wait_window.called) + view.Ok() + + def test_init_nonmodal(self): + view = TV(root, 'Title', 'test text', modal=False) + self.assertFalse(TV.transient.called) + self.assertFalse(TV.grab_set.called) + self.assertFalse(TV.wait_window.called) + view.Ok() + + def test_ok(self): + view = TV(root, 'Title', 'test text', modal=False) + view.destroy = Func() + view.Ok() + self.assertTrue(view.destroy.called) + del view.destroy # unmask real function + view.destroy + + +class textviewTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + cls.orig_mbox = tv.tkMessageBox + tv.tkMessageBox = Mbox + + @classmethod + def tearDownClass(cls): + tv.tkMessageBox = cls.orig_mbox + del cls.orig_mbox + + def test_view_text(self): + # If modal True, tkinter will error with 'can't invoke "event" command' + view = tv.view_text(root, 'Title', 'test text', modal=False) + self.assertIsInstance(view, tv.TextViewer) + + def test_view_file(self): + test_dir = os.path.dirname(__file__) + testfile = os.path.join(test_dir, 'test_textview.py') + view = tv.view_file(root, 'Title', testfile, modal=False) + self.assertIsInstance(view, tv.TextViewer) + self.assertIn('Test', view.textView.get('1.0', '1.end')) + view.Ok() + + # Mock messagebox will be used and view_file will not return anything + testfile = os.path.join(test_dir, '../notthere.py') + view = tv.view_file(root, 'Title', testfile, modal=False) + self.assertIsNone(view) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_warning.py b/Lib/idlelib/idle_test/test_warning.py index 18627ddd2310..54ac993e881e 100644 --- a/Lib/idlelib/idle_test/test_warning.py +++ b/Lib/idlelib/idle_test/test_warning.py @@ -68,6 +68,15 @@ def test_shell_show(self): 'Test', UserWarning, 'test_warning.py', 99, f, 'Line of code') self.assertEqual(shellmsg.splitlines(), f.getvalue().splitlines()) +class ImportWarnTest(unittest.TestCase): + def test_idlever(self): + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + import idlelib.idlever + self.assertEqual(len(w), 1) + self.assertTrue(issubclass(w[-1].category, DeprecationWarning)) + self.assertIn("version", str(w[-1].message)) + if __name__ == '__main__': unittest.main(verbosity=2, exit=False) diff --git a/Lib/idlelib/idle_test/test_widgetredir.py b/Lib/idlelib/idle_test/test_widgetredir.py new file mode 100644 index 000000000000..64405615a0c9 --- /dev/null +++ b/Lib/idlelib/idle_test/test_widgetredir.py @@ -0,0 +1,122 @@ +"""Unittest for idlelib.WidgetRedirector + +100% coverage +""" +from test.support import requires +import unittest +from idlelib.idle_test.mock_idle import Func +from tkinter import Tk, Text, TclError +from idlelib.WidgetRedirector import WidgetRedirector + + +class InitCloseTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.tk = Tk() + cls.text = Text(cls.tk) + + @classmethod + def tearDownClass(cls): + cls.text.destroy() + cls.tk.destroy() + del cls.text, cls.tk + + def test_init(self): + redir = WidgetRedirector(self.text) + self.assertEqual(redir.widget, self.text) + self.assertEqual(redir.tk, self.text.tk) + self.assertRaises(TclError, WidgetRedirector, self.text) + redir.close() # restore self.tk, self.text + + def test_close(self): + redir = WidgetRedirector(self.text) + redir.register('insert', Func) + redir.close() + self.assertEqual(redir._operations, {}) + self.assertFalse(hasattr(self.text, 'widget')) + + +class WidgetRedirectorTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.tk = Tk() + cls.text = Text(cls.tk) + + @classmethod + def tearDownClass(cls): + cls.text.destroy() + cls.tk.destroy() + del cls.text, cls.tk + + def setUp(self): + self.redir = WidgetRedirector(self.text) + self.func = Func() + self.orig_insert = self.redir.register('insert', self.func) + self.text.insert('insert', 'asdf') # leaves self.text empty + + def tearDown(self): + self.text.delete('1.0', 'end') + self.redir.close() + + def test_repr(self): # partly for 100% coverage + self.assertIn('Redirector', repr(self.redir)) + self.assertIn('Original', repr(self.orig_insert)) + + def test_register(self): + self.assertEqual(self.text.get('1.0', 'end'), '\n') + self.assertEqual(self.func.args, ('insert', 'asdf')) + self.assertIn('insert', self.redir._operations) + self.assertIn('insert', self.text.__dict__) + self.assertEqual(self.text.insert, self.func) + + def test_original_command(self): + self.assertEqual(self.orig_insert.operation, 'insert') + self.assertEqual(self.orig_insert.tk_call, self.text.tk.call) + self.orig_insert('insert', 'asdf') + self.assertEqual(self.text.get('1.0', 'end'), 'asdf\n') + + def test_unregister(self): + self.assertIsNone(self.redir.unregister('invalid operation name')) + self.assertEqual(self.redir.unregister('insert'), self.func) + self.assertNotIn('insert', self.redir._operations) + self.assertNotIn('insert', self.text.__dict__) + + def test_unregister_no_attribute(self): + del self.text.insert + self.assertEqual(self.redir.unregister('insert'), self.func) + + def test_dispatch_intercept(self): + self.func.__init__(True) + self.assertTrue(self.redir.dispatch('insert', False)) + self.assertFalse(self.func.args[0]) + + def test_dispatch_bypass(self): + self.orig_insert('insert', 'asdf') + # tk.call returns '' where Python would return None + self.assertEqual(self.redir.dispatch('delete', '1.0', 'end'), '') + self.assertEqual(self.text.get('1.0', 'end'), '\n') + + def test_dispatch_error(self): + self.func.__init__(TclError()) + self.assertEqual(self.redir.dispatch('insert', False), '') + self.assertEqual(self.redir.dispatch('invalid'), '') + + def test_command_dispatch(self): + # Test that .__init__ causes redirection of tk calls + # through redir.dispatch + self.tk.call(self.text._w, 'insert', 'hello') + self.assertEqual(self.func.args, ('hello',)) + self.assertEqual(self.text.get('1.0', 'end'), '\n') + # Ensure that called through redir .dispatch and not through + # self.text.insert by having mock raise TclError. + self.func.__init__(TclError()) + self.assertEqual(self.tk.call(self.text._w, 'insert', 'boo'), '') + + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idlever.py b/Lib/idlelib/idlever.py index cd2c8bfc3958..3e9f69a3e372 100644 --- a/Lib/idlelib/idlever.py +++ b/Lib/idlelib/idlever.py @@ -1 +1,12 @@ -IDLE_VERSION = "3.4.0b1" +""" +The separate Idle version was eliminated years ago; +idlelib.idlever is no longer used by Idle +and will be removed in 3.6 or later. Use + from sys import version + IDLE_VERSION = version[:version.index(' ')] +""" +# Kept for now only for possible existing extension use +import warnings as w +w.warn(__doc__, DeprecationWarning, stacklevel=2) +from sys import version +IDLE_VERSION = version[:version.index(' ')] diff --git a/Lib/idlelib/keybindingDialog.py b/Lib/idlelib/keybindingDialog.py index 0f0da8c7e930..e6438bfc39cb 100644 --- a/Lib/idlelib/keybindingDialog.py +++ b/Lib/idlelib/keybindingDialog.py @@ -4,15 +4,16 @@ from tkinter import * import tkinter.messagebox as tkMessageBox import string -from idlelib import macosxSupport +import sys class GetKeysDialog(Toplevel): - def __init__(self,parent,title,action,currentKeySequences): + def __init__(self,parent,title,action,currentKeySequences,_htest=False): """ action - string, the name of the virtual event these keys will be mapped to currentKeys - list, a list of all key sequence lists currently mapped to virtual events, for overlap checking + _htest - bool, change box location when running htest """ Toplevel.__init__(self, parent) self.configure(borderwidth=5) @@ -38,11 +39,14 @@ def __init__(self,parent,title,action,currentKeySequences): self.LoadFinalKeyList() self.withdraw() #hide while setting geometry self.update_idletasks() - self.geometry("+%d+%d" % - ((parent.winfo_rootx()+((parent.winfo_width()/2) - -(self.winfo_reqwidth()/2)), - parent.winfo_rooty()+((parent.winfo_height()/2) - -(self.winfo_reqheight()/2)) )) ) #centre dialog over parent + self.geometry( + "+%d+%d" % ( + parent.winfo_rootx() + + (parent.winfo_width()/2 - self.winfo_reqwidth()/2), + parent.winfo_rooty() + + ((parent.winfo_height()/2 - self.winfo_reqheight()/2) + if not _htest else 150) + ) ) #centre dialog over parent (or below htest box) self.deiconify() #geometry set, unhide self.wait_window() @@ -133,8 +137,7 @@ def SetModifiersForPlatform(self): order is also important: key binding equality depends on it, so config-keys.def must use the same ordering. """ - import sys - if macosxSupport.runningAsOSXApp(): + if sys.platform == "darwin": self.modifiers = ['Shift', 'Control', 'Option', 'Command'] else: self.modifiers = ['Control', 'Alt', 'Shift'] @@ -259,11 +262,5 @@ def KeysOK(self): return keysOK if __name__ == '__main__': - #test the dialog - root=Tk() - def run(): - keySeq='' - dlg=GetKeysDialog(root,'Get Keys','find-again',[]) - print(dlg.result) - Button(root,text='Dialog',command=run).pack() - root.mainloop() + from idlelib.idle_test.htest import run + run(GetKeysDialog) diff --git a/Lib/idlelib/macosxSupport.py b/Lib/idlelib/macosxSupport.py index 67069fa0f393..b96bae1d5508 100644 --- a/Lib/idlelib/macosxSupport.py +++ b/Lib/idlelib/macosxSupport.py @@ -1,48 +1,70 @@ """ -A number of function that enhance IDLE on MacOSX when it used as a normal -GUI application (as opposed to an X11 application). +A number of functions that enhance IDLE on Mac OSX. """ import sys import tkinter from os import path +import warnings +def runningAsOSXApp(): + warnings.warn("runningAsOSXApp() is deprecated, use isAquaTk()", + DeprecationWarning, stacklevel=2) + return isAquaTk() -_appbundle = None +def isCarbonAquaTk(root): + warnings.warn("isCarbonAquaTk(root) is deprecated, use isCarbonTk()", + DeprecationWarning, stacklevel=2) + return isCarbonTk() -def runningAsOSXApp(): +_tk_type = None + +def _initializeTkVariantTests(root): + """ + Initializes OS X Tk variant values for + isAquaTk(), isCarbonTk(), isCocoaTk(), and isXQuartz(). """ - Returns True if Python is running from within an app on OSX. - If so, the various OS X customizations will be triggered later (menu - fixup, et al). (Originally, this test was supposed to condition - behavior on whether IDLE was running under Aqua Tk rather than - under X11 Tk but that does not work since a framework build - could be linked with X11. For several releases, this test actually - differentiates between whether IDLE is running from a framework or - not. As a future enhancement, it should be considered whether there - should be a difference based on framework and any needed X11 adaptions - should be made dependent on a new function that actually tests for X11.) - """ - global _appbundle - if _appbundle is None: - _appbundle = sys.platform == 'darwin' - if _appbundle: - import sysconfig - _appbundle = bool(sysconfig.get_config_var('PYTHONFRAMEWORK')) - return _appbundle - -_carbonaquatk = None + global _tk_type + if sys.platform == 'darwin': + ws = root.tk.call('tk', 'windowingsystem') + if 'x11' in ws: + _tk_type = "xquartz" + elif 'aqua' not in ws: + _tk_type = "other" + elif 'AppKit' in root.tk.call('winfo', 'server', '.'): + _tk_type = "cocoa" + else: + _tk_type = "carbon" + else: + _tk_type = "other" -def isCarbonAquaTk(root): +def isAquaTk(): + """ + Returns True if IDLE is using a native OS X Tk (Cocoa or Carbon). + """ + assert _tk_type is not None + return _tk_type == "cocoa" or _tk_type == "carbon" + +def isCarbonTk(): """ Returns True if IDLE is using a Carbon Aqua Tk (instead of the newer Cocoa Aqua Tk). """ - global _carbonaquatk - if _carbonaquatk is None: - _carbonaquatk = (runningAsOSXApp() and - 'aqua' in root.tk.call('tk', 'windowingsystem') and - 'AppKit' not in root.tk.call('winfo', 'server', '.')) - return _carbonaquatk + assert _tk_type is not None + return _tk_type == "carbon" + +def isCocoaTk(): + """ + Returns True if IDLE is using a Cocoa Aqua Tk. + """ + assert _tk_type is not None + return _tk_type == "cocoa" + +def isXQuartz(): + """ + Returns True if IDLE is using an OS X X11 Tk. + """ + assert _tk_type is not None + return _tk_type == "xquartz" def tkVersionWarning(root): """ @@ -53,8 +75,7 @@ def tkVersionWarning(root): can still crash unexpectedly. """ - if (runningAsOSXApp() and - ('AppKit' in root.tk.call('winfo', 'server', '.')) ): + if isCocoaTk(): patchlevel = root.tk.call('info', 'patchlevel') if patchlevel not in ('8.5.7', '8.5.9'): return False @@ -88,8 +109,8 @@ def hideTkConsole(root): def overrideRootMenu(root, flist): """ - Replace the Tk root menu by something that's more appropriate for - IDLE. + Replace the Tk root menu by something that is more appropriate for + IDLE with an Aqua Tk. """ # The menu that is attached to the Tk root (".") is also used by AquaTk for # all windows that don't specify a menu of their own. The default menubar @@ -102,17 +123,29 @@ def overrideRootMenu(root, flist): # # Due to a (mis-)feature of TkAqua the user will also see an empty Help # menu. - from tkinter import Menu, Text, Text - from idlelib.EditorWindow import prepstr, get_accelerator + from tkinter import Menu from idlelib import Bindings from idlelib import WindowList - from idlelib.MultiCall import MultiCallCreator + closeItem = Bindings.menudefs[0][1][-2] + + # Remove the last 3 items of the file menu: a separator, close window and + # quit. Close window will be reinserted just above the save item, where + # it should be according to the HIG. Quit is in the application menu. + del Bindings.menudefs[0][1][-3:] + Bindings.menudefs[0][1].insert(6, closeItem) + + # Remove the 'About' entry from the help menu, it is in the application + # menu + del Bindings.menudefs[-1][1][0:2] + # Remove the 'Configure Idle' entry from the options menu, it is in the + # application menu as 'Preferences' + del Bindings.menudefs[-2][1][0] menubar = Menu(root) root.configure(menu=menubar) menudict = {} - menudict['windows'] = menu = Menu(menubar, name='windows') + menudict['windows'] = menu = Menu(menubar, name='windows', tearoff=0) menubar.add_cascade(label='Window', menu=menu, underline=0) def postwindowsmenu(menu=menu): @@ -126,10 +159,14 @@ def postwindowsmenu(menu=menu): WindowList.register_callback(postwindowsmenu) def about_dialog(event=None): + "Handle Help 'About IDLE' event." + # Synchronize with EditorWindow.EditorWindow.about_dialog. from idlelib import aboutDialog aboutDialog.AboutDialog(root, 'About IDLE') def config_dialog(event=None): + "Handle Options 'Configure IDLE' event." + # Synchronize with EditorWindow.EditorWindow.config_dialog. from idlelib import configDialog # Ensure that the root object has an instance_dict attribute, @@ -137,13 +174,13 @@ def config_dialog(event=None): # on an EditorWindow instance that is then passed as the first # argument to ConfigDialog) root.instance_dict = flist.inversedict - root.instance_dict = flist.inversedict configDialog.ConfigDialog(root, 'Settings') def help_dialog(event=None): - from idlelib import textView - fn = path.join(path.abspath(path.dirname(__file__)), 'help.txt') - textView.view_file(root, 'Help', fn) + "Handle Help 'IDLE Help' event." + # Synchronize with EditorWindow.EditorWindow.help_dialog. + from idlelib import help + help.show_idlehelp(root) root.bind('<>', about_dialog) root.bind('<>', config_dialog) @@ -156,9 +193,10 @@ def help_dialog(event=None): # right thing for now. root.createcommand('exit', flist.close_all_callback) - if isCarbonAquaTk(root): + if isCarbonTk(): # for Carbon AquaTk, replace the default Tk apple menu - menudict['application'] = menu = Menu(menubar, name='apple') + menudict['application'] = menu = Menu(menubar, name='apple', + tearoff=0) menubar.add_cascade(label='IDLE', menu=menu) Bindings.menudefs.insert(0, ('application', [ @@ -171,8 +209,7 @@ def help_dialog(event=None): Bindings.menudefs[0][1].append( ('_Preferences....', '<>'), ) - else: - # assume Cocoa AquaTk + if isCocoaTk(): # replace default About dialog with About IDLE one root.createcommand('tkAboutDialog', about_dialog) # replace default "Help" item in Help menu @@ -182,10 +219,22 @@ def help_dialog(event=None): def setupApp(root, flist): """ - Perform setup for the OSX application bundle. + Perform initial OS X customizations if needed. + Called from PyShell.main() after initial calls to Tk() + + There are currently three major versions of Tk in use on OS X: + 1. Aqua Cocoa Tk (native default since OS X 10.6) + 2. Aqua Carbon Tk (original native, 32-bit only, deprecated) + 3. X11 (supported by some third-party distributors, deprecated) + There are various differences among the three that affect IDLE + behavior, primarily with menus, mouse key events, and accelerators. + Some one-time customizations are performed here. + Others are dynamically tested throughout idlelib by calls to the + isAquaTk(), isCarbonTk(), isCocoaTk(), isXQuartz() functions which + are initialized here as well. """ - if not runningAsOSXApp(): return - - hideTkConsole(root) - overrideRootMenu(root, flist) - addOpenEventSupport(root, flist) + _initializeTkVariantTests(root) + if isAquaTk(): + hideTkConsole(root) + overrideRootMenu(root, flist) + addOpenEventSupport(root, flist) diff --git a/Lib/idlelib/rpc.py b/Lib/idlelib/rpc.py index 9c51b8f6b521..aa33041e7b3e 100644 --- a/Lib/idlelib/rpc.py +++ b/Lib/idlelib/rpc.py @@ -29,6 +29,7 @@ import sys import os +import io import socket import select import socketserver @@ -53,16 +54,15 @@ def pickle_code(co): ms = marshal.dumps(co) return unpickle_code, (ms,) -# XXX KBK 24Aug02 function pickling capability not used in Idle -# def unpickle_function(ms): -# return ms +def dumps(obj, protocol=None): + f = io.BytesIO() + p = CodePickler(f, protocol) + p.dump(obj) + return f.getvalue() -# def pickle_function(fn): -# assert isinstance(fn, type.FunctionType) -# return repr(fn) - -copyreg.pickle(types.CodeType, pickle_code, unpickle_code) -# copyreg.pickle(types.FunctionType, pickle_function, unpickle_function) +class CodePickler(pickle.Pickler): + dispatch_table = {types.CodeType: pickle_code} + dispatch_table.update(copyreg.dispatch_table) BUFSIZE = 8*1024 LOCALHOST = '127.0.0.1' @@ -329,7 +329,7 @@ def newseq(self): def putmessage(self, message): self.debug("putmessage:%d:" % message[0]) try: - s = pickle.dumps(message) + s = dumps(message) except pickle.PicklingError: print("Cannot pickle:", repr(message), file=sys.__stderr__) raise @@ -340,10 +340,7 @@ def putmessage(self, message): n = self.sock.send(s[:BUFSIZE]) except (AttributeError, TypeError): raise OSError("socket no longer exists") - except OSError: - raise - else: - s = s[n:] + s = s[n:] buff = b'' bufneed = 4 diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 13cec62976bd..595e7bc3aa11 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -1,8 +1,6 @@ import sys -import io import linecache import time -import socket import traceback import _thread as thread import threading @@ -176,7 +174,7 @@ def show_socket_error(err, address): tkMessageBox.showerror("IDLE Subprocess Error", msg, parent=root) else: tkMessageBox.showerror("IDLE Subprocess Error", - "Socket Error: %s" % err.args[1]) + "Socket Error: %s" % err.args[1], parent=root) root.destroy() def print_exception(): diff --git a/Lib/idlelib/tabbedpages.py b/Lib/idlelib/tabbedpages.py index 255773275586..965f9f8593dc 100644 --- a/Lib/idlelib/tabbedpages.py +++ b/Lib/idlelib/tabbedpages.py @@ -467,9 +467,12 @@ def change_page(self, page_name): self._tab_set.set_selected_tab(page_name) -if __name__ == '__main__': +def _tabbed_pages(parent): # test dialog root=Tk() + width, height, x, y = list(map(int, re.split('[x+]', parent.geometry()))) + root.geometry("+%d+%d"%(x, y + 175)) + root.title("Test tabbed pages") tabPage=TabbedPageSet(root, page_names=['Foobar','Baz'], n_rows=0, expand_tabs=False, ) @@ -488,3 +491,8 @@ def change_page(self, page_name): labelPgName.pack(padx=5) entryPgName.pack(padx=5) root.mainloop() + + +if __name__ == '__main__': + from idlelib.idle_test.htest import run + run(_tabbed_pages) diff --git a/Lib/idlelib/testcode.py b/Lib/idlelib/testcode.py deleted file mode 100644 index 05eaa562cd1b..000000000000 --- a/Lib/idlelib/testcode.py +++ /dev/null @@ -1,31 +0,0 @@ -import string - -def f(): - a = 0 - b = 1 - c = 2 - d = 3 - e = 4 - g() - -def g(): - h() - -def h(): - i() - -def i(): - j() - -def j(): - k() - -def k(): - l() - -l = lambda: test() - -def test(): - string.capwords(1) - -f() diff --git a/Lib/idlelib/textView.py b/Lib/idlelib/textView.py index dd50544c41a1..01b2d8f4ab6e 100644 --- a/Lib/idlelib/textView.py +++ b/Lib/idlelib/textView.py @@ -9,15 +9,21 @@ class TextViewer(Toplevel): """A simple text viewer dialog for IDLE """ - def __init__(self, parent, title, text, modal=True): + def __init__(self, parent, title, text, modal=True, _htest=False): """Show the given text in a scrollable window with a 'close' button + If modal option set to False, user can interact with other windows, + otherwise they will be unable to interact with other windows until + the textview window is closed. + + _htest - bool; change box location when running htest. """ Toplevel.__init__(self, parent) self.configure(borderwidth=5) - self.geometry("=%dx%d+%d+%d" % (625, 500, - parent.winfo_rootx() + 10, - parent.winfo_rooty() + 10)) + # place dialog below parent if running htest + self.geometry("=%dx%d+%d+%d" % (750, 500, + parent.winfo_rootx() + 10, + parent.winfo_rooty() + (10 if not _htest else 100))) #elguavas - config placeholders til config stuff completed self.bg = '#ffffff' self.fg = '#000000' @@ -66,32 +72,15 @@ def view_file(parent, title, filename, encoding=None, modal=True): try: with open(filename, 'r', encoding=encoding) as file: contents = file.read() - except OSError: - import tkinter.messagebox as tkMessageBox + except IOError: tkMessageBox.showerror(title='File Load Error', message='Unable to load file %r .' % filename, parent=parent) else: return view_text(parent, title, contents, modal) - if __name__ == '__main__': - #test the dialog - root=Tk() - root.title('textView test') - filename = './textView.py' - with open(filename, 'r') as f: - text = f.read() - btn1 = Button(root, text='view_text', - command=lambda:view_text(root, 'view_text', text)) - btn1.pack(side=LEFT) - btn2 = Button(root, text='view_file', - command=lambda:view_file(root, 'view_file', filename)) - btn2.pack(side=LEFT) - btn3 = Button(root, text='nonmodal view_text', - command=lambda:view_text(root, 'nonmodal view_text', text, - modal=False)) - btn3.pack(side=LEFT) - close = Button(root, text='Close', command=root.destroy) - close.pack(side=RIGHT) - root.mainloop() + import unittest + unittest.main('idlelib.idle_test.test_textview', verbosity=2, exit=False) + from idlelib.idle_test.htest import run + run(TextViewer) diff --git a/Lib/imaplib.py b/Lib/imaplib.py index dabf161b87aa..4e8a4bb6fa47 100644 --- a/Lib/imaplib.py +++ b/Lib/imaplib.py @@ -45,11 +45,12 @@ # Maximal line length when calling readline(). This is to prevent # reading arbitrary length lines. RFC 3501 and 2060 (IMAP 4rev1) -# don't specify a line length. RFC 2683 however suggests limiting client -# command lines to 1000 octets and server command lines to 8000 octets. -# We have selected 10000 for some extra margin and since that is supposedly -# also what UW and Panda IMAP does. -_MAXLINE = 10000 +# don't specify a line length. RFC 2683 suggests limiting client +# command lines to 1000 octets and that servers should be prepared +# to accept command lines up to 8000 octets, so we used to use 10K here. +# In the modern world (eg: gmail) the response to, for example, a +# search command can be quite large, so we now use 1M. +_MAXLINE = 1000000 # Commands @@ -65,6 +66,7 @@ 'CREATE': ('AUTH', 'SELECTED'), 'DELETE': ('AUTH', 'SELECTED'), 'DELETEACL': ('AUTH', 'SELECTED'), + 'ENABLE': ('AUTH', ), 'EXAMINE': ('AUTH', 'SELECTED'), 'EXPUNGE': ('SELECTED',), 'FETCH': ('SELECTED',), @@ -106,12 +108,17 @@ br' (?P[0-9][0-9]):(?P[0-9][0-9]):(?P[0-9][0-9])' br' (?P[-+])(?P[0-9][0-9])(?P[0-9][0-9])' br'"') +# Literal is no longer used; kept for backward compatibility. Literal = re.compile(br'.*{(?P\d+)}$', re.ASCII) MapCRLF = re.compile(br'\r\n|\r|\n') Response_code = re.compile(br'\[(?P[A-Z-]+)( (?P[^\]]*))?\]') Untagged_response = re.compile(br'\* (?P[A-Z-]+)( (?P.*))?') +# Untagged_status is no longer used; kept for backward compatibility Untagged_status = re.compile( br'\* (?P\d+) (?P[A-Z-]+)( (?P.*))?', re.ASCII) +# We compile these in _mode_xxx. +_Literal = br'.*{(?P\d+)}$' +_Untagged_status = br'\* (?P\d+) (?P[A-Z-]+)( (?P.*))?' @@ -165,7 +172,7 @@ class error(Exception): pass # Logical errors - debug required class abort(error): pass # Service errors - close and retry class readonly(abort): pass # Mailbox status changed to READ-ONLY - def __init__(self, host = '', port = IMAP4_PORT): + def __init__(self, host='', port=IMAP4_PORT): self.debug = Debug self.state = 'LOGOUT' self.literal = None # A literal argument to a command @@ -175,6 +182,7 @@ def __init__(self, host = '', port = IMAP4_PORT): self.is_readonly = False # READ-ONLY desired state self.tagnum = 0 self._tls_established = False + self._mode_ascii() # Open socket to server. @@ -189,6 +197,19 @@ def __init__(self, host = '', port = IMAP4_PORT): pass raise + def _mode_ascii(self): + self.utf8_enabled = False + self._encoding = 'ascii' + self.Literal = re.compile(_Literal, re.ASCII) + self.Untagged_status = re.compile(_Untagged_status, re.ASCII) + + + def _mode_utf8(self): + self.utf8_enabled = True + self._encoding = 'utf-8' + self.Literal = re.compile(_Literal) + self.Untagged_status = re.compile(_Untagged_status) + def _connect(self): # Create unique tag for this session, @@ -238,6 +259,14 @@ def __getattr__(self, attr): return getattr(self, attr.lower()) raise AttributeError("Unknown IMAP4 command: '%s'" % attr) + def __enter__(self): + return self + + def __exit__(self, *args): + try: + self.logout() + except OSError: + pass # Overridable methods @@ -351,7 +380,10 @@ def append(self, mailbox, flags, date_time, message): date_time = Time2Internaldate(date_time) else: date_time = None - self.literal = MapCRLF.sub(CRLF, message) + literal = MapCRLF.sub(CRLF, message) + if self.utf8_enabled: + literal = b'UTF8 (' + literal + b')' + self.literal = literal return self._simple_command(name, mailbox, flags, date_time) @@ -446,6 +478,18 @@ def deleteacl(self, mailbox, who): """ return self._simple_command('DELETEACL', mailbox, who) + def enable(self, capability): + """Send an RFC5161 enable string to the server. + + (typ, [data]) = .enable(capability) + """ + if 'ENABLE' not in self.capabilities: + raise IMAP4.error("Server does not support ENABLE") + typ, data = self._simple_command('ENABLE', capability) + if typ == 'OK' and 'UTF8=ACCEPT' in capability.upper(): + self._mode_utf8() + return typ, data + def expunge(self): """Permanently remove deleted items from selected mailbox. @@ -552,7 +596,7 @@ def login_cram_md5(self, user, password): def _CRAM_MD5_AUTH(self, challenge): """ Authobject to use with CRAM-MD5 authentication. """ import hmac - pwd = (self.password.encode('ASCII') if isinstance(self.password, str) + pwd = (self.password.encode('utf-8') if isinstance(self.password, str) else self.password) return self.user + " " + hmac.HMAC(pwd, challenge, 'md5').hexdigest() @@ -652,9 +696,12 @@ def search(self, charset, *criteria): (typ, [data]) = .search(charset, criterion, ...) 'data' is space separated list of matching message numbers. + If UTF8 is enabled, charset MUST be None. """ name = 'SEARCH' if charset: + if self.utf8_enabled: + raise IMAP4.error("Non-None charset not valid in UTF8 mode") typ, dat = self._simple_command(name, 'CHARSET', charset, *criteria) else: typ, dat = self._simple_command(name, *criteria) @@ -745,7 +792,8 @@ def starttls(self, ssl_context=None): ssl_context = ssl._create_stdlib_context() typ, dat = self._simple_command(name) if typ == 'OK': - self.sock = ssl_context.wrap_socket(self.sock) + self.sock = ssl_context.wrap_socket(self.sock, + server_hostname=self.host) self.file = self.sock.makefile('rb') self._tls_established = True self._get_capabilities() @@ -867,7 +915,7 @@ def _append_untagged(self, typ, dat): def _check_bye(self): bye = self.untagged_responses.get('BYE') if bye: - raise self.abort(bye[-1].decode('ascii', 'replace')) + raise self.abort(bye[-1].decode(self._encoding, 'replace')) def _command(self, name, *args): @@ -888,12 +936,12 @@ def _command(self, name, *args): raise self.readonly('mailbox status changed to READ-ONLY') tag = self._new_tag() - name = bytes(name, 'ASCII') + name = bytes(name, self._encoding) data = tag + b' ' + name for arg in args: if arg is None: continue if isinstance(arg, str): - arg = bytes(arg, "ASCII") + arg = bytes(arg, self._encoding) data = data + b' ' + arg literal = self.literal @@ -903,7 +951,7 @@ def _command(self, name, *args): literator = literal else: literator = None - data = data + bytes(' {%s}' % len(literal), 'ASCII') + data = data + bytes(' {%s}' % len(literal), self._encoding) if __debug__: if self.debug >= 4: @@ -968,7 +1016,7 @@ def _get_capabilities(self): typ, dat = self.capability() if dat == [None]: raise self.error('no CAPABILITY response from server') - dat = str(dat[-1], "ASCII") + dat = str(dat[-1], self._encoding) dat = dat.upper() self.capabilities = tuple(dat.split()) @@ -987,10 +1035,10 @@ def _get_response(self): if self._match(self.tagre, resp): tag = self.mo.group('tag') if not tag in self.tagged_commands: - raise self.abort('unexpected tagged response: %s' % resp) + raise self.abort('unexpected tagged response: %r' % resp) typ = self.mo.group('type') - typ = str(typ, 'ASCII') + typ = str(typ, self._encoding) dat = self.mo.group('data') self.tagged_commands[tag] = (typ, [dat]) else: @@ -999,7 +1047,7 @@ def _get_response(self): # '*' (untagged) responses? if not self._match(Untagged_response, resp): - if self._match(Untagged_status, resp): + if self._match(self.Untagged_status, resp): dat2 = self.mo.group('data2') if self.mo is None: @@ -1009,17 +1057,17 @@ def _get_response(self): self.continuation_response = self.mo.group('data') return None # NB: indicates continuation - raise self.abort("unexpected response: '%s'" % resp) + raise self.abort("unexpected response: %r" % resp) typ = self.mo.group('type') - typ = str(typ, 'ascii') + typ = str(typ, self._encoding) dat = self.mo.group('data') if dat is None: dat = b'' # Null untagged response if dat2: dat = dat + b' ' + dat2 # Is there a literal to come? - while self._match(Literal, dat): + while self._match(self.Literal, dat): # Read literal direct from connection. @@ -1043,7 +1091,7 @@ def _get_response(self): if typ in ('OK', 'NO', 'BAD') and self._match(Response_code, dat): typ = self.mo.group('type') - typ = str(typ, "ASCII") + typ = str(typ, self._encoding) self._append_untagged(typ, self.mo.group('data')) if __debug__: @@ -1061,6 +1109,11 @@ def _get_tagged_response(self, tag): del self.tagged_commands[tag] return result + # If we've seen a BYE at this point, the socket will be + # closed, so report the BYE now. + + self._check_bye() + # Some have reported "unexpected response" exceptions. # Note that ignoring them here causes loops. # Instead, send me details of the unexpected response and @@ -1108,7 +1161,7 @@ def _match(self, cre, s): def _new_tag(self): - tag = self.tagpre + bytes(str(self.tagnum), 'ASCII') + tag = self.tagpre + bytes(str(self.tagnum), self._encoding) self.tagnum = self.tagnum + 1 self.tagged_commands[tag] = None return tag @@ -1198,7 +1251,8 @@ class IMAP4_SSL(IMAP4): """ - def __init__(self, host='', port=IMAP4_SSL_PORT, keyfile=None, certfile=None, ssl_context=None): + def __init__(self, host='', port=IMAP4_SSL_PORT, keyfile=None, + certfile=None, ssl_context=None): if ssl_context is not None and keyfile is not None: raise ValueError("ssl_context and keyfile arguments are mutually " "exclusive") @@ -1216,7 +1270,8 @@ def __init__(self, host='', port=IMAP4_SSL_PORT, keyfile=None, certfile=None, ss def _create_socket(self): sock = IMAP4._create_socket(self) - return self.ssl_context.wrap_socket(sock) + return self.ssl_context.wrap_socket(sock, + server_hostname=self.host) def open(self, host='', port=IMAP4_SSL_PORT): """Setup connection to remote server on "host:port". @@ -1235,7 +1290,7 @@ class IMAP4_stream(IMAP4): Instantiate with: IMAP4_stream(command) - where "command" is a string that can be passed to subprocess.Popen() + "command" - a string that can be passed to subprocess.Popen() for more documentation see the docstring of the parent class IMAP4. """ @@ -1298,7 +1353,7 @@ def __init__(self, mechinst): def process(self, data): ret = self.mech(self.decode(data)) if ret is None: - return '*' # Abort conversation + return b'*' # Abort conversation return self.encode(ret) def encode(self, inp): @@ -1312,7 +1367,7 @@ def encode(self, inp): # oup = b'' if isinstance(inp, str): - inp = inp.encode('ASCII') + inp = inp.encode('utf-8') while inp: if len(inp) > 48: t = inp[:48] diff --git a/Lib/imghdr.py b/Lib/imghdr.py index 0cba063a9c32..b26792539d5b 100644 --- a/Lib/imghdr.py +++ b/Lib/imghdr.py @@ -7,18 +7,16 @@ #-------------------------# def what(file, h=None): - if h is None: - if isinstance(file, str): - f = open(file, 'rb') - h = f.read(32) - else: - location = file.tell() - h = file.read(32) - file.seek(location) - f = None - else: - f = None + f = None try: + if h is None: + if isinstance(file, str): + f = open(file, 'rb') + h = f.read(32) + else: + location = file.tell() + h = file.read(32) + file.seek(location) for tf in tests: res = tf(h, f) if res: @@ -112,6 +110,18 @@ def test_bmp(h, f): tests.append(test_bmp) +def test_webp(h, f): + if h.startswith(b'RIFF') and h[8:12] == b'WEBP': + return 'webp' + +tests.append(test_webp) + +def test_exr(h, f): + if h.startswith(b'\x76\x2f\x31\x01'): + return 'exr' + +tests.append(test_exr) + #--------------------# # Small test program # #--------------------# diff --git a/Lib/imp.py b/Lib/imp.py index c8449c615549..b33995267b8a 100644 --- a/Lib/imp.py +++ b/Lib/imp.py @@ -8,15 +8,16 @@ # (Probably) need to stay in _imp from _imp import (lock_held, acquire_lock, release_lock, get_frozen_object, is_frozen_package, - init_builtin, init_frozen, is_builtin, is_frozen, + init_frozen, is_builtin, is_frozen, _fix_co_filename) try: - from _imp import load_dynamic + from _imp import create_dynamic except ImportError: # Platform doesn't support dynamic loading. - load_dynamic = None + create_dynamic = None -from importlib._bootstrap import SourcelessFileLoader, _ERR_MSG, _SpecMethods +from importlib._bootstrap import _ERR_MSG, _exec, _load, _builtin_from_name +from importlib._bootstrap_external import SourcelessFileLoader from importlib import machinery from importlib import util @@ -29,7 +30,7 @@ warnings.warn("the imp module is deprecated in favour of importlib; " "see the module's documentation for alternative uses", - PendingDeprecationWarning) + DeprecationWarning, stacklevel=2) # DEPRECATED SEARCH_ERROR = 0 @@ -58,24 +59,23 @@ def new_module(name): def get_magic(): """**DEPRECATED** - Return the magic number for .pyc or .pyo files. + Return the magic number for .pyc files. """ return util.MAGIC_NUMBER def get_tag(): - """Return the magic tag for .pyc or .pyo files.""" + """Return the magic tag for .pyc files.""" return sys.implementation.cache_tag def cache_from_source(path, debug_override=None): """**DEPRECATED** - Given the path to a .py file, return the path to its .pyc/.pyo file. + Given the path to a .py file, return the path to its .pyc file. The .py file does not need to exist; this simply returns the path to the - .pyc/.pyo file calculated as if the .py file were imported. The extension - will be .pyc unless sys.flags.optimize is non-zero, then it will be .pyo. + .pyc file calculated as if the .py file were imported. If debug_override is not None, then it must be a boolean and is used in place of sys.flags.optimize. @@ -83,16 +83,18 @@ def cache_from_source(path, debug_override=None): If sys.implementation.cache_tag is None then NotImplementedError is raised. """ - return util.cache_from_source(path, debug_override) + with warnings.catch_warnings(): + warnings.simplefilter('ignore') + return util.cache_from_source(path, debug_override) def source_from_cache(path): """**DEPRECATED** - Given the path to a .pyc./.pyo file, return the path to its .py file. + Given the path to a .pyc. file, return the path to its .py file. - The .pyc/.pyo file does not need to exist; this simply returns the path to - the .py file calculated to correspond to the .pyc/.pyo file. If path does + The .pyc file does not need to exist; this simply returns the path to + the .py file calculated to correspond to the .pyc file. If path does not conform to PEP 3147 format, ValueError will be raised. If sys.implementation.cache_tag is None then NotImplementedError is raised. @@ -130,7 +132,7 @@ def find_module(self, fullname): class _HackedGetData: - """Compatibiilty support for 'file' arguments of various load_*() + """Compatibility support for 'file' arguments of various load_*() functions.""" def __init__(self, fullname, path, file=None): @@ -164,11 +166,10 @@ class _LoadSourceCompatibility(_HackedGetData, machinery.SourceFileLoader): def load_source(name, pathname, file=None): loader = _LoadSourceCompatibility(name, pathname, file) spec = util.spec_from_file_location(name, pathname, loader=loader) - methods = _SpecMethods(spec) if name in sys.modules: - module = methods.exec(sys.modules[name]) + module = _exec(spec, sys.modules[name]) else: - module = methods.load() + module = _load(spec) # To allow reloading to potentially work, use a non-hacked loader which # won't rely on a now-closed file object. module.__loader__ = machinery.SourceFileLoader(name, pathname) @@ -185,11 +186,10 @@ def load_compiled(name, pathname, file=None): """**DEPRECATED**""" loader = _LoadCompiledCompatibility(name, pathname, file) spec = util.spec_from_file_location(name, pathname, loader=loader) - methods = _SpecMethods(spec) if name in sys.modules: - module = methods.exec(sys.modules[name]) + module = _exec(spec, sys.modules[name]) else: - module = methods.load() + module = _load(spec) # To allow reloading to potentially work, use a non-hacked loader which # won't rely on a now-closed file object. module.__loader__ = SourcelessFileLoader(name, pathname) @@ -210,11 +210,10 @@ def load_package(name, path): raise ValueError('{!r} is not a package'.format(path)) spec = util.spec_from_file_location(name, path, submodule_search_locations=[]) - methods = _SpecMethods(spec) if name in sys.modules: - return methods.exec(sys.modules[name]) + return _exec(spec, sys.modules[name]) else: - return methods.load() + return _load(spec) def load_module(name, file, filename, details): @@ -313,3 +312,34 @@ def reload(module): """ return importlib.reload(module) + + +def init_builtin(name): + """**DEPRECATED** + + Load and return a built-in module by name, or None is such module doesn't + exist + """ + try: + return _builtin_from_name(name) + except ImportError: + return None + + +if create_dynamic: + def load_dynamic(name, path, file=None): + """**DEPRECATED** + + Load an extension module. + """ + import importlib.machinery + loader = importlib.machinery.ExtensionFileLoader(name, path) + + # Issue #24748: Skip the sys.modules check in _load_module_shim; + # always load new extension + spec = importlib.machinery.ModuleSpec( + name=name, loader=loader, origin=path) + return _load(spec) + +else: + load_dynamic = None diff --git a/Lib/importlib/__init__.py b/Lib/importlib/__init__.py index 3e969bbead97..b6a9f82e05f2 100644 --- a/Lib/importlib/__init__.py +++ b/Lib/importlib/__init__.py @@ -11,7 +11,6 @@ # initialised below if the frozen one is not available). import _imp # Just the builtin component, NOT the full Python module import sys -import types try: import _frozen_importlib as _bootstrap @@ -23,16 +22,42 @@ # a second copy of the module. _bootstrap.__name__ = 'importlib._bootstrap' _bootstrap.__package__ = 'importlib' - _bootstrap.__file__ = __file__.replace('__init__.py', '_bootstrap.py') + try: + _bootstrap.__file__ = __file__.replace('__init__.py', '_bootstrap.py') + except NameError: + # __file__ is not guaranteed to be defined, e.g. if this code gets + # frozen by a tool like cx_Freeze. + pass sys.modules['importlib._bootstrap'] = _bootstrap +try: + import _frozen_importlib_external as _bootstrap_external +except ImportError: + from . import _bootstrap_external + _bootstrap_external._setup(_bootstrap) + _bootstrap._bootstrap_external = _bootstrap_external +else: + _bootstrap_external.__name__ = 'importlib._bootstrap_external' + _bootstrap_external.__package__ = 'importlib' + try: + _bootstrap_external.__file__ = __file__.replace('__init__.py', '_bootstrap_external.py') + except NameError: + # __file__ is not guaranteed to be defined, e.g. if this code gets + # frozen by a tool like cx_Freeze. + pass + sys.modules['importlib._bootstrap_external'] = _bootstrap_external + # To simplify imports in test code -_w_long = _bootstrap._w_long -_r_long = _bootstrap._r_long +_w_long = _bootstrap_external._w_long +_r_long = _bootstrap_external._r_long # Fully bootstrapped at this point, import whatever you like, circular # dependencies and startup overhead minimisation permitting :) +import types +import warnings + + # Public API ######################################################### from ._bootstrap import __import__ @@ -46,44 +71,16 @@ def invalidate_caches(): finder.invalidate_caches() -def find_spec(name, path=None): - """Return the spec for the specified module. - - First, sys.modules is checked to see if the module was already imported. If - so, then sys.modules[name].__spec__ is returned. If that happens to be - set to None, then ValueError is raised. If the module is not in - sys.modules, then sys.meta_path is searched for a suitable spec with the - value of 'path' given to the finders. None is returned if no spec could - be found. - - Dotted names do not have their parent packages implicitly imported. You will - most likely need to explicitly import all parent packages in the proper - order for a submodule to get the correct spec. - - """ - if name not in sys.modules: - return _bootstrap._find_spec(name, path) - else: - module = sys.modules[name] - if module is None: - return None - try: - spec = module.__spec__ - except AttributeError: - raise ValueError('{}.__spec__ is not set'.format(name)) - else: - if spec is None: - raise ValueError('{}.__spec__ is None'.format(name)) - return spec - - -# XXX Deprecate... def find_loader(name, path=None): """Return the loader for the specified module. This is a backward-compatible wrapper around find_spec(). + This function is deprecated in favor of importlib.util.find_spec(). + """ + warnings.warn('Use importlib.util.find_spec() instead.', + DeprecationWarning, stacklevel=2) try: loader = sys.modules[name].__loader__ if loader is None: @@ -93,7 +90,7 @@ def find_loader(name, path=None): except KeyError: pass except AttributeError: - raise ValueError('{}.__loader__ is not set'.format(name)) + raise ValueError('{}.__loader__ is not set'.format(name)) from None spec = _bootstrap._find_spec(name, path) # We won't worry about malformed specs (missing attributes). @@ -153,12 +150,20 @@ def reload(module): _RELOADING[name] = module try: parent_name = name.rpartition('.')[0] - if parent_name and parent_name not in sys.modules: - msg = "parent {!r} not in sys.modules" - raise ImportError(msg.format(parent_name), name=parent_name) - spec = module.__spec__ = _bootstrap._find_spec(name, None, module) - methods = _bootstrap._SpecMethods(spec) - methods.exec(module) + if parent_name: + try: + parent = sys.modules[parent_name] + except KeyError: + msg = "parent {!r} not in sys.modules" + raise ImportError(msg.format(parent_name), + name=parent_name) from None + else: + pkgpath = parent.__path__ + else: + pkgpath = None + target = module + spec = module.__spec__ = _bootstrap._find_spec(name, pkgpath, target) + _bootstrap._exec(spec, module) # The module may have replaced itself in sys.modules! return sys.modules[name] finally: diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index 6b8f979b8b6d..6f62bb35fef0 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -9,7 +9,7 @@ # # IMPORTANT: Whenever making changes to this module, be sure to run # a top-level make in order to get the frozen version of the module -# update. Not doing so will result in the Makefile to fail for +# updated. Not doing so will result in the Makefile to fail for # all others who don't have a ./python around to freeze the module # in the early stages of compilation. # @@ -22,101 +22,7 @@ # Bootstrap-related code ###################################################### -_CASE_INSENSITIVE_PLATFORMS = 'win', 'cygwin', 'darwin' - - -def _make_relax_case(): - if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS): - def _relax_case(): - """True if filenames must be checked case-insensitively.""" - return b'PYTHONCASEOK' in _os.environ - else: - def _relax_case(): - """True if filenames must be checked case-insensitively.""" - return False - return _relax_case - - -def _w_long(x): - """Convert a 32-bit integer to little-endian.""" - return (int(x) & 0xFFFFFFFF).to_bytes(4, 'little') - - -def _r_long(int_bytes): - """Convert 4 bytes in little-endian to an integer.""" - return int.from_bytes(int_bytes, 'little') - - -def _path_join(*path_parts): - """Replacement for os.path.join().""" - return path_sep.join([part.rstrip(path_separators) - for part in path_parts if part]) - - -def _path_split(path): - """Replacement for os.path.split().""" - if len(path_separators) == 1: - front, _, tail = path.rpartition(path_sep) - return front, tail - for x in reversed(path): - if x in path_separators: - front, tail = path.rsplit(x, maxsplit=1) - return front, tail - return '', path - - -def _path_stat(path): - """Stat the path. - - Made a separate function to make it easier to override in experiments - (e.g. cache stat results). - - """ - return _os.stat(path) - - -def _path_is_mode_type(path, mode): - """Test whether the path is the specified mode type.""" - try: - stat_info = _path_stat(path) - except OSError: - return False - return (stat_info.st_mode & 0o170000) == mode - - -def _path_isfile(path): - """Replacement for os.path.isfile.""" - return _path_is_mode_type(path, 0o100000) - - -def _path_isdir(path): - """Replacement for os.path.isdir.""" - if not path: - path = _os.getcwd() - return _path_is_mode_type(path, 0o040000) - - -def _write_atomic(path, data, mode=0o666): - """Best-effort function to write data to a path atomically. - Be prepared to handle a FileExistsError if concurrent writing of the - temporary file is attempted.""" - # id() is used to generate a pseudo-random filename. - path_tmp = '{}.{}'.format(path, id(path)) - fd = _os.open(path_tmp, - _os.O_EXCL | _os.O_CREAT | _os.O_WRONLY, mode & 0o666) - try: - # We first write data to a temporary file, and then use os.replace() to - # perform an atomic rename. - with _io.FileIO(fd, 'wb') as file: - file.write(data) - _os.replace(path_tmp, path) - except OSError: - try: - _os.unlink(path_tmp) - except OSError: - pass - raise - +_bootstrap_external = None def _wrap(new, old): """Simple substitute for functools.update_wrapper.""" @@ -130,10 +36,6 @@ def _new_module(name): return type(sys)(name) -_code_type = type(_wrap.__code__) - - - class _ManageReload: """Manages the possible clean-up of sys.modules for load_module().""" @@ -309,7 +211,6 @@ def _lock_unlock_module(name): lock.release() # Frame stripping magic ############################################### - def _call_with_frames_removed(f, *args, **kwds): """remove_importlib_frames in import.c will always remove sequences of importlib frames that end with a call to this function @@ -321,199 +222,6 @@ def _call_with_frames_removed(f, *args, **kwds): return f(*args, **kwds) -# Finder/loader utility code ############################################### - -# Magic word to reject .pyc files generated by other Python versions. -# It should change for each incompatible change to the bytecode. -# -# The value of CR and LF is incorporated so if you ever read or write -# a .pyc file in text mode the magic number will be wrong; also, the -# Apple MPW compiler swaps their values, botching string constants. -# -# The magic numbers must be spaced apart at least 2 values, as the -# -U interpeter flag will cause MAGIC+1 being used. They have been -# odd numbers for some time now. -# -# There were a variety of old schemes for setting the magic number. -# The current working scheme is to increment the previous value by -# 10. -# -# Starting with the adoption of PEP 3147 in Python 3.2, every bump in magic -# number also includes a new "magic tag", i.e. a human readable string used -# to represent the magic number in __pycache__ directories. When you change -# the magic number, you must also set a new unique magic tag. Generally this -# can be named after the Python major version of the magic number bump, but -# it can really be anything, as long as it's different than anything else -# that's come before. The tags are included in the following table, starting -# with Python 3.2a0. -# -# Known values: -# Python 1.5: 20121 -# Python 1.5.1: 20121 -# Python 1.5.2: 20121 -# Python 1.6: 50428 -# Python 2.0: 50823 -# Python 2.0.1: 50823 -# Python 2.1: 60202 -# Python 2.1.1: 60202 -# Python 2.1.2: 60202 -# Python 2.2: 60717 -# Python 2.3a0: 62011 -# Python 2.3a0: 62021 -# Python 2.3a0: 62011 (!) -# Python 2.4a0: 62041 -# Python 2.4a3: 62051 -# Python 2.4b1: 62061 -# Python 2.5a0: 62071 -# Python 2.5a0: 62081 (ast-branch) -# Python 2.5a0: 62091 (with) -# Python 2.5a0: 62092 (changed WITH_CLEANUP opcode) -# Python 2.5b3: 62101 (fix wrong code: for x, in ...) -# Python 2.5b3: 62111 (fix wrong code: x += yield) -# Python 2.5c1: 62121 (fix wrong lnotab with for loops and -# storing constants that should have been removed) -# Python 2.5c2: 62131 (fix wrong code: for x, in ... in listcomp/genexp) -# Python 2.6a0: 62151 (peephole optimizations and STORE_MAP opcode) -# Python 2.6a1: 62161 (WITH_CLEANUP optimization) -# Python 2.7a0: 62171 (optimize list comprehensions/change LIST_APPEND) -# Python 2.7a0: 62181 (optimize conditional branches: -# introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE) -# Python 2.7a0 62191 (introduce SETUP_WITH) -# Python 2.7a0 62201 (introduce BUILD_SET) -# Python 2.7a0 62211 (introduce MAP_ADD and SET_ADD) -# Python 3000: 3000 -# 3010 (removed UNARY_CONVERT) -# 3020 (added BUILD_SET) -# 3030 (added keyword-only parameters) -# 3040 (added signature annotations) -# 3050 (print becomes a function) -# 3060 (PEP 3115 metaclass syntax) -# 3061 (string literals become unicode) -# 3071 (PEP 3109 raise changes) -# 3081 (PEP 3137 make __file__ and __name__ unicode) -# 3091 (kill str8 interning) -# 3101 (merge from 2.6a0, see 62151) -# 3103 (__file__ points to source file) -# Python 3.0a4: 3111 (WITH_CLEANUP optimization). -# Python 3.0a5: 3131 (lexical exception stacking, including POP_EXCEPT) -# Python 3.1a0: 3141 (optimize list, set and dict comprehensions: -# change LIST_APPEND and SET_ADD, add MAP_ADD) -# Python 3.1a0: 3151 (optimize conditional branches: -# introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE) -# Python 3.2a0: 3160 (add SETUP_WITH) -# tag: cpython-32 -# Python 3.2a1: 3170 (add DUP_TOP_TWO, remove DUP_TOPX and ROT_FOUR) -# tag: cpython-32 -# Python 3.2a2 3180 (add DELETE_DEREF) -# Python 3.3a0 3190 __class__ super closure changed -# Python 3.3a0 3200 (__qualname__ added) -# 3210 (added size modulo 2**32 to the pyc header) -# Python 3.3a1 3220 (changed PEP 380 implementation) -# Python 3.3a4 3230 (revert changes to implicit __class__ closure) -# Python 3.4a1 3250 (evaluate positional default arguments before -# keyword-only defaults) -# Python 3.4a1 3260 (add LOAD_CLASSDEREF; allow locals of class to override -# free vars) -# Python 3.4a1 3270 (various tweaks to the __class__ closure) -# Python 3.4a1 3280 (remove implicit class argument) -# Python 3.4a4 3290 (changes to __qualname__ computation) -# Python 3.4a4 3300 (more changes to __qualname__ computation) -# -# MAGIC must change whenever the bytecode emitted by the compiler may no -# longer be understood by older implementations of the eval loop (usually -# due to the addition of new opcodes). - -MAGIC_NUMBER = (3300).to_bytes(2, 'little') + b'\r\n' -_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c - -_PYCACHE = '__pycache__' - -SOURCE_SUFFIXES = ['.py'] # _setup() adds .pyw as needed. - -DEBUG_BYTECODE_SUFFIXES = ['.pyc'] -OPTIMIZED_BYTECODE_SUFFIXES = ['.pyo'] - -def cache_from_source(path, debug_override=None): - """Given the path to a .py file, return the path to its .pyc/.pyo file. - - The .py file does not need to exist; this simply returns the path to the - .pyc/.pyo file calculated as if the .py file were imported. The extension - will be .pyc unless sys.flags.optimize is non-zero, then it will be .pyo. - - If debug_override is not None, then it must be a boolean and is used in - place of sys.flags.optimize. - - If sys.implementation.cache_tag is None then NotImplementedError is raised. - - """ - debug = not sys.flags.optimize if debug_override is None else debug_override - if debug: - suffixes = DEBUG_BYTECODE_SUFFIXES - else: - suffixes = OPTIMIZED_BYTECODE_SUFFIXES - head, tail = _path_split(path) - base_filename, sep, _ = tail.partition('.') - tag = sys.implementation.cache_tag - if tag is None: - raise NotImplementedError('sys.implementation.cache_tag is None') - filename = ''.join([base_filename, sep, tag, suffixes[0]]) - return _path_join(head, _PYCACHE, filename) - - -def source_from_cache(path): - """Given the path to a .pyc./.pyo file, return the path to its .py file. - - The .pyc/.pyo file does not need to exist; this simply returns the path to - the .py file calculated to correspond to the .pyc/.pyo file. If path does - not conform to PEP 3147 format, ValueError will be raised. If - sys.implementation.cache_tag is None then NotImplementedError is raised. - - """ - if sys.implementation.cache_tag is None: - raise NotImplementedError('sys.implementation.cache_tag is None') - head, pycache_filename = _path_split(path) - head, pycache = _path_split(head) - if pycache != _PYCACHE: - raise ValueError('{} not bottom-level directory in ' - '{!r}'.format(_PYCACHE, path)) - if pycache_filename.count('.') != 2: - raise ValueError('expected only 2 dots in ' - '{!r}'.format(pycache_filename)) - base_filename = pycache_filename.partition('.')[0] - return _path_join(head, base_filename + SOURCE_SUFFIXES[0]) - - -def _get_sourcefile(bytecode_path): - """Convert a bytecode file path to a source path (if possible). - - This function exists purely for backwards-compatibility for - PyImport_ExecCodeModuleWithFilenames() in the C API. - - """ - if len(bytecode_path) == 0: - return None - rest, _, extension = bytecode_path.rpartition('.') - if not rest or extension.lower()[-3:-1] != 'py': - return bytecode_path - try: - source_path = source_from_cache(bytecode_path) - except (NotImplementedError, ValueError): - source_path = bytecode_path[:-1] - return source_path if _path_isfile(source_path) else bytecode_path - - -def _calc_mode(path): - """Calculate the mode permissions for a bytecode file.""" - try: - mode = _path_stat(path).st_mode - except OSError: - mode = 0o666 - # We always ensure write access so we can update cached files - # later even when the source files are read-only on Windows (#6074) - mode |= 0o200 - return mode - - def _verbose_message(message, *args, verbosity=1): """Print the message to stderr if -v/PYTHONVERBOSE is turned on.""" if sys.flags.verbose >= verbosity: @@ -522,24 +230,6 @@ def _verbose_message(message, *args, verbosity=1): print(message.format(*args), file=sys.stderr) -def _check_name(method): - """Decorator to verify that the module being requested matches the one the - loader can handle. - - The first argument (self) must define _name which the second argument is - compared against. If the comparison fails then ImportError is raised. - - """ - def _check_name_wrapper(self, name=None, *args, **kwargs): - if name is None: - name = self.name - elif self.name != name: - raise ImportError('loader cannot handle %s' % name, name=name) - return method(self, name, *args, **kwargs) - _wrap(_check_name_wrapper, method) - return _check_name_wrapper - - def _requires_builtin(fxn): """Decorator to verify the named module is built-in.""" def _requires_builtin_wrapper(self, fullname): @@ -562,120 +252,20 @@ def _requires_frozen_wrapper(self, fullname): return _requires_frozen_wrapper -def _find_module_shim(self, fullname): - """Try to find a loader for the specified module by delegating to - self.find_loader().""" - # Call find_loader(). If it returns a string (indicating this - # is a namespace package portion), generate a warning and - # return None. - loader, portions = self.find_loader(fullname) - if loader is None and len(portions): - msg = 'Not importing directory {}: missing __init__' - _warnings.warn(msg.format(portions[0]), ImportWarning) - return loader +# Typically used by loader classes as a method replacement. +def _load_module_shim(self, fullname): + """Load the specified module into sys.modules and return it. + This method is deprecated. Use loader.exec_module instead. -def _load_module_shim(self, fullname): - """Load the specified module into sys.modules and return it.""" - # XXX Deprecation Warning here... + """ spec = spec_from_loader(fullname, self) - methods = _SpecMethods(spec) if fullname in sys.modules: module = sys.modules[fullname] - methods.exec(module) + _exec(spec, module) return sys.modules[fullname] else: - return methods.load() - - -def _validate_bytecode_header(data, source_stats=None, name=None, path=None): - """Validate the header of the passed-in bytecode against source_stats (if - given) and returning the bytecode that can be compiled by compile(). - - All other arguments are used to enhance error reporting. - - ImportError is raised when the magic number is incorrect or the bytecode is - found to be stale. EOFError is raised when the data is found to be - truncated. - - """ - exc_details = {} - if name is not None: - exc_details['name'] = name - else: - # To prevent having to make all messages have a conditional name. - name = '' - if path is not None: - exc_details['path'] = path - magic = data[:4] - raw_timestamp = data[4:8] - raw_size = data[8:12] - if magic != MAGIC_NUMBER: - message = 'bad magic number in {!r}: {!r}'.format(name, magic) - _verbose_message(message) - raise ImportError(message, **exc_details) - elif len(raw_timestamp) != 4: - message = 'reached EOF while reading timestamp in {!r}'.format(name) - _verbose_message(message) - raise EOFError(message) - elif len(raw_size) != 4: - message = 'reached EOF while reading size of source in {!r}'.format(name) - _verbose_message(message) - raise EOFError(message) - if source_stats is not None: - try: - source_mtime = int(source_stats['mtime']) - except KeyError: - pass - else: - if _r_long(raw_timestamp) != source_mtime: - message = 'bytecode is stale for {!r}'.format(name) - _verbose_message(message) - raise ImportError(message, **exc_details) - try: - source_size = source_stats['size'] & 0xFFFFFFFF - except KeyError: - pass - else: - if _r_long(raw_size) != source_size: - raise ImportError('bytecode is stale for {!r}'.format(name), - **exc_details) - return data[12:] - - -def _compile_bytecode(data, name=None, bytecode_path=None, source_path=None): - """Compile bytecode as returned by _validate_bytecode_header().""" - code = marshal.loads(data) - if isinstance(code, _code_type): - _verbose_message('code object from {!r}', bytecode_path) - if source_path is not None: - _imp._fix_co_filename(code, source_path) - return code - else: - raise ImportError('Non-code object in {!r}'.format(bytecode_path), - name=name, path=bytecode_path) - -def _code_to_bytecode(code, mtime=0, source_size=0): - """Compile a code object into bytecode for writing out to a byte-compiled - file.""" - data = bytearray(MAGIC_NUMBER) - data.extend(_w_long(mtime)) - data.extend(_w_long(source_size)) - data.extend(marshal.dumps(code)) - return data - - -def decode_source(source_bytes): - """Decode bytes representing source code and return the string. - - Universal newline support is used in the decoding. - """ - import tokenize # To avoid bootstrap issues. - source_bytes_readline = _io.BytesIO(source_bytes).readline - encoding = tokenize.detect_encoding(source_bytes_readline) - newline_decoder = _io.IncrementalNewlineDecoder(None, True) - return newline_decoder.decode(source_bytes.decode(encoding[0])) - + return _load(spec) # Module specifications ####################################################### @@ -683,7 +273,9 @@ def _module_repr(module): # The implementation of ModuleType__repr__(). loader = getattr(module, '__loader__', None) if hasattr(loader, 'module_repr'): - # XXX Deprecation Warning here... + # As soon as BuiltinImporter, FrozenImporter, and NamespaceLoader + # drop their implementations for module_repr. we can add a + # deprecation warning here. try: return loader.module_repr(module) except Exception: @@ -694,7 +286,7 @@ def _module_repr(module): pass else: if spec is not None: - return _SpecMethods(spec).module_repr() + return _module_repr_from_spec(spec) # We could use module.__class__.__name__ instead of 'module' in the # various repr permutations. @@ -815,14 +407,9 @@ def __eq__(self, other): def cached(self): if self._cached is None: if self.origin is not None and self._set_fileattr: - filename = self.origin - if filename.endswith(tuple(SOURCE_SUFFIXES)): - try: - self._cached = cache_from_source(filename) - except NotImplementedError: - pass - elif filename.endswith(tuple(BYTECODE_SUFFIXES)): - self._cached = filename + if _bootstrap_external is None: + raise NotImplementedError + self._cached = _bootstrap_external._get_cached(self.origin) return self._cached @cached.setter @@ -841,10 +428,18 @@ def parent(self): def has_location(self): return self._set_fileattr + @has_location.setter + def has_location(self, value): + self._set_fileattr = bool(value) + def spec_from_loader(name, loader, *, origin=None, is_package=None): """Return a module spec based on various loader methods.""" if hasattr(loader, 'get_filename'): + if _bootstrap_external is None: + raise NotImplementedError + spec_from_file_location = _bootstrap_external.spec_from_file_location + if is_package is None: return spec_from_file_location(name, loader=loader) search = [] if is_package else None @@ -867,70 +462,6 @@ def spec_from_loader(name, loader, *, origin=None, is_package=None): _POPULATE = object() -def spec_from_file_location(name, location=None, *, loader=None, - submodule_search_locations=_POPULATE): - """Return a module spec based on a file location. - - To indicate that the module is a package, set - submodule_search_locations to a list of directory paths. An - empty list is sufficient, though its not otherwise useful to the - import system. - - The loader must take a spec as its only __init__() arg. - - """ - if location is None: - # The caller may simply want a partially populated location- - # oriented spec. So we set the location to a bogus value and - # fill in as much as we can. - location = '' - if hasattr(loader, 'get_filename'): - # ExecutionLoader - try: - location = loader.get_filename(name) - except ImportError: - pass - - # If the location is on the filesystem, but doesn't actually exist, - # we could return None here, indicating that the location is not - # valid. However, we don't have a good way of testing since an - # indirect location (e.g. a zip file or URL) will look like a - # non-existent file relative to the filesystem. - - spec = ModuleSpec(name, loader, origin=location) - spec._set_fileattr = True - - # Pick a loader if one wasn't provided. - if loader is None: - for loader_class, suffixes in _get_supported_file_loaders(): - if location.endswith(tuple(suffixes)): - loader = loader_class(name, location) - spec.loader = loader - break - else: - return None - - # Set submodule_search_paths appropriately. - if submodule_search_locations is _POPULATE: - # Check the loader. - if hasattr(loader, 'is_package'): - try: - is_package = loader.is_package(name) - except ImportError: - pass - else: - if is_package: - spec.submodule_search_locations = [] - else: - spec.submodule_search_locations = submodule_search_locations - if spec.submodule_search_locations == []: - if location: - dirname = _path_split(location)[0] - spec.submodule_search_locations.append(dirname) - - return spec - - def _spec_from_module(module, loader=None, origin=None): # This function is meant for use in _setup(). try: @@ -976,253 +507,190 @@ def _spec_from_module(module, loader=None, origin=None): return spec -class _SpecMethods: - - """Convenience wrapper around spec objects to provide spec-specific - methods.""" - - def __init__(self, spec): - self.spec = spec - - @classmethod - def from_module(cls, module): - """Create a spec from a module's attributes.""" +def _init_module_attrs(spec, module, *, override=False): + # The passed-in module may be not support attribute assignment, + # in which case we simply don't set the attributes. + # __name__ + if (override or getattr(module, '__name__', None) is None): try: - spec = module.__spec__ + module.__name__ = spec.name except AttributeError: - try: - loader = spec.__loader__ - except AttributeError: - spec = _find_spec(module.__name__) - if spec is None: - spec = spec_from_loader(module.__name__, loader) - else: - spec = spec_from_loader(module.__name__, loader) - return cls(spec) - - def module_repr(self): - """Return the repr to use for the module.""" - # We mostly replicate _module_repr() using the spec attributes. - spec = self.spec - name = '?' if spec.name is None else spec.name - if spec.origin is None: - if spec.loader is None: - return ''.format(name) - else: - return ''.format(name, spec.loader) - else: - if spec.has_location: - return ''.format(name, spec.origin) - else: - return ''.format(spec.name, spec.origin) - - def init_module_attrs(self, module, *, _override=False, _force_name=True): - """Set the module's attributes. - - All missing import-related module attributes will be set. Here - is how the spec attributes map onto the module: - - spec.name -> module.__name__ - spec.loader -> module.__loader__ - spec.parent -> module.__package__ - spec -> module.__spec__ - - Optional: - spec.origin -> module.__file__ (if spec.set_fileattr is true) - spec.cached -> module.__cached__ (if __file__ also set) - spec.submodule_search_locations -> module.__path__ (if set) - - """ - spec = self.spec - - # The passed in module may be not support attribute assignment, - # in which case we simply don't set the attributes. - - # __name__ - if (_override or _force_name or - getattr(module, '__name__', None) is None): - try: - module.__name__ = spec.name - except AttributeError: - pass + pass + # __loader__ + if override or getattr(module, '__loader__', None) is None: + loader = spec.loader + if loader is None: + # A backward compatibility hack. + if spec.submodule_search_locations is not None: + if _bootstrap_external is None: + raise NotImplementedError + _NamespaceLoader = _bootstrap_external._NamespaceLoader - # __loader__ - if _override or getattr(module, '__loader__', None) is None: - loader = spec.loader - if loader is None: - # A backward compatibility hack. - if spec.submodule_search_locations is not None: - loader = _NamespaceLoader.__new__(_NamespaceLoader) - loader._path = spec.submodule_search_locations + loader = _NamespaceLoader.__new__(_NamespaceLoader) + loader._path = spec.submodule_search_locations + try: + module.__loader__ = loader + except AttributeError: + pass + # __package__ + if override or getattr(module, '__package__', None) is None: + try: + module.__package__ = spec.parent + except AttributeError: + pass + # __spec__ + try: + module.__spec__ = spec + except AttributeError: + pass + # __path__ + if override or getattr(module, '__path__', None) is None: + if spec.submodule_search_locations is not None: try: - module.__loader__ = loader + module.__path__ = spec.submodule_search_locations except AttributeError: pass - - # __package__ - if _override or getattr(module, '__package__', None) is None: + # __file__/__cached__ + if spec.has_location: + if override or getattr(module, '__file__', None) is None: try: - module.__package__ = spec.parent + module.__file__ = spec.origin except AttributeError: pass - # __spec__ - try: - module.__spec__ = spec - except AttributeError: - pass - - # __path__ - if _override or getattr(module, '__path__', None) is None: - if spec.submodule_search_locations is not None: + if override or getattr(module, '__cached__', None) is None: + if spec.cached is not None: try: - module.__path__ = spec.submodule_search_locations - except AttributeError: - pass - - if spec.has_location: - # __file__ - if _override or getattr(module, '__file__', None) is None: - try: - module.__file__ = spec.origin + module.__cached__ = spec.cached except AttributeError: pass + return module - # __cached__ - if _override or getattr(module, '__cached__', None) is None: - if spec.cached is not None: - try: - module.__cached__ = spec.cached - except AttributeError: - pass - def create(self): - """Return a new module to be loaded. +def module_from_spec(spec): + """Create a module based on the provided spec.""" + # Typically loaders will not implement create_module(). + module = None + if hasattr(spec.loader, 'create_module'): + # If create_module() returns `None` then it means default + # module creation should be used. + module = spec.loader.create_module(spec) + elif hasattr(spec.loader, 'exec_module'): + _warnings.warn('starting in Python 3.6, loaders defining exec_module() ' + 'must also define create_module()', + DeprecationWarning, stacklevel=2) + if module is None: + module = _new_module(spec.name) + _init_module_attrs(spec, module) + return module - The import-related module attributes are also set with the - appropriate values from the spec. - """ - spec = self.spec - # Typically loaders will not implement create_module(). - if hasattr(spec.loader, 'create_module'): - # If create_module() returns `None` it means the default - # module creation should be used. - module = spec.loader.create_module(spec) +def _module_repr_from_spec(spec): + """Return the repr to use for the module.""" + # We mostly replicate _module_repr() using the spec attributes. + name = '?' if spec.name is None else spec.name + if spec.origin is None: + if spec.loader is None: + return ''.format(name) else: - module = None - if module is None: - # This must be done before open() is ever called as the 'io' - # module implicitly imports 'locale' and would otherwise - # trigger an infinite loop. - module = _new_module(spec.name) - self.init_module_attrs(module) - return module - - def _exec(self, module): - """Do everything necessary to execute the module. + return ''.format(name, spec.loader) + else: + if spec.has_location: + return ''.format(name, spec.origin) + else: + return ''.format(spec.name, spec.origin) - The namespace of `module` is used as the target of execution. - This method uses the loader's `exec_module()` method. - """ - self.spec.loader.exec_module(module) +# Used by importlib.reload() and _load_module_shim(). +def _exec(spec, module): + """Execute the spec in an existing module's namespace.""" + name = spec.name + _imp.acquire_lock() + with _ModuleLockManager(name): + if sys.modules.get(name) is not module: + msg = 'module {!r} not in sys.modules'.format(name) + raise ImportError(msg, name=name) + if spec.loader is None: + if spec.submodule_search_locations is None: + raise ImportError('missing loader', name=spec.name) + # namespace package + _init_module_attrs(spec, module, override=True) + return module + _init_module_attrs(spec, module, override=True) + if not hasattr(spec.loader, 'exec_module'): + # (issue19713) Once BuiltinImporter and ExtensionFileLoader + # have exec_module() implemented, we can add a deprecation + # warning here. + spec.loader.load_module(name) + else: + spec.loader.exec_module(module) + return sys.modules[name] + + +def _load_backward_compatible(spec): + # (issue19713) Once BuiltinImporter and ExtensionFileLoader + # have exec_module() implemented, we can add a deprecation + # warning here. + spec.loader.load_module(spec.name) + # The module must be in sys.modules at this point! + module = sys.modules[spec.name] + if getattr(module, '__loader__', None) is None: + try: + module.__loader__ = spec.loader + except AttributeError: + pass + if getattr(module, '__package__', None) is None: + try: + # Since module.__path__ may not line up with + # spec.submodule_search_paths, we can't necessarily rely + # on spec.parent here. + module.__package__ = module.__name__ + if not hasattr(module, '__path__'): + module.__package__ = spec.name.rpartition('.')[0] + except AttributeError: + pass + if getattr(module, '__spec__', None) is None: + try: + module.__spec__ = spec + except AttributeError: + pass + return module - # Used by importlib.reload() and _load_module_shim(). - def exec(self, module): - """Execute the spec in an existing module's namespace.""" - name = self.spec.name - _imp.acquire_lock() - with _ModuleLockManager(name): - if sys.modules.get(name) is not module: - msg = 'module {!r} not in sys.modules'.format(name) - raise ImportError(msg, name=name) - if self.spec.loader is None: - if self.spec.submodule_search_locations is None: - raise ImportError('missing loader', name=self.spec.name) - # namespace package - self.init_module_attrs(module, _override=True) - return module - self.init_module_attrs(module, _override=True) - if not hasattr(self.spec.loader, 'exec_module'): - # XXX DeprecationWarning goes here... - self.spec.loader.load_module(name) - else: - self._exec(module) - return sys.modules[name] - - def _load_backward_compatible(self): - # XXX DeprecationWarning goes here... - spec = self.spec - # The module must be in sys.modules! - spec.loader.load_module(spec.name) - module = sys.modules[spec.name] - if getattr(module, '__loader__', None) is None: - try: - module.__loader__ = spec.loader - except AttributeError: - pass - if getattr(module, '__package__', None) is None: - try: - # Since module.__path__ may not line up with - # spec.submodule_search_paths, we can't necessarily rely - # on spec.parent here. - module.__package__ = module.__name__ - if not hasattr(module, '__path__'): - module.__package__ = spec.name.rpartition('.')[0] - except AttributeError: - pass - if getattr(module, '__spec__', None) is None: - try: - module.__spec__ = spec - except AttributeError: - pass - return module - - # XXX If we don't end up using this for pythonrun.c/runpy, we should - # get rid of it. - def _load_existing(self, module): - """Exec the spec'ed module into an existing module's namespace.""" - # For use by runpy. - with _installed_safely(module): - loaded = self.exec(module) - return loaded - - def _load_unlocked(self): - # A helper for direct use by the import system. - if self.spec.loader is not None: - # not a namespace package - if not hasattr(self.spec.loader, 'exec_module'): - return self._load_backward_compatible() - - module = self.create() - with _installed_safely(module): - if self.spec.loader is None: - if self.spec.submodule_search_locations is None: - raise ImportError('missing loader', name=self.spec.name) - # A namespace package so do nothing. - else: - self._exec(module) +def _load_unlocked(spec): + # A helper for direct use by the import system. + if spec.loader is not None: + # not a namespace package + if not hasattr(spec.loader, 'exec_module'): + return _load_backward_compatible(spec) + + module = module_from_spec(spec) + with _installed_safely(module): + if spec.loader is None: + if spec.submodule_search_locations is None: + raise ImportError('missing loader', name=spec.name) + # A namespace package so do nothing. + else: + spec.loader.exec_module(module) - # We don't ensure that the import-related module attributes get - # set in the sys.modules replacement case. Such modules are on - # their own. - return sys.modules[self.spec.name] + # We don't ensure that the import-related module attributes get + # set in the sys.modules replacement case. Such modules are on + # their own. + return sys.modules[spec.name] - # A method used during testing of _load_unlocked() and by - # _load_module_shim(). - def load(self): - """Return a new module object, loaded by the spec's loader. +# A method used during testing of _load_unlocked() and by +# _load_module_shim(). +def _load(spec): + """Return a new module object, loaded by the spec's loader. - The module is not added to its parent. + The module is not added to its parent. - If a module is already in sys.modules, that existing module gets - clobbered. + If a module is already in sys.modules, that existing module gets + clobbered. - """ - _imp.acquire_lock() - with _ModuleLockManager(self.spec.name): - return self._load_unlocked() + """ + _imp.acquire_lock() + with _ModuleLockManager(spec.name): + return _load_unlocked(spec) # Loaders ##################################################################### @@ -1238,7 +706,11 @@ class BuiltinImporter: @staticmethod def module_repr(module): - # XXX deprecate + """Return repr for the module. + + The method is deprecated. The import machinery does the job itself. + + """ return ''.format(module.__name__) @classmethod @@ -1256,19 +728,24 @@ def find_module(cls, fullname, path=None): If 'path' is ever specified then the search is considered a failure. + This method is deprecated. Use find_spec() instead. + """ spec = cls.find_spec(fullname, path) return spec.loader if spec is not None else None @classmethod - @_requires_builtin - def load_module(cls, fullname): - """Load a built-in module.""" - with _ManageReload(fullname): - module = _call_with_frames_removed(_imp.init_builtin, fullname) - module.__loader__ = cls - module.__package__ = '' - return module + def create_module(self, spec): + """Create a built-in module""" + if spec.name not in sys.builtin_module_names: + raise ImportError('{!r} is not a built-in module'.format(spec.name), + name=spec.name) + return _call_with_frames_removed(_imp.create_builtin, spec) + + @classmethod + def exec_module(self, module): + """Exec a built-in module""" + _call_with_frames_removed(_imp.exec_builtin, module) @classmethod @_requires_builtin @@ -1286,9 +763,10 @@ def get_source(cls, fullname): @_requires_builtin def is_package(cls, fullname): """Return False as built-in modules are never packages.""" - # XXX DeprecationWarning here... return False + load_module = classmethod(_load_module_shim) + class FrozenImporter: @@ -1301,7 +779,11 @@ class FrozenImporter: @staticmethod def module_repr(m): - # XXX deprecate + """Return repr for the module. + + The method is deprecated. The import machinery does the job itself. + + """ return ''.format(m.__name__) @classmethod @@ -1313,9 +795,17 @@ def find_spec(cls, fullname, path=None, target=None): @classmethod def find_module(cls, fullname, path=None): - """Find a frozen module.""" + """Find a frozen module. + + This method is deprecated. Use find_spec() instead. + + """ return cls if _imp.is_frozen(fullname) else None + @classmethod + def create_module(cls, spec): + """Use default semantics for module creation.""" + @staticmethod def exec_module(module): name = module.__spec__.name @@ -1327,7 +817,11 @@ def exec_module(module): @classmethod def load_module(cls, fullname): - """Load a frozen module.""" + """Load a frozen module. + + This method is deprecated. Use exec_module() instead. + + """ return _load_module_shim(cls, fullname) @classmethod @@ -1349,695 +843,6 @@ def is_package(cls, fullname): return _imp.is_frozen_package(fullname) -class WindowsRegistryFinder: - - """Meta path finder for modules declared in the Windows registry.""" - - REGISTRY_KEY = ( - 'Software\\Python\\PythonCore\\{sys_version}' - '\\Modules\\{fullname}') - REGISTRY_KEY_DEBUG = ( - 'Software\\Python\\PythonCore\\{sys_version}' - '\\Modules\\{fullname}\\Debug') - DEBUG_BUILD = False # Changed in _setup() - - @classmethod - def _open_registry(cls, key): - try: - return _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, key) - except OSError: - return _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key) - - @classmethod - def _search_registry(cls, fullname): - if cls.DEBUG_BUILD: - registry_key = cls.REGISTRY_KEY_DEBUG - else: - registry_key = cls.REGISTRY_KEY - key = registry_key.format(fullname=fullname, - sys_version=sys.version[:3]) - try: - with cls._open_registry(key) as hkey: - filepath = _winreg.QueryValue(hkey, '') - except OSError: - return None - return filepath - - @classmethod - def find_spec(cls, fullname, path=None, target=None): - # XXX untested! Need a Windows person to write tests (otherwise mock out appropriately) - filepath = cls._search_registry(fullname) - if filepath is None: - return None - try: - _path_stat(filepath) - except OSError: - return None - for loader, suffixes in _get_supported_file_loaders(): - if filepath.endswith(tuple(suffixes)): - spec = spec_from_loader(fullname, loader(fullname, filepath), - origin=filepath) - return spec - - @classmethod - def find_module(cls, fullname, path=None): - """Find module named in the registry.""" - spec = self.find_spec(fullname, path) - if spec is not None: - return spec.loader - else: - return None - - -class _LoaderBasics: - - """Base class of common code needed by both SourceLoader and - SourcelessFileLoader.""" - - # XXX deprecate? - def is_package(self, fullname): - """Concrete implementation of InspectLoader.is_package by checking if - the path returned by get_filename has a filename of '__init__.py'.""" - filename = _path_split(self.get_filename(fullname))[1] - filename_base = filename.rsplit('.', 1)[0] - tail_name = fullname.rpartition('.')[2] - return filename_base == '__init__' and tail_name != '__init__' - - def exec_module(self, module): - """Execute the module.""" - code = self.get_code(module.__name__) - if code is None: - raise ImportError('cannot load module {!r} when get_code() ' - 'returns None'.format(module.__name__)) - _call_with_frames_removed(exec, code, module.__dict__) - - load_module = _load_module_shim - - -class SourceLoader(_LoaderBasics): - - def path_mtime(self, path): - """Optional method that returns the modification time (an int) for the - specified path, where path is a str. - - Raises IOError when the path cannot be handled. - """ - raise IOError - - def path_stats(self, path): - """Optional method returning a metadata dict for the specified path - to by the path (str). - Possible keys: - - 'mtime' (mandatory) is the numeric timestamp of last source - code modification; - - 'size' (optional) is the size in bytes of the source code. - - Implementing this method allows the loader to read bytecode files. - Raises IOError when the path cannot be handled. - """ - return {'mtime': self.path_mtime(path)} - - def _cache_bytecode(self, source_path, cache_path, data): - """Optional method which writes data (bytes) to a file path (a str). - - Implementing this method allows for the writing of bytecode files. - - The source path is needed in order to correctly transfer permissions - """ - # For backwards compatibility, we delegate to set_data() - return self.set_data(cache_path, data) - - def set_data(self, path, data): - """Optional method which writes data (bytes) to a file path (a str). - - Implementing this method allows for the writing of bytecode files. - """ - - - def get_source(self, fullname): - """Concrete implementation of InspectLoader.get_source.""" - path = self.get_filename(fullname) - try: - source_bytes = self.get_data(path) - except OSError as exc: - raise ImportError('source not available through get_data()', - name=fullname) from exc - return decode_source(source_bytes) - - def source_to_code(self, data, path, *, _optimize=-1): - """Return the code object compiled from source. - - The 'data' argument can be any object type that compile() supports. - """ - return _call_with_frames_removed(compile, data, path, 'exec', - dont_inherit=True, optimize=_optimize) - - def get_code(self, fullname): - """Concrete implementation of InspectLoader.get_code. - - Reading of bytecode requires path_stats to be implemented. To write - bytecode, set_data must also be implemented. - - """ - source_path = self.get_filename(fullname) - source_mtime = None - try: - bytecode_path = cache_from_source(source_path) - except NotImplementedError: - bytecode_path = None - else: - try: - st = self.path_stats(source_path) - except IOError: - pass - else: - source_mtime = int(st['mtime']) - try: - data = self.get_data(bytecode_path) - except OSError: - pass - else: - try: - bytes_data = _validate_bytecode_header(data, - source_stats=st, name=fullname, - path=bytecode_path) - except (ImportError, EOFError): - pass - else: - _verbose_message('{} matches {}', bytecode_path, - source_path) - return _compile_bytecode(bytes_data, name=fullname, - bytecode_path=bytecode_path, - source_path=source_path) - source_bytes = self.get_data(source_path) - code_object = self.source_to_code(source_bytes, source_path) - _verbose_message('code object from {}', source_path) - if (not sys.dont_write_bytecode and bytecode_path is not None and - source_mtime is not None): - data = _code_to_bytecode(code_object, source_mtime, - len(source_bytes)) - try: - self._cache_bytecode(source_path, bytecode_path, data) - _verbose_message('wrote {!r}', bytecode_path) - except NotImplementedError: - pass - return code_object - - -class FileLoader: - - """Base file loader class which implements the loader protocol methods that - require file system usage.""" - - def __init__(self, fullname, path): - """Cache the module name and the path to the file found by the - finder.""" - self.name = fullname - self.path = path - - @_check_name - def load_module(self, fullname): - """Load a module from a file.""" - # The only reason for this method is for the name check. - - # Issue #14857: Avoid the zero-argument form of super so the implementation - # of that form can be updated without breaking the frozen module - return super(FileLoader, self).load_module(fullname) - - @_check_name - def get_filename(self, fullname): - """Return the path to the source file as found by the finder.""" - return self.path - - def get_data(self, path): - """Return the data from path as raw bytes.""" - with _io.FileIO(path, 'r') as file: - return file.read() - - -class SourceFileLoader(FileLoader, SourceLoader): - - """Concrete implementation of SourceLoader using the file system.""" - - def path_stats(self, path): - """Return the metadata for the path.""" - st = _path_stat(path) - return {'mtime': st.st_mtime, 'size': st.st_size} - - def _cache_bytecode(self, source_path, bytecode_path, data): - # Adapt between the two APIs - mode = _calc_mode(source_path) - return self.set_data(bytecode_path, data, _mode=mode) - - def set_data(self, path, data, *, _mode=0o666): - """Write bytes data to a file.""" - parent, filename = _path_split(path) - path_parts = [] - # Figure out what directories are missing. - while parent and not _path_isdir(parent): - parent, part = _path_split(parent) - path_parts.append(part) - # Create needed directories. - for part in reversed(path_parts): - parent = _path_join(parent, part) - try: - _os.mkdir(parent) - except FileExistsError: - # Probably another Python process already created the dir. - continue - except OSError as exc: - # Could be a permission error, read-only filesystem: just forget - # about writing the data. - _verbose_message('could not create {!r}: {!r}', parent, exc) - return - try: - _write_atomic(path, data, _mode) - _verbose_message('created {!r}', path) - except OSError as exc: - # Same as above: just don't write the bytecode. - _verbose_message('could not create {!r}: {!r}', path, exc) - - -class SourcelessFileLoader(FileLoader, _LoaderBasics): - - """Loader which handles sourceless file imports.""" - - def get_code(self, fullname): - path = self.get_filename(fullname) - data = self.get_data(path) - bytes_data = _validate_bytecode_header(data, name=fullname, path=path) - return _compile_bytecode(bytes_data, name=fullname, bytecode_path=path) - - def get_source(self, fullname): - """Return None as there is no source code.""" - return None - - -# Filled in by _setup(). -EXTENSION_SUFFIXES = [] - - -class ExtensionFileLoader: - - """Loader for extension modules. - - The constructor is designed to work with FileFinder. - - """ - - def __init__(self, name, path): - self.name = name - self.path = path - - @_check_name - def load_module(self, fullname): - """Load an extension module.""" - with _ManageReload(fullname): - module = _call_with_frames_removed(_imp.load_dynamic, - fullname, self.path) - _verbose_message('extension module loaded from {!r}', self.path) - is_package = self.is_package(fullname) - if is_package and not hasattr(module, '__path__'): - module.__path__ = [_path_split(self.path)[0]] - module.__loader__ = self - module.__package__ = module.__name__ - if not is_package: - module.__package__ = module.__package__.rpartition('.')[0] - return module - - def is_package(self, fullname): - """Return True if the extension module is a package.""" - file_name = _path_split(self.path)[1] - return any(file_name == '__init__' + suffix - for suffix in EXTENSION_SUFFIXES) - - def get_code(self, fullname): - """Return None as an extension module cannot create a code object.""" - return None - - def get_source(self, fullname): - """Return None as extension modules have no source code.""" - return None - - @_check_name - def get_filename(self, fullname): - """Return the path to the source file as found by the finder.""" - return self.path - - -class _NamespacePath: - """Represents a namespace package's path. It uses the module name - to find its parent module, and from there it looks up the parent's - __path__. When this changes, the module's own path is recomputed, - using path_finder. For top-level modules, the parent module's path - is sys.path.""" - - def __init__(self, name, path, path_finder): - self._name = name - self._path = path - self._last_parent_path = tuple(self._get_parent_path()) - self._path_finder = path_finder - - def _find_parent_path_names(self): - """Returns a tuple of (parent-module-name, parent-path-attr-name)""" - parent, dot, me = self._name.rpartition('.') - if dot == '': - # This is a top-level module. sys.path contains the parent path. - return 'sys', 'path' - # Not a top-level module. parent-module.__path__ contains the - # parent path. - return parent, '__path__' - - def _get_parent_path(self): - parent_module_name, path_attr_name = self._find_parent_path_names() - return getattr(sys.modules[parent_module_name], path_attr_name) - - def _recalculate(self): - # If the parent's path has changed, recalculate _path - parent_path = tuple(self._get_parent_path()) # Make a copy - if parent_path != self._last_parent_path: - spec = self._path_finder(self._name, parent_path) - # Note that no changes are made if a loader is returned, but we - # do remember the new parent path - if spec is not None and spec.loader is None: - if spec.submodule_search_locations: - self._path = spec.submodule_search_locations - self._last_parent_path = parent_path # Save the copy - return self._path - - def __iter__(self): - return iter(self._recalculate()) - - def __len__(self): - return len(self._recalculate()) - - def __repr__(self): - return '_NamespacePath({!r})'.format(self._path) - - def __contains__(self, item): - return item in self._recalculate() - - def append(self, item): - self._path.append(item) - - -# We use this exclusively in init_module_attrs() for backward-compatibility. -class _NamespaceLoader: - def __init__(self, name, path, path_finder): - self._path = _NamespacePath(name, path, path_finder) - - # XXX Deprecate - @classmethod - def module_repr(cls, module): - return ''.format(module.__name__) - - def is_package(self, fullname): - return True - - def get_source(self, fullname): - return '' - - def get_code(self, fullname): - return compile('', '', 'exec', dont_inherit=True) - - # XXX Deprecate - def load_module(self, fullname): - """Load a namespace module.""" - _verbose_message('namespace module loaded with path {!r}', self._path) - return _load_module_shim(self, fullname) - - -# Finders ##################################################################### - -class PathFinder: - - """Meta path finder for sys.path and package __path__ attributes.""" - - @classmethod - def invalidate_caches(cls): - """Call the invalidate_caches() method on all path entry finders - stored in sys.path_importer_caches (where implemented).""" - for finder in sys.path_importer_cache.values(): - if hasattr(finder, 'invalidate_caches'): - finder.invalidate_caches() - - @classmethod - def _path_hooks(cls, path): - """Search sequence of hooks for a finder for 'path'. - - If 'hooks' is false then use sys.path_hooks. - - """ - if not sys.path_hooks: - _warnings.warn('sys.path_hooks is empty', ImportWarning) - for hook in sys.path_hooks: - try: - return hook(path) - except ImportError: - continue - else: - return None - - @classmethod - def _path_importer_cache(cls, path): - """Get the finder for the path entry from sys.path_importer_cache. - - If the path entry is not in the cache, find the appropriate finder - and cache it. If no finder is available, store None. - - """ - if path == '': - path = _os.getcwd() - try: - finder = sys.path_importer_cache[path] - except KeyError: - finder = cls._path_hooks(path) - sys.path_importer_cache[path] = finder - return finder - - @classmethod - def _legacy_get_spec(cls, fullname, finder): - if hasattr(finder, 'find_loader'): - loader, portions = finder.find_loader(fullname) - else: - loader = finder.find_module(fullname) - portions = None - if loader is not None: - return spec_from_loader(fullname, loader) - spec = ModuleSpec(fullname, None) - spec.submodule_search_locations = portions - return spec - - @classmethod - def _get_spec(cls, fullname, path, target=None): - """Find the loader or namespace_path for this module/package name.""" - # If this ends up being a namespace package, namespace_path is - # the list of paths that will become its __path__ - namespace_path = [] - for entry in path: - if not isinstance(entry, (str, bytes)): - continue - finder = cls._path_importer_cache(entry) - if finder is not None: - if hasattr(finder, 'find_spec'): - spec = finder.find_spec(fullname, target) - else: - spec = cls._legacy_get_spec(fullname, finder) - if spec is None: - continue - if spec.loader is not None: - return spec - portions = spec.submodule_search_locations - if portions is None: - raise ImportError('spec missing loader') - # This is possibly part of a namespace package. - # Remember these path entries (if any) for when we - # create a namespace package, and continue iterating - # on path. - namespace_path.extend(portions) - else: - spec = ModuleSpec(fullname, None) - spec.submodule_search_locations = namespace_path - return spec - - @classmethod - def find_spec(cls, fullname, path=None, target=None): - """find the module on sys.path or 'path' based on sys.path_hooks and - sys.path_importer_cache.""" - if path is None: - path = sys.path - spec = cls._get_spec(fullname, path, target) - if spec is None: - return None - elif spec.loader is None: - namespace_path = spec.submodule_search_locations - if namespace_path: - # We found at least one namespace path. Return a - # spec which can create the namespace package. - spec.origin = 'namespace' - spec.submodule_search_locations = _NamespacePath(fullname, namespace_path, cls._get_spec) - return spec - else: - return None - else: - return spec - - @classmethod - def find_module(cls, fullname, path=None): - """find the module on sys.path or 'path' based on sys.path_hooks and - sys.path_importer_cache.""" - # XXX Deprecation warning here. - spec = cls.find_spec(fullname, path) - if spec is None: - return None - return spec.loader - - -class FileFinder: - - """File-based finder. - - Interactions with the file system are cached for performance, being - refreshed when the directory the finder is handling has been modified. - - """ - - def __init__(self, path, *loader_details): - """Initialize with the path to search on and a variable number of - 2-tuples containing the loader and the file suffixes the loader - recognizes.""" - loaders = [] - for loader, suffixes in loader_details: - loaders.extend((suffix, loader) for suffix in suffixes) - self._loaders = loaders - # Base (directory) path - self.path = path or '.' - self._path_mtime = -1 - self._path_cache = set() - self._relaxed_path_cache = set() - - def invalidate_caches(self): - """Invalidate the directory mtime.""" - self._path_mtime = -1 - - find_module = _find_module_shim - - def find_loader(self, fullname): - """Try to find a loader for the specified module, or the namespace - package portions. Returns (loader, list-of-portions).""" - spec = self.find_spec(fullname) - if spec is None: - return None, [] - return spec.loader, spec.submodule_search_locations or [] - - def _get_spec(self, loader_class, fullname, path, submodule_search_locations, target): - loader = loader_class(fullname, path) - try: - get_spec = loader._get_spec - except AttributeError: - return spec_from_file_location(fullname, path, loader=loader, - submodule_search_locations=submodule_search_locations) - else: - return get_spec(fullname, path, submodule_search_locations, target) - - def find_spec(self, fullname, target=None): - """Try to find a loader for the specified module, or the namespace - package portions. Returns (loader, list-of-portions).""" - is_namespace = False - tail_module = fullname.rpartition('.')[2] - try: - mtime = _path_stat(self.path or _os.getcwd()).st_mtime - except OSError: - mtime = -1 - if mtime != self._path_mtime: - self._fill_cache() - self._path_mtime = mtime - # tail_module keeps the original casing, for __file__ and friends - if _relax_case(): - cache = self._relaxed_path_cache - cache_module = tail_module.lower() - else: - cache = self._path_cache - cache_module = tail_module - # Check if the module is the name of a directory (and thus a package). - if cache_module in cache: - base_path = _path_join(self.path, tail_module) - for suffix, loader_class in self._loaders: - init_filename = '__init__' + suffix - full_path = _path_join(base_path, init_filename) - if _path_isfile(full_path): - return self._get_spec(loader_class, fullname, full_path, [base_path], target) - else: - # If a namespace package, return the path if we don't - # find a module in the next section. - is_namespace = _path_isdir(base_path) - # Check for a file w/ a proper suffix exists. - for suffix, loader_class in self._loaders: - full_path = _path_join(self.path, tail_module + suffix) - _verbose_message('trying {}'.format(full_path), verbosity=2) - if cache_module + suffix in cache: - if _path_isfile(full_path): - return self._get_spec(loader_class, fullname, full_path, None, target) - if is_namespace: - _verbose_message('possible namespace for {}'.format(base_path)) - spec = ModuleSpec(fullname, None) - spec.submodule_search_locations = [base_path] - return spec - return None - - def _fill_cache(self): - """Fill the cache of potential modules and packages for this directory.""" - path = self.path - try: - contents = _os.listdir(path or _os.getcwd()) - except (FileNotFoundError, PermissionError, NotADirectoryError): - # Directory has either been removed, turned into a file, or made - # unreadable. - contents = [] - # We store two cached versions, to handle runtime changes of the - # PYTHONCASEOK environment variable. - if not sys.platform.startswith('win'): - self._path_cache = set(contents) - else: - # Windows users can import modules with case-insensitive file - # suffixes (for legacy reasons). Make the suffix lowercase here - # so it's done once instead of for every import. This is safe as - # the specified suffixes to check against are always specified in a - # case-sensitive manner. - lower_suffix_contents = set() - for item in contents: - name, dot, suffix = item.partition('.') - if dot: - new_name = '{}.{}'.format(name, suffix.lower()) - else: - new_name = name - lower_suffix_contents.add(new_name) - self._path_cache = lower_suffix_contents - if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS): - self._relaxed_path_cache = {fn.lower() for fn in contents} - - @classmethod - def path_hook(cls, *loader_details): - """A class method which returns a closure to use on sys.path_hook - which will return an instance using the specified loaders and the path - called on the closure. - - If the path called on the closure is not a directory, ImportError is - raised. - - """ - def path_hook_for_FileFinder(path): - """Path hook for importlib.machinery.FileFinder.""" - if not _path_isdir(path): - raise ImportError('only directories are supported', path=path) - return cls(path, *loader_details) - - return path_hook_for_FileFinder - - def __repr__(self): - return 'FileFinder({!r})'.format(self.path) - - # Import itself ############################################################### class _ImportLockContext: @@ -2062,9 +867,18 @@ def _resolve_name(name, package, level): return '{}.{}'.format(base, name) if name else base +def _find_spec_legacy(finder, name, path): + # This would be a good place for a DeprecationWarning if + # we ended up going that route. + loader = finder.find_module(name, path) + if loader is None: + return None + return spec_from_loader(name, loader) + + def _find_spec(name, path, target=None): """Find a module's loader.""" - if not sys.meta_path: + if sys.meta_path is not None and not sys.meta_path: _warnings.warn('sys.meta_path is empty', ImportWarning) # We check sys.modules here for the reload case. While a passed-in # target will usually indicate a reload there is no guarantee, whereas @@ -2075,10 +889,9 @@ def _find_spec(name, path, target=None): try: find_spec = finder.find_spec except AttributeError: - loader = finder.find_module(name, path) - if loader is None: + spec = _find_spec_legacy(finder, name, path) + if spec is None: continue - spec = spec_from_loader(name, loader) else: spec = find_spec(name, path, target) if spec is not None: @@ -2137,12 +950,12 @@ def _find_and_load_unlocked(name, import_): path = parent_module.__path__ except AttributeError: msg = (_ERR_MSG + '; {!r} is not a package').format(name, parent) - raise ImportError(msg, name=name) + raise ImportError(msg, name=name) from None spec = _find_spec(name, path) if spec is None: raise ImportError(_ERR_MSG.format(name), name=name) else: - module = _SpecMethods(spec)._load_unlocked() + module = _load_unlocked(spec) if parent: # Set the module as an attribute on its parent. parent_module = sys.modules[parent] @@ -2227,17 +1040,6 @@ def _calc___package__(globals): return package -def _get_supported_file_loaders(): - """Returns a list of file-based module loaders. - - Each item is a tuple (loader, suffixes). - """ - extensions = ExtensionFileLoader, _imp.extension_suffixes() - source = SourceFileLoader, SOURCE_SUFFIXES - bytecode = SourcelessFileLoader, BYTECODE_SUFFIXES - return [extensions, source, bytecode] - - def __import__(name, globals=None, locals=None, fromlist=(), level=0): """Import a module. @@ -2277,8 +1079,7 @@ def _builtin_from_name(name): spec = BuiltinImporter.find_spec(name) if spec is None: raise ImportError('no built-in module named ' + name) - methods = _SpecMethods(spec) - return methods._load_unlocked() + return _load_unlocked(spec) def _setup(sys_module, _imp_module): @@ -2289,15 +1090,10 @@ def _setup(sys_module, _imp_module): modules, those two modules must be explicitly passed in. """ - global _imp, sys, BYTECODE_SUFFIXES + global _imp, sys _imp = _imp_module sys = sys_module - if sys.flags.optimize: - BYTECODE_SUFFIXES = OPTIMIZED_BYTECODE_SUFFIXES - else: - BYTECODE_SUFFIXES = DEBUG_BYTECODE_SUFFIXES - # Set up the spec for existing builtin/frozen modules. module_type = type(sys) for name, module in sys.modules.items(): @@ -2309,39 +1105,17 @@ def _setup(sys_module, _imp_module): else: continue spec = _spec_from_module(module, loader) - methods = _SpecMethods(spec) - methods.init_module_attrs(module) + _init_module_attrs(spec, module) # Directly load built-in modules needed during bootstrap. self_module = sys.modules[__name__] - for builtin_name in ('_io', '_warnings', 'builtins', 'marshal'): + for builtin_name in ('_warnings',): if builtin_name not in sys.modules: builtin_module = _builtin_from_name(builtin_name) else: builtin_module = sys.modules[builtin_name] setattr(self_module, builtin_name, builtin_module) - # Directly load the os module (needed during bootstrap). - os_details = ('posix', ['/']), ('nt', ['\\', '/']) - for builtin_os, path_separators in os_details: - # Assumption made in _path_join() - assert all(len(sep) == 1 for sep in path_separators) - path_sep = path_separators[0] - if builtin_os in sys.modules: - os_module = sys.modules[builtin_os] - break - else: - try: - os_module = _builtin_from_name(builtin_os) - break - except ImportError: - continue - else: - raise ImportError('importlib requires posix or nt') - setattr(self_module, '_os', os_module) - setattr(self_module, 'path_sep', path_sep) - setattr(self_module, 'path_separators', ''.join(path_separators)) - # Directly load the _thread module (needed during bootstrap). try: thread_module = _builtin_from_name('_thread') @@ -2354,27 +1128,15 @@ def _setup(sys_module, _imp_module): weakref_module = _builtin_from_name('_weakref') setattr(self_module, '_weakref', weakref_module) - # Directly load the winreg module (needed during bootstrap). - if builtin_os == 'nt': - winreg_module = _builtin_from_name('winreg') - setattr(self_module, '_winreg', winreg_module) - - # Constants - setattr(self_module, '_relax_case', _make_relax_case()) - EXTENSION_SUFFIXES.extend(_imp.extension_suffixes()) - if builtin_os == 'nt': - SOURCE_SUFFIXES.append('.pyw') - if '_d.pyd' in EXTENSION_SUFFIXES: - WindowsRegistryFinder.DEBUG_BUILD = True - def _install(sys_module, _imp_module): """Install importlib as the implementation of import.""" _setup(sys_module, _imp_module) - supported_loaders = _get_supported_file_loaders() - sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders)]) + sys.meta_path.append(BuiltinImporter) sys.meta_path.append(FrozenImporter) - if _os.__name__ == 'nt': - sys.meta_path.append(WindowsRegistryFinder) - sys.meta_path.append(PathFinder) + + global _bootstrap_external + import _frozen_importlib_external + _bootstrap_external = _frozen_importlib_external + _frozen_importlib_external._install(sys.modules[__name__]) diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py new file mode 100644 index 000000000000..e0a1200547bd --- /dev/null +++ b/Lib/importlib/_bootstrap_external.py @@ -0,0 +1,1422 @@ +"""Core implementation of path-based import. + +This module is NOT meant to be directly imported! It has been designed such +that it can be bootstrapped into Python as the implementation of import. As +such it requires the injection of specific modules and attributes in order to +work. One should use importlib as the public-facing version of this module. + +""" +# +# IMPORTANT: Whenever making changes to this module, be sure to run +# a top-level make in order to get the frozen version of the module +# updated. Not doing so will result in the Makefile to fail for +# all others who don't have a ./python around to freeze the module +# in the early stages of compilation. +# + +# See importlib._setup() for what is injected into the global namespace. + +# When editing this code be aware that code executed at import time CANNOT +# reference any injected objects! This includes not only global code but also +# anything specified at the class level. + +# Bootstrap-related code ###################################################### + +_CASE_INSENSITIVE_PLATFORMS = 'win', 'cygwin', 'darwin' + + +def _make_relax_case(): + if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS): + def _relax_case(): + """True if filenames must be checked case-insensitively.""" + return b'PYTHONCASEOK' in _os.environ + else: + def _relax_case(): + """True if filenames must be checked case-insensitively.""" + return False + return _relax_case + + +def _w_long(x): + """Convert a 32-bit integer to little-endian.""" + return (int(x) & 0xFFFFFFFF).to_bytes(4, 'little') + + +def _r_long(int_bytes): + """Convert 4 bytes in little-endian to an integer.""" + return int.from_bytes(int_bytes, 'little') + + +def _path_join(*path_parts): + """Replacement for os.path.join().""" + return path_sep.join([part.rstrip(path_separators) + for part in path_parts if part]) + + +def _path_split(path): + """Replacement for os.path.split().""" + if len(path_separators) == 1: + front, _, tail = path.rpartition(path_sep) + return front, tail + for x in reversed(path): + if x in path_separators: + front, tail = path.rsplit(x, maxsplit=1) + return front, tail + return '', path + + +def _path_stat(path): + """Stat the path. + + Made a separate function to make it easier to override in experiments + (e.g. cache stat results). + + """ + return _os.stat(path) + + +def _path_is_mode_type(path, mode): + """Test whether the path is the specified mode type.""" + try: + stat_info = _path_stat(path) + except OSError: + return False + return (stat_info.st_mode & 0o170000) == mode + + +def _path_isfile(path): + """Replacement for os.path.isfile.""" + return _path_is_mode_type(path, 0o100000) + + +def _path_isdir(path): + """Replacement for os.path.isdir.""" + if not path: + path = _os.getcwd() + return _path_is_mode_type(path, 0o040000) + + +def _write_atomic(path, data, mode=0o666): + """Best-effort function to write data to a path atomically. + Be prepared to handle a FileExistsError if concurrent writing of the + temporary file is attempted.""" + # id() is used to generate a pseudo-random filename. + path_tmp = '{}.{}'.format(path, id(path)) + fd = _os.open(path_tmp, + _os.O_EXCL | _os.O_CREAT | _os.O_WRONLY, mode & 0o666) + try: + # We first write data to a temporary file, and then use os.replace() to + # perform an atomic rename. + with _io.FileIO(fd, 'wb') as file: + file.write(data) + _os.replace(path_tmp, path) + except OSError: + try: + _os.unlink(path_tmp) + except OSError: + pass + raise + + +_code_type = type(_write_atomic.__code__) + + +# Finder/loader utility code ############################################### + +# Magic word to reject .pyc files generated by other Python versions. +# It should change for each incompatible change to the bytecode. +# +# The value of CR and LF is incorporated so if you ever read or write +# a .pyc file in text mode the magic number will be wrong; also, the +# Apple MPW compiler swaps their values, botching string constants. +# +# The magic numbers must be spaced apart at least 2 values, as the +# -U interpeter flag will cause MAGIC+1 being used. They have been +# odd numbers for some time now. +# +# There were a variety of old schemes for setting the magic number. +# The current working scheme is to increment the previous value by +# 10. +# +# Starting with the adoption of PEP 3147 in Python 3.2, every bump in magic +# number also includes a new "magic tag", i.e. a human readable string used +# to represent the magic number in __pycache__ directories. When you change +# the magic number, you must also set a new unique magic tag. Generally this +# can be named after the Python major version of the magic number bump, but +# it can really be anything, as long as it's different than anything else +# that's come before. The tags are included in the following table, starting +# with Python 3.2a0. +# +# Known values: +# Python 1.5: 20121 +# Python 1.5.1: 20121 +# Python 1.5.2: 20121 +# Python 1.6: 50428 +# Python 2.0: 50823 +# Python 2.0.1: 50823 +# Python 2.1: 60202 +# Python 2.1.1: 60202 +# Python 2.1.2: 60202 +# Python 2.2: 60717 +# Python 2.3a0: 62011 +# Python 2.3a0: 62021 +# Python 2.3a0: 62011 (!) +# Python 2.4a0: 62041 +# Python 2.4a3: 62051 +# Python 2.4b1: 62061 +# Python 2.5a0: 62071 +# Python 2.5a0: 62081 (ast-branch) +# Python 2.5a0: 62091 (with) +# Python 2.5a0: 62092 (changed WITH_CLEANUP opcode) +# Python 2.5b3: 62101 (fix wrong code: for x, in ...) +# Python 2.5b3: 62111 (fix wrong code: x += yield) +# Python 2.5c1: 62121 (fix wrong lnotab with for loops and +# storing constants that should have been removed) +# Python 2.5c2: 62131 (fix wrong code: for x, in ... in listcomp/genexp) +# Python 2.6a0: 62151 (peephole optimizations and STORE_MAP opcode) +# Python 2.6a1: 62161 (WITH_CLEANUP optimization) +# Python 2.7a0: 62171 (optimize list comprehensions/change LIST_APPEND) +# Python 2.7a0: 62181 (optimize conditional branches: +# introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE) +# Python 2.7a0 62191 (introduce SETUP_WITH) +# Python 2.7a0 62201 (introduce BUILD_SET) +# Python 2.7a0 62211 (introduce MAP_ADD and SET_ADD) +# Python 3000: 3000 +# 3010 (removed UNARY_CONVERT) +# 3020 (added BUILD_SET) +# 3030 (added keyword-only parameters) +# 3040 (added signature annotations) +# 3050 (print becomes a function) +# 3060 (PEP 3115 metaclass syntax) +# 3061 (string literals become unicode) +# 3071 (PEP 3109 raise changes) +# 3081 (PEP 3137 make __file__ and __name__ unicode) +# 3091 (kill str8 interning) +# 3101 (merge from 2.6a0, see 62151) +# 3103 (__file__ points to source file) +# Python 3.0a4: 3111 (WITH_CLEANUP optimization). +# Python 3.0a5: 3131 (lexical exception stacking, including POP_EXCEPT) +# Python 3.1a0: 3141 (optimize list, set and dict comprehensions: +# change LIST_APPEND and SET_ADD, add MAP_ADD) +# Python 3.1a0: 3151 (optimize conditional branches: +# introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE) +# Python 3.2a0: 3160 (add SETUP_WITH) +# tag: cpython-32 +# Python 3.2a1: 3170 (add DUP_TOP_TWO, remove DUP_TOPX and ROT_FOUR) +# tag: cpython-32 +# Python 3.2a2 3180 (add DELETE_DEREF) +# Python 3.3a0 3190 __class__ super closure changed +# Python 3.3a0 3200 (__qualname__ added) +# 3210 (added size modulo 2**32 to the pyc header) +# Python 3.3a1 3220 (changed PEP 380 implementation) +# Python 3.3a4 3230 (revert changes to implicit __class__ closure) +# Python 3.4a1 3250 (evaluate positional default arguments before +# keyword-only defaults) +# Python 3.4a1 3260 (add LOAD_CLASSDEREF; allow locals of class to override +# free vars) +# Python 3.4a1 3270 (various tweaks to the __class__ closure) +# Python 3.4a1 3280 (remove implicit class argument) +# Python 3.4a4 3290 (changes to __qualname__ computation) +# Python 3.4a4 3300 (more changes to __qualname__ computation) +# Python 3.4rc2 3310 (alter __qualname__ computation) +# Python 3.5a0 3320 (matrix multiplication operator) +# Python 3.5b1 3330 (PEP 448: Additional Unpacking Generalizations) +# Python 3.5b2 3340 (fix dictionary display evaluation order #11205) +# Python 3.5b2 3350 (add GET_YIELD_FROM_ITER opcode #24400) +# +# MAGIC must change whenever the bytecode emitted by the compiler may no +# longer be understood by older implementations of the eval loop (usually +# due to the addition of new opcodes). + +MAGIC_NUMBER = (3350).to_bytes(2, 'little') + b'\r\n' +_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c + +_PYCACHE = '__pycache__' +_OPT = 'opt-' + +SOURCE_SUFFIXES = ['.py'] # _setup() adds .pyw as needed. + +BYTECODE_SUFFIXES = ['.pyc'] +# Deprecated. +DEBUG_BYTECODE_SUFFIXES = OPTIMIZED_BYTECODE_SUFFIXES = BYTECODE_SUFFIXES + +def cache_from_source(path, debug_override=None, *, optimization=None): + """Given the path to a .py file, return the path to its .pyc file. + + The .py file does not need to exist; this simply returns the path to the + .pyc file calculated as if the .py file were imported. + + The 'optimization' parameter controls the presumed optimization level of + the bytecode file. If 'optimization' is not None, the string representation + of the argument is taken and verified to be alphanumeric (else ValueError + is raised). + + The debug_override parameter is deprecated. If debug_override is not None, + a True value is the same as setting 'optimization' to the empty string + while a False value is equivalent to setting 'optimization' to '1'. + + If sys.implementation.cache_tag is None then NotImplementedError is raised. + + """ + if debug_override is not None: + _warnings.warn('the debug_override parameter is deprecated; use ' + "'optimization' instead", DeprecationWarning) + if optimization is not None: + message = 'debug_override or optimization must be set to None' + raise TypeError(message) + optimization = '' if debug_override else 1 + head, tail = _path_split(path) + base, sep, rest = tail.rpartition('.') + tag = sys.implementation.cache_tag + if tag is None: + raise NotImplementedError('sys.implementation.cache_tag is None') + almost_filename = ''.join([(base if base else rest), sep, tag]) + if optimization is None: + if sys.flags.optimize == 0: + optimization = '' + else: + optimization = sys.flags.optimize + optimization = str(optimization) + if optimization != '': + if not optimization.isalnum(): + raise ValueError('{!r} is not alphanumeric'.format(optimization)) + almost_filename = '{}.{}{}'.format(almost_filename, _OPT, optimization) + return _path_join(head, _PYCACHE, almost_filename + BYTECODE_SUFFIXES[0]) + + +def source_from_cache(path): + """Given the path to a .pyc. file, return the path to its .py file. + + The .pyc file does not need to exist; this simply returns the path to + the .py file calculated to correspond to the .pyc file. If path does + not conform to PEP 3147/488 format, ValueError will be raised. If + sys.implementation.cache_tag is None then NotImplementedError is raised. + + """ + if sys.implementation.cache_tag is None: + raise NotImplementedError('sys.implementation.cache_tag is None') + head, pycache_filename = _path_split(path) + head, pycache = _path_split(head) + if pycache != _PYCACHE: + raise ValueError('{} not bottom-level directory in ' + '{!r}'.format(_PYCACHE, path)) + dot_count = pycache_filename.count('.') + if dot_count not in {2, 3}: + raise ValueError('expected only 2 or 3 dots in ' + '{!r}'.format(pycache_filename)) + elif dot_count == 3: + optimization = pycache_filename.rsplit('.', 2)[-2] + if not optimization.startswith(_OPT): + raise ValueError("optimization portion of filename does not start " + "with {!r}".format(_OPT)) + opt_level = optimization[len(_OPT):] + if not opt_level.isalnum(): + raise ValueError("optimization level {!r} is not an alphanumeric " + "value".format(optimization)) + base_filename = pycache_filename.partition('.')[0] + return _path_join(head, base_filename + SOURCE_SUFFIXES[0]) + + +def _get_sourcefile(bytecode_path): + """Convert a bytecode file path to a source path (if possible). + + This function exists purely for backwards-compatibility for + PyImport_ExecCodeModuleWithFilenames() in the C API. + + """ + if len(bytecode_path) == 0: + return None + rest, _, extension = bytecode_path.rpartition('.') + if not rest or extension.lower()[-3:-1] != 'py': + return bytecode_path + try: + source_path = source_from_cache(bytecode_path) + except (NotImplementedError, ValueError): + source_path = bytecode_path[:-1] + return source_path if _path_isfile(source_path) else bytecode_path + + +def _get_cached(filename): + if filename.endswith(tuple(SOURCE_SUFFIXES)): + try: + return cache_from_source(filename) + except NotImplementedError: + pass + elif filename.endswith(tuple(BYTECODE_SUFFIXES)): + return filename + else: + return None + + +def _calc_mode(path): + """Calculate the mode permissions for a bytecode file.""" + try: + mode = _path_stat(path).st_mode + except OSError: + mode = 0o666 + # We always ensure write access so we can update cached files + # later even when the source files are read-only on Windows (#6074) + mode |= 0o200 + return mode + + +def _check_name(method): + """Decorator to verify that the module being requested matches the one the + loader can handle. + + The first argument (self) must define _name which the second argument is + compared against. If the comparison fails then ImportError is raised. + + """ + def _check_name_wrapper(self, name=None, *args, **kwargs): + if name is None: + name = self.name + elif self.name != name: + raise ImportError('loader for %s cannot handle %s' % + (self.name, name), name=name) + return method(self, name, *args, **kwargs) + try: + _wrap = _bootstrap._wrap + except NameError: + # XXX yuck + def _wrap(new, old): + for replace in ['__module__', '__name__', '__qualname__', '__doc__']: + if hasattr(old, replace): + setattr(new, replace, getattr(old, replace)) + new.__dict__.update(old.__dict__) + _wrap(_check_name_wrapper, method) + return _check_name_wrapper + + +def _find_module_shim(self, fullname): + """Try to find a loader for the specified module by delegating to + self.find_loader(). + + This method is deprecated in favor of finder.find_spec(). + + """ + # Call find_loader(). If it returns a string (indicating this + # is a namespace package portion), generate a warning and + # return None. + loader, portions = self.find_loader(fullname) + if loader is None and len(portions): + msg = 'Not importing directory {}: missing __init__' + _warnings.warn(msg.format(portions[0]), ImportWarning) + return loader + + +def _validate_bytecode_header(data, source_stats=None, name=None, path=None): + """Validate the header of the passed-in bytecode against source_stats (if + given) and returning the bytecode that can be compiled by compile(). + + All other arguments are used to enhance error reporting. + + ImportError is raised when the magic number is incorrect or the bytecode is + found to be stale. EOFError is raised when the data is found to be + truncated. + + """ + exc_details = {} + if name is not None: + exc_details['name'] = name + else: + # To prevent having to make all messages have a conditional name. + name = '' + if path is not None: + exc_details['path'] = path + magic = data[:4] + raw_timestamp = data[4:8] + raw_size = data[8:12] + if magic != MAGIC_NUMBER: + message = 'bad magic number in {!r}: {!r}'.format(name, magic) + _bootstrap._verbose_message('{}', message) + raise ImportError(message, **exc_details) + elif len(raw_timestamp) != 4: + message = 'reached EOF while reading timestamp in {!r}'.format(name) + _bootstrap._verbose_message('{}', message) + raise EOFError(message) + elif len(raw_size) != 4: + message = 'reached EOF while reading size of source in {!r}'.format(name) + _bootstrap._verbose_message('{}', message) + raise EOFError(message) + if source_stats is not None: + try: + source_mtime = int(source_stats['mtime']) + except KeyError: + pass + else: + if _r_long(raw_timestamp) != source_mtime: + message = 'bytecode is stale for {!r}'.format(name) + _bootstrap._verbose_message('{}', message) + raise ImportError(message, **exc_details) + try: + source_size = source_stats['size'] & 0xFFFFFFFF + except KeyError: + pass + else: + if _r_long(raw_size) != source_size: + raise ImportError('bytecode is stale for {!r}'.format(name), + **exc_details) + return data[12:] + + +def _compile_bytecode(data, name=None, bytecode_path=None, source_path=None): + """Compile bytecode as returned by _validate_bytecode_header().""" + code = marshal.loads(data) + if isinstance(code, _code_type): + _bootstrap._verbose_message('code object from {!r}', bytecode_path) + if source_path is not None: + _imp._fix_co_filename(code, source_path) + return code + else: + raise ImportError('Non-code object in {!r}'.format(bytecode_path), + name=name, path=bytecode_path) + +def _code_to_bytecode(code, mtime=0, source_size=0): + """Compile a code object into bytecode for writing out to a byte-compiled + file.""" + data = bytearray(MAGIC_NUMBER) + data.extend(_w_long(mtime)) + data.extend(_w_long(source_size)) + data.extend(marshal.dumps(code)) + return data + + +def decode_source(source_bytes): + """Decode bytes representing source code and return the string. + + Universal newline support is used in the decoding. + """ + import tokenize # To avoid bootstrap issues. + source_bytes_readline = _io.BytesIO(source_bytes).readline + encoding = tokenize.detect_encoding(source_bytes_readline) + newline_decoder = _io.IncrementalNewlineDecoder(None, True) + return newline_decoder.decode(source_bytes.decode(encoding[0])) + + +# Module specifications ####################################################### + +_POPULATE = object() + + +def spec_from_file_location(name, location=None, *, loader=None, + submodule_search_locations=_POPULATE): + """Return a module spec based on a file location. + + To indicate that the module is a package, set + submodule_search_locations to a list of directory paths. An + empty list is sufficient, though its not otherwise useful to the + import system. + + The loader must take a spec as its only __init__() arg. + + """ + if location is None: + # The caller may simply want a partially populated location- + # oriented spec. So we set the location to a bogus value and + # fill in as much as we can. + location = '' + if hasattr(loader, 'get_filename'): + # ExecutionLoader + try: + location = loader.get_filename(name) + except ImportError: + pass + + # If the location is on the filesystem, but doesn't actually exist, + # we could return None here, indicating that the location is not + # valid. However, we don't have a good way of testing since an + # indirect location (e.g. a zip file or URL) will look like a + # non-existent file relative to the filesystem. + + spec = _bootstrap.ModuleSpec(name, loader, origin=location) + spec._set_fileattr = True + + # Pick a loader if one wasn't provided. + if loader is None: + for loader_class, suffixes in _get_supported_file_loaders(): + if location.endswith(tuple(suffixes)): + loader = loader_class(name, location) + spec.loader = loader + break + else: + return None + + # Set submodule_search_paths appropriately. + if submodule_search_locations is _POPULATE: + # Check the loader. + if hasattr(loader, 'is_package'): + try: + is_package = loader.is_package(name) + except ImportError: + pass + else: + if is_package: + spec.submodule_search_locations = [] + else: + spec.submodule_search_locations = submodule_search_locations + if spec.submodule_search_locations == []: + if location: + dirname = _path_split(location)[0] + spec.submodule_search_locations.append(dirname) + + return spec + + +# Loaders ##################################################################### + +class WindowsRegistryFinder: + + """Meta path finder for modules declared in the Windows registry.""" + + REGISTRY_KEY = ( + 'Software\\Python\\PythonCore\\{sys_version}' + '\\Modules\\{fullname}') + REGISTRY_KEY_DEBUG = ( + 'Software\\Python\\PythonCore\\{sys_version}' + '\\Modules\\{fullname}\\Debug') + DEBUG_BUILD = False # Changed in _setup() + + @classmethod + def _open_registry(cls, key): + try: + return _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, key) + except OSError: + return _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key) + + @classmethod + def _search_registry(cls, fullname): + if cls.DEBUG_BUILD: + registry_key = cls.REGISTRY_KEY_DEBUG + else: + registry_key = cls.REGISTRY_KEY + key = registry_key.format(fullname=fullname, + sys_version=sys.version[:3]) + try: + with cls._open_registry(key) as hkey: + filepath = _winreg.QueryValue(hkey, '') + except OSError: + return None + return filepath + + @classmethod + def find_spec(cls, fullname, path=None, target=None): + filepath = cls._search_registry(fullname) + if filepath is None: + return None + try: + _path_stat(filepath) + except OSError: + return None + for loader, suffixes in _get_supported_file_loaders(): + if filepath.endswith(tuple(suffixes)): + spec = _bootstrap.spec_from_loader(fullname, + loader(fullname, filepath), + origin=filepath) + return spec + + @classmethod + def find_module(cls, fullname, path=None): + """Find module named in the registry. + + This method is deprecated. Use exec_module() instead. + + """ + spec = cls.find_spec(fullname, path) + if spec is not None: + return spec.loader + else: + return None + + +class _LoaderBasics: + + """Base class of common code needed by both SourceLoader and + SourcelessFileLoader.""" + + def is_package(self, fullname): + """Concrete implementation of InspectLoader.is_package by checking if + the path returned by get_filename has a filename of '__init__.py'.""" + filename = _path_split(self.get_filename(fullname))[1] + filename_base = filename.rsplit('.', 1)[0] + tail_name = fullname.rpartition('.')[2] + return filename_base == '__init__' and tail_name != '__init__' + + def create_module(self, spec): + """Use default semantics for module creation.""" + + def exec_module(self, module): + """Execute the module.""" + code = self.get_code(module.__name__) + if code is None: + raise ImportError('cannot load module {!r} when get_code() ' + 'returns None'.format(module.__name__)) + _bootstrap._call_with_frames_removed(exec, code, module.__dict__) + + def load_module(self, fullname): + return _bootstrap._load_module_shim(self, fullname) + + +class SourceLoader(_LoaderBasics): + + def path_mtime(self, path): + """Optional method that returns the modification time (an int) for the + specified path, where path is a str. + + Raises IOError when the path cannot be handled. + """ + raise IOError + + def path_stats(self, path): + """Optional method returning a metadata dict for the specified path + to by the path (str). + Possible keys: + - 'mtime' (mandatory) is the numeric timestamp of last source + code modification; + - 'size' (optional) is the size in bytes of the source code. + + Implementing this method allows the loader to read bytecode files. + Raises IOError when the path cannot be handled. + """ + return {'mtime': self.path_mtime(path)} + + def _cache_bytecode(self, source_path, cache_path, data): + """Optional method which writes data (bytes) to a file path (a str). + + Implementing this method allows for the writing of bytecode files. + + The source path is needed in order to correctly transfer permissions + """ + # For backwards compatibility, we delegate to set_data() + return self.set_data(cache_path, data) + + def set_data(self, path, data): + """Optional method which writes data (bytes) to a file path (a str). + + Implementing this method allows for the writing of bytecode files. + """ + + + def get_source(self, fullname): + """Concrete implementation of InspectLoader.get_source.""" + path = self.get_filename(fullname) + try: + source_bytes = self.get_data(path) + except OSError as exc: + raise ImportError('source not available through get_data()', + name=fullname) from exc + return decode_source(source_bytes) + + def source_to_code(self, data, path, *, _optimize=-1): + """Return the code object compiled from source. + + The 'data' argument can be any object type that compile() supports. + """ + return _bootstrap._call_with_frames_removed(compile, data, path, 'exec', + dont_inherit=True, optimize=_optimize) + + def get_code(self, fullname): + """Concrete implementation of InspectLoader.get_code. + + Reading of bytecode requires path_stats to be implemented. To write + bytecode, set_data must also be implemented. + + """ + source_path = self.get_filename(fullname) + source_mtime = None + try: + bytecode_path = cache_from_source(source_path) + except NotImplementedError: + bytecode_path = None + else: + try: + st = self.path_stats(source_path) + except IOError: + pass + else: + source_mtime = int(st['mtime']) + try: + data = self.get_data(bytecode_path) + except OSError: + pass + else: + try: + bytes_data = _validate_bytecode_header(data, + source_stats=st, name=fullname, + path=bytecode_path) + except (ImportError, EOFError): + pass + else: + _bootstrap._verbose_message('{} matches {}', bytecode_path, + source_path) + return _compile_bytecode(bytes_data, name=fullname, + bytecode_path=bytecode_path, + source_path=source_path) + source_bytes = self.get_data(source_path) + code_object = self.source_to_code(source_bytes, source_path) + _bootstrap._verbose_message('code object from {}', source_path) + if (not sys.dont_write_bytecode and bytecode_path is not None and + source_mtime is not None): + data = _code_to_bytecode(code_object, source_mtime, + len(source_bytes)) + try: + self._cache_bytecode(source_path, bytecode_path, data) + _bootstrap._verbose_message('wrote {!r}', bytecode_path) + except NotImplementedError: + pass + return code_object + + +class FileLoader: + + """Base file loader class which implements the loader protocol methods that + require file system usage.""" + + def __init__(self, fullname, path): + """Cache the module name and the path to the file found by the + finder.""" + self.name = fullname + self.path = path + + def __eq__(self, other): + return (self.__class__ == other.__class__ and + self.__dict__ == other.__dict__) + + def __hash__(self): + return hash(self.name) ^ hash(self.path) + + @_check_name + def load_module(self, fullname): + """Load a module from a file. + + This method is deprecated. Use exec_module() instead. + + """ + # The only reason for this method is for the name check. + # Issue #14857: Avoid the zero-argument form of super so the implementation + # of that form can be updated without breaking the frozen module + return super(FileLoader, self).load_module(fullname) + + @_check_name + def get_filename(self, fullname): + """Return the path to the source file as found by the finder.""" + return self.path + + def get_data(self, path): + """Return the data from path as raw bytes.""" + with _io.FileIO(path, 'r') as file: + return file.read() + + +class SourceFileLoader(FileLoader, SourceLoader): + + """Concrete implementation of SourceLoader using the file system.""" + + def path_stats(self, path): + """Return the metadata for the path.""" + st = _path_stat(path) + return {'mtime': st.st_mtime, 'size': st.st_size} + + def _cache_bytecode(self, source_path, bytecode_path, data): + # Adapt between the two APIs + mode = _calc_mode(source_path) + return self.set_data(bytecode_path, data, _mode=mode) + + def set_data(self, path, data, *, _mode=0o666): + """Write bytes data to a file.""" + parent, filename = _path_split(path) + path_parts = [] + # Figure out what directories are missing. + while parent and not _path_isdir(parent): + parent, part = _path_split(parent) + path_parts.append(part) + # Create needed directories. + for part in reversed(path_parts): + parent = _path_join(parent, part) + try: + _os.mkdir(parent) + except FileExistsError: + # Probably another Python process already created the dir. + continue + except OSError as exc: + # Could be a permission error, read-only filesystem: just forget + # about writing the data. + _bootstrap._verbose_message('could not create {!r}: {!r}', + parent, exc) + return + try: + _write_atomic(path, data, _mode) + _bootstrap._verbose_message('created {!r}', path) + except OSError as exc: + # Same as above: just don't write the bytecode. + _bootstrap._verbose_message('could not create {!r}: {!r}', path, + exc) + + +class SourcelessFileLoader(FileLoader, _LoaderBasics): + + """Loader which handles sourceless file imports.""" + + def get_code(self, fullname): + path = self.get_filename(fullname) + data = self.get_data(path) + bytes_data = _validate_bytecode_header(data, name=fullname, path=path) + return _compile_bytecode(bytes_data, name=fullname, bytecode_path=path) + + def get_source(self, fullname): + """Return None as there is no source code.""" + return None + + +# Filled in by _setup(). +EXTENSION_SUFFIXES = [] + + +class ExtensionFileLoader(FileLoader, _LoaderBasics): + + """Loader for extension modules. + + The constructor is designed to work with FileFinder. + + """ + + def __init__(self, name, path): + self.name = name + self.path = path + + def __eq__(self, other): + return (self.__class__ == other.__class__ and + self.__dict__ == other.__dict__) + + def __hash__(self): + return hash(self.name) ^ hash(self.path) + + def create_module(self, spec): + """Create an unitialized extension module""" + module = _bootstrap._call_with_frames_removed( + _imp.create_dynamic, spec) + _bootstrap._verbose_message('extension module {!r} loaded from {!r}', + spec.name, self.path) + return module + + def exec_module(self, module): + """Initialize an extension module""" + _bootstrap._call_with_frames_removed(_imp.exec_dynamic, module) + _bootstrap._verbose_message('extension module {!r} executed from {!r}', + self.name, self.path) + + def is_package(self, fullname): + """Return True if the extension module is a package.""" + file_name = _path_split(self.path)[1] + return any(file_name == '__init__' + suffix + for suffix in EXTENSION_SUFFIXES) + + def get_code(self, fullname): + """Return None as an extension module cannot create a code object.""" + return None + + def get_source(self, fullname): + """Return None as extension modules have no source code.""" + return None + + @_check_name + def get_filename(self, fullname): + """Return the path to the source file as found by the finder.""" + return self.path + + +class _NamespacePath: + """Represents a namespace package's path. It uses the module name + to find its parent module, and from there it looks up the parent's + __path__. When this changes, the module's own path is recomputed, + using path_finder. For top-level modules, the parent module's path + is sys.path.""" + + def __init__(self, name, path, path_finder): + self._name = name + self._path = path + self._last_parent_path = tuple(self._get_parent_path()) + self._path_finder = path_finder + + def _find_parent_path_names(self): + """Returns a tuple of (parent-module-name, parent-path-attr-name)""" + parent, dot, me = self._name.rpartition('.') + if dot == '': + # This is a top-level module. sys.path contains the parent path. + return 'sys', 'path' + # Not a top-level module. parent-module.__path__ contains the + # parent path. + return parent, '__path__' + + def _get_parent_path(self): + parent_module_name, path_attr_name = self._find_parent_path_names() + return getattr(sys.modules[parent_module_name], path_attr_name) + + def _recalculate(self): + # If the parent's path has changed, recalculate _path + parent_path = tuple(self._get_parent_path()) # Make a copy + if parent_path != self._last_parent_path: + spec = self._path_finder(self._name, parent_path) + # Note that no changes are made if a loader is returned, but we + # do remember the new parent path + if spec is not None and spec.loader is None: + if spec.submodule_search_locations: + self._path = spec.submodule_search_locations + self._last_parent_path = parent_path # Save the copy + return self._path + + def __iter__(self): + return iter(self._recalculate()) + + def __len__(self): + return len(self._recalculate()) + + def __repr__(self): + return '_NamespacePath({!r})'.format(self._path) + + def __contains__(self, item): + return item in self._recalculate() + + def append(self, item): + self._path.append(item) + + +# We use this exclusively in module_from_spec() for backward-compatibility. +class _NamespaceLoader: + def __init__(self, name, path, path_finder): + self._path = _NamespacePath(name, path, path_finder) + + @classmethod + def module_repr(cls, module): + """Return repr for the module. + + The method is deprecated. The import machinery does the job itself. + + """ + return ''.format(module.__name__) + + def is_package(self, fullname): + return True + + def get_source(self, fullname): + return '' + + def get_code(self, fullname): + return compile('', '', 'exec', dont_inherit=True) + + def create_module(self, spec): + """Use default semantics for module creation.""" + + def exec_module(self, module): + pass + + def load_module(self, fullname): + """Load a namespace module. + + This method is deprecated. Use exec_module() instead. + + """ + # The import system never calls this method. + _bootstrap._verbose_message('namespace module loaded with path {!r}', + self._path) + return _bootstrap._load_module_shim(self, fullname) + + +# Finders ##################################################################### + +class PathFinder: + + """Meta path finder for sys.path and package __path__ attributes.""" + + @classmethod + def invalidate_caches(cls): + """Call the invalidate_caches() method on all path entry finders + stored in sys.path_importer_caches (where implemented).""" + for finder in sys.path_importer_cache.values(): + if hasattr(finder, 'invalidate_caches'): + finder.invalidate_caches() + + @classmethod + def _path_hooks(cls, path): + """Search sequence of hooks for a finder for 'path'. + + If 'hooks' is false then use sys.path_hooks. + + """ + if sys.path_hooks is not None and not sys.path_hooks: + _warnings.warn('sys.path_hooks is empty', ImportWarning) + for hook in sys.path_hooks: + try: + return hook(path) + except ImportError: + continue + else: + return None + + @classmethod + def _path_importer_cache(cls, path): + """Get the finder for the path entry from sys.path_importer_cache. + + If the path entry is not in the cache, find the appropriate finder + and cache it. If no finder is available, store None. + + """ + if path == '': + try: + path = _os.getcwd() + except FileNotFoundError: + # Don't cache the failure as the cwd can easily change to + # a valid directory later on. + return None + try: + finder = sys.path_importer_cache[path] + except KeyError: + finder = cls._path_hooks(path) + sys.path_importer_cache[path] = finder + return finder + + @classmethod + def _legacy_get_spec(cls, fullname, finder): + # This would be a good place for a DeprecationWarning if + # we ended up going that route. + if hasattr(finder, 'find_loader'): + loader, portions = finder.find_loader(fullname) + else: + loader = finder.find_module(fullname) + portions = [] + if loader is not None: + return _bootstrap.spec_from_loader(fullname, loader) + spec = _bootstrap.ModuleSpec(fullname, None) + spec.submodule_search_locations = portions + return spec + + @classmethod + def _get_spec(cls, fullname, path, target=None): + """Find the loader or namespace_path for this module/package name.""" + # If this ends up being a namespace package, namespace_path is + # the list of paths that will become its __path__ + namespace_path = [] + for entry in path: + if not isinstance(entry, (str, bytes)): + continue + finder = cls._path_importer_cache(entry) + if finder is not None: + if hasattr(finder, 'find_spec'): + spec = finder.find_spec(fullname, target) + else: + spec = cls._legacy_get_spec(fullname, finder) + if spec is None: + continue + if spec.loader is not None: + return spec + portions = spec.submodule_search_locations + if portions is None: + raise ImportError('spec missing loader') + # This is possibly part of a namespace package. + # Remember these path entries (if any) for when we + # create a namespace package, and continue iterating + # on path. + namespace_path.extend(portions) + else: + spec = _bootstrap.ModuleSpec(fullname, None) + spec.submodule_search_locations = namespace_path + return spec + + @classmethod + def find_spec(cls, fullname, path=None, target=None): + """find the module on sys.path or 'path' based on sys.path_hooks and + sys.path_importer_cache.""" + if path is None: + path = sys.path + spec = cls._get_spec(fullname, path, target) + if spec is None: + return None + elif spec.loader is None: + namespace_path = spec.submodule_search_locations + if namespace_path: + # We found at least one namespace path. Return a + # spec which can create the namespace package. + spec.origin = 'namespace' + spec.submodule_search_locations = _NamespacePath(fullname, namespace_path, cls._get_spec) + return spec + else: + return None + else: + return spec + + @classmethod + def find_module(cls, fullname, path=None): + """find the module on sys.path or 'path' based on sys.path_hooks and + sys.path_importer_cache. + + This method is deprecated. Use find_spec() instead. + + """ + spec = cls.find_spec(fullname, path) + if spec is None: + return None + return spec.loader + + +class FileFinder: + + """File-based finder. + + Interactions with the file system are cached for performance, being + refreshed when the directory the finder is handling has been modified. + + """ + + def __init__(self, path, *loader_details): + """Initialize with the path to search on and a variable number of + 2-tuples containing the loader and the file suffixes the loader + recognizes.""" + loaders = [] + for loader, suffixes in loader_details: + loaders.extend((suffix, loader) for suffix in suffixes) + self._loaders = loaders + # Base (directory) path + self.path = path or '.' + self._path_mtime = -1 + self._path_cache = set() + self._relaxed_path_cache = set() + + def invalidate_caches(self): + """Invalidate the directory mtime.""" + self._path_mtime = -1 + + find_module = _find_module_shim + + def find_loader(self, fullname): + """Try to find a loader for the specified module, or the namespace + package portions. Returns (loader, list-of-portions). + + This method is deprecated. Use find_spec() instead. + + """ + spec = self.find_spec(fullname) + if spec is None: + return None, [] + return spec.loader, spec.submodule_search_locations or [] + + def _get_spec(self, loader_class, fullname, path, smsl, target): + loader = loader_class(fullname, path) + return spec_from_file_location(fullname, path, loader=loader, + submodule_search_locations=smsl) + + def find_spec(self, fullname, target=None): + """Try to find a loader for the specified module, or the namespace + package portions. Returns (loader, list-of-portions).""" + is_namespace = False + tail_module = fullname.rpartition('.')[2] + try: + mtime = _path_stat(self.path or _os.getcwd()).st_mtime + except OSError: + mtime = -1 + if mtime != self._path_mtime: + self._fill_cache() + self._path_mtime = mtime + # tail_module keeps the original casing, for __file__ and friends + if _relax_case(): + cache = self._relaxed_path_cache + cache_module = tail_module.lower() + else: + cache = self._path_cache + cache_module = tail_module + # Check if the module is the name of a directory (and thus a package). + if cache_module in cache: + base_path = _path_join(self.path, tail_module) + for suffix, loader_class in self._loaders: + init_filename = '__init__' + suffix + full_path = _path_join(base_path, init_filename) + if _path_isfile(full_path): + return self._get_spec(loader_class, fullname, full_path, [base_path], target) + else: + # If a namespace package, return the path if we don't + # find a module in the next section. + is_namespace = _path_isdir(base_path) + # Check for a file w/ a proper suffix exists. + for suffix, loader_class in self._loaders: + full_path = _path_join(self.path, tail_module + suffix) + _bootstrap._verbose_message('trying {}', full_path, verbosity=2) + if cache_module + suffix in cache: + if _path_isfile(full_path): + return self._get_spec(loader_class, fullname, full_path, + None, target) + if is_namespace: + _bootstrap._verbose_message('possible namespace for {}', base_path) + spec = _bootstrap.ModuleSpec(fullname, None) + spec.submodule_search_locations = [base_path] + return spec + return None + + def _fill_cache(self): + """Fill the cache of potential modules and packages for this directory.""" + path = self.path + try: + contents = _os.listdir(path or _os.getcwd()) + except (FileNotFoundError, PermissionError, NotADirectoryError): + # Directory has either been removed, turned into a file, or made + # unreadable. + contents = [] + # We store two cached versions, to handle runtime changes of the + # PYTHONCASEOK environment variable. + if not sys.platform.startswith('win'): + self._path_cache = set(contents) + else: + # Windows users can import modules with case-insensitive file + # suffixes (for legacy reasons). Make the suffix lowercase here + # so it's done once instead of for every import. This is safe as + # the specified suffixes to check against are always specified in a + # case-sensitive manner. + lower_suffix_contents = set() + for item in contents: + name, dot, suffix = item.partition('.') + if dot: + new_name = '{}.{}'.format(name, suffix.lower()) + else: + new_name = name + lower_suffix_contents.add(new_name) + self._path_cache = lower_suffix_contents + if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS): + self._relaxed_path_cache = {fn.lower() for fn in contents} + + @classmethod + def path_hook(cls, *loader_details): + """A class method which returns a closure to use on sys.path_hook + which will return an instance using the specified loaders and the path + called on the closure. + + If the path called on the closure is not a directory, ImportError is + raised. + + """ + def path_hook_for_FileFinder(path): + """Path hook for importlib.machinery.FileFinder.""" + if not _path_isdir(path): + raise ImportError('only directories are supported', path=path) + return cls(path, *loader_details) + + return path_hook_for_FileFinder + + def __repr__(self): + return 'FileFinder({!r})'.format(self.path) + + +# Import setup ############################################################### + +def _fix_up_module(ns, name, pathname, cpathname=None): + # This function is used by PyImport_ExecCodeModuleObject(). + loader = ns.get('__loader__') + spec = ns.get('__spec__') + if not loader: + if spec: + loader = spec.loader + elif pathname == cpathname: + loader = SourcelessFileLoader(name, pathname) + else: + loader = SourceFileLoader(name, pathname) + if not spec: + spec = spec_from_file_location(name, pathname, loader=loader) + try: + ns['__spec__'] = spec + ns['__loader__'] = loader + ns['__file__'] = pathname + ns['__cached__'] = cpathname + except Exception: + # Not important enough to report. + pass + + +def _get_supported_file_loaders(): + """Returns a list of file-based module loaders. + + Each item is a tuple (loader, suffixes). + """ + extensions = ExtensionFileLoader, _imp.extension_suffixes() + source = SourceFileLoader, SOURCE_SUFFIXES + bytecode = SourcelessFileLoader, BYTECODE_SUFFIXES + return [extensions, source, bytecode] + + +def _setup(_bootstrap_module): + """Setup the path-based importers for importlib by importing needed + built-in modules and injecting them into the global namespace. + + Other components are extracted from the core bootstrap module. + + """ + global sys, _imp, _bootstrap + _bootstrap = _bootstrap_module + sys = _bootstrap.sys + _imp = _bootstrap._imp + + # Directly load built-in modules needed during bootstrap. + self_module = sys.modules[__name__] + for builtin_name in ('_io', '_warnings', 'builtins', 'marshal'): + if builtin_name not in sys.modules: + builtin_module = _bootstrap._builtin_from_name(builtin_name) + else: + builtin_module = sys.modules[builtin_name] + setattr(self_module, builtin_name, builtin_module) + + # Directly load the os module (needed during bootstrap). + os_details = ('posix', ['/']), ('nt', ['\\', '/']) + for builtin_os, path_separators in os_details: + # Assumption made in _path_join() + assert all(len(sep) == 1 for sep in path_separators) + path_sep = path_separators[0] + if builtin_os in sys.modules: + os_module = sys.modules[builtin_os] + break + else: + try: + os_module = _bootstrap._builtin_from_name(builtin_os) + break + except ImportError: + continue + else: + raise ImportError('importlib requires posix or nt') + setattr(self_module, '_os', os_module) + setattr(self_module, 'path_sep', path_sep) + setattr(self_module, 'path_separators', ''.join(path_separators)) + + # Directly load the _thread module (needed during bootstrap). + try: + thread_module = _bootstrap._builtin_from_name('_thread') + except ImportError: + # Python was built without threads + thread_module = None + setattr(self_module, '_thread', thread_module) + + # Directly load the _weakref module (needed during bootstrap). + weakref_module = _bootstrap._builtin_from_name('_weakref') + setattr(self_module, '_weakref', weakref_module) + + # Directly load the winreg module (needed during bootstrap). + if builtin_os == 'nt': + winreg_module = _bootstrap._builtin_from_name('winreg') + setattr(self_module, '_winreg', winreg_module) + + # Constants + setattr(self_module, '_relax_case', _make_relax_case()) + EXTENSION_SUFFIXES.extend(_imp.extension_suffixes()) + if builtin_os == 'nt': + SOURCE_SUFFIXES.append('.pyw') + if '_d.pyd' in EXTENSION_SUFFIXES: + WindowsRegistryFinder.DEBUG_BUILD = True + + +def _install(_bootstrap_module): + """Install the path-based import components.""" + _setup(_bootstrap_module) + supported_loaders = _get_supported_file_loaders() + sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders)]) + if _os.__name__ == 'nt': + sys.meta_path.append(WindowsRegistryFinder) + sys.meta_path.append(PathFinder) + + # XXX We expose a couple of classes in _bootstrap for the sake of + # a setuptools bug (https://bitbucket.org/pypa/setuptools/issue/378). + _bootstrap_module.FileFinder = FileFinder + _bootstrap_module.SourceFileLoader = SourceFileLoader diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py index 3995ff2a6867..11af22dab9ba 100644 --- a/Lib/importlib/abc.py +++ b/Lib/importlib/abc.py @@ -1,12 +1,18 @@ """Abstract base classes related to import.""" from . import _bootstrap +from . import _bootstrap_external from . import machinery try: import _frozen_importlib +# import _frozen_importlib_external except ImportError as exc: if exc.name != '_frozen_importlib': raise _frozen_importlib = None +try: + import _frozen_importlib_external +except ImportError as exc: + _frozen_importlib_external = _bootstrap_external import abc @@ -14,7 +20,10 @@ def _register(abstract_cls, *classes): for cls in classes: abstract_cls.register(cls) if _frozen_importlib is not None: - frozen_cls = getattr(_frozen_importlib, cls.__name__) + try: + frozen_cls = getattr(_frozen_importlib, cls.__name__) + except AttributeError: + frozen_cls = getattr(_frozen_importlib_external, cls.__name__) abstract_cls.register(frozen_cls) @@ -43,15 +52,21 @@ class MetaPathFinder(Finder): # We don't define find_spec() here since that would break # hasattr checks we do to support backward compatibility. - # XXX Deprecate def find_module(self, fullname, path): """Return a loader for the module. If no module is found, return None. The fullname is a str and the path is a list of strings or None. + This method is deprecated in favor of finder.find_spec(). If find_spec() + exists then backwards-compatible functionality is provided for this + method. + """ - return None + if not hasattr(self, 'find_spec'): + return None + found = self.find_spec(fullname, path) + return found.loader if found is not None else None def invalidate_caches(self): """An optional method for clearing the finder's cache, if any. @@ -69,7 +84,6 @@ class PathEntryFinder(Finder): # We don't define find_spec() here since that would break # hasattr checks we do to support backward compatibility. - # XXX Deprecate. def find_loader(self, fullname): """Return (loader, namespace portion) for the path entry. @@ -81,11 +95,23 @@ def find_loader(self, fullname): The portion will be discarded if another path entry finder locates the module as a normal module or package. + This method is deprecated in favor of finder.find_spec(). If find_spec() + is provided than backwards-compatible functionality is provided. + """ - return None, [] + if not hasattr(self, 'find_spec'): + return None, [] + found = self.find_spec(fullname) + if found is not None: + if not found.submodule_search_locations: + portions = [] + else: + portions = found.submodule_search_locations + return found.loader, portions + else: + return None, [] - # XXX Deprecate. - find_module = _bootstrap._find_module_shim + find_module = _bootstrap_external._find_module_shim def invalidate_caches(self): """An optional method for clearing the finder's cache, if any. @@ -105,17 +131,13 @@ def create_module(self, spec): This method should raise ImportError if anything prevents it from creating a new module. It may return None to indicate that the spec should create the new module. - - create_module() is optional. - """ - # By default, defer to _SpecMethods.create() for the new module. + # By default, defer to default semantics for the new module. return None # We don't define exec_module() here since that would break # hasattr checks we do to support backward compatibility. - # XXX Deprecate. def load_module(self, fullname): """Return the loaded module. @@ -124,16 +146,23 @@ def load_module(self, fullname): ImportError is raised on failure. + This method is deprecated in favor of loader.exec_module(). If + exec_module() exists then it is used to provide a backwards-compatible + functionality for this method. + """ - raise ImportError + if not hasattr(self, 'exec_module'): + raise ImportError + return _bootstrap._load_module_shim(self, fullname) - # XXX Deprecate. def module_repr(self, module): """Return a module's repr. Used by the module type when the method does not raise NotImplementedError. + This method is deprecated. + """ # The exception will cause ModuleType.__repr__ to ignore this method. raise NotImplementedError @@ -194,15 +223,16 @@ def get_source(self, fullname): """ raise ImportError - def source_to_code(self, data, path=''): + @staticmethod + def source_to_code(data, path=''): """Compile 'data' into a code object. The 'data' argument can be anything that compile() can handle. The'path' argument should be where the data was retrieved (when applicable).""" return compile(data, path, 'exec', dont_inherit=True) - exec_module = _bootstrap._LoaderBasics.exec_module - load_module = _bootstrap._LoaderBasics.load_module + exec_module = _bootstrap_external._LoaderBasics.exec_module + load_module = _bootstrap_external._LoaderBasics.load_module _register(InspectLoader, machinery.BuiltinImporter, machinery.FrozenImporter) @@ -244,7 +274,7 @@ def get_code(self, fullname): _register(ExecutionLoader, machinery.ExtensionFileLoader) -class FileLoader(_bootstrap.FileLoader, ResourceLoader, ExecutionLoader): +class FileLoader(_bootstrap_external.FileLoader, ResourceLoader, ExecutionLoader): """Abstract base class partially implementing the ResourceLoader and ExecutionLoader ABCs.""" @@ -253,7 +283,7 @@ class FileLoader(_bootstrap.FileLoader, ResourceLoader, ExecutionLoader): machinery.SourcelessFileLoader) -class SourceLoader(_bootstrap.SourceLoader, ResourceLoader, ExecutionLoader): +class SourceLoader(_bootstrap_external.SourceLoader, ResourceLoader, ExecutionLoader): """Abstract base class for loading source code (and optionally any corresponding bytecode). diff --git a/Lib/importlib/machinery.py b/Lib/importlib/machinery.py index 2e1b2d73e73f..1b2b5c9b4f34 100644 --- a/Lib/importlib/machinery.py +++ b/Lib/importlib/machinery.py @@ -2,18 +2,18 @@ import _imp -from ._bootstrap import (SOURCE_SUFFIXES, DEBUG_BYTECODE_SUFFIXES, - OPTIMIZED_BYTECODE_SUFFIXES, BYTECODE_SUFFIXES, - EXTENSION_SUFFIXES) from ._bootstrap import ModuleSpec from ._bootstrap import BuiltinImporter from ._bootstrap import FrozenImporter -from ._bootstrap import WindowsRegistryFinder -from ._bootstrap import PathFinder -from ._bootstrap import FileFinder -from ._bootstrap import SourceFileLoader -from ._bootstrap import SourcelessFileLoader -from ._bootstrap import ExtensionFileLoader +from ._bootstrap_external import (SOURCE_SUFFIXES, DEBUG_BYTECODE_SUFFIXES, + OPTIMIZED_BYTECODE_SUFFIXES, BYTECODE_SUFFIXES, + EXTENSION_SUFFIXES) +from ._bootstrap_external import WindowsRegistryFinder +from ._bootstrap_external import PathFinder +from ._bootstrap_external import FileFinder +from ._bootstrap_external import SourceFileLoader +from ._bootstrap_external import SourcelessFileLoader +from ._bootstrap_external import ExtensionFileLoader def all_suffixes(): diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py index 04b19515fd0e..1dbff2605eae 100644 --- a/Lib/importlib/util.py +++ b/Lib/importlib/util.py @@ -1,16 +1,19 @@ """Utility code for constructing importers, etc.""" - -from ._bootstrap import MAGIC_NUMBER -from ._bootstrap import cache_from_source -from ._bootstrap import decode_source -from ._bootstrap import source_from_cache -from ._bootstrap import spec_from_loader -from ._bootstrap import spec_from_file_location +from . import abc +from ._bootstrap import module_from_spec from ._bootstrap import _resolve_name +from ._bootstrap import spec_from_loader +from ._bootstrap import _find_spec +from ._bootstrap_external import MAGIC_NUMBER +from ._bootstrap_external import cache_from_source +from ._bootstrap_external import decode_source +from ._bootstrap_external import source_from_cache +from ._bootstrap_external import spec_from_file_location from contextlib import contextmanager import functools import sys +import types import warnings @@ -29,6 +32,77 @@ def resolve_name(name, package): return _resolve_name(name[level:], package, level) +def _find_spec_from_path(name, path=None): + """Return the spec for the specified module. + + First, sys.modules is checked to see if the module was already imported. If + so, then sys.modules[name].__spec__ is returned. If that happens to be + set to None, then ValueError is raised. If the module is not in + sys.modules, then sys.meta_path is searched for a suitable spec with the + value of 'path' given to the finders. None is returned if no spec could + be found. + + Dotted names do not have their parent packages implicitly imported. You will + most likely need to explicitly import all parent packages in the proper + order for a submodule to get the correct spec. + + """ + if name not in sys.modules: + return _find_spec(name, path) + else: + module = sys.modules[name] + if module is None: + return None + try: + spec = module.__spec__ + except AttributeError: + raise ValueError('{}.__spec__ is not set'.format(name)) from None + else: + if spec is None: + raise ValueError('{}.__spec__ is None'.format(name)) + return spec + + +def find_spec(name, package=None): + """Return the spec for the specified module. + + First, sys.modules is checked to see if the module was already imported. If + so, then sys.modules[name].__spec__ is returned. If that happens to be + set to None, then ValueError is raised. If the module is not in + sys.modules, then sys.meta_path is searched for a suitable spec with the + value of 'path' given to the finders. None is returned if no spec could + be found. + + If the name is for submodule (contains a dot), the parent module is + automatically imported. + + The name and package arguments work the same as importlib.import_module(). + In other words, relative module names (with leading dots) work. + + """ + fullname = resolve_name(name, package) if name.startswith('.') else name + if fullname not in sys.modules: + parent_name = fullname.rpartition('.')[0] + if parent_name: + # Use builtins.__import__() in case someone replaced it. + parent = __import__(parent_name, fromlist=['__path__']) + return _find_spec(fullname, parent.__path__) + else: + return _find_spec(fullname, None) + else: + module = sys.modules[fullname] + if module is None: + return None + try: + spec = module.__spec__ + except AttributeError: + raise ValueError('{}.__spec__ is not set'.format(name)) from None + else: + if spec is None: + raise ValueError('{}.__spec__ is None'.format(name)) + return spec + + @contextmanager def _module_to_load(name): is_reload = name in sys.modules @@ -55,11 +129,16 @@ def _module_to_load(name): module.__initializing__ = False -# XXX deprecate def set_package(fxn): - """Set __package__ on the returned module.""" + """Set __package__ on the returned module. + + This function is deprecated. + + """ @functools.wraps(fxn) def set_package_wrapper(*args, **kwargs): + warnings.warn('The import system now takes care of this automatically.', + DeprecationWarning, stacklevel=2) module = fxn(*args, **kwargs) if getattr(module, '__package__', None) is None: module.__package__ = module.__name__ @@ -69,11 +148,16 @@ def set_package_wrapper(*args, **kwargs): return set_package_wrapper -# XXX deprecate def set_loader(fxn): - """Set __loader__ on the returned module.""" + """Set __loader__ on the returned module. + + This function is deprecated. + + """ @functools.wraps(fxn) def set_loader_wrapper(self, *args, **kwargs): + warnings.warn('The import system now takes care of this automatically.', + DeprecationWarning, stacklevel=2) module = fxn(self, *args, **kwargs) if getattr(module, '__loader__', None) is None: module.__loader__ = self @@ -100,7 +184,7 @@ def module_for_loader(fxn): """ warnings.warn('The import system now takes care of this automatically.', - PendingDeprecationWarning, stacklevel=2) + DeprecationWarning, stacklevel=2) @functools.wraps(fxn) def module_for_loader_wrapper(self, fullname, *args, **kwargs): with _module_to_load(fullname) as module: @@ -118,3 +202,94 @@ def module_for_loader_wrapper(self, fullname, *args, **kwargs): return fxn(self, module, *args, **kwargs) return module_for_loader_wrapper + + +class _Module(types.ModuleType): + + """A subclass of the module type to allow __class__ manipulation.""" + + +class _LazyModule(types.ModuleType): + + """A subclass of the module type which triggers loading upon attribute access.""" + + def __getattribute__(self, attr): + """Trigger the load of the module and return the attribute.""" + # All module metadata must be garnered from __spec__ in order to avoid + # using mutated values. + # Stop triggering this method. + self.__class__ = _Module + # Get the original name to make sure no object substitution occurred + # in sys.modules. + original_name = self.__spec__.name + # Figure out exactly what attributes were mutated between the creation + # of the module and now. + attrs_then = self.__spec__.loader_state + attrs_now = self.__dict__ + attrs_updated = {} + for key, value in attrs_now.items(): + # Code that set the attribute may have kept a reference to the + # assigned object, making identity more important than equality. + if key not in attrs_then: + attrs_updated[key] = value + elif id(attrs_now[key]) != id(attrs_then[key]): + attrs_updated[key] = value + self.__spec__.loader.exec_module(self) + # If exec_module() was used directly there is no guarantee the module + # object was put into sys.modules. + if original_name in sys.modules: + if id(self) != id(sys.modules[original_name]): + msg = ('module object for {!r} substituted in sys.modules ' + 'during a lazy load') + raise ValueError(msg.format(original_name)) + # Update after loading since that's what would happen in an eager + # loading situation. + self.__dict__.update(attrs_updated) + return getattr(self, attr) + + def __delattr__(self, attr): + """Trigger the load and then perform the deletion.""" + # To trigger the load and raise an exception if the attribute + # doesn't exist. + self.__getattribute__(attr) + delattr(self, attr) + + +class LazyLoader(abc.Loader): + + """A loader that creates a module which defers loading until attribute access.""" + + @staticmethod + def __check_eager_loader(loader): + if not hasattr(loader, 'exec_module'): + raise TypeError('loader must define exec_module()') + elif hasattr(loader.__class__, 'create_module'): + if abc.Loader.create_module != loader.__class__.create_module: + # Only care if create_module() is overridden in a subclass of + # importlib.abc.Loader. + raise TypeError('loader cannot define create_module()') + + @classmethod + def factory(cls, loader): + """Construct a callable which returns the eager loader made lazy.""" + cls.__check_eager_loader(loader) + return lambda *args, **kwargs: cls(loader(*args, **kwargs)) + + def __init__(self, loader): + self.__check_eager_loader(loader) + self.loader = loader + + def create_module(self, spec): + """Create a module which can have its __class__ manipulated.""" + return _Module(spec.name) + + def exec_module(self, module): + """Make the module load lazily.""" + module.__spec__.loader = self.loader + module.__loader__ = self.loader + # Don't need to worry about deep-copying as trying to set an attribute + # on an object would have triggered the load, + # e.g. ``module.__spec__.loader = None`` would trigger a load from + # trying to access module.__spec__. + module.__spec__.loader_state = module.__dict__.copy() + module.__class__ = _LazyModule diff --git a/Lib/inspect.py b/Lib/inspect.py index dc94e44b296d..a089be696e5e 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -16,8 +16,8 @@ getmodule() - determine the module that an object came from getclasstree() - arrange classes so as to represent their hierarchy - getargspec(), getargvalues(), getcallargs() - get info about function arguments - getfullargspec() - same, with support for Python-3000 features + getargvalues(), getcallargs() - get info about function arguments + getfullargspec() - same, with support for Python 3 features formatargspec(), formatargvalues() - format an argument spec getouterframes(), getinnerframes() - get info about frames currentframe() - get the current stack frame @@ -32,6 +32,9 @@ 'Yury Selivanov ') import ast +import dis +import collections.abc +import enum import importlib.machinery import itertools import linecache @@ -39,6 +42,7 @@ import re import sys import tokenize +import token import types import warnings import functools @@ -47,18 +51,10 @@ from collections import namedtuple, OrderedDict # Create constants for the compiler flags in Include/code.h -# We try to get them from dis to avoid duplication, but fall -# back to hardcoding so the dependency is optional -try: - from dis import COMPILER_FLAG_NAMES as _flag_names -except ImportError: - CO_OPTIMIZED, CO_NEWLOCALS = 0x1, 0x2 - CO_VARARGS, CO_VARKEYWORDS = 0x4, 0x8 - CO_NESTED, CO_GENERATOR, CO_NOFREE = 0x10, 0x20, 0x40 -else: - mod_dict = globals() - for k, v in _flag_names.items(): - mod_dict["CO_" + v] = k +# We try to get them from dis to avoid duplication +mod_dict = globals() +for k, v in dis.COMPILER_FLAG_NAMES.items(): + mod_dict["CO_" + v] = k # See Include/object.h TPFLAGS_IS_ABSTRACT = 1 << 20 @@ -181,6 +177,15 @@ def isgeneratorfunction(object): return bool((isfunction(object) or ismethod(object)) and object.__code__.co_flags & CO_GENERATOR) +def iscoroutinefunction(object): + """Return true if the object is a coroutine function. + + Coroutine functions are defined with "async def" syntax, + or generators decorated with "types.coroutine". + """ + return bool((isfunction(object) or ismethod(object)) and + object.__code__.co_flags & CO_COROUTINE) + def isgenerator(object): """Return true if the object is a generator. @@ -198,6 +203,17 @@ def isgenerator(object): throw used to raise an exception inside the generator""" return isinstance(object, types.GeneratorType) +def iscoroutine(object): + """Return true if the object is a coroutine.""" + return isinstance(object, types.CoroutineType) + +def isawaitable(object): + """Return true is object can be passed to an ``await`` expression.""" + return (isinstance(object, types.CoroutineType) or + isinstance(object, types.GeneratorType) and + object.gi_code.co_flags & CO_ITERABLE_COROUTINE or + isinstance(object, collections.abc.Awaitable)) + def istraceback(object): """Return true if the object is a traceback. @@ -379,7 +395,7 @@ def classify_class_attrs(cls): # first look in the classes for srch_cls in class_bases: srch_obj = getattr(srch_cls, name, None) - if srch_obj == get_obj: + if srch_obj is get_obj: last_cls = srch_cls # then check the metaclasses for srch_cls in metamro: @@ -387,7 +403,7 @@ def classify_class_attrs(cls): srch_obj = srch_cls.__getattr__(cls, name) except AttributeError: continue - if srch_obj == get_obj: + if srch_obj is get_obj: last_cls = srch_cls if last_cls is not None: homecls = last_cls @@ -401,7 +417,7 @@ def classify_class_attrs(cls): # unable to locate the attribute anywhere, most likely due to # buggy custom __dir__; discard and move on continue - obj = get_obj or dict_obj + obj = get_obj if get_obj is not None else dict_obj # Classify the object or its descriptor. if isinstance(dict_obj, staticmethod): kind = "static method" @@ -412,7 +428,7 @@ def classify_class_attrs(cls): elif isinstance(dict_obj, property): kind = "property" obj = dict_obj - elif isfunction(obj) or ismethoddescriptor(obj): + elif isroutine(obj): kind = "method" else: kind = "data" @@ -466,6 +482,74 @@ def indentsize(line): expline = line.expandtabs() return len(expline) - len(expline.lstrip()) +def _findclass(func): + cls = sys.modules.get(func.__module__) + if cls is None: + return None + for name in func.__qualname__.split('.')[:-1]: + cls = getattr(cls, name) + if not isclass(cls): + return None + return cls + +def _finddoc(obj): + if isclass(obj): + for base in obj.__mro__: + if base is not object: + try: + doc = base.__doc__ + except AttributeError: + continue + if doc is not None: + return doc + return None + + if ismethod(obj): + name = obj.__func__.__name__ + self = obj.__self__ + if (isclass(self) and + getattr(getattr(self, name, None), '__func__') is obj.__func__): + # classmethod + cls = self + else: + cls = self.__class__ + elif isfunction(obj): + name = obj.__name__ + cls = _findclass(obj) + if cls is None or getattr(cls, name) is not obj: + return None + elif isbuiltin(obj): + name = obj.__name__ + self = obj.__self__ + if (isclass(self) and + self.__qualname__ + '.' + name == obj.__qualname__): + # classmethod + cls = self + else: + cls = self.__class__ + elif ismethoddescriptor(obj) or isdatadescriptor(obj): + name = obj.__name__ + cls = obj.__objclass__ + if getattr(cls, name) is not obj: + return None + elif isinstance(obj, property): + func = f.fget + name = func.__name__ + cls = _findclass(func) + if cls is None or getattr(cls, name) is not obj: + return None + else: + return None + + for base in cls.__mro__: + try: + doc = getattr(base, name).__doc__ + except AttributeError: + continue + if doc is not None: + return doc + return None + def getdoc(object): """Get the documentation string for an object. @@ -476,6 +560,11 @@ def getdoc(object): doc = object.__doc__ except AttributeError: return None + if doc is None: + try: + doc = _finddoc(object) + except (AttributeError, TypeError): + return None if not isinstance(doc, str): return None return cleandoc(doc) @@ -516,9 +605,10 @@ def getfile(object): return object.__file__ raise TypeError('{!r} is a built-in module'.format(object)) if isclass(object): - object = sys.modules.get(object.__module__) - if hasattr(object, '__file__'): - return object.__file__ + if hasattr(object, '__module__'): + object = sys.modules.get(object.__module__) + if hasattr(object, '__file__'): + return object.__file__ raise TypeError('{!r} is a built-in class'.format(object)) if ismethod(object): object = object.__func__ @@ -533,23 +623,6 @@ def getfile(object): raise TypeError('{!r} is not a module, class, method, ' 'function, traceback, frame, or code object'.format(object)) -ModuleInfo = namedtuple('ModuleInfo', 'name suffix mode module_type') - -def getmoduleinfo(path): - """Get the module name, suffix, mode, and module type for a given file.""" - warnings.warn('inspect.getmoduleinfo() is deprecated', DeprecationWarning, - 2) - with warnings.catch_warnings(): - warnings.simplefilter('ignore', PendingDeprecationWarning) - import imp - filename = os.path.basename(path) - suffixes = [(-len(suffix), suffix, mode, mtype) - for suffix, mode, mtype in imp.get_suffixes()] - suffixes.sort() # try longest suffixes first, in case they overlap - for neglen, suffix, mode, mtype in suffixes: - if filename[neglen:] == suffix: - return ModuleInfo(filename[:neglen], suffix, mode, mtype) - def getmodulename(path): """Return the module name for a given file, or None.""" fname = os.path.basename(path) @@ -650,11 +723,17 @@ def findsource(object): in the file and the line number indexes a line in that list. An OSError is raised if the source code cannot be retrieved.""" - file = getfile(object) - sourcefile = getsourcefile(object) - if not sourcefile and file[:1] + file[-1:] != '<>': - raise OSError('source code not available') - file = sourcefile if sourcefile else file + file = getsourcefile(object) + if file: + # Invalidate cache if needed. + linecache.checkcache(file) + else: + file = getfile(object) + # Allow filenames in form of "" to pass through. + # `doctest` monkeypatches `linecache` module to enable + # inspection, so let `linecache.getlines` to be called. + if not (file.startswith('<') and file.endswith('>')): + raise OSError('source code not available') module = getmodule(object, file) if module: @@ -702,7 +781,7 @@ def findsource(object): if not hasattr(object, 'co_firstlineno'): raise OSError('could not find function definition') lnum = object.co_firstlineno - 1 - pat = re.compile(r'^(\s*def\s)|(.*(? 0: if pat.match(lines[lnum]): break lnum = lnum - 1 @@ -763,21 +842,37 @@ def __init__(self): self.islambda = False self.started = False self.passline = False + self.indecorator = False + self.decoratorhasargs = False self.last = 1 def tokeneater(self, type, token, srowcol, erowcol, line): - if not self.started: + if not self.started and not self.indecorator: + # skip any decorators + if token == "@": + self.indecorator = True # look for the first "def", "class" or "lambda" - if token in ("def", "class", "lambda"): + elif token in ("def", "class", "lambda"): if token == "lambda": self.islambda = True self.started = True self.passline = True # skip to the end of the line + elif token == "(": + if self.indecorator: + self.decoratorhasargs = True + elif token == ")": + if self.indecorator: + self.indecorator = False + self.decoratorhasargs = False elif type == tokenize.NEWLINE: self.passline = False # stop skipping when a NEWLINE is seen self.last = srowcol[0] if self.islambda: # lambdas always end at the first NEWLINE raise EndOfBlock + # hitting a NEWLINE when in a decorator without args + # ends the decorator + if self.indecorator and not self.decoratorhasargs: + self.indecorator = False elif self.passline: pass elif type == tokenize.INDENT: @@ -814,10 +909,13 @@ def getsourcelines(object): corresponding to the object and the line number indicates where in the original source file the first line of code was found. An OSError is raised if the source code cannot be retrieved.""" + object = unwrap(object) lines, lnum = findsource(object) - if ismodule(object): return lines, 0 - else: return getblock(lines[lnum:]), lnum + 1 + if ismodule(object): + return lines, 0 + else: + return getblock(lines[lnum:]), lnum + 1 def getsource(object): """Return the text of the source code for an object. @@ -905,35 +1003,11 @@ def _getfullargs(co): varkw = co.co_varnames[nargs] return args, varargs, kwonlyargs, varkw - -ArgSpec = namedtuple('ArgSpec', 'args varargs keywords defaults') - -def getargspec(func): - """Get the names and default values of a function's arguments. - - A tuple of four things is returned: (args, varargs, varkw, defaults). - 'args' is a list of the argument names. - 'args' will include keyword-only argument names. - 'varargs' and 'varkw' are the names of the * and ** arguments or None. - 'defaults' is an n-tuple of the default values of the last n arguments. - - Use the getfullargspec() API for Python-3000 code, as annotations - and keyword arguments are supported. getargspec() will raise ValueError - if the func has either annotations or keyword arguments. - """ - - args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \ - getfullargspec(func) - if kwonlyargs or ann: - raise ValueError("Function has keyword-only arguments or annotations" - ", use getfullargspec() API which can support them") - return ArgSpec(args, varargs, varkw, defaults) - FullArgSpec = namedtuple('FullArgSpec', 'args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations') def getfullargspec(func): - """Get the names and default values of a function's arguments. + """Get the names and default values of a callable object's arguments. A tuple of seven things is returned: (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults annotations). @@ -944,16 +1018,82 @@ def getfullargspec(func): 'kwonlydefaults' is a dictionary mapping names from kwonlyargs to defaults. 'annotations' is a dictionary mapping argument names to annotations. - The first four items in the tuple correspond to getargspec(). + This function is deprecated, use inspect.signature() instead. """ - if ismethod(func): - func = func.__func__ - if not isfunction(func): - raise TypeError('{!r} is not a Python function'.format(func)) - args, varargs, kwonlyargs, varkw = _getfullargs(func.__code__) - return FullArgSpec(args, varargs, varkw, func.__defaults__, - kwonlyargs, func.__kwdefaults__, func.__annotations__) + try: + # Re: `skip_bound_arg=False` + # + # There is a notable difference in behaviour between getfullargspec + # and Signature: the former always returns 'self' parameter for bound + # methods, whereas the Signature always shows the actual calling + # signature of the passed object. + # + # To simulate this behaviour, we "unbind" bound methods, to trick + # inspect.signature to always return their first parameter ("self", + # usually) + + # Re: `follow_wrapper_chains=False` + # + # getfullargspec() historically ignored __wrapped__ attributes, + # so we ensure that remains the case in 3.3+ + + sig = _signature_from_callable(func, + follow_wrapper_chains=False, + skip_bound_arg=False, + sigcls=Signature) + except Exception as ex: + # Most of the times 'signature' will raise ValueError. + # But, it can also raise AttributeError, and, maybe something + # else. So to be fully backwards compatible, we catch all + # possible exceptions here, and reraise a TypeError. + raise TypeError('unsupported callable') from ex + + args = [] + varargs = None + varkw = None + kwonlyargs = [] + defaults = () + annotations = {} + defaults = () + kwdefaults = {} + + if sig.return_annotation is not sig.empty: + annotations['return'] = sig.return_annotation + + for param in sig.parameters.values(): + kind = param.kind + name = param.name + + if kind is _POSITIONAL_ONLY: + args.append(name) + elif kind is _POSITIONAL_OR_KEYWORD: + args.append(name) + if param.default is not param.empty: + defaults += (param.default,) + elif kind is _VAR_POSITIONAL: + varargs = name + elif kind is _KEYWORD_ONLY: + kwonlyargs.append(name) + if param.default is not param.empty: + kwdefaults[name] = param.default + elif kind is _VAR_KEYWORD: + varkw = name + + if param.annotation is not param.empty: + annotations[name] = param.annotation + + if not kwdefaults: + # compatibility with 'func.__kwdefaults__' + kwdefaults = None + + if not defaults: + # compatibility with 'func.__defaults__' + defaults = None + + return FullArgSpec(args, varargs, varkw, defaults, + kwonlyargs, kwdefaults, annotations) + ArgInfo = namedtuple('ArgInfo', 'args varargs keywords locals') @@ -970,8 +1110,8 @@ def getargvalues(frame): def formatannotation(annotation, base_module=None): if isinstance(annotation, type): if annotation.__module__ in ('builtins', base_module): - return annotation.__name__ - return annotation.__module__+'.'+annotation.__name__ + return annotation.__qualname__ + return annotation.__module__+'.'+annotation.__qualname__ return repr(annotation) def formatannotationrelativeto(object): @@ -988,8 +1128,7 @@ def formatargspec(args, varargs=None, varkw=None, defaults=None, formatvalue=lambda value: '=' + repr(value), formatreturns=lambda text: ' -> ' + text, formatannotation=formatannotation): - """Format an argument spec from the values returned by getargspec - or getfullargspec. + """Format an argument spec from the values returned by getfullargspec. The first seven arguments are (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations). The other five arguments @@ -1058,7 +1197,7 @@ def _missing_arguments(f_name, argnames, pos, values): elif missing == 2: s = "{} and {}".format(*names) else: - tail = ", {} and {}".format(names[-2:]) + tail = ", {} and {}".format(*names[-2:]) del names[-2:] s = ", ".join(names) + tail raise TypeError("%s() missing %i required %s argument%s: %s" % @@ -1087,12 +1226,14 @@ def _too_many(f_name, args, kwonly, varargs, defcount, given, values): (f_name, sig, "s" if plural else "", given, kwonly_sig, "was" if given == 1 and not kwonly_given else "were")) -def getcallargs(func, *positional, **named): +def getcallargs(*func_and_positional, **named): """Get the mapping of arguments to values. A dict is returned, with keys the function argument names (including the names of the * and ** arguments, if any), and values the respective bound values from 'positional' and 'named'.""" + func = func_and_positional[0] + positional = func_and_positional[1:] spec = getfullargspec(func) args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = spec f_name = func.__name__ @@ -1139,7 +1280,7 @@ def getcallargs(func, *positional, **named): missing = 0 for kwarg in kwonlyargs: if kwarg not in arg2value: - if kwarg in kwonlydefaults: + if kwonlydefaults and kwarg in kwonlydefaults: arg2value[kwarg] = kwonlydefaults[kwarg] else: missing += 1 @@ -1242,6 +1383,8 @@ def getlineno(frame): # FrameType.f_lineno is now a descriptor that grovels co_lnotab return frame.f_lineno +FrameInfo = namedtuple('FrameInfo', ('frame',) + Traceback._fields) + def getouterframes(frame, context=1): """Get a list of records for a frame and all higher (calling) frames. @@ -1249,7 +1392,8 @@ def getouterframes(frame, context=1): name, a list of lines of context, and index within the context.""" framelist = [] while frame: - framelist.append((frame,) + getframeinfo(frame, context)) + frameinfo = (frame,) + getframeinfo(frame, context) + framelist.append(FrameInfo(*frameinfo)) frame = frame.f_back return framelist @@ -1260,7 +1404,8 @@ def getinnerframes(tb, context=1): name, a list of lines of context, and index within the context.""" framelist = [] while tb: - framelist.append((tb.tb_frame,) + getframeinfo(tb, context)) + frameinfo = (tb.tb_frame,) + getframeinfo(tb, context) + framelist.append(FrameInfo(*frameinfo)) tb = tb.tb_next return framelist @@ -1410,6 +1555,45 @@ def getgeneratorlocals(generator): else: return {} + +# ------------------------------------------------ coroutine introspection + +CORO_CREATED = 'CORO_CREATED' +CORO_RUNNING = 'CORO_RUNNING' +CORO_SUSPENDED = 'CORO_SUSPENDED' +CORO_CLOSED = 'CORO_CLOSED' + +def getcoroutinestate(coroutine): + """Get current state of a coroutine object. + + Possible states are: + CORO_CREATED: Waiting to start execution. + CORO_RUNNING: Currently being executed by the interpreter. + CORO_SUSPENDED: Currently suspended at an await expression. + CORO_CLOSED: Execution has completed. + """ + if coroutine.cr_running: + return CORO_RUNNING + if coroutine.cr_frame is None: + return CORO_CLOSED + if coroutine.cr_frame.f_lasti == -1: + return CORO_CREATED + return CORO_SUSPENDED + + +def getcoroutinelocals(coroutine): + """ + Get the mapping of coroutine local variables to their current values. + + A dict is returned, with the keys the local variable names and values the + bound values.""" + frame = getattr(coroutine, "cr_frame", None) + if frame is not None: + return frame.f_locals + else: + return {} + + ############################################################################### ### Function Signature Object (PEP 362) ############################################################################### @@ -1417,13 +1601,19 @@ def getgeneratorlocals(generator): _WrapperDescriptor = type(type.__call__) _MethodWrapper = type(all.__call__) +_ClassMethodWrapper = type(int.__dict__['from_bytes']) _NonUserDefinedCallables = (_WrapperDescriptor, _MethodWrapper, + _ClassMethodWrapper, types.BuiltinFunctionType) -def _get_user_defined_method(cls, method_name): +def _signature_get_user_defined_method(cls, method_name): + """Private helper. Checks if ``cls`` has an attribute + named ``method_name`` and returns it only if it is a + pure python function. + """ try: meth = getattr(cls, method_name) except AttributeError: @@ -1435,8 +1625,486 @@ def _get_user_defined_method(cls, method_name): return meth -def signature(obj): - '''Get a signature object for the passed callable.''' +def _signature_get_partial(wrapped_sig, partial, extra_args=()): + """Private helper to calculate how 'wrapped_sig' signature will + look like after applying a 'functools.partial' object (or alike) + on it. + """ + + old_params = wrapped_sig.parameters + new_params = OrderedDict(old_params.items()) + + partial_args = partial.args or () + partial_keywords = partial.keywords or {} + + if extra_args: + partial_args = extra_args + partial_args + + try: + ba = wrapped_sig.bind_partial(*partial_args, **partial_keywords) + except TypeError as ex: + msg = 'partial object {!r} has incorrect arguments'.format(partial) + raise ValueError(msg) from ex + + + transform_to_kwonly = False + for param_name, param in old_params.items(): + try: + arg_value = ba.arguments[param_name] + except KeyError: + pass + else: + if param.kind is _POSITIONAL_ONLY: + # If positional-only parameter is bound by partial, + # it effectively disappears from the signature + new_params.pop(param_name) + continue + + if param.kind is _POSITIONAL_OR_KEYWORD: + if param_name in partial_keywords: + # This means that this parameter, and all parameters + # after it should be keyword-only (and var-positional + # should be removed). Here's why. Consider the following + # function: + # foo(a, b, *args, c): + # pass + # + # "partial(foo, a='spam')" will have the following + # signature: "(*, a='spam', b, c)". Because attempting + # to call that partial with "(10, 20)" arguments will + # raise a TypeError, saying that "a" argument received + # multiple values. + transform_to_kwonly = True + # Set the new default value + new_params[param_name] = param.replace(default=arg_value) + else: + # was passed as a positional argument + new_params.pop(param.name) + continue + + if param.kind is _KEYWORD_ONLY: + # Set the new default value + new_params[param_name] = param.replace(default=arg_value) + + if transform_to_kwonly: + assert param.kind is not _POSITIONAL_ONLY + + if param.kind is _POSITIONAL_OR_KEYWORD: + new_param = new_params[param_name].replace(kind=_KEYWORD_ONLY) + new_params[param_name] = new_param + new_params.move_to_end(param_name) + elif param.kind in (_KEYWORD_ONLY, _VAR_KEYWORD): + new_params.move_to_end(param_name) + elif param.kind is _VAR_POSITIONAL: + new_params.pop(param.name) + + return wrapped_sig.replace(parameters=new_params.values()) + + +def _signature_bound_method(sig): + """Private helper to transform signatures for unbound + functions to bound methods. + """ + + params = tuple(sig.parameters.values()) + + if not params or params[0].kind in (_VAR_KEYWORD, _KEYWORD_ONLY): + raise ValueError('invalid method signature') + + kind = params[0].kind + if kind in (_POSITIONAL_OR_KEYWORD, _POSITIONAL_ONLY): + # Drop first parameter: + # '(p1, p2[, ...])' -> '(p2[, ...])' + params = params[1:] + else: + if kind is not _VAR_POSITIONAL: + # Unless we add a new parameter type we never + # get here + raise ValueError('invalid argument type') + # It's a var-positional parameter. + # Do nothing. '(*args[, ...])' -> '(*args[, ...])' + + return sig.replace(parameters=params) + + +def _signature_is_builtin(obj): + """Private helper to test if `obj` is a callable that might + support Argument Clinic's __text_signature__ protocol. + """ + return (isbuiltin(obj) or + ismethoddescriptor(obj) or + isinstance(obj, _NonUserDefinedCallables) or + # Can't test 'isinstance(type)' here, as it would + # also be True for regular python classes + obj in (type, object)) + + +def _signature_is_functionlike(obj): + """Private helper to test if `obj` is a duck type of FunctionType. + A good example of such objects are functions compiled with + Cython, which have all attributes that a pure Python function + would have, but have their code statically compiled. + """ + + if not callable(obj) or isclass(obj): + # All function-like objects are obviously callables, + # and not classes. + return False + + name = getattr(obj, '__name__', None) + code = getattr(obj, '__code__', None) + defaults = getattr(obj, '__defaults__', _void) # Important to use _void ... + kwdefaults = getattr(obj, '__kwdefaults__', _void) # ... and not None here + annotations = getattr(obj, '__annotations__', None) + + return (isinstance(code, types.CodeType) and + isinstance(name, str) and + (defaults is None or isinstance(defaults, tuple)) and + (kwdefaults is None or isinstance(kwdefaults, dict)) and + isinstance(annotations, dict)) + + +def _signature_get_bound_param(spec): + """ Private helper to get first parameter name from a + __text_signature__ of a builtin method, which should + be in the following format: '($param1, ...)'. + Assumptions are that the first argument won't have + a default value or an annotation. + """ + + assert spec.startswith('($') + + pos = spec.find(',') + if pos == -1: + pos = spec.find(')') + + cpos = spec.find(':') + assert cpos == -1 or cpos > pos + + cpos = spec.find('=') + assert cpos == -1 or cpos > pos + + return spec[2:pos] + + +def _signature_strip_non_python_syntax(signature): + """ + Private helper function. Takes a signature in Argument Clinic's + extended signature format. + + Returns a tuple of three things: + * that signature re-rendered in standard Python syntax, + * the index of the "self" parameter (generally 0), or None if + the function does not have a "self" parameter, and + * the index of the last "positional only" parameter, + or None if the signature has no positional-only parameters. + """ + + if not signature: + return signature, None, None + + self_parameter = None + last_positional_only = None + + lines = [l.encode('ascii') for l in signature.split('\n')] + generator = iter(lines).__next__ + token_stream = tokenize.tokenize(generator) + + delayed_comma = False + skip_next_comma = False + text = [] + add = text.append + + current_parameter = 0 + OP = token.OP + ERRORTOKEN = token.ERRORTOKEN + + # token stream always starts with ENCODING token, skip it + t = next(token_stream) + assert t.type == tokenize.ENCODING + + for t in token_stream: + type, string = t.type, t.string + + if type == OP: + if string == ',': + if skip_next_comma: + skip_next_comma = False + else: + assert not delayed_comma + delayed_comma = True + current_parameter += 1 + continue + + if string == '/': + assert not skip_next_comma + assert last_positional_only is None + skip_next_comma = True + last_positional_only = current_parameter - 1 + continue + + if (type == ERRORTOKEN) and (string == '$'): + assert self_parameter is None + self_parameter = current_parameter + continue + + if delayed_comma: + delayed_comma = False + if not ((type == OP) and (string == ')')): + add(', ') + add(string) + if (string == ','): + add(' ') + clean_signature = ''.join(text) + return clean_signature, self_parameter, last_positional_only + + +def _signature_fromstr(cls, obj, s, skip_bound_arg=True): + """Private helper to parse content of '__text_signature__' + and return a Signature based on it. + """ + + Parameter = cls._parameter_cls + + clean_signature, self_parameter, last_positional_only = \ + _signature_strip_non_python_syntax(s) + + program = "def foo" + clean_signature + ": pass" + + try: + module = ast.parse(program) + except SyntaxError: + module = None + + if not isinstance(module, ast.Module): + raise ValueError("{!r} builtin has invalid signature".format(obj)) + + f = module.body[0] + + parameters = [] + empty = Parameter.empty + invalid = object() + + module = None + module_dict = {} + module_name = getattr(obj, '__module__', None) + if module_name: + module = sys.modules.get(module_name, None) + if module: + module_dict = module.__dict__ + sys_module_dict = sys.modules + + def parse_name(node): + assert isinstance(node, ast.arg) + if node.annotation != None: + raise ValueError("Annotations are not currently supported") + return node.arg + + def wrap_value(s): + try: + value = eval(s, module_dict) + except NameError: + try: + value = eval(s, sys_module_dict) + except NameError: + raise RuntimeError() + + if isinstance(value, str): + return ast.Str(value) + if isinstance(value, (int, float)): + return ast.Num(value) + if isinstance(value, bytes): + return ast.Bytes(value) + if value in (True, False, None): + return ast.NameConstant(value) + raise RuntimeError() + + class RewriteSymbolics(ast.NodeTransformer): + def visit_Attribute(self, node): + a = [] + n = node + while isinstance(n, ast.Attribute): + a.append(n.attr) + n = n.value + if not isinstance(n, ast.Name): + raise RuntimeError() + a.append(n.id) + value = ".".join(reversed(a)) + return wrap_value(value) + + def visit_Name(self, node): + if not isinstance(node.ctx, ast.Load): + raise ValueError() + return wrap_value(node.id) + + def p(name_node, default_node, default=empty): + name = parse_name(name_node) + if name is invalid: + return None + if default_node and default_node is not _empty: + try: + default_node = RewriteSymbolics().visit(default_node) + o = ast.literal_eval(default_node) + except ValueError: + o = invalid + if o is invalid: + return None + default = o if o is not invalid else default + parameters.append(Parameter(name, kind, default=default, annotation=empty)) + + # non-keyword-only parameters + args = reversed(f.args.args) + defaults = reversed(f.args.defaults) + iter = itertools.zip_longest(args, defaults, fillvalue=None) + if last_positional_only is not None: + kind = Parameter.POSITIONAL_ONLY + else: + kind = Parameter.POSITIONAL_OR_KEYWORD + for i, (name, default) in enumerate(reversed(list(iter))): + p(name, default) + if i == last_positional_only: + kind = Parameter.POSITIONAL_OR_KEYWORD + + # *args + if f.args.vararg: + kind = Parameter.VAR_POSITIONAL + p(f.args.vararg, empty) + + # keyword-only arguments + kind = Parameter.KEYWORD_ONLY + for name, default in zip(f.args.kwonlyargs, f.args.kw_defaults): + p(name, default) + + # **kwargs + if f.args.kwarg: + kind = Parameter.VAR_KEYWORD + p(f.args.kwarg, empty) + + if self_parameter is not None: + # Possibly strip the bound argument: + # - We *always* strip first bound argument if + # it is a module. + # - We don't strip first bound argument if + # skip_bound_arg is False. + assert parameters + _self = getattr(obj, '__self__', None) + self_isbound = _self is not None + self_ismodule = ismodule(_self) + if self_isbound and (self_ismodule or skip_bound_arg): + parameters.pop(0) + else: + # for builtins, self parameter is always positional-only! + p = parameters[0].replace(kind=Parameter.POSITIONAL_ONLY) + parameters[0] = p + + return cls(parameters, return_annotation=cls.empty) + + +def _signature_from_builtin(cls, func, skip_bound_arg=True): + """Private helper function to get signature for + builtin callables. + """ + + if not _signature_is_builtin(func): + raise TypeError("{!r} is not a Python builtin " + "function".format(func)) + + s = getattr(func, "__text_signature__", None) + if not s: + raise ValueError("no signature found for builtin {!r}".format(func)) + + return _signature_fromstr(cls, func, s, skip_bound_arg) + + +def _signature_from_function(cls, func): + """Private helper: constructs Signature for the given python function.""" + + is_duck_function = False + if not isfunction(func): + if _signature_is_functionlike(func): + is_duck_function = True + else: + # If it's not a pure Python function, and not a duck type + # of pure function: + raise TypeError('{!r} is not a Python function'.format(func)) + + Parameter = cls._parameter_cls + + # Parameter information. + func_code = func.__code__ + pos_count = func_code.co_argcount + arg_names = func_code.co_varnames + positional = tuple(arg_names[:pos_count]) + keyword_only_count = func_code.co_kwonlyargcount + keyword_only = arg_names[pos_count:(pos_count + keyword_only_count)] + annotations = func.__annotations__ + defaults = func.__defaults__ + kwdefaults = func.__kwdefaults__ + + if defaults: + pos_default_count = len(defaults) + else: + pos_default_count = 0 + + parameters = [] + + # Non-keyword-only parameters w/o defaults. + non_default_count = pos_count - pos_default_count + for name in positional[:non_default_count]: + annotation = annotations.get(name, _empty) + parameters.append(Parameter(name, annotation=annotation, + kind=_POSITIONAL_OR_KEYWORD)) + + # ... w/ defaults. + for offset, name in enumerate(positional[non_default_count:]): + annotation = annotations.get(name, _empty) + parameters.append(Parameter(name, annotation=annotation, + kind=_POSITIONAL_OR_KEYWORD, + default=defaults[offset])) + + # *args + if func_code.co_flags & CO_VARARGS: + name = arg_names[pos_count + keyword_only_count] + annotation = annotations.get(name, _empty) + parameters.append(Parameter(name, annotation=annotation, + kind=_VAR_POSITIONAL)) + + # Keyword-only parameters. + for name in keyword_only: + default = _empty + if kwdefaults is not None: + default = kwdefaults.get(name, _empty) + + annotation = annotations.get(name, _empty) + parameters.append(Parameter(name, annotation=annotation, + kind=_KEYWORD_ONLY, + default=default)) + # **kwargs + if func_code.co_flags & CO_VARKEYWORDS: + index = pos_count + keyword_only_count + if func_code.co_flags & CO_VARARGS: + index += 1 + + name = arg_names[index] + annotation = annotations.get(name, _empty) + parameters.append(Parameter(name, annotation=annotation, + kind=_VAR_KEYWORD)) + + # Is 'func' is a pure Python function - don't validate the + # parameters list (for correct order and defaults), it should be OK. + return cls(parameters, + return_annotation=annotations.get('return', _empty), + __validate_parameters__=is_duck_function) + + +def _signature_from_callable(obj, *, + follow_wrapper_chains=True, + skip_bound_arg=True, + sigcls): + + """Private helper function to get signature for arbitrary + callable objects. + """ if not callable(obj): raise TypeError('{!r} is not a callable object'.format(obj)) @@ -1444,11 +2112,29 @@ def signature(obj): if isinstance(obj, types.MethodType): # In this case we skip the first parameter of the underlying # function (usually `self` or `cls`). - sig = signature(obj.__func__) - return sig.replace(parameters=tuple(sig.parameters.values())[1:]) + sig = _signature_from_callable( + obj.__func__, + follow_wrapper_chains=follow_wrapper_chains, + skip_bound_arg=skip_bound_arg, + sigcls=sigcls) + + if skip_bound_arg: + return _signature_bound_method(sig) + else: + return sig # Was this function wrapped by a decorator? - obj = unwrap(obj, stop=(lambda f: hasattr(f, "__signature__"))) + if follow_wrapper_chains: + obj = unwrap(obj, stop=(lambda f: hasattr(f, "__signature__"))) + if isinstance(obj, types.MethodType): + # If the unwrapped object is a *method*, we might want to + # skip its first parameter (self). + # See test_signature_wrapped_bound_method for details. + return _signature_from_callable( + obj, + follow_wrapper_chains=follow_wrapper_chains, + skip_bound_arg=skip_bound_arg, + sigcls=sigcls) try: sig = obj.__signature__ @@ -1456,56 +2142,54 @@ def signature(obj): pass else: if sig is not None: + if not isinstance(sig, Signature): + raise TypeError( + 'unexpected object {!r} in __signature__ ' + 'attribute'.format(sig)) return sig + try: + partialmethod = obj._partialmethod + except AttributeError: + pass + else: + if isinstance(partialmethod, functools.partialmethod): + # Unbound partialmethod (see functools.partialmethod) + # This means, that we need to calculate the signature + # as if it's a regular partial object, but taking into + # account that the first positional argument + # (usually `self`, or `cls`) will not be passed + # automatically (as for boundmethods) - if isinstance(obj, types.FunctionType): - return Signature.from_function(obj) + wrapped_sig = _signature_from_callable( + partialmethod.func, + follow_wrapper_chains=follow_wrapper_chains, + skip_bound_arg=skip_bound_arg, + sigcls=sigcls) - if isinstance(obj, types.BuiltinFunctionType): - return Signature.from_builtin(obj) + sig = _signature_get_partial(wrapped_sig, partialmethod, (None,)) - if isinstance(obj, functools.partial): - sig = signature(obj.func) + first_wrapped_param = tuple(wrapped_sig.parameters.values())[0] + new_params = (first_wrapped_param,) + tuple(sig.parameters.values()) - new_params = OrderedDict(sig.parameters.items()) + return sig.replace(parameters=new_params) - partial_args = obj.args or () - partial_keywords = obj.keywords or {} - try: - ba = sig.bind_partial(*partial_args, **partial_keywords) - except TypeError as ex: - msg = 'partial object {!r} has incorrect arguments'.format(obj) - raise ValueError(msg) from ex - - for arg_name, arg_value in ba.arguments.items(): - param = new_params[arg_name] - if arg_name in partial_keywords: - # We set a new default value, because the following code - # is correct: - # - # >>> def foo(a): print(a) - # >>> print(partial(partial(foo, a=10), a=20)()) - # 20 - # >>> print(partial(partial(foo, a=10), a=20)(a=30)) - # 30 - # - # So, with 'partial' objects, passing a keyword argument is - # like setting a new default value for the corresponding - # parameter - # - # We also mark this parameter with '_partial_kwarg' - # flag. Later, in '_bind', the 'default' value of this - # parameter will be added to 'kwargs', to simulate - # the 'functools.partial' real call. - new_params[arg_name] = param.replace(default=arg_value, - _partial_kwarg=True) - - elif (param.kind not in (_VAR_KEYWORD, _VAR_POSITIONAL) and - not param._partial_kwarg): - new_params.pop(arg_name) - - return sig.replace(parameters=new_params.values()) + if isfunction(obj) or _signature_is_functionlike(obj): + # If it's a pure Python function, or an object that is duck type + # of a Python function (Cython functions, for instance), then: + return _signature_from_function(sigcls, obj) + + if _signature_is_builtin(obj): + return _signature_from_builtin(sigcls, obj, + skip_bound_arg=skip_bound_arg) + + if isinstance(obj, functools.partial): + wrapped_sig = _signature_from_callable( + obj.func, + follow_wrapper_chains=follow_wrapper_chains, + skip_bound_arg=skip_bound_arg, + sigcls=sigcls) + return _signature_get_partial(wrapped_sig, obj) sig = None if isinstance(obj, type): @@ -1513,32 +2197,92 @@ def signature(obj): # First, let's see if it has an overloaded __call__ defined # in its metaclass - call = _get_user_defined_method(type(obj), '__call__') + call = _signature_get_user_defined_method(type(obj), '__call__') if call is not None: - sig = signature(call) + sig = _signature_from_callable( + call, + follow_wrapper_chains=follow_wrapper_chains, + skip_bound_arg=skip_bound_arg, + sigcls=sigcls) else: # Now we check if the 'obj' class has a '__new__' method - new = _get_user_defined_method(obj, '__new__') + new = _signature_get_user_defined_method(obj, '__new__') if new is not None: - sig = signature(new) + sig = _signature_from_callable( + new, + follow_wrapper_chains=follow_wrapper_chains, + skip_bound_arg=skip_bound_arg, + sigcls=sigcls) else: # Finally, we should have at least __init__ implemented - init = _get_user_defined_method(obj, '__init__') + init = _signature_get_user_defined_method(obj, '__init__') if init is not None: - sig = signature(init) + sig = _signature_from_callable( + init, + follow_wrapper_chains=follow_wrapper_chains, + skip_bound_arg=skip_bound_arg, + sigcls=sigcls) + + if sig is None: + # At this point we know, that `obj` is a class, with no user- + # defined '__init__', '__new__', or class-level '__call__' + + for base in obj.__mro__[:-1]: + # Since '__text_signature__' is implemented as a + # descriptor that extracts text signature from the + # class docstring, if 'obj' is derived from a builtin + # class, its own '__text_signature__' may be 'None'. + # Therefore, we go through the MRO (except the last + # class in there, which is 'object') to find the first + # class with non-empty text signature. + try: + text_sig = base.__text_signature__ + except AttributeError: + pass + else: + if text_sig: + # If 'obj' class has a __text_signature__ attribute: + # return a signature based on it + return _signature_fromstr(sigcls, obj, text_sig) + + # No '__text_signature__' was found for the 'obj' class. + # Last option is to check if its '__init__' is + # object.__init__ or type.__init__. + if type not in obj.__mro__: + # We have a class (not metaclass), but no user-defined + # __init__ or __new__ for it + if (obj.__init__ is object.__init__ and + obj.__new__ is object.__new__): + # Return a signature of 'object' builtin. + return signature(object) + else: + raise ValueError( + 'no signature found for builtin type {!r}'.format(obj)) + elif not isinstance(obj, _NonUserDefinedCallables): # An object with __call__ # We also check that the 'obj' is not an instance of # _WrapperDescriptor or _MethodWrapper to avoid # infinite recursion (and even potential segfault) - call = _get_user_defined_method(type(obj), '__call__') + call = _signature_get_user_defined_method(type(obj), '__call__') if call is not None: - sig = signature(call) + try: + sig = _signature_from_callable( + call, + follow_wrapper_chains=follow_wrapper_chains, + skip_bound_arg=skip_bound_arg, + sigcls=sigcls) + except ValueError as ex: + msg = 'no signature found for {!r}'.format(obj) + raise ValueError(msg) from ex if sig is not None: # For classes and objects we skip the first parameter of their # __call__, __new__, or __init__ methods - return sig.replace(parameters=tuple(sig.parameters.values())[1:]) + if skip_bound_arg: + return _signature_bound_method(sig) + else: + return sig if isinstance(obj, types.BuiltinFunctionType): # Raise a nicer error message for builtins @@ -1549,35 +2293,33 @@ def signature(obj): class _void: - '''A private marker - used in Parameter & Signature''' + """A private marker - used in Parameter & Signature.""" class _empty: - pass + """Marker object for Signature.empty and Parameter.empty.""" -class _ParameterKind(int): - def __new__(self, *args, name): - obj = int.__new__(self, *args) - obj._name = name - return obj +class _ParameterKind(enum.IntEnum): + POSITIONAL_ONLY = 0 + POSITIONAL_OR_KEYWORD = 1 + VAR_POSITIONAL = 2 + KEYWORD_ONLY = 3 + VAR_KEYWORD = 4 def __str__(self): - return self._name - - def __repr__(self): - return '<_ParameterKind: {!r}>'.format(self._name) + return self._name_ -_POSITIONAL_ONLY = _ParameterKind(0, name='POSITIONAL_ONLY') -_POSITIONAL_OR_KEYWORD = _ParameterKind(1, name='POSITIONAL_OR_KEYWORD') -_VAR_POSITIONAL = _ParameterKind(2, name='VAR_POSITIONAL') -_KEYWORD_ONLY = _ParameterKind(3, name='KEYWORD_ONLY') -_VAR_KEYWORD = _ParameterKind(4, name='VAR_KEYWORD') +_POSITIONAL_ONLY = _ParameterKind.POSITIONAL_ONLY +_POSITIONAL_OR_KEYWORD = _ParameterKind.POSITIONAL_OR_KEYWORD +_VAR_POSITIONAL = _ParameterKind.VAR_POSITIONAL +_KEYWORD_ONLY = _ParameterKind.KEYWORD_ONLY +_VAR_KEYWORD = _ParameterKind.VAR_KEYWORD class Parameter: - '''Represents a parameter in a function signature. + """Represents a parameter in a function signature. Has the following public attributes: @@ -1585,18 +2327,20 @@ class Parameter: The name of the parameter as a string. * default : object The default value for the parameter if specified. If the - parameter has no default value, this attribute is not set. + parameter has no default value, this attribute is set to + `Parameter.empty`. * annotation The annotation for the parameter if specified. If the - parameter has no annotation, this attribute is not set. + parameter has no annotation, this attribute is set to + `Parameter.empty`. * kind : str Describes how argument values are bound to the parameter. Possible values: `Parameter.POSITIONAL_ONLY`, `Parameter.POSITIONAL_OR_KEYWORD`, `Parameter.VAR_POSITIONAL`, `Parameter.KEYWORD_ONLY`, `Parameter.VAR_KEYWORD`. - ''' + """ - __slots__ = ('_name', '_kind', '_default', '_annotation', '_partial_kwarg') + __slots__ = ('_name', '_kind', '_default', '_annotation') POSITIONAL_ONLY = _POSITIONAL_ONLY POSITIONAL_OR_KEYWORD = _POSITIONAL_OR_KEYWORD @@ -1606,8 +2350,7 @@ class Parameter: empty = _empty - def __init__(self, name, kind, *, default=_empty, annotation=_empty, - _partial_kwarg=False): + def __init__(self, name, kind, *, default=_empty, annotation=_empty): if kind not in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD, _VAR_POSITIONAL, _KEYWORD_ONLY, _VAR_KEYWORD): @@ -1621,19 +2364,26 @@ def __init__(self, name, kind, *, default=_empty, annotation=_empty, self._default = default self._annotation = annotation - if name is None: - if kind != _POSITIONAL_ONLY: - raise ValueError("None is not a valid name for a " - "non-positional-only parameter") - self._name = name - else: - name = str(name) - if kind != _POSITIONAL_ONLY and not name.isidentifier(): - msg = '{!r} is not a valid parameter name'.format(name) - raise ValueError(msg) - self._name = name + if name is _empty: + raise ValueError('name is a required attribute for Parameter') + + if not isinstance(name, str): + raise TypeError("name must be a str, not a {!r}".format(name)) - self._partial_kwarg = _partial_kwarg + if not name.isidentifier(): + raise ValueError('{!r} is not a valid parameter name'.format(name)) + + self._name = name + + def __reduce__(self): + return (type(self), + (self._name, self._kind), + {'_default': self._default, + '_annotation': self._annotation}) + + def __setstate__(self, state): + self._default = state['_default'] + self._annotation = state['_annotation'] @property def name(self): @@ -1651,9 +2401,9 @@ def annotation(self): def kind(self): return self._kind - def replace(self, *, name=_void, kind=_void, annotation=_void, - default=_void, _partial_kwarg=_void): - '''Creates a customized copy of the Parameter.''' + def replace(self, *, name=_void, kind=_void, + annotation=_void, default=_void): + """Creates a customized copy of the Parameter.""" if name is _void: name = self._name @@ -1667,20 +2417,11 @@ def replace(self, *, name=_void, kind=_void, annotation=_void, if default is _void: default = self._default - if _partial_kwarg is _void: - _partial_kwarg = self._partial_kwarg - - return type(self)(name, kind, default=default, annotation=annotation, - _partial_kwarg=_partial_kwarg) + return type(self)(name, kind, default=default, annotation=annotation) def __str__(self): kind = self.kind - formatted = self._name - if kind == _POSITIONAL_ONLY: - if formatted is None: - formatted = '' - formatted = '<{}>'.format(formatted) # Add annotation and default value if self._annotation is not _empty: @@ -1698,22 +2439,24 @@ def __str__(self): return formatted def __repr__(self): - return '<{} at {:#x} {!r}>'.format(self.__class__.__name__, - id(self), self.name) + return '<{} "{}">'.format(self.__class__.__name__, self) + + def __hash__(self): + return hash((self.name, self.kind, self.annotation, self.default)) def __eq__(self, other): - return (issubclass(other.__class__, Parameter) and - self._name == other._name and + if self is other: + return True + if not isinstance(other, Parameter): + return NotImplemented + return (self._name == other._name and self._kind == other._kind and self._default == other._default and self._annotation == other._annotation) - def __ne__(self, other): - return not self.__eq__(other) - class BoundArguments: - '''Result of `Signature.bind` call. Holds the mapping of arguments + """Result of `Signature.bind` call. Holds the mapping of arguments to the function's parameters. Has the following public attributes: @@ -1727,7 +2470,9 @@ class BoundArguments: Tuple of positional arguments values. * kwargs : dict Dict of keyword arguments values. - ''' + """ + + __slots__ = ('arguments', '_signature', '__weakref__') def __init__(self, signature, arguments): self.arguments = arguments @@ -1741,12 +2486,7 @@ def signature(self): def args(self): args = [] for param_name, param in self._signature.parameters.items(): - if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or - param._partial_kwarg): - # Keyword arguments mapped by 'functools.partial' - # (Parameter._partial_kwarg is True) are mapped - # in 'BoundArguments.kwargs', along with VAR_KEYWORD & - # KEYWORD_ONLY + if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY): break try: @@ -1771,8 +2511,7 @@ def kwargs(self): kwargs_started = False for param_name, param in self._signature.parameters.items(): if not kwargs_started: - if (param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY) or - param._partial_kwarg): + if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY): kwargs_started = True else: if param_name not in self.arguments: @@ -1796,17 +2535,60 @@ def kwargs(self): return kwargs + def apply_defaults(self): + """Set default values for missing arguments. + + For variable-positional arguments (*args) the default is an + empty tuple. + + For variable-keyword arguments (**kwargs) the default is an + empty dict. + """ + arguments = self.arguments + if not arguments: + return + new_arguments = [] + for name, param in self._signature.parameters.items(): + try: + new_arguments.append((name, arguments[name])) + except KeyError: + if param.default is not _empty: + val = param.default + elif param.kind is _VAR_POSITIONAL: + val = () + elif param.kind is _VAR_KEYWORD: + val = {} + else: + # This BoundArguments was likely produced by + # Signature.bind_partial(). + continue + new_arguments.append((name, val)) + self.arguments = OrderedDict(new_arguments) + def __eq__(self, other): - return (issubclass(other.__class__, BoundArguments) and - self.signature == other.signature and + if self is other: + return True + if not isinstance(other, BoundArguments): + return NotImplemented + return (self.signature == other.signature and self.arguments == other.arguments) - def __ne__(self, other): - return not self.__eq__(other) + def __setstate__(self, state): + self._signature = state['_signature'] + self.arguments = state['arguments'] + + def __getstate__(self): + return {'_signature': self._signature, 'arguments': self.arguments} + + def __repr__(self): + args = [] + for arg, value in self.arguments.items(): + args.append('{}={!r}'.format(arg, value)) + return '<{} ({})>'.format(self.__class__.__name__, ', '.join(args)) class Signature: - '''A Signature object represents the overall signature of a function. + """A Signature object represents the overall signature of a function. It stores a Parameter object for each parameter accepted by the function, as well as information specific to the function itself. @@ -1819,14 +2601,14 @@ class Signature: * return_annotation : object The annotation for the return type of the function if specified. If the function has no annotation for its return type, this - attribute is not set. + attribute is set to `Signature.empty`. * bind(*args, **kwargs) -> BoundArguments Creates a mapping from positional and keyword arguments to parameters. * bind_partial(*args, **kwargs) -> BoundArguments Creates a partial mapping from positional and keyword arguments to parameters (simulating 'functools.partial' behavior.) - ''' + """ __slots__ = ('_return_annotation', '_parameters') @@ -1837,9 +2619,9 @@ class Signature: def __init__(self, parameters=None, *, return_annotation=_empty, __validate_parameters__=True): - '''Constructs Signature from the given list of Parameter + """Constructs Signature from the given list of Parameter objects and 'return_annotation'. All arguments are optional. - ''' + """ if parameters is None: params = OrderedDict() @@ -1847,24 +2629,37 @@ def __init__(self, parameters=None, *, return_annotation=_empty, if __validate_parameters__: params = OrderedDict() top_kind = _POSITIONAL_ONLY + kind_defaults = False for idx, param in enumerate(parameters): kind = param.kind + name = param.name + if kind < top_kind: - msg = 'wrong parameter order: {} before {}' - msg = msg.format(top_kind, param.kind) + msg = 'wrong parameter order: {!r} before {!r}' + msg = msg.format(top_kind, kind) raise ValueError(msg) - else: + elif kind > top_kind: + kind_defaults = False top_kind = kind - name = param.name - if name is None: - name = str(idx) - param = param.replace(name=name) + if kind in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD): + if param.default is _empty: + if kind_defaults: + # No default for this parameter, but the + # previous parameter of the same kind had + # a default + msg = 'non-default argument follows default ' \ + 'argument' + raise ValueError(msg) + else: + # There is a default for this parameter. + kind_defaults = True if name in params: msg = 'duplicate parameter name: {!r}'.format(name) raise ValueError(msg) + params[name] = param else: params = OrderedDict(((param.name, param) @@ -1875,134 +2670,27 @@ def __init__(self, parameters=None, *, return_annotation=_empty, @classmethod def from_function(cls, func): - '''Constructs Signature for the given python function''' + """Constructs Signature for the given python function.""" - if not isinstance(func, types.FunctionType): - raise TypeError('{!r} is not a Python function'.format(func)) - - Parameter = cls._parameter_cls - - # Parameter information. - func_code = func.__code__ - pos_count = func_code.co_argcount - arg_names = func_code.co_varnames - positional = tuple(arg_names[:pos_count]) - keyword_only_count = func_code.co_kwonlyargcount - keyword_only = arg_names[pos_count:(pos_count + keyword_only_count)] - annotations = func.__annotations__ - defaults = func.__defaults__ - kwdefaults = func.__kwdefaults__ - - if defaults: - pos_default_count = len(defaults) - else: - pos_default_count = 0 - - parameters = [] - - # Non-keyword-only parameters w/o defaults. - non_default_count = pos_count - pos_default_count - for name in positional[:non_default_count]: - annotation = annotations.get(name, _empty) - parameters.append(Parameter(name, annotation=annotation, - kind=_POSITIONAL_OR_KEYWORD)) - - # ... w/ defaults. - for offset, name in enumerate(positional[non_default_count:]): - annotation = annotations.get(name, _empty) - parameters.append(Parameter(name, annotation=annotation, - kind=_POSITIONAL_OR_KEYWORD, - default=defaults[offset])) - - # *args - if func_code.co_flags & 0x04: - name = arg_names[pos_count + keyword_only_count] - annotation = annotations.get(name, _empty) - parameters.append(Parameter(name, annotation=annotation, - kind=_VAR_POSITIONAL)) - - # Keyword-only parameters. - for name in keyword_only: - default = _empty - if kwdefaults is not None: - default = kwdefaults.get(name, _empty) - - annotation = annotations.get(name, _empty) - parameters.append(Parameter(name, annotation=annotation, - kind=_KEYWORD_ONLY, - default=default)) - # **kwargs - if func_code.co_flags & 0x08: - index = pos_count + keyword_only_count - if func_code.co_flags & 0x04: - index += 1 - - name = arg_names[index] - annotation = annotations.get(name, _empty) - parameters.append(Parameter(name, annotation=annotation, - kind=_VAR_KEYWORD)) - - return cls(parameters, - return_annotation=annotations.get('return', _empty), - __validate_parameters__=False) + warnings.warn("inspect.Signature.from_function() is deprecated, " + "use Signature.from_callable()", + DeprecationWarning, stacklevel=2) + return _signature_from_function(cls, func) @classmethod def from_builtin(cls, func): - s = getattr(func, "__text_signature__", None) - if not s: - return None - - if s.endswith("/)"): - kind = Parameter.POSITIONAL_ONLY - s = s[:-2] + ')' - else: - kind = Parameter.POSITIONAL_OR_KEYWORD - - s = "def foo" + s + ": pass" - - try: - module = ast.parse(s) - except SyntaxError: - return None - if not isinstance(module, ast.Module): - return None + """Constructs Signature for the given builtin function.""" - # ast.FunctionDef - f = module.body[0] - - parameters = [] - empty = Parameter.empty - - def p(name_node, default_node, default=empty): - name = name_node.arg - - if isinstance(default_node, ast.Num): - default = default.n - elif isinstance(default_node, ast.NameConstant): - default = default_node.value - parameters.append(Parameter(name, kind, default=default, annotation=empty)) - - # non-keyword-only parameters - for name, default in reversed(list(itertools.zip_longest(reversed(f.args.args), reversed(f.args.defaults), fillvalue=None))): - p(name, default) - - # *args - if f.args.vararg: - kind = Parameter.VAR_POSITIONAL - p(f.args.vararg, empty) - - # keyword-only arguments - kind = Parameter.KEYWORD_ONLY - for name, default in zip(f.args.kwonlyargs, f.args.kw_defaults): - p(name, default) - - # **kwargs - if f.args.kwarg: - kind = Parameter.VAR_KEYWORD - p(f.args.kwarg, empty) - - return cls(parameters, return_annotation=cls.empty) + warnings.warn("inspect.Signature.from_builtin() is deprecated, " + "use Signature.from_callable()", + DeprecationWarning, stacklevel=2) + return _signature_from_builtin(cls, func) + @classmethod + def from_callable(cls, obj, *, follow_wrapped=True): + """Constructs Signature for the given callable object.""" + return _signature_from_callable(obj, sigcls=cls, + follow_wrapper_chains=follow_wrapped) @property def parameters(self): @@ -2013,10 +2701,10 @@ def return_annotation(self): return self._return_annotation def replace(self, *, parameters=_void, return_annotation=_void): - '''Creates a customized copy of the Signature. + """Creates a customized copy of the Signature. Pass 'parameters' and/or 'return_annotation' arguments to override them in the new copy. - ''' + """ if parameters is _void: parameters = self.parameters.values() @@ -2027,41 +2715,29 @@ def replace(self, *, parameters=_void, return_annotation=_void): return type(self)(parameters, return_annotation=return_annotation) - def __eq__(self, other): - if (not issubclass(type(other), Signature) or - self.return_annotation != other.return_annotation or - len(self.parameters) != len(other.parameters)): - return False + def _hash_basis(self): + params = tuple(param for param in self.parameters.values() + if param.kind != _KEYWORD_ONLY) - other_positions = {param: idx - for idx, param in enumerate(other.parameters.keys())} + kwo_params = {param.name: param for param in self.parameters.values() + if param.kind == _KEYWORD_ONLY} - for idx, (param_name, param) in enumerate(self.parameters.items()): - if param.kind == _KEYWORD_ONLY: - try: - other_param = other.parameters[param_name] - except KeyError: - return False - else: - if param != other_param: - return False - else: - try: - other_idx = other_positions[param_name] - except KeyError: - return False - else: - if (idx != other_idx or - param != other.parameters[param_name]): - return False + return params, kwo_params, self.return_annotation - return True + def __hash__(self): + params, kwo_params, return_annotation = self._hash_basis() + kwo_params = frozenset(kwo_params.values()) + return hash((params, kwo_params, return_annotation)) - def __ne__(self, other): - return not self.__eq__(other) + def __eq__(self, other): + if self is other: + return True + if not isinstance(other, Signature): + return NotImplemented + return self._hash_basis() == other._hash_basis() def _bind(self, args, kwargs, *, partial=False): - '''Private method. Don't use directly.''' + """Private method. Don't use directly.""" arguments = OrderedDict() @@ -2069,15 +2745,6 @@ def _bind(self, args, kwargs, *, partial=False): parameters_ex = () arg_vals = iter(args) - if partial: - # Support for binding arguments to 'functools.partial' objects. - # See 'functools.partial' case in 'signature()' implementation - # for details. - for param_name, param in self.parameters.items(): - if (param._partial_kwarg and param_name not in kwargs): - # Simulating 'functools.partial' behavior - kwargs[param_name] = param.default - while True: # Let's iterate through the positional arguments and corresponding # parameters @@ -2112,11 +2779,13 @@ def _bind(self, args, kwargs, *, partial=False): parameters_ex = (param,) break else: + # No default, not VAR_KEYWORD, not VAR_POSITIONAL, + # not in `kwargs` if partial: parameters_ex = (param,) break else: - msg = '{arg!r} parameter lacking default value' + msg = 'missing a required argument: {arg!r}' msg = msg.format(arg=param.name) raise TypeError(msg) from None else: @@ -2129,7 +2798,8 @@ def _bind(self, args, kwargs, *, partial=False): if param.kind in (_VAR_KEYWORD, _KEYWORD_ONLY): # Looks like we have no parameter for this positional # argument - raise TypeError('too many positional arguments') + raise TypeError( + 'too many positional arguments') from None if param.kind == _VAR_POSITIONAL: # We have an '*args'-like argument, let's fill it with @@ -2141,8 +2811,9 @@ def _bind(self, args, kwargs, *, partial=False): break if param.name in kwargs: - raise TypeError('multiple values for argument ' - '{arg!r}'.format(arg=param.name)) + raise TypeError( + 'multiple values for argument {arg!r}'.format( + arg=param.name)) from None arguments[param.name] = arg_val @@ -2150,19 +2821,17 @@ def _bind(self, args, kwargs, *, partial=False): # keyword arguments kwargs_param = None for param in itertools.chain(parameters_ex, parameters): - if param.kind == _POSITIONAL_ONLY: - # This should never happen in case of a properly built - # Signature object (but let's have this check here - # to ensure correct behaviour just in case) - raise TypeError('{arg!r} parameter is positional only, ' - 'but was passed as a keyword'. \ - format(arg=param.name)) - if param.kind == _VAR_KEYWORD: # Memorize that we have a '**kwargs'-like parameter kwargs_param = param continue + if param.kind == _VAR_POSITIONAL: + # Named arguments don't refer to '*args'-like parameters. + # We only arrive here if the positional arguments ended + # before reaching the last parameter before *args. + continue + param_name = param.name try: arg_val = kwargs.pop(param_name) @@ -2173,10 +2842,18 @@ def _bind(self, args, kwargs, *, partial=False): # arguments. if (not partial and param.kind != _VAR_POSITIONAL and param.default is _empty): - raise TypeError('{arg!r} parameter lacking default value'. \ + raise TypeError('missing a required argument: {arg!r}'. \ format(arg=param_name)) from None else: + if param.kind == _POSITIONAL_ONLY: + # This should never happen in case of a properly built + # Signature object (but let's have this check here + # to ensure correct behaviour just in case) + raise TypeError('{arg!r} parameter is positional only, ' + 'but was passed as a keyword'. \ + format(arg=param.name)) + arguments[param_name] = arg_val if kwargs: @@ -2184,31 +2861,54 @@ def _bind(self, args, kwargs, *, partial=False): # Process our '**kwargs'-like parameter arguments[kwargs_param.name] = kwargs else: - raise TypeError('too many keyword arguments') + raise TypeError( + 'got an unexpected keyword argument {arg!r}'.format( + arg=next(iter(kwargs)))) return self._bound_arguments_cls(self, arguments) - def bind(__bind_self, *args, **kwargs): - '''Get a BoundArguments object, that maps the passed `args` + def bind(*args, **kwargs): + """Get a BoundArguments object, that maps the passed `args` and `kwargs` to the function's signature. Raises `TypeError` if the passed arguments can not be bound. - ''' - return __bind_self._bind(args, kwargs) + """ + return args[0]._bind(args[1:], kwargs) - def bind_partial(__bind_self, *args, **kwargs): - '''Get a BoundArguments object, that partially maps the + def bind_partial(*args, **kwargs): + """Get a BoundArguments object, that partially maps the passed `args` and `kwargs` to the function's signature. Raises `TypeError` if the passed arguments can not be bound. - ''' - return __bind_self._bind(args, kwargs, partial=True) + """ + return args[0]._bind(args[1:], kwargs, partial=True) + + def __reduce__(self): + return (type(self), + (tuple(self._parameters.values()),), + {'_return_annotation': self._return_annotation}) + + def __setstate__(self, state): + self._return_annotation = state['_return_annotation'] + + def __repr__(self): + return '<{} {}>'.format(self.__class__.__name__, self) def __str__(self): result = [] + render_pos_only_separator = False render_kw_only_separator = True - for idx, param in enumerate(self.parameters.values()): + for param in self.parameters.values(): formatted = str(param) kind = param.kind + + if kind == _POSITIONAL_ONLY: + render_pos_only_separator = True + elif render_pos_only_separator: + # It's not a positional-only parameter, and the flag + # is set to 'True' (there were pos-only params before.) + result.append('/') + render_pos_only_separator = False + if kind == _VAR_POSITIONAL: # OK, we have an '*args'-like parameter, so we won't need # a '*' to separate keyword-only arguments @@ -2224,6 +2924,11 @@ def __str__(self): result.append(formatted) + if render_pos_only_separator: + # There were only positional-only parameters, hence the + # flag was not reset to 'False' + result.append('/') + rendered = '({})'.format(', '.join(result)) if self.return_annotation is not _empty: @@ -2232,6 +2937,12 @@ def __str__(self): return rendered + +def signature(obj, *, follow_wrapped=True): + """Get a signature object for the passed callable.""" + return Signature.from_callable(obj, follow_wrapped=follow_wrapped) + + def _main(): """ Logic for inspecting an object given at command line """ import argparse diff --git a/Lib/io.py b/Lib/io.py index 39878b83374b..8d68f1e42409 100644 --- a/Lib/io.py +++ b/Lib/io.py @@ -70,16 +70,16 @@ # Method descriptions and default implementations are inherited from the C # version however. class IOBase(_io._IOBase, metaclass=abc.ABCMeta): - pass + __doc__ = _io._IOBase.__doc__ class RawIOBase(_io._RawIOBase, IOBase): - pass + __doc__ = _io._RawIOBase.__doc__ class BufferedIOBase(_io._BufferedIOBase, IOBase): - pass + __doc__ = _io._BufferedIOBase.__doc__ class TextIOBase(_io._TextIOBase, IOBase): - pass + __doc__ = _io._TextIOBase.__doc__ RawIOBase.register(FileIO) diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py index 97ff13dfd0a0..7469a9d6ddfa 100644 --- a/Lib/ipaddress.py +++ b/Lib/ipaddress.py @@ -135,7 +135,7 @@ def v4_int_to_packed(address): """ try: return address.to_bytes(4, 'big') - except: + except OverflowError: raise ValueError("Address negative or too large for IPv4") @@ -151,7 +151,7 @@ def v6_int_to_packed(address): """ try: return address.to_bytes(16, 'big') - except: + except OverflowError: raise ValueError("Address negative or too large for IPv6") @@ -164,22 +164,23 @@ def _split_optional_netmask(address): def _find_address_range(addresses): - """Find a sequence of IPv#Address. + """Find a sequence of sorted deduplicated IPv#Address. Args: addresses: a list of IPv#Address objects. - Returns: + Yields: A tuple containing the first and last IP addresses in the sequence. """ - first = last = addresses[0] - for ip in addresses[1:]: - if ip._ip == last._ip + 1: - last = ip - else: - break - return (first, last) + it = iter(addresses) + first = last = next(it) + for ip in it: + if ip._ip != last._ip + 1: + yield first, last + first = ip + last = ip + yield first, last def _count_righthand_zero_bits(number, bits): @@ -195,11 +196,7 @@ def _count_righthand_zero_bits(number, bits): """ if number == 0: return bits - for i in range(bits): - if (number >> i) & 1: - return i - # All bits of interest were zero, even if there are more in the number - return bits + return min(bits, (~number & (number-1)).bit_length()) def summarize_address_range(first, last): @@ -250,15 +247,14 @@ def summarize_address_range(first, last): while first_int <= last_int: nbits = min(_count_righthand_zero_bits(first_int, ip_bits), (last_int - first_int + 1).bit_length() - 1) - net = ip('%s/%d' % (first, ip_bits - nbits)) + net = ip((first_int, ip_bits - nbits)) yield net first_int += 1 << nbits if first_int - 1 == ip._ALL_ONES: break - first = first.__class__(first_int) -def _collapse_addresses_recursive(addresses): +def _collapse_addresses_internal(addresses): """Loops through the addresses, collapsing concurrent netblocks. Example: @@ -268,7 +264,7 @@ def _collapse_addresses_recursive(addresses): ip3 = IPv4Network('192.0.2.128/26') ip4 = IPv4Network('192.0.2.192/26') - _collapse_addresses_recursive([ip1, ip2, ip3, ip4]) -> + _collapse_addresses_internal([ip1, ip2, ip3, ip4]) -> [IPv4Network('192.0.2.0/24')] This shouldn't be called directly; it is called via @@ -282,28 +278,29 @@ def _collapse_addresses_recursive(addresses): passed. """ - while True: - last_addr = None - ret_array = [] - optimized = False - - for cur_addr in addresses: - if not ret_array: - last_addr = cur_addr - ret_array.append(cur_addr) - elif (cur_addr.network_address >= last_addr.network_address and - cur_addr.broadcast_address <= last_addr.broadcast_address): - optimized = True - elif cur_addr == list(last_addr.supernet().subnets())[1]: - ret_array[-1] = last_addr = last_addr.supernet() - optimized = True - else: - last_addr = cur_addr - ret_array.append(cur_addr) - - addresses = ret_array - if not optimized: - return addresses + # First merge + to_merge = list(addresses) + subnets = {} + while to_merge: + net = to_merge.pop() + supernet = net.supernet() + existing = subnets.get(supernet) + if existing is None: + subnets[supernet] = net + elif existing != net: + # Merge consecutive subnets + del subnets[supernet] + to_merge.append(supernet) + # Then iterate over resulting networks, skipping subsumed subnets + last = None + for net in sorted(subnets.values()): + if last is not None: + # Since they are sorted, last.network_address <= net.network_address + # is a given. + if last.broadcast_address >= net.broadcast_address: + continue + yield net + last = net def collapse_addresses(addresses): @@ -324,7 +321,6 @@ def collapse_addresses(addresses): TypeError: If passed a list of mixed version objects. """ - i = 0 addrs = [] ips = [] nets = [] @@ -352,15 +348,13 @@ def collapse_addresses(addresses): # sort and dedup ips = sorted(set(ips)) - nets = sorted(set(nets)) - while i < len(ips): - (first, last) = _find_address_range(ips[i:]) - i = ips.index(last) + 1 - addrs.extend(summarize_address_range(first, last)) + # find consecutive address ranges in the sorted sequence and summarize them + if ips: + for first, last in _find_address_range(ips): + addrs.extend(summarize_address_range(first, last)) - return iter(_collapse_addresses_recursive(sorted( - addrs + nets, key=_BaseNetwork._get_networks_key))) + return _collapse_addresses_internal(addrs + nets) def get_mixed_type_key(obj): @@ -388,43 +382,12 @@ def get_mixed_type_key(obj): return NotImplemented -class _TotalOrderingMixin: - # Helper that derives the other comparison operations from - # __lt__ and __eq__ - # We avoid functools.total_ordering because it doesn't handle - # NotImplemented correctly yet (http://bugs.python.org/issue10042) - def __eq__(self, other): - raise NotImplementedError - def __ne__(self, other): - equal = self.__eq__(other) - if equal is NotImplemented: - return NotImplemented - return not equal - def __lt__(self, other): - raise NotImplementedError - def __le__(self, other): - less = self.__lt__(other) - if less is NotImplemented or not less: - return self.__eq__(other) - return less - def __gt__(self, other): - less = self.__lt__(other) - if less is NotImplemented: - return NotImplemented - equal = self.__eq__(other) - if equal is NotImplemented: - return NotImplemented - return not (less or equal) - def __ge__(self, other): - less = self.__lt__(other) - if less is NotImplemented: - return NotImplemented - return not less - -class _IPAddressBase(_TotalOrderingMixin): +class _IPAddressBase: """The mother class.""" + __slots__ = () + @property def exploded(self): """Return the longhand version of the IP address as a string.""" @@ -435,6 +398,17 @@ def compressed(self): """Return the shorthand version of the IP address as a string.""" return str(self) + @property + def reverse_pointer(self): + """The name of the reverse DNS pointer for the IP address, e.g.: + >>> ipaddress.ip_address("127.0.0.1").reverse_pointer + '1.0.0.127.in-addr.arpa' + >>> ipaddress.ip_address("2001:db8::1").reverse_pointer + '1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa' + + """ + return self._reverse_pointer() + @property def version(self): msg = '%200s has no version specified' % (type(self),) @@ -456,8 +430,9 @@ def _check_packed_address(self, address, expected_len): raise AddressValueError(msg % (address, address_len, expected_len, self._version)) - def _ip_int_from_prefix(self, prefixlen=None): - """Turn the prefix length netmask into a int for comparison. + @classmethod + def _ip_int_from_prefix(cls, prefixlen): + """Turn the prefix length into a bitwise netmask Args: prefixlen: An integer, the prefix length. @@ -466,51 +441,111 @@ def _ip_int_from_prefix(self, prefixlen=None): An integer. """ - if prefixlen is None: - prefixlen = self._prefixlen - return self._ALL_ONES ^ (self._ALL_ONES >> prefixlen) + return cls._ALL_ONES ^ (cls._ALL_ONES >> prefixlen) - def _prefix_from_ip_int(self, ip_int, mask=32): - """Return prefix length from the decimal netmask. + @classmethod + def _prefix_from_ip_int(cls, ip_int): + """Return prefix length from the bitwise netmask. Args: - ip_int: An integer, the IP address. - mask: The netmask. Defaults to 32. + ip_int: An integer, the netmask in expanded bitwise format Returns: An integer, the prefix length. + Raises: + ValueError: If the input intermingles zeroes & ones + """ + trailing_zeroes = _count_righthand_zero_bits(ip_int, + cls._max_prefixlen) + prefixlen = cls._max_prefixlen - trailing_zeroes + leading_ones = ip_int >> trailing_zeroes + all_ones = (1 << prefixlen) - 1 + if leading_ones != all_ones: + byteslen = cls._max_prefixlen // 8 + details = ip_int.to_bytes(byteslen, 'big') + msg = 'Netmask pattern %r mixes zeroes & ones' + raise ValueError(msg % details) + return prefixlen + + @classmethod + def _report_invalid_netmask(cls, netmask_str): + msg = '%r is not a valid netmask' % netmask_str + raise NetmaskValueError(msg) from None + + @classmethod + def _prefix_from_prefix_string(cls, prefixlen_str): + """Return prefix length from a numeric string + + Args: + prefixlen_str: The string to be converted + + Returns: + An integer, the prefix length. + + Raises: + NetmaskValueError: If the input is not a valid netmask """ - return mask - _count_righthand_zero_bits(ip_int, mask) + # int allows a leading +/- as well as surrounding whitespace, + # so we ensure that isn't the case + if not _BaseV4._DECIMAL_DIGITS.issuperset(prefixlen_str): + cls._report_invalid_netmask(prefixlen_str) + try: + prefixlen = int(prefixlen_str) + except ValueError: + cls._report_invalid_netmask(prefixlen_str) + if not (0 <= prefixlen <= cls._max_prefixlen): + cls._report_invalid_netmask(prefixlen_str) + return prefixlen - def _ip_string_from_prefix(self, prefixlen=None): - """Turn a prefix length into a dotted decimal string. + @classmethod + def _prefix_from_ip_string(cls, ip_str): + """Turn a netmask/hostmask string into a prefix length Args: - prefixlen: An integer, the netmask prefix length. + ip_str: The netmask/hostmask to be converted Returns: - A string, the dotted decimal netmask string. + An integer, the prefix length. + Raises: + NetmaskValueError: If the input is not a valid netmask/hostmask """ - if not prefixlen: - prefixlen = self._prefixlen - return self._string_from_ip_int(self._ip_int_from_prefix(prefixlen)) + # Parse the netmask/hostmask like an IP address. + try: + ip_int = cls._ip_int_from_string(ip_str) + except AddressValueError: + cls._report_invalid_netmask(ip_str) + + # Try matching a netmask (this would be /1*0*/ as a bitwise regexp). + # Note that the two ambiguous cases (all-ones and all-zeroes) are + # treated as netmasks. + try: + return cls._prefix_from_ip_int(ip_int) + except ValueError: + pass + + # Invert the bits, and try matching a /0+1+/ hostmask instead. + ip_int ^= cls._ALL_ONES + try: + return cls._prefix_from_ip_int(ip_int) + except ValueError: + cls._report_invalid_netmask(ip_str) + + def __reduce__(self): + return self.__class__, (str(self),) +@functools.total_ordering class _BaseAddress(_IPAddressBase): """A generic IP object. This IP class contains the version independent methods which are used by single IP addresses. - """ - def __init__(self, address): - if (not isinstance(address, bytes) - and '/' in str(address)): - raise AddressValueError("Unexpected '/' in %r" % address) + __slots__ = () def __int__(self): return self._ip @@ -523,12 +558,11 @@ def __eq__(self, other): return NotImplemented def __lt__(self, other): + if not isinstance(other, _BaseAddress): + return NotImplemented if self._version != other._version: raise TypeError('%s and %s are not of the same version' % ( self, other)) - if not isinstance(other, _BaseAddress): - raise TypeError('%s and %s are not of the same type' % ( - self, other)) if self._ip != other._ip: return self._ip < other._ip return False @@ -557,7 +591,11 @@ def __hash__(self): def _get_address_key(self): return (self._version, self) + def __reduce__(self): + return self.__class__, (self._ip,) + +@functools.total_ordering class _BaseNetwork(_IPAddressBase): """A generic IP network object. @@ -607,12 +645,11 @@ def __getitem__(self, n): return self._address_class(broadcast + n) def __lt__(self, other): + if not isinstance(other, _BaseNetwork): + return NotImplemented if self._version != other._version: raise TypeError('%s and %s are not of the same version' % ( self, other)) - if not isinstance(other, _BaseNetwork): - raise TypeError('%s and %s are not of the same type' % ( - self, other)) if self.network_address != other.network_address: return self.network_address < other.network_address if self.netmask != other.netmask: @@ -743,7 +780,7 @@ def address_exclude(self, other): other.broadcast_address <= self.broadcast_address): raise ValueError('%s not contained in %s' % (other, self)) if other == self: - raise StopIteration + return # Make sure we're comparing the network of other. other = other.__class__('%s/%s' % (other.network_address, @@ -873,25 +910,16 @@ def subnets(self, prefixlen_diff=1, new_prefix=None): raise ValueError('prefix length diff must be > 0') new_prefixlen = self._prefixlen + prefixlen_diff - if not self._is_valid_netmask(str(new_prefixlen)): + if new_prefixlen > self._max_prefixlen: raise ValueError( 'prefix length diff %d is invalid for netblock %s' % ( new_prefixlen, self)) - first = self.__class__('%s/%s' % - (self.network_address, - self._prefixlen + prefixlen_diff)) - - yield first - current = first - while True: - broadcast = current.broadcast_address - if broadcast == self.broadcast_address: - return - new_addr = self._address_class(int(broadcast) + 1) - current = self.__class__('%s/%s' % (new_addr, - new_prefixlen)) - + start = int(self.network_address) + end = int(self.broadcast_address) + step = (int(self.hostmask) + 1) >> prefixlen_diff + for new_addr in range(start, end, step): + current = self.__class__((new_addr, new_prefixlen)) yield current def supernet(self, prefixlen_diff=1, new_prefix=None): @@ -925,15 +953,15 @@ def supernet(self, prefixlen_diff=1, new_prefix=None): raise ValueError('cannot set prefixlen_diff and new_prefix') prefixlen_diff = self._prefixlen - new_prefix - if self.prefixlen - prefixlen_diff < 0: + new_prefixlen = self.prefixlen - prefixlen_diff + if new_prefixlen < 0: raise ValueError( 'current prefixlen is %d, cannot have a prefixlen_diff of %d' % (self.prefixlen, prefixlen_diff)) - # TODO (pmoody): optimize this. - t = self.__class__('%s/%d' % (self.network_address, - self.prefixlen - prefixlen_diff), - strict=False) - return t.__class__('%s/%d' % (t.network_address, t.prefixlen)) + return self.__class__(( + int(self.network_address) & (int(self.netmask) << prefixlen_diff), + new_prefixlen + )) @property def is_multicast(self): @@ -1027,21 +1055,49 @@ class _BaseV4: """ + __slots__ = () + _version = 4 # Equivalent to 255.255.255.255 or 32 bits of 1's. _ALL_ONES = (2**IPV4LENGTH) - 1 _DECIMAL_DIGITS = frozenset('0123456789') # the valid octets for host and netmasks. only useful for IPv4. - _valid_mask_octets = frozenset((255, 254, 252, 248, 240, 224, 192, 128, 0)) + _valid_mask_octets = frozenset({255, 254, 252, 248, 240, 224, 192, 128, 0}) - def __init__(self, address): - self._version = 4 - self._max_prefixlen = IPV4LENGTH + _max_prefixlen = IPV4LENGTH + # There are only a handful of valid v4 netmasks, so we cache them all + # when constructed (see _make_netmask()). + _netmask_cache = {} def _explode_shorthand_ip_string(self): return str(self) - def _ip_int_from_string(self, ip_str): + @classmethod + def _make_netmask(cls, arg): + """Make a (netmask, prefix_len) tuple from the given argument. + + Argument can be: + - an integer (the prefix length) + - a string representing the prefix length (e.g. "24") + - a string representing the prefix netmask (e.g. "255.255.255.0") + """ + if arg not in cls._netmask_cache: + if isinstance(arg, int): + prefixlen = arg + else: + try: + # Check for a netmask in prefix length form + prefixlen = cls._prefix_from_prefix_string(arg) + except NetmaskValueError: + # Check for a netmask or hostmask in dotted-quad form. + # This may raise NetmaskValueError. + prefixlen = cls._prefix_from_ip_string(arg) + netmask = IPv4Address(cls._ip_int_from_prefix(prefixlen)) + cls._netmask_cache[arg] = netmask, prefixlen + return cls._netmask_cache[arg] + + @classmethod + def _ip_int_from_string(cls, ip_str): """Turn the given IP string into an integer for comparison. Args: @@ -1062,11 +1118,12 @@ def _ip_int_from_string(self, ip_str): raise AddressValueError("Expected 4 octets in %r" % ip_str) try: - return int.from_bytes(map(self._parse_octet, octets), 'big') + return int.from_bytes(map(cls._parse_octet, octets), 'big') except ValueError as exc: raise AddressValueError("%s in %r" % (exc, ip_str)) from None - def _parse_octet(self, octet_str): + @classmethod + def _parse_octet(cls, octet_str): """Convert a decimal octet into an integer. Args: @@ -1082,7 +1139,7 @@ def _parse_octet(self, octet_str): if not octet_str: raise ValueError("Empty octet not permitted") # Whitelist the characters, since int() allows a lot of bizarre stuff. - if not self._DECIMAL_DIGITS.issuperset(octet_str): + if not cls._DECIMAL_DIGITS.issuperset(octet_str): msg = "Only decimal digits permitted in %r" raise ValueError(msg % octet_str) # We do the length check second, since the invalid character error @@ -1102,7 +1159,8 @@ def _parse_octet(self, octet_str): raise ValueError("Octet %d (> 255) not permitted" % octet_int) return octet_int - def _string_from_ip_int(self, ip_int): + @classmethod + def _string_from_ip_int(cls, ip_int): """Turns a 32-bit integer into dotted decimal notation. Args: @@ -1166,6 +1224,15 @@ def _is_hostmask(self, ip_str): return True return False + def _reverse_pointer(self): + """Return the reverse DNS pointer name for the IPv4 address. + + This implements the method described in RFC1035 3.5. + + """ + reverse_octets = str(self).split('.')[::-1] + return '.'.join(reverse_octets) + '.in-addr.arpa' + @property def max_prefixlen(self): return self._max_prefixlen @@ -1179,6 +1246,8 @@ class IPv4Address(_BaseV4, _BaseAddress): """Represent and manipulate single IPv4 Addresses.""" + __slots__ = ('_ip', '__weakref__') + def __init__(self, address): """ @@ -1195,9 +1264,6 @@ def __init__(self, address): AddressValueError: If ipaddress isn't a valid IPv4 address. """ - _BaseAddress.__init__(self, address) - _BaseV4.__init__(self, address) - # Efficient constructor from integer. if isinstance(address, int): self._check_int_address(address) @@ -1213,6 +1279,8 @@ def __init__(self, address): # Assume input argument to be string or any object representation # which converts into a formatted IP string. addr_str = str(address) + if '/' in addr_str: + raise AddressValueError("Unexpected '/' in %r" % address) self._ip = self._ip_int_from_string(addr_str) @property @@ -1229,8 +1297,7 @@ def is_reserved(self): reserved IPv4 Network range. """ - reserved_network = IPv4Network('240.0.0.0/4') - return self in reserved_network + return self in self._constants._reserved_network @property @functools.lru_cache() @@ -1242,21 +1309,7 @@ def is_private(self): iana-ipv4-special-registry. """ - return (self in IPv4Network('0.0.0.0/8') or - self in IPv4Network('10.0.0.0/8') or - self in IPv4Network('127.0.0.0/8') or - self in IPv4Network('169.254.0.0/16') or - self in IPv4Network('172.16.0.0/12') or - self in IPv4Network('192.0.0.0/29') or - self in IPv4Network('192.0.0.170/31') or - self in IPv4Network('192.0.2.0/24') or - self in IPv4Network('192.168.0.0/16') or - self in IPv4Network('198.18.0.0/15') or - self in IPv4Network('198.51.100.0/24') or - self in IPv4Network('203.0.113.0/24') or - self in IPv4Network('240.0.0.0/4') or - self in IPv4Network('255.255.255.255/32')) - + return any(self in net for net in self._constants._private_networks) @property def is_multicast(self): @@ -1267,8 +1320,7 @@ def is_multicast(self): See RFC 3171 for details. """ - multicast_network = IPv4Network('224.0.0.0/4') - return self in multicast_network + return self in self._constants._multicast_network @property def is_unspecified(self): @@ -1279,8 +1331,7 @@ def is_unspecified(self): RFC 5735 3. """ - unspecified_address = IPv4Address('0.0.0.0') - return self == unspecified_address + return self == self._constants._unspecified_address @property def is_loopback(self): @@ -1290,8 +1341,7 @@ def is_loopback(self): A boolean, True if the address is a loopback per RFC 3330. """ - loopback_network = IPv4Network('127.0.0.0/8') - return self in loopback_network + return self in self._constants._loopback_network @property def is_link_local(self): @@ -1301,8 +1351,7 @@ def is_link_local(self): A boolean, True if the address is link-local per RFC 3927. """ - linklocal_network = IPv4Network('169.254.0.0/16') - return self in linklocal_network + return self in self._constants._linklocal_network class IPv4Interface(IPv4Address): @@ -1314,6 +1363,18 @@ def __init__(self, address): self._prefixlen = self._max_prefixlen return + if isinstance(address, tuple): + IPv4Address.__init__(self, address[0]) + if len(address) > 1: + self._prefixlen = int(address[1]) + else: + self._prefixlen = self._max_prefixlen + + self.network = IPv4Network(address, strict=False) + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + return + addr = _split_optional_netmask(address) IPv4Address.__init__(self, addr[0]) @@ -1353,6 +1414,8 @@ def __lt__(self, other): def __hash__(self): return self._ip ^ self._prefixlen ^ int(self.network.network_address) + __reduce__ = _IPAddressBase.__reduce__ + @property def ip(self): return IPv4Address(self._ip) @@ -1425,24 +1488,30 @@ def __init__(self, address, strict=True): supplied. """ - - _BaseV4.__init__(self, address) _BaseNetwork.__init__(self, address) - # Constructing from a packed address - if isinstance(address, bytes): + # Constructing from a packed address or integer + if isinstance(address, (int, bytes)): self.network_address = IPv4Address(address) - self._prefixlen = self._max_prefixlen - self.netmask = IPv4Address(self._ALL_ONES) - #fixme: address/network test here + self.netmask, self._prefixlen = self._make_netmask(self._max_prefixlen) + #fixme: address/network test here. return - # Efficient constructor from integer. - if isinstance(address, int): - self.network_address = IPv4Address(address) - self._prefixlen = self._max_prefixlen - self.netmask = IPv4Address(self._ALL_ONES) - #fixme: address/network test here. + if isinstance(address, tuple): + if len(address) > 1: + arg = address[1] + else: + # We weren't given an address[1] + arg = self._max_prefixlen + self.network_address = IPv4Address(address[0]) + self.netmask, self._prefixlen = self._make_netmask(arg) + packed = int(self.network_address) + if packed & int(self.netmask) != packed: + if strict: + raise ValueError('%s has host bits set' % self) + else: + self.network_address = IPv4Address(packed & + int(self.netmask)) return # Assume input argument to be string or any object representation @@ -1451,33 +1520,10 @@ def __init__(self, address, strict=True): self.network_address = IPv4Address(self._ip_int_from_string(addr[0])) if len(addr) == 2: - mask = addr[1].split('.') - - if len(mask) == 4: - # We have dotted decimal netmask. - if self._is_valid_netmask(addr[1]): - self.netmask = IPv4Address(self._ip_int_from_string( - addr[1])) - elif self._is_hostmask(addr[1]): - self.netmask = IPv4Address( - self._ip_int_from_string(addr[1]) ^ self._ALL_ONES) - else: - raise NetmaskValueError('%r is not a valid netmask' - % addr[1]) - - self._prefixlen = self._prefix_from_ip_int(int(self.netmask)) - else: - # We have a netmask in prefix length form. - if not self._is_valid_netmask(addr[1]): - raise NetmaskValueError('%r is not a valid netmask' - % addr[1]) - self._prefixlen = int(addr[1]) - self.netmask = IPv4Address(self._ip_int_from_prefix( - self._prefixlen)) + arg = addr[1] else: - self._prefixlen = self._max_prefixlen - self.netmask = IPv4Address(self._ip_int_from_prefix( - self._prefixlen)) + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) if strict: if (IPv4Address(int(self.network_address) & int(self.netmask)) != @@ -1504,6 +1550,37 @@ def is_global(self): not self.is_private) +class _IPv4Constants: + _linklocal_network = IPv4Network('169.254.0.0/16') + + _loopback_network = IPv4Network('127.0.0.0/8') + + _multicast_network = IPv4Network('224.0.0.0/4') + + _private_networks = [ + IPv4Network('0.0.0.0/8'), + IPv4Network('10.0.0.0/8'), + IPv4Network('127.0.0.0/8'), + IPv4Network('169.254.0.0/16'), + IPv4Network('172.16.0.0/12'), + IPv4Network('192.0.0.0/29'), + IPv4Network('192.0.0.170/31'), + IPv4Network('192.0.2.0/24'), + IPv4Network('192.168.0.0/16'), + IPv4Network('198.18.0.0/15'), + IPv4Network('198.51.100.0/24'), + IPv4Network('203.0.113.0/24'), + IPv4Network('240.0.0.0/4'), + IPv4Network('255.255.255.255/32'), + ] + + _reserved_network = IPv4Network('240.0.0.0/4') + + _unspecified_address = IPv4Address('0.0.0.0') + + +IPv4Address._constants = _IPv4Constants + class _BaseV6: @@ -1514,15 +1591,37 @@ class _BaseV6: """ + __slots__ = () + _version = 6 _ALL_ONES = (2**IPV6LENGTH) - 1 _HEXTET_COUNT = 8 _HEX_DIGITS = frozenset('0123456789ABCDEFabcdef') + _max_prefixlen = IPV6LENGTH - def __init__(self, address): - self._version = 6 - self._max_prefixlen = IPV6LENGTH + # There are only a bunch of valid v6 netmasks, so we cache them all + # when constructed (see _make_netmask()). + _netmask_cache = {} + + @classmethod + def _make_netmask(cls, arg): + """Make a (netmask, prefix_len) tuple from the given argument. + + Argument can be: + - an integer (the prefix length) + - a string representing the prefix length (e.g. "24") + - a string representing the prefix netmask (e.g. "255.255.255.0") + """ + if arg not in cls._netmask_cache: + if isinstance(arg, int): + prefixlen = arg + else: + prefixlen = cls._prefix_from_prefix_string(arg) + netmask = IPv6Address(cls._ip_int_from_prefix(prefixlen)) + cls._netmask_cache[arg] = netmask, prefixlen + return cls._netmask_cache[arg] - def _ip_int_from_string(self, ip_str): + @classmethod + def _ip_int_from_string(cls, ip_str): """Turn an IPv6 ip_str into an integer. Args: @@ -1558,7 +1657,7 @@ def _ip_int_from_string(self, ip_str): # An IPv6 address can't have more than 8 colons (9 parts). # The extra colon comes from using the "::" notation for a single # leading or trailing zero part. - _max_parts = self._HEXTET_COUNT + 1 + _max_parts = cls._HEXTET_COUNT + 1 if len(parts) > _max_parts: msg = "At most %d colons permitted in %r" % (_max_parts-1, ip_str) raise AddressValueError(msg) @@ -1590,17 +1689,17 @@ def _ip_int_from_string(self, ip_str): if parts_lo: msg = "Trailing ':' only permitted as part of '::' in %r" raise AddressValueError(msg % ip_str) # :$ requires ::$ - parts_skipped = self._HEXTET_COUNT - (parts_hi + parts_lo) + parts_skipped = cls._HEXTET_COUNT - (parts_hi + parts_lo) if parts_skipped < 1: msg = "Expected at most %d other parts with '::' in %r" - raise AddressValueError(msg % (self._HEXTET_COUNT-1, ip_str)) + raise AddressValueError(msg % (cls._HEXTET_COUNT-1, ip_str)) else: # Otherwise, allocate the entire address to parts_hi. The # endpoints could still be empty, but _parse_hextet() will check # for that. - if len(parts) != self._HEXTET_COUNT: + if len(parts) != cls._HEXTET_COUNT: msg = "Exactly %d parts expected without '::' in %r" - raise AddressValueError(msg % (self._HEXTET_COUNT, ip_str)) + raise AddressValueError(msg % (cls._HEXTET_COUNT, ip_str)) if not parts[0]: msg = "Leading ':' only permitted as part of '::' in %r" raise AddressValueError(msg % ip_str) # ^: requires ^:: @@ -1616,16 +1715,17 @@ def _ip_int_from_string(self, ip_str): ip_int = 0 for i in range(parts_hi): ip_int <<= 16 - ip_int |= self._parse_hextet(parts[i]) + ip_int |= cls._parse_hextet(parts[i]) ip_int <<= 16 * parts_skipped for i in range(-parts_lo, 0): ip_int <<= 16 - ip_int |= self._parse_hextet(parts[i]) + ip_int |= cls._parse_hextet(parts[i]) return ip_int except ValueError as exc: raise AddressValueError("%s in %r" % (exc, ip_str)) from None - def _parse_hextet(self, hextet_str): + @classmethod + def _parse_hextet(cls, hextet_str): """Convert an IPv6 hextet string into an integer. Args: @@ -1640,7 +1740,7 @@ def _parse_hextet(self, hextet_str): """ # Whitelist the characters, since int() allows a lot of bizarre stuff. - if not self._HEX_DIGITS.issuperset(hextet_str): + if not cls._HEX_DIGITS.issuperset(hextet_str): raise ValueError("Only hex digits permitted in %r" % hextet_str) # We do the length check second, since the invalid character error # is likely to be more informative for the user @@ -1650,7 +1750,8 @@ def _parse_hextet(self, hextet_str): # Length check means we can skip checking the integer value return int(hextet_str, 16) - def _compress_hextets(self, hextets): + @classmethod + def _compress_hextets(cls, hextets): """Compresses a list of hextets. Compresses a list of strings, replacing the longest continuous @@ -1697,7 +1798,8 @@ def _compress_hextets(self, hextets): return hextets - def _string_from_ip_int(self, ip_int=None): + @classmethod + def _string_from_ip_int(cls, ip_int=None): """Turns a 128-bit integer into hexadecimal notation. Args: @@ -1711,15 +1813,15 @@ def _string_from_ip_int(self, ip_int=None): """ if ip_int is None: - ip_int = int(self._ip) + ip_int = int(cls._ip) - if ip_int > self._ALL_ONES: + if ip_int > cls._ALL_ONES: raise ValueError('IPv6 address is too large') hex_str = '%032x' % ip_int hextets = ['%x' % int(hex_str[x:x+4], 16) for x in range(0, 32, 4)] - hextets = self._compress_hextets(hextets) + hextets = cls._compress_hextets(hextets) return ':'.join(hextets) def _explode_shorthand_ip_string(self): @@ -1746,6 +1848,15 @@ def _explode_shorthand_ip_string(self): return '%s/%d' % (':'.join(parts), self._prefixlen) return ':'.join(parts) + def _reverse_pointer(self): + """Return the reverse DNS pointer name for the IPv6 address. + + This implements the method described in RFC3596 2.5. + + """ + reverse_chars = self.exploded[::-1].replace(':', '') + return '.'.join(reverse_chars) + '.ip6.arpa' + @property def max_prefixlen(self): return self._max_prefixlen @@ -1759,6 +1870,8 @@ class IPv6Address(_BaseV6, _BaseAddress): """Represent and manipulate single IPv6 Addresses.""" + __slots__ = ('_ip', '__weakref__') + def __init__(self, address): """Instantiate a new IPv6 address object. @@ -1776,9 +1889,6 @@ def __init__(self, address): AddressValueError: If address isn't a valid IPv6 address. """ - _BaseAddress.__init__(self, address) - _BaseV6.__init__(self, address) - # Efficient constructor from integer. if isinstance(address, int): self._check_int_address(address) @@ -1794,6 +1904,8 @@ def __init__(self, address): # Assume input argument to be string or any object representation # which converts into a formatted IP string. addr_str = str(address) + if '/' in addr_str: + raise AddressValueError("Unexpected '/' in %r" % address) self._ip = self._ip_int_from_string(addr_str) @property @@ -1810,8 +1922,7 @@ def is_multicast(self): See RFC 2373 2.7 for details. """ - multicast_network = IPv6Network('ff00::/8') - return self in multicast_network + return self in self._constants._multicast_network @property def is_reserved(self): @@ -1822,16 +1933,7 @@ def is_reserved(self): reserved IPv6 Network ranges. """ - reserved_networks = [IPv6Network('::/8'), IPv6Network('100::/8'), - IPv6Network('200::/7'), IPv6Network('400::/6'), - IPv6Network('800::/5'), IPv6Network('1000::/4'), - IPv6Network('4000::/3'), IPv6Network('6000::/3'), - IPv6Network('8000::/3'), IPv6Network('A000::/3'), - IPv6Network('C000::/3'), IPv6Network('E000::/4'), - IPv6Network('F000::/5'), IPv6Network('F800::/6'), - IPv6Network('FE00::/9')] - - return any(self in x for x in reserved_networks) + return any(self in x for x in self._constants._reserved_networks) @property def is_link_local(self): @@ -1841,8 +1943,7 @@ def is_link_local(self): A boolean, True if the address is reserved per RFC 4291. """ - linklocal_network = IPv6Network('fe80::/10') - return self in linklocal_network + return self in self._constants._linklocal_network @property def is_site_local(self): @@ -1856,8 +1957,7 @@ def is_site_local(self): A boolean, True if the address is reserved per RFC 3513 2.5.6. """ - sitelocal_network = IPv6Network('fec0::/10') - return self in sitelocal_network + return self in self._constants._sitelocal_network @property @functools.lru_cache() @@ -1869,16 +1969,7 @@ def is_private(self): iana-ipv6-special-registry. """ - return (self in IPv6Network('::1/128') or - self in IPv6Network('::/128') or - self in IPv6Network('::ffff:0:0/96') or - self in IPv6Network('100::/64') or - self in IPv6Network('2001::/23') or - self in IPv6Network('2001:2::/48') or - self in IPv6Network('2001:db8::/32') or - self in IPv6Network('2001:10::/28') or - self in IPv6Network('fc00::/7') or - self in IPv6Network('fe80::/10')) + return any(self in net for net in self._constants._private_networks) @property def is_global(self): @@ -1963,6 +2054,16 @@ def __init__(self, address): self.network = IPv6Network(self._ip) self._prefixlen = self._max_prefixlen return + if isinstance(address, tuple): + IPv6Address.__init__(self, address[0]) + if len(address) > 1: + self._prefixlen = int(address[1]) + else: + self._prefixlen = self._max_prefixlen + self.network = IPv6Network(address, strict=False) + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + return addr = _split_optional_netmask(address) IPv6Address.__init__(self, addr[0]) @@ -2001,6 +2102,8 @@ def __lt__(self, other): def __hash__(self): return self._ip ^ self._prefixlen ^ int(self.network.network_address) + __reduce__ = _IPAddressBase.__reduce__ + @property def ip(self): return IPv6Address(self._ip) @@ -2077,21 +2180,28 @@ def __init__(self, address, strict=True): supplied. """ - _BaseV6.__init__(self, address) _BaseNetwork.__init__(self, address) - # Efficient constructor from integer. - if isinstance(address, int): + # Efficient constructor from integer or packed address + if isinstance(address, (bytes, int)): self.network_address = IPv6Address(address) - self._prefixlen = self._max_prefixlen - self.netmask = IPv6Address(self._ALL_ONES) + self.netmask, self._prefixlen = self._make_netmask(self._max_prefixlen) return - # Constructing from a packed address - if isinstance(address, bytes): - self.network_address = IPv6Address(address) - self._prefixlen = self._max_prefixlen - self.netmask = IPv6Address(self._ALL_ONES) + if isinstance(address, tuple): + if len(address) > 1: + arg = address[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + self.network_address = IPv6Address(address[0]) + packed = int(self.network_address) + if packed & int(self.netmask) != packed: + if strict: + raise ValueError('%s has host bits set' % self) + else: + self.network_address = IPv6Address(packed & + int(self.netmask)) return # Assume input argument to be string or any object representation @@ -2101,15 +2211,11 @@ def __init__(self, address, strict=True): self.network_address = IPv6Address(self._ip_int_from_string(addr[0])) if len(addr) == 2: - if self._is_valid_netmask(addr[1]): - self._prefixlen = int(addr[1]) - else: - raise NetmaskValueError('%r is not a valid netmask' - % addr[1]) + arg = addr[1] else: - self._prefixlen = self._max_prefixlen + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) - self.netmask = IPv6Address(self._ip_int_from_prefix(self._prefixlen)) if strict: if (IPv6Address(int(self.network_address) & int(self.netmask)) != self.network_address): @@ -2120,22 +2226,17 @@ def __init__(self, address, strict=True): if self._prefixlen == (self._max_prefixlen - 1): self.hosts = self.__iter__ - def _is_valid_netmask(self, prefixlen): - """Verify that the netmask/prefixlen is valid. - - Args: - prefixlen: A string, the netmask in prefix length format. + def hosts(self): + """Generate Iterator over usable hosts in a network. - Returns: - A boolean, True if the prefix represents a valid IPv6 - netmask. + This is like __iter__ except it doesn't return the + Subnet-Router anycast address. """ - try: - prefixlen = int(prefixlen) - except ValueError: - return False - return 0 <= prefixlen <= self._max_prefixlen + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in range(network + 1, broadcast + 1): + yield self._address_class(x) @property def is_site_local(self): @@ -2151,3 +2252,39 @@ def is_site_local(self): """ return (self.network_address.is_site_local and self.broadcast_address.is_site_local) + + +class _IPv6Constants: + + _linklocal_network = IPv6Network('fe80::/10') + + _multicast_network = IPv6Network('ff00::/8') + + _private_networks = [ + IPv6Network('::1/128'), + IPv6Network('::/128'), + IPv6Network('::ffff:0:0/96'), + IPv6Network('100::/64'), + IPv6Network('2001::/23'), + IPv6Network('2001:2::/48'), + IPv6Network('2001:db8::/32'), + IPv6Network('2001:10::/28'), + IPv6Network('fc00::/7'), + IPv6Network('fe80::/10'), + ] + + _reserved_networks = [ + IPv6Network('::/8'), IPv6Network('100::/8'), + IPv6Network('200::/7'), IPv6Network('400::/6'), + IPv6Network('800::/5'), IPv6Network('1000::/4'), + IPv6Network('4000::/3'), IPv6Network('6000::/3'), + IPv6Network('8000::/3'), IPv6Network('A000::/3'), + IPv6Network('C000::/3'), IPv6Network('E000::/4'), + IPv6Network('F000::/5'), IPv6Network('F800::/6'), + IPv6Network('FE00::/9'), + ] + + _sitelocal_network = IPv6Network('fec0::/10') + + +IPv6Address._constants = _IPv6Constants diff --git a/Lib/json/__init__.py b/Lib/json/__init__.py index a459f77a7b4d..2612657fafbc 100644 --- a/Lib/json/__init__.py +++ b/Lib/json/__init__.py @@ -3,11 +3,8 @@ interchange format. :mod:`json` exposes an API familiar to users of the standard library -:mod:`marshal` and :mod:`pickle` modules. It is the externally maintained -version of the :mod:`json` library contained in Python 2.6, but maintains -compatibility with Python 2.4 and Python 2.5 and (currently) has -significant performance advantages, even without using the optional C -extension for speedups. +:mod:`marshal` and :mod:`pickle` modules. It is derived from a +version of the externally maintained simplejson library. Encoding basic Python object hierarchies:: @@ -101,12 +98,12 @@ __version__ = '2.0.9' __all__ = [ 'dump', 'dumps', 'load', 'loads', - 'JSONDecoder', 'JSONEncoder', + 'JSONDecoder', 'JSONDecodeError', 'JSONEncoder', ] __author__ = 'Bob Ippolito ' -from .decoder import JSONDecoder +from .decoder import JSONDecoder, JSONDecodeError from .encoder import JSONEncoder _default_encoder = JSONEncoder( @@ -187,7 +184,7 @@ def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, default=None, sort_keys=False, **kw): """Serialize ``obj`` to a JSON formatted ``str``. - If ``skipkeys`` is false then ``dict`` keys that are not basic types + If ``skipkeys`` is true then ``dict`` keys that are not basic types (``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped instead of raising a ``TypeError``. @@ -314,7 +311,8 @@ def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, raise TypeError('the JSON object must be str, not {!r}'.format( s.__class__.__name__)) if s.startswith(u'\ufeff'): - raise ValueError("Unexpected UTF-8 BOM (decode using utf-8-sig)") + raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)", + s, 0) if (cls is None and object_hook is None and parse_int is None and parse_float is None and parse_constant is None and object_pairs_hook is None and not kw): diff --git a/Lib/json/decoder.py b/Lib/json/decoder.py index 59e5f41f4dc1..0f03f20042b8 100644 --- a/Lib/json/decoder.py +++ b/Lib/json/decoder.py @@ -8,7 +8,7 @@ except ImportError: c_scanstring = None -__all__ = ['JSONDecoder'] +__all__ = ['JSONDecoder', 'JSONDecodeError'] FLAGS = re.VERBOSE | re.MULTILINE | re.DOTALL @@ -17,32 +17,30 @@ NegInf = float('-inf') -def linecol(doc, pos): - if isinstance(doc, bytes): - newline = b'\n' - else: - newline = '\n' - lineno = doc.count(newline, 0, pos) + 1 - if lineno == 1: - colno = pos + 1 - else: - colno = pos - doc.rindex(newline, 0, pos) - return lineno, colno - - -def errmsg(msg, doc, pos, end=None): - # Note that this function is called from _json - lineno, colno = linecol(doc, pos) - if end is None: - fmt = '{0}: line {1} column {2} (char {3})' - return fmt.format(msg, lineno, colno, pos) - #fmt = '%s: line %d column %d (char %d)' - #return fmt % (msg, lineno, colno, pos) - endlineno, endcolno = linecol(doc, end) - fmt = '{0}: line {1} column {2} - line {3} column {4} (char {5} - {6})' - return fmt.format(msg, lineno, colno, endlineno, endcolno, pos, end) - #fmt = '%s: line %d column %d - line %d column %d (char %d - %d)' - #return fmt % (msg, lineno, colno, endlineno, endcolno, pos, end) +class JSONDecodeError(ValueError): + """Subclass of ValueError with the following additional properties: + + msg: The unformatted error message + doc: The JSON document being parsed + pos: The start index of doc where parsing failed + lineno: The line corresponding to pos + colno: The column corresponding to pos + + """ + # Note that this exception is used from _json + def __init__(self, msg, doc, pos): + lineno = doc.count('\n', 0, pos) + 1 + colno = pos - doc.rfind('\n', 0, pos) + errmsg = '%s: line %d column %d (char %d)' % (msg, lineno, colno, pos) + ValueError.__init__(self, errmsg) + self.msg = msg + self.doc = doc + self.pos = pos + self.lineno = lineno + self.colno = colno + + def __reduce__(self): + return self.__class__, (self.msg, self.doc, self.pos) _CONSTANTS = { @@ -66,7 +64,7 @@ def _decode_uXXXX(s, pos): except ValueError: pass msg = "Invalid \\uXXXX escape" - raise ValueError(errmsg(msg, s, pos)) + raise JSONDecodeError(msg, s, pos) def py_scanstring(s, end, strict=True, _b=BACKSLASH, _m=STRINGCHUNK.match): @@ -84,8 +82,7 @@ def py_scanstring(s, end, strict=True, while 1: chunk = _m(s, end) if chunk is None: - raise ValueError( - errmsg("Unterminated string starting at", s, begin)) + raise JSONDecodeError("Unterminated string starting at", s, begin) end = chunk.end() content, terminator = chunk.groups() # Content is contains zero or more unescaped string characters @@ -99,22 +96,21 @@ def py_scanstring(s, end, strict=True, if strict: #msg = "Invalid control character %r at" % (terminator,) msg = "Invalid control character {0!r} at".format(terminator) - raise ValueError(errmsg(msg, s, end)) + raise JSONDecodeError(msg, s, end) else: _append(terminator) continue try: esc = s[end] except IndexError: - raise ValueError( - errmsg("Unterminated string starting at", s, begin)) + raise JSONDecodeError("Unterminated string starting at", s, begin) # If not a unicode escape sequence, must be in the lookup table if esc != 'u': try: char = _b[esc] except KeyError: msg = "Invalid \\escape: {0!r}".format(esc) - raise ValueError(errmsg(msg, s, end)) + raise JSONDecodeError(msg, s, end) end += 1 else: uni = _decode_uXXXX(s, end) @@ -163,8 +159,8 @@ def JSONObject(s_and_end, strict, scan_once, object_hook, object_pairs_hook, pairs = object_hook(pairs) return pairs, end + 1 elif nextchar != '"': - raise ValueError(errmsg( - "Expecting property name enclosed in double quotes", s, end)) + raise JSONDecodeError( + "Expecting property name enclosed in double quotes", s, end) end += 1 while True: key, end = scanstring(s, end, strict) @@ -174,7 +170,7 @@ def JSONObject(s_and_end, strict, scan_once, object_hook, object_pairs_hook, if s[end:end + 1] != ':': end = _w(s, end).end() if s[end:end + 1] != ':': - raise ValueError(errmsg("Expecting ':' delimiter", s, end)) + raise JSONDecodeError("Expecting ':' delimiter", s, end) end += 1 try: @@ -188,7 +184,7 @@ def JSONObject(s_and_end, strict, scan_once, object_hook, object_pairs_hook, try: value, end = scan_once(s, end) except StopIteration as err: - raise ValueError(errmsg("Expecting value", s, err.value)) from None + raise JSONDecodeError("Expecting value", s, err.value) from None pairs_append((key, value)) try: nextchar = s[end] @@ -202,13 +198,13 @@ def JSONObject(s_and_end, strict, scan_once, object_hook, object_pairs_hook, if nextchar == '}': break elif nextchar != ',': - raise ValueError(errmsg("Expecting ',' delimiter", s, end - 1)) + raise JSONDecodeError("Expecting ',' delimiter", s, end - 1) end = _w(s, end).end() nextchar = s[end:end + 1] end += 1 if nextchar != '"': - raise ValueError(errmsg( - "Expecting property name enclosed in double quotes", s, end - 1)) + raise JSONDecodeError( + "Expecting property name enclosed in double quotes", s, end - 1) if object_pairs_hook is not None: result = object_pairs_hook(pairs) return result, end @@ -232,7 +228,7 @@ def JSONArray(s_and_end, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR): try: value, end = scan_once(s, end) except StopIteration as err: - raise ValueError(errmsg("Expecting value", s, err.value)) from None + raise JSONDecodeError("Expecting value", s, err.value) from None _append(value) nextchar = s[end:end + 1] if nextchar in _ws: @@ -242,7 +238,7 @@ def JSONArray(s_and_end, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR): if nextchar == ']': break elif nextchar != ',': - raise ValueError(errmsg("Expecting ',' delimiter", s, end - 1)) + raise JSONDecodeError("Expecting ',' delimiter", s, end - 1) try: if s[end] in _ws: end += 1 @@ -343,7 +339,7 @@ def decode(self, s, _w=WHITESPACE.match): obj, end = self.raw_decode(s, idx=_w(s, 0).end()) end = _w(s, end).end() if end != len(s): - raise ValueError(errmsg("Extra data", s, end, len(s))) + raise JSONDecodeError("Extra data", s, end) return obj def raw_decode(self, s, idx=0): @@ -358,5 +354,5 @@ def raw_decode(self, s, idx=0): try: obj, end = self.scan_once(s, idx) except StopIteration as err: - raise ValueError(errmsg("Expecting value", s, err.value)) from None + raise JSONDecodeError("Expecting value", s, err.value) from None return obj, end diff --git a/Lib/json/encoder.py b/Lib/json/encoder.py index 05138383bccf..26e9eb2bc692 100644 --- a/Lib/json/encoder.py +++ b/Lib/json/encoder.py @@ -6,6 +6,10 @@ from _json import encode_basestring_ascii as c_encode_basestring_ascii except ImportError: c_encode_basestring_ascii = None +try: + from _json import encode_basestring as c_encode_basestring +except ImportError: + c_encode_basestring = None try: from _json import make_encoder as c_make_encoder except ImportError: @@ -30,7 +34,7 @@ INFINITY = float('inf') FLOAT_REPR = repr -def encode_basestring(s): +def py_encode_basestring(s): """Return a JSON representation of a Python string """ @@ -39,6 +43,9 @@ def replace(match): return '"' + ESCAPE.sub(replace, s) + '"' +encode_basestring = (c_encode_basestring or py_encode_basestring) + + def py_encode_basestring_ascii(s): """Return an ASCII-only JSON representation of a Python string diff --git a/Lib/json/tool.py b/Lib/json/tool.py index 7db45285713b..4f3182c0c1e7 100644 --- a/Lib/json/tool.py +++ b/Lib/json/tool.py @@ -10,28 +10,39 @@ Expecting property name enclosed in double quotes: line 1 column 3 (char 2) """ -import sys +import argparse +import collections import json +import sys + def main(): - if len(sys.argv) == 1: - infile = sys.stdin - outfile = sys.stdout - elif len(sys.argv) == 2: - infile = open(sys.argv[1], 'r') - outfile = sys.stdout - elif len(sys.argv) == 3: - infile = open(sys.argv[1], 'r') - outfile = open(sys.argv[2], 'w') - else: - raise SystemExit(sys.argv[0] + " [infile [outfile]]") + prog = 'python -m json.tool' + description = ('A simple command line interface for json module ' + 'to validate and pretty-print JSON objects.') + parser = argparse.ArgumentParser(prog=prog, description=description) + parser.add_argument('infile', nargs='?', type=argparse.FileType(), + help='a JSON file to be validated or pretty-printed') + parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'), + help='write the output of infile to outfile') + parser.add_argument('--sort-keys', action='http://github.com/store_true', default=False, + help='sort the output of dictionaries alphabetically by key') + options = parser.parse_args() + + infile = options.infile or sys.stdin + outfile = options.outfile or sys.stdout + sort_keys = options.sort_keys with infile: try: - obj = json.load(infile) + if sort_keys: + obj = json.load(infile) + else: + obj = json.load(infile, + object_pairs_hook=collections.OrderedDict) except ValueError as e: raise SystemExit(e) with outfile: - json.dump(obj, outfile, sort_keys=True, indent=4) + json.dump(obj, outfile, sort_keys=sort_keys, indent=4) outfile.write('\n') diff --git a/Lib/lib2to3/Grammar.txt b/Lib/lib2to3/Grammar.txt index 1e1f24cfbc76..c954669e8a72 100644 --- a/Lib/lib2to3/Grammar.txt +++ b/Lib/lib2to3/Grammar.txt @@ -33,7 +33,8 @@ eval_input: testlist NEWLINE* ENDMARKER decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE decorators: decorator+ -decorated: decorators (classdef | funcdef) +decorated: decorators (classdef | funcdef | async_funcdef) +async_funcdef: ASYNC funcdef funcdef: 'def' NAME parameters ['->' test] ':' suite parameters: '(' [typedargslist] ')' typedargslist: ((tfpdef ['=' test] ',')* @@ -56,7 +57,7 @@ small_stmt: (expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) | ('=' (yield_expr|testlist_star_expr))*) testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [','] -augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | +augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=') # For normal assignments, additional restrictions enforced by the interpreter print_stmt: 'print' ( [ test (',' test)* [','] ] | @@ -82,7 +83,8 @@ global_stmt: ('global' | 'nonlocal') NAME (',' NAME)* exec_stmt: 'exec' expr ['in' test [',' test]] assert_stmt: 'assert' test [',' test] -compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated +compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated | async_stmt +async_stmt: ASYNC (funcdef | with_stmt | for_stmt) if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] while_stmt: 'while' test ':' suite ['else' ':' suite] for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] @@ -119,9 +121,9 @@ 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)* +term: factor (('*'|'@'|'/'|'%'|'//') factor)* factor: ('+'|'-'|'~') factor | power -power: atom trailer* ['**' factor] +power: [AWAIT] atom trailer* ['**' factor] atom: ('(' [yield_expr|testlist_gexp] ')' | '[' [listmaker] ']' | '{' [dictsetmaker] '}' | @@ -142,7 +144,7 @@ dictsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) | classdef: 'class' NAME ['(' [arglist] ')'] ':' suite arglist: (argument ',')* (argument [','] - |'*' test (',' argument)* [',' '**' test] + |'*' test (',' argument)* [',' '**' test] |'**' test) argument: test [comp_for] | test '=' test # Really [keyword '='] test @@ -155,4 +157,5 @@ testlist1: test (',' test)* # not used in grammar, but may appear in "node" passed from Parser to Compiler encoding_decl: NAME -yield_expr: 'yield' [testlist] +yield_expr: 'yield' [yield_arg] +yield_arg: 'from' test | testlist diff --git a/Lib/lib2to3/fixer_util.py b/Lib/lib2to3/fixer_util.py index 6e259c54ac47..44502bf7bdbd 100644 --- a/Lib/lib2to3/fixer_util.py +++ b/Lib/lib2to3/fixer_util.py @@ -187,8 +187,8 @@ def parenthesize(node): return Node(syms.atom, [LParen(), node, RParen()]) -consuming_calls = set(["sorted", "list", "set", "any", "all", "tuple", "sum", - "min", "max", "enumerate"]) +consuming_calls = {"sorted", "list", "set", "any", "all", "tuple", "sum", + "min", "max", "enumerate"} def attr_chain(obj, attr): """Follow an attribute chain. @@ -359,7 +359,7 @@ def is_import_stmt(node): root.insert_child(insert_pos, Node(syms.simple_stmt, children)) -_def_syms = set([syms.classdef, syms.funcdef]) +_def_syms = {syms.classdef, syms.funcdef} def find_binding(name, node, package=None): """ Returns the node which binds variable name, otherwise None. If optional argument package is supplied, only imports will @@ -402,7 +402,7 @@ def find_binding(name, node, package=None): return ret return None -_block_syms = set([syms.funcdef, syms.classdef, syms.trailer]) +_block_syms = {syms.funcdef, syms.classdef, syms.trailer} def _find(name, node): nodes = [node] while nodes: diff --git a/Lib/lib2to3/fixes/fix_dict.py b/Lib/lib2to3/fixes/fix_dict.py index 4cc37174cb7f..963f952e0b04 100644 --- a/Lib/lib2to3/fixes/fix_dict.py +++ b/Lib/lib2to3/fixes/fix_dict.py @@ -36,7 +36,7 @@ from .. import fixer_util -iter_exempt = fixer_util.consuming_calls | set(["iter"]) +iter_exempt = fixer_util.consuming_calls | {"iter"} class FixDict(fixer_base.BaseFix): diff --git a/Lib/lib2to3/fixes/fix_exitfunc.py b/Lib/lib2to3/fixes/fix_exitfunc.py index 9afc2fac18a3..2e47887afead 100644 --- a/Lib/lib2to3/fixes/fix_exitfunc.py +++ b/Lib/lib2to3/fixes/fix_exitfunc.py @@ -35,7 +35,7 @@ def start_tree(self, tree, filename): self.sys_import = None def transform(self, node, results): - # First, find a the sys import. We'll just hope it's global scope. + # First, find the sys import. We'll just hope it's global scope. if "sys_import" in results: if self.sys_import is None: self.sys_import = results["sys_import"] diff --git a/Lib/lib2to3/fixes/fix_import.py b/Lib/lib2to3/fixes/fix_import.py index e978fce43fcc..734ca294699c 100644 --- a/Lib/lib2to3/fixes/fix_import.py +++ b/Lib/lib2to3/fixes/fix_import.py @@ -32,7 +32,7 @@ def traverse_imports(names): elif node.type == syms.dotted_as_names: pending.extend(node.children[::-2]) else: - raise AssertionError("unkown node type") + raise AssertionError("unknown node type") class FixImport(fixer_base.BaseFix): diff --git a/Lib/lib2to3/fixes/fix_types.py b/Lib/lib2to3/fixes/fix_types.py index db341047855f..00327a78e8eb 100644 --- a/Lib/lib2to3/fixes/fix_types.py +++ b/Lib/lib2to3/fixes/fix_types.py @@ -42,7 +42,7 @@ 'NotImplementedType' : 'type(NotImplemented)', 'SliceType' : 'slice', 'StringType': 'bytes', # XXX ? - 'StringTypes' : 'str', # XXX ? + 'StringTypes' : '(str,)', # XXX ? 'TupleType': 'tuple', 'TypeType' : 'type', 'UnicodeType': 'str', diff --git a/Lib/lib2to3/main.py b/Lib/lib2to3/main.py index 93bae9021a49..1a1df013ade3 100644 --- a/Lib/lib2to3/main.py +++ b/Lib/lib2to3/main.py @@ -2,7 +2,7 @@ Main program for 2to3. """ -from __future__ import with_statement +from __future__ import with_statement, print_function import sys import os diff --git a/Lib/lib2to3/patcomp.py b/Lib/lib2to3/patcomp.py index 0a259e90afd8..2012ec4855f1 100644 --- a/Lib/lib2to3/patcomp.py +++ b/Lib/lib2to3/patcomp.py @@ -32,7 +32,7 @@ class PatternSyntaxError(Exception): def tokenize_wrapper(input): """Tokenizes a string suppressing significant whitespace.""" - skip = set((token.NEWLINE, token.INDENT, token.DEDENT)) + skip = {token.NEWLINE, token.INDENT, token.DEDENT} tokens = tokenize.generate_tokens(io.StringIO(input).readline) for quintuple in tokens: type, value, start, end, line_text = quintuple diff --git a/Lib/lib2to3/pgen2/grammar.py b/Lib/lib2to3/pgen2/grammar.py index 7f1c5648e264..b4481d1891a2 100644 --- a/Lib/lib2to3/pgen2/grammar.py +++ b/Lib/lib2to3/pgen2/grammar.py @@ -149,6 +149,7 @@ def report(self): { LBRACE } RBRACE @ AT +@= ATEQUAL == EQEQUAL != NOTEQUAL <> NOTEQUAL diff --git a/Lib/lib2to3/pgen2/token.py b/Lib/lib2to3/pgen2/token.py index 6a6d0b6b6502..1a679554d2db 100755 --- a/Lib/lib2to3/pgen2/token.py +++ b/Lib/lib2to3/pgen2/token.py @@ -57,12 +57,15 @@ DOUBLESLASH = 48 DOUBLESLASHEQUAL = 49 AT = 50 -OP = 51 -COMMENT = 52 -NL = 53 -RARROW = 54 -ERRORTOKEN = 55 -N_TOKENS = 56 +ATEQUAL = 51 +OP = 52 +COMMENT = 53 +NL = 54 +RARROW = 55 +AWAIT = 56 +ASYNC = 57 +ERRORTOKEN = 58 +N_TOKENS = 59 NT_OFFSET = 256 #--end constants-- diff --git a/Lib/lib2to3/pgen2/tokenize.py b/Lib/lib2to3/pgen2/tokenize.py index b7c646129cd1..1ff1c61ee225 100644 --- a/Lib/lib2to3/pgen2/tokenize.py +++ b/Lib/lib2to3/pgen2/tokenize.py @@ -84,7 +84,7 @@ def maybe(*choices): return group(*choices) + '?' # recognized as two instances of =). Operator = group(r"\*\*=?", r">>=?", r"<<=?", r"<>", r"!=", r"//=?", r"->", - r"[+\-*/%&|^=<>]=?", + r"[+\-*/%&@|^=<>]=?", r"~") Bracket = '[][(){}]' @@ -220,7 +220,7 @@ def compat(self, token, iterable): for tok in iterable: toknum, tokval = tok[:2] - if toknum in (NAME, NUMBER): + if toknum in (NAME, NUMBER, ASYNC, AWAIT): tokval += ' ' if toknum == INDENT: @@ -237,6 +237,7 @@ def compat(self, token, iterable): toks_append(tokval) cookie_re = re.compile(r'^[ \t\f]*#.*coding[:=][ \t]*([-\w.]+)', re.ASCII) +blank_re = re.compile(br'^[ \t\f]*(?:[#\r\n]|$)', re.ASCII) def _get_normal_name(orig_enc): """Imitates get_normal_name in tokenizer.c.""" @@ -309,6 +310,8 @@ def find_cookie(line): encoding = find_cookie(first) if encoding: return encoding, [first] + if not blank_re.match(first): + return default, [first] second = read_or_stop() if not second: @@ -363,6 +366,12 @@ def generate_tokens(readline): contline = None indents = [0] + # 'stashed' and 'async_*' are used for async/await parsing + stashed = None + async_def = False + async_def_indent = 0 + async_def_nl = False + while 1: # loop over lines in stream try: line = readline() @@ -403,6 +412,10 @@ def generate_tokens(readline): pos = pos + 1 if pos == max: break + if stashed: + yield stashed + stashed = None + if line[pos] in '#\r\n': # skip comments or blank lines if line[pos] == '#': comment_token = line[pos:].rstrip('\r\n') @@ -425,8 +438,19 @@ def generate_tokens(readline): "unindent does not match any outer indentation level", ("", lnum, pos, line)) indents = indents[:-1] + + if async_def and async_def_indent >= indents[-1]: + async_def = False + async_def_nl = False + async_def_indent = 0 + yield (DEDENT, '', (lnum, pos), (lnum, pos), line) + if async_def and async_def_nl and async_def_indent >= indents[-1]: + async_def = False + async_def_nl = False + async_def_indent = 0 + else: # continued statement if not line: raise TokenError("EOF in multi-line statement", (lnum, 0)) @@ -446,9 +470,18 @@ def generate_tokens(readline): newline = NEWLINE if parenlev > 0: newline = NL + elif async_def: + async_def_nl = True + if stashed: + yield stashed + stashed = None yield (newline, token, spos, epos, line) + elif initial == '#': assert not token.endswith("\n") + if stashed: + yield stashed + stashed = None yield (COMMENT, token, spos, epos, line) elif token in triple_quoted: endprog = endprogs[token] @@ -456,6 +489,9 @@ def generate_tokens(readline): if endmatch: # all on one line pos = endmatch.end(0) token = line[start:pos] + if stashed: + yield stashed + stashed = None yield (STRING, token, spos, (lnum, pos), line) else: strstart = (lnum, start) # multiple lines @@ -473,22 +509,63 @@ def generate_tokens(readline): contline = line break else: # ordinary string + if stashed: + yield stashed + stashed = None yield (STRING, token, spos, epos, line) elif initial in namechars: # ordinary name - yield (NAME, token, spos, epos, line) + if token in ('async', 'await'): + if async_def: + yield (ASYNC if token == 'async' else AWAIT, + token, spos, epos, line) + continue + + tok = (NAME, token, spos, epos, line) + if token == 'async' and not stashed: + stashed = tok + continue + + if token == 'def': + if (stashed + and stashed[0] == NAME + and stashed[1] == 'async'): + + async_def = True + async_def_indent = indents[-1] + + yield (ASYNC, stashed[1], + stashed[2], stashed[3], + stashed[4]) + stashed = None + + if stashed: + yield stashed + stashed = None + + yield tok elif initial == '\\': # continued stmt # This yield is new; needed for better idempotency: + if stashed: + yield stashed + stashed = None yield (NL, token, spos, (lnum, pos), line) continued = 1 else: if initial in '([{': parenlev = parenlev + 1 elif initial in ')]}': parenlev = parenlev - 1 + if stashed: + yield stashed + stashed = None yield (OP, token, spos, epos, line) else: yield (ERRORTOKEN, line[pos], (lnum, pos), (lnum, pos+1), line) pos = pos + 1 + if stashed: + yield stashed + stashed = None + for indent in indents[1:]: # pop remaining indent levels yield (DEDENT, '', (lnum, 0), (lnum, 0), '') yield (ENDMARKER, '', (lnum, 0), (lnum, 0), '') diff --git a/Lib/lib2to3/pytree.py b/Lib/lib2to3/pytree.py index c4a1be3500b5..ad3592c05f7e 100644 --- a/Lib/lib2to3/pytree.py +++ b/Lib/lib2to3/pytree.py @@ -64,16 +64,6 @@ def __eq__(self, other): __hash__ = None # For Py3 compatibility. - def __ne__(self, other): - """ - Compare two nodes for inequality. - - This calls the method _eq(). - """ - if self.__class__ is not other.__class__: - return NotImplemented - return not self._eq(other) - def _eq(self, other): """ Compare two nodes for equality. diff --git a/Lib/lib2to3/refactor.py b/Lib/lib2to3/refactor.py index 810031787150..adf999684bea 100644 --- a/Lib/lib2to3/refactor.py +++ b/Lib/lib2to3/refactor.py @@ -57,7 +57,7 @@ def _get_head_types(pat): # Always return leafs if pat.type is None: raise _EveryNode - return set([pat.type]) + return {pat.type} if isinstance(pat, pytree.NegatedPattern): if pat.content: @@ -133,7 +133,7 @@ def _detect_future_features(source): def advance(): tok = next(gen) return tok[0], tok[1] - ignore = frozenset((token.NEWLINE, tokenize.NL, token.COMMENT)) + ignore = frozenset({token.NEWLINE, tokenize.NL, token.COMMENT}) features = set() try: while True: @@ -255,7 +255,7 @@ def get_fixers(self): fixer = fix_class(self.options, self.fixer_log) if fixer.explicit and self.explicit is not True and \ fix_mod_path not in self.explicit: - self.log_message("Skipping implicit fixer: %s", fix_name) + self.log_message("Skipping optional fixer: %s", fix_name) continue self.log_debug("Adding transformation: %s", fix_name) diff --git a/Lib/lib2to3/tests/__init__.py b/Lib/lib2to3/tests/__init__.py index cfaea0de747d..c5166fc94c47 100644 --- a/Lib/lib2to3/tests/__init__.py +++ b/Lib/lib2to3/tests/__init__.py @@ -1,24 +1,9 @@ -"""Make tests/ into a package. This allows us to "import tests" and -have tests.all_tests be a TestSuite representing all test cases -from all test_*.py files in tests/.""" # Author: Collin Winter import os -import os.path import unittest -import types -from . import support +from test.support import load_package_tests -all_tests = unittest.TestSuite() - -tests_dir = os.path.join(os.path.dirname(__file__), '..', 'tests') -tests = [t[0:-3] for t in os.listdir(tests_dir) - if t.startswith('test_') and t.endswith('.py')] - -loader = unittest.TestLoader() - -for t in tests: - __import__("",globals(),locals(),[t],level=1) - mod = globals()[t] - all_tests.addTests(loader.loadTestsFromModule(mod)) +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/lib2to3/tests/__main__.py b/Lib/lib2to3/tests/__main__.py new file mode 100644 index 000000000000..40a23a297ec2 --- /dev/null +++ b/Lib/lib2to3/tests/__main__.py @@ -0,0 +1,4 @@ +from . import load_tests +import unittest + +unittest.main() diff --git a/Lib/lib2to3/tests/data/false_encoding.py b/Lib/lib2to3/tests/data/false_encoding.py old mode 100644 new mode 100755 diff --git a/Lib/lib2to3/tests/pytree_idempotency.py b/Lib/lib2to3/tests/pytree_idempotency.py index 731c4031208f..c6359bf18a1b 100755 --- a/Lib/lib2to3/tests/pytree_idempotency.py +++ b/Lib/lib2to3/tests/pytree_idempotency.py @@ -4,6 +4,8 @@ """Main program for testing the infrastructure.""" +from __future__ import print_function + __author__ = "Guido van Rossum " # Support imports (need to be imported first) diff --git a/Lib/lib2to3/tests/test_all_fixers.py b/Lib/lib2to3/tests/test_all_fixers.py index f64b3d942af2..15079fe0285c 100644 --- a/Lib/lib2to3/tests/test_all_fixers.py +++ b/Lib/lib2to3/tests/test_all_fixers.py @@ -7,12 +7,14 @@ # Python imports import unittest +import test.support # Local imports from lib2to3 import refactor from . import support +@test.support.requires_resource('cpu') class Test_all(support.TestCase): def setUp(self): @@ -21,3 +23,6 @@ def setUp(self): def test_all_project_files(self): for filepath in support.all_project_files(): self.refactor.refactor_file(filepath) + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/lib2to3/tests/test_fixers.py b/Lib/lib2to3/tests/test_fixers.py index 06b0033b8f77..def9b0e47a5d 100644 --- a/Lib/lib2to3/tests/test_fixers.py +++ b/Lib/lib2to3/tests/test_fixers.py @@ -3322,6 +3322,10 @@ def test_basic_types_convert(self): a = """type(None)""" self.check(b, a) + b = "types.StringTypes" + a = "(str,)" + self.check(b, a) + class Test_idioms(FixerTestCase): fixer = "idioms" diff --git a/Lib/lib2to3/tests/test_parser.py b/Lib/lib2to3/tests/test_parser.py index a383a14e30ed..b533c01e28f5 100644 --- a/Lib/lib2to3/tests/test_parser.py +++ b/Lib/lib2to3/tests/test_parser.py @@ -48,6 +48,71 @@ def invalid_syntax(self, code): raise AssertionError("Syntax shouldn't have been valid") +class TestMatrixMultiplication(GrammarTest): + def test_matrix_multiplication_operator(self): + self.validate("a @ b") + self.validate("a @= b") + + +class TestYieldFrom(GrammarTest): + def test_yield_from(self): + self.validate("yield from x") + self.validate("(yield from x) + y") + self.invalid_syntax("yield from") + + +class TestAsyncAwait(GrammarTest): + def test_await_expr(self): + self.validate("""async def foo(): + await x + """) + + self.validate("""async def foo(): + + def foo(): pass + + def foo(): pass + + await x + """) + + self.validate("""async def foo(): return await a""") + + self.validate("""def foo(): + def foo(): pass + async def foo(): await x + """) + + self.invalid_syntax("await x") + self.invalid_syntax("""def foo(): + await x""") + + self.invalid_syntax("""def foo(): + def foo(): pass + async def foo(): pass + await x + """) + + def test_async_var(self): + self.validate("""async = 1""") + self.validate("""await = 1""") + self.validate("""def async(): pass""") + + def test_async_with(self): + self.validate("""async def foo(): + async for a in b: pass""") + + self.invalid_syntax("""def foo(): + async for a in b: pass""") + + def test_async_for(self): + self.validate("""async def foo(): + async with a: pass""") + + self.invalid_syntax("""def foo(): + async with a: pass""") + + class TestRaiseChanges(GrammarTest): def test_2x_style_1(self): self.validate("raise") @@ -77,7 +142,7 @@ def test_3x_style_invalid_4(self): self.invalid_syntax("raise E from") -# Adaptated from Python 3's Lib/test/test_grammar.py:GrammarTests.testFuncdef +# Adapted from Python 3's Lib/test/test_grammar.py:GrammarTests.testFuncdef class TestFunctionAnnotations(GrammarTest): def test_1(self): self.validate("""def f(x) -> list: pass""") diff --git a/Lib/linecache.py b/Lib/linecache.py index 02a9eb52530f..3afcce1f0a14 100644 --- a/Lib/linecache.py +++ b/Lib/linecache.py @@ -1,10 +1,11 @@ -"""Cache lines from files. +"""Cache lines from Python source files. This is intended to read lines from modules imported -- hence if a filename is not found, it will look down the module search path for a file by that name. """ +import functools import sys import os import tokenize @@ -21,7 +22,9 @@ def getline(filename, lineno, module_globals=None): # The cache -cache = {} # The cache +# The cache. Maps filenames to either a thunk which will provide source code, +# or a tuple (size, mtime, lines, fullname) once loaded. +cache = {} def clearcache(): @@ -32,13 +35,19 @@ def clearcache(): def getlines(filename, module_globals=None): - """Get the lines for a file from the cache. + """Get the lines for a Python source file from the cache. Update the cache if it doesn't contain an entry for this file already.""" if filename in cache: - return cache[filename][2] - else: + entry = cache[filename] + if len(entry) != 1: + return cache[filename][2] + + try: return updatecache(filename, module_globals) + except MemoryError: + clearcache() + return [] def checkcache(filename=None): @@ -54,7 +63,11 @@ def checkcache(filename=None): return for filename in filenames: - size, mtime, lines, fullname = cache[filename] + entry = cache[filename] + if len(entry) == 1: + # lazy cache entry, leave it lazy. + continue + size, mtime, lines, fullname = entry if mtime is None: continue # no-op for files loaded via a __loader__ try: @@ -72,7 +85,8 @@ def updatecache(filename, module_globals=None): and return an empty list.""" if filename in cache: - del cache[filename] + if len(cache[filename]) != 1: + del cache[filename] if not filename or (filename.startswith('<') and filename.endswith('>')): return [] @@ -82,27 +96,23 @@ def updatecache(filename, module_globals=None): except OSError: basename = filename - # Try for a __loader__, if available - if module_globals and '__loader__' in module_globals: - name = module_globals.get('__name__') - loader = module_globals['__loader__'] - get_source = getattr(loader, 'get_source', None) - - if name and get_source: - try: - data = get_source(name) - except (ImportError, OSError): - pass - else: - if data is None: - # No luck, the PEP302 loader cannot find the source - # for this module. - return [] - cache[filename] = ( - len(data), None, - [line+'\n' for line in data.splitlines()], fullname - ) - return cache[filename][2] + # Realise a lazy loader based lookup if there is one + # otherwise try to lookup right now. + if lazycache(filename, module_globals): + try: + data = cache[filename][0]() + except (ImportError, OSError): + pass + else: + if data is None: + # No luck, the PEP302 loader cannot find the source + # for this module. + return [] + cache[filename] = ( + len(data), None, + [line+'\n' for line in data.splitlines()], fullname + ) + return cache[filename][2] # Try looking through the module search path, which is only useful # when handling a relative filename. @@ -132,3 +142,36 @@ def updatecache(filename, module_globals=None): size, mtime = stat.st_size, stat.st_mtime cache[filename] = size, mtime, lines, fullname return lines + + +def lazycache(filename, module_globals): + """Seed the cache for filename with module_globals. + + The module loader will be asked for the source only when getlines is + called, not immediately. + + If there is an entry in the cache already, it is not altered. + + :return: True if a lazy load is registered in the cache, + otherwise False. To register such a load a module loader with a + get_source method must be found, the filename must be a cachable + filename, and the filename must not be already cached. + """ + if filename in cache: + if len(cache[filename]) == 1: + return True + else: + return False + if not filename or (filename.startswith('<') and filename.endswith('>')): + return False + # Try for a __loader__, if available + if module_globals and '__loader__' in module_globals: + name = module_globals.get('__name__') + loader = module_globals['__loader__'] + get_source = getattr(loader, 'get_source', None) + + if name and get_source: + get_lines = functools.partial(get_source, name) + cache[filename] = (get_lines,) + return True + return False diff --git a/Lib/locale.py b/Lib/locale.py index 2e82c952aceb..ceaa6d8ff720 100644 --- a/Lib/locale.py +++ b/Lib/locale.py @@ -301,8 +301,8 @@ def str(val): """Convert float to integer, taking the locale into account.""" return format("%.12g", val) -def atof(string, func=float): - "Parses a string as a float according to the locale settings." +def delocalize(string): + "Parses a string as a normalized number according to the locale settings." #First, get rid of the grouping ts = localeconv()['thousands_sep'] if ts: @@ -311,12 +311,15 @@ def atof(string, func=float): dd = localeconv()['decimal_point'] if dd: string = string.replace(dd, '.') - #finally, parse the string - return func(string) + return string -def atoi(str): +def atof(string, func=float): + "Parses a string as a float according to the locale settings." + return func(delocalize(string)) + +def atoi(string): "Converts a string to an integer according to the locale settings." - return atof(str, int) + return int(delocalize(string)) def _test(): setlocale(LC_ALL, "") @@ -336,6 +339,40 @@ def _test(): # overridden below) _setlocale = setlocale +def _replace_encoding(code, encoding): + if '.' in code: + langname = code[:code.index('.')] + else: + langname = code + # Convert the encoding to a C lib compatible encoding string + norm_encoding = encodings.normalize_encoding(encoding) + #print('norm encoding: %r' % norm_encoding) + norm_encoding = encodings.aliases.aliases.get(norm_encoding.lower(), + norm_encoding) + #print('aliased encoding: %r' % norm_encoding) + encoding = norm_encoding + norm_encoding = norm_encoding.lower() + if norm_encoding in locale_encoding_alias: + encoding = locale_encoding_alias[norm_encoding] + else: + norm_encoding = norm_encoding.replace('_', '') + norm_encoding = norm_encoding.replace('-', '') + if norm_encoding in locale_encoding_alias: + encoding = locale_encoding_alias[norm_encoding] + #print('found encoding %r' % encoding) + return langname + '.' + encoding + +def _append_modifier(code, modifier): + if modifier == 'euro': + if '.' not in code: + return code + '.ISO8859-15' + _, _, encoding = code.partition('.') + if encoding in ('ISO8859-15', 'UTF-8'): + return code + if encoding == 'ISO8859-1': + return _replace_encoding(code, 'ISO8859-15') + return code + '@' + modifier + def normalize(localename): """ Returns a normalized locale code for the given locale @@ -352,55 +389,72 @@ def normalize(localename): does. """ - # Normalize the locale name and extract the encoding - fullname = localename.lower() - if ':' in fullname: + # Normalize the locale name and extract the encoding and modifier + code = localename.lower() + if ':' in code: # ':' is sometimes used as encoding delimiter. - fullname = fullname.replace(':', '.') - if '.' in fullname: - langname, encoding = fullname.split('.')[:2] - fullname = langname + '.' + encoding + code = code.replace(':', '.') + if '@' in code: + code, modifier = code.split('@', 1) else: - langname = fullname + modifier = '' + if '.' in code: + langname, encoding = code.split('.')[:2] + else: + langname = code encoding = '' - # First lookup: fullname (possibly with encoding) - norm_encoding = encoding.replace('-', '') - norm_encoding = norm_encoding.replace('_', '') - lookup_name = langname + '.' + encoding + # First lookup: fullname (possibly with encoding and modifier) + lang_enc = langname + if encoding: + norm_encoding = encoding.replace('-', '') + norm_encoding = norm_encoding.replace('_', '') + lang_enc += '.' + norm_encoding + lookup_name = lang_enc + if modifier: + lookup_name += '@' + modifier code = locale_alias.get(lookup_name, None) if code is not None: return code - #print 'first lookup failed' - - # Second try: langname (without encoding) - code = locale_alias.get(langname, None) - if code is not None: - #print 'langname lookup succeeded' - if '.' in code: - langname, defenc = code.split('.') - else: - langname = code - defenc = '' - if encoding: - # Convert the encoding to a C lib compatible encoding string - norm_encoding = encodings.normalize_encoding(encoding) - #print 'norm encoding: %r' % norm_encoding - norm_encoding = encodings.aliases.aliases.get(norm_encoding, - norm_encoding) - #print 'aliased encoding: %r' % norm_encoding - encoding = locale_encoding_alias.get(norm_encoding, - norm_encoding) - else: - encoding = defenc - #print 'found encoding %r' % encoding - if encoding: - return langname + '.' + encoding - else: - return langname - - else: - return localename + #print('first lookup failed') + + if modifier: + # Second try: fullname without modifier (possibly with encoding) + code = locale_alias.get(lang_enc, None) + if code is not None: + #print('lookup without modifier succeeded') + if '@' not in code: + return _append_modifier(code, modifier) + if code.split('@', 1)[1].lower() == modifier: + return code + #print('second lookup failed') + + if encoding: + # Third try: langname (without encoding, possibly with modifier) + lookup_name = langname + if modifier: + lookup_name += '@' + modifier + code = locale_alias.get(lookup_name, None) + if code is not None: + #print('lookup without encoding succeeded') + if '@' not in code: + return _replace_encoding(code, encoding) + code, modifier = code.split('@', 1) + return _replace_encoding(code, encoding) + '@' + modifier + + if modifier: + # Fourth try: langname (without encoding and modifier) + code = locale_alias.get(langname, None) + if code is not None: + #print('lookup without modifier and encoding succeeded') + if '@' not in code: + code = _replace_encoding(code, encoding) + return _append_modifier(code, modifier) + code, defmod = code.split('@', 1) + if defmod.lower() == modifier: + return _replace_encoding(code, encoding) + '@' + defmod + + return localename def _parse_localename(localename): @@ -419,7 +473,7 @@ def _parse_localename(localename): code = normalize(localename) if '@' in code: # Deal with locale modifiers - code, modifier = code.split('@') + code, modifier = code.split('@', 1) if modifier == 'euro' and '.' not in code: # Assume Latin-9 for @euro locales. This is bogus, # since some systems may use other encodings for these @@ -611,6 +665,14 @@ def getpreferredencoding(do_setlocale = True): 'jis': 'JIS7', 'jis7': 'JIS7', 'ajec': 'eucJP', + 'koi8c': 'KOI8-C', + 'microsoftcp1251': 'CP1251', + 'microsoftcp1255': 'CP1255', + 'microsoftcp1256': 'CP1256', + '88591': 'ISO8859-1', + '88592': 'ISO8859-2', + '88595': 'ISO8859-5', + '885915': 'ISO8859-15', # Mappings from Python codec names to C lib encoding names 'ascii': 'ISO8859-1', @@ -637,11 +699,21 @@ def getpreferredencoding(do_setlocale = True): 'euc_kr': 'eucKR', 'utf_8': 'UTF-8', 'koi8_r': 'KOI8-R', + 'koi8_t': 'KOI8-T', 'koi8_u': 'KOI8-U', + 'kz1048': 'RK1048', + 'cp1251': 'CP1251', + 'cp1255': 'CP1255', + 'cp1256': 'CP1256', + # XXX This list is still incomplete. If you know more # mappings, please file a bug report. Thanks. } +for k, v in sorted(locale_encoding_alias.items()): + k = k.replace('_', '') + locale_encoding_alias.setdefault(k, v) + # # The locale_alias table maps lowercase alias names to C locale names # (case-sensitive). Encodings are always separated from the locale @@ -732,458 +804,281 @@ def getpreferredencoding(do_setlocale = True): # updated 'sr_yu.utf8@cyrillic' -> 'sr_CS.UTF-8' to 'sr_RS.UTF-8' # updated 'sr_yu@cyrillic' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8' # +# SS 2013-12-20: +# Updated alias mapping to most recent locale.alias file +# from X.org distribution using makelocalealias.py. +# +# These are the differences compared to the old mapping (Python 3.3.3 +# and older): +# +# updated 'a3' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C' +# updated 'a3_az' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C' +# updated 'a3_az.koi8c' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C' +# updated 'cs_cs.iso88592' -> 'cs_CS.ISO8859-2' to 'cs_CZ.ISO8859-2' +# updated 'hebrew' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8' +# updated 'hebrew.iso88598' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8' +# updated 'sd' -> 'sd_IN@devanagari.UTF-8' to 'sd_IN.UTF-8' +# updated 'sr@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin' +# updated 'sr_cs' -> 'sr_RS.UTF-8' to 'sr_CS.UTF-8' +# updated 'sr_cs.utf8@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin' +# updated 'sr_cs@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin' +# +# SS 2014-10-01: +# Updated alias mapping with glibc 2.19 supported locales. locale_alias = { - 'a3': 'a3_AZ.KOI8-C', - 'a3_az': 'a3_AZ.KOI8-C', - 'a3_az.koi8c': 'a3_AZ.KOI8-C', + 'a3': 'az_AZ.KOI8-C', + 'a3_az': 'az_AZ.KOI8-C', + 'a3_az.koic': 'az_AZ.KOI8-C', + 'aa_dj': 'aa_DJ.ISO8859-1', + 'aa_er': 'aa_ER.UTF-8', + 'aa_et': 'aa_ET.UTF-8', 'af': 'af_ZA.ISO8859-1', 'af_za': 'af_ZA.ISO8859-1', - 'af_za.iso88591': 'af_ZA.ISO8859-1', 'am': 'am_ET.UTF-8', 'am_et': 'am_ET.UTF-8', 'american': 'en_US.ISO8859-1', - 'american.iso88591': 'en_US.ISO8859-1', + 'an_es': 'an_ES.ISO8859-15', 'ar': 'ar_AA.ISO8859-6', 'ar_aa': 'ar_AA.ISO8859-6', - 'ar_aa.iso88596': 'ar_AA.ISO8859-6', 'ar_ae': 'ar_AE.ISO8859-6', - 'ar_ae.iso88596': 'ar_AE.ISO8859-6', 'ar_bh': 'ar_BH.ISO8859-6', - 'ar_bh.iso88596': 'ar_BH.ISO8859-6', 'ar_dz': 'ar_DZ.ISO8859-6', - 'ar_dz.iso88596': 'ar_DZ.ISO8859-6', 'ar_eg': 'ar_EG.ISO8859-6', - 'ar_eg.iso88596': 'ar_EG.ISO8859-6', + 'ar_in': 'ar_IN.UTF-8', 'ar_iq': 'ar_IQ.ISO8859-6', - 'ar_iq.iso88596': 'ar_IQ.ISO8859-6', 'ar_jo': 'ar_JO.ISO8859-6', - 'ar_jo.iso88596': 'ar_JO.ISO8859-6', 'ar_kw': 'ar_KW.ISO8859-6', - 'ar_kw.iso88596': 'ar_KW.ISO8859-6', 'ar_lb': 'ar_LB.ISO8859-6', - 'ar_lb.iso88596': 'ar_LB.ISO8859-6', 'ar_ly': 'ar_LY.ISO8859-6', - 'ar_ly.iso88596': 'ar_LY.ISO8859-6', 'ar_ma': 'ar_MA.ISO8859-6', - 'ar_ma.iso88596': 'ar_MA.ISO8859-6', 'ar_om': 'ar_OM.ISO8859-6', - 'ar_om.iso88596': 'ar_OM.ISO8859-6', 'ar_qa': 'ar_QA.ISO8859-6', - 'ar_qa.iso88596': 'ar_QA.ISO8859-6', 'ar_sa': 'ar_SA.ISO8859-6', - 'ar_sa.iso88596': 'ar_SA.ISO8859-6', 'ar_sd': 'ar_SD.ISO8859-6', - 'ar_sd.iso88596': 'ar_SD.ISO8859-6', 'ar_sy': 'ar_SY.ISO8859-6', - 'ar_sy.iso88596': 'ar_SY.ISO8859-6', 'ar_tn': 'ar_TN.ISO8859-6', - 'ar_tn.iso88596': 'ar_TN.ISO8859-6', 'ar_ye': 'ar_YE.ISO8859-6', - 'ar_ye.iso88596': 'ar_YE.ISO8859-6', 'arabic': 'ar_AA.ISO8859-6', - 'arabic.iso88596': 'ar_AA.ISO8859-6', 'as': 'as_IN.UTF-8', + 'as_in': 'as_IN.UTF-8', + 'ast_es': 'ast_ES.ISO8859-15', + 'ayc_pe': 'ayc_PE.UTF-8', 'az': 'az_AZ.ISO8859-9E', 'az_az': 'az_AZ.ISO8859-9E', 'az_az.iso88599e': 'az_AZ.ISO8859-9E', 'be': 'be_BY.CP1251', 'be@latin': 'be_BY.UTF-8@latin', + 'be_bg.utf8': 'bg_BG.UTF-8', 'be_by': 'be_BY.CP1251', - 'be_by.cp1251': 'be_BY.CP1251', - 'be_by.microsoftcp1251': 'be_BY.CP1251', - 'be_by.utf8@latin': 'be_BY.UTF-8@latin', 'be_by@latin': 'be_BY.UTF-8@latin', + 'bem_zm': 'bem_ZM.UTF-8', + 'ber_dz': 'ber_DZ.UTF-8', + 'ber_ma': 'ber_MA.UTF-8', 'bg': 'bg_BG.CP1251', 'bg_bg': 'bg_BG.CP1251', - 'bg_bg.cp1251': 'bg_BG.CP1251', - 'bg_bg.iso88595': 'bg_BG.ISO8859-5', - 'bg_bg.koi8r': 'bg_BG.KOI8-R', - 'bg_bg.microsoftcp1251': 'bg_BG.CP1251', + 'bho_in': 'bho_IN.UTF-8', + 'bn_bd': 'bn_BD.UTF-8', 'bn_in': 'bn_IN.UTF-8', + 'bo_cn': 'bo_CN.UTF-8', + 'bo_in': 'bo_IN.UTF-8', 'bokmal': 'nb_NO.ISO8859-1', 'bokm\xe5l': 'nb_NO.ISO8859-1', 'br': 'br_FR.ISO8859-1', 'br_fr': 'br_FR.ISO8859-1', - 'br_fr.iso88591': 'br_FR.ISO8859-1', - 'br_fr.iso885914': 'br_FR.ISO8859-14', - 'br_fr.iso885915': 'br_FR.ISO8859-15', - 'br_fr.iso885915@euro': 'br_FR.ISO8859-15', - 'br_fr.utf8@euro': 'br_FR.UTF-8', - 'br_fr@euro': 'br_FR.ISO8859-15', + 'brx_in': 'brx_IN.UTF-8', 'bs': 'bs_BA.ISO8859-2', 'bs_ba': 'bs_BA.ISO8859-2', - 'bs_ba.iso88592': 'bs_BA.ISO8859-2', 'bulgarian': 'bg_BG.CP1251', + 'byn_er': 'byn_ER.UTF-8', 'c': 'C', 'c-french': 'fr_CA.ISO8859-1', - 'c-french.iso88591': 'fr_CA.ISO8859-1', + 'c.ascii': 'C', 'c.en': 'C', 'c.iso88591': 'en_US.ISO8859-1', + 'c.utf8': 'en_US.UTF-8', 'c_c': 'C', 'c_c.c': 'C', 'ca': 'ca_ES.ISO8859-1', 'ca_ad': 'ca_AD.ISO8859-1', - 'ca_ad.iso88591': 'ca_AD.ISO8859-1', - 'ca_ad.iso885915': 'ca_AD.ISO8859-15', - 'ca_ad.iso885915@euro': 'ca_AD.ISO8859-15', - 'ca_ad.utf8@euro': 'ca_AD.UTF-8', - 'ca_ad@euro': 'ca_AD.ISO8859-15', 'ca_es': 'ca_ES.ISO8859-1', - 'ca_es.iso88591': 'ca_ES.ISO8859-1', - 'ca_es.iso885915': 'ca_ES.ISO8859-15', - 'ca_es.iso885915@euro': 'ca_ES.ISO8859-15', - 'ca_es.utf8@euro': 'ca_ES.UTF-8', - 'ca_es@euro': 'ca_ES.ISO8859-15', + 'ca_es@valencia': 'ca_ES.ISO8859-15@valencia', 'ca_fr': 'ca_FR.ISO8859-1', - 'ca_fr.iso88591': 'ca_FR.ISO8859-1', - 'ca_fr.iso885915': 'ca_FR.ISO8859-15', - 'ca_fr.iso885915@euro': 'ca_FR.ISO8859-15', - 'ca_fr.utf8@euro': 'ca_FR.UTF-8', - 'ca_fr@euro': 'ca_FR.ISO8859-15', 'ca_it': 'ca_IT.ISO8859-1', - 'ca_it.iso88591': 'ca_IT.ISO8859-1', - 'ca_it.iso885915': 'ca_IT.ISO8859-15', - 'ca_it.iso885915@euro': 'ca_IT.ISO8859-15', - 'ca_it.utf8@euro': 'ca_IT.UTF-8', - 'ca_it@euro': 'ca_IT.ISO8859-15', 'catalan': 'ca_ES.ISO8859-1', 'cextend': 'en_US.ISO8859-1', - 'cextend.en': 'en_US.ISO8859-1', 'chinese-s': 'zh_CN.eucCN', 'chinese-t': 'zh_TW.eucTW', + 'crh_ua': 'crh_UA.UTF-8', 'croatian': 'hr_HR.ISO8859-2', 'cs': 'cs_CZ.ISO8859-2', 'cs_cs': 'cs_CZ.ISO8859-2', - 'cs_cs.iso88592': 'cs_CS.ISO8859-2', 'cs_cz': 'cs_CZ.ISO8859-2', - 'cs_cz.iso88592': 'cs_CZ.ISO8859-2', + 'csb_pl': 'csb_PL.UTF-8', + 'cv_ru': 'cv_RU.UTF-8', 'cy': 'cy_GB.ISO8859-1', 'cy_gb': 'cy_GB.ISO8859-1', - 'cy_gb.iso88591': 'cy_GB.ISO8859-1', - 'cy_gb.iso885914': 'cy_GB.ISO8859-14', - 'cy_gb.iso885915': 'cy_GB.ISO8859-15', - 'cy_gb@euro': 'cy_GB.ISO8859-15', 'cz': 'cs_CZ.ISO8859-2', 'cz_cz': 'cs_CZ.ISO8859-2', 'czech': 'cs_CZ.ISO8859-2', 'da': 'da_DK.ISO8859-1', - 'da.iso885915': 'da_DK.ISO8859-15', 'da_dk': 'da_DK.ISO8859-1', - 'da_dk.88591': 'da_DK.ISO8859-1', - 'da_dk.885915': 'da_DK.ISO8859-15', - 'da_dk.iso88591': 'da_DK.ISO8859-1', - 'da_dk.iso885915': 'da_DK.ISO8859-15', - 'da_dk@euro': 'da_DK.ISO8859-15', 'danish': 'da_DK.ISO8859-1', - 'danish.iso88591': 'da_DK.ISO8859-1', 'dansk': 'da_DK.ISO8859-1', 'de': 'de_DE.ISO8859-1', - 'de.iso885915': 'de_DE.ISO8859-15', 'de_at': 'de_AT.ISO8859-1', - 'de_at.iso88591': 'de_AT.ISO8859-1', - 'de_at.iso885915': 'de_AT.ISO8859-15', - 'de_at.iso885915@euro': 'de_AT.ISO8859-15', - 'de_at.utf8@euro': 'de_AT.UTF-8', - 'de_at@euro': 'de_AT.ISO8859-15', 'de_be': 'de_BE.ISO8859-1', - 'de_be.iso88591': 'de_BE.ISO8859-1', - 'de_be.iso885915': 'de_BE.ISO8859-15', - 'de_be.iso885915@euro': 'de_BE.ISO8859-15', - 'de_be.utf8@euro': 'de_BE.UTF-8', - 'de_be@euro': 'de_BE.ISO8859-15', 'de_ch': 'de_CH.ISO8859-1', - 'de_ch.iso88591': 'de_CH.ISO8859-1', - 'de_ch.iso885915': 'de_CH.ISO8859-15', - 'de_ch@euro': 'de_CH.ISO8859-15', 'de_de': 'de_DE.ISO8859-1', - 'de_de.88591': 'de_DE.ISO8859-1', - 'de_de.885915': 'de_DE.ISO8859-15', - 'de_de.885915@euro': 'de_DE.ISO8859-15', - 'de_de.iso88591': 'de_DE.ISO8859-1', - 'de_de.iso885915': 'de_DE.ISO8859-15', - 'de_de.iso885915@euro': 'de_DE.ISO8859-15', - 'de_de.utf8@euro': 'de_DE.UTF-8', - 'de_de@euro': 'de_DE.ISO8859-15', + 'de_li.utf8': 'de_LI.UTF-8', 'de_lu': 'de_LU.ISO8859-1', - 'de_lu.iso88591': 'de_LU.ISO8859-1', - 'de_lu.iso885915': 'de_LU.ISO8859-15', - 'de_lu.iso885915@euro': 'de_LU.ISO8859-15', - 'de_lu.utf8@euro': 'de_LU.UTF-8', - 'de_lu@euro': 'de_LU.ISO8859-15', 'deutsch': 'de_DE.ISO8859-1', + 'doi_in': 'doi_IN.UTF-8', 'dutch': 'nl_NL.ISO8859-1', 'dutch.iso88591': 'nl_BE.ISO8859-1', + 'dv_mv': 'dv_MV.UTF-8', + 'dz_bt': 'dz_BT.UTF-8', 'ee': 'ee_EE.ISO8859-4', 'ee_ee': 'ee_EE.ISO8859-4', - 'ee_ee.iso88594': 'ee_EE.ISO8859-4', 'eesti': 'et_EE.ISO8859-1', 'el': 'el_GR.ISO8859-7', + 'el_cy': 'el_CY.ISO8859-7', 'el_gr': 'el_GR.ISO8859-7', - 'el_gr.iso88597': 'el_GR.ISO8859-7', 'el_gr@euro': 'el_GR.ISO8859-15', 'en': 'en_US.ISO8859-1', - 'en.iso88591': 'en_US.ISO8859-1', + 'en_ag': 'en_AG.UTF-8', 'en_au': 'en_AU.ISO8859-1', - 'en_au.iso88591': 'en_AU.ISO8859-1', 'en_be': 'en_BE.ISO8859-1', - 'en_be@euro': 'en_BE.ISO8859-15', 'en_bw': 'en_BW.ISO8859-1', - 'en_bw.iso88591': 'en_BW.ISO8859-1', 'en_ca': 'en_CA.ISO8859-1', - 'en_ca.iso88591': 'en_CA.ISO8859-1', + 'en_dk': 'en_DK.ISO8859-1', + 'en_dl.utf8': 'en_DL.UTF-8', 'en_gb': 'en_GB.ISO8859-1', - 'en_gb.88591': 'en_GB.ISO8859-1', - 'en_gb.iso88591': 'en_GB.ISO8859-1', - 'en_gb.iso885915': 'en_GB.ISO8859-15', - 'en_gb@euro': 'en_GB.ISO8859-15', 'en_hk': 'en_HK.ISO8859-1', - 'en_hk.iso88591': 'en_HK.ISO8859-1', 'en_ie': 'en_IE.ISO8859-1', - 'en_ie.iso88591': 'en_IE.ISO8859-1', - 'en_ie.iso885915': 'en_IE.ISO8859-15', - 'en_ie.iso885915@euro': 'en_IE.ISO8859-15', - 'en_ie.utf8@euro': 'en_IE.UTF-8', - 'en_ie@euro': 'en_IE.ISO8859-15', 'en_in': 'en_IN.ISO8859-1', + 'en_ng': 'en_NG.UTF-8', 'en_nz': 'en_NZ.ISO8859-1', - 'en_nz.iso88591': 'en_NZ.ISO8859-1', 'en_ph': 'en_PH.ISO8859-1', - 'en_ph.iso88591': 'en_PH.ISO8859-1', 'en_sg': 'en_SG.ISO8859-1', - 'en_sg.iso88591': 'en_SG.ISO8859-1', 'en_uk': 'en_GB.ISO8859-1', 'en_us': 'en_US.ISO8859-1', - 'en_us.88591': 'en_US.ISO8859-1', - 'en_us.885915': 'en_US.ISO8859-15', - 'en_us.iso88591': 'en_US.ISO8859-1', - 'en_us.iso885915': 'en_US.ISO8859-15', - 'en_us.iso885915@euro': 'en_US.ISO8859-15', - 'en_us@euro': 'en_US.ISO8859-15', 'en_us@euro@euro': 'en_US.ISO8859-15', 'en_za': 'en_ZA.ISO8859-1', - 'en_za.88591': 'en_ZA.ISO8859-1', - 'en_za.iso88591': 'en_ZA.ISO8859-1', - 'en_za.iso885915': 'en_ZA.ISO8859-15', - 'en_za@euro': 'en_ZA.ISO8859-15', + 'en_zm': 'en_ZM.UTF-8', 'en_zw': 'en_ZW.ISO8859-1', - 'en_zw.iso88591': 'en_ZW.ISO8859-1', + 'en_zw.utf8': 'en_ZS.UTF-8', 'eng_gb': 'en_GB.ISO8859-1', - 'eng_gb.8859': 'en_GB.ISO8859-1', 'english': 'en_EN.ISO8859-1', - 'english.iso88591': 'en_EN.ISO8859-1', 'english_uk': 'en_GB.ISO8859-1', - 'english_uk.8859': 'en_GB.ISO8859-1', 'english_united-states': 'en_US.ISO8859-1', 'english_united-states.437': 'C', 'english_us': 'en_US.ISO8859-1', - 'english_us.8859': 'en_US.ISO8859-1', - 'english_us.ascii': 'en_US.ISO8859-1', 'eo': 'eo_XX.ISO8859-3', + 'eo.utf8': 'eo.UTF-8', 'eo_eo': 'eo_EO.ISO8859-3', - 'eo_eo.iso88593': 'eo_EO.ISO8859-3', + 'eo_us.utf8': 'eo_US.UTF-8', 'eo_xx': 'eo_XX.ISO8859-3', - 'eo_xx.iso88593': 'eo_XX.ISO8859-3', 'es': 'es_ES.ISO8859-1', 'es_ar': 'es_AR.ISO8859-1', - 'es_ar.iso88591': 'es_AR.ISO8859-1', 'es_bo': 'es_BO.ISO8859-1', - 'es_bo.iso88591': 'es_BO.ISO8859-1', 'es_cl': 'es_CL.ISO8859-1', - 'es_cl.iso88591': 'es_CL.ISO8859-1', 'es_co': 'es_CO.ISO8859-1', - 'es_co.iso88591': 'es_CO.ISO8859-1', 'es_cr': 'es_CR.ISO8859-1', - 'es_cr.iso88591': 'es_CR.ISO8859-1', + 'es_cu': 'es_CU.UTF-8', 'es_do': 'es_DO.ISO8859-1', - 'es_do.iso88591': 'es_DO.ISO8859-1', 'es_ec': 'es_EC.ISO8859-1', - 'es_ec.iso88591': 'es_EC.ISO8859-1', 'es_es': 'es_ES.ISO8859-1', - 'es_es.88591': 'es_ES.ISO8859-1', - 'es_es.iso88591': 'es_ES.ISO8859-1', - 'es_es.iso885915': 'es_ES.ISO8859-15', - 'es_es.iso885915@euro': 'es_ES.ISO8859-15', - 'es_es.utf8@euro': 'es_ES.UTF-8', - 'es_es@euro': 'es_ES.ISO8859-15', 'es_gt': 'es_GT.ISO8859-1', - 'es_gt.iso88591': 'es_GT.ISO8859-1', 'es_hn': 'es_HN.ISO8859-1', - 'es_hn.iso88591': 'es_HN.ISO8859-1', 'es_mx': 'es_MX.ISO8859-1', - 'es_mx.iso88591': 'es_MX.ISO8859-1', 'es_ni': 'es_NI.ISO8859-1', - 'es_ni.iso88591': 'es_NI.ISO8859-1', 'es_pa': 'es_PA.ISO8859-1', - 'es_pa.iso88591': 'es_PA.ISO8859-1', - 'es_pa.iso885915': 'es_PA.ISO8859-15', - 'es_pa@euro': 'es_PA.ISO8859-15', 'es_pe': 'es_PE.ISO8859-1', - 'es_pe.iso88591': 'es_PE.ISO8859-1', - 'es_pe.iso885915': 'es_PE.ISO8859-15', - 'es_pe@euro': 'es_PE.ISO8859-15', 'es_pr': 'es_PR.ISO8859-1', - 'es_pr.iso88591': 'es_PR.ISO8859-1', 'es_py': 'es_PY.ISO8859-1', - 'es_py.iso88591': 'es_PY.ISO8859-1', - 'es_py.iso885915': 'es_PY.ISO8859-15', - 'es_py@euro': 'es_PY.ISO8859-15', 'es_sv': 'es_SV.ISO8859-1', - 'es_sv.iso88591': 'es_SV.ISO8859-1', - 'es_sv.iso885915': 'es_SV.ISO8859-15', - 'es_sv@euro': 'es_SV.ISO8859-15', 'es_us': 'es_US.ISO8859-1', - 'es_us.iso88591': 'es_US.ISO8859-1', 'es_uy': 'es_UY.ISO8859-1', - 'es_uy.iso88591': 'es_UY.ISO8859-1', - 'es_uy.iso885915': 'es_UY.ISO8859-15', - 'es_uy@euro': 'es_UY.ISO8859-15', 'es_ve': 'es_VE.ISO8859-1', - 'es_ve.iso88591': 'es_VE.ISO8859-1', - 'es_ve.iso885915': 'es_VE.ISO8859-15', - 'es_ve@euro': 'es_VE.ISO8859-15', 'estonian': 'et_EE.ISO8859-1', 'et': 'et_EE.ISO8859-15', 'et_ee': 'et_EE.ISO8859-15', - 'et_ee.iso88591': 'et_EE.ISO8859-1', - 'et_ee.iso885913': 'et_EE.ISO8859-13', - 'et_ee.iso885915': 'et_EE.ISO8859-15', - 'et_ee.iso88594': 'et_EE.ISO8859-4', - 'et_ee@euro': 'et_EE.ISO8859-15', 'eu': 'eu_ES.ISO8859-1', 'eu_es': 'eu_ES.ISO8859-1', - 'eu_es.iso88591': 'eu_ES.ISO8859-1', - 'eu_es.iso885915': 'eu_ES.ISO8859-15', - 'eu_es.iso885915@euro': 'eu_ES.ISO8859-15', - 'eu_es.utf8@euro': 'eu_ES.UTF-8', - 'eu_es@euro': 'eu_ES.ISO8859-15', + 'eu_fr': 'eu_FR.ISO8859-1', 'fa': 'fa_IR.UTF-8', 'fa_ir': 'fa_IR.UTF-8', 'fa_ir.isiri3342': 'fa_IR.ISIRI-3342', + 'ff_sn': 'ff_SN.UTF-8', 'fi': 'fi_FI.ISO8859-15', - 'fi.iso885915': 'fi_FI.ISO8859-15', 'fi_fi': 'fi_FI.ISO8859-15', - 'fi_fi.88591': 'fi_FI.ISO8859-1', - 'fi_fi.iso88591': 'fi_FI.ISO8859-1', - 'fi_fi.iso885915': 'fi_FI.ISO8859-15', - 'fi_fi.iso885915@euro': 'fi_FI.ISO8859-15', - 'fi_fi.utf8@euro': 'fi_FI.UTF-8', - 'fi_fi@euro': 'fi_FI.ISO8859-15', + 'fil_ph': 'fil_PH.UTF-8', 'finnish': 'fi_FI.ISO8859-1', - 'finnish.iso88591': 'fi_FI.ISO8859-1', 'fo': 'fo_FO.ISO8859-1', 'fo_fo': 'fo_FO.ISO8859-1', - 'fo_fo.iso88591': 'fo_FO.ISO8859-1', - 'fo_fo.iso885915': 'fo_FO.ISO8859-15', - 'fo_fo@euro': 'fo_FO.ISO8859-15', 'fr': 'fr_FR.ISO8859-1', - 'fr.iso885915': 'fr_FR.ISO8859-15', 'fr_be': 'fr_BE.ISO8859-1', - 'fr_be.88591': 'fr_BE.ISO8859-1', - 'fr_be.iso88591': 'fr_BE.ISO8859-1', - 'fr_be.iso885915': 'fr_BE.ISO8859-15', - 'fr_be.iso885915@euro': 'fr_BE.ISO8859-15', - 'fr_be.utf8@euro': 'fr_BE.UTF-8', - 'fr_be@euro': 'fr_BE.ISO8859-15', 'fr_ca': 'fr_CA.ISO8859-1', - 'fr_ca.88591': 'fr_CA.ISO8859-1', - 'fr_ca.iso88591': 'fr_CA.ISO8859-1', - 'fr_ca.iso885915': 'fr_CA.ISO8859-15', - 'fr_ca@euro': 'fr_CA.ISO8859-15', 'fr_ch': 'fr_CH.ISO8859-1', - 'fr_ch.88591': 'fr_CH.ISO8859-1', - 'fr_ch.iso88591': 'fr_CH.ISO8859-1', - 'fr_ch.iso885915': 'fr_CH.ISO8859-15', - 'fr_ch@euro': 'fr_CH.ISO8859-15', 'fr_fr': 'fr_FR.ISO8859-1', - 'fr_fr.88591': 'fr_FR.ISO8859-1', - 'fr_fr.iso88591': 'fr_FR.ISO8859-1', - 'fr_fr.iso885915': 'fr_FR.ISO8859-15', - 'fr_fr.iso885915@euro': 'fr_FR.ISO8859-15', - 'fr_fr.utf8@euro': 'fr_FR.UTF-8', - 'fr_fr@euro': 'fr_FR.ISO8859-15', 'fr_lu': 'fr_LU.ISO8859-1', - 'fr_lu.88591': 'fr_LU.ISO8859-1', - 'fr_lu.iso88591': 'fr_LU.ISO8859-1', - 'fr_lu.iso885915': 'fr_LU.ISO8859-15', - 'fr_lu.iso885915@euro': 'fr_LU.ISO8859-15', - 'fr_lu.utf8@euro': 'fr_LU.UTF-8', - 'fr_lu@euro': 'fr_LU.ISO8859-15', 'fran\xe7ais': 'fr_FR.ISO8859-1', 'fre_fr': 'fr_FR.ISO8859-1', - 'fre_fr.8859': 'fr_FR.ISO8859-1', 'french': 'fr_FR.ISO8859-1', 'french.iso88591': 'fr_CH.ISO8859-1', 'french_france': 'fr_FR.ISO8859-1', - 'french_france.8859': 'fr_FR.ISO8859-1', + 'fur_it': 'fur_IT.UTF-8', + 'fy_de': 'fy_DE.UTF-8', + 'fy_nl': 'fy_NL.UTF-8', 'ga': 'ga_IE.ISO8859-1', 'ga_ie': 'ga_IE.ISO8859-1', - 'ga_ie.iso88591': 'ga_IE.ISO8859-1', - 'ga_ie.iso885914': 'ga_IE.ISO8859-14', - 'ga_ie.iso885915': 'ga_IE.ISO8859-15', - 'ga_ie.iso885915@euro': 'ga_IE.ISO8859-15', - 'ga_ie.utf8@euro': 'ga_IE.UTF-8', - 'ga_ie@euro': 'ga_IE.ISO8859-15', 'galego': 'gl_ES.ISO8859-1', 'galician': 'gl_ES.ISO8859-1', 'gd': 'gd_GB.ISO8859-1', 'gd_gb': 'gd_GB.ISO8859-1', - 'gd_gb.iso88591': 'gd_GB.ISO8859-1', - 'gd_gb.iso885914': 'gd_GB.ISO8859-14', - 'gd_gb.iso885915': 'gd_GB.ISO8859-15', - 'gd_gb@euro': 'gd_GB.ISO8859-15', 'ger_de': 'de_DE.ISO8859-1', - 'ger_de.8859': 'de_DE.ISO8859-1', 'german': 'de_DE.ISO8859-1', 'german.iso88591': 'de_CH.ISO8859-1', 'german_germany': 'de_DE.ISO8859-1', - 'german_germany.8859': 'de_DE.ISO8859-1', + 'gez_er': 'gez_ER.UTF-8', + 'gez_et': 'gez_ET.UTF-8', 'gl': 'gl_ES.ISO8859-1', 'gl_es': 'gl_ES.ISO8859-1', - 'gl_es.iso88591': 'gl_ES.ISO8859-1', - 'gl_es.iso885915': 'gl_ES.ISO8859-15', - 'gl_es.iso885915@euro': 'gl_ES.ISO8859-15', - 'gl_es.utf8@euro': 'gl_ES.UTF-8', - 'gl_es@euro': 'gl_ES.ISO8859-15', 'greek': 'el_GR.ISO8859-7', - 'greek.iso88597': 'el_GR.ISO8859-7', 'gu_in': 'gu_IN.UTF-8', 'gv': 'gv_GB.ISO8859-1', 'gv_gb': 'gv_GB.ISO8859-1', - 'gv_gb.iso88591': 'gv_GB.ISO8859-1', - 'gv_gb.iso885914': 'gv_GB.ISO8859-14', - 'gv_gb.iso885915': 'gv_GB.ISO8859-15', - 'gv_gb@euro': 'gv_GB.ISO8859-15', + 'ha_ng': 'ha_NG.UTF-8', 'he': 'he_IL.ISO8859-8', 'he_il': 'he_IL.ISO8859-8', - 'he_il.cp1255': 'he_IL.CP1255', - 'he_il.iso88598': 'he_IL.ISO8859-8', - 'he_il.microsoftcp1255': 'he_IL.CP1255', - 'hebrew': 'iw_IL.ISO8859-8', - 'hebrew.iso88598': 'iw_IL.ISO8859-8', + 'hebrew': 'he_IL.ISO8859-8', 'hi': 'hi_IN.ISCII-DEV', 'hi_in': 'hi_IN.ISCII-DEV', 'hi_in.isciidev': 'hi_IN.ISCII-DEV', 'hne': 'hne_IN.UTF-8', + 'hne_in': 'hne_IN.UTF-8', 'hr': 'hr_HR.ISO8859-2', 'hr_hr': 'hr_HR.ISO8859-2', - 'hr_hr.iso88592': 'hr_HR.ISO8859-2', 'hrvatski': 'hr_HR.ISO8859-2', + 'hsb_de': 'hsb_DE.ISO8859-2', + 'ht_ht': 'ht_HT.UTF-8', 'hu': 'hu_HU.ISO8859-2', 'hu_hu': 'hu_HU.ISO8859-2', - 'hu_hu.iso88592': 'hu_HU.ISO8859-2', 'hungarian': 'hu_HU.ISO8859-2', + 'hy_am': 'hy_AM.UTF-8', + 'hy_am.armscii8': 'hy_AM.ARMSCII_8', + 'ia': 'ia.UTF-8', + 'ia_fr': 'ia_FR.UTF-8', 'icelandic': 'is_IS.ISO8859-1', - 'icelandic.iso88591': 'is_IS.ISO8859-1', 'id': 'id_ID.ISO8859-1', 'id_id': 'id_ID.ISO8859-1', + 'ig_ng': 'ig_NG.UTF-8', + 'ik_ca': 'ik_CA.UTF-8', 'in': 'id_ID.ISO8859-1', 'in_id': 'id_ID.ISO8859-1', 'is': 'is_IS.ISO8859-1', 'is_is': 'is_IS.ISO8859-1', - 'is_is.iso88591': 'is_IS.ISO8859-1', - 'is_is.iso885915': 'is_IS.ISO8859-15', - 'is_is@euro': 'is_IS.ISO8859-15', 'iso-8859-1': 'en_US.ISO8859-1', 'iso-8859-15': 'en_US.ISO8859-15', 'iso8859-1': 'en_US.ISO8859-1', @@ -1191,76 +1086,55 @@ def getpreferredencoding(do_setlocale = True): 'iso_8859_1': 'en_US.ISO8859-1', 'iso_8859_15': 'en_US.ISO8859-15', 'it': 'it_IT.ISO8859-1', - 'it.iso885915': 'it_IT.ISO8859-15', 'it_ch': 'it_CH.ISO8859-1', - 'it_ch.iso88591': 'it_CH.ISO8859-1', - 'it_ch.iso885915': 'it_CH.ISO8859-15', - 'it_ch@euro': 'it_CH.ISO8859-15', 'it_it': 'it_IT.ISO8859-1', - 'it_it.88591': 'it_IT.ISO8859-1', - 'it_it.iso88591': 'it_IT.ISO8859-1', - 'it_it.iso885915': 'it_IT.ISO8859-15', - 'it_it.iso885915@euro': 'it_IT.ISO8859-15', - 'it_it.utf8@euro': 'it_IT.UTF-8', - 'it_it@euro': 'it_IT.ISO8859-15', 'italian': 'it_IT.ISO8859-1', - 'italian.iso88591': 'it_IT.ISO8859-1', 'iu': 'iu_CA.NUNACOM-8', 'iu_ca': 'iu_CA.NUNACOM-8', 'iu_ca.nunacom8': 'iu_CA.NUNACOM-8', 'iw': 'he_IL.ISO8859-8', 'iw_il': 'he_IL.ISO8859-8', - 'iw_il.iso88598': 'he_IL.ISO8859-8', + 'iw_il.utf8': 'iw_IL.UTF-8', 'ja': 'ja_JP.eucJP', - 'ja.jis': 'ja_JP.JIS7', - 'ja.sjis': 'ja_JP.SJIS', 'ja_jp': 'ja_JP.eucJP', - 'ja_jp.ajec': 'ja_JP.eucJP', 'ja_jp.euc': 'ja_JP.eucJP', - 'ja_jp.eucjp': 'ja_JP.eucJP', - 'ja_jp.iso-2022-jp': 'ja_JP.JIS7', - 'ja_jp.iso2022jp': 'ja_JP.JIS7', - 'ja_jp.jis': 'ja_JP.JIS7', - 'ja_jp.jis7': 'ja_JP.JIS7', 'ja_jp.mscode': 'ja_JP.SJIS', 'ja_jp.pck': 'ja_JP.SJIS', - 'ja_jp.sjis': 'ja_JP.SJIS', - 'ja_jp.ujis': 'ja_JP.eucJP', 'japan': 'ja_JP.eucJP', 'japanese': 'ja_JP.eucJP', 'japanese-euc': 'ja_JP.eucJP', 'japanese.euc': 'ja_JP.eucJP', - 'japanese.sjis': 'ja_JP.SJIS', 'jp_jp': 'ja_JP.eucJP', 'ka': 'ka_GE.GEORGIAN-ACADEMY', 'ka_ge': 'ka_GE.GEORGIAN-ACADEMY', 'ka_ge.georgianacademy': 'ka_GE.GEORGIAN-ACADEMY', 'ka_ge.georgianps': 'ka_GE.GEORGIAN-PS', 'ka_ge.georgianrs': 'ka_GE.GEORGIAN-ACADEMY', + 'kk_kz': 'kk_KZ.RK1048', 'kl': 'kl_GL.ISO8859-1', 'kl_gl': 'kl_GL.ISO8859-1', - 'kl_gl.iso88591': 'kl_GL.ISO8859-1', - 'kl_gl.iso885915': 'kl_GL.ISO8859-15', - 'kl_gl@euro': 'kl_GL.ISO8859-15', 'km_kh': 'km_KH.UTF-8', 'kn': 'kn_IN.UTF-8', 'kn_in': 'kn_IN.UTF-8', 'ko': 'ko_KR.eucKR', 'ko_kr': 'ko_KR.eucKR', 'ko_kr.euc': 'ko_KR.eucKR', - 'ko_kr.euckr': 'ko_KR.eucKR', + 'kok_in': 'kok_IN.UTF-8', 'korean': 'ko_KR.eucKR', 'korean.euc': 'ko_KR.eucKR', 'ks': 'ks_IN.UTF-8', - 'ks_in@devanagari': 'ks_IN@devanagari.UTF-8', + 'ks_in': 'ks_IN.UTF-8', + 'ks_in@devanagari.utf8': 'ks_IN.UTF-8@devanagari', + 'ku_tr': 'ku_TR.ISO8859-9', 'kw': 'kw_GB.ISO8859-1', 'kw_gb': 'kw_GB.ISO8859-1', - 'kw_gb.iso88591': 'kw_GB.ISO8859-1', - 'kw_gb.iso885914': 'kw_GB.ISO8859-14', - 'kw_gb.iso885915': 'kw_GB.ISO8859-15', - 'kw_gb@euro': 'kw_GB.ISO8859-15', 'ky': 'ky_KG.UTF-8', 'ky_kg': 'ky_KG.UTF-8', + 'lb_lu': 'lb_LU.UTF-8', + 'lg_ug': 'lg_UG.ISO8859-10', + 'li_be': 'li_BE.UTF-8', + 'li_nl': 'li_NL.UTF-8', + 'lij_it': 'lij_IT.UTF-8', 'lithuanian': 'lt_LT.ISO8859-13', 'lo': 'lo_LA.MULELAO-1', 'lo_la': 'lo_LA.MULELAO-1', @@ -1269,150 +1143,102 @@ def getpreferredencoding(do_setlocale = True): 'lo_la.mulelao1': 'lo_LA.MULELAO-1', 'lt': 'lt_LT.ISO8859-13', 'lt_lt': 'lt_LT.ISO8859-13', - 'lt_lt.iso885913': 'lt_LT.ISO8859-13', - 'lt_lt.iso88594': 'lt_LT.ISO8859-4', 'lv': 'lv_LV.ISO8859-13', 'lv_lv': 'lv_LV.ISO8859-13', - 'lv_lv.iso885913': 'lv_LV.ISO8859-13', - 'lv_lv.iso88594': 'lv_LV.ISO8859-4', + 'mag_in': 'mag_IN.UTF-8', 'mai': 'mai_IN.UTF-8', + 'mai_in': 'mai_IN.UTF-8', + 'mg_mg': 'mg_MG.ISO8859-15', + 'mhr_ru': 'mhr_RU.UTF-8', 'mi': 'mi_NZ.ISO8859-1', 'mi_nz': 'mi_NZ.ISO8859-1', - 'mi_nz.iso88591': 'mi_NZ.ISO8859-1', 'mk': 'mk_MK.ISO8859-5', 'mk_mk': 'mk_MK.ISO8859-5', - 'mk_mk.cp1251': 'mk_MK.CP1251', - 'mk_mk.iso88595': 'mk_MK.ISO8859-5', - 'mk_mk.microsoftcp1251': 'mk_MK.CP1251', 'ml': 'ml_IN.UTF-8', + 'ml_in': 'ml_IN.UTF-8', + 'mn_mn': 'mn_MN.UTF-8', + 'mni_in': 'mni_IN.UTF-8', 'mr': 'mr_IN.UTF-8', 'mr_in': 'mr_IN.UTF-8', 'ms': 'ms_MY.ISO8859-1', 'ms_my': 'ms_MY.ISO8859-1', - 'ms_my.iso88591': 'ms_MY.ISO8859-1', 'mt': 'mt_MT.ISO8859-3', 'mt_mt': 'mt_MT.ISO8859-3', - 'mt_mt.iso88593': 'mt_MT.ISO8859-3', + 'my_mm': 'my_MM.UTF-8', + 'nan_tw@latin': 'nan_TW.UTF-8@latin', 'nb': 'nb_NO.ISO8859-1', 'nb_no': 'nb_NO.ISO8859-1', - 'nb_no.88591': 'nb_NO.ISO8859-1', - 'nb_no.iso88591': 'nb_NO.ISO8859-1', - 'nb_no.iso885915': 'nb_NO.ISO8859-15', - 'nb_no@euro': 'nb_NO.ISO8859-15', + 'nds_de': 'nds_DE.UTF-8', + 'nds_nl': 'nds_NL.UTF-8', + 'ne_np': 'ne_NP.UTF-8', + 'nhn_mx': 'nhn_MX.UTF-8', + 'niu_nu': 'niu_NU.UTF-8', + 'niu_nz': 'niu_NZ.UTF-8', 'nl': 'nl_NL.ISO8859-1', - 'nl.iso885915': 'nl_NL.ISO8859-15', + 'nl_aw': 'nl_AW.UTF-8', 'nl_be': 'nl_BE.ISO8859-1', - 'nl_be.88591': 'nl_BE.ISO8859-1', - 'nl_be.iso88591': 'nl_BE.ISO8859-1', - 'nl_be.iso885915': 'nl_BE.ISO8859-15', - 'nl_be.iso885915@euro': 'nl_BE.ISO8859-15', - 'nl_be.utf8@euro': 'nl_BE.UTF-8', - 'nl_be@euro': 'nl_BE.ISO8859-15', 'nl_nl': 'nl_NL.ISO8859-1', - 'nl_nl.88591': 'nl_NL.ISO8859-1', - 'nl_nl.iso88591': 'nl_NL.ISO8859-1', - 'nl_nl.iso885915': 'nl_NL.ISO8859-15', - 'nl_nl.iso885915@euro': 'nl_NL.ISO8859-15', - 'nl_nl.utf8@euro': 'nl_NL.UTF-8', - 'nl_nl@euro': 'nl_NL.ISO8859-15', 'nn': 'nn_NO.ISO8859-1', 'nn_no': 'nn_NO.ISO8859-1', - 'nn_no.88591': 'nn_NO.ISO8859-1', - 'nn_no.iso88591': 'nn_NO.ISO8859-1', - 'nn_no.iso885915': 'nn_NO.ISO8859-15', - 'nn_no@euro': 'nn_NO.ISO8859-15', 'no': 'no_NO.ISO8859-1', 'no@nynorsk': 'ny_NO.ISO8859-1', 'no_no': 'no_NO.ISO8859-1', - 'no_no.88591': 'no_NO.ISO8859-1', - 'no_no.iso88591': 'no_NO.ISO8859-1', - 'no_no.iso885915': 'no_NO.ISO8859-15', 'no_no.iso88591@bokmal': 'no_NO.ISO8859-1', 'no_no.iso88591@nynorsk': 'no_NO.ISO8859-1', - 'no_no@euro': 'no_NO.ISO8859-15', 'norwegian': 'no_NO.ISO8859-1', - 'norwegian.iso88591': 'no_NO.ISO8859-1', 'nr': 'nr_ZA.ISO8859-1', 'nr_za': 'nr_ZA.ISO8859-1', - 'nr_za.iso88591': 'nr_ZA.ISO8859-1', 'nso': 'nso_ZA.ISO8859-15', 'nso_za': 'nso_ZA.ISO8859-15', - 'nso_za.iso885915': 'nso_ZA.ISO8859-15', 'ny': 'ny_NO.ISO8859-1', 'ny_no': 'ny_NO.ISO8859-1', - 'ny_no.88591': 'ny_NO.ISO8859-1', - 'ny_no.iso88591': 'ny_NO.ISO8859-1', - 'ny_no.iso885915': 'ny_NO.ISO8859-15', - 'ny_no@euro': 'ny_NO.ISO8859-15', 'nynorsk': 'nn_NO.ISO8859-1', 'oc': 'oc_FR.ISO8859-1', 'oc_fr': 'oc_FR.ISO8859-1', - 'oc_fr.iso88591': 'oc_FR.ISO8859-1', - 'oc_fr.iso885915': 'oc_FR.ISO8859-15', - 'oc_fr@euro': 'oc_FR.ISO8859-15', + 'om_et': 'om_ET.UTF-8', + 'om_ke': 'om_KE.ISO8859-1', 'or': 'or_IN.UTF-8', + 'or_in': 'or_IN.UTF-8', + 'os_ru': 'os_RU.UTF-8', 'pa': 'pa_IN.UTF-8', 'pa_in': 'pa_IN.UTF-8', + 'pa_pk': 'pa_PK.UTF-8', + 'pap_an': 'pap_AN.UTF-8', 'pd': 'pd_US.ISO8859-1', 'pd_de': 'pd_DE.ISO8859-1', - 'pd_de.iso88591': 'pd_DE.ISO8859-1', - 'pd_de.iso885915': 'pd_DE.ISO8859-15', - 'pd_de@euro': 'pd_DE.ISO8859-15', 'pd_us': 'pd_US.ISO8859-1', - 'pd_us.iso88591': 'pd_US.ISO8859-1', - 'pd_us.iso885915': 'pd_US.ISO8859-15', - 'pd_us@euro': 'pd_US.ISO8859-15', 'ph': 'ph_PH.ISO8859-1', 'ph_ph': 'ph_PH.ISO8859-1', - 'ph_ph.iso88591': 'ph_PH.ISO8859-1', 'pl': 'pl_PL.ISO8859-2', 'pl_pl': 'pl_PL.ISO8859-2', - 'pl_pl.iso88592': 'pl_PL.ISO8859-2', 'polish': 'pl_PL.ISO8859-2', 'portuguese': 'pt_PT.ISO8859-1', - 'portuguese.iso88591': 'pt_PT.ISO8859-1', 'portuguese_brazil': 'pt_BR.ISO8859-1', - 'portuguese_brazil.8859': 'pt_BR.ISO8859-1', 'posix': 'C', 'posix-utf2': 'C', 'pp': 'pp_AN.ISO8859-1', 'pp_an': 'pp_AN.ISO8859-1', - 'pp_an.iso88591': 'pp_AN.ISO8859-1', + 'ps_af': 'ps_AF.UTF-8', 'pt': 'pt_PT.ISO8859-1', - 'pt.iso885915': 'pt_PT.ISO8859-15', 'pt_br': 'pt_BR.ISO8859-1', - 'pt_br.88591': 'pt_BR.ISO8859-1', - 'pt_br.iso88591': 'pt_BR.ISO8859-1', - 'pt_br.iso885915': 'pt_BR.ISO8859-15', - 'pt_br@euro': 'pt_BR.ISO8859-15', 'pt_pt': 'pt_PT.ISO8859-1', - 'pt_pt.88591': 'pt_PT.ISO8859-1', - 'pt_pt.iso88591': 'pt_PT.ISO8859-1', - 'pt_pt.iso885915': 'pt_PT.ISO8859-15', - 'pt_pt.iso885915@euro': 'pt_PT.ISO8859-15', - 'pt_pt.utf8@euro': 'pt_PT.UTF-8', - 'pt_pt@euro': 'pt_PT.ISO8859-15', 'ro': 'ro_RO.ISO8859-2', 'ro_ro': 'ro_RO.ISO8859-2', - 'ro_ro.iso88592': 'ro_RO.ISO8859-2', 'romanian': 'ro_RO.ISO8859-2', 'ru': 'ru_RU.UTF-8', - 'ru.koi8r': 'ru_RU.KOI8-R', 'ru_ru': 'ru_RU.UTF-8', - 'ru_ru.cp1251': 'ru_RU.CP1251', - 'ru_ru.iso88595': 'ru_RU.ISO8859-5', - 'ru_ru.koi8r': 'ru_RU.KOI8-R', - 'ru_ru.microsoftcp1251': 'ru_RU.CP1251', 'ru_ua': 'ru_UA.KOI8-U', - 'ru_ua.cp1251': 'ru_UA.CP1251', - 'ru_ua.koi8u': 'ru_UA.KOI8-U', - 'ru_ua.microsoftcp1251': 'ru_UA.CP1251', 'rumanian': 'ro_RO.ISO8859-2', 'russian': 'ru_RU.ISO8859-5', 'rw': 'rw_RW.ISO8859-1', 'rw_rw': 'rw_RW.ISO8859-1', - 'rw_rw.iso88591': 'rw_RW.ISO8859-1', - 'sd': 'sd_IN@devanagari.UTF-8', + 'sa_in': 'sa_IN.UTF-8', + 'sat_in': 'sat_IN.UTF-8', + 'sc_it': 'sc_IT.UTF-8', + 'sd': 'sd_IN.UTF-8', + 'sd_in': 'sd_IN.UTF-8', + 'sd_in@devanagari.utf8': 'sd_IN.UTF-8@devanagari', + 'sd_pk': 'sd_PK.UTF-8', 'se_no': 'se_NO.UTF-8', 'serbocroatian': 'sr_RS.UTF-8@latin', 'sh': 'sr_RS.UTF-8@latin', @@ -1421,42 +1247,38 @@ def getpreferredencoding(do_setlocale = True): 'sh_hr.iso88592': 'hr_HR.ISO8859-2', 'sh_sp': 'sr_CS.ISO8859-2', 'sh_yu': 'sr_RS.UTF-8@latin', + 'shs_ca': 'shs_CA.UTF-8', 'si': 'si_LK.UTF-8', 'si_lk': 'si_LK.UTF-8', + 'sid_et': 'sid_ET.UTF-8', 'sinhala': 'si_LK.UTF-8', 'sk': 'sk_SK.ISO8859-2', 'sk_sk': 'sk_SK.ISO8859-2', - 'sk_sk.iso88592': 'sk_SK.ISO8859-2', 'sl': 'sl_SI.ISO8859-2', 'sl_cs': 'sl_CS.ISO8859-2', 'sl_si': 'sl_SI.ISO8859-2', - 'sl_si.iso88592': 'sl_SI.ISO8859-2', 'slovak': 'sk_SK.ISO8859-2', 'slovene': 'sl_SI.ISO8859-2', 'slovenian': 'sl_SI.ISO8859-2', + 'so_dj': 'so_DJ.ISO8859-1', + 'so_et': 'so_ET.UTF-8', + 'so_ke': 'so_KE.ISO8859-1', + 'so_so': 'so_SO.ISO8859-1', 'sp': 'sr_CS.ISO8859-5', 'sp_yu': 'sr_CS.ISO8859-5', 'spanish': 'es_ES.ISO8859-1', - 'spanish.iso88591': 'es_ES.ISO8859-1', 'spanish_spain': 'es_ES.ISO8859-1', - 'spanish_spain.8859': 'es_ES.ISO8859-1', 'sq': 'sq_AL.ISO8859-2', 'sq_al': 'sq_AL.ISO8859-2', - 'sq_al.iso88592': 'sq_AL.ISO8859-2', + 'sq_mk': 'sq_MK.UTF-8', 'sr': 'sr_RS.UTF-8', 'sr@cyrillic': 'sr_RS.UTF-8', - 'sr@latin': 'sr_RS.UTF-8@latin', - 'sr@latn': 'sr_RS.UTF-8@latin', - 'sr_cs': 'sr_RS.UTF-8', - 'sr_cs.iso88592': 'sr_CS.ISO8859-2', + 'sr@latn': 'sr_CS.UTF-8@latin', + 'sr_cs': 'sr_CS.UTF-8', 'sr_cs.iso88592@latn': 'sr_CS.ISO8859-2', - 'sr_cs.iso88595': 'sr_CS.ISO8859-5', - 'sr_cs.utf8@latn': 'sr_RS.UTF-8@latin', - 'sr_cs@latn': 'sr_RS.UTF-8@latin', + 'sr_cs@latn': 'sr_CS.UTF-8@latin', 'sr_me': 'sr_ME.UTF-8', 'sr_rs': 'sr_RS.UTF-8', - 'sr_rs.utf8@latn': 'sr_RS.UTF-8@latin', - 'sr_rs@latin': 'sr_RS.UTF-8@latin', 'sr_rs@latn': 'sr_RS.UTF-8@latin', 'sr_sp': 'sr_CS.ISO8859-2', 'sr_yu': 'sr_RS.UTF-8@latin', @@ -1465,78 +1287,64 @@ def getpreferredencoding(do_setlocale = True): 'sr_yu.iso88595': 'sr_CS.ISO8859-5', 'sr_yu.iso88595@cyrillic': 'sr_CS.ISO8859-5', 'sr_yu.microsoftcp1251@cyrillic': 'sr_CS.CP1251', + 'sr_yu.utf8': 'sr_RS.UTF-8', 'sr_yu.utf8@cyrillic': 'sr_RS.UTF-8', 'sr_yu@cyrillic': 'sr_RS.UTF-8', 'ss': 'ss_ZA.ISO8859-1', 'ss_za': 'ss_ZA.ISO8859-1', - 'ss_za.iso88591': 'ss_ZA.ISO8859-1', 'st': 'st_ZA.ISO8859-1', 'st_za': 'st_ZA.ISO8859-1', - 'st_za.iso88591': 'st_ZA.ISO8859-1', 'sv': 'sv_SE.ISO8859-1', - 'sv.iso885915': 'sv_SE.ISO8859-15', 'sv_fi': 'sv_FI.ISO8859-1', - 'sv_fi.iso88591': 'sv_FI.ISO8859-1', - 'sv_fi.iso885915': 'sv_FI.ISO8859-15', - 'sv_fi.iso885915@euro': 'sv_FI.ISO8859-15', - 'sv_fi.utf8@euro': 'sv_FI.UTF-8', - 'sv_fi@euro': 'sv_FI.ISO8859-15', 'sv_se': 'sv_SE.ISO8859-1', - 'sv_se.88591': 'sv_SE.ISO8859-1', - 'sv_se.iso88591': 'sv_SE.ISO8859-1', - 'sv_se.iso885915': 'sv_SE.ISO8859-15', - 'sv_se@euro': 'sv_SE.ISO8859-15', + 'sw_ke': 'sw_KE.UTF-8', + 'sw_tz': 'sw_TZ.UTF-8', 'swedish': 'sv_SE.ISO8859-1', - 'swedish.iso88591': 'sv_SE.ISO8859-1', + 'szl_pl': 'szl_PL.UTF-8', 'ta': 'ta_IN.TSCII-0', 'ta_in': 'ta_IN.TSCII-0', 'ta_in.tscii': 'ta_IN.TSCII-0', 'ta_in.tscii0': 'ta_IN.TSCII-0', + 'ta_lk': 'ta_LK.UTF-8', 'te': 'te_IN.UTF-8', + 'te_in': 'te_IN.UTF-8', 'tg': 'tg_TJ.KOI8-C', 'tg_tj': 'tg_TJ.KOI8-C', - 'tg_tj.koi8c': 'tg_TJ.KOI8-C', 'th': 'th_TH.ISO8859-11', 'th_th': 'th_TH.ISO8859-11', - 'th_th.iso885911': 'th_TH.ISO8859-11', 'th_th.tactis': 'th_TH.TIS620', 'th_th.tis620': 'th_TH.TIS620', 'thai': 'th_TH.ISO8859-11', + 'ti_er': 'ti_ER.UTF-8', + 'ti_et': 'ti_ET.UTF-8', + 'tig_er': 'tig_ER.UTF-8', + 'tk_tm': 'tk_TM.UTF-8', 'tl': 'tl_PH.ISO8859-1', 'tl_ph': 'tl_PH.ISO8859-1', - 'tl_ph.iso88591': 'tl_PH.ISO8859-1', 'tn': 'tn_ZA.ISO8859-15', 'tn_za': 'tn_ZA.ISO8859-15', - 'tn_za.iso885915': 'tn_ZA.ISO8859-15', 'tr': 'tr_TR.ISO8859-9', + 'tr_cy': 'tr_CY.ISO8859-9', 'tr_tr': 'tr_TR.ISO8859-9', - 'tr_tr.iso88599': 'tr_TR.ISO8859-9', 'ts': 'ts_ZA.ISO8859-1', 'ts_za': 'ts_ZA.ISO8859-1', - 'ts_za.iso88591': 'ts_ZA.ISO8859-1', 'tt': 'tt_RU.TATAR-CYR', 'tt_ru': 'tt_RU.TATAR-CYR', - 'tt_ru.koi8c': 'tt_RU.KOI8-C', 'tt_ru.tatarcyr': 'tt_RU.TATAR-CYR', + 'tt_ru@iqtelif': 'tt_RU.UTF-8@iqtelif', 'turkish': 'tr_TR.ISO8859-9', - 'turkish.iso88599': 'tr_TR.ISO8859-9', + 'ug_cn': 'ug_CN.UTF-8', 'uk': 'uk_UA.KOI8-U', 'uk_ua': 'uk_UA.KOI8-U', - 'uk_ua.cp1251': 'uk_UA.CP1251', - 'uk_ua.iso88595': 'uk_UA.ISO8859-5', - 'uk_ua.koi8u': 'uk_UA.KOI8-U', - 'uk_ua.microsoftcp1251': 'uk_UA.CP1251', 'univ': 'en_US.utf', 'universal': 'en_US.utf', 'universal.utf8@ucs4': 'en_US.UTF-8', + 'unm_us': 'unm_US.UTF-8', 'ur': 'ur_PK.CP1256', + 'ur_in': 'ur_IN.UTF-8', 'ur_pk': 'ur_PK.CP1256', - 'ur_pk.cp1256': 'ur_PK.CP1256', - 'ur_pk.microsoftcp1256': 'ur_PK.CP1256', 'uz': 'uz_UZ.UTF-8', 'uz_uz': 'uz_UZ.UTF-8', - 'uz_uz.iso88591': 'uz_UZ.ISO8859-1', - 'uz_uz.utf8@cyrillic': 'uz_UZ.UTF-8', 'uz_uz@cyrillic': 'uz_UZ.UTF-8', 've': 've_ZA.UTF-8', 've_za': 've_ZA.UTF-8', @@ -1548,35 +1356,28 @@ def getpreferredencoding(do_setlocale = True): 'vi_vn.viscii111': 'vi_VN.VISCII', 'wa': 'wa_BE.ISO8859-1', 'wa_be': 'wa_BE.ISO8859-1', - 'wa_be.iso88591': 'wa_BE.ISO8859-1', - 'wa_be.iso885915': 'wa_BE.ISO8859-15', - 'wa_be.iso885915@euro': 'wa_BE.ISO8859-15', - 'wa_be@euro': 'wa_BE.ISO8859-15', + 'wae_ch': 'wae_CH.UTF-8', + 'wal_et': 'wal_ET.UTF-8', + 'wo_sn': 'wo_SN.UTF-8', 'xh': 'xh_ZA.ISO8859-1', 'xh_za': 'xh_ZA.ISO8859-1', - 'xh_za.iso88591': 'xh_ZA.ISO8859-1', 'yi': 'yi_US.CP1255', 'yi_us': 'yi_US.CP1255', - 'yi_us.cp1255': 'yi_US.CP1255', - 'yi_us.microsoftcp1255': 'yi_US.CP1255', + 'yo_ng': 'yo_NG.UTF-8', + 'yue_hk': 'yue_HK.UTF-8', 'zh': 'zh_CN.eucCN', 'zh_cn': 'zh_CN.gb2312', 'zh_cn.big5': 'zh_TW.big5', 'zh_cn.euc': 'zh_CN.eucCN', - 'zh_cn.gb18030': 'zh_CN.gb18030', - 'zh_cn.gb2312': 'zh_CN.gb2312', - 'zh_cn.gbk': 'zh_CN.gbk', 'zh_hk': 'zh_HK.big5hkscs', - 'zh_hk.big5': 'zh_HK.big5', 'zh_hk.big5hk': 'zh_HK.big5hkscs', - 'zh_hk.big5hkscs': 'zh_HK.big5hkscs', + 'zh_sg': 'zh_SG.GB2312', + 'zh_sg.gbk': 'zh_SG.GBK', 'zh_tw': 'zh_TW.big5', - 'zh_tw.big5': 'zh_TW.big5', 'zh_tw.euc': 'zh_TW.eucTW', 'zh_tw.euctw': 'zh_TW.eucTW', 'zu': 'zu_ZA.ISO8859-1', 'zu_za': 'zu_ZA.ISO8859-1', - 'zu_za.iso88591': 'zu_ZA.ISO8859-1', } # diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 9b41b9d2779e..104b0be8d07c 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2001-2013 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2015 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, @@ -18,12 +18,13 @@ Logging package for Python. Based on PEP 282 and comments thereto in comp.lang.python. -Copyright (C) 2001-2013 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2015 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ -import sys, os, time, io, traceback, warnings, weakref +import sys, os, time, io, traceback, warnings, weakref, collections + from string import Template __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', @@ -42,6 +43,7 @@ __author__ = "Vinay Sajip " __status__ = "production" +# The following module attributes are no longer updated. __version__ = "0.5.1.2" __date__ = "07 February 2010" @@ -49,34 +51,6 @@ # Miscellaneous module data #--------------------------------------------------------------------------- -# -# _srcfile is used when walking the stack to check when we've got the first -# caller stack frame. -# -if hasattr(sys, 'frozen'): #support for py2exe - _srcfile = "logging%s__init__%s" % (os.sep, __file__[-4:]) -else: - _srcfile = __file__ -_srcfile = os.path.normcase(_srcfile) - - -if hasattr(sys, '_getframe'): - currentframe = lambda: sys._getframe(3) -else: #pragma: no cover - def currentframe(): - """Return the frame object for the caller's stack frame.""" - try: - raise Exception - except Exception: - return sys.exc_info()[2].tb_frame.f_back - -# _srcfile is only used in conjunction with sys._getframe(). -# To provide compatibility with older versions of Python, set _srcfile -# to None if _getframe() is not available; this value will prevent -# findCaller() from being called. -#if not hasattr(sys, "_getframe"): -# _srcfile = None - # #_startTime is used as the base when calculating the relative time of events # @@ -155,7 +129,8 @@ def getLevelName(level): Otherwise, the string "Level %s" % level is returned. """ - return _levelToName.get(level, ("Level %s" % level)) + # See Issue #22386 for the reason for this convoluted expression + return _levelToName.get(level, _nameToLevel.get(level, ("Level %s" % level))) def addLevelName(level, levelName): """ @@ -170,6 +145,40 @@ def addLevelName(level, levelName): finally: _releaseLock() +if hasattr(sys, '_getframe'): + currentframe = lambda: sys._getframe(3) +else: #pragma: no cover + def currentframe(): + """Return the frame object for the caller's stack frame.""" + try: + raise Exception + except Exception: + return sys.exc_info()[2].tb_frame.f_back + +# +# _srcfile is used when walking the stack to check when we've got the first +# caller stack frame, by skipping frames whose filename is that of this +# module's source. It therefore should contain the filename of this module's +# source file. +# +# Ordinarily we would use __file__ for this, but frozen modules don't always +# have __file__ set, for some reason (see Issue #21736). Thus, we get the +# filename from a handy code object from a function defined in this module. +# (There's no particular reason for picking addLevelName.) +# + +_srcfile = os.path.normcase(addLevelName.__code__.co_filename) + +# _srcfile is only used in conjunction with sys._getframe(). +# To provide compatibility with older versions of Python, set _srcfile +# to None if _getframe() is not available; this value will prevent +# findCaller() from being called. You can also do this if you want to avoid +# the overhead of fetching caller information, even when _getframe() is +# available. +#if not hasattr(sys, '_getframe'): +# _srcfile = None + + def _checkLevel(level): if isinstance(level, int): rv = level @@ -252,7 +261,13 @@ def __init__(self, name, level, pathname, lineno, # 'Value is %d' instead of 'Value is 0'. # For the use case of passing a dictionary, this should not be a # problem. - if args and len(args) == 1 and isinstance(args[0], dict) and args[0]: + # Issue #21172: a request was made to relax the isinstance check + # to hasattr(args[0], '__getitem__'). However, the docs on string + # formatting still seem to suggest a mapping object is required. + # Thus, while not removing the isinstance check, it does now look + # for collections.Mapping rather than, as before, dict. + if (args and len(args) == 1 and isinstance(args[0], collections.Mapping) + and args[0]): args = args[0] self.args = args self.levelname = getLevelName(level) @@ -301,6 +316,8 @@ def __str__(self): return ''%(self.name, self.levelno, self.pathname, self.lineno, self.msg) + __repr__ = __str__ + def getMessage(self): """ Return the message for this LogRecord. @@ -390,10 +407,12 @@ def usesTime(self): def format(self, record): return self._tpl.substitute(**record.__dict__) +BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s" + _STYLES = { - '%': PercentStyle, - '{': StrFormatStyle, - '$': StringTemplateStyle + '%': (PercentStyle, BASIC_FORMAT), + '{': (StrFormatStyle, '{levelname}:{name}:{message}'), + '$': (StringTemplateStyle, '${levelname}:${name}:${message}'), } class Formatter(object): @@ -458,7 +477,7 @@ def __init__(self, fmt=None, datefmt=None, style='%'): if style not in _STYLES: raise ValueError('Style must be one of: %s' % ','.join( _STYLES.keys())) - self._style = _STYLES[style](fmt) + self._style = _STYLES[style][0](fmt) self._fmt = self._style._fmt self.datefmt = datefmt @@ -708,16 +727,17 @@ def _removeHandlerRef(wr): Remove a handler reference from the internal cleanup list. """ # This function can be called during module teardown, when globals are - # set to None. If _acquireLock is None, assume this is the case and do - # nothing. - if (_acquireLock is not None and _handlerList is not None and - _releaseLock is not None): - _acquireLock() + # set to None. It can also be called from another thread. So we need to + # pre-emptively grab the necessary globals and check if they're None, + # to prevent race conditions and failures during interpreter shutdown. + acquire, release, handlers = _acquireLock, _releaseLock, _handlerList + if acquire and release and handlers: + acquire() try: - if wr in _handlerList: - _handlerList.remove(wr) + if wr in handlers: + handlers.remove(wr) finally: - _releaseLock() + release() def _addHandlerRef(handler): """ @@ -900,8 +920,15 @@ def handleError(self, record): sys.stderr.write('Logged from file %s, line %s\n' % ( record.filename, record.lineno)) # Issue 18671: output logging message and arguments - sys.stderr.write('Message: %r\n' - 'Arguments: %s\n' % (record.msg, record.args)) + try: + sys.stderr.write('Message: %r\n' + 'Arguments: %s\n' % (record.msg, + record.args)) + except Exception: + sys.stderr.write('Unable to print the message and arguments' + ' - possible formatting error.\nUse the' + ' traceback above to help find the error.\n' + ) except OSError: #pragma: no cover pass # see issue 5971 finally: @@ -986,14 +1013,19 @@ def close(self): """ self.acquire() try: - if self.stream: - self.flush() - if hasattr(self.stream, "close"): - self.stream.close() - self.stream = None - # Issue #19523: call unconditionally to - # prevent a handler leak when delay is set - StreamHandler.close(self) + try: + if self.stream: + try: + self.flush() + finally: + stream = self.stream + self.stream = None + if hasattr(stream, "close"): + stream.close() + finally: + # Issue #19523: call unconditionally to + # prevent a handler leak when delay is set + StreamHandler.close(self) finally: self.release() @@ -1061,7 +1093,6 @@ def append(self, alogger): # # Determine which class to use when instantiating loggers. # -_loggerClass = None def setLoggerClass(klass): """ @@ -1080,7 +1111,6 @@ def getLoggerClass(): """ Return the class to be used when instantiating a logger. """ - return _loggerClass class Manager(object): @@ -1277,12 +1307,11 @@ def error(self, msg, *args, **kwargs): if self.isEnabledFor(ERROR): self._log(ERROR, msg, args, **kwargs) - def exception(self, msg, *args, **kwargs): + def exception(self, msg, *args, exc_info=True, **kwargs): """ Convenience method for logging an ERROR with exception information. """ - kwargs['exc_info'] = True - self.error(msg, *args, **kwargs) + self.error(msg, *args, exc_info=exc_info, **kwargs) def critical(self, msg, *args, **kwargs): """ @@ -1377,7 +1406,9 @@ def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False): else: # pragma: no cover fn, lno, func = "(unknown file)", 0, "(unknown function)" if exc_info: - if not isinstance(exc_info, tuple): + if isinstance(exc_info, BaseException): + exc_info = (type(exc_info), exc_info, exc_info.__traceback__) + elif not isinstance(exc_info, tuple): exc_info = sys.exc_info() record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra, sinfo) @@ -1587,12 +1618,11 @@ def error(self, msg, *args, **kwargs): """ self.log(ERROR, msg, *args, **kwargs) - def exception(self, msg, *args, **kwargs): + def exception(self, msg, *args, exc_info=True, **kwargs): """ Delegate an exception call to the underlying logger. """ - kwargs["exc_info"] = True - self.log(ERROR, msg, *args, **kwargs) + self.log(ERROR, msg, *args, exc_info=exc_info, **kwargs) def critical(self, msg, *args, **kwargs): """ @@ -1643,8 +1673,6 @@ def hasHandlers(self): # Configuration classes and functions #--------------------------------------------------------------------------- -BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s" - def basicConfig(**kwargs): """ Do basic configuration for the logging system. @@ -1700,7 +1728,7 @@ def basicConfig(**kwargs): _acquireLock() try: if len(root.handlers) == 0: - handlers = kwargs.get("handlers") + handlers = kwargs.pop("handlers", None) if handlers is None: if "stream" in kwargs and "filename" in kwargs: raise ValueError("'stream' and 'filename' should not be " @@ -1710,25 +1738,31 @@ def basicConfig(**kwargs): raise ValueError("'stream' or 'filename' should not be " "specified together with 'handlers'") if handlers is None: - filename = kwargs.get("filename") + filename = kwargs.pop("filename", None) + mode = kwargs.pop("filemode", 'a') if filename: - mode = kwargs.get("filemode", 'a') h = FileHandler(filename, mode) else: - stream = kwargs.get("stream") + stream = kwargs.pop("stream", None) h = StreamHandler(stream) handlers = [h] - fs = kwargs.get("format", BASIC_FORMAT) - dfs = kwargs.get("datefmt", None) - style = kwargs.get("style", '%') + dfs = kwargs.pop("datefmt", None) + style = kwargs.pop("style", '%') + if style not in _STYLES: + raise ValueError('Style must be one of: %s' % ','.join( + _STYLES.keys())) + fs = kwargs.pop("format", _STYLES[style][1]) fmt = Formatter(fs, dfs, style) for h in handlers: if h.formatter is None: h.setFormatter(fmt) root.addHandler(h) - level = kwargs.get("level") + level = kwargs.pop("level", None) if level is not None: root.setLevel(level) + if kwargs: + keys = ', '.join(kwargs.keys()) + raise ValueError('Unrecognised argument(s): %s' % keys) finally: _releaseLock() @@ -1770,14 +1804,13 @@ def error(msg, *args, **kwargs): basicConfig() root.error(msg, *args, **kwargs) -def exception(msg, *args, **kwargs): +def exception(msg, *args, exc_info=True, **kwargs): """ Log a message with severity 'ERROR' on the root logger, with exception information. If the logger has no handlers, basicConfig() is called to add a console handler with a pre-defined format. """ - kwargs['exc_info'] = True - error(msg, *args, **kwargs) + error(msg, *args, exc_info=exc_info, **kwargs) def warning(msg, *args, **kwargs): """ diff --git a/Lib/logging/config.py b/Lib/logging/config.py index b882a62ab3e6..8a99923bf31e 100644 --- a/Lib/logging/config.py +++ b/Lib/logging/config.py @@ -1,4 +1,4 @@ -# Copyright 2001-2013 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2014 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, @@ -19,13 +19,19 @@ is based on PEP 282 and comments thereto in comp.lang.python, and influenced by Apache's log4j system. -Copyright (C) 2001-2013 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2014 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ -import sys, logging, logging.handlers, socket, struct, traceback, re +import errno import io +import logging +import logging.handlers +import re +import struct +import sys +import traceback try: import _thread as thread @@ -38,10 +44,7 @@ DEFAULT_LOGGING_CONFIG_PORT = 9030 -if sys.platform == "win32": - RESET_ERROR = 10054 #WSAECONNRESET -else: - RESET_ERROR = 104 #ECONNRESET +RESET_ERROR = errno.ECONNRESET # # The following code implements a socket listener for on-the-fly @@ -113,11 +116,12 @@ def _create_formatters(cp): sectname = "formatter_%s" % form fs = cp.get(sectname, "format", raw=True, fallback=None) dfs = cp.get(sectname, "datefmt", raw=True, fallback=None) + stl = cp.get(sectname, "style", raw=True, fallback='%') c = logging.Formatter class_name = cp[sectname].get("class") if class_name: c = _resolve(class_name) - f = c(fs, dfs) + f = c(fs, dfs, stl) formatters[form] = f return formatters @@ -274,6 +278,30 @@ def valid_ident(s): return True +class ConvertingMixin(object): + """For ConvertingXXX's, this mixin class provides common functions""" + + def convert_with_key(self, key, value, replace=True): + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + if replace: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def convert(self, value): + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + return result + + # The ConvertingXXX classes are wrappers around standard Python containers, # and they serve to convert any suitable values in the container. The # conversion converts base dicts, lists and tuples to their wrapped @@ -283,77 +311,37 @@ def valid_ident(s): # Each wrapper should have a configurator attribute holding the actual # configurator to use for conversion. -class ConvertingDict(dict): +class ConvertingDict(dict, ConvertingMixin): """A converting dictionary wrapper.""" def __getitem__(self, key): value = dict.__getitem__(self, key) - result = self.configurator.convert(value) - #If the converted value is different, save for next time - if value is not result: - self[key] = result - if type(result) in (ConvertingDict, ConvertingList, - ConvertingTuple): - result.parent = self - result.key = key - return result + return self.convert_with_key(key, value) def get(self, key, default=None): value = dict.get(self, key, default) - result = self.configurator.convert(value) - #If the converted value is different, save for next time - if value is not result: - self[key] = result - if type(result) in (ConvertingDict, ConvertingList, - ConvertingTuple): - result.parent = self - result.key = key - return result + return self.convert_with_key(key, value) def pop(self, key, default=None): value = dict.pop(self, key, default) - result = self.configurator.convert(value) - if value is not result: - if type(result) in (ConvertingDict, ConvertingList, - ConvertingTuple): - result.parent = self - result.key = key - return result + return self.convert_with_key(key, value, replace=False) -class ConvertingList(list): +class ConvertingList(list, ConvertingMixin): """A converting list wrapper.""" def __getitem__(self, key): value = list.__getitem__(self, key) - result = self.configurator.convert(value) - #If the converted value is different, save for next time - if value is not result: - self[key] = result - if type(result) in (ConvertingDict, ConvertingList, - ConvertingTuple): - result.parent = self - result.key = key - return result + return self.convert_with_key(key, value) def pop(self, idx=-1): value = list.pop(self, idx) - result = self.configurator.convert(value) - if value is not result: - if type(result) in (ConvertingDict, ConvertingList, - ConvertingTuple): - result.parent = self - return result + return self.convert(value) -class ConvertingTuple(tuple): +class ConvertingTuple(tuple, ConvertingMixin): """A converting tuple wrapper.""" def __getitem__(self, key): value = tuple.__getitem__(self, key) - result = self.configurator.convert(value) - if value is not result: - if type(result) in (ConvertingDict, ConvertingList, - ConvertingTuple): - result.parent = self - result.key = key - return result + # Can't replace a tuple entry. + return self.convert_with_key(key, value, replace=False) class BaseConfigurator(object): """ @@ -673,7 +661,12 @@ def configure_formatter(self, config): fmt = config.get('format', None) dfmt = config.get('datefmt', None) style = config.get('style', '%') - result = logging.Formatter(fmt, dfmt, style) + cname = config.get('class', None) + if not cname: + c = logging.Formatter + else: + c = _resolve(cname) + result = c(fmt, dfmt, style) return result def configure_filter(self, config): @@ -867,12 +860,8 @@ def handle(self): if self.server.ready: self.server.ready.set() except OSError as e: - if not isinstance(e.args, tuple): + if e.errno != RESET_ERROR: raise - else: - errcode = e.args[0] - if errcode != RESET_ERROR: - raise class ConfigSocketReceiver(ThreadingTCPServer): """ diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index b2e7d445cf9a..fba04f12297b 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -1,4 +1,4 @@ -# Copyright 2001-2013 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2015 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, @@ -18,13 +18,12 @@ Additional handlers for the logging package for Python. The core package is based on PEP 282 and comments thereto in comp.lang.python. -Copyright (C) 2001-2013 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2015 Vinay Sajip. All Rights Reserved. To use, simply 'import logging.handlers' and log away! """ -import errno, logging, socket, os, pickle, struct, time, re -from codecs import BOM_UTF8 +import logging, socket, os, pickle, struct, time, re from stat import ST_DEV, ST_INO, ST_MTIME import queue try: @@ -441,11 +440,11 @@ def _statstream(self): sres = os.fstat(self.stream.fileno()) self.dev, self.ino = sres[ST_DEV], sres[ST_INO] - def emit(self, record): + def reopenIfNeeded(self): """ - Emit a record. + Reopen log file if needed. - First check if the underlying file has changed, and if it + Checks if the underlying file has changed, and if it has, close the old stream and reopen the file to get the current stream. """ @@ -464,9 +463,19 @@ def emit(self, record): # we have an open file handle, clean it up self.stream.flush() self.stream.close() + self.stream = None # See Issue #21742: _open () might fail. # open a new file handle and get new stat info from that fd self.stream = self._open() self._statstream() + + def emit(self, record): + """ + Emit a record. + + If underlying file has changed, reopen the file before emitting the + record to it. + """ + self.reopenIfNeeded() logging.FileHandler.emit(self, record) @@ -627,9 +636,10 @@ def close(self): """ self.acquire() try: - if self.sock: - self.sock.close() + sock = self.sock + if sock: self.sock = None + sock.close() logging.Handler.close(self) finally: self.release() @@ -879,21 +889,21 @@ def emit(self, record): The record is formatted, and then sent to the syslog server. If exception information is present, it is NOT sent to the server. """ - msg = self.format(record) - if self.ident: - msg = self.ident + msg - if self.append_nul: - msg += '\000' - - # We need to convert record level to lowercase, maybe this will - # change in the future. - prio = '<%d>' % self.encodePriority(self.facility, - self.mapPriority(record.levelname)) - prio = prio.encode('utf-8') - # Message is a string. Convert to bytes as required by RFC 5424 - msg = msg.encode('utf-8') - msg = prio + msg try: + msg = self.format(record) + if self.ident: + msg = self.ident + msg + if self.append_nul: + msg += '\000' + + # We need to convert record level to lowercase, maybe this will + # change in the future. + prio = '<%d>' % self.encodePriority(self.facility, + self.mapPriority(record.levelname)) + prio = prio.encode('utf-8') + # Message is a string. Convert to bytes as required by RFC 5424 + msg = msg.encode('utf-8') + msg = prio + msg if self.unixsocket: try: self.socket.send(msg) @@ -931,11 +941,11 @@ def __init__(self, mailhost, fromaddr, toaddrs, subject, default is one second). """ logging.Handler.__init__(self) - if isinstance(mailhost, tuple): + if isinstance(mailhost, (list, tuple)): self.mailhost, self.mailport = mailhost else: self.mailhost, self.mailport = mailhost, None - if isinstance(credentials, tuple): + if isinstance(credentials, (list, tuple)): self.username, self.password = credentials else: self.username = None @@ -964,24 +974,26 @@ def emit(self, record): """ try: import smtplib - from email.utils import formatdate + from email.message import EmailMessage + import email.utils + port = self.mailport if not port: port = smtplib.SMTP_PORT smtp = smtplib.SMTP(self.mailhost, port, timeout=self.timeout) - msg = self.format(record) - msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\nDate: %s\r\n\r\n%s" % ( - self.fromaddr, - ",".join(self.toaddrs), - self.getSubject(record), - formatdate(), msg) + msg = EmailMessage() + msg['From'] = self.fromaddr + msg['To'] = ','.join(self.toaddrs) + msg['Subject'] = self.getSubject(record) + msg['Date'] = email.utils.localtime() + msg.set_content(self.format(record)) if self.username: if self.secure is not None: smtp.ehlo() smtp.starttls(*self.secure) smtp.ehlo() smtp.login(self.username, self.password) - smtp.sendmail(self.fromaddr, self.toaddrs, msg) + smtp.send_message(msg) smtp.quit() except Exception: self.handleError(record) @@ -1089,7 +1101,8 @@ class HTTPHandler(logging.Handler): A class which sends records to a Web server, using either GET or POST semantics. """ - def __init__(self, host, url, method="GET", secure=False, credentials=None): + def __init__(self, host, url, method="GET", secure=False, credentials=None, + context=None): """ Initialize the instance with the host, the request URL, and the method ("GET" or "POST") @@ -1098,11 +1111,15 @@ def __init__(self, host, url, method="GET", secure=False, credentials=None): method = method.upper() if method not in ["GET", "POST"]: raise ValueError("method must be GET or POST") + if not secure and context is not None: + raise ValueError("context parameter only makes sense " + "with secure=True") self.host = host self.url = url self.method = method self.secure = secure self.credentials = credentials + self.context = context def mapLogRecord(self, record): """ @@ -1122,7 +1139,7 @@ def emit(self, record): import http.client, urllib.parse host = self.host if self.secure: - h = http.client.HTTPSConnection(host) + h = http.client.HTTPSConnection(host, context=self.context) else: h = http.client.HTTPConnection(host) url = self.url @@ -1208,8 +1225,10 @@ def close(self): This version just flushes and chains to the parent class' close(). """ - self.flush() - logging.Handler.close(self) + try: + self.flush() + finally: + logging.Handler.close(self) class MemoryHandler(BufferingHandler): """ @@ -1263,13 +1282,15 @@ def close(self): """ Flush, set the target to None and lose the buffer. """ - self.flush() - self.acquire() try: - self.target = None - BufferingHandler.close(self) + self.flush() finally: - self.release() + self.acquire() + try: + self.target = None + BufferingHandler.close(self) + finally: + self.release() class QueueHandler(logging.Handler): @@ -1345,7 +1366,7 @@ class QueueListener(object): """ _sentinel = None - def __init__(self, queue, *handlers): + def __init__(self, queue, *handlers, respect_handler_level=False): """ Initialise an instance with the specified queue and handlers. @@ -1354,6 +1375,7 @@ def __init__(self, queue, *handlers): self.handlers = handlers self._stop = threading.Event() self._thread = None + self.respect_handler_level = respect_handler_level def dequeue(self, block): """ @@ -1394,7 +1416,12 @@ def handle(self, record): """ record = self.prepare(record) for handler in self.handlers: - handler.handle(record) + if not self.respect_handler_level: + process = True + else: + process = record.levelno >= handler.level + if process: + handler.handle(record) def _monitor(self): """ diff --git a/Lib/lzma.py b/Lib/lzma.py index 011ad271fbb0..89528b60ce7c 100644 --- a/Lib/lzma.py +++ b/Lib/lzma.py @@ -25,17 +25,16 @@ import io from _lzma import * from _lzma import _encode_filter_properties, _decode_filter_properties +import _compression _MODE_CLOSED = 0 _MODE_READ = 1 -_MODE_READ_EOF = 2 +# Value 2 no longer used _MODE_WRITE = 3 -_BUFFER_SIZE = 8192 - -class LZMAFile(io.BufferedIOBase): +class LZMAFile(_compression.BaseStream): """A file object providing transparent LZMA (de)compression. @@ -92,8 +91,6 @@ def __init__(self, filename=None, mode="r", *, self._fp = None self._closefp = False self._mode = _MODE_CLOSED - self._pos = 0 - self._size = -1 if mode in ("r", "rb"): if check != -1: @@ -105,19 +102,13 @@ def __init__(self, filename=None, mode="r", *, if format is None: format = FORMAT_AUTO mode_code = _MODE_READ - # Save the args to pass to the LZMADecompressor initializer. - # If the file contains multiple compressed streams, each - # stream will need a separate decompressor object. - self._init_args = {"format":format, "filters":filters} - self._decompressor = LZMADecompressor(**self._init_args) - self._buffer = b"" - self._buffer_offset = 0 elif mode in ("w", "wb", "a", "ab", "x", "xb"): if format is None: format = FORMAT_XZ mode_code = _MODE_WRITE self._compressor = LZMACompressor(format=format, check=check, preset=preset, filters=filters) + self._pos = 0 else: raise ValueError("Invalid mode: {!r}".format(mode)) @@ -133,6 +124,11 @@ def __init__(self, filename=None, mode="r", *, else: raise TypeError("filename must be a str or bytes object, or a file") + if self._mode == _MODE_READ: + raw = _compression.DecompressReader(self._fp, LZMADecompressor, + trailing_error=LZMAError, format=format, filters=filters) + self._buffer = io.BufferedReader(raw) + def close(self): """Flush and close the file. @@ -142,9 +138,9 @@ def close(self): if self._mode == _MODE_CLOSED: return try: - if self._mode in (_MODE_READ, _MODE_READ_EOF): - self._decompressor = None - self._buffer = b"" + if self._mode == _MODE_READ: + self._buffer.close() + self._buffer = None elif self._mode == _MODE_WRITE: self._fp.write(self._compressor.flush()) self._compressor = None @@ -169,116 +165,18 @@ def fileno(self): def seekable(self): """Return whether the file supports seeking.""" - return self.readable() and self._fp.seekable() + return self.readable() and self._buffer.seekable() def readable(self): """Return whether the file was opened for reading.""" self._check_not_closed() - return self._mode in (_MODE_READ, _MODE_READ_EOF) + return self._mode == _MODE_READ def writable(self): """Return whether the file was opened for writing.""" self._check_not_closed() return self._mode == _MODE_WRITE - # Mode-checking helper functions. - - def _check_not_closed(self): - if self.closed: - raise ValueError("I/O operation on closed file") - - def _check_can_read(self): - if self._mode not in (_MODE_READ, _MODE_READ_EOF): - self._check_not_closed() - raise io.UnsupportedOperation("File not open for reading") - - def _check_can_write(self): - if self._mode != _MODE_WRITE: - self._check_not_closed() - raise io.UnsupportedOperation("File not open for writing") - - def _check_can_seek(self): - if self._mode not in (_MODE_READ, _MODE_READ_EOF): - self._check_not_closed() - raise io.UnsupportedOperation("Seeking is only supported " - "on files open for reading") - if not self._fp.seekable(): - raise io.UnsupportedOperation("The underlying file object " - "does not support seeking") - - # Fill the readahead buffer if it is empty. Returns False on EOF. - def _fill_buffer(self): - if self._mode == _MODE_READ_EOF: - return False - # Depending on the input data, our call to the decompressor may not - # return any data. In this case, try again after reading another block. - while self._buffer_offset == len(self._buffer): - rawblock = (self._decompressor.unused_data or - self._fp.read(_BUFFER_SIZE)) - - if not rawblock: - if self._decompressor.eof: - self._mode = _MODE_READ_EOF - self._size = self._pos - return False - else: - raise EOFError("Compressed file ended before the " - "end-of-stream marker was reached") - - # Continue to next stream. - if self._decompressor.eof: - self._decompressor = LZMADecompressor(**self._init_args) - - self._buffer = self._decompressor.decompress(rawblock) - self._buffer_offset = 0 - return True - - # Read data until EOF. - # If return_data is false, consume the data without returning it. - def _read_all(self, return_data=True): - # The loop assumes that _buffer_offset is 0. Ensure that this is true. - self._buffer = self._buffer[self._buffer_offset:] - self._buffer_offset = 0 - - blocks = [] - while self._fill_buffer(): - if return_data: - blocks.append(self._buffer) - self._pos += len(self._buffer) - self._buffer = b"" - if return_data: - return b"".join(blocks) - - # Read a block of up to n bytes. - # If return_data is false, consume the data without returning it. - def _read_block(self, n, return_data=True): - # If we have enough data buffered, return immediately. - end = self._buffer_offset + n - if end <= len(self._buffer): - data = self._buffer[self._buffer_offset : end] - self._buffer_offset = end - self._pos += len(data) - return data if return_data else None - - # The loop assumes that _buffer_offset is 0. Ensure that this is true. - self._buffer = self._buffer[self._buffer_offset:] - self._buffer_offset = 0 - - blocks = [] - while n > 0 and self._fill_buffer(): - if n < len(self._buffer): - data = self._buffer[:n] - self._buffer_offset = n - else: - data = self._buffer - self._buffer = b"" - if return_data: - blocks.append(data) - self._pos += len(data) - n -= len(data) - if return_data: - return b"".join(blocks) - def peek(self, size=-1): """Return buffered data without advancing the file position. @@ -286,9 +184,9 @@ def peek(self, size=-1): The exact number of bytes returned is unspecified. """ self._check_can_read() - if not self._fill_buffer(): - return b"" - return self._buffer[self._buffer_offset:] + # Relies on the undocumented fact that BufferedReader.peek() always + # returns at least one byte (except at EOF) + return self._buffer.peek(size) def read(self, size=-1): """Read up to size uncompressed bytes from the file. @@ -297,38 +195,19 @@ def read(self, size=-1): Returns b"" if the file is already at EOF. """ self._check_can_read() - if size == 0: - return b"" - elif size < 0: - return self._read_all() - else: - return self._read_block(size) + return self._buffer.read(size) def read1(self, size=-1): """Read up to size uncompressed bytes, while trying to avoid - making multiple reads from the underlying stream. + making multiple reads from the underlying stream. Reads up to a + buffer's worth of data if size is negative. Returns b"" if the file is at EOF. """ - # Usually, read1() calls _fp.read() at most once. However, sometimes - # this does not give enough data for the decompressor to make progress. - # In this case we make multiple reads, to avoid returning b"". self._check_can_read() - if (size == 0 or - # Only call _fill_buffer() if the buffer is actually empty. - # This gives a significant speedup if *size* is small. - (self._buffer_offset == len(self._buffer) and not self._fill_buffer())): - return b"" - if size > 0: - data = self._buffer[self._buffer_offset : - self._buffer_offset + size] - self._buffer_offset += len(data) - else: - data = self._buffer[self._buffer_offset:] - self._buffer = b"" - self._buffer_offset = 0 - self._pos += len(data) - return data + if size < 0: + size = io.DEFAULT_BUFFER_SIZE + return self._buffer.read1(size) def readline(self, size=-1): """Read a line of uncompressed bytes from the file. @@ -338,15 +217,7 @@ def readline(self, size=-1): case the line may be incomplete). Returns b'' if already at EOF. """ self._check_can_read() - # Shortcut for the common case - the whole line is in the buffer. - if size < 0: - end = self._buffer.find(b"\n", self._buffer_offset) + 1 - if end > 0: - line = self._buffer[self._buffer_offset : end] - self._buffer_offset = end - self._pos += len(line) - return line - return io.BufferedIOBase.readline(self, size) + return self._buffer.readline(size) def write(self, data): """Write a bytes object to the file. @@ -361,16 +232,7 @@ def write(self, data): self._pos += len(data) return len(data) - # Rewind the file to the beginning of the data stream. - def _rewind(self): - self._fp.seek(0, 0) - self._mode = _MODE_READ - self._pos = 0 - self._decompressor = LZMADecompressor(**self._init_args) - self._buffer = b"" - self._buffer_offset = 0 - - def seek(self, offset, whence=0): + def seek(self, offset, whence=io.SEEK_SET): """Change the file position. The new position is specified by offset, relative to the @@ -382,38 +244,17 @@ def seek(self, offset, whence=0): Returns the new file position. - Note that seeking is emulated, sp depending on the parameters, + Note that seeking is emulated, so depending on the parameters, this operation may be extremely slow. """ self._check_can_seek() - - # Recalculate offset as an absolute file position. - if whence == 0: - pass - elif whence == 1: - offset = self._pos + offset - elif whence == 2: - # Seeking relative to EOF - we need to know the file's size. - if self._size < 0: - self._read_all(return_data=False) - offset = self._size + offset - else: - raise ValueError("Invalid value for whence: {}".format(whence)) - - # Make it so that offset is the number of bytes to skip forward. - if offset < self._pos: - self._rewind() - else: - offset -= self._pos - - # Read and discard data until we reach the desired position. - self._read_block(offset, return_data=False) - - return self._pos + return self._buffer.seek(offset, whence) def tell(self): """Return the current file position.""" self._check_not_closed() + if self._mode == _MODE_READ: + return self._buffer.tell() return self._pos @@ -487,11 +328,18 @@ def decompress(data, format=FORMAT_AUTO, memlimit=None, filters=None): results = [] while True: decomp = LZMADecompressor(format, memlimit, filters) - results.append(decomp.decompress(data)) + try: + res = decomp.decompress(data) + except LZMAError: + if results: + break # Leftover data is not a valid LZMA/XZ stream; ignore it. + else: + raise # Error on the first iteration; bail out. + results.append(res) if not decomp.eof: raise LZMAError("Compressed data ended before the " "end-of-stream marker was reached") - if not decomp.unused_data: - return b"".join(results) - # There is unused data left over. Proceed to next stream. data = decomp.unused_data + if not data: + break + return b"".join(results) diff --git a/Lib/macpath.py b/Lib/macpath.py index d34f9e944cc8..a90d1053bc83 100644 --- a/Lib/macpath.py +++ b/Lib/macpath.py @@ -50,20 +50,26 @@ def isabs(s): def join(s, *p): - colon = _get_colon(s) - path = s - for t in p: - if (not s) or isabs(t): - path = t - continue - if t[:1] == colon: - t = t[1:] - if colon not in path: - path = colon + path - if path[-1:] != colon: - path = path + colon - path = path + t - return path + try: + colon = _get_colon(s) + path = s + if not p: + path[:0] + colon #23780: Ensure compatible data type even if p is null. + for t in p: + if (not path) or isabs(t): + path = t + continue + if t[:1] == colon: + t = t[1:] + if colon not in path: + path = colon + path + if path[-1:] != colon: + path = path + colon + path = path + t + return path + except (TypeError, AttributeError, BytesWarning): + genericpath._check_arg_types('join', s, *p) + raise def split(s): diff --git a/Lib/mailbox.py b/Lib/mailbox.py index 5f591bc3491c..24d4aec8a48f 100644 --- a/Lib/mailbox.py +++ b/Lib/mailbox.py @@ -1,5 +1,3 @@ -#! /usr/bin/env python3 - """Read/write support for Maildir, mbox, MH, Babyl, and MMDF mailboxes.""" # Notes for authors of new mailbox subclasses: @@ -8,7 +6,6 @@ # or returning from a flush() method. See functions _sync_flush() and # _sync_close(). -import sys import os import time import calendar @@ -106,7 +103,7 @@ def keys(self): def itervalues(self): """Return an iterator over all messages.""" - for key in self.keys(): + for key in self.iterkeys(): try: value = self[key] except KeyError: @@ -122,7 +119,7 @@ def values(self): def iteritems(self): """Return an iterator over (key, message) tuples.""" - for key in self.keys(): + for key in self.iterkeys(): try: value = self[key] except KeyError: @@ -157,7 +154,7 @@ def pop(self, key, default=None): def popitem(self): """Delete an arbitrary (key, message) pair and return it.""" - for key in self.keys(): + for key in self.iterkeys(): return (key, self.pop(key)) # This is only run once. else: raise KeyError('No messages in mailbox') @@ -165,7 +162,7 @@ def popitem(self): def update(self, arg=None): """Change the messages that correspond to certain keys.""" if hasattr(arg, 'iteritems'): - source = arg.items() + source = arg.iteritems() elif hasattr(arg, 'items'): source = arg.items() else: @@ -562,7 +559,7 @@ def _lookup(self, key): def next(self): """Return the next message in a one-time iteration.""" if not hasattr(self, '_onetime_keys'): - self._onetime_keys = iter(self.keys()) + self._onetime_keys = self.iterkeys() while True: try: return self[next(self._onetime_keys)] @@ -725,10 +722,14 @@ def _post_message_hook(self, f): def close(self): """Flush and close the mailbox.""" - self.flush() - if self._locked: - self.unlock() - self._file.close() # Sync has been done by self.flush() above. + try: + self.flush() + finally: + try: + if self._locked: + self.unlock() + finally: + self._file.close() # Sync has been done by self.flush() above. def _lookup(self, key=None): """Return (start, stop) or raise KeyError.""" @@ -1081,7 +1082,7 @@ def __contains__(self, key): def __len__(self): """Return a count of messages in the mailbox.""" - return len(list(self.keys())) + return len(list(self.iterkeys())) def lock(self): """Lock the mailbox.""" @@ -1195,7 +1196,7 @@ def pack(self): sequences = self.get_sequences() prev = 0 changes = [] - for key in self.keys(): + for key in self.iterkeys(): if key - 1 != prev: changes.append((key, prev + 1)) if hasattr(os, 'link'): @@ -1233,8 +1234,8 @@ def _dump_sequences(self, message, key): class Babyl(_singlefileMailbox): """An Rmail-style Babyl mailbox.""" - _special_labels = frozenset(('unseen', 'deleted', 'filed', 'answered', - 'forwarded', 'edited', 'resent')) + _special_labels = frozenset({'unseen', 'deleted', 'filed', 'answered', + 'forwarded', 'edited', 'resent'}) def __init__(self, path, factory=None, create=True): """Initialize a Babyl mailbox.""" @@ -1952,7 +1953,7 @@ def __iter__(self): while True: line = self.readline() if not line: - raise StopIteration + return yield line def tell(self): @@ -1969,9 +1970,11 @@ def seek(self, offset, whence=0): def close(self): """Close the file.""" if hasattr(self, '_file'): - if hasattr(self._file, 'close'): - self._file.close() - del self._file + try: + if hasattr(self._file, 'close'): + self._file.close() + finally: + del self._file def _read(self, size, read_method): """Read size bytes using read_method.""" @@ -1983,7 +1986,7 @@ def _read(self, size, read_method): return result def __enter__(self): - """Context manager protocol support.""" + """Context management protocol support.""" return self def __exit__(self, *exc): diff --git a/Lib/mailcap.py b/Lib/mailcap.py index bd61b0b0ae94..97e303522cae 100644 --- a/Lib/mailcap.py +++ b/Lib/mailcap.py @@ -22,8 +22,8 @@ def getcaps(): fp = open(mailcap, 'r') except OSError: continue - morecaps = readmailcapfile(fp) - fp.close() + with fp: + morecaps = readmailcapfile(fp) for key, value in morecaps.items(): if not key in caps: caps[key] = value diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index d7161f81343f..d64726b80fbb 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -246,7 +246,8 @@ def enum_types(mimedb): except EnvironmentError: break else: - yield ctype + if '\0' not in ctype: + yield ctype i += 1 with _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, '') as hkcr: @@ -363,9 +364,10 @@ def read_mime_types(file): f = open(file) except OSError: return None - db = MimeTypes() - db.readfp(f, True) - return db.types_map[True] + with f: + db = MimeTypes() + db.readfp(f, True) + return db.types_map[True] def _default_mime_types(): diff --git a/Lib/modulefinder.py b/Lib/modulefinder.py index ebd068aaa240..50f2462da01f 100644 --- a/Lib/modulefinder.py +++ b/Lib/modulefinder.py @@ -1,6 +1,7 @@ """Find modules used by a script, using introspection.""" import dis +import importlib._bootstrap_external import importlib.machinery import marshal import os @@ -222,7 +223,7 @@ def find_all_submodules(self, m): if not m.__path__: return modules = {} - # 'suffixes' used to be a list hardcoded to [".py", ".pyc", ".pyo"]. + # 'suffixes' used to be a list hardcoded to [".py", ".pyc"]. # But we must also collect Python extension modules - although # we cannot separate normal dlls from Python extensions. suffixes = [] @@ -287,11 +288,12 @@ def load_module(self, fqname, fp, pathname, file_info): if type == imp.PY_SOURCE: co = compile(fp.read()+'\n', pathname, 'exec') elif type == imp.PY_COMPILED: - if fp.read(4) != imp.get_magic(): - self.msgout(2, "raise ImportError: Bad magic number", pathname) - raise ImportError("Bad magic number in %s" % pathname) - fp.read(4) - co = marshal.load(fp) + try: + marshal_data = importlib._bootstrap_external._validate_bytecode_header(fp.read()) + except ImportError as exc: + self.msgout(2, "raise ImportError: " + str(exc), pathname) + raise + co = marshal.loads(marshal_data) else: co = None m = self.add_module(fqname) @@ -335,30 +337,6 @@ def _safe_import_hook(self, name, caller, fromlist, level=-1): fullname = name + "." + sub self._add_badmodule(fullname, caller) - def scan_opcodes(self, co, - unpack = struct.unpack): - # Scan the code, and yield 'interesting' opcode combinations - # Version for Python 2.4 and older - code = co.co_code - names = co.co_names - consts = co.co_consts - while code: - c = code[0] - if c in STORE_OPS: - oparg, = unpack('= HAVE_ARGUMENT: - code = code[3:] - else: - code = code[1:] - def scan_opcodes_25(self, co, unpack = struct.unpack): # Scan the code, and yield 'interesting' opcode combinations @@ -390,10 +368,7 @@ def scan_opcodes_25(self, co, def scan_code(self, co, m): code = co.co_code - if sys.version_info >= (2, 5): - scanner = self.scan_opcodes_25 - else: - scanner = self.scan_opcodes + scanner = self.scan_opcodes_25 for what, args in scanner(co): if what == "store": name, = args @@ -593,11 +568,12 @@ def replace_paths_in_code(self, co): if isinstance(consts[i], type(co)): consts[i] = self.replace_paths_in_code(consts[i]) - return types.CodeType(co.co_argcount, co.co_nlocals, co.co_stacksize, - co.co_flags, co.co_code, tuple(consts), co.co_names, - co.co_varnames, new_filename, co.co_name, - co.co_firstlineno, co.co_lnotab, - co.co_freevars, co.co_cellvars) + return types.CodeType(co.co_argcount, co.co_kwonlyargcount, + co.co_nlocals, co.co_stacksize, co.co_flags, + co.co_code, tuple(consts), co.co_names, + co.co_varnames, new_filename, co.co_name, + co.co_firstlineno, co.co_lnotab, co.co_freevars, + co.co_cellvars) def test(): diff --git a/Lib/msilib/__init__.py b/Lib/msilib/__init__.py index d29a5937c9ca..873560d09b26 100644 --- a/Lib/msilib/__init__.py +++ b/Lib/msilib/__init__.py @@ -361,7 +361,7 @@ def add_file(self, file, src=None, version=None, language=None): # [(logical, 0, filehash.IntegerData(1), # filehash.IntegerData(2), filehash.IntegerData(3), # filehash.IntegerData(4))]) - # Automatically remove .pyc/.pyo files on uninstall (2) + # Automatically remove .pyc files on uninstall (2) # XXX: adding so many RemoveFile entries makes installer unbelievably # slow. So instead, we have to use wildcard remove entries if file.endswith(".py"): @@ -382,10 +382,9 @@ def glob(self, pattern, exclude = None): return files def remove_pyc(self): - "Remove .pyc/.pyo files on uninstall" + "Remove .pyc files on uninstall" add_data(self.db, "RemoveFile", - [(self.component+"c", self.component, "*.pyc", self.logical, 2), - (self.component+"o", self.component, "*.pyo", self.logical, 2)]) + [(self.component+"c", self.component, "*.pyc", self.logical, 2)]) class Binary: def __init__(self, fname): diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py index 8ad6fd5f3e5c..4c32237f14cc 100644 --- a/Lib/multiprocessing/connection.py +++ b/Lib/multiprocessing/connection.py @@ -14,7 +14,6 @@ import sys import socket import struct -import errno import time import tempfile import itertools @@ -29,7 +28,7 @@ try: import _winapi - from _winapi import WAIT_OBJECT_0, WAIT_TIMEOUT, INFINITE + from _winapi import WAIT_OBJECT_0, WAIT_ABANDONED_0, WAIT_TIMEOUT, INFINITE except ImportError: if sys.platform == 'win32': raise @@ -77,7 +76,7 @@ def arbitrary_address(family): return tempfile.mktemp(prefix='listener-', dir=util.get_temp_dir()) elif family == 'AF_PIPE': return tempfile.mktemp(prefix=r'\\.\pipe\pyc-%d-%d-' % - (os.getpid(), next(_mmap_counter))) + (os.getpid(), next(_mmap_counter)), dir="") else: raise ValueError('unrecognized family') @@ -221,7 +220,7 @@ def recv_bytes(self, maxlength=None): def recv_bytes_into(self, buf, offset=0): """ - Receive bytes data into a writeable buffer-like object. + Receive bytes data into a writeable bytes-like object. Return the number of bytes read. """ self._check_closed() @@ -366,10 +365,7 @@ def _close(self, _close=os.close): def _send(self, buf, write=_write): remaining = len(buf) while True: - try: - n = write(self._handle, buf) - except InterruptedError: - continue + n = write(self._handle, buf) remaining -= n if remaining == 0: break @@ -380,10 +376,7 @@ def _recv(self, size, read=_read): handle = self._handle remaining = size while remaining > 0: - try: - chunk = read(handle, remaining) - except InterruptedError: - continue + chunk = read(handle, remaining) n = len(chunk) if n == 0: if remaining == size: @@ -395,13 +388,20 @@ def _recv(self, size, read=_read): return buf def _send_bytes(self, buf): - # For wire compatibility with 3.2 and lower n = len(buf) - self._send(struct.pack("!i", n)) - # The condition is necessary to avoid "broken pipe" errors - # when sending a 0-length buffer if the other end closed the pipe. - if n > 0: + # For wire compatibility with 3.2 and lower + header = struct.pack("!i", n) + if n > 16384: + # The payload is large so Nagle's algorithm won't be triggered + # and we'd better avoid the cost of concatenation. + self._send(header) self._send(buf) + else: + # Issue # 20540: concatenate before sending, to avoid delays due + # to Nagle's algorithm on a TCP socket. + # Also note we want to avoid sending a 0-length buffer separately, + # to avoid "broken pipe" errors if the other end closed the pipe. + self._send(header + buf) def _recv_bytes(self, maxsize=None): buf = self._recv(4) @@ -460,9 +460,10 @@ def close(self): ''' Close the bound socket or named pipe of `self`. ''' - if self._listener is not None: - self._listener.close() + listener = self._listener + if listener is not None: self._listener = None + listener.close() address = property(lambda self: self._listener._address) last_accepted = property(lambda self: self._listener._last_accepted) @@ -589,20 +590,18 @@ def __init__(self, address, family, backlog=1): self._unlink = None def accept(self): - while True: - try: - s, self._last_accepted = self._socket.accept() - except InterruptedError: - pass - else: - break + s, self._last_accepted = self._socket.accept() s.setblocking(True) return Connection(s.detach()) def close(self): - self._socket.close() - if self._unlink is not None: - self._unlink() + try: + self._socket.close() + finally: + unlink = self._unlink + if unlink is not None: + self._unlink = None + unlink() def SocketClient(address): @@ -835,7 +834,7 @@ def wait(object_list, timeout=None): try: ov, err = _winapi.ReadFile(fileno(), 0, True) except OSError as e: - err = e.winerror + ov, err = None, e.winerror if err not in _ready_errors: raise if err == _winapi.ERROR_IO_PENDING: @@ -844,7 +843,16 @@ def wait(object_list, timeout=None): else: # If o.fileno() is an overlapped pipe handle and # err == 0 then there is a zero length message - # in the pipe, but it HAS NOT been consumed. + # in the pipe, but it HAS NOT been consumed... + if ov and sys.getwindowsversion()[:2] >= (6, 2): + # ... except on Windows 8 and later, where + # the message HAS been consumed. + try: + _, err = ov.GetOverlappedResult(False) + except OSError as e: + err = e.winerror + if not err and hasattr(o, '_got_empty_message'): + o._got_empty_message = True ready_objects.add(o) timeout = 0 diff --git a/Lib/multiprocessing/dummy/__init__.py b/Lib/multiprocessing/dummy/__init__.py index 97f7af737ea2..1abea64419b2 100644 --- a/Lib/multiprocessing/dummy/__init__.py +++ b/Lib/multiprocessing/dummy/__init__.py @@ -86,7 +86,7 @@ def __repr__(self): if not name.startswith('_'): temp.append('%s=%r' % (name, value)) temp.sort() - return 'Namespace(%s)' % str.join(', ', temp) + return '%s(%s)' % (self.__class__.__name__, ', '.join(temp)) dict = dict list = list @@ -104,7 +104,7 @@ def _set(self, value): self._value = value value = property(_get, _set) def __repr__(self): - return '<%r(%r, %r)>'%(type(self).__name__,self._typecode,self._value) + return '<%s(%r, %r)>'%(type(self).__name__,self._typecode,self._value) def Manager(): return sys.modules[__name__] diff --git a/Lib/multiprocessing/dummy/connection.py b/Lib/multiprocessing/dummy/connection.py index 694ef9621500..19843751c0c6 100644 --- a/Lib/multiprocessing/dummy/connection.py +++ b/Lib/multiprocessing/dummy/connection.py @@ -59,9 +59,8 @@ def poll(self, timeout=0.0): return True if timeout <= 0.0: return False - self._in.not_empty.acquire() - self._in.not_empty.wait(timeout) - self._in.not_empty.release() + with self._in.not_empty: + self._in.not_empty.wait(timeout) return self._in.qsize() > 0 def close(self): diff --git a/Lib/multiprocessing/forkserver.py b/Lib/multiprocessing/forkserver.py index 387517ebdca8..b27cba52e003 100644 --- a/Lib/multiprocessing/forkserver.py +++ b/Lib/multiprocessing/forkserver.py @@ -107,7 +107,7 @@ def ensure_running(self): address = connection.arbitrary_address('AF_UNIX') listener.bind(address) os.chmod(address, 0o600) - listener.listen(100) + listener.listen() # all client processes own the write end of the "alive" pipe; # when they all terminate the read end becomes ready. @@ -188,8 +188,6 @@ def main(listener_fd, alive_r, preload, main_path=None, sys_path=None): finally: os._exit(code) - except InterruptedError: - pass except OSError as e: if e.errno != errno.ECONNABORTED: raise @@ -230,13 +228,7 @@ def read_unsigned(fd): data = b'' length = UNSIGNED_STRUCT.size while len(data) < length: - while True: - try: - s = os.read(fd, length - len(data)) - except InterruptedError: - pass - else: - break + s = os.read(fd, length - len(data)) if not s: raise EOFError('unexpected EOF') data += s @@ -245,13 +237,7 @@ def read_unsigned(fd): def write_unsigned(fd, n): msg = UNSIGNED_STRUCT.pack(n) while msg: - while True: - try: - nbytes = os.write(fd, msg) - except InterruptedError: - pass - else: - break + nbytes = os.write(fd, msg) if nbytes == 0: raise RuntimeError('should not get here') msg = msg[nbytes:] diff --git a/Lib/multiprocessing/heap.py b/Lib/multiprocessing/heap.py index 98bfdc8ee195..44d9638ff6ec 100644 --- a/Lib/multiprocessing/heap.py +++ b/Lib/multiprocessing/heap.py @@ -8,13 +8,11 @@ # import bisect -import itertools import mmap import os import sys import tempfile import threading -import _multiprocessing from . import context from . import reduction @@ -56,7 +54,9 @@ def __getstate__(self): def __setstate__(self, state): self.size, self.name = self._state = state self.buffer = mmap.mmap(-1, self.size, tagname=self.name) - assert _winapi.GetLastError() == _winapi.ERROR_ALREADY_EXISTS + # XXX Temporarily preventing buildbot failures while determining + # XXX the correct long-term fix. See issue 23060 + #assert _winapi.GetLastError() == _winapi.ERROR_ALREADY_EXISTS else: @@ -71,7 +71,14 @@ def __init__(self, size, fd=-1): os.unlink(name) util.Finalize(self, os.close, (self.fd,)) with open(self.fd, 'wb', closefd=False) as f: - f.write(b'\0'*size) + bs = 1024 * 1024 + if size >= bs: + zeros = b'\0' * bs + for _ in range(size // bs): + f.write(zeros) + del zeros + f.write(b'\0' * (size % bs)) + assert f.tell() == size self.buffer = mmap.mmap(self.fd, self.size) def reduce_arena(a): @@ -218,9 +225,8 @@ def malloc(self, size): assert 0 <= size < sys.maxsize if os.getpid() != self._lastpid: self.__init__() # reinitialize after fork - self._lock.acquire() - self._free_pending_blocks() - try: + with self._lock: + self._free_pending_blocks() size = self._roundup(max(size,1), self._alignment) (arena, start, stop) = self._malloc(size) new_stop = start + size @@ -229,8 +235,6 @@ def malloc(self, size): block = (arena, start, new_stop) self._allocated_blocks.add(block) return block - finally: - self._lock.release() # # Class representing a chunk of an mmap -- can be inherited by child process diff --git a/Lib/multiprocessing/managers.py b/Lib/multiprocessing/managers.py index cc87d36612d6..776656ea176a 100644 --- a/Lib/multiprocessing/managers.py +++ b/Lib/multiprocessing/managers.py @@ -65,8 +65,8 @@ def __setstate__(self, state): (self.typeid, self.address, self.id) = state def __repr__(self): - return 'Token(typeid=%r, address=%r, id=%r)' % \ - (self.typeid, self.address, self.id) + return '%s(typeid=%r, address=%r, id=%r)' % \ + (self.__class__.__name__, self.typeid, self.address, self.id) # # Function for communication with a manager's server process @@ -306,8 +306,7 @@ def debug_info(self, c): ''' Return some info --- useful to spot problems with refcounting ''' - self.mutex.acquire() - try: + with self.mutex: result = [] keys = list(self.id_to_obj.keys()) keys.sort() @@ -317,8 +316,6 @@ def debug_info(self, c): (ident, self.id_to_refcount[ident], str(self.id_to_obj[ident][0])[:75])) return '\n'.join(result) - finally: - self.mutex.release() def number_of_objects(self, c): ''' @@ -343,8 +340,7 @@ def create(self, c, typeid, *args, **kwds): ''' Create a new shared object and return its id ''' - self.mutex.acquire() - try: + with self.mutex: callable, exposed, method_to_typeid, proxytype = \ self.registry[typeid] @@ -374,8 +370,6 @@ def create(self, c, typeid, *args, **kwds): # has been created. self.incref(c, ident) return ident, tuple(exposed) - finally: - self.mutex.release() def get_methods(self, c, token): ''' @@ -392,22 +386,16 @@ def accept_connection(self, c, name): self.serve_client(c) def incref(self, c, ident): - self.mutex.acquire() - try: + with self.mutex: self.id_to_refcount[ident] += 1 - finally: - self.mutex.release() def decref(self, c, ident): - self.mutex.acquire() - try: + with self.mutex: assert self.id_to_refcount[ident] >= 1 self.id_to_refcount[ident] -= 1 if self.id_to_refcount[ident] == 0: del self.id_to_obj[ident], self.id_to_refcount[ident] util.debug('disposing of obj with id %r', ident) - finally: - self.mutex.release() # # Class to represent state of a manager @@ -671,14 +659,11 @@ class BaseProxy(object): def __init__(self, token, serializer, manager=None, authkey=None, exposed=None, incref=True): - BaseProxy._mutex.acquire() - try: + with BaseProxy._mutex: tls_idset = BaseProxy._address_to_local.get(token.address, None) if tls_idset is None: tls_idset = util.ForkAwareLocal(), ProcessLocalSet() BaseProxy._address_to_local[token.address] = tls_idset - finally: - BaseProxy._mutex.release() # self._tls is used to record the connection used by this # thread to communicate with the manager at token.address @@ -818,8 +803,8 @@ def __deepcopy__(self, memo): return self._getvalue() def __repr__(self): - return '<%s object, typeid %r at %s>' % \ - (type(self).__name__, self._token.typeid, '0x%x' % id(self)) + return '<%s object, typeid %r at %#x>' % \ + (type(self).__name__, self._token.typeid, id(self)) def __str__(self): ''' @@ -916,7 +901,7 @@ def __repr__(self): if not name.startswith('_'): temp.append('%s=%r' % (name, value)) temp.sort() - return 'Namespace(%s)' % str.join(', ', temp) + return '%s(%s)' % (self.__class__.__name__, ', '.join(temp)) class Value(object): def __init__(self, typecode, value, lock=True): @@ -1077,17 +1062,22 @@ def __imul__(self, value): )) -PoolProxy = MakeProxyType('PoolProxy', ( +BasePoolProxy = MakeProxyType('PoolProxy', ( 'apply', 'apply_async', 'close', 'imap', 'imap_unordered', 'join', - 'map', 'map_async', 'starmap', 'starmap_async', 'terminate' + 'map', 'map_async', 'starmap', 'starmap_async', 'terminate', )) -PoolProxy._method_to_typeid_ = { +BasePoolProxy._method_to_typeid_ = { 'apply_async': 'AsyncResult', 'map_async': 'AsyncResult', 'starmap_async': 'AsyncResult', 'imap': 'Iterator', 'imap_unordered': 'Iterator' } +class PoolProxy(BasePoolProxy): + def __enter__(self): + return self + def __exit__(self, exc_type, exc_val, exc_tb): + self.terminate() # # Definition of SyncManager diff --git a/Lib/multiprocessing/pool.py b/Lib/multiprocessing/pool.py index 1cb2d9567885..6d25469e1620 100644 --- a/Lib/multiprocessing/pool.py +++ b/Lib/multiprocessing/pool.py @@ -24,7 +24,7 @@ # If threading is available then ThreadPool should be provided. Therefore # we avoid top-level imports which are liable to fail on some systems. from . import util -from . import get_context, cpu_count, TimeoutError +from . import get_context, TimeoutError # # Constants representing the state of a pool @@ -87,10 +87,11 @@ def __str__(self): self.exc) def __repr__(self): - return "" % str(self) + return "<%s: %s>" % (self.__class__.__name__, self) -def worker(inqueue, outqueue, initializer=None, initargs=(), maxtasks=None): +def worker(inqueue, outqueue, initializer=None, initargs=(), maxtasks=None, + wrap_exception=False): assert maxtasks is None or (type(maxtasks) == int and maxtasks > 0) put = outqueue.put get = inqueue.get @@ -117,7 +118,8 @@ def worker(inqueue, outqueue, initializer=None, initargs=(), maxtasks=None): try: result = (True, func(*args, **kwds)) except Exception as e: - e = ExceptionWithTraceback(e, e.__traceback__) + if wrap_exception: + e = ExceptionWithTraceback(e, e.__traceback__) result = (False, e) try: put((job, i, result)) @@ -137,6 +139,8 @@ class Pool(object): ''' Class which supports an async version of applying functions to arguments. ''' + _wrap_exception = True + def Process(self, *args, **kwds): return self._ctx.Process(*args, **kwds) @@ -220,7 +224,8 @@ def _repopulate_pool(self): w = self.Process(target=worker, args=(self._inqueue, self._outqueue, self._initializer, - self._initargs, self._maxtasksperchild) + self._initargs, self._maxtasksperchild, + self._wrap_exception) ) self._pool.append(w) w.name = w.name.replace('Process', 'PoolWorker') @@ -369,25 +374,34 @@ def _handle_tasks(taskqueue, put, outqueue, pool, cache): thread = threading.current_thread() for taskseq, set_length in iter(taskqueue.get, None): + task = None i = -1 - for i, task in enumerate(taskseq): - if thread._state: - util.debug('task handler found thread._state != RUN') - break - try: - put(task) - except Exception as e: - job, ind = task[:2] + try: + for i, task in enumerate(taskseq): + if thread._state: + util.debug('task handler found thread._state != RUN') + break try: - cache[job]._set(ind, (False, e)) - except KeyError: - pass - else: + put(task) + except Exception as e: + job, ind = task[:2] + try: + cache[job]._set(ind, (False, e)) + except KeyError: + pass + else: + if set_length: + util.debug('doing set_length()') + set_length(i+1) + continue + break + except Exception as ex: + job, ind = task[:2] if task else (0, 0) + if job in cache: + cache[job]._set(ind + 1, (False, ex)) if set_length: util.debug('doing set_length()') set_length(i+1) - continue - break else: util.debug('task handler got sentinel') @@ -661,8 +675,7 @@ def __iter__(self): return self def next(self, timeout=None): - self._cond.acquire() - try: + with self._cond: try: item = self._items.popleft() except IndexError: @@ -675,8 +688,6 @@ def next(self, timeout=None): if self._index == self._length: raise StopIteration raise TimeoutError - finally: - self._cond.release() success, value = item if success: @@ -686,8 +697,7 @@ def next(self, timeout=None): __next__ = next # XXX def _set(self, i, obj): - self._cond.acquire() - try: + with self._cond: if self._index == i: self._items.append(obj) self._index += 1 @@ -701,18 +711,13 @@ def _set(self, i, obj): if self._index == self._length: del self._cache[self._job] - finally: - self._cond.release() def _set_length(self, length): - self._cond.acquire() - try: + with self._cond: self._length = length if self._index == self._length: self._cond.notify() del self._cache[self._job] - finally: - self._cond.release() # # Class whose instances are returned by `Pool.imap_unordered()` @@ -721,21 +726,19 @@ def _set_length(self, length): class IMapUnorderedIterator(IMapIterator): def _set(self, i, obj): - self._cond.acquire() - try: + with self._cond: self._items.append(obj) self._index += 1 self._cond.notify() if self._index == self._length: del self._cache[self._job] - finally: - self._cond.release() # # # class ThreadPool(Pool): + _wrap_exception = False @staticmethod def Process(*args, **kwds): @@ -754,10 +757,7 @@ def _setup_queues(self): @staticmethod def _help_stuff_finish(inqueue, task_handler, size): # put sentinels at head of inqueue to make workers finish - inqueue.not_empty.acquire() - try: + with inqueue.not_empty: inqueue.queue.clear() inqueue.queue.extend([None] * size) inqueue.not_empty.notify_all() - finally: - inqueue.not_empty.release() diff --git a/Lib/multiprocessing/popen_fork.py b/Lib/multiprocessing/popen_fork.py index 463cc18aa397..d2ebd7cfbe1e 100644 --- a/Lib/multiprocessing/popen_fork.py +++ b/Lib/multiprocessing/popen_fork.py @@ -1,7 +1,6 @@ import os import sys import signal -import errno from . import util @@ -29,8 +28,6 @@ def poll(self, flag=os.WNOHANG): try: pid, sts = os.waitpid(self.pid, flag) except OSError as e: - if e.errno == errno.EINTR: - continue # Child process not yet created. See #1731717 # e.errno == errno.ECHILD == 10 return None @@ -47,7 +44,7 @@ def poll(self, flag=os.WNOHANG): def wait(self, timeout=None): if self.returncode is None: if timeout is not None: - from .connection import wait + from multiprocessing.connection import wait if not wait([self.sentinel], timeout): return None # This shouldn't block if wait() returned successfully. diff --git a/Lib/multiprocessing/popen_forkserver.py b/Lib/multiprocessing/popen_forkserver.py index b115f8123cea..e792194f44ce 100644 --- a/Lib/multiprocessing/popen_forkserver.py +++ b/Lib/multiprocessing/popen_forkserver.py @@ -57,7 +57,7 @@ def _launch(self, process_obj): def poll(self, flag=os.WNOHANG): if self.returncode is None: - from .connection import wait + from multiprocessing.connection import wait timeout = 0 if flag == os.WNOHANG else None if not wait([self.sentinel], timeout): return None diff --git a/Lib/multiprocessing/popen_spawn_posix.py b/Lib/multiprocessing/popen_spawn_posix.py index 8b5dc42aa11a..6b0a8d635fea 100644 --- a/Lib/multiprocessing/popen_spawn_posix.py +++ b/Lib/multiprocessing/popen_spawn_posix.py @@ -1,4 +1,3 @@ -import fcntl import io import os @@ -8,8 +7,6 @@ from . import spawn from . import util -from . import current_process - __all__ = ['Popen'] diff --git a/Lib/multiprocessing/queues.py b/Lib/multiprocessing/queues.py index f6507710922b..786a303b3370 100644 --- a/Lib/multiprocessing/queues.py +++ b/Lib/multiprocessing/queues.py @@ -35,7 +35,8 @@ class Queue(object): def __init__(self, maxsize=0, *, ctx): if maxsize <= 0: - maxsize = _multiprocessing.SemLock.SEM_VALUE_MAX + # Can raise ImportError (see issues #3770 and #23400) + from .synchronize import SEM_VALUE_MAX as maxsize self._maxsize = maxsize self._reader, self._writer = connection.Pipe(duplex=False) self._rlock = ctx.Lock() @@ -81,14 +82,11 @@ def put(self, obj, block=True, timeout=None): if not self._sem.acquire(block, timeout): raise Full - self._notempty.acquire() - try: + with self._notempty: if self._thread is None: self._start_thread() self._buffer.append(obj) self._notempty.notify() - finally: - self._notempty.release() def get(self, block=True, timeout=None): if block and timeout is None: @@ -132,9 +130,13 @@ def put_nowait(self, obj): def close(self): self._closed = True - self._reader.close() - if self._close: - self._close() + try: + self._reader.close() + finally: + close = self._close + if close: + self._close = None + close() def join_thread(self): debug('Queue.join_thread()') @@ -201,12 +203,9 @@ def _finalize_join(twr): @staticmethod def _finalize_close(buffer, notempty): debug('telling queue thread to quit') - notempty.acquire() - try: + with notempty: buffer.append(_sentinel) notempty.notify() - finally: - notempty.release() @staticmethod def _feed(buffer, notempty, send_bytes, writelock, close, ignore_epipe): @@ -295,35 +294,24 @@ def put(self, obj, block=True, timeout=None): if not self._sem.acquire(block, timeout): raise Full - self._notempty.acquire() - self._cond.acquire() - try: + with self._notempty, self._cond: if self._thread is None: self._start_thread() self._buffer.append(obj) self._unfinished_tasks.release() self._notempty.notify() - finally: - self._cond.release() - self._notempty.release() def task_done(self): - self._cond.acquire() - try: + with self._cond: if not self._unfinished_tasks.acquire(False): raise ValueError('task_done() called too many times') if self._unfinished_tasks._semlock._is_zero(): self._cond.notify_all() - finally: - self._cond.release() def join(self): - self._cond.acquire() - try: + with self._cond: if not self._unfinished_tasks._semlock._is_zero(): self._cond.wait() - finally: - self._cond.release() # # Simplified Queue type -- really just a locked pipe diff --git a/Lib/multiprocessing/reduction.py b/Lib/multiprocessing/reduction.py index 01e6de2f96ba..8f209b47dab7 100644 --- a/Lib/multiprocessing/reduction.py +++ b/Lib/multiprocessing/reduction.py @@ -16,7 +16,6 @@ import sys from . import context -from . import util __all__ = ['send_handle', 'recv_handle', 'ForkingPickler', 'register', 'dump'] diff --git a/Lib/multiprocessing/semaphore_tracker.py b/Lib/multiprocessing/semaphore_tracker.py index ddb2b520f56f..de7738eeee8a 100644 --- a/Lib/multiprocessing/semaphore_tracker.py +++ b/Lib/multiprocessing/semaphore_tracker.py @@ -11,7 +11,6 @@ # python" would probably leave unlinked semaphores. # -import errno import os import signal import sys @@ -21,7 +20,6 @@ from . import spawn from . import util -from . import current_process __all__ = ['ensure_running', 'register', 'unregister'] diff --git a/Lib/multiprocessing/sharedctypes.py b/Lib/multiprocessing/sharedctypes.py index 0c178252d508..4258f591c4ca 100644 --- a/Lib/multiprocessing/sharedctypes.py +++ b/Lib/multiprocessing/sharedctypes.py @@ -188,6 +188,12 @@ def __init__(self, obj, lock=None, ctx=None): self.acquire = self._lock.acquire self.release = self._lock.release + def __enter__(self): + return self._lock.__enter__() + + def __exit__(self, *args): + return self._lock.__exit__(*args) + def __reduce__(self): assert_spawning(self) return synchronized, (self._obj, self._lock) @@ -212,32 +218,20 @@ def __len__(self): return len(self._obj) def __getitem__(self, i): - self.acquire() - try: + with self: return self._obj[i] - finally: - self.release() def __setitem__(self, i, value): - self.acquire() - try: + with self: self._obj[i] = value - finally: - self.release() def __getslice__(self, start, stop): - self.acquire() - try: + with self: return self._obj[start:stop] - finally: - self.release() def __setslice__(self, start, stop, values): - self.acquire() - try: + with self: self._obj[start:stop] = values - finally: - self.release() class SynchronizedString(SynchronizedArray): diff --git a/Lib/multiprocessing/spawn.py b/Lib/multiprocessing/spawn.py index 364b53f499c4..336e47990f83 100644 --- a/Lib/multiprocessing/spawn.py +++ b/Lib/multiprocessing/spawn.py @@ -11,6 +11,8 @@ import os import pickle import sys +import runpy +import types from . import get_start_method, set_start_method from . import process @@ -62,7 +64,14 @@ def freeze_support(): Run code for process object if this in not the main process ''' if is_forking(sys.argv): - main() + kwds = {} + for arg in sys.argv[2:]: + name, value = arg.split('=') + if value == 'None': + kwds[name] = None + else: + kwds[name] = int(value) + spawn_main(**kwds) sys.exit() @@ -71,7 +80,8 @@ def get_command_line(**kwds): Returns prefix of command line used for spawning a child process ''' if getattr(sys, 'frozen', False): - return [sys.executable, '--multiprocessing-fork'] + return ([sys.executable, '--multiprocessing-fork'] + + ['%s=%r' % item for item in kwds.items()]) else: prog = 'from multiprocessing.spawn import spawn_main; spawn_main(%s)' prog %= ', '.join('%s=%r' % item for item in kwds.items()) @@ -157,15 +167,19 @@ def get_preparation_data(name): start_method=get_start_method(), ) - if sys.platform != 'win32' or (not WINEXE and not WINSERVICE): - main_path = getattr(sys.modules['__main__'], '__file__', None) - if not main_path and sys.argv[0] not in ('', '-c'): - main_path = sys.argv[0] + # Figure out whether to initialise main in the subprocess as a module + # or through direct execution (or to leave it alone entirely) + main_module = sys.modules['__main__'] + main_mod_name = getattr(main_module.__spec__, "name", None) + if main_mod_name is not None: + d['init_main_from_name'] = main_mod_name + elif sys.platform != 'win32' or (not WINEXE and not WINSERVICE): + main_path = getattr(main_module, '__file__', None) if main_path is not None: if (not os.path.isabs(main_path) and process.ORIGINAL_DIR is not None): main_path = os.path.join(process.ORIGINAL_DIR, main_path) - d['main_path'] = os.path.normpath(main_path) + d['init_main_from_path'] = os.path.normpath(main_path) return d @@ -206,53 +220,68 @@ def prepare(data): if 'start_method' in data: set_start_method(data['start_method']) - if 'main_path' in data: - import_main_path(data['main_path']) + if 'init_main_from_name' in data: + _fixup_main_from_name(data['init_main_from_name']) + elif 'init_main_from_path' in data: + _fixup_main_from_path(data['init_main_from_path']) + +# Multiprocessing module helpers to fix up the main module in +# spawned subprocesses +def _fixup_main_from_name(mod_name): + # __main__.py files for packages, directories, zip archives, etc, run + # their "main only" code unconditionally, so we don't even try to + # populate anything in __main__, nor do we make any changes to + # __main__ attributes + current_main = sys.modules['__main__'] + if mod_name == "__main__" or mod_name.endswith(".__main__"): + return + + # If this process was forked, __main__ may already be populated + if getattr(current_main.__spec__, "name", None) == mod_name: + return + + # Otherwise, __main__ may contain some non-main code where we need to + # support unpickling it properly. We rerun it as __mp_main__ and make + # the normal __main__ an alias to that + old_main_modules.append(current_main) + main_module = types.ModuleType("__mp_main__") + main_content = runpy.run_module(mod_name, + run_name="__mp_main__", + alter_sys=True) + main_module.__dict__.update(main_content) + sys.modules['__main__'] = sys.modules['__mp_main__'] = main_module + + +def _fixup_main_from_path(main_path): + # If this process was forked, __main__ may already be populated + current_main = sys.modules['__main__'] + + # Unfortunately, the main ipython launch script historically had no + # "if __name__ == '__main__'" guard, so we work around that + # by treating it like a __main__.py file + # See https://github.com/ipython/ipython/issues/4698 + main_name = os.path.splitext(os.path.basename(main_path))[0] + if main_name == 'ipython': + return + + # Otherwise, if __file__ already has the setting we expect, + # there's nothing more to do + if getattr(current_main, '__file__', None) == main_path: + return + + # If the parent process has sent a path through rather than a module + # name we assume it is an executable script that may contain + # non-main code that needs to be executed + old_main_modules.append(current_main) + main_module = types.ModuleType("__mp_main__") + main_content = runpy.run_path(main_path, + run_name="__mp_main__") + main_module.__dict__.update(main_content) + sys.modules['__main__'] = sys.modules['__mp_main__'] = main_module def import_main_path(main_path): ''' Set sys.modules['__main__'] to module at main_path ''' - # XXX (ncoghlan): The following code makes several bogus - # assumptions regarding the relationship between __file__ - # and a module's real name. See PEP 302 and issue #10845 - if getattr(sys.modules['__main__'], '__file__', None) == main_path: - return - - main_name = os.path.splitext(os.path.basename(main_path))[0] - if main_name == '__init__': - main_name = os.path.basename(os.path.dirname(main_path)) - - if main_name == '__main__': - main_module = sys.modules['__main__'] - main_module.__file__ = main_path - elif main_name != 'ipython': - # Main modules not actually called __main__.py may - # contain additional code that should still be executed - import importlib - import types - - if main_path is None: - dirs = None - elif os.path.basename(main_path).startswith('__init__.py'): - dirs = [os.path.dirname(os.path.dirname(main_path))] - else: - dirs = [os.path.dirname(main_path)] - - assert main_name not in sys.modules, main_name - sys.modules.pop('__mp_main__', None) - # We should not try to load __main__ - # since that would execute 'if __name__ == "__main__"' - # clauses, potentially causing a psuedo fork bomb. - main_module = types.ModuleType(main_name) - # XXX Use a target of main_module? - spec = importlib.find_spec(main_name, path=dirs) - methods = importlib._bootstrap._SpecMethods(spec) - methods.init_module_attrs(main_module) - main_module.__name__ = '__mp_main__' - code = spec.loader.get_code(main_name) - exec(code, main_module.__dict__) - - old_main_modules.append(sys.modules['__main__']) - sys.modules['__main__'] = sys.modules['__mp_main__'] = main_module + _fixup_main_from_path(main_path) diff --git a/Lib/multiprocessing/synchronize.py b/Lib/multiprocessing/synchronize.py index 9d8e2824772e..d4bdf0e8b173 100644 --- a/Lib/multiprocessing/synchronize.py +++ b/Lib/multiprocessing/synchronize.py @@ -11,10 +11,8 @@ 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition', 'Event' ] -import os import threading import sys -import itertools import tempfile import _multiprocessing @@ -51,9 +49,10 @@ class SemLock(object): _rand = tempfile._RandomNameSequence() def __init__(self, kind, value, maxvalue, *, ctx): - ctx = ctx or get_context() - ctx = ctx.get_context() - unlink_now = sys.platform == 'win32' or ctx._name == 'fork' + if ctx is None: + ctx = context._default_context.get_context() + name = ctx.get_start_method() + unlink_now = sys.platform == 'win32' or name == 'fork' for i in range(100): try: sl = self._semlock = _multiprocessing.SemLock( @@ -135,7 +134,7 @@ def __repr__(self): value = self._semlock._get_value() except Exception: value = 'unknown' - return '' % value + return '<%s(value=%s)>' % (self.__class__.__name__, value) # # Bounded semaphore @@ -151,8 +150,8 @@ def __repr__(self): value = self._semlock._get_value() except Exception: value = 'unknown' - return '' % \ - (value, self._semlock.maxvalue) + return '<%s(value=%s, maxvalue=%s)>' % \ + (self.__class__.__name__, value, self._semlock.maxvalue) # # Non-recursive lock @@ -177,7 +176,7 @@ def __repr__(self): name = 'SomeOtherProcess' except Exception: name = 'unknown' - return '' % name + return '<%s(owner=%s)>' % (self.__class__.__name__, name) # # Recursive lock @@ -203,7 +202,7 @@ def __repr__(self): name, count = 'SomeOtherProcess', 'nonzero' except Exception: name, count = 'unknown', 'unknown' - return '' % (name, count) + return '<%s(%s, %s)>' % (self.__class__.__name__, name, count) # # Condition variable @@ -244,7 +243,7 @@ def __repr__(self): self._woken_count._semlock._get_value()) except Exception: num_waiters = 'unknown' - return '' % (self._lock, num_waiters) + return '<%s(%s, %s)>' % (self.__class__.__name__, self._lock, num_waiters) def wait(self, timeout=None): assert self._lock._semlock._is_mine(), \ @@ -338,34 +337,24 @@ def __init__(self, *, ctx): self._flag = ctx.Semaphore(0) def is_set(self): - self._cond.acquire() - try: + with self._cond: if self._flag.acquire(False): self._flag.release() return True return False - finally: - self._cond.release() def set(self): - self._cond.acquire() - try: + with self._cond: self._flag.acquire(False) self._flag.release() self._cond.notify_all() - finally: - self._cond.release() def clear(self): - self._cond.acquire() - try: + with self._cond: self._flag.acquire(False) - finally: - self._cond.release() def wait(self, timeout=None): - self._cond.acquire() - try: + with self._cond: if self._flag.acquire(False): self._flag.release() else: @@ -375,8 +364,6 @@ def wait(self, timeout=None): self._flag.release() return True return False - finally: - self._cond.release() # # Barrier diff --git a/Lib/multiprocessing/util.py b/Lib/multiprocessing/util.py index e476e853823e..ea5443d63220 100644 --- a/Lib/multiprocessing/util.py +++ b/Lib/multiprocessing/util.py @@ -7,8 +7,6 @@ # Licensed to PSF under a Contributor Agreement. # -import sys -import functools import os import itertools import weakref @@ -214,10 +212,11 @@ def __repr__(self): obj = None if obj is None: - return '' + return '<%s object, dead>' % self.__class__.__name__ - x = ' 0 and s[:1] in _get_bothseps(s) + return len(s) > 0 and s[0] in _get_bothseps(s) # Join two (or more) paths. - -def join(a, *p): - """Join two or more pathname components, inserting "\\" as needed. - If any component is an absolute path, all previous path components - will be discarded.""" - sep = _get_sep(a) - seps = _get_bothseps(a) - colon = _get_colon(a) - path = a - for b in p: - b_wins = 0 # set to 1 iff b makes path irrelevant - if not path: - b_wins = 1 - - elif isabs(b): - # This probably wipes out path so far. However, it's more - # complicated if path begins with a drive letter. You get a+b - # (minus redundant slashes) in these four cases: - # 1. join('c:', '/a') == 'c:/a' - # 2. join('//computer/share', '/a') == '//computer/share/a' - # 3. join('c:/', '/a') == 'c:/a' - # 4. join('//computer/share/', '/a') == '//computer/share/a' - # But b wins in all of these cases: - # 5. join('c:/a', '/b') == '/b' - # 6. join('//computer/share/a', '/b') == '/b' - # 7. join('c:', 'd:/') == 'd:/' - # 8. join('c:', '//computer/share/') == '//computer/share/' - # 9. join('//computer/share', 'd:/') == 'd:/' - # 10. join('//computer/share', '//computer/share/') == '//computer/share/' - # 11. join('c:/', 'd:/') == 'd:/' - # 12. join('c:/', '//computer/share/') == '//computer/share/' - # 13. join('//computer/share/', 'd:/') == 'd:/' - # 14. join('//computer/share/', '//computer/share/') == '//computer/share/' - b_prefix, b_rest = splitdrive(b) - - # if b has a prefix, it always wins. - if b_prefix: - b_wins = 1 - else: - # b doesn't have a prefix. - # but isabs(b) returned true. - # and therefore b_rest[0] must be a slash. - # (but let's check that.) - assert(b_rest and b_rest[0] in seps) - - # so, b still wins if path has a rest that's more than a sep. - # you get a+b if path_rest is empty or only has a sep. - # (see cases 1-4 for times when b loses.) - path_rest = splitdrive(path)[1] - b_wins = path_rest and path_rest not in seps - - if b_wins: - path = b - else: - # Join, and ensure there's a separator. - assert len(path) > 0 - if path[-1:] in seps: - if b and b[:1] in seps: - path += b[1:] - else: - path += b - elif path[-1:] == colon: - path += b - elif b: - if b[:1] in seps: - path += b - else: - path += sep + b - else: - # path is not empty and does not end with a backslash, - # but b is empty; since, e.g., split('a/') produces - # ('a', ''), it's best if join() adds a backslash in - # this case. - path += sep - - return path +def join(path, *paths): + if isinstance(path, bytes): + sep = b'\\' + seps = b'\\/' + colon = b':' + else: + sep = '\\' + seps = '\\/' + colon = ':' + try: + if not paths: + path[:0] + sep #23780: Ensure compatible data type even if p is null. + result_drive, result_path = splitdrive(path) + for p in paths: + p_drive, p_path = splitdrive(p) + if p_path and p_path[0] in seps: + # Second path is absolute + if p_drive or not result_drive: + result_drive = p_drive + result_path = p_path + continue + elif p_drive and p_drive != result_drive: + if p_drive.lower() != result_drive.lower(): + # Different drives => ignore the first path entirely + result_drive = p_drive + result_path = p_path + continue + # Same drive in different case + result_drive = p_drive + # Second path is relative to the first + if result_path and result_path[-1] not in seps: + result_path = result_path + sep + result_path = result_path + p_path + ## add separator between UNC and non-absolute path + if (result_path and result_path[0] not in seps and + result_drive and result_drive[-1:] != colon): + return result_drive + sep + result_path + return result_drive + result_path + except (TypeError, AttributeError, BytesWarning): + genericpath._check_arg_types('join', path, *paths) + raise # Split a path in a drive specification (a drive letter followed by a @@ -201,10 +136,16 @@ def splitdrive(p): Paths cannot contain both a drive letter and a UNC path. """ - empty = _get_empty(p) - if len(p) > 1: - sep = _get_sep(p) - normp = normcase(p) + if len(p) >= 2: + if isinstance(p, bytes): + sep = b'\\' + altsep = b'/' + colon = b':' + else: + sep = '\\' + altsep = '/' + colon = ':' + normp = p.replace(altsep, sep) if (normp[0:2] == sep*2) and (normp[2:3] != sep): # is a UNC path: # vvvvvvvvvvvvvvvvvvvv drive letter or UNC path @@ -212,18 +153,18 @@ def splitdrive(p): # directory ^^^^^^^^^^^^^^^ index = normp.find(sep, 2) if index == -1: - return empty, p + return p[:0], p index2 = normp.find(sep, index + 1) # a UNC path can't have two slashes in a row # (after the initial two) if index2 == index + 1: - return empty, p + return p[:0], p if index2 == -1: index2 = len(p) return p[:index2], p[index2:] - if normp[1:2] == _get_colon(p): + if normp[1:2] == colon: return p[:2], p[2:] - return empty, p + return p[:0], p # Parse UNC paths @@ -240,26 +181,12 @@ def splitunc(p): """ import warnings warnings.warn("ntpath.splitunc is deprecated, use ntpath.splitdrive instead", - DeprecationWarning) - sep = _get_sep(p) - if not p[1:2]: - return p[:0], p # Drive letter present - firstTwo = p[0:2] - if normcase(firstTwo) == sep + sep: - # is a UNC path: - # vvvvvvvvvvvvvvvvvvvv equivalent to drive letter - # \\machine\mountpoint\directories... - # directory ^^^^^^^^^^^^^^^ - normp = normcase(p) - index = normp.find(sep, 2) - if index == -1: - ##raise RuntimeError, 'illegal UNC path: "' + p + '"' - return (p[:0], p) - index = normp.find(sep, index + 1) - if index == -1: - index = len(p) - return p[:index], p[index:] - return p[:0], p + DeprecationWarning, 2) + drive, path = splitdrive(p) + if len(drive) == 2: + # Drive letter present + return p[:0], p + return drive, path # Split a path in head (everything up to the last '/') and tail (the @@ -281,10 +208,7 @@ def split(p): i -= 1 head, tail = p[:i], p[i:] # now tail has no slashes # remove trailing slashes from head, unless it's all slashes - head2 = head - while head2 and head2[-1:] in seps: - head2 = head2[:-1] - head = head2 or head + head = head.rstrip(seps) or head return d + head, tail @@ -294,8 +218,10 @@ def split(p): # It is always true that root + ext == p. def splitext(p): - return genericpath._splitext(p, _get_sep(p), _get_altsep(p), - _get_dot(p)) + if isinstance(p, bytes): + return genericpath._splitext(p, b'\\', b'/', b'.') + else: + return genericpath._splitext(p, '\\', '/', '.') splitext.__doc__ = genericpath._splitext.__doc__ @@ -403,7 +329,7 @@ def expanduser(path): userhome = join(drive, os.environ['HOMEPATH']) if isinstance(path, bytes): - userhome = userhome.encode(sys.getfilesystemencoding()) + userhome = os.fsencode(userhome) if i != 1: #~user userhome = join(dirname(userhome), path[1:i]) @@ -429,14 +355,16 @@ def expandvars(path): Unknown variables are left unchanged.""" if isinstance(path, bytes): - if ord('$') not in path and ord('%') not in path: + if b'$' not in path and b'%' not in path: return path import string varchars = bytes(string.ascii_letters + string.digits + '_-', 'ascii') quote = b'\'' percent = b'%' brace = b'{' + rbrace = b'}' dollar = b'$' + environ = getattr(os, 'environb', None) else: if '$' not in path and '%' not in path: return path @@ -445,7 +373,9 @@ def expandvars(path): quote = '\'' percent = '%' brace = '{' + rbrace = '}' dollar = '$' + environ = os.environ res = path[:0] index = 0 pathlen = len(path) @@ -458,7 +388,7 @@ def expandvars(path): index = path.index(c) res += c + path[:index + 1] except ValueError: - res += path + res += c + path index = pathlen - 1 elif c == percent: # variable or '%' if path[index + 1:index + 2] == percent: @@ -474,14 +404,13 @@ def expandvars(path): index = pathlen - 1 else: var = path[:index] - if isinstance(path, bytes): - var = var.decode('ascii') - if var in os.environ: - value = os.environ[var] - else: - value = '%' + var + '%' - if isinstance(path, bytes): - value = value.encode('ascii') + try: + if environ is None: + value = os.fsencode(os.environ[os.fsdecode(var)]) + else: + value = environ[var] + except KeyError: + value = percent + var + percent res += value elif c == dollar: # variable or '$$' if path[index + 1:index + 2] == dollar: @@ -491,43 +420,35 @@ def expandvars(path): path = path[index+2:] pathlen = len(path) try: - if isinstance(path, bytes): - index = path.index(b'}') - else: - index = path.index('}') - var = path[:index] - if isinstance(path, bytes): - var = var.decode('ascii') - if var in os.environ: - value = os.environ[var] - else: - value = '${' + var + '}' - if isinstance(path, bytes): - value = value.encode('ascii') - res += value + index = path.index(rbrace) except ValueError: - if isinstance(path, bytes): - res += b'${' + path - else: - res += '${' + path + res += dollar + brace + path index = pathlen - 1 + else: + var = path[:index] + try: + if environ is None: + value = os.fsencode(os.environ[os.fsdecode(var)]) + else: + value = environ[var] + except KeyError: + value = dollar + brace + var + rbrace + res += value else: - var = '' + var = path[:0] index += 1 c = path[index:index + 1] while c and c in varchars: - if isinstance(path, bytes): - var += c.decode('ascii') - else: - var += c + var += c index += 1 c = path[index:index + 1] - if var in os.environ: - value = os.environ[var] - else: - value = '$' + var - if isinstance(path, bytes): - value = value.encode('ascii') + try: + if environ is None: + value = os.fsencode(os.environ[os.fsdecode(var)]) + else: + value = environ[var] + except KeyError: + value = dollar + var res += value if c: index -= 1 @@ -543,16 +464,25 @@ def expandvars(path): def normpath(path): """Normalize path, eliminating double slashes, etc.""" - sep = _get_sep(path) - dotdot = _get_dot(path) * 2 - special_prefixes = _get_special(path) + if isinstance(path, bytes): + sep = b'\\' + altsep = b'/' + curdir = b'.' + pardir = b'..' + special_prefixes = (b'\\\\.\\', b'\\\\?\\') + else: + sep = '\\' + altsep = '/' + curdir = '.' + pardir = '..' + special_prefixes = ('\\\\.\\', '\\\\?\\') if path.startswith(special_prefixes): # in the case of paths with these prefixes: # \\.\ -> device names # \\?\ -> literal paths # do not do any normalization, but return the path unchanged return path - path = path.replace(_get_altsep(path), sep) + path = path.replace(altsep, sep) prefix, path = splitdrive(path) # collapse initial backslashes @@ -563,13 +493,13 @@ def normpath(path): comps = path.split(sep) i = 0 while i < len(comps): - if not comps[i] or comps[i] == _get_dot(path): + if not comps[i] or comps[i] == curdir: del comps[i] - elif comps[i] == dotdot: - if i > 0 and comps[i-1] != dotdot: + elif comps[i] == pardir: + if i > 0 and comps[i-1] != pardir: del comps[i-1:i+1] i -= 1 - elif i == 0 and prefix.endswith(_get_sep(path)): + elif i == 0 and prefix.endswith(sep): del comps[i] else: i += 1 @@ -577,7 +507,7 @@ def normpath(path): i += 1 # If the path is now empty, substitute '.' if not prefix and not comps: - comps.append(_get_dot(path)) + comps.append(curdir) return prefix + sep.join(comps) @@ -617,42 +547,109 @@ def abspath(path): supports_unicode_filenames = (hasattr(sys, "getwindowsversion") and sys.getwindowsversion()[3] >= 2) -def relpath(path, start=curdir): +def relpath(path, start=None): """Return a relative version of a path""" - sep = _get_sep(path) + if isinstance(path, bytes): + sep = b'\\' + curdir = b'.' + pardir = b'..' + else: + sep = '\\' + curdir = '.' + pardir = '..' - if start is curdir: - start = _get_dot(path) + if start is None: + start = curdir if not path: raise ValueError("no path specified") - start_abs = abspath(normpath(start)) - path_abs = abspath(normpath(path)) - start_drive, start_rest = splitdrive(start_abs) - path_drive, path_rest = splitdrive(path_abs) - if normcase(start_drive) != normcase(path_drive): - error = "path is on mount '{0}', start on mount '{1}'".format( - path_drive, start_drive) - raise ValueError(error) - - start_list = [x for x in start_rest.split(sep) if x] - path_list = [x for x in path_rest.split(sep) if x] - # Work out how much of the filepath is shared by start and path. - i = 0 - for e1, e2 in zip(start_list, path_list): - if normcase(e1) != normcase(e2): - break - i += 1 + try: + start_abs = abspath(normpath(start)) + path_abs = abspath(normpath(path)) + start_drive, start_rest = splitdrive(start_abs) + path_drive, path_rest = splitdrive(path_abs) + if normcase(start_drive) != normcase(path_drive): + raise ValueError("path is on mount %r, start on mount %r" % ( + path_drive, start_drive)) + + start_list = [x for x in start_rest.split(sep) if x] + path_list = [x for x in path_rest.split(sep) if x] + # Work out how much of the filepath is shared by start and path. + i = 0 + for e1, e2 in zip(start_list, path_list): + if normcase(e1) != normcase(e2): + break + i += 1 - if isinstance(path, bytes): - pardir = b'..' + rel_list = [pardir] * (len(start_list)-i) + path_list[i:] + if not rel_list: + return curdir + return join(*rel_list) + except (TypeError, ValueError, AttributeError, BytesWarning, DeprecationWarning): + genericpath._check_arg_types('relpath', path, start) + raise + + +# Return the longest common sub-path of the sequence of paths given as input. +# The function is case-insensitive and 'separator-insensitive', i.e. if the +# only difference between two paths is the use of '\' versus '/' as separator, +# they are deemed to be equal. +# +# However, the returned path will have the standard '\' separator (even if the +# given paths had the alternative '/' separator) and will have the case of the +# first path given in the sequence. Additionally, any trailing separator is +# stripped from the returned path. + +def commonpath(paths): + """Given a sequence of path names, returns the longest common sub-path.""" + + if not paths: + raise ValueError('commonpath() arg is an empty sequence') + + if isinstance(paths[0], bytes): + sep = b'\\' + altsep = b'/' + curdir = b'.' else: - pardir = '..' - rel_list = [pardir] * (len(start_list)-i) + path_list[i:] - if not rel_list: - return _get_dot(path) - return join(*rel_list) + sep = '\\' + altsep = '/' + curdir = '.' + + try: + drivesplits = [splitdrive(p.replace(altsep, sep).lower()) for p in paths] + split_paths = [p.split(sep) for d, p in drivesplits] + + try: + isabs, = set(p[:1] == sep for d, p in drivesplits) + except ValueError: + raise ValueError("Can't mix absolute and relative paths") from None + + # Check that all drive letters or UNC paths match. The check is made only + # now otherwise type errors for mixing strings and bytes would not be + # caught. + if len(set(d for d, p in drivesplits)) != 1: + raise ValueError("Paths don't have the same drive") + + drive, path = splitdrive(paths[0].replace(altsep, sep)) + common = path.split(sep) + common = [c for c in common if c and c != curdir] + + split_paths = [[c for c in s if c and c != curdir] for s in split_paths] + s1 = min(split_paths) + s2 = max(split_paths) + for i, c in enumerate(s1): + if c != s2[i]: + common = common[:i] + break + else: + common = common[:len(s1)] + + prefix = drive + sep if isabs else drive + return prefix + sep.join(common) + except (TypeError, AttributeError): + genericpath._check_arg_types('commonpath', *paths) + raise # determine if two files are in fact the same file diff --git a/Lib/numbers.py b/Lib/numbers.py index b206457dfc04..7eedc63ec05d 100644 --- a/Lib/numbers.py +++ b/Lib/numbers.py @@ -141,11 +141,6 @@ def __eq__(self, other): """self == other""" raise NotImplementedError - def __ne__(self, other): - """self != other""" - # The default __ne__ doesn't negate __eq__ until 3.0. - return not (self == other) - Complex.register(complex) diff --git a/Lib/opcode.py b/Lib/opcode.py index 0bd1ee679cfd..4c826a7730cd 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -70,6 +70,9 @@ def jabs_op(name, op): def_op('UNARY_INVERT', 15) +def_op('BINARY_MATRIX_MULTIPLY', 16) +def_op('INPLACE_MATRIX_MULTIPLY', 17) + def_op('BINARY_POWER', 19) def_op('BINARY_MULTIPLY', 20) @@ -82,7 +85,10 @@ def jabs_op(name, op): def_op('INPLACE_FLOOR_DIVIDE', 28) def_op('INPLACE_TRUE_DIVIDE', 29) -def_op('STORE_MAP', 54) +def_op('GET_AITER', 50) +def_op('GET_ANEXT', 51) +def_op('BEFORE_ASYNC_WITH', 52) + def_op('INPLACE_ADD', 55) def_op('INPLACE_SUBTRACT', 56) def_op('INPLACE_MULTIPLY', 57) @@ -97,10 +103,12 @@ def jabs_op(name, op): def_op('BINARY_OR', 66) def_op('INPLACE_POWER', 67) def_op('GET_ITER', 68) +def_op('GET_YIELD_FROM_ITER', 69) def_op('PRINT_EXPR', 70) def_op('LOAD_BUILD_CLASS', 71) def_op('YIELD_FROM', 72) +def_op('GET_AWAITABLE', 73) def_op('INPLACE_LSHIFT', 75) def_op('INPLACE_RSHIFT', 76) @@ -108,7 +116,8 @@ def jabs_op(name, op): def_op('INPLACE_XOR', 78) def_op('INPLACE_OR', 79) def_op('BREAK_LOOP', 80) -def_op('WITH_CLEANUP', 81) +def_op('WITH_CLEANUP_START', 81) +def_op('WITH_CLEANUP_FINISH', 82) def_op('RETURN_VALUE', 83) def_op('IMPORT_STAR', 84) @@ -194,7 +203,15 @@ def jabs_op(name, op): def_op('LOAD_CLASSDEREF', 148) hasfree.append(148) +jrel_op('SETUP_ASYNC_WITH', 154) + def_op('EXTENDED_ARG', 144) EXTENDED_ARG = 144 +def_op('BUILD_LIST_UNPACK', 149) +def_op('BUILD_MAP_UNPACK', 150) +def_op('BUILD_MAP_UNPACK_WITH_CALL', 151) +def_op('BUILD_TUPLE_UNPACK', 152) +def_op('BUILD_SET_UNPACK', 153) + del def_op, name_op, jrel_op, jabs_op diff --git a/Lib/operator.py b/Lib/operator.py index d31a9a453797..bc2a9478b8ba 100644 --- a/Lib/operator.py +++ b/Lib/operator.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 """ Operator Interface @@ -13,12 +12,12 @@ __all__ = ['abs', 'add', 'and_', 'attrgetter', 'concat', 'contains', 'countOf', 'delitem', 'eq', 'floordiv', 'ge', 'getitem', 'gt', 'iadd', 'iand', - 'iconcat', 'ifloordiv', 'ilshift', 'imod', 'imul', 'index', - 'indexOf', 'inv', 'invert', 'ior', 'ipow', 'irshift', 'is_', - 'is_not', 'isub', 'itemgetter', 'itruediv', 'ixor', 'le', - 'length_hint', 'lshift', 'lt', 'methodcaller', 'mod', 'mul', 'ne', - 'neg', 'not_', 'or_', 'pos', 'pow', 'rshift', 'setitem', 'sub', - 'truediv', 'truth', 'xor'] + 'iconcat', 'ifloordiv', 'ilshift', 'imatmul', 'imod', 'imul', + 'index', 'indexOf', 'inv', 'invert', 'ior', 'ipow', 'irshift', + 'is_', 'is_not', 'isub', 'itemgetter', 'itruediv', 'ixor', 'le', + 'length_hint', 'lshift', 'lt', 'matmul', 'methodcaller', 'mod', + 'mul', 'ne', 'neg', 'not_', 'or_', 'pos', 'pow', 'rshift', + 'setitem', 'sub', 'subscript', 'truediv', 'truth', 'xor'] from builtins import abs as _abs @@ -106,6 +105,10 @@ def mul(a, b): "Same as a * b." return a * b +def matmul(a, b): + "Same as a @ b." + return a @ b + def neg(a): "Same as -a." return -a @@ -228,10 +231,13 @@ class attrgetter: After h = attrgetter('name.first', 'name.last'), the call h(r) returns (r.name.first, r.name.last). """ + __slots__ = ('_attrs', '_call') + def __init__(self, attr, *attrs): if not attrs: if not isinstance(attr, str): raise TypeError('attribute name must be a string') + self._attrs = (attr,) names = attr.split('.') def func(obj): for name in names: @@ -239,7 +245,8 @@ def func(obj): return obj self._call = func else: - getters = tuple(map(attrgetter, (attr,) + attrs)) + self._attrs = (attr,) + attrs + getters = tuple(map(attrgetter, self._attrs)) def func(obj): return tuple(getter(obj) for getter in getters) self._call = func @@ -247,19 +254,30 @@ def func(obj): def __call__(self, obj): return self._call(obj) + def __repr__(self): + return '%s.%s(%s)' % (self.__class__.__module__, + self.__class__.__qualname__, + ', '.join(map(repr, self._attrs))) + + def __reduce__(self): + return self.__class__, self._attrs + class itemgetter: """ Return a callable object that fetches the given item(s) from its operand. After f = itemgetter(2), the call f(r) returns r[2]. After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3]) """ + __slots__ = ('_items', '_call') + def __init__(self, item, *items): if not items: + self._items = (item,) def func(obj): return obj[item] self._call = func else: - items = (item,) + items + self._items = items = (item,) + items def func(obj): return tuple(obj[i] for i in items) self._call = func @@ -267,6 +285,14 @@ def func(obj): def __call__(self, obj): return self._call(obj) + def __repr__(self): + return '%s.%s(%s)' % (self.__class__.__module__, + self.__class__.__name__, + ', '.join(map(repr, self._items))) + + def __reduce__(self): + return self.__class__, self._items + class methodcaller: """ Return a callable object that calls the given method on its operand. @@ -274,6 +300,7 @@ class methodcaller: After g = methodcaller('name', 'date', foo=1), the call g(r) returns r.name('date', foo=1). """ + __slots__ = ('_name', '_args', '_kwargs') def __init__(*args, **kwargs): if len(args) < 2: @@ -281,12 +308,30 @@ def __init__(*args, **kwargs): raise TypeError(msg) self = args[0] self._name = args[1] + if not isinstance(self._name, str): + raise TypeError('method name must be a string') self._args = args[2:] self._kwargs = kwargs def __call__(self, obj): return getattr(obj, self._name)(*self._args, **self._kwargs) + def __repr__(self): + args = [repr(self._name)] + args.extend(map(repr, self._args)) + args.extend('%s=%r' % (k, v) for k, v in self._kwargs.items()) + return '%s.%s(%s)' % (self.__class__.__module__, + self.__class__.__name__, + ', '.join(args)) + + def __reduce__(self): + if not self._kwargs: + return self.__class__, (self._name,) + self._args + else: + from functools import partial + return partial(self.__class__, self._name, **self._kwargs), self._args + + # In-place Operations *********************************************************# def iadd(a, b): @@ -327,6 +372,11 @@ def imul(a, b): a *= b return a +def imatmul(a, b): + "Same as a @= b." + a @= b + return a + def ior(a, b): "Same as a |= b." a |= b @@ -358,6 +408,32 @@ def ixor(a, b): return a +@object.__new__ # create a singleton instance +class subscript: + """ + A helper to turn subscript notation into indexing objects. This can be + used to create item access patterns ahead of time to pass them into + various subscriptable objects. + + For example: + subscript[5] == 5 + subscript[3:7:2] == slice(3, 7, 2) + subscript[5, 8] == (5, 8) + """ + __slots__ = () + + def __new__(cls): + raise TypeError("cannot create '{}' instances".format(cls.__name__)) + + @staticmethod + def __getitem__(key): + return key + + @staticmethod + def __reduce__(): + return 'subscript' + + try: from _operator import * except ImportError: @@ -384,6 +460,7 @@ def ixor(a, b): __lshift__ = lshift __mod__ = mod __mul__ = mul +__matmul__ = matmul __neg__ = neg __or__ = or_ __pos__ = pos @@ -404,6 +481,7 @@ def ixor(a, b): __ilshift__ = ilshift __imod__ = imod __imul__ = imul +__imatmul__ = imatmul __ior__ = ior __ipow__ = ipow __irshift__ = irshift diff --git a/Lib/optparse.py b/Lib/optparse.py index 22405d5eb8be..432a2eb9b66b 100644 --- a/Lib/optparse.py +++ b/Lib/optparse.py @@ -209,7 +209,6 @@ def __init__(self, short_first): self.parser = None self.indent_increment = indent_increment - self.help_position = self.max_help_position = max_help_position if width is None: try: width = int(os.environ['COLUMNS']) @@ -217,6 +216,8 @@ def __init__(self, width = 80 width -= 2 self.width = width + self.help_position = self.max_help_position = \ + min(max_help_position, max(width - 20, indent_increment * 2)) self.current_indent = 0 self.level = 0 self.help_width = None # computed later @@ -261,7 +262,7 @@ def _format_text(self, text): Format a paragraph of free-form text for inclusion in the help output at the current indentation level. """ - text_width = self.width - self.current_indent + text_width = max(self.width - self.current_indent, 11) indent = " "*self.current_indent return textwrap.fill(text, text_width, @@ -342,7 +343,7 @@ def store_option_strings(self, parser): self.dedent() self.dedent() self.help_position = min(max_len + 2, self.max_help_position) - self.help_width = self.width - self.help_position + self.help_width = max(self.width - self.help_position, 11) def format_option_strings(self, option): """Return a comma-separated list of option strings & metavariables.""" @@ -644,14 +645,8 @@ def _check_type(self): self.type = "string" else: # Allow type objects or builtin type conversion functions - # (int, str, etc.) as an alternative to their names. (The - # complicated check of builtins is only necessary for - # Python 2.1 and earlier, and is short-circuited by the - # first check on modern Pythons.) - import builtins - if ( isinstance(self.type, type) or - (hasattr(self.type, "__name__") and - getattr(builtins, self.type.__name__, None) is self.type) ): + # (int, str, etc.) as an alternative to their names. + if isinstance(self.type, type): self.type = self.type.__name__ if self.type == "str": diff --git a/Lib/os.py b/Lib/os.py index e9880a1e4c7a..3d2c6d3d492b 100644 --- a/Lib/os.py +++ b/Lib/os.py @@ -1,4 +1,4 @@ -r"""OS routines for Mac, NT, or Posix depending on what system we're on. +r"""OS routines for NT or Posix depending on what system we're on. This exports: - all functions from posix, nt or ce, e.g. unlink, stat, etc. @@ -61,6 +61,10 @@ def _get_exports_list(module): except ImportError: pass + import posix + __all__.extend(_get_exports_list(posix)) + del posix + elif 'nt' in _names: name = 'nt' linesep = '\r\n' @@ -206,23 +210,16 @@ def _add(str, fn): SEEK_CUR = 1 SEEK_END = 2 - -def _get_masked_mode(mode): - mask = umask(0) - umask(mask) - return mode & ~mask - # Super directory utilities. # (Inspired by Eric Raymond; the doc strings are mostly his) def makedirs(name, mode=0o777, exist_ok=False): - """makedirs(path [, mode=0o777][, exist_ok=False]) + """makedirs(name [, mode=0o777][, exist_ok=False]) - Super-mkdir; create a leaf directory and all intermediate ones. - Works like mkdir, except that any intermediate path segment (not - just the rightmost) will be created if it does not exist. If the - target directory with the same mode as we specified already exists, - raises an OSError if exist_ok is False, otherwise no exception is + Super-mkdir; create a leaf directory and all intermediate ones. Works like + mkdir, except that any intermediate path segment (not just the rightmost) + will be created if it does not exist. If the target directory already + exists, raise an OSError if exist_ok is False. Otherwise no exception is raised. This is recursive. """ @@ -243,24 +240,11 @@ def makedirs(name, mode=0o777, exist_ok=False): try: mkdir(name, mode) except OSError as e: - dir_exists = path.isdir(name) - expected_mode = _get_masked_mode(mode) - if dir_exists: - # S_ISGID is automatically copied by the OS from parent to child - # directories on mkdir. Don't consider it being set to be a mode - # mismatch as mkdir does not unset it when not specified in mode. - actual_mode = st.S_IMODE(lstat(name).st_mode) & ~st.S_ISGID - else: - actual_mode = -1 - if not (e.errno == errno.EEXIST and exist_ok and dir_exists and - actual_mode == expected_mode): - if dir_exists and actual_mode != expected_mode: - e.strerror += ' (mode %o != expected mode %o)' % ( - actual_mode, expected_mode) + if not exist_ok or e.errno != errno.EEXIST or not path.isdir(name): raise def removedirs(name): - """removedirs(path) + """removedirs(name) Super-rmdir; remove a leaf directory and all empty intermediate ones. Works like rmdir except that, if the leaf directory is @@ -288,7 +272,7 @@ def renames(old, new): empty. Works like rename, except creation of any intermediate directories needed to make the new pathname good is attempted first. After the rename, directories corresponding to rightmost - path segments of the old name will be pruned way until either the + path segments of the old name will be pruned until either the whole path is consumed or a nonempty directory is found. Note: this function can fail with the new directory structure made @@ -332,13 +316,14 @@ def walk(top, topdown=True, onerror=None, followlinks=False): When topdown is true, the caller can modify the dirnames list in-place (e.g., via del or slice assignment), and walk will only recurse into the - subdirectories whose names remain in dirnames; this can be used to prune - the search, or to impose a specific order of visiting. Modifying - dirnames when topdown is false is ineffective, since the directories in - dirnames have already been generated by the time dirnames itself is - generated. - - By default errors from the os.listdir() call are ignored. If + subdirectories whose names remain in dirnames; this can be used to prune the + search, or to impose a specific order of visiting. Modifying dirnames when + topdown is false is ineffective, since the directories in dirnames have + already been generated by the time dirnames itself is generated. No matter + the value of topdown, the list of subdirectories is retrieved before the + tuples for the directory and its subdirectories are generated. + + By default errors from the os.scandir() call are ignored. If optional arg 'onerror' is specified, it should be a function; it will be called with one argument, an OSError instance. It can report the error to continue with the walk, or raise the exception @@ -364,9 +349,11 @@ def walk(top, topdown=True, onerror=None, followlinks=False): print("bytes in", len(files), "non-directory files") if 'CVS' in dirs: dirs.remove('CVS') # don't visit CVS directories + """ - islink, join, isdir = path.islink, path.join, path.isdir + dirs = [] + nondirs = [] # We may not have read permission for top, in which case we can't # get a list of the files the directory contains. os.walk @@ -374,28 +361,71 @@ def walk(top, topdown=True, onerror=None, followlinks=False): # minor reason when (say) a thousand readable directories are still # left to visit. That logic is copied here. try: - # Note that listdir is global in this module due + # Note that scandir is global in this module due # to earlier import-*. - names = listdir(top) - except OSError as err: + scandir_it = scandir(top) + except OSError as error: if onerror is not None: - onerror(err) + onerror(error) return - dirs, nondirs = [], [] - for name in names: - if isdir(join(top, name)): - dirs.append(name) + while True: + try: + try: + entry = next(scandir_it) + except StopIteration: + break + except OSError as error: + if onerror is not None: + onerror(error) + return + + try: + is_dir = entry.is_dir() + except OSError: + # If is_dir() raises an OSError, consider that the entry is not + # a directory, same behaviour than os.path.isdir(). + is_dir = False + + if is_dir: + dirs.append(entry.name) else: - nondirs.append(name) + nondirs.append(entry.name) + if not topdown and is_dir: + # Bottom-up: recurse into sub-directory, but exclude symlinks to + # directories if followlinks is False + if followlinks: + walk_into = True + else: + try: + is_symlink = entry.is_symlink() + except OSError: + # If is_symlink() raises an OSError, consider that the + # entry is not a symbolic link, same behaviour than + # os.path.islink(). + is_symlink = False + walk_into = not is_symlink + + if walk_into: + yield from walk(entry.path, topdown, onerror, followlinks) + + # Yield before recursion if going top down if topdown: yield top, dirs, nondirs - for name in dirs: - new_path = join(top, name) - if followlinks or not islink(new_path): - yield from walk(new_path, topdown, onerror, followlinks) - if not topdown: + + # Recurse into sub-directories + islink, join = path.islink, path.join + for name in dirs: + new_path = join(top, name) + # Issue #23605: os.path.islink() is used instead of caching + # entry.is_symlink() result during the loop on os.scandir() because + # the caller can replace the directory entry during the "yield" + # above. + if followlinks or not islink(new_path): + yield from walk(new_path, topdown, onerror, followlinks) + else: + # Yield after recursion if going bottom up yield top, dirs, nondirs __all__.append("walk") diff --git a/Lib/pathlib.py b/Lib/pathlib.py index e73eca7ec9f0..1b5d2a9025a0 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -6,32 +6,24 @@ import posixpath import re import sys -import weakref -try: - import threading -except ImportError: - import dummy_threading as threading - -from collections import Sequence, defaultdict +from collections import Sequence from contextlib import contextmanager -from errno import EINVAL, ENOENT -from itertools import chain, count +from errno import EINVAL, ENOENT, ENOTDIR from operator import attrgetter from stat import S_ISDIR, S_ISLNK, S_ISREG, S_ISSOCK, S_ISBLK, S_ISCHR, S_ISFIFO -from urllib.parse import quote as urlquote, quote_from_bytes as urlquote_from_bytes +from urllib.parse import quote_from_bytes as urlquote_from_bytes supports_symlinks = True -try: +if os.name == 'nt': import nt -except ImportError: - nt = None -else: if sys.getwindowsversion()[:2] >= (6, 0): from nt import _getfinalpathname else: supports_symlinks = False _getfinalpathname = None +else: + nt = None __all__ = [ @@ -81,6 +73,10 @@ def parse_parts(self, parts): # parts. This makes the result of parsing e.g. # ("C:", "/", "a") reasonably intuitive. for part in it: + if not part: + continue + if altsep: + part = part.replace(altsep, sep) drv = self.splitroot(part)[0] if drv: break @@ -96,12 +92,16 @@ def join_parsed_parts(self, drv, root, parts, drv2, root2, parts2): (drive, root, parts) tuples. Return a new (drive, root, parts) tuple. """ if root2: - parts = parts2 - root = root2 + if not drv2 and drv: + return drv, root2, [drv + root2] + parts2[1:] + elif drv2: + if drv2 == drv or self.casefold(drv2) == self.casefold(drv): + # Same drive => second path is relative to the first + return drv, root, parts + parts2[1:] else: - parts = parts + parts2 - # XXX raise error if drv and drv2 are different? - return drv2 or drv, root, parts + # Second path is non-anchored (common case) + return drv, root, parts + parts2 + return drv2, root2, parts2 class _WindowsFlavour(_Flavour): @@ -113,7 +113,7 @@ class _WindowsFlavour(_Flavour): has_drv = True pathmod = ntpath - is_supported = (nt is not None) + is_supported = (os.name == 'nt') drive_letters = ( set(chr(x) for x in range(ord('a'), ord('z') + 1)) | @@ -225,6 +225,36 @@ def make_uri(self, path): # It's a path on a network drive => 'file://host/share/a/b' return 'file:' + urlquote_from_bytes(path.as_posix().encode('utf-8')) + def gethomedir(self, username): + if 'HOME' in os.environ: + userhome = os.environ['HOME'] + elif 'USERPROFILE' in os.environ: + userhome = os.environ['USERPROFILE'] + elif 'HOMEPATH' in os.environ: + try: + drv = os.environ['HOMEDRIVE'] + except KeyError: + drv = '' + userhome = drv + os.environ['HOMEPATH'] + else: + raise RuntimeError("Can't determine home directory") + + if username: + # Try to guess user home directory. By default all users + # directories are located in the same place and are named by + # corresponding usernames. If current user home directory points + # to nonstandard place, this guess is likely wrong. + if os.environ['USERNAME'] != username: + drv, root, parts = self.parse_parts((userhome,)) + if parts[-1] != os.environ['USERNAME']: + raise RuntimeError("Can't determine home directory " + "for %r" % username) + parts[-1] = username + if drv or root: + userhome = drv + root + self.join(parts[1:]) + else: + userhome = self.join(parts) + return userhome class _PosixFlavour(_Flavour): sep = '/' @@ -257,42 +287,47 @@ def casefold_parts(self, parts): def resolve(self, path): sep = self.sep - def split(p): - return [x for x in p.split(sep) if x] - def absparts(p): - # Our own abspath(), since the posixpath one makes - # the mistake of "normalizing" the path without resolving the - # symlinks first. - if not p.startswith(sep): - return split(os.getcwd()) + split(p) - else: - return split(p) - parts = absparts(str(path))[::-1] accessor = path._accessor - resolved = cur = "" - symlinks = {} - while parts: - part = parts.pop() - cur = resolved + sep + part - if cur in symlinks and symlinks[cur] <= len(parts): - # We've already seen the symlink and there's not less - # work to do than the last time. - raise RuntimeError("Symlink loop from %r" % cur) - try: - target = accessor.readlink(cur) - except OSError as e: - if e.errno != EINVAL: - raise - # Not a symlink - resolved = cur - else: - # Take note of remaining work from this symlink - symlinks[cur] = len(parts) - if target.startswith(sep): - # Symlink points to absolute path - resolved = "" - parts.extend(split(target)[::-1]) - return resolved or sep + seen = {} + def _resolve(path, rest): + if rest.startswith(sep): + path = '' + + for name in rest.split(sep): + if not name or name == '.': + # current dir + continue + if name == '..': + # parent dir + path, _, _ = path.rpartition(sep) + continue + newpath = path + sep + name + if newpath in seen: + # Already seen this path + path = seen[newpath] + if path is not None: + # use cached value + continue + # The symlink is not resolved, so we must have a symlink loop. + raise RuntimeError("Symlink loop from %r" % newpath) + # Resolve the symbolic link + try: + target = accessor.readlink(newpath) + except OSError as e: + if e.errno != EINVAL: + raise + # Not a symlink + path = newpath + else: + seen[newpath] = None # not resolved symlink + path = _resolve(path, target) + seen[newpath] = path # resolved symlink + + return path + # NOTE: according to POSIX, getcwd() cannot contain path components + # which are symlinks. + base = '' if path.is_absolute() else os.getcwd() + return _resolve(base, str(path)) or sep def is_reserved(self, parts): return False @@ -303,6 +338,21 @@ def make_uri(self, path): bpath = bytes(path) return 'file://' + urlquote_from_bytes(bpath) + def gethomedir(self, username): + if not username: + try: + return os.environ['HOME'] + except KeyError: + import pwd + return pwd.getpwuid(os.getuid()).pw_dir + else: + import pwd + try: + return pwd.getpwnam(username).pw_dir + except KeyError: + raise RuntimeError("Can't determine home directory " + "for %r" % username) + _windows_flavour = _WindowsFlavour() _posix_flavour = _PosixFlavour() @@ -572,8 +622,8 @@ def _parse_args(cls, args): if isinstance(a, PurePath): parts += a._parts elif isinstance(a, str): - # Assuming a str - parts.append(a) + # Force-cast str subclasses to str (issue #21127) + parts.append(str(a)) else: raise TypeError( "argument should be a path or str object, not %r" @@ -664,9 +714,6 @@ def __eq__(self, other): return NotImplemented return self._cparts == other._cparts and self._flavour is other._flavour - def __ne__(self, other): - return not self == other - def __hash__(self): try: return self._hash @@ -747,12 +794,21 @@ def with_name(self, name): """Return a new path with the file name changed.""" if not self.name: raise ValueError("%r has an empty name" % (self,)) + drv, root, parts = self._flavour.parse_parts((name,)) + if (not name or name[-1] in [self._flavour.sep, self._flavour.altsep] + or drv or root or len(parts) != 1): + raise ValueError("Invalid name %r" % (name)) return self._from_parsed_parts(self._drv, self._root, self._parts[:-1] + [name]) def with_suffix(self, suffix): """Return a new path with the file suffix changed (or added, if none).""" # XXX if suffix is None, should the current suffix be removed? + f = self._flavour + if f.sep in suffix or f.altsep and f.altsep in suffix: + raise ValueError("Invalid suffix %r" % (suffix)) + if suffix and not suffix.startswith('.') or suffix == '.': + raise ValueError("Invalid suffix %r" % (suffix)) name = self.name if not name: raise ValueError("%r has an empty name" % (self,)) @@ -778,27 +834,23 @@ def relative_to(self, *other): parts = self._parts drv = self._drv root = self._root - if drv or root: - if root: - abs_parts = [drv, root] + parts[1:] - else: - abs_parts = [drv] + parts[1:] + if root: + abs_parts = [drv, root] + parts[1:] else: abs_parts = parts to_drv, to_root, to_parts = self._parse_args(other) - if to_drv or to_root: - if to_root: - to_abs_parts = [to_drv, to_root] + to_parts[1:] - else: - to_abs_parts = [to_drv] + to_parts[1:] + if to_root: + to_abs_parts = [to_drv, to_root] + to_parts[1:] else: to_abs_parts = to_parts n = len(to_abs_parts) - if n == 0 and (drv or root) or abs_parts[:n] != to_abs_parts: + cf = self._flavour.casefold_parts + if (root or drv) if n == 0 else cf(abs_parts[:n]) != cf(to_abs_parts): formatted = self._format_parsed_parts(to_drv, to_root, to_parts) raise ValueError("{!r} does not start with {!r}" .format(str(self), str(formatted))) - return self._from_parsed_parts('', '', abs_parts[n:]) + return self._from_parsed_parts('', root if n == 1 else '', + abs_parts[n:]) @property def parts(self): @@ -939,6 +991,15 @@ def _opener(self, name, flags, mode=0o666): # A stub for the opener argument to built-in open() return self._accessor.open(self, flags, mode) + def _raw_open(self, flags, mode=0o777): + """ + Open the file pointed by this path and return a file descriptor, + as os.open() does. + """ + if self._closed: + self._raise_closed() + return self._accessor.open(self, flags, mode) + # Public API @classmethod @@ -948,6 +1009,24 @@ def cwd(cls): """ return cls(os.getcwd()) + @classmethod + def home(cls): + """Return a new path pointing to the user's home directory (as + returned by os.path.expanduser('~')). + """ + return cls(cls()._flavour.gethomedir(None)) + + def samefile(self, other_path): + """Return whether other_path is the same or not as this file + (as returned by os.path.samefile()). + """ + st = self.stat() + try: + other_st = other_path.stat() + except AttributeError: + other_st = os.stat(other_path) + return os.path.samestat(st, other_st) + def iterdir(self): """Iterate over the files in this directory. Does not yield any result for the special paths '.' and '..'. @@ -1045,15 +1124,6 @@ def group(self): import grp return grp.getgrgid(self.stat().st_gid).gr_name - def _raw_open(self, flags, mode=0o777): - """ - Open the file pointed by this path and return a file descriptor, - as os.open() does. - """ - if self._closed: - self._raise_closed() - return self._accessor.open(self, flags, mode) - def open(self, mode='r', buffering=-1, encoding=None, errors=None, newline=None): """ @@ -1065,6 +1135,39 @@ def open(self, mode='r', buffering=-1, encoding=None, return io.open(str(self), mode, buffering, encoding, errors, newline, opener=self._opener) + def read_bytes(self): + """ + Open the file in bytes mode, read it, and close the file. + """ + with self.open(mode='rb') as f: + return f.read() + + def read_text(self, encoding=None, errors=None): + """ + Open the file in text mode, read it, and close the file. + """ + with self.open(mode='r', encoding=encoding, errors=errors) as f: + return f.read() + + def write_bytes(self, data): + """ + Open the file in bytes mode, write to it, and close the file. + """ + # type-check for the buffer interface before truncating the file + view = memoryview(data) + with self.open(mode='wb') as f: + return f.write(view) + + def write_text(self, data, encoding=None, errors=None): + """ + Open the file in text mode, write to it, and close the file. + """ + if not isinstance(data, str): + raise TypeError('data must be str, not %s' % + data.__class__.__name__) + with self.open(mode='w', encoding=encoding, errors=errors) as f: + return f.write(data) + def touch(self, mode=0o666, exist_ok=True): """ Create this file with the given access mode, if it doesn't exist. @@ -1088,18 +1191,25 @@ def touch(self, mode=0o666, exist_ok=True): fd = self._raw_open(flags, mode) os.close(fd) - def mkdir(self, mode=0o777, parents=False): + def mkdir(self, mode=0o777, parents=False, exist_ok=False): if self._closed: self._raise_closed() if not parents: - self._accessor.mkdir(self, mode) + try: + self._accessor.mkdir(self, mode) + except FileExistsError: + if not exist_ok or not self.is_dir(): + raise else: try: self._accessor.mkdir(self, mode) + except FileExistsError: + if not exist_ok or not self.is_dir(): + raise except OSError as e: if e.errno != ENOENT: raise - self.parent.mkdir(mode, True) + self.parent.mkdir(parents=True) self._accessor.mkdir(self, mode) def chmod(self, mode): @@ -1180,7 +1290,7 @@ def exists(self): try: self.stat() except OSError as e: - if e.errno != ENOENT: + if e.errno not in (ENOENT, ENOTDIR): raise return False return True @@ -1192,7 +1302,7 @@ def is_dir(self): try: return S_ISDIR(self.stat().st_mode) except OSError as e: - if e.errno != ENOENT: + if e.errno not in (ENOENT, ENOTDIR): raise # Path doesn't exist or is a broken symlink # (see https://bitbucket.org/pitrou/pathlib/issue/12/) @@ -1206,7 +1316,7 @@ def is_file(self): try: return S_ISREG(self.stat().st_mode) except OSError as e: - if e.errno != ENOENT: + if e.errno not in (ENOENT, ENOTDIR): raise # Path doesn't exist or is a broken symlink # (see https://bitbucket.org/pitrou/pathlib/issue/12/) @@ -1219,7 +1329,7 @@ def is_symlink(self): try: return S_ISLNK(self.lstat().st_mode) except OSError as e: - if e.errno != ENOENT: + if e.errno not in (ENOENT, ENOTDIR): raise # Path doesn't exist return False @@ -1231,7 +1341,7 @@ def is_block_device(self): try: return S_ISBLK(self.stat().st_mode) except OSError as e: - if e.errno != ENOENT: + if e.errno not in (ENOENT, ENOTDIR): raise # Path doesn't exist or is a broken symlink # (see https://bitbucket.org/pitrou/pathlib/issue/12/) @@ -1244,7 +1354,7 @@ def is_char_device(self): try: return S_ISCHR(self.stat().st_mode) except OSError as e: - if e.errno != ENOENT: + if e.errno not in (ENOENT, ENOTDIR): raise # Path doesn't exist or is a broken symlink # (see https://bitbucket.org/pitrou/pathlib/issue/12/) @@ -1257,7 +1367,7 @@ def is_fifo(self): try: return S_ISFIFO(self.stat().st_mode) except OSError as e: - if e.errno != ENOENT: + if e.errno not in (ENOENT, ENOTDIR): raise # Path doesn't exist or is a broken symlink # (see https://bitbucket.org/pitrou/pathlib/issue/12/) @@ -1270,12 +1380,23 @@ def is_socket(self): try: return S_ISSOCK(self.stat().st_mode) except OSError as e: - if e.errno != ENOENT: + if e.errno not in (ENOENT, ENOTDIR): raise # Path doesn't exist or is a broken symlink # (see https://bitbucket.org/pitrou/pathlib/issue/12/) return False + def expanduser(self): + """ Return a new path with expanded ~ and ~user constructs + (as returned by os.path.expanduser) + """ + if (not (self._drv or self._root) and + self._parts and self._parts[0][:1] == '~'): + homedir = self._flavour.gethomedir(self._parts[0][1:]) + return self._from_parts([homedir] + self._parts[1:]) + + return self + class PosixPath(Path, PurePosixPath): __slots__ = () diff --git a/Lib/pdb.py b/Lib/pdb.py index dd7ceb8927dc..4cba8a0c7482 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -301,7 +301,7 @@ def user_exception(self, frame, exc_info): # An 'Internal StopIteration' exception is an exception debug event # issued by the interpreter when handling a subgenerator run with # 'yield from' or a generator controled by a for loop. No exception has - # actually occured in this case. The debugger uses this debug event to + # actually occurred in this case. The debugger uses this debug event to # stop when the debuggee is returning from such generators. prefix = 'Internal ' if (not exc_traceback and exc_type is StopIteration) else '' @@ -673,7 +673,7 @@ def do_break(self, arg, temporary = 0): # now set the break point err = self.set_break(filename, line, temporary, cond, funcname) if err: - self.error(err, file=self.stdout) + self.error(err) else: bp = self.get_breaks(filename, line)[-1] self.message("Breakpoint %d at %s:%d" % @@ -1316,7 +1316,7 @@ def do_whatis(self, arg): return # Is it a class? if value.__class__ is type: - self.message('Class %s.%s' % (value.__module__, value.__name__)) + self.message('Class %s.%s' % (value.__module__, value.__qualname__)) return # None of the above... self.message(type(value)) @@ -1669,6 +1669,9 @@ def main(): # In most cases SystemExit does not warrant a post-mortem session. print("The program exited via sys.exit(). Exit status:", end=' ') print(sys.exc_info()[1]) + except SyntaxError: + traceback.print_exc() + sys.exit(1) except: traceback.print_exc() print("Uncaught exception. Entering post mortem debugging") diff --git a/Lib/pickle.py b/Lib/pickle.py index c57149a39356..d41753d2d25b 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -23,10 +23,11 @@ """ -from types import FunctionType, ModuleType +from types import FunctionType from copyreg import dispatch_table from copyreg import _extension_registry, _inverted_registry, _extension_cache from itertools import islice +from functools import partial import sys from sys import maxsize from struct import pack, unpack @@ -242,7 +243,7 @@ def readline(self): if not data: self.current_frame = None return self.file_readline() - if data[-1] != b'\n': + if data[-1] != b'\n'[0]: raise UnpicklingError( "pickle exhausted before end of frame") return data @@ -258,33 +259,31 @@ def load_frame(self, frame_size): # Tools used for pickling. -def _getattribute(obj, name, allow_qualname=False): - dotted_path = name.split(".") - if not allow_qualname and len(dotted_path) > 1: - raise AttributeError("Can't get qualified attribute {!r} on {!r}; " + - "use protocols >= 4 to enable support" - .format(name, obj)) - for subpath in dotted_path: +def _getattribute(obj, name): + for subpath in name.split('.'): if subpath == '': raise AttributeError("Can't get local attribute {!r} on {!r}" .format(name, obj)) try: + parent = obj obj = getattr(obj, subpath) except AttributeError: raise AttributeError("Can't get attribute {!r} on {!r}" .format(name, obj)) - return obj + return obj, parent -def whichmodule(obj, name, allow_qualname=False): +def whichmodule(obj, name): """Find the module an object belong to.""" module_name = getattr(obj, '__module__', None) if module_name is not None: return module_name - for module_name, module in sys.modules.items(): + # Protect the iteration by using a list copy of sys.modules against dynamic + # modules that trigger imports of other modules upon calls to getattr. + for module_name, module in list(sys.modules.items()): if module_name == '__main__' or module is None: continue try: - if _getattribute(module, name, allow_qualname) is obj: + if _getattribute(module, name)[0] is obj: return module_name except AttributeError: pass @@ -348,24 +347,25 @@ class _Pickler: def __init__(self, file, protocol=None, *, fix_imports=True): """This takes a binary file for writing a pickle data stream. - The optional protocol argument tells the pickler to use the + The optional *protocol* argument tells the pickler to use the given protocol; supported protocols are 0, 1, 2, 3 and 4. The - default protocol is 3; a backward-incompatible protocol designed for - Python 3. + default protocol is 3; a backward-incompatible protocol designed + for Python 3. 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, a io.BytesIO instance, or any other custom object that - meets this interface. + 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, a 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 *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 protocol is None: protocol = DEFAULT_PROTOCOL @@ -389,10 +389,9 @@ def clear_memo(self): """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. - + 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. """ self.memo.clear() @@ -546,7 +545,7 @@ def save_reduce(self, func, args, state=None, listitems=None, write = self.write func_name = getattr(func, "__name__", "") - if self.proto >= 4 and func_name == "__newobj_ex__": + if self.proto >= 2 and func_name == "__newobj_ex__": cls, args, kwargs = args if not hasattr(cls, "__new__"): raise PicklingError("args[0] from {} args has no __new__" @@ -554,10 +553,16 @@ def save_reduce(self, func, args, state=None, listitems=None, if obj is not None and cls is not obj.__class__: raise PicklingError("args[0] from {} args has the wrong class" .format(func_name)) - save(cls) - save(args) - save(kwargs) - write(NEWOBJ_EX) + if self.proto >= 4: + save(cls) + save(args) + save(kwargs) + write(NEWOBJ_EX) + else: + func = partial(cls.__new__, cls, *args, **kwargs) + save(func) + save(()) + write(REDUCE) elif self.proto >= 2 and func_name == "__newobj__": # A __reduce__ implementation can direct protocol 2 or newer to # use the more efficient NEWOBJ opcode, while still @@ -897,16 +902,16 @@ def save_global(self, obj, name=None): write = self.write memo = self.memo - if name is None and self.proto >= 4: + if name is None: name = getattr(obj, '__qualname__', None) if name is None: name = obj.__name__ - module_name = whichmodule(obj, name, allow_qualname=self.proto >= 4) + module_name = whichmodule(obj, name) try: __import__(module_name, level=0) module = sys.modules[module_name] - obj2 = _getattribute(module, name, allow_qualname=self.proto >= 4) + obj2, parent = _getattribute(module, name) except (ImportError, KeyError, AttributeError): raise PicklingError( "Can't pickle %r: it's not found as %s.%s" % @@ -928,11 +933,16 @@ def save_global(self, obj, name=None): else: write(EXT4 + pack("= 3. if self.proto >= 4: self.save(module_name) self.save(name) write(STACK_GLOBAL) + elif parent is not module: + self.save_reduce(getattr, (parent, lastname)) elif self.proto >= 3: write(GLOBAL + bytes(module_name, "utf-8") + b'\n' + bytes(name, "utf-8") + b'\n') @@ -942,7 +952,7 @@ def save_global(self, obj, name=None): r_import_mapping = _compat_pickle.REVERSE_IMPORT_MAPPING if (module_name, name) in r_name_mapping: module_name, name = r_name_mapping[(module_name, name)] - if module_name in r_import_mapping: + elif module_name in r_import_mapping: module_name = r_import_mapping[module_name] try: write(GLOBAL + bytes(module_name, "ascii") + b'\n' + @@ -975,8 +985,14 @@ def __init__(self, file, *, fix_imports=True, encoding="ASCII", errors="strict"): """This takes a binary file for reading a pickle data stream. - The protocol version of the pickle is detected automatically, so no - proto argument is needed. + The protocol version of the pickle is detected automatically, so + no proto argument is needed. + + 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, a io.BytesIO + object, or any other custom object that meets this interface. The file-like object must have two methods, a read() method that takes an integer argument, and a readline() method that @@ -985,13 +1001,14 @@ def __init__(self, file, *, fix_imports=True, reading, a 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 compatiblity support for pickle stream - generated by Python 2.x. If *fix_imports* is True, pickle will try to - map the old Python 2.x names to the new names used in Python 3.x. The - *encoding* and *errors* tell pickle how to decode 8-bit string - instances pickled by Python 2.x; these default to 'ASCII' and - 'strict', respectively. + Optional keyword arguments are *fix_imports*, *encoding* and + *errors*, which are used to control compatiblity 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. *encoding* can be + 'bytes' to read theses 8-bit string instances as bytes objects. """ self._file_readline = file.readline self._file_read = file.read @@ -1139,6 +1156,15 @@ def load_binfloat(self): self.append(unpack('>d', self.read(8))[0]) dispatch[BINFLOAT[0]] = load_binfloat + def _decode_string(self, value): + # Used to allow strings from Python 2 to be decoded either as + # bytes or Unicode strings. This should be used only with the + # STRING, BINSTRING and SHORT_BINSTRING opcodes. + if self.encoding == "bytes": + return value + else: + return value.decode(self.encoding, self.errors) + def load_string(self): data = self.readline()[:-1] # Strip outermost quotes @@ -1146,8 +1172,7 @@ def load_string(self): data = data[1:-1] else: raise UnpicklingError("the STRING opcode argument must be quoted") - self.append(codecs.escape_decode(data)[0] - .decode(self.encoding, self.errors)) + self.append(self._decode_string(codecs.escape_decode(data)[0])) dispatch[STRING[0]] = load_string def load_binstring(self): @@ -1156,8 +1181,7 @@ def load_binstring(self): if len < 0: raise UnpicklingError("BINSTRING pickle has negative byte count") data = self.read(len) - value = str(data, self.encoding, self.errors) - self.append(value) + self.append(self._decode_string(data)) dispatch[BINSTRING[0]] = load_binstring def load_binbytes(self): @@ -1188,11 +1212,18 @@ def load_binunicode8(self): self.append(str(self.read(len), 'utf-8', 'surrogatepass')) dispatch[BINUNICODE8[0]] = load_binunicode8 + def load_binbytes8(self): + len, = unpack(' maxsize: + raise UnpicklingError("BINBYTES8 exceeds system's maximum size " + "of %d bytes" % maxsize) + self.append(self.read(len)) + dispatch[BINBYTES8[0]] = load_binbytes8 + def load_short_binstring(self): len = self.read(1)[0] data = self.read(len) - value = str(data, self.encoding, self.errors) - self.append(value) + self.append(self._decode_string(data)) dispatch[SHORT_BINSTRING[0]] = load_short_binstring def load_short_binbytes(self): @@ -1355,11 +1386,13 @@ def find_class(self, module, name): if self.proto < 3 and self.fix_imports: if (module, name) in _compat_pickle.NAME_MAPPING: module, name = _compat_pickle.NAME_MAPPING[(module, name)] - if module in _compat_pickle.IMPORT_MAPPING: + elif module in _compat_pickle.IMPORT_MAPPING: module = _compat_pickle.IMPORT_MAPPING[module] __import__(module, level=0) - return _getattribute(sys.modules[module], name, - allow_qualname=self.proto >= 4) + if self.proto >= 4: + return _getattribute(sys.modules[module], name)[0] + else: + return getattr(sys.modules[module], name) def load_reduce(self): stack = self.stack diff --git a/Lib/pickletools.py b/Lib/pickletools.py index a2480f6510ab..43dedb38a58b 100644 --- a/Lib/pickletools.py +++ b/Lib/pickletools.py @@ -969,113 +969,107 @@ def __repr__(self): return self.name -pyint = StackObject( - name='int', - obtype=int, - doc="A short (as opposed to long) Python integer object.") - -pylong = StackObject( - name='long', - obtype=int, - doc="A long (as opposed to short) Python integer object.") +pyint = pylong = StackObject( + name='int', + obtype=int, + doc="A Python integer object.") pyinteger_or_bool = StackObject( - name='int_or_bool', - obtype=(int, bool), - doc="A Python integer object (short or long), or " - "a Python bool.") + name='int_or_bool', + obtype=(int, bool), + doc="A Python integer or boolean object.") pybool = StackObject( - name='bool', - obtype=(bool,), - doc="A Python bool object.") + name='bool', + obtype=bool, + doc="A Python boolean object.") pyfloat = StackObject( - name='float', - obtype=float, - doc="A Python float object.") + name='float', + obtype=float, + doc="A Python float object.") -pystring = StackObject( - name='string', - obtype=bytes, - doc="A Python (8-bit) string object.") +pybytes_or_str = pystring = StackObject( + name='bytes_or_str', + obtype=(bytes, str), + doc="A Python bytes or (Unicode) string object.") pybytes = StackObject( - name='bytes', - obtype=bytes, - doc="A Python bytes object.") + name='bytes', + obtype=bytes, + doc="A Python bytes object.") pyunicode = StackObject( - name='str', - obtype=str, - doc="A Python (Unicode) string object.") + name='str', + obtype=str, + doc="A Python (Unicode) string object.") pynone = StackObject( - name="None", - obtype=type(None), - doc="The Python None object.") + name="None", + obtype=type(None), + doc="The Python None object.") pytuple = StackObject( - name="tuple", - obtype=tuple, - doc="A Python tuple object.") + name="tuple", + obtype=tuple, + doc="A Python tuple object.") pylist = StackObject( - name="list", - obtype=list, - doc="A Python list object.") + name="list", + obtype=list, + doc="A Python list object.") pydict = StackObject( - name="dict", - obtype=dict, - doc="A Python dict object.") + name="dict", + obtype=dict, + doc="A Python dict object.") pyset = StackObject( - name="set", - obtype=set, - doc="A Python set object.") + name="set", + obtype=set, + doc="A Python set object.") pyfrozenset = StackObject( - name="frozenset", - obtype=set, - doc="A Python frozenset object.") + name="frozenset", + obtype=set, + doc="A Python frozenset object.") anyobject = StackObject( - name='any', - obtype=object, - doc="Any kind of object whatsoever.") + name='any', + obtype=object, + doc="Any kind of object whatsoever.") markobject = StackObject( - name="mark", - obtype=StackObject, - doc="""'The mark' is a unique object. - - Opcodes that operate on a variable number of objects - generally don't embed the count of objects in the opcode, - or pull it off the stack. Instead the MARK opcode is used - to push a special marker object on the stack, and then - some other opcodes grab all the objects from the top of - the stack down to (but not including) the topmost marker - object. - """) + name="mark", + obtype=StackObject, + doc="""'The mark' is a unique object. + +Opcodes that operate on a variable number of objects +generally don't embed the count of objects in the opcode, +or pull it off the stack. Instead the MARK opcode is used +to push a special marker object on the stack, and then +some other opcodes grab all the objects from the top of +the stack down to (but not including) the topmost marker +object. +""") stackslice = StackObject( - name="stackslice", - obtype=StackObject, - doc="""An object representing a contiguous slice of the stack. + name="stackslice", + obtype=StackObject, + doc="""An object representing a contiguous slice of the stack. - This is used in conjunction with markobject, to represent all - of the stack following the topmost markobject. For example, - the POP_MARK opcode changes the stack from +This is used in conjunction with markobject, to represent all +of the stack following the topmost markobject. For example, +the POP_MARK opcode changes the stack from - [..., markobject, stackslice] - to - [...] + [..., markobject, stackslice] +to + [...] - No matter how many object are on the stack after the topmost - markobject, POP_MARK gets rid of all of them (including the - topmost markobject too). - """) +No matter how many object are on the stack after the topmost +markobject, POP_MARK gets rid of all of them (including the +topmost markobject too). +""") ############################################################################## # Descriptors for pickle opcodes. @@ -1212,7 +1206,7 @@ def __init__(self, name, code, arg, code='L', arg=decimalnl_long, stack_before=[], - stack_after=[pylong], + stack_after=[pyint], proto=0, doc="""Push a long integer. @@ -1230,7 +1224,7 @@ def __init__(self, name, code, arg, code='\x8a', arg=long1, stack_before=[], - stack_after=[pylong], + stack_after=[pyint], proto=2, doc="""Long integer using one-byte length. @@ -1241,7 +1235,7 @@ def __init__(self, name, code, arg, code='\x8b', arg=long4, stack_before=[], - stack_after=[pylong], + stack_after=[pyint], proto=2, doc="""Long integer using found-byte length. @@ -1254,45 +1248,50 @@ def __init__(self, name, code, arg, code='S', arg=stringnl, stack_before=[], - stack_after=[pystring], + stack_after=[pybytes_or_str], proto=0, doc="""Push a Python string object. The argument is a repr-style string, with bracketing quote characters, and perhaps embedded escapes. The argument extends until the next - newline character. (Actually, they are decoded into a str instance + newline character. These are usually decoded into a str instance using the encoding given to the Unpickler constructor. or the default, - 'ASCII'.) + 'ASCII'. If the encoding given was 'bytes' however, they will be + decoded as bytes object instead. """), I(name='BINSTRING', code='T', arg=string4, stack_before=[], - stack_after=[pystring], + stack_after=[pybytes_or_str], proto=1, doc="""Push a Python string object. - There are two arguments: the first is a 4-byte little-endian signed int - giving the number of bytes in the string, and the second is that many - bytes, which are taken literally as the string content. (Actually, - they are decoded into a str instance using the encoding given to the - Unpickler constructor. or the default, 'ASCII'.) + There are two arguments: the first is a 4-byte little-endian + signed int giving the number of bytes in the string, and the + second is that many bytes, which are taken literally as the string + content. These are usually decoded into a str instance using the + encoding given to the Unpickler constructor. or the default, + 'ASCII'. If the encoding given was 'bytes' however, they will be + decoded as bytes object instead. """), I(name='SHORT_BINSTRING', code='U', arg=string1, stack_before=[], - stack_after=[pystring], + stack_after=[pybytes_or_str], proto=1, doc="""Push a Python string object. - There are two arguments: the first is a 1-byte unsigned int giving - the number of bytes in the string, and the second is that many bytes, - which are taken literally as the string content. (Actually, they - are decoded into a str instance using the encoding given to the - Unpickler constructor. or the default, 'ASCII'.) + There are two arguments: the first is a 1-byte unsigned int giving + the number of bytes in the string, and the second is that many + bytes, which are taken literally as the string content. These are + usually decoded into a str instance using the encoding given to + the Unpickler constructor. or the default, 'ASCII'. If the + encoding given was 'bytes' however, they will be decoded as bytes + object instead. """), # Bytes (protocol 3 only; older protocols don't support bytes at all) @@ -1899,7 +1898,7 @@ def __init__(self, name, code, arg, arg=None, stack_before=[pyunicode, pyunicode], stack_after=[anyobject], - proto=0, + proto=4, doc="""Push a global object (module.attr) on the stack. """), @@ -2283,40 +2282,61 @@ def genops(pickle): def optimize(p): 'Optimize a pickle string by removing unused PUT opcodes' - not_a_put = object() - gets = { not_a_put } # set of args used by a GET opcode - opcodes = [] # (startpos, stoppos, putid) + put = 'PUT' + get = 'GET' + oldids = set() # set of all PUT ids + newids = {} # set of ids used by a GET opcode + opcodes = [] # (op, idx) or (pos, end_pos) proto = 0 + protoheader = b'' for opcode, arg, pos, end_pos in _genops(p, yield_end_pos=True): if 'PUT' in opcode.name: - opcodes.append((pos, end_pos, arg)) + oldids.add(arg) + opcodes.append((put, arg)) + elif opcode.name == 'MEMOIZE': + idx = len(oldids) + oldids.add(idx) + opcodes.append((put, idx)) elif 'FRAME' in opcode.name: pass - else: - if 'GET' in opcode.name: - gets.add(arg) - elif opcode.name == 'PROTO': - assert pos == 0, pos + elif 'GET' in opcode.name: + if opcode.proto > proto: + proto = opcode.proto + newids[arg] = None + opcodes.append((get, arg)) + elif opcode.name == 'PROTO': + if arg > proto: proto = arg - opcodes.append((pos, end_pos, not_a_put)) - prevpos, prevarg = pos, None + if pos == 0: + protoheader = p[pos: end_pos] + else: + opcodes.append((pos, end_pos)) + else: + opcodes.append((pos, end_pos)) + del oldids # Copy the opcodes except for PUTS without a corresponding GET out = io.BytesIO() - opcodes = iter(opcodes) - if proto >= 2: - # Write the PROTO header before any framing - start, stop, _ = next(opcodes) - out.write(p[start:stop]) - buf = pickle._Framer(out.write) - if proto >= 4: - buf.start_framing() - for start, stop, putid in opcodes: - if putid in gets: - buf.commit_frame() - buf.write(p[start:stop]) + # Write the PROTO header before any framing + out.write(protoheader) + pickler = pickle._Pickler(out, proto) if proto >= 4: - buf.end_framing() + pickler.framer.start_framing() + idx = 0 + for op, arg in opcodes: + if op is put: + if arg not in newids: + continue + data = pickler.put(idx) + newids[arg] = idx + idx += 1 + elif op is get: + data = pickler.get(newids[arg]) + else: + data = p[op:arg] + pickler.framer.commit_frame() + pickler.write(data) + pickler.framer.end_framing() return out.getvalue() ############################################################################## @@ -2420,6 +2440,7 @@ def dis(pickle, out=None, memo=None, indentlevel=4, annotate=0): if opcode.name in ("PUT", "BINPUT", "LONG_BINPUT", "MEMOIZE"): if opcode.name == "MEMOIZE": memo_idx = len(memo) + markmsg = "(as %d)" % memo_idx else: assert arg is not None memo_idx = arg diff --git a/Lib/pkgutil.py b/Lib/pkgutil.py index 4682d22366c4..203d515e5ebd 100644 --- a/Lib/pkgutil.py +++ b/Lib/pkgutil.py @@ -16,6 +16,21 @@ 'ImpImporter', 'ImpLoader', 'read_code', 'extend_path', ] + +def _get_spec(finder, name): + """Return the finder-specific module spec.""" + # Works with legacy finders. + try: + find_spec = finder.find_spec + except AttributeError: + loader = finder.find_module(name) + if loader is None: + return None + return importlib.util.spec_from_loader(name, loader) + else: + return find_spec(name) + + def read_code(stream): # This helper is needed in order for the PEP 302 emulation to # correctly handle compiled files @@ -165,7 +180,7 @@ def _iter_file_finder_modules(importer, prefix=''): def _import_imp(): global imp with warnings.catch_warnings(): - warnings.simplefilter('ignore', PendingDeprecationWarning) + warnings.simplefilter('ignore', DeprecationWarning) imp = importlib.import_module('imp') class ImpImporter: @@ -326,9 +341,10 @@ def get_source(self, fullname=None): self.source = self._get_delegate().get_source() return self.source - def _get_delegate(self): - return ImpImporter(self.filename).find_module('__init__') + finder = ImpImporter(self.filename) + spec = _get_spec(finder, '__init__') + return spec.loader def get_filename(self, fullname=None): fullname = self._fix_name(fullname) @@ -440,11 +456,15 @@ def get_loader(module_or_name): """ if module_or_name in sys.modules: module_or_name = sys.modules[module_or_name] + if module_or_name is None: + return None if isinstance(module_or_name, ModuleType): module = module_or_name loader = getattr(module, '__loader__', None) if loader is not None: return loader + if getattr(module, '__spec__', None) is None: + return None fullname = module.__name__ else: fullname = module_or_name @@ -454,29 +474,22 @@ def get_loader(module_or_name): def find_loader(fullname): """Find a PEP 302 "loader" object for fullname - This is s convenience wrapper around :func:`importlib.find_loader` that - sets the *path* argument correctly when searching for submodules, and - also ensures parent packages (if any) are imported before searching for - submodules. + This is a backwards compatibility wrapper around + importlib.util.find_spec that converts most failures to ImportError + and only returns the loader rather than the full spec """ if fullname.startswith('.'): msg = "Relative module name {!r} not supported".format(fullname) raise ImportError(msg) - path = None - pkg_name = fullname.rpartition(".")[0] - if pkg_name: - pkg = importlib.import_module(pkg_name) - path = getattr(pkg, "__path__", None) - if path is None: - return None try: - return importlib.find_loader(fullname, path) + spec = importlib.util.find_spec(fullname) except (ImportError, AttributeError, TypeError, ValueError) as ex: # This hack fixes an impedance mismatch between pkgutil and # importlib, where the latter raises other errors for cases where # pkgutil previously raised ImportError msg = "Error while finding loader for {!r} ({}: {})" raise ImportError(msg.format(fullname, type(ex), ex)) from ex + return spec.loader if spec is not None else None def extend_path(path, name): @@ -538,13 +551,14 @@ def extend_path(path, name): finder = get_importer(dir) if finder is not None: + portions = [] + if hasattr(finder, 'find_spec'): + spec = finder.find_spec(final_name) + if spec is not None: + portions = spec.submodule_search_locations or [] # Is this finder PEP 420 compliant? - if hasattr(finder, 'find_loader'): - loader, portions = finder.find_loader(final_name) - else: - # No, no need to call it - loader = None - portions = [] + elif hasattr(finder, 'find_loader'): + _, portions = finder.find_loader(final_name) for portion in portions: # XXX This may still add duplicate entries to path on @@ -594,7 +608,7 @@ def get_data(package, resource): which does not support get_data(), then None is returned. """ - spec = importlib.find_spec(package) + spec = importlib.util.find_spec(package) if spec is None: return None loader = spec.loader @@ -602,7 +616,7 @@ def get_data(package, resource): return None # XXX needs test mod = (sys.modules.get(package) or - importlib._bootstrap._SpecMethods(spec).load()) + importlib._bootstrap._load(spec)) if mod is None or not hasattr(mod, '__file__'): return None diff --git a/Lib/platform.py b/Lib/platform.py index c3c4b328e110..f3d2c423875a 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -26,12 +26,14 @@ # Betancourt, Randall Hopper, Karl Putland, John Farrell, Greg # Andruk, Just van Rossum, Thomas Heller, Mark R. Levinson, Mark # Hammond, Bill Tutt, Hans Nowak, Uwe Zessin (OpenVMS support), -# Colin Kong, Trent Mick, Guido van Rossum, Anthony Baxter +# Colin Kong, Trent Mick, Guido van Rossum, Anthony Baxter, Steve +# Dower # # History: # # # +# 1.0.8 - changed Windows support to read version from kernel32.dll # 1.0.7 - added DEV_NULL # 1.0.6 - added linux_distribution() # 1.0.5 - fixed Java support to allow running the module on Jython @@ -114,6 +116,8 @@ import collections import sys, os, re, subprocess +import warnings + ### Globals & Constants # Determine the platform's /dev/null device @@ -122,13 +126,17 @@ except AttributeError: # os.devnull was added in Python 2.4, so emulate it for earlier # Python versions - if sys.platform in ('dos','win32','win16'): + if sys.platform in ('dos', 'win32', 'win16'): # Use the old CP/M NUL as device name DEV_NULL = 'NUL' else: # Standard Unix uses /dev/null DEV_NULL = '/dev/null' +# Directory to search for configuration information on Unix. +# Constant used by test_platform to test linux_distribution(). +_UNIXCONFDIR = '/etc' + ### Platform specific APIs _libc_search = re.compile(b'(__libc_init)' @@ -137,7 +145,7 @@ b'|' br'(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)', re.ASCII) -def libc_ver(executable=sys.executable,lib='',version='', +def libc_ver(executable=sys.executable, lib='', version='', chunksize=16384): @@ -159,43 +167,42 @@ def libc_ver(executable=sys.executable,lib='',version='', # here to work around problems with Cygwin not being # able to open symlinks for reading executable = os.path.realpath(executable) - f = open(executable,'rb') - binary = f.read(chunksize) - pos = 0 - while 1: - if b'libc' in binary or b'GLIBC' in binary: - m = _libc_search.search(binary,pos) - else: - m = None - if not m: - binary = f.read(chunksize) - if not binary: - break - pos = 0 - continue - libcinit,glibc,glibcversion,so,threads,soversion = [ - s.decode('latin1') if s is not None else s - for s in m.groups()] - if libcinit and not lib: - lib = 'libc' - elif glibc: - if lib != 'glibc': - lib = 'glibc' - version = glibcversion - elif glibcversion > version: - version = glibcversion - elif so: - if lib != 'glibc': + with open(executable, 'rb') as f: + binary = f.read(chunksize) + pos = 0 + while 1: + if b'libc' in binary or b'GLIBC' in binary: + m = _libc_search.search(binary, pos) + else: + m = None + if not m: + binary = f.read(chunksize) + if not binary: + break + pos = 0 + continue + libcinit, glibc, glibcversion, so, threads, soversion = [ + s.decode('latin1') if s is not None else s + for s in m.groups()] + if libcinit and not lib: lib = 'libc' - if soversion and soversion > version: - version = soversion - if threads and version[-len(threads):] != threads: - version = version + threads - pos = m.end() - f.close() - return lib,version - -def _dist_try_harder(distname,version,id): + elif glibc: + if lib != 'glibc': + lib = 'glibc' + version = glibcversion + elif glibcversion > version: + version = glibcversion + elif so: + if lib != 'glibc': + lib = 'libc' + if soversion and soversion > version: + version = soversion + if threads and version[-len(threads):] != threads: + version = version + threads + pos = m.end() + return lib, version + +def _dist_try_harder(distname, version, id): """ Tries some special tricks to get the distribution information in case the default method fails. @@ -210,7 +217,7 @@ def _dist_try_harder(distname,version,id): for line in open('/var/adm/inst-log/info'): tv = line.split() if len(tv) == 2: - tag,value = tv + tag, value = tv else: continue if tag == 'MIN_DIST_VERSION': @@ -218,7 +225,7 @@ def _dist_try_harder(distname,version,id): elif tag == 'DIST_IDENT': values = value.split('-') id = values[2] - return distname,version,id + return distname, version, id if os.path.exists('/etc/.installed'): # Caldera OpenLinux has some infos in that file (thanks to Colin Kong) @@ -227,7 +234,7 @@ def _dist_try_harder(distname,version,id): if len(pkg) >= 2 and pkg[0] == 'OpenLinux': # XXX does Caldera support non Intel platforms ? If yes, # where can we find the needed id ? - return 'OpenLinux',pkg[1],id + return 'OpenLinux', pkg[1], id if os.path.isdir('/usr/lib/setup'): # Check for slackware version tag file (thanks to Greg Andruk) @@ -239,9 +246,9 @@ def _dist_try_harder(distname,version,id): verfiles.sort() distname = 'slackware' version = verfiles[-1][14:] - return distname,version,id + return distname, version, id - return distname,version,id + return distname, version, id _release_filename = re.compile(r'(\w+)[-_](release|version)', re.ASCII) _lsb_release_version = re.compile(r'(.+)' @@ -294,6 +301,15 @@ def linux_distribution(distname='', version='', id='', supported_dists=_supported_dists, full_distribution_name=1): + import warnings + warnings.warn("dist() and linux_distribution() functions are deprecated " + "in Python 3.5 and will be removed in Python 3.7", + PendingDeprecationWarning, stacklevel=2) + return _linux_distribution(distname, version, id, supported_dists, + full_distribution_name) + +def _linux_distribution(distname, version, id, supported_dists, + full_distribution_name): """ Tries to determine the name of the Linux OS distribution name. @@ -310,28 +326,29 @@ def linux_distribution(distname='', version='', id='', distribution read from the OS is returned. Otherwise the short name taken from supported_dists is used. - Returns a tuple (distname,version,id) which default to the + Returns a tuple (distname, version, id) which default to the args given as parameters. """ try: - etc = os.listdir('/etc') + etc = os.listdir(_UNIXCONFDIR) except OSError: # Probably not a Unix system - return distname,version,id + return distname, version, id etc.sort() for file in etc: m = _release_filename.match(file) if m is not None: - _distname,dummy = m.groups() + _distname, dummy = m.groups() if _distname in supported_dists: distname = _distname break else: - return _dist_try_harder(distname,version,id) + return _dist_try_harder(distname, version, id) # Read the first line - with open('/etc/'+file, 'r') as f: + with open(os.path.join(_UNIXCONFDIR, file), 'r', + encoding='utf-8', errors='surrogateescape') as f: firstline = f.readline() _distname, _version, _id = _parse_release_file(firstline) @@ -345,7 +362,7 @@ def linux_distribution(distname='', version='', id='', # To maintain backwards compatibility: -def dist(distname='',version='',id='', +def dist(distname='', version='', id='', supported_dists=_supported_dists): @@ -355,13 +372,17 @@ def dist(distname='',version='',id='', /etc and then reverts to _dist_try_harder() in case no suitable files are found. - Returns a tuple (distname,version,id) which default to the + Returns a tuple (distname, version, id) which default to the args given as parameters. """ - return linux_distribution(distname, version, id, - supported_dists=supported_dists, - full_distribution_name=0) + import warnings + warnings.warn("dist() and linux_distribution() functions are deprecated " + "in Python 3.5 and will be removed in Python 3.7", + PendingDeprecationWarning, stacklevel=2) + return _linux_distribution(distname, version, id, + supported_dists=supported_dists, + full_distribution_name=0) def popen(cmd, mode='r', bufsize=-1): @@ -380,11 +401,11 @@ def _norm_version(version, build=''): if build: l.append(build) try: - ints = map(int,l) + ints = map(int, l) except ValueError: strings = l else: - strings = list(map(str,ints)) + strings = list(map(str, ints)) version = '.'.join(strings[:3]) return version @@ -403,10 +424,10 @@ def _norm_version(version, build=''): def _syscmd_ver(system='', release='', version='', - supported_platforms=('win32','win16','dos')): + supported_platforms=('win32', 'win16', 'dos')): """ Tries to figure out the OS version used and returns - a tuple (system,release,version). + a tuple (system, release, version). It uses the "ver" shell command for this which is known to exists on Windows, DOS. XXX Others too ? @@ -416,30 +437,30 @@ def _syscmd_ver(system='', release='', version='', """ if sys.platform not in supported_platforms: - return system,release,version + return system, release, version # Try some common cmd strings - for cmd in ('ver','command /c ver','cmd /c ver'): + for cmd in ('ver', 'command /c ver', 'cmd /c ver'): try: - pipe = popen(cmd) + pipe = os.popen(cmd) info = pipe.read() if pipe.close(): raise OSError('command failed') # XXX How can I suppress shell errors from being written # to stderr ? except OSError as why: - #print 'Command %s failed: %s' % (cmd,why) + #print 'Command %s failed: %s' % (cmd, why) continue else: break else: - return system,release,version + return system, release, version # Parse the output info = info.strip() m = _ver_output.match(info) if m is not None: - system,release,version = m.groups() + system, release, version = m.groups() # Strip trailing dots from version and release if release[-1] == '.': release = release[:-1] @@ -448,191 +469,143 @@ def _syscmd_ver(system='', release='', version='', # Normalize the version and build strings (eliminating additional # zeros) version = _norm_version(version) - return system,release,version - -def _win32_getvalue(key,name,default=''): + return system, release, version + +_WIN32_CLIENT_RELEASES = { + (5, 0): "2000", + (5, 1): "XP", + # Strictly, 5.2 client is XP 64-bit, but platform.py historically + # has always called it 2003 Server + (5, 2): "2003Server", + (5, None): "post2003", + + (6, 0): "Vista", + (6, 1): "7", + (6, 2): "8", + (6, 3): "8.1", + (6, None): "post8.1", + + (10, 0): "10", + (10, None): "post10", +} - """ Read a value for name from the registry key. +# Server release name lookup will default to client names if necessary +_WIN32_SERVER_RELEASES = { + (5, 2): "2003Server", - In case this fails, default is returned. + (6, 0): "2008Server", + (6, 1): "2008ServerR2", + (6, 2): "2012Server", + (6, 3): "2012ServerR2", + (6, None): "post2012ServerR2", +} - """ +def _get_real_winver(maj, min, build): + if maj < 6 or (maj == 6 and min < 2): + return maj, min, build + + from ctypes import (c_buffer, POINTER, byref, create_unicode_buffer, + Structure, WinDLL) + from ctypes.wintypes import DWORD, HANDLE + + class VS_FIXEDFILEINFO(Structure): + _fields_ = [ + ("dwSignature", DWORD), + ("dwStrucVersion", DWORD), + ("dwFileVersionMS", DWORD), + ("dwFileVersionLS", DWORD), + ("dwProductVersionMS", DWORD), + ("dwProductVersionLS", DWORD), + ("dwFileFlagsMask", DWORD), + ("dwFileFlags", DWORD), + ("dwFileOS", DWORD), + ("dwFileType", DWORD), + ("dwFileSubtype", DWORD), + ("dwFileDateMS", DWORD), + ("dwFileDateLS", DWORD), + ] + + kernel32 = WinDLL('kernel32') + version = WinDLL('version') + + # We will immediately double the length up to MAX_PATH, but the + # path may be longer, so we retry until the returned string is + # shorter than our buffer. + name_len = actual_len = 130 + while actual_len == name_len: + name_len *= 2 + name = create_unicode_buffer(name_len) + actual_len = kernel32.GetModuleFileNameW(HANDLE(kernel32._handle), + name, len(name)) + if not actual_len: + return maj, min, build + + size = version.GetFileVersionInfoSizeW(name, None) + if not size: + return maj, min, build + + ver_block = c_buffer(size) + if (not version.GetFileVersionInfoW(name, None, size, ver_block) or + not ver_block): + return maj, min, build + + pvi = POINTER(VS_FIXEDFILEINFO)() + if not version.VerQueryValueW(ver_block, "", byref(pvi), byref(DWORD())): + return maj, min, build + + maj = pvi.contents.dwProductVersionMS >> 16 + min = pvi.contents.dwProductVersionMS & 0xFFFF + build = pvi.contents.dwProductVersionLS >> 16 + + return maj, min, build + +def win32_ver(release='', version='', csd='', ptype=''): try: - # Use win32api if available - from win32api import RegQueryValueEx + from sys import getwindowsversion except ImportError: - # On Python 2.0 and later, emulate using winreg - import winreg - RegQueryValueEx = winreg.QueryValueEx + return release, version, csd, ptype try: - return RegQueryValueEx(key,name) - except: - return default - -def win32_ver(release='',version='',csd='',ptype=''): - - """ Get additional version information from the Windows Registry - and return a tuple (version,csd,ptype) referring to version - number, CSD level (service pack), and OS type (multi/single - processor). - - As a hint: ptype returns 'Uniprocessor Free' on single - processor NT machines and 'Multiprocessor Free' on multi - processor machines. The 'Free' refers to the OS version being - free of debugging code. It could also state 'Checked' which - means the OS version uses debugging code, i.e. code that - checks arguments, ranges, etc. (Thomas Heller). + from winreg import OpenKeyEx, QueryValueEx, CloseKey, HKEY_LOCAL_MACHINE + except ImportError: + from _winreg import OpenKeyEx, QueryValueEx, CloseKey, HKEY_LOCAL_MACHINE - Note: this function works best with Mark Hammond's win32 - package installed, but also on Python 2.3 and later. It - obviously only runs on Win32 compatible platforms. + winver = getwindowsversion() + maj, min, build = _get_real_winver(*winver[:3]) + version = '{0}.{1}.{2}'.format(maj, min, build) - """ - # XXX Is there any way to find out the processor type on WinXX ? - # XXX Is win32 available on Windows CE ? - # - # Adapted from code posted by Karl Putland to comp.lang.python. - # - # The mappings between reg. values and release names can be found - # here: http://msdn.microsoft.com/library/en-us/sysinfo/base/osversioninfo_str.asp + release = (_WIN32_CLIENT_RELEASES.get((maj, min)) or + _WIN32_CLIENT_RELEASES.get((maj, None)) or + release) - # Import the needed APIs - try: - import win32api - from win32api import RegQueryValueEx, RegOpenKeyEx, \ - RegCloseKey, GetVersionEx - from win32con import HKEY_LOCAL_MACHINE, VER_PLATFORM_WIN32_NT, \ - VER_PLATFORM_WIN32_WINDOWS, VER_NT_WORKSTATION - except ImportError: - # Emulate the win32api module using Python APIs + # getwindowsversion() reflect the compatibility mode Python is + # running under, and so the service pack value is only going to be + # valid if the versions match. + if winver[:2] == (maj, min): try: - sys.getwindowsversion + csd = 'SP{}'.format(winver.service_pack_major) except AttributeError: - # No emulation possible, so return the defaults... - return release,version,csd,ptype - else: - # Emulation using winreg (added in Python 2.0) and - # sys.getwindowsversion() (added in Python 2.3) - import winreg - GetVersionEx = sys.getwindowsversion - RegQueryValueEx = winreg.QueryValueEx - RegOpenKeyEx = winreg.OpenKeyEx - RegCloseKey = winreg.CloseKey - HKEY_LOCAL_MACHINE = winreg.HKEY_LOCAL_MACHINE - VER_PLATFORM_WIN32_WINDOWS = 1 - VER_PLATFORM_WIN32_NT = 2 - VER_NT_WORKSTATION = 1 - VER_NT_SERVER = 3 - REG_SZ = 1 - - # Find out the registry key and some general version infos - winver = GetVersionEx() - maj,min,buildno,plat,csd = winver - version = '%i.%i.%i' % (maj,min,buildno & 0xFFFF) - if hasattr(winver, "service_pack"): - if winver.service_pack != "": - csd = 'SP%s' % winver.service_pack_major - else: - if csd[:13] == 'Service Pack ': - csd = 'SP' + csd[13:] - - if plat == VER_PLATFORM_WIN32_WINDOWS: - regkey = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion' - # Try to guess the release name - if maj == 4: - if min == 0: - release = '95' - elif min == 10: - release = '98' - elif min == 90: - release = 'Me' - else: - release = 'postMe' - elif maj == 5: - release = '2000' - - elif plat == VER_PLATFORM_WIN32_NT: - regkey = 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion' - if maj <= 4: - release = 'NT' - elif maj == 5: - if min == 0: - release = '2000' - elif min == 1: - release = 'XP' - elif min == 2: - release = '2003Server' - else: - release = 'post2003' - elif maj == 6: - if hasattr(winver, "product_type"): - product_type = winver.product_type - else: - product_type = VER_NT_WORKSTATION - # Without an OSVERSIONINFOEX capable sys.getwindowsversion(), - # or help from the registry, we cannot properly identify - # non-workstation versions. - try: - key = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regkey) - name, type = RegQueryValueEx(key, "ProductName") - # Discard any type that isn't REG_SZ - if type == REG_SZ and name.find("Server") != -1: - product_type = VER_NT_SERVER - except OSError: - # Use default of VER_NT_WORKSTATION - pass - - if min == 0: - if product_type == VER_NT_WORKSTATION: - release = 'Vista' - else: - release = '2008Server' - elif min == 1: - if product_type == VER_NT_WORKSTATION: - release = '7' - else: - release = '2008ServerR2' - elif min == 2: - if product_type == VER_NT_WORKSTATION: - release = '8' - else: - release = '2012Server' - else: - release = 'post2012Server' + if csd[:13] == 'Service Pack ': + csd = 'SP' + csd[13:] - else: - if not release: - # E.g. Win3.1 with win32s - release = '%i.%i' % (maj,min) - return release,version,csd,ptype + # VER_NT_SERVER = 3 + if getattr(winver, 'product_type', None) == 3: + release = (_WIN32_SERVER_RELEASES.get((maj, min)) or + _WIN32_SERVER_RELEASES.get((maj, None)) or + release) - # Open the registry key + key = None try: - keyCurVer = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regkey) - # Get a value to make sure the key exists... - RegQueryValueEx(keyCurVer, 'SystemRoot') + key = OpenKeyEx(HKEY_LOCAL_MACHINE, + r'SOFTWARE\Microsoft\Windows NT\CurrentVersion') + ptype = QueryValueEx(key, 'CurrentType')[0] except: - return release,version,csd,ptype - - # Parse values - #subversion = _win32_getvalue(keyCurVer, - # 'SubVersionNumber', - # ('',1))[0] - #if subversion: - # release = release + subversion # 95a, 95b, etc. - build = _win32_getvalue(keyCurVer, - 'CurrentBuildNumber', - ('',1))[0] - ptype = _win32_getvalue(keyCurVer, - 'CurrentType', - (ptype,1))[0] - - # Normalize version - version = _norm_version(version,build) - - # Close key - RegCloseKey(keyCurVer) - return release,version,csd,ptype + pass + finally: + if key: + CloseKey(key) + + return release, version, csd, ptype + def _mac_ver_xml(): fn = '/System/Library/CoreServices/SystemVersion.plist' @@ -644,18 +617,19 @@ def _mac_ver_xml(): except ImportError: return None - pl = plistlib.readPlist(fn) + with open(fn, 'rb') as f: + pl = plistlib.load(f) release = pl['ProductVersion'] - versioninfo=('', '', '') + versioninfo = ('', '', '') machine = os.uname().machine if machine in ('ppc', 'Power Macintosh'): # Canonical name machine = 'PowerPC' - return release,versioninfo,machine + return release, versioninfo, machine -def mac_ver(release='',versioninfo=('','',''),machine=''): +def mac_ver(release='', versioninfo=('', '', ''), machine=''): """ Get MacOS version information and return it as tuple (release, versioninfo, machine) with versioninfo being a tuple (version, @@ -672,9 +646,9 @@ def mac_ver(release='',versioninfo=('','',''),machine=''): return info # If that also doesn't work return the default values - return release,versioninfo,machine + return release, versioninfo, machine -def _java_getprop(name,default): +def _java_getprop(name, default): from java.lang import System try: @@ -685,13 +659,13 @@ def _java_getprop(name,default): except AttributeError: return default -def java_ver(release='',vendor='',vminfo=('','',''),osinfo=('','','')): +def java_ver(release='', vendor='', vminfo=('', '', ''), osinfo=('', '', '')): """ Version interface for Jython. - Returns a tuple (release,vendor,vminfo,osinfo) with vminfo being - a tuple (vm_name,vm_release,vm_vendor) and osinfo being a - tuple (os_name,os_version,os_arch). + Returns a tuple (release, vendor, vminfo, osinfo) with vminfo being + a tuple (vm_name, vm_release, vm_vendor) and osinfo being a + tuple (os_name, os_version, os_arch). Values which cannot be determined are set to the defaults given as parameters (which all default to ''). @@ -701,7 +675,7 @@ def java_ver(release='',vendor='',vminfo=('','',''),osinfo=('','','')): try: import java.lang except ImportError: - return release,vendor,vminfo,osinfo + return release, vendor, vminfo, osinfo vendor = _java_getprop('java.vendor', vendor) release = _java_getprop('java.version', release) @@ -720,9 +694,9 @@ def java_ver(release='',vendor='',vminfo=('','',''),osinfo=('','','')): ### System name aliasing -def system_alias(system,release,version): +def system_alias(system, release, version): - """ Returns (system,release,version) aliased to common + """ Returns (system, release, version) aliased to common marketing names used for some systems. It also does some reordering of the information in some cases @@ -732,13 +706,13 @@ def system_alias(system,release,version): if system == 'Rhapsody': # Apple's BSD derivative # XXX How can we determine the marketing release number ? - return 'MacOS X Server',system+release,version + return 'MacOS X Server', system+release, version elif system == 'SunOS': # Sun's OS if release < '5': # These releases use the old name SunOS - return system,release,version + return system, release, version # Modify release (marketing release = SunOS release - 3) l = release.split('.') if l: @@ -766,11 +740,11 @@ def system_alias(system,release,version): else: version = '64bit' - elif system in ('win32','win16'): + elif system in ('win32', 'win16'): # In case one of the other tricks system = 'Windows' - return system,release,version + return system, release, version ### Various internal helpers @@ -783,21 +757,21 @@ def _platform(*args): platform = '-'.join(x.strip() for x in filter(len, args)) # Cleanup some possible filename obstacles... - platform = platform.replace(' ','_') - platform = platform.replace('/','-') - platform = platform.replace('\\','-') - platform = platform.replace(':','-') - platform = platform.replace(';','-') - platform = platform.replace('"','-') - platform = platform.replace('(','-') - platform = platform.replace(')','-') + platform = platform.replace(' ', '_') + platform = platform.replace('/', '-') + platform = platform.replace('\\', '-') + platform = platform.replace(':', '-') + platform = platform.replace(';', '-') + platform = platform.replace('"', '-') + platform = platform.replace('(', '-') + platform = platform.replace(')', '-') # No need to report 'unknown' information... - platform = platform.replace('unknown','') + platform = platform.replace('unknown', '') # Fold '--'s and remove trailing '-' while 1: - cleaned = platform.replace('--','-') + cleaned = platform.replace('--', '-') if cleaned == platform: break platform = cleaned @@ -829,14 +803,14 @@ def _follow_symlinks(filepath): filepath = os.path.abspath(filepath) while os.path.islink(filepath): filepath = os.path.normpath( - os.path.join(os.path.dirname(filepath),os.readlink(filepath))) + os.path.join(os.path.dirname(filepath), os.readlink(filepath))) return filepath -def _syscmd_uname(option,default=''): +def _syscmd_uname(option, default=''): """ Interface to the system's uname command. """ - if sys.platform in ('dos','win32','win16'): + if sys.platform in ('dos', 'win32', 'win16'): # XXX Others too ? return default try: @@ -850,7 +824,7 @@ def _syscmd_uname(option,default=''): else: return output -def _syscmd_file(target,default=''): +def _syscmd_file(target, default=''): """ Interface to the system's file command. @@ -859,7 +833,7 @@ def _syscmd_file(target,default=''): default in case the command should fail. """ - if sys.platform in ('dos','win32','win16'): + if sys.platform in ('dos', 'win32', 'win16'): # XXX Others too ? return default target = _follow_symlinks(target) @@ -881,17 +855,17 @@ def _syscmd_file(target,default=''): # Default values for architecture; non-empty strings override the # defaults given as parameters _default_architecture = { - 'win32': ('','WindowsPE'), - 'win16': ('','Windows'), - 'dos': ('','MSDOS'), + 'win32': ('', 'WindowsPE'), + 'win16': ('', 'Windows'), + 'dos': ('', 'MSDOS'), } -def architecture(executable=sys.executable,bits='',linkage=''): +def architecture(executable=sys.executable, bits='', linkage=''): """ Queries the given executable (defaults to the Python interpreter binary) for various architecture information. - Returns a tuple (bits,linkage) which contains information about + Returns a tuple (bits, linkage) which contains information about the bit architecture and the linkage format used for the executable. Both values are returned as strings. @@ -929,16 +903,16 @@ def architecture(executable=sys.executable,bits='',linkage=''): # "file" command did not return anything; we'll try to provide # some sensible defaults then... if sys.platform in _default_architecture: - b,l = _default_architecture[sys.platform] + b, l = _default_architecture[sys.platform] if b: bits = b if l: linkage = l - return bits,linkage + return bits, linkage if 'executable' not in fileout: # Format not supported - return bits,linkage + return bits, linkage # Bits if '32-bit' in fileout: @@ -966,7 +940,7 @@ def architecture(executable=sys.executable,bits='',linkage=''): # XXX the A.OUT format also falls under this class... pass - return bits,linkage + return bits, linkage ### Portable uname() interface @@ -978,7 +952,7 @@ def architecture(executable=sys.executable,bits='',linkage=''): def uname(): """ Fairly portable uname interface. Returns a tuple - of strings (system,node,release,version,machine,processor) + of strings (system, node, release, version, machine, processor) identifying the underlying platform. Note that unlike the os.uname function this also returns @@ -997,7 +971,7 @@ def uname(): # Get some infos from the builtin os.uname API... try: - system,node,release,version,machine = os.uname() + system, node, release, version, machine = os.uname() except AttributeError: no_os_uname = 1 @@ -1015,7 +989,7 @@ def uname(): # Try win32_ver() on win32 platforms if system == 'win32': - release,version,csd,ptype = win32_ver() + release, version, csd, ptype = win32_ver() if release and version: use_syscmd_ver = 0 # Try to use the PROCESSOR_* environment variables @@ -1034,7 +1008,7 @@ def uname(): # Try the 'ver' system command available on some # platforms if use_syscmd_ver: - system,release,version = _syscmd_ver(system) + system, release, version = _syscmd_ver(system) # Normalize system to what win32_ver() normally returns # (_syscmd_ver() tends to return the vendor name as well) if system == 'Microsoft Windows': @@ -1052,7 +1026,7 @@ def uname(): # In case we still don't know anything useful, we'll try to # help ourselves - if system in ('win32','win16'): + if system in ('win32', 'win16'): if not version: if system == 'win32': version = '32bit' @@ -1061,7 +1035,7 @@ def uname(): system = 'Windows' elif system[:4] == 'java': - release,vendor,vminfo,osinfo = java_ver() + release, vendor, vminfo, osinfo = java_ver() system = 'Java' version = ', '.join(vminfo) if not version: @@ -1079,14 +1053,14 @@ def uname(): except ImportError: pass else: - csid, cpu_number = vms_lib.getsyi('SYI$_CPU',0) + csid, cpu_number = vms_lib.getsyi('SYI$_CPU', 0) if (cpu_number >= 128): processor = 'Alpha' else: processor = 'VAX' if not processor: # Get processor information from the uname system command - processor = _syscmd_uname('-p','') + processor = _syscmd_uname('-p', '') #If any unknowns still exist, replace them with ''s, which are more portable if system == 'unknown': @@ -1107,7 +1081,8 @@ def uname(): system = 'Windows' release = 'Vista' - _uname_cache = uname_result(system,node,release,version,machine,processor) + _uname_cache = uname_result(system, node, release, version, + machine, processor) return _uname_cache ### Direct interfaces to some of the uname() return values @@ -1404,57 +1379,66 @@ def platform(aliased=0, terse=0): # Get uname information and then apply platform specific cosmetics # to it... - system,node,release,version,machine,processor = uname() + system, node, release, version, machine, processor = uname() if machine == processor: processor = '' if aliased: - system,release,version = system_alias(system,release,version) + system, release, version = system_alias(system, release, version) if system == 'Windows': # MS platforms - rel,vers,csd,ptype = win32_ver(version) + rel, vers, csd, ptype = win32_ver(version) if terse: - platform = _platform(system,release) + platform = _platform(system, release) else: - platform = _platform(system,release,version,csd) + platform = _platform(system, release, version, csd) elif system in ('Linux',): # Linux based systems - distname,distversion,distid = dist('') + with warnings.catch_warnings(): + # see issue #1322 for more information + warnings.filterwarnings( + 'ignore', + 'dist\(\) and linux_distribution\(\) ' + 'functions are deprecated .*', + PendingDeprecationWarning, + ) + distname, distversion, distid = dist('') if distname and not terse: - platform = _platform(system,release,machine,processor, + platform = _platform(system, release, machine, processor, 'with', - distname,distversion,distid) + distname, distversion, distid) else: # If the distribution name is unknown check for libc vs. glibc - libcname,libcversion = libc_ver(sys.executable) - platform = _platform(system,release,machine,processor, + libcname, libcversion = libc_ver(sys.executable) + platform = _platform(system, release, machine, processor, 'with', libcname+libcversion) elif system == 'Java': # Java platforms - r,v,vminfo,(os_name,os_version,os_arch) = java_ver() + r, v, vminfo, (os_name, os_version, os_arch) = java_ver() if terse or not os_name: - platform = _platform(system,release,version) + platform = _platform(system, release, version) else: - platform = _platform(system,release,version, + platform = _platform(system, release, version, 'on', - os_name,os_version,os_arch) + os_name, os_version, os_arch) elif system == 'MacOS': # MacOS platforms if terse: - platform = _platform(system,release) + platform = _platform(system, release) else: - platform = _platform(system,release,machine) + platform = _platform(system, release, machine) else: # Generic handler if terse: - platform = _platform(system,release) + platform = _platform(system, release) else: - bits,linkage = architecture(sys.executable) - platform = _platform(system,release,machine,processor,bits,linkage) + bits, linkage = architecture(sys.executable) + platform = _platform(system, release, machine, + processor, bits, linkage) _platform_cache[(aliased, terse)] = platform return platform @@ -1465,5 +1449,5 @@ def platform(aliased=0, terse=0): # Default is to print the aliased verbose platform string terse = ('terse' in sys.argv or '--terse' in sys.argv) aliased = (not 'nonaliased' in sys.argv and not '--nonaliased' in sys.argv) - print(platform(aliased,terse)) + print(platform(aliased, terse)) sys.exit(0) diff --git a/Lib/plistlib.py b/Lib/plistlib.py index 277ce622d001..b9946fd313af 100644 --- a/Lib/plistlib.py +++ b/Lib/plistlib.py @@ -478,7 +478,10 @@ def write_value(self, value): self.simple_element("false") elif isinstance(value, int): - self.simple_element("integer", "%d" % value) + if -1 << 63 <= value < 1 << 64: + self.simple_element("integer", "%d" % value) + else: + raise OverflowError(value) elif isinstance(value, float): self.simple_element("real", repr(value)) @@ -616,10 +619,7 @@ def parse(self, fp): offset_table_offset ) = struct.unpack('>6xBBQQQ', trailer) self._fp.seek(offset_table_offset) - offset_format = '>' + _BINARY_FORMAT[offset_size] * num_objects - self._ref_format = _BINARY_FORMAT[self._ref_size] - self._object_offsets = struct.unpack( - offset_format, self._fp.read(offset_size * num_objects)) + self._object_offsets = self._read_ints(num_objects, offset_size) return self._read_object(self._object_offsets[top_object]) except (OSError, IndexError, struct.error): @@ -635,9 +635,16 @@ def _get_size(self, tokenL): return tokenL + def _read_ints(self, n, size): + data = self._fp.read(size * n) + if size in _BINARY_FORMAT: + return struct.unpack('>' + _BINARY_FORMAT[size] * n, data) + else: + return tuple(int.from_bytes(data[i: i + size], 'big') + for i in range(0, size * n, size)) + def _read_refs(self, n): - return struct.unpack( - '>' + self._ref_format * n, self._fp.read(n * self._ref_size)) + return self._read_ints(n, self._ref_size) def _read_object(self, offset): """ @@ -665,7 +672,8 @@ def _read_object(self, offset): return b'' elif tokenH == 0x10: # int - return int.from_bytes(self._fp.read(1 << tokenL), 'big') + return int.from_bytes(self._fp.read(1 << tokenL), + 'big', signed=tokenL >= 3) elif token == 0x22: # real return struct.unpack('>f', self._fp.read(4))[0] @@ -871,14 +879,23 @@ def _write_object(self, value): self._fp.write(b'\x09') elif isinstance(value, int): - if value < 1 << 8: + if value < 0: + try: + self._fp.write(struct.pack('>Bq', 0x13, value)) + except struct.error: + raise OverflowError(value) from None + elif value < 1 << 8: self._fp.write(struct.pack('>BB', 0x10, value)) elif value < 1 << 16: self._fp.write(struct.pack('>BH', 0x11, value)) elif value < 1 << 32: self._fp.write(struct.pack('>BL', 0x12, value)) - else: + elif value < 1 << 63: self._fp.write(struct.pack('>BQ', 0x13, value)) + elif value < 1 << 64: + self._fp.write(b'\x14' + value.to_bytes(16, 'big', signed=True)) + else: + raise OverflowError(value) elif isinstance(value, float): self._fp.write(struct.pack('>Bd', 0x23, value)) @@ -933,7 +950,7 @@ def _write_object(self, value): self._fp.write(struct.pack('>' + self._ref_format * s, *valRefs)) else: - raise InvalidFileException() + raise TypeError(value) def _is_fmt_binary(header): @@ -967,18 +984,16 @@ def load(fp, *, fmt=None, use_builtin_types=True, dict_type=dict): fp.seek(0) for info in _FORMATS.values(): if info['detect'](header): - p = info['parser']( - use_builtin_types=use_builtin_types, - dict_type=dict_type, - ) + P = info['parser'] break else: raise InvalidFileException() else: - p = _FORMATS[fmt]['parser'](use_builtin_types=use_builtin_types) + P = _FORMATS[fmt]['parser'] + p = P(use_builtin_types=use_builtin_types, dict_type=dict_type) return p.parse(fp) diff --git a/Lib/poplib.py b/Lib/poplib.py index 00ffbcb166ba..f6723904e859 100644 --- a/Lib/poplib.py +++ b/Lib/poplib.py @@ -41,7 +41,7 @@ class error_proto(Exception): pass CRLF = CR+LF # maximal line length when calling readline(). This is to prevent -# reading arbitrary lenght lines. RFC 1939 limits POP3 line length to +# reading arbitrary length lines. RFC 1939 limits POP3 line length to # 512 characters, including CRLF. We have selected 2048 just to be on # the safe side. _MAXLINE = 2048 @@ -71,6 +71,7 @@ class POP3: UIDL [msg] uidl(msg = None) CAPA capa() STLS stls() + UTF8 utf8() Raises one exception: 'error_proto'. @@ -136,7 +137,7 @@ def _getline(self): # so only possibilities are ...LF, ...CRLF, CR...LF if line[-2:] == CRLF: return line[:-2], octets - if line[0] == CR: + if line[:1] == CR: return line[1:-1], octets return line[:-1], octets @@ -276,18 +277,23 @@ def quit(self): def close(self): """Close the connection without assuming anything about it.""" - if self.file is not None: - self.file.close() - if self.sock is not None: - try: - self.sock.shutdown(socket.SHUT_RDWR) - except OSError as e: - # The server might already have closed the connection - if e.errno != errno.ENOTCONN: - raise - finally: - self.sock.close() - self.file = self.sock = None + try: + file = self.file + self.file = None + if file is not None: + file.close() + finally: + sock = self.sock + self.sock = None + if sock is not None: + try: + sock.shutdown(socket.SHUT_RDWR) + except OSError as e: + # The server might already have closed the connection + if e.errno != errno.ENOTCONN: + raise + finally: + sock.close() #__del__ = quit @@ -343,6 +349,12 @@ def uidl(self, which=None): return self._longcmd('UIDL') + def utf8(self): + """Try to enter UTF-8 mode (see RFC 6856). Returns server response. + """ + return self._shortcmd('UTF8') + + def capa(self): """Return server capabilities (RFC 2449) as a dictionary >>> c=poplib.POP3('localhost') @@ -387,7 +399,8 @@ def stls(self, context=None): if context is None: context = ssl._create_stdlib_context() resp = self._shortcmd('STLS') - self.sock = context.wrap_socket(self.sock) + self.sock = context.wrap_socket(self.sock, + server_hostname=self.host) self.file = self.sock.makefile('rb') self._tls_established = True return resp @@ -428,7 +441,8 @@ def __init__(self, host, port=POP3_SSL_PORT, keyfile=None, certfile=None, def _create_socket(self, timeout): sock = POP3._create_socket(self, timeout) - sock = self.context.wrap_socket(sock) + sock = self.context.wrap_socket(sock, + server_hostname=self.host) return sock def stls(self, keyfile=None, certfile=None, context=None): diff --git a/Lib/posixpath.py b/Lib/posixpath.py index 492c415aa5da..09b889796849 100644 --- a/Lib/posixpath.py +++ b/Lib/posixpath.py @@ -22,7 +22,8 @@ "ismount", "expanduser","expandvars","normpath","abspath", "samefile","sameopenfile","samestat", "curdir","pardir","sep","pathsep","defpath","altsep","extsep", - "devnull","realpath","supports_unicode_filenames","relpath"] + "devnull","realpath","supports_unicode_filenames","relpath", + "commonpath"] # Strings representing various path-related bits and pieces. # These are primarily for export; internally, they are hardcoded. @@ -48,7 +49,6 @@ def _get_sep(path): def normcase(s): """Normalize case of pathname. Has no effect under Posix""" - # TODO: on Mac OS X, this should really return s.lower(). if not isinstance(s, (bytes, str)): raise TypeError("normcase() argument must be str or bytes, " "not '{}'".format(s.__class__.__name__)) @@ -76,6 +76,8 @@ def join(a, *p): sep = _get_sep(a) path = a try: + if not p: + path[:0] + sep #23780: Ensure compatible data type even if p is null. for b in p: if b.startswith(sep): path = b @@ -83,13 +85,8 @@ def join(a, *p): path += b else: path += sep + b - except TypeError: - valid_types = all(isinstance(s, (str, bytes, bytearray)) - for s in (a, ) + p) - if valid_types: - # Must have a mixture of text and binary data - raise TypeError("Can't mix strings and bytes in path " - "components.") from None + except (TypeError, AttributeError, BytesWarning): + genericpath._check_arg_types('join', a, *p) raise return path @@ -279,6 +276,7 @@ def expandvars(path): search = _varprogb.search start = b'{' end = b'}' + environ = getattr(os, 'environb', None) else: if '$' not in path: return path @@ -288,6 +286,7 @@ def expandvars(path): search = _varprog.search start = '{' end = '}' + environ = os.environ i = 0 while True: m = search(path, i) @@ -297,18 +296,18 @@ def expandvars(path): name = m.group(1) if name.startswith(start) and name.endswith(end): name = name[1:-1] - if isinstance(name, bytes): - name = str(name, 'ASCII') - if name in os.environ: + try: + if environ is None: + value = os.fsencode(os.environ[os.fsdecode(name)]) + else: + value = environ[name] + except KeyError: + i = j + else: tail = path[j:] - value = os.environ[name] - if isinstance(path, bytes): - value = value.encode('ASCII') path = path[:i] + value i = len(path) path += tail - else: - i = j return path @@ -446,13 +445,58 @@ def relpath(path, start=None): if start is None: start = curdir - start_list = [x for x in abspath(start).split(sep) if x] - path_list = [x for x in abspath(path).split(sep) if x] + try: + start_list = [x for x in abspath(start).split(sep) if x] + path_list = [x for x in abspath(path).split(sep) if x] + # Work out how much of the filepath is shared by start and path. + i = len(commonprefix([start_list, path_list])) + + rel_list = [pardir] * (len(start_list)-i) + path_list[i:] + if not rel_list: + return curdir + return join(*rel_list) + except (TypeError, AttributeError, BytesWarning, DeprecationWarning): + genericpath._check_arg_types('relpath', path, start) + raise + - # Work out how much of the filepath is shared by start and path. - i = len(commonprefix([start_list, path_list])) +# Return the longest common sub-path of the sequence of paths given as input. +# The paths are not normalized before comparing them (this is the +# responsibility of the caller). Any trailing separator is stripped from the +# returned path. - rel_list = [pardir] * (len(start_list)-i) + path_list[i:] - if not rel_list: - return curdir - return join(*rel_list) +def commonpath(paths): + """Given a sequence of path names, returns the longest common sub-path.""" + + if not paths: + raise ValueError('commonpath() arg is an empty sequence') + + if isinstance(paths[0], bytes): + sep = b'/' + curdir = b'.' + else: + sep = '/' + curdir = '.' + + try: + split_paths = [path.split(sep) for path in paths] + + try: + isabs, = set(p[:1] == sep for p in paths) + except ValueError: + raise ValueError("Can't mix absolute and relative paths") from None + + split_paths = [[c for c in s if c and c != curdir] for s in split_paths] + s1 = min(split_paths) + s2 = max(split_paths) + common = s1 + for i, c in enumerate(s1): + if c != s2[i]: + common = s1[:i] + break + + prefix = sep if isabs else sep[:0] + return prefix + sep.join(common) + except (TypeError, AttributeError): + genericpath._check_arg_types('commonpath', *paths) + raise diff --git a/Lib/pprint.py b/Lib/pprint.py index 3be9c3625401..87649b48cdfa 100644 --- a/Lib/pprint.py +++ b/Lib/pprint.py @@ -34,9 +34,10 @@ """ +import collections as _collections import re import sys as _sys -from collections import OrderedDict as _OrderedDict +import types as _types from io import StringIO as _StringIO __all__ = ["pprint","pformat","isreadable","isrecursive","saferepr", @@ -85,14 +86,10 @@ def __init__(self, obj): def __lt__(self, other): try: - rv = self.obj.__lt__(other.obj) + return self.obj < other.obj except TypeError: - rv = NotImplemented - - if rv is NotImplemented: - rv = (str(type(self.obj)), id(self.obj)) < \ - (str(type(other.obj)), id(other.obj)) - return rv + return ((str(type(self.obj)), id(self.obj)) < \ + (str(type(other.obj)), id(other.obj))) def _safe_tuple(t): "Helper function for comparing 2-tuples" @@ -123,9 +120,12 @@ def __init__(self, indent=1, width=80, depth=None, stream=None, *, """ indent = int(indent) width = int(width) - assert indent >= 0, "indent must be >= 0" - assert depth is None or depth > 0, "depth must be > 0" - assert width, "width must be != 0" + if indent < 0: + raise ValueError('indent must be >= 0') + if depth is not None and depth <= 0: + raise ValueError('depth must be > 0') + if not width: + raise ValueError('width must be != 0') self._depth = depth self._indent_per_level = indent self._width = width @@ -152,127 +152,223 @@ def isreadable(self, object): return readable and not recursive def _format(self, object, stream, indent, allowance, context, level): - level = level + 1 objid = id(object) if objid in context: stream.write(_recursion(object)) self._recursive = True self._readable = False return - rep = self._repr(object, context, level - 1) - typ = type(object) - max_width = self._width - 1 - indent - allowance - sepLines = len(rep) > max_width - write = stream.write - - if sepLines: - r = getattr(typ, "__repr__", None) - if issubclass(typ, dict): - write('{') - if self._indent_per_level > 1: - write((self._indent_per_level - 1) * ' ') - length = len(object) - if length: - context[objid] = 1 - indent = indent + self._indent_per_level - if issubclass(typ, _OrderedDict): - items = list(object.items()) - else: - items = sorted(object.items(), key=_safe_tuple) - key, ent = items[0] - rep = self._repr(key, context, level) - write(rep) - write(': ') - self._format(ent, stream, indent + len(rep) + 2, - allowance + 1, context, level) - if length > 1: - for key, ent in items[1:]: - rep = self._repr(key, context, level) - write(',\n%s%s: ' % (' '*indent, rep)) - self._format(ent, stream, indent + len(rep) + 2, - allowance + 1, context, level) - indent = indent - self._indent_per_level - del context[objid] - write('}') + rep = self._repr(object, context, level) + max_width = self._width - indent - allowance + if len(rep) > max_width: + p = self._dispatch.get(type(object).__repr__, None) + if p is not None: + context[objid] = 1 + p(self, object, stream, indent, allowance, context, level + 1) + del context[objid] + return + elif isinstance(object, dict): + context[objid] = 1 + self._pprint_dict(object, stream, indent, allowance, + context, level + 1) + del context[objid] return + stream.write(rep) + + _dispatch = {} - if ((issubclass(typ, list) and r is list.__repr__) or - (issubclass(typ, tuple) and r is tuple.__repr__) or - (issubclass(typ, set) and r is set.__repr__) or - (issubclass(typ, frozenset) and r is frozenset.__repr__) - ): - length = len(object) - if issubclass(typ, list): - write('[') - endchar = ']' - elif issubclass(typ, tuple): - write('(') - endchar = ')' - else: - if not length: - write(rep) - return - if typ is set: - write('{') - endchar = '}' + def _pprint_dict(self, object, stream, indent, allowance, context, level): + write = stream.write + write('{') + if self._indent_per_level > 1: + write((self._indent_per_level - 1) * ' ') + length = len(object) + if length: + items = sorted(object.items(), key=_safe_tuple) + self._format_dict_items(items, stream, indent, allowance + 1, + context, level) + write('}') + + _dispatch[dict.__repr__] = _pprint_dict + + def _pprint_ordered_dict(self, object, stream, indent, allowance, context, level): + if not len(object): + stream.write(repr(object)) + return + cls = object.__class__ + stream.write(cls.__name__ + '(') + self._format(list(object.items()), stream, + indent + len(cls.__name__) + 1, allowance + 1, + context, level) + stream.write(')') + + _dispatch[_collections.OrderedDict.__repr__] = _pprint_ordered_dict + + def _pprint_list(self, object, stream, indent, allowance, context, level): + stream.write('[') + self._format_items(object, stream, indent, allowance + 1, + context, level) + stream.write(']') + + _dispatch[list.__repr__] = _pprint_list + + def _pprint_tuple(self, object, stream, indent, allowance, context, level): + stream.write('(') + endchar = ',)' if len(object) == 1 else ')' + self._format_items(object, stream, indent, allowance + len(endchar), + context, level) + stream.write(endchar) + + _dispatch[tuple.__repr__] = _pprint_tuple + + def _pprint_set(self, object, stream, indent, allowance, context, level): + if not len(object): + stream.write(repr(object)) + return + typ = object.__class__ + if typ is set: + stream.write('{') + endchar = '}' + else: + stream.write(typ.__name__ + '({') + endchar = '})' + indent += len(typ.__name__) + 1 + object = sorted(object, key=_safe_key) + self._format_items(object, stream, indent, allowance + len(endchar), + context, level) + stream.write(endchar) + + _dispatch[set.__repr__] = _pprint_set + _dispatch[frozenset.__repr__] = _pprint_set + + def _pprint_str(self, object, stream, indent, allowance, context, level): + write = stream.write + if not len(object): + write(repr(object)) + return + chunks = [] + lines = object.splitlines(True) + if level == 1: + indent += 1 + allowance += 1 + max_width1 = max_width = self._width - indent + for i, line in enumerate(lines): + rep = repr(line) + if i == len(lines) - 1: + max_width1 -= allowance + if len(rep) <= max_width1: + chunks.append(rep) + else: + # A list of alternating (non-space, space) strings + parts = re.findall(r'\S*\s*', line) + assert parts + assert not parts[-1] + parts.pop() # drop empty last part + max_width2 = max_width + current = '' + for j, part in enumerate(parts): + candidate = current + part + if j == len(parts) - 1 and i == len(lines) - 1: + max_width2 -= allowance + if len(repr(candidate)) > max_width2: + if current: + chunks.append(repr(current)) + current = part else: - write(typ.__name__) - write('({') - endchar = '})' - indent += len(typ.__name__) + 1 - object = sorted(object, key=_safe_key) - if self._indent_per_level > 1: - write((self._indent_per_level - 1) * ' ') - if length: - context[objid] = 1 - self._format_items(object, stream, - indent + self._indent_per_level, - allowance + 1, context, level) - del context[objid] - if issubclass(typ, tuple) and length == 1: - write(',') - write(endchar) - return + current = candidate + if current: + chunks.append(repr(current)) + if len(chunks) == 1: + write(rep) + return + if level == 1: + write('(') + for i, rep in enumerate(chunks): + if i > 0: + write('\n' + ' '*indent) + write(rep) + if level == 1: + write(')') + + _dispatch[str.__repr__] = _pprint_str + + def _pprint_bytes(self, object, stream, indent, allowance, context, level): + write = stream.write + if len(object) <= 4: + write(repr(object)) + return + parens = level == 1 + if parens: + indent += 1 + allowance += 1 + write('(') + delim = '' + for rep in _wrap_bytes_repr(object, self._width - indent, allowance): + write(delim) + write(rep) + if not delim: + delim = '\n' + ' '*indent + if parens: + write(')') - if issubclass(typ, str) and len(object) > 0 and r is str.__repr__: - def _str_parts(s): - """ - Return a list of string literals comprising the repr() - of the given string using literal concatenation. - """ - lines = s.splitlines(True) - for i, line in enumerate(lines): - rep = repr(line) - if len(rep) <= max_width: - yield rep - else: - # A list of alternating (non-space, space) strings - parts = re.split(r'(\s+)', line) + [''] - current = '' - for i in range(0, len(parts), 2): - part = parts[i] + parts[i+1] - candidate = current + part - if len(repr(candidate)) > max_width: - if current: - yield repr(current) - current = part - else: - current = candidate - if current: - yield repr(current) - for i, rep in enumerate(_str_parts(object)): - if i > 0: - write('\n' + ' '*indent) - write(rep) - return - write(rep) + _dispatch[bytes.__repr__] = _pprint_bytes + + def _pprint_bytearray(self, object, stream, indent, allowance, context, level): + write = stream.write + write('bytearray(') + self._pprint_bytes(bytes(object), stream, indent + 10, + allowance + 1, context, level + 1) + write(')') + + _dispatch[bytearray.__repr__] = _pprint_bytearray + + def _pprint_mappingproxy(self, object, stream, indent, allowance, context, level): + stream.write('mappingproxy(') + self._format(object.copy(), stream, indent + 13, allowance + 1, + context, level) + stream.write(')') + + _dispatch[_types.MappingProxyType.__repr__] = _pprint_mappingproxy + + def _format_dict_items(self, items, stream, indent, allowance, context, + level): + write = stream.write + indent += self._indent_per_level + delimnl = ',\n' + ' ' * indent + last_index = len(items) - 1 + for i, (key, ent) in enumerate(items): + last = i == last_index + rep = self._repr(key, context, level) + write(rep) + write(': ') + self._format(ent, stream, indent + len(rep) + 2, + allowance if last else 1, + context, level) + if not last: + write(delimnl) def _format_items(self, items, stream, indent, allowance, context, level): write = stream.write + indent += self._indent_per_level + if self._indent_per_level > 1: + write((self._indent_per_level - 1) * ' ') delimnl = ',\n' + ' ' * indent delim = '' - width = max_width = self._width - indent - allowance + 2 - for ent in items: + width = max_width = self._width - indent + 1 + it = iter(items) + try: + next_ent = next(it) + except StopIteration: + return + last = False + while not last: + ent = next_ent + try: + next_ent = next(it) + except StopIteration: + last = True + max_width -= allowance + width -= allowance if self._compact: rep = self._repr(ent, context, level) w = len(rep) + 2 @@ -288,7 +384,9 @@ def _format_items(self, items, stream, indent, allowance, context, level): continue write(delim) delim = delimnl - self._format(ent, stream, indent, allowance, context, level) + self._format(ent, stream, indent, + allowance if last else 1, + context, level) def _repr(self, object, context, level): repr, readable, recursive = self.format(object, context.copy(), @@ -306,29 +404,93 @@ def format(self, object, context, maxlevels, level): """ return _safe_repr(object, context, maxlevels, level) + def _pprint_default_dict(self, object, stream, indent, allowance, context, level): + if not len(object): + stream.write(repr(object)) + return + rdf = self._repr(object.default_factory, context, level) + cls = object.__class__ + indent += len(cls.__name__) + 1 + stream.write('%s(%s,\n%s' % (cls.__name__, rdf, ' ' * indent)) + self._pprint_dict(object, stream, indent, allowance + 1, context, level) + stream.write(')') + + _dispatch[_collections.defaultdict.__repr__] = _pprint_default_dict + + def _pprint_counter(self, object, stream, indent, allowance, context, level): + if not len(object): + stream.write(repr(object)) + return + cls = object.__class__ + stream.write(cls.__name__ + '({') + if self._indent_per_level > 1: + stream.write((self._indent_per_level - 1) * ' ') + items = object.most_common() + self._format_dict_items(items, stream, + indent + len(cls.__name__) + 1, allowance + 2, + context, level) + stream.write('})') + + _dispatch[_collections.Counter.__repr__] = _pprint_counter + + def _pprint_chain_map(self, object, stream, indent, allowance, context, level): + if not len(object.maps): + stream.write(repr(object)) + return + cls = object.__class__ + stream.write(cls.__name__ + '(') + indent += len(cls.__name__) + 1 + for i, m in enumerate(object.maps): + if i == len(object.maps) - 1: + self._format(m, stream, indent, allowance + 1, context, level) + stream.write(')') + else: + self._format(m, stream, indent, 1, context, level) + stream.write(',\n' + ' ' * indent) + + _dispatch[_collections.ChainMap.__repr__] = _pprint_chain_map + + def _pprint_deque(self, object, stream, indent, allowance, context, level): + if not len(object): + stream.write(repr(object)) + return + cls = object.__class__ + stream.write(cls.__name__ + '(') + indent += len(cls.__name__) + 1 + stream.write('[') + if object.maxlen is None: + self._format_items(object, stream, indent, allowance + 2, + context, level) + stream.write('])') + else: + self._format_items(object, stream, indent, 2, + context, level) + rml = self._repr(object.maxlen, context, level) + stream.write('],\n%smaxlen=%s)' % (' ' * indent, rml)) + + _dispatch[_collections.deque.__repr__] = _pprint_deque + + def _pprint_user_dict(self, object, stream, indent, allowance, context, level): + self._format(object.data, stream, indent, allowance, context, level - 1) + + _dispatch[_collections.UserDict.__repr__] = _pprint_user_dict + + def _pprint_user_list(self, object, stream, indent, allowance, context, level): + self._format(object.data, stream, indent, allowance, context, level - 1) + + _dispatch[_collections.UserList.__repr__] = _pprint_user_list + + def _pprint_user_string(self, object, stream, indent, allowance, context, level): + self._format(object.data, stream, indent, allowance, context, level - 1) + + _dispatch[_collections.UserString.__repr__] = _pprint_user_string # Return triple (repr_string, isreadable, isrecursive). def _safe_repr(object, context, maxlevels, level): typ = type(object) - if typ is str: - if 'locale' not in _sys.modules: - return repr(object), True, False - if "'" in object and '"' not in object: - closure = '"' - quotes = {'"': '\\"'} - else: - closure = "'" - quotes = {"'": "\\'"} - qget = quotes.get - sio = _StringIO() - write = sio.write - for char in object: - if char.isalpha(): - write(char) - else: - write(qget(char, repr(char)[1:-1])) - return ("%s%s%s" % (closure, sio.getvalue(), closure)), True, False + if typ in _builtin_scalars: + return repr(object), True, False r = getattr(typ, "__repr__", None) if issubclass(typ, dict) and r is dict.__repr__: @@ -393,6 +555,8 @@ def _safe_repr(object, context, maxlevels, level): rep = repr(object) return rep, (rep and not rep.startswith('<')), False +_builtin_scalars = frozenset({str, bytes, bytearray, int, float, complex, + bool, type(None)}) def _recursion(object): return ("" @@ -412,5 +576,22 @@ def _perfcheck(object=None): print("_safe_repr:", t2 - t1) print("pformat:", t3 - t2) +def _wrap_bytes_repr(object, width, allowance): + current = b'' + last = len(object) // 4 * 4 + for i in range(0, len(object), 4): + part = object[i: i+4] + candidate = current + part + if i == last: + width -= allowance + if len(repr(candidate)) > width: + if current: + yield repr(current) + current = part + else: + current = candidate + if current: + yield repr(current) + if __name__ == "__main__": _perfcheck() diff --git a/Lib/py_compile.py b/Lib/py_compile.py index 1277b93ea5e3..11c5b505cc68 100644 --- a/Lib/py_compile.py +++ b/Lib/py_compile.py @@ -1,9 +1,9 @@ -"""Routine to "compile" a .py file to a .pyc (or .pyo) file. +"""Routine to "compile" a .py file to a .pyc file. This module has intimate knowledge of the format of .pyc files. """ -import importlib._bootstrap +import importlib._bootstrap_external import importlib.machinery import importlib.util import os @@ -67,7 +67,7 @@ def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1): :param file: The source file name. :param cfile: The target byte compiled file name. When not given, this - defaults to the PEP 3147 location. + defaults to the PEP 3147/PEP 488 location. :param dfile: Purported file name, i.e. the file name that shows up in error messages. Defaults to the source file name. :param doraise: Flag indicating whether or not an exception should be @@ -85,12 +85,12 @@ def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1): Note that it isn't necessary to byte-compile Python modules for execution efficiency -- Python itself byte-compiles a module when it is loaded, and if it can, writes out the bytecode to the - corresponding .pyc (or .pyo) file. + corresponding .pyc file. However, if a Python installation is shared between users, it is a good idea to byte-compile all modules upon installation, since other users may not be able to write in the source directories, - and thus they won't be able to write the .pyc/.pyo file, and then + and thus they won't be able to write the .pyc file, and then they would be byte-compiling every module each time it is loaded. This can slow down program start-up considerably. @@ -105,8 +105,9 @@ def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1): """ if cfile is None: if optimize >= 0: + optimization = optimize if optimize >= 1 else '' cfile = importlib.util.cache_from_source(file, - debug_override=not optimize) + optimization=optimization) else: cfile = importlib.util.cache_from_source(file) if os.path.islink(cfile): @@ -136,10 +137,10 @@ def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1): except FileExistsError: pass source_stats = loader.path_stats(file) - bytecode = importlib._bootstrap._code_to_bytecode( + bytecode = importlib._bootstrap_external._code_to_bytecode( code, source_stats['mtime'], source_stats['size']) - mode = importlib._bootstrap._calc_mode(file) - importlib._bootstrap._write_atomic(cfile, bytecode, mode) + mode = importlib._bootstrap_external._calc_mode(file) + importlib._bootstrap_external._write_atomic(cfile, bytecode, mode) return cfile @@ -178,7 +179,7 @@ def main(args=None): except PyCompileError as error: # return value to indicate at least one failure rv = 1 - sys.stderr.write(error.msg) + sys.stderr.write("%s\n" % error.msg) return rv if __name__ == "__main__": diff --git a/Lib/pyclbr.py b/Lib/pyclbr.py index 9ec05ee80b27..dd58ada0aa52 100644 --- a/Lib/pyclbr.py +++ b/Lib/pyclbr.py @@ -42,7 +42,7 @@ import io import os import sys -import importlib +import importlib.util import tokenize from token import NAME, DEDENT, OP from operator import itemgetter @@ -140,13 +140,14 @@ def _readmodule(module, path, inpackage=None): search_path = path else: search_path = path + sys.path - loader = importlib.find_loader(fullmodule, search_path) - fname = loader.get_filename(fullmodule) + # XXX This will change once issue19944 lands. + spec = importlib.util._find_spec_from_path(fullmodule, search_path) + fname = spec.loader.get_filename(fullmodule) _modules[fullmodule] = dict - if loader.is_package(fullmodule): + if spec.loader.is_package(fullmodule): dict['__path__'] = [os.path.dirname(fname)] try: - source = loader.get_source(fullmodule) + source = spec.loader.get_source(fullmodule) if source is None: return dict except (AttributeError, ImportError): diff --git a/Lib/pydoc.py b/Lib/pydoc.py old mode 100755 new mode 100644 index 2e632266eb6f..f4f253010f49 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -1,8 +1,9 @@ #!/usr/bin/env python3 """Generate Python documentation in HTML or text for interactive use. -In the Python interpreter, do "from pydoc import help" to provide -help. Calling help(thing) on a Python object documents the object. +At the Python interactive prompt, calling help(thing) on a Python object +documents the object, and calling help() starts up an interactive +help session. Or, at the shell command line outside of Python: @@ -52,6 +53,7 @@ class or function within a module or module in a package. If the import builtins import importlib._bootstrap +import importlib._bootstrap_external import importlib.machinery import importlib.util import inspect @@ -63,10 +65,11 @@ class or function within a module or module in a package. If the import sys import time import tokenize +import urllib.parse import warnings from collections import deque from reprlib import Repr -from traceback import extract_tb, format_exception_only +from traceback import format_exception_only # --------------------------------------------------------- common routines @@ -137,6 +140,19 @@ def _is_some_method(obj): inspect.isbuiltin(obj) or inspect.ismethoddescriptor(obj)) +def _is_bound_method(fn): + """ + Returns True if fn is a bound method, regardless of whether + fn was implemented in Python or in C. + """ + if inspect.ismethod(fn): + return True + if inspect.isbuiltin(fn): + self = getattr(fn, '__self__', None) + return not (inspect.ismodule(self) or (self is None)) + return False + + def allmethods(cl): methods = {} for key, value in inspect.getmembers(cl, _is_some_method): @@ -193,12 +209,24 @@ def classify_class_attrs(object): results.append((name, kind, cls, value)) return results +def sort_attributes(attrs, object): + 'Sort the attrs list in-place by _fields and then alphabetically by name' + # This allows data descriptors to be ordered according + # to a _fields attribute if present. + fields = getattr(object, '_fields', []) + try: + field_order = {name : i-len(fields) for (i, name) in enumerate(fields)} + except TypeError: + field_order = {} + keyfunc = lambda attr: (field_order.get(attr[0], 0), attr[0]) + attrs.sort(key=keyfunc) + # ----------------------------------------------------- module manipulation def ispackage(path): """Guess whether a path refers to a package directory.""" if os.path.isdir(path): - for ext in ('.py', '.pyc', '.pyo'): + for ext in ('.py', '.pyc'): if os.path.isfile(os.path.join(path, '__init__' + ext)): return True return False @@ -225,34 +253,37 @@ def synopsis(filename, cache={}): mtime = os.stat(filename).st_mtime lastupdate, result = cache.get(filename, (None, None)) if lastupdate is None or lastupdate < mtime: - try: - file = tokenize.open(filename) - except OSError: - # module can't be opened, so skip it - return None - binary_suffixes = importlib.machinery.BYTECODE_SUFFIXES[:] - binary_suffixes += importlib.machinery.EXTENSION_SUFFIXES[:] - if any(filename.endswith(x) for x in binary_suffixes): - # binary modules have to be imported - file.close() - if any(filename.endswith(x) for x in - importlib.machinery.BYTECODE_SUFFIXES): - loader = importlib.machinery.SourcelessFileLoader('__temp__', - filename) - else: - loader = importlib.machinery.ExtensionFileLoader('__temp__', - filename) + # Look for binary suffixes first, falling back to source. + if filename.endswith(tuple(importlib.machinery.BYTECODE_SUFFIXES)): + loader_cls = importlib.machinery.SourcelessFileLoader + elif filename.endswith(tuple(importlib.machinery.EXTENSION_SUFFIXES)): + loader_cls = importlib.machinery.ExtensionFileLoader + else: + loader_cls = None + # Now handle the choice. + if loader_cls is None: + # Must be a source file. try: - module = loader.load_module('__temp__') + file = tokenize.open(filename) + except OSError: + # module can't be opened, so skip it + return None + # text modules can be directly examined + with file: + result = source_synopsis(file) + else: + # Must be a binary module, which has to be imported. + loader = loader_cls('__temp__', filename) + # XXX We probably don't need to pass in the loader here. + spec = importlib.util.spec_from_file_location('__temp__', filename, + loader=loader) + try: + module = importlib._bootstrap._load(spec) except: return None - result = (module.__doc__ or '').splitlines()[0] del sys.modules['__temp__'] - else: - # text modules can be directly examined - result = source_synopsis(file) - file.close() - + result = module.__doc__.splitlines()[0] if module.__doc__ else None + # Cache the result. cache[filename] = (mtime, result) return result @@ -274,11 +305,13 @@ def importfile(path): filename = os.path.basename(path) name, ext = os.path.splitext(filename) if is_bytecode: - loader = importlib._bootstrap.SourcelessFileLoader(name, path) + loader = importlib._bootstrap_external.SourcelessFileLoader(name, path) else: - loader = importlib._bootstrap.SourceFileLoader(name, path) + loader = importlib._bootstrap_external.SourceFileLoader(name, path) + # XXX We probably don't need to pass in the loader here. + spec = importlib.util.spec_from_file_location(name, path, loader=loader) try: - return loader.load_module(name) + return importlib._bootstrap._load(spec) except: raise ErrorDuringImport(path, sys.exc_info()) @@ -574,10 +607,15 @@ def markup(self, text, escape=None, funcs={}, classes={}, methods={}): elif pep: url = 'http://www.python.org/dev/peps/pep-%04d/' % int(pep) results.append('%s' % (url, escape(all))) + elif selfdot: + # Create a link for methods like 'self.method(...)' + # and use for attributes like 'self.attr' + if text[end:end+1] == '(': + results.append('self.' + self.namelink(name, methods)) + else: + results.append('self.%s' % name) elif text[end:end+1] == '(': results.append(self.namelink(name, methods, funcs, classes)) - elif selfdot: - results.append('self.%s' % name) else: results.append(self.namelink(name, classes)) here = end @@ -622,10 +660,7 @@ def docmodule(self, object, name=None, mod=None, *ignored): head = '%s' % linkedname try: path = inspect.getabsfile(object) - url = path - if sys.platform == 'win32': - import nturl2path - url = nturl2path.pathname2url(http://github.com/path) + url = urllib.parse.quote(path) filelink = self.filelink(url, path) except TypeError: filelink = '(built-in)' @@ -844,8 +879,7 @@ def spilldata(msg, attrs, predicate): object.__module__) tag += ':
\n' - # Sort attrs by name. - attrs.sort(key=lambda t: t[0]) + sort_attributes(attrs, object) # Pump out the attrs, segregated by kind. attrs = spill('Methods %s' % tag, attrs, @@ -891,7 +925,7 @@ def docroutine(self, object, name=None, mod=None, anchor = (cl and cl.__name__ or '') + '-' + name note = '' skipdocs = 0 - if inspect.ismethod(object): + if _is_bound_method(object): imclass = object.__self__.__class__ if cl: if imclass is not cl: @@ -902,7 +936,6 @@ def docroutine(self, object, name=None, mod=None, object.__self__.__class__, mod) else: note = ' unbound %s method' % self.classlink(imclass,mod) - object = object.__func__ if name == realname: title = '%s' % (anchor, realname) @@ -917,8 +950,11 @@ def docroutine(self, object, name=None, mod=None, title = '%s = %s' % ( anchor, name, reallink) argspec = None - if inspect.isfunction(object) or inspect.isbuiltin(object): - signature = inspect.signature(object) + if inspect.isroutine(object): + try: + signature = inspect.signature(object) + except (ValueError, TypeError): + signature = None if signature: argspec = str(signature) if realname == '': @@ -930,7 +966,7 @@ def docroutine(self, object, name=None, mod=None, if not argspec: argspec = '(...)' - decl = title + argspec + (note and self.grey( + decl = title + self.escape(argspec) + (note and self.grey( '%s' % note)) if skipdocs: @@ -1234,9 +1270,12 @@ def spilldata(msg, attrs, predicate): doc = getdoc(value) else: doc = None - push(self.docother( - getattr(object, name, None) or homecls.__dict__[name], - name, mod, maxlen=70, doc=doc) + '\n') + try: + obj = getattr(object, name) + except AttributeError: + obj = homecls.__dict__[name] + push(self.docother(obj, name, mod, maxlen=70, doc=doc) + + '\n') return attrs attrs = [(name, kind, cls, value) @@ -1258,8 +1297,8 @@ def spilldata(msg, attrs, predicate): else: tag = "inherited from %s" % classname(thisclass, object.__module__) - # Sort attrs by name. - attrs.sort() + + sort_attributes(attrs, object) # Pump out the attrs, segregated by kind. attrs = spill("Methods %s:\n" % tag, attrs, @@ -1291,7 +1330,7 @@ def docroutine(self, object, name=None, mod=None, cl=None): name = name or realname note = '' skipdocs = 0 - if inspect.ismethod(object): + if _is_bound_method(object): imclass = object.__self__.__class__ if cl: if imclass is not cl: @@ -1302,7 +1341,6 @@ def docroutine(self, object, name=None, mod=None, cl=None): object.__self__.__class__, mod) else: note = ' unbound %s method' % classname(imclass,mod) - object = object.__func__ if name == realname: title = self.bold(realname) @@ -1312,8 +1350,12 @@ def docroutine(self, object, name=None, mod=None, cl=None): skipdocs = 1 title = self.bold(name) + ' = ' + realname argspec = None - if inspect.isfunction(object) or inspect.isbuiltin(object): - signature = inspect.signature(object) + + if inspect.isroutine(object): + try: + signature = inspect.signature(object) + except (ValueError, TypeError): + signature = None if signature: argspec = str(signature) if realname == '': @@ -1380,6 +1422,8 @@ def pager(text): def getpager(): """Decide what method to use for paging through text.""" + if not hasattr(sys.stdin, "isatty"): + return plainpager if not hasattr(sys.stdout, "isatty"): return plainpager if not sys.stdin.isatty() or not sys.stdout.isatty(): @@ -1415,39 +1459,64 @@ def plain(text): def pipepager(text, cmd): """Page through text by feeding it to another program.""" - pipe = os.popen(cmd, 'w') + import subprocess + proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE) try: - pipe.write(text) - pipe.close() + with io.TextIOWrapper(proc.stdin, errors='backslashreplace') as pipe: + try: + pipe.write(text) + except KeyboardInterrupt: + # We've hereby abandoned whatever text hasn't been written, + # but the pager is still in control of the terminal. + pass except OSError: pass # Ignore broken pipes caused by quitting the pager program. + while True: + try: + proc.wait() + break + except KeyboardInterrupt: + # Ignore ctl-c like the pager itself does. Otherwise the pager is + # left running and the terminal is in raw mode and unusable. + pass def tempfilepager(text, cmd): """Page through text by invoking a program on a temporary file.""" import tempfile filename = tempfile.mktemp() - with open(filename, 'w') as file: + with open(filename, 'w', errors='backslashreplace') as file: file.write(text) try: os.system(cmd + ' "' + filename + '"') finally: os.unlink(filename) +def _escape_stdout(text): + # Escape non-encodable characters to avoid encoding errors later + encoding = getattr(sys.stdout, 'encoding', None) or 'utf-8' + return text.encode(encoding, 'backslashreplace').decode(encoding) + def ttypager(text): """Page through text on a text terminal.""" - lines = plain(text).split('\n') + lines = plain(_escape_stdout(text)).split('\n') try: import tty fd = sys.stdin.fileno() old = tty.tcgetattr(fd) tty.setcbreak(fd) getchar = lambda: sys.stdin.read(1) - except (ImportError, AttributeError): + except (ImportError, AttributeError, io.UnsupportedOperation): tty = None getchar = lambda: sys.stdin.readline()[:-1][:1] try: - r = inc = os.environ.get('LINES', 25) - 1 + try: + h = int(os.environ.get('LINES', 0)) + except ValueError: + h = 0 + if h <= 1: + h = 25 + r = inc = h - 1 sys.stdout.write('\n'.join(lines[:inc]) + '\n') while lines[r:]: sys.stdout.write('-- more --') @@ -1473,7 +1542,7 @@ def ttypager(text): def plainpager(text): """Simply print unformatted text. This is the ultimate fallback.""" - sys.stdout.write(plain(text)) + sys.stdout.write(plain(_escape_stdout(text))) def describe(thing): """Produce a short description of the given thing.""" @@ -1531,8 +1600,11 @@ def resolve(thing, forceload=0): """Given an object or a path to an object, get the object and its name.""" if isinstance(thing, str): object = locate(thing, forceload) - if not object: - raise ImportError('no Python documentation found for %r' % thing) + if object is None: + raise ImportError('''\ +No Python documentation found for %r. +Use help() to get the interactive help utility. +Use help(str) for help on the str class.''' % thing) return object, thing else: name = getattr(thing, '__name__', None) @@ -1579,9 +1651,8 @@ def writedoc(thing, forceload=0): try: object, name = resolve(thing, forceload) page = html.page(describe(object), html.document(object, name)) - file = open(name + '.html', 'w', encoding='utf-8') - file.write(page) - file.close() + with open(name + '.html', 'w', encoding='utf-8') as file: + file.write(page) print('wrote', name + '.html') except (ImportError, ErrorDuringImport) as value: print(value) @@ -1601,7 +1672,7 @@ class Helper: # in pydoc_data/topics.py. # # CAUTION: if you change one of these dictionaries, be sure to adapt the - # list of needed labels in Doc/tools/sphinxext/pyspecific.py and + # list of needed labels in Doc/tools/pyspecific.py and # regenerate the pydoc_data/topics.py file by running # make pydoc-topics # in Doc/ and copying the output file into the Lib/ directory. @@ -1701,7 +1772,6 @@ class Helper: 'TRACEBACKS': 'TYPES', 'NONE': ('bltin-null-object', ''), 'ELLIPSIS': ('bltin-ellipsis-object', 'SLICINGS'), - 'FILES': ('bltin-file-objects', ''), 'SPECIALATTRIBUTES': ('specialattrs', ''), 'CLASSES': ('types', 'class SPECIALMETHODS PRIVATENAMES'), 'MODULES': ('typesmodules', 'import'), @@ -1777,7 +1847,8 @@ def __repr__(self): if inspect.stack()[1][3] == '?': self() return '' - return '' + return '<%s.%s instance>' % (self.__class__.__module__, + self.__class__.__qualname__) _GoInteractive = object() def __call__(self, request=_GoInteractive): @@ -1803,7 +1874,10 @@ def interact(self): break request = replace(request, '"', '', "'", '').strip() if request.lower() in ('q', 'quit'): break - self.help(request) + if request == 'help': + self.intro() + else: + self.help(request) def getline(self, prompt): """Read one line, using input() when appropriate.""" @@ -1817,8 +1891,7 @@ def getline(self, prompt): def help(self, request): if type(request) is type(''): request = request.strip() - if request == 'help': self.intro() - elif request == 'keywords': self.listkeywords() + if request == 'keywords': self.listkeywords() elif request == 'symbols': self.listsymbols() elif request == 'topics': self.listtopics() elif request == 'modules': self.listmodules() @@ -1831,13 +1904,14 @@ def help(self, request): elif request in self.keywords: self.showtopic(request) elif request in self.topics: self.showtopic(request) elif request: doc(request, 'Help on %s:', output=self._output) + else: doc(str, 'Help on %s:', output=self._output) elif isinstance(request, Helper): self() else: doc(request, 'Help on %s:', output=self._output) self.output.write('\n') def intro(self): self.output.write(''' -Welcome to Python %s! This is the interactive help utility. +Welcome to Python %s's help utility! If this is your first time using Python, you should definitely check out the tutorial on the Internet at http://docs.python.org/%s/tutorial/. @@ -2008,10 +2082,11 @@ def run(self, callback, key=None, completer=None, onerror=None): callback(None, modname, '') else: try: - loader = importer.find_module(modname) + spec = pkgutil._get_spec(importer, modname) except SyntaxError: # raised by tests for bad coding cookies or BOM continue + loader = spec.loader if hasattr(loader, 'get_source'): try: source = loader.get_source(modname) @@ -2026,12 +2101,12 @@ def run(self, callback, key=None, completer=None, onerror=None): path = None else: try: - module = loader.load_module(modname) + module = importlib._bootstrap._load(spec) except ImportError: if onerror: onerror(modname) continue - desc = (module.__doc__ or '').splitlines()[0] + desc = module.__doc__.splitlines()[0] if module.__doc__ else '' path = getattr(module,'__file__',None) name = modname + ' - ' + desc if name.lower().find(key) >= 0: @@ -2140,8 +2215,8 @@ def log_message(self, *args): class DocServer(http.server.HTTPServer): def __init__(self, port, callback): - self.host = (sys.platform == 'mac') and '127.0.0.1' or 'localhost' - self.address = ('', port) + self.host = 'localhost' + self.address = (self.host, port) self.callback = callback self.base.__init__(self, self.address, self.handler) self.quit = False @@ -2313,7 +2388,7 @@ def bltinlink(name): def html_getfile(path): """Get and display a source file listing safely.""" - path = path.replace('%20', ' ') + path = urllib.parse.unquote(path) with tokenize.open(path) as fp: lines = html.escape(fp.read()) body = '
%s
' % lines diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 4dfa3238fe99..38857d24b375 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,79 +1,79 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Sun Nov 24 06:50:34 2013 -topics = {'assert': '\nThe ``assert`` statement\n************************\n\nAssert statements are a convenient way to insert debugging assertions\ninto a program:\n\n assert_stmt ::= "assert" expression ["," expression]\n\nThe simple form, ``assert expression``, is equivalent to\n\n if __debug__:\n if not expression: raise AssertionError\n\nThe extended form, ``assert expression1, expression2``, is equivalent\nto\n\n if __debug__:\n if not expression1: raise AssertionError(expression2)\n\nThese equivalences assume that ``__debug__`` and ``AssertionError``\nrefer to the built-in variables with those names. In the current\nimplementation, the built-in variable ``__debug__`` is ``True`` under\nnormal circumstances, ``False`` when optimization is requested\n(command line option -O). The current code generator emits no code\nfor an assert statement when optimization is requested at compile\ntime. Note that it is unnecessary to include the source code for the\nexpression that failed in the error message; it will be displayed as\npart of the stack trace.\n\nAssignments to ``__debug__`` are illegal. The value for the built-in\nvariable is determined when the interpreter starts.\n', - 'assignment': '\nAssignment statements\n*********************\n\nAssignment statements are used to (re)bind names to values and to\nmodify attributes or items of mutable objects:\n\n assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression)\n target_list ::= target ("," target)* [","]\n target ::= identifier\n | "(" target_list ")"\n | "[" target_list "]"\n | attributeref\n | subscription\n | slicing\n | "*" target\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn assignment statement evaluates the expression list (remember that\nthis can be a single expression or a comma-separated list, the latter\nyielding a tuple) and assigns the single resulting object to each of\nthe target lists, from left to right.\n\nAssignment is defined recursively depending on the form of the target\n(list). When a target is part of a mutable object (an attribute\nreference, subscription or slicing), the mutable object must\nultimately perform the assignment and decide about its validity, and\nmay raise an exception if the assignment is unacceptable. The rules\nobserved by various types and the exceptions raised are given with the\ndefinition of the object types (see section *The standard type\nhierarchy*).\n\nAssignment of an object to a target list, optionally enclosed in\nparentheses or square brackets, is recursively defined as follows.\n\n* If the target list is a single target: The object is assigned to\n that target.\n\n* If the target list is a comma-separated list of targets: The object\n must be an iterable with the same number of items as there are\n targets in the target list, and the items are assigned, from left to\n right, to the corresponding targets.\n\n * If the target list contains one target prefixed with an asterisk,\n called a "starred" target: The object must be a sequence with at\n least as many items as there are targets in the target list, minus\n one. The first items of the sequence are assigned, from left to\n right, to the targets before the starred target. The final items\n of the sequence are assigned to the targets after the starred\n target. A list of the remaining items in the sequence is then\n assigned to the starred target (the list can be empty).\n\n * Else: The object must be a sequence with the same number of items\n as there are targets in the target list, and the items are\n assigned, from left to right, to the corresponding targets.\n\nAssignment of an object to a single target is recursively defined as\nfollows.\n\n* If the target is an identifier (name):\n\n * If the name does not occur in a ``global`` or ``nonlocal``\n statement in the current code block: the name is bound to the\n object in the current local namespace.\n\n * Otherwise: the name is bound to the object in the global namespace\n or the outer namespace determined by ``nonlocal``, respectively.\n\n The name is rebound if it was already bound. This may cause the\n reference count for the object previously bound to the name to reach\n zero, causing the object to be deallocated and its destructor (if it\n has one) to be called.\n\n* If the target is a target list enclosed in parentheses or in square\n brackets: The object must be an iterable with the same number of\n items as there are targets in the target list, and its items are\n assigned, from left to right, to the corresponding targets.\n\n* If the target is an attribute reference: The primary expression in\n the reference is evaluated. It should yield an object with\n assignable attributes; if this is not the case, ``TypeError`` is\n raised. That object is then asked to assign the assigned object to\n the given attribute; if it cannot perform the assignment, it raises\n an exception (usually but not necessarily ``AttributeError``).\n\n Note: If the object is a class instance and the attribute reference\n occurs on both sides of the assignment operator, the RHS expression,\n ``a.x`` can access either an instance attribute or (if no instance\n attribute exists) a class attribute. The LHS target ``a.x`` is\n always set as an instance attribute, creating it if necessary.\n Thus, the two occurrences of ``a.x`` do not necessarily refer to the\n same attribute: if the RHS expression refers to a class attribute,\n the LHS creates a new instance attribute as the target of the\n assignment:\n\n class Cls:\n x = 3 # class variable\n inst = Cls()\n inst.x = inst.x + 1 # writes inst.x as 4 leaving Cls.x as 3\n\n This description does not necessarily apply to descriptor\n attributes, such as properties created with ``property()``.\n\n* If the target is a subscription: The primary expression in the\n reference is evaluated. It should yield either a mutable sequence\n object (such as a list) or a mapping object (such as a dictionary).\n Next, the subscript expression is evaluated.\n\n If the primary is a mutable sequence object (such as a list), the\n subscript must yield an integer. If it is negative, the sequence\'s\n length is added to it. The resulting value must be a nonnegative\n integer less than the sequence\'s length, and the sequence is asked\n to assign the assigned object to its item with that index. If the\n index is out of range, ``IndexError`` is raised (assignment to a\n subscripted sequence cannot add new items to a list).\n\n If the primary is a mapping object (such as a dictionary), the\n subscript must have a type compatible with the mapping\'s key type,\n and the mapping is then asked to create a key/datum pair which maps\n the subscript to the assigned object. This can either replace an\n existing key/value pair with the same key value, or insert a new\n key/value pair (if no key with the same value existed).\n\n For user-defined objects, the ``__setitem__()`` method is called\n with appropriate arguments.\n\n* If the target is a slicing: The primary expression in the reference\n is evaluated. It should yield a mutable sequence object (such as a\n list). The assigned object should be a sequence object of the same\n type. Next, the lower and upper bound expressions are evaluated,\n insofar they are present; defaults are zero and the sequence\'s\n length. The bounds should evaluate to integers. If either bound is\n negative, the sequence\'s length is added to it. The resulting\n bounds are clipped to lie between zero and the sequence\'s length,\n inclusive. Finally, the sequence object is asked to replace the\n slice with the items of the assigned sequence. The length of the\n slice may be different from the length of the assigned sequence,\n thus changing the length of the target sequence, if the object\n allows it.\n\n**CPython implementation detail:** In the current implementation, the\nsyntax for targets is taken to be the same as for expressions, and\ninvalid syntax is rejected during the code generation phase, causing\nless detailed error messages.\n\nWARNING: Although the definition of assignment implies that overlaps\nbetween the left-hand side and the right-hand side are \'safe\' (for\nexample ``a, b = b, a`` swaps two variables), overlaps *within* the\ncollection of assigned-to variables are not safe! For instance, the\nfollowing program prints ``[0, 2]``:\n\n x = [0, 1]\n i = 0\n i, x[i] = 1, 2\n print(x)\n\nSee also:\n\n **PEP 3132** - Extended Iterable Unpacking\n The specification for the ``*target`` feature.\n\n\nAugmented assignment statements\n===============================\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like ``x += 1`` can be rewritten as\n``x = x + 1`` to achieve a similar, but not exactly equal effect. In\nthe augmented version, ``x`` is only evaluated once. Also, when\npossible, the actual operation is performed *in-place*, meaning that\nrather than creating a new object and assigning that to the target,\nthe old object is modified instead.\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n', - 'atom-identifiers': '\nIdentifiers (Names)\n*******************\n\nAn identifier occurring as an atom is a name. See section\n*Identifiers and keywords* for lexical definition and section *Naming\nand binding* for documentation of naming and binding.\n\nWhen the name is bound to an object, evaluation of the atom yields\nthat object. When a name is not bound, an attempt to evaluate it\nraises a ``NameError`` exception.\n\n**Private name mangling:** When an identifier that textually occurs in\na class definition begins with two or more underscore characters and\ndoes not end in two or more underscores, it is considered a *private\nname* of that class. Private names are transformed to a longer form\nbefore code is generated for them. The transformation inserts the\nclass name, with leading underscores removed and a single underscore\ninserted, in front of the name. For example, the identifier\n``__spam`` occurring in a class named ``Ham`` will be transformed to\n``_Ham__spam``. This transformation is independent of the syntactical\ncontext in which the identifier is used. If the transformed name is\nextremely long (longer than 255 characters), implementation defined\ntruncation may happen. If the class name consists only of underscores,\nno transformation is done.\n', - 'atom-literals': "\nLiterals\n********\n\nPython supports string and bytes literals and various numeric\nliterals:\n\n literal ::= stringliteral | bytesliteral\n | integer | floatnumber | imagnumber\n\nEvaluation of a literal yields an object of the given type (string,\nbytes, integer, floating point number, complex number) with the given\nvalue. The value may be approximated in the case of floating point\nand imaginary (complex) literals. See section *Literals* for details.\n\nAll literals correspond to immutable data types, and hence the\nobject's identity is less important than its value. Multiple\nevaluations of literals with the same value (either the same\noccurrence in the program text or a different occurrence) may obtain\nthe same object or a different object with the same value.\n", - 'attribute-access': '\nCustomizing attribute access\n****************************\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of ``x.name``)\nfor class instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for ``self``). ``name`` is the attribute name.\n This method should return the (computed) attribute value or raise\n an ``AttributeError`` exception.\n\n Note that if the attribute is found through the normal mechanism,\n ``__getattr__()`` is not called. (This is an intentional asymmetry\n between ``__getattr__()`` and ``__setattr__()``.) This is done both\n for efficiency reasons and because otherwise ``__getattr__()``\n would have no way to access other attributes of the instance. Note\n that at least for instance variables, you can fake total control by\n not inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n ``__getattribute__()`` method below for a way to actually get total\n control over attribute access.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines\n ``__getattr__()``, the latter will not be called unless\n ``__getattribute__()`` either calls it explicitly or raises an\n ``AttributeError``. This method should return the (computed)\n attribute value or raise an ``AttributeError`` exception. In order\n to avoid infinite recursion in this method, its implementation\n should always call the base class method with the same name to\n access any attributes it needs, for example,\n ``object.__getattribute__(self, name)``.\n\n Note: This method may still be bypassed when looking up special methods\n as the result of implicit invocation via language syntax or\n built-in functions. See *Special method lookup*.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If ``__setattr__()`` wants to assign to an instance attribute, it\n should call the base class method with the same name, for example,\n ``object.__setattr__(self, name, value)``.\n\nobject.__delattr__(self, name)\n\n Like ``__setattr__()`` but for attribute deletion instead of\n assignment. This should only be implemented if ``del obj.name`` is\n meaningful for the object.\n\nobject.__dir__(self)\n\n Called when ``dir()`` is called on the object. A sequence must be\n returned. ``dir()`` converts the returned sequence to a list and\n sorts it.\n\n\nImplementing Descriptors\n========================\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in an\n*owner* class (the descriptor must be in either the owner\'s class\ndictionary or in the class dictionary for one of its parents). In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' ``__dict__``.\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or ``None`` when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an\n ``AttributeError`` exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\n\nInvoking Descriptors\n====================\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: ``__get__()``, ``__set__()``, and\n``__delete__()``. If any of those methods are defined for an object,\nit is said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, ``a.x`` has a\nlookup chain starting with ``a.__dict__[\'x\']``, then\n``type(a).__dict__[\'x\']``, and continuing through the base classes of\n``type(a)`` excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called.\n\nThe starting point for descriptor invocation is a binding, ``a.x``.\nHow the arguments are assembled depends on ``a``:\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: ``x.__get__(a)``.\n\nInstance Binding\n If binding to an object instance, ``a.x`` is transformed into the\n call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a class, ``A.x`` is transformed into the call:\n ``A.__dict__[\'x\'].__get__(None, A)``.\n\nSuper Binding\n If ``a`` is an instance of ``super``, then the binding ``super(B,\n obj).m()`` searches ``obj.__class__.__mro__`` for the base class\n ``A`` immediately preceding ``B`` and then invokes the descriptor\n with the call: ``A.__dict__[\'m\'].__get__(obj, obj.__class__)``.\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of ``__get__()``, ``__set__()`` and ``__delete__()``.\nIf it does not define ``__get__()``, then accessing the attribute will\nreturn the descriptor object itself unless there is a value in the\nobject\'s instance dictionary. If the descriptor defines ``__set__()``\nand/or ``__delete__()``, it is a data descriptor; if it defines\nneither, it is a non-data descriptor. Normally, data descriptors\ndefine both ``__get__()`` and ``__set__()``, while non-data\ndescriptors have just the ``__get__()`` method. Data descriptors with\n``__set__()`` and ``__get__()`` defined always override a redefinition\nin an instance dictionary. In contrast, non-data descriptors can be\noverridden by instances.\n\nPython methods (including ``staticmethod()`` and ``classmethod()``)\nare implemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe ``property()`` function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n=========\n\nBy default, instances of classes have a dictionary for attribute\nstorage. This wastes space for objects having very few instance\nvariables. The space consumption can become acute when creating large\nnumbers of instances.\n\nThe default can be overridden by defining *__slots__* in a class\ndefinition. The *__slots__* declaration takes a sequence of instance\nvariables and reserves just enough space in each instance to hold a\nvalue for each variable. Space is saved because *__dict__* is not\ncreated for each instance.\n\nobject.__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. If defined in a\n class, *__slots__* reserves space for the declared variables and\n prevents the automatic creation of *__dict__* and *__weakref__* for\n each instance.\n\n\nNotes on using *__slots__*\n--------------------------\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises ``AttributeError``. If\n dynamic assignment of new variables is desired, then add\n ``\'__dict__\'`` to the sequence of strings in the *__slots__*\n declaration.\n\n* Without a *__weakref__* variable for each instance, classes defining\n *__slots__* do not support weak references to its instances. If weak\n reference support is needed, then add ``\'__weakref__\'`` to the\n sequence of strings in the *__slots__* declaration.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the instance\n variable defined by the base class slot is inaccessible (except by\n retrieving its descriptor directly from the base class). This\n renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as ``int``, ``str`` and\n ``tuple``.\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings may\n also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n', - 'attribute-references': '\nAttribute references\n********************\n\nAn attribute reference is a primary followed by a period and a name:\n\n attributeref ::= primary "." identifier\n\nThe primary must evaluate to an object of a type that supports\nattribute references, which most objects do. This object is then\nasked to produce the attribute whose name is the identifier (which can\nbe customized by overriding the ``__getattr__()`` method). If this\nattribute is not available, the exception ``AttributeError`` is\nraised. Otherwise, the type and value of the object produced is\ndetermined by the object. Multiple evaluations of the same attribute\nreference may yield different objects.\n', - 'augassign': '\nAugmented assignment statements\n*******************************\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like ``x += 1`` can be rewritten as\n``x = x + 1`` to achieve a similar, but not exactly equal effect. In\nthe augmented version, ``x`` is only evaluated once. Also, when\npossible, the actual operation is performed *in-place*, meaning that\nrather than creating a new object and assigning that to the target,\nthe old object is modified instead.\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n', - 'binary': '\nBinary arithmetic operations\n****************************\n\nThe binary arithmetic operations have the conventional priority\nlevels. Note that some of these operations also apply to certain non-\nnumeric types. Apart from the power operator, there are only two\nlevels, one for multiplicative operators and one for additive\noperators:\n\n m_expr ::= u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr\n | m_expr "%" u_expr\n a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr\n\nThe ``*`` (multiplication) operator yields the product of its\narguments. The arguments must either both be numbers, or one argument\nmust be an integer and the other must be a sequence. In the former\ncase, the numbers are converted to a common type and then multiplied\ntogether. In the latter case, sequence repetition is performed; a\nnegative repetition factor yields an empty sequence.\n\nThe ``/`` (division) and ``//`` (floor division) operators yield the\nquotient of their arguments. The numeric arguments are first\nconverted to a common type. Division of integers yields a float, while\nfloor division of integers results in an integer; the result is that\nof mathematical division with the \'floor\' function applied to the\nresult. Division by zero raises the ``ZeroDivisionError`` exception.\n\nThe ``%`` (modulo) operator yields the remainder from the division of\nthe first argument by the second. The numeric arguments are first\nconverted to a common type. A zero right argument raises the\n``ZeroDivisionError`` exception. The arguments may be floating point\nnumbers, e.g., ``3.14%0.7`` equals ``0.34`` (since ``3.14`` equals\n``4*0.7 + 0.34``.) The modulo operator always yields a result with\nthe same sign as its second operand (or zero); the absolute value of\nthe result is strictly smaller than the absolute value of the second\noperand [1].\n\nThe floor division and modulo operators are connected by the following\nidentity: ``x == (x//y)*y + (x%y)``. Floor division and modulo are\nalso connected with the built-in function ``divmod()``: ``divmod(x, y)\n== (x//y, x%y)``. [2].\n\nIn addition to performing the modulo operation on numbers, the ``%``\noperator is also overloaded by string objects to perform old-style\nstring formatting (also known as interpolation). The syntax for\nstring formatting is described in the Python Library Reference,\nsection *printf-style String Formatting*.\n\nThe floor division operator, the modulo operator, and the ``divmod()``\nfunction are not defined for complex numbers. Instead, convert to a\nfloating point number using the ``abs()`` function if appropriate.\n\nThe ``+`` (addition) operator yields the sum of its arguments. The\narguments must either both be numbers or both sequences of the same\ntype. In the former case, the numbers are converted to a common type\nand then added together. In the latter case, the sequences are\nconcatenated.\n\nThe ``-`` (subtraction) operator yields the difference of its\narguments. The numeric arguments are first converted to a common\ntype.\n', - 'bitwise': '\nBinary bitwise operations\n*************************\n\nEach of the three bitwise operations has a different priority level:\n\n and_expr ::= shift_expr | and_expr "&" shift_expr\n xor_expr ::= and_expr | xor_expr "^" and_expr\n or_expr ::= xor_expr | or_expr "|" xor_expr\n\nThe ``&`` operator yields the bitwise AND of its arguments, which must\nbe integers.\n\nThe ``^`` operator yields the bitwise XOR (exclusive OR) of its\narguments, which must be integers.\n\nThe ``|`` operator yields the bitwise (inclusive) OR of its arguments,\nwhich must be integers.\n', - 'bltin-code-objects': '\nCode Objects\n************\n\nCode objects are used by the implementation to represent "pseudo-\ncompiled" executable Python code such as a function body. They differ\nfrom function objects because they don\'t contain a reference to their\nglobal execution environment. Code objects are returned by the built-\nin ``compile()`` function and can be extracted from function objects\nthrough their ``__code__`` attribute. See also the ``code`` module.\n\nA code object can be executed or evaluated by passing it (instead of a\nsource string) to the ``exec()`` or ``eval()`` built-in functions.\n\nSee *The standard type hierarchy* for more information.\n', - 'bltin-ellipsis-object': '\nThe Ellipsis Object\n*******************\n\nThis object is commonly used by slicing (see *Slicings*). It supports\nno special operations. There is exactly one ellipsis object, named\n``Ellipsis`` (a built-in name). ``type(Ellipsis)()`` produces the\n``Ellipsis`` singleton.\n\nIt is written as ``Ellipsis`` or ``...``.\n', - 'bltin-null-object': "\nThe Null Object\n***************\n\nThis object is returned by functions that don't explicitly return a\nvalue. It supports no special operations. There is exactly one null\nobject, named ``None`` (a built-in name). ``type(None)()`` produces\nthe same singleton.\n\nIt is written as ``None``.\n", - 'bltin-type-objects': "\nType Objects\n************\n\nType objects represent the various object types. An object's type is\naccessed by the built-in function ``type()``. There are no special\noperations on types. The standard module ``types`` defines names for\nall standard built-in types.\n\nTypes are written like this: ````.\n", - 'booleans': '\nBoolean operations\n******************\n\n or_test ::= and_test | or_test "or" and_test\n and_test ::= not_test | and_test "and" not_test\n not_test ::= comparison | "not" not_test\n\nIn the context of Boolean operations, and also when expressions are\nused by control flow statements, the following values are interpreted\nas false: ``False``, ``None``, numeric zero of all types, and empty\nstrings and containers (including strings, tuples, lists,\ndictionaries, sets and frozensets). All other values are interpreted\nas true. User-defined objects can customize their truth value by\nproviding a ``__bool__()`` method.\n\nThe operator ``not`` yields ``True`` if its argument is false,\n``False`` otherwise.\n\nThe expression ``x and y`` first evaluates *x*; if *x* is false, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\nThe expression ``x or y`` first evaluates *x*; if *x* is true, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\n(Note that neither ``and`` nor ``or`` restrict the value and type they\nreturn to ``False`` and ``True``, but rather return the last evaluated\nargument. This is sometimes useful, e.g., if ``s`` is a string that\nshould be replaced by a default value if it is empty, the expression\n``s or \'foo\'`` yields the desired value. Because ``not`` has to\ninvent a value anyway, it does not bother to return a value of the\nsame type as its argument, so e.g., ``not \'foo\'`` yields ``False``,\nnot ``\'\'``.)\n', - 'break': '\nThe ``break`` statement\n***********************\n\n break_stmt ::= "break"\n\n``break`` may only occur syntactically nested in a ``for`` or\n``while`` loop, but not nested in a function or class definition\nwithin that loop.\n\nIt terminates the nearest enclosing loop, skipping the optional\n``else`` clause if the loop has one.\n\nIf a ``for`` loop is terminated by ``break``, the loop control target\nkeeps its current value.\n\nWhen ``break`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nleaving the loop.\n', - 'callable-types': '\nEmulating callable objects\n**************************\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, ``x(arg1, arg2, ...)`` is a shorthand for\n ``x.__call__(arg1, arg2, ...)``.\n', - 'calls': '\nCalls\n*****\n\nA call calls a callable object (e.g., a *function*) with a possibly\nempty series of *arguments*:\n\n call ::= primary "(" [argument_list [","] | comprehension] ")"\n argument_list ::= positional_arguments ["," keyword_arguments]\n ["," "*" expression] ["," keyword_arguments]\n ["," "**" expression]\n | keyword_arguments ["," "*" expression]\n ["," keyword_arguments] ["," "**" expression]\n | "*" expression ["," keyword_arguments] ["," "**" expression]\n | "**" expression\n positional_arguments ::= expression ("," expression)*\n keyword_arguments ::= keyword_item ("," keyword_item)*\n keyword_item ::= identifier "=" expression\n\nA trailing comma may be present after the positional and keyword\narguments but does not affect the semantics.\n\nThe primary must evaluate to a callable object (user-defined\nfunctions, built-in functions, methods of built-in objects, class\nobjects, methods of class instances, and all objects having a\n``__call__()`` method are callable). All argument expressions are\nevaluated before the call is attempted. Please refer to section\n*Function definitions* for the syntax of formal *parameter* lists.\n\nIf keyword arguments are present, they are first converted to\npositional arguments, as follows. First, a list of unfilled slots is\ncreated for the formal parameters. If there are N positional\narguments, they are placed in the first N slots. Next, for each\nkeyword argument, the identifier is used to determine the\ncorresponding slot (if the identifier is the same as the first formal\nparameter name, the first slot is used, and so on). If the slot is\nalready filled, a ``TypeError`` exception is raised. Otherwise, the\nvalue of the argument is placed in the slot, filling it (even if the\nexpression is ``None``, it fills the slot). When all arguments have\nbeen processed, the slots that are still unfilled are filled with the\ncorresponding default value from the function definition. (Default\nvalues are calculated, once, when the function is defined; thus, a\nmutable object such as a list or dictionary used as default value will\nbe shared by all calls that don\'t specify an argument value for the\ncorresponding slot; this should usually be avoided.) If there are any\nunfilled slots for which no default value is specified, a\n``TypeError`` exception is raised. Otherwise, the list of filled\nslots is used as the argument list for the call.\n\n**CPython implementation detail:** An implementation may provide\nbuilt-in functions whose positional parameters do not have names, even\nif they are \'named\' for the purpose of documentation, and which\ntherefore cannot be supplied by keyword. In CPython, this is the case\nfor functions implemented in C that use ``PyArg_ParseTuple()`` to\nparse their arguments.\n\nIf there are more positional arguments than there are formal parameter\nslots, a ``TypeError`` exception is raised, unless a formal parameter\nusing the syntax ``*identifier`` is present; in this case, that formal\nparameter receives a tuple containing the excess positional arguments\n(or an empty tuple if there were no excess positional arguments).\n\nIf any keyword argument does not correspond to a formal parameter\nname, a ``TypeError`` exception is raised, unless a formal parameter\nusing the syntax ``**identifier`` is present; in this case, that\nformal parameter receives a dictionary containing the excess keyword\narguments (using the keywords as keys and the argument values as\ncorresponding values), or a (new) empty dictionary if there were no\nexcess keyword arguments.\n\nIf the syntax ``*expression`` appears in the function call,\n``expression`` must evaluate to an iterable. Elements from this\niterable are treated as if they were additional positional arguments;\nif there are positional arguments *x1*, ..., *xN*, and ``expression``\nevaluates to a sequence *y1*, ..., *yM*, this is equivalent to a call\nwith M+N positional arguments *x1*, ..., *xN*, *y1*, ..., *yM*.\n\nA consequence of this is that although the ``*expression`` syntax may\nappear *after* some keyword arguments, it is processed *before* the\nkeyword arguments (and the ``**expression`` argument, if any -- see\nbelow). So:\n\n >>> def f(a, b):\n ... print(a, b)\n ...\n >>> f(b=1, *(2,))\n 2 1\n >>> f(a=1, *(2,))\n Traceback (most recent call last):\n File "", line 1, in ?\n TypeError: f() got multiple values for keyword argument \'a\'\n >>> f(1, *(2,))\n 1 2\n\nIt is unusual for both keyword arguments and the ``*expression``\nsyntax to be used in the same call, so in practice this confusion does\nnot arise.\n\nIf the syntax ``**expression`` appears in the function call,\n``expression`` must evaluate to a mapping, the contents of which are\ntreated as additional keyword arguments. In the case of a keyword\nappearing in both ``expression`` and as an explicit keyword argument,\na ``TypeError`` exception is raised.\n\nFormal parameters using the syntax ``*identifier`` or ``**identifier``\ncannot be used as positional argument slots or as keyword argument\nnames.\n\nA call always returns some value, possibly ``None``, unless it raises\nan exception. How this value is computed depends on the type of the\ncallable object.\n\nIf it is---\n\na user-defined function:\n The code block for the function is executed, passing it the\n argument list. The first thing the code block will do is bind the\n formal parameters to the arguments; this is described in section\n *Function definitions*. When the code block executes a ``return``\n statement, this specifies the return value of the function call.\n\na built-in function or method:\n The result is up to the interpreter; see *Built-in Functions* for\n the descriptions of built-in functions and methods.\n\na class object:\n A new instance of that class is returned.\n\na class instance method:\n The corresponding user-defined function is called, with an argument\n list that is one longer than the argument list of the call: the\n instance becomes the first argument.\n\na class instance:\n The class must define a ``__call__()`` method; the effect is then\n the same as if that method was called.\n', - 'class': '\nClass definitions\n*****************\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= [decorators] "class" classname [inheritance] ":" suite\n inheritance ::= "(" [parameter_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. The inheritance list\nusually gives a list of base classes (see *Customizing class creation*\nfor more advanced uses), so each item in the list should evaluate to a\nclass object which allows subclassing. Classes without an inheritance\nlist inherit, by default, from the base class ``object``; hence,\n\n class Foo:\n pass\n\nis equivalent to\n\n class Foo(object):\n pass\n\nThe class\'s suite is then executed in a new execution frame (see\n*Naming and binding*), using a newly created local namespace and the\noriginal global namespace. (Usually, the suite contains mostly\nfunction definitions.) When the class\'s suite finishes execution, its\nexecution frame is discarded but its local namespace is saved. [4] A\nclass object is then created using the inheritance list for the base\nclasses and the saved local namespace for the attribute dictionary.\nThe class name is bound to this class object in the original local\nnamespace.\n\nClass creation can be customized heavily using *metaclasses*.\n\nClasses can also be decorated: just like when decorating functions,\n\n @f1(arg)\n @f2\n class Foo: pass\n\nis equivalent to\n\n class Foo: pass\n Foo = f1(arg)(f2(Foo))\n\nThe evaluation rules for the decorator expressions are the same as for\nfunction decorators. The result must be a class object, which is then\nbound to the class name.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass attributes; they are shared by instances. Instance attributes\ncan be set in a method with ``self.name = value``. Both class and\ninstance attributes are accessible through the notation\n"``self.name``", and an instance attribute hides a class attribute\nwith the same name when accessed in this way. Class attributes can be\nused as defaults for instance attributes, but using mutable values\nthere can lead to unexpected results. *Descriptors* can be used to\ncreate instance variables with different implementation details.\n\nSee also:\n\n **PEP 3115** - Metaclasses in Python 3 **PEP 3129** - Class\n Decorators\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack unless there\n is a ``finally`` clause which happens to raise another exception.\n That new exception causes the old one to be lost.\n\n[2] Currently, control "flows off the end" except in the case of an\n exception or the execution of a ``return``, ``continue``, or\n ``break`` statement.\n\n[3] A string literal appearing as the first statement in the function\n body is transformed into the function\'s ``__doc__`` attribute and\n therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n body is transformed into the namespace\'s ``__doc__`` item and\n therefore the class\'s *docstring*.\n', - 'comparisons': '\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like ``a < b < c`` have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: ``True`` or ``False``.\n\nComparisons can be chained arbitrarily, e.g., ``x < y <= z`` is\nequivalent to ``x < y and y <= z``, except that ``y`` is evaluated\nonly once (but in both cases ``z`` is not evaluated at all when ``x <\ny`` is found to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then ``a op1 b op2 c ... y\nopN z`` is equivalent to ``a op1 b and b op2 c and ... y opN z``,\nexcept that each expression is evaluated at most once.\n\nNote that ``a op1 b op2 c`` doesn\'t imply any kind of comparison\nbetween *a* and *c*, so that, e.g., ``x < y > z`` is perfectly legal\n(though perhaps not pretty).\n\nThe operators ``<``, ``>``, ``==``, ``>=``, ``<=``, and ``!=`` compare\nthe values of two objects. The objects need not have the same type.\nIf both are numbers, they are converted to a common type. Otherwise,\nthe ``==`` and ``!=`` operators *always* consider objects of different\ntypes to be unequal, while the ``<``, ``>``, ``>=`` and ``<=``\noperators raise a ``TypeError`` when comparing objects of different\ntypes that do not implement these operators for the given pair of\ntypes. You can control comparison behavior of objects of non-built-in\ntypes by defining rich comparison methods like ``__gt__()``, described\nin section *Basic customization*.\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* The values ``float(\'NaN\')`` and ``Decimal(\'NaN\')`` are special. The\n are identical to themselves, ``x is x`` but are not equal to\n themselves, ``x != x``. Additionally, comparing any value to a\n not-a-number value will return ``False``. For example, both ``3 <\n float(\'NaN\')`` and ``float(\'NaN\') < 3`` will return ``False``.\n\n* Bytes objects are compared lexicographically using the numeric\n values of their elements.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n [3] String and bytes object can\'t be compared!\n\n* Tuples and lists are compared lexicographically using comparison of\n corresponding elements. This means that to compare equal, each\n element must compare equal and the two sequences must be of the same\n type and have the same length.\n\n If not equal, the sequences are ordered the same as their first\n differing elements. For example, ``[1,2,x] <= [1,2,y]`` has the\n same value as ``x <= y``. If the corresponding element does not\n exist, the shorter sequence is ordered first (for example, ``[1,2] <\n [1,2,3]``).\n\n* Mappings (dictionaries) compare equal if and only if they have the\n same ``(key, value)`` pairs. Order comparisons ``(\'<\', \'<=\', \'>=\',\n \'>\')`` raise ``TypeError``.\n\n* Sets and frozensets define comparison operators to mean subset and\n superset tests. Those relations do not define total orderings (the\n two sets ``{1,2}`` and {2,3} are not equal, nor subsets of one\n another, nor supersets of one another). Accordingly, sets are not\n appropriate arguments for functions which depend on total ordering.\n For example, ``min()``, ``max()``, and ``sorted()`` produce\n undefined results given a list of sets as inputs.\n\n* Most other objects of built-in types compare unequal unless they are\n the same object; the choice whether one object is considered smaller\n or larger than another one is made arbitrarily but consistently\n within one execution of a program.\n\nComparison of objects of the differing types depends on whether either\nof the types provide explicit support for the comparison. Most\nnumeric types can be compared with one another. When cross-type\ncomparison is not supported, the comparison method returns\n``NotImplemented``.\n\nThe operators ``in`` and ``not in`` test for membership. ``x in s``\nevaluates to true if *x* is a member of *s*, and false otherwise. ``x\nnot in s`` returns the negation of ``x in s``. All built-in sequences\nand set types support this as well as dictionary, for which ``in``\ntests whether a the dictionary has a given key. For container types\nsuch as list, tuple, set, frozenset, dict, or collections.deque, the\nexpression ``x in y`` is equivalent to ``any(x is e or x == e for e in\ny)``.\n\nFor the string and bytes types, ``x in y`` is true if and only if *x*\nis a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nEmpty strings are always considered to be a substring of any other\nstring, so ``"" in "abc"`` will return ``True``.\n\nFor user-defined classes which define the ``__contains__()`` method,\n``x in y`` is true if and only if ``y.__contains__(x)`` is true.\n\nFor user-defined classes which do not define ``__contains__()`` but do\ndefine ``__iter__()``, ``x in y`` is true if some value ``z`` with ``x\n== z`` is produced while iterating over ``y``. If an exception is\nraised during the iteration, it is as if ``in`` raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n``__getitem__()``, ``x in y`` is true if and only if there is a non-\nnegative integer index *i* such that ``x == y[i]``, and all lower\ninteger indices do not raise ``IndexError`` exception. (If any other\nexception is raised, it is as if ``in`` raised that exception).\n\nThe operator ``not in`` is defined to have the inverse true value of\n``in``.\n\nThe operators ``is`` and ``is not`` test for object identity: ``x is\ny`` is true if and only if *x* and *y* are the same object. ``x is\nnot y`` yields the inverse truth value. [4]\n', - 'compound': '\nCompound statements\n*******************\n\nCompound statements contain (groups of) other statements; they affect\nor control the execution of those other statements in some way. In\ngeneral, compound statements span multiple lines, although in simple\nincarnations a whole compound statement may be contained in one line.\n\nThe ``if``, ``while`` and ``for`` statements implement traditional\ncontrol flow constructs. ``try`` specifies exception handlers and/or\ncleanup code for a group of statements, while the ``with`` statement\nallows the execution of initialization and finalization code around a\nblock of code. Function and class definitions are also syntactically\ncompound statements.\n\nCompound statements consist of one or more \'clauses.\' A clause\nconsists of a header and a \'suite.\' The clause headers of a\nparticular compound statement are all at the same indentation level.\nEach clause header begins with a uniquely identifying keyword and ends\nwith a colon. A suite is a group of statements controlled by a\nclause. A suite can be one or more semicolon-separated simple\nstatements on the same line as the header, following the header\'s\ncolon, or it can be one or more indented statements on subsequent\nlines. Only the latter form of suite can contain nested compound\nstatements; the following is illegal, mostly because it wouldn\'t be\nclear to which ``if`` clause a following ``else`` clause would belong:\n\n if test1: if test2: print(x)\n\nAlso note that the semicolon binds tighter than the colon in this\ncontext, so that in the following example, either all or none of the\n``print()`` calls are executed:\n\n if x < y < z: print(x); print(y); print(z)\n\nSummarizing:\n\n compound_stmt ::= if_stmt\n | while_stmt\n | for_stmt\n | try_stmt\n | with_stmt\n | funcdef\n | classdef\n suite ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT\n statement ::= stmt_list NEWLINE | compound_stmt\n stmt_list ::= simple_stmt (";" simple_stmt)* [";"]\n\nNote that statements always end in a ``NEWLINE`` possibly followed by\na ``DEDENT``. Also note that optional continuation clauses always\nbegin with a keyword that cannot start a statement, thus there are no\nambiguities (the \'dangling ``else``\' problem is solved in Python by\nrequiring nested ``if`` statements to be indented).\n\nThe formatting of the grammar rules in the following sections places\neach clause on a separate line for clarity.\n\n\nThe ``if`` statement\n====================\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n\n\nThe ``while`` statement\n=======================\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n\n\nThe ``for`` statement\n=====================\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n``expression_list``. The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments (see *Assignment statements*), and then the suite is\nexecuted. When the items are exhausted (which is immediately when the\nsequence is empty or an iterator raises a ``StopIteration``\nexception), the suite in the ``else`` clause, if present, is executed,\nand the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nNames in the target list are not deleted when the loop is finished,\nbut if the sequence is empty, it will not have been assigned to at all\nby the loop. Hint: the built-in function ``range()`` returns an\niterator of integers suitable to emulate the effect of Pascal\'s ``for\ni := a to b do``; e.g., ``list(range(3))`` returns the list ``[0, 1,\n2]``.\n\nNote: There is a subtlety when the sequence is being modified by the loop\n (this can only occur for mutable sequences, i.e. lists). An\n internal counter is used to keep track of which item is used next,\n and this is incremented on each iteration. When this counter has\n reached the length of the sequence the loop terminates. This means\n that if the suite deletes the current (or a previous) item from the\n sequence, the next item will be skipped (since it gets the index of\n the current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n\n\nThe ``try`` statement\n=====================\n\nThe ``try`` statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression ["as" target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nThe ``except`` clause(s) specify one or more exception handlers. When\nno exception occurs in the ``try`` clause, no exception handler is\nexecuted. When an exception occurs in the ``try`` suite, a search for\nan exception handler is started. This search inspects the except\nclauses in turn until one is found that matches the exception. An\nexpression-less except clause, if present, must be last; it matches\nany exception. For an except clause with an expression, that\nexpression is evaluated, and the clause matches the exception if the\nresulting object is "compatible" with the exception. An object is\ncompatible with an exception if it is the class or a base class of the\nexception object or a tuple containing an item compatible with the\nexception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire ``try`` statement\nraised the exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified after the ``as`` keyword in that except clause,\nif present, and the except clause\'s suite is executed. All except\nclauses must have an executable block. When the end of this block is\nreached, execution continues normally after the entire try statement.\n(This means that if two nested handlers exist for the same exception,\nand the exception occurs in the try clause of the inner handler, the\nouter handler will not handle the exception.)\n\nWhen an exception has been assigned using ``as target``, it is cleared\nat the end of the except clause. This is as if\n\n except E as N:\n foo\n\nwas translated to\n\n except E as N:\n try:\n foo\n finally:\n del N\n\nThis means the exception must be assigned to a different name to be\nable to refer to it after the except clause. Exceptions are cleared\nbecause with the traceback attached to them, they form a reference\ncycle with the stack frame, keeping all locals in that frame alive\nuntil the next garbage collection occurs.\n\nBefore an except clause\'s suite is executed, details about the\nexception are stored in the ``sys`` module and can be access via\n``sys.exc_info()``. ``sys.exc_info()`` returns a 3-tuple consisting of\nthe exception class, the exception instance and a traceback object\n(see section *The standard type hierarchy*) identifying the point in\nthe program where the exception occurred. ``sys.exc_info()`` values\nare restored to their previous values (before the call) when returning\nfrom a function that handled an exception.\n\nThe optional ``else`` clause is executed if and when control flows off\nthe end of the ``try`` clause. [2] Exceptions in the ``else`` clause\nare not handled by the preceding ``except`` clauses.\n\nIf ``finally`` is present, it specifies a \'cleanup\' handler. The\n``try`` clause is executed, including any ``except`` and ``else``\nclauses. If an exception occurs in any of the clauses and is not\nhandled, the exception is temporarily saved. The ``finally`` clause is\nexecuted. If there is a saved exception it is re-raised at the end of\nthe ``finally`` clause. If the ``finally`` clause raises another\nexception, the saved exception is set as the context of the new\nexception. If the ``finally`` clause executes a ``return`` or\n``break`` statement, the saved exception is discarded:\n\n def f():\n try:\n 1/0\n finally:\n return 42\n\n >>> f()\n 42\n\nThe exception information is not available to the program during\nexecution of the ``finally`` clause.\n\nWhen a ``return``, ``break`` or ``continue`` statement is executed in\nthe ``try`` suite of a ``try``...``finally`` statement, the\n``finally`` clause is also executed \'on the way out.\' A ``continue``\nstatement is illegal in the ``finally`` clause. (The reason is a\nproblem with the current implementation --- this restriction may be\nlifted in the future).\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the ``raise`` statement to\ngenerate exceptions may be found in section *The raise statement*.\n\n\nThe ``with`` statement\n======================\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the ``with_item``)\n is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nChanged in version 3.1: Support for multiple context expressions.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n\nFunction definitions\n====================\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n funcdef ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [parameter_list [","]] ")"] NEWLINE\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" [parameter] ("," defparameter)* ["," "**" parameter]\n | "**" parameter\n | defparameter [","] )\n parameter ::= identifier [":" expression]\n defparameter ::= parameter ["=" expression]\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more *parameters* have the form *parameter* ``=``\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding *argument* may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters up until the "``*``" must also have a default value ---\nthis is a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated from left to right when the\nfunction definition is executed.** This means that the expression is\nevaluated once, when the function is defined, and that the same "pre-\ncomputed" value is used for each call. This is especially important\nto understand when a default parameter is a mutable object, such as a\nlist or a dictionary: if the function modifies the object (e.g. by\nappending an item to a list), the default value is in effect modified.\nThis is generally not what was intended. A way around this is to use\n``None`` as the default, and explicitly test for it in the body of the\nfunction, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple. If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after "``*``" or "``*identifier``" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "``: expression``"\nfollowing the parameter name. Any parameter may have an annotation\neven those of the form ``*identifier`` or ``**identifier``. Functions\nmay have "return" annotation of the form "``-> expression``" after the\nparameter list. These annotations can be any valid Python expression\nand are evaluated when the function definition is executed.\nAnnotations may be evaluated in a different order than they appear in\nthe source code. The presence of annotations does not change the\nsemantics of a function. The annotation values are available as\nvalues of a dictionary keyed by the parameters\' names in the\n``__annotations__`` attribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda\nexpressions, described in section *Lambdas*. Note that the lambda\nexpression is merely a shorthand for a simplified function definition;\na function defined in a "``def``" statement can be passed around or\nassigned to another name just like a function defined by a lambda\nexpression. The "``def``" form is actually more powerful since it\nallows the execution of multiple statements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects. A "``def``"\nstatement executed inside a function definition defines a local\nfunction that can be returned or passed around. Free variables used\nin the nested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n\nSee also:\n\n **PEP 3107** - Function Annotations\n The original specification for function annotations.\n\n\nClass definitions\n=================\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= [decorators] "class" classname [inheritance] ":" suite\n inheritance ::= "(" [parameter_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. The inheritance list\nusually gives a list of base classes (see *Customizing class creation*\nfor more advanced uses), so each item in the list should evaluate to a\nclass object which allows subclassing. Classes without an inheritance\nlist inherit, by default, from the base class ``object``; hence,\n\n class Foo:\n pass\n\nis equivalent to\n\n class Foo(object):\n pass\n\nThe class\'s suite is then executed in a new execution frame (see\n*Naming and binding*), using a newly created local namespace and the\noriginal global namespace. (Usually, the suite contains mostly\nfunction definitions.) When the class\'s suite finishes execution, its\nexecution frame is discarded but its local namespace is saved. [4] A\nclass object is then created using the inheritance list for the base\nclasses and the saved local namespace for the attribute dictionary.\nThe class name is bound to this class object in the original local\nnamespace.\n\nClass creation can be customized heavily using *metaclasses*.\n\nClasses can also be decorated: just like when decorating functions,\n\n @f1(arg)\n @f2\n class Foo: pass\n\nis equivalent to\n\n class Foo: pass\n Foo = f1(arg)(f2(Foo))\n\nThe evaluation rules for the decorator expressions are the same as for\nfunction decorators. The result must be a class object, which is then\nbound to the class name.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass attributes; they are shared by instances. Instance attributes\ncan be set in a method with ``self.name = value``. Both class and\ninstance attributes are accessible through the notation\n"``self.name``", and an instance attribute hides a class attribute\nwith the same name when accessed in this way. Class attributes can be\nused as defaults for instance attributes, but using mutable values\nthere can lead to unexpected results. *Descriptors* can be used to\ncreate instance variables with different implementation details.\n\nSee also:\n\n **PEP 3115** - Metaclasses in Python 3 **PEP 3129** - Class\n Decorators\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack unless there\n is a ``finally`` clause which happens to raise another exception.\n That new exception causes the old one to be lost.\n\n[2] Currently, control "flows off the end" except in the case of an\n exception or the execution of a ``return``, ``continue``, or\n ``break`` statement.\n\n[3] A string literal appearing as the first statement in the function\n body is transformed into the function\'s ``__doc__`` attribute and\n therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n body is transformed into the namespace\'s ``__doc__`` item and\n therefore the class\'s *docstring*.\n', - 'context-managers': '\nWith Statement Context Managers\n*******************************\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a ``with`` statement. The context\nmanager handles the entry into, and the exit from, the desired runtime\ncontext for the execution of the block of code. Context managers are\nnormally invoked using the ``with`` statement (described in section\n*The with statement*), but can also be used by directly invoking their\nmethods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The ``with``\n statement will bind this method\'s return value to the target(s)\n specified in the ``as`` clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be ``None``.\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that ``__exit__()`` methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n', - 'continue': '\nThe ``continue`` statement\n**************************\n\n continue_stmt ::= "continue"\n\n``continue`` may only occur syntactically nested in a ``for`` or\n``while`` loop, but not nested in a function or class definition or\n``finally`` clause within that loop. It continues with the next cycle\nof the nearest enclosing loop.\n\nWhen ``continue`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nstarting the next loop cycle.\n', - 'conversions': '\nArithmetic conversions\n**********************\n\nWhen a description of an arithmetic operator below uses the phrase\n"the numeric arguments are converted to a common type," this means\nthat the operator implementation for built-in types works that way:\n\n* If either argument is a complex number, the other is converted to\n complex;\n\n* otherwise, if either argument is a floating point number, the other\n is converted to floating point;\n\n* otherwise, both must be integers and no conversion is necessary.\n\nSome additional rules apply for certain operators (e.g., a string left\nargument to the \'%\' operator). Extensions must define their own\nconversion behavior.\n', - 'customization': '\nBasic customization\n*******************\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. ``__new__()`` is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of ``__new__()`` should be the new object instance (usually\n an instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s ``__new__()`` method using\n ``super(currentclass, cls).__new__(cls[, ...])`` with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If ``__new__()`` returns an instance of *cls*, then the new\n instance\'s ``__init__()`` method will be invoked like\n ``__init__(self[, ...])``, where *self* is the new instance and the\n remaining arguments are the same as were passed to ``__new__()``.\n\n If ``__new__()`` does not return an instance of *cls*, then the new\n instance\'s ``__init__()`` method will not be invoked.\n\n ``__new__()`` is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called when the instance is created. The arguments are those\n passed to the class constructor expression. If a base class has an\n ``__init__()`` method, the derived class\'s ``__init__()`` method,\n if any, must explicitly call it to ensure proper initialization of\n the base class part of the instance; for example:\n ``BaseClass.__init__(self, [args...])``. As a special constraint\n on constructors, no value may be returned; doing so will cause a\n ``TypeError`` to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a ``__del__()`` method,\n the derived class\'s ``__del__()`` method, if any, must explicitly\n call it to ensure proper deletion of the base class part of the\n instance. Note that it is possible (though not recommended!) for\n the ``__del__()`` method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n ``__del__()`` methods are called for objects that still exist when\n the interpreter exits.\n\n Note: ``del x`` doesn\'t directly call ``x.__del__()`` --- the former\n decrements the reference count for ``x`` by one, and the latter\n is only called when ``x``\'s reference count reaches zero. Some\n common situations that may prevent the reference count of an\n object from going to zero include: circular references between\n objects (e.g., a doubly-linked list or a tree data structure with\n parent and child pointers); a reference to the object on the\n stack frame of a function that caught an exception (the traceback\n stored in ``sys.exc_info()[2]`` keeps the stack frame alive); or\n a reference to the object on the stack frame that raised an\n unhandled exception in interactive mode (the traceback stored in\n ``sys.last_traceback`` keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the latter two situations can be resolved by storing ``None`` in\n ``sys.last_traceback``. Circular references which are garbage are\n detected and cleaned up when the cyclic garbage collector is\n enabled (it\'s on by default). Refer to the documentation for the\n ``gc`` module for more information about this topic.\n\n Warning: Due to the precarious circumstances under which ``__del__()``\n methods are invoked, exceptions that occur during their execution\n are ignored, and a warning is printed to ``sys.stderr`` instead.\n Also, when ``__del__()`` is invoked in response to a module being\n deleted (e.g., when execution of the program is done), other\n globals referenced by the ``__del__()`` method may already have\n been deleted or in the process of being torn down (e.g. the\n import machinery shutting down). For this reason, ``__del__()``\n methods should do the absolute minimum needed to maintain\n external invariants. Starting with version 1.5, Python\n guarantees that globals whose name begins with a single\n underscore are deleted from their module before other globals are\n deleted; if no other references to such globals exist, this may\n help in assuring that imported modules are still available at the\n time when the ``__del__()`` method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function to compute the\n "official" string representation of an object. If at all possible,\n this should look like a valid Python expression that could be used\n to recreate an object with the same value (given an appropriate\n environment). If this is not possible, a string of the form\n ``<...some useful description...>`` should be returned. The return\n value must be a string object. If a class defines ``__repr__()``\n but not ``__str__()``, then ``__repr__()`` is also used when an\n "informal" string representation of instances of that class is\n required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by ``str(object)`` and the built-in functions ``format()``\n and ``print()`` to compute the "informal" or nicely printable\n string representation of an object. The return value must be a\n *string* object.\n\n This method differs from ``object.__repr__()`` in that there is no\n expectation that ``__str__()`` return a valid Python expression: a\n more convenient or concise representation can be used.\n\n The default implementation defined by the built-in type ``object``\n calls ``object.__repr__()``.\n\nobject.__bytes__(self)\n\n Called by ``bytes()`` to compute a byte-string representation of an\n object. This should return a ``bytes`` object.\n\nobject.__format__(self, format_spec)\n\n Called by the ``format()`` built-in function (and by extension, the\n ``str.format()`` method of class ``str``) to produce a "formatted"\n string representation of an object. The ``format_spec`` argument is\n a string that contains a description of the formatting options\n desired. The interpretation of the ``format_spec`` argument is up\n to the type implementing ``__format__()``, however most classes\n will either delegate formatting to one of the built-in types, or\n use a similar formatting option syntax.\n\n See *Format Specification Mini-Language* for a description of the\n standard formatting syntax.\n\n The return value must be a string object.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n These are the so-called "rich comparison" methods. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` calls ``x.__gt__(y)``, and ``x>=y`` calls\n ``x.__ge__(y)``.\n\n A rich comparison method may return the singleton\n ``NotImplemented`` if it does not implement the operation for a\n given pair of arguments. By convention, ``False`` and ``True`` are\n returned for a successful comparison. However, these methods can\n return any value, so if the comparison operator is used in a\n Boolean context (e.g., in the condition of an ``if`` statement),\n Python will call ``bool()`` on the value to determine if the result\n is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of ``x==y`` does not imply that ``x!=y`` is false.\n Accordingly, when defining ``__eq__()``, one should also define\n ``__ne__()`` so that the operators will behave as expected. See\n the paragraph on ``__hash__()`` for some important notes on\n creating *hashable* objects which support custom comparison\n operations and are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, ``__lt__()`` and ``__gt__()`` are each\n other\'s reflection, ``__le__()`` and ``__ge__()`` are each other\'s\n reflection, and ``__eq__()`` and ``__ne__()`` are their own\n reflection.\n\n Arguments to rich comparison methods are never coerced.\n\n To automatically generate ordering operations from a single root\n operation, see ``functools.total_ordering()``.\n\nobject.__hash__(self)\n\n Called by built-in function ``hash()`` and for operations on\n members of hashed collections including ``set``, ``frozenset``, and\n ``dict``. ``__hash__()`` should return an integer. The only\n required property is that objects which compare equal have the same\n hash value; it is advised to somehow mix together (e.g. using\n exclusive or) the hash values for the components of the object that\n also play a part in comparison of objects.\n\n Note: ``hash()`` truncates the value returned from an object\'s custom\n ``__hash__()`` method to the size of a ``Py_ssize_t``. This is\n typically 8 bytes on 64-bit builds and 4 bytes on 32-bit builds.\n If an object\'s ``__hash__()`` must interoperate on builds of\n different bit sizes, be sure to check the width on all supported\n builds. An easy way to do this is with ``python -c "import sys;\n print(sys.hash_info.width)"``\n\n If a class does not define an ``__eq__()`` method it should not\n define a ``__hash__()`` operation either; if it defines\n ``__eq__()`` but not ``__hash__()``, its instances will not be\n usable as items in hashable collections. If a class defines\n mutable objects and implements an ``__eq__()`` method, it should\n not implement ``__hash__()``, since the implementation of hashable\n collections requires that a key\'s hash value is immutable (if the\n object\'s hash value changes, it will be in the wrong hash bucket).\n\n User-defined classes have ``__eq__()`` and ``__hash__()`` methods\n by default; with them, all objects compare unequal (except with\n themselves) and ``x.__hash__()`` returns an appropriate value such\n that ``x == y`` implies both that ``x is y`` and ``hash(x) ==\n hash(y)``.\n\n A class that overrides ``__eq__()`` and does not define\n ``__hash__()`` will have its ``__hash__()`` implicitly set to\n ``None``. When the ``__hash__()`` method of a class is ``None``,\n instances of the class will raise an appropriate ``TypeError`` when\n a program attempts to retrieve their hash value, and will also be\n correctly identified as unhashable when checking ``isinstance(obj,\n collections.Hashable``).\n\n If a class that overrides ``__eq__()`` needs to retain the\n implementation of ``__hash__()`` from a parent class, the\n interpreter must be told this explicitly by setting ``__hash__ =\n .__hash__``.\n\n If a class that does not override ``__eq__()`` wishes to suppress\n hash support, it should include ``__hash__ = None`` in the class\n definition. A class which defines its own ``__hash__()`` that\n explicitly raises a ``TypeError`` would be incorrectly identified\n as hashable by an ``isinstance(obj, collections.Hashable)`` call.\n\n Note: By default, the ``__hash__()`` values of str, bytes and datetime\n objects are "salted" with an unpredictable random value.\n Although they remain constant within an individual Python\n process, they are not predictable between repeated invocations of\n Python.This is intended to provide protection against a denial-\n of-service caused by carefully-chosen inputs that exploit the\n worst case performance of a dict insertion, O(n^2) complexity.\n See http://www.ocert.org/advisories/ocert-2011-003.html for\n details.Changing hash values affects the iteration order of\n dicts, sets and other mappings. Python has never made guarantees\n about this ordering (and it typically varies between 32-bit and\n 64-bit builds).See also ``PYTHONHASHSEED``.\n\n Changed in version 3.3: Hash randomization is enabled by default.\n\nobject.__bool__(self)\n\n Called to implement truth value testing and the built-in operation\n ``bool()``; should return ``False`` or ``True``. When this method\n is not defined, ``__len__()`` is called, if it is defined, and the\n object is considered true if its result is nonzero. If a class\n defines neither ``__len__()`` nor ``__bool__()``, all its instances\n are considered true.\n', - 'debugger': '\n``pdb`` --- The Python Debugger\n*******************************\n\nThe module ``pdb`` defines an interactive source code debugger for\nPython programs. It supports setting (conditional) breakpoints and\nsingle stepping at the source line level, inspection of stack frames,\nsource code listing, and evaluation of arbitrary Python code in the\ncontext of any stack frame. It also supports post-mortem debugging\nand can be called under program control.\n\nThe debugger is extensible -- it is actually defined as the class\n``Pdb``. This is currently undocumented but easily understood by\nreading the source. The extension interface uses the modules ``bdb``\nand ``cmd``.\n\nThe debugger\'s prompt is ``(Pdb)``. Typical usage to run a program\nunder control of the debugger is:\n\n >>> import pdb\n >>> import mymodule\n >>> pdb.run(\'mymodule.test()\')\n > (0)?()\n (Pdb) continue\n > (1)?()\n (Pdb) continue\n NameError: \'spam\'\n > (1)?()\n (Pdb)\n\nChanged in version 3.3: Tab-completion via the ``readline`` module is\navailable for commands and command arguments, e.g. the current global\nand local names are offered as arguments of the ``p`` command.\n\n``pdb.py`` can also be invoked as a script to debug other scripts.\nFor example:\n\n python3 -m pdb myscript.py\n\nWhen invoked as a script, pdb will automatically enter post-mortem\ndebugging if the program being debugged exits abnormally. After post-\nmortem debugging (or after normal exit of the program), pdb will\nrestart the program. Automatic restarting preserves pdb\'s state (such\nas breakpoints) and in most cases is more useful than quitting the\ndebugger upon program\'s exit.\n\nNew in version 3.2: ``pdb.py`` now accepts a ``-c`` option that\nexecutes commands as if given in a ``.pdbrc`` file, see *Debugger\nCommands*.\n\nThe typical usage to break into the debugger from a running program is\nto insert\n\n import pdb; pdb.set_trace()\n\nat the location you want to break into the debugger. You can then\nstep through the code following this statement, and continue running\nwithout the debugger using the ``continue`` command.\n\nThe typical usage to inspect a crashed program is:\n\n >>> import pdb\n >>> import mymodule\n >>> mymodule.test()\n Traceback (most recent call last):\n File "", line 1, in ?\n File "./mymodule.py", line 4, in test\n test2()\n File "./mymodule.py", line 3, in test2\n print(spam)\n NameError: spam\n >>> pdb.pm()\n > ./mymodule.py(3)test2()\n -> print(spam)\n (Pdb)\n\nThe module defines the following functions; each enters the debugger\nin a slightly different way:\n\npdb.run(statement, globals=None, locals=None)\n\n Execute the *statement* (given as a string or a code object) under\n debugger control. The debugger prompt appears before any code is\n executed; you can set breakpoints and type ``continue``, or you can\n step through the statement using ``step`` or ``next`` (all these\n commands are explained below). The optional *globals* and *locals*\n arguments specify the environment in which the code is executed; by\n default the dictionary of the module ``__main__`` is used. (See\n the explanation of the built-in ``exec()`` or ``eval()``\n functions.)\n\npdb.runeval(expression, globals=None, locals=None)\n\n Evaluate the *expression* (given as a string or a code object)\n under debugger control. When ``runeval()`` returns, it returns the\n value of the expression. Otherwise this function is similar to\n ``run()``.\n\npdb.runcall(function, *args, **kwds)\n\n Call the *function* (a function or method object, not a string)\n with the given arguments. When ``runcall()`` returns, it returns\n whatever the function call returned. The debugger prompt appears\n as soon as the function is entered.\n\npdb.set_trace()\n\n Enter the debugger at the calling stack frame. This is useful to\n hard-code a breakpoint at a given point in a program, even if the\n code is not otherwise being debugged (e.g. when an assertion\n fails).\n\npdb.post_mortem(traceback=None)\n\n Enter post-mortem debugging of the given *traceback* object. If no\n *traceback* is given, it uses the one of the exception that is\n currently being handled (an exception must be being handled if the\n default is to be used).\n\npdb.pm()\n\n Enter post-mortem debugging of the traceback found in\n ``sys.last_traceback``.\n\nThe ``run*`` functions and ``set_trace()`` are aliases for\ninstantiating the ``Pdb`` class and calling the method of the same\nname. If you want to access further features, you have to do this\nyourself:\n\nclass class pdb.Pdb(completekey=\'tab\', stdin=None, stdout=None, skip=None, nosigint=False)\n\n ``Pdb`` is the debugger class.\n\n The *completekey*, *stdin* and *stdout* arguments are passed to the\n underlying ``cmd.Cmd`` class; see the description there.\n\n The *skip* argument, if given, must be an iterable of glob-style\n module name patterns. The debugger will not step into frames that\n originate in a module that matches one of these patterns. [1]\n\n By default, Pdb sets a handler for the SIGINT signal (which is sent\n when the user presses Ctrl-C on the console) when you give a\n ``continue`` command. This allows you to break into the debugger\n again by pressing Ctrl-C. If you want Pdb not to touch the SIGINT\n handler, set *nosigint* tot true.\n\n Example call to enable tracing with *skip*:\n\n import pdb; pdb.Pdb(skip=[\'django.*\']).set_trace()\n\n New in version 3.1: The *skip* argument.\n\n New in version 3.2: The *nosigint* argument. Previously, a SIGINT\n handler was never set by Pdb.\n\n run(statement, globals=None, locals=None)\n runeval(expression, globals=None, locals=None)\n runcall(function, *args, **kwds)\n set_trace()\n\n See the documentation for the functions explained above.\n\n\nDebugger Commands\n=================\n\nThe commands recognized by the debugger are listed below. Most\ncommands can be abbreviated to one or two letters as indicated; e.g.\n``h(elp)`` means that either ``h`` or ``help`` can be used to enter\nthe help command (but not ``he`` or ``hel``, nor ``H`` or ``Help`` or\n``HELP``). Arguments to commands must be separated by whitespace\n(spaces or tabs). Optional arguments are enclosed in square brackets\n(``[]``) in the command syntax; the square brackets must not be typed.\nAlternatives in the command syntax are separated by a vertical bar\n(``|``).\n\nEntering a blank line repeats the last command entered. Exception: if\nthe last command was a ``list`` command, the next 11 lines are listed.\n\nCommands that the debugger doesn\'t recognize are assumed to be Python\nstatements and are executed in the context of the program being\ndebugged. Python statements can also be prefixed with an exclamation\npoint (``!``). This is a powerful way to inspect the program being\ndebugged; it is even possible to change a variable or call a function.\nWhen an exception occurs in such a statement, the exception name is\nprinted but the debugger\'s state is not changed.\n\nThe debugger supports *aliases*. Aliases can have parameters which\nallows one a certain level of adaptability to the context under\nexamination.\n\nMultiple commands may be entered on a single line, separated by\n``;;``. (A single ``;`` is not used as it is the separator for\nmultiple commands in a line that is passed to the Python parser.) No\nintelligence is applied to separating the commands; the input is split\nat the first ``;;`` pair, even if it is in the middle of a quoted\nstring.\n\nIf a file ``.pdbrc`` exists in the user\'s home directory or in the\ncurrent directory, it is read in and executed as if it had been typed\nat the debugger prompt. This is particularly useful for aliases. If\nboth files exist, the one in the home directory is read first and\naliases defined there can be overridden by the local file.\n\nChanged in version 3.2: ``.pdbrc`` can now contain commands that\ncontinue debugging, such as ``continue`` or ``next``. Previously,\nthese commands had no effect.\n\nh(elp) [command]\n\n Without argument, print the list of available commands. With a\n *command* as argument, print help about that command. ``help pdb``\n displays the full documentation (the docstring of the ``pdb``\n module). Since the *command* argument must be an identifier,\n ``help exec`` must be entered to get help on the ``!`` command.\n\nw(here)\n\n Print a stack trace, with the most recent frame at the bottom. An\n arrow indicates the current frame, which determines the context of\n most commands.\n\nd(own) [count]\n\n Move the current frame *count* (default one) levels down in the\n stack trace (to a newer frame).\n\nu(p) [count]\n\n Move the current frame *count* (default one) levels up in the stack\n trace (to an older frame).\n\nb(reak) [([filename:]lineno | function) [, condition]]\n\n With a *lineno* argument, set a break there in the current file.\n With a *function* argument, set a break at the first executable\n statement within that function. The line number may be prefixed\n with a filename and a colon, to specify a breakpoint in another\n file (probably one that hasn\'t been loaded yet). The file is\n searched on ``sys.path``. Note that each breakpoint is assigned a\n number to which all the other breakpoint commands refer.\n\n If a second argument is present, it is an expression which must\n evaluate to true before the breakpoint is honored.\n\n Without argument, list all breaks, including for each breakpoint,\n the number of times that breakpoint has been hit, the current\n ignore count, and the associated condition if any.\n\ntbreak [([filename:]lineno | function) [, condition]]\n\n Temporary breakpoint, which is removed automatically when it is\n first hit. The arguments are the same as for ``break``.\n\ncl(ear) [filename:lineno | bpnumber [bpnumber ...]]\n\n With a *filename:lineno* argument, clear all the breakpoints at\n this line. With a space separated list of breakpoint numbers, clear\n those breakpoints. Without argument, clear all breaks (but first\n ask confirmation).\n\ndisable [bpnumber [bpnumber ...]]\n\n Disable the breakpoints given as a space separated list of\n breakpoint numbers. Disabling a breakpoint means it cannot cause\n the program to stop execution, but unlike clearing a breakpoint, it\n remains in the list of breakpoints and can be (re-)enabled.\n\nenable [bpnumber [bpnumber ...]]\n\n Enable the breakpoints specified.\n\nignore bpnumber [count]\n\n Set the ignore count for the given breakpoint number. If count is\n omitted, the ignore count is set to 0. A breakpoint becomes active\n when the ignore count is zero. When non-zero, the count is\n decremented each time the breakpoint is reached and the breakpoint\n is not disabled and any associated condition evaluates to true.\n\ncondition bpnumber [condition]\n\n Set a new *condition* for the breakpoint, an expression which must\n evaluate to true before the breakpoint is honored. If *condition*\n is absent, any existing condition is removed; i.e., the breakpoint\n is made unconditional.\n\ncommands [bpnumber]\n\n Specify a list of commands for breakpoint number *bpnumber*. The\n commands themselves appear on the following lines. Type a line\n containing just ``end`` to terminate the commands. An example:\n\n (Pdb) commands 1\n (com) p some_variable\n (com) end\n (Pdb)\n\n To remove all commands from a breakpoint, type commands and follow\n it immediately with ``end``; that is, give no commands.\n\n With no *bpnumber* argument, commands refers to the last breakpoint\n set.\n\n You can use breakpoint commands to start your program up again.\n Simply use the continue command, or step, or any other command that\n resumes execution.\n\n Specifying any command resuming execution (currently continue,\n step, next, return, jump, quit and their abbreviations) terminates\n the command list (as if that command was immediately followed by\n end). This is because any time you resume execution (even with a\n simple next or step), you may encounter another breakpoint--which\n could have its own command list, leading to ambiguities about which\n list to execute.\n\n If you use the \'silent\' command in the command list, the usual\n message about stopping at a breakpoint is not printed. This may be\n desirable for breakpoints that are to print a specific message and\n then continue. If none of the other commands print anything, you\n see no sign that the breakpoint was reached.\n\ns(tep)\n\n Execute the current line, stop at the first possible occasion\n (either in a function that is called or on the next line in the\n current function).\n\nn(ext)\n\n Continue execution until the next line in the current function is\n reached or it returns. (The difference between ``next`` and\n ``step`` is that ``step`` stops inside a called function, while\n ``next`` executes called functions at (nearly) full speed, only\n stopping at the next line in the current function.)\n\nunt(il) [lineno]\n\n Without argument, continue execution until the line with a number\n greater than the current one is reached.\n\n With a line number, continue execution until a line with a number\n greater or equal to that is reached. In both cases, also stop when\n the current frame returns.\n\n Changed in version 3.2: Allow giving an explicit line number.\n\nr(eturn)\n\n Continue execution until the current function returns.\n\nc(ont(inue))\n\n Continue execution, only stop when a breakpoint is encountered.\n\nj(ump) lineno\n\n Set the next line that will be executed. Only available in the\n bottom-most frame. This lets you jump back and execute code again,\n or jump forward to skip code that you don\'t want to run.\n\n It should be noted that not all jumps are allowed -- for instance\n it is not possible to jump into the middle of a ``for`` loop or out\n of a ``finally`` clause.\n\nl(ist) [first[, last]]\n\n List source code for the current file. Without arguments, list 11\n lines around the current line or continue the previous listing.\n With ``.`` as argument, list 11 lines around the current line.\n With one argument, list 11 lines around at that line. With two\n arguments, list the given range; if the second argument is less\n than the first, it is interpreted as a count.\n\n The current line in the current frame is indicated by ``->``. If\n an exception is being debugged, the line where the exception was\n originally raised or propagated is indicated by ``>>``, if it\n differs from the current line.\n\n New in version 3.2: The ``>>`` marker.\n\nll | longlist\n\n List all source code for the current function or frame.\n Interesting lines are marked as for ``list``.\n\n New in version 3.2.\n\na(rgs)\n\n Print the argument list of the current function.\n\np expression\n\n Evaluate the *expression* in the current context and print its\n value.\n\n Note: ``print()`` can also be used, but is not a debugger command ---\n this executes the Python ``print()`` function.\n\npp expression\n\n Like the ``p`` command, except the value of the expression is\n pretty-printed using the ``pprint`` module.\n\nwhatis expression\n\n Print the type of the *expression*.\n\nsource expression\n\n Try to get source code for the given object and display it.\n\n New in version 3.2.\n\ndisplay [expression]\n\n Display the value of the expression if it changed, each time\n execution stops in the current frame.\n\n Without expression, list all display expressions for the current\n frame.\n\n New in version 3.2.\n\nundisplay [expression]\n\n Do not display the expression any more in the current frame.\n Without expression, clear all display expressions for the current\n frame.\n\n New in version 3.2.\n\ninteract\n\n Start an interative interpreter (using the ``code`` module) whose\n global namespace contains all the (global and local) names found in\n the current scope.\n\n New in version 3.2.\n\nalias [name [command]]\n\n Create an alias called *name* that executes *command*. The command\n must *not* be enclosed in quotes. Replaceable parameters can be\n indicated by ``%1``, ``%2``, and so on, while ``%*`` is replaced by\n all the parameters. If no command is given, the current alias for\n *name* is shown. If no arguments are given, all aliases are listed.\n\n Aliases may be nested and can contain anything that can be legally\n typed at the pdb prompt. Note that internal pdb commands *can* be\n overridden by aliases. Such a command is then hidden until the\n alias is removed. Aliasing is recursively applied to the first\n word of the command line; all other words in the line are left\n alone.\n\n As an example, here are two useful aliases (especially when placed\n in the ``.pdbrc`` file):\n\n # Print instance variables (usage "pi classInst")\n alias pi for k in %1.__dict__.keys(): print("%1.",k,"=",%1.__dict__[k])\n # Print instance variables in self\n alias ps pi self\n\nunalias name\n\n Delete the specified alias.\n\n! statement\n\n Execute the (one-line) *statement* in the context of the current\n stack frame. The exclamation point can be omitted unless the first\n word of the statement resembles a debugger command. To set a\n global variable, you can prefix the assignment command with a\n ``global`` statement on the same line, e.g.:\n\n (Pdb) global list_options; list_options = [\'-l\']\n (Pdb)\n\nrun [args ...]\nrestart [args ...]\n\n Restart the debugged Python program. If an argument is supplied,\n it is split with ``shlex`` and the result is used as the new\n ``sys.argv``. History, breakpoints, actions and debugger options\n are preserved. ``restart`` is an alias for ``run``.\n\nq(uit)\n\n Quit from the debugger. The program being executed is aborted.\n\n-[ Footnotes ]-\n\n[1] Whether a frame is considered to originate in a certain module is\n determined by the ``__name__`` in the frame globals.\n', - 'del': '\nThe ``del`` statement\n*********************\n\n del_stmt ::= "del" target_list\n\nDeletion is recursively defined very similar to the way assignment is\ndefined. Rather than spelling it out in full details, here are some\nhints.\n\nDeletion of a target list recursively deletes each target, from left\nto right.\n\nDeletion of a name removes the binding of that name from the local or\nglobal namespace, depending on whether the name occurs in a ``global``\nstatement in the same code block. If the name is unbound, a\n``NameError`` exception will be raised.\n\nDeletion of attribute references, subscriptions and slicings is passed\nto the primary object involved; deletion of a slicing is in general\nequivalent to assignment of an empty slice of the right type (but even\nthis is determined by the sliced object).\n\nChanged in version 3.2: Previously it was illegal to delete a name\nfrom the local namespace if it occurs as a free variable in a nested\nblock.\n', - 'dict': '\nDictionary displays\n*******************\n\nA dictionary display is a possibly empty series of key/datum pairs\nenclosed in curly braces:\n\n dict_display ::= "{" [key_datum_list | dict_comprehension] "}"\n key_datum_list ::= key_datum ("," key_datum)* [","]\n key_datum ::= expression ":" expression\n dict_comprehension ::= expression ":" expression comp_for\n\nA dictionary display yields a new dictionary object.\n\nIf a comma-separated sequence of key/datum pairs is given, they are\nevaluated from left to right to define the entries of the dictionary:\neach key object is used as a key into the dictionary to store the\ncorresponding datum. This means that you can specify the same key\nmultiple times in the key/datum list, and the final dictionary\'s value\nfor that key will be the last one given.\n\nA dict comprehension, in contrast to list and set comprehensions,\nneeds two expressions separated with a colon followed by the usual\n"for" and "if" clauses. When the comprehension is run, the resulting\nkey and value elements are inserted in the new dictionary in the order\nthey are produced.\n\nRestrictions on the types of the key values are listed earlier in\nsection *The standard type hierarchy*. (To summarize, the key type\nshould be *hashable*, which excludes all mutable objects.) Clashes\nbetween duplicate keys are not detected; the last datum (textually\nrightmost in the display) stored for a given key value prevails.\n', - 'dynamic-features': '\nInteraction with dynamic features\n*********************************\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nThe ``eval()`` and ``exec()`` functions do not have access to the full\nenvironment for resolving names. Names may be resolved in the local\nand global namespaces of the caller. Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace. [1]\nThe ``exec()`` and ``eval()`` functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n', - 'else': '\nThe ``if`` statement\n********************\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n', - 'exceptions': '\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nNote: Exception messages are not part of the Python API. Their contents\n may change from one version of Python to the next without warning\n and should not be relied on by code which will run under multiple\n versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', - 'execmodel': '\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The string argument passed\nto the built-in functions ``eval()`` and ``exec()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes comprehensions and generator\nexpressions since they are implemented using a function scope. This\nmeans that the following will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block,\nunless declared as ``nonlocal``. If a name is bound at the module\nlevel, it is a global variable. (The variables of the module code\nblock are local and global.) If a variable is used in a code block\nbut not defined there, it is a *free variable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or\nafter ``as`` in a ``with`` statement or ``except`` clause. The\n``import`` statement of the form ``from ... import *`` binds all names\ndefined in the imported module, except those beginning with an\nunderscore. This form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name).\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the ``global`` statement occurs within a block, all uses of the\nname specified in the statement refer to the binding of that name in\nthe top-level namespace. Names are resolved in the top-level\nnamespace by searching the global namespace, i.e. the namespace of the\nmodule containing the code block, and the builtins namespace, the\nnamespace of the module ``builtins``. The global namespace is\nsearched first. If the name is not found there, the builtins\nnamespace is searched. The global statement must precede all uses of\nthe name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``builtins``; when in any other module, ``__builtins__`` is an alias\nfor the dictionary of the ``builtins`` module itself.\n``__builtins__`` can be set to a user-created dictionary to create a\nweak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n``__builtins__``; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should ``import``\nthe ``builtins`` module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe ``global`` statement has the same scope as a name binding\noperation in the same block. If the nearest enclosing scope for a\nfree variable contains a global statement, the free variable is\ntreated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n---------------------------------\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nThe ``eval()`` and ``exec()`` functions do not have access to the full\nenvironment for resolving names. Names may be resolved in the local\nand global namespaces of the caller. Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace. [1]\nThe ``exec()`` and ``eval()`` functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nNote: Exception messages are not part of the Python API. Their contents\n may change from one version of Python to the next without warning\n and should not be relied on by code which will run under multiple\n versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', - 'exprlists': '\nExpression lists\n****************\n\n expression_list ::= expression ( "," expression )* [","]\n\nAn expression list containing at least one comma yields a tuple. The\nlength of the tuple is the number of expressions in the list. The\nexpressions are evaluated from left to right.\n\nThe trailing comma is required only to create a single tuple (a.k.a. a\n*singleton*); it is optional in all other cases. A single expression\nwithout a trailing comma doesn\'t create a tuple, but rather yields the\nvalue of that expression. (To create an empty tuple, use an empty pair\nof parentheses: ``()``.)\n', - 'floating': '\nFloating point literals\n***********************\n\nFloating point literals are described by the following lexical\ndefinitions:\n\n floatnumber ::= pointfloat | exponentfloat\n pointfloat ::= [intpart] fraction | intpart "."\n exponentfloat ::= (intpart | pointfloat) exponent\n intpart ::= digit+\n fraction ::= "." digit+\n exponent ::= ("e" | "E") ["+" | "-"] digit+\n\nNote that the integer and exponent parts are always interpreted using\nradix 10. For example, ``077e010`` is legal, and denotes the same\nnumber as ``77e10``. The allowed range of floating point literals is\nimplementation-dependent. Some examples of floating point literals:\n\n 3.14 10. .001 1e100 3.14e-10 0e0\n\nNote that numeric literals do not include a sign; a phrase like ``-1``\nis actually an expression composed of the unary operator ``-`` and the\nliteral ``1``.\n', - 'for': '\nThe ``for`` statement\n*********************\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n``expression_list``. The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments (see *Assignment statements*), and then the suite is\nexecuted. When the items are exhausted (which is immediately when the\nsequence is empty or an iterator raises a ``StopIteration``\nexception), the suite in the ``else`` clause, if present, is executed,\nand the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nNames in the target list are not deleted when the loop is finished,\nbut if the sequence is empty, it will not have been assigned to at all\nby the loop. Hint: the built-in function ``range()`` returns an\niterator of integers suitable to emulate the effect of Pascal\'s ``for\ni := a to b do``; e.g., ``list(range(3))`` returns the list ``[0, 1,\n2]``.\n\nNote: There is a subtlety when the sequence is being modified by the loop\n (this can only occur for mutable sequences, i.e. lists). An\n internal counter is used to keep track of which item is used next,\n and this is incremented on each iteration. When this counter has\n reached the length of the sequence the loop terminates. This means\n that if the suite deletes the current (or a previous) item from the\n sequence, the next item will be skipped (since it gets the index of\n the current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n', - 'formatstrings': '\nFormat String Syntax\n********************\n\nThe ``str.format()`` method and the ``Formatter`` class share the same\nsyntax for format strings (although in the case of ``Formatter``,\nsubclasses can define their own format string syntax).\n\nFormat strings contain "replacement fields" surrounded by curly braces\n``{}``. Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output. If you need to include\na brace character in the literal text, it can be escaped by doubling:\n``{{`` and ``}}``.\n\nThe grammar for a replacement field is as follows:\n\n replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"\n field_name ::= arg_name ("." attribute_name | "[" element_index "]")*\n arg_name ::= [identifier | integer]\n attribute_name ::= identifier\n element_index ::= integer | index_string\n index_string ::= +\n conversion ::= "r" | "s" | "a"\n format_spec ::= \n\nIn less formal terms, the replacement field can start with a\n*field_name* that specifies the object whose value is to be formatted\nand inserted into the output instead of the replacement field. The\n*field_name* is optionally followed by a *conversion* field, which is\npreceded by an exclamation point ``\'!\'``, and a *format_spec*, which\nis preceded by a colon ``\':\'``. These specify a non-default format\nfor the replacement value.\n\nSee also the *Format Specification Mini-Language* section.\n\nThe *field_name* itself begins with an *arg_name* that is either a\nnumber or a keyword. If it\'s a number, it refers to a positional\nargument, and if it\'s a keyword, it refers to a named keyword\nargument. If the numerical arg_names in a format string are 0, 1, 2,\n... in sequence, they can all be omitted (not just some) and the\nnumbers 0, 1, 2, ... will be automatically inserted in that order.\nBecause *arg_name* is not quote-delimited, it is not possible to\nspecify arbitrary dictionary keys (e.g., the strings ``\'10\'`` or\n``\':-]\'``) within a format string. The *arg_name* can be followed by\nany number of index or attribute expressions. An expression of the\nform ``\'.name\'`` selects the named attribute using ``getattr()``,\nwhile an expression of the form ``\'[index]\'`` does an index lookup\nusing ``__getitem__()``.\n\nChanged in version 3.1: The positional argument specifiers can be\nomitted, so ``\'{} {}\'`` is equivalent to ``\'{0} {1}\'``.\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\n "Bring me a {}" # Implicitly references the first positional argument\n "From {} to {}" # Same as "From {0} to {1}"\n "My quest is {name}" # References keyword argument \'name\'\n "Weight in tons {0.weight}" # \'weight\' attribute of first positional arg\n "Units destroyed: {players[0]}" # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the\n``__format__()`` method of the value itself. However, in some cases\nit is desirable to force a type to be formatted as a string,\noverriding its own definition of formatting. By converting the value\nto a string before calling ``__format__()``, the normal formatting\nlogic is bypassed.\n\nThree conversion flags are currently supported: ``\'!s\'`` which calls\n``str()`` on the value, ``\'!r\'`` which calls ``repr()`` and ``\'!a\'``\nwhich calls ``ascii()``.\n\nSome examples:\n\n "Harold\'s a clever {0!s}" # Calls str() on the argument first\n "Bring out the holy {name!r}" # Calls repr() on the argument first\n "More {!a}" # Calls ascii() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on. Each value type can define its\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields can contain only a field\nname; conversion flags and format specifications are not allowed. The\nreplacement fields within the format_spec are substituted before the\n*format_spec* string is interpreted. This allows the formatting of a\nvalue to be dynamically specified.\n\nSee the *Format examples* section for some examples.\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see *Format String Syntax*). They can also be passed directly to the\nbuilt-in ``format()`` function. Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string (``""``) produces\nthe same result as if you had called ``str()`` on the value. A non-\nempty format string typically modifies the result.\n\nThe general form of a *standard format specifier* is:\n\n format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]\n fill ::= \n align ::= "<" | ">" | "=" | "^"\n sign ::= "+" | "-" | " "\n width ::= integer\n precision ::= integer\n type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n\nIf a valid *align* value is specified, it can be preceded by a *fill*\ncharacter that can be any character and defaults to a space if\nomitted. Note that it is not possible to use ``{`` and ``}`` as *fill*\nchar while using the ``str.format()`` method; this limitation however\ndoesn\'t affect the ``format()`` function.\n\nThe meaning of the various alignment options is as follows:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'<\'`` | Forces the field to be left-aligned within the available |\n | | space (this is the default for most objects). |\n +-----------+------------------------------------------------------------+\n | ``\'>\'`` | Forces the field to be right-aligned within the available |\n | | space (this is the default for numbers). |\n +-----------+------------------------------------------------------------+\n | ``\'=\'`` | Forces the padding to be placed after the sign (if any) |\n | | but before the digits. This is used for printing fields |\n | | in the form \'+000000120\'. This alignment option is only |\n | | valid for numeric types. |\n +-----------+------------------------------------------------------------+\n | ``\'^\'`` | Forces the field to be centered within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'+\'`` | indicates that a sign should be used for both positive as |\n | | well as negative numbers. |\n +-----------+------------------------------------------------------------+\n | ``\'-\'`` | indicates that a sign should be used only for negative |\n | | numbers (this is the default behavior). |\n +-----------+------------------------------------------------------------+\n | space | indicates that a leading space should be used on positive |\n | | numbers, and a minus sign on negative numbers. |\n +-----------+------------------------------------------------------------+\n\nThe ``\'#\'`` option causes the "alternate form" to be used for the\nconversion. The alternate form is defined differently for different\ntypes. This option is only valid for integer, float, complex and\nDecimal types. For integers, when binary, octal, or hexadecimal output\nis used, this option adds the prefix respective ``\'0b\'``, ``\'0o\'``, or\n``\'0x\'`` to the output value. For floats, complex and Decimal the\nalternate form causes the result of the conversion to always contain a\ndecimal-point character, even if no digits follow it. Normally, a\ndecimal-point character appears in the result of these conversions\nonly if a digit follows it. In addition, for ``\'g\'`` and ``\'G\'``\nconversions, trailing zeros are not removed from the result.\n\nThe ``\',\'`` option signals the use of a comma for a thousands\nseparator. For a locale aware separator, use the ``\'n\'`` integer\npresentation type instead.\n\nChanged in version 3.1: Added the ``\',\'`` option (see also **PEP\n378**).\n\n*width* is a decimal integer defining the minimum field width. If not\nspecified, then the field width will be determined by the content.\n\nPreceding the *width* field by a zero (``\'0\'``) character enables\nsign-aware zero-padding for numeric types. This is equivalent to a\n*fill* character of ``\'0\'`` with an *alignment* type of ``\'=\'``.\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value\nformatted with ``\'f\'`` and ``\'F\'``, or before and after the decimal\npoint for a floating point value formatted with ``\'g\'`` or ``\'G\'``.\nFor non-number types the field indicates the maximum field size - in\nother words, how many characters will be used from the field content.\nThe *precision* is not allowed for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available string presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'s\'`` | String format. This is the default type for strings and |\n | | may be omitted. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'s\'``. |\n +-----------+------------------------------------------------------------+\n\nThe available integer presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'b\'`` | Binary format. Outputs the number in base 2. |\n +-----------+------------------------------------------------------------+\n | ``\'c\'`` | Character. Converts the integer to the corresponding |\n | | unicode character before printing. |\n +-----------+------------------------------------------------------------+\n | ``\'d\'`` | Decimal Integer. Outputs the number in base 10. |\n +-----------+------------------------------------------------------------+\n | ``\'o\'`` | Octal format. Outputs the number in base 8. |\n +-----------+------------------------------------------------------------+\n | ``\'x\'`` | Hex format. Outputs the number in base 16, using lower- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'X\'`` | Hex format. Outputs the number in base 16, using upper- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'d\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'d\'``. |\n +-----------+------------------------------------------------------------+\n\nIn addition to the above presentation types, integers can be formatted\nwith the floating point presentation types listed below (except\n``\'n\'`` and None). When doing so, ``float()`` is used to convert the\ninteger to a floating point number before formatting.\n\nThe available presentation types for floating point and decimal values\nare:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'e\'`` | Exponent notation. Prints the number in scientific |\n | | notation using the letter \'e\' to indicate the exponent. |\n | | The default precision is ``6``. |\n +-----------+------------------------------------------------------------+\n | ``\'E\'`` | Exponent notation. Same as ``\'e\'`` except it uses an upper |\n | | case \'E\' as the separator character. |\n +-----------+------------------------------------------------------------+\n | ``\'f\'`` | Fixed point. Displays the number as a fixed-point number. |\n | | The default precision is ``6``. |\n +-----------+------------------------------------------------------------+\n | ``\'F\'`` | Fixed point. Same as ``\'f\'``, but converts ``nan`` to |\n | | ``NAN`` and ``inf`` to ``INF``. |\n +-----------+------------------------------------------------------------+\n | ``\'g\'`` | General format. For a given precision ``p >= 1``, this |\n | | rounds the number to ``p`` significant digits and then |\n | | formats the result in either fixed-point format or in |\n | | scientific notation, depending on its magnitude. The |\n | | precise rules are as follows: suppose that the result |\n | | formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1`` would have exponent ``exp``. Then if ``-4 <= exp |\n | | < p``, the number is formatted with presentation type |\n | | ``\'f\'`` and precision ``p-1-exp``. Otherwise, the number |\n | | is formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1``. In both cases insignificant trailing zeros are |\n | | removed from the significand, and the decimal point is |\n | | also removed if there are no remaining digits following |\n | | it. Positive and negative infinity, positive and negative |\n | | zero, and nans, are formatted as ``inf``, ``-inf``, ``0``, |\n | | ``-0`` and ``nan`` respectively, regardless of the |\n | | precision. A precision of ``0`` is treated as equivalent |\n | | to a precision of ``1``. The default precision is ``6``. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets too large. The representations of |\n | | infinity and NaN are uppercased, too. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'g\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | ``\'%\'`` | Percentage. Multiplies the number by 100 and displays in |\n | | fixed (``\'f\'``) format, followed by a percent sign. |\n +-----------+------------------------------------------------------------+\n | None | Similar to ``\'g\'``, except with at least one digit past |\n | | the decimal point and a default precision of 12. This is |\n | | intended to match ``str()``, except you can add the other |\n | | format modifiers. |\n +-----------+------------------------------------------------------------+\n\n\nFormat examples\n===============\n\nThis section contains examples of the new format syntax and comparison\nwith the old ``%``-formatting.\n\nIn most of the cases the syntax is similar to the old\n``%``-formatting, with the addition of the ``{}`` and with ``:`` used\ninstead of ``%``. For example, ``\'%03.2f\'`` can be translated to\n``\'{:03.2f}\'``.\n\nThe new format syntax also supports new and different options, shown\nin the follow examples.\n\nAccessing arguments by position:\n\n >>> \'{0}, {1}, {2}\'.format(\'a\', \'b\', \'c\')\n \'a, b, c\'\n >>> \'{}, {}, {}\'.format(\'a\', \'b\', \'c\') # 3.1+ only\n \'a, b, c\'\n >>> \'{2}, {1}, {0}\'.format(\'a\', \'b\', \'c\')\n \'c, b, a\'\n >>> \'{2}, {1}, {0}\'.format(*\'abc\') # unpacking argument sequence\n \'c, b, a\'\n >>> \'{0}{1}{0}\'.format(\'abra\', \'cad\') # arguments\' indices can be repeated\n \'abracadabra\'\n\nAccessing arguments by name:\n\n >>> \'Coordinates: {latitude}, {longitude}\'.format(latitude=\'37.24N\', longitude=\'-115.81W\')\n \'Coordinates: 37.24N, -115.81W\'\n >>> coord = {\'latitude\': \'37.24N\', \'longitude\': \'-115.81W\'}\n >>> \'Coordinates: {latitude}, {longitude}\'.format(**coord)\n \'Coordinates: 37.24N, -115.81W\'\n\nAccessing arguments\' attributes:\n\n >>> c = 3-5j\n >>> (\'The complex number {0} is formed from the real part {0.real} \'\n ... \'and the imaginary part {0.imag}.\').format(c)\n \'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.\'\n >>> class Point:\n ... def __init__(self, x, y):\n ... self.x, self.y = x, y\n ... def __str__(self):\n ... return \'Point({self.x}, {self.y})\'.format(self=self)\n ...\n >>> str(Point(4, 2))\n \'Point(4, 2)\'\n\nAccessing arguments\' items:\n\n >>> coord = (3, 5)\n >>> \'X: {0[0]}; Y: {0[1]}\'.format(coord)\n \'X: 3; Y: 5\'\n\nReplacing ``%s`` and ``%r``:\n\n >>> "repr() shows quotes: {!r}; str() doesn\'t: {!s}".format(\'test1\', \'test2\')\n "repr() shows quotes: \'test1\'; str() doesn\'t: test2"\n\nAligning the text and specifying a width:\n\n >>> \'{:<30}\'.format(\'left aligned\')\n \'left aligned \'\n >>> \'{:>30}\'.format(\'right aligned\')\n \' right aligned\'\n >>> \'{:^30}\'.format(\'centered\')\n \' centered \'\n >>> \'{:*^30}\'.format(\'centered\') # use \'*\' as a fill char\n \'***********centered***********\'\n\nReplacing ``%+f``, ``%-f``, and ``% f`` and specifying a sign:\n\n >>> \'{:+f}; {:+f}\'.format(3.14, -3.14) # show it always\n \'+3.140000; -3.140000\'\n >>> \'{: f}; {: f}\'.format(3.14, -3.14) # show a space for positive numbers\n \' 3.140000; -3.140000\'\n >>> \'{:-f}; {:-f}\'.format(3.14, -3.14) # show only the minus -- same as \'{:f}; {:f}\'\n \'3.140000; -3.140000\'\n\nReplacing ``%x`` and ``%o`` and converting the value to different\nbases:\n\n >>> # format also supports binary numbers\n >>> "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42)\n \'int: 42; hex: 2a; oct: 52; bin: 101010\'\n >>> # with 0x, 0o, or 0b as prefix:\n >>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42)\n \'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010\'\n\nUsing the comma as a thousands separator:\n\n >>> \'{:,}\'.format(1234567890)\n \'1,234,567,890\'\n\nExpressing a percentage:\n\n >>> points = 19\n >>> total = 22\n >>> \'Correct answers: {:.2%}\'.format(points/total)\n \'Correct answers: 86.36%\'\n\nUsing type-specific formatting:\n\n >>> import datetime\n >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n >>> \'{:%Y-%m-%d %H:%M:%S}\'.format(d)\n \'2010-07-04 12:15:58\'\n\nNesting arguments and more complex examples:\n\n >>> for align, text in zip(\'<^>\', [\'left\', \'center\', \'right\']):\n ... \'{0:{fill}{align}16}\'.format(text, fill=align, align=align)\n ...\n \'left<<<<<<<<<<<<\'\n \'^^^^^center^^^^^\'\n \'>>>>>>>>>>>right\'\n >>>\n >>> octets = [192, 168, 0, 1]\n >>> \'{:02X}{:02X}{:02X}{:02X}\'.format(*octets)\n \'C0A80001\'\n >>> int(_, 16)\n 3232235521\n >>>\n >>> width = 5\n >>> for num in range(5,12): #doctest: +NORMALIZE_WHITESPACE\n ... for base in \'dXob\':\n ... print(\'{0:{width}{base}}\'.format(num, base=base, width=width), end=\' \')\n ... print()\n ...\n 5 5 5 101\n 6 6 6 110\n 7 7 7 111\n 8 8 10 1000\n 9 9 11 1001\n 10 A 12 1010\n 11 B 13 1011\n', - 'function': '\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n funcdef ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [parameter_list [","]] ")"] NEWLINE\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" [parameter] ("," defparameter)* ["," "**" parameter]\n | "**" parameter\n | defparameter [","] )\n parameter ::= identifier [":" expression]\n defparameter ::= parameter ["=" expression]\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more *parameters* have the form *parameter* ``=``\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding *argument* may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters up until the "``*``" must also have a default value ---\nthis is a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated from left to right when the\nfunction definition is executed.** This means that the expression is\nevaluated once, when the function is defined, and that the same "pre-\ncomputed" value is used for each call. This is especially important\nto understand when a default parameter is a mutable object, such as a\nlist or a dictionary: if the function modifies the object (e.g. by\nappending an item to a list), the default value is in effect modified.\nThis is generally not what was intended. A way around this is to use\n``None`` as the default, and explicitly test for it in the body of the\nfunction, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple. If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after "``*``" or "``*identifier``" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "``: expression``"\nfollowing the parameter name. Any parameter may have an annotation\neven those of the form ``*identifier`` or ``**identifier``. Functions\nmay have "return" annotation of the form "``-> expression``" after the\nparameter list. These annotations can be any valid Python expression\nand are evaluated when the function definition is executed.\nAnnotations may be evaluated in a different order than they appear in\nthe source code. The presence of annotations does not change the\nsemantics of a function. The annotation values are available as\nvalues of a dictionary keyed by the parameters\' names in the\n``__annotations__`` attribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda\nexpressions, described in section *Lambdas*. Note that the lambda\nexpression is merely a shorthand for a simplified function definition;\na function defined in a "``def``" statement can be passed around or\nassigned to another name just like a function defined by a lambda\nexpression. The "``def``" form is actually more powerful since it\nallows the execution of multiple statements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects. A "``def``"\nstatement executed inside a function definition defines a local\nfunction that can be returned or passed around. Free variables used\nin the nested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n\nSee also:\n\n **PEP 3107** - Function Annotations\n The original specification for function annotations.\n', - 'global': '\nThe ``global`` statement\n************************\n\n global_stmt ::= "global" identifier ("," identifier)*\n\nThe ``global`` statement is a declaration which holds for the entire\ncurrent code block. It means that the listed identifiers are to be\ninterpreted as globals. It would be impossible to assign to a global\nvariable without ``global``, although free variables may refer to\nglobals without being declared global.\n\nNames listed in a ``global`` statement must not be used in the same\ncode block textually preceding that ``global`` statement.\n\nNames listed in a ``global`` statement must not be defined as formal\nparameters or in a ``for`` loop control target, ``class`` definition,\nfunction definition, or ``import`` statement.\n\n**CPython implementation detail:** The current implementation does not\nenforce the latter two restrictions, but programs should not abuse\nthis freedom, as future implementations may enforce them or silently\nchange the meaning of the program.\n\n**Programmer\'s note:** the ``global`` is a directive to the parser.\nIt applies only to code parsed at the same time as the ``global``\nstatement. In particular, a ``global`` statement contained in a string\nor code object supplied to the built-in ``exec()`` function does not\naffect the code block *containing* the function call, and code\ncontained in such a string is unaffected by ``global`` statements in\nthe code containing the function call. The same applies to the\n``eval()`` and ``compile()`` functions.\n', - 'id-classes': '\nReserved classes of identifiers\n*******************************\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``builtins`` module. When\n not in interactive mode, ``_`` has no special meaning and is not\n defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library). Current\n system names are discussed in the *Special method names* section\n and elsewhere. More will likely be defined in future versions of\n Python. *Any* use of ``__*__`` names, in any context, that does\n not follow explicitly documented use, is subject to breakage\n without warning.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', - 'identifiers': '\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions.\n\nThe syntax of identifiers in Python is based on the Unicode standard\nannex UAX-31, with elaboration and changes as defined below; see also\n**PEP 3131** for further details.\n\nWithin the ASCII range (U+0001..U+007F), the valid characters for\nidentifiers are the same as in Python 2.x: the uppercase and lowercase\nletters ``A`` through ``Z``, the underscore ``_`` and, except for the\nfirst character, the digits ``0`` through ``9``.\n\nPython 3.0 introduces additional characters from outside the ASCII\nrange (see **PEP 3131**). For these characters, the classification\nuses the version of the Unicode Character Database as included in the\n``unicodedata`` module.\n\nIdentifiers are unlimited in length. Case is significant.\n\n identifier ::= xid_start xid_continue*\n id_start ::= \n id_continue ::= \n xid_start ::= \n xid_continue ::= \n\nThe Unicode category codes mentioned above stand for:\n\n* *Lu* - uppercase letters\n\n* *Ll* - lowercase letters\n\n* *Lt* - titlecase letters\n\n* *Lm* - modifier letters\n\n* *Lo* - other letters\n\n* *Nl* - letter numbers\n\n* *Mn* - nonspacing marks\n\n* *Mc* - spacing combining marks\n\n* *Nd* - decimal numbers\n\n* *Pc* - connector punctuations\n\n* *Other_ID_Start* - explicit list of characters in PropList.txt to\n support backwards compatibility\n\n* *Other_ID_Continue* - likewise\n\nAll identifiers are converted into the normal form NFKC while parsing;\ncomparison of identifiers is based on NFKC.\n\nA non-normative HTML file listing all valid identifier characters for\nUnicode 4.1 can be found at http://www.dcl.hpi.uni-\npotsdam.de/home/loewis/table-3131.html.\n\n\nKeywords\n========\n\nThe following identifiers are used as reserved words, or *keywords* of\nthe language, and cannot be used as ordinary identifiers. They must\nbe spelled exactly as written here:\n\n False class finally is return\n None continue for lambda try\n True def from nonlocal while\n and del global not with\n as elif if or yield\n assert else import pass\n break except in raise\n\n\nReserved classes of identifiers\n===============================\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``builtins`` module. When\n not in interactive mode, ``_`` has no special meaning and is not\n defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library). Current\n system names are discussed in the *Special method names* section\n and elsewhere. More will likely be defined in future versions of\n Python. *Any* use of ``__*__`` names, in any context, that does\n not follow explicitly documented use, is subject to breakage\n without warning.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', - 'if': '\nThe ``if`` statement\n********************\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n', - 'imaginary': '\nImaginary literals\n******************\n\nImaginary literals are described by the following lexical definitions:\n\n imagnumber ::= (floatnumber | intpart) ("j" | "J")\n\nAn imaginary literal yields a complex number with a real part of 0.0.\nComplex numbers are represented as a pair of floating point numbers\nand have the same restrictions on their range. To create a complex\nnumber with a nonzero real part, add a floating point number to it,\ne.g., ``(3+4j)``. Some examples of imaginary literals:\n\n 3.14j 10.j 10j .001j 1e100j 3.14e-10j\n', - 'import': '\nThe ``import`` statement\n************************\n\n import_stmt ::= "import" module ["as" name] ( "," module ["as" name] )*\n | "from" relative_module "import" identifier ["as" name]\n ( "," identifier ["as" name] )*\n | "from" relative_module "import" "(" identifier ["as" name]\n ( "," identifier ["as" name] )* [","] ")"\n | "from" module "import" "*"\n module ::= (identifier ".")* identifier\n relative_module ::= "."* module | "."+\n name ::= identifier\n\nThe basic import statement (no ``from`` clause) is executed in two\nsteps:\n\n1. find a module, loading and initializing it if necessary\n\n2. define a name or names in the local namespace for the scope where\n the ``import`` statement occurs.\n\nWhen the statement contains multiple clauses (separated by commas) the\ntwo steps are carried out separately for each clause, just as though\nthe clauses had been separated out into individiual import statements.\n\nThe details of the first step, finding and loading modules is\ndescribed in greater detail in the section on the *import system*,\nwhich also describes the various types of packages and modules that\ncan be imported, as well as all the hooks that can be used to\ncustomize the import system. Note that failures in this step may\nindicate either that the module could not be located, *or* that an\nerror occurred while initializing the module, which includes execution\nof the module\'s code.\n\nIf the requested module is retrieved successfully, it will be made\navailable in the local namespace in one of three ways:\n\n* If the module name is followed by ``as``, then the name following\n ``as`` is bound directly to the imported module.\n\n* If no other name is specified, and the module being imported is a\n top level module, the module\'s name is bound in the local namespace\n as a reference to the imported module\n\n* If the module being imported is *not* a top level module, then the\n name of the top level package that contains the module is bound in\n the local namespace as a reference to the top level package. The\n imported module must be accessed using its full qualified name\n rather than directly\n\nThe ``from`` form uses a slightly more complex process:\n\n1. find the module specified in the ``from`` clause loading and\n initializing it if necessary;\n\n2. for each of the identifiers specified in the ``import`` clauses:\n\n 1. check if the imported module has an attribute by that name\n\n 2. if not, attempt to import a submodule with that name and then\n check the imported module again for that attribute\n\n 3. if the attribute is not found, ``ImportError`` is raised.\n\n 4. otherwise, a reference to that value is bound in the local\n namespace, using the name in the ``as`` clause if it is present,\n otherwise using the attribute name\n\nExamples:\n\n import foo # foo imported and bound locally\n import foo.bar.baz # foo.bar.baz imported, foo bound locally\n import foo.bar.baz as fbb # foo.bar.baz imported and bound as fbb\n from foo.bar import baz # foo.bar.baz imported and bound as baz\n from foo import attr # foo imported and foo.attr bound as attr\n\nIf the list of identifiers is replaced by a star (``\'*\'``), all public\nnames defined in the module are bound in the local namespace for the\nscope where the ``import`` statement occurs.\n\nThe *public names* defined by a module are determined by checking the\nmodule\'s namespace for a variable named ``__all__``; if defined, it\nmust be a sequence of strings which are names defined or imported by\nthat module. The names given in ``__all__`` are all considered public\nand are required to exist. If ``__all__`` is not defined, the set of\npublic names includes all names found in the module\'s namespace which\ndo not begin with an underscore character (``\'_\'``). ``__all__``\nshould contain the entire public API. It is intended to avoid\naccidentally exporting items that are not part of the API (such as\nlibrary modules which were imported and used within the module).\n\nThe ``from`` form with ``*`` may only occur in a module scope. The\nwild card form of import --- ``import *`` --- is only allowed at the\nmodule level. Attempting to use it in class or function definitions\nwill raise a ``SyntaxError``.\n\nWhen specifying what module to import you do not have to specify the\nabsolute name of the module. When a module or package is contained\nwithin another package it is possible to make a relative import within\nthe same top package without having to mention the package name. By\nusing leading dots in the specified module or package after ``from``\nyou can specify how high to traverse up the current package hierarchy\nwithout specifying exact names. One leading dot means the current\npackage where the module making the import exists. Two dots means up\none package level. Three dots is up two levels, etc. So if you execute\n``from . import mod`` from a module in the ``pkg`` package then you\nwill end up importing ``pkg.mod``. If you execute ``from ..subpkg2\nimport mod`` from within ``pkg.subpkg1`` you will import\n``pkg.subpkg2.mod``. The specification for relative imports is\ncontained within **PEP 328**.\n\n``importlib.import_module()`` is provided to support applications that\ndetermine which modules need to be loaded dynamically.\n\n\nFuture statements\n=================\n\nA *future statement* is a directive to the compiler that a particular\nmodule should be compiled using syntax or semantics that will be\navailable in a specified future release of Python. The future\nstatement is intended to ease migration to future versions of Python\nthat introduce incompatible changes to the language. It allows use of\nthe new features on a per-module basis before the release in which the\nfeature becomes standard.\n\n future_statement ::= "from" "__future__" "import" feature ["as" name]\n ("," feature ["as" name])*\n | "from" "__future__" "import" "(" feature ["as" name]\n ("," feature ["as" name])* [","] ")"\n feature ::= identifier\n name ::= identifier\n\nA future statement must appear near the top of the module. The only\nlines that can appear before a future statement are:\n\n* the module docstring (if any),\n\n* comments,\n\n* blank lines, and\n\n* other future statements.\n\nThe features recognized by Python 3.0 are ``absolute_import``,\n``division``, ``generators``, ``unicode_literals``,\n``print_function``, ``nested_scopes`` and ``with_statement``. They\nare all redundant because they are always enabled, and only kept for\nbackwards compatibility.\n\nA future statement is recognized and treated specially at compile\ntime: Changes to the semantics of core constructs are often\nimplemented by generating different code. It may even be the case\nthat a new feature introduces new incompatible syntax (such as a new\nreserved word), in which case the compiler may need to parse the\nmodule differently. Such decisions cannot be pushed off until\nruntime.\n\nFor any given release, the compiler knows which feature names have\nbeen defined, and raises a compile-time error if a future statement\ncontains a feature not known to it.\n\nThe direct runtime semantics are the same as for any import statement:\nthere is a standard module ``__future__``, described later, and it\nwill be imported in the usual way at the time the future statement is\nexecuted.\n\nThe interesting runtime semantics depend on the specific feature\nenabled by the future statement.\n\nNote that there is nothing special about the statement:\n\n import __future__ [as name]\n\nThat is not a future statement; it\'s an ordinary import statement with\nno special semantics or syntax restrictions.\n\nCode compiled by calls to the built-in functions ``exec()`` and\n``compile()`` that occur in a module ``M`` containing a future\nstatement will, by default, use the new syntax or semantics associated\nwith the future statement. This can be controlled by optional\narguments to ``compile()`` --- see the documentation of that function\nfor details.\n\nA future statement typed at an interactive interpreter prompt will\ntake effect for the rest of the interpreter session. If an\ninterpreter is started with the *-i* option, is passed a script name\nto execute, and the script includes a future statement, it will be in\neffect in the interactive session started after the script is\nexecuted.\n\nSee also:\n\n **PEP 236** - Back to the __future__\n The original proposal for the __future__ mechanism.\n', - 'in': '\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like ``a < b < c`` have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: ``True`` or ``False``.\n\nComparisons can be chained arbitrarily, e.g., ``x < y <= z`` is\nequivalent to ``x < y and y <= z``, except that ``y`` is evaluated\nonly once (but in both cases ``z`` is not evaluated at all when ``x <\ny`` is found to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then ``a op1 b op2 c ... y\nopN z`` is equivalent to ``a op1 b and b op2 c and ... y opN z``,\nexcept that each expression is evaluated at most once.\n\nNote that ``a op1 b op2 c`` doesn\'t imply any kind of comparison\nbetween *a* and *c*, so that, e.g., ``x < y > z`` is perfectly legal\n(though perhaps not pretty).\n\nThe operators ``<``, ``>``, ``==``, ``>=``, ``<=``, and ``!=`` compare\nthe values of two objects. The objects need not have the same type.\nIf both are numbers, they are converted to a common type. Otherwise,\nthe ``==`` and ``!=`` operators *always* consider objects of different\ntypes to be unequal, while the ``<``, ``>``, ``>=`` and ``<=``\noperators raise a ``TypeError`` when comparing objects of different\ntypes that do not implement these operators for the given pair of\ntypes. You can control comparison behavior of objects of non-built-in\ntypes by defining rich comparison methods like ``__gt__()``, described\nin section *Basic customization*.\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* The values ``float(\'NaN\')`` and ``Decimal(\'NaN\')`` are special. The\n are identical to themselves, ``x is x`` but are not equal to\n themselves, ``x != x``. Additionally, comparing any value to a\n not-a-number value will return ``False``. For example, both ``3 <\n float(\'NaN\')`` and ``float(\'NaN\') < 3`` will return ``False``.\n\n* Bytes objects are compared lexicographically using the numeric\n values of their elements.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n [3] String and bytes object can\'t be compared!\n\n* Tuples and lists are compared lexicographically using comparison of\n corresponding elements. This means that to compare equal, each\n element must compare equal and the two sequences must be of the same\n type and have the same length.\n\n If not equal, the sequences are ordered the same as their first\n differing elements. For example, ``[1,2,x] <= [1,2,y]`` has the\n same value as ``x <= y``. If the corresponding element does not\n exist, the shorter sequence is ordered first (for example, ``[1,2] <\n [1,2,3]``).\n\n* Mappings (dictionaries) compare equal if and only if they have the\n same ``(key, value)`` pairs. Order comparisons ``(\'<\', \'<=\', \'>=\',\n \'>\')`` raise ``TypeError``.\n\n* Sets and frozensets define comparison operators to mean subset and\n superset tests. Those relations do not define total orderings (the\n two sets ``{1,2}`` and {2,3} are not equal, nor subsets of one\n another, nor supersets of one another). Accordingly, sets are not\n appropriate arguments for functions which depend on total ordering.\n For example, ``min()``, ``max()``, and ``sorted()`` produce\n undefined results given a list of sets as inputs.\n\n* Most other objects of built-in types compare unequal unless they are\n the same object; the choice whether one object is considered smaller\n or larger than another one is made arbitrarily but consistently\n within one execution of a program.\n\nComparison of objects of the differing types depends on whether either\nof the types provide explicit support for the comparison. Most\nnumeric types can be compared with one another. When cross-type\ncomparison is not supported, the comparison method returns\n``NotImplemented``.\n\nThe operators ``in`` and ``not in`` test for membership. ``x in s``\nevaluates to true if *x* is a member of *s*, and false otherwise. ``x\nnot in s`` returns the negation of ``x in s``. All built-in sequences\nand set types support this as well as dictionary, for which ``in``\ntests whether a the dictionary has a given key. For container types\nsuch as list, tuple, set, frozenset, dict, or collections.deque, the\nexpression ``x in y`` is equivalent to ``any(x is e or x == e for e in\ny)``.\n\nFor the string and bytes types, ``x in y`` is true if and only if *x*\nis a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nEmpty strings are always considered to be a substring of any other\nstring, so ``"" in "abc"`` will return ``True``.\n\nFor user-defined classes which define the ``__contains__()`` method,\n``x in y`` is true if and only if ``y.__contains__(x)`` is true.\n\nFor user-defined classes which do not define ``__contains__()`` but do\ndefine ``__iter__()``, ``x in y`` is true if some value ``z`` with ``x\n== z`` is produced while iterating over ``y``. If an exception is\nraised during the iteration, it is as if ``in`` raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n``__getitem__()``, ``x in y`` is true if and only if there is a non-\nnegative integer index *i* such that ``x == y[i]``, and all lower\ninteger indices do not raise ``IndexError`` exception. (If any other\nexception is raised, it is as if ``in`` raised that exception).\n\nThe operator ``not in`` is defined to have the inverse true value of\n``in``.\n\nThe operators ``is`` and ``is not`` test for object identity: ``x is\ny`` is true if and only if *x* and *y* are the same object. ``x is\nnot y`` yields the inverse truth value. [4]\n', - 'integers': '\nInteger literals\n****************\n\nInteger literals are described by the following lexical definitions:\n\n integer ::= decimalinteger | octinteger | hexinteger | bininteger\n decimalinteger ::= nonzerodigit digit* | "0"+\n nonzerodigit ::= "1"..."9"\n digit ::= "0"..."9"\n octinteger ::= "0" ("o" | "O") octdigit+\n hexinteger ::= "0" ("x" | "X") hexdigit+\n bininteger ::= "0" ("b" | "B") bindigit+\n octdigit ::= "0"..."7"\n hexdigit ::= digit | "a"..."f" | "A"..."F"\n bindigit ::= "0" | "1"\n\nThere is no limit for the length of integer literals apart from what\ncan be stored in available memory.\n\nNote that leading zeros in a non-zero decimal number are not allowed.\nThis is for disambiguation with C-style octal literals, which Python\nused before version 3.0.\n\nSome examples of integer literals:\n\n 7 2147483647 0o177 0b100110111\n 3 79228162514264337593543950336 0o377 0x100000000\n 79228162514264337593543950336 0xdeadbeef\n', - 'lambda': '\nLambdas\n*******\n\n lambda_expr ::= "lambda" [parameter_list]: expression\n lambda_expr_nocond ::= "lambda" [parameter_list]: expression_nocond\n\nLambda expressions (sometimes called lambda forms) have the same\nsyntactic position as expressions. They are a shorthand to create\nanonymous functions; the expression ``lambda arguments: expression``\nyields a function object. The unnamed object behaves like a function\nobject defined with\n\n def (arguments):\n return expression\n\nSee section *Function definitions* for the syntax of parameter lists.\nNote that functions created with lambda expressions cannot contain\nstatements or annotations.\n', - 'lists': '\nList displays\n*************\n\nA list display is a possibly empty series of expressions enclosed in\nsquare brackets:\n\n list_display ::= "[" [expression_list | comprehension] "]"\n\nA list display yields a new list object, the contents being specified\nby either a list of expressions or a comprehension. When a comma-\nseparated list of expressions is supplied, its elements are evaluated\nfrom left to right and placed into the list object in that order.\nWhen a comprehension is supplied, the list is constructed from the\nelements resulting from the comprehension.\n', - 'naming': "\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the '**-c**' option) is a code block. The string argument passed\nto the built-in functions ``eval()`` and ``exec()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block's execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes comprehensions and generator\nexpressions since they are implemented using a function scope. This\nmeans that the following will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block's *environment*.\n\nIf a name is bound in a block, it is a local variable of that block,\nunless declared as ``nonlocal``. If a name is bound at the module\nlevel, it is a global variable. (The variables of the module code\nblock are local and global.) If a variable is used in a code block\nbut not defined there, it is a *free variable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or\nafter ``as`` in a ``with`` statement or ``except`` clause. The\n``import`` statement of the form ``from ... import *`` binds all names\ndefined in the imported module, except those beginning with an\nunderscore. This form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name).\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the ``global`` statement occurs within a block, all uses of the\nname specified in the statement refer to the binding of that name in\nthe top-level namespace. Names are resolved in the top-level\nnamespace by searching the global namespace, i.e. the namespace of the\nmodule containing the code block, and the builtins namespace, the\nnamespace of the module ``builtins``. The global namespace is\nsearched first. If the name is not found there, the builtins\nnamespace is searched. The global statement must precede all uses of\nthe name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module's dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``builtins``; when in any other module, ``__builtins__`` is an alias\nfor the dictionary of the ``builtins`` module itself.\n``__builtins__`` can be set to a user-created dictionary to create a\nweak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n``__builtins__``; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should ``import``\nthe ``builtins`` module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe ``global`` statement has the same scope as a name binding\noperation in the same block. If the nearest enclosing scope for a\nfree variable contains a global statement, the free variable is\ntreated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n=================================\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nThe ``eval()`` and ``exec()`` functions do not have access to the full\nenvironment for resolving names. Names may be resolved in the local\nand global namespaces of the caller. Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace. [1]\nThe ``exec()`` and ``eval()`` functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n", - 'nonlocal': '\nThe ``nonlocal`` statement\n**************************\n\n nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*\n\nThe ``nonlocal`` statement causes the listed identifiers to refer to\npreviously bound variables in the nearest enclosing scope. This is\nimportant because the default behavior for binding is to search the\nlocal namespace first. The statement allows encapsulated code to\nrebind variables outside of the local scope besides the global\n(module) scope.\n\nNames listed in a ``nonlocal`` statement, unlike to those listed in a\n``global`` statement, must refer to pre-existing bindings in an\nenclosing scope (the scope in which a new binding should be created\ncannot be determined unambiguously).\n\nNames listed in a ``nonlocal`` statement must not collide with pre-\nexisting bindings in the local scope.\n\nSee also:\n\n **PEP 3104** - Access to Names in Outer Scopes\n The specification for the ``nonlocal`` statement.\n', - 'numbers': "\nNumeric literals\n****************\n\nThere are three types of numeric literals: integers, floating point\nnumbers, and imaginary numbers. There are no complex literals\n(complex numbers can be formed by adding a real number and an\nimaginary number).\n\nNote that numeric literals do not include a sign; a phrase like ``-1``\nis actually an expression composed of the unary operator '``-``' and\nthe literal ``1``.\n", - 'numeric-types': "\nEmulating numeric types\n***********************\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__truediv__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``//``, ``%``,\n ``divmod()``, ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``,\n ``|``). For instance, to evaluate the expression ``x + y``, where\n *x* is an instance of a class that has an ``__add__()`` method,\n ``x.__add__(y)`` is called. The ``__divmod__()`` method should be\n the equivalent to using ``__floordiv__()`` and ``__mod__()``; it\n should not be related to ``__truediv__()``. Note that\n ``__pow__()`` should be defined to accept an optional third\n argument if the ternary version of the built-in ``pow()`` function\n is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return ``NotImplemented``.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``//``, ``%``,\n ``divmod()``, ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``,\n ``|``) with reflected (swapped) operands. These functions are only\n called if the left operand does not support the corresponding\n operation and the operands are of different types. [2] For\n instance, to evaluate the expression ``x - y``, where *y* is an\n instance of a class that has an ``__rsub__()`` method,\n ``y.__rsub__(x)`` is called if ``x.__sub__(y)`` returns\n *NotImplemented*.\n\n Note that ternary ``pow()`` will not try calling ``__rpow__()``\n (the coercion rules would become too complicated).\n\n Note: If the right operand's type is a subclass of the left operand's\n type and that subclass provides the reflected method for the\n operation, this method will be called before the left operand's\n non-reflected method. This behavior allows subclasses to\n override their ancestors' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n assignments (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\n ``**=``, ``<<=``, ``>>=``, ``&=``, ``^=``, ``|=``). These methods\n should attempt to do the operation in-place (modifying *self*) and\n return the result (which could be, but does not have to be,\n *self*). If a specific method is not defined, the augmented\n assignment falls back to the normal methods. For instance, to\n execute the statement ``x += y``, where *x* is an instance of a\n class that has an ``__iadd__()`` method, ``x.__iadd__(y)`` is\n called. If *x* is an instance of a class that does not define a\n ``__iadd__()`` method, ``x.__add__(y)`` and ``y.__radd__(x)`` are\n considered, as with the evaluation of ``x + y``.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations (``-``, ``+``,\n ``abs()`` and ``~``).\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__float__(self)\nobject.__round__(self[, n])\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``float()`` and ``round()``. Should return a value of\n the appropriate type.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing, or in the\n built-in ``bin()``, ``hex()`` and ``oct()`` functions). Must return\n an integer.\n", - 'objects': '\nObjects, values and types\n*************************\n\n*Objects* are Python\'s abstraction for data. All data in a Python\nprogram is represented by objects or by relations between objects. (In\na sense, and in conformance to Von Neumann\'s model of a "stored\nprogram computer," code is also represented by objects.)\n\nEvery object has an identity, a type and a value. An object\'s\n*identity* never changes once it has been created; you may think of it\nas the object\'s address in memory. The \'``is``\' operator compares the\nidentity of two objects; the ``id()`` function returns an integer\nrepresenting its identity.\n\n**CPython implementation detail:** For CPython, ``id(x)`` is the\nmemory address where ``x`` is stored.\n\nAn object\'s type determines the operations that the object supports\n(e.g., "does it have a length?") and also defines the possible values\nfor objects of that type. The ``type()`` function returns an object\'s\ntype (which is an object itself). Like its identity, an object\'s\n*type* is also unchangeable. [1]\n\nThe *value* of some objects can change. Objects whose value can\nchange are said to be *mutable*; objects whose value is unchangeable\nonce they are created are called *immutable*. (The value of an\nimmutable container object that contains a reference to a mutable\nobject can change when the latter\'s value is changed; however the\ncontainer is still considered immutable, because the collection of\nobjects it contains cannot be changed. So, immutability is not\nstrictly the same as having an unchangeable value, it is more subtle.)\nAn object\'s mutability is determined by its type; for instance,\nnumbers, strings and tuples are immutable, while dictionaries and\nlists are mutable.\n\nObjects are never explicitly destroyed; however, when they become\nunreachable they may be garbage-collected. An implementation is\nallowed to postpone garbage collection or omit it altogether --- it is\na matter of implementation quality how garbage collection is\nimplemented, as long as no objects are collected that are still\nreachable.\n\n**CPython implementation detail:** CPython currently uses a reference-\ncounting scheme with (optional) delayed detection of cyclically linked\ngarbage, which collects most objects as soon as they become\nunreachable, but is not guaranteed to collect garbage containing\ncircular references. See the documentation of the ``gc`` module for\ninformation on controlling the collection of cyclic garbage. Other\nimplementations act differently and CPython may change. Do not depend\non immediate finalization of objects when they become unreachable (ex:\nalways close files).\n\nNote that the use of the implementation\'s tracing or debugging\nfacilities may keep objects alive that would normally be collectable.\nAlso note that catching an exception with a \'``try``...``except``\'\nstatement may keep objects alive.\n\nSome objects contain references to "external" resources such as open\nfiles or windows. It is understood that these resources are freed\nwhen the object is garbage-collected, but since garbage collection is\nnot guaranteed to happen, such objects also provide an explicit way to\nrelease the external resource, usually a ``close()`` method. Programs\nare strongly recommended to explicitly close such objects. The\n\'``try``...``finally``\' statement and the \'``with``\' statement provide\nconvenient ways to do this.\n\nSome objects contain references to other objects; these are called\n*containers*. Examples of containers are tuples, lists and\ndictionaries. The references are part of a container\'s value. In\nmost cases, when we talk about the value of a container, we imply the\nvalues, not the identities of the contained objects; however, when we\ntalk about the mutability of a container, only the identities of the\nimmediately contained objects are implied. So, if an immutable\ncontainer (like a tuple) contains a reference to a mutable object, its\nvalue changes if that mutable object is changed.\n\nTypes affect almost all aspects of object behavior. Even the\nimportance of object identity is affected in some sense: for immutable\ntypes, operations that compute new values may actually return a\nreference to any existing object with the same type and value, while\nfor mutable objects this is not allowed. E.g., after ``a = 1; b =\n1``, ``a`` and ``b`` may or may not refer to the same object with the\nvalue one, depending on the implementation, but after ``c = []; d =\n[]``, ``c`` and ``d`` are guaranteed to refer to two different,\nunique, newly created empty lists. (Note that ``c = d = []`` assigns\nthe same object to both ``c`` and ``d``.)\n', - 'operator-summary': '\nOperator precedence\n*******************\n\nThe following table summarizes the operator precedences in Python,\nfrom lowest precedence (least binding) to highest precedence (most\nbinding). Operators in the same box have the same precedence. Unless\nthe syntax is explicitly given, operators are binary. Operators in\nthe same box group left to right (except for comparisons, including\ntests, which all have the same precedence and chain from left to right\n--- see section *Comparisons* --- and exponentiation, which groups\nfrom right to left).\n\n+-------------------------------------------------+---------------------------------------+\n| Operator | Description |\n+=================================================+=======================================+\n| ``lambda`` | Lambda expression |\n+-------------------------------------------------+---------------------------------------+\n| ``if`` -- ``else`` | Conditional expression |\n+-------------------------------------------------+---------------------------------------+\n| ``or`` | Boolean OR |\n+-------------------------------------------------+---------------------------------------+\n| ``and`` | Boolean AND |\n+-------------------------------------------------+---------------------------------------+\n| ``not`` ``x`` | Boolean NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``in``, ``not in``, ``is``, ``is not``, ``<``, | Comparisons, including membership |\n| ``<=``, ``>``, ``>=``, ``!=``, ``==`` | tests and identity tests |\n+-------------------------------------------------+---------------------------------------+\n| ``|`` | Bitwise OR |\n+-------------------------------------------------+---------------------------------------+\n| ``^`` | Bitwise XOR |\n+-------------------------------------------------+---------------------------------------+\n| ``&`` | Bitwise AND |\n+-------------------------------------------------+---------------------------------------+\n| ``<<``, ``>>`` | Shifts |\n+-------------------------------------------------+---------------------------------------+\n| ``+``, ``-`` | Addition and subtraction |\n+-------------------------------------------------+---------------------------------------+\n| ``*``, ``/``, ``//``, ``%`` | Multiplication, division, remainder |\n| | [5] |\n+-------------------------------------------------+---------------------------------------+\n| ``+x``, ``-x``, ``~x`` | Positive, negative, bitwise NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``**`` | Exponentiation [6] |\n+-------------------------------------------------+---------------------------------------+\n| ``x[index]``, ``x[index:index]``, | Subscription, slicing, call, |\n| ``x(arguments...)``, ``x.attribute`` | attribute reference |\n+-------------------------------------------------+---------------------------------------+\n| ``(expressions...)``, ``[expressions...]``, | Binding or tuple display, list |\n| ``{key: value...}``, ``{expressions...}`` | display, dictionary display, set |\n| | display |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] While ``abs(x%y) < abs(y)`` is true mathematically, for floats it\n may not be true numerically due to roundoff. For example, and\n assuming a platform on which a Python float is an IEEE 754 double-\n precision number, in order that ``-1e-100 % 1e100`` have the same\n sign as ``1e100``, the computed result is ``-1e-100 + 1e100``,\n which is numerically exactly equal to ``1e100``. The function\n ``math.fmod()`` returns a result whose sign matches the sign of\n the first argument instead, and so returns ``-1e-100`` in this\n case. Which approach is more appropriate depends on the\n application.\n\n[2] If x is very close to an exact integer multiple of y, it\'s\n possible for ``x//y`` to be one larger than ``(x-x%y)//y`` due to\n rounding. In such cases, Python returns the latter result, in\n order to preserve that ``divmod(x,y)[0] * y + x % y`` be very\n close to ``x``.\n\n[3] While comparisons between strings make sense at the byte level,\n they may be counter-intuitive to users. For example, the strings\n ``"\\u00C7"`` and ``"\\u0327\\u0043"`` compare differently, even\n though they both represent the same unicode character (LATIN\n CAPITAL LETTER C WITH CEDILLA). To compare strings in a human\n recognizable way, compare using ``unicodedata.normalize()``.\n\n[4] Due to automatic garbage-collection, free lists, and the dynamic\n nature of descriptors, you may notice seemingly unusual behaviour\n in certain uses of the ``is`` operator, like those involving\n comparisons between instance methods, or constants. Check their\n documentation for more info.\n\n[5] The ``%`` operator is also used for string formatting; the same\n precedence applies.\n\n[6] The power operator ``**`` binds less tightly than an arithmetic or\n bitwise unary operator on its right, that is, ``2**-1`` is\n ``0.5``.\n', - 'pass': '\nThe ``pass`` statement\n**********************\n\n pass_stmt ::= "pass"\n\n``pass`` is a null operation --- when it is executed, nothing happens.\nIt is useful as a placeholder when a statement is required\nsyntactically, but no code needs to be executed, for example:\n\n def f(arg): pass # a function that does nothing (yet)\n\n class C: pass # a class with no methods (yet)\n', - 'power': '\nThe power operator\n******************\n\nThe power operator binds more tightly than unary operators on its\nleft; it binds less tightly than unary operators on its right. The\nsyntax is:\n\n power ::= primary ["**" u_expr]\n\nThus, in an unparenthesized sequence of power and unary operators, the\noperators are evaluated from right to left (this does not constrain\nthe evaluation order for the operands): ``-1**2`` results in ``-1``.\n\nThe power operator has the same semantics as the built-in ``pow()``\nfunction, when called with two arguments: it yields its left argument\nraised to the power of its right argument. The numeric arguments are\nfirst converted to a common type, and the result is of that type.\n\nFor int operands, the result has the same type as the operands unless\nthe second argument is negative; in that case, all arguments are\nconverted to float and a float result is delivered. For example,\n``10**2`` returns ``100``, but ``10**-2`` returns ``0.01``.\n\nRaising ``0.0`` to a negative power results in a\n``ZeroDivisionError``. Raising a negative number to a fractional power\nresults in a ``complex`` number. (In earlier versions it raised a\n``ValueError``.)\n', - 'raise': '\nThe ``raise`` statement\n***********************\n\n raise_stmt ::= "raise" [expression ["from" expression]]\n\nIf no expressions are present, ``raise`` re-raises the last exception\nthat was active in the current scope. If no exception is active in\nthe current scope, a ``RuntimeError`` exception is raised indicating\nthat this is an error.\n\nOtherwise, ``raise`` evaluates the first expression as the exception\nobject. It must be either a subclass or an instance of\n``BaseException``. If it is a class, the exception instance will be\nobtained when needed by instantiating the class with no arguments.\n\nThe *type* of the exception is the exception instance\'s class, the\n*value* is the instance itself.\n\nA traceback object is normally created automatically when an exception\nis raised and attached to it as the ``__traceback__`` attribute, which\nis writable. You can create an exception and set your own traceback in\none step using the ``with_traceback()`` exception method (which\nreturns the same exception instance, with its traceback set to its\nargument), like so:\n\n raise Exception("foo occurred").with_traceback(tracebackobj)\n\nThe ``from`` clause is used for exception chaining: if given, the\nsecond *expression* must be another exception class or instance, which\nwill then be attached to the raised exception as the ``__cause__``\nattribute (which is writable). If the raised exception is not\nhandled, both exceptions will be printed:\n\n >>> try:\n ... print(1 / 0)\n ... except Exception as exc:\n ... raise RuntimeError("Something bad happened") from exc\n ...\n Traceback (most recent call last):\n File "", line 2, in \n ZeroDivisionError: int division or modulo by zero\n\n The above exception was the direct cause of the following exception:\n\n Traceback (most recent call last):\n File "", line 4, in \n RuntimeError: Something bad happened\n\nA similar mechanism works implicitly if an exception is raised inside\nan exception handler: the previous exception is then attached as the\nnew exception\'s ``__context__`` attribute:\n\n >>> try:\n ... print(1 / 0)\n ... except:\n ... raise RuntimeError("Something bad happened")\n ...\n Traceback (most recent call last):\n File "", line 2, in \n ZeroDivisionError: int division or modulo by zero\n\n During handling of the above exception, another exception occurred:\n\n Traceback (most recent call last):\n File "", line 4, in \n RuntimeError: Something bad happened\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information about handling exceptions is in section\n*The try statement*.\n', - 'return': '\nThe ``return`` statement\n************************\n\n return_stmt ::= "return" [expression_list]\n\n``return`` may only occur syntactically nested in a function\ndefinition, not within a nested class definition.\n\nIf an expression list is present, it is evaluated, else ``None`` is\nsubstituted.\n\n``return`` leaves the current function call with the expression list\n(or ``None``) as return value.\n\nWhen ``return`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nleaving the function.\n\nIn a generator function, the ``return`` statement indicates that the\ngenerator is done and will cause ``StopIteration`` to be raised. The\nreturned value (if any) is used as an argument to construct\n``StopIteration`` and becomes the ``StopIteration.value`` attribute.\n', - 'sequence-types': "\nEmulating container types\n*************************\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which ``0 <= k < N``\nwhere *N* is the length of the sequence, or slice objects, which\ndefine a range of items. It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``get()``,\n``clear()``, ``setdefault()``, ``pop()``, ``popitem()``, ``copy()``,\nand ``update()`` behaving similar to those for Python's standard\ndictionary objects. The ``collections`` module provides a\n``MutableMapping`` abstract base class to help create those methods\nfrom a base set of ``__getitem__()``, ``__setitem__()``,\n``__delitem__()``, and ``keys()``. Mutable sequences should provide\nmethods ``append()``, ``count()``, ``index()``, ``extend()``,\n``insert()``, ``pop()``, ``remove()``, ``reverse()`` and ``sort()``,\nlike Python standard list objects. Finally, sequence types should\nimplement addition (meaning concatenation) and multiplication (meaning\nrepetition) by defining the methods ``__add__()``, ``__radd__()``,\n``__iadd__()``, ``__mul__()``, ``__rmul__()`` and ``__imul__()``\ndescribed below; they should not define other numerical operators. It\nis recommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should search the mapping's keys; for\nsequences, it should search through the values. It is further\nrecommended that both mappings and sequences implement the\n``__iter__()`` method to allow efficient iteration through the\ncontainer; for mappings, ``__iter__()`` should be the same as\n``keys()``; for sequences, it should iterate through the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function ``len()``. Should return\n the length of the object, an integer ``>=`` 0. Also, an object\n that doesn't define a ``__bool__()`` method and whose ``__len__()``\n method returns zero is considered to be false in a Boolean context.\n\nobject.__length_hint__(self)\n\n Called to implement ``operator.length_hint()``. Should return an\n estimated length for the object (which may be greater or less than\n the actual length). The length must be an integer ``>=`` 0. This\n method is purely an optimization and is never required for\n correctness.\n\n New in version 3.4.\n\nNote: Slicing is done exclusively with the following three methods. A\n call like\n\n a[1:2] = b\n\n is translated to\n\n a[slice(1, 2, None)] = b\n\n and so forth. Missing slice items are always filled in with\n ``None``.\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of ``self[key]``. For sequence\n types, the accepted keys should be integers and slice objects.\n Note that the special interpretation of negative indexes (if the\n class wishes to emulate a sequence type) is up to the\n ``__getitem__()`` method. If *key* is of an inappropriate type,\n ``TypeError`` may be raised; if of a value outside the set of\n indexes for the sequence (after any special interpretation of\n negative values), ``IndexError`` should be raised. For mapping\n types, if *key* is missing (not in the container), ``KeyError``\n should be raised.\n\n Note: ``for`` loops expect that an ``IndexError`` will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the ``__getitem__()`` method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the ``__getitem__()``\n method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container, and should also be made\n available as the method ``keys()``.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the ``reversed()`` built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the ``__reversed__()`` method is not provided, the\n ``reversed()`` built-in will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects that\n support the sequence protocol should only provide\n ``__reversed__()`` if they can provide an implementation that is\n more efficient than the one provided by ``reversed()``.\n\nThe membership test operators (``in`` and ``not in``) are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n For objects that don't define ``__contains__()``, the membership\n test first tries iteration via ``__iter__()``, then the old\n sequence iteration protocol via ``__getitem__()``, see *this\n section in the language reference*.\n", - 'shifting': '\nShifting operations\n*******************\n\nThe shifting operations have lower priority than the arithmetic\noperations:\n\n shift_expr ::= a_expr | shift_expr ( "<<" | ">>" ) a_expr\n\nThese operators accept integers as arguments. They shift the first\nargument to the left or right by the number of bits given by the\nsecond argument.\n\nA right shift by *n* bits is defined as floor division by\n``pow(2,n)``. A left shift by *n* bits is defined as multiplication\nwith ``pow(2,n)``.\n\nNote: In the current implementation, the right-hand operand is required to\n be at most ``sys.maxsize``. If the right-hand operand is larger\n than ``sys.maxsize`` an ``OverflowError`` exception is raised.\n', - 'slicings': '\nSlicings\n********\n\nA slicing selects a range of items in a sequence object (e.g., a\nstring, tuple or list). Slicings may be used as expressions or as\ntargets in assignment or ``del`` statements. The syntax for a\nslicing:\n\n slicing ::= primary "[" slice_list "]"\n slice_list ::= slice_item ("," slice_item)* [","]\n slice_item ::= expression | proper_slice\n proper_slice ::= [lower_bound] ":" [upper_bound] [ ":" [stride] ]\n lower_bound ::= expression\n upper_bound ::= expression\n stride ::= expression\n\nThere is ambiguity in the formal syntax here: anything that looks like\nan expression list also looks like a slice list, so any subscription\ncan be interpreted as a slicing. Rather than further complicating the\nsyntax, this is disambiguated by defining that in this case the\ninterpretation as a subscription takes priority over the\ninterpretation as a slicing (this is the case if the slice list\ncontains no proper slice).\n\nThe semantics for a slicing are as follows. The primary must evaluate\nto a mapping object, and it is indexed (using the same\n``__getitem__()`` method as normal subscription) with a key that is\nconstructed from the slice list, as follows. If the slice list\ncontains at least one comma, the key is a tuple containing the\nconversion of the slice items; otherwise, the conversion of the lone\nslice item is the key. The conversion of a slice item that is an\nexpression is that expression. The conversion of a proper slice is a\nslice object (see section *The standard type hierarchy*) whose\n``start``, ``stop`` and ``step`` attributes are the values of the\nexpressions given as lower bound, upper bound and stride,\nrespectively, substituting ``None`` for missing expressions.\n', - 'specialattrs': '\nSpecial Attributes\n******************\n\nThe implementation adds a few special read-only attributes to several\nobject types, where they are relevant. Some of these are not reported\nby the ``dir()`` built-in function.\n\nobject.__dict__\n\n A dictionary or other mapping object used to store an object\'s\n (writable) attributes.\n\ninstance.__class__\n\n The class to which a class instance belongs.\n\nclass.__bases__\n\n The tuple of base classes of a class object.\n\nclass.__name__\n\n The name of the class or type.\n\nclass.__qualname__\n\n The *qualified name* of the class or type.\n\n New in version 3.3.\n\nclass.__mro__\n\n This attribute is a tuple of classes that are considered when\n looking for base classes during method resolution.\n\nclass.mro()\n\n This method can be overridden by a metaclass to customize the\n method resolution order for its instances. It is called at class\n instantiation, and its result is stored in ``__mro__``.\n\nclass.__subclasses__()\n\n Each class keeps a list of weak references to its immediate\n subclasses. This method returns a list of all those references\n still alive. Example:\n\n >>> int.__subclasses__()\n []\n\n-[ Footnotes ]-\n\n[1] Additional information on these special methods may be found in\n the Python Reference Manual (*Basic customization*).\n\n[2] As a consequence, the list ``[1, 2]`` is considered equal to\n ``[1.0, 2.0]``, and similarly for tuples.\n\n[3] They must have since the parser can\'t tell the type of the\n operands.\n\n[4] Cased characters are those with general category property being\n one of "Lu" (Letter, uppercase), "Ll" (Letter, lowercase), or "Lt"\n (Letter, titlecase).\n\n[5] To format only a tuple you should therefore provide a singleton\n tuple whose only element is the tuple to be formatted.\n', - 'specialnames': '\nSpecial method names\n********************\n\nA class can implement certain operations that are invoked by special\nsyntax (such as arithmetic operations or subscripting and slicing) by\ndefining methods with special names. This is Python\'s approach to\n*operator overloading*, allowing classes to define their own behavior\nwith respect to language operators. For instance, if a class defines\na method named ``__getitem__()``, and ``x`` is an instance of this\nclass, then ``x[i]`` is roughly equivalent to ``type(x).__getitem__(x,\ni)``. Except where mentioned, attempts to execute an operation raise\nan exception when no appropriate method is defined (typically\n``AttributeError`` or ``TypeError``).\n\nWhen implementing a class that emulates any built-in type, it is\nimportant that the emulation only be implemented to the degree that it\nmakes sense for the object being modelled. For example, some\nsequences may work well with retrieval of individual elements, but\nextracting a slice may not make sense. (One example of this is the\n``NodeList`` interface in the W3C\'s Document Object Model.)\n\n\nBasic customization\n===================\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. ``__new__()`` is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of ``__new__()`` should be the new object instance (usually\n an instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s ``__new__()`` method using\n ``super(currentclass, cls).__new__(cls[, ...])`` with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If ``__new__()`` returns an instance of *cls*, then the new\n instance\'s ``__init__()`` method will be invoked like\n ``__init__(self[, ...])``, where *self* is the new instance and the\n remaining arguments are the same as were passed to ``__new__()``.\n\n If ``__new__()`` does not return an instance of *cls*, then the new\n instance\'s ``__init__()`` method will not be invoked.\n\n ``__new__()`` is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called when the instance is created. The arguments are those\n passed to the class constructor expression. If a base class has an\n ``__init__()`` method, the derived class\'s ``__init__()`` method,\n if any, must explicitly call it to ensure proper initialization of\n the base class part of the instance; for example:\n ``BaseClass.__init__(self, [args...])``. As a special constraint\n on constructors, no value may be returned; doing so will cause a\n ``TypeError`` to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a ``__del__()`` method,\n the derived class\'s ``__del__()`` method, if any, must explicitly\n call it to ensure proper deletion of the base class part of the\n instance. Note that it is possible (though not recommended!) for\n the ``__del__()`` method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n ``__del__()`` methods are called for objects that still exist when\n the interpreter exits.\n\n Note: ``del x`` doesn\'t directly call ``x.__del__()`` --- the former\n decrements the reference count for ``x`` by one, and the latter\n is only called when ``x``\'s reference count reaches zero. Some\n common situations that may prevent the reference count of an\n object from going to zero include: circular references between\n objects (e.g., a doubly-linked list or a tree data structure with\n parent and child pointers); a reference to the object on the\n stack frame of a function that caught an exception (the traceback\n stored in ``sys.exc_info()[2]`` keeps the stack frame alive); or\n a reference to the object on the stack frame that raised an\n unhandled exception in interactive mode (the traceback stored in\n ``sys.last_traceback`` keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the latter two situations can be resolved by storing ``None`` in\n ``sys.last_traceback``. Circular references which are garbage are\n detected and cleaned up when the cyclic garbage collector is\n enabled (it\'s on by default). Refer to the documentation for the\n ``gc`` module for more information about this topic.\n\n Warning: Due to the precarious circumstances under which ``__del__()``\n methods are invoked, exceptions that occur during their execution\n are ignored, and a warning is printed to ``sys.stderr`` instead.\n Also, when ``__del__()`` is invoked in response to a module being\n deleted (e.g., when execution of the program is done), other\n globals referenced by the ``__del__()`` method may already have\n been deleted or in the process of being torn down (e.g. the\n import machinery shutting down). For this reason, ``__del__()``\n methods should do the absolute minimum needed to maintain\n external invariants. Starting with version 1.5, Python\n guarantees that globals whose name begins with a single\n underscore are deleted from their module before other globals are\n deleted; if no other references to such globals exist, this may\n help in assuring that imported modules are still available at the\n time when the ``__del__()`` method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function to compute the\n "official" string representation of an object. If at all possible,\n this should look like a valid Python expression that could be used\n to recreate an object with the same value (given an appropriate\n environment). If this is not possible, a string of the form\n ``<...some useful description...>`` should be returned. The return\n value must be a string object. If a class defines ``__repr__()``\n but not ``__str__()``, then ``__repr__()`` is also used when an\n "informal" string representation of instances of that class is\n required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by ``str(object)`` and the built-in functions ``format()``\n and ``print()`` to compute the "informal" or nicely printable\n string representation of an object. The return value must be a\n *string* object.\n\n This method differs from ``object.__repr__()`` in that there is no\n expectation that ``__str__()`` return a valid Python expression: a\n more convenient or concise representation can be used.\n\n The default implementation defined by the built-in type ``object``\n calls ``object.__repr__()``.\n\nobject.__bytes__(self)\n\n Called by ``bytes()`` to compute a byte-string representation of an\n object. This should return a ``bytes`` object.\n\nobject.__format__(self, format_spec)\n\n Called by the ``format()`` built-in function (and by extension, the\n ``str.format()`` method of class ``str``) to produce a "formatted"\n string representation of an object. The ``format_spec`` argument is\n a string that contains a description of the formatting options\n desired. The interpretation of the ``format_spec`` argument is up\n to the type implementing ``__format__()``, however most classes\n will either delegate formatting to one of the built-in types, or\n use a similar formatting option syntax.\n\n See *Format Specification Mini-Language* for a description of the\n standard formatting syntax.\n\n The return value must be a string object.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n These are the so-called "rich comparison" methods. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` calls ``x.__gt__(y)``, and ``x>=y`` calls\n ``x.__ge__(y)``.\n\n A rich comparison method may return the singleton\n ``NotImplemented`` if it does not implement the operation for a\n given pair of arguments. By convention, ``False`` and ``True`` are\n returned for a successful comparison. However, these methods can\n return any value, so if the comparison operator is used in a\n Boolean context (e.g., in the condition of an ``if`` statement),\n Python will call ``bool()`` on the value to determine if the result\n is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of ``x==y`` does not imply that ``x!=y`` is false.\n Accordingly, when defining ``__eq__()``, one should also define\n ``__ne__()`` so that the operators will behave as expected. See\n the paragraph on ``__hash__()`` for some important notes on\n creating *hashable* objects which support custom comparison\n operations and are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, ``__lt__()`` and ``__gt__()`` are each\n other\'s reflection, ``__le__()`` and ``__ge__()`` are each other\'s\n reflection, and ``__eq__()`` and ``__ne__()`` are their own\n reflection.\n\n Arguments to rich comparison methods are never coerced.\n\n To automatically generate ordering operations from a single root\n operation, see ``functools.total_ordering()``.\n\nobject.__hash__(self)\n\n Called by built-in function ``hash()`` and for operations on\n members of hashed collections including ``set``, ``frozenset``, and\n ``dict``. ``__hash__()`` should return an integer. The only\n required property is that objects which compare equal have the same\n hash value; it is advised to somehow mix together (e.g. using\n exclusive or) the hash values for the components of the object that\n also play a part in comparison of objects.\n\n Note: ``hash()`` truncates the value returned from an object\'s custom\n ``__hash__()`` method to the size of a ``Py_ssize_t``. This is\n typically 8 bytes on 64-bit builds and 4 bytes on 32-bit builds.\n If an object\'s ``__hash__()`` must interoperate on builds of\n different bit sizes, be sure to check the width on all supported\n builds. An easy way to do this is with ``python -c "import sys;\n print(sys.hash_info.width)"``\n\n If a class does not define an ``__eq__()`` method it should not\n define a ``__hash__()`` operation either; if it defines\n ``__eq__()`` but not ``__hash__()``, its instances will not be\n usable as items in hashable collections. If a class defines\n mutable objects and implements an ``__eq__()`` method, it should\n not implement ``__hash__()``, since the implementation of hashable\n collections requires that a key\'s hash value is immutable (if the\n object\'s hash value changes, it will be in the wrong hash bucket).\n\n User-defined classes have ``__eq__()`` and ``__hash__()`` methods\n by default; with them, all objects compare unequal (except with\n themselves) and ``x.__hash__()`` returns an appropriate value such\n that ``x == y`` implies both that ``x is y`` and ``hash(x) ==\n hash(y)``.\n\n A class that overrides ``__eq__()`` and does not define\n ``__hash__()`` will have its ``__hash__()`` implicitly set to\n ``None``. When the ``__hash__()`` method of a class is ``None``,\n instances of the class will raise an appropriate ``TypeError`` when\n a program attempts to retrieve their hash value, and will also be\n correctly identified as unhashable when checking ``isinstance(obj,\n collections.Hashable``).\n\n If a class that overrides ``__eq__()`` needs to retain the\n implementation of ``__hash__()`` from a parent class, the\n interpreter must be told this explicitly by setting ``__hash__ =\n .__hash__``.\n\n If a class that does not override ``__eq__()`` wishes to suppress\n hash support, it should include ``__hash__ = None`` in the class\n definition. A class which defines its own ``__hash__()`` that\n explicitly raises a ``TypeError`` would be incorrectly identified\n as hashable by an ``isinstance(obj, collections.Hashable)`` call.\n\n Note: By default, the ``__hash__()`` values of str, bytes and datetime\n objects are "salted" with an unpredictable random value.\n Although they remain constant within an individual Python\n process, they are not predictable between repeated invocations of\n Python.This is intended to provide protection against a denial-\n of-service caused by carefully-chosen inputs that exploit the\n worst case performance of a dict insertion, O(n^2) complexity.\n See http://www.ocert.org/advisories/ocert-2011-003.html for\n details.Changing hash values affects the iteration order of\n dicts, sets and other mappings. Python has never made guarantees\n about this ordering (and it typically varies between 32-bit and\n 64-bit builds).See also ``PYTHONHASHSEED``.\n\n Changed in version 3.3: Hash randomization is enabled by default.\n\nobject.__bool__(self)\n\n Called to implement truth value testing and the built-in operation\n ``bool()``; should return ``False`` or ``True``. When this method\n is not defined, ``__len__()`` is called, if it is defined, and the\n object is considered true if its result is nonzero. If a class\n defines neither ``__len__()`` nor ``__bool__()``, all its instances\n are considered true.\n\n\nCustomizing attribute access\n============================\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of ``x.name``)\nfor class instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for ``self``). ``name`` is the attribute name.\n This method should return the (computed) attribute value or raise\n an ``AttributeError`` exception.\n\n Note that if the attribute is found through the normal mechanism,\n ``__getattr__()`` is not called. (This is an intentional asymmetry\n between ``__getattr__()`` and ``__setattr__()``.) This is done both\n for efficiency reasons and because otherwise ``__getattr__()``\n would have no way to access other attributes of the instance. Note\n that at least for instance variables, you can fake total control by\n not inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n ``__getattribute__()`` method below for a way to actually get total\n control over attribute access.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines\n ``__getattr__()``, the latter will not be called unless\n ``__getattribute__()`` either calls it explicitly or raises an\n ``AttributeError``. This method should return the (computed)\n attribute value or raise an ``AttributeError`` exception. In order\n to avoid infinite recursion in this method, its implementation\n should always call the base class method with the same name to\n access any attributes it needs, for example,\n ``object.__getattribute__(self, name)``.\n\n Note: This method may still be bypassed when looking up special methods\n as the result of implicit invocation via language syntax or\n built-in functions. See *Special method lookup*.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If ``__setattr__()`` wants to assign to an instance attribute, it\n should call the base class method with the same name, for example,\n ``object.__setattr__(self, name, value)``.\n\nobject.__delattr__(self, name)\n\n Like ``__setattr__()`` but for attribute deletion instead of\n assignment. This should only be implemented if ``del obj.name`` is\n meaningful for the object.\n\nobject.__dir__(self)\n\n Called when ``dir()`` is called on the object. A sequence must be\n returned. ``dir()`` converts the returned sequence to a list and\n sorts it.\n\n\nImplementing Descriptors\n------------------------\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in an\n*owner* class (the descriptor must be in either the owner\'s class\ndictionary or in the class dictionary for one of its parents). In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' ``__dict__``.\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or ``None`` when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an\n ``AttributeError`` exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\n\nInvoking Descriptors\n--------------------\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: ``__get__()``, ``__set__()``, and\n``__delete__()``. If any of those methods are defined for an object,\nit is said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, ``a.x`` has a\nlookup chain starting with ``a.__dict__[\'x\']``, then\n``type(a).__dict__[\'x\']``, and continuing through the base classes of\n``type(a)`` excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called.\n\nThe starting point for descriptor invocation is a binding, ``a.x``.\nHow the arguments are assembled depends on ``a``:\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: ``x.__get__(a)``.\n\nInstance Binding\n If binding to an object instance, ``a.x`` is transformed into the\n call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a class, ``A.x`` is transformed into the call:\n ``A.__dict__[\'x\'].__get__(None, A)``.\n\nSuper Binding\n If ``a`` is an instance of ``super``, then the binding ``super(B,\n obj).m()`` searches ``obj.__class__.__mro__`` for the base class\n ``A`` immediately preceding ``B`` and then invokes the descriptor\n with the call: ``A.__dict__[\'m\'].__get__(obj, obj.__class__)``.\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of ``__get__()``, ``__set__()`` and ``__delete__()``.\nIf it does not define ``__get__()``, then accessing the attribute will\nreturn the descriptor object itself unless there is a value in the\nobject\'s instance dictionary. If the descriptor defines ``__set__()``\nand/or ``__delete__()``, it is a data descriptor; if it defines\nneither, it is a non-data descriptor. Normally, data descriptors\ndefine both ``__get__()`` and ``__set__()``, while non-data\ndescriptors have just the ``__get__()`` method. Data descriptors with\n``__set__()`` and ``__get__()`` defined always override a redefinition\nin an instance dictionary. In contrast, non-data descriptors can be\noverridden by instances.\n\nPython methods (including ``staticmethod()`` and ``classmethod()``)\nare implemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe ``property()`` function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n---------\n\nBy default, instances of classes have a dictionary for attribute\nstorage. This wastes space for objects having very few instance\nvariables. The space consumption can become acute when creating large\nnumbers of instances.\n\nThe default can be overridden by defining *__slots__* in a class\ndefinition. The *__slots__* declaration takes a sequence of instance\nvariables and reserves just enough space in each instance to hold a\nvalue for each variable. Space is saved because *__dict__* is not\ncreated for each instance.\n\nobject.__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. If defined in a\n class, *__slots__* reserves space for the declared variables and\n prevents the automatic creation of *__dict__* and *__weakref__* for\n each instance.\n\n\nNotes on using *__slots__*\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises ``AttributeError``. If\n dynamic assignment of new variables is desired, then add\n ``\'__dict__\'`` to the sequence of strings in the *__slots__*\n declaration.\n\n* Without a *__weakref__* variable for each instance, classes defining\n *__slots__* do not support weak references to its instances. If weak\n reference support is needed, then add ``\'__weakref__\'`` to the\n sequence of strings in the *__slots__* declaration.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the instance\n variable defined by the base class slot is inaccessible (except by\n retrieving its descriptor directly from the base class). This\n renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as ``int``, ``str`` and\n ``tuple``.\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings may\n also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, classes are constructed using ``type()``. The class body\nis executed in a new namespace and the class name is bound locally to\nthe result of ``type(name, bases, namespace)``.\n\nThe class creation process can be customised by passing the\n``metaclass`` keyword argument in the class definition line, or by\ninheriting from an existing class that included such an argument. In\nthe following example, both ``MyClass`` and ``MySubclass`` are\ninstances of ``Meta``:\n\n class Meta(type):\n pass\n\n class MyClass(metaclass=Meta):\n pass\n\n class MySubclass(MyClass):\n pass\n\nAny other keyword arguments that are specified in the class definition\nare passed through to all metaclass operations described below.\n\nWhen a class definition is executed, the following steps occur:\n\n* the appropriate metaclass is determined\n\n* the class namespace is prepared\n\n* the class body is executed\n\n* the class object is created\n\n\nDetermining the appropriate metaclass\n-------------------------------------\n\nThe appropriate metaclass for a class definition is determined as\nfollows:\n\n* if no bases and no explicit metaclass are given, then ``type()`` is\n used\n\n* if an explicit metaclass is given and it is *not* an instance of\n ``type()``, then it is used directly as the metaclass\n\n* if an instance of ``type()`` is given as the explicit metaclass, or\n bases are defined, then the most derived metaclass is used\n\nThe most derived metaclass is selected from the explicitly specified\nmetaclass (if any) and the metaclasses (i.e. ``type(cls)``) of all\nspecified base classes. The most derived metaclass is one which is a\nsubtype of *all* of these candidate metaclasses. If none of the\ncandidate metaclasses meets that criterion, then the class definition\nwill fail with ``TypeError``.\n\n\nPreparing the class namespace\n-----------------------------\n\nOnce the appropriate metaclass has been identified, then the class\nnamespace is prepared. If the metaclass has a ``__prepare__``\nattribute, it is called as ``namespace = metaclass.__prepare__(name,\nbases, **kwds)`` (where the additional keyword arguments, if any, come\nfrom the class definition).\n\nIf the metaclass has no ``__prepare__`` attribute, then the class\nnamespace is initialised as an empty ``dict()`` instance.\n\nSee also:\n\n **PEP 3115** - Metaclasses in Python 3000\n Introduced the ``__prepare__`` namespace hook\n\n\nExecuting the class body\n------------------------\n\nThe class body is executed (approximately) as ``exec(body, globals(),\nnamespace)``. The key difference from a normal call to ``exec()`` is\nthat lexical scoping allows the class body (including any methods) to\nreference names from the current and outer scopes when the class\ndefinition occurs inside a function.\n\nHowever, even when the class definition occurs inside the function,\nmethods defined inside the class still cannot see names defined at the\nclass scope. Class variables must be accessed through the first\nparameter of instance or class methods, and cannot be accessed at all\nfrom static methods.\n\n\nCreating the class object\n-------------------------\n\nOnce the class namespace has been populated by executing the class\nbody, the class object is created by calling ``metaclass(name, bases,\nnamespace, **kwds)`` (the additional keywords passed here are the same\nas those passed to ``__prepare__``).\n\nThis class object is the one that will be referenced by the zero-\nargument form of ``super()``. ``__class__`` is an implicit closure\nreference created by the compiler if any methods in a class body refer\nto either ``__class__`` or ``super``. This allows the zero argument\nform of ``super()`` to correctly identify the class being defined\nbased on lexical scoping, while the class or instance that was used to\nmake the current call is identified based on the first argument passed\nto the method.\n\nAfter the class object is created, it is passed to the class\ndecorators included in the class definition (if any) and the resulting\nobject is bound in the local namespace as the defined class.\n\nSee also:\n\n **PEP 3135** - New super\n Describes the implicit ``__class__`` closure reference\n\n\nMetaclass example\n-----------------\n\nThe potential uses for metaclasses are boundless. Some ideas that have\nbeen explored include logging, interface checking, automatic\ndelegation, automatic property creation, proxies, frameworks, and\nautomatic resource locking/synchronization.\n\nHere is an example of a metaclass that uses an\n``collections.OrderedDict`` to remember the order that class members\nwere defined:\n\n class OrderedClass(type):\n\n @classmethod\n def __prepare__(metacls, name, bases, **kwds):\n return collections.OrderedDict()\n\n def __new__(cls, name, bases, namespace, **kwds):\n result = type.__new__(cls, name, bases, dict(namespace))\n result.members = tuple(namespace)\n return result\n\n class A(metaclass=OrderedClass):\n def one(self): pass\n def two(self): pass\n def three(self): pass\n def four(self): pass\n\n >>> A.members\n (\'__module__\', \'one\', \'two\', \'three\', \'four\')\n\nWhen the class definition for *A* gets executed, the process begins\nwith calling the metaclass\'s ``__prepare__()`` method which returns an\nempty ``collections.OrderedDict``. That mapping records the methods\nand attributes of *A* as they are defined within the body of the class\nstatement. Once those definitions are executed, the ordered dictionary\nis fully populated and the metaclass\'s ``__new__()`` method gets\ninvoked. That method builds the new type and it saves the ordered\ndictionary keys in an attribute called ``members``.\n\n\nCustomizing instance and subclass checks\n========================================\n\nThe following methods are used to override the default behavior of the\n``isinstance()`` and ``issubclass()`` built-in functions.\n\nIn particular, the metaclass ``abc.ABCMeta`` implements these methods\nin order to allow the addition of Abstract Base Classes (ABCs) as\n"virtual base classes" to any class or type (including built-in\ntypes), including other ABCs.\n\nclass.__instancecheck__(self, instance)\n\n Return true if *instance* should be considered a (direct or\n indirect) instance of *class*. If defined, called to implement\n ``isinstance(instance, class)``.\n\nclass.__subclasscheck__(self, subclass)\n\n Return true if *subclass* should be considered a (direct or\n indirect) subclass of *class*. If defined, called to implement\n ``issubclass(subclass, class)``.\n\nNote that these methods are looked up on the type (metaclass) of a\nclass. They cannot be defined as class methods in the actual class.\nThis is consistent with the lookup of special methods that are called\non instances, only in this case the instance is itself a class.\n\nSee also:\n\n **PEP 3119** - Introducing Abstract Base Classes\n Includes the specification for customizing ``isinstance()`` and\n ``issubclass()`` behavior through ``__instancecheck__()`` and\n ``__subclasscheck__()``, with motivation for this functionality\n in the context of adding Abstract Base Classes (see the ``abc``\n module) to the language.\n\n\nEmulating callable objects\n==========================\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, ``x(arg1, arg2, ...)`` is a shorthand for\n ``x.__call__(arg1, arg2, ...)``.\n\n\nEmulating container types\n=========================\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which ``0 <= k < N``\nwhere *N* is the length of the sequence, or slice objects, which\ndefine a range of items. It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``get()``,\n``clear()``, ``setdefault()``, ``pop()``, ``popitem()``, ``copy()``,\nand ``update()`` behaving similar to those for Python\'s standard\ndictionary objects. The ``collections`` module provides a\n``MutableMapping`` abstract base class to help create those methods\nfrom a base set of ``__getitem__()``, ``__setitem__()``,\n``__delitem__()``, and ``keys()``. Mutable sequences should provide\nmethods ``append()``, ``count()``, ``index()``, ``extend()``,\n``insert()``, ``pop()``, ``remove()``, ``reverse()`` and ``sort()``,\nlike Python standard list objects. Finally, sequence types should\nimplement addition (meaning concatenation) and multiplication (meaning\nrepetition) by defining the methods ``__add__()``, ``__radd__()``,\n``__iadd__()``, ``__mul__()``, ``__rmul__()`` and ``__imul__()``\ndescribed below; they should not define other numerical operators. It\nis recommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should search the mapping\'s keys; for\nsequences, it should search through the values. It is further\nrecommended that both mappings and sequences implement the\n``__iter__()`` method to allow efficient iteration through the\ncontainer; for mappings, ``__iter__()`` should be the same as\n``keys()``; for sequences, it should iterate through the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function ``len()``. Should return\n the length of the object, an integer ``>=`` 0. Also, an object\n that doesn\'t define a ``__bool__()`` method and whose ``__len__()``\n method returns zero is considered to be false in a Boolean context.\n\nobject.__length_hint__(self)\n\n Called to implement ``operator.length_hint()``. Should return an\n estimated length for the object (which may be greater or less than\n the actual length). The length must be an integer ``>=`` 0. This\n method is purely an optimization and is never required for\n correctness.\n\n New in version 3.4.\n\nNote: Slicing is done exclusively with the following three methods. A\n call like\n\n a[1:2] = b\n\n is translated to\n\n a[slice(1, 2, None)] = b\n\n and so forth. Missing slice items are always filled in with\n ``None``.\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of ``self[key]``. For sequence\n types, the accepted keys should be integers and slice objects.\n Note that the special interpretation of negative indexes (if the\n class wishes to emulate a sequence type) is up to the\n ``__getitem__()`` method. If *key* is of an inappropriate type,\n ``TypeError`` may be raised; if of a value outside the set of\n indexes for the sequence (after any special interpretation of\n negative values), ``IndexError`` should be raised. For mapping\n types, if *key* is missing (not in the container), ``KeyError``\n should be raised.\n\n Note: ``for`` loops expect that an ``IndexError`` will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the ``__getitem__()`` method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the ``__getitem__()``\n method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container, and should also be made\n available as the method ``keys()``.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the ``reversed()`` built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the ``__reversed__()`` method is not provided, the\n ``reversed()`` built-in will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects that\n support the sequence protocol should only provide\n ``__reversed__()`` if they can provide an implementation that is\n more efficient than the one provided by ``reversed()``.\n\nThe membership test operators (``in`` and ``not in``) are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n For objects that don\'t define ``__contains__()``, the membership\n test first tries iteration via ``__iter__()``, then the old\n sequence iteration protocol via ``__getitem__()``, see *this\n section in the language reference*.\n\n\nEmulating numeric types\n=======================\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__truediv__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``//``, ``%``,\n ``divmod()``, ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``,\n ``|``). For instance, to evaluate the expression ``x + y``, where\n *x* is an instance of a class that has an ``__add__()`` method,\n ``x.__add__(y)`` is called. The ``__divmod__()`` method should be\n the equivalent to using ``__floordiv__()`` and ``__mod__()``; it\n should not be related to ``__truediv__()``. Note that\n ``__pow__()`` should be defined to accept an optional third\n argument if the ternary version of the built-in ``pow()`` function\n is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return ``NotImplemented``.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``//``, ``%``,\n ``divmod()``, ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``,\n ``|``) with reflected (swapped) operands. These functions are only\n called if the left operand does not support the corresponding\n operation and the operands are of different types. [2] For\n instance, to evaluate the expression ``x - y``, where *y* is an\n instance of a class that has an ``__rsub__()`` method,\n ``y.__rsub__(x)`` is called if ``x.__sub__(y)`` returns\n *NotImplemented*.\n\n Note that ternary ``pow()`` will not try calling ``__rpow__()``\n (the coercion rules would become too complicated).\n\n Note: If the right operand\'s type is a subclass of the left operand\'s\n type and that subclass provides the reflected method for the\n operation, this method will be called before the left operand\'s\n non-reflected method. This behavior allows subclasses to\n override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n assignments (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\n ``**=``, ``<<=``, ``>>=``, ``&=``, ``^=``, ``|=``). These methods\n should attempt to do the operation in-place (modifying *self*) and\n return the result (which could be, but does not have to be,\n *self*). If a specific method is not defined, the augmented\n assignment falls back to the normal methods. For instance, to\n execute the statement ``x += y``, where *x* is an instance of a\n class that has an ``__iadd__()`` method, ``x.__iadd__(y)`` is\n called. If *x* is an instance of a class that does not define a\n ``__iadd__()`` method, ``x.__add__(y)`` and ``y.__radd__(x)`` are\n considered, as with the evaluation of ``x + y``.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations (``-``, ``+``,\n ``abs()`` and ``~``).\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__float__(self)\nobject.__round__(self[, n])\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``float()`` and ``round()``. Should return a value of\n the appropriate type.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing, or in the\n built-in ``bin()``, ``hex()`` and ``oct()`` functions). Must return\n an integer.\n\n\nWith Statement Context Managers\n===============================\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a ``with`` statement. The context\nmanager handles the entry into, and the exit from, the desired runtime\ncontext for the execution of the block of code. Context managers are\nnormally invoked using the ``with`` statement (described in section\n*The with statement*), but can also be used by directly invoking their\nmethods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The ``with``\n statement will bind this method\'s return value to the target(s)\n specified in the ``as`` clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be ``None``.\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that ``__exit__()`` methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n\nSpecial method lookup\n=====================\n\nFor custom classes, implicit invocations of special methods are only\nguaranteed to work correctly if defined on an object\'s type, not in\nthe object\'s instance dictionary. That behaviour is the reason why\nthe following code raises an exception:\n\n >>> class C:\n ... pass\n ...\n >>> c = C()\n >>> c.__len__ = lambda: 5\n >>> len(c)\n Traceback (most recent call last):\n File "", line 1, in \n TypeError: object of type \'C\' has no len()\n\nThe rationale behind this behaviour lies with a number of special\nmethods such as ``__hash__()`` and ``__repr__()`` that are implemented\nby all objects, including type objects. If the implicit lookup of\nthese methods used the conventional lookup process, they would fail\nwhen invoked on the type object itself:\n\n >>> 1 .__hash__() == hash(1)\n True\n >>> int.__hash__() == hash(int)\n Traceback (most recent call last):\n File "", line 1, in \n TypeError: descriptor \'__hash__\' of \'int\' object needs an argument\n\nIncorrectly attempting to invoke an unbound method of a class in this\nway is sometimes referred to as \'metaclass confusion\', and is avoided\nby bypassing the instance when looking up special methods:\n\n >>> type(1).__hash__(1) == hash(1)\n True\n >>> type(int).__hash__(int) == hash(int)\n True\n\nIn addition to bypassing any instance attributes in the interest of\ncorrectness, implicit special method lookup generally also bypasses\nthe ``__getattribute__()`` method even of the object\'s metaclass:\n\n >>> class Meta(type):\n ... def __getattribute__(*args):\n ... print("Metaclass getattribute invoked")\n ... return type.__getattribute__(*args)\n ...\n >>> class C(object, metaclass=Meta):\n ... def __len__(self):\n ... return 10\n ... def __getattribute__(*args):\n ... print("Class getattribute invoked")\n ... return object.__getattribute__(*args)\n ...\n >>> c = C()\n >>> c.__len__() # Explicit lookup via instance\n Class getattribute invoked\n 10\n >>> type(c).__len__(c) # Explicit lookup via type\n Metaclass getattribute invoked\n 10\n >>> len(c) # Implicit lookup\n 10\n\nBypassing the ``__getattribute__()`` machinery in this fashion\nprovides significant scope for speed optimisations within the\ninterpreter, at the cost of some flexibility in the handling of\nspecial methods (the special method *must* be set on the class object\nitself in order to be consistently invoked by the interpreter).\n\n-[ Footnotes ]-\n\n[1] It *is* possible in some cases to change an object\'s type, under\n certain controlled conditions. It generally isn\'t a good idea\n though, since it can lead to some very strange behaviour if it is\n handled incorrectly.\n\n[2] For operands of the same type, it is assumed that if the non-\n reflected method (such as ``__add__()``) fails the operation is\n not supported, which is why the reflected method is not called.\n', - 'string-methods': '\nString Methods\n**************\n\nStrings implement all of the *common* sequence operations, along with\nthe additional methods described below.\n\nStrings also support two styles of string formatting, one providing a\nlarge degree of flexibility and customization (see ``str.format()``,\n*Format String Syntax* and *String Formatting*) and the other based on\nC ``printf`` style formatting that handles a narrower range of types\nand is slightly harder to use correctly, but is often faster for the\ncases it can handle (*printf-style String Formatting*).\n\nThe *Text Processing Services* section of the standard library covers\na number of other modules that provide various text related utilities\n(including regular expression support in the ``re`` module).\n\nstr.capitalize()\n\n Return a copy of the string with its first character capitalized\n and the rest lowercased.\n\nstr.casefold()\n\n Return a casefolded copy of the string. Casefolded strings may be\n used for caseless matching.\n\n Casefolding is similar to lowercasing but more aggressive because\n it is intended to remove all case distinctions in a string. For\n example, the German lowercase letter ``\'\xc3\x9f\'`` is equivalent to\n ``"ss"``. Since it is already lowercase, ``lower()`` would do\n nothing to ``\'\xc3\x9f\'``; ``casefold()`` converts it to ``"ss"``.\n\n The casefolding algorithm is described in section 3.13 of the\n Unicode Standard.\n\n New in version 3.3.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.encode(encoding="utf-8", errors="strict")\n\n Return an encoded version of the string as a bytes object. Default\n encoding is ``\'utf-8\'``. *errors* may be given to set a different\n error handling scheme. The default for *errors* is ``\'strict\'``,\n meaning that encoding errors raise a ``UnicodeError``. Other\n possible values are ``\'ignore\'``, ``\'replace\'``,\n ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and any other name\n registered via ``codecs.register_error()``, see section *Codec Base\n Classes*. For a list of possible encodings, see section *Standard\n Encodings*.\n\n Changed in version 3.1: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\nstr.expandtabs(tabsize=8)\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. Tab positions occur every *tabsize* characters\n (default is 8, giving tab positions at columns 0, 8, 16 and so on).\n To expand the string, the current column is set to zero and the\n string is examined character by character. If the character is a\n tab (``\\t``), one or more space characters are inserted in the\n result until the current column is equal to the next tab position.\n (The tab character itself is not copied.) If the character is a\n newline (``\\n``) or return (``\\r``), it is copied and the current\n column is reset to zero. Any other character is copied unchanged\n and the current column is incremented by one regardless of how the\n character is represented when printed.\n\n >>> \'01\\t012\\t0123\\t01234\'.expandtabs()\n \'01 012 0123 01234\'\n >>> \'01\\t012\\t0123\\t01234\'.expandtabs(4)\n \'01 012 0123 01234\'\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` if *sub* is not found.\n\n Note: The ``find()`` method should be used only if you need to know the\n position of *sub*. To check if *sub* is a substring or not, use\n the ``in`` operator:\n\n >>> \'Py\' in \'Python\'\n True\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces ``{}``. Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\nstr.format_map(mapping)\n\n Similar to ``str.format(**mapping)``, except that ``mapping`` is\n used directly and not copied to a ``dict`` . This is useful if for\n example ``mapping`` is a dict subclass:\n\n >>> class Default(dict):\n ... def __missing__(self, key):\n ... return key\n ...\n >>> \'{name} was born in {country}\'.format_map(Default(name=\'Guido\'))\n \'Guido was born in country\'\n\n New in version 3.2.\n\nstr.index(sub[, start[, end]])\n\n Like ``find()``, but raise ``ValueError`` when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise. A character\n ``c`` is alphanumeric if one of the following returns ``True``:\n ``c.isalpha()``, ``c.isdecimal()``, ``c.isdigit()``, or\n ``c.isnumeric()``.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise. Alphabetic\n characters are those characters defined in the Unicode character\n database as "Letter", i.e., those with general category property\n being one of "Lm", "Lt", "Lu", "Ll", or "Lo". Note that this is\n different from the "Alphabetic" property defined in the Unicode\n Standard.\n\nstr.isdecimal()\n\n Return true if all characters in the string are decimal characters\n and there is at least one character, false otherwise. Decimal\n characters are those from general category "Nd". This category\n includes digit characters, and all characters that can be used to\n form decimal-radix numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise. Digits include decimal\n characters and digits that need special handling, such as the\n compatibility superscript digits. Formally, a digit is a character\n that has the property value Numeric_Type=Digit or\n Numeric_Type=Decimal.\n\nstr.isidentifier()\n\n Return true if the string is a valid identifier according to the\n language definition, section *Identifiers and keywords*.\n\n Use ``keyword.iskeyword()`` to test for reserved identifiers such\n as ``def`` and ``class``.\n\nstr.islower()\n\n Return true if all cased characters [4] in the string are lowercase\n and there is at least one cased character, false otherwise.\n\nstr.isnumeric()\n\n Return true if all characters in the string are numeric characters,\n and there is at least one character, false otherwise. Numeric\n characters include digit characters, and all characters that have\n the Unicode numeric value property, e.g. U+2155, VULGAR FRACTION\n ONE FIFTH. Formally, numeric characters are those with the\n property value Numeric_Type=Digit, Numeric_Type=Decimal or\n Numeric_Type=Numeric.\n\nstr.isprintable()\n\n Return true if all characters in the string are printable or the\n string is empty, false otherwise. Nonprintable characters are\n those characters defined in the Unicode character database as\n "Other" or "Separator", excepting the ASCII space (0x20) which is\n considered printable. (Note that printable characters in this\n context are those which should not be escaped when ``repr()`` is\n invoked on a string. It has no bearing on the handling of strings\n written to ``sys.stdout`` or ``sys.stderr``.)\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise. Whitespace\n characters are those characters defined in the Unicode character\n database as "Other" or "Separator" and those with bidirectional\n property being one of "WS", "B", or "S".\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\nstr.isupper()\n\n Return true if all cased characters [4] in the string are uppercase\n and there is at least one cased character, false otherwise.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. A ``TypeError`` will be raised if there are\n any non-string values in *iterable*, including ``bytes`` objects.\n The separator between elements is the string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than or\n equal to ``len(s)``.\n\nstr.lower()\n\n Return a copy of the string with all the cased characters [4]\n converted to lowercase.\n\n The lowercasing algorithm used is described in section 3.13 of the\n Unicode Standard.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\nstatic str.maketrans(x[, y[, z]])\n\n This static method returns a translation table usable for\n ``str.translate()``.\n\n If there is only one argument, it must be a dictionary mapping\n Unicode ordinals (integers) or characters (strings of length 1) to\n Unicode ordinals, strings (of arbitrary lengths) or None.\n Character keys will then be converted to ordinals.\n\n If there are two arguments, they must be strings of equal length,\n and in the resulting dictionary, each character in x will be mapped\n to the character at the same position in y. If there is a third\n argument, it must be a string, whose characters will be mapped to\n None in the result.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n is not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than or\n equal to ``len(s)``.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\nstr.rsplit(sep=None, maxsplit=-1)\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n ``None``, any whitespace string is a separator. Except for\n splitting from the right, ``rsplit()`` behaves like ``split()``\n which is described in detail below.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\nstr.split(sep=None, maxsplit=-1)\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most ``maxsplit+1``\n elements). If *maxsplit* is not specified or ``-1``, then there is\n no limit on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``). The *sep*\n argument may consist of multiple characters (for example,\n ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n an empty string with a specified separator returns ``[\'\']``.\n\n If *sep* is not specified or is ``None``, a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a ``None`` separator returns\n ``[]``.\n\n For example, ``\' 1 2 3 \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n and ``\' 1 2 3 \'.split(None, 1)`` returns ``[\'1\', \'2 3 \']``.\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. This method uses the *universal newlines* approach to\n splitting lines. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\n For example, ``\'ab c\\n\\nde fg\\rkl\\r\\n\'.splitlines()`` returns\n ``[\'ab c\', \'\', \'de fg\', \'kl\']``, while the same call with\n ``splitlines(True)`` returns ``[\'ab c\\n\', \'\\n\', \'de fg\\r\',\n \'kl\\r\\n\']``.\n\n Unlike ``split()`` when a delimiter string *sep* is given, this\n method returns an empty list for the empty string, and a terminal\n line break does not result in an extra line.\n\nstr.startswith(prefix[, start[, end]])\n\n Return ``True`` if string starts with the *prefix*, otherwise\n return ``False``. *prefix* can also be a tuple of prefixes to look\n for. With optional *start*, test string beginning at that\n position. With optional *end*, stop comparing string at that\n position.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or ``None``, the\n *chars* argument defaults to removing whitespace. The *chars*\n argument is not a prefix or suffix; rather, all combinations of its\n values are stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa. Note that it is not necessarily true that\n ``s.swapcase().swapcase() == s``.\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n ... return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n ... lambda mo: mo.group(0)[0].upper() +\n ... mo.group(0)[1:].lower(),\n ... s)\n ...\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\nstr.translate(map)\n\n Return a copy of the *s* where all characters have been mapped\n through the *map* which must be a dictionary of Unicode ordinals\n (integers) to Unicode ordinals, strings or ``None``. Unmapped\n characters are left untouched. Characters mapped to ``None`` are\n deleted.\n\n You can use ``str.maketrans()`` to create a translation map from\n character-to-character mappings in different formats.\n\n Note: An even more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see\n ``encodings.cp1251`` for an example).\n\nstr.upper()\n\n Return a copy of the string with all the cased characters [4]\n converted to uppercase. Note that ``str.upper().isupper()`` might\n be ``False`` if ``s`` contains uncased characters or if the Unicode\n category of the resulting character(s) is not "Lu" (Letter,\n uppercase), but e.g. "Lt" (Letter, titlecase).\n\n The uppercasing algorithm used is described in section 3.13 of the\n Unicode Standard.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than or equal to ``len(s)``.\n', - 'strings': '\nString and Bytes literals\n*************************\n\nString literals are described by the following lexical definitions:\n\n stringliteral ::= [stringprefix](shortstring | longstring)\n stringprefix ::= "r" | "u" | "R" | "U"\n shortstring ::= "\'" shortstringitem* "\'" | \'"\' shortstringitem* \'"\'\n longstring ::= "\'\'\'" longstringitem* "\'\'\'" | \'"""\' longstringitem* \'"""\'\n shortstringitem ::= shortstringchar | stringescapeseq\n longstringitem ::= longstringchar | stringescapeseq\n shortstringchar ::= \n longstringchar ::= \n stringescapeseq ::= "\\" \n\n bytesliteral ::= bytesprefix(shortbytes | longbytes)\n bytesprefix ::= "b" | "B" | "br" | "Br" | "bR" | "BR" | "rb" | "rB" | "Rb" | "RB"\n shortbytes ::= "\'" shortbytesitem* "\'" | \'"\' shortbytesitem* \'"\'\n longbytes ::= "\'\'\'" longbytesitem* "\'\'\'" | \'"""\' longbytesitem* \'"""\'\n shortbytesitem ::= shortbyteschar | bytesescapeseq\n longbytesitem ::= longbyteschar | bytesescapeseq\n shortbyteschar ::= \n longbyteschar ::= \n bytesescapeseq ::= "\\" \n\nOne syntactic restriction not indicated by these productions is that\nwhitespace is not allowed between the ``stringprefix`` or\n``bytesprefix`` and the rest of the literal. The source character set\nis defined by the encoding declaration; it is UTF-8 if no encoding\ndeclaration is given in the source file; see section *Encoding\ndeclarations*.\n\nIn plain English: Both types of literals can be enclosed in matching\nsingle quotes (``\'``) or double quotes (``"``). They can also be\nenclosed in matching groups of three single or double quotes (these\nare generally referred to as *triple-quoted strings*). The backslash\n(``\\``) character is used to escape characters that otherwise have a\nspecial meaning, such as newline, backslash itself, or the quote\ncharacter.\n\nBytes literals are always prefixed with ``\'b\'`` or ``\'B\'``; they\nproduce an instance of the ``bytes`` type instead of the ``str`` type.\nThey may only contain ASCII characters; bytes with a numeric value of\n128 or greater must be expressed with escapes.\n\nAs of Python 3.3 it is possible again to prefix unicode strings with a\n``u`` prefix to simplify maintenance of dual 2.x and 3.x codebases.\n\nBoth string and bytes literals may optionally be prefixed with a\nletter ``\'r\'`` or ``\'R\'``; such strings are called *raw strings* and\ntreat backslashes as literal characters. As a result, in string\nliterals, ``\'\\U\'`` and ``\'\\u\'`` escapes in raw strings are not treated\nspecially. Given that Python 2.x\'s raw unicode literals behave\ndifferently than Python 3.x\'s the ``\'ur\'`` syntax is not supported.\n\n New in version 3.3: The ``\'rb\'`` prefix of raw bytes literals has\n been added as a synonym of ``\'br\'``.\n\n New in version 3.3: Support for the unicode legacy literal\n (``u\'value\'``) was reintroduced to simplify the maintenance of dual\n Python 2.x and 3.x codebases. See **PEP 414** for more information.\n\nIn triple-quoted strings, unescaped newlines and quotes are allowed\n(and are retained), except that three unescaped quotes in a row\nterminate the string. (A "quote" is the character used to open the\nstring, i.e. either ``\'`` or ``"``.)\n\nUnless an ``\'r\'`` or ``\'R\'`` prefix is present, escape sequences in\nstrings are interpreted according to rules similar to those used by\nStandard C. The recognized escape sequences are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence | Meaning | Notes |\n+===================+===================================+=========+\n| ``\\newline`` | Backslash and newline ignored | |\n+-------------------+-----------------------------------+---------+\n| ``\\\\`` | Backslash (``\\``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\\'`` | Single quote (``\'``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\"`` | Double quote (``"``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\a`` | ASCII Bell (BEL) | |\n+-------------------+-----------------------------------+---------+\n| ``\\b`` | ASCII Backspace (BS) | |\n+-------------------+-----------------------------------+---------+\n| ``\\f`` | ASCII Formfeed (FF) | |\n+-------------------+-----------------------------------+---------+\n| ``\\n`` | ASCII Linefeed (LF) | |\n+-------------------+-----------------------------------+---------+\n| ``\\r`` | ASCII Carriage Return (CR) | |\n+-------------------+-----------------------------------+---------+\n| ``\\t`` | ASCII Horizontal Tab (TAB) | |\n+-------------------+-----------------------------------+---------+\n| ``\\v`` | ASCII Vertical Tab (VT) | |\n+-------------------+-----------------------------------+---------+\n| ``\\ooo`` | Character with octal value *ooo* | (1,3) |\n+-------------------+-----------------------------------+---------+\n| ``\\xhh`` | Character with hex value *hh* | (2,3) |\n+-------------------+-----------------------------------+---------+\n\nEscape sequences only recognized in string literals are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence | Meaning | Notes |\n+===================+===================================+=========+\n| ``\\N{name}`` | Character named *name* in the | (4) |\n| | Unicode database | |\n+-------------------+-----------------------------------+---------+\n| ``\\uxxxx`` | Character with 16-bit hex value | (5) |\n| | *xxxx* | |\n+-------------------+-----------------------------------+---------+\n| ``\\Uxxxxxxxx`` | Character with 32-bit hex value | (6) |\n| | *xxxxxxxx* | |\n+-------------------+-----------------------------------+---------+\n\nNotes:\n\n1. As in Standard C, up to three octal digits are accepted.\n\n2. Unlike in Standard C, exactly two hex digits are required.\n\n3. In a bytes literal, hexadecimal and octal escapes denote the byte\n with the given value. In a string literal, these escapes denote a\n Unicode character with the given value.\n\n4. Changed in version 3.3: Support for name aliases [1] has been\n added.\n\n5. Individual code units which form parts of a surrogate pair can be\n encoded using this escape sequence. Exactly four hex digits are\n required.\n\n6. Any Unicode character can be encoded this way. Exactly eight hex\n digits are required.\n\nUnlike Standard C, all unrecognized escape sequences are left in the\nstring unchanged, i.e., *the backslash is left in the string*. (This\nbehavior is useful when debugging: if an escape sequence is mistyped,\nthe resulting output is more easily recognized as broken.) It is also\nimportant to note that the escape sequences only recognized in string\nliterals fall into the category of unrecognized escapes for bytes\nliterals.\n\nEven in a raw string, string quotes can be escaped with a backslash,\nbut the backslash remains in the string; for example, ``r"\\""`` is a\nvalid string literal consisting of two characters: a backslash and a\ndouble quote; ``r"\\"`` is not a valid string literal (even a raw\nstring cannot end in an odd number of backslashes). Specifically, *a\nraw string cannot end in a single backslash* (since the backslash\nwould escape the following quote character). Note also that a single\nbackslash followed by a newline is interpreted as those two characters\nas part of the string, *not* as a line continuation.\n', - 'subscriptions': '\nSubscriptions\n*************\n\nA subscription selects an item of a sequence (string, tuple or list)\nor mapping (dictionary) object:\n\n subscription ::= primary "[" expression_list "]"\n\nThe primary must evaluate to an object that supports subscription,\ne.g. a list or dictionary. User-defined objects can support\nsubscription by defining a ``__getitem__()`` method.\n\nFor built-in objects, there are two types of objects that support\nsubscription:\n\nIf the primary is a mapping, the expression list must evaluate to an\nobject whose value is one of the keys of the mapping, and the\nsubscription selects the value in the mapping that corresponds to that\nkey. (The expression list is a tuple except if it has exactly one\nitem.)\n\nIf the primary is a sequence, the expression (list) must evaluate to\nan integer or a slice (as discussed in the following section).\n\nThe formal syntax makes no special provision for negative indices in\nsequences; however, built-in sequences all provide a ``__getitem__()``\nmethod that interprets negative indices by adding the length of the\nsequence to the index (so that ``x[-1]`` selects the last item of\n``x``). The resulting value must be a nonnegative integer less than\nthe number of items in the sequence, and the subscription selects the\nitem whose index is that value (counting from zero). Since the support\nfor negative indices and slicing occurs in the object\'s\n``__getitem__()`` method, subclasses overriding this method will need\nto explicitly add that support.\n\nA string\'s items are characters. A character is not a separate data\ntype but a string of exactly one character.\n', - 'truth': "\nTruth Value Testing\n*******************\n\nAny object can be tested for truth value, for use in an ``if`` or\n``while`` condition or as operand of the Boolean operations below. The\nfollowing values are considered false:\n\n* ``None``\n\n* ``False``\n\n* zero of any numeric type, for example, ``0``, ``0.0``, ``0j``.\n\n* any empty sequence, for example, ``''``, ``()``, ``[]``.\n\n* any empty mapping, for example, ``{}``.\n\n* instances of user-defined classes, if the class defines a\n ``__bool__()`` or ``__len__()`` method, when that method returns the\n integer zero or ``bool`` value ``False``. [1]\n\nAll other values are considered true --- so objects of many types are\nalways true.\n\nOperations and built-in functions that have a Boolean result always\nreturn ``0`` or ``False`` for false and ``1`` or ``True`` for true,\nunless otherwise stated. (Important exception: the Boolean operations\n``or`` and ``and`` always return one of their operands.)\n", - 'try': '\nThe ``try`` statement\n*********************\n\nThe ``try`` statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression ["as" target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nThe ``except`` clause(s) specify one or more exception handlers. When\nno exception occurs in the ``try`` clause, no exception handler is\nexecuted. When an exception occurs in the ``try`` suite, a search for\nan exception handler is started. This search inspects the except\nclauses in turn until one is found that matches the exception. An\nexpression-less except clause, if present, must be last; it matches\nany exception. For an except clause with an expression, that\nexpression is evaluated, and the clause matches the exception if the\nresulting object is "compatible" with the exception. An object is\ncompatible with an exception if it is the class or a base class of the\nexception object or a tuple containing an item compatible with the\nexception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire ``try`` statement\nraised the exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified after the ``as`` keyword in that except clause,\nif present, and the except clause\'s suite is executed. All except\nclauses must have an executable block. When the end of this block is\nreached, execution continues normally after the entire try statement.\n(This means that if two nested handlers exist for the same exception,\nand the exception occurs in the try clause of the inner handler, the\nouter handler will not handle the exception.)\n\nWhen an exception has been assigned using ``as target``, it is cleared\nat the end of the except clause. This is as if\n\n except E as N:\n foo\n\nwas translated to\n\n except E as N:\n try:\n foo\n finally:\n del N\n\nThis means the exception must be assigned to a different name to be\nable to refer to it after the except clause. Exceptions are cleared\nbecause with the traceback attached to them, they form a reference\ncycle with the stack frame, keeping all locals in that frame alive\nuntil the next garbage collection occurs.\n\nBefore an except clause\'s suite is executed, details about the\nexception are stored in the ``sys`` module and can be access via\n``sys.exc_info()``. ``sys.exc_info()`` returns a 3-tuple consisting of\nthe exception class, the exception instance and a traceback object\n(see section *The standard type hierarchy*) identifying the point in\nthe program where the exception occurred. ``sys.exc_info()`` values\nare restored to their previous values (before the call) when returning\nfrom a function that handled an exception.\n\nThe optional ``else`` clause is executed if and when control flows off\nthe end of the ``try`` clause. [2] Exceptions in the ``else`` clause\nare not handled by the preceding ``except`` clauses.\n\nIf ``finally`` is present, it specifies a \'cleanup\' handler. The\n``try`` clause is executed, including any ``except`` and ``else``\nclauses. If an exception occurs in any of the clauses and is not\nhandled, the exception is temporarily saved. The ``finally`` clause is\nexecuted. If there is a saved exception it is re-raised at the end of\nthe ``finally`` clause. If the ``finally`` clause raises another\nexception, the saved exception is set as the context of the new\nexception. If the ``finally`` clause executes a ``return`` or\n``break`` statement, the saved exception is discarded:\n\n def f():\n try:\n 1/0\n finally:\n return 42\n\n >>> f()\n 42\n\nThe exception information is not available to the program during\nexecution of the ``finally`` clause.\n\nWhen a ``return``, ``break`` or ``continue`` statement is executed in\nthe ``try`` suite of a ``try``...``finally`` statement, the\n``finally`` clause is also executed \'on the way out.\' A ``continue``\nstatement is illegal in the ``finally`` clause. (The reason is a\nproblem with the current implementation --- this restriction may be\nlifted in the future).\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the ``raise`` statement to\ngenerate exceptions may be found in section *The raise statement*.\n', - 'types': '\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.), although such additions\nwill often be provided via the standard library instead.\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name ``None``.\n It is used to signify the absence of a value in many situations,\n e.g., it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``NotImplemented``. Numeric methods and rich comparison methods may\n return this value if they do not implement the operation for the\n operands provided. (The interpreter will then try the reflected\n operation, or some other fallback, depending on the operator.) Its\n truth value is true.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the literal ``...`` or the\n built-in name ``Ellipsis``. Its truth value is true.\n\n``numbers.Number``\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n ``numbers.Integral``\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are two types of integers:\n\n Integers (``int``)\n\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans (``bool``)\n These represent the truth values False and True. The two\n objects representing the values False and True are the only\n Boolean objects. The Boolean type is a subtype of the integer\n type, and Boolean values behave like the values 0 and 1,\n respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ``"False"`` or\n ``"True"`` are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers.\n\n ``numbers.Real`` (``float``)\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these is\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n ``numbers.Complex`` (``complex``)\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number ``z`` can be retrieved through the read-only\n attributes ``z.real`` and ``z.imag``.\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function ``len()`` returns the number of\n items of a sequence. When the length of a sequence is *n*, the\n index set contains the numbers 0, 1, ..., *n*-1. Item *i* of\n sequence *a* is selected by ``a[i]``.\n\n Sequences also support slicing: ``a[i:j]`` selects all items with\n index *k* such that *i* ``<=`` *k* ``<`` *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: ``a[i:j:k]`` selects all items of *a* with index *x*\n where ``x = i + n*k``, *n* ``>=`` ``0`` and *i* ``<=`` *x* ``<``\n *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n A string is a sequence of values that represent Unicode\n codepoints. All the codepoints in range ``U+0000 - U+10FFFF``\n can be represented in a string. Python doesn\'t have a\n ``chr`` type, and every character in the string is\n represented as a string object with length ``1``. The built-\n in function ``ord()`` converts a character to its codepoint\n (as an integer); ``chr()`` converts an integer in range ``0 -\n 10FFFF`` to the corresponding character. ``str.encode()`` can\n be used to convert a ``str`` to ``bytes`` using the given\n encoding, and ``bytes.decode()`` can be used to achieve the\n opposite.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Bytes\n A bytes object is an immutable array. The items are 8-bit\n bytes, represented by integers in the range 0 <= x < 256.\n Bytes literals (like ``b\'abc\'``) and the built-in function\n ``bytes()`` can be used to construct bytes objects. Also,\n bytes objects can be decoded to strings via the ``decode()``\n method.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and ``del`` (delete) statements.\n\n There are currently two intrinsic mutable sequence types:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n Byte Arrays\n A bytearray object is a mutable array. They are created by\n the built-in ``bytearray()`` constructor. Aside from being\n mutable (and hence unhashable), byte arrays otherwise provide\n the same interface and functionality as immutable bytes\n objects.\n\n The extension module ``array`` provides an additional example of\n a mutable sequence type, as does the ``collections`` module.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function ``len()``\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n ``set()`` constructor and can be modified afterwards by several\n methods, such as ``add()``.\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in ``frozenset()`` constructor. As a frozenset is\n immutable and *hashable*, it can be used again as an element of\n another set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation ``a[k]`` selects the item indexed by\n ``k`` from the mapping ``a``; this can be used in expressions and\n as the target of assignments or ``del`` statements. The built-in\n function ``len()`` returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``) then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the ``{...}``\n notation (see section *Dictionary displays*).\n\n The extension modules ``dbm.ndbm`` and ``dbm.gnu`` provide\n additional examples of mapping types, as does the\n ``collections`` module.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +---------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +===========================+=================================+=============+\n | ``__doc__`` | The function\'s documentation | Writable |\n | | string, or ``None`` if | |\n | | unavailable | |\n +---------------------------+---------------------------------+-------------+\n | ``__name__`` | The function\'s name | Writable |\n +---------------------------+---------------------------------+-------------+\n | ``__qualname__`` | The function\'s *qualified name* | Writable |\n | | New in version 3.3. | |\n +---------------------------+---------------------------------+-------------+\n | ``__module__`` | The name of the module the | Writable |\n | | function was defined in, or | |\n | | ``None`` if unavailable. | |\n +---------------------------+---------------------------------+-------------+\n | ``__defaults__`` | A tuple containing default | Writable |\n | | argument values for those | |\n | | arguments that have defaults, | |\n | | or ``None`` if no arguments | |\n | | have a default value | |\n +---------------------------+---------------------------------+-------------+\n | ``__code__`` | The code object representing | Writable |\n | | the compiled function body. | |\n +---------------------------+---------------------------------+-------------+\n | ``__globals__`` | A reference to the dictionary | Read-only |\n | | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +---------------------------+---------------------------------+-------------+\n | ``__dict__`` | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +---------------------------+---------------------------------+-------------+\n | ``__closure__`` | ``None`` or a tuple of cells | Read-only |\n | | that contain bindings for the | |\n | | function\'s free variables. | |\n +---------------------------+---------------------------------+-------------+\n | ``__annotations__`` | A dict containing annotations | Writable |\n | | of parameters. The keys of the | |\n | | dict are the parameter names, | |\n | | or ``\'return\'`` for the return | |\n | | annotation, if provided. | |\n +---------------------------+---------------------------------+-------------+\n | ``__kwdefaults__`` | A dict containing defaults for | Writable |\n | | keyword-only parameters. | |\n +---------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n Instance methods\n An instance method object combines a class, a class instance and\n any callable object (normally a user-defined function).\n\n Special read-only attributes: ``__self__`` is the class instance\n object, ``__func__`` is the function object; ``__doc__`` is the\n method\'s documentation (same as ``__func__.__doc__``);\n ``__name__`` is the method name (same as ``__func__.__name__``);\n ``__module__`` is the name of the module the method was defined\n in, or ``None`` if unavailable.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object or a class\n method object.\n\n When an instance method object is created by retrieving a user-\n defined function object from a class via one of its instances,\n its ``__self__`` attribute is the instance, and the method\n object is said to be bound. The new method\'s ``__func__``\n attribute is the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the ``__func__``\n attribute of the new instance is not the original method object\n but its ``__func__`` attribute.\n\n When an instance method object is created by retrieving a class\n method object from a class or instance, its ``__self__``\n attribute is the class itself, and its ``__func__`` attribute is\n the function object underlying the class method.\n\n When an instance method object is called, the underlying\n function (``__func__``) is called, inserting the class instance\n (``__self__``) in front of the argument list. For instance,\n when ``C`` is a class which contains a definition for a function\n ``f()``, and ``x`` is an instance of ``C``, calling ``x.f(1)``\n is equivalent to calling ``C.f(x, 1)``.\n\n When an instance method object is derived from a class method\n object, the "class instance" stored in ``__self__`` will\n actually be the class itself, so that calling either ``x.f(1)``\n or ``C.f(1)`` is equivalent to calling ``f(C,1)`` where ``f`` is\n the underlying function.\n\n Note that the transformation from function object to instance\n method object happens each time the attribute is retrieved from\n the instance. In some cases, a fruitful optimization is to\n assign the attribute to a local variable and call that local\n variable. Also notice that this transformation only happens for\n user-defined functions; other callable objects (and all non-\n callable objects) are retrieved without transformation. It is\n also important to note that user-defined functions which are\n attributes of a class instance are not converted to bound\n methods; this *only* happens when the function is an attribute\n of the class.\n\n Generator functions\n A function or method which uses the ``yield`` statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s ``iterator.__next__()`` method will cause the\n function to execute until it provides a value using the\n ``yield`` statement. When the function executes a ``return``\n statement or falls off the end, a ``StopIteration`` exception is\n raised and the iterator will have reached the end of the set of\n values to be returned.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are ``len()`` and ``math.sin()``\n (``math`` is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: ``__doc__`` is the function\'s documentation\n string, or ``None`` if unavailable; ``__name__`` is the\n function\'s name; ``__self__`` is set to ``None`` (but see the\n next item); ``__module__`` is the name of the module the\n function was defined in or ``None`` if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n ``alist.append()``, assuming *alist* is a list object. In this\n case, the special read-only attribute ``__self__`` is set to the\n object denoted by *alist*.\n\n Classes\n Classes are callable. These objects normally act as factories\n for new instances of themselves, but variations are possible for\n class types that override ``__new__()``. The arguments of the\n call are passed to ``__new__()`` and, in the typical case, to\n ``__init__()`` to initialize the new instance.\n\n Class Instances\n Instances of arbitrary classes can be made callable by defining\n a ``__call__()`` method in their class.\n\nModules\n Modules are a basic organizational unit of Python code, and are\n created by the *import system* as invoked either by the ``import``\n statement (see ``import``), or by calling functions such as\n ``importlib.import_module()`` and built-in ``__import__()``. A\n module object has a namespace implemented by a dictionary object\n (this is the dictionary referenced by the ``__globals__`` attribute\n of functions defined in the module). Attribute references are\n translated to lookups in this dictionary, e.g., ``m.x`` is\n equivalent to ``m.__dict__["x"]``. A module object does not contain\n the code object used to initialize the module (since it isn\'t\n needed once the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``.\n\n Special read-only attribute: ``__dict__`` is the module\'s namespace\n as a dictionary object.\n\n **CPython implementation detail:** Because of the way CPython\n clears module dictionaries, the module dictionary will be cleared\n when the module falls out of scope even if the dictionary still has\n live references. To avoid this, copy the dictionary or keep the\n module around while using its dictionary directly.\n\n Predefined (writable) attributes: ``__name__`` is the module\'s\n name; ``__doc__`` is the module\'s documentation string, or ``None``\n if unavailable; ``__file__`` is the pathname of the file from which\n the module was loaded, if it was loaded from a file. The\n ``__file__`` attribute may be missing for certain types of modules,\n such as C modules that are statically linked into the interpreter;\n for extension modules loaded dynamically from a shared library, it\n is the pathname of the shared library file.\n\nCustom classes\n Custom class types are typically created by class definitions (see\n section *Class definitions*). A class has a namespace implemented\n by a dictionary object. Class attribute references are translated\n to lookups in this dictionary, e.g., ``C.x`` is translated to\n ``C.__dict__["x"]`` (although there are a number of hooks which\n allow for other means of locating attributes). When the attribute\n name is not found there, the attribute search continues in the base\n classes. This search of the base classes uses the C3 method\n resolution order which behaves correctly even in the presence of\n \'diamond\' inheritance structures where there are multiple\n inheritance paths leading back to a common ancestor. Additional\n details on the C3 MRO used by Python can be found in the\n documentation accompanying the 2.3 release at\n http://www.python.org/download/releases/2.3/mro/.\n\n When a class attribute reference (for class ``C``, say) would yield\n a class method object, it is transformed into an instance method\n object whose ``__self__`` attributes is ``C``. When it would yield\n a static method object, it is transformed into the object wrapped\n by the static method object. See section *Implementing Descriptors*\n for another way in which attributes retrieved from a class may\n differ from those actually contained in its ``__dict__``.\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: ``__name__`` is the class name; ``__module__``\n is the module name in which the class was defined; ``__dict__`` is\n the dictionary containing the class\'s namespace; ``__bases__`` is a\n tuple (possibly empty or a singleton) containing the base classes,\n in the order of their occurrence in the base class list;\n ``__doc__`` is the class\'s documentation string, or None if\n undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object, it is transformed into an instance method object\n whose ``__self__`` attribute is the instance. Static method and\n class method objects are also transformed; see above under\n "Classes". See section *Implementing Descriptors* for another way\n in which attributes of a class retrieved via its instances may\n differ from the objects actually stored in the class\'s\n ``__dict__``. If no class attribute is found, and the object\'s\n class has a ``__getattr__()`` method, that is called to satisfy the\n lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n ``__setattr__()`` or ``__delattr__()`` method, this is called\n instead of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: ``__dict__`` is the attribute dictionary;\n ``__class__`` is the instance\'s class.\n\nI/O objects (also known as file objects)\n A *file object* represents an open file. Various shortcuts are\n available to create file objects: the ``open()`` built-in function,\n and also ``os.popen()``, ``os.fdopen()``, and the ``makefile()``\n method of socket objects (and perhaps by other functions or methods\n provided by extension modules).\n\n The objects ``sys.stdin``, ``sys.stdout`` and ``sys.stderr`` are\n initialized to file objects corresponding to the interpreter\'s\n standard input, output and error streams; they are all open in text\n mode and therefore follow the interface defined by the\n ``io.TextIOBase`` abstract class.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: ``co_name`` gives the function\n name; ``co_argcount`` is the number of positional arguments\n (including arguments with default values); ``co_nlocals`` is the\n number of local variables used by the function (including\n arguments); ``co_varnames`` is a tuple containing the names of\n the local variables (starting with the argument names);\n ``co_cellvars`` is a tuple containing the names of local\n variables that are referenced by nested functions;\n ``co_freevars`` is a tuple containing the names of free\n variables; ``co_code`` is a string representing the sequence of\n bytecode instructions; ``co_consts`` is a tuple containing the\n literals used by the bytecode; ``co_names`` is a tuple\n containing the names used by the bytecode; ``co_filename`` is\n the filename from which the code was compiled;\n ``co_firstlineno`` is the first line number of the function;\n ``co_lnotab`` is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); ``co_stacksize`` is the required stack size\n (including local variables); ``co_flags`` is an integer encoding\n a number of flags for the interpreter.\n\n The following flag bits are defined for ``co_flags``: bit\n ``0x04`` is set if the function uses the ``*arguments`` syntax\n to accept an arbitrary number of positional arguments; bit\n ``0x08`` is set if the function uses the ``**keywords`` syntax\n to accept arbitrary keyword arguments; bit ``0x20`` is set if\n the function is a generator.\n\n Future feature declarations (``from __future__ import\n division``) also use bits in ``co_flags`` to indicate whether a\n code object was compiled with a particular feature enabled: bit\n ``0x2000`` is set if the function was compiled with future\n division enabled; bits ``0x10`` and ``0x1000`` were used in\n earlier versions of Python.\n\n Other bits in ``co_flags`` are reserved for internal use.\n\n If a code object represents a function, the first item in\n ``co_consts`` is the documentation string of the function, or\n ``None`` if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: ``f_back`` is to the previous\n stack frame (towards the caller), or ``None`` if this is the\n bottom stack frame; ``f_code`` is the code object being executed\n in this frame; ``f_locals`` is the dictionary used to look up\n local variables; ``f_globals`` is used for global variables;\n ``f_builtins`` is used for built-in (intrinsic) names;\n ``f_lasti`` gives the precise instruction (this is an index into\n the bytecode string of the code object).\n\n Special writable attributes: ``f_trace``, if not ``None``, is a\n function called at the start of each source code line (this is\n used by the debugger); ``f_lineno`` is the current line number\n of the frame --- writing to this from within a trace function\n jumps to the given line (only for the bottom-most frame). A\n debugger can implement a Jump command (aka Set Next Statement)\n by writing to f_lineno.\n\n Frame objects support one method:\n\n frame.clear()\n\n This method clears all references to local variables held by\n the frame. Also, if the frame belonged to a generator, the\n generator is finalized. This helps break reference cycles\n involving frame objects (for example when catching an\n exception and storing its traceback for later use).\n\n ``RuntimeError`` is raised if the frame is currently\n executing.\n\n New in version 3.4.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as the third item of the\n tuple returned by ``sys.exc_info()``. When the program contains\n no suitable handler, the stack trace is written (nicely\n formatted) to the standard error stream; if the interpreter is\n interactive, it is also made available to the user as\n ``sys.last_traceback``.\n\n Special read-only attributes: ``tb_next`` is the next level in\n the stack trace (towards the frame where the exception\n occurred), or ``None`` if there is no next level; ``tb_frame``\n points to the execution frame of the current level;\n ``tb_lineno`` gives the line number where the exception\n occurred; ``tb_lasti`` indicates the precise instruction. The\n line number and last instruction in the traceback may differ\n from the line number of its frame object if the exception\n occurred in a ``try`` statement with no matching except clause\n or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices for ``__getitem__()``\n methods. They are also created by the built-in ``slice()``\n function.\n\n Special read-only attributes: ``start`` is the lower bound;\n ``stop`` is the upper bound; ``step`` is the step value; each is\n ``None`` if omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the slice that the slice object\n would describe if applied to a sequence of *length* items.\n It returns a tuple of three integers; respectively these are\n the *start* and *stop* indices and the *step* or stride\n length of the slice. Missing or out-of-bounds indices are\n handled in a manner consistent with regular slices.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n ``staticmethod()`` constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in ``classmethod()`` constructor.\n', - 'typesfunctions': '\nFunctions\n*********\n\nFunction objects are created by function definitions. The only\noperation on a function object is to call it: ``func(argument-list)``.\n\nThere are really two flavors of function objects: built-in functions\nand user-defined functions. Both support the same operation (to call\nthe function), but the implementation is different, hence the\ndifferent object types.\n\nSee *Function definitions* for more information.\n', - 'typesmapping': '\nMapping Types --- ``dict``\n**************************\n\nA *mapping* object maps *hashable* values to arbitrary objects.\nMappings are mutable objects. There is currently only one standard\nmapping type, the *dictionary*. (For other containers see the built-\nin ``list``, ``set``, and ``tuple`` classes, and the ``collections``\nmodule.)\n\nA dictionary\'s keys are *almost* arbitrary values. Values that are\nnot *hashable*, that is, values containing lists, dictionaries or\nother mutable types (that are compared by value rather than by object\nidentity) may not be used as keys. Numeric types used for keys obey\nthe normal rules for numeric comparison: if two numbers compare equal\n(such as ``1`` and ``1.0``) then they can be used interchangeably to\nindex the same dictionary entry. (Note however, that since computers\nstore floating-point numbers as approximations it is usually unwise to\nuse them as dictionary keys.)\n\nDictionaries can be created by placing a comma-separated list of\n``key: value`` pairs within braces, for example: ``{\'jack\': 4098,\n\'sjoerd\': 4127}`` or ``{4098: \'jack\', 4127: \'sjoerd\'}``, or by the\n``dict`` constructor.\n\nclass class dict(**kwarg)\nclass class dict(mapping, **kwarg)\nclass class dict(iterable, **kwarg)\n\n Return a new dictionary initialized from an optional positional\n argument and a possibly empty set of keyword arguments.\n\n If no positional argument is given, an empty dictionary is created.\n If a positional argument is given and it is a mapping object, a\n dictionary is created with the same key-value pairs as the mapping\n object. Otherwise, the positional argument must be an *iterator*\n object. Each item in the iterable must itself be an iterator with\n exactly two objects. The first object of each item becomes a key\n in the new dictionary, and the second object the corresponding\n value. If a key occurs more than once, the last value for that key\n becomes the corresponding value in the new dictionary.\n\n If keyword arguments are given, the keyword arguments and their\n values are added to the dictionary created from the positional\n argument. If a key being added is already present, the value from\n the keyword argument replaces the value from the positional\n argument.\n\n To illustrate, the following examples all return a dictionary equal\n to ``{"one": 1, "two": 2, "three": 3}``:\n\n >>> a = dict(one=1, two=2, three=3)\n >>> b = {\'one\': 1, \'two\': 2, \'three\': 3}\n >>> c = dict(zip([\'one\', \'two\', \'three\'], [1, 2, 3]))\n >>> d = dict([(\'two\', 2), (\'one\', 1), (\'three\', 3)])\n >>> e = dict({\'three\': 3, \'one\': 1, \'two\': 2})\n >>> a == b == c == d == e\n True\n\n Providing keyword arguments as in the first example only works for\n keys that are valid Python identifiers. Otherwise, any valid keys\n can be used.\n\n These are the operations that dictionaries support (and therefore,\n custom mapping types should support too):\n\n len(d)\n\n Return the number of items in the dictionary *d*.\n\n d[key]\n\n Return the item of *d* with key *key*. Raises a ``KeyError`` if\n *key* is not in the map.\n\n If a subclass of dict defines a method ``__missing__()``, if the\n key *key* is not present, the ``d[key]`` operation calls that\n method with the key *key* as argument. The ``d[key]`` operation\n then returns or raises whatever is returned or raised by the\n ``__missing__(key)`` call if the key is not present. No other\n operations or methods invoke ``__missing__()``. If\n ``__missing__()`` is not defined, ``KeyError`` is raised.\n ``__missing__()`` must be a method; it cannot be an instance\n variable:\n\n >>> class Counter(dict):\n ... def __missing__(self, key):\n ... return 0\n >>> c = Counter()\n >>> c[\'red\']\n 0\n >>> c[\'red\'] += 1\n >>> c[\'red\']\n 1\n\n See ``collections.Counter`` for a complete implementation\n including other methods helpful for accumulating and managing\n tallies.\n\n d[key] = value\n\n Set ``d[key]`` to *value*.\n\n del d[key]\n\n Remove ``d[key]`` from *d*. Raises a ``KeyError`` if *key* is\n not in the map.\n\n key in d\n\n Return ``True`` if *d* has a key *key*, else ``False``.\n\n key not in d\n\n Equivalent to ``not key in d``.\n\n iter(d)\n\n Return an iterator over the keys of the dictionary. This is a\n shortcut for ``iter(d.keys())``.\n\n clear()\n\n Remove all items from the dictionary.\n\n copy()\n\n Return a shallow copy of the dictionary.\n\n classmethod fromkeys(seq[, value])\n\n Create a new dictionary with keys from *seq* and values set to\n *value*.\n\n ``fromkeys()`` is a class method that returns a new dictionary.\n *value* defaults to ``None``.\n\n get(key[, default])\n\n Return the value for *key* if *key* is in the dictionary, else\n *default*. If *default* is not given, it defaults to ``None``,\n so that this method never raises a ``KeyError``.\n\n items()\n\n Return a new view of the dictionary\'s items (``(key, value)``\n pairs). See the *documentation of view objects*.\n\n keys()\n\n Return a new view of the dictionary\'s keys. See the\n *documentation of view objects*.\n\n pop(key[, default])\n\n If *key* is in the dictionary, remove it and return its value,\n else return *default*. If *default* is not given and *key* is\n not in the dictionary, a ``KeyError`` is raised.\n\n popitem()\n\n Remove and return an arbitrary ``(key, value)`` pair from the\n dictionary.\n\n ``popitem()`` is useful to destructively iterate over a\n dictionary, as often used in set algorithms. If the dictionary\n is empty, calling ``popitem()`` raises a ``KeyError``.\n\n setdefault(key[, default])\n\n If *key* is in the dictionary, return its value. If not, insert\n *key* with a value of *default* and return *default*. *default*\n defaults to ``None``.\n\n update([other])\n\n Update the dictionary with the key/value pairs from *other*,\n overwriting existing keys. Return ``None``.\n\n ``update()`` accepts either another dictionary object or an\n iterable of key/value pairs (as tuples or other iterables of\n length two). If keyword arguments are specified, the dictionary\n is then updated with those key/value pairs: ``d.update(red=1,\n blue=2)``.\n\n values()\n\n Return a new view of the dictionary\'s values. See the\n *documentation of view objects*.\n\nSee also:\n\n ``types.MappingProxyType`` can be used to create a read-only view\n of a ``dict``.\n\n\nDictionary view objects\n=======================\n\nThe objects returned by ``dict.keys()``, ``dict.values()`` and\n``dict.items()`` are *view objects*. They provide a dynamic view on\nthe dictionary\'s entries, which means that when the dictionary\nchanges, the view reflects these changes.\n\nDictionary views can be iterated over to yield their respective data,\nand support membership tests:\n\nlen(dictview)\n\n Return the number of entries in the dictionary.\n\niter(dictview)\n\n Return an iterator over the keys, values or items (represented as\n tuples of ``(key, value)``) in the dictionary.\n\n Keys and values are iterated over in an arbitrary order which is\n non-random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If keys,\n values and items views are iterated over with no intervening\n modifications to the dictionary, the order of items will directly\n correspond. This allows the creation of ``(value, key)`` pairs\n using ``zip()``: ``pairs = zip(d.values(), d.keys())``. Another\n way to create the same list is ``pairs = [(v, k) for (k, v) in\n d.items()]``.\n\n Iterating views while adding or deleting entries in the dictionary\n may raise a ``RuntimeError`` or fail to iterate over all entries.\n\nx in dictview\n\n Return ``True`` if *x* is in the underlying dictionary\'s keys,\n values or items (in the latter case, *x* should be a ``(key,\n value)`` tuple).\n\nKeys views are set-like since their entries are unique and hashable.\nIf all values are hashable, so that ``(key, value)`` pairs are unique\nand hashable, then the items view is also set-like. (Values views are\nnot treated as set-like since the entries are generally not unique.)\nFor set-like views, all of the operations defined for the abstract\nbase class ``collections.abc.Set`` are available (for example, ``==``,\n``<``, or ``^``).\n\nAn example of dictionary view usage:\n\n >>> dishes = {\'eggs\': 2, \'sausage\': 1, \'bacon\': 1, \'spam\': 500}\n >>> keys = dishes.keys()\n >>> values = dishes.values()\n\n >>> # iteration\n >>> n = 0\n >>> for val in values:\n ... n += val\n >>> print(n)\n 504\n\n >>> # keys and values are iterated over in the same order\n >>> list(keys)\n [\'eggs\', \'bacon\', \'sausage\', \'spam\']\n >>> list(values)\n [2, 1, 1, 500]\n\n >>> # view objects are dynamic and reflect dict changes\n >>> del dishes[\'eggs\']\n >>> del dishes[\'sausage\']\n >>> list(keys)\n [\'spam\', \'bacon\']\n\n >>> # set operations\n >>> keys & {\'eggs\', \'bacon\', \'salad\'}\n {\'bacon\'}\n >>> keys ^ {\'sausage\', \'juice\'}\n {\'juice\', \'sausage\', \'bacon\', \'spam\'}\n', - 'typesmethods': '\nMethods\n*******\n\nMethods are functions that are called using the attribute notation.\nThere are two flavors: built-in methods (such as ``append()`` on\nlists) and class instance methods. Built-in methods are described\nwith the types that support them.\n\nIf you access a method (a function defined in a class namespace)\nthrough an instance, you get a special object: a *bound method* (also\ncalled *instance method*) object. When called, it will add the\n``self`` argument to the argument list. Bound methods have two\nspecial read-only attributes: ``m.__self__`` is the object on which\nthe method operates, and ``m.__func__`` is the function implementing\nthe method. Calling ``m(arg-1, arg-2, ..., arg-n)`` is completely\nequivalent to calling ``m.__func__(m.__self__, arg-1, arg-2, ...,\narg-n)``.\n\nLike function objects, bound method objects support getting arbitrary\nattributes. However, since method attributes are actually stored on\nthe underlying function object (``meth.__func__``), setting method\nattributes on bound methods is disallowed. Attempting to set an\nattribute on a method results in an ``AttributeError`` being raised.\nIn order to set a method attribute, you need to explicitly set it on\nthe underlying function object:\n\n >>> class C:\n ... def method(self):\n ... pass\n ...\n >>> c = C()\n >>> c.method.whoami = \'my name is method\' # can\'t set on the method\n Traceback (most recent call last):\n File "", line 1, in \n AttributeError: \'method\' object has no attribute \'whoami\'\n >>> c.method.__func__.whoami = \'my name is method\'\n >>> c.method.whoami\n \'my name is method\'\n\nSee *The standard type hierarchy* for more information.\n', - 'typesmodules': "\nModules\n*******\n\nThe only special operation on a module is attribute access:\n``m.name``, where *m* is a module and *name* accesses a name defined\nin *m*'s symbol table. Module attributes can be assigned to. (Note\nthat the ``import`` statement is not, strictly speaking, an operation\non a module object; ``import foo`` does not require a module object\nnamed *foo* to exist, rather it requires an (external) *definition*\nfor a module named *foo* somewhere.)\n\nA special attribute of every module is ``__dict__``. This is the\ndictionary containing the module's symbol table. Modifying this\ndictionary will actually change the module's symbol table, but direct\nassignment to the ``__dict__`` attribute is not possible (you can\nwrite ``m.__dict__['a'] = 1``, which defines ``m.a`` to be ``1``, but\nyou can't write ``m.__dict__ = {}``). Modifying ``__dict__`` directly\nis not recommended.\n\nModules built into the interpreter are written like this: ````. If loaded from a file, they are written as\n````.\n", - 'typesseq': '\nSequence Types --- ``list``, ``tuple``, ``range``\n*************************************************\n\nThere are three basic sequence types: lists, tuples, and range\nobjects. Additional sequence types tailored for processing of *binary\ndata* and *text strings* are described in dedicated sections.\n\n\nCommon Sequence Operations\n==========================\n\nThe operations in the following table are supported by most sequence\ntypes, both mutable and immutable. The ``collections.abc.Sequence``\nABC is provided to make it easier to correctly implement these\noperations on custom sequence types.\n\nThis table lists the sequence operations sorted in ascending priority\n(operations in the same box have the same priority). In the table,\n*s* and *t* are sequences of the same type, *n*, *i*, *j* and *k* are\nintegers and *x* is an arbitrary object that meets any type and value\nrestrictions imposed by *s*.\n\nThe ``in`` and ``not in`` operations have the same priorities as the\ncomparison operations. The ``+`` (concatenation) and ``*``\n(repetition) operations have the same priority as the corresponding\nnumeric operations.\n\n+----------------------------+----------------------------------+------------+\n| Operation | Result | Notes |\n+============================+==================================+============+\n| ``x in s`` | ``True`` if an item of *s* is | (1) |\n| | equal to *x*, else ``False`` | |\n+----------------------------+----------------------------------+------------+\n| ``x not in s`` | ``False`` if an item of *s* is | (1) |\n| | equal to *x*, else ``True`` | |\n+----------------------------+----------------------------------+------------+\n| ``s + t`` | the concatenation of *s* and *t* | (6)(7) |\n+----------------------------+----------------------------------+------------+\n| ``s * n`` or ``n * s`` | *n* shallow copies of *s* | (2)(7) |\n| | concatenated | |\n+----------------------------+----------------------------------+------------+\n| ``s[i]`` | *i*th item of *s*, origin 0 | (3) |\n+----------------------------+----------------------------------+------------+\n| ``s[i:j]`` | slice of *s* from *i* to *j* | (3)(4) |\n+----------------------------+----------------------------------+------------+\n| ``s[i:j:k]`` | slice of *s* from *i* to *j* | (3)(5) |\n| | with step *k* | |\n+----------------------------+----------------------------------+------------+\n| ``len(s)`` | length of *s* | |\n+----------------------------+----------------------------------+------------+\n| ``min(s)`` | smallest item of *s* | |\n+----------------------------+----------------------------------+------------+\n| ``max(s)`` | largest item of *s* | |\n+----------------------------+----------------------------------+------------+\n| ``s.index(x[, i[, j]])`` | index of the first occurrence of | (8) |\n| | *x* in *s* (at or after index | |\n| | *i* and before index *j*) | |\n+----------------------------+----------------------------------+------------+\n| ``s.count(x)`` | total number of occurrences of | |\n| | *x* in *s* | |\n+----------------------------+----------------------------------+------------+\n\nSequences of the same type also support comparisons. In particular,\ntuples and lists are compared lexicographically by comparing\ncorresponding elements. This means that to compare equal, every\nelement must compare equal and the two sequences must be of the same\ntype and have the same length. (For full details see *Comparisons* in\nthe language reference.)\n\nNotes:\n\n1. While the ``in`` and ``not in`` operations are used only for simple\n containment testing in the general case, some specialised sequences\n (such as ``str``, ``bytes`` and ``bytearray``) also use them for\n subsequence testing:\n\n >>> "gg" in "eggs"\n True\n\n2. Values of *n* less than ``0`` are treated as ``0`` (which yields an\n empty sequence of the same type as *s*). Note also that the copies\n are shallow; nested structures are not copied. This often haunts\n new Python programmers; consider:\n\n >>> lists = [[]] * 3\n >>> lists\n [[], [], []]\n >>> lists[0].append(3)\n >>> lists\n [[3], [3], [3]]\n\n What has happened is that ``[[]]`` is a one-element list containing\n an empty list, so all three elements of ``[[]] * 3`` are (pointers\n to) this single empty list. Modifying any of the elements of\n ``lists`` modifies this single list. You can create a list of\n different lists this way:\n\n >>> lists = [[] for i in range(3)]\n >>> lists[0].append(3)\n >>> lists[1].append(5)\n >>> lists[2].append(7)\n >>> lists\n [[3], [5], [7]]\n\n3. If *i* or *j* is negative, the index is relative to the end of the\n string: ``len(s) + i`` or ``len(s) + j`` is substituted. But note\n that ``-0`` is still ``0``.\n\n4. The slice of *s* from *i* to *j* is defined as the sequence of\n items with index *k* such that ``i <= k < j``. If *i* or *j* is\n greater than ``len(s)``, use ``len(s)``. If *i* is omitted or\n ``None``, use ``0``. If *j* is omitted or ``None``, use\n ``len(s)``. If *i* is greater than or equal to *j*, the slice is\n empty.\n\n5. The slice of *s* from *i* to *j* with step *k* is defined as the\n sequence of items with index ``x = i + n*k`` such that ``0 <= n <\n (j-i)/k``. In other words, the indices are ``i``, ``i+k``,\n ``i+2*k``, ``i+3*k`` and so on, stopping when *j* is reached (but\n never including *j*). If *i* or *j* is greater than ``len(s)``,\n use ``len(s)``. If *i* or *j* are omitted or ``None``, they become\n "end" values (which end depends on the sign of *k*). Note, *k*\n cannot be zero. If *k* is ``None``, it is treated like ``1``.\n\n6. Concatenating immutable sequences always results in a new object.\n This means that building up a sequence by repeated concatenation\n will have a quadratic runtime cost in the total sequence length.\n To get a linear runtime cost, you must switch to one of the\n alternatives below:\n\n * if concatenating ``str`` objects, you can build a list and use\n ``str.join()`` at the end or else write to a ``io.StringIO``\n instance and retrieve its value when complete\n\n * if concatenating ``bytes`` objects, you can similarly use\n ``bytes.join()`` or ``io.BytesIO``, or you can do in-place\n concatenation with a ``bytearray`` object. ``bytearray`` objects\n are mutable and have an efficient overallocation mechanism\n\n * if concatenating ``tuple`` objects, extend a ``list`` instead\n\n * for other types, investigate the relevant class documentation\n\n7. Some sequence types (such as ``range``) only support item sequences\n that follow specific patterns, and hence don\'t support sequence\n concatenation or repetition.\n\n8. ``index`` raises ``ValueError`` when *x* is not found in *s*. When\n supported, the additional arguments to the index method allow\n efficient searching of subsections of the sequence. Passing the\n extra arguments is roughly equivalent to using ``s[i:j].index(x)``,\n only without copying any data and with the returned index being\n relative to the start of the sequence rather than the start of the\n slice.\n\n\nImmutable Sequence Types\n========================\n\nThe only operation that immutable sequence types generally implement\nthat is not also implemented by mutable sequence types is support for\nthe ``hash()`` built-in.\n\nThis support allows immutable sequences, such as ``tuple`` instances,\nto be used as ``dict`` keys and stored in ``set`` and ``frozenset``\ninstances.\n\nAttempting to hash an immutable sequence that contains unhashable\nvalues will result in ``TypeError``.\n\n\nMutable Sequence Types\n======================\n\nThe operations in the following table are defined on mutable sequence\ntypes. The ``collections.abc.MutableSequence`` ABC is provided to make\nit easier to correctly implement these operations on custom sequence\ntypes.\n\nIn the table *s* is an instance of a mutable sequence type, *t* is any\niterable object and *x* is an arbitrary object that meets any type and\nvalue restrictions imposed by *s* (for example, ``bytearray`` only\naccepts integers that meet the value restriction ``0 <= x <= 255``).\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | appends *x* to the end of the | |\n| | sequence (same as | |\n| | ``s[len(s):len(s)] = [x]``) | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.clear()`` | removes all items from ``s`` | (5) |\n| | (same as ``del s[:]``) | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.copy()`` | creates a shallow copy of ``s`` | (5) |\n| | (same as ``s[:]``) | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(t)`` | extends *s* with the contents of | |\n| | *t* (same as ``s[len(s):len(s)] | |\n| | = t``) | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | inserts *x* into *s* at the | |\n| | index given by *i* (same as | |\n| | ``s[i:i] = [x]``) | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | retrieves the item at *i* and | (2) |\n| | also removes it from *s* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | remove the first item from *s* | (3) |\n| | where ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (4) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n3. ``remove`` raises ``ValueError`` when *x* is not found in *s*.\n\n4. The ``reverse()`` method modifies the sequence in place for economy\n of space when reversing a large sequence. To remind users that it\n operates by side effect, it does not return the reversed sequence.\n\n5. ``clear()`` and ``copy()`` are included for consistency with the\n interfaces of mutable containers that don\'t support slicing\n operations (such as ``dict`` and ``set``)\n\n New in version 3.3: ``clear()`` and ``copy()`` methods.\n\n\nLists\n=====\n\nLists are mutable sequences, typically used to store collections of\nhomogeneous items (where the precise degree of similarity will vary by\napplication).\n\nclass class list([iterable])\n\n Lists may be constructed in several ways:\n\n * Using a pair of square brackets to denote the empty list: ``[]``\n\n * Using square brackets, separating items with commas: ``[a]``,\n ``[a, b, c]``\n\n * Using a list comprehension: ``[x for x in iterable]``\n\n * Using the type constructor: ``list()`` or ``list(iterable)``\n\n The constructor builds a list whose items are the same and in the\n same order as *iterable*\'s items. *iterable* may be either a\n sequence, a container that supports iteration, or an iterator\n object. If *iterable* is already a list, a copy is made and\n returned, similar to ``iterable[:]``. For example, ``list(\'abc\')``\n returns ``[\'a\', \'b\', \'c\']`` and ``list( (1, 2, 3) )`` returns ``[1,\n 2, 3]``. If no argument is given, the constructor creates a new\n empty list, ``[]``.\n\n Many other operations also produce lists, including the\n ``sorted()`` built-in.\n\n Lists implement all of the *common* and *mutable* sequence\n operations. Lists also provide the following additional method:\n\n sort(*, key=None, reverse=None)\n\n This method sorts the list in place, using only ``<``\n comparisons between items. Exceptions are not suppressed - if\n any comparison operations fail, the entire sort operation will\n fail (and the list will likely be left in a partially modified\n state).\n\n ``sort()`` accepts two arguments that can only be passed by\n keyword (*keyword-only arguments*):\n\n *key* specifies a function of one argument that is used to\n extract a comparison key from each list element (for example,\n ``key=str.lower``). The key corresponding to each item in the\n list is calculated once and then used for the entire sorting\n process. The default value of ``None`` means that list items are\n sorted directly without calculating a separate key value.\n\n The ``functools.cmp_to_key()`` utility is available to convert a\n 2.x style *cmp* function to a *key* function.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n This method modifies the sequence in place for economy of space\n when sorting a large sequence. To remind users that it operates\n by side effect, it does not return the sorted sequence (use\n ``sorted()`` to explicitly request a new sorted list instance).\n\n The ``sort()`` method is guaranteed to be stable. A sort is\n stable if it guarantees not to change the relative order of\n elements that compare equal --- this is helpful for sorting in\n multiple passes (for example, sort by department, then by salary\n grade).\n\n **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python makes the list appear\n empty for the duration, and raises ``ValueError`` if it can\n detect that the list has been mutated during a sort.\n\n\nTuples\n======\n\nTuples are immutable sequences, typically used to store collections of\nheterogeneous data (such as the 2-tuples produced by the\n``enumerate()`` built-in). Tuples are also used for cases where an\nimmutable sequence of homogeneous data is needed (such as allowing\nstorage in a ``set`` or ``dict`` instance).\n\nclass class tuple([iterable])\n\n Tuples may be constructed in a number of ways:\n\n * Using a pair of parentheses to denote the empty tuple: ``()``\n\n * Using a trailing comma for a singleton tuple: ``a,`` or ``(a,)``\n\n * Separating items with commas: ``a, b, c`` or ``(a, b, c)``\n\n * Using the ``tuple()`` built-in: ``tuple()`` or\n ``tuple(iterable)``\n\n The constructor builds a tuple whose items are the same and in the\n same order as *iterable*\'s items. *iterable* may be either a\n sequence, a container that supports iteration, or an iterator\n object. If *iterable* is already a tuple, it is returned\n unchanged. For example, ``tuple(\'abc\')`` returns ``(\'a\', \'b\',\n \'c\')`` and ``tuple( [1, 2, 3] )`` returns ``(1, 2, 3)``. If no\n argument is given, the constructor creates a new empty tuple,\n ``()``.\n\n Note that it is actually the comma which makes a tuple, not the\n parentheses. The parentheses are optional, except in the empty\n tuple case, or when they are needed to avoid syntactic ambiguity.\n For example, ``f(a, b, c)`` is a function call with three\n arguments, while ``f((a, b, c))`` is a function call with a 3-tuple\n as the sole argument.\n\n Tuples implement all of the *common* sequence operations.\n\nFor heterogeneous collections of data where access by name is clearer\nthan access by index, ``collections.namedtuple()`` may be a more\nappropriate choice than a simple tuple object.\n\n\nRanges\n======\n\nThe ``range`` type represents an immutable sequence of numbers and is\ncommonly used for looping a specific number of times in ``for`` loops.\n\nclass class range(stop)\nclass class range(start, stop[, step])\n\n The arguments to the range constructor must be integers (either\n built-in ``int`` or any object that implements the ``__index__``\n special method). If the *step* argument is omitted, it defaults to\n ``1``. If the *start* argument is omitted, it defaults to ``0``. If\n *step* is zero, ``ValueError`` is raised.\n\n For a positive *step*, the contents of a range ``r`` are determined\n by the formula ``r[i] = start + step*i`` where ``i >= 0`` and\n ``r[i] < stop``.\n\n For a negative *step*, the contents of the range are still\n determined by the formula ``r[i] = start + step*i``, but the\n constraints are ``i >= 0`` and ``r[i] > stop``.\n\n A range object will be empty if ``r[0]`` does not meet the value\n constraint. Ranges do support negative indices, but these are\n interpreted as indexing from the end of the sequence determined by\n the positive indices.\n\n Ranges containing absolute values larger than ``sys.maxsize`` are\n permitted but some features (such as ``len()``) may raise\n ``OverflowError``.\n\n Range examples:\n\n >>> list(range(10))\n [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n >>> list(range(1, 11))\n [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n >>> list(range(0, 30, 5))\n [0, 5, 10, 15, 20, 25]\n >>> list(range(0, 10, 3))\n [0, 3, 6, 9]\n >>> list(range(0, -10, -1))\n [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]\n >>> list(range(0))\n []\n >>> list(range(1, 0))\n []\n\n Ranges implement all of the *common* sequence operations except\n concatenation and repetition (due to the fact that range objects\n can only represent sequences that follow a strict pattern and\n repetition and concatenation will usually violate that pattern).\n\nThe advantage of the ``range`` type over a regular ``list`` or\n``tuple`` is that a ``range`` object will always take the same (small)\namount of memory, no matter the size of the range it represents (as it\nonly stores the ``start``, ``stop`` and ``step`` values, calculating\nindividual items and subranges as needed).\n\nRange objects implement the ``collections.abc.Sequence`` ABC, and\nprovide features such as containment tests, element index lookup,\nslicing and support for negative indices (see *Sequence Types ---\nlist, tuple, range*):\n\n>>> r = range(0, 20, 2)\n>>> r\nrange(0, 20, 2)\n>>> 11 in r\nFalse\n>>> 10 in r\nTrue\n>>> r.index(10)\n5\n>>> r[5]\n10\n>>> r[:5]\nrange(0, 10, 2)\n>>> r[-1]\n18\n\nTesting range objects for equality with ``==`` and ``!=`` compares\nthem as sequences. That is, two range objects are considered equal if\nthey represent the same sequence of values. (Note that two range\nobjects that compare equal might have different ``start``, ``stop``\nand ``step`` attributes, for example ``range(0) == range(2, 1, 3)`` or\n``range(0, 3, 2) == range(0, 4, 2)``.)\n\nChanged in version 3.2: Implement the Sequence ABC. Support slicing\nand negative indices. Test ``int`` objects for membership in constant\ntime instead of iterating through all items.\n\nChanged in version 3.3: Define \'==\' and \'!=\' to compare range objects\nbased on the sequence of values they define (instead of comparing\nbased on object identity).\n\nNew in version 3.3: The ``start``, ``stop`` and ``step`` attributes.\n', - 'typesseq-mutable': "\nMutable Sequence Types\n**********************\n\nThe operations in the following table are defined on mutable sequence\ntypes. The ``collections.abc.MutableSequence`` ABC is provided to make\nit easier to correctly implement these operations on custom sequence\ntypes.\n\nIn the table *s* is an instance of a mutable sequence type, *t* is any\niterable object and *x* is an arbitrary object that meets any type and\nvalue restrictions imposed by *s* (for example, ``bytearray`` only\naccepts integers that meet the value restriction ``0 <= x <= 255``).\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | appends *x* to the end of the | |\n| | sequence (same as | |\n| | ``s[len(s):len(s)] = [x]``) | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.clear()`` | removes all items from ``s`` | (5) |\n| | (same as ``del s[:]``) | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.copy()`` | creates a shallow copy of ``s`` | (5) |\n| | (same as ``s[:]``) | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(t)`` | extends *s* with the contents of | |\n| | *t* (same as ``s[len(s):len(s)] | |\n| | = t``) | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | inserts *x* into *s* at the | |\n| | index given by *i* (same as | |\n| | ``s[i:i] = [x]``) | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | retrieves the item at *i* and | (2) |\n| | also removes it from *s* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | remove the first item from *s* | (3) |\n| | where ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (4) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n3. ``remove`` raises ``ValueError`` when *x* is not found in *s*.\n\n4. The ``reverse()`` method modifies the sequence in place for economy\n of space when reversing a large sequence. To remind users that it\n operates by side effect, it does not return the reversed sequence.\n\n5. ``clear()`` and ``copy()`` are included for consistency with the\n interfaces of mutable containers that don't support slicing\n operations (such as ``dict`` and ``set``)\n\n New in version 3.3: ``clear()`` and ``copy()`` methods.\n", - 'unary': '\nUnary arithmetic and bitwise operations\n***************************************\n\nAll unary arithmetic and bitwise operations have the same priority:\n\n u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr\n\nThe unary ``-`` (minus) operator yields the negation of its numeric\nargument.\n\nThe unary ``+`` (plus) operator yields its numeric argument unchanged.\n\nThe unary ``~`` (invert) operator yields the bitwise inversion of its\ninteger argument. The bitwise inversion of ``x`` is defined as\n``-(x+1)``. It only applies to integral numbers.\n\nIn all three cases, if the argument does not have the proper type, a\n``TypeError`` exception is raised.\n', - 'while': '\nThe ``while`` statement\n***********************\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n', - 'with': '\nThe ``with`` statement\n**********************\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the ``with_item``)\n is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nChanged in version 3.1: Support for multiple context expressions.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n', - 'yield': '\nThe ``yield`` statement\n***********************\n\n yield_stmt ::= yield_expression\n\nThe ``yield`` statement is only used when defining a generator\nfunction, and is only used in the body of the generator function.\nUsing a ``yield`` statement in a function definition is sufficient to\ncause that definition to create a generator function instead of a\nnormal function.\n\nWhen a generator function is called, it returns an iterator known as a\ngenerator iterator, or more commonly, a generator. The body of the\ngenerator function is executed by calling the ``next()`` function on\nthe generator repeatedly until it raises an exception.\n\nWhen a ``yield`` statement is executed, the state of the generator is\nfrozen and the value of ``expression_list`` is returned to\n``next()``\'s caller. By "frozen" we mean that all local state is\nretained, including the current bindings of local variables, the\ninstruction pointer, and the internal evaluation stack: enough\ninformation is saved so that the next time ``next()`` is invoked, the\nfunction can proceed exactly as if the ``yield`` statement were just\nanother external call.\n\nThe ``yield`` statement is allowed in the ``try`` clause of a ``try``\n... ``finally`` construct. If the generator is not resumed before it\nis finalized (by reaching a zero reference count or by being garbage\ncollected), the generator-iterator\'s ``close()`` method will be\ncalled, allowing any pending ``finally`` clauses to execute.\n\nWhen ``yield from `` is used, it treats the supplied expression\nas a subiterator, producing values from it until the underlying\niterator is exhausted.\n\n Changed in version 3.3: Added ``yield from `` to delegate\n control flow to a subiterator\n\nFor full details of ``yield`` semantics, refer to the *Yield\nexpressions* section.\n\nSee also:\n\n **PEP 0255** - Simple Generators\n The proposal for adding generators and the ``yield`` statement\n to Python.\n\n **PEP 0342** - Coroutines via Enhanced Generators\n The proposal to enhance the API and syntax of generators, making\n them usable as simple coroutines.\n\n **PEP 0380** - Syntax for Delegating to a Subgenerator\n The proposal to introduce the ``yield_from`` syntax, making\n delegation to sub-generators easy.\n'} +# Autogenerated by Sphinx on Sat May 23 17:38:41 2015 +topics = {'assert': u'\nThe "assert" statement\n**********************\n\nAssert statements are a convenient way to insert debugging assertions\ninto a program:\n\n assert_stmt ::= "assert" expression ["," expression]\n\nThe simple form, "assert expression", is equivalent to\n\n if __debug__:\n if not expression: raise AssertionError\n\nThe extended form, "assert expression1, expression2", is equivalent to\n\n if __debug__:\n if not expression1: raise AssertionError(expression2)\n\nThese equivalences assume that "__debug__" and "AssertionError" refer\nto the built-in variables with those names. In the current\nimplementation, the built-in variable "__debug__" is "True" under\nnormal circumstances, "False" when optimization is requested (command\nline option -O). The current code generator emits no code for an\nassert statement when optimization is requested at compile time. Note\nthat it is unnecessary to include the source code for the expression\nthat failed in the error message; it will be displayed as part of the\nstack trace.\n\nAssignments to "__debug__" are illegal. The value for the built-in\nvariable is determined when the interpreter starts.\n', + 'assignment': u'\nAssignment statements\n*********************\n\nAssignment statements are used to (re)bind names to values and to\nmodify attributes or items of mutable objects:\n\n assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression)\n target_list ::= target ("," target)* [","]\n target ::= identifier\n | "(" target_list ")"\n | "[" target_list "]"\n | attributeref\n | subscription\n | slicing\n | "*" target\n\n(See section *Primaries* for the syntax definitions for\n*attributeref*, *subscription*, and *slicing*.)\n\nAn assignment statement evaluates the expression list (remember that\nthis can be a single expression or a comma-separated list, the latter\nyielding a tuple) and assigns the single resulting object to each of\nthe target lists, from left to right.\n\nAssignment is defined recursively depending on the form of the target\n(list). When a target is part of a mutable object (an attribute\nreference, subscription or slicing), the mutable object must\nultimately perform the assignment and decide about its validity, and\nmay raise an exception if the assignment is unacceptable. The rules\nobserved by various types and the exceptions raised are given with the\ndefinition of the object types (see section *The standard type\nhierarchy*).\n\nAssignment of an object to a target list, optionally enclosed in\nparentheses or square brackets, is recursively defined as follows.\n\n* If the target list is a single target: The object is assigned to\n that target.\n\n* If the target list is a comma-separated list of targets: The\n object must be an iterable with the same number of items as there\n are targets in the target list, and the items are assigned, from\n left to right, to the corresponding targets.\n\n * If the target list contains one target prefixed with an\n asterisk, called a "starred" target: The object must be a sequence\n with at least as many items as there are targets in the target\n list, minus one. The first items of the sequence are assigned,\n from left to right, to the targets before the starred target. The\n final items of the sequence are assigned to the targets after the\n starred target. A list of the remaining items in the sequence is\n then assigned to the starred target (the list can be empty).\n\n * Else: The object must be a sequence with the same number of\n items as there are targets in the target list, and the items are\n assigned, from left to right, to the corresponding targets.\n\nAssignment of an object to a single target is recursively defined as\nfollows.\n\n* If the target is an identifier (name):\n\n * If the name does not occur in a "global" or "nonlocal" statement\n in the current code block: the name is bound to the object in the\n current local namespace.\n\n * Otherwise: the name is bound to the object in the global\n namespace or the outer namespace determined by "nonlocal",\n respectively.\n\n The name is rebound if it was already bound. This may cause the\n reference count for the object previously bound to the name to reach\n zero, causing the object to be deallocated and its destructor (if it\n has one) to be called.\n\n* If the target is a target list enclosed in parentheses or in\n square brackets: The object must be an iterable with the same number\n of items as there are targets in the target list, and its items are\n assigned, from left to right, to the corresponding targets.\n\n* If the target is an attribute reference: The primary expression in\n the reference is evaluated. It should yield an object with\n assignable attributes; if this is not the case, "TypeError" is\n raised. That object is then asked to assign the assigned object to\n the given attribute; if it cannot perform the assignment, it raises\n an exception (usually but not necessarily "AttributeError").\n\n Note: If the object is a class instance and the attribute reference\n occurs on both sides of the assignment operator, the RHS expression,\n "a.x" can access either an instance attribute or (if no instance\n attribute exists) a class attribute. The LHS target "a.x" is always\n set as an instance attribute, creating it if necessary. Thus, the\n two occurrences of "a.x" do not necessarily refer to the same\n attribute: if the RHS expression refers to a class attribute, the\n LHS creates a new instance attribute as the target of the\n assignment:\n\n class Cls:\n x = 3 # class variable\n inst = Cls()\n inst.x = inst.x + 1 # writes inst.x as 4 leaving Cls.x as 3\n\n This description does not necessarily apply to descriptor\n attributes, such as properties created with "property()".\n\n* If the target is a subscription: The primary expression in the\n reference is evaluated. It should yield either a mutable sequence\n object (such as a list) or a mapping object (such as a dictionary).\n Next, the subscript expression is evaluated.\n\n If the primary is a mutable sequence object (such as a list), the\n subscript must yield an integer. If it is negative, the sequence\'s\n length is added to it. The resulting value must be a nonnegative\n integer less than the sequence\'s length, and the sequence is asked\n to assign the assigned object to its item with that index. If the\n index is out of range, "IndexError" is raised (assignment to a\n subscripted sequence cannot add new items to a list).\n\n If the primary is a mapping object (such as a dictionary), the\n subscript must have a type compatible with the mapping\'s key type,\n and the mapping is then asked to create a key/datum pair which maps\n the subscript to the assigned object. This can either replace an\n existing key/value pair with the same key value, or insert a new\n key/value pair (if no key with the same value existed).\n\n For user-defined objects, the "__setitem__()" method is called with\n appropriate arguments.\n\n* If the target is a slicing: The primary expression in the\n reference is evaluated. It should yield a mutable sequence object\n (such as a list). The assigned object should be a sequence object\n of the same type. Next, the lower and upper bound expressions are\n evaluated, insofar they are present; defaults are zero and the\n sequence\'s length. The bounds should evaluate to integers. If\n either bound is negative, the sequence\'s length is added to it. The\n resulting bounds are clipped to lie between zero and the sequence\'s\n length, inclusive. Finally, the sequence object is asked to replace\n the slice with the items of the assigned sequence. The length of\n the slice may be different from the length of the assigned sequence,\n thus changing the length of the target sequence, if the target\n sequence allows it.\n\n**CPython implementation detail:** In the current implementation, the\nsyntax for targets is taken to be the same as for expressions, and\ninvalid syntax is rejected during the code generation phase, causing\nless detailed error messages.\n\nAlthough the definition of assignment implies that overlaps between\nthe left-hand side and the right-hand side are \'simultanenous\' (for\nexample "a, b = b, a" swaps two variables), overlaps *within* the\ncollection of assigned-to variables occur left-to-right, sometimes\nresulting in confusion. For instance, the following program prints\n"[0, 2]":\n\n x = [0, 1]\n i = 0\n i, x[i] = 1, 2 # i is updated, then x[i] is updated\n print(x)\n\nSee also: **PEP 3132** - Extended Iterable Unpacking\n\n The specification for the "*target" feature.\n\n\nAugmented assignment statements\n===============================\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions of the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like "x += 1" can be rewritten as\n"x = x + 1" to achieve a similar, but not exactly equal effect. In the\naugmented version, "x" is only evaluated once. Also, when possible,\nthe actual operation is performed *in-place*, meaning that rather than\ncreating a new object and assigning that to the target, the old object\nis modified instead.\n\nUnlike normal assignments, augmented assignments evaluate the left-\nhand side *before* evaluating the right-hand side. For example, "a[i]\n+= f(x)" first looks-up "a[i]", then it evaluates "f(x)" and performs\nthe addition, and lastly, it writes the result back to "a[i]".\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n', + 'atom-identifiers': u'\nIdentifiers (Names)\n*******************\n\nAn identifier occurring as an atom is a name. See section\n*Identifiers and keywords* for lexical definition and section *Naming\nand binding* for documentation of naming and binding.\n\nWhen the name is bound to an object, evaluation of the atom yields\nthat object. When a name is not bound, an attempt to evaluate it\nraises a "NameError" exception.\n\n**Private name mangling:** When an identifier that textually occurs in\na class definition begins with two or more underscore characters and\ndoes not end in two or more underscores, it is considered a *private\nname* of that class. Private names are transformed to a longer form\nbefore code is generated for them. The transformation inserts the\nclass name, with leading underscores removed and a single underscore\ninserted, in front of the name. For example, the identifier "__spam"\noccurring in a class named "Ham" will be transformed to "_Ham__spam".\nThis transformation is independent of the syntactical context in which\nthe identifier is used. If the transformed name is extremely long\n(longer than 255 characters), implementation defined truncation may\nhappen. If the class name consists only of underscores, no\ntransformation is done.\n', + 'atom-literals': u"\nLiterals\n********\n\nPython supports string and bytes literals and various numeric\nliterals:\n\n literal ::= stringliteral | bytesliteral\n | integer | floatnumber | imagnumber\n\nEvaluation of a literal yields an object of the given type (string,\nbytes, integer, floating point number, complex number) with the given\nvalue. The value may be approximated in the case of floating point\nand imaginary (complex) literals. See section *Literals* for details.\n\nAll literals correspond to immutable data types, and hence the\nobject's identity is less important than its value. Multiple\nevaluations of literals with the same value (either the same\noccurrence in the program text or a different occurrence) may obtain\nthe same object or a different object with the same value.\n", + 'attribute-access': u'\nCustomizing attribute access\n****************************\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of "x.name") for\nclass instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for "self"). "name" is the attribute name. This\n method should return the (computed) attribute value or raise an\n "AttributeError" exception.\n\n Note that if the attribute is found through the normal mechanism,\n "__getattr__()" is not called. (This is an intentional asymmetry\n between "__getattr__()" and "__setattr__()".) This is done both for\n efficiency reasons and because otherwise "__getattr__()" would have\n no way to access other attributes of the instance. Note that at\n least for instance variables, you can fake total control by not\n inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n "__getattribute__()" method below for a way to actually get total\n control over attribute access.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines "__getattr__()",\n the latter will not be called unless "__getattribute__()" either\n calls it explicitly or raises an "AttributeError". This method\n should return the (computed) attribute value or raise an\n "AttributeError" exception. In order to avoid infinite recursion in\n this method, its implementation should always call the base class\n method with the same name to access any attributes it needs, for\n example, "object.__getattribute__(self, name)".\n\n Note: This method may still be bypassed when looking up special\n methods as the result of implicit invocation via language syntax\n or built-in functions. See *Special method lookup*.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If "__setattr__()" wants to assign to an instance attribute, it\n should call the base class method with the same name, for example,\n "object.__setattr__(self, name, value)".\n\nobject.__delattr__(self, name)\n\n Like "__setattr__()" but for attribute deletion instead of\n assignment. This should only be implemented if "del obj.name" is\n meaningful for the object.\n\nobject.__dir__(self)\n\n Called when "dir()" is called on the object. A sequence must be\n returned. "dir()" converts the returned sequence to a list and\n sorts it.\n\n\nImplementing Descriptors\n========================\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in an\n*owner* class (the descriptor must be in either the owner\'s class\ndictionary or in the class dictionary for one of its parents). In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' "__dict__".\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or "None" when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an "AttributeError"\n exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\nThe attribute "__objclass__" is interpreted by the "inspect" module as\nspecifying the class where this object was defined (setting this\nappropriately can assist in runtime introspection of dynamic class\nattributes). For callables, it may indicate that an instance of the\ngiven type (or a subclass) is expected or required as the first\npositional argument (for example, CPython sets this attribute for\nunbound methods that are implemented in C).\n\n\nInvoking Descriptors\n====================\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: "__get__()", "__set__()", and\n"__delete__()". If any of those methods are defined for an object, it\nis said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, "a.x" has a\nlookup chain starting with "a.__dict__[\'x\']", then\n"type(a).__dict__[\'x\']", and continuing through the base classes of\n"type(a)" excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called.\n\nThe starting point for descriptor invocation is a binding, "a.x". How\nthe arguments are assembled depends on "a":\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: "x.__get__(a)".\n\nInstance Binding\n If binding to an object instance, "a.x" is transformed into the\n call: "type(a).__dict__[\'x\'].__get__(a, type(a))".\n\nClass Binding\n If binding to a class, "A.x" is transformed into the call:\n "A.__dict__[\'x\'].__get__(None, A)".\n\nSuper Binding\n If "a" is an instance of "super", then the binding "super(B,\n obj).m()" searches "obj.__class__.__mro__" for the base class "A"\n immediately preceding "B" and then invokes the descriptor with the\n call: "A.__dict__[\'m\'].__get__(obj, obj.__class__)".\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of "__get__()", "__set__()" and "__delete__()". If it\ndoes not define "__get__()", then accessing the attribute will return\nthe descriptor object itself unless there is a value in the object\'s\ninstance dictionary. If the descriptor defines "__set__()" and/or\n"__delete__()", it is a data descriptor; if it defines neither, it is\na non-data descriptor. Normally, data descriptors define both\n"__get__()" and "__set__()", while non-data descriptors have just the\n"__get__()" method. Data descriptors with "__set__()" and "__get__()"\ndefined always override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances.\n\nPython methods (including "staticmethod()" and "classmethod()") are\nimplemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe "property()" function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n=========\n\nBy default, instances of classes have a dictionary for attribute\nstorage. This wastes space for objects having very few instance\nvariables. The space consumption can become acute when creating large\nnumbers of instances.\n\nThe default can be overridden by defining *__slots__* in a class\ndefinition. The *__slots__* declaration takes a sequence of instance\nvariables and reserves just enough space in each instance to hold a\nvalue for each variable. Space is saved because *__dict__* is not\ncreated for each instance.\n\nobject.__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. *__slots__*\n reserves space for the declared variables and prevents the\n automatic creation of *__dict__* and *__weakref__* for each\n instance.\n\n\nNotes on using *__slots__*\n--------------------------\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises "AttributeError". If\n dynamic assignment of new variables is desired, then add\n "\'__dict__\'" to the sequence of strings in the *__slots__*\n declaration.\n\n* Without a *__weakref__* variable for each instance, classes\n defining *__slots__* do not support weak references to its\n instances. If weak reference support is needed, then add\n "\'__weakref__\'" to the sequence of strings in the *__slots__*\n declaration.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the\n instance variable defined by the base class slot is inaccessible\n (except by retrieving its descriptor directly from the base class).\n This renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as "int", "bytes" and "tuple".\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings\n may also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n', + 'attribute-references': u'\nAttribute references\n********************\n\nAn attribute reference is a primary followed by a period and a name:\n\n attributeref ::= primary "." identifier\n\nThe primary must evaluate to an object of a type that supports\nattribute references, which most objects do. This object is then\nasked to produce the attribute whose name is the identifier. This\nproduction can be customized by overriding the "__getattr__()" method.\nIf this attribute is not available, the exception "AttributeError" is\nraised. Otherwise, the type and value of the object produced is\ndetermined by the object. Multiple evaluations of the same attribute\nreference may yield different objects.\n', + 'augassign': u'\nAugmented assignment statements\n*******************************\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions of the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like "x += 1" can be rewritten as\n"x = x + 1" to achieve a similar, but not exactly equal effect. In the\naugmented version, "x" is only evaluated once. Also, when possible,\nthe actual operation is performed *in-place*, meaning that rather than\ncreating a new object and assigning that to the target, the old object\nis modified instead.\n\nUnlike normal assignments, augmented assignments evaluate the left-\nhand side *before* evaluating the right-hand side. For example, "a[i]\n+= f(x)" first looks-up "a[i]", then it evaluates "f(x)" and performs\nthe addition, and lastly, it writes the result back to "a[i]".\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n', + 'binary': u'\nBinary arithmetic operations\n****************************\n\nThe binary arithmetic operations have the conventional priority\nlevels. Note that some of these operations also apply to certain non-\nnumeric types. Apart from the power operator, there are only two\nlevels, one for multiplicative operators and one for additive\noperators:\n\n m_expr ::= u_expr | m_expr "*" u_expr | m_expr "@" m_expr |\n m_expr "//" u_expr| m_expr "/" u_expr |\n m_expr "%" u_expr\n a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr\n\nThe "*" (multiplication) operator yields the product of its arguments.\nThe arguments must either both be numbers, or one argument must be an\ninteger and the other must be a sequence. In the former case, the\nnumbers are converted to a common type and then multiplied together.\nIn the latter case, sequence repetition is performed; a negative\nrepetition factor yields an empty sequence.\n\nThe "@" (at) operator is intended to be used for matrix\nmultiplication. No builtin Python types implement this operator.\n\nNew in version 3.5.\n\nThe "/" (division) and "//" (floor division) operators yield the\nquotient of their arguments. The numeric arguments are first\nconverted to a common type. Division of integers yields a float, while\nfloor division of integers results in an integer; the result is that\nof mathematical division with the \'floor\' function applied to the\nresult. Division by zero raises the "ZeroDivisionError" exception.\n\nThe "%" (modulo) operator yields the remainder from the division of\nthe first argument by the second. The numeric arguments are first\nconverted to a common type. A zero right argument raises the\n"ZeroDivisionError" exception. The arguments may be floating point\nnumbers, e.g., "3.14%0.7" equals "0.34" (since "3.14" equals "4*0.7 +\n0.34".) The modulo operator always yields a result with the same sign\nas its second operand (or zero); the absolute value of the result is\nstrictly smaller than the absolute value of the second operand [1].\n\nThe floor division and modulo operators are connected by the following\nidentity: "x == (x//y)*y + (x%y)". Floor division and modulo are also\nconnected with the built-in function "divmod()": "divmod(x, y) ==\n(x//y, x%y)". [2].\n\nIn addition to performing the modulo operation on numbers, the "%"\noperator is also overloaded by string objects to perform old-style\nstring formatting (also known as interpolation). The syntax for\nstring formatting is described in the Python Library Reference,\nsection *printf-style String Formatting*.\n\nThe floor division operator, the modulo operator, and the "divmod()"\nfunction are not defined for complex numbers. Instead, convert to a\nfloating point number using the "abs()" function if appropriate.\n\nThe "+" (addition) operator yields the sum of its arguments. The\narguments must either both be numbers or both be sequences of the same\ntype. In the former case, the numbers are converted to a common type\nand then added together. In the latter case, the sequences are\nconcatenated.\n\nThe "-" (subtraction) operator yields the difference of its arguments.\nThe numeric arguments are first converted to a common type.\n', + 'bitwise': u'\nBinary bitwise operations\n*************************\n\nEach of the three bitwise operations has a different priority level:\n\n and_expr ::= shift_expr | and_expr "&" shift_expr\n xor_expr ::= and_expr | xor_expr "^" and_expr\n or_expr ::= xor_expr | or_expr "|" xor_expr\n\nThe "&" operator yields the bitwise AND of its arguments, which must\nbe integers.\n\nThe "^" operator yields the bitwise XOR (exclusive OR) of its\narguments, which must be integers.\n\nThe "|" operator yields the bitwise (inclusive) OR of its arguments,\nwhich must be integers.\n', + 'bltin-code-objects': u'\nCode Objects\n************\n\nCode objects are used by the implementation to represent "pseudo-\ncompiled" executable Python code such as a function body. They differ\nfrom function objects because they don\'t contain a reference to their\nglobal execution environment. Code objects are returned by the built-\nin "compile()" function and can be extracted from function objects\nthrough their "__code__" attribute. See also the "code" module.\n\nA code object can be executed or evaluated by passing it (instead of a\nsource string) to the "exec()" or "eval()" built-in functions.\n\nSee *The standard type hierarchy* for more information.\n', + 'bltin-ellipsis-object': u'\nThe Ellipsis Object\n*******************\n\nThis object is commonly used by slicing (see *Slicings*). It supports\nno special operations. There is exactly one ellipsis object, named\n"Ellipsis" (a built-in name). "type(Ellipsis)()" produces the\n"Ellipsis" singleton.\n\nIt is written as "Ellipsis" or "...".\n', + 'bltin-null-object': u'\nThe Null Object\n***************\n\nThis object is returned by functions that don\'t explicitly return a\nvalue. It supports no special operations. There is exactly one null\nobject, named "None" (a built-in name). "type(None)()" produces the\nsame singleton.\n\nIt is written as "None".\n', + 'bltin-type-objects': u'\nType Objects\n************\n\nType objects represent the various object types. An object\'s type is\naccessed by the built-in function "type()". There are no special\noperations on types. The standard module "types" defines names for\nall standard built-in types.\n\nTypes are written like this: "".\n', + 'booleans': u'\nBoolean operations\n******************\n\n or_test ::= and_test | or_test "or" and_test\n and_test ::= not_test | and_test "and" not_test\n not_test ::= comparison | "not" not_test\n\nIn the context of Boolean operations, and also when expressions are\nused by control flow statements, the following values are interpreted\nas false: "False", "None", numeric zero of all types, and empty\nstrings and containers (including strings, tuples, lists,\ndictionaries, sets and frozensets). All other values are interpreted\nas true. User-defined objects can customize their truth value by\nproviding a "__bool__()" method.\n\nThe operator "not" yields "True" if its argument is false, "False"\notherwise.\n\nThe expression "x and y" first evaluates *x*; if *x* is false, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\nThe expression "x or y" first evaluates *x*; if *x* is true, its value\nis returned; otherwise, *y* is evaluated and the resulting value is\nreturned.\n\n(Note that neither "and" nor "or" restrict the value and type they\nreturn to "False" and "True", but rather return the last evaluated\nargument. This is sometimes useful, e.g., if "s" is a string that\nshould be replaced by a default value if it is empty, the expression\n"s or \'foo\'" yields the desired value. Because "not" has to create a\nnew value, it returns a boolean value regardless of the type of its\nargument (for example, "not \'foo\'" produces "False" rather than "\'\'".)\n', + 'break': u'\nThe "break" statement\n*********************\n\n break_stmt ::= "break"\n\n"break" may only occur syntactically nested in a "for" or "while"\nloop, but not nested in a function or class definition within that\nloop.\n\nIt terminates the nearest enclosing loop, skipping the optional "else"\nclause if the loop has one.\n\nIf a "for" loop is terminated by "break", the loop control target\nkeeps its current value.\n\nWhen "break" passes control out of a "try" statement with a "finally"\nclause, that "finally" clause is executed before really leaving the\nloop.\n', + 'callable-types': u'\nEmulating callable objects\n**************************\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, "x(arg1, arg2, ...)" is a shorthand for\n "x.__call__(arg1, arg2, ...)".\n', + 'calls': u'\nCalls\n*****\n\nA call calls a callable object (e.g., a *function*) with a possibly\nempty series of *arguments*:\n\n call ::= primary "(" [argument_list [","] | comprehension] ")"\n argument_list ::= positional_arguments ["," keyword_arguments]\n ["," "*" expression] ["," keyword_arguments]\n ["," "**" expression]\n | keyword_arguments ["," "*" expression]\n ["," keyword_arguments] ["," "**" expression]\n | "*" expression ["," keyword_arguments] ["," "**" expression]\n | "**" expression\n positional_arguments ::= expression ("," expression)*\n keyword_arguments ::= keyword_item ("," keyword_item)*\n keyword_item ::= identifier "=" expression\n\nAn optional trailing comma may be present after the positional and\nkeyword arguments but does not affect the semantics.\n\nThe primary must evaluate to a callable object (user-defined\nfunctions, built-in functions, methods of built-in objects, class\nobjects, methods of class instances, and all objects having a\n"__call__()" method are callable). All argument expressions are\nevaluated before the call is attempted. Please refer to section\n*Function definitions* for the syntax of formal *parameter* lists.\n\nIf keyword arguments are present, they are first converted to\npositional arguments, as follows. First, a list of unfilled slots is\ncreated for the formal parameters. If there are N positional\narguments, they are placed in the first N slots. Next, for each\nkeyword argument, the identifier is used to determine the\ncorresponding slot (if the identifier is the same as the first formal\nparameter name, the first slot is used, and so on). If the slot is\nalready filled, a "TypeError" exception is raised. Otherwise, the\nvalue of the argument is placed in the slot, filling it (even if the\nexpression is "None", it fills the slot). When all arguments have\nbeen processed, the slots that are still unfilled are filled with the\ncorresponding default value from the function definition. (Default\nvalues are calculated, once, when the function is defined; thus, a\nmutable object such as a list or dictionary used as default value will\nbe shared by all calls that don\'t specify an argument value for the\ncorresponding slot; this should usually be avoided.) If there are any\nunfilled slots for which no default value is specified, a "TypeError"\nexception is raised. Otherwise, the list of filled slots is used as\nthe argument list for the call.\n\n**CPython implementation detail:** An implementation may provide\nbuilt-in functions whose positional parameters do not have names, even\nif they are \'named\' for the purpose of documentation, and which\ntherefore cannot be supplied by keyword. In CPython, this is the case\nfor functions implemented in C that use "PyArg_ParseTuple()" to parse\ntheir arguments.\n\nIf there are more positional arguments than there are formal parameter\nslots, a "TypeError" exception is raised, unless a formal parameter\nusing the syntax "*identifier" is present; in this case, that formal\nparameter receives a tuple containing the excess positional arguments\n(or an empty tuple if there were no excess positional arguments).\n\nIf any keyword argument does not correspond to a formal parameter\nname, a "TypeError" exception is raised, unless a formal parameter\nusing the syntax "**identifier" is present; in this case, that formal\nparameter receives a dictionary containing the excess keyword\narguments (using the keywords as keys and the argument values as\ncorresponding values), or a (new) empty dictionary if there were no\nexcess keyword arguments.\n\nIf the syntax "*expression" appears in the function call, "expression"\nmust evaluate to an iterable. Elements from this iterable are treated\nas if they were additional positional arguments; if there are\npositional arguments *x1*, ..., *xN*, and "expression" evaluates to a\nsequence *y1*, ..., *yM*, this is equivalent to a call with M+N\npositional arguments *x1*, ..., *xN*, *y1*, ..., *yM*.\n\nA consequence of this is that although the "*expression" syntax may\nappear *after* some keyword arguments, it is processed *before* the\nkeyword arguments (and the "**expression" argument, if any -- see\nbelow). So:\n\n >>> def f(a, b):\n ... print(a, b)\n ...\n >>> f(b=1, *(2,))\n 2 1\n >>> f(a=1, *(2,))\n Traceback (most recent call last):\n File "", line 1, in ?\n TypeError: f() got multiple values for keyword argument \'a\'\n >>> f(1, *(2,))\n 1 2\n\nIt is unusual for both keyword arguments and the "*expression" syntax\nto be used in the same call, so in practice this confusion does not\narise.\n\nIf the syntax "**expression" appears in the function call,\n"expression" must evaluate to a mapping, the contents of which are\ntreated as additional keyword arguments. In the case of a keyword\nappearing in both "expression" and as an explicit keyword argument, a\n"TypeError" exception is raised.\n\nFormal parameters using the syntax "*identifier" or "**identifier"\ncannot be used as positional argument slots or as keyword argument\nnames.\n\nA call always returns some value, possibly "None", unless it raises an\nexception. How this value is computed depends on the type of the\ncallable object.\n\nIf it is---\n\na user-defined function:\n The code block for the function is executed, passing it the\n argument list. The first thing the code block will do is bind the\n formal parameters to the arguments; this is described in section\n *Function definitions*. When the code block executes a "return"\n statement, this specifies the return value of the function call.\n\na built-in function or method:\n The result is up to the interpreter; see *Built-in Functions* for\n the descriptions of built-in functions and methods.\n\na class object:\n A new instance of that class is returned.\n\na class instance method:\n The corresponding user-defined function is called, with an argument\n list that is one longer than the argument list of the call: the\n instance becomes the first argument.\n\na class instance:\n The class must define a "__call__()" method; the effect is then the\n same as if that method was called.\n', + 'class': u'\nClass definitions\n*****************\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= [decorators] "class" classname [inheritance] ":" suite\n inheritance ::= "(" [parameter_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. The inheritance list\nusually gives a list of base classes (see *Customizing class creation*\nfor more advanced uses), so each item in the list should evaluate to a\nclass object which allows subclassing. Classes without an inheritance\nlist inherit, by default, from the base class "object"; hence,\n\n class Foo:\n pass\n\nis equivalent to\n\n class Foo(object):\n pass\n\nThe class\'s suite is then executed in a new execution frame (see\n*Naming and binding*), using a newly created local namespace and the\noriginal global namespace. (Usually, the suite contains mostly\nfunction definitions.) When the class\'s suite finishes execution, its\nexecution frame is discarded but its local namespace is saved. [4] A\nclass object is then created using the inheritance list for the base\nclasses and the saved local namespace for the attribute dictionary.\nThe class name is bound to this class object in the original local\nnamespace.\n\nClass creation can be customized heavily using *metaclasses*.\n\nClasses can also be decorated: just like when decorating functions,\n\n @f1(arg)\n @f2\n class Foo: pass\n\nis equivalent to\n\n class Foo: pass\n Foo = f1(arg)(f2(Foo))\n\nThe evaluation rules for the decorator expressions are the same as for\nfunction decorators. The result must be a class object, which is then\nbound to the class name.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass attributes; they are shared by instances. Instance attributes\ncan be set in a method with "self.name = value". Both class and\ninstance attributes are accessible through the notation ""self.name"",\nand an instance attribute hides a class attribute with the same name\nwhen accessed in this way. Class attributes can be used as defaults\nfor instance attributes, but using mutable values there can lead to\nunexpected results. *Descriptors* can be used to create instance\nvariables with different implementation details.\n\nSee also: **PEP 3115** - Metaclasses in Python 3 **PEP 3129** -\n Class Decorators\n', + 'comparisons': u'\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like "a < b < c" have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: "True" or "False".\n\nComparisons can be chained arbitrarily, e.g., "x < y <= z" is\nequivalent to "x < y and y <= z", except that "y" is evaluated only\nonce (but in both cases "z" is not evaluated at all when "x < y" is\nfound to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then "a op1 b op2 c ... y\nopN z" is equivalent to "a op1 b and b op2 c and ... y opN z", except\nthat each expression is evaluated at most once.\n\nNote that "a op1 b op2 c" doesn\'t imply any kind of comparison between\n*a* and *c*, so that, e.g., "x < y > z" is perfectly legal (though\nperhaps not pretty).\n\nThe operators "<", ">", "==", ">=", "<=", and "!=" compare the values\nof two objects. The objects need not have the same type. If both are\nnumbers, they are converted to a common type. Otherwise, the "==" and\n"!=" operators *always* consider objects of different types to be\nunequal, while the "<", ">", ">=" and "<=" operators raise a\n"TypeError" when comparing objects of different types that do not\nimplement these operators for the given pair of types. You can\ncontrol comparison behavior of objects of non-built-in types by\ndefining rich comparison methods like "__gt__()", described in section\n*Basic customization*.\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* The values "float(\'NaN\')" and "Decimal(\'NaN\')" are special. They\n are identical to themselves, "x is x" but are not equal to\n themselves, "x != x". Additionally, comparing any value to a\n not-a-number value will return "False". For example, both "3 <\n float(\'NaN\')" and "float(\'NaN\') < 3" will return "False".\n\n* Bytes objects are compared lexicographically using the numeric\n values of their elements.\n\n* Strings are compared lexicographically using the numeric\n equivalents (the result of the built-in function "ord()") of their\n characters. [3] String and bytes object can\'t be compared!\n\n* Tuples and lists are compared lexicographically using comparison\n of corresponding elements. This means that to compare equal, each\n element must compare equal and the two sequences must be of the same\n type and have the same length.\n\n If not equal, the sequences are ordered the same as their first\n differing elements. For example, "[1,2,x] <= [1,2,y]" has the same\n value as "x <= y". If the corresponding element does not exist, the\n shorter sequence is ordered first (for example, "[1,2] < [1,2,3]").\n\n* Mappings (dictionaries) compare equal if and only if they have the\n same "(key, value)" pairs. Order comparisons "(\'<\', \'<=\', \'>=\',\n \'>\')" raise "TypeError".\n\n* Sets and frozensets define comparison operators to mean subset and\n superset tests. Those relations do not define total orderings (the\n two sets "{1,2}" and {2,3} are not equal, nor subsets of one\n another, nor supersets of one another). Accordingly, sets are not\n appropriate arguments for functions which depend on total ordering.\n For example, "min()", "max()", and "sorted()" produce undefined\n results given a list of sets as inputs.\n\n* Most other objects of built-in types compare unequal unless they\n are the same object; the choice whether one object is considered\n smaller or larger than another one is made arbitrarily but\n consistently within one execution of a program.\n\nComparison of objects of differing types depends on whether either of\nthe types provide explicit support for the comparison. Most numeric\ntypes can be compared with one another. When cross-type comparison is\nnot supported, the comparison method returns "NotImplemented".\n\nThe operators "in" and "not in" test for membership. "x in s"\nevaluates to true if *x* is a member of *s*, and false otherwise. "x\nnot in s" returns the negation of "x in s". All built-in sequences\nand set types support this as well as dictionary, for which "in" tests\nwhether the dictionary has a given key. For container types such as\nlist, tuple, set, frozenset, dict, or collections.deque, the\nexpression "x in y" is equivalent to "any(x is e or x == e for e in\ny)".\n\nFor the string and bytes types, "x in y" is true if and only if *x* is\na substring of *y*. An equivalent test is "y.find(x) != -1". Empty\nstrings are always considered to be a substring of any other string,\nso """ in "abc"" will return "True".\n\nFor user-defined classes which define the "__contains__()" method, "x\nin y" is true if and only if "y.__contains__(x)" is true.\n\nFor user-defined classes which do not define "__contains__()" but do\ndefine "__iter__()", "x in y" is true if some value "z" with "x == z"\nis produced while iterating over "y". If an exception is raised\nduring the iteration, it is as if "in" raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n"__getitem__()", "x in y" is true if and only if there is a non-\nnegative integer index *i* such that "x == y[i]", and all lower\ninteger indices do not raise "IndexError" exception. (If any other\nexception is raised, it is as if "in" raised that exception).\n\nThe operator "not in" is defined to have the inverse true value of\n"in".\n\nThe operators "is" and "is not" test for object identity: "x is y" is\ntrue if and only if *x* and *y* are the same object. "x is not y"\nyields the inverse truth value. [4]\n', + 'compound': u'\nCompound statements\n*******************\n\nCompound statements contain (groups of) other statements; they affect\nor control the execution of those other statements in some way. In\ngeneral, compound statements span multiple lines, although in simple\nincarnations a whole compound statement may be contained in one line.\n\nThe "if", "while" and "for" statements implement traditional control\nflow constructs. "try" specifies exception handlers and/or cleanup\ncode for a group of statements, while the "with" statement allows the\nexecution of initialization and finalization code around a block of\ncode. Function and class definitions are also syntactically compound\nstatements.\n\nA compound statement consists of one or more \'clauses.\' A clause\nconsists of a header and a \'suite.\' The clause headers of a\nparticular compound statement are all at the same indentation level.\nEach clause header begins with a uniquely identifying keyword and ends\nwith a colon. A suite is a group of statements controlled by a\nclause. A suite can be one or more semicolon-separated simple\nstatements on the same line as the header, following the header\'s\ncolon, or it can be one or more indented statements on subsequent\nlines. Only the latter form of a suite can contain nested compound\nstatements; the following is illegal, mostly because it wouldn\'t be\nclear to which "if" clause a following "else" clause would belong:\n\n if test1: if test2: print(x)\n\nAlso note that the semicolon binds tighter than the colon in this\ncontext, so that in the following example, either all or none of the\n"print()" calls are executed:\n\n if x < y < z: print(x); print(y); print(z)\n\nSummarizing:\n\n compound_stmt ::= if_stmt\n | while_stmt\n | for_stmt\n | try_stmt\n | with_stmt\n | funcdef\n | classdef\n | async_with_stmt\n | async_for_stmt\n | async_funcdef\n suite ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT\n statement ::= stmt_list NEWLINE | compound_stmt\n stmt_list ::= simple_stmt (";" simple_stmt)* [";"]\n\nNote that statements always end in a "NEWLINE" possibly followed by a\n"DEDENT". Also note that optional continuation clauses always begin\nwith a keyword that cannot start a statement, thus there are no\nambiguities (the \'dangling "else"\' problem is solved in Python by\nrequiring nested "if" statements to be indented).\n\nThe formatting of the grammar rules in the following sections places\neach clause on a separate line for clarity.\n\n\nThe "if" statement\n==================\n\nThe "if" statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the "if" statement is executed or evaluated).\nIf all expressions are false, the suite of the "else" clause, if\npresent, is executed.\n\n\nThe "while" statement\n=====================\n\nThe "while" statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the "else" clause, if present, is executed\nand the loop terminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite. A "continue" statement\nexecuted in the first suite skips the rest of the suite and goes back\nto testing the expression.\n\n\nThe "for" statement\n===================\n\nThe "for" statement is used to iterate over the elements of a sequence\n(such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n"expression_list". The suite is then executed once for each item\nprovided by the iterator, in the order returned by the iterator. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments (see *Assignment statements*), and then the suite is\nexecuted. When the items are exhausted (which is immediately when the\nsequence is empty or an iterator raises a "StopIteration" exception),\nthe suite in the "else" clause, if present, is executed, and the loop\nterminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite. A "continue" statement\nexecuted in the first suite skips the rest of the suite and continues\nwith the next item, or with the "else" clause if there is no next\nitem.\n\nThe for-loop makes assignments to the variables(s) in the target list.\nThis overwrites all previous assignments to those variables including\nthose made in the suite of the for-loop:\n\n for i in range(10):\n print(i)\n i = 5 # this will not affect the for-loop\n # because i will be overwritten with the next\n # index in the range\n\nNames in the target list are not deleted when the loop is finished,\nbut if the sequence is empty, they will not have been assigned to at\nall by the loop. Hint: the built-in function "range()" returns an\niterator of integers suitable to emulate the effect of Pascal\'s "for i\n:= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, 2]".\n\nNote: There is a subtlety when the sequence is being modified by the\n loop (this can only occur for mutable sequences, i.e. lists). An\n internal counter is used to keep track of which item is used next,\n and this is incremented on each iteration. When this counter has\n reached the length of the sequence the loop terminates. This means\n that if the suite deletes the current (or a previous) item from the\n sequence, the next item will be skipped (since it gets the index of\n the current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n\n\nThe "try" statement\n===================\n\nThe "try" statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression ["as" identifier]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nThe "except" clause(s) specify one or more exception handlers. When no\nexception occurs in the "try" clause, no exception handler is\nexecuted. When an exception occurs in the "try" suite, a search for an\nexception handler is started. This search inspects the except clauses\nin turn until one is found that matches the exception. An expression-\nless except clause, if present, must be last; it matches any\nexception. For an except clause with an expression, that expression\nis evaluated, and the clause matches the exception if the resulting\nobject is "compatible" with the exception. An object is compatible\nwith an exception if it is the class or a base class of the exception\nobject or a tuple containing an item compatible with the exception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire "try" statement raised\nthe exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified after the "as" keyword in that except clause, if\npresent, and the except clause\'s suite is executed. All except\nclauses must have an executable block. When the end of this block is\nreached, execution continues normally after the entire try statement.\n(This means that if two nested handlers exist for the same exception,\nand the exception occurs in the try clause of the inner handler, the\nouter handler will not handle the exception.)\n\nWhen an exception has been assigned using "as target", it is cleared\nat the end of the except clause. This is as if\n\n except E as N:\n foo\n\nwas translated to\n\n except E as N:\n try:\n foo\n finally:\n del N\n\nThis means the exception must be assigned to a different name to be\nable to refer to it after the except clause. Exceptions are cleared\nbecause with the traceback attached to them, they form a reference\ncycle with the stack frame, keeping all locals in that frame alive\nuntil the next garbage collection occurs.\n\nBefore an except clause\'s suite is executed, details about the\nexception are stored in the "sys" module and can be accessed via\n"sys.exc_info()". "sys.exc_info()" returns a 3-tuple consisting of the\nexception class, the exception instance and a traceback object (see\nsection *The standard type hierarchy*) identifying the point in the\nprogram where the exception occurred. "sys.exc_info()" values are\nrestored to their previous values (before the call) when returning\nfrom a function that handled an exception.\n\nThe optional "else" clause is executed if and when control flows off\nthe end of the "try" clause. [2] Exceptions in the "else" clause are\nnot handled by the preceding "except" clauses.\n\nIf "finally" is present, it specifies a \'cleanup\' handler. The "try"\nclause is executed, including any "except" and "else" clauses. If an\nexception occurs in any of the clauses and is not handled, the\nexception is temporarily saved. The "finally" clause is executed. If\nthere is a saved exception it is re-raised at the end of the "finally"\nclause. If the "finally" clause raises another exception, the saved\nexception is set as the context of the new exception. If the "finally"\nclause executes a "return" or "break" statement, the saved exception\nis discarded:\n\n >>> def f():\n ... try:\n ... 1/0\n ... finally:\n ... return 42\n ...\n >>> f()\n 42\n\nThe exception information is not available to the program during\nexecution of the "finally" clause.\n\nWhen a "return", "break" or "continue" statement is executed in the\n"try" suite of a "try"..."finally" statement, the "finally" clause is\nalso executed \'on the way out.\' A "continue" statement is illegal in\nthe "finally" clause. (The reason is a problem with the current\nimplementation --- this restriction may be lifted in the future).\n\nThe return value of a function is determined by the last "return"\nstatement executed. Since the "finally" clause always executes, a\n"return" statement executed in the "finally" clause will always be the\nlast one executed:\n\n >>> def foo():\n ... try:\n ... return \'try\'\n ... finally:\n ... return \'finally\'\n ...\n >>> foo()\n \'finally\'\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the "raise" statement to\ngenerate exceptions may be found in section *The raise statement*.\n\n\nThe "with" statement\n====================\n\nThe "with" statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common "try"..."except"..."finally"\nusage patterns to be encapsulated for convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the "with" statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the "with_item")\n is evaluated to obtain a context manager.\n\n2. The context manager\'s "__exit__()" is loaded for later use.\n\n3. The context manager\'s "__enter__()" method is invoked.\n\n4. If a target was included in the "with" statement, the return\n value from "__enter__()" is assigned to it.\n\n Note: The "with" statement guarantees that if the "__enter__()"\n method returns without an error, then "__exit__()" will always be\n called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s "__exit__()" method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to "__exit__()". Otherwise, three\n "None" arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the "__exit__()" method was false, the exception is reraised.\n If the return value was true, the exception is suppressed, and\n execution continues with the statement following the "with"\n statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from "__exit__()" is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple "with" statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nChanged in version 3.1: Support for multiple context expressions.\n\nSee also: **PEP 0343** - The "with" statement\n\n The specification, background, and examples for the Python "with"\n statement.\n\n\nFunction definitions\n====================\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n funcdef ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [parameter_list [","]] ")"] NEWLINE\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n | "*" [parameter] ("," defparameter)* ["," "**" parameter]\n | "**" parameter\n | defparameter [","] )\n parameter ::= identifier [":" expression]\n defparameter ::= parameter ["=" expression]\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more *parameters* have the form *parameter* "="\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding *argument* may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters up until the ""*"" must also have a default value --- this\nis a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated from left to right when the\nfunction definition is executed.** This means that the expression is\nevaluated once, when the function is defined, and that the same "pre-\ncomputed" value is used for each call. This is especially important\nto understand when a default parameter is a mutable object, such as a\nlist or a dictionary: if the function modifies the object (e.g. by\nappending an item to a list), the default value is in effect modified.\nThis is generally not what was intended. A way around this is to use\n"None" as the default, and explicitly test for it in the body of the\nfunction, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n""*identifier"" is present, it is initialized to a tuple receiving any\nexcess positional parameters, defaulting to the empty tuple. If the\nform ""**identifier"" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after ""*"" or ""*identifier"" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "": expression"" following\nthe parameter name. Any parameter may have an annotation even those\nof the form "*identifier" or "**identifier". Functions may have\n"return" annotation of the form ""-> expression"" after the parameter\nlist. These annotations can be any valid Python expression and are\nevaluated when the function definition is executed. Annotations may\nbe evaluated in a different order than they appear in the source code.\nThe presence of annotations does not change the semantics of a\nfunction. The annotation values are available as values of a\ndictionary keyed by the parameters\' names in the "__annotations__"\nattribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda\nexpressions, described in section *Lambdas*. Note that the lambda\nexpression is merely a shorthand for a simplified function definition;\na function defined in a ""def"" statement can be passed around or\nassigned to another name just like a function defined by a lambda\nexpression. The ""def"" form is actually more powerful since it\nallows the execution of multiple statements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects. A ""def""\nstatement executed inside a function definition defines a local\nfunction that can be returned or passed around. Free variables used\nin the nested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n\nSee also: **PEP 3107** - Function Annotations\n\n The original specification for function annotations.\n\n\nClass definitions\n=================\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= [decorators] "class" classname [inheritance] ":" suite\n inheritance ::= "(" [parameter_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. The inheritance list\nusually gives a list of base classes (see *Customizing class creation*\nfor more advanced uses), so each item in the list should evaluate to a\nclass object which allows subclassing. Classes without an inheritance\nlist inherit, by default, from the base class "object"; hence,\n\n class Foo:\n pass\n\nis equivalent to\n\n class Foo(object):\n pass\n\nThe class\'s suite is then executed in a new execution frame (see\n*Naming and binding*), using a newly created local namespace and the\noriginal global namespace. (Usually, the suite contains mostly\nfunction definitions.) When the class\'s suite finishes execution, its\nexecution frame is discarded but its local namespace is saved. [4] A\nclass object is then created using the inheritance list for the base\nclasses and the saved local namespace for the attribute dictionary.\nThe class name is bound to this class object in the original local\nnamespace.\n\nClass creation can be customized heavily using *metaclasses*.\n\nClasses can also be decorated: just like when decorating functions,\n\n @f1(arg)\n @f2\n class Foo: pass\n\nis equivalent to\n\n class Foo: pass\n Foo = f1(arg)(f2(Foo))\n\nThe evaluation rules for the decorator expressions are the same as for\nfunction decorators. The result must be a class object, which is then\nbound to the class name.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass attributes; they are shared by instances. Instance attributes\ncan be set in a method with "self.name = value". Both class and\ninstance attributes are accessible through the notation ""self.name"",\nand an instance attribute hides a class attribute with the same name\nwhen accessed in this way. Class attributes can be used as defaults\nfor instance attributes, but using mutable values there can lead to\nunexpected results. *Descriptors* can be used to create instance\nvariables with different implementation details.\n\nSee also: **PEP 3115** - Metaclasses in Python 3 **PEP 3129** -\n Class Decorators\n\n\nCoroutines\n==========\n\n\nCoroutine function definition\n-----------------------------\n\n async_funcdef ::= "async" funcdef\n\nExecution of Python coroutines can be suspended and resumed at many\npoints (see *coroutine*.) "await" expressions, "async for" and "async\nwith" can only be used in their bodies.\n\nFunctions defined with "async def" syntax are always coroutine\nfunctions, even if they do not contain "await" or "async" keywords.\n\nIt is a "SyntaxError" to use "yield" expressions in coroutines.\n\nNew in version 3.5.\n\n\nThe "async for" statement\n-------------------------\n\n async_for_stmt ::= "async" for_stmt\n\nAn *asynchronous iterable* is able to call asynchronous code in its\n*iter* implementation, and *asynchronous iterator* can call\nasynchronous code in its *next* method.\n\nThe "async for" statement allows convenient iteration over\nasynchronous iterators.\n\nThe following code:\n\n async for TARGET in ITER:\n BLOCK\n else:\n BLOCK2\n\nIs semantically equivalent to:\n\n iter = (ITER)\n iter = await type(iter).__aiter__(iter)\n running = True\n while running:\n try:\n TARGET = await type(iter).__anext__(iter)\n except StopAsyncIteration:\n running = False\n else:\n BLOCK\n else:\n BLOCK2\n\nSee also "__aiter__()" and "__anext__()" for details.\n\nNew in version 3.5.\n\n\nThe "async with" statement\n--------------------------\n\n async_with_stmt ::= "async" with_stmt\n\nAn *asynchronous context manager* is a *context manager* that is able\nto suspend execution in its *enter* and *exit* methods.\n\nThe following code:\n\n async with EXPR as VAR:\n BLOCK\n\nIs semantically equivalent to:\n\n mgr = (EXPR)\n aexit = type(mgr).__aexit__\n aenter = type(mgr).__aenter__(mgr)\n exc = True\n\n VAR = await aenter\n try:\n BLOCK\n except:\n if not await aexit(mgr, *sys.exc_info()):\n raise\n else:\n await aexit(mgr, None, None, None)\n\nSee also "__aenter__()" and "__aexit__()" for details.\n\nNew in version 3.5.\n\nSee also: **PEP 492** - Coroutines with async and await syntax\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack unless\n there is a "finally" clause which happens to raise another\n exception. That new exception causes the old one to be lost.\n\n[2] Currently, control "flows off the end" except in the case of\n an exception or the execution of a "return", "continue", or\n "break" statement.\n\n[3] A string literal appearing as the first statement in the\n function body is transformed into the function\'s "__doc__"\n attribute and therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n body is transformed into the namespace\'s "__doc__" item and\n therefore the class\'s *docstring*.\n', + 'context-managers': u'\nWith Statement Context Managers\n*******************************\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a "with" statement. The context manager\nhandles the entry into, and the exit from, the desired runtime context\nfor the execution of the block of code. Context managers are normally\ninvoked using the "with" statement (described in section *The with\nstatement*), but can also be used by directly invoking their methods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The "with"\n statement will bind this method\'s return value to the target(s)\n specified in the "as" clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be "None".\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that "__exit__()" methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also: **PEP 0343** - The "with" statement\n\n The specification, background, and examples for the Python "with"\n statement.\n', + 'continue': u'\nThe "continue" statement\n************************\n\n continue_stmt ::= "continue"\n\n"continue" may only occur syntactically nested in a "for" or "while"\nloop, but not nested in a function or class definition or "finally"\nclause within that loop. It continues with the next cycle of the\nnearest enclosing loop.\n\nWhen "continue" passes control out of a "try" statement with a\n"finally" clause, that "finally" clause is executed before really\nstarting the next loop cycle.\n', + 'conversions': u'\nArithmetic conversions\n**********************\n\nWhen a description of an arithmetic operator below uses the phrase\n"the numeric arguments are converted to a common type," this means\nthat the operator implementation for built-in types works as follows:\n\n* If either argument is a complex number, the other is converted to\n complex;\n\n* otherwise, if either argument is a floating point number, the\n other is converted to floating point;\n\n* otherwise, both must be integers and no conversion is necessary.\n\nSome additional rules apply for certain operators (e.g., a string as a\nleft argument to the \'%\' operator). Extensions must define their own\nconversion behavior.\n', + 'customization': u'\nBasic customization\n*******************\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. "__new__()" is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of "__new__()" should be the new object instance (usually an\n instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s "__new__()" method using\n "super(currentclass, cls).__new__(cls[, ...])" with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If "__new__()" returns an instance of *cls*, then the new\n instance\'s "__init__()" method will be invoked like\n "__init__(self[, ...])", where *self* is the new instance and the\n remaining arguments are the same as were passed to "__new__()".\n\n If "__new__()" does not return an instance of *cls*, then the new\n instance\'s "__init__()" method will not be invoked.\n\n "__new__()" is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called after the instance has been created (by "__new__()"), but\n before it is returned to the caller. The arguments are those\n passed to the class constructor expression. If a base class has an\n "__init__()" method, the derived class\'s "__init__()" method, if\n any, must explicitly call it to ensure proper initialization of the\n base class part of the instance; for example:\n "BaseClass.__init__(self, [args...])".\n\n Because "__new__()" and "__init__()" work together in constructing\n objects ("__new__()" to create it, and "__init__()" to customise\n it), no non-"None" value may be returned by "__init__()"; doing so\n will cause a "TypeError" to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a "__del__()" method, the\n derived class\'s "__del__()" method, if any, must explicitly call it\n to ensure proper deletion of the base class part of the instance.\n Note that it is possible (though not recommended!) for the\n "__del__()" method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n "__del__()" methods are called for objects that still exist when\n the interpreter exits.\n\n Note: "del x" doesn\'t directly call "x.__del__()" --- the former\n decrements the reference count for "x" by one, and the latter is\n only called when "x"\'s reference count reaches zero. Some common\n situations that may prevent the reference count of an object from\n going to zero include: circular references between objects (e.g.,\n a doubly-linked list or a tree data structure with parent and\n child pointers); a reference to the object on the stack frame of\n a function that caught an exception (the traceback stored in\n "sys.exc_info()[2]" keeps the stack frame alive); or a reference\n to the object on the stack frame that raised an unhandled\n exception in interactive mode (the traceback stored in\n "sys.last_traceback" keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the second can be resolved by freeing the reference to the\n traceback object when it is no longer useful, and the third can\n be resolved by storing "None" in "sys.last_traceback". Circular\n references which are garbage are detected and cleaned up when the\n cyclic garbage collector is enabled (it\'s on by default). Refer\n to the documentation for the "gc" module for more information\n about this topic.\n\n Warning: Due to the precarious circumstances under which\n "__del__()" methods are invoked, exceptions that occur during\n their execution are ignored, and a warning is printed to\n "sys.stderr" instead. Also, when "__del__()" is invoked in\n response to a module being deleted (e.g., when execution of the\n program is done), other globals referenced by the "__del__()"\n method may already have been deleted or in the process of being\n torn down (e.g. the import machinery shutting down). For this\n reason, "__del__()" methods should do the absolute minimum needed\n to maintain external invariants. Starting with version 1.5,\n Python guarantees that globals whose name begins with a single\n underscore are deleted from their module before other globals are\n deleted; if no other references to such globals exist, this may\n help in assuring that imported modules are still available at the\n time when the "__del__()" method is called.\n\nobject.__repr__(self)\n\n Called by the "repr()" built-in function to compute the "official"\n string representation of an object. If at all possible, this\n should look like a valid Python expression that could be used to\n recreate an object with the same value (given an appropriate\n environment). If this is not possible, a string of the form\n "<...some useful description...>" should be returned. The return\n value must be a string object. If a class defines "__repr__()" but\n not "__str__()", then "__repr__()" is also used when an "informal"\n string representation of instances of that class is required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by "str(object)" and the built-in functions "format()" and\n "print()" to compute the "informal" or nicely printable string\n representation of an object. The return value must be a *string*\n object.\n\n This method differs from "object.__repr__()" in that there is no\n expectation that "__str__()" return a valid Python expression: a\n more convenient or concise representation can be used.\n\n The default implementation defined by the built-in type "object"\n calls "object.__repr__()".\n\nobject.__bytes__(self)\n\n Called by "bytes()" to compute a byte-string representation of an\n object. This should return a "bytes" object.\n\nobject.__format__(self, format_spec)\n\n Called by the "format()" built-in function (and by extension, the\n "str.format()" method of class "str") to produce a "formatted"\n string representation of an object. The "format_spec" argument is a\n string that contains a description of the formatting options\n desired. The interpretation of the "format_spec" argument is up to\n the type implementing "__format__()", however most classes will\n either delegate formatting to one of the built-in types, or use a\n similar formatting option syntax.\n\n See *Format Specification Mini-Language* for a description of the\n standard formatting syntax.\n\n The return value must be a string object.\n\n Changed in version 3.4: The __format__ method of "object" itself\n raises a "TypeError" if passed any non-empty string.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n These are the so-called "rich comparison" methods. The\n correspondence between operator symbols and method names is as\n follows: "xy" calls\n "x.__gt__(y)", and "x>=y" calls "x.__ge__(y)".\n\n A rich comparison method may return the singleton "NotImplemented"\n if it does not implement the operation for a given pair of\n arguments. By convention, "False" and "True" are returned for a\n successful comparison. However, these methods can return any value,\n so if the comparison operator is used in a Boolean context (e.g.,\n in the condition of an "if" statement), Python will call "bool()"\n on the value to determine if the result is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of "x==y" does not imply that "x!=y" is false.\n Accordingly, when defining "__eq__()", one should also define\n "__ne__()" so that the operators will behave as expected. See the\n paragraph on "__hash__()" for some important notes on creating\n *hashable* objects which support custom comparison operations and\n are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, "__lt__()" and "__gt__()" are each other\'s\n reflection, "__le__()" and "__ge__()" are each other\'s reflection,\n and "__eq__()" and "__ne__()" are their own reflection.\n\n Arguments to rich comparison methods are never coerced.\n\n To automatically generate ordering operations from a single root\n operation, see "functools.total_ordering()".\n\nobject.__hash__(self)\n\n Called by built-in function "hash()" and for operations on members\n of hashed collections including "set", "frozenset", and "dict".\n "__hash__()" should return an integer. The only required property\n is that objects which compare equal have the same hash value; it is\n advised to somehow mix together (e.g. using exclusive or) the hash\n values for the components of the object that also play a part in\n comparison of objects.\n\n Note: "hash()" truncates the value returned from an object\'s\n custom "__hash__()" method to the size of a "Py_ssize_t". This\n is typically 8 bytes on 64-bit builds and 4 bytes on 32-bit\n builds. If an object\'s "__hash__()" must interoperate on builds\n of different bit sizes, be sure to check the width on all\n supported builds. An easy way to do this is with "python -c\n "import sys; print(sys.hash_info.width)""\n\n If a class does not define an "__eq__()" method it should not\n define a "__hash__()" operation either; if it defines "__eq__()"\n but not "__hash__()", its instances will not be usable as items in\n hashable collections. If a class defines mutable objects and\n implements an "__eq__()" method, it should not implement\n "__hash__()", since the implementation of hashable collections\n requires that a key\'s hash value is immutable (if the object\'s hash\n value changes, it will be in the wrong hash bucket).\n\n User-defined classes have "__eq__()" and "__hash__()" methods by\n default; with them, all objects compare unequal (except with\n themselves) and "x.__hash__()" returns an appropriate value such\n that "x == y" implies both that "x is y" and "hash(x) == hash(y)".\n\n A class that overrides "__eq__()" and does not define "__hash__()"\n will have its "__hash__()" implicitly set to "None". When the\n "__hash__()" method of a class is "None", instances of the class\n will raise an appropriate "TypeError" when a program attempts to\n retrieve their hash value, and will also be correctly identified as\n unhashable when checking "isinstance(obj, collections.Hashable").\n\n If a class that overrides "__eq__()" needs to retain the\n implementation of "__hash__()" from a parent class, the interpreter\n must be told this explicitly by setting "__hash__ =\n .__hash__".\n\n If a class that does not override "__eq__()" wishes to suppress\n hash support, it should include "__hash__ = None" in the class\n definition. A class which defines its own "__hash__()" that\n explicitly raises a "TypeError" would be incorrectly identified as\n hashable by an "isinstance(obj, collections.Hashable)" call.\n\n Note: By default, the "__hash__()" values of str, bytes and\n datetime objects are "salted" with an unpredictable random value.\n Although they remain constant within an individual Python\n process, they are not predictable between repeated invocations of\n Python.This is intended to provide protection against a denial-\n of-service caused by carefully-chosen inputs that exploit the\n worst case performance of a dict insertion, O(n^2) complexity.\n See http://www.ocert.org/advisories/ocert-2011-003.html for\n details.Changing hash values affects the iteration order of\n dicts, sets and other mappings. Python has never made guarantees\n about this ordering (and it typically varies between 32-bit and\n 64-bit builds).See also "PYTHONHASHSEED".\n\n Changed in version 3.3: Hash randomization is enabled by default.\n\nobject.__bool__(self)\n\n Called to implement truth value testing and the built-in operation\n "bool()"; should return "False" or "True". When this method is not\n defined, "__len__()" is called, if it is defined, and the object is\n considered true if its result is nonzero. If a class defines\n neither "__len__()" nor "__bool__()", all its instances are\n considered true.\n', + 'debugger': u'\n"pdb" --- The Python Debugger\n*****************************\n\n**Source code:** Lib/pdb.py\n\n======================================================================\n\nThe module "pdb" defines an interactive source code debugger for\nPython programs. It supports setting (conditional) breakpoints and\nsingle stepping at the source line level, inspection of stack frames,\nsource code listing, and evaluation of arbitrary Python code in the\ncontext of any stack frame. It also supports post-mortem debugging\nand can be called under program control.\n\nThe debugger is extensible -- it is actually defined as the class\n"Pdb". This is currently undocumented but easily understood by reading\nthe source. The extension interface uses the modules "bdb" and "cmd".\n\nThe debugger\'s prompt is "(Pdb)". Typical usage to run a program under\ncontrol of the debugger is:\n\n >>> import pdb\n >>> import mymodule\n >>> pdb.run(\'mymodule.test()\')\n > (0)?()\n (Pdb) continue\n > (1)?()\n (Pdb) continue\n NameError: \'spam\'\n > (1)?()\n (Pdb)\n\nChanged in version 3.3: Tab-completion via the "readline" module is\navailable for commands and command arguments, e.g. the current global\nand local names are offered as arguments of the "p" command.\n\n"pdb.py" can also be invoked as a script to debug other scripts. For\nexample:\n\n python3 -m pdb myscript.py\n\nWhen invoked as a script, pdb will automatically enter post-mortem\ndebugging if the program being debugged exits abnormally. After post-\nmortem debugging (or after normal exit of the program), pdb will\nrestart the program. Automatic restarting preserves pdb\'s state (such\nas breakpoints) and in most cases is more useful than quitting the\ndebugger upon program\'s exit.\n\nNew in version 3.2: "pdb.py" now accepts a "-c" option that executes\ncommands as if given in a ".pdbrc" file, see *Debugger Commands*.\n\nThe typical usage to break into the debugger from a running program is\nto insert\n\n import pdb; pdb.set_trace()\n\nat the location you want to break into the debugger. You can then\nstep through the code following this statement, and continue running\nwithout the debugger using the "continue" command.\n\nThe typical usage to inspect a crashed program is:\n\n >>> import pdb\n >>> import mymodule\n >>> mymodule.test()\n Traceback (most recent call last):\n File "", line 1, in ?\n File "./mymodule.py", line 4, in test\n test2()\n File "./mymodule.py", line 3, in test2\n print(spam)\n NameError: spam\n >>> pdb.pm()\n > ./mymodule.py(3)test2()\n -> print(spam)\n (Pdb)\n\nThe module defines the following functions; each enters the debugger\nin a slightly different way:\n\npdb.run(statement, globals=None, locals=None)\n\n Execute the *statement* (given as a string or a code object) under\n debugger control. The debugger prompt appears before any code is\n executed; you can set breakpoints and type "continue", or you can\n step through the statement using "step" or "next" (all these\n commands are explained below). The optional *globals* and *locals*\n arguments specify the environment in which the code is executed; by\n default the dictionary of the module "__main__" is used. (See the\n explanation of the built-in "exec()" or "eval()" functions.)\n\npdb.runeval(expression, globals=None, locals=None)\n\n Evaluate the *expression* (given as a string or a code object)\n under debugger control. When "runeval()" returns, it returns the\n value of the expression. Otherwise this function is similar to\n "run()".\n\npdb.runcall(function, *args, **kwds)\n\n Call the *function* (a function or method object, not a string)\n with the given arguments. When "runcall()" returns, it returns\n whatever the function call returned. The debugger prompt appears\n as soon as the function is entered.\n\npdb.set_trace()\n\n Enter the debugger at the calling stack frame. This is useful to\n hard-code a breakpoint at a given point in a program, even if the\n code is not otherwise being debugged (e.g. when an assertion\n fails).\n\npdb.post_mortem(traceback=None)\n\n Enter post-mortem debugging of the given *traceback* object. If no\n *traceback* is given, it uses the one of the exception that is\n currently being handled (an exception must be being handled if the\n default is to be used).\n\npdb.pm()\n\n Enter post-mortem debugging of the traceback found in\n "sys.last_traceback".\n\nThe "run*" functions and "set_trace()" are aliases for instantiating\nthe "Pdb" class and calling the method of the same name. If you want\nto access further features, you have to do this yourself:\n\nclass class pdb.Pdb(completekey=\'tab\', stdin=None, stdout=None, skip=None, nosigint=False)\n\n "Pdb" is the debugger class.\n\n The *completekey*, *stdin* and *stdout* arguments are passed to the\n underlying "cmd.Cmd" class; see the description there.\n\n The *skip* argument, if given, must be an iterable of glob-style\n module name patterns. The debugger will not step into frames that\n originate in a module that matches one of these patterns. [1]\n\n By default, Pdb sets a handler for the SIGINT signal (which is sent\n when the user presses Ctrl-C on the console) when you give a\n "continue" command. This allows you to break into the debugger\n again by pressing Ctrl-C. If you want Pdb not to touch the SIGINT\n handler, set *nosigint* tot true.\n\n Example call to enable tracing with *skip*:\n\n import pdb; pdb.Pdb(skip=[\'django.*\']).set_trace()\n\n New in version 3.1: The *skip* argument.\n\n New in version 3.2: The *nosigint* argument. Previously, a SIGINT\n handler was never set by Pdb.\n\n run(statement, globals=None, locals=None)\n runeval(expression, globals=None, locals=None)\n runcall(function, *args, **kwds)\n set_trace()\n\n See the documentation for the functions explained above.\n\n\nDebugger Commands\n=================\n\nThe commands recognized by the debugger are listed below. Most\ncommands can be abbreviated to one or two letters as indicated; e.g.\n"h(elp)" means that either "h" or "help" can be used to enter the help\ncommand (but not "he" or "hel", nor "H" or "Help" or "HELP").\nArguments to commands must be separated by whitespace (spaces or\ntabs). Optional arguments are enclosed in square brackets ("[]") in\nthe command syntax; the square brackets must not be typed.\nAlternatives in the command syntax are separated by a vertical bar\n("|").\n\nEntering a blank line repeats the last command entered. Exception: if\nthe last command was a "list" command, the next 11 lines are listed.\n\nCommands that the debugger doesn\'t recognize are assumed to be Python\nstatements and are executed in the context of the program being\ndebugged. Python statements can also be prefixed with an exclamation\npoint ("!"). This is a powerful way to inspect the program being\ndebugged; it is even possible to change a variable or call a function.\nWhen an exception occurs in such a statement, the exception name is\nprinted but the debugger\'s state is not changed.\n\nThe debugger supports *aliases*. Aliases can have parameters which\nallows one a certain level of adaptability to the context under\nexamination.\n\nMultiple commands may be entered on a single line, separated by ";;".\n(A single ";" is not used as it is the separator for multiple commands\nin a line that is passed to the Python parser.) No intelligence is\napplied to separating the commands; the input is split at the first\n";;" pair, even if it is in the middle of a quoted string.\n\nIf a file ".pdbrc" exists in the user\'s home directory or in the\ncurrent directory, it is read in and executed as if it had been typed\nat the debugger prompt. This is particularly useful for aliases. If\nboth files exist, the one in the home directory is read first and\naliases defined there can be overridden by the local file.\n\nChanged in version 3.2: ".pdbrc" can now contain commands that\ncontinue debugging, such as "continue" or "next". Previously, these\ncommands had no effect.\n\nh(elp) [command]\n\n Without argument, print the list of available commands. With a\n *command* as argument, print help about that command. "help pdb"\n displays the full documentation (the docstring of the "pdb"\n module). Since the *command* argument must be an identifier, "help\n exec" must be entered to get help on the "!" command.\n\nw(here)\n\n Print a stack trace, with the most recent frame at the bottom. An\n arrow indicates the current frame, which determines the context of\n most commands.\n\nd(own) [count]\n\n Move the current frame *count* (default one) levels down in the\n stack trace (to a newer frame).\n\nu(p) [count]\n\n Move the current frame *count* (default one) levels up in the stack\n trace (to an older frame).\n\nb(reak) [([filename:]lineno | function) [, condition]]\n\n With a *lineno* argument, set a break there in the current file.\n With a *function* argument, set a break at the first executable\n statement within that function. The line number may be prefixed\n with a filename and a colon, to specify a breakpoint in another\n file (probably one that hasn\'t been loaded yet). The file is\n searched on "sys.path". Note that each breakpoint is assigned a\n number to which all the other breakpoint commands refer.\n\n If a second argument is present, it is an expression which must\n evaluate to true before the breakpoint is honored.\n\n Without argument, list all breaks, including for each breakpoint,\n the number of times that breakpoint has been hit, the current\n ignore count, and the associated condition if any.\n\ntbreak [([filename:]lineno | function) [, condition]]\n\n Temporary breakpoint, which is removed automatically when it is\n first hit. The arguments are the same as for "break".\n\ncl(ear) [filename:lineno | bpnumber [bpnumber ...]]\n\n With a *filename:lineno* argument, clear all the breakpoints at\n this line. With a space separated list of breakpoint numbers, clear\n those breakpoints. Without argument, clear all breaks (but first\n ask confirmation).\n\ndisable [bpnumber [bpnumber ...]]\n\n Disable the breakpoints given as a space separated list of\n breakpoint numbers. Disabling a breakpoint means it cannot cause\n the program to stop execution, but unlike clearing a breakpoint, it\n remains in the list of breakpoints and can be (re-)enabled.\n\nenable [bpnumber [bpnumber ...]]\n\n Enable the breakpoints specified.\n\nignore bpnumber [count]\n\n Set the ignore count for the given breakpoint number. If count is\n omitted, the ignore count is set to 0. A breakpoint becomes active\n when the ignore count is zero. When non-zero, the count is\n decremented each time the breakpoint is reached and the breakpoint\n is not disabled and any associated condition evaluates to true.\n\ncondition bpnumber [condition]\n\n Set a new *condition* for the breakpoint, an expression which must\n evaluate to true before the breakpoint is honored. If *condition*\n is absent, any existing condition is removed; i.e., the breakpoint\n is made unconditional.\n\ncommands [bpnumber]\n\n Specify a list of commands for breakpoint number *bpnumber*. The\n commands themselves appear on the following lines. Type a line\n containing just "end" to terminate the commands. An example:\n\n (Pdb) commands 1\n (com) p some_variable\n (com) end\n (Pdb)\n\n To remove all commands from a breakpoint, type commands and follow\n it immediately with "end"; that is, give no commands.\n\n With no *bpnumber* argument, commands refers to the last breakpoint\n set.\n\n You can use breakpoint commands to start your program up again.\n Simply use the continue command, or step, or any other command that\n resumes execution.\n\n Specifying any command resuming execution (currently continue,\n step, next, return, jump, quit and their abbreviations) terminates\n the command list (as if that command was immediately followed by\n end). This is because any time you resume execution (even with a\n simple next or step), you may encounter another breakpoint--which\n could have its own command list, leading to ambiguities about which\n list to execute.\n\n If you use the \'silent\' command in the command list, the usual\n message about stopping at a breakpoint is not printed. This may be\n desirable for breakpoints that are to print a specific message and\n then continue. If none of the other commands print anything, you\n see no sign that the breakpoint was reached.\n\ns(tep)\n\n Execute the current line, stop at the first possible occasion\n (either in a function that is called or on the next line in the\n current function).\n\nn(ext)\n\n Continue execution until the next line in the current function is\n reached or it returns. (The difference between "next" and "step"\n is that "step" stops inside a called function, while "next"\n executes called functions at (nearly) full speed, only stopping at\n the next line in the current function.)\n\nunt(il) [lineno]\n\n Without argument, continue execution until the line with a number\n greater than the current one is reached.\n\n With a line number, continue execution until a line with a number\n greater or equal to that is reached. In both cases, also stop when\n the current frame returns.\n\n Changed in version 3.2: Allow giving an explicit line number.\n\nr(eturn)\n\n Continue execution until the current function returns.\n\nc(ont(inue))\n\n Continue execution, only stop when a breakpoint is encountered.\n\nj(ump) lineno\n\n Set the next line that will be executed. Only available in the\n bottom-most frame. This lets you jump back and execute code again,\n or jump forward to skip code that you don\'t want to run.\n\n It should be noted that not all jumps are allowed -- for instance\n it is not possible to jump into the middle of a "for" loop or out\n of a "finally" clause.\n\nl(ist) [first[, last]]\n\n List source code for the current file. Without arguments, list 11\n lines around the current line or continue the previous listing.\n With "." as argument, list 11 lines around the current line. With\n one argument, list 11 lines around at that line. With two\n arguments, list the given range; if the second argument is less\n than the first, it is interpreted as a count.\n\n The current line in the current frame is indicated by "->". If an\n exception is being debugged, the line where the exception was\n originally raised or propagated is indicated by ">>", if it differs\n from the current line.\n\n New in version 3.2: The ">>" marker.\n\nll | longlist\n\n List all source code for the current function or frame.\n Interesting lines are marked as for "list".\n\n New in version 3.2.\n\na(rgs)\n\n Print the argument list of the current function.\n\np expression\n\n Evaluate the *expression* in the current context and print its\n value.\n\n Note: "print()" can also be used, but is not a debugger command\n --- this executes the Python "print()" function.\n\npp expression\n\n Like the "p" command, except the value of the expression is pretty-\n printed using the "pprint" module.\n\nwhatis expression\n\n Print the type of the *expression*.\n\nsource expression\n\n Try to get source code for the given object and display it.\n\n New in version 3.2.\n\ndisplay [expression]\n\n Display the value of the expression if it changed, each time\n execution stops in the current frame.\n\n Without expression, list all display expressions for the current\n frame.\n\n New in version 3.2.\n\nundisplay [expression]\n\n Do not display the expression any more in the current frame.\n Without expression, clear all display expressions for the current\n frame.\n\n New in version 3.2.\n\ninteract\n\n Start an interative interpreter (using the "code" module) whose\n global namespace contains all the (global and local) names found in\n the current scope.\n\n New in version 3.2.\n\nalias [name [command]]\n\n Create an alias called *name* that executes *command*. The command\n must *not* be enclosed in quotes. Replaceable parameters can be\n indicated by "%1", "%2", and so on, while "%*" is replaced by all\n the parameters. If no command is given, the current alias for\n *name* is shown. If no arguments are given, all aliases are listed.\n\n Aliases may be nested and can contain anything that can be legally\n typed at the pdb prompt. Note that internal pdb commands *can* be\n overridden by aliases. Such a command is then hidden until the\n alias is removed. Aliasing is recursively applied to the first\n word of the command line; all other words in the line are left\n alone.\n\n As an example, here are two useful aliases (especially when placed\n in the ".pdbrc" file):\n\n # Print instance variables (usage "pi classInst")\n alias pi for k in %1.__dict__.keys(): print("%1.",k,"=",%1.__dict__[k])\n # Print instance variables in self\n alias ps pi self\n\nunalias name\n\n Delete the specified alias.\n\n! statement\n\n Execute the (one-line) *statement* in the context of the current\n stack frame. The exclamation point can be omitted unless the first\n word of the statement resembles a debugger command. To set a\n global variable, you can prefix the assignment command with a\n "global" statement on the same line, e.g.:\n\n (Pdb) global list_options; list_options = [\'-l\']\n (Pdb)\n\nrun [args ...]\nrestart [args ...]\n\n Restart the debugged Python program. If an argument is supplied,\n it is split with "shlex" and the result is used as the new\n "sys.argv". History, breakpoints, actions and debugger options are\n preserved. "restart" is an alias for "run".\n\nq(uit)\n\n Quit from the debugger. The program being executed is aborted.\n\n-[ Footnotes ]-\n\n[1] Whether a frame is considered to originate in a certain module\n is determined by the "__name__" in the frame globals.\n', + 'del': u'\nThe "del" statement\n*******************\n\n del_stmt ::= "del" target_list\n\nDeletion is recursively defined very similar to the way assignment is\ndefined. Rather than spelling it out in full details, here are some\nhints.\n\nDeletion of a target list recursively deletes each target, from left\nto right.\n\nDeletion of a name removes the binding of that name from the local or\nglobal namespace, depending on whether the name occurs in a "global"\nstatement in the same code block. If the name is unbound, a\n"NameError" exception will be raised.\n\nDeletion of attribute references, subscriptions and slicings is passed\nto the primary object involved; deletion of a slicing is in general\nequivalent to assignment of an empty slice of the right type (but even\nthis is determined by the sliced object).\n\nChanged in version 3.2: Previously it was illegal to delete a name\nfrom the local namespace if it occurs as a free variable in a nested\nblock.\n', + 'dict': u'\nDictionary displays\n*******************\n\nA dictionary display is a possibly empty series of key/datum pairs\nenclosed in curly braces:\n\n dict_display ::= "{" [key_datum_list | dict_comprehension] "}"\n key_datum_list ::= key_datum ("," key_datum)* [","]\n key_datum ::= expression ":" expression\n dict_comprehension ::= expression ":" expression comp_for\n\nA dictionary display yields a new dictionary object.\n\nIf a comma-separated sequence of key/datum pairs is given, they are\nevaluated from left to right to define the entries of the dictionary:\neach key object is used as a key into the dictionary to store the\ncorresponding datum. This means that you can specify the same key\nmultiple times in the key/datum list, and the final dictionary\'s value\nfor that key will be the last one given.\n\nA dict comprehension, in contrast to list and set comprehensions,\nneeds two expressions separated with a colon followed by the usual\n"for" and "if" clauses. When the comprehension is run, the resulting\nkey and value elements are inserted in the new dictionary in the order\nthey are produced.\n\nRestrictions on the types of the key values are listed earlier in\nsection *The standard type hierarchy*. (To summarize, the key type\nshould be *hashable*, which excludes all mutable objects.) Clashes\nbetween duplicate keys are not detected; the last datum (textually\nrightmost in the display) stored for a given key value prevails.\n', + 'dynamic-features': u'\nInteraction with dynamic features\n*********************************\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nThe "eval()" and "exec()" functions do not have access to the full\nenvironment for resolving names. Names may be resolved in the local\nand global namespaces of the caller. Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace. [1]\nThe "exec()" and "eval()" functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n', + 'else': u'\nThe "if" statement\n******************\n\nThe "if" statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the "if" statement is executed or evaluated).\nIf all expressions are false, the suite of the "else" clause, if\npresent, is executed.\n', + 'exceptions': u'\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the "raise" statement. Exception\nhandlers are specified with the "try" ... "except" statement. The\n"finally" clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n"SystemExit".\n\nExceptions are identified by class instances. The "except" clause is\nselected depending on the class of the instance: it must reference the\nclass of the instance or a base class thereof. The instance can be\nreceived by the handler and can carry additional information about the\nexceptional condition.\n\nNote: Exception messages are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the "try" statement in section *The try\nstatement* and "raise" statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by\n these operations is not available at the time the module is\n compiled.\n', + 'execmodel': u'\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\nas a command line argument to the interpreter) is a code block. A\nscript command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The string argument passed\nto the built-in functions "eval()" and "exec()" is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes comprehensions and generator\nexpressions since they are implemented using a function scope. This\nmeans that the following will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block,\nunless declared as "nonlocal". If a name is bound at the module\nlevel, it is a global variable. (The variables of the module code\nblock are local and global.) If a variable is used in a code block\nbut not defined there, it is a *free variable*.\n\nWhen a name is not found at all, a "NameError" exception is raised.\nIf the name refers to a local variable that has not been bound, an\n"UnboundLocalError" exception is raised. "UnboundLocalError" is a\nsubclass of "NameError".\n\nThe following constructs bind names: formal parameters to functions,\n"import" statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, "for" loop header, or after\n"as" in a "with" statement or "except" clause. The "import" statement\nof the form "from ... import *" binds all names defined in the\nimported module, except those beginning with an underscore. This form\nmay only be used at the module level.\n\nA target occurring in a "del" statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name).\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the "global" statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtins namespace, the namespace\nof the module "builtins". The global namespace is searched first. If\nthe name is not found there, the builtins namespace is searched. The\n"global" statement must precede all uses of the name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name "__builtins__" in its global\nnamespace; this should be a dictionary or a module (in the latter case\nthe module\'s dictionary is used). By default, when in the "__main__"\nmodule, "__builtins__" is the built-in module "builtins"; when in any\nother module, "__builtins__" is an alias for the dictionary of the\n"builtins" module itself. "__builtins__" can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n"__builtins__"; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should "import"\nthe "builtins" module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n"__main__".\n\nThe "global" statement has the same scope as a name binding operation\nin the same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n---------------------------------\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nThe "eval()" and "exec()" functions do not have access to the full\nenvironment for resolving names. Names may be resolved in the local\nand global namespaces of the caller. Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace. [1]\nThe "exec()" and "eval()" functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the "raise" statement. Exception\nhandlers are specified with the "try" ... "except" statement. The\n"finally" clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n"SystemExit".\n\nExceptions are identified by class instances. The "except" clause is\nselected depending on the class of the instance: it must reference the\nclass of the instance or a base class thereof. The instance can be\nreceived by the handler and can carry additional information about the\nexceptional condition.\n\nNote: Exception messages are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the "try" statement in section *The try\nstatement* and "raise" statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by\n these operations is not available at the time the module is\n compiled.\n', + 'exprlists': u'\nExpression lists\n****************\n\n expression_list ::= expression ( "," expression )* [","]\n\nAn expression list containing at least one comma yields a tuple. The\nlength of the tuple is the number of expressions in the list. The\nexpressions are evaluated from left to right.\n\nThe trailing comma is required only to create a single tuple (a.k.a. a\n*singleton*); it is optional in all other cases. A single expression\nwithout a trailing comma doesn\'t create a tuple, but rather yields the\nvalue of that expression. (To create an empty tuple, use an empty pair\nof parentheses: "()".)\n', + 'floating': u'\nFloating point literals\n***********************\n\nFloating point literals are described by the following lexical\ndefinitions:\n\n floatnumber ::= pointfloat | exponentfloat\n pointfloat ::= [intpart] fraction | intpart "."\n exponentfloat ::= (intpart | pointfloat) exponent\n intpart ::= digit+\n fraction ::= "." digit+\n exponent ::= ("e" | "E") ["+" | "-"] digit+\n\nNote that the integer and exponent parts are always interpreted using\nradix 10. For example, "077e010" is legal, and denotes the same number\nas "77e10". The allowed range of floating point literals is\nimplementation-dependent. Some examples of floating point literals:\n\n 3.14 10. .001 1e100 3.14e-10 0e0\n\nNote that numeric literals do not include a sign; a phrase like "-1"\nis actually an expression composed of the unary operator "-" and the\nliteral "1".\n', + 'for': u'\nThe "for" statement\n*******************\n\nThe "for" statement is used to iterate over the elements of a sequence\n(such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n"expression_list". The suite is then executed once for each item\nprovided by the iterator, in the order returned by the iterator. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments (see *Assignment statements*), and then the suite is\nexecuted. When the items are exhausted (which is immediately when the\nsequence is empty or an iterator raises a "StopIteration" exception),\nthe suite in the "else" clause, if present, is executed, and the loop\nterminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite. A "continue" statement\nexecuted in the first suite skips the rest of the suite and continues\nwith the next item, or with the "else" clause if there is no next\nitem.\n\nThe for-loop makes assignments to the variables(s) in the target list.\nThis overwrites all previous assignments to those variables including\nthose made in the suite of the for-loop:\n\n for i in range(10):\n print(i)\n i = 5 # this will not affect the for-loop\n # because i will be overwritten with the next\n # index in the range\n\nNames in the target list are not deleted when the loop is finished,\nbut if the sequence is empty, they will not have been assigned to at\nall by the loop. Hint: the built-in function "range()" returns an\niterator of integers suitable to emulate the effect of Pascal\'s "for i\n:= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, 2]".\n\nNote: There is a subtlety when the sequence is being modified by the\n loop (this can only occur for mutable sequences, i.e. lists). An\n internal counter is used to keep track of which item is used next,\n and this is incremented on each iteration. When this counter has\n reached the length of the sequence the loop terminates. This means\n that if the suite deletes the current (or a previous) item from the\n sequence, the next item will be skipped (since it gets the index of\n the current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n', + 'formatstrings': u'\nFormat String Syntax\n********************\n\nThe "str.format()" method and the "Formatter" class share the same\nsyntax for format strings (although in the case of "Formatter",\nsubclasses can define their own format string syntax).\n\nFormat strings contain "replacement fields" surrounded by curly braces\n"{}". Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output. If you need to include\na brace character in the literal text, it can be escaped by doubling:\n"{{" and "}}".\n\nThe grammar for a replacement field is as follows:\n\n replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"\n field_name ::= arg_name ("." attribute_name | "[" element_index "]")*\n arg_name ::= [identifier | integer]\n attribute_name ::= identifier\n element_index ::= integer | index_string\n index_string ::= +\n conversion ::= "r" | "s" | "a"\n format_spec ::= \n\nIn less formal terms, the replacement field can start with a\n*field_name* that specifies the object whose value is to be formatted\nand inserted into the output instead of the replacement field. The\n*field_name* is optionally followed by a *conversion* field, which is\npreceded by an exclamation point "\'!\'", and a *format_spec*, which is\npreceded by a colon "\':\'". These specify a non-default format for the\nreplacement value.\n\nSee also the *Format Specification Mini-Language* section.\n\nThe *field_name* itself begins with an *arg_name* that is either a\nnumber or a keyword. If it\'s a number, it refers to a positional\nargument, and if it\'s a keyword, it refers to a named keyword\nargument. If the numerical arg_names in a format string are 0, 1, 2,\n... in sequence, they can all be omitted (not just some) and the\nnumbers 0, 1, 2, ... will be automatically inserted in that order.\nBecause *arg_name* is not quote-delimited, it is not possible to\nspecify arbitrary dictionary keys (e.g., the strings "\'10\'" or\n"\':-]\'") within a format string. The *arg_name* can be followed by any\nnumber of index or attribute expressions. An expression of the form\n"\'.name\'" selects the named attribute using "getattr()", while an\nexpression of the form "\'[index]\'" does an index lookup using\n"__getitem__()".\n\nChanged in version 3.1: The positional argument specifiers can be\nomitted, so "\'{} {}\'" is equivalent to "\'{0} {1}\'".\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\n "Bring me a {}" # Implicitly references the first positional argument\n "From {} to {}" # Same as "From {0} to {1}"\n "My quest is {name}" # References keyword argument \'name\'\n "Weight in tons {0.weight}" # \'weight\' attribute of first positional arg\n "Units destroyed: {players[0]}" # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the "__format__()"\nmethod of the value itself. However, in some cases it is desirable to\nforce a type to be formatted as a string, overriding its own\ndefinition of formatting. By converting the value to a string before\ncalling "__format__()", the normal formatting logic is bypassed.\n\nThree conversion flags are currently supported: "\'!s\'" which calls\n"str()" on the value, "\'!r\'" which calls "repr()" and "\'!a\'" which\ncalls "ascii()".\n\nSome examples:\n\n "Harold\'s a clever {0!s}" # Calls str() on the argument first\n "Bring out the holy {name!r}" # Calls repr() on the argument first\n "More {!a}" # Calls ascii() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on. Each value type can define its\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields can contain only a field\nname; conversion flags and format specifications are not allowed. The\nreplacement fields within the format_spec are substituted before the\n*format_spec* string is interpreted. This allows the formatting of a\nvalue to be dynamically specified.\n\nSee the *Format examples* section for some examples.\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see *Format String Syntax*). They can also be passed directly to the\nbuilt-in "format()" function. Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string ("""") produces\nthe same result as if you had called "str()" on the value. A non-empty\nformat string typically modifies the result.\n\nThe general form of a *standard format specifier* is:\n\n format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]\n fill ::= \n align ::= "<" | ">" | "=" | "^"\n sign ::= "+" | "-" | " "\n width ::= integer\n precision ::= integer\n type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n\nIf a valid *align* value is specified, it can be preceded by a *fill*\ncharacter that can be any character and defaults to a space if\nomitted. Note that it is not possible to use "{" and "}" as *fill*\nchar while using the "str.format()" method; this limitation however\ndoesn\'t affect the "format()" function.\n\nThe meaning of the various alignment options is as follows:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | "\'<\'" | Forces the field to be left-aligned within the available |\n | | space (this is the default for most objects). |\n +-----------+------------------------------------------------------------+\n | "\'>\'" | Forces the field to be right-aligned within the available |\n | | space (this is the default for numbers). |\n +-----------+------------------------------------------------------------+\n | "\'=\'" | Forces the padding to be placed after the sign (if any) |\n | | but before the digits. This is used for printing fields |\n | | in the form \'+000000120\'. This alignment option is only |\n | | valid for numeric types. |\n +-----------+------------------------------------------------------------+\n | "\'^\'" | Forces the field to be centered within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | "\'+\'" | indicates that a sign should be used for both positive as |\n | | well as negative numbers. |\n +-----------+------------------------------------------------------------+\n | "\'-\'" | indicates that a sign should be used only for negative |\n | | numbers (this is the default behavior). |\n +-----------+------------------------------------------------------------+\n | space | indicates that a leading space should be used on positive |\n | | numbers, and a minus sign on negative numbers. |\n +-----------+------------------------------------------------------------+\n\nThe "\'#\'" option causes the "alternate form" to be used for the\nconversion. The alternate form is defined differently for different\ntypes. This option is only valid for integer, float, complex and\nDecimal types. For integers, when binary, octal, or hexadecimal output\nis used, this option adds the prefix respective "\'0b\'", "\'0o\'", or\n"\'0x\'" to the output value. For floats, complex and Decimal the\nalternate form causes the result of the conversion to always contain a\ndecimal-point character, even if no digits follow it. Normally, a\ndecimal-point character appears in the result of these conversions\nonly if a digit follows it. In addition, for "\'g\'" and "\'G\'"\nconversions, trailing zeros are not removed from the result.\n\nThe "\',\'" option signals the use of a comma for a thousands separator.\nFor a locale aware separator, use the "\'n\'" integer presentation type\ninstead.\n\nChanged in version 3.1: Added the "\',\'" option (see also **PEP 378**).\n\n*width* is a decimal integer defining the minimum field width. If not\nspecified, then the field width will be determined by the content.\n\nPreceding the *width* field by a zero ("\'0\'") character enables sign-\naware zero-padding for numeric types. This is equivalent to a *fill*\ncharacter of "\'0\'" with an *alignment* type of "\'=\'".\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value\nformatted with "\'f\'" and "\'F\'", or before and after the decimal point\nfor a floating point value formatted with "\'g\'" or "\'G\'". For non-\nnumber types the field indicates the maximum field size - in other\nwords, how many characters will be used from the field content. The\n*precision* is not allowed for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available string presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | "\'s\'" | String format. This is the default type for strings and |\n | | may be omitted. |\n +-----------+------------------------------------------------------------+\n | None | The same as "\'s\'". |\n +-----------+------------------------------------------------------------+\n\nThe available integer presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | "\'b\'" | Binary format. Outputs the number in base 2. |\n +-----------+------------------------------------------------------------+\n | "\'c\'" | Character. Converts the integer to the corresponding |\n | | unicode character before printing. |\n +-----------+------------------------------------------------------------+\n | "\'d\'" | Decimal Integer. Outputs the number in base 10. |\n +-----------+------------------------------------------------------------+\n | "\'o\'" | Octal format. Outputs the number in base 8. |\n +-----------+------------------------------------------------------------+\n | "\'x\'" | Hex format. Outputs the number in base 16, using lower- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | "\'X\'" | Hex format. Outputs the number in base 16, using upper- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | "\'n\'" | Number. This is the same as "\'d\'", except that it uses the |\n | | current locale setting to insert the appropriate number |\n | | separator characters. |\n +-----------+------------------------------------------------------------+\n | None | The same as "\'d\'". |\n +-----------+------------------------------------------------------------+\n\nIn addition to the above presentation types, integers can be formatted\nwith the floating point presentation types listed below (except "\'n\'"\nand None). When doing so, "float()" is used to convert the integer to\na floating point number before formatting.\n\nThe available presentation types for floating point and decimal values\nare:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | "\'e\'" | Exponent notation. Prints the number in scientific |\n | | notation using the letter \'e\' to indicate the exponent. |\n | | The default precision is "6". |\n +-----------+------------------------------------------------------------+\n | "\'E\'" | Exponent notation. Same as "\'e\'" except it uses an upper |\n | | case \'E\' as the separator character. |\n +-----------+------------------------------------------------------------+\n | "\'f\'" | Fixed point. Displays the number as a fixed-point number. |\n | | The default precision is "6". |\n +-----------+------------------------------------------------------------+\n | "\'F\'" | Fixed point. Same as "\'f\'", but converts "nan" to "NAN" |\n | | and "inf" to "INF". |\n +-----------+------------------------------------------------------------+\n | "\'g\'" | General format. For a given precision "p >= 1", this |\n | | rounds the number to "p" significant digits and then |\n | | formats the result in either fixed-point format or in |\n | | scientific notation, depending on its magnitude. The |\n | | precise rules are as follows: suppose that the result |\n | | formatted with presentation type "\'e\'" and precision "p-1" |\n | | would have exponent "exp". Then if "-4 <= exp < p", the |\n | | number is formatted with presentation type "\'f\'" and |\n | | precision "p-1-exp". Otherwise, the number is formatted |\n | | with presentation type "\'e\'" and precision "p-1". In both |\n | | cases insignificant trailing zeros are removed from the |\n | | significand, and the decimal point is also removed if |\n | | there are no remaining digits following it. Positive and |\n | | negative infinity, positive and negative zero, and nans, |\n | | are formatted as "inf", "-inf", "0", "-0" and "nan" |\n | | respectively, regardless of the precision. A precision of |\n | | "0" is treated as equivalent to a precision of "1". The |\n | | default precision is "6". |\n +-----------+------------------------------------------------------------+\n | "\'G\'" | General format. Same as "\'g\'" except switches to "\'E\'" if |\n | | the number gets too large. The representations of infinity |\n | | and NaN are uppercased, too. |\n +-----------+------------------------------------------------------------+\n | "\'n\'" | Number. This is the same as "\'g\'", except that it uses the |\n | | current locale setting to insert the appropriate number |\n | | separator characters. |\n +-----------+------------------------------------------------------------+\n | "\'%\'" | Percentage. Multiplies the number by 100 and displays in |\n | | fixed ("\'f\'") format, followed by a percent sign. |\n +-----------+------------------------------------------------------------+\n | None | Similar to "\'g\'", except that fixed-point notation, when |\n | | used, has at least one digit past the decimal point. The |\n | | default precision is as high as needed to represent the |\n | | particular value. The overall effect is to match the |\n | | output of "str()" as altered by the other format |\n | | modifiers. |\n +-----------+------------------------------------------------------------+\n\n\nFormat examples\n===============\n\nThis section contains examples of the new format syntax and comparison\nwith the old "%"-formatting.\n\nIn most of the cases the syntax is similar to the old "%"-formatting,\nwith the addition of the "{}" and with ":" used instead of "%". For\nexample, "\'%03.2f\'" can be translated to "\'{:03.2f}\'".\n\nThe new format syntax also supports new and different options, shown\nin the follow examples.\n\nAccessing arguments by position:\n\n >>> \'{0}, {1}, {2}\'.format(\'a\', \'b\', \'c\')\n \'a, b, c\'\n >>> \'{}, {}, {}\'.format(\'a\', \'b\', \'c\') # 3.1+ only\n \'a, b, c\'\n >>> \'{2}, {1}, {0}\'.format(\'a\', \'b\', \'c\')\n \'c, b, a\'\n >>> \'{2}, {1}, {0}\'.format(*\'abc\') # unpacking argument sequence\n \'c, b, a\'\n >>> \'{0}{1}{0}\'.format(\'abra\', \'cad\') # arguments\' indices can be repeated\n \'abracadabra\'\n\nAccessing arguments by name:\n\n >>> \'Coordinates: {latitude}, {longitude}\'.format(latitude=\'37.24N\', longitude=\'-115.81W\')\n \'Coordinates: 37.24N, -115.81W\'\n >>> coord = {\'latitude\': \'37.24N\', \'longitude\': \'-115.81W\'}\n >>> \'Coordinates: {latitude}, {longitude}\'.format(**coord)\n \'Coordinates: 37.24N, -115.81W\'\n\nAccessing arguments\' attributes:\n\n >>> c = 3-5j\n >>> (\'The complex number {0} is formed from the real part {0.real} \'\n ... \'and the imaginary part {0.imag}.\').format(c)\n \'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.\'\n >>> class Point:\n ... def __init__(self, x, y):\n ... self.x, self.y = x, y\n ... def __str__(self):\n ... return \'Point({self.x}, {self.y})\'.format(self=self)\n ...\n >>> str(Point(4, 2))\n \'Point(4, 2)\'\n\nAccessing arguments\' items:\n\n >>> coord = (3, 5)\n >>> \'X: {0[0]}; Y: {0[1]}\'.format(coord)\n \'X: 3; Y: 5\'\n\nReplacing "%s" and "%r":\n\n >>> "repr() shows quotes: {!r}; str() doesn\'t: {!s}".format(\'test1\', \'test2\')\n "repr() shows quotes: \'test1\'; str() doesn\'t: test2"\n\nAligning the text and specifying a width:\n\n >>> \'{:<30}\'.format(\'left aligned\')\n \'left aligned \'\n >>> \'{:>30}\'.format(\'right aligned\')\n \' right aligned\'\n >>> \'{:^30}\'.format(\'centered\')\n \' centered \'\n >>> \'{:*^30}\'.format(\'centered\') # use \'*\' as a fill char\n \'***********centered***********\'\n\nReplacing "%+f", "%-f", and "% f" and specifying a sign:\n\n >>> \'{:+f}; {:+f}\'.format(3.14, -3.14) # show it always\n \'+3.140000; -3.140000\'\n >>> \'{: f}; {: f}\'.format(3.14, -3.14) # show a space for positive numbers\n \' 3.140000; -3.140000\'\n >>> \'{:-f}; {:-f}\'.format(3.14, -3.14) # show only the minus -- same as \'{:f}; {:f}\'\n \'3.140000; -3.140000\'\n\nReplacing "%x" and "%o" and converting the value to different bases:\n\n >>> # format also supports binary numbers\n >>> "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42)\n \'int: 42; hex: 2a; oct: 52; bin: 101010\'\n >>> # with 0x, 0o, or 0b as prefix:\n >>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42)\n \'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010\'\n\nUsing the comma as a thousands separator:\n\n >>> \'{:,}\'.format(1234567890)\n \'1,234,567,890\'\n\nExpressing a percentage:\n\n >>> points = 19\n >>> total = 22\n >>> \'Correct answers: {:.2%}\'.format(points/total)\n \'Correct answers: 86.36%\'\n\nUsing type-specific formatting:\n\n >>> import datetime\n >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n >>> \'{:%Y-%m-%d %H:%M:%S}\'.format(d)\n \'2010-07-04 12:15:58\'\n\nNesting arguments and more complex examples:\n\n >>> for align, text in zip(\'<^>\', [\'left\', \'center\', \'right\']):\n ... \'{0:{fill}{align}16}\'.format(text, fill=align, align=align)\n ...\n \'left<<<<<<<<<<<<\'\n \'^^^^^center^^^^^\'\n \'>>>>>>>>>>>right\'\n >>>\n >>> octets = [192, 168, 0, 1]\n >>> \'{:02X}{:02X}{:02X}{:02X}\'.format(*octets)\n \'C0A80001\'\n >>> int(_, 16)\n 3232235521\n >>>\n >>> width = 5\n >>> for num in range(5,12): #doctest: +NORMALIZE_WHITESPACE\n ... for base in \'dXob\':\n ... print(\'{0:{width}{base}}\'.format(num, base=base, width=width), end=\' \')\n ... print()\n ...\n 5 5 5 101\n 6 6 6 110\n 7 7 7 111\n 8 8 10 1000\n 9 9 11 1001\n 10 A 12 1010\n 11 B 13 1011\n', + 'function': u'\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n funcdef ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [parameter_list [","]] ")"] NEWLINE\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n | "*" [parameter] ("," defparameter)* ["," "**" parameter]\n | "**" parameter\n | defparameter [","] )\n parameter ::= identifier [":" expression]\n defparameter ::= parameter ["=" expression]\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more *parameters* have the form *parameter* "="\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding *argument* may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters up until the ""*"" must also have a default value --- this\nis a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated from left to right when the\nfunction definition is executed.** This means that the expression is\nevaluated once, when the function is defined, and that the same "pre-\ncomputed" value is used for each call. This is especially important\nto understand when a default parameter is a mutable object, such as a\nlist or a dictionary: if the function modifies the object (e.g. by\nappending an item to a list), the default value is in effect modified.\nThis is generally not what was intended. A way around this is to use\n"None" as the default, and explicitly test for it in the body of the\nfunction, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n""*identifier"" is present, it is initialized to a tuple receiving any\nexcess positional parameters, defaulting to the empty tuple. If the\nform ""**identifier"" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after ""*"" or ""*identifier"" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "": expression"" following\nthe parameter name. Any parameter may have an annotation even those\nof the form "*identifier" or "**identifier". Functions may have\n"return" annotation of the form ""-> expression"" after the parameter\nlist. These annotations can be any valid Python expression and are\nevaluated when the function definition is executed. Annotations may\nbe evaluated in a different order than they appear in the source code.\nThe presence of annotations does not change the semantics of a\nfunction. The annotation values are available as values of a\ndictionary keyed by the parameters\' names in the "__annotations__"\nattribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda\nexpressions, described in section *Lambdas*. Note that the lambda\nexpression is merely a shorthand for a simplified function definition;\na function defined in a ""def"" statement can be passed around or\nassigned to another name just like a function defined by a lambda\nexpression. The ""def"" form is actually more powerful since it\nallows the execution of multiple statements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects. A ""def""\nstatement executed inside a function definition defines a local\nfunction that can be returned or passed around. Free variables used\nin the nested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n\nSee also: **PEP 3107** - Function Annotations\n\n The original specification for function annotations.\n', + 'global': u'\nThe "global" statement\n**********************\n\n global_stmt ::= "global" identifier ("," identifier)*\n\nThe "global" statement is a declaration which holds for the entire\ncurrent code block. It means that the listed identifiers are to be\ninterpreted as globals. It would be impossible to assign to a global\nvariable without "global", although free variables may refer to\nglobals without being declared global.\n\nNames listed in a "global" statement must not be used in the same code\nblock textually preceding that "global" statement.\n\nNames listed in a "global" statement must not be defined as formal\nparameters or in a "for" loop control target, "class" definition,\nfunction definition, or "import" statement.\n\n**CPython implementation detail:** The current implementation does not\nenforce the two restrictions, but programs should not abuse this\nfreedom, as future implementations may enforce them or silently change\nthe meaning of the program.\n\n**Programmer\'s note:** the "global" is a directive to the parser. It\napplies only to code parsed at the same time as the "global"\nstatement. In particular, a "global" statement contained in a string\nor code object supplied to the built-in "exec()" function does not\naffect the code block *containing* the function call, and code\ncontained in such a string is unaffected by "global" statements in the\ncode containing the function call. The same applies to the "eval()"\nand "compile()" functions.\n', + 'id-classes': u'\nReserved classes of identifiers\n*******************************\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n"_*"\n Not imported by "from module import *". The special identifier "_"\n is used in the interactive interpreter to store the result of the\n last evaluation; it is stored in the "builtins" module. When not\n in interactive mode, "_" has no special meaning and is not defined.\n See section *The import statement*.\n\n Note: The name "_" is often used in conjunction with\n internationalization; refer to the documentation for the\n "gettext" module for more information on this convention.\n\n"__*__"\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library). Current\n system names are discussed in the *Special method names* section\n and elsewhere. More will likely be defined in future versions of\n Python. *Any* use of "__*__" names, in any context, that does not\n follow explicitly documented use, is subject to breakage without\n warning.\n\n"__*"\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', + 'identifiers': u'\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions.\n\nThe syntax of identifiers in Python is based on the Unicode standard\nannex UAX-31, with elaboration and changes as defined below; see also\n**PEP 3131** for further details.\n\nWithin the ASCII range (U+0001..U+007F), the valid characters for\nidentifiers are the same as in Python 2.x: the uppercase and lowercase\nletters "A" through "Z", the underscore "_" and, except for the first\ncharacter, the digits "0" through "9".\n\nPython 3.0 introduces additional characters from outside the ASCII\nrange (see **PEP 3131**). For these characters, the classification\nuses the version of the Unicode Character Database as included in the\n"unicodedata" module.\n\nIdentifiers are unlimited in length. Case is significant.\n\n identifier ::= xid_start xid_continue*\n id_start ::= \n id_continue ::= \n xid_start ::= \n xid_continue ::= \n\nThe Unicode category codes mentioned above stand for:\n\n* *Lu* - uppercase letters\n\n* *Ll* - lowercase letters\n\n* *Lt* - titlecase letters\n\n* *Lm* - modifier letters\n\n* *Lo* - other letters\n\n* *Nl* - letter numbers\n\n* *Mn* - nonspacing marks\n\n* *Mc* - spacing combining marks\n\n* *Nd* - decimal numbers\n\n* *Pc* - connector punctuations\n\n* *Other_ID_Start* - explicit list of characters in PropList.txt to\n support backwards compatibility\n\n* *Other_ID_Continue* - likewise\n\nAll identifiers are converted into the normal form NFKC while parsing;\ncomparison of identifiers is based on NFKC.\n\nA non-normative HTML file listing all valid identifier characters for\nUnicode 4.1 can be found at http://www.dcl.hpi.uni-\npotsdam.de/home/loewis/table-3131.html.\n\n\nKeywords\n========\n\nThe following identifiers are used as reserved words, or *keywords* of\nthe language, and cannot be used as ordinary identifiers. They must\nbe spelled exactly as written here:\n\n False class finally is return\n None continue for lambda try\n True def from nonlocal while\n and del global not with\n as elif if or yield\n assert else import pass\n break except in raise\n\n\nReserved classes of identifiers\n===============================\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n"_*"\n Not imported by "from module import *". The special identifier "_"\n is used in the interactive interpreter to store the result of the\n last evaluation; it is stored in the "builtins" module. When not\n in interactive mode, "_" has no special meaning and is not defined.\n See section *The import statement*.\n\n Note: The name "_" is often used in conjunction with\n internationalization; refer to the documentation for the\n "gettext" module for more information on this convention.\n\n"__*__"\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library). Current\n system names are discussed in the *Special method names* section\n and elsewhere. More will likely be defined in future versions of\n Python. *Any* use of "__*__" names, in any context, that does not\n follow explicitly documented use, is subject to breakage without\n warning.\n\n"__*"\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', + 'if': u'\nThe "if" statement\n******************\n\nThe "if" statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the "if" statement is executed or evaluated).\nIf all expressions are false, the suite of the "else" clause, if\npresent, is executed.\n', + 'imaginary': u'\nImaginary literals\n******************\n\nImaginary literals are described by the following lexical definitions:\n\n imagnumber ::= (floatnumber | intpart) ("j" | "J")\n\nAn imaginary literal yields a complex number with a real part of 0.0.\nComplex numbers are represented as a pair of floating point numbers\nand have the same restrictions on their range. To create a complex\nnumber with a nonzero real part, add a floating point number to it,\ne.g., "(3+4j)". Some examples of imaginary literals:\n\n 3.14j 10.j 10j .001j 1e100j 3.14e-10j\n', + 'import': u'\nThe "import" statement\n**********************\n\n import_stmt ::= "import" module ["as" name] ( "," module ["as" name] )*\n | "from" relative_module "import" identifier ["as" name]\n ( "," identifier ["as" name] )*\n | "from" relative_module "import" "(" identifier ["as" name]\n ( "," identifier ["as" name] )* [","] ")"\n | "from" module "import" "*"\n module ::= (identifier ".")* identifier\n relative_module ::= "."* module | "."+\n name ::= identifier\n\nThe basic import statement (no "from" clause) is executed in two\nsteps:\n\n1. find a module, loading and initializing it if necessary\n\n2. define a name or names in the local namespace for the scope\n where the "import" statement occurs.\n\nWhen the statement contains multiple clauses (separated by commas) the\ntwo steps are carried out separately for each clause, just as though\nthe clauses had been separated out into individiual import statements.\n\nThe details of the first step, finding and loading modules are\ndescribed in greater detail in the section on the *import system*,\nwhich also describes the various types of packages and modules that\ncan be imported, as well as all the hooks that can be used to\ncustomize the import system. Note that failures in this step may\nindicate either that the module could not be located, *or* that an\nerror occurred while initializing the module, which includes execution\nof the module\'s code.\n\nIf the requested module is retrieved successfully, it will be made\navailable in the local namespace in one of three ways:\n\n* If the module name is followed by "as", then the name following\n "as" is bound directly to the imported module.\n\n* If no other name is specified, and the module being imported is a\n top level module, the module\'s name is bound in the local namespace\n as a reference to the imported module\n\n* If the module being imported is *not* a top level module, then the\n name of the top level package that contains the module is bound in\n the local namespace as a reference to the top level package. The\n imported module must be accessed using its full qualified name\n rather than directly\n\nThe "from" form uses a slightly more complex process:\n\n1. find the module specified in the "from" clause, loading and\n initializing it if necessary;\n\n2. for each of the identifiers specified in the "import" clauses:\n\n 1. check if the imported module has an attribute by that name\n\n 2. if not, attempt to import a submodule with that name and then\n check the imported module again for that attribute\n\n 3. if the attribute is not found, "ImportError" is raised.\n\n 4. otherwise, a reference to that value is stored in the local\n namespace, using the name in the "as" clause if it is present,\n otherwise using the attribute name\n\nExamples:\n\n import foo # foo imported and bound locally\n import foo.bar.baz # foo.bar.baz imported, foo bound locally\n import foo.bar.baz as fbb # foo.bar.baz imported and bound as fbb\n from foo.bar import baz # foo.bar.baz imported and bound as baz\n from foo import attr # foo imported and foo.attr bound as attr\n\nIf the list of identifiers is replaced by a star ("\'*\'"), all public\nnames defined in the module are bound in the local namespace for the\nscope where the "import" statement occurs.\n\nThe *public names* defined by a module are determined by checking the\nmodule\'s namespace for a variable named "__all__"; if defined, it must\nbe a sequence of strings which are names defined or imported by that\nmodule. The names given in "__all__" are all considered public and\nare required to exist. If "__all__" is not defined, the set of public\nnames includes all names found in the module\'s namespace which do not\nbegin with an underscore character ("\'_\'"). "__all__" should contain\nthe entire public API. It is intended to avoid accidentally exporting\nitems that are not part of the API (such as library modules which were\nimported and used within the module).\n\nThe wild card form of import --- "from module import *" --- is only\nallowed at the module level. Attempting to use it in class or\nfunction definitions will raise a "SyntaxError".\n\nWhen specifying what module to import you do not have to specify the\nabsolute name of the module. When a module or package is contained\nwithin another package it is possible to make a relative import within\nthe same top package without having to mention the package name. By\nusing leading dots in the specified module or package after "from" you\ncan specify how high to traverse up the current package hierarchy\nwithout specifying exact names. One leading dot means the current\npackage where the module making the import exists. Two dots means up\none package level. Three dots is up two levels, etc. So if you execute\n"from . import mod" from a module in the "pkg" package then you will\nend up importing "pkg.mod". If you execute "from ..subpkg2 import mod"\nfrom within "pkg.subpkg1" you will import "pkg.subpkg2.mod". The\nspecification for relative imports is contained within **PEP 328**.\n\n"importlib.import_module()" is provided to support applications that\ndetermine dynamically the modules to be loaded.\n\n\nFuture statements\n=================\n\nA *future statement* is a directive to the compiler that a particular\nmodule should be compiled using syntax or semantics that will be\navailable in a specified future release of Python where the feature\nbecomes standard.\n\nThe future statement is intended to ease migration to future versions\nof Python that introduce incompatible changes to the language. It\nallows use of the new features on a per-module basis before the\nrelease in which the feature becomes standard.\n\n future_statement ::= "from" "__future__" "import" feature ["as" name]\n ("," feature ["as" name])*\n | "from" "__future__" "import" "(" feature ["as" name]\n ("," feature ["as" name])* [","] ")"\n feature ::= identifier\n name ::= identifier\n\nA future statement must appear near the top of the module. The only\nlines that can appear before a future statement are:\n\n* the module docstring (if any),\n\n* comments,\n\n* blank lines, and\n\n* other future statements.\n\nThe features recognized by Python 3.0 are "absolute_import",\n"division", "generators", "unicode_literals", "print_function",\n"nested_scopes" and "with_statement". They are all redundant because\nthey are always enabled, and only kept for backwards compatibility.\n\nA future statement is recognized and treated specially at compile\ntime: Changes to the semantics of core constructs are often\nimplemented by generating different code. It may even be the case\nthat a new feature introduces new incompatible syntax (such as a new\nreserved word), in which case the compiler may need to parse the\nmodule differently. Such decisions cannot be pushed off until\nruntime.\n\nFor any given release, the compiler knows which feature names have\nbeen defined, and raises a compile-time error if a future statement\ncontains a feature not known to it.\n\nThe direct runtime semantics are the same as for any import statement:\nthere is a standard module "__future__", described later, and it will\nbe imported in the usual way at the time the future statement is\nexecuted.\n\nThe interesting runtime semantics depend on the specific feature\nenabled by the future statement.\n\nNote that there is nothing special about the statement:\n\n import __future__ [as name]\n\nThat is not a future statement; it\'s an ordinary import statement with\nno special semantics or syntax restrictions.\n\nCode compiled by calls to the built-in functions "exec()" and\n"compile()" that occur in a module "M" containing a future statement\nwill, by default, use the new syntax or semantics associated with the\nfuture statement. This can be controlled by optional arguments to\n"compile()" --- see the documentation of that function for details.\n\nA future statement typed at an interactive interpreter prompt will\ntake effect for the rest of the interpreter session. If an\ninterpreter is started with the *-i* option, is passed a script name\nto execute, and the script includes a future statement, it will be in\neffect in the interactive session started after the script is\nexecuted.\n\nSee also: **PEP 236** - Back to the __future__\n\n The original proposal for the __future__ mechanism.\n', + 'in': u'\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like "a < b < c" have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: "True" or "False".\n\nComparisons can be chained arbitrarily, e.g., "x < y <= z" is\nequivalent to "x < y and y <= z", except that "y" is evaluated only\nonce (but in both cases "z" is not evaluated at all when "x < y" is\nfound to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then "a op1 b op2 c ... y\nopN z" is equivalent to "a op1 b and b op2 c and ... y opN z", except\nthat each expression is evaluated at most once.\n\nNote that "a op1 b op2 c" doesn\'t imply any kind of comparison between\n*a* and *c*, so that, e.g., "x < y > z" is perfectly legal (though\nperhaps not pretty).\n\nThe operators "<", ">", "==", ">=", "<=", and "!=" compare the values\nof two objects. The objects need not have the same type. If both are\nnumbers, they are converted to a common type. Otherwise, the "==" and\n"!=" operators *always* consider objects of different types to be\nunequal, while the "<", ">", ">=" and "<=" operators raise a\n"TypeError" when comparing objects of different types that do not\nimplement these operators for the given pair of types. You can\ncontrol comparison behavior of objects of non-built-in types by\ndefining rich comparison methods like "__gt__()", described in section\n*Basic customization*.\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* The values "float(\'NaN\')" and "Decimal(\'NaN\')" are special. They\n are identical to themselves, "x is x" but are not equal to\n themselves, "x != x". Additionally, comparing any value to a\n not-a-number value will return "False". For example, both "3 <\n float(\'NaN\')" and "float(\'NaN\') < 3" will return "False".\n\n* Bytes objects are compared lexicographically using the numeric\n values of their elements.\n\n* Strings are compared lexicographically using the numeric\n equivalents (the result of the built-in function "ord()") of their\n characters. [3] String and bytes object can\'t be compared!\n\n* Tuples and lists are compared lexicographically using comparison\n of corresponding elements. This means that to compare equal, each\n element must compare equal and the two sequences must be of the same\n type and have the same length.\n\n If not equal, the sequences are ordered the same as their first\n differing elements. For example, "[1,2,x] <= [1,2,y]" has the same\n value as "x <= y". If the corresponding element does not exist, the\n shorter sequence is ordered first (for example, "[1,2] < [1,2,3]").\n\n* Mappings (dictionaries) compare equal if and only if they have the\n same "(key, value)" pairs. Order comparisons "(\'<\', \'<=\', \'>=\',\n \'>\')" raise "TypeError".\n\n* Sets and frozensets define comparison operators to mean subset and\n superset tests. Those relations do not define total orderings (the\n two sets "{1,2}" and {2,3} are not equal, nor subsets of one\n another, nor supersets of one another). Accordingly, sets are not\n appropriate arguments for functions which depend on total ordering.\n For example, "min()", "max()", and "sorted()" produce undefined\n results given a list of sets as inputs.\n\n* Most other objects of built-in types compare unequal unless they\n are the same object; the choice whether one object is considered\n smaller or larger than another one is made arbitrarily but\n consistently within one execution of a program.\n\nComparison of objects of differing types depends on whether either of\nthe types provide explicit support for the comparison. Most numeric\ntypes can be compared with one another. When cross-type comparison is\nnot supported, the comparison method returns "NotImplemented".\n\nThe operators "in" and "not in" test for membership. "x in s"\nevaluates to true if *x* is a member of *s*, and false otherwise. "x\nnot in s" returns the negation of "x in s". All built-in sequences\nand set types support this as well as dictionary, for which "in" tests\nwhether the dictionary has a given key. For container types such as\nlist, tuple, set, frozenset, dict, or collections.deque, the\nexpression "x in y" is equivalent to "any(x is e or x == e for e in\ny)".\n\nFor the string and bytes types, "x in y" is true if and only if *x* is\na substring of *y*. An equivalent test is "y.find(x) != -1". Empty\nstrings are always considered to be a substring of any other string,\nso """ in "abc"" will return "True".\n\nFor user-defined classes which define the "__contains__()" method, "x\nin y" is true if and only if "y.__contains__(x)" is true.\n\nFor user-defined classes which do not define "__contains__()" but do\ndefine "__iter__()", "x in y" is true if some value "z" with "x == z"\nis produced while iterating over "y". If an exception is raised\nduring the iteration, it is as if "in" raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n"__getitem__()", "x in y" is true if and only if there is a non-\nnegative integer index *i* such that "x == y[i]", and all lower\ninteger indices do not raise "IndexError" exception. (If any other\nexception is raised, it is as if "in" raised that exception).\n\nThe operator "not in" is defined to have the inverse true value of\n"in".\n\nThe operators "is" and "is not" test for object identity: "x is y" is\ntrue if and only if *x* and *y* are the same object. "x is not y"\nyields the inverse truth value. [4]\n', + 'integers': u'\nInteger literals\n****************\n\nInteger literals are described by the following lexical definitions:\n\n integer ::= decimalinteger | octinteger | hexinteger | bininteger\n decimalinteger ::= nonzerodigit digit* | "0"+\n nonzerodigit ::= "1"..."9"\n digit ::= "0"..."9"\n octinteger ::= "0" ("o" | "O") octdigit+\n hexinteger ::= "0" ("x" | "X") hexdigit+\n bininteger ::= "0" ("b" | "B") bindigit+\n octdigit ::= "0"..."7"\n hexdigit ::= digit | "a"..."f" | "A"..."F"\n bindigit ::= "0" | "1"\n\nThere is no limit for the length of integer literals apart from what\ncan be stored in available memory.\n\nNote that leading zeros in a non-zero decimal number are not allowed.\nThis is for disambiguation with C-style octal literals, which Python\nused before version 3.0.\n\nSome examples of integer literals:\n\n 7 2147483647 0o177 0b100110111\n 3 79228162514264337593543950336 0o377 0xdeadbeef\n', + 'lambda': u'\nLambdas\n*******\n\n lambda_expr ::= "lambda" [parameter_list]: expression\n lambda_expr_nocond ::= "lambda" [parameter_list]: expression_nocond\n\nLambda expressions (sometimes called lambda forms) are used to create\nanonymous functions. The expression "lambda arguments: expression"\nyields a function object. The unnamed object behaves like a function\nobject defined with\n\n def (arguments):\n return expression\n\nSee section *Function definitions* for the syntax of parameter lists.\nNote that functions created with lambda expressions cannot contain\nstatements or annotations.\n', + 'lists': u'\nList displays\n*************\n\nA list display is a possibly empty series of expressions enclosed in\nsquare brackets:\n\n list_display ::= "[" [expression_list | comprehension] "]"\n\nA list display yields a new list object, the contents being specified\nby either a list of expressions or a comprehension. When a comma-\nseparated list of expressions is supplied, its elements are evaluated\nfrom left to right and placed into the list object in that order.\nWhen a comprehension is supplied, the list is constructed from the\nelements resulting from the comprehension.\n', + 'naming': u'\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\nas a command line argument to the interpreter) is a code block. A\nscript command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The string argument passed\nto the built-in functions "eval()" and "exec()" is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes comprehensions and generator\nexpressions since they are implemented using a function scope. This\nmeans that the following will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block,\nunless declared as "nonlocal". If a name is bound at the module\nlevel, it is a global variable. (The variables of the module code\nblock are local and global.) If a variable is used in a code block\nbut not defined there, it is a *free variable*.\n\nWhen a name is not found at all, a "NameError" exception is raised.\nIf the name refers to a local variable that has not been bound, an\n"UnboundLocalError" exception is raised. "UnboundLocalError" is a\nsubclass of "NameError".\n\nThe following constructs bind names: formal parameters to functions,\n"import" statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, "for" loop header, or after\n"as" in a "with" statement or "except" clause. The "import" statement\nof the form "from ... import *" binds all names defined in the\nimported module, except those beginning with an underscore. This form\nmay only be used at the module level.\n\nA target occurring in a "del" statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name).\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the "global" statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtins namespace, the namespace\nof the module "builtins". The global namespace is searched first. If\nthe name is not found there, the builtins namespace is searched. The\n"global" statement must precede all uses of the name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name "__builtins__" in its global\nnamespace; this should be a dictionary or a module (in the latter case\nthe module\'s dictionary is used). By default, when in the "__main__"\nmodule, "__builtins__" is the built-in module "builtins"; when in any\nother module, "__builtins__" is an alias for the dictionary of the\n"builtins" module itself. "__builtins__" can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n"__builtins__"; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should "import"\nthe "builtins" module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n"__main__".\n\nThe "global" statement has the same scope as a name binding operation\nin the same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n=================================\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nThe "eval()" and "exec()" functions do not have access to the full\nenvironment for resolving names. Names may be resolved in the local\nand global namespaces of the caller. Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace. [1]\nThe "exec()" and "eval()" functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n', + 'nonlocal': u'\nThe "nonlocal" statement\n************************\n\n nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*\n\nThe "nonlocal" statement causes the listed identifiers to refer to\npreviously bound variables in the nearest enclosing scope excluding\nglobals. This is important because the default behavior for binding is\nto search the local namespace first. The statement allows\nencapsulated code to rebind variables outside of the local scope\nbesides the global (module) scope.\n\nNames listed in a "nonlocal" statement, unlike those listed in a\n"global" statement, must refer to pre-existing bindings in an\nenclosing scope (the scope in which a new binding should be created\ncannot be determined unambiguously).\n\nNames listed in a "nonlocal" statement must not collide with pre-\nexisting bindings in the local scope.\n\nSee also: **PEP 3104** - Access to Names in Outer Scopes\n\n The specification for the "nonlocal" statement.\n', + 'numbers': u'\nNumeric literals\n****************\n\nThere are three types of numeric literals: integers, floating point\nnumbers, and imaginary numbers. There are no complex literals\n(complex numbers can be formed by adding a real number and an\nimaginary number).\n\nNote that numeric literals do not include a sign; a phrase like "-1"\nis actually an expression composed of the unary operator \'"-"\' and the\nliteral "1".\n', + 'numeric-types': u'\nEmulating numeric types\n***********************\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__matmul__(self, other)\nobject.__truediv__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations ("+", "-", "*", "@", "/", "//", "%", "divmod()",\n "pow()", "**", "<<", ">>", "&", "^", "|"). For instance, to\n evaluate the expression "x + y", where *x* is an instance of a\n class that has an "__add__()" method, "x.__add__(y)" is called.\n The "__divmod__()" method should be the equivalent to using\n "__floordiv__()" and "__mod__()"; it should not be related to\n "__truediv__()". Note that "__pow__()" should be defined to accept\n an optional third argument if the ternary version of the built-in\n "pow()" function is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return "NotImplemented".\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rmatmul__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations ("+", "-", "*", "@", "/", "//", "%", "divmod()",\n "pow()", "**", "<<", ">>", "&", "^", "|") with reflected (swapped)\n operands. These functions are only called if the left operand does\n not support the corresponding operation and the operands are of\n different types. [2] For instance, to evaluate the expression "x -\n y", where *y* is an instance of a class that has an "__rsub__()"\n method, "y.__rsub__(x)" is called if "x.__sub__(y)" returns\n *NotImplemented*.\n\n Note that ternary "pow()" will not try calling "__rpow__()" (the\n coercion rules would become too complicated).\n\n Note: If the right operand\'s type is a subclass of the left\n operand\'s type and that subclass provides the reflected method\n for the operation, this method will be called before the left\n operand\'s non-reflected method. This behavior allows subclasses\n to override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__imatmul__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n assignments ("+=", "-=", "*=", "@=", "/=", "//=", "%=", "**=",\n "<<=", ">>=", "&=", "^=", "|="). These methods should attempt to\n do the operation in-place (modifying *self*) and return the result\n (which could be, but does not have to be, *self*). If a specific\n method is not defined, the augmented assignment falls back to the\n normal methods. For instance, if *x* is an instance of a class\n with an "__iadd__()" method, "x += y" is equivalent to "x =\n x.__iadd__(y)" . Otherwise, "x.__add__(y)" and "y.__radd__(x)" are\n considered, as with the evaluation of "x + y". In certain\n situations, augmented assignment can result in unexpected errors\n (see *Why does a_tuple[i] += [\'item\'] raise an exception when the\n addition works?*), but this behavior is in fact part of the data\n model.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations ("-", "+",\n "abs()" and "~").\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__float__(self)\nobject.__round__(self[, n])\n\n Called to implement the built-in functions "complex()", "int()",\n "float()" and "round()". Should return a value of the appropriate\n type.\n\nobject.__index__(self)\n\n Called to implement "operator.index()", and whenever Python needs\n to losslessly convert the numeric object to an integer object (such\n as in slicing, or in the built-in "bin()", "hex()" and "oct()"\n functions). Presence of this method indicates that the numeric\n object is an integer type. Must return an integer.\n\n Note: In order to have a coherent integer type class, when\n "__index__()" is defined "__int__()" should also be defined, and\n both should return the same value.\n', + 'objects': u'\nObjects, values and types\n*************************\n\n*Objects* are Python\'s abstraction for data. All data in a Python\nprogram is represented by objects or by relations between objects. (In\na sense, and in conformance to Von Neumann\'s model of a "stored\nprogram computer," code is also represented by objects.)\n\nEvery object has an identity, a type and a value. An object\'s\n*identity* never changes once it has been created; you may think of it\nas the object\'s address in memory. The \'"is"\' operator compares the\nidentity of two objects; the "id()" function returns an integer\nrepresenting its identity.\n\n**CPython implementation detail:** For CPython, "id(x)" is the memory\naddress where "x" is stored.\n\nAn object\'s type determines the operations that the object supports\n(e.g., "does it have a length?") and also defines the possible values\nfor objects of that type. The "type()" function returns an object\'s\ntype (which is an object itself). Like its identity, an object\'s\n*type* is also unchangeable. [1]\n\nThe *value* of some objects can change. Objects whose value can\nchange are said to be *mutable*; objects whose value is unchangeable\nonce they are created are called *immutable*. (The value of an\nimmutable container object that contains a reference to a mutable\nobject can change when the latter\'s value is changed; however the\ncontainer is still considered immutable, because the collection of\nobjects it contains cannot be changed. So, immutability is not\nstrictly the same as having an unchangeable value, it is more subtle.)\nAn object\'s mutability is determined by its type; for instance,\nnumbers, strings and tuples are immutable, while dictionaries and\nlists are mutable.\n\nObjects are never explicitly destroyed; however, when they become\nunreachable they may be garbage-collected. An implementation is\nallowed to postpone garbage collection or omit it altogether --- it is\na matter of implementation quality how garbage collection is\nimplemented, as long as no objects are collected that are still\nreachable.\n\n**CPython implementation detail:** CPython currently uses a reference-\ncounting scheme with (optional) delayed detection of cyclically linked\ngarbage, which collects most objects as soon as they become\nunreachable, but is not guaranteed to collect garbage containing\ncircular references. See the documentation of the "gc" module for\ninformation on controlling the collection of cyclic garbage. Other\nimplementations act differently and CPython may change. Do not depend\non immediate finalization of objects when they become unreachable (so\nyou should always close files explicitly).\n\nNote that the use of the implementation\'s tracing or debugging\nfacilities may keep objects alive that would normally be collectable.\nAlso note that catching an exception with a \'"try"..."except"\'\nstatement may keep objects alive.\n\nSome objects contain references to "external" resources such as open\nfiles or windows. It is understood that these resources are freed\nwhen the object is garbage-collected, but since garbage collection is\nnot guaranteed to happen, such objects also provide an explicit way to\nrelease the external resource, usually a "close()" method. Programs\nare strongly recommended to explicitly close such objects. The\n\'"try"..."finally"\' statement and the \'"with"\' statement provide\nconvenient ways to do this.\n\nSome objects contain references to other objects; these are called\n*containers*. Examples of containers are tuples, lists and\ndictionaries. The references are part of a container\'s value. In\nmost cases, when we talk about the value of a container, we imply the\nvalues, not the identities of the contained objects; however, when we\ntalk about the mutability of a container, only the identities of the\nimmediately contained objects are implied. So, if an immutable\ncontainer (like a tuple) contains a reference to a mutable object, its\nvalue changes if that mutable object is changed.\n\nTypes affect almost all aspects of object behavior. Even the\nimportance of object identity is affected in some sense: for immutable\ntypes, operations that compute new values may actually return a\nreference to any existing object with the same type and value, while\nfor mutable objects this is not allowed. E.g., after "a = 1; b = 1",\n"a" and "b" may or may not refer to the same object with the value\none, depending on the implementation, but after "c = []; d = []", "c"\nand "d" are guaranteed to refer to two different, unique, newly\ncreated empty lists. (Note that "c = d = []" assigns the same object\nto both "c" and "d".)\n', + 'operator-summary': u'\nOperator precedence\n*******************\n\nThe following table summarizes the operator precedence in Python, from\nlowest precedence (least binding) to highest precedence (most\nbinding). Operators in the same box have the same precedence. Unless\nthe syntax is explicitly given, operators are binary. Operators in\nthe same box group left to right (except for exponentiation, which\ngroups from right to left).\n\nNote that comparisons, membership tests, and identity tests, all have\nthe same precedence and have a left-to-right chaining feature as\ndescribed in the *Comparisons* section.\n\n+-------------------------------------------------+---------------------------------------+\n| Operator | Description |\n+=================================================+=======================================+\n| "lambda" | Lambda expression |\n+-------------------------------------------------+---------------------------------------+\n| "if" -- "else" | Conditional expression |\n+-------------------------------------------------+---------------------------------------+\n| "or" | Boolean OR |\n+-------------------------------------------------+---------------------------------------+\n| "and" | Boolean AND |\n+-------------------------------------------------+---------------------------------------+\n| "not" "x" | Boolean NOT |\n+-------------------------------------------------+---------------------------------------+\n| "in", "not in", "is", "is not", "<", "<=", ">", | Comparisons, including membership |\n| ">=", "!=", "==" | tests and identity tests |\n+-------------------------------------------------+---------------------------------------+\n| "|" | Bitwise OR |\n+-------------------------------------------------+---------------------------------------+\n| "^" | Bitwise XOR |\n+-------------------------------------------------+---------------------------------------+\n| "&" | Bitwise AND |\n+-------------------------------------------------+---------------------------------------+\n| "<<", ">>" | Shifts |\n+-------------------------------------------------+---------------------------------------+\n| "+", "-" | Addition and subtraction |\n+-------------------------------------------------+---------------------------------------+\n| "*", "@", "/", "//", "%" | Multiplication, matrix multiplication |\n| | division, remainder [5] |\n+-------------------------------------------------+---------------------------------------+\n| "+x", "-x", "~x" | Positive, negative, bitwise NOT |\n+-------------------------------------------------+---------------------------------------+\n| "**" | Exponentiation [6] |\n+-------------------------------------------------+---------------------------------------+\n| "await" "x" | Await expression |\n+-------------------------------------------------+---------------------------------------+\n| "x[index]", "x[index:index]", | Subscription, slicing, call, |\n| "x(arguments...)", "x.attribute" | attribute reference |\n+-------------------------------------------------+---------------------------------------+\n| "(expressions...)", "[expressions...]", "{key: | Binding or tuple display, list |\n| value...}", "{expressions...}" | display, dictionary display, set |\n| | display |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] While "abs(x%y) < abs(y)" is true mathematically, for floats\n it may not be true numerically due to roundoff. For example, and\n assuming a platform on which a Python float is an IEEE 754 double-\n precision number, in order that "-1e-100 % 1e100" have the same\n sign as "1e100", the computed result is "-1e-100 + 1e100", which\n is numerically exactly equal to "1e100". The function\n "math.fmod()" returns a result whose sign matches the sign of the\n first argument instead, and so returns "-1e-100" in this case.\n Which approach is more appropriate depends on the application.\n\n[2] If x is very close to an exact integer multiple of y, it\'s\n possible for "x//y" to be one larger than "(x-x%y)//y" due to\n rounding. In such cases, Python returns the latter result, in\n order to preserve that "divmod(x,y)[0] * y + x % y" be very close\n to "x".\n\n[3] While comparisons between strings make sense at the byte\n level, they may be counter-intuitive to users. For example, the\n strings ""\\u00C7"" and ""\\u0327\\u0043"" compare differently, even\n though they both represent the same unicode character (LATIN\n CAPITAL LETTER C WITH CEDILLA). To compare strings in a human\n recognizable way, compare using "unicodedata.normalize()".\n\n[4] Due to automatic garbage-collection, free lists, and the\n dynamic nature of descriptors, you may notice seemingly unusual\n behaviour in certain uses of the "is" operator, like those\n involving comparisons between instance methods, or constants.\n Check their documentation for more info.\n\n[5] The "%" operator is also used for string formatting; the same\n precedence applies.\n\n[6] The power operator "**" binds less tightly than an arithmetic\n or bitwise unary operator on its right, that is, "2**-1" is "0.5".\n', + 'pass': u'\nThe "pass" statement\n********************\n\n pass_stmt ::= "pass"\n\n"pass" is a null operation --- when it is executed, nothing happens.\nIt is useful as a placeholder when a statement is required\nsyntactically, but no code needs to be executed, for example:\n\n def f(arg): pass # a function that does nothing (yet)\n\n class C: pass # a class with no methods (yet)\n', + 'power': u'\nThe power operator\n******************\n\nThe power operator binds more tightly than unary operators on its\nleft; it binds less tightly than unary operators on its right. The\nsyntax is:\n\n power ::= await ["**" u_expr]\n\nThus, in an unparenthesized sequence of power and unary operators, the\noperators are evaluated from right to left (this does not constrain\nthe evaluation order for the operands): "-1**2" results in "-1".\n\nThe power operator has the same semantics as the built-in "pow()"\nfunction, when called with two arguments: it yields its left argument\nraised to the power of its right argument. The numeric arguments are\nfirst converted to a common type, and the result is of that type.\n\nFor int operands, the result has the same type as the operands unless\nthe second argument is negative; in that case, all arguments are\nconverted to float and a float result is delivered. For example,\n"10**2" returns "100", but "10**-2" returns "0.01".\n\nRaising "0.0" to a negative power results in a "ZeroDivisionError".\nRaising a negative number to a fractional power results in a "complex"\nnumber. (In earlier versions it raised a "ValueError".)\n', + 'raise': u'\nThe "raise" statement\n*********************\n\n raise_stmt ::= "raise" [expression ["from" expression]]\n\nIf no expressions are present, "raise" re-raises the last exception\nthat was active in the current scope. If no exception is active in\nthe current scope, a "RuntimeError" exception is raised indicating\nthat this is an error.\n\nOtherwise, "raise" evaluates the first expression as the exception\nobject. It must be either a subclass or an instance of\n"BaseException". If it is a class, the exception instance will be\nobtained when needed by instantiating the class with no arguments.\n\nThe *type* of the exception is the exception instance\'s class, the\n*value* is the instance itself.\n\nA traceback object is normally created automatically when an exception\nis raised and attached to it as the "__traceback__" attribute, which\nis writable. You can create an exception and set your own traceback in\none step using the "with_traceback()" exception method (which returns\nthe same exception instance, with its traceback set to its argument),\nlike so:\n\n raise Exception("foo occurred").with_traceback(tracebackobj)\n\nThe "from" clause is used for exception chaining: if given, the second\n*expression* must be another exception class or instance, which will\nthen be attached to the raised exception as the "__cause__" attribute\n(which is writable). If the raised exception is not handled, both\nexceptions will be printed:\n\n >>> try:\n ... print(1 / 0)\n ... except Exception as exc:\n ... raise RuntimeError("Something bad happened") from exc\n ...\n Traceback (most recent call last):\n File "", line 2, in \n ZeroDivisionError: int division or modulo by zero\n\n The above exception was the direct cause of the following exception:\n\n Traceback (most recent call last):\n File "", line 4, in \n RuntimeError: Something bad happened\n\nA similar mechanism works implicitly if an exception is raised inside\nan exception handler or a "finally" clause: the previous exception is\nthen attached as the new exception\'s "__context__" attribute:\n\n >>> try:\n ... print(1 / 0)\n ... except:\n ... raise RuntimeError("Something bad happened")\n ...\n Traceback (most recent call last):\n File "", line 2, in \n ZeroDivisionError: int division or modulo by zero\n\n During handling of the above exception, another exception occurred:\n\n Traceback (most recent call last):\n File "", line 4, in \n RuntimeError: Something bad happened\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information about handling exceptions is in section\n*The try statement*.\n', + 'return': u'\nThe "return" statement\n**********************\n\n return_stmt ::= "return" [expression_list]\n\n"return" may only occur syntactically nested in a function definition,\nnot within a nested class definition.\n\nIf an expression list is present, it is evaluated, else "None" is\nsubstituted.\n\n"return" leaves the current function call with the expression list (or\n"None") as return value.\n\nWhen "return" passes control out of a "try" statement with a "finally"\nclause, that "finally" clause is executed before really leaving the\nfunction.\n\nIn a generator function, the "return" statement indicates that the\ngenerator is done and will cause "StopIteration" to be raised. The\nreturned value (if any) is used as an argument to construct\n"StopIteration" and becomes the "StopIteration.value" attribute.\n', + 'sequence-types': u'\nEmulating container types\n*************************\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which "0 <= k < N" where\n*N* is the length of the sequence, or slice objects, which define a\nrange of items. It is also recommended that mappings provide the\nmethods "keys()", "values()", "items()", "get()", "clear()",\n"setdefault()", "pop()", "popitem()", "copy()", and "update()"\nbehaving similar to those for Python\'s standard dictionary objects.\nThe "collections" module provides a "MutableMapping" abstract base\nclass to help create those methods from a base set of "__getitem__()",\n"__setitem__()", "__delitem__()", and "keys()". Mutable sequences\nshould provide methods "append()", "count()", "index()", "extend()",\n"insert()", "pop()", "remove()", "reverse()" and "sort()", like Python\nstandard list objects. Finally, sequence types should implement\naddition (meaning concatenation) and multiplication (meaning\nrepetition) by defining the methods "__add__()", "__radd__()",\n"__iadd__()", "__mul__()", "__rmul__()" and "__imul__()" described\nbelow; they should not define other numerical operators. It is\nrecommended that both mappings and sequences implement the\n"__contains__()" method to allow efficient use of the "in" operator;\nfor mappings, "in" should search the mapping\'s keys; for sequences, it\nshould search through the values. It is further recommended that both\nmappings and sequences implement the "__iter__()" method to allow\nefficient iteration through the container; for mappings, "__iter__()"\nshould be the same as "keys()"; for sequences, it should iterate\nthrough the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function "len()". Should return\n the length of the object, an integer ">=" 0. Also, an object that\n doesn\'t define a "__bool__()" method and whose "__len__()" method\n returns zero is considered to be false in a Boolean context.\n\nobject.__length_hint__(self)\n\n Called to implement "operator.length_hint()". Should return an\n estimated length for the object (which may be greater or less than\n the actual length). The length must be an integer ">=" 0. This\n method is purely an optimization and is never required for\n correctness.\n\n New in version 3.4.\n\nNote: Slicing is done exclusively with the following three methods.\n A call like\n\n a[1:2] = b\n\n is translated to\n\n a[slice(1, 2, None)] = b\n\n and so forth. Missing slice items are always filled in with "None".\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of "self[key]". For sequence types,\n the accepted keys should be integers and slice objects. Note that\n the special interpretation of negative indexes (if the class wishes\n to emulate a sequence type) is up to the "__getitem__()" method. If\n *key* is of an inappropriate type, "TypeError" may be raised; if of\n a value outside the set of indexes for the sequence (after any\n special interpretation of negative values), "IndexError" should be\n raised. For mapping types, if *key* is missing (not in the\n container), "KeyError" should be raised.\n\n Note: "for" loops expect that an "IndexError" will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__missing__(self, key)\n\n Called by "dict"."__getitem__()" to implement "self[key]" for dict\n subclasses when key is not in the dictionary.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to "self[key]". Same note as for\n "__getitem__()". This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the "__getitem__()" method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of "self[key]". Same note as for\n "__getitem__()". This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the "__getitem__()" method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the "reversed()" built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the "__reversed__()" method is not provided, the "reversed()"\n built-in will fall back to using the sequence protocol ("__len__()"\n and "__getitem__()"). Objects that support the sequence protocol\n should only provide "__reversed__()" if they can provide an\n implementation that is more efficient than the one provided by\n "reversed()".\n\nThe membership test operators ("in" and "not in") are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n For objects that don\'t define "__contains__()", the membership test\n first tries iteration via "__iter__()", then the old sequence\n iteration protocol via "__getitem__()", see *this section in the\n language reference*.\n', + 'shifting': u'\nShifting operations\n*******************\n\nThe shifting operations have lower priority than the arithmetic\noperations:\n\n shift_expr ::= a_expr | shift_expr ( "<<" | ">>" ) a_expr\n\nThese operators accept integers as arguments. They shift the first\nargument to the left or right by the number of bits given by the\nsecond argument.\n\nA right shift by *n* bits is defined as floor division by "pow(2,n)".\nA left shift by *n* bits is defined as multiplication with "pow(2,n)".\n\nNote: In the current implementation, the right-hand operand is\n required to be at most "sys.maxsize". If the right-hand operand is\n larger than "sys.maxsize" an "OverflowError" exception is raised.\n', + 'slicings': u'\nSlicings\n********\n\nA slicing selects a range of items in a sequence object (e.g., a\nstring, tuple or list). Slicings may be used as expressions or as\ntargets in assignment or "del" statements. The syntax for a slicing:\n\n slicing ::= primary "[" slice_list "]"\n slice_list ::= slice_item ("," slice_item)* [","]\n slice_item ::= expression | proper_slice\n proper_slice ::= [lower_bound] ":" [upper_bound] [ ":" [stride] ]\n lower_bound ::= expression\n upper_bound ::= expression\n stride ::= expression\n\nThere is ambiguity in the formal syntax here: anything that looks like\nan expression list also looks like a slice list, so any subscription\ncan be interpreted as a slicing. Rather than further complicating the\nsyntax, this is disambiguated by defining that in this case the\ninterpretation as a subscription takes priority over the\ninterpretation as a slicing (this is the case if the slice list\ncontains no proper slice).\n\nThe semantics for a slicing are as follows. The primary is indexed\n(using the same "__getitem__()" method as normal subscription) with a\nkey that is constructed from the slice list, as follows. If the slice\nlist contains at least one comma, the key is a tuple containing the\nconversion of the slice items; otherwise, the conversion of the lone\nslice item is the key. The conversion of a slice item that is an\nexpression is that expression. The conversion of a proper slice is a\nslice object (see section *The standard type hierarchy*) whose\n"start", "stop" and "step" attributes are the values of the\nexpressions given as lower bound, upper bound and stride,\nrespectively, substituting "None" for missing expressions.\n', + 'specialattrs': u'\nSpecial Attributes\n******************\n\nThe implementation adds a few special read-only attributes to several\nobject types, where they are relevant. Some of these are not reported\nby the "dir()" built-in function.\n\nobject.__dict__\n\n A dictionary or other mapping object used to store an object\'s\n (writable) attributes.\n\ninstance.__class__\n\n The class to which a class instance belongs.\n\nclass.__bases__\n\n The tuple of base classes of a class object.\n\nclass.__name__\n\n The name of the class or type.\n\nclass.__qualname__\n\n The *qualified name* of the class or type.\n\n New in version 3.3.\n\nclass.__mro__\n\n This attribute is a tuple of classes that are considered when\n looking for base classes during method resolution.\n\nclass.mro()\n\n This method can be overridden by a metaclass to customize the\n method resolution order for its instances. It is called at class\n instantiation, and its result is stored in "__mro__".\n\nclass.__subclasses__()\n\n Each class keeps a list of weak references to its immediate\n subclasses. This method returns a list of all those references\n still alive. Example:\n\n >>> int.__subclasses__()\n []\n\n-[ Footnotes ]-\n\n[1] Additional information on these special methods may be found\n in the Python Reference Manual (*Basic customization*).\n\n[2] As a consequence, the list "[1, 2]" is considered equal to\n "[1.0, 2.0]", and similarly for tuples.\n\n[3] They must have since the parser can\'t tell the type of the\n operands.\n\n[4] Cased characters are those with general category property\n being one of "Lu" (Letter, uppercase), "Ll" (Letter, lowercase),\n or "Lt" (Letter, titlecase).\n\n[5] To format only a tuple you should therefore provide a\n singleton tuple whose only element is the tuple to be formatted.\n', + 'specialnames': u'\nSpecial method names\n********************\n\nA class can implement certain operations that are invoked by special\nsyntax (such as arithmetic operations or subscripting and slicing) by\ndefining methods with special names. This is Python\'s approach to\n*operator overloading*, allowing classes to define their own behavior\nwith respect to language operators. For instance, if a class defines\na method named "__getitem__()", and "x" is an instance of this class,\nthen "x[i]" is roughly equivalent to "type(x).__getitem__(x, i)".\nExcept where mentioned, attempts to execute an operation raise an\nexception when no appropriate method is defined (typically\n"AttributeError" or "TypeError").\n\nWhen implementing a class that emulates any built-in type, it is\nimportant that the emulation only be implemented to the degree that it\nmakes sense for the object being modelled. For example, some\nsequences may work well with retrieval of individual elements, but\nextracting a slice may not make sense. (One example of this is the\n"NodeList" interface in the W3C\'s Document Object Model.)\n\n\nBasic customization\n===================\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. "__new__()" is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of "__new__()" should be the new object instance (usually an\n instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s "__new__()" method using\n "super(currentclass, cls).__new__(cls[, ...])" with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If "__new__()" returns an instance of *cls*, then the new\n instance\'s "__init__()" method will be invoked like\n "__init__(self[, ...])", where *self* is the new instance and the\n remaining arguments are the same as were passed to "__new__()".\n\n If "__new__()" does not return an instance of *cls*, then the new\n instance\'s "__init__()" method will not be invoked.\n\n "__new__()" is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called after the instance has been created (by "__new__()"), but\n before it is returned to the caller. The arguments are those\n passed to the class constructor expression. If a base class has an\n "__init__()" method, the derived class\'s "__init__()" method, if\n any, must explicitly call it to ensure proper initialization of the\n base class part of the instance; for example:\n "BaseClass.__init__(self, [args...])".\n\n Because "__new__()" and "__init__()" work together in constructing\n objects ("__new__()" to create it, and "__init__()" to customise\n it), no non-"None" value may be returned by "__init__()"; doing so\n will cause a "TypeError" to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a "__del__()" method, the\n derived class\'s "__del__()" method, if any, must explicitly call it\n to ensure proper deletion of the base class part of the instance.\n Note that it is possible (though not recommended!) for the\n "__del__()" method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n "__del__()" methods are called for objects that still exist when\n the interpreter exits.\n\n Note: "del x" doesn\'t directly call "x.__del__()" --- the former\n decrements the reference count for "x" by one, and the latter is\n only called when "x"\'s reference count reaches zero. Some common\n situations that may prevent the reference count of an object from\n going to zero include: circular references between objects (e.g.,\n a doubly-linked list or a tree data structure with parent and\n child pointers); a reference to the object on the stack frame of\n a function that caught an exception (the traceback stored in\n "sys.exc_info()[2]" keeps the stack frame alive); or a reference\n to the object on the stack frame that raised an unhandled\n exception in interactive mode (the traceback stored in\n "sys.last_traceback" keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the second can be resolved by freeing the reference to the\n traceback object when it is no longer useful, and the third can\n be resolved by storing "None" in "sys.last_traceback". Circular\n references which are garbage are detected and cleaned up when the\n cyclic garbage collector is enabled (it\'s on by default). Refer\n to the documentation for the "gc" module for more information\n about this topic.\n\n Warning: Due to the precarious circumstances under which\n "__del__()" methods are invoked, exceptions that occur during\n their execution are ignored, and a warning is printed to\n "sys.stderr" instead. Also, when "__del__()" is invoked in\n response to a module being deleted (e.g., when execution of the\n program is done), other globals referenced by the "__del__()"\n method may already have been deleted or in the process of being\n torn down (e.g. the import machinery shutting down). For this\n reason, "__del__()" methods should do the absolute minimum needed\n to maintain external invariants. Starting with version 1.5,\n Python guarantees that globals whose name begins with a single\n underscore are deleted from their module before other globals are\n deleted; if no other references to such globals exist, this may\n help in assuring that imported modules are still available at the\n time when the "__del__()" method is called.\n\nobject.__repr__(self)\n\n Called by the "repr()" built-in function to compute the "official"\n string representation of an object. If at all possible, this\n should look like a valid Python expression that could be used to\n recreate an object with the same value (given an appropriate\n environment). If this is not possible, a string of the form\n "<...some useful description...>" should be returned. The return\n value must be a string object. If a class defines "__repr__()" but\n not "__str__()", then "__repr__()" is also used when an "informal"\n string representation of instances of that class is required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by "str(object)" and the built-in functions "format()" and\n "print()" to compute the "informal" or nicely printable string\n representation of an object. The return value must be a *string*\n object.\n\n This method differs from "object.__repr__()" in that there is no\n expectation that "__str__()" return a valid Python expression: a\n more convenient or concise representation can be used.\n\n The default implementation defined by the built-in type "object"\n calls "object.__repr__()".\n\nobject.__bytes__(self)\n\n Called by "bytes()" to compute a byte-string representation of an\n object. This should return a "bytes" object.\n\nobject.__format__(self, format_spec)\n\n Called by the "format()" built-in function (and by extension, the\n "str.format()" method of class "str") to produce a "formatted"\n string representation of an object. The "format_spec" argument is a\n string that contains a description of the formatting options\n desired. The interpretation of the "format_spec" argument is up to\n the type implementing "__format__()", however most classes will\n either delegate formatting to one of the built-in types, or use a\n similar formatting option syntax.\n\n See *Format Specification Mini-Language* for a description of the\n standard formatting syntax.\n\n The return value must be a string object.\n\n Changed in version 3.4: The __format__ method of "object" itself\n raises a "TypeError" if passed any non-empty string.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n These are the so-called "rich comparison" methods. The\n correspondence between operator symbols and method names is as\n follows: "xy" calls\n "x.__gt__(y)", and "x>=y" calls "x.__ge__(y)".\n\n A rich comparison method may return the singleton "NotImplemented"\n if it does not implement the operation for a given pair of\n arguments. By convention, "False" and "True" are returned for a\n successful comparison. However, these methods can return any value,\n so if the comparison operator is used in a Boolean context (e.g.,\n in the condition of an "if" statement), Python will call "bool()"\n on the value to determine if the result is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of "x==y" does not imply that "x!=y" is false.\n Accordingly, when defining "__eq__()", one should also define\n "__ne__()" so that the operators will behave as expected. See the\n paragraph on "__hash__()" for some important notes on creating\n *hashable* objects which support custom comparison operations and\n are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, "__lt__()" and "__gt__()" are each other\'s\n reflection, "__le__()" and "__ge__()" are each other\'s reflection,\n and "__eq__()" and "__ne__()" are their own reflection.\n\n Arguments to rich comparison methods are never coerced.\n\n To automatically generate ordering operations from a single root\n operation, see "functools.total_ordering()".\n\nobject.__hash__(self)\n\n Called by built-in function "hash()" and for operations on members\n of hashed collections including "set", "frozenset", and "dict".\n "__hash__()" should return an integer. The only required property\n is that objects which compare equal have the same hash value; it is\n advised to somehow mix together (e.g. using exclusive or) the hash\n values for the components of the object that also play a part in\n comparison of objects.\n\n Note: "hash()" truncates the value returned from an object\'s\n custom "__hash__()" method to the size of a "Py_ssize_t". This\n is typically 8 bytes on 64-bit builds and 4 bytes on 32-bit\n builds. If an object\'s "__hash__()" must interoperate on builds\n of different bit sizes, be sure to check the width on all\n supported builds. An easy way to do this is with "python -c\n "import sys; print(sys.hash_info.width)""\n\n If a class does not define an "__eq__()" method it should not\n define a "__hash__()" operation either; if it defines "__eq__()"\n but not "__hash__()", its instances will not be usable as items in\n hashable collections. If a class defines mutable objects and\n implements an "__eq__()" method, it should not implement\n "__hash__()", since the implementation of hashable collections\n requires that a key\'s hash value is immutable (if the object\'s hash\n value changes, it will be in the wrong hash bucket).\n\n User-defined classes have "__eq__()" and "__hash__()" methods by\n default; with them, all objects compare unequal (except with\n themselves) and "x.__hash__()" returns an appropriate value such\n that "x == y" implies both that "x is y" and "hash(x) == hash(y)".\n\n A class that overrides "__eq__()" and does not define "__hash__()"\n will have its "__hash__()" implicitly set to "None". When the\n "__hash__()" method of a class is "None", instances of the class\n will raise an appropriate "TypeError" when a program attempts to\n retrieve their hash value, and will also be correctly identified as\n unhashable when checking "isinstance(obj, collections.Hashable").\n\n If a class that overrides "__eq__()" needs to retain the\n implementation of "__hash__()" from a parent class, the interpreter\n must be told this explicitly by setting "__hash__ =\n .__hash__".\n\n If a class that does not override "__eq__()" wishes to suppress\n hash support, it should include "__hash__ = None" in the class\n definition. A class which defines its own "__hash__()" that\n explicitly raises a "TypeError" would be incorrectly identified as\n hashable by an "isinstance(obj, collections.Hashable)" call.\n\n Note: By default, the "__hash__()" values of str, bytes and\n datetime objects are "salted" with an unpredictable random value.\n Although they remain constant within an individual Python\n process, they are not predictable between repeated invocations of\n Python.This is intended to provide protection against a denial-\n of-service caused by carefully-chosen inputs that exploit the\n worst case performance of a dict insertion, O(n^2) complexity.\n See http://www.ocert.org/advisories/ocert-2011-003.html for\n details.Changing hash values affects the iteration order of\n dicts, sets and other mappings. Python has never made guarantees\n about this ordering (and it typically varies between 32-bit and\n 64-bit builds).See also "PYTHONHASHSEED".\n\n Changed in version 3.3: Hash randomization is enabled by default.\n\nobject.__bool__(self)\n\n Called to implement truth value testing and the built-in operation\n "bool()"; should return "False" or "True". When this method is not\n defined, "__len__()" is called, if it is defined, and the object is\n considered true if its result is nonzero. If a class defines\n neither "__len__()" nor "__bool__()", all its instances are\n considered true.\n\n\nCustomizing attribute access\n============================\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of "x.name") for\nclass instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for "self"). "name" is the attribute name. This\n method should return the (computed) attribute value or raise an\n "AttributeError" exception.\n\n Note that if the attribute is found through the normal mechanism,\n "__getattr__()" is not called. (This is an intentional asymmetry\n between "__getattr__()" and "__setattr__()".) This is done both for\n efficiency reasons and because otherwise "__getattr__()" would have\n no way to access other attributes of the instance. Note that at\n least for instance variables, you can fake total control by not\n inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n "__getattribute__()" method below for a way to actually get total\n control over attribute access.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines "__getattr__()",\n the latter will not be called unless "__getattribute__()" either\n calls it explicitly or raises an "AttributeError". This method\n should return the (computed) attribute value or raise an\n "AttributeError" exception. In order to avoid infinite recursion in\n this method, its implementation should always call the base class\n method with the same name to access any attributes it needs, for\n example, "object.__getattribute__(self, name)".\n\n Note: This method may still be bypassed when looking up special\n methods as the result of implicit invocation via language syntax\n or built-in functions. See *Special method lookup*.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If "__setattr__()" wants to assign to an instance attribute, it\n should call the base class method with the same name, for example,\n "object.__setattr__(self, name, value)".\n\nobject.__delattr__(self, name)\n\n Like "__setattr__()" but for attribute deletion instead of\n assignment. This should only be implemented if "del obj.name" is\n meaningful for the object.\n\nobject.__dir__(self)\n\n Called when "dir()" is called on the object. A sequence must be\n returned. "dir()" converts the returned sequence to a list and\n sorts it.\n\n\nImplementing Descriptors\n------------------------\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in an\n*owner* class (the descriptor must be in either the owner\'s class\ndictionary or in the class dictionary for one of its parents). In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' "__dict__".\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or "None" when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an "AttributeError"\n exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\nThe attribute "__objclass__" is interpreted by the "inspect" module as\nspecifying the class where this object was defined (setting this\nappropriately can assist in runtime introspection of dynamic class\nattributes). For callables, it may indicate that an instance of the\ngiven type (or a subclass) is expected or required as the first\npositional argument (for example, CPython sets this attribute for\nunbound methods that are implemented in C).\n\n\nInvoking Descriptors\n--------------------\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: "__get__()", "__set__()", and\n"__delete__()". If any of those methods are defined for an object, it\nis said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, "a.x" has a\nlookup chain starting with "a.__dict__[\'x\']", then\n"type(a).__dict__[\'x\']", and continuing through the base classes of\n"type(a)" excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called.\n\nThe starting point for descriptor invocation is a binding, "a.x". How\nthe arguments are assembled depends on "a":\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: "x.__get__(a)".\n\nInstance Binding\n If binding to an object instance, "a.x" is transformed into the\n call: "type(a).__dict__[\'x\'].__get__(a, type(a))".\n\nClass Binding\n If binding to a class, "A.x" is transformed into the call:\n "A.__dict__[\'x\'].__get__(None, A)".\n\nSuper Binding\n If "a" is an instance of "super", then the binding "super(B,\n obj).m()" searches "obj.__class__.__mro__" for the base class "A"\n immediately preceding "B" and then invokes the descriptor with the\n call: "A.__dict__[\'m\'].__get__(obj, obj.__class__)".\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of "__get__()", "__set__()" and "__delete__()". If it\ndoes not define "__get__()", then accessing the attribute will return\nthe descriptor object itself unless there is a value in the object\'s\ninstance dictionary. If the descriptor defines "__set__()" and/or\n"__delete__()", it is a data descriptor; if it defines neither, it is\na non-data descriptor. Normally, data descriptors define both\n"__get__()" and "__set__()", while non-data descriptors have just the\n"__get__()" method. Data descriptors with "__set__()" and "__get__()"\ndefined always override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances.\n\nPython methods (including "staticmethod()" and "classmethod()") are\nimplemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe "property()" function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n---------\n\nBy default, instances of classes have a dictionary for attribute\nstorage. This wastes space for objects having very few instance\nvariables. The space consumption can become acute when creating large\nnumbers of instances.\n\nThe default can be overridden by defining *__slots__* in a class\ndefinition. The *__slots__* declaration takes a sequence of instance\nvariables and reserves just enough space in each instance to hold a\nvalue for each variable. Space is saved because *__dict__* is not\ncreated for each instance.\n\nobject.__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. *__slots__*\n reserves space for the declared variables and prevents the\n automatic creation of *__dict__* and *__weakref__* for each\n instance.\n\n\nNotes on using *__slots__*\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises "AttributeError". If\n dynamic assignment of new variables is desired, then add\n "\'__dict__\'" to the sequence of strings in the *__slots__*\n declaration.\n\n* Without a *__weakref__* variable for each instance, classes\n defining *__slots__* do not support weak references to its\n instances. If weak reference support is needed, then add\n "\'__weakref__\'" to the sequence of strings in the *__slots__*\n declaration.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the\n instance variable defined by the base class slot is inaccessible\n (except by retrieving its descriptor directly from the base class).\n This renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as "int", "bytes" and "tuple".\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings\n may also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, classes are constructed using "type()". The class body is\nexecuted in a new namespace and the class name is bound locally to the\nresult of "type(name, bases, namespace)".\n\nThe class creation process can be customised by passing the\n"metaclass" keyword argument in the class definition line, or by\ninheriting from an existing class that included such an argument. In\nthe following example, both "MyClass" and "MySubclass" are instances\nof "Meta":\n\n class Meta(type):\n pass\n\n class MyClass(metaclass=Meta):\n pass\n\n class MySubclass(MyClass):\n pass\n\nAny other keyword arguments that are specified in the class definition\nare passed through to all metaclass operations described below.\n\nWhen a class definition is executed, the following steps occur:\n\n* the appropriate metaclass is determined\n\n* the class namespace is prepared\n\n* the class body is executed\n\n* the class object is created\n\n\nDetermining the appropriate metaclass\n-------------------------------------\n\nThe appropriate metaclass for a class definition is determined as\nfollows:\n\n* if no bases and no explicit metaclass are given, then "type()" is\n used\n\n* if an explicit metaclass is given and it is *not* an instance of\n "type()", then it is used directly as the metaclass\n\n* if an instance of "type()" is given as the explicit metaclass, or\n bases are defined, then the most derived metaclass is used\n\nThe most derived metaclass is selected from the explicitly specified\nmetaclass (if any) and the metaclasses (i.e. "type(cls)") of all\nspecified base classes. The most derived metaclass is one which is a\nsubtype of *all* of these candidate metaclasses. If none of the\ncandidate metaclasses meets that criterion, then the class definition\nwill fail with "TypeError".\n\n\nPreparing the class namespace\n-----------------------------\n\nOnce the appropriate metaclass has been identified, then the class\nnamespace is prepared. If the metaclass has a "__prepare__" attribute,\nit is called as "namespace = metaclass.__prepare__(name, bases,\n**kwds)" (where the additional keyword arguments, if any, come from\nthe class definition).\n\nIf the metaclass has no "__prepare__" attribute, then the class\nnamespace is initialised as an empty "dict()" instance.\n\nSee also: **PEP 3115** - Metaclasses in Python 3000\n\n Introduced the "__prepare__" namespace hook\n\n\nExecuting the class body\n------------------------\n\nThe class body is executed (approximately) as "exec(body, globals(),\nnamespace)". The key difference from a normal call to "exec()" is that\nlexical scoping allows the class body (including any methods) to\nreference names from the current and outer scopes when the class\ndefinition occurs inside a function.\n\nHowever, even when the class definition occurs inside the function,\nmethods defined inside the class still cannot see names defined at the\nclass scope. Class variables must be accessed through the first\nparameter of instance or class methods, and cannot be accessed at all\nfrom static methods.\n\n\nCreating the class object\n-------------------------\n\nOnce the class namespace has been populated by executing the class\nbody, the class object is created by calling "metaclass(name, bases,\nnamespace, **kwds)" (the additional keywords passed here are the same\nas those passed to "__prepare__").\n\nThis class object is the one that will be referenced by the zero-\nargument form of "super()". "__class__" is an implicit closure\nreference created by the compiler if any methods in a class body refer\nto either "__class__" or "super". This allows the zero argument form\nof "super()" to correctly identify the class being defined based on\nlexical scoping, while the class or instance that was used to make the\ncurrent call is identified based on the first argument passed to the\nmethod.\n\nAfter the class object is created, it is passed to the class\ndecorators included in the class definition (if any) and the resulting\nobject is bound in the local namespace as the defined class.\n\nSee also: **PEP 3135** - New super\n\n Describes the implicit "__class__" closure reference\n\n\nMetaclass example\n-----------------\n\nThe potential uses for metaclasses are boundless. Some ideas that have\nbeen explored include logging, interface checking, automatic\ndelegation, automatic property creation, proxies, frameworks, and\nautomatic resource locking/synchronization.\n\nHere is an example of a metaclass that uses an\n"collections.OrderedDict" to remember the order that class variables\nare defined:\n\n class OrderedClass(type):\n\n @classmethod\n def __prepare__(metacls, name, bases, **kwds):\n return collections.OrderedDict()\n\n def __new__(cls, name, bases, namespace, **kwds):\n result = type.__new__(cls, name, bases, dict(namespace))\n result.members = tuple(namespace)\n return result\n\n class A(metaclass=OrderedClass):\n def one(self): pass\n def two(self): pass\n def three(self): pass\n def four(self): pass\n\n >>> A.members\n (\'__module__\', \'one\', \'two\', \'three\', \'four\')\n\nWhen the class definition for *A* gets executed, the process begins\nwith calling the metaclass\'s "__prepare__()" method which returns an\nempty "collections.OrderedDict". That mapping records the methods and\nattributes of *A* as they are defined within the body of the class\nstatement. Once those definitions are executed, the ordered dictionary\nis fully populated and the metaclass\'s "__new__()" method gets\ninvoked. That method builds the new type and it saves the ordered\ndictionary keys in an attribute called "members".\n\n\nCustomizing instance and subclass checks\n========================================\n\nThe following methods are used to override the default behavior of the\n"isinstance()" and "issubclass()" built-in functions.\n\nIn particular, the metaclass "abc.ABCMeta" implements these methods in\norder to allow the addition of Abstract Base Classes (ABCs) as\n"virtual base classes" to any class or type (including built-in\ntypes), including other ABCs.\n\nclass.__instancecheck__(self, instance)\n\n Return true if *instance* should be considered a (direct or\n indirect) instance of *class*. If defined, called to implement\n "isinstance(instance, class)".\n\nclass.__subclasscheck__(self, subclass)\n\n Return true if *subclass* should be considered a (direct or\n indirect) subclass of *class*. If defined, called to implement\n "issubclass(subclass, class)".\n\nNote that these methods are looked up on the type (metaclass) of a\nclass. They cannot be defined as class methods in the actual class.\nThis is consistent with the lookup of special methods that are called\non instances, only in this case the instance is itself a class.\n\nSee also: **PEP 3119** - Introducing Abstract Base Classes\n\n Includes the specification for customizing "isinstance()" and\n "issubclass()" behavior through "__instancecheck__()" and\n "__subclasscheck__()", with motivation for this functionality in\n the context of adding Abstract Base Classes (see the "abc"\n module) to the language.\n\n\nEmulating callable objects\n==========================\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, "x(arg1, arg2, ...)" is a shorthand for\n "x.__call__(arg1, arg2, ...)".\n\n\nEmulating container types\n=========================\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which "0 <= k < N" where\n*N* is the length of the sequence, or slice objects, which define a\nrange of items. It is also recommended that mappings provide the\nmethods "keys()", "values()", "items()", "get()", "clear()",\n"setdefault()", "pop()", "popitem()", "copy()", and "update()"\nbehaving similar to those for Python\'s standard dictionary objects.\nThe "collections" module provides a "MutableMapping" abstract base\nclass to help create those methods from a base set of "__getitem__()",\n"__setitem__()", "__delitem__()", and "keys()". Mutable sequences\nshould provide methods "append()", "count()", "index()", "extend()",\n"insert()", "pop()", "remove()", "reverse()" and "sort()", like Python\nstandard list objects. Finally, sequence types should implement\naddition (meaning concatenation) and multiplication (meaning\nrepetition) by defining the methods "__add__()", "__radd__()",\n"__iadd__()", "__mul__()", "__rmul__()" and "__imul__()" described\nbelow; they should not define other numerical operators. It is\nrecommended that both mappings and sequences implement the\n"__contains__()" method to allow efficient use of the "in" operator;\nfor mappings, "in" should search the mapping\'s keys; for sequences, it\nshould search through the values. It is further recommended that both\nmappings and sequences implement the "__iter__()" method to allow\nefficient iteration through the container; for mappings, "__iter__()"\nshould be the same as "keys()"; for sequences, it should iterate\nthrough the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function "len()". Should return\n the length of the object, an integer ">=" 0. Also, an object that\n doesn\'t define a "__bool__()" method and whose "__len__()" method\n returns zero is considered to be false in a Boolean context.\n\nobject.__length_hint__(self)\n\n Called to implement "operator.length_hint()". Should return an\n estimated length for the object (which may be greater or less than\n the actual length). The length must be an integer ">=" 0. This\n method is purely an optimization and is never required for\n correctness.\n\n New in version 3.4.\n\nNote: Slicing is done exclusively with the following three methods.\n A call like\n\n a[1:2] = b\n\n is translated to\n\n a[slice(1, 2, None)] = b\n\n and so forth. Missing slice items are always filled in with "None".\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of "self[key]". For sequence types,\n the accepted keys should be integers and slice objects. Note that\n the special interpretation of negative indexes (if the class wishes\n to emulate a sequence type) is up to the "__getitem__()" method. If\n *key* is of an inappropriate type, "TypeError" may be raised; if of\n a value outside the set of indexes for the sequence (after any\n special interpretation of negative values), "IndexError" should be\n raised. For mapping types, if *key* is missing (not in the\n container), "KeyError" should be raised.\n\n Note: "for" loops expect that an "IndexError" will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__missing__(self, key)\n\n Called by "dict"."__getitem__()" to implement "self[key]" for dict\n subclasses when key is not in the dictionary.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to "self[key]". Same note as for\n "__getitem__()". This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the "__getitem__()" method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of "self[key]". Same note as for\n "__getitem__()". This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the "__getitem__()" method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the "reversed()" built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the "__reversed__()" method is not provided, the "reversed()"\n built-in will fall back to using the sequence protocol ("__len__()"\n and "__getitem__()"). Objects that support the sequence protocol\n should only provide "__reversed__()" if they can provide an\n implementation that is more efficient than the one provided by\n "reversed()".\n\nThe membership test operators ("in" and "not in") are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n For objects that don\'t define "__contains__()", the membership test\n first tries iteration via "__iter__()", then the old sequence\n iteration protocol via "__getitem__()", see *this section in the\n language reference*.\n\n\nEmulating numeric types\n=======================\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__matmul__(self, other)\nobject.__truediv__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations ("+", "-", "*", "@", "/", "//", "%", "divmod()",\n "pow()", "**", "<<", ">>", "&", "^", "|"). For instance, to\n evaluate the expression "x + y", where *x* is an instance of a\n class that has an "__add__()" method, "x.__add__(y)" is called.\n The "__divmod__()" method should be the equivalent to using\n "__floordiv__()" and "__mod__()"; it should not be related to\n "__truediv__()". Note that "__pow__()" should be defined to accept\n an optional third argument if the ternary version of the built-in\n "pow()" function is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return "NotImplemented".\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rmatmul__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations ("+", "-", "*", "@", "/", "//", "%", "divmod()",\n "pow()", "**", "<<", ">>", "&", "^", "|") with reflected (swapped)\n operands. These functions are only called if the left operand does\n not support the corresponding operation and the operands are of\n different types. [2] For instance, to evaluate the expression "x -\n y", where *y* is an instance of a class that has an "__rsub__()"\n method, "y.__rsub__(x)" is called if "x.__sub__(y)" returns\n *NotImplemented*.\n\n Note that ternary "pow()" will not try calling "__rpow__()" (the\n coercion rules would become too complicated).\n\n Note: If the right operand\'s type is a subclass of the left\n operand\'s type and that subclass provides the reflected method\n for the operation, this method will be called before the left\n operand\'s non-reflected method. This behavior allows subclasses\n to override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__imatmul__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n assignments ("+=", "-=", "*=", "@=", "/=", "//=", "%=", "**=",\n "<<=", ">>=", "&=", "^=", "|="). These methods should attempt to\n do the operation in-place (modifying *self*) and return the result\n (which could be, but does not have to be, *self*). If a specific\n method is not defined, the augmented assignment falls back to the\n normal methods. For instance, if *x* is an instance of a class\n with an "__iadd__()" method, "x += y" is equivalent to "x =\n x.__iadd__(y)" . Otherwise, "x.__add__(y)" and "y.__radd__(x)" are\n considered, as with the evaluation of "x + y". In certain\n situations, augmented assignment can result in unexpected errors\n (see *Why does a_tuple[i] += [\'item\'] raise an exception when the\n addition works?*), but this behavior is in fact part of the data\n model.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations ("-", "+",\n "abs()" and "~").\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__float__(self)\nobject.__round__(self[, n])\n\n Called to implement the built-in functions "complex()", "int()",\n "float()" and "round()". Should return a value of the appropriate\n type.\n\nobject.__index__(self)\n\n Called to implement "operator.index()", and whenever Python needs\n to losslessly convert the numeric object to an integer object (such\n as in slicing, or in the built-in "bin()", "hex()" and "oct()"\n functions). Presence of this method indicates that the numeric\n object is an integer type. Must return an integer.\n\n Note: In order to have a coherent integer type class, when\n "__index__()" is defined "__int__()" should also be defined, and\n both should return the same value.\n\n\nWith Statement Context Managers\n===============================\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a "with" statement. The context manager\nhandles the entry into, and the exit from, the desired runtime context\nfor the execution of the block of code. Context managers are normally\ninvoked using the "with" statement (described in section *The with\nstatement*), but can also be used by directly invoking their methods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The "with"\n statement will bind this method\'s return value to the target(s)\n specified in the "as" clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be "None".\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that "__exit__()" methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also: **PEP 0343** - The "with" statement\n\n The specification, background, and examples for the Python "with"\n statement.\n\n\nSpecial method lookup\n=====================\n\nFor custom classes, implicit invocations of special methods are only\nguaranteed to work correctly if defined on an object\'s type, not in\nthe object\'s instance dictionary. That behaviour is the reason why\nthe following code raises an exception:\n\n >>> class C:\n ... pass\n ...\n >>> c = C()\n >>> c.__len__ = lambda: 5\n >>> len(c)\n Traceback (most recent call last):\n File "", line 1, in \n TypeError: object of type \'C\' has no len()\n\nThe rationale behind this behaviour lies with a number of special\nmethods such as "__hash__()" and "__repr__()" that are implemented by\nall objects, including type objects. If the implicit lookup of these\nmethods used the conventional lookup process, they would fail when\ninvoked on the type object itself:\n\n >>> 1 .__hash__() == hash(1)\n True\n >>> int.__hash__() == hash(int)\n Traceback (most recent call last):\n File "", line 1, in \n TypeError: descriptor \'__hash__\' of \'int\' object needs an argument\n\nIncorrectly attempting to invoke an unbound method of a class in this\nway is sometimes referred to as \'metaclass confusion\', and is avoided\nby bypassing the instance when looking up special methods:\n\n >>> type(1).__hash__(1) == hash(1)\n True\n >>> type(int).__hash__(int) == hash(int)\n True\n\nIn addition to bypassing any instance attributes in the interest of\ncorrectness, implicit special method lookup generally also bypasses\nthe "__getattribute__()" method even of the object\'s metaclass:\n\n >>> class Meta(type):\n ... def __getattribute__(*args):\n ... print("Metaclass getattribute invoked")\n ... return type.__getattribute__(*args)\n ...\n >>> class C(object, metaclass=Meta):\n ... def __len__(self):\n ... return 10\n ... def __getattribute__(*args):\n ... print("Class getattribute invoked")\n ... return object.__getattribute__(*args)\n ...\n >>> c = C()\n >>> c.__len__() # Explicit lookup via instance\n Class getattribute invoked\n 10\n >>> type(c).__len__(c) # Explicit lookup via type\n Metaclass getattribute invoked\n 10\n >>> len(c) # Implicit lookup\n 10\n\nBypassing the "__getattribute__()" machinery in this fashion provides\nsignificant scope for speed optimisations within the interpreter, at\nthe cost of some flexibility in the handling of special methods (the\nspecial method *must* be set on the class object itself in order to be\nconsistently invoked by the interpreter).\n', + 'string-methods': u'\nString Methods\n**************\n\nStrings implement all of the *common* sequence operations, along with\nthe additional methods described below.\n\nStrings also support two styles of string formatting, one providing a\nlarge degree of flexibility and customization (see "str.format()",\n*Format String Syntax* and *String Formatting*) and the other based on\nC "printf" style formatting that handles a narrower range of types and\nis slightly harder to use correctly, but is often faster for the cases\nit can handle (*printf-style String Formatting*).\n\nThe *Text Processing Services* section of the standard library covers\na number of other modules that provide various text related utilities\n(including regular expression support in the "re" module).\n\nstr.capitalize()\n\n Return a copy of the string with its first character capitalized\n and the rest lowercased.\n\nstr.casefold()\n\n Return a casefolded copy of the string. Casefolded strings may be\n used for caseless matching.\n\n Casefolding is similar to lowercasing but more aggressive because\n it is intended to remove all case distinctions in a string. For\n example, the German lowercase letter "\'\xdf\'" is equivalent to ""ss"".\n Since it is already lowercase, "lower()" would do nothing to "\'\xdf\'";\n "casefold()" converts it to ""ss"".\n\n The casefolding algorithm is described in section 3.13 of the\n Unicode Standard.\n\n New in version 3.3.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is an ASCII space). The\n original string is returned if *width* is less than or equal to\n "len(s)".\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.encode(encoding="utf-8", errors="strict")\n\n Return an encoded version of the string as a bytes object. Default\n encoding is "\'utf-8\'". *errors* may be given to set a different\n error handling scheme. The default for *errors* is "\'strict\'",\n meaning that encoding errors raise a "UnicodeError". Other possible\n values are "\'ignore\'", "\'replace\'", "\'xmlcharrefreplace\'",\n "\'backslashreplace\'" and any other name registered via\n "codecs.register_error()", see section *Error Handlers*. For a list\n of possible encodings, see section *Standard Encodings*.\n\n Changed in version 3.1: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return "True" if the string ends with the specified *suffix*,\n otherwise return "False". *suffix* can also be a tuple of suffixes\n to look for. With optional *start*, test beginning at that\n position. With optional *end*, stop comparing at that position.\n\nstr.expandtabs(tabsize=8)\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. Tab positions occur every *tabsize* characters\n (default is 8, giving tab positions at columns 0, 8, 16 and so on).\n To expand the string, the current column is set to zero and the\n string is examined character by character. If the character is a\n tab ("\\t"), one or more space characters are inserted in the result\n until the current column is equal to the next tab position. (The\n tab character itself is not copied.) If the character is a newline\n ("\\n") or return ("\\r"), it is copied and the current column is\n reset to zero. Any other character is copied unchanged and the\n current column is incremented by one regardless of how the\n character is represented when printed.\n\n >>> \'01\\t012\\t0123\\t01234\'.expandtabs()\n \'01 012 0123 01234\'\n >>> \'01\\t012\\t0123\\t01234\'.expandtabs(4)\n \'01 012 0123 01234\'\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice "s[start:end]".\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return "-1" if *sub* is not found.\n\n Note: The "find()" method should be used only if you need to know\n the position of *sub*. To check if *sub* is a substring or not,\n use the "in" operator:\n\n >>> \'Py\' in \'Python\'\n True\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces "{}". Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\nstr.format_map(mapping)\n\n Similar to "str.format(**mapping)", except that "mapping" is used\n directly and not copied to a "dict". This is useful if for example\n "mapping" is a dict subclass:\n\n >>> class Default(dict):\n ... def __missing__(self, key):\n ... return key\n ...\n >>> \'{name} was born in {country}\'.format_map(Default(name=\'Guido\'))\n \'Guido was born in country\'\n\n New in version 3.2.\n\nstr.index(sub[, start[, end]])\n\n Like "find()", but raise "ValueError" when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise. A character "c"\n is alphanumeric if one of the following returns "True":\n "c.isalpha()", "c.isdecimal()", "c.isdigit()", or "c.isnumeric()".\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise. Alphabetic\n characters are those characters defined in the Unicode character\n database as "Letter", i.e., those with general category property\n being one of "Lm", "Lt", "Lu", "Ll", or "Lo". Note that this is\n different from the "Alphabetic" property defined in the Unicode\n Standard.\n\nstr.isdecimal()\n\n Return true if all characters in the string are decimal characters\n and there is at least one character, false otherwise. Decimal\n characters are those from general category "Nd". This category\n includes digit characters, and all characters that can be used to\n form decimal-radix numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise. Digits include decimal\n characters and digits that need special handling, such as the\n compatibility superscript digits. Formally, a digit is a character\n that has the property value Numeric_Type=Digit or\n Numeric_Type=Decimal.\n\nstr.isidentifier()\n\n Return true if the string is a valid identifier according to the\n language definition, section *Identifiers and keywords*.\n\n Use "keyword.iskeyword()" to test for reserved identifiers such as\n "def" and "class".\n\nstr.islower()\n\n Return true if all cased characters [4] in the string are lowercase\n and there is at least one cased character, false otherwise.\n\nstr.isnumeric()\n\n Return true if all characters in the string are numeric characters,\n and there is at least one character, false otherwise. Numeric\n characters include digit characters, and all characters that have\n the Unicode numeric value property, e.g. U+2155, VULGAR FRACTION\n ONE FIFTH. Formally, numeric characters are those with the\n property value Numeric_Type=Digit, Numeric_Type=Decimal or\n Numeric_Type=Numeric.\n\nstr.isprintable()\n\n Return true if all characters in the string are printable or the\n string is empty, false otherwise. Nonprintable characters are\n those characters defined in the Unicode character database as\n "Other" or "Separator", excepting the ASCII space (0x20) which is\n considered printable. (Note that printable characters in this\n context are those which should not be escaped when "repr()" is\n invoked on a string. It has no bearing on the handling of strings\n written to "sys.stdout" or "sys.stderr".)\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise. Whitespace\n characters are those characters defined in the Unicode character\n database as "Other" or "Separator" and those with bidirectional\n property being one of "WS", "B", or "S".\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\nstr.isupper()\n\n Return true if all cased characters [4] in the string are uppercase\n and there is at least one cased character, false otherwise.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. A "TypeError" will be raised if there are\n any non-string values in *iterable*, including "bytes" objects.\n The separator between elements is the string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is an ASCII\n space). The original string is returned if *width* is less than or\n equal to "len(s)".\n\nstr.lower()\n\n Return a copy of the string with all the cased characters [4]\n converted to lowercase.\n\n The lowercasing algorithm used is described in section 3.13 of the\n Unicode Standard.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or "None", the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\nstatic str.maketrans(x[, y[, z]])\n\n This static method returns a translation table usable for\n "str.translate()".\n\n If there is only one argument, it must be a dictionary mapping\n Unicode ordinals (integers) or characters (strings of length 1) to\n Unicode ordinals, strings (of arbitrary lengths) or None.\n Character keys will then be converted to ordinals.\n\n If there are two arguments, they must be strings of equal length,\n and in the resulting dictionary, each character in x will be mapped\n to the character at the same position in y. If there is a third\n argument, it must be a string, whose characters will be mapped to\n None in the result.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within "s[start:end]".\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return "-1" on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like "rfind()" but raises "ValueError" when the substring *sub* is\n not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is an ASCII\n space). The original string is returned if *width* is less than or\n equal to "len(s)".\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\nstr.rsplit(sep=None, maxsplit=-1)\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n "None", any whitespace string is a separator. Except for splitting\n from the right, "rsplit()" behaves like "split()" which is\n described in detail below.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or "None", the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\nstr.split(sep=None, maxsplit=-1)\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most "maxsplit+1"\n elements). If *maxsplit* is not specified or "-1", then there is\n no limit on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n "\'1,,2\'.split(\',\')" returns "[\'1\', \'\', \'2\']"). The *sep* argument\n may consist of multiple characters (for example,\n "\'1<>2<>3\'.split(\'<>\')" returns "[\'1\', \'2\', \'3\']"). Splitting an\n empty string with a specified separator returns "[\'\']".\n\n For example:\n\n >>> \'1,2,3\'.split(\',\')\n [\'1\', \'2\', \'3\']\n >>> \'1,2,3\'.split(\',\', maxsplit=1)\n [\'1\', \'2,3\']\n >>> \'1,2,,3,\'.split(\',\')\n [\'1\', \'2\', \'\', \'3\', \'\']\n\n If *sep* is not specified or is "None", a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a "None" separator returns "[]".\n\n For example:\n\n >>> \'1 2 3\'.split()\n [\'1\', \'2\', \'3\']\n >>> \'1 2 3\'.split(maxsplit=1)\n [\'1\', \'2 3\']\n >>> \' 1 2 3 \'.split()\n [\'1\', \'2\', \'3\']\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\n This method splits on the following line boundaries. In\n particular, the boundaries are a superset of *universal newlines*.\n\n +-------------------------+-------------------------------+\n | Representation | Description |\n +=========================+===============================+\n | "\\n" | Line Feed |\n +-------------------------+-------------------------------+\n | "\\r" | Carriage Return |\n +-------------------------+-------------------------------+\n | "\\r\\n" | Carriage Return + Line Feed |\n +-------------------------+-------------------------------+\n | "\\v" or "\\x0b" | Line Tabulation |\n +-------------------------+-------------------------------+\n | "\\f" or "\\x0c" | Form Feed |\n +-------------------------+-------------------------------+\n | "\\x1c" | File Separator |\n +-------------------------+-------------------------------+\n | "\\x1d" | Group Separator |\n +-------------------------+-------------------------------+\n | "\\x1e" | Record Separator |\n +-------------------------+-------------------------------+\n | "\\x85" | Next Line (C1 Control Code) |\n +-------------------------+-------------------------------+\n | "\\u2028" | Line Separator |\n +-------------------------+-------------------------------+\n | "\\u2029" | Paragraph Separator |\n +-------------------------+-------------------------------+\n\n Changed in version 3.2: "\\v" and "\\f" added to list of line\n boundaries.\n\n For example:\n\n >>> \'ab c\\n\\nde fg\\rkl\\r\\n\'.splitlines()\n [\'ab c\', \'\', \'de fg\', \'kl\']\n >>> \'ab c\\n\\nde fg\\rkl\\r\\n\'.splitlines(keepends=True)\n [\'ab c\\n\', \'\\n\', \'de fg\\r\', \'kl\\r\\n\']\n\n Unlike "split()" when a delimiter string *sep* is given, this\n method returns an empty list for the empty string, and a terminal\n line break does not result in an extra line:\n\n >>> "".splitlines()\n []\n >>> "One line\\n".splitlines()\n [\'One line\']\n\n For comparison, "split(\'\\n\')" gives:\n\n >>> \'\'.split(\'\\n\')\n [\'\']\n >>> \'Two lines\\n\'.split(\'\\n\')\n [\'Two lines\', \'\']\n\nstr.startswith(prefix[, start[, end]])\n\n Return "True" if string starts with the *prefix*, otherwise return\n "False". *prefix* can also be a tuple of prefixes to look for.\n With optional *start*, test string beginning at that position.\n With optional *end*, stop comparing string at that position.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or "None", the *chars*\n argument defaults to removing whitespace. The *chars* argument is\n not a prefix or suffix; rather, all combinations of its values are\n stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\n The outermost leading and trailing *chars* argument values are\n stripped from the string. Characters are removed from the leading\n end until reaching a string character that is not contained in the\n set of characters in *chars*. A similar action takes place on the\n trailing end. For example:\n\n >>> comment_string = \'#....... Section 3.2.1 Issue #32 .......\'\n >>> comment_string.strip(\'.#! \')\n \'Section 3.2.1 Issue #32\'\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa. Note that it is not necessarily true that\n "s.swapcase().swapcase() == s".\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n For example:\n\n >>> \'Hello world\'.title()\n \'Hello World\'\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n ... return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n ... lambda mo: mo.group(0)[0].upper() +\n ... mo.group(0)[1:].lower(),\n ... s)\n ...\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\nstr.translate(map)\n\n Return a copy of the *s* where all characters have been mapped\n through the *map* which must be a dictionary of Unicode ordinals\n (integers) to Unicode ordinals, strings or "None". Unmapped\n characters are left untouched. Characters mapped to "None" are\n deleted.\n\n You can use "str.maketrans()" to create a translation map from\n character-to-character mappings in different formats.\n\n Note: An even more flexible approach is to create a custom\n character mapping codec using the "codecs" module (see\n "encodings.cp1251" for an example).\n\nstr.upper()\n\n Return a copy of the string with all the cased characters [4]\n converted to uppercase. Note that "str.upper().isupper()" might be\n "False" if "s" contains uncased characters or if the Unicode\n category of the resulting character(s) is not "Lu" (Letter,\n uppercase), but e.g. "Lt" (Letter, titlecase).\n\n The uppercasing algorithm used is described in section 3.13 of the\n Unicode Standard.\n\nstr.zfill(width)\n\n Return a copy of the string left filled with ASCII "\'0\'" digits to\n make a string of length *width*. A leading sign prefix\n ("\'+\'"/"\'-\'") is handled by inserting the padding *after* the sign\n character rather than before. The original string is returned if\n *width* is less than or equal to "len(s)".\n\n For example:\n\n >>> "42".zfill(5)\n \'00042\'\n >>> "-42".zfill(5)\n \'-0042\'\n', + 'strings': u'\nString and Bytes literals\n*************************\n\nString literals are described by the following lexical definitions:\n\n stringliteral ::= [stringprefix](shortstring | longstring)\n stringprefix ::= "r" | "u" | "R" | "U"\n shortstring ::= "\'" shortstringitem* "\'" | \'"\' shortstringitem* \'"\'\n longstring ::= "\'\'\'" longstringitem* "\'\'\'" | \'"""\' longstringitem* \'"""\'\n shortstringitem ::= shortstringchar | stringescapeseq\n longstringitem ::= longstringchar | stringescapeseq\n shortstringchar ::= \n longstringchar ::= \n stringescapeseq ::= "\\" \n\n bytesliteral ::= bytesprefix(shortbytes | longbytes)\n bytesprefix ::= "b" | "B" | "br" | "Br" | "bR" | "BR" | "rb" | "rB" | "Rb" | "RB"\n shortbytes ::= "\'" shortbytesitem* "\'" | \'"\' shortbytesitem* \'"\'\n longbytes ::= "\'\'\'" longbytesitem* "\'\'\'" | \'"""\' longbytesitem* \'"""\'\n shortbytesitem ::= shortbyteschar | bytesescapeseq\n longbytesitem ::= longbyteschar | bytesescapeseq\n shortbyteschar ::= \n longbyteschar ::= \n bytesescapeseq ::= "\\" \n\nOne syntactic restriction not indicated by these productions is that\nwhitespace is not allowed between the "stringprefix" or "bytesprefix"\nand the rest of the literal. The source character set is defined by\nthe encoding declaration; it is UTF-8 if no encoding declaration is\ngiven in the source file; see section *Encoding declarations*.\n\nIn plain English: Both types of literals can be enclosed in matching\nsingle quotes ("\'") or double quotes ("""). They can also be enclosed\nin matching groups of three single or double quotes (these are\ngenerally referred to as *triple-quoted strings*). The backslash\n("\\") character is used to escape characters that otherwise have a\nspecial meaning, such as newline, backslash itself, or the quote\ncharacter.\n\nBytes literals are always prefixed with "\'b\'" or "\'B\'"; they produce\nan instance of the "bytes" type instead of the "str" type. They may\nonly contain ASCII characters; bytes with a numeric value of 128 or\ngreater must be expressed with escapes.\n\nAs of Python 3.3 it is possible again to prefix string literals with a\n"u" prefix to simplify maintenance of dual 2.x and 3.x codebases.\n\nBoth string and bytes literals may optionally be prefixed with a\nletter "\'r\'" or "\'R\'"; such strings are called *raw strings* and treat\nbackslashes as literal characters. As a result, in string literals,\n"\'\\U\'" and "\'\\u\'" escapes in raw strings are not treated specially.\nGiven that Python 2.x\'s raw unicode literals behave differently than\nPython 3.x\'s the "\'ur\'" syntax is not supported.\n\nNew in version 3.3: The "\'rb\'" prefix of raw bytes literals has been\nadded as a synonym of "\'br\'".\n\nNew in version 3.3: Support for the unicode legacy literal\n("u\'value\'") was reintroduced to simplify the maintenance of dual\nPython 2.x and 3.x codebases. See **PEP 414** for more information.\n\nIn triple-quoted literals, unescaped newlines and quotes are allowed\n(and are retained), except that three unescaped quotes in a row\nterminate the literal. (A "quote" is the character used to open the\nliteral, i.e. either "\'" or """.)\n\nUnless an "\'r\'" or "\'R\'" prefix is present, escape sequences in string\nand bytes literals are interpreted according to rules similar to those\nused by Standard C. The recognized escape sequences are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence | Meaning | Notes |\n+===================+===================================+=========+\n| "\\newline" | Backslash and newline ignored | |\n+-------------------+-----------------------------------+---------+\n| "\\\\" | Backslash ("\\") | |\n+-------------------+-----------------------------------+---------+\n| "\\\'" | Single quote ("\'") | |\n+-------------------+-----------------------------------+---------+\n| "\\"" | Double quote (""") | |\n+-------------------+-----------------------------------+---------+\n| "\\a" | ASCII Bell (BEL) | |\n+-------------------+-----------------------------------+---------+\n| "\\b" | ASCII Backspace (BS) | |\n+-------------------+-----------------------------------+---------+\n| "\\f" | ASCII Formfeed (FF) | |\n+-------------------+-----------------------------------+---------+\n| "\\n" | ASCII Linefeed (LF) | |\n+-------------------+-----------------------------------+---------+\n| "\\r" | ASCII Carriage Return (CR) | |\n+-------------------+-----------------------------------+---------+\n| "\\t" | ASCII Horizontal Tab (TAB) | |\n+-------------------+-----------------------------------+---------+\n| "\\v" | ASCII Vertical Tab (VT) | |\n+-------------------+-----------------------------------+---------+\n| "\\ooo" | Character with octal value *ooo* | (1,3) |\n+-------------------+-----------------------------------+---------+\n| "\\xhh" | Character with hex value *hh* | (2,3) |\n+-------------------+-----------------------------------+---------+\n\nEscape sequences only recognized in string literals are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence | Meaning | Notes |\n+===================+===================================+=========+\n| "\\N{name}" | Character named *name* in the | (4) |\n| | Unicode database | |\n+-------------------+-----------------------------------+---------+\n| "\\uxxxx" | Character with 16-bit hex value | (5) |\n| | *xxxx* | |\n+-------------------+-----------------------------------+---------+\n| "\\Uxxxxxxxx" | Character with 32-bit hex value | (6) |\n| | *xxxxxxxx* | |\n+-------------------+-----------------------------------+---------+\n\nNotes:\n\n1. As in Standard C, up to three octal digits are accepted.\n\n2. Unlike in Standard C, exactly two hex digits are required.\n\n3. In a bytes literal, hexadecimal and octal escapes denote the\n byte with the given value. In a string literal, these escapes\n denote a Unicode character with the given value.\n\n4. Changed in version 3.3: Support for name aliases [1] has been\n added.\n\n5. Individual code units which form parts of a surrogate pair can\n be encoded using this escape sequence. Exactly four hex digits are\n required.\n\n6. Any Unicode character can be encoded this way. Exactly eight\n hex digits are required.\n\nUnlike Standard C, all unrecognized escape sequences are left in the\nstring unchanged, i.e., *the backslash is left in the result*. (This\nbehavior is useful when debugging: if an escape sequence is mistyped,\nthe resulting output is more easily recognized as broken.) It is also\nimportant to note that the escape sequences only recognized in string\nliterals fall into the category of unrecognized escapes for bytes\nliterals.\n\nEven in a raw literal, quotes can be escaped with a backslash, but the\nbackslash remains in the result; for example, "r"\\""" is a valid\nstring literal consisting of two characters: a backslash and a double\nquote; "r"\\"" is not a valid string literal (even a raw string cannot\nend in an odd number of backslashes). Specifically, *a raw literal\ncannot end in a single backslash* (since the backslash would escape\nthe following quote character). Note also that a single backslash\nfollowed by a newline is interpreted as those two characters as part\nof the literal, *not* as a line continuation.\n', + 'subscriptions': u'\nSubscriptions\n*************\n\nA subscription selects an item of a sequence (string, tuple or list)\nor mapping (dictionary) object:\n\n subscription ::= primary "[" expression_list "]"\n\nThe primary must evaluate to an object that supports subscription\n(lists or dictionaries for example). User-defined objects can support\nsubscription by defining a "__getitem__()" method.\n\nFor built-in objects, there are two types of objects that support\nsubscription:\n\nIf the primary is a mapping, the expression list must evaluate to an\nobject whose value is one of the keys of the mapping, and the\nsubscription selects the value in the mapping that corresponds to that\nkey. (The expression list is a tuple except if it has exactly one\nitem.)\n\nIf the primary is a sequence, the expression (list) must evaluate to\nan integer or a slice (as discussed in the following section).\n\nThe formal syntax makes no special provision for negative indices in\nsequences; however, built-in sequences all provide a "__getitem__()"\nmethod that interprets negative indices by adding the length of the\nsequence to the index (so that "x[-1]" selects the last item of "x").\nThe resulting value must be a nonnegative integer less than the number\nof items in the sequence, and the subscription selects the item whose\nindex is that value (counting from zero). Since the support for\nnegative indices and slicing occurs in the object\'s "__getitem__()"\nmethod, subclasses overriding this method will need to explicitly add\nthat support.\n\nA string\'s items are characters. A character is not a separate data\ntype but a string of exactly one character.\n', + 'truth': u'\nTruth Value Testing\n*******************\n\nAny object can be tested for truth value, for use in an "if" or\n"while" condition or as operand of the Boolean operations below. The\nfollowing values are considered false:\n\n* "None"\n\n* "False"\n\n* zero of any numeric type, for example, "0", "0.0", "0j".\n\n* any empty sequence, for example, "\'\'", "()", "[]".\n\n* any empty mapping, for example, "{}".\n\n* instances of user-defined classes, if the class defines a\n "__bool__()" or "__len__()" method, when that method returns the\n integer zero or "bool" value "False". [1]\n\nAll other values are considered true --- so objects of many types are\nalways true.\n\nOperations and built-in functions that have a Boolean result always\nreturn "0" or "False" for false and "1" or "True" for true, unless\notherwise stated. (Important exception: the Boolean operations "or"\nand "and" always return one of their operands.)\n', + 'try': u'\nThe "try" statement\n*******************\n\nThe "try" statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression ["as" identifier]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nThe "except" clause(s) specify one or more exception handlers. When no\nexception occurs in the "try" clause, no exception handler is\nexecuted. When an exception occurs in the "try" suite, a search for an\nexception handler is started. This search inspects the except clauses\nin turn until one is found that matches the exception. An expression-\nless except clause, if present, must be last; it matches any\nexception. For an except clause with an expression, that expression\nis evaluated, and the clause matches the exception if the resulting\nobject is "compatible" with the exception. An object is compatible\nwith an exception if it is the class or a base class of the exception\nobject or a tuple containing an item compatible with the exception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire "try" statement raised\nthe exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified after the "as" keyword in that except clause, if\npresent, and the except clause\'s suite is executed. All except\nclauses must have an executable block. When the end of this block is\nreached, execution continues normally after the entire try statement.\n(This means that if two nested handlers exist for the same exception,\nand the exception occurs in the try clause of the inner handler, the\nouter handler will not handle the exception.)\n\nWhen an exception has been assigned using "as target", it is cleared\nat the end of the except clause. This is as if\n\n except E as N:\n foo\n\nwas translated to\n\n except E as N:\n try:\n foo\n finally:\n del N\n\nThis means the exception must be assigned to a different name to be\nable to refer to it after the except clause. Exceptions are cleared\nbecause with the traceback attached to them, they form a reference\ncycle with the stack frame, keeping all locals in that frame alive\nuntil the next garbage collection occurs.\n\nBefore an except clause\'s suite is executed, details about the\nexception are stored in the "sys" module and can be accessed via\n"sys.exc_info()". "sys.exc_info()" returns a 3-tuple consisting of the\nexception class, the exception instance and a traceback object (see\nsection *The standard type hierarchy*) identifying the point in the\nprogram where the exception occurred. "sys.exc_info()" values are\nrestored to their previous values (before the call) when returning\nfrom a function that handled an exception.\n\nThe optional "else" clause is executed if and when control flows off\nthe end of the "try" clause. [2] Exceptions in the "else" clause are\nnot handled by the preceding "except" clauses.\n\nIf "finally" is present, it specifies a \'cleanup\' handler. The "try"\nclause is executed, including any "except" and "else" clauses. If an\nexception occurs in any of the clauses and is not handled, the\nexception is temporarily saved. The "finally" clause is executed. If\nthere is a saved exception it is re-raised at the end of the "finally"\nclause. If the "finally" clause raises another exception, the saved\nexception is set as the context of the new exception. If the "finally"\nclause executes a "return" or "break" statement, the saved exception\nis discarded:\n\n >>> def f():\n ... try:\n ... 1/0\n ... finally:\n ... return 42\n ...\n >>> f()\n 42\n\nThe exception information is not available to the program during\nexecution of the "finally" clause.\n\nWhen a "return", "break" or "continue" statement is executed in the\n"try" suite of a "try"..."finally" statement, the "finally" clause is\nalso executed \'on the way out.\' A "continue" statement is illegal in\nthe "finally" clause. (The reason is a problem with the current\nimplementation --- this restriction may be lifted in the future).\n\nThe return value of a function is determined by the last "return"\nstatement executed. Since the "finally" clause always executes, a\n"return" statement executed in the "finally" clause will always be the\nlast one executed:\n\n >>> def foo():\n ... try:\n ... return \'try\'\n ... finally:\n ... return \'finally\'\n ...\n >>> foo()\n \'finally\'\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the "raise" statement to\ngenerate exceptions may be found in section *The raise statement*.\n', + 'types': u'\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.), although such additions\nwill often be provided via the standard library instead.\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name "None". It\n is used to signify the absence of a value in many situations, e.g.,\n it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n "NotImplemented". Numeric methods and rich comparison methods\n should return this value if they do not implement the operation for\n the operands provided. (The interpreter will then try the\n reflected operation, or some other fallback, depending on the\n operator.) Its truth value is true.\n\n See *Implementing the arithmetic operations* for more details.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the literal "..." or the\n built-in name "Ellipsis". Its truth value is true.\n\n"numbers.Number"\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n "numbers.Integral"\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are two types of integers:\n\n Integers ("int")\n\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans ("bool")\n These represent the truth values False and True. The two\n objects representing the values "False" and "True" are the\n only Boolean objects. The Boolean type is a subtype of the\n integer type, and Boolean values behave like the values 0 and\n 1, respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ""False"" or\n ""True"" are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers.\n\n "numbers.Real" ("float")\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these are\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n "numbers.Complex" ("complex")\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number "z" can be retrieved through the read-only\n attributes "z.real" and "z.imag".\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function "len()" returns the number of items\n of a sequence. When the length of a sequence is *n*, the index set\n contains the numbers 0, 1, ..., *n*-1. Item *i* of sequence *a* is\n selected by "a[i]".\n\n Sequences also support slicing: "a[i:j]" selects all items with\n index *k* such that *i* "<=" *k* "<" *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: "a[i:j:k]" selects all items of *a* with index *x* where\n "x = i + n*k", *n* ">=" "0" and *i* "<=" *x* "<" *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n A string is a sequence of values that represent Unicode code\n points. All the code points in the range "U+0000 - U+10FFFF"\n can be represented in a string. Python doesn\'t have a "char"\n type; instead, every code point in the string is represented\n as a string object with length "1". The built-in function\n "ord()" converts a code point from its string form to an\n integer in the range "0 - 10FFFF"; "chr()" converts an\n integer in the range "0 - 10FFFF" to the corresponding length\n "1" string object. "str.encode()" can be used to convert a\n "str" to "bytes" using the given text encoding, and\n "bytes.decode()" can be used to achieve the opposite.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Bytes\n A bytes object is an immutable array. The items are 8-bit\n bytes, represented by integers in the range 0 <= x < 256.\n Bytes literals (like "b\'abc\'") and the built-in function\n "bytes()" can be used to construct bytes objects. Also,\n bytes objects can be decoded to strings via the "decode()"\n method.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and "del" (delete) statements.\n\n There are currently two intrinsic mutable sequence types:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n Byte Arrays\n A bytearray object is a mutable array. They are created by\n the built-in "bytearray()" constructor. Aside from being\n mutable (and hence unhashable), byte arrays otherwise provide\n the same interface and functionality as immutable bytes\n objects.\n\n The extension module "array" provides an additional example of a\n mutable sequence type, as does the "collections" module.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function "len()"\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., "1" and\n "1.0"), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n "set()" constructor and can be modified afterwards by several\n methods, such as "add()".\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in "frozenset()" constructor. As a frozenset is immutable\n and *hashable*, it can be used again as an element of another\n set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation "a[k]" selects the item indexed by "k"\n from the mapping "a"; this can be used in expressions and as the\n target of assignments or "del" statements. The built-in function\n "len()" returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., "1" and "1.0")\n then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the "{...}"\n notation (see section *Dictionary displays*).\n\n The extension modules "dbm.ndbm" and "dbm.gnu" provide\n additional examples of mapping types, as does the "collections"\n module.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +---------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +===========================+=================================+=============+\n | "__doc__" | The function\'s documentation | Writable |\n | | string, or "None" if | |\n | | unavailable; not inherited by | |\n | | subclasses | |\n +---------------------------+---------------------------------+-------------+\n | "__name__" | The function\'s name | Writable |\n +---------------------------+---------------------------------+-------------+\n | "__qualname__" | The function\'s *qualified name* | Writable |\n | | New in version 3.3. | |\n +---------------------------+---------------------------------+-------------+\n | "__module__" | The name of the module the | Writable |\n | | function was defined in, or | |\n | | "None" if unavailable. | |\n +---------------------------+---------------------------------+-------------+\n | "__defaults__" | A tuple containing default | Writable |\n | | argument values for those | |\n | | arguments that have defaults, | |\n | | or "None" if no arguments have | |\n | | a default value | |\n +---------------------------+---------------------------------+-------------+\n | "__code__" | The code object representing | Writable |\n | | the compiled function body. | |\n +---------------------------+---------------------------------+-------------+\n | "__globals__" | A reference to the dictionary | Read-only |\n | | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +---------------------------+---------------------------------+-------------+\n | "__dict__" | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +---------------------------+---------------------------------+-------------+\n | "__closure__" | "None" or a tuple of cells that | Read-only |\n | | contain bindings for the | |\n | | function\'s free variables. | |\n +---------------------------+---------------------------------+-------------+\n | "__annotations__" | A dict containing annotations | Writable |\n | | of parameters. The keys of the | |\n | | dict are the parameter names, | |\n | | and "\'return\'" for the return | |\n | | annotation, if provided. | |\n +---------------------------+---------------------------------+-------------+\n | "__kwdefaults__" | A dict containing defaults for | Writable |\n | | keyword-only parameters. | |\n +---------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n Instance methods\n An instance method object combines a class, a class instance and\n any callable object (normally a user-defined function).\n\n Special read-only attributes: "__self__" is the class instance\n object, "__func__" is the function object; "__doc__" is the\n method\'s documentation (same as "__func__.__doc__"); "__name__"\n is the method name (same as "__func__.__name__"); "__module__"\n is the name of the module the method was defined in, or "None"\n if unavailable.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object or a class\n method object.\n\n When an instance method object is created by retrieving a user-\n defined function object from a class via one of its instances,\n its "__self__" attribute is the instance, and the method object\n is said to be bound. The new method\'s "__func__" attribute is\n the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the "__func__"\n attribute of the new instance is not the original method object\n but its "__func__" attribute.\n\n When an instance method object is created by retrieving a class\n method object from a class or instance, its "__self__" attribute\n is the class itself, and its "__func__" attribute is the\n function object underlying the class method.\n\n When an instance method object is called, the underlying\n function ("__func__") is called, inserting the class instance\n ("__self__") in front of the argument list. For instance, when\n "C" is a class which contains a definition for a function "f()",\n and "x" is an instance of "C", calling "x.f(1)" is equivalent to\n calling "C.f(x, 1)".\n\n When an instance method object is derived from a class method\n object, the "class instance" stored in "__self__" will actually\n be the class itself, so that calling either "x.f(1)" or "C.f(1)"\n is equivalent to calling "f(C,1)" where "f" is the underlying\n function.\n\n Note that the transformation from function object to instance\n method object happens each time the attribute is retrieved from\n the instance. In some cases, a fruitful optimization is to\n assign the attribute to a local variable and call that local\n variable. Also notice that this transformation only happens for\n user-defined functions; other callable objects (and all non-\n callable objects) are retrieved without transformation. It is\n also important to note that user-defined functions which are\n attributes of a class instance are not converted to bound\n methods; this *only* happens when the function is an attribute\n of the class.\n\n Generator functions\n A function or method which uses the "yield" statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s "iterator.__next__()" method will cause the\n function to execute until it provides a value using the "yield"\n statement. When the function executes a "return" statement or\n falls off the end, a "StopIteration" exception is raised and the\n iterator will have reached the end of the set of values to be\n returned.\n\n Coroutine functions\n A function or method which is defined using "async def" is\n called a *coroutine function*. Such a function, when called,\n returns a *coroutine* object. It may contain "await"\n expressions, as well as "async with" and "async for" statements.\n See also *Coroutines* section.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are "len()" and "math.sin()"\n ("math" is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: "__doc__" is the function\'s documentation\n string, or "None" if unavailable; "__name__" is the function\'s\n name; "__self__" is set to "None" (but see the next item);\n "__module__" is the name of the module the function was defined\n in or "None" if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n "alist.append()", assuming *alist* is a list object. In this\n case, the special read-only attribute "__self__" is set to the\n object denoted by *alist*.\n\n Classes\n Classes are callable. These objects normally act as factories\n for new instances of themselves, but variations are possible for\n class types that override "__new__()". The arguments of the\n call are passed to "__new__()" and, in the typical case, to\n "__init__()" to initialize the new instance.\n\n Class Instances\n Instances of arbitrary classes can be made callable by defining\n a "__call__()" method in their class.\n\nModules\n Modules are a basic organizational unit of Python code, and are\n created by the *import system* as invoked either by the "import"\n statement (see "import"), or by calling functions such as\n "importlib.import_module()" and built-in "__import__()". A module\n object has a namespace implemented by a dictionary object (this is\n the dictionary referenced by the "__globals__" attribute of\n functions defined in the module). Attribute references are\n translated to lookups in this dictionary, e.g., "m.x" is equivalent\n to "m.__dict__["x"]". A module object does not contain the code\n object used to initialize the module (since it isn\'t needed once\n the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., "m.x = 1" is equivalent to "m.__dict__["x"] = 1".\n\n Special read-only attribute: "__dict__" is the module\'s namespace\n as a dictionary object.\n\n **CPython implementation detail:** Because of the way CPython\n clears module dictionaries, the module dictionary will be cleared\n when the module falls out of scope even if the dictionary still has\n live references. To avoid this, copy the dictionary or keep the\n module around while using its dictionary directly.\n\n Predefined (writable) attributes: "__name__" is the module\'s name;\n "__doc__" is the module\'s documentation string, or "None" if\n unavailable; "__file__" is the pathname of the file from which the\n module was loaded, if it was loaded from a file. The "__file__"\n attribute may be missing for certain types of modules, such as C\n modules that are statically linked into the interpreter; for\n extension modules loaded dynamically from a shared library, it is\n the pathname of the shared library file.\n\nCustom classes\n Custom class types are typically created by class definitions (see\n section *Class definitions*). A class has a namespace implemented\n by a dictionary object. Class attribute references are translated\n to lookups in this dictionary, e.g., "C.x" is translated to\n "C.__dict__["x"]" (although there are a number of hooks which allow\n for other means of locating attributes). When the attribute name is\n not found there, the attribute search continues in the base\n classes. This search of the base classes uses the C3 method\n resolution order which behaves correctly even in the presence of\n \'diamond\' inheritance structures where there are multiple\n inheritance paths leading back to a common ancestor. Additional\n details on the C3 MRO used by Python can be found in the\n documentation accompanying the 2.3 release at\n https://www.python.org/download/releases/2.3/mro/.\n\n When a class attribute reference (for class "C", say) would yield a\n class method object, it is transformed into an instance method\n object whose "__self__" attributes is "C". When it would yield a\n static method object, it is transformed into the object wrapped by\n the static method object. See section *Implementing Descriptors*\n for another way in which attributes retrieved from a class may\n differ from those actually contained in its "__dict__".\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: "__name__" is the class name; "__module__" is\n the module name in which the class was defined; "__dict__" is the\n dictionary containing the class\'s namespace; "__bases__" is a tuple\n (possibly empty or a singleton) containing the base classes, in the\n order of their occurrence in the base class list; "__doc__" is the\n class\'s documentation string, or None if undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object, it is transformed into an instance method object\n whose "__self__" attribute is the instance. Static method and\n class method objects are also transformed; see above under\n "Classes". See section *Implementing Descriptors* for another way\n in which attributes of a class retrieved via its instances may\n differ from the objects actually stored in the class\'s "__dict__".\n If no class attribute is found, and the object\'s class has a\n "__getattr__()" method, that is called to satisfy the lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n "__setattr__()" or "__delattr__()" method, this is called instead\n of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: "__dict__" is the attribute dictionary;\n "__class__" is the instance\'s class.\n\nI/O objects (also known as file objects)\n A *file object* represents an open file. Various shortcuts are\n available to create file objects: the "open()" built-in function,\n and also "os.popen()", "os.fdopen()", and the "makefile()" method\n of socket objects (and perhaps by other functions or methods\n provided by extension modules).\n\n The objects "sys.stdin", "sys.stdout" and "sys.stderr" are\n initialized to file objects corresponding to the interpreter\'s\n standard input, output and error streams; they are all open in text\n mode and therefore follow the interface defined by the\n "io.TextIOBase" abstract class.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: "co_name" gives the function name;\n "co_argcount" is the number of positional arguments (including\n arguments with default values); "co_nlocals" is the number of\n local variables used by the function (including arguments);\n "co_varnames" is a tuple containing the names of the local\n variables (starting with the argument names); "co_cellvars" is a\n tuple containing the names of local variables that are\n referenced by nested functions; "co_freevars" is a tuple\n containing the names of free variables; "co_code" is a string\n representing the sequence of bytecode instructions; "co_consts"\n is a tuple containing the literals used by the bytecode;\n "co_names" is a tuple containing the names used by the bytecode;\n "co_filename" is the filename from which the code was compiled;\n "co_firstlineno" is the first line number of the function;\n "co_lnotab" is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); "co_stacksize" is the required stack size\n (including local variables); "co_flags" is an integer encoding a\n number of flags for the interpreter.\n\n The following flag bits are defined for "co_flags": bit "0x04"\n is set if the function uses the "*arguments" syntax to accept an\n arbitrary number of positional arguments; bit "0x08" is set if\n the function uses the "**keywords" syntax to accept arbitrary\n keyword arguments; bit "0x20" is set if the function is a\n generator.\n\n Future feature declarations ("from __future__ import division")\n also use bits in "co_flags" to indicate whether a code object\n was compiled with a particular feature enabled: bit "0x2000" is\n set if the function was compiled with future division enabled;\n bits "0x10" and "0x1000" were used in earlier versions of\n Python.\n\n Other bits in "co_flags" are reserved for internal use.\n\n If a code object represents a function, the first item in\n "co_consts" is the documentation string of the function, or\n "None" if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: "f_back" is to the previous stack\n frame (towards the caller), or "None" if this is the bottom\n stack frame; "f_code" is the code object being executed in this\n frame; "f_locals" is the dictionary used to look up local\n variables; "f_globals" is used for global variables;\n "f_builtins" is used for built-in (intrinsic) names; "f_lasti"\n gives the precise instruction (this is an index into the\n bytecode string of the code object).\n\n Special writable attributes: "f_trace", if not "None", is a\n function called at the start of each source code line (this is\n used by the debugger); "f_lineno" is the current line number of\n the frame --- writing to this from within a trace function jumps\n to the given line (only for the bottom-most frame). A debugger\n can implement a Jump command (aka Set Next Statement) by writing\n to f_lineno.\n\n Frame objects support one method:\n\n frame.clear()\n\n This method clears all references to local variables held by\n the frame. Also, if the frame belonged to a generator, the\n generator is finalized. This helps break reference cycles\n involving frame objects (for example when catching an\n exception and storing its traceback for later use).\n\n "RuntimeError" is raised if the frame is currently executing.\n\n New in version 3.4.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as the third item of the\n tuple returned by "sys.exc_info()". When the program contains no\n suitable handler, the stack trace is written (nicely formatted)\n to the standard error stream; if the interpreter is interactive,\n it is also made available to the user as "sys.last_traceback".\n\n Special read-only attributes: "tb_next" is the next level in the\n stack trace (towards the frame where the exception occurred), or\n "None" if there is no next level; "tb_frame" points to the\n execution frame of the current level; "tb_lineno" gives the line\n number where the exception occurred; "tb_lasti" indicates the\n precise instruction. The line number and last instruction in\n the traceback may differ from the line number of its frame\n object if the exception occurred in a "try" statement with no\n matching except clause or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices for "__getitem__()"\n methods. They are also created by the built-in "slice()"\n function.\n\n Special read-only attributes: "start" is the lower bound; "stop"\n is the upper bound; "step" is the step value; each is "None" if\n omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the slice that the slice object\n would describe if applied to a sequence of *length* items.\n It returns a tuple of three integers; respectively these are\n the *start* and *stop* indices and the *step* or stride\n length of the slice. Missing or out-of-bounds indices are\n handled in a manner consistent with regular slices.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n "staticmethod()" constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in "classmethod()" constructor.\n', + 'typesfunctions': u'\nFunctions\n*********\n\nFunction objects are created by function definitions. The only\noperation on a function object is to call it: "func(argument-list)".\n\nThere are really two flavors of function objects: built-in functions\nand user-defined functions. Both support the same operation (to call\nthe function), but the implementation is different, hence the\ndifferent object types.\n\nSee *Function definitions* for more information.\n', + 'typesmapping': u'\nMapping Types --- "dict"\n************************\n\nA *mapping* object maps *hashable* values to arbitrary objects.\nMappings are mutable objects. There is currently only one standard\nmapping type, the *dictionary*. (For other containers see the built-\nin "list", "set", and "tuple" classes, and the "collections" module.)\n\nA dictionary\'s keys are *almost* arbitrary values. Values that are\nnot *hashable*, that is, values containing lists, dictionaries or\nother mutable types (that are compared by value rather than by object\nidentity) may not be used as keys. Numeric types used for keys obey\nthe normal rules for numeric comparison: if two numbers compare equal\n(such as "1" and "1.0") then they can be used interchangeably to index\nthe same dictionary entry. (Note however, that since computers store\nfloating-point numbers as approximations it is usually unwise to use\nthem as dictionary keys.)\n\nDictionaries can be created by placing a comma-separated list of "key:\nvalue" pairs within braces, for example: "{\'jack\': 4098, \'sjoerd\':\n4127}" or "{4098: \'jack\', 4127: \'sjoerd\'}", or by the "dict"\nconstructor.\n\nclass class dict(**kwarg)\nclass class dict(mapping, **kwarg)\nclass class dict(iterable, **kwarg)\n\n Return a new dictionary initialized from an optional positional\n argument and a possibly empty set of keyword arguments.\n\n If no positional argument is given, an empty dictionary is created.\n If a positional argument is given and it is a mapping object, a\n dictionary is created with the same key-value pairs as the mapping\n object. Otherwise, the positional argument must be an *iterable*\n object. Each item in the iterable must itself be an iterable with\n exactly two objects. The first object of each item becomes a key\n in the new dictionary, and the second object the corresponding\n value. If a key occurs more than once, the last value for that key\n becomes the corresponding value in the new dictionary.\n\n If keyword arguments are given, the keyword arguments and their\n values are added to the dictionary created from the positional\n argument. If a key being added is already present, the value from\n the keyword argument replaces the value from the positional\n argument.\n\n To illustrate, the following examples all return a dictionary equal\n to "{"one": 1, "two": 2, "three": 3}":\n\n >>> a = dict(one=1, two=2, three=3)\n >>> b = {\'one\': 1, \'two\': 2, \'three\': 3}\n >>> c = dict(zip([\'one\', \'two\', \'three\'], [1, 2, 3]))\n >>> d = dict([(\'two\', 2), (\'one\', 1), (\'three\', 3)])\n >>> e = dict({\'three\': 3, \'one\': 1, \'two\': 2})\n >>> a == b == c == d == e\n True\n\n Providing keyword arguments as in the first example only works for\n keys that are valid Python identifiers. Otherwise, any valid keys\n can be used.\n\n These are the operations that dictionaries support (and therefore,\n custom mapping types should support too):\n\n len(d)\n\n Return the number of items in the dictionary *d*.\n\n d[key]\n\n Return the item of *d* with key *key*. Raises a "KeyError" if\n *key* is not in the map.\n\n If a subclass of dict defines a method "__missing__()" and *key*\n is not present, the "d[key]" operation calls that method with\n the key *key* as argument. The "d[key]" operation then returns\n or raises whatever is returned or raised by the\n "__missing__(key)" call. No other operations or methods invoke\n "__missing__()". If "__missing__()" is not defined, "KeyError"\n is raised. "__missing__()" must be a method; it cannot be an\n instance variable:\n\n >>> class Counter(dict):\n ... def __missing__(self, key):\n ... return 0\n >>> c = Counter()\n >>> c[\'red\']\n 0\n >>> c[\'red\'] += 1\n >>> c[\'red\']\n 1\n\n The example above shows part of the implementation of\n "collections.Counter". A different "__missing__" method is used\n by "collections.defaultdict".\n\n d[key] = value\n\n Set "d[key]" to *value*.\n\n del d[key]\n\n Remove "d[key]" from *d*. Raises a "KeyError" if *key* is not\n in the map.\n\n key in d\n\n Return "True" if *d* has a key *key*, else "False".\n\n key not in d\n\n Equivalent to "not key in d".\n\n iter(d)\n\n Return an iterator over the keys of the dictionary. This is a\n shortcut for "iter(d.keys())".\n\n clear()\n\n Remove all items from the dictionary.\n\n copy()\n\n Return a shallow copy of the dictionary.\n\n classmethod fromkeys(seq[, value])\n\n Create a new dictionary with keys from *seq* and values set to\n *value*.\n\n "fromkeys()" is a class method that returns a new dictionary.\n *value* defaults to "None".\n\n get(key[, default])\n\n Return the value for *key* if *key* is in the dictionary, else\n *default*. If *default* is not given, it defaults to "None", so\n that this method never raises a "KeyError".\n\n items()\n\n Return a new view of the dictionary\'s items ("(key, value)"\n pairs). See the *documentation of view objects*.\n\n keys()\n\n Return a new view of the dictionary\'s keys. See the\n *documentation of view objects*.\n\n pop(key[, default])\n\n If *key* is in the dictionary, remove it and return its value,\n else return *default*. If *default* is not given and *key* is\n not in the dictionary, a "KeyError" is raised.\n\n popitem()\n\n Remove and return an arbitrary "(key, value)" pair from the\n dictionary.\n\n "popitem()" is useful to destructively iterate over a\n dictionary, as often used in set algorithms. If the dictionary\n is empty, calling "popitem()" raises a "KeyError".\n\n setdefault(key[, default])\n\n If *key* is in the dictionary, return its value. If not, insert\n *key* with a value of *default* and return *default*. *default*\n defaults to "None".\n\n update([other])\n\n Update the dictionary with the key/value pairs from *other*,\n overwriting existing keys. Return "None".\n\n "update()" accepts either another dictionary object or an\n iterable of key/value pairs (as tuples or other iterables of\n length two). If keyword arguments are specified, the dictionary\n is then updated with those key/value pairs: "d.update(red=1,\n blue=2)".\n\n values()\n\n Return a new view of the dictionary\'s values. See the\n *documentation of view objects*.\n\nSee also: "types.MappingProxyType" can be used to create a read-only\n view of a "dict".\n\n\nDictionary view objects\n=======================\n\nThe objects returned by "dict.keys()", "dict.values()" and\n"dict.items()" are *view objects*. They provide a dynamic view on the\ndictionary\'s entries, which means that when the dictionary changes,\nthe view reflects these changes.\n\nDictionary views can be iterated over to yield their respective data,\nand support membership tests:\n\nlen(dictview)\n\n Return the number of entries in the dictionary.\n\niter(dictview)\n\n Return an iterator over the keys, values or items (represented as\n tuples of "(key, value)") in the dictionary.\n\n Keys and values are iterated over in an arbitrary order which is\n non-random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If keys,\n values and items views are iterated over with no intervening\n modifications to the dictionary, the order of items will directly\n correspond. This allows the creation of "(value, key)" pairs using\n "zip()": "pairs = zip(d.values(), d.keys())". Another way to\n create the same list is "pairs = [(v, k) for (k, v) in d.items()]".\n\n Iterating views while adding or deleting entries in the dictionary\n may raise a "RuntimeError" or fail to iterate over all entries.\n\nx in dictview\n\n Return "True" if *x* is in the underlying dictionary\'s keys, values\n or items (in the latter case, *x* should be a "(key, value)"\n tuple).\n\nKeys views are set-like since their entries are unique and hashable.\nIf all values are hashable, so that "(key, value)" pairs are unique\nand hashable, then the items view is also set-like. (Values views are\nnot treated as set-like since the entries are generally not unique.)\nFor set-like views, all of the operations defined for the abstract\nbase class "collections.abc.Set" are available (for example, "==",\n"<", or "^").\n\nAn example of dictionary view usage:\n\n >>> dishes = {\'eggs\': 2, \'sausage\': 1, \'bacon\': 1, \'spam\': 500}\n >>> keys = dishes.keys()\n >>> values = dishes.values()\n\n >>> # iteration\n >>> n = 0\n >>> for val in values:\n ... n += val\n >>> print(n)\n 504\n\n >>> # keys and values are iterated over in the same order\n >>> list(keys)\n [\'eggs\', \'bacon\', \'sausage\', \'spam\']\n >>> list(values)\n [2, 1, 1, 500]\n\n >>> # view objects are dynamic and reflect dict changes\n >>> del dishes[\'eggs\']\n >>> del dishes[\'sausage\']\n >>> list(keys)\n [\'spam\', \'bacon\']\n\n >>> # set operations\n >>> keys & {\'eggs\', \'bacon\', \'salad\'}\n {\'bacon\'}\n >>> keys ^ {\'sausage\', \'juice\'}\n {\'juice\', \'sausage\', \'bacon\', \'spam\'}\n', + 'typesmethods': u'\nMethods\n*******\n\nMethods are functions that are called using the attribute notation.\nThere are two flavors: built-in methods (such as "append()" on lists)\nand class instance methods. Built-in methods are described with the\ntypes that support them.\n\nIf you access a method (a function defined in a class namespace)\nthrough an instance, you get a special object: a *bound method* (also\ncalled *instance method*) object. When called, it will add the "self"\nargument to the argument list. Bound methods have two special read-\nonly attributes: "m.__self__" is the object on which the method\noperates, and "m.__func__" is the function implementing the method.\nCalling "m(arg-1, arg-2, ..., arg-n)" is completely equivalent to\ncalling "m.__func__(m.__self__, arg-1, arg-2, ..., arg-n)".\n\nLike function objects, bound method objects support getting arbitrary\nattributes. However, since method attributes are actually stored on\nthe underlying function object ("meth.__func__"), setting method\nattributes on bound methods is disallowed. Attempting to set an\nattribute on a method results in an "AttributeError" being raised. In\norder to set a method attribute, you need to explicitly set it on the\nunderlying function object:\n\n >>> class C:\n ... def method(self):\n ... pass\n ...\n >>> c = C()\n >>> c.method.whoami = \'my name is method\' # can\'t set on the method\n Traceback (most recent call last):\n File "", line 1, in \n AttributeError: \'method\' object has no attribute \'whoami\'\n >>> c.method.__func__.whoami = \'my name is method\'\n >>> c.method.whoami\n \'my name is method\'\n\nSee *The standard type hierarchy* for more information.\n', + 'typesmodules': u'\nModules\n*******\n\nThe only special operation on a module is attribute access: "m.name",\nwhere *m* is a module and *name* accesses a name defined in *m*\'s\nsymbol table. Module attributes can be assigned to. (Note that the\n"import" statement is not, strictly speaking, an operation on a module\nobject; "import foo" does not require a module object named *foo* to\nexist, rather it requires an (external) *definition* for a module\nnamed *foo* somewhere.)\n\nA special attribute of every module is "__dict__". This is the\ndictionary containing the module\'s symbol table. Modifying this\ndictionary will actually change the module\'s symbol table, but direct\nassignment to the "__dict__" attribute is not possible (you can write\n"m.__dict__[\'a\'] = 1", which defines "m.a" to be "1", but you can\'t\nwrite "m.__dict__ = {}"). Modifying "__dict__" directly is not\nrecommended.\n\nModules built into the interpreter are written like this: "". If loaded from a file, they are written as\n"".\n', + 'typesseq': u'\nSequence Types --- "list", "tuple", "range"\n*******************************************\n\nThere are three basic sequence types: lists, tuples, and range\nobjects. Additional sequence types tailored for processing of *binary\ndata* and *text strings* are described in dedicated sections.\n\n\nCommon Sequence Operations\n==========================\n\nThe operations in the following table are supported by most sequence\ntypes, both mutable and immutable. The "collections.abc.Sequence" ABC\nis provided to make it easier to correctly implement these operations\non custom sequence types.\n\nThis table lists the sequence operations sorted in ascending priority.\nIn the table, *s* and *t* are sequences of the same type, *n*, *i*,\n*j* and *k* are integers and *x* is an arbitrary object that meets any\ntype and value restrictions imposed by *s*.\n\nThe "in" and "not in" operations have the same priorities as the\ncomparison operations. The "+" (concatenation) and "*" (repetition)\noperations have the same priority as the corresponding numeric\noperations.\n\n+----------------------------+----------------------------------+------------+\n| Operation | Result | Notes |\n+============================+==================================+============+\n| "x in s" | "True" if an item of *s* is | (1) |\n| | equal to *x*, else "False" | |\n+----------------------------+----------------------------------+------------+\n| "x not in s" | "False" if an item of *s* is | (1) |\n| | equal to *x*, else "True" | |\n+----------------------------+----------------------------------+------------+\n| "s + t" | the concatenation of *s* and *t* | (6)(7) |\n+----------------------------+----------------------------------+------------+\n| "s * n" or "n * s" | *n* shallow copies of *s* | (2)(7) |\n| | concatenated | |\n+----------------------------+----------------------------------+------------+\n| "s[i]" | *i*th item of *s*, origin 0 | (3) |\n+----------------------------+----------------------------------+------------+\n| "s[i:j]" | slice of *s* from *i* to *j* | (3)(4) |\n+----------------------------+----------------------------------+------------+\n| "s[i:j:k]" | slice of *s* from *i* to *j* | (3)(5) |\n| | with step *k* | |\n+----------------------------+----------------------------------+------------+\n| "len(s)" | length of *s* | |\n+----------------------------+----------------------------------+------------+\n| "min(s)" | smallest item of *s* | |\n+----------------------------+----------------------------------+------------+\n| "max(s)" | largest item of *s* | |\n+----------------------------+----------------------------------+------------+\n| "s.index(x[, i[, j]])" | index of the first occurrence of | (8) |\n| | *x* in *s* (at or after index | |\n| | *i* and before index *j*) | |\n+----------------------------+----------------------------------+------------+\n| "s.count(x)" | total number of occurrences of | |\n| | *x* in *s* | |\n+----------------------------+----------------------------------+------------+\n\nSequences of the same type also support comparisons. In particular,\ntuples and lists are compared lexicographically by comparing\ncorresponding elements. This means that to compare equal, every\nelement must compare equal and the two sequences must be of the same\ntype and have the same length. (For full details see *Comparisons* in\nthe language reference.)\n\nNotes:\n\n1. While the "in" and "not in" operations are used only for simple\n containment testing in the general case, some specialised sequences\n (such as "str", "bytes" and "bytearray") also use them for\n subsequence testing:\n\n >>> "gg" in "eggs"\n True\n\n2. Values of *n* less than "0" are treated as "0" (which yields an\n empty sequence of the same type as *s*). Note also that the copies\n are shallow; nested structures are not copied. This often haunts\n new Python programmers; consider:\n\n >>> lists = [[]] * 3\n >>> lists\n [[], [], []]\n >>> lists[0].append(3)\n >>> lists\n [[3], [3], [3]]\n\n What has happened is that "[[]]" is a one-element list containing\n an empty list, so all three elements of "[[]] * 3" are (pointers\n to) this single empty list. Modifying any of the elements of\n "lists" modifies this single list. You can create a list of\n different lists this way:\n\n >>> lists = [[] for i in range(3)]\n >>> lists[0].append(3)\n >>> lists[1].append(5)\n >>> lists[2].append(7)\n >>> lists\n [[3], [5], [7]]\n\n3. If *i* or *j* is negative, the index is relative to the end of\n the string: "len(s) + i" or "len(s) + j" is substituted. But note\n that "-0" is still "0".\n\n4. The slice of *s* from *i* to *j* is defined as the sequence of\n items with index *k* such that "i <= k < j". If *i* or *j* is\n greater than "len(s)", use "len(s)". If *i* is omitted or "None",\n use "0". If *j* is omitted or "None", use "len(s)". If *i* is\n greater than or equal to *j*, the slice is empty.\n\n5. The slice of *s* from *i* to *j* with step *k* is defined as the\n sequence of items with index "x = i + n*k" such that "0 <= n <\n (j-i)/k". In other words, the indices are "i", "i+k", "i+2*k",\n "i+3*k" and so on, stopping when *j* is reached (but never\n including *j*). If *i* or *j* is greater than "len(s)", use\n "len(s)". If *i* or *j* are omitted or "None", they become "end"\n values (which end depends on the sign of *k*). Note, *k* cannot be\n zero. If *k* is "None", it is treated like "1".\n\n6. Concatenating immutable sequences always results in a new\n object. This means that building up a sequence by repeated\n concatenation will have a quadratic runtime cost in the total\n sequence length. To get a linear runtime cost, you must switch to\n one of the alternatives below:\n\n * if concatenating "str" objects, you can build a list and use\n "str.join()" at the end or else write to a "io.StringIO" instance\n and retrieve its value when complete\n\n * if concatenating "bytes" objects, you can similarly use\n "bytes.join()" or "io.BytesIO", or you can do in-place\n concatenation with a "bytearray" object. "bytearray" objects are\n mutable and have an efficient overallocation mechanism\n\n * if concatenating "tuple" objects, extend a "list" instead\n\n * for other types, investigate the relevant class documentation\n\n7. Some sequence types (such as "range") only support item\n sequences that follow specific patterns, and hence don\'t support\n sequence concatenation or repetition.\n\n8. "index" raises "ValueError" when *x* is not found in *s*. When\n supported, the additional arguments to the index method allow\n efficient searching of subsections of the sequence. Passing the\n extra arguments is roughly equivalent to using "s[i:j].index(x)",\n only without copying any data and with the returned index being\n relative to the start of the sequence rather than the start of the\n slice.\n\n\nImmutable Sequence Types\n========================\n\nThe only operation that immutable sequence types generally implement\nthat is not also implemented by mutable sequence types is support for\nthe "hash()" built-in.\n\nThis support allows immutable sequences, such as "tuple" instances, to\nbe used as "dict" keys and stored in "set" and "frozenset" instances.\n\nAttempting to hash an immutable sequence that contains unhashable\nvalues will result in "TypeError".\n\n\nMutable Sequence Types\n======================\n\nThe operations in the following table are defined on mutable sequence\ntypes. The "collections.abc.MutableSequence" ABC is provided to make\nit easier to correctly implement these operations on custom sequence\ntypes.\n\nIn the table *s* is an instance of a mutable sequence type, *t* is any\niterable object and *x* is an arbitrary object that meets any type and\nvalue restrictions imposed by *s* (for example, "bytearray" only\naccepts integers that meet the value restriction "0 <= x <= 255").\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| "s[i] = x" | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j] = t" | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j]" | same as "s[i:j] = []" | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j:k] = t" | the elements of "s[i:j:k]" are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j:k]" | removes the elements of | |\n| | "s[i:j:k]" from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.append(x)" | appends *x* to the end of the | |\n| | sequence (same as | |\n| | "s[len(s):len(s)] = [x]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.clear()" | removes all items from "s" (same | (5) |\n| | as "del s[:]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.copy()" | creates a shallow copy of "s" | (5) |\n| | (same as "s[:]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.extend(t)" | extends *s* with the contents of | |\n| | *t* (same as "s[len(s):len(s)] = | |\n| | t") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.insert(i, x)" | inserts *x* into *s* at the | |\n| | index given by *i* (same as | |\n| | "s[i:i] = [x]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.pop([i])" | retrieves the item at *i* and | (2) |\n| | also removes it from *s* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.remove(x)" | remove the first item from *s* | (3) |\n| | where "s[i] == x" | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.reverse()" | reverses the items of *s* in | (4) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The optional argument *i* defaults to "-1", so that by default\n the last item is removed and returned.\n\n3. "remove" raises "ValueError" when *x* is not found in *s*.\n\n4. The "reverse()" method modifies the sequence in place for\n economy of space when reversing a large sequence. To remind users\n that it operates by side effect, it does not return the reversed\n sequence.\n\n5. "clear()" and "copy()" are included for consistency with the\n interfaces of mutable containers that don\'t support slicing\n operations (such as "dict" and "set")\n\n New in version 3.3: "clear()" and "copy()" methods.\n\n\nLists\n=====\n\nLists are mutable sequences, typically used to store collections of\nhomogeneous items (where the precise degree of similarity will vary by\napplication).\n\nclass class list([iterable])\n\n Lists may be constructed in several ways:\n\n * Using a pair of square brackets to denote the empty list: "[]"\n\n * Using square brackets, separating items with commas: "[a]",\n "[a, b, c]"\n\n * Using a list comprehension: "[x for x in iterable]"\n\n * Using the type constructor: "list()" or "list(iterable)"\n\n The constructor builds a list whose items are the same and in the\n same order as *iterable*\'s items. *iterable* may be either a\n sequence, a container that supports iteration, or an iterator\n object. If *iterable* is already a list, a copy is made and\n returned, similar to "iterable[:]". For example, "list(\'abc\')"\n returns "[\'a\', \'b\', \'c\']" and "list( (1, 2, 3) )" returns "[1, 2,\n 3]". If no argument is given, the constructor creates a new empty\n list, "[]".\n\n Many other operations also produce lists, including the "sorted()"\n built-in.\n\n Lists implement all of the *common* and *mutable* sequence\n operations. Lists also provide the following additional method:\n\n sort(*, key=None, reverse=None)\n\n This method sorts the list in place, using only "<" comparisons\n between items. Exceptions are not suppressed - if any comparison\n operations fail, the entire sort operation will fail (and the\n list will likely be left in a partially modified state).\n\n "sort()" accepts two arguments that can only be passed by\n keyword (*keyword-only arguments*):\n\n *key* specifies a function of one argument that is used to\n extract a comparison key from each list element (for example,\n "key=str.lower"). The key corresponding to each item in the list\n is calculated once and then used for the entire sorting process.\n The default value of "None" means that list items are sorted\n directly without calculating a separate key value.\n\n The "functools.cmp_to_key()" utility is available to convert a\n 2.x style *cmp* function to a *key* function.\n\n *reverse* is a boolean value. If set to "True", then the list\n elements are sorted as if each comparison were reversed.\n\n This method modifies the sequence in place for economy of space\n when sorting a large sequence. To remind users that it operates\n by side effect, it does not return the sorted sequence (use\n "sorted()" to explicitly request a new sorted list instance).\n\n The "sort()" method is guaranteed to be stable. A sort is\n stable if it guarantees not to change the relative order of\n elements that compare equal --- this is helpful for sorting in\n multiple passes (for example, sort by department, then by salary\n grade).\n\n **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python makes the list appear\n empty for the duration, and raises "ValueError" if it can detect\n that the list has been mutated during a sort.\n\n\nTuples\n======\n\nTuples are immutable sequences, typically used to store collections of\nheterogeneous data (such as the 2-tuples produced by the "enumerate()"\nbuilt-in). Tuples are also used for cases where an immutable sequence\nof homogeneous data is needed (such as allowing storage in a "set" or\n"dict" instance).\n\nclass class tuple([iterable])\n\n Tuples may be constructed in a number of ways:\n\n * Using a pair of parentheses to denote the empty tuple: "()"\n\n * Using a trailing comma for a singleton tuple: "a," or "(a,)"\n\n * Separating items with commas: "a, b, c" or "(a, b, c)"\n\n * Using the "tuple()" built-in: "tuple()" or "tuple(iterable)"\n\n The constructor builds a tuple whose items are the same and in the\n same order as *iterable*\'s items. *iterable* may be either a\n sequence, a container that supports iteration, or an iterator\n object. If *iterable* is already a tuple, it is returned\n unchanged. For example, "tuple(\'abc\')" returns "(\'a\', \'b\', \'c\')"\n and "tuple( [1, 2, 3] )" returns "(1, 2, 3)". If no argument is\n given, the constructor creates a new empty tuple, "()".\n\n Note that it is actually the comma which makes a tuple, not the\n parentheses. The parentheses are optional, except in the empty\n tuple case, or when they are needed to avoid syntactic ambiguity.\n For example, "f(a, b, c)" is a function call with three arguments,\n while "f((a, b, c))" is a function call with a 3-tuple as the sole\n argument.\n\n Tuples implement all of the *common* sequence operations.\n\nFor heterogeneous collections of data where access by name is clearer\nthan access by index, "collections.namedtuple()" may be a more\nappropriate choice than a simple tuple object.\n\n\nRanges\n======\n\nThe "range" type represents an immutable sequence of numbers and is\ncommonly used for looping a specific number of times in "for" loops.\n\nclass class range(stop)\nclass class range(start, stop[, step])\n\n The arguments to the range constructor must be integers (either\n built-in "int" or any object that implements the "__index__"\n special method). If the *step* argument is omitted, it defaults to\n "1". If the *start* argument is omitted, it defaults to "0". If\n *step* is zero, "ValueError" is raised.\n\n For a positive *step*, the contents of a range "r" are determined\n by the formula "r[i] = start + step*i" where "i >= 0" and "r[i] <\n stop".\n\n For a negative *step*, the contents of the range are still\n determined by the formula "r[i] = start + step*i", but the\n constraints are "i >= 0" and "r[i] > stop".\n\n A range object will be empty if "r[0]" does not meet the value\n constraint. Ranges do support negative indices, but these are\n interpreted as indexing from the end of the sequence determined by\n the positive indices.\n\n Ranges containing absolute values larger than "sys.maxsize" are\n permitted but some features (such as "len()") may raise\n "OverflowError".\n\n Range examples:\n\n >>> list(range(10))\n [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n >>> list(range(1, 11))\n [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n >>> list(range(0, 30, 5))\n [0, 5, 10, 15, 20, 25]\n >>> list(range(0, 10, 3))\n [0, 3, 6, 9]\n >>> list(range(0, -10, -1))\n [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]\n >>> list(range(0))\n []\n >>> list(range(1, 0))\n []\n\n Ranges implement all of the *common* sequence operations except\n concatenation and repetition (due to the fact that range objects\n can only represent sequences that follow a strict pattern and\n repetition and concatenation will usually violate that pattern).\n\nThe advantage of the "range" type over a regular "list" or "tuple" is\nthat a "range" object will always take the same (small) amount of\nmemory, no matter the size of the range it represents (as it only\nstores the "start", "stop" and "step" values, calculating individual\nitems and subranges as needed).\n\nRange objects implement the "collections.abc.Sequence" ABC, and\nprovide features such as containment tests, element index lookup,\nslicing and support for negative indices (see *Sequence Types ---\nlist, tuple, range*):\n\n>>> r = range(0, 20, 2)\n>>> r\nrange(0, 20, 2)\n>>> 11 in r\nFalse\n>>> 10 in r\nTrue\n>>> r.index(10)\n5\n>>> r[5]\n10\n>>> r[:5]\nrange(0, 10, 2)\n>>> r[-1]\n18\n\nTesting range objects for equality with "==" and "!=" compares them as\nsequences. That is, two range objects are considered equal if they\nrepresent the same sequence of values. (Note that two range objects\nthat compare equal might have different "start", "stop" and "step"\nattributes, for example "range(0) == range(2, 1, 3)" or "range(0, 3,\n2) == range(0, 4, 2)".)\n\nChanged in version 3.2: Implement the Sequence ABC. Support slicing\nand negative indices. Test "int" objects for membership in constant\ntime instead of iterating through all items.\n\nChanged in version 3.3: Define \'==\' and \'!=\' to compare range objects\nbased on the sequence of values they define (instead of comparing\nbased on object identity).\n\nNew in version 3.3: The "start", "stop" and "step" attributes.\n', + 'typesseq-mutable': u'\nMutable Sequence Types\n**********************\n\nThe operations in the following table are defined on mutable sequence\ntypes. The "collections.abc.MutableSequence" ABC is provided to make\nit easier to correctly implement these operations on custom sequence\ntypes.\n\nIn the table *s* is an instance of a mutable sequence type, *t* is any\niterable object and *x* is an arbitrary object that meets any type and\nvalue restrictions imposed by *s* (for example, "bytearray" only\naccepts integers that meet the value restriction "0 <= x <= 255").\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| "s[i] = x" | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j] = t" | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j]" | same as "s[i:j] = []" | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j:k] = t" | the elements of "s[i:j:k]" are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j:k]" | removes the elements of | |\n| | "s[i:j:k]" from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.append(x)" | appends *x* to the end of the | |\n| | sequence (same as | |\n| | "s[len(s):len(s)] = [x]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.clear()" | removes all items from "s" (same | (5) |\n| | as "del s[:]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.copy()" | creates a shallow copy of "s" | (5) |\n| | (same as "s[:]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.extend(t)" | extends *s* with the contents of | |\n| | *t* (same as "s[len(s):len(s)] = | |\n| | t") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.insert(i, x)" | inserts *x* into *s* at the | |\n| | index given by *i* (same as | |\n| | "s[i:i] = [x]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.pop([i])" | retrieves the item at *i* and | (2) |\n| | also removes it from *s* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.remove(x)" | remove the first item from *s* | (3) |\n| | where "s[i] == x" | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.reverse()" | reverses the items of *s* in | (4) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The optional argument *i* defaults to "-1", so that by default\n the last item is removed and returned.\n\n3. "remove" raises "ValueError" when *x* is not found in *s*.\n\n4. The "reverse()" method modifies the sequence in place for\n economy of space when reversing a large sequence. To remind users\n that it operates by side effect, it does not return the reversed\n sequence.\n\n5. "clear()" and "copy()" are included for consistency with the\n interfaces of mutable containers that don\'t support slicing\n operations (such as "dict" and "set")\n\n New in version 3.3: "clear()" and "copy()" methods.\n', + 'unary': u'\nUnary arithmetic and bitwise operations\n***************************************\n\nAll unary arithmetic and bitwise operations have the same priority:\n\n u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr\n\nThe unary "-" (minus) operator yields the negation of its numeric\nargument.\n\nThe unary "+" (plus) operator yields its numeric argument unchanged.\n\nThe unary "~" (invert) operator yields the bitwise inversion of its\ninteger argument. The bitwise inversion of "x" is defined as\n"-(x+1)". It only applies to integral numbers.\n\nIn all three cases, if the argument does not have the proper type, a\n"TypeError" exception is raised.\n', + 'while': u'\nThe "while" statement\n*********************\n\nThe "while" statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the "else" clause, if present, is executed\nand the loop terminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite. A "continue" statement\nexecuted in the first suite skips the rest of the suite and goes back\nto testing the expression.\n', + 'with': u'\nThe "with" statement\n********************\n\nThe "with" statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common "try"..."except"..."finally"\nusage patterns to be encapsulated for convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the "with" statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the "with_item")\n is evaluated to obtain a context manager.\n\n2. The context manager\'s "__exit__()" is loaded for later use.\n\n3. The context manager\'s "__enter__()" method is invoked.\n\n4. If a target was included in the "with" statement, the return\n value from "__enter__()" is assigned to it.\n\n Note: The "with" statement guarantees that if the "__enter__()"\n method returns without an error, then "__exit__()" will always be\n called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s "__exit__()" method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to "__exit__()". Otherwise, three\n "None" arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the "__exit__()" method was false, the exception is reraised.\n If the return value was true, the exception is suppressed, and\n execution continues with the statement following the "with"\n statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from "__exit__()" is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple "with" statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nChanged in version 3.1: Support for multiple context expressions.\n\nSee also: **PEP 0343** - The "with" statement\n\n The specification, background, and examples for the Python "with"\n statement.\n', + 'yield': u'\nThe "yield" statement\n*********************\n\n yield_stmt ::= yield_expression\n\nA "yield" statement is semantically equivalent to a *yield\nexpression*. The yield statement can be used to omit the parentheses\nthat would otherwise be required in the equivalent yield expression\nstatement. For example, the yield statements\n\n yield \n yield from \n\nare equivalent to the yield expression statements\n\n (yield )\n (yield from )\n\nYield expressions and statements are only used when defining a\n*generator* function, and are only used in the body of the generator\nfunction. Using yield in a function definition is sufficient to cause\nthat definition to create a generator function instead of a normal\nfunction.\n\nFor full details of "yield" semantics, refer to the *Yield\nexpressions* section.\n'} diff --git a/Lib/queue.py b/Lib/queue.py index 3cee36b8961e..572425e844c5 100644 --- a/Lib/queue.py +++ b/Lib/queue.py @@ -6,10 +6,7 @@ import dummy_threading as threading from collections import deque from heapq import heappush, heappop -try: - from time import monotonic as time -except ImportError: - from time import time +from time import monotonic as time __all__ = ['Empty', 'Full', 'Queue', 'PriorityQueue', 'LifoQueue'] diff --git a/Lib/quopri.py b/Lib/quopri.py index e5bd010d5ba8..cbd979abdffc 100755 --- a/Lib/quopri.py +++ b/Lib/quopri.py @@ -44,13 +44,11 @@ def quote(c): def encode(input, output, quotetabs, header=False): """Read 'input', apply quoted-printable encoding, and write to 'output'. - 'input' and 'output' are files with readline() and write() methods. - The 'quotetabs' flag indicates whether embedded tabs and spaces should be - quoted. Note that line-ending tabs and spaces are always encoded, as per - RFC 1521. - The 'header' flag indicates whether we are encoding spaces as _ as per - RFC 1522. - """ + 'input' and 'output' are binary file objects. The 'quotetabs' flag + indicates whether embedded tabs and spaces should be quoted. Note that + line-ending tabs and spaces are always encoded, as per RFC 1521. + The 'header' flag indicates whether we are encoding spaces as _ as per RFC + 1522.""" if b2a_qp is not None: data = input.read() @@ -118,7 +116,7 @@ def encodestring(s, quotetabs=False, header=False): def decode(input, output, header=False): """Read 'input', apply quoted-printable decoding, and write to 'output'. - 'input' and 'output' are files with readline() and write() methods. + 'input' and 'output' are binary file objects. If 'header' is true, decode underscore as space (per RFC 1522).""" if a2b_qp is not None: @@ -147,7 +145,7 @@ def decode(input, output, header=False): new = new + c; i = i+1 elif i+1 == n and not partial: partial = 1; break - elif i+1 < n and line[i+1] == ESCAPE: + elif i+1 < n and line[i+1:i+2] == ESCAPE: new = new + ESCAPE; i = i+2 elif i+2 < n and ishex(line[i+1:i+2]) and ishex(line[i+2:i+3]): new = new + bytes((unhex(line[i+1:i+3]),)); i = i+3 diff --git a/Lib/random.py b/Lib/random.py index 808175ab4a10..1f5be45a4b6d 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -105,7 +105,9 @@ def seed(self, a=None, version=2): if a is None: try: - a = int.from_bytes(_urandom(32), 'big') + # Seed with enough bytes to span the 19937 bit + # state space for the Mersenne Twister + a = int.from_bytes(_urandom(2500), 'big') except NotImplementedError: import time a = int(time.time() * 256) # use fractional seconds @@ -353,7 +355,10 @@ def triangular(self, low=0.0, high=1.0, mode=None): """ u = self.random() - c = 0.5 if mode is None else (mode - low) / (high - low) + try: + c = 0.5 if mode is None else (mode - low) / (high - low) + except ZeroDivisionError: + return low if u > c: u = 1.0 - u c = 1.0 - c @@ -682,7 +687,7 @@ def _test_generator(n, func, args): print(round(t1-t0, 3), 'sec,', end=' ') avg = total/n stddev = _sqrt(sqsum/n - avg*avg) - print('avg %g, stddev %g, min %g, max %g' % \ + print('avg %g, stddev %g, min %g, max %g\n' % \ (avg, stddev, smallest, largest)) diff --git a/Lib/re.py b/Lib/re.py index 77f5e3fadbab..dde8901c626f 100644 --- a/Lib/re.py +++ b/Lib/re.py @@ -122,12 +122,19 @@ import sys import sre_compile import sre_parse +try: + import _locale +except ImportError: + _locale = None # public symbols -__all__ = [ "match", "fullmatch", "search", "sub", "subn", "split", "findall", - "compile", "purge", "template", "escape", "A", "I", "L", "M", "S", "X", - "U", "ASCII", "IGNORECASE", "LOCALE", "MULTILINE", "DOTALL", "VERBOSE", - "UNICODE", "error" ] +__all__ = [ + "match", "fullmatch", "search", "sub", "subn", "split", + "findall", "finditer", "compile", "purge", "template", "escape", + "error", "A", "I", "L", "M", "S", "X", "U", + "ASCII", "IGNORECASE", "LOCALE", "MULTILINE", "DOTALL", "VERBOSE", + "UNICODE", +] __version__ = "2.2.1" @@ -205,14 +212,12 @@ def findall(pattern, string, flags=0): Empty matches are included in the result.""" return _compile(pattern, flags).findall(string) -if sys.hexversion >= 0x02020000: - __all__.append("finditer") - def finditer(pattern, string, flags=0): - """Return an iterator over all non-overlapping matches in the - string. For each match, the iterator returns a match object. +def finditer(pattern, string, flags=0): + """Return an iterator over all non-overlapping matches in the + string. For each match, the iterator returns a match object. - Empty matches are included in the result.""" - return _compile(pattern, flags).finditer(string) + Empty matches are included in the result.""" + return _compile(pattern, flags).finditer(string) def compile(pattern, flags=0): "Compile a regular expression pattern, returning a pattern object." @@ -273,20 +278,29 @@ def escape(pattern): def _compile(pattern, flags): # internal: compile pattern try: - return _cache[type(pattern), pattern, flags] + p, loc = _cache[type(pattern), pattern, flags] + if loc is None or loc == _locale.setlocale(_locale.LC_CTYPE): + return p except KeyError: pass if isinstance(pattern, _pattern_type): if flags: raise ValueError( - "Cannot process flags argument with a compiled pattern") + "cannot process flags argument with a compiled pattern") return pattern if not sre_compile.isstring(pattern): raise TypeError("first argument must be string or compiled pattern") p = sre_compile.compile(pattern, flags) - if len(_cache) >= _MAXCACHE: - _cache.clear() - _cache[type(pattern), pattern, flags] = p + if not (flags & DEBUG): + if len(_cache) >= _MAXCACHE: + _cache.clear() + if p.flags & LOCALE: + if not _locale: + return p + loc = _locale.setlocale(_locale.LC_CTYPE) + else: + loc = None + _cache[type(pattern), pattern, flags] = p, loc return p def _compile_repl(repl, pattern): @@ -337,10 +351,11 @@ def __init__(self, lexicon, flags=0): s = sre_parse.Pattern() s.flags = flags for phrase, action in lexicon: + gid = s.opengroup() p.append(sre_parse.SubPattern(s, [ - (SUBPATTERN, (len(p)+1, sre_parse.parse(phrase, flags))), + (SUBPATTERN, (gid, sre_parse.parse(phrase, flags))), ])) - s.groups = len(p)+1 + s.closegroup(gid, p[-1]) p = sre_parse.SubPattern(s, [(BRANCH, (None, p))]) self.scanner = sre_compile.compile(p) def scan(self, string): @@ -348,7 +363,7 @@ def scan(self, string): append = result.append match = self.scanner.scanner(string).match i = 0 - while 1: + while True: m = match() if not m: break diff --git a/Lib/reprlib.py b/Lib/reprlib.py index f8033604da28..ecbd2cc47228 100644 --- a/Lib/reprlib.py +++ b/Lib/reprlib.py @@ -83,16 +83,22 @@ def repr_list(self, x, level): return self._repr_iterable(x, level, '[', ']', self.maxlist) def repr_array(self, x, level): + if not x: + return "array('%s')" % x.typecode header = "array('%s', [" % x.typecode return self._repr_iterable(x, level, header, '])', self.maxarray) def repr_set(self, x, level): + if not x: + return 'set()' x = _possibly_sorted(x) - return self._repr_iterable(x, level, 'set([', '])', self.maxset) + return self._repr_iterable(x, level, '{', '}', self.maxset) def repr_frozenset(self, x, level): + if not x: + return 'frozenset()' x = _possibly_sorted(x) - return self._repr_iterable(x, level, 'frozenset([', '])', + return self._repr_iterable(x, level, 'frozenset({', '})', self.maxfrozenset) def repr_deque(self, x, level): @@ -136,7 +142,7 @@ def repr_instance(self, x, level): # Bugs in x.__repr__() can cause arbitrary # exceptions -- then make up something except Exception: - return '<%s instance at %x>' % (x.__class__.__name__, id(x)) + return '<%s instance at %#x>' % (x.__class__.__name__, id(x)) if len(s) > self.maxother: i = max(0, (self.maxother-3)//2) j = max(0, self.maxother-3-i) diff --git a/Lib/rlcompleter.py b/Lib/rlcompleter.py index 94f9341beef0..613848f7adf8 100644 --- a/Lib/rlcompleter.py +++ b/Lib/rlcompleter.py @@ -73,6 +73,12 @@ def complete(self, text, state): if self.use_main_ns: self.namespace = __main__.__dict__ + if not text.strip(): + if state == 0: + return '\t' + else: + return None + if state == 0: if "." in text: self.matches = self.attr_matches(text) @@ -100,6 +106,12 @@ def global_matches(self, text): n = len(text) for word in keyword.kwlist: if word[:n] == text: + if word in {'finally', 'try'}: + word = word + ':' + elif word not in {'False', 'None', 'True', + 'break', 'continue', 'pass', + 'else'}: + word = word + ' ' matches.append(word) for nspace in [builtins.__dict__, self.namespace]: for word, val in nspace.items(): @@ -130,20 +142,35 @@ def attr_matches(self, text): return [] # get the content of the object, except __builtins__ - words = dir(thisobject) - if "__builtins__" in words: - words.remove("__builtins__") + words = set(dir(thisobject)) + words.discard("__builtins__") if hasattr(thisobject, '__class__'): - words.append('__class__') - words.extend(get_class_members(thisobject.__class__)) + words.add('__class__') + words.update(get_class_members(thisobject.__class__)) matches = [] n = len(attr) - for word in words: - if word[:n] == attr and hasattr(thisobject, word): - val = getattr(thisobject, word) - word = self._callable_postfix(val, "%s.%s" % (expr, word)) - matches.append(word) + if attr == '': + noprefix = '_' + elif attr == '_': + noprefix = '__' + else: + noprefix = None + while True: + for word in words: + if (word[:n] == attr and + not (noprefix and word[:n+1] == noprefix) and + hasattr(thisobject, word)): + val = getattr(thisobject, word) + word = self._callable_postfix(val, "%s.%s" % (expr, word)) + matches.append(word) + if matches or not noprefix: + break + if noprefix == '_': + noprefix = '__' + else: + noprefix = None + matches.sort() return matches def get_class_members(klass): diff --git a/Lib/runpy.py b/Lib/runpy.py index 1e0a2be4f0c9..1c5729da3558 100644 --- a/Lib/runpy.py +++ b/Lib/runpy.py @@ -10,11 +10,11 @@ # to implement PEP 338 (Executing Modules as Scripts) -import os import sys import importlib.machinery # importlib first so we can test #15386 via -m +import importlib.util import types -from pkgutil import read_code, get_loader, get_importer +from pkgutil import read_code, get_importer __all__ = [ "run_module", "run_path", @@ -58,51 +58,59 @@ def __exit__(self, *args): self.value = self._sentinel sys.argv[0] = self._saved_value +# TODO: Replace these helpers with importlib._bootstrap_external functions. def _run_code(code, run_globals, init_globals=None, - mod_name=None, mod_fname=None, - mod_loader=None, pkg_name=None): + mod_name=None, mod_spec=None, + pkg_name=None, script_name=None): """Helper to run code in nominated namespace""" if init_globals is not None: run_globals.update(init_globals) + if mod_spec is None: + loader = None + fname = script_name + cached = None + else: + loader = mod_spec.loader + fname = mod_spec.origin + cached = mod_spec.cached + if pkg_name is None: + pkg_name = mod_spec.parent run_globals.update(__name__ = mod_name, - __file__ = mod_fname, - __cached__ = None, + __file__ = fname, + __cached__ = cached, __doc__ = None, - __loader__ = mod_loader, - __package__ = pkg_name) + __loader__ = loader, + __package__ = pkg_name, + __spec__ = mod_spec) exec(code, run_globals) return run_globals def _run_module_code(code, init_globals=None, - mod_name=None, mod_fname=None, - mod_loader=None, pkg_name=None): + mod_name=None, mod_spec=None, + pkg_name=None, script_name=None): """Helper to run code in new namespace with sys modified""" - with _TempModule(mod_name) as temp_module, _ModifiedArgv0(mod_fname): + fname = script_name if mod_spec is None else mod_spec.origin + with _TempModule(mod_name) as temp_module, _ModifiedArgv0(fname): mod_globals = temp_module.module.__dict__ _run_code(code, mod_globals, init_globals, - mod_name, mod_fname, mod_loader, pkg_name) + mod_name, mod_spec, pkg_name, script_name) # Copy the globals of the temporary module, as they # may be cleared when the temporary module goes away return mod_globals.copy() - -# This helper is needed due to a missing component in the PEP 302 -# loader protocol (specifically, "get_filename" is non-standard) -# Since we can't introduce new features in maintenance releases, -# support was added to zipimporter under the name '_get_filename' -def _get_filename(loader, mod_name): - for attr in ("get_filename", "_get_filename"): - meth = getattr(loader, attr, None) - if meth is not None: - return os.path.abspath(meth(mod_name)) - return None - # Helper to get the loader, code and filename for a module def _get_module_details(mod_name): - loader = get_loader(mod_name) - if loader is None: + try: + spec = importlib.util.find_spec(mod_name) + except (ImportError, AttributeError, TypeError, ValueError) as ex: + # This hack fixes an impedance mismatch between pkgutil and + # importlib, where the latter raises other errors for cases where + # pkgutil previously raised ImportError + msg = "Error while finding spec for {!r} ({}: {})" + raise ImportError(msg.format(mod_name, type(ex), ex)) from ex + if spec is None: raise ImportError("No module named %s" % mod_name) - if loader.is_package(mod_name): + if spec.submodule_search_locations is not None: if mod_name == "__main__" or mod_name.endswith(".__main__"): raise ImportError("Cannot use package as __main__ module") try: @@ -111,11 +119,14 @@ def _get_module_details(mod_name): except ImportError as e: raise ImportError(("%s; %r is a package and cannot " + "be directly executed") %(e, mod_name)) + loader = spec.loader + if loader is None: + raise ImportError("%r is a namespace package and cannot be executed" + % mod_name) code = loader.get_code(mod_name) if code is None: raise ImportError("No code object available for %s" % mod_name) - filename = _get_filename(loader, mod_name) - return mod_name, loader, code, filename + return mod_name, spec, code # XXX ncoghlan: Should this be documented and made public? # (Current thoughts: don't repeat the mistake that lead to its @@ -137,9 +148,9 @@ def _run_module_as_main(mod_name, alter_argv=True): """ try: if alter_argv or mod_name != "__main__": # i.e. -m switch - mod_name, loader, code, fname = _get_module_details(mod_name) + mod_name, mod_spec, code = _get_module_details(mod_name) else: # i.e. directory or zipfile execution - mod_name, loader, code, fname = _get_main_module_details() + mod_name, mod_spec, code = _get_main_module_details() except ImportError as exc: # Try to provide a good error message # for directories, zip files and the -m switch @@ -152,12 +163,11 @@ def _run_module_as_main(mod_name, alter_argv=True): info = "can't find '__main__' module in %r" % sys.argv[0] msg = "%s: %s" % (sys.executable, info) sys.exit(msg) - pkg_name = mod_name.rpartition('.')[0] main_globals = sys.modules["__main__"].__dict__ if alter_argv: - sys.argv[0] = fname + sys.argv[0] = mod_spec.origin return _run_code(code, main_globals, None, - "__main__", fname, loader, pkg_name) + "__main__", mod_spec) def run_module(mod_name, init_globals=None, run_name=None, alter_sys=False): @@ -165,17 +175,14 @@ def run_module(mod_name, init_globals=None, Returns the resulting top level namespace dictionary """ - mod_name, loader, code, fname = _get_module_details(mod_name) + mod_name, mod_spec, code = _get_module_details(mod_name) if run_name is None: run_name = mod_name - pkg_name = mod_name.rpartition('.')[0] if alter_sys: - return _run_module_code(code, init_globals, run_name, - fname, loader, pkg_name) + return _run_module_code(code, init_globals, run_name, mod_spec) else: # Leave the sys module alone - return _run_code(code, {}, init_globals, run_name, - fname, loader, pkg_name) + return _run_code(code, {}, init_globals, run_name, mod_spec) def _get_main_module_details(): # Helper that gives a nicer error message when attempting to @@ -204,10 +211,7 @@ def _get_code_from_file(run_name, fname): # That didn't work, so try it as normal source code with open(fname, "rb") as f: code = compile(f.read(), fname, 'exec') - loader = importlib.machinery.SourceFileLoader(run_name, fname) - else: - loader = importlib.machinery.SourcelessFileLoader(run_name, fname) - return code, loader + return code, fname def run_path(path_name, init_globals=None, run_name=None): """Execute code located at the specified filesystem location @@ -231,9 +235,9 @@ def run_path(path_name, init_globals=None, run_name=None): if isinstance(importer, type(None)) or is_NullImporter: # Not a valid sys.path entry, so run the code directly # execfile() doesn't help as we want to allow compiled files - code, mod_loader = _get_code_from_file(run_name, path_name) - return _run_module_code(code, init_globals, run_name, path_name, - mod_loader, pkg_name) + code, fname = _get_code_from_file(run_name, path_name) + return _run_module_code(code, init_globals, run_name, + pkg_name=pkg_name, script_name=fname) else: # Importer is defined for path, so add it to # the start of sys.path @@ -245,12 +249,12 @@ def run_path(path_name, init_globals=None, run_name=None): # have no choice and we have to remove it even while we read the # code. If we don't do this, a __loader__ attribute in the # existing __main__ module may prevent location of the new module. - mod_name, loader, code, fname = _get_main_module_details() + mod_name, mod_spec, code = _get_main_module_details() with _TempModule(run_name) as temp_module, \ _ModifiedArgv0(path_name): mod_globals = temp_module.module.__dict__ return _run_code(code, mod_globals, init_globals, - run_name, fname, loader, pkg_name).copy() + run_name, mod_spec, pkg_name).copy() finally: try: sys.path.remove(path_name) diff --git a/Lib/sched.py b/Lib/sched.py index 2e6b00a2a22e..bd7c0f1b6ff3 100644 --- a/Lib/sched.py +++ b/Lib/sched.py @@ -35,21 +35,28 @@ import threading except ImportError: import dummy_threading as threading -try: - from time import monotonic as _time -except ImportError: - from time import time as _time +from time import monotonic as _time __all__ = ["scheduler"] class Event(namedtuple('Event', 'time, priority, action, argument, kwargs')): def __eq__(s, o): return (s.time, s.priority) == (o.time, o.priority) - def __ne__(s, o): return (s.time, s.priority) != (o.time, o.priority) def __lt__(s, o): return (s.time, s.priority) < (o.time, o.priority) def __le__(s, o): return (s.time, s.priority) <= (o.time, o.priority) def __gt__(s, o): return (s.time, s.priority) > (o.time, o.priority) def __ge__(s, o): return (s.time, s.priority) >= (o.time, o.priority) +Event.time.__doc__ = ('''Numeric type compatible with the return value of the +timefunc function passed to the constructor.''') +Event.priority.__doc__ = ('''Events scheduled for the same time will be executed +in the order of their priority.''') +Event.action.__doc__ = ('''Executing the event means executing +action(*argument, **kwargs)''') +Event.argument.__doc__ = ('''argument is a sequence holding the positional +arguments for the action.''') +Event.kwargs.__doc__ = ('''kwargs is a dictionary holding the keyword +arguments for the action.''') + _sentinel = object() class scheduler: diff --git a/Lib/selectors.py b/Lib/selectors.py index c533f13d6957..ecd8632d7048 100644 --- a/Lib/selectors.py +++ b/Lib/selectors.py @@ -7,7 +7,7 @@ from abc import ABCMeta, abstractmethod from collections import namedtuple, Mapping -import functools +import math import select import sys @@ -25,6 +25,9 @@ def _fileobj_to_fd(fileobj): Returns: corresponding file descriptor + + Raises: + ValueError if the object is invalid """ if isinstance(fileobj, int): fd = fileobj @@ -40,9 +43,17 @@ def _fileobj_to_fd(fileobj): SelectorKey = namedtuple('SelectorKey', ['fileobj', 'fd', 'events', 'data']) -"""Object used to associate a file object to its backing file descriptor, -selected event mask and attached data.""" +SelectorKey.__doc__ = """SelectorKey(fileobj, fd, events, data) + + Object used to associate a file object to its backing + file descriptor, selected event mask, and attached data. +""" +SelectorKey.fileobj.__doc__ = 'File object registered.' +SelectorKey.fd.__doc__ = 'Underlying file descriptor.' +SelectorKey.events.__doc__ = 'Events that must be waited for on this file object.' +SelectorKey.data.__doc__ = ('''Optional opaque data associated to this file object. +For example, this could be used to store a per-client session ID.''') class _SelectorMapping(Mapping): """Mapping of file objects to selector keys.""" @@ -55,7 +66,8 @@ def __len__(self): def __getitem__(self, fileobj): try: - return self._selector._fd_to_key[_fileobj_to_fd(fileobj)] + fd = self._selector._fileobj_lookup(fileobj) + return self._selector._fd_to_key[fd] except KeyError: raise KeyError("{!r} is not registered".format(fileobj)) from None @@ -75,7 +87,7 @@ class BaseSelector(metaclass=ABCMeta): A selector can use various implementations (select(), poll(), epoll()...) depending on the platform. The default `Selector` class uses the most - performant implementation on the current platform. + efficient implementation on the current platform. """ @abstractmethod @@ -89,6 +101,15 @@ def register(self, fileobj, events, data=None): Returns: SelectorKey instance + + Raises: + ValueError if events is invalid + KeyError if fileobj is already registered + OSError if fileobj is closed or otherwise is unacceptable to + the underlying system call (if a system call is made) + + Note: + OSError may or may not be raised """ raise NotImplementedError @@ -101,6 +122,13 @@ def unregister(self, fileobj): Returns: SelectorKey instance + + Raises: + KeyError if fileobj is not registered + + Note: + If fileobj is registered but has since been closed this does + *not* raise OSError (even if the wrapped syscall does) """ raise NotImplementedError @@ -114,6 +142,9 @@ def modify(self, fileobj, events, data=None): Returns: SelectorKey instance + + Raises: + Anything that unregister() or register() raises """ self.unregister(fileobj) return self.register(fileobj, events, data) @@ -151,6 +182,8 @@ def get_key(self, fileobj): SelectorKey for this file object """ mapping = self.get_map() + if mapping is None: + raise RuntimeError('Selector is closed') try: return mapping[fileobj] except KeyError: @@ -177,22 +210,41 @@ def __init__(self): # read-only mapping returned by get_map() self._map = _SelectorMapping(self) + def _fileobj_lookup(self, fileobj): + """Return a file descriptor from a file object. + + This wraps _fileobj_to_fd() to do an exhaustive search in case + the object is invalid but we still have it in our map. This + is used by unregister() so we can unregister an object that + was previously registered even if it is closed. It is also + used by _SelectorMapping. + """ + try: + return _fileobj_to_fd(fileobj) + except ValueError: + # Do an exhaustive search. + for key in self._fd_to_key.values(): + if key.fileobj is fileobj: + return key.fd + # Raise ValueError after all. + raise + def register(self, fileobj, events, data=None): if (not events) or (events & ~(EVENT_READ | EVENT_WRITE)): raise ValueError("Invalid events: {!r}".format(events)) - key = SelectorKey(fileobj, _fileobj_to_fd(fileobj), events, data) + key = SelectorKey(fileobj, self._fileobj_lookup(fileobj), events, data) if key.fd in self._fd_to_key: - raise KeyError("{!r} (FD {}) is already " - "registered".format(fileobj, key.fd)) + raise KeyError("{!r} (FD {}) is already registered" + .format(fileobj, key.fd)) self._fd_to_key[key.fd] = key return key def unregister(self, fileobj): try: - key = self._fd_to_key.pop(_fileobj_to_fd(fileobj)) + key = self._fd_to_key.pop(self._fileobj_lookup(fileobj)) except KeyError: raise KeyError("{!r} is not registered".format(fileobj)) from None return key @@ -200,7 +252,7 @@ def unregister(self, fileobj): def modify(self, fileobj, events, data=None): # TODO: Subclasses can probably optimize this even further. try: - key = self._fd_to_key[_fileobj_to_fd(fileobj)] + key = self._fd_to_key[self._fileobj_lookup(fileobj)] except KeyError: raise KeyError("{!r} is not registered".format(fileobj)) from None if events != key.events: @@ -214,6 +266,7 @@ def modify(self, fileobj, events, data=None): def close(self): self._fd_to_key.clear() + self._map = None def get_map(self): return self._map @@ -309,7 +362,14 @@ def unregister(self, fileobj): return key def select(self, timeout=None): - timeout = None if timeout is None else max(int(1000 * timeout), 0) + if timeout is None: + timeout = None + elif timeout <= 0: + timeout = 0 + else: + # poll() has a resolution of 1 millisecond, round away from + # zero to wait *at least* timeout seconds. + timeout = math.ceil(timeout * 1e3) ready = [] try: fd_event_list = self._poll.poll(timeout) @@ -352,12 +412,29 @@ def register(self, fileobj, events, data=None): def unregister(self, fileobj): key = super().unregister(fileobj) - self._epoll.unregister(key.fd) + try: + self._epoll.unregister(key.fd) + except OSError: + # This can happen if the FD was closed since it + # was registered. + pass return key def select(self, timeout=None): - timeout = -1 if timeout is None else max(timeout, 0) - max_ev = len(self._fd_to_key) + if timeout is None: + timeout = -1 + elif timeout <= 0: + timeout = 0 + else: + # epoll_wait() has a resolution of 1 millisecond, round away + # from zero to wait *at least* timeout seconds. + timeout = math.ceil(timeout * 1e3) * 1e-3 + + # epoll_wait() expects `maxevents` to be greater than zero; + # we want to make sure that `select()` can be called when no + # FD is registered. + max_ev = max(len(self._fd_to_key), 1) + ready = [] try: fd_event_list = self._epoll.poll(timeout, max_ev) @@ -380,6 +457,64 @@ def close(self): super().close() +if hasattr(select, 'devpoll'): + + class DevpollSelector(_BaseSelectorImpl): + """Solaris /dev/poll selector.""" + + def __init__(self): + super().__init__() + self._devpoll = select.devpoll() + + def fileno(self): + return self._devpoll.fileno() + + def register(self, fileobj, events, data=None): + key = super().register(fileobj, events, data) + poll_events = 0 + if events & EVENT_READ: + poll_events |= select.POLLIN + if events & EVENT_WRITE: + poll_events |= select.POLLOUT + self._devpoll.register(key.fd, poll_events) + return key + + def unregister(self, fileobj): + key = super().unregister(fileobj) + self._devpoll.unregister(key.fd) + return key + + def select(self, timeout=None): + if timeout is None: + timeout = None + elif timeout <= 0: + timeout = 0 + else: + # devpoll() has a resolution of 1 millisecond, round away from + # zero to wait *at least* timeout seconds. + timeout = math.ceil(timeout * 1e3) + ready = [] + try: + fd_event_list = self._devpoll.poll(timeout) + except InterruptedError: + return ready + for fd, event in fd_event_list: + events = 0 + if event & ~select.POLLIN: + events |= EVENT_WRITE + if event & ~select.POLLOUT: + events |= EVENT_READ + + key = self._key_from_fd(fd) + if key: + ready.append((key, events & key.events)) + return ready + + def close(self): + self._devpoll.close() + super().close() + + if hasattr(select, 'kqueue'): class KqueueSelector(_BaseSelectorImpl): @@ -409,11 +544,20 @@ def unregister(self, fileobj): if key.events & EVENT_READ: kev = select.kevent(key.fd, select.KQ_FILTER_READ, select.KQ_EV_DELETE) - self._kqueue.control([kev], 0, 0) + try: + self._kqueue.control([kev], 0, 0) + except OSError: + # This can happen if the FD was closed since it + # was registered. + pass if key.events & EVENT_WRITE: kev = select.kevent(key.fd, select.KQ_FILTER_WRITE, select.KQ_EV_DELETE) - self._kqueue.control([kev], 0, 0) + try: + self._kqueue.control([kev], 0, 0) + except OSError: + # See comment above. + pass return key def select(self, timeout=None): @@ -443,12 +587,15 @@ def close(self): super().close() -# Choose the best implementation: roughly, epoll|kqueue > poll > select. +# Choose the best implementation, roughly: +# epoll|kqueue|devpoll > poll > select. # select() also can't accept a FD > FD_SETSIZE (usually around 1024) if 'KqueueSelector' in globals(): DefaultSelector = KqueueSelector elif 'EpollSelector' in globals(): DefaultSelector = EpollSelector +elif 'DevpollSelector' in globals(): + DefaultSelector = DevpollSelector elif 'PollSelector' in globals(): DefaultSelector = PollSelector else: diff --git a/Lib/shelve.py b/Lib/shelve.py index cef580e5cdca..581baf1e6f3f 100644 --- a/Lib/shelve.py +++ b/Lib/shelve.py @@ -138,17 +138,21 @@ def __exit__(self, type, value, traceback): self.close() def close(self): - self.sync() - try: - self.dict.close() - except AttributeError: - pass - # Catch errors that may happen when close is called from __del__ - # because CPython is in interpreter shutdown. + if self.dict is None: + return try: - self.dict = _ClosedDict() - except (NameError, TypeError): - self.dict = None + self.sync() + try: + self.dict.close() + except AttributeError: + pass + finally: + # Catch errors that may happen when close is called from __del__ + # because CPython is in interpreter shutdown. + try: + self.dict = _ClosedDict() + except: + self.dict = None def __del__(self): if not hasattr(self, 'writeback'): diff --git a/Lib/shlex.py b/Lib/shlex.py index 69f3b456af10..f08391800b14 100644 --- a/Lib/shlex.py +++ b/Lib/shlex.py @@ -49,9 +49,6 @@ def __init__(self, instream=None, infile=None, posix=False): self.token = '' self.filestack = deque() self.source = None - if self.debug: - print('shlex: reading from %s, line %d' \ - % (self.instream, self.lineno)) def push_token(self, tok): "Push a token onto the stack popped by the get_token method" @@ -290,15 +287,17 @@ def quote(s): return "'" + s.replace("'", "'\"'\"'") + "'" -if __name__ == '__main__': - if len(sys.argv) == 1: - lexer = shlex() - else: - file = sys.argv[1] - lexer = shlex(open(file), file) +def _print_tokens(lexer): while 1: tt = lexer.get_token() - if tt: - print("Token: " + repr(tt)) - else: + if not tt: break + print("Token: " + repr(tt)) + +if __name__ == '__main__': + if len(sys.argv) == 1: + _print_tokens(shlex()) + else: + fn = sys.argv[1] + with open(fn) as f: + _print_tokens(shlex(f, fn)) diff --git a/Lib/shutil.py b/Lib/shutil.py index 502bb6782c41..f47a763f35b4 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -7,7 +7,6 @@ import os import sys import stat -from os.path import abspath import fnmatch import collections import errno @@ -20,6 +19,13 @@ except ImportError: _BZ2_SUPPORTED = False +try: + import lzma + del lzma + _LZMA_SUPPORTED = True +except ImportError: + _LZMA_SUPPORTED = False + try: from pwd import getpwnam except ImportError: @@ -36,7 +42,8 @@ "register_archive_format", "unregister_archive_format", "get_unpack_formats", "register_unpack_format", "unregister_unpack_format", "unpack_archive", - "ignore_patterns", "chown", "which"] + "ignore_patterns", "chown", "which", "get_terminal_size", + "SameFileError"] # disk_usage is added later, if available on the platform class Error(OSError): @@ -320,7 +327,11 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, if not os.path.exists(linkto) and ignore_dangling_symlinks: continue # otherwise let the copy occurs. copy2 will raise an error - copy_function(srcname, dstname) + if os.path.isdir(srcname): + copytree(srcname, dstname, symlinks, ignore, + copy_function) + else: + copy_function(srcname, dstname) elif os.path.isdir(srcname): copytree(srcname, dstname, symlinks, ignore, copy_function) else: @@ -336,7 +347,7 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, copystat(src, dst) except OSError as why: # Copying file access times may fail on Windows - if why.winerror is None: + if getattr(why, 'winerror', None) is None: errors.append((src, dst, str(why))) if errors: raise Error(errors) @@ -483,9 +494,10 @@ def onerror(*args): def _basename(path): # A basename() variant which first strips the trailing slash, if present. # Thus we always get the last component of the path, even for directories. - return os.path.basename(path.rstrip(os.path.sep)) + sep = os.path.sep + (os.path.altsep or '') + return os.path.basename(path.rstrip(sep)) -def move(src, dst): +def move(src, dst, copy_function=copy2): """Recursively move a file or directory to another location. This is similar to the Unix "mv" command. Return the file or directory's destination. @@ -502,6 +514,11 @@ def move(src, dst): recreated under the new name if os.rename() fails because of cross filesystem renames. + The optional `copy_function` argument is a callable that will be used + to copy the source or it will be delegated to `copytree`. + By default, copy2() is used, but any function that supports the same + signature (like copy()) can be used. + A lot more could be done here... A look at a mv.c shows a lot of the issues this implementation glosses over. @@ -526,17 +543,19 @@ def move(src, dst): os.unlink(src) elif os.path.isdir(src): if _destinsrc(src, dst): - raise Error("Cannot move a directory '%s' into itself '%s'." % (src, dst)) - copytree(src, real_dst, symlinks=True) + raise Error("Cannot move a directory '%s' into itself" + " '%s'." % (src, dst)) + copytree(src, real_dst, copy_function=copy_function, + symlinks=True) rmtree(src) else: - copy2(src, real_dst) + copy_function(src, real_dst) os.unlink(src) return real_dst def _destinsrc(src, dst): - src = abspath(src) - dst = abspath(dst) + src = os.path.abspath(src) + dst = os.path.abspath(dst) if not src.endswith(os.path.sep): src += os.path.sep if not dst.endswith(os.path.sep): @@ -572,14 +591,14 @@ def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, """Create a (possibly compressed) tar file from all the files under 'base_dir'. - 'compress' must be "gzip" (the default), "bzip2", or None. + 'compress' must be "gzip" (the default), "bzip2", "xz", or None. 'owner' and 'group' can be used to define an owner and a group for the archive that is being built. If not provided, the current owner and group will be used. The output tar file will be named 'base_name' + ".tar", possibly plus - the appropriate compression extension (".gz", or ".bz2"). + the appropriate compression extension (".gz", ".bz2", or ".xz"). Returns the output filename. """ @@ -590,6 +609,10 @@ def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, tar_compression['bzip2'] = 'bz2' compress_ext['bzip2'] = '.bz2' + if _LZMA_SUPPORTED: + tar_compression['xz'] = 'xz' + compress_ext['xz'] = '.xz' + # flags for compression program, each element of list will be an argument if compress is not None and compress not in compress_ext: raise ValueError("bad value for 'compress', or compression format not " @@ -598,7 +621,7 @@ def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, archive_name = base_name + '.tar' + compress_ext.get(compress, '') archive_dir = os.path.dirname(archive_name) - if not os.path.exists(archive_dir): + if archive_dir and not os.path.exists(archive_dir): if logger is not None: logger.info("creating %s", archive_dir) if not dry_run: @@ -629,23 +652,6 @@ def _set_uid_gid(tarinfo): return archive_name -def _call_external_zip(base_dir, zip_filename, verbose=False, dry_run=False): - # XXX see if we want to keep an external call here - if verbose: - zipoptions = "-r" - else: - zipoptions = "-rq" - from distutils.errors import DistutilsExecError - from distutils.spawn import spawn - try: - spawn(["zip", zipoptions, zip_filename, base_dir], dry_run=dry_run) - except DistutilsExecError: - # XXX really should distinguish between "couldn't find - # external 'zip' command" and "zip failed". - raise ExecError("unable to create zip file '%s': " - "could neither import the 'zipfile' module nor " - "find a standalone zip utility") % zip_filename - def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None): """Create a zip file from all the files under 'base_dir'. @@ -655,41 +661,40 @@ def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None): available, raises ExecError. Returns the name of the output zip file. """ + import zipfile + zip_filename = base_name + ".zip" archive_dir = os.path.dirname(base_name) - if not os.path.exists(archive_dir): + if archive_dir and not os.path.exists(archive_dir): if logger is not None: logger.info("creating %s", archive_dir) if not dry_run: os.makedirs(archive_dir) - # If zipfile module is not available, try spawning an external 'zip' - # command. - try: - import zipfile - except ImportError: - zipfile = None - - if zipfile is None: - _call_external_zip(base_dir, zip_filename, verbose, dry_run) - else: - if logger is not None: - logger.info("creating '%s' and adding '%s' to it", - zip_filename, base_dir) - - if not dry_run: - zip = zipfile.ZipFile(zip_filename, "w", - compression=zipfile.ZIP_DEFLATED) + if logger is not None: + logger.info("creating '%s' and adding '%s' to it", + zip_filename, base_dir) + if not dry_run: + with zipfile.ZipFile(zip_filename, "w", + compression=zipfile.ZIP_DEFLATED) as zf: + path = os.path.normpath(base_dir) + zf.write(path, path) + if logger is not None: + logger.info("adding '%s'", path) for dirpath, dirnames, filenames in os.walk(base_dir): + for name in sorted(dirnames): + path = os.path.normpath(os.path.join(dirpath, name)) + zf.write(path, path) + if logger is not None: + logger.info("adding '%s'", path) for name in filenames: path = os.path.normpath(os.path.join(dirpath, name)) if os.path.isfile(path): - zip.write(path, path) + zf.write(path, path) if logger is not None: logger.info("adding '%s'", path) - zip.close() return zip_filename @@ -703,6 +708,10 @@ def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None): _ARCHIVE_FORMATS['bztar'] = (_make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file") +if _LZMA_SUPPORTED: + _ARCHIVE_FORMATS['xztar'] = (_make_tarball, [('compress', 'xz')], + "xz'ed tar-file") + def get_archive_formats(): """Returns a list of supported formats for archiving and unarchiving. @@ -891,7 +900,7 @@ def _unpack_zipfile(filename, extract_dir): zip.close() def _unpack_tarfile(filename, extract_dir): - """Unpack tar/tar.gz/tar.bz2 `filename` to `extract_dir` + """Unpack tar/tar.gz/tar.bz2/tar.xz `filename` to `extract_dir` """ try: tarobj = tarfile.open(filename) @@ -910,9 +919,13 @@ def _unpack_tarfile(filename, extract_dir): } if _BZ2_SUPPORTED: - _UNPACK_FORMATS['bztar'] = (['.bz2'], _unpack_tarfile, [], + _UNPACK_FORMATS['bztar'] = (['.tar.bz2', '.tbz2'], _unpack_tarfile, [], "bzip2'ed tar-file") +if _LZMA_SUPPORTED: + _UNPACK_FORMATS['xztar'] = (['.tar.xz', '.txz'], _unpack_tarfile, [], + "xz'ed tar-file") + def _find_unpack_format(filename): for name, info in _UNPACK_FORMATS.items(): for extension in info[0]: @@ -961,6 +974,9 @@ def unpack_archive(filename, extract_dir=None, format=None): __all__.append('disk_usage') _ntuple_diskusage = collections.namedtuple('usage', 'total used free') + _ntuple_diskusage.total.__doc__ = 'Total space in bytes' + _ntuple_diskusage.used.__doc__ = 'Used space in bytes' + _ntuple_diskusage.free.__doc__ = 'Free space in bytes' def disk_usage(path): """Return disk usage statistics about the given path. diff --git a/Lib/signal.py b/Lib/signal.py new file mode 100644 index 000000000000..371d7128f851 --- /dev/null +++ b/Lib/signal.py @@ -0,0 +1,79 @@ +import _signal +from _signal import * +from functools import wraps as _wraps +from enum import IntEnum as _IntEnum + +_globals = globals() + +_IntEnum._convert( + 'Signals', __name__, + lambda name: + name.isupper() + and (name.startswith('SIG') and not name.startswith('SIG_')) + or name.startswith('CTRL_')) + +_IntEnum._convert( + 'Handlers', __name__, + lambda name: name in ('SIG_DFL', 'SIG_IGN')) + +if 'pthread_sigmask' in _globals: + _IntEnum._convert( + 'Sigmasks', __name__, + lambda name: name in ('SIG_BLOCK', 'SIG_UNBLOCK', 'SIG_SETMASK')) + + +def _int_to_enum(value, enum_klass): + """Convert a numeric value to an IntEnum member. + If it's not a known member, return the numeric value itself. + """ + try: + return enum_klass(value) + except ValueError: + return value + + +def _enum_to_int(value): + """Convert an IntEnum member to a numeric value. + If it's not a IntEnum member return the value itself. + """ + try: + return int(value) + except (ValueError, TypeError): + return value + + +@_wraps(_signal.signal) +def signal(signalnum, handler): + handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler)) + return _int_to_enum(handler, Handlers) + + +@_wraps(_signal.getsignal) +def getsignal(signalnum): + handler = _signal.getsignal(signalnum) + return _int_to_enum(handler, Handlers) + + +if 'pthread_sigmask' in _globals: + @_wraps(_signal.pthread_sigmask) + def pthread_sigmask(how, mask): + sigs_set = _signal.pthread_sigmask(how, mask) + return set(_int_to_enum(x, Signals) for x in sigs_set) + pthread_sigmask.__doc__ = _signal.pthread_sigmask.__doc__ + + +if 'sigpending' in _globals: + @_wraps(_signal.sigpending) + def sigpending(): + sigs = _signal.sigpending() + return set(_int_to_enum(x, Signals) for x in sigs) + + +if 'sigwait' in _globals: + @_wraps(_signal.sigwait) + def sigwait(sigset): + retsig = _signal.sigwait(sigset) + return _int_to_enum(retsig, Signals) + sigwait.__doc__ = _signal.sigwait + +del _globals, _wraps diff --git a/Lib/site-packages/README.txt b/Lib/site-packages/README.txt new file mode 100644 index 000000000000..273f6251a7f9 --- /dev/null +++ b/Lib/site-packages/README.txt @@ -0,0 +1,2 @@ +This directory exists so that 3rd party packages can be installed +here. Read the source for site.py for more details. diff --git a/Lib/site.py b/Lib/site.py index b0d8268f8165..3a8d1c372837 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -7,7 +7,7 @@ This will append site-specific paths to the module search path. On Unix (including Mac OSX), it starts with sys.prefix and sys.exec_prefix (if different) and appends -lib/python/site-packages as well as lib/site-python. +lib/python/site-packages. On other platforms (such as Windows), it tries each of the prefixes directly, as well as with lib/site-packages appended. The resulting directories, if they exist, are appended to sys.path, and @@ -15,7 +15,7 @@ If a file named "pyvenv.cfg" exists one directory above sys.executable, sys.prefix and sys.exec_prefix are set to that directory and -it is also checked for site-packages and site-python (sys.base_prefix and +it is also checked for site-packages (sys.base_prefix and sys.base_exec_prefix will always be the "real" prefixes of the Python installation). If "pyvenv.cfg" (a bootstrap configuration file) contains the key "include-system-site-packages" set to anything other than "false" @@ -98,8 +98,8 @@ def makepath(*paths): def abs_paths(): """Set all module __file__ and __cached__ attributes to an absolute path""" for m in set(sys.modules.values()): - if (getattr(getattr(m, '__loader__', None), '__module__', None) != - '_frozen_importlib'): + if (getattr(getattr(m, '__loader__', None), '__module__', None) not in + ('_frozen_importlib', '_frozen_importlib_external')): continue # don't mess with a PEP 302-supplied __file__ try: m.__file__ = os.path.abspath(m.__file__) @@ -285,8 +285,7 @@ def addusersitepackages(known_paths): return known_paths def getsitepackages(prefixes=None): - """Returns a list containing all global site-packages directories - (and possibly site-python). + """Returns a list containing all global site-packages directories. For each directory present in ``prefixes`` (or the global ``PREFIXES``), this function will find its `site-packages` subdirectory depending on the @@ -307,7 +306,6 @@ def getsitepackages(prefixes=None): sitepackages.append(os.path.join(prefix, "lib", "python" + sys.version[:3], "site-packages")) - sitepackages.append(os.path.join(prefix, "lib", "site-python")) else: sitepackages.append(prefix) sitepackages.append(os.path.join(prefix, "lib", "site-packages")) @@ -323,14 +321,9 @@ def getsitepackages(prefixes=None): return sitepackages def addsitepackages(known_paths, prefixes=None): - """Add site-packages (and possibly site-python) to sys.path""" + """Add site-packages to sys.path""" for sitedir in getsitepackages(prefixes): if os.path.isdir(sitedir): - if "site-python" in sitedir: - import warnings - warnings.warn('"site-python" directories will not be ' - 'supported in 3.5 anymore', - DeprecationWarning) addsitedir(sitedir, known_paths) return known_paths @@ -364,12 +357,17 @@ def setcopyright(): builtins.credits = _sitebuiltins._Printer("credits", """\ Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands for supporting Python development. See www.python.org for more information.""") - here = os.path.dirname(os.__file__) + files, dirs = [], [] + # Not all modules are required to have a __file__ attribute. See + # PEP 420 for more details. + if hasattr(os, '__file__'): + here = os.path.dirname(os.__file__) + files.extend(["LICENSE.txt", "LICENSE"]) + dirs.extend([os.path.join(here, os.pardir), here, os.curdir]) builtins.license = _sitebuiltins._Printer( "license", - "See http://www.python.org/download/releases/%.5s/license" % sys.version, - ["LICENSE.txt", "LICENSE"], - [os.path.join(here, os.pardir), here, os.curdir]) + "See https://www.python.org/psf/license/", + files, dirs) def sethelper(): @@ -409,7 +407,7 @@ def register_readline(): # want to ignore the exception. pass - if readline.get_history_item(1) is None: + if readline.get_current_history_length() == 0: # If no history was loaded, default to .python_history. # The guard is necessary to avoid doubling history size at # each interpreter exit when readline was already configured @@ -467,7 +465,9 @@ def venv(known_paths): config_line = re.compile(CONFIG_LINE) virtual_conf = candidate_confs[0] system_site = "true" - with open(virtual_conf) as f: + # Issue 25185: Use UTF-8, as that's what the venv module uses when + # writing the file. + with open(virtual_conf, encoding='utf-8') as f: for line in f: line = line.strip() m = config_line.match(line) @@ -478,6 +478,12 @@ def venv(known_paths): system_site = value.lower() elif key == 'home': sys._home = value + elif key == 'applocal' and value.lower() == 'true': + # App-local installs use the exe_dir as prefix, + # not one level higher, and do not use system + # site packages. + site_prefix = exe_dir + system_site = 'false' sys.prefix = sys.exec_prefix = site_prefix diff --git a/Lib/smtpd.py b/Lib/smtpd.py index 1fa157ade7cc..732066ef9a5a 100755 --- a/Lib/smtpd.py +++ b/Lib/smtpd.py @@ -1,5 +1,5 @@ #! /usr/bin/env python3 -"""An RFC 5321 smtp proxy. +"""An RFC 5321 smtp proxy with optional RFC 1870 and RFC 6531 extensions. Usage: %(program)s [options] [localhost:localport [remotehost:remoteport]] @@ -25,6 +25,10 @@ Restrict the total size of the incoming message to "limit" number of bytes via the RFC 1870 SIZE extension. Defaults to 33554432 bytes. + --smtputf8 + -u + Enable the SMTPUTF8 extension and behave as an RFC 6531 smtp proxy. + --debug -d Turn on debugging prints. @@ -98,7 +102,6 @@ def flush(self): pass DEBUGSTREAM = Devnull() NEWLINE = '\n' -EMPTYSTRING = '' COMMASPACE = ', ' DATA_SIZE_DEFAULT = 33554432 @@ -116,26 +119,48 @@ class SMTPChannel(asynchat.async_chat): command_size_limit = 512 command_size_limits = collections.defaultdict(lambda x=command_size_limit: x) - command_size_limits.update({ - 'MAIL': command_size_limit + 26, - }) - max_command_size_limit = max(command_size_limits.values()) + + @property + def max_command_size_limit(self): + try: + return max(self.command_size_limits.values()) + except ValueError: + return self.command_size_limit def __init__(self, server, conn, addr, data_size_limit=DATA_SIZE_DEFAULT, - map=None): + map=None, enable_SMTPUTF8=False, decode_data=None): asynchat.async_chat.__init__(self, conn, map=map) self.smtp_server = server self.conn = conn self.addr = addr self.data_size_limit = data_size_limit - self.received_lines = [] - self.smtp_state = self.COMMAND + self.enable_SMTPUTF8 = enable_SMTPUTF8 + if enable_SMTPUTF8: + if decode_data: + raise ValueError("decode_data and enable_SMTPUTF8 cannot" + " be set to True at the same time") + decode_data = False + if decode_data is None: + warn("The decode_data default of True will change to False in 3.6;" + " specify an explicit value for this keyword", + DeprecationWarning, 2) + decode_data = True + self._decode_data = decode_data + if decode_data: + self._emptystring = '' + self._linesep = '\r\n' + self._dotsep = '.' + self._newline = NEWLINE + else: + self._emptystring = b'' + self._linesep = b'\r\n' + self._dotsep = ord(b'.') + self._newline = b'\n' + self._set_rset_state() self.seen_greeting = '' - self.mailfrom = None - self.rcpttos = [] - self.received_data = '' + self.extended_smtp = False + self.command_size_limits.clear() self.fqdn = socket.getfqdn() - self.num_bytes = 0 try: self.peer = conn.getpeername() except OSError as err: @@ -147,8 +172,22 @@ def __init__(self, server, conn, addr, data_size_limit=DATA_SIZE_DEFAULT, return print('Peer:', repr(self.peer), file=DEBUGSTREAM) self.push('220 %s %s' % (self.fqdn, __version__)) + + def _set_post_data_state(self): + """Reset state variables to their post-DATA state.""" + self.smtp_state = self.COMMAND + self.mailfrom = None + self.rcpttos = [] + self.require_SMTPUTF8 = False + self.num_bytes = 0 self.set_terminator(b'\r\n') - self.extended_smtp = False + + def _set_rset_state(self): + """Reset all state variables except the greeting.""" + self._set_post_data_state() + self.received_data = '' + self.received_lines = [] + # properties for backwards-compatibility @property @@ -272,9 +311,10 @@ def __addr(self, value): "set 'addr' instead", DeprecationWarning, 2) self.addr = value - # Overrides base class for convenience + # Overrides base class for convenience. def push(self, msg): - asynchat.async_chat.push(self, bytes(msg + '\r\n', 'ascii')) + asynchat.async_chat.push(self, bytes( + msg + '\r\n', 'utf-8' if self.require_SMTPUTF8 else 'ascii')) # Implementation of base class abstract method def collect_incoming_data(self, data): @@ -287,11 +327,14 @@ def collect_incoming_data(self, data): return elif limit: self.num_bytes += len(data) - self.received_lines.append(str(data, "utf-8")) + if self._decode_data: + self.received_lines.append(str(data, 'utf-8')) + else: + self.received_lines.append(data) # Implementation of base class abstract method def found_terminator(self): - line = EMPTYSTRING.join(self.received_lines) + line = self._emptystring.join(self.received_lines) print('Data:', repr(line), file=DEBUGSTREAM) self.received_lines = [] if self.smtp_state == self.COMMAND: @@ -299,7 +342,8 @@ def found_terminator(self): if not line: self.push('500 Error: bad syntax') return - method = None + if not self._decode_data: + line = str(line, 'utf-8') i = line.find(' ') if i < 0: command = line.upper() @@ -330,21 +374,21 @@ def found_terminator(self): # Remove extraneous carriage returns and de-transparency according # to RFC 5321, Section 4.5.2. data = [] - for text in line.split('\r\n'): - if text and text[0] == '.': + for text in line.split(self._linesep): + if text and text[0] == self._dotsep: data.append(text[1:]) else: data.append(text) - self.received_data = NEWLINE.join(data) - status = self.smtp_server.process_message(self.peer, - self.mailfrom, - self.rcpttos, - self.received_data) - self.rcpttos = [] - self.mailfrom = None - self.smtp_state = self.COMMAND - self.num_bytes = 0 - self.set_terminator(b'\r\n') + self.received_data = self._newline.join(data) + args = (self.peer, self.mailfrom, self.rcpttos, self.received_data) + kwargs = {} + if not self._decode_data: + kwargs = { + 'mail_options': self.mail_options, + 'rcpt_options': self.rcpt_options, + } + status = self.smtp_server.process_message(*args, **kwargs) + self._set_post_data_state() if not status: self.push('250 OK') else: @@ -355,26 +399,35 @@ def smtp_HELO(self, arg): if not arg: self.push('501 Syntax: HELO hostname') return + # See issue #21783 for a discussion of this behavior. if self.seen_greeting: self.push('503 Duplicate HELO/EHLO') - else: - self.seen_greeting = arg - self.extended_smtp = False - self.push('250 %s' % self.fqdn) + return + self._set_rset_state() + self.seen_greeting = arg + self.push('250 %s' % self.fqdn) def smtp_EHLO(self, arg): if not arg: self.push('501 Syntax: EHLO hostname') return + # See issue #21783 for a discussion of this behavior. if self.seen_greeting: self.push('503 Duplicate HELO/EHLO') - else: - self.seen_greeting = arg - self.extended_smtp = True - self.push('250-%s' % self.fqdn) - if self.data_size_limit: - self.push('250-SIZE %s' % self.data_size_limit) - self.push('250 HELP') + return + self._set_rset_state() + self.seen_greeting = arg + self.extended_smtp = True + self.push('250-%s' % self.fqdn) + if self.data_size_limit: + self.push('250-SIZE %s' % self.data_size_limit) + self.command_size_limits['MAIL'] += 26 + if not self._decode_data: + self.push('250-8BITMIME') + if self.enable_SMTPUTF8: + self.push('250-SMTPUTF8') + self.command_size_limits['MAIL'] += 10 + self.push('250 HELP') def smtp_NOOP(self, arg): if arg: @@ -405,15 +458,19 @@ def _getaddr(self, arg): return address.addr_spec, rest def _getparams(self, params): - # Return any parameters that appear to be syntactically valid according - # to RFC 1869, ignore all others. (Postel rule: accept what we can.) - params = [param.split('=', 1) for param in params.split() - if '=' in param] - return {k: v for k, v in params if k.isalnum()} + # Return params as dictionary. Return None if not all parameters + # appear to be syntactically valid according to RFC 1869. + result = {} + for param in params: + param, eq, value = param.partition('=') + if not param.isalnum() or eq and not value: + return None + result[param] = value if eq else True + return result def smtp_HELP(self, arg): if arg: - extended = ' [SP MAIL', arg, file=DEBUGSTREAM) syntaxerr = '501 Syntax: MAIL FROM:
' @@ -476,16 +533,26 @@ def smtp_MAIL(self, arg): if not self.extended_smtp and params: self.push(syntaxerr) return - if not address: - self.push(syntaxerr) - return if self.mailfrom: self.push('503 Error: nested MAIL command') return - params = self._getparams(params.upper()) + self.mail_options = params.upper().split() + params = self._getparams(self.mail_options) if params is None: self.push(syntaxerr) return + if not self._decode_data: + body = params.pop('BODY', '7BIT') + if body not in ['7BIT', '8BITMIME']: + self.push('501 Error: BODY can only be one of 7BIT, 8BITMIME') + return + if self.enable_SMTPUTF8: + smtputf8 = params.pop('SMTPUTF8', False) + if smtputf8 is True: + self.require_SMTPUTF8 = True + elif smtputf8 is not False: + self.push('501 Error: SMTPUTF8 takes no arguments') + return size = params.pop('SIZE', None) if size: if not size.isdigit(): @@ -520,23 +587,17 @@ def smtp_RCPT(self, arg): if not address: self.push(syntaxerr) return - if params: - if self.extended_smtp: - params = self._getparams(params.upper()) - if params is None: - self.push(syntaxerr) - return - else: - self.push(syntaxerr) - return - if not address: + if not self.extended_smtp and params: self.push(syntaxerr) return - if params and len(params.keys()) > 0: - self.push('555 RCPT TO parameters not recognized or not implemented') + self.rcpt_options = params.upper().split() + params = self._getparams(self.rcpt_options) + if params is None: + self.push(syntaxerr) return - if not address: - self.push('501 Syntax: RCPT TO:
') + # XXX currently there are no options we recognize. + if len(params.keys()) > 0: + self.push('555 RCPT TO parameters not recognized or not implemented') return self.rcpttos.append(address) print('recips:', self.rcpttos, file=DEBUGSTREAM) @@ -546,11 +607,7 @@ def smtp_RSET(self, arg): if arg: self.push('501 Syntax: RSET') return - # Resets the sender, recipients, and data, but not the greeting - self.mailfrom = None - self.rcpttos = [] - self.received_data = '' - self.smtp_state = self.COMMAND + self._set_rset_state() self.push('250 OK') def smtp_DATA(self, arg): @@ -577,13 +634,29 @@ class SMTPServer(asyncore.dispatcher): channel_class = SMTPChannel def __init__(self, localaddr, remoteaddr, - data_size_limit=DATA_SIZE_DEFAULT, map=None): + data_size_limit=DATA_SIZE_DEFAULT, map=None, + enable_SMTPUTF8=False, decode_data=None): self._localaddr = localaddr self._remoteaddr = remoteaddr self.data_size_limit = data_size_limit + self.enable_SMTPUTF8 = enable_SMTPUTF8 + if enable_SMTPUTF8: + if decode_data: + raise ValueError("The decode_data and enable_SMTPUTF8" + " parameters cannot be set to True at the" + " same time.") + decode_data = False + if decode_data is None: + warn("The decode_data default of True will change to False in 3.6;" + " specify an explicit value for this keyword", + DeprecationWarning, 2) + decode_data = True + self._decode_data = decode_data asyncore.dispatcher.__init__(self, map=map) try: - self.create_socket(socket.AF_INET, socket.SOCK_STREAM) + gai_results = socket.getaddrinfo(*localaddr, + type=socket.SOCK_STREAM) + self.create_socket(gai_results[0][0], gai_results[0][1]) # try to re-use a server port if possible self.set_reuse_addr() self.bind(localaddr) @@ -598,11 +671,16 @@ def __init__(self, localaddr, remoteaddr, def handle_accepted(self, conn, addr): print('Incoming connection from %s' % repr(addr), file=DEBUGSTREAM) - channel = self.channel_class(self, conn, addr, self.data_size_limit, - self._map) + channel = self.channel_class(self, + conn, + addr, + self.data_size_limit, + self._map, + self.enable_SMTPUTF8, + self._decode_data) # API for "doing something useful with the message" - def process_message(self, peer, mailfrom, rcpttos, data): + def process_message(self, peer, mailfrom, rcpttos, data, **kwargs): """Override this abstract method to handle messages from the client. peer is a tuple containing (ipaddr, port) of the client that made the @@ -620,29 +698,58 @@ def process_message(self, peer, mailfrom, rcpttos, data): containing a `.' followed by other text has had the leading dot removed. - This function should return None, for a normal `250 Ok' response; - otherwise it returns the desired response string in RFC 821 format. + kwargs is a dictionary containing additional information. It is empty + unless decode_data=False or enable_SMTPUTF8=True was given as init + parameter, in which case ut will contain the following keys: + 'mail_options': list of parameters to the mail command. All + elements are uppercase strings. Example: + ['BODY=8BITMIME', 'SMTPUTF8']. + 'rcpt_options': same, for the rcpt command. + + This function should return None for a normal `250 Ok' response; + otherwise, it should return the desired response string in RFC 821 + format. """ raise NotImplementedError class DebuggingServer(SMTPServer): - # Do something with the gathered message - def process_message(self, peer, mailfrom, rcpttos, data): + + def _print_message_content(self, peer, data): inheaders = 1 - lines = data.split('\n') - print('---------- MESSAGE FOLLOWS ----------') + lines = data.splitlines() for line in lines: # headers first if inheaders and not line: - print('X-Peer:', peer[0]) + peerheader = 'X-Peer: ' + peer[0] + if not isinstance(data, str): + # decoded_data=false; make header match other binary output + peerheader = repr(peerheader.encode('utf-8')) + print(peerheader) inheaders = 0 + if not isinstance(data, str): + # Avoid spurious 'str on bytes instance' warning. + line = repr(line) print(line) + + def process_message(self, peer, mailfrom, rcpttos, data, **kwargs): + print('---------- MESSAGE FOLLOWS ----------') + if kwargs: + if kwargs.get('mail_options'): + print('mail options: %s' % kwargs['mail_options']) + if kwargs.get('rcpt_options'): + print('rcpt options: %s\n' % kwargs['rcpt_options']) + self._print_message_content(peer, data) print('------------ END MESSAGE ------------') class PureProxy(SMTPServer): + def __init__(self, *args, **kwargs): + if 'enable_SMTPUTF8' in kwargs and kwargs['enable_SMTPUTF8']: + raise ValueError("PureProxy does not support SMTPUTF8.") + super(PureProxy, self).__init__(*args, **kwargs) + def process_message(self, peer, mailfrom, rcpttos, data): lines = data.split('\n') # Look for the last header @@ -683,6 +790,11 @@ def _deliver(self, mailfrom, rcpttos, data): class MailmanProxy(PureProxy): + def __init__(self, *args, **kwargs): + if 'enable_SMTPUTF8' in kwargs and kwargs['enable_SMTPUTF8']: + raise ValueError("MailmanProxy does not support SMTPUTF8.") + super(PureProxy, self).__init__(*args, **kwargs) + def process_message(self, peer, mailfrom, rcpttos, data): from io import StringIO from Mailman import Utils @@ -761,17 +873,19 @@ def process_message(self, peer, mailfrom, rcpttos, data): class Options: - setuid = 1 + setuid = True classname = 'PureProxy' size_limit = None + enable_SMTPUTF8 = False def parseargs(): global DEBUGSTREAM try: opts, args = getopt.getopt( - sys.argv[1:], 'nVhc:s:d', - ['class=', 'nosetuid', 'version', 'help', 'size=', 'debug']) + sys.argv[1:], 'nVhc:s:du', + ['class=', 'nosetuid', 'version', 'help', 'size=', 'debug', + 'smtputf8']) except getopt.error as e: usage(1, e) @@ -783,11 +897,13 @@ def parseargs(): print(__version__) sys.exit(0) elif opt in ('-n', '--nosetuid'): - options.setuid = 0 + options.setuid = False elif opt in ('-c', '--class'): options.classname = arg elif opt in ('-d', '--debug'): DEBUGSTREAM = sys.stderr + elif opt in ('-u', '--smtputf8'): + options.enable_SMTPUTF8 = True elif opt in ('-s', '--size'): try: int_size = int(arg) @@ -842,7 +958,7 @@ def parseargs(): class_ = getattr(mod, classname) proxy = class_((options.localhost, options.localport), (options.remotehost, options.remoteport), - options.size_limit) + options.size_limit, enable_SMTPUTF8=options.enable_SMTPUTF8) if options.setuid: try: import pwd diff --git a/Lib/smtplib.py b/Lib/smtplib.py old mode 100644 new mode 100755 index 6fc65f6b6a3a..4fe6aaf8e12b --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -50,8 +50,9 @@ import base64 import hmac import copy +import datetime +import sys from email.base64mime import body_encode as encode_base64 -from sys import stderr __all__ = ["SMTPException", "SMTPServerDisconnected", "SMTPResponseException", "SMTPSenderRefused", "SMTPRecipientsRefused", "SMTPDataError", @@ -62,6 +63,7 @@ SMTP_SSL_PORT = 465 CRLF = "\r\n" bCRLF = b"\r\n" +_MAXLINE = 8192 # more than 8 times larger than RFC 821, 4.5.3 OLDSTYLE_AUTH = re.compile(r"auth=(.*)", re.I) @@ -69,6 +71,13 @@ class SMTPException(OSError): """Base class for all exceptions raised by this module.""" +class SMTPNotSupportedError(SMTPException): + """The command or option is not supported by the SMTP server. + + This exception is raised when an attempt is made to run a command or a + command with an option which is not supported by the server. + """ + class SMTPServerDisconnected(SMTPException): """Not connected to any SMTP server. @@ -232,8 +241,10 @@ def __init__(self, host='', port=0, local_hostname=None, will be used. """ + self._host = host self.timeout = timeout self.esmtp_features = {} + self.command_encoding = 'ascii' self.source_address = source_address if host: @@ -280,12 +291,17 @@ def set_debuglevel(self, debuglevel): """ self.debuglevel = debuglevel + def _print_debug(self, *args): + if self.debuglevel > 1: + print(datetime.datetime.now().time(), *args, file=sys.stderr) + else: + print(*args, file=sys.stderr) + def _get_socket(self, host, port, timeout): # This makes it simpler for SMTP_SSL to use the SMTP connect code # and just alter the socket connection bit. if self.debuglevel > 0: - print('connect: to', (host, port), self.source_address, - file=stderr) + self._print_debug('connect: to', (host, port), self.source_address) return socket.create_connection((host, port), timeout, self.source_address) @@ -315,21 +331,24 @@ def connect(self, host='localhost', port=0, source_address=None): if not port: port = self.default_port if self.debuglevel > 0: - print('connect:', (host, port), file=stderr) + self._print_debug('connect:', (host, port)) self.sock = self._get_socket(host, port, self.timeout) self.file = None (code, msg) = self.getreply() if self.debuglevel > 0: - print("connect:", msg, file=stderr) + self._print_debug('connect:', repr(msg)) return (code, msg) def send(self, s): """Send `s' to the server.""" if self.debuglevel > 0: - print('send:', repr(s), file=stderr) + self._print_debug('send:', repr(s)) if hasattr(self, 'sock') and self.sock: if isinstance(s, str): - s = s.encode("ascii") + # send is used by the 'data' command, where command_encoding + # should not be used, but 'data' needs to convert the string to + # binary itself anyway, so that's not a problem. + s = s.encode(self.command_encoding) try: self.sock.sendall(s) except OSError: @@ -364,7 +383,7 @@ def getreply(self): self.file = self.sock.makefile('rb') while 1: try: - line = self.file.readline() + line = self.file.readline(_MAXLINE + 1) except OSError as e: self.close() raise SMTPServerDisconnected("Connection unexpectedly closed: " @@ -373,7 +392,10 @@ def getreply(self): self.close() raise SMTPServerDisconnected("Connection unexpectedly closed") if self.debuglevel > 0: - print('reply:', repr(line), file=stderr) + self._print_debug('reply:', repr(line)) + if len(line) > _MAXLINE: + self.close() + raise SMTPResponseException(500, "Line too long.") resp.append(line[4:].strip(b' \t\r\n')) code = line[:3] # Check that the error code is syntactically correct. @@ -389,8 +411,7 @@ def getreply(self): errmsg = b"\n".join(resp) if self.debuglevel > 0: - print('reply: retcode (%s); Msg: %s' % (errcode, errmsg), - file=stderr) + self._print_debug('reply: retcode (%s); Msg: %a' % (errcode, errmsg)) return errcode, errmsg def docmd(self, cmd, args=""): @@ -472,16 +493,42 @@ def help(self, args=''): def rset(self): """SMTP 'rset' command -- resets session.""" + self.command_encoding = 'ascii' return self.docmd("rset") + def _rset(self): + """Internal 'rset' command which ignores any SMTPServerDisconnected error. + + Used internally in the library, since the server disconnected error + should appear to the application when the *next* command is issued, if + we are doing an internal "safety" reset. + """ + try: + self.rset() + except SMTPServerDisconnected: + pass + def noop(self): """SMTP 'noop' command -- doesn't do anything :>""" return self.docmd("noop") def mail(self, sender, options=[]): - """SMTP 'mail' command -- begins mail xfer session.""" + """SMTP 'mail' command -- begins mail xfer session. + + This method may raise the following exceptions: + + SMTPNotSupportedError The options parameter includes 'SMTPUTF8' + but the SMTPUTF8 extension is not supported by + the server. + """ optionlist = '' if options and self.does_esmtp: + if any(x.lower()=='smtputf8' for x in options): + if self.has_extn('smtputf8'): + self.command_encoding = 'utf-8' + else: + raise SMTPNotSupportedError( + 'SMTPUTF8 not supported by server') optionlist = ' ' + ' '.join(options) self.putcmd("mail", "FROM:%s%s" % (quoteaddr(sender), optionlist)) return self.getreply() @@ -501,13 +548,13 @@ def data(self, msg): Raises SMTPDataError if there is an unexpected reply to the DATA command; the return value from this method is the final response code received when the all data is sent. If msg - is a string, lone '\r' and '\n' characters are converted to - '\r\n' characters. If msg is bytes, it is transmitted as is. + is a string, lone '\\r' and '\\n' characters are converted to + '\\r\\n' characters. If msg is bytes, it is transmitted as is. """ self.putcmd("data") (code, repl) = self.getreply() if self.debuglevel > 0: - print("data:", (code, repl), file=stderr) + self._print_debug('data:', (code, repl)) if code != 354: raise SMTPDataError(code, repl) else: @@ -520,7 +567,7 @@ def data(self, msg): self.send(q) (code, msg) = self.getreply() if self.debuglevel > 0: - print("data:", (code, msg), file=stderr) + self._print_debug('data:', (code, msg)) return (code, msg) def verify(self, address): @@ -554,12 +601,78 @@ def ehlo_or_helo_if_needed(self): if not (200 <= code <= 299): raise SMTPHeloError(code, resp) - def login(self, user, password): + def auth(self, mechanism, authobject, *, initial_response_ok=True): + """Authentication command - requires response processing. + + 'mechanism' specifies which authentication mechanism is to + be used - the valid values are those listed in the 'auth' + element of 'esmtp_features'. + + 'authobject' must be a callable object taking a single argument: + + data = authobject(challenge) + + It will be called to process the server's challenge response; the + challenge argument it is passed will be a bytes. It should return + bytes data that will be base64 encoded and sent to the server. + + Keyword arguments: + - initial_response_ok: Allow sending the RFC 4954 initial-response + to the AUTH command, if the authentication methods supports it. + """ + # RFC 4954 allows auth methods to provide an initial response. Not all + # methods support it. By definition, if they return something other + # than None when challenge is None, then they do. See issue #15014. + mechanism = mechanism.upper() + initial_response = (authobject() if initial_response_ok else None) + if initial_response is not None: + response = encode_base64(initial_response.encode('ascii'), eol='') + (code, resp) = self.docmd("AUTH", mechanism + " " + response) + else: + (code, resp) = self.docmd("AUTH", mechanism) + # Server replies with 334 (challenge) or 535 (not supported) + if code == 334: + challenge = base64.decodebytes(resp) + response = encode_base64( + authobject(challenge).encode('ascii'), eol='') + (code, resp) = self.docmd(response) + if code in (235, 503): + return (code, resp) + raise SMTPAuthenticationError(code, resp) + + def auth_cram_md5(self, challenge=None): + """ Authobject to use with CRAM-MD5 authentication. Requires self.user + and self.password to be set.""" + # CRAM-MD5 does not support initial-response. + if challenge is None: + return None + return self.user + " " + hmac.HMAC( + self.password.encode('ascii'), challenge, 'md5').hexdigest() + + def auth_plain(self, challenge=None): + """ Authobject to use with PLAIN authentication. Requires self.user and + self.password to be set.""" + return "\0%s\0%s" % (self.user, self.password) + + def auth_login(self, challenge=None): + """ Authobject to use with LOGIN authentication. Requires self.user and + self.password to be set.""" + (code, resp) = self.docmd( + encode_base64(self.user.encode('ascii'), eol='')) + if code == 334: + return self.password + raise SMTPAuthenticationError(code, resp) + + def login(self, user, password, *, initial_response_ok=True): """Log in on an SMTP server that requires authentication. The arguments are: - - user: The user name to authenticate with. - - password: The password for the authentication. + - user: The user name to authenticate with. + - password: The password for the authentication. + + Keyword arguments: + - initial_response_ok: Allow sending the RFC 4954 initial-response + to the AUTH command, if the authentication methods supports it. If there has been no previous EHLO or HELO command this session, this method tries ESMTP EHLO first. @@ -572,67 +685,49 @@ def login(self, user, password): the helo greeting. SMTPAuthenticationError The server didn't accept the username/ password combination. + SMTPNotSupportedError The AUTH command is not supported by the + server. SMTPException No suitable authentication method was found. """ - def encode_cram_md5(challenge, user, password): - challenge = base64.decodebytes(challenge) - response = user + " " + hmac.HMAC(password.encode('ascii'), - challenge, 'md5').hexdigest() - return encode_base64(response.encode('ascii'), eol='') - - def encode_plain(user, password): - s = "\0%s\0%s" % (user, password) - return encode_base64(s.encode('ascii'), eol='') - - AUTH_PLAIN = "PLAIN" - AUTH_CRAM_MD5 = "CRAM-MD5" - AUTH_LOGIN = "LOGIN" - self.ehlo_or_helo_if_needed() - if not self.has_extn("auth"): - raise SMTPException("SMTP AUTH extension not supported by server.") + raise SMTPNotSupportedError( + "SMTP AUTH extension not supported by server.") # Authentication methods the server claims to support advertised_authlist = self.esmtp_features["auth"].split() - # List of authentication methods we support: from preferred to - # less preferred methods. Except for the purpose of testing the weaker - # ones, we prefer stronger methods like CRAM-MD5: - preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN] + # Authentication methods we can handle in our preferred order: + preferred_auths = ['CRAM-MD5', 'PLAIN', 'LOGIN'] - # We try the authentication methods the server advertises, but only the - # ones *we* support. And in our preferred order. - authlist = [auth for auth in preferred_auths if auth in advertised_authlist] + # We try the supported authentications in our preferred order, if + # the server supports them. + authlist = [auth for auth in preferred_auths + if auth in advertised_authlist] if not authlist: raise SMTPException("No suitable authentication method found.") # Some servers advertise authentication methods they don't really # support, so if authentication fails, we continue until we've tried # all methods. + self.user, self.password = user, password for authmethod in authlist: - if authmethod == AUTH_CRAM_MD5: - (code, resp) = self.docmd("AUTH", AUTH_CRAM_MD5) - if code == 334: - (code, resp) = self.docmd(encode_cram_md5(resp, user, password)) - elif authmethod == AUTH_PLAIN: - (code, resp) = self.docmd("AUTH", - AUTH_PLAIN + " " + encode_plain(user, password)) - elif authmethod == AUTH_LOGIN: - (code, resp) = self.docmd("AUTH", - "%s %s" % (AUTH_LOGIN, encode_base64(user.encode('ascii'), eol=''))) - if code == 334: - (code, resp) = self.docmd(encode_base64(password.encode('ascii'), eol='')) - - # 235 == 'Authentication successful' - # 503 == 'Error: already authenticated' - if code in (235, 503): - return (code, resp) - - # We could not login sucessfully. Return result of last attempt. - raise SMTPAuthenticationError(code, resp) + method_name = 'auth_' + authmethod.lower().replace('-', '_') + try: + (code, resp) = self.auth( + authmethod, getattr(self, method_name), + initial_response_ok=initial_response_ok) + # 235 == 'Authentication successful' + # 503 == 'Error: already authenticated' + if code in (235, 503): + return (code, resp) + except SMTPAuthenticationError as e: + last_exception = e + + # We could not login successfully. Return result of last attempt. + raise last_exception def starttls(self, keyfile=None, certfile=None, context=None): """Puts the connection to the SMTP server into TLS mode. @@ -653,7 +748,8 @@ def starttls(self, keyfile=None, certfile=None, context=None): """ self.ehlo_or_helo_if_needed() if not self.has_extn("starttls"): - raise SMTPException("STARTTLS extension not supported by server.") + raise SMTPNotSupportedError( + "STARTTLS extension not supported by server.") (resp, reply) = self.docmd("STARTTLS") if resp == 220: if not _have_ssl: @@ -667,7 +763,8 @@ def starttls(self, keyfile=None, certfile=None, context=None): if context is None: context = ssl._create_stdlib_context(certfile=certfile, keyfile=keyfile) - self.sock = context.wrap_socket(self.sock) + self.sock = context.wrap_socket(self.sock, + server_hostname=self._host) self.file = None # RFC 3207: # The client MUST discard any knowledge obtained from @@ -717,6 +814,9 @@ def sendmail(self, from_addr, to_addrs, msg, mail_options=[], SMTPDataError The server replied with an unexpected error code (other than a refusal of a recipient). + SMTPNotSupportedError The mail_options parameter includes 'SMTPUTF8' + but the SMTPUTF8 extension is not supported by + the server. Note: the connection will be open even after an exception is raised. @@ -745,8 +845,6 @@ def sendmail(self, from_addr, to_addrs, msg, mail_options=[], if isinstance(msg, str): msg = _fix_eols(msg).encode('ascii') if self.does_esmtp: - # Hmmm? what's this? -ddm - # self.esmtp_features['7bit']="" if self.has_extn('size'): esmtp_opts.append("size=%d" % len(msg)) for option in mail_options: @@ -756,7 +854,7 @@ def sendmail(self, from_addr, to_addrs, msg, mail_options=[], if code == 421: self.close() else: - self.rset() + self._rset() raise SMTPSenderRefused(code, resp, from_addr) senderrs = {} if isinstance(to_addrs, str): @@ -770,14 +868,14 @@ def sendmail(self, from_addr, to_addrs, msg, mail_options=[], raise SMTPRecipientsRefused(senderrs) if len(senderrs) == len(to_addrs): # the server refused all our recipients - self.rset() + self._rset() raise SMTPRecipientsRefused(senderrs) (code, resp) = self.data(msg) if code != 250: if code == 421: self.close() else: - self.rset() + self._rset() raise SMTPDataError(code, resp) #if we got here then somebody got our mail return senderrs @@ -794,7 +892,13 @@ def send_message(self, msg, from_addr=None, to_addrs=None, to_addr, any Bcc field (or Resent-Bcc field, when the Message is a resent) of the Message object won't be transmitted. The Message object is then serialized using email.generator.BytesGenerator and - sendmail is called to transmit the message. + sendmail is called to transmit the message. If the sender or any of + the recipient addresses contain non-ASCII and the server advertises the + SMTPUTF8 capability, the policy is cloned with utf8 set to True for the + serialization, and SMTPUTF8 and BODY=8BITMIME are asserted on the send. + If the server does not support SMTPUTF8, an SMPTNotSupported error is + raised. Otherwise the generator is called without modifying the + policy. """ # 'Resent-Date' is a mandatory field if the Message is resent (RFC 2822 @@ -807,6 +911,7 @@ def send_message(self, msg, from_addr=None, to_addrs=None, # option allowing the user to enable the heuristics. (It should be # possible to guess correctly almost all of the time.) + self.ehlo_or_helo_if_needed() resent = msg.get_all('Resent-Date') if resent is None: header_prefix = '' @@ -822,14 +927,30 @@ def send_message(self, msg, from_addr=None, to_addrs=None, if to_addrs is None: addr_fields = [f for f in (msg[header_prefix + 'To'], msg[header_prefix + 'Bcc'], - msg[header_prefix + 'Cc']) if f is not None] + msg[header_prefix + 'Cc']) + if f is not None] to_addrs = [a[1] for a in email.utils.getaddresses(addr_fields)] # Make a local copy so we can delete the bcc headers. msg_copy = copy.copy(msg) del msg_copy['Bcc'] del msg_copy['Resent-Bcc'] + international = False + try: + ''.join([from_addr, *to_addrs]).encode('ascii') + except UnicodeEncodeError: + if not self.has_extn('smtputf8'): + raise SMTPNotSupportedError( + "One or more source or delivery addresses require" + " internationalized email support, but the server" + " does not advertise the required SMTPUTF8 capability") + international = True with io.BytesIO() as bytesmsg: - g = email.generator.BytesGenerator(bytesmsg) + if international: + g = email.generator.BytesGenerator( + bytesmsg, policy=msg.policy.clone(utf8=True)) + mail_options += ['SMTPUTF8', 'BODY=8BITMIME'] + else: + g = email.generator.BytesGenerator(bytesmsg) g.flatten(msg_copy, linesep='\r\n') flatmsg = bytesmsg.getvalue() return self.sendmail(from_addr, to_addrs, flatmsg, mail_options, @@ -837,16 +958,24 @@ def send_message(self, msg, from_addr=None, to_addrs=None, def close(self): """Close the connection to the SMTP server.""" - if self.file: - self.file.close() - self.file = None - if self.sock: - self.sock.close() - self.sock = None + try: + file = self.file + self.file = None + if file: + file.close() + finally: + sock = self.sock + self.sock = None + if sock: + sock.close() def quit(self): """Terminate the SMTP session.""" res = self.docmd("quit") + # A new EHLO is required after reconnecting with connect() + self.ehlo_resp = self.helo_resp = None + self.esmtp_features = {} + self.does_esmtp = False self.close() return res @@ -889,10 +1018,11 @@ def __init__(self, host='', port=0, local_hostname=None, def _get_socket(self, host, port, timeout): if self.debuglevel > 0: - print('connect:', (host, port), file=stderr) + self._print_debug('connect:', (host, port)) new_socket = socket.create_connection((host, port), timeout, self.source_address) - new_socket = self.context.wrap_socket(new_socket) + new_socket = self.context.wrap_socket(new_socket, + server_hostname=self._host) return new_socket __all__.append("SMTP_SSL") @@ -936,14 +1066,14 @@ def connect(self, host='localhost', port=0, source_address=None): self.sock.connect(host) except OSError: if self.debuglevel > 0: - print('connect fail:', host, file=stderr) + self._print_debug('connect fail:', host) if self.sock: self.sock.close() self.sock = None raise (code, msg) = self.getreply() if self.debuglevel > 0: - print('connect:', msg, file=stderr) + self._print_debug('connect:', msg) return (code, msg) diff --git a/Lib/sndhdr.py b/Lib/sndhdr.py index 240e5072f8fd..7ecafb40e821 100644 --- a/Lib/sndhdr.py +++ b/Lib/sndhdr.py @@ -32,6 +32,23 @@ __all__ = ['what', 'whathdr'] +from collections import namedtuple + +SndHeaders = namedtuple('SndHeaders', + 'filetype framerate nchannels nframes sampwidth') + +SndHeaders.filetype.__doc__ = ("""The value for type indicates the data type +and will be one of the strings 'aifc', 'aiff', 'au','hcom', +'sndr', 'sndt', 'voc', 'wav', '8svx', 'sb', 'ub', or 'ul'.""") +SndHeaders.framerate.__doc__ = ("""The sampling_rate will be either the actual +value or 0 if unknown or difficult to decode.""") +SndHeaders.nchannels.__doc__ = ("""The number of channels or 0 if it cannot be +determined or if the value is difficult to decode.""") +SndHeaders.nframes.__doc__ = ("""The value for frames will be either the number +of frames or -1.""") +SndHeaders.sampwidth.__doc__ = ("""Either the sample size in bits or +'A' for A-LAW or 'U' for u-LAW.""") + def what(filename): """Guess the type of a sound file.""" res = whathdr(filename) @@ -45,7 +62,7 @@ def whathdr(filename): for tf in tests: res = tf(h, f) if res: - return res + return SndHeaders(*res) return None diff --git a/Lib/socket.py b/Lib/socket.py index 6d67b3d2824b..db34ab37ee67 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -35,11 +35,13 @@ error -- exception raised for I/O errors has_ipv6 -- boolean value indicating if IPv6 is supported -Integer constants: +IntEnum constants: AF_INET, AF_UNIX -- socket domains (first argument to socket() call) SOCK_STREAM, SOCK_DGRAM, SOCK_RAW -- socket types (second argument) +Integer constants: + Many other constants may be defined; these may be used in calls to the setsockopt() and getsockopt() methods. """ @@ -47,7 +49,7 @@ import _socket from _socket import * -import os, sys, io +import os, sys, io, selectors from enum import IntEnum try: @@ -58,7 +60,8 @@ EAGAIN = getattr(errno, 'EAGAIN', 11) EWOULDBLOCK = getattr(errno, 'EWOULDBLOCK', 11) -__all__ = ["getfqdn", "create_connection"] +__all__ = ["fromfd", "getfqdn", "create_connection", + "AddressFamily", "SocketKind"] __all__.extend(os._get_exports_list(_socket)) # Set up the socket.AF_* socket.SOCK_* constants as members of IntEnums for @@ -66,15 +69,20 @@ # Note that _socket only knows about the integer values. The public interface # in this module understands the enums and translates them back from integers # where needed (e.g. .family property of a socket object). -AddressFamily = IntEnum('AddressFamily', - {name: value for name, value in globals().items() - if name.isupper() and name.startswith('AF_')}) -globals().update(AddressFamily.__members__) -SocketType = IntEnum('SocketType', - {name: value for name, value in globals().items() - if name.isupper() and name.startswith('SOCK_')}) -globals().update(SocketType.__members__) +IntEnum._convert( + 'AddressFamily', + __name__, + lambda C: C.isupper() and C.startswith('AF_')) + +IntEnum._convert( + 'SocketKind', + __name__, + lambda C: C.isupper() and C.startswith('SOCK_')) + +_LOCALHOST = '127.0.0.1' +_LOCALHOST_V6 = '::1' + def _intenum_converter(value, enum_klass): """Convert a numeric family value to an IntEnum member. @@ -109,6 +117,9 @@ def _intenum_converter(value, enum_klass): __all__.append("errorTab") +class _GiveupOnSendfile(Exception): pass + + class socket(_socket.socket): """A subclass of _socket.socket adding the makefile() method.""" @@ -138,7 +149,7 @@ def __repr__(self): closed = getattr(self, '_closed', False) s = "<%s.%s%s fd=%i, family=%s, type=%s, proto=%i" \ % (self.__class__.__module__, - self.__class__.__name__, + self.__class__.__qualname__, " [closed]" if closed else "", self.fileno(), self.family, @@ -198,9 +209,8 @@ def makefile(self, mode="r", buffering=None, *, except the only mode characters supported are 'r', 'w' and 'b'. The semantics are similar too. (XXX refactor to share code?) """ - for c in mode: - if c not in {"r", "w", "b"}: - raise ValueError("invalid mode %r (only r, w, b allowed)") + if not set(mode) <= {"r", "w", "b"}: + raise ValueError("invalid mode %r (only r, w, b allowed)" % (mode,)) writing = "w" in mode reading = "r" in mode or not writing assert reading or writing @@ -233,6 +243,149 @@ def makefile(self, mode="r", buffering=None, *, text.mode = mode return text + if hasattr(os, 'sendfile'): + + def _sendfile_use_sendfile(self, file, offset=0, count=None): + self._check_sendfile_params(file, offset, count) + sockno = self.fileno() + try: + fileno = file.fileno() + except (AttributeError, io.UnsupportedOperation) as err: + raise _GiveupOnSendfile(err) # not a regular file + try: + fsize = os.fstat(fileno).st_size + except OSError: + raise _GiveupOnSendfile(err) # not a regular file + if not fsize: + return 0 # empty file + blocksize = fsize if not count else count + + timeout = self.gettimeout() + if timeout == 0: + raise ValueError("non-blocking sockets are not supported") + # poll/select have the advantage of not requiring any + # extra file descriptor, contrarily to epoll/kqueue + # (also, they require a single syscall). + if hasattr(selectors, 'PollSelector'): + selector = selectors.PollSelector() + else: + selector = selectors.SelectSelector() + selector.register(sockno, selectors.EVENT_WRITE) + + total_sent = 0 + # localize variable access to minimize overhead + selector_select = selector.select + os_sendfile = os.sendfile + try: + while True: + if timeout and not selector_select(timeout): + raise _socket.timeout('timed out') + if count: + blocksize = count - total_sent + if blocksize <= 0: + break + try: + sent = os_sendfile(sockno, fileno, offset, blocksize) + except BlockingIOError: + if not timeout: + # Block until the socket is ready to send some + # data; avoids hogging CPU resources. + selector_select() + continue + except OSError as err: + if total_sent == 0: + # We can get here for different reasons, the main + # one being 'file' is not a regular mmap(2)-like + # file, in which case we'll fall back on using + # plain send(). + raise _GiveupOnSendfile(err) + raise err from None + else: + if sent == 0: + break # EOF + offset += sent + total_sent += sent + return total_sent + finally: + if total_sent > 0 and hasattr(file, 'seek'): + file.seek(offset) + else: + def _sendfile_use_sendfile(self, file, offset=0, count=None): + raise _GiveupOnSendfile( + "os.sendfile() not available on this platform") + + def _sendfile_use_send(self, file, offset=0, count=None): + self._check_sendfile_params(file, offset, count) + if self.gettimeout() == 0: + raise ValueError("non-blocking sockets are not supported") + if offset: + file.seek(offset) + blocksize = min(count, 8192) if count else 8192 + total_sent = 0 + # localize variable access to minimize overhead + file_read = file.read + sock_send = self.send + try: + while True: + if count: + blocksize = min(count - total_sent, blocksize) + if blocksize <= 0: + break + data = memoryview(file_read(blocksize)) + if not data: + break # EOF + while True: + try: + sent = sock_send(data) + except BlockingIOError: + continue + else: + total_sent += sent + if sent < len(data): + data = data[sent:] + else: + break + return total_sent + finally: + if total_sent > 0 and hasattr(file, 'seek'): + file.seek(offset + total_sent) + + def _check_sendfile_params(self, file, offset, count): + if 'b' not in getattr(file, 'mode', 'b'): + raise ValueError("file should be opened in binary mode") + if not self.type & SOCK_STREAM: + raise ValueError("only SOCK_STREAM type sockets are supported") + if count is not None: + if not isinstance(count, int): + raise TypeError( + "count must be a positive integer (got {!r})".format(count)) + if count <= 0: + raise ValueError( + "count must be a positive integer (got {!r})".format(count)) + + def sendfile(self, file, offset=0, count=None): + """sendfile(file[, offset[, count]]) -> sent + + Send a file until EOF is reached by using high-performance + os.sendfile() and return the total number of bytes which + were sent. + *file* must be a regular file object opened in binary mode. + If os.sendfile() is not available (e.g. Windows) or file is + not a regular file socket.send() will be used instead. + *offset* tells from where to start reading the file. + If specified, *count* is the total number of bytes to transmit + as opposed to sending the file until EOF is reached. + File position is updated on return or also in case of error in + which case file.tell() can be used to figure out the number of + bytes which were sent. + The socket must be of SOCK_STREAM type. + Non-blocking sockets are not supported. + """ + try: + return self._sendfile_use_sendfile(file, offset, count) + except _GiveupOnSendfile: + return self._sendfile_use_send(file, offset, count) + def _decref_socketios(self): if self._io_refs > 0: self._io_refs -= 1 @@ -269,7 +422,7 @@ def family(self): def type(self): """Read-only access to the socket type. """ - return _intenum_converter(super().type, SocketType) + return _intenum_converter(super().type, SocketKind) if os.name == 'nt': def get_inheritable(self): @@ -297,10 +450,11 @@ def fromfd(fd, family, type, proto=0): def fromshare(info): """ fromshare(info) -> socket object - Create a socket object from a the bytes object returned by + Create a socket object from the bytes object returned by socket.share(pid). """ return socket(0, 0, 0, info) + __all__.append("fromshare") if hasattr(_socket, "socketpair"): @@ -322,6 +476,52 @@ def socketpair(family=None, type=SOCK_STREAM, proto=0): b = socket(family, type, proto, b.detach()) return a, b +else: + + # Origin: https://gist.github.com/4325783, by Geert Jansen. Public domain. + def socketpair(family=AF_INET, type=SOCK_STREAM, proto=0): + if family == AF_INET: + host = _LOCALHOST + elif family == AF_INET6: + host = _LOCALHOST_V6 + else: + raise ValueError("Only AF_INET and AF_INET6 socket address families " + "are supported") + if type != SOCK_STREAM: + raise ValueError("Only SOCK_STREAM socket type is supported") + if proto != 0: + raise ValueError("Only protocol zero is supported") + + # We create a connected TCP socket. Note the trick with + # setblocking(False) that prevents us from having to create a thread. + lsock = socket(family, type, proto) + try: + lsock.bind((host, 0)) + lsock.listen() + # On IPv6, ignore flow_info and scope_id + addr, port = lsock.getsockname()[:2] + csock = socket(family, type, proto) + try: + csock.setblocking(False) + try: + csock.connect((addr, port)) + except (BlockingIOError, InterruptedError): + pass + csock.setblocking(True) + ssock, _ = lsock.accept() + except: + csock.close() + raise + finally: + lsock.close() + return (ssock, csock) + +socketpair.__doc__ = """socketpair([family[, type[, proto]]]) -> (socket object, socket object) +Create a pair of socket objects from the sockets returned by the platform +socketpair() function. +The arguments are the same as for socket() except the default family is AF_UNIX +if defined on the platform; otherwise, the default is AF_INET. +""" _blocking_errnos = { EAGAIN, EWOULDBLOCK } @@ -372,8 +572,6 @@ def readinto(self, b): except timeout: self._timeout_occurred = True raise - except InterruptedError: - continue except error as e: if e.args[0] in _blocking_errnos: return None @@ -530,6 +728,6 @@ def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): for res in _socket.getaddrinfo(host, port, family, type, proto, flags): af, socktype, proto, canonname, sa = res addrlist.append((_intenum_converter(af, AddressFamily), - _intenum_converter(socktype, SocketType), + _intenum_converter(socktype, SocketKind), proto, canonname, sa)) return addrlist diff --git a/Lib/socketserver.py b/Lib/socketserver.py index e9e4e4e4add0..0ce8e8106581 100644 --- a/Lib/socketserver.py +++ b/Lib/socketserver.py @@ -94,7 +94,7 @@ class will essentially render the service "deaf" while one request is Another approach to handling multiple simultaneous requests in an environment that supports neither threads nor fork (or where these are too expensive or inappropriate for the service) is to maintain an -explicit table of partially finished requests and to use select() to +explicit table of partially finished requests and to use a selector to decide which request to work on next (or whether to handle a new incoming request). This is particularly important for stream services where each client can potentially be connected for a long time (if @@ -104,7 +104,6 @@ class will essentially render the service "deaf" while one request is - Standard classes for Sun RPC (which uses either UDP or TCP) - Standard mix-in classes to implement various authentication and encryption schemes -- Standard framework for select-based multiplexing XXX Open problems: - What to do with out-of-band data? @@ -130,32 +129,31 @@ class will essentially render the service "deaf" while one request is import socket -import select -import sys +import selectors import os import errno try: import threading except ImportError: import dummy_threading as threading +from time import monotonic as time -__all__ = ["TCPServer","UDPServer","ForkingUDPServer","ForkingTCPServer", - "ThreadingUDPServer","ThreadingTCPServer","BaseRequestHandler", - "StreamRequestHandler","DatagramRequestHandler", - "ThreadingMixIn", "ForkingMixIn"] +__all__ = ["BaseServer", "TCPServer", "UDPServer", "ForkingUDPServer", + "ForkingTCPServer", "ThreadingUDPServer", "ThreadingTCPServer", + "BaseRequestHandler", "StreamRequestHandler", + "DatagramRequestHandler", "ThreadingMixIn", "ForkingMixIn"] if hasattr(socket, "AF_UNIX"): __all__.extend(["UnixStreamServer","UnixDatagramServer", "ThreadingUnixStreamServer", "ThreadingUnixDatagramServer"]) -def _eintr_retry(func, *args): - """restart a system call interrupted by EINTR""" - while True: - try: - return func(*args) - except OSError as e: - if e.errno != errno.EINTR: - raise +# poll/select have the advantage of not requiring any extra file descriptor, +# contrarily to epoll/kqueue (also, they require a single syscall). +if hasattr(selectors, 'PollSelector'): + _ServerSelector = selectors.PollSelector +else: + _ServerSelector = selectors.SelectSelector + class BaseServer: @@ -167,7 +165,7 @@ class BaseServer: - serve_forever(poll_interval=0.5) - shutdown() - handle_request() # if you do not use serve_forever() - - fileno() -> int # for select() + - fileno() -> int # for selector Methods that may be overridden: @@ -228,17 +226,19 @@ def serve_forever(self, poll_interval=0.5): """ self.__is_shut_down.clear() try: - while not self.__shutdown_request: - # XXX: Consider using another file descriptor or - # connecting to the socket to wake this up instead of - # polling. Polling reduces our responsiveness to a - # shutdown request and wastes cpu at all other times. - r, w, e = _eintr_retry(select.select, [self], [], [], - poll_interval) - if self in r: - self._handle_request_noblock() - - self.service_actions() + # XXX: Consider using another file descriptor or connecting to the + # socket to wake this up instead of polling. Polling reduces our + # responsiveness to a shutdown request and wastes cpu at all other + # times. + with _ServerSelector() as selector: + selector.register(self, selectors.EVENT_READ) + + while not self.__shutdown_request: + ready = selector.select(poll_interval) + if ready: + self._handle_request_noblock() + + self.service_actions() finally: self.__shutdown_request = False self.__is_shut_down.set() @@ -261,16 +261,16 @@ def service_actions(self): """ pass - # The distinction between handling, getting, processing and - # finishing a request is fairly arbitrary. Remember: + # The distinction between handling, getting, processing and finishing a + # request is fairly arbitrary. Remember: # - # - handle_request() is the top-level call. It calls - # select, get_request(), verify_request() and process_request() + # - handle_request() is the top-level call. It calls selector.select(), + # get_request(), verify_request() and process_request() # - get_request() is different for stream or datagram sockets - # - process_request() is the place that may fork a new process - # or create a new thread to finish the request - # - finish_request() instantiates the request handler class; - # this constructor will handle the request all by itself + # - process_request() is the place that may fork a new process or create a + # new thread to finish the request + # - finish_request() instantiates the request handler class; this + # constructor will handle the request all by itself def handle_request(self): """Handle one request, possibly blocking. @@ -284,18 +284,30 @@ def handle_request(self): timeout = self.timeout elif self.timeout is not None: timeout = min(timeout, self.timeout) - fd_sets = _eintr_retry(select.select, [self], [], [], timeout) - if not fd_sets[0]: - self.handle_timeout() - return - self._handle_request_noblock() + if timeout is not None: + deadline = time() + timeout + + # Wait until a request arrives or the timeout expires - the loop is + # necessary to accommodate early wakeups due to EINTR. + with _ServerSelector() as selector: + selector.register(self, selectors.EVENT_READ) + + while True: + ready = selector.select(timeout) + if ready: + return self._handle_request_noblock() + else: + if timeout is not None: + timeout = deadline - time() + if timeout < 0: + return self.handle_timeout() def _handle_request_noblock(self): """Handle one request, without blocking. - I assume that select.select has returned that the socket is - readable before this function was called, so there should be - no risk of blocking in get_request(). + I assume that selector.select() has returned that the socket is + readable before this function was called, so there should be no risk of + blocking in get_request(). """ try: request, client_address = self.get_request() @@ -378,7 +390,7 @@ class TCPServer(BaseServer): - serve_forever(poll_interval=0.5) - shutdown() - handle_request() # if you don't use serve_forever() - - fileno() -> int # for select() + - fileno() -> int # for selector Methods that may be overridden: @@ -427,8 +439,12 @@ def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True): self.socket = socket.socket(self.address_family, self.socket_type) if bind_and_activate: - self.server_bind() - self.server_activate() + try: + self.server_bind() + self.server_activate() + except: + self.server_close() + raise def server_bind(self): """Called by constructor to bind the socket. @@ -460,7 +476,7 @@ def server_close(self): def fileno(self): """Return socket file number. - Interface required by select(). + Interface required by selector. """ return self.socket.fileno() @@ -524,35 +540,37 @@ class ForkingMixIn: def collect_children(self): """Internal routine to wait for children that have exited.""" - if self.active_children is None: return + if self.active_children is None: + return + + # If we're above the max number of children, wait and reap them until + # we go back below threshold. Note that we use waitpid(-1) below to be + # able to collect children in size() syscalls instead + # of size(): the downside is that this might reap children + # which we didn't spawn, which is why we only resort to this when we're + # above max_children. while len(self.active_children) >= self.max_children: - # XXX: This will wait for any child process, not just ones - # spawned by this library. This could confuse other - # libraries that expect to be able to wait for their own - # children. try: - pid, status = os.waitpid(0, 0) + pid, _ = os.waitpid(-1, 0) + self.active_children.discard(pid) + except ChildProcessError: + # we don't have any children, we're done + self.active_children.clear() except OSError: - pid = None - if pid not in self.active_children: continue - self.active_children.remove(pid) - - # XXX: This loop runs more system calls than it ought - # to. There should be a way to put the active_children into a - # process group and then use os.waitpid(-pgid) to wait for any - # of that set, but I couldn't find a way to allocate pgids - # that couldn't collide. - for child in self.active_children: + break + + # Now reap all defunct children. + for pid in self.active_children.copy(): try: - pid, status = os.waitpid(child, os.WNOHANG) + pid, _ = os.waitpid(pid, os.WNOHANG) + # if the child hasn't exited yet, pid will be 0 and ignored by + # discard() below + self.active_children.discard(pid) + except ChildProcessError: + # someone else reaped it + self.active_children.discard(pid) except OSError: - pid = None - if not pid: continue - try: - self.active_children.remove(pid) - except ValueError as e: - raise ValueError('%s. x=%d and list=%r' % (e.message, pid, - self.active_children)) + pass def handle_timeout(self): """Wait for zombies after self.timeout seconds of inactivity. @@ -574,8 +592,8 @@ def process_request(self, request, client_address): if pid: # Parent process if self.active_children is None: - self.active_children = [] - self.active_children.append(pid) + self.active_children = set() + self.active_children.add(pid) self.close_request(request) return else: diff --git a/Lib/sqlite3/dbapi2.py b/Lib/sqlite3/dbapi2.py index 9a0b76645e1e..991682ce9ef3 100644 --- a/Lib/sqlite3/dbapi2.py +++ b/Lib/sqlite3/dbapi2.py @@ -22,6 +22,7 @@ import datetime import time +import collections.abc from _sqlite3 import * @@ -50,6 +51,7 @@ def TimestampFromTicks(ticks): sqlite_version_info = tuple([int(x) for x in sqlite_version.split(".")]) Binary = memoryview +collections.abc.Sequence.register(Row) def register_adapters_and_converters(): def adapt_date(val): diff --git a/Lib/sqlite3/test/factory.py b/Lib/sqlite3/test/factory.py index 0314ebd4411a..f587596f6448 100644 --- a/Lib/sqlite3/test/factory.py +++ b/Lib/sqlite3/test/factory.py @@ -23,6 +23,7 @@ import unittest import sqlite3 as sqlite +from collections.abc import Sequence class MyConnection(sqlite.Connection): def __init__(self, *args, **kwargs): @@ -96,9 +97,37 @@ def CheckSqliteRowIndex(self): self.assertEqual(col1, 1, "by name: wrong result for column 'A'") self.assertEqual(col2, 2, "by name: wrong result for column 'B'") - col1, col2 = row[0], row[1] - self.assertEqual(col1, 1, "by index: wrong result for column 0") - self.assertEqual(col2, 2, "by index: wrong result for column 1") + self.assertEqual(row[0], 1, "by index: wrong result for column 0") + self.assertEqual(row[1], 2, "by index: wrong result for column 1") + self.assertEqual(row[-1], 2, "by index: wrong result for column -1") + self.assertEqual(row[-2], 1, "by index: wrong result for column -2") + + with self.assertRaises(IndexError): + row['c'] + with self.assertRaises(IndexError): + row[2] + with self.assertRaises(IndexError): + row[-3] + with self.assertRaises(IndexError): + row[2**1000] + + def CheckSqliteRowSlice(self): + # A sqlite.Row can be sliced like a list. + self.con.row_factory = sqlite.Row + row = self.con.execute("select 1, 2, 3, 4").fetchone() + self.assertEqual(row[0:0], ()) + self.assertEqual(row[0:1], (1,)) + self.assertEqual(row[1:3], (2, 3)) + self.assertEqual(row[3:1], ()) + # Explicit bounds are optional. + self.assertEqual(row[1:], (2, 3, 4)) + self.assertEqual(row[:3], (1, 2, 3)) + # Slices can use negative indices. + self.assertEqual(row[-2:-1], (3,)) + self.assertEqual(row[-2:], (3, 4)) + # Slicing supports steps. + self.assertEqual(row[0:4:2], (1, 3)) + self.assertEqual(row[3:0:-2], (4, 2)) def CheckSqliteRowIter(self): """Checks if the row object is iterable""" @@ -112,6 +141,7 @@ def CheckSqliteRowAsTuple(self): self.con.row_factory = sqlite.Row row = self.con.execute("select 1 as a, 2 as b").fetchone() t = tuple(row) + self.assertEqual(t, (row['a'], row['b'])) def CheckSqliteRowAsDict(self): """Checks if the row object can be correctly converted to a dictionary""" @@ -141,6 +171,23 @@ def CheckSqliteRowHashCmp(self): self.assertNotEqual(row_1, row_3) self.assertNotEqual(hash(row_1), hash(row_3)) + def CheckSqliteRowAsSequence(self): + """ Checks if the row object can act like a sequence """ + self.con.row_factory = sqlite.Row + row = self.con.execute("select 1 as a, 2 as b").fetchone() + + as_tuple = tuple(row) + self.assertEqual(list(reversed(row)), list(reversed(as_tuple))) + self.assertIsInstance(row, Sequence) + + def CheckFakeCursorClass(self): + # Issue #24257: Incorrect use of PyObject_IsInstance() caused + # segmentation fault. + class FakeCursor(str): + __class__ = sqlite.Cursor + cur = self.con.cursor(factory=FakeCursor) + self.assertRaises(TypeError, sqlite.Row, cur, ()) + def tearDown(self): self.con.close() diff --git a/Lib/sqlite3/test/hooks.py b/Lib/sqlite3/test/hooks.py index 60f760548213..ede0becad4eb 100644 --- a/Lib/sqlite3/test/hooks.py +++ b/Lib/sqlite3/test/hooks.py @@ -162,7 +162,7 @@ def progress(): create table bar (a, b) """) second_count = len(progress_calls) - self.assertGreater(first_count, second_count) + self.assertGreaterEqual(first_count, second_count) def CheckCancelOperation(self): """ diff --git a/Lib/sqlite3/test/regression.py b/Lib/sqlite3/test/regression.py index b927cb3ed185..eaaaa2c528eb 100644 --- a/Lib/sqlite3/test/regression.py +++ b/Lib/sqlite3/test/regression.py @@ -330,6 +330,21 @@ def CheckConvertTimestampMicrosecondPadding(self): datetime.datetime(2012, 4, 4, 15, 6, 0, 123456), ]) + def CheckInvalidIsolationLevelType(self): + # isolation level is a string, not an integer + self.assertRaises(TypeError, + sqlite.connect, ":memory:", isolation_level=123) + + + def CheckNullCharacter(self): + # Issue #21147 + con = sqlite.connect(":memory:") + self.assertRaises(ValueError, con, "\0select 1") + self.assertRaises(ValueError, con, "select 1\0") + cur = con.cursor() + self.assertRaises(ValueError, cur.execute, " \0select 2") + self.assertRaises(ValueError, cur.execute, "select 2\0") + def suite(): regression_suite = unittest.makeSuite(RegressionTests, "Check") diff --git a/Lib/sqlite3/test/types.py b/Lib/sqlite3/test/types.py index a8fdad9ee13e..adad571b9a06 100644 --- a/Lib/sqlite3/test/types.py +++ b/Lib/sqlite3/test/types.py @@ -88,19 +88,10 @@ def __init__(self, _val): _val = _val.decode('utf-8') self.val = _val - def __cmp__(self, other): - if not isinstance(other, DeclTypesTests.Foo): - raise ValueError - if self.val == other.val: - return 0 - else: - return 1 - def __eq__(self, other): - c = self.__cmp__(other) - if c is NotImplemented: - return c - return c == 0 + if not isinstance(other, DeclTypesTests.Foo): + return NotImplemented + return self.val == other.val def __conform__(self, protocol): if protocol is sqlite.PrepareProtocol: diff --git a/Lib/sre_compile.py b/Lib/sre_compile.py index 3a5083fde872..4edb03fa300e 100644 --- a/Lib/sre_compile.py +++ b/Lib/sre_compile.py @@ -10,25 +10,56 @@ """Internal support module for sre""" -import _sre, sys +import _sre import sre_parse from sre_constants import * -from _sre import MAXREPEAT assert _sre.MAGIC == MAGIC, "SRE module mismatch" -if _sre.CODESIZE == 2: - MAXCODE = 65535 -else: - MAXCODE = 0xFFFFFFFF - -def _identityfunction(x): - return x - -_LITERAL_CODES = set([LITERAL, NOT_LITERAL]) -_REPEATING_CODES = set([REPEAT, MIN_REPEAT, MAX_REPEAT]) -_SUCCESS_CODES = set([SUCCESS, FAILURE]) -_ASSERT_CODES = set([ASSERT, ASSERT_NOT]) +_LITERAL_CODES = {LITERAL, NOT_LITERAL} +_REPEATING_CODES = {REPEAT, MIN_REPEAT, MAX_REPEAT} +_SUCCESS_CODES = {SUCCESS, FAILURE} +_ASSERT_CODES = {ASSERT, ASSERT_NOT} + +# Sets of lowercase characters which have the same uppercase. +_equivalences = ( + # LATIN SMALL LETTER I, LATIN SMALL LETTER DOTLESS I + (0x69, 0x131), # iı + # LATIN SMALL LETTER S, LATIN SMALL LETTER LONG S + (0x73, 0x17f), # sſ + # MICRO SIGN, GREEK SMALL LETTER MU + (0xb5, 0x3bc), # µμ + # COMBINING GREEK YPOGEGRAMMENI, GREEK SMALL LETTER IOTA, GREEK PROSGEGRAMMENI + (0x345, 0x3b9, 0x1fbe), # \u0345ιι + # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS, GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA + (0x390, 0x1fd3), # ΐΐ + # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS, GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA + (0x3b0, 0x1fe3), # ΰΰ + # GREEK SMALL LETTER BETA, GREEK BETA SYMBOL + (0x3b2, 0x3d0), # βϐ + # GREEK SMALL LETTER EPSILON, GREEK LUNATE EPSILON SYMBOL + (0x3b5, 0x3f5), # εϵ + # GREEK SMALL LETTER THETA, GREEK THETA SYMBOL + (0x3b8, 0x3d1), # θϑ + # GREEK SMALL LETTER KAPPA, GREEK KAPPA SYMBOL + (0x3ba, 0x3f0), # κϰ + # GREEK SMALL LETTER PI, GREEK PI SYMBOL + (0x3c0, 0x3d6), # πϖ + # GREEK SMALL LETTER RHO, GREEK RHO SYMBOL + (0x3c1, 0x3f1), # ρϱ + # GREEK SMALL LETTER FINAL SIGMA, GREEK SMALL LETTER SIGMA + (0x3c2, 0x3c3), # ςσ + # GREEK SMALL LETTER PHI, GREEK PHI SYMBOL + (0x3c6, 0x3d5), # φϕ + # LATIN SMALL LETTER S WITH DOT ABOVE, LATIN SMALL LETTER LONG S WITH DOT ABOVE + (0x1e61, 0x1e9b), # ṡẛ + # LATIN SMALL LIGATURE LONG S T, LATIN SMALL LIGATURE ST + (0xfb05, 0xfb06), # ſtst +) + +# Maps the lowercase code to lowercase codes which have the same uppercase. +_ignorecase_fixes = {i: tuple(j for j in t if i != j) + for t in _equivalences for i in t} def _compile(code, pattern, flags): # internal: compile a (sub)pattern @@ -38,68 +69,86 @@ def _compile(code, pattern, flags): REPEATING_CODES = _REPEATING_CODES SUCCESS_CODES = _SUCCESS_CODES ASSERT_CODES = _ASSERT_CODES + if (flags & SRE_FLAG_IGNORECASE and + not (flags & SRE_FLAG_LOCALE) and + flags & SRE_FLAG_UNICODE): + fixes = _ignorecase_fixes + else: + fixes = None for op, av in pattern: if op in LITERAL_CODES: if flags & SRE_FLAG_IGNORECASE: - emit(OPCODES[OP_IGNORE[op]]) - emit(_sre.getlower(av, flags)) + lo = _sre.getlower(av, flags) + if fixes and lo in fixes: + emit(IN_IGNORE) + skip = _len(code); emit(0) + if op is NOT_LITERAL: + emit(NEGATE) + for k in (lo,) + fixes[lo]: + emit(LITERAL) + emit(k) + emit(FAILURE) + code[skip] = _len(code) - skip + else: + emit(OP_IGNORE[op]) + emit(lo) else: - emit(OPCODES[op]) + emit(op) emit(av) elif op is IN: if flags & SRE_FLAG_IGNORECASE: - emit(OPCODES[OP_IGNORE[op]]) + emit(OP_IGNORE[op]) def fixup(literal, flags=flags): return _sre.getlower(literal, flags) else: - emit(OPCODES[op]) - fixup = _identityfunction + emit(op) + fixup = None skip = _len(code); emit(0) - _compile_charset(av, flags, code, fixup) + _compile_charset(av, flags, code, fixup, fixes) code[skip] = _len(code) - skip elif op is ANY: if flags & SRE_FLAG_DOTALL: - emit(OPCODES[ANY_ALL]) + emit(ANY_ALL) else: - emit(OPCODES[ANY]) + emit(ANY) elif op in REPEATING_CODES: if flags & SRE_FLAG_TEMPLATE: - raise error("internal: unsupported template operator") + raise error("internal: unsupported template operator %r" % (op,)) elif _simple(av) and op is not REPEAT: if op is MAX_REPEAT: - emit(OPCODES[REPEAT_ONE]) + emit(REPEAT_ONE) else: - emit(OPCODES[MIN_REPEAT_ONE]) + emit(MIN_REPEAT_ONE) skip = _len(code); emit(0) emit(av[0]) emit(av[1]) _compile(code, av[2], flags) - emit(OPCODES[SUCCESS]) + emit(SUCCESS) code[skip] = _len(code) - skip else: - emit(OPCODES[REPEAT]) + emit(REPEAT) skip = _len(code); emit(0) emit(av[0]) emit(av[1]) _compile(code, av[2], flags) code[skip] = _len(code) - skip if op is MAX_REPEAT: - emit(OPCODES[MAX_UNTIL]) + emit(MAX_UNTIL) else: - emit(OPCODES[MIN_UNTIL]) + emit(MIN_UNTIL) elif op is SUBPATTERN: if av[0]: - emit(OPCODES[MARK]) + emit(MARK) emit((av[0]-1)*2) # _compile_info(code, av[1], flags) _compile(code, av[1], flags) if av[0]: - emit(OPCODES[MARK]) + emit(MARK) emit((av[0]-1)*2+1) elif op in SUCCESS_CODES: - emit(OPCODES[op]) + emit(op) elif op in ASSERT_CODES: - emit(OPCODES[op]) + emit(op) skip = _len(code); emit(0) if av[0] >= 0: emit(0) # look ahead @@ -109,57 +158,57 @@ def fixup(literal, flags=flags): raise error("look-behind requires fixed-width pattern") emit(lo) # look behind _compile(code, av[1], flags) - emit(OPCODES[SUCCESS]) + emit(SUCCESS) code[skip] = _len(code) - skip elif op is CALL: - emit(OPCODES[op]) + emit(op) skip = _len(code); emit(0) _compile(code, av, flags) - emit(OPCODES[SUCCESS]) + emit(SUCCESS) code[skip] = _len(code) - skip elif op is AT: - emit(OPCODES[op]) + emit(op) if flags & SRE_FLAG_MULTILINE: av = AT_MULTILINE.get(av, av) if flags & SRE_FLAG_LOCALE: av = AT_LOCALE.get(av, av) elif flags & SRE_FLAG_UNICODE: av = AT_UNICODE.get(av, av) - emit(ATCODES[av]) + emit(av) elif op is BRANCH: - emit(OPCODES[op]) + emit(op) tail = [] tailappend = tail.append for av in av[1]: skip = _len(code); emit(0) # _compile_info(code, av, flags) _compile(code, av, flags) - emit(OPCODES[JUMP]) + emit(JUMP) tailappend(_len(code)); emit(0) code[skip] = _len(code) - skip - emit(0) # end of branch + emit(FAILURE) # end of branch for tail in tail: code[tail] = _len(code) - tail elif op is CATEGORY: - emit(OPCODES[op]) + emit(op) if flags & SRE_FLAG_LOCALE: av = CH_LOCALE[av] elif flags & SRE_FLAG_UNICODE: av = CH_UNICODE[av] - emit(CHCODES[av]) + emit(av) elif op is GROUPREF: if flags & SRE_FLAG_IGNORECASE: - emit(OPCODES[OP_IGNORE[op]]) + emit(OP_IGNORE[op]) else: - emit(OPCODES[op]) + emit(op) emit(av-1) elif op is GROUPREF_EXISTS: - emit(OPCODES[op]) + emit(op) emit(av[0]-1) skipyes = _len(code); emit(0) _compile(code, av[1], flags) if av[2]: - emit(OPCODES[JUMP]) + emit(JUMP) skipno = _len(code); emit(0) code[skipyes] = _len(code) - skipyes + 1 _compile(code, av[2], flags) @@ -167,38 +216,36 @@ def fixup(literal, flags=flags): else: code[skipyes] = _len(code) - skipyes + 1 else: - raise ValueError("unsupported operand type", op) + raise error("internal: unsupported operand type %r" % (op,)) -def _compile_charset(charset, flags, code, fixup=None): +def _compile_charset(charset, flags, code, fixup=None, fixes=None): # compile charset subprogram emit = code.append - if fixup is None: - fixup = _identityfunction - for op, av in _optimize_charset(charset, fixup): - emit(OPCODES[op]) + for op, av in _optimize_charset(charset, fixup, fixes): + emit(op) if op is NEGATE: pass elif op is LITERAL: - emit(fixup(av)) - elif op is RANGE: - emit(fixup(av[0])) - emit(fixup(av[1])) + emit(av) + elif op is RANGE or op is RANGE_IGNORE: + emit(av[0]) + emit(av[1]) elif op is CHARSET: code.extend(av) elif op is BIGCHARSET: code.extend(av) elif op is CATEGORY: if flags & SRE_FLAG_LOCALE: - emit(CHCODES[CH_LOCALE[av]]) + emit(CH_LOCALE[av]) elif flags & SRE_FLAG_UNICODE: - emit(CHCODES[CH_UNICODE[av]]) + emit(CH_UNICODE[av]) else: - emit(CHCODES[av]) + emit(av) else: - raise error("internal: unsupported set operator") - emit(OPCODES[FAILURE]) + raise error("internal: unsupported set operator %r" % (op,)) + emit(FAILURE) -def _optimize_charset(charset, fixup): +def _optimize_charset(charset, fixup, fixes): # internal: optimize character set out = [] tail = [] @@ -207,10 +254,27 @@ def _optimize_charset(charset, fixup): while True: try: if op is LITERAL: - charmap[fixup(av)] = 1 + if fixup: + lo = fixup(av) + charmap[lo] = 1 + if fixes and lo in fixes: + for k in fixes[lo]: + charmap[k] = 1 + else: + charmap[av] = 1 elif op is RANGE: - for i in range(fixup(av[0]), fixup(av[1])+1): - charmap[i] = 1 + r = range(av[0], av[1]+1) + if fixup: + r = map(fixup, r) + if fixup and fixes: + for i in r: + charmap[i] = 1 + if i in fixes: + for k in fixes[i]: + charmap[k] = 1 + else: + for i in r: + charmap[i] = 1 elif op is NEGATE: out.append((op, av)) else: @@ -220,7 +284,12 @@ def _optimize_charset(charset, fixup): # character set contains non-UCS1 character codes charmap += b'\0' * 0xff00 continue - # character set contains non-BMP character codes + # Character set contains non-BMP character codes. + # There are only two ranges of cased non-BMP characters: + # 10400-1044F (Deseret) and 118A0-118DF (Warang Citi), + # and for both ranges RANGE_IGNORE works. + if fixup and op is RANGE: + op = RANGE_IGNORE tail.append((op, av)) break @@ -247,8 +316,10 @@ def _optimize_charset(charset, fixup): else: out.append((RANGE, (p, q - 1))) out += tail - if len(out) < len(charset): + # if the case was changed or new representation is more compact + if fixup or len(out) < len(charset): return out + # else original character set is good enough return charset # use bitmap @@ -298,6 +369,7 @@ def _optimize_charset(charset, fixup): return out _CODEBITS = _sre.CODESIZE * 8 +MAXCODE = (1 << _CODEBITS) - 1 _BITS_TRANS = b'0' + b'1' * 255 def _mk_bitmap(bits, _CODEBITS=_CODEBITS, _int=int): s = bits.translate(_BITS_TRANS)[::-1] @@ -306,8 +378,7 @@ def _mk_bitmap(bits, _CODEBITS=_CODEBITS, _int=int): def _bytes_to_codes(b): # Convert block indices to word array - import array - a = array.array('I', b) + a = memoryview(b).cast('I') assert a.itemsize == _sre.CODESIZE assert len(a) * a.itemsize == len(b) return a.tolist() @@ -338,54 +409,39 @@ def _generate_overlap_table(prefix): table[i] = idx + 1 return table -def _compile_info(code, pattern, flags): - # internal: compile an info block. in the current version, - # this contains min/max pattern width, and an optional literal - # prefix or a character map - lo, hi = pattern.getwidth() - if lo == 0: - return # not worth it - # look for a literal prefix +def _get_literal_prefix(pattern): + # look for literal prefix prefix = [] prefixappend = prefix.append - prefix_skip = 0 + prefix_skip = None + got_all = True + for op, av in pattern.data: + if op is LITERAL: + prefixappend(av) + elif op is SUBPATTERN: + prefix1, prefix_skip1, got_all = _get_literal_prefix(av[1]) + if prefix_skip is None: + if av[0] is not None: + prefix_skip = len(prefix) + elif prefix_skip1 is not None: + prefix_skip = len(prefix) + prefix_skip1 + prefix.extend(prefix1) + if not got_all: + break + else: + got_all = False + break + return prefix, prefix_skip, got_all + +def _get_charset_prefix(pattern): charset = [] # not used charsetappend = charset.append - if not (flags & SRE_FLAG_IGNORECASE): - # look for literal prefix - for op, av in pattern.data: + if pattern.data: + op, av = pattern.data[0] + if op is SUBPATTERN and av[1]: + op, av = av[1][0] if op is LITERAL: - if len(prefix) == prefix_skip: - prefix_skip = prefix_skip + 1 - prefixappend(av) - elif op is SUBPATTERN and len(av[1]) == 1: - op, av = av[1][0] - if op is LITERAL: - prefixappend(av) - else: - break - else: - break - # if no prefix, look for charset prefix - if not prefix and pattern.data: - op, av = pattern.data[0] - if op is SUBPATTERN and av[1]: - op, av = av[1][0] - if op is LITERAL: - charsetappend((op, av)) - elif op is BRANCH: - c = [] - cappend = c.append - for p in av[1]: - if not p: - break - op, av = p[0] - if op is LITERAL: - cappend((op, av)) - else: - break - else: - charset = c + charsetappend((op, av)) elif op is BRANCH: c = [] cappend = c.append @@ -399,24 +455,59 @@ def _compile_info(code, pattern, flags): break else: charset = c - elif op is IN: - charset = av + elif op is BRANCH: + c = [] + cappend = c.append + for p in av[1]: + if not p: + break + op, av = p[0] + if op is LITERAL: + cappend((op, av)) + else: + break + else: + charset = c + elif op is IN: + charset = av + return charset + +def _compile_info(code, pattern, flags): + # internal: compile an info block. in the current version, + # this contains min/max pattern width, and an optional literal + # prefix or a character map + lo, hi = pattern.getwidth() + if hi > MAXCODE: + hi = MAXCODE + if lo == 0: + code.extend([INFO, 4, 0, lo, hi]) + return + # look for a literal prefix + prefix = [] + prefix_skip = 0 + charset = [] # not used + if not (flags & SRE_FLAG_IGNORECASE): + # look for literal prefix + prefix, prefix_skip, got_all = _get_literal_prefix(pattern) + # if no prefix, look for charset prefix + if not prefix: + charset = _get_charset_prefix(pattern) ## if prefix: -## print "*** PREFIX", prefix, prefix_skip +## print("*** PREFIX", prefix, prefix_skip) ## if charset: -## print "*** CHARSET", charset +## print("*** CHARSET", charset) # add an info block emit = code.append - emit(OPCODES[INFO]) + emit(INFO) skip = len(code); emit(0) # literal flag mask = 0 if prefix: mask = SRE_INFO_PREFIX - if len(prefix) == prefix_skip == len(pattern.data): - mask = mask + SRE_INFO_LITERAL + if prefix_skip is None and got_all: + mask = mask | SRE_INFO_LITERAL elif charset: - mask = mask + SRE_INFO_CHARSET + mask = mask | SRE_INFO_CHARSET emit(mask) # pattern length if lo < MAXCODE: @@ -424,13 +515,12 @@ def _compile_info(code, pattern, flags): else: emit(MAXCODE) prefix = prefix[:MAXCODE] - if hi < MAXCODE: - emit(hi) - else: - emit(0) + emit(min(hi, MAXCODE)) # add literal prefix if prefix: emit(len(prefix)) # length + if prefix_skip is None: + prefix_skip = len(prefix) emit(prefix_skip) # skip code.extend(prefix) # generate overlap table @@ -453,7 +543,7 @@ def _code(p, flags): # compile the pattern _compile(code, p.data, flags) - code.append(OPCODES[SUCCESS]) + code.append(SUCCESS) return code @@ -468,13 +558,7 @@ def compile(p, flags=0): code = _code(p, flags) - # print code - - # XXX: get rid of this limitation! - if p.pattern.groups > 100: - raise AssertionError( - "sorry, but this version only supports 100 named groups" - ) + # print(code) # map in either direction groupindex = p.pattern.groupdict diff --git a/Lib/sre_constants.py b/Lib/sre_constants.py index 23e3516006cd..fc684ae96fd3 100644 --- a/Lib/sre_constants.py +++ b/Lib/sre_constants.py @@ -13,153 +13,115 @@ # update when constants are added or removed -MAGIC = 20031017 +MAGIC = 20140917 -from _sre import MAXREPEAT +from _sre import MAXREPEAT, MAXGROUPS # SRE standard exception (access as sre.error) # should this really be here? class error(Exception): - pass + def __init__(self, msg, pattern=None, pos=None): + self.msg = msg + self.pattern = pattern + self.pos = pos + if pattern is not None and pos is not None: + msg = '%s at position %d' % (msg, pos) + if isinstance(pattern, str): + newline = '\n' + else: + newline = b'\n' + self.lineno = pattern.count(newline, 0, pos) + 1 + self.colno = pos - pattern.rfind(newline, 0, pos) + if newline in pattern: + msg = '%s (line %d, column %d)' % (msg, self.lineno, self.colno) + else: + self.lineno = self.colno = None + super().__init__(msg) + + +class _NamedIntConstant(int): + def __new__(cls, value, name): + self = super(_NamedIntConstant, cls).__new__(cls, value) + self.name = name + return self + + def __str__(self): + return self.name + + __repr__ = __str__ + +MAXREPEAT = _NamedIntConstant(MAXREPEAT, 'MAXREPEAT') + +def _makecodes(names): + names = names.strip().split() + items = [_NamedIntConstant(i, name) for i, name in enumerate(names)] + globals().update({item.name: item for item in items}) + return items # operators +# failure=0 success=1 (just because it looks better that way :-) +OPCODES = _makecodes(""" + FAILURE SUCCESS + + ANY ANY_ALL + ASSERT ASSERT_NOT + AT + BRANCH + CALL + CATEGORY + CHARSET BIGCHARSET + GROUPREF GROUPREF_EXISTS GROUPREF_IGNORE + IN IN_IGNORE + INFO + JUMP + LITERAL LITERAL_IGNORE + MARK + MAX_UNTIL + MIN_UNTIL + NOT_LITERAL NOT_LITERAL_IGNORE + NEGATE + RANGE + REPEAT + REPEAT_ONE + SUBPATTERN + MIN_REPEAT_ONE + RANGE_IGNORE -FAILURE = "failure" -SUCCESS = "success" - -ANY = "any" -ANY_ALL = "any_all" -ASSERT = "assert" -ASSERT_NOT = "assert_not" -AT = "at" -BIGCHARSET = "bigcharset" -BRANCH = "branch" -CALL = "call" -CATEGORY = "category" -CHARSET = "charset" -GROUPREF = "groupref" -GROUPREF_IGNORE = "groupref_ignore" -GROUPREF_EXISTS = "groupref_exists" -IN = "in" -IN_IGNORE = "in_ignore" -INFO = "info" -JUMP = "jump" -LITERAL = "literal" -LITERAL_IGNORE = "literal_ignore" -MARK = "mark" -MAX_REPEAT = "max_repeat" -MAX_UNTIL = "max_until" -MIN_REPEAT = "min_repeat" -MIN_UNTIL = "min_until" -NEGATE = "negate" -NOT_LITERAL = "not_literal" -NOT_LITERAL_IGNORE = "not_literal_ignore" -RANGE = "range" -REPEAT = "repeat" -REPEAT_ONE = "repeat_one" -SUBPATTERN = "subpattern" -MIN_REPEAT_ONE = "min_repeat_one" + MIN_REPEAT MAX_REPEAT +""") +del OPCODES[-2:] # remove MIN_REPEAT and MAX_REPEAT # positions -AT_BEGINNING = "at_beginning" -AT_BEGINNING_LINE = "at_beginning_line" -AT_BEGINNING_STRING = "at_beginning_string" -AT_BOUNDARY = "at_boundary" -AT_NON_BOUNDARY = "at_non_boundary" -AT_END = "at_end" -AT_END_LINE = "at_end_line" -AT_END_STRING = "at_end_string" -AT_LOC_BOUNDARY = "at_loc_boundary" -AT_LOC_NON_BOUNDARY = "at_loc_non_boundary" -AT_UNI_BOUNDARY = "at_uni_boundary" -AT_UNI_NON_BOUNDARY = "at_uni_non_boundary" +ATCODES = _makecodes(""" + AT_BEGINNING AT_BEGINNING_LINE AT_BEGINNING_STRING + AT_BOUNDARY AT_NON_BOUNDARY + AT_END AT_END_LINE AT_END_STRING + AT_LOC_BOUNDARY AT_LOC_NON_BOUNDARY + AT_UNI_BOUNDARY AT_UNI_NON_BOUNDARY +""") # categories -CATEGORY_DIGIT = "category_digit" -CATEGORY_NOT_DIGIT = "category_not_digit" -CATEGORY_SPACE = "category_space" -CATEGORY_NOT_SPACE = "category_not_space" -CATEGORY_WORD = "category_word" -CATEGORY_NOT_WORD = "category_not_word" -CATEGORY_LINEBREAK = "category_linebreak" -CATEGORY_NOT_LINEBREAK = "category_not_linebreak" -CATEGORY_LOC_WORD = "category_loc_word" -CATEGORY_LOC_NOT_WORD = "category_loc_not_word" -CATEGORY_UNI_DIGIT = "category_uni_digit" -CATEGORY_UNI_NOT_DIGIT = "category_uni_not_digit" -CATEGORY_UNI_SPACE = "category_uni_space" -CATEGORY_UNI_NOT_SPACE = "category_uni_not_space" -CATEGORY_UNI_WORD = "category_uni_word" -CATEGORY_UNI_NOT_WORD = "category_uni_not_word" -CATEGORY_UNI_LINEBREAK = "category_uni_linebreak" -CATEGORY_UNI_NOT_LINEBREAK = "category_uni_not_linebreak" - -OPCODES = [ - - # failure=0 success=1 (just because it looks better that way :-) - FAILURE, SUCCESS, - - ANY, ANY_ALL, - ASSERT, ASSERT_NOT, - AT, - BRANCH, - CALL, - CATEGORY, - CHARSET, BIGCHARSET, - GROUPREF, GROUPREF_EXISTS, GROUPREF_IGNORE, - IN, IN_IGNORE, - INFO, - JUMP, - LITERAL, LITERAL_IGNORE, - MARK, - MAX_UNTIL, - MIN_UNTIL, - NOT_LITERAL, NOT_LITERAL_IGNORE, - NEGATE, - RANGE, - REPEAT, - REPEAT_ONE, - SUBPATTERN, - MIN_REPEAT_ONE +CHCODES = _makecodes(""" + CATEGORY_DIGIT CATEGORY_NOT_DIGIT + CATEGORY_SPACE CATEGORY_NOT_SPACE + CATEGORY_WORD CATEGORY_NOT_WORD + CATEGORY_LINEBREAK CATEGORY_NOT_LINEBREAK + CATEGORY_LOC_WORD CATEGORY_LOC_NOT_WORD + CATEGORY_UNI_DIGIT CATEGORY_UNI_NOT_DIGIT + CATEGORY_UNI_SPACE CATEGORY_UNI_NOT_SPACE + CATEGORY_UNI_WORD CATEGORY_UNI_NOT_WORD + CATEGORY_UNI_LINEBREAK CATEGORY_UNI_NOT_LINEBREAK +""") -] - -ATCODES = [ - AT_BEGINNING, AT_BEGINNING_LINE, AT_BEGINNING_STRING, AT_BOUNDARY, - AT_NON_BOUNDARY, AT_END, AT_END_LINE, AT_END_STRING, - AT_LOC_BOUNDARY, AT_LOC_NON_BOUNDARY, AT_UNI_BOUNDARY, - AT_UNI_NON_BOUNDARY -] - -CHCODES = [ - CATEGORY_DIGIT, CATEGORY_NOT_DIGIT, CATEGORY_SPACE, - CATEGORY_NOT_SPACE, CATEGORY_WORD, CATEGORY_NOT_WORD, - CATEGORY_LINEBREAK, CATEGORY_NOT_LINEBREAK, CATEGORY_LOC_WORD, - CATEGORY_LOC_NOT_WORD, CATEGORY_UNI_DIGIT, CATEGORY_UNI_NOT_DIGIT, - CATEGORY_UNI_SPACE, CATEGORY_UNI_NOT_SPACE, CATEGORY_UNI_WORD, - CATEGORY_UNI_NOT_WORD, CATEGORY_UNI_LINEBREAK, - CATEGORY_UNI_NOT_LINEBREAK -] - -def makedict(list): - d = {} - i = 0 - for item in list: - d[item] = i - i = i + 1 - return d - -OPCODES = makedict(OPCODES) -ATCODES = makedict(ATCODES) -CHCODES = makedict(CHCODES) # replacement operations for "ignore case" mode OP_IGNORE = { GROUPREF: GROUPREF_IGNORE, IN: IN_IGNORE, LITERAL: LITERAL_IGNORE, - NOT_LITERAL: NOT_LITERAL_IGNORE + NOT_LITERAL: NOT_LITERAL_IGNORE, + RANGE: RANGE_IGNORE, } AT_MULTILINE = { @@ -217,11 +179,11 @@ def makedict(list): if __name__ == "__main__": def dump(f, d, prefix): - items = sorted(d.items(), key=lambda a: a[1]) - for k, v in items: - f.write("#define %s_%s %s\n" % (prefix, k.upper(), v)) - f = open("sre_constants.h", "w") - f.write("""\ + items = sorted(d) + for item in items: + f.write("#define %s_%s %d\n" % (prefix, item, item)) + with open("sre_constants.h", "w") as f: + f.write("""\ /* * Secret Labs' Regular Expression Engine * @@ -237,25 +199,24 @@ def dump(f, d, prefix): """) - f.write("#define SRE_MAGIC %d\n" % MAGIC) + f.write("#define SRE_MAGIC %d\n" % MAGIC) - dump(f, OPCODES, "SRE_OP") - dump(f, ATCODES, "SRE") - dump(f, CHCODES, "SRE") + dump(f, OPCODES, "SRE_OP") + dump(f, ATCODES, "SRE") + dump(f, CHCODES, "SRE") - f.write("#define SRE_FLAG_TEMPLATE %d\n" % SRE_FLAG_TEMPLATE) - f.write("#define SRE_FLAG_IGNORECASE %d\n" % SRE_FLAG_IGNORECASE) - f.write("#define SRE_FLAG_LOCALE %d\n" % SRE_FLAG_LOCALE) - f.write("#define SRE_FLAG_MULTILINE %d\n" % SRE_FLAG_MULTILINE) - f.write("#define SRE_FLAG_DOTALL %d\n" % SRE_FLAG_DOTALL) - f.write("#define SRE_FLAG_UNICODE %d\n" % SRE_FLAG_UNICODE) - f.write("#define SRE_FLAG_VERBOSE %d\n" % SRE_FLAG_VERBOSE) - f.write("#define SRE_FLAG_DEBUG %d\n" % SRE_FLAG_DEBUG) - f.write("#define SRE_FLAG_ASCII %d\n" % SRE_FLAG_ASCII) + f.write("#define SRE_FLAG_TEMPLATE %d\n" % SRE_FLAG_TEMPLATE) + f.write("#define SRE_FLAG_IGNORECASE %d\n" % SRE_FLAG_IGNORECASE) + f.write("#define SRE_FLAG_LOCALE %d\n" % SRE_FLAG_LOCALE) + f.write("#define SRE_FLAG_MULTILINE %d\n" % SRE_FLAG_MULTILINE) + f.write("#define SRE_FLAG_DOTALL %d\n" % SRE_FLAG_DOTALL) + f.write("#define SRE_FLAG_UNICODE %d\n" % SRE_FLAG_UNICODE) + f.write("#define SRE_FLAG_VERBOSE %d\n" % SRE_FLAG_VERBOSE) + f.write("#define SRE_FLAG_DEBUG %d\n" % SRE_FLAG_DEBUG) + f.write("#define SRE_FLAG_ASCII %d\n" % SRE_FLAG_ASCII) - f.write("#define SRE_INFO_PREFIX %d\n" % SRE_INFO_PREFIX) - f.write("#define SRE_INFO_LITERAL %d\n" % SRE_INFO_LITERAL) - f.write("#define SRE_INFO_CHARSET %d\n" % SRE_INFO_CHARSET) + f.write("#define SRE_INFO_PREFIX %d\n" % SRE_INFO_PREFIX) + f.write("#define SRE_INFO_LITERAL %d\n" % SRE_INFO_LITERAL) + f.write("#define SRE_INFO_CHARSET %d\n" % SRE_INFO_CHARSET) - f.close() print("done") diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py index 6583ef6c4a7d..67f84e940f5f 100644 --- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -12,20 +12,21 @@ # XXX: show string offset and offending character for all errors -import sys - from sre_constants import * -from _sre import MAXREPEAT SPECIAL_CHARS = ".\\[{()*+?^$|" REPEAT_CHARS = "*+?{" -DIGITS = set("0123456789") +DIGITS = frozenset("0123456789") + +OCTDIGITS = frozenset("01234567") +HEXDIGITS = frozenset("0123456789abcdefABCDEF") +ASCIILETTERS = frozenset("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") -OCTDIGITS = set("01234567") -HEXDIGITS = set("0123456789abcdefABCDEF") +WHITESPACE = frozenset(" \t\n\r\v\f") -WHITESPACE = set(" \t\n\r\v\f") +_REPEATCODES = frozenset({MIN_REPEAT, MAX_REPEAT}) +_UNITCODES = frozenset({ANY, RANGE, IN, LITERAL, NOT_LITERAL, CATEGORY}) ESCAPES = { r"\a": (LITERAL, ord("\a")), @@ -68,24 +69,36 @@ class Pattern: # master pattern object. keeps track of global attributes def __init__(self): self.flags = 0 - self.open = [] - self.groups = 1 self.groupdict = {} + self.subpatterns = [None] # group 0 + self.lookbehindgroups = None + @property + def groups(self): + return len(self.subpatterns) def opengroup(self, name=None): gid = self.groups - self.groups = gid + 1 + self.subpatterns.append(None) + if self.groups > MAXGROUPS: + raise error("too many groups") if name is not None: ogid = self.groupdict.get(name, None) if ogid is not None: - raise error("redefinition of group name %s as group %d; " - "was group %d" % (repr(name), gid, ogid)) + raise error("redefinition of group name %r as group %d; " + "was group %d" % (name, gid, ogid)) self.groupdict[name] = gid - self.open.append(gid) return gid - def closegroup(self, gid): - self.open.remove(gid) + def closegroup(self, gid, p): + self.subpatterns[gid] = p def checkgroup(self, gid): - return gid < self.groups and gid not in self.open + return gid < self.groups and self.subpatterns[gid] is not None + + def checklookbehindgroup(self, gid, source): + if self.lookbehindgroups is not None: + if not self.checkgroup(gid): + raise source.error('cannot refer to an open group') + if gid >= self.lookbehindgroups: + raise source.error('cannot refer to group defined in the same ' + 'lookbehind subpattern') class SubPattern: # a subpattern, in intermediate form @@ -96,33 +109,45 @@ def __init__(self, pattern, data=None): self.data = data self.width = None def dump(self, level=0): - nl = 1 + nl = True seqtypes = (tuple, list) for op, av in self.data: - print(level*" " + op, end=' '); nl = 0 - if op == "in": + print(level*" " + str(op), end='') + if op is IN: # member sublanguage - print(); nl = 1 + print() for op, a in av: - print((level+1)*" " + op, a) - elif op == "branch": - print(); nl = 1 - i = 0 - for a in av[1]: - if i > 0: - print(level*" " + "or") - a.dump(level+1); nl = 1 - i = i + 1 + print((level+1)*" " + str(op), a) + elif op is BRANCH: + print() + for i, a in enumerate(av[1]): + if i: + print(level*" " + "OR") + a.dump(level+1) + elif op is GROUPREF_EXISTS: + condgroup, item_yes, item_no = av + print('', condgroup) + item_yes.dump(level+1) + if item_no: + print(level*" " + "ELSE") + item_no.dump(level+1) elif isinstance(av, seqtypes): + nl = False for a in av: if isinstance(a, SubPattern): - if not nl: print() - a.dump(level+1); nl = 1 + if not nl: + print() + a.dump(level+1) + nl = True else: - print(a, end=' ') ; nl = 0 + if not nl: + print(' ', end='') + print(a, end='') + nl = False + if not nl: + print() else: - print(av, end=' ') ; nl = 0 - if not nl: print() + print('', av) def __repr__(self): return repr(self.data) def __len__(self): @@ -141,11 +166,9 @@ def append(self, code): self.data.append(code) def getwidth(self): # determine the width (min, max) for this subpattern - if self.width: + if self.width is not None: return self.width lo = hi = 0 - UNITCODES = (ANY, RANGE, IN, LITERAL, NOT_LITERAL, CATEGORY) - REPEATCODES = (MIN_REPEAT, MAX_REPEAT) for op, av in self.data: if op is BRANCH: i = MAXREPEAT - 1 @@ -164,14 +187,28 @@ def getwidth(self): i, j = av[1].getwidth() lo = lo + i hi = hi + j - elif op in REPEATCODES: + elif op in _REPEATCODES: i, j = av[2].getwidth() lo = lo + i * av[0] hi = hi + j * av[1] - elif op in UNITCODES: + elif op in _UNITCODES: lo = lo + 1 hi = hi + 1 - elif op == SUCCESS: + elif op is GROUPREF: + i, j = self.pattern.subpatterns[av].getwidth() + lo = lo + i + hi = hi + j + elif op is GROUPREF_EXISTS: + i, j = av[1].getwidth() + if av[2] is not None: + l, h = av[2].getwidth() + i = min(i, l) + j = max(j, h) + else: + i = 0 + lo = lo + i + hi = hi + j + elif op is SUCCESS: break self.width = min(lo, MAXREPEAT - 1), min(hi, MAXREPEAT) return self.width @@ -180,33 +217,33 @@ class Tokenizer: def __init__(self, string): self.istext = isinstance(string, str) self.string = string + if not self.istext: + string = str(string, 'latin1') + self.decoded_string = string self.index = 0 + self.next = None self.__next() def __next(self): - if self.index >= len(self.string): + index = self.index + try: + char = self.decoded_string[index] + except IndexError: self.next = None return - char = self.string[self.index:self.index+1] - # Special case for the str8, since indexing returns a integer - # XXX This is only needed for test_bug_926075 in test_re.py - if char and not self.istext: - char = chr(char[0]) if char == "\\": + index += 1 try: - c = self.string[self.index + 1] + char += self.decoded_string[index] except IndexError: - raise error("bogus escape (end of line)") - if not self.istext: - c = chr(c) - char = char + c - self.index = self.index + len(char) + raise error("bad escape (end of pattern)", + self.string, len(self.string) - 1) from None + self.index = index + 1 self.next = char - def match(self, char, skip=1): + def match(self, char): if char == self.next: - if skip: - self.__next() - return 1 - return 0 + self.__next() + return True + return False def get(self): this = self.next self.__next() @@ -220,10 +257,30 @@ def getwhile(self, n, charset): result += c self.__next() return result + def getuntil(self, terminator): + result = '' + while True: + c = self.next + self.__next() + if c is None: + if not result: + raise self.error("missing group name") + raise self.error("missing %s, unterminated name" % terminator, + len(result)) + if c == terminator: + if not result: + raise self.error("missing group name", 1) + break + result += c + return result def tell(self): - return self.index, self.next + return self.index - len(self.next or '') def seek(self, index): - self.index, self.next = index + self.index = index + self.__next() + + def error(self, msg, offset=0): + return error(msg, self.string, self.tell() - offset) # The following three functions are not used in this module anymore, but we keep # them here (with DeprecationWarnings) for backwards compatibility. @@ -258,7 +315,7 @@ def _class_escape(source, escape): if code: return code code = CATEGORIES.get(escape) - if code and code[0] == IN: + if code and code[0] is IN: return code try: c = escape[1:2] @@ -266,33 +323,41 @@ def _class_escape(source, escape): # hexadecimal escape (exactly two digits) escape += source.getwhile(2, HEXDIGITS) if len(escape) != 4: - raise ValueError - return LITERAL, int(escape[2:], 16) & 0xff + raise source.error("incomplete escape %s" % escape, len(escape)) + return LITERAL, int(escape[2:], 16) elif c == "u" and source.istext: # unicode escape (exactly four digits) escape += source.getwhile(4, HEXDIGITS) if len(escape) != 6: - raise ValueError + raise source.error("incomplete escape %s" % escape, len(escape)) return LITERAL, int(escape[2:], 16) elif c == "U" and source.istext: # unicode escape (exactly eight digits) escape += source.getwhile(8, HEXDIGITS) if len(escape) != 10: - raise ValueError + raise source.error("incomplete escape %s" % escape, len(escape)) c = int(escape[2:], 16) chr(c) # raise ValueError for invalid code return LITERAL, c elif c in OCTDIGITS: # octal escape (up to three digits) escape += source.getwhile(2, OCTDIGITS) - return LITERAL, int(escape[1:], 8) & 0xff + c = int(escape[1:], 8) + if c > 0o377: + raise source.error('octal escape value %s outside of ' + 'range 0-0o377' % escape, len(escape)) + return LITERAL, c elif c in DIGITS: raise ValueError if len(escape) == 2: + if c in ASCIILETTERS: + import warnings + warnings.warn('bad escape %s' % escape, + DeprecationWarning, stacklevel=8) return LITERAL, ord(escape[1]) except ValueError: pass - raise error("bogus escape: %s" % repr(escape)) + raise source.error("bad escape %s" % escape, len(escape)) def _escape(source, escape, state): # handle escape code in expression @@ -308,64 +373,70 @@ def _escape(source, escape, state): # hexadecimal escape escape += source.getwhile(2, HEXDIGITS) if len(escape) != 4: - raise ValueError - return LITERAL, int(escape[2:], 16) & 0xff + raise source.error("incomplete escape %s" % escape, len(escape)) + return LITERAL, int(escape[2:], 16) elif c == "u" and source.istext: # unicode escape (exactly four digits) escape += source.getwhile(4, HEXDIGITS) if len(escape) != 6: - raise ValueError + raise source.error("incomplete escape %s" % escape, len(escape)) return LITERAL, int(escape[2:], 16) elif c == "U" and source.istext: # unicode escape (exactly eight digits) escape += source.getwhile(8, HEXDIGITS) if len(escape) != 10: - raise ValueError + raise source.error("incomplete escape %s" % escape, len(escape)) c = int(escape[2:], 16) chr(c) # raise ValueError for invalid code return LITERAL, c elif c == "0": # octal escape escape += source.getwhile(2, OCTDIGITS) - return LITERAL, int(escape[1:], 8) & 0xff + return LITERAL, int(escape[1:], 8) elif c in DIGITS: # octal escape *or* decimal group reference (sigh) if source.next in DIGITS: - escape = escape + source.get() + escape += source.get() if (escape[1] in OCTDIGITS and escape[2] in OCTDIGITS and source.next in OCTDIGITS): # got three octal digits; this is an octal escape - escape = escape + source.get() - return LITERAL, int(escape[1:], 8) & 0xff + escape += source.get() + c = int(escape[1:], 8) + if c > 0o377: + raise source.error('octal escape value %s outside of ' + 'range 0-0o377' % escape, + len(escape)) + return LITERAL, c # not an octal escape, so this is a group reference group = int(escape[1:]) if group < state.groups: if not state.checkgroup(group): - raise error("cannot refer to open group") + raise source.error("cannot refer to an open group", + len(escape)) + state.checklookbehindgroup(group, source) return GROUPREF, group - raise ValueError + raise source.error("invalid group reference", len(escape)) if len(escape) == 2: + if c in ASCIILETTERS: + import warnings + warnings.warn('bad escape %s' % escape, + DeprecationWarning, stacklevel=8) return LITERAL, ord(escape[1]) except ValueError: pass - raise error("bogus escape: %s" % repr(escape)) + raise source.error("bad escape %s" % escape, len(escape)) -def _parse_sub(source, state, nested=1): +def _parse_sub(source, state, nested=True): # parse an alternation: a|b|c items = [] itemsappend = items.append sourcematch = source.match - while 1: + start = source.tell() + while True: itemsappend(_parse(source, state)) - if sourcematch("|"): - continue - if not nested: - break - if not source.next or sourcematch(")", 0): + if not sourcematch("|"): break - else: - raise error("pattern not properly closed") if len(items) == 1: return items[0] @@ -374,7 +445,7 @@ def _parse_sub(source, state, nested=1): subpatternappend = subpattern.append # check if all items share a common prefix - while 1: + while True: prefix = None for item in items: if not item: @@ -394,16 +465,12 @@ def _parse_sub(source, state, nested=1): # check if the branch can be replaced by a character set for item in items: - if len(item) != 1 or item[0][0] != LITERAL: + if len(item) != 1 or item[0][0] is not LITERAL: break else: # we can store this as a character set instead of a # branch (the compiler may optimize this even more) - set = [] - setappend = set.append - for item in items: - setappend(item[0]) - subpatternappend((IN, set)) + subpatternappend((IN, [item[0] for item in items])) return subpattern subpattern.append((BRANCH, (None, items))) @@ -413,21 +480,14 @@ def _parse_sub_cond(source, state, condgroup): item_yes = _parse(source, state) if source.match("|"): item_no = _parse(source, state) - if source.match("|"): - raise error("conditional backref with more than two branches") + if source.next == "|": + raise source.error("conditional backref with more than two branches") else: item_no = None - if source.next and not source.match(")", 0): - raise error("pattern not properly closed") subpattern = SubPattern(state) subpattern.append((GROUPREF_EXISTS, (condgroup, item_yes, item_no))) return subpattern -_PATTERNENDERS = set("|)") -_ASSERTCHARS = set("=!<") -_LOOKBEHINDASSERTCHARS = set("=!") -_REPEATCODES = set([MIN_REPEAT, MAX_REPEAT]) - def _parse(source, state): # parse a simple pattern subpattern = SubPattern(state) @@ -437,34 +497,38 @@ def _parse(source, state): sourceget = source.get sourcematch = source.match _len = len - PATTERNENDERS = _PATTERNENDERS - ASSERTCHARS = _ASSERTCHARS - LOOKBEHINDASSERTCHARS = _LOOKBEHINDASSERTCHARS - REPEATCODES = _REPEATCODES + _ord = ord + verbose = state.flags & SRE_FLAG_VERBOSE - while 1: + while True: - if source.next in PATTERNENDERS: - break # end of subpattern - this = sourceget() + this = source.next if this is None: break # end of pattern + if this in "|)": + break # end of subpattern + sourceget() - if state.flags & SRE_FLAG_VERBOSE: + if verbose: # skip whitespace and comments if this in WHITESPACE: continue if this == "#": - while 1: + while True: this = sourceget() - if this in (None, "\n"): + if this is None or this == "\n": break continue - if this and this[0] not in SPECIAL_CHARS: - subpatternappend((LITERAL, ord(this))) + if this[0] == "\\": + code = _escape(source, this, state) + subpatternappend(code) + + elif this not in SPECIAL_CHARS: + subpatternappend((LITERAL, _ord(this))) elif this == "[": + here = source.tell() - 1 # character set set = [] setappend = set.append @@ -474,39 +538,42 @@ def _parse(source, state): setappend((NEGATE, None)) # check remaining characters start = set[:] - while 1: + while True: this = sourceget() + if this is None: + raise source.error("unterminated character set", + source.tell() - here) if this == "]" and set != start: break - elif this and this[0] == "\\": + elif this[0] == "\\": code1 = _class_escape(source, this) - elif this: - code1 = LITERAL, ord(this) else: - raise error("unexpected end of regular expression") + code1 = LITERAL, _ord(this) if sourcematch("-"): # potential range - this = sourceget() - if this == "]": + that = sourceget() + if that is None: + raise source.error("unterminated character set", + source.tell() - here) + if that == "]": if code1[0] is IN: code1 = code1[1][0] setappend(code1) - setappend((LITERAL, ord("-"))) + setappend((LITERAL, _ord("-"))) break - elif this: - if this[0] == "\\": - code2 = _class_escape(source, this) - else: - code2 = LITERAL, ord(this) - if code1[0] != LITERAL or code2[0] != LITERAL: - raise error("bad character range") - lo = code1[1] - hi = code2[1] - if hi < lo: - raise error("bad character range") - setappend((RANGE, (lo, hi))) + if that[0] == "\\": + code2 = _class_escape(source, that) else: - raise error("unexpected end of regular expression") + code2 = LITERAL, _ord(that) + if code1[0] != LITERAL or code2[0] != LITERAL: + msg = "bad character range %s-%s" % (this, that) + raise source.error(msg, len(this) + 1 + len(that)) + lo = code1[1] + hi = code2[1] + if hi < lo: + msg = "bad character range %s-%s" % (this, that) + raise source.error(msg, len(this) + 1 + len(that)) + setappend((RANGE, (lo, hi))) else: if code1[0] is IN: code1 = code1[1][0] @@ -521,8 +588,9 @@ def _parse(source, state): # XXX: should add charmap optimization here subpatternappend((IN, set)) - elif this and this[0] in REPEAT_CHARS: + elif this in REPEAT_CHARS: # repeat previous item + here = source.tell() if this == "?": min, max = 0, 1 elif this == "*": @@ -532,20 +600,19 @@ def _parse(source, state): min, max = 1, MAXREPEAT elif this == "{": if source.next == "}": - subpatternappend((LITERAL, ord(this))) + subpatternappend((LITERAL, _ord(this))) continue - here = source.tell() min, max = 0, MAXREPEAT lo = hi = "" while source.next in DIGITS: - lo = lo + source.get() + lo += sourceget() if sourcematch(","): while source.next in DIGITS: - hi = hi + sourceget() + hi += sourceget() else: hi = lo if not sourcematch("}"): - subpatternappend((LITERAL, ord(this))) + subpatternappend((LITERAL, _ord(this))) source.seek(here) continue if lo: @@ -557,18 +624,21 @@ def _parse(source, state): if max >= MAXREPEAT: raise OverflowError("the repetition number is too large") if max < min: - raise error("bad repeat interval") + raise source.error("min repeat greater than max repeat", + source.tell() - here) else: - raise error("not supported") + raise AssertionError("unsupported quantifier %r" % (char,)) # figure out which item to repeat if subpattern: item = subpattern[-1:] else: item = None - if not item or (_len(item) == 1 and item[0][0] == AT): - raise error("nothing to repeat") - if item[0][0] in REPEATCODES: - raise error("multiple repeat") + if not item or (_len(item) == 1 and item[0][0] is AT): + raise source.error("nothing to repeat", + source.tell() - here + len(this)) + if item[0][0] in _REPEATCODES: + raise source.error("multiple repeat", + source.tell() - here + len(this)) if sourcematch("?"): subpattern[-1] = (MIN_REPEAT, (min, max, item)) else: @@ -578,135 +648,140 @@ def _parse(source, state): subpatternappend((ANY, None)) elif this == "(": - group = 1 + start = source.tell() - 1 + group = True name = None condgroup = None if sourcematch("?"): - group = 0 # options - if sourcematch("P"): + char = sourceget() + if char is None: + raise source.error("unexpected end of pattern") + if char == "P": # python extensions if sourcematch("<"): # named group: skip forward to end of name - name = "" - while 1: - char = sourceget() - if char is None: - raise error("unterminated name") - if char == ">": - break - name = name + char - group = 1 - if not name: - raise error("missing group name") + name = source.getuntil(">") if not name.isidentifier(): - raise error("bad character in group name %r" % name) + msg = "bad character in group name %r" % name + raise source.error(msg, len(name) + 1) elif sourcematch("="): # named backreference - name = "" - while 1: - char = sourceget() - if char is None: - raise error("unterminated name") - if char == ")": - break - name = name + char - if not name: - raise error("missing group name") + name = source.getuntil(")") if not name.isidentifier(): - raise error("bad character in backref group name " - "%r" % name) + msg = "bad character in group name %r" % name + raise source.error(msg, len(name) + 1) gid = state.groupdict.get(name) if gid is None: - raise error("unknown group name") + msg = "unknown group name %r" % name + raise source.error(msg, len(name) + 1) + if not state.checkgroup(gid): + raise source.error("cannot refer to an open group", + len(name) + 1) + state.checklookbehindgroup(gid, source) subpatternappend((GROUPREF, gid)) continue else: char = sourceget() if char is None: - raise error("unexpected end of pattern") - raise error("unknown specifier: ?P%s" % char) - elif sourcematch(":"): + raise source.error("unexpected end of pattern") + raise source.error("unknown extension ?P" + char, + len(char) + 2) + elif char == ":": # non-capturing group - group = 2 - elif sourcematch("#"): + group = None + elif char == "#": # comment - while 1: - if source.next is None or source.next == ")": + while True: + if source.next is None: + raise source.error("missing ), unterminated comment", + source.tell() - start) + if sourceget() == ")": break - sourceget() - if not sourcematch(")"): - raise error("unbalanced parenthesis") continue - elif source.next in ASSERTCHARS: + elif char in "=!<": # lookahead assertions - char = sourceget() dir = 1 if char == "<": - if source.next not in LOOKBEHINDASSERTCHARS: - raise error("syntax error") - dir = -1 # lookbehind char = sourceget() + if char is None: + raise source.error("unexpected end of pattern") + if char not in "=!": + raise source.error("unknown extension ?<" + char, + len(char) + 2) + dir = -1 # lookbehind + lookbehindgroups = state.lookbehindgroups + if lookbehindgroups is None: + state.lookbehindgroups = state.groups p = _parse_sub(source, state) + if dir < 0: + if lookbehindgroups is None: + state.lookbehindgroups = None if not sourcematch(")"): - raise error("unbalanced parenthesis") + raise source.error("missing ), unterminated subpattern", + source.tell() - start) if char == "=": subpatternappend((ASSERT, (dir, p))) else: subpatternappend((ASSERT_NOT, (dir, p))) continue - elif sourcematch("("): + elif char == "(": # conditional backreference group - condname = "" - while 1: - char = sourceget() - if char is None: - raise error("unterminated name") - if char == ")": - break - condname = condname + char - group = 2 - if not condname: - raise error("missing group name") + condname = source.getuntil(")") + group = None if condname.isidentifier(): condgroup = state.groupdict.get(condname) if condgroup is None: - raise error("unknown group name") + msg = "unknown group name %r" % condname + raise source.error(msg, len(condname) + 1) else: try: condgroup = int(condname) + if condgroup < 0: + raise ValueError except ValueError: - raise error("bad character in group name") - else: + msg = "bad character in group name %r" % condname + raise source.error(msg, len(condname) + 1) from None + if not condgroup: + raise source.error("bad group number", + len(condname) + 1) + if condgroup >= MAXGROUPS: + raise source.error("invalid group reference", + len(condname) + 1) + state.checklookbehindgroup(condgroup, source) + elif char in FLAGS: # flags - if not source.next in FLAGS: - raise error("unexpected end of pattern") - while source.next in FLAGS: - state.flags = state.flags | FLAGS[sourceget()] - if group: - # parse group contents - if group == 2: - # anonymous group - group = None + while True: + state.flags |= FLAGS[char] + char = sourceget() + if char is None: + raise source.error("missing )") + if char == ")": + break + if char not in FLAGS: + raise source.error("unknown flag", len(char)) + verbose = state.flags & SRE_FLAG_VERBOSE + continue else: + raise source.error("unknown extension ?" + char, + len(char) + 1) + + # parse group contents + if group is not None: + try: group = state.opengroup(name) - if condgroup: - p = _parse_sub_cond(source, state, condgroup) - else: - p = _parse_sub(source, state) - if not sourcematch(")"): - raise error("unbalanced parenthesis") - if group is not None: - state.closegroup(group) - subpatternappend((SUBPATTERN, (group, p))) + except error as err: + raise source.error(err.msg, len(name) + 1) from None + if condgroup: + p = _parse_sub_cond(source, state, condgroup) else: - while 1: - char = sourceget() - if char is None: - raise error("unexpected end of pattern") - if char == ")": - break - raise error("unknown extension") + p = _parse_sub(source, state) + if not source.match(")"): + raise source.error("missing ), unterminated subpattern", + source.tell() - start) + if group is not None: + state.closegroup(group, p) + subpatternappend((SUBPATTERN, (group, p))) elif this == "^": subpatternappend((AT, AT_BEGINNING)) @@ -714,25 +789,31 @@ def _parse(source, state): elif this == "$": subpattern.append((AT, AT_END)) - elif this and this[0] == "\\": - code = _escape(source, this, state) - subpatternappend(code) - else: - raise error("parser error") + raise AssertionError("unsupported special character %r" % (char,)) return subpattern def fix_flags(src, flags): # Check and fix flags according to the type of pattern (str or bytes) if isinstance(src, str): + if flags & SRE_FLAG_LOCALE: + import warnings + warnings.warn("LOCALE flag with a str pattern is deprecated. " + "Will be an error in 3.6", + DeprecationWarning, stacklevel=6) if not flags & SRE_FLAG_ASCII: flags |= SRE_FLAG_UNICODE elif flags & SRE_FLAG_UNICODE: raise ValueError("ASCII and UNICODE flags are incompatible") else: if flags & SRE_FLAG_UNICODE: - raise ValueError("can't use UNICODE flag with a bytes pattern") + raise ValueError("cannot use UNICODE flag with a bytes pattern") + if flags & SRE_FLAG_LOCALE and flags & SRE_FLAG_ASCII: + import warnings + warnings.warn("ASCII and LOCALE flags are incompatible. " + "Will be an error in 3.6", + DeprecationWarning, stacklevel=6) return flags def parse(str, flags=0, pattern=None): @@ -748,11 +829,9 @@ def parse(str, flags=0, pattern=None): p = _parse_sub(source, pattern, 0) p.pattern.flags = fix_flags(str, p.pattern.flags) - tail = source.get() - if tail == ")": - raise error("unbalanced parenthesis") - elif tail: - raise error("bogus characters at end of regular expression") + if source.next is not None: + assert source.next == ")" + raise source.error("unbalanced parenthesis") if flags & SRE_FLAG_DEBUG: p.dump() @@ -779,6 +858,7 @@ def addgroup(index): del literal[:] groups.append((len(literals), index)) literals.append(None) + groupindex = pattern.groupindex while True: this = sget() if this is None: @@ -788,27 +868,25 @@ def addgroup(index): c = this[1] if c == "g": name = "" - if s.match("<"): - while True: - char = sget() - if char is None: - raise error("unterminated group name") - if char == ">": - break - name += char - if not name: - raise error("missing group name") - try: - index = int(name) - if index < 0: - raise error("negative group number") - except ValueError: - if not name.isidentifier(): - raise error("bad character in group name") + if not s.match("<"): + raise s.error("missing <") + name = s.getuntil(">") + if name.isidentifier(): try: - index = pattern.groupindex[name] + index = groupindex[name] except KeyError: - raise IndexError("unknown group name") + raise IndexError("unknown group name %r" % name) + else: + try: + index = int(name) + if index < 0: + raise ValueError + except ValueError: + raise s.error("bad character in group name %r" % name, + len(name) + 1) from None + if index >= MAXGROUPS: + raise s.error("invalid group reference", + len(name) + 1) addgroup(index) elif c == "0": if s.next in OCTDIGITS: @@ -824,14 +902,21 @@ def addgroup(index): s.next in OCTDIGITS): this += sget() isoctal = True - lappend(chr(int(this[1:], 8) & 0xff)) + c = int(this[1:], 8) + if c > 0o377: + raise s.error('octal escape value %s outside of ' + 'range 0-0o377' % this, len(this)) + lappend(chr(c)) if not isoctal: addgroup(int(this[1:])) else: try: this = chr(ESCAPES[this][1]) except KeyError: - pass + if c in ASCIILETTERS: + import warnings + warnings.warn('bad escape %s' % this, + DeprecationWarning, stacklevel=4) lappend(this) else: lappend(this) @@ -845,14 +930,12 @@ def addgroup(index): def expand_template(template, match): g = match.group - sep = match.string[:0] + empty = match.string[:0] groups, literals = template literals = literals[:] try: for index, group in groups: - literals[index] = s = g(group) - if s is None: - raise error("unmatched group") + literals[index] = g(group) or empty except IndexError: raise error("invalid group reference") - return sep.join(literals) + return empty.join(literals) diff --git a/Lib/ssl.py b/Lib/ssl.py index 4c155ea7d446..ab7a49b5763f 100644 --- a/Lib/ssl.py +++ b/Lib/ssl.py @@ -87,26 +87,30 @@ ALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY """ +import ipaddress import textwrap import re import sys import os from collections import namedtuple -from enum import Enum as _Enum +from enum import Enum as _Enum, IntEnum as _IntEnum import _ssl # if we can't import it, let the error propagate from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION -from _ssl import _SSLContext +from _ssl import _SSLContext, MemoryBIO from _ssl import ( SSLError, SSLZeroReturnError, SSLWantReadError, SSLWantWriteError, SSLSyscallError, SSLEOFError, ) from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED -from _ssl import (VERIFY_DEFAULT, VERIFY_CRL_CHECK_LEAF, VERIFY_CRL_CHECK_CHAIN, - VERIFY_X509_STRICT) from _ssl import txt2obj as _txt2obj, nid2obj as _nid2obj -from _ssl import RAND_status, RAND_egd, RAND_add, RAND_bytes, RAND_pseudo_bytes +from _ssl import RAND_status, RAND_add, RAND_bytes, RAND_pseudo_bytes +try: + from _ssl import RAND_egd +except ImportError: + # LibreSSL does not provide RAND_egd + pass def _import_symbols(prefix): for n in dir(_ssl): @@ -116,42 +120,30 @@ def _import_symbols(prefix): _import_symbols('OP_') _import_symbols('ALERT_DESCRIPTION_') _import_symbols('SSL_ERROR_') +_import_symbols('VERIFY_') -from _ssl import HAS_SNI, HAS_ECDH, HAS_NPN +from _ssl import HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN -from _ssl import PROTOCOL_SSLv3, PROTOCOL_SSLv23, PROTOCOL_TLSv1 from _ssl import _OPENSSL_API_VERSION +_IntEnum._convert( + '_SSLMethod', __name__, + lambda name: name.startswith('PROTOCOL_'), + source=_ssl) + +_PROTOCOL_NAMES = {value: name for name, value in _SSLMethod.__members__.items()} -_PROTOCOL_NAMES = { - PROTOCOL_TLSv1: "TLSv1", - PROTOCOL_SSLv23: "SSLv23", - PROTOCOL_SSLv3: "SSLv3", -} try: - from _ssl import PROTOCOL_SSLv2 _SSLv2_IF_EXISTS = PROTOCOL_SSLv2 -except ImportError: +except NameError: _SSLv2_IF_EXISTS = None -else: - _PROTOCOL_NAMES[PROTOCOL_SSLv2] = "SSLv2" - -try: - from _ssl import PROTOCOL_TLSv1_1, PROTOCOL_TLSv1_2 -except ImportError: - pass -else: - _PROTOCOL_NAMES[PROTOCOL_TLSv1_1] = "TLSv1.1" - _PROTOCOL_NAMES[PROTOCOL_TLSv1_2] = "TLSv1.2" if sys.platform == "win32": from _ssl import enum_certificates, enum_crls -from socket import getnameinfo as _getnameinfo -from socket import SHUT_RDWR as _SHUT_RDWR from socket import socket, AF_INET, SOCK_STREAM, create_connection +from socket import SOL_SOCKET, SO_TYPE import base64 # for DER-to-PEM translation -import traceback import errno @@ -164,14 +156,35 @@ def _import_symbols(prefix): # Disable weak or insecure ciphers by default # (OpenSSL's default setting is 'DEFAULT:!aNULL:!eNULL') -_DEFAULT_CIPHERS = 'DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2' - -# restricted and more secure ciphers -# HIGH: high encryption cipher suites with key length >= 128 bits (no MD5) -# !aNULL: only authenticated cipher suites (no anonymous DH) -# !RC4: no RC4 streaming cipher, RC4 is broken -# !DSS: RSA is preferred over DSA -_RESTRICTED_CIPHERS = 'HIGH:!aNULL:!RC4:!DSS' +# Enable a better set of ciphers by default +# This list has been explicitly chosen to: +# * Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE) +# * Prefer ECDHE over DHE for better performance +# * Prefer any AES-GCM over any AES-CBC for better performance and security +# * Then Use HIGH cipher suites as a fallback +# * Then Use 3DES as fallback which is secure but slow +# * Disable NULL authentication, NULL encryption, and MD5 MACs for security +# reasons +_DEFAULT_CIPHERS = ( + 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:' + 'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:' + '!eNULL:!MD5' +) + +# Restricted and more secure ciphers for the server side +# This list has been explicitly chosen to: +# * Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE) +# * Prefer ECDHE over DHE for better performance +# * Prefer any AES-GCM over any AES-CBC for better performance and security +# * Then Use HIGH cipher suites as a fallback +# * Then Use 3DES as fallback which is secure but slow +# * Disable NULL authentication, NULL encryption, MD5 MACs, DSS, and RC4 for +# security reasons +_RESTRICTED_SERVER_CIPHERS = ( + 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:' + 'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:' + '!eNULL:!MD5:!DSS:!RC4' +) class CertificateError(ValueError): @@ -192,7 +205,7 @@ def _dnsname_match(dn, hostname, max_wildcards=1): wildcards = leftmost.count('*') if wildcards > max_wildcards: # Issue #17980: avoid denials of service by refusing more - # than one wildcard per fragment. A survery of established + # than one wildcard per fragment. A survey of established # policy among SSL implementations showed it to be a # reasonable choice. raise CertificateError( @@ -227,6 +240,17 @@ def _dnsname_match(dn, hostname, max_wildcards=1): return pat.match(hostname) +def _ipaddress_match(ipname, host_ip): + """Exact matching of IP addresses. + + RFC 6125 explicitly doesn't define an algorithm for this + (section 1.7.2 - "Out of Scope"). + """ + # OpenSSL may add a trailing newline to a subjectAltName's IP address + ip = ipaddress.ip_address(ipname.rstrip()) + return ip == host_ip + + def match_hostname(cert, hostname): """Verify that *cert* (in decoded format as returned by SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 @@ -239,11 +263,20 @@ def match_hostname(cert, hostname): raise ValueError("empty or no certificate, match_hostname needs a " "SSL socket or SSL context with either " "CERT_OPTIONAL or CERT_REQUIRED") + try: + host_ip = ipaddress.ip_address(hostname) + except ValueError: + # Not an IP address (common case) + host_ip = None dnsnames = [] san = cert.get('subjectAltName', ()) for key, value in san: if key == 'DNS': - if _dnsname_match(value, hostname): + if host_ip is None and _dnsname_match(value, hostname): + return + dnsnames.append(value) + elif key == 'IP Address': + if host_ip is not None and _ipaddress_match(value, host_ip): return dnsnames.append(value) if not dnsnames: @@ -342,6 +375,12 @@ def wrap_socket(self, sock, server_side=False, server_hostname=server_hostname, _context=self) + def wrap_bio(self, incoming, outgoing, server_side=False, + server_hostname=None): + sslobj = self._wrap_bio(incoming, outgoing, server_side=server_side, + server_hostname=server_hostname) + return SSLObject(sslobj) + def set_npn_protocols(self, npn_protocols): protos = bytearray() for protocol in npn_protocols: @@ -353,6 +392,17 @@ def set_npn_protocols(self, npn_protocols): self._set_npn_protocols(protos) + def set_alpn_protocols(self, alpn_protocols): + protos = bytearray() + for protocol in alpn_protocols: + b = bytes(protocol, 'ascii') + if len(b) == 0 or len(b) > 255: + raise SSLError('ALPN protocols must be 1 to 255 in length') + protos.append(len(b)) + protos.extend(b) + + self._set_alpn_protocols(protos) + def _load_windows_store_certs(self, storename, purpose): certs = bytearray() for cert, encoding, trust in enum_certificates(storename): @@ -369,8 +419,7 @@ def load_default_certs(self, purpose=Purpose.SERVER_AUTH): if sys.platform == "win32": for storename in self._windows_cert_stores: self._load_windows_store_certs(storename, purpose) - else: - self.set_default_verify_paths() + self.set_default_verify_paths() def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None, @@ -383,17 +432,35 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None, """ if not isinstance(purpose, _ASN1Object): raise TypeError(purpose) - context = SSLContext(PROTOCOL_TLSv1) + + context = SSLContext(PROTOCOL_SSLv23) + # SSLv2 considered harmful. context.options |= OP_NO_SSLv2 + + # SSLv3 has problematic security and is only required for really old + # clients such as IE6 on Windows XP + context.options |= OP_NO_SSLv3 + # disable compression to prevent CRIME attacks (OpenSSL 1.0+) context.options |= getattr(_ssl, "OP_NO_COMPRESSION", 0) - # disallow ciphers with known vulnerabilities - context.set_ciphers(_RESTRICTED_CIPHERS) - # verify certs and host name in client mode + if purpose == Purpose.SERVER_AUTH: + # verify certs and host name in client mode context.verify_mode = CERT_REQUIRED context.check_hostname = True + elif purpose == Purpose.CLIENT_AUTH: + # Prefer the server's ciphers by default so that we get stronger + # encryption + context.options |= getattr(_ssl, "OP_CIPHER_SERVER_PREFERENCE", 0) + + # Use single use keys in order to improve forward secrecy + context.options |= getattr(_ssl, "OP_SINGLE_DH_USE", 0) + context.options |= getattr(_ssl, "OP_SINGLE_ECDH_USE", 0) + + # disallow ciphers with known vulnerabilities + context.set_ciphers(_RESTRICTED_SERVER_CIPHERS) + if cafile or capath or cadata: context.load_verify_locations(cafile, capath, cadata) elif context.verify_mode != CERT_NONE: @@ -403,9 +470,8 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None, context.load_default_certs(purpose) return context - -def _create_stdlib_context(protocol=PROTOCOL_SSLv23, *, cert_reqs=None, - purpose=Purpose.SERVER_AUTH, +def _create_unverified_context(protocol=PROTOCOL_SSLv23, *, cert_reqs=None, + check_hostname=False, purpose=Purpose.SERVER_AUTH, certfile=None, keyfile=None, cafile=None, capath=None, cadata=None): """Create a SSLContext object for Python stdlib modules @@ -421,9 +487,13 @@ def _create_stdlib_context(protocol=PROTOCOL_SSLv23, *, cert_reqs=None, context = SSLContext(protocol) # SSLv2 considered harmful. context.options |= OP_NO_SSLv2 + # SSLv3 has problematic security and is only required for really old + # clients such as IE6 on Windows XP + context.options |= OP_NO_SSLv3 if cert_reqs is not None: context.verify_mode = cert_reqs + context.check_hostname = check_hostname if keyfile and not certfile: raise ValueError("certfile must be specified") @@ -441,6 +511,149 @@ def _create_stdlib_context(protocol=PROTOCOL_SSLv23, *, cert_reqs=None, return context +# Used by http.client if no context is explicitly passed. +_create_default_https_context = create_default_context + + +# Backwards compatibility alias, even though it's not a public name. +_create_stdlib_context = _create_unverified_context + + +class SSLObject: + """This class implements an interface on top of a low-level SSL object as + implemented by OpenSSL. This object captures the state of an SSL connection + but does not provide any network IO itself. IO needs to be performed + through separate "BIO" objects which are OpenSSL's IO abstraction layer. + + This class does not have a public constructor. Instances are returned by + ``SSLContext.wrap_bio``. This class is typically used by framework authors + that want to implement asynchronous IO for SSL through memory buffers. + + When compared to ``SSLSocket``, this object lacks the following features: + + * Any form of network IO incluging methods such as ``recv`` and ``send``. + * The ``do_handshake_on_connect`` and ``suppress_ragged_eofs`` machinery. + """ + + def __init__(self, sslobj, owner=None): + self._sslobj = sslobj + # Note: _sslobj takes a weak reference to owner + self._sslobj.owner = owner or self + + @property + def context(self): + """The SSLContext that is currently in use.""" + return self._sslobj.context + + @context.setter + def context(self, ctx): + self._sslobj.context = ctx + + @property + def server_side(self): + """Whether this is a server-side socket.""" + return self._sslobj.server_side + + @property + def server_hostname(self): + """The currently set server hostname (for SNI), or ``None`` if no + server hostame is set.""" + return self._sslobj.server_hostname + + def read(self, len=0, buffer=None): + """Read up to 'len' bytes from the SSL object and return them. + + If 'buffer' is provided, read into this buffer and return the number of + bytes read. + """ + if buffer is not None: + v = self._sslobj.read(len, buffer) + else: + v = self._sslobj.read(len or 1024) + return v + + def write(self, data): + """Write 'data' to the SSL object and return the number of bytes + written. + + The 'data' argument must support the buffer interface. + """ + return self._sslobj.write(data) + + def getpeercert(self, binary_form=False): + """Returns a formatted version of the data in the certificate provided + by the other end of the SSL channel. + + Return None if no certificate was provided, {} if a certificate was + provided, but not validated. + """ + return self._sslobj.peer_certificate(binary_form) + + def selected_npn_protocol(self): + """Return the currently selected NPN protocol as a string, or ``None`` + if a next protocol was not negotiated or if NPN is not supported by one + of the peers.""" + if _ssl.HAS_NPN: + return self._sslobj.selected_npn_protocol() + + def selected_alpn_protocol(self): + """Return the currently selected ALPN protocol as a string, or ``None`` + if a next protocol was not negotiated or if ALPN is not supported by one + of the peers.""" + if _ssl.HAS_ALPN: + return self._sslobj.selected_alpn_protocol() + + def cipher(self): + """Return the currently selected cipher as a 3-tuple ``(name, + ssl_version, secret_bits)``.""" + return self._sslobj.cipher() + + def shared_ciphers(self): + """Return a list of ciphers shared by the client during the handshake or + None if this is not a valid server connection. + """ + return self._sslobj.shared_ciphers() + + def compression(self): + """Return the current compression algorithm in use, or ``None`` if + compression was not negotiated or not supported by one of the peers.""" + return self._sslobj.compression() + + def pending(self): + """Return the number of bytes that can be read immediately.""" + return self._sslobj.pending() + + def do_handshake(self): + """Start the SSL/TLS handshake.""" + self._sslobj.do_handshake() + if self.context.check_hostname: + if not self.server_hostname: + raise ValueError("check_hostname needs server_hostname " + "argument") + match_hostname(self.getpeercert(), self.server_hostname) + + def unwrap(self): + """Start the SSL shutdown handshake.""" + return self._sslobj.shutdown() + + def get_channel_binding(self, cb_type="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).""" + if cb_type not in CHANNEL_BINDING_TYPES: + raise ValueError("Unsupported channel binding type") + if cb_type != "tls-unique": + raise NotImplementedError( + "{0} channel binding type not implemented" + .format(cb_type)) + return self._sslobj.tls_unique_cb() + + def version(self): + """Return a string identifying the protocol version used by the + current SSL channel. """ + return self._sslobj.version() + + class SSLSocket(socket): """This class implements a subtype of socket.socket that wraps the underlying OS socket in an SSL context when necessary, and @@ -481,16 +694,15 @@ def __init__(self, sock=None, keyfile=None, certfile=None, self.ssl_version = ssl_version self.ca_certs = ca_certs self.ciphers = ciphers + # Can't use sock.type as other flags (such as SOCK_NONBLOCK) get + # mixed in. + if sock.getsockopt(SOL_SOCKET, SO_TYPE) != SOCK_STREAM: + raise NotImplementedError("only stream sockets are supported") if server_side and server_hostname: raise ValueError("server_hostname can only be specified " "in client mode") if self._context.check_hostname and not server_hostname: - if HAS_SNI: - raise ValueError("check_hostname requires server_hostname") - else: - raise ValueError("check_hostname requires server_hostname, " - "but it's not supported by your OpenSSL " - "library") + raise ValueError("check_hostname requires server_hostname") self.server_side = server_side self.server_hostname = server_hostname self.do_handshake_on_connect = do_handshake_on_connect @@ -524,8 +736,9 @@ def __init__(self, sock=None, keyfile=None, certfile=None, if connected: # create the SSL object try: - self._sslobj = self._context._wrap_socket(self, server_side, - server_hostname) + sslobj = self._context._wrap_socket(self, server_side, + server_hostname) + self._sslobj = SSLObject(sslobj, owner=self) if do_handshake_on_connect: timeout = self.gettimeout() if timeout == 0.0: @@ -570,11 +783,7 @@ def read(self, len=0, buffer=None): if not self._sslobj: raise ValueError("Read on closed or unwrapped SSL socket.") try: - if buffer is not None: - v = self._sslobj.read(len, buffer) - else: - v = self._sslobj.read(len or 1024) - return v + return self._sslobj.read(len, buffer) except SSLError as x: if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs: if buffer is not None: @@ -601,7 +810,7 @@ def getpeercert(self, binary_form=False): self._checkClosed() self._check_connected() - return self._sslobj.peer_certificate(binary_form) + return self._sslobj.getpeercert(binary_form) def selected_npn_protocol(self): self._checkClosed() @@ -610,6 +819,13 @@ def selected_npn_protocol(self): else: return self._sslobj.selected_npn_protocol() + def selected_alpn_protocol(self): + self._checkClosed() + if not self._sslobj or not _ssl.HAS_ALPN: + return None + else: + return self._sslobj.selected_alpn_protocol() + def cipher(self): self._checkClosed() if not self._sslobj: @@ -617,6 +833,12 @@ def cipher(self): else: return self._sslobj.cipher() + def shared_ciphers(self): + self._checkClosed() + if not self._sslobj: + return None + return self._sslobj.shared_ciphers() + def compression(self): self._checkClosed() if not self._sslobj: @@ -631,17 +853,7 @@ def send(self, data, flags=0): raise ValueError( "non-zero flags not allowed in calls to send() on %s" % self.__class__) - try: - v = self._sslobj.write(data) - except SSLError as x: - if x.args[0] == SSL_ERROR_WANT_READ: - return 0 - elif x.args[0] == SSL_ERROR_WANT_WRITE: - return 0 - else: - raise - else: - return v + return self._sslobj.write(data) else: return socket.send(self, data, flags) @@ -677,6 +889,16 @@ def sendall(self, data, flags=0): else: return socket.sendall(self, data, flags) + def sendfile(self, file, offset=0, count=None): + """Send a file, possibly by using os.sendfile() if this is a + clear-text socket. Return the total number of bytes sent. + """ + if self._sslobj is None: + # os.sendfile() works with plain sockets only + return super().sendfile(file, offset, count) + else: + return self._sendfile_use_send(file, offset, count) + def recv(self, buflen=1024, flags=0): self._checkClosed() if self._sslobj: @@ -741,7 +963,7 @@ def shutdown(self, how): def unwrap(self): if self._sslobj: - s = self._sslobj.shutdown() + s = self._sslobj.unwrap() self._sslobj = None return s else: @@ -762,17 +984,6 @@ def do_handshake(self, block=False): finally: self.settimeout(timeout) - if self.context.check_hostname: - try: - if not self.server_hostname: - raise ValueError("check_hostname needs server_hostname " - "argument") - match_hostname(self.getpeercert(), self.server_hostname) - except Exception: - self.shutdown(_SHUT_RDWR) - self.close() - raise - def _real_connect(self, addr, connect_ex): if self.server_side: raise ValueError("can't connect in server-side mode") @@ -780,7 +991,8 @@ def _real_connect(self, addr, connect_ex): # connected at the time of the call. We connect it, then wrap it. if self._connected: raise ValueError("attempt to connect already-connected SSLSocket!") - self._sslobj = self.context._wrap_socket(self, False, self.server_hostname) + sslobj = self.context._wrap_socket(self, False, self.server_hostname) + self._sslobj = SSLObject(sslobj, owner=self) try: if connect_ex: rc = socket.connect_ex(self, addr) @@ -823,15 +1035,18 @@ def get_channel_binding(self, cb_type="tls-unique"): 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). """ - if cb_type not in CHANNEL_BINDING_TYPES: - raise ValueError("Unsupported channel binding type") - if cb_type != "tls-unique": - raise NotImplementedError( - "{0} channel binding type not implemented" - .format(cb_type)) if self._sslobj is None: return None - return self._sslobj.tls_unique_cb() + return self._sslobj.get_channel_binding(cb_type) + + def version(self): + """ + Return a string identifying the protocol version used by the + current SSL channel, or None if there is no established channel. + """ + if self._sslobj is None: + return None + return self._sslobj.version() def wrap_socket(sock, keyfile=None, certfile=None, @@ -851,12 +1066,34 @@ def wrap_socket(sock, keyfile=None, certfile=None, # some utility functions def cert_time_to_seconds(cert_time): - """Takes a date-time string in standard ASN1_print form - ("MON DAY 24HOUR:MINUTE:SEC YEAR TIMEZONE") and return - a Python time value in seconds past the epoch.""" + """Return the time in seconds since the Epoch, given the timestring + representing the "notBefore" or "notAfter" date from a certificate + in ``"%b %d %H:%M:%S %Y %Z"`` strptime format (C locale). + + "notBefore" or "notAfter" dates must use UTC (RFC 5280). - import time - return time.mktime(time.strptime(cert_time, "%b %d %H:%M:%S %Y GMT")) + Month is one of: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec + UTC should be specified as GMT (see ASN1_TIME_print()) + """ + from time import strptime + from calendar import timegm + + months = ( + "Jan","Feb","Mar","Apr","May","Jun", + "Jul","Aug","Sep","Oct","Nov","Dec" + ) + time_format = ' %d %H:%M:%S %Y GMT' # NOTE: no month, fixed GMT + try: + month_number = months.index(cert_time[:3].title()) + 1 + except ValueError: + raise ValueError('time data %r does not match ' + 'format "%%b%s"' % (cert_time, time_format)) + else: + # found valid month + tt = strptime(cert_time[3:], time_format) + # return an integer, the previous mktime()-based implementation + # returned a float (fractional seconds are always zero here). + return timegm((tt[0], month_number) + tt[2:6]) PEM_HEADER = "-----BEGIN CERTIFICATE-----" PEM_FOOTER = "-----END CERTIFICATE-----" @@ -883,7 +1120,7 @@ def PEM_cert_to_DER_cert(pem_cert_string): d = pem_cert_string.strip()[len(PEM_HEADER):-len(PEM_FOOTER)] return base64.decodebytes(d.encode('ASCII', 'strict')) -def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None): +def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv23, ca_certs=None): """Retrieve the certificate from the server at the specified address, and return it as a PEM-encoded string. If 'ca_certs' is specified, validate the server cert against it. diff --git a/Lib/stat.py b/Lib/stat.py index 3eecc3e0d348..46837c06dacf 100644 --- a/Lib/stat.py +++ b/Lib/stat.py @@ -148,6 +148,29 @@ def filemode(mode): perm.append("-") return "".join(perm) + +# Windows FILE_ATTRIBUTE constants for interpreting os.stat()'s +# "st_file_attributes" member + +FILE_ATTRIBUTE_ARCHIVE = 32 +FILE_ATTRIBUTE_COMPRESSED = 2048 +FILE_ATTRIBUTE_DEVICE = 64 +FILE_ATTRIBUTE_DIRECTORY = 16 +FILE_ATTRIBUTE_ENCRYPTED = 16384 +FILE_ATTRIBUTE_HIDDEN = 2 +FILE_ATTRIBUTE_INTEGRITY_STREAM = 32768 +FILE_ATTRIBUTE_NORMAL = 128 +FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 8192 +FILE_ATTRIBUTE_NO_SCRUB_DATA = 131072 +FILE_ATTRIBUTE_OFFLINE = 4096 +FILE_ATTRIBUTE_READONLY = 1 +FILE_ATTRIBUTE_REPARSE_POINT = 1024 +FILE_ATTRIBUTE_SPARSE_FILE = 512 +FILE_ATTRIBUTE_SYSTEM = 4 +FILE_ATTRIBUTE_TEMPORARY = 256 +FILE_ATTRIBUTE_VIRTUAL = 65536 + + # If available, use C implementation try: from _stat import * diff --git a/Lib/statistics.py b/Lib/statistics.py index a67a6d11cd6c..3972ed2e5f7e 100644 --- a/Lib/statistics.py +++ b/Lib/statistics.py @@ -144,19 +144,31 @@ def _sum(data, start=0): >>> _sum(data) Decimal('0.6963') + Mixed types are currently treated as an error, except that int is + allowed. """ + # We fail as soon as we reach a value that is not an int or the type of + # the first value which is not an int. E.g. _sum([int, int, float, int]) + # is okay, but sum([int, int, float, Fraction]) is not. + allowed_types = {int, type(start)} n, d = _exact_ratio(start) - T = type(start) partials = {d: n} # map {denominator: sum of numerators} # Micro-optimizations. - coerce_types = _coerce_types exact_ratio = _exact_ratio partials_get = partials.get - # Add numerators for each denominator, and track the "current" type. + # Add numerators for each denominator. for x in data: - T = _coerce_types(T, type(x)) + _check_type(type(x), allowed_types) n, d = exact_ratio(x) partials[d] = partials_get(d, 0) + n + # Find the expected result type. If allowed_types has only one item, it + # will be int; if it has two, use the one which isn't int. + assert len(allowed_types) in (1, 2) + if len(allowed_types) == 1: + assert allowed_types.pop() is int + T = int + else: + T = (allowed_types - {int}).pop() if None in partials: assert issubclass(T, (float, Decimal)) assert not math.isfinite(partials[None]) @@ -172,6 +184,15 @@ def _sum(data, start=0): return T(total) +def _check_type(T, allowed): + if T not in allowed: + if len(allowed) == 1: + allowed.add(T) + else: + types = ', '.join([t.__name__ for t in allowed] + [T.__name__]) + raise TypeError("unsupported mixed types: %s" % types) + + def _exact_ratio(x): """Convert Real number x exactly to (numerator, denominator) pair. @@ -222,55 +243,19 @@ def _decimal_to_ratio(d): num = 0 for digit in digits: num = num*10 + digit + if exp < 0: + den = 10**-exp + else: + num *= 10**exp + den = 1 if sign: num = -num - den = 10**-exp return (num, den) -def _coerce_types(T1, T2): - """Coerce types T1 and T2 to a common type. - - >>> _coerce_types(int, float) - - - Coercion is performed according to this table, where "N/A" means - that a TypeError exception is raised. - - +----------+-----------+-----------+-----------+----------+ - | | int | Fraction | Decimal | float | - +----------+-----------+-----------+-----------+----------+ - | int | int | Fraction | Decimal | float | - | Fraction | Fraction | Fraction | N/A | float | - | Decimal | Decimal | N/A | Decimal | float | - | float | float | float | float | float | - +----------+-----------+-----------+-----------+----------+ - - Subclasses trump their parent class; two subclasses of the same - base class will be coerced to the second of the two. - - """ - # Get the common/fast cases out of the way first. - if T1 is T2: return T1 - if T1 is int: return T2 - if T2 is int: return T1 - # Subclasses trump their parent class. - if issubclass(T2, T1): return T2 - if issubclass(T1, T2): return T1 - # Floats trump everything else. - if issubclass(T2, float): return T2 - if issubclass(T1, float): return T1 - # Subclasses of the same base class give priority to the second. - if T1.__base__ is T2.__base__: return T2 - # Otherwise, just give up. - raise TypeError('cannot coerce types %r and %r' % (T1, T2)) - - def _counts(data): # Generate a table of sorted (value, frequency) pairs. - if data is None: - raise TypeError('None is not iterable') - table = collections.Counter(data).most_common() + table = collections.Counter(iter(data)).most_common() if not table: return table # Extract the values with the highest frequency. diff --git a/Lib/string.py b/Lib/string.py index b57c79b75e5b..1add44be4d71 100644 --- a/Lib/string.py +++ b/Lib/string.py @@ -94,7 +94,11 @@ def _invalid(self, mo): raise ValueError('Invalid placeholder in string: line %d, col %d' % (lineno, colno)) - def substitute(self, *args, **kws): + def substitute(*args, **kws): + if not args: + raise TypeError("descriptor 'substitute' of 'Template' object " + "needs an argument") + self, *args = args # allow the "self" keyword be passed if len(args) > 1: raise TypeError('Too many positional arguments') if not args: @@ -108,10 +112,7 @@ def convert(mo): # Check the most common path first. named = mo.group('named') or mo.group('braced') if named is not None: - val = mapping[named] - # We use this idiom instead of str() because the latter will - # fail if val is a Unicode containing non-ASCII characters. - return '%s' % (val,) + return str(mapping[named]) if mo.group('escaped') is not None: return self.delimiter if mo.group('invalid') is not None: @@ -120,7 +121,11 @@ def convert(mo): self.pattern) return self.pattern.sub(convert, self.template) - def safe_substitute(self, *args, **kws): + def safe_substitute(*args, **kws): + if not args: + raise TypeError("descriptor 'safe_substitute' of 'Template' object " + "needs an argument") + self, *args = args # allow the "self" keyword be passed if len(args) > 1: raise TypeError('Too many positional arguments') if not args: @@ -134,9 +139,7 @@ def convert(mo): named = mo.group('named') or mo.group('braced') if named is not None: try: - # We use this idiom instead of str() because the latter - # will fail if val is a Unicode containing non-ASCII - return '%s' % (mapping[named],) + return str(mapping[named]) except KeyError: return mo.group() if mo.group('escaped') is not None: @@ -160,16 +163,32 @@ def convert(mo): # The field name parser is implemented in _string.formatter_field_name_split class Formatter: - def format(self, format_string, *args, **kwargs): + def format(*args, **kwargs): + if not args: + raise TypeError("descriptor 'format' of 'Formatter' object " + "needs an argument") + self, *args = args # allow the "self" keyword be passed + try: + format_string, *args = args # allow the "format_string" keyword be passed + except ValueError: + if 'format_string' in kwargs: + format_string = kwargs.pop('format_string') + import warnings + warnings.warn("Passing 'format_string' as keyword argument is " + "deprecated", DeprecationWarning, stacklevel=2) + else: + raise TypeError("format() missing 1 required positional " + "argument: 'format_string'") from None return self.vformat(format_string, args, kwargs) def vformat(self, format_string, args, kwargs): used_args = set() - result = self._vformat(format_string, args, kwargs, used_args, 2) + result, _ = self._vformat(format_string, args, kwargs, used_args, 2) self.check_unused_args(used_args, args, kwargs) return result - def _vformat(self, format_string, args, kwargs, used_args, recursion_depth): + def _vformat(self, format_string, args, kwargs, used_args, recursion_depth, + auto_arg_index=0): if recursion_depth < 0: raise ValueError('Max string recursion exceeded') result = [] @@ -185,6 +204,23 @@ def _vformat(self, format_string, args, kwargs, used_args, recursion_depth): # this is some markup, find the object and do # the formatting + # handle arg indexing when empty field_names are given. + if field_name == '': + if auto_arg_index is False: + raise ValueError('cannot switch from manual field ' + 'specification to automatic field ' + 'numbering') + field_name = str(auto_arg_index) + auto_arg_index += 1 + elif field_name.isdigit(): + if auto_arg_index: + raise ValueError('cannot switch from manual field ' + 'specification to automatic field ' + 'numbering') + # disable auto arg incrementing, if it gets + # used later on, then an exception will be raised + auto_arg_index = False + # given the field_name, find the object it references # and the argument it came from obj, arg_used = self.get_field(field_name, args, kwargs) @@ -194,13 +230,15 @@ def _vformat(self, format_string, args, kwargs, used_args, recursion_depth): obj = self.convert_field(obj, conversion) # expand the format spec, if needed - format_spec = self._vformat(format_spec, args, kwargs, - used_args, recursion_depth-1) + format_spec, auto_arg_index = self._vformat( + format_spec, args, kwargs, + used_args, recursion_depth-1, + auto_arg_index=auto_arg_index) # format the object and append to the result result.append(self.format_field(obj, format_spec)) - return ''.join(result) + return ''.join(result), auto_arg_index def get_value(self, key, args, kwargs): diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 0942d94ef71f..b6c437438e4c 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -11,7 +11,7 @@ This module allows you to spawn processes, connect to their input/output/error pipes, and obtain their return codes. This module -intends to replace several other, older modules and functions, like: +intends to replace several older modules and functions: os.system os.spawn* @@ -104,17 +104,21 @@ class Popen(args, bufsize=-1, executable=None, If env is not None, it defines the environment variables for the new process. -If universal_newlines is false, the file objects stdin, stdout and stderr +If universal_newlines is False, the file objects stdin, stdout and stderr are opened as binary files, and no line ending conversion is done. -If universal_newlines is true, the file objects stdout and stderr are -opened as a text files, but lines may be terminated by any of '\n', +If universal_newlines is True, the file objects stdout and stderr are +opened as a text file, but lines may be terminated by any of '\n', the Unix end-of-line convention, '\r', the old Macintosh convention or '\r\n', the Windows convention. All of these external representations are seen as '\n' by the Python program. Also, the newlines attribute of the file objects stdout, stdin and stderr are not updated by the communicate() method. +In either case, the process being communicated with should start up +expecting to receive bytes on its standard input and decode them with +the same encoding they are sent in. + The startupinfo and creationflags, if given, will be passed to the underlying CreateProcess() function. They can specify things such as appearance of the main window and priority for the new process. @@ -184,6 +188,9 @@ class Popen(args, bufsize=-1, executable=None, pass a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument. + If universal_newlines is set to True, the "input" argument must + be a string rather than bytes, and the return value will be a string. + Exceptions ---------- Exceptions raised in the child process, before the new program has @@ -225,9 +232,13 @@ class Popen(args, bufsize=-1, executable=None, communicate(input=None) Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to - terminate. The optional input argument should be a string to be + terminate. The optional input argument should be data to be sent to the child process, or None, if no data should be sent to - the child. + the child. If the Popen instance was constructed with universal_newlines + set to True, the input argument should be a string and will be encoded + using the preferred system encoding (see locale.getpreferredencoding); + if universal_newlines is False, the input argument should be a + byte string. communicate() returns a tuple (stdout, stderr). @@ -345,21 +356,16 @@ class Popen(args, bufsize=-1, executable=None, """ import sys -mswindows = (sys.platform == "win32") +_mswindows = (sys.platform == "win32") import io import os import time -import traceback -import gc import signal import builtins import warnings import errno -try: - from time import monotonic as _time -except ImportError: - from time import time as _time +from time import monotonic as _time # Exception classes used by this module. class SubprocessError(Exception): pass @@ -371,29 +377,53 @@ class CalledProcessError(SubprocessError): The exit status will be stored in the returncode attribute; check_output() will also store the output in the output attribute. """ - def __init__(self, returncode, cmd, output=None): + def __init__(self, returncode, cmd, output=None, stderr=None): self.returncode = returncode self.cmd = cmd self.output = output + self.stderr = stderr + def __str__(self): return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode) + @property + def stdout(self): + """Alias for output attribute, to match stderr""" + return self.output + + @stdout.setter + def stdout(self, value): + # There's no obvious reason to set this, but allow it anyway so + # .stdout is a transparent alias for .output + self.output = value + class TimeoutExpired(SubprocessError): """This exception is raised when the timeout expires while waiting for a child process. """ - def __init__(self, cmd, timeout, output=None): + def __init__(self, cmd, timeout, output=None, stderr=None): self.cmd = cmd self.timeout = timeout self.output = output + self.stderr = stderr def __str__(self): return ("Command '%s' timed out after %s seconds" % (self.cmd, self.timeout)) + @property + def stdout(self): + return self.output + + @stdout.setter + def stdout(self, value): + # There's no obvious reason to set this, but allow it anyway so + # .stdout is a transparent alias for .output + self.output = value -if mswindows: + +if _mswindows: import threading import msvcrt import _winapi @@ -407,6 +437,10 @@ class STARTUPINFO: import _posixsubprocess import select import selectors + try: + import threading + except ImportError: + import dummy_threading as threading # When select or poll has indicated that the file is writable, # we can write up to _PIPE_BUF bytes without risk of blocking. @@ -423,9 +457,12 @@ class STARTUPINFO: __all__ = ["Popen", "PIPE", "STDOUT", "call", "check_call", "getstatusoutput", - "getoutput", "check_output", "CalledProcessError", "DEVNULL"] + "getoutput", "check_output", "run", "CalledProcessError", "DEVNULL", + "SubprocessError", "TimeoutExpired", "CompletedProcess"] + # NOTE: We intentionally exclude list2cmdline as it is + # considered an internal implementation detail. issue10838. -if mswindows: +if _mswindows: from _winapi import (CREATE_NEW_CONSOLE, CREATE_NEW_PROCESS_GROUP, STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE, SW_HIDE, @@ -451,15 +488,11 @@ def Detach(self): raise ValueError("already closed") def __repr__(self): - return "Handle(%d)" % int(self) + return "%s(%d)" % (self.__class__.__name__, int(self)) __del__ = Close __str__ = __repr__ -try: - MAXFD = os.sysconf("SC_OPEN_MAX") -except: - MAXFD = 256 # This lists holds Popen instances for which the underlying process had not # exited at the time its __del__ method got called: those processes are wait()ed @@ -483,14 +516,6 @@ def _cleanup(): DEVNULL = -3 -def _eintr_retry_call(func, *args): - while True: - try: - return func(*args) - except InterruptedError: - continue - - # XXX This function is only used by multiprocessing and the test suite, # but it's here so that it can be imported when Python is compiled without # threads. @@ -589,34 +614,102 @@ def check_output(*popenargs, timeout=None, **kwargs): ... input=b"when in the course of fooman events\n") b'when in the course of barman events\n' - If universal_newlines=True is passed, the return value will be a - string rather than bytes. + If universal_newlines=True is passed, the "input" argument must be a + string and the return value will be a string rather than bytes. """ if 'stdout' in kwargs: raise ValueError('stdout argument not allowed, it will be overridden.') - if 'input' in kwargs: + + if 'input' in kwargs and kwargs['input'] is None: + # Explicitly passing input=None was previously equivalent to passing an + # empty string. That is maintained here for backwards compatibility. + kwargs['input'] = '' if kwargs.get('universal_newlines', False) else b'' + + return run(*popenargs, stdout=PIPE, timeout=timeout, check=True, + **kwargs).stdout + + +class CompletedProcess(object): + """A process that has finished running. + + This is returned by run(). + + Attributes: + args: The list or str args passed to run(). + returncode: The exit code of the process, negative for signals. + stdout: The standard output (None if not captured). + stderr: The standard error (None if not captured). + """ + def __init__(self, args, returncode, stdout=None, stderr=None): + self.args = args + self.returncode = returncode + self.stdout = stdout + self.stderr = stderr + + def __repr__(self): + args = ['args={!r}'.format(self.args), + 'returncode={!r}'.format(self.returncode)] + if self.stdout is not None: + args.append('stdout={!r}'.format(self.stdout)) + if self.stderr is not None: + args.append('stderr={!r}'.format(self.stderr)) + return "{}({})".format(type(self).__name__, ', '.join(args)) + + def check_returncode(self): + """Raise CalledProcessError if the exit code is non-zero.""" + if self.returncode: + raise CalledProcessError(self.returncode, self.args, self.stdout, + self.stderr) + + +def run(*popenargs, input=None, timeout=None, check=False, **kwargs): + """Run command with arguments and return a CompletedProcess instance. + + The returned instance will have attributes args, returncode, stdout and + stderr. By default, stdout and stderr are not captured, and those attributes + will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them. + + If check is True and the exit code was non-zero, it raises a + CalledProcessError. The CalledProcessError object will have the return code + in the returncode attribute, and output & stderr attributes if those streams + were captured. + + If timeout is given, and the process takes too long, a TimeoutExpired + exception will be raised. + + There is an optional argument "input", allowing you to + pass a string to the subprocess's stdin. If you use this argument + you may not also use the Popen constructor's "stdin" argument, as + it will be used internally. + + The other arguments are the same as for the Popen constructor. + + If universal_newlines=True is passed, the "input" argument must be a + string and stdout/stderr in the returned object will be strings rather than + bytes. + """ + if input is not None: if 'stdin' in kwargs: raise ValueError('stdin and input arguments may not both be used.') - inputdata = kwargs['input'] - del kwargs['input'] kwargs['stdin'] = PIPE - else: - inputdata = None - with Popen(*popenargs, stdout=PIPE, **kwargs) as process: + + with Popen(*popenargs, **kwargs) as process: try: - output, unused_err = process.communicate(inputdata, timeout=timeout) + stdout, stderr = process.communicate(input, timeout=timeout) except TimeoutExpired: process.kill() - output, unused_err = process.communicate() - raise TimeoutExpired(process.args, timeout, output=output) + stdout, stderr = process.communicate() + raise TimeoutExpired(process.args, timeout, output=stdout, + stderr=stderr) except: process.kill() process.wait() raise retcode = process.poll() - if retcode: - raise CalledProcessError(retcode, process.args, output=output) - return output + if check and retcode: + raise CalledProcessError(retcode, process.args, + output=stdout, stderr=stderr) + return CompletedProcess(process.args, retcode, stdout, stderr) def list2cmdline(seq): @@ -738,6 +831,9 @@ def getoutput(cmd): class Popen(object): + + _child_created = False # Set here since __del__ checks it + def __init__(self, args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS, @@ -747,8 +843,13 @@ def __init__(self, args, bufsize=-1, executable=None, pass_fds=()): """Create new Popen instance.""" _cleanup() + # Held while anything is calling waitpid before returncode has been + # updated to prevent clobbering returncode if wait() or poll() are + # called from multiple threads at once. After acquiring the lock, + # code must re-check self.returncode to see if another thread just + # finished a waitpid() call. + self._waitpid_lock = threading.Lock() - self._child_created = False self._input = None self._communication_started = False if bufsize is None: @@ -756,7 +857,7 @@ def __init__(self, args, bufsize=-1, executable=None, if not isinstance(bufsize, int): raise TypeError("bufsize must be an integer") - if mswindows: + if _mswindows: if preexec_fn is not None: raise ValueError("preexec_fn is not supported on Windows " "platforms") @@ -816,7 +917,7 @@ def __init__(self, args, bufsize=-1, executable=None, # quickly terminating child could make our fds unwrappable # (see #8458). - if mswindows: + if _mswindows: if p2cwrite != -1: p2cwrite = msvcrt.open_osfhandle(p2cwrite.Detach(), 0) if c2pread != -1: @@ -827,7 +928,8 @@ def __init__(self, args, bufsize=-1, executable=None, if p2cwrite != -1: self.stdin = io.open(p2cwrite, 'wb', bufsize) if universal_newlines: - self.stdin = io.TextIOWrapper(self.stdin, write_through=True) + self.stdin = io.TextIOWrapper(self.stdin, write_through=True, + line_buffering=(bufsize == 1)) if c2pread != -1: self.stdout = io.open(c2pread, 'rb', bufsize) if universal_newlines: @@ -885,16 +987,15 @@ def __exit__(self, type, value, traceback): self.stdout.close() if self.stderr: self.stderr.close() - if self.stdin: - self.stdin.close() - # Wait for the process to terminate, to avoid zombies. - self.wait() - - def __del__(self, _maxsize=sys.maxsize, _active=_active): - # If __init__ hasn't had a chance to execute (e.g. if it - # was passed an undeclared keyword argument), we don't - # have a _child_created attribute at all. - if not getattr(self, '_child_created', False): + try: # Flushing a BufferedWriter may raise an error + if self.stdin: + self.stdin.close() + finally: + # Wait for the process to terminate, to avoid zombies. + self.wait() + + def __del__(self, _maxsize=sys.maxsize): + if not self._child_created: # We didn't get to successfully create a child process. return # In case the child hasn't been waited on, check if it's done. @@ -908,14 +1009,35 @@ def _get_devnull(self): self._devnull = os.open(os.devnull, os.O_RDWR) return self._devnull + def _stdin_write(self, input): + if input: + try: + self.stdin.write(input) + except BrokenPipeError: + # communicate() must ignore broken pipe error + pass + except OSError as e: + if e.errno == errno.EINVAL and self.poll() is not None: + # Issue #19612: On Windows, stdin.write() fails with EINVAL + # if the process already exited before the write + pass + else: + raise + self.stdin.close() + def communicate(self, input=None, timeout=None): """Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for - process to terminate. The optional input argument should be - bytes to be sent to the child process, or None, if no data - should be sent to the child. + process to terminate. - communicate() returns a tuple (stdout, stderr).""" + The optional "input" argument should be data to be sent to the + child process (if self.universal_newlines is True, this should + be a string; if it is False, "input" should be bytes), or + None, if no data should be sent to the child. + + communicate() returns a tuple (stdout, stderr). These will be + bytes or, if self.universal_newlines was True, a string. + """ if self._communication_started and input: raise ValueError("Cannot send input after starting communication") @@ -928,18 +1050,12 @@ def communicate(self, input=None, timeout=None): stdout = None stderr = None if self.stdin: - if input: - try: - self.stdin.write(input) - except OSError as e: - if e.errno != errno.EPIPE and e.errno != errno.EINVAL: - raise - self.stdin.close() + self._stdin_write(input) elif self.stdout: - stdout = _eintr_retry_call(self.stdout.read) + stdout = self.stdout.read() self.stdout.close() elif self.stderr: - stderr = _eintr_retry_call(self.stderr.read) + stderr = self.stderr.read() self.stderr.close() self.wait() else: @@ -978,7 +1094,7 @@ def _check_timeout(self, endtime, orig_timeout): raise TimeoutExpired(self.args, orig_timeout) - if mswindows: + if _mswindows: # # Windows methods # @@ -1183,13 +1299,7 @@ def _communicate(self, input, endtime, orig_timeout): self.stderr_thread.start() if self.stdin: - if input is not None: - try: - self.stdin.write(input) - except OSError as e: - if e.errno != errno.EPIPE: - raise - self.stdin.close() + self._stdin_write(input) # Wait for the reader threads, or time out. If we time out, the # threads remain reading and the fds left open in case the user @@ -1304,16 +1414,6 @@ def _get_handles(self, stdin, stdout, stderr): errread, errwrite) - def _close_fds(self, fds_to_keep): - start_fd = 3 - for fd in sorted(fds_to_keep): - if fd >= start_fd: - os.closerange(start_fd, fd) - start_fd = fd + 1 - if start_fd <= MAXFD: - os.closerange(start_fd, MAXFD) - - def _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, @@ -1399,7 +1499,7 @@ def _execute_child(self, args, executable, preexec_fn, close_fds, # exception (limited in size) errpipe_data = bytearray() while True: - part = _eintr_retry_call(os.read, errpipe_read, 50000) + part = os.read(errpipe_read, 50000) errpipe_data += part if not part or len(errpipe_data) > 50000: break @@ -1409,10 +1509,9 @@ def _execute_child(self, args, executable, preexec_fn, close_fds, if errpipe_data: try: - _eintr_retry_call(os.waitpid, self.pid, 0) - except OSError as e: - if e.errno != errno.ECHILD: - raise + os.waitpid(self.pid, 0) + except ChildProcessError: + pass try: exception_name, hex_errno, err_msg = ( errpipe_data.split(b':', 2)) @@ -1445,8 +1544,9 @@ def _execute_child(self, args, executable, preexec_fn, close_fds, def _handle_exitstatus(self, sts, _WIFSIGNALED=os.WIFSIGNALED, _WTERMSIG=os.WTERMSIG, _WIFEXITED=os.WIFEXITED, _WEXITSTATUS=os.WEXITSTATUS): + """All callers to this function MUST hold self._waitpid_lock.""" # This method is called (indirectly) by __del__, so it cannot - # refer to anything outside of its local scope.""" + # refer to anything outside of its local scope. if _WIFSIGNALED(sts): self.returncode = -_WTERMSIG(sts) elif _WIFEXITED(sts): @@ -1466,7 +1566,13 @@ def _internal_poll(self, _deadstate=None, _waitpid=os.waitpid, """ if self.returncode is None: + if not self._waitpid_lock.acquire(False): + # Something else is busy calling waitpid. Don't allow two + # at once. We know nothing yet. + return None try: + if self.returncode is not None: + return self.returncode # Another thread waited. pid, sts = _waitpid(self.pid, _WNOHANG) if pid == self.pid: self._handle_exitstatus(sts) @@ -1480,15 +1586,16 @@ def _internal_poll(self, _deadstate=None, _waitpid=os.waitpid, # can't get the status. # http://bugs.python.org/issue15756 self.returncode = 0 + finally: + self._waitpid_lock.release() return self.returncode def _try_wait(self, wait_flags): + """All callers to this function MUST hold self._waitpid_lock.""" try: - (pid, sts) = _eintr_retry_call(os.waitpid, self.pid, wait_flags) - except OSError as e: - if e.errno != errno.ECHILD: - raise + (pid, sts) = os.waitpid(self.pid, wait_flags) + except ChildProcessError: # This happens if SIGCLD is set to be ignored or waiting # for child processes has otherwise been disabled for our # process. This child is dead, we can't get the status. @@ -1516,11 +1623,17 @@ def wait(self, timeout=None, endtime=None): # cribbed from Lib/threading.py in Thread.wait() at r71065. delay = 0.0005 # 500 us -> initial delay of 1 ms while True: - (pid, sts) = self._try_wait(os.WNOHANG) - assert pid == self.pid or pid == 0 - if pid == self.pid: - self._handle_exitstatus(sts) - break + if self._waitpid_lock.acquire(False): + try: + if self.returncode is not None: + break # Another thread waited. + (pid, sts) = self._try_wait(os.WNOHANG) + assert pid == self.pid or pid == 0 + if pid == self.pid: + self._handle_exitstatus(sts) + break + finally: + self._waitpid_lock.release() remaining = self._remaining_time(endtime) if remaining <= 0: raise TimeoutExpired(self.args, timeout) @@ -1528,11 +1641,15 @@ def wait(self, timeout=None, endtime=None): time.sleep(delay) else: while self.returncode is None: - (pid, sts) = self._try_wait(0) - # Check the pid and loop as waitpid has been known to return - # 0 even without WNOHANG in odd situations. issue14396. - if pid == self.pid: - self._handle_exitstatus(sts) + with self._waitpid_lock: + if self.returncode is not None: + break # Another thread waited. + (pid, sts) = self._try_wait(0) + # Check the pid and loop as waitpid has been known to + # return 0 even without WNOHANG in odd situations. + # http://bugs.python.org/issue14396. + if pid == self.pid: + self._handle_exitstatus(sts) return self.returncode @@ -1562,6 +1679,9 @@ def _communicate(self, input, endtime, orig_timeout): self._save_input(input) + if self._input: + input_view = memoryview(self._input) + with _PopenSelector() as selector: if self.stdin and input: selector.register(self.stdin, selectors.EVENT_WRITE) @@ -1583,22 +1703,19 @@ def _communicate(self, input, endtime, orig_timeout): for key, events in ready: if key.fileobj is self.stdin: - chunk = self._input[self._input_offset : - self._input_offset + _PIPE_BUF] + chunk = input_view[self._input_offset : + self._input_offset + _PIPE_BUF] try: self._input_offset += os.write(key.fd, chunk) - except OSError as e: - if e.errno == errno.EPIPE: - selector.unregister(key.fileobj) - key.fileobj.close() - else: - raise + except BrokenPipeError: + selector.unregister(key.fileobj) + key.fileobj.close() else: if self._input_offset >= len(self._input): selector.unregister(key.fileobj) key.fileobj.close() elif key.fileobj in (self.stdout, self.stderr): - data = os.read(key.fd, 4096) + data = os.read(key.fd, 32768) if not data: selector.unregister(key.fileobj) key.fileobj.close() diff --git a/Lib/sunau.py b/Lib/sunau.py index 3c244925d1e8..0473e9e4ca15 100644 --- a/Lib/sunau.py +++ b/Lib/sunau.py @@ -97,7 +97,7 @@ be patched up. It is best to first set all parameters, perhaps possibly the compression type, and then write audio frames using writeframesraw. -When all frames have been written, either call writeframes('') or +When all frames have been written, either call writeframes(b'') or close() to patch up the sizes in the header. The close() method is called automatically when the class instance is destroyed. @@ -210,12 +210,9 @@ def initfp(self, file): self._framesize = self._framesize * self._nchannels if self._hdr_size > 24: self._info = file.read(self._hdr_size - 24) - for i in range(len(self._info)): - if self._info[i] == b'\0': - self._info = self._info[:i] - break + self._info, _, _ = self._info.partition(b'\0') else: - self._info = '' + self._info = b'' try: self._data_pos = file.tell() except (AttributeError, OSError): @@ -298,9 +295,11 @@ def setpos(self, pos): self._soundpos = pos def close(self): - if self._opened and self._file: - self._file.close() - self._file = None + file = self._file + if file: + self._file = None + if self._opened: + file.close() class Au_write: @@ -441,9 +440,10 @@ def close(self): self._patchheader() self._file.flush() finally: - if self._opened and self._file: - self._file.close() + file = self._file self._file = None + if self._opened: + file.close() # # private methods diff --git a/Lib/symbol.py b/Lib/symbol.py index 5cf4a65f22b8..754149716307 100755 --- a/Lib/symbol.py +++ b/Lib/symbol.py @@ -16,82 +16,85 @@ decorator = 259 decorators = 260 decorated = 261 -funcdef = 262 -parameters = 263 -typedargslist = 264 -tfpdef = 265 -varargslist = 266 -vfpdef = 267 -stmt = 268 -simple_stmt = 269 -small_stmt = 270 -expr_stmt = 271 -testlist_star_expr = 272 -augassign = 273 -del_stmt = 274 -pass_stmt = 275 -flow_stmt = 276 -break_stmt = 277 -continue_stmt = 278 -return_stmt = 279 -yield_stmt = 280 -raise_stmt = 281 -import_stmt = 282 -import_name = 283 -import_from = 284 -import_as_name = 285 -dotted_as_name = 286 -import_as_names = 287 -dotted_as_names = 288 -dotted_name = 289 -global_stmt = 290 -nonlocal_stmt = 291 -assert_stmt = 292 -compound_stmt = 293 -if_stmt = 294 -while_stmt = 295 -for_stmt = 296 -try_stmt = 297 -with_stmt = 298 -with_item = 299 -except_clause = 300 -suite = 301 -test = 302 -test_nocond = 303 -lambdef = 304 -lambdef_nocond = 305 -or_test = 306 -and_test = 307 -not_test = 308 -comparison = 309 -comp_op = 310 -star_expr = 311 -expr = 312 -xor_expr = 313 -and_expr = 314 -shift_expr = 315 -arith_expr = 316 -term = 317 -factor = 318 -power = 319 -atom = 320 -testlist_comp = 321 -trailer = 322 -subscriptlist = 323 -subscript = 324 -sliceop = 325 -exprlist = 326 -testlist = 327 -dictorsetmaker = 328 -classdef = 329 -arglist = 330 -argument = 331 -comp_iter = 332 -comp_for = 333 -comp_if = 334 -encoding_decl = 335 -yield_expr = 336 -yield_arg = 337 +async_funcdef = 262 +funcdef = 263 +parameters = 264 +typedargslist = 265 +tfpdef = 266 +varargslist = 267 +vfpdef = 268 +stmt = 269 +simple_stmt = 270 +small_stmt = 271 +expr_stmt = 272 +testlist_star_expr = 273 +augassign = 274 +del_stmt = 275 +pass_stmt = 276 +flow_stmt = 277 +break_stmt = 278 +continue_stmt = 279 +return_stmt = 280 +yield_stmt = 281 +raise_stmt = 282 +import_stmt = 283 +import_name = 284 +import_from = 285 +import_as_name = 286 +dotted_as_name = 287 +import_as_names = 288 +dotted_as_names = 289 +dotted_name = 290 +global_stmt = 291 +nonlocal_stmt = 292 +assert_stmt = 293 +compound_stmt = 294 +async_stmt = 295 +if_stmt = 296 +while_stmt = 297 +for_stmt = 298 +try_stmt = 299 +with_stmt = 300 +with_item = 301 +except_clause = 302 +suite = 303 +test = 304 +test_nocond = 305 +lambdef = 306 +lambdef_nocond = 307 +or_test = 308 +and_test = 309 +not_test = 310 +comparison = 311 +comp_op = 312 +star_expr = 313 +expr = 314 +xor_expr = 315 +and_expr = 316 +shift_expr = 317 +arith_expr = 318 +term = 319 +factor = 320 +power = 321 +atom_expr = 322 +atom = 323 +testlist_comp = 324 +trailer = 325 +subscriptlist = 326 +subscript = 327 +sliceop = 328 +exprlist = 329 +testlist = 330 +dictorsetmaker = 331 +classdef = 332 +arglist = 333 +argument = 334 +comp_iter = 335 +comp_for = 336 +comp_if = 337 +encoding_decl = 338 +yield_expr = 339 +yield_arg = 340 #--end constants-- sym_name = {} diff --git a/Lib/symtable.py b/Lib/symtable.py index e23313b031c9..84fec4aa6668 100644 --- a/Lib/symtable.py +++ b/Lib/symtable.py @@ -2,7 +2,7 @@ import _symtable from _symtable import (USE, DEF_GLOBAL, DEF_LOCAL, DEF_PARAM, - DEF_IMPORT, DEF_BOUND, OPT_IMPORT_STAR, SCOPE_OFF, SCOPE_MASK, FREE, + DEF_IMPORT, DEF_BOUND, SCOPE_OFF, SCOPE_MASK, FREE, LOCAL, GLOBAL_IMPLICIT, GLOBAL_EXPLICIT, CELL) import weakref @@ -74,8 +74,7 @@ def get_lineno(self): return self._table.lineno def is_optimized(self): - return bool(self._table.type == _symtable.TYPE_FUNCTION - and not self._table.optimized) + return bool(self._table.type == _symtable.TYPE_FUNCTION) def is_nested(self): return bool(self._table.nested) @@ -87,10 +86,6 @@ def has_exec(self): """Return true if the scope uses exec. Deprecated method.""" return False - def has_import_star(self): - """Return true if the scope uses import *""" - return bool(self._table.optimized & OPT_IMPORT_STAR) - def get_identifiers(self): return self._table.symbols.keys() diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py index dbf77672054b..137932ef7846 100644 --- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py @@ -57,7 +57,7 @@ 'purelib': '{userbase}/Python{py_version_nodot}/site-packages', 'platlib': '{userbase}/Python{py_version_nodot}/site-packages', 'include': '{userbase}/Python{py_version_nodot}/Include', - 'scripts': '{userbase}/Scripts', + 'scripts': '{userbase}/Python{py_version_nodot}/Scripts', 'data': '{userbase}', }, 'posix_user': { @@ -109,13 +109,8 @@ def _safe_realpath(path): # unable to retrieve the real program name _PROJECT_BASE = _safe_realpath(os.getcwd()) -if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower(): - _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir)) -# PC/VS7.1 -if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower(): - _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) -# PC/AMD64 -if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower(): +if (os.name == 'nt' and + _PROJECT_BASE.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))): _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) # set for cross builds @@ -129,11 +124,9 @@ def _is_python_source_dir(d): return False _sys_home = getattr(sys, '_home', None) -if _sys_home and os.name == 'nt' and \ - _sys_home.lower().endswith(('pcbuild', 'pcbuild\\amd64')): - _sys_home = os.path.dirname(_sys_home) - if _sys_home.endswith('pcbuild'): # must be amd64 - _sys_home = os.path.dirname(_sys_home) +if (_sys_home and os.name == 'nt' and + _sys_home.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))): + _sys_home = os.path.dirname(os.path.dirname(_sys_home)) def is_python_build(check_home=False): if check_home and _sys_home: return _is_python_source_dir(_sys_home) diff --git a/Lib/tarfile.py b/Lib/tarfile.py old mode 100644 new mode 100755 index f4df6c7b0ac4..ca45126ff131 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -38,6 +38,7 @@ #--------- # Imports #--------- +from builtins import open as bltn_open import sys import os import io @@ -65,8 +66,6 @@ # from tarfile import * __all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError"] -from builtins import open as _open # Since 'open' is TarFile.open - #--------------------------------------------------------- # tar constants #--------------------------------------------------------- @@ -179,7 +178,8 @@ def nti(s): n = -(256 ** (len(s) - 1) - n) else: try: - n = int(nts(s, "ascii", "strict") or "0", 8) + s = nts(s, "ascii", "strict") + n = int(s.strip() or "0", 8) except ValueError: raise InvalidHeaderError("invalid header") return n @@ -196,7 +196,7 @@ def itn(n, digits=8, format=DEFAULT_FORMAT): # A 0o200 byte indicates a positive number, a 0o377 byte a negative # number. if 0 <= n < 8 ** (digits - 1): - s = bytes("%0*o" % (digits - 1, n), "ascii") + NUL + s = bytes("%0*o" % (digits - 1, int(n)), "ascii") + NUL elif format == GNU_FORMAT and -256 ** (digits - 1) <= n < 256 ** (digits - 1): if n >= 0: s = bytearray([0o200]) @@ -225,7 +225,7 @@ def calc_chksums(buf): signed_chksum = 256 + sum(struct.unpack_from("148b8x356b", buf)) return unsigned_chksum, signed_chksum -def copyfileobj(src, dst, length=None): +def copyfileobj(src, dst, length=None, exception=OSError): """Copy length bytes from fileobj src to fileobj dst. If length is None, copy the entire content. """ @@ -240,13 +240,13 @@ def copyfileobj(src, dst, length=None): for b in range(blocks): buf = src.read(BUFSIZE) if len(buf) < BUFSIZE: - raise OSError("end of file reached") + raise exception("unexpected end of data") dst.write(buf) if remainder != 0: buf = src.read(remainder) if len(buf) < remainder: - raise OSError("end of file reached") + raise exception("unexpected end of data") dst.write(buf) return @@ -257,6 +257,12 @@ def filemode(mode): DeprecationWarning, 2) return stat.filemode(mode) +def _safe_print(s): + encoding = getattr(sys.stdout, 'encoding', None) + if encoding is not None: + s = s.encode(encoding, 'backslashreplace').decode(encoding) + print(s, end=' ') + class TarError(Exception): """Base exception.""" @@ -444,26 +450,26 @@ def close(self): if self.closed: return - if self.mode == "w" and self.comptype != "tar": - self.buf += self.cmp.flush() - - if self.mode == "w" and self.buf: - self.fileobj.write(self.buf) - self.buf = b"" - if self.comptype == "gz": - # The native zlib crc is an unsigned 32-bit integer, but - # the Python wrapper implicitly casts that to a signed C - # long. So, on a 32-bit box self.crc may "look negative", - # while the same crc on a 64-bit box may "look positive". - # To avoid irksome warnings from the `struct` module, force - # it to look positive on all boxes. - self.fileobj.write(struct.pack(" 1 or mode not in "raw": - raise ValueError("mode must be 'r', 'a' or 'w'") + modes = {"r": "rb", "a": "r+b", "w": "wb", "x": "xb"} + if mode not in modes: + raise ValueError("mode must be 'r', 'a', 'w' or 'x'") self.mode = mode - self._mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode] + self._mode = modes[mode] if not fileobj: if self.mode == "a" and not os.path.exists(name): @@ -1418,7 +1428,8 @@ def __init__(self, name=None, mode="r", fileobj=None, format=None, fileobj = bltn_open(name, self._mode) self._extfileobj = False else: - if name is None and hasattr(fileobj, "name"): + if (name is None and hasattr(fileobj, "name") and + isinstance(fileobj.name, (str, bytes))): name = fileobj.name if hasattr(fileobj, "mode"): self._mode = fileobj.mode @@ -1477,7 +1488,7 @@ def __init__(self, name=None, mode="r", fileobj=None, format=None, except HeaderError as e: raise ReadError(str(e)) - if self.mode in "aw": + if self.mode in ("a", "w", "x"): self._loaded = True if self.pax_headers: @@ -1518,6 +1529,15 @@ def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs): 'w:bz2' open for writing with bzip2 compression 'w:xz' open for writing with lzma compression + 'x' or 'x:' create a tarfile exclusively without compression, raise + an exception if the file is already created + 'x:gz' create an gzip compressed tarfile, raise an exception + if the file is already created + 'x:bz2' create an bzip2 compressed tarfile, raise an exception + if the file is already created + 'x:xz' create an lzma compressed tarfile, raise an exception + if the file is already created + 'r|*' open a stream of tar blocks with transparent compression 'r|' open an uncompressed stream of tar blocks for reading 'r|gz' open a gzip compressed stream of tar blocks @@ -1564,7 +1584,7 @@ def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs): filemode = filemode or "r" comptype = comptype or "tar" - if filemode not in "rw": + if filemode not in ("r", "w"): raise ValueError("mode must be 'r' or 'w'") stream = _Stream(name, filemode, comptype, fileobj, bufsize) @@ -1576,7 +1596,7 @@ def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs): t._extfileobj = False return t - elif mode in "aw": + elif mode in ("a", "w", "x"): return cls.taropen(name, mode, fileobj, **kwargs) raise ValueError("undiscernible mode") @@ -1585,8 +1605,8 @@ def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs): def taropen(cls, name, mode="r", fileobj=None, **kwargs): """Open uncompressed tar archive name for reading or writing. """ - if len(mode) > 1 or mode not in "raw": - raise ValueError("mode must be 'r', 'a' or 'w'") + if mode not in ("r", "a", "w", "x"): + raise ValueError("mode must be 'r', 'a', 'w' or 'x'") return cls(name, mode, fileobj, **kwargs) @classmethod @@ -1594,8 +1614,8 @@ def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): """Open gzip compressed tar archive name for reading or writing. Appending is not allowed. """ - if len(mode) > 1 or mode not in "rw": - raise ValueError("mode must be 'r' or 'w'") + if mode not in ("r", "w", "x"): + raise ValueError("mode must be 'r', 'w' or 'x'") try: import gzip @@ -1603,21 +1623,24 @@ def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): except (ImportError, AttributeError): raise CompressionError("gzip module is not available") - extfileobj = fileobj is not None try: fileobj = gzip.GzipFile(name, mode + "b", compresslevel, fileobj) + except OSError: + if fileobj is not None and mode == 'r': + raise ReadError("not a gzip file") + raise + + try: t = cls.taropen(name, mode, fileobj, **kwargs) except OSError: - if not extfileobj and fileobj is not None: - fileobj.close() - if fileobj is None: - raise - raise ReadError("not a gzip file") + fileobj.close() + if mode == 'r': + raise ReadError("not a gzip file") + raise except: - if not extfileobj and fileobj is not None: - fileobj.close() + fileobj.close() raise - t._extfileobj = extfileobj + t._extfileobj = False return t @classmethod @@ -1625,8 +1648,8 @@ def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): """Open bzip2 compressed tar archive name for reading or writing. Appending is not allowed. """ - if len(mode) > 1 or mode not in "rw": - raise ValueError("mode must be 'r' or 'w'.") + if mode not in ("r", "w", "x"): + raise ValueError("mode must be 'r', 'w' or 'x'") try: import bz2 @@ -1640,7 +1663,12 @@ def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): t = cls.taropen(name, mode, fileobj, **kwargs) except (OSError, EOFError): fileobj.close() - raise ReadError("not a bzip2 file") + if mode == 'r': + raise ReadError("not a bzip2 file") + raise + except: + fileobj.close() + raise t._extfileobj = False return t @@ -1649,8 +1677,8 @@ def xzopen(cls, name, mode="r", fileobj=None, preset=None, **kwargs): """Open lzma compressed tar archive name for reading or writing. Appending is not allowed. """ - if mode not in ("r", "w"): - raise ValueError("mode must be 'r' or 'w'") + if mode not in ("r", "w", "x"): + raise ValueError("mode must be 'r', 'w' or 'x'") try: import lzma @@ -1663,7 +1691,12 @@ def xzopen(cls, name, mode="r", fileobj=None, preset=None, **kwargs): t = cls.taropen(name, mode, fileobj, **kwargs) except (lzma.LZMAError, EOFError): fileobj.close() - raise ReadError("not an lzma file") + if mode == 'r': + raise ReadError("not an lzma file") + raise + except: + fileobj.close() + raise t._extfileobj = False return t @@ -1685,18 +1718,19 @@ def close(self): if self.closed: return - if self.mode in "aw": - self.fileobj.write(NUL * (BLOCKSIZE * 2)) - self.offset += (BLOCKSIZE * 2) - # fill up the end with zero-blocks - # (like option -b20 for tar does) - blocks, remainder = divmod(self.offset, RECORDSIZE) - if remainder > 0: - self.fileobj.write(NUL * (RECORDSIZE - remainder)) - - if not self._extfileobj: - self.fileobj.close() self.closed = True + try: + if self.mode in ("a", "w", "x"): + self.fileobj.write(NUL * (BLOCKSIZE * 2)) + self.offset += (BLOCKSIZE * 2) + # fill up the end with zero-blocks + # (like option -b20 for tar does) + blocks, remainder = divmod(self.offset, RECORDSIZE) + if remainder > 0: + self.fileobj.write(NUL * (RECORDSIZE - remainder)) + finally: + if not self._extfileobj: + self.fileobj.close() def getmember(self, name): """Return a TarInfo object for member `name'. If `name' can not be @@ -1732,7 +1766,7 @@ def gettarinfo(self, name=None, arcname=None, fileobj=None): addfile(). If given, `arcname' specifies an alternative name for the file in the archive. """ - self._check("aw") + self._check("awx") # When fileobj is given, replace name by # fileobj's real name. @@ -1823,33 +1857,36 @@ def gettarinfo(self, name=None, arcname=None, fileobj=None): tarinfo.devminor = os.minor(statres.st_rdev) return tarinfo - def list(self, verbose=True): + def list(self, verbose=True, *, members=None): """Print a table of contents to sys.stdout. If `verbose' is False, only the names of the members are printed. If it is True, an `ls -l'-like - output is produced. + output is produced. `members' is optional and must be a subset of the + list returned by getmembers(). """ self._check() - for tarinfo in self: + if members is None: + members = self + for tarinfo in members: if verbose: - print(stat.filemode(tarinfo.mode), end=' ') - print("%s/%s" % (tarinfo.uname or tarinfo.uid, - tarinfo.gname or tarinfo.gid), end=' ') + _safe_print(stat.filemode(tarinfo.mode)) + _safe_print("%s/%s" % (tarinfo.uname or tarinfo.uid, + tarinfo.gname or tarinfo.gid)) if tarinfo.ischr() or tarinfo.isblk(): - print("%10s" % ("%d,%d" \ - % (tarinfo.devmajor, tarinfo.devminor)), end=' ') + _safe_print("%10s" % + ("%d,%d" % (tarinfo.devmajor, tarinfo.devminor))) else: - print("%10d" % tarinfo.size, end=' ') - print("%d-%02d-%02d %02d:%02d:%02d" \ - % time.localtime(tarinfo.mtime)[:6], end=' ') + _safe_print("%10d" % tarinfo.size) + _safe_print("%d-%02d-%02d %02d:%02d:%02d" \ + % time.localtime(tarinfo.mtime)[:6]) - print(tarinfo.name + ("/" if tarinfo.isdir() else ""), end=' ') + _safe_print(tarinfo.name + ("/" if tarinfo.isdir() else "")) if verbose: if tarinfo.issym(): - print("->", tarinfo.linkname, end=' ') + _safe_print("-> " + tarinfo.linkname) if tarinfo.islnk(): - print("link to", tarinfo.linkname, end=' ') + _safe_print("link to " + tarinfo.linkname) print() def add(self, name, arcname=None, recursive=True, exclude=None, *, filter=None): @@ -1863,7 +1900,7 @@ def add(self, name, arcname=None, recursive=True, exclude=None, *, filter=None): TarInfo object, if it returns None the TarInfo object will be excluded from the archive. """ - self._check("aw") + self._check("awx") if arcname is None: arcname = name @@ -1920,7 +1957,7 @@ def addfile(self, tarinfo, fileobj=None): On Windows platforms, `fileobj' should always be opened with mode 'rb' to avoid irritation about the file size. """ - self._check("aw") + self._check("awx") tarinfo = copy.copy(tarinfo) @@ -1939,12 +1976,13 @@ def addfile(self, tarinfo, fileobj=None): self.members.append(tarinfo) - def extractall(self, path=".", members=None): + def extractall(self, path=".", members=None, *, numeric_owner=False): """Extract all members from the archive to the current working directory and set owner, modification time and permissions on directories afterwards. `path' specifies a different directory to extract to. `members' is optional and must be a subset of the - list returned by getmembers(). + list returned by getmembers(). If `numeric_owner` is True, only + the numbers for user/group names are used and not the names. """ directories = [] @@ -1958,7 +1996,8 @@ def extractall(self, path=".", members=None): tarinfo = copy.copy(tarinfo) tarinfo.mode = 0o700 # Do not set_attrs directories, as we will do that further down - self.extract(tarinfo, path, set_attrs=not tarinfo.isdir()) + self.extract(tarinfo, path, set_attrs=not tarinfo.isdir(), + numeric_owner=numeric_owner) # Reverse sort directories. directories.sort(key=lambda a: a.name) @@ -1968,7 +2007,7 @@ def extractall(self, path=".", members=None): for tarinfo in directories: dirpath = os.path.join(path, tarinfo.name) try: - self.chown(tarinfo, dirpath) + self.chown(tarinfo, dirpath, numeric_owner=numeric_owner) self.utime(tarinfo, dirpath) self.chmod(tarinfo, dirpath) except ExtractError as e: @@ -1977,12 +2016,14 @@ def extractall(self, path=".", members=None): else: self._dbg(1, "tarfile: %s" % e) - def extract(self, member, path="", set_attrs=True): + def extract(self, member, path="", set_attrs=True, *, numeric_owner=False): """Extract a member from the archive to the current working directory, using its full name. Its file information is extracted as accurately as possible. `member' may be a filename or a TarInfo object. You can specify a different directory using `path'. File attributes (owner, - mtime, mode) are set unless `set_attrs' is False. + mtime, mode) are set unless `set_attrs' is False. If `numeric_owner` + is True, only the numbers for user/group names are used and not + the names. """ self._check("r") @@ -1997,7 +2038,8 @@ def extract(self, member, path="", set_attrs=True): try: self._extract_member(tarinfo, os.path.join(path, tarinfo.name), - set_attrs=set_attrs) + set_attrs=set_attrs, + numeric_owner=numeric_owner) except OSError as e: if self.errorlevel > 0: raise @@ -2043,7 +2085,8 @@ def extractfile(self, member): # blkdev, etc.), return None instead of a file object. return None - def _extract_member(self, tarinfo, targetpath, set_attrs=True): + def _extract_member(self, tarinfo, targetpath, set_attrs=True, + numeric_owner=False): """Extract the TarInfo object tarinfo to a physical file called targetpath. """ @@ -2081,7 +2124,7 @@ def _extract_member(self, tarinfo, targetpath, set_attrs=True): self.makefile(tarinfo, targetpath) if set_attrs: - self.chown(tarinfo, targetpath) + self.chown(tarinfo, targetpath, numeric_owner) if not tarinfo.issym(): self.chmod(tarinfo, targetpath) self.utime(tarinfo, targetpath) @@ -2110,9 +2153,9 @@ def makefile(self, tarinfo, targetpath): if tarinfo.sparse is not None: for offset, size in tarinfo.sparse: target.seek(offset) - copyfileobj(source, target, size) + copyfileobj(source, target, size, ReadError) else: - copyfileobj(source, target, tarinfo.size) + copyfileobj(source, target, tarinfo.size, ReadError) target.seek(tarinfo.size) target.truncate() @@ -2170,19 +2213,24 @@ def makelink(self, tarinfo, targetpath): except KeyError: raise ExtractError("unable to resolve link inside archive") - def chown(self, tarinfo, targetpath): - """Set owner of targetpath according to tarinfo. + def chown(self, tarinfo, targetpath, numeric_owner): + """Set owner of targetpath according to tarinfo. If numeric_owner + is True, use .gid/.uid instead of .gname/.uname. """ if pwd and hasattr(os, "geteuid") and os.geteuid() == 0: # We have to be root to do so. - try: - g = grp.getgrnam(tarinfo.gname)[2] - except KeyError: + if numeric_owner: g = tarinfo.gid - try: - u = pwd.getpwnam(tarinfo.uname)[2] - except KeyError: u = tarinfo.uid + else: + try: + g = grp.getgrnam(tarinfo.gname)[2] + except KeyError: + g = tarinfo.gid + try: + u = pwd.getpwnam(tarinfo.uname)[2] + except KeyError: + u = tarinfo.uid try: if tarinfo.issym() and hasattr(os, "lchown"): os.lchown(targetpath, u, g) @@ -2222,8 +2270,13 @@ def next(self): self.firstmember = None return m + # Advance the file pointer. + if self.offset != self.fileobj.tell(): + self.fileobj.seek(self.offset - 1) + if not self.fileobj.read(1): + raise ReadError("unexpected end of data") + # Read the next block. - self.fileobj.seek(self.offset) tarinfo = None while True: try: @@ -2402,7 +2455,6 @@ def is_tarfile(name): except TarError: return False -bltn_open = open open = TarFile.open @@ -2472,16 +2524,16 @@ def main(): _, ext = os.path.splitext(tar_name) compressions = { # gz - 'gz': 'gz', - 'tgz': 'gz', + '.gz': 'gz', + '.tgz': 'gz', # xz - 'xz': 'xz', - 'txz': 'xz', + '.xz': 'xz', + '.txz': 'xz', # bz2 - 'bz2': 'bz2', - 'tbz': 'bz2', - 'tbz2': 'bz2', - 'tb2': 'bz2', + '.bz2': 'bz2', + '.tbz': 'bz2', + '.tbz2': 'bz2', + '.tb2': 'bz2', } tar_mode = 'w:' + compressions[ext] if ext in compressions else 'w' tar_files = args.create diff --git a/Lib/telnetlib.py b/Lib/telnetlib.py index 0cacac85fa0e..72dabc76e0cd 100644 --- a/Lib/telnetlib.py +++ b/Lib/telnetlib.py @@ -36,10 +36,7 @@ import sys import socket import selectors -try: - from time import monotonic as _time -except ImportError: - from time import time as _time +from time import monotonic as _time __all__ = ["Telnet"] @@ -264,12 +261,13 @@ def set_debuglevel(self, debuglevel): def close(self): """Close the connection.""" - if self.sock: - self.sock.close() - self.sock = 0 - self.eof = 1 + sock = self.sock + self.sock = None + self.eof = True self.iacseq = b'' self.sb = 0 + if sock: + sock.close() def get_socket(self): """Return the socket object used internally.""" diff --git a/Lib/tempfile.py b/Lib/tempfile.py index 5d3462102f19..e87eb0933564 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -1,10 +1,18 @@ """Temporary files. This module provides generic, low- and high-level interfaces for -creating temporary files and directories. The interfaces listed -as "safe" just below can be used without fear of race conditions. -Those listed as "unsafe" cannot, and are provided for backward -compatibility only. +creating temporary files and directories. All of the interfaces +provided by this module can be used without fear of race conditions +except for 'mktemp'. 'mktemp' is subject to race conditions and +should not be used; it is provided for backward compatibility only. + +The default path names are returned as str. If you supply bytes as +input, all return values will be in bytes. Ex: + + >>> tempfile.mkstemp() + (4, '/tmp/tmptpu9nin8') + >>> tempfile.mkdtemp(suffix=b'') + b'/tmp/tmppbi8f0hy' This module also provides some data items to the user: @@ -21,18 +29,21 @@ "mkstemp", "mkdtemp", # low level safe interfaces "mktemp", # deprecated unsafe interface "TMP_MAX", "gettempprefix", # constants - "tempdir", "gettempdir" + "tempdir", "gettempdir", + "gettempprefixb", "gettempdirb", ] # Imports. +import functools as _functools import warnings as _warnings -import sys as _sys import io as _io import os as _os +import shutil as _shutil import errno as _errno from random import Random as _Random +import weakref as _weakref try: import _thread @@ -53,8 +64,10 @@ else: TMP_MAX = 10000 -# Although it does not have an underscore for historical reasons, this -# variable is an internal implementation detail (see issue 10354). +# This variable _was_ unused for legacy reasons, see issue 10354. +# But as of 3.5 we actually use it at runtime so changing it would +# have a possibly desirable side effect... But we do not want to support +# that as an API. It is undocumented on purpose. Do not depend on this. template = "tmp" # Internal routines. @@ -70,7 +83,7 @@ # file doesn't exist. def _stat(fn): fd = _os.open(fn, _os.O_RDONLY) - os.close(fd) + _os.close(fd) def _exists(fn): try: @@ -80,6 +93,46 @@ def _exists(fn): else: return True + +def _infer_return_type(*args): + """Look at the type of all args and divine their implied return type.""" + return_type = None + for arg in args: + if arg is None: + continue + if isinstance(arg, bytes): + if return_type is str: + raise TypeError("Can't mix bytes and non-bytes in " + "path components.") + return_type = bytes + else: + if return_type is bytes: + raise TypeError("Can't mix bytes and non-bytes in " + "path components.") + return_type = str + if return_type is None: + return str # tempfile APIs return a str by default. + return return_type + + +def _sanitize_params(prefix, suffix, dir): + """Common parameter processing for most APIs in this module.""" + output_type = _infer_return_type(prefix, suffix, dir) + if suffix is None: + suffix = output_type() + if prefix is None: + if output_type is str: + prefix = template + else: + prefix = _os.fsencode(template) + if dir is None: + if output_type is str: + dir = gettempdir() + else: + dir = gettempdirb() + return prefix, suffix, dir, output_type + + class _RandomNameSequence: """An instance of _RandomNameSequence generates an endless sequence of unpredictable strings which can safely be incorporated @@ -164,6 +217,13 @@ def _get_default_tempdir(): return dir except FileExistsError: pass + except PermissionError: + # This exception is thrown when a directory with the chosen name + # already exists on windows. + if (_os.name == 'nt' and _os.path.isdir(dir) and + _os.access(dir, _os.W_OK)): + continue + break # no point trying more names in this directory except OSError: break # no point trying more names in this directory raise FileNotFoundError(_errno.ENOENT, @@ -186,26 +246,29 @@ def _get_candidate_names(): return _name_sequence -def _mkstemp_inner(dir, pre, suf, flags): +def _mkstemp_inner(dir, pre, suf, flags, output_type): """Code common to mkstemp, TemporaryFile, and NamedTemporaryFile.""" names = _get_candidate_names() + if output_type is bytes: + names = map(_os.fsencode, names) for seq in range(TMP_MAX): name = next(names) file = _os.path.join(dir, pre + name + suf) try: fd = _os.open(file, flags, 0o600) - return (fd, _os.path.abspath(file)) except FileExistsError: continue # try again except PermissionError: # This exception is thrown when a directory with the chosen name # already exists on windows. - if _os.name == 'nt': + if (_os.name == 'nt' and _os.path.isdir(dir) and + _os.access(dir, _os.W_OK)): continue else: raise + return (fd, _os.path.abspath(file)) raise FileExistsError(_errno.EEXIST, "No usable temporary file name found") @@ -214,9 +277,13 @@ def _mkstemp_inner(dir, pre, suf, flags): # User visible interfaces. def gettempprefix(): - """Accessor for tempdir.template.""" + """The default prefix for temporary directories.""" return template +def gettempprefixb(): + """The default prefix for temporary directories as bytes.""" + return _os.fsencode(gettempprefix()) + tempdir = None def gettempdir(): @@ -231,7 +298,11 @@ def gettempdir(): _once_lock.release() return tempdir -def mkstemp(suffix="", prefix=template, dir=None, text=False): +def gettempdirb(): + """A bytes version of tempfile.gettempdir().""" + return _os.fsencode(gettempdir()) + +def mkstemp(suffix=None, prefix=None, dir=None, text=False): """User-callable function to create and return a unique temporary file. The return value is a pair (fd, name) where fd is the file descriptor returned by os.open, and name is the filename. @@ -249,6 +320,10 @@ def mkstemp(suffix="", prefix=template, dir=None, text=False): mode. Else (the default) the file is opened in binary mode. On some operating systems, this makes no difference. + suffix, prefix and dir must all contain the same type if specified. + If they are bytes, the returned name will be bytes; str otherwise. + A value of None will cause an appropriate default to be used. + The file is readable and writable only by the creating user ID. If the operating system uses permission bits to indicate whether a file is executable, the file is executable by no one. The file @@ -257,18 +332,17 @@ def mkstemp(suffix="", prefix=template, dir=None, text=False): Caller is responsible for deleting the file when done with it. """ - if dir is None: - dir = gettempdir() + prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) if text: flags = _text_openflags else: flags = _bin_openflags - return _mkstemp_inner(dir, prefix, suffix, flags) + return _mkstemp_inner(dir, prefix, suffix, flags, output_type) -def mkdtemp(suffix="", prefix=template, dir=None): +def mkdtemp(suffix=None, prefix=None, dir=None): """User-callable function to create and return a unique temporary directory. The return value is the pathname of the directory. @@ -281,19 +355,28 @@ def mkdtemp(suffix="", prefix=template, dir=None): Caller is responsible for deleting the directory when done with it. """ - if dir is None: - dir = gettempdir() + prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) names = _get_candidate_names() + if output_type is bytes: + names = map(_os.fsencode, names) for seq in range(TMP_MAX): name = next(names) file = _os.path.join(dir, prefix + name + suffix) try: _os.mkdir(file, 0o700) - return file except FileExistsError: continue # try again + except PermissionError: + # This exception is thrown when a directory with the chosen name + # already exists on windows. + if (_os.name == 'nt' and _os.path.isdir(dir) and + _os.access(dir, _os.W_OK)): + continue + else: + raise + return file raise FileExistsError(_errno.EEXIST, "No usable temporary directory name found") @@ -305,8 +388,8 @@ def mktemp(suffix="", prefix=template, dir=None): Arguments are as for mkstemp, except that the 'text' argument is not accepted. - This function is unsafe and should not be used. The file name - refers to a file that did not exist at some point, but by the time + THIS FUNCTION IS UNSAFE AND SHOULD NOT BE USED. The file name may + refer to a file that did not exist at some point, but by the time you get around to creating it, someone else may have beaten you to the punch. """ @@ -329,6 +412,49 @@ def mktemp(suffix="", prefix=template, dir=None): "No usable temporary filename found") +class _TemporaryFileCloser: + """A separate object allowing proper closing of a temporary file's + underlying file object, without adding a __del__ method to the + temporary file.""" + + file = None # Set here since __del__ checks it + close_called = False + + def __init__(self, file, name, delete=True): + self.file = file + self.name = name + self.delete = delete + + # NT provides delete-on-close as a primitive, so we don't need + # the wrapper to do anything special. We still use it so that + # file.name is useful (i.e. not "(fdopen)") with NamedTemporaryFile. + if _os.name != 'nt': + # Cache the unlinker so we don't get spurious errors at + # shutdown when the module-level "os" is None'd out. Note + # that this must be referenced as self.unlink, because the + # name TemporaryFileWrapper may also get None'd out before + # __del__ is called. + + def close(self, unlink=_os.unlink): + if not self.close_called and self.file is not None: + self.close_called = True + try: + self.file.close() + finally: + if self.delete: + unlink(self.name) + + # Need to ensure the file is deleted on __del__ + def __del__(self): + self.close() + + else: + def close(self): + if not self.close_called: + self.close_called = True + self.file.close() + + class _TemporaryFileWrapper: """Temporary file wrapper @@ -340,8 +466,8 @@ class _TemporaryFileWrapper: def __init__(self, file, name, delete=True): self.file = file self.name = name - self.close_called = False self.delete = delete + self._closer = _TemporaryFileCloser(file, name, delete) def __getattr__(self, name): # Attribute lookups are delegated to the underlying file @@ -349,6 +475,15 @@ def __getattr__(self, name): # (i.e. methods are cached, closed and friends are not) file = self.__dict__['file'] a = getattr(file, name) + if hasattr(a, '__call__'): + func = a + @_functools.wraps(func) + def func_wrapper(*args, **kwargs): + return func(*args, **kwargs) + # Avoid closing the file as long as the wrapper is alive, + # see issue #18879. + func_wrapper._closer = self._closer + a = func_wrapper if not isinstance(a, int): setattr(self, name, a) return a @@ -359,44 +494,32 @@ def __enter__(self): self.file.__enter__() return self - # iter() doesn't use __getattr__ to find the __iter__ method - def __iter__(self): - return iter(self.file) - - # NT provides delete-on-close as a primitive, so we don't need - # the wrapper to do anything special. We still use it so that - # file.name is useful (i.e. not "(fdopen)") with NamedTemporaryFile. - if _os.name != 'nt': - # Cache the unlinker so we don't get spurious errors at - # shutdown when the module-level "os" is None'd out. Note - # that this must be referenced as self.unlink, because the - # name TemporaryFileWrapper may also get None'd out before - # __del__ is called. - unlink = _os.unlink - - def close(self): - if not self.close_called: - self.close_called = True - self.file.close() - if self.delete: - self.unlink(self.name) + # Need to trap __exit__ as well to ensure the file gets + # deleted when used in a with statement + def __exit__(self, exc, value, tb): + result = self.file.__exit__(exc, value, tb) + self.close() + return result - def __del__(self): - self.close() + def close(self): + """ + Close the temporary file, possibly deleting it. + """ + self._closer.close() - # Need to trap __exit__ as well to ensure the file gets - # deleted when used in a with statement - def __exit__(self, exc, value, tb): - result = self.file.__exit__(exc, value, tb) - self.close() - return result - else: - def __exit__(self, exc, value, tb): - self.file.__exit__(exc, value, tb) + # iter() doesn't use __getattr__ to find the __iter__ method + def __iter__(self): + # Don't return iter(self.file), but yield from it to avoid closing + # file as long as it's being used as iterator (see issue #23700). We + # can't use 'yield from' here because iter(file) returns the file + # object itself, which has a close method, and thus the file would get + # closed when the generator is finalized, due to PEP380 semantics. + for line in self.file: + yield line def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, - newline=None, suffix="", prefix=template, + newline=None, suffix=None, prefix=None, dir=None, delete=True): """Create and return a temporary file. Arguments: @@ -413,8 +536,7 @@ def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, when it is closed unless the 'delete' argument is set to False. """ - if dir is None: - dir = gettempdir() + prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) flags = _bin_openflags @@ -423,11 +545,15 @@ def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, if _os.name == 'nt' and delete: flags |= _os.O_TEMPORARY - (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags) - file = _io.open(fd, mode, buffering=buffering, - newline=newline, encoding=encoding) + (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags, output_type) + try: + file = _io.open(fd, mode, buffering=buffering, + newline=newline, encoding=encoding) - return _TemporaryFileWrapper(file, name, delete) + return _TemporaryFileWrapper(file, name, delete) + except Exception: + _os.close(fd) + raise if _os.name != 'posix' or _os.sys.platform == 'cygwin': # On non-POSIX and Cygwin systems, assume that we cannot unlink a file @@ -435,8 +561,13 @@ def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, TemporaryFile = NamedTemporaryFile else: + # Is the O_TMPFILE flag available and does it work? + # The flag is set to False if os.open(dir, os.O_TMPFILE) raises an + # IsADirectoryError exception + _O_TMPFILE_WORKS = hasattr(_os, 'O_TMPFILE') + def TemporaryFile(mode='w+b', buffering=-1, encoding=None, - newline=None, suffix="", prefix=template, + newline=None, suffix=None, prefix=None, dir=None): """Create and return a temporary file. Arguments: @@ -450,13 +581,41 @@ def TemporaryFile(mode='w+b', buffering=-1, encoding=None, Returns an object with a file-like interface. The file has no name, and will cease to exist when it is closed. """ + global _O_TMPFILE_WORKS - if dir is None: - dir = gettempdir() + prefix, suffix, dir, output_type = _sanitize_params(prefix, suffix, dir) flags = _bin_openflags + if _O_TMPFILE_WORKS: + try: + flags2 = (flags | _os.O_TMPFILE) & ~_os.O_CREAT + fd = _os.open(dir, flags2, 0o600) + except IsADirectoryError: + # Linux kernel older than 3.11 ignores the O_TMPFILE flag: + # O_TMPFILE is read as O_DIRECTORY. Trying to open a directory + # with O_RDWR|O_DIRECTORY fails with IsADirectoryError, a + # directory cannot be open to write. Set flag to False to not + # try again. + _O_TMPFILE_WORKS = False + except OSError: + # The filesystem of the directory does not support O_TMPFILE. + # For example, OSError(95, 'Operation not supported'). + # + # On Linux kernel older than 3.11, trying to open a regular + # file (or a symbolic link to a regular file) with O_TMPFILE + # fails with NotADirectoryError, because O_TMPFILE is read as + # O_DIRECTORY. + pass + else: + try: + return _io.open(fd, mode, buffering=buffering, + newline=newline, encoding=encoding) + except: + _os.close(fd) + raise + # Fallback to _mkstemp_inner(). - (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags) + (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags, output_type) try: _os.unlink(name) return _io.open(fd, mode, buffering=buffering, @@ -474,13 +633,13 @@ class SpooledTemporaryFile: def __init__(self, max_size=0, mode='w+b', buffering=-1, encoding=None, newline=None, - suffix="", prefix=template, dir=None): + suffix=None, prefix=None, dir=None): if 'b' in mode: self._file = _io.BytesIO() else: # Setting newline="\n" avoids newline translation; # this is important because otherwise on Windows we'd - # hget double newline translation upon rollover(). + # get double newline translation upon rollover(). self._file = _io.StringIO(newline="\n") self._max_size = max_size self._rolled = False @@ -625,10 +784,17 @@ class TemporaryDirectory(object): in it are removed. """ - def __init__(self, suffix="", prefix=template, dir=None): - self._closed = False - self.name = None # Handle mkdtemp raising an exception + def __init__(self, suffix=None, prefix=None, dir=None): self.name = mkdtemp(suffix, prefix, dir) + self._finalizer = _weakref.finalize( + self, self._cleanup, self.name, + warn_message="Implicitly cleaning up {!r}".format(self)) + + @classmethod + def _cleanup(cls, name, warn_message): + _shutil.rmtree(name) + _warnings.warn(warn_message, ResourceWarning) + def __repr__(self): return "<{} {!r}>".format(self.__class__.__name__, self.name) @@ -636,60 +802,9 @@ def __repr__(self): def __enter__(self): return self.name - def cleanup(self, _warn=False): - if self.name and not self._closed: - try: - self._rmtree(self.name) - except (TypeError, AttributeError) as ex: - # Issue #10188: Emit a warning on stderr - # if the directory could not be cleaned - # up due to missing globals - if "None" not in str(ex): - raise - print("ERROR: {!r} while cleaning up {!r}".format(ex, self,), - file=_sys.stderr) - return - self._closed = True - if _warn: - self._warn("Implicitly cleaning up {!r}".format(self), - ResourceWarning) - def __exit__(self, exc, value, tb): self.cleanup() - def __del__(self): - # Issue a ResourceWarning if implicit cleanup needed - self.cleanup(_warn=True) - - # XXX (ncoghlan): The following code attempts to make - # this class tolerant of the module nulling out process - # that happens during CPython interpreter shutdown - # Alas, it doesn't actually manage it. See issue #10188 - _listdir = staticmethod(_os.listdir) - _path_join = staticmethod(_os.path.join) - _isdir = staticmethod(_os.path.isdir) - _islink = staticmethod(_os.path.islink) - _remove = staticmethod(_os.remove) - _rmdir = staticmethod(_os.rmdir) - _warn = _warnings.warn - - def _rmtree(self, path): - # Essentially a stripped down version of shutil.rmtree. We can't - # use globals because they may be None'ed out at shutdown. - for name in self._listdir(path): - fullname = self._path_join(path, name) - try: - isdir = self._isdir(fullname) and not self._islink(fullname) - except OSError: - isdir = False - if isdir: - self._rmtree(fullname) - else: - try: - self._remove(fullname) - except OSError: - pass - try: - self._rmdir(path) - except OSError: - pass + def cleanup(self): + if self._finalizer.detach(): + _shutil.rmtree(self.name) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index bd26e3d3f2ca..e9120abe5d9c 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 - # # Unit tests for the multiprocessing package # @@ -21,7 +19,7 @@ import struct import operator import test.support -import test.script_helper +import test.support.script_helper # Skip tests if _multiprocessing wasn't built. @@ -198,7 +196,7 @@ class _TestProcess(BaseTestCase): def test_current(self): if self.TYPE == 'threads': - return + self.skipTest('test not appropriate for {}'.format(self.TYPE)) current = self.current_process() authkey = current.authkey @@ -212,7 +210,7 @@ def test_current(self): def test_daemon_argument(self): if self.TYPE == "threads": - return + self.skipTest('test not appropriate for {}'.format(self.TYPE)) # By default uses the current process's daemon flag. proc0 = self.Process(target=self._test) @@ -277,7 +275,7 @@ def _test_terminate(cls): def test_terminate(self): if self.TYPE == 'threads': - return + self.skipTest('test not appropriate for {}'.format(self.TYPE)) p = self.Process(target=self._test_terminate) p.daemon = True @@ -385,7 +383,7 @@ def _test_sentinel(cls, event): def test_sentinel(self): if self.TYPE == "threads": - return + self.skipTest('test not appropriate for {}'.format(self.TYPE)) event = self.Event() p = self.Process(target=self._test_sentinel, args=(event,)) with self.assertRaises(ValueError): @@ -441,7 +439,7 @@ def test_subclassing(self): def test_stderr_flush(self): # sys.stderr is flushed at process shutdown (issue #13812) if self.TYPE == "threads": - return + self.skipTest('test not appropriate for {}'.format(self.TYPE)) testfn = test.support.TESTFN self.addCleanup(test.support.unlink, testfn) @@ -469,7 +467,7 @@ def _test_sys_exit(cls, reason, testfn): def test_sys_exit(self): # See Issue 13854 if self.TYPE == 'threads': - return + self.skipTest('test not appropriate for {}'.format(self.TYPE)) testfn = test.support.TESTFN self.addCleanup(test.support.unlink, testfn) @@ -678,7 +676,7 @@ def test_qsize(self): try: self.assertEqual(q.qsize(), 0) except NotImplementedError: - return + self.skipTest('qsize method not implemented') q.put(1) self.assertEqual(q.qsize(), 1) q.put(5) @@ -697,9 +695,6 @@ def _test_task_done(cls, q): def test_task_done(self): queue = self.JoinableQueue() - if sys.version_info < (2, 5) and not hasattr(queue, 'task_done'): - self.skipTest("requires 'queue.task_done()' method") - workers = [self.Process(target=self._test_task_done, args=(queue,)) for i in range(4)] @@ -718,12 +713,35 @@ def test_task_done(self): for p in workers: p.join() + def test_no_import_lock_contention(self): + with test.support.temp_cwd(): + module_name = 'imported_by_an_imported_module' + with open(module_name + '.py', 'w') as f: + f.write("""if 1: + import multiprocessing + + q = multiprocessing.Queue() + q.put('knock knock') + q.get(timeout=3) + q.close() + del q + """) + + with test.support.DirsOnSysPath(os.getcwd()): + try: + __import__(module_name) + except pyqueue.Empty: + self.fail("Probable regression on import lock contention;" + " see Issue #22853") + def test_timeout(self): q = multiprocessing.Queue() start = time.time() - self.assertRaises(pyqueue.Empty, q.get, True, 0.2) + self.assertRaises(pyqueue.Empty, q.get, True, 0.200) delta = time.time() - start - self.assertGreaterEqual(delta, 0.18) + # Tolerate a delta of 30 ms because of the bad clock resolution on + # Windows (usually 15.6 ms) + self.assertGreaterEqual(delta, 0.170) # # @@ -786,7 +804,7 @@ def test_bounded_semaphore(self): def test_timeout(self): if self.TYPE != 'processes': - return + self.skipTest('test not appropriate for {}'.format(self.TYPE)) sem = self.Semaphore(0) acquire = TimingWrapper(sem.acquire) @@ -1406,7 +1424,7 @@ def _test_thousand_f(cls, barrier, passes, conn, lock): def test_thousand(self): if self.TYPE == 'manager': - return + self.skipTest('test not appropriate for {}'.format(self.TYPE)) passes = 1000 lock = self.Lock() conn, child_conn = self.Pipe(False) @@ -1642,6 +1660,14 @@ def sqr(x, wait=0.0): def mul(x, y): return x*y +class SayWhenError(ValueError): pass + +def exception_throwing_generator(total, when): + for i in range(total): + if i == when: + raise SayWhenError("Somebody said when") + yield i + class _TestPool(BaseTestCase): @classmethod @@ -1701,7 +1727,7 @@ def test_map_async_callbacks(self): def test_map_unplicklable(self): # Issue #19425 -- failure to pickle should not cause a hang if self.TYPE == 'threads': - return + self.skipTest('test not appropriate for {}'.format(self.TYPE)) class A(object): def __reduce__(self): raise RuntimeError('cannot pickle') @@ -1740,6 +1766,25 @@ def test_imap(self): self.assertEqual(next(it), i*i) self.assertRaises(StopIteration, it.__next__) + def test_imap_handle_iterable_exception(self): + if self.TYPE == 'manager': + self.skipTest('test not appropriate for {}'.format(self.TYPE)) + + it = self.pool.imap(sqr, exception_throwing_generator(10, 3), 1) + for i in range(3): + self.assertEqual(next(it), i*i) + self.assertRaises(SayWhenError, it.__next__) + + # SayWhenError seen at start of problematic chunk's results + it = self.pool.imap(sqr, exception_throwing_generator(20, 7), 2) + for i in range(6): + self.assertEqual(next(it), i*i) + self.assertRaises(SayWhenError, it.__next__) + it = self.pool.imap(sqr, exception_throwing_generator(20, 7), 4) + for i in range(4): + self.assertEqual(next(it), i*i) + self.assertRaises(SayWhenError, it.__next__) + def test_imap_unordered(self): it = self.pool.imap_unordered(sqr, list(range(1000))) self.assertEqual(sorted(it), list(map(sqr, list(range(1000))))) @@ -1747,6 +1792,31 @@ def test_imap_unordered(self): it = self.pool.imap_unordered(sqr, list(range(1000)), chunksize=53) self.assertEqual(sorted(it), list(map(sqr, list(range(1000))))) + def test_imap_unordered_handle_iterable_exception(self): + if self.TYPE == 'manager': + self.skipTest('test not appropriate for {}'.format(self.TYPE)) + + it = self.pool.imap_unordered(sqr, + exception_throwing_generator(10, 3), + 1) + expected_values = list(map(sqr, list(range(10)))) + with self.assertRaises(SayWhenError): + # imap_unordered makes it difficult to anticipate the SayWhenError + for i in range(10): + value = next(it) + self.assertIn(value, expected_values) + expected_values.remove(value) + + it = self.pool.imap_unordered(sqr, + exception_throwing_generator(20, 7), + 2) + expected_values = list(map(sqr, list(range(20)))) + with self.assertRaises(SayWhenError): + for i in range(20): + value = next(it) + self.assertIn(value, expected_values) + expected_values.remove(value) + def test_make_pool(self): self.assertRaises(ValueError, multiprocessing.Pool, -1) self.assertRaises(ValueError, multiprocessing.Pool, 0) @@ -1815,6 +1885,17 @@ def test_traceback(self): self.assertIn('raise RuntimeError(123) # some comment', f1.getvalue()) + @classmethod + def _test_wrapped_exception(cls): + raise RuntimeError('foo') + + def test_wrapped_exception(self): + # Issue #20980: Should not wrap exception when using thread pool + with self.Pool(1) as p: + with self.assertRaises(RuntimeError): + p.apply(self._test_wrapped_exception) + + def raising(): raise KeyError("key") @@ -2012,6 +2093,12 @@ class QueueManager2(BaseManager): class _TestRemoteManager(BaseTestCase): ALLOWED_TYPES = ('manager',) + values = ['hello world', None, True, 2.25, + 'hall\xe5 v\xe4rlden', + '\u043f\u0440\u0438\u0432\u0456\u0442 \u0441\u0432\u0456\u0442', + b'hall\xe5 v\xe4rlden', + ] + result = values[:] @classmethod def _putter(cls, address, authkey): @@ -2020,7 +2107,8 @@ def _putter(cls, address, authkey): ) manager.connect() queue = manager.get_queue() - queue.put(('hello world', None, True, 2.25)) + # Note that xmlrpclib will deserialize object as a list not a tuple + queue.put(tuple(cls.values)) def test_remote(self): authkey = os.urandom(32) @@ -2040,8 +2128,7 @@ def test_remote(self): manager2.connect() queue = manager2.get_queue() - # Note that xmlrpclib will deserialize object as a list not a tuple - self.assertEqual(queue.get(), ['hello world', None, True, 2.25]) + self.assertEqual(queue.get(), self.result) # Because we are using xmlrpclib for serialization instead of # pickle this will cause a serialization error. @@ -2224,7 +2311,7 @@ def test_spawn_close(self): def test_sendbytes(self): if self.TYPE != 'processes': - return + self.skipTest('test not appropriate for {}'.format(self.TYPE)) msg = latin('abcdefghijklmnopqrstuvwxyz') a, b = self.Pipe() @@ -2537,7 +2624,7 @@ def _listener(cls, conn, families): l = socket.socket() l.bind((test.support.HOST, 0)) - l.listen(1) + l.listen() conn.send(l.getsockname()) new_conn, addr = l.accept() conn.send(new_conn) @@ -3184,7 +3271,7 @@ def test_wait_socket(self, slow=False): from multiprocessing.connection import wait l = socket.socket() l.bind((test.support.HOST, 0)) - l.listen(4) + l.listen() addr = l.getsockname() readers = [] procs = [] @@ -3396,13 +3483,13 @@ def test_noforkbomb(self): sm = multiprocessing.get_start_method() name = os.path.join(os.path.dirname(__file__), 'mp_fork_bomb.py') if sm != 'fork': - rc, out, err = test.script_helper.assert_python_failure(name, sm) - self.assertEqual('', out.decode('ascii')) - self.assertIn('RuntimeError', err.decode('ascii')) + rc, out, err = test.support.script_helper.assert_python_failure(name, sm) + self.assertEqual(out, b'') + self.assertIn(b'RuntimeError', err) else: - rc, out, err = test.script_helper.assert_python_ok(name, sm) - self.assertEqual('123', out.decode('ascii').rstrip()) - self.assertEqual('', err.decode('ascii')) + rc, out, err = test.support.script_helper.assert_python_ok(name, sm) + self.assertEqual(out.rstrip(), b'123') + self.assertEqual(err, b'') # # Issue #17555: ForkAwareThreadLock @@ -3656,7 +3743,7 @@ def test_semaphore_tracker(self): _multiprocessing.sem_unlink(name1) p.terminate() p.wait() - time.sleep(1.0) + time.sleep(2.0) with self.assertRaises(OSError) as ctx: _multiprocessing.sem_unlink(name2) # docs say it should be ENOENT, but OSX seems to give EINVAL diff --git a/Lib/test/audiotests.py b/Lib/test/audiotests.py index b7497ce5b06d..0ae22428512d 100644 --- a/Lib/test/audiotests.py +++ b/Lib/test/audiotests.py @@ -45,8 +45,9 @@ def check_params(self, f, nchannels, sampwidth, framerate, nframes, self.assertEqual(params.comptype, comptype) self.assertEqual(params.compname, compname) - dump = pickle.dumps(params) - self.assertEqual(pickle.loads(dump), params) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + dump = pickle.dumps(params, proto) + self.assertEqual(pickle.loads(dump), params) class AudioWriteTests(AudioTests): diff --git a/Lib/test/badsyntax_async1.py b/Lib/test/badsyntax_async1.py new file mode 100644 index 000000000000..fb85e2905213 --- /dev/null +++ b/Lib/test/badsyntax_async1.py @@ -0,0 +1,2 @@ +async def foo(a=await something()): + pass diff --git a/Lib/test/badsyntax_async2.py b/Lib/test/badsyntax_async2.py new file mode 100644 index 000000000000..fb85e2905213 --- /dev/null +++ b/Lib/test/badsyntax_async2.py @@ -0,0 +1,2 @@ +async def foo(a=await something()): + pass diff --git a/Lib/test/badsyntax_async3.py b/Lib/test/badsyntax_async3.py new file mode 100644 index 000000000000..dde1bc595578 --- /dev/null +++ b/Lib/test/badsyntax_async3.py @@ -0,0 +1,2 @@ +async def foo(): + [i async for i in els] diff --git a/Lib/test/badsyntax_async4.py b/Lib/test/badsyntax_async4.py new file mode 100644 index 000000000000..d033b2811482 --- /dev/null +++ b/Lib/test/badsyntax_async4.py @@ -0,0 +1,2 @@ +async def foo(): + await diff --git a/Lib/test/badsyntax_async5.py b/Lib/test/badsyntax_async5.py new file mode 100644 index 000000000000..9d19af6109cf --- /dev/null +++ b/Lib/test/badsyntax_async5.py @@ -0,0 +1,2 @@ +def foo(): + await something() diff --git a/Lib/test/badsyntax_async6.py b/Lib/test/badsyntax_async6.py new file mode 100644 index 000000000000..cb0a23d5f0c9 --- /dev/null +++ b/Lib/test/badsyntax_async6.py @@ -0,0 +1,2 @@ +async def foo(): + yield diff --git a/Lib/test/badsyntax_async7.py b/Lib/test/badsyntax_async7.py new file mode 100644 index 000000000000..51e4bf9b5b23 --- /dev/null +++ b/Lib/test/badsyntax_async7.py @@ -0,0 +1,2 @@ +async def foo(): + yield from [] diff --git a/Lib/test/badsyntax_async8.py b/Lib/test/badsyntax_async8.py new file mode 100644 index 000000000000..3c636f9ac4ad --- /dev/null +++ b/Lib/test/badsyntax_async8.py @@ -0,0 +1,2 @@ +async def foo(): + await await fut diff --git a/Lib/test/coding20731.py b/Lib/test/coding20731.py new file mode 100644 index 000000000000..b0e227ad110e --- /dev/null +++ b/Lib/test/coding20731.py @@ -0,0 +1,4 @@ +#coding:latin1 + + + diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index b67d28c8b66d..11deffccd7a7 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -3,8 +3,10 @@ See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases """ +import decimal import sys import pickle +import random import unittest from operator import lt, le, gt, ge, eq, ne, truediv, floordiv, mod @@ -49,6 +51,44 @@ def test_constants(self): self.assertEqual(datetime.MINYEAR, 1) self.assertEqual(datetime.MAXYEAR, 9999) + def test_name_cleanup(self): + if '_Fast' not in str(self): + return + datetime = datetime_module + names = set(name for name in dir(datetime) + if not name.startswith('__') and not name.endswith('__')) + allowed = set(['MAXYEAR', 'MINYEAR', 'date', 'datetime', + 'datetime_CAPI', 'time', 'timedelta', 'timezone', + 'tzinfo']) + self.assertEqual(names - allowed, set([])) + + def test_divide_and_round(self): + if '_Fast' in str(self): + return + dar = datetime_module._divide_and_round + + self.assertEqual(dar(-10, -3), 3) + self.assertEqual(dar(5, -2), -2) + + # four cases: (2 signs of a) x (2 signs of b) + self.assertEqual(dar(7, 3), 2) + self.assertEqual(dar(-7, 3), -2) + self.assertEqual(dar(7, -3), -2) + self.assertEqual(dar(-7, -3), 2) + + # ties to even - eight cases: + # (2 signs of a) x (2 signs of b) x (even / odd quotient) + self.assertEqual(dar(10, 4), 2) + self.assertEqual(dar(-10, 4), -2) + self.assertEqual(dar(10, -4), -2) + self.assertEqual(dar(-10, -4), 2) + + self.assertEqual(dar(6, 4), 2) + self.assertEqual(dar(-6, 4), -2) + self.assertEqual(dar(6, -4), -2) + self.assertEqual(dar(-6, -4), 2) + + ############################################################################# # tzinfo tests @@ -76,8 +116,18 @@ class PicklableFixedOffset(FixedOffset): def __init__(self, offset=None, name=None, dstoffset=None): FixedOffset.__init__(self, offset, name, dstoffset) +class _TZInfo(tzinfo): + def utcoffset(self, datetime_module): + return random.random() + class TestTZInfo(unittest.TestCase): + def test_refcnt_crash_bug_22044(self): + tz1 = _TZInfo() + dt1 = datetime(2014, 7, 21, 11, 32, 3, 0, tz1) + with self.assertRaises(TypeError): + dt1.utcoffset() + def test_non_abstractness(self): # In order to allow subclasses to get pickled, the C implementation # wasn't able to get away with having __init__ raise @@ -142,6 +192,29 @@ def test_pickling_subclass(self): self.assertEqual(derived.utcoffset(None), offset) self.assertEqual(derived.tzname(None), oname) + def test_issue23600(self): + DSTDIFF = DSTOFFSET = timedelta(hours=1) + + class UKSummerTime(tzinfo): + """Simple time zone which pretends to always be in summer time, since + that's what shows the failure. + """ + + def utcoffset(self, dt): + return DSTOFFSET + + def dst(self, dt): + return DSTDIFF + + def tzname(self, dt): + return 'UKSummerTime' + + tz = UKSummerTime() + u = datetime(2014, 4, 26, 12, 1, tzinfo=tz) + t = tz.fromutc(u) + self.assertEqual(t - t.utcoffset(), u) + + class TestTimeZone(unittest.TestCase): def setUp(self): @@ -208,7 +281,8 @@ def test_dst(self): with self.assertRaises(TypeError): self.EST.dst(5) def test_tzname(self): - self.assertEqual('UTC+00:00', timezone(ZERO).tzname(None)) + self.assertEqual('UTC', timezone.utc.tzname(None)) + self.assertEqual('UTC', timezone(ZERO).tzname(None)) self.assertEqual('UTC-05:00', timezone(-5 * HOUR).tzname(None)) self.assertEqual('UTC+09:30', timezone(9.5 * HOUR).tzname(None)) self.assertEqual('UTC-00:01', timezone(timedelta(minutes=-1)).tzname(None)) @@ -371,6 +445,10 @@ def test_computations(self): eq((-3*us) * 0.5, -2*us) eq((-5*us) * 0.5, -2*us) + # Issue #23521 + eq(td(seconds=1) * 0.123456, td(microseconds=123456)) + eq(td(seconds=1) * 0.6112295, td(microseconds=611229)) + # Division by int and float eq((3*us) / 2, 2*us) eq((5*us) / 2, 2*us) @@ -385,6 +463,9 @@ def test_computations(self): for i in range(-10, 10): eq((i*us/-3)//us, round(i/-3)) + # Issue #23521 + eq(td(seconds=1) / (1 / 0.6112295), td(microseconds=611229)) + # Issue #11576 eq(td(999999999, 86399, 999999) - td(999999999, 86399, 999998), td(0, 0, 1)) @@ -605,8 +686,16 @@ def test_microsecond_rounding(self): # Single-field rounding. eq(td(milliseconds=0.4/1000), td(0)) # rounds to 0 eq(td(milliseconds=-0.4/1000), td(0)) # rounds to 0 + eq(td(milliseconds=0.5/1000), td(microseconds=0)) + eq(td(milliseconds=-0.5/1000), td(microseconds=-0)) eq(td(milliseconds=0.6/1000), td(microseconds=1)) eq(td(milliseconds=-0.6/1000), td(microseconds=-1)) + eq(td(milliseconds=1.5/1000), td(microseconds=2)) + eq(td(milliseconds=-1.5/1000), td(microseconds=-2)) + eq(td(seconds=0.5/10**6), td(microseconds=0)) + eq(td(seconds=-0.5/10**6), td(microseconds=-0)) + eq(td(seconds=1/2**7), td(microseconds=7812)) + eq(td(seconds=-1/2**7), td(microseconds=-7812)) # Rounding due to contributions from more than one field. us_per_hour = 3600e6 @@ -1120,11 +1209,13 @@ def test_strftime(self): #check that this standard extension works t.strftime("%f") - def test_format(self): dt = self.theclass(2007, 9, 10) self.assertEqual(dt.__format__(''), str(dt)) + with self.assertRaisesRegex(TypeError, '^must be str, not int$'): + dt.__format__(123) + # check that a derived class's __str__() gets called class A(self.theclass): def __str__(self): @@ -1276,8 +1367,6 @@ def __le__(self, other): return isinstance(other, LargerThanAnything) def __eq__(self, other): return isinstance(other, LargerThanAnything) - def __ne__(self, other): - return not isinstance(other, LargerThanAnything) def __gt__(self, other): return not isinstance(other, LargerThanAnything) def __ge__(self, other): @@ -1380,9 +1469,10 @@ def test_backdoor_resistance(self): for month_byte in b'9', b'\0', b'\r', b'\xff': self.assertRaises(TypeError, self.theclass, base[:2] + month_byte + base[3:]) - # Good bytes, but bad tzinfo: - self.assertRaises(TypeError, self.theclass, - bytes([1] * len(base)), 'EST') + if issubclass(self.theclass, datetime): + # Good bytes, but bad tzinfo: + with self.assertRaisesRegex(TypeError, '^bad tzinfo state arg$'): + self.theclass(bytes([1] * len(base)), 'EST') for ord_byte in range(1, 13): # This shouldn't blow up because of the month byte alone. If @@ -1458,6 +1548,9 @@ def test_format(self): dt = self.theclass(2007, 9, 10, 4, 5, 1, 123) self.assertEqual(dt.__format__(''), str(dt)) + with self.assertRaisesRegex(TypeError, '^must be str, not int$'): + dt.__format__(123) + # check that a derived class's __str__() gets called class A(self.theclass): def __str__(self): @@ -1671,11 +1764,12 @@ def test_pickling(self): def test_more_pickling(self): a = self.theclass(2003, 2, 7, 16, 48, 37, 444116) - s = pickle.dumps(a) - b = pickle.loads(s) - self.assertEqual(b.year, 2003) - self.assertEqual(b.month, 2) - self.assertEqual(b.day, 7) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + s = pickle.dumps(a, proto) + b = pickle.loads(s) + self.assertEqual(b.year, 2003) + self.assertEqual(b.month, 2) + self.assertEqual(b.day, 7) def test_pickling_subclass_datetime(self): args = 6, 7, 23, 20, 59, 1, 64**2 @@ -1778,12 +1872,14 @@ def test_timestamp_aware(self): tzinfo=timezone(timedelta(hours=-5), 'EST')) self.assertEqual(t.timestamp(), 18000 + 3600 + 2*60 + 3 + 4*1e-6) + def test_microsecond_rounding(self): for fts in [self.theclass.fromtimestamp, self.theclass.utcfromtimestamp]: zero = fts(0) self.assertEqual(zero.second, 0) self.assertEqual(zero.microsecond, 0) + one = fts(1e-6) try: minus_one = fts(-1e-6) except OSError: @@ -1794,22 +1890,28 @@ def test_microsecond_rounding(self): self.assertEqual(minus_one.microsecond, 999999) t = fts(-1e-8) - self.assertEqual(t, minus_one) + self.assertEqual(t, zero) t = fts(-9e-7) self.assertEqual(t, minus_one) t = fts(-1e-7) - self.assertEqual(t, minus_one) + self.assertEqual(t, zero) + t = fts(-1/2**7) + self.assertEqual(t.second, 59) + self.assertEqual(t.microsecond, 992188) t = fts(1e-7) self.assertEqual(t, zero) t = fts(9e-7) - self.assertEqual(t, zero) + self.assertEqual(t, one) t = fts(0.99999949) self.assertEqual(t.second, 0) self.assertEqual(t.microsecond, 999999) t = fts(0.9999999) + self.assertEqual(t.second, 1) + self.assertEqual(t.microsecond, 0) + t = fts(1/2**7) self.assertEqual(t.second, 0) - self.assertEqual(t.microsecond, 999999) + self.assertEqual(t.microsecond, 7812) def test_insane_fromtimestamp(self): # It's possible that some platform maps time_t to double, @@ -1828,6 +1930,7 @@ def test_insane_utcfromtimestamp(self): for insane in -1e200, 1e200: self.assertRaises(OverflowError, self.theclass.utcfromtimestamp, insane) + @unittest.skipIf(sys.platform == "win32", "Windows doesn't accept negative timestamps") def test_negative_float_fromtimestamp(self): # The result is tz-dependent; at least test that this doesn't @@ -2029,6 +2132,7 @@ def newmeth(self, start): class TestSubclassDateTime(TestDateTime): theclass = SubclassDatetime # Override tests not designed for subclass + @unittest.skip('not appropriate for subclasses') def test_roundtrip(self): pass @@ -2206,6 +2310,9 @@ def test_format(self): t = self.theclass(1, 2, 3, 4) self.assertEqual(t.__format__(''), str(t)) + with self.assertRaisesRegex(TypeError, '^must be str, not int$'): + t.__format__(123) + # check that a derived class's __str__() gets called class A(self.theclass): def __str__(self): @@ -2269,13 +2376,14 @@ def test_pickling_subclass_time(self): self.assertEqual(orig, derived) def test_bool(self): + # time is always True. cls = self.theclass self.assertTrue(cls(1)) self.assertTrue(cls(0, 1)) self.assertTrue(cls(0, 0, 1)) self.assertTrue(cls(0, 0, 0, 1)) - self.assertFalse(cls(0)) - self.assertFalse(cls()) + self.assertTrue(cls(0)) + self.assertTrue(cls()) def test_replace(self): cls = self.theclass @@ -2334,6 +2442,9 @@ def test_backdoor_resistance(self): for hour_byte in ' ', '9', chr(24), '\xff': self.assertRaises(TypeError, self.theclass, hour_byte + base[1:]) + # Good bytes, but bad tzinfo: + with self.assertRaisesRegex(TypeError, '^bad tzinfo state arg$'): + self.theclass(bytes([1] * len(base)), 'EST') # A mixin for classes with a tzinfo= argument. Subclasses must define # theclass as a class atribute, and theclass(1, 1, 1, tzinfo=whatever) @@ -2593,7 +2704,7 @@ def tzname(self, dt): return self.tz self.assertRaises(TypeError, t.strftime, "%Z") # Issue #6697: - if '_Fast' in str(type(self)): + if '_Fast' in str(self): Badtzname.tz = '\ud800' self.assertRaises(ValueError, t.strftime, "%Z") @@ -2628,7 +2739,7 @@ def test_pickling(self): self.assertEqual(derived.tzname(), 'cookie') def test_more_bool(self): - # Test cases with non-None tzinfo. + # time is always True. cls = self.theclass t = cls(0, tzinfo=FixedOffset(-300, "")) @@ -2638,23 +2749,11 @@ def test_more_bool(self): self.assertTrue(t) t = cls(5, tzinfo=FixedOffset(300, "")) - self.assertFalse(t) + self.assertTrue(t) t = cls(23, 59, tzinfo=FixedOffset(23*60 + 59, "")) - self.assertFalse(t) - - # Mostly ensuring this doesn't overflow internally. - t = cls(0, tzinfo=FixedOffset(23*60 + 59, "")) self.assertTrue(t) - # But this should yield a value error -- the utcoffset is bogus. - t = cls(0, tzinfo=FixedOffset(24*60, "")) - self.assertRaises(ValueError, lambda: bool(t)) - - # Likewise. - t = cls(0, tzinfo=FixedOffset(-24*60, "")) - self.assertRaises(ValueError, lambda: bool(t)) - def test_replace(self): cls = self.theclass z100 = FixedOffset(100, "+100") @@ -3767,8 +3866,59 @@ def test_bug_1028306(self): self.assertEqual(as_datetime, datetime_sc) self.assertEqual(datetime_sc, as_datetime) -def test_main(): - support.run_unittest(__name__) + def test_extra_attributes(self): + for x in [date.today(), + time(), + datetime.utcnow(), + timedelta(), + tzinfo(), + timezone(timedelta())]: + with self.assertRaises(AttributeError): + x.abc = 1 + + def test_check_arg_types(self): + class Number: + def __init__(self, value): + self.value = value + def __int__(self): + return self.value + + for xx in [decimal.Decimal(10), + decimal.Decimal('10.9'), + Number(10)]: + self.assertEqual(datetime(10, 10, 10, 10, 10, 10, 10), + datetime(xx, xx, xx, xx, xx, xx, xx)) + + with self.assertRaisesRegex(TypeError, '^an integer is required ' + '\(got type str\)$'): + datetime(10, 10, '10') + + f10 = Number(10.9) + with self.assertRaisesRegex(TypeError, '^__int__ returned non-int ' + '\(type float\)$'): + datetime(10, 10, f10) + + class Float(float): + pass + s10 = Float(10.9) + with self.assertRaisesRegex(TypeError, '^integer argument expected, ' + 'got float$'): + datetime(10, 10, s10) + + with self.assertRaises(TypeError): + datetime(10., 10, 10) + with self.assertRaises(TypeError): + datetime(10, 10., 10) + with self.assertRaises(TypeError): + datetime(10, 10, 10.) + with self.assertRaises(TypeError): + datetime(10, 10, 10, 10.) + with self.assertRaises(TypeError): + datetime(10, 10, 10, 10, 10.) + with self.assertRaises(TypeError): + datetime(10, 10, 10, 10, 10, 10.) + with self.assertRaises(TypeError): + datetime(10, 10, 10, 10, 10, 10, 10.) if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/decimaltestdata/exp.decTest b/Lib/test/decimaltestdata/exp.decTest index 021b478ac2e2..6a7af23b6255 100644 --- a/Lib/test/decimaltestdata/exp.decTest +++ b/Lib/test/decimaltestdata/exp.decTest @@ -19,7 +19,7 @@ ------------------------------------------------------------------------ version: 2.59 --- Tests of the exponential funtion. Currently all testcases here +-- Tests of the exponential function. Currently all testcases here -- show results which are correctly rounded (within <= 0.5 ulp). extended: 1 diff --git a/Lib/test/dh1024.pem b/Lib/test/dh1024.pem new file mode 100644 index 000000000000..a391176b5fea --- /dev/null +++ b/Lib/test/dh1024.pem @@ -0,0 +1,7 @@ +-----BEGIN DH PARAMETERS----- +MIGHAoGBAIbzw1s9CT8SV5yv6L7esdAdZYZjPi3qWFs61CYTFFQnf2s/d09NYaJt +rrvJhIzWavqnue71qXCf83/J3nz3FEwUU/L0mGyheVbsSHiI64wUo3u50wK5Igo0 +RNs/LD0irs7m0icZ//hijafTU+JOBiuA8zMI+oZfU7BGuc9XrUprAgEC +-----END DH PARAMETERS----- + +Generated with: openssl dhparam -out dh1024.pem 1024 diff --git a/Lib/test/dh512.pem b/Lib/test/dh512.pem deleted file mode 100644 index 200d16cd8971..000000000000 --- a/Lib/test/dh512.pem +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN DH PARAMETERS----- -MEYCQQD1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWak -XUGfnHy9iUsiGSa6q6Jew1XpKgVfAgEC ------END DH PARAMETERS----- - -These are the 512 bit DH parameters from "Assigned Number for SKIP Protocols" -(http://www.skip-vpn.org/spec/numbers.html). -See there for how they were generated. -Note that g is not a generator, but this is not a problem since p is a safe prime. diff --git a/Lib/test/eintrdata/eintr_tester.py b/Lib/test/eintrdata/eintr_tester.py new file mode 100644 index 000000000000..ee6e75bb9944 --- /dev/null +++ b/Lib/test/eintrdata/eintr_tester.py @@ -0,0 +1,476 @@ +""" +This test suite exercises some system calls subject to interruption with EINTR, +to check that it is actually handled transparently. +It is intended to be run by the main test suite within a child process, to +ensure there is no background thread running (so that signals are delivered to +the correct thread). +Signals are generated in-process using setitimer(ITIMER_REAL), which allows +sub-second periodicity (contrarily to signal()). +""" + +import contextlib +import faulthandler +import io +import os +import select +import signal +import socket +import subprocess +import sys +import time +import unittest + +from test import support + +@contextlib.contextmanager +def kill_on_error(proc): + """Context manager killing the subprocess if a Python exception is raised.""" + with proc: + try: + yield proc + except: + proc.kill() + raise + + +@unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") +class EINTRBaseTest(unittest.TestCase): + """ Base class for EINTR tests. """ + + # delay for initial signal delivery + signal_delay = 0.1 + # signal delivery periodicity + signal_period = 0.1 + # default sleep time for tests - should obviously have: + # sleep_time > signal_period + sleep_time = 0.2 + + @classmethod + def setUpClass(cls): + cls.orig_handler = signal.signal(signal.SIGALRM, lambda *args: None) + signal.setitimer(signal.ITIMER_REAL, cls.signal_delay, + cls.signal_period) + + # Issue #25277: Use faulthandler to try to debug a hang on FreeBSD + if hasattr(faulthandler, 'dump_traceback_later'): + faulthandler.dump_traceback_later(10 * 60, exit=True) + + @classmethod + def stop_alarm(cls): + signal.setitimer(signal.ITIMER_REAL, 0, 0) + + @classmethod + def tearDownClass(cls): + cls.stop_alarm() + signal.signal(signal.SIGALRM, cls.orig_handler) + if hasattr(faulthandler, 'cancel_dump_traceback_later'): + faulthandler.cancel_dump_traceback_later() + + def subprocess(self, *args, **kw): + cmd_args = (sys.executable, '-c') + args + return subprocess.Popen(cmd_args, **kw) + + +@unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") +class OSEINTRTest(EINTRBaseTest): + """ EINTR tests for the os module. """ + + def new_sleep_process(self): + code = 'import time; time.sleep(%r)' % self.sleep_time + return self.subprocess(code) + + def _test_wait_multiple(self, wait_func): + num = 3 + processes = [self.new_sleep_process() for _ in range(num)] + for _ in range(num): + wait_func() + + def test_wait(self): + self._test_wait_multiple(os.wait) + + @unittest.skipUnless(hasattr(os, 'wait3'), 'requires wait3()') + def test_wait3(self): + self._test_wait_multiple(lambda: os.wait3(0)) + + def _test_wait_single(self, wait_func): + proc = self.new_sleep_process() + wait_func(proc.pid) + + def test_waitpid(self): + self._test_wait_single(lambda pid: os.waitpid(pid, 0)) + + @unittest.skipUnless(hasattr(os, 'wait4'), 'requires wait4()') + def test_wait4(self): + self._test_wait_single(lambda pid: os.wait4(pid, 0)) + + def test_read(self): + rd, wr = os.pipe() + self.addCleanup(os.close, rd) + # wr closed explicitly by parent + + # the payload below are smaller than PIPE_BUF, hence the writes will be + # atomic + datas = [b"hello", b"world", b"spam"] + + code = '\n'.join(( + 'import os, sys, time', + '', + 'wr = int(sys.argv[1])', + 'datas = %r' % datas, + 'sleep_time = %r' % self.sleep_time, + '', + 'for data in datas:', + ' # let the parent block on read()', + ' time.sleep(sleep_time)', + ' os.write(wr, data)', + )) + + proc = self.subprocess(code, str(wr), pass_fds=[wr]) + with kill_on_error(proc): + os.close(wr) + for data in datas: + self.assertEqual(data, os.read(rd, len(data))) + self.assertEqual(proc.wait(), 0) + + def test_write(self): + rd, wr = os.pipe() + self.addCleanup(os.close, wr) + # rd closed explicitly by parent + + # we must write enough data for the write() to block + data = b"x" * support.PIPE_MAX_SIZE + + code = '\n'.join(( + 'import io, os, sys, time', + '', + 'rd = int(sys.argv[1])', + 'sleep_time = %r' % self.sleep_time, + 'data = b"x" * %s' % support.PIPE_MAX_SIZE, + 'data_len = len(data)', + '', + '# let the parent block on write()', + 'time.sleep(sleep_time)', + '', + 'read_data = io.BytesIO()', + 'while len(read_data.getvalue()) < data_len:', + ' chunk = os.read(rd, 2 * data_len)', + ' read_data.write(chunk)', + '', + 'value = read_data.getvalue()', + 'if value != data:', + ' raise Exception("read error: %s vs %s bytes"', + ' % (len(value), data_len))', + )) + + proc = self.subprocess(code, str(rd), pass_fds=[rd]) + with kill_on_error(proc): + os.close(rd) + written = 0 + while written < len(data): + written += os.write(wr, memoryview(data)[written:]) + self.assertEqual(proc.wait(), 0) + + +@unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") +class SocketEINTRTest(EINTRBaseTest): + """ EINTR tests for the socket module. """ + + @unittest.skipUnless(hasattr(socket, 'socketpair'), 'needs socketpair()') + def _test_recv(self, recv_func): + rd, wr = socket.socketpair() + self.addCleanup(rd.close) + # wr closed explicitly by parent + + # single-byte payload guard us against partial recv + datas = [b"x", b"y", b"z"] + + code = '\n'.join(( + 'import os, socket, sys, time', + '', + 'fd = int(sys.argv[1])', + 'family = %s' % int(wr.family), + 'sock_type = %s' % int(wr.type), + 'datas = %r' % datas, + 'sleep_time = %r' % self.sleep_time, + '', + 'wr = socket.fromfd(fd, family, sock_type)', + 'os.close(fd)', + '', + 'with wr:', + ' for data in datas:', + ' # let the parent block on recv()', + ' time.sleep(sleep_time)', + ' wr.sendall(data)', + )) + + fd = wr.fileno() + proc = self.subprocess(code, str(fd), pass_fds=[fd]) + with kill_on_error(proc): + wr.close() + for data in datas: + self.assertEqual(data, recv_func(rd, len(data))) + self.assertEqual(proc.wait(), 0) + + def test_recv(self): + self._test_recv(socket.socket.recv) + + @unittest.skipUnless(hasattr(socket.socket, 'recvmsg'), 'needs recvmsg()') + def test_recvmsg(self): + self._test_recv(lambda sock, data: sock.recvmsg(data)[0]) + + def _test_send(self, send_func): + rd, wr = socket.socketpair() + self.addCleanup(wr.close) + # rd closed explicitly by parent + + # we must send enough data for the send() to block + data = b"xyz" * (support.SOCK_MAX_SIZE // 3) + + code = '\n'.join(( + 'import os, socket, sys, time', + '', + 'fd = int(sys.argv[1])', + 'family = %s' % int(rd.family), + 'sock_type = %s' % int(rd.type), + 'sleep_time = %r' % self.sleep_time, + 'data = b"xyz" * %s' % (support.SOCK_MAX_SIZE // 3), + 'data_len = len(data)', + '', + 'rd = socket.fromfd(fd, family, sock_type)', + 'os.close(fd)', + '', + 'with rd:', + ' # let the parent block on send()', + ' time.sleep(sleep_time)', + '', + ' received_data = bytearray(data_len)', + ' n = 0', + ' while n < data_len:', + ' n += rd.recv_into(memoryview(received_data)[n:])', + '', + 'if received_data != data:', + ' raise Exception("recv error: %s vs %s bytes"', + ' % (len(received_data), data_len))', + )) + + fd = rd.fileno() + proc = self.subprocess(code, str(fd), pass_fds=[fd]) + with kill_on_error(proc): + rd.close() + written = 0 + while written < len(data): + sent = send_func(wr, memoryview(data)[written:]) + # sendall() returns None + written += len(data) if sent is None else sent + self.assertEqual(proc.wait(), 0) + + def test_send(self): + self._test_send(socket.socket.send) + + def test_sendall(self): + self._test_send(socket.socket.sendall) + + @unittest.skipUnless(hasattr(socket.socket, 'sendmsg'), 'needs sendmsg()') + def test_sendmsg(self): + self._test_send(lambda sock, data: sock.sendmsg([data])) + + def test_accept(self): + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.addCleanup(sock.close) + + sock.bind((support.HOST, 0)) + port = sock.getsockname()[1] + sock.listen() + + code = '\n'.join(( + 'import socket, time', + '', + 'host = %r' % support.HOST, + 'port = %s' % port, + 'sleep_time = %r' % self.sleep_time, + '', + '# let parent block on accept()', + 'time.sleep(sleep_time)', + 'with socket.create_connection((host, port)):', + ' time.sleep(sleep_time)', + )) + + proc = self.subprocess(code) + with kill_on_error(proc): + client_sock, _ = sock.accept() + client_sock.close() + self.assertEqual(proc.wait(), 0) + + # Issue #25122: There is a race condition in the FreeBSD kernel on + # handling signals in the FIFO device. Skip the test until the bug is + # fixed in the kernel. + # https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=203162 + @support.requires_freebsd_version(10, 3) + @unittest.skipUnless(hasattr(os, 'mkfifo'), 'needs mkfifo()') + def _test_open(self, do_open_close_reader, do_open_close_writer): + filename = support.TESTFN + + # Use a fifo: until the child opens it for reading, the parent will + # block when trying to open it for writing. + support.unlink(filename) + os.mkfifo(filename) + self.addCleanup(support.unlink, filename) + + code = '\n'.join(( + 'import os, time', + '', + 'path = %a' % filename, + 'sleep_time = %r' % self.sleep_time, + '', + '# let the parent block', + 'time.sleep(sleep_time)', + '', + do_open_close_reader, + )) + + proc = self.subprocess(code) + with kill_on_error(proc): + do_open_close_writer(filename) + self.assertEqual(proc.wait(), 0) + + def python_open(self, path): + fp = open(path, 'w') + fp.close() + + def test_open(self): + self._test_open("fp = open(path, 'r')\nfp.close()", + self.python_open) + + def os_open(self, path): + fd = os.open(path, os.O_WRONLY) + os.close(fd) + + def test_os_open(self): + self._test_open("fd = os.open(path, os.O_RDONLY)\nos.close(fd)", + self.os_open) + + +@unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") +class TimeEINTRTest(EINTRBaseTest): + """ EINTR tests for the time module. """ + + def test_sleep(self): + t0 = time.monotonic() + time.sleep(self.sleep_time) + self.stop_alarm() + dt = time.monotonic() - t0 + self.assertGreaterEqual(dt, self.sleep_time) + + +@unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") +class SignalEINTRTest(EINTRBaseTest): + """ EINTR tests for the signal module. """ + + @unittest.skipUnless(hasattr(signal, 'sigtimedwait'), + 'need signal.sigtimedwait()') + def test_sigtimedwait(self): + t0 = time.monotonic() + signal.sigtimedwait([signal.SIGUSR1], self.sleep_time) + dt = time.monotonic() - t0 + self.assertGreaterEqual(dt, self.sleep_time) + + @unittest.skipUnless(hasattr(signal, 'sigwaitinfo'), + 'need signal.sigwaitinfo()') + def test_sigwaitinfo(self): + # Issue #25277: The sleep is a weak synchronization between the parent + # and the child process. If the sleep is too low, the test hangs on + # slow or highly loaded systems. + self.sleep_time = 2.0 + + signum = signal.SIGUSR1 + pid = os.getpid() + + old_handler = signal.signal(signum, lambda *args: None) + self.addCleanup(signal.signal, signum, old_handler) + + code = '\n'.join(( + 'import os, time', + 'pid = %s' % os.getpid(), + 'signum = %s' % int(signum), + 'sleep_time = %r' % self.sleep_time, + 'time.sleep(sleep_time)', + 'os.kill(pid, signum)', + )) + + t0 = time.monotonic() + proc = self.subprocess(code) + with kill_on_error(proc): + # parent + signal.sigwaitinfo([signum]) + dt = time.monotonic() - t0 + self.assertEqual(proc.wait(), 0) + + self.assertGreaterEqual(dt, self.sleep_time) + + +@unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") +class SelectEINTRTest(EINTRBaseTest): + """ EINTR tests for the select module. """ + + def test_select(self): + t0 = time.monotonic() + select.select([], [], [], self.sleep_time) + dt = time.monotonic() - t0 + self.stop_alarm() + self.assertGreaterEqual(dt, self.sleep_time) + + @unittest.skipUnless(hasattr(select, 'poll'), 'need select.poll') + def test_poll(self): + poller = select.poll() + + t0 = time.monotonic() + poller.poll(self.sleep_time * 1e3) + dt = time.monotonic() - t0 + self.stop_alarm() + self.assertGreaterEqual(dt, self.sleep_time) + + @unittest.skipUnless(hasattr(select, 'epoll'), 'need select.epoll') + def test_epoll(self): + poller = select.epoll() + self.addCleanup(poller.close) + + t0 = time.monotonic() + poller.poll(self.sleep_time) + dt = time.monotonic() - t0 + self.stop_alarm() + self.assertGreaterEqual(dt, self.sleep_time) + + @unittest.skipUnless(hasattr(select, 'kqueue'), 'need select.kqueue') + def test_kqueue(self): + kqueue = select.kqueue() + self.addCleanup(kqueue.close) + + t0 = time.monotonic() + kqueue.control(None, 1, self.sleep_time) + dt = time.monotonic() - t0 + self.stop_alarm() + self.assertGreaterEqual(dt, self.sleep_time) + + @unittest.skipUnless(hasattr(select, 'devpoll'), 'need select.devpoll') + def test_devpoll(self): + poller = select.devpoll() + self.addCleanup(poller.close) + + t0 = time.monotonic() + poller.poll(self.sleep_time * 1e3) + dt = time.monotonic() - t0 + self.stop_alarm() + self.assertGreaterEqual(dt, self.sleep_time) + + +def test_main(): + support.run_unittest( + OSEINTRTest, + SocketEINTRTest, + TimeEINTRTest, + SignalEINTRTest, + SelectEINTRTest) + + +if __name__ == "__main__": + test_main() diff --git a/Lib/test/exception_hierarchy.txt b/Lib/test/exception_hierarchy.txt index 1c1f69f36b3b..05137654de62 100644 --- a/Lib/test/exception_hierarchy.txt +++ b/Lib/test/exception_hierarchy.txt @@ -4,6 +4,7 @@ BaseException +-- GeneratorExit +-- Exception +-- StopIteration + +-- StopAsyncIteration +-- ArithmeticError | +-- FloatingPointError | +-- OverflowError @@ -38,6 +39,7 @@ BaseException +-- ReferenceError +-- RuntimeError | +-- NotImplementedError + | +-- RecursionError +-- SyntaxError | +-- IndentationError | +-- TabError diff --git a/Lib/test/fork_wait.py b/Lib/test/fork_wait.py index 19b54ec736b7..713039dd8268 100644 --- a/Lib/test/fork_wait.py +++ b/Lib/test/fork_wait.py @@ -48,7 +48,12 @@ def test_wait(self): for i in range(NUM_THREADS): _thread.start_new(self.f, (i,)) - time.sleep(LONGSLEEP) + # busy-loop to wait for threads + deadline = time.monotonic() + 10.0 + while len(self.alive) < NUM_THREADS: + time.sleep(0.1) + if deadline < time.monotonic(): + break a = sorted(self.alive.keys()) self.assertEqual(a, list(range(NUM_THREADS))) diff --git a/Lib/test/imghdrdata/python.bmp b/Lib/test/imghdrdata/python.bmp new file mode 100644 index 000000000000..675f95191a45 Binary files /dev/null and b/Lib/test/imghdrdata/python.bmp differ diff --git a/Lib/test/imghdrdata/python.exr b/Lib/test/imghdrdata/python.exr new file mode 100644 index 000000000000..773c81ee1fb8 Binary files /dev/null and b/Lib/test/imghdrdata/python.exr differ diff --git a/Lib/test/imghdrdata/python.gif b/Lib/test/imghdrdata/python.gif new file mode 100644 index 000000000000..96fd9fef76b1 Binary files /dev/null and b/Lib/test/imghdrdata/python.gif differ diff --git a/Lib/test/imghdrdata/python.jpg b/Lib/test/imghdrdata/python.jpg new file mode 100644 index 000000000000..21222c09f5a7 Binary files /dev/null and b/Lib/test/imghdrdata/python.jpg differ diff --git a/Lib/test/imghdrdata/python.pbm b/Lib/test/imghdrdata/python.pbm new file mode 100644 index 000000000000..1848ba7ff064 --- /dev/null +++ b/Lib/test/imghdrdata/python.pbm @@ -0,0 +1,3 @@ +P4 +16 16 +�������[�a_�X������?�� \ No newline at end of file diff --git a/Lib/test/imghdrdata/python.pgm b/Lib/test/imghdrdata/python.pgm new file mode 100644 index 000000000000..8349f2a53a9b Binary files /dev/null and b/Lib/test/imghdrdata/python.pgm differ diff --git a/Lib/test/imghdrdata/python.png b/Lib/test/imghdrdata/python.png new file mode 100644 index 000000000000..1a987f79fcd2 Binary files /dev/null and b/Lib/test/imghdrdata/python.png differ diff --git a/Lib/test/imghdrdata/python.ppm b/Lib/test/imghdrdata/python.ppm new file mode 100644 index 000000000000..7d9cdb321587 Binary files /dev/null and b/Lib/test/imghdrdata/python.ppm differ diff --git a/Lib/test/imghdrdata/python.ras b/Lib/test/imghdrdata/python.ras new file mode 100644 index 000000000000..130e96f817ed Binary files /dev/null and b/Lib/test/imghdrdata/python.ras differ diff --git a/Lib/test/imghdrdata/python.sgi b/Lib/test/imghdrdata/python.sgi new file mode 100644 index 000000000000..ffe9081c7a5b Binary files /dev/null and b/Lib/test/imghdrdata/python.sgi differ diff --git a/Lib/test/imghdrdata/python.tiff b/Lib/test/imghdrdata/python.tiff new file mode 100644 index 000000000000..39d0bfcec025 Binary files /dev/null and b/Lib/test/imghdrdata/python.tiff differ diff --git a/Lib/test/imghdrdata/python.webp b/Lib/test/imghdrdata/python.webp new file mode 100644 index 000000000000..e824ec7fb1c7 Binary files /dev/null and b/Lib/test/imghdrdata/python.webp differ diff --git a/Lib/test/imghdrdata/python.xbm b/Lib/test/imghdrdata/python.xbm new file mode 100644 index 000000000000..cfbee2e98062 --- /dev/null +++ b/Lib/test/imghdrdata/python.xbm @@ -0,0 +1,6 @@ +#define python_width 16 +#define python_height 16 +static char python_bits[] = { + 0xDF, 0xFE, 0x8F, 0xFD, 0x5F, 0xFB, 0xAB, 0xFE, 0xB5, 0x8D, 0xDA, 0x8F, + 0xA5, 0x86, 0xFA, 0x83, 0x1A, 0x80, 0x0D, 0x80, 0x0D, 0x80, 0x0F, 0xE0, + 0x0F, 0xF8, 0x0F, 0xF8, 0x0F, 0xFC, 0xFF, 0xFF, }; diff --git a/Lib/test/imp_dummy.py b/Lib/test/imp_dummy.py new file mode 100644 index 000000000000..2a4deb49547c --- /dev/null +++ b/Lib/test/imp_dummy.py @@ -0,0 +1,3 @@ +# Fodder for test of issue24748 in test_imp + +dummy_name = True diff --git a/Lib/test/inspect_fodder.py b/Lib/test/inspect_fodder.py index 0c1d8103e9d0..068d8258b925 100644 --- a/Lib/test/inspect_fodder.py +++ b/Lib/test/inspect_fodder.py @@ -45,9 +45,16 @@ def argue(self, a, b, c): self.ex = sys.exc_info() self.tr = inspect.trace() + def contradiction(self): + 'The automatic gainsaying.' + pass + # line 48 class MalodorousPervert(StupidGit): - pass + def abuse(self, a, b, c): + pass + def contradiction(self): + pass Tit = MalodorousPervert @@ -55,4 +62,10 @@ class ParrotDroppings: pass class FesteringGob(MalodorousPervert, ParrotDroppings): + def abuse(self, a, b, c): + pass + def contradiction(self): + pass + +async def lobbest(grenade): pass diff --git a/Lib/test/inspect_fodder2.py b/Lib/test/inspect_fodder2.py index bd7106fea86b..c6987ea2c9e4 100644 --- a/Lib/test/inspect_fodder2.py +++ b/Lib/test/inspect_fodder2.py @@ -109,3 +109,31 @@ def annotated(arg1: list): #line 109 def keyword_only_arg(*, arg): pass + +@wrap(lambda: None) +def func114(): + return 115 + +class ClassWithMethod: + def method(self): + pass + +from functools import wraps + +def decorator(func): + @wraps(func) + def fake(): + return 42 + return fake + +#line 129 +@decorator +def real(): + return 20 + +#line 134 +class cls135: + def func136(): + def func137(): + never_reached1 + never_reached2 diff --git a/Lib/test/libregrtest/__init__.py b/Lib/test/libregrtest/__init__.py new file mode 100644 index 000000000000..9f7b1c1fe25f --- /dev/null +++ b/Lib/test/libregrtest/__init__.py @@ -0,0 +1,2 @@ +from test.libregrtest.cmdline import _parse_args, RESOURCE_NAMES +from test.libregrtest.main import main, main_in_temp_cwd diff --git a/Lib/test/libregrtest/cmdline.py b/Lib/test/libregrtest/cmdline.py new file mode 100644 index 000000000000..a9cee6e79c7c --- /dev/null +++ b/Lib/test/libregrtest/cmdline.py @@ -0,0 +1,344 @@ +import argparse +import os +import sys +from test import support + + +USAGE = """\ +python -m test [options] [test_name1 [test_name2 ...]] +python path/to/Lib/test/regrtest.py [options] [test_name1 [test_name2 ...]] +""" + +DESCRIPTION = """\ +Run Python regression tests. + +If no arguments or options are provided, finds all files matching +the pattern "test_*" in the Lib/test subdirectory and runs +them in alphabetical order (but see -M and -u, below, for exceptions). + +For more rigorous testing, it is useful to use the following +command line: + +python -E -Wd -m test [options] [test_name1 ...] +""" + +EPILOG = """\ +Additional option details: + +-r randomizes test execution order. You can use --randseed=int to provide a +int seed value for the randomizer; this is useful for reproducing troublesome +test orders. + +-s On the first invocation of regrtest using -s, the first test file found +or the first test file given on the command line is run, and the name of +the next test is recorded in a file named pynexttest. If run from the +Python build directory, pynexttest is located in the 'build' subdirectory, +otherwise it is located in tempfile.gettempdir(). On subsequent runs, +the test in pynexttest is run, and the next test is written to pynexttest. +When the last test has been run, pynexttest is deleted. In this way it +is possible to single step through the test files. This is useful when +doing memory analysis on the Python interpreter, which process tends to +consume too many resources to run the full regression test non-stop. + +-S is used to continue running tests after an aborted run. It will +maintain the order a standard run (ie, this assumes -r is not used). +This is useful after the tests have prematurely stopped for some external +reason and you want to start running from where you left off rather +than starting from the beginning. + +-f reads the names of tests from the file given as f's argument, one +or more test names per line. Whitespace is ignored. Blank lines and +lines beginning with '#' are ignored. This is especially useful for +whittling down failures involving interactions among tests. + +-L causes the leaks(1) command to be run just before exit if it exists. +leaks(1) is available on Mac OS X and presumably on some other +FreeBSD-derived systems. + +-R runs each test several times and examines sys.gettotalrefcount() to +see if the test appears to be leaking references. The argument should +be of the form stab:run:fname where 'stab' is the number of times the +test is run to let gettotalrefcount settle down, 'run' is the number +of times further it is run and 'fname' is the name of the file the +reports are written to. These parameters all have defaults (5, 4 and +"reflog.txt" respectively), and the minimal invocation is '-R :'. + +-M runs tests that require an exorbitant amount of memory. These tests +typically try to ascertain containers keep working when containing more than +2 billion objects, which only works on 64-bit systems. There are also some +tests that try to exhaust the address space of the process, which only makes +sense on 32-bit systems with at least 2Gb of memory. The passed-in memlimit, +which is a string in the form of '2.5Gb', determines howmuch memory the +tests will limit themselves to (but they may go slightly over.) The number +shouldn't be more memory than the machine has (including swap memory). You +should also keep in mind that swap memory is generally much, much slower +than RAM, and setting memlimit to all available RAM or higher will heavily +tax the machine. On the other hand, it is no use running these tests with a +limit of less than 2.5Gb, and many require more than 20Gb. Tests that expect +to use more than memlimit memory will be skipped. The big-memory tests +generally run very, very long. + +-u is used to specify which special resource intensive tests to run, +such as those requiring large file support or network connectivity. +The argument is a comma-separated list of words indicating the +resources to test. Currently only the following are defined: + + all - Enable all special resources. + + none - Disable all special resources (this is the default). + + audio - Tests that use the audio device. (There are known + cases of broken audio drivers that can crash Python or + even the Linux kernel.) + + curses - Tests that use curses and will modify the terminal's + state and output modes. + + largefile - It is okay to run some test that may create huge + files. These tests can take a long time and may + consume >2GB of disk space temporarily. + + network - It is okay to run tests that use external network + resource, e.g. testing SSL support for sockets. + + decimal - Test the decimal module against a large suite that + verifies compliance with standards. + + cpu - Used for certain CPU-heavy tests. + + subprocess Run all tests for the subprocess module. + + urlfetch - It is okay to download files required on testing. + + gui - Run tests that require a running GUI. + +To enable all resources except one, use '-uall,-'. For +example, to run all the tests except for the gui tests, give the +option '-uall,-gui'. +""" + + +RESOURCE_NAMES = ('audio', 'curses', 'largefile', 'network', + 'decimal', 'cpu', 'subprocess', 'urlfetch', 'gui') + +class _ArgParser(argparse.ArgumentParser): + + def error(self, message): + super().error(message + "\nPass -h or --help for complete help.") + + +def _create_parser(): + # Set prog to prevent the uninformative "__main__.py" from displaying in + # error messages when using "python -m test ...". + parser = _ArgParser(prog='regrtest.py', + usage=USAGE, + description=DESCRIPTION, + epilog=EPILOG, + add_help=False, + formatter_class=argparse.RawDescriptionHelpFormatter) + + # Arguments with this clause added to its help are described further in + # the epilog's "Additional option details" section. + more_details = ' See the section at bottom for more details.' + + group = parser.add_argument_group('General options') + # We add help explicitly to control what argument group it renders under. + group.add_argument('-h', '--help', action='http://github.com/help', + help='show this help message and exit') + group.add_argument('--timeout', metavar='TIMEOUT', type=float, + help='dump the traceback and exit if a test takes ' + 'more than TIMEOUT seconds; disabled if TIMEOUT ' + 'is negative or equals to zero') + group.add_argument('--wait', action='http://github.com/store_true', + help='wait for user input, e.g., allow a debugger ' + 'to be attached') + group.add_argument('--slaveargs', metavar='ARGS') + group.add_argument('-S', '--start', metavar='START', + help='the name of the test at which to start.' + + more_details) + + group = parser.add_argument_group('Verbosity') + group.add_argument('-v', '--verbose', action='http://github.com/count', + help='run tests in verbose mode with output to stdout') + group.add_argument('-w', '--verbose2', action='http://github.com/store_true', + help='re-run failed tests in verbose mode') + group.add_argument('-W', '--verbose3', action='http://github.com/store_true', + help='display test output on failure') + group.add_argument('-q', '--quiet', action='http://github.com/store_true', + help='no output unless one or more tests fail') + group.add_argument('-o', '--slow', action='http://github.com/store_true', dest='print_slow', + help='print the slowest 10 tests') + group.add_argument('--header', action='http://github.com/store_true', + help='print header with interpreter info') + + group = parser.add_argument_group('Selecting tests') + group.add_argument('-r', '--randomize', action='http://github.com/store_true', + help='randomize test execution order.' + more_details) + group.add_argument('--randseed', metavar='SEED', + dest='random_seed', type=int, + help='pass a random seed to reproduce a previous ' + 'random run') + group.add_argument('-f', '--fromfile', metavar='FILE', + help='read names of tests to run from a file.' + + more_details) + group.add_argument('-x', '--exclude', action='http://github.com/store_true', + help='arguments are tests to *exclude*') + group.add_argument('-s', '--single', action='http://github.com/store_true', + help='single step through a set of tests.' + + more_details) + group.add_argument('-m', '--match', metavar='PAT', + dest='match_tests', + help='match test cases and methods with glob pattern PAT') + group.add_argument('-G', '--failfast', action='http://github.com/store_true', + help='fail as soon as a test fails (only with -v or -W)') + group.add_argument('-u', '--use', metavar='RES1,RES2,...', + action='http://github.com/append', type=resources_list, + help='specify which special resource intensive tests ' + 'to run.' + more_details) + group.add_argument('-M', '--memlimit', metavar='LIMIT', + help='run very large memory-consuming tests.' + + more_details) + group.add_argument('--testdir', metavar='DIR', + type=relative_filename, + help='execute test files in the specified directory ' + '(instead of the Python stdlib test suite)') + + group = parser.add_argument_group('Special runs') + group.add_argument('-l', '--findleaks', action='http://github.com/store_true', + help='if GC is available detect tests that leak memory') + group.add_argument('-L', '--runleaks', action='http://github.com/store_true', + help='run the leaks(1) command just before exit.' + + more_details) + group.add_argument('-R', '--huntrleaks', metavar='RUNCOUNTS', + type=huntrleaks, + help='search for reference leaks (needs debug build, ' + 'very slow).' + more_details) + group.add_argument('-j', '--multiprocess', metavar='PROCESSES', + dest='use_mp', type=int, + help='run PROCESSES processes at once') + group.add_argument('-T', '--coverage', action='http://github.com/store_true', + dest='trace', + help='turn on code coverage tracing using the trace ' + 'module') + group.add_argument('-D', '--coverdir', metavar='DIR', + type=relative_filename, + help='directory where coverage files are put') + group.add_argument('-N', '--nocoverdir', + action='http://github.com/store_const', const=None, dest='coverdir', + help='put coverage files alongside modules') + group.add_argument('-t', '--threshold', metavar='THRESHOLD', + type=int, + help='call gc.set_threshold(THRESHOLD)') + group.add_argument('-n', '--nowindows', action='http://github.com/store_true', + help='suppress error message boxes on Windows') + group.add_argument('-F', '--forever', action='http://github.com/store_true', + help='run the specified tests in a loop, until an ' + 'error happens') + group.add_argument('--list-tests', action='http://github.com/store_true', + help="only write the name of tests that will be run, " + "don't execute them") + group.add_argument('-P', '--pgo', dest='pgo', action='http://github.com/store_true', + help='enable Profile Guided Optimization training') + + parser.add_argument('args', nargs=argparse.REMAINDER, + help=argparse.SUPPRESS) + + return parser + + +def relative_filename(string): + # CWD is replaced with a temporary dir before calling main(), so we + # join it with the saved CWD so it ends up where the user expects. + return os.path.join(support.SAVEDCWD, string) + + +def huntrleaks(string): + args = string.split(':') + if len(args) not in (2, 3): + raise argparse.ArgumentTypeError( + 'needs 2 or 3 colon-separated arguments') + nwarmup = int(args[0]) if args[0] else 5 + ntracked = int(args[1]) if args[1] else 4 + fname = args[2] if len(args) > 2 and args[2] else 'reflog.txt' + return nwarmup, ntracked, fname + + +def resources_list(string): + u = [x.lower() for x in string.split(',')] + for r in u: + if r == 'all' or r == 'none': + continue + if r[0] == '-': + r = r[1:] + if r not in RESOURCE_NAMES: + raise argparse.ArgumentTypeError('invalid resource: ' + r) + return u + + +def _parse_args(args, **kwargs): + # Defaults + ns = argparse.Namespace(testdir=None, verbose=0, quiet=False, + exclude=False, single=False, randomize=False, fromfile=None, + findleaks=False, use_resources=None, trace=False, coverdir='coverage', + runleaks=False, huntrleaks=False, verbose2=False, print_slow=False, + random_seed=None, use_mp=None, verbose3=False, forever=False, + header=False, failfast=False, match_tests=None, pgo=False) + for k, v in kwargs.items(): + if not hasattr(ns, k): + raise TypeError('%r is an invalid keyword argument ' + 'for this function' % k) + setattr(ns, k, v) + if ns.use_resources is None: + ns.use_resources = [] + + parser = _create_parser() + parser.parse_args(args=args, namespace=ns) + + if ns.single and ns.fromfile: + parser.error("-s and -f don't go together!") + if ns.use_mp and ns.trace: + parser.error("-T and -j don't go together!") + if ns.use_mp and ns.findleaks: + parser.error("-l and -j don't go together!") + if ns.failfast and not (ns.verbose or ns.verbose3): + parser.error("-G/--failfast needs either -v or -W") + if ns.pgo and (ns.verbose or ns.verbose2 or ns.verbose3): + parser.error("--pgo/-v don't go together!") + + if ns.nowindows: + print("Warning: the --nowindows (-n) option is deprecated. " + "Use -vv to display assertions in stderr.", file=sys.stderr) + + if ns.quiet: + ns.verbose = 0 + if ns.timeout is not None: + if ns.timeout <= 0: + ns.timeout = None + if ns.use_mp is not None: + if ns.use_mp <= 0: + # Use all cores + extras for tests that like to sleep + ns.use_mp = 2 + (os.cpu_count() or 1) + if ns.use_mp == 1: + ns.use_mp = None + if ns.use: + for a in ns.use: + for r in a: + if r == 'all': + ns.use_resources[:] = RESOURCE_NAMES + continue + if r == 'none': + del ns.use_resources[:] + continue + remove = False + if r[0] == '-': + remove = True + r = r[1:] + if remove: + if r in ns.use_resources: + ns.use_resources.remove(r) + elif r not in ns.use_resources: + ns.use_resources.append(r) + if ns.random_seed is not None: + ns.randomize = True + + return ns diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py new file mode 100644 index 000000000000..82788ad941d9 --- /dev/null +++ b/Lib/test/libregrtest/main.py @@ -0,0 +1,455 @@ +import faulthandler +import os +import platform +import random +import re +import sys +import sysconfig +import tempfile +import textwrap +from test.libregrtest.cmdline import _parse_args +from test.libregrtest.runtest import ( + findtests, runtest, + STDTESTS, NOTTESTS, PASSED, FAILED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED, + INTERRUPTED, CHILD_ERROR) +from test.libregrtest.setup import setup_tests +from test import support +try: + import gc +except ImportError: + gc = None + + +# When tests are run from the Python build directory, it is best practice +# to keep the test files in a subfolder. This eases the cleanup of leftover +# files using the "make distclean" command. +if sysconfig.is_python_build(): + TEMPDIR = os.path.join(sysconfig.get_config_var('srcdir'), 'build') +else: + TEMPDIR = tempfile.gettempdir() +TEMPDIR = os.path.abspath(TEMPDIR) + + +class Regrtest: + """Execute a test suite. + + This also parses command-line options and modifies its behavior + accordingly. + + tests -- a list of strings containing test names (optional) + testdir -- the directory in which to look for tests (optional) + + Users other than the Python test suite will certainly want to + specify testdir; if it's omitted, the directory containing the + Python test suite is searched for. + + If the tests argument is omitted, the tests listed on the + command-line will be used. If that's empty, too, then all *.py + files beginning with test_ will be used. + + The other default arguments (verbose, quiet, exclude, + single, randomize, findleaks, use_resources, trace, coverdir, + print_slow, and random_seed) allow programmers calling main() + directly to set the values that would normally be set by flags + on the command line. + """ + def __init__(self): + # Namespace of command line options + self.ns = None + + # tests + self.tests = [] + self.selected = [] + + # test results + self.good = [] + self.bad = [] + self.skipped = [] + self.resource_denieds = [] + self.environment_changed = [] + self.interrupted = False + + # used by --slow + self.test_times = [] + + # used by --coverage, trace.Trace instance + self.tracer = None + + # used by --findleaks, store for gc.garbage + self.found_garbage = [] + + # used to display the progress bar "[ 3/100]" + self.test_count = '' + self.test_count_width = 1 + + # used by --single + self.next_single_test = None + self.next_single_filename = None + + def accumulate_result(self, test, result): + ok, test_time = result + if ok not in (CHILD_ERROR, INTERRUPTED): + self.test_times.append((test_time, test)) + if ok == PASSED: + self.good.append(test) + elif ok == FAILED: + self.bad.append(test) + elif ok == ENV_CHANGED: + self.environment_changed.append(test) + elif ok == SKIPPED: + self.skipped.append(test) + elif ok == RESOURCE_DENIED: + self.skipped.append(test) + self.resource_denieds.append(test) + + def display_progress(self, test_index, test): + if self.ns.quiet: + return + if self.bad and not self.ns.pgo: + fmt = "[{1:{0}}{2}/{3}] {4}" + else: + fmt = "[{1:{0}}{2}] {4}" + print(fmt.format(self.test_count_width, test_index, + self.test_count, len(self.bad), test), + flush=True) + + def parse_args(self, kwargs): + ns = _parse_args(sys.argv[1:], **kwargs) + + if ns.timeout and not hasattr(faulthandler, 'dump_traceback_later'): + print("Warning: The timeout option requires " + "faulthandler.dump_traceback_later", file=sys.stderr) + ns.timeout = None + + if ns.threshold is not None and gc is None: + print('No GC available, ignore --threshold.', file=sys.stderr) + ns.threshold = None + + if ns.findleaks: + if gc is not None: + # Uncomment the line below to report garbage that is not + # freeable by reference counting alone. By default only + # garbage that is not collectable by the GC is reported. + pass + #gc.set_debug(gc.DEBUG_SAVEALL) + else: + print('No GC available, disabling --findleaks', + file=sys.stderr) + ns.findleaks = False + + # Strip .py extensions. + removepy(ns.args) + + return ns + + def find_tests(self, tests): + self.tests = tests + + if self.ns.single: + self.next_single_filename = os.path.join(TEMPDIR, 'pynexttest') + try: + with open(self.next_single_filename, 'r') as fp: + next_test = fp.read().strip() + self.tests = [next_test] + except OSError: + pass + + if self.ns.fromfile: + self.tests = [] + with open(os.path.join(support.SAVEDCWD, self.ns.fromfile)) as fp: + count_pat = re.compile(r'\[\s*\d+/\s*\d+\]') + for line in fp: + line = count_pat.sub('', line) + guts = line.split() # assuming no test has whitespace in its name + if guts and not guts[0].startswith('#'): + self.tests.extend(guts) + + removepy(self.tests) + + stdtests = STDTESTS[:] + nottests = NOTTESTS.copy() + if self.ns.exclude: + for arg in self.ns.args: + if arg in stdtests: + stdtests.remove(arg) + nottests.add(arg) + self.ns.args = [] + + # if testdir is set, then we are not running the python tests suite, so + # don't add default tests to be executed or skipped (pass empty values) + if self.ns.testdir: + alltests = findtests(self.ns.testdir, list(), set()) + else: + alltests = findtests(self.ns.testdir, stdtests, nottests) + + self.selected = self.tests or self.ns.args or alltests + if self.ns.single: + self.selected = self.selected[:1] + try: + pos = alltests.index(self.selected[0]) + self.next_single_test = alltests[pos + 1] + except IndexError: + pass + + # Remove all the selected tests that precede start if it's set. + if self.ns.start: + try: + del self.selected[:self.selected.index(self.ns.start)] + except ValueError: + print("Couldn't find starting test (%s), using all tests" + % self.ns.start, file=sys.stderr) + + if self.ns.randomize: + if self.ns.random_seed is None: + self.ns.random_seed = random.randrange(10000000) + random.seed(self.ns.random_seed) + random.shuffle(self.selected) + + def list_tests(self): + for name in self.selected: + print(name) + + def rerun_failed_tests(self): + self.ns.verbose = True + self.ns.failfast = False + self.ns.verbose3 = False + self.ns.match_tests = None + + print("Re-running failed tests in verbose mode") + for test in self.bad[:]: + print("Re-running test %r in verbose mode" % test, flush=True) + try: + self.ns.verbose = True + ok = runtest(self.ns, test) + except KeyboardInterrupt: + # print a newline separate from the ^C + print() + break + else: + if ok[0] in {PASSED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED}: + self.bad.remove(test) + else: + if self.bad: + print(count(len(self.bad), 'test'), "failed again:") + printlist(self.bad) + + def display_result(self): + if self.interrupted: + # print a newline after ^C + print() + print("Test suite interrupted by signal SIGINT.") + executed = set(self.good) | set(self.bad) | set(self.skipped) + omitted = set(self.selected) - executed + print(count(len(omitted), "test"), "omitted:") + printlist(omitted) + + # If running the test suite for PGO then no one cares about + # results. + if self.ns.pgo: + return + + if self.good and not self.ns.quiet: + if (not self.bad + and not self.skipped + and not self.interrupted + and len(self.good) > 1): + print("All", end=' ') + print(count(len(self.good), "test"), "OK.") + + if self.ns.print_slow: + self.test_times.sort(reverse=True) + print("10 slowest tests:") + for time, test in self.test_times[:10]: + print("%s: %.1fs" % (test, time)) + + if self.bad: + print(count(len(self.bad), "test"), "failed:") + printlist(self.bad) + + if self.environment_changed: + print("{} altered the execution environment:".format( + count(len(self.environment_changed), "test"))) + printlist(self.environment_changed) + + if self.skipped and not self.ns.quiet: + print(count(len(self.skipped), "test"), "skipped:") + printlist(self.skipped) + + def run_tests_sequential(self): + if self.ns.trace: + import trace + self.tracer = trace.Trace(trace=False, count=True) + + save_modules = sys.modules.keys() + + for test_index, test in enumerate(self.tests, 1): + self.display_progress(test_index, test) + if self.tracer: + # If we're tracing code coverage, then we don't exit with status + # if on a false return value from main. + cmd = ('result = runtest(self.ns, test); ' + 'self.accumulate_result(test, result)') + self.tracer.runctx(cmd, globals=globals(), locals=vars()) + else: + try: + result = runtest(self.ns, test) + except KeyboardInterrupt: + self.accumulate_result(test, (INTERRUPTED, None)) + self.interrupted = True + break + else: + self.accumulate_result(test, result) + + if self.ns.findleaks: + gc.collect() + if gc.garbage: + print("Warning: test created", len(gc.garbage), end=' ') + print("uncollectable object(s).") + # move the uncollectable objects somewhere so we don't see + # them again + self.found_garbage.extend(gc.garbage) + del gc.garbage[:] + + # Unload the newly imported modules (best effort finalization) + for module in sys.modules.keys(): + if module not in save_modules and module.startswith("test."): + support.unload(module) + + def _test_forever(self, tests): + while True: + for test in tests: + yield test + if self.bad: + return + + def run_tests(self): + # For a partial run, we do not need to clutter the output. + if (self.ns.verbose + or self.ns.header + or not (self.ns.pgo or self.ns.quiet or self.ns.single + or self.tests or self.ns.args)): + # Print basic platform information + print("==", platform.python_implementation(), *sys.version.split()) + print("== ", platform.platform(aliased=True), + "%s-endian" % sys.byteorder) + print("== ", "hash algorithm:", sys.hash_info.algorithm, + "64bit" if sys.maxsize > 2**32 else "32bit") + print("== ", os.getcwd()) + print("Testing with flags:", sys.flags) + + if self.ns.randomize: + print("Using random seed", self.ns.random_seed) + + if self.ns.forever: + self.tests = self._test_forever(list(self.selected)) + self.test_count = '' + self.test_count_width = 3 + else: + self.tests = iter(self.selected) + self.test_count = '/{}'.format(len(self.selected)) + self.test_count_width = len(self.test_count) - 1 + + if self.ns.use_mp: + from test.libregrtest.runtest_mp import run_tests_multiprocess + run_tests_multiprocess(self) + else: + self.run_tests_sequential() + + def finalize(self): + if self.next_single_filename: + if self.next_single_test: + with open(self.next_single_filename, 'w') as fp: + fp.write(self.next_single_test + '\n') + else: + os.unlink(self.next_single_filename) + + if self.tracer: + r = self.tracer.results() + r.write_results(show_missing=True, summary=True, + coverdir=self.ns.coverdir) + + if self.ns.runleaks: + os.system("leaks %d" % os.getpid()) + + def main(self, tests=None, **kwargs): + self.ns = self.parse_args(kwargs) + + if self.ns.slaveargs is not None: + from test.libregrtest.runtest_mp import run_tests_slave + run_tests_slave(self.ns.slaveargs) + + if self.ns.wait: + input("Press any key to continue...") + + setup_tests(self.ns) + + self.find_tests(tests) + + if self.ns.list_tests: + self.list_tests() + sys.exit(0) + + self.run_tests() + self.display_result() + + if self.ns.verbose2 and self.bad: + self.rerun_failed_tests() + + self.finalize() + sys.exit(len(self.bad) > 0 or self.interrupted) + + +def removepy(names): + if not names: + return + for idx, name in enumerate(names): + basename, ext = os.path.splitext(name) + if ext == '.py': + names[idx] = basename + + +def count(n, word): + if n == 1: + return "%d %s" % (n, word) + else: + return "%d %ss" % (n, word) + + +def printlist(x, width=70, indent=4): + """Print the elements of iterable x to stdout. + + Optional arg width (default 70) is the maximum line length. + Optional arg indent (default 4) is the number of blanks with which to + begin each line. + """ + + blanks = ' ' * indent + # Print the sorted list: 'x' may be a '--random' list or a set() + print(textwrap.fill(' '.join(str(elt) for elt in sorted(x)), width, + initial_indent=blanks, subsequent_indent=blanks)) + + +def main(tests=None, **kwargs): + Regrtest().main(tests=tests, **kwargs) + + +def main_in_temp_cwd(): + """Run main() in a temporary working directory.""" + if sysconfig.is_python_build(): + try: + os.mkdir(TEMPDIR) + except FileExistsError: + pass + + # Define a writable temp dir that will be used as cwd while running + # the tests. The name of the dir includes the pid to allow parallel + # testing (see the -j option). + test_cwd = 'test_python_{}'.format(os.getpid()) + test_cwd = os.path.join(TEMPDIR, test_cwd) + + # Run the tests in a context manager that temporarily changes the CWD to a + # temporary and writable directory. If it's not possible to create or + # change the CWD, the original CWD will be used. The original CWD is + # available from support.SAVEDCWD. + with support.temp_cwd(test_cwd, quiet=True): + main() diff --git a/Lib/test/libregrtest/refleak.py b/Lib/test/libregrtest/refleak.py new file mode 100644 index 000000000000..59dc49fe77cc --- /dev/null +++ b/Lib/test/libregrtest/refleak.py @@ -0,0 +1,202 @@ +import errno +import os +import re +import sys +import warnings +from inspect import isabstract +from test import support + + +try: + MAXFD = os.sysconf("SC_OPEN_MAX") +except Exception: + MAXFD = 256 + + +def fd_count(): + """Count the number of open file descriptors""" + if sys.platform.startswith(('linux', 'freebsd')): + try: + names = os.listdir("/proc/self/fd") + return len(names) + except FileNotFoundError: + pass + + count = 0 + for fd in range(MAXFD): + try: + # Prefer dup() over fstat(). fstat() can require input/output + # whereas dup() doesn't. + fd2 = os.dup(fd) + except OSError as e: + if e.errno != errno.EBADF: + raise + else: + os.close(fd2) + count += 1 + return count + + +def dash_R(the_module, test, indirect_test, huntrleaks): + """Run a test multiple times, looking for reference leaks. + + Returns: + False if the test didn't leak references; True if we detected refleaks. + """ + # This code is hackish and inelegant, but it seems to do the job. + import copyreg + import collections.abc + + if not hasattr(sys, 'gettotalrefcount'): + raise Exception("Tracking reference leaks requires a debug build " + "of Python") + + # Save current values for dash_R_cleanup() to restore. + fs = warnings.filters[:] + ps = copyreg.dispatch_table.copy() + pic = sys.path_importer_cache.copy() + try: + import zipimport + except ImportError: + zdc = None # Run unmodified on platforms without zipimport support + else: + zdc = zipimport._zip_directory_cache.copy() + abcs = {} + for abc in [getattr(collections.abc, a) for a in collections.abc.__all__]: + if not isabstract(abc): + continue + for obj in abc.__subclasses__() + [abc]: + abcs[obj] = obj._abc_registry.copy() + + nwarmup, ntracked, fname = huntrleaks + fname = os.path.join(support.SAVEDCWD, fname) + repcount = nwarmup + ntracked + rc_deltas = [0] * repcount + alloc_deltas = [0] * repcount + fd_deltas = [0] * repcount + + print("beginning", repcount, "repetitions", file=sys.stderr) + print(("1234567890"*(repcount//10 + 1))[:repcount], file=sys.stderr, + flush=True) + # initialize variables to make pyflakes quiet + rc_before = alloc_before = fd_before = 0 + for i in range(repcount): + indirect_test() + alloc_after, rc_after, fd_after = dash_R_cleanup(fs, ps, pic, zdc, + abcs) + print('.', end='', flush=True) + if i >= nwarmup: + rc_deltas[i] = rc_after - rc_before + alloc_deltas[i] = alloc_after - alloc_before + fd_deltas[i] = fd_after - fd_before + alloc_before = alloc_after + rc_before = rc_after + fd_before = fd_after + print(file=sys.stderr) + # These checkers return False on success, True on failure + def check_rc_deltas(deltas): + return any(deltas) + def check_alloc_deltas(deltas): + # At least 1/3rd of 0s + if 3 * deltas.count(0) < len(deltas): + return True + # Nothing else than 1s, 0s and -1s + if not set(deltas) <= {1,0,-1}: + return True + return False + failed = False + for deltas, item_name, checker in [ + (rc_deltas, 'references', check_rc_deltas), + (alloc_deltas, 'memory blocks', check_alloc_deltas), + (fd_deltas, 'file descriptors', check_rc_deltas)]: + if checker(deltas): + msg = '%s leaked %s %s, sum=%s' % ( + test, deltas[nwarmup:], item_name, sum(deltas)) + print(msg, file=sys.stderr, flush=True) + with open(fname, "a") as refrep: + print(msg, file=refrep) + refrep.flush() + failed = True + return failed + + +def dash_R_cleanup(fs, ps, pic, zdc, abcs): + import gc, copyreg + import _strptime, linecache + import urllib.parse, urllib.request, mimetypes, doctest + import struct, filecmp, collections.abc + from distutils.dir_util import _path_created + from weakref import WeakSet + + # Clear the warnings registry, so they can be displayed again + for mod in sys.modules.values(): + if hasattr(mod, '__warningregistry__'): + del mod.__warningregistry__ + + # Restore some original values. + warnings.filters[:] = fs + copyreg.dispatch_table.clear() + copyreg.dispatch_table.update(ps) + sys.path_importer_cache.clear() + sys.path_importer_cache.update(pic) + try: + import zipimport + except ImportError: + pass # Run unmodified on platforms without zipimport support + else: + zipimport._zip_directory_cache.clear() + zipimport._zip_directory_cache.update(zdc) + + # clear type cache + sys._clear_type_cache() + + # Clear ABC registries, restoring previously saved ABC registries. + for abc in [getattr(collections.abc, a) for a in collections.abc.__all__]: + if not isabstract(abc): + continue + for obj in abc.__subclasses__() + [abc]: + obj._abc_registry = abcs.get(obj, WeakSet()).copy() + obj._abc_cache.clear() + obj._abc_negative_cache.clear() + + # Flush standard output, so that buffered data is sent to the OS and + # associated Python objects are reclaimed. + for stream in (sys.stdout, sys.stderr, sys.__stdout__, sys.__stderr__): + if stream is not None: + stream.flush() + + # Clear assorted module caches. + _path_created.clear() + re.purge() + _strptime._regex_cache.clear() + urllib.parse.clear_cache() + urllib.request.urlcleanup() + linecache.clearcache() + mimetypes._default_mime_types() + filecmp._cache.clear() + struct._clearcache() + doctest.master = None + try: + import ctypes + except ImportError: + # Don't worry about resetting the cache if ctypes is not supported + pass + else: + ctypes._reset_cache() + + # Collect cyclic trash and read memory statistics immediately after. + func1 = sys.getallocatedblocks + func2 = sys.gettotalrefcount + gc.collect() + return func1(), func2(), fd_count() + + +def warm_caches(): + # char cache + s = bytes(range(256)) + for i in range(256): + s[i:i+1] + # unicode cache + [chr(i) for i in range(256)] + # int cache + list(range(-5, 257)) diff --git a/Lib/test/libregrtest/runtest.py b/Lib/test/libregrtest/runtest.py new file mode 100644 index 000000000000..043f23c09516 --- /dev/null +++ b/Lib/test/libregrtest/runtest.py @@ -0,0 +1,242 @@ +import faulthandler +import importlib +import io +import os +import sys +import time +import traceback +import unittest +from test import support +from test.libregrtest.refleak import dash_R +from test.libregrtest.save_env import saved_test_environment + + +# Test result constants. +PASSED = 1 +FAILED = 0 +ENV_CHANGED = -1 +SKIPPED = -2 +RESOURCE_DENIED = -3 +INTERRUPTED = -4 +CHILD_ERROR = -5 # error in a child process + + +# small set of tests to determine if we have a basically functioning interpreter +# (i.e. if any of these fail, then anything else is likely to follow) +STDTESTS = [ + 'test_grammar', + 'test_opcodes', + 'test_dict', + 'test_builtin', + 'test_exceptions', + 'test_types', + 'test_unittest', + 'test_doctest', + 'test_doctest2', + 'test_support' +] + +# set of tests that we don't want to be executed when using regrtest +NOTTESTS = set() + + +def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS): + """Return a list of all applicable test modules.""" + testdir = findtestdir(testdir) + names = os.listdir(testdir) + tests = [] + others = set(stdtests) | nottests + for name in names: + mod, ext = os.path.splitext(name) + if mod[:5] == "test_" and ext in (".py", "") and mod not in others: + tests.append(mod) + return stdtests + sorted(tests) + + +def runtest(ns, test): + """Run a single test. + + test -- the name of the test + verbose -- if true, print more messages + quiet -- if true, don't print 'skipped' messages (probably redundant) + huntrleaks -- run multiple times to test for leaks; requires a debug + build; a triple corresponding to -R's three arguments + output_on_failure -- if true, display test output on failure + timeout -- dump the traceback and exit if a test takes more than + timeout seconds + failfast, match_tests -- See regrtest command-line flags for these. + pgo -- if true, suppress any info irrelevant to a generating a PGO build + + Returns the tuple result, test_time, where result is one of the constants: + INTERRUPTED KeyboardInterrupt when run under -j + RESOURCE_DENIED test skipped because resource denied + SKIPPED test skipped for some other reason + ENV_CHANGED test failed because it changed the execution environment + FAILED test failed + PASSED test passed + """ + + verbose = ns.verbose + quiet = ns.quiet + huntrleaks = ns.huntrleaks + output_on_failure = ns.verbose3 + failfast = ns.failfast + match_tests = ns.match_tests + timeout = ns.timeout + pgo = ns.pgo + + use_timeout = (timeout is not None) + if use_timeout: + faulthandler.dump_traceback_later(timeout, exit=True) + try: + support.match_tests = match_tests + if failfast: + support.failfast = True + if output_on_failure: + support.verbose = True + + # Reuse the same instance to all calls to runtest(). Some + # tests keep a reference to sys.stdout or sys.stderr + # (eg. test_argparse). + if runtest.stringio is None: + stream = io.StringIO() + runtest.stringio = stream + else: + stream = runtest.stringio + stream.seek(0) + stream.truncate() + + orig_stdout = sys.stdout + orig_stderr = sys.stderr + try: + sys.stdout = stream + sys.stderr = stream + result = runtest_inner(test, verbose, quiet, huntrleaks, + display_failure=False, pgo=pgo) + if result[0] == FAILED: + output = stream.getvalue() + orig_stderr.write(output) + orig_stderr.flush() + finally: + sys.stdout = orig_stdout + sys.stderr = orig_stderr + else: + support.verbose = verbose # Tell tests to be moderately quiet + result = runtest_inner(test, verbose, quiet, huntrleaks, + display_failure=not verbose, pgo=pgo) + return result + finally: + if use_timeout: + faulthandler.cancel_dump_traceback_later() + cleanup_test_droppings(test, verbose) +runtest.stringio = None + + +def runtest_inner(test, verbose, quiet, + huntrleaks=False, display_failure=True, *, pgo=False): + support.unload(test) + + test_time = 0.0 + refleak = False # True if the test leaked references. + try: + if test.startswith('test.'): + abstest = test + else: + # Always import it from the test package + abstest = 'test.' + test + with saved_test_environment(test, verbose, quiet, pgo=pgo) as environment: + start_time = time.time() + the_module = importlib.import_module(abstest) + # If the test has a test_main, that will run the appropriate + # tests. If not, use normal unittest test loading. + test_runner = getattr(the_module, "test_main", None) + if test_runner is None: + def test_runner(): + loader = unittest.TestLoader() + tests = loader.loadTestsFromModule(the_module) + for error in loader.errors: + print(error, file=sys.stderr) + if loader.errors: + raise Exception("errors while loading tests") + support.run_unittest(tests) + test_runner() + if huntrleaks: + refleak = dash_R(the_module, test, test_runner, huntrleaks) + test_time = time.time() - start_time + except support.ResourceDenied as msg: + if not quiet and not pgo: + print(test, "skipped --", msg, flush=True) + return RESOURCE_DENIED, test_time + except unittest.SkipTest as msg: + if not quiet and not pgo: + print(test, "skipped --", msg, flush=True) + return SKIPPED, test_time + except KeyboardInterrupt: + raise + except support.TestFailed as msg: + if not pgo: + if display_failure: + print("test", test, "failed --", msg, file=sys.stderr, + flush=True) + else: + print("test", test, "failed", file=sys.stderr, flush=True) + return FAILED, test_time + except: + msg = traceback.format_exc() + if not pgo: + print("test", test, "crashed --", msg, file=sys.stderr, + flush=True) + return FAILED, test_time + else: + if refleak: + return FAILED, test_time + if environment.changed: + return ENV_CHANGED, test_time + return PASSED, test_time + + +def cleanup_test_droppings(testname, verbose): + import shutil + import stat + import gc + + # First kill any dangling references to open files etc. + # This can also issue some ResourceWarnings which would otherwise get + # triggered during the following test run, and possibly produce failures. + gc.collect() + + # Try to clean up junk commonly left behind. While tests shouldn't leave + # any files or directories behind, when a test fails that can be tedious + # for it to arrange. The consequences can be especially nasty on Windows, + # since if a test leaves a file open, it cannot be deleted by name (while + # there's nothing we can do about that here either, we can display the + # name of the offending test, which is a real help). + for name in (support.TESTFN, + "db_home", + ): + if not os.path.exists(name): + continue + + if os.path.isdir(name): + kind, nuker = "directory", shutil.rmtree + elif os.path.isfile(name): + kind, nuker = "file", os.unlink + else: + raise SystemError("os.path says %r exists but is neither " + "directory nor file" % name) + + if verbose: + print("%r left behind %s %r" % (testname, kind, name)) + try: + # if we have chmod, fix possible permissions problems + # that might prevent cleanup + if (hasattr(os, 'chmod')): + os.chmod(name, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) + nuker(name) + except Exception as msg: + print(("%r left behind %s %r and it couldn't be " + "removed: %s" % (testname, kind, name, msg)), file=sys.stderr) + + +def findtestdir(path=None): + return path or os.path.dirname(os.path.dirname(__file__)) or os.curdir diff --git a/Lib/test/libregrtest/runtest_mp.py b/Lib/test/libregrtest/runtest_mp.py new file mode 100644 index 000000000000..4473db45492f --- /dev/null +++ b/Lib/test/libregrtest/runtest_mp.py @@ -0,0 +1,224 @@ +import json +import os +import queue +import sys +import time +import traceback +import types +from test import support +try: + import threading +except ImportError: + print("Multiprocess option requires thread support") + sys.exit(2) + +from test.libregrtest.runtest import runtest, INTERRUPTED, CHILD_ERROR +from test.libregrtest.setup import setup_tests + + +# Minimum duration of a test to display its duration or to mention that +# the test is running in background +PROGRESS_MIN_TIME = 30.0 # seconds + +# Display the running tests if nothing happened last N seconds +PROGRESS_UPDATE = 60.0 # seconds + + +def run_test_in_subprocess(testname, ns): + """Run the given test in a subprocess with --slaveargs. + + ns is the option Namespace parsed from command-line arguments. regrtest + is invoked in a subprocess with the --slaveargs argument; when the + subprocess exits, its return code, stdout and stderr are returned as a + 3-tuple. + """ + from subprocess import Popen, PIPE + + ns_dict = vars(ns) + slaveargs = (ns_dict, testname) + slaveargs = json.dumps(slaveargs) + + cmd = [sys.executable, *support.args_from_interpreter_flags(), + '-X', 'faulthandler', + '-m', 'test.regrtest', + '--slaveargs', slaveargs] + if ns.pgo: + cmd += ['--pgo'] + + # Running the child from the same working directory as regrtest's original + # invocation ensures that TEMPDIR for the child is the same when + # sysconfig.is_python_build() is true. See issue 15300. + popen = Popen(cmd, + stdout=PIPE, stderr=PIPE, + universal_newlines=True, + close_fds=(os.name != 'nt'), + cwd=support.SAVEDCWD) + with popen: + stdout, stderr = popen.communicate() + retcode = popen.wait() + return retcode, stdout, stderr + + +def run_tests_slave(slaveargs): + ns_dict, testname = json.loads(slaveargs) + ns = types.SimpleNamespace(**ns_dict) + + setup_tests(ns) + + try: + result = runtest(ns, testname) + except KeyboardInterrupt: + result = INTERRUPTED, '' + except BaseException as e: + traceback.print_exc() + result = CHILD_ERROR, str(e) + + print() # Force a newline (just in case) + print(json.dumps(result), flush=True) + sys.exit(0) + + +# We do not use a generator so multiple threads can call next(). +class MultiprocessIterator: + + """A thread-safe iterator over tests for multiprocess mode.""" + + def __init__(self, tests): + self.interrupted = False + self.lock = threading.Lock() + self.tests = tests + + def __iter__(self): + return self + + def __next__(self): + with self.lock: + if self.interrupted: + raise StopIteration('tests interrupted') + return next(self.tests) + + +class MultiprocessThread(threading.Thread): + def __init__(self, pending, output, ns): + super().__init__() + self.pending = pending + self.output = output + self.ns = ns + self.current_test = None + self.start_time = None + + def _runtest(self): + try: + test = next(self.pending) + except StopIteration: + self.output.put((None, None, None, None)) + return True + + try: + self.start_time = time.monotonic() + self.current_test = test + + retcode, stdout, stderr = run_test_in_subprocess(test, self.ns) + finally: + self.current_test = None + + stdout, _, result = stdout.strip().rpartition("\n") + if retcode != 0: + result = (CHILD_ERROR, "Exit code %s" % retcode) + self.output.put((test, stdout.rstrip(), stderr.rstrip(), + result)) + return True + + if not result: + self.output.put((None, None, None, None)) + return True + + result = json.loads(result) + self.output.put((test, stdout.rstrip(), stderr.rstrip(), + result)) + return False + + def run(self): + try: + stop = False + while not stop: + stop = self._runtest() + except BaseException: + self.output.put((None, None, None, None)) + raise + + +def run_tests_multiprocess(regrtest): + output = queue.Queue() + pending = MultiprocessIterator(regrtest.tests) + + workers = [MultiprocessThread(pending, output, regrtest.ns) + for i in range(regrtest.ns.use_mp)] + for worker in workers: + worker.start() + + def get_running(workers): + running = [] + for worker in workers: + current_test = worker.current_test + if not current_test: + continue + dt = time.monotonic() - worker.start_time + if dt >= PROGRESS_MIN_TIME: + running.append('%s (%.0f sec)' % (current_test, dt)) + return running + + finished = 0 + test_index = 1 + timeout = max(PROGRESS_UPDATE, PROGRESS_MIN_TIME) + try: + while finished < regrtest.ns.use_mp: + try: + item = output.get(timeout=timeout) + except queue.Empty: + running = get_running(workers) + if running and not regrtest.ns.pgo: + print('running: %s' % ', '.join(running)) + continue + + test, stdout, stderr, result = item + if test is None: + finished += 1 + continue + regrtest.accumulate_result(test, result) + + # Display progress + text = test + ok, test_time = result + if (ok not in (CHILD_ERROR, INTERRUPTED) + and test_time >= PROGRESS_MIN_TIME + and not regrtest.ns.pgo): + text += ' (%.0f sec)' % test_time + running = get_running(workers) + if running and not regrtest.ns.pgo: + text += ' -- running: %s' % ', '.join(running) + regrtest.display_progress(test_index, text) + + # Copy stdout and stderr from the child process + if stdout: + print(stdout, flush=True) + if stderr and not regrtest.ns.pgo: + print(stderr, file=sys.stderr, flush=True) + + if result[0] == INTERRUPTED: + raise KeyboardInterrupt + if result[0] == CHILD_ERROR: + msg = "Child error on {}: {}".format(test, result[1]) + raise Exception(msg) + test_index += 1 + except KeyboardInterrupt: + regrtest.interrupted = True + pending.interrupted = True + print() + + running = [worker.current_test for worker in workers] + running = list(filter(bool, running)) + if running: + print("Waiting for %s" % ', '.join(running)) + for worker in workers: + worker.join() diff --git a/Lib/test/libregrtest/save_env.py b/Lib/test/libregrtest/save_env.py new file mode 100644 index 000000000000..90900a977013 --- /dev/null +++ b/Lib/test/libregrtest/save_env.py @@ -0,0 +1,285 @@ +import builtins +import locale +import logging +import os +import shutil +import sys +import sysconfig +import warnings +from test import support +try: + import threading +except ImportError: + threading = None +try: + import _multiprocessing, multiprocessing.process +except ImportError: + multiprocessing = None + + +# Unit tests are supposed to leave the execution environment unchanged +# once they complete. But sometimes tests have bugs, especially when +# tests fail, and the changes to environment go on to mess up other +# tests. This can cause issues with buildbot stability, since tests +# are run in random order and so problems may appear to come and go. +# There are a few things we can save and restore to mitigate this, and +# the following context manager handles this task. + +class saved_test_environment: + """Save bits of the test environment and restore them at block exit. + + with saved_test_environment(testname, verbose, quiet): + #stuff + + Unless quiet is True, a warning is printed to stderr if any of + the saved items was changed by the test. The attribute 'changed' + is initially False, but is set to True if a change is detected. + + If verbose is more than 1, the before and after state of changed + items is also printed. + """ + + changed = False + + def __init__(self, testname, verbose=0, quiet=False, *, pgo=False): + self.testname = testname + self.verbose = verbose + self.quiet = quiet + self.pgo = pgo + + # To add things to save and restore, add a name XXX to the resources list + # and add corresponding get_XXX/restore_XXX functions. get_XXX should + # return the value to be saved and compared against a second call to the + # get function when test execution completes. restore_XXX should accept + # the saved value and restore the resource using it. It will be called if + # and only if a change in the value is detected. + # + # Note: XXX will have any '.' replaced with '_' characters when determining + # the corresponding method names. + + resources = ('sys.argv', 'cwd', 'sys.stdin', 'sys.stdout', 'sys.stderr', + 'os.environ', 'sys.path', 'sys.path_hooks', '__import__', + 'warnings.filters', 'asyncore.socket_map', + 'logging._handlers', 'logging._handlerList', 'sys.gettrace', + 'sys.warnoptions', + # multiprocessing.process._cleanup() may release ref + # to a thread, so check processes first. + 'multiprocessing.process._dangling', 'threading._dangling', + 'sysconfig._CONFIG_VARS', 'sysconfig._INSTALL_SCHEMES', + 'files', 'locale', 'warnings.showwarning', + ) + + def get_sys_argv(self): + return id(sys.argv), sys.argv, sys.argv[:] + def restore_sys_argv(self, saved_argv): + sys.argv = saved_argv[1] + sys.argv[:] = saved_argv[2] + + def get_cwd(self): + return os.getcwd() + def restore_cwd(self, saved_cwd): + os.chdir(saved_cwd) + + def get_sys_stdout(self): + return sys.stdout + def restore_sys_stdout(self, saved_stdout): + sys.stdout = saved_stdout + + def get_sys_stderr(self): + return sys.stderr + def restore_sys_stderr(self, saved_stderr): + sys.stderr = saved_stderr + + def get_sys_stdin(self): + return sys.stdin + def restore_sys_stdin(self, saved_stdin): + sys.stdin = saved_stdin + + def get_os_environ(self): + return id(os.environ), os.environ, dict(os.environ) + def restore_os_environ(self, saved_environ): + os.environ = saved_environ[1] + os.environ.clear() + os.environ.update(saved_environ[2]) + + def get_sys_path(self): + return id(sys.path), sys.path, sys.path[:] + def restore_sys_path(self, saved_path): + sys.path = saved_path[1] + sys.path[:] = saved_path[2] + + def get_sys_path_hooks(self): + return id(sys.path_hooks), sys.path_hooks, sys.path_hooks[:] + def restore_sys_path_hooks(self, saved_hooks): + sys.path_hooks = saved_hooks[1] + sys.path_hooks[:] = saved_hooks[2] + + def get_sys_gettrace(self): + return sys.gettrace() + def restore_sys_gettrace(self, trace_fxn): + sys.settrace(trace_fxn) + + def get___import__(self): + return builtins.__import__ + def restore___import__(self, import_): + builtins.__import__ = import_ + + def get_warnings_filters(self): + return id(warnings.filters), warnings.filters, warnings.filters[:] + def restore_warnings_filters(self, saved_filters): + warnings.filters = saved_filters[1] + warnings.filters[:] = saved_filters[2] + + def get_asyncore_socket_map(self): + asyncore = sys.modules.get('asyncore') + # XXX Making a copy keeps objects alive until __exit__ gets called. + return asyncore and asyncore.socket_map.copy() or {} + def restore_asyncore_socket_map(self, saved_map): + asyncore = sys.modules.get('asyncore') + if asyncore is not None: + asyncore.close_all(ignore_all=True) + asyncore.socket_map.update(saved_map) + + def get_shutil_archive_formats(self): + # we could call get_archives_formats() but that only returns the + # registry keys; we want to check the values too (the functions that + # are registered) + return shutil._ARCHIVE_FORMATS, shutil._ARCHIVE_FORMATS.copy() + def restore_shutil_archive_formats(self, saved): + shutil._ARCHIVE_FORMATS = saved[0] + shutil._ARCHIVE_FORMATS.clear() + shutil._ARCHIVE_FORMATS.update(saved[1]) + + def get_shutil_unpack_formats(self): + return shutil._UNPACK_FORMATS, shutil._UNPACK_FORMATS.copy() + def restore_shutil_unpack_formats(self, saved): + shutil._UNPACK_FORMATS = saved[0] + shutil._UNPACK_FORMATS.clear() + shutil._UNPACK_FORMATS.update(saved[1]) + + def get_logging__handlers(self): + # _handlers is a WeakValueDictionary + return id(logging._handlers), logging._handlers, logging._handlers.copy() + def restore_logging__handlers(self, saved_handlers): + # Can't easily revert the logging state + pass + + def get_logging__handlerList(self): + # _handlerList is a list of weakrefs to handlers + return id(logging._handlerList), logging._handlerList, logging._handlerList[:] + def restore_logging__handlerList(self, saved_handlerList): + # Can't easily revert the logging state + pass + + def get_sys_warnoptions(self): + return id(sys.warnoptions), sys.warnoptions, sys.warnoptions[:] + def restore_sys_warnoptions(self, saved_options): + sys.warnoptions = saved_options[1] + sys.warnoptions[:] = saved_options[2] + + # Controlling dangling references to Thread objects can make it easier + # to track reference leaks. + def get_threading__dangling(self): + if not threading: + return None + # This copies the weakrefs without making any strong reference + return threading._dangling.copy() + def restore_threading__dangling(self, saved): + if not threading: + return + threading._dangling.clear() + threading._dangling.update(saved) + + # Same for Process objects + def get_multiprocessing_process__dangling(self): + if not multiprocessing: + return None + # Unjoined process objects can survive after process exits + multiprocessing.process._cleanup() + # This copies the weakrefs without making any strong reference + return multiprocessing.process._dangling.copy() + def restore_multiprocessing_process__dangling(self, saved): + if not multiprocessing: + return + multiprocessing.process._dangling.clear() + multiprocessing.process._dangling.update(saved) + + def get_sysconfig__CONFIG_VARS(self): + # make sure the dict is initialized + sysconfig.get_config_var('prefix') + return (id(sysconfig._CONFIG_VARS), sysconfig._CONFIG_VARS, + dict(sysconfig._CONFIG_VARS)) + def restore_sysconfig__CONFIG_VARS(self, saved): + sysconfig._CONFIG_VARS = saved[1] + sysconfig._CONFIG_VARS.clear() + sysconfig._CONFIG_VARS.update(saved[2]) + + def get_sysconfig__INSTALL_SCHEMES(self): + return (id(sysconfig._INSTALL_SCHEMES), sysconfig._INSTALL_SCHEMES, + sysconfig._INSTALL_SCHEMES.copy()) + def restore_sysconfig__INSTALL_SCHEMES(self, saved): + sysconfig._INSTALL_SCHEMES = saved[1] + sysconfig._INSTALL_SCHEMES.clear() + sysconfig._INSTALL_SCHEMES.update(saved[2]) + + def get_files(self): + return sorted(fn + ('/' if os.path.isdir(fn) else '') + for fn in os.listdir()) + def restore_files(self, saved_value): + fn = support.TESTFN + if fn not in saved_value and (fn + '/') not in saved_value: + if os.path.isfile(fn): + support.unlink(fn) + elif os.path.isdir(fn): + support.rmtree(fn) + + _lc = [getattr(locale, lc) for lc in dir(locale) + if lc.startswith('LC_')] + def get_locale(self): + pairings = [] + for lc in self._lc: + try: + pairings.append((lc, locale.setlocale(lc, None))) + except (TypeError, ValueError): + continue + return pairings + def restore_locale(self, saved): + for lc, setting in saved: + locale.setlocale(lc, setting) + + def get_warnings_showwarning(self): + return warnings.showwarning + def restore_warnings_showwarning(self, fxn): + warnings.showwarning = fxn + + def resource_info(self): + for name in self.resources: + method_suffix = name.replace('.', '_') + get_name = 'get_' + method_suffix + restore_name = 'restore_' + method_suffix + yield name, getattr(self, get_name), getattr(self, restore_name) + + def __enter__(self): + self.saved_values = dict((name, get()) for name, get, restore + in self.resource_info()) + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + saved_values = self.saved_values + del self.saved_values + for name, get, restore in self.resource_info(): + current = get() + original = saved_values.pop(name) + # Check for changes to the resource's value + if current != original: + self.changed = True + restore(original) + if not self.quiet and not self.pgo: + print("Warning -- {} was modified by {}".format( + name, self.testname), + file=sys.stderr) + if self.verbose > 1: + print(" Before: {}\n After: {} ".format( + original, current), + file=sys.stderr) + return False diff --git a/Lib/test/libregrtest/setup.py b/Lib/test/libregrtest/setup.py new file mode 100644 index 000000000000..6e05c7e6ffaf --- /dev/null +++ b/Lib/test/libregrtest/setup.py @@ -0,0 +1,116 @@ +import atexit +import faulthandler +import os +import signal +import sys +import unittest +from test import support +try: + import gc +except ImportError: + gc = None + +from test.libregrtest.refleak import warm_caches + + +def setup_tests(ns): + # Display the Python traceback on fatal errors (e.g. segfault) + faulthandler.enable(all_threads=True) + + # Display the Python traceback on SIGALRM or SIGUSR1 signal + signals = [] + if hasattr(signal, 'SIGALRM'): + signals.append(signal.SIGALRM) + if hasattr(signal, 'SIGUSR1'): + signals.append(signal.SIGUSR1) + for signum in signals: + faulthandler.register(signum, chain=True) + + replace_stdout() + support.record_original_stdout(sys.stdout) + + # Some times __path__ and __file__ are not absolute (e.g. while running from + # Lib/) and, if we change the CWD to run the tests in a temporary dir, some + # imports might fail. This affects only the modules imported before os.chdir(). + # These modules are searched first in sys.path[0] (so '' -- the CWD) and if + # they are found in the CWD their __file__ and __path__ will be relative (this + # happens before the chdir). All the modules imported after the chdir, are + # not found in the CWD, and since the other paths in sys.path[1:] are absolute + # (site.py absolutize them), the __file__ and __path__ will be absolute too. + # Therefore it is necessary to absolutize manually the __file__ and __path__ of + # the packages to prevent later imports to fail when the CWD is different. + for module in sys.modules.values(): + if hasattr(module, '__path__'): + module.__path__ = [os.path.abspath(path) + for path in module.__path__] + if hasattr(module, '__file__'): + module.__file__ = os.path.abspath(module.__file__) + + # MacOSX (a.k.a. Darwin) has a default stack size that is too small + # for deeply recursive regular expressions. We see this as crashes in + # the Python test suite when running test_re.py and test_sre.py. The + # fix is to set the stack limit to 2048. + # This approach may also be useful for other Unixy platforms that + # suffer from small default stack limits. + if sys.platform == 'darwin': + try: + import resource + except ImportError: + pass + else: + soft, hard = resource.getrlimit(resource.RLIMIT_STACK) + newsoft = min(hard, max(soft, 1024*2048)) + resource.setrlimit(resource.RLIMIT_STACK, (newsoft, hard)) + + if ns.huntrleaks: + unittest.BaseTestSuite._cleanup = False + + # Avoid false positives due to various caches + # filling slowly with random data: + warm_caches() + + if ns.memlimit is not None: + support.set_memlimit(ns.memlimit) + + if ns.threshold is not None: + gc.set_threshold(ns.threshold) + + try: + import msvcrt + except ImportError: + pass + else: + msvcrt.SetErrorMode(msvcrt.SEM_FAILCRITICALERRORS| + msvcrt.SEM_NOALIGNMENTFAULTEXCEPT| + msvcrt.SEM_NOGPFAULTERRORBOX| + msvcrt.SEM_NOOPENFILEERRORBOX) + try: + msvcrt.CrtSetReportMode + except AttributeError: + # release build + pass + else: + for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]: + if ns.verbose and ns.verbose >= 2: + msvcrt.CrtSetReportMode(m, msvcrt.CRTDBG_MODE_FILE) + msvcrt.CrtSetReportFile(m, msvcrt.CRTDBG_FILE_STDERR) + else: + msvcrt.CrtSetReportMode(m, 0) + + support.use_resources = ns.use_resources + + +def replace_stdout(): + """Set stdout encoder error handler to backslashreplace (as stderr error + handler) to avoid UnicodeEncodeError when printing a traceback""" + stdout = sys.stdout + sys.stdout = open(stdout.fileno(), 'w', + encoding=stdout.encoding, + errors="backslashreplace", + closefd=False, + newline='\n') + + def restore_stdout(): + sys.stdout.close() + sys.stdout = stdout + atexit.register(restore_stdout) diff --git a/Lib/test/list_tests.py b/Lib/test/list_tests.py index 42e118ba8f8f..1adfc75b77a0 100644 --- a/Lib/test/list_tests.py +++ b/Lib/test/list_tests.py @@ -30,6 +30,12 @@ def test_init(self): self.assertNotEqual(id(a), id(b)) self.assertEqual(a, b) + def test_getitem_error(self): + msg = "list indices must be integers or slices" + with self.assertRaisesRegex(TypeError, msg): + a = [] + a['a'] = "python" + def test_repr(self): l0 = [] l2 = [0, 1, 2] @@ -50,7 +56,7 @@ def test_repr(self): l0 = [] for i in range(sys.getrecursionlimit() + 100): l0 = [l0] - self.assertRaises(RuntimeError, repr, l0) + self.assertRaises(RecursionError, repr, l0) def test_print(self): d = self.type2test(range(200)) @@ -120,6 +126,10 @@ def test_setitem(self): a[-1] = 9 self.assertEqual(a, self.type2test([5,6,7,8,9])) + msg = "list indices must be integers or slices" + with self.assertRaisesRegex(TypeError, msg): + a['a'] = "python" + def test_delitem(self): a = self.type2test([0, 1]) del a[1] diff --git a/Lib/test/lock_tests.py b/Lib/test/lock_tests.py index 1cbcea234396..055bf28565d1 100644 --- a/Lib/test/lock_tests.py +++ b/Lib/test/lock_tests.py @@ -7,6 +7,7 @@ from _thread import start_new_thread, TIMEOUT_MAX import threading import unittest +import weakref from test import support @@ -39,8 +40,12 @@ def task(): self.finished.append(tid) while not self._can_exit: _wait() - for i in range(n): - start_new_thread(task, ()) + try: + for i in range(n): + start_new_thread(task, ()) + except: + self._can_exit = True + raise def wait_for_started(self): while len(self.started) < self.n: @@ -82,7 +87,13 @@ def test_constructor(self): def test_repr(self): lock = self.locktype() - repr(lock) + self.assertRegex(repr(lock), "") + del lock + + def test_locked_repr(self): + lock = self.locktype() + lock.acquire() + self.assertRegex(repr(lock), "") del lock def test_acquire_destroy(self): @@ -188,6 +199,17 @@ def f(): self.assertFalse(results[0]) self.assertTimeout(results[1], 0.5) + def test_weakref_exists(self): + lock = self.locktype() + ref = weakref.ref(lock) + self.assertIsNotNone(ref()) + + def test_weakref_deleted(self): + lock = self.locktype() + ref = weakref.ref(lock) + del lock + self.assertIsNone(ref()) + class LockTests(BaseLockTests): """ @@ -384,6 +406,14 @@ def f(): b.wait_for_finished() self.assertEqual(results, [True] * N) + def test_reset_internal_locks(self): + evt = self.eventtype() + old_lock = evt._cond._lock + evt._reset_internal_locks() + new_lock = evt._cond._lock + self.assertIsNot(new_lock, old_lock) + self.assertIs(type(new_lock), type(old_lock)) + class ConditionTests(BaseTestCase): """ diff --git a/Lib/test/make_ssl_certs.py b/Lib/test/make_ssl_certs.py index 4251d5524ffa..81d04f82dcfb 100644 --- a/Lib/test/make_ssl_certs.py +++ b/Lib/test/make_ssl_certs.py @@ -115,7 +115,7 @@ def make_ca(): with open(os.path.join('cadir','index.txt'),'a+') as f: pass # empty file with open(os.path.join('cadir','crl.txt'),'a+') as f: - r.write("00") + f.write("00") with open(os.path.join('cadir','index.txt.attr'),'w+') as f: f.write('unique_subject = no') diff --git a/Lib/test/mapping_tests.py b/Lib/test/mapping_tests.py index bc12c7756f2d..ff82f4eb7d89 100644 --- a/Lib/test/mapping_tests.py +++ b/Lib/test/mapping_tests.py @@ -64,7 +64,7 @@ def test_read(self): self.assertEqual(d, d) self.assertNotEqual(p, d) self.assertNotEqual(d, p) - #__non__zero__ + #bool if p: self.fail("Empty mapping must compare to False") if not d: self.fail("Full mapping must compare to True") # keys(), items(), iterkeys() ... diff --git a/Lib/test/mock_socket.py b/Lib/test/mock_socket.py index 8ef0ec8c8dae..b28c4732cc3c 100644 --- a/Lib/test/mock_socket.py +++ b/Lib/test/mock_socket.py @@ -21,8 +21,13 @@ class MockFile: """ def __init__(self, lines): self.lines = lines - def readline(self): - return self.lines.pop(0) + b'\r\n' + def readline(self, limit=-1): + result = self.lines.pop(0) + b'\r\n' + if limit >= 0: + # Re-insert the line, removing the \r\n we added. + self.lines.insert(0, result[limit:-2]) + result = result[:limit] + return result def close(self): pass @@ -30,8 +35,9 @@ def close(self): class MockSocket: """Mock socket object used by smtpd and smtplib tests. """ - def __init__(self): + def __init__(self, family=None): global _reply_data + self.family = family self.output = [] self.lines = [] if _reply_data: @@ -96,15 +102,14 @@ def send(self, data, flags=None): return len(data) def getpeername(self): - return 'peer' + return ('peer-address', 'peer-port') def close(self): pass def socket(family=None, type=None, proto=None): - return MockSocket() - + return MockSocket(family) def create_connection(address, timeout=socket_module._GLOBAL_DEFAULT_TIMEOUT, source_address=None): @@ -139,13 +144,16 @@ def gethostname(): def gethostbyname(name): return "" +def getaddrinfo(*args, **kw): + return socket_module.getaddrinfo(*args, **kw) gaierror = socket_module.gaierror error = socket_module.error # Constants -AF_INET = None -SOCK_STREAM = None +AF_INET = socket_module.AF_INET +AF_INET6 = socket_module.AF_INET6 +SOCK_STREAM = socket_module.SOCK_STREAM SOL_SOCKET = None SO_REUSEADDR = None diff --git a/Lib/test/multibytecodec_support.py b/Lib/test/multibytecodec_support.py index dcaae7b95c0d..f9884c68ebaa 100644 --- a/Lib/test/multibytecodec_support.py +++ b/Lib/test/multibytecodec_support.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # multibytecodec_support.py # Common Unittest Routines for CJK codecs @@ -22,7 +21,7 @@ class TestBase: roundtriptest = 1 # set if roundtrip is possible with unicode has_iso10646 = 0 # set if this encoding contains whole iso10646 map xmlcharnametest = None # string to test xmlcharrefreplace - unmappedunicode = '\udeee' # a unicode codepoint that is not mapped. + unmappedunicode = '\udeee' # a unicode code point that is not mapped. def setUp(self): if self.codec is None: @@ -73,7 +72,7 @@ def test_errorhandle(self): def test_xmlcharrefreplace(self): if self.has_iso10646: - return + self.skipTest('encoding contains full ISO 10646 map') s = "\u0b13\u0b23\u0b60 nd eggs" self.assertEqual( @@ -83,7 +82,7 @@ def test_xmlcharrefreplace(self): def test_customreplace_encode(self): if self.has_iso10646: - return + self.skipTest('encoding contains full ISO 10646 map') from html.entities import codepoint2name @@ -271,6 +270,13 @@ def test_streamwriter(self): self.assertEqual(ostream.getvalue(), self.tstring[0]) + def test_streamwriter_reset_no_pending(self): + # Issue #23247: Calling reset() on a fresh StreamWriter instance + # (without pending data) must not crash + stream = BytesIO() + writer = self.writer(stream) + writer.reset() + class TestBase_Mapping(unittest.TestCase): pass_enctest = [] @@ -278,8 +284,7 @@ class TestBase_Mapping(unittest.TestCase): supmaps = [] codectests = [] - def __init__(self, *args, **kw): - unittest.TestCase.__init__(self, *args, **kw) + def setUp(self): try: self.open_mapping_file().close() # test it to report the error early except (OSError, HTTPException): diff --git a/Lib/test/outstanding_bugs.py b/Lib/test/outstanding_bugs.py index 0849ee588582..7e527a670643 100644 --- a/Lib/test/outstanding_bugs.py +++ b/Lib/test/outstanding_bugs.py @@ -10,79 +10,9 @@ from test import support # -# One test case for outstanding bugs at the moment: +# No test cases for outstanding bugs at the moment. # -# test_io -import io -class TextIOWrapperTest(unittest.TestCase): - - def setUp(self): - self.testdata = b"AAA\r\nBBB\rCCC\r\nDDD\nEEE\r\n" - self.normalized = b"AAA\nBBB\nCCC\nDDD\nEEE\n".decode("ASCII") - - def tearDown(self): - support.unlink(support.TESTFN) - - - def test_issue1395_1(self): - txt = io.TextIOWrapper(io.BytesIO(self.testdata), encoding="ASCII") - - # read one char at a time - reads = "" - while True: - c = txt.read(1) - if not c: - break - reads += c - self.assertEqual(reads, self.normalized) - - def test_issue1395_2(self): - txt = io.TextIOWrapper(io.BytesIO(self.testdata), encoding="ASCII") - txt._CHUNK_SIZE = 4 - - reads = "" - while True: - c = txt.read(4) - if not c: - break - reads += c - self.assertEqual(reads, self.normalized) - - def test_issue1395_3(self): - txt = io.TextIOWrapper(io.BytesIO(self.testdata), encoding="ASCII") - txt._CHUNK_SIZE = 4 - - reads = txt.read(4) - reads += txt.read(4) - reads += txt.readline() - reads += txt.readline() - reads += txt.readline() - self.assertEqual(reads, self.normalized) - - def test_issue1395_4(self): - txt = io.TextIOWrapper(io.BytesIO(self.testdata), encoding="ASCII") - txt._CHUNK_SIZE = 4 - - reads = txt.read(4) - reads += txt.read() - self.assertEqual(reads, self.normalized) - - def test_issue1395_5(self): - txt = io.TextIOWrapper(io.BytesIO(self.testdata), encoding="ASCII") - txt._CHUNK_SIZE = 4 - - reads = txt.read(4) - pos = txt.tell() - txt.seek(0) - txt.seek(pos) - self.assertEqual(txt.read(4), "BBB\n") - - - -def test_main(): - support.run_unittest( - TextIOWrapperTest) if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index 30b21bf62cb1..fd641e31617b 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -1,8 +1,11 @@ +import collections import copyreg +import dbm import io +import functools import pickle import pickletools -import random +import struct import sys import unittest import weakref @@ -15,13 +18,14 @@ from pickle import bytes_types +requires_32b = unittest.skipUnless(sys.maxsize < 2**32, + "test is only meaningful on 32-bit builds") + # Tests that try a number of pickle protocols should have a # for proto in protocols: # kind of outer loop. protocols = range(pickle.HIGHEST_PROTOCOL + 1) -ascii_char_size = 1 - # Return True if opcode code appears in the pickle, else False. def opcode_in_pickle(code, pickle): @@ -141,25 +145,26 @@ def create_dynamic_class(name, bases): result.reduce_args = (name, bases) return result -# DATA0 .. DATA2 are the pickles we expect under the various protocols, for +# DATA0 .. DATA4 are the pickles we expect under the various protocols, for # the object returned by create_data(). DATA0 = ( - b'(lp0\nL0L\naL1L\naF2.0\nac' - b'builtins\ncomplex\n' - b'p1\n(F3.0\nF0.0\ntp2\nRp' - b'3\naL1L\naL-1L\naL255L\naL-' - b'255L\naL-256L\naL65535L\na' - b'L-65535L\naL-65536L\naL2' - b'147483647L\naL-2147483' - b'647L\naL-2147483648L\na(' - b'Vabc\np4\ng4\nccopyreg' - b'\n_reconstructor\np5\n(' - b'c__main__\nC\np6\ncbu' - b'iltins\nobject\np7\nNt' - b'p8\nRp9\n(dp10\nVfoo\np1' - b'1\nL1L\nsVbar\np12\nL2L\nsb' - b'g9\ntp13\nag13\naL5L\na.' + b'(lp0\nL0L\naL1L\naF2.0\n' + b'ac__builtin__\ncomple' + b'x\np1\n(F3.0\nF0.0\ntp2\n' + b'Rp3\naL1L\naL-1L\naL255' + b'L\naL-255L\naL-256L\naL' + b'65535L\naL-65535L\naL-' + b'65536L\naL2147483647L' + b'\naL-2147483647L\naL-2' + b'147483648L\na(Vabc\np4' + b'\ng4\nccopy_reg\n_recon' + b'structor\np5\n(c__main' + b'__\nC\np6\nc__builtin__' + b'\nobject\np7\nNtp8\nRp9\n' + b'(dp10\nVfoo\np11\nL1L\ns' + b'Vbar\np12\nL2L\nsbg9\ntp' + b'13\nag13\naL5L\na.' ) # Disassembly of DATA0 @@ -173,88 +178,88 @@ def create_dynamic_class(name, bases): 14: a APPEND 15: F FLOAT 2.0 20: a APPEND - 21: c GLOBAL 'builtins complex' - 39: p PUT 1 - 42: ( MARK - 43: F FLOAT 3.0 - 48: F FLOAT 0.0 - 53: t TUPLE (MARK at 42) - 54: p PUT 2 - 57: R REDUCE - 58: p PUT 3 - 61: a APPEND - 62: L LONG 1 - 66: a APPEND - 67: L LONG -1 - 72: a APPEND - 73: L LONG 255 - 79: a APPEND - 80: L LONG -255 - 87: a APPEND - 88: L LONG -256 - 95: a APPEND - 96: L LONG 65535 - 104: a APPEND - 105: L LONG -65535 - 114: a APPEND - 115: L LONG -65536 - 124: a APPEND - 125: L LONG 2147483647 - 138: a APPEND - 139: L LONG -2147483647 - 153: a APPEND - 154: L LONG -2147483648 - 168: a APPEND - 169: ( MARK - 170: V UNICODE 'abc' - 175: p PUT 4 - 178: g GET 4 - 181: c GLOBAL 'copyreg _reconstructor' - 205: p PUT 5 - 208: ( MARK - 209: c GLOBAL '__main__ C' - 221: p PUT 6 - 224: c GLOBAL 'builtins object' - 241: p PUT 7 - 244: N NONE - 245: t TUPLE (MARK at 208) - 246: p PUT 8 - 249: R REDUCE - 250: p PUT 9 - 253: ( MARK - 254: d DICT (MARK at 253) - 255: p PUT 10 - 259: V UNICODE 'foo' - 264: p PUT 11 - 268: L LONG 1 - 272: s SETITEM - 273: V UNICODE 'bar' - 278: p PUT 12 - 282: L LONG 2 - 286: s SETITEM - 287: b BUILD - 288: g GET 9 - 291: t TUPLE (MARK at 169) - 292: p PUT 13 - 296: a APPEND - 297: g GET 13 - 301: a APPEND - 302: L LONG 5 - 306: a APPEND - 307: . STOP + 21: c GLOBAL '__builtin__ complex' + 42: p PUT 1 + 45: ( MARK + 46: F FLOAT 3.0 + 51: F FLOAT 0.0 + 56: t TUPLE (MARK at 45) + 57: p PUT 2 + 60: R REDUCE + 61: p PUT 3 + 64: a APPEND + 65: L LONG 1 + 69: a APPEND + 70: L LONG -1 + 75: a APPEND + 76: L LONG 255 + 82: a APPEND + 83: L LONG -255 + 90: a APPEND + 91: L LONG -256 + 98: a APPEND + 99: L LONG 65535 + 107: a APPEND + 108: L LONG -65535 + 117: a APPEND + 118: L LONG -65536 + 127: a APPEND + 128: L LONG 2147483647 + 141: a APPEND + 142: L LONG -2147483647 + 156: a APPEND + 157: L LONG -2147483648 + 171: a APPEND + 172: ( MARK + 173: V UNICODE 'abc' + 178: p PUT 4 + 181: g GET 4 + 184: c GLOBAL 'copy_reg _reconstructor' + 209: p PUT 5 + 212: ( MARK + 213: c GLOBAL '__main__ C' + 225: p PUT 6 + 228: c GLOBAL '__builtin__ object' + 248: p PUT 7 + 251: N NONE + 252: t TUPLE (MARK at 212) + 253: p PUT 8 + 256: R REDUCE + 257: p PUT 9 + 260: ( MARK + 261: d DICT (MARK at 260) + 262: p PUT 10 + 266: V UNICODE 'foo' + 271: p PUT 11 + 275: L LONG 1 + 279: s SETITEM + 280: V UNICODE 'bar' + 285: p PUT 12 + 289: L LONG 2 + 293: s SETITEM + 294: b BUILD + 295: g GET 9 + 298: t TUPLE (MARK at 172) + 299: p PUT 13 + 303: a APPEND + 304: g GET 13 + 308: a APPEND + 309: L LONG 5 + 313: a APPEND + 314: . STOP highest protocol among opcodes = 0 """ DATA1 = ( - b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c' - b'builtins\ncomplex\nq\x01' + b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c__' + b'builtin__\ncomplex\nq\x01' b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t' b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ' b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff' b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab' - b'cq\x04h\x04ccopyreg\n_reco' + b'cq\x04h\x04ccopy_reg\n_reco' b'nstructor\nq\x05(c__main' - b'__\nC\nq\x06cbuiltins\n' + b'__\nC\nq\x06c__builtin__\n' b'object\nq\x07Ntq\x08Rq\t}q\n(' b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar' b'q\x0cK\x02ubh\ttq\rh\rK\x05e.' @@ -268,66 +273,66 @@ def create_dynamic_class(name, bases): 4: K BININT1 0 6: K BININT1 1 8: G BINFLOAT 2.0 - 17: c GLOBAL 'builtins complex' - 35: q BINPUT 1 - 37: ( MARK - 38: G BINFLOAT 3.0 - 47: G BINFLOAT 0.0 - 56: t TUPLE (MARK at 37) - 57: q BINPUT 2 - 59: R REDUCE - 60: q BINPUT 3 - 62: K BININT1 1 - 64: J BININT -1 - 69: K BININT1 255 - 71: J BININT -255 - 76: J BININT -256 - 81: M BININT2 65535 - 84: J BININT -65535 - 89: J BININT -65536 - 94: J BININT 2147483647 - 99: J BININT -2147483647 - 104: J BININT -2147483648 - 109: ( MARK - 110: X BINUNICODE 'abc' - 118: q BINPUT 4 - 120: h BINGET 4 - 122: c GLOBAL 'copyreg _reconstructor' - 146: q BINPUT 5 - 148: ( MARK - 149: c GLOBAL '__main__ C' - 161: q BINPUT 6 - 163: c GLOBAL 'builtins object' - 180: q BINPUT 7 - 182: N NONE - 183: t TUPLE (MARK at 148) - 184: q BINPUT 8 - 186: R REDUCE - 187: q BINPUT 9 - 189: } EMPTY_DICT - 190: q BINPUT 10 - 192: ( MARK - 193: X BINUNICODE 'foo' - 201: q BINPUT 11 - 203: K BININT1 1 - 205: X BINUNICODE 'bar' - 213: q BINPUT 12 - 215: K BININT1 2 - 217: u SETITEMS (MARK at 192) - 218: b BUILD - 219: h BINGET 9 - 221: t TUPLE (MARK at 109) - 222: q BINPUT 13 - 224: h BINGET 13 - 226: K BININT1 5 - 228: e APPENDS (MARK at 3) - 229: . STOP + 17: c GLOBAL '__builtin__ complex' + 38: q BINPUT 1 + 40: ( MARK + 41: G BINFLOAT 3.0 + 50: G BINFLOAT 0.0 + 59: t TUPLE (MARK at 40) + 60: q BINPUT 2 + 62: R REDUCE + 63: q BINPUT 3 + 65: K BININT1 1 + 67: J BININT -1 + 72: K BININT1 255 + 74: J BININT -255 + 79: J BININT -256 + 84: M BININT2 65535 + 87: J BININT -65535 + 92: J BININT -65536 + 97: J BININT 2147483647 + 102: J BININT -2147483647 + 107: J BININT -2147483648 + 112: ( MARK + 113: X BINUNICODE 'abc' + 121: q BINPUT 4 + 123: h BINGET 4 + 125: c GLOBAL 'copy_reg _reconstructor' + 150: q BINPUT 5 + 152: ( MARK + 153: c GLOBAL '__main__ C' + 165: q BINPUT 6 + 167: c GLOBAL '__builtin__ object' + 187: q BINPUT 7 + 189: N NONE + 190: t TUPLE (MARK at 152) + 191: q BINPUT 8 + 193: R REDUCE + 194: q BINPUT 9 + 196: } EMPTY_DICT + 197: q BINPUT 10 + 199: ( MARK + 200: X BINUNICODE 'foo' + 208: q BINPUT 11 + 210: K BININT1 1 + 212: X BINUNICODE 'bar' + 220: q BINPUT 12 + 222: K BININT1 2 + 224: u SETITEMS (MARK at 199) + 225: b BUILD + 226: h BINGET 9 + 228: t TUPLE (MARK at 112) + 229: q BINPUT 13 + 231: h BINGET 13 + 233: K BININT1 5 + 235: e APPENDS (MARK at 3) + 236: . STOP highest protocol among opcodes = 1 """ DATA2 = ( b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c' - b'builtins\ncomplex\n' + b'__builtin__\ncomplex\n' b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00' b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff' b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff' @@ -347,6 +352,77 @@ def create_dynamic_class(name, bases): 6: K BININT1 0 8: K BININT1 1 10: G BINFLOAT 2.0 + 19: c GLOBAL '__builtin__ complex' + 40: q BINPUT 1 + 42: G BINFLOAT 3.0 + 51: G BINFLOAT 0.0 + 60: \x86 TUPLE2 + 61: q BINPUT 2 + 63: R REDUCE + 64: q BINPUT 3 + 66: K BININT1 1 + 68: J BININT -1 + 73: K BININT1 255 + 75: J BININT -255 + 80: J BININT -256 + 85: M BININT2 65535 + 88: J BININT -65535 + 93: J BININT -65536 + 98: J BININT 2147483647 + 103: J BININT -2147483647 + 108: J BININT -2147483648 + 113: ( MARK + 114: X BINUNICODE 'abc' + 122: q BINPUT 4 + 124: h BINGET 4 + 126: c GLOBAL '__main__ C' + 138: q BINPUT 5 + 140: ) EMPTY_TUPLE + 141: \x81 NEWOBJ + 142: q BINPUT 6 + 144: } EMPTY_DICT + 145: q BINPUT 7 + 147: ( MARK + 148: X BINUNICODE 'foo' + 156: q BINPUT 8 + 158: K BININT1 1 + 160: X BINUNICODE 'bar' + 168: q BINPUT 9 + 170: K BININT1 2 + 172: u SETITEMS (MARK at 147) + 173: b BUILD + 174: h BINGET 6 + 176: t TUPLE (MARK at 113) + 177: q BINPUT 10 + 179: h BINGET 10 + 181: K BININT1 5 + 183: e APPENDS (MARK at 5) + 184: . STOP +highest protocol among opcodes = 2 +""" + +DATA3 = ( + b'\x80\x03]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c' + b'builtins\ncomplex\nq\x01G' + b'@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00\x86q\x02' + b'Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff' + b'\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7f' + b'J\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00abcq' + b'\x04h\x04c__main__\nC\nq\x05)\x81q' + b'\x06}q\x07(X\x03\x00\x00\x00barq\x08K\x02X\x03\x00' + b'\x00\x00fooq\tK\x01ubh\x06tq\nh\nK\x05' + b'e.' +) + +# Disassembly of DATA3 +DATA3_DIS = """\ + 0: \x80 PROTO 3 + 2: ] EMPTY_LIST + 3: q BINPUT 0 + 5: ( MARK + 6: K BININT1 0 + 8: K BININT1 1 + 10: G BINFLOAT 2.0 19: c GLOBAL 'builtins complex' 37: q BINPUT 1 39: G BINFLOAT 3.0 @@ -378,12 +454,12 @@ def create_dynamic_class(name, bases): 141: } EMPTY_DICT 142: q BINPUT 7 144: ( MARK - 145: X BINUNICODE 'foo' + 145: X BINUNICODE 'bar' 153: q BINPUT 8 - 155: K BININT1 1 - 157: X BINUNICODE 'bar' + 155: K BININT1 2 + 157: X BINUNICODE 'foo' 165: q BINPUT 9 - 167: K BININT1 2 + 167: K BININT1 1 169: u SETITEMS (MARK at 144) 170: b BUILD 171: h BINGET 6 @@ -396,22 +472,101 @@ def create_dynamic_class(name, bases): highest protocol among opcodes = 2 """ +DATA4 = ( + b'\x80\x04\x95\xa8\x00\x00\x00\x00\x00\x00\x00]\x94(K\x00K\x01G@' + b'\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x07' + b'complex\x94\x93\x94G@\x08\x00\x00\x00\x00\x00\x00G' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x86\x94R\x94K\x01J\xff\xff\xff\xffK' + b'\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ' + b'\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(' + b'\x8c\x03abc\x94h\x06\x8c\x08__main__\x94\x8c' + b'\x01C\x94\x93\x94)\x81\x94}\x94(\x8c\x03bar\x94K\x02\x8c' + b'\x03foo\x94K\x01ubh\nt\x94h\x0eK\x05e.' +) + +# Disassembly of DATA4 +DATA4_DIS = """\ + 0: \x80 PROTO 4 + 2: \x95 FRAME 168 + 11: ] EMPTY_LIST + 12: \x94 MEMOIZE + 13: ( MARK + 14: K BININT1 0 + 16: K BININT1 1 + 18: G BINFLOAT 2.0 + 27: \x8c SHORT_BINUNICODE 'builtins' + 37: \x94 MEMOIZE + 38: \x8c SHORT_BINUNICODE 'complex' + 47: \x94 MEMOIZE + 48: \x93 STACK_GLOBAL + 49: \x94 MEMOIZE + 50: G BINFLOAT 3.0 + 59: G BINFLOAT 0.0 + 68: \x86 TUPLE2 + 69: \x94 MEMOIZE + 70: R REDUCE + 71: \x94 MEMOIZE + 72: K BININT1 1 + 74: J BININT -1 + 79: K BININT1 255 + 81: J BININT -255 + 86: J BININT -256 + 91: M BININT2 65535 + 94: J BININT -65535 + 99: J BININT -65536 + 104: J BININT 2147483647 + 109: J BININT -2147483647 + 114: J BININT -2147483648 + 119: ( MARK + 120: \x8c SHORT_BINUNICODE 'abc' + 125: \x94 MEMOIZE + 126: h BINGET 6 + 128: \x8c SHORT_BINUNICODE '__main__' + 138: \x94 MEMOIZE + 139: \x8c SHORT_BINUNICODE 'C' + 142: \x94 MEMOIZE + 143: \x93 STACK_GLOBAL + 144: \x94 MEMOIZE + 145: ) EMPTY_TUPLE + 146: \x81 NEWOBJ + 147: \x94 MEMOIZE + 148: } EMPTY_DICT + 149: \x94 MEMOIZE + 150: ( MARK + 151: \x8c SHORT_BINUNICODE 'bar' + 156: \x94 MEMOIZE + 157: K BININT1 2 + 159: \x8c SHORT_BINUNICODE 'foo' + 164: \x94 MEMOIZE + 165: K BININT1 1 + 167: u SETITEMS (MARK at 150) + 168: b BUILD + 169: h BINGET 10 + 171: t TUPLE (MARK at 119) + 172: \x94 MEMOIZE + 173: h BINGET 14 + 175: K BININT1 5 + 177: e APPENDS (MARK at 13) + 178: . STOP +highest protocol among opcodes = 4 +""" + # set([1,2]) pickled from 2.x with protocol 2 -DATA3 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.' +DATA_SET = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.' # xrange(5) pickled from 2.x with protocol 2 -DATA4 = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.' +DATA_XRANGE = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.' # a SimpleCookie() object pickled from 2.x with protocol 2 -DATA5 = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key' - b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U' - b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07' - b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U' - b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b' - b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.') +DATA_COOKIE = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key' + b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U' + b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07' + b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U' + b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b' + b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.') # set([3]) pickled from 2.x with protocol 2 -DATA6 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.' +DATA_SET2 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.' python2_exceptions_without_args = ( ArithmeticError, @@ -463,20 +618,10 @@ def create_dynamic_class(name, bases): exception_pickle = b'\x80\x02cexceptions\n?\nq\x00)Rq\x01.' -# Exception objects without arguments pickled from 2.x with protocol 2 -DATA7 = { - exception : - exception_pickle.replace(b'?', exception.__name__.encode("ascii")) - for exception in python2_exceptions_without_args -} - -# StandardError is mapped to Exception, test that separately -DATA8 = exception_pickle.replace(b'?', b'StandardError') - # UnicodeEncodeError object pickled from 2.x with protocol 2 -DATA9 = (b'\x80\x02cexceptions\nUnicodeEncodeError\n' - b'q\x00(U\x05asciiq\x01X\x03\x00\x00\x00fooq\x02K\x00K\x01' - b'U\x03badq\x03tq\x04Rq\x05.') +DATA_UEERR = (b'\x80\x02cexceptions\nUnicodeEncodeError\n' + b'q\x00(U\x05asciiq\x01X\x03\x00\x00\x00fooq\x02K\x00K\x01' + b'U\x03badq\x03tq\x04Rq\x05.') def create_data(): @@ -500,16 +645,11 @@ def create_data(): return x -class AbstractPickleTests(unittest.TestCase): - # Subclass must define self.dumps, self.loads. - - optimized = False +class AbstractUnpickleTests(unittest.TestCase): + # Subclass must define self.loads. _testdata = create_data() - def setUp(self): - pass - def assert_is_copy(self, obj, objcopy, msg=None): """Utility method to verify if two objects are copies of each others. """ @@ -528,33 +668,6 @@ def assert_is_copy(self, obj, objcopy, msg=None): self.assertEqual(getattr(obj, slot, None), getattr(objcopy, slot, None), msg=msg) - def test_misc(self): - # test various datatypes not tested by testdata - for proto in protocols: - x = myint(4) - s = self.dumps(x, proto) - y = self.loads(s) - self.assert_is_copy(x, y) - - x = (1, ()) - s = self.dumps(x, proto) - y = self.loads(s) - self.assert_is_copy(x, y) - - x = initarg(1, x) - s = self.dumps(x, proto) - y = self.loads(s) - self.assert_is_copy(x, y) - - # XXX test __reduce__ protocol? - - def test_roundtrip_equality(self): - expected = self._testdata - for proto in protocols: - s = self.dumps(expected, proto) - got = self.loads(s) - self.assert_is_copy(expected, got) - def test_load_from_data0(self): self.assert_is_copy(self._testdata, self.loads(DATA0)) @@ -564,6 +677,12 @@ def test_load_from_data1(self): def test_load_from_data2(self): self.assert_is_copy(self._testdata, self.loads(DATA2)) + def test_load_from_data3(self): + self.assert_is_copy(self._testdata, self.loads(DATA3)) + + def test_load_from_data4(self): + self.assert_is_copy(self._testdata, self.loads(DATA4)) + def test_load_classic_instance(self): # See issue5180. Test loading 2.x pickles that # contain an instance of old style class. @@ -571,14 +690,14 @@ def test_load_classic_instance(self): xname = X.__name__.encode('ascii') # Protocol 0 (text mode pickle): """ - 0: ( MARK - 1: i INST '__main__ X' (MARK at 0) - 15: p PUT 0 - 18: ( MARK - 19: d DICT (MARK at 18) - 20: p PUT 1 - 23: b BUILD - 24: . STOP + 0: ( MARK + 1: i INST '__main__ X' (MARK at 0) + 13: p PUT 0 + 16: ( MARK + 17: d DICT (MARK at 16) + 18: p PUT 1 + 21: b BUILD + 22: . STOP """ pickle0 = (b"(i__main__\n" b"X\n" @@ -588,15 +707,15 @@ def test_load_classic_instance(self): # Protocol 1 (binary mode pickle) """ - 0: ( MARK - 1: c GLOBAL '__main__ X' - 15: q BINPUT 0 - 17: o OBJ (MARK at 0) - 18: q BINPUT 1 - 20: } EMPTY_DICT - 21: q BINPUT 2 - 23: b BUILD - 24: . STOP + 0: ( MARK + 1: c GLOBAL '__main__ X' + 13: q BINPUT 0 + 15: o OBJ (MARK at 0) + 16: q BINPUT 1 + 18: } EMPTY_DICT + 19: q BINPUT 2 + 21: b BUILD + 22: . STOP """ pickle1 = (b'(c__main__\n' b'X\n' @@ -605,22 +724,298 @@ def test_load_classic_instance(self): # Protocol 2 (pickle2 = b'\x80\x02' + pickle1) """ - 0: \x80 PROTO 2 - 2: ( MARK - 3: c GLOBAL '__main__ X' - 17: q BINPUT 0 - 19: o OBJ (MARK at 2) - 20: q BINPUT 1 - 22: } EMPTY_DICT - 23: q BINPUT 2 - 25: b BUILD - 26: . STOP + 0: \x80 PROTO 2 + 2: ( MARK + 3: c GLOBAL '__main__ X' + 15: q BINPUT 0 + 17: o OBJ (MARK at 2) + 18: q BINPUT 1 + 20: } EMPTY_DICT + 21: q BINPUT 2 + 23: b BUILD + 24: . STOP """ pickle2 = (b'\x80\x02(c__main__\n' b'X\n' b'q\x00oq\x01}q\x02b.').replace(b'X', xname) self.assert_is_copy(X(*args), self.loads(pickle2)) + def test_maxint64(self): + maxint64 = (1 << 63) - 1 + data = b'I' + str(maxint64).encode("ascii") + b'\n.' + got = self.loads(data) + self.assert_is_copy(maxint64, got) + + # Try too with a bogus literal. + data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.' + self.assertRaises(ValueError, self.loads, data) + + def test_pop_empty_stack(self): + # Test issue7455 + s = b'0' + self.assertRaises((pickle.UnpicklingError, IndexError), self.loads, s) + + def test_unpickle_from_2x(self): + # Unpickle non-trivial data from Python 2.x. + loaded = self.loads(DATA_SET) + self.assertEqual(loaded, set([1, 2])) + loaded = self.loads(DATA_XRANGE) + self.assertEqual(type(loaded), type(range(0))) + self.assertEqual(list(loaded), list(range(5))) + loaded = self.loads(DATA_COOKIE) + self.assertEqual(type(loaded), SimpleCookie) + self.assertEqual(list(loaded.keys()), ["key"]) + self.assertEqual(loaded["key"].value, "value") + + # Exception objects without arguments pickled from 2.x with protocol 2 + for exc in python2_exceptions_without_args: + data = exception_pickle.replace(b'?', exc.__name__.encode("ascii")) + loaded = self.loads(data) + self.assertIs(type(loaded), exc) + + # StandardError is mapped to Exception, test that separately + loaded = self.loads(exception_pickle.replace(b'?', b'StandardError')) + self.assertIs(type(loaded), Exception) + + loaded = self.loads(DATA_UEERR) + self.assertIs(type(loaded), UnicodeEncodeError) + self.assertEqual(loaded.object, "foo") + self.assertEqual(loaded.encoding, "ascii") + self.assertEqual(loaded.start, 0) + self.assertEqual(loaded.end, 1) + self.assertEqual(loaded.reason, "bad") + + def test_load_python2_str_as_bytes(self): + # From Python 2: pickle.dumps('a\x00\xa0', protocol=0) + self.assertEqual(self.loads(b"S'a\\x00\\xa0'\n.", + encoding="bytes"), b'a\x00\xa0') + # From Python 2: pickle.dumps('a\x00\xa0', protocol=1) + self.assertEqual(self.loads(b'U\x03a\x00\xa0.', + encoding="bytes"), b'a\x00\xa0') + # From Python 2: pickle.dumps('a\x00\xa0', protocol=2) + self.assertEqual(self.loads(b'\x80\x02U\x03a\x00\xa0.', + encoding="bytes"), b'a\x00\xa0') + + def test_load_python2_unicode_as_str(self): + # From Python 2: pickle.dumps(u'π', protocol=0) + self.assertEqual(self.loads(b'V\\u03c0\n.', + encoding='bytes'), 'π') + # From Python 2: pickle.dumps(u'π', protocol=1) + self.assertEqual(self.loads(b'X\x02\x00\x00\x00\xcf\x80.', + encoding="bytes"), 'π') + # From Python 2: pickle.dumps(u'π', protocol=2) + self.assertEqual(self.loads(b'\x80\x02X\x02\x00\x00\x00\xcf\x80.', + encoding="bytes"), 'π') + + def test_load_long_python2_str_as_bytes(self): + # From Python 2: pickle.dumps('x' * 300, protocol=1) + self.assertEqual(self.loads(pickle.BINSTRING + + struct.pack("', '<\\\u1234>', '<\n>', '<\\>', '<\\\U00012345>', @@ -752,7 +1142,6 @@ def test_bytes(self): self.assert_is_copy(s, self.loads(p)) def test_ints(self): - import sys for proto in protocols: n = sys.maxsize while n: @@ -762,16 +1151,6 @@ def test_ints(self): self.assert_is_copy(expected, n2) n = n >> 1 - def test_maxint64(self): - maxint64 = (1 << 63) - 1 - data = b'I' + str(maxint64).encode("ascii") + b'\n.' - got = self.loads(data) - self.assert_is_copy(maxint64, got) - - # Try too with a bogus literal. - data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.' - self.assertRaises(ValueError, self.loads, data) - def test_long(self): for proto in protocols: # 256 bytes is where LONG4 begins. @@ -811,15 +1190,18 @@ def test_float_format(self): self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.') def test_reduce(self): - pass + for proto in protocols: + inst = AAA() + dumped = self.dumps(inst, proto) + loaded = self.loads(dumped) + self.assertEqual(loaded, REDUCE_A) def test_getinitargs(self): - pass - - def test_pop_empty_stack(self): - # Test issue7455 - s = b'0' - self.assertRaises((pickle.UnpicklingError, IndexError), self.loads, s) + for proto in protocols: + inst = initarg(1, 2) + dumped = self.dumps(inst, proto) + loaded = self.loads(dumped) + self.assert_is_copy(inst, loaded) def test_metaclass(self): a = use_metaclass() @@ -1029,6 +1411,18 @@ def test_newobj_proxies(self): self.assertEqual(B(x), B(y), detail) self.assertEqual(x.__dict__, y.__dict__, detail) + def test_newobj_not_class(self): + # Issue 24552 + global SimpleNewObj + save = SimpleNewObj + o = SimpleNewObj.__new__(SimpleNewObj) + b = self.dumps(o, 4) + try: + SimpleNewObj = 42 + self.assertRaises((TypeError, pickle.UnpicklingError), self.loads, b) + finally: + SimpleNewObj = save + # Register a type with copyreg, with extension code extcode. Pickle # an object of that type. Check that the resulting pickle uses opcode # (EXT[124]) under proto 2, and not in proto 1. @@ -1146,16 +1540,60 @@ def test_set_chunking(self): self.assertGreaterEqual(num_additems, 2) def test_simple_newobj(self): - x = object.__new__(SimpleNewObj) # avoid __init__ + x = SimpleNewObj.__new__(SimpleNewObj, 0xface) # avoid __init__ x.abc = 666 for proto in protocols: - s = self.dumps(x, proto) - self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), - 2 <= proto < 4) - self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s), - proto >= 4) - y = self.loads(s) # will raise TypeError if __init__ called - self.assert_is_copy(x, y) + with self.subTest(proto=proto): + s = self.dumps(x, proto) + if proto < 1: + self.assertIn(b'\nL64206', s) # LONG + else: + self.assertIn(b'M\xce\xfa', s) # BININT2 + self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), + 2 <= proto) + self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s)) + y = self.loads(s) # will raise TypeError if __init__ called + self.assert_is_copy(x, y) + + def test_complex_newobj(self): + x = ComplexNewObj.__new__(ComplexNewObj, 0xface) # avoid __init__ + x.abc = 666 + for proto in protocols: + with self.subTest(proto=proto): + s = self.dumps(x, proto) + if proto < 1: + self.assertIn(b'\nL64206', s) # LONG + elif proto < 2: + self.assertIn(b'M\xce\xfa', s) # BININT2 + elif proto < 4: + self.assertIn(b'X\x04\x00\x00\x00FACE', s) # BINUNICODE + else: + self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE + self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), + 2 <= proto) + self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s)) + y = self.loads(s) # will raise TypeError if __init__ called + self.assert_is_copy(x, y) + + def test_complex_newobj_ex(self): + x = ComplexNewObjEx.__new__(ComplexNewObjEx, 0xface) # avoid __init__ + x.abc = 666 + for proto in protocols: + with self.subTest(proto=proto): + s = self.dumps(x, proto) + if proto < 1: + self.assertIn(b'\nL64206', s) # LONG + elif proto < 2: + self.assertIn(b'M\xce\xfa', s) # BININT2 + elif proto < 4: + self.assertIn(b'X\x04\x00\x00\x00FACE', s) # BINUNICODE + else: + self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE + self.assertFalse(opcode_in_pickle(pickle.NEWOBJ, s)) + self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s), + 4 <= proto) + y = self.loads(s) # will raise TypeError if __init__ called + self.assert_is_copy(x, y) def test_newobj_list_slots(self): x = SlotList([1, 2, 3]) @@ -1267,42 +1705,15 @@ def test_attribute_name_interning(self): for x_key, y_key in zip(x_keys, y_keys): self.assertIs(x_key, y_key) - def test_unpickle_from_2x(self): - # Unpickle non-trivial data from Python 2.x. - loaded = self.loads(DATA3) - self.assertEqual(loaded, set([1, 2])) - loaded = self.loads(DATA4) - self.assertEqual(type(loaded), type(range(0))) - self.assertEqual(list(loaded), list(range(5))) - loaded = self.loads(DATA5) - self.assertEqual(type(loaded), SimpleCookie) - self.assertEqual(list(loaded.keys()), ["key"]) - self.assertEqual(loaded["key"].value, "Set-Cookie: key=value") - - for (exc, data) in DATA7.items(): - loaded = self.loads(data) - self.assertIs(type(loaded), exc) - - loaded = self.loads(DATA8) - self.assertIs(type(loaded), Exception) - - loaded = self.loads(DATA9) - self.assertIs(type(loaded), UnicodeEncodeError) - self.assertEqual(loaded.object, "foo") - self.assertEqual(loaded.encoding, "ascii") - self.assertEqual(loaded.start, 0) - self.assertEqual(loaded.end, 1) - self.assertEqual(loaded.reason, "bad") - def test_pickle_to_2x(self): # Pickle non-trivial data with protocol 2, expecting that it yields # the same result as Python 2.x did. # NOTE: this test is a bit too strong since we can produce different # bytecode that 2.x will still understand. dumped = self.dumps(range(5), 2) - self.assertEqual(dumped, DATA4) + self.assertEqual(dumped, DATA_XRANGE) dumped = self.dumps(set([3]), 2) - self.assertEqual(dumped, DATA6) + self.assertEqual(dumped, DATA_SET2) def test_large_pickles(self): # Test the correctness of internal buffering routines when handling @@ -1314,11 +1725,6 @@ def test_large_pickles(self): self.assertEqual(len(loaded), len(data)) self.assertEqual(loaded, data) - def test_empty_bytestring(self): - # issue 11286 - empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r') - self.assertEqual(empty, '') - def test_int_pickling_efficiency(self): # Test compacity of int representation (see issue #12744) for proto in protocols: @@ -1331,64 +1737,6 @@ def test_int_pickling_efficiency(self): for p in pickles: self.assertFalse(opcode_in_pickle(pickle.LONG, p)) - def check_negative_32b_binXXX(self, dumped): - if sys.maxsize > 2**32: - self.skipTest("test is only meaningful on 32-bit builds") - # XXX Pure Python pickle reads lengths as signed and passes - # them directly to read() (hence the EOFError) - with self.assertRaises((pickle.UnpicklingError, EOFError, - ValueError, OverflowError)): - self.loads(dumped) - - def test_negative_32b_binbytes(self): - # On 32-bit builds, a BINBYTES of 2**31 or more is refused - self.check_negative_32b_binXXX(b'\x80\x03B\xff\xff\xff\xffxyzq\x00.') - - def test_negative_32b_binunicode(self): - # On 32-bit builds, a BINUNICODE of 2**31 or more is refused - self.check_negative_32b_binXXX(b'\x80\x03X\xff\xff\xff\xffxyzq\x00.') - - def test_negative_put(self): - # Issue #12847 - dumped = b'Va\np-1\n.' - self.assertRaises(ValueError, self.loads, dumped) - - def test_negative_32b_binput(self): - # Issue #12847 - if sys.maxsize > 2**32: - self.skipTest("test is only meaningful on 32-bit builds") - dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.' - self.assertRaises(ValueError, self.loads, dumped) - - def test_badly_escaped_string(self): - self.assertRaises(ValueError, self.loads, b"S'\\'\n.") - - def test_badly_quoted_string(self): - # Issue #17710 - badpickles = [b"S'\n.", - b'S"\n.', - b'S\' \n.', - b'S" \n.', - b'S\'"\n.', - b'S"\'\n.', - b"S' ' \n.", - b'S" " \n.', - b"S ''\n.", - b'S ""\n.', - b'S \n.', - b'S\n.', - b'S.'] - for p in badpickles: - self.assertRaises(pickle.UnpicklingError, self.loads, p) - - def test_correctly_quoted_string(self): - goodpickles = [(b"S''\n.", ''), - (b'S""\n.', ''), - (b'S"\\n"\n.', '\n'), - (b"S'\\n'\n.", '\n')] - for p, expected in goodpickles: - self.assertEqual(self.loads(p), expected) - def _check_pickling_with_opcode(self, obj, opcode, proto): pickled = self.dumps(obj, proto) self.assertTrue(opcode_in_pickle(opcode, pickled)) @@ -1416,6 +1764,26 @@ def test_setitems_on_non_dicts(self): FRAME_SIZE_TARGET = 64 * 1024 + def check_frame_opcodes(self, pickled): + """ + Check the arguments of FRAME opcodes in a protocol 4+ pickle. + """ + frame_opcode_size = 9 + last_arg = last_pos = None + for op, arg, pos in pickletools.genops(pickled): + if op.name != 'FRAME': + continue + if last_pos is not None: + # The previous frame's size should be equal to the number + # of bytes up to the current frame. + frame_size = pos - last_pos - frame_opcode_size + self.assertEqual(frame_size, last_arg) + last_arg, last_pos = arg, pos + # The last frame's size should be equal to the number of bytes up + # to the pickle's end. + frame_size = len(pickled) - last_pos - frame_opcode_size + self.assertEqual(frame_size, last_arg) + def test_framing_many_objects(self): obj = list(range(10**5)) for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): @@ -1429,6 +1797,7 @@ def test_framing_many_objects(self): self.FRAME_SIZE_TARGET / 2) self.assertLessEqual(bytes_per_frame, self.FRAME_SIZE_TARGET * 1) + self.check_frame_opcodes(pickled) def test_framing_large_objects(self): N = 1024 * 1024 @@ -1440,6 +1809,7 @@ def test_framing_large_objects(self): self.assertEqual(obj, unpickled) n_frames = count_opcode(pickle.FRAME, pickled) self.assertGreaterEqual(n_frames, len(obj)) + self.check_frame_opcodes(pickled) def test_optional_frames(self): if pickle.HIGHEST_PROTOCOL < 4: @@ -1487,13 +1857,24 @@ class A: class B: class C: pass - - for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): for obj in [Nested.A, Nested.A.B, Nested.A.B.C]: with self.subTest(proto=proto, obj=obj): unpickled = self.loads(self.dumps(obj, proto)) self.assertIs(obj, unpickled) + def test_recursive_nested_names(self): + global Recursive + class Recursive: + pass + Recursive.mod = sys.modules[Recursive.__module__] + Recursive.__qualname__ = 'Recursive.mod.Recursive' + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(proto=proto): + unpickled = self.loads(self.dumps(Recursive, proto)) + self.assertIs(unpickled, Recursive) + del Recursive.mod # break reference loop + def test_py_methods(self): global PyMethodsTest class PyMethodsTest: @@ -1532,7 +1913,7 @@ def pie(self): (PyMethodsTest.biscuits, PyMethodsTest), (PyMethodsTest.Nested.pie, PyMethodsTest.Nested) ) - for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): for method in py_methods: with self.subTest(proto=proto, method=method): unpickled = self.loads(self.dumps(method, proto)) @@ -1543,7 +1924,6 @@ def pie(self): unpickled = self.loads(self.dumps(method, proto)) self.assertEqual(method(obj), unpickled(obj)) - def test_c_methods(self): global Subclass class Subclass(tuple): @@ -1573,25 +1953,64 @@ class Nested(str): (Subclass.Nested("sweet").count, ("e",)), (Subclass.Nested.count, (Subclass.Nested("sweet"), "e")), ) - for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): for method, args in c_methods: with self.subTest(proto=proto, method=method): unpickled = self.loads(self.dumps(method, proto)) self.assertEqual(method(*args), unpickled(*args)) + def test_compat_pickle(self): + tests = [ + (range(1, 7), '__builtin__', 'xrange'), + (map(int, '123'), 'itertools', 'imap'), + (functools.reduce, '__builtin__', 'reduce'), + (dbm.whichdb, 'whichdb', 'whichdb'), + (Exception(), 'exceptions', 'Exception'), + (collections.UserDict(), 'UserDict', 'IterableUserDict'), + (collections.UserList(), 'UserList', 'UserList'), + (collections.defaultdict(), 'collections', 'defaultdict'), + ] + for val, mod, name in tests: + for proto in range(3): + with self.subTest(type=type(val), proto=proto): + pickled = self.dumps(val, proto) + self.assertIn(('c%s\n%s' % (mod, name)).encode(), pickled) + self.assertIs(type(self.loads(pickled)), type(val)) + + def test_local_lookup_error(self): + # Test that whichmodule() errors out cleanly when looking up + # an assumed globally-reachable object fails. + def f(): + pass + # Since the function is local, lookup will fail + for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((AttributeError, pickle.PicklingError)): + pickletools.dis(self.dumps(f, proto)) + # Same without a __module__ attribute (exercises a different path + # in _pickle.c). + del f.__module__ + for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((AttributeError, pickle.PicklingError)): + pickletools.dis(self.dumps(f, proto)) + # Yet a different path. + f.__name__ = f.__qualname__ + for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((AttributeError, pickle.PicklingError)): + pickletools.dis(self.dumps(f, proto)) + class BigmemPickleTests(unittest.TestCase): # Binary protocols can serialize longs of up to 2GB-1 - @bigmemtest(size=_2G, memuse=1 + 1, dry_run=False) + @bigmemtest(size=_2G, memuse=3.6, dry_run=False) def test_huge_long_32b(self, size): data = 1 << (8 * size) try: for proto in protocols: + if proto < 2: + continue with self.subTest(proto=proto): - if proto < 2: - continue with self.assertRaises((ValueError, OverflowError)): self.dumps(data, protocol=proto) finally: @@ -1601,49 +2020,75 @@ def test_huge_long_32b(self, size): # (older protocols don't have a dedicated opcode for bytes and are # too inefficient) - @bigmemtest(size=_2G, memuse=1 + 1, dry_run=False) + @bigmemtest(size=_2G, memuse=2.5, dry_run=False) def test_huge_bytes_32b(self, size): data = b"abcd" * (size // 4) try: for proto in protocols: + if proto < 3: + continue with self.subTest(proto=proto): - if proto < 3: - continue try: pickled = self.dumps(data, protocol=proto) - self.assertTrue(b"abcd" in pickled[:19]) - self.assertTrue(b"abcd" in pickled[-18:]) + header = (pickle.BINBYTES + + struct.pack("2GB of disk space temporarily. - - network - It is okay to run tests that use external network - resource, e.g. testing SSL support for sockets. - - decimal - Test the decimal module against a large suite that - verifies compliance with standards. - - cpu - Used for certain CPU-heavy tests. - - subprocess Run all tests for the subprocess module. - - urlfetch - It is okay to download files required on testing. - - gui - Run tests that require a running GUI. - -To enable all resources except one, use '-uall,-'. For -example, to run all the tests except for the gui tests, give the -option '-uall,-gui'. -""" - # We import importlib *ASAP* in order to test #15386 import importlib -import argparse -import builtins -import faulthandler -import io -import json -import locale -import logging import os -import platform -import random -import re -import shutil -import signal import sys -import sysconfig -import tempfile -import time -import traceback -import unittest -import warnings -from inspect import isabstract - -try: - import threading -except ImportError: - threading = None -try: - import _multiprocessing, multiprocessing.process -except ImportError: - multiprocessing = None - - -# Some times __path__ and __file__ are not absolute (e.g. while running from -# Lib/) and, if we change the CWD to run the tests in a temporary dir, some -# imports might fail. This affects only the modules imported before os.chdir(). -# These modules are searched first in sys.path[0] (so '' -- the CWD) and if -# they are found in the CWD their __file__ and __path__ will be relative (this -# happens before the chdir). All the modules imported after the chdir, are -# not found in the CWD, and since the other paths in sys.path[1:] are absolute -# (site.py absolutize them), the __file__ and __path__ will be absolute too. -# Therefore it is necessary to absolutize manually the __file__ and __path__ of -# the packages to prevent later imports to fail when the CWD is different. -for module in sys.modules.values(): - if hasattr(module, '__path__'): - module.__path__ = [os.path.abspath(path) for path in module.__path__] - if hasattr(module, '__file__'): - module.__file__ = os.path.abspath(module.__file__) - - -# MacOSX (a.k.a. Darwin) has a default stack size that is too small -# for deeply recursive regular expressions. We see this as crashes in -# the Python test suite when running test_re.py and test_sre.py. The -# fix is to set the stack limit to 2048. -# This approach may also be useful for other Unixy platforms that -# suffer from small default stack limits. -if sys.platform == 'darwin': - try: - import resource - except ImportError: - pass - else: - soft, hard = resource.getrlimit(resource.RLIMIT_STACK) - newsoft = min(hard, max(soft, 1024*2048)) - resource.setrlimit(resource.RLIMIT_STACK, (newsoft, hard)) - -# Test result constants. -PASSED = 1 -FAILED = 0 -ENV_CHANGED = -1 -SKIPPED = -2 -RESOURCE_DENIED = -3 -INTERRUPTED = -4 -CHILD_ERROR = -5 # error in a child process - -from test import support - -RESOURCE_NAMES = ('audio', 'curses', 'largefile', 'network', - 'decimal', 'cpu', 'subprocess', 'urlfetch', 'gui') - -# When tests are run from the Python build directory, it is best practice -# to keep the test files in a subfolder. This eases the cleanup of leftover -# files using the "make distclean" command. -if sysconfig.is_python_build(): - TEMPDIR = os.path.join(sysconfig.get_config_var('srcdir'), 'build') -else: - TEMPDIR = tempfile.gettempdir() -TEMPDIR = os.path.abspath(TEMPDIR) - -class _ArgParser(argparse.ArgumentParser): - - def error(self, message): - super().error(message + "\nPass -h or --help for complete help.") - -def _create_parser(): - # Set prog to prevent the uninformative "__main__.py" from displaying in - # error messages when using "python -m test ...". - parser = _ArgParser(prog='regrtest.py', - usage=USAGE, - description=DESCRIPTION, - epilog=EPILOG, - add_help=False, - formatter_class=argparse.RawDescriptionHelpFormatter) - - # Arguments with this clause added to its help are described further in - # the epilog's "Additional option details" section. - more_details = ' See the section at bottom for more details.' - - group = parser.add_argument_group('General options') - # We add help explicitly to control what argument group it renders under. - group.add_argument('-h', '--help', action='http://github.com/help', - help='show this help message and exit') - group.add_argument('--timeout', metavar='TIMEOUT', type=float, - help='dump the traceback and exit if a test takes ' - 'more than TIMEOUT seconds; disabled if TIMEOUT ' - 'is negative or equals to zero') - group.add_argument('--wait', action='http://github.com/store_true', - help='wait for user input, e.g., allow a debugger ' - 'to be attached') - group.add_argument('--slaveargs', metavar='ARGS') - group.add_argument('-S', '--start', metavar='START', - help='the name of the test at which to start.' + - more_details) - - group = parser.add_argument_group('Verbosity') - group.add_argument('-v', '--verbose', action='http://github.com/count', - help='run tests in verbose mode with output to stdout') - group.add_argument('-w', '--verbose2', action='http://github.com/store_true', - help='re-run failed tests in verbose mode') - group.add_argument('-W', '--verbose3', action='http://github.com/store_true', - help='display test output on failure') - group.add_argument('-q', '--quiet', action='http://github.com/store_true', - help='no output unless one or more tests fail') - group.add_argument('-o', '--slow', action='http://github.com/store_true', dest='print_slow', - help='print the slowest 10 tests') - group.add_argument('--header', action='http://github.com/store_true', - help='print header with interpreter info') - - group = parser.add_argument_group('Selecting tests') - group.add_argument('-r', '--randomize', action='http://github.com/store_true', - help='randomize test execution order.' + more_details) - group.add_argument('--randseed', metavar='SEED', - dest='random_seed', type=int, - help='pass a random seed to reproduce a previous ' - 'random run') - group.add_argument('-f', '--fromfile', metavar='FILE', - help='read names of tests to run from a file.' + - more_details) - group.add_argument('-x', '--exclude', action='http://github.com/store_true', - help='arguments are tests to *exclude*') - group.add_argument('-s', '--single', action='http://github.com/store_true', - help='single step through a set of tests.' + - more_details) - group.add_argument('-m', '--match', metavar='PAT', - dest='match_tests', - help='match test cases and methods with glob pattern PAT') - group.add_argument('-G', '--failfast', action='http://github.com/store_true', - help='fail as soon as a test fails (only with -v or -W)') - group.add_argument('-u', '--use', metavar='RES1,RES2,...', - action='http://github.com/append', type=resources_list, - help='specify which special resource intensive tests ' - 'to run.' + more_details) - group.add_argument('-M', '--memlimit', metavar='LIMIT', - help='run very large memory-consuming tests.' + - more_details) - group.add_argument('--testdir', metavar='DIR', - type=relative_filename, - help='execute test files in the specified directory ' - '(instead of the Python stdlib test suite)') - - group = parser.add_argument_group('Special runs') - group.add_argument('-l', '--findleaks', action='http://github.com/store_true', - help='if GC is available detect tests that leak memory') - group.add_argument('-L', '--runleaks', action='http://github.com/store_true', - help='run the leaks(1) command just before exit.' + - more_details) - group.add_argument('-R', '--huntrleaks', metavar='RUNCOUNTS', - type=huntrleaks, - help='search for reference leaks (needs debug build, ' - 'very slow).' + more_details) - group.add_argument('-j', '--multiprocess', metavar='PROCESSES', - dest='use_mp', type=int, - help='run PROCESSES processes at once') - group.add_argument('-T', '--coverage', action='http://github.com/store_true', - dest='trace', - help='turn on code coverage tracing using the trace ' - 'module') - group.add_argument('-D', '--coverdir', metavar='DIR', - type=relative_filename, - help='directory where coverage files are put') - group.add_argument('-N', '--nocoverdir', - action='http://github.com/store_const', const=None, dest='coverdir', - help='put coverage files alongside modules') - group.add_argument('-t', '--threshold', metavar='THRESHOLD', - type=int, - help='call gc.set_threshold(THRESHOLD)') - group.add_argument('-n', '--nowindows', action='http://github.com/store_true', - help='suppress error message boxes on Windows') - group.add_argument('-F', '--forever', action='http://github.com/store_true', - help='run the specified tests in a loop, until an ' - 'error happens') - - parser.add_argument('args', nargs=argparse.REMAINDER, - help=argparse.SUPPRESS) - - return parser - -def relative_filename(string): - # CWD is replaced with a temporary dir before calling main(), so we - # join it with the saved CWD so it ends up where the user expects. - return os.path.join(support.SAVEDCWD, string) - -def huntrleaks(string): - args = string.split(':') - if len(args) not in (2, 3): - raise argparse.ArgumentTypeError( - 'needs 2 or 3 colon-separated arguments') - nwarmup = int(args[0]) if args[0] else 5 - ntracked = int(args[1]) if args[1] else 4 - fname = args[2] if len(args) > 2 and args[2] else 'reflog.txt' - return nwarmup, ntracked, fname - -def resources_list(string): - u = [x.lower() for x in string.split(',')] - for r in u: - if r == 'all' or r == 'none': - continue - if r[0] == '-': - r = r[1:] - if r not in RESOURCE_NAMES: - raise argparse.ArgumentTypeError('invalid resource: ' + r) - return u - -def _parse_args(args, **kwargs): - # Defaults - ns = argparse.Namespace(testdir=None, verbose=0, quiet=False, - exclude=False, single=False, randomize=False, fromfile=None, - findleaks=False, use_resources=None, trace=False, coverdir='coverage', - runleaks=False, huntrleaks=False, verbose2=False, print_slow=False, - random_seed=None, use_mp=None, verbose3=False, forever=False, - header=False, failfast=False, match_tests=None) - for k, v in kwargs.items(): - if not hasattr(ns, k): - raise TypeError('%r is an invalid keyword argument ' - 'for this function' % k) - setattr(ns, k, v) - if ns.use_resources is None: - ns.use_resources = [] - - parser = _create_parser() - parser.parse_args(args=args, namespace=ns) - - if ns.single and ns.fromfile: - parser.error("-s and -f don't go together!") - if ns.use_mp and ns.trace: - parser.error("-T and -j don't go together!") - if ns.use_mp and ns.findleaks: - parser.error("-l and -j don't go together!") - if ns.use_mp and ns.memlimit: - parser.error("-M and -j don't go together!") - if ns.failfast and not (ns.verbose or ns.verbose3): - parser.error("-G/--failfast needs either -v or -W") - - if ns.quiet: - ns.verbose = 0 - if ns.timeout is not None: - if hasattr(faulthandler, 'dump_traceback_later'): - if ns.timeout <= 0: - ns.timeout = None - else: - print("Warning: The timeout option requires " - "faulthandler.dump_traceback_later") - ns.timeout = None - if ns.use_mp is not None: - if ns.use_mp <= 0: - # Use all cores + extras for tests that like to sleep - ns.use_mp = 2 + (os.cpu_count() or 1) - if ns.use_mp == 1: - ns.use_mp = None - if ns.use: - for a in ns.use: - for r in a: - if r == 'all': - ns.use_resources[:] = RESOURCE_NAMES - continue - if r == 'none': - del ns.use_resources[:] - continue - remove = False - if r[0] == '-': - remove = True - r = r[1:] - if remove: - if r in ns.use_resources: - ns.use_resources.remove(r) - elif r not in ns.use_resources: - ns.use_resources.append(r) - if ns.random_seed is not None: - ns.randomize = True - - return ns - - -def run_test_in_subprocess(testname, ns): - """Run the given test in a subprocess with --slaveargs. - - ns is the option Namespace parsed from command-line arguments. regrtest - is invoked in a subprocess with the --slaveargs argument; when the - subprocess exits, its return code, stdout and stderr are returned as a - 3-tuple. - """ - from subprocess import Popen, PIPE - base_cmd = ([sys.executable] + support.args_from_interpreter_flags() + - ['-X', 'faulthandler', '-m', 'test.regrtest']) - - slaveargs = ( - (testname, ns.verbose, ns.quiet), - dict(huntrleaks=ns.huntrleaks, - use_resources=ns.use_resources, - output_on_failure=ns.verbose3, - timeout=ns.timeout, failfast=ns.failfast, - match_tests=ns.match_tests)) - # Running the child from the same working directory as regrtest's original - # invocation ensures that TEMPDIR for the child is the same when - # sysconfig.is_python_build() is true. See issue 15300. - popen = Popen(base_cmd + ['--slaveargs', json.dumps(slaveargs)], - stdout=PIPE, stderr=PIPE, - universal_newlines=True, - close_fds=(os.name != 'nt'), - cwd=support.SAVEDCWD) - stdout, stderr = popen.communicate() - retcode = popen.wait() - return retcode, stdout, stderr - - -def main(tests=None, **kwargs): - """Execute a test suite. - - This also parses command-line options and modifies its behavior - accordingly. - - tests -- a list of strings containing test names (optional) - testdir -- the directory in which to look for tests (optional) - - Users other than the Python test suite will certainly want to - specify testdir; if it's omitted, the directory containing the - Python test suite is searched for. - - If the tests argument is omitted, the tests listed on the - command-line will be used. If that's empty, too, then all *.py - files beginning with test_ will be used. - - The other default arguments (verbose, quiet, exclude, - single, randomize, findleaks, use_resources, trace, coverdir, - print_slow, and random_seed) allow programmers calling main() - directly to set the values that would normally be set by flags - on the command line. - """ - # Display the Python traceback on fatal errors (e.g. segfault) - faulthandler.enable(all_threads=True) - - # Display the Python traceback on SIGALRM or SIGUSR1 signal - signals = [] - if hasattr(signal, 'SIGALRM'): - signals.append(signal.SIGALRM) - if hasattr(signal, 'SIGUSR1'): - signals.append(signal.SIGUSR1) - for signum in signals: - faulthandler.register(signum, chain=True) - - replace_stdout() - - support.record_original_stdout(sys.stdout) - - ns = _parse_args(sys.argv[1:], **kwargs) - - if ns.huntrleaks: - # Avoid false positives due to various caches - # filling slowly with random data: - warm_caches() - if ns.memlimit is not None: - support.set_memlimit(ns.memlimit) - if ns.threshold is not None: - import gc - gc.set_threshold(ns.threshold) - if ns.nowindows: - import msvcrt - msvcrt.SetErrorMode(msvcrt.SEM_FAILCRITICALERRORS| - msvcrt.SEM_NOALIGNMENTFAULTEXCEPT| - msvcrt.SEM_NOGPFAULTERRORBOX| - msvcrt.SEM_NOOPENFILEERRORBOX) - try: - msvcrt.CrtSetReportMode - except AttributeError: - # release build - pass - else: - for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]: - msvcrt.CrtSetReportMode(m, msvcrt.CRTDBG_MODE_FILE) - msvcrt.CrtSetReportFile(m, msvcrt.CRTDBG_FILE_STDERR) - if ns.wait: - input("Press any key to continue...") - - if ns.slaveargs is not None: - args, kwargs = json.loads(ns.slaveargs) - if kwargs.get('huntrleaks'): - unittest.BaseTestSuite._cleanup = False - try: - result = runtest(*args, **kwargs) - except KeyboardInterrupt: - result = INTERRUPTED, '' - except BaseException as e: - traceback.print_exc() - result = CHILD_ERROR, str(e) - sys.stdout.flush() - print() # Force a newline (just in case) - print(json.dumps(result)) - sys.exit(0) - - good = [] - bad = [] - skipped = [] - resource_denieds = [] - environment_changed = [] - interrupted = False - - if ns.findleaks: - try: - import gc - except ImportError: - print('No GC available, disabling findleaks.') - ns.findleaks = False - else: - # Uncomment the line below to report garbage that is not - # freeable by reference counting alone. By default only - # garbage that is not collectable by the GC is reported. - #gc.set_debug(gc.DEBUG_SAVEALL) - found_garbage = [] - - if ns.huntrleaks: - unittest.BaseTestSuite._cleanup = False - - if ns.single: - filename = os.path.join(TEMPDIR, 'pynexttest') - try: - with open(filename, 'r') as fp: - next_test = fp.read().strip() - tests = [next_test] - except OSError: - pass - - if ns.fromfile: - tests = [] - with open(os.path.join(support.SAVEDCWD, ns.fromfile)) as fp: - count_pat = re.compile(r'\[\s*\d+/\s*\d+\]') - for line in fp: - line = count_pat.sub('', line) - guts = line.split() # assuming no test has whitespace in its name - if guts and not guts[0].startswith('#'): - tests.extend(guts) - - # Strip .py extensions. - removepy(ns.args) - removepy(tests) - - stdtests = STDTESTS[:] - nottests = NOTTESTS.copy() - if ns.exclude: - for arg in ns.args: - if arg in stdtests: - stdtests.remove(arg) - nottests.add(arg) - ns.args = [] - - # For a partial run, we do not need to clutter the output. - if ns.verbose or ns.header or not (ns.quiet or ns.single or tests or ns.args): - # Print basic platform information - print("==", platform.python_implementation(), *sys.version.split()) - print("== ", platform.platform(aliased=True), - "%s-endian" % sys.byteorder) - print("== ", "hash algorithm:", sys.hash_info.algorithm, - "64bit" if sys.maxsize > 2**32 else "32bit") - print("== ", os.getcwd()) - print("Testing with flags:", sys.flags) - - # if testdir is set, then we are not running the python tests suite, so - # don't add default tests to be executed or skipped (pass empty values) - if ns.testdir: - alltests = findtests(ns.testdir, list(), set()) - else: - alltests = findtests(ns.testdir, stdtests, nottests) - - selected = tests or ns.args or alltests - if ns.single: - selected = selected[:1] - try: - next_single_test = alltests[alltests.index(selected[0])+1] - except IndexError: - next_single_test = None - # Remove all the selected tests that precede start if it's set. - if ns.start: - try: - del selected[:selected.index(ns.start)] - except ValueError: - print("Couldn't find starting test (%s), using all tests" % ns.start) - if ns.randomize: - if ns.random_seed is None: - ns.random_seed = random.randrange(10000000) - random.seed(ns.random_seed) - print("Using random seed", ns.random_seed) - random.shuffle(selected) - if ns.trace: - import trace, tempfile - tracer = trace.Trace(ignoredirs=[sys.base_prefix, sys.base_exec_prefix, - tempfile.gettempdir()], - trace=False, count=True) - - test_times = [] - support.verbose = ns.verbose # Tell tests to be moderately quiet - support.use_resources = ns.use_resources - save_modules = sys.modules.keys() - - def accumulate_result(test, result): - ok, test_time = result - test_times.append((test_time, test)) - if ok == PASSED: - good.append(test) - elif ok == FAILED: - bad.append(test) - elif ok == ENV_CHANGED: - environment_changed.append(test) - elif ok == SKIPPED: - skipped.append(test) - elif ok == RESOURCE_DENIED: - skipped.append(test) - resource_denieds.append(test) - - if ns.forever: - def test_forever(tests=list(selected)): - while True: - for test in tests: - yield test - if bad: - return - tests = test_forever() - test_count = '' - test_count_width = 3 - else: - tests = iter(selected) - test_count = '/{}'.format(len(selected)) - test_count_width = len(test_count) - 1 - - if ns.use_mp: - try: - from threading import Thread - except ImportError: - print("Multiprocess option requires thread support") - sys.exit(2) - from queue import Queue - debug_output_pat = re.compile(r"\[\d+ refs, \d+ blocks\]$") - output = Queue() - pending = MultiprocessTests(tests) - def work(): - # A worker thread. - try: - while True: - try: - test = next(pending) - except StopIteration: - output.put((None, None, None, None)) - return - retcode, stdout, stderr = run_test_in_subprocess(test, ns) - # Strip last refcount output line if it exists, since it - # comes from the shutdown of the interpreter in the subcommand. - stderr = debug_output_pat.sub("", stderr) - stdout, _, result = stdout.strip().rpartition("\n") - if retcode != 0: - result = (CHILD_ERROR, "Exit code %s" % retcode) - output.put((test, stdout.rstrip(), stderr.rstrip(), result)) - return - if not result: - output.put((None, None, None, None)) - return - result = json.loads(result) - output.put((test, stdout.rstrip(), stderr.rstrip(), result)) - except BaseException: - output.put((None, None, None, None)) - raise - workers = [Thread(target=work) for i in range(ns.use_mp)] - for worker in workers: - worker.start() - finished = 0 - test_index = 1 - try: - while finished < ns.use_mp: - test, stdout, stderr, result = output.get() - if test is None: - finished += 1 - continue - accumulate_result(test, result) - if not ns.quiet: - fmt = "[{1:{0}}{2}/{3}] {4}" if bad else "[{1:{0}}{2}] {4}" - print(fmt.format( - test_count_width, test_index, test_count, - len(bad), test)) - if stdout: - print(stdout) - if stderr: - print(stderr, file=sys.stderr) - sys.stdout.flush() - sys.stderr.flush() - if result[0] == INTERRUPTED: - raise KeyboardInterrupt - if result[0] == CHILD_ERROR: - raise Exception("Child error on {}: {}".format(test, result[1])) - test_index += 1 - except KeyboardInterrupt: - interrupted = True - pending.interrupted = True - for worker in workers: - worker.join() - else: - for test_index, test in enumerate(tests, 1): - if not ns.quiet: - fmt = "[{1:{0}}{2}/{3}] {4}" if bad else "[{1:{0}}{2}] {4}" - print(fmt.format( - test_count_width, test_index, test_count, len(bad), test)) - sys.stdout.flush() - if ns.trace: - # If we're tracing code coverage, then we don't exit with status - # if on a false return value from main. - tracer.runctx('runtest(test, ns.verbose, ns.quiet, timeout=ns.timeout)', - globals=globals(), locals=vars()) - else: - try: - result = runtest(test, ns.verbose, ns.quiet, - ns.huntrleaks, - output_on_failure=ns.verbose3, - timeout=ns.timeout, failfast=ns.failfast, - match_tests=ns.match_tests) - accumulate_result(test, result) - except KeyboardInterrupt: - interrupted = True - break - except: - raise - if ns.findleaks: - gc.collect() - if gc.garbage: - print("Warning: test created", len(gc.garbage), end=' ') - print("uncollectable object(s).") - # move the uncollectable objects somewhere so we don't see - # them again - found_garbage.extend(gc.garbage) - del gc.garbage[:] - # Unload the newly imported modules (best effort finalization) - for module in sys.modules.keys(): - if module not in save_modules and module.startswith("test."): - support.unload(module) - - if interrupted: - # print a newline after ^C - print() - print("Test suite interrupted by signal SIGINT.") - omitted = set(selected) - set(good) - set(bad) - set(skipped) - print(count(len(omitted), "test"), "omitted:") - printlist(omitted) - if good and not ns.quiet: - if not bad and not skipped and not interrupted and len(good) > 1: - print("All", end=' ') - print(count(len(good), "test"), "OK.") - if ns.print_slow: - test_times.sort(reverse=True) - print("10 slowest tests:") - for time, test in test_times[:10]: - print("%s: %.1fs" % (test, time)) - if bad: - bad = sorted(set(bad) - set(environment_changed)) - if bad: - print(count(len(bad), "test"), "failed:") - printlist(bad) - if environment_changed: - print("{} altered the execution environment:".format( - count(len(environment_changed), "test"))) - printlist(environment_changed) - if skipped and not ns.quiet: - print(count(len(skipped), "test"), "skipped:") - printlist(skipped) - - if ns.verbose2 and bad: - print("Re-running failed tests in verbose mode") - for test in bad: - print("Re-running test %r in verbose mode" % test) - sys.stdout.flush() - try: - ns.verbose = True - ok = runtest(test, True, ns.quiet, ns.huntrleaks, - timeout=ns.timeout) - except KeyboardInterrupt: - # print a newline separate from the ^C - print() - break - except: - raise - - if ns.single: - if next_single_test: - with open(filename, 'w') as fp: - fp.write(next_single_test + '\n') - else: - os.unlink(filename) - - if ns.trace: - r = tracer.results() - r.write_results(show_missing=True, summary=True, coverdir=ns.coverdir) - - if ns.runleaks: - os.system("leaks %d" % os.getpid()) - - sys.exit(len(bad) > 0 or interrupted) - - -# small set of tests to determine if we have a basically functioning interpreter -# (i.e. if any of these fail, then anything else is likely to follow) -STDTESTS = [ - 'test_grammar', - 'test_opcodes', - 'test_dict', - 'test_builtin', - 'test_exceptions', - 'test_types', - 'test_unittest', - 'test_doctest', - 'test_doctest2', - 'test_support' -] - -# set of tests that we don't want to be executed when using regrtest -NOTTESTS = set() - -def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS): - """Return a list of all applicable test modules.""" - testdir = findtestdir(testdir) - names = os.listdir(testdir) - tests = [] - others = set(stdtests) | nottests - for name in names: - mod, ext = os.path.splitext(name) - if mod[:5] == "test_" and ext in (".py", "") and mod not in others: - tests.append(mod) - return stdtests + sorted(tests) - -# We do not use a generator so multiple threads can call next(). -class MultiprocessTests(object): - - """A thread-safe iterator over tests for multiprocess mode.""" - - def __init__(self, tests): - self.interrupted = False - self.lock = threading.Lock() - self.tests = tests - - def __iter__(self): - return self - - def __next__(self): - with self.lock: - if self.interrupted: - raise StopIteration('tests interrupted') - return next(self.tests) - -def replace_stdout(): - """Set stdout encoder error handler to backslashreplace (as stderr error - handler) to avoid UnicodeEncodeError when printing a traceback""" - import atexit - - stdout = sys.stdout - sys.stdout = open(stdout.fileno(), 'w', - encoding=stdout.encoding, - errors="backslashreplace", - closefd=False, - newline='\n') - - def restore_stdout(): - sys.stdout.close() - sys.stdout = stdout - atexit.register(restore_stdout) - -def runtest(test, verbose, quiet, - huntrleaks=False, use_resources=None, - output_on_failure=False, failfast=False, match_tests=None, - timeout=None): - """Run a single test. - - test -- the name of the test - verbose -- if true, print more messages - quiet -- if true, don't print 'skipped' messages (probably redundant) - huntrleaks -- run multiple times to test for leaks; requires a debug - build; a triple corresponding to -R's three arguments - use_resources -- list of extra resources to use - output_on_failure -- if true, display test output on failure - timeout -- dump the traceback and exit if a test takes more than - timeout seconds - failfast, match_tests -- See regrtest command-line flags for these. - - Returns the tuple result, test_time, where result is one of the constants: - INTERRUPTED KeyboardInterrupt when run under -j - RESOURCE_DENIED test skipped because resource denied - SKIPPED test skipped for some other reason - ENV_CHANGED test failed because it changed the execution environment - FAILED test failed - PASSED test passed - """ - - if use_resources is not None: - support.use_resources = use_resources - use_timeout = (timeout is not None) - if use_timeout: - faulthandler.dump_traceback_later(timeout, exit=True) - try: - support.match_tests = match_tests - if failfast: - support.failfast = True - if output_on_failure: - support.verbose = True - - # Reuse the same instance to all calls to runtest(). Some - # tests keep a reference to sys.stdout or sys.stderr - # (eg. test_argparse). - if runtest.stringio is None: - stream = io.StringIO() - runtest.stringio = stream - else: - stream = runtest.stringio - stream.seek(0) - stream.truncate() - - orig_stdout = sys.stdout - orig_stderr = sys.stderr - try: - sys.stdout = stream - sys.stderr = stream - result = runtest_inner(test, verbose, quiet, huntrleaks, - display_failure=False) - if result[0] == FAILED: - output = stream.getvalue() - orig_stderr.write(output) - orig_stderr.flush() - finally: - sys.stdout = orig_stdout - sys.stderr = orig_stderr - else: - support.verbose = verbose # Tell tests to be moderately quiet - result = runtest_inner(test, verbose, quiet, huntrleaks, - display_failure=not verbose) - return result - finally: - if use_timeout: - faulthandler.cancel_dump_traceback_later() - cleanup_test_droppings(test, verbose) -runtest.stringio = None - -# Unit tests are supposed to leave the execution environment unchanged -# once they complete. But sometimes tests have bugs, especially when -# tests fail, and the changes to environment go on to mess up other -# tests. This can cause issues with buildbot stability, since tests -# are run in random order and so problems may appear to come and go. -# There are a few things we can save and restore to mitigate this, and -# the following context manager handles this task. - -class saved_test_environment: - """Save bits of the test environment and restore them at block exit. - - with saved_test_environment(testname, verbose, quiet): - #stuff - - Unless quiet is True, a warning is printed to stderr if any of - the saved items was changed by the test. The attribute 'changed' - is initially False, but is set to True if a change is detected. - - If verbose is more than 1, the before and after state of changed - items is also printed. - """ - - changed = False - - def __init__(self, testname, verbose=0, quiet=False): - self.testname = testname - self.verbose = verbose - self.quiet = quiet - - # To add things to save and restore, add a name XXX to the resources list - # and add corresponding get_XXX/restore_XXX functions. get_XXX should - # return the value to be saved and compared against a second call to the - # get function when test execution completes. restore_XXX should accept - # the saved value and restore the resource using it. It will be called if - # and only if a change in the value is detected. - # - # Note: XXX will have any '.' replaced with '_' characters when determining - # the corresponding method names. - - resources = ('sys.argv', 'cwd', 'sys.stdin', 'sys.stdout', 'sys.stderr', - 'os.environ', 'sys.path', 'sys.path_hooks', '__import__', - 'warnings.filters', 'asyncore.socket_map', - 'logging._handlers', 'logging._handlerList', 'sys.gettrace', - 'sys.warnoptions', - # multiprocessing.process._cleanup() may release ref - # to a thread, so check processes first. - 'multiprocessing.process._dangling', 'threading._dangling', - 'sysconfig._CONFIG_VARS', 'sysconfig._INSTALL_SCHEMES', - 'support.TESTFN', 'locale', 'warnings.showwarning', - ) - - def get_sys_argv(self): - return id(sys.argv), sys.argv, sys.argv[:] - def restore_sys_argv(self, saved_argv): - sys.argv = saved_argv[1] - sys.argv[:] = saved_argv[2] - - def get_cwd(self): - return os.getcwd() - def restore_cwd(self, saved_cwd): - os.chdir(saved_cwd) - - def get_sys_stdout(self): - return sys.stdout - def restore_sys_stdout(self, saved_stdout): - sys.stdout = saved_stdout - - def get_sys_stderr(self): - return sys.stderr - def restore_sys_stderr(self, saved_stderr): - sys.stderr = saved_stderr - - def get_sys_stdin(self): - return sys.stdin - def restore_sys_stdin(self, saved_stdin): - sys.stdin = saved_stdin - - def get_os_environ(self): - return id(os.environ), os.environ, dict(os.environ) - def restore_os_environ(self, saved_environ): - os.environ = saved_environ[1] - os.environ.clear() - os.environ.update(saved_environ[2]) - - def get_sys_path(self): - return id(sys.path), sys.path, sys.path[:] - def restore_sys_path(self, saved_path): - sys.path = saved_path[1] - sys.path[:] = saved_path[2] - - def get_sys_path_hooks(self): - return id(sys.path_hooks), sys.path_hooks, sys.path_hooks[:] - def restore_sys_path_hooks(self, saved_hooks): - sys.path_hooks = saved_hooks[1] - sys.path_hooks[:] = saved_hooks[2] - - def get_sys_gettrace(self): - return sys.gettrace() - def restore_sys_gettrace(self, trace_fxn): - sys.settrace(trace_fxn) - - def get___import__(self): - return builtins.__import__ - def restore___import__(self, import_): - builtins.__import__ = import_ - - def get_warnings_filters(self): - return id(warnings.filters), warnings.filters, warnings.filters[:] - def restore_warnings_filters(self, saved_filters): - warnings.filters = saved_filters[1] - warnings.filters[:] = saved_filters[2] - - def get_asyncore_socket_map(self): - asyncore = sys.modules.get('asyncore') - # XXX Making a copy keeps objects alive until __exit__ gets called. - return asyncore and asyncore.socket_map.copy() or {} - def restore_asyncore_socket_map(self, saved_map): - asyncore = sys.modules.get('asyncore') - if asyncore is not None: - asyncore.close_all(ignore_all=True) - asyncore.socket_map.update(saved_map) - - def get_shutil_archive_formats(self): - # we could call get_archives_formats() but that only returns the - # registry keys; we want to check the values too (the functions that - # are registered) - return shutil._ARCHIVE_FORMATS, shutil._ARCHIVE_FORMATS.copy() - def restore_shutil_archive_formats(self, saved): - shutil._ARCHIVE_FORMATS = saved[0] - shutil._ARCHIVE_FORMATS.clear() - shutil._ARCHIVE_FORMATS.update(saved[1]) - - def get_shutil_unpack_formats(self): - return shutil._UNPACK_FORMATS, shutil._UNPACK_FORMATS.copy() - def restore_shutil_unpack_formats(self, saved): - shutil._UNPACK_FORMATS = saved[0] - shutil._UNPACK_FORMATS.clear() - shutil._UNPACK_FORMATS.update(saved[1]) - - def get_logging__handlers(self): - # _handlers is a WeakValueDictionary - return id(logging._handlers), logging._handlers, logging._handlers.copy() - def restore_logging__handlers(self, saved_handlers): - # Can't easily revert the logging state - pass - - def get_logging__handlerList(self): - # _handlerList is a list of weakrefs to handlers - return id(logging._handlerList), logging._handlerList, logging._handlerList[:] - def restore_logging__handlerList(self, saved_handlerList): - # Can't easily revert the logging state - pass - - def get_sys_warnoptions(self): - return id(sys.warnoptions), sys.warnoptions, sys.warnoptions[:] - def restore_sys_warnoptions(self, saved_options): - sys.warnoptions = saved_options[1] - sys.warnoptions[:] = saved_options[2] - - # Controlling dangling references to Thread objects can make it easier - # to track reference leaks. - def get_threading__dangling(self): - if not threading: - return None - # This copies the weakrefs without making any strong reference - return threading._dangling.copy() - def restore_threading__dangling(self, saved): - if not threading: - return - threading._dangling.clear() - threading._dangling.update(saved) - - # Same for Process objects - def get_multiprocessing_process__dangling(self): - if not multiprocessing: - return None - # Unjoined process objects can survive after process exits - multiprocessing.process._cleanup() - # This copies the weakrefs without making any strong reference - return multiprocessing.process._dangling.copy() - def restore_multiprocessing_process__dangling(self, saved): - if not multiprocessing: - return - multiprocessing.process._dangling.clear() - multiprocessing.process._dangling.update(saved) - - def get_sysconfig__CONFIG_VARS(self): - # make sure the dict is initialized - sysconfig.get_config_var('prefix') - return (id(sysconfig._CONFIG_VARS), sysconfig._CONFIG_VARS, - dict(sysconfig._CONFIG_VARS)) - def restore_sysconfig__CONFIG_VARS(self, saved): - sysconfig._CONFIG_VARS = saved[1] - sysconfig._CONFIG_VARS.clear() - sysconfig._CONFIG_VARS.update(saved[2]) - - def get_sysconfig__INSTALL_SCHEMES(self): - return (id(sysconfig._INSTALL_SCHEMES), sysconfig._INSTALL_SCHEMES, - sysconfig._INSTALL_SCHEMES.copy()) - def restore_sysconfig__INSTALL_SCHEMES(self, saved): - sysconfig._INSTALL_SCHEMES = saved[1] - sysconfig._INSTALL_SCHEMES.clear() - sysconfig._INSTALL_SCHEMES.update(saved[2]) - - def get_support_TESTFN(self): - if os.path.isfile(support.TESTFN): - result = 'f' - elif os.path.isdir(support.TESTFN): - result = 'd' - else: - result = None - return result - def restore_support_TESTFN(self, saved_value): - if saved_value is None: - if os.path.isfile(support.TESTFN): - os.unlink(support.TESTFN) - elif os.path.isdir(support.TESTFN): - shutil.rmtree(support.TESTFN) - - _lc = [getattr(locale, lc) for lc in dir(locale) - if lc.startswith('LC_')] - def get_locale(self): - pairings = [] - for lc in self._lc: - try: - pairings.append((lc, locale.setlocale(lc, None))) - except (TypeError, ValueError): - continue - return pairings - def restore_locale(self, saved): - for lc, setting in saved: - locale.setlocale(lc, setting) - - def get_warnings_showwarning(self): - return warnings.showwarning - def restore_warnings_showwarning(self, fxn): - warnings.showwarning = fxn - - def resource_info(self): - for name in self.resources: - method_suffix = name.replace('.', '_') - get_name = 'get_' + method_suffix - restore_name = 'restore_' + method_suffix - yield name, getattr(self, get_name), getattr(self, restore_name) - - def __enter__(self): - self.saved_values = dict((name, get()) for name, get, restore - in self.resource_info()) - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - saved_values = self.saved_values - del self.saved_values - for name, get, restore in self.resource_info(): - current = get() - original = saved_values.pop(name) - # Check for changes to the resource's value - if current != original: - self.changed = True - restore(original) - if not self.quiet: - print("Warning -- {} was modified by {}".format( - name, self.testname), - file=sys.stderr) - if self.verbose > 1: - print(" Before: {}\n After: {} ".format( - original, current), - file=sys.stderr) - return False - - -def runtest_inner(test, verbose, quiet, - huntrleaks=False, display_failure=True): - support.unload(test) - - test_time = 0.0 - refleak = False # True if the test leaked references. - try: - if test.startswith('test.'): - abstest = test - else: - # Always import it from the test package - abstest = 'test.' + test - with saved_test_environment(test, verbose, quiet) as environment: - start_time = time.time() - the_module = importlib.import_module(abstest) - # If the test has a test_main, that will run the appropriate - # tests. If not, use normal unittest test loading. - test_runner = getattr(the_module, "test_main", None) - if test_runner is None: - tests = unittest.TestLoader().loadTestsFromModule(the_module) - test_runner = lambda: support.run_unittest(tests) - test_runner() - if huntrleaks: - refleak = dash_R(the_module, test, test_runner, huntrleaks) - test_time = time.time() - start_time - except support.ResourceDenied as msg: - if not quiet: - print(test, "skipped --", msg) - sys.stdout.flush() - return RESOURCE_DENIED, test_time - except unittest.SkipTest as msg: - if not quiet: - print(test, "skipped --", msg) - sys.stdout.flush() - return SKIPPED, test_time - except KeyboardInterrupt: - raise - except support.TestFailed as msg: - if display_failure: - print("test", test, "failed --", msg, file=sys.stderr) - else: - print("test", test, "failed", file=sys.stderr) - sys.stderr.flush() - return FAILED, test_time - except: - msg = traceback.format_exc() - print("test", test, "crashed --", msg, file=sys.stderr) - sys.stderr.flush() - return FAILED, test_time - else: - if refleak: - return FAILED, test_time - if environment.changed: - return ENV_CHANGED, test_time - return PASSED, test_time - -def cleanup_test_droppings(testname, verbose): - import shutil - import stat - import gc - - # First kill any dangling references to open files etc. - # This can also issue some ResourceWarnings which would otherwise get - # triggered during the following test run, and possibly produce failures. - gc.collect() - - # Try to clean up junk commonly left behind. While tests shouldn't leave - # any files or directories behind, when a test fails that can be tedious - # for it to arrange. The consequences can be especially nasty on Windows, - # since if a test leaves a file open, it cannot be deleted by name (while - # there's nothing we can do about that here either, we can display the - # name of the offending test, which is a real help). - for name in (support.TESTFN, - "db_home", - ): - if not os.path.exists(name): - continue - - if os.path.isdir(name): - kind, nuker = "directory", shutil.rmtree - elif os.path.isfile(name): - kind, nuker = "file", os.unlink - else: - raise SystemError("os.path says %r exists but is neither " - "directory nor file" % name) - - if verbose: - print("%r left behind %s %r" % (testname, kind, name)) - try: - # if we have chmod, fix possible permissions problems - # that might prevent cleanup - if (hasattr(os, 'chmod')): - os.chmod(name, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) - nuker(name) - except Exception as msg: - print(("%r left behind %s %r and it couldn't be " - "removed: %s" % (testname, kind, name, msg)), file=sys.stderr) - -def dash_R(the_module, test, indirect_test, huntrleaks): - """Run a test multiple times, looking for reference leaks. - - Returns: - False if the test didn't leak references; True if we detected refleaks. - """ - # This code is hackish and inelegant, but it seems to do the job. - import copyreg - import collections.abc - - if not hasattr(sys, 'gettotalrefcount'): - raise Exception("Tracking reference leaks requires a debug build " - "of Python") - - # Save current values for dash_R_cleanup() to restore. - fs = warnings.filters[:] - ps = copyreg.dispatch_table.copy() - pic = sys.path_importer_cache.copy() - try: - import zipimport - except ImportError: - zdc = None # Run unmodified on platforms without zipimport support - else: - zdc = zipimport._zip_directory_cache.copy() - abcs = {} - for abc in [getattr(collections.abc, a) for a in collections.abc.__all__]: - if not isabstract(abc): - continue - for obj in abc.__subclasses__() + [abc]: - abcs[obj] = obj._abc_registry.copy() - - nwarmup, ntracked, fname = huntrleaks - fname = os.path.join(support.SAVEDCWD, fname) - repcount = nwarmup + ntracked - rc_deltas = [0] * repcount - alloc_deltas = [0] * repcount - - print("beginning", repcount, "repetitions", file=sys.stderr) - print(("1234567890"*(repcount//10 + 1))[:repcount], file=sys.stderr) - sys.stderr.flush() - for i in range(repcount): - indirect_test() - alloc_after, rc_after = dash_R_cleanup(fs, ps, pic, zdc, abcs) - sys.stderr.write('.') - sys.stderr.flush() - if i >= nwarmup: - rc_deltas[i] = rc_after - rc_before - alloc_deltas[i] = alloc_after - alloc_before - alloc_before, rc_before = alloc_after, rc_after - print(file=sys.stderr) - # These checkers return False on success, True on failure - def check_rc_deltas(deltas): - return any(deltas) - def check_alloc_deltas(deltas): - # At least 1/3rd of 0s - if 3 * deltas.count(0) < len(deltas): - return True - # Nothing else than 1s, 0s and -1s - if not set(deltas) <= {1,0,-1}: - return True - return False - failed = False - for deltas, item_name, checker in [ - (rc_deltas, 'references', check_rc_deltas), - (alloc_deltas, 'memory blocks', check_alloc_deltas)]: - if checker(deltas): - msg = '%s leaked %s %s, sum=%s' % ( - test, deltas[nwarmup:], item_name, sum(deltas)) - print(msg, file=sys.stderr) - sys.stderr.flush() - with open(fname, "a") as refrep: - print(msg, file=refrep) - refrep.flush() - failed = True - return failed - -def dash_R_cleanup(fs, ps, pic, zdc, abcs): - import gc, copyreg - import _strptime, linecache - import urllib.parse, urllib.request, mimetypes, doctest - import struct, filecmp, collections.abc - from distutils.dir_util import _path_created - from weakref import WeakSet - - # Clear the warnings registry, so they can be displayed again - for mod in sys.modules.values(): - if hasattr(mod, '__warningregistry__'): - del mod.__warningregistry__ - - # Restore some original values. - warnings.filters[:] = fs - copyreg.dispatch_table.clear() - copyreg.dispatch_table.update(ps) - sys.path_importer_cache.clear() - sys.path_importer_cache.update(pic) - try: - import zipimport - except ImportError: - pass # Run unmodified on platforms without zipimport support - else: - zipimport._zip_directory_cache.clear() - zipimport._zip_directory_cache.update(zdc) - - # clear type cache - sys._clear_type_cache() - - # Clear ABC registries, restoring previously saved ABC registries. - for abc in [getattr(collections.abc, a) for a in collections.abc.__all__]: - if not isabstract(abc): - continue - for obj in abc.__subclasses__() + [abc]: - obj._abc_registry = abcs.get(obj, WeakSet()).copy() - obj._abc_cache.clear() - obj._abc_negative_cache.clear() - - # Flush standard output, so that buffered data is sent to the OS and - # associated Python objects are reclaimed. - for stream in (sys.stdout, sys.stderr, sys.__stdout__, sys.__stderr__): - if stream is not None: - stream.flush() - - # Clear assorted module caches. - _path_created.clear() - re.purge() - _strptime._regex_cache.clear() - urllib.parse.clear_cache() - urllib.request.urlcleanup() - linecache.clearcache() - mimetypes._default_mime_types() - filecmp._cache.clear() - struct._clearcache() - doctest.master = None - try: - import ctypes - except ImportError: - # Don't worry about resetting the cache if ctypes is not supported - pass - else: - ctypes._reset_cache() - - # Collect cyclic trash and read memory statistics immediately after. - func1 = sys.getallocatedblocks - func2 = sys.gettotalrefcount - gc.collect() - return func1(), func2() - -def warm_caches(): - # char cache - s = bytes(range(256)) - for i in range(256): - s[i:i+1] - # unicode cache - x = [chr(i) for i in range(256)] - # int cache - x = list(range(-5, 257)) - -def findtestdir(path=None): - return path or os.path.dirname(__file__) or os.curdir - -def removepy(names): - if not names: - return - for idx, name in enumerate(names): - basename, ext = os.path.splitext(name) - if ext == '.py': - names[idx] = basename - -def count(n, word): - if n == 1: - return "%d %s" % (n, word) - else: - return "%d %ss" % (n, word) - -def printlist(x, width=70, indent=4): - """Print the elements of iterable x to stdout. - - Optional arg width (default 70) is the maximum line length. - Optional arg indent (default 4) is the number of blanks with which to - begin each line. - """ - - from textwrap import fill - blanks = ' ' * indent - # Print the sorted list: 'x' may be a '--random' list or a set() - print(fill(' '.join(str(elt) for elt in sorted(x)), width, - initial_indent=blanks, subsequent_indent=blanks)) - - -def main_in_temp_cwd(): - """Run main() in a temporary working directory.""" - if sysconfig.is_python_build(): - try: - os.mkdir(TEMPDIR) - except FileExistsError: - pass - - # Define a writable temp dir that will be used as cwd while running - # the tests. The name of the dir includes the pid to allow parallel - # testing (see the -j option). - test_cwd = 'test_python_{}'.format(os.getpid()) - test_cwd = os.path.join(TEMPDIR, test_cwd) - - # Run the tests in a context manager that temporarily changes the CWD to a - # temporary and writable directory. If it's not possible to create or - # change the CWD, the original CWD will be used. The original CWD is - # available from support.SAVEDCWD. - with support.temp_cwd(test_cwd, quiet=True): - main() +from test.libregrtest import main, main_in_temp_cwd if __name__ == '__main__': diff --git a/Lib/test/selfsigned_pythontestdotnet.pem b/Lib/test/selfsigned_pythontestdotnet.pem new file mode 100644 index 000000000000..9a80073a5ba0 --- /dev/null +++ b/Lib/test/selfsigned_pythontestdotnet.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIIChzCCAfCgAwIBAgIJAKGU95wKR8pSMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV +BAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9u +IFNvZnR3YXJlIEZvdW5kYXRpb24xIzAhBgNVBAMMGnNlbGYtc2lnbmVkLnB5dGhv +bnRlc3QubmV0MB4XDTE0MTEwMjE4MDkyOVoXDTI0MTAzMDE4MDkyOVowcDELMAkG +A1UEBhMCWFkxFzAVBgNVBAcMDkNhc3RsZSBBbnRocmF4MSMwIQYDVQQKDBpQeXRo +b24gU29mdHdhcmUgRm91bmRhdGlvbjEjMCEGA1UEAwwac2VsZi1zaWduZWQucHl0 +aG9udGVzdC5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANDXQXW9tjyZ +Xt0Iv2tLL1+jinr4wGg36ioLDLFkMf+2Y1GL0v0BnKYG4N1OKlAU15LXGeGer8vm +Sv/yIvmdrELvhAbbo3w4a9TMYQA4XkIVLdvu3mvNOAet+8PMJxn26dbDhG809ALv +EHY57lQsBS3G59RZyBPVqAqmImWNJnVzAgMBAAGjKTAnMCUGA1UdEQQeMByCGnNl +bGYtc2lnbmVkLnB5dGhvbnRlc3QubmV0MA0GCSqGSIb3DQEBBQUAA4GBAIOXmdtM +eG9qzP9TiXW/Gc/zI4cBfdCpC+Y4gOfC9bQUC7hefix4iO3+iZjgy3X/FaRxUUoV +HKiXcXIaWqTSUWp45cSh0MbwZXudp6JIAptzdAhvvCrPKeC9i9GvxsPD4LtDAL97 +vSaxQBezA7hdxZd90/EeyMgVZgAnTCnvAWX9 +-----END CERTIFICATE----- diff --git a/Lib/test/seq_tests.py b/Lib/test/seq_tests.py index f185a8251c2f..24162494dd61 100644 --- a/Lib/test/seq_tests.py +++ b/Lib/test/seq_tests.py @@ -85,6 +85,14 @@ def itermulti(seqn): 'Test multiple tiers of iterators' return chain(map(lambda x:x, iterfunc(IterGen(Sequence(seqn))))) +class LyingTuple(tuple): + def __iter__(self): + yield 1 + +class LyingList(list): + def __iter__(self): + yield 1 + class CommonTest(unittest.TestCase): # The type to be tested type2test = None @@ -131,6 +139,10 @@ def __getitem__(self, i): self.assertRaises(TypeError, self.type2test, IterNoNext(s)) self.assertRaises(ZeroDivisionError, self.type2test, IterGenExc(s)) + # Issue #23757 + self.assertEqual(self.type2test(LyingTuple((2,))), self.type2test((1,))) + self.assertEqual(self.type2test(LyingList([2])), self.type2test([1])) + def test_truth(self): self.assertFalse(self.type2test()) self.assertTrue(self.type2test([42])) @@ -392,6 +404,7 @@ def __eq__(self, other): def test_pickle(self): lst = self.type2test([4, 5, 6, 7]) - lst2 = pickle.loads(pickle.dumps(lst)) - self.assertEqual(lst2, lst) - self.assertNotEqual(id(lst2), id(lst)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + lst2 = pickle.loads(pickle.dumps(lst, proto)) + self.assertEqual(lst2, lst) + self.assertNotEqual(id(lst2), id(lst)) diff --git a/Lib/test/ssl_servers.py b/Lib/test/ssl_servers.py index 759b3f487e32..f9d30cf0bd73 100644 --- a/Lib/test/ssl_servers.py +++ b/Lib/test/ssl_servers.py @@ -150,7 +150,7 @@ def stop(self): def make_https_server(case, *, context=None, certfile=CERTFILE, host=HOST, handler_class=None): if context is None: - context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) # We assume the certfile contains both private key and certificate context.load_cert_chain(certfile) server = HTTPSServerThread(context, host, handler_class) @@ -182,6 +182,8 @@ def cleanup(): parser.add_argument('--curve-name', dest='curve_name', type=str, action='http://github.com/store', help='curve name for EC-based Diffie-Hellman') + parser.add_argument('--ciphers', dest='ciphers', type=str, + help='allowed cipher list') parser.add_argument('--dh', dest='dh_file', type=str, action='http://github.com/store', help='PEM file containing DH parameters') args = parser.parse_args() @@ -192,12 +194,14 @@ def cleanup(): else: handler_class = RootedHTTPRequestHandler handler_class.root = os.getcwd() - context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) + context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) context.load_cert_chain(CERTFILE) if args.curve_name: context.set_ecdh_curve(args.curve_name) if args.dh_file: context.load_dh_params(args.dh_file) + if args.ciphers: + context.set_ciphers(args.ciphers) server = HTTPSServer(("", args.port), handler_class, context) if args.verbose: diff --git a/Lib/test/ssltests.py b/Lib/test/ssltests.py new file mode 100644 index 000000000000..9b0ed22b9565 --- /dev/null +++ b/Lib/test/ssltests.py @@ -0,0 +1,22 @@ +# Convenience test module to run all of the SSL-related tests in the +# standard library. + +import sys +import subprocess + +TESTS = ['test_asyncio', 'test_ftplib', 'test_hashlib', 'test_httplib', + 'test_imaplib', 'test_nntplib', 'test_poplib', 'test_smtplib', + 'test_smtpnet', 'test_urllib2_localnet', 'test_venv'] + +def run_regrtests(*extra_args): + args = [sys.executable, "-m", "test"] + if not extra_args: + args.append("-unetwork") + else: + args.extend(extra_args) + args.extend(TESTS) + result = subprocess.call(args) + sys.exit(result) + +if __name__ == '__main__': + run_regrtests(*sys.argv[1:]) diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py index 30784d4ec5b3..e086994b0b64 100644 --- a/Lib/test/string_tests.py +++ b/Lib/test/string_tests.py @@ -1,11 +1,10 @@ """ -Common tests shared by test_str, test_unicode, test_userstring and test_string. +Common tests shared by test_unicode, test_userstring and test_string. """ import unittest, string, sys, struct from test import support from collections import UserList -import _testcapi class Sequence: def __init__(self, seq='wxyz'): self.seq = seq @@ -80,11 +79,9 @@ class subtype(self.__class__.type2test): def checkraises(self, exc, obj, methodname, *args): obj = self.fixtype(obj) args = self.fixtype(args) - self.assertRaises( - exc, - getattr(obj, methodname), - *args - ) + with self.assertRaises(exc) as cm: + getattr(obj, methodname)(*args) + self.assertNotEqual(str(cm.exception), '') # call obj.method(*args) without any checks def checkcall(self, obj, methodname, *args): @@ -676,10 +673,10 @@ def test_replace(self): self.checkraises(TypeError, 'hello', 'replace', 42, 'h') self.checkraises(TypeError, 'hello', 'replace', 'h', 42) + @unittest.skipIf(sys.maxsize > (1 << 32) or struct.calcsize('P') != 4, + 'only applies to 32-bit platforms') def test_replace_overflow(self): # Check for overflow checking on 32 bit machines - if sys.maxsize != 2147483647 or struct.calcsize("P") > 4: - return A2_16 = "A" * (2**16) self.checkraises(OverflowError, A2_16, "replace", "", A2_16) self.checkraises(OverflowError, A2_16, "replace", "A", A2_16) @@ -979,6 +976,9 @@ def test_startswith(self): self.checkequal(True, 'helloworld', 'startswith', 'lowo', 3) self.checkequal(True, 'helloworld', 'startswith', 'lowo', 3, 7) self.checkequal(False, 'helloworld', 'startswith', 'lowo', 3, 6) + self.checkequal(True, '', 'startswith', '', 0, 1) + self.checkequal(True, '', 'startswith', '', 0, 0) + self.checkequal(False, '', 'startswith', '', 1, 0) # test negative indices self.checkequal(True, 'hello', 'startswith', 'he', 0, -1) @@ -1025,6 +1025,9 @@ def test_endswith(self): self.checkequal(False, 'helloworld', 'endswith', 'lowo', 3, 8) self.checkequal(False, 'ab', 'endswith', 'ab', 0, 1) self.checkequal(False, 'ab', 'endswith', 'ab', 0, 0) + self.checkequal(True, '', 'endswith', '', 0, 1) + self.checkequal(True, '', 'endswith', '', 0, 0) + self.checkequal(False, '', 'endswith', '', 1, 0) # test negative indices self.checkequal(True, 'hello', 'endswith', 'lo', -2) @@ -1120,8 +1123,7 @@ def test_mul(self): def test_join(self): # join now works with any sequence type # moved here, because the argument order is - # different in string.join (see the test in - # test.test_string.StringTest.test_join) + # different in string.join self.checkequal('a b c d', ' ', 'join', ['a', 'b', 'c', 'd']) self.checkequal('abcd', '', 'join', ('a', 'b', 'c', 'd')) self.checkequal('bd', '', 'join', ('', 'b', '', 'd')) @@ -1141,6 +1143,7 @@ def test_join(self): self.checkequal('a b c', ' ', 'join', BadSeq2()) self.checkraises(TypeError, ' ', 'join') + self.checkraises(TypeError, ' ', 'join', None) self.checkraises(TypeError, ' ', 'join', 7) self.checkraises(TypeError, ' ', 'join', [1, 2, bytes()]) try: @@ -1198,19 +1201,27 @@ def test_formatting(self): # Outrageously large width or precision should raise ValueError. self.checkraises(ValueError, '%%%df' % (2**64), '__mod__', (3.2)) self.checkraises(ValueError, '%%.%df' % (2**64), '__mod__', (3.2)) + self.checkraises(OverflowError, '%*s', '__mod__', + (sys.maxsize + 1, '')) + self.checkraises(OverflowError, '%.*f', '__mod__', + (sys.maxsize + 1, 1. / 7)) + class X(object): pass + self.checkraises(TypeError, 'abc', '__mod__', X()) + + @support.cpython_only + def test_formatting_c_limits(self): + from _testcapi import PY_SSIZE_T_MAX, INT_MAX, UINT_MAX + SIZE_MAX = (1 << (PY_SSIZE_T_MAX.bit_length() + 1)) - 1 self.checkraises(OverflowError, '%*s', '__mod__', - (_testcapi.PY_SSIZE_T_MAX + 1, '')) + (PY_SSIZE_T_MAX + 1, '')) self.checkraises(OverflowError, '%.*f', '__mod__', - (_testcapi.INT_MAX + 1, 1. / 7)) + (INT_MAX + 1, 1. / 7)) # Issue 15989 self.checkraises(OverflowError, '%*s', '__mod__', - (1 << (_testcapi.PY_SSIZE_T_MAX.bit_length() + 1), '')) + (SIZE_MAX + 1, '')) self.checkraises(OverflowError, '%.*f', '__mod__', - (_testcapi.UINT_MAX + 1, 1. / 7)) - - class X(object): pass - self.checkraises(TypeError, 'abc', '__mod__', X()) + (UINT_MAX + 1, 1. / 7)) def test_floatformatting(self): # float formatting diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index a242a4727d13..8b180b565790 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -3,29 +3,32 @@ if __name__ != 'test.support': raise ImportError('support must be imported from the test package') +import collections.abc import contextlib import errno +import faulthandler +import fnmatch import functools import gc -import socket -import sys -import os -import platform -import shutil -import warnings -import unittest import importlib import importlib.util -import collections.abc +import logging.handlers +import nntplib +import os +import platform import re +import shutil +import socket +import stat +import struct import subprocess -import time +import sys import sysconfig -import fnmatch -import logging.handlers -import struct import tempfile -import _testcapi +import time +import unittest +import urllib.error +import warnings try: import _thread, threading @@ -85,7 +88,7 @@ "skip_unless_symlink", "requires_gzip", "requires_bz2", "requires_lzma", "bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute", "requires_IEEE_754", "skip_unless_xattr", "requires_zlib", - "anticipate_failure", + "anticipate_failure", "load_package_tests", "detect_api_mismatch", # sys "is_jython", "check_impl_detail", # network @@ -95,7 +98,7 @@ # logging "TestHandler", # threads - "threading_setup", "threading_cleanup", + "threading_setup", "threading_cleanup", "reap_threads", "start_threads", # miscellaneous "check_warnings", "EnvironmentVarGuard", "run_with_locale", "swap_item", "swap_attr", "Matcher", "set_memlimit", "SuppressCrashReport", "sortdict", @@ -188,6 +191,25 @@ def anticipate_failure(condition): return unittest.expectedFailure return lambda f: f +def load_package_tests(pkg_dir, loader, standard_tests, pattern): + """Generic load_tests implementation for simple test packages. + + Most packages can implement load_tests using this function as follows: + + def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) + """ + if pattern is None: + pattern = "test*" + top_dir = os.path.dirname( # Lib + os.path.dirname( # test + os.path.dirname(__file__))) # support + package_tests = loader.discover(start_dir=pkg_dir, + top_level_dir=top_dir, + pattern=pattern) + standard_tests.addTests(package_tests) + return standard_tests + def import_fresh_module(name, fresh=(), blocked=(), deprecated=False): """Import and return a module, deliberately bypassing sys.modules. @@ -317,7 +339,13 @@ def _rmtree(path): def _rmtree_inner(path): for name in os.listdir(path): fullname = os.path.join(path, name) - if os.path.isdir(fullname): + try: + mode = os.lstat(fullname).st_mode + except OSError as exc: + print("support.rmtree(): os.lstat(%r) failed with %s" % (fullname, exc), + file=sys.__stderr__) + mode = 0 + if stat.S_ISDIR(mode): _waitfor(_rmtree_inner, fullname, waitall=True) os.rmdir(fullname) else: @@ -348,43 +376,43 @@ def rmtree(path): pass def make_legacy_pyc(source): - """Move a PEP 3147 pyc/pyo file to its legacy pyc/pyo location. - - The choice of .pyc or .pyo extension is done based on the __debug__ flag - value. + """Move a PEP 3147/488 pyc file to its legacy pyc location. :param source: The file system path to the source file. The source file - does not need to exist, however the PEP 3147 pyc file must exist. + does not need to exist, however the PEP 3147/488 pyc file must exist. :return: The file system path to the legacy pyc file. """ pyc_file = importlib.util.cache_from_source(source) up_one = os.path.dirname(os.path.abspath(source)) - legacy_pyc = os.path.join(up_one, source + ('c' if __debug__ else 'o')) + legacy_pyc = os.path.join(up_one, source + 'c') os.rename(pyc_file, legacy_pyc) return legacy_pyc def forget(modname): """'Forget' a module was ever imported. - This removes the module from sys.modules and deletes any PEP 3147 or - legacy .pyc and .pyo files. + This removes the module from sys.modules and deletes any PEP 3147/488 or + legacy .pyc files. """ unload(modname) for dirname in sys.path: source = os.path.join(dirname, modname + '.py') # It doesn't matter if they exist or not, unlink all possible - # combinations of PEP 3147 and legacy pyc and pyo files. + # combinations of PEP 3147/488 and legacy pyc files. unlink(source + 'c') - unlink(source + 'o') - unlink(importlib.util.cache_from_source(source, debug_override=True)) - unlink(importlib.util.cache_from_source(source, debug_override=False)) - -# On some platforms, should not run gui test even if it is allowed -# in `use_resources'. -if sys.platform.startswith('win'): - import ctypes - import ctypes.wintypes - def _is_gui_available(): + for opt in ('', 1, 2): + unlink(importlib.util.cache_from_source(source, optimization=opt)) + +# Check whether a gui is actually available +def _is_gui_available(): + if hasattr(_is_gui_available, 'result'): + return _is_gui_available.result + reason = None + if sys.platform.startswith('win'): + # if Python is running as a service (such as the buildbot service), + # gui interaction may be disallowed + import ctypes + import ctypes.wintypes UOI_FLAGS = 1 WSF_VISIBLE = 0x0001 class USEROBJECTFLAGS(ctypes.Structure): @@ -404,29 +432,63 @@ class USEROBJECTFLAGS(ctypes.Structure): ctypes.byref(needed)) if not res: raise ctypes.WinError() - return bool(uof.dwFlags & WSF_VISIBLE) -else: - def _is_gui_available(): - return True + if not bool(uof.dwFlags & WSF_VISIBLE): + reason = "gui not available (WSF_VISIBLE flag not set)" + elif sys.platform == 'darwin': + # The Aqua Tk implementations on OS X can abort the process if + # being called in an environment where a window server connection + # cannot be made, for instance when invoked by a buildbot or ssh + # process not running under the same user id as the current console + # user. To avoid that, raise an exception if the window manager + # connection is not available. + from ctypes import cdll, c_int, pointer, Structure + from ctypes.util import find_library + + app_services = cdll.LoadLibrary(find_library("ApplicationServices")) + + if app_services.CGMainDisplayID() == 0: + reason = "gui tests cannot run without OS X window manager" + else: + class ProcessSerialNumber(Structure): + _fields_ = [("highLongOfPSN", c_int), + ("lowLongOfPSN", c_int)] + psn = ProcessSerialNumber() + psn_p = pointer(psn) + if ( (app_services.GetCurrentProcess(psn_p) < 0) or + (app_services.SetFrontProcess(psn_p) < 0) ): + reason = "cannot run without OS X gui process" + + # check on every platform whether tkinter can actually do anything + if not reason: + try: + from tkinter import Tk + root = Tk() + root.update() + root.destroy() + except Exception as e: + err_string = str(e) + if len(err_string) > 50: + err_string = err_string[:50] + ' [...]' + reason = 'Tk unavailable due to {}: {}'.format(type(e).__name__, + err_string) + + _is_gui_available.reason = reason + _is_gui_available.result = not reason + + return _is_gui_available.result def is_resource_enabled(resource): - """Test whether a resource is enabled. Known resources are set by - regrtest.py.""" - return use_resources is not None and resource in use_resources + """Test whether a resource is enabled. -def requires(resource, msg=None): - """Raise ResourceDenied if the specified resource is not available. - - If the caller's module is __main__ then automatically return True. The - possibility of False being returned occurs when regrtest.py is - executing. + Known resources are set by regrtest.py. If not running under regrtest.py, + all resources are assumed enabled unless use_resources has been set. """ + return use_resources is None or resource in use_resources + +def requires(resource, msg=None): + """Raise ResourceDenied if the specified resource is not available.""" if resource == 'gui' and not _is_gui_available(): - raise unittest.SkipTest("Cannot use the 'gui' resource") - # see if the caller's module is __main__ - if so, treat as if - # the resource was set - if sys._getframe(1).f_globals.get("__name__") == "__main__": - return + raise ResourceDenied(_is_gui_available.reason) if not is_resource_enabled(resource): if msg is None: msg = "Use of the %r resource not enabled" % resource @@ -627,6 +689,18 @@ def _is_ipv6_enabled(): IPV6_ENABLED = _is_ipv6_enabled() +def system_must_validate_cert(f): + """Skip the test on TLS certificate validation failures.""" + @functools.wraps(f) + def dec(*args, **kwargs): + try: + f(*args, **kwargs) + except IOError as e: + if "CERTIFICATE_VERIFY_FAILED" in str(e): + raise unittest.SkipTest("system does not contain " + "necessary certificates") + raise + return dec # A constant likely larger than the underlying OS pipe buffer size, to # make writes blocking. @@ -964,8 +1038,14 @@ def check_valid_file(fn): # Verify the requirement before downloading the file requires('urlfetch') - print('\tfetching %s ...' % url, file=get_original_stdout()) - f = urllib.request.urlopen(url, timeout=15) + if verbose: + print('\tfetching %s ...' % url, file=get_original_stdout()) + opener = urllib.request.build_opener() + if gzip: + opener.addheaders.append(('Accept-Encoding', 'gzip')) + f = opener.open(url, timeout=15) + if gzip and f.headers.get('Content-Encoding') == 'gzip': + f = gzip.GzipFile(fileobj=f) try: with open(fn, "wb") as out: s = f.read() @@ -1243,6 +1323,11 @@ def filter_error(err): n = getattr(err, 'errno', None) if (isinstance(err, socket.timeout) or (isinstance(err, socket.gaierror) and n in gai_errnos) or + (isinstance(err, urllib.error.HTTPError) and + 500 <= err.code <= 599) or + (isinstance(err, urllib.error.URLError) and + (("ConnectionRefusedError" in err.reason) or + ("TimeoutError" in err.reason))) or n in captured_errnos): if not verbose: sys.stderr.write(denied.args[0] + "\n") @@ -1253,6 +1338,10 @@ def filter_error(err): if timeout is not None: socket.setdefaulttimeout(timeout) yield + except nntplib.NNTPTemporaryError as err: + if verbose: + sys.stderr.write(denied.args[0] + "\n") + raise denied from err except OSError as err: # urllib can wrap original socket errors multiple times (!), we must # unwrap to get at the original error. @@ -1292,7 +1381,7 @@ def captured_stdout(): with captured_stdout() as stdout: print("hello") - self.assertEqual(stdout.getvalue(), "hello\n") + self.assertEqual(stdout.getvalue(), "hello\\n") """ return captured_output("stdout") @@ -1301,7 +1390,7 @@ def captured_stderr(): with captured_stderr() as stderr: print("hello", file=sys.stderr) - self.assertEqual(stderr.getvalue(), "hello\n") + self.assertEqual(stderr.getvalue(), "hello\\n") """ return captured_output("stderr") @@ -1309,7 +1398,7 @@ def captured_stdin(): """Capture the input to sys.stdin: with captured_stdin() as stdin: - stdin.write('hello\n') + stdin.write('hello\\n') stdin.seek(0) # call test code that consumes from sys.stdin captured = input() @@ -1352,7 +1441,7 @@ def python_is_optimized(): for opt in cflags.split(): if opt.startswith('-O'): final_opt = opt - return final_opt != '' and final_opt != '-O0' + return final_opt not in ('', '-O0', '-Og') _header = 'nP' @@ -1373,6 +1462,7 @@ def calcvobjsize(fmt): _TPFLAGS_HEAPTYPE = 1<<9 def check_sizeof(test, o, size): + import _testcapi result = sys.getsizeof(o) # add GC header size if ((type(o) == type) and (o.__flags__ & _TPFLAGS_HEAPTYPE) or\ @@ -1589,7 +1679,7 @@ def _id(obj): def requires_resource(resource): if resource == 'gui' and not _is_gui_available(): - return unittest.skip("resource 'gui' is not available") + return unittest.skip(_is_gui_available.reason) if is_resource_enabled(resource): return _id else: @@ -1853,6 +1943,42 @@ def reap_children(): except: break +@contextlib.contextmanager +def start_threads(threads, unlock=None): + threads = list(threads) + started = [] + try: + try: + for t in threads: + t.start() + started.append(t) + except: + if verbose: + print("Can't start %d threads, only %d threads started" % + (len(threads), len(started))) + raise + yield + finally: + try: + if unlock: + unlock() + endtime = starttime = time.time() + for timeout in range(1, 16): + endtime += 60 + for t in started: + t.join(max(endtime - time.time(), 0.01)) + started = [t for t in started if t.isAlive()] + if not started: + break + if verbose: + print('Unable to join %d threads during a period of ' + '%d minutes' % (len(started), timeout)) + finally: + started = [t for t in started if t.isAlive()] + if started: + faulthandler.dump_traceback(sys.stdout) + raise AssertionError('Unable to join %d threads' % len(started)) + @contextlib.contextmanager def swap_attr(obj, attr, new_val): """Temporary swap out an attribute with a new object. @@ -2047,16 +2173,30 @@ def skip_unless_xattr(test): def fs_is_case_insensitive(directory): """Detects if the file system for the specified directory is case-insensitive.""" - base_fp, base_path = tempfile.mkstemp(dir=directory) - case_path = base_path.upper() - if case_path == base_path: - case_path = base_path.lower() - try: - return os.path.samefile(base_path, case_path) - except FileNotFoundError: - return False - finally: - os.unlink(base_path) + with tempfile.NamedTemporaryFile(dir=directory) as base: + base_path = base.name + case_path = base_path.upper() + if case_path == base_path: + case_path = base_path.lower() + try: + return os.path.samefile(base_path, case_path) + except FileNotFoundError: + return False + + +def detect_api_mismatch(ref_api, other_api, *, ignore=()): + """Returns the set of items in ref_api not in other_api, except for a + defined list of items to be ignored in this check. + + By default this skips private attributes beginning with '_' but + includes all magic methods, i.e. those starting and ending in '__'. + """ + missing_items = set(dir(ref_api)) - set(dir(other_api)) + if ignore: + missing_items -= set(ignore) + missing_items = set(m for m in missing_items + if not m.startswith('_') or m.endswith('__')) + return missing_items class SuppressCrashReport: @@ -2066,6 +2206,7 @@ class SuppressCrashReport: disable the creation of coredump file. """ old_value = None + old_modes = None def __enter__(self): """On Windows, disable Windows Error Reporting dialogs using @@ -2083,6 +2224,26 @@ def __enter__(self): SEM_NOGPFAULTERRORBOX = 0x02 self.old_value = self._k32.SetErrorMode(SEM_NOGPFAULTERRORBOX) self._k32.SetErrorMode(self.old_value | SEM_NOGPFAULTERRORBOX) + + # Suppress assert dialogs in debug builds + # (see http://bugs.python.org/issue23314) + try: + import msvcrt + msvcrt.CrtSetReportMode + except (AttributeError, ImportError): + # no msvcrt or a release build + pass + else: + self.old_modes = {} + for report_type in [msvcrt.CRT_WARN, + msvcrt.CRT_ERROR, + msvcrt.CRT_ASSERT]: + old_mode = msvcrt.CrtSetReportMode(report_type, + msvcrt.CRTDBG_MODE_FILE) + old_file = msvcrt.CrtSetReportFile(report_type, + msvcrt.CRTDBG_FILE_STDERR) + self.old_modes[report_type] = old_mode, old_file + else: if resource is not None: try: @@ -2114,6 +2275,12 @@ def __exit__(self, *ignore_exc): if sys.platform.startswith('win'): self._k32.SetErrorMode(self.old_value) + + if self.old_modes: + import msvcrt + for report_type, (old_mode, old_file) in self.old_modes.items(): + msvcrt.CrtSetReportMode(report_type, old_mode) + msvcrt.CrtSetReportFile(report_type, old_file) else: if resource is not None: try: @@ -2172,4 +2339,5 @@ def run_in_subinterp(code): raise unittest.SkipTest("run_in_subinterp() cannot be used " "if tracemalloc module is tracing " "memory allocations") + import _testcapi return _testcapi.run_in_subinterp(code) diff --git a/Lib/test/script_helper.py b/Lib/test/support/script_helper.py similarity index 57% rename from Lib/test/script_helper.py rename to Lib/test/support/script_helper.py index 4d5c1f120adf..584b0e8eefa6 100644 --- a/Lib/test/script_helper.py +++ b/Lib/test/support/script_helper.py @@ -1,6 +1,7 @@ # Common utility functions used by various script execution tests # e.g. test_cmd_line, test_cmd_line_script and test_runpy +import collections import importlib import sys import os @@ -13,20 +14,60 @@ import zipfile from importlib.util import source_from_cache -from test.support import make_legacy_pyc, strip_python_stderr, temp_dir +from test.support import make_legacy_pyc, strip_python_stderr + + +# Cached result of the expensive test performed in the function below. +__cached_interp_requires_environment = None + +def interpreter_requires_environment(): + """ + Returns True if our sys.executable interpreter requires environment + variables in order to be able to run at all. + + This is designed to be used with @unittest.skipIf() to annotate tests + that need to use an assert_python*() function to launch an isolated + mode (-I) or no environment mode (-E) sub-interpreter process. + + A normal build & test does not run into this situation but it can happen + when trying to run the standard library test suite from an interpreter that + doesn't have an obvious home with Python's current home finding logic. + + Setting PYTHONHOME is one way to get most of the testsuite to run in that + situation. PYTHONPATH or PYTHONUSERSITE are other common environment + variables that might impact whether or not the interpreter can start. + """ + global __cached_interp_requires_environment + if __cached_interp_requires_environment is None: + # Try running an interpreter with -E to see if it works or not. + try: + subprocess.check_call([sys.executable, '-E', + '-c', 'import sys; sys.exit(0)']) + except subprocess.CalledProcessError: + __cached_interp_requires_environment = True + else: + __cached_interp_requires_environment = False + + return __cached_interp_requires_environment + + +_PythonRunResult = collections.namedtuple("_PythonRunResult", + ("rc", "out", "err")) + # Executing the interpreter in a subprocess -def _assert_python(expected_success, *args, **env_vars): +def run_python_until_end(*args, **env_vars): + env_required = interpreter_requires_environment() if '__isolated' in env_vars: isolated = env_vars.pop('__isolated') else: - isolated = not env_vars + isolated = not env_vars and not env_required cmd_line = [sys.executable, '-X', 'faulthandler'] if isolated: # isolated mode: ignore Python environment variables, ignore user # site-packages, and don't add the current directory to sys.path cmd_line.append('-I') - elif not env_vars: + elif not env_vars and not env_required: # ignore Python environment variables cmd_line.append('-E') # Need to preserve the original environment, for in-place testing of @@ -49,11 +90,36 @@ def _assert_python(expected_success, *args, **env_vars): p.stderr.close() rc = p.returncode err = strip_python_stderr(err) - if (rc and expected_success) or (not rc and not expected_success): - raise AssertionError( - "Process return code is %d, " - "stderr follows:\n%s" % (rc, err.decode('ascii', 'ignore'))) - return rc, out, err + return _PythonRunResult(rc, out, err), cmd_line + +def _assert_python(expected_success, *args, **env_vars): + res, cmd_line = run_python_until_end(*args, **env_vars) + if (res.rc and expected_success) or (not res.rc and not expected_success): + # Limit to 80 lines to ASCII characters + maxlen = 80 * 100 + out, err = res.out, res.err + if len(out) > maxlen: + out = b'(... truncated stdout ...)' + out[-maxlen:] + if len(err) > maxlen: + err = b'(... truncated stderr ...)' + err[-maxlen:] + out = out.decode('ascii', 'replace').rstrip() + err = err.decode('ascii', 'replace').rstrip() + raise AssertionError("Process return code is %d\n" + "command line: %r\n" + "\n" + "stdout:\n" + "---\n" + "%s\n" + "---\n" + "\n" + "stderr:\n" + "---\n" + "%s\n" + "---" + % (res.rc, cmd_line, + out, + err)) + return res def assert_python_ok(*args, **env_vars): """ @@ -78,7 +144,7 @@ def assert_python_failure(*args, **env_vars): """ return _assert_python(False, *args, **env_vars) -def spawn_python(*args, **kw): +def spawn_python(*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw): """Run a Python subprocess with the given arguments. kw is extra keyword args to pass to subprocess.Popen. Returns a Popen @@ -86,8 +152,16 @@ def spawn_python(*args, **kw): """ cmd_line = [sys.executable, '-E'] cmd_line.extend(args) + # Under Fedora (?), GNU readline can output junk on stderr when initialized, + # depending on the TERM setting. Setting TERM=vt100 is supposed to disable + # that. References: + # - http://reinout.vanrees.org/weblog/2009/08/14/readline-invisible-character-hack.html + # - http://stackoverflow.com/questions/15760712/python-readline-module-prints-escape-character-during-import + # - http://lists.gnu.org/archive/html/bug-readline/2007-08/msg00004.html + env = kw.setdefault('env', dict(os.environ)) + env['TERM'] = 'vt100' return subprocess.Popen(cmd_line, stdin=subprocess.PIPE, - stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + stdout=stdout, stderr=stderr, **kw) def kill_python(p): @@ -101,8 +175,10 @@ def kill_python(p): subprocess._cleanup() return data -def make_script(script_dir, script_basename, source): - script_filename = script_basename+os.extsep+'py' +def make_script(script_dir, script_basename, source, omit_suffix=False): + script_filename = script_basename + if not omit_suffix: + script_filename += os.extsep + 'py' script_name = os.path.join(script_dir, script_filename) # The script should be encoded to UTF-8, the default string encoding script_file = open(script_name, 'w', encoding='utf-8') @@ -145,8 +221,8 @@ def make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, script_name = make_script(zip_dir, script_basename, source) unlink.append(script_name) if compiled: - init_name = py_compile(init_name, doraise=True) - script_name = py_compile(script_name, doraise=True) + init_name = py_compile.compile(init_name, doraise=True) + script_name = py_compile.compile(script_name, doraise=True) unlink.extend((init_name, script_name)) pkg_names = [os.sep.join([pkg_name]*i) for i in range(1, depth+1)] script_name_in_zip = os.path.join(pkg_names[-1], os.path.basename(script_name)) diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py index 8cc285f70a5c..e94d984f2b94 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -72,13 +72,14 @@ def test_all(self): # rlcompleter needs special consideration; it import readline which # initializes GNU readline which calls setlocale(LC_CTYPE, "")... :-( + import locale + locale_tuple = locale.getlocale(locale.LC_CTYPE) try: import rlcompleter - import locale except ImportError: pass - else: - locale.setlocale(locale.LC_CTYPE, 'C') + finally: + locale.setlocale(locale.LC_CTYPE, locale_tuple) ignored = [] failed_imports = [] diff --git a/Lib/test/test___future__.py b/Lib/test/test___future__.py index 9ae4ce40ad47..559a1873addd 100644 --- a/Lib/test/test___future__.py +++ b/Lib/test/test___future__.py @@ -1,6 +1,4 @@ -#! /usr/bin/env python3 import unittest -from test import support import __future__ GOOD_SERIALS = ("alpha", "beta", "candidate", "final") @@ -59,8 +57,5 @@ def check(t, name): ".compiler_flag isn't int") -def test_main(): - support.run_unittest(FutureTest) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test__locale.py b/Lib/test/test__locale.py index 4231f37bc963..d95d3a4e0baa 100644 --- a/Lib/test/test__locale.py +++ b/Lib/test/test__locale.py @@ -9,7 +9,6 @@ import sys import unittest from platform import uname -from test.support import run_unittest if uname().system == "Darwin": maj, min, mic = [int(part) for part in uname().release.split(".")] @@ -24,45 +23,53 @@ 'da_DK', 'nn_NO', 'cs_CZ', 'de_LU', 'es_BO', 'sq_AL', 'sk_SK', 'fr_CH', 'de_DE', 'sr_YU', 'br_FR', 'nl_BE', 'sv_FI', 'pl_PL', 'fr_CA', 'fo_FO', 'bs_BA', 'fr_LU', 'kl_GL', 'fa_IR', 'de_BE', 'sv_SE', 'it_CH', 'uk_UA', - 'eu_ES', 'vi_VN', 'af_ZA', 'nb_NO', 'en_DK', 'tg_TJ', 'en_US', - 'es_ES.ISO8859-1', 'fr_FR.ISO8859-15', 'ru_RU.KOI8-R', 'ko_KR.eucKR'] - -# Issue #13441: Skip some locales (e.g. cs_CZ and hu_HU) on Solaris to -# workaround a mbstowcs() bug. For example, on Solaris, the hu_HU locale uses -# the locale encoding ISO-8859-2, the thousauds separator is b'\xA0' and it is -# decoded as U+30000020 (an invalid character) by mbstowcs(). -if sys.platform == 'sunos5': - old_locale = locale.setlocale(locale.LC_ALL) - try: - locales = [] - for loc in candidate_locales: - try: - locale.setlocale(locale.LC_ALL, loc) - except Error: - continue - encoding = locale.getpreferredencoding(False) - try: - localeconv() - except Exception as err: - print("WARNING: Skip locale %s (encoding %s): [%s] %s" - % (loc, encoding, type(err), err)) - else: - locales.append(loc) - candidate_locales = locales - finally: - locale.setlocale(locale.LC_ALL, old_locale) - -# Workaround for MSVC6(debug) crash bug -if "MSC v.1200" in sys.version: - def accept(loc): - a = loc.split(".") - return not(len(a) == 2 and len(a[-1]) >= 9) - candidate_locales = [loc for loc in candidate_locales if accept(loc)] + 'eu_ES', 'vi_VN', 'af_ZA', 'nb_NO', 'en_DK', 'tg_TJ', 'ps_AF', 'en_US', + 'fr_FR.ISO8859-1', 'fr_FR.UTF-8', 'fr_FR.ISO8859-15@euro', + 'ru_RU.KOI8-R', 'ko_KR.eucKR'] + +def setUpModule(): + global candidate_locales + # Issue #13441: Skip some locales (e.g. cs_CZ and hu_HU) on Solaris to + # workaround a mbstowcs() bug. For example, on Solaris, the hu_HU locale uses + # the locale encoding ISO-8859-2, the thousauds separator is b'\xA0' and it is + # decoded as U+30000020 (an invalid character) by mbstowcs(). + if sys.platform == 'sunos5': + old_locale = locale.setlocale(locale.LC_ALL) + try: + locales = [] + for loc in candidate_locales: + try: + locale.setlocale(locale.LC_ALL, loc) + except Error: + continue + encoding = locale.getpreferredencoding(False) + try: + localeconv() + except Exception as err: + print("WARNING: Skip locale %s (encoding %s): [%s] %s" + % (loc, encoding, type(err), err)) + else: + locales.append(loc) + candidate_locales = locales + finally: + locale.setlocale(locale.LC_ALL, old_locale) + + # Workaround for MSVC6(debug) crash bug + if "MSC v.1200" in sys.version: + def accept(loc): + a = loc.split(".") + return not(len(a) == 2 and len(a[-1]) >= 9) + candidate_locales = [loc for loc in candidate_locales if accept(loc)] # List known locale values to test against when available. # Dict formatted as `` : (, )``. If a # value is not known, use '' . -known_numerics = {'fr_FR' : (',', ''), 'en_US':('.', ',')} +known_numerics = { + 'en_US': ('.', ','), + 'de_DE' : (',', '.'), + 'fr_FR.UTF-8' : (',', ' '), + 'ps_AF': ('\u066b', '\u066c'), +} class _LocaleTests(unittest.TestCase): @@ -91,10 +98,12 @@ def numeric_tester(self, calc_type, calc_value, data_type, used_locale): calc_value, known_value, calc_type, data_type, set_locale, used_locale)) + return True @unittest.skipUnless(nl_langinfo, "nl_langinfo is not available") def test_lc_numeric_nl_langinfo(self): # Test nl_langinfo against known values + tested = False for loc in candidate_locales: try: setlocale(LC_NUMERIC, loc) @@ -103,10 +112,14 @@ def test_lc_numeric_nl_langinfo(self): continue for li, lc in ((RADIXCHAR, "decimal_point"), (THOUSEP, "thousands_sep")): - self.numeric_tester('nl_langinfo', nl_langinfo(li), lc, loc) + if self.numeric_tester('nl_langinfo', nl_langinfo(li), lc, loc): + tested = True + if not tested: + self.skipTest('no suitable locales') def test_lc_numeric_localeconv(self): # Test localeconv against known values + tested = False for loc in candidate_locales: try: setlocale(LC_NUMERIC, loc) @@ -116,11 +129,15 @@ def test_lc_numeric_localeconv(self): formatting = localeconv() for lc in ("decimal_point", "thousands_sep"): - self.numeric_tester('localeconv', formatting[lc], lc, loc) + if self.numeric_tester('localeconv', formatting[lc], lc, loc): + tested = True + if not tested: + self.skipTest('no suitable locales') @unittest.skipUnless(nl_langinfo, "nl_langinfo is not available") def test_lc_numeric_basic(self): # Test nl_langinfo against localeconv + tested = False for loc in candidate_locales: try: setlocale(LC_NUMERIC, loc) @@ -140,10 +157,14 @@ def test_lc_numeric_basic(self): "(set to %s, using %s)" % ( nl_radixchar, li_radixchar, loc, set_locale)) + tested = True + if not tested: + self.skipTest('no suitable locales') def test_float_parsing(self): # Bug #1391872: Test whether float parsing is okay on European # locales. + tested = False for loc in candidate_locales: try: setlocale(LC_NUMERIC, loc) @@ -162,9 +183,10 @@ def test_float_parsing(self): if localeconv()['decimal_point'] != '.': self.assertRaises(ValueError, float, localeconv()['decimal_point'].join(['1', '23'])) + tested = True + if not tested: + self.skipTest('no suitable locales') -def test_main(): - run_unittest(_LocaleTests) if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test__opcode.py b/Lib/test/test__opcode.py index 0152e9d94da4..1075decc2704 100644 --- a/Lib/test/test__opcode.py +++ b/Lib/test/test__opcode.py @@ -1,5 +1,5 @@ import dis -from test.support import run_unittest, import_module +from test.support import import_module import unittest _opcode = import_module("_opcode") @@ -16,8 +16,5 @@ def test_stack_effect(self): self.assertRaises(ValueError, _opcode.stack_effect, dis.opmap['BUILD_SLICE']) self.assertRaises(ValueError, _opcode.stack_effect, dis.opmap['POP_TOP'], 0) -def test_main(): - run_unittest(OpcodeTests) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test__osx_support.py b/Lib/test/test__osx_support.py index fb159ecf4138..ac6325a751ef 100644 --- a/Lib/test/test__osx_support.py +++ b/Lib/test/test__osx_support.py @@ -109,7 +109,9 @@ def test__save_modified_value_unchanged(self): def test__supports_universal_builds(self): import platform - self.assertEqual(platform.mac_ver()[0].split('.') >= ['10', '4'], + mac_ver_tuple = tuple(int(i) for i in + platform.mac_ver()[0].split('.')[0:2]) + self.assertEqual(mac_ver_tuple >= (10, 4), _osx_support._supports_universal_builds()) def test__find_appropriate_compiler(self): @@ -271,9 +273,5 @@ def test_get_platform_osx(self): result = _osx_support.get_platform_osx(config_vars, ' ', ' ', ' ') self.assertEqual(('macosx', '10.6', 'fat'), result) -def test_main(): - if sys.platform == 'darwin': - test.support.run_unittest(Test_OSXSupport) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_abc.py b/Lib/test/test_abc.py index 93f9dae21519..e1765f0d5a54 100644 --- a/Lib/test/test_abc.py +++ b/Lib/test/test_abc.py @@ -194,9 +194,9 @@ def foo(self, val): pass # check that the property's __isabstractmethod__ descriptor does the # right thing when presented with a value that fails truth testing: class NotBool(object): - def __nonzero__(self): + def __bool__(self): raise ValueError() - __len__ = __nonzero__ + __len__ = __bool__ with self.assertRaises(ValueError): class F(C): def bar(self): diff --git a/Lib/test/test_abstract_numbers.py b/Lib/test/test_abstract_numbers.py index 253e6f082c30..2e06f0d16fdd 100644 --- a/Lib/test/test_abstract_numbers.py +++ b/Lib/test/test_abstract_numbers.py @@ -4,7 +4,6 @@ import operator import unittest from numbers import Complex, Real, Rational, Integral -from test import support class TestNumbers(unittest.TestCase): def test_int(self): @@ -40,9 +39,6 @@ def test_complex(self): self.assertRaises(TypeError, float, c1) self.assertRaises(TypeError, int, c1) -def test_main(): - support.run_unittest(TestNumbers) - if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_aifc.py b/Lib/test/test_aifc.py index 041b23688c66..ab5143787b0d 100644 --- a/Lib/test/test_aifc.py +++ b/Lib/test/test_aifc.py @@ -14,9 +14,6 @@ class AifcTest(audiotests.AudioWriteTests, module = aifc close_fd = True test_unseekable_read = None - test_unseekable_write = None - test_unseekable_incompleted_write = None - test_unseekable_overflowed_write = None class AifcPCM8Test(AifcTest, unittest.TestCase): diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index c10c5909bf3e..893ec394f643 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -20,15 +20,6 @@ class StdIOBuffer(StringIO): class TestCase(unittest.TestCase): - def assertEqual(self, obj1, obj2): - if obj1 != obj2: - print('') - print(repr(obj1)) - print(repr(obj2)) - print(obj1) - print(obj2) - super(TestCase, self).assertEqual(obj1, obj2) - def setUp(self): # The tests assume that line wrapping occurs at 80 columns, but this # behaviour can be overridden by setting the COLUMNS environment @@ -47,6 +38,9 @@ def setUp(self): def tearDown(self): os.chdir(self.old_dir) + for root, dirs, files in os.walk(self.temp_dir, topdown=False): + for name in files: + os.chmod(os.path.join(self.temp_dir, name), stat.S_IWRITE) shutil.rmtree(self.temp_dir, True) def create_readonly_file(self, filename): @@ -75,9 +69,6 @@ def __repr__(self): def __eq__(self, other): return vars(self) == vars(other) - def __ne__(self, other): - return not (self == other) - class ArgumentParserError(Exception): @@ -232,8 +223,8 @@ def test_failures(self, tester): parser = self._get_parser(tester) for args_str in tester.failures: args = args_str.split() - raises = tester.assertRaises - raises(ArgumentParserError, parser.parse_args, args) + with tester.assertRaises(ArgumentParserError, msg=args): + parser.parse_args(args) def test_successes(self, tester): parser = self._get_parser(tester) @@ -641,7 +632,7 @@ class TestOptionalsChoices(ParserTestCase): class TestOptionalsRequired(ParserTestCase): - """Tests the an optional action that is required""" + """Tests an optional action that is required""" argument_signatures = [ Sig('-x', type=int, required=True), @@ -762,6 +753,39 @@ class TestOptionalsActionCount(ParserTestCase): ] +class TestOptionalsAllowLongAbbreviation(ParserTestCase): + """Allow long options to be abbreviated unambiguously""" + + argument_signatures = [ + Sig('--foo'), + Sig('--foobaz'), + Sig('--fooble', action='http://github.com/store_true'), + ] + failures = ['--foob 5', '--foob'] + successes = [ + ('', NS(foo=None, foobaz=None, fooble=False)), + ('--foo 7', NS(foo='7', foobaz=None, fooble=False)), + ('--fooba a', NS(foo=None, foobaz='a', fooble=False)), + ('--foobl --foo g', NS(foo='g', foobaz=None, fooble=True)), + ] + + +class TestOptionalsDisallowLongAbbreviation(ParserTestCase): + """Do not allow abbreviations of long options at all""" + + parser_signature = Sig(allow_abbrev=False) + argument_signatures = [ + Sig('--foo'), + Sig('--foodle', action='http://github.com/store_true'), + Sig('--foonly'), + ] + failures = ['-foon 3', '--foon 3', '--food', '--food --foo 2'] + successes = [ + ('', NS(foo=None, foodle=False, foonly=None)), + ('--foo 3', NS(foo='3', foodle=False, foonly=None)), + ('--foonly 7 --foodle --foo 2', NS(foo='2', foodle=True, foonly='7')), + ] + # ================ # Positional tests # ================ @@ -1990,14 +2014,9 @@ def test_subparser_title_help(self): ''')) def _test_subparser_help(self, args_str, expected_help): - try: + with self.assertRaises(ArgumentParserError) as cm: self.parser.parse_args(args_str.split()) - except ArgumentParserError: - err = sys.exc_info()[1] - if err.stdout != expected_help: - print(repr(expected_help)) - print(repr(err.stdout)) - self.assertEqual(err.stdout, expected_help) + self.assertEqual(expected_help, cm.exception.stdout) def test_subparser1_help(self): self._test_subparser_help('5.0 1 -h', textwrap.dedent('''\ @@ -2792,6 +2811,13 @@ def test_set_defaults_parents(self): parser = ErrorRaisingArgumentParser(parents=[parent]) self.assertEqual(NS(x='foo'), parser.parse_args([])) + def test_set_defaults_on_parent_and_subparser(self): + parser = argparse.ArgumentParser() + xparser = parser.add_subparsers().add_parser('X') + parser.set_defaults(foo=1) + xparser.set_defaults(foo=2) + self.assertEqual(NS(foo=2), parser.parse_args(['X'])) + def test_set_defaults_same_as_add_argument(self): parser = ErrorRaisingArgumentParser() parser.set_defaults(w='W', x='X', y='Y', z='Z') @@ -2836,15 +2862,15 @@ class TestGetDefault(TestCase): def test_get_default(self): parser = ErrorRaisingArgumentParser() - self.assertEqual(None, parser.get_default("foo")) - self.assertEqual(None, parser.get_default("bar")) + self.assertIsNone(parser.get_default("foo")) + self.assertIsNone(parser.get_default("bar")) parser.add_argument("--foo") - self.assertEqual(None, parser.get_default("foo")) - self.assertEqual(None, parser.get_default("bar")) + self.assertIsNone(parser.get_default("foo")) + self.assertIsNone(parser.get_default("bar")) parser.add_argument("--bar", type=int, default=42) - self.assertEqual(None, parser.get_default("foo")) + self.assertIsNone(parser.get_default("foo")) self.assertEqual(42, parser.get_default("bar")) parser.set_defaults(foo="badger") @@ -2859,18 +2885,16 @@ class TestNamespaceContainsSimple(TestCase): def test_empty(self): ns = argparse.Namespace() - self.assertEqual('' in ns, False) - self.assertEqual('' not in ns, True) - self.assertEqual('x' in ns, False) + self.assertNotIn('', ns) + self.assertNotIn('x', ns) def test_non_empty(self): ns = argparse.Namespace(x=1, y=2) - self.assertEqual('x' in ns, True) - self.assertEqual('x' not in ns, False) - self.assertEqual('y' in ns, True) - self.assertEqual('' in ns, False) - self.assertEqual('xx' in ns, False) - self.assertEqual('z' in ns, False) + self.assertNotIn('', ns) + self.assertIn('x', ns) + self.assertIn('y', ns) + self.assertNotIn('xx', ns) + self.assertNotIn('z', ns) # ===================== # Help formatting tests @@ -2926,13 +2950,6 @@ def _get_parser(self, tester): def _test(self, tester, parser_text): expected_text = getattr(tester, self.func_suffix) expected_text = textwrap.dedent(expected_text) - if expected_text != parser_text: - print(repr(expected_text)) - print(repr(parser_text)) - for char1, char2 in zip(expected_text, parser_text): - if char1 != char2: - print('first diff: %r %r' % (char1, char2)) - break tester.assertEqual(expected_text, parser_text) def test_format(self, tester): @@ -3005,6 +3022,60 @@ class TestHelpBiggerOptionals(HelpTestCase): 0.1 ''' +class TestShortColumns(HelpTestCase): + '''Test extremely small number of columns. + + TestCase prevents "COLUMNS" from being too small in the tests themselves, + but we don't want any exceptions thrown in such case. Only ugly representation. + ''' + def setUp(self): + env = support.EnvironmentVarGuard() + env.set("COLUMNS", '15') + self.addCleanup(env.__exit__) + + parser_signature = TestHelpBiggerOptionals.parser_signature + argument_signatures = TestHelpBiggerOptionals.argument_signatures + argument_group_signatures = TestHelpBiggerOptionals.argument_group_signatures + usage = '''\ + usage: PROG + [-h] + [-v] + [-x] + [--y Y] + foo + bar + ''' + help = usage + '''\ + + DESCRIPTION + + positional arguments: + foo + FOO HELP + bar + BAR HELP + + optional arguments: + -h, --help + show this + help + message and + exit + -v, --version + show + program's + version + number and + exit + -x + X HELP + --y Y + Y HELP + + EPILOG + ''' + version = TestHelpBiggerOptionals.version + class TestHelpBiggerOptionalGroups(HelpTestCase): """Make sure that argument help aligns when options are longer""" @@ -3781,34 +3852,6 @@ class TestHelpNoHelpOptional(HelpTestCase): version = '' -class TestHelpVersionOptional(HelpTestCase): - """Test that the --version argument can be suppressed help messages""" - - parser_signature = Sig(prog='PROG') - argument_signatures = [ - Sig('-v', '--version', action='http://github.com/version', version='1.0'), - Sig('--foo', help='foo help'), - Sig('spam', help='spam help'), - ] - argument_group_signatures = [] - usage = '''\ - usage: PROG [-h] [-v] [--foo FOO] spam - ''' - help = usage + '''\ - - positional arguments: - spam spam help - - optional arguments: - -h, --help show this help message and exit - -v, --version show program's version number and exit - --foo FOO foo help - ''' - version = '''\ - 1.0 - ''' - - class TestHelpNone(HelpTestCase): """Test that no errors occur if no help is specified""" @@ -4016,6 +4059,32 @@ class TestHelpVersionAction(HelpTestCase): ''' version = '' + +class TestHelpVersionActionSuppress(HelpTestCase): + """Test that the --version argument can be suppressed in help messages""" + + parser_signature = Sig(prog='PROG') + argument_signatures = [ + Sig('-v', '--version', action='http://github.com/version', version='1.0', + help=argparse.SUPPRESS), + Sig('--foo', help='foo help'), + Sig('spam', help='spam help'), + ] + argument_group_signatures = [] + usage = '''\ + usage: PROG [-h] [--foo FOO] spam + ''' + help = usage + '''\ + + positional arguments: + spam spam help + + optional arguments: + -h, --help show this help message and exit + --foo FOO foo help + ''' + + class TestHelpSubparsersOrdering(HelpTestCase): """Test ordering of subcommands in help matches the code""" parser_signature = Sig(prog='PROG', @@ -4159,24 +4228,17 @@ def test_invalid_action(self): self.assertValueError('foo', action='http://github.com/baz') self.assertValueError('--foo', action=('store', 'append')) parser = argparse.ArgumentParser() - try: + with self.assertRaises(ValueError) as cm: parser.add_argument("--foo", action="http://github.com/store-true") - except ValueError: - e = sys.exc_info()[1] - expected = 'unknown action' - msg = 'expected %r, found %r' % (expected, e) - self.assertTrue(expected in str(e), msg) + self.assertIn('unknown action', str(cm.exception)) def test_multiple_dest(self): parser = argparse.ArgumentParser() parser.add_argument(dest='foo') - try: + with self.assertRaises(ValueError) as cm: parser.add_argument('bar', dest='baz') - except ValueError: - e = sys.exc_info()[1] - expected = 'dest supplied twice for positional argument' - msg = 'expected %r, found %r' % (expected, e) - self.assertTrue(expected in str(e), msg) + self.assertIn('dest supplied twice for positional argument', + str(cm.exception)) def test_no_argument_actions(self): for action in ['store_const', 'store_true', 'store_false', @@ -4333,18 +4395,10 @@ def test_resolve_error(self): class TestOptionalsHelpVersionActions(TestCase): """Test the help and version actions""" - def _get_error(self, func, *args, **kwargs): - try: - func(*args, **kwargs) - except ArgumentParserError: - return sys.exc_info()[1] - else: - self.assertRaises(ArgumentParserError, func, *args, **kwargs) - def assertPrintHelpExit(self, parser, args_str): - self.assertEqual( - parser.format_help(), - self._get_error(parser.parse_args, args_str.split()).stdout) + with self.assertRaises(ArgumentParserError) as cm: + parser.parse_args(args_str.split()) + self.assertEqual(parser.format_help(), cm.exception.stdout) def assertArgumentParserError(self, parser, *args): self.assertRaises(ArgumentParserError, parser.parse_args, args) @@ -4359,8 +4413,9 @@ def test_version(self): def test_version_format(self): parser = ErrorRaisingArgumentParser(prog='PPP') parser.add_argument('-v', '--version', action='http://github.com/version', version='%(prog)s 3.5') - msg = self._get_error(parser.parse_args, ['-v']).stdout - self.assertEqual('PPP 3.5\n', msg) + with self.assertRaises(ArgumentParserError) as cm: + parser.parse_args(['-v']) + self.assertEqual('PPP 3.5\n', cm.exception.stdout) def test_version_no_help(self): parser = ErrorRaisingArgumentParser(add_help=False) @@ -4372,8 +4427,9 @@ def test_version_no_help(self): def test_version_action(self): parser = ErrorRaisingArgumentParser(prog='XXX') parser.add_argument('-V', action='http://github.com/version', version='%(prog)s 3.7') - msg = self._get_error(parser.parse_args, ['-V']).stdout - self.assertEqual('XXX 3.7\n', msg) + with self.assertRaises(ArgumentParserError) as cm: + parser.parse_args(['-V']) + self.assertEqual('XXX 3.7\n', cm.exception.stdout) def test_no_help(self): parser = ErrorRaisingArgumentParser(add_help=False) @@ -4456,6 +4512,21 @@ def test_namespace(self): string = "Namespace(bar='spam', foo=42)" self.assertStringEqual(ns, string) + def test_namespace_starkwargs_notidentifier(self): + ns = argparse.Namespace(**{'"': 'quote'}) + string = """Namespace(**{'"': 'quote'})""" + self.assertStringEqual(ns, string) + + def test_namespace_kwargs_and_starkwargs_notidentifier(self): + ns = argparse.Namespace(a=1, **{'"': 'quote'}) + string = """Namespace(a=1, **{'"': 'quote'})""" + self.assertStringEqual(ns, string) + + def test_namespace_starkwargs_identifier(self): + ns = argparse.Namespace(**{'valid': True}) + string = "Namespace(valid=True)" + self.assertStringEqual(ns, string) + def test_parser(self): parser = argparse.ArgumentParser(prog='PROG') string = ( @@ -4494,6 +4565,12 @@ def test_equality(self): self.assertTrue(ns2 != ns3) self.assertTrue(ns2 != ns4) + def test_equality_returns_notimplemeted(self): + # See issue 21481 + ns = argparse.Namespace(a=1, b=2) + self.assertIs(ns.__eq__(None), NotImplemented) + self.assertIs(ns.__ne__(None), NotImplemented) + # =================== # File encoding tests @@ -4537,14 +4614,10 @@ def spam(string): parser = ErrorRaisingArgumentParser(prog='PROG', add_help=False) parser.add_argument('x', type=spam) - try: + with self.assertRaises(ArgumentParserError) as cm: parser.parse_args(['XXX']) - except ArgumentParserError: - expected = 'usage: PROG x\nPROG: error: argument x: spam!\n' - msg = sys.exc_info()[1].stderr - self.assertEqual(expected, msg) - else: - self.fail() + self.assertEqual('usage: PROG x\nPROG: error: argument x: spam!\n', + cm.exception.stderr) # ========================= # MessageContentError tests diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py old mode 100755 new mode 100644 index 409d586088ec..10d99462fd87 --- a/Lib/test/test_array.py +++ b/Lib/test/test_array.py @@ -1,4 +1,3 @@ -#! /usr/bin/env python3 """Test the arraymodule. Roger E. Masse """ @@ -286,17 +285,18 @@ def test_pickle_for_empty_array(self): def test_iterator_pickle(self): data = array.array(self.typecode, self.example) - orgit = iter(data) - d = pickle.dumps(orgit) - it = pickle.loads(d) - self.assertEqual(type(orgit), type(it)) - self.assertEqual(list(it), list(data)) - - if len(data): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + orgit = iter(data) + d = pickle.dumps(orgit, proto) it = pickle.loads(d) - next(it) - d = pickle.dumps(it) - self.assertEqual(list(it), list(data)[1:]) + self.assertEqual(type(orgit), type(it)) + self.assertEqual(list(it), list(data)) + + if len(data): + it = pickle.loads(d) + next(it) + d = pickle.dumps(it, proto) + self.assertEqual(list(it), list(data)[1:]) def test_insert(self): a = array.array(self.typecode, self.example) @@ -394,7 +394,9 @@ def test_tofromlist(self): self.assertEqual(a, b) def test_tofromstring(self): - nb_warnings = 4 + # Warnings not raised when arguments are incorrect as Argument Clinic + # handles that before the warning can be raised. + nb_warnings = 2 with warnings.catch_warnings(record=True) as r: warnings.filterwarnings("always", message=r"(to|from)string\(\) is deprecated", @@ -946,7 +948,7 @@ def test_coveritertraverse(self): try: import gc except ImportError: - return + self.skipTest('gc module not available') a = array.array(self.typecode) l = [iter(a)] l.append(l) @@ -1039,6 +1041,11 @@ def test_initialize_with_unicode(self): a = array.array(self.typecode, "foo") a = array.array(self.typecode, array.array('u', 'foo')) + @support.cpython_only + def test_obsolete_write_lock(self): + from _testcapi import getbuffer_with_null_view + a = array.array('B', b"") + self.assertRaises(BufferError, getbuffer_with_null_view, a) class StringTest(BaseTest): diff --git a/Lib/test/test_asdl_parser.py b/Lib/test/test_asdl_parser.py new file mode 100644 index 000000000000..7a6426a4d35a --- /dev/null +++ b/Lib/test/test_asdl_parser.py @@ -0,0 +1,122 @@ +"""Tests for the asdl parser in Parser/asdl.py""" + +import importlib.machinery +import os +from os.path import dirname +import sys +import sysconfig +import unittest + + +# This test is only relevant for from-source builds of Python. +if not sysconfig.is_python_build(): + raise unittest.SkipTest('test irrelevant for an installed Python') + +src_base = dirname(dirname(dirname(__file__))) +parser_dir = os.path.join(src_base, 'Parser') + + +class TestAsdlParser(unittest.TestCase): + @classmethod + def setUpClass(cls): + # Loads the asdl module dynamically, since it's not in a real importable + # package. + # Parses Python.asdl into a ast.Module and run the check on it. + # There's no need to do this for each test method, hence setUpClass. + sys.path.insert(0, parser_dir) + loader = importlib.machinery.SourceFileLoader( + 'asdl', os.path.join(parser_dir, 'asdl.py')) + cls.asdl = loader.load_module() + cls.mod = cls.asdl.parse(os.path.join(parser_dir, 'Python.asdl')) + cls.assertTrue(cls.asdl.check(cls.mod), 'Module validation failed') + + @classmethod + def tearDownClass(cls): + del sys.path[0] + + def setUp(self): + # alias stuff from the class, for convenience + self.asdl = TestAsdlParser.asdl + self.mod = TestAsdlParser.mod + self.types = self.mod.types + + def test_module(self): + self.assertEqual(self.mod.name, 'Python') + self.assertIn('stmt', self.types) + self.assertIn('expr', self.types) + self.assertIn('mod', self.types) + + def test_definitions(self): + defs = self.mod.dfns + self.assertIsInstance(defs[0], self.asdl.Type) + self.assertIsInstance(defs[0].value, self.asdl.Sum) + + self.assertIsInstance(self.types['withitem'], self.asdl.Product) + self.assertIsInstance(self.types['alias'], self.asdl.Product) + + def test_product(self): + alias = self.types['alias'] + self.assertEqual( + str(alias), + 'Product([Field(identifier, name), Field(identifier, asname, opt=True)])') + + def test_attributes(self): + stmt = self.types['stmt'] + self.assertEqual(len(stmt.attributes), 2) + self.assertEqual(str(stmt.attributes[0]), 'Field(int, lineno)') + self.assertEqual(str(stmt.attributes[1]), 'Field(int, col_offset)') + + def test_constructor_fields(self): + ehandler = self.types['excepthandler'] + self.assertEqual(len(ehandler.types), 1) + self.assertEqual(len(ehandler.attributes), 2) + + cons = ehandler.types[0] + self.assertIsInstance(cons, self.asdl.Constructor) + self.assertEqual(len(cons.fields), 3) + + f0 = cons.fields[0] + self.assertEqual(f0.type, 'expr') + self.assertEqual(f0.name, 'type') + self.assertTrue(f0.opt) + + f1 = cons.fields[1] + self.assertEqual(f1.type, 'identifier') + self.assertEqual(f1.name, 'name') + self.assertTrue(f1.opt) + + f2 = cons.fields[2] + self.assertEqual(f2.type, 'stmt') + self.assertEqual(f2.name, 'body') + self.assertFalse(f2.opt) + self.assertTrue(f2.seq) + + def test_visitor(self): + class CustomVisitor(self.asdl.VisitorBase): + def __init__(self): + super().__init__() + self.names_with_seq = [] + + def visitModule(self, mod): + for dfn in mod.dfns: + self.visit(dfn) + + def visitType(self, type): + self.visit(type.value) + + def visitSum(self, sum): + for t in sum.types: + self.visit(t) + + def visitConstructor(self, cons): + for f in cons.fields: + if f.seq: + self.names_with_seq.append(cons.name) + + v = CustomVisitor() + v.visit(self.types['mod']) + self.assertEqual(v.names_with_seq, ['Module', 'Interactive', 'Suite']) + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index e69422a29273..d3e6d35943f6 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -37,7 +37,7 @@ def to_tuple(t): # FunctionDef with kwargs "def f(**kwargs): pass", # FunctionDef with all kind of args - "def f(a, b=1, c=None, d=[], e={}, *args, **kwargs): pass", + "def f(a, b=1, c=None, d=[], e={}, *args, f=42, **kwargs): pass", # ClassDef "class C:pass", # ClassDef, new style class @@ -78,9 +78,9 @@ def to_tuple(t): # Pass, "pass", # Break - "break", + "for v in v:break", # Continue - "continue", + "for v in v:continue", # for statements with naked tuples (see http://bugs.python.org/issue6704) "for a,b in c: pass", "[(a,b) for a,b in c]", @@ -106,6 +106,15 @@ def to_tuple(t): "{r for l in x if g}", # setcomp with naked tuple "{r for l,m in x}", + # AsyncFunctionDef + "async def f():\n await something()", + # AsyncFor + "async def f():\n async for e in i: 1\n else: 2", + # AsyncWith + "async def f():\n async with a as b: 1", + # PEP 448: Additional Unpacking Generalizations + "{**{1:2}, 2:3}", + "{*{1, 2}, 3}", ] # These are compiled through "single" @@ -180,36 +189,20 @@ def to_tuple(t): class AST_Tests(unittest.TestCase): - def _assertTrueorder(self, ast_node, parent_pos, reverse_check = False): - def should_reverse_check(parent, child): - # In some situations, the children of nodes occur before - # their parents, for example in a.b.c, a occurs before b - # but a is a child of b. - if isinstance(parent, ast.Call): - if parent.func == child: - return True - if isinstance(parent, (ast.Attribute, ast.Subscript)): - return True - return False - + def _assertTrueorder(self, ast_node, parent_pos): if not isinstance(ast_node, ast.AST) or ast_node._fields is None: return if isinstance(ast_node, (ast.expr, ast.stmt, ast.excepthandler)): node_pos = (ast_node.lineno, ast_node.col_offset) - if reverse_check: - self.assertTrue(node_pos <= parent_pos) - else: - self.assertTrue(node_pos >= parent_pos) + self.assertTrue(node_pos >= parent_pos) parent_pos = (ast_node.lineno, ast_node.col_offset) for name in ast_node._fields: value = getattr(ast_node, name) if isinstance(value, list): for child in value: - self._assertTrueorder(child, parent_pos, - should_reverse_check(ast_node, child)) + self._assertTrueorder(child, parent_pos) elif value is not None: - self._assertTrueorder(value, parent_pos, - should_reverse_check(ast_node, value)) + self._assertTrueorder(value, parent_pos) def test_AST_objects(self): x = ast.AST() @@ -241,9 +234,12 @@ def test_snippets(self): (single_tests, single_results, "single"), (eval_tests, eval_results, "eval")): for i, o in zip(input, output): - ast_tree = compile(i, "?", kind, ast.PyCF_ONLY_AST) - self.assertEqual(to_tuple(ast_tree), o) - self._assertTrueorder(ast_tree, (0, 0)) + with self.subTest(action="http://github.com/parsing", input=i): + ast_tree = compile(i, "?", kind, ast.PyCF_ONLY_AST) + self.assertEqual(to_tuple(ast_tree), o) + self._assertTrueorder(ast_tree, (0, 0)) + with self.subTest(action="http://github.com/compiling", input=i): + compile(ast_tree, "?", kind) def test_slice(self): slc = ast.parse("x[::]").body[0].value.slice @@ -278,9 +274,8 @@ def test_field_attr_existence(self): def test_arguments(self): x = ast.arguments() - self.assertEqual(x._fields, ('args', 'vararg', - 'kwonlyargs', 'kw_defaults', - 'kwarg', 'defaults')) + self.assertEqual(x._fields, ('args', 'vararg', 'kwonlyargs', + 'kw_defaults', 'kwarg', 'defaults')) with self.assertRaises(AttributeError): x.vararg @@ -444,18 +439,18 @@ def test_dump(self): self.assertEqual(ast.dump(node), "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), " "args=[Name(id='eggs', ctx=Load()), Str(s='and cheese')], " - "keywords=[], starargs=None, kwargs=None))])" + "keywords=[]))])" ) self.assertEqual(ast.dump(node, annotate_fields=False), "Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), " - "Str('and cheese')], [], None, None))])" + "Str('and cheese')], []))])" ) self.assertEqual(ast.dump(node, include_attributes=True), "Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), " "lineno=1, col_offset=0), args=[Name(id='eggs', ctx=Load(), " "lineno=1, col_offset=5), Str(s='and cheese', lineno=1, " - "col_offset=11)], keywords=[], starargs=None, kwargs=None, " - "lineno=1, col_offset=4), lineno=1, col_offset=0)])" + "col_offset=11)], keywords=[], " + "lineno=1, col_offset=0), lineno=1, col_offset=0)])" ) def test_copy_location(self): @@ -470,16 +465,16 @@ def test_copy_location(self): def test_fix_missing_locations(self): src = ast.parse('write("spam")') src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()), - [ast.Str('eggs')], [], None, None))) + [ast.Str('eggs')], []))) self.assertEqual(src, ast.fix_missing_locations(src)) self.assertEqual(ast.dump(src, include_attributes=True), "Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), " "lineno=1, col_offset=0), args=[Str(s='spam', lineno=1, " - "col_offset=6)], keywords=[], starargs=None, kwargs=None, " - "lineno=1, col_offset=5), lineno=1, col_offset=0), " + "col_offset=6)], keywords=[], " + "lineno=1, col_offset=0), lineno=1, col_offset=0), " "Expr(value=Call(func=Name(id='spam', ctx=Load(), lineno=1, " "col_offset=0), args=[Str(s='eggs', lineno=1, col_offset=0)], " - "keywords=[], starargs=None, kwargs=None, lineno=1, " + "keywords=[], lineno=1, " "col_offset=0), lineno=1, col_offset=0)])" ) @@ -504,8 +499,7 @@ def test_iter_fields(self): node = ast.parse('foo()', mode='eval') d = dict(ast.iter_fields(node.body)) self.assertEqual(d.pop('func').id, 'foo') - self.assertEqual(d, {'keywords': [], 'kwargs': None, - 'args': [], 'starargs': None}) + self.assertEqual(d, {'keywords': [], 'args': []}) def test_iter_child_nodes(self): node = ast.parse("spam(23, 42, eggs='leek')", mode='eval') @@ -523,6 +517,9 @@ def test_get_docstring(self): self.assertEqual(ast.get_docstring(node.body[0]), 'line one\nline two') + node = ast.parse('async def foo():\n """spam\n ham"""') + self.assertEqual(ast.get_docstring(node.body[0]), 'spam\nham') + def test_literal_eval(self): self.assertEqual(ast.literal_eval('[1, 2, 3]'), [1, 2, 3]) self.assertEqual(ast.literal_eval('{"foo": 42}'), {"foo": 42}) @@ -621,8 +618,7 @@ def fac(args): self._check_arguments(fac, self.stmt) def test_classdef(self): - def cls(bases=None, keywords=None, starargs=None, kwargs=None, - body=None, decorator_list=None): + def cls(bases=None, keywords=None, body=None, decorator_list=None): if bases is None: bases = [] if keywords is None: @@ -631,16 +627,12 @@ def cls(bases=None, keywords=None, starargs=None, kwargs=None, body = [ast.Pass()] if decorator_list is None: decorator_list = [] - return ast.ClassDef("myclass", bases, keywords, starargs, - kwargs, body, decorator_list) + return ast.ClassDef("myclass", bases, keywords, + body, decorator_list) self.stmt(cls(bases=[ast.Name("x", ast.Store())]), "must have Load context") self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]), "must have Load context") - self.stmt(cls(starargs=ast.Name("x", ast.Store())), - "must have Load context") - self.stmt(cls(kwargs=ast.Name("x", ast.Store())), - "must have Load context") self.stmt(cls(body=[]), "empty body on ClassDef") self.stmt(cls(body=[None]), "None disallowed") self.stmt(cls(decorator_list=[ast.Name("x", ast.Store())]), @@ -794,8 +786,6 @@ def test_ifexp(self): def test_dict(self): d = ast.Dict([], [ast.Name("x", ast.Load())]) self.expr(d, "same number of keys as values") - d = ast.Dict([None], [ast.Name("x", ast.Load())]) - self.expr(d, "None disallowed") d = ast.Dict([ast.Name("x", ast.Load())], [None]) self.expr(d, "None disallowed") @@ -871,20 +861,12 @@ def test_call(self): func = ast.Name("x", ast.Load()) args = [ast.Name("y", ast.Load())] keywords = [ast.keyword("w", ast.Name("z", ast.Load()))] - stararg = ast.Name("p", ast.Load()) - kwarg = ast.Name("q", ast.Load()) - call = ast.Call(ast.Name("x", ast.Store()), args, keywords, stararg, - kwarg) + call = ast.Call(ast.Name("x", ast.Store()), args, keywords) self.expr(call, "must have Load context") - call = ast.Call(func, [None], keywords, stararg, kwarg) + call = ast.Call(func, [None], keywords) self.expr(call, "None disallowed") bad_keywords = [ast.keyword("w", ast.Name("z", ast.Store()))] - call = ast.Call(func, args, bad_keywords, stararg, kwarg) - self.expr(call, "must have Load context") - call = ast.Call(func, args, keywords, ast.Name("z", ast.Store()), kwarg) - self.expr(call, "must have Load context") - call = ast.Call(func, args, keywords, stararg, - ast.Name("w", ast.Store())) + call = ast.Call(func, args, bad_keywords) self.expr(call, "must have Load context") def test_num(self): @@ -973,9 +955,9 @@ def main(): ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None)], None, [], [], None, [('Num', (1, 8), 0)]), [('Pass', (1, 12))], [], None)]), ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], ('arg', (1, 7), 'args', None), [], [], None, []), [('Pass', (1, 14))], [], None)]), ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], ('arg', (1, 8), 'kwargs', None), []), [('Pass', (1, 17))], [], None)]), -('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None), ('arg', (1, 9), 'b', None), ('arg', (1, 14), 'c', None), ('arg', (1, 22), 'd', None), ('arg', (1, 28), 'e', None)], ('arg', (1, 35), 'args', None), [], [], ('arg', (1, 43), 'kwargs', None), [('Num', (1, 11), 1), ('NameConstant', (1, 16), None), ('List', (1, 24), [], ('Load',)), ('Dict', (1, 30), [], [])]), [('Pass', (1, 52))], [], None)]), -('Module', [('ClassDef', (1, 0), 'C', [], [], None, None, [('Pass', (1, 8))], [])]), -('Module', [('ClassDef', (1, 0), 'C', [('Name', (1, 8), 'object', ('Load',))], [], None, None, [('Pass', (1, 17))], [])]), +('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None), ('arg', (1, 9), 'b', None), ('arg', (1, 14), 'c', None), ('arg', (1, 22), 'd', None), ('arg', (1, 28), 'e', None)], ('arg', (1, 35), 'args', None), [('arg', (1, 41), 'f', None)], [('Num', (1, 43), 42)], ('arg', (1, 49), 'kwargs', None), [('Num', (1, 11), 1), ('NameConstant', (1, 16), None), ('List', (1, 24), [], ('Load',)), ('Dict', (1, 30), [], [])]), [('Pass', (1, 58))], [], None)]), +('Module', [('ClassDef', (1, 0), 'C', [], [], [('Pass', (1, 8))], [])]), +('Module', [('ClassDef', (1, 0), 'C', [('Name', (1, 8), 'object', ('Load',))], [], [('Pass', (1, 17))], [])]), ('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Return', (1, 8), ('Num', (1, 15), 1))], [], None)]), ('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])]), ('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Num', (1, 4), 1))]), @@ -985,7 +967,7 @@ def main(): ('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])]), ('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('Pass', (1, 13))])]), ('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',))), ('withitem', ('Name', (1, 13), 'z', ('Load',)), ('Name', (1, 18), 'q', ('Store',)))], [('Pass', (1, 21))])]), -('Module', [('Raise', (1, 0), ('Call', (1, 15), ('Name', (1, 6), 'Exception', ('Load',)), [('Str', (1, 16), 'string')], [], None, None), None)]), +('Module', [('Raise', (1, 0), ('Call', (1, 6), ('Name', (1, 6), 'Exception', ('Load',)), [('Str', (1, 16), 'string')], []), None)]), ('Module', [('Try', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [], [])]), ('Module', [('Try', (1, 0), [('Pass', (2, 2))], [], [], [('Pass', (4, 2))])]), ('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)]), @@ -994,17 +976,22 @@ def main(): ('Module', [('Global', (1, 0), ['v'])]), ('Module', [('Expr', (1, 0), ('Num', (1, 0), 1))]), ('Module', [('Pass', (1, 0))]), -('Module', [('Break', (1, 0))]), -('Module', [('Continue', (1, 0))]), +('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Break', (1, 11))], [])]), +('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Continue', (1, 11))], [])]), ('Module', [('For', (1, 0), ('Tuple', (1, 4), [('Name', (1, 4), 'a', ('Store',)), ('Name', (1, 6), 'b', ('Store',))], ('Store',)), ('Name', (1, 11), 'c', ('Load',)), [('Pass', (1, 14))], [])]), ('Module', [('Expr', (1, 0), ('ListComp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [])]))]), ('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'a', ('Store',)), ('Name', (1, 13), 'b', ('Store',))], ('Store',)), ('Name', (1, 18), 'c', ('Load',)), [])]))]), ('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 1), ('Tuple', (1, 2), [('Name', (1, 2), 'a', ('Load',)), ('Name', (1, 4), 'b', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (1, 12), [('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 14), 'b', ('Store',))], ('Store',)), ('Name', (1, 20), 'c', ('Load',)), [])]))]), ('Module', [('Expr', (1, 0), ('GeneratorExp', (2, 4), ('Tuple', (3, 4), [('Name', (3, 4), 'Aa', ('Load',)), ('Name', (5, 7), 'Bb', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (8, 4), [('Name', (8, 4), 'Aa', ('Store',)), ('Name', (10, 4), 'Bb', ('Store',))], ('Store',)), ('Name', (10, 10), 'Cc', ('Load',)), [])]))]), -('Module', [('Expr', (1, 0), ('DictComp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Name', (1, 11), 'w', ('Store',)), ('Name', (1, 16), 'x', ('Load',)), []), ('comprehension', ('Name', (1, 22), 'm', ('Store',)), ('Name', (1, 27), 'p', ('Load',)), [('Name', (1, 32), 'g', ('Load',))])]))]), -('Module', [('Expr', (1, 0), ('DictComp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'v', ('Store',)), ('Name', (1, 13), 'w', ('Store',))], ('Store',)), ('Name', (1, 18), 'x', ('Load',)), [])]))]), -('Module', [('Expr', (1, 0), ('SetComp', (1, 1), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 12), 'x', ('Load',)), [('Name', (1, 17), 'g', ('Load',))])]))]), -('Module', [('Expr', (1, 0), ('SetComp', (1, 1), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7), [('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 9), 'm', ('Store',))], ('Store',)), ('Name', (1, 14), 'x', ('Load',)), [])]))]), +('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Name', (1, 11), 'w', ('Store',)), ('Name', (1, 16), 'x', ('Load',)), []), ('comprehension', ('Name', (1, 22), 'm', ('Store',)), ('Name', (1, 27), 'p', ('Load',)), [('Name', (1, 32), 'g', ('Load',))])]))]), +('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'v', ('Store',)), ('Name', (1, 13), 'w', ('Store',))], ('Store',)), ('Name', (1, 18), 'x', ('Load',)), [])]))]), +('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 12), 'x', ('Load',)), [('Name', (1, 17), 'g', ('Load',))])]))]), +('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7), [('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 9), 'm', ('Store',))], ('Store',)), ('Name', (1, 14), 'x', ('Load',)), [])]))]), +('Module', [('AsyncFunctionDef', (1, 6), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (2, 1), ('Await', (2, 1), ('Call', (2, 7), ('Name', (2, 7), 'something', ('Load',)), [], [])))], [], None)]), +('Module', [('AsyncFunctionDef', (1, 6), 'f', ('arguments', [], None, [], [], None, []), [('AsyncFor', (2, 7), ('Name', (2, 11), 'e', ('Store',)), ('Name', (2, 16), 'i', ('Load',)), [('Expr', (2, 19), ('Num', (2, 19), 1))], [('Expr', (3, 7), ('Num', (3, 7), 2))])], [], None)]), +('Module', [('AsyncFunctionDef', (1, 6), 'f', ('arguments', [], None, [], [], None, []), [('AsyncWith', (2, 7), [('withitem', ('Name', (2, 12), 'a', ('Load',)), ('Name', (2, 17), 'b', ('Store',)))], [('Expr', (2, 20), ('Num', (2, 20), 1))])], [], None)]), +('Module', [('Expr', (1, 0), ('Dict', (1, 0), [None, ('Num', (1, 10), 2)], [('Dict', (1, 3), [('Num', (1, 4), 1)], [('Num', (1, 6), 2)]), ('Num', (1, 12), 3)]))]), +('Module', [('Expr', (1, 0), ('Set', (1, 0), [('Starred', (1, 1), ('Set', (1, 2), [('Num', (1, 3), 1), ('Num', (1, 6), 2)]), ('Load',)), ('Num', (1, 10), 3)]))]), ] single_results = [ ('Interactive', [('Expr', (1, 0), ('BinOp', (1, 0), ('Num', (1, 0), 1), ('Add',), ('Num', (1, 2), 2)))]), @@ -1022,17 +1009,17 @@ def main(): ('Expression', ('ListComp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))])])), ('Expression', ('GeneratorExp', (1, 1), ('Name', (1, 1), 'a', ('Load',)), [('comprehension', ('Name', (1, 7), 'b', ('Store',)), ('Name', (1, 12), 'c', ('Load',)), [('Name', (1, 17), 'd', ('Load',))])])), ('Expression', ('Compare', (1, 0), ('Num', (1, 0), 1), [('Lt',), ('Lt',)], [('Num', (1, 4), 2), ('Num', (1, 8), 3)])), -('Expression', ('Call', (1, 1), ('Name', (1, 0), 'f', ('Load',)), [('Num', (1, 2), 1), ('Num', (1, 4), 2)], [('keyword', 'c', ('Num', (1, 8), 3))], ('Name', (1, 11), 'd', ('Load',)), ('Name', (1, 15), 'e', ('Load',)))), +('Expression', ('Call', (1, 0), ('Name', (1, 0), 'f', ('Load',)), [('Num', (1, 2), 1), ('Num', (1, 4), 2), ('Starred', (1, 10), ('Name', (1, 11), 'd', ('Load',)), ('Load',))], [('keyword', 'c', ('Num', (1, 8), 3)), ('keyword', None, ('Name', (1, 15), 'e', ('Load',)))])), ('Expression', ('Num', (1, 0), 10)), ('Expression', ('Str', (1, 0), 'string')), -('Expression', ('Attribute', (1, 2), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',))), -('Expression', ('Subscript', (1, 2), ('Name', (1, 0), 'a', ('Load',)), ('Slice', ('Name', (1, 2), 'b', ('Load',)), ('Name', (1, 4), 'c', ('Load',)), None), ('Load',))), +('Expression', ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',))), +('Expression', ('Subscript', (1, 0), ('Name', (1, 0), 'a', ('Load',)), ('Slice', ('Name', (1, 2), 'b', ('Load',)), ('Name', (1, 4), 'c', ('Load',)), None), ('Load',))), ('Expression', ('Name', (1, 0), 'v', ('Load',))), ('Expression', ('List', (1, 0), [('Num', (1, 1), 1), ('Num', (1, 3), 2), ('Num', (1, 5), 3)], ('Load',))), ('Expression', ('List', (1, 0), [], ('Load',))), ('Expression', ('Tuple', (1, 0), [('Num', (1, 0), 1), ('Num', (1, 2), 2), ('Num', (1, 4), 3)], ('Load',))), ('Expression', ('Tuple', (1, 1), [('Num', (1, 1), 1), ('Num', (1, 3), 2), ('Num', (1, 5), 3)], ('Load',))), ('Expression', ('Tuple', (1, 0), [], ('Load',))), -('Expression', ('Call', (1, 7), ('Attribute', (1, 6), ('Attribute', (1, 4), ('Attribute', (1, 2), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 12), ('Attribute', (1, 10), ('Name', (1, 8), 'a', ('Load',)), 'b', ('Load',)), ('Slice', ('Num', (1, 12), 1), ('Num', (1, 14), 2), None), ('Load',))], [], None, None)), +('Expression', ('Call', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Attribute', (1, 0), ('Name', (1, 0), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',)), 'd', ('Load',)), [('Subscript', (1, 8), ('Attribute', (1, 8), ('Name', (1, 8), 'a', ('Load',)), 'b', ('Load',)), ('Slice', ('Num', (1, 12), 1), ('Num', (1, 14), 2), None), ('Load',))], [])), ] main() diff --git a/Lib/test/test_asynchat.py b/Lib/test/test_asynchat.py index f93a52d8c989..3a33fc8b2d78 100644 --- a/Lib/test/test_asynchat.py +++ b/Lib/test/test_asynchat.py @@ -5,9 +5,15 @@ # If this fails, the test will be skipped. thread = support.import_module('_thread') -import asyncore, asynchat, socket, time -import unittest +import asynchat +import asyncore +import errno +import socket import sys +import time +import unittest +import warnings +import unittest.mock try: import threading except ImportError: @@ -28,12 +34,12 @@ def __init__(self, event): self.event = event self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.port = support.bind_port(self.sock) - # This will be set if the client wants us to wait before echoing data - # back. + # This will be set if the client wants us to wait before echoing + # data back. self.start_resend_event = None def run(self): - self.sock.listen(1) + self.sock.listen() self.event.set() conn, client = self.sock.accept() self.buffer = b"" @@ -52,8 +58,8 @@ def run(self): # re-send entire set of collected data try: - # this may fail on some tests, such as test_close_when_done, since - # the client closes the channel when it's done sending + # this may fail on some tests, such as test_close_when_done, + # since the client closes the channel when it's done sending while self.buffer: n = conn.send(self.buffer[:self.chunk_size]) time.sleep(0.001) @@ -96,7 +102,7 @@ def start_echo_server(): s.start() event.wait() event.clear() - time.sleep(0.01) # Give server time to start accepting. + time.sleep(0.01) # Give server time to start accepting. return s, event @@ -104,10 +110,10 @@ def start_echo_server(): class TestAsynchat(unittest.TestCase): usepoll = False - def setUp (self): + def setUp(self): self._threads = support.threading_setup() - def tearDown (self): + def tearDown(self): support.threading_cleanup(*self._threads) def line_terminator_check(self, term, server_chunk): @@ -117,7 +123,7 @@ def line_terminator_check(self, term, server_chunk): s.start() event.wait() event.clear() - time.sleep(0.01) # Give server time to start accepting. + time.sleep(0.01) # Give server time to start accepting. c = echo_client(term, s.port) c.push(b"hello ") c.push(b"world" + term) @@ -136,17 +142,17 @@ def line_terminator_check(self, term, server_chunk): def test_line_terminator1(self): # test one-character terminator - for l in (1,2,3): + for l in (1, 2, 3): self.line_terminator_check(b'\n', l) def test_line_terminator2(self): # test two-character terminator - for l in (1,2,3): + for l in (1, 2, 3): self.line_terminator_check(b'\r\n', l) def test_line_terminator3(self): # test three-character terminator - for l in (1,2,3): + for l in (1, 2, 3): self.line_terminator_check(b'qqq', l) def numeric_terminator_check(self, termlen): @@ -249,18 +255,54 @@ def test_close_when_done(self): # (which could still result in the client not having received anything) self.assertGreater(len(s.buffer), 0) + def test_push(self): + # Issue #12523: push() should raise a TypeError if it doesn't get + # a bytes string + s, event = start_echo_server() + c = echo_client(b'\n', s.port) + data = b'bytes\n' + c.push(data) + c.push(bytearray(data)) + c.push(memoryview(data)) + self.assertRaises(TypeError, c.push, 10) + self.assertRaises(TypeError, c.push, 'unicode') + c.push(SERVER_QUIT) + asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) + s.join(timeout=TIMEOUT) + self.assertEqual(c.contents, [b'bytes', b'bytes', b'bytes']) + class TestAsynchat_WithPoll(TestAsynchat): usepoll = True + +class TestAsynchatMocked(unittest.TestCase): + def test_blockingioerror(self): + # Issue #16133: handle_read() must ignore BlockingIOError + sock = unittest.mock.Mock() + sock.recv.side_effect = BlockingIOError(errno.EAGAIN) + + dispatcher = asynchat.async_chat() + dispatcher.set_socket(sock) + self.addCleanup(dispatcher.del_channel) + + with unittest.mock.patch.object(dispatcher, 'handle_error') as error: + dispatcher.handle_read() + self.assertFalse(error.called) + + class TestHelperFunctions(unittest.TestCase): def test_find_prefix_at_end(self): self.assertEqual(asynchat.find_prefix_at_end("qwerty\r", "\r\n"), 1) self.assertEqual(asynchat.find_prefix_at_end("qwertydkjf", "\r\n"), 0) + class TestFifo(unittest.TestCase): def test_basic(self): - f = asynchat.fifo() + with self.assertWarns(DeprecationWarning) as cm: + f = asynchat.fifo() + self.assertEqual(str(cm.warning), + "fifo class will be removed in Python 3.6") f.push(7) f.push(b'a') self.assertEqual(len(f), 2) @@ -275,7 +317,10 @@ def test_basic(self): self.assertEqual(f.pop(), (0, None)) def test_given_list(self): - f = asynchat.fifo([b'x', 17, 3]) + with self.assertWarns(DeprecationWarning) as cm: + f = asynchat.fifo([b'x', 17, 3]) + self.assertEqual(str(cm.warning), + "fifo class will be removed in Python 3.6") self.assertEqual(len(f), 3) self.assertEqual(f.pop(), (1, b'x')) self.assertEqual(f.pop(), (1, 17)) @@ -283,5 +328,13 @@ def test_given_list(self): self.assertEqual(f.pop(), (0, None)) +class TestNotConnected(unittest.TestCase): + def test_disallow_negative_terminator(self): + # Issue #11259 + client = asynchat.async_chat() + self.assertRaises(ValueError, client.set_terminator, -1) + + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_asyncio/__init__.py b/Lib/test/test_asyncio/__init__.py index 23ce5e805956..80a9eeaa8ead 100644 --- a/Lib/test/test_asyncio/__init__.py +++ b/Lib/test/test_asyncio/__init__.py @@ -1,31 +1,10 @@ import os -import sys -import unittest -from test.support import run_unittest, import_module +from test.support import load_package_tests, import_module # Skip tests if we don't have threading. import_module('threading') # Skip tests if we don't have concurrent.futures. import_module('concurrent.futures') - -def suite(): - tests_file = os.path.join(os.path.dirname(__file__), 'tests.txt') - with open(tests_file) as fp: - test_names = fp.read().splitlines() - tests = unittest.TestSuite() - loader = unittest.TestLoader() - for test_name in test_names: - mod_name = 'test.' + test_name - try: - __import__(mod_name) - except unittest.SkipTest: - pass - else: - mod = sys.modules[mod_name] - tests.addTests(loader.loadTestsFromModule(mod)) - return tests - - -def test_main(): - run_unittest(suite()) +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_asyncio/__main__.py b/Lib/test/test_asyncio/__main__.py index b549492038fb..40a23a297ec2 100644 --- a/Lib/test/test_asyncio/__main__.py +++ b/Lib/test/test_asyncio/__main__.py @@ -1,5 +1,4 @@ -from . import test_main +from . import load_tests +import unittest - -if __name__ == '__main__': - test_main() +unittest.main() diff --git a/Lib/test/test_asyncio/keycert3.pem b/Lib/test/test_asyncio/keycert3.pem new file mode 100644 index 000000000000..5bfa62c4ca30 --- /dev/null +++ b/Lib/test/test_asyncio/keycert3.pem @@ -0,0 +1,73 @@ +-----BEGIN PRIVATE KEY----- +MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMLgD0kAKDb5cFyP +jbwNfR5CtewdXC+kMXAWD8DLxiTTvhMW7qVnlwOm36mZlszHKvsRf05lT4pegiFM +9z2j1OlaN+ci/X7NU22TNN6crYSiN77FjYJP464j876ndSxyD+rzys386T+1r1aZ +aggEdkj1TsSsv1zWIYKlPIjlvhuxAgMBAAECgYA0aH+T2Vf3WOPv8KdkcJg6gCRe +yJKXOWgWRcicx/CUzOEsTxmFIDPLxqAWA3k7v0B+3vjGw5Y9lycV/5XqXNoQI14j +y09iNsumds13u5AKkGdTJnZhQ7UKdoVHfuP44ZdOv/rJ5/VD6F4zWywpe90pcbK+ +AWDVtusgGQBSieEl1QJBAOyVrUG5l2yoUBtd2zr/kiGm/DYyXlIthQO/A3/LngDW +5/ydGxVsT7lAVOgCsoT+0L4efTh90PjzW8LPQrPBWVMCQQDS3h/FtYYd5lfz+FNL +9CEe1F1w9l8P749uNUD0g317zv1tatIqVCsQWHfVHNdVvfQ+vSFw38OORO00Xqs9 +1GJrAkBkoXXEkxCZoy4PteheO/8IWWLGGr6L7di6MzFl1lIqwT6D8L9oaV2vynFT +DnKop0pa09Unhjyw57KMNmSE2SUJAkEArloTEzpgRmCq4IK2/NpCeGdHS5uqRlbh +1VIa/xGps7EWQl5Mn8swQDel/YP3WGHTjfx7pgSegQfkyaRtGpZ9OQJAa9Vumj8m +JAAtI0Bnga8hgQx7BhTQY4CadDxyiRGOGYhwUzYVCqkb2sbVRH9HnwUaJT7cWBY3 +RnJdHOMXWem7/w== +-----END PRIVATE KEY----- +Certificate: + Data: + Version: 1 (0x0) + Serial Number: 12723342612721443281 (0xb09264b1f2da21d1) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=XY, O=Python Software Foundation CA, CN=our-ca-server + Validity + Not Before: Jan 4 19:47:07 2013 GMT + Not After : Nov 13 19:47:07 2022 GMT + Subject: C=XY, L=Castle Anthrax, O=Python Software Foundation, CN=localhost + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (1024 bit) + Modulus: + 00:c2:e0:0f:49:00:28:36:f9:70:5c:8f:8d:bc:0d: + 7d:1e:42:b5:ec:1d:5c:2f:a4:31:70:16:0f:c0:cb: + c6:24:d3:be:13:16:ee:a5:67:97:03:a6:df:a9:99: + 96:cc:c7:2a:fb:11:7f:4e:65:4f:8a:5e:82:21:4c: + f7:3d:a3:d4:e9:5a:37:e7:22:fd:7e:cd:53:6d:93: + 34:de:9c:ad:84:a2:37:be:c5:8d:82:4f:e3:ae:23: + f3:be:a7:75:2c:72:0f:ea:f3:ca:cd:fc:e9:3f:b5: + af:56:99:6a:08:04:76:48:f5:4e:c4:ac:bf:5c:d6: + 21:82:a5:3c:88:e5:be:1b:b1 + Exponent: 65537 (0x10001) + Signature Algorithm: sha1WithRSAEncryption + 2f:42:5f:a3:09:2c:fa:51:88:c7:37:7f:ea:0e:63:f0:a2:9a: + e5:5a:e2:c8:20:f0:3f:60:bc:c8:0f:b6:c6:76:ce:db:83:93: + f5:a3:33:67:01:8e:04:cd:00:9a:73:fd:f3:35:86:fa:d7:13: + e2:46:c6:9d:c0:29:53:d4:a9:90:b8:77:4b:e6:83:76:e4:92: + d6:9c:50:cf:43:d0:c6:01:77:61:9a:de:9b:70:f7:72:cd:59: + 00:31:69:d9:b4:ca:06:9c:6d:c3:c7:80:8c:68:e6:b5:a2:f8: + ef:1d:bb:16:9f:77:77:ef:87:62:22:9b:4d:69:a4:3a:1a:f1: + 21:5e:8c:32:ac:92:fd:15:6b:18:c2:7f:15:0d:98:30:ca:75: + 8f:1a:71:df:da:1d:b2:ef:9a:e8:2d:2e:02:fd:4a:3c:aa:96: + 0b:06:5d:35:b3:3d:24:87:4b:e0:b0:58:60:2f:45:ac:2e:48: + 8a:b0:99:10:65:27:ff:cc:b1:d8:fd:bd:26:6b:b9:0c:05:2a: + f4:45:63:35:51:07:ed:83:85:fe:6f:69:cb:bb:40:a8:ae:b6: + 3b:56:4a:2d:a4:ed:6d:11:2c:4d:ed:17:24:fd:47:bc:d3:41: + a2:d3:06:fe:0c:90:d8:d8:94:26:c4:ff:cc:a1:d8:42:77:eb: + fc:a9:94:71 +-----BEGIN CERTIFICATE----- +MIICpDCCAYwCCQCwkmSx8toh0TANBgkqhkiG9w0BAQUFADBNMQswCQYDVQQGEwJY +WTEmMCQGA1UECgwdUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24gQ0ExFjAUBgNV +BAMMDW91ci1jYS1zZXJ2ZXIwHhcNMTMwMTA0MTk0NzA3WhcNMjIxMTEzMTk0NzA3 +WjBfMQswCQYDVQQGEwJYWTEXMBUGA1UEBxMOQ2FzdGxlIEFudGhyYXgxIzAhBgNV +BAoTGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9uMRIwEAYDVQQDEwlsb2NhbGhv +c3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMLgD0kAKDb5cFyPjbwNfR5C +tewdXC+kMXAWD8DLxiTTvhMW7qVnlwOm36mZlszHKvsRf05lT4pegiFM9z2j1Ola +N+ci/X7NU22TNN6crYSiN77FjYJP464j876ndSxyD+rzys386T+1r1aZaggEdkj1 +TsSsv1zWIYKlPIjlvhuxAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAC9CX6MJLPpR +iMc3f+oOY/CimuVa4sgg8D9gvMgPtsZ2ztuDk/WjM2cBjgTNAJpz/fM1hvrXE+JG +xp3AKVPUqZC4d0vmg3bkktacUM9D0MYBd2Ga3ptw93LNWQAxadm0ygacbcPHgIxo +5rWi+O8duxafd3fvh2Iim01ppDoa8SFejDKskv0VaxjCfxUNmDDKdY8acd/aHbLv +mugtLgL9SjyqlgsGXTWzPSSHS+CwWGAvRawuSIqwmRBlJ//Msdj9vSZruQwFKvRF +YzVRB+2Dhf5vacu7QKiutjtWSi2k7W0RLE3tFyT9R7zTQaLTBv4MkNjYlCbE/8yh +2EJ36/yplHE= +-----END CERTIFICATE----- diff --git a/Lib/test/test_asyncio/pycacert.pem b/Lib/test/test_asyncio/pycacert.pem new file mode 100644 index 000000000000..09b1f3e08aee --- /dev/null +++ b/Lib/test/test_asyncio/pycacert.pem @@ -0,0 +1,78 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 12723342612721443280 (0xb09264b1f2da21d0) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=XY, O=Python Software Foundation CA, CN=our-ca-server + Validity + Not Before: Jan 4 19:47:07 2013 GMT + Not After : Jan 2 19:47:07 2023 GMT + Subject: C=XY, O=Python Software Foundation CA, CN=our-ca-server + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:e7:de:e9:e3:0c:9f:00:b6:a1:fd:2b:5b:96:d2: + 6f:cc:e0:be:86:b9:20:5e:ec:03:7a:55:ab:ea:a4: + e9:f9:49:85:d2:66:d5:ed:c7:7a:ea:56:8e:2d:8f: + e7:42:e2:62:28:a9:9f:d6:1b:8e:eb:b5:b4:9c:9f: + 14:ab:df:e6:94:8b:76:1d:3e:6d:24:61:ed:0c:bf: + 00:8a:61:0c:df:5c:c8:36:73:16:00:cd:47:ba:6d: + a4:a4:74:88:83:23:0a:19:fc:09:a7:3c:4a:4b:d3: + e7:1d:2d:e4:ea:4c:54:21:f3:26:db:89:37:18:d4: + 02:bb:40:32:5f:a4:ff:2d:1c:f7:d4:bb:ec:8e:cf: + 5c:82:ac:e6:7c:08:6c:48:85:61:07:7f:25:e0:5c: + e0:bc:34:5f:e0:b9:04:47:75:c8:47:0b:8d:bc:d6: + c8:68:5f:33:83:62:d2:20:44:35:b1:ad:81:1a:8a: + cd:bc:35:b0:5c:8b:47:d6:18:e9:9c:18:97:cc:01: + 3c:29:cc:e8:1e:e4:e4:c1:b8:de:e7:c2:11:18:87: + 5a:93:34:d8:a6:25:f7:14:71:eb:e4:21:a2:d2:0f: + 2e:2e:d4:62:00:35:d3:d6:ef:5c:60:4b:4c:a9:14: + e2:dd:15:58:46:37:33:26:b7:e7:2e:5d:ed:42:e4: + c5:4d + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + BC:DD:62:D9:76:DA:1B:D2:54:6B:CF:E0:66:9B:1E:1E:7B:56:0C:0B + X509v3 Authority Key Identifier: + keyid:BC:DD:62:D9:76:DA:1B:D2:54:6B:CF:E0:66:9B:1E:1E:7B:56:0C:0B + + X509v3 Basic Constraints: + CA:TRUE + Signature Algorithm: sha1WithRSAEncryption + 7d:0a:f5:cb:8d:d3:5d:bd:99:8e:f8:2b:0f:ba:eb:c2:d9:a6: + 27:4f:2e:7b:2f:0e:64:d8:1c:35:50:4e:ee:fc:90:b9:8d:6d: + a8:c5:c6:06:b0:af:f3:2d:bf:3b:b8:42:07:dd:18:7d:6d:95: + 54:57:85:18:60:47:2f:eb:78:1b:f9:e8:17:fd:5a:0d:87:17: + 28:ac:4c:6a:e6:bc:29:f4:f4:55:70:29:42:de:85:ea:ab:6c: + 23:06:64:30:75:02:8e:53:bc:5e:01:33:37:cc:1e:cd:b8:a4: + fd:ca:e4:5f:65:3b:83:1c:86:f1:55:02:a0:3a:8f:db:91:b7: + 40:14:b4:e7:8d:d2:ee:73:ba:e3:e5:34:2d:bc:94:6f:4e:24: + 06:f7:5f:8b:0e:a7:8e:6b:de:5e:75:f4:32:9a:50:b1:44:33: + 9a:d0:05:e2:78:82:ff:db:da:8a:63:eb:a9:dd:d1:bf:a0:61: + ad:e3:9e:8a:24:5d:62:0e:e7:4c:91:7f:ef:df:34:36:3b:2f: + 5d:f5:84:b2:2f:c4:6d:93:96:1a:6f:30:28:f1:da:12:9a:64: + b4:40:33:1d:bd:de:2b:53:a8:ea:be:d6:bc:4e:96:f5:44:fb: + 32:18:ae:d5:1f:f6:69:af:b6:4e:7b:1d:58:ec:3b:a9:53:a3: + 5e:58:c8:9e +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIJALCSZLHy2iHQMA0GCSqGSIb3DQEBBQUAME0xCzAJBgNV +BAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUgRm91bmRhdGlvbiBDQTEW +MBQGA1UEAwwNb3VyLWNhLXNlcnZlcjAeFw0xMzAxMDQxOTQ3MDdaFw0yMzAxMDIx +OTQ3MDdaME0xCzAJBgNVBAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUg +Rm91bmRhdGlvbiBDQTEWMBQGA1UEAwwNb3VyLWNhLXNlcnZlcjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAOfe6eMMnwC2of0rW5bSb8zgvoa5IF7sA3pV +q+qk6flJhdJm1e3HeupWji2P50LiYiipn9Ybjuu1tJyfFKvf5pSLdh0+bSRh7Qy/ +AIphDN9cyDZzFgDNR7ptpKR0iIMjChn8Cac8SkvT5x0t5OpMVCHzJtuJNxjUArtA +Ml+k/y0c99S77I7PXIKs5nwIbEiFYQd/JeBc4Lw0X+C5BEd1yEcLjbzWyGhfM4Ni +0iBENbGtgRqKzbw1sFyLR9YY6ZwYl8wBPCnM6B7k5MG43ufCERiHWpM02KYl9xRx +6+QhotIPLi7UYgA109bvXGBLTKkU4t0VWEY3Mya35y5d7ULkxU0CAwEAAaNQME4w +HQYDVR0OBBYEFLzdYtl22hvSVGvP4GabHh57VgwLMB8GA1UdIwQYMBaAFLzdYtl2 +2hvSVGvP4GabHh57VgwLMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB +AH0K9cuN0129mY74Kw+668LZpidPLnsvDmTYHDVQTu78kLmNbajFxgawr/Mtvzu4 +QgfdGH1tlVRXhRhgRy/reBv56Bf9Wg2HFyisTGrmvCn09FVwKULeheqrbCMGZDB1 +Ao5TvF4BMzfMHs24pP3K5F9lO4MchvFVAqA6j9uRt0AUtOeN0u5zuuPlNC28lG9O +JAb3X4sOp45r3l519DKaULFEM5rQBeJ4gv/b2opj66nd0b+gYa3jnookXWIO50yR +f+/fNDY7L131hLIvxG2TlhpvMCjx2hKaZLRAMx293itTqOq+1rxOlvVE+zIYrtUf +9mmvtk57HVjsO6lTo15YyJ4= +-----END CERTIFICATE----- diff --git a/Lib/test/test_asyncio/sample.crt b/Lib/test/test_asyncio/sample.crt deleted file mode 100644 index 6a1e3f3c2e76..000000000000 --- a/Lib/test/test_asyncio/sample.crt +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICMzCCAZwCCQDFl4ys0fU7iTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQGEwJV -UzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuLUZyYW5jaXNjbzEi -MCAGA1UECgwZUHl0aG9uIFNvZnR3YXJlIEZvbmRhdGlvbjAeFw0xMzAzMTgyMDA3 -MjhaFw0yMzAzMTYyMDA3MjhaMF4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp -Zm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMSIwIAYDVQQKDBlQeXRob24g -U29mdHdhcmUgRm9uZGF0aW9uMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCn -t3s+J7L0xP/YdAQOacpPi9phlrzKZhcXL3XMu2LCUg2fNJpx/47Vc5TZSaO11uO7 -gdwVz3Z7Q2epAgwo59JLffLt5fia8+a/SlPweI/j4+wcIIIiqusnLfpqR8cIAavg -Z06cLYCDvb9wMlheIvSJY12skc1nnphWS2YJ0Xm6uQIDAQABMA0GCSqGSIb3DQEB -BQUAA4GBAE9PknG6pv72+5z/gsDGYy8sK5UNkbWSNr4i4e5lxVsF03+/M71H+3AB -MxVX4+A+Vlk2fmU+BrdHIIUE0r1dDcO3josQ9hc9OJpp5VLSQFP8VeuJCmzYPp9I -I8WbW93cnXnChTrYQVdgVoFdv7GE9YgU7NYkrGIM0nZl1/f/bHPB ------END CERTIFICATE----- diff --git a/Lib/test/test_asyncio/sample.key b/Lib/test/test_asyncio/sample.key deleted file mode 100644 index edfea8dcab3d..000000000000 --- a/Lib/test/test_asyncio/sample.key +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQCnt3s+J7L0xP/YdAQOacpPi9phlrzKZhcXL3XMu2LCUg2fNJpx -/47Vc5TZSaO11uO7gdwVz3Z7Q2epAgwo59JLffLt5fia8+a/SlPweI/j4+wcIIIi -qusnLfpqR8cIAavgZ06cLYCDvb9wMlheIvSJY12skc1nnphWS2YJ0Xm6uQIDAQAB -AoGABfm8k19Yue3W68BecKEGS0VBV57GRTPT+MiBGvVGNIQ15gk6w3sGfMZsdD1y -bsUkQgcDb2d/4i5poBTpl/+Cd41V+c20IC/sSl5X1IEreHMKSLhy/uyjyiyfXlP1 -iXhToFCgLWwENWc8LzfUV8vuAV5WG6oL9bnudWzZxeqx8V0CQQDR7xwVj6LN70Eb -DUhSKLkusmFw5Gk9NJ/7wZ4eHg4B8c9KNVvSlLCLhcsVTQXuqYeFpOqytI45SneP -lr0vrvsDAkEAzITYiXu6ox5huDCG7imX2W9CAYuX638urLxBqBXMS7GqBzojD6RL -21Q8oPwJWJquERa3HDScq1deiQbM9uKIkwJBAIa1PLslGN216Xv3UPHPScyKD/aF -ynXIv+OnANPoiyp6RH4ksQ/18zcEGiVH8EeNpvV9tlAHhb+DZibQHgNr74sCQQC0 -zhToplu/bVKSlUQUNO0rqrI9z30FErDewKeCw5KSsIRSU1E/uM3fHr9iyq4wiL6u -GNjUtKZ0y46lsT9uW6LFAkB5eqeEQnshAdr3X5GykWHJ8DDGBXPPn6Rce1NX4RSq -V9khG2z1bFyfo+hMqpYnF2k32hVq3E54RS8YYnwBsVof ------END RSA PRIVATE KEY----- diff --git a/Lib/test/test_asyncio/ssl_cert.pem b/Lib/test/test_asyncio/ssl_cert.pem new file mode 100644 index 000000000000..47a7d7e37e80 --- /dev/null +++ b/Lib/test/test_asyncio/ssl_cert.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICVDCCAb2gAwIBAgIJANfHOBkZr8JOMA0GCSqGSIb3DQEBBQUAMF8xCzAJBgNV +BAYTAlhZMRcwFQYDVQQHEw5DYXN0bGUgQW50aHJheDEjMCEGA1UEChMaUHl0aG9u +IFNvZnR3YXJlIEZvdW5kYXRpb24xEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0xMDEw +MDgyMzAxNTZaFw0yMDEwMDUyMzAxNTZaMF8xCzAJBgNVBAYTAlhZMRcwFQYDVQQH +Ew5DYXN0bGUgQW50aHJheDEjMCEGA1UEChMaUHl0aG9uIFNvZnR3YXJlIEZvdW5k +YXRpb24xEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAw +gYkCgYEA21vT5isq7F68amYuuNpSFlKDPrMUCa4YWYqZRt2OZ+/3NKaZ2xAiSwr7 +6MrQF70t5nLbSPpqE5+5VrS58SY+g/sXLiFd6AplH1wJZwh78DofbFYXUggktFMt +pTyiX8jtP66bkcPkDADA089RI1TQR6Ca+n7HFa7c1fabVV6i3zkCAwEAAaMYMBYw +FAYDVR0RBA0wC4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBBQUAA4GBAHPctQBEQ4wd +BJ6+JcpIraopLn8BGhbjNWj40mmRqWB/NAWF6M5ne7KpGAu7tLeG4hb1zLaldK8G +lxy2GPSRF6LFS48dpEj2HbMv2nvv6xxalDMJ9+DicWgAKTQ6bcX2j3GUkCR0g/T1 +CRlNBAAlvhKzO7Clpf9l0YKBEfraJByX +-----END CERTIFICATE----- diff --git a/Lib/test/test_asyncio/ssl_key.pem b/Lib/test/test_asyncio/ssl_key.pem new file mode 100644 index 000000000000..3fd3bbd54a34 --- /dev/null +++ b/Lib/test/test_asyncio/ssl_key.pem @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANtb0+YrKuxevGpm +LrjaUhZSgz6zFAmuGFmKmUbdjmfv9zSmmdsQIksK++jK0Be9LeZy20j6ahOfuVa0 +ufEmPoP7Fy4hXegKZR9cCWcIe/A6H2xWF1IIJLRTLaU8ol/I7T+um5HD5AwAwNPP +USNU0Eegmvp+xxWu3NX2m1Veot85AgMBAAECgYA3ZdZ673X0oexFlq7AAmrutkHt +CL7LvwrpOiaBjhyTxTeSNWzvtQBkIU8DOI0bIazA4UreAFffwtvEuPmonDb3F+Iq +SMAu42XcGyVZEl+gHlTPU9XRX7nTOXVt+MlRRRxL6t9GkGfUAXI3XxJDXW3c0vBK +UL9xqD8cORXOfE06rQJBAP8mEX1ERkR64Ptsoe4281vjTlNfIbs7NMPkUnrn9N/Y +BLhjNIfQ3HFZG8BTMLfX7kCS9D593DW5tV4Z9BP/c6cCQQDcFzCcVArNh2JSywOQ +ZfTfRbJg/Z5Lt9Fkngv1meeGNPgIMLN8Sg679pAOOWmzdMO3V706rNPzSVMME7E5 +oPIfAkEA8pDddarP5tCvTTgUpmTFbakm0KoTZm2+FzHcnA4jRh+XNTjTOv98Y6Ik +eO5d1ZnKXseWvkZncQgxfdnMqqpj5wJAcNq/RVne1DbYlwWchT2Si65MYmmJ8t+F +0mcsULqjOnEMwf5e+ptq5LzwbyrHZYq5FNk7ocufPv/ZQrcSSC+cFwJBAKvOJByS +x56qyGeZLOQlWS2JS3KJo59XuLFGqcbgN9Om9xFa41Yb4N9NvplFivsvZdw3m1Q/ +SPIXQuT8RMPDVNQ= +-----END PRIVATE KEY----- diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index 96f29750c721..54b771e8b289 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -2,30 +2,46 @@ import errno import logging +import math +import os import socket +import sys +import threading import time import unittest -import unittest.mock -from test.support import find_unused_port, IPV6_ENABLED +from unittest import mock +import asyncio from asyncio import base_events from asyncio import constants -from asyncio import events -from asyncio import futures -from asyncio import protocols -from asyncio import tasks from asyncio import test_utils +try: + from test import support +except ImportError: + from asyncio import test_support as support +try: + from test.support.script_helper import assert_python_ok +except ImportError: + try: + from test.script_helper import assert_python_ok + except ImportError: + from asyncio.test_support import assert_python_ok -class BaseEventLoopTests(unittest.TestCase): +MOCK_ANY = mock.ANY +PY34 = sys.version_info >= (3, 4) + + +class BaseEventLoopTests(test_utils.TestCase): def setUp(self): self.loop = base_events.BaseEventLoop() - self.loop._selector = unittest.mock.Mock() - events.set_event_loop(None) + self.loop._selector = mock.Mock() + self.loop._selector.select.return_value = () + self.set_event_loop(self.loop) def test_not_implemented(self): - m = unittest.mock.Mock() + m = mock.Mock() self.assertRaises( NotImplementedError, self.loop._make_socket_transport, m, m) @@ -39,8 +55,6 @@ def test_not_implemented(self): NotImplementedError, self.loop._process_events, []) self.assertRaises( NotImplementedError, self.loop._write_to_self) - self.assertRaises( - NotImplementedError, self.loop._read_from_self) self.assertRaises( NotImplementedError, self.loop._make_read_pipe_transport, m, m) @@ -48,23 +62,32 @@ def test_not_implemented(self): NotImplementedError, self.loop._make_write_pipe_transport, m, m) gen = self.loop._make_subprocess_transport(m, m, m, m, m, m, m) - self.assertRaises(NotImplementedError, next, iter(gen)) + with self.assertRaises(NotImplementedError): + gen.send(None) + + def test_close(self): + self.assertFalse(self.loop.is_closed()) + self.loop.close() + self.assertTrue(self.loop.is_closed()) + + # it should be possible to call close() more than once + self.loop.close() + self.loop.close() + + # operation blocked when the loop is closed + f = asyncio.Future(loop=self.loop) + self.assertRaises(RuntimeError, self.loop.run_forever) + self.assertRaises(RuntimeError, self.loop.run_until_complete, f) def test__add_callback_handle(self): - h = events.Handle(lambda: False, ()) + h = asyncio.Handle(lambda: False, (), self.loop) self.loop._add_callback(h) self.assertFalse(self.loop._scheduled) self.assertIn(h, self.loop._ready) - def test__add_callback_timer(self): - h = events.TimerHandle(time.monotonic()+10, lambda: False, ()) - - self.loop._add_callback(h) - self.assertIn(h, self.loop._scheduled) - def test__add_callback_cancelled_handle(self): - h = events.Handle(lambda: False, ()) + h = asyncio.Handle(lambda: False, (), self.loop) h.cancel() self.loop._add_callback(h) @@ -72,13 +95,13 @@ def test__add_callback_cancelled_handle(self): self.assertFalse(self.loop._ready) def test_set_default_executor(self): - executor = unittest.mock.Mock() + executor = mock.Mock() self.loop.set_default_executor(executor) self.assertIs(executor, self.loop._default_executor) def test_getnameinfo(self): - sockaddr = unittest.mock.Mock() - self.loop.run_in_executor = unittest.mock.Mock() + sockaddr = mock.Mock() + self.loop.run_in_executor = mock.Mock() self.loop.getnameinfo(sockaddr) self.assertEqual( (None, socket.getnameinfo, sockaddr, 0), @@ -90,7 +113,7 @@ def cb(): h = self.loop.call_soon(cb) self.assertEqual(h._callback, cb) - self.assertIsInstance(h, events.Handle) + self.assertIsInstance(h, asyncio.Handle) self.assertIn(h, self.loop._ready) def test_call_later(self): @@ -98,7 +121,7 @@ def cb(): pass h = self.loop.call_later(10.0, cb) - self.assertIsInstance(h, events.TimerHandle) + self.assertIsInstance(h, asyncio.TimerHandle) self.assertIn(h, self.loop._scheduled) self.assertNotIn(h, self.loop._ready) @@ -108,7 +131,7 @@ def test_call_later_negative_delays(self): def cb(arg): calls.append(arg) - self.loop._process_events = unittest.mock.Mock() + self.loop._process_events = mock.Mock() self.loop.call_later(-1, cb, 'a') self.loop.call_later(-2, cb, 'b') test_utils.run_briefly(self.loop) @@ -118,13 +141,86 @@ def test_time_and_call_at(self): def cb(): self.loop.stop() - self.loop._process_events = unittest.mock.Mock() - when = self.loop.time() + 0.1 + self.loop._process_events = mock.Mock() + delay = 0.1 + + when = self.loop.time() + delay self.loop.call_at(when, cb) t0 = self.loop.time() self.loop.run_forever() - t1 = self.loop.time() - self.assertTrue(0.09 <= t1-t0 <= 0.9, t1-t0) + dt = self.loop.time() - t0 + + # 50 ms: maximum granularity of the event loop + self.assertGreaterEqual(dt, delay - 0.050, dt) + # tolerate a difference of +800 ms because some Python buildbots + # are really slow + self.assertLessEqual(dt, 0.9, dt) + + def check_thread(self, loop, debug): + def cb(): + pass + + loop.set_debug(debug) + if debug: + msg = ("Non-thread-safe operation invoked on an event loop other " + "than the current one") + with self.assertRaisesRegex(RuntimeError, msg): + loop.call_soon(cb) + with self.assertRaisesRegex(RuntimeError, msg): + loop.call_later(60, cb) + with self.assertRaisesRegex(RuntimeError, msg): + loop.call_at(loop.time() + 60, cb) + else: + loop.call_soon(cb) + loop.call_later(60, cb) + loop.call_at(loop.time() + 60, cb) + + def test_check_thread(self): + def check_in_thread(loop, event, debug, create_loop, fut): + # wait until the event loop is running + event.wait() + + try: + if create_loop: + loop2 = base_events.BaseEventLoop() + try: + asyncio.set_event_loop(loop2) + self.check_thread(loop, debug) + finally: + asyncio.set_event_loop(None) + loop2.close() + else: + self.check_thread(loop, debug) + except Exception as exc: + loop.call_soon_threadsafe(fut.set_exception, exc) + else: + loop.call_soon_threadsafe(fut.set_result, None) + + def test_thread(loop, debug, create_loop=False): + event = threading.Event() + fut = asyncio.Future(loop=loop) + loop.call_soon(event.set) + args = (loop, event, debug, create_loop, fut) + thread = threading.Thread(target=check_in_thread, args=args) + thread.start() + loop.run_until_complete(fut) + thread.join() + + self.loop._process_events = mock.Mock() + self.loop._write_to_self = mock.Mock() + + # raise RuntimeError if the thread has no event loop + test_thread(self.loop, True) + + # check disabled if debug mode is disabled + test_thread(self.loop, False) + + # raise RuntimeError if the event loop of the thread is not the called + # event loop + test_thread(self.loop, True, create_loop=True) + + # check disabled if debug mode is disabled + test_thread(self.loop, False, create_loop=True) def test_run_once_in_executor_handle(self): def cb(): @@ -132,28 +228,28 @@ def cb(): self.assertRaises( AssertionError, self.loop.run_in_executor, - None, events.Handle(cb, ()), ('',)) + None, asyncio.Handle(cb, (), self.loop), ('',)) self.assertRaises( AssertionError, self.loop.run_in_executor, - None, events.TimerHandle(10, cb, ())) + None, asyncio.TimerHandle(10, cb, (), self.loop)) def test_run_once_in_executor_cancelled(self): def cb(): pass - h = events.Handle(cb, ()) + h = asyncio.Handle(cb, (), self.loop) h.cancel() f = self.loop.run_in_executor(None, h) - self.assertIsInstance(f, futures.Future) + self.assertIsInstance(f, asyncio.Future) self.assertTrue(f.done()) self.assertIsNone(f.result()) def test_run_once_in_executor_plain(self): def cb(): pass - h = events.Handle(cb, ()) - f = futures.Future(loop=self.loop) - executor = unittest.mock.Mock() + h = asyncio.Handle(cb, (), self.loop) + f = asyncio.Future(loop=self.loop) + executor = mock.Mock() executor.submit.return_value = f self.loop.set_default_executor(executor) @@ -161,7 +257,7 @@ def cb(): res = self.loop.run_in_executor(None, h) self.assertIs(f, res) - executor = unittest.mock.Mock() + executor = mock.Mock() executor.submit.return_value = f res = self.loop.run_in_executor(executor, h) self.assertIs(f, res) @@ -170,12 +266,14 @@ def cb(): f.cancel() # Don't complain about abandoned Future. def test__run_once(self): - h1 = events.TimerHandle(time.monotonic() + 5.0, lambda: True, ()) - h2 = events.TimerHandle(time.monotonic() + 10.0, lambda: True, ()) + h1 = asyncio.TimerHandle(time.monotonic() + 5.0, lambda: True, (), + self.loop) + h2 = asyncio.TimerHandle(time.monotonic() + 10.0, lambda: True, (), + self.loop) h1.cancel() - self.loop._process_events = unittest.mock.Mock() + self.loop._process_events = mock.Mock() self.loop._scheduled.append(h1) self.loop._scheduled.append(h2) self.loop._run_once() @@ -185,33 +283,36 @@ def test__run_once(self): self.assertEqual([h2], self.loop._scheduled) self.assertTrue(self.loop._process_events.called) - @unittest.mock.patch('asyncio.base_events.time') - @unittest.mock.patch('asyncio.base_events.logger') - def test__run_once_logging(self, m_logging, m_time): - # Log to INFO level if timeout > 1.0 sec. - idx = -1 - data = [10.0, 10.0, 12.0, 13.0] + def test_set_debug(self): + self.loop.set_debug(True) + self.assertTrue(self.loop.get_debug()) + self.loop.set_debug(False) + self.assertFalse(self.loop.get_debug()) - def monotonic(): - nonlocal data, idx - idx += 1 - return data[idx] + @mock.patch('asyncio.base_events.logger') + def test__run_once_logging(self, m_logger): + def slow_select(timeout): + # Sleep a bit longer than a second to avoid timer resolution + # issues. + time.sleep(1.1) + return [] - m_time.monotonic = monotonic - m_logging.INFO = logging.INFO - m_logging.DEBUG = logging.DEBUG + # logging needs debug flag + self.loop.set_debug(True) - self.loop._scheduled.append( - events.TimerHandle(11.0, lambda: True, ())) - self.loop._process_events = unittest.mock.Mock() + # Log to INFO level if timeout > 1.0 sec. + self.loop._selector.select = slow_select + self.loop._process_events = mock.Mock() self.loop._run_once() - self.assertEqual(logging.INFO, m_logging.log.call_args[0][0]) + self.assertEqual(logging.INFO, m_logger.log.call_args[0][0]) - idx = -1 - data = [10.0, 10.0, 10.3, 13.0] - self.loop._scheduled = [events.TimerHandle(11.0, lambda:True, ())] + def fast_select(timeout): + time.sleep(0.001) + return [] + + self.loop._selector.select = fast_select self.loop._run_once() - self.assertEqual(logging.DEBUG, m_logging.log.call_args[0][0]) + self.assertEqual(logging.DEBUG, m_logger.log.call_args[0][0]) def test__run_once_schedule_handle(self): handle = None @@ -222,28 +323,449 @@ def cb(loop): processed = True handle = loop.call_soon(lambda: True) - h = events.TimerHandle(time.monotonic() - 1, cb, (self.loop,)) + h = asyncio.TimerHandle(time.monotonic() - 1, cb, (self.loop,), + self.loop) - self.loop._process_events = unittest.mock.Mock() + self.loop._process_events = mock.Mock() self.loop._scheduled.append(h) self.loop._run_once() self.assertTrue(processed) self.assertEqual([handle], list(self.loop._ready)) + def test__run_once_cancelled_event_cleanup(self): + self.loop._process_events = mock.Mock() + + self.assertTrue( + 0 < base_events._MIN_CANCELLED_TIMER_HANDLES_FRACTION < 1.0) + + def cb(): + pass + + # Set up one "blocking" event that will not be cancelled to + # ensure later cancelled events do not make it to the head + # of the queue and get cleaned. + not_cancelled_count = 1 + self.loop.call_later(3000, cb) + + # Add less than threshold (base_events._MIN_SCHEDULED_TIMER_HANDLES) + # cancelled handles, ensure they aren't removed + + cancelled_count = 2 + for x in range(2): + h = self.loop.call_later(3600, cb) + h.cancel() + + # Add some cancelled events that will be at head and removed + cancelled_count += 2 + for x in range(2): + h = self.loop.call_later(100, cb) + h.cancel() + + # This test is invalid if _MIN_SCHEDULED_TIMER_HANDLES is too low + self.assertLessEqual(cancelled_count + not_cancelled_count, + base_events._MIN_SCHEDULED_TIMER_HANDLES) + + self.assertEqual(self.loop._timer_cancelled_count, cancelled_count) + + self.loop._run_once() + + cancelled_count -= 2 + + self.assertEqual(self.loop._timer_cancelled_count, cancelled_count) + + self.assertEqual(len(self.loop._scheduled), + cancelled_count + not_cancelled_count) + + # Need enough events to pass _MIN_CANCELLED_TIMER_HANDLES_FRACTION + # so that deletion of cancelled events will occur on next _run_once + add_cancel_count = int(math.ceil( + base_events._MIN_SCHEDULED_TIMER_HANDLES * + base_events._MIN_CANCELLED_TIMER_HANDLES_FRACTION)) + 1 + + add_not_cancel_count = max(base_events._MIN_SCHEDULED_TIMER_HANDLES - + add_cancel_count, 0) + + # Add some events that will not be cancelled + not_cancelled_count += add_not_cancel_count + for x in range(add_not_cancel_count): + self.loop.call_later(3600, cb) + + # Add enough cancelled events + cancelled_count += add_cancel_count + for x in range(add_cancel_count): + h = self.loop.call_later(3600, cb) + h.cancel() + + # Ensure all handles are still scheduled + self.assertEqual(len(self.loop._scheduled), + cancelled_count + not_cancelled_count) + + self.loop._run_once() + + # Ensure cancelled events were removed + self.assertEqual(len(self.loop._scheduled), not_cancelled_count) + + # Ensure only uncancelled events remain scheduled + self.assertTrue(all([not x._cancelled for x in self.loop._scheduled])) + def test_run_until_complete_type_error(self): - self.assertRaises( - TypeError, self.loop.run_until_complete, 'blah') + self.assertRaises(TypeError, + self.loop.run_until_complete, 'blah') + + def test_run_until_complete_loop(self): + task = asyncio.Future(loop=self.loop) + other_loop = self.new_test_loop() + self.addCleanup(other_loop.close) + self.assertRaises(ValueError, + other_loop.run_until_complete, task) + + def test_subprocess_exec_invalid_args(self): + args = [sys.executable, '-c', 'pass'] + + # missing program parameter (empty args) + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_exec, + asyncio.SubprocessProtocol) + + # expected multiple arguments, not a list + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_exec, + asyncio.SubprocessProtocol, args) + + # program arguments must be strings, not int + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_exec, + asyncio.SubprocessProtocol, sys.executable, 123) + + # universal_newlines, shell, bufsize must not be set + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_exec, + asyncio.SubprocessProtocol, *args, universal_newlines=True) + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_exec, + asyncio.SubprocessProtocol, *args, shell=True) + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_exec, + asyncio.SubprocessProtocol, *args, bufsize=4096) + + def test_subprocess_shell_invalid_args(self): + # expected a string, not an int or a list + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_shell, + asyncio.SubprocessProtocol, 123) + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_shell, + asyncio.SubprocessProtocol, [sys.executable, '-c', 'pass']) + + # universal_newlines, shell, bufsize must not be set + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_shell, + asyncio.SubprocessProtocol, 'exit 0', universal_newlines=True) + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_shell, + asyncio.SubprocessProtocol, 'exit 0', shell=True) + self.assertRaises(TypeError, + self.loop.run_until_complete, self.loop.subprocess_shell, + asyncio.SubprocessProtocol, 'exit 0', bufsize=4096) + + def test_default_exc_handler_callback(self): + self.loop._process_events = mock.Mock() + + def zero_error(fut): + fut.set_result(True) + 1/0 + + # Test call_soon (events.Handle) + with mock.patch('asyncio.base_events.logger') as log: + fut = asyncio.Future(loop=self.loop) + self.loop.call_soon(zero_error, fut) + fut.add_done_callback(lambda fut: self.loop.stop()) + self.loop.run_forever() + log.error.assert_called_with( + test_utils.MockPattern('Exception in callback.*zero'), + exc_info=(ZeroDivisionError, MOCK_ANY, MOCK_ANY)) + + # Test call_later (events.TimerHandle) + with mock.patch('asyncio.base_events.logger') as log: + fut = asyncio.Future(loop=self.loop) + self.loop.call_later(0.01, zero_error, fut) + fut.add_done_callback(lambda fut: self.loop.stop()) + self.loop.run_forever() + log.error.assert_called_with( + test_utils.MockPattern('Exception in callback.*zero'), + exc_info=(ZeroDivisionError, MOCK_ANY, MOCK_ANY)) + + def test_default_exc_handler_coro(self): + self.loop._process_events = mock.Mock() + + @asyncio.coroutine + def zero_error_coro(): + yield from asyncio.sleep(0.01, loop=self.loop) + 1/0 + + # Test Future.__del__ + with mock.patch('asyncio.base_events.logger') as log: + fut = asyncio.ensure_future(zero_error_coro(), loop=self.loop) + fut.add_done_callback(lambda *args: self.loop.stop()) + self.loop.run_forever() + fut = None # Trigger Future.__del__ or futures._TracebackLogger + if PY34: + # Future.__del__ in Python 3.4 logs error with + # an actual exception context + log.error.assert_called_with( + test_utils.MockPattern('.*exception was never retrieved'), + exc_info=(ZeroDivisionError, MOCK_ANY, MOCK_ANY)) + else: + # futures._TracebackLogger logs only textual traceback + log.error.assert_called_with( + test_utils.MockPattern( + '.*exception was never retrieved.*ZeroDiv'), + exc_info=False) + + def test_set_exc_handler_invalid(self): + with self.assertRaisesRegex(TypeError, 'A callable object or None'): + self.loop.set_exception_handler('spam') + + def test_set_exc_handler_custom(self): + def zero_error(): + 1/0 + + def run_loop(): + handle = self.loop.call_soon(zero_error) + self.loop._run_once() + return handle + + self.loop.set_debug(True) + self.loop._process_events = mock.Mock() + + mock_handler = mock.Mock() + self.loop.set_exception_handler(mock_handler) + handle = run_loop() + mock_handler.assert_called_with(self.loop, { + 'exception': MOCK_ANY, + 'message': test_utils.MockPattern( + 'Exception in callback.*zero_error'), + 'handle': handle, + 'source_traceback': handle._source_traceback, + }) + mock_handler.reset_mock() + + self.loop.set_exception_handler(None) + with mock.patch('asyncio.base_events.logger') as log: + run_loop() + log.error.assert_called_with( + test_utils.MockPattern( + 'Exception in callback.*zero'), + exc_info=(ZeroDivisionError, MOCK_ANY, MOCK_ANY)) + + assert not mock_handler.called + + def test_set_exc_handler_broken(self): + def run_loop(): + def zero_error(): + 1/0 + self.loop.call_soon(zero_error) + self.loop._run_once() + + def handler(loop, context): + raise AttributeError('spam') + + self.loop._process_events = mock.Mock() + + self.loop.set_exception_handler(handler) + + with mock.patch('asyncio.base_events.logger') as log: + run_loop() + log.error.assert_called_with( + test_utils.MockPattern( + 'Unhandled error in exception handler'), + exc_info=(AttributeError, MOCK_ANY, MOCK_ANY)) + + def test_default_exc_handler_broken(self): + _context = None + + class Loop(base_events.BaseEventLoop): + + _selector = mock.Mock() + _process_events = mock.Mock() + + def default_exception_handler(self, context): + nonlocal _context + _context = context + # Simulates custom buggy "default_exception_handler" + raise ValueError('spam') + + loop = Loop() + self.addCleanup(loop.close) + asyncio.set_event_loop(loop) + + def run_loop(): + def zero_error(): + 1/0 + loop.call_soon(zero_error) + loop._run_once() + + with mock.patch('asyncio.base_events.logger') as log: + run_loop() + log.error.assert_called_with( + 'Exception in default exception handler', + exc_info=True) + + def custom_handler(loop, context): + raise ValueError('ham') + + _context = None + loop.set_exception_handler(custom_handler) + with mock.patch('asyncio.base_events.logger') as log: + run_loop() + log.error.assert_called_with( + test_utils.MockPattern('Exception in default exception.*' + 'while handling.*in custom'), + exc_info=True) + + # Check that original context was passed to default + # exception handler. + self.assertIn('context', _context) + self.assertIs(type(_context['context']['exception']), + ZeroDivisionError) + + def test_set_task_factory_invalid(self): + with self.assertRaisesRegex( + TypeError, 'task factory must be a callable or None'): + + self.loop.set_task_factory(1) + + self.assertIsNone(self.loop.get_task_factory()) + + def test_set_task_factory(self): + self.loop._process_events = mock.Mock() + + class MyTask(asyncio.Task): + pass + + @asyncio.coroutine + def coro(): + pass + + factory = lambda loop, coro: MyTask(coro, loop=loop) + + self.assertIsNone(self.loop.get_task_factory()) + self.loop.set_task_factory(factory) + self.assertIs(self.loop.get_task_factory(), factory) + + task = self.loop.create_task(coro()) + self.assertTrue(isinstance(task, MyTask)) + self.loop.run_until_complete(task) + + self.loop.set_task_factory(None) + self.assertIsNone(self.loop.get_task_factory()) + + task = self.loop.create_task(coro()) + self.assertTrue(isinstance(task, asyncio.Task)) + self.assertFalse(isinstance(task, MyTask)) + self.loop.run_until_complete(task) + + def test_env_var_debug(self): + code = '\n'.join(( + 'import asyncio', + 'loop = asyncio.get_event_loop()', + 'print(loop.get_debug())')) + + # Test with -E to not fail if the unit test was run with + # PYTHONASYNCIODEBUG set to a non-empty string + sts, stdout, stderr = assert_python_ok('-E', '-c', code) + self.assertEqual(stdout.rstrip(), b'False') + + sts, stdout, stderr = assert_python_ok('-c', code, + PYTHONASYNCIODEBUG='') + self.assertEqual(stdout.rstrip(), b'False') + + sts, stdout, stderr = assert_python_ok('-c', code, + PYTHONASYNCIODEBUG='1') + self.assertEqual(stdout.rstrip(), b'True') + + sts, stdout, stderr = assert_python_ok('-E', '-c', code, + PYTHONASYNCIODEBUG='1') + self.assertEqual(stdout.rstrip(), b'False') + + def test_create_task(self): + class MyTask(asyncio.Task): + pass + + @asyncio.coroutine + def test(): + pass + + class EventLoop(base_events.BaseEventLoop): + def create_task(self, coro): + return MyTask(coro, loop=loop) + loop = EventLoop() + self.set_event_loop(loop) -class MyProto(protocols.Protocol): + coro = test() + task = asyncio.ensure_future(coro, loop=loop) + self.assertIsInstance(task, MyTask) + + # make warnings quiet + task._log_destroy_pending = False + coro.close() + + def test_run_forever_keyboard_interrupt(self): + # Python issue #22601: ensure that the temporary task created by + # run_forever() consumes the KeyboardInterrupt and so don't log + # a warning + @asyncio.coroutine + def raise_keyboard_interrupt(): + raise KeyboardInterrupt + + self.loop._process_events = mock.Mock() + self.loop.call_exception_handler = mock.Mock() + + try: + self.loop.run_until_complete(raise_keyboard_interrupt()) + except KeyboardInterrupt: + pass + self.loop.close() + support.gc_collect() + + self.assertFalse(self.loop.call_exception_handler.called) + + def test_run_until_complete_baseexception(self): + # Python issue #22429: run_until_complete() must not schedule a pending + # call to stop() if the future raised a BaseException + @asyncio.coroutine + def raise_keyboard_interrupt(): + raise KeyboardInterrupt + + self.loop._process_events = mock.Mock() + + try: + self.loop.run_until_complete(raise_keyboard_interrupt()) + except KeyboardInterrupt: + pass + + def func(): + self.loop.stop() + func.called = True + func.called = False + try: + self.loop.call_soon(func) + self.loop.run_forever() + except KeyboardInterrupt: + pass + self.assertTrue(func.called) + + +class MyProto(asyncio.Protocol): done = None def __init__(self, create_future=False): self.state = 'INITIAL' self.nbytes = 0 if create_future: - self.done = futures.Future() + self.done = asyncio.Future() def connection_made(self, transport): self.transport = transport @@ -266,14 +788,14 @@ def connection_lost(self, exc): self.done.set_result(None) -class MyDatagramProto(protocols.DatagramProtocol): +class MyDatagramProto(asyncio.DatagramProtocol): done = None - def __init__(self, create_future=False): + def __init__(self, create_future=False, loop=None): self.state = 'INITIAL' self.nbytes = 0 if create_future: - self.done = futures.Future() + self.done = asyncio.Future(loop=loop) def connection_made(self, transport): self.transport = transport @@ -294,29 +816,26 @@ def connection_lost(self, exc): self.done.set_result(None) -class BaseEventLoopWithSelectorTests(unittest.TestCase): +class BaseEventLoopWithSelectorTests(test_utils.TestCase): def setUp(self): - self.loop = events.new_event_loop() - events.set_event_loop(None) + self.loop = asyncio.new_event_loop() + self.set_event_loop(self.loop) - def tearDown(self): - self.loop.close() - - @unittest.mock.patch('asyncio.base_events.socket') + @mock.patch('asyncio.base_events.socket') def test_create_connection_multiple_errors(self, m_socket): - class MyProto(protocols.Protocol): + class MyProto(asyncio.Protocol): pass - @tasks.coroutine + @asyncio.coroutine def getaddrinfo(*args, **kw): yield from [] return [(2, 1, 6, '', ('107.6.106.82', 80)), (2, 1, 6, '', ('107.6.106.82', 80))] def getaddrinfo_task(*args, **kwds): - return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop) + return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop) idx = -1 errors = ['err1', 'err2'] @@ -336,6 +855,27 @@ def _socket(*args, **kw): self.assertEqual(str(cm.exception), 'Multiple exceptions: err1, err2') + @mock.patch('asyncio.base_events.socket') + def test_create_connection_timeout(self, m_socket): + # Ensure that the socket is closed on timeout + sock = mock.Mock() + m_socket.socket.return_value = sock + + def getaddrinfo(*args, **kw): + fut = asyncio.Future(loop=self.loop) + addr = (socket.AF_INET, socket.SOCK_STREAM, 0, '', + ('127.0.0.1', 80)) + fut.set_result([addr]) + return fut + self.loop.getaddrinfo = getaddrinfo + + with mock.patch.object(self.loop, 'sock_connect', + side_effect=asyncio.TimeoutError): + coro = self.loop.create_connection(MyProto, '127.0.0.1', 80) + with self.assertRaises(asyncio.TimeoutError): + self.loop.run_until_complete(coro) + self.assertTrue(sock.close.called) + def test_create_connection_host_port_sock(self): coro = self.loop.create_connection( MyProto, 'example.com', 80, sock=object()) @@ -346,12 +886,12 @@ def test_create_connection_no_host_port_sock(self): self.assertRaises(ValueError, self.loop.run_until_complete, coro) def test_create_connection_no_getaddrinfo(self): - @tasks.coroutine + @asyncio.coroutine def getaddrinfo(*args, **kw): yield from [] def getaddrinfo_task(*args, **kwds): - return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop) + return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop) self.loop.getaddrinfo = getaddrinfo_task coro = self.loop.create_connection(MyProto, 'example.com', 80) @@ -359,16 +899,16 @@ def getaddrinfo_task(*args, **kwds): OSError, self.loop.run_until_complete, coro) def test_create_connection_connect_err(self): - @tasks.coroutine + @asyncio.coroutine def getaddrinfo(*args, **kw): yield from [] return [(2, 1, 6, '', ('107.6.106.82', 80))] def getaddrinfo_task(*args, **kwds): - return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop) + return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop) self.loop.getaddrinfo = getaddrinfo_task - self.loop.sock_connect = unittest.mock.Mock() + self.loop.sock_connect = mock.Mock() self.loop.sock_connect.side_effect = OSError coro = self.loop.create_connection(MyProto, 'example.com', 80) @@ -376,16 +916,16 @@ def getaddrinfo_task(*args, **kwds): OSError, self.loop.run_until_complete, coro) def test_create_connection_multiple(self): - @tasks.coroutine + @asyncio.coroutine def getaddrinfo(*args, **kw): return [(2, 1, 6, '', ('0.0.0.1', 80)), (2, 1, 6, '', ('0.0.0.2', 80))] def getaddrinfo_task(*args, **kwds): - return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop) + return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop) self.loop.getaddrinfo = getaddrinfo_task - self.loop.sock_connect = unittest.mock.Mock() + self.loop.sock_connect = mock.Mock() self.loop.sock_connect.side_effect = OSError coro = self.loop.create_connection( @@ -393,7 +933,7 @@ def getaddrinfo_task(*args, **kwds): with self.assertRaises(OSError): self.loop.run_until_complete(coro) - @unittest.mock.patch('asyncio.base_events.socket') + @mock.patch('asyncio.base_events.socket') def test_create_connection_multiple_errors_local_addr(self, m_socket): def bind(addr): @@ -404,16 +944,16 @@ def bind(addr): m_socket.socket.return_value.bind = bind - @tasks.coroutine + @asyncio.coroutine def getaddrinfo(*args, **kw): return [(2, 1, 6, '', ('0.0.0.1', 80)), (2, 1, 6, '', ('0.0.0.2', 80))] def getaddrinfo_task(*args, **kwds): - return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop) + return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop) self.loop.getaddrinfo = getaddrinfo_task - self.loop.sock_connect = unittest.mock.Mock() + self.loop.sock_connect = mock.Mock() self.loop.sock_connect.side_effect = OSError('Err2') coro = self.loop.create_connection( @@ -426,7 +966,7 @@ def getaddrinfo_task(*args, **kwds): self.assertTrue(m_socket.socket.return_value.close.called) def test_create_connection_no_local_addr(self): - @tasks.coroutine + @asyncio.coroutine def getaddrinfo(host, *args, **kw): if host == 'example.com': return [(2, 1, 6, '', ('107.6.106.82', 80)), @@ -435,7 +975,7 @@ def getaddrinfo(host, *args, **kw): return [] def getaddrinfo_task(*args, **kwds): - return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop) + return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop) self.loop.getaddrinfo = getaddrinfo_task coro = self.loop.create_connection( @@ -445,22 +985,25 @@ def getaddrinfo_task(*args, **kwds): OSError, self.loop.run_until_complete, coro) def test_create_connection_ssl_server_hostname_default(self): - self.loop.getaddrinfo = unittest.mock.Mock() + self.loop.getaddrinfo = mock.Mock() def mock_getaddrinfo(*args, **kwds): - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) f.set_result([(socket.AF_INET, socket.SOCK_STREAM, socket.SOL_TCP, '', ('1.2.3.4', 80))]) return f self.loop.getaddrinfo.side_effect = mock_getaddrinfo - self.loop.sock_connect = unittest.mock.Mock() + self.loop.sock_connect = mock.Mock() self.loop.sock_connect.return_value = () - self.loop._make_ssl_transport = unittest.mock.Mock() + self.loop._make_ssl_transport = mock.Mock() class _SelectorTransportMock: _sock = None + def get_extra_info(self, key): + return mock.Mock() + def close(self): self._sock.close() @@ -472,7 +1015,7 @@ def mock_make_ssl_transport(sock, protocol, sslcontext, waiter, return transport self.loop._make_ssl_transport.side_effect = mock_make_ssl_transport - ANY = unittest.mock.ANY + ANY = mock.ANY # First try the default server_hostname. self.loop._make_ssl_transport.reset_mock() coro = self.loop.create_connection(MyProto, 'python.org', 80, ssl=True) @@ -527,14 +1070,14 @@ def test_create_server_empty_host(self): # if host is empty string use None instead host = object() - @tasks.coroutine + @asyncio.coroutine def getaddrinfo(*args, **kw): nonlocal host host = args[0] yield from [] def getaddrinfo_task(*args, **kwds): - return tasks.Task(getaddrinfo(*args, **kwds), loop=self.loop) + return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop) self.loop.getaddrinfo = getaddrinfo_task fut = self.loop.create_server(MyProto, '', 0) @@ -551,13 +1094,26 @@ def test_create_server_no_host_port_sock(self): self.assertRaises(ValueError, self.loop.run_until_complete, fut) def test_create_server_no_getaddrinfo(self): - getaddrinfo = self.loop.getaddrinfo = unittest.mock.Mock() + getaddrinfo = self.loop.getaddrinfo = mock.Mock() getaddrinfo.return_value = [] f = self.loop.create_server(MyProto, '0.0.0.0', 0) self.assertRaises(OSError, self.loop.run_until_complete, f) - @unittest.mock.patch('asyncio.base_events.socket') + @mock.patch('asyncio.base_events.socket') + def test_create_server_nosoreuseport(self, m_socket): + m_socket.getaddrinfo = socket.getaddrinfo + m_socket.SOCK_STREAM = socket.SOCK_STREAM + m_socket.SOL_SOCKET = socket.SOL_SOCKET + del m_socket.SO_REUSEPORT + m_socket.socket.return_value = mock.Mock() + + f = self.loop.create_server( + MyProto, '0.0.0.0', 0, reuse_port=True) + + self.assertRaises(ValueError, self.loop.run_until_complete, f) + + @mock.patch('asyncio.base_events.socket') def test_create_server_cant_bind(self, m_socket): class Err(OSError): @@ -565,16 +1121,18 @@ class Err(OSError): m_socket.getaddrinfo.return_value = [ (2, 1, 6, '', ('127.0.0.1', 10100))] - m_sock = m_socket.socket.return_value = unittest.mock.Mock() + m_socket.getaddrinfo._is_coroutine = False + m_sock = m_socket.socket.return_value = mock.Mock() m_sock.bind.side_effect = Err fut = self.loop.create_server(MyProto, '0.0.0.0', 0) self.assertRaises(OSError, self.loop.run_until_complete, fut) self.assertTrue(m_sock.close.called) - @unittest.mock.patch('asyncio.base_events.socket') + @mock.patch('asyncio.base_events.socket') def test_create_datagram_endpoint_no_addrinfo(self, m_socket): m_socket.getaddrinfo.return_value = [] + m_socket.getaddrinfo._is_coroutine = False coro = self.loop.create_datagram_endpoint( MyDatagramProto, local_addr=('localhost', 0)) @@ -592,43 +1150,43 @@ def test_create_datagram_endpoint_addr_error(self): AssertionError, self.loop.run_until_complete, coro) def test_create_datagram_endpoint_connect_err(self): - self.loop.sock_connect = unittest.mock.Mock() + self.loop.sock_connect = mock.Mock() self.loop.sock_connect.side_effect = OSError coro = self.loop.create_datagram_endpoint( - protocols.DatagramProtocol, remote_addr=('127.0.0.1', 0)) + asyncio.DatagramProtocol, remote_addr=('127.0.0.1', 0)) self.assertRaises( OSError, self.loop.run_until_complete, coro) - @unittest.mock.patch('asyncio.base_events.socket') + @mock.patch('asyncio.base_events.socket') def test_create_datagram_endpoint_socket_err(self, m_socket): m_socket.getaddrinfo = socket.getaddrinfo m_socket.socket.side_effect = OSError coro = self.loop.create_datagram_endpoint( - protocols.DatagramProtocol, family=socket.AF_INET) + asyncio.DatagramProtocol, family=socket.AF_INET) self.assertRaises( OSError, self.loop.run_until_complete, coro) coro = self.loop.create_datagram_endpoint( - protocols.DatagramProtocol, local_addr=('127.0.0.1', 0)) + asyncio.DatagramProtocol, local_addr=('127.0.0.1', 0)) self.assertRaises( OSError, self.loop.run_until_complete, coro) - @unittest.skipUnless(IPV6_ENABLED, 'IPv6 not supported or enabled') + @unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 not supported or enabled') def test_create_datagram_endpoint_no_matching_family(self): coro = self.loop.create_datagram_endpoint( - protocols.DatagramProtocol, + asyncio.DatagramProtocol, remote_addr=('127.0.0.1', 0), local_addr=('::1', 0)) self.assertRaises( ValueError, self.loop.run_until_complete, coro) - @unittest.mock.patch('asyncio.base_events.socket') + @mock.patch('asyncio.base_events.socket') def test_create_datagram_endpoint_setblk_err(self, m_socket): m_socket.socket.return_value.setblocking.side_effect = OSError coro = self.loop.create_datagram_endpoint( - protocols.DatagramProtocol, family=socket.AF_INET) + asyncio.DatagramProtocol, family=socket.AF_INET) self.assertRaises( OSError, self.loop.run_until_complete, coro) self.assertTrue( @@ -636,17 +1194,17 @@ def test_create_datagram_endpoint_setblk_err(self, m_socket): def test_create_datagram_endpoint_noaddr_nofamily(self): coro = self.loop.create_datagram_endpoint( - protocols.DatagramProtocol) + asyncio.DatagramProtocol) self.assertRaises(ValueError, self.loop.run_until_complete, coro) - @unittest.mock.patch('asyncio.base_events.socket') + @mock.patch('asyncio.base_events.socket') def test_create_datagram_endpoint_cant_bind(self, m_socket): class Err(OSError): pass m_socket.AF_INET6 = socket.AF_INET6 m_socket.getaddrinfo = socket.getaddrinfo - m_sock = m_socket.socket.return_value = unittest.mock.Mock() + m_sock = m_socket.socket.return_value = mock.Mock() m_sock.bind.side_effect = Err fut = self.loop.create_datagram_endpoint( @@ -655,30 +1213,199 @@ class Err(OSError): self.assertRaises(Err, self.loop.run_until_complete, fut) self.assertTrue(m_sock.close.called) + def test_create_datagram_endpoint_sock(self): + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + sock.bind(('127.0.0.1', 0)) + fut = self.loop.create_datagram_endpoint( + lambda: MyDatagramProto(create_future=True, loop=self.loop), + sock=sock) + transport, protocol = self.loop.run_until_complete(fut) + transport.close() + self.loop.run_until_complete(protocol.done) + self.assertEqual('CLOSED', protocol.state) + + def test_create_datagram_endpoint_sock_sockopts(self): + fut = self.loop.create_datagram_endpoint( + MyDatagramProto, local_addr=('127.0.0.1', 0), sock=object()) + self.assertRaises(ValueError, self.loop.run_until_complete, fut) + + fut = self.loop.create_datagram_endpoint( + MyDatagramProto, remote_addr=('127.0.0.1', 0), sock=object()) + self.assertRaises(ValueError, self.loop.run_until_complete, fut) + + fut = self.loop.create_datagram_endpoint( + MyDatagramProto, family=1, sock=object()) + self.assertRaises(ValueError, self.loop.run_until_complete, fut) + + fut = self.loop.create_datagram_endpoint( + MyDatagramProto, proto=1, sock=object()) + self.assertRaises(ValueError, self.loop.run_until_complete, fut) + + fut = self.loop.create_datagram_endpoint( + MyDatagramProto, flags=1, sock=object()) + self.assertRaises(ValueError, self.loop.run_until_complete, fut) + + fut = self.loop.create_datagram_endpoint( + MyDatagramProto, reuse_address=True, sock=object()) + self.assertRaises(ValueError, self.loop.run_until_complete, fut) + + fut = self.loop.create_datagram_endpoint( + MyDatagramProto, reuse_port=True, sock=object()) + self.assertRaises(ValueError, self.loop.run_until_complete, fut) + + fut = self.loop.create_datagram_endpoint( + MyDatagramProto, allow_broadcast=True, sock=object()) + self.assertRaises(ValueError, self.loop.run_until_complete, fut) + + def test_create_datagram_endpoint_sockopts(self): + # Socket options should not be applied unless asked for. + # SO_REUSEADDR defaults to on for UNIX. + # SO_REUSEPORT is not available on all platforms. + + coro = self.loop.create_datagram_endpoint( + lambda: MyDatagramProto(create_future=True, loop=self.loop), + local_addr=('127.0.0.1', 0)) + transport, protocol = self.loop.run_until_complete(coro) + sock = transport.get_extra_info('socket') + + reuse_address_default_on = ( + os.name == 'posix' and sys.platform != 'cygwin') + reuseport_supported = hasattr(socket, 'SO_REUSEPORT') + + if reuse_address_default_on: + self.assertTrue( + sock.getsockopt( + socket.SOL_SOCKET, socket.SO_REUSEADDR)) + else: + self.assertFalse( + sock.getsockopt( + socket.SOL_SOCKET, socket.SO_REUSEADDR)) + if reuseport_supported: + self.assertFalse( + sock.getsockopt( + socket.SOL_SOCKET, socket.SO_REUSEPORT)) + self.assertFalse( + sock.getsockopt( + socket.SOL_SOCKET, socket.SO_BROADCAST)) + + transport.close() + self.loop.run_until_complete(protocol.done) + self.assertEqual('CLOSED', protocol.state) + + coro = self.loop.create_datagram_endpoint( + lambda: MyDatagramProto(create_future=True, loop=self.loop), + local_addr=('127.0.0.1', 0), + reuse_address=True, + reuse_port=reuseport_supported, + allow_broadcast=True) + transport, protocol = self.loop.run_until_complete(coro) + sock = transport.get_extra_info('socket') + + self.assertTrue( + sock.getsockopt( + socket.SOL_SOCKET, socket.SO_REUSEADDR)) + if reuseport_supported: + self.assertTrue( + sock.getsockopt( + socket.SOL_SOCKET, socket.SO_REUSEPORT)) + self.assertTrue( + sock.getsockopt( + socket.SOL_SOCKET, socket.SO_BROADCAST)) + + transport.close() + self.loop.run_until_complete(protocol.done) + self.assertEqual('CLOSED', protocol.state) + + @mock.patch('asyncio.base_events.socket') + def test_create_datagram_endpoint_nosoreuseport(self, m_socket): + m_socket.getaddrinfo = socket.getaddrinfo + m_socket.SOCK_DGRAM = socket.SOCK_DGRAM + m_socket.SOL_SOCKET = socket.SOL_SOCKET + del m_socket.SO_REUSEPORT + m_socket.socket.return_value = mock.Mock() + + coro = self.loop.create_datagram_endpoint( + lambda: MyDatagramProto(loop=self.loop), + local_addr=('127.0.0.1', 0), + reuse_address=False, + reuse_port=True) + + self.assertRaises(ValueError, self.loop.run_until_complete, coro) + def test_accept_connection_retry(self): - sock = unittest.mock.Mock() + sock = mock.Mock() sock.accept.side_effect = BlockingIOError() self.loop._accept_connection(MyProto, sock) self.assertFalse(sock.close.called) - @unittest.mock.patch('asyncio.selector_events.logger') + @mock.patch('asyncio.base_events.logger') def test_accept_connection_exception(self, m_log): - sock = unittest.mock.Mock() + sock = mock.Mock() sock.fileno.return_value = 10 sock.accept.side_effect = OSError(errno.EMFILE, 'Too many open files') - self.loop.remove_reader = unittest.mock.Mock() - self.loop.call_later = unittest.mock.Mock() + self.loop.remove_reader = mock.Mock() + self.loop.call_later = mock.Mock() self.loop._accept_connection(MyProto, sock) - self.assertTrue(m_log.exception.called) + self.assertTrue(m_log.error.called) self.assertFalse(sock.close.called) self.loop.remove_reader.assert_called_with(10) self.loop.call_later.assert_called_with(constants.ACCEPT_RETRY_DELAY, # self.loop._start_serving - unittest.mock.ANY, + mock.ANY, MyProto, sock, None, None) + def test_call_coroutine(self): + @asyncio.coroutine + def simple_coroutine(): + pass + + coro_func = simple_coroutine + coro_obj = coro_func() + self.addCleanup(coro_obj.close) + for func in (coro_func, coro_obj): + with self.assertRaises(TypeError): + self.loop.call_soon(func) + with self.assertRaises(TypeError): + self.loop.call_soon_threadsafe(func) + with self.assertRaises(TypeError): + self.loop.call_later(60, func) + with self.assertRaises(TypeError): + self.loop.call_at(self.loop.time() + 60, func) + with self.assertRaises(TypeError): + self.loop.run_in_executor(None, func) + + @mock.patch('asyncio.base_events.logger') + def test_log_slow_callbacks(self, m_logger): + def stop_loop_cb(loop): + loop.stop() + + @asyncio.coroutine + def stop_loop_coro(loop): + yield from () + loop.stop() + + asyncio.set_event_loop(self.loop) + self.loop.set_debug(True) + self.loop.slow_callback_duration = 0.0 + + # slow callback + self.loop.call_soon(stop_loop_cb, self.loop) + self.loop.run_forever() + fmt, *args = m_logger.warning.call_args[0] + self.assertRegex(fmt % tuple(args), + "^Executing " + "took .* seconds$") + + # slow task + asyncio.ensure_future(stop_loop_coro(self.loop), loop=self.loop) + self.loop.run_forever() + fmt, *args = m_logger.warning.call_args[0] + self.assertRegex(fmt % tuple(args), + "^Executing " + "took .* seconds$") + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index 18411ecc246b..141fde74e6bd 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -4,6 +4,8 @@ import gc import io import os +import platform +import re import signal import socket try: @@ -16,34 +18,76 @@ import time import errno import unittest -import unittest.mock -from test.support import find_unused_port, IPV6_ENABLED +from unittest import mock +import weakref -from asyncio import futures -from asyncio import events -from asyncio import transports -from asyncio import protocols +import asyncio +from asyncio import proactor_events from asyncio import selector_events -from asyncio import tasks +from asyncio import sslproto from asyncio import test_utils -from asyncio import locks - - -class MyProto(protocols.Protocol): +try: + from test import support +except ImportError: + from asyncio import test_support as support + + +def data_file(filename): + if hasattr(support, 'TEST_HOME_DIR'): + fullname = os.path.join(support.TEST_HOME_DIR, filename) + if os.path.isfile(fullname): + return fullname + fullname = os.path.join(os.path.dirname(__file__), filename) + if os.path.isfile(fullname): + return fullname + raise FileNotFoundError(filename) + + +def osx_tiger(): + """Return True if the platform is Mac OS 10.4 or older.""" + if sys.platform != 'darwin': + return False + version = platform.mac_ver()[0] + version = tuple(map(int, version.split('.'))) + return version < (10, 5) + + +ONLYCERT = data_file('ssl_cert.pem') +ONLYKEY = data_file('ssl_key.pem') +SIGNED_CERTFILE = data_file('keycert3.pem') +SIGNING_CA = data_file('pycacert.pem') +PEERCERT = {'serialNumber': 'B09264B1F2DA21D1', + 'version': 1, + 'subject': ((('countryName', 'XY'),), + (('localityName', 'Castle Anthrax'),), + (('organizationName', 'Python Software Foundation'),), + (('commonName', 'localhost'),)), + 'issuer': ((('countryName', 'XY'),), + (('organizationName', 'Python Software Foundation CA'),), + (('commonName', 'our-ca-server'),)), + 'notAfter': 'Nov 13 19:47:07 2022 GMT', + 'notBefore': 'Jan 4 19:47:07 2013 GMT'} + + +class MyBaseProto(asyncio.Protocol): + connected = None done = None def __init__(self, loop=None): + self.transport = None self.state = 'INITIAL' self.nbytes = 0 if loop is not None: - self.done = futures.Future(loop=loop) + self.connected = asyncio.Future(loop=loop) + self.done = asyncio.Future(loop=loop) def connection_made(self, transport): self.transport = transport assert self.state == 'INITIAL', self.state self.state = 'CONNECTED' - transport.write(b'GET / HTTP/1.0\r\nHost: example.com\r\n\r\n') + if self.connected: + self.connected.set_result(None) def data_received(self, data): assert self.state == 'CONNECTED', self.state @@ -60,14 +104,20 @@ def connection_lost(self, exc): self.done.set_result(None) -class MyDatagramProto(protocols.DatagramProtocol): +class MyProto(MyBaseProto): + def connection_made(self, transport): + super().connection_made(transport) + transport.write(b'GET / HTTP/1.0\r\nHost: example.com\r\n\r\n') + + +class MyDatagramProto(asyncio.DatagramProtocol): done = None def __init__(self, loop=None): self.state = 'INITIAL' self.nbytes = 0 if loop is not None: - self.done = futures.Future(loop=loop) + self.done = asyncio.Future(loop=loop) def connection_made(self, transport): self.transport = transport @@ -88,7 +138,7 @@ def connection_lost(self, exc): self.done.set_result(None) -class MyReadPipeProto(protocols.Protocol): +class MyReadPipeProto(asyncio.Protocol): done = None def __init__(self, loop=None): @@ -96,7 +146,7 @@ def __init__(self, loop=None): self.nbytes = 0 self.transport = None if loop is not None: - self.done = futures.Future(loop=loop) + self.done = asyncio.Future(loop=loop) def connection_made(self, transport): self.transport = transport @@ -112,20 +162,22 @@ def eof_received(self): self.state.append('EOF') def connection_lost(self, exc): + if 'EOF' not in self.state: + self.state.append('EOF') # It is okay if EOF is missed. assert self.state == ['INITIAL', 'CONNECTED', 'EOF'], self.state self.state.append('CLOSED') if self.done: self.done.set_result(None) -class MyWritePipeProto(protocols.BaseProtocol): +class MyWritePipeProto(asyncio.BaseProtocol): done = None def __init__(self, loop=None): self.state = 'INITIAL' self.transport = None if loop is not None: - self.done = futures.Future(loop=loop) + self.done = asyncio.Future(loop=loop) def connection_made(self, transport): self.transport = transport @@ -139,18 +191,18 @@ def connection_lost(self, exc): self.done.set_result(None) -class MySubprocessProtocol(protocols.SubprocessProtocol): +class MySubprocessProtocol(asyncio.SubprocessProtocol): def __init__(self, loop): self.state = 'INITIAL' self.transport = None - self.connected = futures.Future(loop=loop) - self.completed = futures.Future(loop=loop) - self.disconnects = {fd: futures.Future(loop=loop) for fd in range(3)} + self.connected = asyncio.Future(loop=loop) + self.completed = asyncio.Future(loop=loop) + self.disconnects = {fd: asyncio.Future(loop=loop) for fd in range(3)} self.data = {1: b'', 2: b''} self.returncode = None - self.got_data = {1: locks.Event(loop=loop), - 2: locks.Event(loop=loop)} + self.got_data = {1: asyncio.Event(loop=loop), + 2: asyncio.Event(loop=loop)} def connection_made(self, transport): self.transport = transport @@ -185,22 +237,23 @@ class EventLoopTestsMixin: def setUp(self): super().setUp() self.loop = self.create_event_loop() - events.set_event_loop(None) + self.set_event_loop(self.loop) def tearDown(self): # just in case if we have transport close callbacks - test_utils.run_briefly(self.loop) + if not self.loop.is_closed(): + test_utils.run_briefly(self.loop) self.loop.close() gc.collect() super().tearDown() def test_run_until_complete_nesting(self): - @tasks.coroutine + @asyncio.coroutine def coro1(): yield - @tasks.coroutine + @asyncio.coroutine def coro2(): self.assertTrue(self.loop.is_running()) self.loop.run_until_complete(coro1()) @@ -213,15 +266,15 @@ def coro2(): def test_run_until_complete(self): t0 = self.loop.time() - self.loop.run_until_complete(tasks.sleep(0.1, loop=self.loop)) + self.loop.run_until_complete(asyncio.sleep(0.1, loop=self.loop)) t1 = self.loop.time() self.assertTrue(0.08 <= t1-t0 <= 0.8, t1-t0) def test_run_until_complete_stopped(self): - @tasks.coroutine + @asyncio.coroutine def cb(): self.loop.stop() - yield from tasks.sleep(0.1, loop=self.loop) + yield from asyncio.sleep(0.1, loop=self.loop) task = cb() self.assertRaises(RuntimeError, self.loop.run_until_complete, task) @@ -297,7 +350,8 @@ def run(arg): def test_reader_callback(self): r, w = test_utils.socketpair() - bytes_read = [] + r.setblocking(False) + bytes_read = bytearray() def reader(): try: @@ -307,54 +361,84 @@ def reader(): # at least on Linux -- see man select. return if data: - bytes_read.append(data) + bytes_read.extend(data) else: self.assertTrue(self.loop.remove_reader(r.fileno())) r.close() self.loop.add_reader(r.fileno(), reader) self.loop.call_soon(w.send, b'abc') - test_utils.run_briefly(self.loop) + test_utils.run_until(self.loop, lambda: len(bytes_read) >= 3) self.loop.call_soon(w.send, b'def') - test_utils.run_briefly(self.loop) + test_utils.run_until(self.loop, lambda: len(bytes_read) >= 6) self.loop.call_soon(w.close) self.loop.call_soon(self.loop.stop) self.loop.run_forever() - self.assertEqual(b''.join(bytes_read), b'abcdef') + self.assertEqual(bytes_read, b'abcdef') def test_writer_callback(self): r, w = test_utils.socketpair() w.setblocking(False) - self.loop.add_writer(w.fileno(), w.send, b'x'*(256*1024)) - test_utils.run_briefly(self.loop) - def remove_writer(): - self.assertTrue(self.loop.remove_writer(w.fileno())) + def writer(data): + w.send(data) + self.loop.stop() - self.loop.call_soon(remove_writer) - self.loop.call_soon(self.loop.stop) + data = b'x' * 1024 + self.loop.add_writer(w.fileno(), writer, data) self.loop.run_forever() + + self.assertTrue(self.loop.remove_writer(w.fileno())) + self.assertFalse(self.loop.remove_writer(w.fileno())) + w.close() - data = r.recv(256*1024) + read = r.recv(len(data) * 2) r.close() - self.assertGreaterEqual(len(data), 200) + self.assertEqual(read, data) + + def _basetest_sock_client_ops(self, httpd, sock): + if not isinstance(self.loop, proactor_events.BaseProactorEventLoop): + # in debug mode, socket operations must fail + # if the socket is not in blocking mode + self.loop.set_debug(True) + sock.setblocking(True) + with self.assertRaises(ValueError): + self.loop.run_until_complete( + self.loop.sock_connect(sock, httpd.address)) + with self.assertRaises(ValueError): + self.loop.run_until_complete( + self.loop.sock_sendall(sock, b'GET / HTTP/1.0\r\n\r\n')) + with self.assertRaises(ValueError): + self.loop.run_until_complete( + self.loop.sock_recv(sock, 1024)) + with self.assertRaises(ValueError): + self.loop.run_until_complete( + self.loop.sock_accept(sock)) + + # test in non-blocking mode + sock.setblocking(False) + self.loop.run_until_complete( + self.loop.sock_connect(sock, httpd.address)) + self.loop.run_until_complete( + self.loop.sock_sendall(sock, b'GET / HTTP/1.0\r\n\r\n')) + data = self.loop.run_until_complete( + self.loop.sock_recv(sock, 1024)) + # consume data + self.loop.run_until_complete( + self.loop.sock_recv(sock, 1024)) + sock.close() + self.assertTrue(data.startswith(b'HTTP/1.0 200 OK')) def test_sock_client_ops(self): with test_utils.run_test_server() as httpd: sock = socket.socket() - sock.setblocking(False) - self.loop.run_until_complete( - self.loop.sock_connect(sock, httpd.address)) - self.loop.run_until_complete( - self.loop.sock_sendall(sock, b'GET / HTTP/1.0\r\n\r\n')) - data = self.loop.run_until_complete( - self.loop.sock_recv(sock, 1024)) - # consume data - self.loop.run_until_complete( - self.loop.sock_recv(sock, 1024)) - sock.close() + self._basetest_sock_client_ops(httpd, sock) - self.assertTrue(data.startswith(b'HTTP/1.0 200 OK')) + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_unix_sock_client_ops(self): + with test_utils.run_test_unix_server() as httpd: + sock = socket.socket(socket.AF_UNIX) + self._basetest_sock_client_ops(httpd, sock) def test_sock_client_fail(self): # Make sure that we will get an unused port @@ -423,10 +507,10 @@ def my_handler(): self.assertFalse(self.loop.remove_signal_handler(signal.SIGKILL)) # Now set a handler and handle it. self.loop.add_signal_handler(signal.SIGINT, my_handler) - test_utils.run_briefly(self.loop) + os.kill(os.getpid(), signal.SIGINT) - test_utils.run_briefly(self.loop) - self.assertEqual(caught, 1) + test_utils.run_until(self.loop, lambda: caught) + # Removing it should restore the default handler. self.assertTrue(self.loop.remove_signal_handler(signal.SIGINT)) self.assertEqual(signal.getsignal(signal.SIGINT), @@ -467,16 +551,33 @@ def my_handler(*args): self.loop.run_forever() self.assertEqual(caught, 1) + def _basetest_create_connection(self, connection_fut, check_sockname=True): + tr, pr = self.loop.run_until_complete(connection_fut) + self.assertIsInstance(tr, asyncio.Transport) + self.assertIsInstance(pr, asyncio.Protocol) + self.assertIs(pr.transport, tr) + if check_sockname: + self.assertIsNotNone(tr.get_extra_info('sockname')) + self.loop.run_until_complete(pr.done) + self.assertGreater(pr.nbytes, 0) + tr.close() + def test_create_connection(self): with test_utils.run_test_server() as httpd: - f = self.loop.create_connection( + conn_fut = self.loop.create_connection( lambda: MyProto(loop=self.loop), *httpd.address) - tr, pr = self.loop.run_until_complete(f) - self.assertIsInstance(tr, transports.Transport) - self.assertIsInstance(pr, protocols.Protocol) - self.loop.run_until_complete(pr.done) - self.assertGreater(pr.nbytes, 0) - tr.close() + self._basetest_create_connection(conn_fut) + + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_create_unix_connection(self): + # Issue #20682: On Mac OS X Tiger, getsockname() returns a + # zero-length address for UNIX socket. + check_sockname = not osx_tiger() + + with test_utils.run_test_unix_server() as httpd: + conn_fut = self.loop.create_unix_connection( + lambda: MyProto(loop=self.loop), httpd.address) + self._basetest_create_connection(conn_fut, check_sockname) def test_create_connection_sock(self): with test_utils.run_test_server() as httpd: @@ -500,30 +601,131 @@ def test_create_connection_sock(self): f = self.loop.create_connection( lambda: MyProto(loop=self.loop), sock=sock) tr, pr = self.loop.run_until_complete(f) - self.assertIsInstance(tr, transports.Transport) - self.assertIsInstance(pr, protocols.Protocol) + self.assertIsInstance(tr, asyncio.Transport) + self.assertIsInstance(pr, asyncio.Protocol) self.loop.run_until_complete(pr.done) self.assertGreater(pr.nbytes, 0) tr.close() + def check_ssl_extra_info(self, client, check_sockname=True, + peername=None, peercert={}): + if check_sockname: + self.assertIsNotNone(client.get_extra_info('sockname')) + if peername: + self.assertEqual(peername, + client.get_extra_info('peername')) + else: + self.assertIsNotNone(client.get_extra_info('peername')) + self.assertEqual(peercert, + client.get_extra_info('peercert')) + + # test SSL cipher + cipher = client.get_extra_info('cipher') + self.assertIsInstance(cipher, tuple) + self.assertEqual(len(cipher), 3, cipher) + self.assertIsInstance(cipher[0], str) + self.assertIsInstance(cipher[1], str) + self.assertIsInstance(cipher[2], int) + + # test SSL object + sslobj = client.get_extra_info('ssl_object') + self.assertIsNotNone(sslobj) + self.assertEqual(sslobj.compression(), + client.get_extra_info('compression')) + self.assertEqual(sslobj.cipher(), + client.get_extra_info('cipher')) + self.assertEqual(sslobj.getpeercert(), + client.get_extra_info('peercert')) + self.assertEqual(sslobj.compression(), + client.get_extra_info('compression')) + + def _basetest_create_ssl_connection(self, connection_fut, + check_sockname=True, + peername=None): + tr, pr = self.loop.run_until_complete(connection_fut) + self.assertIsInstance(tr, asyncio.Transport) + self.assertIsInstance(pr, asyncio.Protocol) + self.assertTrue('ssl' in tr.__class__.__name__.lower()) + self.check_ssl_extra_info(tr, check_sockname, peername) + self.loop.run_until_complete(pr.done) + self.assertGreater(pr.nbytes, 0) + tr.close() + + def _test_create_ssl_connection(self, httpd, create_connection, + check_sockname=True, peername=None): + conn_fut = create_connection(ssl=test_utils.dummy_ssl_context()) + self._basetest_create_ssl_connection(conn_fut, check_sockname, + peername) + + # ssl.Purpose was introduced in Python 3.4 + if hasattr(ssl, 'Purpose'): + def _dummy_ssl_create_context(purpose=ssl.Purpose.SERVER_AUTH, *, + cafile=None, capath=None, + cadata=None): + """ + A ssl.create_default_context() replacement that doesn't enable + cert validation. + """ + self.assertEqual(purpose, ssl.Purpose.SERVER_AUTH) + return test_utils.dummy_ssl_context() + + # With ssl=True, ssl.create_default_context() should be called + with mock.patch('ssl.create_default_context', + side_effect=_dummy_ssl_create_context) as m: + conn_fut = create_connection(ssl=True) + self._basetest_create_ssl_connection(conn_fut, check_sockname, + peername) + self.assertEqual(m.call_count, 1) + + # With the real ssl.create_default_context(), certificate + # validation will fail + with self.assertRaises(ssl.SSLError) as cm: + conn_fut = create_connection(ssl=True) + # Ignore the "SSL handshake failed" log in debug mode + with test_utils.disable_logger(): + self._basetest_create_ssl_connection(conn_fut, check_sockname, + peername) + + self.assertEqual(cm.exception.reason, 'CERTIFICATE_VERIFY_FAILED') + @unittest.skipIf(ssl is None, 'No ssl module') def test_create_ssl_connection(self): with test_utils.run_test_server(use_ssl=True) as httpd: - f = self.loop.create_connection( - lambda: MyProto(loop=self.loop), *httpd.address, - ssl=test_utils.dummy_ssl_context()) - tr, pr = self.loop.run_until_complete(f) - self.assertIsInstance(tr, transports.Transport) - self.assertIsInstance(pr, protocols.Protocol) - self.assertTrue('ssl' in tr.__class__.__name__.lower()) - self.assertIsNotNone(tr.get_extra_info('sockname')) - self.loop.run_until_complete(pr.done) - self.assertGreater(pr.nbytes, 0) - tr.close() + create_connection = functools.partial( + self.loop.create_connection, + lambda: MyProto(loop=self.loop), + *httpd.address) + self._test_create_ssl_connection(httpd, create_connection, + peername=httpd.address) + + def test_legacy_create_ssl_connection(self): + with test_utils.force_legacy_ssl_support(): + self.test_create_ssl_connection() + + @unittest.skipIf(ssl is None, 'No ssl module') + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_create_ssl_unix_connection(self): + # Issue #20682: On Mac OS X Tiger, getsockname() returns a + # zero-length address for UNIX socket. + check_sockname = not osx_tiger() + + with test_utils.run_test_unix_server(use_ssl=True) as httpd: + create_connection = functools.partial( + self.loop.create_unix_connection, + lambda: MyProto(loop=self.loop), httpd.address, + server_hostname='127.0.0.1') + + self._test_create_ssl_connection(httpd, create_connection, + check_sockname, + peername=httpd.address) + + def test_legacy_create_ssl_unix_connection(self): + with test_utils.force_legacy_ssl_support(): + self.test_create_ssl_unix_connection() def test_create_connection_local_addr(self): with test_utils.run_test_server() as httpd: - port = find_unused_port() + port = support.find_unused_port() f = self.loop.create_connection( lambda: MyProto(loop=self.loop), *httpd.address, local_addr=(httpd.address[0], port)) @@ -542,15 +744,43 @@ def test_create_connection_local_addr_in_use(self): self.assertEqual(cm.exception.errno, errno.EADDRINUSE) self.assertIn(str(httpd.address), cm.exception.strerror) - def test_create_server(self): - proto = None + @mock.patch('asyncio.base_events.socket') + def create_server_multiple_hosts(self, family, hosts, mock_sock): + @asyncio.coroutine + def getaddrinfo(host, port, *args, **kw): + if family == socket.AF_INET: + return [[family, socket.SOCK_STREAM, 6, '', (host, port)]] + else: + return [[family, socket.SOCK_STREAM, 6, '', (host, port, 0, 0)]] - def factory(): - nonlocal proto - proto = MyProto() - return proto + def getaddrinfo_task(*args, **kwds): + return asyncio.Task(getaddrinfo(*args, **kwds), loop=self.loop) - f = self.loop.create_server(factory, '0.0.0.0', 0) + if family == socket.AF_INET: + mock_sock.socket().getsockbyname.side_effect = [(host, 80) + for host in hosts] + else: + mock_sock.socket().getsockbyname.side_effect = [(host, 80, 0, 0) + for host in hosts] + self.loop.getaddrinfo = getaddrinfo_task + self.loop._start_serving = mock.Mock() + self.loop._stop_serving = mock.Mock() + f = self.loop.create_server(lambda: MyProto(self.loop), hosts, 80) + server = self.loop.run_until_complete(f) + self.addCleanup(server.close) + server_hosts = [sock.getsockbyname()[0] for sock in server.sockets] + self.assertEqual(server_hosts, hosts) + + def test_create_server_multiple_hosts_ipv4(self): + self.create_server_multiple_hosts(socket.AF_INET, + ['1.2.3.4', '5.6.7.8']) + + def test_create_server_multiple_hosts_ipv6(self): + self.create_server_multiple_hosts(socket.AF_INET6, ['::1', '::2']) + + def test_create_server(self): + proto = MyProto(self.loop) + f = self.loop.create_server(lambda: proto, '0.0.0.0', 0) server = self.loop.run_until_complete(f) self.assertEqual(len(server.sockets), 1) sock = server.sockets[0] @@ -559,14 +789,11 @@ def factory(): client = socket.socket() client.connect(('127.0.0.1', port)) client.sendall(b'xxx') - test_utils.run_briefly(self.loop) - test_utils.run_until(self.loop, lambda: proto is not None, 10) - self.assertIsInstance(proto, MyProto) - self.assertEqual('INITIAL', proto.state) - test_utils.run_briefly(self.loop) + + self.loop.run_until_complete(proto.connected) self.assertEqual('CONNECTED', proto.state) - test_utils.run_until(self.loop, lambda: proto.nbytes > 0, - timeout=10) + + test_utils.run_until(self.loop, lambda: proto.nbytes > 0) self.assertEqual(3, proto.nbytes) # extra info is available @@ -576,7 +803,7 @@ def factory(): # close connection proto.transport.close() - test_utils.run_briefly(self.loop) # windows iocp + self.loop.run_until_complete(proto.done) self.assertEqual('CLOSED', proto.state) @@ -587,52 +814,120 @@ def factory(): # close server server.close() - @unittest.skipIf(ssl is None, 'No ssl module') - def test_create_server_ssl(self): - proto = None + @unittest.skipUnless(hasattr(socket, 'SO_REUSEPORT'), 'No SO_REUSEPORT') + def test_create_server_reuse_port(self): + proto = MyProto(self.loop) + f = self.loop.create_server( + lambda: proto, '0.0.0.0', 0) + server = self.loop.run_until_complete(f) + self.assertEqual(len(server.sockets), 1) + sock = server.sockets[0] + self.assertFalse( + sock.getsockopt( + socket.SOL_SOCKET, socket.SO_REUSEPORT)) + server.close() - class ClientMyProto(MyProto): - def connection_made(self, transport): - self.transport = transport - assert self.state == 'INITIAL', self.state - self.state = 'CONNECTED' + test_utils.run_briefly(self.loop) - def factory(): - nonlocal proto - proto = MyProto(loop=self.loop) - return proto + proto = MyProto(self.loop) + f = self.loop.create_server( + lambda: proto, '0.0.0.0', 0, reuse_port=True) + server = self.loop.run_until_complete(f) + self.assertEqual(len(server.sockets), 1) + sock = server.sockets[0] + self.assertTrue( + sock.getsockopt( + socket.SOL_SOCKET, socket.SO_REUSEPORT)) + server.close() + + def _make_unix_server(self, factory, **kwargs): + path = test_utils.gen_unix_socket_path() + self.addCleanup(lambda: os.path.exists(path) and os.unlink(path)) + + f = self.loop.create_unix_server(factory, path, **kwargs) + server = self.loop.run_until_complete(f) - here = os.path.dirname(__file__) + return server, path + + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_create_unix_server(self): + proto = MyProto(loop=self.loop) + server, path = self._make_unix_server(lambda: proto) + self.assertEqual(len(server.sockets), 1) + + client = socket.socket(socket.AF_UNIX) + client.connect(path) + client.sendall(b'xxx') + + self.loop.run_until_complete(proto.connected) + self.assertEqual('CONNECTED', proto.state) + test_utils.run_until(self.loop, lambda: proto.nbytes > 0) + self.assertEqual(3, proto.nbytes) + + # close connection + proto.transport.close() + self.loop.run_until_complete(proto.done) + + self.assertEqual('CLOSED', proto.state) + + # the client socket must be closed after to avoid ECONNRESET upon + # recv()/send() on the serving socket + client.close() + + # close server + server.close() + + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_create_unix_server_path_socket_error(self): + proto = MyProto(loop=self.loop) + sock = socket.socket() + with sock: + f = self.loop.create_unix_server(lambda: proto, '/test', sock=sock) + with self.assertRaisesRegex(ValueError, + 'path and sock can not be specified ' + 'at the same time'): + self.loop.run_until_complete(f) + + def _create_ssl_context(self, certfile, keyfile=None): sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) - sslcontext.load_cert_chain( - certfile=os.path.join(here, 'sample.crt'), - keyfile=os.path.join(here, 'sample.key')) + sslcontext.options |= ssl.OP_NO_SSLv2 + sslcontext.load_cert_chain(certfile, keyfile) + return sslcontext - f = self.loop.create_server( - factory, '127.0.0.1', 0, ssl=sslcontext) + def _make_ssl_server(self, factory, certfile, keyfile=None): + sslcontext = self._create_ssl_context(certfile, keyfile) + f = self.loop.create_server(factory, '127.0.0.1', 0, ssl=sslcontext) server = self.loop.run_until_complete(f) + sock = server.sockets[0] host, port = sock.getsockname() self.assertEqual(host, '127.0.0.1') + return server, host, port + + def _make_ssl_unix_server(self, factory, certfile, keyfile=None): + sslcontext = self._create_ssl_context(certfile, keyfile) + return self._make_unix_server(factory, ssl=sslcontext) + + @unittest.skipIf(ssl is None, 'No ssl module') + def test_create_server_ssl(self): + proto = MyProto(loop=self.loop) + server, host, port = self._make_ssl_server( + lambda: proto, ONLYCERT, ONLYKEY) - f_c = self.loop.create_connection(ClientMyProto, host, port, + f_c = self.loop.create_connection(MyBaseProto, host, port, ssl=test_utils.dummy_ssl_context()) client, pr = self.loop.run_until_complete(f_c) client.write(b'xxx') - test_utils.run_briefly(self.loop) - self.assertIsInstance(proto, MyProto) - test_utils.run_briefly(self.loop) + self.loop.run_until_complete(proto.connected) self.assertEqual('CONNECTED', proto.state) - test_utils.run_until(self.loop, lambda: proto.nbytes > 0, - timeout=10) + + test_utils.run_until(self.loop, lambda: proto.nbytes > 0) self.assertEqual(3, proto.nbytes) # extra info is available - self.assertIsNotNone(proto.transport.get_extra_info('sockname')) - self.assertEqual('127.0.0.1', - proto.transport.get_extra_info('peername')[0]) + self.check_ssl_extra_info(client, peername=(host, port)) # close connection proto.transport.close() @@ -646,8 +941,210 @@ def factory(): # stop serving server.close() + def test_legacy_create_server_ssl(self): + with test_utils.force_legacy_ssl_support(): + self.test_create_server_ssl() + + @unittest.skipIf(ssl is None, 'No ssl module') + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_create_unix_server_ssl(self): + proto = MyProto(loop=self.loop) + server, path = self._make_ssl_unix_server( + lambda: proto, ONLYCERT, ONLYKEY) + + f_c = self.loop.create_unix_connection( + MyBaseProto, path, ssl=test_utils.dummy_ssl_context(), + server_hostname='') + + client, pr = self.loop.run_until_complete(f_c) + + client.write(b'xxx') + self.loop.run_until_complete(proto.connected) + self.assertEqual('CONNECTED', proto.state) + test_utils.run_until(self.loop, lambda: proto.nbytes > 0) + self.assertEqual(3, proto.nbytes) + + # close connection + proto.transport.close() + self.loop.run_until_complete(proto.done) + self.assertEqual('CLOSED', proto.state) + + # the client socket must be closed after to avoid ECONNRESET upon + # recv()/send() on the serving socket + client.close() + + # stop serving + server.close() + + def test_legacy_create_unix_server_ssl(self): + with test_utils.force_legacy_ssl_support(): + self.test_create_unix_server_ssl() + + @unittest.skipIf(ssl is None, 'No ssl module') + def test_create_server_ssl_verify_failed(self): + proto = MyProto(loop=self.loop) + server, host, port = self._make_ssl_server( + lambda: proto, SIGNED_CERTFILE) + + sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + sslcontext_client.options |= ssl.OP_NO_SSLv2 + sslcontext_client.verify_mode = ssl.CERT_REQUIRED + if hasattr(sslcontext_client, 'check_hostname'): + sslcontext_client.check_hostname = True + + + # no CA loaded + f_c = self.loop.create_connection(MyProto, host, port, + ssl=sslcontext_client) + with mock.patch.object(self.loop, 'call_exception_handler'): + with test_utils.disable_logger(): + with self.assertRaisesRegex(ssl.SSLError, + 'certificate verify failed '): + self.loop.run_until_complete(f_c) + + # execute the loop to log the connection error + test_utils.run_briefly(self.loop) + + # close connection + self.assertIsNone(proto.transport) + server.close() + + def test_legacy_create_server_ssl_verify_failed(self): + with test_utils.force_legacy_ssl_support(): + self.test_create_server_ssl_verify_failed() + + @unittest.skipIf(ssl is None, 'No ssl module') + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_create_unix_server_ssl_verify_failed(self): + proto = MyProto(loop=self.loop) + server, path = self._make_ssl_unix_server( + lambda: proto, SIGNED_CERTFILE) + + sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + sslcontext_client.options |= ssl.OP_NO_SSLv2 + sslcontext_client.verify_mode = ssl.CERT_REQUIRED + if hasattr(sslcontext_client, 'check_hostname'): + sslcontext_client.check_hostname = True + + # no CA loaded + f_c = self.loop.create_unix_connection(MyProto, path, + ssl=sslcontext_client, + server_hostname='invalid') + with mock.patch.object(self.loop, 'call_exception_handler'): + with test_utils.disable_logger(): + with self.assertRaisesRegex(ssl.SSLError, + 'certificate verify failed '): + self.loop.run_until_complete(f_c) + + # execute the loop to log the connection error + test_utils.run_briefly(self.loop) + + # close connection + self.assertIsNone(proto.transport) + server.close() + + + def test_legacy_create_unix_server_ssl_verify_failed(self): + with test_utils.force_legacy_ssl_support(): + self.test_create_unix_server_ssl_verify_failed() + + @unittest.skipIf(ssl is None, 'No ssl module') + def test_create_server_ssl_match_failed(self): + proto = MyProto(loop=self.loop) + server, host, port = self._make_ssl_server( + lambda: proto, SIGNED_CERTFILE) + + sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + sslcontext_client.options |= ssl.OP_NO_SSLv2 + sslcontext_client.verify_mode = ssl.CERT_REQUIRED + sslcontext_client.load_verify_locations( + cafile=SIGNING_CA) + if hasattr(sslcontext_client, 'check_hostname'): + sslcontext_client.check_hostname = True + + # incorrect server_hostname + f_c = self.loop.create_connection(MyProto, host, port, + ssl=sslcontext_client) + with mock.patch.object(self.loop, 'call_exception_handler'): + with test_utils.disable_logger(): + with self.assertRaisesRegex( + ssl.CertificateError, + "hostname '127.0.0.1' doesn't match 'localhost'"): + self.loop.run_until_complete(f_c) + + # close connection + proto.transport.close() + server.close() + + def test_legacy_create_server_ssl_match_failed(self): + with test_utils.force_legacy_ssl_support(): + self.test_create_server_ssl_match_failed() + + @unittest.skipIf(ssl is None, 'No ssl module') + @unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'No UNIX Sockets') + def test_create_unix_server_ssl_verified(self): + proto = MyProto(loop=self.loop) + server, path = self._make_ssl_unix_server( + lambda: proto, SIGNED_CERTFILE) + + sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + sslcontext_client.options |= ssl.OP_NO_SSLv2 + sslcontext_client.verify_mode = ssl.CERT_REQUIRED + sslcontext_client.load_verify_locations(cafile=SIGNING_CA) + if hasattr(sslcontext_client, 'check_hostname'): + sslcontext_client.check_hostname = True + + # Connection succeeds with correct CA and server hostname. + f_c = self.loop.create_unix_connection(MyProto, path, + ssl=sslcontext_client, + server_hostname='localhost') + client, pr = self.loop.run_until_complete(f_c) + + # close connection + proto.transport.close() + client.close() + server.close() + self.loop.run_until_complete(proto.done) + + def test_legacy_create_unix_server_ssl_verified(self): + with test_utils.force_legacy_ssl_support(): + self.test_create_unix_server_ssl_verified() + + @unittest.skipIf(ssl is None, 'No ssl module') + def test_create_server_ssl_verified(self): + proto = MyProto(loop=self.loop) + server, host, port = self._make_ssl_server( + lambda: proto, SIGNED_CERTFILE) + + sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + sslcontext_client.options |= ssl.OP_NO_SSLv2 + sslcontext_client.verify_mode = ssl.CERT_REQUIRED + sslcontext_client.load_verify_locations(cafile=SIGNING_CA) + if hasattr(sslcontext_client, 'check_hostname'): + sslcontext_client.check_hostname = True + + # Connection succeeds with correct CA and server hostname. + f_c = self.loop.create_connection(MyProto, host, port, + ssl=sslcontext_client, + server_hostname='localhost') + client, pr = self.loop.run_until_complete(f_c) + + # extra info is available + self.check_ssl_extra_info(client,peername=(host, port), + peercert=PEERCERT) + + # close connection + proto.transport.close() + client.close() + server.close() + self.loop.run_until_complete(proto.done) + + def test_legacy_create_server_ssl_verified(self): + with test_utils.force_legacy_ssl_support(): + self.test_create_server_ssl_verified() + def test_create_server_sock(self): - proto = futures.Future(loop=self.loop) + proto = asyncio.Future(loop=self.loop) class TestMyProto(MyProto): def connection_made(self, transport): @@ -688,9 +1185,9 @@ def test_create_server_addr_in_use(self): server.close() - @unittest.skipUnless(IPV6_ENABLED, 'IPv6 not supported or enabled') + @unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 not supported or enabled') def test_create_server_dual_stack(self): - f_proto = futures.Future(loop=self.loop) + f_proto = asyncio.Future(loop=self.loop) class TestMyProto(MyProto): def connection_made(self, transport): @@ -700,7 +1197,7 @@ def connection_made(self, transport): try_count = 0 while True: try: - port = find_unused_port() + port = support.find_unused_port() f = self.loop.create_server(TestMyProto, host=None, port=port) server = self.loop.run_until_complete(f) except OSError as ex: @@ -719,7 +1216,7 @@ def connection_made(self, transport): proto.transport.close() client.close() - f_proto = futures.Future(loop=self.loop) + f_proto = asyncio.Future(loop=self.loop) client = socket.socket(socket.AF_INET6) client.connect(('::1', port)) client.send(b'xxx') @@ -761,22 +1258,25 @@ def datagram_received(self, data, addr): s_transport, server = self.loop.run_until_complete(coro) host, port = s_transport.get_extra_info('sockname') + self.assertIsInstance(s_transport, asyncio.Transport) + self.assertIsInstance(server, TestMyDatagramProto) + self.assertEqual('INITIALIZED', server.state) + self.assertIs(server.transport, s_transport) + coro = self.loop.create_datagram_endpoint( lambda: MyDatagramProto(loop=self.loop), remote_addr=(host, port)) transport, client = self.loop.run_until_complete(coro) + self.assertIsInstance(transport, asyncio.Transport) + self.assertIsInstance(client, MyDatagramProto) self.assertEqual('INITIALIZED', client.state) + self.assertIs(client.transport, transport) + transport.sendto(b'xxx') - for _ in range(1000): - if server.nbytes: - break - test_utils.run_briefly(self.loop) + test_utils.run_until(self.loop, lambda: server.nbytes) self.assertEqual(3, server.nbytes) - for _ in range(1000): - if client.nbytes: - break - test_utils.run_briefly(self.loop) + test_utils.run_until(self.loop, lambda: client.nbytes) # received self.assertEqual(8, client.nbytes) @@ -790,10 +1290,37 @@ def datagram_received(self, data, addr): self.assertEqual('CLOSED', client.state) server.transport.close() + def test_create_datagram_endpoint_sock(self): + sock = None + local_address = ('127.0.0.1', 0) + infos = self.loop.run_until_complete( + self.loop.getaddrinfo( + *local_address, type=socket.SOCK_DGRAM)) + for family, type, proto, cname, address in infos: + try: + sock = socket.socket(family=family, type=type, proto=proto) + sock.setblocking(False) + sock.bind(address) + except: + pass + else: + break + else: + assert False, 'Can not create socket.' + + f = self.loop.create_connection( + lambda: MyDatagramProto(loop=self.loop), sock=sock) + tr, pr = self.loop.run_until_complete(f) + self.assertIsInstance(tr, asyncio.Transport) + self.assertIsInstance(pr, MyDatagramProto) + tr.close() + self.loop.run_until_complete(pr.done) + def test_internal_fds(self): loop = self.create_event_loop() if not isinstance(loop, selector_events.BaseSelectorEventLoop): - return + loop.close() + self.skipTest('loop is not a BaseSelectorEventLoop') self.assertEqual(1, loop._internal_fds) loop.close() @@ -804,19 +1331,15 @@ def test_internal_fds(self): @unittest.skipUnless(sys.platform != 'win32', "Don't support pipes for Windows") def test_read_pipe(self): - proto = None - - def factory(): - nonlocal proto - proto = MyReadPipeProto(loop=self.loop) - return proto + proto = MyReadPipeProto(loop=self.loop) rpipe, wpipe = os.pipe() pipeobj = io.open(rpipe, 'rb', 1024) - @tasks.coroutine + @asyncio.coroutine def connect(): - t, p = yield from self.loop.connect_read_pipe(factory, pipeobj) + t, p = yield from self.loop.connect_read_pipe( + lambda: proto, pipeobj) self.assertIs(p, proto) self.assertIs(t, proto.transport) self.assertEqual(['INITIAL', 'CONNECTED'], proto.state) @@ -825,11 +1348,11 @@ def connect(): self.loop.run_until_complete(connect()) os.write(wpipe, b'1') - test_utils.run_briefly(self.loop) + test_utils.run_until(self.loop, lambda: proto.nbytes >= 1) self.assertEqual(1, proto.nbytes) os.write(wpipe, b'2345') - test_utils.run_briefly(self.loop) + test_utils.run_until(self.loop, lambda: proto.nbytes >= 5) self.assertEqual(['INITIAL', 'CONNECTED'], proto.state) self.assertEqual(5, proto.nbytes) @@ -842,38 +1365,71 @@ def connect(): @unittest.skipUnless(sys.platform != 'win32', "Don't support pipes for Windows") - def test_write_pipe(self): - proto = None - transport = None - - def factory(): - nonlocal proto - proto = MyWritePipeProto(loop=self.loop) - return proto - - rpipe, wpipe = os.pipe() - pipeobj = io.open(wpipe, 'wb', 1024) - - @tasks.coroutine + # select, poll and kqueue don't support character devices (PTY) on Mac OS X + # older than 10.6 (Snow Leopard) + @support.requires_mac_ver(10, 6) + # Issue #20495: The test hangs on FreeBSD 7.2 but pass on FreeBSD 9 + @support.requires_freebsd_version(8) + def test_read_pty_output(self): + proto = MyReadPipeProto(loop=self.loop) + + master, slave = os.openpty() + master_read_obj = io.open(master, 'rb', 0) + + @asyncio.coroutine def connect(): - nonlocal transport - t, p = yield from self.loop.connect_write_pipe(factory, pipeobj) + t, p = yield from self.loop.connect_read_pipe(lambda: proto, + master_read_obj) self.assertIs(p, proto) self.assertIs(t, proto.transport) - self.assertEqual('CONNECTED', proto.state) - transport = t + self.assertEqual(['INITIAL', 'CONNECTED'], proto.state) + self.assertEqual(0, proto.nbytes) self.loop.run_until_complete(connect()) + os.write(slave, b'1') + test_utils.run_until(self.loop, lambda: proto.nbytes) + self.assertEqual(1, proto.nbytes) + + os.write(slave, b'2345') + test_utils.run_until(self.loop, lambda: proto.nbytes >= 5) + self.assertEqual(['INITIAL', 'CONNECTED'], proto.state) + self.assertEqual(5, proto.nbytes) + + os.close(slave) + self.loop.run_until_complete(proto.done) + self.assertEqual( + ['INITIAL', 'CONNECTED', 'EOF', 'CLOSED'], proto.state) + # extra info is available + self.assertIsNotNone(proto.transport.get_extra_info('pipe')) + + @unittest.skipUnless(sys.platform != 'win32', + "Don't support pipes for Windows") + def test_write_pipe(self): + rpipe, wpipe = os.pipe() + pipeobj = io.open(wpipe, 'wb', 1024) + + proto = MyWritePipeProto(loop=self.loop) + connect = self.loop.connect_write_pipe(lambda: proto, pipeobj) + transport, p = self.loop.run_until_complete(connect) + self.assertIs(p, proto) + self.assertIs(transport, proto.transport) + self.assertEqual('CONNECTED', proto.state) + transport.write(b'1') - test_utils.run_briefly(self.loop) - data = os.read(rpipe, 1024) + + data = bytearray() + def reader(data): + chunk = os.read(rpipe, 1024) + data += chunk + return len(data) + + test_utils.run_until(self.loop, lambda: reader(data) >= 1) self.assertEqual(b'1', data) transport.write(b'2345') - test_utils.run_briefly(self.loop) - data = os.read(rpipe, 1024) - self.assertEqual(b'2345', data) + test_utils.run_until(self.loop, lambda: reader(data) >= 5) + self.assertEqual(b'12345', data) self.assertEqual('CONNECTED', proto.state) os.close(rpipe) @@ -889,28 +1445,15 @@ def connect(): @unittest.skipUnless(sys.platform != 'win32', "Don't support pipes for Windows") def test_write_pipe_disconnect_on_close(self): - proto = None - transport = None - - def factory(): - nonlocal proto - proto = MyWritePipeProto(loop=self.loop) - return proto - rsock, wsock = test_utils.socketpair() + rsock.setblocking(False) pipeobj = io.open(wsock.detach(), 'wb', 1024) - @tasks.coroutine - def connect(): - nonlocal transport - t, p = yield from self.loop.connect_write_pipe(factory, - pipeobj) - self.assertIs(p, proto) - self.assertIs(t, proto.transport) - self.assertEqual('CONNECTED', proto.state) - transport = t - - self.loop.run_until_complete(connect()) + proto = MyWritePipeProto(loop=self.loop) + connect = self.loop.connect_write_pipe(lambda: proto, pipeobj) + transport, p = self.loop.run_until_complete(connect) + self.assertIs(p, proto) + self.assertIs(transport, proto.transport) self.assertEqual('CONNECTED', proto.state) transport.write(b'1') @@ -922,6 +1465,50 @@ def connect(): self.loop.run_until_complete(proto.done) self.assertEqual('CLOSED', proto.state) + @unittest.skipUnless(sys.platform != 'win32', + "Don't support pipes for Windows") + # select, poll and kqueue don't support character devices (PTY) on Mac OS X + # older than 10.6 (Snow Leopard) + @support.requires_mac_ver(10, 6) + def test_write_pty(self): + master, slave = os.openpty() + slave_write_obj = io.open(slave, 'wb', 0) + + proto = MyWritePipeProto(loop=self.loop) + connect = self.loop.connect_write_pipe(lambda: proto, slave_write_obj) + transport, p = self.loop.run_until_complete(connect) + self.assertIs(p, proto) + self.assertIs(transport, proto.transport) + self.assertEqual('CONNECTED', proto.state) + + transport.write(b'1') + + data = bytearray() + def reader(data): + chunk = os.read(master, 1024) + data += chunk + return len(data) + + test_utils.run_until(self.loop, lambda: reader(data) >= 1, + timeout=10) + self.assertEqual(b'1', data) + + transport.write(b'2345') + test_utils.run_until(self.loop, lambda: reader(data) >= 5, + timeout=10) + self.assertEqual(b'12345', data) + self.assertEqual('CONNECTED', proto.state) + + os.close(master) + + # extra info is available + self.assertIsNotNone(proto.transport.get_extra_info('pipe')) + + # close connection + proto.transport.close() + self.loop.run_until_complete(proto.done) + self.assertEqual('CLOSED', proto.state) + def test_prompt_cancellation(self): r, w = test_utils.socketpair() r.setblocking(False) @@ -930,12 +1517,12 @@ def test_prompt_cancellation(self): if ov is not None: self.assertTrue(ov.pending) - @tasks.coroutine + @asyncio.coroutine def main(): try: self.loop.call_soon(f.cancel) yield from f - except futures.CancelledError: + except asyncio.CancelledError: res = 'cancelled' else: res = None @@ -944,13 +1531,13 @@ def main(): return res start = time.monotonic() - t = tasks.Task(main(), loop=self.loop) + t = asyncio.Task(main(), loop=self.loop) self.loop.run_forever() elapsed = time.monotonic() - start self.assertLess(elapsed, 0.1) self.assertEqual(t.result(), 'cancelled') - self.assertRaises(futures.CancelledError, f.result) + self.assertRaises(asyncio.CancelledError, f.result) if ov is not None: self.assertFalse(ov.pending) self.loop._stop_serving(r) @@ -958,6 +1545,121 @@ def main(): r.close() w.close() + def test_timeout_rounding(self): + def _run_once(): + self.loop._run_once_counter += 1 + orig_run_once() + + orig_run_once = self.loop._run_once + self.loop._run_once_counter = 0 + self.loop._run_once = _run_once + + @asyncio.coroutine + def wait(): + loop = self.loop + yield from asyncio.sleep(1e-2, loop=loop) + yield from asyncio.sleep(1e-4, loop=loop) + yield from asyncio.sleep(1e-6, loop=loop) + yield from asyncio.sleep(1e-8, loop=loop) + yield from asyncio.sleep(1e-10, loop=loop) + + self.loop.run_until_complete(wait()) + # The ideal number of call is 12, but on some platforms, the selector + # may sleep at little bit less than timeout depending on the resolution + # of the clock used by the kernel. Tolerate a few useless calls on + # these platforms. + self.assertLessEqual(self.loop._run_once_counter, 20, + {'clock_resolution': self.loop._clock_resolution, + 'selector': self.loop._selector.__class__.__name__}) + + def test_sock_connect_address(self): + # In debug mode, sock_connect() must ensure that the address is already + # resolved (call _check_resolved_address()) + self.loop.set_debug(True) + + addresses = [(socket.AF_INET, ('www.python.org', 80))] + if support.IPV6_ENABLED: + addresses.extend(( + (socket.AF_INET6, ('www.python.org', 80)), + (socket.AF_INET6, ('www.python.org', 80, 0, 0)), + )) + + for family, address in addresses: + for sock_type in (socket.SOCK_STREAM, socket.SOCK_DGRAM): + sock = socket.socket(family, sock_type) + with sock: + sock.setblocking(False) + connect = self.loop.sock_connect(sock, address) + with self.assertRaises(ValueError) as cm: + self.loop.run_until_complete(connect) + self.assertIn('address must be resolved', + str(cm.exception)) + + def test_remove_fds_after_closing(self): + loop = self.create_event_loop() + callback = lambda: None + r, w = test_utils.socketpair() + self.addCleanup(r.close) + self.addCleanup(w.close) + loop.add_reader(r, callback) + loop.add_writer(w, callback) + loop.close() + self.assertFalse(loop.remove_reader(r)) + self.assertFalse(loop.remove_writer(w)) + + def test_add_fds_after_closing(self): + loop = self.create_event_loop() + callback = lambda: None + r, w = test_utils.socketpair() + self.addCleanup(r.close) + self.addCleanup(w.close) + loop.close() + with self.assertRaises(RuntimeError): + loop.add_reader(r, callback) + with self.assertRaises(RuntimeError): + loop.add_writer(w, callback) + + def test_close_running_event_loop(self): + @asyncio.coroutine + def close_loop(loop): + self.loop.close() + + coro = close_loop(self.loop) + with self.assertRaises(RuntimeError): + self.loop.run_until_complete(coro) + + def test_close(self): + self.loop.close() + + @asyncio.coroutine + def test(): + pass + + func = lambda: False + coro = test() + self.addCleanup(coro.close) + + # operation blocked when the loop is closed + with self.assertRaises(RuntimeError): + self.loop.run_forever() + with self.assertRaises(RuntimeError): + fut = asyncio.Future(loop=self.loop) + self.loop.run_until_complete(fut) + with self.assertRaises(RuntimeError): + self.loop.call_soon(func) + with self.assertRaises(RuntimeError): + self.loop.call_soon_threadsafe(func) + with self.assertRaises(RuntimeError): + self.loop.call_later(1.0, func) + with self.assertRaises(RuntimeError): + self.loop.call_at(self.loop.time() + .0, func) + with self.assertRaises(RuntimeError): + self.loop.run_in_executor(None, func) + with self.assertRaises(RuntimeError): + self.loop.create_task(coro) + with self.assertRaises(RuntimeError): + self.loop.add_signal_handler(signal.SIGTERM, func) + class SubprocessTestsMixin: @@ -976,78 +1678,57 @@ def check_killed(self, returncode): self.assertEqual(-signal.SIGKILL, returncode) def test_subprocess_exec(self): - proto = None - transp = None - prog = os.path.join(os.path.dirname(__file__), 'echo.py') - @tasks.coroutine - def connect(): - nonlocal proto, transp - transp, proto = yield from self.loop.subprocess_exec( - functools.partial(MySubprocessProtocol, self.loop), - sys.executable, prog) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_exec( + functools.partial(MySubprocessProtocol, self.loop), + sys.executable, prog) + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.connected) self.assertEqual('CONNECTED', proto.state) stdin = transp.get_pipe_transport(0) stdin.write(b'Python The Winner') self.loop.run_until_complete(proto.got_data[1].wait()) - transp.close() + with test_utils.disable_logger(): + transp.close() self.loop.run_until_complete(proto.completed) - self.check_terminated(proto.returncode) + self.check_killed(proto.returncode) self.assertEqual(b'Python The Winner', proto.data[1]) def test_subprocess_interactive(self): - proto = None - transp = None - prog = os.path.join(os.path.dirname(__file__), 'echo.py') - @tasks.coroutine - def connect(): - nonlocal proto, transp - transp, proto = yield from self.loop.subprocess_exec( - functools.partial(MySubprocessProtocol, self.loop), - sys.executable, prog) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_exec( + functools.partial(MySubprocessProtocol, self.loop), + sys.executable, prog) + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.connected) self.assertEqual('CONNECTED', proto.state) - try: - stdin = transp.get_pipe_transport(0) - stdin.write(b'Python ') - self.loop.run_until_complete(proto.got_data[1].wait()) - proto.got_data[1].clear() - self.assertEqual(b'Python ', proto.data[1]) - - stdin.write(b'The Winner') - self.loop.run_until_complete(proto.got_data[1].wait()) - self.assertEqual(b'Python The Winner', proto.data[1]) - finally: - transp.close() + stdin = transp.get_pipe_transport(0) + stdin.write(b'Python ') + self.loop.run_until_complete(proto.got_data[1].wait()) + proto.got_data[1].clear() + self.assertEqual(b'Python ', proto.data[1]) + + stdin.write(b'The Winner') + self.loop.run_until_complete(proto.got_data[1].wait()) + self.assertEqual(b'Python The Winner', proto.data[1]) + with test_utils.disable_logger(): + transp.close() self.loop.run_until_complete(proto.completed) - self.check_terminated(proto.returncode) + self.check_killed(proto.returncode) def test_subprocess_shell(self): - proto = None - transp = None - - @tasks.coroutine - def connect(): - nonlocal proto, transp - transp, proto = yield from self.loop.subprocess_shell( - functools.partial(MySubprocessProtocol, self.loop), - 'echo Python') - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_shell( + functools.partial(MySubprocessProtocol, self.loop), + 'echo Python') + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.connected) transp.get_pipe_transport(0).close() @@ -1056,35 +1737,24 @@ def connect(): self.assertTrue(all(f.done() for f in proto.disconnects.values())) self.assertEqual(proto.data[1].rstrip(b'\r\n'), b'Python') self.assertEqual(proto.data[2], b'') + transp.close() def test_subprocess_exitcode(self): - proto = None - - @tasks.coroutine - def connect(): - nonlocal proto - transp, proto = yield from self.loop.subprocess_shell( - functools.partial(MySubprocessProtocol, self.loop), - 'exit 7', stdin=None, stdout=None, stderr=None) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_shell( + functools.partial(MySubprocessProtocol, self.loop), + 'exit 7', stdin=None, stdout=None, stderr=None) + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.completed) self.assertEqual(7, proto.returncode) + transp.close() def test_subprocess_close_after_finish(self): - proto = None - transp = None - - @tasks.coroutine - def connect(): - nonlocal proto, transp - transp, proto = yield from self.loop.subprocess_shell( - functools.partial(MySubprocessProtocol, self.loop), - 'exit 7', stdin=None, stdout=None, stderr=None) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_shell( + functools.partial(MySubprocessProtocol, self.loop), + 'exit 7', stdin=None, stdout=None, stderr=None) + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.assertIsNone(transp.get_pipe_transport(0)) self.assertIsNone(transp.get_pipe_transport(1)) self.assertIsNone(transp.get_pipe_transport(2)) @@ -1093,84 +1763,59 @@ def connect(): self.assertIsNone(transp.close()) def test_subprocess_kill(self): - proto = None - transp = None - prog = os.path.join(os.path.dirname(__file__), 'echo.py') - @tasks.coroutine - def connect(): - nonlocal proto, transp - transp, proto = yield from self.loop.subprocess_exec( - functools.partial(MySubprocessProtocol, self.loop), - sys.executable, prog) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_exec( + functools.partial(MySubprocessProtocol, self.loop), + sys.executable, prog) + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.connected) transp.kill() self.loop.run_until_complete(proto.completed) self.check_killed(proto.returncode) + transp.close() def test_subprocess_terminate(self): - proto = None - transp = None - prog = os.path.join(os.path.dirname(__file__), 'echo.py') - @tasks.coroutine - def connect(): - nonlocal proto, transp - transp, proto = yield from self.loop.subprocess_exec( - functools.partial(MySubprocessProtocol, self.loop), - sys.executable, prog) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_exec( + functools.partial(MySubprocessProtocol, self.loop), + sys.executable, prog) + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.connected) transp.terminate() self.loop.run_until_complete(proto.completed) self.check_terminated(proto.returncode) + transp.close() @unittest.skipIf(sys.platform == 'win32', "Don't have SIGHUP") def test_subprocess_send_signal(self): - proto = None - transp = None - prog = os.path.join(os.path.dirname(__file__), 'echo.py') - @tasks.coroutine - def connect(): - nonlocal proto, transp - transp, proto = yield from self.loop.subprocess_exec( - functools.partial(MySubprocessProtocol, self.loop), - sys.executable, prog) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_exec( + functools.partial(MySubprocessProtocol, self.loop), + sys.executable, prog) + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.connected) transp.send_signal(signal.SIGHUP) self.loop.run_until_complete(proto.completed) self.assertEqual(-signal.SIGHUP, proto.returncode) + transp.close() def test_subprocess_stderr(self): - proto = None - transp = None - prog = os.path.join(os.path.dirname(__file__), 'echo2.py') - @tasks.coroutine - def connect(): - nonlocal proto, transp - transp, proto = yield from self.loop.subprocess_exec( - functools.partial(MySubprocessProtocol, self.loop), - sys.executable, prog) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_exec( + functools.partial(MySubprocessProtocol, self.loop), + sys.executable, prog) + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.connected) stdin = transp.get_pipe_transport(0) @@ -1184,20 +1829,13 @@ def connect(): self.assertEqual(0, proto.returncode) def test_subprocess_stderr_redirect_to_stdout(self): - proto = None - transp = None - prog = os.path.join(os.path.dirname(__file__), 'echo2.py') - @tasks.coroutine - def connect(): - nonlocal proto, transp - transp, proto = yield from self.loop.subprocess_exec( - functools.partial(MySubprocessProtocol, self.loop), - sys.executable, prog, stderr=subprocess.STDOUT) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_exec( + functools.partial(MySubprocessProtocol, self.loop), + sys.executable, prog, stderr=subprocess.STDOUT) + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.connected) stdin = transp.get_pipe_transport(0) @@ -1214,20 +1852,13 @@ def connect(): self.assertEqual(0, proto.returncode) def test_subprocess_close_client_stream(self): - proto = None - transp = None - prog = os.path.join(os.path.dirname(__file__), 'echo3.py') - @tasks.coroutine - def connect(): - nonlocal proto, transp - transp, proto = yield from self.loop.subprocess_exec( - functools.partial(MySubprocessProtocol, self.loop), - sys.executable, prog) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + connect = self.loop.subprocess_exec( + functools.partial(MySubprocessProtocol, self.loop), + sys.executable, prog) + transp, proto = self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.connected) stdin = transp.get_pipe_transport(0) @@ -1248,49 +1879,99 @@ def connect(): # GetLastError()==ERROR_INVALID_NAME on Windows!?! (Using # WriteFile() we get ERROR_BROKEN_PIPE as expected.) self.assertEqual(b'ERR:OSError', proto.data[2]) - transp.close() + with test_utils.disable_logger(): + transp.close() self.loop.run_until_complete(proto.completed) - self.check_terminated(proto.returncode) + self.check_killed(proto.returncode) def test_subprocess_wait_no_same_group(self): - proto = None - transp = None - - @tasks.coroutine - def connect(): - nonlocal proto - # start the new process in a new session - transp, proto = yield from self.loop.subprocess_shell( - functools.partial(MySubprocessProtocol, self.loop), - 'exit 7', stdin=None, stdout=None, stderr=None, - start_new_session=True) - self.assertIsInstance(proto, MySubprocessProtocol) - - self.loop.run_until_complete(connect()) + # start the new process in a new session + connect = self.loop.subprocess_shell( + functools.partial(MySubprocessProtocol, self.loop), + 'exit 7', stdin=None, stdout=None, stderr=None, + start_new_session=True) + _, proto = yield self.loop.run_until_complete(connect) + self.assertIsInstance(proto, MySubprocessProtocol) self.loop.run_until_complete(proto.completed) self.assertEqual(7, proto.returncode) + def test_subprocess_exec_invalid_args(self): + @asyncio.coroutine + def connect(**kwds): + yield from self.loop.subprocess_exec( + asyncio.SubprocessProtocol, + 'pwd', **kwds) + + with self.assertRaises(ValueError): + self.loop.run_until_complete(connect(universal_newlines=True)) + with self.assertRaises(ValueError): + self.loop.run_until_complete(connect(bufsize=4096)) + with self.assertRaises(ValueError): + self.loop.run_until_complete(connect(shell=True)) + + def test_subprocess_shell_invalid_args(self): + @asyncio.coroutine + def connect(cmd=None, **kwds): + if not cmd: + cmd = 'pwd' + yield from self.loop.subprocess_shell( + asyncio.SubprocessProtocol, + cmd, **kwds) + + with self.assertRaises(ValueError): + self.loop.run_until_complete(connect(['ls', '-l'])) + with self.assertRaises(ValueError): + self.loop.run_until_complete(connect(universal_newlines=True)) + with self.assertRaises(ValueError): + self.loop.run_until_complete(connect(bufsize=4096)) + with self.assertRaises(ValueError): + self.loop.run_until_complete(connect(shell=False)) + if sys.platform == 'win32': - from asyncio import windows_events - class SelectEventLoopTests(EventLoopTestsMixin, unittest.TestCase): + class SelectEventLoopTests(EventLoopTestsMixin, test_utils.TestCase): def create_event_loop(self): - return windows_events.SelectorEventLoop() + return asyncio.SelectorEventLoop() class ProactorEventLoopTests(EventLoopTestsMixin, SubprocessTestsMixin, - unittest.TestCase): + test_utils.TestCase): def create_event_loop(self): - return windows_events.ProactorEventLoop() + return asyncio.ProactorEventLoop() - def test_create_ssl_connection(self): - raise unittest.SkipTest("IocpEventLoop imcompatible with SSL") + if not sslproto._is_sslproto_available(): + def test_create_ssl_connection(self): + raise unittest.SkipTest("need python 3.5 (ssl.MemoryBIO)") - def test_create_server_ssl(self): - raise unittest.SkipTest("IocpEventLoop imcompatible with SSL") + def test_create_server_ssl(self): + raise unittest.SkipTest("need python 3.5 (ssl.MemoryBIO)") + + def test_create_server_ssl_verify_failed(self): + raise unittest.SkipTest("need python 3.5 (ssl.MemoryBIO)") + + def test_create_server_ssl_match_failed(self): + raise unittest.SkipTest("need python 3.5 (ssl.MemoryBIO)") + + def test_create_server_ssl_verified(self): + raise unittest.SkipTest("need python 3.5 (ssl.MemoryBIO)") + + def test_legacy_create_ssl_connection(self): + raise unittest.SkipTest("IocpEventLoop incompatible with legacy SSL") + + def test_legacy_create_server_ssl(self): + raise unittest.SkipTest("IocpEventLoop incompatible with legacy SSL") + + def test_legacy_create_server_ssl_verify_failed(self): + raise unittest.SkipTest("IocpEventLoop incompatible with legacy SSL") + + def test_legacy_create_server_ssl_match_failed(self): + raise unittest.SkipTest("IocpEventLoop incompatible with legacy SSL") + + def test_legacy_create_server_ssl_verified(self): + raise unittest.SkipTest("IocpEventLoop incompatible with legacy SSL") def test_reader_callback(self): raise unittest.SkipTest("IocpEventLoop does not have add_reader()") @@ -1307,128 +1988,290 @@ def test_writer_callback_cancel(self): def test_create_datagram_endpoint(self): raise unittest.SkipTest( "IocpEventLoop does not have create_datagram_endpoint()") + + def test_remove_fds_after_closing(self): + raise unittest.SkipTest("IocpEventLoop does not have add_reader()") else: from asyncio import selectors - from asyncio import unix_events class UnixEventLoopTestsMixin(EventLoopTestsMixin): def setUp(self): super().setUp() - watcher = unix_events.SafeChildWatcher() + watcher = asyncio.SafeChildWatcher() watcher.attach_loop(self.loop) - events.set_child_watcher(watcher) + asyncio.set_child_watcher(watcher) def tearDown(self): - events.set_child_watcher(None) + asyncio.set_child_watcher(None) super().tearDown() if hasattr(selectors, 'KqueueSelector'): class KqueueEventLoopTests(UnixEventLoopTestsMixin, SubprocessTestsMixin, - unittest.TestCase): + test_utils.TestCase): def create_event_loop(self): - return unix_events.SelectorEventLoop( + return asyncio.SelectorEventLoop( selectors.KqueueSelector()) + # kqueue doesn't support character devices (PTY) on Mac OS X older + # than 10.9 (Maverick) + @support.requires_mac_ver(10, 9) + # Issue #20667: KqueueEventLoopTests.test_read_pty_output() + # hangs on OpenBSD 5.5 + @unittest.skipIf(sys.platform.startswith('openbsd'), + 'test hangs on OpenBSD') + def test_read_pty_output(self): + super().test_read_pty_output() + + # kqueue doesn't support character devices (PTY) on Mac OS X older + # than 10.9 (Maverick) + @support.requires_mac_ver(10, 9) + def test_write_pty(self): + super().test_write_pty() + if hasattr(selectors, 'EpollSelector'): class EPollEventLoopTests(UnixEventLoopTestsMixin, SubprocessTestsMixin, - unittest.TestCase): + test_utils.TestCase): def create_event_loop(self): - return unix_events.SelectorEventLoop(selectors.EpollSelector()) + return asyncio.SelectorEventLoop(selectors.EpollSelector()) if hasattr(selectors, 'PollSelector'): class PollEventLoopTests(UnixEventLoopTestsMixin, SubprocessTestsMixin, - unittest.TestCase): + test_utils.TestCase): def create_event_loop(self): - return unix_events.SelectorEventLoop(selectors.PollSelector()) + return asyncio.SelectorEventLoop(selectors.PollSelector()) # Should always exist. class SelectEventLoopTests(UnixEventLoopTestsMixin, SubprocessTestsMixin, - unittest.TestCase): + test_utils.TestCase): def create_event_loop(self): - return unix_events.SelectorEventLoop(selectors.SelectSelector()) + return asyncio.SelectorEventLoop(selectors.SelectSelector()) + + +def noop(*args): + pass -class HandleTests(unittest.TestCase): +class HandleTests(test_utils.TestCase): + + def setUp(self): + self.loop = mock.Mock() + self.loop.get_debug.return_value = True def test_handle(self): def callback(*args): return args args = () - h = events.Handle(callback, args) + h = asyncio.Handle(callback, args, self.loop) self.assertIs(h._callback, callback) self.assertIs(h._args, args) self.assertFalse(h._cancelled) - r = repr(h) - self.assertTrue(r.startswith( - 'Handle(' - '.callback')) - self.assertTrue(r.endswith('())')) - h.cancel() self.assertTrue(h._cancelled) - r = repr(h) - self.assertTrue(r.startswith( - 'Handle(' - '.callback')) - self.assertTrue(r.endswith('())'), r) - - def test_make_handle(self): + def test_handle_from_handle(self): def callback(*args): return args - h1 = events.Handle(callback, ()) + h1 = asyncio.Handle(callback, (), loop=self.loop) self.assertRaises( - AssertionError, events.make_handle, h1, ()) + AssertionError, asyncio.Handle, h1, (), self.loop) - @unittest.mock.patch('asyncio.events.logger') - def test_callback_with_exception(self, log): + def test_callback_with_exception(self): def callback(): raise ValueError() - h = events.Handle(callback, ()) + self.loop = mock.Mock() + self.loop.call_exception_handler = mock.Mock() + + h = asyncio.Handle(callback, (), self.loop) h._run() - self.assertTrue(log.exception.called) + + self.loop.call_exception_handler.assert_called_with({ + 'message': test_utils.MockPattern('Exception in callback.*'), + 'exception': mock.ANY, + 'handle': h, + 'source_traceback': h._source_traceback, + }) + + def test_handle_weakref(self): + wd = weakref.WeakValueDictionary() + h = asyncio.Handle(lambda: None, (), self.loop) + wd['h'] = h # Would fail without __weakref__ slot. + + def test_handle_repr(self): + self.loop.get_debug.return_value = False + + # simple function + h = asyncio.Handle(noop, (1, 2), self.loop) + filename, lineno = test_utils.get_function_source(noop) + self.assertEqual(repr(h), + '' + % (filename, lineno)) + + # cancelled handle + h.cancel() + self.assertEqual(repr(h), + '') + + # decorated function + cb = asyncio.coroutine(noop) + h = asyncio.Handle(cb, (), self.loop) + self.assertEqual(repr(h), + '' + % (filename, lineno)) + + # partial function + cb = functools.partial(noop, 1, 2) + h = asyncio.Handle(cb, (3,), self.loop) + regex = (r'^$' + % (re.escape(filename), lineno)) + self.assertRegex(repr(h), regex) + + # partial method + if sys.version_info >= (3, 4): + method = HandleTests.test_handle_repr + cb = functools.partialmethod(method) + filename, lineno = test_utils.get_function_source(method) + h = asyncio.Handle(cb, (), self.loop) + + cb_regex = r'' + cb_regex = (r'functools.partialmethod\(%s, , \)\(\)' % cb_regex) + regex = (r'^$' + % (cb_regex, re.escape(filename), lineno)) + self.assertRegex(repr(h), regex) + + def test_handle_repr_debug(self): + self.loop.get_debug.return_value = True + + # simple function + create_filename = __file__ + create_lineno = sys._getframe().f_lineno + 1 + h = asyncio.Handle(noop, (1, 2), self.loop) + filename, lineno = test_utils.get_function_source(noop) + self.assertEqual(repr(h), + '' + % (filename, lineno, create_filename, create_lineno)) + + # cancelled handle + h.cancel() + self.assertEqual( + repr(h), + '' + % (filename, lineno, create_filename, create_lineno)) + + # double cancellation won't overwrite _repr + h.cancel() + self.assertEqual( + repr(h), + '' + % (filename, lineno, create_filename, create_lineno)) + + def test_handle_source_traceback(self): + loop = asyncio.get_event_loop_policy().new_event_loop() + loop.set_debug(True) + self.set_event_loop(loop) + + def check_source_traceback(h): + lineno = sys._getframe(1).f_lineno - 1 + self.assertIsInstance(h._source_traceback, list) + self.assertEqual(h._source_traceback[-1][:3], + (__file__, + lineno, + 'test_handle_source_traceback')) + + # call_soon + h = loop.call_soon(noop) + check_source_traceback(h) + + # call_soon_threadsafe + h = loop.call_soon_threadsafe(noop) + check_source_traceback(h) + + # call_later + h = loop.call_later(0, noop) + check_source_traceback(h) + + # call_at + h = loop.call_later(0, noop) + check_source_traceback(h) class TimerTests(unittest.TestCase): + def setUp(self): + self.loop = mock.Mock() + def test_hash(self): when = time.monotonic() - h = events.TimerHandle(when, lambda: False, ()) + h = asyncio.TimerHandle(when, lambda: False, (), + mock.Mock()) self.assertEqual(hash(h), hash(when)) def test_timer(self): def callback(*args): return args - args = () + args = (1, 2, 3) when = time.monotonic() - h = events.TimerHandle(when, callback, args) + h = asyncio.TimerHandle(when, callback, args, mock.Mock()) self.assertIs(h._callback, callback) self.assertIs(h._args, args) self.assertFalse(h._cancelled) - r = repr(h) - self.assertTrue(r.endswith('())')) - + # cancel h.cancel() self.assertTrue(h._cancelled) + self.assertIsNone(h._callback) + self.assertIsNone(h._args) - r = repr(h) - self.assertTrue(r.endswith('())'), r) - + # when cannot be None self.assertRaises(AssertionError, - events.TimerHandle, None, callback, args) + asyncio.TimerHandle, None, callback, args, + self.loop) + + def test_timer_repr(self): + self.loop.get_debug.return_value = False + + # simple function + h = asyncio.TimerHandle(123, noop, (), self.loop) + src = test_utils.get_function_source(noop) + self.assertEqual(repr(h), + '' % src) + + # cancelled handle + h.cancel() + self.assertEqual(repr(h), + '') + + def test_timer_repr_debug(self): + self.loop.get_debug.return_value = True + + # simple function + create_filename = __file__ + create_lineno = sys._getframe().f_lineno + 1 + h = asyncio.TimerHandle(123, noop, (), self.loop) + filename, lineno = test_utils.get_function_source(noop) + self.assertEqual(repr(h), + '' + % (filename, lineno, create_filename, create_lineno)) + + # cancelled handle + h.cancel() + self.assertEqual(repr(h), + '' + % (filename, lineno, create_filename, create_lineno)) + def test_timer_comparison(self): def callback(*args): @@ -1436,8 +2279,8 @@ def callback(*args): when = time.monotonic() - h1 = events.TimerHandle(when, callback, ()) - h2 = events.TimerHandle(when, callback, ()) + h1 = asyncio.TimerHandle(when, callback, (), self.loop) + h2 = asyncio.TimerHandle(when, callback, (), self.loop) # TODO: Use assertLess etc. self.assertFalse(h1 < h2) self.assertFalse(h2 < h1) @@ -1453,8 +2296,8 @@ def callback(*args): h2.cancel() self.assertFalse(h1 == h2) - h1 = events.TimerHandle(when, callback, ()) - h2 = events.TimerHandle(when + 10.0, callback, ()) + h1 = asyncio.TimerHandle(when, callback, (), self.loop) + h2 = asyncio.TimerHandle(when + 10.0, callback, (), self.loop) self.assertTrue(h1 < h2) self.assertFalse(h2 < h1) self.assertTrue(h1 <= h2) @@ -1466,7 +2309,7 @@ def callback(*args): self.assertFalse(h1 == h2) self.assertTrue(h1 != h2) - h3 = events.Handle(callback, ()) + h3 = asyncio.Handle(callback, (), self.loop) self.assertIs(NotImplemented, h1.__eq__(h3)) self.assertIs(NotImplemented, h1.__ne__(h3)) @@ -1474,8 +2317,8 @@ def callback(*args): class AbstractEventLoopTests(unittest.TestCase): def test_not_implemented(self): - f = unittest.mock.Mock() - loop = events.AbstractEventLoop() + f = mock.Mock() + loop = asyncio.AbstractEventLoop() self.assertRaises( NotImplementedError, loop.run_forever) self.assertRaises( @@ -1484,8 +2327,12 @@ def test_not_implemented(self): NotImplementedError, loop.stop) self.assertRaises( NotImplementedError, loop.is_running) + self.assertRaises( + NotImplementedError, loop.is_closed) self.assertRaises( NotImplementedError, loop.close) + self.assertRaises( + NotImplementedError, loop.create_task, None) self.assertRaises( NotImplementedError, loop.call_later, None, None) self.assertRaises( @@ -1534,34 +2381,44 @@ def test_not_implemented(self): NotImplementedError, loop.remove_signal_handler, 1) self.assertRaises( NotImplementedError, loop.connect_read_pipe, f, - unittest.mock.sentinel.pipe) + mock.sentinel.pipe) self.assertRaises( NotImplementedError, loop.connect_write_pipe, f, - unittest.mock.sentinel.pipe) + mock.sentinel.pipe) self.assertRaises( NotImplementedError, loop.subprocess_shell, f, - unittest.mock.sentinel) + mock.sentinel) self.assertRaises( NotImplementedError, loop.subprocess_exec, f) + self.assertRaises( + NotImplementedError, loop.set_exception_handler, f) + self.assertRaises( + NotImplementedError, loop.default_exception_handler, f) + self.assertRaises( + NotImplementedError, loop.call_exception_handler, f) + self.assertRaises( + NotImplementedError, loop.get_debug) + self.assertRaises( + NotImplementedError, loop.set_debug, f) class ProtocolsAbsTests(unittest.TestCase): def test_empty(self): - f = unittest.mock.Mock() - p = protocols.Protocol() + f = mock.Mock() + p = asyncio.Protocol() self.assertIsNone(p.connection_made(f)) self.assertIsNone(p.connection_lost(f)) self.assertIsNone(p.data_received(f)) self.assertIsNone(p.eof_received()) - dp = protocols.DatagramProtocol() + dp = asyncio.DatagramProtocol() self.assertIsNone(dp.connection_made(f)) self.assertIsNone(dp.connection_lost(f)) self.assertIsNone(dp.error_received(f)) self.assertIsNone(dp.datagram_received(f, f)) - sp = protocols.SubprocessProtocol() + sp = asyncio.SubprocessProtocol() self.assertIsNone(sp.connection_made(f)) self.assertIsNone(sp.connection_lost(f)) self.assertIsNone(sp.pipe_data_received(1, f)) @@ -1571,16 +2428,8 @@ def test_empty(self): class PolicyTests(unittest.TestCase): - def create_policy(self): - if sys.platform == "win32": - from asyncio import windows_events - return windows_events.DefaultEventLoopPolicy() - else: - from asyncio import unix_events - return unix_events.DefaultEventLoopPolicy() - def test_event_loop_policy(self): - policy = events.AbstractEventLoopPolicy() + policy = asyncio.AbstractEventLoopPolicy() self.assertRaises(NotImplementedError, policy.get_event_loop) self.assertRaises(NotImplementedError, policy.set_event_loop, object()) self.assertRaises(NotImplementedError, policy.new_event_loop) @@ -1589,20 +2438,20 @@ def test_event_loop_policy(self): object()) def test_get_event_loop(self): - policy = self.create_policy() + policy = asyncio.DefaultEventLoopPolicy() self.assertIsNone(policy._local._loop) loop = policy.get_event_loop() - self.assertIsInstance(loop, events.AbstractEventLoop) + self.assertIsInstance(loop, asyncio.AbstractEventLoop) self.assertIs(policy._local._loop, loop) self.assertIs(loop, policy.get_event_loop()) loop.close() def test_get_event_loop_calls_set_event_loop(self): - policy = self.create_policy() + policy = asyncio.DefaultEventLoopPolicy() - with unittest.mock.patch.object( + with mock.patch.object( policy, "set_event_loop", wraps=policy.set_event_loop) as m_set_event_loop: @@ -1616,30 +2465,30 @@ def test_get_event_loop_calls_set_event_loop(self): loop.close() def test_get_event_loop_after_set_none(self): - policy = self.create_policy() + policy = asyncio.DefaultEventLoopPolicy() policy.set_event_loop(None) - self.assertRaises(AssertionError, policy.get_event_loop) + self.assertRaises(RuntimeError, policy.get_event_loop) - @unittest.mock.patch('asyncio.events.threading.current_thread') + @mock.patch('asyncio.events.threading.current_thread') def test_get_event_loop_thread(self, m_current_thread): def f(): - policy = self.create_policy() - self.assertRaises(AssertionError, policy.get_event_loop) + policy = asyncio.DefaultEventLoopPolicy() + self.assertRaises(RuntimeError, policy.get_event_loop) th = threading.Thread(target=f) th.start() th.join() def test_new_event_loop(self): - policy = self.create_policy() + policy = asyncio.DefaultEventLoopPolicy() loop = policy.new_event_loop() - self.assertIsInstance(loop, events.AbstractEventLoop) + self.assertIsInstance(loop, asyncio.AbstractEventLoop) loop.close() def test_set_event_loop(self): - policy = self.create_policy() + policy = asyncio.DefaultEventLoopPolicy() old_loop = policy.get_event_loop() self.assertRaises(AssertionError, policy.set_event_loop, object()) @@ -1652,19 +2501,19 @@ def test_set_event_loop(self): old_loop.close() def test_get_event_loop_policy(self): - policy = events.get_event_loop_policy() - self.assertIsInstance(policy, events.AbstractEventLoopPolicy) - self.assertIs(policy, events.get_event_loop_policy()) + policy = asyncio.get_event_loop_policy() + self.assertIsInstance(policy, asyncio.AbstractEventLoopPolicy) + self.assertIs(policy, asyncio.get_event_loop_policy()) def test_set_event_loop_policy(self): self.assertRaises( - AssertionError, events.set_event_loop_policy, object()) + AssertionError, asyncio.set_event_loop_policy, object()) - old_policy = events.get_event_loop_policy() + old_policy = asyncio.get_event_loop_policy() - policy = self.create_policy() - events.set_event_loop_policy(policy) - self.assertIs(policy, events.get_event_loop_policy()) + policy = asyncio.DefaultEventLoopPolicy() + asyncio.set_event_loop_policy(policy) + self.assertIs(policy, asyncio.get_event_loop_policy()) self.assertIsNot(policy, old_policy) diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py index e35fcf070855..0bc0581d2816 100644 --- a/Lib/test/test_asyncio/test_futures.py +++ b/Lib/test/test_asyncio/test_futures.py @@ -1,87 +1,97 @@ """Tests for futures.py.""" import concurrent.futures +import re +import sys import threading import unittest -import unittest.mock +from unittest import mock -from asyncio import events -from asyncio import futures +import asyncio from asyncio import test_utils +try: + from test import support +except ImportError: + from asyncio import test_support as support def _fakefunc(f): return f +def first_cb(): + pass -class FutureTests(unittest.TestCase): +def last_cb(): + pass - def setUp(self): - self.loop = test_utils.TestLoop() - events.set_event_loop(None) - def tearDown(self): - self.loop.close() +class FutureTests(test_utils.TestCase): + + def setUp(self): + self.loop = self.new_test_loop() + self.addCleanup(self.loop.close) def test_initial_state(self): - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) self.assertFalse(f.cancelled()) self.assertFalse(f.done()) f.cancel() self.assertTrue(f.cancelled()) def test_init_constructor_default_loop(self): - try: - events.set_event_loop(self.loop) - f = futures.Future() - self.assertIs(f._loop, self.loop) - finally: - events.set_event_loop(None) + asyncio.set_event_loop(self.loop) + f = asyncio.Future() + self.assertIs(f._loop, self.loop) def test_constructor_positional(self): - # Make sure Future does't accept a positional argument - self.assertRaises(TypeError, futures.Future, 42) + # Make sure Future doesn't accept a positional argument + self.assertRaises(TypeError, asyncio.Future, 42) def test_cancel(self): - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) self.assertTrue(f.cancel()) self.assertTrue(f.cancelled()) self.assertTrue(f.done()) - self.assertRaises(futures.CancelledError, f.result) - self.assertRaises(futures.CancelledError, f.exception) - self.assertRaises(futures.InvalidStateError, f.set_result, None) - self.assertRaises(futures.InvalidStateError, f.set_exception, None) + self.assertRaises(asyncio.CancelledError, f.result) + self.assertRaises(asyncio.CancelledError, f.exception) + self.assertRaises(asyncio.InvalidStateError, f.set_result, None) + self.assertRaises(asyncio.InvalidStateError, f.set_exception, None) self.assertFalse(f.cancel()) def test_result(self): - f = futures.Future(loop=self.loop) - self.assertRaises(futures.InvalidStateError, f.result) + f = asyncio.Future(loop=self.loop) + self.assertRaises(asyncio.InvalidStateError, f.result) f.set_result(42) self.assertFalse(f.cancelled()) self.assertTrue(f.done()) self.assertEqual(f.result(), 42) self.assertEqual(f.exception(), None) - self.assertRaises(futures.InvalidStateError, f.set_result, None) - self.assertRaises(futures.InvalidStateError, f.set_exception, None) + self.assertRaises(asyncio.InvalidStateError, f.set_result, None) + self.assertRaises(asyncio.InvalidStateError, f.set_exception, None) self.assertFalse(f.cancel()) def test_exception(self): exc = RuntimeError() - f = futures.Future(loop=self.loop) - self.assertRaises(futures.InvalidStateError, f.exception) + f = asyncio.Future(loop=self.loop) + self.assertRaises(asyncio.InvalidStateError, f.exception) f.set_exception(exc) self.assertFalse(f.cancelled()) self.assertTrue(f.done()) self.assertRaises(RuntimeError, f.result) self.assertEqual(f.exception(), exc) - self.assertRaises(futures.InvalidStateError, f.set_result, None) - self.assertRaises(futures.InvalidStateError, f.set_exception, None) + self.assertRaises(asyncio.InvalidStateError, f.set_result, None) + self.assertRaises(asyncio.InvalidStateError, f.set_exception, None) self.assertFalse(f.cancel()) + def test_exception_class(self): + f = asyncio.Future(loop=self.loop) + f.set_exception(RuntimeError) + self.assertIsInstance(f.exception(), RuntimeError) + def test_yield_from_twice(self): - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) def fixture(): yield 'A' @@ -98,68 +108,97 @@ def fixture(): # The second "yield from f" does not yield f. self.assertEqual(next(g), ('C', 42)) # yield 'C', y. - def test_repr(self): - f_pending = futures.Future(loop=self.loop) - self.assertEqual(repr(f_pending), 'Future') + def test_future_repr(self): + self.loop.set_debug(True) + f_pending_debug = asyncio.Future(loop=self.loop) + frame = f_pending_debug._source_traceback[-1] + self.assertEqual(repr(f_pending_debug), + '' + % (frame[0], frame[1])) + f_pending_debug.cancel() + + self.loop.set_debug(False) + f_pending = asyncio.Future(loop=self.loop) + self.assertEqual(repr(f_pending), '') f_pending.cancel() - f_cancelled = futures.Future(loop=self.loop) + f_cancelled = asyncio.Future(loop=self.loop) f_cancelled.cancel() - self.assertEqual(repr(f_cancelled), 'Future') + self.assertEqual(repr(f_cancelled), '') - f_result = futures.Future(loop=self.loop) + f_result = asyncio.Future(loop=self.loop) f_result.set_result(4) - self.assertEqual(repr(f_result), 'Future') + self.assertEqual(repr(f_result), '') self.assertEqual(f_result.result(), 4) exc = RuntimeError() - f_exception = futures.Future(loop=self.loop) + f_exception = asyncio.Future(loop=self.loop) f_exception.set_exception(exc) - self.assertEqual(repr(f_exception), 'Future') + self.assertEqual(repr(f_exception), + '') self.assertIs(f_exception.exception(), exc) - f_few_callbacks = futures.Future(loop=self.loop) - f_few_callbacks.add_done_callback(_fakefunc) - self.assertIn('Future' % fake_repr) + f_one_callbacks.cancel() + self.assertEqual(repr(f_one_callbacks), + '') + + f_two_callbacks = asyncio.Future(loop=self.loop) + f_two_callbacks.add_done_callback(first_cb) + f_two_callbacks.add_done_callback(last_cb) + first_repr = func_repr(first_cb) + last_repr = func_repr(last_cb) + self.assertRegex(repr(f_two_callbacks), + r'' + % (first_repr, last_repr)) + + f_many_callbacks = asyncio.Future(loop=self.loop) + f_many_callbacks.add_done_callback(first_cb) + for i in range(8): f_many_callbacks.add_done_callback(_fakefunc) - r = repr(f_many_callbacks) - self.assertIn('Future', r) + f_many_callbacks.add_done_callback(last_cb) + cb_regex = r'%s, <8 more>, %s' % (first_repr, last_repr) + self.assertRegex(repr(f_many_callbacks), + r'' % cb_regex) f_many_callbacks.cancel() + self.assertEqual(repr(f_many_callbacks), + '') def test_copy_state(self): - # Test the internal _copy_state method since it's being directly - # invoked in other modules. - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) f.set_result(10) - newf = futures.Future(loop=self.loop) + newf = asyncio.Future(loop=self.loop) newf._copy_state(f) self.assertTrue(newf.done()) self.assertEqual(newf.result(), 10) - f_exception = futures.Future(loop=self.loop) + f_exception = asyncio.Future(loop=self.loop) f_exception.set_exception(RuntimeError()) - newf_exception = futures.Future(loop=self.loop) + newf_exception = asyncio.Future(loop=self.loop) newf_exception._copy_state(f_exception) self.assertTrue(newf_exception.done()) self.assertRaises(RuntimeError, newf_exception.result) - f_cancelled = futures.Future(loop=self.loop) + f_cancelled = asyncio.Future(loop=self.loop) f_cancelled.cancel() - newf_cancelled = futures.Future(loop=self.loop) + newf_cancelled = asyncio.Future(loop=self.loop) newf_cancelled._copy_state(f_cancelled) self.assertTrue(newf_cancelled.cancelled()) def test_iter(self): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) def coro(): yield from fut @@ -170,46 +209,46 @@ def test(): self.assertRaises(AssertionError, test) fut.cancel() - @unittest.mock.patch('asyncio.futures.logger') + @mock.patch('asyncio.base_events.logger') def test_tb_logger_abandoned(self, m_log): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) del fut self.assertFalse(m_log.error.called) - @unittest.mock.patch('asyncio.futures.logger') + @mock.patch('asyncio.base_events.logger') def test_tb_logger_result_unretrieved(self, m_log): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) fut.set_result(42) del fut self.assertFalse(m_log.error.called) - @unittest.mock.patch('asyncio.futures.logger') + @mock.patch('asyncio.base_events.logger') def test_tb_logger_result_retrieved(self, m_log): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) fut.set_result(42) fut.result() del fut self.assertFalse(m_log.error.called) - @unittest.mock.patch('asyncio.futures.logger') + @mock.patch('asyncio.base_events.logger') def test_tb_logger_exception_unretrieved(self, m_log): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) fut.set_exception(RuntimeError('boom')) del fut test_utils.run_briefly(self.loop) self.assertTrue(m_log.error.called) - @unittest.mock.patch('asyncio.futures.logger') + @mock.patch('asyncio.base_events.logger') def test_tb_logger_exception_retrieved(self, m_log): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) fut.set_exception(RuntimeError('boom')) fut.exception() del fut self.assertFalse(m_log.error.called) - @unittest.mock.patch('asyncio.futures.logger') + @mock.patch('asyncio.base_events.logger') def test_tb_logger_exception_result_retrieved(self, m_log): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) fut.set_exception(RuntimeError('boom')) self.assertRaises(RuntimeError, fut.result) del fut @@ -221,29 +260,29 @@ def run(arg): return (arg, threading.get_ident()) ex = concurrent.futures.ThreadPoolExecutor(1) f1 = ex.submit(run, 'oi') - f2 = futures.wrap_future(f1, loop=self.loop) + f2 = asyncio.wrap_future(f1, loop=self.loop) res, ident = self.loop.run_until_complete(f2) - self.assertIsInstance(f2, futures.Future) + self.assertIsInstance(f2, asyncio.Future) self.assertEqual(res, 'oi') self.assertNotEqual(ident, threading.get_ident()) def test_wrap_future_future(self): - f1 = futures.Future(loop=self.loop) - f2 = futures.wrap_future(f1) + f1 = asyncio.Future(loop=self.loop) + f2 = asyncio.wrap_future(f1) self.assertIs(f1, f2) - @unittest.mock.patch('asyncio.futures.events') + @mock.patch('asyncio.futures.events') def test_wrap_future_use_global_loop(self, m_events): def run(arg): return (arg, threading.get_ident()) ex = concurrent.futures.ThreadPoolExecutor(1) f1 = ex.submit(run, 'oi') - f2 = futures.wrap_future(f1) + f2 = asyncio.wrap_future(f1) self.assertIs(m_events.get_event_loop.return_value, f2._loop) def test_wrap_future_cancel(self): f1 = concurrent.futures.Future() - f2 = futures.wrap_future(f1, loop=self.loop) + f2 = asyncio.wrap_future(f1, loop=self.loop) f2.cancel() test_utils.run_briefly(self.loop) self.assertTrue(f1.cancelled()) @@ -251,7 +290,7 @@ def test_wrap_future_cancel(self): def test_wrap_future_cancel2(self): f1 = concurrent.futures.Future() - f2 = futures.wrap_future(f1, loop=self.loop) + f2 = asyncio.wrap_future(f1, loop=self.loop) f1.set_result(42) f2.cancel() test_utils.run_briefly(self.loop) @@ -259,15 +298,100 @@ def test_wrap_future_cancel2(self): self.assertEqual(f1.result(), 42) self.assertTrue(f2.cancelled()) + def test_future_source_traceback(self): + self.loop.set_debug(True) + + future = asyncio.Future(loop=self.loop) + lineno = sys._getframe().f_lineno - 1 + self.assertIsInstance(future._source_traceback, list) + self.assertEqual(future._source_traceback[-1][:3], + (__file__, + lineno, + 'test_future_source_traceback')) + + @mock.patch('asyncio.base_events.logger') + def check_future_exception_never_retrieved(self, debug, m_log): + self.loop.set_debug(debug) + + def memory_error(): + try: + raise MemoryError() + except BaseException as exc: + return exc + exc = memory_error() + + future = asyncio.Future(loop=self.loop) + if debug: + source_traceback = future._source_traceback + future.set_exception(exc) + future = None + test_utils.run_briefly(self.loop) + support.gc_collect() + + if sys.version_info >= (3, 4): + if debug: + frame = source_traceback[-1] + regex = (r'^Future exception was never retrieved\n' + r'future: \n' + r'source_traceback: Object ' + r'created at \(most recent call last\):\n' + r' File' + r'.*\n' + r' File "{filename}", line {lineno}, ' + r'in check_future_exception_never_retrieved\n' + r' future = asyncio\.Future\(loop=self\.loop\)$' + ).format(filename=re.escape(frame[0]), + lineno=frame[1]) + else: + regex = (r'^Future exception was never retrieved\n' + r'future: ' + r'$' + ) + exc_info = (type(exc), exc, exc.__traceback__) + m_log.error.assert_called_once_with(mock.ANY, exc_info=exc_info) + else: + if debug: + frame = source_traceback[-1] + regex = (r'^Future/Task exception was never retrieved\n' + r'Future/Task created at \(most recent call last\):\n' + r' File' + r'.*\n' + r' File "{filename}", line {lineno}, ' + r'in check_future_exception_never_retrieved\n' + r' future = asyncio\.Future\(loop=self\.loop\)\n' + r'Traceback \(most recent call last\):\n' + r'.*\n' + r'MemoryError$' + ).format(filename=re.escape(frame[0]), + lineno=frame[1]) + else: + regex = (r'^Future/Task exception was never retrieved\n' + r'Traceback \(most recent call last\):\n' + r'.*\n' + r'MemoryError$' + ) + m_log.error.assert_called_once_with(mock.ANY, exc_info=False) + message = m_log.error.call_args[0][0] + self.assertRegex(message, re.compile(regex, re.DOTALL)) + + def test_future_exception_never_retrieved(self): + self.check_future_exception_never_retrieved(False) + + def test_future_exception_never_retrieved_debug(self): + self.check_future_exception_never_retrieved(True) + + def test_set_result_unless_cancelled(self): + fut = asyncio.Future(loop=self.loop) + fut.cancel() + fut._set_result_unless_cancelled(2) + self.assertTrue(fut.cancelled()) -class FutureDoneCallbackTests(unittest.TestCase): - def setUp(self): - self.loop = test_utils.TestLoop() - events.set_event_loop(None) +class FutureDoneCallbackTests(test_utils.TestCase): - def tearDown(self): - self.loop.close() + def setUp(self): + self.loop = self.new_test_loop() def run_briefly(self): test_utils.run_briefly(self.loop) @@ -279,7 +403,7 @@ def bag_appender(future): return bag_appender def _new_future(self): - return futures.Future(loop=self.loop) + return asyncio.Future(loop=self.loop) def test_callbacks_invoked_on_set_result(self): bag = [] diff --git a/Lib/test/test_asyncio/test_locks.py b/Lib/test/test_asyncio/test_locks.py index df106e0d151d..cdf5d9d3b635 100644 --- a/Lib/test/test_asyncio/test_locks.py +++ b/Lib/test/test_asyncio/test_locks.py @@ -1,16 +1,12 @@ """Tests for lock.py""" import unittest -import unittest.mock +from unittest import mock import re -from asyncio import events -from asyncio import futures -from asyncio import locks -from asyncio import tasks +import asyncio from asyncio import test_utils - STR_RGX_REPR = ( r'^<(?P.*?) object at (?P
.*?)' r'\[(?P' @@ -20,37 +16,30 @@ RGX_REPR = re.compile(STR_RGX_REPR) -class LockTests(unittest.TestCase): +class LockTests(test_utils.TestCase): def setUp(self): - self.loop = test_utils.TestLoop() - events.set_event_loop(None) - - def tearDown(self): - self.loop.close() + self.loop = self.new_test_loop() def test_ctor_loop(self): - loop = unittest.mock.Mock() - lock = locks.Lock(loop=loop) + loop = mock.Mock() + lock = asyncio.Lock(loop=loop) self.assertIs(lock._loop, loop) - lock = locks.Lock(loop=self.loop) + lock = asyncio.Lock(loop=self.loop) self.assertIs(lock._loop, self.loop) def test_ctor_noloop(self): - try: - events.set_event_loop(self.loop) - lock = locks.Lock() - self.assertIs(lock._loop, self.loop) - finally: - events.set_event_loop(None) + asyncio.set_event_loop(self.loop) + lock = asyncio.Lock() + self.assertIs(lock._loop, self.loop) def test_repr(self): - lock = locks.Lock(loop=self.loop) + lock = asyncio.Lock(loop=self.loop) self.assertTrue(repr(lock).endswith('[unlocked]>')) self.assertTrue(RGX_REPR.match(repr(lock))) - @tasks.coroutine + @asyncio.coroutine def acquire_lock(): yield from lock @@ -59,9 +48,9 @@ def acquire_lock(): self.assertTrue(RGX_REPR.match(repr(lock))) def test_lock(self): - lock = locks.Lock(loop=self.loop) + lock = asyncio.Lock(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def acquire_lock(): return (yield from lock) @@ -74,31 +63,31 @@ def acquire_lock(): self.assertFalse(lock.locked()) def test_acquire(self): - lock = locks.Lock(loop=self.loop) + lock = asyncio.Lock(loop=self.loop) result = [] self.assertTrue(self.loop.run_until_complete(lock.acquire())) - @tasks.coroutine + @asyncio.coroutine def c1(result): if (yield from lock.acquire()): result.append(1) return True - @tasks.coroutine + @asyncio.coroutine def c2(result): if (yield from lock.acquire()): result.append(2) return True - @tasks.coroutine + @asyncio.coroutine def c3(result): if (yield from lock.acquire()): result.append(3) return True - t1 = tasks.Task(c1(result), loop=self.loop) - t2 = tasks.Task(c2(result), loop=self.loop) + t1 = asyncio.Task(c1(result), loop=self.loop) + t2 = asyncio.Task(c2(result), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual([], result) @@ -110,7 +99,7 @@ def c3(result): test_utils.run_briefly(self.loop) self.assertEqual([1], result) - t3 = tasks.Task(c3(result), loop=self.loop) + t3 = asyncio.Task(c3(result), loop=self.loop) lock.release() test_utils.run_briefly(self.loop) @@ -128,13 +117,13 @@ def c3(result): self.assertTrue(t3.result()) def test_acquire_cancel(self): - lock = locks.Lock(loop=self.loop) + lock = asyncio.Lock(loop=self.loop) self.assertTrue(self.loop.run_until_complete(lock.acquire())) - task = tasks.Task(lock.acquire(), loop=self.loop) + task = asyncio.Task(lock.acquire(), loop=self.loop) self.loop.call_soon(task.cancel) self.assertRaises( - futures.CancelledError, + asyncio.CancelledError, self.loop.run_until_complete, task) self.assertFalse(lock._waiters) @@ -153,9 +142,9 @@ def test_cancel_race(self): # B's waiter; instead, it should move on to C's waiter. # Setup: A has the lock, b and c are waiting. - lock = locks.Lock(loop=self.loop) + lock = asyncio.Lock(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def lockit(name, blocker): yield from lock.acquire() try: @@ -164,14 +153,14 @@ def lockit(name, blocker): finally: lock.release() - fa = futures.Future(loop=self.loop) - ta = tasks.Task(lockit('A', fa), loop=self.loop) + fa = asyncio.Future(loop=self.loop) + ta = asyncio.Task(lockit('A', fa), loop=self.loop) test_utils.run_briefly(self.loop) self.assertTrue(lock.locked()) - tb = tasks.Task(lockit('B', None), loop=self.loop) + tb = asyncio.Task(lockit('B', None), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual(len(lock._waiters), 1) - tc = tasks.Task(lockit('C', None), loop=self.loop) + tc = asyncio.Task(lockit('C', None), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual(len(lock._waiters), 2) @@ -187,12 +176,12 @@ def lockit(name, blocker): self.assertTrue(tc.done()) def test_release_not_acquired(self): - lock = locks.Lock(loop=self.loop) + lock = asyncio.Lock(loop=self.loop) self.assertRaises(RuntimeError, lock.release) def test_release_no_waiters(self): - lock = locks.Lock(loop=self.loop) + lock = asyncio.Lock(loop=self.loop) self.loop.run_until_complete(lock.acquire()) self.assertTrue(lock.locked()) @@ -200,9 +189,9 @@ def test_release_no_waiters(self): self.assertFalse(lock.locked()) def test_context_manager(self): - lock = locks.Lock(loop=self.loop) + lock = asyncio.Lock(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def acquire_lock(): return (yield from lock) @@ -211,8 +200,26 @@ def acquire_lock(): self.assertFalse(lock.locked()) + def test_context_manager_cant_reuse(self): + lock = asyncio.Lock(loop=self.loop) + + @asyncio.coroutine + def acquire_lock(): + return (yield from lock) + + # This spells "yield from lock" outside a generator. + cm = self.loop.run_until_complete(acquire_lock()) + with cm: + self.assertTrue(lock.locked()) + + self.assertFalse(lock.locked()) + + with self.assertRaises(AttributeError): + with cm: + pass + def test_context_manager_no_yield(self): - lock = locks.Lock(loop=self.loop) + lock = asyncio.Lock(loop=self.loop) try: with lock: @@ -222,34 +229,29 @@ def test_context_manager_no_yield(self): str(err), '"yield from" should be used as context manager expression') + self.assertFalse(lock.locked()) -class EventTests(unittest.TestCase): - def setUp(self): - self.loop = test_utils.TestLoop() - events.set_event_loop(None) +class EventTests(test_utils.TestCase): - def tearDown(self): - self.loop.close() + def setUp(self): + self.loop = self.new_test_loop() def test_ctor_loop(self): - loop = unittest.mock.Mock() - ev = locks.Event(loop=loop) + loop = mock.Mock() + ev = asyncio.Event(loop=loop) self.assertIs(ev._loop, loop) - ev = locks.Event(loop=self.loop) + ev = asyncio.Event(loop=self.loop) self.assertIs(ev._loop, self.loop) def test_ctor_noloop(self): - try: - events.set_event_loop(self.loop) - ev = locks.Event() - self.assertIs(ev._loop, self.loop) - finally: - events.set_event_loop(None) + asyncio.set_event_loop(self.loop) + ev = asyncio.Event() + self.assertIs(ev._loop, self.loop) def test_repr(self): - ev = locks.Event(loop=self.loop) + ev = asyncio.Event(loop=self.loop) self.assertTrue(repr(ev).endswith('[unset]>')) match = RGX_REPR.match(repr(ev)) self.assertEqual(match.group('extras'), 'unset') @@ -258,38 +260,38 @@ def test_repr(self): self.assertTrue(repr(ev).endswith('[set]>')) self.assertTrue(RGX_REPR.match(repr(ev))) - ev._waiters.append(unittest.mock.Mock()) + ev._waiters.append(mock.Mock()) self.assertTrue('waiters:1' in repr(ev)) self.assertTrue(RGX_REPR.match(repr(ev))) def test_wait(self): - ev = locks.Event(loop=self.loop) + ev = asyncio.Event(loop=self.loop) self.assertFalse(ev.is_set()) result = [] - @tasks.coroutine + @asyncio.coroutine def c1(result): if (yield from ev.wait()): result.append(1) - @tasks.coroutine + @asyncio.coroutine def c2(result): if (yield from ev.wait()): result.append(2) - @tasks.coroutine + @asyncio.coroutine def c3(result): if (yield from ev.wait()): result.append(3) - t1 = tasks.Task(c1(result), loop=self.loop) - t2 = tasks.Task(c2(result), loop=self.loop) + t1 = asyncio.Task(c1(result), loop=self.loop) + t2 = asyncio.Task(c2(result), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual([], result) - t3 = tasks.Task(c3(result), loop=self.loop) + t3 = asyncio.Task(c3(result), loop=self.loop) ev.set() test_utils.run_briefly(self.loop) @@ -303,24 +305,24 @@ def c3(result): self.assertIsNone(t3.result()) def test_wait_on_set(self): - ev = locks.Event(loop=self.loop) + ev = asyncio.Event(loop=self.loop) ev.set() res = self.loop.run_until_complete(ev.wait()) self.assertTrue(res) def test_wait_cancel(self): - ev = locks.Event(loop=self.loop) + ev = asyncio.Event(loop=self.loop) - wait = tasks.Task(ev.wait(), loop=self.loop) + wait = asyncio.Task(ev.wait(), loop=self.loop) self.loop.call_soon(wait.cancel) self.assertRaises( - futures.CancelledError, + asyncio.CancelledError, self.loop.run_until_complete, wait) self.assertFalse(ev._waiters) def test_clear(self): - ev = locks.Event(loop=self.loop) + ev = asyncio.Event(loop=self.loop) self.assertFalse(ev.is_set()) ev.set() @@ -330,16 +332,16 @@ def test_clear(self): self.assertFalse(ev.is_set()) def test_clear_with_waiters(self): - ev = locks.Event(loop=self.loop) + ev = asyncio.Event(loop=self.loop) result = [] - @tasks.coroutine + @asyncio.coroutine def c1(result): if (yield from ev.wait()): result.append(1) return True - t = tasks.Task(c1(result), loop=self.loop) + t = asyncio.Task(c1(result), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual([], result) @@ -359,59 +361,52 @@ def c1(result): self.assertTrue(t.result()) -class ConditionTests(unittest.TestCase): +class ConditionTests(test_utils.TestCase): def setUp(self): - self.loop = test_utils.TestLoop() - events.set_event_loop(None) - - def tearDown(self): - self.loop.close() + self.loop = self.new_test_loop() def test_ctor_loop(self): - loop = unittest.mock.Mock() - cond = locks.Condition(loop=loop) + loop = mock.Mock() + cond = asyncio.Condition(loop=loop) self.assertIs(cond._loop, loop) - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) self.assertIs(cond._loop, self.loop) def test_ctor_noloop(self): - try: - events.set_event_loop(self.loop) - cond = locks.Condition() - self.assertIs(cond._loop, self.loop) - finally: - events.set_event_loop(None) + asyncio.set_event_loop(self.loop) + cond = asyncio.Condition() + self.assertIs(cond._loop, self.loop) def test_wait(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) result = [] - @tasks.coroutine + @asyncio.coroutine def c1(result): yield from cond.acquire() if (yield from cond.wait()): result.append(1) return True - @tasks.coroutine + @asyncio.coroutine def c2(result): yield from cond.acquire() if (yield from cond.wait()): result.append(2) return True - @tasks.coroutine + @asyncio.coroutine def c3(result): yield from cond.acquire() if (yield from cond.wait()): result.append(3) return True - t1 = tasks.Task(c1(result), loop=self.loop) - t2 = tasks.Task(c2(result), loop=self.loop) - t3 = tasks.Task(c3(result), loop=self.loop) + t1 = asyncio.Task(c1(result), loop=self.loop) + t2 = asyncio.Task(c2(result), loop=self.loop) + t3 = asyncio.Task(c3(result), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual([], result) @@ -451,25 +446,25 @@ def c3(result): self.assertTrue(t3.result()) def test_wait_cancel(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) self.loop.run_until_complete(cond.acquire()) - wait = tasks.Task(cond.wait(), loop=self.loop) + wait = asyncio.Task(cond.wait(), loop=self.loop) self.loop.call_soon(wait.cancel) self.assertRaises( - futures.CancelledError, + asyncio.CancelledError, self.loop.run_until_complete, wait) self.assertFalse(cond._waiters) self.assertTrue(cond.locked()) def test_wait_unacquired(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) self.assertRaises( RuntimeError, self.loop.run_until_complete, cond.wait()) def test_wait_for(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) presult = False def predicate(): @@ -477,7 +472,7 @@ def predicate(): result = [] - @tasks.coroutine + @asyncio.coroutine def c1(result): yield from cond.acquire() if (yield from cond.wait_for(predicate)): @@ -485,7 +480,7 @@ def c1(result): cond.release() return True - t = tasks.Task(c1(result), loop=self.loop) + t = asyncio.Task(c1(result), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual([], result) @@ -507,7 +502,7 @@ def c1(result): self.assertTrue(t.result()) def test_wait_for_unacquired(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) # predicate can return true immediately res = self.loop.run_until_complete(cond.wait_for(lambda: [1, 2, 3])) @@ -519,10 +514,10 @@ def test_wait_for_unacquired(self): cond.wait_for(lambda: False)) def test_notify(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) result = [] - @tasks.coroutine + @asyncio.coroutine def c1(result): yield from cond.acquire() if (yield from cond.wait()): @@ -530,7 +525,7 @@ def c1(result): cond.release() return True - @tasks.coroutine + @asyncio.coroutine def c2(result): yield from cond.acquire() if (yield from cond.wait()): @@ -538,7 +533,7 @@ def c2(result): cond.release() return True - @tasks.coroutine + @asyncio.coroutine def c3(result): yield from cond.acquire() if (yield from cond.wait()): @@ -546,9 +541,9 @@ def c3(result): cond.release() return True - t1 = tasks.Task(c1(result), loop=self.loop) - t2 = tasks.Task(c2(result), loop=self.loop) - t3 = tasks.Task(c3(result), loop=self.loop) + t1 = asyncio.Task(c1(result), loop=self.loop) + t2 = asyncio.Task(c2(result), loop=self.loop) + t3 = asyncio.Task(c3(result), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual([], result) @@ -574,11 +569,11 @@ def c3(result): self.assertTrue(t3.result()) def test_notify_all(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) result = [] - @tasks.coroutine + @asyncio.coroutine def c1(result): yield from cond.acquire() if (yield from cond.wait()): @@ -586,7 +581,7 @@ def c1(result): cond.release() return True - @tasks.coroutine + @asyncio.coroutine def c2(result): yield from cond.acquire() if (yield from cond.wait()): @@ -594,8 +589,8 @@ def c2(result): cond.release() return True - t1 = tasks.Task(c1(result), loop=self.loop) - t2 = tasks.Task(c2(result), loop=self.loop) + t1 = asyncio.Task(c1(result), loop=self.loop) + t2 = asyncio.Task(c2(result), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual([], result) @@ -612,33 +607,33 @@ def c2(result): self.assertTrue(t2.result()) def test_notify_unacquired(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) self.assertRaises(RuntimeError, cond.notify) def test_notify_all_unacquired(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) self.assertRaises(RuntimeError, cond.notify_all) def test_repr(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) self.assertTrue('unlocked' in repr(cond)) self.assertTrue(RGX_REPR.match(repr(cond))) self.loop.run_until_complete(cond.acquire()) self.assertTrue('locked' in repr(cond)) - cond._waiters.append(unittest.mock.Mock()) + cond._waiters.append(mock.Mock()) self.assertTrue('waiters:1' in repr(cond)) self.assertTrue(RGX_REPR.match(repr(cond))) - cond._waiters.append(unittest.mock.Mock()) + cond._waiters.append(mock.Mock()) self.assertTrue('waiters:2' in repr(cond)) self.assertTrue(RGX_REPR.match(repr(cond))) def test_context_manager(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def acquire_cond(): return (yield from cond) @@ -648,7 +643,7 @@ def acquire_cond(): self.assertFalse(cond.locked()) def test_context_manager_no_yield(self): - cond = locks.Condition(loop=self.loop) + cond = asyncio.Condition(loop=self.loop) try: with cond: @@ -658,38 +653,48 @@ def test_context_manager_no_yield(self): str(err), '"yield from" should be used as context manager expression') + self.assertFalse(cond.locked()) -class SemaphoreTests(unittest.TestCase): + def test_explicit_lock(self): + lock = asyncio.Lock(loop=self.loop) + cond = asyncio.Condition(lock, loop=self.loop) - def setUp(self): - self.loop = test_utils.TestLoop() - events.set_event_loop(None) + self.assertIs(cond._lock, lock) + self.assertIs(cond._loop, lock._loop) + + def test_ambiguous_loops(self): + loop = self.new_test_loop() + self.addCleanup(loop.close) + + lock = asyncio.Lock(loop=self.loop) + with self.assertRaises(ValueError): + asyncio.Condition(lock, loop=loop) - def tearDown(self): - self.loop.close() + +class SemaphoreTests(test_utils.TestCase): + + def setUp(self): + self.loop = self.new_test_loop() def test_ctor_loop(self): - loop = unittest.mock.Mock() - sem = locks.Semaphore(loop=loop) + loop = mock.Mock() + sem = asyncio.Semaphore(loop=loop) self.assertIs(sem._loop, loop) - sem = locks.Semaphore(loop=self.loop) + sem = asyncio.Semaphore(loop=self.loop) self.assertIs(sem._loop, self.loop) def test_ctor_noloop(self): - try: - events.set_event_loop(self.loop) - sem = locks.Semaphore() - self.assertIs(sem._loop, self.loop) - finally: - events.set_event_loop(None) + asyncio.set_event_loop(self.loop) + sem = asyncio.Semaphore() + self.assertIs(sem._loop, self.loop) def test_initial_value_zero(self): - sem = locks.Semaphore(0, loop=self.loop) + sem = asyncio.Semaphore(0, loop=self.loop) self.assertTrue(sem.locked()) def test_repr(self): - sem = locks.Semaphore(loop=self.loop) + sem = asyncio.Semaphore(loop=self.loop) self.assertTrue(repr(sem).endswith('[unlocked,value:1]>')) self.assertTrue(RGX_REPR.match(repr(sem))) @@ -698,19 +703,19 @@ def test_repr(self): self.assertTrue('waiters' not in repr(sem)) self.assertTrue(RGX_REPR.match(repr(sem))) - sem._waiters.append(unittest.mock.Mock()) + sem._waiters.append(mock.Mock()) self.assertTrue('waiters:1' in repr(sem)) self.assertTrue(RGX_REPR.match(repr(sem))) - sem._waiters.append(unittest.mock.Mock()) + sem._waiters.append(mock.Mock()) self.assertTrue('waiters:2' in repr(sem)) self.assertTrue(RGX_REPR.match(repr(sem))) def test_semaphore(self): - sem = locks.Semaphore(loop=self.loop) + sem = asyncio.Semaphore(loop=self.loop) self.assertEqual(1, sem._value) - @tasks.coroutine + @asyncio.coroutine def acquire_lock(): return (yield from sem) @@ -725,43 +730,43 @@ def acquire_lock(): self.assertEqual(1, sem._value) def test_semaphore_value(self): - self.assertRaises(ValueError, locks.Semaphore, -1) + self.assertRaises(ValueError, asyncio.Semaphore, -1) def test_acquire(self): - sem = locks.Semaphore(3, loop=self.loop) + sem = asyncio.Semaphore(3, loop=self.loop) result = [] self.assertTrue(self.loop.run_until_complete(sem.acquire())) self.assertTrue(self.loop.run_until_complete(sem.acquire())) self.assertFalse(sem.locked()) - @tasks.coroutine + @asyncio.coroutine def c1(result): yield from sem.acquire() result.append(1) return True - @tasks.coroutine + @asyncio.coroutine def c2(result): yield from sem.acquire() result.append(2) return True - @tasks.coroutine + @asyncio.coroutine def c3(result): yield from sem.acquire() result.append(3) return True - @tasks.coroutine + @asyncio.coroutine def c4(result): yield from sem.acquire() result.append(4) return True - t1 = tasks.Task(c1(result), loop=self.loop) - t2 = tasks.Task(c2(result), loop=self.loop) - t3 = tasks.Task(c3(result), loop=self.loop) + t1 = asyncio.Task(c1(result), loop=self.loop) + t2 = asyncio.Task(c2(result), loop=self.loop) + t3 = asyncio.Task(c3(result), loop=self.loop) test_utils.run_briefly(self.loop) self.assertEqual([1], result) @@ -769,7 +774,7 @@ def c4(result): self.assertEqual(2, len(sem._waiters)) self.assertEqual(0, sem._value) - t4 = tasks.Task(c4(result), loop=self.loop) + t4 = asyncio.Task(c4(result), loop=self.loop) sem.release() sem.release() @@ -777,40 +782,76 @@ def c4(result): test_utils.run_briefly(self.loop) self.assertEqual(0, sem._value) - self.assertEqual([1, 2, 3], result) + self.assertEqual(3, len(result)) self.assertTrue(sem.locked()) self.assertEqual(1, len(sem._waiters)) self.assertEqual(0, sem._value) self.assertTrue(t1.done()) self.assertTrue(t1.result()) - self.assertTrue(t2.done()) - self.assertTrue(t2.result()) - self.assertTrue(t3.done()) - self.assertTrue(t3.result()) - self.assertFalse(t4.done()) + race_tasks = [t2, t3, t4] + done_tasks = [t for t in race_tasks if t.done() and t.result()] + self.assertTrue(2, len(done_tasks)) # cleanup locked semaphore sem.release() + self.loop.run_until_complete(asyncio.gather(*race_tasks)) def test_acquire_cancel(self): - sem = locks.Semaphore(loop=self.loop) + sem = asyncio.Semaphore(loop=self.loop) self.loop.run_until_complete(sem.acquire()) - acquire = tasks.Task(sem.acquire(), loop=self.loop) + acquire = asyncio.Task(sem.acquire(), loop=self.loop) self.loop.call_soon(acquire.cancel) self.assertRaises( - futures.CancelledError, + asyncio.CancelledError, self.loop.run_until_complete, acquire) - self.assertFalse(sem._waiters) + self.assertTrue((not sem._waiters) or + all(waiter.done() for waiter in sem._waiters)) + + def test_acquire_cancel_before_awoken(self): + sem = asyncio.Semaphore(value=0, loop=self.loop) + + t1 = asyncio.Task(sem.acquire(), loop=self.loop) + t2 = asyncio.Task(sem.acquire(), loop=self.loop) + t3 = asyncio.Task(sem.acquire(), loop=self.loop) + t4 = asyncio.Task(sem.acquire(), loop=self.loop) + + test_utils.run_briefly(self.loop) + + sem.release() + t1.cancel() + t2.cancel() + + test_utils.run_briefly(self.loop) + num_done = sum(t.done() for t in [t3, t4]) + self.assertEqual(num_done, 1) + + t3.cancel() + t4.cancel() + test_utils.run_briefly(self.loop) + + def test_acquire_hang(self): + sem = asyncio.Semaphore(value=0, loop=self.loop) + + t1 = asyncio.Task(sem.acquire(), loop=self.loop) + t2 = asyncio.Task(sem.acquire(), loop=self.loop) + + test_utils.run_briefly(self.loop) + + sem.release() + t1.cancel() + + test_utils.run_briefly(self.loop) + self.assertTrue(sem.locked()) def test_release_not_acquired(self): - sem = locks.BoundedSemaphore(loop=self.loop) + sem = asyncio.BoundedSemaphore(loop=self.loop) self.assertRaises(ValueError, sem.release) def test_release_no_waiters(self): - sem = locks.Semaphore(loop=self.loop) + sem = asyncio.Semaphore(loop=self.loop) self.loop.run_until_complete(sem.acquire()) self.assertTrue(sem.locked()) @@ -818,9 +859,9 @@ def test_release_no_waiters(self): self.assertFalse(sem.locked()) def test_context_manager(self): - sem = locks.Semaphore(2, loop=self.loop) + sem = asyncio.Semaphore(2, loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def acquire_lock(): return (yield from sem) @@ -833,6 +874,19 @@ def acquire_lock(): self.assertEqual(2, sem._value) + def test_context_manager_no_yield(self): + sem = asyncio.Semaphore(2, loop=self.loop) + + try: + with sem: + self.fail('RuntimeError is not raised in with expression') + except RuntimeError as err: + self.assertEqual( + str(err), + '"yield from" should be used as context manager expression') + + self.assertEqual(2, sem._value) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_pep492.py b/Lib/test/test_asyncio/test_pep492.py new file mode 100644 index 000000000000..41e1b8a9e0cc --- /dev/null +++ b/Lib/test/test_asyncio/test_pep492.py @@ -0,0 +1,208 @@ +"""Tests support for new syntax introduced by PEP 492.""" + +import collections.abc +import types +import unittest + +from test import support +from unittest import mock + +import asyncio +from asyncio import test_utils + + +class BaseTest(test_utils.TestCase): + + def setUp(self): + self.loop = asyncio.BaseEventLoop() + self.loop._process_events = mock.Mock() + self.loop._selector = mock.Mock() + self.loop._selector.select.return_value = () + self.set_event_loop(self.loop) + + +class LockTests(BaseTest): + + def test_context_manager_async_with(self): + primitives = [ + asyncio.Lock(loop=self.loop), + asyncio.Condition(loop=self.loop), + asyncio.Semaphore(loop=self.loop), + asyncio.BoundedSemaphore(loop=self.loop), + ] + + async def test(lock): + await asyncio.sleep(0.01, loop=self.loop) + self.assertFalse(lock.locked()) + async with lock as _lock: + self.assertIs(_lock, None) + self.assertTrue(lock.locked()) + await asyncio.sleep(0.01, loop=self.loop) + self.assertTrue(lock.locked()) + self.assertFalse(lock.locked()) + + for primitive in primitives: + self.loop.run_until_complete(test(primitive)) + self.assertFalse(primitive.locked()) + + def test_context_manager_with_await(self): + primitives = [ + asyncio.Lock(loop=self.loop), + asyncio.Condition(loop=self.loop), + asyncio.Semaphore(loop=self.loop), + asyncio.BoundedSemaphore(loop=self.loop), + ] + + async def test(lock): + await asyncio.sleep(0.01, loop=self.loop) + self.assertFalse(lock.locked()) + with await lock as _lock: + self.assertIs(_lock, None) + self.assertTrue(lock.locked()) + await asyncio.sleep(0.01, loop=self.loop) + self.assertTrue(lock.locked()) + self.assertFalse(lock.locked()) + + for primitive in primitives: + self.loop.run_until_complete(test(primitive)) + self.assertFalse(primitive.locked()) + + +class StreamReaderTests(BaseTest): + + def test_readline(self): + DATA = b'line1\nline2\nline3' + + stream = asyncio.StreamReader(loop=self.loop) + stream.feed_data(DATA) + stream.feed_eof() + + async def reader(): + data = [] + async for line in stream: + data.append(line) + return data + + data = self.loop.run_until_complete(reader()) + self.assertEqual(data, [b'line1\n', b'line2\n', b'line3']) + + +class CoroutineTests(BaseTest): + + def test_iscoroutine(self): + async def foo(): pass + + f = foo() + try: + self.assertTrue(asyncio.iscoroutine(f)) + finally: + f.close() # silence warning + + # Test that asyncio.iscoroutine() uses collections.abc.Coroutine + class FakeCoro: + def send(self, value): pass + def throw(self, typ, val=None, tb=None): pass + def close(self): pass + def __await__(self): yield + + self.assertTrue(asyncio.iscoroutine(FakeCoro())) + + def test_iscoroutinefunction(self): + async def foo(): pass + self.assertTrue(asyncio.iscoroutinefunction(foo)) + + def test_function_returning_awaitable(self): + class Awaitable: + def __await__(self): + return ('spam',) + + @asyncio.coroutine + def func(): + return Awaitable() + + coro = func() + self.assertEqual(coro.send(None), 'spam') + coro.close() + + def test_async_def_coroutines(self): + async def bar(): + return 'spam' + async def foo(): + return await bar() + + # production mode + data = self.loop.run_until_complete(foo()) + self.assertEqual(data, 'spam') + + # debug mode + self.loop.set_debug(True) + data = self.loop.run_until_complete(foo()) + self.assertEqual(data, 'spam') + + @mock.patch('asyncio.coroutines.logger') + def test_async_def_wrapped(self, m_log): + async def foo(): + pass + async def start(): + foo_coro = foo() + self.assertRegex( + repr(foo_coro), + r'') + + with support.check_warnings((r'.*foo.*was never', + RuntimeWarning)): + foo_coro = None + support.gc_collect() + self.assertTrue(m_log.error.called) + message = m_log.error.call_args[0][0] + self.assertRegex(message, + r'CoroWrapper.*foo.*was never') + + self.loop.set_debug(True) + self.loop.run_until_complete(start()) + + async def start(): + foo_coro = foo() + task = asyncio.ensure_future(foo_coro, loop=self.loop) + self.assertRegex(repr(task), r'Task.*foo.*running') + + self.loop.run_until_complete(start()) + + + def test_types_coroutine(self): + def gen(): + yield from () + return 'spam' + + @types.coroutine + def func(): + return gen() + + async def coro(): + wrapper = func() + self.assertIsInstance(wrapper, types._GeneratorWrapper) + return await wrapper + + data = self.loop.run_until_complete(coro()) + self.assertEqual(data, 'spam') + + def test_task_print_stack(self): + T = None + + async def foo(): + f = T.get_stack(limit=1) + try: + self.assertEqual(f[0].f_code.co_name, 'foo') + finally: + f = None + + async def runner(): + nonlocal T + T = asyncio.ensure_future(foo(), loop=self.loop) + await T + + self.loop.run_until_complete(runner()) + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py index 5a2a51c42e6e..fcd9ab1e18f6 100644 --- a/Lib/test/test_asyncio/test_proactor_events.py +++ b/Lib/test/test_asyncio/test_proactor_events.py @@ -2,7 +2,7 @@ import socket import unittest -import unittest.mock +from unittest import mock import asyncio from asyncio.proactor_events import BaseProactorEventLoop @@ -12,26 +12,41 @@ from asyncio import test_utils -class ProactorSocketTransportTests(unittest.TestCase): +def close_transport(transport): + # Don't call transport.close() because the event loop and the IOCP proactor + # are mocked + if transport._sock is None: + return + transport._sock.close() + transport._sock = None + + +class ProactorSocketTransportTests(test_utils.TestCase): def setUp(self): - self.loop = test_utils.TestLoop() - self.proactor = unittest.mock.Mock() + self.loop = self.new_test_loop() + self.addCleanup(self.loop.close) + self.proactor = mock.Mock() self.loop._proactor = self.proactor self.protocol = test_utils.make_test_protocol(asyncio.Protocol) - self.sock = unittest.mock.Mock(socket.socket) + self.sock = mock.Mock(socket.socket) + + def socket_transport(self, waiter=None): + transport = _ProactorSocketTransport(self.loop, self.sock, + self.protocol, waiter=waiter) + self.addCleanup(close_transport, transport) + return transport def test_ctor(self): fut = asyncio.Future(loop=self.loop) - tr = _ProactorSocketTransport( - self.loop, self.sock, self.protocol, fut) + tr = self.socket_transport(waiter=fut) test_utils.run_briefly(self.loop) self.assertIsNone(fut.result()) self.protocol.connection_made(tr) self.proactor.recv.assert_called_with(self.sock, 4096) def test_loop_reading(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._loop_reading() self.loop._proactor.recv.assert_called_with(self.sock, 4096) self.assertFalse(self.protocol.data_received.called) @@ -41,8 +56,7 @@ def test_loop_reading_data(self): res = asyncio.Future(loop=self.loop) res.set_result(b'data') - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - + tr = self.socket_transport() tr._read_fut = res tr._loop_reading(res) self.loop._proactor.recv.assert_called_with(self.sock, 4096) @@ -52,11 +66,10 @@ def test_loop_reading_no_data(self): res = asyncio.Future(loop=self.loop) res.set_result(b'') - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - + tr = self.socket_transport() self.assertRaises(AssertionError, tr._loop_reading, res) - tr.close = unittest.mock.Mock() + tr.close = mock.Mock() tr._read_fut = res tr._loop_reading(res) self.assertFalse(self.loop._proactor.recv.called) @@ -66,35 +79,37 @@ def test_loop_reading_no_data(self): def test_loop_reading_aborted(self): err = self.loop._proactor.recv.side_effect = ConnectionAbortedError() - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - tr._fatal_error = unittest.mock.Mock() + tr = self.socket_transport() + tr._fatal_error = mock.Mock() tr._loop_reading() - tr._fatal_error.assert_called_with(err) + tr._fatal_error.assert_called_with( + err, + 'Fatal read error on pipe transport') def test_loop_reading_aborted_closing(self): self.loop._proactor.recv.side_effect = ConnectionAbortedError() - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._closing = True - tr._fatal_error = unittest.mock.Mock() + tr._fatal_error = mock.Mock() tr._loop_reading() self.assertFalse(tr._fatal_error.called) def test_loop_reading_aborted_is_fatal(self): self.loop._proactor.recv.side_effect = ConnectionAbortedError() - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._closing = False - tr._fatal_error = unittest.mock.Mock() + tr._fatal_error = mock.Mock() tr._loop_reading() self.assertTrue(tr._fatal_error.called) def test_loop_reading_conn_reset_lost(self): err = self.loop._proactor.recv.side_effect = ConnectionResetError() - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._closing = False - tr._fatal_error = unittest.mock.Mock() - tr._force_close = unittest.mock.Mock() + tr._fatal_error = mock.Mock() + tr._force_close = mock.Mock() tr._loop_reading() self.assertFalse(tr._fatal_error.called) tr._force_close.assert_called_with(err) @@ -102,47 +117,51 @@ def test_loop_reading_conn_reset_lost(self): def test_loop_reading_exception(self): err = self.loop._proactor.recv.side_effect = (OSError()) - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - tr._fatal_error = unittest.mock.Mock() + tr = self.socket_transport() + tr._fatal_error = mock.Mock() tr._loop_reading() - tr._fatal_error.assert_called_with(err) + tr._fatal_error.assert_called_with( + err, + 'Fatal read error on pipe transport') def test_write(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - tr._loop_writing = unittest.mock.Mock() + tr = self.socket_transport() + tr._loop_writing = mock.Mock() tr.write(b'data') - self.assertEqual(tr._buffer, [b'data']) - self.assertTrue(tr._loop_writing.called) + self.assertEqual(tr._buffer, None) + tr._loop_writing.assert_called_with(data=b'data') def test_write_no_data(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr.write(b'') self.assertFalse(tr._buffer) def test_write_more(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - tr._write_fut = unittest.mock.Mock() - tr._loop_writing = unittest.mock.Mock() + tr = self.socket_transport() + tr._write_fut = mock.Mock() + tr._loop_writing = mock.Mock() tr.write(b'data') - self.assertEqual(tr._buffer, [b'data']) + self.assertEqual(tr._buffer, b'data') self.assertFalse(tr._loop_writing.called) def test_loop_writing(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - tr._buffer = [b'da', b'ta'] + tr = self.socket_transport() + tr._buffer = bytearray(b'data') tr._loop_writing() self.loop._proactor.send.assert_called_with(self.sock, b'data') self.loop._proactor.send.return_value.add_done_callback.\ assert_called_with(tr._loop_writing) - @unittest.mock.patch('asyncio.proactor_events.logger') + @mock.patch('asyncio.proactor_events.logger') def test_loop_writing_err(self, m_log): err = self.loop._proactor.send.side_effect = OSError() - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - tr._fatal_error = unittest.mock.Mock() + tr = self.socket_transport() + tr._fatal_error = mock.Mock() tr._buffer = [b'da', b'ta'] tr._loop_writing() - tr._fatal_error.assert_called_with(err) + tr._fatal_error.assert_called_with( + err, + 'Fatal write error on pipe transport') tr._conn_lost = 1 tr.write(b'data') @@ -150,14 +169,14 @@ def test_loop_writing_err(self, m_log): tr.write(b'data') tr.write(b'data') tr.write(b'data') - self.assertEqual(tr._buffer, []) + self.assertEqual(tr._buffer, None) m_log.warning.assert_called_with('socket.send() raised exception.') def test_loop_writing_stop(self): fut = asyncio.Future(loop=self.loop) fut.set_result(b'data') - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._write_fut = fut tr._loop_writing(fut) self.assertIsNone(tr._write_fut) @@ -166,7 +185,7 @@ def test_loop_writing_closing(self): fut = asyncio.Future(loop=self.loop) fut.set_result(1) - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._write_fut = fut tr.close() tr._loop_writing(fut) @@ -175,13 +194,13 @@ def test_loop_writing_closing(self): self.protocol.connection_lost.assert_called_with(None) def test_abort(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - tr._force_close = unittest.mock.Mock() + tr = self.socket_transport() + tr._force_close = mock.Mock() tr.abort() tr._force_close.assert_called_with(None) def test_close(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr.close() test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) @@ -194,66 +213,65 @@ def test_close(self): self.assertFalse(self.protocol.connection_lost.called) def test_close_write_fut(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - tr._write_fut = unittest.mock.Mock() + tr = self.socket_transport() + tr._write_fut = mock.Mock() tr.close() test_utils.run_briefly(self.loop) self.assertFalse(self.protocol.connection_lost.called) def test_close_buffer(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._buffer = [b'data'] tr.close() test_utils.run_briefly(self.loop) self.assertFalse(self.protocol.connection_lost.called) - @unittest.mock.patch('asyncio.proactor_events.logger') + @mock.patch('asyncio.base_events.logger') def test_fatal_error(self, m_logging): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) - tr._force_close = unittest.mock.Mock() + tr = self.socket_transport() + tr._force_close = mock.Mock() tr._fatal_error(None) self.assertTrue(tr._force_close.called) - self.assertTrue(m_logging.exception.called) + self.assertTrue(m_logging.error.called) def test_force_close(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._buffer = [b'data'] - read_fut = tr._read_fut = unittest.mock.Mock() - write_fut = tr._write_fut = unittest.mock.Mock() + read_fut = tr._read_fut = mock.Mock() + write_fut = tr._write_fut = mock.Mock() tr._force_close(None) read_fut.cancel.assert_called_with() write_fut.cancel.assert_called_with() test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) - self.assertEqual([], tr._buffer) + self.assertEqual(None, tr._buffer) self.assertEqual(tr._conn_lost, 1) def test_force_close_idempotent(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._closing = True tr._force_close(None) test_utils.run_briefly(self.loop) self.assertFalse(self.protocol.connection_lost.called) def test_fatal_error_2(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._buffer = [b'data'] tr._force_close(None) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) - self.assertEqual([], tr._buffer) + self.assertEqual(None, tr._buffer) def test_call_connection_lost(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() tr._call_connection_lost(None) self.assertTrue(self.protocol.connection_lost.called) self.assertTrue(self.sock.close.called) def test_write_eof(self): - tr = _ProactorSocketTransport( - self.loop, self.sock, self.protocol) + tr = self.socket_transport() self.assertTrue(tr.can_write_eof()) tr.write_eof() self.sock.shutdown.assert_called_with(socket.SHUT_WR) @@ -262,7 +280,7 @@ def test_write_eof(self): tr.close() def test_write_eof_buffer(self): - tr = _ProactorSocketTransport(self.loop, self.sock, self.protocol) + tr = self.socket_transport() f = asyncio.Future(loop=self.loop) tr._loop._proactor.send.return_value = f tr.write(b'data') @@ -306,11 +324,10 @@ def test_write_eof_duplex_pipe(self): self.assertFalse(tr.can_write_eof()) with self.assertRaises(NotImplementedError): tr.write_eof() - tr.close() + close_transport(tr) def test_pause_resume_reading(self): - tr = _ProactorSocketTransport( - self.loop, self.sock, self.protocol) + tr = self.socket_transport() futures = [] for msg in [b'data1', b'data2', b'data3', b'data4', b'']: f = asyncio.Future(loop=self.loop) @@ -337,30 +354,111 @@ def test_pause_resume_reading(self): tr.close() -class BaseProactorEventLoopTests(unittest.TestCase): + def pause_writing_transport(self, high): + tr = self.socket_transport() + tr.set_write_buffer_limits(high=high) + + self.assertEqual(tr.get_write_buffer_size(), 0) + self.assertFalse(self.protocol.pause_writing.called) + self.assertFalse(self.protocol.resume_writing.called) + return tr + + def test_pause_resume_writing(self): + tr = self.pause_writing_transport(high=4) + + # write a large chunk, must pause writing + fut = asyncio.Future(loop=self.loop) + self.loop._proactor.send.return_value = fut + tr.write(b'large data') + self.loop._run_once() + self.assertTrue(self.protocol.pause_writing.called) + + # flush the buffer + fut.set_result(None) + self.loop._run_once() + self.assertEqual(tr.get_write_buffer_size(), 0) + self.assertTrue(self.protocol.resume_writing.called) + + def test_pause_writing_2write(self): + tr = self.pause_writing_transport(high=4) + + # first short write, the buffer is not full (3 <= 4) + fut1 = asyncio.Future(loop=self.loop) + self.loop._proactor.send.return_value = fut1 + tr.write(b'123') + self.loop._run_once() + self.assertEqual(tr.get_write_buffer_size(), 3) + self.assertFalse(self.protocol.pause_writing.called) + + # fill the buffer, must pause writing (6 > 4) + tr.write(b'abc') + self.loop._run_once() + self.assertEqual(tr.get_write_buffer_size(), 6) + self.assertTrue(self.protocol.pause_writing.called) + + def test_pause_writing_3write(self): + tr = self.pause_writing_transport(high=4) + + # first short write, the buffer is not full (1 <= 4) + fut = asyncio.Future(loop=self.loop) + self.loop._proactor.send.return_value = fut + tr.write(b'1') + self.loop._run_once() + self.assertEqual(tr.get_write_buffer_size(), 1) + self.assertFalse(self.protocol.pause_writing.called) + + # second short write, the buffer is not full (3 <= 4) + tr.write(b'23') + self.loop._run_once() + self.assertEqual(tr.get_write_buffer_size(), 3) + self.assertFalse(self.protocol.pause_writing.called) + + # fill the buffer, must pause writing (6 > 4) + tr.write(b'abc') + self.loop._run_once() + self.assertEqual(tr.get_write_buffer_size(), 6) + self.assertTrue(self.protocol.pause_writing.called) + + def test_dont_pause_writing(self): + tr = self.pause_writing_transport(high=4) + + # write a large chunk which completes immedialty, + # it should not pause writing + fut = asyncio.Future(loop=self.loop) + fut.set_result(None) + self.loop._proactor.send.return_value = fut + tr.write(b'very large data') + self.loop._run_once() + self.assertEqual(tr.get_write_buffer_size(), 0) + self.assertFalse(self.protocol.pause_writing.called) + + +class BaseProactorEventLoopTests(test_utils.TestCase): def setUp(self): - self.sock = unittest.mock.Mock(socket.socket) - self.proactor = unittest.mock.Mock() + self.sock = mock.Mock(socket.socket) + self.proactor = mock.Mock() - self.ssock, self.csock = unittest.mock.Mock(), unittest.mock.Mock() + self.ssock, self.csock = mock.Mock(), mock.Mock() class EventLoop(BaseProactorEventLoop): def _socketpair(s): return (self.ssock, self.csock) self.loop = EventLoop(self.proactor) + self.set_event_loop(self.loop) - @unittest.mock.patch.object(BaseProactorEventLoop, 'call_soon') - @unittest.mock.patch.object(BaseProactorEventLoop, '_socketpair') + @mock.patch.object(BaseProactorEventLoop, 'call_soon') + @mock.patch.object(BaseProactorEventLoop, '_socketpair') def test_ctor(self, socketpair, call_soon): ssock, csock = socketpair.return_value = ( - unittest.mock.Mock(), unittest.mock.Mock()) + mock.Mock(), mock.Mock()) loop = BaseProactorEventLoop(self.proactor) self.assertIs(loop._ssock, ssock) self.assertIs(loop._csock, csock) self.assertEqual(loop._internal_fds, 1) call_soon.assert_called_with(loop._loop_self_reading) + loop.close() def test_close_self_pipe(self): self.loop._close_self_pipe() @@ -370,8 +468,11 @@ def test_close_self_pipe(self): self.assertIsNone(self.loop._ssock) self.assertIsNone(self.loop._csock) + # Don't call close(): _close_self_pipe() cannot be called twice + self.loop._closed = True + def test_close(self): - self.loop._close_self_pipe = unittest.mock.Mock() + self.loop._close_self_pipe = mock.Mock() self.loop.close() self.assertTrue(self.loop._close_self_pipe.called) self.assertTrue(self.proactor.close.called) @@ -398,12 +499,17 @@ def test_sock_accept(self): self.proactor.accept.assert_called_with(self.sock) def test_socketpair(self): + class EventLoop(BaseProactorEventLoop): + # override the destructor to not log a ResourceWarning + def __del__(self): + pass self.assertRaises( - NotImplementedError, BaseProactorEventLoop, self.proactor) + NotImplementedError, EventLoop, self.proactor) def test_make_socket_transport(self): - tr = self.loop._make_socket_transport(self.sock, unittest.mock.Mock()) + tr = self.loop._make_socket_transport(self.sock, asyncio.Protocol()) self.assertIsInstance(tr, _ProactorSocketTransport) + close_transport(tr) def test_loop_self_reading(self): self.loop._loop_self_reading() @@ -412,7 +518,7 @@ def test_loop_self_reading(self): self.loop._loop_self_reading) def test_loop_self_reading_fut(self): - fut = unittest.mock.Mock() + fut = mock.Mock() self.loop._loop_self_reading(fut) self.assertTrue(fut.result.called) self.proactor.recv.assert_called_with(self.ssock, 4096) @@ -420,22 +526,23 @@ def test_loop_self_reading_fut(self): self.loop._loop_self_reading) def test_loop_self_reading_exception(self): - self.loop.close = unittest.mock.Mock() + self.loop.close = mock.Mock() + self.loop.call_exception_handler = mock.Mock() self.proactor.recv.side_effect = OSError() - self.assertRaises(OSError, self.loop._loop_self_reading) - self.assertTrue(self.loop.close.called) + self.loop._loop_self_reading() + self.assertTrue(self.loop.call_exception_handler.called) def test_write_to_self(self): self.loop._write_to_self() - self.csock.send.assert_called_with(b'x') + self.csock.send.assert_called_with(b'\0') def test_process_events(self): self.loop._process_events([]) - @unittest.mock.patch('asyncio.proactor_events.logger') + @mock.patch('asyncio.base_events.logger') def test_create_server(self, m_log): - pf = unittest.mock.Mock() - call_soon = self.loop.call_soon = unittest.mock.Mock() + pf = mock.Mock() + call_soon = self.loop.call_soon = mock.Mock() self.loop._start_serving(pf, self.sock) self.assertTrue(call_soon.called) @@ -446,10 +553,10 @@ def test_create_server(self, m_log): self.proactor.accept.assert_called_with(self.sock) # conn - fut = unittest.mock.Mock() - fut.result.return_value = (unittest.mock.Mock(), unittest.mock.Mock()) + fut = mock.Mock() + fut.result.return_value = (mock.Mock(), mock.Mock()) - make_tr = self.loop._make_socket_transport = unittest.mock.Mock() + make_tr = self.loop._make_socket_transport = mock.Mock() loop(fut) self.assertTrue(fut.result.called) self.assertTrue(make_tr.called) @@ -458,11 +565,11 @@ def test_create_server(self, m_log): fut.result.side_effect = OSError() loop(fut) self.assertTrue(self.sock.close.called) - self.assertTrue(m_log.exception.called) + self.assertTrue(m_log.error.called) def test_create_server_cancel(self): - pf = unittest.mock.Mock() - call_soon = self.loop.call_soon = unittest.mock.Mock() + pf = mock.Mock() + call_soon = self.loop.call_soon = mock.Mock() self.loop._start_serving(pf, self.sock) loop = call_soon.call_args[0][0] @@ -474,7 +581,7 @@ def test_create_server_cancel(self): self.assertTrue(self.sock.close.called) def test_stop_serving(self): - sock = unittest.mock.Mock() + sock = mock.Mock() self.loop._stop_serving(sock) self.assertTrue(sock.close.called) self.proactor._stop_serving.assert_called_with(sock) diff --git a/Lib/test/test_asyncio/test_queues.py b/Lib/test/test_asyncio/test_queues.py index 8af4ee7f9b03..591a9bb53516 100644 --- a/Lib/test/test_asyncio/test_queues.py +++ b/Lib/test/test_asyncio/test_queues.py @@ -1,24 +1,16 @@ """Tests for queues.py""" import unittest -import unittest.mock +from unittest import mock -from asyncio import events -from asyncio import futures -from asyncio import locks -from asyncio import queues -from asyncio import tasks +import asyncio from asyncio import test_utils -class _QueueTestBase(unittest.TestCase): +class _QueueTestBase(test_utils.TestCase): def setUp(self): - self.loop = test_utils.TestLoop() - events.set_event_loop(None) - - def tearDown(self): - self.loop.close() + self.loop = self.new_test_loop() class QueueBasicTests(_QueueTestBase): @@ -36,60 +28,56 @@ def gen(): self.assertAlmostEqual(0.2, when) yield 0.1 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - q = queues.Queue(loop=loop) + q = asyncio.Queue(loop=loop) self.assertTrue(fn(q).startswith('", repr(stream)) + + def test___repr__nondefault_limit(self): + stream = asyncio.StreamReader(loop=self.loop, limit=123) + self.assertEqual("", repr(stream)) + + def test___repr__eof(self): + stream = asyncio.StreamReader(loop=self.loop) + stream.feed_eof() + self.assertEqual("", repr(stream)) + + def test___repr__data(self): + stream = asyncio.StreamReader(loop=self.loop) + stream.feed_data(b'data') + self.assertEqual("", repr(stream)) + + def test___repr__exception(self): + stream = asyncio.StreamReader(loop=self.loop) + exc = RuntimeError() + stream.set_exception(exc) + self.assertEqual("", repr(stream)) + + def test___repr__waiter(self): + stream = asyncio.StreamReader(loop=self.loop) + stream._waiter = asyncio.Future(loop=self.loop) + self.assertRegex( + repr(stream), + ">") + stream._waiter.set_result(None) + self.loop.run_until_complete(stream._waiter) + stream._waiter = None + self.assertEqual("", repr(stream)) + + def test___repr__transport(self): + stream = asyncio.StreamReader(loop=self.loop) + stream._transport = mock.Mock() + stream._transport.__repr__ = mock.Mock() + stream._transport.__repr__.return_value = "" + self.assertEqual(">", repr(stream)) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py new file mode 100644 index 000000000000..38f0ceeb1f2b --- /dev/null +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -0,0 +1,472 @@ +import signal +import sys +import unittest +import warnings +from unittest import mock + +import asyncio +from asyncio import base_subprocess +from asyncio import subprocess +from asyncio import test_utils +try: + from test import support +except ImportError: + from asyncio import test_support as support +if sys.platform != 'win32': + from asyncio import unix_events + +# Program blocking +PROGRAM_BLOCKED = [sys.executable, '-c', 'import time; time.sleep(3600)'] + +# Program copying input to output +PROGRAM_CAT = [ + sys.executable, '-c', + ';'.join(('import sys', + 'data = sys.stdin.buffer.read()', + 'sys.stdout.buffer.write(data)'))] + +class TestSubprocessTransport(base_subprocess.BaseSubprocessTransport): + def _start(self, *args, **kwargs): + self._proc = mock.Mock() + self._proc.stdin = None + self._proc.stdout = None + self._proc.stderr = None + + +class SubprocessTransportTests(test_utils.TestCase): + def setUp(self): + self.loop = self.new_test_loop() + self.set_event_loop(self.loop) + + + def create_transport(self, waiter=None): + protocol = mock.Mock() + protocol.connection_made._is_coroutine = False + protocol.process_exited._is_coroutine = False + transport = TestSubprocessTransport( + self.loop, protocol, ['test'], False, + None, None, None, 0, waiter=waiter) + return (transport, protocol) + + def test_proc_exited(self): + waiter = asyncio.Future(loop=self.loop) + transport, protocol = self.create_transport(waiter) + transport._process_exited(6) + self.loop.run_until_complete(waiter) + + self.assertEqual(transport.get_returncode(), 6) + + self.assertTrue(protocol.connection_made.called) + self.assertTrue(protocol.process_exited.called) + self.assertTrue(protocol.connection_lost.called) + self.assertEqual(protocol.connection_lost.call_args[0], (None,)) + + self.assertFalse(transport._closed) + self.assertIsNone(transport._loop) + self.assertIsNone(transport._proc) + self.assertIsNone(transport._protocol) + + # methods must raise ProcessLookupError if the process exited + self.assertRaises(ProcessLookupError, + transport.send_signal, signal.SIGTERM) + self.assertRaises(ProcessLookupError, transport.terminate) + self.assertRaises(ProcessLookupError, transport.kill) + + transport.close() + + +class SubprocessMixin: + + def test_stdin_stdout(self): + args = PROGRAM_CAT + + @asyncio.coroutine + def run(data): + proc = yield from asyncio.create_subprocess_exec( + *args, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + loop=self.loop) + + # feed data + proc.stdin.write(data) + yield from proc.stdin.drain() + proc.stdin.close() + + # get output and exitcode + data = yield from proc.stdout.read() + exitcode = yield from proc.wait() + return (exitcode, data) + + task = run(b'some data') + task = asyncio.wait_for(task, 60.0, loop=self.loop) + exitcode, stdout = self.loop.run_until_complete(task) + self.assertEqual(exitcode, 0) + self.assertEqual(stdout, b'some data') + + def test_communicate(self): + args = PROGRAM_CAT + + @asyncio.coroutine + def run(data): + proc = yield from asyncio.create_subprocess_exec( + *args, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + loop=self.loop) + stdout, stderr = yield from proc.communicate(data) + return proc.returncode, stdout + + task = run(b'some data') + task = asyncio.wait_for(task, 60.0, loop=self.loop) + exitcode, stdout = self.loop.run_until_complete(task) + self.assertEqual(exitcode, 0) + self.assertEqual(stdout, b'some data') + + def test_shell(self): + create = asyncio.create_subprocess_shell('exit 7', + loop=self.loop) + proc = self.loop.run_until_complete(create) + exitcode = self.loop.run_until_complete(proc.wait()) + self.assertEqual(exitcode, 7) + + def test_start_new_session(self): + # start the new process in a new session + create = asyncio.create_subprocess_shell('exit 8', + start_new_session=True, + loop=self.loop) + proc = self.loop.run_until_complete(create) + exitcode = self.loop.run_until_complete(proc.wait()) + self.assertEqual(exitcode, 8) + + def test_kill(self): + args = PROGRAM_BLOCKED + create = asyncio.create_subprocess_exec(*args, loop=self.loop) + proc = self.loop.run_until_complete(create) + proc.kill() + returncode = self.loop.run_until_complete(proc.wait()) + if sys.platform == 'win32': + self.assertIsInstance(returncode, int) + # expect 1 but sometimes get 0 + else: + self.assertEqual(-signal.SIGKILL, returncode) + + def test_terminate(self): + args = PROGRAM_BLOCKED + create = asyncio.create_subprocess_exec(*args, loop=self.loop) + proc = self.loop.run_until_complete(create) + proc.terminate() + returncode = self.loop.run_until_complete(proc.wait()) + if sys.platform == 'win32': + self.assertIsInstance(returncode, int) + # expect 1 but sometimes get 0 + else: + self.assertEqual(-signal.SIGTERM, returncode) + + @unittest.skipIf(sys.platform == 'win32', "Don't have SIGHUP") + def test_send_signal(self): + code = 'import time; print("sleeping", flush=True); time.sleep(3600)' + args = [sys.executable, '-c', code] + create = asyncio.create_subprocess_exec(*args, + stdout=subprocess.PIPE, + loop=self.loop) + proc = self.loop.run_until_complete(create) + + @asyncio.coroutine + def send_signal(proc): + # basic synchronization to wait until the program is sleeping + line = yield from proc.stdout.readline() + self.assertEqual(line, b'sleeping\n') + + proc.send_signal(signal.SIGHUP) + returncode = (yield from proc.wait()) + return returncode + + returncode = self.loop.run_until_complete(send_signal(proc)) + self.assertEqual(-signal.SIGHUP, returncode) + + def prepare_broken_pipe_test(self): + # buffer large enough to feed the whole pipe buffer + large_data = b'x' * support.PIPE_MAX_SIZE + + # the program ends before the stdin can be feeded + create = asyncio.create_subprocess_exec( + sys.executable, '-c', 'pass', + stdin=subprocess.PIPE, + loop=self.loop) + proc = self.loop.run_until_complete(create) + return (proc, large_data) + + def test_stdin_broken_pipe(self): + proc, large_data = self.prepare_broken_pipe_test() + + @asyncio.coroutine + def write_stdin(proc, data): + proc.stdin.write(data) + yield from proc.stdin.drain() + + coro = write_stdin(proc, large_data) + # drain() must raise BrokenPipeError or ConnectionResetError + with test_utils.disable_logger(): + self.assertRaises((BrokenPipeError, ConnectionResetError), + self.loop.run_until_complete, coro) + self.loop.run_until_complete(proc.wait()) + + def test_communicate_ignore_broken_pipe(self): + proc, large_data = self.prepare_broken_pipe_test() + + # communicate() must ignore BrokenPipeError when feeding stdin + with test_utils.disable_logger(): + self.loop.run_until_complete(proc.communicate(large_data)) + self.loop.run_until_complete(proc.wait()) + + def test_pause_reading(self): + limit = 10 + size = (limit * 2 + 1) + + @asyncio.coroutine + def test_pause_reading(): + code = '\n'.join(( + 'import sys', + 'sys.stdout.write("x" * %s)' % size, + 'sys.stdout.flush()', + )) + + connect_read_pipe = self.loop.connect_read_pipe + + @asyncio.coroutine + def connect_read_pipe_mock(*args, **kw): + transport, protocol = yield from connect_read_pipe(*args, **kw) + transport.pause_reading = mock.Mock() + transport.resume_reading = mock.Mock() + return (transport, protocol) + + self.loop.connect_read_pipe = connect_read_pipe_mock + + proc = yield from asyncio.create_subprocess_exec( + sys.executable, '-c', code, + stdin=asyncio.subprocess.PIPE, + stdout=asyncio.subprocess.PIPE, + limit=limit, + loop=self.loop) + stdout_transport = proc._transport.get_pipe_transport(1) + + stdout, stderr = yield from proc.communicate() + + # The child process produced more than limit bytes of output, + # the stream reader transport should pause the protocol to not + # allocate too much memory. + return (stdout, stdout_transport) + + # Issue #22685: Ensure that the stream reader pauses the protocol + # when the child process produces too much data + stdout, transport = self.loop.run_until_complete(test_pause_reading()) + + self.assertEqual(stdout, b'x' * size) + self.assertTrue(transport.pause_reading.called) + self.assertTrue(transport.resume_reading.called) + + def test_stdin_not_inheritable(self): + # asyncio issue #209: stdin must not be inheritable, otherwise + # the Process.communicate() hangs + @asyncio.coroutine + def len_message(message): + code = 'import sys; data = sys.stdin.read(); print(len(data))' + proc = yield from asyncio.create_subprocess_exec( + sys.executable, '-c', code, + stdin=asyncio.subprocess.PIPE, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + close_fds=False, + loop=self.loop) + stdout, stderr = yield from proc.communicate(message) + exitcode = yield from proc.wait() + return (stdout, exitcode) + + output, exitcode = self.loop.run_until_complete(len_message(b'abc')) + self.assertEqual(output.rstrip(), b'3') + self.assertEqual(exitcode, 0) + + def test_cancel_process_wait(self): + # Issue #23140: cancel Process.wait() + + @asyncio.coroutine + def cancel_wait(): + proc = yield from asyncio.create_subprocess_exec( + *PROGRAM_BLOCKED, + loop=self.loop) + + # Create an internal future waiting on the process exit + task = self.loop.create_task(proc.wait()) + self.loop.call_soon(task.cancel) + try: + yield from task + except asyncio.CancelledError: + pass + + # Cancel the future + task.cancel() + + # Kill the process and wait until it is done + proc.kill() + yield from proc.wait() + + self.loop.run_until_complete(cancel_wait()) + + def test_cancel_make_subprocess_transport_exec(self): + @asyncio.coroutine + def cancel_make_transport(): + coro = asyncio.create_subprocess_exec(*PROGRAM_BLOCKED, + loop=self.loop) + task = self.loop.create_task(coro) + + self.loop.call_soon(task.cancel) + try: + yield from task + except asyncio.CancelledError: + pass + + # ignore the log: + # "Exception during subprocess creation, kill the subprocess" + with test_utils.disable_logger(): + self.loop.run_until_complete(cancel_make_transport()) + + def test_cancel_post_init(self): + @asyncio.coroutine + def cancel_make_transport(): + coro = self.loop.subprocess_exec(asyncio.SubprocessProtocol, + *PROGRAM_BLOCKED) + task = self.loop.create_task(coro) + + self.loop.call_soon(task.cancel) + try: + yield from task + except asyncio.CancelledError: + pass + + # ignore the log: + # "Exception during subprocess creation, kill the subprocess" + with test_utils.disable_logger(): + self.loop.run_until_complete(cancel_make_transport()) + test_utils.run_briefly(self.loop) + + def test_close_kill_running(self): + @asyncio.coroutine + def kill_running(): + create = self.loop.subprocess_exec(asyncio.SubprocessProtocol, + *PROGRAM_BLOCKED) + transport, protocol = yield from create + + kill_called = False + def kill(): + nonlocal kill_called + kill_called = True + orig_kill() + + proc = transport.get_extra_info('subprocess') + orig_kill = proc.kill + proc.kill = kill + returncode = transport.get_returncode() + transport.close() + yield from transport._wait() + return (returncode, kill_called) + + # Ignore "Close running child process: kill ..." log + with test_utils.disable_logger(): + returncode, killed = self.loop.run_until_complete(kill_running()) + self.assertIsNone(returncode) + + # transport.close() must kill the process if it is still running + self.assertTrue(killed) + test_utils.run_briefly(self.loop) + + def test_close_dont_kill_finished(self): + @asyncio.coroutine + def kill_running(): + create = self.loop.subprocess_exec(asyncio.SubprocessProtocol, + *PROGRAM_BLOCKED) + transport, protocol = yield from create + proc = transport.get_extra_info('subprocess') + + # kill the process (but asyncio is not notified immediatly) + proc.kill() + proc.wait() + + proc.kill = mock.Mock() + proc_returncode = proc.poll() + transport_returncode = transport.get_returncode() + transport.close() + return (proc_returncode, transport_returncode, proc.kill.called) + + # Ignore "Unknown child process pid ..." log of SafeChildWatcher, + # emitted because the test already consumes the exit status: + # proc.wait() + with test_utils.disable_logger(): + result = self.loop.run_until_complete(kill_running()) + test_utils.run_briefly(self.loop) + + proc_returncode, transport_return_code, killed = result + + self.assertIsNotNone(proc_returncode) + self.assertIsNone(transport_return_code) + + # transport.close() must not kill the process if it finished, even if + # the transport was not notified yet + self.assertFalse(killed) + + def test_popen_error(self): + # Issue #24763: check that the subprocess transport is closed + # when BaseSubprocessTransport fails + if sys.platform == 'win32': + target = 'asyncio.windows_utils.Popen' + else: + target = 'subprocess.Popen' + with mock.patch(target) as popen: + exc = ZeroDivisionError + popen.side_effect = exc + + create = asyncio.create_subprocess_exec(sys.executable, '-c', + 'pass', loop=self.loop) + with warnings.catch_warnings(record=True) as warns: + with self.assertRaises(exc): + self.loop.run_until_complete(create) + self.assertEqual(warns, []) + + +if sys.platform != 'win32': + # Unix + class SubprocessWatcherMixin(SubprocessMixin): + + Watcher = None + + def setUp(self): + policy = asyncio.get_event_loop_policy() + self.loop = policy.new_event_loop() + self.set_event_loop(self.loop) + + watcher = self.Watcher() + watcher.attach_loop(self.loop) + policy.set_child_watcher(watcher) + self.addCleanup(policy.set_child_watcher, None) + + class SubprocessSafeWatcherTests(SubprocessWatcherMixin, + test_utils.TestCase): + + Watcher = unix_events.SafeChildWatcher + + class SubprocessFastWatcherTests(SubprocessWatcherMixin, + test_utils.TestCase): + + Watcher = unix_events.FastChildWatcher + +else: + # Windows + class SubprocessProactorTests(SubprocessMixin, test_utils.TestCase): + + def setUp(self): + self.loop = asyncio.ProactorEventLoop() + self.set_event_loop(self.loop) + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 8f0d081554bb..9772baed1c5a 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -1,158 +1,395 @@ """Tests for tasks.py.""" -import gc +import contextlib +import functools +import io +import os +import re +import sys +import types import unittest -import unittest.mock -from unittest.mock import Mock +import weakref +from unittest import mock -from asyncio import events -from asyncio import futures -from asyncio import tasks +import asyncio +from asyncio import coroutines from asyncio import test_utils +try: + from test import support +except ImportError: + from asyncio import test_support as support +try: + from test.support.script_helper import assert_python_ok +except ImportError: + try: + from test.script_helper import assert_python_ok + except ImportError: + from asyncio.test_support import assert_python_ok + + +PY34 = (sys.version_info >= (3, 4)) +PY35 = (sys.version_info >= (3, 5)) + + +@asyncio.coroutine +def coroutine_function(): + pass + + +@contextlib.contextmanager +def set_coroutine_debug(enabled): + coroutines = asyncio.coroutines + + old_debug = coroutines._DEBUG + try: + coroutines._DEBUG = enabled + yield + finally: + coroutines._DEBUG = old_debug + + + +def format_coroutine(qualname, state, src, source_traceback, generator=False): + if generator: + state = '%s' % state + else: + state = '%s, defined' % state + if source_traceback is not None: + frame = source_traceback[-1] + return ('coro=<%s() %s at %s> created at %s:%s' + % (qualname, state, src, frame[0], frame[1])) + else: + return 'coro=<%s() %s at %s>' % (qualname, state, src) class Dummy: def __repr__(self): - return 'Dummy()' + return '' def __call__(self, *args): pass -class TaskTests(unittest.TestCase): +class TaskTests(test_utils.TestCase): def setUp(self): - self.loop = test_utils.TestLoop() - events.set_event_loop(None) - - def tearDown(self): - self.loop.close() - gc.collect() + self.loop = self.new_test_loop() def test_task_class(self): - @tasks.coroutine + @asyncio.coroutine def notmuch(): return 'ok' - t = tasks.Task(notmuch(), loop=self.loop) + t = asyncio.Task(notmuch(), loop=self.loop) self.loop.run_until_complete(t) self.assertTrue(t.done()) self.assertEqual(t.result(), 'ok') self.assertIs(t._loop, self.loop) - loop = events.new_event_loop() - t = tasks.Task(notmuch(), loop=loop) + loop = asyncio.new_event_loop() + self.set_event_loop(loop) + t = asyncio.Task(notmuch(), loop=loop) self.assertIs(t._loop, loop) + loop.run_until_complete(t) loop.close() - def test_async_coroutine(self): - @tasks.coroutine + def test_ensure_future_coroutine(self): + @asyncio.coroutine def notmuch(): return 'ok' - t = tasks.async(notmuch(), loop=self.loop) + t = asyncio.ensure_future(notmuch(), loop=self.loop) self.loop.run_until_complete(t) self.assertTrue(t.done()) self.assertEqual(t.result(), 'ok') self.assertIs(t._loop, self.loop) - loop = events.new_event_loop() - t = tasks.async(notmuch(), loop=loop) + loop = asyncio.new_event_loop() + self.set_event_loop(loop) + t = asyncio.ensure_future(notmuch(), loop=loop) self.assertIs(t._loop, loop) + loop.run_until_complete(t) loop.close() - def test_async_future(self): - f_orig = futures.Future(loop=self.loop) + def test_ensure_future_future(self): + f_orig = asyncio.Future(loop=self.loop) f_orig.set_result('ko') - f = tasks.async(f_orig) + f = asyncio.ensure_future(f_orig) self.loop.run_until_complete(f) self.assertTrue(f.done()) self.assertEqual(f.result(), 'ko') self.assertIs(f, f_orig) - loop = events.new_event_loop() + loop = asyncio.new_event_loop() + self.set_event_loop(loop) with self.assertRaises(ValueError): - f = tasks.async(f_orig, loop=loop) + f = asyncio.ensure_future(f_orig, loop=loop) loop.close() - f = tasks.async(f_orig, loop=self.loop) + f = asyncio.ensure_future(f_orig, loop=self.loop) self.assertIs(f, f_orig) - def test_async_task(self): - @tasks.coroutine + def test_ensure_future_task(self): + @asyncio.coroutine def notmuch(): return 'ok' - t_orig = tasks.Task(notmuch(), loop=self.loop) - t = tasks.async(t_orig) + t_orig = asyncio.Task(notmuch(), loop=self.loop) + t = asyncio.ensure_future(t_orig) self.loop.run_until_complete(t) self.assertTrue(t.done()) self.assertEqual(t.result(), 'ok') self.assertIs(t, t_orig) - loop = events.new_event_loop() + loop = asyncio.new_event_loop() + self.set_event_loop(loop) with self.assertRaises(ValueError): - t = tasks.async(t_orig, loop=loop) + t = asyncio.ensure_future(t_orig, loop=loop) loop.close() - t = tasks.async(t_orig, loop=self.loop) + t = asyncio.ensure_future(t_orig, loop=self.loop) self.assertIs(t, t_orig) - def test_async_neither(self): + @unittest.skipUnless(PY35, 'need python 3.5 or later') + def test_ensure_future_awaitable(self): + class Aw: + def __init__(self, coro): + self.coro = coro + def __await__(self): + return (yield from self.coro) + + @asyncio.coroutine + def coro(): + return 'ok' + + loop = asyncio.new_event_loop() + self.set_event_loop(loop) + fut = asyncio.ensure_future(Aw(coro()), loop=loop) + loop.run_until_complete(fut) + assert fut.result() == 'ok' + + def test_ensure_future_neither(self): with self.assertRaises(TypeError): - tasks.async('ok') + asyncio.ensure_future('ok') + + def test_async_warning(self): + f = asyncio.Future(loop=self.loop) + with self.assertWarnsRegex(DeprecationWarning, + 'function is deprecated, use ensure_'): + self.assertIs(f, asyncio.async(f)) + + def test_get_stack(self): + T = None + + @asyncio.coroutine + def foo(): + yield from bar() + + @asyncio.coroutine + def bar(): + # test get_stack() + f = T.get_stack(limit=1) + try: + self.assertEqual(f[0].f_code.co_name, 'foo') + finally: + f = None + + # test print_stack() + file = io.StringIO() + T.print_stack(limit=1, file=file) + file.seek(0) + tb = file.read() + self.assertRegex(tb, r'foo\(\) running') + + @asyncio.coroutine + def runner(): + nonlocal T + T = asyncio.ensure_future(foo(), loop=self.loop) + yield from T + + self.loop.run_until_complete(runner()) def test_task_repr(self): - @tasks.coroutine + self.loop.set_debug(False) + + @asyncio.coroutine def notmuch(): yield from [] return 'abc' - t = tasks.Task(notmuch(), loop=self.loop) + # test coroutine function + self.assertEqual(notmuch.__name__, 'notmuch') + if PY35: + self.assertEqual(notmuch.__qualname__, + 'TaskTests.test_task_repr..notmuch') + self.assertEqual(notmuch.__module__, __name__) + + filename, lineno = test_utils.get_function_source(notmuch) + src = "%s:%s" % (filename, lineno) + + # test coroutine object + gen = notmuch() + if coroutines._DEBUG or PY35: + coro_qualname = 'TaskTests.test_task_repr..notmuch' + else: + coro_qualname = 'notmuch' + self.assertEqual(gen.__name__, 'notmuch') + if PY35: + self.assertEqual(gen.__qualname__, + coro_qualname) + + # test pending Task + t = asyncio.Task(gen, loop=self.loop) t.add_done_callback(Dummy()) - self.assertEqual(repr(t), 'Task()') + + coro = format_coroutine(coro_qualname, 'running', src, + t._source_traceback, generator=True) + self.assertEqual(repr(t), + '()]>' % coro) + + # test cancelling Task t.cancel() # Does not take immediate effect! - self.assertEqual(repr(t), 'Task()') - self.assertRaises(futures.CancelledError, + self.assertEqual(repr(t), + '()]>' % coro) + + # test cancelled Task + self.assertRaises(asyncio.CancelledError, self.loop.run_until_complete, t) - self.assertEqual(repr(t), 'Task()') - t = tasks.Task(notmuch(), loop=self.loop) + coro = format_coroutine(coro_qualname, 'done', src, + t._source_traceback) + self.assertEqual(repr(t), + '' % coro) + + # test finished Task + t = asyncio.Task(notmuch(), loop=self.loop) self.loop.run_until_complete(t) - self.assertEqual(repr(t), "Task()") + coro = format_coroutine(coro_qualname, 'done', src, + t._source_traceback) + self.assertEqual(repr(t), + "" % coro) - def test_task_repr_custom(self): - @tasks.coroutine - def coro(): - pass + def test_task_repr_coro_decorator(self): + self.loop.set_debug(False) - class T(futures.Future): - def __repr__(self): - return 'T[]' + @asyncio.coroutine + def notmuch(): + # notmuch() function doesn't use yield from: it will be wrapped by + # @coroutine decorator + return 123 + + # test coroutine function + self.assertEqual(notmuch.__name__, 'notmuch') + if PY35: + self.assertEqual(notmuch.__qualname__, + 'TaskTests.test_task_repr_coro_decorator' + '..notmuch') + self.assertEqual(notmuch.__module__, __name__) + + # test coroutine object + gen = notmuch() + if coroutines._DEBUG or PY35: + # On Python >= 3.5, generators now inherit the name of the + # function, as expected, and have a qualified name (__qualname__ + # attribute). + coro_name = 'notmuch' + coro_qualname = ('TaskTests.test_task_repr_coro_decorator' + '..notmuch') + else: + # On Python < 3.5, generators inherit the name of the code, not of + # the function. See: http://bugs.python.org/issue21205 + coro_name = coro_qualname = 'coro' + self.assertEqual(gen.__name__, coro_name) + if PY35: + self.assertEqual(gen.__qualname__, coro_qualname) + + # test repr(CoroWrapper) + if coroutines._DEBUG: + # format the coroutine object + if coroutines._DEBUG: + filename, lineno = test_utils.get_function_source(notmuch) + frame = gen._source_traceback[-1] + coro = ('%s() running, defined at %s:%s, created at %s:%s' + % (coro_qualname, filename, lineno, + frame[0], frame[1])) + else: + code = gen.gi_code + coro = ('%s() running at %s:%s' + % (coro_qualname, code.co_filename, + code.co_firstlineno)) - class MyTask(tasks.Task, T): - def __repr__(self): - return super().__repr__() + self.assertEqual(repr(gen), '' % coro) - gen = coro() - t = MyTask(gen, loop=self.loop) - self.assertEqual(repr(t), 'T[]()') - gen.close() + # test pending Task + t = asyncio.Task(gen, loop=self.loop) + t.add_done_callback(Dummy()) + + # format the coroutine object + if coroutines._DEBUG: + src = '%s:%s' % test_utils.get_function_source(notmuch) + else: + code = gen.gi_code + src = '%s:%s' % (code.co_filename, code.co_firstlineno) + coro = format_coroutine(coro_qualname, 'running', src, + t._source_traceback, + generator=not coroutines._DEBUG) + self.assertEqual(repr(t), + '()]>' % coro) + self.loop.run_until_complete(t) + + def test_task_repr_wait_for(self): + self.loop.set_debug(False) + + @asyncio.coroutine + def wait_for(fut): + return (yield from fut) + + fut = asyncio.Future(loop=self.loop) + task = asyncio.Task(wait_for(fut), loop=self.loop) + test_utils.run_briefly(self.loop) + self.assertRegex(repr(task), + '' % re.escape(repr(fut))) + + fut.set_result(None) + self.loop.run_until_complete(task) + + def test_task_repr_partial_corowrapper(self): + # Issue #222: repr(CoroWrapper) must not fail in debug mode if the + # coroutine is a partial function + with set_coroutine_debug(True): + self.loop.set_debug(True) + + @asyncio.coroutine + def func(x, y): + yield from asyncio.sleep(0) + + partial_func = asyncio.coroutine(functools.partial(func, 1)) + task = self.loop.create_task(partial_func(2)) + + # make warnings quiet + task._log_destroy_pending = False + self.addCleanup(task._coro.close) + + coro_repr = repr(task._coro) + expected = ('.func(1)() running, ') + self.assertTrue(coro_repr.startswith(expected), + coro_repr) def test_task_basics(self): - @tasks.coroutine + @asyncio.coroutine def outer(): a = yield from inner1() b = yield from inner2() return a+b - @tasks.coroutine + @asyncio.coroutine def inner1(): return 42 - @tasks.coroutine + @asyncio.coroutine def inner2(): return 1000 @@ -166,69 +403,68 @@ def gen(): self.assertAlmostEqual(10.0, when) yield 0 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - @tasks.coroutine + @asyncio.coroutine def task(): - yield from tasks.sleep(10.0, loop=loop) + yield from asyncio.sleep(10.0, loop=loop) return 12 - t = tasks.Task(task(), loop=loop) + t = asyncio.Task(task(), loop=loop) loop.call_soon(t.cancel) - with self.assertRaises(futures.CancelledError): + with self.assertRaises(asyncio.CancelledError): loop.run_until_complete(t) self.assertTrue(t.done()) self.assertTrue(t.cancelled()) self.assertFalse(t.cancel()) def test_cancel_yield(self): - @tasks.coroutine + @asyncio.coroutine def task(): yield yield return 12 - t = tasks.Task(task(), loop=self.loop) + t = asyncio.Task(task(), loop=self.loop) test_utils.run_briefly(self.loop) # start coro t.cancel() self.assertRaises( - futures.CancelledError, self.loop.run_until_complete, t) + asyncio.CancelledError, self.loop.run_until_complete, t) self.assertTrue(t.done()) self.assertTrue(t.cancelled()) self.assertFalse(t.cancel()) def test_cancel_inner_future(self): - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def task(): yield from f return 12 - t = tasks.Task(task(), loop=self.loop) + t = asyncio.Task(task(), loop=self.loop) test_utils.run_briefly(self.loop) # start task f.cancel() - with self.assertRaises(futures.CancelledError): + with self.assertRaises(asyncio.CancelledError): self.loop.run_until_complete(t) self.assertTrue(f.cancelled()) self.assertTrue(t.cancelled()) def test_cancel_both_task_and_inner_future(self): - f = futures.Future(loop=self.loop) + f = asyncio.Future(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def task(): yield from f return 12 - t = tasks.Task(task(), loop=self.loop) + t = asyncio.Task(task(), loop=self.loop) test_utils.run_briefly(self.loop) f.cancel() t.cancel() - with self.assertRaises(futures.CancelledError): + with self.assertRaises(asyncio.CancelledError): self.loop.run_until_complete(t) self.assertTrue(t.done()) @@ -236,18 +472,18 @@ def task(): self.assertTrue(t.cancelled()) def test_cancel_task_catching(self): - fut1 = futures.Future(loop=self.loop) - fut2 = futures.Future(loop=self.loop) + fut1 = asyncio.Future(loop=self.loop) + fut2 = asyncio.Future(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def task(): yield from fut1 try: yield from fut2 - except futures.CancelledError: + except asyncio.CancelledError: return 42 - t = tasks.Task(task(), loop=self.loop) + t = asyncio.Task(task(), loop=self.loop) test_utils.run_briefly(self.loop) self.assertIs(t._fut_waiter, fut1) # White-box test. fut1.set_result(None) @@ -260,21 +496,21 @@ def task(): self.assertFalse(t.cancelled()) def test_cancel_task_ignoring(self): - fut1 = futures.Future(loop=self.loop) - fut2 = futures.Future(loop=self.loop) - fut3 = futures.Future(loop=self.loop) + fut1 = asyncio.Future(loop=self.loop) + fut2 = asyncio.Future(loop=self.loop) + fut3 = asyncio.Future(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def task(): yield from fut1 try: yield from fut2 - except futures.CancelledError: + except asyncio.CancelledError: pass res = yield from fut3 return res - t = tasks.Task(task(), loop=self.loop) + t = asyncio.Task(task(), loop=self.loop) test_utils.run_briefly(self.loop) self.assertIs(t._fut_waiter, fut1) # White-box test. fut1.set_result(None) @@ -291,20 +527,20 @@ def task(): self.assertFalse(t.cancelled()) def test_cancel_current_task(self): - loop = events.new_event_loop() - self.addCleanup(loop.close) + loop = asyncio.new_event_loop() + self.set_event_loop(loop) - @tasks.coroutine + @asyncio.coroutine def task(): t.cancel() self.assertTrue(t._must_cancel) # White-box test. # The sleep should be cancelled immediately. - yield from tasks.sleep(100, loop=loop) + yield from asyncio.sleep(100, loop=loop) return 12 - t = tasks.Task(task(), loop=loop) + t = asyncio.Task(task(), loop=loop) self.assertRaises( - futures.CancelledError, loop.run_until_complete, t) + asyncio.CancelledError, loop.run_until_complete, t) self.assertTrue(t.done()) self.assertFalse(t._must_cancel) # White-box test. self.assertFalse(t.cancel()) @@ -320,25 +556,26 @@ def gen(): self.assertAlmostEqual(0.3, when) yield 0.1 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) x = 0 waiters = [] - @tasks.coroutine + @asyncio.coroutine def task(): nonlocal x while x < 10: - waiters.append(tasks.sleep(0.1, loop=loop)) + waiters.append(asyncio.sleep(0.1, loop=loop)) yield from waiters[-1] x += 1 if x == 2: loop.stop() - t = tasks.Task(task(), loop=loop) - self.assertRaises( - RuntimeError, loop.run_until_complete, t) + t = asyncio.Task(task(), loop=loop) + with self.assertRaises(RuntimeError) as cm: + loop.run_until_complete(t) + self.assertEqual(str(cm.exception), + 'Event loop stopped before Future completed.') self.assertFalse(t.done()) self.assertEqual(x, 2) self.assertAlmostEqual(0.3, loop.time()) @@ -346,6 +583,8 @@ def task(): # close generators for w in waiters: w.close() + t.cancel() + self.assertRaises(asyncio.CancelledError, loop.run_until_complete, t) def test_wait_for(self): @@ -355,30 +594,42 @@ def gen(): when = yield 0 self.assertAlmostEqual(0.1, when) when = yield 0.1 - self.assertAlmostEqual(0.4, when) - yield 0.1 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - @tasks.coroutine + foo_running = None + + @asyncio.coroutine def foo(): - yield from tasks.sleep(0.2, loop=loop) + nonlocal foo_running + foo_running = True + try: + yield from asyncio.sleep(0.2, loop=loop) + finally: + foo_running = False return 'done' - fut = tasks.Task(foo(), loop=loop) + fut = asyncio.Task(foo(), loop=loop) - with self.assertRaises(futures.TimeoutError): - loop.run_until_complete(tasks.wait_for(fut, 0.1, loop=loop)) - - self.assertFalse(fut.done()) + with self.assertRaises(asyncio.TimeoutError): + loop.run_until_complete(asyncio.wait_for(fut, 0.1, loop=loop)) + self.assertTrue(fut.done()) + # it should have been cancelled due to the timeout + self.assertTrue(fut.cancelled()) self.assertAlmostEqual(0.1, loop.time()) + self.assertEqual(foo_running, False) - # wait for result - res = loop.run_until_complete( - tasks.wait_for(fut, 0.3, loop=loop)) + def test_wait_for_blocking(self): + loop = self.new_test_loop() + + @asyncio.coroutine + def coro(): + return 'done' + + res = loop.run_until_complete(asyncio.wait_for(coro(), + timeout=None, + loop=loop)) self.assertEqual(res, 'done') - self.assertAlmostEqual(0.2, loop.time()) def test_wait_for_with_global_loop(self): @@ -389,28 +640,39 @@ def gen(): self.assertAlmostEqual(0.01, when) yield 0.01 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - @tasks.coroutine + @asyncio.coroutine def foo(): - yield from tasks.sleep(0.2, loop=loop) + yield from asyncio.sleep(0.2, loop=loop) return 'done' - events.set_event_loop(loop) + asyncio.set_event_loop(loop) try: - fut = tasks.Task(foo(), loop=loop) - with self.assertRaises(futures.TimeoutError): - loop.run_until_complete(tasks.wait_for(fut, 0.01)) + fut = asyncio.Task(foo(), loop=loop) + with self.assertRaises(asyncio.TimeoutError): + loop.run_until_complete(asyncio.wait_for(fut, 0.01)) finally: - events.set_event_loop(None) + asyncio.set_event_loop(None) self.assertAlmostEqual(0.01, loop.time()) - self.assertFalse(fut.done()) + self.assertTrue(fut.done()) + self.assertTrue(fut.cancelled()) - # move forward to close generator - loop.advance_time(10) - loop.run_until_complete(fut) + def test_wait_for_race_condition(self): + + def gen(): + yield 0.1 + yield 0.1 + yield 0.1 + + loop = self.new_test_loop(gen) + + fut = asyncio.Future(loop=loop) + task = asyncio.wait_for(fut, timeout=0.2, loop=loop) + loop.call_later(0.1, fut.set_result, "ok") + res = loop.run_until_complete(task) + self.assertEqual(res, "ok") def test_wait(self): @@ -421,25 +683,24 @@ def gen(): self.assertAlmostEqual(0.15, when) yield 0.15 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - a = tasks.Task(tasks.sleep(0.1, loop=loop), loop=loop) - b = tasks.Task(tasks.sleep(0.15, loop=loop), loop=loop) + a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop) + b = asyncio.Task(asyncio.sleep(0.15, loop=loop), loop=loop) - @tasks.coroutine + @asyncio.coroutine def foo(): - done, pending = yield from tasks.wait([b, a], loop=loop) + done, pending = yield from asyncio.wait([b, a], loop=loop) self.assertEqual(done, set([a, b])) self.assertEqual(pending, set()) return 42 - res = loop.run_until_complete(tasks.Task(foo(), loop=loop)) + res = loop.run_until_complete(asyncio.Task(foo(), loop=loop)) self.assertEqual(res, 42) self.assertAlmostEqual(0.15, loop.time()) # Doing it again should take no time and exercise a different path. - res = loop.run_until_complete(tasks.Task(foo(), loop=loop)) + res = loop.run_until_complete(asyncio.Task(foo(), loop=loop)) self.assertAlmostEqual(0.15, loop.time()) self.assertEqual(res, 42) @@ -452,37 +713,51 @@ def gen(): self.assertAlmostEqual(0.015, when) yield 0.015 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - a = tasks.Task(tasks.sleep(0.01, loop=loop), loop=loop) - b = tasks.Task(tasks.sleep(0.015, loop=loop), loop=loop) + a = asyncio.Task(asyncio.sleep(0.01, loop=loop), loop=loop) + b = asyncio.Task(asyncio.sleep(0.015, loop=loop), loop=loop) - @tasks.coroutine + @asyncio.coroutine def foo(): - done, pending = yield from tasks.wait([b, a]) + done, pending = yield from asyncio.wait([b, a]) self.assertEqual(done, set([a, b])) self.assertEqual(pending, set()) return 42 - events.set_event_loop(loop) - try: - res = loop.run_until_complete( - tasks.Task(foo(), loop=loop)) - finally: - events.set_event_loop(None) + asyncio.set_event_loop(loop) + res = loop.run_until_complete( + asyncio.Task(foo(), loop=loop)) self.assertEqual(res, 42) + def test_wait_duplicate_coroutines(self): + @asyncio.coroutine + def coro(s): + return s + c = coro('test') + + task = asyncio.Task( + asyncio.wait([c, c, coro('spam')], loop=self.loop), + loop=self.loop) + + done, pending = self.loop.run_until_complete(task) + + self.assertFalse(pending) + self.assertEqual(set(f.result() for f in done), {'test', 'spam'}) + def test_wait_errors(self): self.assertRaises( ValueError, self.loop.run_until_complete, - tasks.wait(set(), loop=self.loop)) + asyncio.wait(set(), loop=self.loop)) - self.assertRaises( - ValueError, self.loop.run_until_complete, - tasks.wait([tasks.sleep(10.0, loop=self.loop)], - return_when=-1, loop=self.loop)) + # -1 is an invalid return_when value + sleep_coro = asyncio.sleep(10.0, loop=self.loop) + wait_coro = asyncio.wait([sleep_coro], return_when=-1, loop=self.loop) + self.assertRaises(ValueError, + self.loop.run_until_complete, wait_coro) + + sleep_coro.close() def test_wait_first_completed(self): @@ -493,14 +768,13 @@ def gen(): self.assertAlmostEqual(0.1, when) yield 0.1 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - a = tasks.Task(tasks.sleep(10.0, loop=loop), loop=loop) - b = tasks.Task(tasks.sleep(0.1, loop=loop), loop=loop) - task = tasks.Task( - tasks.wait([b, a], return_when=tasks.FIRST_COMPLETED, - loop=loop), + a = asyncio.Task(asyncio.sleep(10.0, loop=loop), loop=loop) + b = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop) + task = asyncio.Task( + asyncio.wait([b, a], return_when=asyncio.FIRST_COMPLETED, + loop=loop), loop=loop) done, pending = loop.run_until_complete(task) @@ -513,26 +787,26 @@ def gen(): # move forward to close generator loop.advance_time(10) - loop.run_until_complete(tasks.wait([a, b], loop=loop)) + loop.run_until_complete(asyncio.wait([a, b], loop=loop)) def test_wait_really_done(self): # there is possibility that some tasks in the pending list # became done but their callbacks haven't all been called yet - @tasks.coroutine + @asyncio.coroutine def coro1(): yield - @tasks.coroutine + @asyncio.coroutine def coro2(): yield yield - a = tasks.Task(coro1(), loop=self.loop) - b = tasks.Task(coro2(), loop=self.loop) - task = tasks.Task( - tasks.wait([b, a], return_when=tasks.FIRST_COMPLETED, - loop=self.loop), + a = asyncio.Task(coro1(), loop=self.loop) + b = asyncio.Task(coro2(), loop=self.loop) + task = asyncio.Task( + asyncio.wait([b, a], return_when=asyncio.FIRST_COMPLETED, + loop=self.loop), loop=self.loop) done, pending = self.loop.run_until_complete(task) @@ -549,20 +823,19 @@ def gen(): self.assertAlmostEqual(10.0, when) yield 0 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) # first_exception, task already has exception - a = tasks.Task(tasks.sleep(10.0, loop=loop), loop=loop) + a = asyncio.Task(asyncio.sleep(10.0, loop=loop), loop=loop) - @tasks.coroutine + @asyncio.coroutine def exc(): raise ZeroDivisionError('err') - b = tasks.Task(exc(), loop=loop) - task = tasks.Task( - tasks.wait([b, a], return_when=tasks.FIRST_EXCEPTION, - loop=loop), + b = asyncio.Task(exc(), loop=loop) + task = asyncio.Task( + asyncio.wait([b, a], return_when=asyncio.FIRST_EXCEPTION, + loop=loop), loop=loop) done, pending = loop.run_until_complete(task) @@ -572,7 +845,7 @@ def exc(): # move forward to close generator loop.advance_time(10) - loop.run_until_complete(tasks.wait([a, b], loop=loop)) + loop.run_until_complete(asyncio.wait([a, b], loop=loop)) def test_wait_first_exception_in_wait(self): @@ -583,20 +856,19 @@ def gen(): self.assertAlmostEqual(0.01, when) yield 0.01 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) # first_exception, exception during waiting - a = tasks.Task(tasks.sleep(10.0, loop=loop), loop=loop) + a = asyncio.Task(asyncio.sleep(10.0, loop=loop), loop=loop) - @tasks.coroutine + @asyncio.coroutine def exc(): - yield from tasks.sleep(0.01, loop=loop) + yield from asyncio.sleep(0.01, loop=loop) raise ZeroDivisionError('err') - b = tasks.Task(exc(), loop=loop) - task = tasks.wait([b, a], return_when=tasks.FIRST_EXCEPTION, - loop=loop) + b = asyncio.Task(exc(), loop=loop) + task = asyncio.wait([b, a], return_when=asyncio.FIRST_EXCEPTION, + loop=loop) done, pending = loop.run_until_complete(task) self.assertEqual({b}, done) @@ -605,7 +877,7 @@ def exc(): # move forward to close generator loop.advance_time(10) - loop.run_until_complete(tasks.wait([a, b], loop=loop)) + loop.run_until_complete(asyncio.wait([a, b], loop=loop)) def test_wait_with_exception(self): @@ -616,30 +888,29 @@ def gen(): self.assertAlmostEqual(0.15, when) yield 0.15 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - a = tasks.Task(tasks.sleep(0.1, loop=loop), loop=loop) + a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop) - @tasks.coroutine + @asyncio.coroutine def sleeper(): - yield from tasks.sleep(0.15, loop=loop) + yield from asyncio.sleep(0.15, loop=loop) raise ZeroDivisionError('really') - b = tasks.Task(sleeper(), loop=loop) + b = asyncio.Task(sleeper(), loop=loop) - @tasks.coroutine + @asyncio.coroutine def foo(): - done, pending = yield from tasks.wait([b, a], loop=loop) + done, pending = yield from asyncio.wait([b, a], loop=loop) self.assertEqual(len(done), 2) self.assertEqual(pending, set()) errors = set(f for f in done if f.exception() is not None) self.assertEqual(len(errors), 1) - loop.run_until_complete(tasks.Task(foo(), loop=loop)) + loop.run_until_complete(asyncio.Task(foo(), loop=loop)) self.assertAlmostEqual(0.15, loop.time()) - loop.run_until_complete(tasks.Task(foo(), loop=loop)) + loop.run_until_complete(asyncio.Task(foo(), loop=loop)) self.assertAlmostEqual(0.15, loop.time()) def test_wait_with_timeout(self): @@ -653,25 +924,24 @@ def gen(): self.assertAlmostEqual(0.11, when) yield 0.11 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - a = tasks.Task(tasks.sleep(0.1, loop=loop), loop=loop) - b = tasks.Task(tasks.sleep(0.15, loop=loop), loop=loop) + a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop) + b = asyncio.Task(asyncio.sleep(0.15, loop=loop), loop=loop) - @tasks.coroutine + @asyncio.coroutine def foo(): - done, pending = yield from tasks.wait([b, a], timeout=0.11, - loop=loop) + done, pending = yield from asyncio.wait([b, a], timeout=0.11, + loop=loop) self.assertEqual(done, set([a])) self.assertEqual(pending, set([b])) - loop.run_until_complete(tasks.Task(foo(), loop=loop)) + loop.run_until_complete(asyncio.Task(foo(), loop=loop)) self.assertAlmostEqual(0.11, loop.time()) # move forward to close generator loop.advance_time(10) - loop.run_until_complete(tasks.wait([a, b], loop=loop)) + loop.run_until_complete(asyncio.wait([a, b], loop=loop)) def test_wait_concurrent_complete(self): @@ -684,14 +954,13 @@ def gen(): self.assertAlmostEqual(0.1, when) yield 0.1 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - a = tasks.Task(tasks.sleep(0.1, loop=loop), loop=loop) - b = tasks.Task(tasks.sleep(0.15, loop=loop), loop=loop) + a = asyncio.Task(asyncio.sleep(0.1, loop=loop), loop=loop) + b = asyncio.Task(asyncio.sleep(0.15, loop=loop), loop=loop) done, pending = loop.run_until_complete( - tasks.wait([b, a], timeout=0.1, loop=loop)) + asyncio.wait([b, a], timeout=0.1, loop=loop)) self.assertEqual(done, set([a])) self.assertEqual(pending, set([b])) @@ -699,7 +968,7 @@ def gen(): # move forward to close generator loop.advance_time(10) - loop.run_until_complete(tasks.wait([a, b], loop=loop)) + loop.run_until_complete(asyncio.wait([a, b], loop=loop)) def test_as_completed(self): @@ -709,15 +978,16 @@ def gen(): yield 0.01 yield 0 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) + # disable "slow callback" warning + loop.slow_callback_duration = 1.0 completed = set() time_shifted = False - @tasks.coroutine + @asyncio.coroutine def sleeper(dt, x): nonlocal time_shifted - yield from tasks.sleep(dt, loop=loop) + yield from asyncio.sleep(dt, loop=loop) completed.add(x) if not time_shifted and 'a' in completed and 'b' in completed: time_shifted = True @@ -728,63 +998,78 @@ def sleeper(dt, x): b = sleeper(0.01, 'b') c = sleeper(0.15, 'c') - @tasks.coroutine + @asyncio.coroutine def foo(): values = [] - for f in tasks.as_completed([b, c, a], loop=loop): + for f in asyncio.as_completed([b, c, a], loop=loop): values.append((yield from f)) return values - res = loop.run_until_complete(tasks.Task(foo(), loop=loop)) + res = loop.run_until_complete(asyncio.Task(foo(), loop=loop)) self.assertAlmostEqual(0.15, loop.time()) self.assertTrue('a' in res[:2]) self.assertTrue('b' in res[:2]) self.assertEqual(res[2], 'c') # Doing it again should take no time and exercise a different path. - res = loop.run_until_complete(tasks.Task(foo(), loop=loop)) + res = loop.run_until_complete(asyncio.Task(foo(), loop=loop)) self.assertAlmostEqual(0.15, loop.time()) def test_as_completed_with_timeout(self): def gen(): - when = yield - self.assertAlmostEqual(0.12, when) - when = yield 0 - self.assertAlmostEqual(0.1, when) - when = yield 0 - self.assertAlmostEqual(0.15, when) - when = yield 0.1 - self.assertAlmostEqual(0.12, when) - yield 0.02 + yield + yield 0 + yield 0 + yield 0.1 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - a = tasks.sleep(0.1, 'a', loop=loop) - b = tasks.sleep(0.15, 'b', loop=loop) + a = asyncio.sleep(0.1, 'a', loop=loop) + b = asyncio.sleep(0.15, 'b', loop=loop) - @tasks.coroutine + @asyncio.coroutine def foo(): values = [] - for f in tasks.as_completed([a, b], timeout=0.12, loop=loop): + for f in asyncio.as_completed([a, b], timeout=0.12, loop=loop): + if values: + loop.advance_time(0.02) try: v = yield from f values.append((1, v)) - except futures.TimeoutError as exc: + except asyncio.TimeoutError as exc: values.append((2, exc)) return values - res = loop.run_until_complete(tasks.Task(foo(), loop=loop)) + res = loop.run_until_complete(asyncio.Task(foo(), loop=loop)) self.assertEqual(len(res), 2, res) self.assertEqual(res[0], (1, 'a')) self.assertEqual(res[1][0], 2) - self.assertIsInstance(res[1][1], futures.TimeoutError) + self.assertIsInstance(res[1][1], asyncio.TimeoutError) self.assertAlmostEqual(0.12, loop.time()) # move forward to close generator loop.advance_time(10) - loop.run_until_complete(tasks.wait([a, b], loop=loop)) + loop.run_until_complete(asyncio.wait([a, b], loop=loop)) + + def test_as_completed_with_unused_timeout(self): + + def gen(): + yield + yield 0 + yield 0.01 + + loop = self.new_test_loop(gen) + + a = asyncio.sleep(0.01, 'a', loop=loop) + + @asyncio.coroutine + def foo(): + for f in asyncio.as_completed([a], timeout=1, loop=loop): + v = yield from f + self.assertEqual(v, 'a') + + loop.run_until_complete(asyncio.Task(foo(), loop=loop)) def test_as_completed_reverse_wait(self): @@ -793,13 +1078,12 @@ def gen(): yield 0.05 yield 0 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - a = tasks.sleep(0.05, 'a', loop=loop) - b = tasks.sleep(0.10, 'b', loop=loop) + a = asyncio.sleep(0.05, 'a', loop=loop) + b = asyncio.sleep(0.10, 'b', loop=loop) fs = {a, b} - futs = list(tasks.as_completed(fs, loop=loop)) + futs = list(asyncio.as_completed(fs, loop=loop)) self.assertEqual(len(futs), 2) x = loop.run_until_complete(futs[1]) @@ -819,18 +1103,38 @@ def gen(): self.assertAlmostEqual(0.05, when) yield 0.05 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - a = tasks.sleep(0.05, 'a', loop=loop) - b = tasks.sleep(0.05, 'b', loop=loop) + a = asyncio.sleep(0.05, 'a', loop=loop) + b = asyncio.sleep(0.05, 'b', loop=loop) fs = {a, b} - futs = list(tasks.as_completed(fs, loop=loop)) + futs = list(asyncio.as_completed(fs, loop=loop)) self.assertEqual(len(futs), 2) - waiter = tasks.wait(futs, loop=loop) + waiter = asyncio.wait(futs, loop=loop) done, pending = loop.run_until_complete(waiter) self.assertEqual(set(f.result() for f in done), {'a', 'b'}) + def test_as_completed_duplicate_coroutines(self): + + @asyncio.coroutine + def coro(s): + return s + + @asyncio.coroutine + def runner(): + result = [] + c = coro('ham') + for f in asyncio.as_completed([c, c, coro('spam')], + loop=self.loop): + result.append((yield from f)) + return result + + fut = asyncio.Task(runner(), loop=self.loop) + self.loop.run_until_complete(fut) + result = fut.result() + self.assertEqual(set(result), {'ham', 'spam'}) + self.assertEqual(len(result), 2) + def test_sleep(self): def gen(): @@ -840,16 +1144,15 @@ def gen(): self.assertAlmostEqual(0.1, when) yield 0.05 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - @tasks.coroutine + @asyncio.coroutine def sleeper(dt, arg): - yield from tasks.sleep(dt/2, loop=loop) - res = yield from tasks.sleep(dt/2, arg, loop=loop) + yield from asyncio.sleep(dt/2, loop=loop) + res = yield from asyncio.sleep(dt/2, arg, loop=loop) return res - t = tasks.Task(sleeper(0.1, 'yeah'), loop=loop) + t = asyncio.Task(sleeper(0.1, 'yeah'), loop=loop) loop.run_until_complete(t) self.assertTrue(t.done()) self.assertEqual(t.result(), 'yeah') @@ -862,18 +1165,17 @@ def gen(): self.assertAlmostEqual(10.0, when) yield 0 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - t = tasks.Task(tasks.sleep(10.0, 'yeah', loop=loop), - loop=loop) + t = asyncio.Task(asyncio.sleep(10.0, 'yeah', loop=loop), + loop=loop) handle = None orig_call_later = loop.call_later - def call_later(self, delay, callback, *args): + def call_later(delay, callback, *args): nonlocal handle - handle = orig_call_later(self, delay, callback, *args) + handle = orig_call_later(delay, callback, *args) return handle loop.call_later = call_later @@ -894,24 +1196,19 @@ def gen(): self.assertAlmostEqual(5000, when) yield 0.1 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) - - sleepfut = None + loop = self.new_test_loop(gen) - @tasks.coroutine + @asyncio.coroutine def sleep(dt): - nonlocal sleepfut - sleepfut = tasks.sleep(dt, loop=loop) - yield from sleepfut + yield from asyncio.sleep(dt, loop=loop) - @tasks.coroutine + @asyncio.coroutine def doit(): - sleeper = tasks.Task(sleep(5000), loop=loop) + sleeper = asyncio.Task(sleep(5000), loop=loop) loop.call_later(0.1, sleeper.cancel) try: yield from sleeper - except futures.CancelledError: + except asyncio.CancelledError: return 'cancelled' else: return 'slept in' @@ -921,37 +1218,37 @@ def doit(): self.assertAlmostEqual(0.1, loop.time()) def test_task_cancel_waiter_future(self): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def coro(): yield from fut - task = tasks.Task(coro(), loop=self.loop) + task = asyncio.Task(coro(), loop=self.loop) test_utils.run_briefly(self.loop) self.assertIs(task._fut_waiter, fut) task.cancel() test_utils.run_briefly(self.loop) self.assertRaises( - futures.CancelledError, self.loop.run_until_complete, task) + asyncio.CancelledError, self.loop.run_until_complete, task) self.assertIsNone(task._fut_waiter) self.assertTrue(fut.cancelled()) def test_step_in_completed_task(self): - @tasks.coroutine + @asyncio.coroutine def notmuch(): return 'ko' gen = notmuch() - task = tasks.Task(gen, loop=self.loop) + task = asyncio.Task(gen, loop=self.loop) task.set_result('ok') self.assertRaises(AssertionError, task._step) gen.close() def test_step_result(self): - @tasks.coroutine + @asyncio.coroutine def notmuch(): yield None yield 1 @@ -963,7 +1260,7 @@ def notmuch(): def test_step_result_future(self): # If coroutine returns future, task waits on this future. - class Fut(futures.Future): + class Fut(asyncio.Future): def __init__(self, *args, **kwds): self.cb_added = False super().__init__(*args, **kwds) @@ -975,12 +1272,12 @@ def add_done_callback(self, fn): fut = Fut(loop=self.loop) result = None - @tasks.coroutine + @asyncio.coroutine def wait_for_future(): nonlocal result result = yield from fut - t = tasks.Task(wait_for_future(), loop=self.loop) + t = asyncio.Task(wait_for_future(), loop=self.loop) test_utils.run_briefly(self.loop) self.assertTrue(fut.cb_added) @@ -992,11 +1289,11 @@ def wait_for_future(): self.assertIsNone(t.result()) def test_step_with_baseexception(self): - @tasks.coroutine + @asyncio.coroutine def notmutch(): raise BaseException() - task = tasks.Task(notmutch(), loop=self.loop) + task = asyncio.Task(notmutch(), loop=self.loop) self.assertRaises(BaseException, task._step) self.assertTrue(task.done()) @@ -1009,23 +1306,22 @@ def gen(): self.assertAlmostEqual(10.0, when) yield 0 - loop = test_utils.TestLoop(gen) - self.addCleanup(loop.close) + loop = self.new_test_loop(gen) - @tasks.coroutine + @asyncio.coroutine def sleeper(): - yield from tasks.sleep(10, loop=loop) + yield from asyncio.sleep(10, loop=loop) base_exc = BaseException() - @tasks.coroutine + @asyncio.coroutine def notmutch(): try: yield from sleeper() - except futures.CancelledError: + except asyncio.CancelledError: raise base_exc - task = tasks.Task(notmutch(), loop=loop) + task = asyncio.Task(notmutch(), loop=loop) test_utils.run_briefly(loop) task.cancel() @@ -1041,21 +1337,21 @@ def test_iscoroutinefunction(self): def fn(): pass - self.assertFalse(tasks.iscoroutinefunction(fn)) + self.assertFalse(asyncio.iscoroutinefunction(fn)) def fn1(): yield - self.assertFalse(tasks.iscoroutinefunction(fn1)) + self.assertFalse(asyncio.iscoroutinefunction(fn1)) - @tasks.coroutine + @asyncio.coroutine def fn2(): yield - self.assertTrue(tasks.iscoroutinefunction(fn2)) + self.assertTrue(asyncio.iscoroutinefunction(fn2)) def test_yield_vs_yield_from(self): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def wait_for_future(): yield fut @@ -1066,11 +1362,11 @@ def wait_for_future(): self.assertFalse(fut.done()) def test_yield_vs_yield_from_generator(self): - @tasks.coroutine + @asyncio.coroutine def coro(): yield - @tasks.coroutine + @asyncio.coroutine def wait_for_future(): gen = coro() try: @@ -1084,65 +1380,103 @@ def wait_for_future(): self.loop.run_until_complete, task) def test_coroutine_non_gen_function(self): - @tasks.coroutine + @asyncio.coroutine def func(): return 'test' - self.assertTrue(tasks.iscoroutinefunction(func)) + self.assertTrue(asyncio.iscoroutinefunction(func)) coro = func() - self.assertTrue(tasks.iscoroutine(coro)) + self.assertTrue(asyncio.iscoroutine(coro)) res = self.loop.run_until_complete(coro) self.assertEqual(res, 'test') def test_coroutine_non_gen_function_return_future(self): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def func(): return fut - @tasks.coroutine + @asyncio.coroutine def coro(): fut.set_result('test') - t1 = tasks.Task(func(), loop=self.loop) - t2 = tasks.Task(coro(), loop=self.loop) + t1 = asyncio.Task(func(), loop=self.loop) + t2 = asyncio.Task(coro(), loop=self.loop) res = self.loop.run_until_complete(t1) self.assertEqual(res, 'test') self.assertIsNone(t2.result()) + def test_current_task(self): + self.assertIsNone(asyncio.Task.current_task(loop=self.loop)) + + @asyncio.coroutine + def coro(loop): + self.assertTrue(asyncio.Task.current_task(loop=loop) is task) + + task = asyncio.Task(coro(self.loop), loop=self.loop) + self.loop.run_until_complete(task) + self.assertIsNone(asyncio.Task.current_task(loop=self.loop)) + + def test_current_task_with_interleaving_tasks(self): + self.assertIsNone(asyncio.Task.current_task(loop=self.loop)) + + fut1 = asyncio.Future(loop=self.loop) + fut2 = asyncio.Future(loop=self.loop) + + @asyncio.coroutine + def coro1(loop): + self.assertTrue(asyncio.Task.current_task(loop=loop) is task1) + yield from fut1 + self.assertTrue(asyncio.Task.current_task(loop=loop) is task1) + fut2.set_result(True) + + @asyncio.coroutine + def coro2(loop): + self.assertTrue(asyncio.Task.current_task(loop=loop) is task2) + fut1.set_result(True) + yield from fut2 + self.assertTrue(asyncio.Task.current_task(loop=loop) is task2) + + task1 = asyncio.Task(coro1(self.loop), loop=self.loop) + task2 = asyncio.Task(coro2(self.loop), loop=self.loop) + + self.loop.run_until_complete(asyncio.wait((task1, task2), + loop=self.loop)) + self.assertIsNone(asyncio.Task.current_task(loop=self.loop)) + # Some thorough tests for cancellation propagation through # coroutines, tasks and wait(). def test_yield_future_passes_cancel(self): # Cancelling outer() cancels inner() cancels waiter. proof = 0 - waiter = futures.Future(loop=self.loop) + waiter = asyncio.Future(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def inner(): nonlocal proof try: yield from waiter - except futures.CancelledError: + except asyncio.CancelledError: proof += 1 raise else: self.fail('got past sleep() in inner()') - @tasks.coroutine + @asyncio.coroutine def outer(): nonlocal proof try: yield from inner() - except futures.CancelledError: + except asyncio.CancelledError: proof += 100 # Expect this path. else: proof += 10 - f = tasks.async(outer(), loop=self.loop) + f = asyncio.ensure_future(outer(), loop=self.loop) test_utils.run_briefly(self.loop) f.cancel() self.loop.run_until_complete(f) @@ -1153,39 +1487,39 @@ def test_yield_wait_does_not_shield_cancel(self): # Cancelling outer() makes wait() return early, leaves inner() # running. proof = 0 - waiter = futures.Future(loop=self.loop) + waiter = asyncio.Future(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def inner(): nonlocal proof yield from waiter proof += 1 - @tasks.coroutine + @asyncio.coroutine def outer(): nonlocal proof - d, p = yield from tasks.wait([inner()], loop=self.loop) + d, p = yield from asyncio.wait([inner()], loop=self.loop) proof += 100 - f = tasks.async(outer(), loop=self.loop) + f = asyncio.ensure_future(outer(), loop=self.loop) test_utils.run_briefly(self.loop) f.cancel() self.assertRaises( - futures.CancelledError, self.loop.run_until_complete, f) + asyncio.CancelledError, self.loop.run_until_complete, f) waiter.set_result(None) test_utils.run_briefly(self.loop) self.assertEqual(proof, 1) def test_shield_result(self): - inner = futures.Future(loop=self.loop) - outer = tasks.shield(inner) + inner = asyncio.Future(loop=self.loop) + outer = asyncio.shield(inner) inner.set_result(42) res = self.loop.run_until_complete(outer) self.assertEqual(res, 42) def test_shield_exception(self): - inner = futures.Future(loop=self.loop) - outer = tasks.shield(inner) + inner = asyncio.Future(loop=self.loop) + outer = asyncio.shield(inner) test_utils.run_briefly(self.loop) exc = RuntimeError('expected') inner.set_exception(exc) @@ -1193,50 +1527,50 @@ def test_shield_exception(self): self.assertIs(outer.exception(), exc) def test_shield_cancel(self): - inner = futures.Future(loop=self.loop) - outer = tasks.shield(inner) + inner = asyncio.Future(loop=self.loop) + outer = asyncio.shield(inner) test_utils.run_briefly(self.loop) inner.cancel() test_utils.run_briefly(self.loop) self.assertTrue(outer.cancelled()) def test_shield_shortcut(self): - fut = futures.Future(loop=self.loop) + fut = asyncio.Future(loop=self.loop) fut.set_result(42) - res = self.loop.run_until_complete(tasks.shield(fut)) + res = self.loop.run_until_complete(asyncio.shield(fut)) self.assertEqual(res, 42) def test_shield_effect(self): # Cancelling outer() does not affect inner(). proof = 0 - waiter = futures.Future(loop=self.loop) + waiter = asyncio.Future(loop=self.loop) - @tasks.coroutine + @asyncio.coroutine def inner(): nonlocal proof yield from waiter proof += 1 - @tasks.coroutine + @asyncio.coroutine def outer(): nonlocal proof - yield from tasks.shield(inner(), loop=self.loop) + yield from asyncio.shield(inner(), loop=self.loop) proof += 100 - f = tasks.async(outer(), loop=self.loop) + f = asyncio.ensure_future(outer(), loop=self.loop) test_utils.run_briefly(self.loop) f.cancel() - with self.assertRaises(futures.CancelledError): + with self.assertRaises(asyncio.CancelledError): self.loop.run_until_complete(f) waiter.set_result(None) test_utils.run_briefly(self.loop) self.assertEqual(proof, 1) def test_shield_gather(self): - child1 = futures.Future(loop=self.loop) - child2 = futures.Future(loop=self.loop) - parent = tasks.gather(child1, child2, loop=self.loop) - outer = tasks.shield(parent, loop=self.loop) + child1 = asyncio.Future(loop=self.loop) + child2 = asyncio.Future(loop=self.loop) + parent = asyncio.gather(child1, child2, loop=self.loop) + outer = asyncio.shield(parent, loop=self.loop) test_utils.run_briefly(self.loop) outer.cancel() test_utils.run_briefly(self.loop) @@ -1247,41 +1581,258 @@ def test_shield_gather(self): self.assertEqual(parent.result(), [1, 2]) def test_gather_shield(self): - child1 = futures.Future(loop=self.loop) - child2 = futures.Future(loop=self.loop) - inner1 = tasks.shield(child1, loop=self.loop) - inner2 = tasks.shield(child2, loop=self.loop) - parent = tasks.gather(inner1, inner2, loop=self.loop) + child1 = asyncio.Future(loop=self.loop) + child2 = asyncio.Future(loop=self.loop) + inner1 = asyncio.shield(child1, loop=self.loop) + inner2 = asyncio.shield(child2, loop=self.loop) + parent = asyncio.gather(inner1, inner2, loop=self.loop) test_utils.run_briefly(self.loop) parent.cancel() # This should cancel inner1 and inner2 but bot child1 and child2. test_utils.run_briefly(self.loop) - self.assertIsInstance(parent.exception(), futures.CancelledError) + self.assertIsInstance(parent.exception(), asyncio.CancelledError) self.assertTrue(inner1.cancelled()) self.assertTrue(inner2.cancelled()) child1.set_result(1) child2.set_result(2) test_utils.run_briefly(self.loop) + def test_as_completed_invalid_args(self): + fut = asyncio.Future(loop=self.loop) + + # as_completed() expects a list of futures, not a future instance + self.assertRaises(TypeError, self.loop.run_until_complete, + asyncio.as_completed(fut, loop=self.loop)) + coro = coroutine_function() + self.assertRaises(TypeError, self.loop.run_until_complete, + asyncio.as_completed(coro, loop=self.loop)) + coro.close() + + def test_wait_invalid_args(self): + fut = asyncio.Future(loop=self.loop) + + # wait() expects a list of futures, not a future instance + self.assertRaises(TypeError, self.loop.run_until_complete, + asyncio.wait(fut, loop=self.loop)) + coro = coroutine_function() + self.assertRaises(TypeError, self.loop.run_until_complete, + asyncio.wait(coro, loop=self.loop)) + coro.close() + + # wait() expects at least a future + self.assertRaises(ValueError, self.loop.run_until_complete, + asyncio.wait([], loop=self.loop)) + + def test_corowrapper_mocks_generator(self): + + def check(): + # A function that asserts various things. + # Called twice, with different debug flag values. + + @asyncio.coroutine + def coro(): + # The actual coroutine. + self.assertTrue(gen.gi_running) + yield from fut + + # A completed Future used to run the coroutine. + fut = asyncio.Future(loop=self.loop) + fut.set_result(None) + + # Call the coroutine. + gen = coro() + + # Check some properties. + self.assertTrue(asyncio.iscoroutine(gen)) + self.assertIsInstance(gen.gi_frame, types.FrameType) + self.assertFalse(gen.gi_running) + self.assertIsInstance(gen.gi_code, types.CodeType) + + # Run it. + self.loop.run_until_complete(gen) + + # The frame should have changed. + self.assertIsNone(gen.gi_frame) + + # Test with debug flag cleared. + with set_coroutine_debug(False): + check() + + # Test with debug flag set. + with set_coroutine_debug(True): + check() + + def test_yield_from_corowrapper(self): + with set_coroutine_debug(True): + @asyncio.coroutine + def t1(): + return (yield from t2()) + + @asyncio.coroutine + def t2(): + f = asyncio.Future(loop=self.loop) + asyncio.Task(t3(f), loop=self.loop) + return (yield from f) + + @asyncio.coroutine + def t3(f): + f.set_result((1, 2, 3)) + + task = asyncio.Task(t1(), loop=self.loop) + val = self.loop.run_until_complete(task) + self.assertEqual(val, (1, 2, 3)) + + def test_yield_from_corowrapper_send(self): + def foo(): + a = yield + return a + + def call(arg): + cw = asyncio.coroutines.CoroWrapper(foo()) + cw.send(None) + try: + cw.send(arg) + except StopIteration as ex: + return ex.args[0] + else: + raise AssertionError('StopIteration was expected') + + self.assertEqual(call((1, 2)), (1, 2)) + self.assertEqual(call('spam'), 'spam') + + def test_corowrapper_weakref(self): + wd = weakref.WeakValueDictionary() + def foo(): yield from [] + cw = asyncio.coroutines.CoroWrapper(foo()) + wd['cw'] = cw # Would fail without __weakref__ slot. + cw.gen = None # Suppress warning from __del__. + + @unittest.skipUnless(PY34, + 'need python 3.4 or later') + def test_log_destroyed_pending_task(self): + @asyncio.coroutine + def kill_me(loop): + future = asyncio.Future(loop=loop) + yield from future + # at this point, the only reference to kill_me() task is + # the Task._wakeup() method in future._callbacks + raise Exception("code never reached") + + mock_handler = mock.Mock() + self.loop.set_debug(True) + self.loop.set_exception_handler(mock_handler) + + # schedule the task + coro = kill_me(self.loop) + task = asyncio.ensure_future(coro, loop=self.loop) + self.assertEqual(asyncio.Task.all_tasks(loop=self.loop), {task}) + + # execute the task so it waits for future + self.loop._run_once() + self.assertEqual(len(self.loop._ready), 0) + + # remove the future used in kill_me(), and references to the task + del coro.gi_frame.f_locals['future'] + coro = None + source_traceback = task._source_traceback + task = None + + # no more reference to kill_me() task: the task is destroyed by the GC + support.gc_collect() + + self.assertEqual(asyncio.Task.all_tasks(loop=self.loop), set()) + + mock_handler.assert_called_with(self.loop, { + 'message': 'Task was destroyed but it is pending!', + 'task': mock.ANY, + 'source_traceback': source_traceback, + }) + mock_handler.reset_mock() + + @mock.patch('asyncio.coroutines.logger') + def test_coroutine_never_yielded(self, m_log): + with set_coroutine_debug(True): + @asyncio.coroutine + def coro_noop(): + pass + + tb_filename = __file__ + tb_lineno = sys._getframe().f_lineno + 2 + # create a coroutine object but don't use it + coro_noop() + support.gc_collect() + + self.assertTrue(m_log.error.called) + message = m_log.error.call_args[0][0] + func_filename, func_lineno = test_utils.get_function_source(coro_noop) + + regex = (r'^ ' + r'was never yielded from\n' + r'Coroutine object created at \(most recent call last\):\n' + r'.*\n' + r' File "%s", line %s, in test_coroutine_never_yielded\n' + r' coro_noop\(\)$' + % (re.escape(coro_noop.__qualname__), + re.escape(func_filename), func_lineno, + re.escape(tb_filename), tb_lineno)) + + self.assertRegex(message, re.compile(regex, re.DOTALL)) + + def test_task_source_traceback(self): + self.loop.set_debug(True) + + task = asyncio.Task(coroutine_function(), loop=self.loop) + lineno = sys._getframe().f_lineno - 1 + self.assertIsInstance(task._source_traceback, list) + self.assertEqual(task._source_traceback[-1][:3], + (__file__, + lineno, + 'test_task_source_traceback')) + self.loop.run_until_complete(task) + + def _test_cancel_wait_for(self, timeout): + loop = asyncio.new_event_loop() + self.addCleanup(loop.close) + + @asyncio.coroutine + def blocking_coroutine(): + fut = asyncio.Future(loop=loop) + # Block: fut result is never set + yield from fut + + task = loop.create_task(blocking_coroutine()) + + wait = loop.create_task(asyncio.wait_for(task, timeout, loop=loop)) + loop.call_soon(wait.cancel) + + self.assertRaises(asyncio.CancelledError, + loop.run_until_complete, wait) + + # Python issue #23219: cancelling the wait must also cancel the task + self.assertTrue(task.cancelled()) + + def test_cancel_blocking_wait_for(self): + self._test_cancel_wait_for(None) + + def test_cancel_wait_for(self): + self._test_cancel_wait_for(60.0) + class GatherTestsBase: def setUp(self): - self.one_loop = test_utils.TestLoop() - self.other_loop = test_utils.TestLoop() - - def tearDown(self): - self.one_loop.close() - self.other_loop.close() + self.one_loop = self.new_test_loop() + self.other_loop = self.new_test_loop() + self.set_event_loop(self.one_loop, cleanup=False) def _run_loop(self, loop): while loop._ready: test_utils.run_briefly(loop) def _check_success(self, **kwargs): - a, b, c = [futures.Future(loop=self.one_loop) for i in range(3)] - fut = tasks.gather(*self.wrap_futures(a, b, c), **kwargs) - cb = Mock() + a, b, c = [asyncio.Future(loop=self.one_loop) for i in range(3)] + fut = asyncio.gather(*self.wrap_futures(a, b, c), **kwargs) + cb = test_utils.MockCallback() fut.add_done_callback(cb) b.set_result(1) a.set_result(2) @@ -1301,9 +1852,9 @@ def test_result_exception_success(self): self._check_success(return_exceptions=True) def test_one_exception(self): - a, b, c, d, e = [futures.Future(loop=self.one_loop) for i in range(5)] - fut = tasks.gather(*self.wrap_futures(a, b, c, d, e)) - cb = Mock() + a, b, c, d, e = [asyncio.Future(loop=self.one_loop) for i in range(5)] + fut = asyncio.gather(*self.wrap_futures(a, b, c, d, e)) + cb = test_utils.MockCallback() fut.add_done_callback(cb) exc = ZeroDivisionError() a.set_result(1) @@ -1316,12 +1867,13 @@ def test_one_exception(self): c.set_result(3) d.cancel() e.set_exception(RuntimeError()) + e.exception() def test_return_exceptions(self): - a, b, c, d = [futures.Future(loop=self.one_loop) for i in range(4)] - fut = tasks.gather(*self.wrap_futures(a, b, c, d), - return_exceptions=True) - cb = Mock() + a, b, c, d = [asyncio.Future(loop=self.one_loop) for i in range(4)] + fut = asyncio.gather(*self.wrap_futures(a, b, c, d), + return_exceptions=True) + cb = test_utils.MockCallback() fut.add_done_callback(cb) exc = ZeroDivisionError() exc2 = RuntimeError() @@ -1336,22 +1888,50 @@ def test_return_exceptions(self): cb.assert_called_once_with(fut) self.assertEqual(fut.result(), [3, 1, exc, exc2]) + def test_env_var_debug(self): + aio_path = os.path.dirname(os.path.dirname(asyncio.__file__)) + + code = '\n'.join(( + 'import asyncio.coroutines', + 'print(asyncio.coroutines._DEBUG)')) -class FutureGatherTests(GatherTestsBase, unittest.TestCase): + # Test with -E to not fail if the unit test was run with + # PYTHONASYNCIODEBUG set to a non-empty string + sts, stdout, stderr = assert_python_ok('-E', '-c', code, + PYTHONPATH=aio_path) + self.assertEqual(stdout.rstrip(), b'False') + + sts, stdout, stderr = assert_python_ok('-c', code, + PYTHONASYNCIODEBUG='', + PYTHONPATH=aio_path) + self.assertEqual(stdout.rstrip(), b'False') + + sts, stdout, stderr = assert_python_ok('-c', code, + PYTHONASYNCIODEBUG='1', + PYTHONPATH=aio_path) + self.assertEqual(stdout.rstrip(), b'True') + + sts, stdout, stderr = assert_python_ok('-E', '-c', code, + PYTHONASYNCIODEBUG='1', + PYTHONPATH=aio_path) + self.assertEqual(stdout.rstrip(), b'False') + + +class FutureGatherTests(GatherTestsBase, test_utils.TestCase): def wrap_futures(self, *futures): return futures def _check_empty_sequence(self, seq_or_iter): - events.set_event_loop(self.one_loop) - self.addCleanup(events.set_event_loop, None) - fut = tasks.gather(*seq_or_iter) - self.assertIsInstance(fut, futures.Future) + asyncio.set_event_loop(self.one_loop) + self.addCleanup(asyncio.set_event_loop, None) + fut = asyncio.gather(*seq_or_iter) + self.assertIsInstance(fut, asyncio.Future) self.assertIs(fut._loop, self.one_loop) self._run_loop(self.one_loop) self.assertTrue(fut.done()) self.assertEqual(fut.result(), []) - fut = tasks.gather(*seq_or_iter, loop=self.other_loop) + fut = asyncio.gather(*seq_or_iter, loop=self.other_loop) self.assertIs(fut._loop, self.other_loop) def test_constructor_empty_sequence(self): @@ -1361,28 +1941,28 @@ def test_constructor_empty_sequence(self): self._check_empty_sequence(iter("")) def test_constructor_heterogenous_futures(self): - fut1 = futures.Future(loop=self.one_loop) - fut2 = futures.Future(loop=self.other_loop) + fut1 = asyncio.Future(loop=self.one_loop) + fut2 = asyncio.Future(loop=self.other_loop) with self.assertRaises(ValueError): - tasks.gather(fut1, fut2) + asyncio.gather(fut1, fut2) with self.assertRaises(ValueError): - tasks.gather(fut1, loop=self.other_loop) + asyncio.gather(fut1, loop=self.other_loop) def test_constructor_homogenous_futures(self): - children = [futures.Future(loop=self.other_loop) for i in range(3)] - fut = tasks.gather(*children) + children = [asyncio.Future(loop=self.other_loop) for i in range(3)] + fut = asyncio.gather(*children) self.assertIs(fut._loop, self.other_loop) self._run_loop(self.other_loop) self.assertFalse(fut.done()) - fut = tasks.gather(*children, loop=self.other_loop) + fut = asyncio.gather(*children, loop=self.other_loop) self.assertIs(fut._loop, self.other_loop) self._run_loop(self.other_loop) self.assertFalse(fut.done()) def test_one_cancellation(self): - a, b, c, d, e = [futures.Future(loop=self.one_loop) for i in range(5)] - fut = tasks.gather(a, b, c, d, e) - cb = Mock() + a, b, c, d, e = [asyncio.Future(loop=self.one_loop) for i in range(5)] + fut = asyncio.gather(a, b, c, d, e) + cb = test_utils.MockCallback() fut.add_done_callback(cb) a.set_result(1) b.cancel() @@ -1390,17 +1970,18 @@ def test_one_cancellation(self): self.assertTrue(fut.done()) cb.assert_called_once_with(fut) self.assertFalse(fut.cancelled()) - self.assertIsInstance(fut.exception(), futures.CancelledError) + self.assertIsInstance(fut.exception(), asyncio.CancelledError) # Does nothing c.set_result(3) d.cancel() e.set_exception(RuntimeError()) + e.exception() def test_result_exception_one_cancellation(self): - a, b, c, d, e, f = [futures.Future(loop=self.one_loop) + a, b, c, d, e, f = [asyncio.Future(loop=self.one_loop) for i in range(6)] - fut = tasks.gather(a, b, c, d, e, f, return_exceptions=True) - cb = Mock() + fut = asyncio.gather(a, b, c, d, e, f, return_exceptions=True) + cb = test_utils.MockCallback() fut.add_done_callback(cb) a.set_result(1) zde = ZeroDivisionError() @@ -1413,75 +1994,80 @@ def test_result_exception_one_cancellation(self): rte = RuntimeError() f.set_exception(rte) res = self.one_loop.run_until_complete(fut) - self.assertIsInstance(res[2], futures.CancelledError) - self.assertIsInstance(res[4], futures.CancelledError) + self.assertIsInstance(res[2], asyncio.CancelledError) + self.assertIsInstance(res[4], asyncio.CancelledError) res[2] = res[4] = None self.assertEqual(res, [1, zde, None, 3, None, rte]) cb.assert_called_once_with(fut) -class CoroutineGatherTests(GatherTestsBase, unittest.TestCase): +class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase): def setUp(self): super().setUp() - events.set_event_loop(self.one_loop) - - def tearDown(self): - events.set_event_loop(None) - super().tearDown() + asyncio.set_event_loop(self.one_loop) def wrap_futures(self, *futures): coros = [] for fut in futures: - @tasks.coroutine + @asyncio.coroutine def coro(fut=fut): return (yield from fut) coros.append(coro()) return coros def test_constructor_loop_selection(self): - @tasks.coroutine + @asyncio.coroutine def coro(): return 'abc' gen1 = coro() gen2 = coro() - fut = tasks.gather(gen1, gen2) + fut = asyncio.gather(gen1, gen2) self.assertIs(fut._loop, self.one_loop) - gen1.close() - gen2.close() + self.one_loop.run_until_complete(fut) + + self.set_event_loop(self.other_loop, cleanup=False) gen3 = coro() gen4 = coro() - fut = tasks.gather(gen3, gen4, loop=self.other_loop) - self.assertIs(fut._loop, self.other_loop) - gen3.close() - gen4.close() + fut2 = asyncio.gather(gen3, gen4, loop=self.other_loop) + self.assertIs(fut2._loop, self.other_loop) + self.other_loop.run_until_complete(fut2) + + def test_duplicate_coroutines(self): + @asyncio.coroutine + def coro(s): + return s + c = coro('abc') + fut = asyncio.gather(c, c, coro('def'), c, loop=self.one_loop) + self._run_loop(self.one_loop) + self.assertEqual(fut.result(), ['abc', 'abc', 'def', 'abc']) def test_cancellation_broadcast(self): # Cancelling outer() cancels all children. proof = 0 - waiter = futures.Future(loop=self.one_loop) + waiter = asyncio.Future(loop=self.one_loop) - @tasks.coroutine + @asyncio.coroutine def inner(): nonlocal proof yield from waiter proof += 1 - child1 = tasks.async(inner(), loop=self.one_loop) - child2 = tasks.async(inner(), loop=self.one_loop) + child1 = asyncio.ensure_future(inner(), loop=self.one_loop) + child2 = asyncio.ensure_future(inner(), loop=self.one_loop) gatherer = None - @tasks.coroutine + @asyncio.coroutine def outer(): nonlocal proof, gatherer - gatherer = tasks.gather(child1, child2, loop=self.one_loop) + gatherer = asyncio.gather(child1, child2, loop=self.one_loop) yield from gatherer proof += 100 - f = tasks.async(outer(), loop=self.one_loop) + f = asyncio.ensure_future(outer(), loop=self.one_loop) test_utils.run_briefly(self.one_loop) self.assertTrue(f.cancel()) - with self.assertRaises(futures.CancelledError): + with self.assertRaises(asyncio.CancelledError): self.one_loop.run_until_complete(f) self.assertFalse(gatherer.cancel()) self.assertTrue(waiter.cancelled()) @@ -1493,19 +2079,19 @@ def outer(): def test_exception_marking(self): # Test for the first line marked "Mark exception retrieved." - @tasks.coroutine + @asyncio.coroutine def inner(f): yield from f raise RuntimeError('should not be ignored') - a = futures.Future(loop=self.one_loop) - b = futures.Future(loop=self.one_loop) + a = asyncio.Future(loop=self.one_loop) + b = asyncio.Future(loop=self.one_loop) - @tasks.coroutine + @asyncio.coroutine def outer(): - yield from tasks.gather(inner(a), inner(b), loop=self.one_loop) + yield from asyncio.gather(inner(a), inner(b), loop=self.one_loop) - f = tasks.async(outer(), loop=self.one_loop) + f = asyncio.ensure_future(outer(), loop=self.one_loop) test_utils.run_briefly(self.one_loop) a.set_result(None) test_utils.run_briefly(self.one_loop) @@ -1514,5 +2100,93 @@ def outer(): self.assertIsInstance(f.exception(), RuntimeError) +class RunCoroutineThreadsafeTests(test_utils.TestCase): + """Test case for futures.submit_to_loop.""" + + def setUp(self): + self.loop = self.new_test_loop(self.time_gen) + + def time_gen(self): + """Handle the timer.""" + yield 0 # second + yield 1 # second + + @asyncio.coroutine + def add(self, a, b, fail=False, cancel=False): + """Wait 1 second and return a + b.""" + yield from asyncio.sleep(1, loop=self.loop) + if fail: + raise RuntimeError("Fail!") + if cancel: + asyncio.tasks.Task.current_task(self.loop).cancel() + yield + return a + b + + def target(self, fail=False, cancel=False, timeout=None): + """Run add coroutine in the event loop.""" + coro = self.add(1, 2, fail=fail, cancel=cancel) + future = asyncio.run_coroutine_threadsafe(coro, self.loop) + try: + return future.result(timeout) + finally: + future.done() or future.cancel() + + def test_run_coroutine_threadsafe(self): + """Test coroutine submission from a thread to an event loop.""" + future = self.loop.run_in_executor(None, self.target) + result = self.loop.run_until_complete(future) + self.assertEqual(result, 3) + + def test_run_coroutine_threadsafe_with_exception(self): + """Test coroutine submission from a thread to an event loop + when an exception is raised.""" + future = self.loop.run_in_executor(None, self.target, True) + with self.assertRaises(RuntimeError) as exc_context: + self.loop.run_until_complete(future) + self.assertIn("Fail!", exc_context.exception.args) + + def test_run_coroutine_threadsafe_with_timeout(self): + """Test coroutine submission from a thread to an event loop + when a timeout is raised.""" + callback = lambda: self.target(timeout=0) + future = self.loop.run_in_executor(None, callback) + with self.assertRaises(asyncio.TimeoutError): + self.loop.run_until_complete(future) + # Clear the time generator and tasks + test_utils.run_briefly(self.loop) + # Check that there's no pending task (add has been cancelled) + for task in asyncio.Task.all_tasks(self.loop): + self.assertTrue(task.done()) + + def test_run_coroutine_threadsafe_task_cancelled(self): + """Test coroutine submission from a tread to an event loop + when the task is cancelled.""" + callback = lambda: self.target(cancel=True) + future = self.loop.run_in_executor(None, callback) + with self.assertRaises(asyncio.CancelledError): + self.loop.run_until_complete(future) + + def test_run_coroutine_threadsafe_task_factory_exception(self): + """Test coroutine submission from a tread to an event loop + when the task factory raise an exception.""" + # Clear the time generator + asyncio.ensure_future(self.add(1, 2), loop=self.loop) + # Schedule the target + future = self.loop.run_in_executor(None, self.target) + # Set corrupted task factory + self.loop.set_task_factory(lambda loop, coro: wrong_name) + # Set exception handler + callback = test_utils.MockCallback() + self.loop.set_exception_handler(callback) + # Run event loop + with self.assertRaises(NameError) as exc_context: + self.loop.run_until_complete(future) + # Check exceptions + self.assertIn('wrong_name', exc_context.exception.args[0]) + self.assertEqual(len(callback.call_args_list), 1) + (loop, context), kwargs = callback.call_args + self.assertEqual(context['exception'], exc_context.exception) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_transports.py b/Lib/test/test_asyncio/test_transports.py index f96445c19c85..3b6e3d67075b 100644 --- a/Lib/test/test_asyncio/test_transports.py +++ b/Lib/test/test_asyncio/test_transports.py @@ -1,19 +1,20 @@ """Tests for transports.py.""" import unittest -import unittest.mock +from unittest import mock +import asyncio from asyncio import transports class TransportTests(unittest.TestCase): def test_ctor_extra_is_none(self): - transport = transports.Transport() + transport = asyncio.Transport() self.assertEqual(transport._extra, {}) def test_get_extra_info(self): - transport = transports.Transport({'extra': 'info'}) + transport = asyncio.Transport({'extra': 'info'}) self.assertEqual('info', transport.get_extra_info('extra')) self.assertIsNone(transport.get_extra_info('unknown')) @@ -21,15 +22,21 @@ def test_get_extra_info(self): self.assertIs(default, transport.get_extra_info('unknown', default)) def test_writelines(self): - transport = transports.Transport() - transport.write = unittest.mock.Mock() + transport = asyncio.Transport() + transport.write = mock.Mock() - transport.writelines(['line1', 'line2', 'line3']) - self.assertEqual(3, transport.write.call_count) + transport.writelines([b'line1', + bytearray(b'line2'), + memoryview(b'line3')]) + self.assertEqual(1, transport.write.call_count) + transport.write.assert_called_with(b'line1line2line3') def test_not_implemented(self): - transport = transports.Transport() + transport = asyncio.Transport() + self.assertRaises(NotImplementedError, + transport.set_write_buffer_limits) + self.assertRaises(NotImplementedError, transport.get_write_buffer_size) self.assertRaises(NotImplementedError, transport.write, 'data') self.assertRaises(NotImplementedError, transport.write_eof) self.assertRaises(NotImplementedError, transport.can_write_eof) @@ -39,13 +46,13 @@ def test_not_implemented(self): self.assertRaises(NotImplementedError, transport.abort) def test_dgram_not_implemented(self): - transport = transports.DatagramTransport() + transport = asyncio.DatagramTransport() self.assertRaises(NotImplementedError, transport.sendto, 'data') self.assertRaises(NotImplementedError, transport.abort) def test_subprocess_transport_not_implemented(self): - transport = transports.SubprocessTransport() + transport = asyncio.SubprocessTransport() self.assertRaises(NotImplementedError, transport.get_pid) self.assertRaises(NotImplementedError, transport.get_returncode) @@ -54,6 +61,31 @@ def test_subprocess_transport_not_implemented(self): self.assertRaises(NotImplementedError, transport.terminate) self.assertRaises(NotImplementedError, transport.kill) + def test_flowcontrol_mixin_set_write_limits(self): + + class MyTransport(transports._FlowControlMixin, + transports.Transport): + + def get_write_buffer_size(self): + return 512 + + loop = mock.Mock() + transport = MyTransport(loop=loop) + transport._protocol = mock.Mock() + + self.assertFalse(transport._protocol_paused) + + with self.assertRaisesRegex(ValueError, 'high.*must be >= low'): + transport.set_write_buffer_limits(high=0, low=1) + + transport.set_write_buffer_limits(high=1024, low=128) + self.assertFalse(transport._protocol_paused) + self.assertEqual(transport.get_write_buffer_limits(), (128, 1024)) + + transport.set_write_buffer_limits(high=256, low=128) + self.assertTrue(transport._protocol_paused) + self.assertEqual(transport.get_write_buffer_limits(), (128, 256)) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index 98cf407959de..dc0835c527d1 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -1,38 +1,46 @@ """Tests for unix_events.py.""" import collections -import gc import errno import io import os -import pprint import signal +import socket import stat import sys +import tempfile import threading import unittest -import unittest.mock +from unittest import mock if sys.platform == 'win32': raise unittest.SkipTest('UNIX only') -from asyncio import events -from asyncio import futures -from asyncio import protocols +import asyncio +from asyncio import log from asyncio import test_utils from asyncio import unix_events +MOCK_ANY = mock.ANY + + +def close_pipe_transport(transport): + # Don't call transport.close() because the event loop and the selector + # are mocked + if transport._pipe is None: + return + transport._pipe.close() + transport._pipe = None + + @unittest.skipUnless(signal, 'Signals are not supported') -class SelectorEventLoopTests(unittest.TestCase): +class SelectorEventLoopSignalTests(test_utils.TestCase): def setUp(self): - self.loop = unix_events.SelectorEventLoop() - events.set_event_loop(None) - - def tearDown(self): - self.loop.close() + self.loop = asyncio.SelectorEventLoop() + self.set_event_loop(self.loop) def test_check_signal(self): self.assertRaises( @@ -41,17 +49,18 @@ def test_check_signal(self): ValueError, self.loop._check_signal, signal.NSIG + 1) def test_handle_signal_no_handler(self): - self.loop._handle_signal(signal.NSIG + 1, ()) + self.loop._handle_signal(signal.NSIG + 1) def test_handle_signal_cancelled_handler(self): - h = events.Handle(unittest.mock.Mock(), ()) + h = asyncio.Handle(mock.Mock(), (), + loop=mock.Mock()) h.cancel() self.loop._signal_handlers[signal.NSIG + 1] = h - self.loop.remove_signal_handler = unittest.mock.Mock() - self.loop._handle_signal(signal.NSIG + 1, ()) + self.loop.remove_signal_handler = mock.Mock() + self.loop._handle_signal(signal.NSIG + 1) self.loop.remove_signal_handler.assert_called_with(signal.NSIG + 1) - @unittest.mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.unix_events.signal') def test_add_signal_handler_setup_error(self, m_signal): m_signal.NSIG = signal.NSIG m_signal.set_wakeup_fd.side_effect = ValueError @@ -61,17 +70,35 @@ def test_add_signal_handler_setup_error(self, m_signal): self.loop.add_signal_handler, signal.SIGINT, lambda: True) - @unittest.mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.unix_events.signal') + def test_add_signal_handler_coroutine_error(self, m_signal): + m_signal.NSIG = signal.NSIG + + @asyncio.coroutine + def simple_coroutine(): + yield from [] + + # callback must not be a coroutine function + coro_func = simple_coroutine + coro_obj = coro_func() + self.addCleanup(coro_obj.close) + for func in (coro_func, coro_obj): + self.assertRaisesRegex( + TypeError, 'coroutines cannot be used with add_signal_handler', + self.loop.add_signal_handler, + signal.SIGINT, func) + + @mock.patch('asyncio.unix_events.signal') def test_add_signal_handler(self, m_signal): m_signal.NSIG = signal.NSIG cb = lambda: True self.loop.add_signal_handler(signal.SIGHUP, cb) h = self.loop._signal_handlers.get(signal.SIGHUP) - self.assertIsInstance(h, events.Handle) + self.assertIsInstance(h, asyncio.Handle) self.assertEqual(h._callback, cb) - @unittest.mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.unix_events.signal') def test_add_signal_handler_install_error(self, m_signal): m_signal.NSIG = signal.NSIG @@ -89,8 +116,8 @@ class Err(OSError): self.loop.add_signal_handler, signal.SIGINT, lambda: True) - @unittest.mock.patch('asyncio.unix_events.signal') - @unittest.mock.patch('asyncio.unix_events.logger') + @mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.base_events.logger') def test_add_signal_handler_install_error2(self, m_logging, m_signal): m_signal.NSIG = signal.NSIG @@ -106,8 +133,8 @@ class Err(OSError): self.assertFalse(m_logging.info.called) self.assertEqual(1, m_signal.set_wakeup_fd.call_count) - @unittest.mock.patch('asyncio.unix_events.signal') - @unittest.mock.patch('asyncio.unix_events.logger') + @mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.base_events.logger') def test_add_signal_handler_install_error3(self, m_logging, m_signal): class Err(OSError): errno = errno.EINVAL @@ -121,7 +148,7 @@ class Err(OSError): self.assertFalse(m_logging.info.called) self.assertEqual(2, m_signal.set_wakeup_fd.call_count) - @unittest.mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.unix_events.signal') def test_remove_signal_handler(self, m_signal): m_signal.NSIG = signal.NSIG @@ -134,7 +161,7 @@ def test_remove_signal_handler(self, m_signal): self.assertEqual( (signal.SIGHUP, m_signal.SIG_DFL), m_signal.signal.call_args[0]) - @unittest.mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.unix_events.signal') def test_remove_signal_handler_2(self, m_signal): m_signal.NSIG = signal.NSIG m_signal.SIGINT = signal.SIGINT @@ -151,8 +178,8 @@ def test_remove_signal_handler_2(self, m_signal): (signal.SIGINT, m_signal.default_int_handler), m_signal.signal.call_args[0]) - @unittest.mock.patch('asyncio.unix_events.signal') - @unittest.mock.patch('asyncio.unix_events.logger') + @mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.base_events.logger') def test_remove_signal_handler_cleanup_error(self, m_logging, m_signal): m_signal.NSIG = signal.NSIG self.loop.add_signal_handler(signal.SIGHUP, lambda: True) @@ -162,7 +189,7 @@ def test_remove_signal_handler_cleanup_error(self, m_logging, m_signal): self.loop.remove_signal_handler(signal.SIGHUP) self.assertTrue(m_logging.info) - @unittest.mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.unix_events.signal') def test_remove_signal_handler_error(self, m_signal): m_signal.NSIG = signal.NSIG self.loop.add_signal_handler(signal.SIGHUP, lambda: True) @@ -172,7 +199,7 @@ def test_remove_signal_handler_error(self, m_signal): self.assertRaises( OSError, self.loop.remove_signal_handler, signal.SIGHUP) - @unittest.mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.unix_events.signal') def test_remove_signal_handler_error2(self, m_signal): m_signal.NSIG = signal.NSIG self.loop.add_signal_handler(signal.SIGHUP, lambda: True) @@ -184,7 +211,7 @@ class Err(OSError): self.assertRaises( RuntimeError, self.loop.remove_signal_handler, signal.SIGHUP) - @unittest.mock.patch('asyncio.unix_events.signal') + @mock.patch('asyncio.unix_events.signal') def test_close(self, m_signal): m_signal.NSIG = signal.NSIG @@ -201,53 +228,148 @@ def test_close(self, m_signal): m_signal.set_wakeup_fd.assert_called_once_with(-1) -class UnixReadPipeTransportTests(unittest.TestCase): +@unittest.skipUnless(hasattr(socket, 'AF_UNIX'), + 'UNIX Sockets are not supported') +class SelectorEventLoopUnixSocketTests(test_utils.TestCase): + + def setUp(self): + self.loop = asyncio.SelectorEventLoop() + self.set_event_loop(self.loop) + + def test_create_unix_server_existing_path_sock(self): + with test_utils.unix_socket_path() as path: + sock = socket.socket(socket.AF_UNIX) + sock.bind(path) + with sock: + coro = self.loop.create_unix_server(lambda: None, path) + with self.assertRaisesRegex(OSError, + 'Address.*is already in use'): + self.loop.run_until_complete(coro) + + def test_create_unix_server_existing_path_nonsock(self): + with tempfile.NamedTemporaryFile() as file: + coro = self.loop.create_unix_server(lambda: None, file.name) + with self.assertRaisesRegex(OSError, + 'Address.*is already in use'): + self.loop.run_until_complete(coro) + + def test_create_unix_server_ssl_bool(self): + coro = self.loop.create_unix_server(lambda: None, path='spam', + ssl=True) + with self.assertRaisesRegex(TypeError, + 'ssl argument must be an SSLContext'): + self.loop.run_until_complete(coro) + + def test_create_unix_server_nopath_nosock(self): + coro = self.loop.create_unix_server(lambda: None, path=None) + with self.assertRaisesRegex(ValueError, + 'path was not specified, and no sock'): + self.loop.run_until_complete(coro) + + def test_create_unix_server_path_inetsock(self): + sock = socket.socket() + with sock: + coro = self.loop.create_unix_server(lambda: None, path=None, + sock=sock) + with self.assertRaisesRegex(ValueError, + 'A UNIX Domain Socket was expected'): + self.loop.run_until_complete(coro) + + @mock.patch('asyncio.unix_events.socket') + def test_create_unix_server_bind_error(self, m_socket): + # Ensure that the socket is closed on any bind error + sock = mock.Mock() + m_socket.socket.return_value = sock + + sock.bind.side_effect = OSError + coro = self.loop.create_unix_server(lambda: None, path="/test") + with self.assertRaises(OSError): + self.loop.run_until_complete(coro) + self.assertTrue(sock.close.called) + + sock.bind.side_effect = MemoryError + coro = self.loop.create_unix_server(lambda: None, path="/test") + with self.assertRaises(MemoryError): + self.loop.run_until_complete(coro) + self.assertTrue(sock.close.called) + + def test_create_unix_connection_path_sock(self): + coro = self.loop.create_unix_connection( + lambda: None, os.devnull, sock=object()) + with self.assertRaisesRegex(ValueError, 'path and sock can not be'): + self.loop.run_until_complete(coro) + + def test_create_unix_connection_nopath_nosock(self): + coro = self.loop.create_unix_connection( + lambda: None, None) + with self.assertRaisesRegex(ValueError, + 'no path and sock were specified'): + self.loop.run_until_complete(coro) + + def test_create_unix_connection_nossl_serverhost(self): + coro = self.loop.create_unix_connection( + lambda: None, os.devnull, server_hostname='spam') + with self.assertRaisesRegex(ValueError, + 'server_hostname is only meaningful'): + self.loop.run_until_complete(coro) + + def test_create_unix_connection_ssl_noserverhost(self): + coro = self.loop.create_unix_connection( + lambda: None, os.devnull, ssl=True) + + with self.assertRaisesRegex( + ValueError, 'you have to pass server_hostname when using ssl'): + + self.loop.run_until_complete(coro) + + +class UnixReadPipeTransportTests(test_utils.TestCase): def setUp(self): - self.loop = test_utils.TestLoop() - self.protocol = test_utils.make_test_protocol(protocols.Protocol) - self.pipe = unittest.mock.Mock(spec_set=io.RawIOBase) + self.loop = self.new_test_loop() + self.protocol = test_utils.make_test_protocol(asyncio.Protocol) + self.pipe = mock.Mock(spec_set=io.RawIOBase) self.pipe.fileno.return_value = 5 - fcntl_patcher = unittest.mock.patch('fcntl.fcntl') - fcntl_patcher.start() - self.addCleanup(fcntl_patcher.stop) + blocking_patcher = mock.patch('asyncio.unix_events._set_nonblocking') + blocking_patcher.start() + self.addCleanup(blocking_patcher.stop) - fstat_patcher = unittest.mock.patch('os.fstat') + fstat_patcher = mock.patch('os.fstat') m_fstat = fstat_patcher.start() - st = unittest.mock.Mock() + st = mock.Mock() st.st_mode = stat.S_IFIFO m_fstat.return_value = st self.addCleanup(fstat_patcher.stop) + def read_pipe_transport(self, waiter=None): + transport = unix_events._UnixReadPipeTransport(self.loop, self.pipe, + self.protocol, + waiter=waiter) + self.addCleanup(close_pipe_transport, transport) + return transport + def test_ctor(self): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) - self.loop.assert_reader(5, tr._read_ready) - test_utils.run_briefly(self.loop) - self.protocol.connection_made.assert_called_with(tr) + waiter = asyncio.Future(loop=self.loop) + tr = self.read_pipe_transport(waiter=waiter) + self.loop.run_until_complete(waiter) - def test_ctor_with_waiter(self): - fut = futures.Future(loop=self.loop) - unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol, fut) - test_utils.run_briefly(self.loop) - self.assertIsNone(fut.result()) + self.protocol.connection_made.assert_called_with(tr) + self.loop.assert_reader(5, tr._read_ready) + self.assertIsNone(waiter.result()) - @unittest.mock.patch('os.read') + @mock.patch('os.read') def test__read_ready(self, m_read): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.read_pipe_transport() m_read.return_value = b'data' tr._read_ready() m_read.assert_called_with(5, tr.max_size) self.protocol.data_received.assert_called_with(b'data') - @unittest.mock.patch('os.read') + @mock.patch('os.read') def test__read_ready_eof(self, m_read): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.read_pipe_transport() m_read.return_value = b'' tr._read_ready() @@ -257,10 +379,9 @@ def test__read_ready_eof(self, m_read): self.protocol.eof_received.assert_called_with() self.protocol.connection_lost.assert_called_with(None) - @unittest.mock.patch('os.read') + @mock.patch('os.read') def test__read_ready_blocked(self, m_read): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.read_pipe_transport() m_read.side_effect = BlockingIOError tr._read_ready() @@ -268,62 +389,55 @@ def test__read_ready_blocked(self, m_read): test_utils.run_briefly(self.loop) self.assertFalse(self.protocol.data_received.called) - @unittest.mock.patch('asyncio.log.logger.exception') - @unittest.mock.patch('os.read') + @mock.patch('asyncio.log.logger.error') + @mock.patch('os.read') def test__read_ready_error(self, m_read, m_logexc): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.read_pipe_transport() err = OSError() m_read.side_effect = err - tr._close = unittest.mock.Mock() + tr._close = mock.Mock() tr._read_ready() m_read.assert_called_with(5, tr.max_size) tr._close.assert_called_with(err) - m_logexc.assert_called_with('Fatal error for %s', tr) + m_logexc.assert_called_with( + test_utils.MockPattern( + 'Fatal read error on pipe transport' + '\nprotocol:.*\ntransport:.*'), + exc_info=(OSError, MOCK_ANY, MOCK_ANY)) - @unittest.mock.patch('os.read') + @mock.patch('os.read') def test_pause_reading(self, m_read): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) - - m = unittest.mock.Mock() + tr = self.read_pipe_transport() + m = mock.Mock() self.loop.add_reader(5, m) tr.pause_reading() self.assertFalse(self.loop.readers) - @unittest.mock.patch('os.read') + @mock.patch('os.read') def test_resume_reading(self, m_read): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.read_pipe_transport() tr.resume_reading() self.loop.assert_reader(5, tr._read_ready) - @unittest.mock.patch('os.read') + @mock.patch('os.read') def test_close(self, m_read): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) - - tr._close = unittest.mock.Mock() + tr = self.read_pipe_transport() + tr._close = mock.Mock() tr.close() tr._close.assert_called_with(None) - @unittest.mock.patch('os.read') + @mock.patch('os.read') def test_close_already_closing(self, m_read): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.read_pipe_transport() tr._closing = True - tr._close = unittest.mock.Mock() + tr._close = mock.Mock() tr.close() self.assertFalse(tr._close.called) - @unittest.mock.patch('os.read') + @mock.patch('os.read') def test__close(self, m_read): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.read_pipe_transport() err = object() tr._close(err) self.assertTrue(tr._closing) @@ -332,8 +446,9 @@ def test__close(self, m_read): self.protocol.connection_lost.assert_called_with(err) def test__call_connection_lost(self): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.read_pipe_transport() + self.assertIsNotNone(tr._protocol) + self.assertIsNotNone(tr._loop) err = None tr._call_connection_lost(err) @@ -341,15 +456,12 @@ def test__call_connection_lost(self): self.pipe.close.assert_called_with() self.assertIsNone(tr._protocol) - self.assertEqual(2, sys.getrefcount(self.protocol), - pprint.pformat(gc.get_referrers(self.protocol))) self.assertIsNone(tr._loop) - self.assertEqual(2, sys.getrefcount(self.loop), - pprint.pformat(gc.get_referrers(self.loop))) def test__call_connection_lost_with_err(self): - tr = unix_events._UnixReadPipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.read_pipe_transport() + self.assertIsNotNone(tr._protocol) + self.assertIsNotNone(tr._loop) err = OSError() tr._call_connection_lost(err) @@ -357,89 +469,77 @@ def test__call_connection_lost_with_err(self): self.pipe.close.assert_called_with() self.assertIsNone(tr._protocol) - self.assertEqual(2, sys.getrefcount(self.protocol), - pprint.pformat(gc.get_referrers(self.protocol))) self.assertIsNone(tr._loop) - self.assertEqual(2, sys.getrefcount(self.loop), - pprint.pformat(gc.get_referrers(self.loop))) -class UnixWritePipeTransportTests(unittest.TestCase): +class UnixWritePipeTransportTests(test_utils.TestCase): def setUp(self): - self.loop = test_utils.TestLoop() - self.protocol = test_utils.make_test_protocol(protocols.BaseProtocol) - self.pipe = unittest.mock.Mock(spec_set=io.RawIOBase) + self.loop = self.new_test_loop() + self.protocol = test_utils.make_test_protocol(asyncio.BaseProtocol) + self.pipe = mock.Mock(spec_set=io.RawIOBase) self.pipe.fileno.return_value = 5 - fcntl_patcher = unittest.mock.patch('fcntl.fcntl') - fcntl_patcher.start() - self.addCleanup(fcntl_patcher.stop) + blocking_patcher = mock.patch('asyncio.unix_events._set_nonblocking') + blocking_patcher.start() + self.addCleanup(blocking_patcher.stop) - fstat_patcher = unittest.mock.patch('os.fstat') + fstat_patcher = mock.patch('os.fstat') m_fstat = fstat_patcher.start() - st = unittest.mock.Mock() + st = mock.Mock() st.st_mode = stat.S_IFSOCK m_fstat.return_value = st self.addCleanup(fstat_patcher.stop) + def write_pipe_transport(self, waiter=None): + transport = unix_events._UnixWritePipeTransport(self.loop, self.pipe, + self.protocol, + waiter=waiter) + self.addCleanup(close_pipe_transport, transport) + return transport + def test_ctor(self): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - self.loop.assert_reader(5, tr._read_ready) - test_utils.run_briefly(self.loop) - self.protocol.connection_made.assert_called_with(tr) + waiter = asyncio.Future(loop=self.loop) + tr = self.write_pipe_transport(waiter=waiter) + self.loop.run_until_complete(waiter) - def test_ctor_with_waiter(self): - fut = futures.Future(loop=self.loop) - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol, fut) + self.protocol.connection_made.assert_called_with(tr) self.loop.assert_reader(5, tr._read_ready) - test_utils.run_briefly(self.loop) - self.assertEqual(None, fut.result()) + self.assertEqual(None, waiter.result()) def test_can_write_eof(self): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.write_pipe_transport() self.assertTrue(tr.can_write_eof()) - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test_write(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() m_write.return_value = 4 tr.write(b'data') m_write.assert_called_with(5, b'data') self.assertFalse(self.loop.writers) self.assertEqual([], tr._buffer) - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test_write_no_data(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() tr.write(b'') self.assertFalse(m_write.called) self.assertFalse(self.loop.writers) self.assertEqual([], tr._buffer) - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test_write_partial(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() m_write.return_value = 2 tr.write(b'data') m_write.assert_called_with(5, b'data') self.loop.assert_writer(5, tr._write_ready) self.assertEqual([b'ta'], tr._buffer) - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test_write_buffer(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() self.loop.add_writer(5, tr._write_ready) tr._buffer = [b'previous'] tr.write(b'data') @@ -447,31 +547,29 @@ def test_write_buffer(self, m_write): self.loop.assert_writer(5, tr._write_ready) self.assertEqual([b'previous', b'data'], tr._buffer) - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test_write_again(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() m_write.side_effect = BlockingIOError() tr.write(b'data') m_write.assert_called_with(5, b'data') self.loop.assert_writer(5, tr._write_ready) self.assertEqual([b'data'], tr._buffer) - @unittest.mock.patch('asyncio.unix_events.logger') - @unittest.mock.patch('os.write') + @mock.patch('asyncio.unix_events.logger') + @mock.patch('os.write') def test_write_err(self, m_write, m_log): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() err = OSError() m_write.side_effect = err - tr._fatal_error = unittest.mock.Mock() + tr._fatal_error = mock.Mock() tr.write(b'data') m_write.assert_called_with(5, b'data') self.assertFalse(self.loop.writers) self.assertEqual([], tr._buffer) - tr._fatal_error.assert_called_with(err) + tr._fatal_error.assert_called_with( + err, + 'Fatal write error on pipe transport') self.assertEqual(1, tr._conn_lost) tr.write(b'data') @@ -483,11 +581,11 @@ def test_write_err(self, m_write, m_log): # This is a bit overspecified. :-( m_log.warning.assert_called_with( 'pipe closed by peer or os.write(pipe, data) raised exception.') + tr.close() - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test_write_close(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.write_pipe_transport() tr._read_ready() # pipe was closed by peer tr.write(b'data') @@ -496,8 +594,7 @@ def test_write_close(self, m_write): self.assertEqual(tr._conn_lost, 2) def test__read_ready(self): - tr = unix_events._UnixWritePipeTransport(self.loop, self.pipe, - self.protocol) + tr = self.write_pipe_transport() tr._read_ready() self.assertFalse(self.loop.readers) self.assertFalse(self.loop.writers) @@ -505,10 +602,9 @@ def test__read_ready(self): test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test__write_ready(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.write_pipe_transport() self.loop.add_writer(5, tr._write_ready) tr._buffer = [b'da', b'ta'] m_write.return_value = 4 @@ -517,11 +613,9 @@ def test__write_ready(self, m_write): self.assertFalse(self.loop.writers) self.assertEqual([], tr._buffer) - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test__write_ready_partial(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() self.loop.add_writer(5, tr._write_ready) tr._buffer = [b'da', b'ta'] m_write.return_value = 3 @@ -530,11 +624,9 @@ def test__write_ready_partial(self, m_write): self.loop.assert_writer(5, tr._write_ready) self.assertEqual([b'a'], tr._buffer) - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test__write_ready_again(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() self.loop.add_writer(5, tr._write_ready) tr._buffer = [b'da', b'ta'] m_write.side_effect = BlockingIOError() @@ -543,11 +635,9 @@ def test__write_ready_again(self, m_write): self.loop.assert_writer(5, tr._write_ready) self.assertEqual([b'data'], tr._buffer) - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test__write_ready_empty(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() self.loop.add_writer(5, tr._write_ready) tr._buffer = [b'da', b'ta'] m_write.return_value = 0 @@ -556,12 +646,10 @@ def test__write_ready_empty(self, m_write): self.loop.assert_writer(5, tr._write_ready) self.assertEqual([b'data'], tr._buffer) - @unittest.mock.patch('asyncio.log.logger.exception') - @unittest.mock.patch('os.write') + @mock.patch('asyncio.log.logger.error') + @mock.patch('os.write') def test__write_ready_err(self, m_write, m_logexc): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() self.loop.add_writer(5, tr._write_ready) tr._buffer = [b'da', b'ta'] m_write.side_effect = err = OSError() @@ -571,16 +659,18 @@ def test__write_ready_err(self, m_write, m_logexc): self.assertFalse(self.loop.readers) self.assertEqual([], tr._buffer) self.assertTrue(tr._closing) - m_logexc.assert_called_with('Fatal error for %s', tr) + m_logexc.assert_called_with( + test_utils.MockPattern( + 'Fatal write error on pipe transport' + '\nprotocol:.*\ntransport:.*'), + exc_info=(OSError, MOCK_ANY, MOCK_ANY)) self.assertEqual(1, tr._conn_lost) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(err) - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test__write_ready_closing(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() self.loop.add_writer(5, tr._write_ready) tr._closing = True tr._buffer = [b'da', b'ta'] @@ -593,11 +683,9 @@ def test__write_ready_closing(self, m_write): self.protocol.connection_lost.assert_called_with(None) self.pipe.close.assert_called_with() - @unittest.mock.patch('os.write') + @mock.patch('os.write') def test_abort(self, m_write): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() self.loop.add_writer(5, tr._write_ready) self.loop.add_reader(5, tr._read_ready) tr._buffer = [b'da', b'ta'] @@ -611,8 +699,9 @@ def test_abort(self, m_write): self.protocol.connection_lost.assert_called_with(None) def test__call_connection_lost(self): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.write_pipe_transport() + self.assertIsNotNone(tr._protocol) + self.assertIsNotNone(tr._loop) err = None tr._call_connection_lost(err) @@ -620,15 +709,12 @@ def test__call_connection_lost(self): self.pipe.close.assert_called_with() self.assertIsNone(tr._protocol) - self.assertEqual(2, sys.getrefcount(self.protocol), - pprint.pformat(gc.get_referrers(self.protocol))) self.assertIsNone(tr._loop) - self.assertEqual(2, sys.getrefcount(self.loop), - pprint.pformat(gc.get_referrers(self.loop))) def test__call_connection_lost_with_err(self): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.write_pipe_transport() + self.assertIsNotNone(tr._protocol) + self.assertIsNotNone(tr._loop) err = OSError() tr._call_connection_lost(err) @@ -636,33 +722,26 @@ def test__call_connection_lost_with_err(self): self.pipe.close.assert_called_with() self.assertIsNone(tr._protocol) - self.assertEqual(2, sys.getrefcount(self.protocol), - pprint.pformat(gc.get_referrers(self.protocol))) self.assertIsNone(tr._loop) - self.assertEqual(2, sys.getrefcount(self.loop), - pprint.pformat(gc.get_referrers(self.loop))) def test_close(self): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - - tr.write_eof = unittest.mock.Mock() + tr = self.write_pipe_transport() + tr.write_eof = mock.Mock() tr.close() tr.write_eof.assert_called_with() - def test_close_closing(self): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) + # closing the transport twice must not fail + tr.close() - tr.write_eof = unittest.mock.Mock() + def test_close_closing(self): + tr = self.write_pipe_transport() + tr.write_eof = mock.Mock() tr._closing = True tr.close() self.assertFalse(tr.write_eof.called) def test_write_eof(self): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) - + tr = self.write_pipe_transport() tr.write_eof() self.assertTrue(tr._closing) self.assertFalse(self.loop.readers) @@ -670,8 +749,7 @@ def test_write_eof(self): self.protocol.connection_lost.assert_called_with(None) def test_write_eof_pending(self): - tr = unix_events._UnixWritePipeTransport( - self.loop, self.pipe, self.protocol) + tr = self.write_pipe_transport() tr._buffer = [b'data'] tr.write_eof() self.assertTrue(tr._closing) @@ -681,8 +759,8 @@ def test_write_eof_pending(self): class AbstractChildWatcherTests(unittest.TestCase): def test_not_implemented(self): - f = unittest.mock.Mock() - watcher = unix_events.AbstractChildWatcher() + f = mock.Mock() + watcher = asyncio.AbstractChildWatcher() self.assertRaises( NotImplementedError, watcher.add_child_handler, f, f) self.assertRaises( @@ -700,7 +778,7 @@ def test_not_implemented(self): class BaseChildWatcherTests(unittest.TestCase): def test_not_implemented(self): - f = unittest.mock.Mock() + f = mock.Mock() watcher = unix_events.BaseChildWatcher() self.assertRaises( NotImplementedError, watcher._do_waitpid, f) @@ -717,20 +795,20 @@ def test_not_implemented(self): class ChildWatcherTestsMixin: - ignore_warnings = unittest.mock.patch.object(unix_events.logger, "warning") + ignore_warnings = mock.patch.object(log.logger, "warning") def setUp(self): - self.loop = test_utils.TestLoop() + self.loop = self.new_test_loop() self.running = False self.zombies = {} - with unittest.mock.patch.object( + with mock.patch.object( self.loop, "add_signal_handler") as self.m_add_signal_handler: self.watcher = self.create_watcher() self.watcher.attach_loop(self.loop) def waitpid(self, pid, flags): - if isinstance(self.watcher, unix_events.SafeChildWatcher) or pid != -1: + if isinstance(self.watcher, asyncio.SafeChildWatcher) or pid != -1: self.assertGreater(pid, 0) try: if pid < 0: @@ -768,8 +846,8 @@ def test_create_watcher(self): def waitpid_mocks(func): def wrapped_func(self): def patch(target, wrapper): - return unittest.mock.patch(target, wraps=wrapper, - new_callable=unittest.mock.Mock) + return mock.patch(target, wraps=wrapper, + new_callable=mock.Mock) with patch('os.WTERMSIG', self.WTERMSIG) as m_WTERMSIG, \ patch('os.WEXITSTATUS', self.WEXITSTATUS) as m_WEXITSTATUS, \ @@ -785,7 +863,7 @@ def patch(target, wrapper): @waitpid_mocks def test_sigchld(self, m): # register a child - callback = unittest.mock.Mock() + callback = mock.Mock() with self.watcher: self.running = True @@ -845,8 +923,8 @@ def test_sigchld(self, m): @waitpid_mocks def test_sigchld_two_children(self, m): - callback1 = unittest.mock.Mock() - callback2 = unittest.mock.Mock() + callback1 = mock.Mock() + callback2 = mock.Mock() # register child 1 with self.watcher: @@ -871,7 +949,7 @@ def test_sigchld_two_children(self, m): self.assertFalse(m.WEXITSTATUS.called) self.assertFalse(m.WTERMSIG.called) - # childen are running + # children are running self.watcher._sig_chld() self.assertFalse(callback1.called) @@ -949,8 +1027,8 @@ def test_sigchld_two_children(self, m): @waitpid_mocks def test_sigchld_two_children_terminating_together(self, m): - callback1 = unittest.mock.Mock() - callback2 = unittest.mock.Mock() + callback1 = mock.Mock() + callback2 = mock.Mock() # register child 1 with self.watcher: @@ -975,7 +1053,7 @@ def test_sigchld_two_children_terminating_together(self, m): self.assertFalse(m.WEXITSTATUS.called) self.assertFalse(m.WTERMSIG.called) - # childen are running + # children are running self.watcher._sig_chld() self.assertFalse(callback1.called) @@ -1019,7 +1097,7 @@ def test_sigchld_two_children_terminating_together(self, m): @waitpid_mocks def test_sigchld_race_condition(self, m): # register a child - callback = unittest.mock.Mock() + callback = mock.Mock() with self.watcher: # child terminates before being registered @@ -1040,8 +1118,8 @@ def test_sigchld_race_condition(self, m): @waitpid_mocks def test_sigchld_replace_handler(self, m): - callback1 = unittest.mock.Mock() - callback2 = unittest.mock.Mock() + callback1 = mock.Mock() + callback2 = mock.Mock() # register a child with self.watcher: @@ -1093,7 +1171,7 @@ def test_sigchld_replace_handler(self, m): @waitpid_mocks def test_sigchld_remove_handler(self, m): - callback = unittest.mock.Mock() + callback = mock.Mock() # register a child with self.watcher: @@ -1125,7 +1203,7 @@ def test_sigchld_remove_handler(self, m): @waitpid_mocks def test_sigchld_unknown_status(self, m): - callback = unittest.mock.Mock() + callback = mock.Mock() # register a child with self.watcher: @@ -1162,9 +1240,9 @@ def test_sigchld_unknown_status(self, m): @waitpid_mocks def test_remove_child_handler(self, m): - callback1 = unittest.mock.Mock() - callback2 = unittest.mock.Mock() - callback3 = unittest.mock.Mock() + callback1 = mock.Mock() + callback2 = mock.Mock() + callback3 = mock.Mock() # register children with self.watcher: @@ -1195,7 +1273,7 @@ def test_remove_child_handler(self, m): @waitpid_mocks def test_sigchld_unhandled_exception(self, m): - callback = unittest.mock.Mock() + callback = mock.Mock() # register a child with self.watcher: @@ -1205,16 +1283,16 @@ def test_sigchld_unhandled_exception(self, m): # raise an exception m.waitpid.side_effect = ValueError - with unittest.mock.patch.object(unix_events.logger, - "exception") as m_exception: + with mock.patch.object(log.logger, + 'error') as m_error: self.assertEqual(self.watcher._sig_chld(), None) - self.assertTrue(m_exception.called) + self.assertTrue(m_error.called) @waitpid_mocks def test_sigchld_child_reaped_elsewhere(self, m): # register a child - callback = unittest.mock.Mock() + callback = mock.Mock() with self.watcher: self.running = True @@ -1239,8 +1317,7 @@ def test_sigchld_child_reaped_elsewhere(self, m): with self.ignore_warnings: self.watcher._sig_chld() - callback.assert_called(m.waitpid) - if isinstance(self.watcher, unix_events.FastChildWatcher): + if isinstance(self.watcher, asyncio.FastChildWatcher): # here the FastChildWatche enters a deadlock # (there is no way to prevent it) self.assertFalse(callback.called) @@ -1250,8 +1327,8 @@ def test_sigchld_child_reaped_elsewhere(self, m): @waitpid_mocks def test_sigchld_unknown_pid_during_registration(self, m): # register two children - callback1 = unittest.mock.Mock() - callback2 = unittest.mock.Mock() + callback1 = mock.Mock() + callback2 = mock.Mock() with self.ignore_warnings, self.watcher: self.running = True @@ -1271,7 +1348,7 @@ def test_sigchld_unknown_pid_during_registration(self, m): @waitpid_mocks def test_set_loop(self, m): # register a child - callback = unittest.mock.Mock() + callback = mock.Mock() with self.watcher: self.running = True @@ -1279,20 +1356,17 @@ def test_set_loop(self, m): # attach a new loop old_loop = self.loop - self.loop = test_utils.TestLoop() + self.loop = self.new_test_loop() + patch = mock.patch.object - with unittest.mock.patch.object( - old_loop, - "remove_signal_handler") as m_old_remove_signal_handler, \ - unittest.mock.patch.object( - self.loop, - "add_signal_handler") as m_new_add_signal_handler: + with patch(old_loop, "remove_signal_handler") as m_old_remove, \ + patch(self.loop, "add_signal_handler") as m_new_add: self.watcher.attach_loop(self.loop) - m_old_remove_signal_handler.assert_called_once_with( + m_old_remove.assert_called_once_with( signal.SIGCHLD) - m_new_add_signal_handler.assert_called_once_with( + m_new_add.assert_called_once_with( signal.SIGCHLD, self.watcher._sig_chld) # child terminates @@ -1305,9 +1379,9 @@ def test_set_loop(self, m): @waitpid_mocks def test_set_loop_race_condition(self, m): # register 3 children - callback1 = unittest.mock.Mock() - callback2 = unittest.mock.Mock() - callback3 = unittest.mock.Mock() + callback1 = mock.Mock() + callback2 = mock.Mock() + callback3 = mock.Mock() with self.watcher: self.running = True @@ -1319,7 +1393,7 @@ def test_set_loop_race_condition(self, m): old_loop = self.loop self.loop = None - with unittest.mock.patch.object( + with mock.patch.object( old_loop, "remove_signal_handler") as m_remove_signal_handler: self.watcher.attach_loop(None) @@ -1331,15 +1405,15 @@ def test_set_loop_race_condition(self, m): self.add_zombie(61, 11) self.add_zombie(62, -5) - # SIGCHLD was not catched + # SIGCHLD was not caught self.assertFalse(callback1.called) self.assertFalse(callback2.called) self.assertFalse(callback3.called) # attach a new loop - self.loop = test_utils.TestLoop() + self.loop = self.new_test_loop() - with unittest.mock.patch.object( + with mock.patch.object( self.loop, "add_signal_handler") as m_add_signal_handler: self.watcher.attach_loop(self.loop) @@ -1365,8 +1439,7 @@ def test_set_loop_race_condition(self, m): @waitpid_mocks def test_close(self, m): # register two children - callback1 = unittest.mock.Mock() - callback2 = unittest.mock.Mock() + callback1 = mock.Mock() with self.watcher: self.running = True @@ -1380,10 +1453,10 @@ def test_close(self, m): self.watcher.add_child_handler(64, callback1) self.assertEqual(len(self.watcher._callbacks), 1) - if isinstance(self.watcher, unix_events.FastChildWatcher): + if isinstance(self.watcher, asyncio.FastChildWatcher): self.assertEqual(len(self.watcher._zombies), 1) - with unittest.mock.patch.object( + with mock.patch.object( self.loop, "remove_signal_handler") as m_remove_signal_handler: @@ -1392,31 +1465,31 @@ def test_close(self, m): m_remove_signal_handler.assert_called_once_with( signal.SIGCHLD) self.assertFalse(self.watcher._callbacks) - if isinstance(self.watcher, unix_events.FastChildWatcher): + if isinstance(self.watcher, asyncio.FastChildWatcher): self.assertFalse(self.watcher._zombies) -class SafeChildWatcherTests (ChildWatcherTestsMixin, unittest.TestCase): +class SafeChildWatcherTests (ChildWatcherTestsMixin, test_utils.TestCase): def create_watcher(self): - return unix_events.SafeChildWatcher() + return asyncio.SafeChildWatcher() -class FastChildWatcherTests (ChildWatcherTestsMixin, unittest.TestCase): +class FastChildWatcherTests (ChildWatcherTestsMixin, test_utils.TestCase): def create_watcher(self): - return unix_events.FastChildWatcher() + return asyncio.FastChildWatcher() class PolicyTests(unittest.TestCase): def create_policy(self): - return unix_events.DefaultEventLoopPolicy() + return asyncio.DefaultEventLoopPolicy() def test_get_child_watcher(self): policy = self.create_policy() self.assertIsNone(policy._watcher) watcher = policy.get_child_watcher() - self.assertIsInstance(watcher, unix_events.SafeChildWatcher) + self.assertIsInstance(watcher, asyncio.SafeChildWatcher) self.assertIs(policy._watcher, watcher) @@ -1425,7 +1498,7 @@ def test_get_child_watcher(self): def test_get_child_watcher_after_set(self): policy = self.create_policy() - watcher = unix_events.FastChildWatcher() + watcher = asyncio.FastChildWatcher() policy.set_child_watcher(watcher) self.assertIs(policy._watcher, watcher) @@ -1438,7 +1511,7 @@ def test_get_child_watcher_with_mainloop_existing(self): self.assertIsNone(policy._watcher) watcher = policy.get_child_watcher() - self.assertIsInstance(watcher, unix_events.SafeChildWatcher) + self.assertIsInstance(watcher, asyncio.SafeChildWatcher) self.assertIs(watcher._loop, loop) loop.close() @@ -1449,10 +1522,10 @@ def f(): policy.set_event_loop(policy.new_event_loop()) self.assertIsInstance(policy.get_event_loop(), - events.AbstractEventLoop) + asyncio.AbstractEventLoop) watcher = policy.get_child_watcher() - self.assertIsInstance(watcher, unix_events.SafeChildWatcher) + self.assertIsInstance(watcher, asyncio.SafeChildWatcher) self.assertIsNone(watcher._loop) policy.get_event_loop().close() diff --git a/Lib/test/test_asyncio/test_windows_events.py b/Lib/test/test_asyncio/test_windows_events.py index 7ba33dacc41d..7fcf4023eecd 100644 --- a/Lib/test/test_asyncio/test_windows_events.py +++ b/Lib/test/test_asyncio/test_windows_events.py @@ -1,6 +1,7 @@ import os import sys import unittest +from unittest import mock if sys.platform != 'win32': raise unittest.SkipTest('Windows only') @@ -8,17 +9,12 @@ import _winapi import asyncio - -from asyncio import windows_events -from asyncio import futures -from asyncio import protocols -from asyncio import streams -from asyncio import transports -from asyncio import test_utils from asyncio import _overlapped +from asyncio import test_utils +from asyncio import windows_events -class UpperProto(protocols.Protocol): +class UpperProto(asyncio.Protocol): def __init__(self): self.buf = [] @@ -32,29 +28,26 @@ def data_received(self, data): self.trans.close() -class ProactorTests(unittest.TestCase): +class ProactorTests(test_utils.TestCase): def setUp(self): - self.loop = windows_events.ProactorEventLoop() - asyncio.set_event_loop(None) - - def tearDown(self): - self.loop.close() - self.loop = None + self.loop = asyncio.ProactorEventLoop() + self.set_event_loop(self.loop) def test_close(self): a, b = self.loop._socketpair() - trans = self.loop._make_socket_transport(a, protocols.Protocol()) - f = asyncio.async(self.loop.sock_recv(b, 100)) + trans = self.loop._make_socket_transport(a, asyncio.Protocol()) + f = asyncio.ensure_future(self.loop.sock_recv(b, 100)) trans.close() self.loop.run_until_complete(f) self.assertEqual(f.result(), b'') + b.close() def test_double_bind(self): ADDRESS = r'\\.\pipe\test_double_bind-%s' % os.getpid() server1 = windows_events.PipeServer(ADDRESS) with self.assertRaises(PermissionError): - server2 = windows_events.PipeServer(ADDRESS) + windows_events.PipeServer(ADDRESS) server1.close() def test_pipe(self): @@ -66,7 +59,7 @@ def _test_pipe(self): with self.assertRaises(FileNotFoundError): yield from self.loop.create_pipe_connection( - protocols.Protocol, ADDRESS) + asyncio.Protocol, ADDRESS) [server] = yield from self.loop.start_serving_pipe( UpperProto, ADDRESS) @@ -74,11 +67,12 @@ def _test_pipe(self): clients = [] for i in range(5): - stream_reader = streams.StreamReader(loop=self.loop) - protocol = streams.StreamReaderProtocol(stream_reader) + stream_reader = asyncio.StreamReader(loop=self.loop) + protocol = asyncio.StreamReaderProtocol(stream_reader, + loop=self.loop) trans, proto = yield from self.loop.create_pipe_connection( lambda: protocol, ADDRESS) - self.assertIsInstance(trans, transports.Transport) + self.assertIsInstance(trans, asyncio.Transport) self.assertEqual(protocol, proto) clients.append((stream_reader, trans)) @@ -94,45 +88,73 @@ def _test_pipe(self): with self.assertRaises(FileNotFoundError): yield from self.loop.create_pipe_connection( - protocols.Protocol, ADDRESS) + asyncio.Protocol, ADDRESS) return 'done' + def test_connect_pipe_cancel(self): + exc = OSError() + exc.winerror = _overlapped.ERROR_PIPE_BUSY + with mock.patch.object(_overlapped, 'ConnectPipe', side_effect=exc) as connect: + coro = self.loop._proactor.connect_pipe('pipe_address') + task = self.loop.create_task(coro) + + # check that it's possible to cancel connect_pipe() + task.cancel() + with self.assertRaises(asyncio.CancelledError): + self.loop.run_until_complete(task) + def test_wait_for_handle(self): event = _overlapped.CreateEvent(None, True, False, None) self.addCleanup(_winapi.CloseHandle, event) - # Wait for unset event with 0.2s timeout; + # Wait for unset event with 0.5s timeout; # result should be False at timeout - f = self.loop._proactor.wait_for_handle(event, 0.2) + fut = self.loop._proactor.wait_for_handle(event, 0.5) start = self.loop.time() - self.loop.run_until_complete(f) + done = self.loop.run_until_complete(fut) elapsed = self.loop.time() - start - self.assertFalse(f.result()) - self.assertTrue(0.18 < elapsed < 0.5, elapsed) + + self.assertEqual(done, False) + self.assertFalse(fut.result()) + self.assertTrue(0.48 < elapsed < 0.9, elapsed) _overlapped.SetEvent(event) - # Wait for for set event; + # Wait for set event; # result should be True immediately - f = self.loop._proactor.wait_for_handle(event, 10) + fut = self.loop._proactor.wait_for_handle(event, 10) start = self.loop.time() - self.loop.run_until_complete(f) + done = self.loop.run_until_complete(fut) elapsed = self.loop.time() - start - self.assertTrue(f.result()) - self.assertTrue(0 <= elapsed < 0.02, elapsed) - _overlapped.ResetEvent(event) + self.assertEqual(done, True) + self.assertTrue(fut.result()) + self.assertTrue(0 <= elapsed < 0.3, elapsed) + + # asyncio issue #195: cancelling a done _WaitHandleFuture + # must not crash + fut.cancel() + + def test_wait_for_handle_cancel(self): + event = _overlapped.CreateEvent(None, True, False, None) + self.addCleanup(_winapi.CloseHandle, event) # Wait for unset event with a cancelled future; # CancelledError should be raised immediately - f = self.loop._proactor.wait_for_handle(event, 10) - f.cancel() + fut = self.loop._proactor.wait_for_handle(event, 10) + fut.cancel() start = self.loop.time() - with self.assertRaises(futures.CancelledError): - self.loop.run_until_complete(f) + with self.assertRaises(asyncio.CancelledError): + self.loop.run_until_complete(fut) elapsed = self.loop.time() - start - self.assertTrue(0 <= elapsed < 0.02, elapsed) + self.assertTrue(0 <= elapsed < 0.1, elapsed) + + # asyncio issue #195: cancelling a _WaitHandleFuture twice + # must not crash + fut = self.loop._proactor.wait_for_handle(event) + fut.cancel() + fut.cancel() if __name__ == '__main__': diff --git a/Lib/test/test_asyncio/test_windows_utils.py b/Lib/test/test_asyncio/test_windows_utils.py index fa9d66c0217d..d48b8bcbb087 100644 --- a/Lib/test/test_asyncio/test_windows_utils.py +++ b/Lib/test/test_asyncio/test_windows_utils.py @@ -1,38 +1,73 @@ """Tests for window_utils""" +import socket import sys -import test.support import unittest -import unittest.mock +import warnings +from unittest import mock if sys.platform != 'win32': raise unittest.SkipTest('Windows only') import _winapi -from asyncio import windows_utils from asyncio import _overlapped +from asyncio import windows_utils +try: + from test import support +except ImportError: + from asyncio import test_support as support class WinsocketpairTests(unittest.TestCase): - def test_winsocketpair(self): - ssock, csock = windows_utils.socketpair() - + def check_winsocketpair(self, ssock, csock): csock.send(b'xxx') self.assertEqual(b'xxx', ssock.recv(1024)) - csock.close() ssock.close() - @unittest.mock.patch('asyncio.windows_utils.socket') + def test_winsocketpair(self): + ssock, csock = windows_utils.socketpair() + self.check_winsocketpair(ssock, csock) + + @unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 not supported or enabled') + def test_winsocketpair_ipv6(self): + ssock, csock = windows_utils.socketpair(family=socket.AF_INET6) + self.check_winsocketpair(ssock, csock) + + @unittest.skipIf(hasattr(socket, 'socketpair'), + 'socket.socketpair is available') + @mock.patch('asyncio.windows_utils.socket') def test_winsocketpair_exc(self, m_socket): + m_socket.AF_INET = socket.AF_INET + m_socket.SOCK_STREAM = socket.SOCK_STREAM m_socket.socket.return_value.getsockname.return_value = ('', 12345) m_socket.socket.return_value.accept.return_value = object(), object() m_socket.socket.return_value.connect.side_effect = OSError() self.assertRaises(OSError, windows_utils.socketpair) + def test_winsocketpair_invalid_args(self): + self.assertRaises(ValueError, + windows_utils.socketpair, family=socket.AF_UNSPEC) + self.assertRaises(ValueError, + windows_utils.socketpair, type=socket.SOCK_DGRAM) + self.assertRaises(ValueError, + windows_utils.socketpair, proto=1) + + @unittest.skipIf(hasattr(socket, 'socketpair'), + 'socket.socketpair is available') + @mock.patch('asyncio.windows_utils.socket') + def test_winsocketpair_close(self, m_socket): + m_socket.AF_INET = socket.AF_INET + m_socket.SOCK_STREAM = socket.SOCK_STREAM + sock = mock.Mock() + m_socket.socket.return_value = sock + sock.bind.side_effect = OSError + self.assertRaises(OSError, windows_utils.socketpair) + self.assertTrue(sock.close.called) + class PipeTests(unittest.TestCase): @@ -81,8 +116,10 @@ def test_pipe_handle(self): self.assertEqual(p.handle, h) # check garbage collection of p closes handle - del p - test.support.gc_collect() + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", "", ResourceWarning) + del p + support.gc_collect() try: _winapi.CloseHandle(h) except OSError as e: @@ -136,6 +173,10 @@ def test_popen(self): self.assertTrue(msg.upper().rstrip().startswith(out)) self.assertTrue(b"stderr".startswith(err)) + # The context manager calls wait() and closes resources + with p: + pass + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/tests.txt b/Lib/test/test_asyncio/tests.txt deleted file mode 100644 index 30609cd5fe24..000000000000 --- a/Lib/test/test_asyncio/tests.txt +++ /dev/null @@ -1,13 +0,0 @@ -test_asyncio.test_base_events -test_asyncio.test_events -test_asyncio.test_futures -test_asyncio.test_locks -test_asyncio.test_proactor_events -test_asyncio.test_queues -test_asyncio.test_selector_events -test_asyncio.test_streams -test_asyncio.test_tasks -test_asyncio.test_transports -test_asyncio.test_unix_events -test_asyncio.test_windows_events -test_asyncio.test_windows_utils diff --git a/Lib/test/test_asyncore.py b/Lib/test/test_asyncore.py index 084d2472952c..38579168cfd4 100644 --- a/Lib/test/test_asyncore.py +++ b/Lib/test/test_asyncore.py @@ -5,14 +5,11 @@ import socket import sys import time -import warnings import errno import struct from test import support -from test.support import TESTFN, run_unittest, unlink, HOST, HOSTv6 from io import BytesIO -from io import StringIO try: import threading @@ -67,7 +64,7 @@ def handle_error(self): # used when testing senders; just collects what it gets until newline is sent def capture_server(evt, buf, serv): try: - serv.listen(5) + serv.listen() conn, addr = serv.accept() except socket.timeout: pass @@ -94,7 +91,7 @@ def bind_af_aware(sock, addr): """Helper function to bind a socket according to its family.""" if HAS_UNIX_SOCKETS and sock.family == socket.AF_UNIX: # Make sure the path doesn't exist. - unlink(addr) + support.unlink(addr) sock.bind(addr) @@ -257,40 +254,29 @@ def test_log(self): d = asyncore.dispatcher() # capture output of dispatcher.log() (to stderr) - fp = StringIO() - stderr = sys.stderr l1 = "Lovely spam! Wonderful spam!" l2 = "I don't like spam!" - try: - sys.stderr = fp + with support.captured_stderr() as stderr: d.log(l1) d.log(l2) - finally: - sys.stderr = stderr - lines = fp.getvalue().splitlines() + lines = stderr.getvalue().splitlines() self.assertEqual(lines, ['log: %s' % l1, 'log: %s' % l2]) def test_log_info(self): d = asyncore.dispatcher() # capture output of dispatcher.log_info() (to stdout via print) - fp = StringIO() - stdout = sys.stdout l1 = "Have you got anything without spam?" l2 = "Why can't she have egg bacon spam and sausage?" l3 = "THAT'S got spam in it!" - try: - sys.stdout = fp + with support.captured_stdout() as stdout: d.log_info(l1, 'EGGS') d.log_info(l2) d.log_info(l3, 'SPAM') - finally: - sys.stdout = stdout - lines = fp.getvalue().splitlines() + lines = stdout.getvalue().splitlines() expected = ['EGGS: %s' % l1, 'info: %s' % l2, 'SPAM: %s' % l3] - self.assertEqual(lines, expected) def test_unhandled(self): @@ -298,41 +284,19 @@ def test_unhandled(self): d.ignore_log_types = () # capture output of dispatcher.log_info() (to stdout via print) - fp = StringIO() - stdout = sys.stdout - try: - sys.stdout = fp + with support.captured_stdout() as stdout: d.handle_expt() d.handle_read() d.handle_write() d.handle_connect() - finally: - sys.stdout = stdout - lines = fp.getvalue().splitlines() + lines = stdout.getvalue().splitlines() expected = ['warning: unhandled incoming priority event', 'warning: unhandled read event', 'warning: unhandled write event', 'warning: unhandled connect event'] self.assertEqual(lines, expected) - def test_issue_8594(self): - # XXX - this test is supposed to be removed in next major Python - # version - d = asyncore.dispatcher(socket.socket()) - # make sure the error message no longer refers to the socket - # object but the dispatcher instance instead - self.assertRaisesRegex(AttributeError, 'dispatcher instance', - getattr, d, 'foo') - # cheap inheritance with the underlying socket is supposed - # to still work but a DeprecationWarning is expected - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always") - family = d.family - self.assertEqual(family, socket.AF_INET) - self.assertEqual(len(w), 1) - self.assertTrue(issubclass(w[0].category, DeprecationWarning)) - def test_strerror(self): # refers to bug #8573 err = asyncore._strerror(errno.EPERM) @@ -349,9 +313,8 @@ def readable(self): def handle_connect(self): pass -class DispatcherWithSendTests(unittest.TestCase): - usepoll = False +class DispatcherWithSendTests(unittest.TestCase): def setUp(self): pass @@ -378,7 +341,7 @@ def test_send(self): data = b"Suppose there isn't a 16-ton weight?" d = dispatcherwithsend_noread() d.create_socket() - d.connect((HOST, port)) + d.connect((support.HOST, port)) # give time for socket to connect time.sleep(0.1) @@ -401,23 +364,19 @@ def test_send(self): self.fail("join() timed out") - -class DispatcherWithSendTests_UsePoll(DispatcherWithSendTests): - usepoll = True - @unittest.skipUnless(hasattr(asyncore, 'file_wrapper'), 'asyncore.file_wrapper required') class FileWrapperTest(unittest.TestCase): def setUp(self): self.d = b"It's not dead, it's sleeping!" - with open(TESTFN, 'wb') as file: + with open(support.TESTFN, 'wb') as file: file.write(self.d) def tearDown(self): - unlink(TESTFN) + support.unlink(support.TESTFN) def test_recv(self): - fd = os.open(TESTFN, os.O_RDONLY) + fd = os.open(support.TESTFN, os.O_RDONLY) w = asyncore.file_wrapper(fd) os.close(fd) @@ -431,20 +390,20 @@ def test_recv(self): def test_send(self): d1 = b"Come again?" d2 = b"I want to buy some cheese." - fd = os.open(TESTFN, os.O_WRONLY | os.O_APPEND) + fd = os.open(support.TESTFN, os.O_WRONLY | os.O_APPEND) w = asyncore.file_wrapper(fd) os.close(fd) w.write(d1) w.send(d2) w.close() - with open(TESTFN, 'rb') as file: + with open(support.TESTFN, 'rb') as file: self.assertEqual(file.read(), self.d + d1 + d2) @unittest.skipUnless(hasattr(asyncore, 'file_dispatcher'), 'asyncore.file_dispatcher required') def test_dispatcher(self): - fd = os.open(TESTFN, os.O_RDONLY) + fd = os.open(support.TESTFN, os.O_RDONLY) data = [] class FileDispatcher(asyncore.file_dispatcher): def handle_read(self): @@ -454,6 +413,26 @@ def handle_read(self): asyncore.loop(timeout=0.01, use_poll=True, count=2) self.assertEqual(b"".join(data), self.d) + def test_resource_warning(self): + # Issue #11453 + fd = os.open(support.TESTFN, os.O_RDONLY) + f = asyncore.file_wrapper(fd) + + os.close(fd) + with support.check_warnings(('', ResourceWarning)): + f = None + support.gc_collect() + + def test_close_twice(self): + fd = os.open(support.TESTFN, os.O_RDONLY) + f = asyncore.file_wrapper(fd) + os.close(fd) + + f.close() + self.assertEqual(f.fd, -1) + # calling close twice should not fail + f.close() + class BaseTestHandler(asyncore.dispatcher): @@ -815,12 +794,12 @@ def cleanup(): class TestAPI_UseIPv4Sockets(BaseTestAPI): family = socket.AF_INET - addr = (HOST, 0) + addr = (support.HOST, 0) @unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 support required') class TestAPI_UseIPv6Sockets(BaseTestAPI): family = socket.AF_INET6 - addr = (HOSTv6, 0) + addr = (support.HOSTv6, 0) @unittest.skipUnless(HAS_UNIX_SOCKETS, 'Unix sockets required') class TestAPI_UseUnixSockets(BaseTestAPI): @@ -829,7 +808,7 @@ class TestAPI_UseUnixSockets(BaseTestAPI): addr = support.TESTFN def tearDown(self): - unlink(self.addr) + support.unlink(self.addr) BaseTestAPI.tearDown(self) class TestAPI_UseIPv4Select(TestAPI_UseIPv4Sockets, unittest.TestCase): diff --git a/Lib/test/test_atexit.py b/Lib/test/test_atexit.py index 84644f17a887..172bd25419ce 100644 --- a/Lib/test/test_atexit.py +++ b/Lib/test/test_atexit.py @@ -2,7 +2,6 @@ import unittest import io import atexit -import _testcapi from test import support ### helpers @@ -178,9 +177,5 @@ def f(): self.assertEqual(atexit._ncallbacks(), n) -def test_main(): - support.run_unittest(__name__) - - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_audioop.py b/Lib/test/test_audioop.py index d5075450e637..8f34d72427e1 100644 --- a/Lib/test/test_audioop.py +++ b/Lib/test/test_audioop.py @@ -269,6 +269,21 @@ def test_lin2adpcm(self): self.assertEqual(audioop.lin2adpcm(b'\0' * w * 10, w, None), (b'\0' * 5, (0, 0))) + def test_invalid_adpcm_state(self): + # state must be a tuple or None, not an integer + self.assertRaises(TypeError, audioop.adpcm2lin, b'\0', 1, 555) + self.assertRaises(TypeError, audioop.lin2adpcm, b'\0', 1, 555) + # Issues #24456, #24457: index out of range + self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0, -1)) + self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0, 89)) + self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0, -1)) + self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0, 89)) + # value out of range + self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (-0x8001, 0)) + self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0x8000, 0)) + self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (-0x8001, 0)) + self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0x8000, 0)) + def test_lin2alaw(self): self.assertEqual(audioop.lin2alaw(datas[1], 1), b'\xd5\x87\xa4\x24\xaa\x2a\x5a') @@ -358,6 +373,9 @@ def test_ratecv(self): (b'', (-2, ((0, 0),)))) self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None)[0], datas[w]) + self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None, 1, 0)[0], + datas[w]) + state = None d1, state = audioop.ratecv(b'\x00\x01\x02', 1, 1, 8000, 16000, state) d2, state = audioop.ratecv(b'\x00\x01\x02', 1, 1, 8000, 16000, state) @@ -373,6 +391,20 @@ def test_ratecv(self): self.assertEqual(d, d0) self.assertEqual(state, state0) + expected = { + 1: packs[1](0, 0x0d, 0x37, -0x26, 0x55, -0x4b, -0x14), + 2: packs[2](0, 0x0da7, 0x3777, -0x2630, 0x5673, -0x4a64, -0x129a), + 3: packs[3](0, 0x0da740, 0x377776, -0x262fca, + 0x56740c, -0x4a62fd, -0x1298c0), + 4: packs[4](0, 0x0da740da, 0x37777776, -0x262fc962, + 0x56740da6, -0x4a62fc96, -0x1298bf26), + } + for w in 1, 2, 3, 4: + self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None, 3, 1)[0], + expected[w]) + self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None, 30, 10)[0], + expected[w]) + def test_reverse(self): for w in 1, 2, 3, 4: self.assertEqual(audioop.reverse(b'', w), b'') diff --git a/Lib/test/test_augassign.py b/Lib/test/test_augassign.py index 9a59c58ec066..5093e9d0f364 100644 --- a/Lib/test/test_augassign.py +++ b/Lib/test/test_augassign.py @@ -1,6 +1,5 @@ # Augmented assignment test. -from test.support import run_unittest import unittest @@ -136,12 +135,12 @@ def __imul__(self, val): output.append("__imul__ called") return self - def __div__(self, val): - output.append("__div__ called") - def __rdiv__(self, val): - output.append("__rdiv__ called") - def __idiv__(self, val): - output.append("__idiv__ called") + def __matmul__(self, val): + output.append("__matmul__ called") + def __rmatmul__(self, val): + output.append("__rmatmul__ called") + def __imatmul__(self, val): + output.append("__imatmul__ called") return self def __floordiv__(self, val): @@ -233,6 +232,10 @@ def __ilshift__(self, val): 1 * x x *= 1 + x @ 1 + 1 @ x + x @= 1 + x / 1 1 / x x /= 1 @@ -279,6 +282,9 @@ def __ilshift__(self, val): __mul__ called __rmul__ called __imul__ called +__matmul__ called +__rmatmul__ called +__imatmul__ called __truediv__ called __rtruediv__ called __itruediv__ called @@ -308,8 +314,5 @@ def __ilshift__(self, val): __ilshift__ called '''.splitlines()) -def test_main(): - run_unittest(AugAssignTest) - if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test_base64.py b/Lib/test/test_base64.py index b9738ddaf5ba..a0f548d295fa 100644 --- a/Lib/test/test_base64.py +++ b/Lib/test/test_base64.py @@ -3,10 +3,8 @@ import base64 import binascii import os -import sys -import subprocess -import struct from array import array +from test.support import script_helper class LegacyBase64TestCase(unittest.TestCase): @@ -622,15 +620,13 @@ def test_ErrorHeritage(self): self.assertTrue(issubclass(binascii.Error, ValueError)) - class TestMain(unittest.TestCase): def tearDown(self): if os.path.exists(support.TESTFN): os.unlink(support.TESTFN) - def get_output(self, *args, **options): - args = (sys.executable, '-m', 'base64') + args - return subprocess.check_output(args, **options) + def get_output(self, *args): + return script_helper.assert_python_ok('-m', 'base64', *args).out def test_encode_decode(self): output = self.get_output('-t') @@ -643,13 +639,14 @@ def test_encode_decode(self): def test_encode_file(self): with open(support.TESTFN, 'wb') as fp: fp.write(b'a\xffb\n') - output = self.get_output('-e', support.TESTFN) self.assertEqual(output.rstrip(), b'Yf9iCg==') - with open(support.TESTFN, 'rb') as fp: - output = self.get_output('-e', stdin=fp) - self.assertEqual(output.rstrip(), b'Yf9iCg==') + def test_encode_from_stdin(self): + with script_helper.spawn_python('-m', 'base64', '-e') as proc: + out, err = proc.communicate(b'a\xffb\n') + self.assertEqual(out.rstrip(), b'Yf9iCg==') + self.assertIsNone(err) def test_decode(self): with open(support.TESTFN, 'wb') as fp: @@ -657,10 +654,5 @@ def test_decode(self): output = self.get_output('-d', support.TESTFN) self.assertEqual(output.rstrip(), b'a\xffb') - - -def test_main(): - support.run_unittest(__name__) - if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index 04d8f9d68048..fbc933e4e677 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -1,6 +1,5 @@ """Test the binascii C module.""" -from test import support import unittest import binascii import array @@ -136,6 +135,18 @@ def test_uu(self): # Issue #7701 (crash on a pydebug build) self.assertEqual(binascii.b2a_uu(b'x'), b'!> \n') + def test_crc_hqx(self): + crc = binascii.crc_hqx(self.type2test(b"Test the CRC-32 of"), 0) + crc = binascii.crc_hqx(self.type2test(b" this string."), crc) + self.assertEqual(crc, 14290) + + self.assertRaises(TypeError, binascii.crc_hqx) + self.assertRaises(TypeError, binascii.crc_hqx, self.type2test(b'')) + + for crc in 0, 1, 0x1234, 0x12345, 0x12345678, -1: + self.assertEqual(binascii.crc_hqx(self.type2test(b''), crc), + crc & 0xffff) + def test_crc32(self): crc = binascii.crc32(self.type2test(b"Test the CRC-32 of")) crc = binascii.crc32(self.type2test(b" this string."), crc) @@ -148,11 +159,25 @@ def test_hqx(self): # Then calculate the hexbin4 binary-to-ASCII translation rle = binascii.rlecode_hqx(self.data) a = binascii.b2a_hqx(self.type2test(rle)) + b, _ = binascii.a2b_hqx(self.type2test(a)) res = binascii.rledecode_hqx(b) - self.assertEqual(res, self.rawdata) + def test_rle(self): + # test repetition with a repetition longer than the limit of 255 + data = (b'a' * 100 + b'b' + b'c' * 300) + + encoded = binascii.rlecode_hqx(data) + self.assertEqual(encoded, + (b'a\x90d' # 'a' * 100 + b'b' # 'b' + b'c\x90\xff' # 'c' * 255 + b'c\x90-')) # 'c' * 45 + + decoded = binascii.rledecode_hqx(encoded) + self.assertEqual(decoded, data) + def test_hex(self): # test hexlification s = b'{s\005\000\000\000worldi\002\000\000\000s\005\000\000\000helloi\001\000\000\0000' @@ -162,9 +187,13 @@ def test_hex(self): self.assertRaises(binascii.Error, binascii.a2b_hex, t[:-1]) self.assertRaises(binascii.Error, binascii.a2b_hex, t[:-1] + b'q') - self.assertEqual(binascii.hexlify(b'a'), b'61') + # Confirm that b2a_hex == hexlify and a2b_hex == unhexlify + self.assertEqual(binascii.hexlify(self.type2test(s)), t) + self.assertEqual(binascii.unhexlify(self.type2test(t)), u) def test_qp(self): + binascii.a2b_qp(data=b"", header=False) # Keyword arguments allowed + # A test for SF bug 534347 (segfaults without the proper fix) try: binascii.a2b_qp(b"", **{1:1}) @@ -172,6 +201,7 @@ def test_qp(self): pass else: self.fail("binascii.a2b_qp(**{1:1}) didn't raise TypeError") + self.assertEqual(binascii.a2b_qp(b"= "), b"= ") self.assertEqual(binascii.a2b_qp(b"=="), b"=") self.assertEqual(binascii.a2b_qp(b"=AX"), b"=AX") @@ -246,6 +276,16 @@ def test_unicode_a2b(self): # non-ASCII string self.assertRaises(ValueError, a2b, "\x80") + def test_b2a_base64_newline(self): + # Issue #25357: test newline parameter + b = self.type2test(b'hello') + self.assertEqual(binascii.b2a_base64(b), + b'aGVsbG8=\n') + self.assertEqual(binascii.b2a_base64(b, newline=True), + b'aGVsbG8=\n') + self.assertEqual(binascii.b2a_base64(b, newline=False), + b'aGVsbG8=') + class ArrayBinASCIITest(BinASCIITest): def type2test(self, s): @@ -260,11 +300,5 @@ class MemoryviewBinASCIITest(BinASCIITest): type2test = memoryview -def test_main(): - support.run_unittest(BinASCIITest, - ArrayBinASCIITest, - BytearrayBinASCIITest, - MemoryviewBinASCIITest) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_binhex.py b/Lib/test/test_binhex.py old mode 100755 new mode 100644 index a807bca6393d..9d4c85afaa6d --- a/Lib/test/test_binhex.py +++ b/Lib/test/test_binhex.py @@ -1,4 +1,3 @@ -#! /usr/bin/env python3 """Test script for the binhex C module Uses the mechanism of the python binhex module diff --git a/Lib/test/test_binop.py b/Lib/test/test_binop.py index 84179167e218..823740c4449f 100644 --- a/Lib/test/test_binop.py +++ b/Lib/test/test_binop.py @@ -3,6 +3,7 @@ import unittest from test import support from operator import eq, ne, lt, gt, le, ge +from abc import ABCMeta def gcd(a, b): """Greatest common divisor using Euclid's algorithm.""" @@ -194,10 +195,6 @@ def __eq__(self, other): return float(self) == other return NotImplemented - def __ne__(self, other): - """Compare two Rats for inequality.""" - return not self == other - class RatTestCase(unittest.TestCase): """Unit tests for Rat class and its support utilities.""" @@ -336,7 +333,7 @@ def __ge__(self, other): self.log_operation('A.__ge__') return NotImplemented -class B(OperationLogger): +class B(OperationLogger, metaclass=ABCMeta): def __eq__(self, other): self.log_operation('B.__eq__') return NotImplemented @@ -358,6 +355,20 @@ def __ge__(self, other): self.log_operation('C.__ge__') return NotImplemented +class V(OperationLogger): + """Virtual subclass of B""" + def __eq__(self, other): + self.log_operation('V.__eq__') + return NotImplemented + def __le__(self, other): + self.log_operation('V.__le__') + return NotImplemented + def __ge__(self, other): + self.log_operation('V.__ge__') + return NotImplemented +B.register(V) + + class OperationOrderTests(unittest.TestCase): def test_comparison_orders(self): self.assertEqual(op_sequence(eq, A, A), ['A.__eq__', 'A.__eq__']) @@ -373,8 +384,10 @@ def test_comparison_orders(self): self.assertEqual(op_sequence(le, B, C), ['C.__ge__', 'B.__le__']) self.assertEqual(op_sequence(le, C, B), ['C.__le__', 'B.__ge__']) -def test_main(): - support.run_unittest(RatTestCase, OperationOrderTests) + self.assertTrue(issubclass(V, B)) + self.assertEqual(op_sequence(eq, B, V), ['B.__eq__', 'V.__eq__']) + self.assertEqual(op_sequence(le, B, V), ['B.__le__', 'V.__ge__']) + if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_bool.py b/Lib/test/test_bool.py index 4bab28be7750..250743949bf5 100644 --- a/Lib/test/test_bool.py +++ b/Lib/test/test_bool.py @@ -269,10 +269,9 @@ def test_marshal(self): def test_pickle(self): import pickle - self.assertIs(pickle.loads(pickle.dumps(True)), True) - self.assertIs(pickle.loads(pickle.dumps(False)), False) - self.assertIs(pickle.loads(pickle.dumps(True, True)), True) - self.assertIs(pickle.loads(pickle.dumps(False, True)), False) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.assertIs(pickle.loads(pickle.dumps(True, proto)), True) + self.assertIs(pickle.loads(pickle.dumps(False, proto)), False) def test_picklevalues(self): # Test for specific backwards-compatible pickle values diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py index 1667847a9df1..a65339041539 100644 --- a/Lib/test/test_buffer.py +++ b/Lib/test/test_buffer.py @@ -11,6 +11,7 @@ # memoryview tests is now in this module. # +import contextlib import unittest from test import support from itertools import permutations, product @@ -149,15 +150,15 @@ def randrange_fmt(mode, char, obj): format character.""" x = randrange(*fmtdict[mode][char]) if char == 'c': - x = bytes(chr(x), 'latin1') + x = bytes([x]) + if obj == 'numpy' and x == b'\x00': + # http://projects.scipy.org/numpy/ticket/1925 + x = b'\x01' if char == '?': x = bool(x) if char == 'f' or char == 'd': x = struct.pack(char, x) x = struct.unpack(char, x)[0] - if obj == 'numpy' and x == b'\x00': - # http://projects.scipy.org/numpy/ticket/1925 - x = b'\x01' return x def gen_item(fmt, obj): @@ -216,7 +217,7 @@ def iter_format(nitems, testobj='ndarray'): for t in iter_mode(nitems, testobj): yield t if testobj != 'ndarray': - raise StopIteration + return yield struct_items(nitems, testobj) @@ -1007,6 +1008,7 @@ def test_ndarray_getbuf(self): # shape, strides, offset structure = ( ([], [], 0), + ([1,3,1], [], 0), ([12], [], 0), ([12], [-1], 11), ([6], [2], 0), @@ -1078,6 +1080,18 @@ def test_ndarray_getbuf(self): self.assertRaises(BufferError, ndarray, ex, getbuf=PyBUF_ANY_CONTIGUOUS) nd = ndarray(ex, getbuf=PyBUF_SIMPLE) + # Issue #22445: New precise contiguity definition. + for shape in [1,12,1], [7,0,7]: + for order in 0, ND_FORTRAN: + ex = ndarray(items, shape=shape, flags=order|ND_WRITABLE) + self.assertTrue(is_contiguous(ex, 'F')) + self.assertTrue(is_contiguous(ex, 'C')) + + for flags in requests: + nd = ndarray(ex, getbuf=flags) + self.assertTrue(is_contiguous(nd, 'F')) + self.assertTrue(is_contiguous(nd, 'C')) + def test_ndarray_exceptions(self): nd = ndarray([9], [1]) ndm = ndarray([9], [1], flags=ND_VAREXPORT) @@ -2449,6 +2463,21 @@ def test_memoryview_cast_zero_shape(self): self.assertEqual(m.tobytes(), b'') self.assertEqual(m.tolist(), []) + check_sizeof = support.check_sizeof + + def test_memoryview_sizeof(self): + check = self.check_sizeof + vsize = support.calcvobjsize + base_struct = 'Pnin 2P2n2i5P P' + per_dim = '3n' + + items = list(range(8)) + check(memoryview(b''), vsize(base_struct + 1 * per_dim)) + a = ndarray(items, shape=[2, 4], format="b") + check(memoryview(a), vsize(base_struct + 2 * per_dim)) + a = ndarray(items, shape=[2, 2, 2], format="b") + check(memoryview(a), vsize(base_struct + 3 * per_dim)) + def test_memoryview_struct_module(self): class INT(object): @@ -2530,8 +2559,7 @@ def test_memoryview_cast_invalid(self): ex = ndarray(sitems, shape=[1], format=sfmt) msrc = memoryview(ex) for dfmt, _, _ in iter_format(1): - if (not is_memoryview_format(sfmt) or - not is_memoryview_format(dfmt)): + if not is_memoryview_format(dfmt): self.assertRaises(ValueError, msrc.cast, dfmt, [32//dsize]) else: @@ -2744,6 +2772,32 @@ def test_memoryview_cast_1D_ND(self): ndim=ndim, shape=shape, strides=strides, lst=lst, cast=True) + if ctypes: + # format: "T{>l:x:>d:y:}" + class BEPoint(ctypes.BigEndianStructure): + _fields_ = [("x", ctypes.c_long), ("y", ctypes.c_double)] + point = BEPoint(100, 200.1) + m1 = memoryview(point) + m2 = m1.cast('B') + self.assertEqual(m2.obj, point) + self.assertEqual(m2.itemsize, 1) + self.assertEqual(m2.readonly, 0) + self.assertEqual(m2.ndim, 1) + self.assertEqual(m2.shape, (m2.nbytes,)) + self.assertEqual(m2.strides, (1,)) + self.assertEqual(m2.suboffsets, ()) + + x = ctypes.c_double(1.2) + m1 = memoryview(x) + m2 = m1.cast('c') + self.assertEqual(m2.obj, x) + self.assertEqual(m2.itemsize, 1) + self.assertEqual(m2.readonly, 0) + self.assertEqual(m2.ndim, 1) + self.assertEqual(m2.shape, (m2.nbytes,)) + self.assertEqual(m2.strides, (1,)) + self.assertEqual(m2.suboffsets, ()) + def test_memoryview_tolist(self): # Most tolist() tests are in self.verify() etc. @@ -2797,6 +2851,13 @@ def test_memoryview_sequence(self): m = memoryview(ex) self.assertRaises(TypeError, eval, "9.0 in m", locals()) + @contextlib.contextmanager + def assert_out_of_bounds_error(self, dim): + with self.assertRaises(IndexError) as cm: + yield + self.assertEqual(str(cm.exception), + "index out of bounds on dimension %d" % (dim,)) + def test_memoryview_index(self): # ndim = 0 @@ -2823,12 +2884,31 @@ def test_memoryview_index(self): self.assertRaises(IndexError, m.__getitem__, -8) self.assertRaises(IndexError, m.__getitem__, 8) - # Not implemented: multidimensional sub-views + # multi-dimensional ex = ndarray(list(range(12)), shape=[3,4], flags=ND_WRITABLE) m = memoryview(ex) - self.assertRaises(NotImplementedError, m.__getitem__, 0) - self.assertRaises(NotImplementedError, m.__setitem__, 0, 9) + self.assertEqual(m[0, 0], 0) + self.assertEqual(m[2, 0], 8) + self.assertEqual(m[2, 3], 11) + self.assertEqual(m[-1, -1], 11) + self.assertEqual(m[-3, -4], 0) + + # out of bounds + for index in (3, -4): + with self.assert_out_of_bounds_error(dim=1): + m[index, 0] + for index in (4, -5): + with self.assert_out_of_bounds_error(dim=2): + m[0, index] + self.assertRaises(IndexError, m.__getitem__, (2**64, 0)) + self.assertRaises(IndexError, m.__getitem__, (0, 2**64)) + + self.assertRaises(TypeError, m.__getitem__, (0, 0, 0)) + self.assertRaises(TypeError, m.__getitem__, (0.0, 0.0)) + + # Not implemented: multidimensional sub-views + self.assertRaises(NotImplementedError, m.__getitem__, ()) self.assertRaises(NotImplementedError, m.__getitem__, 0) def test_memoryview_assign(self): @@ -2917,10 +2997,27 @@ def test_memoryview_assign(self): m = memoryview(ex) self.assertRaises(NotImplementedError, m.__setitem__, 0, 1) - # Not implemented: multidimensional sub-views + # multi-dimensional ex = ndarray(list(range(12)), shape=[3,4], flags=ND_WRITABLE) m = memoryview(ex) + m[0,1] = 42 + self.assertEqual(ex[0][1], 42) + m[-1,-1] = 43 + self.assertEqual(ex[2][3], 43) + # errors + for index in (3, -4): + with self.assert_out_of_bounds_error(dim=1): + m[index, 0] = 0 + for index in (4, -5): + with self.assert_out_of_bounds_error(dim=2): + m[0, index] = 0 + self.assertRaises(IndexError, m.__setitem__, (2**64, 0), 0) + self.assertRaises(IndexError, m.__setitem__, (0, 2**64), 0) + + self.assertRaises(TypeError, m.__setitem__, (0, 0, 0), 0) + self.assertRaises(TypeError, m.__setitem__, (0.0, 0.0), 0) + # Not implemented: multidimensional sub-views self.assertRaises(NotImplementedError, m.__setitem__, 0, [2, 3]) def test_memoryview_slice(self): @@ -2933,8 +3030,8 @@ def test_memoryview_slice(self): self.assertRaises(ValueError, m.__setitem__, slice(0,2,0), bytearray([1,2])) - # invalid slice key - self.assertRaises(TypeError, m.__getitem__, ()) + # 0-dim slicing (identity function) + self.assertRaises(NotImplementedError, m.__getitem__, ()) # multidimensional slices ex = ndarray(list(range(12)), shape=[12], flags=ND_WRITABLE) diff --git a/Lib/test/test_bufio.py b/Lib/test/test_bufio.py index 6338ad8e3c44..9931c84680c7 100644 --- a/Lib/test/test_bufio.py +++ b/Lib/test/test_bufio.py @@ -34,7 +34,7 @@ def try_one(self, s): line = f.readline() self.assertEqual(line, s) line = f.readline() - self.assertTrue(not line) # Must be at EOF + self.assertFalse(line) # Must be at EOF f.close() finally: support.unlink(support.TESTFN) diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 68430660f016..5deeb72b449c 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -16,6 +16,7 @@ import warnings from operator import neg from test.support import TESTFN, unlink, run_unittest, check_warnings +from test.support.script_helper import assert_python_ok try: import pty, signal except ImportError: @@ -120,9 +121,9 @@ def map_char(arg): class BuiltinTest(unittest.TestCase): # Helper to check picklability - def check_iter_pickle(self, it, seq): + def check_iter_pickle(self, it, seq, proto): itorg = it - d = pickle.dumps(it) + d = pickle.dumps(it, proto) it = pickle.loads(d) self.assertEqual(type(itorg), type(it)) self.assertEqual(list(it), seq) @@ -133,7 +134,7 @@ def check_iter_pickle(self, it, seq): next(it) except StopIteration: return - d = pickle.dumps(it) + d = pickle.dumps(it, proto) it = pickle.loads(d) self.assertEqual(list(it), seq[1:]) @@ -311,11 +312,11 @@ def test_compile(self): self.assertRaises(TypeError, compile) self.assertRaises(ValueError, compile, 'print(42)\n', '', 'badmode') self.assertRaises(ValueError, compile, 'print(42)\n', '', 'single', 0xff) - self.assertRaises(TypeError, compile, chr(0), 'f', 'exec') + self.assertRaises(ValueError, compile, chr(0), 'f', 'exec') self.assertRaises(TypeError, compile, 'pass', '?', 'exec', mode='eval', source='0', filename='tmp') compile('print("\xe5")\n', '', 'exec') - self.assertRaises(TypeError, compile, chr(0), 'f', 'exec') + self.assertRaises(ValueError, compile, chr(0), 'f', 'exec') self.assertRaises(ValueError, compile, str('a = 1'), 'f', 'bad') # test the optimize argument @@ -635,9 +636,10 @@ def badfunc(): self.assertRaises(TypeError, list, filter(42, (1, 2))) def test_filter_pickle(self): - f1 = filter(filter_char, "abcdeabcde") - f2 = filter(filter_char, "abcdeabcde") - self.check_iter_pickle(f1, list(f2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + f1 = filter(filter_char, "abcdeabcde") + f2 = filter(filter_char, "abcdeabcde") + self.check_iter_pickle(f1, list(f2), proto) def test_getattr(self): self.assertTrue(getattr(sys, 'stdout') is sys.stdout) @@ -833,9 +835,10 @@ def badfunc(x): self.assertRaises(RuntimeError, list, map(badfunc, range(5))) def test_map_pickle(self): - m1 = map(map_char, "Is this the real life?") - m2 = map(map_char, "Is this the real life?") - self.check_iter_pickle(m1, list(m2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + m1 = map(map_char, "Is this the real life?") + m2 = map(map_char, "Is this the real life?") + self.check_iter_pickle(m1, list(m2), proto) def test_max(self): self.assertEqual(max('123123'), '3') @@ -1091,7 +1094,7 @@ def test_pow(self): self.assertAlmostEqual(pow(-1, 0.5), 1j) self.assertAlmostEqual(pow(-1, 1/3), 0.5 + 0.8660254037844386j) - self.assertRaises(TypeError, pow, -1, -2, 3) + self.assertRaises(ValueError, pow, -1, -2, 3) self.assertRaises(ValueError, pow, 1, 2, 0) self.assertRaises(TypeError, pow) @@ -1131,82 +1134,6 @@ def test_input(self): sys.stdout = savestdout fp.close() - @unittest.skipUnless(pty, "the pty and signal modules must be available") - def check_input_tty(self, prompt, terminal_input, stdio_encoding=None): - if not sys.stdin.isatty() or not sys.stdout.isatty(): - self.skipTest("stdin and stdout must be ttys") - r, w = os.pipe() - try: - pid, fd = pty.fork() - except (OSError, AttributeError) as e: - os.close(r) - os.close(w) - self.skipTest("pty.fork() raised {}".format(e)) - if pid == 0: - # Child - try: - # Make sure we don't get stuck if there's a problem - signal.alarm(2) - os.close(r) - # Check the error handlers are accounted for - if stdio_encoding: - sys.stdin = io.TextIOWrapper(sys.stdin.detach(), - encoding=stdio_encoding, - errors='surrogateescape') - sys.stdout = io.TextIOWrapper(sys.stdout.detach(), - encoding=stdio_encoding, - errors='replace') - with open(w, "w") as wpipe: - print("tty =", sys.stdin.isatty() and sys.stdout.isatty(), file=wpipe) - print(ascii(input(prompt)), file=wpipe) - except: - traceback.print_exc() - finally: - # We don't want to return to unittest... - os._exit(0) - # Parent - os.close(w) - os.write(fd, terminal_input + b"\r\n") - # Get results from the pipe - with open(r, "r") as rpipe: - lines = [] - while True: - line = rpipe.readline().strip() - if line == "": - # The other end was closed => the child exited - break - lines.append(line) - # Check the result was got and corresponds to the user's terminal input - if len(lines) != 2: - # Something went wrong, try to get at stderr - with open(fd, "r", encoding="ascii", errors="ignore") as child_output: - self.fail("got %d lines in pipe but expected 2, child output was:\n%s" - % (len(lines), child_output.read())) - os.close(fd) - # Check we did exercise the GNU readline path - self.assertIn(lines[0], {'tty = True', 'tty = False'}) - if lines[0] != 'tty = True': - self.skipTest("standard IO in should have been a tty") - input_result = eval(lines[1]) # ascii() -> eval() roundtrip - if stdio_encoding: - expected = terminal_input.decode(stdio_encoding, 'surrogateescape') - else: - expected = terminal_input.decode(sys.stdin.encoding) # what else? - self.assertEqual(input_result, expected) - - def test_input_tty(self): - # Test input() functionality when wired to a tty (the code path - # is different and invokes GNU readline if available). - self.check_input_tty("prompt", b"quux") - - def test_input_tty_non_ascii(self): - # Check stdin/stdout encoding is used when invoking GNU readline - self.check_input_tty("prompté", b"quux\xe9", "utf-8") - - def test_input_tty_non_ascii_unicode_errors(self): - # Check stdin/stdout error handler is used when invoking GNU readline - self.check_input_tty("prompté", b"quux\xe9", "ascii") - # test_int(): see test_int.py for tests of built-in function int(). def test_repr(self): @@ -1432,8 +1359,9 @@ def test_zip_pickle(self): a = (1, 2, 3) b = (4, 5, 6) t = [(1, 4), (2, 5), (3, 6)] - z1 = zip(a, b) - self.check_iter_pickle(z1, t) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + z1 = zip(a, b) + self.check_iter_pickle(z1, t, proto) def test_format(self): # Test the basic machinery of the format() builtin. Don't test @@ -1560,6 +1488,119 @@ def test_construct_singletons(self): self.assertRaises(TypeError, tp, 1, 2) self.assertRaises(TypeError, tp, a=1, b=2) +@unittest.skipUnless(pty, "the pty and signal modules must be available") +class PtyTests(unittest.TestCase): + """Tests that use a pseudo terminal to guarantee stdin and stdout are + terminals in the test environment""" + + def run_child(self, child, terminal_input): + r, w = os.pipe() # Pipe test results from child back to parent + try: + pid, fd = pty.fork() + except (OSError, AttributeError) as e: + os.close(r) + os.close(w) + self.skipTest("pty.fork() raised {}".format(e)) + raise + if pid == 0: + # Child + try: + # Make sure we don't get stuck if there's a problem + signal.alarm(2) + os.close(r) + with open(w, "w") as wpipe: + child(wpipe) + except: + traceback.print_exc() + finally: + # We don't want to return to unittest... + os._exit(0) + # Parent + os.close(w) + os.write(fd, terminal_input) + # Get results from the pipe + with open(r, "r") as rpipe: + lines = [] + while True: + line = rpipe.readline().strip() + if line == "": + # The other end was closed => the child exited + break + lines.append(line) + # Check the result was got and corresponds to the user's terminal input + if len(lines) != 2: + # Something went wrong, try to get at stderr + # Beware of Linux raising EIO when the slave is closed + child_output = bytearray() + while True: + try: + chunk = os.read(fd, 3000) + except OSError: # Assume EIO + break + if not chunk: + break + child_output.extend(chunk) + os.close(fd) + child_output = child_output.decode("ascii", "ignore") + self.fail("got %d lines in pipe but expected 2, child output was:\n%s" + % (len(lines), child_output)) + os.close(fd) + return lines + + def check_input_tty(self, prompt, terminal_input, stdio_encoding=None): + if not sys.stdin.isatty() or not sys.stdout.isatty(): + self.skipTest("stdin and stdout must be ttys") + def child(wpipe): + # Check the error handlers are accounted for + if stdio_encoding: + sys.stdin = io.TextIOWrapper(sys.stdin.detach(), + encoding=stdio_encoding, + errors='surrogateescape') + sys.stdout = io.TextIOWrapper(sys.stdout.detach(), + encoding=stdio_encoding, + errors='replace') + print("tty =", sys.stdin.isatty() and sys.stdout.isatty(), file=wpipe) + print(ascii(input(prompt)), file=wpipe) + lines = self.run_child(child, terminal_input + b"\r\n") + # Check we did exercise the GNU readline path + self.assertIn(lines[0], {'tty = True', 'tty = False'}) + if lines[0] != 'tty = True': + self.skipTest("standard IO in should have been a tty") + input_result = eval(lines[1]) # ascii() -> eval() roundtrip + if stdio_encoding: + expected = terminal_input.decode(stdio_encoding, 'surrogateescape') + else: + expected = terminal_input.decode(sys.stdin.encoding) # what else? + self.assertEqual(input_result, expected) + + def test_input_tty(self): + # Test input() functionality when wired to a tty (the code path + # is different and invokes GNU readline if available). + self.check_input_tty("prompt", b"quux") + + def test_input_tty_non_ascii(self): + # Check stdin/stdout encoding is used when invoking GNU readline + self.check_input_tty("prompté", b"quux\xe9", "utf-8") + + def test_input_tty_non_ascii_unicode_errors(self): + # Check stdin/stdout error handler is used when invoking GNU readline + self.check_input_tty("prompté", b"quux\xe9", "ascii") + + def test_input_no_stdout_fileno(self): + # Issue #24402: If stdin is the original terminal but stdout.fileno() + # fails, do not use the original stdout file descriptor + def child(wpipe): + print("stdin.isatty():", sys.stdin.isatty(), file=wpipe) + sys.stdout = io.StringIO() # Does not support fileno() + input("prompt") + print("captured:", ascii(sys.stdout.getvalue()), file=wpipe) + lines = self.run_child(child, b"quux\r") + expected = ( + "stdin.isatty(): True", + "captured: 'prompt'", + ) + self.assertSequenceEqual(lines, expected) + class TestSorted(unittest.TestCase): def test_basic(self): @@ -1592,6 +1633,41 @@ def test_baddecorator(self): data = 'The quick Brown fox Jumped over The lazy Dog'.split() self.assertRaises(TypeError, sorted, data, None, lambda x,y: 0) + +class ShutdownTest(unittest.TestCase): + + def test_cleanup(self): + # Issue #19255: builtins are still available at shutdown + code = """if 1: + import builtins + import sys + + class C: + def __del__(self): + print("before") + # Check that builtins still exist + len(()) + print("after") + + c = C() + # Make this module survive until builtins and sys are cleaned + builtins.here = sys.modules[__name__] + sys.here = sys.modules[__name__] + # Create a reference loop so that this module needs to go + # through a GC phase. + here = sys.modules[__name__] + """ + # Issue #20599: Force ASCII encoding to get a codec implemented in C, + # otherwise the codec may be unloaded before C.__del__() is called, and + # so print("before") fails because the codec cannot be used to encode + # "before" to sys.stdout.encoding. For example, on Windows, + # sys.stdout.encoding is the OEM code page and these code pages are + # implemented in Python + rc, out, err = assert_python_ok("-c", code, + PYTHONIOENCODING="ascii") + self.assertEqual(["before", "after"], out.decode().splitlines()) + + def load_tests(loader, tests, pattern): from doctest import DocTestSuite tests.addTest(DocTestSuite(builtins)) diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 847c7a613fe7..87799dfd191e 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -13,9 +13,11 @@ import pickle import tempfile import unittest + import test.support import test.string_tests import test.buffer_tests +from test.support import bigaddrspacetest, MAX_Py_ssize_t if sys.flags.bytes_warning: @@ -98,6 +100,14 @@ class C: self.assertRaises(TypeError, self.type2test, [0.0]) self.assertRaises(TypeError, self.type2test, [None]) self.assertRaises(TypeError, self.type2test, [C()]) + self.assertRaises(TypeError, self.type2test, 0, 'ascii') + self.assertRaises(TypeError, self.type2test, b'', 'ascii') + self.assertRaises(TypeError, self.type2test, 0, errors='ignore') + self.assertRaises(TypeError, self.type2test, b'', errors='ignore') + self.assertRaises(TypeError, self.type2test, '') + self.assertRaises(TypeError, self.type2test, '', errors='ignore') + self.assertRaises(TypeError, self.type2test, '', b'ascii') + self.assertRaises(TypeError, self.type2test, '', 'ascii', b'ignore') def test_constructor_value_errors(self): self.assertRaises(ValueError, self.type2test, [-1]) @@ -111,6 +121,17 @@ def test_constructor_value_errors(self): self.assertRaises(ValueError, self.type2test, [sys.maxsize+1]) self.assertRaises(ValueError, self.type2test, [10**100]) + @bigaddrspacetest + def test_constructor_overflow(self): + size = MAX_Py_ssize_t + self.assertRaises((OverflowError, MemoryError), self.type2test, size) + try: + # Should either pass or raise an error (e.g. on debug builds with + # additional malloc() overhead), but shouldn't crash. + bytearray(size - 4) + except (OverflowError, MemoryError): + pass + def test_compare(self): b1 = self.type2test([1, 2, 3]) b2 = self.type2test([1, 2, 3]) @@ -280,6 +301,28 @@ def test_fromhex(self): self.assertRaises(ValueError, self.type2test.fromhex, '\x00') self.assertRaises(ValueError, self.type2test.fromhex, '12 \x00 34') + for data, pos in ( + # invalid first hexadecimal character + ('12 x4 56', 3), + # invalid second hexadecimal character + ('12 3x 56', 4), + # two invalid hexadecimal characters + ('12 xy 56', 3), + # test non-ASCII string + ('12 3\xff 56', 4), + ): + with self.assertRaises(ValueError) as cm: + self.type2test.fromhex(data) + self.assertIn('at position %s' % pos, str(cm.exception)) + + def test_hex(self): + self.assertRaises(TypeError, self.type2test.hex) + self.assertRaises(TypeError, self.type2test.hex, 1) + self.assertEqual(self.type2test(b"").hex(), "") + self.assertEqual(bytearray([0x1a, 0x2b, 0x30]).hex(), '1a2b30') + self.assertEqual(self.type2test(b"\x1a\x2b\x30").hex(), '1a2b30') + self.assertEqual(memoryview(b"\x1a\x2b\x30").hex(), '1a2b30') + def test_join(self): self.assertEqual(self.type2test(b"").join([]), b"") self.assertEqual(self.type2test(b"").join([b""]), b"") @@ -298,6 +341,7 @@ def test_join(self): seq = [b"abc"] * 1000 expected = b"abc" + b".:abc" * 999 self.assertEqual(dot_join(seq), expected) + self.assertRaises(TypeError, self.type2test(b" ").join, None) # Error handling and cleanup when some item in the middle of the # sequence has the wrong type. with self.assertRaises(TypeError): @@ -439,6 +483,28 @@ def test_rindex(self): self.assertEqual(b.rindex(i, 3, 9), 7) self.assertRaises(ValueError, b.rindex, w, 1, 3) + def test_mod(self): + b = b'hello, %b!' + orig = b + b = b % b'world' + self.assertEqual(b, b'hello, world!') + self.assertEqual(orig, b'hello, %b!') + self.assertFalse(b is orig) + b = b'%s / 100 = %d%%' + a = b % (b'seventy-nine', 79) + self.assertEqual(a, b'seventy-nine / 100 = 79%') + + def test_imod(self): + b = b'hello, %b!' + orig = b + b %= b'world' + self.assertEqual(b, b'hello, world!') + self.assertEqual(orig, b'hello, %b!') + self.assertFalse(b is orig) + b = b'%s / 100 = %d%%' + b %= (b'seventy-nine', 79) + self.assertEqual(b, b'seventy-nine / 100 = 79%') + def test_replace(self): b = self.type2test(b'mississippi') self.assertEqual(b.replace(b'i', b'a'), b'massassappa') @@ -533,22 +599,23 @@ def test_pickling(self): self.assertEqual(b, q) def test_iterator_pickling(self): - for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0": - it = itorg = iter(self.type2test(b)) - data = list(self.type2test(b)) - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(type(itorg), type(it)) - self.assertEqual(list(it), data) - - it = pickle.loads(d) - try: - next(it) - except StopIteration: - continue - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(list(it), data[1:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + for b in b"", b"a", b"abc", b"\xffab\x80", b"\0\0\377\0\0": + it = itorg = iter(self.type2test(b)) + data = list(self.type2test(b)) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(type(itorg), type(it)) + self.assertEqual(list(it), data) + + it = pickle.loads(d) + try: + next(it) + except StopIteration: + continue + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(list(it), data[1:]) def test_strip(self): b = self.type2test(b'mississippi') @@ -699,8 +766,13 @@ def test_find_etc_raise_correct_error_messages(self): class BytesTest(BaseBytesTest, unittest.TestCase): type2test = bytes + def test_getitem_error(self): + msg = "byte indices must be integers or slices" + with self.assertRaisesRegex(TypeError, msg): + b'python'['a'] + def test_buffer_is_readonly(self): - fd = os.dup(sys.stdin.fileno()) + fd = os.open(__file__, os.O_RDONLY) with open(fd, "rb", buffering=0) as f: self.assertRaises(TypeError, f.readinto, b"") @@ -724,29 +796,127 @@ def __index__(self): # Test PyBytes_FromFormat() def test_from_format(self): - test.support.import_module('ctypes') - from ctypes import pythonapi, py_object, c_int, c_char_p + ctypes = test.support.import_module('ctypes') + _testcapi = test.support.import_module('_testcapi') + from ctypes import pythonapi, py_object + from ctypes import ( + c_int, c_uint, + c_long, c_ulong, + c_size_t, c_ssize_t, + c_char_p) + PyBytes_FromFormat = pythonapi.PyBytes_FromFormat PyBytes_FromFormat.restype = py_object + # basic tests self.assertEqual(PyBytes_FromFormat(b'format'), b'format') - + self.assertEqual(PyBytes_FromFormat(b'Hello %s !', b'world'), + b'Hello world !') + + # test formatters + self.assertEqual(PyBytes_FromFormat(b'c=%c', c_int(0)), + b'c=\0') + self.assertEqual(PyBytes_FromFormat(b'c=%c', c_int(ord('@'))), + b'c=@') + self.assertEqual(PyBytes_FromFormat(b'c=%c', c_int(255)), + b'c=\xff') + self.assertEqual(PyBytes_FromFormat(b'd=%d ld=%ld zd=%zd', + c_int(1), c_long(2), + c_size_t(3)), + b'd=1 ld=2 zd=3') + self.assertEqual(PyBytes_FromFormat(b'd=%d ld=%ld zd=%zd', + c_int(-1), c_long(-2), + c_size_t(-3)), + b'd=-1 ld=-2 zd=-3') + self.assertEqual(PyBytes_FromFormat(b'u=%u lu=%lu zu=%zu', + c_uint(123), c_ulong(456), + c_size_t(789)), + b'u=123 lu=456 zu=789') + self.assertEqual(PyBytes_FromFormat(b'i=%i', c_int(123)), + b'i=123') + self.assertEqual(PyBytes_FromFormat(b'i=%i', c_int(-123)), + b'i=-123') + self.assertEqual(PyBytes_FromFormat(b'x=%x', c_int(0xabc)), + b'x=abc') + + sizeof_ptr = ctypes.sizeof(c_char_p) + + if os.name == 'nt': + # Windows (MSCRT) + ptr_format = '0x%0{}X'.format(2 * sizeof_ptr) + def ptr_formatter(ptr): + return (ptr_format % ptr) + else: + # UNIX (glibc) + def ptr_formatter(ptr): + return '%#x' % ptr + + ptr = 0xabcdef + self.assertEqual(PyBytes_FromFormat(b'ptr=%p', c_char_p(ptr)), + ('ptr=' + ptr_formatter(ptr)).encode('ascii')) + self.assertEqual(PyBytes_FromFormat(b's=%s', c_char_p(b'cstr')), + b's=cstr') + + # test minimum and maximum integer values + size_max = c_size_t(-1).value + for formatstr, ctypes_type, value, py_formatter in ( + (b'%d', c_int, _testcapi.INT_MIN, str), + (b'%d', c_int, _testcapi.INT_MAX, str), + (b'%ld', c_long, _testcapi.LONG_MIN, str), + (b'%ld', c_long, _testcapi.LONG_MAX, str), + (b'%lu', c_ulong, _testcapi.ULONG_MAX, str), + (b'%zd', c_ssize_t, _testcapi.PY_SSIZE_T_MIN, str), + (b'%zd', c_ssize_t, _testcapi.PY_SSIZE_T_MAX, str), + (b'%zu', c_size_t, size_max, str), + (b'%p', c_char_p, size_max, ptr_formatter), + ): + self.assertEqual(PyBytes_FromFormat(formatstr, ctypes_type(value)), + py_formatter(value).encode('ascii')), + + # width and precision (width is currently ignored) + self.assertEqual(PyBytes_FromFormat(b'%5s', b'a'), + b'a') + self.assertEqual(PyBytes_FromFormat(b'%.3s', b'abcdef'), + b'abc') + + # '%%' formatter + self.assertEqual(PyBytes_FromFormat(b'%%'), + b'%') + self.assertEqual(PyBytes_FromFormat(b'[%%]'), + b'[%]') + self.assertEqual(PyBytes_FromFormat(b'%%%c', c_int(ord('_'))), + b'%_') + self.assertEqual(PyBytes_FromFormat(b'%%s'), + b'%s') + + # Invalid formats and partial formatting self.assertEqual(PyBytes_FromFormat(b'%'), b'%') - self.assertEqual(PyBytes_FromFormat(b'%%'), b'%') - self.assertEqual(PyBytes_FromFormat(b'%%s'), b'%s') - self.assertEqual(PyBytes_FromFormat(b'[%%]'), b'[%]') - self.assertEqual(PyBytes_FromFormat(b'%%%c', c_int(ord('_'))), b'%_') + self.assertEqual(PyBytes_FromFormat(b'x=%i y=%', c_int(2), c_int(3)), + b'x=2 y=%') - self.assertEqual(PyBytes_FromFormat(b'c:%c', c_int(255)), - b'c:\xff') - self.assertEqual(PyBytes_FromFormat(b's:%s', c_char_p(b'cstr')), - b's:cstr') + # Issue #19969: %c must raise OverflowError for values + # not in the range [0; 255] + self.assertRaises(OverflowError, + PyBytes_FromFormat, b'%c', c_int(-1)) + self.assertRaises(OverflowError, + PyBytes_FromFormat, b'%c', c_int(256)) class ByteArrayTest(BaseBytesTest, unittest.TestCase): type2test = bytearray + def test_getitem_error(self): + msg = "bytearray indices must be integers or slices" + with self.assertRaisesRegex(TypeError, msg): + bytearray(b'python')['a'] + + def test_setitem_error(self): + msg = "bytearray indices must be integers or slices" + with self.assertRaisesRegex(TypeError, msg): + b = bytearray(b'python') + b['a'] = "python" + def test_nohash(self): self.assertRaises(TypeError, hash, bytearray()) @@ -918,6 +1088,22 @@ def test_setslice_extend(self): b.extend(range(100, 110)) self.assertEqual(list(b), list(range(10, 110))) + def test_fifo_overrun(self): + # Test for issue #23985, a buffer overrun when implementing a FIFO + # Build Python in pydebug mode for best results. + b = bytearray(10) + b.pop() # Defeat expanding buffer off-by-one quirk + del b[:1] # Advance start pointer without reallocating + b += bytes(2) # Append exactly the number of deleted bytes + del b # Free memory buffer, allowing pydebug verification + + def test_del_expand(self): + # Reducing the size should not expand the buffer (issue #23985) + b = bytearray(10) + size = sys.getsizeof(b) + del b[:1] + self.assertLessEqual(sys.getsizeof(b), size) + def test_extended_set_del_slice(self): indices = (0, None, 1, 3, 19, 300, 1<<333, -1, -2, -31, -300) for start in indices: @@ -945,6 +1131,28 @@ def test_setslice_trap(self): b[8:] = b self.assertEqual(b, bytearray(list(range(8)) + list(range(256)))) + def test_mod(self): + b = bytearray(b'hello, %b!') + orig = b + b = b % b'world' + self.assertEqual(b, b'hello, world!') + self.assertEqual(orig, bytearray(b'hello, %b!')) + self.assertFalse(b is orig) + b = bytearray(b'%s / 100 = %d%%') + a = b % (b'seventy-nine', 79) + self.assertEqual(a, bytearray(b'seventy-nine / 100 = 79%')) + + def test_imod(self): + b = bytearray(b'hello, %b!') + orig = b + b %= b'world' + self.assertEqual(b, b'hello, world!') + self.assertEqual(orig, bytearray(b'hello, %b!')) + self.assertFalse(b is orig) + b = bytearray(b'%s / 100 = %d%%') + b %= (b'seventy-nine', 79) + self.assertEqual(b, bytearray(b'seventy-nine / 100 = 79%')) + def test_iconcat(self): b = bytearray(b"abc") b1 = b @@ -985,10 +1193,27 @@ def test_alloc(self): for i in range(100): b += b"x" alloc = b.__alloc__() - self.assertTrue(alloc >= len(b)) + self.assertGreater(alloc, len(b)) # including trailing null byte if alloc not in seq: seq.append(alloc) + def test_init_alloc(self): + b = bytearray() + def g(): + for i in range(1, 100): + yield i + a = list(b) + self.assertEqual(a, list(range(1, len(a)+1))) + self.assertEqual(len(b), len(a)) + self.assertLessEqual(len(b), i) + alloc = b.__alloc__() + self.assertGreater(alloc, len(b)) # including trailing null byte + b.__init__(g()) + self.assertEqual(list(b), list(range(1, 100))) + self.assertEqual(len(b), 99) + alloc = b.__alloc__() + self.assertGreater(alloc, len(b)) + def test_extend(self): orig = b'hello' a = bytearray(orig) @@ -1135,6 +1360,10 @@ def delslice(): self.assertRaises(BufferError, delslice) self.assertEqual(b, orig) + @test.support.cpython_only + def test_obsolete_write_lock(self): + from _testcapi import getbuffer_with_null_view + self.assertRaises(BufferError, getbuffer_with_null_view, bytearray()) class AssortedBytesTest(unittest.TestCase): # @@ -1245,20 +1474,35 @@ def test_return_self(self): b = bytearray() self.assertFalse(b.replace(b'', b'') is b) + @unittest.skipUnless(sys.flags.bytes_warning, + "BytesWarning is needed for this test: use -bb option") def test_compare(self): - if sys.flags.bytes_warning: - def bytes_warning(): - return test.support.check_warnings(('', BytesWarning)) - with bytes_warning(): - b'' == '' - with bytes_warning(): - b'' != '' - with bytes_warning(): - bytearray(b'') == '' - with bytes_warning(): - bytearray(b'') != '' - else: - self.skipTest("BytesWarning is needed for this test: use -bb option") + def bytes_warning(): + return test.support.check_warnings(('', BytesWarning)) + with bytes_warning(): + b'' == '' + with bytes_warning(): + '' == b'' + with bytes_warning(): + b'' != '' + with bytes_warning(): + '' != b'' + with bytes_warning(): + bytearray(b'') == '' + with bytes_warning(): + '' == bytearray(b'') + with bytes_warning(): + bytearray(b'') != '' + with bytes_warning(): + '' != bytearray(b'') + with bytes_warning(): + b'\0' == 0 + with bytes_warning(): + 0 == b'\0' + with bytes_warning(): + b'\0' != 0 + with bytes_warning(): + 0 != b'\0' # Optimizations: # __iter__? (optimization) diff --git a/Lib/test/test_bz2.py b/Lib/test/test_bz2.py index 8d93e2d88fe1..a1e4b8d8e296 100644 --- a/Lib/test/test_bz2.py +++ b/Lib/test/test_bz2.py @@ -1,15 +1,16 @@ -#!/usr/bin/env python3 from test import support from test.support import bigmemtest, _4G import unittest -from io import BytesIO +from io import BytesIO, DEFAULT_BUFFER_SIZE import os import pickle +import glob import random import subprocess import sys from test.support import unlink +import _compression try: import threading @@ -50,6 +51,20 @@ class BaseTest(unittest.TestCase): TEXT = b''.join(TEXT_LINES) DATA = b'BZh91AY&SY.\xc8N\x18\x00\x01>_\x80\x00\x10@\x02\xff\xf0\x01\x07n\x00?\xe7\xff\xe00\x01\x99\xaa\x00\xc0\x03F\x86\x8c#&\x83F\x9a\x03\x06\xa6\xd0\xa6\x93M\x0fQ\xa7\xa8\x06\x804hh\x12$\x11\xa4i4\xf14S\xd2\x88\xe5\xcd9gd6\x0b\n\xe9\x9b\xd5\x8a\x99\xf7\x08.K\x8ev\xfb\xf7xw\xbb\xdf\xa1\x92\xf1\xdd|/";\xa2\xba\x9f\xd5\xb1#A\xb6\xf6\xb3o\xc9\xc5y\\\xebO\xe7\x85\x9a\xbc\xb6f8\x952\xd5\xd7"%\x89>V,\xf7\xa6z\xe2\x9f\xa3\xdf\x11\x11"\xd6E)I\xa9\x13^\xca\xf3r\xd0\x03U\x922\xf26\xec\xb6\xed\x8b\xc3U\x13\x9d\xc5\x170\xa4\xfa^\x92\xacDF\x8a\x97\xd6\x19\xfe\xdd\xb8\xbd\x1a\x9a\x19\xa3\x80ankR\x8b\xe5\xd83]\xa9\xc6\x08\x82f\xf6\xb9"6l$\xb8j@\xc0\x8a\xb0l1..\xbak\x83ls\x15\xbc\xf4\xc1\x13\xbe\xf8E\xb8\x9d\r\xa8\x9dk\x84\xd3n\xfa\xacQ\x07\xb1%y\xaav\xb4\x08\xe0z\x1b\x16\xf5\x04\xe9\xcc\xb9\x08z\x1en7.G\xfc]\xc9\x14\xe1B@\xbb!8`' EMPTY_DATA = b'BZh9\x17rE8P\x90\x00\x00\x00\x00' + BAD_DATA = b'this is not a valid bzip2 file' + + # Some tests need more than one block of uncompressed data. Since one block + # is at least 100 kB, we gather some data dynamically and compress it. + # Note that this assumes that compression works correctly, so we cannot + # simply use the bigger test data for all tests. + test_size = 0 + BIG_TEXT = bytearray(128*1024) + for fname in glob.glob(os.path.join(os.path.dirname(__file__), '*.py')): + with open(fname, 'rb') as fh: + test_size += fh.readinto(memoryview(BIG_TEXT)[test_size:]) + if test_size > 128*1024: + break + BIG_DATA = bz2.compress(BIG_TEXT, compresslevel=1) def setUp(self): self.filename = support.TESTFN @@ -80,47 +95,63 @@ def decompress(self, data): class BZ2FileTest(BaseTest): "Test the BZ2File class." - def createTempFile(self, streams=1): + def createTempFile(self, streams=1, suffix=b""): with open(self.filename, "wb") as f: f.write(self.DATA * streams) + f.write(suffix) def testBadArgs(self): self.assertRaises(TypeError, BZ2File, 123.456) - self.assertRaises(ValueError, BZ2File, "/dev/null", "z") - self.assertRaises(ValueError, BZ2File, "/dev/null", "rx") - self.assertRaises(ValueError, BZ2File, "/dev/null", "rbt") - self.assertRaises(ValueError, BZ2File, "/dev/null", compresslevel=0) - self.assertRaises(ValueError, BZ2File, "/dev/null", compresslevel=10) + self.assertRaises(ValueError, BZ2File, os.devnull, "z") + self.assertRaises(ValueError, BZ2File, os.devnull, "rx") + self.assertRaises(ValueError, BZ2File, os.devnull, "rbt") + self.assertRaises(ValueError, BZ2File, os.devnull, compresslevel=0) + self.assertRaises(ValueError, BZ2File, os.devnull, compresslevel=10) def testRead(self): self.createTempFile() with BZ2File(self.filename) as bz2f: - self.assertRaises(TypeError, bz2f.read, None) + self.assertRaises(TypeError, bz2f.read, float()) self.assertEqual(bz2f.read(), self.TEXT) + def testReadBadFile(self): + self.createTempFile(streams=0, suffix=self.BAD_DATA) + with BZ2File(self.filename) as bz2f: + self.assertRaises(OSError, bz2f.read) + def testReadMultiStream(self): self.createTempFile(streams=5) with BZ2File(self.filename) as bz2f: - self.assertRaises(TypeError, bz2f.read, None) + self.assertRaises(TypeError, bz2f.read, float()) self.assertEqual(bz2f.read(), self.TEXT * 5) def testReadMonkeyMultiStream(self): # Test BZ2File.read() on a multi-stream archive where a stream # boundary coincides with the end of the raw read buffer. - buffer_size = bz2._BUFFER_SIZE - bz2._BUFFER_SIZE = len(self.DATA) + buffer_size = _compression.BUFFER_SIZE + _compression.BUFFER_SIZE = len(self.DATA) try: self.createTempFile(streams=5) with BZ2File(self.filename) as bz2f: - self.assertRaises(TypeError, bz2f.read, None) + self.assertRaises(TypeError, bz2f.read, float()) self.assertEqual(bz2f.read(), self.TEXT * 5) finally: - bz2._BUFFER_SIZE = buffer_size + _compression.BUFFER_SIZE = buffer_size + + def testReadTrailingJunk(self): + self.createTempFile(suffix=self.BAD_DATA) + with BZ2File(self.filename) as bz2f: + self.assertEqual(bz2f.read(), self.TEXT) + + def testReadMultiStreamTrailingJunk(self): + self.createTempFile(streams=5, suffix=self.BAD_DATA) + with BZ2File(self.filename) as bz2f: + self.assertEqual(bz2f.read(), self.TEXT * 5) def testRead0(self): self.createTempFile() with BZ2File(self.filename) as bz2f: - self.assertRaises(TypeError, bz2f.read, None) + self.assertRaises(TypeError, bz2f.read, float()) self.assertEqual(bz2f.read(0), b"") def testReadChunk10(self): @@ -477,10 +508,8 @@ def comp(): for i in range(5): f.write(data) threads = [threading.Thread(target=comp) for i in range(nthreads)] - for t in threads: - t.start() - for t in threads: - t.join() + with support.start_threads(threads): + pass def testWithoutThreading(self): module = support.import_fresh_module("bz2", blocked=("threading",)) @@ -531,13 +560,24 @@ def testOpenBytesFilename(self): with BZ2File(str_filename, "rb") as f: self.assertEqual(f.read(), self.DATA) + def testDecompressLimited(self): + """Decompressed data buffering should be limited""" + bomb = bz2.compress(bytes(int(2e6)), compresslevel=9) + self.assertLess(len(bomb), _compression.BUFFER_SIZE) + + decomp = BZ2File(BytesIO(bomb)) + self.assertEqual(bytes(1), decomp.read(1)) + max_decomp = 1 + DEFAULT_BUFFER_SIZE + self.assertLessEqual(decomp._buffer.raw.tell(), max_decomp, + "Excessive amount of data was decompressed") + # Tests for a BZ2File wrapping another file object: def testReadBytesIO(self): with BytesIO(self.DATA) as bio: with BZ2File(bio) as bz2f: - self.assertRaises(TypeError, bz2f.read, None) + self.assertRaises(TypeError, bz2f.read, float()) self.assertEqual(bz2f.read(), self.TEXT) self.assertFalse(bio.closed) @@ -630,8 +670,9 @@ def testCompress4G(self, size): data = None def testPickle(self): - with self.assertRaises(TypeError): - pickle.dumps(BZ2Compressor()) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises(TypeError): + pickle.dumps(BZ2Compressor(), proto) class BZ2DecompressorTest(BaseTest): @@ -669,7 +710,7 @@ def testEOFError(self): self.assertRaises(EOFError, bz2d.decompress, b"anything") self.assertRaises(EOFError, bz2d.decompress, b"") - @bigmemtest(size=_4G + 100, memuse=3) + @bigmemtest(size=_4G + 100, memuse=3.3) def testDecompress4G(self, size): # "Test BZ2Decompressor.decompress() with >4GiB input" blocksize = 10 * 1024 * 1024 @@ -686,9 +727,99 @@ def testDecompress4G(self, size): decompressed = None def testPickle(self): - with self.assertRaises(TypeError): - pickle.dumps(BZ2Decompressor()) - + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises(TypeError): + pickle.dumps(BZ2Decompressor(), proto) + + def testDecompressorChunksMaxsize(self): + bzd = BZ2Decompressor() + max_length = 100 + out = [] + + # Feed some input + len_ = len(self.BIG_DATA) - 64 + out.append(bzd.decompress(self.BIG_DATA[:len_], + max_length=max_length)) + self.assertFalse(bzd.needs_input) + self.assertEqual(len(out[-1]), max_length) + + # Retrieve more data without providing more input + out.append(bzd.decompress(b'', max_length=max_length)) + self.assertFalse(bzd.needs_input) + self.assertEqual(len(out[-1]), max_length) + + # Retrieve more data while providing more input + out.append(bzd.decompress(self.BIG_DATA[len_:], + max_length=max_length)) + self.assertLessEqual(len(out[-1]), max_length) + + # Retrieve remaining uncompressed data + while not bzd.eof: + out.append(bzd.decompress(b'', max_length=max_length)) + self.assertLessEqual(len(out[-1]), max_length) + + out = b"".join(out) + self.assertEqual(out, self.BIG_TEXT) + self.assertEqual(bzd.unused_data, b"") + + def test_decompressor_inputbuf_1(self): + # Test reusing input buffer after moving existing + # contents to beginning + bzd = BZ2Decompressor() + out = [] + + # Create input buffer and fill it + self.assertEqual(bzd.decompress(self.DATA[:100], + max_length=0), b'') + + # Retrieve some results, freeing capacity at beginning + # of input buffer + out.append(bzd.decompress(b'', 2)) + + # Add more data that fits into input buffer after + # moving existing data to beginning + out.append(bzd.decompress(self.DATA[100:105], 15)) + + # Decompress rest of data + out.append(bzd.decompress(self.DATA[105:])) + self.assertEqual(b''.join(out), self.TEXT) + + def test_decompressor_inputbuf_2(self): + # Test reusing input buffer by appending data at the + # end right away + bzd = BZ2Decompressor() + out = [] + + # Create input buffer and empty it + self.assertEqual(bzd.decompress(self.DATA[:200], + max_length=0), b'') + out.append(bzd.decompress(b'')) + + # Fill buffer with new data + out.append(bzd.decompress(self.DATA[200:280], 2)) + + # Append some more data, not enough to require resize + out.append(bzd.decompress(self.DATA[280:300], 2)) + + # Decompress rest of data + out.append(bzd.decompress(self.DATA[300:])) + self.assertEqual(b''.join(out), self.TEXT) + + def test_decompressor_inputbuf_3(self): + # Test reusing input buffer after extending it + + bzd = BZ2Decompressor() + out = [] + + # Create almost full input buffer + out.append(bzd.decompress(self.DATA[:200], 5)) + + # Add even more data to it, requiring resize + out.append(bzd.decompress(self.DATA[200:300], 5)) + + # Decompress rest of data + out.append(bzd.decompress(self.DATA[300:])) + self.assertEqual(b''.join(out), self.TEXT) class CompressDecompressTest(BaseTest): def testCompress(self): @@ -714,10 +845,21 @@ def testDecompressToEmptyString(self): def testDecompressIncomplete(self): self.assertRaises(ValueError, bz2.decompress, self.DATA[:-10]) + def testDecompressBadData(self): + self.assertRaises(OSError, bz2.decompress, self.BAD_DATA) + def testDecompressMultiStream(self): text = bz2.decompress(self.DATA * 5) self.assertEqual(text, self.TEXT * 5) + def testDecompressTrailingJunk(self): + text = bz2.decompress(self.DATA + self.BAD_DATA) + self.assertEqual(text, self.TEXT) + + def testDecompressMultiStreamTrailingJunk(self): + text = bz2.decompress(self.DATA * 5 + self.BAD_DATA) + self.assertEqual(text, self.TEXT * 5) + class OpenTest(BaseTest): "Test the open function." diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index f680b52f0974..80ed6325881a 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -2,13 +2,14 @@ import unittest from test import support -from test.script_helper import assert_python_ok +from test.support.script_helper import assert_python_ok, assert_python_failure import time import locale import sys import datetime +import os -result_2004_01_text = """ +result_2004_01_text = """\ January 2004 Mo Tu We Th Fr Sa Su 1 2 3 4 @@ -18,7 +19,7 @@ 26 27 28 29 30 31 """ -result_2004_text = """ +result_2004_text = """\ 2004 January February March @@ -56,7 +57,7 @@ 25 26 27 28 29 30 31 29 30 27 28 29 30 31 """ -result_2004_html = """ +result_2004_html = """\ @@ -327,8 +328,8 @@ def neitherspacenordigit(c): def check_htmlcalendar_encoding(self, req, res): cal = calendar.HTMLCalendar() self.assertEqual( - cal.formatyearpage(2004, encoding=req).strip(b' \t\n'), - (result_2004_html % {'e': res}).strip(' \t\n').encode(res) + cal.formatyearpage(2004, encoding=req), + (result_2004_html % {'e': res}).encode(res) ) def test_output(self): @@ -339,8 +340,8 @@ def test_output(self): def test_output_textcalendar(self): self.assertEqual( - calendar.TextCalendar().formatyear(2004).strip(), - result_2004_text.strip() + calendar.TextCalendar().formatyear(2004), + result_2004_text ) def test_output_htmlcalendar_encoding_ascii(self): @@ -383,8 +384,8 @@ def test_formatweekheader_long(self): def test_formatmonth(self): self.assertEqual( - calendar.TextCalendar().formatmonth(2004, 1).strip(), - result_2004_01_text.strip() + calendar.TextCalendar().formatmonth(2004, 1), + result_2004_01_text ) def test_formatmonthname_with_year(self): @@ -692,23 +693,127 @@ def test_several_leapyears_in_range(self): self.assertEqual(calendar.leapdays(1997,2020), 5) -class ConsoleOutputTestCase(unittest.TestCase): - def test_outputs_bytes(self): - (return_code, stdout, stderr) = assert_python_ok('-m', 'calendar', '--type=html', '2010') +def conv(s): + return s.replace('\n', os.linesep).encode() + +class CommandLineTestCase(unittest.TestCase): + def run_ok(self, *args): + return assert_python_ok('-m', 'calendar', *args)[1] + + def assertFailure(self, *args): + rc, stdout, stderr = assert_python_failure('-m', 'calendar', *args) + self.assertIn(b'Usage:', stderr) + self.assertEqual(rc, 2) + + def test_help(self): + stdout = self.run_ok('-h') + self.assertIn(b'Usage:', stdout) + self.assertIn(b'calendar.py', stdout) + self.assertIn(b'--help', stdout) + + def test_illegal_arguments(self): + self.assertFailure('-z') + #self.assertFailure('spam') + #self.assertFailure('2004', 'spam') + self.assertFailure('-t', 'html', '2004', '1') + + def test_output_current_year(self): + stdout = self.run_ok() + year = datetime.datetime.now().year + self.assertIn((' %s' % year).encode(), stdout) + self.assertIn(b'January', stdout) + self.assertIn(b'Mo Tu We Th Fr Sa Su', stdout) + + def test_output_year(self): + stdout = self.run_ok('2004') + self.assertEqual(stdout, conv(result_2004_text)) + + def test_output_month(self): + stdout = self.run_ok('2004', '1') + self.assertEqual(stdout, conv(result_2004_01_text)) + + def test_option_encoding(self): + self.assertFailure('-e') + self.assertFailure('--encoding') + stdout = self.run_ok('--encoding', 'utf-16-le', '2004') + self.assertEqual(stdout, result_2004_text.encode('utf-16-le')) + + def test_option_locale(self): + self.assertFailure('-L') + self.assertFailure('--locale') + self.assertFailure('-L', 'en') + lang, enc = locale.getdefaultlocale() + lang = lang or 'C' + enc = enc or 'UTF-8' + try: + oldlocale = locale.getlocale(locale.LC_TIME) + try: + locale.setlocale(locale.LC_TIME, (lang, enc)) + finally: + locale.setlocale(locale.LC_TIME, oldlocale) + except (locale.Error, ValueError): + self.skipTest('cannot set the system default locale') + stdout = self.run_ok('--locale', lang, '--encoding', enc, '2004') + self.assertIn('2004'.encode(enc), stdout) + + def test_option_width(self): + self.assertFailure('-w') + self.assertFailure('--width') + self.assertFailure('-w', 'spam') + stdout = self.run_ok('--width', '3', '2004') + self.assertIn(b'Mon Tue Wed Thu Fri Sat Sun', stdout) + + def test_option_lines(self): + self.assertFailure('-l') + self.assertFailure('--lines') + self.assertFailure('-l', 'spam') + stdout = self.run_ok('--lines', '2', '2004') + self.assertIn(conv('December\n\nMo Tu We'), stdout) + + def test_option_spacing(self): + self.assertFailure('-s') + self.assertFailure('--spacing') + self.assertFailure('-s', 'spam') + stdout = self.run_ok('--spacing', '8', '2004') + self.assertIn(b'Su Mo', stdout) + + def test_option_months(self): + self.assertFailure('-m') + self.assertFailure('--month') + self.assertFailure('-m', 'spam') + stdout = self.run_ok('--months', '1', '2004') + self.assertIn(conv('\nMo Tu We Th Fr Sa Su\n'), stdout) + + def test_option_type(self): + self.assertFailure('-t') + self.assertFailure('--type') + self.assertFailure('-t', 'spam') + stdout = self.run_ok('--type', 'text', '2004') + self.assertEqual(stdout, conv(result_2004_text)) + stdout = self.run_ok('--type', 'html', '2004') self.assertEqual(stdout[:6], b'Calendar for 2004', stdout) + + def test_html_output_current_year(self): + stdout = self.run_ok('--type', 'html') + year = datetime.datetime.now().year + self.assertIn(('Calendar for %s' % year).encode(), + stdout) + self.assertIn(b'January', + stdout) + + def test_html_output_year_encoding(self): + stdout = self.run_ok('-t', 'html', '--encoding', 'ascii', '2004') + self.assertEqual(stdout, + (result_2004_html % {'e': 'ascii'}).encode('ascii')) -def test_main(): - support.run_unittest( - OutputTestCase, - CalendarTestCase, - MondayTestCase, - SundayTestCase, - TimegmTestCase, - MonthRangeTestCase, - LeapdaysTestCase, - ConsoleOutputTestCase - ) + def test_html_output_year_css(self): + self.assertFailure('-t', 'html', '-c') + self.assertFailure('-t', 'html', '--css') + stdout = self.run_ok('-t', 'html', '--css', 'custom.css', '2004') + self.assertIn(b'', stdout) if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py index c00ccbac85b2..e2b8e0fd1233 100644 --- a/Lib/test/test_call.py +++ b/Lib/test/test_call.py @@ -1,5 +1,4 @@ import unittest -from test import support # The test cases here cover several paths through the function calling # code. They depend on the METH_XXX flag that is used to define a C @@ -123,9 +122,5 @@ def test_oldargs1_2_kw(self): self.assertRaises(TypeError, [].count, x=2, y=2) -def test_main(): - support.run_unittest(CFunctionCalls) - - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 22c8eb0709ce..eae3addcb182 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -6,10 +6,12 @@ import random import subprocess import sys +import textwrap import time import unittest from test import support from test.support import MISSING_C_DOCSTRINGS +from test.support.script_helper import assert_python_failure try: import _posixsubprocess except ImportError: @@ -18,7 +20,11 @@ import threading except ImportError: threading = None -import _testcapi +# Skip this test if the _testcapi module isn't available. +_testcapi = support.import_module('_testcapi') + +# Were we compiled --with-pydebug or with #define Py_DEBUG? +Py_DEBUG = hasattr(sys, 'gettotalrefcount') def testfunction(self): @@ -117,7 +123,7 @@ def test_docstring_signature_parsing(self): self.assertEqual(_testcapi.no_docstring.__doc__, None) self.assertEqual(_testcapi.no_docstring.__text_signature__, None) - self.assertEqual(_testcapi.docstring_empty.__doc__, "") + self.assertEqual(_testcapi.docstring_empty.__doc__, None) self.assertEqual(_testcapi.docstring_empty.__text_signature__, None) self.assertEqual(_testcapi.docstring_no_signature.__doc__, @@ -125,20 +131,110 @@ def test_docstring_signature_parsing(self): self.assertEqual(_testcapi.docstring_no_signature.__text_signature__, None) self.assertEqual(_testcapi.docstring_with_invalid_signature.__doc__, - "docstring_with_invalid_signature (boo)\n" + "docstring_with_invalid_signature($module, /, boo)\n" "\n" "This docstring has an invalid signature." ) self.assertEqual(_testcapi.docstring_with_invalid_signature.__text_signature__, None) + self.assertEqual(_testcapi.docstring_with_invalid_signature2.__doc__, + "docstring_with_invalid_signature2($module, /, boo)\n" + "\n" + "--\n" + "\n" + "This docstring also has an invalid signature." + ) + self.assertEqual(_testcapi.docstring_with_invalid_signature2.__text_signature__, None) + self.assertEqual(_testcapi.docstring_with_signature.__doc__, "This docstring has a valid signature.") - self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "(sig)") + self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "($module, /, sig)") + + self.assertEqual(_testcapi.docstring_with_signature_but_no_doc.__doc__, None) + self.assertEqual(_testcapi.docstring_with_signature_but_no_doc.__text_signature__, + "($module, /, sig)") self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__doc__, - "This docstring has a valid signature and some extra newlines.") + "\nThis docstring has a valid signature and some extra newlines.") self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__, - "(parameter)") + "($module, /, parameter)") + + def test_c_type_with_matrix_multiplication(self): + M = _testcapi.matmulType + m1 = M() + m2 = M() + self.assertEqual(m1 @ m2, ("matmul", m1, m2)) + self.assertEqual(m1 @ 42, ("matmul", m1, 42)) + self.assertEqual(42 @ m1, ("matmul", 42, m1)) + o = m1 + o @= m2 + self.assertEqual(o, ("imatmul", m1, m2)) + o = m1 + o @= 42 + self.assertEqual(o, ("imatmul", m1, 42)) + o = 42 + o @= m1 + self.assertEqual(o, ("matmul", 42, m1)) + + def test_return_null_without_error(self): + # Issue #23571: A function must not return NULL without setting an + # error + if Py_DEBUG: + code = textwrap.dedent(""" + import _testcapi + from test import support + + with support.SuppressCrashReport(): + _testcapi.return_null_without_error() + """) + rc, out, err = assert_python_failure('-c', code) + self.assertRegex(err.replace(b'\r', b''), + br'Fatal Python error: a function returned NULL ' + br'without setting an error\n' + br'SystemError: returned NULL ' + br'without setting an error\n' + br'\n' + br'Current thread.*:\n' + br' File .*", line 6 in ') + else: + with self.assertRaises(SystemError) as cm: + _testcapi.return_null_without_error() + self.assertRegex(str(cm.exception), + 'return_null_without_error.* ' + 'returned NULL without setting an error') + + def test_return_result_with_error(self): + # Issue #23571: A function must not return a result with an error set + if Py_DEBUG: + code = textwrap.dedent(""" + import _testcapi + from test import support + + with support.SuppressCrashReport(): + _testcapi.return_result_with_error() + """) + rc, out, err = assert_python_failure('-c', code) + self.assertRegex(err.replace(b'\r', b''), + br'Fatal Python error: a function returned a ' + br'result with an error set\n' + br'ValueError\n' + br'\n' + br'During handling of the above exception, ' + br'another exception occurred:\n' + br'\n' + br'SystemError: ' + br'returned a result with an error set\n' + br'\n' + br'Current thread.*:\n' + br' File .*, line 6 in ') + else: + with self.assertRaises(SystemError) as cm: + _testcapi.return_result_with_error() + self.assertRegex(str(cm.exception), + 'return_result_with_error.* ' + 'returned a result with an error set') @unittest.skipUnless(threading, 'Threading required for this test.') @@ -192,15 +288,11 @@ class foo(object):pass context.lock = threading.Lock() context.event = threading.Event() - for i in range(context.nThreads): - t = threading.Thread(target=self.pendingcalls_thread, args = (context,)) - t.start() - threads.append(t) - - self.pendingcalls_wait(context.l, n, context) - - for t in threads: - t.join() + threads = [threading.Thread(target=self.pendingcalls_thread, + args=(context,)) + for i in range(context.nThreads)] + with support.start_threads(threads): + self.pendingcalls_wait(context.l, n, context) def pendingcalls_thread(self, context): try: @@ -258,7 +350,7 @@ def setUp(self): exename += ext exepath = os.path.dirname(sys.executable) else: - exepath = os.path.join(basepath, "Modules") + exepath = os.path.join(basepath, "Programs") self.test_exe = exe = os.path.join(exepath, exename) if not os.path.exists(exe): self.skipTest("%r doesn't exist" % exe) @@ -277,12 +369,13 @@ def run_embedded_interpreter(self, *args): cmd.extend(args) p = subprocess.Popen(cmd, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + stderr=subprocess.PIPE, + universal_newlines=True) (out, err) = p.communicate() self.assertEqual(p.returncode, 0, "bad returncode %d, stderr is %r" % (p.returncode, err)) - return out.decode("latin1"), err.decode("latin1") + return out, err def test_subinterps(self): # This is just a "don't crash" test @@ -309,34 +402,38 @@ def test_forced_io_encoding(self): print() print(out) print(err) + expected_errors = sys.__stdout__.errors expected_stdin_encoding = sys.__stdin__.encoding expected_pipe_encoding = self._get_default_pipe_encoding() - expected_output = os.linesep.join([ + expected_output = '\n'.join([ "--- Use defaults ---", "Expected encoding: default", "Expected errors: default", - "stdin: {0}:strict", - "stdout: {1}:strict", - "stderr: {1}:backslashreplace", + "stdin: {in_encoding}:{errors}", + "stdout: {out_encoding}:{errors}", + "stderr: {out_encoding}:backslashreplace", "--- Set errors only ---", "Expected encoding: default", - "Expected errors: surrogateescape", - "stdin: {0}:surrogateescape", - "stdout: {1}:surrogateescape", - "stderr: {1}:backslashreplace", + "Expected errors: ignore", + "stdin: {in_encoding}:ignore", + "stdout: {out_encoding}:ignore", + "stderr: {out_encoding}:backslashreplace", "--- Set encoding only ---", "Expected encoding: latin-1", "Expected errors: default", - "stdin: latin-1:strict", - "stdout: latin-1:strict", + "stdin: latin-1:{errors}", + "stdout: latin-1:{errors}", "stderr: latin-1:backslashreplace", "--- Set encoding and errors ---", "Expected encoding: latin-1", - "Expected errors: surrogateescape", - "stdin: latin-1:surrogateescape", - "stdout: latin-1:surrogateescape", - "stderr: latin-1:backslashreplace"]).format(expected_stdin_encoding, - expected_pipe_encoding) + "Expected errors: replace", + "stdin: latin-1:replace", + "stdout: latin-1:replace", + "stderr: latin-1:backslashreplace"]) + expected_output = expected_output.format( + in_encoding=expected_stdin_encoding, + out_encoding=expected_pipe_encoding, + errors=expected_errors) # This is useful if we ever trip over odd platform behaviour self.maxDiff = None self.assertEqual(out.strip(), expected_output) diff --git a/Lib/test/test_cgi.py b/Lib/test/test_cgi.py index d80ec0776787..ab9f6ab6a558 100644 --- a/Lib/test/test_cgi.py +++ b/Lib/test/test_cgi.py @@ -1,4 +1,4 @@ -from test.support import run_unittest, check_warnings +from test.support import check_warnings import cgi import os import sys @@ -137,6 +137,13 @@ def test_fieldstorage_properties(self): fs.list.append(namedtuple('MockFieldStorage', 'name')('fieldvalue')) self.assertTrue(fs) + def test_fieldstorage_invalid(self): + self.assertRaises(TypeError, cgi.FieldStorage, "not-a-file-obj", + environ={"REQUEST_METHOD":"PUT"}) + self.assertRaises(TypeError, cgi.FieldStorage, "foo", "bar") + fs = cgi.FieldStorage(headers={'content-type':'text/plain'}) + self.assertRaises(TypeError, bool, fs) + def test_escape(self): # cgi.escape() is deprecated. with warnings.catch_warnings(): @@ -179,9 +186,9 @@ def test_log(self): cgi.initlog("%s", "Testing initlog 1") cgi.log("%s", "Testing log 2") self.assertEqual(cgi.logfp.getvalue(), "Testing initlog 1\nTesting log 2\n") - if os.path.exists("/dev/null"): + if os.path.exists(os.devnull): cgi.logfp = None - cgi.logfile = "/dev/null" + cgi.logfile = os.devnull cgi.initlog("%s", "Testing log 3") self.addCleanup(cgi.closelog) cgi.log("Testing log 4") @@ -220,7 +227,7 @@ def __getattr__(self, name): # if we're not chunking properly, readline is only called twice # (by read_binary); if we are chunking properly, it will be called 5 times # as long as the chunksize is 1 << 16. - self.assertTrue(f.numcalls > 2) + self.assertGreater(f.numcalls, 2) f.close() def test_fieldstorage_multipart(self): @@ -241,6 +248,25 @@ def test_fieldstorage_multipart(self): got = getattr(fs.list[x], k) self.assertEqual(got, exp) + def test_fieldstorage_multipart_leading_whitespace(self): + env = { + 'REQUEST_METHOD': 'POST', + 'CONTENT_TYPE': 'multipart/form-data; boundary={}'.format(BOUNDARY), + 'CONTENT_LENGTH': '560'} + # Add some leading whitespace to our post data that will cause the + # first line to not be the innerboundary. + fp = BytesIO(b"\r\n" + POSTDATA.encode('latin-1')) + fs = cgi.FieldStorage(fp, environ=env, encoding="latin-1") + self.assertEqual(len(fs.list), 4) + expect = [{'name':'id', 'filename':None, 'value':'1234'}, + {'name':'title', 'filename':None, 'value':''}, + {'name':'file', 'filename':'test.txt', 'value':b'Testing 123.\n'}, + {'name':'submit', 'filename':None, 'value':' Add '}] + for x in range(len(fs.list)): + for k, exp in expect[x].items(): + got = getattr(fs.list[x], k) + self.assertEqual(got, exp) + def test_fieldstorage_multipart_non_ascii(self): #Test basic FieldStorage multipart parsing env = {'REQUEST_METHOD':'POST', @@ -300,6 +326,35 @@ def test_fieldstorage_multipart_w3c(self): got = getattr(files[x], k) self.assertEqual(got, exp) + def test_fieldstorage_part_content_length(self): + BOUNDARY = "JfISa01" + POSTDATA = """--JfISa01 +Content-Disposition: form-data; name="submit-name" +Content-Length: 5 + +Larry +--JfISa01""" + env = { + 'REQUEST_METHOD': 'POST', + 'CONTENT_TYPE': 'multipart/form-data; boundary={}'.format(BOUNDARY), + 'CONTENT_LENGTH': str(len(POSTDATA))} + fp = BytesIO(POSTDATA.encode('latin-1')) + fs = cgi.FieldStorage(fp, environ=env, encoding="latin-1") + self.assertEqual(len(fs.list), 1) + self.assertEqual(fs.list[0].name, 'submit-name') + self.assertEqual(fs.list[0].value, 'Larry') + + def test_fieldstorage_as_context_manager(self): + fp = BytesIO(b'x' * 10) + env = {'REQUEST_METHOD': 'PUT'} + with cgi.FieldStorage(fp=fp, environ=env) as fs: + content = fs.file.read() + self.assertFalse(fs.file.closed) + self.assertTrue(fs.file.closed) + self.assertEqual(content, 'x' * 10) + with self.assertRaisesRegex(ValueError, 'I/O operation on closed file'): + fs.file.read() + _qs_result = { 'key1': 'value1', 'key2': ['value2x', 'value2y'], @@ -474,9 +529,5 @@ def test_parse_header(self): --AaB03x-- """ - -def test_main(): - run_unittest(CgiTests) - if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test_cgitb.py b/Lib/test/test_cgitb.py index 2e072a9f2ac5..a87a4224f94d 100644 --- a/Lib/test/test_cgitb.py +++ b/Lib/test/test_cgitb.py @@ -1,5 +1,5 @@ -from test.support import run_unittest -from test.script_helper import assert_python_failure, temp_dir +from test.support import temp_dir +from test.support.script_helper import assert_python_failure import unittest import sys import cgitb @@ -63,8 +63,5 @@ def test_syshook_no_logdir_text_format(self): self.assertNotIn('

', out) -def test_main(): - run_unittest(TestCgitb) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_charmapcodec.py b/Lib/test/test_charmapcodec.py index 6226587267e1..4064aef9352f 100644 --- a/Lib/test/test_charmapcodec.py +++ b/Lib/test/test_charmapcodec.py @@ -49,8 +49,5 @@ def test_constructory(self): def test_maptoundefined(self): self.assertRaises(UnicodeError, str, b'abc\001', codecname) -def test_main(): - test.support.run_unittest(CharmapCodecTest) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_class.py b/Lib/test/test_class.py index c7003fbe608b..4d554a397b4a 100644 --- a/Lib/test/test_class.py +++ b/Lib/test/test_class.py @@ -2,7 +2,6 @@ import unittest -from test import support testmeths = [ @@ -13,8 +12,12 @@ "rsub", "mul", "rmul", + "matmul", + "rmatmul", "truediv", "rtruediv", + "floordiv", + "rfloordiv", "mod", "rmod", "divmod", @@ -174,15 +177,31 @@ def testBinaryOps(self): 1 * testme self.assertCallStack([("__rmul__", (testme, 1))]) - if 1/2 == 0: - callLst[:] = [] - testme / 1 - self.assertCallStack([("__div__", (testme, 1))]) + callLst[:] = [] + testme @ 1 + self.assertCallStack([("__matmul__", (testme, 1))]) + + callLst[:] = [] + 1 @ testme + self.assertCallStack([("__rmatmul__", (testme, 1))]) + + callLst[:] = [] + testme / 1 + self.assertCallStack([("__truediv__", (testme, 1))]) + + callLst[:] = [] + 1 / testme + self.assertCallStack([("__rtruediv__", (testme, 1))]) + + callLst[:] = [] + testme // 1 + self.assertCallStack([("__floordiv__", (testme, 1))]) - callLst[:] = [] - 1 / testme - self.assertCallStack([("__rdiv__", (testme, 1))]) + + callLst[:] = [] + 1 // testme + self.assertCallStack([("__rfloordiv__", (testme, 1))]) callLst[:] = [] testme % 1 @@ -444,12 +463,16 @@ class BadTypeClass: def __int__(self): return None __float__ = __int__ + __complex__ = __int__ __str__ = __int__ __repr__ = __int__ - __oct__ = __int__ - __hex__ = __int__ + __bytes__ = __int__ + __bool__ = __int__ + __index__ = __int__ + def index(x): + return [][x] - for f in [int, float, str, repr, oct, hex]: + for f in [float, complex, str, repr, bytes, bin, oct, hex, bool, index]: self.assertRaises(TypeError, f, BadTypeClass()) def testHashStuff(self): @@ -477,10 +500,10 @@ class A: try: a() # This should not segfault - except RuntimeError: + except RecursionError: pass else: - self.fail("Failed to raise RuntimeError") + self.fail("Failed to raise RecursionError") def testForExceptionsRaisedInInstanceGetattr2(self): # Tests for exceptions raised in instance_getattr2(). @@ -545,8 +568,5 @@ class B(A): a = A(hash(A.f)^(-1)) hash(a.f) -def test_main(): - support.run_unittest(ClassTests) - -if __name__=='__main__': - test_main() +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_cmath.py b/Lib/test/test_cmath.py index 4db6b2b991ba..1f884e52a2c9 100644 --- a/Lib/test/test_cmath.py +++ b/Lib/test/test_cmath.py @@ -1,5 +1,6 @@ -from test.support import run_unittest, requires_IEEE_754 +from test.support import requires_IEEE_754, cpython_only from test.test_math import parse_testfile, test_file +import test.test_math as test_math import unittest import cmath, math from cmath import phase, polar, rect, pi @@ -381,17 +382,48 @@ def polar_complex(z): self.rAssertAlmostEqual(expected.imag, actual.imag, msg=error_message) - def assertCISEqual(self, a, b): - eps = 1E-7 - if abs(a[0] - b[0]) > eps or abs(a[1] - b[1]) > eps: - self.fail((a ,b)) + def check_polar(self, func): + def check(arg, expected): + got = func(arg) + for e, g in zip(expected, got): + self.rAssertAlmostEqual(e, g) + check(0, (0., 0.)) + check(1, (1., 0.)) + check(-1, (1., pi)) + check(1j, (1., pi / 2)) + check(-3j, (3., -pi / 2)) + inf = float('inf') + check(complex(inf, 0), (inf, 0.)) + check(complex(-inf, 0), (inf, pi)) + check(complex(3, inf), (inf, pi / 2)) + check(complex(5, -inf), (inf, -pi / 2)) + check(complex(inf, inf), (inf, pi / 4)) + check(complex(inf, -inf), (inf, -pi / 4)) + check(complex(-inf, inf), (inf, 3 * pi / 4)) + check(complex(-inf, -inf), (inf, -3 * pi / 4)) + nan = float('nan') + check(complex(nan, 0), (nan, nan)) + check(complex(0, nan), (nan, nan)) + check(complex(nan, nan), (nan, nan)) + check(complex(inf, nan), (inf, nan)) + check(complex(-inf, nan), (inf, nan)) + check(complex(nan, inf), (inf, nan)) + check(complex(nan, -inf), (inf, nan)) def test_polar(self): - self.assertCISEqual(polar(0), (0., 0.)) - self.assertCISEqual(polar(1.), (1., 0.)) - self.assertCISEqual(polar(-1.), (1., pi)) - self.assertCISEqual(polar(1j), (1., pi/2)) - self.assertCISEqual(polar(-1j), (1., -pi/2)) + self.check_polar(polar) + + @cpython_only + def test_polar_errno(self): + # Issue #24489: check a previously set C errno doesn't disturb polar() + from _testcapi import set_errno + def polar_with_errno_set(z): + set_errno(11) + try: + return polar(z) + finally: + set_errno(0) + self.check_polar(polar_with_errno_set) def test_phase(self): self.assertAlmostEqual(phase(0), 0.) @@ -529,8 +561,46 @@ def testAtanhSign(self): self.assertComplexIdentical(cmath.atanh(z), z) -def test_main(): - run_unittest(CMathTests) +class IsCloseTests(test_math.IsCloseTests): + isclose = cmath.isclose + + def test_reject_complex_tolerances(self): + with self.assertRaises(TypeError): + self.isclose(1j, 1j, rel_tol=1j) + + with self.assertRaises(TypeError): + self.isclose(1j, 1j, abs_tol=1j) + + with self.assertRaises(TypeError): + self.isclose(1j, 1j, rel_tol=1j, abs_tol=1j) + + def test_complex_values(self): + # test complex values that are close to within 12 decimal places + complex_examples = [(1.0+1.0j, 1.000000000001+1.0j), + (1.0+1.0j, 1.0+1.000000000001j), + (-1.0+1.0j, -1.000000000001+1.0j), + (1.0-1.0j, 1.0-0.999999999999j), + ] + + self.assertAllClose(complex_examples, rel_tol=1e-12) + self.assertAllNotClose(complex_examples, rel_tol=1e-13) + + def test_complex_near_zero(self): + # test values near zero that are near to within three decimal places + near_zero_examples = [(0.001j, 0), + (0.001, 0), + (0.001+0.001j, 0), + (-0.001+0.001j, 0), + (0.001-0.001j, 0), + (-0.001-0.001j, 0), + ] + + self.assertAllClose(near_zero_examples, abs_tol=1.5e-03) + self.assertAllNotClose(near_zero_examples, abs_tol=0.5e-03) + + self.assertIsClose(0.001-0.001j, 0.001+0.001j, abs_tol=2e-03) + self.assertIsNotClose(0.001-0.001j, 0.001+0.001j, abs_tol=1e-03) + if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_cmd.py b/Lib/test/test_cmd.py index 661853582372..0c31454456d0 100644 --- a/Lib/test/test_cmd.py +++ b/Lib/test/test_cmd.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 """ Test script for the 'cmd' module Original by Michael Schneider @@ -230,7 +229,7 @@ def test_coverage(coverdir): trace = support.import_module('trace') tracer=trace.Trace(ignoredirs=[sys.base_prefix, sys.base_exec_prefix,], trace=0, count=1) - tracer.run('reload(cmd);test_main()') + tracer.run('import importlib; importlib.reload(cmd); test_main()') r=tracer.results() print("Writing coverage results...") r.write_results(show_missing=True, summary=True, coverdir=coverdir) diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 327c1455fcf7..0feb63fd4e09 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -8,7 +8,8 @@ import sys import subprocess import tempfile -from test.script_helper import (spawn_python, kill_python, assert_python_ok, +from test.support import script_helper +from test.support.script_helper import (spawn_python, kill_python, assert_python_ok, assert_python_failure) @@ -58,7 +59,7 @@ def test_verbose(self): def test_xoptions(self): def get_xoptions(*args): - # use subprocess module directly because test.script_helper adds + # use subprocess module directly because test.support.script_helper adds # "-X faulthandler" to the command line args = (sys.executable, '-E') + args args += ('-c', 'import sys; print(sys._xoptions)') @@ -270,7 +271,11 @@ def test_empty_PYTHONPATH_issue16309(self): def test_displayhook_unencodable(self): for encoding in ('ascii', 'latin-1', 'utf-8'): - env = os.environ.copy() + # We are testing a PYTHON environment variable here, so we can't + # use -E, -I, or script_helper (which uses them). So instead we do + # poor-man's isolation by deleting the PYTHON vars from env. + env = {key:value for (key,value) in os.environ.copy().items() + if not key.startswith('PYTHON')} env['PYTHONIOENCODING'] = encoding p = subprocess.Popen( [sys.executable, '-i'], @@ -339,7 +344,8 @@ def test_stdout_flush_at_shutdown(self): # Issue #5319: if stdout.flush() fails at shutdown, an error should # be printed out. code = """if 1: - import os, sys + import os, sys, test.support + test.support.SuppressCrashReport().__enter__() sys.stdout.write('x') os.close(sys.stdout.fileno())""" rc, out, err = assert_python_ok('-c', code) @@ -439,7 +445,8 @@ def test_unknown_options(self): self.assertEqual(err.splitlines().count(b'Unknown option: -a'), 1) self.assertEqual(b'', out) - + @unittest.skipIf(script_helper.interpreter_requires_environment(), + 'Cannot run -I tests when PYTHON env vars are required.') def test_isolatedmode(self): self.verify_valid_flag('-I') self.verify_valid_flag('-IEs') diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py index f804d8645f68..fda3e62bd6a1 100644 --- a/Lib/test/test_cmd_line_script.py +++ b/Lib/test/test_cmd_line_script.py @@ -1,5 +1,6 @@ # tests command line execution of scripts +import contextlib import importlib import importlib.machinery import zipimport @@ -8,13 +9,13 @@ import os import os.path import py_compile +import subprocess import textwrap from test import support -from test.script_helper import ( +from test.support.script_helper import ( make_pkg, make_script, make_zip_pkg, make_zip_script, - assert_python_ok, assert_python_failure, temp_dir, - spawn_python, kill_python) + assert_python_ok, assert_python_failure, spawn_python, kill_python) verbose = support.verbose @@ -41,11 +42,28 @@ def f(): _loader = __loader__ if __loader__ is BuiltinImporter else type(__loader__) print('__loader__==%a' % _loader) print('__file__==%a' % __file__) -assertEqual(__cached__, None) +print('__cached__==%a' % __cached__) print('__package__==%r' % __package__) +# Check PEP 451 details +import os.path +if __package__ is not None: + print('__main__ was located through the import system') + assertIdentical(__spec__.loader, __loader__) + expected_spec_name = os.path.splitext(os.path.basename(__file__))[0] + if __package__: + expected_spec_name = __package__ + "." + expected_spec_name + assertEqual(__spec__.name, expected_spec_name) + assertEqual(__spec__.parent, __package__) + assertIdentical(__spec__.submodule_search_locations, None) + assertEqual(__spec__.origin, __file__) + if __spec__.cached is not None: + assertEqual(__spec__.cached, __cached__) # Check the sys module import sys assertIdentical(globals(), sys.modules[__name__].__dict__) +if __spec__ is not None: + # XXX: We're not currently making __main__ available under its real name + pass # assertIdentical(globals(), sys.modules[__spec__.name].__dict__) from test import test_cmd_line_script example_args_list = test_cmd_line_script.example_args assertEqual(sys.argv[1:], example_args_list) @@ -95,7 +113,7 @@ def _check_output(self, script_name, exit_code, data, expected_loader): if verbose > 1: print("Output from test script %r:" % script_name) - print(data) + print(repr(data)) self.assertEqual(exit_code, 0) printed_loader = '__loader__==%a' % expected_loader printed_file = '__file__==%a' % expected_file @@ -134,7 +152,7 @@ def _check_import_error(self, script_name, expected_msg, rc, out, err = assert_python_failure(*run_args) if verbose > 1: print('Output from test script %r:' % script_name) - print(err) + print(repr(err)) print('Expected output: %r' % expected_msg) self.assertIn(expected_msg.encode('utf-8'), err) @@ -156,15 +174,62 @@ def test_stdin_loader(self): expected = repr(importlib.machinery.BuiltinImporter).encode("utf-8") self.assertIn(expected, out) + @contextlib.contextmanager + def interactive_python(self, separate_stderr=False): + if separate_stderr: + p = spawn_python('-i', bufsize=1, stderr=subprocess.PIPE) + stderr = p.stderr + else: + p = spawn_python('-i', bufsize=1, stderr=subprocess.STDOUT) + stderr = p.stdout + try: + # Drain stderr until prompt + while True: + data = stderr.read(4) + if data == b">>> ": + break + stderr.readline() + yield p + finally: + kill_python(p) + stderr.close() + + def check_repl_stdout_flush(self, separate_stderr=False): + with self.interactive_python(separate_stderr) as p: + p.stdin.write(b"print('foo')\n") + p.stdin.flush() + self.assertEqual(b'foo', p.stdout.readline().strip()) + + def check_repl_stderr_flush(self, separate_stderr=False): + with self.interactive_python(separate_stderr) as p: + p.stdin.write(b"1/0\n") + p.stdin.flush() + stderr = p.stderr if separate_stderr else p.stdout + self.assertIn(b'Traceback ', stderr.readline()) + self.assertIn(b'File ""', stderr.readline()) + self.assertIn(b'ZeroDivisionError', stderr.readline()) + + def test_repl_stdout_flush(self): + self.check_repl_stdout_flush() + + def test_repl_stdout_flush_separate_stderr(self): + self.check_repl_stdout_flush(True) + + def test_repl_stderr_flush(self): + self.check_repl_stderr_flush() + + def test_repl_stderr_flush_separate_stderr(self): + self.check_repl_stderr_flush(True) + def test_basic_script(self): - with temp_dir() as script_dir: + with support.temp_dir() as script_dir: script_name = _make_test_script(script_dir, 'script') self._check_script(script_name, script_name, script_name, script_dir, None, importlib.machinery.SourceFileLoader) def test_script_compiled(self): - with temp_dir() as script_dir: + with support.temp_dir() as script_dir: script_name = _make_test_script(script_dir, 'script') py_compile.compile(script_name, doraise=True) os.remove(script_name) @@ -174,14 +239,14 @@ def test_script_compiled(self): importlib.machinery.SourcelessFileLoader) def test_directory(self): - with temp_dir() as script_dir: + with support.temp_dir() as script_dir: script_name = _make_test_script(script_dir, '__main__') self._check_script(script_dir, script_name, script_dir, script_dir, '', importlib.machinery.SourceFileLoader) def test_directory_compiled(self): - with temp_dir() as script_dir: + with support.temp_dir() as script_dir: script_name = _make_test_script(script_dir, '__main__') py_compile.compile(script_name, doraise=True) os.remove(script_name) @@ -191,19 +256,19 @@ def test_directory_compiled(self): importlib.machinery.SourcelessFileLoader) def test_directory_error(self): - with temp_dir() as script_dir: + with support.temp_dir() as script_dir: msg = "can't find '__main__' module in %r" % script_dir self._check_import_error(script_dir, msg) def test_zipfile(self): - with temp_dir() as script_dir: + with support.temp_dir() as script_dir: script_name = _make_test_script(script_dir, '__main__') zip_name, run_name = make_zip_script(script_dir, 'test_zip', script_name) self._check_script(zip_name, run_name, zip_name, zip_name, '', zipimport.zipimporter) def test_zipfile_compiled(self): - with temp_dir() as script_dir: + with support.temp_dir() as script_dir: script_name = _make_test_script(script_dir, '__main__') compiled_name = py_compile.compile(script_name, doraise=True) zip_name, run_name = make_zip_script(script_dir, 'test_zip', compiled_name) @@ -211,14 +276,14 @@ def test_zipfile_compiled(self): zipimport.zipimporter) def test_zipfile_error(self): - with temp_dir() as script_dir: + with support.temp_dir() as script_dir: script_name = _make_test_script(script_dir, 'not_main') zip_name, run_name = make_zip_script(script_dir, 'test_zip', script_name) msg = "can't find '__main__' module in %r" % zip_name self._check_import_error(zip_name, msg) def test_module_in_package(self): - with temp_dir() as script_dir: + with support.temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') make_pkg(pkg_dir) script_name = _make_test_script(pkg_dir, 'script') @@ -228,14 +293,14 @@ def test_module_in_package(self): importlib.machinery.SourceFileLoader) def test_module_in_package_in_zipfile(self): - with temp_dir() as script_dir: + with support.temp_dir() as script_dir: zip_name, run_name = _make_test_zip_pkg(script_dir, 'test_zip', 'test_pkg', 'script') launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.script', zip_name) self._check_script(launch_name, run_name, run_name, zip_name, 'test_pkg', zipimport.zipimporter) def test_module_in_subpackage_in_zipfile(self): - with temp_dir() as script_dir: + with support.temp_dir() as script_dir: zip_name, run_name = _make_test_zip_pkg(script_dir, 'test_zip', 'test_pkg', 'script', depth=2) launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.test_pkg.script', zip_name) self._check_script(launch_name, run_name, run_name, @@ -243,7 +308,7 @@ def test_module_in_subpackage_in_zipfile(self): zipimport.zipimporter) def test_package(self): - with temp_dir() as script_dir: + with support.temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') make_pkg(pkg_dir) script_name = _make_test_script(pkg_dir, '__main__') @@ -253,7 +318,7 @@ def test_package(self): importlib.machinery.SourceFileLoader) def test_package_compiled(self): - with temp_dir() as script_dir: + with support.temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') make_pkg(pkg_dir) script_name = _make_test_script(pkg_dir, '__main__') @@ -266,7 +331,7 @@ def test_package_compiled(self): importlib.machinery.SourcelessFileLoader) def test_package_error(self): - with temp_dir() as script_dir: + with support.temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') make_pkg(pkg_dir) msg = ("'test_pkg' is a package and cannot " @@ -275,7 +340,7 @@ def test_package_error(self): self._check_import_error(launch_name, msg) def test_package_recursion(self): - with temp_dir() as script_dir: + with support.temp_dir() as script_dir: pkg_dir = os.path.join(script_dir, 'test_pkg') make_pkg(pkg_dir) main_dir = os.path.join(pkg_dir, '__main__') @@ -289,14 +354,14 @@ def test_package_recursion(self): def test_issue8202(self): # Make sure package __init__ modules see "-m" in sys.argv0 while # searching for the module to execute - with temp_dir() as script_dir: + with support.temp_dir() as script_dir: with support.change_cwd(path=script_dir): pkg_dir = os.path.join(script_dir, 'test_pkg') make_pkg(pkg_dir, "import sys; print('init_argv0==%r' % sys.argv[0])") script_name = _make_test_script(pkg_dir, 'script') rc, out, err = assert_python_ok('-m', 'test_pkg.script', *example_args, __isolated=False) if verbose > 1: - print(out) + print(repr(out)) expected = "init_argv0==%r" % '-m' self.assertIn(expected.encode('utf-8'), out) self._check_output(script_name, rc, out, @@ -306,7 +371,7 @@ def test_issue8202(self): def test_issue8202_dash_c_file_ignored(self): # Make sure a "-c" file in the current directory # does not alter the value of sys.path[0] - with temp_dir() as script_dir: + with support.temp_dir() as script_dir: with support.change_cwd(path=script_dir): with open("-c", "w") as f: f.write("data") @@ -314,14 +379,14 @@ def test_issue8202_dash_c_file_ignored(self): 'import sys; print("sys.path[0]==%r" % sys.path[0])', __isolated=False) if verbose > 1: - print(out) + print(repr(out)) expected = "sys.path[0]==%r" % '' self.assertIn(expected.encode('utf-8'), out) def test_issue8202_dash_m_file_ignored(self): # Make sure a "-m" file in the current directory # does not alter the value of sys.path[0] - with temp_dir() as script_dir: + with support.temp_dir() as script_dir: script_name = _make_test_script(script_dir, 'other') with support.change_cwd(path=script_dir): with open("-m", "w") as f: @@ -336,7 +401,7 @@ def test_dash_m_error_code_is_one(self): # If a module is invoked with the -m command line flag # and results in an error that the return code to the # shell is '1' - with temp_dir() as script_dir: + with support.temp_dir() as script_dir: with support.change_cwd(path=script_dir): pkg_dir = os.path.join(script_dir, 'test_pkg') make_pkg(pkg_dir) @@ -344,7 +409,7 @@ def test_dash_m_error_code_is_one(self): "if __name__ == '__main__': raise ValueError") rc, out, err = assert_python_failure('-m', 'test_pkg.other', *example_args) if verbose > 1: - print(out) + print(repr(out)) self.assertEqual(rc, 1) def test_pep_409_verbiage(self): @@ -356,7 +421,7 @@ def test_pep_409_verbiage(self): except: raise NameError from None """) - with temp_dir() as script_dir: + with support.temp_dir() as script_dir: script_name = _make_test_script(script_dir, 'script', script) exitcode, stdout, stderr = assert_python_failure(script_name) text = stderr.decode('ascii').split('\n') @@ -388,6 +453,24 @@ def test_non_ascii(self): 'stdout=%r stderr=%r' % (stdout, stderr)) self.assertEqual(0, rc) + def test_issue20500_exit_with_exception_value(self): + script = textwrap.dedent("""\ + import sys + error = None + try: + raise ValueError('some text') + except ValueError as err: + error = err + + if error: + sys.exit(error) + """) + with support.temp_dir() as script_dir: + script_name = _make_test_script(script_dir, 'script', script) + exitcode, stdout, stderr = assert_python_failure(script_name) + text = stderr.decode('ascii') + self.assertEqual(text, "some text") + def test_main(): support.run_unittest(CmdLineTest) diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index 3377a7b07a8c..21b12a56e4a8 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -104,7 +104,7 @@ import unittest import weakref -import _testcapi +from test.support import run_doctest, run_unittest, cpython_only def consts(t): @@ -126,7 +126,9 @@ def dump(co): class CodeTest(unittest.TestCase): + @cpython_only def test_newempty(self): + import _testcapi co = _testcapi.code_newempty("filename", "funcname", 15) self.assertEqual(co.co_filename, "filename") self.assertEqual(co.co_name, "funcname") @@ -159,7 +161,6 @@ def callback(code): def test_main(verbose=None): - from test.support import run_doctest, run_unittest from test import test_code run_doctest(test_code, verbose) run_unittest(CodeTest, CodeWeakRefTest) diff --git a/Lib/test/test_code_module.py b/Lib/test/test_code_module.py index 5fd21dc32c61..3394b39e01d8 100644 --- a/Lib/test/test_code_module.py +++ b/Lib/test/test_code_module.py @@ -1,6 +1,7 @@ "Test InteractiveConsole and InteractiveInterpreter from code module" import sys import unittest +from textwrap import dedent from contextlib import ExitStack from unittest import mock from test import support @@ -51,7 +52,7 @@ def test_syntax_error(self): self.infunc.side_effect = ["undefined", EOFError('Finished')] self.console.interact() for call in self.stderr.method_calls: - if 'NameError:' in ''.join(call[1]): + if 'NameError' in ''.join(call[1]): break else: raise AssertionError("No syntax error from console") @@ -78,9 +79,40 @@ def test_banner(self): self.console.interact(banner='') self.assertEqual(len(self.stderr.method_calls), 1) + def test_cause_tb(self): + self.infunc.side_effect = ["raise ValueError('') from AttributeError", + EOFError('Finished')] + self.console.interact() + output = ''.join(''.join(call[1]) for call in self.stderr.method_calls) + expected = dedent(""" + AttributeError + + The above exception was the direct cause of the following exception: + + Traceback (most recent call last): + File "", line 1, in + ValueError + """) + self.assertIn(expected, output) + + def test_context_tb(self): + self.infunc.side_effect = ["try: ham\nexcept: eggs\n", + EOFError('Finished')] + self.console.interact() + output = ''.join(''.join(call[1]) for call in self.stderr.method_calls) + expected = dedent(""" + Traceback (most recent call last): + File "", line 1, in + NameError: name 'ham' is not defined + + During handling of the above exception, another exception occurred: + + Traceback (most recent call last): + File "", line 2, in + NameError: name 'eggs' is not defined + """) + self.assertIn(expected, output) -def test_main(): - support.run_unittest(TestInteractiveConsole) if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_codeccallbacks.py b/Lib/test/test_codeccallbacks.py index 84804bb0dafa..ee1e28a763ca 100644 --- a/Lib/test/test_codeccallbacks.py +++ b/Lib/test/test_codeccallbacks.py @@ -6,14 +6,6 @@ import unittest import warnings -try: - import ctypes -except ImportError: - ctypes = None - SIZEOF_WCHAR_T = -1 -else: - SIZEOF_WCHAR_T = ctypes.sizeof(ctypes.c_wchar) - class PosReturn: # this can be used for configurable callbacks @@ -158,6 +150,22 @@ def test_backslashescape(self): sout = b"a\xac\\u1234\xa4\\u8000\\U0010ffff" self.assertEqual(sin.encode("iso-8859-15", "backslashreplace"), sout) + def test_nameescape(self): + # Does the same as backslashescape, but prefers ``\N{...}`` escape + # sequences. + sin = "a\xac\u1234\u20ac\u8000\U0010ffff" + sout = (b'a\\N{NOT SIGN}\\N{ETHIOPIC SYLLABLE SEE}\\N{EURO SIGN}' + b'\\N{CJK UNIFIED IDEOGRAPH-8000}\\U0010ffff') + self.assertEqual(sin.encode("ascii", "namereplace"), sout) + + sout = (b'a\xac\\N{ETHIOPIC SYLLABLE SEE}\\N{EURO SIGN}' + b'\\N{CJK UNIFIED IDEOGRAPH-8000}\\U0010ffff') + self.assertEqual(sin.encode("latin-1", "namereplace"), sout) + + sout = (b'a\xac\\N{ETHIOPIC SYLLABLE SEE}\xa4' + b'\\N{CJK UNIFIED IDEOGRAPH-8000}\\U0010ffff') + self.assertEqual(sin.encode("iso-8859-15", "namereplace"), sout) + def test_decoding_callbacks(self): # This is a test for a decoding callback handler # that allows the decoding of the invalid sequence @@ -212,14 +220,12 @@ def test_decodeunicodeinternal(self): b"\x00\x00\x00\x00\x00".decode, "unicode-internal", ) - if SIZEOF_WCHAR_T == 4: - def handler_unicodeinternal(exc): - if not isinstance(exc, UnicodeDecodeError): - raise TypeError("don't know how to handle %r" % exc) - return ("\x01", 1) - - with test.support.check_warnings(('unicode_internal codec has been ' - 'deprecated', DeprecationWarning)): + if len('\0'.encode('unicode-internal')) == 4: + def handler_unicodeinternal(exc): + if not isinstance(exc, UnicodeDecodeError): + raise TypeError("don't know how to handle %r" % exc) + return ("\x01", 1) + self.assertEqual( b"\x00\x00\x00\x00\x00".decode("unicode-internal", "ignore"), "\u0000" @@ -230,6 +236,11 @@ def handler_unicodeinternal(exc): "\u0000\ufffd" ) + self.assertEqual( + b"\x00\x00\x00\x00\x00".decode("unicode-internal", "backslashreplace"), + "\u0000\\x00" + ) + codecs.register_error("test.hui", handler_unicodeinternal) self.assertEqual( @@ -297,7 +308,7 @@ def handler2(exc): def test_longstrings(self): # test long strings to check for memory overflow problems errors = [ "strict", "ignore", "replace", "xmlcharrefreplace", - "backslashreplace"] + "backslashreplace", "namereplace"] # register the handlers under different names, # to prevent the codec from recognizing the name for err in errors: @@ -364,12 +375,11 @@ def test_unicodeencodeerror(self): ["ascii", "\uffffx", 0, 1, "ouch"], "'ascii' codec can't encode character '\\uffff' in position 0: ouch" ) - if SIZEOF_WCHAR_T == 4: - self.check_exceptionobjectargs( - UnicodeEncodeError, - ["ascii", "\U00010000x", 0, 1, "ouch"], - "'ascii' codec can't encode character '\\U00010000' in position 0: ouch" - ) + self.check_exceptionobjectargs( + UnicodeEncodeError, + ["ascii", "\U00010000x", 0, 1, "ouch"], + "'ascii' codec can't encode character '\\U00010000' in position 0: ouch" + ) def test_unicodedecodeerror(self): self.check_exceptionobjectargs( @@ -399,12 +409,11 @@ def test_unicodetranslateerror(self): ["g\uffffrk", 1, 2, "ouch"], "can't translate character '\\uffff' in position 1: ouch" ) - if SIZEOF_WCHAR_T == 4: - self.check_exceptionobjectargs( - UnicodeTranslateError, - ["g\U00010000rk", 1, 2, "ouch"], - "can't translate character '\\U00010000' in position 1: ouch" - ) + self.check_exceptionobjectargs( + UnicodeTranslateError, + ["g\U00010000rk", 1, 2, "ouch"], + "can't translate character '\\U00010000' in position 1: ouch" + ) self.check_exceptionobjectargs( UnicodeTranslateError, ["g\xfcrk", 1, 3, "ouch"], @@ -431,6 +440,16 @@ def test_badandgoodstrictexceptions(self): codecs.strict_errors, UnicodeEncodeError("ascii", "\u3042", 0, 1, "ouch") ) + self.assertRaises( + UnicodeDecodeError, + codecs.strict_errors, + UnicodeDecodeError("ascii", bytearray(b"\xff"), 0, 1, "ouch") + ) + self.assertRaises( + UnicodeTranslateError, + codecs.strict_errors, + UnicodeTranslateError("\u3042", 0, 1, "ouch") + ) def test_badandgoodignoreexceptions(self): # "ignore" complains about a non-exception passed in @@ -448,18 +467,18 @@ def test_badandgoodignoreexceptions(self): # If the correct exception is passed in, "ignore" returns an empty replacement self.assertEqual( codecs.ignore_errors( - UnicodeEncodeError("ascii", "\u3042", 0, 1, "ouch")), - ("", 1) + UnicodeEncodeError("ascii", "a\u3042b", 1, 2, "ouch")), + ("", 2) ) self.assertEqual( codecs.ignore_errors( - UnicodeDecodeError("ascii", bytearray(b"\xff"), 0, 1, "ouch")), - ("", 1) + UnicodeDecodeError("ascii", bytearray(b"a\xffb"), 1, 2, "ouch")), + ("", 2) ) self.assertEqual( codecs.ignore_errors( - UnicodeTranslateError("\u3042", 0, 1, "ouch")), - ("", 1) + UnicodeTranslateError("a\u3042b", 1, 2, "ouch")), + ("", 2) ) def test_badandgoodreplaceexceptions(self): @@ -488,18 +507,18 @@ def test_badandgoodreplaceexceptions(self): # With the correct exception, "replace" returns an "?" or "\ufffd" replacement self.assertEqual( codecs.replace_errors( - UnicodeEncodeError("ascii", "\u3042", 0, 1, "ouch")), - ("?", 1) + UnicodeEncodeError("ascii", "a\u3042b", 1, 2, "ouch")), + ("?", 2) ) self.assertEqual( codecs.replace_errors( - UnicodeDecodeError("ascii", bytearray(b"\xff"), 0, 1, "ouch")), - ("\ufffd", 1) + UnicodeDecodeError("ascii", bytearray(b"a\xffb"), 1, 2, "ouch")), + ("\ufffd", 2) ) self.assertEqual( codecs.replace_errors( - UnicodeTranslateError("\u3042", 0, 1, "ouch")), - ("\ufffd", 1) + UnicodeTranslateError("a\u3042b", 1, 2, "ouch")), + ("\ufffd", 2) ) def test_badandgoodxmlcharrefreplaceexceptions(self): @@ -527,13 +546,16 @@ def test_badandgoodxmlcharrefreplaceexceptions(self): UnicodeTranslateError("\u3042", 0, 1, "ouch") ) # Use the correct exception - cs = (0, 1, 9, 10, 99, 100, 999, 1000, 9999, 10000, 0x3042) + cs = (0, 1, 9, 10, 99, 100, 999, 1000, 9999, 10000, 99999, 100000, + 999999, 1000000) + cs += (0xd800, 0xdfff) s = "".join(chr(c) for c in cs) self.assertEqual( codecs.xmlcharrefreplace_errors( - UnicodeEncodeError("ascii", s, 0, len(s), "ouch") + UnicodeEncodeError("ascii", "a" + s + "b", + 1, 1 + len(s), "ouch") ), - ("".join("&#%d;" % ord(c) for c in s), len(s)) + ("".join("&#%d;" % c for c in cs), 1 + len(s)) ) def test_badandgoodbackslashreplaceexceptions(self): @@ -549,67 +571,212 @@ def test_badandgoodbackslashreplaceexceptions(self): codecs.backslashreplace_errors, UnicodeError("ouch") ) - # "backslashreplace" can only be used for encoding + # Use the correct exception + tests = [ + ("\u3042", "\\u3042"), + ("\n", "\\x0a"), + ("a", "\\x61"), + ("\x00", "\\x00"), + ("\xff", "\\xff"), + ("\u0100", "\\u0100"), + ("\uffff", "\\uffff"), + ("\U00010000", "\\U00010000"), + ("\U0010ffff", "\\U0010ffff"), + # Lone surrogates + ("\ud800", "\\ud800"), + ("\udfff", "\\udfff"), + ("\ud800\udfff", "\\ud800\\udfff"), + ] + for s, r in tests: + with self.subTest(str=s): + self.assertEqual( + codecs.backslashreplace_errors( + UnicodeEncodeError("ascii", "a" + s + "b", + 1, 1 + len(s), "ouch")), + (r, 1 + len(s)) + ) + self.assertEqual( + codecs.backslashreplace_errors( + UnicodeTranslateError("a" + s + "b", + 1, 1 + len(s), "ouch")), + (r, 1 + len(s)) + ) + tests = [ + (b"a", "\\x61"), + (b"\n", "\\x0a"), + (b"\x00", "\\x00"), + (b"\xff", "\\xff"), + ] + for b, r in tests: + with self.subTest(bytes=b): + self.assertEqual( + codecs.backslashreplace_errors( + UnicodeDecodeError("ascii", bytearray(b"a" + b + b"b"), + 1, 2, "ouch")), + (r, 2) + ) + + def test_badandgoodnamereplaceexceptions(self): + # "namereplace" complains about a non-exception passed in + self.assertRaises( + TypeError, + codecs.namereplace_errors, + 42 + ) + # "namereplace" complains about the wrong exception types + self.assertRaises( + TypeError, + codecs.namereplace_errors, + UnicodeError("ouch") + ) + # "namereplace" can only be used for encoding self.assertRaises( TypeError, - codecs.backslashreplace_errors, + codecs.namereplace_errors, UnicodeDecodeError("ascii", bytearray(b"\xff"), 0, 1, "ouch") ) self.assertRaises( TypeError, - codecs.backslashreplace_errors, + codecs.namereplace_errors, UnicodeTranslateError("\u3042", 0, 1, "ouch") ) # Use the correct exception - self.assertEqual( - codecs.backslashreplace_errors( - UnicodeEncodeError("ascii", "\u3042", 0, 1, "ouch")), - ("\\u3042", 1) + tests = [ + ("\u3042", "\\N{HIRAGANA LETTER A}"), + ("\x00", "\\x00"), + ("\ufbf9", "\\N{ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH " + "HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM}"), + ("\U000e007f", "\\N{CANCEL TAG}"), + ("\U0010ffff", "\\U0010ffff"), + # Lone surrogates + ("\ud800", "\\ud800"), + ("\udfff", "\\udfff"), + ("\ud800\udfff", "\\ud800\\udfff"), + ] + for s, r in tests: + with self.subTest(str=s): + self.assertEqual( + codecs.namereplace_errors( + UnicodeEncodeError("ascii", "a" + s + "b", + 1, 1 + len(s), "ouch")), + (r, 1 + len(s)) + ) + + def test_badandgoodsurrogateescapeexceptions(self): + surrogateescape_errors = codecs.lookup_error('surrogateescape') + # "surrogateescape" complains about a non-exception passed in + self.assertRaises( + TypeError, + surrogateescape_errors, + 42 ) - self.assertEqual( - codecs.backslashreplace_errors( - UnicodeEncodeError("ascii", "\x00", 0, 1, "ouch")), - ("\\x00", 1) + # "surrogateescape" complains about the wrong exception types + self.assertRaises( + TypeError, + surrogateescape_errors, + UnicodeError("ouch") ) - self.assertEqual( - codecs.backslashreplace_errors( - UnicodeEncodeError("ascii", "\xff", 0, 1, "ouch")), - ("\\xff", 1) + # "surrogateescape" can not be used for translating + self.assertRaises( + TypeError, + surrogateescape_errors, + UnicodeTranslateError("\udc80", 0, 1, "ouch") ) + # Use the correct exception + for s in ("a", "\udc7f", "\udd00"): + with self.subTest(str=s): + self.assertRaises( + UnicodeEncodeError, + surrogateescape_errors, + UnicodeEncodeError("ascii", s, 0, 1, "ouch") + ) self.assertEqual( - codecs.backslashreplace_errors( - UnicodeEncodeError("ascii", "\u0100", 0, 1, "ouch")), - ("\\u0100", 1) + surrogateescape_errors( + UnicodeEncodeError("ascii", "a\udc80b", 1, 2, "ouch")), + (b"\x80", 2) + ) + self.assertRaises( + UnicodeDecodeError, + surrogateescape_errors, + UnicodeDecodeError("ascii", bytearray(b"a"), 0, 1, "ouch") ) self.assertEqual( - codecs.backslashreplace_errors( - UnicodeEncodeError("ascii", "\uffff", 0, 1, "ouch")), - ("\\uffff", 1) - ) - if SIZEOF_WCHAR_T > 0: - self.assertEqual( - codecs.backslashreplace_errors( - UnicodeEncodeError("ascii", "\U00010000", - 0, 1, "ouch")), - ("\\U00010000", 1) - ) - self.assertEqual( - codecs.backslashreplace_errors( - UnicodeEncodeError("ascii", "\U0010ffff", - 0, 1, "ouch")), - ("\\U0010ffff", 1) - ) - # Lone surrogates (regardless of unicode width) - self.assertEqual( - codecs.backslashreplace_errors( - UnicodeEncodeError("ascii", "\ud800", 0, 1, "ouch")), - ("\\ud800", 1) - ) - self.assertEqual( - codecs.backslashreplace_errors( - UnicodeEncodeError("ascii", "\udfff", 0, 1, "ouch")), - ("\\udfff", 1) - ) + surrogateescape_errors( + UnicodeDecodeError("ascii", bytearray(b"a\x80b"), 1, 2, "ouch")), + ("\udc80", 2) + ) + + def test_badandgoodsurrogatepassexceptions(self): + surrogatepass_errors = codecs.lookup_error('surrogatepass') + # "surrogatepass" complains about a non-exception passed in + self.assertRaises( + TypeError, + surrogatepass_errors, + 42 + ) + # "surrogatepass" complains about the wrong exception types + self.assertRaises( + TypeError, + surrogatepass_errors, + UnicodeError("ouch") + ) + # "surrogatepass" can not be used for translating + self.assertRaises( + TypeError, + surrogatepass_errors, + UnicodeTranslateError("\ud800", 0, 1, "ouch") + ) + # Use the correct exception + for enc in ("utf-8", "utf-16le", "utf-16be", "utf-32le", "utf-32be"): + with self.subTest(encoding=enc): + self.assertRaises( + UnicodeEncodeError, + surrogatepass_errors, + UnicodeEncodeError(enc, "a", 0, 1, "ouch") + ) + self.assertRaises( + UnicodeDecodeError, + surrogatepass_errors, + UnicodeDecodeError(enc, "a".encode(enc), 0, 1, "ouch") + ) + for s in ("\ud800", "\udfff", "\ud800\udfff"): + with self.subTest(str=s): + self.assertRaises( + UnicodeEncodeError, + surrogatepass_errors, + UnicodeEncodeError("ascii", s, 0, len(s), "ouch") + ) + tests = [ + ("utf-8", "\ud800", b'\xed\xa0\x80', 3), + ("utf-16le", "\ud800", b'\x00\xd8', 2), + ("utf-16be", "\ud800", b'\xd8\x00', 2), + ("utf-32le", "\ud800", b'\x00\xd8\x00\x00', 4), + ("utf-32be", "\ud800", b'\x00\x00\xd8\x00', 4), + ("utf-8", "\udfff", b'\xed\xbf\xbf', 3), + ("utf-16le", "\udfff", b'\xff\xdf', 2), + ("utf-16be", "\udfff", b'\xdf\xff', 2), + ("utf-32le", "\udfff", b'\xff\xdf\x00\x00', 4), + ("utf-32be", "\udfff", b'\x00\x00\xdf\xff', 4), + ("utf-8", "\ud800\udfff", b'\xed\xa0\x80\xed\xbf\xbf', 3), + ("utf-16le", "\ud800\udfff", b'\x00\xd8\xff\xdf', 2), + ("utf-16be", "\ud800\udfff", b'\xd8\x00\xdf\xff', 2), + ("utf-32le", "\ud800\udfff", b'\x00\xd8\x00\x00\xff\xdf\x00\x00', 4), + ("utf-32be", "\ud800\udfff", b'\x00\x00\xd8\x00\x00\x00\xdf\xff', 4), + ] + for enc, s, b, n in tests: + with self.subTest(encoding=enc, str=s, bytes=b): + self.assertEqual( + surrogatepass_errors( + UnicodeEncodeError(enc, "a" + s + "b", + 1, 1 + len(s), "ouch")), + (b, 1 + len(s)) + ) + self.assertEqual( + surrogatepass_errors( + UnicodeDecodeError(enc, bytearray(b"a" + b[:n] + b"b"), + 1, 1 + n, "ouch")), + (s[:1], 1 + n) + ) def test_badhandlerresults(self): results = ( 42, "foo", (1,2,3), ("foo", 1, 3), ("foo", None), ("foo",), ("foo", 1, 3), ("foo", None), ("foo",) ) @@ -651,6 +818,10 @@ def test_lookup(self): codecs.backslashreplace_errors, codecs.lookup_error("backslashreplace") ) + self.assertEqual( + codecs.namereplace_errors, + codecs.lookup_error("namereplace") + ) def test_unencodablereplacement(self): def unencrepl(exc): @@ -688,9 +859,8 @@ def test_xmlcharrefvalues(self): # enhance coverage of: # Python/codecs.c::PyCodec_XMLCharRefReplaceErrors() # and inline implementations - v = (1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000) - if SIZEOF_WCHAR_T == 4: - v += (100000, 500000, 1000000) + v = (1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000, 100000, + 500000, 1000000) s = "".join([chr(x) for x in v]) codecs.register_error("test.xmlcharrefreplace", codecs.xmlcharrefreplace_errors) for enc in ("ascii", "iso-8859-15"): @@ -804,7 +974,8 @@ def badencodereturn2(exc): class D(dict): def __getitem__(self, key): raise ValueError - for err in ("strict", "replace", "xmlcharrefreplace", "backslashreplace", "test.posreturn"): + for err in ("strict", "replace", "xmlcharrefreplace", + "backslashreplace", "namereplace", "test.posreturn"): self.assertRaises(UnicodeError, codecs.charmap_encode, "\xff", err, {0xff: None}) self.assertRaises(ValueError, codecs.charmap_encode, "\xff", err, D()) self.assertRaises(TypeError, codecs.charmap_encode, "\xff", err, {0xff: 300}) @@ -819,7 +990,7 @@ class D(dict): def __getitem__(self, key): raise ValueError #self.assertRaises(ValueError, "\xff".translate, D()) - self.assertRaises(TypeError, "\xff".translate, {0xff: sys.maxunicode+1}) + self.assertRaises(ValueError, "\xff".translate, {0xff: sys.maxunicode+1}) self.assertRaises(TypeError, "\xff".translate, {0xff: ()}) def test_bug828737(self): @@ -875,6 +1046,30 @@ def mutating(exc): with self.assertRaises(TypeError): data.decode(encoding, "test.replacing") + def test_fake_error_class(self): + handlers = [ + codecs.strict_errors, + codecs.ignore_errors, + codecs.replace_errors, + codecs.backslashreplace_errors, + codecs.namereplace_errors, + codecs.xmlcharrefreplace_errors, + codecs.lookup_error('surrogateescape'), + codecs.lookup_error('surrogatepass'), + ] + for cls in UnicodeEncodeError, UnicodeDecodeError, UnicodeTranslateError: + class FakeUnicodeError(str): + __class__ = cls + for handler in handlers: + with self.subTest(handler=handler, error_class=cls): + self.assertRaises(TypeError, handler, FakeUnicodeError()) + class FakeUnicodeError(Exception): + __class__ = cls + for handler in handlers: + with self.subTest(handler=handler, error_class=cls): + with self.assertRaises((TypeError, FakeUnicodeError)): + handler(FakeUnicodeError()) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_codecencodings_cn.py b/Lib/test/test_codecencodings_cn.py index b08c5fcb1a7f..d0e3a15d1623 100644 --- a/Lib/test/test_codecencodings_cn.py +++ b/Lib/test/test_codecencodings_cn.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_codecencodings_cn.py # Codec encoding tests for PRC encodings. @@ -84,8 +83,5 @@ class Test_HZ(multibytecodec_support.TestBase, unittest.TestCase): (b"ab~{\x79\x79\x41\x44~}cd", "replace", "ab\ufffd\ufffd\u804acd"), ) -def test_main(): - support.run_unittest(__name__) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_codecencodings_hk.py b/Lib/test/test_codecencodings_hk.py index 31363f4bea87..bb9be1118434 100644 --- a/Lib/test/test_codecencodings_hk.py +++ b/Lib/test/test_codecencodings_hk.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_codecencodings_hk.py # Codec encoding tests for HongKong encodings. @@ -20,8 +19,5 @@ class Test_Big5HKSCS(multibytecodec_support.TestBase, unittest.TestCase): (b"abc\x80\x80\xc1\xc4", "ignore", "abc\u8b10"), ) -def test_main(): - support.run_unittest(__name__) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_codecencodings_iso2022.py b/Lib/test/test_codecencodings_iso2022.py index e4c1839b4267..8a3ca70de6fa 100644 --- a/Lib/test/test_codecencodings_iso2022.py +++ b/Lib/test/test_codecencodings_iso2022.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python -# # Codec encoding tests for ISO 2022 encodings. from test import support @@ -36,11 +34,9 @@ class Test_ISO2022_KR(multibytecodec_support.TestBase, unittest.TestCase): # iso2022_kr.txt cannot be used to test "chunk coding": the escape # sequence is only written on the first line + @unittest.skip('iso2022_kr.txt cannot be used to test "chunk coding"') def test_chunkcoding(self): pass -def test_main(): - support.run_unittest(__name__) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_codecencodings_jp.py b/Lib/test/test_codecencodings_jp.py index 30c9e195f317..44b63a00c8b4 100644 --- a/Lib/test/test_codecencodings_jp.py +++ b/Lib/test/test_codecencodings_jp.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_codecencodings_jp.py # Codec encoding tests for Japanese encodings. @@ -124,8 +123,5 @@ class Test_SJISX0213(multibytecodec_support.TestBase, unittest.TestCase): b"\x85Gℜ\x85Q = ⟨ሴ⟩" ) -def test_main(): - support.run_unittest(__name__) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_codecencodings_kr.py b/Lib/test/test_codecencodings_kr.py index 4dd60499c87f..b6a74fbd5bfd 100644 --- a/Lib/test/test_codecencodings_kr.py +++ b/Lib/test/test_codecencodings_kr.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_codecencodings_kr.py # Codec encoding tests for ROK encodings. @@ -67,8 +66,5 @@ class Test_JOHAB(multibytecodec_support.TestBase, unittest.TestCase): (b"\x8CBxy", "replace", "\uFFFDBxy"), ) -def test_main(): - support.run_unittest(__name__) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_codecencodings_tw.py b/Lib/test/test_codecencodings_tw.py index 96245b74ed34..917429672679 100644 --- a/Lib/test/test_codecencodings_tw.py +++ b/Lib/test/test_codecencodings_tw.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_codecencodings_tw.py # Codec encoding tests for ROC encodings. @@ -20,8 +19,5 @@ class Test_Big5(multibytecodec_support.TestBase, unittest.TestCase): (b"abc\x80\x80\xc1\xc4", "ignore", "abc\u8b10"), ) -def test_main(): - support.run_unittest(__name__) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_codecmaps_cn.py b/Lib/test/test_codecmaps_cn.py index 1a761cffc763..f1bd3840c9ab 100644 --- a/Lib/test/test_codecmaps_cn.py +++ b/Lib/test/test_codecmaps_cn.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_codecmaps_cn.py # Codec mapping tests for PRC encodings @@ -11,23 +10,18 @@ class TestGB2312Map(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'gb2312' - mapfileurl = 'http://people.freebsd.org/~perky/i18n/EUC-CN.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/EUC-CN.TXT' class TestGBKMap(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'gbk' - mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/VENDORS/' \ - 'MICSFT/WINDOWS/CP936.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/CP936.TXT' class TestGB18030Map(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'gb18030' - mapfileurl = 'http://source.icu-project.org/repos/icu/data/' \ - 'trunk/charset/data/xml/gb-18030-2000.xml' + mapfileurl = 'http://www.pythontest.net/unicode/gb-18030-2000.xml' -def test_main(): - support.run_unittest(__name__) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_codecmaps_hk.py b/Lib/test/test_codecmaps_hk.py index 5f4e7c7e0201..4c0c4156da9d 100644 --- a/Lib/test/test_codecmaps_hk.py +++ b/Lib/test/test_codecmaps_hk.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_codecmaps_hk.py # Codec mapping tests for HongKong encodings @@ -11,11 +10,7 @@ class TestBig5HKSCSMap(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'big5hkscs' - mapfileurl = 'http://people.freebsd.org/~perky/i18n/BIG5HKSCS-2004.TXT' - -def test_main(): - support.run_unittest(__name__) + mapfileurl = 'http://www.pythontest.net/unicode/BIG5HKSCS-2004.TXT' if __name__ == "__main__": - support.use_resources = ['urlfetch'] - test_main() + unittest.main() diff --git a/Lib/test/test_codecmaps_jp.py b/Lib/test/test_codecmaps_jp.py index 1fdbf634e3ac..577382329a90 100644 --- a/Lib/test/test_codecmaps_jp.py +++ b/Lib/test/test_codecmaps_jp.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_codecmaps_jp.py # Codec mapping tests for Japanese encodings @@ -11,8 +10,7 @@ class TestCP932Map(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'cp932' - mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/' \ - 'WINDOWS/CP932.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/CP932.TXT' supmaps = [ (b'\x80', '\u0080'), (b'\xa0', '\uf8f0'), @@ -28,15 +26,14 @@ class TestEUCJPCOMPATMap(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'euc_jp' mapfilename = 'EUC-JP.TXT' - mapfileurl = 'http://people.freebsd.org/~perky/i18n/EUC-JP.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/EUC-JP.TXT' class TestSJISCOMPATMap(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'shift_jis' mapfilename = 'SHIFTJIS.TXT' - mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/OBSOLETE' \ - '/EASTASIA/JIS/SHIFTJIS.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/SHIFTJIS.TXT' pass_enctest = [ (b'\x81_', '\\'), ] @@ -50,18 +47,15 @@ class TestEUCJISX0213Map(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'euc_jisx0213' mapfilename = 'EUC-JISX0213.TXT' - mapfileurl = 'http://people.freebsd.org/~perky/i18n/EUC-JISX0213.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/EUC-JISX0213.TXT' class TestSJISX0213Map(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'shift_jisx0213' mapfilename = 'SHIFT_JISX0213.TXT' - mapfileurl = 'http://people.freebsd.org/~perky/i18n/SHIFT_JISX0213.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/SHIFT_JISX0213.TXT' -def test_main(): - support.run_unittest(__name__) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_codecmaps_kr.py b/Lib/test/test_codecmaps_kr.py index 03564025ed25..6cb41c8b290d 100644 --- a/Lib/test/test_codecmaps_kr.py +++ b/Lib/test/test_codecmaps_kr.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_codecmaps_kr.py # Codec mapping tests for ROK encodings @@ -11,14 +10,13 @@ class TestCP949Map(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'cp949' - mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT' \ - '/WINDOWS/CP949.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/CP949.TXT' class TestEUCKRMap(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'euc_kr' - mapfileurl = 'http://people.freebsd.org/~perky/i18n/EUC-KR.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/EUC-KR.TXT' # A4D4 HANGUL FILLER indicates the begin of 8-bytes make-up sequence. pass_enctest = [(b'\xa4\xd4', '\u3164')] @@ -28,8 +26,7 @@ class TestEUCKRMap(multibytecodec_support.TestBase_Mapping, class TestJOHABMap(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'johab' - mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/' \ - 'KSC/JOHAB.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/JOHAB.TXT' # KS X 1001 standard assigned 0x5c as WON SIGN. # but, in early 90s that is the only era used johab widely, # the most softwares implements it as REVERSE SOLIDUS. @@ -37,8 +34,5 @@ class TestJOHABMap(multibytecodec_support.TestBase_Mapping, pass_enctest = [(b'\\', '\u20a9')] pass_dectest = [(b'\\', '\u20a9')] -def test_main(): - support.run_unittest(__name__) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_codecmaps_tw.py b/Lib/test/test_codecmaps_tw.py index 44467e378a72..2ea44b56f1f6 100644 --- a/Lib/test/test_codecmaps_tw.py +++ b/Lib/test/test_codecmaps_tw.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 # # test_codecmaps_tw.py # Codec mapping tests for ROC encodings @@ -11,14 +10,12 @@ class TestBIG5Map(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'big5' - mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/OBSOLETE/' \ - 'EASTASIA/OTHER/BIG5.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/BIG5.TXT' class TestCP950Map(multibytecodec_support.TestBase_Mapping, unittest.TestCase): encoding = 'cp950' - mapfileurl = 'http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/' \ - 'WINDOWS/CP950.TXT' + mapfileurl = 'http://www.pythontest.net/unicode/CP950.TXT' pass_enctest = [ (b'\xa2\xcc', '\u5341'), (b'\xa2\xce', '\u5345'), @@ -27,8 +24,5 @@ class TestCP950Map(multibytecodec_support.TestBase_Mapping, (b"\xFFxy", "replace", "\ufffdxy"), ) -def test_main(): - support.run_unittest(__name__) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index f6823805feec..ff314b10fbdd 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -1,4 +1,3 @@ -import _testcapi import codecs import contextlib import io @@ -28,6 +27,7 @@ def check(input, expect): self.assertEqual(coder(input), (expect, len(input))) return check + class Queue(object): """ queue: write bytes at one end, read bytes from the other end @@ -48,6 +48,7 @@ def read(self, size=-1): self._buffer = self._buffer[size:] return s + class MixInCheckStateHandling: def check_state_handling_decode(self, encoding, u, s): for i in range(len(s)+1): @@ -81,6 +82,7 @@ def check_state_handling_encode(self, encoding, u, s): part2 = d.encode(u[i:], True) self.assertEqual(s, part1+part2) + class ReadTest(MixInCheckStateHandling): def check_partial(self, input, partialresults): # get a StreamReader for the encoding and feed the bytestring version @@ -148,19 +150,20 @@ def readalllines(input, keepends=True, size=None): self.assertEqual(readalllines(s, True, 10), sexpected) self.assertEqual(readalllines(s, False, 10), sexpectednoends) + lineends = ("\n", "\r\n", "\r", "\u2028") # Test long lines (multiple calls to read() in readline()) vw = [] vwo = [] - for (i, lineend) in enumerate("\n \r\n \r \u2028".split()): - vw.append((i*200)*"\3042" + lineend) - vwo.append((i*200)*"\3042") - self.assertEqual(readalllines("".join(vw), True), "".join(vw)) - self.assertEqual(readalllines("".join(vw), False),"".join(vwo)) + for (i, lineend) in enumerate(lineends): + vw.append((i*200+200)*"\u3042" + lineend) + vwo.append((i*200+200)*"\u3042") + self.assertEqual(readalllines("".join(vw), True), "|".join(vw)) + self.assertEqual(readalllines("".join(vw), False), "|".join(vwo)) # Test lines where the first read might end with \r, so the # reader has to look ahead whether this is a lone \r or a \r\n for size in range(80): - for lineend in "\n \r\n \r \u2028".split(): + for lineend in lineends: s = 10*(size*"a" + lineend + "xxx\n") reader = getreader(s) for i in range(10): @@ -168,12 +171,54 @@ def readalllines(input, keepends=True, size=None): reader.readline(keepends=True), size*"a" + lineend, ) + self.assertEqual( + reader.readline(keepends=True), + "xxx\n", + ) reader = getreader(s) for i in range(10): self.assertEqual( reader.readline(keepends=False), size*"a", ) + self.assertEqual( + reader.readline(keepends=False), + "xxx", + ) + + def test_mixed_readline_and_read(self): + lines = ["Humpty Dumpty sat on a wall,\n", + "Humpty Dumpty had a great fall.\r\n", + "All the king's horses and all the king's men\r", + "Couldn't put Humpty together again."] + data = ''.join(lines) + def getreader(): + stream = io.BytesIO(data.encode(self.encoding)) + return codecs.getreader(self.encoding)(stream) + + # Issue #8260: Test readline() followed by read() + f = getreader() + self.assertEqual(f.readline(), lines[0]) + self.assertEqual(f.read(), ''.join(lines[1:])) + self.assertEqual(f.read(), '') + + # Issue #16636: Test readline() followed by readlines() + f = getreader() + self.assertEqual(f.readline(), lines[0]) + self.assertEqual(f.readlines(), lines[1:]) + self.assertEqual(f.read(), '') + + # Test read() followed by read() + f = getreader() + self.assertEqual(f.read(size=40, chars=5), data[:5]) + self.assertEqual(f.read(), data[5:]) + self.assertEqual(f.read(), '') + + # Issue #12446: Test read() followed by readlines() + f = getreader() + self.assertEqual(f.read(size=40, chars=5), data[:5]) + self.assertEqual(f.readlines(), [lines[0][5:]] + lines[1:]) + self.assertEqual(f.read(), '') def test_bug1175396(self): s = [ @@ -307,6 +352,8 @@ def test_lone_surrogates(self): self.assertRaises(UnicodeEncodeError, "\ud800".encode, self.encoding) self.assertEqual("[\uDC80]".encode(self.encoding, "backslashreplace"), "[\\udc80]".encode(self.encoding)) + self.assertEqual("[\uDC80]".encode(self.encoding, "namereplace"), + "[\\udc80]".encode(self.encoding)) self.assertEqual("[\uDC80]".encode(self.encoding, "xmlcharrefreplace"), "[�]".encode(self.encoding)) self.assertEqual("[\uDC80]".encode(self.encoding, "ignore"), @@ -314,6 +361,12 @@ def test_lone_surrogates(self): self.assertEqual("[\uDC80]".encode(self.encoding, "replace"), "[?]".encode(self.encoding)) + # sequential surrogate characters + self.assertEqual("[\uD800\uDC80]".encode(self.encoding, "ignore"), + "[]".encode(self.encoding)) + self.assertEqual("[\uD800\uDC80]".encode(self.encoding, "replace"), + "[??]".encode(self.encoding)) + bom = "".encode(self.encoding) for before, after in [("\U00010fff", "A"), ("[", "]"), ("A", "\U00010fff")]: @@ -334,6 +387,11 @@ def test_lone_surrogates(self): before + after) self.assertEqual(test_sequence.decode(self.encoding, "replace"), before + self.ill_formed_sequence_replace + after) + backslashreplace = ''.join('\\x%02x' % b + for b in self.ill_formed_sequence) + self.assertEqual(test_sequence.decode(self.encoding, "backslashreplace"), + before + backslashreplace + after) + class UTF32Test(ReadTest, unittest.TestCase): encoding = "utf-32" @@ -430,6 +488,7 @@ def test_issue8941(self): self.assertEqual('\U00010000' * 1024, codecs.utf_32_decode(encoded_be)[0]) + class UTF32LETest(ReadTest, unittest.TestCase): encoding = "utf-32-le" ill_formed_sequence = b"\x80\xdc\x00\x00" @@ -475,6 +534,7 @@ def test_issue8941(self): self.assertEqual('\U00010000' * 1024, codecs.utf_32_le_decode(encoded)[0]) + class UTF32BETest(ReadTest, unittest.TestCase): encoding = "utf-32-be" ill_formed_sequence = b"\x00\x00\xdc\x80" @@ -699,6 +759,7 @@ class UTF8Test(ReadTest, unittest.TestCase): encoding = "utf-8" ill_formed_sequence = b"\xed\xb2\x80" ill_formed_sequence_replace = "\ufffd" * 3 + BOM = b'' def test_partial(self): self.check_partial( @@ -727,27 +788,49 @@ def test_decoder_state(self): self.check_state_handling_decode(self.encoding, u, u.encode(self.encoding)) + def test_decode_error(self): + for data, error_handler, expected in ( + (b'[\x80\xff]', 'ignore', '[]'), + (b'[\x80\xff]', 'replace', '[\ufffd\ufffd]'), + (b'[\x80\xff]', 'surrogateescape', '[\udc80\udcff]'), + (b'[\x80\xff]', 'backslashreplace', '[\\x80\\xff]'), + ): + with self.subTest(data=data, error_handler=error_handler, + expected=expected): + self.assertEqual(data.decode(self.encoding, error_handler), + expected) + def test_lone_surrogates(self): super().test_lone_surrogates() # not sure if this is making sense for # UTF-16 and UTF-32 - self.assertEqual("[\uDC80]".encode('utf-8', "surrogateescape"), - b'[\x80]') + self.assertEqual("[\uDC80]".encode(self.encoding, "surrogateescape"), + self.BOM + b'[\x80]') + + with self.assertRaises(UnicodeEncodeError) as cm: + "[\uDC80\uD800\uDFFF]".encode(self.encoding, "surrogateescape") + exc = cm.exception + self.assertEqual(exc.object[exc.start:exc.end], '\uD800\uDFFF') def test_surrogatepass_handler(self): - self.assertEqual("abc\ud800def".encode("utf-8", "surrogatepass"), - b"abc\xed\xa0\x80def") - self.assertEqual(b"abc\xed\xa0\x80def".decode("utf-8", "surrogatepass"), + self.assertEqual("abc\ud800def".encode(self.encoding, "surrogatepass"), + self.BOM + b"abc\xed\xa0\x80def") + self.assertEqual("\U00010fff\uD800".encode(self.encoding, "surrogatepass"), + self.BOM + b"\xf0\x90\xbf\xbf\xed\xa0\x80") + self.assertEqual("[\uD800\uDC80]".encode(self.encoding, "surrogatepass"), + self.BOM + b'[\xed\xa0\x80\xed\xb2\x80]') + + self.assertEqual(b"abc\xed\xa0\x80def".decode(self.encoding, "surrogatepass"), "abc\ud800def") - self.assertEqual("\U00010fff\uD800".encode("utf-8", "surrogatepass"), - b"\xf0\x90\xbf\xbf\xed\xa0\x80") - self.assertEqual(b"\xf0\x90\xbf\xbf\xed\xa0\x80".decode("utf-8", "surrogatepass"), + self.assertEqual(b"\xf0\x90\xbf\xbf\xed\xa0\x80".decode(self.encoding, "surrogatepass"), "\U00010fff\uD800") + self.assertTrue(codecs.lookup_error("surrogatepass")) with self.assertRaises(UnicodeDecodeError): - b"abc\xed\xa0".decode("utf-8", "surrogatepass") + b"abc\xed\xa0".decode(self.encoding, "surrogatepass") with self.assertRaises(UnicodeDecodeError): - b"abc\xed\xa0z".decode("utf-8", "surrogatepass") + b"abc\xed\xa0z".decode(self.encoding, "surrogatepass") + @unittest.skipUnless(sys.platform == 'win32', 'cp65001 is a Windows-only codec') @@ -766,6 +849,7 @@ def test_encode(self): ('\udc80', 'ignore', b''), ('\udc80', 'replace', b'?'), ('\udc80', 'backslashreplace', b'\\udc80'), + ('\udc80', 'namereplace', b'\\udc80'), ('\udc80', 'surrogatepass', b'\xed\xb2\x80'), )) else: @@ -827,6 +911,8 @@ def test_lone_surrogates(self): self.assertRaises(UnicodeDecodeError, b"\xed\xa0\x80".decode, "cp65001") self.assertEqual("[\uDC80]".encode("cp65001", "backslashreplace"), b'[\\udc80]') + self.assertEqual("[\uDC80]".encode("cp65001", "namereplace"), + b'[\\udc80]') self.assertEqual("[\uDC80]".encode("cp65001", "xmlcharrefreplace"), b'[�]') self.assertEqual("[\uDC80]".encode("cp65001", "surrogateescape"), @@ -849,25 +935,79 @@ def test_surrogatepass_handler(self): self.assertTrue(codecs.lookup_error("surrogatepass")) - class UTF7Test(ReadTest, unittest.TestCase): encoding = "utf-7" + def test_ascii(self): + # Set D (directly encoded characters) + set_d = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789' + '\'(),-./:?') + self.assertEqual(set_d.encode(self.encoding), set_d.encode('ascii')) + self.assertEqual(set_d.encode('ascii').decode(self.encoding), set_d) + # Set O (optional direct characters) + set_o = ' !"#$%&*;<=>@[]^_`{|}' + self.assertEqual(set_o.encode(self.encoding), set_o.encode('ascii')) + self.assertEqual(set_o.encode('ascii').decode(self.encoding), set_o) + # + + self.assertEqual('a+b'.encode(self.encoding), b'a+-b') + self.assertEqual(b'a+-b'.decode(self.encoding), 'a+b') + # White spaces + ws = ' \t\n\r' + self.assertEqual(ws.encode(self.encoding), ws.encode('ascii')) + self.assertEqual(ws.encode('ascii').decode(self.encoding), ws) + # Other ASCII characters + other_ascii = ''.join(sorted(set(bytes(range(0x80)).decode()) - + set(set_d + set_o + '+' + ws))) + self.assertEqual(other_ascii.encode(self.encoding), + b'+AAAAAQACAAMABAAFAAYABwAIAAsADAAOAA8AEAARABIAEwAU' + b'ABUAFgAXABgAGQAaABsAHAAdAB4AHwBcAH4Afw-') + def test_partial(self): self.check_partial( - "a+-b", + 'a+-b\x00c\x80d\u0100e\U00010000f', [ - "a", - "a", - "a+", - "a+-", - "a+-b", + 'a', + 'a', + 'a+', + 'a+-', + 'a+-b', + 'a+-b', + 'a+-b', + 'a+-b', + 'a+-b', + 'a+-b\x00', + 'a+-b\x00c', + 'a+-b\x00c', + 'a+-b\x00c', + 'a+-b\x00c', + 'a+-b\x00c', + 'a+-b\x00c\x80', + 'a+-b\x00c\x80d', + 'a+-b\x00c\x80d', + 'a+-b\x00c\x80d', + 'a+-b\x00c\x80d', + 'a+-b\x00c\x80d', + 'a+-b\x00c\x80d\u0100', + 'a+-b\x00c\x80d\u0100e', + 'a+-b\x00c\x80d\u0100e', + 'a+-b\x00c\x80d\u0100e', + 'a+-b\x00c\x80d\u0100e', + 'a+-b\x00c\x80d\u0100e', + 'a+-b\x00c\x80d\u0100e', + 'a+-b\x00c\x80d\u0100e', + 'a+-b\x00c\x80d\u0100e', + 'a+-b\x00c\x80d\u0100e\U00010000', + 'a+-b\x00c\x80d\u0100e\U00010000f', ] ) def test_errors(self): tests = [ + (b'\xffb', '\ufffdb'), (b'a\xffb', 'a\ufffdb'), + (b'a\xff\xffb', 'a\ufffd\ufffdb'), (b'a+IK', 'a\ufffd'), (b'a+IK-b', 'a\ufffdb'), (b'a+IK,b', 'a\ufffdb'), @@ -883,6 +1023,8 @@ def test_errors(self): (b'a+//,+IKw-b', 'a\ufffd\u20acb'), (b'a+///,+IKw-b', 'a\uffff\ufffd\u20acb'), (b'a+////,+IKw-b', 'a\uffff\ufffd\u20acb'), + (b'a+IKw-b\xff', 'a\u20acb\ufffd'), + (b'a+IKw\xffb', 'a\u20ac\ufffdb'), ] for raw, expected in tests: with self.subTest(raw=raw): @@ -894,8 +1036,36 @@ def test_nonbmp(self): self.assertEqual('\U000104A0'.encode(self.encoding), b'+2AHcoA-') self.assertEqual('\ud801\udca0'.encode(self.encoding), b'+2AHcoA-') self.assertEqual(b'+2AHcoA-'.decode(self.encoding), '\U000104A0') + self.assertEqual(b'+2AHcoA'.decode(self.encoding), '\U000104A0') + self.assertEqual('\u20ac\U000104A0'.encode(self.encoding), b'+IKzYAdyg-') + self.assertEqual(b'+IKzYAdyg-'.decode(self.encoding), '\u20ac\U000104A0') + self.assertEqual(b'+IKzYAdyg'.decode(self.encoding), '\u20ac\U000104A0') + self.assertEqual('\u20ac\u20ac\U000104A0'.encode(self.encoding), + b'+IKwgrNgB3KA-') + self.assertEqual(b'+IKwgrNgB3KA-'.decode(self.encoding), + '\u20ac\u20ac\U000104A0') + self.assertEqual(b'+IKwgrNgB3KA'.decode(self.encoding), + '\u20ac\u20ac\U000104A0') - test_lone_surrogates = None + def test_lone_surrogates(self): + tests = [ + (b'a+2AE-b', 'a\ud801b'), + (b'a+2AE\xffb', 'a\ufffdb'), + (b'a+2AE', 'a\ufffd'), + (b'a+2AEA-b', 'a\ufffdb'), + (b'a+2AH-b', 'a\ufffdb'), + (b'a+IKzYAQ-b', 'a\u20ac\ud801b'), + (b'a+IKzYAQ\xffb', 'a\u20ac\ufffdb'), + (b'a+IKzYAQA-b', 'a\u20ac\ufffdb'), + (b'a+IKzYAd-b', 'a\u20ac\ufffdb'), + (b'a+IKwgrNgB-b', 'a\u20ac\u20ac\ud801b'), + (b'a+IKwgrNgB\xffb', 'a\u20ac\u20ac\ufffdb'), + (b'a+IKwgrNgB', 'a\u20ac\u20ac\ufffd'), + (b'a+IKwgrNgBA-b', 'a\u20ac\u20ac\ufffdb'), + ] + for raw, expected in tests: + with self.subTest(raw=raw): + self.assertEqual(raw.decode('utf-7', 'replace'), expected) class UTF16ExTest(unittest.TestCase): @@ -924,6 +1094,7 @@ def test_bad_args(self): class UTF8SigTest(UTF8Test, unittest.TestCase): encoding = "utf-8-sig" + BOM = codecs.BOM_UTF8 def test_partial(self): self.check_partial( @@ -1009,6 +1180,7 @@ def test_stream_bare(self): class EscapeDecodeTest(unittest.TestCase): def test_empty(self): self.assertEqual(codecs.escape_decode(b""), (b"", 0)) + self.assertEqual(codecs.escape_decode(bytearray()), (b"", 0)) def test_raw(self): decode = codecs.escape_decode @@ -1058,6 +1230,7 @@ def test_errors(self): self.assertEqual(decode(br"[\x0]\x0", "ignore"), (b"[]", 8)) self.assertEqual(decode(br"[\x0]\x0", "replace"), (b"[?]?", 8)) + class RecodingTest(unittest.TestCase): def test_recoding(self): f = io.BytesIO() @@ -1067,6 +1240,8 @@ def test_recoding(self): # Python used to crash on this at exit because of a refcount # bug in _codecsmodule.c + self.assertTrue(f.closed) + # From RFC 3492 punycode_testcases = [ # A Arabic (Egyptian): @@ -1175,6 +1350,7 @@ def test_recoding(self): if len(i)!=2: print(repr(i)) + class PunycodeTest(unittest.TestCase): def test_encode(self): for uni, puny in punycode_testcases: @@ -1194,6 +1370,7 @@ def test_decode(self): puny = puny.decode("ascii").encode("ascii") self.assertEqual(uni, puny.decode("punycode")) + class UnicodeInternalTest(unittest.TestCase): @unittest.skipUnless(SIZEOF_WCHAR_T == 4, 'specific to 32-bit wchar_t') def test_bug1251300(self): @@ -1225,14 +1402,19 @@ def test_bug1251300(self): "unicode_internal") if sys.byteorder == "little": invalid = b"\x00\x00\x11\x00" + invalid_backslashreplace = r"\x00\x00\x11\x00" else: invalid = b"\x00\x11\x00\x00" + invalid_backslashreplace = r"\x00\x11\x00\x00" with support.check_warnings(): self.assertRaises(UnicodeDecodeError, invalid.decode, "unicode_internal") with support.check_warnings(): self.assertEqual(invalid.decode("unicode_internal", "replace"), '\ufffd') + with support.check_warnings(): + self.assertEqual(invalid.decode("unicode_internal", "backslashreplace"), + invalid_backslashreplace) @unittest.skipUnless(SIZEOF_WCHAR_T == 4, 'specific to 32-bit wchar_t') def test_decode_error_attributes(self): @@ -1443,6 +1625,7 @@ def test_nameprep(self): except Exception as e: raise support.TestFailed("Test 3.%d: %s" % (pos+1, str(e))) + class IDNACodecTest(unittest.TestCase): def test_builtin_decode(self): self.assertEqual(str(b"python.org", "idna"), "python.org") @@ -1519,6 +1702,17 @@ def test_incremental_encode(self): self.assertEqual(encoder.encode("ample.org."), b"xn--xample-9ta.org.") self.assertEqual(encoder.encode("", True), b"") + def test_errors(self): + """Only supports "strict" error handler""" + "python.org".encode("idna", "strict") + b"python.org".decode("idna", "strict") + for errors in ("ignore", "replace", "backslashreplace", + "surrogateescape"): + self.assertRaises(Exception, "python.org".encode, "idna", errors) + self.assertRaises(Exception, + b"python.org".decode, "idna", errors) + + class CodecsModuleTest(unittest.TestCase): def test_decode(self): @@ -1528,6 +1722,12 @@ def test_decode(self): self.assertEqual(codecs.decode(b'abc'), 'abc') self.assertRaises(UnicodeDecodeError, codecs.decode, b'\xff', 'ascii') + # test keywords + self.assertEqual(codecs.decode(obj=b'\xe4\xf6\xfc', encoding='latin-1'), + '\xe4\xf6\xfc') + self.assertEqual(codecs.decode(b'[\xff]', 'ascii', errors='ignore'), + '[]') + def test_encode(self): self.assertEqual(codecs.encode('\xe4\xf6\xfc', 'latin-1'), b'\xe4\xf6\xfc') @@ -1536,6 +1736,12 @@ def test_encode(self): self.assertEqual(codecs.encode('abc'), b'abc') self.assertRaises(UnicodeEncodeError, codecs.encode, '\xffff', 'ascii') + # test keywords + self.assertEqual(codecs.encode(obj='\xe4\xf6\xfc', encoding='latin-1'), + b'\xe4\xf6\xfc') + self.assertEqual(codecs.encode('[\xff]', 'ascii', errors='ignore'), + b'[]') + def test_register(self): self.assertRaises(TypeError, codecs.register) self.assertRaises(TypeError, codecs.register, 42) @@ -1574,6 +1780,48 @@ def test_lookup_issue1813(self): c = codecs.lookup('ASCII') self.assertEqual(c.name, 'ascii') + def test_all(self): + api = ( + "encode", "decode", + "register", "CodecInfo", "Codec", "IncrementalEncoder", + "IncrementalDecoder", "StreamReader", "StreamWriter", "lookup", + "getencoder", "getdecoder", "getincrementalencoder", + "getincrementaldecoder", "getreader", "getwriter", + "register_error", "lookup_error", + "strict_errors", "replace_errors", "ignore_errors", + "xmlcharrefreplace_errors", "backslashreplace_errors", + "namereplace_errors", + "open", "EncodedFile", + "iterencode", "iterdecode", + "BOM", "BOM_BE", "BOM_LE", + "BOM_UTF8", "BOM_UTF16", "BOM_UTF16_BE", "BOM_UTF16_LE", + "BOM_UTF32", "BOM_UTF32_BE", "BOM_UTF32_LE", + "BOM32_BE", "BOM32_LE", "BOM64_BE", "BOM64_LE", # Undocumented + "StreamReaderWriter", "StreamRecoder", + ) + self.assertCountEqual(api, codecs.__all__) + for api in codecs.__all__: + getattr(codecs, api) + + def test_open(self): + self.addCleanup(support.unlink, support.TESTFN) + for mode in ('w', 'r', 'r+', 'w+', 'a', 'a+'): + with self.subTest(mode), \ + codecs.open(support.TESTFN, mode, 'ascii') as file: + self.assertIsInstance(file, codecs.StreamReaderWriter) + + def test_undefined(self): + self.assertRaises(UnicodeError, codecs.encode, 'abc', 'undefined') + self.assertRaises(UnicodeError, codecs.decode, b'abc', 'undefined') + self.assertRaises(UnicodeError, codecs.encode, '', 'undefined') + self.assertRaises(UnicodeError, codecs.decode, b'', 'undefined') + for errors in ('strict', 'ignore', 'replace', 'backslashreplace'): + self.assertRaises(UnicodeError, + codecs.encode, 'abc', 'undefined', errors) + self.assertRaises(UnicodeError, + codecs.decode, b'abc', 'undefined', errors) + + class StreamReaderTest(unittest.TestCase): def setUp(self): @@ -1584,6 +1832,7 @@ def test_readlines(self): f = self.reader(self.stream) self.assertEqual(f.readlines(), ['\ud55c\n', '\uae00']) + class EncodedFileTest(unittest.TestCase): def test_basic(self): @@ -1674,7 +1923,9 @@ def test_basic(self): "iso8859_9", "johab", "koi8_r", + "koi8_t", "koi8_u", + "kz1048", "latin_1", "mac_cyrillic", "mac_greek", @@ -1707,17 +1958,15 @@ def test_basic(self): # "undefined" # The following encodings don't work in stateful mode -broken_unicode_with_streams = [ +broken_unicode_with_stateful = [ "punycode", "unicode_internal" ] -broken_incremental_coders = broken_unicode_with_streams + [ - "idna", -] + class BasicUnicodeTest(unittest.TestCase, MixInCheckStateHandling): def test_basics(self): - s = "abc123" # all codecs should be able to encode these + s = "abc123" # all codecs should be able to encode these for encoding in all_unicode_encodings: name = codecs.lookup(encoding).name if encoding.endswith("_codec"): @@ -1729,11 +1978,11 @@ def test_basics(self): with support.check_warnings(): # unicode-internal has been deprecated (b, size) = codecs.getencoder(encoding)(s) - self.assertEqual(size, len(s), "%r != %r (encoding=%r)" % (size, len(s), encoding)) + self.assertEqual(size, len(s), "encoding=%r" % encoding) (chars, size) = codecs.getdecoder(encoding)(b) - self.assertEqual(chars, s, "%r != %r (encoding=%r)" % (chars, s, encoding)) + self.assertEqual(chars, s, "encoding=%r" % encoding) - if encoding not in broken_unicode_with_streams: + if encoding not in broken_unicode_with_stateful: # check stream reader/writer q = Queue(b"") writer = codecs.getwriter(encoding)(q) @@ -1749,15 +1998,13 @@ def test_basics(self): for c in encodedresult: q.write(bytes([c])) decodedresult += reader.read() - self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding)) + self.assertEqual(decodedresult, s, "encoding=%r" % encoding) - if encoding not in broken_incremental_coders: - # check incremental decoder/encoder (fetched via the Python - # and C API) and iterencode()/iterdecode() + if encoding not in broken_unicode_with_stateful: + # check incremental decoder/encoder and iterencode()/iterdecode() try: encoder = codecs.getincrementalencoder(encoding)() - cencoder = _testcapi.codec_incrementalencoder(encoding) - except LookupError: # no IncrementalEncoder + except LookupError: # no IncrementalEncoder pass else: # check incremental decoder/encoder @@ -1770,45 +2017,71 @@ def test_basics(self): for c in encodedresult: decodedresult += decoder.decode(bytes([c])) decodedresult += decoder.decode(b"", True) - self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding)) + self.assertEqual(decodedresult, s, + "encoding=%r" % encoding) + + # check iterencode()/iterdecode() + result = "".join(codecs.iterdecode( + codecs.iterencode(s, encoding), encoding)) + self.assertEqual(result, s, "encoding=%r" % encoding) + + # check iterencode()/iterdecode() with empty string + result = "".join(codecs.iterdecode( + codecs.iterencode("", encoding), encoding)) + self.assertEqual(result, "") + if encoding not in ("idna", "mbcs"): + # check incremental decoder/encoder with errors argument + try: + encoder = codecs.getincrementalencoder(encoding)("ignore") + except LookupError: # no IncrementalEncoder + pass + else: + encodedresult = b"".join(encoder.encode(c) for c in s) + decoder = codecs.getincrementaldecoder(encoding)("ignore") + decodedresult = "".join(decoder.decode(bytes([c])) + for c in encodedresult) + self.assertEqual(decodedresult, s, + "encoding=%r" % encoding) + + @support.cpython_only + def test_basics_capi(self): + from _testcapi import codec_incrementalencoder, codec_incrementaldecoder + s = "abc123" # all codecs should be able to encode these + for encoding in all_unicode_encodings: + if encoding not in broken_unicode_with_stateful: + # check incremental decoder/encoder (fetched via the C API) + try: + cencoder = codec_incrementalencoder(encoding) + except LookupError: # no IncrementalEncoder + pass + else: # check C API encodedresult = b"" for c in s: encodedresult += cencoder.encode(c) encodedresult += cencoder.encode("", True) - cdecoder = _testcapi.codec_incrementaldecoder(encoding) + cdecoder = codec_incrementaldecoder(encoding) decodedresult = "" for c in encodedresult: decodedresult += cdecoder.decode(bytes([c])) decodedresult += cdecoder.decode(b"", True) - self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding)) - - # check iterencode()/iterdecode() - result = "".join(codecs.iterdecode(codecs.iterencode(s, encoding), encoding)) - self.assertEqual(result, s, "%r != %r (encoding=%r)" % (result, s, encoding)) - - # check iterencode()/iterdecode() with empty string - result = "".join(codecs.iterdecode(codecs.iterencode("", encoding), encoding)) - self.assertEqual(result, "") + self.assertEqual(decodedresult, s, + "encoding=%r" % encoding) if encoding not in ("idna", "mbcs"): # check incremental decoder/encoder with errors argument try: - encoder = codecs.getincrementalencoder(encoding)("ignore") - cencoder = _testcapi.codec_incrementalencoder(encoding, "ignore") - except LookupError: # no IncrementalEncoder + cencoder = codec_incrementalencoder(encoding, "ignore") + except LookupError: # no IncrementalEncoder pass else: - encodedresult = b"".join(encoder.encode(c) for c in s) - decoder = codecs.getincrementaldecoder(encoding)("ignore") - decodedresult = "".join(decoder.decode(bytes([c])) for c in encodedresult) - self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding)) - encodedresult = b"".join(cencoder.encode(c) for c in s) - cdecoder = _testcapi.codec_incrementaldecoder(encoding, "ignore") - decodedresult = "".join(cdecoder.decode(bytes([c])) for c in encodedresult) - self.assertEqual(decodedresult, s, "%r != %r (encoding=%r)" % (decodedresult, s, encoding)) + cdecoder = codec_incrementaldecoder(encoding, "ignore") + decodedresult = "".join(cdecoder.decode(bytes([c])) + for c in encodedresult) + self.assertEqual(decodedresult, s, + "encoding=%r" % encoding) def test_seek(self): # all codecs should be able to encode these @@ -1816,7 +2089,7 @@ def test_seek(self): for encoding in all_unicode_encodings: if encoding == "idna": # FIXME: See SF bug #1163178 continue - if encoding in broken_unicode_with_streams: + if encoding in broken_unicode_with_stateful: continue reader = codecs.getreader(encoding)(io.BytesIO(s.encode(encoding))) for t in range(5): @@ -1849,10 +2122,11 @@ def test_decoder_state(self): # Check that getstate() and setstate() handle the state properly u = "abc123" for encoding in all_unicode_encodings: - if encoding not in broken_incremental_coders: + if encoding not in broken_unicode_with_stateful: self.check_state_handling_decode(encoding, u, u.encode(encoding)) self.check_state_handling_encode(encoding, u, u.encode(encoding)) + class CharmapTest(unittest.TestCase): def test_decode_with_string_map(self): self.assertEqual( @@ -1883,6 +2157,16 @@ def test_decode_with_string_map(self): ("ab\ufffd", 3) ) + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", "ab"), + ("ab\\x02", 3) + ) + + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", "ab\ufffe"), + ("ab\\x02", 3) + ) + self.assertEqual( codecs.charmap_decode(b"\x00\x01\x02", "ignore", "ab"), ("ab", 3) @@ -1959,6 +2243,25 @@ def test_decode_with_int2str_map(self): ("ab\ufffd", 3) ) + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", + {0: 'a', 1: 'b'}), + ("ab\\x02", 3) + ) + + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", + {0: 'a', 1: 'b', 2: None}), + ("ab\\x02", 3) + ) + + # Issue #14850 + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", + {0: 'a', 1: 'b', 2: '\ufffe'}), + ("ab\\x02", 3) + ) + self.assertEqual( codecs.charmap_decode(b"\x00\x01\x02", "ignore", {0: 'a', 1: 'b'}), @@ -2035,6 +2338,18 @@ def test_decode_with_int2int_map(self): ("ab\ufffd", 3) ) + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", + {0: a, 1: b}), + ("ab\\x02", 3) + ) + + self.assertEqual( + codecs.charmap_decode(b"\x00\x01\x02", "backslashreplace", + {0: a, 1: b, 2: 0xFFFE}), + ("ab\\x02", 3) + ) + self.assertEqual( codecs.charmap_decode(b"\x00\x01\x02", "ignore", {0: a, 1: b}), @@ -2053,6 +2368,7 @@ def test_encodedfile(self): f = io.BytesIO(b"\xc3\xbc") with codecs.EncodedFile(f, "latin-1", "utf-8") as ef: self.assertEqual(ef.read(), b"\xfc") + self.assertTrue(f.closed) def test_streamreaderwriter(self): f = io.BytesIO(b"\xc3\xbc") @@ -2061,6 +2377,7 @@ def test_streamreaderwriter(self): info.streamwriter, 'strict') as srw: self.assertEqual(srw.read(), "\xfc") + class TypesTest(unittest.TestCase): def test_decode_unicode(self): # Most decoders don't accept unicode input @@ -2093,9 +2410,13 @@ def test_unicode_escape(self): self.assertRaises(UnicodeDecodeError, codecs.unicode_escape_decode, br"\U00110000") self.assertEqual(codecs.unicode_escape_decode(r"\U00110000", "replace"), ("\ufffd", 10)) + self.assertEqual(codecs.unicode_escape_decode(r"\U00110000", "backslashreplace"), + (r"\x5c\x55\x30\x30\x31\x31\x30\x30\x30\x30", 10)) self.assertRaises(UnicodeDecodeError, codecs.raw_unicode_escape_decode, br"\U00110000") self.assertEqual(codecs.raw_unicode_escape_decode(r"\U00110000", "replace"), ("\ufffd", 10)) + self.assertEqual(codecs.raw_unicode_escape_decode(r"\U00110000", "backslashreplace"), + (r"\x5c\x55\x30\x30\x31\x31\x30\x30\x30\x30", 10)) class UnicodeEscapeTest(unittest.TestCase): @@ -2335,7 +2656,7 @@ def test_seek0(self): try: import zlib except ImportError: - pass + zlib = None else: bytes_transform_encodings.append("zlib_codec") transform_aliases["zlib_codec"] = ["zip", "zlib"] @@ -2347,6 +2668,7 @@ def test_seek0(self): bytes_transform_encodings.append("bz2_codec") transform_aliases["bz2_codec"] = ["bz2"] + class TransformCodecTest(unittest.TestCase): def test_basics(self): @@ -2370,8 +2692,6 @@ def test_read(self): def test_readline(self): for encoding in bytes_transform_encodings: - if encoding in ['uu_codec', 'zlib_codec']: - continue with self.subTest(encoding=encoding): sin = codecs.encode(b"\x80", encoding) reader = codecs.getreader(encoding)(io.BytesIO(sin)) @@ -2440,6 +2760,7 @@ def test_binary_to_text_blacklists_text_transforms(self): bad_input.decode("rot_13") self.assertIsNone(failure.exception.__cause__) + @unittest.skipUnless(zlib, "Requires zlib support") def test_custom_zlib_error_is_wrapped(self): # Check zlib codec gives a good error for malformed input msg = "^decoding with 'zlib_codec' codec failed" @@ -2468,6 +2789,18 @@ def test_aliases(self): info = codecs.lookup(alias) self.assertEqual(info.name, expected_name) + def test_quopri_stateless(self): + # Should encode with quotetabs=True + encoded = codecs.encode(b"space tab\teol \n", "quopri-codec") + self.assertEqual(encoded, b"space=20tab=09eol=20\n") + # But should still support unescaped tabs and spaces + unescaped = b"space tab eol\n" + self.assertEqual(codecs.decode(unescaped, "quopri-codec"), unescaped) + + def test_uu_invalid(self): + # Missing "begin" line + self.assertRaises(ValueError, codecs.decode, b"", "uu-codec") + # The codec system tries to wrap exceptions in order to ensure the error # mentions the operation being performed and the codec involved. We @@ -2483,6 +2816,14 @@ def _get_test_codec(codec_name): return _TEST_CODECS.get(codec_name) codecs.register(_get_test_codec) # Returns None, not usable as a decorator +try: + # Issue #22166: Also need to clear the internal cache in CPython + from _codecs import _forget_codec +except ImportError: + def _forget_codec(codec_name): + pass + + class ExceptionChainingTest(unittest.TestCase): def setUp(self): @@ -2508,6 +2849,12 @@ def setUp(self): def tearDown(self): _TEST_CODECS.pop(self.codec_name, None) + # Issue #22166: Also pop from caches to avoid appearance of ref leaks + encodings._cache.pop(self.codec_name, None) + try: + _forget_codec(self.codec_name) + except KeyError: + pass def set_codec(self, encode, decode): codec_info = codecs.CodecInfo(encode, decode, @@ -2521,6 +2868,7 @@ def assertWrapped(self, operation, exc_type, msg): with self.assertRaisesRegex(exc_type, full_msg) as caught: yield caught self.assertIsInstance(caught.exception.__cause__, exc_type) + self.assertIsNotNone(caught.exception.__cause__.__traceback__) def raise_obj(self, *args, **kwds): # Helper to dynamically change the object raised by a test codec @@ -2654,15 +3002,15 @@ def test_code_page_name(self): self.assertRaisesRegex(UnicodeEncodeError, 'cp932', codecs.code_page_encode, 932, '\xff') self.assertRaisesRegex(UnicodeDecodeError, 'cp932', - codecs.code_page_decode, 932, b'\x81\x00') + codecs.code_page_decode, 932, b'\x81\x00', 'strict', True) self.assertRaisesRegex(UnicodeDecodeError, 'CP_UTF8', - codecs.code_page_decode, self.CP_UTF8, b'\xff') + codecs.code_page_decode, self.CP_UTF8, b'\xff', 'strict', True) def check_decode(self, cp, tests): for raw, errors, expected in tests: if expected is not None: try: - decoded = codecs.code_page_decode(cp, raw, errors) + decoded = codecs.code_page_decode(cp, raw, errors, True) except UnicodeDecodeError as err: self.fail('Unable to decode %a from "cp%s" with ' 'errors=%r: %s' % (raw, cp, errors, err)) @@ -2674,7 +3022,7 @@ def check_decode(self, cp, tests): self.assertLessEqual(decoded[1], len(raw)) else: self.assertRaises(UnicodeDecodeError, - codecs.code_page_decode, cp, raw, errors) + codecs.code_page_decode, cp, raw, errors, True) def check_encode(self, cp, tests): for text, errors, expected in tests: @@ -2702,7 +3050,12 @@ def test_cp932(self): ('[\xff]', 'replace', b'[y]'), ('[\u20ac]', 'replace', b'[?]'), ('[\xff]', 'backslashreplace', b'[\\xff]'), + ('[\xff]', 'namereplace', + b'[\\N{LATIN SMALL LETTER Y WITH DIAERESIS}]'), ('[\xff]', 'xmlcharrefreplace', b'[ÿ]'), + ('\udcff', 'strict', None), + ('[\udcff]', 'surrogateescape', b'[\xff]'), + ('[\udcff]', 'surrogatepass', None), )) self.check_decode(932, ( (b'abc', 'strict', 'abc'), @@ -2711,10 +3064,13 @@ def test_cp932(self): (b'[\xff]', 'strict', None), (b'[\xff]', 'ignore', '[]'), (b'[\xff]', 'replace', '[\ufffd]'), + (b'[\xff]', 'backslashreplace', '[\\xff]'), (b'[\xff]', 'surrogateescape', '[\udcff]'), + (b'[\xff]', 'surrogatepass', None), (b'\x81\x00abc', 'strict', None), (b'\x81\x00abc', 'ignore', '\x00abc'), (b'\x81\x00abc', 'replace', '\ufffd\x00abc'), + (b'\x81\x00abc', 'backslashreplace', '\\x81\x00abc'), )) def test_cp1252(self): @@ -2722,9 +3078,12 @@ def test_cp1252(self): ('abc', 'strict', b'abc'), ('\xe9\u20ac', 'strict', b'\xe9\x80'), ('\xff', 'strict', b'\xff'), + # test error handlers ('\u0141', 'strict', None), ('\u0141', 'ignore', b''), ('\u0141', 'replace', b'L'), + ('\udc98', 'surrogateescape', b'\x98'), + ('\udc98', 'surrogatepass', None), )) self.check_decode(1252, ( (b'abc', 'strict', 'abc'), @@ -2787,5 +3146,81 @@ def test_incremental(self): self.assertEqual(decoded, ('abc', 3)) +class ASCIITest(unittest.TestCase): + def test_encode(self): + self.assertEqual('abc123'.encode('ascii'), b'abc123') + + def test_encode_error(self): + for data, error_handler, expected in ( + ('[\x80\xff\u20ac]', 'ignore', b'[]'), + ('[\x80\xff\u20ac]', 'replace', b'[???]'), + ('[\x80\xff\u20ac]', 'xmlcharrefreplace', b'[€ÿ€]'), + ('[\x80\xff\u20ac\U000abcde]', 'backslashreplace', + b'[\\x80\\xff\\u20ac\\U000abcde]'), + ('[\udc80\udcff]', 'surrogateescape', b'[\x80\xff]'), + ): + with self.subTest(data=data, error_handler=error_handler, + expected=expected): + self.assertEqual(data.encode('ascii', error_handler), + expected) + + def test_encode_surrogateescape_error(self): + with self.assertRaises(UnicodeEncodeError): + # the first character can be decoded, but not the second + '\udc80\xff'.encode('ascii', 'surrogateescape') + + def test_decode(self): + self.assertEqual(b'abc'.decode('ascii'), 'abc') + + def test_decode_error(self): + for data, error_handler, expected in ( + (b'[\x80\xff]', 'ignore', '[]'), + (b'[\x80\xff]', 'replace', '[\ufffd\ufffd]'), + (b'[\x80\xff]', 'surrogateescape', '[\udc80\udcff]'), + (b'[\x80\xff]', 'backslashreplace', '[\\x80\\xff]'), + ): + with self.subTest(data=data, error_handler=error_handler, + expected=expected): + self.assertEqual(data.decode('ascii', error_handler), + expected) + + +class Latin1Test(unittest.TestCase): + def test_encode(self): + for data, expected in ( + ('abc', b'abc'), + ('\x80\xe9\xff', b'\x80\xe9\xff'), + ): + with self.subTest(data=data, expected=expected): + self.assertEqual(data.encode('latin1'), expected) + + def test_encode_errors(self): + for data, error_handler, expected in ( + ('[\u20ac\udc80]', 'ignore', b'[]'), + ('[\u20ac\udc80]', 'replace', b'[??]'), + ('[\u20ac\U000abcde]', 'backslashreplace', + b'[\\u20ac\\U000abcde]'), + ('[\u20ac\udc80]', 'xmlcharrefreplace', b'[€�]'), + ('[\udc80\udcff]', 'surrogateescape', b'[\x80\xff]'), + ): + with self.subTest(data=data, error_handler=error_handler, + expected=expected): + self.assertEqual(data.encode('latin1', error_handler), + expected) + + def test_encode_surrogateescape_error(self): + with self.assertRaises(UnicodeEncodeError): + # the first character can be decoded, but not the second + '\udc80\u20ac'.encode('latin1', 'surrogateescape') + + def test_decode(self): + for data, expected in ( + (b'abc', 'abc'), + (b'[\x80\xff]', '[\x80\xff]'), + ): + with self.subTest(data=data, expected=expected): + self.assertEqual(data.decode('latin1'), expected) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_codeop.py b/Lib/test/test_codeop.py index b65423b34cd6..509bf5dfd21e 100644 --- a/Lib/test/test_codeop.py +++ b/Lib/test/test_codeop.py @@ -3,7 +3,7 @@ Nick Mathewson """ import unittest -from test.support import run_unittest, is_jython +from test.support import is_jython from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT import io @@ -296,9 +296,5 @@ def test_filename(self): compile("a = 1\n", "def", 'single').co_filename) -def test_main(): - run_unittest(CodeopTests) - - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index 56e812070582..af79af9b5ec5 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -1,7 +1,8 @@ """Unit tests for collections.py.""" import unittest, doctest, operator -from test.support import TESTFN, forget, unlink +from test.support import TESTFN, forget, unlink, import_fresh_module +import contextlib import inspect from test import support from collections import namedtuple, Counter, OrderedDict, _count_elements @@ -11,9 +12,12 @@ import keyword import re import sys -from collections import UserDict +import types +from collections import UserDict, UserString, UserList from collections import ChainMap -from collections.abc import Hashable, Iterable, Iterator +from collections import deque +from collections.abc import Awaitable, Coroutine, AsyncIterator, AsyncIterable +from collections.abc import Hashable, Iterable, Iterator, Generator from collections.abc import Sized, Container, Callable from collections.abc import Set, MutableSet from collections.abc import Mapping, MutableMapping, KeysView, ItemsView @@ -21,6 +25,26 @@ from collections.abc import ByteString +class TestUserObjects(unittest.TestCase): + def _superset_test(self, a, b): + self.assertGreaterEqual( + set(dir(a)), + set(dir(b)), + '{a} should have all the methods of {b}'.format( + a=a.__name__, + b=b.__name__, + ), + ) + def test_str_protocol(self): + self._superset_test(UserString, str) + + def test_list_protocol(self): + self._superset_test(UserList, list) + + def test_dict_protocol(self): + self._superset_test(UserDict, dict) + + ################################################################################ ### ChainMap (helper class for configparser and the string module) ################################################################################ @@ -63,10 +87,17 @@ def test_basics(self): for m1, m2 in zip(d.maps[1:], e.maps[1:]): self.assertIs(m1, m2) - for e in [pickle.loads(pickle.dumps(d)), - copy.deepcopy(d), + # check deep copies + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + e = pickle.loads(pickle.dumps(d, proto)) + self.assertEqual(d, e) + self.assertEqual(d.maps, e.maps) + self.assertIsNot(d, e) + for m1, m2 in zip(d.maps, e.maps): + self.assertIsNot(m1, m2, e) + for e in [copy.deepcopy(d), eval(repr(d)) - ]: # check deep copies + ]: self.assertEqual(d, e) self.assertEqual(d.maps, e.maps) self.assertIsNot(d, e) @@ -189,6 +220,14 @@ def test_factory_doc_attr(self): Point = namedtuple('Point', 'x y') self.assertEqual(Point.__doc__, 'Point(x, y)') + @unittest.skipIf(sys.flags.optimize >= 2, + "Docstrings are omitted with -O2 and above") + def test_doc_writable(self): + Point = namedtuple('Point', 'x y') + self.assertEqual(Point.x.__doc__, 'Alias for field number 0') + Point.x.__doc__ = 'docstring for Point.x' + self.assertEqual(Point.x.__doc__, 'docstring for Point.x') + def test_name_fixer(self): for spec, renamed in [ [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char @@ -218,7 +257,6 @@ def test_instance(self): self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method - self.assertEqual(vars(p), p._asdict()) # verify that vars() works try: p._replace(x=1, error=2) @@ -301,7 +339,7 @@ def test_pickle(self): for module in (pickle,): loads = getattr(module, 'loads') dumps = getattr(module, 'dumps') - for protocol in -1, 0, 1, 2: + for protocol in range(-1, module.HIGHEST_PROTOCOL + 1): q = loads(dumps(p, protocol)) self.assertEqual(p, q) self.assertEqual(p._fields, q._fields) @@ -373,6 +411,17 @@ def test_source(self): globals().pop('NTColor', None) # clean-up after this test + def test_namedtuple_subclass_issue_24931(self): + class Point(namedtuple('_Point', ['x', 'y'])): + pass + + a = Point(3, 4) + self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)])) + + a.w = 5 + self.assertEqual(a.__dict__, {'w': 5}) + + ################################################################################ ### Abstract Base Classes ################################################################################ @@ -438,6 +487,121 @@ def __eq__(self, other): class TestOneTrickPonyABCs(ABCTestCase): + def test_Awaitable(self): + def gen(): + yield + + @types.coroutine + def coro(): + yield + + async def new_coro(): + pass + + class Bar: + def __await__(self): + yield + + class MinimalCoro(Coroutine): + def send(self, value): + return value + def throw(self, typ, val=None, tb=None): + super().throw(typ, val, tb) + def __await__(self): + yield + + non_samples = [None, int(), gen(), object()] + for x in non_samples: + self.assertNotIsInstance(x, Awaitable) + self.assertFalse(issubclass(type(x), Awaitable), repr(type(x))) + + samples = [Bar(), MinimalCoro()] + for x in samples: + self.assertIsInstance(x, Awaitable) + self.assertTrue(issubclass(type(x), Awaitable)) + + c = coro() + # Iterable coroutines (generators with CO_ITERABLE_COROUTINE + # flag don't have '__await__' method, hence can't be instances + # of Awaitable. Use inspect.isawaitable to detect them. + self.assertNotIsInstance(c, Awaitable) + + c = new_coro() + self.assertIsInstance(c, Awaitable) + c.close() # awoid RuntimeWarning that coro() was not awaited + + class CoroLike: pass + Coroutine.register(CoroLike) + self.assertTrue(isinstance(CoroLike(), Awaitable)) + self.assertTrue(issubclass(CoroLike, Awaitable)) + CoroLike = None + support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache + + def test_Coroutine(self): + def gen(): + yield + + @types.coroutine + def coro(): + yield + + async def new_coro(): + pass + + class Bar: + def __await__(self): + yield + + class MinimalCoro(Coroutine): + def send(self, value): + return value + def throw(self, typ, val=None, tb=None): + super().throw(typ, val, tb) + def __await__(self): + yield + + non_samples = [None, int(), gen(), object(), Bar()] + for x in non_samples: + self.assertNotIsInstance(x, Coroutine) + self.assertFalse(issubclass(type(x), Coroutine), repr(type(x))) + + samples = [MinimalCoro()] + for x in samples: + self.assertIsInstance(x, Awaitable) + self.assertTrue(issubclass(type(x), Awaitable)) + + c = coro() + # Iterable coroutines (generators with CO_ITERABLE_COROUTINE + # flag don't have '__await__' method, hence can't be instances + # of Coroutine. Use inspect.isawaitable to detect them. + self.assertNotIsInstance(c, Coroutine) + + c = new_coro() + self.assertIsInstance(c, Coroutine) + c.close() # awoid RuntimeWarning that coro() was not awaited + + class CoroLike: + def send(self, value): + pass + def throw(self, typ, val=None, tb=None): + pass + def close(self): + pass + def __await__(self): + pass + self.assertTrue(isinstance(CoroLike(), Coroutine)) + self.assertTrue(issubclass(CoroLike, Coroutine)) + + class CoroLike: + def send(self, value): + pass + def close(self): + pass + def __await__(self): + pass + self.assertFalse(isinstance(CoroLike(), Coroutine)) + self.assertFalse(issubclass(CoroLike, Coroutine)) + def test_Hashable(self): # Check some non-hashables non_samples = [bytearray(), list(), set(), dict()] @@ -464,6 +628,40 @@ def __hash__(self): self.validate_abstract_methods(Hashable, '__hash__') self.validate_isinstance(Hashable, '__hash__') + def test_AsyncIterable(self): + class AI: + async def __aiter__(self): + return self + self.assertTrue(isinstance(AI(), AsyncIterable)) + self.assertTrue(issubclass(AI, AsyncIterable)) + # Check some non-iterables + non_samples = [None, object, []] + for x in non_samples: + self.assertNotIsInstance(x, AsyncIterable) + self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x))) + self.validate_abstract_methods(AsyncIterable, '__aiter__') + self.validate_isinstance(AsyncIterable, '__aiter__') + + def test_AsyncIterator(self): + class AI: + async def __aiter__(self): + return self + async def __anext__(self): + raise StopAsyncIteration + self.assertTrue(isinstance(AI(), AsyncIterator)) + self.assertTrue(issubclass(AI, AsyncIterator)) + non_samples = [None, object, []] + # Check some non-iterables + for x in non_samples: + self.assertNotIsInstance(x, AsyncIterator) + self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x))) + # Similarly to regular iterators (see issue 10565) + class AnextOnly: + async def __anext__(self): + raise StopAsyncIteration + self.assertNotIsInstance(AnextOnly(), AsyncIterator) + self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__') + def test_Iterable(self): # Check some non-iterables non_samples = [None, 42, 3.14, 1j] @@ -511,9 +709,80 @@ def test_Iterator(self): class NextOnly: def __next__(self): yield 1 - raise StopIteration + return self.assertNotIsInstance(NextOnly(), Iterator) + def test_Generator(self): + class NonGen1: + def __iter__(self): return self + def __next__(self): return None + def close(self): pass + def throw(self, typ, val=None, tb=None): pass + + class NonGen2: + def __iter__(self): return self + def __next__(self): return None + def close(self): pass + def send(self, value): return value + + class NonGen3: + def close(self): pass + def send(self, value): return value + def throw(self, typ, val=None, tb=None): pass + + non_samples = [ + None, 42, 3.14, 1j, b"", "", (), [], {}, set(), + iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()] + for x in non_samples: + self.assertNotIsInstance(x, Generator) + self.assertFalse(issubclass(type(x), Generator), repr(type(x))) + + class Gen: + def __iter__(self): return self + def __next__(self): return None + def close(self): pass + def send(self, value): return value + def throw(self, typ, val=None, tb=None): pass + + class MinimalGen(Generator): + def send(self, value): + return value + def throw(self, typ, val=None, tb=None): + super().throw(typ, val, tb) + + def gen(): + yield 1 + + samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()] + for x in samples: + self.assertIsInstance(x, Iterator) + self.assertIsInstance(x, Generator) + self.assertTrue(issubclass(type(x), Generator), repr(type(x))) + self.validate_abstract_methods(Generator, 'send', 'throw') + + # mixin tests + mgen = MinimalGen() + self.assertIs(mgen, iter(mgen)) + self.assertIs(mgen.send(None), next(mgen)) + self.assertEqual(2, mgen.send(2)) + self.assertIsNone(mgen.close()) + self.assertRaises(ValueError, mgen.throw, ValueError) + self.assertRaisesRegex(ValueError, "^huhu$", + mgen.throw, ValueError, ValueError("huhu")) + self.assertRaises(StopIteration, mgen.throw, StopIteration()) + + class FailOnClose(Generator): + def send(self, value): return value + def throw(self, *args): raise ValueError + + self.assertRaises(ValueError, FailOnClose().close) + + class IgnoreGeneratorExit(Generator): + def send(self, value): return value + def throw(self, *args): pass + + self.assertRaises(RuntimeError, IgnoreGeneratorExit().close) + def test_Sized(self): non_samples = [None, 42, 3.14, 1j, (lambda: (yield))(), @@ -640,6 +909,59 @@ def __hash__(self): a, b = OneTwoThreeSet(), OneTwoThreeSet() self.assertTrue(hash(a) == hash(b)) + def test_isdisjoint_Set(self): + class MySet(Set): + def __init__(self, itr): + self.contents = itr + def __contains__(self, x): + return x in self.contents + def __iter__(self): + return iter(self.contents) + def __len__(self): + return len([x for x in self.contents]) + s1 = MySet((1, 2, 3)) + s2 = MySet((4, 5, 6)) + s3 = MySet((1, 5, 6)) + self.assertTrue(s1.isdisjoint(s2)) + self.assertFalse(s1.isdisjoint(s3)) + + def test_equality_Set(self): + class MySet(Set): + def __init__(self, itr): + self.contents = itr + def __contains__(self, x): + return x in self.contents + def __iter__(self): + return iter(self.contents) + def __len__(self): + return len([x for x in self.contents]) + s1 = MySet((1,)) + s2 = MySet((1, 2)) + s3 = MySet((3, 4)) + s4 = MySet((3, 4)) + self.assertTrue(s2 > s1) + self.assertTrue(s1 < s2) + self.assertFalse(s2 <= s1) + self.assertFalse(s2 <= s3) + self.assertFalse(s1 >= s2) + self.assertEqual(s3, s4) + self.assertNotEqual(s2, s3) + + def test_arithmetic_Set(self): + class MySet(Set): + def __init__(self, itr): + self.contents = itr + def __contains__(self, x): + return x in self.contents + def __iter__(self): + return iter(self.contents) + def __len__(self): + return len([x for x in self.contents]) + s1 = MySet((1, 2, 3)) + s2 = MySet((3, 4, 5)) + s3 = s1 & s2 + self.assertEqual(s3, MySet((3,))) + def test_MutableSet(self): self.assertIsInstance(set(), MutableSet) self.assertTrue(issubclass(set, MutableSet)) @@ -720,14 +1042,166 @@ def __lt__(self, x): cs = MyComparableSet() ncs = MyNonComparableSet() + self.assertFalse(ncs < cs) + self.assertTrue(ncs <= cs) + self.assertFalse(ncs > cs) + self.assertTrue(ncs >= cs) + + def assertSameSet(self, s1, s2): + # coerce both to a real set then check equality + self.assertSetEqual(set(s1), set(s2)) + + def test_Set_interoperability_with_real_sets(self): + # Issue: 8743 + class ListSet(Set): + def __init__(self, elements=()): + self.data = [] + for elem in elements: + if elem not in self.data: + self.data.append(elem) + def __contains__(self, elem): + return elem in self.data + def __iter__(self): + return iter(self.data) + def __len__(self): + return len(self.data) + def __repr__(self): + return 'Set({!r})'.format(self.data) + + r1 = set('abc') + r2 = set('bcd') + r3 = set('abcde') + f1 = ListSet('abc') + f2 = ListSet('bcd') + f3 = ListSet('abcde') + l1 = list('abccba') + l2 = list('bcddcb') + l3 = list('abcdeedcba') + + target = r1 & r2 + self.assertSameSet(f1 & f2, target) + self.assertSameSet(f1 & r2, target) + self.assertSameSet(r2 & f1, target) + self.assertSameSet(f1 & l2, target) + + target = r1 | r2 + self.assertSameSet(f1 | f2, target) + self.assertSameSet(f1 | r2, target) + self.assertSameSet(r2 | f1, target) + self.assertSameSet(f1 | l2, target) + + fwd_target = r1 - r2 + rev_target = r2 - r1 + self.assertSameSet(f1 - f2, fwd_target) + self.assertSameSet(f2 - f1, rev_target) + self.assertSameSet(f1 - r2, fwd_target) + self.assertSameSet(f2 - r1, rev_target) + self.assertSameSet(r1 - f2, fwd_target) + self.assertSameSet(r2 - f1, rev_target) + self.assertSameSet(f1 - l2, fwd_target) + self.assertSameSet(f2 - l1, rev_target) + + target = r1 ^ r2 + self.assertSameSet(f1 ^ f2, target) + self.assertSameSet(f1 ^ r2, target) + self.assertSameSet(r2 ^ f1, target) + self.assertSameSet(f1 ^ l2, target) + + # Don't change the following to use assertLess or other + # "more specific" unittest assertions. The current + # assertTrue/assertFalse style makes the pattern of test + # case combinations clear and allows us to know for sure + # the exact operator being invoked. + + # proper subset + self.assertTrue(f1 < f3) + self.assertFalse(f1 < f1) + self.assertFalse(f1 < f2) + self.assertTrue(r1 < f3) + self.assertFalse(r1 < f1) + self.assertFalse(r1 < f2) + self.assertTrue(r1 < r3) + self.assertFalse(r1 < r1) + self.assertFalse(r1 < r2) + with self.assertRaises(TypeError): + f1 < l3 + with self.assertRaises(TypeError): + f1 < l1 + with self.assertRaises(TypeError): + f1 < l2 + + # any subset + self.assertTrue(f1 <= f3) + self.assertTrue(f1 <= f1) + self.assertFalse(f1 <= f2) + self.assertTrue(r1 <= f3) + self.assertTrue(r1 <= f1) + self.assertFalse(r1 <= f2) + self.assertTrue(r1 <= r3) + self.assertTrue(r1 <= r1) + self.assertFalse(r1 <= r2) + with self.assertRaises(TypeError): + f1 <= l3 + with self.assertRaises(TypeError): + f1 <= l1 + with self.assertRaises(TypeError): + f1 <= l2 + + # proper superset + self.assertTrue(f3 > f1) + self.assertFalse(f1 > f1) + self.assertFalse(f2 > f1) + self.assertTrue(r3 > r1) + self.assertFalse(f1 > r1) + self.assertFalse(f2 > r1) + self.assertTrue(r3 > r1) + self.assertFalse(r1 > r1) + self.assertFalse(r2 > r1) + with self.assertRaises(TypeError): + f1 > l3 + with self.assertRaises(TypeError): + f1 > l1 with self.assertRaises(TypeError): - ncs < cs + f1 > l2 + + # any superset + self.assertTrue(f3 >= f1) + self.assertTrue(f1 >= f1) + self.assertFalse(f2 >= f1) + self.assertTrue(r3 >= r1) + self.assertTrue(f1 >= r1) + self.assertFalse(f2 >= r1) + self.assertTrue(r3 >= r1) + self.assertTrue(r1 >= r1) + self.assertFalse(r2 >= r1) with self.assertRaises(TypeError): - ncs <= cs + f1 >= l3 with self.assertRaises(TypeError): - cs > ncs + f1 >=l1 with self.assertRaises(TypeError): - cs >= ncs + f1 >= l2 + + # equality + self.assertTrue(f1 == f1) + self.assertTrue(r1 == f1) + self.assertTrue(f1 == r1) + self.assertFalse(f1 == f3) + self.assertFalse(r1 == f3) + self.assertFalse(f1 == r3) + self.assertFalse(f1 == l3) + self.assertFalse(f1 == l1) + self.assertFalse(f1 == l2) + + # inequality + self.assertFalse(f1 != f1) + self.assertFalse(r1 != f1) + self.assertFalse(f1 != r1) + self.assertTrue(f1 != f3) + self.assertTrue(r1 != f3) + self.assertTrue(f1 != r3) + self.assertTrue(f1 != l3) + self.assertTrue(f1 != l1) + self.assertTrue(f1 != l2) def test_Mapping(self): for sample in [dict]: @@ -788,6 +1262,41 @@ def test_Sequence(self): self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__', '__getitem__') + def test_Sequence_mixins(self): + class SequenceSubclass(Sequence): + def __init__(self, seq=()): + self.seq = seq + + def __getitem__(self, index): + return self.seq[index] + + def __len__(self): + return len(self.seq) + + # Compare Sequence.index() behavior to (list|str).index() behavior + def assert_index_same(seq1, seq2, index_args): + try: + expected = seq1.index(*index_args) + except ValueError: + with self.assertRaises(ValueError): + seq2.index(*index_args) + else: + actual = seq2.index(*index_args) + self.assertEqual( + actual, expected, '%r.index%s' % (seq1, index_args)) + + for ty in list, str: + nativeseq = ty('abracadabra') + indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3)) + seqseq = SequenceSubclass(nativeseq) + for letter in set(nativeseq) | {'z'}: + assert_index_same(nativeseq, seqseq, (letter,)) + for start in range(-3, len(nativeseq) + 3): + assert_index_same(nativeseq, seqseq, (letter, start)) + for stop in range(-3, len(nativeseq) + 3): + assert_index_same( + nativeseq, seqseq, (letter, start, stop)) + def test_ByteString(self): for sample in [bytes, bytearray]: self.assertIsInstance(sample(), ByteString) @@ -802,7 +1311,7 @@ def test_MutableSequence(self): for sample in [tuple, str, bytes]: self.assertNotIsInstance(sample(), MutableSequence) self.assertFalse(issubclass(sample, MutableSequence)) - for sample in [list, bytearray]: + for sample in [list, bytearray, deque]: self.assertIsInstance(sample(), MutableSequence) self.assertTrue(issubclass(sample, MutableSequence)) self.assertFalse(issubclass(str, MutableSequence)) @@ -932,32 +1441,47 @@ def test_basics(self): self.assertEqual(c.setdefault('e', 5), 5) self.assertEqual(c['e'], 5) + def test_init(self): + self.assertEqual(list(Counter(self=42).items()), [('self', 42)]) + self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)]) + self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)]) + self.assertRaises(TypeError, Counter, 42) + self.assertRaises(TypeError, Counter, (), ()) + self.assertRaises(TypeError, Counter.__init__) + + def test_update(self): + c = Counter() + c.update(self=42) + self.assertEqual(list(c.items()), [('self', 42)]) + c = Counter() + c.update(iterable=42) + self.assertEqual(list(c.items()), [('iterable', 42)]) + c = Counter() + c.update(iterable=None) + self.assertEqual(list(c.items()), [('iterable', None)]) + self.assertRaises(TypeError, Counter().update, 42) + self.assertRaises(TypeError, Counter().update, {}, {}) + self.assertRaises(TypeError, Counter.update) + def test_copying(self): # Check that counters are copyable, deepcopyable, picklable, and #have a repr/eval round-trip words = Counter('which witch had which witches wrist watch'.split()) + def check(dup): + msg = "\ncopy: %s\nwords: %s" % (dup, words) + self.assertIsNot(dup, words, msg) + self.assertEqual(dup, words) + check(words.copy()) + check(copy.copy(words)) + check(copy.deepcopy(words)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(proto=proto): + check(pickle.loads(pickle.dumps(words, proto))) + check(eval(repr(words))) update_test = Counter() update_test.update(words) - for label, dup in [ - ('words.copy()', words.copy()), - ('copy.copy(words)', copy.copy(words)), - ('copy.deepcopy(words)', copy.deepcopy(words)), - ('pickle.loads(pickle.dumps(words, 0))', - pickle.loads(pickle.dumps(words, 0))), - ('pickle.loads(pickle.dumps(words, 1))', - pickle.loads(pickle.dumps(words, 1))), - ('pickle.loads(pickle.dumps(words, 2))', - pickle.loads(pickle.dumps(words, 2))), - ('pickle.loads(pickle.dumps(words, -1))', - pickle.loads(pickle.dumps(words, -1))), - ('eval(repr(words))', eval(repr(words))), - ('update_test', update_test), - ('Counter(words)', Counter(words)), - ]: - with self.subTest(label=label): - msg = "\ncopy: %s\nwords: %s" % (dup, words) - self.assertIsNot(dup, words, msg) - self.assertEqual(dup, words) + check(update_test) + check(Counter(words)) def test_copy_subclass(self): class MyCounter(Counter): @@ -1053,6 +1577,16 @@ def test_subtract(self): c.subtract('aaaabbcce') self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1)) + c = Counter() + c.subtract(self=42) + self.assertEqual(list(c.items()), [('self', -42)]) + c = Counter() + c.subtract(iterable=42) + self.assertEqual(list(c.items()), [('iterable', -42)]) + self.assertRaises(TypeError, Counter().subtract, 42) + self.assertRaises(TypeError, Counter().subtract, {}, {}) + self.assertRaises(TypeError, Counter.subtract) + def test_unary(self): c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40)) @@ -1090,9 +1624,24 @@ def test_helper_function(self): ### OrderedDict ################################################################################ -class TestOrderedDict(unittest.TestCase): +py_coll = import_fresh_module('collections', blocked=['_collections']) +c_coll = import_fresh_module('collections', fresh=['_collections']) + + +@contextlib.contextmanager +def replaced_module(name, replacement): + original_module = sys.modules[name] + sys.modules[name] = replacement + try: + yield + finally: + sys.modules[name] = original_module + + +class OrderedDictTests: def test_init(self): + OrderedDict = self.module.OrderedDict with self.assertRaises(TypeError): OrderedDict([('a', 1), ('b', 2)], None) # too many args pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] @@ -1103,8 +1652,11 @@ def test_init(self): c=3, e=5).items()), pairs) # mixed input # make sure no positional args conflict with possible kwdargs - self.assertEqual(inspect.getargspec(OrderedDict.__dict__['__init__']).args, - ['self']) + self.assertEqual(list(OrderedDict(self=42).items()), [('self', 42)]) + self.assertEqual(list(OrderedDict(other=42).items()), [('other', 42)]) + self.assertRaises(TypeError, OrderedDict, 42) + self.assertRaises(TypeError, OrderedDict, (), ()) + self.assertRaises(TypeError, OrderedDict.__init__) # Make sure that direct calls to __init__ do not clear previous contents d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)]) @@ -1113,6 +1665,7 @@ def test_init(self): [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)]) def test_update(self): + OrderedDict = self.module.OrderedDict with self.assertRaises(TypeError): OrderedDict().update([('a', 1), ('b', 2)], None) # too many args pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] @@ -1149,11 +1702,30 @@ def test_update(self): self.assertEqual(list(d.items()), [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)]) + self.assertRaises(TypeError, OrderedDict().update, 42) + self.assertRaises(TypeError, OrderedDict().update, (), ()) + self.assertRaises(TypeError, OrderedDict.update) + + self.assertRaises(TypeError, OrderedDict().update, 42) + self.assertRaises(TypeError, OrderedDict().update, (), ()) + self.assertRaises(TypeError, OrderedDict.update) + + def test_fromkeys(self): + OrderedDict = self.module.OrderedDict + od = OrderedDict.fromkeys('abc') + self.assertEqual(list(od.items()), [(c, None) for c in 'abc']) + od = OrderedDict.fromkeys('abc', value=None) + self.assertEqual(list(od.items()), [(c, None) for c in 'abc']) + od = OrderedDict.fromkeys('abc', value=0) + self.assertEqual(list(od.items()), [(c, 0) for c in 'abc']) + def test_abc(self): + OrderedDict = self.module.OrderedDict self.assertIsInstance(OrderedDict(), MutableMapping) self.assertTrue(issubclass(OrderedDict, MutableMapping)) def test_clear(self): + OrderedDict = self.module.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] shuffle(pairs) od = OrderedDict(pairs) @@ -1162,6 +1734,7 @@ def test_clear(self): self.assertEqual(len(od), 0) def test_delitem(self): + OrderedDict = self.module.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] od = OrderedDict(pairs) del od['a'] @@ -1171,6 +1744,7 @@ def test_delitem(self): self.assertEqual(list(od.items()), pairs[:2] + pairs[3:]) def test_setitem(self): + OrderedDict = self.module.OrderedDict od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)]) od['c'] = 10 # existing element od['f'] = 20 # new element @@ -1178,6 +1752,7 @@ def test_setitem(self): [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)]) def test_iterators(self): + OrderedDict = self.module.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] shuffle(pairs) od = OrderedDict(pairs) @@ -1187,8 +1762,51 @@ def test_iterators(self): self.assertEqual(list(od.items()), pairs) self.assertEqual(list(reversed(od)), [t[0] for t in reversed(pairs)]) + self.assertEqual(list(reversed(od.keys())), + [t[0] for t in reversed(pairs)]) + self.assertEqual(list(reversed(od.values())), + [t[1] for t in reversed(pairs)]) + self.assertEqual(list(reversed(od.items())), list(reversed(pairs))) + + def test_detect_deletion_during_iteration(self): + OrderedDict = self.module.OrderedDict + od = OrderedDict.fromkeys('abc') + it = iter(od) + key = next(it) + del od[key] + with self.assertRaises(Exception): + # Note, the exact exception raised is not guaranteed + # The only guarantee that the next() will not succeed + next(it) + + def test_sorted_iterators(self): + OrderedDict = self.module.OrderedDict + with self.assertRaises(TypeError): + OrderedDict([('a', 1), ('b', 2)], None) + pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] + od = OrderedDict(pairs) + self.assertEqual(sorted(od), [t[0] for t in pairs]) + self.assertEqual(sorted(od.keys()), [t[0] for t in pairs]) + self.assertEqual(sorted(od.values()), [t[1] for t in pairs]) + self.assertEqual(sorted(od.items()), pairs) + self.assertEqual(sorted(reversed(od)), + sorted([t[0] for t in reversed(pairs)])) + + def test_iterators_empty(self): + OrderedDict = self.module.OrderedDict + od = OrderedDict() + empty = [] + self.assertEqual(list(od), empty) + self.assertEqual(list(od.keys()), empty) + self.assertEqual(list(od.values()), empty) + self.assertEqual(list(od.items()), empty) + self.assertEqual(list(reversed(od)), empty) + self.assertEqual(list(reversed(od.keys())), empty) + self.assertEqual(list(reversed(od.values())), empty) + self.assertEqual(list(reversed(od.items())), empty) def test_popitem(self): + OrderedDict = self.module.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] shuffle(pairs) od = OrderedDict(pairs) @@ -1198,7 +1816,19 @@ def test_popitem(self): od.popitem() self.assertEqual(len(od), 0) + def test_popitem_last(self): + OrderedDict = self.module.OrderedDict + pairs = [(i, i) for i in range(30)] + + obj = OrderedDict(pairs) + for i in range(8): + obj.popitem(True) + obj.popitem(True) + obj.popitem(last=True) + self.assertEqual(len(obj), 20) + def test_pop(self): + OrderedDict = self.module.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] shuffle(pairs) od = OrderedDict(pairs) @@ -1219,10 +1849,12 @@ def __missing__(self, key): self.assertEqual(m.pop('b', 5), 5) self.assertEqual(m.pop('a', 6), 1) self.assertEqual(m.pop('a', 6), 6) + self.assertEqual(m.pop('a', default=6), 6) with self.assertRaises(KeyError): m.pop('a') def test_equality(self): + OrderedDict = self.module.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] shuffle(pairs) od1 = OrderedDict(pairs) @@ -1238,36 +1870,34 @@ def test_equality(self): self.assertNotEqual(od1, OrderedDict(pairs[:-1])) def test_copying(self): + OrderedDict = self.module.OrderedDict # Check that ordered dicts are copyable, deepcopyable, picklable, # and have a repr/eval round-trip pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] od = OrderedDict(pairs) + def check(dup): + msg = "\ncopy: %s\nod: %s" % (dup, od) + self.assertIsNot(dup, od, msg) + self.assertEqual(dup, od) + self.assertEqual(list(dup.items()), list(od.items())) + self.assertEqual(len(dup), len(od)) + self.assertEqual(type(dup), type(od)) + check(od.copy()) + check(copy.copy(od)) + check(copy.deepcopy(od)) + # pickle directly pulls the module, so we have to fake it + with replaced_module('collections', self.module): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(proto=proto): + check(pickle.loads(pickle.dumps(od, proto))) + check(eval(repr(od))) update_test = OrderedDict() update_test.update(od) - for label, dup in [ - ('od.copy()', od.copy()), - ('copy.copy(od)', copy.copy(od)), - ('copy.deepcopy(od)', copy.deepcopy(od)), - ('pickle.loads(pickle.dumps(od, 0))', - pickle.loads(pickle.dumps(od, 0))), - ('pickle.loads(pickle.dumps(od, 1))', - pickle.loads(pickle.dumps(od, 1))), - ('pickle.loads(pickle.dumps(od, 2))', - pickle.loads(pickle.dumps(od, 2))), - ('pickle.loads(pickle.dumps(od, 3))', - pickle.loads(pickle.dumps(od, 3))), - ('pickle.loads(pickle.dumps(od, -1))', - pickle.loads(pickle.dumps(od, -1))), - ('eval(repr(od))', eval(repr(od))), - ('update_test', update_test), - ('OrderedDict(od)', OrderedDict(od)), - ]: - with self.subTest(label=label): - msg = "\ncopy: %s\nod: %s" % (dup, od) - self.assertIsNot(dup, od, msg) - self.assertEqual(dup, od) + check(update_test) + check(OrderedDict(od)) def test_yaml_linkage(self): + OrderedDict = self.module.OrderedDict # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature. # In yaml, lists are native but tuples are not. pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] @@ -1277,6 +1907,7 @@ def test_yaml_linkage(self): self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1])) def test_reduce_not_too_fat(self): + OrderedDict = self.module.OrderedDict # do not save instance dictionary if not needed pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] od = OrderedDict(pairs) @@ -1285,15 +1916,20 @@ def test_reduce_not_too_fat(self): self.assertIsNotNone(od.__reduce__()[2]) def test_pickle_recursive(self): + OrderedDict = self.module.OrderedDict od = OrderedDict() od[1] = od - for proto in range(-1, pickle.HIGHEST_PROTOCOL + 1): - dup = pickle.loads(pickle.dumps(od, proto)) - self.assertIsNot(dup, od) - self.assertEqual(list(dup.keys()), [1]) - self.assertIs(dup[1], dup) + + # pickle directly pulls the module, so we have to fake it + with replaced_module('collections', self.module): + for proto in range(-1, pickle.HIGHEST_PROTOCOL + 1): + dup = pickle.loads(pickle.dumps(od, proto)) + self.assertIsNot(dup, od) + self.assertEqual(list(dup.keys()), [1]) + self.assertIs(dup[1], dup) def test_repr(self): + OrderedDict = self.module.OrderedDict od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]) self.assertEqual(repr(od), "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])") @@ -1301,6 +1937,7 @@ def test_repr(self): self.assertEqual(repr(OrderedDict()), "OrderedDict()") def test_repr_recursive(self): + OrderedDict = self.module.OrderedDict # See issue #9826 od = OrderedDict.fromkeys('abc') od['x'] = od @@ -1308,6 +1945,7 @@ def test_repr_recursive(self): "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])") def test_setdefault(self): + OrderedDict = self.module.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] shuffle(pairs) od = OrderedDict(pairs) @@ -1318,6 +1956,7 @@ def test_setdefault(self): self.assertEqual(od.setdefault('x', 10), 10) # make sure 'x' is added to the end self.assertEqual(list(od.items())[-1], ('x', 10)) + self.assertEqual(od.setdefault('g', default=9), 9) # make sure setdefault still works when __missing__ is defined class Missing(OrderedDict): @@ -1326,16 +1965,19 @@ def __missing__(self, key): self.assertEqual(Missing().setdefault(5, 9), 9) def test_reinsert(self): + OrderedDict = self.module.OrderedDict # Given insert a, insert b, delete a, re-insert a, # verify that a is now later than b. od = OrderedDict() od['a'] = 1 od['b'] = 2 del od['a'] + self.assertEqual(list(od.items()), [('b', 2)]) od['a'] = 1 self.assertEqual(list(od.items()), [('b', 2), ('a', 1)]) def test_move_to_end(self): + OrderedDict = self.module.OrderedDict od = OrderedDict.fromkeys('abcde') self.assertEqual(list(od), list('abcde')) od.move_to_end('c') @@ -1346,16 +1988,44 @@ def test_move_to_end(self): self.assertEqual(list(od), list('cabde')) od.move_to_end('e') self.assertEqual(list(od), list('cabde')) + od.move_to_end('b', last=False) + self.assertEqual(list(od), list('bcade')) with self.assertRaises(KeyError): od.move_to_end('x') + with self.assertRaises(KeyError): + od.move_to_end('x', 0) + + def test_move_to_end_issue25406(self): + OrderedDict = self.module.OrderedDict + od = OrderedDict.fromkeys('abc') + od.move_to_end('c', last=False) + self.assertEqual(list(od), list('cab')) + od.move_to_end('a', last=False) + self.assertEqual(list(od), list('acb')) + + od = OrderedDict.fromkeys('abc') + od.move_to_end('a') + self.assertEqual(list(od), list('bca')) + od.move_to_end('c') + self.assertEqual(list(od), list('bac')) def test_sizeof(self): + OrderedDict = self.module.OrderedDict # Wimpy test: Just verify the reported size is larger than a regular dict d = dict(a=1) od = OrderedDict(**d) self.assertGreater(sys.getsizeof(od), sys.getsizeof(d)) + def test_views(self): + OrderedDict = self.module.OrderedDict + # See http://bugs.python.org/issue24286 + s = 'the quick brown fox jumped over a lazy dog yesterday before dawn'.split() + od = OrderedDict.fromkeys(s) + self.assertEqual(od.keys(), dict(od).keys()) + self.assertEqual(od.items(), dict(od).items()) + def test_override_update(self): + OrderedDict = self.module.OrderedDict # Verify that subclasses can override update() without breaking __init__() class MyOD(OrderedDict): def update(self, *args, **kwds): @@ -1363,18 +2033,171 @@ def update(self, *args, **kwds): items = [('a', 1), ('c', 3), ('b', 2)] self.assertEqual(list(MyOD(items).items()), items) -class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol): - type2test = OrderedDict + +class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase): + + module = py_coll + + +@unittest.skipUnless(c_coll, 'requires the C version of the collections module') +class CPythonOrderedDictTests(OrderedDictTests, unittest.TestCase): + + module = c_coll + + def test_delitem_hash_collision(self): + OrderedDict = self.module.OrderedDict + + class Key: + def __init__(self, hash): + self._hash = hash + self.value = str(id(self)) + def __hash__(self): + return self._hash + def __eq__(self, other): + try: + return self.value == other.value + except AttributeError: + return False + def __repr__(self): + return self.value + + def blocking_hash(hash): + # See the collision-handling in lookdict (in Objects/dictobject.c). + MINSIZE = 8 + i = (hash & MINSIZE-1) + return (i << 2) + i + hash + 1 + + COLLIDING = 1 + + key = Key(COLLIDING) + colliding = Key(COLLIDING) + blocking = Key(blocking_hash(COLLIDING)) + + od = OrderedDict() + od[key] = ... + od[blocking] = ... + od[colliding] = ... + od['after'] = ... + + del od[blocking] + del od[colliding] + self.assertEqual(list(od.items()), [(key, ...), ('after', ...)]) + + def test_key_change_during_iteration(self): + OrderedDict = self.module.OrderedDict + + od = OrderedDict.fromkeys('abcde') + self.assertEqual(list(od), list('abcde')) + with self.assertRaises(RuntimeError): + for i, k in enumerate(od): + od.move_to_end(k) + self.assertLess(i, 5) + with self.assertRaises(RuntimeError): + for k in od: + od['f'] = None + with self.assertRaises(RuntimeError): + for k in od: + del od['c'] + self.assertEqual(list(od), list('bdeaf')) + + def test_issue24347(self): + OrderedDict = self.module.OrderedDict + + class Key: + def __hash__(self): + return randrange(100000) + + od = OrderedDict() + for i in range(100): + key = Key() + od[key] = i + + # These should not crash. + with self.assertRaises(KeyError): + repr(od) + with self.assertRaises(KeyError): + od.copy() + + def test_issue24348(self): + OrderedDict = self.module.OrderedDict + + class Key: + def __hash__(self): + return 1 + + od = OrderedDict() + od[Key()] = 0 + # This should not crash. + od.popitem() + + def test_issue24667(self): + """ + dict resizes after a certain number of insertion operations, + whether or not there were deletions that freed up slots in the + hash table. During fast node lookup, OrderedDict must correctly + respond to all resizes, even if the current "size" is the same + as the old one. We verify that here by forcing a dict resize + on a sparse odict and then perform an operation that should + trigger an odict resize (e.g. popitem). One key aspect here is + that we will keep the size of the odict the same at each popitem + call. This verifies that we handled the dict resize properly. + """ + OrderedDict = self.module.OrderedDict + + od = OrderedDict() + for c0 in '0123456789ABCDEF': + for c1 in '0123456789ABCDEF': + if len(od) == 4: + # This should not raise a KeyError. + od.popitem(last=False) + key = c0 + c1 + od[key] = key + + +class PurePythonGeneralMappingTests(mapping_tests.BasicTestMappingProtocol): + + @classmethod + def setUpClass(cls): + cls.type2test = py_coll.OrderedDict + + def test_popitem(self): + d = self._empty_mapping() + self.assertRaises(KeyError, d.popitem) + + +@unittest.skipUnless(c_coll, 'requires the C version of the collections module') +class CPythonGeneralMappingTests(mapping_tests.BasicTestMappingProtocol): + + @classmethod + def setUpClass(cls): + cls.type2test = c_coll.OrderedDict def test_popitem(self): d = self._empty_mapping() self.assertRaises(KeyError, d.popitem) -class MyOrderedDict(OrderedDict): - pass -class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol): - type2test = MyOrderedDict +class PurePythonSubclassMappingTests(mapping_tests.BasicTestMappingProtocol): + + @classmethod + def setUpClass(cls): + class MyOrderedDict(py_coll.OrderedDict): + pass + cls.type2test = MyOrderedDict + + def test_popitem(self): + d = self._empty_mapping() + self.assertRaises(KeyError, d.popitem) + + +@unittest.skipUnless(c_coll, 'requires the C version of the collections module') +class CPythonSubclassMappingTests(mapping_tests.BasicTestMappingProtocol): + + @classmethod + def setUpClass(cls): + class MyOrderedDict(c_coll.OrderedDict): + pass + cls.type2test = MyOrderedDict def test_popitem(self): d = self._empty_mapping() @@ -1391,7 +2214,11 @@ def test_main(verbose=None): NamedTupleDocs = doctest.DocTestSuite(module=collections) test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs, TestCollectionABCs, TestCounter, TestChainMap, - TestOrderedDict, GeneralMappingTests, SubclassMappingTests] + PurePythonOrderedDictTests, CPythonOrderedDictTests, + PurePythonGeneralMappingTests, CPythonGeneralMappingTests, + PurePythonSubclassMappingTests, CPythonSubclassMappingTests, + TestUserObjects, + ] support.run_unittest(*test_classes) support.run_doctest(collections, verbose) diff --git a/Lib/test/test_compare.py b/Lib/test/test_compare.py index ee3794ae9a3d..471c8dae767a 100644 --- a/Lib/test/test_compare.py +++ b/Lib/test/test_compare.py @@ -1,5 +1,4 @@ import unittest -from test import support class Empty: def __repr__(self): @@ -48,8 +47,69 @@ def test_id_comparisons(self): def test_ne_defaults_to_not_eq(self): a = Cmp(1) b = Cmp(1) - self.assertTrue(a == b) - self.assertFalse(a != b) + c = Cmp(2) + self.assertIs(a == b, True) + self.assertIs(a != b, False) + self.assertIs(a != c, True) + + def test_ne_high_priority(self): + """object.__ne__() should allow reflected __ne__() to be tried""" + calls = [] + class Left: + # Inherits object.__ne__() + def __eq__(*args): + calls.append('Left.__eq__') + return NotImplemented + class Right: + def __eq__(*args): + calls.append('Right.__eq__') + return NotImplemented + def __ne__(*args): + calls.append('Right.__ne__') + return NotImplemented + Left() != Right() + self.assertSequenceEqual(calls, ['Left.__eq__', 'Right.__ne__']) + + def test_ne_low_priority(self): + """object.__ne__() should not invoke reflected __eq__()""" + calls = [] + class Base: + # Inherits object.__ne__() + def __eq__(*args): + calls.append('Base.__eq__') + return NotImplemented + class Derived(Base): # Subclassing forces higher priority + def __eq__(*args): + calls.append('Derived.__eq__') + return NotImplemented + def __ne__(*args): + calls.append('Derived.__ne__') + return NotImplemented + Base() != Derived() + self.assertSequenceEqual(calls, ['Derived.__ne__', 'Base.__eq__']) + + def test_other_delegation(self): + """No default delegation between operations except __ne__()""" + ops = ( + ('__eq__', lambda a, b: a == b), + ('__lt__', lambda a, b: a < b), + ('__le__', lambda a, b: a <= b), + ('__gt__', lambda a, b: a > b), + ('__ge__', lambda a, b: a >= b), + ) + for name, func in ops: + with self.subTest(name): + def unexpected(*args): + self.fail('Unexpected operator method called') + class C: + __ne__ = unexpected + for other, _ in ops: + if other != name: + setattr(C, other, unexpected) + if name == '__eq__': + self.assertIs(func(C(), object()), False) + else: + self.assertRaises(TypeError, func, C(), object()) def test_issue_1393(self): x = lambda: None @@ -60,8 +120,5 @@ def test_issue_1393(self): self.assertEqual(Anything(), y) -def test_main(): - support.run_unittest(ComparisonTest) - if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index ccd08db66703..db821be031c9 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -1,8 +1,12 @@ +import math +import os import unittest import sys import _ast +import tempfile import types from test import support +from test.support import script_helper class TestSpecifics(unittest.TestCase): @@ -303,9 +307,26 @@ def test_lambda_doc(self): l = lambda: "foo" self.assertIsNone(l.__doc__) -## def test_unicode_encoding(self): -## code = "# -*- coding: utf-8 -*-\npass\n" -## self.assertRaises(SyntaxError, compile, code, "tmp", "exec") + def test_encoding(self): + code = b'# -*- coding: badencoding -*-\npass\n' + self.assertRaises(SyntaxError, compile, code, 'tmp', 'exec') + code = '# -*- coding: badencoding -*-\n"\xc2\xa4"\n' + compile(code, 'tmp', 'exec') + self.assertEqual(eval(code), '\xc2\xa4') + code = '"\xc2\xa4"\n' + self.assertEqual(eval(code), '\xc2\xa4') + code = b'"\xc2\xa4"\n' + self.assertEqual(eval(code), '\xa4') + code = b'# -*- coding: latin1 -*-\n"\xc2\xa4"\n' + self.assertEqual(eval(code), '\xc2\xa4') + code = b'# -*- coding: utf-8 -*-\n"\xc2\xa4"\n' + self.assertEqual(eval(code), '\xa4') + code = b'# -*- coding: iso8859-15 -*-\n"\xc2\xa4"\n' + self.assertEqual(eval(code), '\xc2\u20ac') + code = '"""\\\n# -*- coding: iso8859-15 -*-\n\xc2\xa4"""\n' + self.assertEqual(eval(code), '# -*- coding: iso8859-15 -*-\n\xc2\xa4') + code = b'"""\\\n# -*- coding: iso8859-15 -*-\n\xc2\xa4"""\n' + self.assertEqual(eval(code), '# -*- coding: iso8859-15 -*-\n\xa4') def test_subscripts(self): # SF bug 1448804 @@ -407,7 +428,7 @@ def f(): def test_compile_ast(self): fname = __file__ - if fname.lower().endswith(('pyc', 'pyo')): + if fname.lower().endswith('pyc'): fname = fname[:-1] with open(fname, 'r') as f: fcontents = f.read() @@ -440,6 +461,17 @@ def test_compile_ast(self): ast.body = [_ast.BoolOp()] self.assertRaises(TypeError, compile, ast, '', 'exec') + def test_dict_evaluation_order(self): + i = 0 + + def f(): + nonlocal i + i += 1 + return i + + d = {f(): f(), f(): f()} + self.assertEqual(d, {1: 2, 3: 4}) + @support.cpython_only def test_same_filename_used(self): s = """def f(): pass\ndef g(): pass""" @@ -474,6 +506,16 @@ def test_bad_single_statement(self): self.assertInvalidSingle('f()\nxy # blah\nblah()') self.assertInvalidSingle('x = 5 # comment\nx = 6\n') + def test_particularly_evil_undecodable(self): + # Issue 24022 + src = b'0000\x00\n00000000000\n\x00\n\x9e\n' + with tempfile.TemporaryDirectory() as tmpd: + fn = os.path.join(tmpd, "bad.py") + with open(fn, "wb") as fp: + fp.write(src) + res = script_helper.run_python_until_end(fn)[0] + self.assertIn(b"Non-UTF-8", res.err) + @support.cpython_only def test_compiler_recursion_limit(self): # Expected limit is sys.getrecursionlimit() * the scaling factor @@ -492,7 +534,7 @@ def check_limit(prefix, repeated): broken = prefix + repeated * fail_depth details = "Compiling ({!r} + {!r} * {})".format( prefix, repeated, fail_depth) - with self.assertRaises(RuntimeError, msg=details): + with self.assertRaises(RecursionError, msg=details): self.compile_single(broken) check_limit("a", "()") @@ -501,8 +543,43 @@ def check_limit(prefix, repeated): check_limit("a", "*a") -def test_main(): - support.run_unittest(TestSpecifics) +class TestStackSize(unittest.TestCase): + # These tests check that the computed stack size for a code object + # stays within reasonable bounds (see issue #21523 for an example + # dysfunction). + N = 100 + + def check_stack_size(self, code): + # To assert that the alleged stack size is not O(N), we + # check that it is smaller than log(N). + if isinstance(code, str): + code = compile(code, "", "single") + max_size = math.ceil(math.log(len(code.co_code))) + self.assertLessEqual(code.co_stacksize, max_size) + + def test_and(self): + self.check_stack_size("x and " * self.N + "x") + + def test_or(self): + self.check_stack_size("x or " * self.N + "x") + + def test_and_or(self): + self.check_stack_size("x and x or " * self.N + "x") + + def test_chained_comparison(self): + self.check_stack_size("x < " * self.N + "x") + + def test_if_else(self): + self.check_stack_size("x if x else " * self.N + "x") + + def test_binop(self): + self.check_stack_size("x + " * self.N + "x") + + def test_func_and(self): + code = "def f(x):\n" + code += " x and x\n" * self.N + self.check_stack_size(code) + if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_compileall.py b/Lib/test/test_compileall.py index ff2515df4cf1..ef2b66935682 100644 --- a/Lib/test/test_compileall.py +++ b/Lib/test/test_compileall.py @@ -2,17 +2,24 @@ import compileall import importlib.util import os +import pathlib import py_compile import shutil import struct -import subprocess -import sys import tempfile import time import unittest import io -from test import support, script_helper +from unittest import mock, skipUnless +try: + from concurrent.futures import ProcessPoolExecutor + _have_multiprocessing = True +except ImportError: + _have_multiprocessing = False + +from test import support +from test.support import script_helper class CompileallTests(unittest.TestCase): @@ -96,18 +103,45 @@ def test_no_pycache_in_non_package(self): def test_optimize(self): # make sure compiling with different optimization settings than the # interpreter's creates the correct file names - optimize = 1 if __debug__ else 0 + optimize, opt = (1, 1) if __debug__ else (0, '') compileall.compile_dir(self.directory, quiet=True, optimize=optimize) cached = importlib.util.cache_from_source(self.source_path, - debug_override=not optimize) + optimization=opt) self.assertTrue(os.path.isfile(cached)) cached2 = importlib.util.cache_from_source(self.source_path2, - debug_override=not optimize) + optimization=opt) self.assertTrue(os.path.isfile(cached2)) cached3 = importlib.util.cache_from_source(self.source_path3, - debug_override=not optimize) + optimization=opt) self.assertTrue(os.path.isfile(cached3)) + @mock.patch('compileall.ProcessPoolExecutor') + def test_compile_pool_called(self, pool_mock): + compileall.compile_dir(self.directory, quiet=True, workers=5) + self.assertTrue(pool_mock.called) + + def test_compile_workers_non_positive(self): + with self.assertRaisesRegex(ValueError, + "workers must be greater or equal to 0"): + compileall.compile_dir(self.directory, workers=-1) + + @mock.patch('compileall.ProcessPoolExecutor') + def test_compile_workers_cpu_count(self, pool_mock): + compileall.compile_dir(self.directory, quiet=True, workers=0) + self.assertEqual(pool_mock.call_args[1]['max_workers'], None) + + @mock.patch('compileall.ProcessPoolExecutor') + @mock.patch('compileall.compile_file') + def test_compile_one_worker(self, compile_file_mock, pool_mock): + compileall.compile_dir(self.directory, quiet=True) + self.assertFalse(pool_mock.called) + self.assertTrue(compile_file_mock.called) + + @mock.patch('compileall.ProcessPoolExecutor', new=None) + @mock.patch('compileall.compile_file') + def test_compile_missing_multiprocessing(self, compile_file_mock): + compileall.compile_dir(self.directory, quiet=True, workers=5) + self.assertTrue(compile_file_mock.called) class EncodingTest(unittest.TestCase): """Issue 6716: compileall should escape source code when printing errors @@ -135,6 +169,33 @@ def test_error(self): class CommandLineTests(unittest.TestCase): """Test compileall's CLI.""" + @classmethod + def setUpClass(cls): + for path in filter(os.path.isdir, sys.path): + directory_created = False + directory = pathlib.Path(path) / '__pycache__' + path = directory / 'test.try' + try: + if not directory.is_dir(): + directory.mkdir() + directory_created = True + with path.open('w') as file: + file.write('# for test_compileall') + except OSError: + sys_path_writable = False + break + finally: + support.unlink(str(path)) + if directory_created: + directory.rmdir() + else: + sys_path_writable = True + cls._sys_path_writable = sys_path_writable + + def _skip_if_sys_path_not_writable(self): + if not self._sys_path_writable: + raise unittest.SkipTest('not all entries on sys.path are writable') + def _get_run_args(self, args): interp_args = ['-S'] if sys.flags.optimize: @@ -161,8 +222,8 @@ def assertNotCompiled(self, fn): self.assertFalse(os.path.exists(path)) def setUp(self): - self.addCleanup(self._cleanup) self.directory = tempfile.mkdtemp() + self.addCleanup(support.rmtree, self.directory) self.pkgdir = os.path.join(self.directory, 'foo') os.mkdir(self.pkgdir) self.pkgdir_cachedir = os.path.join(self.pkgdir, '__pycache__') @@ -170,23 +231,46 @@ def setUp(self): self.initfn = script_helper.make_script(self.pkgdir, '__init__', '') self.barfn = script_helper.make_script(self.pkgdir, 'bar', '') - def _cleanup(self): - support.rmtree(self.directory) - def test_no_args_compiles_path(self): # Note that -l is implied for the no args case. + self._skip_if_sys_path_not_writable() bazfn = script_helper.make_script(self.directory, 'baz', '') self.assertRunOK(PYTHONPATH=self.directory) self.assertCompiled(bazfn) self.assertNotCompiled(self.initfn) self.assertNotCompiled(self.barfn) + def test_no_args_respects_force_flag(self): + self._skip_if_sys_path_not_writable() + bazfn = script_helper.make_script(self.directory, 'baz', '') + self.assertRunOK(PYTHONPATH=self.directory) + pycpath = importlib.util.cache_from_source(bazfn) + # Set atime/mtime backward to avoid file timestamp resolution issues + os.utime(pycpath, (time.time()-60,)*2) + mtime = os.stat(pycpath).st_mtime + # Without force, no recompilation + self.assertRunOK(PYTHONPATH=self.directory) + mtime2 = os.stat(pycpath).st_mtime + self.assertEqual(mtime, mtime2) + # Now force it. + self.assertRunOK('-f', PYTHONPATH=self.directory) + mtime2 = os.stat(pycpath).st_mtime + self.assertNotEqual(mtime, mtime2) + + def test_no_args_respects_quiet_flag(self): + self._skip_if_sys_path_not_writable() + script_helper.make_script(self.directory, 'baz', '') + noisy = self.assertRunOK(PYTHONPATH=self.directory) + self.assertIn(b'Listing ', noisy) + quiet = self.assertRunOK('-q', PYTHONPATH=self.directory) + self.assertNotIn(b'Listing ', quiet) + # Ensure that the default behavior of compileall's CLI is to create - # PEP 3147 pyc/pyo files. + # PEP 3147/PEP 488 pyc files. for name, ext, switch in [ ('normal', 'pyc', []), - ('optimize', 'pyo', ['-O']), - ('doubleoptimize', 'pyo', ['-OO']), + ('optimize', 'opt-1.pyc', ['-O']), + ('doubleoptimize', 'opt-2.pyc', ['-OO']), ]: def f(self, ext=ext, switch=switch): script_helper.assert_python_ok(*(switch + @@ -203,13 +287,12 @@ def f(self, ext=ext, switch=switch): def test_legacy_paths(self): # Ensure that with the proper switch, compileall leaves legacy - # pyc/pyo files, and no __pycache__ directory. + # pyc files, and no __pycache__ directory. self.assertRunOK('-b', '-q', self.pkgdir) # Verify the __pycache__ directory contents. self.assertFalse(os.path.exists(self.pkgdir_cachedir)) - opt = 'c' if __debug__ else 'o' - expected = sorted(['__init__.py', '__init__.py' + opt, 'bar.py', - 'bar.py' + opt]) + expected = sorted(['__init__.py', '__init__.pyc', 'bar.py', + 'bar.pyc']) self.assertEqual(sorted(os.listdir(self.pkgdir)), expected) def test_multiple_runs(self): @@ -252,12 +335,53 @@ def test_recursion_control(self): self.assertCompiled(subinitfn) self.assertCompiled(hamfn) + def test_recursion_limit(self): + subpackage = os.path.join(self.pkgdir, 'spam') + subpackage2 = os.path.join(subpackage, 'ham') + subpackage3 = os.path.join(subpackage2, 'eggs') + for pkg in (subpackage, subpackage2, subpackage3): + script_helper.make_pkg(pkg) + + subinitfn = os.path.join(subpackage, '__init__.py') + hamfn = script_helper.make_script(subpackage, 'ham', '') + spamfn = script_helper.make_script(subpackage2, 'spam', '') + eggfn = script_helper.make_script(subpackage3, 'egg', '') + + self.assertRunOK('-q', '-r 0', self.pkgdir) + self.assertNotCompiled(subinitfn) + self.assertFalse( + os.path.exists(os.path.join(subpackage, '__pycache__'))) + + self.assertRunOK('-q', '-r 1', self.pkgdir) + self.assertCompiled(subinitfn) + self.assertCompiled(hamfn) + self.assertNotCompiled(spamfn) + + self.assertRunOK('-q', '-r 2', self.pkgdir) + self.assertCompiled(subinitfn) + self.assertCompiled(hamfn) + self.assertCompiled(spamfn) + self.assertNotCompiled(eggfn) + + self.assertRunOK('-q', '-r 5', self.pkgdir) + self.assertCompiled(subinitfn) + self.assertCompiled(hamfn) + self.assertCompiled(spamfn) + self.assertCompiled(eggfn) + def test_quiet(self): noisy = self.assertRunOK(self.pkgdir) quiet = self.assertRunOK('-q', self.pkgdir) self.assertNotEqual(b'', noisy) self.assertEqual(b'', quiet) + def test_silent(self): + script_helper.make_script(self.pkgdir, 'crunchyfrog', 'bad(syntax') + _, quiet, _ = self.assertRunNotOK('-q', self.pkgdir) + _, silent, _ = self.assertRunNotOK('-qq', self.pkgdir) + self.assertNotEqual(b'', quiet) + self.assertEqual(b'', silent) + def test_regexp(self): self.assertRunOK('-q', '-x', r'ba[^\\/]*$', self.pkgdir) self.assertNotCompiled(self.barfn) @@ -358,6 +482,29 @@ def test_invalid_arg_produces_message(self): out = self.assertRunOK('badfilename') self.assertRegex(out, b"Can't list 'badfilename'") + @skipUnless(_have_multiprocessing, "requires multiprocessing") + def test_workers(self): + bar2fn = script_helper.make_script(self.directory, 'bar2', '') + files = [] + for suffix in range(5): + pkgdir = os.path.join(self.directory, 'foo{}'.format(suffix)) + os.mkdir(pkgdir) + fn = script_helper.make_script(pkgdir, '__init__', '') + files.append(script_helper.make_script(pkgdir, 'bar2', '')) + + self.assertRunOK(self.directory, '-j', '0') + self.assertCompiled(bar2fn) + for file in files: + self.assertCompiled(file) + + @mock.patch('compileall.compile_dir') + def test_workers_available_cores(self, compile_dir): + with mock.patch("sys.argv", + new=[sys.executable, self.directory, "-j0"]): + compileall.main() + self.assertTrue(compile_dir.called) + self.assertEqual(compile_dir.call_args[-1]['workers'], None) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py index cd55375bdb98..0ef9a7a1098e 100644 --- a/Lib/test/test_complex.py +++ b/Lib/test/test_complex.py @@ -27,7 +27,7 @@ def assertAlmostEqual(self, a, b): unittest.TestCase.assertAlmostEqual(self, a, b) def assertCloseAbs(self, x, y, eps=1e-9): - """Return true iff floats x and y "are close\"""" + """Return true iff floats x and y "are close".""" # put the one with larger magnitude second if abs(x) > abs(y): x, y = y, x @@ -62,7 +62,7 @@ def assertFloatsAreIdentical(self, x, y): self.fail(msg.format(x, y)) def assertClose(self, x, y, eps=1e-9): - """Return true iff complexes x and y "are close\"""" + """Return true iff complexes x and y "are close".""" self.assertCloseAbs(x.real, y.real, eps) self.assertCloseAbs(x.imag, y.imag, eps) @@ -104,6 +104,11 @@ def test_truediv(self): self.assertAlmostEqual(complex.__truediv__(2+0j, 1+1j), 1-1j) self.assertRaises(ZeroDivisionError, complex.__truediv__, 1+1j, 0+0j) + for denom_real, denom_imag in [(0, NAN), (NAN, 0), (NAN, NAN)]: + z = complex(0, 0) / complex(denom_real, denom_imag) + self.assertTrue(isnan(z.real)) + self.assertTrue(isnan(z.imag)) + def test_floordiv(self): self.assertRaises(TypeError, complex.__floordiv__, 3+0j, 1.5+0j) self.assertRaises(TypeError, complex.__floordiv__, 3+0j, 0+0j) diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index a7e945cb5e9d..b99740b47db7 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -9,8 +9,9 @@ # without thread support. test.support.import_module('threading') -from test.script_helper import assert_python_ok +from test.support.script_helper import assert_python_ok +import os import sys import threading import time @@ -350,6 +351,13 @@ def test_zero_timeout(self): SUCCESSFUL_FUTURE]), completed_futures) + def test_duplicate_futures(self): + # Issue 20367. Duplicate futures should not raise exceptions or give + # duplicate responses. + future1 = self.executor.submit(time.sleep, 2) + completed = [f for f in futures.as_completed([future1,future1])] + self.assertEqual(len(completed), 1) + class ThreadPoolAsCompletedTests(ThreadPoolMixin, AsCompletedTests, unittest.TestCase): pass @@ -418,6 +426,13 @@ def test_no_stale_references(self): self.assertTrue(collected, "Stale reference not collected within timeout.") + def test_max_workers_negative(self): + for number in (0, -1): + with self.assertRaisesRegex(ValueError, + "max_workers must be greater " + "than 0"): + self.executor_type(max_workers=number) + class ThreadPoolExecutorTest(ThreadPoolMixin, ExecutorTest, unittest.TestCase): def test_map_submits_without_iteration(self): @@ -430,6 +445,11 @@ def record_finished(n): self.executor.shutdown(wait=True) self.assertCountEqual(finished, range(10)) + def test_default_workers(self): + executor = self.executor_type() + self.assertEqual(executor._max_workers, + (os.cpu_count() or 1) * 5) + class ProcessPoolExecutorTest(ProcessPoolMixin, ExecutorTest, unittest.TestCase): def test_killed_child(self): @@ -444,6 +464,48 @@ def test_killed_child(self): # Submitting other jobs fails as well. self.assertRaises(BrokenProcessPool, self.executor.submit, pow, 2, 8) + def test_map_chunksize(self): + def bad_map(): + list(self.executor.map(pow, range(40), range(40), chunksize=-1)) + + ref = list(map(pow, range(40), range(40))) + self.assertEqual( + list(self.executor.map(pow, range(40), range(40), chunksize=6)), + ref) + self.assertEqual( + list(self.executor.map(pow, range(40), range(40), chunksize=50)), + ref) + self.assertEqual( + list(self.executor.map(pow, range(40), range(40), chunksize=40)), + ref) + self.assertRaises(ValueError, bad_map) + + @classmethod + def _test_traceback(cls): + raise RuntimeError(123) # some comment + + def test_traceback(self): + # We want ensure that the traceback from the child process is + # contained in the traceback raised in the main process. + future = self.executor.submit(self._test_traceback) + with self.assertRaises(Exception) as cm: + future.result() + + exc = cm.exception + self.assertIs(type(exc), RuntimeError) + self.assertEqual(exc.args, (123,)) + cause = exc.__cause__ + self.assertIs(type(cause), futures.process._RemoteTraceback) + self.assertIn('raise RuntimeError(123) # some comment', cause.tb) + + with test.support.captured_stderr() as f1: + try: + raise exc + except RuntimeError: + sys.excepthook(*sys.exc_info()) + self.assertIn('raise RuntimeError(123) # some comment', + f1.getvalue()) + class FutureTests(unittest.TestCase): def test_done_callback_with_result(self): diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index 29e7ed99ae92..71a8f3f8d96d 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -579,7 +579,7 @@ def get_error(self, cf, exc, section, option): return e else: self.fail("expected exception type %s.%s" - % (exc.__module__, exc.__name__)) + % (exc.__module__, exc.__qualname__)) def test_boolean(self): cf = self.fromstring( @@ -707,8 +707,7 @@ class mystr(str): def test_read_returns_file_list(self): if self.delimiters[0] != '=': - # skip reading the file if we're using an incompatible format - return + self.skipTest('incompatible format') file1 = support.findfile("cfgparser.1") # check when we pass a mix of readable and non-readable files: cf = self.newconfig() @@ -848,7 +847,8 @@ def test_interpolation(self): "something with lots of interpolation (10 steps)") e = self.get_error(cf, configparser.InterpolationDepthError, "Foo", "bar11") if self.interpolation == configparser._UNSET: - self.assertEqual(e.args, ("bar11", "Foo", "%(with1)s")) + self.assertEqual(e.args, ("bar11", "Foo", + "something %(with11)s lots of interpolation (11 steps)")) elif isinstance(self.interpolation, configparser.LegacyInterpolation): self.assertEqual(e.args, ("bar11", "Foo", "something %(with11)s lots of interpolation (11 steps)")) @@ -862,7 +862,7 @@ def test_interpolation_missing_value(self): self.assertEqual(e.option, "name") if self.interpolation == configparser._UNSET: self.assertEqual(e.args, ('name', 'Interpolation Error', - '', 'reference')) + '%(reference)s', 'reference')) elif isinstance(self.interpolation, configparser.LegacyInterpolation): self.assertEqual(e.args, ('name', 'Interpolation Error', '%(reference)s', 'reference')) @@ -1178,7 +1178,7 @@ def test_strange_options(self): with self.assertRaises(exception_class) as cm: cf['interpolated']['$trying'] self.assertEqual(cm.exception.reference, 'dollars:${sick') - self.assertEqual(cm.exception.args[2], '}') #rawval + self.assertEqual(cm.exception.args[2], '${dollars:${sick}}') #rawval def test_case_sensitivity_basic(self): ini = textwrap.dedent(""" @@ -1585,6 +1585,34 @@ def test_sectionproxy_repr(self): """) self.assertEqual(repr(parser['section']), '') + def test_inconsistent_converters_state(self): + parser = configparser.ConfigParser() + import decimal + parser.converters['decimal'] = decimal.Decimal + parser.read_string(""" + [s1] + one = 1 + [s2] + two = 2 + """) + self.assertIn('decimal', parser.converters) + self.assertEqual(parser.getdecimal('s1', 'one'), 1) + self.assertEqual(parser.getdecimal('s2', 'two'), 2) + self.assertEqual(parser['s1'].getdecimal('one'), 1) + self.assertEqual(parser['s2'].getdecimal('two'), 2) + del parser.getdecimal + with self.assertRaises(AttributeError): + parser.getdecimal('s1', 'one') + self.assertIn('decimal', parser.converters) + del parser.converters['decimal'] + self.assertNotIn('decimal', parser.converters) + with self.assertRaises(AttributeError): + parser.getdecimal('s1', 'one') + with self.assertRaises(AttributeError): + parser['s1'].getdecimal('one') + with self.assertRaises(AttributeError): + parser['s2'].getdecimal('two') + class ExceptionPicklingTestCase(unittest.TestCase): """Tests for issue #13760: ConfigParser exceptions are not picklable.""" @@ -1592,104 +1620,113 @@ class ExceptionPicklingTestCase(unittest.TestCase): def test_error(self): import pickle e1 = configparser.Error('value') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(repr(e1), repr(e2)) def test_nosectionerror(self): import pickle e1 = configparser.NoSectionError('section') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(repr(e1), repr(e2)) def test_nooptionerror(self): import pickle e1 = configparser.NoOptionError('option', 'section') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.option, e2.option) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.option, e2.option) + self.assertEqual(repr(e1), repr(e2)) def test_duplicatesectionerror(self): import pickle e1 = configparser.DuplicateSectionError('section', 'source', 123) - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.source, e2.source) - self.assertEqual(e1.lineno, e2.lineno) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.source, e2.source) + self.assertEqual(e1.lineno, e2.lineno) + self.assertEqual(repr(e1), repr(e2)) def test_duplicateoptionerror(self): import pickle e1 = configparser.DuplicateOptionError('section', 'option', 'source', 123) - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.option, e2.option) - self.assertEqual(e1.source, e2.source) - self.assertEqual(e1.lineno, e2.lineno) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.option, e2.option) + self.assertEqual(e1.source, e2.source) + self.assertEqual(e1.lineno, e2.lineno) + self.assertEqual(repr(e1), repr(e2)) def test_interpolationerror(self): import pickle e1 = configparser.InterpolationError('option', 'section', 'msg') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.option, e2.option) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.option, e2.option) + self.assertEqual(repr(e1), repr(e2)) def test_interpolationmissingoptionerror(self): import pickle e1 = configparser.InterpolationMissingOptionError('option', 'section', 'rawval', 'reference') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.option, e2.option) - self.assertEqual(e1.reference, e2.reference) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.option, e2.option) + self.assertEqual(e1.reference, e2.reference) + self.assertEqual(repr(e1), repr(e2)) def test_interpolationsyntaxerror(self): import pickle e1 = configparser.InterpolationSyntaxError('option', 'section', 'msg') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.option, e2.option) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.option, e2.option) + self.assertEqual(repr(e1), repr(e2)) def test_interpolationdeptherror(self): import pickle e1 = configparser.InterpolationDepthError('option', 'section', 'rawval') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.section, e2.section) - self.assertEqual(e1.option, e2.option) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.section, e2.section) + self.assertEqual(e1.option, e2.option) + self.assertEqual(repr(e1), repr(e2)) def test_parsingerror(self): import pickle @@ -1697,36 +1734,39 @@ def test_parsingerror(self): e1.append(1, 'line1') e1.append(2, 'line2') e1.append(3, 'line3') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.source, e2.source) - self.assertEqual(e1.errors, e2.errors) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.source, e2.source) + self.assertEqual(e1.errors, e2.errors) + self.assertEqual(repr(e1), repr(e2)) e1 = configparser.ParsingError(filename='filename') e1.append(1, 'line1') e1.append(2, 'line2') e1.append(3, 'line3') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.source, e2.source) - self.assertEqual(e1.errors, e2.errors) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.source, e2.source) + self.assertEqual(e1.errors, e2.errors) + self.assertEqual(repr(e1), repr(e2)) def test_missingsectionheadererror(self): import pickle e1 = configparser.MissingSectionHeaderError('filename', 123, 'line') - pickled = pickle.dumps(e1) - e2 = pickle.loads(pickled) - self.assertEqual(e1.message, e2.message) - self.assertEqual(e1.args, e2.args) - self.assertEqual(e1.line, e2.line) - self.assertEqual(e1.source, e2.source) - self.assertEqual(e1.lineno, e2.lineno) - self.assertEqual(repr(e1), repr(e2)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + pickled = pickle.dumps(e1, proto) + e2 = pickle.loads(pickled) + self.assertEqual(e1.message, e2.message) + self.assertEqual(e1.args, e2.args) + self.assertEqual(e1.line, e2.line) + self.assertEqual(e1.source, e2.source) + self.assertEqual(e1.lineno, e2.lineno) + self.assertEqual(repr(e1), repr(e2)) class InlineCommentStrippingTestCase(unittest.TestCase): @@ -1765,5 +1805,252 @@ def test_stripping(self): self.assertEqual(s['k3'], 'v3;#//still v3# and still v3') +class ExceptionContextTestCase(unittest.TestCase): + """ Test that implementation details doesn't leak + through raising exceptions. """ + + def test_get_basic_interpolation(self): + parser = configparser.ConfigParser() + parser.read_string(""" + [Paths] + home_dir: /Users + my_dir: %(home_dir1)s/lumberjack + my_pictures: %(my_dir)s/Pictures + """) + cm = self.assertRaises(configparser.InterpolationMissingOptionError) + with cm: + parser.get('Paths', 'my_dir') + self.assertIs(cm.exception.__suppress_context__, True) + + def test_get_extended_interpolation(self): + parser = configparser.ConfigParser( + interpolation=configparser.ExtendedInterpolation()) + parser.read_string(""" + [Paths] + home_dir: /Users + my_dir: ${home_dir1}/lumberjack + my_pictures: ${my_dir}/Pictures + """) + cm = self.assertRaises(configparser.InterpolationMissingOptionError) + with cm: + parser.get('Paths', 'my_dir') + self.assertIs(cm.exception.__suppress_context__, True) + + def test_missing_options(self): + parser = configparser.ConfigParser() + parser.read_string(""" + [Paths] + home_dir: /Users + """) + with self.assertRaises(configparser.NoSectionError) as cm: + parser.options('test') + self.assertIs(cm.exception.__suppress_context__, True) + + def test_missing_section(self): + config = configparser.ConfigParser() + with self.assertRaises(configparser.NoSectionError) as cm: + config.set('Section1', 'an_int', '15') + self.assertIs(cm.exception.__suppress_context__, True) + + def test_remove_option(self): + config = configparser.ConfigParser() + with self.assertRaises(configparser.NoSectionError) as cm: + config.remove_option('Section1', 'an_int') + self.assertIs(cm.exception.__suppress_context__, True) + + +class ConvertersTestCase(BasicTestCase, unittest.TestCase): + """Introduced in 3.5, issue #18159.""" + + config_class = configparser.ConfigParser + + def newconfig(self, defaults=None): + instance = super().newconfig(defaults=defaults) + instance.converters['list'] = lambda v: [e.strip() for e in v.split() + if e.strip()] + return instance + + def test_converters(self): + cfg = self.newconfig() + self.assertIn('boolean', cfg.converters) + self.assertIn('list', cfg.converters) + self.assertIsNone(cfg.converters['int']) + self.assertIsNone(cfg.converters['float']) + self.assertIsNone(cfg.converters['boolean']) + self.assertIsNotNone(cfg.converters['list']) + self.assertEqual(len(cfg.converters), 4) + with self.assertRaises(ValueError): + cfg.converters[''] = lambda v: v + with self.assertRaises(ValueError): + cfg.converters[None] = lambda v: v + cfg.read_string(""" + [s] + str = string + int = 1 + float = 0.5 + list = a b c d e f g + bool = yes + """) + s = cfg['s'] + self.assertEqual(s['str'], 'string') + self.assertEqual(s['int'], '1') + self.assertEqual(s['float'], '0.5') + self.assertEqual(s['list'], 'a b c d e f g') + self.assertEqual(s['bool'], 'yes') + self.assertEqual(cfg.get('s', 'str'), 'string') + self.assertEqual(cfg.get('s', 'int'), '1') + self.assertEqual(cfg.get('s', 'float'), '0.5') + self.assertEqual(cfg.get('s', 'list'), 'a b c d e f g') + self.assertEqual(cfg.get('s', 'bool'), 'yes') + self.assertEqual(cfg.get('s', 'str'), 'string') + self.assertEqual(cfg.getint('s', 'int'), 1) + self.assertEqual(cfg.getfloat('s', 'float'), 0.5) + self.assertEqual(cfg.getlist('s', 'list'), ['a', 'b', 'c', 'd', + 'e', 'f', 'g']) + self.assertEqual(cfg.getboolean('s', 'bool'), True) + self.assertEqual(s.get('str'), 'string') + self.assertEqual(s.getint('int'), 1) + self.assertEqual(s.getfloat('float'), 0.5) + self.assertEqual(s.getlist('list'), ['a', 'b', 'c', 'd', + 'e', 'f', 'g']) + self.assertEqual(s.getboolean('bool'), True) + with self.assertRaises(AttributeError): + cfg.getdecimal('s', 'float') + with self.assertRaises(AttributeError): + s.getdecimal('float') + import decimal + cfg.converters['decimal'] = decimal.Decimal + self.assertIn('decimal', cfg.converters) + self.assertIsNotNone(cfg.converters['decimal']) + self.assertEqual(len(cfg.converters), 5) + dec0_5 = decimal.Decimal('0.5') + self.assertEqual(cfg.getdecimal('s', 'float'), dec0_5) + self.assertEqual(s.getdecimal('float'), dec0_5) + del cfg.converters['decimal'] + self.assertNotIn('decimal', cfg.converters) + self.assertEqual(len(cfg.converters), 4) + with self.assertRaises(AttributeError): + cfg.getdecimal('s', 'float') + with self.assertRaises(AttributeError): + s.getdecimal('float') + with self.assertRaises(KeyError): + del cfg.converters['decimal'] + with self.assertRaises(KeyError): + del cfg.converters[''] + with self.assertRaises(KeyError): + del cfg.converters[None] + + +class BlatantOverrideConvertersTestCase(unittest.TestCase): + """What if somebody overrode a getboolean()? We want to make sure that in + this case the automatic converters do not kick in.""" + + config = """ + [one] + one = false + two = false + three = long story short + + [two] + one = false + two = false + three = four + """ + + def test_converters_at_init(self): + cfg = configparser.ConfigParser(converters={'len': len}) + cfg.read_string(self.config) + self._test_len(cfg) + self.assertIsNotNone(cfg.converters['len']) + + def test_inheritance(self): + class StrangeConfigParser(configparser.ConfigParser): + gettysburg = 'a historic borough in south central Pennsylvania' + + def getboolean(self, section, option, *, raw=False, vars=None, + fallback=configparser._UNSET): + if section == option: + return True + return super().getboolean(section, option, raw=raw, vars=vars, + fallback=fallback) + def getlen(self, section, option, *, raw=False, vars=None, + fallback=configparser._UNSET): + return self._get_conv(section, option, len, raw=raw, vars=vars, + fallback=fallback) + + cfg = StrangeConfigParser() + cfg.read_string(self.config) + self._test_len(cfg) + self.assertIsNone(cfg.converters['len']) + self.assertTrue(cfg.getboolean('one', 'one')) + self.assertTrue(cfg.getboolean('two', 'two')) + self.assertFalse(cfg.getboolean('one', 'two')) + self.assertFalse(cfg.getboolean('two', 'one')) + cfg.converters['boolean'] = cfg._convert_to_boolean + self.assertFalse(cfg.getboolean('one', 'one')) + self.assertFalse(cfg.getboolean('two', 'two')) + self.assertFalse(cfg.getboolean('one', 'two')) + self.assertFalse(cfg.getboolean('two', 'one')) + + def _test_len(self, cfg): + self.assertEqual(len(cfg.converters), 4) + self.assertIn('boolean', cfg.converters) + self.assertIn('len', cfg.converters) + self.assertNotIn('tysburg', cfg.converters) + self.assertIsNone(cfg.converters['int']) + self.assertIsNone(cfg.converters['float']) + self.assertIsNone(cfg.converters['boolean']) + self.assertEqual(cfg.getlen('one', 'one'), 5) + self.assertEqual(cfg.getlen('one', 'two'), 5) + self.assertEqual(cfg.getlen('one', 'three'), 16) + self.assertEqual(cfg.getlen('two', 'one'), 5) + self.assertEqual(cfg.getlen('two', 'two'), 5) + self.assertEqual(cfg.getlen('two', 'three'), 4) + self.assertEqual(cfg.getlen('two', 'four', fallback=0), 0) + with self.assertRaises(configparser.NoOptionError): + cfg.getlen('two', 'four') + self.assertEqual(cfg['one'].getlen('one'), 5) + self.assertEqual(cfg['one'].getlen('two'), 5) + self.assertEqual(cfg['one'].getlen('three'), 16) + self.assertEqual(cfg['two'].getlen('one'), 5) + self.assertEqual(cfg['two'].getlen('two'), 5) + self.assertEqual(cfg['two'].getlen('three'), 4) + self.assertEqual(cfg['two'].getlen('four', 0), 0) + self.assertEqual(cfg['two'].getlen('four'), None) + + def test_instance_assignment(self): + cfg = configparser.ConfigParser() + cfg.getboolean = lambda section, option: True + cfg.getlen = lambda section, option: len(cfg[section][option]) + cfg.read_string(self.config) + self.assertEqual(len(cfg.converters), 3) + self.assertIn('boolean', cfg.converters) + self.assertNotIn('len', cfg.converters) + self.assertIsNone(cfg.converters['int']) + self.assertIsNone(cfg.converters['float']) + self.assertIsNone(cfg.converters['boolean']) + self.assertTrue(cfg.getboolean('one', 'one')) + self.assertTrue(cfg.getboolean('two', 'two')) + self.assertTrue(cfg.getboolean('one', 'two')) + self.assertTrue(cfg.getboolean('two', 'one')) + cfg.converters['boolean'] = cfg._convert_to_boolean + self.assertFalse(cfg.getboolean('one', 'one')) + self.assertFalse(cfg.getboolean('two', 'two')) + self.assertFalse(cfg.getboolean('one', 'two')) + self.assertFalse(cfg.getboolean('two', 'one')) + self.assertEqual(cfg.getlen('one', 'one'), 5) + self.assertEqual(cfg.getlen('one', 'two'), 5) + self.assertEqual(cfg.getlen('one', 'three'), 16) + self.assertEqual(cfg.getlen('two', 'one'), 5) + self.assertEqual(cfg.getlen('two', 'two'), 5) + self.assertEqual(cfg.getlen('two', 'three'), 4) + # If a getter impl is assigned straight to the instance, it won't + # be available on the section proxies. + with self.assertRaises(AttributeError): + self.assertEqual(cfg['one'].getlen('one'), 5) + with self.assertRaises(AttributeError): + self.assertEqual(cfg['two'].getlen('one'), 5) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_contains.py b/Lib/test/test_contains.py index a667a16d8c79..3c6bdeffda34 100644 --- a/Lib/test/test_contains.py +++ b/Lib/test/test_contains.py @@ -1,5 +1,4 @@ from collections import deque -from test.support import run_unittest import unittest @@ -86,8 +85,5 @@ def __hash__(self): self.assertTrue(container == container) -def test_main(): - run_unittest(TestContains) - if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test_contextlib.py b/Lib/test/test_contextlib.py index b8770c828f56..30a6377bed89 100644 --- a/Lib/test/test_contextlib.py +++ b/Lib/test/test_contextlib.py @@ -83,6 +83,42 @@ def woohoo(): raise ZeroDivisionError(999) self.assertEqual(state, [1, 42, 999]) + def test_contextmanager_except_stopiter(self): + stop_exc = StopIteration('spam') + @contextmanager + def woohoo(): + yield + try: + with self.assertWarnsRegex(PendingDeprecationWarning, + "StopIteration"): + with woohoo(): + raise stop_exc + except Exception as ex: + self.assertIs(ex, stop_exc) + else: + self.fail('StopIteration was suppressed') + + def test_contextmanager_except_pep479(self): + code = """\ +from __future__ import generator_stop +from contextlib import contextmanager +@contextmanager +def woohoo(): + yield +""" + locals = {} + exec(code, locals, locals) + woohoo = locals['woohoo'] + + stop_exc = StopIteration('spam') + try: + with woohoo(): + raise stop_exc + except Exception as ex: + self.assertIs(ex, stop_exc) + else: + self.fail('StopIteration was suppressed') + def _create_contextmanager_attribs(self): def attribs(**kw): def decorate(func): @@ -111,6 +147,14 @@ def test_instance_docstring_given_cm_docstring(self): baz = self._create_contextmanager_attribs()(None) self.assertEqual(baz.__doc__, "Whee!") + def test_keywords(self): + # Ensure no keyword arguments are inhibited + @contextmanager + def woohoo(self, func, args, kwds): + yield (self, func, args, kwds) + with woohoo(self=11, func=22, args=33, kwds=44) as target: + self.assertEqual(target, (11, 22, 33, 44)) + class ClosingTestCase(unittest.TestCase): @@ -626,6 +670,67 @@ def suppress_exc(*exc_details): else: self.fail("Expected KeyError, but no exception was raised") + def test_exit_exception_with_correct_context(self): + # http://bugs.python.org/issue20317 + @contextmanager + def gets_the_context_right(exc): + try: + yield + finally: + raise exc + + exc1 = Exception(1) + exc2 = Exception(2) + exc3 = Exception(3) + exc4 = Exception(4) + + # The contextmanager already fixes the context, so prior to the + # fix, ExitStack would try to fix it *again* and get into an + # infinite self-referential loop + try: + with ExitStack() as stack: + stack.enter_context(gets_the_context_right(exc4)) + stack.enter_context(gets_the_context_right(exc3)) + stack.enter_context(gets_the_context_right(exc2)) + raise exc1 + except Exception as exc: + self.assertIs(exc, exc4) + self.assertIs(exc.__context__, exc3) + self.assertIs(exc.__context__.__context__, exc2) + self.assertIs(exc.__context__.__context__.__context__, exc1) + self.assertIsNone( + exc.__context__.__context__.__context__.__context__) + + def test_exit_exception_with_existing_context(self): + # Addresses a lack of test coverage discovered after checking in a + # fix for issue 20317 that still contained debugging code. + def raise_nested(inner_exc, outer_exc): + try: + raise inner_exc + finally: + raise outer_exc + exc1 = Exception(1) + exc2 = Exception(2) + exc3 = Exception(3) + exc4 = Exception(4) + exc5 = Exception(5) + try: + with ExitStack() as stack: + stack.callback(raise_nested, exc4, exc5) + stack.callback(raise_nested, exc2, exc3) + raise exc1 + except Exception as exc: + self.assertIs(exc, exc5) + self.assertIs(exc.__context__, exc4) + self.assertIs(exc.__context__.__context__, exc3) + self.assertIs(exc.__context__.__context__.__context__, exc2) + self.assertIs( + exc.__context__.__context__.__context__.__context__, exc1) + self.assertIsNone( + exc.__context__.__context__.__context__.__context__.__context__) + + + def test_body_exception_suppress(self): def suppress_exc(*exc_details): return True @@ -657,60 +762,76 @@ class Example(object): pass stack.push(cm) self.assertIs(stack._exit_callbacks[-1], cm) -class TestRedirectStdout(unittest.TestCase): + +class TestRedirectStream: + + redirect_stream = None + orig_stream = None @support.requires_docstrings def test_instance_docs(self): # Issue 19330: ensure context manager instances have good docstrings - cm_docstring = redirect_stdout.__doc__ - obj = redirect_stdout(None) + cm_docstring = self.redirect_stream.__doc__ + obj = self.redirect_stream(None) self.assertEqual(obj.__doc__, cm_docstring) def test_no_redirect_in_init(self): - orig_stdout = sys.stdout - redirect_stdout(None) - self.assertIs(sys.stdout, orig_stdout) + orig_stdout = getattr(sys, self.orig_stream) + self.redirect_stream(None) + self.assertIs(getattr(sys, self.orig_stream), orig_stdout) def test_redirect_to_string_io(self): f = io.StringIO() msg = "Consider an API like help(), which prints directly to stdout" - orig_stdout = sys.stdout - with redirect_stdout(f): - print(msg) - self.assertIs(sys.stdout, orig_stdout) + orig_stdout = getattr(sys, self.orig_stream) + with self.redirect_stream(f): + print(msg, file=getattr(sys, self.orig_stream)) + self.assertIs(getattr(sys, self.orig_stream), orig_stdout) s = f.getvalue().strip() self.assertEqual(s, msg) def test_enter_result_is_target(self): f = io.StringIO() - with redirect_stdout(f) as enter_result: + with self.redirect_stream(f) as enter_result: self.assertIs(enter_result, f) def test_cm_is_reusable(self): f = io.StringIO() - write_to_f = redirect_stdout(f) - orig_stdout = sys.stdout + write_to_f = self.redirect_stream(f) + orig_stdout = getattr(sys, self.orig_stream) with write_to_f: - print("Hello", end=" ") + print("Hello", end=" ", file=getattr(sys, self.orig_stream)) with write_to_f: - print("World!") - self.assertIs(sys.stdout, orig_stdout) + print("World!", file=getattr(sys, self.orig_stream)) + self.assertIs(getattr(sys, self.orig_stream), orig_stdout) s = f.getvalue() self.assertEqual(s, "Hello World!\n") def test_cm_is_reentrant(self): f = io.StringIO() - write_to_f = redirect_stdout(f) - orig_stdout = sys.stdout + write_to_f = self.redirect_stream(f) + orig_stdout = getattr(sys, self.orig_stream) with write_to_f: - print("Hello", end=" ") + print("Hello", end=" ", file=getattr(sys, self.orig_stream)) with write_to_f: - print("World!") - self.assertIs(sys.stdout, orig_stdout) + print("World!", file=getattr(sys, self.orig_stream)) + self.assertIs(getattr(sys, self.orig_stream), orig_stdout) s = f.getvalue() self.assertEqual(s, "Hello World!\n") +class TestRedirectStdout(TestRedirectStream, unittest.TestCase): + + redirect_stream = redirect_stdout + orig_stream = "stdout" + + +class TestRedirectStderr(TestRedirectStream, unittest.TestCase): + + redirect_stream = redirect_stderr + orig_stream = "stderr" + + class TestSuppress(unittest.TestCase): @support.requires_docstrings @@ -759,9 +880,11 @@ def test_cm_is_reentrant(self): with ignore_exceptions: len(5) with ignore_exceptions: - 1/0 with ignore_exceptions: # Check nested usage len(5) + outer_continued = True + 1/0 + self.assertTrue(outer_continued) if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py index cde0baecad62..b9eadddbf268 100644 --- a/Lib/test/test_copy.py +++ b/Lib/test/test_copy.py @@ -7,7 +7,6 @@ from operator import le, lt, ge, gt, eq, ne import unittest -from test import support order_comparisons = le, lt, ge, gt equality_comparisons = eq, ne @@ -98,6 +97,7 @@ class WithMetaclass(metaclass=abc.ABCMeta): pass tests = [None, 42, 2**100, 3.14, True, False, 1j, "hello", "hello\u1234", f.__code__, + b"world", bytes(range(256)), NewStyle, range(10), Classic, max, WithMetaclass] for x in tests: self.assertIs(copy.copy(x), x) @@ -145,6 +145,40 @@ def __eq__(self, other): x = C(42) self.assertEqual(copy.copy(x), x) + def test_copy_inst_getnewargs(self): + class C(int): + def __new__(cls, foo): + self = int.__new__(cls) + self.foo = foo + return self + def __getnewargs__(self): + return self.foo, + def __eq__(self, other): + return self.foo == other.foo + x = C(42) + y = copy.copy(x) + self.assertIsInstance(y, C) + self.assertEqual(y, x) + self.assertIsNot(y, x) + self.assertEqual(y.foo, x.foo) + + def test_copy_inst_getnewargs_ex(self): + class C(int): + def __new__(cls, *, foo): + self = int.__new__(cls) + self.foo = foo + return self + def __getnewargs_ex__(self): + return (), {'foo': self.foo} + def __eq__(self, other): + return self.foo == other.foo + x = C(foo=42) + y = copy.copy(x) + self.assertIsInstance(y, C) + self.assertEqual(y, x) + self.assertIsNot(y, x) + self.assertEqual(y.foo, x.foo) + def test_copy_inst_getstate(self): class C: def __init__(self, foo): @@ -293,7 +327,7 @@ def test_deepcopy_reflexive_list(self): x.append(x) y = copy.deepcopy(x) for op in comparisons: - self.assertRaises(RuntimeError, op, y, x) + self.assertRaises(RecursionError, op, y, x) self.assertIsNot(y, x) self.assertIs(y[0], y) self.assertEqual(len(y), 1) @@ -320,7 +354,7 @@ def test_deepcopy_reflexive_tuple(self): x[0].append(x) y = copy.deepcopy(x) for op in comparisons: - self.assertRaises(RuntimeError, op, y, x) + self.assertRaises(RecursionError, op, y, x) self.assertIsNot(y, x) self.assertIsNot(y[0], x[0]) self.assertIs(y[0][0], y) @@ -339,7 +373,7 @@ def test_deepcopy_reflexive_dict(self): for op in order_comparisons: self.assertRaises(TypeError, op, y, x) for op in equality_comparisons: - self.assertRaises(RuntimeError, op, y, x) + self.assertRaises(RecursionError, op, y, x) self.assertIsNot(y, x) self.assertIs(y['foo'], y) self.assertEqual(len(y), 1) @@ -404,6 +438,42 @@ def __eq__(self, other): self.assertIsNot(y, x) self.assertIsNot(y.foo, x.foo) + def test_deepcopy_inst_getnewargs(self): + class C(int): + def __new__(cls, foo): + self = int.__new__(cls) + self.foo = foo + return self + def __getnewargs__(self): + return self.foo, + def __eq__(self, other): + return self.foo == other.foo + x = C([42]) + y = copy.deepcopy(x) + self.assertIsInstance(y, C) + self.assertEqual(y, x) + self.assertIsNot(y, x) + self.assertEqual(y.foo, x.foo) + self.assertIsNot(y.foo, x.foo) + + def test_deepcopy_inst_getnewargs_ex(self): + class C(int): + def __new__(cls, *, foo): + self = int.__new__(cls) + self.foo = foo + return self + def __getnewargs_ex__(self): + return (), {'foo': self.foo} + def __eq__(self, other): + return self.foo == other.foo + x = C(foo=[42]) + y = copy.deepcopy(x) + self.assertIsInstance(y, C) + self.assertEqual(y, x) + self.assertIsNot(y, x) + self.assertEqual(y.foo, x.foo) + self.assertIsNot(y.foo, x.foo) + def test_deepcopy_inst_getstate(self): class C: def __init__(self, foo): @@ -751,8 +821,5 @@ def m(self): def global_foo(x, y): return x+y -def test_main(): - support.run_unittest(TestCopy) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_copyreg.py b/Lib/test/test_copyreg.py index abe0748f851b..52e887cb36c4 100644 --- a/Lib/test/test_copyreg.py +++ b/Lib/test/test_copyreg.py @@ -1,7 +1,6 @@ import copyreg import unittest -from test import support from test.pickletester import ExtensionSaver class C: @@ -113,9 +112,5 @@ def test_slotnames(self): self.assertEqual(result, expected) -def test_main(): - support.run_unittest(CopyRegTestCase) - - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py new file mode 100644 index 000000000000..b15e24408432 --- /dev/null +++ b/Lib/test/test_coroutines.py @@ -0,0 +1,1473 @@ +import contextlib +import inspect +import sys +import types +import unittest +import warnings +from test import support + + +class AsyncYieldFrom: + def __init__(self, obj): + self.obj = obj + + def __await__(self): + yield from self.obj + + +class AsyncYield: + def __init__(self, value): + self.value = value + + def __await__(self): + yield self.value + + +def run_async(coro): + assert coro.__class__ in {types.GeneratorType, types.CoroutineType} + + buffer = [] + result = None + while True: + try: + buffer.append(coro.send(None)) + except StopIteration as ex: + result = ex.args[0] if ex.args else None + break + return buffer, result + + +def run_async__await__(coro): + assert coro.__class__ is types.CoroutineType + aw = coro.__await__() + buffer = [] + result = None + i = 0 + while True: + try: + if i % 2: + buffer.append(next(aw)) + else: + buffer.append(aw.send(None)) + i += 1 + except StopIteration as ex: + result = ex.args[0] if ex.args else None + break + return buffer, result + + +@contextlib.contextmanager +def silence_coro_gc(): + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + yield + support.gc_collect() + + +class AsyncBadSyntaxTest(unittest.TestCase): + + def test_badsyntax_1(self): + with self.assertRaisesRegex(SyntaxError, "'await' outside"): + import test.badsyntax_async1 + + def test_badsyntax_2(self): + with self.assertRaisesRegex(SyntaxError, "'await' outside"): + import test.badsyntax_async2 + + def test_badsyntax_3(self): + with self.assertRaisesRegex(SyntaxError, 'invalid syntax'): + import test.badsyntax_async3 + + def test_badsyntax_4(self): + with self.assertRaisesRegex(SyntaxError, 'invalid syntax'): + import test.badsyntax_async4 + + def test_badsyntax_5(self): + with self.assertRaisesRegex(SyntaxError, 'invalid syntax'): + import test.badsyntax_async5 + + def test_badsyntax_6(self): + with self.assertRaisesRegex( + SyntaxError, "'yield' inside async function"): + + import test.badsyntax_async6 + + def test_badsyntax_7(self): + with self.assertRaisesRegex( + SyntaxError, "'yield from' inside async function"): + + import test.badsyntax_async7 + + def test_badsyntax_8(self): + with self.assertRaisesRegex(SyntaxError, 'invalid syntax'): + import test.badsyntax_async8 + + def test_badsyntax_9(self): + ns = {} + for comp in {'(await a for a in b)', + '[await a for a in b]', + '{await a for a in b}', + '{await a: c for a in b}'}: + + with self.assertRaisesRegex(SyntaxError, 'await.*in comprehen'): + exec('async def f():\n\t{}'.format(comp), ns, ns) + + def test_badsyntax_10(self): + # Tests for issue 24619 + + samples = [ + """async def foo(): + def bar(): pass + await = 1 + """, + + """async def foo(): + + def bar(): pass + await = 1 + """, + + """async def foo(): + def bar(): pass + if 1: + await = 1 + """, + + """def foo(): + async def bar(): pass + if 1: + await a + """, + + """def foo(): + async def bar(): pass + await a + """, + + """def foo(): + def baz(): pass + async def bar(): pass + await a + """, + + """def foo(): + def baz(): pass + # 456 + async def bar(): pass + # 123 + await a + """, + + """async def foo(): + def baz(): pass + # 456 + async def bar(): pass + # 123 + await = 2 + """, + + """def foo(): + + def baz(): pass + + async def bar(): pass + + await a + """, + + """async def foo(): + + def baz(): pass + + async def bar(): pass + + await = 2 + """, + + """async def foo(): + def async(): pass + """, + + """async def foo(): + def await(): pass + """, + + """async def foo(): + def bar(): + await + """, + + """async def foo(): + return lambda async: await + """, + + """async def foo(): + return lambda a: await + """, + + """await a()""", + + """async def foo(a=await b): + pass + """, + + """async def foo(a:await b): + pass + """, + + """def baz(): + async def foo(a=await b): + pass + """, + + """async def foo(async): + pass + """, + + """async def foo(): + def bar(): + def baz(): + async = 1 + """, + + """async def foo(): + def bar(): + def baz(): + pass + async = 1 + """, + + """def foo(): + async def bar(): + + async def baz(): + pass + + def baz(): + 42 + + async = 1 + """, + + """async def foo(): + def bar(): + def baz(): + pass\nawait foo() + """, + + """def foo(): + def bar(): + async def baz(): + pass\nawait foo() + """, + + """async def foo(await): + pass + """, + + """def foo(): + + async def bar(): pass + + await a + """, + + """def foo(): + async def bar(): + pass\nawait a + """] + + for code in samples: + with self.subTest(code=code), self.assertRaises(SyntaxError): + compile(code, "", "exec") + + def test_goodsyntax_1(self): + # Tests for issue 24619 + + def foo(await): + async def foo(): pass + async def foo(): + pass + return await + 1 + self.assertEqual(foo(10), 11) + + def foo(await): + async def foo(): pass + async def foo(): pass + return await + 2 + self.assertEqual(foo(20), 22) + + def foo(await): + + async def foo(): pass + + async def foo(): pass + + return await + 2 + self.assertEqual(foo(20), 22) + + def foo(await): + """spam""" + async def foo(): \ + pass + # 123 + async def foo(): pass + # 456 + return await + 2 + self.assertEqual(foo(20), 22) + + def foo(await): + def foo(): pass + def foo(): pass + async def bar(): return await_ + await_ = await + try: + bar().send(None) + except StopIteration as ex: + return ex.args[0] + self.assertEqual(foo(42), 42) + + async def f(): + async def g(): pass + await z + await = 1 + self.assertTrue(inspect.iscoroutinefunction(f)) + + +class TokenizerRegrTest(unittest.TestCase): + + def test_oneline_defs(self): + buf = [] + for i in range(500): + buf.append('def i{i}(): return {i}'.format(i=i)) + buf = '\n'.join(buf) + + # Test that 500 consequent, one-line defs is OK + ns = {} + exec(buf, ns, ns) + self.assertEqual(ns['i499'](), 499) + + # Test that 500 consequent, one-line defs *and* + # one 'async def' following them is OK + buf += '\nasync def foo():\n return' + ns = {} + exec(buf, ns, ns) + self.assertEqual(ns['i499'](), 499) + self.assertTrue(inspect.iscoroutinefunction(ns['foo'])) + + +class CoroutineTest(unittest.TestCase): + + def test_gen_1(self): + def gen(): yield + self.assertFalse(hasattr(gen, '__await__')) + + def test_func_1(self): + async def foo(): + return 10 + + f = foo() + self.assertIsInstance(f, types.CoroutineType) + self.assertTrue(bool(foo.__code__.co_flags & inspect.CO_COROUTINE)) + self.assertFalse(bool(foo.__code__.co_flags & inspect.CO_GENERATOR)) + self.assertTrue(bool(f.cr_code.co_flags & inspect.CO_COROUTINE)) + self.assertFalse(bool(f.cr_code.co_flags & inspect.CO_GENERATOR)) + self.assertEqual(run_async(f), ([], 10)) + + self.assertEqual(run_async__await__(foo()), ([], 10)) + + def bar(): pass + self.assertFalse(bool(bar.__code__.co_flags & inspect.CO_COROUTINE)) + + def test_func_2(self): + async def foo(): + raise StopIteration + + with self.assertRaisesRegex( + RuntimeError, "coroutine raised StopIteration"): + + run_async(foo()) + + def test_func_3(self): + async def foo(): + raise StopIteration + + with silence_coro_gc(): + self.assertRegex(repr(foo()), '^$') + + def test_func_4(self): + async def foo(): + raise StopIteration + + check = lambda: self.assertRaisesRegex( + TypeError, "'coroutine' object is not iterable") + + with check(): + list(foo()) + + with check(): + tuple(foo()) + + with check(): + sum(foo()) + + with check(): + iter(foo()) + + with silence_coro_gc(), check(): + for i in foo(): + pass + + with silence_coro_gc(), check(): + [i for i in foo()] + + def test_func_5(self): + @types.coroutine + def bar(): + yield 1 + + async def foo(): + await bar() + + check = lambda: self.assertRaisesRegex( + TypeError, "'coroutine' object is not iterable") + + with check(): + for el in foo(): pass + + # the following should pass without an error + for el in bar(): + self.assertEqual(el, 1) + self.assertEqual([el for el in bar()], [1]) + self.assertEqual(tuple(bar()), (1,)) + self.assertEqual(next(iter(bar())), 1) + + def test_func_6(self): + @types.coroutine + def bar(): + yield 1 + yield 2 + + async def foo(): + await bar() + + f = foo() + self.assertEqual(f.send(None), 1) + self.assertEqual(f.send(None), 2) + with self.assertRaises(StopIteration): + f.send(None) + + def test_func_7(self): + async def bar(): + return 10 + + def foo(): + yield from bar() + + with silence_coro_gc(), self.assertRaisesRegex( + TypeError, + "cannot 'yield from' a coroutine object in a non-coroutine generator"): + + list(foo()) + + def test_func_8(self): + @types.coroutine + def bar(): + return (yield from foo()) + + async def foo(): + return 'spam' + + self.assertEqual(run_async(bar()), ([], 'spam') ) + + def test_func_9(self): + async def foo(): pass + + with self.assertWarnsRegex( + RuntimeWarning, "coroutine '.*test_func_9.*foo' was never awaited"): + + foo() + support.gc_collect() + + def test_func_10(self): + N = 0 + + @types.coroutine + def gen(): + nonlocal N + try: + a = yield + yield (a ** 2) + except ZeroDivisionError: + N += 100 + raise + finally: + N += 1 + + async def foo(): + await gen() + + coro = foo() + aw = coro.__await__() + self.assertIs(aw, iter(aw)) + next(aw) + self.assertEqual(aw.send(10), 100) + + self.assertEqual(N, 0) + aw.close() + self.assertEqual(N, 1) + + coro = foo() + aw = coro.__await__() + next(aw) + with self.assertRaises(ZeroDivisionError): + aw.throw(ZeroDivisionError, None, None) + self.assertEqual(N, 102) + + def test_func_11(self): + async def func(): pass + coro = func() + # Test that PyCoro_Type and _PyCoroWrapper_Type types were properly + # initialized + self.assertIn('__await__', dir(coro)) + self.assertIn('__iter__', dir(coro.__await__())) + self.assertIn('coroutine_wrapper', repr(coro.__await__())) + coro.close() # avoid RuntimeWarning + + def test_func_12(self): + async def g(): + i = me.send(None) + await foo + me = g() + with self.assertRaisesRegex(ValueError, + "coroutine already executing"): + me.send(None) + + def test_func_13(self): + async def g(): + pass + with self.assertRaisesRegex( + TypeError, + "can't send non-None value to a just-started coroutine"): + + g().send('spam') + + def test_func_14(self): + @types.coroutine + def gen(): + yield + async def coro(): + try: + await gen() + except GeneratorExit: + await gen() + c = coro() + c.send(None) + with self.assertRaisesRegex(RuntimeError, + "coroutine ignored GeneratorExit"): + c.close() + + def test_cr_await(self): + @types.coroutine + def a(): + self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_RUNNING) + self.assertIsNone(coro_b.cr_await) + yield + self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_RUNNING) + self.assertIsNone(coro_b.cr_await) + + async def c(): + await a() + + async def b(): + self.assertIsNone(coro_b.cr_await) + await c() + self.assertIsNone(coro_b.cr_await) + + coro_b = b() + self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_CREATED) + self.assertIsNone(coro_b.cr_await) + + coro_b.send(None) + self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_SUSPENDED) + self.assertEqual(coro_b.cr_await.cr_await.gi_code.co_name, 'a') + + with self.assertRaises(StopIteration): + coro_b.send(None) # complete coroutine + self.assertEqual(inspect.getcoroutinestate(coro_b), inspect.CORO_CLOSED) + self.assertIsNone(coro_b.cr_await) + + def test_corotype_1(self): + ct = types.CoroutineType + self.assertIn('into coroutine', ct.send.__doc__) + self.assertIn('inside coroutine', ct.close.__doc__) + self.assertIn('in coroutine', ct.throw.__doc__) + self.assertIn('of the coroutine', ct.__dict__['__name__'].__doc__) + self.assertIn('of the coroutine', ct.__dict__['__qualname__'].__doc__) + self.assertEqual(ct.__name__, 'coroutine') + + async def f(): pass + c = f() + self.assertIn('coroutine object', repr(c)) + c.close() + + def test_await_1(self): + + async def foo(): + await 1 + with self.assertRaisesRegex(TypeError, "object int can.t.*await"): + run_async(foo()) + + def test_await_2(self): + async def foo(): + await [] + with self.assertRaisesRegex(TypeError, "object list can.t.*await"): + run_async(foo()) + + def test_await_3(self): + async def foo(): + await AsyncYieldFrom([1, 2, 3]) + + self.assertEqual(run_async(foo()), ([1, 2, 3], None)) + self.assertEqual(run_async__await__(foo()), ([1, 2, 3], None)) + + def test_await_4(self): + async def bar(): + return 42 + + async def foo(): + return await bar() + + self.assertEqual(run_async(foo()), ([], 42)) + + def test_await_5(self): + class Awaitable: + def __await__(self): + return + + async def foo(): + return (await Awaitable()) + + with self.assertRaisesRegex( + TypeError, "__await__.*returned non-iterator of type"): + + run_async(foo()) + + def test_await_6(self): + class Awaitable: + def __await__(self): + return iter([52]) + + async def foo(): + return (await Awaitable()) + + self.assertEqual(run_async(foo()), ([52], None)) + + def test_await_7(self): + class Awaitable: + def __await__(self): + yield 42 + return 100 + + async def foo(): + return (await Awaitable()) + + self.assertEqual(run_async(foo()), ([42], 100)) + + def test_await_8(self): + class Awaitable: + pass + + async def foo(): return await Awaitable() + + with self.assertRaisesRegex( + TypeError, "object Awaitable can't be used in 'await' expression"): + + run_async(foo()) + + def test_await_9(self): + def wrap(): + return bar + + async def bar(): + return 42 + + async def foo(): + b = bar() + + db = {'b': lambda: wrap} + + class DB: + b = wrap + + return (await bar() + await wrap()() + await db['b']()()() + + await bar() * 1000 + await DB.b()()) + + async def foo2(): + return -await bar() + + self.assertEqual(run_async(foo()), ([], 42168)) + self.assertEqual(run_async(foo2()), ([], -42)) + + def test_await_10(self): + async def baz(): + return 42 + + async def bar(): + return baz() + + async def foo(): + return await (await bar()) + + self.assertEqual(run_async(foo()), ([], 42)) + + def test_await_11(self): + def ident(val): + return val + + async def bar(): + return 'spam' + + async def foo(): + return ident(val=await bar()) + + async def foo2(): + return await bar(), 'ham' + + self.assertEqual(run_async(foo2()), ([], ('spam', 'ham'))) + + def test_await_12(self): + async def coro(): + return 'spam' + + class Awaitable: + def __await__(self): + return coro() + + async def foo(): + return await Awaitable() + + with self.assertRaisesRegex( + TypeError, "__await__\(\) returned a coroutine"): + + run_async(foo()) + + def test_await_13(self): + class Awaitable: + def __await__(self): + return self + + async def foo(): + return await Awaitable() + + with self.assertRaisesRegex( + TypeError, "__await__.*returned non-iterator of type"): + + run_async(foo()) + + def test_await_14(self): + class Wrapper: + # Forces the interpreter to use CoroutineType.__await__ + def __init__(self, coro): + assert coro.__class__ is types.CoroutineType + self.coro = coro + def __await__(self): + return self.coro.__await__() + + class FutureLike: + def __await__(self): + return (yield) + + class Marker(Exception): + pass + + async def coro1(): + try: + return await FutureLike() + except ZeroDivisionError: + raise Marker + async def coro2(): + return await Wrapper(coro1()) + + c = coro2() + c.send(None) + with self.assertRaisesRegex(StopIteration, 'spam'): + c.send('spam') + + c = coro2() + c.send(None) + with self.assertRaises(Marker): + c.throw(ZeroDivisionError) + + def test_with_1(self): + class Manager: + def __init__(self, name): + self.name = name + + async def __aenter__(self): + await AsyncYieldFrom(['enter-1-' + self.name, + 'enter-2-' + self.name]) + return self + + async def __aexit__(self, *args): + await AsyncYieldFrom(['exit-1-' + self.name, + 'exit-2-' + self.name]) + + if self.name == 'B': + return True + + + async def foo(): + async with Manager("A") as a, Manager("B") as b: + await AsyncYieldFrom([('managers', a.name, b.name)]) + 1/0 + + f = foo() + result, _ = run_async(f) + + self.assertEqual( + result, ['enter-1-A', 'enter-2-A', 'enter-1-B', 'enter-2-B', + ('managers', 'A', 'B'), + 'exit-1-B', 'exit-2-B', 'exit-1-A', 'exit-2-A'] + ) + + async def foo(): + async with Manager("A") as a, Manager("C") as c: + await AsyncYieldFrom([('managers', a.name, c.name)]) + 1/0 + + with self.assertRaises(ZeroDivisionError): + run_async(foo()) + + def test_with_2(self): + class CM: + def __aenter__(self): + pass + + async def foo(): + async with CM(): + pass + + with self.assertRaisesRegex(AttributeError, '__aexit__'): + run_async(foo()) + + def test_with_3(self): + class CM: + def __aexit__(self): + pass + + async def foo(): + async with CM(): + pass + + with self.assertRaisesRegex(AttributeError, '__aenter__'): + run_async(foo()) + + def test_with_4(self): + class CM: + def __enter__(self): + pass + + def __exit__(self): + pass + + async def foo(): + async with CM(): + pass + + with self.assertRaisesRegex(AttributeError, '__aexit__'): + run_async(foo()) + + def test_with_5(self): + # While this test doesn't make a lot of sense, + # it's a regression test for an early bug with opcodes + # generation + + class CM: + async def __aenter__(self): + return self + + async def __aexit__(self, *exc): + pass + + async def func(): + async with CM(): + assert (1, ) == 1 + + with self.assertRaises(AssertionError): + run_async(func()) + + def test_with_6(self): + class CM: + def __aenter__(self): + return 123 + + def __aexit__(self, *e): + return 456 + + async def foo(): + async with CM(): + pass + + with self.assertRaisesRegex( + TypeError, "object int can't be used in 'await' expression"): + # it's important that __aexit__ wasn't called + run_async(foo()) + + def test_with_7(self): + class CM: + async def __aenter__(self): + return self + + def __aexit__(self, *e): + return 444 + + async def foo(): + async with CM(): + 1/0 + + try: + run_async(foo()) + except TypeError as exc: + self.assertRegex( + exc.args[0], "object int can't be used in 'await' expression") + self.assertTrue(exc.__context__ is not None) + self.assertTrue(isinstance(exc.__context__, ZeroDivisionError)) + else: + self.fail('invalid asynchronous context manager did not fail') + + + def test_with_8(self): + CNT = 0 + + class CM: + async def __aenter__(self): + return self + + def __aexit__(self, *e): + return 456 + + async def foo(): + nonlocal CNT + async with CM(): + CNT += 1 + + + with self.assertRaisesRegex( + TypeError, "object int can't be used in 'await' expression"): + + run_async(foo()) + + self.assertEqual(CNT, 1) + + + def test_with_9(self): + CNT = 0 + + class CM: + async def __aenter__(self): + return self + + async def __aexit__(self, *e): + 1/0 + + async def foo(): + nonlocal CNT + async with CM(): + CNT += 1 + + with self.assertRaises(ZeroDivisionError): + run_async(foo()) + + self.assertEqual(CNT, 1) + + def test_with_10(self): + CNT = 0 + + class CM: + async def __aenter__(self): + return self + + async def __aexit__(self, *e): + 1/0 + + async def foo(): + nonlocal CNT + async with CM(): + async with CM(): + raise RuntimeError + + try: + run_async(foo()) + except ZeroDivisionError as exc: + self.assertTrue(exc.__context__ is not None) + self.assertTrue(isinstance(exc.__context__, ZeroDivisionError)) + self.assertTrue(isinstance(exc.__context__.__context__, + RuntimeError)) + else: + self.fail('exception from __aexit__ did not propagate') + + def test_with_11(self): + CNT = 0 + + class CM: + async def __aenter__(self): + raise NotImplementedError + + async def __aexit__(self, *e): + 1/0 + + async def foo(): + nonlocal CNT + async with CM(): + raise RuntimeError + + try: + run_async(foo()) + except NotImplementedError as exc: + self.assertTrue(exc.__context__ is None) + else: + self.fail('exception from __aenter__ did not propagate') + + def test_with_12(self): + CNT = 0 + + class CM: + async def __aenter__(self): + return self + + async def __aexit__(self, *e): + return True + + async def foo(): + nonlocal CNT + async with CM() as cm: + self.assertIs(cm.__class__, CM) + raise RuntimeError + + run_async(foo()) + + def test_with_13(self): + CNT = 0 + + class CM: + async def __aenter__(self): + 1/0 + + async def __aexit__(self, *e): + return True + + async def foo(): + nonlocal CNT + CNT += 1 + async with CM(): + CNT += 1000 + CNT += 10000 + + with self.assertRaises(ZeroDivisionError): + run_async(foo()) + self.assertEqual(CNT, 1) + + def test_for_1(self): + aiter_calls = 0 + + class AsyncIter: + def __init__(self): + self.i = 0 + + async def __aiter__(self): + nonlocal aiter_calls + aiter_calls += 1 + return self + + async def __anext__(self): + self.i += 1 + + if not (self.i % 10): + await AsyncYield(self.i * 10) + + if self.i > 100: + raise StopAsyncIteration + + return self.i, self.i + + + buffer = [] + async def test1(): + async for i1, i2 in AsyncIter(): + buffer.append(i1 + i2) + + yielded, _ = run_async(test1()) + # Make sure that __aiter__ was called only once + self.assertEqual(aiter_calls, 1) + self.assertEqual(yielded, [i * 100 for i in range(1, 11)]) + self.assertEqual(buffer, [i*2 for i in range(1, 101)]) + + + buffer = [] + async def test2(): + nonlocal buffer + async for i in AsyncIter(): + buffer.append(i[0]) + if i[0] == 20: + break + else: + buffer.append('what?') + buffer.append('end') + + yielded, _ = run_async(test2()) + # Make sure that __aiter__ was called only once + self.assertEqual(aiter_calls, 2) + self.assertEqual(yielded, [100, 200]) + self.assertEqual(buffer, [i for i in range(1, 21)] + ['end']) + + + buffer = [] + async def test3(): + nonlocal buffer + async for i in AsyncIter(): + if i[0] > 20: + continue + buffer.append(i[0]) + else: + buffer.append('what?') + buffer.append('end') + + yielded, _ = run_async(test3()) + # Make sure that __aiter__ was called only once + self.assertEqual(aiter_calls, 3) + self.assertEqual(yielded, [i * 100 for i in range(1, 11)]) + self.assertEqual(buffer, [i for i in range(1, 21)] + + ['what?', 'end']) + + def test_for_2(self): + tup = (1, 2, 3) + refs_before = sys.getrefcount(tup) + + async def foo(): + async for i in tup: + print('never going to happen') + + with self.assertRaisesRegex( + TypeError, "async for' requires an object.*__aiter__.*tuple"): + + run_async(foo()) + + self.assertEqual(sys.getrefcount(tup), refs_before) + + def test_for_3(self): + class I: + def __aiter__(self): + return self + + aiter = I() + refs_before = sys.getrefcount(aiter) + + async def foo(): + async for i in aiter: + print('never going to happen') + + with self.assertRaisesRegex( + TypeError, + "async for' received an invalid object.*__aiter.*\: I"): + + run_async(foo()) + + self.assertEqual(sys.getrefcount(aiter), refs_before) + + def test_for_4(self): + class I: + async def __aiter__(self): + return self + + def __anext__(self): + return () + + aiter = I() + refs_before = sys.getrefcount(aiter) + + async def foo(): + async for i in aiter: + print('never going to happen') + + with self.assertRaisesRegex( + TypeError, + "async for' received an invalid object.*__anext__.*tuple"): + + run_async(foo()) + + self.assertEqual(sys.getrefcount(aiter), refs_before) + + def test_for_5(self): + class I: + async def __aiter__(self): + return self + + def __anext__(self): + return 123 + + async def foo(): + async for i in I(): + print('never going to happen') + + with self.assertRaisesRegex( + TypeError, + "async for' received an invalid object.*__anext.*int"): + + run_async(foo()) + + def test_for_6(self): + I = 0 + + class Manager: + async def __aenter__(self): + nonlocal I + I += 10000 + + async def __aexit__(self, *args): + nonlocal I + I += 100000 + + class Iterable: + def __init__(self): + self.i = 0 + + async def __aiter__(self): + return self + + async def __anext__(self): + if self.i > 10: + raise StopAsyncIteration + self.i += 1 + return self.i + + ############## + + manager = Manager() + iterable = Iterable() + mrefs_before = sys.getrefcount(manager) + irefs_before = sys.getrefcount(iterable) + + async def main(): + nonlocal I + + async with manager: + async for i in iterable: + I += 1 + I += 1000 + + run_async(main()) + self.assertEqual(I, 111011) + + self.assertEqual(sys.getrefcount(manager), mrefs_before) + self.assertEqual(sys.getrefcount(iterable), irefs_before) + + ############## + + async def main(): + nonlocal I + + async with Manager(): + async for i in Iterable(): + I += 1 + I += 1000 + + async with Manager(): + async for i in Iterable(): + I += 1 + I += 1000 + + run_async(main()) + self.assertEqual(I, 333033) + + ############## + + async def main(): + nonlocal I + + async with Manager(): + I += 100 + async for i in Iterable(): + I += 1 + else: + I += 10000000 + I += 1000 + + async with Manager(): + I += 100 + async for i in Iterable(): + I += 1 + else: + I += 10000000 + I += 1000 + + run_async(main()) + self.assertEqual(I, 20555255) + + def test_for_7(self): + CNT = 0 + class AI: + async def __aiter__(self): + 1/0 + async def foo(): + nonlocal CNT + async for i in AI(): + CNT += 1 + CNT += 10 + with self.assertRaises(ZeroDivisionError): + run_async(foo()) + self.assertEqual(CNT, 0) + + +class CoroAsyncIOCompatTest(unittest.TestCase): + + def test_asyncio_1(self): + # asyncio cannot be imported when Python is compiled without thread + # support + asyncio = support.import_module('asyncio') + + class MyException(Exception): + pass + + buffer = [] + + class CM: + async def __aenter__(self): + buffer.append(1) + await asyncio.sleep(0.01) + buffer.append(2) + return self + + async def __aexit__(self, exc_type, exc_val, exc_tb): + await asyncio.sleep(0.01) + buffer.append(exc_type.__name__) + + async def f(): + async with CM() as c: + await asyncio.sleep(0.01) + raise MyException + buffer.append('unreachable') + + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + try: + loop.run_until_complete(f()) + except MyException: + pass + finally: + loop.close() + asyncio.set_event_loop(None) + + self.assertEqual(buffer, [1, 2, 'MyException']) + + +class SysSetCoroWrapperTest(unittest.TestCase): + + def test_set_wrapper_1(self): + async def foo(): + return 'spam' + + wrapped = None + def wrap(gen): + nonlocal wrapped + wrapped = gen + return gen + + self.assertIsNone(sys.get_coroutine_wrapper()) + + sys.set_coroutine_wrapper(wrap) + self.assertIs(sys.get_coroutine_wrapper(), wrap) + try: + f = foo() + self.assertTrue(wrapped) + + self.assertEqual(run_async(f), ([], 'spam')) + finally: + sys.set_coroutine_wrapper(None) + + self.assertIsNone(sys.get_coroutine_wrapper()) + + wrapped = None + with silence_coro_gc(): + foo() + self.assertFalse(wrapped) + + def test_set_wrapper_2(self): + self.assertIsNone(sys.get_coroutine_wrapper()) + with self.assertRaisesRegex(TypeError, "callable expected, got int"): + sys.set_coroutine_wrapper(1) + self.assertIsNone(sys.get_coroutine_wrapper()) + + def test_set_wrapper_3(self): + async def foo(): + return 'spam' + + def wrapper(coro): + async def wrap(coro): + return await coro + return wrap(coro) + + sys.set_coroutine_wrapper(wrapper) + try: + with silence_coro_gc(), self.assertRaisesRegex( + RuntimeError, + "coroutine wrapper.*\.wrapper at 0x.*attempted to " + "recursively wrap .* wrap .*"): + + foo() + finally: + sys.set_coroutine_wrapper(None) + + def test_set_wrapper_4(self): + @types.coroutine + def foo(): + return 'spam' + + wrapped = None + def wrap(gen): + nonlocal wrapped + wrapped = gen + return gen + + sys.set_coroutine_wrapper(wrap) + try: + foo() + self.assertIs( + wrapped, None, + "generator-based coroutine was wrapped via " + "sys.set_coroutine_wrapper") + finally: + sys.set_coroutine_wrapper(None) + + +class CAPITest(unittest.TestCase): + + def test_tp_await_1(self): + from _testcapi import awaitType as at + + async def foo(): + future = at(iter([1])) + return (await future) + + self.assertEqual(foo().send(None), 1) + + def test_tp_await_2(self): + # Test tp_await to __await__ mapping + from _testcapi import awaitType as at + future = at(iter([1])) + self.assertEqual(next(future.__await__()), 1) + + def test_tp_await_3(self): + from _testcapi import awaitType as at + + async def foo(): + future = at(1) + return (await future) + + with self.assertRaisesRegex( + TypeError, "__await__.*returned non-iterator of type 'int'"): + self.assertEqual(foo().send(None), 1) + + +if __name__=="__main__": + unittest.main() diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py index c3eb7faf8f6a..f18983fbb279 100644 --- a/Lib/test/test_cprofile.py +++ b/Lib/test/test_cprofile.py @@ -11,7 +11,7 @@ class CProfileTest(ProfileTest): profilerclass = cProfile.Profile profilermodule = cProfile - expected_max_output = "{built-in method max}" + expected_max_output = "{built-in method builtins.max}" def get_expected_output(self): return _ProfileOutput @@ -29,6 +29,7 @@ def test_bad_counter_during_dealloc(self): obj.enable() obj = _lsprof.Profiler(1) obj.disable() + obj.clear() finally: sys.stderr = orig_stderr finally: @@ -71,9 +72,9 @@ def main(): profilee.py:88(helper2) <- 6 0.234 0.300 profilee.py:55(helper) 2 0.078 0.100 profilee.py:84(helper2_indirect) profilee.py:98(subhelper) <- 8 0.064 0.080 profilee.py:88(helper2) -{built-in method exc_info} <- 4 0.000 0.000 profilee.py:73(helper1) -{built-in method hasattr} <- 4 0.000 0.004 profilee.py:73(helper1) +{built-in method builtins.hasattr} <- 4 0.000 0.004 profilee.py:73(helper1) 8 0.000 0.008 profilee.py:88(helper2) +{built-in method sys.exc_info} <- 4 0.000 0.000 profilee.py:73(helper1) {method 'append' of 'list' objects} <- 4 0.000 0.000 profilee.py:73(helper1)""" _ProfileOutput['print_callees'] = """\ :1() -> 1 0.270 1.000 profilee.py:25(testfunc) @@ -86,12 +87,12 @@ def main(): profilee.py:55(helper) -> 4 0.116 0.120 profilee.py:73(helper1) 2 0.000 0.140 profilee.py:84(helper2_indirect) 6 0.234 0.300 profilee.py:88(helper2) -profilee.py:73(helper1) -> 4 0.000 0.000 {built-in method exc_info} +profilee.py:73(helper1) -> 4 0.000 0.004 {built-in method builtins.hasattr} profilee.py:84(helper2_indirect) -> 2 0.006 0.040 profilee.py:35(factorial) 2 0.078 0.100 profilee.py:88(helper2) profilee.py:88(helper2) -> 8 0.064 0.080 profilee.py:98(subhelper) profilee.py:98(subhelper) -> 16 0.016 0.016 profilee.py:110(__getattr__) -{built-in method hasattr} -> 12 0.012 0.012 profilee.py:110(__getattr__)""" +{built-in method builtins.hasattr} -> 12 0.012 0.012 profilee.py:110(__getattr__)""" if __name__ == "__main__": main() diff --git a/Lib/test/test_crashers.py b/Lib/test/test_crashers.py index 336ccbeaff95..58dfd001da36 100644 --- a/Lib/test/test_crashers.py +++ b/Lib/test/test_crashers.py @@ -8,7 +8,7 @@ import glob import os.path import test.support -from test.script_helper import assert_python_failure +from test.support.script_helper import assert_python_failure CRASHER_DIR = os.path.join(os.path.dirname(__file__), "crashers") CRASHER_FILES = os.path.join(CRASHER_DIR, "*.py") @@ -30,9 +30,8 @@ def test_crashers_crash(self): assert_python_failure(fname) -def test_main(): - test.support.run_unittest(CrasherTest) +def tearDownModule(): test.support.reap_children() if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_csv.py b/Lib/test/test_csv.py index 01fba21f0e3c..8e9c2b479a78 100644 --- a/Lib/test/test_csv.py +++ b/Lib/test/test_csv.py @@ -124,12 +124,19 @@ def _write_test(self, fields, expect, **kwargs): self.assertEqual(fileobj.read(), expect + writer.dialect.lineterminator) + def _write_error_test(self, exc, fields, **kwargs): + with TemporaryFile("w+", newline='') as fileobj: + writer = csv.writer(fileobj, **kwargs) + with self.assertRaises(exc): + writer.writerow(fields) + fileobj.seek(0) + self.assertEqual(fileobj.read(), '') + def test_write_arg_valid(self): - self.assertRaises(csv.Error, self._write_test, None, '') + self._write_error_test(csv.Error, None) self._write_test((), '') self._write_test([None], '""') - self.assertRaises(csv.Error, self._write_test, - [None], None, quoting = csv.QUOTE_NONE) + self._write_error_test(csv.Error, [None], quoting = csv.QUOTE_NONE) # Check that exceptions are passed up the chain class BadList: def __len__(self): @@ -137,11 +144,11 @@ def __len__(self): def __getitem__(self, i): if i > 2: raise OSError - self.assertRaises(OSError, self._write_test, BadList(), '') + self._write_error_test(OSError, BadList()) class BadItem: def __str__(self): raise OSError - self.assertRaises(OSError, self._write_test, [BadItem()], '') + self._write_error_test(OSError, [BadItem()]) def test_write_bigfield(self): # This exercises the buffer realloc functionality @@ -151,10 +158,8 @@ def test_write_bigfield(self): def test_write_quoting(self): self._write_test(['a',1,'p,q'], 'a,1,"p,q"') - self.assertRaises(csv.Error, - self._write_test, - ['a',1,'p,q'], 'a,1,p,q', - quoting = csv.QUOTE_NONE) + self._write_error_test(csv.Error, ['a',1,'p,q'], + quoting = csv.QUOTE_NONE) self._write_test(['a',1,'p,q'], 'a,1,"p,q"', quoting = csv.QUOTE_MINIMAL) self._write_test(['a',1,'p,q'], '"a",1,"p,q"', @@ -167,10 +172,8 @@ def test_write_quoting(self): def test_write_escape(self): self._write_test(['a',1,'p,q'], 'a,1,"p,q"', escapechar='\\') - self.assertRaises(csv.Error, - self._write_test, - ['a',1,'p,"q"'], 'a,1,"p,\\"q\\""', - escapechar=None, doublequote=False) + self._write_error_test(csv.Error, ['a',1,'p,"q"'], + escapechar=None, doublequote=False) self._write_test(['a',1,'p,"q"'], 'a,1,"p,\\"q\\""', escapechar='\\', doublequote = False) self._write_test(['"'], '""""', @@ -183,6 +186,14 @@ def test_write_escape(self): self._write_test(['a',1,'p,q'], 'a,1,p\\,q', escapechar='\\', quoting = csv.QUOTE_NONE) + def test_write_iterable(self): + self._write_test(iter(['a', 1, 'p,q']), 'a,1,"p,q"') + self._write_test(iter(['a', 1, None]), 'a,1,') + self._write_test(iter([]), '') + self._write_test(iter([None]), '""') + self._write_error_test(csv.Error, iter([None]), quoting=csv.QUOTE_NONE) + self._write_test(iter([None, None]), ',') + def test_writerows(self): class BrokenFile: def write(self, buf): @@ -575,6 +586,16 @@ def test_write_simple_dict(self): fileobj.readline() # header self.assertEqual(fileobj.read(), "10,,abc\r\n") + def test_write_multiple_dict_rows(self): + fileobj = StringIO() + writer = csv.DictWriter(fileobj, fieldnames=["f1", "f2", "f3"]) + writer.writeheader() + self.assertEqual(fileobj.getvalue(), "f1,f2,f3\r\n") + writer.writerows([{"f1": 1, "f2": "abc", "f3": "f"}, + {"f1": 2, "f2": 5, "f3": "xyz"}]) + self.assertEqual(fileobj.getvalue(), + "f1,f2,f3\r\n1,abc,f\r\n2,5,xyz\r\n") + def test_write_no_fields(self): fileobj = StringIO() self.assertRaises(TypeError, csv.DictWriter, fileobj) @@ -756,6 +777,7 @@ class mydialect(csv.Dialect): lineterminator = '\r\n' quoting = csv.QUOTE_NONE d = mydialect() + self.assertEqual(d.quoting, csv.QUOTE_NONE) mydialect.quoting = None self.assertRaises(csv.Error, mydialect) @@ -764,12 +786,21 @@ class mydialect(csv.Dialect): mydialect.quoting = csv.QUOTE_ALL mydialect.quotechar = '"' d = mydialect() + self.assertEqual(d.quoting, csv.QUOTE_ALL) + self.assertEqual(d.quotechar, '"') + self.assertTrue(d.doublequote) mydialect.quotechar = "''" - self.assertRaises(csv.Error, mydialect) + with self.assertRaises(csv.Error) as cm: + mydialect() + self.assertEqual(str(cm.exception), + '"quotechar" must be a 1-character string') mydialect.quotechar = 4 - self.assertRaises(csv.Error, mydialect) + with self.assertRaises(csv.Error) as cm: + mydialect() + self.assertEqual(str(cm.exception), + '"quotechar" must be string, not int') def test_delimiter(self): class mydialect(csv.Dialect): @@ -780,12 +811,31 @@ class mydialect(csv.Dialect): lineterminator = '\r\n' quoting = csv.QUOTE_NONE d = mydialect() + self.assertEqual(d.delimiter, ";") mydialect.delimiter = ":::" - self.assertRaises(csv.Error, mydialect) + with self.assertRaises(csv.Error) as cm: + mydialect() + self.assertEqual(str(cm.exception), + '"delimiter" must be a 1-character string') + + mydialect.delimiter = "" + with self.assertRaises(csv.Error) as cm: + mydialect() + self.assertEqual(str(cm.exception), + '"delimiter" must be a 1-character string') + + mydialect.delimiter = b"," + with self.assertRaises(csv.Error) as cm: + mydialect() + self.assertEqual(str(cm.exception), + '"delimiter" must be string, not bytes') mydialect.delimiter = 4 - self.assertRaises(csv.Error, mydialect) + with self.assertRaises(csv.Error) as cm: + mydialect() + self.assertEqual(str(cm.exception), + '"delimiter" must be string, not int') def test_lineterminator(self): class mydialect(csv.Dialect): @@ -796,12 +846,31 @@ class mydialect(csv.Dialect): lineterminator = '\r\n' quoting = csv.QUOTE_NONE d = mydialect() + self.assertEqual(d.lineterminator, '\r\n') mydialect.lineterminator = ":::" d = mydialect() + self.assertEqual(d.lineterminator, ":::") mydialect.lineterminator = 4 - self.assertRaises(csv.Error, mydialect) + with self.assertRaises(csv.Error) as cm: + mydialect() + self.assertEqual(str(cm.exception), + '"lineterminator" must be a string') + + def test_invalid_chars(self): + def create_invalid(field_name, value): + class mydialect(csv.Dialect): + pass + setattr(mydialect, field_name, value) + d = mydialect() + + for field_name in ("delimiter", "escapechar", "quotechar"): + with self.subTest(field_name=field_name): + self.assertRaises(csv.Error, create_invalid, field_name, "") + self.assertRaises(csv.Error, create_invalid, field_name, "abc") + self.assertRaises(csv.Error, create_invalid, field_name, b'x') + self.assertRaises(csv.Error, create_invalid, field_name, 5) class TestSniffer(unittest.TestCase): @@ -1015,12 +1084,5 @@ def test_unicode_write(self): self.assertEqual(fileobj.read(), expected) - -def test_main(): - mod = sys.modules[__name__] - support.run_unittest( - *[getattr(mod, name) for name in dir(mod) if name.startswith('Test')] - ) - if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test_ctypes.py b/Lib/test/test_ctypes.py index 496355e61d34..68268992e9f9 100644 --- a/Lib/test/test_ctypes.py +++ b/Lib/test/test_ctypes.py @@ -1,16 +1,9 @@ import unittest - from test.support import import_module -# Skip tests if _ctypes module was not built. -import_module('_ctypes') - -import ctypes.test +ctypes_test = import_module('ctypes.test') -def load_tests(*args): - skipped, testcases = ctypes.test.get_tests(ctypes.test, "test_*.py", verbosity=0) - suites = [unittest.makeSuite(t) for t in testcases] - return unittest.TestSuite(suites) +load_tests = ctypes_test.load_tests if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py index 7310afc9958f..274704152007 100644 --- a/Lib/test/test_curses.py +++ b/Lib/test/test_curses.py @@ -2,364 +2,381 @@ # Test script for the curses module # # This script doesn't actually display anything very coherent. but it -# does call every method and function. +# does call (nearly) every method and function. # # Functions not tested: {def,reset}_{shell,prog}_mode, getch(), getstr(), # init_color() # Only called, not tested: getmouse(), ungetmouse() # -import sys, tempfile, os +import os +import sys +import tempfile +import unittest + +from test.support import requires, import_module, verbose # Optionally test curses module. This currently requires that the # 'curses' resource be given on the regrtest command line using the -u # option. If not available, nothing after this line will be executed. - -import unittest -from test.support import requires, import_module +import inspect requires('curses') # If either of these don't exist, skip the tests. curses = import_module('curses') curses.panel = import_module('curses.panel') +term = os.environ.get('TERM', 'unknown') + +@unittest.skipUnless(sys.__stdout__.isatty(), 'sys.__stdout__ is not a tty') +@unittest.skipIf(term == 'unknown', + "$TERM=%r, calling initscr() may cause exit" % term) +@unittest.skipIf(sys.platform == "cygwin", + "cygwin's curses mostly just hangs") +class TestCurses(unittest.TestCase): + @classmethod + def setUpClass(cls): + curses.setupterm(fd=sys.__stdout__.fileno()) + + def setUp(self): + if verbose: + # just to make the test output a little more readable + print() + self.stdscr = curses.initscr() + curses.savetty() + + def tearDown(self): + curses.resetty() + curses.endwin() + + def test_window_funcs(self): + "Test the methods of windows" + stdscr = self.stdscr + win = curses.newwin(10,10) + win = curses.newwin(5,5, 5,5) + win2 = curses.newwin(15,15, 5,5) + + for meth in [stdscr.addch, stdscr.addstr]: + for args in [('a'), ('a', curses.A_BOLD), + (4,4, 'a'), (5,5, 'a', curses.A_BOLD)]: + meth(*args) + + for meth in [stdscr.box, stdscr.clear, stdscr.clrtobot, + stdscr.clrtoeol, stdscr.cursyncup, stdscr.delch, + stdscr.deleteln, stdscr.erase, stdscr.getbegyx, + stdscr.getbkgd, stdscr.getkey, stdscr.getmaxyx, + stdscr.getparyx, stdscr.getyx, stdscr.inch, + stdscr.insertln, stdscr.instr, stdscr.is_wintouched, + win.noutrefresh, stdscr.redrawwin, stdscr.refresh, + stdscr.standout, stdscr.standend, stdscr.syncdown, + stdscr.syncup, stdscr.touchwin, stdscr.untouchwin]: + meth() + + stdscr.addnstr('1234', 3) + stdscr.addnstr('1234', 3, curses.A_BOLD) + stdscr.addnstr(4,4, '1234', 3) + stdscr.addnstr(5,5, '1234', 3, curses.A_BOLD) + + stdscr.attron(curses.A_BOLD) + stdscr.attroff(curses.A_BOLD) + stdscr.attrset(curses.A_BOLD) + stdscr.bkgd(' ') + stdscr.bkgd(' ', curses.A_REVERSE) + stdscr.bkgdset(' ') + stdscr.bkgdset(' ', curses.A_REVERSE) -# XXX: if newterm was supported we could use it instead of initscr and not exit -term = os.environ.get('TERM') -if not term or term == 'unknown': - raise unittest.SkipTest("$TERM=%r, calling initscr() may cause exit" % term) - -if sys.platform == "cygwin": - raise unittest.SkipTest("cygwin's curses mostly just hangs") - -def window_funcs(stdscr): - "Test the methods of windows" - win = curses.newwin(10,10) - win = curses.newwin(5,5, 5,5) - win2 = curses.newwin(15,15, 5,5) - - for meth in [stdscr.addch, stdscr.addstr]: - for args in [('a'), ('a', curses.A_BOLD), - (4,4, 'a'), (5,5, 'a', curses.A_BOLD)]: - meth(*args) - - for meth in [stdscr.box, stdscr.clear, stdscr.clrtobot, - stdscr.clrtoeol, stdscr.cursyncup, stdscr.delch, - stdscr.deleteln, stdscr.erase, stdscr.getbegyx, - stdscr.getbkgd, stdscr.getkey, stdscr.getmaxyx, - stdscr.getparyx, stdscr.getyx, stdscr.inch, - stdscr.insertln, stdscr.instr, stdscr.is_wintouched, - win.noutrefresh, stdscr.redrawwin, stdscr.refresh, - stdscr.standout, stdscr.standend, stdscr.syncdown, - stdscr.syncup, stdscr.touchwin, stdscr.untouchwin]: - meth() - - stdscr.addnstr('1234', 3) - stdscr.addnstr('1234', 3, curses.A_BOLD) - stdscr.addnstr(4,4, '1234', 3) - stdscr.addnstr(5,5, '1234', 3, curses.A_BOLD) - - stdscr.attron(curses.A_BOLD) - stdscr.attroff(curses.A_BOLD) - stdscr.attrset(curses.A_BOLD) - stdscr.bkgd(' ') - stdscr.bkgd(' ', curses.A_REVERSE) - stdscr.bkgdset(' ') - stdscr.bkgdset(' ', curses.A_REVERSE) - - win.border(65, 66, 67, 68, - 69, 70, 71, 72) - win.border('|', '!', '-', '_', - '+', '\\', '#', '/') - try: win.border(65, 66, 67, 68, - 69, [], 71, 72) - except TypeError: - pass - else: - raise RuntimeError("Expected win.border() to raise TypeError") - - stdscr.clearok(1) - - win4 = stdscr.derwin(2,2) - win4 = stdscr.derwin(1,1, 5,5) - win4.mvderwin(9,9) - - stdscr.echochar('a') - stdscr.echochar('a', curses.A_BOLD) - stdscr.hline('-', 5) - stdscr.hline('-', 5, curses.A_BOLD) - stdscr.hline(1,1,'-', 5) - stdscr.hline(1,1,'-', 5, curses.A_BOLD) - - stdscr.idcok(1) - stdscr.idlok(1) - stdscr.immedok(1) - stdscr.insch('c') - stdscr.insdelln(1) - stdscr.insnstr('abc', 3) - stdscr.insnstr('abc', 3, curses.A_BOLD) - stdscr.insnstr(5, 5, 'abc', 3) - stdscr.insnstr(5, 5, 'abc', 3, curses.A_BOLD) - - stdscr.insstr('def') - stdscr.insstr('def', curses.A_BOLD) - stdscr.insstr(5, 5, 'def') - stdscr.insstr(5, 5, 'def', curses.A_BOLD) - stdscr.is_linetouched(0) - stdscr.keypad(1) - stdscr.leaveok(1) - stdscr.move(3,3) - win.mvwin(2,2) - stdscr.nodelay(1) - stdscr.notimeout(1) - win2.overlay(win) - win2.overwrite(win) - win2.overlay(win, 1, 2, 3, 3, 2, 1) - win2.overwrite(win, 1, 2, 3, 3, 2, 1) - stdscr.redrawln(1,2) - - stdscr.scrollok(1) - stdscr.scroll() - stdscr.scroll(2) - stdscr.scroll(-3) - - stdscr.move(12, 2) - stdscr.setscrreg(10,15) - win3 = stdscr.subwin(10,10) - win3 = stdscr.subwin(10,10, 5,5) - stdscr.syncok(1) - stdscr.timeout(5) - stdscr.touchline(5,5) - stdscr.touchline(5,5,0) - stdscr.vline('a', 3) - stdscr.vline('a', 3, curses.A_STANDOUT) - stdscr.chgat(5, 2, 3, curses.A_BLINK) - stdscr.chgat(3, curses.A_BOLD) - stdscr.chgat(5, 8, curses.A_UNDERLINE) - stdscr.chgat(curses.A_BLINK) - stdscr.refresh() - - stdscr.vline(1,1, 'a', 3) - stdscr.vline(1,1, 'a', 3, curses.A_STANDOUT) - - if hasattr(curses, 'resize'): - stdscr.resize() - if hasattr(curses, 'enclose'): - stdscr.enclose() - - -def module_funcs(stdscr): - "Test module-level functions" - - for func in [curses.baudrate, curses.beep, curses.can_change_color, - curses.cbreak, curses.def_prog_mode, curses.doupdate, - curses.filter, curses.flash, curses.flushinp, - curses.has_colors, curses.has_ic, curses.has_il, - curses.isendwin, curses.killchar, curses.longname, - curses.nocbreak, curses.noecho, curses.nonl, - curses.noqiflush, curses.noraw, - curses.reset_prog_mode, curses.termattrs, - curses.termname, curses.erasechar, curses.getsyx]: - func() - - # Functions that actually need arguments - if curses.tigetstr("cnorm"): - curses.curs_set(1) - curses.delay_output(1) - curses.echo() ; curses.echo(1) - - f = tempfile.TemporaryFile() - stdscr.putwin(f) - f.seek(0) - curses.getwin(f) - f.close() - - curses.halfdelay(1) - curses.intrflush(1) - curses.meta(1) - curses.napms(100) - curses.newpad(50,50) - win = curses.newwin(5,5) - win = curses.newwin(5,5, 1,1) - curses.nl() ; curses.nl(1) - curses.putp(b'abc') - curses.qiflush() - curses.raw() ; curses.raw(1) - curses.setsyx(5,5) - curses.tigetflag('hc') - curses.tigetnum('co') - curses.tigetstr('cr') - curses.tparm(b'cr') - curses.typeahead(sys.__stdin__.fileno()) - curses.unctrl('a') - curses.ungetch('a') - curses.use_env(1) - - # Functions only available on a few platforms - if curses.has_colors(): - curses.start_color() - curses.init_pair(2, 1,1) - curses.color_content(1) - curses.color_pair(2) - curses.pair_content(curses.COLOR_PAIRS - 1) - curses.pair_number(0) - - if hasattr(curses, 'use_default_colors'): - curses.use_default_colors() - - if hasattr(curses, 'keyname'): - curses.keyname(13) - - if hasattr(curses, 'has_key'): - curses.has_key(13) - - if hasattr(curses, 'getmouse'): - (availmask, oldmask) = curses.mousemask(curses.BUTTON1_PRESSED) - # availmask indicates that mouse stuff not available. - if availmask != 0: - curses.mouseinterval(10) - # just verify these don't cause errors - curses.ungetmouse(0, 0, 0, 0, curses.BUTTON1_PRESSED) - m = curses.getmouse() - - if hasattr(curses, 'is_term_resized'): - curses.is_term_resized(*stdscr.getmaxyx()) - if hasattr(curses, 'resizeterm'): - curses.resizeterm(*stdscr.getmaxyx()) - if hasattr(curses, 'resize_term'): - curses.resize_term(*stdscr.getmaxyx()) - -def unit_tests(): - from curses import ascii - for ch, expected in [('a', 'a'), ('A', 'A'), - (';', ';'), (' ', ' '), - ('\x7f', '^?'), ('\n', '^J'), ('\0', '^@'), - # Meta-bit characters - ('\x8a', '!^J'), ('\xc1', '!A'), - ]: - if ascii.unctrl(ch) != expected: - print('curses.unctrl fails on character', repr(ch)) - - -def test_userptr_without_set(stdscr): - w = curses.newwin(10, 10) - p = curses.panel.new_panel(w) - # try to access userptr() before calling set_userptr() -- segfaults - try: - p.userptr() - raise RuntimeError('userptr should fail since not set') - except curses.panel.error: - pass - -def test_userptr_memory_leak(stdscr): - w = curses.newwin(10, 10) - p = curses.panel.new_panel(w) - obj = object() - nrefs = sys.getrefcount(obj) - for i in range(100): - p.set_userptr(obj) - - p.set_userptr(None) - if sys.getrefcount(obj) != nrefs: - raise RuntimeError("set_userptr leaked references") - -def test_userptr_segfault(stdscr): - panel = curses.panel.new_panel(stdscr) - class A: - def __del__(self): - panel.set_userptr(None) - panel.set_userptr(A()) - panel.set_userptr(None) - -def test_resize_term(stdscr): - if hasattr(curses, 'resizeterm'): + 69, 70, 71, 72) + win.border('|', '!', '-', '_', + '+', '\\', '#', '/') + with self.assertRaises(TypeError, + msg="Expected win.border() to raise TypeError"): + win.border(65, 66, 67, 68, + 69, [], 71, 72) + + stdscr.clearok(1) + + win4 = stdscr.derwin(2,2) + win4 = stdscr.derwin(1,1, 5,5) + win4.mvderwin(9,9) + + stdscr.echochar('a') + stdscr.echochar('a', curses.A_BOLD) + stdscr.hline('-', 5) + stdscr.hline('-', 5, curses.A_BOLD) + stdscr.hline(1,1,'-', 5) + stdscr.hline(1,1,'-', 5, curses.A_BOLD) + + stdscr.idcok(1) + stdscr.idlok(1) + stdscr.immedok(1) + stdscr.insch('c') + stdscr.insdelln(1) + stdscr.insnstr('abc', 3) + stdscr.insnstr('abc', 3, curses.A_BOLD) + stdscr.insnstr(5, 5, 'abc', 3) + stdscr.insnstr(5, 5, 'abc', 3, curses.A_BOLD) + + stdscr.insstr('def') + stdscr.insstr('def', curses.A_BOLD) + stdscr.insstr(5, 5, 'def') + stdscr.insstr(5, 5, 'def', curses.A_BOLD) + stdscr.is_linetouched(0) + stdscr.keypad(1) + stdscr.leaveok(1) + stdscr.move(3,3) + win.mvwin(2,2) + stdscr.nodelay(1) + stdscr.notimeout(1) + win2.overlay(win) + win2.overwrite(win) + win2.overlay(win, 1, 2, 2, 1, 3, 3) + win2.overwrite(win, 1, 2, 2, 1, 3, 3) + stdscr.redrawln(1,2) + + stdscr.scrollok(1) + stdscr.scroll() + stdscr.scroll(2) + stdscr.scroll(-3) + + stdscr.move(12, 2) + stdscr.setscrreg(10,15) + win3 = stdscr.subwin(10,10) + win3 = stdscr.subwin(10,10, 5,5) + stdscr.syncok(1) + stdscr.timeout(5) + stdscr.touchline(5,5) + stdscr.touchline(5,5,0) + stdscr.vline('a', 3) + stdscr.vline('a', 3, curses.A_STANDOUT) + stdscr.chgat(5, 2, 3, curses.A_BLINK) + stdscr.chgat(3, curses.A_BOLD) + stdscr.chgat(5, 8, curses.A_UNDERLINE) + stdscr.chgat(curses.A_BLINK) + stdscr.refresh() + + stdscr.vline(1,1, 'a', 3) + stdscr.vline(1,1, 'a', 3, curses.A_STANDOUT) + + if hasattr(curses, 'resize'): + stdscr.resize() + if hasattr(curses, 'enclose'): + stdscr.enclose() + + + def test_module_funcs(self): + "Test module-level functions" + stdscr = self.stdscr + for func in [curses.baudrate, curses.beep, curses.can_change_color, + curses.cbreak, curses.def_prog_mode, curses.doupdate, + curses.filter, curses.flash, curses.flushinp, + curses.has_colors, curses.has_ic, curses.has_il, + curses.isendwin, curses.killchar, curses.longname, + curses.nocbreak, curses.noecho, curses.nonl, + curses.noqiflush, curses.noraw, + curses.reset_prog_mode, curses.termattrs, + curses.termname, curses.erasechar, curses.getsyx]: + func() + + # Functions that actually need arguments + if curses.tigetstr("cnorm"): + curses.curs_set(1) + curses.delay_output(1) + curses.echo() ; curses.echo(1) + + f = tempfile.TemporaryFile() + stdscr.putwin(f) + f.seek(0) + curses.getwin(f) + f.close() + + curses.halfdelay(1) + curses.intrflush(1) + curses.meta(1) + curses.napms(100) + curses.newpad(50,50) + win = curses.newwin(5,5) + win = curses.newwin(5,5, 1,1) + curses.nl() ; curses.nl(1) + curses.putp(b'abc') + curses.qiflush() + curses.raw() ; curses.raw(1) + curses.setsyx(5,5) + curses.tigetflag('hc') + curses.tigetnum('co') + curses.tigetstr('cr') + curses.tparm(b'cr') + curses.typeahead(sys.__stdin__.fileno()) + curses.unctrl('a') + curses.ungetch('a') + curses.use_env(1) + + # Functions only available on a few platforms + if curses.has_colors(): + curses.start_color() + curses.init_pair(2, 1,1) + curses.color_content(1) + curses.color_pair(2) + curses.pair_content(curses.COLOR_PAIRS - 1) + curses.pair_number(0) + + if hasattr(curses, 'use_default_colors'): + curses.use_default_colors() + + if hasattr(curses, 'keyname'): + curses.keyname(13) + + if hasattr(curses, 'has_key'): + curses.has_key(13) + + if hasattr(curses, 'getmouse'): + (availmask, oldmask) = curses.mousemask(curses.BUTTON1_PRESSED) + # availmask indicates that mouse stuff not available. + if availmask != 0: + curses.mouseinterval(10) + # just verify these don't cause errors + curses.ungetmouse(0, 0, 0, 0, curses.BUTTON1_PRESSED) + m = curses.getmouse() + + if hasattr(curses, 'is_term_resized'): + curses.is_term_resized(*stdscr.getmaxyx()) + if hasattr(curses, 'resizeterm'): + curses.resizeterm(*stdscr.getmaxyx()) + if hasattr(curses, 'resize_term'): + curses.resize_term(*stdscr.getmaxyx()) + + def test_unctrl(self): + from curses import ascii + for ch, expected in [('a', 'a'), ('A', 'A'), + (';', ';'), (' ', ' '), + ('\x7f', '^?'), ('\n', '^J'), ('\0', '^@'), + # Meta-bit characters + ('\x8a', '!^J'), ('\xc1', '!A'), + ]: + self.assertEqual(ascii.unctrl(ch), expected, + 'curses.unctrl fails on character %r' % ch) + + + def test_userptr_without_set(self): + w = curses.newwin(10, 10) + p = curses.panel.new_panel(w) + # try to access userptr() before calling set_userptr() -- segfaults + with self.assertRaises(curses.panel.error, + msg='userptr should fail since not set'): + p.userptr() + + def test_userptr_memory_leak(self): + w = curses.newwin(10, 10) + p = curses.panel.new_panel(w) + obj = object() + nrefs = sys.getrefcount(obj) + for i in range(100): + p.set_userptr(obj) + + p.set_userptr(None) + self.assertEqual(sys.getrefcount(obj), nrefs, + "set_userptr leaked references") + + def test_userptr_segfault(self): + panel = curses.panel.new_panel(self.stdscr) + class A: + def __del__(self): + panel.set_userptr(None) + panel.set_userptr(A()) + panel.set_userptr(None) + + @unittest.skipUnless(hasattr(curses, 'resizeterm'), + 'resizeterm not available') + def test_resize_term(self): lines, cols = curses.LINES, curses.COLS - curses.resizeterm(lines - 1, cols + 1) - - if curses.LINES != lines - 1 or curses.COLS != cols + 1: - raise RuntimeError("Expected resizeterm to update LINES and COLS") - -def test_issue6243(stdscr): - curses.ungetch(1025) - stdscr.getkey() - -def test_unget_wch(stdscr): - if not hasattr(curses, 'unget_wch'): - return - encoding = stdscr.encoding - for ch in ('a', '\xe9', '\u20ac', '\U0010FFFF'): + new_lines = lines - 1 + new_cols = cols + 1 + curses.resizeterm(new_lines, new_cols) + + self.assertEqual(curses.LINES, new_lines) + self.assertEqual(curses.COLS, new_cols) + + def test_issue6243(self): + curses.ungetch(1025) + self.stdscr.getkey() + + @unittest.skipUnless(hasattr(curses, 'unget_wch'), + 'unget_wch not available') + def test_unget_wch(self): + stdscr = self.stdscr + encoding = stdscr.encoding + for ch in ('a', '\xe9', '\u20ac', '\U0010FFFF'): + try: + ch.encode(encoding) + except UnicodeEncodeError: + continue + try: + curses.unget_wch(ch) + except Exception as err: + self.fail("unget_wch(%a) failed with encoding %s: %s" + % (ch, stdscr.encoding, err)) + read = stdscr.get_wch() + self.assertEqual(read, ch) + + code = ord(ch) + curses.unget_wch(code) + read = stdscr.get_wch() + self.assertEqual(read, ch) + + def test_issue10570(self): + b = curses.tparm(curses.tigetstr("cup"), 5, 3) + self.assertIs(type(b), bytes) + curses.putp(b) + + def test_encoding(self): + stdscr = self.stdscr + import codecs + encoding = stdscr.encoding + codecs.lookup(encoding) + + with self.assertRaises(TypeError): + stdscr.encoding = 10 + + stdscr.encoding = encoding + with self.assertRaises(TypeError): + del stdscr.encoding + + def test_issue21088(self): + stdscr = self.stdscr + # + # http://bugs.python.org/issue21088 + # + # the bug: + # when converting curses.window.addch to Argument Clinic + # the first two parameters were switched. + + # if someday we can represent the signature of addch + # we will need to rewrite this test. try: - ch.encode(encoding) - except UnicodeEncodeError: - continue - try: - curses.unget_wch(ch) - except Exception as err: - raise Exception("unget_wch(%a) failed with encoding %s: %s" - % (ch, stdscr.encoding, err)) - read = stdscr.get_wch() - if read != ch: - raise AssertionError("%r != %r" % (read, ch)) - - code = ord(ch) - curses.unget_wch(code) - read = stdscr.get_wch() - if read != ch: - raise AssertionError("%r != %r" % (read, ch)) - -def test_issue10570(): - b = curses.tparm(curses.tigetstr("cup"), 5, 3) - assert type(b) is bytes - curses.putp(b) - -def test_encoding(stdscr): - import codecs - encoding = stdscr.encoding - codecs.lookup(encoding) - try: - stdscr.encoding = 10 - except TypeError: - pass - else: - raise AssertionError("TypeError not raised") - stdscr.encoding = encoding - try: - del stdscr.encoding - except TypeError: - pass - else: - raise AssertionError("TypeError not raised") - -def main(stdscr): - curses.savetty() - try: - module_funcs(stdscr) - window_funcs(stdscr) - test_userptr_without_set(stdscr) - test_userptr_memory_leak(stdscr) - test_userptr_segfault(stdscr) - test_resize_term(stdscr) - test_issue6243(stdscr) - test_unget_wch(stdscr) - test_issue10570() - test_encoding(stdscr) - finally: - curses.resetty() + signature = inspect.signature(stdscr.addch) + self.assertFalse(signature) + except ValueError: + # not generating a signature is fine. + pass + + # So. No signature for addch. + # But Argument Clinic gave us a human-readable equivalent + # as the first line of the docstring. So we parse that, + # and ensure that the parameters appear in the correct order. + # Since this is parsing output from Argument Clinic, we can + # be reasonably certain the generated parsing code will be + # correct too. + human_readable_signature = stdscr.addch.__doc__.split("\n")[0] + offset = human_readable_signature.find("[y, x,]") + assert offset >= 0, "" + + def test_update_lines_cols(self): + # this doesn't actually test that LINES and COLS are updated, + # because we can't automate changing them. See Issue #4254 for + # a manual test script. We can only test that the function + # can be called. + curses.update_lines_cols() -def test_main(): - if not sys.__stdout__.isatty(): - raise unittest.SkipTest("sys.__stdout__ is not a tty") - # testing setupterm() inside initscr/endwin - # causes terminal breakage - curses.setupterm(fd=sys.__stdout__.fileno()) - try: - stdscr = curses.initscr() - main(stdscr) - finally: - curses.endwin() - unit_tests() if __name__ == '__main__': - curses.wrapper(main) - unit_tests() + unittest.main() diff --git a/Lib/test/test_datetime.py b/Lib/test/test_datetime.py index d9ddb32363a0..2d4eb52c62c0 100644 --- a/Lib/test/test_datetime.py +++ b/Lib/test/test_datetime.py @@ -1,20 +1,20 @@ import unittest import sys + from test.support import import_fresh_module, run_unittest TESTS = 'test.datetimetester' -# XXX: import_fresh_module() is supposed to leave sys.module cache untouched, -# XXX: but it does not, so we have to save and restore it ourselves. -save_sys_modules = sys.modules.copy() try: pure_tests = import_fresh_module(TESTS, fresh=['datetime', '_strptime'], blocked=['_datetime']) fast_tests = import_fresh_module(TESTS, fresh=['datetime', '_datetime', '_strptime']) finally: - sys.modules.clear() - sys.modules.update(save_sys_modules) + # XXX: import_fresh_module() is supposed to leave sys.module cache untouched, + # XXX: but it does not, so we have to cleanup ourselves. + for modname in ['datetime', '_datetime', '_strptime']: + sys.modules.pop(modname, None) test_modules = [pure_tests, fast_tests] test_suffixes = ["_Pure", "_Fast"] # XXX(gb) First run all the _Pure tests, then all the _Fast tests. You might diff --git a/Lib/test/test_dbm.py b/Lib/test/test_dbm.py index 1c5777024234..623d9929d58f 100644 --- a/Lib/test/test_dbm.py +++ b/Lib/test/test_dbm.py @@ -1,4 +1,3 @@ -#! /usr/bin/env python3 """Test script for the dbm.open function based on testdumbdbm.py""" import os diff --git a/Lib/test/test_dbm_dumb.py b/Lib/test/test_dbm_dumb.py index 9fd8cde59a84..ff63c88c0bc5 100644 --- a/Lib/test/test_dbm_dumb.py +++ b/Lib/test/test_dbm_dumb.py @@ -1,13 +1,14 @@ -#! /usr/bin/env python3 """Test script for the dumbdbm module Original by Roger E. Masse """ import io +import operator import os import unittest import dbm.dumb as dumbdbm from test import support +from functools import partial _fname = support.TESTFN @@ -191,12 +192,48 @@ def test_context_manager(self): with dumbdbm.open(_fname, 'r') as db: self.assertEqual(list(db.keys()), [b"dumbdbm context manager"]) - # This currently just raises AttributeError rather than a specific - # exception like the GNU or NDBM based implementations. See - # http://bugs.python.org/issue19385 for details. - with self.assertRaises(Exception): + with self.assertRaises(dumbdbm.error): db.keys() + def test_check_closed(self): + f = dumbdbm.open(_fname, 'c') + f.close() + + for meth in (partial(operator.delitem, f), + partial(operator.setitem, f, 'b'), + partial(operator.getitem, f), + partial(operator.contains, f)): + with self.assertRaises(dumbdbm.error) as cm: + meth('test') + self.assertEqual(str(cm.exception), + "DBM object has already been closed") + + for meth in (operator.methodcaller('keys'), + operator.methodcaller('iterkeys'), + operator.methodcaller('items'), + len): + with self.assertRaises(dumbdbm.error) as cm: + meth(f) + self.assertEqual(str(cm.exception), + "DBM object has already been closed") + + def test_create_new(self): + with dumbdbm.open(_fname, 'n') as f: + for k in self._dict: + f[k] = self._dict[k] + + with dumbdbm.open(_fname, 'n') as f: + self.assertEqual(f.keys(), []) + + def test_eval(self): + with open(_fname + '.dir', 'w') as stream: + stream.write("str(print('Hacked!')), 0\n") + with support.captured_stdout() as stdout: + with self.assertRaises(ValueError): + with dumbdbm.open(_fname) as f: + pass + self.assertEqual(stdout.getvalue(), '') + def tearDown(self): _delete_files() diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 6378ef300e21..137aaa537e2d 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -33,12 +33,13 @@ import numbers import locale from test.support import (run_unittest, run_doctest, is_resource_enabled, - requires_IEEE_754) + requires_IEEE_754, requires_docstrings) from test.support import (check_warnings, import_fresh_module, TestFailed, run_with_locale, cpython_only) import random import time import warnings +import inspect try: import threading except ImportError: @@ -300,7 +301,6 @@ def eval_file(self, file): #Exception raised where there shouldn't have been one. self.fail('Exception "'+exception.__class__.__name__ + '" raised on line '+line) - return def eval_line(self, s): if s.find(' -> ') >= 0 and s[:2] != '--' and not s.startswith(' --'): @@ -460,7 +460,6 @@ def FixQuotes(val): self.assertEqual(myexceptions, theirexceptions, 'Incorrect flags set in ' + s + ' -- got ' + str(myexceptions)) - return def getexceptions(self): return [e for e in Signals[self.decimal] if self.context.flags[e]] @@ -1059,6 +1058,11 @@ def test_formatting(self): # issue 6850 ('a=-7.0', '0.12345', 'aaaa0.1'), + + # issue 22090 + ('<^+15.20%', 'inf', '<<+Infinity%<<<'), + ('\x07>,%', 'sNaN1234567', 'sNaN1234567%'), + ('=10.10%', 'NaN123', ' NaN123%'), ] for fmt, d, result in test_values: self.assertEqual(format(Decimal(d), fmt), result) @@ -1072,7 +1076,7 @@ def test_n_format(self): try: from locale import CHAR_MAX except ImportError: - return + self.skipTest('locale.CHAR_MAX not available') def make_grouping(lst): return ''.join([chr(x) for x in lst]) if self.decimal == C else lst @@ -1163,8 +1167,12 @@ def test_wide_char_separator_decimal_point(self): decimal_point = locale.localeconv()['decimal_point'] thousands_sep = locale.localeconv()['thousands_sep'] - if decimal_point != '\u066b' or thousands_sep != '\u066c': - return + if decimal_point != '\u066b': + self.skipTest('inappropriate decimal point separator' + '({!a} not {!a})'.format(decimal_point, '\u066b')) + if thousands_sep != '\u066c': + self.skipTest('inappropriate thousands separator' + '({!a} not {!a})'.format(thousands_sep, '\u066c')) self.assertEqual(format(Decimal('100000000.123'), 'n'), '100\u066c000\u066c000\u066b123') @@ -1514,7 +1522,6 @@ def thfunc1(cls): cls.assertTrue(c1.flags[Inexact]) for sig in Overflow, Underflow, DivisionByZero, InvalidOperation: cls.assertFalse(c1.flags[sig]) - return def thfunc2(cls): Decimal = cls.decimal.Decimal @@ -1559,7 +1566,6 @@ def thfunc2(cls): cls.assertTrue(thiscontext.flags[Inexact]) for sig in Overflow, Underflow, DivisionByZero, InvalidOperation: cls.assertFalse(thiscontext.flags[sig]) - return class ThreadingTest(unittest.TestCase): '''Unit tests for thread local contexts in Decimal.''' @@ -1601,7 +1607,6 @@ def test_threading(self): DefaultContext.prec = save_prec DefaultContext.Emax = save_emax DefaultContext.Emin = save_emin - return @unittest.skipUnless(threading, 'threading required') class CThreadingTest(ThreadingTest): @@ -2402,37 +2407,55 @@ def test_abc(self): self.assertNotIsInstance(Decimal(0), numbers.Real) def test_pickle(self): - Decimal = self.decimal.Decimal + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + Decimal = self.decimal.Decimal - savedecimal = sys.modules['decimal'] + savedecimal = sys.modules['decimal'] - # Round trip - sys.modules['decimal'] = self.decimal - d = Decimal('-3.141590000') - p = pickle.dumps(d) - e = pickle.loads(p) - self.assertEqual(d, e) + # Round trip + sys.modules['decimal'] = self.decimal + d = Decimal('-3.141590000') + p = pickle.dumps(d, proto) + e = pickle.loads(p) + self.assertEqual(d, e) - if C: - # Test interchangeability - x = C.Decimal('-3.123e81723') - y = P.Decimal('-3.123e81723') + if C: + # Test interchangeability + x = C.Decimal('-3.123e81723') + y = P.Decimal('-3.123e81723') - sys.modules['decimal'] = C - sx = pickle.dumps(x) - sys.modules['decimal'] = P - r = pickle.loads(sx) - self.assertIsInstance(r, P.Decimal) - self.assertEqual(r, y) + sys.modules['decimal'] = C + sx = pickle.dumps(x, proto) + sys.modules['decimal'] = P + r = pickle.loads(sx) + self.assertIsInstance(r, P.Decimal) + self.assertEqual(r, y) + + sys.modules['decimal'] = P + sy = pickle.dumps(y, proto) + sys.modules['decimal'] = C + r = pickle.loads(sy) + self.assertIsInstance(r, C.Decimal) + self.assertEqual(r, x) - sys.modules['decimal'] = P - sy = pickle.dumps(y) - sys.modules['decimal'] = C - r = pickle.loads(sy) - self.assertIsInstance(r, C.Decimal) - self.assertEqual(r, x) + x = C.Decimal('-3.123e81723').as_tuple() + y = P.Decimal('-3.123e81723').as_tuple() - sys.modules['decimal'] = savedecimal + sys.modules['decimal'] = C + sx = pickle.dumps(x, proto) + sys.modules['decimal'] = P + r = pickle.loads(sx) + self.assertIsInstance(r, P.DecimalTuple) + self.assertEqual(r, y) + + sys.modules['decimal'] = P + sy = pickle.dumps(y, proto) + sys.modules['decimal'] = C + r = pickle.loads(sy) + self.assertIsInstance(r, C.DecimalTuple) + self.assertEqual(r, x) + + sys.modules['decimal'] = savedecimal def test_int(self): Decimal = self.decimal.Decimal @@ -2756,63 +2779,64 @@ def test_from_legacy_strings(self): def test_pickle(self): - Context = self.decimal.Context + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + Context = self.decimal.Context - savedecimal = sys.modules['decimal'] + savedecimal = sys.modules['decimal'] - # Round trip - sys.modules['decimal'] = self.decimal - c = Context() - e = pickle.loads(pickle.dumps(c)) - - self.assertEqual(c.prec, e.prec) - self.assertEqual(c.Emin, e.Emin) - self.assertEqual(c.Emax, e.Emax) - self.assertEqual(c.rounding, e.rounding) - self.assertEqual(c.capitals, e.capitals) - self.assertEqual(c.clamp, e.clamp) - self.assertEqual(c.flags, e.flags) - self.assertEqual(c.traps, e.traps) - - # Test interchangeability - combinations = [(C, P), (P, C)] if C else [(P, P)] - for dumper, loader in combinations: - for ri, _ in enumerate(RoundingModes): - for fi, _ in enumerate(OrderedSignals[dumper]): - for ti, _ in enumerate(OrderedSignals[dumper]): - - prec = random.randrange(1, 100) - emin = random.randrange(-100, 0) - emax = random.randrange(1, 100) - caps = random.randrange(2) - clamp = random.randrange(2) - - # One module dumps - sys.modules['decimal'] = dumper - c = dumper.Context( - prec=prec, Emin=emin, Emax=emax, - rounding=RoundingModes[ri], - capitals=caps, clamp=clamp, - flags=OrderedSignals[dumper][:fi], - traps=OrderedSignals[dumper][:ti] - ) - s = pickle.dumps(c) - - # The other module loads - sys.modules['decimal'] = loader - d = pickle.loads(s) - self.assertIsInstance(d, loader.Context) - - self.assertEqual(d.prec, prec) - self.assertEqual(d.Emin, emin) - self.assertEqual(d.Emax, emax) - self.assertEqual(d.rounding, RoundingModes[ri]) - self.assertEqual(d.capitals, caps) - self.assertEqual(d.clamp, clamp) - assert_signals(self, d, 'flags', OrderedSignals[loader][:fi]) - assert_signals(self, d, 'traps', OrderedSignals[loader][:ti]) - - sys.modules['decimal'] = savedecimal + # Round trip + sys.modules['decimal'] = self.decimal + c = Context() + e = pickle.loads(pickle.dumps(c, proto)) + + self.assertEqual(c.prec, e.prec) + self.assertEqual(c.Emin, e.Emin) + self.assertEqual(c.Emax, e.Emax) + self.assertEqual(c.rounding, e.rounding) + self.assertEqual(c.capitals, e.capitals) + self.assertEqual(c.clamp, e.clamp) + self.assertEqual(c.flags, e.flags) + self.assertEqual(c.traps, e.traps) + + # Test interchangeability + combinations = [(C, P), (P, C)] if C else [(P, P)] + for dumper, loader in combinations: + for ri, _ in enumerate(RoundingModes): + for fi, _ in enumerate(OrderedSignals[dumper]): + for ti, _ in enumerate(OrderedSignals[dumper]): + + prec = random.randrange(1, 100) + emin = random.randrange(-100, 0) + emax = random.randrange(1, 100) + caps = random.randrange(2) + clamp = random.randrange(2) + + # One module dumps + sys.modules['decimal'] = dumper + c = dumper.Context( + prec=prec, Emin=emin, Emax=emax, + rounding=RoundingModes[ri], + capitals=caps, clamp=clamp, + flags=OrderedSignals[dumper][:fi], + traps=OrderedSignals[dumper][:ti] + ) + s = pickle.dumps(c, proto) + + # The other module loads + sys.modules['decimal'] = loader + d = pickle.loads(s) + self.assertIsInstance(d, loader.Context) + + self.assertEqual(d.prec, prec) + self.assertEqual(d.Emin, emin) + self.assertEqual(d.Emax, emax) + self.assertEqual(d.rounding, RoundingModes[ri]) + self.assertEqual(d.capitals, caps) + self.assertEqual(d.clamp, clamp) + assert_signals(self, d, 'flags', OrderedSignals[loader][:fi]) + assert_signals(self, d, 'traps', OrderedSignals[loader][:ti]) + + sys.modules['decimal'] = savedecimal def test_equality_with_other_types(self): Decimal = self.decimal.Decimal @@ -4151,9 +4175,7 @@ def test_module_attributes(self): self.assertEqual(C.__version__, P.__version__) self.assertEqual(C.__libmpdec_version__, P.__libmpdec_version__) - x = dir(C) - y = [s for s in dir(P) if '__' in s or not s.startswith('_')] - self.assertEqual(set(x) - set(y), set()) + self.assertEqual(dir(C), dir(P)) def test_context_attributes(self): @@ -4432,18 +4454,6 @@ class PyCoverage(Coverage): class PyFunctionality(unittest.TestCase): """Extra functionality in decimal.py""" - def test_py_quantize_watchexp(self): - # watchexp functionality - Decimal = P.Decimal - localcontext = P.localcontext - - with localcontext() as c: - c.prec = 1 - c.Emax = 1 - c.Emin = -1 - x = Decimal(99999).quantize(Decimal("1e3"), watchexp=False) - self.assertEqual(x, Decimal('1.00E+5')) - def test_py_alternate_formatting(self): # triples giving a format, a Decimal, and the expected result Decimal = P.Decimal @@ -4524,7 +4534,6 @@ def checkSameDec(operation, useOther=False): self.assertEqual(d1._sign, b1._sign) self.assertEqual(d1._int, b1._int) self.assertEqual(d1._exp, b1._exp) - return Decimal(d1) self.assertEqual(d1._sign, b1._sign) @@ -5270,7 +5279,7 @@ def test_invalid_override(self): try: from locale import CHAR_MAX except ImportError: - return + self.skipTest('locale.CHAR_MAX not available') def make_grouping(lst): return ''.join([chr(x) for x in lst]) @@ -5387,6 +5396,143 @@ def test_sizeof(self): y = Decimal(10**(9*25)).__sizeof__() self.assertEqual(y, x+4) +@requires_docstrings +@unittest.skipUnless(C, "test requires C version") +class SignatureTest(unittest.TestCase): + """Function signatures""" + + def test_inspect_module(self): + for attr in dir(P): + if attr.startswith('_'): + continue + p_func = getattr(P, attr) + c_func = getattr(C, attr) + if (attr == 'Decimal' or attr == 'Context' or + inspect.isfunction(p_func)): + p_sig = inspect.signature(p_func) + c_sig = inspect.signature(c_func) + + # parameter names: + c_names = list(c_sig.parameters.keys()) + p_names = [x for x in p_sig.parameters.keys() if not + x.startswith('_')] + + self.assertEqual(c_names, p_names, + msg="parameter name mismatch in %s" % p_func) + + c_kind = [x.kind for x in c_sig.parameters.values()] + p_kind = [x[1].kind for x in p_sig.parameters.items() if not + x[0].startswith('_')] + + # parameters: + if attr != 'setcontext': + self.assertEqual(c_kind, p_kind, + msg="parameter kind mismatch in %s" % p_func) + + def test_inspect_types(self): + + POS = inspect._ParameterKind.POSITIONAL_ONLY + POS_KWD = inspect._ParameterKind.POSITIONAL_OR_KEYWORD + + # Type heuristic (type annotations would help!): + pdict = {C: {'other': C.Decimal(1), + 'third': C.Decimal(1), + 'x': C.Decimal(1), + 'y': C.Decimal(1), + 'z': C.Decimal(1), + 'a': C.Decimal(1), + 'b': C.Decimal(1), + 'c': C.Decimal(1), + 'exp': C.Decimal(1), + 'modulo': C.Decimal(1), + 'num': "1", + 'f': 1.0, + 'rounding': C.ROUND_HALF_UP, + 'context': C.getcontext()}, + P: {'other': P.Decimal(1), + 'third': P.Decimal(1), + 'a': P.Decimal(1), + 'b': P.Decimal(1), + 'c': P.Decimal(1), + 'exp': P.Decimal(1), + 'modulo': P.Decimal(1), + 'num': "1", + 'f': 1.0, + 'rounding': P.ROUND_HALF_UP, + 'context': P.getcontext()}} + + def mkargs(module, sig): + args = [] + kwargs = {} + for name, param in sig.parameters.items(): + if name == 'self': continue + if param.kind == POS: + args.append(pdict[module][name]) + elif param.kind == POS_KWD: + kwargs[name] = pdict[module][name] + else: + raise TestFailed("unexpected parameter kind") + return args, kwargs + + def tr(s): + """The C Context docstrings use 'x' in order to prevent confusion + with the article 'a' in the descriptions.""" + if s == 'x': return 'a' + if s == 'y': return 'b' + if s == 'z': return 'c' + return s + + def doit(ty): + p_type = getattr(P, ty) + c_type = getattr(C, ty) + for attr in dir(p_type): + if attr.startswith('_'): + continue + p_func = getattr(p_type, attr) + c_func = getattr(c_type, attr) + if inspect.isfunction(p_func): + p_sig = inspect.signature(p_func) + c_sig = inspect.signature(c_func) + + # parameter names: + p_names = list(p_sig.parameters.keys()) + c_names = [tr(x) for x in c_sig.parameters.keys()] + + self.assertEqual(c_names, p_names, + msg="parameter name mismatch in %s" % p_func) + + p_kind = [x.kind for x in p_sig.parameters.values()] + c_kind = [x.kind for x in c_sig.parameters.values()] + + # 'self' parameter: + self.assertIs(p_kind[0], POS_KWD) + self.assertIs(c_kind[0], POS) + + # remaining parameters: + if ty == 'Decimal': + self.assertEqual(c_kind[1:], p_kind[1:], + msg="parameter kind mismatch in %s" % p_func) + else: # Context methods are positional only in the C version. + self.assertEqual(len(c_kind), len(p_kind), + msg="parameter kind mismatch in %s" % p_func) + + # Run the function: + args, kwds = mkargs(C, c_sig) + try: + getattr(c_type(9), attr)(*args, **kwds) + except Exception as err: + raise TestFailed("invalid signature for %s: %s %s" % (c_func, args, kwds)) + + args, kwds = mkargs(P, p_sig) + try: + getattr(p_type(9), attr)(*args, **kwds) + except Exception as err: + raise TestFailed("invalid signature for %s: %s %s" % (p_func, args, kwds)) + + doit('Decimal') + doit('Context') + + all_tests = [ CExplicitConstructionTest, PyExplicitConstructionTest, CImplicitConstructionTest, PyImplicitConstructionTest, @@ -5412,9 +5558,10 @@ def test_sizeof(self): all_tests = all_tests[1::2] else: all_tests.insert(0, CheckAttributes) + all_tests.insert(1, SignatureTest) -def test_main(arith=False, verbose=None, todo_tests=None, debug=None): +def test_main(arith=None, verbose=None, todo_tests=None, debug=None): """ Execute the tests. Runs all arithmetic tests if arith is True or if the "decimal" resource @@ -5424,7 +5571,7 @@ def test_main(arith=False, verbose=None, todo_tests=None, debug=None): init(C) init(P) global TEST_ALL, DEBUG - TEST_ALL = arith or is_resource_enabled('decimal') + TEST_ALL = arith if arith is not None else is_resource_enabled('decimal') DEBUG = debug if todo_tests is None: diff --git a/Lib/test/test_decorators.py b/Lib/test/test_decorators.py index 53c946911229..d0a2ec9fddb8 100644 --- a/Lib/test/test_decorators.py +++ b/Lib/test/test_decorators.py @@ -1,5 +1,4 @@ import unittest -from test import support def funcattrs(**kwds): def decorate(func): @@ -301,9 +300,5 @@ def applied_second(x): class C(object): pass self.assertEqual(C.extra, 'second') -def test_main(): - support.run_unittest(TestDecorators) - support.run_unittest(TestClassDecorators) - -if __name__=="__main__": - test_main() +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_defaultdict.py b/Lib/test/test_defaultdict.py index 532d535981b3..a90bc2b488cf 100644 --- a/Lib/test/test_defaultdict.py +++ b/Lib/test/test_defaultdict.py @@ -5,7 +5,6 @@ import pickle import tempfile import unittest -from test import support from collections import defaultdict @@ -157,8 +156,9 @@ def __init__(self): def _factory(self): return [] d = sub() - self.assertTrue(repr(d).startswith( - "defaultdict(, \{\}\)") # NOTE: printing a subclass of a builtin type does not call its # tp_print slot. So this part is essentially the same test as above. @@ -183,8 +183,5 @@ def test_pickleing(self): o = pickle.loads(s) self.assertEqual(d, o) -def test_main(): - support.run_unittest(TestDefaultDict) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_deque.py b/Lib/test/test_deque.py index 7bff1d2798b4..c61e80bc2e45 100644 --- a/Lib/test/test_deque.py +++ b/Lib/test/test_deque.py @@ -164,6 +164,26 @@ def test_comparisons(self): self.assertEqual(x > y, list(x) > list(y), (x,y)) self.assertEqual(x >= y, list(x) >= list(y), (x,y)) + def test_contains(self): + n = 200 + + d = deque(range(n)) + for i in range(n): + self.assertTrue(i in d) + self.assertTrue((n+1) not in d) + + # Test detection of mutation during iteration + d = deque(range(n)) + d[n//2] = MutateCmp(d, False) + with self.assertRaises(RuntimeError): + n in d + + # Test detection of comparison exceptions + d = deque(range(n)) + d[n//2] = BadCmp() + with self.assertRaises(RuntimeError): + n in d + def test_extend(self): d = deque('a') self.assertRaises(TypeError, d.extend, 1) @@ -172,6 +192,26 @@ def test_extend(self): d.extend(d) self.assertEqual(list(d), list('abcdabcd')) + def test_add(self): + d = deque() + e = deque('abc') + f = deque('def') + self.assertEqual(d + d, deque()) + self.assertEqual(e + f, deque('abcdef')) + self.assertEqual(e + e, deque('abcabc')) + self.assertEqual(e + d, deque('abc')) + self.assertEqual(d + e, deque('abc')) + self.assertIsNot(d + d, deque()) + self.assertIsNot(e + d, deque('abc')) + self.assertIsNot(d + e, deque('abc')) + + g = deque('abcdef', maxlen=4) + h = deque('gh') + self.assertEqual(g + h, deque('efgh')) + + with self.assertRaises(TypeError): + deque('abc') + 'def' + def test_iadd(self): d = deque('a') d += 'bcd' @@ -211,6 +251,116 @@ def test_getitem(self): self.assertRaises(IndexError, d.__getitem__, 0) self.assertRaises(IndexError, d.__getitem__, -1) + def test_index(self): + for n in 1, 2, 30, 40, 200: + + d = deque(range(n)) + for i in range(n): + self.assertEqual(d.index(i), i) + + with self.assertRaises(ValueError): + d.index(n+1) + + # Test detection of mutation during iteration + d = deque(range(n)) + d[n//2] = MutateCmp(d, False) + with self.assertRaises(RuntimeError): + d.index(n) + + # Test detection of comparison exceptions + d = deque(range(n)) + d[n//2] = BadCmp() + with self.assertRaises(RuntimeError): + d.index(n) + + # Test start and stop arguments behavior matches list.index() + elements = 'ABCDEFGHI' + nonelement = 'Z' + d = deque(elements * 2) + s = list(elements * 2) + for start in range(-5 - len(s)*2, 5 + len(s) * 2): + for stop in range(-5 - len(s)*2, 5 + len(s) * 2): + for element in elements + 'Z': + try: + target = s.index(element, start, stop) + except ValueError: + with self.assertRaises(ValueError): + d.index(element, start, stop) + else: + self.assertEqual(d.index(element, start, stop), target) + + def test_insert_bug_24913(self): + d = deque('A' * 3) + with self.assertRaises(ValueError): + i = d.index("Hello world", 0, 4) + + def test_insert(self): + # Test to make sure insert behaves like lists + elements = 'ABCDEFGHI' + for i in range(-5 - len(elements)*2, 5 + len(elements) * 2): + d = deque('ABCDEFGHI') + s = list('ABCDEFGHI') + d.insert(i, 'Z') + s.insert(i, 'Z') + self.assertEqual(list(d), s) + + def test_imul(self): + for n in (-10, -1, 0, 1, 2, 10, 1000): + d = deque() + d *= n + self.assertEqual(d, deque()) + self.assertIsNone(d.maxlen) + + for n in (-10, -1, 0, 1, 2, 10, 1000): + d = deque('a') + d *= n + self.assertEqual(d, deque('a' * n)) + self.assertIsNone(d.maxlen) + + for n in (-10, -1, 0, 1, 2, 10, 499, 500, 501, 1000): + d = deque('a', 500) + d *= n + self.assertEqual(d, deque('a' * min(n, 500))) + self.assertEqual(d.maxlen, 500) + + for n in (-10, -1, 0, 1, 2, 10, 1000): + d = deque('abcdef') + d *= n + self.assertEqual(d, deque('abcdef' * n)) + self.assertIsNone(d.maxlen) + + for n in (-10, -1, 0, 1, 2, 10, 499, 500, 501, 1000): + d = deque('abcdef', 500) + d *= n + self.assertEqual(d, deque(('abcdef' * n)[-500:])) + self.assertEqual(d.maxlen, 500) + + def test_mul(self): + d = deque('abc') + self.assertEqual(d * -5, deque()) + self.assertEqual(d * 0, deque()) + self.assertEqual(d * 1, deque('abc')) + self.assertEqual(d * 2, deque('abcabc')) + self.assertEqual(d * 3, deque('abcabcabc')) + self.assertIsNot(d * 1, d) + + self.assertEqual(deque() * 0, deque()) + self.assertEqual(deque() * 1, deque()) + self.assertEqual(deque() * 5, deque()) + + self.assertEqual(-5 * d, deque()) + self.assertEqual(0 * d, deque()) + self.assertEqual(1 * d, deque('abc')) + self.assertEqual(2 * d, deque('abcabc')) + self.assertEqual(3 * d, deque('abcabcabc')) + + d = deque('abc', maxlen=5) + self.assertEqual(d * -5, deque()) + self.assertEqual(d * 0, deque()) + self.assertEqual(d * 1, deque('abc')) + self.assertEqual(d * 2, deque('bcabc')) + self.assertEqual(d * 30, deque('bcabc')) + def test_setitem(self): n = 200 d = deque(range(n)) @@ -474,16 +624,17 @@ def test_pickle(self): def test_iterator_pickle(self): data = deque(range(200)) - it = itorg = iter(data) - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(type(itorg), type(it)) - self.assertEqual(list(it), list(data)) - - it = pickle.loads(d) - next(it) - d = pickle.dumps(it) - self.assertEqual(list(it), list(data)[1:]) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + it = itorg = iter(data) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(type(itorg), type(it)) + self.assertEqual(list(it), list(data)) + + it = pickle.loads(d) + next(it) + d = pickle.dumps(it, proto) + self.assertEqual(list(it), list(data)[1:]) def test_deepcopy(self): mut = [10] @@ -503,10 +654,33 @@ def test_copy(self): self.assertNotEqual(id(d), id(e)) self.assertEqual(list(d), list(e)) + for i in range(5): + for maxlen in range(-1, 6): + s = [random.random() for j in range(i)] + d = deque(s) if maxlen == -1 else deque(s, maxlen) + e = d.copy() + self.assertEqual(d, e) + self.assertEqual(d.maxlen, e.maxlen) + self.assertTrue(all(x is y for x, y in zip(d, e))) + + def test_copy_method(self): + mut = [10] + d = deque([mut]) + e = d.copy() + self.assertEqual(list(d), list(e)) + mut[0] = 11 + self.assertNotEqual(id(d), id(e)) + self.assertEqual(list(d), list(e)) + def test_reversed(self): for s in ('abcd', range(2000)): self.assertEqual(list(reversed(deque(s))), list(reversed(s))) + def test_reversed_new(self): + klass = type(reversed(deque())) + for s in ('abcd', range(2000)): + self.assertEqual(list(klass(deque(s))), list(reversed(s))) + def test_gc_doesnt_blowup(self): import gc # This used to assert-fail in deque_traverse() under a debug @@ -536,7 +710,7 @@ class C(object): @support.cpython_only def test_sizeof(self): - BLOCKLEN = 62 + BLOCKLEN = 64 basesize = support.calcobjsize('2P4nlP') blocksize = struct.calcsize('2P%dP' % BLOCKLEN) self.assertEqual(object.__sizeof__(deque()), basesize) @@ -614,11 +788,12 @@ def test_copy_pickle(self): self.assertEqual(type(d), type(e)) self.assertEqual(list(d), list(e)) - s = pickle.dumps(d) - e = pickle.loads(s) - self.assertNotEqual(id(d), id(e)) - self.assertEqual(type(d), type(e)) - self.assertEqual(list(d), list(e)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + s = pickle.dumps(d, proto) + e = pickle.loads(s) + self.assertNotEqual(id(d), id(e)) + self.assertEqual(type(d), type(e)) + self.assertEqual(list(d), list(e)) d = Deque('abcde', maxlen=4) @@ -630,11 +805,12 @@ def test_copy_pickle(self): self.assertEqual(type(d), type(e)) self.assertEqual(list(d), list(e)) - s = pickle.dumps(d) - e = pickle.loads(s) - self.assertNotEqual(id(d), id(e)) - self.assertEqual(type(d), type(e)) - self.assertEqual(list(d), list(e)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + s = pickle.dumps(d, proto) + e = pickle.loads(s) + self.assertNotEqual(id(d), id(e)) + self.assertEqual(type(d), type(e)) + self.assertEqual(list(d), list(e)) ## def test_pickle(self): ## d = Deque('abc') @@ -681,6 +857,21 @@ def test_subclass_with_kwargs(self): # SF bug #1486663 -- this used to erroneously raise a TypeError SubclassWithKwargs(newarg=1) +class TestSequence(seq_tests.CommonTest): + type2test = deque + + def test_getitem(self): + # For now, bypass tests that require slicing + pass + + def test_getslice(self): + # For now, bypass tests that require slicing + pass + + def test_subscript(self): + # For now, bypass tests that require slicing + pass + #============================================================================== libreftest = """ @@ -795,6 +986,7 @@ def test_main(verbose=None): TestVariousIteratorArgs, TestSubclass, TestSubclassWithKwargs, + TestSequence, ) support.run_unittest(*test_classes) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index f08a3d2bf613..d75109995e1a 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -21,7 +21,9 @@ def __init__(self, *args, **kwargs): 'add': '+', 'sub': '-', 'mul': '*', - 'div': '/', + 'matmul': '@', + 'truediv': '/', + 'floordiv': '//', 'divmod': 'divmod', 'pow': '**', 'lshift': '<<', @@ -52,8 +54,6 @@ def __init__(self, *args, **kwargs): 'invert': '~', 'int': 'int', 'float': 'float', - 'oct': 'oct', - 'hex': 'hex', } for name, expr in list(self.unops.items()): @@ -82,12 +82,6 @@ def unop_test(self, a, res, expr="len(a)", meth="__len__"): def binop_test(self, a, b, res, expr="a+b", meth="__add__"): d = {'a': a, 'b': b} - # XXX Hack so this passes before 2.3 when -Qnew is specified. - if meth == "__div__" and 1/2 == 0.5: - meth = "__truediv__" - - if meth == '__divmod__': pass - self.assertEqual(eval(expr, d), res) t = type(a) m = getattr(t, meth) @@ -221,7 +215,7 @@ def test_dicts(self): def number_operators(self, a, b, skip=[]): dict = {'a': a, 'b': b} - for name, expr in list(self.binops.items()): + for name, expr in self.binops.items(): if name not in skip: name = "__%s__" % name if hasattr(a, name): @@ -261,7 +255,7 @@ def test_complexes(self): # Testing complex operations... self.number_operators(100.0j, 3.0j, skip=['lt', 'le', 'gt', 'ge', 'int', 'float', - 'divmod', 'mod']) + 'floordiv', 'divmod', 'mod']) class Number(complex): __slots__ = ['prec'] @@ -1026,6 +1020,67 @@ class Cdict(object): self.assertEqual(x.foo, 1) self.assertEqual(x.__dict__, {'foo': 1}) + def test_object_class_assignment_between_heaptypes_and_nonheaptypes(self): + class SubType(types.ModuleType): + a = 1 + + m = types.ModuleType("m") + self.assertTrue(m.__class__ is types.ModuleType) + self.assertFalse(hasattr(m, "a")) + + m.__class__ = SubType + self.assertTrue(m.__class__ is SubType) + self.assertTrue(hasattr(m, "a")) + + m.__class__ = types.ModuleType + self.assertTrue(m.__class__ is types.ModuleType) + self.assertFalse(hasattr(m, "a")) + + # Make sure that builtin immutable objects don't support __class__ + # assignment, because the object instances may be interned. + # We set __slots__ = () to ensure that the subclasses are + # memory-layout compatible, and thus otherwise reasonable candidates + # for __class__ assignment. + + # The following types have immutable instances, but are not + # subclassable and thus don't need to be checked: + # NoneType, bool + + class MyInt(int): + __slots__ = () + with self.assertRaises(TypeError): + (1).__class__ = MyInt + + class MyFloat(float): + __slots__ = () + with self.assertRaises(TypeError): + (1.0).__class__ = MyFloat + + class MyComplex(complex): + __slots__ = () + with self.assertRaises(TypeError): + (1 + 2j).__class__ = MyComplex + + class MyStr(str): + __slots__ = () + with self.assertRaises(TypeError): + "a".__class__ = MyStr + + class MyBytes(bytes): + __slots__ = () + with self.assertRaises(TypeError): + b"a".__class__ = MyBytes + + class MyTuple(tuple): + __slots__ = () + with self.assertRaises(TypeError): + ().__class__ = MyTuple + + class MyFrozenSet(frozenset): + __slots__ = () + with self.assertRaises(TypeError): + frozenset().__class__ = MyFrozenSet + def test_slots(self): # Testing __slots__... class C0(object): @@ -1149,7 +1204,7 @@ class C(object): except (TypeError, UnicodeEncodeError): pass else: - raise TestFailed("[chr(128)] slots not caught") + self.fail("[chr(128)] slots not caught") # Test leaks class Counted(object): @@ -2012,7 +2067,7 @@ def delx(self): self.assertIs(raw.fset, C.__dict__['setx']) self.assertIs(raw.fdel, C.__dict__['delx']) - for attr in "__doc__", "fget", "fset", "fdel": + for attr in "fget", "fset", "fdel": try: setattr(raw, attr, 42) except AttributeError as msg: @@ -2023,6 +2078,9 @@ def delx(self): self.fail("expected AttributeError from trying to set readonly %r " "attr on a property" % attr) + raw.__doc__ = 42 + self.assertEqual(raw.__doc__, 42) + class D(object): __getitem__ = property(lambda s: 1/0) @@ -2050,6 +2108,7 @@ def setter(self_, value): prop2 = property(fset=setter) self.assertEqual(prop2.__doc__, None) + @support.cpython_only def test_testcapi_no_segfault(self): # this segfaulted in 2.5b2 try: @@ -3009,8 +3068,6 @@ def cant(x, C): cant(object(), list) cant(list(), object) class Int(int): __slots__ = [] - cant(2, Int) - cant(Int(), int) cant(True, int) cant(2, bool) o = object() @@ -3330,7 +3387,7 @@ class A(object): A.__call__ = A() try: A()() - except RuntimeError: + except RecursionError: pass else: self.fail("Recursion limit should have been reached for __call__()") @@ -3741,6 +3798,37 @@ class D(C): else: assert 0, "best_base calculation found wanting" + def test_unsubclassable_types(self): + with self.assertRaises(TypeError): + class X(type(None)): + pass + with self.assertRaises(TypeError): + class X(object, type(None)): + pass + with self.assertRaises(TypeError): + class X(type(None), object): + pass + class O(object): + pass + with self.assertRaises(TypeError): + class X(O, type(None)): + pass + with self.assertRaises(TypeError): + class X(type(None), O): + pass + + class X(object): + pass + with self.assertRaises(TypeError): + X.__bases__ = type(None), + with self.assertRaises(TypeError): + X.__bases__ = object, type(None) + with self.assertRaises(TypeError): + X.__bases__ = type(None), object + with self.assertRaises(TypeError): + X.__bases__ = O, type(None) + with self.assertRaises(TypeError): + X.__bases__ = type(None), O def test_mutable_bases_with_failing_mro(self): # Testing mutable bases with failing mro... @@ -4159,9 +4247,9 @@ def check(expr, x, y): ('__add__', 'x + y', 'x += y'), ('__sub__', 'x - y', 'x -= y'), ('__mul__', 'x * y', 'x *= y'), - ('__truediv__', 'operator.truediv(x, y)', None), - ('__floordiv__', 'operator.floordiv(x, y)', None), - ('__div__', 'x / y', 'x /= y'), + ('__matmul__', 'x @ y', 'x @= y'), + ('__truediv__', 'x / y', 'x /= y'), + ('__floordiv__', 'x // y', 'x //= y'), ('__mod__', 'x % y', 'x %= y'), ('__divmod__', 'divmod(x, y)', None), ('__pow__', 'x ** y', 'x **= y'), @@ -4223,8 +4311,8 @@ class X(object): # Also check type_getattro for correctness. class Meta(type): pass - class X(object): - __metaclass__ = Meta + class X(metaclass=Meta): + pass X.a = 42 Meta.a = Descr("a") self.assertEqual(X.a, 42) @@ -4305,8 +4393,8 @@ class Foo: pass Foo.__repr__ = Foo.__str__ foo = Foo() - self.assertRaises(RuntimeError, str, foo) - self.assertRaises(RuntimeError, repr, foo) + self.assertRaises(RecursionError, str, foo) + self.assertRaises(RecursionError, repr, foo) def test_mixing_slot_wrappers(self): class X(dict): @@ -4413,6 +4501,69 @@ class OverrideBoth(OverrideNew, OverrideInit): self.assertRaises(TypeError, case, 1, 2, 3) self.assertRaises(TypeError, case, 1, 2, foo=3) + def test_subclassing_does_not_duplicate_dict_descriptors(self): + class Base: + pass + class Sub(Base): + pass + self.assertIn("__dict__", Base.__dict__) + self.assertNotIn("__dict__", Sub.__dict__) + + def test_bound_method_repr(self): + class Foo: + def method(self): + pass + self.assertRegex(repr(Foo().method), + r">") + + + class Base: + def method(self): + pass + class Derived1(Base): + pass + class Derived2(Base): + def method(self): + pass + base = Base() + derived1 = Derived1() + derived2 = Derived2() + super_d2 = super(Derived2, derived2) + self.assertRegex(repr(base.method), + r">") + self.assertRegex(repr(derived1.method), + r">") + self.assertRegex(repr(derived2.method), + r">") + self.assertRegex(repr(super_d2.method), + r">") + + class Foo: + @classmethod + def method(cls): + pass + foo = Foo() + self.assertRegex(repr(foo.method), # access via instance + r">") + self.assertRegex(repr(Foo.method), # access via the class + r">") + + + class MyCallable: + def __call__(self, arg): + pass + func = MyCallable() # func has no __name__ or __qualname__ attributes + instance = object() + method = types.MethodType(func, instance) + self.assertRegex(repr(method), + r">") + func.__name__ = "name" + self.assertRegex(repr(method), + r">") + func.__qualname__ = "qualname" + self.assertRegex(repr(method), + r">") + class DictProxyTests(unittest.TestCase): def setUp(self): @@ -4527,26 +4678,15 @@ class PicklingTests(unittest.TestCase): def _check_reduce(self, proto, obj, args=(), kwargs={}, state=None, listitems=None, dictitems=None): - if proto >= 4: + if proto >= 2: reduce_value = obj.__reduce_ex__(proto) - self.assertEqual(reduce_value[:3], - (copyreg.__newobj_ex__, - (type(obj), args, kwargs), - state)) - if listitems is not None: - self.assertListEqual(list(reduce_value[3]), listitems) + if kwargs: + self.assertEqual(reduce_value[0], copyreg.__newobj_ex__) + self.assertEqual(reduce_value[1], (type(obj), args, kwargs)) else: - self.assertIsNone(reduce_value[3]) - if dictitems is not None: - self.assertDictEqual(dict(reduce_value[4]), dictitems) - else: - self.assertIsNone(reduce_value[4]) - elif proto >= 2: - reduce_value = obj.__reduce_ex__(proto) - self.assertEqual(reduce_value[:3], - (copyreg.__newobj__, - (type(obj),) + args, - state)) + self.assertEqual(reduce_value[0], copyreg.__newobj__) + self.assertEqual(reduce_value[1], (type(obj),) + args) + self.assertEqual(reduce_value[2], state) if listitems is not None: self.assertListEqual(list(reduce_value[3]), listitems) else: @@ -4598,11 +4738,8 @@ def __getnewargs_ex__(self): return (args, kwargs) obj = C3() for proto in protocols: - if proto >= 4: + if proto >= 2: self._check_reduce(proto, obj, args, kwargs) - elif proto >= 2: - with self.assertRaises(ValueError): - obj.__reduce_ex__(proto) class C4: def __getnewargs_ex__(self): @@ -4623,14 +4760,6 @@ def __getnewargs_ex__(self): with self.assertRaises((TypeError, ValueError)): obj.__reduce_ex__(proto) - class C8: - def __getnewargs_ex__(self): - return (args, kwargs) - obj = C8() - for proto in protocols: - if 2 <= proto < 4: - with self.assertRaises(ValueError): - obj.__reduce_ex__(proto) class C9: def __getnewargs_ex__(self): return (args, {}) @@ -4700,6 +4829,20 @@ class C16(list): for proto in protocols: self._check_reduce(proto, obj, listitems=list(obj)) + def test_special_method_lookup(self): + protocols = range(pickle.HIGHEST_PROTOCOL + 1) + class Picky: + def __getstate__(self): + return {} + + def __getattr__(self, attr): + if attr in ("__getnewargs__", "__getnewargs_ex__"): + raise AssertionError(attr) + return None + for protocol in protocols: + state = {} if protocol >= 2 else None + self._check_reduce(protocol, Picky(), state=state) + def _assert_is_copy(self, obj, objcopy, msg=None): """Utility method to verify if two objects are copies of each others. """ @@ -4915,10 +5058,6 @@ def __repr__(self): kwargs = getattr(cls, 'KWARGS', {}) obj = cls(*cls.ARGS, **kwargs) proto = pickle_copier.proto - if 2 <= proto < 4 and hasattr(cls, '__getnewargs_ex__'): - with self.assertRaises(ValueError): - pickle_copier.dumps(obj, proto) - continue objcopy = pickle_copier.copy(obj) self._assert_is_copy(obj, objcopy) # For test classes that supports this, make sure we didn't go @@ -4935,10 +5074,6 @@ def __repr__(self): with self.subTest(cls=cls): kwargs = getattr(cls, 'KWARGS', {}) obj = cls(*cls.ARGS, **kwargs) - # XXX: We need to modify the copy module to support PEP 3154's - # reduce protocol 4. - if hasattr(cls, '__getnewargs_ex__'): - continue objcopy = deepcopy(obj) self._assert_is_copy(obj, objcopy) # For test classes that supports this, make sure we didn't go @@ -4951,11 +5086,258 @@ def __repr__(self): self._assert_is_copy(obj, objcopy2) +class SharedKeyTests(unittest.TestCase): + + @support.cpython_only + def test_subclasses(self): + # Verify that subclasses can share keys (per PEP 412) + class A: + pass + class B(A): + pass + + a, b = A(), B() + self.assertEqual(sys.getsizeof(vars(a)), sys.getsizeof(vars(b))) + self.assertLess(sys.getsizeof(vars(a)), sys.getsizeof({})) + a.x, a.y, a.z, a.w = range(4) + self.assertNotEqual(sys.getsizeof(vars(a)), sys.getsizeof(vars(b))) + a2 = A() + self.assertEqual(sys.getsizeof(vars(a)), sys.getsizeof(vars(a2))) + self.assertLess(sys.getsizeof(vars(a)), sys.getsizeof({})) + b.u, b.v, b.w, b.t = range(4) + self.assertLess(sys.getsizeof(vars(b)), sys.getsizeof({})) + + +class DebugHelperMeta(type): + """ + Sets default __doc__ and simplifies repr() output. + """ + def __new__(mcls, name, bases, attrs): + if attrs.get('__doc__') is None: + attrs['__doc__'] = name # helps when debugging with gdb + return type.__new__(mcls, name, bases, attrs) + def __repr__(cls): + return repr(cls.__name__) + + +class MroTest(unittest.TestCase): + """ + Regressions for some bugs revealed through + mcsl.mro() customization (typeobject.c: mro_internal()) and + cls.__bases__ assignment (typeobject.c: type_set_bases()). + """ + + def setUp(self): + self.step = 0 + self.ready = False + + def step_until(self, limit): + ret = (self.step < limit) + if ret: + self.step += 1 + return ret + + def test_incomplete_set_bases_on_self(self): + """ + type_set_bases must be aware that type->tp_mro can be NULL. + """ + class M(DebugHelperMeta): + def mro(cls): + if self.step_until(1): + assert cls.__mro__ is None + cls.__bases__ += () + + return type.mro(cls) + + class A(metaclass=M): + pass + + def test_reent_set_bases_on_base(self): + """ + Deep reentrancy must not over-decref old_mro. + """ + class M(DebugHelperMeta): + def mro(cls): + if cls.__mro__ is not None and cls.__name__ == 'B': + # 4-5 steps are usually enough to make it crash somewhere + if self.step_until(10): + A.__bases__ += () + + return type.mro(cls) + + class A(metaclass=M): + pass + class B(A): + pass + B.__bases__ += () + + def test_reent_set_bases_on_direct_base(self): + """ + Similar to test_reent_set_bases_on_base, but may crash differently. + """ + class M(DebugHelperMeta): + def mro(cls): + base = cls.__bases__[0] + if base is not object: + if self.step_until(5): + base.__bases__ += () + + return type.mro(cls) + + class A(metaclass=M): + pass + class B(A): + pass + class C(B): + pass + + def test_reent_set_bases_tp_base_cycle(self): + """ + type_set_bases must check for an inheritance cycle not only through + MRO of the type, which may be not yet updated in case of reentrance, + but also through tp_base chain, which is assigned before diving into + inner calls to mro(). + + Otherwise, the following snippet can loop forever: + do { + // ... + type = type->tp_base; + } while (type != NULL); + + Functions that rely on tp_base (like solid_base and PyType_IsSubtype) + would not be happy in that case, causing a stack overflow. + """ + class M(DebugHelperMeta): + def mro(cls): + if self.ready: + if cls.__name__ == 'B1': + B2.__bases__ = (B1,) + if cls.__name__ == 'B2': + B1.__bases__ = (B2,) + return type.mro(cls) + + class A(metaclass=M): + pass + class B1(A): + pass + class B2(A): + pass + + self.ready = True + with self.assertRaises(TypeError): + B1.__bases__ += () + + def test_tp_subclasses_cycle_in_update_slots(self): + """ + type_set_bases must check for reentrancy upon finishing its job + by updating tp_subclasses of old/new bases of the type. + Otherwise, an implicit inheritance cycle through tp_subclasses + can break functions that recurse on elements of that field + (like recurse_down_subclasses and mro_hierarchy) eventually + leading to a stack overflow. + """ + class M(DebugHelperMeta): + def mro(cls): + if self.ready and cls.__name__ == 'C': + self.ready = False + C.__bases__ = (B2,) + return type.mro(cls) + + class A(metaclass=M): + pass + class B1(A): + pass + class B2(A): + pass + class C(A): + pass + + self.ready = True + C.__bases__ = (B1,) + B1.__bases__ = (C,) + + self.assertEqual(C.__bases__, (B2,)) + self.assertEqual(B2.__subclasses__(), [C]) + self.assertEqual(B1.__subclasses__(), []) + + self.assertEqual(B1.__bases__, (C,)) + self.assertEqual(C.__subclasses__(), [B1]) + + def test_tp_subclasses_cycle_error_return_path(self): + """ + The same as test_tp_subclasses_cycle_in_update_slots, but tests + a code path executed on error (goto bail). + """ + class E(Exception): + pass + class M(DebugHelperMeta): + def mro(cls): + if self.ready and cls.__name__ == 'C': + if C.__bases__ == (B2,): + self.ready = False + else: + C.__bases__ = (B2,) + raise E + return type.mro(cls) + + class A(metaclass=M): + pass + class B1(A): + pass + class B2(A): + pass + class C(A): + pass + + self.ready = True + with self.assertRaises(E): + C.__bases__ = (B1,) + B1.__bases__ = (C,) + + self.assertEqual(C.__bases__, (B2,)) + self.assertEqual(C.__mro__, tuple(type.mro(C))) + + def test_incomplete_extend(self): + """ + Extending an unitialized type with type->tp_mro == NULL must + throw a reasonable TypeError exception, instead of failing + with PyErr_BadInternalCall. + """ + class M(DebugHelperMeta): + def mro(cls): + if cls.__mro__ is None and cls.__name__ != 'X': + with self.assertRaises(TypeError): + class X(cls): + pass + + return type.mro(cls) + + class A(metaclass=M): + pass + + def test_incomplete_super(self): + """ + Attrubute lookup on a super object must be aware that + its target type can be uninitialized (type->tp_mro == NULL). + """ + class M(DebugHelperMeta): + def mro(cls): + if cls.__mro__ is None: + with self.assertRaises(AttributeError): + super(cls, cls).xxx + + return type.mro(cls) + + class A(metaclass=M): + pass + + def test_main(): # Run all local test cases, with PTypesLongInitTest first. support.run_unittest(PTypesLongInitTest, OperatorsTest, ClassPropertiesAndMethods, DictProxyTests, - MiscTests, PicklingTests) + MiscTests, PicklingTests, SharedKeyTests, + MroTest) if __name__ == "__main__": test_main() diff --git a/Lib/test/test_devpoll.py b/Lib/test/test_devpoll.py index 40ebeee5975b..955618ae1557 100644 --- a/Lib/test/test_devpoll.py +++ b/Lib/test/test_devpoll.py @@ -7,12 +7,10 @@ import select import sys import unittest -from test.support import TESTFN, run_unittest +from test.support import TESTFN, run_unittest, cpython_only -try: - select.devpoll -except AttributeError: - raise unittest.SkipTest("select.devpoll not defined") +if not hasattr(select, 'devpoll') : + raise unittest.SkipTest('test works only on Solaris OS family') def find_ready_matching(ready, flag): @@ -120,6 +118,26 @@ def test_fd_non_inheritable(self): self.addCleanup(devpoll.close) self.assertEqual(os.get_inheritable(devpoll.fileno()), False) + def test_events_mask_overflow(self): + pollster = select.devpoll() + w, r = os.pipe() + pollster.register(w) + # Issue #17919 + self.assertRaises(OverflowError, pollster.register, 0, -1) + self.assertRaises(OverflowError, pollster.register, 0, 1 << 64) + self.assertRaises(OverflowError, pollster.modify, 1, -1) + self.assertRaises(OverflowError, pollster.modify, 1, 1 << 64) + + @cpython_only + def test_events_mask_overflow_c_limits(self): + from _testcapi import USHRT_MAX + pollster = select.devpoll() + w, r = os.pipe() + pollster.register(w) + # Issue #17919 + self.assertRaises(OverflowError, pollster.register, 0, USHRT_MAX + 1) + self.assertRaises(OverflowError, pollster.modify, 1, USHRT_MAX + 1) + def test_main(): run_unittest(DevPollTests) diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index a38895945ed5..2488b63474bd 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -837,57 +837,60 @@ class MyDict(dict): self._tracked(MyDict()) def test_iterator_pickling(self): - data = {1:"a", 2:"b", 3:"c"} - it = iter(data) - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(sorted(it), sorted(data)) - - it = pickle.loads(d) - try: - drop = next(it) - except StopIteration: - return - d = pickle.dumps(it) - it = pickle.loads(d) - del data[drop] - self.assertEqual(sorted(it), sorted(data)) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + data = {1:"a", 2:"b", 3:"c"} + it = iter(data) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(sorted(it), sorted(data)) + + it = pickle.loads(d) + try: + drop = next(it) + except StopIteration: + continue + d = pickle.dumps(it, proto) + it = pickle.loads(d) + del data[drop] + self.assertEqual(sorted(it), sorted(data)) def test_itemiterator_pickling(self): - data = {1:"a", 2:"b", 3:"c"} - # dictviews aren't picklable, only their iterators - itorg = iter(data.items()) - d = pickle.dumps(itorg) - it = pickle.loads(d) - # note that the type of type of the unpickled iterator - # is not necessarily the same as the original. It is - # merely an object supporting the iterator protocol, yielding - # the same objects as the original one. - # self.assertEqual(type(itorg), type(it)) - self.assertTrue(isinstance(it, collections.abc.Iterator)) - self.assertEqual(dict(it), data) - - it = pickle.loads(d) - drop = next(it) - d = pickle.dumps(it) - it = pickle.loads(d) - del data[drop[0]] - self.assertEqual(dict(it), data) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + data = {1:"a", 2:"b", 3:"c"} + # dictviews aren't picklable, only their iterators + itorg = iter(data.items()) + d = pickle.dumps(itorg, proto) + it = pickle.loads(d) + # note that the type of type of the unpickled iterator + # is not necessarily the same as the original. It is + # merely an object supporting the iterator protocol, yielding + # the same objects as the original one. + # self.assertEqual(type(itorg), type(it)) + self.assertIsInstance(it, collections.abc.Iterator) + self.assertEqual(dict(it), data) + + it = pickle.loads(d) + drop = next(it) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + del data[drop[0]] + self.assertEqual(dict(it), data) def test_valuesiterator_pickling(self): - data = {1:"a", 2:"b", 3:"c"} - # data.values() isn't picklable, only its iterator - it = iter(data.values()) - d = pickle.dumps(it) - it = pickle.loads(d) - self.assertEqual(sorted(list(it)), sorted(list(data.values()))) - - it = pickle.loads(d) - drop = next(it) - d = pickle.dumps(it) - it = pickle.loads(d) - values = list(it) + [drop] - self.assertEqual(sorted(values), sorted(list(data.values()))) + for proto in range(pickle.HIGHEST_PROTOCOL): + data = {1:"a", 2:"b", 3:"c"} + # data.values() isn't picklable, only its iterator + it = iter(data.values()) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + self.assertEqual(sorted(list(it)), sorted(list(data.values()))) + + it = pickle.loads(d) + drop = next(it) + d = pickle.dumps(it, proto) + it = pickle.loads(d) + values = list(it) + [drop] + self.assertEqual(sorted(values), sorted(list(data.values()))) def test_instance_dict_getattr_str_subclass(self): class Foo: @@ -906,6 +909,49 @@ class Foo: pass f.a = 'a' self.assertEqual(f.__dict__, {1:1, 'a':'a'}) + def check_reentrant_insertion(self, mutate): + # This object will trigger mutation of the dict when replaced + # by another value. Note this relies on refcounting: the test + # won't achieve its purpose on fully-GCed Python implementations. + class Mutating: + def __del__(self): + mutate(d) + + d = {k: Mutating() for k in 'abcdefghijklmnopqr'} + for k in list(d): + d[k] = k + + def test_reentrant_insertion(self): + # Reentrant insertion shouldn't crash (see issue #22653) + def mutate(d): + d['b'] = 5 + self.check_reentrant_insertion(mutate) + + def mutate(d): + d.update(self.__dict__) + d.clear() + self.check_reentrant_insertion(mutate) + + def mutate(d): + while d: + d.popitem() + self.check_reentrant_insertion(mutate) + + def test_merge_and_mutate(self): + class X: + def __hash__(self): + return 0 + + def __eq__(self, o): + other.clear() + return False + + l = [(i,0) for i in range(1, 1337)] + other = dict(l) + other[X()] = 0 + d = {X(): 0, 1: 1} + self.assertRaises(RuntimeError, d.update, other) + from test import mapping_tests class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol): @@ -917,12 +963,5 @@ class Dict(dict): class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol): type2test = Dict -def test_main(): - support.run_unittest( - DictTest, - GeneralMappingTests, - SubclassMappingTests, - ) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_dictviews.py b/Lib/test/test_dictviews.py index 7b02ea9eba31..fcb6814b5420 100644 --- a/Lib/test/test_dictviews.py +++ b/Lib/test/test_dictviews.py @@ -1,5 +1,5 @@ +import collections import unittest -from test import support class DictSetTest(unittest.TestCase): @@ -196,11 +196,29 @@ def test_items_set_operations(self): def test_recursive_repr(self): d = {} d[42] = d.values() - self.assertRaises(RuntimeError, repr, d) + self.assertRaises(RecursionError, repr, d) + def test_abc_registry(self): + d = dict(a=1) + + self.assertIsInstance(d.keys(), collections.KeysView) + self.assertIsInstance(d.keys(), collections.MappingView) + self.assertIsInstance(d.keys(), collections.Set) + self.assertIsInstance(d.keys(), collections.Sized) + self.assertIsInstance(d.keys(), collections.Iterable) + self.assertIsInstance(d.keys(), collections.Container) + + self.assertIsInstance(d.values(), collections.ValuesView) + self.assertIsInstance(d.values(), collections.MappingView) + self.assertIsInstance(d.values(), collections.Sized) + + self.assertIsInstance(d.items(), collections.ItemsView) + self.assertIsInstance(d.items(), collections.MappingView) + self.assertIsInstance(d.items(), collections.Set) + self.assertIsInstance(d.items(), collections.Sized) + self.assertIsInstance(d.items(), collections.Iterable) + self.assertIsInstance(d.items(), collections.Container) -def test_main(): - support.run_unittest(DictSetTest) if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_difflib.py b/Lib/test/test_difflib.py index 325449aa557c..ab9debf8e252 100644 --- a/Lib/test/test_difflib.py +++ b/Lib/test/test_difflib.py @@ -76,6 +76,15 @@ def test_comparing_empty_lists(self): diff_gen = difflib.unified_diff([], []) self.assertRaises(StopIteration, next, diff_gen) + def test_matching_blocks_cache(self): + # Issue #21635 + s = difflib.SequenceMatcher(None, "abxcd", "abcd") + first = s.get_matching_blocks() + second = s.get_matching_blocks() + self.assertEqual(second[0].size, 2) + self.assertEqual(second[1].size, 2) + self.assertEqual(second[2].size, 0) + def test_added_tab_hint(self): # Check fix for bug #1488943 diff = list(difflib.Differ().compare(["\tI am a buggy"],["\t\tI am a bug"])) @@ -98,6 +107,20 @@ def test_added_tab_hint(self): 5. Flat is better than nested. """ +patch914575_nonascii_from1 = """ + 1. Beautiful is beTTer than ugly. + 2. Explicit is better than ımplıcıt. + 3. Simple is better than complex. + 4. Complex is better than complicated. +""" + +patch914575_nonascii_to1 = """ + 1. Beautiful is better than ügly. + 3. Sımple is better than complex. + 4. Complicated is better than cömplex. + 5. Flat is better than nested. +""" + patch914575_from2 = """ \t\tLine 1: preceeded by from:[tt] to:[ssss] \t\tLine 2: preceeded by from:[sstt] to:[sssst] @@ -214,6 +237,27 @@ def test_recursion_limit(self): new = [(i%2 and "K:%d" or "V:B:%d") % i for i in range(limit*2)] difflib.SequenceMatcher(None, old, new).get_opcodes() + def test_make_file_default_charset(self): + html_diff = difflib.HtmlDiff() + output = html_diff.make_file(patch914575_from1.splitlines(), + patch914575_to1.splitlines()) + self.assertIn('content="text/html; charset=utf-8"', output) + + def test_make_file_iso88591_charset(self): + html_diff = difflib.HtmlDiff() + output = html_diff.make_file(patch914575_from1.splitlines(), + patch914575_to1.splitlines(), + charset='iso-8859-1') + self.assertIn('content="text/html; charset=iso-8859-1"', output) + + def test_make_file_usascii_charset_with_nonascii_input(self): + html_diff = difflib.HtmlDiff() + output = html_diff.make_file(patch914575_nonascii_from1.splitlines(), + patch914575_nonascii_to1.splitlines(), + charset='us-ascii') + self.assertIn('content="text/html; charset=us-ascii"', output) + self.assertIn('ımplıcıt', output) + class TestOutputFormat(unittest.TestCase): def test_tab_delimiter(self): @@ -278,12 +322,157 @@ def test_range_format_context(self): self.assertEqual(fmt(0,0), '0') +class TestBytes(unittest.TestCase): + # don't really care about the content of the output, just the fact + # that it's bytes and we don't crash + def check(self, diff): + diff = list(diff) # trigger exceptions first + for line in diff: + self.assertIsInstance( + line, bytes, + "all lines of diff should be bytes, but got: %r" % line) + + def test_byte_content(self): + # if we receive byte strings, we return byte strings + a = [b'hello', b'andr\xe9'] # iso-8859-1 bytes + b = [b'hello', b'andr\xc3\xa9'] # utf-8 bytes + + unified = difflib.unified_diff + context = difflib.context_diff + + check = self.check + check(difflib.diff_bytes(unified, a, a)) + check(difflib.diff_bytes(unified, a, b)) + + # now with filenames (content and filenames are all bytes!) + check(difflib.diff_bytes(unified, a, a, b'a', b'a')) + check(difflib.diff_bytes(unified, a, b, b'a', b'b')) + + # and with filenames and dates + check(difflib.diff_bytes(unified, a, a, b'a', b'a', b'2005', b'2013')) + check(difflib.diff_bytes(unified, a, b, b'a', b'b', b'2005', b'2013')) + + # same all over again, with context diff + check(difflib.diff_bytes(context, a, a)) + check(difflib.diff_bytes(context, a, b)) + check(difflib.diff_bytes(context, a, a, b'a', b'a')) + check(difflib.diff_bytes(context, a, b, b'a', b'b')) + check(difflib.diff_bytes(context, a, a, b'a', b'a', b'2005', b'2013')) + check(difflib.diff_bytes(context, a, b, b'a', b'b', b'2005', b'2013')) + + def test_byte_filenames(self): + # somebody renamed a file from ISO-8859-2 to UTF-8 + fna = b'\xb3odz.txt' # "łodz.txt" + fnb = b'\xc5\x82odz.txt' + + # they transcoded the content at the same time + a = [b'\xa3odz is a city in Poland.'] + b = [b'\xc5\x81odz is a city in Poland.'] + + check = self.check + unified = difflib.unified_diff + context = difflib.context_diff + check(difflib.diff_bytes(unified, a, b, fna, fnb)) + check(difflib.diff_bytes(context, a, b, fna, fnb)) + + def assertDiff(expect, actual): + # do not compare expect and equal as lists, because unittest + # uses difflib to report difference between lists + actual = list(actual) + self.assertEqual(len(expect), len(actual)) + for e, a in zip(expect, actual): + self.assertEqual(e, a) + + expect = [ + b'--- \xb3odz.txt', + b'+++ \xc5\x82odz.txt', + b'@@ -1 +1 @@', + b'-\xa3odz is a city in Poland.', + b'+\xc5\x81odz is a city in Poland.', + ] + actual = difflib.diff_bytes(unified, a, b, fna, fnb, lineterm=b'') + assertDiff(expect, actual) + + # with dates (plain ASCII) + datea = b'2005-03-18' + dateb = b'2005-03-19' + check(difflib.diff_bytes(unified, a, b, fna, fnb, datea, dateb)) + check(difflib.diff_bytes(context, a, b, fna, fnb, datea, dateb)) + + expect = [ + # note the mixed encodings here: this is deeply wrong by every + # tenet of Unicode, but it doesn't crash, it's parseable by + # patch, and it's how UNIX(tm) diff behaves + b'--- \xb3odz.txt\t2005-03-18', + b'+++ \xc5\x82odz.txt\t2005-03-19', + b'@@ -1 +1 @@', + b'-\xa3odz is a city in Poland.', + b'+\xc5\x81odz is a city in Poland.', + ] + actual = difflib.diff_bytes(unified, a, b, fna, fnb, datea, dateb, + lineterm=b'') + assertDiff(expect, actual) + + def test_mixed_types_content(self): + # type of input content must be consistent: all str or all bytes + a = [b'hello'] + b = ['hello'] + + unified = difflib.unified_diff + context = difflib.context_diff + + expect = "lines to compare must be str, not bytes (b'hello')" + self._assert_type_error(expect, unified, a, b) + self._assert_type_error(expect, unified, b, a) + self._assert_type_error(expect, context, a, b) + self._assert_type_error(expect, context, b, a) + + expect = "all arguments must be bytes, not str ('hello')" + self._assert_type_error(expect, difflib.diff_bytes, unified, a, b) + self._assert_type_error(expect, difflib.diff_bytes, unified, b, a) + self._assert_type_error(expect, difflib.diff_bytes, context, a, b) + self._assert_type_error(expect, difflib.diff_bytes, context, b, a) + + def test_mixed_types_filenames(self): + # cannot pass filenames as bytes if content is str (this may not be + # the right behaviour, but at least the test demonstrates how + # things work) + a = ['hello\n'] + b = ['ohell\n'] + fna = b'ol\xe9.txt' # filename transcoded from ISO-8859-1 + fnb = b'ol\xc3a9.txt' # to UTF-8 + self._assert_type_error( + "all arguments must be str, not: b'ol\\xe9.txt'", + difflib.unified_diff, a, b, fna, fnb) + + def test_mixed_types_dates(self): + # type of dates must be consistent with type of contents + a = [b'foo\n'] + b = [b'bar\n'] + datea = '1 fév' + dateb = '3 fév' + self._assert_type_error( + "all arguments must be bytes, not str ('1 fév')", + difflib.diff_bytes, difflib.unified_diff, + a, b, b'a', b'b', datea, dateb) + + # if input is str, non-ASCII dates are fine + a = ['foo\n'] + b = ['bar\n'] + list(difflib.unified_diff(a, b, 'a', 'b', datea, dateb)) + + def _assert_type_error(self, msg, generator, *args): + with self.assertRaises(TypeError) as ctx: + list(generator(*args)) + self.assertEqual(msg, str(ctx.exception)) + + def test_main(): difflib.HtmlDiff._default_prefix = 0 Doctests = doctest.DocTestSuite(difflib) run_unittest( TestWithAscii, TestAutojunk, TestSFpatches, TestSFbugs, - TestOutputFormat, Doctests) + TestOutputFormat, TestBytes, Doctests) if __name__ == '__main__': test_main() diff --git a/Lib/test/test_difflib_expect.html b/Lib/test/test_difflib_expect.html index 71b6d7a8620d..ea7a24ef4beb 100644 --- a/Lib/test/test_difflib_expect.html +++ b/Lib/test/test_difflib_expect.html @@ -6,7 +6,7 @@ + content="text/html; charset=utf-8" /> ``. +- Issue #15528: Add weakref.finalize to support finalization using + weakref callbacks. -- Issue #10817: Fix urlretrieve function to raise ContentTooShortError even - when reporthook is None. Patch by Jyrki Pulliainen. +- Issue #14173: Avoid crashing when reading a signal handler during + interpreter shutdown. -- Fix the xmlrpc.client user agent to return something similar to - urllib.request user agent: "Python-xmlrpc/3.3". +- Issue #15902: Fix imp.load_module() accepting None as a file when loading an + extension module. -- Issue #13293: Better error message when trying to marshal bytes using - xmlrpc.client. +- Issue #13721: SSLSocket.getpeercert() and SSLSocket.do_handshake() now + raise an OSError with ENOTCONN, instead of an AttributeError, when the + SSLSocket is not connected. -- Issue #13291: NameError in xmlrpc package. +- Issue #14679: add an __all__ (that contains only HTMLParser) to html.parser. -- Issue #13258: Use callable() built-in in the standard library. +- Issue #17802: Fix an UnboundLocalError in html.parser. Initial tests by + Thomas Barlow. -- Issue #13273: fix a bug that prevented HTMLParser to properly detect some - tags when strict=False. +- Issue #17358: Modules loaded by imp.load_source() and load_compiled() (and by + extention load_module()) now have a better chance of working when reloaded. -- Issue #11183: Add finer-grained exceptions to the ssl module, so that - you don't have to inspect the exception's attributes in the common case. +- Issue #17804: New function ``struct.iter_unpack`` allows for streaming + struct unpacking. -- Issue #13216: Add cp65001 codec, the Windows UTF-8 (CP_UTF8). +- Issue #17830: When keyword.py is used to update a keyword file, it now + preserves the line endings of the original file. -- Issue #13226: Add RTLD_xxx constants to the os module. These constants can be - used with sys.setdlopenflags(). +- Issue #17272: Making the urllib.request's Request.full_url a descriptor. + Fixes bugs with assignment to full_url. Patch by Demian Brecht. -- Issue #10278: Add clock_getres(), clock_gettime() and CLOCK_xxx constants to - the time module. time.clock_gettime(time.CLOCK_MONOTONIC) provides a - monotonic clock +- Issue #17353: Plistlib emitted empty data tags with deeply nested datastructures -- Issue #10332: multiprocessing: fix a race condition when a Pool is closed - before all tasks have completed. +- Issue #11714: Use 'with' statements to assure a Semaphore releases a + condition variable. Original patch by Thomas Rachel. -- Issue #13255: wrong docstrings in array module. +- Issue #16624: `subprocess.check_output` now accepts an `input` argument, + allowing the subprocess's stdin to be provided as a (byte) string. + Patch by Zack Weinberg. -- Issue #8540: Remove deprecated Context._clamp attribute in Decimal module. +- Issue #17795: Reverted backwards-incompatible change in SysLogHandler with + Unix domain sockets. -- Issue #13235: Added DeprecationWarning to logging.warn() method and function. +- Issue #16694: Add a pure Python implementation of the operator module. + Patch by Zachary Ware. -- Issue #9168: now smtpd is able to bind privileged port. +- Issue #11182: remove the unused and undocumented pydoc.Scanner class. + Patch by Martin Morrison. -- Issue #12529: fix cgi.parse_header issue on strings with double-quotes and - semicolons together. Patch by Ben Darnell and Petri Lehtinen. +- Issue #17741: Add ElementTree.XMLPullParser, an event-driven parser for + non-blocking applications. -- Issue #13227: functools.lru_cache() now has a option to distinguish - calls with different argument types. +- Issue #17555: Fix ForkAwareThreadLock so that size of after fork + registry does not grow exponentially with generation of process. -- Issue #6090: zipfile raises a ValueError when a document with a timestamp - earlier than 1980 is provided. Patch contributed by Petri Lehtinen. +- Issue #17707: fix regression in multiprocessing.Queue's get() method where + it did not block for short timeouts. -- Issue #13150: sysconfig no longer parses the Makefile and config.h files - when imported, instead doing it at build time. This makes importing - sysconfig faster and reduces Python startup time by 20%. +- Issue #17720: Fix the Python implementation of pickle.Unpickler to correctly + process the APPENDS opcode when it is used on non-list objects. -- Issue #12448: smtplib now flushes stdout while running ``python -m smtplib`` - in order to display the prompt correctly. +- Issue #17012: shutil.which() no longer falls back to the PATH environment + variable if an empty path argument is specified. Patch by Serhiy Storchaka. -- Issue #12454: The mailbox module is now using ASCII, instead of the locale - encoding, to read and write .mh_sequences files. +- Issue #17710: Fix pickle raising a SystemError on bogus input. -- Issue #13194: zlib.compressobj().copy() and zlib.decompressobj().copy() are - now available on Windows. +- Issue #17341: Include the invalid name in the error messages from re about + invalid group names. -- Issue #1673007: urllib.request now supports HEAD request via new method argument. - Patch contributions by David Stanek, Patrick Westerhoff and Ezio Melotti. +- Issue #17702: os.environ now raises KeyError with the original environment + variable name (str on UNIX), instead of using the encoded name (bytes on + UNIX). -- Issue #12386: packaging does not fail anymore when writing the RESOURCES - file. +- Issue #16163: Make the importlib based version of pkgutil.iter_importers + work for submodules. Initial patch by Berker Peksag. -- Issue #13158: Fix decoding and encoding of GNU tar specific base-256 number - fields in tarfile. +- Issue #16804: Fix a bug in the 'site' module that caused running + 'python -S -m site' to incorrectly throw an exception. -- Issue #13025: mimetypes is now reading MIME types using the UTF-8 encoding, - instead of the locale encoding. +- Issue #15480: Remove the deprecated and unused TYPE_INT64 code from marshal. + Initial patch by Daniel Riti. -- Issue #10653: On Windows, use strftime() instead of wcsftime() because - wcsftime() doesn't format time zone correctly. +- Issue #2118: SMTPException is now a subclass of OSError. -- Issue #13150: The tokenize module doesn't compile large regular expressions - at startup anymore. +- Issue #17016: Get rid of possible pointer wraparounds and integer overflows + in the re module. Patch by Nickolai Zeldovich. -- Issue #11171: Fix distutils.sysconfig.get_makefile_filename when Python was - configured with different prefix and exec-prefix. +- Issue #16658: add missing return to HTTPConnection.send() + Patch by Jeff Knupp. -- Issue #11254: Teach distutils and packaging to compile .pyc and .pyo files in - PEP 3147-compliant __pycache__ directories. +- Issue #9556: the logging package now allows specifying a time-of-day for a + TimedRotatingFileHandler to rotate. -- Issue #7367: Fix pkgutil.walk_paths to skip directories whose - contents cannot be read. +- Issue #14971: unittest test discovery no longer gets confused when a function + has a different __name__ than its name in the TestCase class dictionary. -- Issue #3163: The struct module gets new format characters 'n' and 'N' - supporting C integer types ``ssize_t`` and ``size_t``, respectively. +- Issue #17487: The wave getparams method now returns a namedtuple rather than + a plain tuple. -- Issue #13099: Fix sqlite3.Cursor.lastrowid under a Turkish locale. - Reported and diagnosed by Thomas Kluyver. +- Issue #17675: socket repr() provides local and remote addresses (if any). + Patch by Giampaolo Rodola' -- Issue #13087: BufferedReader.seek() now always raises UnsupportedOperation - if the underlying raw stream is unseekable, even if the seek could be - satisfied using the internal buffer. Patch by John O'Connor. +- Issue #17093: Make the ABCs in importlib.abc provide default values or raise + reasonable exceptions for their methods to make them more amenable to super() + calls. -- Issue #7689: Allow pickling of dynamically created classes when their - metaclass is registered with copyreg. Patch by Nicolas M. Thiéry and Craig - Citro. +- Issue #17566: Make importlib.abc.Loader.module_repr() optional instead of an + abstractmethod; now it raises NotImplementedError so as to be ignored by default. -- Issue #13034: When decoding some SSL certificates, the subjectAltName - extension could be unreported. +- Issue #17678: Remove the use of deprecated method in http/cookiejar.py by + changing the call to get_origin_req_host() to origin_req_host. -- Issue #12306: Expose the runtime version of the zlib C library as a constant, - ZLIB_RUNTIME_VERSION, in the zlib module. Patch by Torsten Landschoff. +- Issue #17666: Fix reading gzip files with an extra field. -- Issue #12959: Add collections.ChainMap to collections.__all__. +- Issue #16475: Support object instancing, recursion and interned strings + in marshal -- Issue #8933: distutils' PKG-INFO files and packaging's METADATA files will - now correctly report Metadata-Version: 1.1 instead of 1.0 if a Classifier or - Download-URL field is present. +- Issue #17502: Process DEFAULT values in mock side_effect that returns iterator. -- Issue #12567: Add curses.unget_wch() function. Push a character so the next - get_wch() will return it. +- Issue #16795: On the ast.arguments object, unify vararg with varargannotation + and kwarg and kwargannotation. Change the column offset of ast.Attribute to be + at the attribute name. -- Issue #9561: distutils and packaging now writes egg-info files using UTF-8, - instead of the locale encoding. +- Issue #17434: Properly raise a SyntaxError when a string occurs between future + imports. -- Issue #8286: The distutils command sdist will print a warning message instead - of crashing when an invalid path is given in the manifest template. +- Issue #17117: Import and @importlib.util.set_loader now set __loader__ when + it has a value of None or the attribute doesn't exist. -- Issue #12841: tarfile unnecessarily checked the existence of numerical user - and group ids on extraction. If one of them did not exist the respective id - of the current user (i.e. root) was used for the file and ownership - information was lost. +- Issue #17032: The "global" in the "NameError: global name 'x' is not defined" + error message has been removed. Patch by Ram Rachum. -- Issue #12888: Fix a bug in HTMLParser.unescape that prevented it to escape - more than 128 entities. Patch by Peter Otten. +- Issue #18080: When building a C extension module on OS X, if the compiler + is overriden with the CC environment variable, use the new compiler as + the default for linking if LDSHARED is not also overriden. This restores + Distutils behavior introduced in 3.2.3 and inadvertently dropped in 3.3.0. -- Issue #12878: Expose a __dict__ attribute on io.IOBase and its subclasses. +- Issue #18113: Fixed a refcount leak in the curses.panel module's + set_userptr() method. Reported by Atsuo Ishimoto. -- Issue #12494: On error, call(), check_call(), check_output() and - getstatusoutput() functions of the subprocess module now kill the process, - read its status (to avoid zombis) and close pipes. +- Implement PEP 443 "Single-dispatch generic functions". -- Issue #12720: Expose low-level Linux extended file attribute functions in os. +- Implement PEP 435 "Adding an Enum type to the Python standard library". -- Issue #10946: The distutils commands bdist_dumb, bdist_wininst and bdist_msi - now respect a --skip-build option given to bdist. The packaging commands - were fixed too. +- Issue #15596: Faster pickling of unicode strings. -- Issue #12847: Fix a crash with negative PUT and LONG_BINPUT arguments in - the C pickle implementation. +- Issue #17572: Avoid chained exceptions when passing bad directives to + time.strptime(). Initial patch by Claudiu Popa. -- Issue #11564: Avoid crashes when trying to pickle huge objects or containers - (more than 2**31 items). Instead, in most cases, an OverflowError is raised. +- Issue #17435: threading.Timer's __init__ method no longer uses mutable + default values for the args and kwargs parameters. -- Issue #12287: Fix a stack corruption in ossaudiodev module when the FD is - greater than FD_SETSIZE. +- Issue #17526: fix an IndexError raised while passing code without filename to + inspect.findsource(). Initial patch by Tyler Doyle. -- Issue #12839: Fix crash in zlib module due to version mismatch. - Fix by Richard M. Tew. +- Issue #17540: Added style parameter to logging formatter configuration by dict. -- Issue #9923: The mailcap module now correctly uses the platform path - separator for the MAILCAP environment variable on non-POSIX platforms. +- Issue #16692: The ssl module now supports TLS 1.1 and TLS 1.2. Initial + patch by Michele Orrù. -- Issue #12835: Follow up to #6560 that unconditionally prevents use of the - unencrypted sendmsg/recvmsg APIs on SSL wrapped sockets. Patch by David - Watson. +- Issue #17025: multiprocessing: Reduce Queue and SimpleQueue contention. -- Issue #12803: SSLContext.load_cert_chain() now accepts a password argument - to be used if the private key is encrypted. Patch by Adam Simpkins. +- Issue #17536: Add to webbrowser's browser list: www-browser, x-www-browser, + iceweasel, iceape. -- Issue #11657: Fix sending file descriptors over 255 over a multiprocessing - Pipe. +- Issue #17150: pprint now uses line continuations to wrap long string + literals. -- Issue #12811: tabnanny.check() now promptly closes checked files. Patch by - Anthony Briggs. +- Issue #17488: Change the subprocess.Popen bufsize parameter default value + from unbuffered (0) to buffering (-1) to match the behavior existing code + expects and match the behavior of the subprocess module in Python 2 to avoid + introducing hard to track down bugs. -- Issue #6560: The sendmsg/recvmsg API is now exposed by the socket module - when provided by the underlying platform, supporting processing of - ancillary data in pure Python code. Patch by David Watson and Heiko Wundram. +- Issue #17521: Corrected non-enabling of logger following two calls to + fileConfig(). -- Issue #12326: On Linux, sys.platform doesn't contain the major version - anymore. It is now always 'linux', instead of 'linux2' or 'linux3' depending - on the Linux version used to build Python. +- Issue #17508: Corrected logging MemoryHandler configuration in dictConfig() + where the target handler wasn't configured first. -- Issue #12213: Fix a buffering bug with interleaved reads and writes that - could appear on BufferedRandom streams. +- Issue #17209: curses.window.get_wch() now correctly handles KeyboardInterrupt + (CTRL+c). -- Issue #12778: Reduce memory consumption when JSON-encoding a large - container of many small objects. +- Issue #5713: smtplib now handles 421 (closing connection) error codes when + sending mail by closing the socket and reporting the 421 error code via the + exception appropriate to the command that received the error response. -- Issue #12650: Fix a race condition where a subprocess.Popen could leak - resources (FD/zombie) when killed at the wrong time. +- Issue #16997: unittest.TestCase now provides a subTest() context manager + to procedurally generate, in an easy way, small test instances. -- Issue #12744: Fix inefficient representation of integers between 2**31 and - 2**63 on systems with a 64-bit C "long". +- Issue #17485: Also delete the Request Content-Length header if the data + attribute is deleted. (Follow on to issue Issue #16464). -- Issue #12646: Add an 'eof' attribute to zlib.Decompress, to make it easier to - detect truncated input streams. +- Issue #15927: CVS now correctly parses escaped newlines and carriage + when parsing with quoting turned off. -- Issue #11513: Fix exception handling ``tarfile.TarFile.gzopen()`` when - the file cannot be opened. +- Issue #17467: add readline and readlines support to mock_open in + unittest.mock. -- Issue #12687: Fix a possible buffering bug when unpickling text mode - (protocol 0, mostly) pickles. +- Issue #13248: removed deprecated and undocumented difflib.isbjunk, + isbpopular. -- Issue #10087: Fix the html output format of the calendar module. +- Issue #17192: Update the ctypes module's libffi to v3.0.13. This + specifically addresses a stack misalignment issue on x86 and issues on + some more recent platforms. -- Issue #13121: add support for inplace math operators to collections.Counter. +- Issue #8862: Fixed curses cleanup when getkey is interrputed by a signal. -- Add support for unary plus and unary minus to collections.Counter. +- Issue #17443: imaplib.IMAP4_stream was using the default unbuffered IO + in subprocess, but the imap code assumes buffered IO. In Python2 this + worked by accident. IMAP4_stream now explicitly uses buffered IO. -- Issue #12683: urlparse updated to include svn as schemes that uses relative - paths. (svn from 1.5 onwards support relative path). +- Issue #17476: Fixed regression relative to Python2 in undocumented pydoc + 'allmethods'; it was missing unbound methods on the class. -- Issue #12655: Expose functions from sched.h in the os module: sched_yield(), - sched_setscheduler(), sched_getscheduler(), sched_setparam(), - sched_get_min_priority(), sched_get_max_priority(), sched_rr_get_interval(), - sched_getaffinity(), sched_setaffinity(). +- Issue #17474: Remove the deprecated methods of Request class. -- Add ThreadError to threading.__all__. +- Issue #16709: unittest discover order is no-longer filesystem specific. Patch + by Jeff Ramnani. -- Issues #11104, #8688: Fix the behavior of distutils' sdist command with - manually-maintained MANIFEST files. +- Use the HTTPS PyPI url for upload, overriding any plain HTTP URL in pypirc. -- Issue #11281: smtplib.STMP gets source_address parameter, which adds the - ability to bind to specific source address on a machine with multiple - interfaces. Patch by Paulo Scardine. +- Issue #5024: sndhdr.whichhdr now returns the frame count for WAV files + rather than -1. -- Issue #12464: tempfile.TemporaryDirectory.cleanup() should not follow - symlinks: fix it. Patch by Petri Lehtinen. +- Issue #17460: Remove the strict argument of HTTPConnection and removing the + DeprecationWarning being issued from 3.2 onwards. -- Issue #8887: "pydoc somebuiltin.somemethod" (or help('somebuiltin.somemethod') - in Python code) now finds the doc of the method. +- Issue #16880: Do not assume _imp.load_dynamic() is defined in the imp module. -- Issue #10968: Remove indirection in threading. The public names (Event, - Condition, etc.) used to be factory functions returning instances of hidden - classes (_Event, _Condition, etc.), because (if Guido recalls correctly) this - code pre-dates the ability to subclass extension types. It is now possible - to inherit from these classes, without having to import the private - underscored names like multiprocessing did. +- Issue #16389: Fixed a performance regression relative to Python 3.1 in the + caching of compiled regular expressions. -- Issue #9723: Add shlex.quote functions, to escape filenames and command - lines. +- Added missing FeedParser and BytesFeedParser to email.parser.__all__. -- Issue #12603: Fix pydoc.synopsis() on files with non-negative st_mtime. +- Issue #17431: Fix missing import of BytesFeedParser in email.parser. -- Issue #12514: Use try/finally to assure the timeit module restores garbage - collections when it is done. +- Issue #12921: http.server's send_error takes an explain argument to send more + information in response. Patch contributed by Karl. -- Issue #12607: In subprocess, fix issue where if stdin, stdout or stderr is - given as a low fd, it gets overwritten. +- Issue #17414: Add timeit, repeat, and default_timer to timeit.__all__. -- Issue #12576: Fix urlopen behavior on sites which do not send (or obfuscates) - ``Connection: close`` header. +- Issue #1285086: Get rid of the refcounting hack and speed up + urllib.parse.unquote() and urllib.parse.unquote_to_bytes(). -- Issue #12560: Build libpython.so on OpenBSD. Patch by Stefan Sperling. +- Issue #17099: Have importlib.find_loader() raise ValueError when __loader__ + is not set, harmonizing with what happens when the attribute is set to None. -- Issue #1813: Fix codec lookup under Turkish locales. +- Expose the O_PATH constant in the os module if it is available. -- Issue #12591: Improve support of "universal newlines" in the subprocess - module: the piped streams can now be properly read from or written to. +- Issue #17368: Fix an off-by-one error in the Python JSON decoder that caused + a failure while decoding empty object literals when object_pairs_hook was + specified. -- Issue #12591: Allow io.TextIOWrapper to work with raw IO objects (without - a read1() method), and add a *write_through* parameter to mandate - unbuffered writes. +- Issue #17385: Fix quadratic behavior in threading.Condition. The FIFO + queue now uses a deque instead of a list. -- Issue #10883: Fix socket leaks in urllib.request when using FTP. +- Issue #15806: Add contextlib.ignore(). This creates a context manager to + ignore specified exceptions, replacing the "except SomeException: pass" idiom. -- Issue #12592: Make Python build on OpenBSD 5 (and future major releases). +- Issue #14645: The email generator classes now produce output using the + specified linesep throughout. Previously if the prolog, epilog, or + body were stored with a different linesep, that linesep was used. This + fix corrects an RFC non-compliance issue with smtplib.send_message. -- Issue #12372: POSIX semaphores are broken on AIX: don't use them. +- Issue #17278: Fix a crash in heapq.heappush() and heapq.heappop() when + the list is being resized concurrently. -- Issue #12551: Provide a get_channel_binding() method on SSL sockets so as - to get channel binding data for the current SSL session (only the - "tls-unique" channel binding is implemented). This allows the implementation - of certain authentication mechanisms such as SCRAM-SHA-1-PLUS. Patch by - Jacek Konieczny. +- Issue #16962: Use getdents64 instead of the obsolete getdents syscall + in the subprocess module on Linux. -- Issue #665194: email.utils now has format_datetime and parsedate_to_datetime - functions, allowing for round tripping of RFC2822 format dates. +- Issue #16935: unittest now counts the module as skipped if it raises SkipTest, + instead of counting it as an error. Patch by Zachary Ware. -- Issue #12571: Add a plat-linux3 directory mirroring the plat-linux2 - directory, so that "import DLFCN" and other similar imports work on - Linux 3.0. +- Issue #17018: Make Process.join() retry if os.waitpid() fails with EINTR. -- Issue #7484: smtplib no longer puts <> around addresses in VRFY and EXPN - commands; they aren't required and in fact postfix doesn't support that form. +- Issue #17223: array module: Fix a crasher when converting an array containing + invalid characters (outside range [U+0000; U+10ffff]) to Unicode: + repr(array), str(array) and array.tounicode(). Patch written by Manuel Jacob. -- Issue #12273: Remove ast.__version__. AST changes can be accounted for by - checking sys.version_info or sys._mercurial. +- Issue #17197: profile/cProfile modules refactored so that code of run() and + runctx() utility functions is not duplicated in both modules. -- Silence spurious "broken pipe" tracebacks when shutting down a - ProcessPoolExecutor. +- Issue #14720: sqlite3: Convert datetime microseconds correctly. + Patch by Lowe Thiderman. -- Fix potential resource leaks in concurrent.futures.ProcessPoolExecutor - by joining all queues and processes when shutdown() is called. +- Issue #15132: Allow a list for the defaultTest argument of + unittest.TestProgram. Patch by Jyrki Pulliainen. -- Issue #11603: Fix a crash when __str__ is rebound as __repr__. Patch by - Andreas Stührk. +- Issue #17225: JSON decoder now counts columns in the first line starting + with 1, as in other lines. -- Issue #11321: Fix a crash with multiple imports of the _pickle module when - embedding Python. Patch by Andreas Stührk. +- Issue #6623: Added explicit DeprecationWarning for ftplib.netrc, which has + been deprecated and undocumented for a long time. -- Issue #6755: Add get_wch() method to curses.window class. Patch by Iñigo - Serna. +- Issue #13700: Fix byte/string handling in imaplib authentication when an + authobject is specified. -- Add cgi.closelog() function to close the log file. +- Issue #13153: Tkinter functions now raise TclError instead of ValueError when + a string argument contains non-BMP character. -- Issue #12502: asyncore: fix polling loop with AF_UNIX sockets. +- Issue #9669: Protect re against infinite loops on zero-width matching in + non-greedy repeat. Patch by Matthew Barnett. -- Issue #4376: ctypes now supports nested structures in a endian different than - the parent structure. Patch by Vlad Riscutia. +- Issue #13169: The maximal repetition number in a regular expression has been + increased from 65534 to 2147483647 (on 32-bit platform) or 4294967294 (on + 64-bit). -- Raise ValueError when attempting to set the _CHUNK_SIZE attribute of a - TextIOWrapper to a huge value, not TypeError. +- Issue #17143: Fix a missing import in the trace module. Initial patch by + Berker Peksag. -- Issue #12504: Close file handles in a timely manner in packaging.database. - This fixes a bug with the remove (uninstall) feature on Windows. +- Issue #15220: email.feedparser's line splitting algorithm is now simpler and + faster. -- Issues #12169 and #10510: Factor out code used by various packaging commands - to make HTTP POST requests, and make sure it uses CRLF. +- Issue #16743: Fix mmap overflow check on 32 bit Windows. -- Issue #12016: Multibyte CJK decoders now resynchronize faster. They only - ignore the first byte of an invalid byte sequence. For example, - b'\xff\n'.decode('gb2312', 'replace') gives '\ufffd\n' instead of '\ufffd'. +- Issue #16996: webbrowser module now uses shutil.which() to find a + web-browser on the executable search path. -- Issue #12459: time.sleep() now raises a ValueError if the sleep length is - negative, instead of an infinite sleep on Windows or raising an IOError on - Linux for example, to have the same behaviour on all platforms. +- Issue #16800: tempfile.gettempdir() no longer left temporary files when + the disk is full. Original patch by Amir Szekely. -- Issue #12451: pydoc: html_getfile() now uses tokenize.open() to support - Python scripts using a encoding different than UTF-8 (read the coding cookie - of the script). +- Issue #17192: Import libffi-3.0.12. -- Issue #12493: subprocess: Popen.communicate() now also handles EINTR errors - if the process has only one pipe. +- Issue #16564: Fixed regression relative to Python2 in the operation of + email.encoders.encode_7or8bit when used with binary data. -- Issue #12467: warnings: fix a race condition if a warning is emitted at - shutdown, if globals()['__file__'] is None. +- Issue #17052: unittest discovery should use self.testLoader. -- Issue #12451: pydoc: importfile() now opens the Python script in binary mode, - instead of text mode using the locale encoding, to avoid encoding issues. +- Issue #4591: Uid and gid values larger than 2**31 are supported now. -- Issue #12451: runpy: run_path() now opens the Python script in binary mode, - instead of text mode using the locale encoding, to support other encodings - than UTF-8 (scripts using the coding cookie). +- Issue #17141: random.vonmisesvariate() no longer hangs for large kappas. -- Issue #12451: xml.dom.pulldom: parse() now opens files in binary mode instead - of the text mode (using the locale encoding) to avoid encoding issues. +- Issue #17149: Fix random.vonmisesvariate to always return results in + [0, 2*math.pi]. -- Issue #12147: Adjust the new-in-3.2 smtplib.send_message method for better - conformance to the RFCs: correctly handle Sender and Resent- headers. +- Issue #1470548: XMLGenerator now works with binary output streams. -- Issue #12352: Fix a deadlock in multiprocessing.Heap when a block is freed by - the garbage collector while the Heap lock is held. +- Issue #6975: os.path.realpath() now correctly resolves multiple nested + symlinks on POSIX platforms. -- Issue #12462: time.sleep() now immediately calls the (Python) signal handler - if it is interrupted by a signal, instead of having to wait until the next - instruction. +- Issue #13773: sqlite3.connect() gets a new `uri` parameter to pass the + filename as a URI, allowing to pass custom options. -- Issue #12442: new shutil.disk_usage function, providing total, used and free - disk space statistics. +- Issue #16564: Fixed regression relative to Python2 in the operation of + email.encoders.encode_noop when used with binary data. -- Issue #12451: The XInclude default loader of xml.etree now decodes files from - UTF-8 instead of the locale encoding if the encoding is not specified. It now - also opens XML files for the parser in binary mode instead of the text mode - to avoid encoding issues. +- Issue #10355: The mode, name, encoding and newlines properties now work on + SpooledTemporaryFile objects even when they have not yet rolled over. + Obsolete method xreadline (which has never worked in Python 3) has been + removed. -- Issue #12451: doctest.debug_script() doesn't create a temporary file - anymore to avoid encoding issues. +- Issue #16686: Fixed a lot of bugs in audioop module. Fixed crashes in + avgpp(), maxpp() and ratecv(). Fixed an integer overflow in add(), bias(), + and ratecv(). reverse(), lin2lin() and ratecv() no more lose precision for + 32-bit samples. max() and rms() no more returns a negative result and + various other functions now work correctly with 32-bit sample -0x80000000. -- Issue #12451: pydoc.synopsis() now reads the encoding cookie if available, - to read the Python script from the right encoding. +- Issue #17073: Fix some integer overflows in sqlite3 module. -- Issue #12451: distutils now opens the setup script in binary mode to read the - encoding cookie, instead of opening it in UTF-8. +- Issue #16723: httplib.HTTPResponse no longer marked closed when the connection + is automatically closed. -- Issue #9516: On Mac OS X, change Distutils to no longer globally attempt to - check or set the MACOSX_DEPLOYMENT_TARGET environment variable for the - interpreter process. This could cause failures in non-Distutils subprocesses - and was unreliable since tests or user programs could modify the interpreter - environment after Distutils set it. Instead, have Distutils set the - deployment target only in the environment of each build subprocess. It is - still possible to globally override the default by setting - MACOSX_DEPLOYMENT_TARGET before launching the interpreter; its value must be - greater or equal to the default value, the value with which the interpreter - was built. Also, implement the same handling in packaging. +- Issue #15359: Add CAN_BCM protocol support to the socket module. Patch by + Brian Thorne. -- Issue #12422: In the copy module, don't store objects that are their own copy - in the memo dict. +- Issue #16948: Fix quoted printable body encoding for non-latin1 character + sets in the email package. -- Issue #12303: Add sigwaitinfo() and sigtimedwait() to the signal module. +- Issue #16811: Fix folding of headers with no value in the provisional email + policies. -- Issue #12404: Remove C89 incompatible code from mmap module. Patch by Akira - Kitada. +- Issue #17132: Update symbol for "yield from" grammar changes. -- Issue #1874: email now detects and reports as a defect the presence of - any CTE other than 7bit, 8bit, or binary on a multipart. +- Issue #17076: Make copying of xattrs more tolerant of missing FS support. + Patch by Thomas Wouters. -- Issue #12383: Fix subprocess module with env={}: don't copy the environment - variables, start with an empty environment. +- Issue #17089: Expat parser now correctly works with string input when the + internal XML encoding is not UTF-8 or US-ASCII. It also now accepts bytes + and strings larger than 2 GiB. -- Issue #11637: Fix support for importing packaging setup hooks from the - project directory. +- Issue #6083: Fix multiple segmentation faults occured when PyArg_ParseTuple + parses nested mutating sequence. -- Issue #6771: Moved the curses.wrapper function from the single-function - wrapper module into __init__, eliminating the module. Since __init__ was - already importing the function to curses.wrapper, there is no API change. +- Issue #5289: Fix ctypes.util.find_library on Solaris. -- Issue #11584: email.header.decode_header no longer fails if the header - passed to it is a Header object, and Header/make_header no longer fail - if given binary unknown-8bit input. +- Issue #17106: Fix a segmentation fault in io.TextIOWrapper when an underlying + stream or a decoder produces data of an unexpected type (i.e. when + io.TextIOWrapper initialized with text stream or use bytes-to-bytes codec). -- Issue #11700: mailbox proxy object close methods can now be called multiple - times without error. +- Issue #17015: When it has a spec, a Mock object now inspects its signature + when matching calls, so that arguments can be matched positionally or + by name. -- Issue #11767: Correct file descriptor leak in mailbox's __getitem__ method. +- Issue #15633: httplib.HTTPResponse is now mark closed when the server + sends less than the advertised Content-Length. -- Issue #12133: AbstractHTTPHandler.do_open() of urllib.request closes the HTTP - connection if its getresponse() method fails with a socket error. Patch - written by Ezio Melotti. +- Issue #12268: The io module file object write methods no longer abort early + when one of its write system calls is interrupted (EINTR). -- Issue #12240: Allow multiple setup hooks in packaging's setup.cfg files. - Original patch by Erik Bray. +- Issue #6972: The zipfile module no longer overwrites files outside of + its destination path when extracting malicious zip files. -- Issue #9284: Allow inspect.findsource() to find the source of doctest - functions. +- Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an + incomplete "End of Central Directory" record. Original patch by Guilherme + Polo and Alan McIntyre. -- Issue #11595: Fix assorted bugs in packaging.util.cfg_to_args, a - compatibility helper for the distutils-packaging transition. Original patch - by Erik Bray. +- Issue #17071: Signature.bind() now works when one of the keyword arguments + is named ``self``. -- Issue #12287: In ossaudiodev, check that the device isn't closed in several - methods. +- Issue #12004: Fix an internal error in PyZipFile when writing an invalid + Python file. Patch by Ben Morgan. -- Issue #12009: Fixed regression in netrc file comment handling. +- Have py_compile use importlib as much as possible to avoid code duplication. + Code now raises FileExistsError if the file path to be used for the + byte-compiled file is a symlink or non-regular file as a warning that import + will not keep the file path type if it writes to that path. -- Issue #12246: Warn and fail when trying to install a third-party project from - an uninstalled Python (built in a source checkout). Original patch by - Tshepang Lekhonkhobe. +- Issue #16972: Have site.addpackage() consider already known paths even when + none are explicitly passed in. Bug report and fix by Kirill. -- Issue #10694: zipfile now ignores garbage at the end of a zipfile. +- Issue #1602133: on Mac OS X a shared library build (``--enable-shared``) + now fills the ``os.environ`` variable correctly. -- Issue #12283: Fixed regression in smtplib quoting of leading dots in DATA. +- Issue #15505: `unittest.installHandler` no longer assumes SIGINT handler is + set to a callable object. -- Issue #10424: Argparse now includes the names of the missing required - arguments in the missing arguments error message. +- Issue #13454: Fix a crash when deleting an iterator created by itertools.tee() + if all other iterators were very advanced before. -- Issue #12168: SysLogHandler now allows NUL termination to be controlled using - a new 'append_nul' attribute on the handler. +- Issue #12411: Fix to cgi.parse_multipart to correctly use bytes boundaries + and bytes data. Patch by Jonas Wagner. -- Issue #11583: Speed up os.path.isdir on Windows by using GetFileAttributes - instead of os.stat. +- Issue #16957: shutil.which() no longer searches a bare file name in the + current directory on Unix and no longer searches a relative file path with + a directory part in PATH directories. Patch by Thomas Kluyver. -- Issue #12021: Make mmap's read() method argument optional. Patch by Petri - Lehtinen. +- Issue #1159051: GzipFile now raises EOFError when reading a corrupted file + with truncated header or footer. -- Issue #9205: concurrent.futures.ProcessPoolExecutor now detects killed - children and raises BrokenProcessPool in such a situation. Previously it - would reliably freeze/deadlock. +- Issue #16993: shutil.which() now preserves the case of the path and extension + on Windows. -- Issue #12040: Expose a new attribute ``sentinel`` on instances of - ``multiprocessing.Process``. Also, fix Process.join() to not use polling - anymore, when given a timeout. +- Issue #16992: On Windows in signal.set_wakeup_fd, validate the file + descriptor argument. -- Issue #11893: Remove obsolete internal wrapper class ``SSLFakeFile`` in the - smtplib module. Patch by Catalin Iacob. +- Issue #16422: For compatibility with the Python version, the C version of + decimal now uses strings instead of integers for rounding mode constants. -- Issue #12080: Fix a Decimal.power() case that took an unreasonably long time - to compute. +- Issue #15861: tkinter now correctly works with lists and tuples containing + strings with whitespaces, backslashes or unbalanced braces. -- Issue #12221: Remove __version__ attributes from pyexpat, pickle, tarfile, - pydoc, tkinter, and xml.parsers.expat. This were useless version constants - left over from the Mercurial transition +- Issue #9720: zipfile now writes correct local headers for files larger than + 4 GiB. -- Named tuples now work correctly with vars(). +- Issue #16955: Fix the poll() method for multiprocessing's socket + connections on Windows. -- Issue #12085: Fix an attribute error in subprocess.Popen destructor if the - constructor has failed, e.g. because of an undeclared keyword argument. Patch - written by Oleg Oshmyan. +- SSLContext.load_dh_params() now properly closes the input file. -- Issue #12028: Make threading._get_ident() public, rename it to - threading.get_ident() and document it. This function was already used using - _thread.get_ident(). +- Issue #15031: Refactor some .pyc management code to cut down on code + duplication. Thanks to Ronan Lamy for the report and taking an initial stab + at the problem. -- Issue #12171: IncrementalEncoder.reset() of CJK codecs (multibytecodec) calls - encreset() instead of decreset(). +- Issue #16398: Optimize deque.rotate() so that it only moves pointers + and doesn't touch the underlying data with increfs and decrefs. -- Issue #12218: Removed wsgiref.egg-info. +- Issue #16900: Issue a ResourceWarning when an ssl socket is left unclosed. -- Issue #12196: Add pipe2() to the os module. +- Issue #13899: \A, \Z, and \B now correctly match the A, Z, and B literals + when used inside character classes (e.g. '[\A]'). Patch by Matthew Barnett. -- Issue #985064: Make plistlib more resilient to faulty input plists. - Patch by Mher Movsisyan. +- Issue #15545: Fix regression in sqlite3's iterdump method where it was + failing if the connection used a row factory (such as sqlite3.Row) that + produced unsortable objects. (Regression was introduced by fix for 9750). -- Issue #1625: BZ2File and bz2.decompress() now support multi-stream files. - Initial patch by Nir Aides. +- fcntl: add F_DUPFD_CLOEXEC constant, available on Linux 2.6.24+. -- Issue #12175: BufferedReader.read(-1) now calls raw.readall() if available. +- Issue #15972: Fix error messages when os functions expecting a file name or + file descriptor receive the incorrect type. -- Issue #12175: FileIO.readall() now only reads the file position and size - once. +- Issue #8109: The ssl module now has support for server-side SNI, thanks + to a :meth:`SSLContext.set_servername_callback` method. Patch by Daniel + Black. -- Issue #12175: RawIOBase.readall() now returns None if read() returns None. +- Issue #16860: In tempfile, use O_CLOEXEC when available to set the + close-on-exec flag atomically. -- Issue #12175: FileIO.readall() now raises a ValueError instead of an IOError - if the file is closed. +- Issue #16674: random.getrandbits() is now 20-40% faster for small integers. -- Issue #11109: New service_action method for BaseServer, used by ForkingMixin - class for cleanup. Initial Patch by Justin Warkentin. +- Issue #16009: JSON error messages now provide more information. -- Issue #12045: Avoid duplicate execution of command in - ctypes.util._get_soname(). Patch by Sijin Joseph. +- Issue #16828: Fix error incorrectly raised by bz2.compress(b'') and + bz2.BZ2Compressor.compress(b''). Initial patch by Martin Packman. -- Issue #10818: Remove the Tk GUI and the serve() function of the pydoc module, - pydoc -g has been deprecated in Python 3.2 and it has a new enhanced web - server. +- Issue #16833: In http.client.HTTPConnection, do not concatenate the request + headers and body when the payload exceeds 16 KB, since it can consume more + memory for no benefit. Patch by Benno Leslie. -- Issue #1441530: In imaplib, read the data in one chunk to speed up large - reads and simplify code. +- Issue #16541: tk_setPalette() now works with keyword arguments. -- Issue #12070: Fix the Makefile parser of the sysconfig module to handle - correctly references to "bogus variable" (e.g. "prefix=$/opt/python"). +- Issue #16820: In configparser, `parser.popitem()` no longer raises ValueError. + This makes `parser.clean()` work correctly. -- Issue #12100: Don't reset incremental encoders of CJK codecs at each call to - their encode() method anymore, but continue to call the reset() method if the - final argument is True. +- Issue #16820: In configparser, ``parser['section'] = {}`` now preserves + section order within the parser. This makes `parser.update()` preserve section + order as well. -- Issue #12049: Add RAND_bytes() and RAND_pseudo_bytes() functions to the ssl - module. +- Issue #16820: In configparser, ``parser['DEFAULT'] = {}`` now correctly + clears previous values stored in the default section. Same goes for + ``parser.update({'DEFAULT': {}})``. -- Issue #6501: os.device_encoding() returns None on Windows if the application - has no console. +- Issue #9586: Redefine SEM_FAILED on MacOSX to keep compiler happy. -- Issue #12105: Add O_CLOEXEC to the os module. +- Issue #16787: Increase asyncore and asynchat default output buffers size, to + decrease CPU usage and increase throughput. -- Issue #12079: Decimal('Infinity').fma(Decimal('0'), (3.91224318126786e+19+0j)) - now raises TypeError (reflecting the invalid type of the 3rd argument) rather - than Decimal.InvalidOperation. +- Issue #10527: make multiprocessing use poll() instead of select() if available. -- Issue #12124: zipimport doesn't keep a reference to zlib.decompress() anymore - to be able to unload the module. +- Issue #16688: Now regexes contained backreferences correctly work with + non-ASCII strings. Patch by Matthew Barnett. -- Add the packaging module, an improved fork of distutils (also known as - distutils2). +- Issue #16486: Make aifc files act as context managers. -- Issue #12065: connect_ex() on an SSL socket now returns the original errno - when the socket's timeout expires (it used to return None). +- Issue #16485: Now file descriptors are closed if file header patching failed + on closing an aifc file. -- Issue #8809: The SMTP_SSL constructor and SMTP.starttls() now support - passing a ``context`` argument pointing to an ssl.SSLContext instance. - Patch by Kasun Herath. +- Issue #16640: Run less code under a lock in sched module. -- Issue #9516: Issue #9516: avoid errors in sysconfig when MACOSX_DEPLOYMENT_TARGET - is set in shell. +- Issue #16165: sched.scheduler.run() no longer blocks a scheduler for other + threads. -- Issue #8650: Make zlib module 64-bit clean. compress(), decompress() and - their incremental counterparts now raise OverflowError if given an input - larger than 4GB, instead of silently truncating the input and returning - an incorrect result. +- Issue #16641: Default values of sched.scheduler.enter() are no longer + modifiable. -- Issue #12050: zlib.decompressobj().decompress() now clears the unconsumed_tail - attribute when called without a max_length argument. +- Issue #16618: Make glob.glob match consistently across strings and bytes + regarding leading dots. Patch by Serhiy Storchaka. -- Issue #12062: Fix a flushing bug when doing a certain type of I/O sequence - on a file opened in read+write mode (namely: reading, seeking a bit forward, - writing, then seeking before the previous write but still within buffered - data, and writing again). +- Issue #16788: Add samestat to Lib/ntpath.py -- Issue #9971: Write an optimized implementation of BufferedReader.readinto(). - Patch by John O'Connor. +- Issue #16713: Parsing of 'tel' urls using urlparse separates params from + path. -- Issue #11799: urllib.request Authentication Handlers will raise a ValueError - when presented with an unsupported Authentication Scheme. Patch contributed - by Yuval Greenfield. +- Issue #16443: Add docstrings to regular expression match objects. + Patch by Anton Kasyanov. -- Issue #10419, #6011: build_scripts command of distutils handles correctly - non-ASCII path (path to the Python executable). Open and write the script in - binary mode, but ensure that the shebang is decodable from UTF-8 and from the - encoding of the script. +- Issue #15701: Fix HTTPError info method call to return the headers information. -- Issue #8498: In socket.accept(), allow to specify 0 as a backlog value in - order to accept exactly one connection. Patch by Daniel Evers. +- Issue #16752: Add a missing import to modulefinder. Patch by Berker Peksag. -- Issue #12011: signal.signal() and signal.siginterrupt() raise an OSError, - instead of a RuntimeError: OSError has an errno attribute. +- Issue #16646: ftplib.FTP.makeport() might lose socket error details. + (patch by Serhiy Storchaka) -- Issue #3709: add a flush_headers method to BaseHTTPRequestHandler, which - manages the sending of headers to output stream and flushing the internal - headers buffer. Patch contribution by Andrew Schaaf +- Issue #16626: Fix infinite recursion in glob.glob() on Windows when the + pattern contains a wildcard in the drive or UNC path. Patch by Serhiy + Storchaka. -- Issue #11743: Rewrite multiprocessing connection classes in pure Python. +- Issue #15783: Except for the number methods, the C version of decimal now + supports all None default values present in decimal.py. These values were + largely undocumented. -- Issue #11164: Stop trying to use _xmlplus in the xml module. +- Issue #11175: argparse.FileType now accepts encoding and errors + arguments. Patch by Lucas Maystre. -- Issue #11888: Add log2 function to math module. Patch written by Mark - Dickinson. +- Issue #16488: epoll() objects now support the `with` statement. Patch + by Serhiy Storchaka. -- Issue #12012: ssl.PROTOCOL_SSLv2 becomes optional. +- Issue #16298: In HTTPResponse.read(), close the socket when there is no + Content-Length and the incoming stream is finished. Patch by Eran + Rundstein. -- Issue #8407: The signal handler writes the signal number as a single byte - instead of a nul byte into the wakeup file descriptor. So it is possible to - wait more than one signal and know which signals were raised. +- Issue #16049: Add abc.ABC class to enable the use of inheritance to create + ABCs, rather than the more cumbersome metaclass=ABCMeta. Patch by Bruno + Dupuis. -- Issue #8407: Add pthread_kill(), sigpending() and sigwait() functions to the - signal module. +- Expose the TCP_FASTOPEN and MSG_FASTOPEN flags in socket when they're + available. -- Issue #11927: SMTP_SSL now uses port 465 by default as documented. Patch - by Kasun Herath. +- Issue #15701: Add a .headers attribute to urllib.error.HTTPError. Patch + contributed by Berker Peksag. -- Issue #12002: ftplib's abort() method raises TypeError. +- Issue #15872: Fix 3.3 regression introduced by the new fd-based shutil.rmtree + that caused it to not ignore certain errors when ignore_errors was set. + Patch by Alessandro Moura and Serhiy Storchaka. -- Issue #11916: Add a number of MacOSX specific definitions to the errno module. - Patch by Pierre Carrier. +- Issue #16248: Disable code execution from the user's home directory by + tkinter when the -E flag is passed to Python. Patch by Zachary Ware. -- Issue #11999: fixed sporadic sync failure mailbox.Maildir due to its trying to - detect mtime changes by comparing to the system clock instead of to the - previous value of the mtime. +- Issue #13390: New function :func:`sys.getallocatedblocks()` returns the + number of memory blocks currently allocated. -- Issue #11072: added MLSD command (RFC-3659) support to ftplib. +- Issue #16628: Fix a memory leak in ctypes.resize(). -- Issue #8808: The IMAP4_SSL constructor now allows passing an SSLContext - parameter to control parameters of the secure channel. Patch by Sijin - Joseph. +- Issue #13614: Fix setup.py register failure with invalid rst in description. + Patch by Julien Courteau and Pierre Paul Lefebvre. -- ntpath.samefile failed to notice that "a.txt" and "A.TXT" refer to the same - file on Windows XP. As noticed in issue #10684. +- Issue #13512: Create ~/.pypirc securely (CVE-2011-4944). Initial patch by + Philip Jenvey, tested by Mageia and Debian. -- Issue #12000: When a SSL certificate has a subjectAltName without any - dNSName entry, ssl.match_hostname() should use the subject's commonName. - Patch by Nicolas Bareil. +- Issue #7719: Make distutils ignore ``.nfs*`` files instead of choking later + on. Initial patch by SilentGhost and Jeff Ramnani. -- Issue #10775: assertRaises, assertRaisesRegex, assertWarns, and - assertWarnsRegex now accept a keyword argument 'msg' when used as context - managers. Initial patch by Winston Ewert. +- Issue #13120: Allow to call pdb.set_trace() from thread. + Patch by Ilya Sandler. -- Issue #10684: shutil.move used to delete a folder on case insensitive - filesystems when the source and destination name where the same except - for the case. +- Issue #16585: Make CJK encoders support error handlers that return bytes per + PEP 383. -- Issue #11647: objects created using contextlib.contextmanager now support - more than one call to the function when used as a decorator. Initial patch - by Ysj Ray. +- Issue #10182: The re module doesn't truncate indices to 32 bits anymore. + Patch by Serhiy Storchaka. -- Issue #11930: Removed deprecated time.accept2dyear variable. - Removed year >= 1000 restriction from datetime.strftime. +- Issue #16333: use (",", ": ") as default separator in json when indent is + specified, to avoid trailing whitespace. Patch by Serhiy Storchaka. -- logging: don't define QueueListener if Python has no thread support. +- Issue #16573: In 2to3, treat enumerate() like a consuming call, so superfluous + list() calls aren't added to filter(), map(), and zip() which are directly + passed enumerate(). -- functools.cmp_to_key() now works with collections.Hashable(). +- Issue #16464: Reset the Content-Length header when a urllib Request is reused + with new data. -- Issue #11277: mmap.mmap() calls fcntl(fd, F_FULLFSYNC) on Mac OS X to get - around a mmap bug with sparse files. Patch written by Steffen Daode Nurpmeso. +- Issue #12848: The pure Python pickle implementation now treats object + lengths as unsigned 32-bit integers, like the C implementation does. + Patch by Serhiy Storchaka. -- Issue #8407: Add signal.pthread_sigmask() function to fetch and/or change the - signal mask of the calling thread. +- Issue #16423: urllib.request now has support for ``data:`` URLs. Patch by + Mathias Panzenböck. -- Issue #11858: configparser.ExtendedInterpolation expected lower-case section - names. +- Issue #4473: Add a POP3.stls() to switch a clear-text POP3 session into + an encrypted POP3 session, on supported servers. Patch by Lorenzo Catucci. -- Issue #11324: ConfigParser(interpolation=None) now works correctly. +- Issue #4473: Add a POP3.capa() method to query the capabilities advertised + by the POP3 server. Patch by Lorenzo Catucci. -- Issue #11811: ssl.get_server_certificate() is now IPv6-compatible. Patch - by Charles-François Natali. +- Issue #4473: Ensure the socket is shutdown cleanly in POP3.close(). + Patch by Lorenzo Catucci. -- Issue #11763: don't use difflib in TestCase.assertMultiLineEqual if the - strings are too long. +- Issue #16522: added FAIL_FAST flag to doctest. -- Issue #11236: getpass.getpass responds to ctrl-c or ctrl-z on terminal. +- Issue #15627: Add the importlib.abc.InspectLoader.source_to_code() method. -- Issue #11856: Speed up parsing of JSON numbers. +- Issue #16408: Fix file descriptors not being closed in error conditions + in the zipfile module. Patch by Serhiy Storchaka. -- Issue #11005: threading.RLock()._release_save() raises a RuntimeError if the - lock was not acquired. +- Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak + references to bound methods. -- Issue #11258: Speed up ctypes.util.find_library() under Linux by a factor - of 5 to 10. Initial patch by Jonas H. +- Issue #16469: Fix exceptions from float -> Fraction and Decimal -> Fraction + conversions for special values to be consistent with those for float -> int + and Decimal -> int. Patch by Alexey Kachayev. -- Issue #11382: Trivial system calls, such as dup() or pipe(), needn't - release the GIL. Patch by Charles-François Natali. +- Issue #16481: multiprocessing no longer leaks process handles on Windows. -- Issue #11223: Add threading._info() function providing informations about - the thread implementation. +- Issue #12428: Add a pure Python implementation of functools.partial(). + Patch by Brian Thorne. -- Issue #11731: simplify/enhance email parser/generator API by introducing - policy objects. +- Issue #16140: The subprocess module no longer double closes its child + subprocess.PIPE parent file descriptors on child error prior to exec(). -- Issue #11768: The signal handler of the signal module only calls - Py_AddPendingCall() for the first signal to fix a deadlock on reentrant or - parallel calls. PyErr_SetInterrupt() writes also into the wake up file. +- Remove a bare print to stdout from the subprocess module that could have + happened if the child process wrote garbage to its pre-exec error pipe. -- Issue #11492: fix several issues with header folding in the email package. +- The subprocess module now raises its own SubprocessError instead of a + RuntimeError in various error situations which should not normally happen. -- Issue #11852: Add missing imports and update tests. +- Issue #16327: The subprocess module no longer leaks file descriptors + used for stdin/stdout/stderr pipes to the child when fork() fails. -- Issue #11875: collections.OrderedDict's __reduce__ was temporarily - mutating the object instead of just working on a copy. +- Issue #14396: Handle the odd rare case of waitpid returning 0 when not + expected in subprocess.Popen.wait(). -- Issue #11467: Fix urlparse behavior when handling urls which contains scheme - specific part only digits. Patch by Santoso Wijaya. +- Issue #16411: Fix a bug where zlib.decompressobj().flush() might try to access + previously-freed memory. Patch by Serhiy Storchaka. -- collections.Counter().copy() now works correctly for subclasses. +- Issue #16357: fix calling accept() on a SSLSocket created through + SSLContext.wrap_socket(). Original patch by Jeff McNeil. -- Issue #11474: Fix the bug with url2pathname() handling of '/C|/' on Windows. - Patch by Santoso Wijaya. +- Issue #16409: The reporthook callback made by the legacy + urllib.request.urlretrieve API now properly supplies a constant non-zero + block_size as it did in Python 3.2 and 2.7. This matches the behavior of + urllib.request.URLopener.retrieve. -- Issue #11684: complete email.parser bytes API by adding BytesHeaderParser. +- Issue #16431: Use the type information when constructing a Decimal subtype + from a Decimal argument. -- The bz2 module now handles 4GiB+ input buffers correctly. +- Issue #15641: Clean up deprecated classes from importlib + Patch by Taras Lyapun. -- Issue #9233: Fix json.loads('{}') to return a dict (instead of a list), when - _json is not available. +- Issue #16350: zlib.decompressobj().decompress() now accumulates data from + successive calls after EOF in unused_data, instead of only saving the argument + to the last call. decompressobj().flush() now correctly sets unused_data and + unconsumed_tail. A bug in the handling of MemoryError when setting the + unconsumed_tail attribute has also been fixed. Patch by Serhiy Storchaka. -- Issue #11830: Remove unnecessary introspection code in the decimal module. +- Issue #12759: sre_parse now raises a proper error when the name of the group + is missing. Initial patch by Serhiy Storchaka. -- Issue #11703: urllib2.geturl() does not return correct url when the original - url contains #fragment. +- Issue #16152: fix tokenize to ignore whitespace at the end of the code when + no newline is found. Patch by Ned Batchelder. -- Issue #10019: Fixed regression in json module where an indent of 0 stopped - adding newlines and acted instead like 'None'. +- Issue #16284: Prevent keeping unnecessary references to worker functions + in concurrent.futures ThreadPoolExecutor. -- Issue #11186: pydoc ignores a module if its name contains a surrogate - character in the index of modules. +- Issue #16230: Fix a crash in select.select() when one the lists changes + size while iterated on. Patch by Serhiy Storchaka. -- Issue #11815: Use a light-weight SimpleQueue for the result queue in - concurrent.futures.ProcessPoolExecutor. +- Issue #16228: Fix a crash in the json module where a list changes size + while it is being encoded. Patch by Serhiy Storchaka. -- Issue #5162: Treat services like frozen executables to allow child spawning - from multiprocessing.forking on Windows. +- Issue #16351: New function gc.get_stats() returns per-generation collection + statistics. -- logging.basicConfig now supports an optional 'handlers' argument taking an - iterable of handlers to be added to the root logger. Additional parameter - checks were also added to basicConfig. +- Issue #14897: Enhance error messages of struct.pack and + struct.pack_into. Patch by Matti Mäki. -- Issue #11814: Fix likely typo in multiprocessing.Pool._terminate(). +- Issue #16316: mimetypes now recognizes the .xz and .txz (.tar.xz) extensions. + Patch by Serhiy Storchaka. -- Issue #11747: Fix range formatting in difflib.context_diff() and - difflib.unified_diff(). +- Issue #12890: cgitb no longer prints spurious

tags in text + mode when the logdir option is specified. -- Issue #8428: Fix a race condition in multiprocessing.Pool when terminating - worker processes: new processes would be spawned while the pool is being - shut down. Patch by Charles-François Natali. +- Issue #16307: Fix multiprocessing.Pool.map_async not calling its callbacks. + Patch by Janne Karila. -- Issue #2650: re.escape() no longer escapes the '_'. +- Issue #16305: Fix a segmentation fault occurring when interrupting + math.factorial. -- Issue #11757: select.select() now raises ValueError when a negative timeout - is passed (previously, a select.error with EINVAL would be raised). Patch - by Charles-François Natali. +- Issue #16116: Fix include and library paths to be correct when building C + extensions in venvs. -- Issue #7311: fix html.parser to accept non-ASCII attribute values. +- Issue #16245: Fix the value of a few entities in html.entities.html5. -- Issue #11605: email.parser.BytesFeedParser was incorrectly converting - multipart subparts with an 8-bit CTE into unicode instead of preserving the - bytes. +- Issue #16301: Fix the localhost verification in urllib/request.py for file:// + urls. -- Issue #1690608: email.util.formataddr is now RFC 2047 aware: it now has a - charset parameter that defaults to utf-8 and is used as the charset for RFC - 2047 encoding when the realname contains non-ASCII characters. +- Issue #16250: Fix the invocations of URLError which had misplaced filename + attribute for exception. -- Issue #10963: Ensure that subprocess.communicate() never raises EPIPE. +- Issue #10836: Fix exception raised when file not found in urlretrieve + Initial patch by Ezio Melotti. -- Issue #10791: Implement missing method GzipFile.read1(), allowing GzipFile - to be wrapped in a TextIOWrapper. Patch by Nadeem Vawda. +- Issue #14398: Fix size truncation and overflow bugs in the bz2 module. -- Issue #11707: Added a fast C version of functools.cmp_to_key(). - Patch by Filip Gruszczyński. +- Issue #12692: Fix resource leak in urllib.request when talking to an HTTP + server that does not include a ``Connection: close`` header in its responses. -- Issue #11688: Add sqlite3.Connection.set_trace_callback(). Patch by - Torsten Landschoff. +- Issue #12034: Fix bogus caching of result in check_GetFinalPathNameByHandle. + Patch by Atsuo Ishimoto. -- Issue #11746: Fix SSLContext.load_cert_chain() to accept elliptic curve - private keys. +- Improve performance of `lzma.LZMAFile` (see also issue #16034). -- Issue #5863: Rewrite BZ2File in pure Python, and allow it to accept - file-like objects using a new ``fileobj`` constructor argument. Patch by - Nadeem Vawda. +- Issue #16220: wsgiref now always calls close() on an iterable response. + Patch by Brent Tubbs. -- unittest.TestCase.assertSameElements has been removed. +- Issue #16270: urllib may hang when used for retrieving files via FTP by using + a context manager. Patch by Giampaolo Rodola'. -- sys.getfilesystemencoding() raises a RuntimeError if initfsencoding() was not - called yet: detect bootstrap (startup) issues earlier. +- Issue #16461: Wave library should be able to deal with 4GB wav files, + and sample rate of 44100 Hz. -- Issue #11393: Add the new faulthandler module. +- Issue #16176: Properly identify Windows 8 via platform.platform() -- Issue #11618: Fix the timeout logic in threading.Lock.acquire() under Windows. +- Issue #16088: BaseHTTPRequestHandler's send_error method includes a + Content-Length header in it's response now. Patch by Antoine Pitrou. -- Removed the 'strict' argument to email.parser.Parser, which has been - deprecated since Python 2.4. +- Issue #16114: The subprocess module no longer provides a misleading error + message stating that args[0] did not exist when either the cwd or executable + keyword arguments specified a path that did not exist. -- Issue #11256: Fix inspect.getcallargs on functions that take only keyword - arguments. +- Issue #16169: Fix ctypes.WinError()'s confusion between errno and winerror. -- Issue #11696: Fix ID generation in msilib. +- Issue #16110: logging.fileConfig now accepts a pre-initialised ConfigParser + instance. -- itertools.accumulate now supports an optional *func* argument for - a user-supplied binary function. +- Issue #1492704: shutil.copyfile() raises a distinct SameFileError now if + source and destination are the same file. Patch by Atsuo Ishimoto. -- Issue #11692: Remove unnecessary demo functions in subprocess module. +- Issue #13896: Make shelf instances work with 'with' as context managers. + Original patch by Filip Gruszczyński. -- Issue #9696: Fix exception incorrectly raised by xdrlib.Packer.pack_int when - trying to pack a negative (in-range) integer. +- Issue #15417: Add support for csh and fish in venv activation scripts. -- Issue #11675: multiprocessing.[Raw]Array objects created from an integer size - are now zeroed on creation. This matches the behaviour specified by the - documentation. +- Issue #14377: ElementTree.write and some of the module-level functions have + a new parameter - *short_empty_elements*. It controls how elements with no + contents are emitted. -- Issue #7639: Fix short file name generation in bdist_msi +- Issue #16089: Allow ElementTree.TreeBuilder to work again with a non-Element + element_factory (fixes a regression in SimpleTAL). -- Issue #11635: Don't use polling in worker threads and processes launched by - concurrent.futures. +- Issue #9650: List commonly used format codes in time.strftime and + time.strptime docsttings. Original patch by Mike Hoy. -- Issue #5845: Automatically read readline configuration to enable completion - in interactive mode. +- Issue #15452: logging configuration socket listener now has a verify option + that allows an application to apply a verification function to the + received configuration data before it is acted upon. -- Issue #6811: Allow importlib to change a code object's co_filename attribute - to match the path to where the source code currently is, not where the code - object originally came from. +- Issue #16034: Fix performance regressions in the new `bz2.BZ2File` + implementation. Initial patch by Serhiy Storchaka. -- Issue #8754: Have importlib use the repr of a module name in error messages. +- `pty.spawn()` now returns the child process status returned by `os.waitpid()`. -- Issue #11591: Prevent "import site" from modifying sys.path when python - was started with -S. +- Issue #15756: `subprocess.poll()` now properly handles `errno.ECHILD` to + return a returncode of 0 when the child has already exited or cannot be waited + on. -- collections.namedtuple() now adds a _source attribute to the generated - class. This make the source more accessible than the outdated - "verbose" option which prints to stdout but doesn't make the source - string available. +- Issue #15323: Improve failure message of `Mock.assert_called_once_with()`. -- Issue #11371: Mark getopt error messages as localizable. Patch by Filip - Gruszczyński. +- Issue #16064: ``unittest -m`` claims executable is "python", not "python3". -- Issue #11333: Add __slots__ to collections ABCs. +- Issue #12376: Pass on parameters in `TextTestResult.__init__()` super call. -- Issue #11628: cmp_to_key generated class should use __slots__. +- Issue #15222: Insert blank line after each message in mbox mailboxes. -- Issue #11666: let help() display named tuple attributes and methods - that start with a leading underscore. +- Issue #16013: Fix `csv.Reader` parsing issue with ending quote characters. + Patch by Serhiy Storchaka. -- Issue #11662: Make urllib and urllib2 ignore redirections if the - scheme is not HTTP, HTTPS or FTP (CVE-2011-1521). +- Issue #15421: Fix an OverflowError in `Calendar.itermonthdates()` after + `datetime.MAXYEAR`. Patch by Cédric Krier. -- Issue #5537: Fix time2isoz() and time2netscape() functions of - httplib.cookiejar for expiration year greater than 2038 on 32-bit systems. +- Issue #16112: platform.architecture does not correctly escape argument to + /usr/bin/file. Patch by David Benjamin. -- Issue #4391: Use proper gettext plural forms in optparse. +- Issue #15970: `xml.etree.ElementTree` now serializes correctly the empty HTML + elements 'meta' and 'param'. -- Issue #11127: Raise a TypeError when trying to pickle a socket object. +- Issue #15842: The `SocketIO.{readable,writable,seekable}` methods now raise + ValueError when the file-like object is closed. Patch by Alessandro Moura. -- Issue #11563: ``Connection: close`` header is sent by requests using URLOpener - class which helps in closing of sockets after connection is over. Patch - contributions by Jeff McNeil and Nadeem Vawda. +- Issue #15876: Fix a refleak in the `curses` module: window.encoding. -- Issue #11459: A ``bufsize`` value of 0 in subprocess.Popen() really creates - unbuffered pipes, such that select() works properly on them. +- Issue #15881: Fix `atexit` hook in `multiprocessing`. Original patch by Chris + McDonough. -- Issue #5421: Fix misleading error message when one of socket.sendto()'s - arguments has the wrong type. Patch by Nikita Vetoshkin. +- Issue #15841: The readable(), writable() and seekable() methods of + `io.BytesIO` and `io.StringIO` objects now raise ValueError when the object + has been closed. Patch by Alessandro Moura. -- Issue #10812: Add some extra posix functions to the os module. +- Issue #15447: Use `subprocess.DEVNULL` in webbrowser, instead of opening + `os.devnull` explicitly and leaving it open. -- Issue #10979: unittest stdout buffering now works with class and module - setup and teardown. +- Issue #15509: `webbrowser.UnixBrowser` no longer passes empty arguments to + Popen when ``%action`` substitutions produce empty strings. -- Issue #11243: fix the parameter querying methods of Message to work if - the headers contain un-encoded non-ASCII data. +- Issue #12776, issue #11839: Call `argparse` type function (specified by + add_argument) only once. Before, the type function was called twice in the + case where the default was specified and the argument was given as well. This + was especially problematic for the FileType type, as a default file would + always be opened, even if a file argument was specified on the command line. -- Issue #11401: fix handling of headers with no value; this fixes a regression - relative to Python2 and the result is now the same as it was in Python2. +- Issue #15906: Fix a regression in argparse caused by the preceding change, + when ``action='http://github.com/append'``, ``type='str'`` and ``default=[]``. -- Issue #9298: base64 bodies weren't being folded to line lengths less than 78, - which was a regression relative to Python2. Unlike Python2, the last line - of the folded body now ends with a carriage return. +- Issue #16113: Added sha3 module based on the Keccak reference implementation + 3.2. The `hashlib` module has four additional hash algorithms: `sha3_224`, + `sha3_256`, `sha3_384` and `sha3_512`. As part of the patch some common + code was moved from _hashopenssl.c to hashlib.h. -- Issue #11560: shutil.unpack_archive now correctly handles the format - parameter. Patch by Evan Dandrea. +- ctypes.call_commethod was removed, since its only usage was in the defunct + samples directory. -- Issue #5870: Add `subprocess.DEVNULL` constant. +- Issue #16692: Added TLSv1.1 and TLSv1.2 support for the ssl modules. -- Issue #11133: fix two cases where inspect.getattr_static can trigger code - execution. Patch by Andreas Stührk. +- Issue #16832: add abc.get_cache_token() to expose cache validity checking + support in ABCMeta. -- Issue #11569: use absolute path to the sysctl command in multiprocessing to - ensure that it will be found regardless of the shell PATH. This ensures - that multiprocessing.cpu_count works on default installs of MacOSX. +IDLE +---- -- Issue #11501: disutils.archive_utils.make_zipfile no longer fails if zlib is - not installed. Instead, the zipfile.ZIP_STORED compression is used to create - the ZipFile. Patch by Natalia B. Bidart. +- Issue #18429: Format / Format Paragraph, now works when comment blocks + are selected. As with text blocks, this works best when the selection + only includes complete lines. -- Issue #11289: `smtp.SMTP` class is now a context manager so it can be used - in a `with` statement. Contributed by Giampaolo Rodola. +- Issue #18226: Add docstrings and unittests for FormatParagraph.py. + Original patches by Todd Rovito and Phil Webster. -- Issue #11554: Fixed support for Japanese codecs; previously the body output - encoding was not done if euc-jp or shift-jis was specified as the charset. +- Issue #18279: Format - Strip trailing whitespace no longer marks a file as + changed when it has not been changed. This fix followed the addition of a + test file originally written by Phil Webster (the issue's main goal). -- Issue #11407: `TestCase.run` returns the result object used or created. - Contributed by Janathan Hartley. +- Issue #7136: In the Idle File menu, "New Window" is renamed "New File". + Patch by Tal Einat, Roget Serwy, and Todd Rovito. -- Issue #11500: Fixed a bug in the OS X proxy bypass code for fully qualified - IP addresses in the proxy exception list. +- Remove dead imports of imp. -- Issue #11491: dbm.error is no longer raised when dbm.open is called with - the "n" as the flag argument and the file exists. The behavior matches - the documentation and general logic. +- Issue #18196: Avoid displaying spurious SystemExit tracebacks. -- Issue #1162477: Postel Principle adjustment to email date parsing: handle the - fact that some non-compliant MUAs use '.' instead of ':' in time specs. +- Issue #5492: Avoid traceback when exiting IDLE caused by a race condition. -- Issue #11131: Fix sign of zero in decimal.Decimal plus and minus - operations when the rounding mode is ROUND_FLOOR. +- Issue #17511: Keep IDLE find dialog open after clicking "Find Next". + Original patch by Sarah K. -- Issue #9935: Speed up pickling of instances of user-defined classes. +- Issue #18055: Move IDLE off of imp and on to importlib. -- Issue #5622: Fix curses.wrapper to raise correct exception if curses - initialization fails. +- Issue #15392: Create a unittest framework for IDLE. + Initial patch by Rajagopalasarma Jayakrishnan. + See Lib/idlelib/idle_test/README.txt for how to run Idle tests. -- Issue #11408: In threading.Lock.acquire(), only call gettimeofday() when - really necessary. Patch by Charles-François Natali. +- Issue #14146: Highlight source line while debugging on Windows. -- Issue #11391: Writing to a mmap object created with - ``mmap.PROT_READ|mmap.PROT_EXEC`` would segfault instead of raising a - TypeError. Patch by Charles-François Natali. +- Issue #17838: Allow sys.stdin to be reassigned. -- Issue #9795: add context manager protocol support for nntplib.NNTP class. +- Issue #13495: Avoid loading the color delegator twice in IDLE. -- Issue #11306: mailbox in certain cases adapts to an inability to open - certain files in read-write mode. Previously it detected this by - checking for EACCES, now it also checks for EROFS. +- Issue #17798: Allow IDLE to edit new files when specified on command line. -- Issue #11265: asyncore now correctly handles EPIPE, EBADF and EAGAIN errors - on accept(), send() and recv(). +- Issue #14735: Update IDLE docs to omit "Control-z on Windows". -- Issue #11377: Deprecate platform.popen() and reimplement it with os.popen(). +- Issue #17532: Always include Options menu for IDLE on OS X. + Patch by Guilherme Simões. -- Issue #8513: On UNIX, subprocess supports bytes command string. +- Issue #17585: Fixed IDLE regression. Now closes when using exit() or quit(). -- Issue #10866: Add socket.sethostname(). Initial patch by Ross Lagerwall. +- Issue #17657: Show full Tk version in IDLE's about dialog. + Patch by Todd Rovito. -- Issue #11140: Lock.release() now raises a RuntimeError when attempting - to release an unacquired lock, as claimed in the threading documentation. - The _thread.error exception is now an alias of RuntimeError. Patch by - Filip Gruszczyński. Patch for _dummy_thread by Aymeric Augustin. +- Issue #17613: Prevent traceback when removing syntax colorizer in IDLE. -- Issue #8594: ftplib now provides a source_address parameter to specify which - (address, port) to bind to before connecting. +- Issue #1207589: Backwards-compatibility patch for right-click menu in IDLE. -- Issue #11326: Add the missing connect_ex() implementation for SSL sockets, - and make it work for non-blocking connects. +- Issue #16887: IDLE now accepts Cancel in tabify/untabify dialog box. -- Issue #11297: Add collections.ChainMap(). +- Issue #17625: In IDLE, close the replace dialog after it is used. -- Issue #10755: Add the posix.flistdir() function. Patch by Ross Lagerwall. +- Issue #14254: IDLE now handles readline correctly across shell restarts. -- Issue #4761: Add the ``*at()`` family of functions (openat(), etc.) to the - posix module. Patch by Ross Lagerwall. +- Issue #17614: IDLE no longer raises exception when quickly closing a file. -- Issue #7322: Trying to read from a socket's file-like object after a timeout - occurred now raises an error instead of silently losing data. +- Issue #6698: IDLE now opens just an editor window when configured to do so. -- Issue #11291: poplib.POP no longer suppresses errors on quit(). +- Issue #8900: Using keyboard shortcuts in IDLE to open a file no longer + raises an exception. -- Issue #11177: asyncore's create_socket() arguments can now be omitted. +- Issue #6649: Fixed missing exit status in IDLE. Patch by Guilherme Polo. -- Issue #6064: Add a ``daemon`` keyword argument to the threading.Thread - and multiprocessing.Process constructors in order to override the - default behaviour of inheriting the daemonic property from the current - thread/process. +- Issue #17114: IDLE now uses non-strict config parser. -- Issue #10956: Buffered I/O classes retry reading or writing after a signal - has arrived and the handler returned successfully. +- Issue #9290: In IDLE the sys.std* streams now implement io.TextIOBase + interface and support all mandatory methods and properties. -- Issue #10784: New os.getpriority() and os.setpriority() functions. +- Issue #5066: Update IDLE docs. Patch by Todd Rovito. -- Issue #11114: Fix catastrophic performance of tell() on text files (up - to 1000x faster in some cases). It is still one to two order of magnitudes - slower than binary tell(). +- Issue #16829: IDLE printing no longer fails if there are spaces or other + special characters in the file path. -- Issue #10882: Add os.sendfile function. +- Issue #16491: IDLE now prints chained exception tracebacks. -- Issue #10868: Allow usage of the register method of an ABC as a class - decorator. +- Issue #16819: IDLE method completion now correctly works for bytes literals. -- Issue #11224: Fixed a regression in tarfile that affected the file-like - objects returned by TarFile.extractfile() regarding performance, memory - consumption and failures with the stream interface. +- Issue #16504: IDLE now catches SyntaxErrors raised by tokenizer. Patch by + Roger Serwy. -- Issue #10924: Adding salt and Modular Crypt Format to crypt library. - Moved old C wrapper to _crypt, and added a Python wrapper with - enhanced salt generation and simpler API for password generation. +- Issue #16511: Use default IDLE width and height if config param is not valid. + Patch Serhiy Storchaka. -- Issue #11074: Make 'tokenize' so it can be reloaded. +- Issue #1207589: Add Cut/Copy/Paste items to IDLE right click Context Menu + Patch by Todd Rovito. -- Issue #11085: Moved collections abstract base classes into a separate - module called collections.abc, following the pattern used by importlib.abc. - For backwards compatibility, the names are imported into the collections - module. +- Issue #16123: IDLE - deprecate running without a subprocess. + Patch by Roger Serwy. -- Issue #4681: Allow mmap() to work on file sizes and offsets larger than - 4GB, even on 32-bit builds. Initial patch by Ross Lagerwall, adapted for - 32-bit Windows. +Tests +----- -- Issue #11169: compileall module uses repr() to format filenames and paths to - escape surrogate characters and show spaces. +- Issue #1666318: Add a test that shutil.copytree() retains directory + permissions. Patch by Catherine Devlin. -- Issue #11089: Fix performance issue limiting the use of ConfigParser() - with large config files. +- Issue #18273: move the tests in Lib/test/json_tests to Lib/test/test_json + and make them discoverable by unittest. Patch by Zachary Ware. -- Issue #10276: Fix the results of zlib.crc32() and zlib.adler32() on buffers - larger than 4GB. Patch by Nadeem Vawda. +- Fix a fcntl test case on KFreeBSD, Debian #708653 (Petr Salinger). -- Issue #11388: Added a clear() method to MutableSequence +- Issue #18396: Fix spurious test failure in test_signal on Windows when + faulthandler is enabled (Patch by Jeremy Kloth) -- Issue #11174: Add argparse.MetavarTypeHelpFormatter, which uses type names - for the names of optional and positional arguments in help messages. +- Issue #17046: Fix broken test_executable_without_cwd in test_subprocess. -- Issue #9348: Raise an early error if argparse nargs and metavar don't match. +- Issue #15415: Add new temp_dir() and change_cwd() context managers to + test.support, and refactor temp_cwd() to use them. Patch by Chris Jerdonek. -- Issue #9026: Fix order of argparse sub-commands in help messages. +- Issue #15494: test.support is now a package rather than a module (Initial + patch by Indra Talip) -- Issue #9347: Fix formatting for tuples in argparse type= error messages. +- Issue #17944: test_zipfile now discoverable and uses subclassing to + generate tests for different compression types. Fixed a bug with skipping + some tests due to use of exhausted iterators. -- Issue #12191: Added shutil.chown() to change user and/or group owner of a - given path also specifying their names. +- Issue #18266: test_largefile now works with unittest test discovery and + supports running only selected tests. Patch by Zachary Ware. -- Issue #13988: The _elementtree accelerator is used whenever available. - Now xml.etree.cElementTree becomes a deprecated alias to ElementTree. +- Issue #17767: test_locale now works with unittest test discovery. + Original patch by Zachary Ware. -Build ------ +- Issue #18375: Assume --randomize when --randseed is used for running the + testsuite. -- Issue #6807: Run msisupport.mak earlier. +- Issue #11185: Fix test_wait4 under AIX. Patch by Sébastien Sablé. -- Issue #10580: Minor grammar change in Windows installer. +- Issue #18207: Fix test_ssl for some versions of OpenSSL that ignore seconds + in ASN1_TIME fields. -- Issue #13326: Clean __pycache__ directories correctly on OpenBSD. +- Issue #18094: test_uuid no longer reports skipped tests as passed. -- PEP 393: the configure option --with-wide-unicode is removed. +- Issue #17992: Add timeouts to asyncore and asynchat tests so that they won't + accidentally hang. -- Issue #12852: Set _XOPEN_SOURCE to 700, instead of 600, to get POSIX 2008 - functions on OpenBSD (e.g. fdopendir). +- Issue #17833: Fix test_gdb failures seen on machines where debug symbols + for glibc are available (seen on PPC64 Linux). -- Issue #11863: Remove support for legacy systems deprecated in Python 3.2 - (following PEP 11). These systems are systems using Mach C Threads, - SunOS lightweight processes, GNU pth threads and IRIX threads. +- Issue #7855: Add tests for ctypes/winreg for issues found in IronPython. + Initial patch by Dino Viehland. -- Issue #8746: Correct faulty configure checks so that os.chflags() and - os.lchflags() are once again built on systems that support these - functions (BSD and OS X). Also add new stat file flags for OS X - (UF_HIDDEN and UF_COMPRESSED). +- Issue #11078: test___all__ now checks for duplicates in __all__. + Initial patch by R. David Murray. -- Issue #10645: Installing Python no longer creates a - Python-X.Y.Z-pyX.Y.egg-info file in the lib-dynload directory. +- Issue #17712: Fix test_gdb failures on Ubuntu 13.04. -- Do not accidentally include the directory containing sqlite.h twice when - building sqlite3. +- Issue #17835: Fix test_io when the default OS pipe buffer size is larger + than one million bytes. -- Issue #11217: For 64-bit/32-bit Mac OS X universal framework builds, - ensure "make install" creates symlinks in --prefix bin for the "-32" - files in the framework bin directory like the installer does. +- Issue #17065: Use process-unique key for winreg tests to avoid failures if + test is run multiple times in parallel (eg: on a buildbot host). -- Issue #11347: Use --no-as-needed when linking libpython3.so. +- Issue #12820: add tests for the xml.dom.minicompat module. + Patch by John Chandler and Phil Connell. -- Issue #11411: Fix 'make DESTDIR=' with a relative destination. +- Issue #17691: test_univnewlines now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #11268: Prevent Mac OS X Installer failure if Documentation - package had previously been installed. +- Issue #17790: test_set now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #11495: OSF support is eliminated. It was deprecated in Python 3.2. +- Issue #17789: test_random now works with unittest test discovery. + Patch by Zachary Ware. -IDLE ----- +- Issue #17779: test_osx_env now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #14409: IDLE now properly executes commands in the Shell window - when it cannot read the normal config files on startup and - has to use the built-in default key bindings. - There was previously a bug in one of the defaults. +- Issue #17766: test_iterlen now works with unittest test discovery. + Patch by Zachary Ware. -- IDLE can be launched as python -m idlelib +- Issue #17690: test_time now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #3573: IDLE hangs when passing invalid command line args - (directory(ies) instead of file(s)) (Patch by Guilherme Polo) +- Issue #17692: test_sqlite now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #14200: IDLE shell crash on printing non-BMP unicode character. +- Issue #11995: test_pydoc doesn't import all sys.path modules anymore. -- Issue #5219: Prevent event handler cascade in IDLE. +- Issue #17448: test_sax now skips if there are no xml parsers available + instead of raising an ImportError. -- Issue #964437: Make IDLE help window non-modal. - Patch by Guilherme Polo and Roger Serwy. +- Issue #11420: make test suite pass with -B/DONTWRITEBYTECODE set. + Initial patch by Thomas Wouters. -- Issue #13933: IDLE auto-complete did not work with some imported - module, like hashlib. (Patch by Roger Serwy) +- Issue #10652: make tcl/tk tests run after __all__ test, patch by + Zachary Ware. -- Issue #13506: Add '' to path for IDLE Shell when started and restarted with Restart Shell. - Original patches by Marco Scataglini and Roger Serwy. +- Issue #11963: remove human verification from test_parser and test_subprocess. -- Issue #4625: If IDLE cannot write to its recent file or breakpoint files, - display a message popup and continue rather than crash. Original patch by - Roger Serwy. +- Issue #11732: add a new suppress_crash_popup() context manager to test.support + that disables crash popups on Windows and use it in test_faulthandler and + test_capi. -- Issue #8641: Update IDLE 3 syntax coloring to recognize b".." and not u"..". - Patch by Tal Einat. +- Issue #13898: test_ssl no longer prints a spurious stack trace on Ubuntu. -- Issue #13296: Fix IDLE to clear compile __future__ flags on shell restart. - (Patch by Roger Serwy) +- Issue #17283: Share code between `__main__.py` and `regrtest.py` in + `Lib/test`. -- Issue #9871: Prevent IDLE 3 crash when given byte stings - with invalid hex escape sequences, like b'\x0'. - (Original patch by Claudiu Popa.) +- Issue #17249: convert a test in test_capi to use unittest and reap threads. -- Issue #12636: IDLE reads the coding cookie when executing a Python script. +- Issue #17107: Test client-side SNI support in urllib.request thanks to + the new server-side SNI support in the ssl module. Initial patch by + Daniel Black. -- Issue #12540: Prevent zombie IDLE processes on Windows due to changes - in os.kill(). +- Issue #17041: Fix testing when Python is configured with the + --without-doc-strings. -- Issue #12590: IDLE editor window now always displays the first line - when opening a long file. With Tk 8.5, the first line was hidden. +- Issue #16923: Fix ResourceWarnings in test_ssl. -- Issue #11088: don't crash when using F5 to run a script in IDLE on MacOSX - with Tk 8.5. +- Issue #15539: Added regression tests for Tools/scripts/pindent.py. -- Issue #1028: Tk returns invalid Unicode null in %A: UnicodeDecodeError. - With Tk < 8.5 _tkinter.c:PythonCmd() raised UnicodeDecodeError, caused - IDLE to exit. Converted to valid Unicode null in PythonCmd(). +- Issue #17479: test_io now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #11718: IDLE's open module dialog couldn't find the __init__.py - file in a package. +- Issue #17066: test_robotparser now works with unittest test discovery. + Patch by Zachary Ware. -Tools/Demos ------------ +- Issue #17334: test_index now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #14053: patchcheck.py ("make patchcheck") now works with MQ patches. - Patch by Francisco Martín Brugué. +- Issue #17333: test_imaplib now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #13930: 2to3 is now able to write its converted output files to another - directory tree as well as copying unchanged files and altering the file - suffix. See its new -o, -W and --add-suffix options. This makes it more - useful in many automated code translation workflows. +- Issue #17082: test_dbm* now work with unittest test discovery. + Patch by Zachary Ware. -- Issue #13628: python-gdb.py is now able to retrieve more frames in the Python - traceback if Python is optimized. +- Issue #17079: test_ctypes now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #11996: libpython (gdb), replace "py-bt" command by "py-bt-full" and - add a smarter "py-bt" command printing a classic Python traceback. +- Issue #17304: test_hash now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #11179: Make ccbench work under Python 3.1 and 2.7 again. +- Issue #17303: test_future* now work with unittest test discovery. + Patch by Zachary Ware. -- Issue #10639: reindent.py no longer converts newlines and will raise - an error if attempting to convert a file with mixed newlines. - "--newline" option added to specify new line character. +- Issue #17163: test_file now works with unittest test discovery. + Patch by Zachary Ware. -Extension Modules ------------------ +- Issue #16925: test_configparser now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #16847: Fixed improper use of _PyUnicode_CheckConsistency() in - non-pydebug builds. Several extension modules now compile cleanly when - assert()s are enabled in standard builds (-DDEBUG flag). +- Issue #16918: test_codecs now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #13840: The error message produced by ctypes.create_string_buffer - when given a Unicode string has been fixed. +- Issue #16919: test_crypt now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #9975: socket: Fix incorrect use of flowinfo and scope_id. Patch by - Vilmos Nebehaj. +- Issue #16910: test_bytes, test_unicode, and test_userstring now work with + unittest test discovery. Patch by Zachary Ware. -- Issue #7777: socket: Add Reliable Datagram Sockets (PF_RDS) support. +- Issue #16905: test_warnings now works with unittest test discovery. + Initial patch by Berker Peksag. -- Issue #13159: FileIO and BZ2Compressor/BZ2Decompressor now use a linear-time - buffer growth strategy instead of a quadratic-time one. +- Issue #16898: test_bufio now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #10141: socket: Add SocketCAN (PF_CAN) support. Initial patch by - Matthias Fuchs, updated by Tiago Gonçalves. +- Issue #16888: test_array now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #13070: Fix a crash when a TextIOWrapper caught in a reference cycle - would be finalized after the reference to its underlying BufferedRWPair's - writer got cleared by the GC. +- Issue #16896: test_asyncore now works with unittest test discovery. + Patch by Zachary Ware. -- Issue #12881: ctypes: Fix segfault with large structure field names. +- Issue #16897: test_bisect now works with unittest test discovery. + Initial patch by Zachary Ware. -- Issue #13058: ossaudiodev: fix a file descriptor leak on error. Patch by - Thomas Jarosch. +- Issue #16852: test_genericpath, test_posixpath, test_ntpath, and test_macpath + now work with unittest test discovery. Patch by Zachary Ware. -- Issue #13013: ctypes: Fix a reference leak in PyCArrayType_from_ctype. - Thanks to Suman Saha for finding the bug and providing a patch. +- Issue #16748: test_heapq now works with unittest test discovery. -- Issue #13022: Fix: _multiprocessing.recvfd() doesn't check that - file descriptor was actually received. +- Issue #10646: Tests rearranged for os.samefile/samestat to check for not + just symlinks but also hard links. -- Issue #1172711: Add 'long long' support to the array module. - Initial patch by Oren Tirosh and Hirokazu Yamamoto. +- Issue #15302: Switch regrtest from using getopt to using argparse. -- Issue #12483: ctypes: Fix a crash when the destruction of a callback - object triggers the garbage collector. +- Issue #15324: Fix regrtest parsing of --fromfile, --match, and --randomize + options. -- Issue #12950: Fix passing file descriptors in multiprocessing, under - OpenIndiana/Illumos. +- Issue #16702: test_urllib2_localnet tests now correctly ignores proxies for + localhost tests. -- Issue #12764: Fix a crash in ctypes when the name of a Structure field is not - a string. +- Issue #16664: Add regression tests for glob's behaviour concerning entries + starting with a ".". Patch by Sebastian Kreft. -- Issue #11241: subclasses of ctypes.Array can now be subclassed. +- Issue #13390: The ``-R`` option to regrtest now also checks for memory + allocation leaks, using :func:`sys.getallocatedblocks()`. -- Issue #9651: Fix a crash when ctypes.create_string_buffer(0) was passed to - some functions like file.write(). +- Issue #16559: Add more tests for the json module, including some from the + official test suite at json.org. Patch by Serhiy Storchaka. -- Issue #10309: Define _GNU_SOURCE so that mremap() gets the proper - signature. Without this, architectures where sizeof void* != sizeof int are - broken. Patch given by Hallvard B Furuseth. +- Issue #16661: Fix the `os.getgrouplist()` test by not assuming that it gives + the same output as :command:`id -G`. -- Issue #12051: Fix segfault in json.dumps() while encoding highly-nested - objects using the C accelerations. +- Issue #16115: Add some tests for the executable argument to + subprocess.Popen(). Initial patch by Kushal Das. -- Issue #12017: Fix segfault in json.loads() while decoding highly-nested - objects using the C accelerations. +- Issue #16126: PyErr_Format format mismatch in _testcapimodule.c. + Patch by Serhiy Storchaka. -- Issue #1838: Prevent segfault in ctypes, when _as_parameter_ on a class is set - to an instance of the class. +- Issue #15304: Fix warning message when `os.chdir()` fails inside + `test.support.temp_cwd()`. Patch by Chris Jerdonek. -Tests ------ +- Issue #15802: Fix test logic in `TestMaildir.test_create_tmp()`. Patch by + Serhiy Storchaka. -- Issue #13125: Silence spurious test_lib2to3 output when in non-verbose mode. - Patch by Mikhail Novikov. +- Issue #15557: Added a test suite for the webbrowser module, thanks to Anton + Barkovsky. -- Issue #13447: Add a test file to host regression tests for bugs in the - scripts found in the Tools directory. +- Issue #16698: Skip posix test_getgroups when built with OS X + deployment target prior to 10.6. -- Issue #10881: Fix test_site failure with OS X framework builds. +Build +----- -- Issue #13901: Prevent test_distutils failures on OS X with --enable-shared. +- Issue #16067: Add description into MSI file to replace installer's + temporary name. -- Issue #13862: Fix spurious failure in test_zlib due to runtime/compile time - minor versions not matching. +- Issue #18257: Fix readlink usage in python-config. Install the python + version again on Darwin. -- Issue #12804: Fix test_socket and test_urllib2net failures when running tests - on a system without internet access. +- Issue #18481: Add C coverage reporting with gcov and lcov. A new make target + "coverage-report" creates an instrumented Python build, runs unit tests + and creates a HTML. The report can be updated with "make coverage-lcov". -- Issue #13726: Fix the ambiguous -S flag in regrtest. It is -o/--slow for slow - tests. +- Issue #17845: Clarified the message printed when some module are not built. -- Issue #11659: Fix ResourceWarning in test_subprocess introduced by #11459. - Patch by Ben Hayden. +- Issue #18256: Compilation fix for recent AIX releases. Patch by + David Edelsohn. -- Issue #11577: fix ResourceWarning triggered by improved binhex test coverage +- Issue #17547: In configure, explicitly pass -Wformat for the benefit for GCC + 4.8. -- Issue #11509: Significantly increase test coverage of fileinput. - Patch by Denver Coneybeare at PyCon 2011 Sprints. +- Issue #15172: Document NASM 2.10+ as requirement for building OpenSSL 1.0.1 + on Windows. -- Issue #11689: Fix a variable scoping error in an sqlite3 test +- Issue #17591: Use lowercase filenames when including Windows header files. + Patch by Roumen Petrov. -- Issue #13786: Remove unimplemented 'trace' long option from regrtest.py. +- Issue #17550: Fix the --enable-profiling configure switch. -- Issue #13725: Fix regrtest to recognize the documented -d flag. - Patch by Erno Tukia. +- Issue #17425: Build with openssl 1.0.1d on Windows. -- Issue #13304: Skip test case if user site-packages disabled (-s or - PYTHONNOUSERSITE). (Patch by Carl Meyer) +- Issue #16754: Fix the incorrect shared library extension on linux. Introduce + two makefile macros SHLIB_SUFFIX and EXT_SUFFIX. SO now has the value of + SHLIB_SUFFIX again (as in 2.x and 3.1). The SO macro is removed in 3.4. -- Issue #5661: Add a test for ECONNRESET/EPIPE handling to test_asyncore. Patch - by Xavier de Gaye. +- Issue #5033: Fix building of the sqlite3 extension module when the + SQLite library version has "beta" in it. Patch by Andreas Pelme. -- Issue #13218: Fix test_ssl failures on Debian/Ubuntu. +- Issue #17228: Fix building without pymalloc. -- Re-enable lib2to3's test_parser.py tests, though with an expected failure - (see issue 13125). +- Issue #3718: Use AC_ARG_VAR to set MACHDEP in configure.ac. -- Issue #12656: Add tests for IPv6 and Unix sockets to test_asyncore. +- Issue #16235: Implement python-config as a shell script. -- Issue #6484: Add unit tests for mailcap module (patch by Gregory Nofi) +- Issue #16769: Remove outdated Visual Studio projects. -- Issue #11651: Improve the Makefile test targets to run more of the test suite - more quickly. The --multiprocess option is now enabled by default, reducing - the amount of time needed to run the tests. "make test" and "make quicktest" - now include some resource-intensive tests, but no longer run the test suite - twice to check for bugs in .pyc generation. Tools/scripts/run_test.py provides - an easy platform-independent way to run test suite with sensible defaults. +- Issue #17031: Fix running regen in cross builds. -- Issue #12331: The test suite for the packaging module can now run from an - installed Python. +- Issue #3754: fix typo in pthread AC_CACHE_VAL. -- Issue #12331: The test suite for lib2to3 can now run from an installed - Python. +- Issue #15484: Fix _PYTHON_PROJECT_BASE for srcdir != builddir builds; + use _PYTHON_PROJECT_BASE in distutils/sysconfig.py. -- Issue #12626: In regrtest, allow to filter tests using a glob filter - with the ``-m`` (or ``--match``) option. This works with all test cases - using the unittest module. This is useful with long test suites - such as test_io or test_subprocess. +- Drop support for Windows 2000 (changeset e52df05b496a). -- Issue #12624: It is now possible to fail after the first failure when - running in verbose mode (``-v`` or ``-W``), by using the ``--failfast`` - (or ``-G``) option to regrtest. This is useful with long test suites - such as test_io or test_subprocess. +- Issue #17029: Let h2py search the multiarch system include directory. -- Issue #12587: Correct faulty test file and reference in test_tokenize. - (Patch by Robert Xiao) +- Issue #16953: Fix socket module compilation on platforms with + HAVE_BROKEN_POLL. Patch by Jeffrey Armstrong. -- Issue #12573: Add resource checks for dangling Thread and Process objects. +- Issue #16320: Remove redundant Makefile dependencies for strings and bytes. -- Issue #12549: Correct test_platform to not fail when OS X returns 'x86_64' - as the processor type on some Mac systems. +- Cross compiling needs host and build settings. configure no longer + creates a broken PYTHON_FOR_BUILD variable when --build is missing. -- Skip network tests when getaddrinfo() returns EAI_AGAIN, meaning a temporary - failure in name resolution. +- Fix cross compiling issue in setup.py, ensure that lib_dirs and inc_dirs are + defined in cross compiling mode, too. -- Issue #11812: Solve transient socket failure to connect to 'localhost' - in test_telnetlib.py. +- Issue #16836: Enable IPv6 support even if IPv6 is disabled on the build host. -- Solved a potential deadlock in test_telnetlib.py. Related to issue #11812. +- Issue #16593: Have BSD 'make -s' do the right thing, thanks to Daniel Shahaf -- Avoid failing in test_robotparser when mueblesmoraleda.com is flaky and - an overzealous DNS service (e.g. OpenDNS) redirects to a placeholder - Web site. +- Issue #16262: fix out-of-src-tree builds, if mercurial is not installed. -- Avoid failing in test_urllibnet.test_bad_address when some overzealous - DNS service (e.g. OpenDNS) resolves a non-existent domain name. The test - is now skipped instead. +- Issue #15298: ensure _sysconfigdata is generated in build directory, not + source directory. -- Issue #12440: When testing whether some bits in SSLContext.options can be - reset, check the version of the OpenSSL headers Python was compiled against, - rather than the runtime version of the OpenSSL library. +- Issue #15833: Fix a regression in 3.3 that resulted in exceptions being + raised if importlib failed to write byte-compiled files. This affected + attempts to build Python out-of-tree from a read-only source directory. -- Issue #11512: Add a test suite for the cgitb module. Patch by Robbie Clemons. +- Issue #15923: Fix a mistake in ``asdl_c.py`` that resulted in a TypeError + after 2801bf875a24 (see #15801). -- Issue #12497: Install test/data to prevent failures of the various codecmaps - tests. +- Issue #16135: Remove OS/2 support. -- Issue #12496: Install test/capath directory to prevent test_connect_capath - testcase failure in test_ssl. +- Issue #15819: Make sure we can build Python out-of-tree from a read-only + source directory. (Somewhat related to issue #9860.) -- Issue #12469: Run wakeup and pending signal tests in a subprocess to run the - test in a fresh process with only one thread and to not change signal - handling of the parent process. +- Issue #15587: Enable Tk high-resolution text rendering on Macs with + Retina displays. Applies to Tkinter apps, such as IDLE, on OS X + framework builds linked with Cocoa Tk 8.5. -- Issue #8716: Avoid crashes caused by Aqua Tk on OSX when attempting to run - test_tk or test_ttk_guionly under a username that is not currently logged - in to the console windowserver (as may be the case under buildbot or ssh). +- Issue #17161: make install now also installs a python3 man page. -- Issue #12407: Explicitly skip test_capi.EmbeddingTest under Windows. +C-API +----- -- Issue #12400: regrtest -W doesn't rerun the tests twice anymore, but captures - the output and displays it on failure instead. regrtest -v doesn't print the - error twice anymore if there is only one error. +- Issue #18351: Fix various issues in a function in importlib provided to help + PyImport_ExecCodeModuleWithPathnames() (and thus by extension + PyImport_ExecCodeModule() and PyImport_ExecCodeModuleEx()). -- Issue #12141: Install copies of template C module file so that - test_build_ext of test_distutils and test_command_build_ext of - test_packaging are no longer silently skipped when - run outside of a build directory. +- Issue #9369: The types of `char*` arguments of PyObject_CallFunction() and + PyObject_CallMethod() now changed to `const char*`. Based on patches by + Jörg Müller and Lars Buitinck. -- Issue #8746: Add additional tests for os.chflags() and os.lchflags(). - Patch by Garrett Cooper. +- Issue #17206: Py_CLEAR(), Py_DECREF(), Py_XINCREF() and Py_XDECREF() now + expand their arguments once instead of multiple times. Patch written by Illia + Polosukhin. -- Issue #10736: Fix test_ttk test_widgets failures with Cocoa Tk 8.5.9 - 2.8 + on Mac OS X. (Patch by Ronald Oussoren) +- Issue #17522: Add the PyGILState_Check() API. -- Issue #12057: Add tests for ISO 2022 codecs (iso2022_jp, iso2022_jp_2, - iso2022_kr). +- Issue #17327: Add PyDict_SetDefault. -- Issue #12096: Fix a race condition in test_threading.test_waitfor(). Patch - written by Charles-François Natali. +- Issue #16881: Fix Py_ARRAY_LENGTH macro for GCC < 3.1. -- Issue #11614: import __hello__ prints "Hello World!". Patch written by - Andreas Stührk. +- Issue #16505: Remove unused Py_TPFLAGS_INT_SUBCLASS. -- Issue #5723: Improve json tests to be executed with and without accelerations. +- Issue #16086: PyTypeObject.tp_flags and PyType_Spec.flags are now unsigned + (unsigned long and unsigned int) to avoid an undefined behaviour with + Py_TPFLAGS_TYPE_SUBCLASS ((1 << 31). PyType_GetFlags() result type is + now unsigned too (unsigned long, instead of long). -- Issue #12041: Make test_wait3 more robust. +- Issue #16166: Add PY_LITTLE_ENDIAN and PY_BIG_ENDIAN macros and unified + endianness detection and handling. -- Issue #11873: Change regex in test_compileall to fix occasional failures when - when the randomly generated temporary path happened to match the regex. +Documentation +------------- -- Issue #11958: Fix FTP tests for IPv6, bind to "::1" instead of "localhost". - Patch written by Charles-Francois Natali. +- Issue #23006: Improve the documentation and indexing of dict.__missing__. + Add an entry in the language datamodel special methods section. + Revise and index its discussion in the stdtypes mapping/dict section. -- Issue #8407, #11859: Fix tests of test_io using threads and an alarm: use - pthread_sigmask() to ensure that the SIGALRM signal is received by the main - thread. +- Issue #17701: Improving strftime documentation. -- Issue #11811: Factor out detection of IPv6 support on the current host - and make it available as ``test.support.IPV6_ENABLED``. Patch by - Charles-François Natali. +- Issue #18440: Clarify that `hash()` can truncate the value returned from an + object's custom `__hash__()` method. -- Issue #10914: Add a minimal embedding test to test_capi. +- Issue #17844: Add links to encoders and decoders for bytes-to-bytes codecs. -- Issue #11223: Skip test_lock_acquire_interruption() and - test_rlock_acquire_interruption() of test_threadsignals if a thread lock is - implemented using a POSIX mutex and a POSIX condition variable. A POSIX - condition variable cannot be interrupted by a signal (e.g. on Linux, the - futex system call is restarted). +- Issue #14097: improve the "introduction" page of the tutorial. -- Issue #11790: Fix sporadic failures in test_multiprocessing.WithProcessesTestCondition. +- Issue #17977: The documentation for the cadefault argument's default value + in urllib.request.urlopen() is fixed to match the code. -- Fix possible "file already exists" error when running the tests in parallel. +- Issue #6696: add documentation for the Profile objects, and improve + profile/cProfile docs. Patch by Tom Pinckney. -- Issue #11719: Fix message about unexpected test_msilib skip on non-Windows - platforms. Patch by Nadeem Vawda. +- Issue #15940: Specify effect of locale on time functions. -- Issue #11727: Add a --timeout option to regrtest: if a test takes more than - TIMEOUT seconds, dumps the traceback of all threads and exits. +- Issue #17538: Document XML vulnerabilties -- Issue #11653: fix -W with -j in regrtest. +- Issue #16642: sched.scheduler timefunc initial default is time.monotonic. + Patch by Ramchandra Apte -- The email test suite now lives in the Lib/test/test_email package. The test - harness code has also been modernized to allow use of new unittest features. +- Issue #17047: remove doubled words in docs and docstrings + reported by Serhiy Storchaka and Matthew Barnett. -- regrtest now discovers test packages as well as test modules. +- Issue #15465: Document the versioning macros in the C API docs rather than + the standard library docs. Patch by Kushal Das. -- Issue #11577: improve test coverage of binhex.py. Patch by Arkady Koplyarov. +- Issue #16406: Combine the pages for uploading and registering to PyPI. -- New test_crashers added to exercise the scripts in the Lib/test/crashers - directory and confirm they fail as expected +- Issue #16403: Document how distutils uses the maintainer field in + PKG-INFO. Patch by Jyrki Pulliainen. -- Issue #11578: added test for the timeit module. Patch by Michael Henry. +- Issue #16695: Document how glob handles filenames starting with a + dot. Initial patch by Jyrki Pulliainen. -- Issue #11503: improve test coverage of posixpath.py. Patch by Evan Dandrea. +- Issue #8890: Stop advertising an insecure practice by replacing uses + of the /tmp directory with better alternatives in the documentation. + Patch by Geoff Wilson. -- Issue #11505: improves test coverage of string.py, increases granularity of - string.Formatter tests. Initial patch by Alicia Arlen. +- Issue #17203: add long option names to unittest discovery docs. -- Issue #11548: Improve test coverage of the shutil module. Patch by - Evan Dandrea. +- Issue #13094: add "Why do lambdas defined in a loop with different values + all return the same result?" programming FAQ. -- Issue #11554: Reactivated test_email_codecs. +- Issue #14901: Update portions of the Windows FAQ. + Patch by Ashish Nitin Patil. -- Issue #11505: improves test coverage of string.py. Patch by Alicia - Arlen +- Issue #16267: Better document the 3.3+ approach to combining + @abstractmethod with @staticmethod, @classmethod and @property -- Issue #11490: test_subprocess.test_leaking_fds_on_error no longer gives a - false positive if the last directory in the path is inaccessible. +- Issue #15209: Clarify exception chaining description in exceptions module + documentation -- Issue #11223: Fix test_threadsignals to fail, not hang, when the - non-semaphore implementation of locks is used under POSIX. +- Issue #15990: Improve argument/parameter documentation. -- Issue #10911: Add tests on CGI with non-ASCII characters. Patch written by - Pierre Quentel. +- Issue #16209: Move the documentation for the str built-in function to a new + str class entry in the "Text Sequence Type" section. -- Issue #9931: Fix hangs in GUI tests under Windows in certain conditions. - Patch by Hirokazu Yamamoto. +- Issue #13538: Improve str() and object.__str__() documentation. -- Issue #10512: Properly close sockets under test.test_cgi. +- Issue #16489: Make it clearer that importlib.find_loader() needs parent + packages to be explicitly imported. -- Issue #10992: Make tests pass under coverage. +- Issue #16400: Update the description of which versions of a given package + PyPI displays. -- Issue #10826: Prevent sporadic failure in test_subprocess on Solaris due - to open door files. +- Issue #15677: Document that zlib and gzip accept a compression level of 0 to + mean 'no compression'. Patch by Brian Brazil. -- Issue #10990: Prevent tests from clobbering a set trace function. +- Issue #16197: Update winreg docstrings and documentation to match code. + Patch by Zachary Ware. -C-API ------ +- Issue #8040: added a version switcher to the documentation. Patch by + Yury Selivanov. -- Issue #13452: PyUnicode_EncodeDecimal() doesn't support error handlers - different than "strict" anymore. The caller was unable to compute the - size of the output buffer: it depends on the error handler. +- Issue #16241: Document -X faulthandler command line option. + Patch by Marek Šuppa. -- Issue #13560: Add PyUnicode_DecodeLocale(), PyUnicode_DecodeLocaleAndSize() - and PyUnicode_EncodeLocale() functions to the C API to decode/encode from/to - the current locale encoding. +- Additional comments and some style changes in the concurrent.futures URL + retrieval example -- Issue #10831: PyUnicode_FromFormat() supports %li, %lli and %zi formats. +- Issue #16115: Improve subprocess.Popen() documentation around args, shell, + and executable arguments. -- Issue #11246: Fix PyUnicode_FromFormat("%V") to decode the byte string from - UTF-8 (with replace error handler) instead of ISO-8859-1 (in strict mode). - Patch written by Ray Allen. +- Issue #13498: Clarify docs of os.makedirs()'s exist_ok argument. Done with + great native-speaker help from R. David Murray. -- Issue #10830: Fix PyUnicode_FromFormatV("%c") for non-BMP characters on - narrow build. +- Issue #15533: Clarify docs and add tests for `subprocess.Popen()`'s cwd + argument. -- Add PyObject_GenericGetDict and PyObject_GeneriSetDict. They are generic - implementations for the getter and setter of a ``__dict__`` descriptor of C - types. +- Issue #15979: Improve timeit documentation. -- Issue #13727: Add 3 macros to access PyDateTime_Delta members: - PyDateTime_DELTA_GET_DAYS, PyDateTime_DELTA_GET_SECONDS, - PyDateTime_DELTA_GET_MICROSECONDS. +- Issue #16036: Improve documentation of built-in `int()`'s signature and + arguments. -- Issue #10542: Add 4 macros to work with surrogates: Py_UNICODE_IS_SURROGATE, - Py_UNICODE_IS_HIGH_SURROGATE, Py_UNICODE_IS_LOW_SURROGATE, - Py_UNICODE_JOIN_SURROGATES. +- Issue #15935: Clarification of `argparse` docs, re: add_argument() type and + default arguments. Patch contributed by Chris Jerdonek. -- Issue #12724: Add Py_RETURN_NOTIMPLEMENTED macro for returning NotImplemented. +- Issue #11964: Document a change in v3.2 to the behavior of the indent + parameter of json encoding operations. -- PY_PATCHLEVEL_REVISION has been removed, since it's meaningless with - Mercurial. +- Issue #15116: Remove references to appscript as it is no longer being + supported. -- Issue #12173: The first argument of PyImport_ImportModuleLevel is now `const - char *` instead of `char *`. +Tools/Demos +----------- -- Issue #12380: PyArg_ParseTuple now accepts a bytearray for the 'c' format. +- Issue #18817: Fix a resource warning in Lib/aifc.py demo. Patch by + Vajrasky Kok. -Documentation -------------- +- Issue #18439: Make patchcheck work on Windows for ACKS, NEWS. -- Issue #13989: Document that GzipFile does not support text mode, and give a - more helpful error message when opened with an invalid mode string. +- Issue #18448: Fix a typo in Tools/demo/eiffel.py. -- Issue #13921: Undocument and clean up sqlite3.OptimizedUnicode, - which is obsolete in Python 3.x. It's now aliased to str for - backwards compatibility. +- Issue #18457: Fixed saving of formulas and complex numbers in + Tools/demo/ss1.py. -- Issue #12102: Document that buffered files must be flushed before being used - with mmap. Patch by Steffen Daode Nurpmeso. +- Issue #18449: Make Tools/demo/ss1.py work again on Python 3. Patch by + Févry Thibault. -- Issue #8982: Improve the documentation for the argparse Namespace object. +- Issue #12990: The "Python Launcher" on OSX could not launch python scripts + that have paths that include wide characters. -- Issue #9343: Document that argparse parent parsers must be configured before - their children. +- Issue #15239: Make mkstringprep.py work again on Python 3. -- Issue #13498: Clarify docs of os.makedirs()'s exist_ok argument. Done with - great native-speaker help from R. David Murray. +- Issue #17028: Allowed Python arguments to be supplied to the Windows + launcher. -- Issues #13491 and #13995: Fix many errors in sqlite3 documentation. - Initial patch for #13491 by Johannes Vogel. +- Issue #17156: pygettext.py now detects the encoding of source files and + correctly writes and escapes non-ascii characters. -- Issue #13402: Document absoluteness of sys.executable. +- Issue #15539: Fix a number of bugs in Tools/scripts/pindent.py. Now + pindent.py works with a "with" statement. pindent.py no longer produces + improper indentation. pindent.py now works with continued lines broken after + "class" or "def" keywords and with continuations at the start of line. -- Issue #13883: PYTHONCASEOK also works on OS X. +- Issue #11797: Add a 2to3 fixer that maps reload() to imp.reload(). -- Issue #9021: Add an introduction to the copy module documentation. +- Issue #10966: Remove the concept of unexpected skipped tests. -- Issue #6005: Examples in the socket library documentation use sendall, where - relevant, instead send method. +- Issue #9893: Removed the Misc/Vim directory. -- Issue #12798: Updated the mimetypes documentation. +- Removed the Misc/TextMate directory. -- Issue #12949: Document the kwonlyargcount argument for the PyCode_New - C API function. +- Issue #16245: Add the Tools/scripts/parse_html5_entities.py script to parse + the list of HTML5 entities and update the html.entities.html5 dictionary. -- Issue #13513: Fix io.IOBase documentation to correctly link to the - io.IOBase.readline method instead of the readline module. +- Issue #15378: Fix Tools/unicode/comparecodecs.py. Patch by Serhiy Storchaka. -- Issue #13237: Reorganise subprocess documentation to emphasise convenience - functions and the most commonly needed arguments to Popen. +- Issue #16549: Make json.tool work again on Python 3 and add tests. + Initial patch by Berker Peksag and Serhiy Storchaka. -- Issue #13141: Demonstrate recommended style for socketserver examples. +- Issue #13301: use ast.literal_eval() instead of eval() in Tools/i18n/msgfmt.py + Patch by Serhiy Storchaka. -- Issue #11818: Fix tempfile examples for Python 3. +Windows +------- +- Issue #18569: The installer now adds .py to the PATHEXT variable when extensions + are registered. Patch by Paul Moore. **(For information about older versions, consult the HISTORY file.)** diff --git a/Misc/Porting b/Misc/Porting index 51f73e63d1e4..c43b11297884 100644 --- a/Misc/Porting +++ b/Misc/Porting @@ -1,41 +1 @@ -Q. I want to port Python to a new platform. How do I begin? - -A. I guess the two things to start with is to familiarize yourself -with are the development system for your target platform and the -generic build process for Python. Make sure you can compile and run a -simple hello-world program on your target platform. Make sure you can -compile and run the Python interpreter on a platform to which it has -already been ported (preferably Unix, but Mac or Windows will do, -too). - -I also would never start something like this without at least -medium-level understanding of your target platform (i.e. how it is -generally used, how to write platform specific apps etc.) and Python -(or else you'll never know how to test the results). - -The build process for Python, in particular the Makefiles in the -source distribution, will give you a hint on which files to compile -for Python. Not all source files are relevant -- some are platform -specific, others are only used in emergencies (e.g. getopt.c). The -Makefiles tell the story. - -You'll also need a pyconfig.h file tailored for your platform. You can -start with pyconfig.h.in, read the comments and turn on definitions that -apply to your platform. - -And you'll need a config.c file, which lists the built-in modules you -support. Start with Modules/config.c.in. - -Finally, you'll run into some things that aren't supported on your -target platform. Forget about the posix module for now -- simply take -it out of the config.c file. - -Bang on it until you get a >>> prompt. (You may have to disable the -importing of "site.py" by passing the -S option.) - -Then bang on it until it executes very simple Python statements. - -Now bang on it some more. At some point you'll want to use the os -module; this is the time to start thinking about what to do with the -posix module. It's okay to simply #ifdef out those functions that -cause problems; the remaining ones will be quite useful. +This document is moved to https://docs.python.org/devguide/faq.html#how-do-i-port-python-to-a-new-platform diff --git a/Misc/README b/Misc/README index e7780a2f315d..ddb8f3f97590 100644 --- a/Misc/README +++ b/Misc/README @@ -21,7 +21,6 @@ README The file you're reading now README.AIX Information about using Python on AIX README.coverity Information about running Coverity's Prevent on Python README.valgrind Information for Valgrind users, see valgrind-python.supp -RPM (Old) tools to build RPMs SpecialBuilds.txt Describes extra symbols you can set for debug builds svnmap.txt Map of old SVN revs and branches to hg changeset ids valgrind-python.supp Valgrind suppression file, see README.valgrind diff --git a/Misc/RPM/README b/Misc/RPM/README deleted file mode 100644 index d883c95e85b9..000000000000 --- a/Misc/RPM/README +++ /dev/null @@ -1,33 +0,0 @@ -This directory contains support file used to build RPM releases of -Python. Its contents are maintained by Sean Reifschneider -. - -If you wish to build RPMs from the base Python release tar-file, note -that you will have to download the -"doc//html-.tar.bz2" -file from python.org and place it into your "SOURCES" directory for -the build to complete. This is the same directory that you place the -Python-2.3.1 release tar-file in. You can then use the ".spec" file in -this directory to build RPMs. - -You may also wish to pursue RPMs provided by distribution makers to see if -they have one suitable for your uses. If, for example, you just want a -slightly newer version of Python than what the distro provides, you could -pick up the closest SRPM your distro provides, and then modify it to -the newer version, and build that. It may be as simple as just changing -the "version" information in the spec file (or it may require fixing -patches). - -NOTE: I am *NOT* recommending just using the binary RPM, and never do an -install with "--force" or "--nodeps". - -Also worth pursuing may be newer versions provided by similar distros. For -example, a Python 3 SRPM from Fedora may be a good baseline to try building -on CentOS. - -Many newer SRPMs won't install on older distros because of format changes. -You can manually extract these SRPMS with: - - mkdir foo - cd foo - rpm2cpio <../python3-*.src.rpm | cpio -ivd diff --git a/Misc/RPM/python-3.4.spec b/Misc/RPM/python-3.4.spec deleted file mode 100644 index 16e009c58c06..000000000000 --- a/Misc/RPM/python-3.4.spec +++ /dev/null @@ -1,389 +0,0 @@ -########################## -# User-modifiable configs -########################## - -# Is the resulting package and the installed binary named "python" or -# "python2"? -#WARNING: Commenting out doesn't work. Last line is what's used. -%define config_binsuffix none -%define config_binsuffix 2.6 - -# Build tkinter? "auto" enables it if /usr/bin/wish exists. -#WARNING: Commenting out doesn't work. Last line is what's used. -%define config_tkinter no -%define config_tkinter yes -%define config_tkinter auto - -# Use pymalloc? The last line (commented or not) determines wether -# pymalloc is used. -#WARNING: Commenting out doesn't work. Last line is what's used. -%define config_pymalloc no -%define config_pymalloc yes - -# Enable IPV6? -#WARNING: Commenting out doesn't work. Last line is what's used. -%define config_ipv6 yes -%define config_ipv6 no - -# Build shared libraries or .a library? -#WARNING: Commenting out doesn't work. Last line is what's used. -%define config_sharedlib no -%define config_sharedlib yes - -# Location of the HTML directory. -%define config_htmldir /var/www/html/python - -################################# -# End of user-modifiable configs -################################# - -%define name python -#--start constants-- -%define version 3.4.0b1 -%define libvers 3.4 -#--end constants-- -%define release 1pydotorg -%define __prefix /usr - -# kludge to get around rpm define weirdness -%define ipv6 %(if [ "%{config_ipv6}" = yes ]; then echo --enable-ipv6; else echo --disable-ipv6; fi) -%define pymalloc %(if [ "%{config_pymalloc}" = yes ]; then echo --with-pymalloc; else echo --without-pymalloc; fi) -%define binsuffix %(if [ "%{config_binsuffix}" = none ]; then echo ; else echo "%{config_binsuffix}"; fi) -%define include_tkinter %(if [ \\( "%{config_tkinter}" = auto -a -f /usr/bin/wish \\) -o "%{config_tkinter}" = yes ]; then echo 1; else echo 0; fi) -%define libdirname %(( uname -m | egrep -q '_64$' && [ -d /usr/lib64 ] && echo lib64 ) || echo lib) -%define sharedlib %(if [ "%{config_sharedlib}" = yes ]; then echo --enable-shared; else echo ; fi) -%define include_sharedlib %(if [ "%{config_sharedlib}" = yes ]; then echo 1; else echo 0; fi) - -# detect if documentation is available -%define include_docs %(if [ -f "%{_sourcedir}/html-%{version}.tar.bz2" ]; then echo 1; else echo 0; fi) - -Summary: An interpreted, interactive, object-oriented programming language. -Name: %{name}%{binsuffix} -Version: %{version} -Release: %{release} -License: PSF -Group: Development/Languages -Source: Python-%{version}.tar.bz2 -%if %{include_docs} -Source1: html-%{version}.tar.bz2 -%endif -BuildRoot: %{_tmppath}/%{name}-%{version}-root -BuildPrereq: expat-devel -BuildPrereq: db4-devel -BuildPrereq: gdbm-devel -BuildPrereq: sqlite-devel -Prefix: %{__prefix} -Packager: Sean Reifschneider - -%description -Python is an interpreted, interactive, object-oriented programming -language. It incorporates modules, exceptions, dynamic typing, very high -level dynamic data types, and classes. Python combines remarkable power -with very clear syntax. It has interfaces to many system calls and -libraries, as well as to various window systems, and is extensible in C or -C++. It is also usable as an extension language for applications that need -a programmable interface. Finally, Python is portable: it runs on many -brands of UNIX, on PCs under Windows, MS-DOS, and on the Mac. - -%package devel -Summary: The libraries and header files needed for Python extension development. -Prereq: python%{binsuffix} = %{PACKAGE_VERSION} -Group: Development/Libraries - -%description devel -The Python programming language's interpreter can be extended with -dynamically loaded extensions and can be embedded in other programs. -This package contains the header files and libraries needed to do -these types of tasks. - -Install python-devel if you want to develop Python extensions. The -python package will also need to be installed. You'll probably also -want to install the python-docs package, which contains Python -documentation. - -%if %{include_tkinter} -%package tkinter -Summary: A graphical user interface for the Python scripting language. -Group: Development/Languages -Prereq: python%{binsuffix} = %{PACKAGE_VERSION}-%{release} - -%description tkinter -The Tkinter (Tk interface) program is an graphical user interface for -the Python scripting language. - -You should install the tkinter package if you'd like to use a graphical -user interface for Python programming. -%endif - -%package tools -Summary: A collection of development tools included with Python. -Group: Development/Tools -Prereq: python%{binsuffix} = %{PACKAGE_VERSION}-%{release} - -%description tools -The Python package includes several development tools that are used -to build python programs. This package contains a selection of those -tools, including the IDLE Python IDE. - -Install python-tools if you want to use these tools to develop -Python programs. You will also need to install the python and -tkinter packages. - -%if %{include_docs} -%package docs -Summary: Python-related documentation. -Group: Development/Documentation - -%description docs -Documentation relating to the Python programming language in HTML and info -formats. -%endif - -%changelog -* Mon Dec 20 2004 Sean Reifschneider [2.4-2pydotorg] -- Changing the idle wrapper so that it passes arguments to idle. - -* Tue Oct 19 2004 Sean Reifschneider [2.4b1-1pydotorg] -- Updating to 2.4. - -* Thu Jul 22 2004 Sean Reifschneider [2.3.4-3pydotorg] -- Paul Tiemann fixes for %{prefix}. -- Adding permission changes for directory as suggested by reimeika.ca -- Adding code to detect when it should be using lib64. -- Adding a define for the location of /var/www/html for docs. - -* Thu May 27 2004 Sean Reifschneider [2.3.4-2pydotorg] -- Including changes from Ian Holsman to build under Red Hat 7.3. -- Fixing some problems with the /usr/local path change. - -* Sat Mar 27 2004 Sean Reifschneider [2.3.2-3pydotorg] -- Being more agressive about finding the paths to fix for - #!/usr/local/bin/python. - -* Sat Feb 07 2004 Sean Reifschneider [2.3.3-2pydotorg] -- Adding code to remove "#!/usr/local/bin/python" from particular files and - causing the RPM build to terminate if there are any unexpected files - which have that line in them. - -* Mon Oct 13 2003 Sean Reifschneider [2.3.2-1pydotorg] -- Adding code to detect wether documentation is available to build. - -* Fri Sep 19 2003 Sean Reifschneider [2.3.1-1pydotorg] -- Updating to the 2.3.1 release. - -* Mon Feb 24 2003 Sean Reifschneider [2.3b1-1pydotorg] -- Updating to 2.3b1 release. - -* Mon Feb 17 2003 Sean Reifschneider [2.3a1-1] -- Updating to 2.3 release. - -* Sun Dec 23 2001 Sean Reifschneider -[Release 2.2-2] -- Added -docs package. -- Added "auto" config_tkinter setting which only enables tk if - /usr/bin/wish exists. - -* Sat Dec 22 2001 Sean Reifschneider -[Release 2.2-1] -- Updated to 2.2. -- Changed the extension to "2" from "2.2". - -* Tue Nov 18 2001 Sean Reifschneider -[Release 2.2c1-1] -- Updated to 2.2c1. - -* Thu Nov 1 2001 Sean Reifschneider -[Release 2.2b1-3] -- Changed the way the sed for fixing the #! in pydoc works. - -* Wed Oct 24 2001 Sean Reifschneider -[Release 2.2b1-2] -- Fixed missing "email" package, thanks to anonymous report on sourceforge. -- Fixed missing "compiler" package. - -* Mon Oct 22 2001 Sean Reifschneider -[Release 2.2b1-1] -- Updated to 2.2b1. - -* Mon Oct 9 2001 Sean Reifschneider -[Release 2.2a4-4] -- otto@balinor.mat.unimi.it mentioned that the license file is missing. - -* Sun Sep 30 2001 Sean Reifschneider -[Release 2.2a4-3] -- Ignacio Vazquez-Abrams pointed out that I had a spruious double-quote in - the spec files. Thanks. - -* Wed Jul 25 2001 Sean Reifschneider -[Release 2.2a1-1] -- Updated to 2.2a1 release. -- Changed idle and pydoc to use binsuffix macro - -####### -# PREP -####### -%prep -%setup -n Python-%{version} - -######## -# BUILD -######## -%build -echo "Setting for ipv6: %{ipv6}" -echo "Setting for pymalloc: %{pymalloc}" -echo "Setting for binsuffix: %{binsuffix}" -echo "Setting for include_tkinter: %{include_tkinter}" -echo "Setting for libdirname: %{libdirname}" -echo "Setting for sharedlib: %{sharedlib}" -echo "Setting for include_sharedlib: %{include_sharedlib}" -./configure --enable-unicode=ucs4 %{sharedlib} %{ipv6} %{pymalloc} --prefix=%{__prefix} -make - -########## -# INSTALL -########## -%install -# set the install path -echo '[install_scripts]' >setup.cfg -echo 'install_dir='"${RPM_BUILD_ROOT}%{__prefix}/bin" >>setup.cfg - -[ -d "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT -mkdir -p $RPM_BUILD_ROOT%{__prefix}/%{libdirname}/python%{libvers}/lib-dynload -make prefix=$RPM_BUILD_ROOT%{__prefix} install - -# REPLACE PATH IN PYDOC -if [ ! -z "%{binsuffix}" ] -then - ( - cd $RPM_BUILD_ROOT%{__prefix}/bin - mv pydoc pydoc.old - sed 's|#!.*|#!%{__prefix}/bin/env python'%{binsuffix}'|' \ - pydoc.old >pydoc - chmod 755 pydoc - rm -f pydoc.old - ) -fi - -# add the binsuffix -if [ ! -z "%{binsuffix}" ] -then - rm -f $RPM_BUILD_ROOT%{__prefix}/bin/python[0-9a-zA-Z]* - ( cd $RPM_BUILD_ROOT%{__prefix}/bin; - for file in *; do mv "$file" "$file"%{binsuffix}; done ) - ( cd $RPM_BUILD_ROOT%{_mandir}/man1; mv python.1 python%{binsuffix}.1 ) -fi - -######## -# Tools -echo '#!%{__prefix}/bin/env python%{binsuffix}' >${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix} -echo 'import os, sys' >>${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix} -echo 'os.execvp("%{__prefix}/bin/python%{binsuffix}", ["%{__prefix}/bin/python%{binsuffix}", "%{__prefix}/lib/python%{libvers}/idlelib/idle.py"] + sys.argv[1:])' >>${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix} -echo 'print "Failed to exec Idle"' >>${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix} -echo 'sys.exit(1)' >>${RPM_BUILD_ROOT}%{__prefix}/bin/idle%{binsuffix} -chmod 755 $RPM_BUILD_ROOT%{__prefix}/bin/idle%{binsuffix} -cp -a Tools $RPM_BUILD_ROOT%{__prefix}/%{libdirname}/python%{libvers} - -# MAKE FILE LISTS -rm -f mainpkg.files -find "$RPM_BUILD_ROOT""%{__prefix}"/%{libdirname}/python%{libvers} -type f | - sed "s|^${RPM_BUILD_ROOT}|/|" | - grep -v -e '/python%{libvers}/config$' -e '_tkinter.so$' >mainpkg.files -find "$RPM_BUILD_ROOT""%{__prefix}"/bin -type f -o -type l | - sed "s|^${RPM_BUILD_ROOT}|/|" | - grep -v -e '/bin/2to3%{binsuffix}$' | - grep -v -e '/bin/pydoc%{binsuffix}$' | - grep -v -e '/bin/smtpd.py%{binsuffix}$' | - grep -v -e '/bin/idle%{binsuffix}$' >>mainpkg.files - -rm -f tools.files -find "$RPM_BUILD_ROOT""%{__prefix}"/%{libdirname}/python%{libvers}/idlelib \ - "$RPM_BUILD_ROOT""%{__prefix}"/%{libdirname}/python%{libvers}/Tools -type f | - sed "s|^${RPM_BUILD_ROOT}|/|" >tools.files -echo "%{__prefix}"/bin/2to3%{binsuffix} >>tools.files -echo "%{__prefix}"/bin/pydoc%{binsuffix} >>tools.files -echo "%{__prefix}"/bin/smtpd.py%{binsuffix} >>tools.files -echo "%{__prefix}"/bin/idle%{binsuffix} >>tools.files - -###### -# Docs -%if %{include_docs} -mkdir -p "$RPM_BUILD_ROOT"%{config_htmldir} -( - cd "$RPM_BUILD_ROOT"%{config_htmldir} - bunzip2 < %{SOURCE1} | tar x -) -%endif - -# fix the #! line in installed files -find "$RPM_BUILD_ROOT" -type f -print0 | - xargs -0 grep -l /usr/local/bin/python | while read file -do - FIXFILE="$file" - sed 's|^#!.*python|#!%{__prefix}/bin/env python'"%{binsuffix}"'|' \ - "$FIXFILE" >/tmp/fix-python-path.$$ - cat /tmp/fix-python-path.$$ >"$FIXFILE" - rm -f /tmp/fix-python-path.$$ -done - -# check to see if there are any straggling #! lines -find "$RPM_BUILD_ROOT" -type f | xargs egrep -n '^#! */usr/local/bin/python' \ - | grep ':1:#!' >/tmp/python-rpm-files.$$ || true -if [ -s /tmp/python-rpm-files.$$ ] -then - echo '*****************************************************' - cat /tmp/python-rpm-files.$$ - cat <<@EOF - ***************************************************** - There are still files referencing /usr/local/bin/python in the - install directory. They are listed above. Please fix the .spec - file and try again. If you are an end-user, you probably want - to report this to jafo-rpms@tummy.com as well. - ***************************************************** -@EOF - rm -f /tmp/python-rpm-files.$$ - exit 1 -fi -rm -f /tmp/python-rpm-files.$$ - -######## -# CLEAN -######## -%clean -[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf $RPM_BUILD_ROOT -rm -f mainpkg.files tools.files - -######## -# FILES -######## -%files -f mainpkg.files -%defattr(-,root,root) -%doc Misc/README Misc/cheatsheet Misc/Porting -%doc LICENSE Misc/ACKS Misc/HISTORY Misc/NEWS -%{_mandir}/man1/python%{binsuffix}.1* - -%attr(755,root,root) %dir %{__prefix}/include/python%{libvers} -%attr(755,root,root) %dir %{__prefix}/%{libdirname}/python%{libvers}/ -%if %{include_sharedlib} -%{__prefix}/%{libdirname}/libpython* -%endif - -%files devel -%defattr(-,root,root) -%{__prefix}/include/python%{libvers}/*.h -%{__prefix}/%{libdirname}/python%{libvers}/config - -%files -f tools.files tools -%defattr(-,root,root) - -%if %{include_tkinter} -%files tkinter -%defattr(-,root,root) -%{__prefix}/%{libdirname}/python%{libvers}/tkinter -%{__prefix}/%{libdirname}/python%{libvers}/lib-dynload/_tkinter.so* -%endif - -%if %{include_docs} -%files docs -%defattr(-,root,root) -%{config_htmldir}/* -%endif diff --git a/Misc/SpecialBuilds.txt b/Misc/SpecialBuilds.txt index 646ac2344cb3..3004174bcdca 100644 --- a/Misc/SpecialBuilds.txt +++ b/Misc/SpecialBuilds.txt @@ -13,12 +13,14 @@ Py_REF_DEBUG ------------ Turn on aggregate reference counting. This arranges that extern _Py_RefTotal -hold a count of all references, the sum of ob_refcnt across all objects. In a -debug-mode build, this is where the "8288" comes from in +hold a count of all references, the sum of ob_refcnt across all objects. +Passing ``-X showrefcount`` on the command line causes the interactive +interpreter to print the reference count total as well the number of memory +blocks allocated after each statement: >>> 23 23 - [8288 refs] + [8288 refs, 14332 blocks] >>> Note that if this count increases when you're not storing away new objects, @@ -214,12 +216,11 @@ LLTRACE Compile in support for Low Level TRACE-ing of the main interpreter loop. -When this preprocessor symbol is defined, before PyEval_EvalFrame (eval_frame in -2.3 and 2.2, eval_code2 before that) executes a frame's code it checks the -frame's global namespace for a variable "__lltrace__". If such a variable is -found, mounds of information about what the interpreter is doing are sprayed to -stdout, such as every opcode and opcode argument and values pushed onto and -popped off the value stack. +When this preprocessor symbol is defined, before PyEval_EvalFrame executes a +frame's code it checks the frame's global namespace for a variable +"__lltrace__". If such a variable is found, mounds of information about what +the interpreter is doing are sprayed to stdout, such as every opcode and opcode +argument and values pushed onto and popped off the value stack. Not useful very often, but very useful when needed. diff --git a/Misc/coverity_model.c b/Misc/coverity_model.c index 57f3aeb11adf..493e7c1b30f1 100644 --- a/Misc/coverity_model.c +++ b/Misc/coverity_model.c @@ -85,7 +85,7 @@ PyObject *PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename) } /* Python/fileutils.c */ -wchar_t *_Py_char2wchar(const char* arg, size_t *size) +wchar_t *Py_DecodeLocale(const char* arg, size_t *size) { wchar_t *w; __coverity_tainted_data_sink__(arg); @@ -122,7 +122,8 @@ static long r_long(RFILE *p) /* Coverity doesn't understand that fdopendir() may take ownership of fd. */ -DIR *fdopendir(int fd) { +DIR *fdopendir(int fd) +{ DIR *d; if (d) { __coverity_close__(fd); @@ -130,3 +131,58 @@ DIR *fdopendir(int fd) { return d; } +/* Modules/_datetime.c + * + * Coverity thinks that the input values for these function come from a + * tainted source PyDateTime_DATE_GET_* macros use bit shifting. + */ +static PyObject * +build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag) +{ + PyObject *result; + + __coverity_tainted_data_sanitize__(y); + __coverity_tainted_data_sanitize__(m); + __coverity_tainted_data_sanitize__(d); + __coverity_tainted_data_sanitize__(hh); + __coverity_tainted_data_sanitize__(mm); + __coverity_tainted_data_sanitize__(ss); + __coverity_tainted_data_sanitize__(dstflag); + + return result; +} + +static int +ymd_to_ord(int year, int month, int day) +{ + int ord = 0; + + __coverity_tainted_data_sanitize__(year); + __coverity_tainted_data_sanitize__(month); + __coverity_tainted_data_sanitize__(day); + + return ord; +} + +static int +normalize_date(int *year, int *month, int *day) +{ + __coverity_tainted_data_sanitize__(*year); + __coverity_tainted_data_sanitize__(*month); + __coverity_tainted_data_sanitize__(*day); + + return 0; +} + +static int +weekday(int year, int month, int day) +{ + int w = 0; + + __coverity_tainted_data_sanitize__(year); + __coverity_tainted_data_sanitize__(month); + __coverity_tainted_data_sanitize__(day); + + return w; +} + diff --git a/Misc/gdbinit b/Misc/gdbinit index 9484b51824a3..3b6fe50ef931 100644 --- a/Misc/gdbinit +++ b/Misc/gdbinit @@ -150,10 +150,10 @@ end # generally useful macro to print a Unicode string def pu - set $uni = $arg0 + set $uni = $arg0 set $i = 0 while (*$uni && $i++<100) - if (*$uni < 0x80) + if (*$uni < 0x80) print *(char*)$uni++ else print /x *(short*)$uni++ diff --git a/Misc/python-config.in b/Misc/python-config.in index 0b9b5dc4413f..e13da7543c9f 100644 --- a/Misc/python-config.in +++ b/Misc/python-config.in @@ -47,8 +47,9 @@ for opt in opt_flags: print(' '.join(flags)) elif opt in ('--libs', '--ldflags'): - libs = getvar('LIBS').split() + getvar('SYSLIBS').split() - libs.append('-lpython' + pyver + sys.abiflags) + libs = ['-lpython' + pyver + sys.abiflags] + libs += getvar('LIBS').split() + libs += getvar('SYSLIBS').split() # add the prefix/lib/pythonX.Y/config dir, but only if there is no # shared library in prefix/lib/. if opt == '--ldflags': diff --git a/Misc/python-config.sh.in b/Misc/python-config.sh.in index f5a3dbebeaa2..30c692787100 100644 --- a/Misc/python-config.sh.in +++ b/Misc/python-config.sh.in @@ -40,7 +40,7 @@ LIBM="@LIBM@" LIBC="@LIBC@" SYSLIBS="$LIBM $LIBC" ABIFLAGS="@ABIFLAGS@" -LIBS="@LIBS@ $SYSLIBS -lpython${VERSION}${ABIFLAGS}" +LIBS="-lpython${VERSION}${ABIFLAGS} @LIBS@ $SYSLIBS" BASECFLAGS="@BASECFLAGS@" LDLIBRARY="@LDLIBRARY@" LINKFORSHARED="@LINKFORSHARED@" @@ -49,7 +49,7 @@ PY_ENABLE_SHARED="@PY_ENABLE_SHARED@" LDVERSION="@LDVERSION@" LIBDEST=${prefix}/lib/python${VERSION} LIBPL=$(echo "@LIBPL@" | sed "s#$prefix_build#$prefix_real#") -SO="@SO@" +SO="@EXT_SUFFIX@" PYTHONFRAMEWORK="@PYTHONFRAMEWORK@" INCDIR="-I$includedir/python${VERSION}${ABIFLAGS}" PLATINCDIR="-I$includedir/python${VERSION}${ABIFLAGS}" diff --git a/Misc/python.man b/Misc/python.man index 52aedee5bf0b..6dbdba9e5fe1 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -87,8 +87,7 @@ python \- an interpreted, interactive, object-oriented programming language .SH DESCRIPTION Python is an interpreted, interactive, object-oriented programming language that combines remarkable power with very clear syntax. -For an introduction to programming in Python you are referred to the -Python Tutorial. +For an introduction to programming in Python, see the Python Tutorial. The Python Library Reference documents built-in and standard types, constants, functions and modules. Finally, the Python Reference Manual describes the syntax and @@ -104,10 +103,10 @@ Python is also adaptable as an extension language for existing applications. See the internal documentation for hints. .PP -Documentation for installed Python modules and packages can be -viewed by running the +Documentation for installed Python modules and packages can be +viewed by running the .B pydoc -program. +program. .SH COMMAND LINE OPTIONS .TP .B \-B @@ -143,30 +142,27 @@ useful to inspect global variables or a stack trace when a script raises an exception. .TP .B \-I -Run Python in isolated mode. This also implies \fB\-E\fP and \fB\-S\fP. In +Run Python in isolated mode. This also implies \fB\-E\fP and \fB\-s\fP. In isolated mode sys.path contains neither the script’s directory nor the user’s site-packages directory. All PYTHON* environment variables are ignored, too. Further restrictions may be imposed to prevent the user from injecting malicious code. .TP .BI "\-m " module-name -Searches -.I sys.path -for the named module and runs the corresponding -.I .py +Searches +.I sys.path +for the named module and runs the corresponding +.I .py file as a script. .TP .B \-O -Turn on basic optimizations. This changes the filename extension for -compiled (bytecode) files from -.I .pyc -to \fI.pyo\fP. Given twice, causes docstrings to be discarded. +Turn on basic optimizations. Given twice, causes docstrings to be discarded. .TP .B \-OO Discard docstrings in addition to the \fB-O\fP optimizations. .TP .B \-q -Do not print the version and copyright messages. These messages are +Do not print the version and copyright messages. These messages are also suppressed in non-interactive mode. .TP .B \-s @@ -193,7 +189,7 @@ The text I/O layer will still be line-buffered. .B \-v Print a message each time a module is initialized, showing the place (filename or built-in module) from which it is loaded. When given -twice, print a message for each file that is checked for when +twice, print a message for each file that is checked for when searching for a module. Also provides information on module cleanup at exit. .TP @@ -384,11 +380,6 @@ You can also change the prompts and .I sys.ps2 in this file. -.IP PYTHONY2K -Set this to a non-empty string to cause the \fItime\fP module to -require dates specified as strings to include 4-digit years, otherwise -2-digit years are converted based on rules described in the \fItime\fP -module documentation. .IP PYTHONOPTIMIZE If this is set to a non-empty string it is equivalent to specifying the \fB\-O\fP option. If set to an integer, it is equivalent to @@ -423,7 +414,7 @@ the \fB\-u\fP option. .IP PYTHONVERBOSE If this is set to a non-empty string it is equivalent to specifying the \fB\-v\fP option. If set to an integer, it is equivalent to -specifying \fB\-v\fP multiple times. +specifying \fB\-v\fP multiple times. .IP PYTHONWARNINGS If this is set to a comma-separated string it is equivalent to specifying the \fB\-W\fP option for each separate value. @@ -440,17 +431,17 @@ values. The integer must be a decimal number in the range [0,4294967295]. Specifying the value 0 will disable hash randomization. .SH AUTHOR -The Python Software Foundation: http://www.python.org/psf +The Python Software Foundation: https://www.python.org/psf/ .SH INTERNET RESOURCES -Main website: http://www.python.org/ +Main website: https://www.python.org/ .br -Documentation: http://docs.python.org/py3k/ +Documentation: https://docs.python.org/ .br -Developer resources: http://docs.python.org/devguide/ +Developer resources: https://docs.python.org/devguide/ .br -Downloads: http://python.org/download/ +Downloads: https://www.python.org/downloads/ .br -Module repository: http://pypi.python.org/ +Module repository: https://pypi.python.org/ .br Newsgroups: comp.lang.python, comp.lang.python.announce .SH LICENSING diff --git a/Modules/README b/Modules/README new file mode 100644 index 000000000000..9b79f538892f --- /dev/null +++ b/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/Modules/Setup.config.in b/Modules/Setup.config.in index 5ac2404bf8a1..adac030b6a0a 100644 --- a/Modules/Setup.config.in +++ b/Modules/Setup.config.in @@ -7,7 +7,7 @@ @USE_THREAD_MODULE@_thread _threadmodule.c # The signal module -@USE_SIGNAL_MODULE@signal signalmodule.c +@USE_SIGNAL_MODULE@_signal signalmodule.c # The rest of the modules previously listed in this file are built # by the setup.py script in Python 2.1 and later. diff --git a/Modules/Setup.dist b/Modules/Setup.dist index 01fb85ffc368..06ba6adf24e3 100644 --- a/Modules/Setup.dist +++ b/Modules/Setup.dist @@ -91,7 +91,7 @@ SITEPATH= TESTPATH= # Path components for machine- or system-dependent modules and shared libraries -MACHDEPPATH=:plat-$(MACHDEP) +MACHDEPPATH=:$(PLATDIR) EXTRAMACHDEPPATH= COREPYTHONPATH=$(DESTPATH)$(SITEPATH)$(TESTPATH)$(MACHDEPPATH)$(EXTRAMACHDEPPATH) @@ -118,6 +118,7 @@ _collections _collectionsmodule.c # Container types itertools itertoolsmodule.c # Functions creating iterators for efficient looping atexit atexitmodule.c # Register functions to be run at interpreter-shutdown _stat _stat.c # stat.h interface +time timemodule.c # -lm # time operations and variables # access to ISO C locale support _locale _localemodule.c # -lintl @@ -171,7 +172,6 @@ _symtable symtablemodule.c #cmath cmathmodule.c _math.c # -lm # complex math library functions #math mathmodule.c _math.c # -lm # math library functions, e.g. sin() #_struct _struct.c # binary structure packing/unpacking -#time timemodule.c # -lm # time operations and variables #_weakref _weakref.c # basic weak reference support #_testcapi _testcapimodule.c # Python C API test module #_random _randommodule.c # Random number generator diff --git a/Modules/_bz2module.c b/Modules/_bz2module.c index fd05de0a27c6..7dfd3072dc26 100644 --- a/Modules/_bz2module.c +++ b/Modules/_bz2module.c @@ -51,11 +51,21 @@ typedef struct { 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; #ifdef WITH_THREAD PyThread_type_lock lock; #endif } BZ2Decompressor; +static PyTypeObject BZ2Compressor_Type; +static PyTypeObject BZ2Decompressor_Type; /* Helper functions. */ @@ -109,19 +119,23 @@ catch_bz2_error(int bzerror) } #if BUFSIZ < 8192 -#define SMALLCHUNK 8192 +#define INITIAL_BUFFER_SIZE 8192 #else -#define SMALLCHUNK BUFSIZ +#define INITIAL_BUFFER_SIZE BUFSIZ #endif static int -grow_buffer(PyObject **buf) +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 */ @@ -140,14 +154,14 @@ compress(BZ2Compressor *c, char *data, size_t len, int action) size_t data_size = 0; PyObject *result; - result = PyBytes_FromStringAndSize(NULL, SMALLCHUNK); + 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 = SMALLCHUNK; + c->bzs.avail_out = INITIAL_BUFFER_SIZE; for (;;) { char *this_out; int bzerror; @@ -166,7 +180,7 @@ compress(BZ2Compressor *c, char *data, size_t len, int action) if (c->bzs.avail_out == 0) { size_t buffer_left = PyBytes_GET_SIZE(result) - data_size; if (buffer_left == 0) { - if (grow_buffer(&result) < 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; @@ -186,7 +200,7 @@ compress(BZ2Compressor *c, char *data, size_t len, int action) if (action == BZ_FINISH && bzerror == BZ_STREAM_END) break; } - if (data_size != PyBytes_GET_SIZE(result)) + if (data_size != (size_t)PyBytes_GET_SIZE(result)) if (_PyBytes_Resize(&result, data_size) < 0) goto error; return result; @@ -196,44 +210,57 @@ compress(BZ2Compressor *c, char *data, size_t len, int action) return NULL; } -PyDoc_STRVAR(BZ2Compressor_compress__doc__, -"compress(data) -> bytes\n" -"\n" -"Provide data to the compressor object. Returns a chunk of\n" -"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.\n"); +/*[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 * -BZ2Compressor_compress(BZ2Compressor *self, PyObject *args) +_bz2_BZ2Compressor_compress_impl(BZ2Compressor *self, Py_buffer *data) +/*[clinic end generated code: output=59365426e941fbcc input=85c963218070fc4c]*/ { - Py_buffer buffer; PyObject *result = NULL; - if (!PyArg_ParseTuple(args, "y*:compress", &buffer)) - return NULL; - ACQUIRE_LOCK(self); if (self->flushed) PyErr_SetString(PyExc_ValueError, "Compressor has been flushed"); else - result = compress(self, buffer.buf, buffer.len, BZ_RUN); + result = compress(self, data->buf, data->len, BZ_RUN); RELEASE_LOCK(self); - PyBuffer_Release(&buffer); return result; } -PyDoc_STRVAR(BZ2Compressor_flush__doc__, -"flush() -> bytes\n" -"\n" -"Finish the compression process. Returns the compressed data left\n" -"in internal buffers.\n" -"\n" -"The compressor object may not be used after this method is called.\n"); +/*[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 * -BZ2Compressor_flush(BZ2Compressor *self, PyObject *noargs) +_bz2_BZ2Compressor_flush_impl(BZ2Compressor *self) +/*[clinic end generated code: output=3ef03fc1b092a701 input=d64405d3c6f76691]*/ { PyObject *result = NULL; @@ -274,14 +301,24 @@ 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 -BZ2Compressor_init(BZ2Compressor *self, PyObject *args, PyObject *kwargs) +_bz2_BZ2Compressor___init___impl(BZ2Compressor *self, int compresslevel) +/*[clinic end generated code: output=c4e6adfd02963827 input=4e1ff7b8394b6e9a]*/ { - int compresslevel = 9; int bzerror; - if (!PyArg_ParseTuple(args, "|i:BZ2Compressor", &compresslevel)) - return -1; if (!(1 <= compresslevel && compresslevel <= 9)) { PyErr_SetString(PyExc_ValueError, "compresslevel must be between 1 and 9"); @@ -325,22 +362,12 @@ BZ2Compressor_dealloc(BZ2Compressor *self) } static PyMethodDef BZ2Compressor_methods[] = { - {"compress", (PyCFunction)BZ2Compressor_compress, METH_VARARGS, - BZ2Compressor_compress__doc__}, - {"flush", (PyCFunction)BZ2Compressor_flush, METH_NOARGS, - BZ2Compressor_flush__doc__}, + _BZ2_BZ2COMPRESSOR_COMPRESS_METHODDEF + _BZ2_BZ2COMPRESSOR_FLUSH_METHODDEF {"__getstate__", (PyCFunction)BZ2Compressor_getstate, METH_NOARGS}, {NULL} }; -PyDoc_STRVAR(BZ2Compressor__doc__, -"BZ2Compressor(compresslevel=9)\n" -"\n" -"Create a compressor object for compressing data incrementally.\n" -"\n" -"compresslevel, if given, must be a number between 1 and 9.\n" -"\n" -"For one-shot compression, use the compress() function instead.\n"); static PyTypeObject BZ2Compressor_Type = { PyVarObject_HEAD_INIT(NULL, 0) @@ -363,7 +390,7 @@ static PyTypeObject BZ2Compressor_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ - BZ2Compressor__doc__, /* tp_doc */ + _bz2_BZ2Compressor___init____doc__, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -378,7 +405,7 @@ static PyTypeObject BZ2Compressor_Type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)BZ2Compressor_init, /* tp_init */ + _bz2_BZ2Compressor___init__, /* tp_init */ 0, /* tp_alloc */ PyType_GenericNew, /* tp_new */ }; @@ -386,64 +413,66 @@ static PyTypeObject BZ2Compressor_Type = { /* BZ2Decompressor class. */ -static PyObject * -decompress(BZ2Decompressor *d, char *data, size_t len) +/* 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) { - size_t data_size = 0; + /* 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; - result = PyBytes_FromStringAndSize(NULL, SMALLCHUNK); + 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 result; - d->bzs.next_in = data; - /* On a 64-bit system, len might not fit in avail_in (an unsigned int). - Do decompression in chunks of no more than UINT_MAX bytes each. */ - d->bzs.avail_in = (unsigned int)Py_MIN(len, UINT_MAX); - len -= d->bzs.avail_in; - d->bzs.next_out = PyBytes_AS_STRING(result); - d->bzs.avail_out = SMALLCHUNK; + return NULL; + + bzs->next_out = PyBytes_AS_STRING(result); for (;;) { - char *this_out; - int bzerror; + 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 - this_out = d->bzs.next_out; - bzerror = BZ2_bzDecompress(&d->bzs); - data_size += d->bzs.next_out - this_out; + 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(bzerror)) + if (catch_bz2_error(bzret)) goto error; - if (bzerror == BZ_STREAM_END) { + if (bzret == BZ_STREAM_END) { d->eof = 1; - len += d->bzs.avail_in; - if (len > 0) { /* Save leftover input to unused_data */ - Py_CLEAR(d->unused_data); - d->unused_data = PyBytes_FromStringAndSize(d->bzs.next_in, len); - if (d->unused_data == NULL) - goto error; - } break; - } - if (d->bzs.avail_in == 0) { - if (len == 0) + } else if (d->bzs_avail_in_real == 0) { + break; + } else if (bzs->avail_out == 0) { + if (data_size == max_length) break; - d->bzs.avail_in = (unsigned int)Py_MIN(len, UINT_MAX); - len -= d->bzs.avail_in; - } - if (d->bzs.avail_out == 0) { - size_t buffer_left = PyBytes_GET_SIZE(result) - data_size; - if (buffer_left == 0) { - if (grow_buffer(&result) < 0) - goto error; - d->bzs.next_out = PyBytes_AS_STRING(result) + data_size; - buffer_left = PyBytes_GET_SIZE(result) - data_size; - } - d->bzs.avail_out = (unsigned int)Py_MIN(buffer_left, UINT_MAX); + 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) < 0) + if (_PyBytes_Resize(&result, data_size) == -1) goto error; + return result; error: @@ -451,32 +480,152 @@ decompress(BZ2Decompressor *d, char *data, size_t len) return NULL; } -PyDoc_STRVAR(BZ2Decompressor_decompress__doc__, -"decompress(data) -> bytes\n" -"\n" -"Provide data to the decompressor object. Returns a chunk of\n" -"decompressed data if possible, or b'' otherwise.\n" -"\n" -"Attempting to decompress data after the end of stream is reached\n" -"raises an EOFError. Any data found after the end of the stream\n" -"is ignored and saved in the unused_data attribute.\n"); static PyObject * -BZ2Decompressor_decompress(BZ2Decompressor *self, PyObject *args) +decompress(BZ2Decompressor *d, char *data, size_t len, Py_ssize_t max_length) { - Py_buffer buffer; - PyObject *result = NULL; + 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; - if (!PyArg_ParseTuple(args, "y*:decompress", &buffer)) + 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) return NULL; + if (d->eof) { + d->needs_input = 0; + if (d->bzs_avail_in_real > 0) { + Py_CLEAR(d->unused_data); + 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 + + self: self(type="BZ2Decompressor *") + 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=9558b424c8b00516]*/ +{ + PyObject *result = NULL; + ACQUIRE_LOCK(self); if (self->eof) PyErr_SetString(PyExc_EOFError, "End of stream already reached"); else - result = decompress(self, buffer.buf, buffer.len); + result = decompress(self, data->buf, data->len, max_length); RELEASE_LOCK(self); - PyBuffer_Release(&buffer); return result; } @@ -488,14 +637,20 @@ BZ2Decompressor_getstate(BZ2Decompressor *self, PyObject *noargs) return NULL; } +/*[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 -BZ2Decompressor_init(BZ2Decompressor *self, PyObject *args, PyObject *kwargs) +_bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self) +/*[clinic end generated code: output=e4d2b9bb866ab8f1 input=95f6500dcda60088]*/ { int bzerror; - if (!PyArg_ParseTuple(args, ":BZ2Decompressor")) - return -1; - #ifdef WITH_THREAD self->lock = PyThread_allocate_lock(); if (self->lock == NULL) { @@ -504,7 +659,11 @@ BZ2Decompressor_init(BZ2Decompressor *self, PyObject *args, PyObject *kwargs) } #endif - self->unused_data = PyBytes_FromStringAndSize("", 0); + self->needs_input = 1; + self->bzs_avail_in_real = 0; + self->input_buffer = NULL; + self->input_buffer_size = 0; + self->unused_data = PyBytes_FromStringAndSize(NULL, 0); if (self->unused_data == NULL) goto error; @@ -526,6 +685,8 @@ BZ2Decompressor_init(BZ2Decompressor *self, PyObject *args, PyObject *kwargs) 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); #ifdef WITH_THREAD @@ -536,8 +697,7 @@ BZ2Decompressor_dealloc(BZ2Decompressor *self) } static PyMethodDef BZ2Decompressor_methods[] = { - {"decompress", (PyCFunction)BZ2Decompressor_decompress, METH_VARARGS, - BZ2Decompressor_decompress__doc__}, + _BZ2_BZ2DECOMPRESSOR_DECOMPRESS_METHODDEF {"__getstate__", (PyCFunction)BZ2Decompressor_getstate, METH_NOARGS}, {NULL} }; @@ -548,21 +708,19 @@ PyDoc_STRVAR(BZ2Decompressor_eof__doc__, 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} }; -PyDoc_STRVAR(BZ2Decompressor__doc__, -"BZ2Decompressor()\n" -"\n" -"Create a decompressor object for decompressing data incrementally.\n" -"\n" -"For one-shot decompression, use the decompress() function instead.\n"); - static PyTypeObject BZ2Decompressor_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_bz2.BZ2Decompressor", /* tp_name */ @@ -584,7 +742,7 @@ static PyTypeObject BZ2Decompressor_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ - BZ2Decompressor__doc__, /* tp_doc */ + _bz2_BZ2Decompressor___init____doc__, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -599,7 +757,7 @@ static PyTypeObject BZ2Decompressor_Type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)BZ2Decompressor_init, /* tp_init */ + _bz2_BZ2Decompressor___init__, /* tp_init */ 0, /* tp_alloc */ PyType_GenericNew, /* tp_new */ }; diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c index 0b093ab19fcb..7575773f455a 100644 --- a/Modules/_codecsmodule.c +++ b/Modules/_codecsmodule.c @@ -42,18 +42,30 @@ Copyright (c) Corporation for National Research Initiatives. #include #endif +/*[clinic input] +module _codecs +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e1390e3da3cb9deb]*/ + +#include "clinic/_codecsmodule.c.h" + /* --- Registry ----------------------------------------------------------- */ -PyDoc_STRVAR(register__doc__, -"register(search_function)\n\ -\n\ -Register a codec search function. Search functions are expected to take\n\ -one argument, the encoding name in all lower case letters, and return\n\ -a tuple of functions (encoder, decoder, stream_reader, stream_writer)\n\ -(or a CodecInfo object)."); +/*[clinic input] +_codecs.register + search_function: object + / -static -PyObject *codec_register(PyObject *self, PyObject *search_function) +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(PyModuleDef *module, PyObject *search_function) +/*[clinic end generated code: output=d17608b6ad380eb8 input=369578467955cae4]*/ { if (PyCodec_Register(search_function)) return NULL; @@ -61,122 +73,140 @@ PyObject *codec_register(PyObject *self, PyObject *search_function) Py_RETURN_NONE; } -PyDoc_STRVAR(lookup__doc__, -"lookup(encoding) -> CodecInfo\n\ -\n\ -Looks up a codec tuple in the Python codec registry and returns\n\ -a CodecInfo object."); - -static -PyObject *codec_lookup(PyObject *self, PyObject *args) -{ - char *encoding; +/*[clinic input] +_codecs.lookup + encoding: str + / - if (!PyArg_ParseTuple(args, "s:lookup", &encoding)) - return NULL; +Looks up a codec tuple in the Python codec registry and returns a CodecInfo object. +[clinic start generated code]*/ +static PyObject * +_codecs_lookup_impl(PyModuleDef *module, const char *encoding) +/*[clinic end generated code: output=798e41aff0c04ef6 input=3c572c0db3febe9c]*/ +{ return _PyCodec_Lookup(encoding); } -PyDoc_STRVAR(encode__doc__, -"encode(obj, [encoding[,errors]]) -> object\n\ -\n\ -Encodes obj using the codec registered for encoding. encoding defaults\n\ -to the default encoding. errors may be given to set a different error\n\ -handling scheme. Default is 'strict' meaning that encoding errors raise\n\ -a ValueError. Other possible values are 'ignore', 'replace' and\n\ -'xmlcharrefreplace' as well as any other name registered with\n\ -codecs.register_error that can handle ValueErrors."); +/*[clinic input] +_codecs.encode + obj: object + encoding: str(c_default="NULL") = "utf-8" + errors: str(c_default="NULL") = "strict" -static PyObject * -codec_encode(PyObject *self, PyObject *args) -{ - const char *encoding = NULL; - const char *errors = NULL; - PyObject *v; +Encodes obj using the codec registered for encoding. - if (!PyArg_ParseTuple(args, "O|ss:encode", &v, &encoding, &errors)) - return NULL; +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(PyModuleDef *module, PyObject *obj, const char *encoding, + const char *errors) +/*[clinic end generated code: output=5c073f62249c8d7c input=cd5b685040ff61f0]*/ +{ if (encoding == NULL) encoding = PyUnicode_GetDefaultEncoding(); /* Encode via the codec registry */ - return PyCodec_Encode(v, encoding, errors); + return PyCodec_Encode(obj, encoding, errors); } -PyDoc_STRVAR(decode__doc__, -"decode(obj, [encoding[,errors]]) -> object\n\ -\n\ -Decodes obj using the codec registered for encoding. encoding defaults\n\ -to the default encoding. errors may be given to set a different error\n\ -handling scheme. Default is 'strict' meaning that encoding errors raise\n\ -a ValueError. Other possible values are 'ignore' and 'replace'\n\ -as well as any other name registered with codecs.register_error that is\n\ -able to handle ValueErrors."); +/*[clinic input] +_codecs.decode + obj: object + encoding: str(c_default="NULL") = "utf-8" + errors: str(c_default="NULL") = "strict" -static PyObject * -codec_decode(PyObject *self, PyObject *args) -{ - const char *encoding = NULL; - const char *errors = NULL; - PyObject *v; +Decodes obj using the codec registered for encoding. - if (!PyArg_ParseTuple(args, "O|ss:decode", &v, &encoding, &errors)) - return NULL; +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(PyModuleDef *module, PyObject *obj, const char *encoding, + const char *errors) +/*[clinic end generated code: output=c81cbf6189a7f878 input=7702c0cc2fa1add6]*/ +{ if (encoding == NULL) encoding = PyUnicode_GetDefaultEncoding(); /* Decode via the codec registry */ - return PyCodec_Decode(v, encoding, errors); + 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(PyModuleDef *module, const char *encoding) +/*[clinic end generated code: output=b56a9b99d2d28080 input=18d5d92d0e386c38]*/ +{ + if (_PyCodec_Forget(encoding) < 0) { + return NULL; + }; + Py_RETURN_NONE; +} + static -PyObject *codec_tuple(PyObject *unicode, +PyObject *codec_tuple(PyObject *decoded, Py_ssize_t len) { - PyObject *v; - if (unicode == NULL) + if (decoded == NULL) return NULL; - v = Py_BuildValue("On", unicode, len); - Py_DECREF(unicode); - return v; + return Py_BuildValue("Nn", decoded, len); } /* --- String codecs ------------------------------------------------------ */ +/*[clinic input] +_codecs.escape_decode + data: Py_buffer(accept={str, buffer}) + errors: str(accept={str, NoneType}) = NULL + / +[clinic start generated code]*/ + static PyObject * -escape_decode(PyObject *self, - PyObject *args) +_codecs_escape_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors) +/*[clinic end generated code: output=648fa3e78d03e658 input=0018edfd99db714d]*/ { - const char *errors = NULL; - const char *data; - Py_ssize_t size; - - if (!PyArg_ParseTuple(args, "s#|z:escape_decode", - &data, &size, &errors)) - return NULL; - return codec_tuple(PyBytes_DecodeEscape(data, size, errors, 0, NULL), - size); + 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}) = NULL + / +[clinic start generated code]*/ + static PyObject * -escape_encode(PyObject *self, - PyObject *args) +_codecs_escape_encode_impl(PyModuleDef *module, PyObject *data, + const char *errors) +/*[clinic end generated code: output=fcd6f34fe4111c50 input=da9ded00992f32f2]*/ { - PyObject *str; Py_ssize_t size; Py_ssize_t newsize; - const char *errors = NULL; PyObject *v; - if (!PyArg_ParseTuple(args, "O!|z:escape_encode", - &PyBytes_Type, &str, &errors)) - return NULL; - - size = PyBytes_GET_SIZE(str); + size = PyBytes_GET_SIZE(data); if (size > PY_SSIZE_T_MAX / 4) { PyErr_SetString(PyExc_OverflowError, "string is too large to encode"); @@ -196,7 +226,7 @@ escape_encode(PyObject *self, 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(str)[i]; + c = PyBytes_AS_STRING(data)[i]; if (c == '\'' || c == '\\') *p++ = '\\', *p++ = c; else if (c == '\t') @@ -224,20 +254,18 @@ escape_encode(PyObject *self, } /* --- Decoder ------------------------------------------------------------ */ +/*[clinic input] +_codecs.unicode_internal_decode + obj: object + errors: str(accept={str, NoneType}) = NULL + / +[clinic start generated code]*/ static PyObject * -unicode_internal_decode(PyObject *self, - PyObject *args) +_codecs_unicode_internal_decode_impl(PyModuleDef *module, PyObject *obj, + const char *errors) +/*[clinic end generated code: output=9fe47c2cd8807d92 input=8d57930aeda170c6]*/ { - PyObject *obj; - const char *errors = NULL; - const char *data; - Py_ssize_t size; - - if (!PyArg_ParseTuple(args, "O|z:unicode_internal_decode", - &obj, &errors)) - return NULL; - if (PyUnicode_Check(obj)) { if (PyUnicode_READY(obj) < 0) return NULL; @@ -245,128 +273,122 @@ unicode_internal_decode(PyObject *self, return codec_tuple(obj, PyUnicode_GET_LENGTH(obj)); } else { - if (PyObject_AsReadBuffer(obj, (const void **)&data, &size)) + Py_buffer view; + PyObject *result; + if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) != 0) return NULL; - return codec_tuple(_PyUnicode_DecodeUnicodeInternal(data, size, errors), - size); + result = codec_tuple( + _PyUnicode_DecodeUnicodeInternal(view.buf, view.len, errors), + view.len); + PyBuffer_Release(&view); + return result; } } +/*[clinic input] +_codecs.utf_7_decode + data: Py_buffer + errors: str(accept={str, NoneType}) = NULL + final: int(c_default="0") = False + / +[clinic start generated code]*/ + static PyObject * -utf_7_decode(PyObject *self, - PyObject *args) +_codecs_utf_7_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int final) +/*[clinic end generated code: output=ca945e907e72e827 input=bc4d6247ecdb01e6]*/ { - Py_buffer pbuf; - const char *errors = NULL; - int final = 0; - Py_ssize_t consumed; - PyObject *decoded = NULL; - - if (!PyArg_ParseTuple(args, "y*|zi:utf_7_decode", - &pbuf, &errors, &final)) - return NULL; - consumed = pbuf.len; - - decoded = PyUnicode_DecodeUTF7Stateful(pbuf.buf, pbuf.len, errors, - final ? NULL : &consumed); - PyBuffer_Release(&pbuf); - if (decoded == NULL) - return NULL; + 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}) = NULL + final: int(c_default="0") = False + / +[clinic start generated code]*/ + static PyObject * -utf_8_decode(PyObject *self, - PyObject *args) +_codecs_utf_8_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int final) +/*[clinic end generated code: output=7309f9ff4ef5c9b6 input=39161d71e7422ee2]*/ { - Py_buffer pbuf; - const char *errors = NULL; - int final = 0; - Py_ssize_t consumed; - PyObject *decoded = NULL; - - if (!PyArg_ParseTuple(args, "y*|zi:utf_8_decode", - &pbuf, &errors, &final)) - return NULL; - consumed = pbuf.len; - - decoded = PyUnicode_DecodeUTF8Stateful(pbuf.buf, pbuf.len, errors, - final ? NULL : &consumed); - PyBuffer_Release(&pbuf); - if (decoded == NULL) - return NULL; + 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}) = NULL + final: int(c_default="0") = False + / +[clinic start generated code]*/ + static PyObject * -utf_16_decode(PyObject *self, - PyObject *args) +_codecs_utf_16_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int final) +/*[clinic end generated code: output=8d2fa0507d9bef2c input=f3cf01d1461007ce]*/ { - Py_buffer pbuf; - const char *errors = NULL; int byteorder = 0; - int final = 0; - Py_ssize_t consumed; - PyObject *decoded; - - if (!PyArg_ParseTuple(args, "y*|zi:utf_16_decode", - &pbuf, &errors, &final)) - return NULL; - consumed = pbuf.len; /* This is overwritten unless final is true. */ - decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, - &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); - if (decoded == NULL) - return NULL; + /* 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}) = NULL + final: int(c_default="0") = False + / +[clinic start generated code]*/ + static PyObject * -utf_16_le_decode(PyObject *self, - PyObject *args) +_codecs_utf_16_le_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int final) +/*[clinic end generated code: output=4fd621515ef4ce18 input=a77e3bf97335d94e]*/ { - Py_buffer pbuf; - const char *errors = NULL; int byteorder = -1; - int final = 0; - Py_ssize_t consumed; - PyObject *decoded = NULL; - - if (!PyArg_ParseTuple(args, "y*|zi:utf_16_le_decode", - &pbuf, &errors, &final)) - return NULL; - - consumed = pbuf.len; /* This is overwritten unless final is true. */ - decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, - &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); - if (decoded == NULL) - return NULL; + /* 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}) = NULL + final: int(c_default="0") = False + / +[clinic start generated code]*/ + static PyObject * -utf_16_be_decode(PyObject *self, - PyObject *args) +_codecs_utf_16_be_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int final) +/*[clinic end generated code: output=792f4eacb3e1fa05 input=606f69fae91b5563]*/ { - Py_buffer pbuf; - const char *errors = NULL; int byteorder = 1; - int final = 0; - Py_ssize_t consumed; - PyObject *decoded = NULL; - - if (!PyArg_ParseTuple(args, "y*|zi:utf_16_be_decode", - &pbuf, &errors, &final)) - return NULL; - - consumed = pbuf.len; /* This is overwritten unless final is true. */ - decoded = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, - &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); - if (decoded == NULL) - return NULL; + /* 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); } @@ -377,98 +399,94 @@ utf_16_be_decode(PyObject *self, 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}) = NULL + byteorder: int = 0 + final: int(c_default="0") = False + / +[clinic start generated code]*/ static PyObject * -utf_16_ex_decode(PyObject *self, - PyObject *args) +_codecs_utf_16_ex_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int byteorder, int final) +/*[clinic end generated code: output=f136a186dc2defa0 input=f6e7f697658c013e]*/ { - Py_buffer pbuf; - const char *errors = NULL; - int byteorder = 0; - PyObject *unicode, *tuple; - int final = 0; - Py_ssize_t consumed; + /* This is overwritten unless final is true. */ + Py_ssize_t consumed = data->len; - if (!PyArg_ParseTuple(args, "y*|zii:utf_16_ex_decode", - &pbuf, &errors, &byteorder, &final)) - return NULL; - consumed = pbuf.len; /* This is overwritten unless final is true. */ - unicode = PyUnicode_DecodeUTF16Stateful(pbuf.buf, pbuf.len, errors, - &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); - if (unicode == NULL) + PyObject *decoded = PyUnicode_DecodeUTF16Stateful(data->buf, data->len, + errors, &byteorder, + final ? NULL : &consumed); + if (decoded == NULL) return NULL; - tuple = Py_BuildValue("Oni", unicode, consumed, byteorder); - Py_DECREF(unicode); - return tuple; + return Py_BuildValue("Nni", decoded, consumed, byteorder); } +/*[clinic input] +_codecs.utf_32_decode + data: Py_buffer + errors: str(accept={str, NoneType}) = NULL + final: int(c_default="0") = False + / +[clinic start generated code]*/ + static PyObject * -utf_32_decode(PyObject *self, - PyObject *args) +_codecs_utf_32_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int final) +/*[clinic end generated code: output=b7635e55857e8efb input=86d4f41c6c2e763d]*/ { - Py_buffer pbuf; - const char *errors = NULL; int byteorder = 0; - int final = 0; - Py_ssize_t consumed; - PyObject *decoded; - - if (!PyArg_ParseTuple(args, "y*|zi:utf_32_decode", - &pbuf, &errors, &final)) - return NULL; - consumed = pbuf.len; /* This is overwritten unless final is true. */ - decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, - &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); - if (decoded == NULL) - return NULL; + /* 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}) = NULL + final: int(c_default="0") = False + / +[clinic start generated code]*/ + static PyObject * -utf_32_le_decode(PyObject *self, - PyObject *args) +_codecs_utf_32_le_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int final) +/*[clinic end generated code: output=a79d1787d8ddf988 input=d18b650772d188ba]*/ { - Py_buffer pbuf; - const char *errors = NULL; int byteorder = -1; - int final = 0; - Py_ssize_t consumed; - PyObject *decoded; - - if (!PyArg_ParseTuple(args, "y*|zi:utf_32_le_decode", - &pbuf, &errors, &final)) - return NULL; - consumed = pbuf.len; /* This is overwritten unless final is true. */ - decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, - &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); - if (decoded == NULL) - return NULL; + /* 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}) = NULL + final: int(c_default="0") = False + / +[clinic start generated code]*/ + static PyObject * -utf_32_be_decode(PyObject *self, - PyObject *args) +_codecs_utf_32_be_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int final) +/*[clinic end generated code: output=a8356b0f36779981 input=19c271b5d34926d8]*/ { - Py_buffer pbuf; - const char *errors = NULL; int byteorder = 1; - int final = 0; - Py_ssize_t consumed; - PyObject *decoded; - - if (!PyArg_ParseTuple(args, "y*|zi:utf_32_be_decode", - &pbuf, &errors, &final)) - return NULL; - consumed = pbuf.len; /* This is overwritten unless final is true. */ - decoded = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, - &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); - if (decoded == NULL) - return NULL; + /* 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); } @@ -479,167 +497,157 @@ utf_32_be_decode(PyObject *self, 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}) = NULL + byteorder: int = 0 + final: int(c_default="0") = False + / +[clinic start generated code]*/ static PyObject * -utf_32_ex_decode(PyObject *self, - PyObject *args) +_codecs_utf_32_ex_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int byteorder, int final) +/*[clinic end generated code: output=ab8c70977c1992f5 input=4af3e6ccfe34a076]*/ { - Py_buffer pbuf; - const char *errors = NULL; - int byteorder = 0; - PyObject *unicode, *tuple; - int final = 0; - Py_ssize_t consumed; - - if (!PyArg_ParseTuple(args, "y*|zii:utf_32_ex_decode", - &pbuf, &errors, &byteorder, &final)) - return NULL; - consumed = pbuf.len; /* This is overwritten unless final is true. */ - unicode = PyUnicode_DecodeUTF32Stateful(pbuf.buf, pbuf.len, errors, - &byteorder, final ? NULL : &consumed); - PyBuffer_Release(&pbuf); - if (unicode == NULL) + Py_ssize_t consumed = data->len; + PyObject *decoded = PyUnicode_DecodeUTF32Stateful(data->buf, data->len, + errors, &byteorder, + final ? NULL : &consumed); + if (decoded == NULL) return NULL; - tuple = Py_BuildValue("Oni", unicode, consumed, byteorder); - Py_DECREF(unicode); - return tuple; + return Py_BuildValue("Nni", decoded, consumed, byteorder); } +/*[clinic input] +_codecs.unicode_escape_decode + data: Py_buffer(accept={str, buffer}) + errors: str(accept={str, NoneType}) = NULL + / +[clinic start generated code]*/ + static PyObject * -unicode_escape_decode(PyObject *self, - PyObject *args) +_codecs_unicode_escape_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors) +/*[clinic end generated code: output=d1aa63f2620c4999 input=49fd27d06813a7f5]*/ { - Py_buffer pbuf; - const char *errors = NULL; - PyObject *unicode; - - if (!PyArg_ParseTuple(args, "s*|z:unicode_escape_decode", - &pbuf, &errors)) - return NULL; - - unicode = PyUnicode_DecodeUnicodeEscape(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + 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}) = NULL + / +[clinic start generated code]*/ + static PyObject * -raw_unicode_escape_decode(PyObject *self, - PyObject *args) +_codecs_raw_unicode_escape_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors) +/*[clinic end generated code: output=0bf96cc182d81379 input=770903a211434ebc]*/ { - Py_buffer pbuf; - const char *errors = NULL; - PyObject *unicode; - - if (!PyArg_ParseTuple(args, "s*|z:raw_unicode_escape_decode", - &pbuf, &errors)) - return NULL; - - unicode = PyUnicode_DecodeRawUnicodeEscape(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + 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}) = NULL + / +[clinic start generated code]*/ + static PyObject * -latin_1_decode(PyObject *self, - PyObject *args) +_codecs_latin_1_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors) +/*[clinic end generated code: output=66b916f5055aaf13 input=5cad0f1759c618ec]*/ { - Py_buffer pbuf; - PyObject *unicode; - const char *errors = NULL; - - if (!PyArg_ParseTuple(args, "y*|z:latin_1_decode", - &pbuf, &errors)) - return NULL; - - unicode = PyUnicode_DecodeLatin1(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + 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}) = NULL + / +[clinic start generated code]*/ + static PyObject * -ascii_decode(PyObject *self, - PyObject *args) +_codecs_ascii_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors) +/*[clinic end generated code: output=7f213a1b5cdafc65 input=ad1106f64037bd16]*/ { - Py_buffer pbuf; - PyObject *unicode; - const char *errors = NULL; - - if (!PyArg_ParseTuple(args, "y*|z:ascii_decode", - &pbuf, &errors)) - return NULL; - - unicode = PyUnicode_DecodeASCII(pbuf.buf, pbuf.len, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + 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}) = NULL + mapping: object = NULL + / +[clinic start generated code]*/ + static PyObject * -charmap_decode(PyObject *self, - PyObject *args) +_codecs_charmap_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, PyObject *mapping) +/*[clinic end generated code: output=87d27f365098bbae input=19712ca35c5a80e2]*/ { - Py_buffer pbuf; - PyObject *unicode; - const char *errors = NULL; - PyObject *mapping = NULL; + PyObject *decoded; - if (!PyArg_ParseTuple(args, "y*|zO:charmap_decode", - &pbuf, &errors, &mapping)) - return NULL; if (mapping == Py_None) mapping = NULL; - unicode = PyUnicode_DecodeCharmap(pbuf.buf, pbuf.len, mapping, errors); - PyBuffer_Release(&pbuf); - return codec_tuple(unicode, pbuf.len); + decoded = PyUnicode_DecodeCharmap(data->buf, data->len, mapping, errors); + return codec_tuple(decoded, data->len); } #ifdef HAVE_MBCS +/*[clinic input] +_codecs.mbcs_decode + data: Py_buffer + errors: str(accept={str, NoneType}) = NULL + final: int(c_default="0") = False + / +[clinic start generated code]*/ + static PyObject * -mbcs_decode(PyObject *self, - PyObject *args) +_codecs_mbcs_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int final) +/*[clinic end generated code: output=0ebaf3a5b20e53fa input=d492c1ca64f4fa8a]*/ { - Py_buffer pbuf; - const char *errors = NULL; - int final = 0; - Py_ssize_t consumed; - PyObject *decoded = NULL; - - if (!PyArg_ParseTuple(args, "y*|zi:mbcs_decode", - &pbuf, &errors, &final)) - return NULL; - consumed = pbuf.len; - - decoded = PyUnicode_DecodeMBCSStateful(pbuf.buf, pbuf.len, errors, - final ? NULL : &consumed); - PyBuffer_Release(&pbuf); - if (decoded == NULL) - return NULL; + 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.code_page_decode + codepage: int + data: Py_buffer + errors: str(accept={str, NoneType}) = NULL + final: int(c_default="0") = False + / +[clinic start generated code]*/ + static PyObject * -code_page_decode(PyObject *self, - PyObject *args) +_codecs_code_page_decode_impl(PyModuleDef *module, int codepage, + Py_buffer *data, const char *errors, int final) +/*[clinic end generated code: output=4318e3d9971e31ba input=4f3152a304e21d51]*/ { - Py_buffer pbuf; - const char *errors = NULL; - int final = 0; - Py_ssize_t consumed; - PyObject *decoded = NULL; - int code_page; - - if (!PyArg_ParseTuple(args, "iy*|zi:code_page_decode", - &code_page, &pbuf, &errors, &final)) - return NULL; - consumed = pbuf.len; - - decoded = PyUnicode_DecodeCodePageStateful(code_page, - pbuf.buf, pbuf.len, errors, - final ? NULL : &consumed); - PyBuffer_Release(&pbuf); - if (decoded == NULL) - return NULL; + Py_ssize_t consumed = data->len; + PyObject *decoded = PyUnicode_DecodeCodePageStateful(codepage, + data->buf, data->len, + errors, + final ? NULL : &consumed); return codec_tuple(decoded, consumed); } @@ -647,47 +655,42 @@ code_page_decode(PyObject *self, /* --- Encoder ------------------------------------------------------------ */ +/*[clinic input] +_codecs.readbuffer_encode + data: Py_buffer(accept={str, buffer}) + errors: str(accept={str, NoneType}) = NULL + / +[clinic start generated code]*/ + static PyObject * -readbuffer_encode(PyObject *self, - PyObject *args) +_codecs_readbuffer_encode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors) +/*[clinic end generated code: output=319cc24083299859 input=b7c322b89d4ab923]*/ { - Py_buffer pdata; - const char *data; - Py_ssize_t size; - const char *errors = NULL; - PyObject *result; - - if (!PyArg_ParseTuple(args, "s*|z:readbuffer_encode", - &pdata, &errors)) - return NULL; - data = pdata.buf; - size = pdata.len; - - result = PyBytes_FromStringAndSize(data, size); - PyBuffer_Release(&pdata); - return codec_tuple(result, size); + PyObject *result = PyBytes_FromStringAndSize(data->buf, data->len); + return codec_tuple(result, data->len); } +/*[clinic input] +_codecs.unicode_internal_encode + obj: object + errors: str(accept={str, NoneType}) = NULL + / +[clinic start generated code]*/ + static PyObject * -unicode_internal_encode(PyObject *self, - PyObject *args) +_codecs_unicode_internal_encode_impl(PyModuleDef *module, PyObject *obj, + const char *errors) +/*[clinic end generated code: output=be08457068ad503b input=8628f0280cf5ba61]*/ { - PyObject *obj; - const char *errors = NULL; - const char *data; - Py_ssize_t len, size; - if (PyErr_WarnEx(PyExc_DeprecationWarning, "unicode_internal codec has been deprecated", 1)) return NULL; - if (!PyArg_ParseTuple(args, "O|z:unicode_internal_encode", - &obj, &errors)) - return NULL; - if (PyUnicode_Check(obj)) { Py_UNICODE *u; + Py_ssize_t len, size; if (PyUnicode_READY(obj) < 0) return NULL; @@ -695,29 +698,37 @@ unicode_internal_encode(PyObject *self, u = PyUnicode_AsUnicodeAndSize(obj, &len); if (u == NULL) return NULL; - if (len > PY_SSIZE_T_MAX / sizeof(Py_UNICODE)) + if ((size_t)len > (size_t)PY_SSIZE_T_MAX / sizeof(Py_UNICODE)) return PyErr_NoMemory(); size = len * sizeof(Py_UNICODE); return codec_tuple(PyBytes_FromStringAndSize((const char*)u, size), PyUnicode_GET_LENGTH(obj)); } else { - if (PyObject_AsReadBuffer(obj, (const void **)&data, &size)) + Py_buffer view; + PyObject *result; + if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) != 0) return NULL; - return codec_tuple(PyBytes_FromStringAndSize(data, size), size); + result = codec_tuple(PyBytes_FromStringAndSize(view.buf, view.len), + view.len); + PyBuffer_Release(&view); + return result; } } +/*[clinic input] +_codecs.utf_7_encode + str: object + errors: str(accept={str, NoneType}) = NULL + / +[clinic start generated code]*/ + static PyObject * -utf_7_encode(PyObject *self, - PyObject *args) +_codecs_utf_7_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors) +/*[clinic end generated code: output=a7accc496a32b759 input=fd91a78f103b0421]*/ { - PyObject *str, *v; - const char *errors = NULL; - - if (!PyArg_ParseTuple(args, "O|z:utf_7_encode", - &str, &errors)) - return NULL; + PyObject *v; str = PyUnicode_FromObject(str); if (str == NULL || PyUnicode_READY(str) < 0) { @@ -730,16 +741,19 @@ utf_7_encode(PyObject *self, return v; } +/*[clinic input] +_codecs.utf_8_encode + str: object + errors: str(accept={str, NoneType}) = NULL + / +[clinic start generated code]*/ + static PyObject * -utf_8_encode(PyObject *self, - PyObject *args) +_codecs_utf_8_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors) +/*[clinic end generated code: output=ec831d80e7aedede input=2c22d40532f071f3]*/ { - PyObject *str, *v; - const char *errors = NULL; - - if (!PyArg_ParseTuple(args, "O|z:utf_8_encode", - &str, &errors)) - return NULL; + PyObject *v; str = PyUnicode_FromObject(str); if (str == NULL || PyUnicode_READY(str) < 0) { @@ -759,17 +773,20 @@ utf_8_encode(PyObject *self, */ +/*[clinic input] +_codecs.utf_16_encode + str: object + errors: str(accept={str, NoneType}) = NULL + byteorder: int = 0 + / +[clinic start generated code]*/ + static PyObject * -utf_16_encode(PyObject *self, - PyObject *args) +_codecs_utf_16_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors, int byteorder) +/*[clinic end generated code: output=93ac58e960a9ee4d input=3935a489b2d5385e]*/ { - PyObject *str, *v; - const char *errors = NULL; - int byteorder = 0; - - if (!PyArg_ParseTuple(args, "O|zi:utf_16_encode", - &str, &errors, &byteorder)) - return NULL; + PyObject *v; str = PyUnicode_FromObject(str); if (str == NULL || PyUnicode_READY(str) < 0) { @@ -782,16 +799,19 @@ utf_16_encode(PyObject *self, return v; } +/*[clinic input] +_codecs.utf_16_le_encode + str: object + errors: str(accept={str, NoneType}) = NULL + / +[clinic start generated code]*/ + static PyObject * -utf_16_le_encode(PyObject *self, - PyObject *args) +_codecs_utf_16_le_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors) +/*[clinic end generated code: output=422bedb8da34fb66 input=bc27df05d1d20dfe]*/ { - PyObject *str, *v; - const char *errors = NULL; - - if (!PyArg_ParseTuple(args, "O|z:utf_16_le_encode", - &str, &errors)) - return NULL; + PyObject *v; str = PyUnicode_FromObject(str); if (str == NULL || PyUnicode_READY(str) < 0) { @@ -804,16 +824,19 @@ utf_16_le_encode(PyObject *self, return v; } +/*[clinic input] +_codecs.utf_16_be_encode + str: object + errors: str(accept={str, NoneType}) = NULL + / +[clinic start generated code]*/ + static PyObject * -utf_16_be_encode(PyObject *self, - PyObject *args) +_codecs_utf_16_be_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors) +/*[clinic end generated code: output=3aa7ee9502acdd77 input=5a69d4112763462b]*/ { - PyObject *str, *v; - const char *errors = NULL; - - if (!PyArg_ParseTuple(args, "O|z:utf_16_be_encode", - &str, &errors)) - return NULL; + PyObject *v; str = PyUnicode_FromObject(str); if (str == NULL || PyUnicode_READY(str) < 0) { @@ -833,17 +856,20 @@ utf_16_be_encode(PyObject *self, */ +/*[clinic input] +_codecs.utf_32_encode + str: object + errors: str(accept={str, NoneType}) = NULL + byteorder: int = 0 + / +[clinic start generated code]*/ + static PyObject * -utf_32_encode(PyObject *self, - PyObject *args) +_codecs_utf_32_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors, int byteorder) +/*[clinic end generated code: output=3e7d5a003b02baed input=434a1efa492b8d58]*/ { - PyObject *str, *v; - const char *errors = NULL; - int byteorder = 0; - - if (!PyArg_ParseTuple(args, "O|zi:utf_32_encode", - &str, &errors, &byteorder)) - return NULL; + PyObject *v; str = PyUnicode_FromObject(str); if (str == NULL || PyUnicode_READY(str) < 0) { @@ -856,16 +882,19 @@ utf_32_encode(PyObject *self, return v; } +/*[clinic input] +_codecs.utf_32_le_encode + str: object + errors: str(accept={str, NoneType}) = NULL + / +[clinic start generated code]*/ + static PyObject * -utf_32_le_encode(PyObject *self, - PyObject *args) +_codecs_utf_32_le_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors) +/*[clinic end generated code: output=5dda641cd33dbfc2 input=dfa2d7dc78b99422]*/ { - PyObject *str, *v; - const char *errors = NULL; - - if (!PyArg_ParseTuple(args, "O|z:utf_32_le_encode", - &str, &errors)) - return NULL; + PyObject *v; str = PyUnicode_FromObject(str); if (str == NULL || PyUnicode_READY(str) < 0) { @@ -878,16 +907,19 @@ utf_32_le_encode(PyObject *self, return v; } +/*[clinic input] +_codecs.utf_32_be_encode + str: object + errors: str(accept={str, NoneType}) = NULL + / +[clinic start generated code]*/ + static PyObject * -utf_32_be_encode(PyObject *self, - PyObject *args) +_codecs_utf_32_be_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors) +/*[clinic end generated code: output=ccca8b44d91a7c7a input=4595617b18169002]*/ { - PyObject *str, *v; - const char *errors = NULL; - - if (!PyArg_ParseTuple(args, "O|z:utf_32_be_encode", - &str, &errors)) - return NULL; + PyObject *v; str = PyUnicode_FromObject(str); if (str == NULL || PyUnicode_READY(str) < 0) { @@ -900,16 +932,19 @@ utf_32_be_encode(PyObject *self, return v; } +/*[clinic input] +_codecs.unicode_escape_encode + str: object + errors: str(accept={str, NoneType}) = NULL + / +[clinic start generated code]*/ + static PyObject * -unicode_escape_encode(PyObject *self, - PyObject *args) +_codecs_unicode_escape_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors) +/*[clinic end generated code: output=389f23d2b8f8d80b input=8273506f14076912]*/ { - PyObject *str, *v; - const char *errors = NULL; - - if (!PyArg_ParseTuple(args, "O|z:unicode_escape_encode", - &str, &errors)) - return NULL; + PyObject *v; str = PyUnicode_FromObject(str); if (str == NULL || PyUnicode_READY(str) < 0) { @@ -922,16 +957,19 @@ unicode_escape_encode(PyObject *self, return v; } +/*[clinic input] +_codecs.raw_unicode_escape_encode + str: object + errors: str(accept={str, NoneType}) = NULL + / +[clinic start generated code]*/ + static PyObject * -raw_unicode_escape_encode(PyObject *self, - PyObject *args) +_codecs_raw_unicode_escape_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors) +/*[clinic end generated code: output=fec4e39d6ec37a62 input=181755d5dfacef3c]*/ { - PyObject *str, *v; - const char *errors = NULL; - - if (!PyArg_ParseTuple(args, "O|z:raw_unicode_escape_encode", - &str, &errors)) - return NULL; + PyObject *v; str = PyUnicode_FromObject(str); if (str == NULL || PyUnicode_READY(str) < 0) { @@ -944,16 +982,19 @@ raw_unicode_escape_encode(PyObject *self, return v; } +/*[clinic input] +_codecs.latin_1_encode + str: object + errors: str(accept={str, NoneType}) = NULL + / +[clinic start generated code]*/ + static PyObject * -latin_1_encode(PyObject *self, - PyObject *args) +_codecs_latin_1_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors) +/*[clinic end generated code: output=ecf00eb8e48c889c input=f03f6dcf1d84bee4]*/ { - PyObject *str, *v; - const char *errors = NULL; - - if (!PyArg_ParseTuple(args, "O|z:latin_1_encode", - &str, &errors)) - return NULL; + PyObject *v; str = PyUnicode_FromObject(str); if (str == NULL || PyUnicode_READY(str) < 0) { @@ -966,16 +1007,19 @@ latin_1_encode(PyObject *self, return v; } +/*[clinic input] +_codecs.ascii_encode + str: object + errors: str(accept={str, NoneType}) = NULL + / +[clinic start generated code]*/ + static PyObject * -ascii_encode(PyObject *self, - PyObject *args) +_codecs_ascii_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors) +/*[clinic end generated code: output=a9d18fc6b6b91cfb input=d87e25a10a593fee]*/ { - PyObject *str, *v; - const char *errors = NULL; - - if (!PyArg_ParseTuple(args, "O|z:ascii_encode", - &str, &errors)) - return NULL; + PyObject *v; str = PyUnicode_FromObject(str); if (str == NULL || PyUnicode_READY(str) < 0) { @@ -988,17 +1032,21 @@ ascii_encode(PyObject *self, return v; } +/*[clinic input] +_codecs.charmap_encode + str: object + errors: str(accept={str, NoneType}) = NULL + mapping: object = NULL + / +[clinic start generated code]*/ + static PyObject * -charmap_encode(PyObject *self, - PyObject *args) +_codecs_charmap_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors, PyObject *mapping) +/*[clinic end generated code: output=14ca42b83853c643 input=85f4172661e8dad9]*/ { - PyObject *str, *v; - const char *errors = NULL; - PyObject *mapping = NULL; + PyObject *v; - if (!PyArg_ParseTuple(args, "O|zO:charmap_encode", - &str, &errors, &mapping)) - return NULL; if (mapping == Py_None) mapping = NULL; @@ -1013,27 +1061,34 @@ charmap_encode(PyObject *self, return v; } -static PyObject* -charmap_build(PyObject *self, PyObject *args) +/*[clinic input] +_codecs.charmap_build + map: unicode + / +[clinic start generated code]*/ + +static PyObject * +_codecs_charmap_build_impl(PyModuleDef *module, PyObject *map) +/*[clinic end generated code: output=9485b58fa44afa6a input=d91a91d1717dbc6d]*/ { - PyObject *map; - if (!PyArg_ParseTuple(args, "U:charmap_build", &map)) - return NULL; return PyUnicode_BuildEncodingMap(map); } #ifdef HAVE_MBCS +/*[clinic input] +_codecs.mbcs_encode + str: object + errors: str(accept={str, NoneType}) = NULL + / +[clinic start generated code]*/ + static PyObject * -mbcs_encode(PyObject *self, - PyObject *args) +_codecs_mbcs_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors) +/*[clinic end generated code: output=d1a013bc68798bd7 input=65c09ee1e4203263]*/ { - PyObject *str, *v; - const char *errors = NULL; - - if (!PyArg_ParseTuple(args, "O|z:mbcs_encode", - &str, &errors)) - return NULL; + PyObject *v; str = PyUnicode_FromObject(str); if (str == NULL || PyUnicode_READY(str) < 0) { @@ -1046,17 +1101,20 @@ mbcs_encode(PyObject *self, return v; } +/*[clinic input] +_codecs.code_page_encode + code_page: int + str: object + errors: str(accept={str, NoneType}) = NULL + / +[clinic start generated code]*/ + static PyObject * -code_page_encode(PyObject *self, - PyObject *args) +_codecs_code_page_encode_impl(PyModuleDef *module, int code_page, + PyObject *str, const char *errors) +/*[clinic end generated code: output=3b406618dbfbce25 input=c8562ec460c2e309]*/ { - PyObject *str, *v; - const char *errors = NULL; - int code_page; - - if (!PyArg_ParseTuple(args, "iO|z:code_page_encode", - &code_page, &str, &errors)) - return NULL; + PyObject *v; str = PyUnicode_FromObject(str); if (str == NULL || PyUnicode_READY(str) < 0) { @@ -1075,99 +1133,95 @@ code_page_encode(PyObject *self, /* --- Error handler registry --------------------------------------------- */ -PyDoc_STRVAR(register_error__doc__, -"register_error(errors, handler)\n\ -\n\ -Register the specified error handler under the name\n\ -errors. handler must be a callable object, that\n\ -will be called with an exception instance containing\n\ -information about the location of the encoding/decoding\n\ -error and must return a (replacement, new position) tuple."); +/*[clinic input] +_codecs.register_error + errors: str + handler: object + / -static PyObject *register_error(PyObject *self, PyObject *args) -{ - const char *name; - PyObject *handler; +Register the specified error handler under the name errors. - if (!PyArg_ParseTuple(args, "sO:register_error", - &name, &handler)) - return NULL; - if (PyCodec_RegisterError(name, handler)) +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(PyModuleDef *module, const char *errors, + PyObject *handler) +/*[clinic end generated code: output=be00d3b1849ce68a input=5e6709203c2e33fe]*/ +{ + if (PyCodec_RegisterError(errors, handler)) return NULL; Py_RETURN_NONE; } -PyDoc_STRVAR(lookup_error__doc__, -"lookup_error(errors) -> handler\n\ -\n\ -Return the error handler for the specified error handling name\n\ -or raise a LookupError, if no handler exists under this name."); +/*[clinic input] +_codecs.lookup_error + name: str + / -static PyObject *lookup_error(PyObject *self, PyObject *args) -{ - const char *name; +lookup_error(errors) -> handler - if (!PyArg_ParseTuple(args, "s:lookup_error", - &name)) - return NULL; +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(PyModuleDef *module, const char *name) +/*[clinic end generated code: output=731e6df8c83c6158 input=4775dd65e6235aba]*/ +{ return PyCodec_LookupError(name); } /* --- Module API --------------------------------------------------------- */ static PyMethodDef _codecs_functions[] = { - {"register", codec_register, METH_O, - register__doc__}, - {"lookup", codec_lookup, METH_VARARGS, - lookup__doc__}, - {"encode", codec_encode, METH_VARARGS, - encode__doc__}, - {"decode", codec_decode, METH_VARARGS, - decode__doc__}, - {"escape_encode", escape_encode, METH_VARARGS}, - {"escape_decode", escape_decode, METH_VARARGS}, - {"utf_8_encode", utf_8_encode, METH_VARARGS}, - {"utf_8_decode", utf_8_decode, METH_VARARGS}, - {"utf_7_encode", utf_7_encode, METH_VARARGS}, - {"utf_7_decode", utf_7_decode, METH_VARARGS}, - {"utf_16_encode", utf_16_encode, METH_VARARGS}, - {"utf_16_le_encode", utf_16_le_encode, METH_VARARGS}, - {"utf_16_be_encode", utf_16_be_encode, METH_VARARGS}, - {"utf_16_decode", utf_16_decode, METH_VARARGS}, - {"utf_16_le_decode", utf_16_le_decode, METH_VARARGS}, - {"utf_16_be_decode", utf_16_be_decode, METH_VARARGS}, - {"utf_16_ex_decode", utf_16_ex_decode, METH_VARARGS}, - {"utf_32_encode", utf_32_encode, METH_VARARGS}, - {"utf_32_le_encode", utf_32_le_encode, METH_VARARGS}, - {"utf_32_be_encode", utf_32_be_encode, METH_VARARGS}, - {"utf_32_decode", utf_32_decode, METH_VARARGS}, - {"utf_32_le_decode", utf_32_le_decode, METH_VARARGS}, - {"utf_32_be_decode", utf_32_be_decode, METH_VARARGS}, - {"utf_32_ex_decode", utf_32_ex_decode, METH_VARARGS}, - {"unicode_escape_encode", unicode_escape_encode, METH_VARARGS}, - {"unicode_escape_decode", unicode_escape_decode, METH_VARARGS}, - {"unicode_internal_encode", unicode_internal_encode, METH_VARARGS}, - {"unicode_internal_decode", unicode_internal_decode, METH_VARARGS}, - {"raw_unicode_escape_encode", raw_unicode_escape_encode, METH_VARARGS}, - {"raw_unicode_escape_decode", raw_unicode_escape_decode, METH_VARARGS}, - {"latin_1_encode", latin_1_encode, METH_VARARGS}, - {"latin_1_decode", latin_1_decode, METH_VARARGS}, - {"ascii_encode", ascii_encode, METH_VARARGS}, - {"ascii_decode", ascii_decode, METH_VARARGS}, - {"charmap_encode", charmap_encode, METH_VARARGS}, - {"charmap_decode", charmap_decode, METH_VARARGS}, - {"charmap_build", charmap_build, METH_VARARGS}, - {"readbuffer_encode", readbuffer_encode, METH_VARARGS}, -#ifdef HAVE_MBCS - {"mbcs_encode", mbcs_encode, METH_VARARGS}, - {"mbcs_decode", mbcs_decode, METH_VARARGS}, - {"code_page_encode", code_page_encode, METH_VARARGS}, - {"code_page_decode", code_page_decode, METH_VARARGS}, -#endif - {"register_error", register_error, METH_VARARGS, - register_error__doc__}, - {"lookup_error", lookup_error, METH_VARARGS, - lookup_error__doc__}, + _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_UNICODE_INTERNAL_ENCODE_METHODDEF + _CODECS_UNICODE_INTERNAL_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_CODE_PAGE_ENCODE_METHODDEF + _CODECS_CODE_PAGE_DECODE_METHODDEF + _CODECS_REGISTER_ERROR_METHODDEF + _CODECS_LOOKUP_ERROR_METHODDEF + _CODECS__FORGET_CODEC_METHODDEF {NULL, NULL} /* sentinel */ }; diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 310e67207e7b..aa879beff84e 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -1,50 +1,73 @@ #include "Python.h" #include "structmember.h" +#ifdef STDC_HEADERS +#include +#else +#include /* For size_t */ +#endif + /* collections module implementation of a deque() datatype Written and maintained by Raymond D. Hettinger - Copyright (c) 2004-2013 Python Software Foundation. + Copyright (c) 2004-2015 Python Software Foundation. All rights reserved. */ /* 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::data overhead ratio. - * - * Ideally, the block length will be set to two less than some - * multiple of the cache-line length (so that the full block - * including the leftlink and rightlink will fit neatly into - * cache lines). + * 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 62 +#define BLOCKLEN 64 #define CENTER ((BLOCKLEN - 1) / 2) -/* A `dequeobject` is composed of a doubly-linked list of `block` nodes. +/* 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 simplifies the design. * - * The indices, d.leftindex and d.rightindex are always in the range - * 0 <= index < BLOCKLEN. - * Their exact relationship is: - * (d.leftindex + d.len - 1) % BLOCKLEN == d.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. * - * Empty deques have d.len == 0; d.leftblock==d.rightblock; - * d.leftindex == CENTER+1; and d.rightindex == CENTER. - * Checking for d.len == 0 is the intended way to see whether d is empty. + * 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, - * d.leftindex + d.len - 1 == d.rightindex. + * Whenever d.leftblock == d.rightblock, then: + * d.leftindex + d.len - 1 == d.rightindex * - * However, when d.leftblock != d.rightblock, d.leftindex and d.rightindex - * become indices into distinct blocks and either may be larger than the - * other. + * 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 { @@ -53,6 +76,19 @@ typedef struct BLOCK { 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; + 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 @@ -75,24 +111,17 @@ typedef struct BLOCK { #endif /* A simple freelisting scheme is used to minimize calls to the memory - allocator. It accomodates common use cases where new blocks are being + 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 10 +#define MAXFREEBLOCKS 16 static Py_ssize_t numfreeblocks = 0; static block *freeblocks[MAXFREEBLOCKS]; static block * newblock(Py_ssize_t len) { block *b; - /* To prevent len from overflowing PY_SSIZE_T_MAX, we refuse to - * allocate new blocks if the current len is nearing overflow. */ - if (len >= PY_SSIZE_T_MAX - 2*BLOCKLEN) { - PyErr_SetString(PyExc_OverflowError, - "cannot add more blocks to the deque"); - return NULL; - } if (numfreeblocks) { numfreeblocks--; return freeblocks[numfreeblocks]; @@ -116,35 +145,6 @@ freeblock(block *b) } } -typedef struct { - PyObject_VAR_HEAD - block *leftblock; - block *rightblock; - Py_ssize_t leftindex; /* in range(BLOCKLEN) */ - Py_ssize_t rightindex; /* in range(BLOCKLEN) */ - long state; /* incremented whenever the indices move */ - Py_ssize_t maxlen; - PyObject *weakreflist; /* List of weak references */ -} dequeobject; - -/* 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(). - */ - -#define TRIM(d, popfunction) \ - if (d->maxlen != -1 && Py_SIZE(d) > d->maxlen) { \ - PyObject *rv = popfunction(d, NULL); \ - assert(rv != NULL && Py_SIZE(d) <= d->maxlen); \ - Py_DECREF(rv); \ - } - -static PyTypeObject deque_type; - static PyObject * deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -165,14 +165,14 @@ deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds) MARK_END(b->rightlink); assert(BLOCKLEN >= 2); + Py_SIZE(deque) = 0; deque->leftblock = b; deque->rightblock = b; deque->leftindex = CENTER + 1; deque->rightindex = CENTER; - Py_SIZE(deque) = 0; deque->state = 0; - deque->weakreflist = NULL; deque->maxlen = -1; + deque->weakreflist = NULL; return (PyObject *)deque; } @@ -192,14 +192,8 @@ deque_pop(dequeobject *deque, PyObject *unused) Py_SIZE(deque)--; deque->state++; - if (deque->rightindex == -1) { - if (Py_SIZE(deque) == 0) { - 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; - } else { + if (deque->rightindex < 0) { + if (Py_SIZE(deque)) { prevblock = deque->rightblock->leftlink; assert(deque->leftblock != deque->rightblock); freeblock(deque->rightblock); @@ -207,6 +201,12 @@ deque_pop(dequeobject *deque, PyObject *unused) 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; @@ -231,13 +231,7 @@ deque_popleft(dequeobject *deque, PyObject *unused) deque->state++; if (deque->leftindex == BLOCKLEN) { - if (Py_SIZE(deque) == 0) { - 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; - } else { + if (Py_SIZE(deque)) { assert(deque->leftblock != deque->rightblock); prevblock = deque->leftblock->rightlink; freeblock(deque->leftblock); @@ -245,6 +239,12 @@ deque_popleft(dequeobject *deque, PyObject *unused) 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; @@ -252,11 +252,24 @@ deque_popleft(dequeobject *deque, PyObject *unused) 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 PyObject * deque_append(dequeobject *deque, PyObject *item) { - deque->state++; - if (deque->rightindex == BLOCKLEN-1) { + if (deque->rightindex == BLOCKLEN - 1) { block *b = newblock(Py_SIZE(deque)); if (b == NULL) return NULL; @@ -267,11 +280,16 @@ deque_append(dequeobject *deque, PyObject *item) MARK_END(b->rightlink); deque->rightindex = -1; } - Py_INCREF(item); Py_SIZE(deque)++; + Py_INCREF(item); deque->rightindex++; deque->rightblock->data[deque->rightindex] = item; - TRIM(deque, deque_popleft); + if (NEEDS_TRIM(deque, deque->maxlen)) { + PyObject *olditem = deque_popleft(deque, NULL); + Py_DECREF(olditem); + } else { + deque->state++; + } Py_RETURN_NONE; } @@ -280,7 +298,6 @@ PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque."); static PyObject * deque_appendleft(dequeobject *deque, PyObject *item) { - deque->state++; if (deque->leftindex == 0) { block *b = newblock(Py_SIZE(deque)); if (b == NULL) @@ -292,37 +309,57 @@ deque_appendleft(dequeobject *deque, PyObject *item) MARK_END(b->leftlink); deque->leftindex = BLOCKLEN; } - Py_INCREF(item); Py_SIZE(deque)++; + Py_INCREF(item); deque->leftindex--; deque->leftblock->data[deque->leftindex] = item; - TRIM(deque, deque_pop); + if (NEEDS_TRIM(deque, deque->maxlen)) { + PyObject *olditem = deque_pop(deque, NULL); + Py_DECREF(olditem); + } else { + deque->state++; + } 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; - while ((item = PyIter_Next(it)) != NULL) { + iternext = *Py_TYPE(it)->tp_iternext; + while ((item = iternext(it)) != NULL) { Py_DECREF(item); } - Py_DECREF(it); - if (PyErr_Occurred()) - return NULL; - Py_RETURN_NONE; + 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) { @@ -347,12 +384,12 @@ deque_extend(dequeobject *deque, PyObject *iterable) if (it == NULL) return NULL; - if (deque->maxlen == 0) + if (maxlen == 0) return consume_iterator(it); - while ((item = PyIter_Next(it)) != NULL) { - deque->state++; - if (deque->rightindex == BLOCKLEN-1) { + iternext = *Py_TYPE(it)->tp_iternext; + while ((item = iternext(it)) != NULL) { + if (deque->rightindex == BLOCKLEN - 1) { block *b = newblock(Py_SIZE(deque)); if (b == NULL) { Py_DECREF(item); @@ -369,12 +406,14 @@ deque_extend(dequeobject *deque, PyObject *iterable) Py_SIZE(deque)++; deque->rightindex++; deque->rightblock->data[deque->rightindex] = item; - TRIM(deque, deque_popleft); + if (NEEDS_TRIM(deque, maxlen)) { + PyObject *olditem = deque_popleft(deque, NULL); + Py_DECREF(olditem); + } else { + deque->state++; + } } - Py_DECREF(it); - if (PyErr_Occurred()) - return NULL; - Py_RETURN_NONE; + return finalize_iterator(it); } PyDoc_STRVAR(extend_doc, @@ -384,6 +423,8 @@ 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) { @@ -408,11 +449,11 @@ deque_extendleft(dequeobject *deque, PyObject *iterable) if (it == NULL) return NULL; - if (deque->maxlen == 0) + if (maxlen == 0) return consume_iterator(it); - while ((item = PyIter_Next(it)) != NULL) { - deque->state++; + iternext = *Py_TYPE(it)->tp_iternext; + while ((item = iternext(it)) != NULL) { if (deque->leftindex == 0) { block *b = newblock(Py_SIZE(deque)); if (b == NULL) { @@ -430,12 +471,14 @@ deque_extendleft(dequeobject *deque, PyObject *iterable) Py_SIZE(deque)++; deque->leftindex--; deque->leftblock->data[deque->leftindex] = item; - TRIM(deque, deque_pop); + if (NEEDS_TRIM(deque, maxlen)) { + PyObject *olditem = deque_pop(deque, NULL); + Py_DECREF(olditem); + } else { + deque->state++; + } } - Py_DECREF(it); - if (PyErr_Occurred()) - return NULL; - Py_RETURN_NONE; + return finalize_iterator(it); } PyDoc_STRVAR(extendleft_doc, @@ -449,11 +492,273 @@ deque_inplace_concat(dequeobject *deque, PyObject *other) 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) +{ + 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) + return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "O", deque, NULL); + else + return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "Oi", + deque, old_deque->maxlen, NULL); +} + +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); + 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 void +deque_clear(dequeobject *deque) +{ + block *b; + block *prevblock; + block *leftblock; + Py_ssize_t leftindex; + Py_ssize_t n; + PyObject *item; + + if (Py_SIZE(deque) == 0) + return; + + /* 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(0); + if (b == NULL) { + PyErr_Clear(); + goto alternate_method; + } + + /* Remember the old size, leftblock, and leftindex */ + leftblock = deque->leftblock; + leftindex = deque->leftindex; + n = Py_SIZE(deque); + + /* 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. + */ + while (n--) { + item = leftblock->data[leftindex]; + Py_DECREF(item); + leftindex++; + if (leftindex == BLOCKLEN && n) { + CHECK_NOT_END(leftblock->rightlink); + prevblock = leftblock; + leftblock = leftblock->rightlink; + leftindex = 0; + freeblock(prevblock); + } + } + CHECK_END(leftblock->rightlink); + freeblock(leftblock); + return; + + alternate_method: + while (Py_SIZE(deque)) { + item = deque_pop(deque, NULL); + assert (item != NULL); + Py_DECREF(item); + } +} + +static PyObject * +deque_clearmethod(dequeobject *deque) +{ + 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(Py_SIZE(deque) + i); + 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; + + 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); + 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 a 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) { @@ -503,16 +808,16 @@ _deque_rotate(dequeobject *deque, Py_ssize_t n) if (m > leftindex) m = leftindex; assert (m > 0 && m <= len); - src = &rightblock->data[rightindex]; - dest = &leftblock->data[leftindex - 1]; rightindex -= m; leftindex -= m; + src = &rightblock->data[rightindex + 1]; + dest = &leftblock->data[leftindex]; n -= m; do { - *(dest--) = *(src--); + *(dest++) = *(src++); } while (--m); } - if (rightindex == -1) { + if (rightindex < 0) { assert(leftblock != rightblock); assert(b == NULL); b = rightblock; @@ -585,7 +890,7 @@ deque_rotate(dequeobject *deque, PyObject *args) if (!PyArg_ParseTuple(args, "|n:rotate", &n)) return NULL; - if (_deque_rotate(deque, n) == 0) + if (!_deque_rotate(deque, n)) Py_RETURN_NONE; return NULL; } @@ -600,11 +905,10 @@ deque_reverse(dequeobject *deque, PyObject *unused) block *rightblock = deque->rightblock; Py_ssize_t leftindex = deque->leftindex; Py_ssize_t rightindex = deque->rightindex; - Py_ssize_t n = (Py_SIZE(deque))/2; - Py_ssize_t i; + Py_ssize_t n = Py_SIZE(deque) >> 1; PyObject *tmp; - for (i=0 ; i 0) { /* Validate that pointers haven't met in the middle */ assert(leftblock != rightblock || leftindex < rightindex); CHECK_NOT_END(leftblock); @@ -624,7 +928,7 @@ deque_reverse(dequeobject *deque, PyObject *unused) /* Step backwards with the right block/index pair */ rightindex--; - if (rightindex == -1) { + if (rightindex < 0) { rightblock = rightblock->leftlink; rightindex = BLOCKLEN - 1; } @@ -641,20 +945,18 @@ 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 i; Py_ssize_t count = 0; + size_t start_state = deque->state; PyObject *item; - long start_state = deque->state; int cmp; - for (i=0 ; idata[index]; cmp = PyObject_RichCompareBool(item, v, Py_EQ); - if (cmp > 0) - count++; - else if (cmp < 0) + if (cmp < 0) return NULL; + count += cmp; if (start_state != deque->state) { PyErr_SetString(PyExc_RuntimeError, @@ -675,12 +977,138 @@ deque_count(dequeobject *deque, PyObject *v) 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--) { + CHECK_NOT_END(b); + item = b->data[index]; + cmp = PyObject_RichCompareBool(item, v, Py_EQ); + 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 *args) +{ + Py_ssize_t i, 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; + + if (!PyArg_ParseTuple(args, "O|O&O&:index", &v, + _PyEval_SliceIndex, &start, + _PyEval_SliceIndex, &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); + + for (i=0 ; i= start) { + int cmp; + CHECK_NOT_END(b); + item = b->data[index]; + cmp = PyObject_RichCompareBool(item, v, Py_EQ); + if (cmp > 0) + return PyLong_FromSsize_t(i); + else 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 *args) +{ + Py_ssize_t index; + Py_ssize_t n = Py_SIZE(deque); + PyObject *value; + PyObject *rv; + + if (!PyArg_ParseTuple(args, "nO:insert", &index, &value)) + 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) { @@ -698,9 +1126,9 @@ deque_remove(dequeobject *deque, PyObject *value) if (cmp > 0) { PyObject *tgt = deque_popleft(deque, NULL); assert (tgt != NULL); - Py_DECREF(tgt); - if (_deque_rotate(deque, i) == -1) + if (_deque_rotate(deque, i)) return NULL; + Py_DECREF(tgt); Py_RETURN_NONE; } else if (cmp < 0) { @@ -716,19 +1144,12 @@ deque_remove(dequeobject *deque, PyObject *value) PyDoc_STRVAR(remove_doc, "D.remove(value) -- remove first occurrence of value."); -static void -deque_clear(dequeobject *deque) +static int +valid_index(Py_ssize_t i, Py_ssize_t limit) { - PyObject *item; - - while (Py_SIZE(deque)) { - item = deque_pop(deque, NULL); - assert (item != NULL); - Py_DECREF(item); - } - assert(deque->leftblock == deque->rightblock && - deque->leftindex - 1 == deque->rightindex && - Py_SIZE(deque) == 0); + /* 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 * @@ -738,9 +1159,8 @@ deque_item(dequeobject *deque, Py_ssize_t i) PyObject *item; Py_ssize_t n, index=i; - if (i < 0 || i >= Py_SIZE(deque)) { - PyErr_SetString(PyExc_IndexError, - "deque index out of range"); + if (!valid_index(i, Py_SIZE(deque))) { + PyErr_SetString(PyExc_IndexError, "deque index out of range"); return NULL; } @@ -752,14 +1172,16 @@ deque_item(dequeobject *deque, Py_ssize_t i) b = deque->rightblock; } else { i += deque->leftindex; - n = i / BLOCKLEN; - i %= BLOCKLEN; + 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--) b = b->rightlink; } else { - n = (deque->leftindex + Py_SIZE(deque) - 1) / BLOCKLEN - n; + n = (Py_ssize_t)( + ((size_t)(deque->leftindex + Py_SIZE(deque) - 1)) + / BLOCKLEN - n); b = deque->rightblock; while (n--) b = b->leftlink; @@ -770,27 +1192,20 @@ deque_item(dequeobject *deque, Py_ssize_t i) return item; } -/* delitem() implemented in terms of rotate for simplicity and reasonable - performance near the end points. If for some reason this method becomes - popular, it is not hard to re-implement this using direct data movement - (similar to code in list slice assignment) and achieve a two or threefold - performance boost. -*/ - 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) == -1) + if (_deque_rotate(deque, -i)) return -1; - item = deque_popleft(deque, NULL); + rv = _deque_rotate(deque, i); assert (item != NULL); Py_DECREF(item); - - return _deque_rotate(deque, i); + return rv; } static int @@ -800,23 +1215,24 @@ deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v) block *b; Py_ssize_t n, len=Py_SIZE(deque), halflen=(len+1)>>1, index=i; - if (i < 0 || i >= len) { - PyErr_SetString(PyExc_IndexError, - "deque index out of range"); + 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 = i / BLOCKLEN; - i %= BLOCKLEN; + n = (Py_ssize_t)((size_t) i / BLOCKLEN); + i = (Py_ssize_t)((size_t) i % BLOCKLEN); if (index <= halflen) { b = deque->leftblock; while (n--) b = b->rightlink; } else { - n = (deque->leftindex + len - 1) / BLOCKLEN - n; + n = (Py_ssize_t)( + ((size_t)(deque->leftindex + Py_SIZE(deque) - 1)) + / BLOCKLEN - n); b = deque->rightblock; while (n--) b = b->leftlink; @@ -828,15 +1244,6 @@ deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v) return 0; } -static PyObject * -deque_clearmethod(dequeobject *deque) -{ - deque_clear(deque); - Py_RETURN_NONE; -} - -PyDoc_STRVAR(clear_doc, "Remove all elements from the deque."); - static void deque_dealloc(dequeobject *deque) { @@ -860,6 +1267,7 @@ deque_traverse(dequeobject *deque, visitproc visit, void *arg) 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++) { @@ -868,25 +1276,14 @@ deque_traverse(dequeobject *deque, visitproc visit, void *arg) } indexlo = 0; } - for (index = indexlo; index <= deque->rightindex; index++) { + indexhigh = deque->rightindex; + for (index = indexlo; index <= indexhigh; index++) { item = b->data[index]; Py_VISIT(item); } return 0; } -static PyObject * -deque_copy(PyObject *deque) -{ - if (((dequeobject *)deque)->maxlen == -1) - return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "O", deque, NULL); - else - return PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "Oi", - deque, ((dequeobject *)deque)->maxlen, NULL); -} - -PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque."); - static PyObject * deque_reduce(dequeobject *deque) { @@ -902,12 +1299,12 @@ deque_reduce(dequeobject *deque) return NULL; } if (dict == NULL) { - if (deque->maxlen == -1) + if (deque->maxlen < 0) result = Py_BuildValue("O(O)", Py_TYPE(deque), aslist); else result = Py_BuildValue("O(On)", Py_TYPE(deque), aslist, deque->maxlen); } else { - if (deque->maxlen == -1) + if (deque->maxlen < 0) result = Py_BuildValue("O(OO)O", Py_TYPE(deque), aslist, Py_None, dict); else result = Py_BuildValue("O(On)O", Py_TYPE(deque), aslist, deque->maxlen, dict); @@ -937,14 +1334,13 @@ deque_repr(PyObject *deque) Py_ReprLeave(deque); return NULL; } - if (((dequeobject *)deque)->maxlen != -1) - + if (((dequeobject *)deque)->maxlen >= 0) result = PyUnicode_FromFormat("deque(%R, maxlen=%zd)", aslist, ((dequeobject *)deque)->maxlen); else result = PyUnicode_FromFormat("deque(%R)", aslist); - Py_DECREF(aslist); Py_ReprLeave(deque); + Py_DECREF(aslist); return result; } @@ -999,7 +1395,7 @@ deque_richcompare(PyObject *v, PyObject *w, int op) } Py_DECREF(x); Py_DECREF(y); - if (b == -1) + if (b < 0) goto done; } /* We reached the end of one deque or both */ @@ -1034,8 +1430,14 @@ deque_init(dequeobject *deque, PyObject *args, PyObject *kwdargs) Py_ssize_t maxlen = -1; char *kwlist[] = {"iterable", "maxlen", 0}; - if (!PyArg_ParseTupleAndKeywords(args, kwdargs, "|OO:deque", kwlist, &iterable, &maxlenobj)) - return -1; + if (kwdargs == NULL) { + if (!PyArg_UnpackTuple(args, "deque()", 0, 2, &iterable, &maxlenobj)) + return -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()) @@ -1046,7 +1448,8 @@ deque_init(dequeobject *deque, PyObject *args, PyObject *kwdargs) } } deque->maxlen = maxlen; - deque_clear(deque); + if (Py_SIZE(deque) > 0) + deque_clear(deque); if (iterable != NULL) { PyObject *rv = deque_extend(deque, iterable); if (rv == NULL) @@ -1063,7 +1466,7 @@ deque_sizeof(dequeobject *deque, void *unused) Py_ssize_t blocks; res = sizeof(dequeobject); - blocks = (deque->leftindex + Py_SIZE(deque) + BLOCKLEN - 1) / BLOCKLEN; + 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); @@ -1073,14 +1476,23 @@ deque_sizeof(dequeobject *deque, void *unused) 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) { - if (deque->maxlen == -1) + 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"}, @@ -1089,19 +1501,30 @@ static PyGetSetDef deque_getset[] = { static PySequenceMethods deque_as_sequence = { (lenfunc)deque_len, /* sq_length */ - 0, /* sq_concat */ - 0, /* sq_repeat */ + (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 */ + (ssizeobjargproc)deque_ass_item, /* sq_ass_item */ 0, /* sq_ass_slice */ - 0, /* sq_contains */ - (binaryfunc)deque_inplace_concat, /* sq_inplace_concat */ - 0, /* sq_inplace_repeat */ - + (objobjproc)deque_contains, /* sq_contains */ + (binaryfunc)deque_inplace_concat, /* sq_inplace_concat */ + (ssizeargfunc)deque_inplace_repeat, /* sq_inplace_repeat */ }; -/* deque object ********************************************************/ +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); @@ -1117,17 +1540,23 @@ static PyMethodDef deque_methods[] = { METH_NOARGS, clear_doc}, {"__copy__", (PyCFunction)deque_copy, METH_NOARGS, copy_doc}, + {"copy", (PyCFunction)deque_copy, + METH_NOARGS, copy_doc}, {"count", (PyCFunction)deque_count, - METH_O, count_doc}, + METH_O, count_doc}, {"extend", (PyCFunction)deque_extend, METH_O, extend_doc}, {"extendleft", (PyCFunction)deque_extendleft, METH_O, extendleft_doc}, + {"index", (PyCFunction)deque_index, + METH_VARARGS, index_doc}, + {"insert", (PyCFunction)deque_insert, + METH_VARARGS, insert_doc}, {"pop", (PyCFunction)deque_pop, METH_NOARGS, pop_doc}, {"popleft", (PyCFunction)deque_popleft, METH_NOARGS, popleft_doc}, - {"__reduce__", (PyCFunction)deque_reduce, + {"__reduce__", (PyCFunction)deque_reduce, METH_NOARGS, reduce_doc}, {"remove", (PyCFunction)deque_remove, METH_O, remove_doc}, @@ -1145,7 +1574,7 @@ static PyMethodDef deque_methods[] = { PyDoc_STRVAR(deque_doc, "deque([iterable[, maxlen]]) --> deque object\n\ \n\ -Build an ordered collection with optimized access from its endpoints."); +A list-like sequence optimized for data accesses near its endpoints."); static PyTypeObject deque_type = { PyVarObject_HEAD_INIT(NULL, 0) @@ -1159,7 +1588,7 @@ static PyTypeObject deque_type = { 0, /* tp_setattr */ 0, /* tp_reserved */ deque_repr, /* tp_repr */ - 0, /* tp_as_number */ + &deque_as_number, /* tp_as_number */ &deque_as_sequence, /* tp_as_sequence */ 0, /* tp_as_mapping */ PyObject_HashNotImplemented, /* tp_hash */ @@ -1195,10 +1624,10 @@ static PyTypeObject deque_type = { typedef struct { PyObject_HEAD - Py_ssize_t index; block *b; + Py_ssize_t index; dequeobject *deque; - long state; /* state when the iterator is created */ + size_t state; /* state when the iterator is created */ Py_ssize_t counter; /* number of items remaining for iteration */ } dequeiterobject; @@ -1315,7 +1744,7 @@ static PyMethodDef dequeiter_methods[] = { static PyTypeObject dequeiter_type = { PyVarObject_HEAD_INIT(NULL, 0) - "_collections._deque_iterator", /* tp_name */ + "_collections._deque_iterator", /* tp_name */ sizeof(dequeiterobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ @@ -1334,7 +1763,7 @@ static PyTypeObject dequeiter_type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ (traverseproc)dequeiter_traverse, /* tp_traverse */ 0, /* tp_clear */ @@ -1397,7 +1826,7 @@ dequereviter_next(dequeiterobject *it) item = it->b->data[it->index]; it->index--; it->counter--; - if (it->index == -1 && it->counter > 0) { + if (it->index < 0 && it->counter > 0) { CHECK_NOT_END(it->b->leftlink); it->b = it->b->leftlink; it->index = BLOCKLEN - 1; @@ -1437,7 +1866,7 @@ dequereviter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static PyTypeObject dequereviter_type = { PyVarObject_HEAD_INIT(NULL, 0) - "_collections._deque_reverse_iterator", /* tp_name */ + "_collections._deque_reverse_iterator", /* tp_name */ sizeof(dequeiterobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ @@ -1456,7 +1885,7 @@ static PyTypeObject dequereviter_type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ (traverseproc)dequeiter_traverse, /* tp_traverse */ 0, /* tp_clear */ @@ -1682,7 +2111,7 @@ defdict_init(PyObject *self, PyObject *args, PyObject *kwds) newdefault = PyTuple_GET_ITEM(args, 0); if (!PyCallable_Check(newdefault) && newdefault != Py_None) { PyErr_SetString(PyExc_TypeError, - "first argument must be callable"); + "first argument must be callable or None"); return -1; } } @@ -1699,11 +2128,13 @@ defdict_init(PyObject *self, PyObject *args, PyObject *kwds) } PyDoc_STRVAR(defdict_doc, -"defaultdict(default_factory) --> dict with default factory\n\ +"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 */ @@ -1798,19 +2229,40 @@ _count_elements(PyObject *self, PyObject *args) if (mapping_get != NULL && mapping_get == dict_get && mapping_setitem != NULL && mapping_setitem == dict_setitem) { 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; - oldval = PyDict_GetItem(mapping, key); + + 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 (PyDict_SetItem(mapping, key, one) == -1) - break; + if (_PyDict_SetItem_KnownHash(mapping, key, one, hash) < 0) + goto done; } else { newval = PyNumber_Add(oldval, one); if (newval == NULL) - break; - if (PyDict_SetItem(mapping, key, newval) == -1) - break; + goto done; + if (_PyDict_SetItem_KnownHash(mapping, key, newval, hash) < 0) + goto done; Py_CLEAR(newval); } Py_DECREF(key); @@ -1835,7 +2287,7 @@ _count_elements(PyObject *self, PyObject *args) Py_DECREF(oldval); if (newval == NULL) break; - if (PyObject_SetItem(mapping, key, newval) == -1) + if (PyObject_SetItem(mapping, key, newval) < 0) break; Py_CLEAR(newval); Py_DECREF(key); @@ -1899,6 +2351,9 @@ PyInit__collections(void) 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); diff --git a/Modules/_cryptmodule.c b/Modules/_cryptmodule.c index 51007889bf82..d422cfdff7d4 100644 --- a/Modules/_cryptmodule.c +++ b/Modules/_cryptmodule.c @@ -5,40 +5,43 @@ #include -#ifdef __VMS -#include -#endif - /* 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. -static PyObject *crypt_crypt(PyObject *self, PyObject *args) +*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(PyModuleDef *module, const char *word, const char *salt) +/*[clinic end generated code: output=995ad1e854d83069 input=0e8edec9c364352b]*/ { - char *word, *salt; -#ifndef __VMS - extern char * crypt(const char *, const char *); -#endif - - if (!PyArg_ParseTuple(args, "ss:crypt", &word, &salt)) { - return NULL; - } /* On some platforms (AtheOS) crypt returns NULL for an invalid salt. Return None in that case. XXX Maybe raise an exception? */ return Py_BuildValue("s", crypt(word, salt)); - } -PyDoc_STRVAR(crypt_crypt__doc__, -"crypt(word, salt) -> string\n\ -word will usually be a user's password. salt is a 2-character string\n\ -which will be used to select one of 4096 variations of DES. The characters\n\ -in salt must be either \".\", \"/\", or an alphanumeric character. Returns\n\ -the hashed password as a string, which will be composed of characters from\n\ -the same alphabet as the salt."); - static PyMethodDef crypt_methods[] = { - {"crypt", crypt_crypt, METH_VARARGS, crypt_crypt__doc__}, + CRYPT_CRYPT_METHODDEF {NULL, NULL} /* sentinel */ }; diff --git a/Modules/_csv.c b/Modules/_csv.c index 183a9a5edb4d..af901e2d3ec0 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -239,10 +239,16 @@ _set_char(const char *name, Py_UCS4 *target, PyObject *src, Py_UCS4 dflt) *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 an 1-character string", + "\"%s\" must be a 1-character string", name); return -1; } @@ -284,7 +290,7 @@ dialect_check_quoting(int quoting) StyleDesc *qs; for (qs = quote_styles; qs->name; qs++) { - if (qs->style == quoting) + if ((int)qs->style == quoting) return 0; } PyErr_Format(PyExc_TypeError, "bad \"quoting\" value"); @@ -425,7 +431,8 @@ dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (dialect_check_quoting(self->quoting)) goto err; if (self->delimiter == 0) { - PyErr_SetString(PyExc_TypeError, "delimiter must be set"); + PyErr_SetString(PyExc_TypeError, + "\"delimiter\" must be a 1-character string"); goto err; } if (quotechar == Py_None && quoting == NULL) @@ -1002,7 +1009,7 @@ join_reset(WriterObj *self) */ static Py_ssize_t join_append_data(WriterObj *self, unsigned int field_kind, void *field_data, - Py_ssize_t field_len, int quote_empty, int *quoted, + Py_ssize_t field_len, int *quoted, int copy_phase) { DialectObj *dialect = self->dialect; @@ -1064,18 +1071,6 @@ join_append_data(WriterObj *self, unsigned int field_kind, void *field_data, ADDCH(c); } - /* If field is empty check if it needs to be quoted. - */ - if (i == 0 && quote_empty) { - if (dialect->quoting == QUOTE_NONE) { - PyErr_Format(_csvstate_global->error_obj, - "single empty field record must be quoted"); - return -1; - } - else - *quoted = 1; - } - if (*quoted) { if (copy_phase) ADDCH(dialect->quotechar); @@ -1119,7 +1114,7 @@ join_check_rec_size(WriterObj *self, Py_ssize_t rec_len) } static int -join_append(WriterObj *self, PyObject *field, int *quoted, int quote_empty) +join_append(WriterObj *self, PyObject *field, int quoted) { unsigned int field_kind = -1; void *field_data = NULL; @@ -1134,7 +1129,7 @@ join_append(WriterObj *self, PyObject *field, int *quoted, int quote_empty) field_len = PyUnicode_GET_LENGTH(field); } rec_len = join_append_data(self, field_kind, field_data, field_len, - quote_empty, quoted, 0); + "ed, 0); if (rec_len < 0) return 0; @@ -1143,7 +1138,7 @@ join_append(WriterObj *self, PyObject *field, int *quoted, int quote_empty) return 0; self->rec_len = join_append_data(self, field_kind, field_data, field_len, - quote_empty, quoted, 1); + "ed, 1); self->num_fields++; return 1; @@ -1174,37 +1169,30 @@ join_append_lineterminator(WriterObj *self) } PyDoc_STRVAR(csv_writerow_doc, -"writerow(sequence)\n" +"writerow(iterable)\n" "\n" -"Construct and write a CSV record from a sequence of fields. Non-string\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; - Py_ssize_t len, i; - PyObject *line, *result; - - if (!PySequence_Check(seq)) - return PyErr_Format(_csvstate_global->error_obj, "sequence expected"); + PyObject *iter, *field, *line, *result; - len = PySequence_Length(seq); - if (len < 0) - return NULL; + iter = PyObject_GetIter(seq); + if (iter == NULL) + return PyErr_Format(_csvstate_global->error_obj, + "iterable expected, not %.200s", + seq->ob_type->tp_name); /* Join all fields in internal buffer. */ join_reset(self); - for (i = 0; i < len; i++) { - PyObject *field; + while ((field = PyIter_Next(iter))) { int append_ok; int quoted; - field = PySequence_GetItem(seq, i); - if (field == NULL) - return NULL; - switch (dialect->quoting) { case QUOTE_NONNUMERIC: quoted = !PyNumber_Check(field); @@ -1218,11 +1206,11 @@ csv_writerow(WriterObj *self, PyObject *seq) } if (PyUnicode_Check(field)) { - append_ok = join_append(self, field, "ed, len == 1); + append_ok = join_append(self, field, quoted); Py_DECREF(field); } else if (field == Py_None) { - append_ok = join_append(self, NULL, "ed, len == 1); + append_ok = join_append(self, NULL, quoted); Py_DECREF(field); } else { @@ -1230,19 +1218,37 @@ csv_writerow(WriterObj *self, PyObject *seq) str = PyObject_Str(field); Py_DECREF(field); - if (str == NULL) + if (str == NULL) { + Py_DECREF(iter); return NULL; - append_ok = join_append(self, str, "ed, len == 1); + } + append_ok = join_append(self, str, quoted); Py_DECREF(str); } - if (!append_ok) + if (!append_ok) { + Py_DECREF(iter); + return NULL; + } + } + Py_DECREF(iter); + if (PyErr_Occurred()) + return NULL; + + if (self->num_fields > 0 && self->rec_size == 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 0; + return NULL; line = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, (void *) self->rec, self->rec_len); @@ -1254,9 +1260,9 @@ csv_writerow(WriterObj *self, PyObject *seq) } PyDoc_STRVAR(csv_writerows_doc, -"writerows(sequence of sequences)\n" +"writerows(iterable of iterables)\n" "\n" -"Construct and write a series of sequences to a csv file. Non-string\n" +"Construct and write a series of iterables to a csv file. Non-string\n" "elements will be converted to string."); static PyObject * @@ -1556,7 +1562,7 @@ PyDoc_STRVAR(csv_reader_doc, "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"); +"of the CSV file (which can span multiple input lines).\n"); PyDoc_STRVAR(csv_writer_doc, " csv_writer = csv.writer(fileobj [, dialect='excel']\n" @@ -1582,7 +1588,7 @@ PyDoc_STRVAR(csv_get_dialect_doc, PyDoc_STRVAR(csv_register_dialect_doc, "Create a mapping from a string name to a dialect class.\n" -" dialect = csv.register_dialect(name, dialect)"); +" dialect = csv.register_dialect(name[, dialect[, **fmtparams]])"); PyDoc_STRVAR(csv_unregister_dialect_doc, "Delete the name/dialect mapping associated with a string name.\n" diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 820a6060950a..b9fd82e835b5 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -159,10 +159,8 @@ _DictRemover_call(PyObject *myself, PyObject *args, PyObject *kw) if (-1 == PyDict_DelItem(self->dict, self->key)) /* XXX Error context */ PyErr_WriteUnraisable(Py_None); - Py_DECREF(self->key); - self->key = NULL; - Py_DECREF(self->dict); - self->dict = NULL; + Py_CLEAR(self->key); + Py_CLEAR(self->dict); } Py_INCREF(Py_None); return Py_None; @@ -290,6 +288,48 @@ _ctypes_alloc_format_string(const char *prefix, const char *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) + 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; +} + /* PyCStructType_Type - a meta type/class. Creating a new class using this one as __metaclass__ will call the contructor StructUnionType_new. It replaces the @@ -423,39 +463,45 @@ KeepRef(CDataObject *target, Py_ssize_t index, PyObject *keep); static PyObject * CDataType_from_buffer(PyObject *type, PyObject *args) { - void *buffer; - Py_ssize_t buffer_len; + Py_buffer buffer; Py_ssize_t offset = 0; - PyObject *obj, *result; + PyObject *result, *mv; StgDictObject *dict = PyType_stgdict(type); assert (dict); - if (!PyArg_ParseTuple(args, "O|n:from_buffer", &obj, &offset)) - return NULL; - - if (-1 == PyObject_AsWriteBuffer(obj, &buffer, &buffer_len)) + if (!PyArg_ParseTuple(args, "w*|n:from_buffer", &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) { + 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); + buffer.len, dict->size + offset); + PyBuffer_Release(&buffer); return NULL; } - result = PyCData_AtAddress(type, (char *)buffer + offset); - if (result == NULL) + result = PyCData_AtAddress(type, (char *)buffer.buf + offset); + if (result == NULL) { + PyBuffer_Release(&buffer); return NULL; + } - Py_INCREF(obj); - if (-1 == KeepRef((CDataObject *)result, -1, obj)) { + mv = PyMemoryView_FromBuffer(&buffer); + if (mv == NULL) { + PyBuffer_Release(&buffer); return NULL; } + /* Hack the memoryview so that it will release the buffer. */ + ((PyMemoryViewObject *)mv)->mbuf->master.obj = buffer.obj; + ((PyMemoryViewObject *)mv)->view.obj = buffer.obj; + if (-1 == KeepRef((CDataObject *)result, -1, mv)) + result = NULL; return result; } @@ -468,37 +514,36 @@ GenericPyCData_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static PyObject * CDataType_from_buffer_copy(PyObject *type, PyObject *args) { - const void *buffer; - Py_ssize_t buffer_len; + Py_buffer buffer; Py_ssize_t offset = 0; - PyObject *obj, *result; + PyObject *result; StgDictObject *dict = PyType_stgdict(type); assert (dict); - if (!PyArg_ParseTuple(args, "O|n:from_buffer", &obj, &offset)) - return NULL; - - if (-1 == PyObject_AsReadBuffer(obj, (const void**)&buffer, &buffer_len)) + if (!PyArg_ParseTuple(args, "y*|n:from_buffer", &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) { + 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); + buffer.len, dict->size + offset); + PyBuffer_Release(&buffer); return NULL; } result = GenericPyCData_new((PyTypeObject *)type, NULL, NULL); - if (result == NULL) - return NULL; - memcpy(((CDataObject *)result)->b_ptr, - (char *)buffer+offset, dict->size); + if (result != NULL) { + memcpy(((CDataObject *)result)->b_ptr, + (char *)buffer.buf + offset, dict->size); + } + PyBuffer_Release(&buffer); return result; } @@ -548,7 +593,7 @@ CDataType_in_dll(PyObject *type, PyObject *args) #ifdef __CYGWIN__ /* dlerror() isn't very helpful on cygwin */ PyErr_Format(PyExc_ValueError, - "symbol '%s' not found (%s) ", + "symbol '%s' not found", name); #else PyErr_SetString(PyExc_ValueError, ctypes_dlerror()); @@ -862,14 +907,21 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (proto) { StgDictObject *itemdict = PyType_stgdict(proto); + const char *current_format; 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... */ - stgdict->format = _ctypes_alloc_format_string("&", - itemdict->format ? itemdict->format : "B"); + 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; @@ -1033,7 +1085,7 @@ CharArray_set_raw(CDataObject *self, PyObject *value) ptr = view.buf; if (size > self->b_size) { PyErr_SetString(PyExc_ValueError, - "string too long"); + "byte string too long"); goto fail; } @@ -1085,7 +1137,7 @@ CharArray_set_value(CDataObject *self, PyObject *value) size = PyBytes_GET_SIZE(value); if (size > self->b_size) { PyErr_SetString(PyExc_ValueError, - "string too long"); + "byte string too long"); Py_DECREF(value); return -1; } @@ -1247,7 +1299,6 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) long length; int overflow; Py_ssize_t itemsize, itemalign; - char buf[32]; /* create the new instance (which is a class, since we are a metatype!) */ @@ -1297,13 +1348,7 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } assert(itemdict->format); - if (itemdict->format[0] == '(') { - sprintf(buf, "(%ld,", length); - stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format+1); - } else { - sprintf(buf, "(%ld)", length); - stgdict->format = _ctypes_alloc_format_string(buf, itemdict->format); - } + stgdict->format = _ctypes_alloc_format_string(NULL, itemdict->format); if (stgdict->format == NULL) goto error; stgdict->ndim = itemdict->ndim + 1; @@ -1431,7 +1476,7 @@ c_wchar_p_from_param(PyObject *type, PyObject *value) Py_INCREF(Py_None); return Py_None; } - if (PyUnicode_Check(value) || PyBytes_Check(value)) { + if (PyUnicode_Check(value)) { PyCArgObject *parg; struct fielddesc *fd = _ctypes_get_fielddesc("Z"); @@ -1583,25 +1628,8 @@ c_void_p_from_param(PyObject *type, PyObject *value) return (PyObject *)parg; } /* XXX struni: remove later */ -/* string */ - 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; - } /* bytes */ - if (PyByteArray_Check(value)) { + if (PyBytes_Check(value)) { PyCArgObject *parg; struct fielddesc *fd = _ctypes_get_fielddesc("z"); @@ -2791,8 +2819,9 @@ _PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, src->b_ptr, size); - if (PyCPointerTypeObject_Check(type)) - /* XXX */; + if (PyCPointerTypeObject_Check(type)) { + /* XXX */ + } value = GetKeepedObjects(src); if (value == NULL) @@ -2934,10 +2963,8 @@ static int PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob) { if (ob == NULL) { - Py_XDECREF(self->restype); - self->restype = NULL; - Py_XDECREF(self->checker); - self->checker = NULL; + Py_CLEAR(self->restype); + Py_CLEAR(self->checker); return 0; } if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) { @@ -2980,10 +3007,8 @@ PyCFuncPtr_set_argtypes(PyCFuncPtrObject *self, PyObject *ob) PyObject *converters; if (ob == NULL || ob == Py_None) { - Py_XDECREF(self->converters); - self->converters = NULL; - Py_XDECREF(self->argtypes); - self->argtypes = NULL; + Py_CLEAR(self->converters); + Py_CLEAR(self->argtypes); } else { converters = converters_from_argtypes(ob); if (!converters) @@ -3182,7 +3207,7 @@ _get_name(PyObject *obj, char **pname) return *pname ? 1 : 0; } PyErr_SetString(PyExc_TypeError, - "function name must be string or integer"); + "function name must be string, bytes object or integer"); return 0; } @@ -3255,7 +3280,7 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds) #ifdef __CYGWIN__ /* dlerror() isn't very helpful on cygwin */ PyErr_Format(PyExc_AttributeError, - "function '%s' not found (%s) ", + "function '%s' not found", name); #else PyErr_SetString(PyExc_AttributeError, ctypes_dlerror()); @@ -3838,7 +3863,7 @@ PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds) self, callargs, NULL); - /* If the errcheck funtion failed, return 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, @@ -4281,8 +4306,11 @@ Array_subscript(PyObject *myself, PyObject *item) slicelen); } - dest = (wchar_t *)PyMem_Malloc( - slicelen * sizeof(wchar_t)); + dest = PyMem_New(wchar_t, slicelen); + if (dest == NULL) { + PyErr_NoMemory(); + return NULL; + } for (cur = start, i = 0; i < slicelen; cur += step, i++) { @@ -4811,7 +4839,7 @@ Pointer_set_contents(CDataObject *self, PyObject *value, void *closure) *(void **)self->b_ptr = dst->b_ptr; /* - A Pointer instance must keep a the value it points to alive. So, a + 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. */ @@ -4962,7 +4990,7 @@ Pointer_subscript(PyObject *myself, PyObject *item) return PyUnicode_FromWideChar(ptr + start, len); } - dest = (wchar_t *)PyMem_Malloc(len * sizeof(wchar_t)); + dest = PyMem_New(wchar_t, len); if (dest == NULL) return PyErr_NoMemory(); for (cur = start, i = 0; i < len; cur += step, i++) { diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index 3a6845f39bb6..f957e02f1fd7 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -527,6 +527,49 @@ EXPORT(int) PointInRect(RECT *prc, POINT pt) 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; diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index ec8fd12a8969..7cd61640f819 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -92,49 +92,6 @@ PrintError(char *msg, ...) } -/* after code that pyrex generates */ -void _ctypes_add_traceback(char *funcname, char *filename, int lineno) -{ - PyObject *py_globals = 0; - PyCodeObject *py_code = 0; - PyFrameObject *py_frame = 0; - PyObject *exception, *value, *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(&exception, &value, &tb); - - py_globals = PyDict_New(); - if (!py_globals) - goto bad; - py_code = PyCode_NewEmpty(filename, funcname, lineno); - if (!py_code) - goto bad; - py_frame = PyFrame_New( - PyThreadState_Get(), /*PyThreadState *tstate,*/ - py_code, /*PyCodeObject *code,*/ - py_globals, /*PyObject *globals,*/ - 0 /*PyObject *locals*/ - ); - if (!py_frame) - goto bad; - py_frame->f_lineno = lineno; - - PyErr_Restore(exception, value, tb); - PyTraceBack_Here(py_frame); - - Py_DECREF(py_globals); - Py_DECREF(py_code); - Py_DECREF(py_frame); - return; - - bad: - Py_XDECREF(py_globals); - Py_XDECREF(py_code); - Py_XDECREF(py_frame); -} - #ifdef MS_WIN32 /* * We must call AddRef() on non-NULL COM pointers we receive as arguments @@ -254,7 +211,7 @@ static void _CallPythonObject(void *mem, } #define CHECK(what, x) \ -if (x == NULL) _ctypes_add_traceback(what, "_ctypes/callbacks.c", __LINE__ - 1), PyErr_Print() +if (x == NULL) _PyTraceback_Add(what, "_ctypes/callbacks.c", __LINE__ - 1), PyErr_Print() if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) { error_object = _ctypes_get_errobj(&space); diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 74119a3b4d08..03a911fa0698 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -919,7 +919,7 @@ static PyObject *GetResult(PyObject *restype, void *result, PyObject *checker) v = PyObject_CallFunctionObjArgs(checker, retval, NULL); if (v == NULL) - _ctypes_add_traceback("GetResult", "_ctypes/callproc.c", __LINE__-2); + _PyTraceback_Add("GetResult", "_ctypes/callproc.c", __LINE__-2); Py_DECREF(retval); return v; } @@ -1140,9 +1140,6 @@ PyObject *_ctypes_callproc(PPROC pProc, for (i = 0; i < argcount; ++i) { atypes[i] = args[i].ffi_type; if (atypes[i]->type == FFI_TYPE_STRUCT -#ifdef _WIN64 - && atypes[i]->size <= sizeof(void *) -#endif ) avalues[i] = (void *)args[i].value.p; else @@ -1606,7 +1603,7 @@ resize(PyObject *self, PyObject *args) "Memory cannot be resized because this object doesn't own it"); return NULL; } - if (size <= sizeof(obj->b_value)) { + if ((size_t)size <= sizeof(obj->b_value)) { /* internal default buffer is large enough */ obj->b_size = size; goto done; @@ -1672,24 +1669,30 @@ POINTER(PyObject *self, PyObject *cls) } if (PyUnicode_CheckExact(cls)) { char *name = _PyUnicode_AsString(cls); - buf = alloca(strlen(name) + 3 + 1); + 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); } else if (PyType_Check(cls)) { typ = (PyTypeObject *)cls; - buf = alloca(strlen(typ->tp_name) + 3 + 1); + 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); diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 65772cfa45a4..3c7a52a6d9ed 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -765,6 +765,7 @@ I_set_sw(void *ptr, PyObject *value, Py_ssize_t size) 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)); @@ -1160,7 +1161,7 @@ c_set(void *ptr, PyObject *value, Py_ssize_t size) } error: PyErr_Format(PyExc_TypeError, - "one character string expected"); + "one character bytes, bytearray or integer expected"); return NULL; } @@ -1295,7 +1296,7 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length) Py_INCREF(value); } else { PyErr_Format(PyExc_TypeError, - "expected string, %s found", + "expected bytes, %s found", value->ob_type->tp_name); return NULL; } @@ -1311,7 +1312,7 @@ s_set(void *ptr, PyObject *value, Py_ssize_t length) ++size; } else if (size > length) { PyErr_Format(PyExc_ValueError, - "string too long (%zd, maximum length %zd)", + "bytes too long (%zd, maximum length %zd)", size, length); Py_DECREF(value); return NULL; @@ -1354,14 +1355,6 @@ z_get(void *ptr, Py_ssize_t size) { /* XXX What about invalid pointers ??? */ if (*(void **)ptr) { -#if defined(MS_WIN32) && !defined(_WIN32_WCE) - if (IsBadStringPtrA(*(char **)ptr, -1)) { - PyErr_Format(PyExc_ValueError, - "invalid string pointer %p", - *(char **)ptr); - return NULL; - } -#endif return PyBytes_FromStringAndSize(*(char **)ptr, strlen(*(char **)ptr)); } else { @@ -1418,14 +1411,6 @@ Z_get(void *ptr, Py_ssize_t size) wchar_t *p; p = *(wchar_t **)ptr; if (p) { -#if defined(MS_WIN32) && !defined(_WIN32_WCE) - if (IsBadStringPtrW(*(wchar_t **)ptr, -1)) { - PyErr_Format(PyExc_ValueError, - "invalid string pointer %p", - *(wchar_t **)ptr); - return NULL; - } -#endif return PyUnicode_FromWideChar(p, wcslen(p)); } else { Py_INCREF(Py_None); @@ -1455,15 +1440,15 @@ BSTR_set(void *ptr, PyObject *value, Py_ssize_t size) /* create a BSTR from value */ if (value) { wchar_t* wvalue; - Py_ssize_t size; - wvalue = PyUnicode_AsUnicodeAndSize(value, &size); + Py_ssize_t wsize; + wvalue = PyUnicode_AsUnicodeAndSize(value, &wsize); if (wvalue == NULL) return NULL; - if ((unsigned) size != size) { + if ((unsigned) wsize != wsize) { PyErr_SetString(PyExc_ValueError, "String too long for BSTR"); return NULL; } - bstr = SysAllocStringLen(wvalue, (unsigned)size); + bstr = SysAllocStringLen(wvalue, (unsigned)wsize); Py_DECREF(value); } else bstr = NULL; @@ -1640,9 +1625,9 @@ 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 INT_ALIGN (sizeof(s_int) - sizeof(int)) #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)) @@ -1684,8 +1669,8 @@ 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, 4, FFI_TYPE_UINT32 }; -ffi_type ffi_type_sint32 = { 4, 4, FFI_TYPE_SINT32 }; +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 }; diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index 5237ac23d6d1..0d3f7241ca8f 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -191,7 +191,7 @@ typedef struct { 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 doen't + 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 */ @@ -353,10 +353,11 @@ extern char *_ctypes_conversion_errors; extern void _ctypes_free_closure(void *); extern void *_ctypes_alloc_closure(void); -extern void _ctypes_add_traceback(char *, char *, int); - 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); diff --git a/Modules/_ctypes/libffi.diff b/Modules/_ctypes/libffi.diff index ade28e5f9e27..ffa7bafe0e09 100644 --- a/Modules/_ctypes/libffi.diff +++ b/Modules/_ctypes/libffi.diff @@ -1,8 +1,7 @@ -diff -r -N -u libffi.orig/autom4te.cache/output.0 libffi/autom4te.cache/output.0 -diff -r -N -u libffi.orig/configure libffi/configure ---- libffi.orig/configure 2013-03-17 15:37:50.000000000 -0700 -+++ libffi/configure 2013-03-18 15:11:39.611575163 -0700 -@@ -13368,6 +13368,10 @@ +diff -urN libffi-3.1/configure libffi/configure +--- libffi-3.1/configure 2014-05-19 15:44:03.000000000 +0200 ++++ libffi/configure 2014-08-09 21:51:07.877871443 +0200 +@@ -17236,6 +17236,10 @@ fi ;; @@ -13,22 +12,22 @@ diff -r -N -u libffi.orig/configure libffi/configure x86_64-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86 ;; -@@ -13426,12 +13430,12 @@ +@@ -17298,12 +17302,12 @@ ;; mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*) - TARGET=MIPS; TARGETDIR=mips + TARGET=MIPS_IRIX; TARGETDIR=mips ;; - mips*-*-linux* | mips*-*-openbsd*) + mips*-*linux* | mips*-*-openbsd*) # Support 128-bit long double for NewABI. HAVE_LONG_DOUBLE='defined(__mips64)' - TARGET=MIPS; TARGETDIR=mips -+ TARGET=MIPS_IRIX; TARGETDIR=mips ++ TARGET=MIPS_LINUX; TARGETDIR=mips ;; - powerpc*-*-linux* | powerpc-*-sysv*) -@@ -13491,7 +13495,7 @@ + nios2*-linux*) +@@ -17373,7 +17377,7 @@ as_fn_error $? "\"libffi has not been ported to $host.\"" "$LINENO" 5 fi @@ -37,7 +36,7 @@ diff -r -N -u libffi.orig/configure libffi/configure MIPS_TRUE= MIPS_FALSE='#' else -@@ -14862,6 +14866,12 @@ +@@ -18814,6 +18818,12 @@ ac_config_files="$ac_config_files include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile libffi.pc" @@ -50,7 +49,7 @@ diff -r -N -u libffi.orig/configure libffi/configure cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure -@@ -16047,6 +16057,8 @@ +@@ -20126,6 +20136,8 @@ "testsuite/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/Makefile" ;; "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;; "libffi.pc") CONFIG_FILES="$CONFIG_FILES libffi.pc" ;; @@ -59,9 +58,9 @@ diff -r -N -u libffi.orig/configure libffi/configure *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac -diff -r -N -u libffi.orig/configure.ac libffi/configure.ac ---- libffi.orig/configure.ac 2013-03-17 15:37:50.000000000 -0700 -+++ libffi/configure.ac 2013-03-18 15:11:11.392989136 -0700 +diff -urN libffi-3.1/configure.ac libffi/configure.ac +--- libffi-3.1/configure.ac 2014-05-11 15:57:49.000000000 +0200 ++++ libffi/configure.ac 2014-08-09 21:51:07.877871443 +0200 @@ -1,4 +1,7 @@ dnl Process this with autoconf to create configure +# @@ -70,33 +69,32 @@ diff -r -N -u libffi.orig/configure.ac libffi/configure.ac AC_PREREQ(2.68) -@@ -146,6 +149,10 @@ - fi +@@ -144,6 +147,9 @@ + AM_LTLDFLAGS='-no-undefined -bindir "$(bindir)"'; + fi ;; - + i*86-*-nto-qnx*) + TARGET=X86; TARGETDIR=x86 + ;; -+ - x86_64-*-darwin*) + i?86-*-darwin*) TARGET=X86_DARWIN; TARGETDIR=x86 ;; -@@ -204,12 +211,12 @@ +@@ -218,12 +224,12 @@ ;; mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*) - TARGET=MIPS; TARGETDIR=mips + TARGET=MIPS_IRIX; TARGETDIR=mips ;; - mips*-*-linux* | mips*-*-openbsd*) + mips*-*linux* | mips*-*-openbsd*) # Support 128-bit long double for NewABI. HAVE_LONG_DOUBLE='defined(__mips64)' - TARGET=MIPS; TARGETDIR=mips -+ TARGET=MIPS_IRIX; TARGETDIR=mips ++ TARGET=MIPS_LINUX; TARGETDIR=mips ;; - powerpc*-*-linux* | powerpc-*-sysv*) -@@ -269,7 +276,7 @@ + nios2*-linux*) +@@ -293,7 +299,7 @@ AC_MSG_ERROR(["libffi has not been ported to $host."]) fi @@ -105,7 +103,7 @@ diff -r -N -u libffi.orig/configure.ac libffi/configure.ac AM_CONDITIONAL(BFIN, test x$TARGET = xBFIN) AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC) AM_CONDITIONAL(X86, test x$TARGET = xX86) -@@ -567,4 +574,8 @@ +@@ -617,4 +623,8 @@ AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile libffi.pc) @@ -114,19 +112,19 @@ diff -r -N -u libffi.orig/configure.ac libffi/configure.ac +AC_CONFIG_FILES(fficonfig.py) + AC_OUTPUT ---- libffi-3.0.11/fficonfig.py.in 1970-01-01 01:00:00.000000000 +0100 -+++ libffi/fficonfig.py.in 2012-03-15 01:04:27.000000000 +0100 +diff -urN libffi-3.1/fficonfig.py.in libffi/fficonfig.py.in +--- libffi-3.1/fficonfig.py.in 1970-01-01 01:00:00.000000000 +0100 ++++ libffi/fficonfig.py.in 2014-08-09 21:43:25.229871827 +0200 @@ -0,0 +1,35 @@ +ffi_sources = """ +src/prep_cif.c +src/closures.c -+src/dlmalloc.c +""".split() + +ffi_platforms = { + 'MIPS_IRIX': ['src/mips/ffi.c', 'src/mips/o32.S', 'src/mips/n32.S'], + 'MIPS_LINUX': ['src/mips/ffi.c', 'src/mips/o32.S'], -+ 'X86': ['src/x86/ffi.c', 'src/x86/sysv.S'], ++ 'X86': ['src/x86/ffi.c', 'src/x86/sysv.S', 'src/x86/win32.S'], + 'X86_FREEBSD': ['src/x86/ffi.c', 'src/x86/freebsd.S'], + 'X86_WIN32': ['src/x86/ffi.c', 'src/x86/win32.S'], + 'SPARC': ['src/sparc/ffi.c', 'src/sparc/v8.S', 'src/sparc/v9.S'], @@ -134,9 +132,10 @@ diff -r -N -u libffi.orig/configure.ac libffi/configure.ac + 'IA64': ['src/ia64/ffi.c', 'src/ia64/unix.S'], + 'M32R': ['src/m32r/sysv.S', 'src/m32r/ffi.c'], + 'M68K': ['src/m68k/ffi.c', 'src/m68k/sysv.S'], -+ 'POWERPC': ['src/powerpc/ffi.c', 'src/powerpc/sysv.S', 'src/powerpc/ppc_closure.S', 'src/powerpc/linux64.S', 'src/powerpc/linux64_closure.S'], ++ 'POWERPC': ['src/powerpc/ffi.c', 'src/powerpc/ffi_sysv.c', 'src/powerpc/ffi_linux64.c', 'src/powerpc/sysv.S', 'src/powerpc/ppc_closure.S', 'src/powerpc/linux64.S', 'src/powerpc/linux64_closure.S'], + 'POWERPC_AIX': ['src/powerpc/ffi_darwin.c', 'src/powerpc/aix.S', 'src/powerpc/aix_closure.S'], + 'POWERPC_FREEBSD': ['src/powerpc/ffi.c', 'src/powerpc/sysv.S', 'src/powerpc/ppc_closure.S'], ++ 'AARCH64': ['src/aarch64/sysv.S', 'src/aarch64/ffi.c'], + 'ARM': ['src/arm/sysv.S', 'src/arm/ffi.c'], + 'LIBFFI_CRIS': ['src/cris/sysv.S', 'src/cris/ffi.c'], + 'FRV': ['src/frv/eabi.S', 'src/frv/ffi.c'], @@ -152,9 +151,9 @@ diff -r -N -u libffi.orig/configure.ac libffi/configure.ac +ffi_sources += ffi_platforms['@TARGET@'] + +ffi_cflags = '@CFLAGS@' -diff -urN libffi-3.0.11/src/dlmalloc.c libffi/src/dlmalloc.c ---- libffi-3.0.11/src/dlmalloc.c 2012-04-12 04:46:06.000000000 +0200 -+++ libffi/src/dlmalloc.c 2012-06-26 15:15:58.949547461 +0200 +diff -urN libffi-3.1/src/dlmalloc.c libffi/src/dlmalloc.c +--- libffi-3.1/src/dlmalloc.c 2014-04-25 19:45:13.000000000 +0200 ++++ libffi/src/dlmalloc.c 2014-08-09 21:51:07.881871443 +0200 @@ -457,6 +457,11 @@ #define LACKS_ERRNO_H #define MALLOC_FAILURE_ACTION @@ -167,3 +166,44 @@ diff -urN libffi-3.0.11/src/dlmalloc.c libffi/src/dlmalloc.c #endif /* WIN32 */ #ifdef __OS2__ +@@ -4497,7 +4502,7 @@ + char* tbase = (char*)(CALL_MMAP(tsize)); + if (tbase != CMFAIL) { + m = init_user_mstate(tbase, tsize); +- set_segment_flags(&m->seg, IS_MMAPPED_BIT); ++ (void)set_segment_flags(&m->seg, IS_MMAPPED_BIT); + set_lock(m, locked); + } + } +@@ -4512,7 +4517,7 @@ + if (capacity > msize + TOP_FOOT_SIZE && + capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { + m = init_user_mstate((char*)base, capacity); +- set_segment_flags(&m->seg, EXTERN_BIT); ++ (void)set_segment_flags(&m->seg, EXTERN_BIT); + set_lock(m, locked); + } + return (mspace)m; +diff -urN libffi-3.1/src/arm/ffi.c libffi/src/arm/ffi.c +--- libffi-3.1/src/arm/ffi.c Sat Aug 09 23:52:34 2014 +0200 ++++ libffi/src/arm/ffi.c Sat Aug 09 23:58:38 2014 +0200 +@@ -154,9 +154,6 @@ + + int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space) + { +- // make sure we are using FFI_VFP +- FFI_ASSERT(ecif->cif->abi == FFI_VFP); +- + register unsigned int i, vi = 0; + register void **p_argv; + register char *argp, *regp, *eo_regp; +@@ -165,6 +162,9 @@ + char done_with_regs = 0; + char is_vfp_type; + ++ // make sure we are using FFI_VFP ++ FFI_ASSERT(ecif->cif->abi == FFI_VFP); ++ + /* the first 4 words on the stack are used for values passed in core + * registers. */ + regp = stack; diff --git a/Modules/_ctypes/libffi/.gitignore b/Modules/_ctypes/libffi/.gitignore deleted file mode 100644 index 6af76ac33c99..000000000000 --- a/Modules/_ctypes/libffi/.gitignore +++ /dev/null @@ -1,21 +0,0 @@ -.libs -.deps -*.o -*.lo -.dirstamp -*.la -Makefile -config.log -config.status -*~ -fficonfig.h -include/ffi.h -include/ffitarget.h -libffi.pc -libtool -stamp-h1 -libffi*gz -autom4te.cache -libffi.xcodeproj/xcuserdata -libffi.xcodeproj/project.xcworkspace -ios/ diff --git a/Modules/_ctypes/libffi/.travis.yml b/Modules/_ctypes/libffi/.travis.yml deleted file mode 100644 index 1a6a425c066e..000000000000 --- a/Modules/_ctypes/libffi/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -language: c -compiler: - - gcc - - clang - -before_script: sudo apt-get install dejagnu - -script: ./configure && make && make check diff --git a/Modules/_ctypes/libffi/ChangeLog b/Modules/_ctypes/libffi/ChangeLog index e0b057c79a49..c85cbe621acc 100644 --- a/Modules/_ctypes/libffi/ChangeLog +++ b/Modules/_ctypes/libffi/ChangeLog @@ -1,5509 +1,5105 @@ -2013-03-17 Anthony Green +commit 0403f332b1f478696c30d3d8a0e2f6eef24aaf88 +Author: Anthony Green +Date: Mon May 19 09:41:32 2014 -0400 - * README: Update for 3.0.13. - * configure.ac: Ditto. - * configure: Rebuilt. - * doc/*: Update version. + Update date. Annoucing 3.1 today. -2013-03-17 Dave Korn +commit 94ac0c168ee7b115409121d88b25a4979446c8da +Author: Anthony Green +Date: Mon May 19 09:37:21 2014 -0400 - * src/closures.c (is_emutramp_enabled - [!FFI_MMAP_EXEC_EMUTRAMP_PAX]): Move default definition outside - enclosing #if scope. + Increment libtool library revision number -2013-03-17 Anthony Green +commit 57465744b6e1295d7202de5a7734df589518f1c8 +Author: Anthony Green +Date: Sun May 11 10:30:22 2014 -0400 - * configure.ac: Only modify toolexecdir in certain cases. - * configure: Rebuilt. + Update to version 3.1 -2013-03-16 Gilles Talis +commit 0c2251a42df5108b6d9ebe5fe1cf83d0bcdf660e +Author: Anthony Green +Date: Sun May 11 10:22:30 2014 -0400 - * src/powerpc/ffi.c (ffi_prep_args_SYSV): Don't use - fparg_count,etc on __NO_FPRS__ targets. + Support versions of git older than 1.8.5 -2013-03-16 Alan Hourihane +commit 70c303cb88e23aaee91c87c56b108c50ab4f3c2f +Author: Anthony Green +Date: Sun May 11 09:56:40 2014 -0400 - * src/m68k/sysv.S (epilogue): Don't use extb instruction on - m680000 machines. + Fix testsuite for GCC 4.9.0 -2013-03-16 Alex Gaynor +commit 52b3457093ed19b2a7c5fcf243c4014c90ce6225 +Author: Magnus Granberg +Date: Sun May 11 09:55:28 2014 -0400 - * src/x86/ffi.c (ffi_prep_cif_machdep): Always align stack. + Check /proc/self/status for PaX status. -2013-03-13 Markos Chandras +commit 7ba4c5d72aa440a4b21fb57e999e67c5957761da +Author: Dominik Vogt +Date: Sun May 11 09:52:47 2014 -0400 - * configure.ac: Add support for Imagination Technologies Meta. - * Makefile.am: Likewise. - * README: Add Imagination Technologies Meta details. - * src/metag/ffi.c: New. - * src/metag/ffitarget.h: Likewise. - * src/metag/sysv.S: Likewise. + Use to get correct dir -2013-02-24 Andreas Schwab +commit 31e0d4ecff6dc2a6c75a066ee099b52a43f6ba27 +Merge: 1c0e9a7 99909eb +Author: Anthony Green +Date: Wed Apr 23 19:24:47 2014 -0400 - * doc/libffi.texi (Structures): Fix missing category argument of - @deftp. + Merge pull request #119 from joshtriplett/fastcall-fastball + + src/x86/win32.S: Define ffi_closure_FASTCALL in the MASM section, too -2013-02-11 Anthony Green +commit 99909eb6184b62408d88b6b4e7ab38e84e6d0bf3 +Author: Josh Triplett +Date: Tue Apr 22 21:17:52 2014 -0700 - * configure.ac: Update release number to 3.0.12. - * configure: Rebuilt. - * README: Update release info. + src/x86/win32.S: Define ffi_closure_FASTCALL in the MASM section, too -2013-02-10 Anthony Green +commit 1c0e9a7297ced15413c2d2d5d35f6c650c4b46c9 +Merge: 93a24f2 d369522 +Author: Anthony Green +Date: Mon Apr 21 12:41:56 2014 -0400 - * README: Add Moxie. - * src/moxie/ffi.c: Created. - * src/moxie/eabi.S: Created. - * src/moxie/ffitarget.h: Created. - * Makefile.am (nodist_libffi_la_SOURCES): Add Moxie. - * Makefile.in: Rebuilt. - * configure.ac: Add Moxie. - * configure: Rebuilt. - * testsuite/libffi.call/huge_struct.c: Disable format string - warnings for moxie*-*-elf tests. + Merge pull request #101 from joshtriplett/fastcall-closures + + Support closures for fastcall -2013-02-10 Anthony Green +commit d36952273d4fafbda91ecc205fc0824f7cc65e70 +Author: Josh Triplett +Date: Sun Apr 20 12:03:25 2014 -0700 - * Makefile.am (LTLDFLAGS): Fix reference. - * Makefile.in: Rebuilt. + Support fastcall closures + + libffi on 32-bit x86 now supports closures for all supported ABIs. + Thus, rewrite the last remaining duplicated-by-ABI test (closure_stdcall + and closure_thiscall) to use the generic ABI_NUM/ABI_ATTR mechanism. -2013-02-10 Anthony Green +commit 93a24f216bcdd1018b976d697179c6d49004015a +Merge: dd11a04 2349fec +Author: Anthony Green +Date: Sat Apr 12 19:38:07 2014 -0400 - * README: Update supported platforms. Update test results link. + Merge pull request #80 from ueno/devel + + Fix typo in doc -2013-02-09 Anthony Green +commit dd11a04061cb49ce1d702545693c24eb1267d648 +Merge: 8fa2812 03ca880 +Author: Anthony Green +Date: Sat Apr 12 19:37:21 2014 -0400 - * testsuite/libffi.call/negint.c: Remove forced -O2. - * testsuite/libffi.call/many2.c (foo): Remove GCCism. - * testsuite/libffi.call/ffitest.h: Add default PRIuPTR definition. + Merge pull request #86 from joshtriplett/testsuite-CC-CXX + + testsuite ignores CC parameter supplied to configure or make - * src/sparc/v8.S (ffi_closure_v8): Import ancient ulonglong - closure return type fix developed by Martin v. Löwis for cpython - fork. +commit 8fa2812355e685a42abf9a62fbc674d616b2edee +Merge: 8a58e6b 419503f +Author: Anthony Green +Date: Sat Apr 12 19:32:08 2014 -0400 -2013-02-08 Andreas Tobler + Merge pull request #116 from frida/fix/darwin-aarch64-variadic + + Fix handling of variadic calls on Darwin/AArch64 - * src/powerpc/ffi.c (ffi_prep_cif_machdep): Fix small struct - support. - * src/powerpc/sysv.S: Ditto. +commit 8a58e6b7805b736def197b8baf8e465a2a3f6913 +Merge: 30b77c5 a539f7f +Author: Anthony Green +Date: Sat Apr 12 19:30:18 2014 -0400 -2013-02-08 Anthony Green + Merge pull request #115 from frida/fix/darwin-aarch64-alignment + + Fix alignment of AArch64 assembler functions - * testsuite/libffi.call/cls_longdouble.c: Remove xfail for - arm*-*-*. +commit 30b77c56f95c63ecd83399aafdbad7b07330f2fd +Merge: dc33cb3 3e2b84d +Author: Anthony Green +Date: Sat Apr 12 19:29:13 2014 -0400 -2013-02-08 Anthony Green + Merge pull request #117 from frida/fix/windows-regression + + Fix Windows regression - * src/sparc/ffi.c (ffi_prep_closure_loc): Fix cache flushing for GCC. +commit 3e2b84d295531720917bf46afc532fc6d877e3ec +Author: Ole André Vadla Ravnås +Date: Sat Apr 12 01:04:04 2014 +0200 -2013-02-08 Matthias Klose + Fix Windows regression + + Introduced by b5fed601948237037513a9b7f967c8fc6c9ff1f6. - * man/ffi_prep_cif.3: Clean up for debian linter. +commit 419503f409c321fe31ff59d963ef34bb913420d0 +Author: Ole André Vadla Ravnås +Date: Sun Apr 6 20:54:13 2014 +0200 -2013-02-08 Peter Bergner + Fix handling of variadic calls on Darwin/AArch64 - * src/powerpc/ffi.c (ffi_prep_args_SYSV): Account for FP args pushed - on the stack. +commit a539f7ffd6783aa11353d13265520e453c565fb4 +Author: Ole André Vadla Ravnås +Date: Sun Apr 6 20:53:02 2014 +0200 -2013-02-08 Anthony Green + Fix alignment of AArch64 assembler functions + +commit dc33cb3c998da521a960385c1269c3aef552f69f +Merge: c860a99 b5fed60 +Author: Anthony Green +Date: Sat Apr 5 23:41:22 2014 -0400 - * Makefile.am (EXTRA_DIST): Add missing files. - * testsuite/Makefile.am (EXTRA_DIST): Ditto. - * Makefile.in: Rebuilt. + Merge pull request #114 from joshtriplett/bounce-on-a-tiny-trampoline + + Fix ABI on 32-bit non-Windows x86: go back to trampoline size 10 + +commit b5fed601948237037513a9b7f967c8fc6c9ff1f6 +Author: Josh Triplett +Date: Sat Apr 5 17:33:42 2014 -0700 + + Fix ABI on 32-bit non-Windows x86: go back to trampoline size 10 + + The trampoline size is part of the ABI, so it cannot change. Move the + logic from the stdcall and thiscall trampolines to the functions they + call, to reduce them both to 10 bytes. + + This drops the previously added support for raw THISCALL closures on + non-Windows. (Non-raw THISCALL closures still work.) + +commit 03ca880081b22efab09ba72268270f83017d3d7b +Author: Josh Triplett +Date: Thu Mar 27 08:44:34 2014 -0700 + + README: Note the testsuite changes to respect $CC and $CXX + +commit d74df8c5d8c6722ecb908da98c86cc8e2c755b84 +Author: Josh Triplett +Date: Thu Mar 27 00:44:12 2014 -0700 + + README: Update Windows example to set both CC and CXX -2013-02-08 Anthony Green +commit 7d698125b1f05173f3656a89755a2eb58813b002 +Author: Josh Triplett +Date: Wed Mar 26 23:17:56 2014 -0700 - * configure.ac: Move sparc asm config checks to within functions - for compatibility with sun tools. - * configure: Rebuilt. - * src/sparc/ffi.c (ffi_prep_closure_loc): Flush cache on v9 - systems. - * src/sparc/v8.S (ffi_flush_icache): Implement a sparc v9 cache - flusher. + Use the proper C++ compiler to run C++ tests + + Running the C compiler with -shared-libgcc -lstdc++ does not work on + non-GCC compilers. -2013-02-08 Nathan Rossi +commit fa5e88f170cb37c7b2b9bb015c8c5b854ffd8a3e +Author: Josh Triplett +Date: Wed Mar 26 23:53:57 2014 -0700 - * src/microblaze/ffi.c (ffi_closure_call_SYSV): Fix handling of - small big-endian structures. - (ffi_prep_args): Ditto. + .travis.yml: Make the build command more readable by splitting at && + + "script" can contain multiple commands to run in sequence. -2013-02-07 Anthony Green +commit 0c3824702d3d59d37f8c177d646303f546187683 +Author: Josh Triplett +Date: Wed Mar 26 14:51:32 2014 -0700 + + Always set CC_FOR_TARGET for dejagnu, to make the testsuite respect $CC + + This fixes cross-compilation and compilation with CC="gcc -m32". + +commit 9946a92af31b30cb7760150d1f8ca6c11b01aeea +Author: Josh Triplett +Date: Wed Mar 26 20:18:58 2014 -0700 + + Stop looking for expect and runtest above top_builddir + + Users wishing to test hand-compiled versions of expect and runtest can + easily enough put them in their path or set EXPECT and RUNTEST + themselves. - * src/sparc/v8.S (ffi_call_v8): Fix typo from last patch - (effectively hiding ffi_call_v8). +commit acb202325215058639234efb7af1f04c1c8a1f44 +Author: Josh Triplett +Date: Wed Mar 26 20:18:41 2014 -0700 + + Stop setting an empty AM_RUNTESTFLAGS -2013-02-07 Anthony Green +commit c860a992fef5d7cd7bb0975b1632d17a9fafe007 +Author: Anthony Green +Date: Tue Mar 25 17:02:51 2014 -0400 - * configure.ac: Update bug reporting address. - * configure.in: Rebuild. + Upgrade version to 3.1-rc1 + +commit 9837073e6203048a162a226798c5d252600219ed +Author: Anthony Green +Date: Tue Mar 25 16:24:14 2014 -0400 + + Update copyright date and clean up README notes. - * src/sparc/v8.S (ffi_flush_icache): Out-of-line cache flusher for - Sun compiler. - * src/sparc/ffi.c (ffi_call): Remove warning. - Call ffi_flush_icache for non-GCC builds. - (ffi_prep_closure_loc): Use ffi_flush_icache. +commit 18d3baa9f597b026675baa1b4e5a5eeef7577a08 +Merge: afee537 f0c8a31 +Author: Anthony Green +Date: Tue Mar 25 16:12:53 2014 -0400 + + Merge pull request #108 from joshtriplett/freebsd + + [3.1 blocker] Fix FreeBSD support + +commit afee53738a995e23bd2f89fd0f7b30b380566106 +Merge: 7d24785 b2d610e +Author: Anthony Green +Date: Tue Mar 25 16:12:35 2014 -0400 + + Merge pull request #106 from joshtriplett/darwin-award + + [3.1 blocker] Update OS X build system to include win32.S on 32-bit + +commit 7d2478568ed9f03cbf57627f449a2d2cf4d1571c +Merge: beab5f3 56be47f +Author: Anthony Green +Date: Tue Mar 25 16:12:17 2014 -0400 + + Merge pull request #110 from joshtriplett/w64 + + Fix 64-bit Windows support + +commit beab5f334d9ec5b8b91d1cc727d1029b40358e7e +Merge: 28fb197 ef5890e +Author: Anthony Green +Date: Tue Mar 25 16:07:47 2014 -0400 + + Merge pull request #105 from joshtriplett/win32-relocations + + [3.1 blocker] win32.S needs to handle relocations/GOT + +commit f0c8a31577172104049283f0a80c723084a5bd77 +Author: Josh Triplett +Date: Mon Mar 24 22:14:26 2014 -0700 + + Compile win32.S on FreeBSD + +commit b2d610e028b5ce48d1ad7e5d0debc9c321d891b2 +Author: Josh Triplett +Date: Fri Mar 21 11:10:13 2014 -0700 + + Compile win32.S on 32-bit Darwin as well + +commit be50b87a490e794362cb4a27ada2fbaab202adb8 +Author: Josh Triplett +Date: Mon Mar 24 21:44:13 2014 -0700 + + Always use configure to detect whether global symbols need underscores + + 64-bit Windows already used this check; make it universal, and use it in + place of an ifdef on X86_WIN32, to handle non-Windows platforms that use + the underscore, such as Darwin. + +commit 56be47f87629e31afbcb0774aa65735f539ee972 +Author: Josh Triplett +Date: Mon Mar 24 21:24:53 2014 -0700 + + Fix a warning on 64-bit Windows + + When sizeof(size_t) != sizeof(unsigned), adding a size_t to cif->bytes + produces a "possible loss of data" warning. However, the size_t in + question refers to the size of a single parameter. Use a cast to avoid + the warning. + +commit 48a8eda74aad8a21b6f26df5df08fe64c043d208 +Author: Josh Triplett +Date: Mon Mar 24 21:21:12 2014 -0700 + + Avoid referencing undefined ABIs on 64-bit Windows builds + + 64-bit Windows does not have FFI_STDCALL, FFI_THISCALL, or FFI_FASTCALL. + +commit f0f4138f90345d7d67dfa6783a7e1c7cc30d3c6f +Author: Josh Triplett +Date: Sat Mar 22 10:00:53 2014 -0700 + + win32.S: Add handling for position-independent code on Darwin + + Newer versions of Darwin generate the necessary stub functions + automatically and just need a call instruction, but accomodating older + versions as well requires adding the stub. + +commit ef5890ebafb7cd2fbf9acf161edb55fe1382871c +Author: Josh Triplett +Date: Fri Mar 21 11:01:39 2014 -0700 + + win32.S: Use shifting for multiplication rather than repeated addition + + The jump table code added a register to itself twice to multiply by 4; + shift the register left by 2 instead. + +commit 4fca48901e7e4f53bf490ed22607b2d2d8f4bfcc +Author: Josh Triplett +Date: Fri Mar 21 11:00:41 2014 -0700 + + win32.S: Make the jump tables position-independent + + Now that non-Windows platforms include win32.S, it needs to support + building as position-independent code. This fixes build failures on + target platforms that do not allow text relocations. + +commit 2087dcf736274286f76c69d3988fb6d7cc4fd0f5 +Author: Josh Triplett +Date: Fri Mar 21 10:57:06 2014 -0700 + + win32.S: Make calls to ffi_closure_SYSV_inner position-independent + + Now that non-Windows platforms include win32.S, it needs to support + building as position-independent code. This fixes one source of build + failures on target platforms that do not allow text relocations. + +commit 28fb197079cf1d11da4eef7c8c243ab05590c528 +Merge: c697472 c3dd0a1 +Author: Anthony Green +Date: Tue Mar 18 12:19:36 2014 -0400 + + Merge pull request #107 from rvandermeulen/msvcc + + Various compatibility fixes and improvements to msvcc.sh. + +commit c3dd0a1a0245fc174361a70876e88ae24285f861 +Author: Ryan VanderMeulen +Date: Tue Mar 18 12:09:45 2014 -0400 + + Various compatibility fixes and improvements to msvcc.sh. + + * Don't try to mix incompatible optimization flags in debug builds. + * Workaround ax_cc_maxopt.m4 not supporting MSVC and change -O3 to -O2. + * Fix MSVC warning by properly passing linker flags to compiler. + * Make msvcc.sh return 1 if invalid command line options are used rather than silently eating them. + * Add more comments. + +commit c697472fccfbb5b87b007c053cda9ef014b346b9 +Merge: 83fd2bc e48918e +Author: Anthony Green +Date: Mon Mar 17 00:32:42 2014 -0400 + + Merge pull request #102 from joshtriplett/test-generic + + Add ABIs to the test matrix; unify many bits of the testsuite + +commit e48918ecf876bc85d040fc50a232059c566553a8 +Author: Josh Triplett +Date: Sun Mar 16 20:29:27 2014 -0700 + + testsuite: Add ABIs to the test matrix; unify tests across ABIs + + This eliminates all the *_win32.c tests in favor of the tests they were + branched from, and expands test coverage to run many more tests on + stdcall, thiscall, and fastcall. + + This same mechanism also supports testing any other target that has + multiple ABIs. + +commit 4d4d368e5a55d9443c4c53b1b70d58ab6d8c941c +Author: Josh Triplett +Date: Sun Mar 16 17:02:05 2014 -0700 + + testsuite: Replace ffitestcxx.h with ffitest.h + + ffitest.h contains a superset of the functionality of ffitestcxx.h; + make the C++ tests include ffitest.h instead, and remove ffitestcxx.h. + +commit 3f97cf3413c46caf2a79f32ac9cda4620972c2d7 +Author: Josh Triplett +Date: Sun Mar 16 16:53:42 2014 -0700 + + testsuite: Unify the C and C++ testsuites + + These two testsuites differ only in the source file glob and a couple of + additional compiler options; unify the remaining bits. + +commit 0d9cce8edb937bbe771a6cdd25f671edf06d2128 +Author: Josh Triplett +Date: Sun Mar 16 16:22:58 2014 -0700 + + testsuite: ffitest.h: Parenthesize the CHECK macro + +commit 5695ec1444c5323e48fe4314f8c8f027625e67df +Author: Josh Triplett +Date: Sun Mar 16 16:04:58 2014 -0700 + + testsuite: Factor out a function to run a matrix of tests + + This commons up code from libffi.call/call.exp and + libffi.special/special.exp, unifies the optimization option matrix + between the two, and makes it easier to add more axes to the matrix + in the future. + +commit dfdb02cc869855d3b68571e5f7aa77ae8c9d254a +Author: Josh Triplett +Date: Sun Mar 16 15:26:26 2014 -0700 + + testsuite: Introduce a __THISCALL__ compiler-specific macro + +commit 83fd2bce0456224483435d4b764063f4513fd464 +Merge: 3658a07 06ff924 +Author: Anthony Green +Date: Sun Mar 16 22:03:29 2014 -0400 + + Merge pull request #99 from joshtriplett/gitignore + + .gitignore: Ignore more generated files + +commit 3658a0700a50d37a2fdba04fd9d79ad2f706d9f5 +Merge: d948d0a 46c5d3c +Author: Anthony Green +Date: Sun Mar 16 21:37:42 2014 -0400 + + Merge pull request #100 from rvandermeulen/bug-756740 + + Change double quotes in Makefile.am to single quotes. + +commit 46c5d3c30fdc2b43c076ad955078d7c5f1e75b37 +Author: Ryan VanderMeulen +Date: Sun Mar 16 21:16:08 2014 -0400 + + Change double quotes in Makefile.am to single quotes. + + This was originally done in PR #84, except the change was made to Makefile.in instead of Makefile.am and was therefore reverted the next time the files were regenerated. + +commit 06ff924215a2f9739efa2c059dc595bc4ec1c851 +Author: Josh Triplett +Date: Sun Mar 16 16:19:46 2014 -0700 + + .gitignore: Ignore more generated files + + The build process generates doc/libffi.info and fficonfig.h.in, so add + them to .gitignore. + +commit bad8948346e9b8813023a0cc78a3b6eb8d9c14c6 +Author: Josh Triplett +Date: Sun Mar 16 15:16:18 2014 -0700 - * Makefile.am (EXTRA_DIST): Add libtool-ldflags. - * Makefile.in: Rebuilt. - * libtool-ldflags: New file. + testsuite: Introduce a __STDCALL__ compiler-specific macro + + Several tests want to use stdcall, which differs in syntax by compiler, + so introduce a macro for it in ffitest.h. -2013-02-07 Daniel Schepler +commit 98a793fa36a4ab3ba24d059cb80a2891cdb940e1 +Author: Josh Triplett +Date: Sun Mar 16 15:20:36 2014 -0700 - * configure.ac: Correctly identify x32 systems as 64-bit. - * m4/libtool.m4: Remove libtool expr error. - * aclocal.m4, configure: Rebuilt. + testsuite: Common up the ifdef blocks for compiler-specific macros -2013-02-07 Anthony Green +commit d948d0a729c934b0224749338a3ba0a2c8f51c45 +Merge: b61b472 a86bd31 +Author: Anthony Green +Date: Sun Mar 16 10:53:48 2014 -0400 - * configure.ac: Fix GCC usage test. - * configure: Rebuilt. - * README: Mention LLVM/GCC x86_64 issue. - * testsuite/Makefile.in: Rebuilt. + Merge pull request #98 from joshtriplett/unconfigure.host + + Merge configure.host into configure.ac -2013-02-07 Anthony Green +commit a86bd318e2424d879d784ee7b29d6536d7a17c18 +Author: Josh Triplett +Date: Sun Mar 16 06:58:59 2014 -0700 - * testsuite/libffi.call/cls_double_va.c (main): Replace // style - comments with /* */ for xlc compiler. - * testsuite/libffi.call/stret_large.c (main): Ditto. - * testsuite/libffi.call/stret_large2.c (main): Ditto. - * testsuite/libffi.call/nested_struct1.c (main): Ditto. - * testsuite/libffi.call/huge_struct.c (main): Ditto. - * testsuite/libffi.call/float_va.c (main): Ditto. - * testsuite/libffi.call/cls_struct_va1.c (main): Ditto. - * testsuite/libffi.call/cls_pointer_stack.c (main): Ditto. - * testsuite/libffi.call/cls_pointer.c (main): Ditto. - * testsuite/libffi.call/cls_longdouble_va.c (main): Ditto. + Merge configure.host into configure.ac + + configure.host only has a single entry, and shows no signs of needing + more added. -2013-02-06 Anthony Green +commit b61b472bd0647006d6685238721002017f1d119c +Author: Anthony Green +Date: Sun Mar 16 09:45:55 2014 -0400 - * man/ffi_prep_cif.3: Clean up for debian lintian checker. + Update version to 3.1-rc0. Clean up README. -2013-02-06 Anthony Green +commit 7a64e7dbba54e6e9f69954adfb943be1856ff928 +Merge: 11a5c5c eef2e02 +Author: Anthony Green +Date: Sun Mar 16 09:39:08 2014 -0400 - * Makefile.am (pkgconfigdir): Add missing pkgconfig install bits. - * Makefile.in: Rebuild. + Merge pull request #97 from joshtriplett/remove-more-generated-files + + Remove more generated files -2013-02-02 Mark H Weaver +commit 11a5c5c39f5861011f6c5ddf795da3a32b5f0082 +Merge: 9a62a21 1c68c07 +Author: Anthony Green +Date: Sun Mar 16 09:38:47 2014 -0400 + + Merge pull request #96 from joshtriplett/sawing-changelogs + + Generate ChangeLog from git in make dist; remove it from version control - * src/x86/ffi64.c (ffi_call): Sign-extend integer arguments passed - via general purpose registers. +commit eef2e02a13d7d1c8145d47a64467f654406a3548 +Author: Josh Triplett +Date: Sun Mar 16 06:26:03 2014 -0700 -2013-01-21 Nathan Rossi + doc: Remove autogenerated info file and stamp - * README: Add MicroBlaze details. - * Makefile.am: Add MicroBlaze support. - * configure.ac: Likewise. - * src/microblaze/ffi.c: New. - * src/microblaze/ffitarget.h: Likewise. - * src/microblaze/sysv.S: Likewise. +commit 9fb403d3c5d9643e0f561cab6d4a07b1e54907ff +Author: Josh Triplett +Date: Sun Mar 16 06:25:52 2014 -0700 + + fficonfig.h.in: Remove, configure generates it + +commit 1c68c07217fda78a779778c1480fedef7a58d5b4 +Author: Josh Triplett +Date: Sun Mar 16 06:11:58 2014 -0700 + + Generate ChangeLog from git in make dist + + Archive the existing ChangeLog to ChangeLog.libffi-3.1 -2013-01-21 Nathan Rossi - * testsuite/libffi.call/return_uc.c: Fixed issue. +commit c65ed55e655711e008282edbdd82ce95d008b4f6 +Author: Josh Triplett +Date: Sun Mar 16 05:52:00 2014 -0700 + + ChangeLog.v1: Fix typo in explanatory header. -2013-01-21 Chris Zankel +commit 9a62a21f5c3a8e1da463229f3170c8ab3031d920 +Author: Anthony Green +Date: Sun Mar 16 09:03:57 2014 -0400 - * README: Add Xtensa support. - * Makefile.am: Likewise. - * configure.ac: Likewise. - * Makefile.in Regenerate. - * configure: Likewise. - * src/prep_cif.c: Handle Xtensa. - * src/xtensa: New directory. - * src/xtensa/ffi.c: New file. - * src/xtensa/ffitarget.h: Ditto. - * src/xtensa/sysv.S: Ditto. + Add missing ChangeLog entry. Clean up some entries. + +commit 9bc704c58cb7a049d867837e3a11e2e31886ec66 +Merge: 694447a e892e58 +Author: Anthony Green +Date: Sun Mar 16 08:41:00 2014 -0400 -2013-01-11 Anthony Green + Merge pull request #95 from joshtriplett/news + + README: Update news for 3.0.14 - * src/powerpc/ffi_darwin.c (ffi_prep_args): Replace // style - comments with /* */ for xlc compiler. - * src/powerpc/aix.S (ffi_call_AIX): Ditto. - * testsuite/libffi.call/ffitest.h (allocate_mmap): Delete - deprecated inline function. - * testsuite/libffi.special/ffitestcxx.h: Ditto. - * README: Add update for AIX support. +commit e892e581d1838a06c18c7ecd50ebd79915cff92b +Author: Josh Triplett +Date: Sun Mar 16 05:38:24 2014 -0700 -2013-01-11 Anthony Green + README: Update news for 3.0.14 - * configure.ac: Robustify pc relative reloc check. - * m4/ax_cc_maxopt.m4: Don't -malign-double. This is an ABI - changing option for 32-bit x86. - * aclocal.m4, configure: Rebuilt. - * README: Update supported target list. +commit 694447aa29deadd571efb4e9a26ee3f68ede1493 +Merge: fdc87f3 45a6c21 +Author: Anthony Green +Date: Sun Mar 16 08:32:05 2014 -0400 -2013-01-10 Anthony Green + Merge pull request #93 from joshtriplett/travis-dist + + Make Travis check "make dist" + +commit 45a6c21efa944b520842e631dc54919b04884744 +Author: Josh Triplett +Date: Sun Mar 16 05:29:08 2014 -0700 + + .travis.yml: Test "make dist" too. + +commit fdc87f3b2ea37b58a4a9ae6c35083f544909fe3c +Merge: 7412b83 e1911f7 +Author: Anthony Green +Date: Sun Mar 16 08:05:51 2014 -0400 + + Merge pull request #85 from joshtriplett/stdcall + + stdcall support on Linux + +commit e1911f78df113ca58738b66089a070d4cf747de7 +Author: Josh Triplett +Date: Sun Mar 16 03:25:53 2014 -0700 + + Add support for stdcall, thiscall, and fastcall on non-Windows x86-32 + + Linux supports the stdcall calling convention, either via functions + explicitly declared with the stdcall attribute, or via code compiled + with -mrtd which effectively makes stdcall the default. + + This introduces FFI_STDCALL, FFI_THISCALL, and FFI_FASTCALL on + non-Windows x86-32 platforms, as non-default calling conventions. + +commit 7412b838d543aae4fa925862bd5702d3dacbc29a +Merge: c0cc5fd 9531d05 +Author: Anthony Green +Date: Sun Mar 16 07:58:16 2014 -0400 + + Merge pull request #90 from joshtriplett/win32-unifdef + + prep_cif.c: Remove unnecessary ifdef for X86_WIN32 + +commit c0cc5fdaa237b67e86f22d2f6e13f3b42d9aae33 +Merge: 98b5296 b3a5da0 +Author: Anthony Green +Date: Sun Mar 16 07:57:59 2014 -0400 + + Merge pull request #89 from joshtriplett/travis32 + + .travis.yml: Test on both 32-bit and 64-bit + +commit 9531d05f64c2a674e0197158ffad68d69f177bd0 +Author: Josh Triplett +Date: Sun Mar 16 01:50:02 2014 -0700 + + prep_cif.c: Remove unnecessary ifdef for X86_WIN32 + + ffi_prep_cif_core had a special case for X86_WIN32, checking for + FFI_THISCALL in addition to the FFI_FIRST_ABI-to-FFI_LAST_ABI range + before returning FFI_BAD_ABI. However, on X86_WIN32, FFI_THISCALL + already falls in that range, making the special case unnecessary. + Remove it. + +commit b3a5da068abd2f2983d9e67adbf41b0e0f34e37f +Author: Josh Triplett +Date: Sat Mar 15 23:27:56 2014 -0700 + + .travis.yml: Test on both 32-bit and 64-bit + +commit 98b52960485a261399f081915f36063de3854a5f +Merge: 134ce4c f6dd184 +Author: Anthony Green +Date: Sun Mar 16 07:51:33 2014 -0400 + + Merge pull request #94 from joshtriplett/esp-extra-stackery-perception + + ChangeLog: Document testsuite changes to remove fragile stack pointer checks + +commit f6dd1845434dd53e22129becdfa092c082df307c +Author: Josh Triplett +Date: Sun Mar 16 04:49:36 2014 -0700 + + ChangeLog: Document testsuite changes to remove fragile stack pointer checks + +commit 134ce4c0266bf994f07518fc534de53f1d3c8de8 +Merge: 2680e9e 9c27932 +Author: Anthony Green +Date: Sun Mar 16 07:47:17 2014 -0400 + + Merge pull request #91 from joshtriplett/esp-extra-stackery-perception + + testsuite: Remove fragile stack pointer checks + +commit 9c279328ee12fc869adff63ca81f1230977bd42b +Author: Josh Triplett +Date: Sun Mar 16 02:31:19 2014 -0700 + + testsuite: Remove fragile stack pointer checks + + testsuite/libffi.call/closure_stdcall.c and + testsuite/libffi.call/closure_thiscall.c include inline assembly to save + the stack pointer before and after the call, and compare the values. + However, compilers can and do leave the stack in different states for + these two pieces of inline assembly, such as by saving a temporary value + on the stack across the call; observed with gcc -Os, and verified as + spurious through careful inspection of disassembly. + +commit 2680e9ea9b4c87ea8042a61e551bd667493d4bd3 +Merge: 071eab3 82f8cb2 +Author: Anthony Green +Date: Sun Mar 16 07:44:08 2014 -0400 + + Merge pull request #88 from joshtriplett/such-precision-many-fail-wow + + testsuite/libffi.call/many.c: Avoid spurious failure due to excess precision + +commit 82f8cb24a1d976db35ae31a4b86cec8926da327d +Author: Josh Triplett +Date: Sun Mar 16 04:27:32 2014 -0700 + + ChangeLog: Document many.c and many_win32.c changes to avoid spurious failures + +commit 88d562a8b5912e99306063fe3bc289bab6ca6ebe +Author: Josh Triplett +Date: Sat Mar 15 22:08:19 2014 -0700 + + testsuite/libffi.call/many_win32.c: Avoid spurious failure due to excess precision + + The test case testsuite/libffi.call/many_win32.c can spuriously fail due + to excess floating-point precision. Instrumenting it with some printf + calls shows differences well above FLT_EPSILON. (Note when + instrumenting it that multiple computations of the difference, such as + one in a print and another in the conditional, may produce different + results.) + + Rather than complicating the test suite with architecture-specific flags + to avoid excess precision, just simplify the floating-point computation + to avoid a dependency on potential excess precision. + +commit c00a49ecd165b2d06c1c9b249d212dc843fa116f +Author: Josh Triplett +Date: Sat Mar 15 22:08:19 2014 -0700 + + testsuite/libffi.call/many.c: Avoid spurious failure due to excess precision + + The test case testsuite/libffi.call/many.c can spuriously fail due to + excess floating-point precision. Instrumenting it with some printf + calls shows differences well above FLT_EPSILON. (Note when + instrumenting it that multiple computations of the difference, such as + one in a print and another in the conditional, may produce different + results.) + + Rather than complicating the test suite with architecture-specific flags + to avoid excess precision, just simplify the floating-point computation + to avoid a dependency on potential excess precision. + +commit 071eab32a7f9fbbef46c0d8f37d9985bc9cceb37 +Merge: 2228c7a 2f44952 +Author: Anthony Green +Date: Sun Mar 16 07:36:52 2014 -0400 + + Merge pull request #92 from joshtriplett/autogen + + Re-add libtool-ldflags + +commit 2f44952c95765c1486fad66f57235f8d459a9748 +Author: Josh Triplett +Date: Sun Mar 16 04:35:12 2014 -0700 + + Re-add libtool-ldflags + +commit 2228c7ab190f3c529b9018495467b841fa21cba2 +Merge: 76d19d0 35634db +Author: Anthony Green +Date: Sun Mar 16 07:25:18 2014 -0400 + + Merge pull request #87 from joshtriplett/autogen + + Remove autogenerated files from the repository + +commit 35634dbceaac0a1544f7385addc01d21ef1ef6a8 +Author: Josh Triplett +Date: Sat Mar 15 18:11:16 2014 -0700 + + Remove autogenerated files from the repository + + Add an autogen.sh to regenerate them. + +commit 76d19d004e36e99d261ee78261e2f52cea5e4ab1 +Merge: c86d9b6 a1a6f71 +Author: Anthony Green +Date: Fri Mar 14 16:54:31 2014 -0400 + + Ensure the linker supports @unwind sections in libffi. + +commit c86d9b6cc6e16ee262844a33b40441374400758c +Merge: 4efb7db f8cdf11 +Author: Anthony Green +Date: Fri Mar 14 16:51:20 2014 -0400 + + Fix merge + +commit 4efb7dbfd9427c478a948cd0d464210123db8de8 +Merge: 634a475 18eb81d +Author: Anthony Green +Date: Fri Mar 14 16:47:57 2014 -0400 + + Merge pull request #81 from rvandermeulen/bug-756740 + + Allow building for mipsel with Android NDK r8. + +commit a1a6f71bfe4199293043b2e4cfb4c8d3cb1112f9 +Author: Ryan VanderMeulen +Date: Mon Mar 10 15:12:47 2014 -0400 + + Remove stray hunk that shouldn't have been included in this patch. + +commit f8cdf11467181f2a9a6b7e748167569aa58e3a81 +Author: Ryan VanderMeulen +Date: Mon Mar 10 15:04:58 2014 -0400 + + Replace double quotes with single quotes in Makefile.in to improve compatibility between some versions of MSYS and gmake. From Mozilla bug 943728. + https://bugzilla.mozilla.org/show_bug.cgi?id=943728 + +commit dfa3738732e1bc3a7f4130395ae4bab55fcebb99 +Author: Ryan VanderMeulen +Date: Mon Mar 10 14:53:48 2014 -0400 + + Ensure the linker supports @unwind sections in libffi. From Mozilla bug 756740. + https://bugzilla.mozilla.org/show_bug.cgi?id=778414 + + Also tracked as issue #42. + https://github.com/atgreen/libffi/issues/42 + +commit 18eb81d032f29d645d0498ba92bddfd651f009ae +Author: Ryan VanderMeulen +Date: Mon Mar 10 14:43:37 2014 -0400 - * README (tested): Add Compiler column to table. + Allow building for mipsel with Android NDK r8. From Mozilla bug 756740. + https://bugzilla.mozilla.org/show_bug.cgi?id=756740 -2013-01-10 Anthony Green +commit 2349fec9a818fb52fd2f294bcbc7b3156cd113de +Author: Daiki Ueno +Date: Wed Mar 5 17:53:02 2014 +0900 - * src/x86/ffi64.c (struct register_args): Make sse array and array - of unions for sunpro compiler compatibility. + Fix typo in doc -2013-01-10 Anthony Green +commit 634a475eaf1bee31c09f7d519e31c13b64cd24df +Author: Anthony Green +Date: Sat Mar 1 18:37:29 2014 -0500 - * configure.ac: Test target platform size_t size. Handle both 32 - and 64-bit builds for x86_64-* and i?86-* targets (allowing for - CFLAG option to change default settings). - * configure, aclocal.m4: Rebuilt. + Update Makefile for new darwin scripts -2013-01-10 Anthony Green +commit c7b67e874bb89859f9a07d1cf9606052b6c0dcc1 +Author: Anthony Green +Date: Sat Mar 1 18:34:18 2014 -0500 - * testsuite/libffi.special/special.exp: Only run exception - handling tests when using GNU compiler. + Add README note - * m4/ax_compiler_vendor.m4: New file. - * configure.ac: Test for compiler vendor and don't use - AX_CFLAGS_WARN_ALL with the sun compiler. - * aclocal.m4, configure: Rebuilt. +commit a04e30ba3dc303133d459c1ac273ceefe4d49b32 +Author: Anthony Green +Date: Fri Feb 28 17:20:59 2014 -0500 -2013-01-10 Anthony Green + Add missing -DFFI_DEBUG flag - * include/ffi_common.h: Don't use GCCisms to define types when - building with the SUNPRO compiler. +commit 934dc1b5c8d6a9e727bedc72342831eb7d62c35f +Merge: 11d7aa9 67fbef3 +Author: Anthony Green +Date: Fri Feb 28 01:10:17 2014 -0500 -2013-01-10 Anthony Green + Merge branch 'master' of github.com:/atgreen/libffi - * configure.ac: Put local.exp in the right place. - * configure: Rebuilt. +commit 11d7aa9d7a4bbe642944edc0f07cf96db9b270b6 +Merge: b40aeda 3b44d41 +Author: Anthony Green +Date: Fri Feb 28 01:06:48 2014 -0500 - * src/x86/ffi.c: Update comment about regparm function attributes. - * src/x86/sysv.S (ffi_closure_SYSV): The SUNPRO compiler requires - that all function arguments be passed on the stack (no regparm - support). + Merge pull request #46 from makotokato/android-clang + + Fix build failure when using clang for Android -2013-01-08 Anthony Green +commit 67fbef3b56ff0ef88f9b1a7fe48cb77222fa6cec +Merge: b40aeda 3b44d41 +Author: Anthony Green +Date: Fri Feb 28 01:06:48 2014 -0500 - * configure.ac: Generate local.exp. This sets CC_FOR_TARGET - when we are using the vendor compiler. - * testsuite/Makefile.am (EXTRA_DEJAGNU_SITE_CONFIG): Point to - ../local.exp. - * configure, testsuite/Makefile.in: Rebuilt. + Merge pull request #46 from makotokato/android-clang + + Fix build failure when using clang for Android - * testsuite/libffi.call/call.exp: Run tests with different - options, depending on whether or not we are using gcc or the - vendor compiler. - * testsuite/lib/libffi.exp (libffi-init): Set using_gcc based on - whether or not we are building/testing with gcc. +commit b40aeda31a74d95a37c723b6243aabac466e67c4 +Merge: 20698ab 53ceaf1 +Author: Anthony Green +Date: Fri Feb 28 01:01:29 2014 -0500 -2013-01-08 Anthony Green + Merge branch 'master' of github.com:/atgreen/libffi - * configure.ac: Switch x86 solaris target to X86 by default. - * configure: Rebuilt. +commit 53ceaf14c5eeb16ba09745f0ca87cca367d41a90 +Merge: 860fe66 cc9b518 +Author: Anthony Green +Date: Fri Feb 28 01:01:02 2014 -0500 -2013-01-08 Anthony Green + Merge pull request #40 from wojdyr/master + + Correct the -L flag in libffi.pc.in - * configure.ac: Fix test for read-only eh_frame. - * configure: Rebuilt. +commit 20698abc6a00092fd7fd3e434a3a29dc0f048f1e +Merge: 64bd069 1a0b01e +Author: Anthony Green +Date: Fri Feb 28 00:56:27 2014 -0500 -2013-01-08 Anthony Green + Merge pull request #66 from ppizarro/master + + BlackFin fixes - Fatal error when calling a function defined in a shared library from within the function called by FFI - * src/x86/sysv.S, src/x86/unix64.S: Only emit DWARF unwind info - when building with the GNU toolchain. - * testsuite/libffi.call/ffitest.h (CHECK): Fix for Solaris vendor - compiler. +commit 860fe6646f5ae603e99a8d1d722ddddba8b75769 +Merge: 64bd069 1a0b01e +Author: Anthony Green +Date: Fri Feb 28 00:56:27 2014 -0500 -2013-01-07 Thorsten Glaser + Merge pull request #66 from ppizarro/master + + BlackFin fixes - Fatal error when calling a function defined in a shared library from within the function called by FFI - * testsuite/libffi.call/cls_uchar_va.c, - testsuite/libffi.call/cls_ushort_va.c, - testsuite/libffi.call/va_1.c: Testsuite fixes. +commit 64bd06990a7accf72271516a2110b86cdccd8df4 +Author: Anthony Green +Date: Fri Feb 28 00:52:56 2014 -0500 -2013-01-07 Thorsten Glaser + Add ChangeLog entry for Josh's change - * src/m68k/ffi.c (CIF_FLAGS_SINT8, CIF_FLAGS_SINT16): Define. - (ffi_prep_cif_machdep): Fix 8-bit and 16-bit signed calls. - * src/m68k/sysv.S (ffi_call_SYSV, ffi_closure_SYSV): Ditto. +commit edf29c5169b06fcfc241445e152e325bc3c50e0e +Merge: 33c9954 3998d26 +Author: Anthony Green +Date: Fri Feb 28 00:50:25 2014 -0500 -2013-01-04 Anthony Green + Merge pull request #75 from joshtriplett/longdouble + + Fix build error on x86 without distinct long double - * Makefile.am (AM_CFLAGS): Don't automatically add -fexceptions - and -Wall. This is set in the configure script after testing for - GCC. - * Makefile.in: Rebuilt. +commit 33c9954f2eec539011a0f93270aaf013318837ae +Author: Anthony Green +Date: Fri Feb 28 00:38:41 2014 -0500 -2013-01-02 rofl0r + Rebuilt with new libtool - * src/powerpc/ffi.c (ffi_prep_cif_machdep): Fix build error on ppc - when long double == double. +commit 926b6989fbd08488b9105943293353d45ac527e0 +Merge: 5a88c85 cc82051 +Author: Anthony Green +Date: Fri Feb 28 00:26:57 2014 -0500 -2013-01-02 Reini Urban + Merge branch 'master' of github.com:/atgreen/libffi + + Conflicts: + ChangeLog - * Makefile.am (libffi_la_LDFLAGS): Add -no-undefined to LDFLAGS - (required for shared libs on cygwin/mingw). - * Makefile.in: Rebuilt. +commit 5a88c85fde304052bed1581ed0b6452ac2c68838 +Author: Anthony Green +Date: Fri Feb 28 00:23:04 2014 -0500 -2012-10-31 Alan Modra + Fix spelling errors - * src/powerpc/linux64_closure.S: Add new ABI support. - * src/powerpc/linux64.S: Likewise. +commit cc82051c7e80cea772c4b72da026eb7e68d598fc +Author: Anthony Green +Date: Fri Feb 28 00:23:04 2014 -0500 -2012-10-30 Magnus Granberg - Pavel Labushev + Fix spelling errors - * configure.ac: New options pax_emutramp - * configure, fficonfig.h.in: Regenerated - * src/closures.c: New function emutramp_enabled_check() and - checks. +commit 001aaf4b1b56349596bb6f6b5c1613dcbbd84ea8 +Author: Anthony Green +Date: Fri Feb 28 00:20:17 2014 -0500 -2012-10-30 Frederick Cheung + When no VFP arguments are present the IP register is used + uninitialized. Initialize it to the value of FP. + + This fixes a number of testsuite failures when configured for + armv7l-unknown-linux-gnueabihf - * configure.ac: Enable FFI_MAP_EXEC_WRIT for Darwin 12 (mountain - lion) and future version. - * configure: Rebuild. +commit 49f7729c3ce697c12408c42ccb29cdf4eb66bb85 +Author: Anthony Green +Date: Fri Feb 28 00:17:16 2014 -0500 -2012-10-30 James Greenhalgh - Marcus Shawcroft + aarch64 fix - * README: Add details of aarch64 port. - * src/aarch64/ffi.c: New. - * src/aarch64/ffitarget.h: Likewise. - * src/aarch64/sysv.S: Likewise. - * Makefile.am: Support aarch64. - * configure.ac: Support aarch64. - * Makefile.in, configure: Rebuilt. +commit 447483d51c6aa9df7116f346a73fc1cf795f4c2b +Merge: 51377bd b4df9cf +Author: Anthony Green +Date: Thu Feb 27 15:42:41 2014 -0500 -2012-10-30 James Greenhalgh - Marcus Shawcroft + Fix ChangeLog merge - * testsuite/lib/libffi.exp: Add support for aarch64. - * testsuite/libffi.call/cls_struct_va1.c: New. - * testsuite/libffi.call/cls_uchar_va.c: Likewise. - * testsuite/libffi.call/cls_uint_va.c: Likewise. - * testsuite/libffi.call/cls_ulong_va.c: Likewise. - * testsuite/libffi.call/cls_ushort_va.c: Likewise. - * testsuite/libffi.call/nested_struct11.c: Likewise. - * testsuite/libffi.call/uninitialized.c: Likewise. - * testsuite/libffi.call/va_1.c: Likewise. - * testsuite/libffi.call/va_struct1.c: Likewise. - * testsuite/libffi.call/va_struct2.c: Likewise. - * testsuite/libffi.call/va_struct3.c: Likewise. +commit 3998d2604b5c0d45a098ff3119a9fd9710ef429d +Author: Josh Triplett +Date: Mon Feb 17 11:20:33 2014 -0800 -2012-10-12 Walter Lee + Fix build error on x86 without distinct long double + + src/x86/ffi64.c: In function 'classify_argument': + src/x86/ffi64.c:205:5: error: duplicate case value + case FFI_TYPE_LONGDOUBLE: + ^ + src/x86/ffi64.c:202:5: error: previously used here + case FFI_TYPE_DOUBLE: + ^ - * Makefile.am: Add TILE-Gx/TILEPro support. - * configure.ac: Likewise. - * Makefile.in: Regenerate. - * configure: Likewise. - * src/prep_cif.c (ffi_prep_cif_core): Handle TILE-Gx/TILEPro. - * src/tile: New directory. - * src/tile/ffi.c: New file. - * src/tile/ffitarget.h: Ditto. - * src/tile/tile.S: Ditto. +commit 51377bda9aed0b2c1309c818460cab9d9ab3d46e +Merge: f08da54 40927bd +Author: Anthony Green +Date: Sat Feb 15 08:06:29 2014 -0500 -2012-10-12 Matthias Klose + Merge pull request #72 from heiher/devel + + MIPS N32: Fix call floating point va function - * generate-osx-source-and-headers.py: Normalize whitespace. +commit f08da5465463e60a28f5e921f23ebf2ba984c148 +Merge: 3dc3f32 fa5f25c +Author: Anthony Green +Date: Sat Feb 15 08:06:11 2014 -0500 -2012-09-14 David Edelsohn + Merge pull request #68 from zeldin/master + + Linux/ppc64: Remove assumption on contents of r11 in closure - * configure: Regenerated. +commit 40927bd3e1e7c6007025ba10854fd8a0664e47df +Author: Heiher +Date: Tue Jan 21 23:18:27 2014 +0800 -2012-08-26 Andrew Pinski + Fix call floating point va function + + I'm not sure floating-point arguments in GPR or FPR before calling + variable number arguments function. so, load all arguments to GPR and + FPR. - PR libffi/53014 - * src/mips/ffi.c (ffi_prep_closure_loc): Allow n32 with soft-float and n64 with - soft-float. +commit b4df9cf9cc4a9a9401a53fd6bea1f3c2c283b97b +Author: Zachary Waldowski +Date: Wed Feb 5 14:22:52 2014 -0500 -2012-08-08 Uros Bizjak + AArch64: Fix void fall-through case when assertions are enabled - * src/s390/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, - just return FFI_BAD_ABI when things are wrong. +commit f466aad0d91a117e42571d1d6fb434fa0433c930 +Author: Zachary Waldowski +Date: Tue Jan 21 16:38:31 2014 -0500 -2012-07-18 H.J. Lu + AArch64: Fix missing semicolons when assertions are enabled - PR libffi/53982 - PR libffi/53973 - * src/x86/ffitarget.h: Check __ILP32__ instead of __LP64__ for x32. - (FFI_SIZEOF_JAVA_RAW): Defined to 4 for x32. +commit 7ea677733bd98917241852b8901a6b7580728895 +Author: Anthony Green +Date: Sat Nov 30 20:58:31 2013 -0500 -2012-05-16 H.J. Lu + Remove build-ios from Makefile + + Conflicts: + ChangeLog - * configure: Regenerated. +commit 6ae046cc59c12b2cd40158d6bcb96f4a59886159 +Author: Anthony Green +Date: Sat Nov 30 21:06:51 2013 -0500 -2012-05-05 Nicolas Lelong + Mention Aarch64 on iOS - * libffi.xcodeproj/project.pbxproj: Fixes. - * README: Update for iOS builds. +commit bfc06b3fdb32abe90ce0749aedfec649df85a7ef +Author: Zachary Waldowski +Date: Mon Dec 30 17:36:39 2013 -0500 -2012-04-23 Alexandre Keunecke I. de Mendonca + Update ChangeLog - * configure.ac: Add Blackfin/sysv support - * Makefile.am: Add Blackfin/sysv support - * src/bfin/ffi.c: Add Blackfin/sysv support - * src/bfin/ffitarget.h: Add Blackfin/sysv support +commit 0a0f12ce1f7be81006b08a3c81a636926d283a9b +Author: Zachary Waldowski +Date: Thu Jan 9 13:50:17 2014 -0500 -2012-04-11 Anthony Green + AArch64: Remove duplicitous element_count call. + + This inhibits an analyzer warning by Clang. - * Makefile.am (EXTRA_DIST): Add new script. - * Makefile.in: Rebuilt. +commit 4330fdcd92e67c816288d64ab230237065768206 +Author: Zachary Waldowski +Date: Thu Jan 9 13:53:30 2014 -0500 -2012-04-11 Zachary Waldowski + Darwin/aarch64: Respect iOS ABI re: stack argument alignment - * generate-ios-source-and-headers.py, - libffi.xcodeproj/project.pbxproj: Support a Mac static library via - Xcode. Set iOS compatibility to 4.0. Move iOS trampoline - generation into an Xcode "run script" phase. Include both as - Xcode build scripts. Don't always regenerate config files. +commit 0a333d6c3973935d4fe02aae76b10e39d3c88e07 +Author: Zachary Waldowski +Date: Thu Jan 9 14:03:29 2014 -0500 -2012-04-10 Anthony Green + Darwin/aarch64: Fix size_t assumptions - * src/powerpc/ffi_darwin.c (ffi_prep_args): Add missing semicolon. +commit 2c18e3c76aad1b426617db05a4384e7c3a920176 +Author: Zachary Waldowski +Date: Mon Dec 30 16:14:02 2013 -0500 -2012-04-06 Anthony Green + Darwin/aarch64: Fix "shadows declaration" warnings - * Makefile.am (EXTRA_DIST): Add new iOS/xcode files. - * Makefile.in: Rebuilt. +commit 1b8a8e20e344f3c55495ab6eb46bd14e843d4b3e +Author: Zachary Waldowski +Date: Thu Jan 9 13:55:21 2014 -0500 -2012-04-06 Mike Lewis + Darwin/aarch64: Use Clang cache invalidation builtin - * generate-ios-source-and-headers.py: New file. - * libffi.xcodeproj/project.pbxproj: New file. - * README: Update instructions on building iOS binary. - * build-ios.sh: Delete. +commit 6030cdcae776f8fb5876a53168f7d1e75d28a242 +Author: Zachary Waldowski +Date: Mon Dec 30 15:45:51 2013 -0500 -2012-04-06 Anthony Green + Darwin/aarch64: Account for long double being equal to double - * src/x86/ffi64.c (UINT128): Define differently for Intel and GNU - compilers, then use it. +commit 5658b0892683d2e24e4d5842978c184a7ad33858 +Author: Zachary Waldowski +Date: Mon Dec 30 16:33:47 2013 -0500 -2012-04-06 H.J. Lu + Darwin/aarch64: Use CNAME, restrict .size like ARM - * m4/libtool.m4 (_LT_ENABLE_LOCK): Support x32. +commit 07175780802acec5dc49fdedd6d20a62409a6707 +Author: Zachary Waldowski +Date: Mon Dec 30 17:48:22 2013 -0500 -2012-04-06 Anthony Green + Darwin/aarch64: Fix invalid reference in assembly - * testsuite/Makefile.am (EXTRA_DIST): Add missing test cases. - * testsuite/Makefile.in: Rebuilt. +commit 9da28b44277fea3aeb827c35dd63d609d2524a8b +Author: Zachary Waldowski +Date: Mon Dec 30 16:23:21 2013 -0500 -2012-04-05 Zachary Waldowski + Darwin/x86_64: Fix 64-bit type shortening warnings - * include/ffi.h.in: Add missing trampoline table fields. - * src/arm/sysv.S: Fix ENTRY definition, and wrap symbol references - in CNAME. - * src/x86/ffi.c: Wrap Windows specific code in ifdefs. +commit 821d398f08bd1d540a5b235507812ffeee49b580 +Author: Zachary Waldowski +Date: Thu Jan 9 13:15:06 2014 -0500 -2012-04-02 Peter Bergner + Darwin: Merge build scripts, redo project, incl. arm64 - * src/powerpc/ffi.c (ffi_prep_args_SYSV): Declare double_tmp. - Silence casting pointer to integer of different size warning. - Delete goto to previously deleted label. - (ffi_call): Silence possibly undefined warning. - (ffi_closure_helper_SYSV): Declare variable type. +commit 6eff9ff9e72463b9783be2514f944b6f05692054 +Author: Zachary Waldowski +Date: Mon Dec 30 17:48:10 2013 -0500 -2012-04-02 Peter Rosin + Darwin/iOS: Improve unified syntax use for LLVM - * src/x86/win32.S (ffi_call_win32): Sign/zero extend the return - value in the Intel version as is already done for the AT&T version. - (ffi_closure_SYSV): Likewise. - (ffi_closure_raw_SYSV): Likewise. - (ffi_closure_STDCALL): Likewise. +commit ba0ea99c82aadd5957386a031e3122011bd36d52 +Author: Zachary Waldowski +Date: Mon Dec 30 15:27:44 2013 -0500 -2012-03-29 Peter Rosin + Fix dlmalloc warnings due to set_segment_flags, sizeof(size_t) - * src/x86/win32.S (ffi_closure_raw_THISCALL): Unify the frame - generation, fix the ENDP label and remove the surplus third arg - from the 'lea' insn. +commit 994be3a5c1d0d17b19103396103e128517fd62f9 +Author: Zachary Waldowski +Date: Mon Dec 30 15:27:14 2013 -0500 -2012-03-29 Peter Rosin - - * src/x86/win32.S (ffi_closure_raw_SYSV): Make the 'stubraw' label - visible outside the PROC, so that ffi_closure_raw_THISCALL can see - it. Also instruct the assembler to add a frame to the function. - -2012-03-23 Peter Rosin - - * Makefile.am (AM_CPPFLAGS): Add -DFFI_BUILDING. - * Makefile.in: Rebuilt. - * include/ffi.h.in [MSVC]: Add __declspec(dllimport) decorations - to all data exports, when compiling libffi clients using MSVC. - -2012-03-29 Peter Rosin - - * src/x86/ffitarget.h (ffi_abi): Add new ABI FFI_MS_CDECL and - make it the default for MSVC. - (FFI_TYPE_MS_STRUCT): New structure return convention. - * src/x86/ffi.c (ffi_prep_cif_machdep): Tweak the structure - return convention for FFI_MS_CDECL to be FFI_TYPE_MS_STRUCT - instead of an ordinary FFI_TYPE_STRUCT. - (ffi_prep_args): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT. - (ffi_call): Likewise. - (ffi_prep_incoming_args_SYSV): Likewise. - (ffi_raw_call): Likewise. - (ffi_prep_closure_loc): Treat FFI_MS_CDECL as FFI_SYSV. - * src/x86/win32.S (ffi_closure_SYSV): For FFI_TYPE_MS_STRUCT, - return a pointer to the result structure in eax and don't pop - that pointer from the stack, the caller takes care of it. - (ffi_call_win32): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT. - (ffi_closure_raw_SYSV): Likewise. - -2012-03-22 Peter Rosin - - * testsuite/libffi.call/closure_stdcall.c [MSVC]: Add inline - assembly version with Intel syntax. - * testsuite/libffi.call/closure_thiscall.c [MSVC]: Likewise. - -2012-03-23 Peter Rosin - - * testsuite/libffi.call/ffitest.h: Provide abstration of - __attribute__((fastcall)) in the form of a __FASTCALL__ - define. Define it to __fastcall for MSVC. - * testsuite/libffi.call/fastthis1_win32.c: Use the above. - * testsuite/libffi.call/fastthis2_win32.c: Likewise. - * testsuite/libffi.call/fastthis3_win32.c: Likewise. - * testsuite/libffi.call/strlen2_win32.c: Likewise. - * testsuite/libffi.call/struct1_win32.c: Likewise. - * testsuite/libffi.call/struct2_win32.c: Likewise. - -2012-03-22 Peter Rosin - - * src/x86/win32.S [MSVC] (ffi_closure_THISCALL): Remove the manual - frame on function entry, MASM adds one automatically. - -2012-03-22 Peter Rosin - - * testsuite/libffi.call/ffitest.h [MSVC]: Add kludge for missing - bits in the MSVC headers. - -2012-03-22 Peter Rosin - - * testsuite/libffi.call/cls_12byte.c: Adjust to the C89 style - with no declarations after statements. - * testsuite/libffi.call/cls_16byte.c: Likewise. - * testsuite/libffi.call/cls_18byte.c: Likewise. - * testsuite/libffi.call/cls_19byte.c: Likewise. - * testsuite/libffi.call/cls_1_1byte.c: Likewise. - * testsuite/libffi.call/cls_20byte.c: Likewise. - * testsuite/libffi.call/cls_20byte1.c: Likewise. - * testsuite/libffi.call/cls_24byte.c: Likewise. - * testsuite/libffi.call/cls_2byte.c: Likewise. - * testsuite/libffi.call/cls_3_1byte.c: Likewise. - * testsuite/libffi.call/cls_3byte1.c: Likewise. - * testsuite/libffi.call/cls_3byte2.c: Likewise. - * testsuite/libffi.call/cls_4_1byte.c: Likewise. - * testsuite/libffi.call/cls_4byte.c: Likewise. - * testsuite/libffi.call/cls_5_1_byte.c: Likewise. - * testsuite/libffi.call/cls_5byte.c: Likewise. - * testsuite/libffi.call/cls_64byte.c: Likewise. - * testsuite/libffi.call/cls_6_1_byte.c: Likewise. - * testsuite/libffi.call/cls_6byte.c: Likewise. - * testsuite/libffi.call/cls_7_1_byte.c: Likewise. - * testsuite/libffi.call/cls_7byte.c: Likewise. - * testsuite/libffi.call/cls_8byte.c: Likewise. - * testsuite/libffi.call/cls_9byte1.c: Likewise. - * testsuite/libffi.call/cls_9byte2.c: Likewise. - * testsuite/libffi.call/cls_align_double.c: Likewise. - * testsuite/libffi.call/cls_align_float.c: Likewise. - * testsuite/libffi.call/cls_align_longdouble.c: Likewise. - * testsuite/libffi.call/cls_align_longdouble_split.c: Likewise. - * testsuite/libffi.call/cls_align_longdouble_split2.c: Likewise. - * testsuite/libffi.call/cls_align_pointer.c: Likewise. - * testsuite/libffi.call/cls_align_sint16.c: Likewise. - * testsuite/libffi.call/cls_align_sint32.c: Likewise. - * testsuite/libffi.call/cls_align_sint64.c: Likewise. - * testsuite/libffi.call/cls_align_uint16.c: Likewise. - * testsuite/libffi.call/cls_align_uint32.c: Likewise. - * testsuite/libffi.call/cls_align_uint64.c: Likewise. - * testsuite/libffi.call/cls_dbls_struct.c: Likewise. - * testsuite/libffi.call/cls_pointer_stack.c: Likewise. - * testsuite/libffi.call/err_bad_typedef.c: Likewise. - * testsuite/libffi.call/huge_struct.c: Likewise. - * testsuite/libffi.call/nested_struct.c: Likewise. - * testsuite/libffi.call/nested_struct1.c: Likewise. - * testsuite/libffi.call/nested_struct10.c: Likewise. - * testsuite/libffi.call/nested_struct2.c: Likewise. - * testsuite/libffi.call/nested_struct3.c: Likewise. - * testsuite/libffi.call/nested_struct4.c: Likewise. - * testsuite/libffi.call/nested_struct5.c: Likewise. - * testsuite/libffi.call/nested_struct6.c: Likewise. - * testsuite/libffi.call/nested_struct7.c: Likewise. - * testsuite/libffi.call/nested_struct8.c: Likewise. - * testsuite/libffi.call/nested_struct9.c: Likewise. - * testsuite/libffi.call/stret_large.c: Likewise. - * testsuite/libffi.call/stret_large2.c: Likewise. - * testsuite/libffi.call/stret_medium.c: Likewise. - * testsuite/libffi.call/stret_medium2.c: Likewise. - * testsuite/libffi.call/struct1.c: Likewise. - * testsuite/libffi.call/struct1_win32.c: Likewise. - * testsuite/libffi.call/struct2.c: Likewise. - * testsuite/libffi.call/struct2_win32.c: Likewise. - * testsuite/libffi.call/struct3.c: Likewise. - * testsuite/libffi.call/struct4.c: Likewise. - * testsuite/libffi.call/struct5.c: Likewise. - * testsuite/libffi.call/struct6.c: Likewise. - * testsuite/libffi.call/struct7.c: Likewise. - * testsuite/libffi.call/struct8.c: Likewise. - * testsuite/libffi.call/struct9.c: Likewise. - * testsuite/libffi.call/testclosure.c: Likewise. - -2012-03-21 Peter Rosin - - * testsuite/libffi.call/float_va.c (float_va_fn): Use %f when - printing doubles (%lf is for long doubles). - (main): Likewise. - -2012-03-21 Peter Rosin - - * testsuite/lib/target-libpath.exp [*-*-cygwin*, *-*-mingw*] - (set_ld_library_path_env_vars): Add the library search dir to PATH - (and save PATH for later). - (restore_ld_library_path_env_vars): Restore PATH. - -2012-03-21 Peter Rosin - - * testsuite/lib/target-libpath.exp [*-*-cygwin*, *-*-mingw*] - (set_ld_library_path_env_vars): Add the library search dir to PATH - (and save PATH for later). - (restore_ld_library_path_env_vars): Restore PATH. - -2012-03-20 Peter Rosin - - * testsuite/libffi.call/strlen2_win32.c (main): Remove bug. - * src/x86/win32.S [MSVC] (ffi_closure_SYSV): Make the 'stub' label - visible outside the PROC, so that ffi_closure_THISCALL can see it. - -2012-03-20 Peter Rosin - - * testsuite/libffi.call/strlen2_win32.c (main): Remove bug. - * src/x86/win32.S [MSVC] (ffi_closure_SYSV): Make the 'stub' label - visible outside the PROC, so that ffi_closure_THISCALL can see it. - -2012-03-19 Alan Hourihane - - * src/m68k/ffi.c: Add MINT support. - * src/m68k/sysv.S: Ditto. - -2012-03-06 Chung-Lin Tang - - * src/arm/ffi.c (ffi_call): Add __ARM_EABI__ guard around call to - ffi_call_VFP(). - (ffi_prep_closure_loc): Add __ARM_EABI__ guard around use of - ffi_closure_VFP. - * src/arm/sysv.S: Add __ARM_EABI__ guard around VFP code. - -2012-03-19 chennam - - * src/powerpc/ffi_darwin.c (ffi_prep_closure_loc): Fix AIX closure - support. - -2012-03-13 Kaz Kojima - - * src/sh/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, - just return FFI_BAD_ABI when things are wrong. - * src/sh64/ffi.c (ffi_prep_closure_loc): Ditto. - -2012-03-09 David Edelsohn - - * src/powerpc/aix_closure.S (ffi_closure_ASM): Adjust for Darwin64 - change to return value of ffi_closure_helper_DARWIN and load type - from return type. - -2012-03-03 H.J. Lu - - * src/x86/ffi64.c (ffi_call): Cast the return value to unsigned - long. - (ffi_prep_closure_loc): Cast to 64bit address in trampoline. - (ffi_closure_unix64_inner): Cast return pointer to unsigned long - first. + Darwin/iOS: Fix mis-typing of vfp_reg_free - * src/x86/ffitarget.h (FFI_SIZEOF_ARG): Defined to 8 for x32. - (ffi_arg): Set to unsigned long long for x32. - (ffi_sarg): Set to long long for x32. +commit a8e0a835ab1f62d03ad6391760e3e8b7732d24f8 +Author: Zachary Waldowski +Date: Mon Dec 30 15:26:20 2013 -0500 -2012-03-03 H.J. Lu + Darwin/ARM: Assert on NULL dereference + + This inhibits an analyzer warning by Clang on all platforms. - * src/prep_cif.c (ffi_prep_cif_core): Properly check bad ABI. +commit 13675341581c489ed9df8ba390c8e08a732decb2 +Author: Zachary Waldowski +Date: Thu Jan 9 13:42:08 2014 -0500 -2012-03-03 Andoni Morales Alastruey + Darwin/i386: Inhibit Clang previous prototype warnings - * configure.ac: Add -no-undefined for both 32- and 64-bit x86 - windows-like hosts. - * configure: Rebuilt. +commit 66469c381e2e2cc96e7d409266dea0ffe177eeca +Author: Zachary Waldowski +Date: Thu Jan 9 13:41:45 2014 -0500 -2012-02-27 Mikael Pettersson + Darwin/ARM: Inhibit Clang previous prototype warnings - PR libffi/52223 - * Makefile.am (FLAGS_TO_PASS): Define. - * Makefile.in: Regenerate. +commit 5bfe62a00d2d659eec9f19b39802b6e69844fc27 +Author: Zachary Waldowski +Date: Thu Jan 9 13:41:27 2014 -0500 -2012-02-23 Anthony Green + Darwin/AArch64: Inhibit Clang previous prototype warnings - * src/*/ffitarget.h: Ensure that users never include ffitarget.h - directly. +commit fa5f25c20f76a6ef5e950a7ccbce826672c8a620 +Author: Marcus Comstedt +Date: Sat Jan 4 19:00:08 2014 +0100 -2012-02-23 Kai Tietz + Linux/ppc64: Remove assumption on contents of r11 in closure - PR libffi/52221 - * src/x86/ffi.c (ffi_closure_raw_THISCALL): New - prototype. - (ffi_prep_raw_closure_loc): Use ffi_closure_raw_THISCALL for - thiscall-convention. - (ffi_raw_call): Use ffi_prep_args_raw. - * src/x86/win32.S (ffi_closure_raw_THISCALL): Add - implementation for stub. +commit 1a0b01e171e9c750437cef2f18917f5a6e32c498 +Author: Paulo Pizarro +Date: Thu Jan 2 16:17:59 2014 -0200 -2012-02-10 Kai Tietz + When the function called by the ffi called a function defined in a shared library generate a fatal error + The correction was to take into consideration the GOT. - * configure.ac (AM_LTLDFLAGS): Add -no-undefine for x64 - windows target. - * configure: Regenerated. +commit 3dc3f32c35db5ab995a835225f6815369735ceb7 +Author: Anthony Green +Date: Thu Dec 5 16:23:25 2013 -0500 -2012-02-08 Kai Tietz + Undo iOS ARM64 changes. - * src/prep_cif.c (ffi_prep_cif): Allow for X86_WIN32 - also FFI_THISCALL. - * src/x86/ffi.c (ffi_closure_THISCALL): Add prototype. - (FFI_INIT_TRAMPOLINE_THISCALL): New trampoline code. - (ffi_prep_closure_loc): Add FFI_THISCALL support. - * src/x86/ffitarget.h (FFI_TRAMPOLINE_SIZE): Adjust size. - * src/x86/win32.S (ffi_closure_THISCALL): New closure code - for thiscall-calling convention. - * testsuite/libffi.call/closure_thiscall.c: New test. +commit 356b2cbc304bfe5bdc28b8d1c68d1ff084e9ec37 +Merge: 484a758 07345a3 +Author: Anthony Green +Date: Sat Nov 30 22:38:13 2013 -0500 -2012-01-28 Kai Tietz + Merge branch 'master' of github.com:/atgreen/libffi - * src/libffi/src/x86/ffi.c (ffi_call_win32): Add new - argument to prototype for specify calling-convention. - (ffi_call): Add support for stdcall/thiscall convention. - (ffi_prep_args): Likewise. - (ffi_raw_call): Likewise. - * src/x86/ffitarget.h (ffi_abi): Add FFI_THISCALL and - FFI_FASTCALL. - * src/x86/win32.S (_ffi_call_win32): Add support for - fastcall/thiscall calling-convention calls. - * testsuite/libffi.call/fastthis1_win32.c: New test. - * testsuite/libffi.call/fastthis2_win32.c: New test. - * testsuite/libffi.call/fastthis3_win32.c: New test. - * testsuite/libffi.call/strlen2_win32.c: New test. - * testsuite/libffi.call/many2_win32.c: New test. - * testsuite/libffi.call/struct1_win32.c: New test. - * testsuite/libffi.call/struct2_win32.c: New test. +commit 484a7584260e2fbb399ce90083046834271bf9ff +Author: Anthony Green +Date: Sat Nov 30 21:06:51 2013 -0500 -2012-01-23 Uros Bizjak + Mention Aarch64 on iOS - * src/alpha/ffi.c (ffi_prep_closure_loc): Check for bad ABI. +commit 07345a30ec0a2fa45a7c363d301f57723690cfa0 +Author: Anthony Green +Date: Sat Nov 30 21:06:51 2013 -0500 -2012-01-23 Anthony Green - Chris Young + Mention Aarch64 on iOS - * configure.ac: Add Amiga support. - * configure: Rebuilt. +commit d4b931c1b872378c35f12ddbb9a6d55e7f17c65e +Author: Anthony Green +Date: Sat Nov 30 20:58:31 2013 -0500 -2012-01-23 Dmitry Nadezhin + Remove build-ios from Makefile - * include/ffi_common.h (LIKELY, UNLIKELY): Fix definitions. +commit dfbf236d70fc1ec68e6ff193584a154353508e2f +Merge: 852ac3b bb9740e +Author: Anthony Green +Date: Sat Nov 30 20:54:54 2013 -0500 -2012-01-23 Andreas Schwab + Merge branch 'master' of github.com:/atgreen/libffi + Add ChangeLog entry. - * src/m68k/sysv.S (ffi_call_SYSV): Properly test for plain - mc68000. Test for __HAVE_68881__ in addition to __MC68881__. +commit bb9740e545205f93a525c77aa6d1cbf4ca9371f3 +Merge: ac75368 4d701e0 +Author: Anthony Green +Date: Sat Nov 30 17:54:39 2013 -0800 -2012-01-19 Jakub Jelinek + Merge pull request #60 from zwaldowski/ios-redo + + Mac/iOS support, including aarch64 port - PR rtl-optimization/48496 - * src/ia64/ffi.c (ffi_call): Fix up aliasing violations. +commit 4d701e03faa475a5eb3b54b90046114a1e27b813 +Author: Zachary Waldowski +Date: Sat Nov 30 13:25:27 2013 -0500 -2012-01-09 Rainer Orth + Darwin: Properly export headers from Xcode project - * configure.ac (i?86-*-*): Set TARGET to X86_64. - * configure: Regenerate. +commit 022f12eb9ad2264e838fa5fb453733f5177888f4 +Author: Zachary Waldowski +Date: Sat Nov 30 12:21:38 2013 -0500 -2011-12-07 Andrew Pinski + Darwin: Freshen gen scripts, remove old build-ios.sh - PR libffi/50051 - * src/mips/n32.S: Add ".set mips4". +commit e820fe2025d7ad3df7584407946dfaad2af69599 +Author: Zachary Waldowski +Date: Sat Nov 30 12:03:51 2013 -0500 -2011-11-21 Andreas Tobler + Darwin/iOS: Include x86_64+aarch64 pieces in library - * configure: Regenerate. +commit 0278284e470ec91db7cdc15ac3dcd64683305848 +Author: Zachary Waldowski +Date: Sat Nov 30 03:03:37 2013 -0500 -2011-11-12 David Gilbert + Darwin/aarch64: size_t assumptions - * doc/libffi.texi, include/ffi.h.in, include/ffi_common.h, - man/Makefile.am, man/ffi.3, man/ffi_prep_cif.3, - man/ffi_prep_cif_var.3, src/arm/ffi.c, src/arm/ffitarget.h, - src/cris/ffi.c, src/prep_cif.c, - testsuite/libffi.call/cls_double_va.c, - testsuite/libffi.call/cls_longdouble_va.c, - testsuite/libffi.call/float_va.c: Many changes to support variadic - function calls. +commit 9775446b6441c91cd9059215c106aa3bcf949767 +Author: Zachary Waldowski +Date: Sat Nov 30 02:39:34 2013 -0500 -2011-11-12 Kyle Moffett + Darwin/aarch64: Fix “shadows declaration” warnings - * src/powerpc/ffi.c, src/powerpc/ffitarget.h, - src/powerpc/ppc_closure.S, src/powerpc/sysv.S: Many changes for - softfloat powerpc variants. +commit 4260badc37705d3618e774dfe61184ac709881c1 +Author: Zachary Waldowski +Date: Sat Nov 30 02:08:14 2013 -0500 -2011-11-12 Petr Salinger + Darwin/aarch64: Use Clang cache invalidation builtin - * configure.ac (FFI_EXEC_TRAMPOLINE_TABLE): Fix kfreebsd support. - * configure: Rebuilt. +commit 9fa7998d5f9250908cbf12a671479852ebadf9d1 +Author: Zachary Waldowski +Date: Sat Nov 30 02:07:48 2013 -0500 -2011-11-12 Timothy Wall + Darwin/aarch64: Inhibit Xcode warning - * src/arm/ffi.c (ffi_prep_args, ffi_prep_incoming_args_SYSV): Max - alignment of 4 for wince on ARM. +commit 0e832048a93830575b0976406444e134e649a4f7 +Author: Zachary Waldowski +Date: Sat Nov 30 02:07:34 2013 -0500 -2011-11-12 Kyle Moffett - Anthony Green + Darwin/aarch64: double == long double - * src/ppc/sysv.S, src/ppc/ffi.c: Remove use of ppc string - instructions (not available on some cores, like the PPC440). +commit 602dc22d76931092610234cf063f9f1b8dbc1a51 +Author: Zachary Waldowski +Date: Sat Nov 30 02:06:00 2013 -0500 -2011-11-12 Kimura Wataru + Darwin/iOS prep script: try and compile for arm64 - * m4/ax_enable_builddir: Change from string comparison to numeric - comparison for wc output. - * configure.ac: Enable FFI_MMAP_EXEC_WRIT for darwin11 aka Mac OS - X 10.7. - * configure: Rebuilt. +commit b513dfe79de4725e8a717325a9e3b5b9f69f63dc +Author: Zachary Waldowski +Date: Sat Nov 30 02:05:22 2013 -0500 -2011-11-12 Anthony Green + Darwin/aarch64: Restrict .size to ELF like arm32. - * Makefile.am (AM_CCASFLAGS): Add -g option to build assembly - files with debug info. - * Makefile.in: Rebuilt. +commit bc978099bf2812de755c076b67ef9c2547607572 +Author: Zachary Waldowski +Date: Sat Nov 30 02:04:57 2013 -0500 -2011-11-12 Jasper Lievisse Adriaanse + Darwin/aarch64: Potentially(?) fix compile error - * README: Update list of supported OpenBSD systems. +commit d6bb9314467c6e0683156559d23ca341c43fa3c8 +Author: Zachary Waldowski +Date: Sat Nov 30 02:04:22 2013 -0500 -2011-11-12 Anthony Green + Darwin/aarch64: Use CNAME refs - * libtool-version: Update. - * Makefile.am (nodist_libffi_la_SOURCES): Add src/debug.c if - FFI_DEBUG. - (libffi_la_SOURCES): Remove src/debug.c - (EXTRA_DIST): Add src/debug.c - * Makefile.in: Rebuilt. - * README: Update for 3.0.11. +commit 33c46ce5680eea28d3437c8771ec1d137e226b45 +Author: Zachary Waldowski +Date: Sat Nov 30 04:13:42 2013 -0500 -2011-11-10 Richard Henderson + Darwin/Mac: Fix 64/32 shortening warnings - * configure.ac (GCC_AS_CFI_PSEUDO_OP): Use it instead of inline check. - * configure, aclocal.m4: Rebuild. +commit 0612081e6c161d9d820742f995975d35da2adbc2 +Author: Zachary Waldowski +Date: Sat Nov 30 03:03:00 2013 -0500 -2011-09-04 Iain Sandoe + Darwin: Misc size_t warnings - PR libffi/49594 - * src/powerpc/darwin_closure.S (stubs): Make the stub binding - helper reference track the architecture pointer size. +commit 6a6247d179ec3859311c2d8775841b884f309f66 +Author: Zachary Waldowski +Date: Sat Nov 30 02:55:48 2013 -0500 -2011-08-25 Andrew Haley + Darwin: Fix dlmalloc warnings due to sizeof(size_t) - * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Remove hard-coded assembly - instructions. - * src/arm/sysv.S (ffi_arm_trampoline): Put them here instead. +commit 4d60d9e1e32de6166ffd63bbe9ce54cf961c78fc +Author: Zachary Waldowski +Date: Sat Nov 30 04:09:30 2013 -0500 -2011-07-11 Andrew Haley + Darwin: Rebuild Xcode project - * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Clear icache. +commit cb719a5c1c2eb391d6a5f5e02484ba4aa990a51b +Author: Zachary Waldowski +Date: Sat Nov 30 04:09:18 2013 -0500 -2011-06-29 Rainer Orth + Darwin/iOS: Fix LLVM 3.3 warning re: memcpy. - * testsuite/libffi.call/cls_double_va.c: Move PR number to comment. - * testsuite/libffi.call/cls_longdouble_va.c: Likewise. +commit 21bde92c9abb378f9c456a9d95e6f9b99ef8c920 +Author: Zachary Waldowski +Date: Sat Nov 30 03:43:42 2013 -0500 -2011-06-29 Rainer Orth + Darwin: Clean up, modernize generator scripts - PR libffi/46660 - * testsuite/libffi.call/cls_double_va.c: xfail dg-output on - mips-sgi-irix6*. - * testsuite/libffi.call/cls_longdouble_va.c: Likewise. +commit fd54eab74cef7891e4acaaafb71e783142ecb69e +Author: Zachary Waldowski +Date: Sat Nov 30 03:38:02 2013 -0500 -2011-06-14 Rainer Orth + Darwin/Mac: Also exclude OS X generated source - * testsuite/libffi.call/huge_struct.c (test_large_fn): Use PRIu8, - PRId8 instead of %hhu, %hhd. - * testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRId8, - PRIu8): Define. - [__sgi__] (PRId8, PRIu8): Define. +commit 953b6f14c655141f9e7d82550a312c3eeb961091 +Author: Zachary Waldowski +Date: Tue Apr 24 11:16:20 2012 -0400 -2011-04-29 Rainer Orth + Darwin/iOS: More unified syntax support w/ Clang. + + Signed-off-by: Zachary Waldowski - * src/alpha/osf.S (UA_SI, FDE_ENCODING, FDE_ENCODE, FDE_ARANGE): - Define. - Use them to handle ELF vs. ECOFF differences. - [__osf__] (_GLOBAL__F_ffi_call_osf): Define. +commit c713a55379481c339877f2e0003d97cb8d9ed80e +Author: Zachary Waldowski +Date: Tue Apr 24 10:25:29 2012 -0400 -2011-03-30 Timothy Wall + Darwin/iOS: Simplify RETLDM arguments for LLVM 3.1 + + Signed-off-by: Zachary Waldowski - * src/powerpc/darwin.S: Fix unknown FDE encoding. - * src/powerpc/darwin_closure.S: ditto. +commit 16ba1b80028db5cb71cf86e5f79f5e48317f83c8 +Author: Zachary Waldowski +Date: Wed Apr 11 23:26:04 2012 -0400 -2011-02-25 Anthony Green + Darwin: Silence Clang warnings. - * src/powerpc/ffi.c (ffi_prep_closure_loc): Allow for more - 32-bit ABIs. +commit 852ac3bd302d6ed97b1ef65f4cbed69c258a48df +Merge: ab79d6e ac75368 +Author: Anthony Green +Date: Thu Nov 21 21:25:44 2013 -0500 -2011-02-15 Anthony Green + Merge branch 'master' of github.com:/atgreen/libffi + + Conflicts: + ChangeLog - * m4/ax_cc_maxopt.m4: Don't -malign-double or use -ffast-math. - * configure: Rebuilt. +commit ab79d6e21992dd86139ba07530ff888833b78a04 +Author: Alan Modra +Date: Thu Nov 21 06:12:35 2013 -0500 + + This separates the 32-bit sysv/linux/bsd code from the 64-bit linux + code, and makes it possible to link code compiled with different + options to those used to compile libffi. For example, a + -mlong-double-128 libffi can be used with -mlong-double-64 code. + + Using the return value area as a place to pass parameters wasn't such + a good idea, causing a failure of cls_ulonglong.c. I didn't see this + when running the mainline gcc libffi testsuite because that version of + the test is inferior to the upstreamm libffi test. + + Using NUM_FPR_ARG_REGISTERS rather than NUM_FPR_ARG_REGISTERS64 meant + that a parameter save area could be allocated before it was strictly + necessary. Wrong but harmless. Found when splitting apart ffi.c + into 32-bit and 64-bit support. + +commit ac7536889334d4be50709006d7e23536364d7891 +Author: Alan Modra +Date: Thu Nov 21 06:12:35 2013 -0500 + + This separates the 32-bit sysv/linux/bsd code from the 64-bit linux + code, and makes it possible to link code compiled with different + options to those used to compile libffi. For example, a + -mlong-double-128 libffi can be used with -mlong-double-64 code. + + Using the return value area as a place to pass parameters wasn't such + a good idea, causing a failure of cls_ulonglong.c. I didn't see this + when running the mainline gcc libffi testsuite because that version of + the test is inferior to the upstreamm libffi test. + + Using NUM_FPR_ARG_REGISTERS rather than NUM_FPR_ARG_REGISTERS64 meant + that a parameter save area could be allocated before it was strictly + necessary. Wrong but harmless. Found when splitting apart ffi.c + into 32-bit and 64-bit support. + +commit 69df91cfb4fa6bcb644350a80bff970f27478a6a +Merge: 2f45082 aa1f62c +Author: Anthony Green +Date: Mon Nov 18 06:34:04 2013 -0800 + + Merge pull request #59 from iains/powerpc-darwin-unwind-fix + + Fix PowerPC Darwin FDE encodings to use pcrel correctly. Modernise the picbase labels. + +commit aa1f62c0a093c30325dff1d4d2b6b4b22eb96929 +Author: Iain Sandoe +Date: Mon Nov 18 13:11:56 2013 +0000 + + Fix PowerPC Darwin FDE encodings to use pcrel correctly. Modernise the picbase labels. + +commit 2f450822a8698ba88441c56d152c7dc8924b127f +Author: Anthony Green +Date: Mon Nov 18 06:52:29 2013 -0500 + + Clean up code to appease modern GCC compiler. + +commit 16d56c51aded374730920a4acde76ff3d2860ae1 +Author: Alan Modra +Date: Mon Nov 18 06:36:03 2013 -0500 + + An #endif in the wrong place would cause compile failure on powerpcle. + Using bl instead of b doesn't cause runtime failures as you might think, + but does mess the processor branch prediction. + +commit 34f878a5ef28663f6b1d7fd26fb099429ea1579e +Merge: 83f65b6 1fd0457 +Author: Anthony Green +Date: Sat Nov 16 06:57:54 2013 -0500 + + Merge branch 'master' of github.com:/atgreen/libffi + + Conflicts: + ChangeLog + src/powerpc/ffi.c + +commit 83f65b63d9764a9cc7688fc5cda5ee2bd23faf54 +Author: Alan Modra +Date: Sat Nov 16 06:53:50 2013 -0500 + + Finally, this adds _CALL_ELF == 2 support. ELFv1 objects can't be + linked with ELFv2 objects, so this is one case where preprocessor + tests in ffi.c are fine. Also, there is no need to define a new + FFI_ELFv2 or somesuch value in enum ffi_abi. FFI_LINUX64 will happily + serve both ABIs. + +commit 1fd045784cac874b5d76b7fa931f67209a8280d3 +Author: Alan Modra +Date: Sat Nov 16 06:53:50 2013 -0500 + + Finally, this adds _CALL_ELF == 2 support. ELFv1 objects can't be + linked with ELFv2 objects, so this is one case where preprocessor + tests in ffi.c are fine. Also, there is no need to define a new + FFI_ELFv2 or somesuch value in enum ffi_abi. FFI_LINUX64 will happily + serve both ABIs. + +commit 362851379a49ce07d3e36e82c4e5c7b6cc16a352 +Author: Alan Modra +Date: Sat Nov 16 06:52:43 2013 -0500 + + Andreas' 2013-02-08 change reverted some breakage for struct return + values from 2011-11-12, but in so doing reintroduced string + instructions to sysv.S that are not supported on all powerpc variants. + This patch properly copies the bounce buffer to destination in C code + rather than in asm. + + I have tested this on powerpc64-linux, powerpc-linux and + powerpc-freebsd. Well, the last on powerpc-linux by lying to + configure with + + CC="gcc -m32 -msvr4-struct-return -mlong-double-64" \ + CXX="g++ -m32 -msvr4-struct-return -mlong-double-64" \ + /src/libffi-current/configure --build=powerpc-freebsd + + and then + + make && make CC="gcc -m32" CXX="g++ -m32" \ + RUNTESTFLAGS=--target_board=unix/-m32/-msvr4-struct-return/-mlong-double-64\ + check + +commit 1c06515d927d9de1582438d4eb5953890e79c5c7 +Author: Alan Modra +Date: Sat Nov 16 06:41:36 2013 -0500 + + The powerpc64 ABIs align structs passed by value, a fact ignored by + gcc for quite some time. Since gcc now does the correct alignment, + libffi needs to follow suit. This ought to be made selectable via + a new abi value, and the #ifdefs removed from ffi.c along with many + other #ifdefs present there and in assembly. I'll do that with a + followup patch sometime. + + This is a revised version of + https://sourceware.org/ml/libffi-discuss/2013/msg00162.html + +commit a97cf1fae575d8bfd5259c5c422025ad43911326 +Author: Alan Modra +Date: Sat Nov 16 06:40:13 2013 -0500 + + This patch prepares for ELFv2, where sizes of these areas change. It + also makes some minor changes to improve code efficiency. + +commit 164283f4ac5972ce2ab5e015cc2ab1014c23276c +Author: Alan Modra +Date: Sat Nov 16 06:38:55 2013 -0500 + + The powerpc64 support opted to pass floating point values both in the + fpr area and the parameter save area, necessary when the backend + doesn't know if a function argument corresponds to the ellipsis + arguments of a variadic function. This patch adds powerpc support for + variadic functions, and changes the code to only pass fp in the ABI + mandated area. ELFv2 needs this change since the parameter save area + may not exist there. + + This also fixes two faulty tests that used a non-variadic function + cast to call a variadic function, and spuriously reasoned that this is + somehow necessary for static functions.. + +commit 31257b3189f81a199bc2902c22bc5f2d7c54ccde +Author: Andrew Haley +Date: Sat Nov 16 06:35:51 2013 -0500 + + Fix sample closure code + +commit db0ace3a38496af73eae3df02ef353736d16909f +Author: Andrew Haley +Date: Sat Nov 16 06:29:25 2013 -0500 + + Fix broken test cases + +commit de10f5039ed7a53382ddcc95c368d03e535edb98 +Merge: 58c2577 f3657da +Author: Anthony Green +Date: Thu Nov 14 10:56:29 2013 -0500 + + Merge branch 'master' of https://github.com/bivab/libffi + + Conflicts: + ChangeLog + +commit f3657da278dd63afcdd8762894a9bdaea8ef028a +Author: David Schneider +Date: Thu Nov 14 13:02:16 2013 +0100 + + update Changelog + +commit 58c2577a3ff80e7416ef0434769e2af23365719c +Author: Alan Modra +Date: Wed Nov 13 16:55:36 2013 -0500 + + This enshrines the current testsuite practice of using ffi_arg for + returned values. It would be reasonable and logical to use the actual + return argument type as passed to ffi_prep_cif, but this would mean + changing a large number of tests that use ffi_arg and all backends + that write results to an ffi_arg. + +commit 8af42f9944f7ed72c81ae360aac6a84dc11f89dc +Author: Anthony Green +Date: Wed Nov 13 16:40:28 2013 -0500 + + Respect HAVE_ALLOCA_H + +commit cdf405d574f479b782454516366bd4f4b9b3415e +Author: David Schneider +Date: Wed Nov 13 15:50:21 2013 +0100 + + add a testcase for the double/float issue on ARMHF + +commit 77f823e31ffb557a466b24f7fba845fbf7831798 +Author: David Schneider +Date: Wed Nov 13 14:26:57 2013 +0100 -2011-02-13 Ralf Wildenhues + stop trying to assing vfp regs once we are done with the registers - * configure: Regenerate. +commit 37067ec5036f2a6ed7a4799f83f8f53160460344 +Author: David Schneider +Date: Tue Nov 12 19:49:01 2013 +0100 -2011-02-13 Anthony Green + mark all vfp registers as used when done. + + To avoid assigning registers the would fit, once arguments have been on + the stack, we mark all registers as used once we do not find a free + register for the first time. - * include/ffi_common.h (UNLIKELY, LIKELY): Define. - * src/x86/ffi64.c (UNLIKELY, LIKELY): Remove definition. - * src/prep_cif.c (UNLIKELY, LIKELY): Remove definition. +commit 2f5b7ce545473a7f6e41193edc29407cbebe82d5 +Author: Anthony Green +Date: Sat Nov 9 06:16:32 2013 -0500 - * src/prep_cif.c (initialize_aggregate): Convert assertion into - FFI_BAD_TYPEDEF return. Initialize arg size and alignment to 0. + UltraSPARC IIi fix. Update README and build configury. - * src/pa/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, - just return FFI_BAD_ABI when things are wrong. - * src/arm/ffi.c (ffi_prep_closure_loc): Ditto. - * src/powerpc/ffi.c (ffi_prep_closure_loc): Ditto. - * src/mips/ffi.c (ffi_prep_closure_loc): Ditto. - * src/ia64/ffi.c (ffi_prep_closure_loc): Ditto. - * src/avr32/ffi.c (ffi_prep_closure_loc): Ditto. +commit becd754434173032f426d22ffcbfe24f55b3c137 +Author: Mark Kettenis +Date: Wed Nov 6 06:43:49 2013 -0500 -2011-02-11 Anthony Green + Align the stack pointer to 16-bytes. - * src/sparc/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, - just return FFI_BAD_ABI when things are wrong. +commit 05c31093409f7b3e6d795fac21d2c954313d8162 +Author: Konstantin Belousov +Date: Wed Nov 6 06:40:58 2013 -0500 -2012-02-11 Eric Botcazou + Mark executable as not requiring executable stack. - * src/sparc/v9.S (STACKFRAME): Bump to 176. +commit cf6bf9818e8394cfcdb07a40c6a5e2ee6b01d333 +Author: Anthony Green +Date: Sat Nov 2 17:23:59 2013 -0400 -2011-02-09 Stuart Shelton + Fix up docs - http://bugs.gentoo.org/show_bug.cgi?id=286911 - * src/mips/ffitarget.h: Clean up error messages. - * src/java_raw_api.c (ffi_java_translate_args): Cast raw arg to - ffi_raw*. - * include/ffi.h.in: Add pragma for SGI compiler. +commit 02177176854d16fc0f1a5958aa34da2f306630ee +Merge: c242217 c265b4c +Author: Anthony Green +Date: Sat Nov 2 17:11:22 2013 -0400 -2011-02-09 Anthony Green + Merge branch 'master' of github.com:/atgreen/libffi - * configure.ac: Add powerpc64-*-darwin* support. +commit c2422174b3edc0de0b148dfd6b67087bb881c4a6 +Merge: f4b843f d918d47 +Author: Anthony Green +Date: Sat Nov 2 14:08:23 2013 -0700 -2011-02-09 Anthony Green + Merge pull request #45 from foss-for-synopsys-dwc-arc-processors/arc_support + + arc: Fix build error - * README: Mention Interix. +commit c265b4cacb9130f042699a85de9c7242b3f49cc3 +Merge: f4b843f d918d47 +Author: Anthony Green +Date: Sat Nov 2 14:08:23 2013 -0700 -2011-02-09 Jonathan Callen + Merge pull request #45 from foss-for-synopsys-dwc-arc-processors/arc_support + + arc: Fix build error - * configure.ac: Add Interix to win32/cygwin/mingw case. - * configure: Ditto. - * src/closures.c: Treat Interix like Cygwin, instead of as a - generic win32. +commit f4b843f83710ac378c48abd87fe66bb519d30d2e +Author: Anthony Green +Date: Sat Nov 2 17:01:15 2013 -0400 -2011-02-09 Anthony Green + Don't align stack for win32 - * testsuite/libffi.call/err_bad_typedef.c: Remove xfail. - * testsuite/libffi.call/err_bad_abi.c: Remove xfail. - * src/x86/ffi64.c (UNLIKELY, LIKELY): Define. - (ffi_prep_closure_loc): Check for bad ABI. - * src/prep_cif.c (UNLIKELY, LIKELY): Define. - (initialize_aggregate): Check for bad types. +commit f3cd39345713db8e414cf642b6cb65a4cfe6018c +Merge: 666f3e7 6aa1590 +Author: Anthony Green +Date: Sat Nov 2 13:17:57 2013 -0700 -2011-02-09 Landon Fuller + Merge pull request #51 from vbudovski/for_upstream + + Don't use 16 byte aligned stack for WIN32 - * Makefile.am (EXTRA_DIST): Add build-ios.sh, src/arm/gentramp.sh, - src/arm/trampoline.S. - (nodist_libffi_la_SOURCES): Add src/arc/trampoline.S. - * configure.ac (FFI_EXEC_TRAMPOLINE_TABLE): Define. - * src/arm/ffi.c (ffi_trampoline_table) - (ffi_closure_trampoline_table_page, ffi_trampoline_table_entry) - (FFI_TRAMPOLINE_CODELOC_CONFIG, FFI_TRAMPOLINE_CONFIG_PAGE_OFFSET) - (FFI_TRAMPOLINE_COUNT, ffi_trampoline_lock, ffi_trampoline_tables) - (ffi_trampoline_table_alloc, ffi_closure_alloc, ffi_closure_free): - Define for FFI_EXEC_TRAMPOLINE_TABLE case (iOS). - (ffi_prep_closure_loc): Handl FFI_EXEC_TRAMPOLINE_TABLE case - separately. - * src/arm/sysv.S: Handle Apple iOS host. - * src/closures.c: Handle FFI_EXEC_TRAMPOLINE_TABLE case. - * build-ios.sh: New file. - * fficonfig.h.in, configure, Makefile.in: Rebuilt. - * README: Mention ARM iOS. +commit 666f3e71b56d92c49fcd2d7f349b8f8ebca0f8a3 +Author: Anthony Green +Date: Sat Oct 26 09:12:42 2013 -0400 -2011-02-08 Oren Held + Add more credits to README. Tidy up. - * src/dlmalloc.c (_STRUCT_MALLINFO): Define in order to avoid - redefinition of mallinfo on HP-UX. +commit 73ada14e756bad97fad0e6915a821a3c7e079f81 +Author: Anthony Green +Date: Sat Oct 26 09:09:45 2013 -0400 -2011-02-08 Ginn Chen + Update README - * src/sparc/ffi.c (ffi_call): Make compatible with Solaris Studio - aggregate return ABI. Flush cache. - (ffi_prep_closure_loc): Flush cache. +commit d3372c54ce7117e80d389ba875dc5b6b2213c71e +Author: Mark H Weaver +Date: Sat Oct 26 08:30:06 2013 -0400 -2011-02-11 Anthony Green + Fix N32 ABI issue for MIPS. - From Tom Honermann : - * src/powerpc/aix.S (ffi_call_AIX): Support for xlc toolchain on - AIX. Declare .ffi_prep_args. Insert nops after branch - instructions so that the AIX linker can insert TOC reload - instructions. - * src/powerpc/aix_closure.S: Declare .ffi_closure_helper_DARWIN. +commit d6716aba8118eb0513885cfe557bedebb7016e8b +Author: Anthony Green +Date: Tue Oct 15 15:42:49 2013 -0400 -2011-02-08 Ed + Update travis-ci build dependencies to include texinfo - * src/powerpc/asm.h: Fix grammar nit in comment. +commit 16b93a211bcfbe4bd0efdcf94de225a71aa0ee02 +Author: Sandra Loosemore +Date: Tue Oct 15 15:33:59 2013 -0400 -2011-02-08 Uli Link + Add nios2 port. - * include/ffi.h.in (FFI_64_BIT_MAX): Define and use. +commit 2f5626ce02fce8267ab48ceb6d7d0ed7d672a75e +Author: Sandra Loosemore +Date: Tue Oct 15 15:32:16 2013 -0400 -2011-02-09 Rainer Orth + Fix testsuite bug - PR libffi/46661 - * testsuite/libffi.call/cls_pointer.c (main): Cast void * to - uintptr_t first. - * testsuite/libffi.call/cls_pointer_stack.c (main): Likewise. +commit f64e4a865557e440774436b4c2b2fd7374290e97 +Author: Marcus Shawcroft +Date: Tue Oct 15 15:20:14 2013 -0400 -2011-02-08 Rafael Avila de Espindola + Fix many.c testcase for Aarch64 - * configure.ac: Fix x86 test for pc related relocs. - * configure: Rebuilt. +commit 128cd1d2f358f26d9fa75a27cf2b30356f5dd903 +Author: Anthony Green +Date: Tue Oct 8 06:45:51 2013 -0400 -2011-02-07 Joel Sherrill + Fix spelling errors - * libffi/src/m68k/ffi.c: Add RTEMS support for cache flushing. - Handle case when CPU variant does not have long double support. - * libffi/src/m68k/sysv.S: Add support for mc68000, Coldfire, - and cores with soft floating point. - -2011-02-07 Joel Sherrill - - * configure.ac: Add mips*-*-rtems* support. - * configure: Regenerate. - * src/mips/ffitarget.h: Ensure needed constants are available - for targets which do not have sgidefs.h. - -2011-01-26 Dave Korn - - PR target/40125 - * configure.ac (AM_LTLDFLAGS): Add -bindir option for windows DLLs. - * configure: Regenerate. - -2010-12-18 Iain Sandoe - - PR libffi/29152 - PR libffi/42378 - * src/powerpc/darwin_closure.S: Provide Darwin64 implementation, - update comments. - * src/powerpc/ffitarget.h (POWERPC_DARWIN64): New, - (FFI_TRAMPOLINE_SIZE): Update for Darwin64. - * src/powerpc/darwin.S: Provide Darwin64 implementation, - update comments. - * src/powerpc/ffi_darwin.c: Likewise. - -2010-12-06 Rainer Orth - - * configure.ac (libffi_cv_as_ascii_pseudo_op): Use double - backslashes. - (libffi_cv_as_string_pseudo_op): Likewise. - * configure: Regenerate. - -2010-12-03 Chung-Lin Tang - - * src/arm/sysv.S (ffi_closure_SYSV): Add UNWIND to .pad directive. - (ffi_closure_VFP): Same. - (ffi_call_VFP): Move down to before ffi_closure_VFP. Add '.fpu vfp' - directive. - -2010-12-01 Rainer Orth - - * testsuite/libffi.call/ffitest.h [__sgi] (PRId64, PRIu64): Define. - (PRIuPTR): Define. +commit ff06269d707cafbfef2a88afb07a79c9d1480c5f +Author: Anthony Green +Date: Tue Oct 8 06:32:18 2013 -0400 -2010-11-29 Richard Henderson - Rainer Orth + Update README for M88K and VAX - * src/x86/sysv.S (FDE_ENCODING, FDE_ENCODE): Define. - (.eh_frame): Use FDE_ENCODING. - (.LASFDE1, .LASFDE2, LASFDE3): Simplify with FDE_ENCODE. +commit d2fcbcdfbea750d1f6a9f493e2e6c4d5ffa71b34 +Author: Anthony Green +Date: Tue Oct 8 06:27:46 2013 -0400 -2010-11-22 Jacek Caban + Add m88k and VAX support. Update some configury bits. - * configure.ac: Check for symbol underscores on mingw-w64. - * configure: Rebuilt. - * src/x86/win64.S: Correctly access extern symbols in respect to - underscores. +commit 6aa15900accc0a648cdebf11ec11d11697ebfffd +Author: Vitaly Budovski +Date: Thu Sep 5 12:05:06 2013 +1000 -2010-11-15 Rainer Orth + Don't use 16 byte aligned stack for WIN32 + + This fixes a crash when accessing __stdcall functions in Python ctypes. - * testsuite/lib/libffi-dg.exp: Rename ... - * testsuite/lib/libffi.exp: ... to this. - * libffi/testsuite/libffi.call/call.exp: Don't load libffi-dg.exp. - * libffi/testsuite/libffi.special/special.exp: Likewise. +commit 3b44d41156149af8da2a58825fefdfa23274ae7a +Author: Makoto Kato +Date: Wed Jul 10 15:34:53 2013 +0900 -2010-10-28 Chung-Lin Tang + Fix build failure when using clang for Android + + clang for Android generates __gnu_linux__ define, but gcc for Android doesn't. So we should add check it for Android - * src/arm/ffi.c (ffi_prep_args): Add VFP register argument handling - code, new parameter, and return value. Update comments. - (ffi_prep_cif_machdep): Add case for VFP struct return values. Add - call to layout_vfp_args(). - (ffi_call_SYSV): Update declaration. - (ffi_call_VFP): New declaration. - (ffi_call): Add VFP struct return conditions. Call ffi_call_VFP() - when ABI is FFI_VFP. - (ffi_closure_VFP): New declaration. - (ffi_closure_SYSV_inner): Add new vfp_args parameter, update call to - ffi_prep_incoming_args_SYSV(). - (ffi_prep_incoming_args_SYSV): Update parameters. Add VFP argument - case handling. - (ffi_prep_closure_loc): Pass ffi_closure_VFP to trampoline - construction under VFP hard-float. - (rec_vfp_type_p): New function. - (vfp_type_p): Same. - (place_vfp_arg): Same. - (layout_vfp_args): Same. - * src/arm/ffitarget.h (ffi_abi): Add FFI_VFP. Define FFI_DEFAULT_ABI - based on __ARM_PCS_VFP. - (FFI_EXTRA_CIF_FIELDS): Define for adding VFP hard-float specific - fields. - (FFI_TYPE_STRUCT_VFP_FLOAT): Define internally used type code. - (FFI_TYPE_STRUCT_VFP_DOUBLE): Same. - * src/arm/sysv.S (ffi_call_SYSV): Change call of ffi_prep_args() to - direct call. Move function pointer load upwards. - (ffi_call_VFP): New function. - (ffi_closure_VFP): Same. +commit d918d47809c174d62283306b282749f8db93661f +Author: Mischa Jonker +Date: Mon Jul 8 15:51:36 2013 +0200 - * testsuite/lib/libffi-dg.exp (check-flags): New function. - (dg-skip-if): New function. - * testsuite/libffi.call/cls_double_va.c: Skip if target is arm*-*-* - and compiler options include -mfloat-abi=hard. - * testsuite/libffi.call/cls_longdouble_va.c: Same. + arc: Fix build error + + One part of the patch for ARC support was missing in the upstreamed + version. + + Signed-off-by: Mischa Jonker -2010-10-01 Jakub Jelinek +commit d3d099b40c122550279789200263346f120f6909 +Author: Anthony Green +Date: Tue Jul 2 16:11:38 2013 -0400 - PR libffi/45677 - * src/x86/ffi64.c (ffi_prep_cif_machdep): Ensure cif->bytes is - a multiple of 8. - * testsuite/libffi.call/many2.c: New test. + little-endian ppc64 support -2010-08-20 Mark Wielaard +commit 0f8690a84c874ec09a090c8c6adfb93c594acac6 +Author: Anthony Green +Date: Tue Jul 2 15:54:40 2013 -0400 - * src/closures.c (open_temp_exec_file_mnt): Check if getmntent_r - returns NULL. + Rebuild for ARC additions -2010-08-09 Andreas Tobler +commit f88118b345f27c46f5445d6e4832c498ff9a6d85 +Author: Anthony Green +Date: Tue Jul 2 15:51:27 2013 -0400 - * configure.ac: Add target powerpc64-*-freebsd*. - * configure: Regenerate. - * testsuite/libffi.call/cls_align_longdouble_split.c: Pass - -mlong-double-128 only to linux targets. - * testsuite/libffi.call/cls_align_longdouble_split2.c: Likewise. - * testsuite/libffi.call/cls_longdouble.c: Likewise. - * testsuite/libffi.call/huge_struct.c: Likewise. + Revert "Merge pull request #36 from abergmeier/emscripten_fix" + + This reverts commit 6a4d901dde7b3f87984c563505717cde3113d16e, reversing + changes made to b50a13b9c07ec09af4b9697e482acdad571e6961. -2010-08-05 Dan Witte +commit 6a4d901dde7b3f87984c563505717cde3113d16e +Merge: b50a13b 587002c +Author: Anthony Green +Date: Tue Jul 2 12:12:34 2013 -0700 - * Makefile.am: Pass FFI_DEBUG define to msvcc.sh for linking to the - debug CRT when --enable-debug is given. - * configure.ac: Define it. - * msvcc.sh: Translate -g and -DFFI_DEBUG appropriately. + Merge pull request #36 from abergmeier/emscripten_fix + + Fixes for building with Emscripten -2010-08-04 Dan Witte +commit b50a13b9c07ec09af4b9697e482acdad571e6961 +Merge: 767f1f9 b082e15 +Author: Anthony Green +Date: Tue Jul 2 12:10:26 2013 -0700 - * src/x86/ffitarget.h: Add X86_ANY define for all x86/x86_64 - platforms. - * src/x86/ffi.c: Remove redundant ifdef checks. - * src/prep_cif.c: Push stack space computation into src/x86/ffi.c - for X86_ANY so return value space doesn't get added twice. + Merge pull request #44 from foss-for-synopsys-dwc-arc-processors/arc_support + + Add ARC support -2010-08-03 Neil Rashbrooke +commit 767f1f96e5282da44d7340e6815e9820a3f78e39 +Merge: c3c40e0 b8a91d8 +Author: Anthony Green +Date: Tue Jul 2 12:08:04 2013 -0700 - * msvcc.sh: Don't pass -safeseh to ml64 because behavior is buggy. + Merge pull request #43 from JensTimmerman/__m128 + + added include for xmmintrin.h -2010-07-22 Dan Witte +commit b8a91d81be77d479327fdb6bdd9fdae6d18e6e63 +Author: Jens Timmerman +Date: Tue Jul 2 10:57:37 2013 +0200 - * src/*/ffitarget.h: Make FFI_LAST_ABI one past the last valid ABI. - * src/prep_cif.c: Fix ABI assertion. - * src/cris/ffi.c: Ditto. + added include for xmmintrin.h -2010-07-10 Evan Phoenix +commit b082e15091961373c03d10ed0251f619ebb6ed76 +Author: Mischa Jonker +Date: Mon Jun 10 16:19:33 2013 +0200 - * src/closures.c (selinux_enabled_check): Fix strncmp usage bug. + Add ARC support + + This adds support for the ARC architecture to libffi. DesignWare ARC + is a family of processors from Synopsys, Inc. + + This patch has been tested on a little-endian system and passes + the testsuite. + + Signed-off-by: Mischa Jonker -2010-07-07 Dan Horák +commit cc9b518687e46b0d1acafdd4bc3f3b281c25a3d9 +Author: Marcin Wojdyr +Date: Tue May 14 15:01:23 2013 +0200 - * include/ffi.h.in: Protect #define with #ifndef. - * src/powerpc/ffitarget.h: Ditto. - * src/s390/ffitarget.h: Ditto. - * src/sparc/ffitarget.h: Ditto. + Update libffi.pc.in + + use -L${toolexeclibdir} instead of -L${libdir} + to be consistent with Makefile.am -2010-07-07 Neil Roberts +commit 587002c092cffe6e7a8d7028f246c241d03b738c +Author: Andreas Bergmeier +Date: Fri Apr 19 17:12:24 2013 +0200 - * src/x86/sysv.S (ffi_call_SYSV): Align the stack pointer to - 16-bytes. + Enable disabling of libtool on platforms where it does not work (e.g. LLVM). + Build libraries normally then. -2010-07-02 Jakub Jelinek +commit c3c40e0290377d7cf948b072eedd8317c4bf215e +Merge: ede96e4 4750e3c +Author: Anthony Green +Date: Sat Mar 30 05:24:14 2013 -0700 - * Makefile.am (AM_MAKEFLAGS): Pass also mandir to submakes. - * Makefile.in: Regenerated. + Merge pull request #34 from davidsch/armhf + + Fix ARM hard-float support for large numbers of VFP arguments -2010-05-19 Rainer Orth +commit 4750e3c662fd9569cb3e2d28f539685fd1ca8caf +Author: David Schneider +Date: Thu Mar 28 16:56:36 2013 +0100 - * configure.ac (libffi_cv_as_x86_pcrel): Check for illegal in as - output, too. - (libffi_cv_as_ascii_pseudo_op): Check for .ascii. - (libffi_cv_as_string_pseudo_op): Check for .string. - * configure: Regenerate. - * fficonfig.h.in: Regenerate. - * src/x86/sysv.S (.eh_frame): Use .ascii, .string or error. + update changelog -2010-05-11 Dan Witte +commit 9708e7cf09f1bf815f4d6485eb1f180fabb35804 +Author: David Schneider +Date: Wed Mar 27 19:31:04 2013 +0100 - * doc/libffi.tex: Document previous change. + folow the ARM hard-float ABI in ffi_prep_incoming_args_VFP -2010-05-11 Makoto Kato +commit b41120981e5e49ca2da10b94b154775f50da5f36 +Author: David Schneider +Date: Wed Mar 27 16:38:35 2013 +0100 - * src/x86/ffi.c (ffi_call): Don't copy structs passed by value. + create separated versions of ffi_prep_incoming_args_* for SYSV and VFP ABIs. + + The different versions will be called depending on the value of cif->abi -2010-05-05 Michael Kohler +commit dd26f1f39c54861c5b91931f0f37a72942c2a072 +Author: David Schneider +Date: Thu Mar 28 15:39:01 2013 +0100 - * src/dlmalloc.c (dlfree): Fix spelling. - * src/ia64/ffi.c (ffi_prep_cif_machdep): Ditto. - * configure.ac: Ditto. - * configure: Rebuilt. + add a failing test for closures on ARM hardfloat -2010-04-13 Dan Witte +commit 3c1608613ab3c2184222b98c5482cddedd6b559b +Author: David Schneider +Date: Tue Mar 26 19:24:47 2013 +0100 - * msvcc.sh: Build with -W3 instead of -Wall. - * src/powerpc/ffi_darwin.c: Remove build warnings. - * src/x86/ffi.c: Ditto. - * src/x86/ffitarget.h: Ditto. + extend ffi_prepare_args for FFI_VFP (hard-float ABI), fixing an issue with passing VFP arguments in VFP registers and the stack, while at the same time not using all core registers. -2010-04-12 Dan Witte - Walter Meinl +commit 0f2ff2d4c92719be8936179f9ab674f4d1a3fd14 +Author: David Schneider +Date: Tue Mar 26 19:22:02 2013 +0100 - * configure.ac: Add OS/2 support. - * configure: Rebuilt. - * src/closures.c: Ditto. - * src/dlmalloc.c: Ditto. - * src/x86/win32.S: Ditto. + separate ARM ffi_prepare_args in a version implementing the simple SYSV calling convention and one for the hard-float calling convention -2010-04-07 Jakub Jelinek +commit 3a352b8a8252400a83de22c7c424bf1887b4a2ef +Author: David Schneider +Date: Tue Mar 26 14:24:04 2013 +0100 - * testsuite/libffi.call/err_bad_abi.c: Remove unused args variable. + move the hardfloat specific argument copying code to the helper function -2010-04-02 Ralf Wildenhues +commit 5df6b7944a4225b6eb329f3886be64e04e966f29 +Author: David Schneider +Date: Tue Mar 26 14:02:21 2013 +0100 - * Makefile.in: Regenerate. - * aclocal.m4: Regenerate. - * include/Makefile.in: Regenerate. - * man/Makefile.in: Regenerate. - * testsuite/Makefile.in: Regenerate. + extract setting of arguments to be passed to a helper function -2010-03-30 Dan Witte +commit 7d1048c471bb4b1f9d67a9e9f8e95f9a1d2e6d45 +Author: David Schneider +Date: Tue Mar 26 11:33:33 2013 +0100 - * msvcc.sh: Disable build warnings. - * README (tested): Clarify windows build procedure. + extract code to align the argument storage pointer to a helper function -2010-03-15 Rainer Orth +commit b9f013788f0f384c423ad963475aaacb55598135 +Author: David Schneider +Date: Mon Mar 25 13:27:36 2013 +0100 - * configure.ac (libffi_cv_as_x86_64_unwind_section_type): New test. - * configure: Regenerate. - * fficonfig.h.in: Regenerate. - * libffi/src/x86/unix64.S (.eh_frame) - [HAVE_AS_X86_64_UNWIND_SECTION_TYPE]: Use @unwind section type. + add a testcase, that on ARM hardfloat needs more than the 8 VFP argument registers to pass arguments to a call -2010-03-14 Matthias Klose +commit 2fbdb0f231cafdb77b025d3cd8afe90cda99b3ba +Author: David Schneider +Date: Mon Mar 25 13:26:02 2013 +0100 - * src/x86/ffi64.c: Fix typo in comment. - * src/x86/ffi.c: Use /* ... */ comment style. + use the absolute value to check the test result against an epsilon -2010-02-24 Rainer Orth +commit ede96e4eb660bbf3e0fe048135efa8106f48af5d +Merge: f22ab3c 9e34992 +Author: Anthony Green +Date: Sun Mar 17 18:38:21 2013 -0400 - * doc/libffi.texi (The Closure API): Fix typo. - * doc/libffi.info: Remove. + Merge branch 'master' of github.com:/atgreen/libffi -2010-02-15 Matthias Klose +commit f22ab3c6877cbdd07f058b68816b0086b1cb0e1e +Merge: 12b1886 d08124b +Author: Anthony Green +Date: Sun Mar 17 18:34:54 2013 -0400 - * src/arm/sysv.S (__ARM_ARCH__): Define for processor - __ARM_ARCH_7EM__. + Merge branch 'master' of github.com:/atgreen/libffi -2010-01-15 Anthony Green +commit 9e34992a5ea2fda1dba5875bf96dc91a7230f51f +Merge: 12b1886 d08124b +Author: Anthony Green +Date: Sun Mar 17 18:34:54 2013 -0400 - * README: Add notes on building with Microsoft Visual C++. + Merge branch 'master' of github.com:/atgreen/libffi -2010-01-15 Daniel Witte +commit 12b1886d7b1f8aa264b1d348bfa47a0e14712df4 +Author: Anthony Green +Date: Sun Mar 17 18:32:12 2013 -0400 - * msvcc.sh: New file. + cygwin fix & updates for 3.0.13 - * src/x86/win32.S: Port assembly routines to MSVC and #ifdef. - * src/x86/ffi.c: Tweak function declaration and remove excess - parens. - * include/ffi.h.in: Add __declspec(align(8)) to typedef struct - ffi_closure. +commit d08124bedf2c6d61874fe215404783aeb9f6f1ac +Author: Anthony Green +Date: Sun Mar 17 18:32:12 2013 -0400 - * src/x86/ffi.c: Merge ffi_call_SYSV and ffi_call_STDCALL into new - function ffi_call_win32 on X86_WIN32. - * src/x86/win32.S (ffi_call_SYSV): Rename to ffi_call_win32. - (ffi_call_STDCALL): Remove. + cygwin fix & updates for 3.0.13 - * src/prep_cif.c (ffi_prep_cif): Move stack space allocation code - to ffi_prep_cif_machdep for x86. - * src/x86/ffi.c (ffi_prep_cif_machdep): To here. +commit cb32c812d04d1dfa72002cc04924e7e4fef89e02 +Author: Anthony Green +Date: Sun Mar 17 09:27:55 2013 -0400 -2010-01-15 Oliver Kiddle + Fix lib install dir - * src/x86/ffitarget.h (ffi_abi): Check for __i386 and __amd64 for - Sun Studio compiler compatibility. +commit efd7866a361a6f636bae8400d26c6811e56ca207 +Author: Anthony Green +Date: Sat Mar 16 08:35:57 2013 -0400 -2010-01-12 Conrad Irwin + 2.0.13rc1 - * doc/libffi.texi: Add closure example. +commit ff647ad4dff2f07dd153f295a1f70b1d906cd6ca +Merge: 4acf005 d9dd417 +Author: Anthony Green +Date: Sat Mar 16 08:20:40 2013 -0400 -2010-01-07 Rainer Orth + Merge branch 'master' of github.com:/atgreen/libffi + + Conflicts: + ChangeLog - PR libffi/40701 - * testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRIdLL, - PRIuLL, PRId64, PRIu64, PRIuPTR): Define. - * testsuite/libffi.call/cls_align_sint64.c: Add -Wno-format on - alpha*-dec-osf*. - * testsuite/libffi.call/cls_align_uint64.c: Likewise. - * testsuite/libffi.call/cls_ulonglong.c: Likewise. - * testsuite/libffi.call/return_ll1.c: Likewise. - * testsuite/libffi.call/stret_medium2.c: Likewise. - * testsuite/libffi.special/ffitestcxx.h (allocate_mmap): Cast - MAP_FAILED to char *. +commit 4acf0056f55c757490dae6c29a65b0321327ea8a +Author: Anthony Green +Date: Sat Mar 16 08:18:45 2013 -0400 -2010-01-06 Rainer Orth + Build fix for soft-float power targets - * src/mips/n32.S: Use .abicalls and .eh_frame with __GNUC__. +commit 675c9839224e4268187f1ec6f512127f9db555d0 +Author: Anthony Green +Date: Sat Mar 16 08:12:38 2013 -0400 -2009-12-31 Anthony Green + Documentation fix - * README: Update for libffi 3.0.9. +commit 8a286f570ccd41db81f74ea7f248da62241d898a +Author: Anthony Green +Date: Sat Mar 16 08:01:19 2013 -0400 -2009-12-27 Matthias Klose + Fix for m68000 systems - * configure.ac (HAVE_LONG_DOUBLE): Define for mips when - appropriate. - * configure: Rebuilt. +commit d9dd417b09566af55b7b3000bb53ccaf2e1d6c92 +Author: Anthony Green +Date: Sat Mar 16 08:01:19 2013 -0400 -2009-12-26 Anthony Green + Fix for m68000 systems - * testsuite/libffi.call/cls_longdouble_va.c: Mark as xfail for - avr32*-*-*. - * testsuite/libffi.call/cls_double_va.c: Ditto. +commit 215763d012a944d95406b394d6013b80d220e870 +Author: Anthony Green +Date: Sat Mar 16 07:57:35 2013 -0400 -2009-12-26 Andreas Tobler + Update configury. - * testsuite/libffi.call/ffitest.h: Conditionally include stdint.h - and inttypes.h. - * testsuite/libffi.special/unwindtest.cc: Ditto. +commit 9180d8f39c9b6afe17b78277c2711a5d9948e824 +Merge: 2fb527a 7e1b326 +Author: Anthony Green +Date: Sat Mar 16 07:46:55 2013 -0400 -2009-12-26 Andreas Tobler + Merge branch 'master' of github.com:/atgreen/libffi - * configure.ac: Add amd64-*-openbsd*. - * configure: Rebuilt. - * testsuite/lib/libffi-dg.exp (libffi_target_compile): Link - openbsd programs with -lpthread. +commit 2fb527a017a4943e176a489ff103231b86464b59 +Author: Anthony Green +Date: Sat Mar 16 07:46:38 2013 -0400 -2009-12-26 Anthony Green + Add Meta processor support - * testsuite/libffi.call/cls_double_va.c, - testsuite/libffi.call/cls_longdouble.c, - testsuite/libffi.call/cls_longdouble_va.c, - testsuite/libffi.call/cls_pointer.c, - testsuite/libffi.call/cls_pointer_stack.c: Remove xfail for - mips*-*-* and arm*-*-*. - * testsuite/libffi.call/cls_align_longdouble_split.c, - testsuite/libffi.call/cls_align_longdouble_split2.c, - testsuite/libffi.call/stret_medium2.c, - testsuite/libffi.call/stret_medium.c, - testsuite/libffi.call/stret_large.c, - testsuite/libffi.call/stret_large2.c: Remove xfail for arm*-*-*. +commit 211a9ebf4d1a9801e15e103566aed2b8c42790be +Merge: f308faf ee18766 +Author: Anthony Green +Date: Sat Mar 16 04:24:40 2013 -0700 -2009-12-31 Kay Tietz + Merge pull request #32 from alex/patch-1 + + Fix for a crasher due to misaligned stack on x86-32. - * testsuite/libffi.call/ffitest.h, - testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRuLL): Fix - definitions. +commit 7e1b32649efd24814e86172e196f390566f9e970 +Merge: f308faf ee18766 +Author: Anthony Green +Date: Sat Mar 16 04:24:40 2013 -0700 -2009-12-31 Carlo Bramini + Merge pull request #32 from alex/patch-1 + + Fix for a crasher due to misaligned stack on x86-32. - * configure.ac (AM_LTLDFLAGS): Define for windows hosts. - * Makefile.am (libffi_la_LDFLAGS): Add AM_LTLDFLAGS. - * configure: Rebuilt. - * Makefile.in: Rebuilt. +commit ee18766b169811426c14b011fbb46d81e344f926 +Author: Alex Gaynor +Date: Thu Mar 14 15:00:33 2013 -0700 -2009-12-31 Anthony Green - Blake Chaffin. + Fix for a crasher due to misaligned stack on x86-32. + + Full information on reproduction (using Python's ctypes available here: http://bugs.python.org/issue17423) - * testsuite/libffi.call/huge_struct.c: New test case from Blake - Chaffin @ Apple. +commit f308faf1eabaf8dc24966ab17fbf94368f46b9c7 +Author: Anthony Green +Date: Mon Feb 11 14:25:13 2013 -0500 -2009-12-28 David Edelsohn + Add moxie support. Release 3.0.12. - * src/powerpc/ffi_darwin.c (ffi_prep_args): Copy abi and nargs to - local variables. - (aix_adjust_aggregate_sizes): New function. - (ffi_prep_cif_machdep): Call it. +commit 4ea22e54e3b143fe05c413f6dddd236af6bcbfb2 +Author: Anthony Green +Date: Sun Feb 10 08:48:38 2013 -0500 -2009-12-26 Andreas Tobler + Update README - * configure.ac: Define FFI_MMAP_EXEC_WRIT for the given targets. - * configure: Regenerate. - * fficonfig.h.in: Likewise. - * src/closures.c: Remove the FFI_MMAP_EXEC_WRIT definition for - Solaris/x86. +commit 10e77227b6ae85f46f28590bfb09ca3608554358 +Author: Anthony Green +Date: Sun Feb 10 08:47:26 2013 -0500 -2009-12-26 Andreas Schwab + mend - * src/powerpc/ffi.c (ffi_prep_args_SYSV): Advance intarg_count - when a float arguments is passed in memory. - (ffi_closure_helper_SYSV): Mark general registers as used up when - a 64bit or soft-float long double argument is passed in memory. +commit a9521411a53d58f2bf88199242200ceb0d4dae3a +Author: Anthony Green +Date: Sat Feb 9 06:54:40 2013 -0500 -2009-12-25 Matthias Klose + sparc v8 and testsuite fixes - * man/ffi_call.3: Fix #include in examples. - * doc/libffi.texi: Add dircategory. +commit 70b11b47eea93bf43627588d494d0b3b0d062481 +Author: Anthony Green +Date: Fri Feb 8 16:12:19 2013 -0500 -2009-12-25 Frank Everdij + Fix small struct passing on ppc - * include/ffi.h.in: Placed '__GNUC__' ifdef around - '__attribute__((aligned(8)))' in ffi_closure, fixes compile for - IRIX MIPSPro c99. - * include/ffi_common.h: Added '__sgi' define to non - '__attribute__((__mode__()))' integer typedefs. - * src/mips/ffi.c (ffi_call, ffi_closure_mips_inner_O32, - ffi_closure_mips_inner_N32): Added 'defined(_MIPSEB)' to BE check. - (ffi_closure_mips_inner_O32, ffi_closure_mips_inner_N32): Added - FFI_LONGDOUBLE support and alignment(N32 only). - * src/mips/ffitarget.h: Corrected '#include ' for IRIX and - fixed non '__attribute__((__mode__()))' integer typedefs. - * src/mips/n32.S: Put '#ifdef linux' around '.abicalls' and '.eh_frame' - since they are Linux/GNU Assembler specific. +commit 63ba1fa79f7c4ce42de848debe233aab31aecb51 +Author: Anthony Green +Date: Fri Feb 8 15:18:19 2013 -0500 -2009-12-25 Bradley Smith + Remove xfail for arm*-*-*. - * configure.ac, Makefile.am, src/avr32/ffi.c, - src/avr32/ffitarget.h, - src/avr32/sysv.S: Add AVR32 port. - * configure, Makefile.in: Rebuilt. +commit 24fbca4c1d57d4ea628c0a8ba643684daf54a37e +Author: Anthony Green +Date: Fri Feb 8 14:19:56 2013 -0500 -2009-12-21 Andreas Tobler + Fix typo - * configure.ac: Make i?86 build on FreeBSD and OpenBSD. - * configure: Regenerate. +commit b0fa11cb0a94ce6baca058eab9b10e40475e71d6 +Author: Anthony Green +Date: Fri Feb 8 14:17:13 2013 -0500 -2009-12-15 John David Anglin + More man page cleanup - * testsuite/libffi.call/ffitest.h: Define PRIuPTR on PA HP-UX. +commit 8bd15d139a58a6e46dc90a1cb2d89f59f32f06c7 +Author: Anthony Green +Date: Fri Feb 8 13:56:37 2013 -0500 -2009-12-13 John David Anglin + Fix many.c testcase for ppc - * src/pa/ffi.c (ffi_closure_inner_pa32): Handle FFI_TYPE_LONGDOUBLE - type on HP-UX. +commit 7aab825cf198be85490d3cd80e778d415d85ad9b +Author: Anthony Green +Date: Fri Feb 8 13:26:21 2013 -0500 -2012-02-13 Kai Tietz + Add missing files to dist - PR libffi/52221 - * src/x86/ffi.c (ffi_prep_raw_closure_loc): Add thiscall - support for X86_WIN32. - (FFI_INIT_TRAMPOLINE_THISCALL): Fix displacement. +commit cb03ea8f4eb08024e44abe4392edc77b89fbfbad +Author: Anthony Green +Date: Fri Feb 8 12:25:18 2013 -0500 -2009-12-11 Eric Botcazou + sparc v9 fixes for sun tools - * src/sparc/ffi.c (ffi_closure_sparc_inner_v9): Properly align 'long - double' arguments. +commit 35ee8d44f31dd3d3b88083c837dc351593e13cc2 +Author: Anthony Green +Date: Fri Feb 8 07:12:41 2013 -0500 -2009-12-11 Eric Botcazou + Fix microblaze big-endian struct issue - * testsuite/libffi.call/ffitest.h: Define PRIuPTR on Solaris < 10. +commit 9db7e1a958fc484ba149efe027008b9a170395fb +Author: Anthony Green +Date: Thu Feb 7 21:06:08 2013 -0500 -2009-12-10 Rainer Orth + Fix botched sparc patch. Update version. - PR libffi/40700 - * src/closures.c [X86_64 && __sun__ && __svr4__] - (FFI_MMAP_EXEC_WRIT): Define. +commit ce0138e61455f268af326e26908b9680ec2c4bea +Author: Anthony Green +Date: Thu Feb 7 18:04:01 2013 -0500 -2009-12-08 David Daney + Update bug report address. rc2. - * testsuite/libffi.call/stret_medium.c: Remove xfail for mips*-*-* - * testsuite/libffi.call/cls_align_longdouble_split2.c: Same. - * testsuite/libffi.call/stret_large.c: Same. - * testsuite/libffi.call/cls_align_longdouble_split.c: Same. - * testsuite/libffi.call/stret_large2.c: Same. - * testsuite/libffi.call/stret_medium2.c: Same. +commit fd07c9e40451e0ec1d0475cd54a83d45ccaea2c0 +Author: Anthony Green +Date: Thu Feb 7 18:00:36 2013 -0500 -2009-12-07 David Edelsohn + Add cache flushing routine for sun compiler on sparc solaris 2.8 - * src/powerpc/aix_closure.S (libffi_closure_ASM): Fix tablejump - typo. +commit ed6ae9501b2bab45daf93b4935eb0c977635b763 +Author: Anthony Green +Date: Thu Feb 7 16:43:36 2013 -0500 -2009-12-05 David Edelsohn + Add libtool-ldflags. Define toolexeclibdir for non-GCC builds. - * src/powerpc/aix.S: Update AIX32 code to be consistent with AIX64 - code. - * src/powerpc/aix_closure.S: Same. +commit ffef2e046aaec853be356f0b8770a335185ea9cf +Author: Anthony Green +Date: Thu Feb 7 15:47:01 2013 -0500 -2009-12-05 Ralf Wildenhues + x32 and libtool fixes - * Makefile.in: Regenerate. - * configure: Regenerate. - * include/Makefile.in: Regenerate. - * man/Makefile.in: Regenerate. - * testsuite/Makefile.in: Regenerate. +commit 95eecebb2858dc6f1495a61072ff36d0a8127144 +Author: Anthony Green +Date: Thu Feb 7 15:32:46 2013 -0500 -2009-12-04 David Edelsohn + Remove a.out cruft from dist - * src/powerpc/aix_closure.S: Reorganize 64-bit code to match - linux64_closure.S. +commit 176aa9d2e23d9cd57d6f250692d910b408f9a651 +Author: Anthony Green +Date: Thu Feb 7 15:29:22 2013 -0500 -2009-12-04 Uros Bizjak + Fix GCC usage test and update README - PR libffi/41908 - * src/x86/ffi64.c (classify_argument): Update from - gcc/config/i386/i386.c. - (ffi_closure_unix64_inner): Do not use the address of two consecutive - SSE registers directly. - * testsuite/libffi.call/cls_dbls_struct.c (main): Remove xfail - for x86_64 linux targets. +commit f3a4f3fdde89b04d66983a42a25d09161c5d4d54 +Author: Anthony Green +Date: Thu Feb 7 09:57:20 2013 -0500 -2009-12-04 David Edelsohn + Fixes for AIX xlc compiler. - * src/powerpc/ffi_darwin.c (ffi_closure_helper_DARWIN): Increment - pfr for long double split between fpr13 and stack. +commit 522f8fef49848927482bc63c94afaea5b84e5ec1 +Author: Anthony Green +Date: Wed Feb 6 20:31:31 2013 -0500 -2009-12-03 David Edelsohn + Fix man page. Clean out junk. - * src/powerpc/ffi_darwin.c (ffi_prep_args): Increment next_arg and - fparg_count twice for long double. +commit c4dfa259eb4e8e6f4c397868d7fee80aa0bb6a12 +Author: Anthony Green +Date: Wed Feb 6 17:43:24 2013 -0500 -2009-12-03 David Edelsohn + Bump soversion - PR libffi/42243 - * src/powerpc/ffi_darwin.c (ffi_prep_args): Remove extra parentheses. +commit f62bd63fe6123cadedb8b2b2c72eb549c40fbce9 +Author: Anthony Green +Date: Wed Feb 6 17:38:32 2013 -0500 -2009-12-03 Uros Bizjak + Release candidate 1 - * testsuite/libffi.call/cls_longdouble_va.c (main): Fix format string. - Remove xfails for x86 linux targets. +commit f7cd61e9e68a4a51147df04d75bfe5b91b9d9286 +Author: Anthony Green +Date: Wed Feb 6 17:38:04 2013 -0500 -2009-12-02 David Edelsohn + Fix pkgconfig install bits - * src/powerpc/ffi_darwin.c (ffi_prep_args): Fix typo in INT64 - case. +commit 6a790129427121f7db2d876e7218a3104e6d2741 +Author: Anthony Green +Date: Wed Feb 6 17:37:15 2013 -0500 -2009-12-01 David Edelsohn + Work around LLVM ABI problem on x86-64 - * src/powerpc/aix.S (ffi_call_AIX): Convert to more standard - register usage. Call ffi_prep_args directly. Add long double - return value support. - * src/powerpc/ffi_darwin.c (ffi_prep_args): Double arg increment - applies to FFI_TYPE_DOUBLE. Correct fpr_base increment typo. - Separate FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases. - (ffi_prep_cif_machdep): Only 16 byte stack alignment in 64 bit - mode. - (ffi_closure_helper_DARWIN): Remove nf and ng counters. Move temp - into case. - * src/powerpc/aix_closure.S: Maintain 16 byte stack alignment. - Allocate result area between params and FPRs. +commit 370112938e705128fd5dd4017fc1a1210bd0271a +Merge: bada2e3 bcc0c28 +Author: Anthony Green +Date: Sun Jan 27 05:09:04 2013 -0800 -2009-11-30 David Edelsohn + Merge pull request #28 from jralls/master + + Reorder x86_64 checks - PR target/35484 - * src/powerpc/ffitarget.h (POWERPC64): Define for PPC64 Linux and - AIX64. - * src/powerpc/aix.S: Implement AIX64 version. - * src/powerpc/aix_closure.S: Implement AIX64 version. - (ffi_closure_ASM): Use extsb, lha and displament addresses. - * src/powerpc/ffi_darwin.c (ffi_prep_args): Implement AIX64 - support. - (ffi_prep_cif_machdep): Same. - (ffi_call): Same. - (ffi_closure_helper_DARWIN): Same. +commit bcc0c28001b6d427d5cd8037d2e3c892babc6b4c +Author: John Ralls +Date: Sat Jan 26 15:21:14 2013 -0800 -2009-11-02 Andreas Tobler + Reorder x86_64 tests + + So that darwin and cygwin/mingw are tested before the generic check -- + which allows them to actually be set. - PR libffi/41908 - * testsuite/libffi.call/testclosure.c: New test. +commit bada2e326d9a9acf3ae40cfa4f5d7a9ba97b2ea8 +Author: Anthony Green +Date: Mon Jan 21 08:02:07 2013 -0500 -2009-09-28 Kai Tietz + Update README - * src/x86/win64.S (_ffi_call_win64 stack): Remove for gnu - assembly version use of ___chkstk. +commit 655bb8f3690feba8e840a5f1854b1d78ed08f692 +Merge: 1035ffb 840f975 +Author: Anthony Green +Date: Mon Jan 21 08:01:24 2013 -0500 -2009-09-23 Matthias Klose + Merge branch 'master' of github.com:/atgreen/libffi - PR libffi/40242, PR libffi/41443 - * src/arm/sysv.S (__ARM_ARCH__): Define for processors - __ARM_ARCH_6T2__, __ARM_ARCH_6M__, __ARM_ARCH_7__, - __ARM_ARCH_7A__, __ARM_ARCH_7R__, __ARM_ARCH_7M__. - Change the conditionals to __SOFTFP__ || __ARM_EABI__ - for -mfloat-abi=softfp to work. +commit 1035ffb2f468e1a1c401d58cff7e7abb69838e68 +Merge: aeb8719 4086024 +Author: Anthony Green +Date: Mon Jan 21 07:55:53 2013 -0500 -2009-09-17 Loren J. Rittle + Update README - PR testsuite/32843 (strikes again) - * src/x86/ffi.c (ffi_prep_cif_machdep): Add X86_FREEBSD to - enable proper extension on char and short. +commit 840f975866052fdd91b2c224d56e01ae5900b60d +Merge: aeb8719 4086024 +Author: Anthony Green +Date: Mon Jan 21 07:55:53 2013 -0500 -2009-09-15 David Daney + Merge branch 'master' of github.com:/atgreen/libffi - * src/java_raw_api.c (ffi_java_raw_to_rvalue): Remove special - handling for FFI_TYPE_POINTER. - * src/mips/ffitarget.h (FFI_TYPE_STRUCT_D_SOFT, - FFI_TYPE_STRUCT_F_SOFT, FFI_TYPE_STRUCT_DD_SOFT, - FFI_TYPE_STRUCT_FF_SOFT, FFI_TYPE_STRUCT_FD_SOFT, - FFI_TYPE_STRUCT_DF_SOFT, FFI_TYPE_STRUCT_SOFT): New defines. - (FFI_N32_SOFT_FLOAT, FFI_N64_SOFT_FLOAT): New ffi_abi enumerations. - (enum ffi_abi): Set FFI_DEFAULT_ABI for soft-float. - * src/mips/n32.S (ffi_call_N32): Add handling for soft-float - structure and pointer returns. - (ffi_closure_N32): Add handling for pointer returns. - * src/mips/ffi.c (ffi_prep_args, calc_n32_struct_flags, - calc_n32_return_struct_flags): Handle soft-float. - (ffi_prep_cif_machdep): Handle soft-float, fix pointer handling. - (ffi_call_N32): Declare proper argument types. - (ffi_call, copy_struct_N32, ffi_closure_mips_inner_N32): Handle - soft-float. +commit aeb8719a34756969970603fca4568530d56708af +Author: Anthony Green +Date: Mon Jan 21 07:37:30 2013 -0500 -2009-08-24 Ralf Wildenhues + New microblaze support - * configure.ac (AC_PREREQ): Bump to 2.64. +commit 40860245a4fd91a1b88adc9171ec993c549e45d5 +Author: Anthony Green +Date: Mon Jan 21 07:37:30 2013 -0500 -2009-08-22 Ralf Wildenhues + New microblaze support - * Makefile.am (install-html, install-pdf): Remove. - * Makefile.in: Regenerate. +commit 20cae32b152b43679ae65a85db9a1c6bb8a143dd +Author: Anthony Green +Date: Mon Jan 21 07:07:38 2013 -0500 - * Makefile.in: Regenerate. - * aclocal.m4: Regenerate. - * configure: Regenerate. - * fficonfig.h.in: Regenerate. - * include/Makefile.in: Regenerate. - * man/Makefile.in: Regenerate. - * testsuite/Makefile.in: Regenerate. + Xtensa support -2011-08-22 Jasper Lievisse Adriaanse +commit 9742f91782faef4a15941508a22c408fb7d1d227 +Author: Anthony Green +Date: Mon Jan 21 07:03:41 2013 -0500 - * configure.ac: Add OpenBSD/hppa and OpenBSD/powerpc support. - * configure: Rebuilt. + Mention IBM XL compiler support on AIX. -2009-07-30 Ralf Wildenhues +commit f03eab08248f122ce3b623a18df9e19fae1b6e98 +Author: Anthony Green +Date: Fri Jan 11 17:14:11 2013 -0500 - * configure.ac (_AC_ARG_VAR_PRECIOUS): Use m4_rename_force. + Remove obsolete inline test functions -2009-07-24 Dave Korn - - PR libffi/40807 - * src/x86/ffi.c (ffi_prep_cif_machdep): Also use sign/zero-extending - return types for X86_WIN32. - * src/x86/win32.S (_ffi_call_SYSV): Handle omitted return types. - (_ffi_call_STDCALL, _ffi_closure_SYSV, _ffi_closure_raw_SYSV, - _ffi_closure_STDCALL): Likewise. - - * src/closures.c (is_selinux_enabled): Define to const 0 for Cygwin. - (dlmmap, dlmunmap): Also use these functions on Cygwin. - -2009-07-11 Richard Sandiford - - PR testsuite/40699 - PR testsuite/40707 - PR testsuite/40709 - * testsuite/lib/libffi-dg.exp: Revert 2009-07-02, 2009-07-01 and - 2009-06-30 commits. - -2009-07-01 Richard Sandiford - - * testsuite/lib/libffi-dg.exp (libffi-init): Set ld_library_path - to "" before adding paths. (This reinstates an assignment that - was removed by my 2009-06-30 commit, but changes the initial - value from "." to "".) - -2009-07-01 H.J. Lu - - PR testsuite/40601 - * testsuite/lib/libffi-dg.exp (libffi-init): Properly set - gccdir. Adjust ld_library_path for gcc only if gccdir isn't - empty. - -2009-06-30 Richard Sandiford - - * testsuite/lib/libffi-dg.exp (libffi-init): Don't add "." - to ld_library_path. Use add_path. Add just find_libgcc_s - to ld_library_path, not every libgcc multilib directory. - -2009-06-16 Wim Lewis - - * src/powerpc/ffi.c: Avoid clobbering cr3 and cr4, which are - supposed to be callee-saved. - * src/powerpc/sysv.S (small_struct_return_value): Fix overrun of - return buffer for odd-size structs. - -2009-06-16 Andreas Tobler - - PR libffi/40444 - * testsuite/lib/libffi-dg.exp (libffi_target_compile): Add - allow_stack_execute for Darwin. - -2009-06-16 Andrew Haley - - * configure.ac (TARGETDIR): Add missing blank lines. - * configure: Regenerate. - -2009-06-16 Andrew Haley - - * testsuite/libffi.call/cls_align_sint64.c, - testsuite/libffi.call/cls_align_uint64.c, - testsuite/libffi.call/cls_longdouble_va.c, - testsuite/libffi.call/cls_ulonglong.c, - testsuite/libffi.call/return_ll1.c, - testsuite/libffi.call/stret_medium2.c: Fix printf format - specifiers. - * testsuite/libffi.call/ffitest.h, - testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRIuLL): Define. - -2009-06-15 Andrew Haley - - * testsuite/libffi.call/err_bad_typedef.c: xfail everywhere. - * testsuite/libffi.call/err_bad_abi.c: Likewise. - -2009-06-12 Andrew Haley - - * Makefile.am: Remove info_TEXINFOS. - -2009-06-12 Andrew Haley - - * ChangeLog.libffi: testsuite/libffi.call/cls_align_sint64.c, - testsuite/libffi.call/cls_align_uint64.c, - testsuite/libffi.call/cls_ulonglong.c, - testsuite/libffi.call/return_ll1.c, - testsuite/libffi.call/stret_medium2.c: Fix printf format - specifiers. - testsuite/libffi.special/unwindtest.cc: include stdint.h. - -2009-06-11 Timothy Wall - - * Makefile.am, - configure.ac, - include/ffi.h.in, - include/ffi_common.h, - src/closures.c, - src/dlmalloc.c, - src/x86/ffi.c, - src/x86/ffitarget.h, - src/x86/win64.S (new), - README: Added win64 support (mingw or MSVC) - * Makefile.in, - include/Makefile.in, - man/Makefile.in, - testsuite/Makefile.in, - configure, - aclocal.m4: Regenerated - * ltcf-c.sh: properly escape cygwin/w32 path - * man/ffi_call.3: Clarify size requirements for return value. - * src/x86/ffi64.c: Fix filename in comment. - * src/x86/win32.S: Remove unused extern. - - * testsuite/libffi.call/closure_fn0.c, - testsuite/libffi.call/closure_fn1.c, - testsuite/libffi.call/closure_fn2.c, - testsuite/libffi.call/closure_fn3.c, - testsuite/libffi.call/closure_fn4.c, - testsuite/libffi.call/closure_fn5.c, - testsuite/libffi.call/closure_fn6.c, - testsuite/libffi.call/closure_stdcall.c, - testsuite/libffi.call/cls_12byte.c, - testsuite/libffi.call/cls_16byte.c, - testsuite/libffi.call/cls_18byte.c, - testsuite/libffi.call/cls_19byte.c, - testsuite/libffi.call/cls_1_1byte.c, - testsuite/libffi.call/cls_20byte.c, - testsuite/libffi.call/cls_20byte1.c, - testsuite/libffi.call/cls_24byte.c, - testsuite/libffi.call/cls_2byte.c, - testsuite/libffi.call/cls_3_1byte.c, - testsuite/libffi.call/cls_3byte1.c, - testsuite/libffi.call/cls_3byte2.c, - testsuite/libffi.call/cls_4_1byte.c, - testsuite/libffi.call/cls_4byte.c, - testsuite/libffi.call/cls_5_1_byte.c, - testsuite/libffi.call/cls_5byte.c, - testsuite/libffi.call/cls_64byte.c, - testsuite/libffi.call/cls_6_1_byte.c, - testsuite/libffi.call/cls_6byte.c, - testsuite/libffi.call/cls_7_1_byte.c, - testsuite/libffi.call/cls_7byte.c, - testsuite/libffi.call/cls_8byte.c, - testsuite/libffi.call/cls_9byte1.c, - testsuite/libffi.call/cls_9byte2.c, - testsuite/libffi.call/cls_align_double.c, - testsuite/libffi.call/cls_align_float.c, - testsuite/libffi.call/cls_align_longdouble.c, - testsuite/libffi.call/cls_align_longdouble_split.c, - testsuite/libffi.call/cls_align_longdouble_split2.c, - testsuite/libffi.call/cls_align_pointer.c, - testsuite/libffi.call/cls_align_sint16.c, - testsuite/libffi.call/cls_align_sint32.c, - testsuite/libffi.call/cls_align_sint64.c, - testsuite/libffi.call/cls_align_uint16.c, - testsuite/libffi.call/cls_align_uint32.c, - testsuite/libffi.call/cls_align_uint64.c, - testsuite/libffi.call/cls_dbls_struct.c, - testsuite/libffi.call/cls_double.c, - testsuite/libffi.call/cls_double_va.c, - testsuite/libffi.call/cls_float.c, - testsuite/libffi.call/cls_longdouble.c, - testsuite/libffi.call/cls_longdouble_va.c, - testsuite/libffi.call/cls_multi_schar.c, - testsuite/libffi.call/cls_multi_sshort.c, - testsuite/libffi.call/cls_multi_sshortchar.c, - testsuite/libffi.call/cls_multi_uchar.c, - testsuite/libffi.call/cls_multi_ushort.c, - testsuite/libffi.call/cls_multi_ushortchar.c, - testsuite/libffi.call/cls_pointer.c, - testsuite/libffi.call/cls_pointer_stack.c, - testsuite/libffi.call/cls_schar.c, - testsuite/libffi.call/cls_sint.c, - testsuite/libffi.call/cls_sshort.c, - testsuite/libffi.call/cls_uchar.c, - testsuite/libffi.call/cls_uint.c, - testsuite/libffi.call/cls_ulonglong.c, - testsuite/libffi.call/cls_ushort.c, - testsuite/libffi.call/err_bad_abi.c, - testsuite/libffi.call/err_bad_typedef.c, - testsuite/libffi.call/float2.c, - testsuite/libffi.call/huge_struct.c, - testsuite/libffi.call/nested_struct.c, - testsuite/libffi.call/nested_struct1.c, - testsuite/libffi.call/nested_struct10.c, - testsuite/libffi.call/nested_struct2.c, - testsuite/libffi.call/nested_struct3.c, - testsuite/libffi.call/nested_struct4.c, - testsuite/libffi.call/nested_struct5.c, - testsuite/libffi.call/nested_struct6.c, - testsuite/libffi.call/nested_struct7.c, - testsuite/libffi.call/nested_struct8.c, - testsuite/libffi.call/nested_struct9.c, - testsuite/libffi.call/problem1.c, - testsuite/libffi.call/return_ldl.c, - testsuite/libffi.call/return_ll1.c, - testsuite/libffi.call/stret_large.c, - testsuite/libffi.call/stret_large2.c, - testsuite/libffi.call/stret_medium.c, - testsuite/libffi.call/stret_medium2.c, - testsuite/libffi.special/unwindtest.cc: use ffi_closure_alloc instead - of checking for MMAP. Use intptr_t instead of long casts. - -2009-06-11 Kaz Kojima - - * testsuite/libffi.call/cls_longdouble_va.c: Add xfail sh*-*-linux-*. - * testsuite/libffi.call/err_bad_abi.c: Add xfail sh*-*-*. - * testsuite/libffi.call/err_bad_typedef.c: Likewise. - -2009-06-09 Andrew Haley - - * src/x86/freebsd.S: Add missing file. - -2009-06-08 Andrew Haley - - Import from libffi 3.0.8: - - * doc/libffi.texi: New file. - * doc/libffi.info: Likewise. - * doc/stamp-vti: Likewise. - * man/Makefile.am: New file. - * man/ffi_call.3: New file. - - * Makefile.am (EXTRA_DIST): Add src/x86/darwin64.S, - src/dlmalloc.c. - (nodist_libffi_la_SOURCES): Add X86_FREEBSD. - - * configure.ac: Bump version to 3.0.8. - parisc*-*-linux*: Add. - i386-*-freebsd* | i386-*-openbsd*: Add. - powerpc-*-beos*: Add. - AM_CONDITIONAL X86_FREEBSD: Add. - AC_CONFIG_FILES: Add man/Makefile. - - * include/ffi.h.in (FFI_FN): Change void (*)() to void (*)(void). - -2009-06-08 Andrew Haley - - * README: Import from libffi 3.0.8. - -2009-06-08 Andrew Haley - - * testsuite/libffi.call/err_bad_abi.c: Add xfails. - * testsuite/libffi.call/cls_longdouble_va.c: Add xfails. - * testsuite/libffi.call/cls_dbls_struct.c: Add xfail x86_64-*-linux-*. - * testsuite/libffi.call/err_bad_typedef.c: Add xfails. - - * testsuite/libffi.call/stret_medium2.c: Add __UNUSED__ to args. - * testsuite/libffi.call/stret_medium.c: Likewise. - * testsuite/libffi.call/stret_large2.c: Likewise. - * testsuite/libffi.call/stret_large.c: Likewise. - -2008-12-26 Timothy Wall - - * testsuite/libffi.call/cls_longdouble.c, - testsuite/libffi.call/cls_longdouble_va.c, - testsuite/libffi.call/cls_align_longdouble.c, - testsuite/libffi.call/cls_align_longdouble_split.c, - testsuite/libffi.call/cls_align_longdouble_split2.c: mark expected - failures on x86_64 cygwin/mingw. - -2008-12-22 Timothy Wall - - * testsuite/libffi.call/closure_fn0.c, - testsuite/libffi.call/closure_fn1.c, - testsuite/libffi.call/closure_fn2.c, - testsuite/libffi.call/closure_fn3.c, - testsuite/libffi.call/closure_fn4.c, - testsuite/libffi.call/closure_fn5.c, - testsuite/libffi.call/closure_fn6.c, - testsuite/libffi.call/closure_loc_fn0.c, - testsuite/libffi.call/closure_stdcall.c, - testsuite/libffi.call/cls_align_pointer.c, - testsuite/libffi.call/cls_pointer.c, - testsuite/libffi.call/cls_pointer_stack.c: use portable cast from - pointer to integer (intptr_t). - * testsuite/libffi.call/cls_longdouble.c: disable for win64. - -2008-07-24 Anthony Green - - * testsuite/libffi.call/cls_dbls_struct.c, - testsuite/libffi.call/cls_double_va.c, - testsuite/libffi.call/cls_longdouble.c, - testsuite/libffi.call/cls_longdouble_va.c, - testsuite/libffi.call/cls_pointer.c, - testsuite/libffi.call/cls_pointer_stack.c, - testsuite/libffi.call/err_bad_abi.c: Clean up failures from - compiler warnings. - -2008-03-04 Anthony Green - Blake Chaffin - hos@tamanegi.org - - * testsuite/libffi.call/cls_align_longdouble_split2.c - testsuite/libffi.call/cls_align_longdouble_split.c - testsuite/libffi.call/cls_dbls_struct.c - testsuite/libffi.call/cls_double_va.c - testsuite/libffi.call/cls_longdouble.c - testsuite/libffi.call/cls_longdouble_va.c - testsuite/libffi.call/cls_pointer.c - testsuite/libffi.call/cls_pointer_stack.c - testsuite/libffi.call/err_bad_abi.c - testsuite/libffi.call/err_bad_typedef.c - testsuite/libffi.call/stret_large2.c - testsuite/libffi.call/stret_large.c - testsuite/libffi.call/stret_medium2.c - testsuite/libffi.call/stret_medium.c: New tests from Apple. - -2009-06-05 Andrew Haley - - * src/x86/ffitarget.h, src/x86/ffi.c: Merge stdcall changes from - libffi. - -2009-06-04 Andrew Haley - - * src/x86/ffitarget.h, src/x86/win32.S, src/x86/ffi.c: Back out - stdcall changes. - -2008-02-26 Anthony Green - Thomas Heller - - * src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C - comment. - -2008-02-03 Timothy Wall - - * src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL): Calculate jump return - offset based on code pointer, not data pointer. - -2008-01-31 Timothy Wall - - * testsuite/libffi.call/closure_stdcall.c: Add test for stdcall - closures. - * src/x86/ffitarget.h: Increase size of trampoline for stdcall - closures. - * src/x86/win32.S: Add assembly for stdcall closure. - * src/x86/ffi.c: Initialize stdcall closure trampoline. - -2009-06-04 Andrew Haley - - * include/ffi.h.in: Change void (*)() to void (*)(void). - * src/x86/ffi.c: Likewise. - -2009-06-04 Andrew Haley - - * src/powerpc/ppc_closure.S: Insert licence header. - * src/powerpc/linux64_closure.S: Likewise. - * src/m68k/sysv.S: Likewise. - - * src/sh64/ffi.c: Change void (*)() to void (*)(void). - * src/powerpc/ffi.c: Likewise. - * src/powerpc/ffi_darwin.c: Likewise. - * src/m32r/ffi.c: Likewise. - * src/sh64/ffi.c: Likewise. - * src/x86/ffi64.c: Likewise. - * src/alpha/ffi.c: Likewise. - * src/alpha/osf.S: Likewise. - * src/frv/ffi.c: Likewise. - * src/s390/ffi.c: Likewise. - * src/pa/ffi.c: Likewise. - * src/pa/hpux32.S: Likewise. - * src/ia64/unix.S: Likewise. - * src/ia64/ffi.c: Likewise. - * src/sparc/ffi.c: Likewise. - * src/mips/ffi.c: Likewise. - * src/sh/ffi.c: Likewise. - -2008-02-15 David Daney - - * src/mips/ffi.c (USE__BUILTIN___CLEAR_CACHE): - Define (conditionally), and use it to include cachectl.h. - (ffi_prep_closure_loc): Fix cache flushing. - * src/mips/ffitarget.h (_ABIN32, _ABI64, _ABIO32): Define. - -2009-06-04 Andrew Haley - - include/ffi.h.in, - src/arm/ffitarget.h, - src/arm/ffi.c, - src/arm/sysv.S, - src/powerpc/ffitarget.h, - src/closures.c, - src/sh64/ffitarget.h, - src/sh64/ffi.c, - src/sh64/sysv.S, - src/types.c, - src/x86/ffi64.c, - src/x86/ffitarget.h, - src/x86/win32.S, - src/x86/darwin.S, - src/x86/ffi.c, - src/x86/sysv.S, - src/x86/unix64.S, - src/alpha/ffitarget.h, - src/alpha/ffi.c, - src/alpha/osf.S, - src/m68k/ffitarget.h, - src/frv/ffitarget.h, - src/frv/ffi.c, - src/s390/ffitarget.h, - src/s390/sysv.S, - src/cris/ffitarget.h, - src/pa/linux.S, - src/pa/ffitarget.h, - src/pa/ffi.c, - src/raw_api.c, - src/ia64/ffitarget.h, - src/ia64/unix.S, - src/ia64/ffi.c, - src/ia64/ia64_flags.h, - src/java_raw_api.c, - src/debug.c, - src/sparc/v9.S, - src/sparc/ffitarget.h, - src/sparc/ffi.c, - src/sparc/v8.S, - src/mips/ffitarget.h, - src/mips/n32.S, - src/mips/o32.S, - src/mips/ffi.c, - src/prep_cif.c, - src/sh/ffitarget.h, - src/sh/ffi.c, - src/sh/sysv.S: Update license text. - -2009-05-22 Dave Korn - - * src/x86/win32.S (_ffi_closure_STDCALL): New function. - (.eh_frame): Add FDE for it. - -2009-05-22 Dave Korn - - * configure.ac: Also check if assembler supports pc-relative - relocs on X86_WIN32 targets. - * configure: Regenerate. - * src/x86/win32.S (ffi_prep_args): Declare extern, not global. - (_ffi_call_SYSV): Add missing function type symbol .def and - add EH markup labels. - (_ffi_call_STDCALL): Likewise. - (_ffi_closure_SYSV): Likewise. - (_ffi_closure_raw_SYSV): Likewise. - (.eh_frame): Add hand-crafted EH data. - -2009-04-09 Jakub Jelinek - - * testsuite/lib/libffi-dg.exp: Change copyright header to refer to - version 3 of the GNU General Public License and to point readers - at the COPYING3 file and the FSF's license web page. - * testsuite/libffi.call/call.exp: Likewise. - * testsuite/libffi.special/special.exp: Likewise. - -2009-03-01 Ralf Wildenhues - - * configure: Regenerate. - -2008-12-18 Rainer Orth - - PR libffi/26048 - * configure.ac (HAVE_AS_X86_PCREL): New test. - * configure: Regenerate. - * fficonfig.h.in: Regenerate. - * src/x86/sysv.S [!FFI_NO_RAW_API]: Precalculate - RAW_CLOSURE_CIF_OFFSET, RAW_CLOSURE_FUN_OFFSET, - RAW_CLOSURE_USER_DATA_OFFSET for the Solaris 10/x86 assembler. - (.eh_frame): Only use SYMBOL-. iff HAVE_AS_X86_PCREL. - * src/x86/unix64.S (.Lstore_table): Move to .text section. - (.Lload_table): Likewise. - (.eh_frame): Only use SYMBOL-. iff HAVE_AS_X86_PCREL. - -2008-12-18 Ralf Wildenhues - - * configure: Regenerate. - -2008-11-21 Eric Botcazou - - * src/sparc/ffi.c (ffi_prep_cif_machdep): Add support for - signed/unsigned int8/16 return values. - * src/sparc/v8.S (ffi_call_v8): Likewise. - (ffi_closure_v8): Likewise. - -2008-09-26 Peter O'Gorman - Steve Ellcey - - * configure: Regenerate for new libtool. - * Makefile.in: Ditto. - * include/Makefile.in: Ditto. - * aclocal.m4: Ditto. - -2008-08-25 Andreas Tobler - - * src/powerpc/ffitarget.h (ffi_abi): Add FFI_LINUX and - FFI_LINUX_SOFT_FLOAT to the POWERPC_FREEBSD enum. - Add note about flag bits used for FFI_SYSV_TYPE_SMALL_STRUCT. - Adjust copyright notice. - * src/powerpc/ffi.c: Add two new flags to indicate if we have one - register or two register to use for FFI_SYSV structs. - (ffi_prep_cif_machdep): Pass the right register flag introduced above. - (ffi_closure_helper_SYSV): Fix the return type for - FFI_SYSV_TYPE_SMALL_STRUCT. Comment. - Adjust copyright notice. - -2008-07-16 Kaz Kojima - - * src/sh/ffi.c (ffi_prep_closure_loc): Turn INSN into an unsigned - int. +commit 05fbe1faedc7b2580d5f14010d00e9e3cee73951 +Author: Anthony Green +Date: Fri Jan 11 16:54:40 2013 -0500 -2008-06-17 Ralf Wildenhues + xlc compiler support - * configure: Regenerate. - * include/Makefile.in: Regenerate. - * testsuite/Makefile.in: Regenerate. +commit 0b4986a7889ed1864674192228f1162c1b5770a8 +Author: Anthony Green +Date: Fri Jan 11 11:19:52 2013 -0500 -2008-06-07 Joseph Myers + [travis] install dejagnu with sudo - * configure.ac (parisc*-*-linux*, powerpc-*-sysv*, - powerpc-*-beos*): Remove. - * configure: Regenerate. +commit 3c337eef51ab9a4993fc875bfa26289dd6a08881 +Author: Anthony Green +Date: Fri Jan 11 11:18:14 2013 -0500 -2008-05-09 Julian Brown + [travis] install dejagnu - * Makefile.am (LTLDFLAGS): New. - (libffi_la_LDFLAGS): Use above. - * Makefile.in: Regenerate. +commit 90720962ce1baf9fc35d1bde1738102bcd5bd5ed +Author: Anthony Green +Date: Fri Jan 11 10:57:30 2013 -0500 -2008-04-18 Paolo Bonzini + Add first travis config file - PR bootstrap/35457 - * aclocal.m4: Regenerate. - * configure: Regenerate. +commit bff052d9cd5be41ba9e47c76114054af487d3c30 +Author: Anthony Green +Date: Fri Jan 11 10:24:32 2013 -0500 -2008-03-26 Kaz Kojima + 32-bit x86 fix and more - * src/sh/sysv.S: Add .note.GNU-stack on Linux. - * src/sh64/sysv.S: Likewise. - -2008-03-26 Daniel Jacobowitz +commit cd41aeab6176f839167955c016ecc19f65f75df3 +Author: Anthony Green +Date: Thu Jan 10 17:25:45 2013 -0500 - * src/arm/sysv.S: Fix ARM comment marker. + Add compiler column to table -2008-03-26 Jakub Jelinek +commit 8bf987d4df7c4d21435b9211f6cc86abf5904b42 +Author: Anthony Green +Date: Thu Jan 10 17:24:51 2013 -0500 - * src/alpha/osf.S: Add .note.GNU-stack on Linux. - * src/s390/sysv.S: Likewise. - * src/powerpc/ppc_closure.S: Likewise. - * src/powerpc/sysv.S: Likewise. - * src/x86/unix64.S: Likewise. - * src/x86/sysv.S: Likewise. - * src/sparc/v8.S: Likewise. - * src/sparc/v9.S: Likewise. - * src/m68k/sysv.S: Likewise. - * src/arm/sysv.S: Likewise. + Fix for sunpro compiler on Solaris -2008-03-16 Ralf Wildenhues - - * aclocal.m4: Regenerate. - * configure: Likewise. - * Makefile.in: Likewise. - * include/Makefile.in: Likewise. - * testsuite/Makefile.in: Likewise. - -2008-02-12 Bjoern Koenig - Andreas Tobler - - * configure.ac: Add amd64-*-freebsd* target. - * configure: Regenerate. - -2008-01-30 H.J. Lu +commit 3ee74fd6dc8ccd32b608bbff73526838fc34f70b +Author: Anthony Green +Date: Thu Jan 10 17:15:03 2013 -0500 - PR libffi/34612 - * src/x86/sysv.S (ffi_closure_SYSV): Pop 4 byte from stack when - returning struct. - - * testsuite/libffi.call/call.exp: Add "-O2 -fomit-frame-pointer" - tests. - -2008-01-24 David Edelsohn - - * configure: Regenerate. - -2008-01-06 Andreas Tobler - - * src/x86/ffi.c (ffi_prep_cif_machdep): Fix thinko. - -2008-01-05 Andreas Tobler - - PR testsuite/32843 - * src/x86/ffi.c (ffi_prep_cif_machdep): Add code for - signed/unsigned int8/16 for X86_DARWIN. - Updated copyright info. - Handle one and two byte structs with special cif->flags. - * src/x86/ffitarget.h: Add special types for one and two byte structs. - Updated copyright info. - * src/x86/darwin.S (ffi_call_SYSV): Rewrite to use a jump table like - sysv.S - Remove code to pop args from the stack after call. - Special-case signed/unsigned for int8/16, one and two byte structs. - (ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8, - FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32, - FFI_TYPE_SINT32. - Updated copyright info. + Update documentation version. -2007-12-08 David Daney +commit 13e2d7b92557a9511a0414df82bf2df3edc55cba +Author: Anthony Green +Date: Thu Jan 10 10:52:02 2013 -0500 - * src/mips/n32.S (ffi_call_N32): Replace dadd with ADDU, dsub with - SUBU, add with ADDU and use smaller code sequences. + Handle both 32 and 64-bit x86 builds regardless of target triple -2007-12-07 David Daney - - * src/mips/ffi.c (ffi_prep_cif_machdep): Handle long double return - type. +commit 5141543000fc86a3d49a907a2313713ee79e504d +Author: Anthony Green +Date: Thu Jan 10 07:35:53 2013 -0500 -2007-12-06 David Daney + Don't run EH tests with non-GNU compiler - * include/ffi.h.in (FFI_SIZEOF_JAVA_RAW): Define if not already - defined. - (ffi_java_raw): New typedef. - (ffi_java_raw_call, ffi_java_ptrarray_to_raw, - ffi_java_raw_to_ptrarray): Change parameter types from ffi_raw to - ffi_java_raw. - (ffi_java_raw_closure) : Same. - (ffi_prep_java_raw_closure, ffi_prep_java_raw_closure_loc): Change - parameter types. - * src/java_raw_api.c (ffi_java_raw_size): Replace FFI_SIZEOF_ARG with - FFI_SIZEOF_JAVA_RAW. - (ffi_java_raw_to_ptrarray): Change type of raw to ffi_java_raw. - Replace FFI_SIZEOF_ARG with FFI_SIZEOF_JAVA_RAW. Use - sizeof(ffi_java_raw) for alignment calculations. - (ffi_java_ptrarray_to_raw): Same. - (ffi_java_rvalue_to_raw): Add special handling for FFI_TYPE_POINTER - if FFI_SIZEOF_JAVA_RAW == 4. - (ffi_java_raw_to_rvalue): Same. - (ffi_java_raw_call): Change type of raw to ffi_java_raw. - (ffi_java_translate_args): Same. - (ffi_prep_java_raw_closure_loc, ffi_prep_java_raw_closure): Change - parameter types. - * src/mips/ffitarget.h (FFI_SIZEOF_JAVA_RAW): Define for N32 ABI. - -2007-12-06 David Daney - - * src/mips/n32.S (ffi_closure_N32): Use 64-bit add instruction on - pointer values. - -2007-12-01 Andreas Tobler - - PR libffi/31937 - * src/powerpc/ffitarget.h: Introduce new ABI FFI_LINUX_SOFT_FLOAT. - Add local FFI_TYPE_UINT128 to handle soft-float long-double-128. - * src/powerpc/ffi.c: Distinguish between __NO_FPRS__ and not and - set the NUM_FPR_ARG_REGISTERS according to. - Add support for potential soft-float support under hard-float - architecture. - (ffi_prep_args_SYSV): Set NUM_FPR_ARG_REGISTERS to 0 in case of - FFI_LINUX_SOFT_FLOAT, handle float, doubles and long-doubles according - to the FFI_LINUX_SOFT_FLOAT ABI. - (ffi_prep_cif_machdep): Likewise. - (ffi_closure_helper_SYSV): Likewise. - * src/powerpc/ppc_closure.S: Make sure not to store float/double - on archs where __NO_FPRS__ is true. - Add FFI_TYPE_UINT128 support. - * src/powerpc/sysv.S: Add support for soft-float long-double-128. - Adjust copyright notice. - -2007-11-25 Andreas Tobler - - * src/closures.c: Move defintion of MAYBE_UNUSED from here to ... - * include/ffi_common.h: ... here. - Update copyright. - -2007-11-17 Andreas Tobler - - * src/powerpc/sysv.S: Load correct cr to compare if we have long double. - * src/powerpc/linux64.S: Likewise. - * src/powerpc/ffi.c: Add a comment to show which part goes into cr6. - * testsuite/libffi.call/return_ldl.c: New test. - -2007-09-04 - - * src/arm/sysv.S (UNWIND): New. - (Whole file): Conditionally compile unwinder directives. - * src/arm/sysv.S: Add unwinder directives. - - * src/arm/ffi.c (ffi_prep_args): Align structs by at least 4 bytes. - Only treat r0 as a struct address if we're actually returning a - struct by address. - Only copy the bytes that are actually within a struct. - (ffi_prep_cif_machdep): A Composite Type not larger than 4 bytes - is returned in r0, not passed by address. - (ffi_call): Allocate a word-sized temporary for the case where - a composite is returned in r0. - (ffi_prep_incoming_args_SYSV): Align as necessary. - -2007-08-05 Steven Newbury - - * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Use __clear_cache instead of - directly using the sys_cacheflush syscall. - -2007-07-27 Andrew Haley - - * src/arm/sysv.S (ffi_closure_SYSV): Add soft-float. - -2007-09-03 Maciej W. Rozycki - - * Makefile.am: Unify MIPS_IRIX and MIPS_LINUX into MIPS. - * configure.ac: Likewise. - * Makefile.in: Regenerate. - * include/Makefile.in: Likewise. - * testsuite/Makefile.in: Likewise. - * configure: Likewise. - -2007-08-24 David Daney - - * testsuite/libffi.call/return_sl.c: New test. - -2007-08-10 David Daney - - * testsuite/libffi.call/cls_multi_ushort.c, - testsuite/libffi.call/cls_align_uint16.c, - testsuite/libffi.call/nested_struct1.c, - testsuite/libffi.call/nested_struct3.c, - testsuite/libffi.call/cls_7_1_byte.c, - testsuite/libffi.call/nested_struct5.c, - testsuite/libffi.call/cls_double.c, - testsuite/libffi.call/nested_struct7.c, - testsuite/libffi.call/cls_sint.c, - testsuite/libffi.call/nested_struct9.c, - testsuite/libffi.call/cls_20byte1.c, - testsuite/libffi.call/cls_multi_sshortchar.c, - testsuite/libffi.call/cls_align_sint64.c, - testsuite/libffi.call/cls_3byte2.c, - testsuite/libffi.call/cls_multi_schar.c, - testsuite/libffi.call/cls_multi_uchar.c, - testsuite/libffi.call/cls_19byte.c, - testsuite/libffi.call/cls_9byte1.c, - testsuite/libffi.call/cls_align_float.c, - testsuite/libffi.call/closure_fn1.c, - testsuite/libffi.call/problem1.c, - testsuite/libffi.call/closure_fn3.c, - testsuite/libffi.call/cls_sshort.c, - testsuite/libffi.call/closure_fn5.c, - testsuite/libffi.call/cls_align_double.c, - testsuite/libffi.call/nested_struct.c, - testsuite/libffi.call/cls_2byte.c, - testsuite/libffi.call/nested_struct10.c, - testsuite/libffi.call/cls_4byte.c, - testsuite/libffi.call/cls_6byte.c, - testsuite/libffi.call/cls_8byte.c, - testsuite/libffi.call/cls_multi_sshort.c, - testsuite/libffi.call/cls_align_sint16.c, - testsuite/libffi.call/cls_align_uint32.c, - testsuite/libffi.call/cls_20byte.c, - testsuite/libffi.call/cls_float.c, - testsuite/libffi.call/nested_struct2.c, - testsuite/libffi.call/cls_5_1_byte.c, - testsuite/libffi.call/nested_struct4.c, - testsuite/libffi.call/cls_24byte.c, - testsuite/libffi.call/nested_struct6.c, - testsuite/libffi.call/cls_64byte.c, - testsuite/libffi.call/nested_struct8.c, - testsuite/libffi.call/cls_uint.c, - testsuite/libffi.call/cls_multi_ushortchar.c, - testsuite/libffi.call/cls_schar.c, - testsuite/libffi.call/cls_uchar.c, - testsuite/libffi.call/cls_align_uint64.c, - testsuite/libffi.call/cls_ulonglong.c, - testsuite/libffi.call/cls_align_longdouble.c, - testsuite/libffi.call/cls_1_1byte.c, - testsuite/libffi.call/cls_12byte.c, - testsuite/libffi.call/cls_3_1byte.c, - testsuite/libffi.call/cls_3byte1.c, - testsuite/libffi.call/cls_4_1byte.c, - testsuite/libffi.call/cls_6_1_byte.c, - testsuite/libffi.call/cls_16byte.c, - testsuite/libffi.call/cls_18byte.c, - testsuite/libffi.call/closure_fn0.c, - testsuite/libffi.call/cls_9byte2.c, - testsuite/libffi.call/closure_fn2.c, - testsuite/libffi.call/closure_fn4.c, - testsuite/libffi.call/cls_ushort.c, - testsuite/libffi.call/closure_fn6.c, - testsuite/libffi.call/cls_5byte.c, - testsuite/libffi.call/cls_align_pointer.c, - testsuite/libffi.call/cls_7byte.c, - testsuite/libffi.call/cls_align_sint32.c, - testsuite/libffi.special/unwindtest_ffi_call.cc, - testsuite/libffi.special/unwindtest.cc: Remove xfail for mips64*-*-*. - -2007-08-10 David Daney - - PR libffi/28313 - * configure.ac: Don't treat mips64 as a special case. - * Makefile.am (nodist_libffi_la_SOURCES): Add n32.S. - * configure: Regenerate - * Makefile.in: Ditto. - * fficonfig.h.in: Ditto. - * src/mips/ffitarget.h (REG_L, REG_S, SUBU, ADDU, SRL, LI): Indent. - (LA, EH_FRAME_ALIGN, FDE_ADDR_BYTES): New preprocessor macros. - (FFI_DEFAULT_ABI): Set for n64 case. - (FFI_CLOSURES, FFI_TRAMPOLINE_SIZE): Define for n32 and n64 cases. - * src/mips/n32.S (ffi_call_N32): Add debug macros and labels for FDE. - (ffi_closure_N32): New function. - (.eh_frame): New section - * src/mips/o32.S: Clean up comments. - (ffi_closure_O32): Pass ffi_closure parameter in $12. - * src/mips/ffi.c: Use FFI_MIPS_N32 instead of - _MIPS_SIM == _ABIN32 throughout. - (FFI_MIPS_STOP_HERE): New, use in place of - ffi_stop_here. - (ffi_prep_args): Use unsigned long to hold pointer values. Rewrite - to support n32/n64 ABIs. - (calc_n32_struct_flags): Rewrite. - (calc_n32_return_struct_flags): Remove unused variable. Reverse - position of flag bits. - (ffi_prep_cif_machdep): Rewrite n32 portion. - (ffi_call): Enable for n64. Add special handling for small structure - return values. - (ffi_prep_closure_loc): Add n32 and n64 support. - (ffi_closure_mips_inner_O32): Add cast to silence warning. - (copy_struct_N32, ffi_closure_mips_inner_N32): New functions. - -2007-08-08 David Daney - - * testsuite/libffi.call/ffitest.h (ffi_type_mylong): Remove definition. - * testsuite/libffi.call/cls_align_uint16.c (main): Use correct type - specifiers. - * testsuite/libffi.call/nested_struct1.c (main): Ditto. - * testsuite/libffi.call/cls_sint.c (main): Ditto. - * testsuite/libffi.call/nested_struct9.c (main): Ditto. - * testsuite/libffi.call/cls_20byte1.c (main): Ditto. - * testsuite/libffi.call/cls_9byte1.c (main): Ditto. - * testsuite/libffi.call/closure_fn1.c (main): Ditto. - * testsuite/libffi.call/closure_fn3.c (main): Ditto. - * testsuite/libffi.call/return_dbl2.c (main): Ditto. - * testsuite/libffi.call/cls_sshort.c (main): Ditto. - * testsuite/libffi.call/return_fl3.c (main): Ditto. - * testsuite/libffi.call/closure_fn5.c (main): Ditto. - * testsuite/libffi.call/nested_struct.c (main): Ditto. - * testsuite/libffi.call/nested_struct10.c (main): Ditto. - * testsuite/libffi.call/return_ll1.c (main): Ditto. - * testsuite/libffi.call/cls_8byte.c (main): Ditto. - * testsuite/libffi.call/cls_align_uint32.c (main): Ditto. - * testsuite/libffi.call/cls_align_sint16.c (main): Ditto. - * testsuite/libffi.call/cls_20byte.c (main): Ditto. - * testsuite/libffi.call/nested_struct2.c (main): Ditto. - * testsuite/libffi.call/cls_24byte.c (main): Ditto. - * testsuite/libffi.call/nested_struct6.c (main): Ditto. - * testsuite/libffi.call/cls_uint.c (main): Ditto. - * testsuite/libffi.call/cls_12byte.c (main): Ditto. - * testsuite/libffi.call/cls_16byte.c (main): Ditto. - * testsuite/libffi.call/closure_fn0.c (main): Ditto. - * testsuite/libffi.call/cls_9byte2.c (main): Ditto. - * testsuite/libffi.call/closure_fn2.c (main): Ditto. - * testsuite/libffi.call/return_dbl1.c (main): Ditto. - * testsuite/libffi.call/closure_fn4.c (main): Ditto. - * testsuite/libffi.call/closure_fn6.c (main): Ditto. - * testsuite/libffi.call/cls_align_sint32.c (main): Ditto. - -2007-08-07 Andrew Haley - - * src/x86/sysv.S (ffi_closure_raw_SYSV): Fix typo in previous - checkin. - -2007-08-06 Andrew Haley - - PR testsuite/32843 - * src/x86/sysv.S (ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8, - FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32, - FFI_TYPE_SINT32. - -2007-08-02 David Daney - - * testsuite/libffi.call/return_ul.c (main): Define return type as - ffi_arg. Use proper printf conversion specifier. - -2007-07-30 Andrew Haley - - PR testsuite/32843 - * src/x86/ffi.c (ffi_prep_cif_machdep): in x86 case, add code for - signed/unsigned int8/16. - * src/x86/sysv.S (ffi_call_SYSV): Rewrite to: - Use a jump table. - Remove code to pop args from the stack after call. - Special-case signed/unsigned int8/16. - * testsuite/libffi.call/return_sc.c (main): Revert. - -2007-07-26 Richard Guenther - - PR testsuite/32843 - * testsuite/libffi.call/return_sc.c (main): Verify call - result as signed char, not ffi_arg. - -2007-07-16 Rainer Orth - - * configure.ac (i?86-*-solaris2.1[0-9]): Set TARGET to X86_64. - * configure: Regenerate. - -2007-07-11 David Daney - - * src/mips/ffi.c: Don't include sys/cachectl.h. - (ffi_prep_closure_loc): Use __builtin___clear_cache() instead of - cacheflush(). - -2007-05-18 Aurelien Jarno - - * src/arm/ffi.c (ffi_prep_closure_loc): Renamed and ajusted - from (ffi_prep_closure): ... this. - (FFI_INIT_TRAMPOLINE): Adjust. - -2005-12-31 Phil Blundell - - * src/arm/ffi.c (ffi_prep_incoming_args_SYSV, - ffi_closure_SYSV_inner, ffi_prep_closure): New, add closure support. - * src/arm/sysv.S(ffi_closure_SYSV): Likewise. - * src/arm/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise. - (FFI_CLOSURES): Enable closure support. - -2007-07-03 Andrew Haley - - * testsuite/libffi.call/cls_multi_ushort.c, - testsuite/libffi.call/cls_align_uint16.c, - testsuite/libffi.call/nested_struct1.c, - testsuite/libffi.call/nested_struct3.c, - testsuite/libffi.call/cls_7_1_byte.c, - testsuite/libffi.call/cls_double.c, - testsuite/libffi.call/nested_struct5.c, - testsuite/libffi.call/nested_struct7.c, - testsuite/libffi.call/cls_sint.c, - testsuite/libffi.call/nested_struct9.c, - testsuite/libffi.call/cls_20byte1.c, - testsuite/libffi.call/cls_multi_sshortchar.c, - testsuite/libffi.call/cls_align_sint64.c, - testsuite/libffi.call/cls_3byte2.c, - testsuite/libffi.call/cls_multi_schar.c, - testsuite/libffi.call/cls_multi_uchar.c, - testsuite/libffi.call/cls_19byte.c, - testsuite/libffi.call/cls_9byte1.c, - testsuite/libffi.call/cls_align_float.c, - testsuite/libffi.call/closure_fn1.c, - testsuite/libffi.call/problem1.c, - testsuite/libffi.call/closure_fn3.c, - testsuite/libffi.call/cls_sshort.c, - testsuite/libffi.call/closure_fn5.c, - testsuite/libffi.call/cls_align_double.c, - testsuite/libffi.call/cls_2byte.c, - testsuite/libffi.call/nested_struct.c, - testsuite/libffi.call/nested_struct10.c, - testsuite/libffi.call/cls_4byte.c, - testsuite/libffi.call/cls_6byte.c, - testsuite/libffi.call/cls_8byte.c, - testsuite/libffi.call/cls_multi_sshort.c, - testsuite/libffi.call/cls_align_uint32.c, - testsuite/libffi.call/cls_align_sint16.c, - testsuite/libffi.call/cls_float.c, - testsuite/libffi.call/cls_20byte.c, - testsuite/libffi.call/cls_5_1_byte.c, - testsuite/libffi.call/nested_struct2.c, - testsuite/libffi.call/cls_24byte.c, - testsuite/libffi.call/nested_struct4.c, - testsuite/libffi.call/nested_struct6.c, - testsuite/libffi.call/cls_64byte.c, - testsuite/libffi.call/nested_struct8.c, - testsuite/libffi.call/cls_uint.c, - testsuite/libffi.call/cls_multi_ushortchar.c, - testsuite/libffi.call/cls_schar.c, - testsuite/libffi.call/cls_uchar.c, - testsuite/libffi.call/cls_align_uint64.c, - testsuite/libffi.call/cls_ulonglong.c, - testsuite/libffi.call/cls_align_longdouble.c, - testsuite/libffi.call/cls_1_1byte.c, - testsuite/libffi.call/cls_12byte.c, - testsuite/libffi.call/cls_3_1byte.c, - testsuite/libffi.call/cls_3byte1.c, - testsuite/libffi.call/cls_4_1byte.c, - testsuite/libffi.call/cls_6_1_byte.c, - testsuite/libffi.call/cls_16byte.c, - testsuite/libffi.call/cls_18byte.c, - testsuite/libffi.call/closure_fn0.c, - testsuite/libffi.call/cls_9byte2.c, - testsuite/libffi.call/closure_fn2.c, - testsuite/libffi.call/closure_fn4.c, - testsuite/libffi.call/cls_ushort.c, - testsuite/libffi.call/closure_fn6.c, - testsuite/libffi.call/cls_5byte.c, - testsuite/libffi.call/cls_align_pointer.c, - testsuite/libffi.call/cls_7byte.c, - testsuite/libffi.call/cls_align_sint32.c, - testsuite/libffi.special/unwindtest_ffi_call.cc, - testsuite/libffi.special/unwindtest.cc: Enable for ARM. - -2007-07-05 H.J. Lu - - * aclocal.m4: Regenerated. - -2007-06-02 Paolo Bonzini - - * configure: Regenerate. - -2007-05-23 Steve Ellcey - - * Makefile.in: Regenerate. - * configure: Regenerate. - * aclocal.m4: Regenerate. - * include/Makefile.in: Regenerate. - * testsuite/Makefile.in: Regenerate. - -2007-05-10 Roman Zippel - - * src/m68k/ffi.c (ffi_prep_incoming_args_SYSV, - ffi_closure_SYSV_inner,ffi_prep_closure): New, add closure support. - * src/m68k/sysv.S(ffi_closure_SYSV,ffi_closure_struct_SYSV): Likewise. - * src/m68k/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise. - (FFI_CLOSURES): Enable closure support. - -2007-05-10 Roman Zippel - - * configure.ac (HAVE_AS_CFI_PSEUDO_OP): New test. - * configure: Regenerate. - * fficonfig.h.in: Regenerate. - * src/m68k/sysv.S (CFI_STARTPROC,CFI_ENDPROC, - CFI_OFFSET,CFI_DEF_CFA): New macros. - (ffi_call_SYSV): Add callframe annotation. - -2007-05-10 Roman Zippel - - * src/m68k/ffi.c (ffi_prep_args,ffi_prep_cif_machdep): Fix - numerous test suite failures. - * src/m68k/sysv.S (ffi_call_SYSV): Likewise. - -2007-04-11 Paolo Bonzini - - * Makefile.am (EXTRA_DIST): Bring up to date. - * Makefile.in: Regenerate. - * src/frv/eabi.S: Remove RCS keyword. - -2007-04-06 Richard Henderson - - * configure.ac: Tidy target case. - (HAVE_LONG_DOUBLE): Allow the target to override. - * configure: Regenerate. - * include/ffi.h.in: Don't define ffi_type_foo if - LIBFFI_HIDE_BASIC_TYPES is defined. - (ffi_type_longdouble): If not HAVE_LONG_DOUBLE, define - to ffi_type_double. - * types.c (LIBFFI_HIDE_BASIC_TYPES): Define. - (FFI_TYPEDEF, ffi_type_void): Mark the data const. - (ffi_type_longdouble): Special case for Alpha. Don't define - if long double == double. - - * src/alpha/ffi.c (FFI_TYPE_LONGDOUBLE): Assert unique value. - (ffi_prep_cif_machdep): Handle it as the 128-bit type. - (ffi_call, ffi_closure_osf_inner): Likewise. - (ffi_closure_osf_inner): Likewise. Mark hidden. - (ffi_call_osf, ffi_closure_osf): Mark hidden. - * src/alpha/ffitarget.h (FFI_LAST_ABI): Tidy definition. - * src/alpha/osf.S (ffi_call_osf, ffi_closure_osf): Mark hidden. - (load_table): Handle 128-bit long double. - - * testsuite/libffi.call/float4.c: Add -mieee for alpha. - -2007-04-06 Tom Tromey - - PR libffi/31491: - * README: Fixed bug in example. - -2007-04-03 Jakub Jelinek - - * src/closures.c: Include sys/statfs.h. - (_GNU_SOURCE): Define on Linux. - (FFI_MMAP_EXEC_SELINUX): Define. - (selinux_enabled): New variable. - (selinux_enabled_check): New function. - (is_selinux_enabled): Define. - (dlmmap): Use it. - -2007-03-24 Uros Bizjak - - * testsuite/libffi.call/return_fl2.c (return_fl): Mark as static. - Use 'volatile float sum' to create sum of floats to avoid false - negative due to excess precision on ix86 targets. - (main): Ditto. - -2007-03-08 Alexandre Oliva - - * src/powerpc/ffi.c (flush_icache): Fix left-over from previous - patch. - (ffi_prep_closure_loc): Remove unneeded casts. Add needed ones. - -2007-03-07 Alexandre Oliva - - * include/ffi.h.in (ffi_closure_alloc, ffi_closure_free): New. - (ffi_prep_closure_loc): New. - (ffi_prep_raw_closure_loc): New. - (ffi_prep_java_raw_closure_loc): New. - * src/closures.c: New file. - * src/dlmalloc.c [FFI_MMAP_EXEC_WRIT] (struct malloc_segment): - Replace sflags with exec_offset. - [FFI_MMAP_EXEC_WRIT] (mmap_exec_offset, add_segment_exec_offset, - sub_segment_exec_offset): New macros. - (get_segment_flags, set_segment_flags, check_segment_merge): New - macros. - (is_mmapped_segment, is_extern_segment): Use get_segment_flags. - (add_segment, sys_alloc, create_mspace, create_mspace_with_base, - destroy_mspace): Use new macros. - (sys_alloc): Silence warning. - * Makefile.am (libffi_la_SOURCES): Add src/closures.c. - * Makefile.in: Rebuilt. - * src/prep_cif [FFI_CLOSURES] (ffi_prep_closure): Implement in - terms of ffi_prep_closure_loc. - * src/raw_api.c (ffi_prep_raw_closure_loc): Renamed and adjusted - from... - (ffi_prep_raw_closure): ... this. Re-implement in terms of the - renamed version. - * src/java_raw_api (ffi_prep_java_raw_closure_loc): Renamed and - adjusted from... - (ffi_prep_java_raw_closure): ... this. Re-implement in terms of - the renamed version. - * src/alpha/ffi.c (ffi_prep_closure_loc): Renamed from - (ffi_prep_closure): ... this. - * src/pa/ffi.c: Likewise. - * src/cris/ffi.c: Likewise. Adjust. - * src/frv/ffi.c: Likewise. - * src/ia64/ffi.c: Likewise. - * src/mips/ffi.c: Likewise. - * src/powerpc/ffi_darwin.c: Likewise. - * src/s390/ffi.c: Likewise. - * src/sh/ffi.c: Likewise. - * src/sh64/ffi.c: Likewise. - * src/sparc/ffi.c: Likewise. - * src/x86/ffi64.c: Likewise. - * src/x86/ffi.c: Likewise. - (FFI_INIT_TRAMPOLINE): Adjust. - (ffi_prep_raw_closure_loc): Renamed and adjusted from... - (ffi_prep_raw_closure): ... this. - * src/powerpc/ffi.c (ffi_prep_closure_loc): Renamed from - (ffi_prep_closure): ... this. - (flush_icache): Adjust. - -2007-03-07 Alexandre Oliva - - * src/dlmalloc.c: New file, imported version 2.8.3 of Doug - Lea's malloc. - -2007-03-01 Brooks Moses - - * Makefile.am: Add dummy install-pdf target. - * Makefile.in: Regenerate - -2007-02-13 Andreas Krebbel - - * src/s390/ffi.c (ffi_prep_args, ffi_prep_cif_machdep, - ffi_closure_helper_SYSV): Add long double handling. - -2007-02-02 Jakub Jelinek - - * src/powerpc/linux64.S (ffi_call_LINUX64): Move restore of r2 - immediately after bctrl instruction. - -2007-01-18 Alexandre Oliva - - * Makefile.am (all-recursive, install-recursive, - mostlyclean-recursive, clean-recursive, distclean-recursive, - maintainer-clean-recursive): Add missing targets. - * Makefile.in: Rebuilt. - -2006-12-14 Andreas Tobler - - * configure.ac: Add TARGET for x86_64-*-darwin*. - * Makefile.am (nodist_libffi_la_SOURCES): Add rules for 64-bit sources - for X86_DARWIN. - * src/x86/ffitarget.h: Set trampoline size for x86_64-*-darwin*. - * src/x86/darwin64.S: New file for x86_64-*-darwin* support. - * configure: Regenerate. - * Makefile.in: Regenerate. - * include/Makefile.in: Regenerate. - * testsuite/Makefile.in: Regenerate. - * testsuite/libffi.special/unwindtest_ffi_call.cc: New test case for - ffi_call only. - -2006-12-13 Andreas Tobler - - * aclocal.m4: Regenerate with aclocal -I .. as written in the - Makefile.am. - -2006-10-31 Geoffrey Keating - - * src/powerpc/ffi_darwin.c (darwin_adjust_aggregate_sizes): New. - (ffi_prep_cif_machdep): Call darwin_adjust_aggregate_sizes for - Darwin. - * testsuite/libffi.call/nested_struct4.c: Remove Darwin XFAIL. - * testsuite/libffi.call/nested_struct6.c: Remove Darwin XFAIL. - -2006-10-10 Paolo Bonzini - Sandro Tolaini - - * configure.ac [i*86-*-darwin*]: Set X86_DARWIN symbol and - conditional. - * configure: Regenerated. - * Makefile.am (nodist_libffi_la_SOURCES) [X86_DARWIN]: New case. - (EXTRA_DIST): Add src/x86/darwin.S. - * Makefile.in: Regenerated. - * include/Makefile.in: Regenerated. - * testsuite/Makefile.in: Regenerated. - - * src/x86/ffi.c (ffi_prep_cif_machdep) [X86_DARWIN]: Treat like - X86_WIN32, and additionally align stack to 16 bytes. - * src/x86/darwin.S: New, based on sysv.S. - * src/prep_cif.c (ffi_prep_cif) [X86_DARWIN]: Align > 8-byte structs. - -2006-09-12 David Daney - - PR libffi/23935 - * include/Makefile.am: Install both ffi.h and ffitarget.h in - $(libdir)/gcc/$(target_alias)/$(gcc_version)/include. - * aclocal.m4: Regenerated for automake 1.9.6. - * Makefile.in: Regenerated. - * include/Makefile.in: Regenerated. - * testsuite/Makefile.in: Regenerated. - -2006-08-17 Andreas Tobler - - * include/ffi_common.h (struct): Revert accidental commit. - -2006-08-15 Andreas Tobler - - * include/ffi_common.h: Remove lint directives. - * include/ffi.h.in: Likewise. - -2006-07-25 Torsten Schoenfeld - - * include/ffi.h.in (ffi_type_ulong, ffi_type_slong): Define correctly - for 32-bit architectures. - * testsuite/libffi.call/return_ul.c: New test case. - -2006-07-19 David Daney - - * testsuite/libffi.call/closure_fn6.c: Remove xfail for mips, - xfail remains for mips64. - -2006-05-23 Carlos O'Donell - - * Makefile.am: Add install-html target. Add install-html to .PHONY - * Makefile.in: Regenerate. - * aclocal.m4: Regenerate. - * include/Makefile.in: Regenerate. - * testsuite/Makefile.in: Regenerate. - -2006-05-18 John David Anglin - - * pa/ffi.c (ffi_prep_args_pa32): Load floating point arguments from - stack slot. - -2006-04-22 Andreas Tobler - - * README: Remove notice about 'Crazy Comments'. - * src/debug.c: Remove lint directives. Cleanup white spaces. - * src/java_raw_api.c: Likewise. - * src/prep_cif.c: Likewise. - * src/raw_api.c: Likewise. - * src/ffitest.c: Delete. No longer needed, all test cases migrated - to the testsuite. - * src/arm/ffi.c: Remove lint directives. - * src/m32r/ffi.c: Likewise. - * src/pa/ffi.c: Likewise. - * src/powerpc/ffi.c: Likewise. - * src/powerpc/ffi_darwin.c: Likewise. - * src/sh/ffi.c: Likewise. - * src/sh64/ffi.c: Likewise. - * src/x86/ffi.c: Likewise. - * testsuite/libffi.call/float2.c: Likewise. - * testsuite/libffi.call/promotion.c: Likewise. - * testsuite/libffi.call/struct1.c: Likewise. - -2006-04-13 Andreas Tobler - - * src/pa/hpux32.S: Correct unwind offset calculation for - ffi_closure_pa32. - * src/pa/linux.S: Likewise. - -2006-04-12 James E Wilson - - PR libgcj/26483 - * src/ia64/ffi.c (stf_spill, ldf_fill): Rewrite as macros. - (hfa_type_load): Call stf_spill. - (hfa_type_store): Call ldf_fill. - (ffi_call): Adjust calls to above routines. Add local temps for - macro result. - -2006-04-10 Matthias Klose - - * testsuite/lib/libffi-dg.exp (libffi-init): Recognize multilib - directory names containing underscores. - -2006-04-07 James E Wilson - - * testsuite/libffi.call/float4.c: New testcase. - -2006-04-05 John David Anglin - Andreas Tobler - - * Makefile.am: Add PA_HPUX port. - * Makefile.in: Regenerate. - * include/Makefile.in: Likewise. - * testsuite/Makefile.in: Likewise. - * configure.ac: Add PA_HPUX rules. - * configure: Regenerate. - * src/pa/ffitarget.h: Rename linux target to PA_LINUX. - Add PA_HPUX and PA64_HPUX. - Rename FFI_LINUX ABI to FFI_PA32 ABI. - (FFI_TRAMPOLINE_SIZE): Define for 32-bit HP-UX targets. - (FFI_TYPE_SMALL_STRUCT2): Define. - (FFI_TYPE_SMALL_STRUCT4): Likewise. - (FFI_TYPE_SMALL_STRUCT8): Likewise. - (FFI_TYPE_SMALL_STRUCT3): Redefine. - (FFI_TYPE_SMALL_STRUCT5): Likewise. - (FFI_TYPE_SMALL_STRUCT6): Likewise. - (FFI_TYPE_SMALL_STRUCT7): Likewise. - * src/pa/ffi.c (ROUND_DOWN): Delete. - (fldw, fstw, fldd, fstd): Use '__asm__'. - (ffi_struct_type): Add support for FFI_TYPE_SMALL_STRUCT2, - FFI_TYPE_SMALL_STRUCT4 and FFI_TYPE_SMALL_STRUCT8. - (ffi_prep_args_LINUX): Rename to ffi_prep_args_pa32. Update comment. - Simplify incrementing of stack slot variable. Change type of local - 'n' to unsigned int. - (ffi_size_stack_LINUX): Rename to ffi_size_stack_pa32. Handle long - double on PA_HPUX. - (ffi_prep_cif_machdep): Likewise. - (ffi_call): Likewise. - (ffi_closure_inner_LINUX): Rename to ffi_closure_inner_pa32. Change - return type to ffi_status. Simplify incrementing of stack slot - variable. Only copy floating point argument registers when PA_LINUX - is true. Reformat debug statement. - Add support for FFI_TYPE_SMALL_STRUCT2, FFI_TYPE_SMALL_STRUCT4 and - FFI_TYPE_SMALL_STRUCT8. - (ffi_closure_LINUX): Rename to ffi_closure_pa32. Add 'extern' to - declaration. - (ffi_prep_closure): Make linux trampoline conditional on PA_LINUX. - Add nops to cache flush. Add trampoline for PA_HPUX. - * src/pa/hpux32.S: New file. - * src/pa/linux.S (ffi_call_LINUX): Rename to ffi_call_pa32. Rename - ffi_prep_args_LINUX to ffi_prep_args_pa32. - Localize labels. Add support for 2, 4 and 8-byte small structs. Handle - unaligned destinations in 3, 5, 6 and 7-byte small structs. Order - argument type checks so that common argument types appear first. - (ffi_closure_LINUX): Rename to ffi_closure_pa32. Rename - ffi_closure_inner_LINUX to ffi_closure_inner_pa32. - -2006-03-24 Alan Modra - - * src/powerpc/ffitarget.h (enum ffi_abi): Add FFI_LINUX. Default - for 32-bit using IBM extended double format. Fix FFI_LAST_ABI. - * src/powerpc/ffi.c (ffi_prep_args_SYSV): Handle linux variant of - FFI_TYPE_LONGDOUBLE. - (ffi_prep_args64): Assert using IBM extended double. - (ffi_prep_cif_machdep): Don't munge FFI_TYPE_LONGDOUBLE type. - Handle FFI_LINUX FFI_TYPE_LONGDOUBLE return and args. - (ffi_call): Handle FFI_LINUX. - (ffi_closure_helper_SYSV): Non FFI_LINUX long double return needs - gpr3 return pointer as for struct return. Handle FFI_LINUX - FFI_TYPE_LONGDOUBLE return and args. Don't increment "nf" - unnecessarily. - * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Load both f1 and f2 - for FFI_TYPE_LONGDOUBLE. Move epilogue insns into case table. - Don't use r6 as pointer to results, instead use sp offset. Don't - make a special call to load lr with case table address, instead - use offset from previous call. - * src/powerpc/sysv.S (ffi_call_SYSV): Save long double return. - * src/powerpc/linux64.S (ffi_call_LINUX64): Simplify long double - return. - -2006-03-15 Kaz Kojima - - * src/sh64/ffi.c (ffi_prep_cif_machdep): Handle float arguments - passed with FP registers correctly. - (ffi_closure_helper_SYSV): Likewise. - * src/sh64/sysv.S: Likewise. - -2006-03-01 Andreas Tobler - - * testsuite/libffi.special/unwindtest.cc (closure_test_fn): Mark cif, - args and userdata unused. - (closure_test_fn1): Mark cif and userdata unused. - (main): Remove unused res. - -2006-02-28 Andreas Tobler - - * testsuite/libffi.call/call.exp: Adjust FSF address. Add test runs for - -O2, -O3, -Os and the warning flags -W -Wall. - * testsuite/libffi.special/special.exp: Likewise. - * testsuite/libffi.call/ffitest.h: Add an __UNUSED__ macro to mark - unused parameter unused for gcc or else do nothing. - * testsuite/libffi.special/ffitestcxx.h: Likewise. - * testsuite/libffi.call/cls_12byte.c (cls_struct_12byte_gn): Mark cif - and userdata unused. - * testsuite/libffi.call/cls_16byte.c (cls_struct_16byte_gn): Likewise. - * testsuite/libffi.call/cls_18byte.c (cls_struct_18byte_gn): Likewise. - * testsuite/libffi.call/cls_19byte.c (cls_struct_19byte_gn): Likewise. - * testsuite/libffi.call/cls_1_1byte.c (cls_struct_1_1byte_gn): Likewise. - * testsuite/libffi.call/cls_20byte.c (cls_struct_20byte_gn): Likewise. - * testsuite/libffi.call/cls_20byte1.c (cls_struct_20byte_gn): Likewise. - * testsuite/libffi.call/cls_24byte.c (cls_struct_24byte_gn): Likewise. - * testsuite/libffi.call/cls_2byte.c (cls_struct_2byte_gn): Likewise. - * testsuite/libffi.call/cls_3_1byte.c (cls_struct_3_1byte_gn): Likewise. - * testsuite/libffi.call/cls_3byte1.c (cls_struct_3byte_gn): Likewise. - * testsuite/libffi.call/cls_3byte2.c (cls_struct_3byte_gn1): Likewise. - * testsuite/libffi.call/cls_4_1byte.c (cls_struct_4_1byte_gn): Likewise. - * testsuite/libffi.call/cls_4byte.c (cls_struct_4byte_gn): Likewise. - * testsuite/libffi.call/cls_5_1_byte.c (cls_struct_5byte_gn): Likewise. - * testsuite/libffi.call/cls_5byte.c (cls_struct_5byte_gn): Likewise. - * testsuite/libffi.call/cls_64byte.c (cls_struct_64byte_gn): Likewise. - * testsuite/libffi.call/cls_6_1_byte.c (cls_struct_6byte_gn): Likewise. - * testsuite/libffi.call/cls_6byte.c (cls_struct_6byte_gn): Likewise. - * testsuite/libffi.call/cls_7_1_byte.c (cls_struct_7byte_gn): Likewise. - * testsuite/libffi.call/cls_7byte.c (cls_struct_7byte_gn): Likewise. - * testsuite/libffi.call/cls_8byte.c (cls_struct_8byte_gn): Likewise. - * testsuite/libffi.call/cls_9byte1.c (cls_struct_9byte_gn): Likewise. - * testsuite/libffi.call/cls_9byte2.c (cls_struct_9byte_gn): Likewise. - * testsuite/libffi.call/cls_align_double.c (cls_struct_align_gn): - Likewise. - * testsuite/libffi.call/cls_align_float.c (cls_struct_align_gn): - Likewise. - * testsuite/libffi.call/cls_align_longdouble.c (cls_struct_align_gn): - Likewise. - * testsuite/libffi.call/cls_align_pointer.c (cls_struct_align_fn): Cast - void* to avoid compiler warning. - (main): Likewise. - (cls_struct_align_gn): Mark cif and userdata unused. - * testsuite/libffi.call/cls_align_sint16.c (cls_struct_align_gn): - Likewise. - * testsuite/libffi.call/cls_align_sint32.c (cls_struct_align_gn): - Likewise. - * testsuite/libffi.call/cls_align_sint64.c (cls_struct_align_gn): - Likewise. - * testsuite/libffi.call/cls_align_uint16.c (cls_struct_align_gn): - Likewise. - * testsuite/libffi.call/cls_align_uint32.c (cls_struct_align_gn): - Likewise. - * testsuite/libffi.call/cls_double.c (cls_ret_double_fn): Likewise. - * testsuite/libffi.call/cls_float.c (cls_ret_float_fn): Likewise. - * testsuite/libffi.call/cls_multi_schar.c (test_func_gn): Mark cif and - data unused. - (main): Cast res_call to silence gcc. - * testsuite/libffi.call/cls_multi_sshort.c (test_func_gn): Mark cif and - data unused. - (main): Cast res_call to silence gcc. - * testsuite/libffi.call/cls_multi_sshortchar.c (test_func_gn): Mark cif - and data unused. - (main): Cast res_call to silence gcc. - * testsuite/libffi.call/cls_multi_uchar.c (test_func_gn): Mark cif and - data unused. - (main): Cast res_call to silence gcc. - * testsuite/libffi.call/cls_multi_ushort.c (test_func_gn): Mark cif and - data unused. - (main): Cast res_call to silence gcc. - * testsuite/libffi.call/cls_multi_ushortchar.c (test_func_gn): Mark cif - and data unused. - (main): Cast res_call to silence gcc. - * testsuite/libffi.call/cls_schar.c (cls_ret_schar_fn): Mark cif and - userdata unused. - (cls_ret_schar_fn): Cast printf parameter to silence gcc. - * testsuite/libffi.call/cls_sint.c (cls_ret_sint_fn): Mark cif and - userdata unused. - (cls_ret_sint_fn): Cast printf parameter to silence gcc. - * testsuite/libffi.call/cls_sshort.c (cls_ret_sshort_fn): Mark cif and - userdata unused. - (cls_ret_sshort_fn): Cast printf parameter to silence gcc. - * testsuite/libffi.call/cls_uchar.c (cls_ret_uchar_fn): Mark cif and - userdata unused. - (cls_ret_uchar_fn): Cast printf parameter to silence gcc. - * testsuite/libffi.call/cls_uint.c (cls_ret_uint_fn): Mark cif and - userdata unused. - (cls_ret_uint_fn): Cast printf parameter to silence gcc. - * testsuite/libffi.call/cls_ulonglong.c (cls_ret_ulonglong_fn): Mark cif - and userdata unused. - * testsuite/libffi.call/cls_ushort.c (cls_ret_ushort_fn): Mark cif and - userdata unused. - (cls_ret_ushort_fn): Cast printf parameter to silence gcc. - * testsuite/libffi.call/float.c (floating): Remove unused parameter e. - * testsuite/libffi.call/float1.c (main): Remove unused variable i. - Cleanup white spaces. - * testsuite/libffi.call/negint.c (checking): Remove unused variable i. - * testsuite/libffi.call/nested_struct.c (cls_struct_combined_gn): Mark - cif and userdata unused. - * testsuite/libffi.call/nested_struct1.c (cls_struct_combined_gn): - Likewise. - * testsuite/libffi.call/nested_struct10.c (B_gn): Likewise. - * testsuite/libffi.call/nested_struct2.c (B_fn): Adjust printf - formatters to silence gcc. - (B_gn): Mark cif and userdata unused. - * testsuite/libffi.call/nested_struct3.c (B_gn): Mark cif and userdata - unused. - * testsuite/libffi.call/nested_struct4.c: Mention related PR. - (B_gn): Mark cif and userdata unused. - * testsuite/libffi.call/nested_struct5.c (B_gn): Mark cif and userdata - unused. - * testsuite/libffi.call/nested_struct6.c: Mention related PR. - (B_gn): Mark cif and userdata unused. - * testsuite/libffi.call/nested_struct7.c (B_gn): Mark cif and userdata - unused. - * testsuite/libffi.call/nested_struct8.c (B_gn): Likewise. - * testsuite/libffi.call/nested_struct9.c (B_gn): Likewise. - * testsuite/libffi.call/problem1.c (stub): Likewise. - * testsuite/libffi.call/pyobjc-tc.c (main): Cast the result to silence - gcc. - * testsuite/libffi.call/return_fl2.c (return_fl): Add the note mentioned - in the last commit for this test case in the test case itself. - * testsuite/libffi.call/closure_fn0.c (closure_test_fn0): Mark cif as - unused. - * testsuite/libffi.call/closure_fn1.c (closure_test_fn1): Likewise. - * testsuite/libffi.call/closure_fn2.c (closure_test_fn2): Likewise. - * testsuite/libffi.call/closure_fn3.c (closure_test_fn3): Likewise. - * testsuite/libffi.call/closure_fn4.c (closure_test_fn0): Likewise. - * testsuite/libffi.call/closure_fn5.c (closure_test_fn5): Likewise. - * testsuite/libffi.call/closure_fn6.c (closure_test_fn0): Likewise. - -2006-02-22 Kaz Kojima - - * src/sh/sysv.S: Fix register numbers in the FDE for - ffi_closure_SYSV. - -2006-02-20 Andreas Tobler - - * testsuite/libffi.call/return_fl2.c (return_fl): Remove static - declaration to avoid a false negative on ix86. See PR323. - -2006-02-18 Kaz Kojima - - * src/sh/ffi.c (ffi_closure_helper_SYSV): Remove unused variable - and cast integer to void * if needed. Update the pointer to - the FP register saved area correctly. - -2006-02-17 Andreas Tobler - - * testsuite/libffi.call/nested_struct6.c: XFAIL this test until PR25630 - is fixed. - * testsuite/libffi.call/nested_struct4.c: Likewise. - -2006-02-16 Andreas Tobler - - * testsuite/libffi.call/return_dbl.c: New test case. - * testsuite/libffi.call/return_dbl1.c: Likewise. - * testsuite/libffi.call/return_dbl2.c: Likewise. - * testsuite/libffi.call/return_fl.c: Likewise. - * testsuite/libffi.call/return_fl1.c: Likewise. - * testsuite/libffi.call/return_fl2.c: Likewise. - * testsuite/libffi.call/return_fl3.c: Likewise. - * testsuite/libffi.call/closure_fn6.c: Likewise. - - * testsuite/libffi.call/nested_struct2.c: Remove ffi_type_mylong - definition. - * testsuite/libffi.call/ffitest.h: Add ffi_type_mylong definition - here to be used by other test cases too. - - * testsuite/libffi.call/nested_struct10.c: New test case. - * testsuite/libffi.call/nested_struct9.c: Likewise. - * testsuite/libffi.call/nested_struct8.c: Likewise. - * testsuite/libffi.call/nested_struct7.c: Likewise. - * testsuite/libffi.call/nested_struct6.c: Likewise. - * testsuite/libffi.call/nested_struct5.c: Likewise. - * testsuite/libffi.call/nested_struct4.c: Likewise. - -2006-01-21 Andreas Tobler - - * configure.ac: Enable libffi for sparc64-*-freebsd*. - * configure: Rebuilt. - -2006-01-18 Jakub Jelinek - - * src/powerpc/sysv.S (smst_two_register): Don't call __ashldi3, - instead do the shifting inline. - * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't compute %r5 - shift count unconditionally. Simplify load sequences for 1, 2, 3, 4 - and 8 byte structs, for the remaining struct sizes don't call - __lshrdi3, instead do the shifting inline. - -2005-12-07 Thiemo Seufer - - * src/mips/ffitarget.h: Remove obsolete sgidefs.h include. Add - missing parentheses. - * src/mips/o32.S (ffi_call_O32): Code formatting. Define - and use A3_OFF, FP_OFF, RA_OFF. Micro-optimizations. - (ffi_closure_O32): Likewise, but with newly defined A3_OFF2, - A2_OFF2, A1_OFF2, A0_OFF2, RA_OFF2, FP_OFF2, S0_OFF2, GP_OFF2, - V1_OFF2, V0_OFF2, FA_1_1_OFF2, FA_1_0_OFF2, FA_0_1_OFF2, - FA_0_0_OFF2. - * src/mips/ffi.c (ffi_prep_args): Code formatting. Fix - endianness bugs. - (ffi_prep_closure): Improve trampoline instruction scheduling. - (ffi_closure_mips_inner_O32): Fix endianness bugs. - -2005-12-03 Alan Modra - - * src/powerpc/ffi.c: Formatting. - (ffi_prep_args_SYSV): Avoid possible aliasing problems by using unions. - (ffi_prep_args64): Likewise. - -2005-09-30 Geoffrey Keating - - * testsuite/lib/libffi-dg.exp (libffi_target_compile): For - darwin, use -shared-libgcc not -lgcc_s, and explain why. - -2005-09-26 Tom Tromey - - * testsuite/libffi.call/float1.c (value_type): New typedef. - (CANARY): New define. - (main): Check for result buffer overflow. - * src/powerpc/linux64.S: Handle linux64 long double returns. - * src/powerpc/ffi.c (FLAG_RETURNS_128BITS): New constant. - (ffi_prep_cif_machdep): Handle linux64 long double returns. - -2005-08-25 Alan Modra - - PR target/23404 - * src/powerpc/ffi.c (ffi_prep_args_SYSV): Correct placement of stack - homed fp args. - (ffi_status ffi_prep_cif_machdep): Correct stack sizing for same. - -2005-08-11 Jakub Jelinek - - * configure.ac (HAVE_HIDDEN_VISIBILITY_ATTRIBUTE): New test. - (AH_BOTTOM): Add FFI_HIDDEN definition. - * configure: Rebuilt. - * fficonfig.h.in: Rebuilt. - * src/powerpc/ffi.c (hidden): Remove. - (ffi_closure_LINUX64, ffi_prep_args64, ffi_call_LINUX64, - ffi_closure_helper_LINUX64): Use FFI_HIDDEN instead of hidden. - * src/powerpc/linux64_closure.S (ffi_closure_LINUX64, - .ffi_closure_LINUX64): Use FFI_HIDDEN instead of .hidden. - * src/x86/ffi.c (ffi_closure_SYSV, ffi_closure_raw_SYSV): Remove, - add FFI_HIDDEN to its prototype. - (ffi_closure_SYSV_inner): New. - * src/x86/sysv.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New. - * src/x86/win32.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New. - -2005-08-10 Alfred M. Szmidt - - PR libffi/21819: - * configure: Rebuilt. - * configure.ac: Handle i*86-*-gnu*. - -2005-08-09 Jakub Jelinek - - * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Use - DW_CFA_offset_extended_sf rather than - DW_CFA_GNU_negative_offset_extended. - * src/powerpc/sysv.S (ffi_call_SYSV): Likewise. - -2005-07-22 SUGIOKA Toshinobu - - * src/sh/sysv.S (ffi_call_SYSV): Stop argument popping correctly - on sh3. - (ffi_closure_SYSV): Change the stack layout for sh3 struct argument. - * src/sh/ffi.c (ffi_prep_args): Fix sh3 argument copy, when it is - partially on register. - (ffi_closure_helper_SYSV): Likewise. - (ffi_prep_cif_machdep): Don't set too many cif->flags. - -2005-07-20 Kaz Kojima - - * src/sh/ffi.c (ffi_call): Handle small structures correctly. - Remove empty line. - * src/sh64/ffi.c (simple_type): Remove. - (return_type): Handle small structures correctly. - (ffi_prep_args): Likewise. - (ffi_call): Likewise. - (ffi_closure_helper_SYSV): Likewise. - * src/sh64/sysv.S (ffi_call_SYSV): Handle 1, 2 and 4-byte return. - Emit position independent code if PIC and remove wrong datalabel - prefixes from EH data. - -2005-07-19 Andreas Tobler - - * Makefile.am (nodist_libffi_la_SOURCES): Add POWERPC_FREEBSD. - * Makefile.in: Regenerate. - * include/Makefile.in: Likewise. - * testsuite/Makefile.in: Likewise. - * configure.ac: Add POWERPC_FREEBSD rules. - * configure: Regenerate. - * src/powerpc/ffitarget.h: Add POWERPC_FREEBSD rules. - (FFI_SYSV_TYPE_SMALL_STRUCT): Define. - * src/powerpc/ffi.c: Add flags to handle small structure returns - in ffi_call_SYSV. - (ffi_prep_cif_machdep): Handle small structures for SYSV 4 ABI. - Aka FFI_SYSV. - (ffi_closure_helper_SYSV): Likewise. - * src/powerpc/ppc_closure.S: Add return types for small structures. - * src/powerpc/sysv.S: Add bits to handle small structures for - final SYSV 4 ABI. - -2005-07-10 Andreas Tobler - - * testsuite/libffi.call/cls_5_1_byte.c: New test file. - * testsuite/libffi.call/cls_6_1_byte.c: Likewise. - * testsuite/libffi.call/cls_7_1_byte.c: Likewise. - -2005-07-05 Randolph Chung - - * src/pa/ffi.c (ffi_struct_type): Rename FFI_TYPE_SMALL_STRUCT1 - as FFI_TYPE_SMALL_STRUCT3. Break out handling for 5-7 byte - structures. Kill compilation warnings. - (ffi_closure_inner_LINUX): Print return values as hex in debug - message. Rename FFI_TYPE_SMALL_STRUCT1 as FFI_TYPE_SMALL_STRUCT3. - Properly handle 5-7 byte structure returns. - * src/pa/ffitarget.h (FFI_TYPE_SMALL_STRUCT1) - (FFI_TYPE_SMALL_STRUCT2): Remove. - (FFI_TYPE_SMALL_STRUCT3, FFI_TYPE_SMALL_STRUCT5) - (FFI_TYPE_SMALL_STRUCT6, FFI_TYPE_SMALL_STRUCT7): Define. - * src/pa/linux.S: Mark source file as using PA1.1 assembly. - (checksmst1, checksmst2): Remove. - (checksmst3): Optimize handling of 3-byte struct returns. - (checksmst567): Properly handle 5-7 byte struct returns. - -2005-06-15 Rainer Orth - - PR libgcj/21943 - * src/mips/n32.S: Enforce PIC code. - * src/mips/o32.S: Likewise. - -2005-06-15 Rainer Orth - - * configure.ac: Treat i*86-*-solaris2.10 and up as X86_64. - * configure: Regenerate. +commit 56ba8d86f47937a0afb81a2b9e77c9d235d9db45 +Author: Anthony Green +Date: Thu Jan 10 07:25:10 2013 -0500 -2005-06-01 Alan Modra + Don't use warning checking macro with sun compiler - * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't use JUMPTARGET - to call ffi_closure_helper_SYSV. Append @local instead. - * src/powerpc/sysv.S (ffi_call_SYSV): Likewise for ffi_prep_args_SYSV. +commit 6a028caec1b2c7904feb4c4f9cb7e1125e1d1b60 +Author: Anthony Green +Date: Thu Jan 10 01:19:43 2013 -0500 -2005-05-17 Kelley Cook + Don't use GCCisms to define types when + + building with the SUNPRO compiler. - * configure.ac: Use AC_C_BIGENDIAN instead of AC_C_BIGENDIAN_CROSS. - Use AC_CHECK_SIZEOF instead of AC_COMPILE_CHECK_SIZEOF. - * Makefile.am (ACLOCAL_AMFLAGS): Remove -I ../config. - * aclocal.m4, configure, fficonfig.h.in, Makefile.in, - include/Makefile.in, testsuite/Makefile.in: Regenerate. +commit 2d9b3939751b3ef9739049509d353ade10b32a8f +Author: Anthony Green +Date: Wed Jan 9 21:14:54 2013 -0500 -2005-05-09 Mike Stump + Fix for closures with sunpro compiler - * configure: Regenerate. +commit 8308984e479e3274a36e98e8272b5adbb6b774c2 +Author: Anthony Green +Date: Tue Jan 8 15:14:21 2013 -0500 -2005-05-08 Richard Henderson + Make sure we're running dejagnu tests with the right compiler. - PR libffi/21285 - * src/alpha/osf.S: Update unwind into to match code. +commit f26c7ca67147450db2fe25ea932944e6cf145d5c +Author: Anthony Green +Date: Tue Jan 8 14:47:05 2013 -0500 -2005-05-04 Andreas Degert - Richard Henderson + Make compiler options in dejagnu runs compiler specific - * src/x86/ffi64.c (ffi_prep_cif_machdep): Save sse-used flag in - bit 11 of flags. - (ffi_call): Mask return type field. Pass ssecount to ffi_call_unix64. - (ffi_prep_closure): Set carry bit if sse-used flag set. - * src/x86/unix64.S (ffi_call_unix64): Add ssecount argument. - Only load sse registers if ssecount non-zero. - (ffi_closure_unix64): Only save sse registers if carry set on entry. +commit 74c776e21907fc2e59257c021f23077f8b7966cb +Author: Anthony Green +Date: Tue Jan 8 12:25:54 2013 -0500 -2005-04-29 Ralf Corsepius + Switch x86 Solaris to X86 from X86_64 - * configure.ac: Add i*86-*-rtems*, sparc*-*-rtems*, - powerpc-*rtems*, arm*-*-rtems*, sh-*-rtems*. - * configure: Regenerate. +commit 8962c8c8d06803e310bac0ffc8e84ea15daeff3f +Author: Anthony Green +Date: Tue Jan 8 12:22:24 2013 -0500 -2005-04-20 Hans-Peter Nilsson + Fix read-only eh_frame test - * testsuite/lib/libffi-dg.exp (libffi-dg-test-1): In regsub use, - have Tcl8.3-compatible intermediate variable. +commit 35ddb69c2b49746d940e919ca226ecc1be94f14a +Author: Anthony Green +Date: Tue Jan 8 07:53:37 2013 -0500 -2005-04-18 Simon Posnjak - Hans-Peter Nilsson + Only emit DWARF unwind info when building with GCC - * Makefile.am: Add CRIS support. - * configure.ac: Likewise. - * Makefile.in, configure, testsuite/Makefile.in, - include/Makefile.in: Regenerate. - * src/cris: New directory. - * src/cris/ffi.c, src/cris/sysv.S, src/cris/ffitarget.h: New files. - * src/prep_cif.c (ffi_prep_cif): Wrap in #ifndef __CRIS__. +commit f7879bc3f3a8d0bbfcc38771732c160a58ba9cd8 +Author: Anthony Green +Date: Tue Jan 8 07:30:28 2013 -0500 - * testsuite/lib/libffi-dg.exp (libffi-dg-test-1): Replace \n with - \r?\n in output tests. + Testsuite fix for Solaris vendor compiler -2005-04-12 Mike Stump +commit 67cea90fc0897021466fd102671019d30db474cd +Author: Anthony Green +Date: Mon Jan 7 06:30:24 2013 -0500 - * configure: Regenerate. + mend -2005-03-30 Hans Boehm +commit 0de3277b18cf54be3b81d509b9be9b47d9bc1e82 +Author: Thorsten Glaser +Date: Mon Dec 3 00:02:31 2012 +0000 - * src/ia64/ffitarget.h (ffi_arg): Use long long instead of DI. + Testsuite fixes (was Re: [PATCH] Fix libffi on m68k-linux-gnu, completely) + + Dixi quod… + + >although I believe some 3.0.11 checks to be broken: + + And indeed, with a few minor changes on top of git master, + I still get a full run of PASS plus one XPASS on amd64-linux! + + With the other patches (from this message’s parent) and + these applied, I get a full PASS on m68k-linux as well. + + So, please git am these three diffs ☺ + + bye, + //mirabilos + -- + FWIW, I'm quite impressed with mksh interactively. I thought it was much + *much* more bare bones. But it turns out it beats the living hell out of + ksh93 in that respect. I'd even consider it for my daily use if I hadn't + wasted half my life on my zsh setup. :-) -- Frank Terbeck in #!/bin/mksh + From 5cb15a3bad1f0fb360520dd48bfc938c821cdcca Mon Sep 17 00:00:00 2001 + From: Thorsten Glaser + Date: Sun, 2 Dec 2012 23:20:56 +0000 + Subject: [PATCH 1/2] Fix tests writing to a closure retval via pointer casts + + As explained in + all other tests that do the same cast to an ffi_arg pointer instead. + + PASS on amd64-linux (Xen domU) and m68k-linux (ARAnyM) + + Signed-off-by: Thorsten Glaser -2005-03-30 Steve Ellcey +commit 8f4772f383abd71cfa141c8a70ba11c1aa4ebe2c +Author: Anthony Green +Date: Mon Jan 7 06:14:53 2013 -0500 - * src/ia64/ffitarget.h (ffi_arg) ADD DI attribute. - (ffi_sarg) Ditto. - * src/ia64/unix.S (ffi_closure_unix): Extend gp - to 64 bits in ILP32 mode. - Load 64 bits even for short data. + m68k fixes for signed 8 and 16-bit calls. -2005-03-23 Mike Stump +commit ea7f8440d58afbebb181e295ff564fdf3d6590a0 +Author: Anthony Green +Date: Fri Jan 4 09:09:32 2013 -0500 - * src/powerpc/darwin.S: Update for -m64 multilib. - * src/powerpc/darwin_closure.S: Likewise. + remove gcc-ism -2005-03-21 Zack Weinberg +commit f06c0f10377ac04eeba5e632dbe5c62c629df4e6 +Author: Anthony Green +Date: Wed Jan 2 09:39:17 2013 -0500 - * configure.ac: Do not invoke TL_AC_GCC_VERSION. - Do not set tool_include_dir. - * aclocal.m4, configure, Makefile.in, testsuite/Makefile.in: - Regenerate. - * include/Makefile.am: Set gcc_version and toollibffidir. - * include/Makefile.in: Regenerate. + Add missing ChangeLog entry and generated files. -2005-02-22 Andrew Haley +commit 1f8675d4c101d19d67ca0a55ff2ba973349558ad +Merge: 335f419 f6b58d2 +Author: Anthony Green +Date: Wed Jan 2 06:34:38 2013 -0800 - * src/powerpc/ffi.c (ffi_prep_cif_machdep): Bump alignment to - odd-numbered register pairs for 64-bit integer types. + Merge pull request #26 from rofl0r/master + + fix build error on ppc when long double == double -2005-02-23 Andreas Tobler +commit 335f419a86090cda9f215d149572f9481c3ad034 +Merge: 53236d5 6d6f711 +Author: Anthony Green +Date: Wed Jan 2 06:30:03 2013 -0800 - PR libffi/20104 - * testsuite/libffi.call/return_ll1.c: New test case. + Merge pull request #23 from rurban/master + + cygwin/mingw shared libs need libtool LDFLAGS = -no-undefined -2005-02-11 Janis Johnson +commit 53236d5061034cc0a7f4647fc1bd05ba1aeb3d2a +Author: Anthony Green +Date: Wed Jan 2 09:24:55 2013 -0500 - * testsuite/libffi.call/cls_align_longdouble.c: Remove dg-options. - * testsuite/libffi.call/float.c: Ditto. - * testsuite/libffi.call/float2.c: Ditto. - * testsuite/libffi.call/float3.c: Ditto. + Regenerate files -2005-02-08 Andreas Tobler +commit 72222ca3fbe560e13c8dc89ca441b28b7cc74daf +Author: Anthony Green +Date: Wed Jan 2 09:06:38 2013 -0500 - * src/frv/ffitarget.h: Remove PPC stuff which does not belong to frv. + Update texinfo.tex -2005-01-12 Eric Botcazou +commit 1e326c95431fc9896422fa36659f3e833852579c +Author: Anthony Green +Date: Wed Jan 2 09:05:02 2013 -0500 - * testsuite/libffi.special/special.exp (cxx_options): Add - -shared-libgcc. + Update config.guess and config.sub -2004-12-31 Richard Henderson +commit cb6671f5b8a9596ff968c6b6c304f70adf71b368 +Author: Anthony Green +Date: Wed Jan 2 08:56:07 2013 -0500 - * src/types.c (FFI_AGGREGATE_TYPEDEF): Remove. - (FFI_TYPEDEF): Rename from FFI_INTEGRAL_TYPEDEF. Replace size and - offset parameters with a type parameter; deduce size and structure - alignment. Update all users. + Missing .gitignore changes for xcode support -2004-12-31 Richard Henderson +commit ebbe77966855395a2a47ed2c09a38f93eb0481cf +Author: Anthony Green +Date: Wed Jan 2 08:54:05 2013 -0500 - * src/types.c (FFI_TYPE_POINTER): Define with sizeof. - (FFI_TYPE_LONGDOUBLE): Fix for ia64. - * src/ia64/ffitarget.h (struct ffi_ia64_trampoline_struct): Move - into ffi_prep_closure. - * src/ia64/ia64_flags.h, src/ia64/ffi.c, src/ia64/unix.S: Rewrite - from scratch. + missed x32 libtool patch. -2004-12-27 Richard Henderson +commit 4394096da0aca0dd422b479a043c18b4f05c5770 +Author: Anthony Green +Date: Wed Jan 2 08:51:35 2013 -0500 - * src/x86/unix64.S: Fix typo in unwind info. + missed trampoline_table patch. Move to GCC. -2004-12-25 Richard Henderson +commit ed7a59c3ff7c84bd95c374a5aff21599f705e6dc +Author: Anthony Green +Date: Wed Jan 2 08:48:01 2013 -0500 - * src/x86/ffi64.c (struct register_args): Rename from stackLayout. - (enum x86_64_reg_class): Add X86_64_COMPLEX_X87_CLASS. - (merge_classes): Check for it. - (SSE_CLASS_P): New. - (classify_argument): Pass byte_offset by value; perform all updates - inside struct case. - (examine_argument): Add classes argument; handle - X86_64_COMPLEX_X87_CLASS. - (ffi_prep_args): Merge into ... - (ffi_call): ... here. Share stack frame with ffi_call_unix64. - (ffi_prep_cif_machdep): Setup cif->flags for proper structure return. - (ffi_fill_return_value): Remove. - (ffi_prep_closure): Remove dead assert. - (ffi_closure_unix64_inner): Rename from ffi_closure_UNIX64_inner. - Rewrite to use struct register_args instead of va_list. Create - flags for handling structure returns. - * src/x86/unix64.S: Remove dead strings. - (ffi_call_unix64): Rename from ffi_call_UNIX64. Rewrite to share - stack frame with ffi_call. Handle structure returns properly. - (float2sse, floatfloat2sse, double2sse): Remove. - (sse2float, sse2double, sse2floatfloat): Remove. - (ffi_closure_unix64): Rename from ffi_closure_UNIX64. Rewrite - to handle structure returns properly. + Windows symbol export fix. Move to GCC. -2004-12-08 David Edelsohn +commit ccee09a4ff843b11c7d8b6819776f57d187305c7 +Author: Anthony Green +Date: Wed Jan 2 08:41:55 2013 -0500 - * Makefile.am (AM_MAKEFLAGS): Remove duplicate LIBCFLAGS and - PICFLAG. - * Makefile.in: Regenerated. + +2012-03-21 Peter Rosin + + + + * testsuite/lib/target-libpath.exp [*-*-cygwin*, *-*-mingw*] + + (set_ld_library_path_env_vars): Add the library search dir to PATH + + (and save PATH for later). + + (restore_ld_library_path_env_vars): Restore PATH. -2004-12-02 Richard Sandiford +commit 089dbce7cc0889eb26444d89ae062c73c69f26f0 +Author: Anthony Green +Date: Wed Jan 2 08:37:35 2013 -0500 - * configure.ac: Use TL_AC_GCC_VERSION to set gcc_version. - * configure, aclocal.m4, Makefile.in: Regenerate. - * include/Makefile.in, testsuite/Makefile.in: Regenerate. + med -2004-11-29 Kelley Cook +commit 980a334c42b4b0eff32e55929ec6727d1326b05d +Author: Anthony Green +Date: Wed Jan 2 07:36:42 2013 -0500 - * configure: Regenerate for libtool change. + Test GCC update -2004-11-25 Kelley Cook +commit 8bad679ade5000e57cdc9cacde22e8b99840930f +Author: Anthony Green +Date: Wed Jan 2 08:28:35 2013 -0500 - * configure: Regenerate for libtool reversion. + New stand-alone patch -2004-11-24 Kelley Cook +commit 981c32ee115e9f0d6546a74592875e138222a9d1 +Author: Anthony Green +Date: Wed Jan 2 07:34:03 2013 -0500 - * configure: Regenerate for libtool change. + Merge with GCC. Eliminate quilt bits. -2004-11-23 John David Anglin +commit 61a054929517fb80c437ba71c91f3e20cfff581a +Author: Anthony Green +Date: Wed Nov 28 06:07:41 2012 -0500 - * testsuite/lib/libffi-dg.exp: Use new procs in target-libpath.exp. + Refresh config.guess and config.sub -2004-11-23 Richard Sandiford +commit f6b58d2bdc0a24ce94dedce59802f091979df265 +Author: rofl0r +Date: Thu Nov 22 16:26:21 2012 +0100 - * src/mips/o32.S (ffi_call_O32, ffi_closure_O32): Use jalr instead - of jal. Use an absolute encoding for the frame information. + fix build on ppc when long double == double -2004-11-23 Kelley Cook +commit 69da33a0761aeac73f9e9646269da61c906d6020 +Author: Anthony Green +Date: Mon Nov 12 15:25:47 2012 -0500 - * Makefile.am: Remove no-dependencies. Add ACLOCAL_AMFLAGS. - * acinclude.m4: Delete logic for sincludes. - * aclocal.m4, Makefile.in, configure: Regenerate. - * include/Makefile: Likewise. - * testsuite/Makefile: Likewise. + Pull in config.sub for aarch64 support and more -2004-11-22 Eric Botcazou +commit f680b598b7bdde325ac9349e8c35151c228bf2df +Author: Anthony Green +Date: Tue Nov 6 16:00:40 2012 -0500 - * src/sparc/ffi.c (ffi_prep_closure): Align doubles and 64-bit integers - on a 8-byte boundary. - * src/sparc/v8.S (ffi_closure_v8): Reserve frame space for arguments. + Add missing aarch64 configury bits -2004-10-27 Richard Earnshaw +commit dfadfb19853c57c8623c436d0ef2bdafab24b433 +Author: Anthony Green +Date: Wed Oct 31 06:46:41 2012 -0400 - * src/arm/ffi.c (ffi_prep_cif_machdep): Handle functions that return - long long values. Round stack allocation to a multiple of 8 bytes - for ATPCS compatibility. - * src/arm/sysv.S (ffi_call_SYSV): Rework to avoid use of APCS register - names. Handle returning long long types. Add Thumb and interworking - support. Improve soft-float code. + Rebase for ppc64 fix -2004-10-27 Richard Earnshaw +commit e944b8c7eb1e2eeb9c0f3b9742b4d7f476860ce1 +Author: Anthony Green +Date: Tue Oct 30 14:06:09 2012 -0400 - * testsuite/lib/libffi-db.exp (load_gcc_lib): New function. - (libffi_exit): New function. - (libffi_init): Build the testglue wrapper if needed. + Add PaX work-around -2004-10-25 Eric Botcazou +commit 9ccd51be1fdeb99f8b4f42f905166c2abbba8ac0 +Merge: f342996 fa5d747 +Author: Anthony Green +Date: Tue Oct 30 13:37:37 2012 -0400 - PR other/18138 - * testsuite/lib/libffi-dg.exp: Accept more than one multilib libgcc. + Fix commit conflicts -2004-10-25 Kazuhiro Inaoka +commit f342996cb50eb23b868afcff5ac0cdbb6b505d63 +Author: Anthony Green +Date: Tue Oct 30 07:42:27 2012 -0400 - * src/m32r/libffitarget.h (FFI_CLOSURES): Set to 0. + Darwin12 fix -2004-10-20 Kaz Kojima +commit 58e8b66f70cef2e3c9b0e5a707b45d634cbbf5d9 +Author: Anthony Green +Date: Tue Oct 30 07:07:19 2012 -0400 - * src/sh/sysv.S (ffi_call_SYSV): Don't align for double data. - * testsuite/libffi.call/float3.c: New test case. - -2004-10-18 Kaz Kojima - - * src/sh/ffi.c (ffi_prep_closure): Set T bit in trampoline for - the function returning a structure pointed with R2. - * src/sh/sysv.S (ffi_closure_SYSV): Use R2 as the pointer to - the structure return value if T bit set. Emit position - independent code and EH data if PIC. - -2004-10-13 Kazuhiro Inaoka - - * Makefile.am: Add m32r support. - * configure.ac: Likewise. - * Makefile.in: Regenerate. - * confiugre: Regenerate. - * src/types.c: Add m32r port to FFI_INTERNAL_TYPEDEF - (uint64, sint64, double, longdouble) - * src/m32r: New directory. - * src/m32r/ffi.c: New file. - * src/m32r/sysv.S: Likewise. - * src/m32r/ffitarget.h: Likewise. - -2004-10-02 Kaz Kojima - - * testsuite/libffi.call/negint.c: New test case. - -2004-09-14 H.J. Lu - - PR libgcj/17465 - * testsuite/lib/libffi-dg.exp: Don't use global ld_library_path. - Set up LD_LIBRARY_PATH, SHLIB_PATH, LD_LIBRARYN32_PATH, - LD_LIBRARY64_PATH, LD_LIBRARY_PATH_32, LD_LIBRARY_PATH_64 and - DYLD_LIBRARY_PATH. - -2004-09-05 Andreas Tobler - - * testsuite/libffi.call/many_win32.c: Remove whitespaces. - * testsuite/libffi.call/promotion.c: Likewise. - * testsuite/libffi.call/return_ll.c: Remove unused var. Cleanup - whitespaces. - * testsuite/libffi.call/return_sc.c: Likewise. - * testsuite/libffi.call/return_uc.c: Likewise. - -2004-09-05 Andreas Tobler - - * src/powerpc/darwin.S: Fix comments and identation. - * src/powerpc/darwin_closure.S: Likewise. - -2004-09-02 Andreas Tobler - - * src/powerpc/ffi_darwin.c: Add flag for longdouble return values. - (ffi_prep_args): Handle longdouble arguments. - (ffi_prep_cif_machdep): Set flags for longdouble. Calculate space for - longdouble. - (ffi_closure_helper_DARWIN): Add closure handling for longdouble. - * src/powerpc/darwin.S (_ffi_call_DARWIN): Add handling of longdouble - values. - * src/powerpc/darwin_closure.S (_ffi_closure_ASM): Likewise. - * src/types.c: Defined longdouble size and alignment for darwin. - -2004-09-02 Andreas Tobler - - * src/powerpc/aix.S: Remove whitespaces. - * src/powerpc/aix_closure.S: Likewise. - * src/powerpc/asm.h: Likewise. - * src/powerpc/ffi.c: Likewise. - * src/powerpc/ffitarget.h: Likewise. - * src/powerpc/linux64.S: Likewise. - * src/powerpc/linux64_closure.S: Likewise. - * src/powerpc/ppc_closure.S: Likewise. - * src/powerpc/sysv.S: Likewise. - -2004-08-30 Anthony Green - - * Makefile.am: Add frv support. - * Makefile.in, testsuite/Makefile.in: Rebuilt. - * configure.ac: Read configure.host. - * configure.in: Read configure.host. - * configure.host: New file. frv-elf needs libgloss. - * include/ffi.h.in: Force ffi_closure to have a nice big (8) - alignment. This is needed to frv and shouldn't harm the others. - * include/ffi_common.h (ALIGN_DOWN): New macro. - * src/frv/ffi.c, src/frv/ffitarget.h, src/frv/eabi.S: New files. - -2004-08-24 David Daney - - * testsuite/libffi.call/closure_fn0.c: Xfail mips64* instead of mips*. - * testsuite/libffi.call/closure_fn1.c: Likewise. - * testsuite/libffi.call/closure_fn2.c Likewise. - * testsuite/libffi.call/closure_fn3.c: Likewise. - * testsuite/libffi.call/closure_fn4.c: Likewise. - * testsuite/libffi.call/closure_fn5.c: Likewise. - * testsuite/libffi.call/cls_18byte.c: Likewise. - * testsuite/libffi.call/cls_19byte.c: Likewise. - * testsuite/libffi.call/cls_1_1byte.c: Likewise. - * testsuite/libffi.call/cls_20byte.c: Likewise. - * testsuite/libffi.call/cls_20byte1.c: Likewise. - * testsuite/libffi.call/cls_24byte.c: Likewise. - * testsuite/libffi.call/cls_2byte.c: Likewise. - * testsuite/libffi.call/cls_3_1byte.c: Likewise. - * testsuite/libffi.call/cls_3byte1.c: Likewise. - * testsuite/libffi.call/cls_3byte2.c: Likewise. - * testsuite/libffi.call/cls_4_1byte.c: Likewise. - * testsuite/libffi.call/cls_4byte.c: Likewise. - * testsuite/libffi.call/cls_64byte.c: Likewise. - * testsuite/libffi.call/cls_6byte.c: Likewise. - * testsuite/libffi.call/cls_7byte.c: Likewise. - * testsuite/libffi.call/cls_8byte.c: Likewise. - * testsuite/libffi.call/cls_9byte1.c: Likewise. - * testsuite/libffi.call/cls_9byte2.c: Likewise. - * testsuite/libffi.call/cls_align_double.c: Likewise. - * testsuite/libffi.call/cls_align_float.c: Likewise. - * testsuite/libffi.call/cls_align_longdouble.c: Likewise. - * testsuite/libffi.call/cls_align_pointer.c: Likewise. - * testsuite/libffi.call/cls_align_sint16.c: Likewise. - * testsuite/libffi.call/cls_align_sint32.c: Likewise. - * testsuite/libffi.call/cls_align_sint64.c: Likewise. - * testsuite/libffi.call/cls_align_uint16.c: Likewise. - * testsuite/libffi.call/cls_align_uint32.c: Likewise. - * testsuite/libffi.call/cls_align_uint64.c: Likewise. - * testsuite/libffi.call/cls_double.c: Likewise. - * testsuite/libffi.call/cls_float.c: Likewise. - * testsuite/libffi.call/cls_multi_schar.c: Likewise. - * testsuite/libffi.call/cls_multi_sshort.c: Likewise. - * testsuite/libffi.call/cls_multi_sshortchar.c: Likewise. - * testsuite/libffi.call/cls_multi_uchar.c: Likewise. - * testsuite/libffi.call/cls_multi_ushort.c: Likewise. - * testsuite/libffi.call/cls_multi_ushortchar.c: Likewise. - * testsuite/libffi.call/cls_schar.c: Likewise. - * testsuite/libffi.call/cls_sint.c: Likewise. - * testsuite/libffi.call/cls_sshort.c: Likewise. - * testsuite/libffi.call/cls_uchar.c: Likewise. - * testsuite/libffi.call/cls_uint.c: Likewise. - * testsuite/libffi.call/cls_ulonglong.c: Likewise. - * testsuite/libffi.call/cls_ushort.c: Likewise. - * testsuite/libffi.call/nested_struct.c: Likewise. - * testsuite/libffi.call/nested_struct1.c: Likewise. - * testsuite/libffi.call/nested_struct2.c: Likewise. - * testsuite/libffi.call/nested_struct3.c: Likewise. - * testsuite/libffi.call/problem1.c: Likewise. - * testsuite/libffi.special/unwindtest.cc: Likewise. - * testsuite/libffi.call/cls_12byte.c: Likewise and set return value - to zero. - * testsuite/libffi.call/cls_16byte.c: Likewise. - * testsuite/libffi.call/cls_5byte.c: Likewise. - -2004-08-23 David Daney - - PR libgcj/13141 - * src/mips/ffitarget.h (FFI_O32_SOFT_FLOAT): New ABI. - * src/mips/ffi.c (ffi_prep_args): Fix alignment calculation. - (ffi_prep_cif_machdep): Handle FFI_O32_SOFT_FLOAT floating point - parameters and return types. - (ffi_call): Handle FFI_O32_SOFT_FLOAT ABI. - (ffi_prep_closure): Ditto. - (ffi_closure_mips_inner_O32): Handle FFI_O32_SOFT_FLOAT ABI, fix - alignment calculations. - * src/mips/o32.S (ffi_closure_O32): Don't use floating point - instructions if FFI_O32_SOFT_FLOAT, make stack frame ABI compliant. - -2004-08-14 Casey Marshall - - * src/mips/ffi.c (ffi_pref_cif_machdep): set `cif->flags' to - contain `FFI_TYPE_UINT64' as return type for any 64-bit - integer (O32 ABI only). - (ffi_prep_closure): new function. - (ffi_closure_mips_inner_O32): new function. - * src/mips/ffitarget.h: Define `FFI_CLOSURES' and - `FFI_TRAMPOLINE_SIZE' appropriately if the ABI is o32. - * src/mips/o32.S (ffi_call_O32): add labels for .eh_frame. Return - 64 bit integers correctly. - (ffi_closure_O32): new function. - Added DWARF-2 unwind info for both functions. - -2004-08-10 Andrew Haley - - * src/x86/ffi64.c (ffi_prep_args ): 8-align all stack arguments. - -2004-08-01 Robert Millan - - * configure.ac: Detect knetbsd-gnu and kfreebsd-gnu. - * configure: Regenerate. - -2004-07-30 Maciej W. Rozycki - - * acinclude.m4 (AC_FUNC_MMAP_BLACKLIST): Check for - and mmap() explicitly instead of relying on preset autoconf cache - variables. - * aclocal.m4: Regenerate. - * configure: Regenerate. - -2004-07-11 Ulrich Weigand - - * src/s390/ffi.c (ffi_prep_args): Fix C aliasing violation. - (ffi_check_float_struct): Remove unused prototype. - -2004-06-30 Geoffrey Keating - - * src/powerpc/ffi_darwin.c (flush_icache): ';' is a comment - character on Darwin, use '\n\t' instead. - -2004-06-26 Matthias Klose - - * libtool-version: Fix typo in revision/age. - -2004-06-17 Matthias Klose - - * libtool-version: New. - * Makefile.am (libffi_la_LDFLAGS): Use -version-info for soname. - * Makefile.in: Regenerate. - -2004-06-15 Paolo Bonzini - - * Makefile.am: Remove useless multilib rules. - * Makefile.in: Regenerate. - * aclocal.m4: Regenerate with automake 1.8.5. - * configure.ac: Remove useless multilib configury. - * configure: Regenerate. - -2004-06-15 Paolo Bonzini - - * .cvsignore: New file. - -2004-06-10 Jakub Jelinek - - * src/ia64/unix.S (ffi_call_unix): Insert group barrier break - fp_done. - (ffi_closure_UNIX): Fix f14/f15 adjustment if FLOAT_SZ is ever - changed from 8. - -2004-06-06 Sean McNeil - - * configure.ac: Add x86_64-*-freebsd* support. - * configure: Regenerate. + AArch64 port -2004-04-26 Joe Buck +commit fa5d747905472571fd472c07d4726017624f66b3 +Author: Anthony Green +Date: Tue Oct 30 07:07:19 2012 -0400 - Bug 15093 - * configure.ac: Test for existence of mmap and sys/mman.h before - checking blacklist. Fix suggested by Jim Wilson. - * configure: Regenerate. + AArch64 port -2004-04-26 Matt Austern +commit 6993a6686f43f2313b18142c1e96189a27db2aa3 +Author: Anthony Green +Date: Tue Oct 30 06:59:32 2012 -0400 - * src/powerpc/darwin.S: Go through a non-lazy pointer for initial - FDE location. - * src/powerpc/darwin_closure.S: Likewise. + Fix autoconf macros -2004-04-24 Andreas Tobler +commit 70084e70ddb13b29dd05c751b1904de206bbe790 +Author: Anthony Green +Date: Fri Oct 12 23:55:06 2012 -0400 - * testsuite/libffi.call/cls_multi_schar.c (main): Fix initialization - error. Reported by Thomas Heller . - * testsuite/libffi.call/cls_multi_sshort.c (main): Likewise. - * testsuite/libffi.call/cls_multi_ushort.c (main): Likewise. + Update Tile* port info -2004-03-20 Matthias Klose +commit 9c00a3f6742d61404b31268cc773e7130ff43331 +Author: Anthony Green +Date: Fri Oct 12 16:46:06 2012 -0400 - * src/pa/linux.S: Fix typo. + TILE-Gx/TILEPro support -2004-03-19 Matthias Klose +commit 048d2f41c3a6664b4b64bf21e804686662da4160 +Author: Anthony Green +Date: Thu Oct 11 10:55:25 2012 -0400 - * Makefile.am: Update. - * Makefile.in: Regenerate. - * src/pa/ffi.h.in: Remove. - * src/pa/ffitarget.h: New file. + Rebase -2004-02-10 Randolph Chung +commit 6d6f71108064f5069edd7bf771059d3b82640135 +Author: Reini Urban +Date: Sat Jul 7 12:42:00 2012 -0500 - * Makefile.am: Add PA support. - * Makefile.in: Regenerate. - * include/Makefile.in: Regenerate. - * configure.ac: Add PA target. - * configure: Regenerate. - * src/pa/ffi.c: New file. - * src/pa/ffi.h.in: Add PA support. - * src/pa/linux.S: New file. - * prep_cif.c: Add PA support. + cygwin/mingw shared libs need libtool LDFLAGS = -no-undefined + + otherwise only static libs are created. -2004-03-16 Hosaka Yuji +commit d330f19292da8f39a78a9e2b0ba08df8094e3bc5 +Author: Nicolas Lelong +Date: Sat May 5 09:37:02 2012 -0400 - * src/types.c: Fix alignment size of X86_WIN32 case int64 and - double. - * src/x86/ffi.c (ffi_prep_args): Replace ecif->cif->rtype->type - with ecif->cif->flags. - (ffi_call, ffi_prep_incoming_args_SYSV): Replace cif->rtype->type - with cif->flags. - (ffi_prep_cif_machdep): Add X86_WIN32 struct case. - (ffi_closure_SYSV): Add 1 or 2-bytes struct case for X86_WIN32. - * src/x86/win32.S (retstruct1b, retstruct2b, sc_retstruct1b, - sc_retstruct2b): Add for 1 or 2-bytes struct case. + iOS build fixes. -2004-03-15 Kelley Cook +commit 09b23cfc1d6d15361eee18818851fd3cacb26559 +Author: Anthony Green +Date: Fri Apr 27 08:29:48 2012 -0400 - * configure.in: Rename file to ... - * configure.ac: ... this. - * fficonfig.h.in: Regenerate. - * Makefile.in: Regenerate. - * include/Makefile.in: Regenerate. - * testsuite/Makefile.in: Regenerate. - -2004-03-12 Matt Austern - - * src/powerpc/darwin.S: Fix EH information so it corresponds to - changes in EH format resulting from addition of linkonce support. - * src/powerpc/darwin_closure.S: Likewise. - -2004-03-11 Andreas Tobler - Paolo Bonzini - - * Makefile.am (AUTOMAKE_OPTIONS): Set them. - Remove VPATH. Remove rules for object files. Remove multilib support. - (AM_CCASFLAGS): Add. - * configure.in (AC_CONFIG_HEADERS): Relace AM_CONFIG_HEADER. - (AC_PREREQ): Bump version to 2.59. - (AC_INIT): Fill with version info and bug address. - (ORIGINAL_LD_FOR_MULTILIBS): Remove. - (AM_ENABLE_MULTILIB): Use this instead of AC_ARG_ENABLE. - De-precious CC so that the right flags are passed down to multilibs. - (AC_MSG_ERROR): Replace obsolete macro AC_ERROR. - (AC_CONFIG_FILES): Replace obsolete macro AC_LINK_FILES. - (AC_OUTPUT): Reorganize the output with AC_CONFIG_COMMANDS. - * configure: Rebuilt. - * aclocal.m4: Likewise. - * Makefile.in, include/Makefile.in, testsuite/Makefile.in: Likewise. - * fficonfig.h.in: Likewise. - -2004-03-11 Andreas Schwab - - * src/ia64/ffi.c (ffi_prep_incoming_args_UNIX): Get floating point - arguments from fp registers only for the first 8 parameter slots. - Don't convert a float parameter when passed in memory. + Update README with Blackfin/uClinux support -2004-03-09 Hans-Peter Nilsson - - * configure: Regenerate for config/accross.m4 correction. - -2004-02-25 Matt Kraai - - * src/powerpc/ffi.c (ffi_prep_args_SYSV): Change - ecif->cif->bytes to bytes. - (ffi_prep_cif_machdep): Add braces around nested if statement. - -2004-02-09 Alan Modra - - * src/types.c (pointer): POWERPC64 has 8 byte pointers. - - * src/powerpc/ffi.c (ffi_prep_args64): Correct long double handling. - (ffi_closure_helper_LINUX64): Fix typo. - * testsuite/libffi.call/cls_align_longdouble.c: Pass -mlong-double-128 - for powerpc64-*-*. - * testsuite/libffi.call/float.c: Likewise. - * testsuite/libffi.call/float2.c: Likewise. - -2004-02-08 Alan Modra - - * src/powerpc/ffi.c (ffi_prep_cif_machdep ): Correct - long double function return and long double arg handling. - (ffi_closure_helper_LINUX64): Formatting. Delete unused "ng" var. - Use "end_pfr" instead of "nf". Correct long double handling. - Localise "temp". - * src/powerpc/linux64.S (ffi_call_LINUX64): Save f2 long double - return value. - * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Allocate - space for long double return value. Adjust stack frame and offsets. - Load f2 long double return. - -2004-02-07 Alan Modra - - * src/types.c: Use 16 byte long double for POWERPC64. - -2004-01-25 Eric Botcazou - - * src/sparc/ffi.c (ffi_prep_args_v9): Shift the parameter array - when the structure return address is passed in %o0. - (ffi_V9_return_struct): Rename into ffi_v9_layout_struct. - (ffi_v9_layout_struct): Align the field following a nested structure - on a word boundary. Use memmove instead of memcpy. - (ffi_call): Update call to ffi_V9_return_struct. - (ffi_prep_closure): Define 'ctx' only for V8. - (ffi_closure_sparc_inner): Clone into ffi_closure_sparc_inner_v8 - and ffi_closure_sparc_inner_v9. - (ffi_closure_sparc_inner_v8): Return long doubles by reference. - Always skip the structure return address. For structures and long - doubles, copy the argument directly. - (ffi_closure_sparc_inner_v9): Skip the structure return address only - if required. Shift the maximum floating-point slot accordingly. For - big structures, copy the argument directly; otherwise, left-justify the - argument and call ffi_v9_layout_struct to lay out the structure on - the stack. - * src/sparc/v8.S: Undef STACKFRAME before defining it. - (ffi_closure_v8): Pass the structure return address. Update call to - ffi_closure_sparc_inner_v8. Short-circuit FFI_TYPE_INT handling. - Skip the 'unimp' insn when returning long doubles and structures. - * src/sparc/v9.S: Undef STACKFRAME before defining it. - (ffi_closure_v9): Increase the frame size by 2 words. Short-circuit - FFI_TYPE_INT handling. Load structures both in integers and - floating-point registers on return. - * README: Update status of the SPARC port. - -2004-01-24 Andreas Tobler - - * testsuite/libffi.call/pyobjc-tc.c (main): Treat result value - as of type ffi_arg. - * testsuite/libffi.call/struct3.c (main): Fix CHECK. - -2004-01-22 Ulrich Weigand - - * testsuite/libffi.call/cls_uint.c (cls_ret_uint_fn): Treat result - value as of type ffi_arg, not unsigned int. - -2004-01-21 Michael Ritzert - - * ffi64.c (ffi_prep_args): Cast the RHS of an assignment instead - of the LHS. - -2004-01-12 Andreas Tobler - - * testsuite/lib/libffi-dg.exp: Set LD_LIBRARY_PATH_32 for - Solaris. - -2004-01-08 Rainer Orth - - * testsuite/libffi.call/ffitest.h (allocate_mmap): Cast MAP_FAILED - to void *. - -2003-12-10 Richard Henderson - - * testsuite/libffi.call/cls_align_pointer.c: Cast pointers to - size_t instead of int. - -2003-12-04 Hosaka Yuji - - * testsuite/libffi.call/many_win32.c: Include . - * testsuite/libffi.call/many_win32.c (main): Replace variable - int i with unsigned long ul. - - * testsuite/libffi.call/cls_align_uint64.c: New test case. - * testsuite/libffi.call/cls_align_sint64.c: Likewise. - * testsuite/libffi.call/cls_align_uint32.c: Likewise. - * testsuite/libffi.call/cls_align_sint32.c: Likewise. - * testsuite/libffi.call/cls_align_uint16.c: Likewise. - * testsuite/libffi.call/cls_align_sint16.c: Likewise. - * testsuite/libffi.call/cls_align_float.c: Likewise. - * testsuite/libffi.call/cls_align_double.c: Likewise. - * testsuite/libffi.call/cls_align_longdouble.c: Likewise. - * testsuite/libffi.call/cls_align_pointer.c: Likewise. - -2003-12-02 Hosaka Yuji - - PR other/13221 - * src/x86/ffi.c (ffi_prep_args, ffi_prep_incoming_args_SYSV): - Align arguments to 32 bits. - -2003-12-01 Andreas Tobler - - PR other/13221 - * testsuite/libffi.call/cls_multi_sshort.c: New test case. - * testsuite/libffi.call/cls_multi_sshortchar.c: Likewise. - * testsuite/libffi.call/cls_multi_uchar.c: Likewise. - * testsuite/libffi.call/cls_multi_schar.c: Likewise. - * testsuite/libffi.call/cls_multi_ushortchar.c: Likewise. - * testsuite/libffi.call/cls_multi_ushort.c: Likewise. - - * testsuite/libffi.special/unwindtest.cc: Cosmetics. - -2003-11-26 Kaveh R. Ghazi - - * testsuite/libffi.call/ffitest.h: Include . - * testsuite/libffi.special/ffitestcxx.h: Likewise. - -2003-11-22 Andreas Tobler - - * Makefile.in: Rebuilt. - * configure: Likewise. - * testsuite/libffi.special/unwindtest.cc: Convert the mmap to - the right type. - -2003-11-21 Andreas Jaeger - Andreas Tobler - - * acinclude.m4: Add AC_FUNC_MMAP_BLACKLIST. - * configure.in: Call AC_FUNC_MMAP_BLACKLIST. - * Makefile.in: Rebuilt. - * aclocal.m4: Likewise. - * configure: Likewise. - * fficonfig.h.in: Likewise. - * testsuite/lib/libffi-dg.exp: Add include dir. - * testsuite/libffi.call/ffitest.h: Add MMAP definitions. - * testsuite/libffi.special/ffitestcxx.h: Likewise. - * testsuite/libffi.call/closure_fn0.c: Use MMAP functionality - for ffi_closure if available. - * testsuite/libffi.call/closure_fn1.c: Likewise. - * testsuite/libffi.call/closure_fn2.c: Likewise. - * testsuite/libffi.call/closure_fn3.c: Likewise. - * testsuite/libffi.call/closure_fn4.c: Likewise. - * testsuite/libffi.call/closure_fn5.c: Likewise. - * testsuite/libffi.call/cls_12byte.c: Likewise. - * testsuite/libffi.call/cls_16byte.c: Likewise. - * testsuite/libffi.call/cls_18byte.c: Likewise. - * testsuite/libffi.call/cls_19byte.c: Likewise. - * testsuite/libffi.call/cls_1_1byte.c: Likewise. - * testsuite/libffi.call/cls_20byte.c: Likewise. - * testsuite/libffi.call/cls_20byte1.c: Likewise. - * testsuite/libffi.call/cls_24byte.c: Likewise. - * testsuite/libffi.call/cls_2byte.c: Likewise. - * testsuite/libffi.call/cls_3_1byte.c: Likewise. - * testsuite/libffi.call/cls_3byte1.c: Likewise. - * testsuite/libffi.call/cls_3byte2.c: Likewise. - * testsuite/libffi.call/cls_4_1byte.c: Likewise. - * testsuite/libffi.call/cls_4byte.c: Likewise. - * testsuite/libffi.call/cls_5byte.c: Likewise. - * testsuite/libffi.call/cls_64byte.c: Likewise. - * testsuite/libffi.call/cls_6byte.c: Likewise. - * testsuite/libffi.call/cls_7byte.c: Likewise. - * testsuite/libffi.call/cls_8byte.c: Likewise. - * testsuite/libffi.call/cls_9byte1.c: Likewise. - * testsuite/libffi.call/cls_9byte2.c: Likewise. - * testsuite/libffi.call/cls_double.c: Likewise. - * testsuite/libffi.call/cls_float.c: Likewise. - * testsuite/libffi.call/cls_schar.c: Likewise. - * testsuite/libffi.call/cls_sint.c: Likewise. - * testsuite/libffi.call/cls_sshort.c: Likewise. - * testsuite/libffi.call/cls_uchar.c: Likewise. - * testsuite/libffi.call/cls_uint.c: Likewise. - * testsuite/libffi.call/cls_ulonglong.c: Likewise. - * testsuite/libffi.call/cls_ushort.c: Likewise. - * testsuite/libffi.call/nested_struct.c: Likewise. - * testsuite/libffi.call/nested_struct1.c: Likewise. - * testsuite/libffi.call/nested_struct2.c: Likewise. - * testsuite/libffi.call/nested_struct3.c: Likewise. - * testsuite/libffi.call/problem1.c: Likewise. - * testsuite/libffi.special/unwindtest.cc: Likewise. - -2003-11-20 Andreas Tobler - - * testsuite/lib/libffi-dg.exp: Make the -lgcc_s conditional. - -2003-11-19 Andreas Tobler - - * testsuite/lib/libffi-dg.exp: Add DYLD_LIBRARY_PATH for darwin. - Add -lgcc_s to additional flags. - -2003-11-12 Andreas Tobler - - * configure.in, include/Makefile.am: PR libgcj/11147, install - the ffitarget.h header file in a gcc versioned and target - dependent place. - * configure: Regenerated. - * Makefile.in, include/Makefile.in: Likewise. - * testsuite/Makefile.in: Likewise. - -2003-11-09 Andreas Tobler - - * testsuite/libffi.call/closure_fn0.c: Print result and check - with dg-output to make debugging easier. - * testsuite/libffi.call/closure_fn1.c: Likewise. - * testsuite/libffi.call/closure_fn2.c: Likewise. - * testsuite/libffi.call/closure_fn3.c: Likewise. - * testsuite/libffi.call/closure_fn4.c: Likewise. - * testsuite/libffi.call/closure_fn5.c: Likewise. - * testsuite/libffi.call/cls_12byte.c: Likewise. - * testsuite/libffi.call/cls_16byte.c: Likewise. - * testsuite/libffi.call/cls_18byte.c: Likewise. - * testsuite/libffi.call/cls_19byte.c: Likewise. - * testsuite/libffi.call/cls_1_1byte.c: Likewise. - * testsuite/libffi.call/cls_20byte.c: Likewise. - * testsuite/libffi.call/cls_20byte1.c: Likewise. - * testsuite/libffi.call/cls_24byte.c: Likewise. - * testsuite/libffi.call/cls_2byte.c: Likewise. - * testsuite/libffi.call/cls_3_1byte.c: Likewise. - * testsuite/libffi.call/cls_3byte1.c: Likewise. - * testsuite/libffi.call/cls_3byte2.c: Likewise. - * testsuite/libffi.call/cls_4_1byte.c: Likewise. - * testsuite/libffi.call/cls_4byte.c: Likewise. - * testsuite/libffi.call/cls_5byte.c: Likewise. - * testsuite/libffi.call/cls_64byte.c: Likewise. - * testsuite/libffi.call/cls_6byte.c: Likewise. - * testsuite/libffi.call/cls_7byte.c: Likewise. - * testsuite/libffi.call/cls_8byte.c: Likewise. - * testsuite/libffi.call/cls_9byte1.c: Likewise. - * testsuite/libffi.call/cls_9byte2.c: Likewise. - * testsuite/libffi.call/cls_double.c: Likewise. - * testsuite/libffi.call/cls_float.c: Likewise. - * testsuite/libffi.call/cls_schar.c: Likewise. - * testsuite/libffi.call/cls_sint.c: Likewise. - * testsuite/libffi.call/cls_sshort.c: Likewise. - * testsuite/libffi.call/cls_uchar.c: Likewise. - * testsuite/libffi.call/cls_uint.c: Likewise. - * testsuite/libffi.call/cls_ulonglong.c: Likewise. - * testsuite/libffi.call/cls_ushort.c: Likewise. - * testsuite/libffi.call/problem1.c: Likewise. - - * testsuite/libffi.special/unwindtest.cc: Make ffi_closure - static. - -2003-11-08 Andreas Tobler - - * testsuite/libffi.call/cls_9byte2.c: New test case. - * testsuite/libffi.call/cls_9byte1.c: Likewise. - * testsuite/libffi.call/cls_64byte.c: Likewise. - * testsuite/libffi.call/cls_20byte1.c: Likewise. - * testsuite/libffi.call/cls_19byte.c: Likewise. - * testsuite/libffi.call/cls_18byte.c: Likewise. - * testsuite/libffi.call/closure_fn4.c: Likewise. - * testsuite/libffi.call/closure_fn5.c: Likewise. - * testsuite/libffi.call/cls_schar.c: Likewise. - * testsuite/libffi.call/cls_sint.c: Likewise. - * testsuite/libffi.call/cls_sshort.c: Likewise. - * testsuite/libffi.call/nested_struct2.c: Likewise. - * testsuite/libffi.call/nested_struct3.c: Likewise. - -2003-11-08 Andreas Tobler - - * testsuite/libffi.call/cls_double.c: Do a check on the result. - * testsuite/libffi.call/cls_uchar.c: Likewise. - * testsuite/libffi.call/cls_uint.c: Likewise. - * testsuite/libffi.call/cls_ulonglong.c: Likewise. - * testsuite/libffi.call/cls_ushort.c: Likewise. - * testsuite/libffi.call/return_sc.c: Cleanup whitespaces. - -2003-11-06 Andreas Tobler - - * src/prep_cif.c (ffi_prep_cif): Move the validity check after - the initialization. - -2003-10-23 Andreas Tobler - - * src/java_raw_api.c (ffi_java_ptrarray_to_raw): Replace - FFI_ASSERT(FALSE) with FFI_ASSERT(0). - -2003-10-22 David Daney - - * src/mips/ffitarget.h: Replace undefined UINT32 and friends with - __attribute__((__mode__(__SI__))) and friends. - -2003-10-22 Andreas Schwab - - * src/ia64/ffi.c: Replace FALSE/TRUE with false/true. - -2003-10-21 Andreas Tobler - - * configure.in: AC_LINK_FILES(ffitarget.h). - * configure: Regenerate. - * Makefile.in: Likewise. - * include/Makefile.in: Likewise. - * testsuite/Makefile.in: Likewise. - * fficonfig.h.in: Likewise. - -2003-10-21 Paolo Bonzini - Richard Henderson - - Avoid that ffi.h includes fficonfig.h. - - * Makefile.am (EXTRA_DIST): Include ffitarget.h files - (TARGET_SRC_MIPS_GCC): Renamed to TARGET_SRC_MIPS_IRIX. - (TARGET_SRC_MIPS_SGI): Removed. - (MIPS_GCC): Renamed to TARGET_SRC_MIPS_IRIX. - (MIPS_SGI): Removed. - (CLEANFILES): Removed. - (mostlyclean-am, clean-am, mostlyclean-sub, clean-sub): New - targets. - * acconfig.h: Removed. - * configure.in: Compute sizeofs only for double and long double. - Use them to define and subst HAVE_LONG_DOUBLE. Include comments - into AC_DEFINE instead of using acconfig.h. Create - include/ffitarget.h instead of include/fficonfig.h. Rename - MIPS_GCC to MIPS_IRIX, drop MIPS_SGI since we are in gcc's tree. - AC_DEFINE EH_FRAME_FLAGS. - * include/Makefile.am (DISTCLEANFILES): New automake macro. - (hack_DATA): Add ffitarget.h. - * include/ffi.h.in: Remove all system specific definitions. - Declare raw API even if it is not installed, why bother? - Use limits.h instead of SIZEOF_* to define ffi_type_*. Do - not define EH_FRAME_FLAGS, it is in fficonfig.h now. Include - ffitarget.h instead of fficonfig.h. Remove ALIGN macro. - (UINT_ARG, INT_ARG): Removed, use ffi_arg and ffi_sarg instead. - * include/ffi_common.h (bool): Do not define. - (ffi_assert): Accept failed assertion. - (ffi_type_test): Return void and accept file/line. - (FFI_ASSERT): Pass stringized failed assertion. - (FFI_ASSERT_AT): New macro. - (FFI_ASSERT_VALID_TYPE): New macro. - (UINT8, SINT8, UINT16, SINT16, UINT32, SINT32, - UINT64, SINT64): Define here with gcc's __attribute__ macro - instead of in ffi.h - (FLOAT32, ALIGN): Define here instead of in ffi.h - * include/ffi-mips.h: Removed. Its content moved to - src/mips/ffitarget.h after separating assembly and C sections. - * src/alpha/ffi.c, src/alpha/ffi.c, src/java_raw_api.c - src/prep_cif.c, src/raw_api.c, src/ia64/ffi.c, - src/mips/ffi.c, src/mips/n32.S, src/mips/o32.S, - src/mips/ffitarget.h, src/sparc/ffi.c, src/x86/ffi64.c: - SIZEOF_ARG -> FFI_SIZEOF_ARG. - * src/ia64/ffi.c: Include stdbool.h (provided by GCC 2.95+). - * src/debug.c (ffi_assert): Accept stringized failed assertion. - (ffi_type_test): Rewritten. - * src/prep-cif.c (initialize_aggregate, ffi_prep_cif): Call - FFI_ASSERT_VALID_TYPE. - * src/alpha/ffitarget.h, src/arm/ffitarget.h, - src/ia64/ffitarget.h, src/m68k/ffitarget.h, - src/mips/ffitarget.h, src/powerpc/ffitarget.h, - src/s390/ffitarget.h, src/sh/ffitarget.h, - src/sh64/ffitarget.h, src/sparc/ffitarget.h, - src/x86/ffitarget.h: New files. - * src/alpha/osf.S, src/arm/sysv.S, src/ia64/unix.S, - src/m68k/sysv.S, src/mips/n32.S, src/mips/o32.S, - src/powerpc/aix.S, src/powerpc/darwin.S, - src/powerpc/ffi_darwin.c, src/powerpc/linux64.S, - src/powerpc/linux64_closure.S, src/powerpc/ppc_closure.S, - src/powerpc/sysv.S, src/s390/sysv.S, src/sh/sysv.S, - src/sh64/sysv.S, src/sparc/v8.S, src/sparc/v9.S, - src/x86/sysv.S, src/x86/unix64.S, src/x86/win32.S: - include fficonfig.h - -2003-10-20 Rainer Orth - - * src/mips/ffi.c: Use _ABIN32, _ABIO32 instead of external - _MIPS_SIM_NABI32, _MIPS_SIM_ABI32. - -2003-10-19 Andreas Tobler - - * src/powerpc/ffi_darwin.c (ffi_prep_args): Declare bytes again. - Used when FFI_DEBUG = 1. - -2003-10-14 Alan Modra - - * src/types.c (double, longdouble): Default POWERPC64 to 8 byte size - and align. - -2003-10-06 Rainer Orth - - * include/ffi_mips.h: Define FFI_MIPS_N32 for N32/N64 ABIs, - FFI_MIPS_O32 for O32 ABI. - -2003-10-01 Andreas Tobler - - * testsuite/lib/libffi-dg.exp: Set LD_LIBRARY_PATH_64 for - SPARC64. Cleanup whitespaces. - -2003-09-19 Andreas Tobler - - * testsuite/libffi.call/closure_fn0.c: Xfail mips, arm, - strongarm, xscale. Cleanup whitespaces. - * testsuite/libffi.call/closure_fn1.c: Likewise. - * testsuite/libffi.call/closure_fn2.c: Likewise. - * testsuite/libffi.call/closure_fn3.c: Likewise. - * testsuite/libffi.call/cls_12byte.c: Likewise. - * testsuite/libffi.call/cls_16byte.c: Likewise. - * testsuite/libffi.call/cls_1_1byte.c: Likewise. - * testsuite/libffi.call/cls_20byte.c: Likewise. - * testsuite/libffi.call/cls_24byte.c: Likewise. - * testsuite/libffi.call/cls_2byte.c: Likewise. - * testsuite/libffi.call/cls_3_1byte.c: Likewise. - * testsuite/libffi.call/cls_3byte1.c: Likewise. - * testsuite/libffi.call/cls_3byte2.c: Likewise. - * testsuite/libffi.call/cls_4_1byte.c: Likewise. - * testsuite/libffi.call/cls_4byte.c: Likewise. - * testsuite/libffi.call/cls_5byte.c: Likewise. - * testsuite/libffi.call/cls_6byte.c: Likewise. - * testsuite/libffi.call/cls_7byte.c: Likewise. - * testsuite/libffi.call/cls_8byte.c: Likewise. - * testsuite/libffi.call/cls_double.c: Likewise. - * testsuite/libffi.call/cls_float.c: Likewise. - * testsuite/libffi.call/cls_uchar.c: Likewise. - * testsuite/libffi.call/cls_uint.c: Likewise. - * testsuite/libffi.call/cls_ulonglong.c: Likewise. - * testsuite/libffi.call/cls_ushort.c: Likewise. - * testsuite/libffi.call/nested_struct.c: Likewise. - * testsuite/libffi.call/nested_struct1.c: Likewise. - * testsuite/libffi.call/problem1.c: Likewise. - * testsuite/libffi.special/unwindtest.cc: Likewise. - * testsuite/libffi.call/pyobjc-tc.c: Cleanup whitespaces. - -2003-09-18 David Edelsohn - - * src/powerpc/aix.S: Cleanup whitespaces. - * src/powerpc/aix_closure.S: Likewise. - -2003-09-18 Andreas Tobler - - * src/powerpc/darwin.S: Cleanup whitespaces, comment formatting. - * src/powerpc/darwin_closure.S: Likewise. - * src/powerpc/ffi_darwin.c: Likewise. - -2003-09-18 Andreas Tobler - David Edelsohn - - * src/types.c (double): Add AIX and Darwin to the right TYPEDEF. - * src/powerpc/aix_closure.S: Remove the pointer to the outgoing - parameter stack. - * src/powerpc/darwin_closure.S: Likewise. - * src/powerpc/ffi_darwin.c (ffi_prep_args): Handle structures - according to the Darwin/AIX ABI. - (ffi_prep_cif_machdep): Likewise. - (ffi_closure_helper_DARWIN): Likewise. - Remove the outgoing parameter stack logic. Simplify the evaluation - of the different CASE types. - (ffi_prep_clousure): Avoid the casts on lvalues. Change the branch - statement in the trampoline code. - -2003-09-18 Kaz Kojima - - * src/sh/ffi.c (ffi_prep_args): Take account into the alignement - for the register size. - (ffi_closure_helper_SYSV): Handle the structure return value - address correctly. - (ffi_closure_helper_SYSV): Return the appropriate type when - the registers are used for the structure return value. - * src/sh/sysv.S (ffi_closure_SYSV): Fix the stack layout for - the 64-bit return value. Update copyright years. - -2003-09-17 Rainer Orth - - * testsuite/lib/libffi-dg.exp (libffi_target_compile): Search in - srcdir for ffi_mips.h. - -2003-09-12 Alan Modra - - * src/prep_cif.c (initialize_aggregate): Include tail padding in - structure size. - * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Correct - placement of float result. - * testsuite/libffi.special/unwindtest.cc (closure_test_fn1): Correct - cast of "resp" for big-endian 64 bit machines. - -2003-09-11 Alan Modra - - * src/types.c (double, longdouble): Merge identical SH and ARM - typedefs, and add POWERPC64. - * src/powerpc/ffi.c (ffi_prep_args64): Correct next_arg calc for - struct split over gpr and rest. - (ffi_prep_cif_machdep): Correct intarg_count for structures. - * src/powerpc/linux64.S (ffi_call_LINUX64): Fix gpr offsets. - -2003-09-09 Andreas Tobler - - * src/powerpc/ffi.c (ffi_closure_helper_SYSV) Handle struct - passing correctly. - -2003-09-09 Alan Modra - - * configure: Regenerate. - -2003-09-04 Andreas Tobler - - * Makefile.am: Remove build rules for ffitest. - * Makefile.in: Rebuilt. - -2003-09-04 Andreas Tobler - - * src/java_raw_api.c: Include to fix compiler warning - about implicit declaration of abort(). - -2003-09-04 Andreas Tobler - - * Makefile.am: Add dejagnu test framework. Fixes PR other/11411. - * Makefile.in: Rebuilt. - * configure.in: Add dejagnu test framework. - * configure: Rebuilt. - - * testsuite/Makefile.am: New file. - * testsuite/Makefile.in: Built - * testsuite/lib/libffi-dg.exp: New file. - * testsuite/config/default.exp: Likewise. - * testsuite/libffi.call/call.exp: Likewise. - * testsuite/libffi.call/ffitest.h: Likewise. - * testsuite/libffi.call/closure_fn0.c: Likewise. - * testsuite/libffi.call/closure_fn1.c: Likewise. - * testsuite/libffi.call/closure_fn2.c: Likewise. - * testsuite/libffi.call/closure_fn3.c: Likewise. - * testsuite/libffi.call/cls_1_1byte.c: Likewise. - * testsuite/libffi.call/cls_3_1byte.c: Likewise. - * testsuite/libffi.call/cls_4_1byte.c: Likewise. - * testsuite/libffi.call/cls_2byte.c: Likewise. - * testsuite/libffi.call/cls_3byte1.c: Likewise. - * testsuite/libffi.call/cls_3byte2.c: Likewise. - * testsuite/libffi.call/cls_4byte.c: Likewise. - * testsuite/libffi.call/cls_5byte.c: Likewise. - * testsuite/libffi.call/cls_6byte.c: Likewise. - * testsuite/libffi.call/cls_7byte.c: Likewise. - * testsuite/libffi.call/cls_8byte.c: Likewise. - * testsuite/libffi.call/cls_12byte.c: Likewise. - * testsuite/libffi.call/cls_16byte.c: Likewise. - * testsuite/libffi.call/cls_20byte.c: Likewise. - * testsuite/libffi.call/cls_24byte.c: Likewise. - * testsuite/libffi.call/cls_double.c: Likewise. - * testsuite/libffi.call/cls_float.c: Likewise. - * testsuite/libffi.call/cls_uchar.c: Likewise. - * testsuite/libffi.call/cls_uint.c: Likewise. - * testsuite/libffi.call/cls_ulonglong.c: Likewise. - * testsuite/libffi.call/cls_ushort.c: Likewise. - * testsuite/libffi.call/float.c: Likewise. - * testsuite/libffi.call/float1.c: Likewise. - * testsuite/libffi.call/float2.c: Likewise. - * testsuite/libffi.call/many.c: Likewise. - * testsuite/libffi.call/many_win32.c: Likewise. - * testsuite/libffi.call/nested_struct.c: Likewise. - * testsuite/libffi.call/nested_struct1.c: Likewise. - * testsuite/libffi.call/pyobjc-tc.c: Likewise. - * testsuite/libffi.call/problem1.c: Likewise. - * testsuite/libffi.call/promotion.c: Likewise. - * testsuite/libffi.call/return_ll.c: Likewise. - * testsuite/libffi.call/return_sc.c: Likewise. - * testsuite/libffi.call/return_uc.c: Likewise. - * testsuite/libffi.call/strlen.c: Likewise. - * testsuite/libffi.call/strlen_win32.c: Likewise. - * testsuite/libffi.call/struct1.c: Likewise. - * testsuite/libffi.call/struct2.c: Likewise. - * testsuite/libffi.call/struct3.c: Likewise. - * testsuite/libffi.call/struct4.c: Likewise. - * testsuite/libffi.call/struct5.c: Likewise. - * testsuite/libffi.call/struct6.c: Likewise. - * testsuite/libffi.call/struct7.c: Likewise. - * testsuite/libffi.call/struct8.c: Likewise. - * testsuite/libffi.call/struct9.c: Likewise. - * testsuite/libffi.special/special.exp: New file. - * testsuite/libffi.special/ffitestcxx.h: Likewise. - * testsuite/libffi.special/unwindtest.cc: Likewise. - - -2003-08-13 Kaz Kojima - - * src/sh/ffi.c (OFS_INT16): Set 0 for little endian case. Update - copyright years. - -2003-08-02 Alan Modra - - * src/powerpc/ffi.c (ffi_prep_args64): Modify for changed gcc - structure passing. - (ffi_closure_helper_LINUX64): Likewise. - * src/powerpc/linux64.S: Remove code writing to parm save area. - * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Use return - address in lr from ffi_closure_helper_LINUX64 call to calculate - table address. Optimize function tail. - -2003-07-28 Andreas Tobler - - * src/sparc/ffi.c: Handle all floating point registers. - * src/sparc/v9.S: Likewise. Fixes second part of PR target/11410. - -2003-07-11 Gerald Pfeifer - - * README: Note that libffi is not part of GCC. Update the project - URL and status. - -2003-06-19 Franz Sirl - - * src/powerpc/ppc_closure.S: Include ffi.h. - -2003-06-13 Rainer Orth - - * src/x86/sysv.S: Avoid gas-only .uleb128/.sleb128 directives. - Use C style comments. - -2003-06-13 Kaz Kojima - - * Makefile.am: Add SHmedia support. Fix a typo of SH support. - * Makefile.in: Regenerate. - * configure.in (sh64-*-linux*, sh5*-*-linux*): Add target. - * configure: Regenerate. - * include/ffi.h.in: Add SHmedia support. - * src/sh64/ffi.c: New file. - * src/sh64/sysv.S: New file. - -2003-05-16 Jakub Jelinek - - * configure.in (HAVE_RO_EH_FRAME): Check whether .eh_frame section - should be read-only. - * configure: Rebuilt. - * fficonfig.h.in: Rebuilt. - * include/ffi.h.in (EH_FRAME_FLAGS): Define. - * src/alpha/osf.S: Use EH_FRAME_FLAGS. - * src/powerpc/linux64.S: Likewise. - * src/powerpc/linux64_closure.S: Likewise. Include ffi.h. - * src/powerpc/sysv.S: Use EH_FRAME_FLAGS. Use pcrel encoding - if -fpic/-fPIC/-mrelocatable. - * src/powerpc/powerpc_closure.S: Likewise. - * src/sparc/v8.S: If HAVE_RO_EH_FRAME is defined, don't include - #write in .eh_frame flags. - * src/sparc/v9.S: Likewise. - * src/x86/unix64.S: Use EH_FRAME_FLAGS. - * src/x86/sysv.S: Likewise. Use pcrel encoding if -fpic/-fPIC. - * src/s390/sysv.S: Use EH_FRAME_FLAGS. Include ffi.h. - -2003-05-07 Jeff Sturm - - Fixes PR bootstrap/10656 - * configure.in (HAVE_AS_REGISTER_PSEUDO_OP): Test assembler - support for .register pseudo-op. - * src/sparc/v8.S: Use it. - * fficonfig.h.in: Rebuilt. - * configure: Rebuilt. - -2003-04-18 Jakub Jelinek - - * include/ffi.h.in (POWERPC64): Define if 64-bit. - (enum ffi_abi): Add FFI_LINUX64 on POWERPC. - Make it the default on POWERPC64. - (FFI_TRAMPOLINE_SIZE): Define to 24 on POWERPC64. - * configure.in: Change powerpc-*-linux* into powerpc*-*-linux*. - * configure: Rebuilt. - * src/powerpc/ffi.c (hidden): Define. - (ffi_prep_args_SYSV): Renamed from - ffi_prep_args. Cast pointers to unsigned long to shut up warnings. - (NUM_GPR_ARG_REGISTERS64, NUM_FPR_ARG_REGISTERS64, - ASM_NEEDS_REGISTERS64): New. - (ffi_prep_args64): New function. - (ffi_prep_cif_machdep): Handle FFI_LINUX64 ABI. - (ffi_call): Likewise. - (ffi_prep_closure): Likewise. - (flush_icache): Surround by #ifndef POWERPC64. - (ffi_dblfl): New union type. - (ffi_closure_helper_SYSV): Use it to avoid aliasing problems. - (ffi_closure_helper_LINUX64): New function. - * src/powerpc/ppc_closure.S: Surround whole file by #ifndef - __powerpc64__. - * src/powerpc/sysv.S: Likewise. - (ffi_call_SYSV): Rename ffi_prep_args to ffi_prep_args_SYSV. - * src/powerpc/linux64.S: New file. - * src/powerpc/linux64_closure.S: New file. - * Makefile.am (EXTRA_DIST): Add src/powerpc/linux64.S and - src/powerpc/linux64_closure.S. - (TARGET_SRC_POWERPC): Likewise. +commit 213ed15c70e72d666154c08e2b41dae3f61f20d3 +Author: Anthony Green +Date: Fri Apr 27 01:34:15 2012 -0400 - * src/ffitest.c (closure_test_fn, closure_test_fn1, closure_test_fn2, - closure_test_fn3): Fix result printing on big-endian 64-bit - machines. - (main): Print tst2_arg instead of uninitialized tst2_result. + Add blackfin supprt from Alexandre Keunecke. - * src/ffitest.c (main): Hide what closure pointer really points to - from the compiler. +commit ff3d76fd427382ce7d2b2ed54acdd0bce470ca4f +Author: Anthony Green +Date: Wed Apr 11 23:16:48 2012 -0400 -2003-04-16 Richard Earnshaw + 3.0.11 - * configure.in (arm-*-netbsdelf*): Add configuration. - (configure): Regenerated. +commit 7e0a412c4fd9cbe77b467a9bf86f56aea62632c3 +Author: Anthony Green +Date: Wed Apr 11 22:47:44 2012 -0400 -2003-04-04 Loren J. Rittle + Update files to ship - * include/Makefile.in: Regenerate. +commit 39e6a5860416f7bad992149817e1da1ba7c460d4 +Author: Zachary Waldowski +Date: Wed Apr 11 22:39:46 2012 -0400 -2003-03-21 Zdenek Dvorak + More mac/ios build improvements - * libffi/include/ffi.h.in: Define X86 instead of X86_64 in 32 - bit mode. - * libffi/src/x86/ffi.c (ffi_closure_SYSV, ffi_closure_raw_SYSV): - Receive closure pointer through parameter, read args using - __builtin_dwarf_cfa. - (FFI_INIT_TRAMPOLINE): Send closure reference through eax. +commit 853cc722a16f8d1254573ef3bb73c7b8f3d8a110 +Author: Anthony Green +Date: Tue Apr 10 06:33:33 2012 -0400 -2003-03-12 Andreas Schwab + Fix typo for darwin targets - * configure.in: Avoid trailing /. in toolexeclibdir. - * configure: Rebuilt. +commit 3f5023068cda07a3dd6dacbaa875a5b5fc96d4bb +Author: Anthony Green +Date: Fri Apr 6 20:34:51 2012 -0400 -2003-03-03 Andreas Tobler + mend - * src/powerpc/darwin_closure.S: Recode to fit dynamic libraries. +commit ebb8e8945681ce0af7a5c47a980287e8ece84b84 +Author: Mike Lewis +Date: Fri Apr 6 20:02:08 2012 -0400 -2003-02-06 Andreas Tobler + Build iOS library with xcode - * libffi/src/powerpc/darwin_closure.S: - Fix alignement bug, allocate 8 bytes for the result. - * libffi/src/powerpc/aix_closure.S: - Likewise. - * libffi/src/powerpc/ffi_darwin.c: - Update stackframe description for aix/darwin_closure.S. +commit a098b44f4c592c2192fcdef4fad6108eb3f4301c +Author: Anthony Green +Date: Fri Apr 6 17:04:35 2012 -0400 -2003-02-06 Jakub Jelinek + Reapply missing testsuite changes for arm - * src/s390/ffi.c (ffi_closure_helper_SYSV): Add hidden visibility - attribute. +commit 10d1e51393f08c14045db85843208f44f9f1e9ba +Author: Anthony Green +Date: Fri Apr 6 11:57:14 2012 -0400 -2003-01-31 Christian Cornelssen , - Andreas Schwab + Update to rc4. Upgrade autoconf version. - * configure.in: Adjust command to source config-ml.in to account - for changes to the libffi_basedir definition. - (libffi_basedir): Remove ${srcdir} from value and include trailing - slash if nonempty. +commit 9bcc884276dc0a807b2605e510b11b1740dd9aa2 +Author: Anthony Green +Date: Fri Apr 6 11:53:07 2012 -0400 - * configure: Regenerate. + Fix Linux/x32 reference in README -2003-01-29 Franz Sirl +commit a044a56b1cd2a0924f5ec0d6b5a5089d14fcd1a1 +Author: Anthony Green +Date: Fri Apr 6 10:39:10 2012 -0400 - * src/powerpc/ppc_closure.S: Recode to fit shared libs. + Linux/x32 libtool fix -2003-01-28 Andrew Haley +commit 59bb61a36661b972e8443531d3b7bc736e131a4b +Author: Anthony Green +Date: Fri Apr 6 08:26:14 2012 -0400 - * include/ffi.h.in: Enable FFI_CLOSURES for x86_64. - * src/x86/ffi64.c (ffi_prep_closure): New. - (ffi_closure_UNIX64_inner): New. - * src/x86/unix64.S (ffi_closure_UNIX64): New. + Update libtool version, README, tests dists -2003-01-27 Alexandre Oliva +commit f2981454cbe25cf9411b710f46c5f5552003a123 +Author: Anthony Green +Date: Thu Apr 5 15:45:19 2012 -0400 - * configure.in (toolexecdir, toolexeclibdir): Set and AC_SUBST. - Remove USE_LIBDIR conditional. - * Makefile.am (toolexecdir, toolexeclibdir): Don't override. - * Makefile.in, configure: Rebuilt. + Revert debug code changes -2003-01027 David Edelsohn +commit 39dccddb606f6fdb8dcb177d416e884041da6e30 +Author: Zachary Waldowski +Date: Thu Apr 5 12:32:41 2012 -0400 - * Makefile.am (TARGET_SRC_POWERPC_AIX): Fix typo. - * Makefile.in: Regenerate. + Fix building with Clang for Darwin (OS X 10.6+ and iOS + 4.0+) -2003-01-22 Andrew Haley +commit 3afaa9a34a81a305227ae8cf4f12b9d0484d055e +Author: Peter Rosin +Date: Tue Apr 3 07:40:31 2012 -0400 - * src/powerpc/darwin.S (_ffi_call_AIX): Add Augmentation size to - unwind info. + Fix return_uc.c test case on windows. -2003-01-21 Andreas Tobler +commit 65f40c35a2873d8328359ec4512bd0736dbe32c7 +Author: Anthony Green +Date: Tue Apr 3 07:35:59 2012 -0400 - * src/powerpc/darwin.S: Add unwind info. - * src/powerpc/darwin_closure.S: Likewise. + Repair ppc build regression. -2003-01-14 Andrew Haley +commit 0a1ab12a8d15caa894116a82249551f23ef65612 +Author: Peter Rosin +Date: Fri Mar 30 08:14:08 2012 -0400 - * src/x86/ffi64.c (ffi_prep_args): Check for void retval. - (ffi_prep_cif_machdep): Likewise. - * src/x86/unix64.S: Add unwind info. + Various MSVC-related changes. -2003-01-14 Andreas Jaeger +commit e1539266e6c6dde3c99832323586f33f977d1dc0 +Author: Anthony Green +Date: Fri Mar 30 00:40:18 2012 -0400 - * src/ffitest.c (main): Only use ffi_closures if those are - supported. + ARM VFP fix for old toolchains -2003-01-13 Andreas Tobler +commit 7c5e60b5f47d725036a72162f136272bc407e3a1 +Author: Anthony Green +Date: Thu Mar 29 08:48:22 2012 -0400 - * libffi/src/ffitest.c - add closure testcases + Rebase on fixed GCC sources -2003-01-13 Kevin B. Hendricks +commit e72ed5eeaa9cfb0fdc86f6b3422734177b659f96 +Author: Anthony Green +Date: Wed Mar 21 09:52:28 2012 -0400 - * libffi/src/powerpc/ffi.c - fix alignment bug for float (4 byte aligned iso 8 byte) + Fix vararg float test -2003-01-09 Geoffrey Keating +commit bd78c9c3311244dd5f877c915b0dff91621dd253 +Author: Anthony Green +Date: Wed Mar 21 08:09:30 2012 -0400 - * src/powerpc/ffi_darwin.c: Remove RCS version string. - * src/powerpc/darwin.S: Remove RCS version string. + More cygwin fixes -2003-01-03 Jeff Sturm +commit 84d3253f86dad6b4f261231935675d35fd964b05 +Author: Anthony Green +Date: Mon Mar 19 23:07:35 2012 -0400 - * include/ffi.h.in: Add closure defines for SPARC, SPARC64. - * src/ffitest.c (main): Use static storage for closure. - * src/sparc/ffi.c (ffi_prep_closure, ffi_closure_sparc_inner): New. - * src/sparc/v8.S (ffi_closure_v8): New. - * src/sparc/v9.S (ffi_closure_v9): New. + Rebase post GCC merge -2002-11-10 Ranjit Mathew +commit 964c5b93f80dcaacf73056b7d15a4d2b4b7a217c +Author: Anthony Green +Date: Sat Mar 3 14:46:20 2012 -0500 - * include/ffi.h.in: Added FFI_STDCALL ffi_type - enumeration for X86_WIN32. - * src/x86/win32.S: Added ffi_call_STDCALL function - definition. - * src/x86/ffi.c (ffi_call/ffi_raw_call): Added - switch cases for recognising FFI_STDCALL and - calling ffi_call_STDCALL if target is X86_WIN32. - * src/ffitest.c (my_stdcall_strlen/stdcall_many): - stdcall versions of the "my_strlen" and "many" - test functions (for X86_WIN32). - Added test cases to test stdcall invocation using - these functions. + abi check fixes and Linux/x32 support -2002-12-02 Kaz Kojima +commit 6c194233a5f6f1d274669afc5924a9e1f69d4876 +Author: Anthony Green +Date: Sat Mar 3 14:17:54 2012 -0500 - * src/sh/sysv.S: Add DWARF2 unwind info. + Add -no-undefined for both 32- and 64-bit x86 + windows-like hosts. -2002-11-27 Ulrich Weigand +commit 8360bf1cd0aba8db5582266da70467de7e89a57a +Author: Anthony Green +Date: Thu Feb 23 07:01:13 2012 -0500 - * src/s390/sysv.S (.eh_frame section): Make section read-only. + Ensure that users don't include ffitarget.h directly -2002-11-26 Jim Wilson +commit d578b89619cf3d2baff027b203619dc307fc12e3 +Author: Anthony Green +Date: Wed Feb 15 00:18:18 2012 -0500 - * src/types.c (FFI_TYPE_POINTER): Has size 8 on IA64. + Fix ABI check regression -2002-11-23 H.J. Lu +commit dee20f8e45c486f5018f31e09bb362992aa498c3 +Author: Anthony Green +Date: Fri Feb 10 13:06:46 2012 -0500 - * acinclude.m4: Add dummy AM_PROG_LIBTOOL. - Include ../config/accross.m4. - * aclocal.m4; Rebuild. - * configure: Likewise. + Rebased from gcc -2002-11-15 Ulrich Weigand +commit 4130e1972d001143e5e9f3c6b65f2a6f9524169e +Author: Anthony Green +Date: Fri Feb 3 13:18:27 2012 -0600 - * src/s390/sysv.S (.eh_frame section): Adapt to pcrel FDE encoding. + Refresh autoconf-archive m4 scripts -2002-11-11 DJ Delorie +commit 1ff9c604bb214b5a305064af1049577ef783730a +Author: Anthony Green +Date: Wed Feb 1 16:34:30 2012 -0600 - * configure.in: Look for common files in the right place. + Rebase from GCC -2002-10-08 Ulrich Weigand +commit 211060eb8f714af0e935430efa6bb45e8e3ffc5d +Author: Anthony Green +Date: Mon Jan 23 14:24:01 2012 -0500 - * src/java_raw_api.c (ffi_java_raw_to_ptrarray): Interpret - raw data as _Jv_word values, not ffi_raw. - (ffi_java_ptrarray_to_raw): Likewise. - (ffi_java_rvalue_to_raw): New function. - (ffi_java_raw_call): Call it. - (ffi_java_raw_to_rvalue): New function. - (ffi_java_translate_args): Call it. - * src/ffitest.c (closure_test_fn): Interpret return value - as ffi_arg, not int. - * src/s390/ffi.c (ffi_prep_cif_machdep): Add missing - FFI_TYPE_POINTER case. - (ffi_closure_helper_SYSV): Likewise. Also, assume return - values extended to word size. + Alpha fix -2002-10-02 Andreas Jaeger +commit 78d9c638ba0de6edfbc603fd65d19c6562663248 +Author: Anthony Green +Date: Mon Jan 23 14:17:24 2012 -0500 - * src/x86/ffi64.c (ffi_prep_cif_machdep): Remove debug output. + mend -2002-10-01 Bo Thorsen +commit afaf3381604bd81803d8a5f3bf4d462299f1aac3 +Author: Anthony Green +Date: Mon Jan 23 14:17:13 2012 -0500 - * include/ffi.h.in: Fix i386 win32 compilation. + mend -2002-09-30 Ulrich Weigand +commit 9e9c4aeb77de5608d602109f22100c1c0c79faad +Author: Anthony Green +Date: Mon Jan 23 14:11:23 2012 -0500 - * configure.in: Add s390x-*-linux-* target. - * configure: Regenerate. - * include/ffi.h.in: Define S390X for s390x targets. - (FFI_CLOSURES): Define for s390/s390x. - (FFI_TRAMPOLINE_SIZE): Likewise. - (FFI_NATIVE_RAW_API): Likewise. - * src/prep_cif.c (ffi_prep_cif): Do not compute stack space for s390. - * src/types.c (FFI_TYPE_POINTER): Use 8-byte pointers on s390x. - * src/s390/ffi.c: Major rework of existing code. Add support for - s390x targets. Add closure support. - * src/s390/sysv.S: Likewise. + Add Amiga support -2002-09-29 Richard Earnshaw +commit 8efc0b1f4027d5a3cbf205e55d422d94e60f3226 +Author: Anthony Green +Date: Mon Jan 23 13:47:38 2012 -0500 - * src/arm/sysv.S: Fix typo. + Unlikely fixes -2002-09-28 Richard Earnshaw +commit 1df51398ae183dc208ba4599ee867278b04d13d3 +Author: Anthony Green +Date: Mon Jan 23 13:43:59 2012 -0500 - * src/arm/sysv.S: If we don't have machine/asm.h and the pre-processor - has defined __USER_LABEL_PREFIX__, then use it in CNAME. - (ffi_call_SYSV): Handle soft-float. + mend -2002-09-27 Bo Thorsen +commit cd2277cc796b96b149cd284ae85326529fe7fb9c +Author: Anthony Green +Date: Mon Jan 23 13:43:38 2012 -0500 - * include/ffi.h.in: Fix multilib x86-64 support. + mend -2002-09-22 Kaveh R. Ghazi +commit 164e6fe04b189746c8bd5810c6e3e919770bb9d4 +Author: Anthony Green +Date: Mon Jan 23 12:41:06 2012 -0500 - * Makefile.am (all-multi): Fix multilib parallel build. + m68k fixes -2002-07-19 Kaz Kojima +commit c365ee7577bef00cb3c2c0b5224147aea04138d8 +Author: Anthony Green +Date: Mon Jan 23 11:13:18 2012 -0500 - * configure.in (sh[34]*-*-linux*): Add brackets. - * configure: Regenerate. + Refresh -2002-07-18 Kaz Kojima +commit f22c38bbd93bcc0c04bf26c3e414556b3177c385 +Author: Anthony Green +Date: Fri Nov 18 15:13:41 2011 -0500 - * Makefile.am: Add SH support. - * Makefile.in: Regenerate. - * configure.in (sh-*-linux*, sh[34]*-*-linux*): Add target. - * configure: Regenerate. - * include/ffi.h.in: Add SH support. - * src/sh/ffi.c: New file. - * src/sh/sysv.S: New file. - * src/types.c: Add SH support. + Update variadic patch -2002-07-16 Bo Thorsen +commit 03e9ee321a3c208f88d2432587ce40b2bb2430ba +Author: Anthony Green +Date: Fri Nov 18 15:13:00 2011 -0500 - * src/x86/ffi64.c: New file that adds x86-64 support. - * src/x86/unix64.S: New file that handles argument setup for - x86-64. - * src/x86/sysv.S: Don't use this on x86-64. - * src/x86/ffi.c: Don't use this on x86-64. - Remove unused vars. - * src/prep_cif.c (ffi_prep_cif): Don't do stack size calculation - for x86-64. - * src/ffitest.c (struct6): New test that tests a special case in - the x86-64 ABI. - (struct7): Likewise. - (struct8): Likewise. - (struct9): Likewise. - (closure_test_fn): Silence warning about this when it's not used. - (main): Add the new tests. - (main): Fix a couple of wrong casts and silence some compiler warnings. - * include/ffi.h.in: Add x86-64 ABI definition. - * fficonfig.h.in: Regenerate. - * Makefile.am: Add x86-64 support. - * configure.in: Likewise. - * Makefile.in: Regenerate. - * configure: Likewise. + Fix cls_double_va.c and update docs -2002-06-24 Bo Thorsen +commit 95f31151ec792809cfb80d385350f9f56d95aa25 +Author: Anthony Green +Date: Sat Nov 12 23:46:05 2011 -0500 - * src/types.c: Merge settings for similar architectures. - Add x86-64 sizes and alignments. + Rerun automake -2002-06-23 Bo Thorsen +commit 198ed1ef85cf18342627f8d44bc3f12c9975a49d +Author: Anthony Green +Date: Sat Nov 12 23:45:20 2011 -0500 - * src/arm/ffi.c (ffi_prep_args): Remove unused vars. - * src/sparc/ffi.c (ffi_prep_args_v8): Likewise. - * src/mips/ffi.c (ffi_prep_args): Likewise. - * src/m68k/ffi.c (ffi_prep_args): Likewise. + Update version number -2002-07-18 H.J. Lu (hjl@gnu.org) +commit 4f17e1f142e805b13959ba2594ee735eae439f4e +Author: Anthony Green +Date: Sat Nov 12 17:22:24 2011 -0500 - * Makefile.am (TARGET_SRC_MIPS_LINUX): New. - (libffi_la_SOURCES): Support MIPS_LINUX. - (libffi_convenience_la_SOURCES): Likewise. - * Makefile.in: Regenerated. + Fix last patch - * configure.in (mips64*-*): Skip. - (mips*-*-linux*): New. - * configure: Regenerated. +commit ff9454da44859716a5bd4eaa344499288c79694f +Author: Anthony Green +Date: Sat Nov 12 17:18:51 2011 -0500 - * src/mips/ffi.c: Include . + Add David Gilbert's variadic function call support -2002-06-06 Ulrich Weigand +commit ea14ae85e8f54ff046b7fb8a9cfe349475272044 +Author: Anthony Green +Date: Sat Nov 12 16:36:59 2011 -0500 - * src/s390/sysv.S: Save/restore %r6. Add DWARF-2 unwind info. + clean up -2002-05-27 Roger Sayle +commit 52891f8a93f9b8de801cca4cf05639422dc9773e +Author: Anthony Green +Date: Sat Nov 12 16:35:55 2011 -0500 - * src/x86/ffi.c (ffi_prep_args): Remove reference to avn. + Add powerpc soft float support -2002-05-27 Bo Thorsen +commit c8f1bde8e2566c5a87474b4d08aa934d6d28ee75 +Author: Anthony Green +Date: Sat Nov 12 16:21:02 2011 -0500 - * src/x86/ffi.c (ffi_prep_args): Remove unused variable and - fix formatting. + Remove junk file -2002-05-13 Andreas Tobler +commit 6a6e7f862f3cc677e19131587caa619e7f9c7ffd +Author: Anthony Green +Date: Sat Nov 12 16:20:42 2011 -0500 - * src/powerpc/ffi_darwin.c (ffi_prep_closure): Declare fd at - beginning of function (for older apple cc). + Fix kfreebsd -2002-05-08 Alexandre Oliva +commit d52fbed05ccbdee9ed8b9c911cbb4f85b0ff0f2a +Author: Anthony Green +Date: Sat Nov 12 16:13:41 2011 -0500 - * configure.in (ORIGINAL_LD_FOR_MULTILIBS): Preserve LD at - script entry, and set LD to it when configuring multilibs. - * configure: Rebuilt. + Add missing ChangeLog entry -2002-05-05 Jason Thorpe +commit 322052ce65c4fdac85bedc24726fd0e0094ba521 +Author: Anthony Green +Date: Sat Nov 12 16:11:49 2011 -0500 - * configure.in (sparc64-*-netbsd*): Add target. - (sparc-*-netbsdelf*): Likewise. - * configure: Regenerate. + Fix arm wince alignment issue -2002-04-28 David S. Miller +commit af18df2bc2f52df81e7b5c619bd86db8489dc873 +Author: Anthony Green +Date: Sat Nov 12 15:52:08 2011 -0500 - * configure.in, configure: Fix SPARC test in previous change. + Remove use of ppc string instructions -2002-04-29 Gerhard Tonn +commit 236c9391321f83ad40daf03f40c35c9ebc1da6b3 +Author: Anthony Green +Date: Sat Nov 12 07:37:40 2011 -0500 - * Makefile.am: Add Linux for S/390 support. - * Makefile.in: Regenerate. - * configure.in: Add Linux for S/390 support. - * configure: Regenerate. - * include/ffi.h.in: Add Linux for S/390 support. - * src/s390/ffi.c: New file from libffi CVS tree. - * src/s390/sysv.S: New file from libffi CVS tree. + Fix darwin11 build problem -2002-04-28 Jakub Jelinek +commit c411f140f305ebb00d33c92b7cb2742bcd241b6a +Author: Anthony Green +Date: Sat Nov 12 07:32:36 2011 -0500 - * configure.in (HAVE_AS_SPARC_UA_PCREL): Check for working - %r_disp32(). - * src/sparc/v8.S: Use it. - * src/sparc/v9.S: Likewise. - * fficonfig.h.in: Rebuilt. - * configure: Rebuilt. + Fix ax_enable_builddir macro on BSD systems -2002-04-08 Hans Boehm +commit 3d56106b07735abef6ae9f032e94f560a0ed2f30 +Author: Anthony Green +Date: Sat Nov 12 07:20:24 2011 -0500 - * src/java_raw_api.c (ffi_java_raw_size): Handle FFI_TYPE_DOUBLE - correctly. - * src/ia64/unix.S: Add unwind information. Fix comments. - Save sp in a way that's compatible with unwind info. - (ffi_call_unix): Correctly restore sp in all cases. - * src/ia64/ffi.c: Add, fix comments. + Rebase -2002-04-08 Jakub Jelinek +commit 8c01954c50bf8ef2e00a3db166060a1b8f83a20d +Author: Anthony Green +Date: Tue Sep 6 14:26:32 2011 -0400 - * src/sparc/v8.S: Make .eh_frame dependent on target word size. + Build assembly files with debug info -2002-04-06 Jason Thorpe +commit fed646a2078969f4ce89c29107f1e72e03f4a977 +Author: Anthony Green +Date: Tue Sep 6 09:50:20 2011 -0400 - * configure.in (alpha*-*-netbsd*): Add target. - * configure: Regenerate. + Regenerate configury with missing m4 macros -2002-04-04 Jeff Sturm +commit d76441cf71216f8f1e62e7ec852a7f4e21371ec8 +Author: Anthony Green +Date: Wed Aug 24 10:14:23 2011 -0400 - * src/sparc/v8.S: Add unwind info. - * src/sparc/v9.S: Likewise. + Update list of supported OpenBSD systems -2002-03-30 Krister Walfridsson +commit ee6696fdf4768ba6dd037fb6dd99435afa13816e +Author: Anthony Green +Date: Tue Aug 23 12:30:29 2011 -0400 - * configure.in: Enable i*86-*-netbsdelf*. - * configure: Rebuilt. + 3.0.11-rc1. soname bump. -2002-03-29 David Billinghurst +commit c6265c36a91eab8175d0e72db84d8225418f2379 +Author: Anthony Green +Date: Tue Aug 23 10:31:33 2011 -0400 - PR other/2620 - * src/mips/n32.s: Delete - * src/mips/o32.s: Delete + Version 3.0.10 -2002-03-21 Loren J. Rittle +commit cc5e41bf32d18a14dbdd653d52eacdbdc934c392 +Author: Anthony Green +Date: Mon Aug 22 16:34:24 2011 -0400 - * configure.in: Enable alpha*-*-freebsd*. - * configure: Rebuilt. + Fix use of autoconf macros -2002-03-17 Bryce McKinlay +commit 049d8386ff52399e69a530b55b9feedc8a2589d2 +Author: Anthony Green +Date: Mon Aug 22 14:50:10 2011 -0400 - * Makefile.am: libfficonvenience -> libffi_convenience. - * Makefile.in: Rebuilt. + Many new patches - * Makefile.am: Define ffitest_OBJECTS. - * Makefile.in: Rebuilt. +commit 3b7efa4e74f0dcebf70b447391987aedd3473306 +Author: Anthony Green +Date: Mon Aug 15 13:25:13 2011 -0400 -2002-03-07 Andreas Tobler - David Edelsohn + Revert remove-debug-code patch temporarily (for ARM Fedora release) - * Makefile.am (EXTRA_DIST): Add Darwin and AIX closure files. - (TARGET_SRC_POWERPC_AIX): Add aix_closure.S. - (TARGET_SRC_POWERPC_DARWIN): Add darwin_closure.S. - * Makefile.in: Regenerate. - * include/ffi.h.in: Add AIX and Darwin closure definitions. - * src/powerpc/ffi_darwin.c (ffi_prep_closure): New function. - (flush_icache, flush_range): New functions. - (ffi_closure_helper_DARWIN): New function. - * src/powerpc/aix_closure.S: New file. - * src/powerpc/darwin_closure.S: New file. +commit d992ac54a2a9e7e064ffebcb91e05e7cb86185c7 +Author: Anthony Green +Date: Fri Jul 29 17:32:53 2011 -0400 -2002-02-24 Jeff Sturm + Refresh from GCC - * include/ffi.h.in: Add typedef for ffi_arg. - * src/ffitest.c (main): Declare rint with ffi_arg. +commit 2d3fb36420e09304220ee6c0652bae5eccdb965d +Author: Anthony Green +Date: Wed Mar 30 16:54:42 2011 -0400 -2002-02-21 Andreas Tobler + Fix darwin EH - * src/powerpc/ffi_darwin.c (ffi_prep_args): Skip appropriate - number of GPRs for floating-point arguments. +commit 30ff28e1d8cd9ed5319f1fbe9c7cccacc8161fb3 +Author: Anthony Green +Date: Mon Feb 28 15:36:23 2011 -0500 -2002-01-31 Anthony Green + Fix permissions - * configure: Rebuilt. - * configure.in: Replace CHECK_SIZEOF and endian tests with - cross-compiler friendly macros. - * aclocal.m4 (AC_COMPILE_CHECK_SIZEOF, AC_C_BIGENDIAN_CROSS): New - macros. +commit 09f8f310f4f53a24289682d3d28f4399d7bafc3b +Author: Anthony Green +Date: Mon Feb 28 15:36:07 2011 -0500 -2002-01-18 David Edelsohn + More AIX fixes. rc9. - * src/powerpc/darwin.S (_ffi_call_AIX): New. - * src/powerpc/aix.S (ffi_call_DARWIN): New. +commit 53d7b165642c220aa5166ba350b490802f359b54 +Merge: 18dd85d 3000dc2 +Author: Anthony Green +Date: Mon Feb 28 15:23:31 2011 -0500 -2002-01-17 David Edelsohn + Merge branch 'master' of https://github.com/landonf/libffi-ios - * Makefile.am (EXTRA_DIST): Add Darwin and AIX files. - (TARGET_SRC_POWERPC_AIX): New. - (POWERPC_AIX): New stanza. - * Makefile.in: Regenerate. - * configure.in: Add AIX case. - * configure: Regenerate. - * include/ffi.h.in (ffi_abi): Add FFI_AIX. - * src/powerpc/ffi_darwin.c (ffi_status): Use "long" to scale frame - size. Fix "long double" support. - (ffi_call): Add FFI_AIX case. - * src/powerpc/aix.S: New. +commit 18dd85d6cb9f3f3eea2a3b70eb4e150045905c55 +Author: Anthony Green +Date: Fri Feb 25 16:23:04 2011 -0500 -2001-10-09 John Hornkvist + rc8. fix last patch. - Implement Darwin PowerPC ABI. - * configure.in: Handle powerpc-*-darwin*. - * Makefile.am: Set source files for POWERPC_DARWIN. - * configure: Rebuilt. - * Makefile.in: Rebuilt. - * include/ffi.h.in: Define FFI_DARWIN and FFI_DEFAULT_ABI for - POWERPC_DARWIN. - * src/powerpc/darwin.S: New file. - * src/powerpc/ffi_darwin.c: New file. +commit 74ee6ea8b42e60d44a3ae8938b1e42a38c1e66b4 +Author: Anthony Green +Date: Fri Feb 25 15:52:14 2011 -0500 -2001-10-07 Joseph S. Myers + rc7. More AIX fixes. - * src/x86/ffi.c: Fix spelling error of "separate" as "seperate". +commit 2541679dbd3db0014890f42192dbf8008ab923fa +Author: Anthony Green +Date: Fri Feb 25 15:09:13 2011 -0500 -2001-07-16 Rainer Orth + Fix ppc32 bug - * src/x86/sysv.S: Avoid gas-only .balign directive. - Use C style comments. +commit cbb062cc35c518004f1ab45c847f8ec4f66069ad +Author: Anthony Green +Date: Thu Feb 17 20:39:21 2011 -0500 -2001-07-16 Rainer Orth + Another non-GCC configury fix - * src/alpha/ffi.c (ffi_prep_closure): Avoid gas-only mnemonic. - Fixes PR bootstrap/3563. +commit 8cf8878425e9971866fa6b27a3e4914729ad3960 +Author: Anthony Green +Date: Tue Feb 15 15:19:49 2011 -0500 -2001-06-26 Rainer Orth + Fix ax_cc_maxopt.m4 - * src/alpha/osf.S (ffi_closure_osf): Use .rdata for ECOFF. +commit 24b72070c0937f9000744c77a636f07e04786b6a +Author: Anthony Green +Date: Mon Feb 14 15:30:57 2011 -0500 -2001-06-25 Rainer Orth + Fix warning and msvcc patches - * configure.in: Recognize sparc*-sun-* host. - * configure: Regenerate. +commit d72c49e556a8c516e97f6722d1be2f1209c21207 +Author: Anthony Green +Date: Sun Feb 13 11:41:05 2011 -0500 -2001-06-06 Andrew Haley + Add missing msvcc.sh - * src/alpha/osf.S (__FRAME_BEGIN__): Conditionalize for ELF. +commit 3000dc237f6017a7445d8404097a4f46b73fdd29 +Merge: 55e4a5a 1fbf9dc +Author: Landon Fuller +Date: Sun Feb 13 08:55:53 2011 -0500 -2001-06-03 Andrew Haley + Merge remote branch 'upstream/master' - * src/alpha/osf.S: Add unwind info. - * src/powerpc/sysv.S: Add unwind info. - * src/powerpc/ppc_closure.S: Likewise. +commit 1fbf9dc44feea564e84ad7406d17c5d5906ce0e0 +Author: Anthony Green +Date: Sun Feb 13 08:06:39 2011 -0500 -2000-05-31 Jeff Sturm + Fix bad_abi test. rc5. - * configure.in: Fix AC_ARG_ENABLE usage. - * configure: Rebuilt. +commit 90af15ef5c1614b76370c4d13954586fabf9e8e3 +Author: Anthony Green +Date: Sat Feb 12 12:29:36 2011 -0500 -2001-05-06 Bryce McKinlay + iOS fixes - * configure.in: Remove warning about beta code. - * configure: Rebuilt. +commit 55e4a5aa1568558a04aa40f16fc022e459af53e3 +Author: Landon Fuller +Date: Sat Feb 12 12:13:46 2011 -0500 -2001-04-25 Hans Boehm + Add support for building a full armv6/armv7/i386 universal iOS library - * src/ia64/unix.S: Restore stack pointer when returning from - ffi_closure_UNIX. - * src/ia64/ffi.c: Fix typo in comment. +commit a0c80f279b8733d001cb5e5c5a3289ecb7a6e56a +Author: Landon Fuller +Date: Sat Feb 12 11:43:49 2011 -0500 -2001-04-18 Jim Wilson + Update my e-mail address. - * src/ia64/unix.S: Delete unnecessary increment and decrement of loc2 - to eliminate RAW DV. +commit 8195e0e11df7a53fa474caa9375f73ca1136ed66 +Author: Landon Fuller +Date: Sat Feb 12 11:27:00 2011 -0500 -2001-04-12 Bryce McKinlay + Fix symbol prefixes on Darwin. - * Makefile.am: Make a libtool convenience library. - * Makefile.in: Rebuilt. +commit 56b3f8cef0f28cefaa0f40fe0cf7c524adef131d +Author: Landon Fuller +Date: Sat Feb 12 11:14:54 2011 -0500 -2001-03-29 Bryce McKinlay + Modify the ffi_closure structures to hold table/table entry pointers instead of a code buffer. + + This re-integrates commit da2773e02ab26cc11a7f. - * configure.in: Use different syntax for subdirectory creation. - * configure: Rebuilt. +commit 28a00f61ff3f64c4eb2269ce2aea3d493274469e +Author: Landon Fuller +Date: Sat Feb 12 11:01:48 2011 -0500 -2001-03-27 Jon Beniston + Apple assembler support; fixed most gas/ELF-isms. - * configure.in: Added X86_WIN32 target (Win32, CygWin, MingW). - * configure: Rebuilt. - * Makefile.am: Added X86_WIN32 target support. - * Makefile.in: Rebuilt. +commit 7f2ea33a80bfced5e48ed7292f3b8f057d54ff8f +Author: Landon Fuller +Date: Sat Feb 12 10:39:18 2011 -0500 - * include/ffi.h.in: Added X86_WIN32 target support. + Replace RETLDM macro. + + The macro is incompatible with Apple's assembler; switch to + a simple inline version. - * src/ffitest.c: Doesn't run structure tests for X86_WIN32 targets. - * src/types.c: Added X86_WIN32 target support. +commit 92ff23e77fa586455b427b71f49e1d9502470e6e +Author: Landon Fuller +Date: Sat Feb 12 10:24:49 2011 -0500 - * src/x86/win32.S: New file. Based on sysv.S, but with EH - stuff removed and made to work with CygWin's gas. + Switch to the current iOS 4.2 SDK. -2001-03-26 Bryce McKinlay +commit 58fb8ca2dfb89ad70284bb9678d3d4dbb658c8a7 +Merge: cc3fbd9 71c792f +Author: Landon Fuller +Date: Sat Feb 12 10:23:19 2011 -0500 - * configure.in: Make target subdirectory in build dir. - * Makefile.am: Override suffix based rules to specify correct output - subdirectory. - * Makefile.in: Rebuilt. - * configure: Rebuilt. + Merge remote branch 'upstream/master' -2001-03-23 Kevin B Hendricks +commit cc3fbd975ce9366d4c40a6ff6c108f664867bd7c +Merge: e449a43 f6ab3ed +Author: Landon Fuller +Date: Sat Feb 12 10:21:02 2011 -0500 - * src/powerpc/ppc_closure.S: New file. - * src/powerpc/ffi.c (ffi_prep_args): Fixed ABI compatibility bug - involving long long and register pairs. - (ffi_prep_closure): New function. - (flush_icache): Likewise. - (ffi_closure_helper_SYSV): Likewise. - * include/ffi.h.in (FFI_CLOSURES): Define on PPC. - (FFI_TRAMPOLINE_SIZE): Likewise. - (FFI_NATIVE_RAW_API): Likewise. - * Makefile.in: Rebuilt. - * Makefile.am (EXTRA_DIST): Added src/powerpc/ppc_closure.S. - (TARGET_SRC_POWERPC): Likewise. + Merge branch 'master' of github.com:landonf/libffi-ios -2001-03-19 Tom Tromey +commit e449a43bbe12f8119399928db1ae26adc71dde14 +Author: Landon Fuller +Date: Sat Feb 12 10:20:42 2011 -0500 - * Makefile.in: Rebuilt. - * Makefile.am (ffitest_LDFLAGS): New macro. + Allow specification of the minimum supported iOS version. -2001-03-02 Nick Clifton +commit 71c792f51bcf3e2f334e5ea1fb1a8b667cb3aedb +Author: Anthony Green +Date: Sat Feb 12 09:33:11 2011 -0500 - * include/ffi.h.in: Remove RCS ident string. - * include/ffi_mips.h: Remove RCS ident string. - * src/debug.c: Remove RCS ident string. - * src/ffitest.c: Remove RCS ident string. - * src/prep_cif.c: Remove RCS ident string. - * src/types.c: Remove RCS ident string. - * src/alpha/ffi.c: Remove RCS ident string. - * src/alpha/osf.S: Remove RCS ident string. - * src/arm/ffi.c: Remove RCS ident string. - * src/arm/sysv.S: Remove RCS ident string. - * src/mips/ffi.c: Remove RCS ident string. - * src/mips/n32.S: Remove RCS ident string. - * src/mips/o32.S: Remove RCS ident string. - * src/sparc/ffi.c: Remove RCS ident string. - * src/sparc/v8.S: Remove RCS ident string. - * src/sparc/v9.S: Remove RCS ident string. - * src/x86/ffi.c: Remove RCS ident string. - * src/x86/sysv.S: Remove RCS ident string. - -2001-02-08 Joseph S. Myers - - * include/ffi.h.in: Change sourceware.cygnus.com references to - gcc.gnu.org. - -2000-12-09 Richard Henderson - - * src/alpha/ffi.c (ffi_call): Simplify struct return test. - (ffi_closure_osf_inner): Index rather than increment avalue - and arg_types. Give ffi_closure_osf the raw return value type. - * src/alpha/osf.S (ffi_closure_osf): Handle return value type - promotion. - -2000-12-07 Richard Henderson - - * src/raw_api.c (ffi_translate_args): Fix typo. - (ffi_prep_closure): Likewise. - - * include/ffi.h.in [ALPHA]: Define FFI_CLOSURES and - FFI_TRAMPOLINE_SIZE. - * src/alpha/ffi.c (ffi_prep_cif_machdep): Adjust minimal - cif->bytes for new ffi_call_osf implementation. - (ffi_prep_args): Absorb into ... - (ffi_call): ... here. Do all stack allocation here and - avoid a callback function. - (ffi_prep_closure, ffi_closure_osf_inner): New. - * src/alpha/osf.S (ffi_call_osf): Reimplement with no callback. - (ffi_closure_osf): New. - -2000-09-10 Alexandre Oliva - - * config.guess, config.sub, install-sh: Removed. - * ltconfig, ltmain.sh, missing, mkinstalldirs: Likewise. - * Makefile.in: Rebuilt. - - * acinclude.m4: Include libtool macros from the top level. - * aclocal.m4, configure: Rebuilt. - -2000-08-22 Alexandre Oliva - - * configure.in [i*86-*-freebsd*] (TARGET, TARGETDIR): Set. - * configure: Rebuilt. - -2000-05-11 Scott Bambrough - - * libffi/src/arm/sysv.S (ffi_call_SYSV): Doubles are not saved to - memory correctly. Use conditional instructions, not branches where - possible. - -2000-05-04 Tom Tromey - - * configure: Rebuilt. - * configure.in: Match `arm*-*-linux-*'. - From Chris Dornan . - -2000-04-28 Jakub Jelinek - - * Makefile.am (SUBDIRS): Define. - (AM_MAKEFLAGS): Likewise. - (Multilib support.): Add section. - * Makefile.in: Rebuilt. - * ltconfig (extra_compiler_flags, extra_compiler_flags_value): - New variables. Set for gcc using -print-multi-lib. Export them - to libtool. - (sparc64-*-linux-gnu*): Use libsuff 64 for search paths. - * ltmain.sh (B|b|V): Don't throw away gcc's -B, -b and -V options - for -shared links. - (extra_compiler_flags_value, extra_compiler_flags): Check these - for extra compiler options which need to be passed down in - compiler_flags. - -2000-04-16 Anthony Green - - * configure: Rebuilt. - * configure.in: Change i*86-pc-linux* to i*86-*-linux*. - -2000-04-14 Jakub Jelinek - - * include/ffi.h.in (SPARC64): Define for 64bit SPARC builds. - Set SPARC FFI_DEFAULT_ABI based on SPARC64 define. - * src/sparc/ffi.c (ffi_prep_args_v8): Renamed from ffi_prep_args. - Replace all void * sizeofs with sizeof(int). - Only compare type with FFI_TYPE_LONGDOUBLE if LONGDOUBLE is - different than DOUBLE. - Remove FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases (handled elsewhere). - (ffi_prep_args_v9): New function. - (ffi_prep_cif_machdep): Handle V9 ABI and long long on V8. - (ffi_V9_return_struct): New function. - (ffi_call): Handle FFI_V9 ABI from 64bit code and FFI_V8 ABI from - 32bit code (not yet cross-arch calls). - * src/sparc/v8.S: Add struct return delay nop. - Handle long long. - * src/sparc/v9.S: New file. - * src/prep_cif.c (ffi_prep_cif): Return structure pointer - is used on sparc64 only for structures larger than 32 bytes. - Pass by reference for structures is done for structure arguments - larger than 16 bytes. - * src/ffitest.c (main): Use 64bit rint on sparc64. - Run long long tests on sparc. - * src/types.c (FFI_TYPE_POINTER): Pointer is 64bit on alpha and - sparc64. - (FFI_TYPE_LONGDOUBLE): long double is 128 bit aligned to 128 bits - on sparc64. - * configure.in (sparc-*-linux*): New supported target. - (sparc64-*-linux*): Likewise. - * configure: Rebuilt. - * Makefile.am: Add v9.S to SPARC files. - * Makefile.in: Likewise. - (LINK): Surround $(CCLD) into double quotes, so that multilib - compiles work correctly. - -2000-04-04 Alexandre Petit-Bianco - - * configure: Rebuilt. - * configure.in: (i*86-*-solaris*): New libffi target. Patch - proposed by Bryce McKinlay. - -2000-03-20 Tom Tromey - - * Makefile.in: Hand edit for java_raw_api.lo. - -2000-03-08 Bryce McKinlay + rc4 - * config.guess, config.sub: Update from the gcc tree. - Fix for PR libgcj/168. +commit 7c7c9f327299331022f6000603a35f2310dfe308 +Author: Anthony Green +Date: Sat Feb 12 09:29:29 2011 -0500 -2000-03-03 Tom Tromey + ungccify parts of the build - * Makefile.in: Fixed ia64 by hand. +commit ed62e48b95a0fa60b685f647cb73c9e190eec35c +Author: Anthony Green +Date: Fri Feb 11 12:23:58 2011 -0500 - * configure: Rebuilt. - * configure.in (--enable-multilib): New option. - (libffi_basedir): New subst. - (AC_OUTPUT): Added multilib code. + Fix permissions -2000-03-02 Tom Tromey +commit 17d9e9e68ddb1b915a0b9751713033861b598575 +Author: Anthony Green +Date: Fri Feb 11 12:23:20 2011 -0500 - * Makefile.in: Rebuilt. - * Makefile.am (TARGET_SRC_IA64): Use `ia64', not `alpha', as - directory name. + Use newer autotools. Only build debug.c when --enable-debug. -2000-02-25 Hans Boehm +commit 6972a4ffda75761eaab7dfbe0fb1516b255e8e0c +Author: Anthony Green +Date: Fri Feb 11 07:32:51 2011 -0500 - * src/ia64/ffi.c, src/ia64/ia64_flags.h, src/ia64/unix.S: New - files. - * src/raw_api.c (ffi_translate_args): Fixed typo in argument - list. - (ffi_prep_raw_closure): Use ffi_translate_args, not - ffi_closure_translate. - * src/java_raw_api.c: New file. - * src/ffitest.c (closure_test_fn): New function. - (main): Define `rint' as long long on IA64. Added new test when - FFI_CLOSURES is defined. - * include/ffi.h.in (ALIGN): Use size_t, not unsigned. - (ffi_abi): Recognize IA64. - (ffi_raw): Added `flt' field. - Added "Java raw API" code. - * configure.in: Recognize ia64. - * Makefile.am (TARGET_SRC_IA64): New macro. - (libffi_la_common_SOURCES): Added java_raw_api.c. - (libffi_la_SOURCES): Define in IA64 case. + Fix xlc build on AIX -2000-01-04 Tom Tromey +commit 1833aa0fb9831eb0725b63e35886c0f6d35df480 +Author: Anthony Green +Date: Fri Feb 11 07:11:04 2011 -0500 - * Makefile.in: Rebuilt with newer automake. + sparc ABI test fix. -1999-12-31 Tom Tromey +commit f1fb139b4e283fffdcf205a903943d5e9d2bb2a2 +Author: Anthony Green +Date: Wed Feb 9 18:30:02 2011 -0500 - * Makefile.am (INCLUDES): Added -I$(top_srcdir)/src. + Fix tests -1999-09-01 Tom Tromey +commit 5cb470331d181c84d5d621e88868327a324a5898 +Author: Anthony Green +Date: Wed Feb 9 15:23:06 2011 -0500 - * include/ffi.h.in: Removed PACKAGE and VERSION defines and - undefs. - * fficonfig.h.in: Rebuilt. - * configure: Rebuilt. - * configure.in: Pass 3rd argument to AM_INIT_AUTOMAKE. - Use AM_PROG_LIBTOOL (automake 1.4 compatibility). - * acconfig.h: Don't #undef PACKAGE or VERSION. + Fix permissions -1999-08-09 Anthony Green +commit 269deef6dbbb426695919d3398357fada3bb288c +Author: Anthony Green +Date: Wed Feb 9 15:22:23 2011 -0500 - * include/ffi.h.in: Try to work around messy header problem - with PACKAGE and VERSION. + rc3 - * configure: Rebuilt. - * configure.in: Change version to 2.00-beta. +commit 42695e72504f647444b8e8e9b90bd24f1e3220e1 +Author: Anthony Green +Date: Wed Feb 9 15:12:35 2011 -0500 - * fficonfig.h.in: Rebuilt. - * acconfig.h (FFI_NO_STRUCTS, FFI_NO_RAW_API): Define. + Fix IRIX support - * src/x86/ffi.c (ffi_raw_call): Rename. +commit a6e56b97f62a3feeb3301c24a2e4cae55e546021 +Author: Anthony Green +Date: Wed Feb 9 15:00:42 2011 -0500 -1999-08-02 Kresten Krab Thorup + Add powerpc64-*-darwin* support - * src/x86/ffi.c (ffi_closure_SYSV): New function. - (ffi_prep_incoming_args_SYSV): Ditto. - (ffi_prep_closure): Ditto. - (ffi_closure_raw_SYSV): Ditto. - (ffi_prep_raw_closure): More ditto. - (ffi_call_raw): Final ditto. +commit 747d6c32d4abb07c10c3a1f93579c3929aaa2487 +Author: Anthony Green +Date: Wed Feb 9 14:56:23 2011 -0500 - * include/ffi.h.in: Add definitions for closure and raw API. + Add Interix support - * src/x86/ffi.c (ffi_prep_cif_machdep): Added case for - FFI_TYPE_UINT64. +commit eab6e41cde382aa07de6c011d514a14c0d62eb47 +Author: Anthony Green +Date: Wed Feb 9 10:15:02 2011 -0500 - * Makefile.am (libffi_la_common_SOURCES): Added raw_api.c + Remove README.markdown form libffi-ios - * src/raw_api.c: New file. +commit 69dbe845f4ee3e6ce8999f17a1e4f2179ef7da89 +Author: Anthony Green +Date: Wed Feb 9 07:38:43 2011 -0500 - * include/ffi.h.in (ffi_raw): New type. - (UINT_ARG, SINT_ARG): New defines. - (ffi_closure, ffi_raw_closure): New types. - (ffi_prep_closure, ffi_prep_raw_closure): New declarations. + Fix xfails - * configure.in: Add check for endianness and sizeof void*. +commit f498318c07b95137fe259d86bdbe15347588b84a +Author: Anthony Green +Date: Wed Feb 9 06:26:46 2011 -0500 - * src/x86/sysv.S (ffi_call_SYSV): Call fixup routine via argument, - instead of directly. + Update README for iOS again - * configure: Rebuilt. +commit 630b9c0ac43c7edcbfd892e23c09fb26724f4ac0 +Author: Anthony Green +Date: Wed Feb 9 06:24:23 2011 -0500 -Thu Jul 8 14:28:42 1999 Anthony Green + Update to rc2 - * configure.in: Add x86 and powerpc BeOS configurations. - From Makoto Kato . +commit 0cad4386fa4c9ea5f8ca88b16247db4e5c8fea90 +Author: Anthony Green +Date: Wed Feb 9 06:11:46 2011 -0500 -1999-05-09 Anthony Green + Add ChangeLog entry. Fix copyright headers. - * configure.in: Add warning about this being beta code. - Remove src/Makefile.am from the picture. - * configure: Rebuilt. +commit 09cb76f2645bd2c151846e9249d8ea707ba01e8c +Author: Anthony Green +Date: Tue Feb 8 20:39:51 2011 -0500 - * Makefile.am: Move logic from src/Makefile.am. Add changes - to support libffi as a target library. - * Makefile.in: Rebuilt. + Add missing change - * aclocal.m4, config.guess, config.sub, ltconfig, ltmain.sh: - Upgraded to new autoconf, automake, libtool. +commit 2e3a48ccdd54340983c46a29a0b41985e3e789ac +Author: Anthony Green +Date: Tue Feb 8 20:37:26 2011 -0500 - * README: Tweaks. + Fix make dist - * LICENSE: Update copyright date. +commit 5e4814d9928e236a2a4afe84d6e1d4fdaa473206 +Author: Anthony Green +Date: Tue Feb 8 19:46:28 2011 -0500 - * src/Makefile.am, src/Makefile.in: Removed. + fix permissions -1998-11-29 Anthony Green +commit 5c0cc6f1536aa1738795a97303810a823c7fa2cb +Author: Anthony Green +Date: Tue Feb 8 19:45:59 2011 -0500 - * include/ChangeLog: Removed. - * src/ChangeLog: Removed. - * src/mips/ChangeLog: Removed. - * src/sparc/ChangeLog: Remboved. - * src/x86/ChangeLog: Removed. + 3.0.10rc1 - * ChangeLog.v1: Created. +commit 857fe3de46d2286afa2fe772920ecf4aefa1688f +Author: Anthony Green +Date: Tue Feb 8 19:39:20 2011 -0500 + + Clean ups + +commit e2214f8adb5577c247452e2cc9f4cbe304d7ca9f +Author: Anthony Green +Date: Tue Feb 8 19:22:56 2011 -0500 + + Update README + +commit 1106229a5721a659da5c231ec0e8211119615394 +Merge: bc9d0be f6ab3ed +Author: Anthony Green +Date: Tue Feb 8 19:20:09 2011 -0500 + + Add iOS support + +commit bc9d0be2958ce475757f34dd2c878948aa77a39f +Author: Anthony Green +Date: Tue Feb 8 17:04:26 2011 -0500 + + 3.0.10rc0 changes + +commit 3b836249feae6d08d3e6887486e4b9961ddafa09 +Author: Anthony Green +Date: Tue Feb 8 14:28:59 2011 -0500 + + Rebase from GCC + +commit a26e3940619faeba6de54824c9540c90b1aab513 +Author: Anthony Green +Date: Tue Feb 8 13:56:12 2011 -0500 + + copyright updates patch + +commit b8099539f00e224107594101e9760b6dc081a056 +Author: Anthony Green +Date: Tue Feb 8 13:50:43 2011 -0500 + + Fix msvcc.sh botch + +commit dc411e8f99113a34656bfd2d3ae51259972488cc +Author: Anthony Green +Date: Tue Feb 8 10:49:29 2011 -0500 + + Fix HP-UX build + +commit 404585d1348e30ac58203bbd876d9131e5aed874 +Author: Anthony Green +Date: Tue Feb 8 10:44:36 2011 -0500 + + Fix sparc v8 aggregate type returns for sun's compiler + +commit 19ce713188e193e4522740d24c20170411883d2d +Author: Anthony Green +Date: Tue Feb 8 10:34:23 2011 -0500 + + grammar fix + +commit 89284fe55f1a8ad3bddbea796ee00d0e3ba411ce +Author: Anthony Green +Date: Tue Feb 8 10:19:19 2011 -0500 + + Fix AIX build with IBM XLC + +commit ba022c338af97cb18d9f8ed5a607fd483a61c09c +Author: Anthony Green +Date: Tue Feb 8 10:12:48 2011 -0500 + + fix win64-underscore patch + +commit 097e5f3924ee92a3ba6cd72f787da8a3eb14fea3 +Author: Anthony Green +Date: Tue Feb 8 10:11:00 2011 -0500 + + x86 pcrel test part 2 + +commit ed2c518d960b91d444be74e5a55779a9c4602f3b +Author: Anthony Green +Date: Tue Feb 8 10:10:07 2011 -0500 + + x86 pcrel test + +commit 0e5843995f46900ef212531281e08b224464f413 +Author: Anthony Green +Date: Tue Feb 8 07:52:40 2011 -0500 + + Refresh from GCC + +commit 5b9cd52784339a42e417174a55e310e214d435f9 +Author: Anthony Green +Date: Mon Nov 22 15:19:57 2010 -0500 + + win64-underscore patch + +commit 2db72615b50eb5c0f29725c02c740a2f0d7fc7d9 +Author: Anthony Green +Date: Sun Nov 21 10:50:56 2010 -0500 + + Rebase + +commit f6ab3edc23dc8fc7c47a31c896044150c23f04b5 +Author: Landon Fuller +Date: Wed Oct 27 19:34:51 2010 -0400 + + Include the license header in the generated output. + +commit cef619462887fa0f360e3ee702d1e04f112b5b38 +Author: Landon Fuller +Date: Wed Oct 27 13:59:30 2010 -0400 + + Add missing copyright/license header. + +commit 53f387b203413c9aa6e31f49dbb70d37d816330b +Author: Landon Fuller +Date: Sun Sep 19 19:57:17 2010 -0700 + + Minor README fix. + +commit 4fbcb5b5fbce11f4b168060e00639db33c85b75b +Author: Landon Fuller +Date: Sun Sep 19 19:50:37 2010 -0700 + + Minor README fix. + +commit 8e7652ef6acab5db7a29f786686a54f05cdbdc7d +Author: Landon Fuller +Date: Sun Sep 19 19:49:39 2010 -0700 + + Add a libffi-ios-specific github README. + +commit 83038cf24aa1a92b62b91ffee1dcc25d79243484 +Author: Landon Fuller +Date: Sun Sep 19 14:36:45 2010 -0700 + + Implement FFI_EXEC_TRAMPOLINE_TABLE allocator for iOS/ARM. + + This provides working closure support on iOS/ARM devices where + PROT_WRITE|PROT_EXEC is not permitted. The code passes basic + smoke tests, but requires further review. + +commit b00ff3e98fdde622cef617030e14d5356dff988f +Author: Landon Fuller +Date: Sun Sep 19 14:22:26 2010 -0700 + + Rename the generated symbol + +commit da2773e02ab26cc11a7fe87e985599f35cdf0649 +Author: Landon Fuller +Date: Sun Sep 19 14:21:37 2010 -0700 + + Modify the ffi_closure structures to hold table/table entry pointers instead of a code buffer. + +commit 01d71b7bed41844f80cb9feef20dcc5ece5ba2d0 +Author: Landon Fuller +Date: Sun Sep 19 14:21:14 2010 -0700 + + Regenerated the autoconf script + +commit 19afda0069c42e51c81dca7b10a5cf884b4cdce0 +Author: Landon Fuller +Date: Sun Sep 19 14:20:52 2010 -0700 + + Enable AC_SUBST for FFI_EXEC_TRAMPOLINE_TABLE + +commit 9e1196444e78aef20028c18891f44ebe39a815fd +Author: Landon Fuller +Date: Sun Sep 19 10:43:06 2010 -0700 + + Add a hard-coded FFI_EXEC_TRAMPOLINE_TABLE arm implementation. + + This implements support for re-mapping a shared table of executable + trampolines directly in front of a writable configuration page, working + around PROT_WRITE restrictions for sandboxed applications on Apple's + iOS. + + This implementation is for testing purposes; a proper allocator is still + necessary, and ARM-specific code needs to be moved out of + src/closures.c. + +commit f38364b399184e682fc3e785084bd497827bc5af +Author: Landon Fuller +Date: Sun Sep 19 10:42:36 2010 -0700 + + Fix symbol prefix for ffi_closure_SYSV_inner on Darwin. + +commit 36849e7716b77aa25e4175d1f4be1b93dbf47aac +Author: Landon Fuller +Date: Sun Sep 19 09:35:04 2010 -0700 + + Whitespace/comment fixes. + +commit b764162526854686e579a48b6ac5981f4eb886a3 +Author: Landon Fuller +Date: Sun Sep 19 09:04:34 2010 -0700 + + Fix the script name (build-iphone.sh -> build-ios.sh) + +commit a3d9aa85013341451ea97766485b7a11852d32b2 +Author: Landon Fuller +Date: Sun Sep 19 09:03:52 2010 -0700 + + Update the autogenerated autoconf/automake files. + +commit c71480eaf839f26bbdfcd8965f65ac4d8defddc0 +Author: Landon Fuller +Date: Sun Sep 19 09:02:05 2010 -0700 + + Update automake/autoconf to conditionally build src/arm/trampoline.S if FFI_EXEC_TRAMPOLINE_TABLE is enabled. + +commit 9af9291b73bc5e27ecd949bec8157f20426d65b8 +Author: Landon Fuller +Date: Sun Sep 19 08:52:33 2010 -0700 + + Add the trampoline table generated by gentramp.sh + +commit 68ce0c383ece84f69945d1c8c3fed03f7f9cb5d6 +Author: Landon Fuller +Date: Sun Sep 19 08:38:19 2010 -0700 + + Add a shell script that generates the ARM trampoline page. + + This generates a page of 340 trampolines, aligned within one page. The + trampolines use pc-relative addressing to reference config data + (context, jump address) from a page placed directly prior to the + trampoline page. This can be used on systems -- such as iOS -- that do not + support writable, executable memory by remapping the executable page + containing the trampolines directly above a newly allocated writable + config page. + +commit 75af086be8830a8eafe9b1ebda199d788bcb0c62 +Author: Landon Fuller +Date: Sat Sep 18 18:12:19 2010 -0700 + + Update autoconf files + +commit 1ac92cca9b02ef8d6a769f0de1adccd5c9630355 +Author: Landon Fuller +Date: Sat Sep 18 18:08:14 2010 -0700 + + Add autoconf check for W^X platforms that require a trampoline table. + + This adds the FFI_EXEC_TRAMPOLINE_TABLE. The flag is enabled for + arm-apple-darwin, where PROT_EXEC on writable (or formerly writable) pages is + not permitted for sandboxed binaries. + +commit be72fbab29b7190c702d8e1ac3d149855e95879d +Author: Landon Fuller +Date: Sat Sep 18 18:02:25 2010 -0700 + + Use the correct host triple for arm/darwin + +commit 70150bdf4509269965c72f2032bf74f285767afe +Author: Landon Fuller +Date: Sat Sep 18 16:38:03 2010 -0700 + + Add missing UNWIND entry; disables .pad on non-EABI targets. + +commit 6b452bafaec498df975ba8ac4c99de174e5f74f7 +Author: Landon Fuller +Date: Sat Sep 18 16:21:32 2010 -0700 + + Apple assembler support; fixed most gas/ELF-isms. + +commit 8ddac835b6f8b54ede764d0ea977dee4c82e2d67 +Author: Landon Fuller +Date: Sat Sep 18 15:38:06 2010 -0700 + + Fix placement of the __APPLE__ macro. + +commit 69043d02936bb0579ac59b4ee1ed8dec38c38db7 +Author: Landon Fuller +Date: Sat Sep 18 15:32:08 2010 -0700 + + Work-around libffi's FP ABI detection. + + On iOS, we must use the AAPCS floating point return value calling + conventions. libffi's ARM implementation will only use these conventions + if __SOFTFP__ is defined, which is not the case when GCC's + -mfloat-abi defaults to 'softfp' instead of 'soft'. To work around this + we manually define __SOFTFP__ for Apple platforms in the ARM-specific + sysv.S. + + See also: + http://developer.apple.com/library/ios/#documentation/Xcode/Conceptual/iPhoneOSABIReference/Introduction/Introduction.html + http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf + +commit a82e6c354ea805114642a6e440abd0832cb1d23f +Author: Landon Fuller +Date: Sat Sep 18 14:44:24 2010 -0700 + + Add a stub iOS build script to drive autoconf + +commit 84e8de6e9fc19388f6f1102c013b7d0d52940ecc +Author: Anthony Green +Date: Fri Aug 6 01:35:12 2010 -0400 + + Restore execute permissions + +commit 3aeecc9eb1a6feba6549849cdd335c926415a4fc +Author: Anthony Green +Date: Thu Aug 5 15:19:00 2010 -0400 + + Fix win64-struct-args patch + +commit 00d0b59cd13f89ab8b44bd894eb7f0a131fcb472 +Author: Anthony Green +Date: Thu Aug 5 14:56:53 2010 -0400 + + Fix debug build for windows + +commit bda487e87064f27965155459a62dc52a744778d0 +Author: Anthony Green +Date: Thu Aug 5 09:02:41 2010 -0400 + + Don't use -safeseh with ml64 + +commit c1d28ba8d5029795af313ffeb81c97efc6d4c847 +Author: Anthony Green +Date: Thu Aug 5 08:48:16 2010 -0400 + + stdcall-x86-closure-fix + +commit 5feacad4a56c85b3f23a267a30b2cf424cd59548 +Author: Anthony Green +Date: Thu Aug 5 08:30:04 2010 -0400 + + define generic symbols carefully + +commit 10ea848900bc3018ac213cef52b44cacbe5cbebc +Author: Anthony Green +Date: Thu Aug 5 08:24:27 2010 -0400 + + don't copy win64 struct args + +commit d14178be4c49c3ada44a9fe9efe11d444372ddab +Author: Anthony Green +Date: Fri Jul 23 09:14:00 2010 -0400 + + FFI_LAST_ABI fix + +commit 3f5b1375ab1e2b8e3d593e21b27097a4a50f9b83 +Author: Anthony Green +Date: Mon Jul 12 14:39:18 2010 -0400 + + rebase + +commit eaf444eabc4c78703c0f98ac0197b1619c1b1bef +Author: Anthony Green +Date: Sat Jul 10 08:59:09 2010 -0400 + + Fix selinux test + +commit 630974152247f100ece4d44f10c3721bb4599fbf +Author: Anthony Green +Date: Wed May 5 20:14:56 2010 -0400 + + Micharl Kohler's spelling fixes + +commit 9dc9a293f3d4589fcaf02dd4288c8cebaefa508e +Author: Anthony Green +Date: Tue Apr 13 10:33:52 2010 -0400 + + Rebase to latest GCC sources + +commit f2c2a4fce9b3eca9f39b4f3545118bc256da4a73 +Author: Anthony Green +Date: Tue Apr 13 10:19:28 2010 -0400 + + Remove warnings and add OS/2 support + +commit c0b69e57d529e33d18b658cc5572a21e3663247c +Author: Anthony Green +Date: Tue Mar 30 08:30:22 2010 -0400 + + Dan Witte's windows build fixes. + +commit 59a259f4d348f593b45f452309f4d020a28051c4 +Author: Anthony Green +Date: Mon Mar 15 05:57:51 2010 -0400 + + Remove junk file + +commit 3de1eb36d37a66829e606421939874d0d60d816d +Author: Anthony Green +Date: Mon Mar 15 05:57:24 2010 -0400 + + fix-comments patch + +commit c3813b6d7f8a777700f4c5862190c0db148d4de8 +Author: Anthony Green +Date: Tue Jan 26 16:48:56 2010 -0500 + + Rebuild Makefiles with automake 1.11.1 for CVE-2009-4029. + +commit 8d27f68baa365bf883b6053c5f6bc819646d5434 +Author: Anthony Green +Date: Fri Jan 15 11:35:37 2010 -0500 + + Mention recent changes in README + +commit ff3cd68b8cf2d9a28cad7aa9beff46236eacec8c +Author: Anthony Green +Date: Fri Jan 15 11:27:24 2010 -0500 + + Add msvc.sh wrapper + +commit cadeba6cb53414a1253582f1719c286665de7b6c +Author: Anthony Green +Date: Fri Jan 15 10:46:51 2010 -0500 + + Microsoft Visual C port + +commit 0739e7dc00db766eb64f502ec4137b817638c9a1 +Author: Anthony Green +Date: Fri Jan 15 09:48:33 2010 -0500 + + Add x86 Sun Studio compiler support + +commit edfdfd2e85b8d01d2455934f1d7f4d7eb2f3cf1c +Author: Anthony Green +Date: Wed Jan 13 02:56:19 2010 -0500 + + Add closure example doc + +commit 7b7a42f221cf171e8d09df34cac6dc1fd8458cc3 +Author: Anthony Green +Date: Tue Jan 12 09:14:14 2010 -0500 + + Rebase from GCC + +commit 4b18d1f73dc7733137869e4ab5725cb90c1c8fde +Author: Anthony Green +Date: Fri Jan 1 10:24:27 2010 -0500 + + Add x86-64 MingW to README + +commit c3042afaf3f84abbbe9c91bf9bc9896b0d9eb003 +Author: Anthony Green +Date: Fri Jan 1 08:08:02 2010 -0500 + + Reset quilt patches post 3.0.9 merge with GCC + +commit b0304e9679bdfec6ac45a57b5c96542697249418 +Author: Anthony Green +Date: Thu Dec 31 11:32:40 2009 -0500 + + Update version + +commit 2e7e03d014d9c9bf40e97ce75cba089ad052fa6b +Author: Anthony Green +Date: Thu Dec 31 07:43:22 2009 -0500 + + Final updates before 3.0.9 + +commit aea706c52825c8eee677ffa7fdbdd3aed1725492 +Author: Anthony Green +Date: Tue Dec 29 10:09:31 2009 -0500 + + really 3.0.9rc12 + +commit 0cfe60e9d13f132b88995cfee41f2156344f6fa2 +Author: Anthony Green +Date: Tue Dec 29 10:06:04 2009 -0500 + + 3.0.9rc12 + +commit 14e2e92e8645804b6940b3e96c98e9f7f384a6b2 +Author: Anthony Green +Date: Sun Dec 27 21:03:33 2009 -0500 + + 3.0.9rc11 + +commit 884402787bf8eaf7ec207085037cf8ace2f660ec +Author: Anthony Green +Date: Sat Dec 26 12:57:23 2009 -0500 + + HPUX support and avr32 test fixes. + +commit 01c78756aff22efb1f122f8e93e068d7bf2185c7 +Author: Anthony Green +Date: Sat Dec 26 10:05:18 2009 -0500 + + 3.0.9rc9 + +commit 70868464651320268d79c6894db5a50fdc11032a +Author: Anthony Green +Date: Sat Dec 26 09:58:03 2009 -0500 + + Remove xfails for mips and arm + +commit 838d4ad920ec85cf5ca3b511221d67f6d9a99024 +Author: Anthony Green +Date: Sat Dec 26 09:57:27 2009 -0500 + + Remove a bunch of xfails. + +commit 7e37eaaf772f48906e69618c773b0a36c3927de9 +Author: Anthony Green +Date: Sat Dec 26 07:46:50 2009 -0500 + + Fix huge_struct for solaris + +commit 07cc7a37194bc34064ebed7f2724333a798411c8 +Author: Anthony Green +Date: Sat Dec 26 07:23:04 2009 -0500 + + 3.0.9rc8 + +commit 2b9be16ffabc81326128bc1bbdddff8ddc5d13d3 +Author: Anthony Green +Date: Sat Dec 26 07:04:45 2009 -0500 + + 3.0.9rc8 + +commit 9458d88f676e9a21ab8993a54e16754b11687419 +Author: Anthony Green +Date: Sat Dec 26 07:02:27 2009 -0500 + + Rebase from GCC + +commit 6a3412417593f068a04dc6163f4269cb295ad5ca +Author: Anthony Green +Date: Sat Dec 26 06:51:33 2009 -0500 + + Add Andreas Schwab's powerpc fix + +commit 39c8792ece1043f41f4c395a2ce71f4cf0ff4674 +Author: Anthony Green +Date: Fri Dec 25 21:52:28 2009 -0500 + + 3.0.9rc7 + +commit 1d04af52e3e24db69f742064694c22f8df5cc70e +Author: Anthony Green +Date: Fri Dec 25 09:50:36 2009 -0500 + + Updated some mips XFAILs + +commit 26e9509c9b7929bc4fcf697071699051a652b1fd +Author: Anthony Green +Date: Fri Dec 25 02:19:23 2009 -0500 + + Clean up ChangeLog.libffi for older patches. + +commit 9c157d3215e4393777f83eb6fa801df6528f40d7 +Author: Anthony Green +Date: Fri Dec 25 02:15:40 2009 -0500 + + Clean up undefine_AC_ARG_VAR_PRECIOUS patch. + +commit d22de05b0bfc480766bc1240615ce2830eee71b8 +Author: Anthony Green +Date: Fri Dec 25 02:04:23 2009 -0500 + + Fix patches + +commit 1fe3dc7c20dc4dbd8fed0d19c8618027d44ed971 +Author: Anthony Green +Date: Fri Dec 25 01:39:00 2009 -0500 + + Add windows support patch. + +commit f7c0bc613a88f7dbc2d18b345c10fa438833c170 +Author: Anthony Green +Date: Fri Dec 25 01:22:11 2009 -0500 + + 3.0.9rc6 + +commit c7fa2da8260258c11ab1dc7ac06fb611a2c1b50f +Author: Anthony Green +Date: Thu Dec 24 07:22:44 2009 -0500 + + 3.0.9rc6 + +commit da11bece0fde66fc0268db3a01207dda857e25d2 +Author: Anthony Green +Date: Thu Dec 24 05:34:46 2009 -0500 + + Release 3.0.9rc5 + +commit e3399b11edeab546b066bfc18574f3edb905d0dc +Author: Anthony Green +Date: Thu Dec 24 01:09:32 2009 -0500 + + Update README + +commit 115ab36fceee69740a01ce49bc27e1908cc237b1 +Author: Anthony Green +Date: Thu Dec 24 00:22:00 2009 -0500 + + Update missing changes for 3.0.9r4. + +commit f8c7a245bf5a80bd7e730ec03fcad17c8dcfcb07 +Author: Anthony Green +Date: Wed Dec 23 23:46:22 2009 -0500 + + Switch to quilt. Rebase to latest GCC. + +commit ce806772f02387b9a74f6496a263a368bccd5d59 +Merge: cd98813 dcc1f6b +Author: Anthony Green +Date: Mon Oct 5 00:41:35 2009 -0400 + + Merge branch 'master' of git@github.com:atgreen/libffi + +commit dcc1f6b4f1ffd2713bf68b791a13f85d455c8b1b +Author: Anthony Green +Date: Mon Oct 5 00:29:33 2009 -0400 + + More clean up. + +commit 2829f5941a223b9d851d8ab6318318e6197d7e01 +Author: Anthony Green +Date: Mon Oct 5 00:28:03 2009 -0400 + + Clean up + +commit cd98813de517ea64041637e3e78d27a001d6d3b4 +Author: Anthony Green +Date: Mon Oct 5 00:25:29 2009 -0400 + + From Jens Rehsack. Fix for 64-bit AIX. + +commit e4a91de766acc47f6c50f13cc11719a65e23ecba +Author: Anthony Green +Date: Mon Oct 5 00:16:17 2009 -0400 + + From Abdulaziz Ghuloum. Adds special case for Snow Leopard. + +commit 3425a763bcdaadb8b430226f427ec833afdcc96a +Author: Anthony Green +Date: Sun Oct 4 23:57:29 2009 -0400 + + Fix detection of free/openbsd. From Alexis Ballier. + +commit 2340e7a777902de61499d47823ad8d5e0eeb6203 +Author: Anthony Green +Date: Sun Oct 4 23:53:17 2009 -0400 + + AVR support + +commit 5cbe2058c128e848446ae79fe15ee54260a90559 +Author: Anthony Green +Date: Sun Oct 4 23:53:11 2009 -0400 + + Initial stand-alone patch. + +commit c6dddbd02bad9654ed58cdb0feb360934d105dec +Author: Anthony Green +Date: Sun Oct 4 08:11:33 2009 -0400 + + Initial commit + +commit 5ffc0c37486fb1538bccc0ca7acc807d4f1af932 +Author: Anthony Green +Date: Sun Oct 4 07:58:22 2009 -0400 + + Update version to 3.0.9rc1. Add more useful things to .gitignore. + +commit bd29f83ee9f6fa6b65adee9d3f57834f364d9887 +Author: Anthony Green +Date: Tue Sep 29 12:07:26 2009 -0400 + + Add .gitignore + +commit 9474f853f83e3f0167c1b306177321bfcc93e56d +Author: Anthony Green +Date: Tue Sep 29 11:13:02 2009 -0400 + + Remove old CVSROOT files. + +commit 0c25275ec24bfe2c2c25a000465f0950ef9dd51b +Author: twall +Date: Wed Aug 19 12:57:34 2009 +0000 + + Apply Dave Korn's cygwin/GCC changes + +commit 39228c27ed3f677a95b46380a8d31602b5777e1a +Author: aph +Date: Tue Jun 16 18:00:47 2009 +0000 + + 2009-06-16 Wim Lewis + + * src/powerpc/ffi.c: Avoid clobbering cr3 and cr4, which are + supposed to be callee-saved. + * src/powerpc/sysv.S (small_struct_return_value): Fix overrun of + return buffer for odd-size structs. + +commit 5e93cc704d127c2c8ae7f5d2cef621145d43e777 +Author: aph +Date: Tue Jun 16 17:41:47 2009 +0000 + + 2009-06-16 Andreas Tobler + + PR libffi/40444 + * testsuite/lib/libffi-dg.exp (libffi_target_compile): Add + allow_stack_execute for Darwin. + +commit b509af8959dc371b92392c623522ea6f4946a71d +Author: aph +Date: Tue Jun 16 16:17:52 2009 +0000 + + 2009-06-16 Andrew Haley + + * configure.ac (TARGETDIR): Add missing blank lines. + * configure: Regenerate. + +commit d57e96dc56ee76fbbb9b59d73aeaa92354db5ecb +Author: aph +Date: Tue Jun 16 09:59:02 2009 +0000 + + 2009-06-16 Andrew Haley + + * testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/return_ll1.c, + testsuite/libffi.call/stret_medium2.c: Fix printf format + specifiers. + * testsuite/libffi.call/huge_struct.c: Ad x86 XFAILs. + * testsuite/libffi.call/float2.c: Fix dg-excess-errors. + * testsuite/libffi.call/ffitest.h, + testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRIuLL): Define. + +commit b01d6d1982c9e020507029bfd5a58a8c60d111fa +Author: aph +Date: Tue Jun 16 09:44:54 2009 +0000 + + 2009-06-16 Andrew Haley + + * testsuite/libffi.call/err_bad_typedef.c: xfail everywhere. + * testsuite/libffi.call/err_bad_abi.c: Likewise. + +commit 35b6ded138591900a88055a8a8ac1fadc29a76d6 +Author: aph +Date: Fri Jun 12 15:29:20 2009 +0000 + + 2009-06-11 Kaz Kojima + + * testsuite/libffi.call/cls_longdouble_va.c: Add xfail sh*-*-linux-*. + * testsuite/libffi.call/err_bad_abi.c: Add xfail sh*-*-*. + * testsuite/libffi.call/err_bad_typedef.c: Likewise. + +commit acc46605f2d95d67d69398e7644610f10a157ce3 +Author: aph +Date: Fri Jun 12 14:21:28 2009 +0000 + + 2009-06-12 Andrew Haley + + * ChangeLog.libffi: testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/return_ll1.c, + testsuite/libffi.call/stret_medium2.c: Fix printf format + specifiers. + testsuite/libffi.special/unwindtest.cc: include stdint.h. + +commit 16d1996ed0797bd7c11aca2b0fe7e7748751aaf6 +Author: twall +Date: Thu Jun 11 14:27:42 2009 +0000 + + update changelog + +commit 92a515c33efe91be3cb0258f01c63aff208489c7 +Author: twall +Date: Thu Jun 11 14:27:28 2009 +0000 + + use ffi_closure_alloc instead of stack-based closure + +commit e4363160ba9e50167f9ca0a7399d537a1d2cd0ce +Author: twall +Date: Thu Jun 11 14:26:23 2009 +0000 + + remove unused extern + +commit 1dc2781d2ba38f5f000ff70069d617fb21e1d2af +Author: twall +Date: Thu Jun 11 11:36:16 2009 +0000 + + remove not-yet-applied changelog entries + +commit bb27735fe689dac97ec0dc847ed8d3d519620109 +Author: twall +Date: Wed Jun 10 10:42:36 2009 +0000 + + add win64 support + +commit b2a54c100c74854a409820817d54617fdda39eb8 +Author: aph +Date: Mon Jun 8 16:50:49 2009 +0000 + + 2009-06-08 Andrew Haley + + * testsuite/libffi.call/err_bad_abi.c: Add xfails. + * testsuite/libffi.call/cls_longdouble_va.c: Add xfails. + * testsuite/libffi.call/cls_dbls_struct.c: Add xfail x86_64-*-linux-*. + * testsuite/libffi.call/err_bad_typedef.c: Add xfails. + + * testsuite/libffi.call/stret_medium2.c: Add __UNUSED__ to args. + * testsuite/libffi.call/stret_medium.c: Likewise. + * testsuite/libffi.call/stret_large2.c: Likewise. + * testsuite/libffi.call/stret_large.c: Likewise. + +commit 25723e7141f73d3736d7244b980c89d97db852b6 +Author: aph +Date: Fri Jun 5 13:03:40 2009 +0000 + + 2009-06-05 Andrew Haley + + * src/x86/win32.S (_ffi_closure_STDCALL): Import from gcc. + +commit 70758199c7cd41f411987360ccb302b497a56dc9 +Author: aph +Date: Thu Jun 4 16:29:58 2009 +0000 + + 2009-06-04 Andrew Haley + + * src/powerpc/ffitarget.h: Fix misapplied merge from gcc. + +commit e8bb12563f9aa23ddf36fa6a5b92b16b5c3e1a7f +Author: aph +Date: Thu Jun 4 14:59:18 2009 +0000 + + 2009-06-04 Andrew Haley + + * src/mips/o32.S, + src/mips/n32.S: Fix licence formatting. + +commit d66a8e32c3671479e3ce0f6819673e5932ba6b7f +Author: aph +Date: Thu Jun 4 14:43:40 2009 +0000 + + 2009-06-04 Andrew Haley + + * src/x86/darwin.S: Fix licence formatting. + src/x86/win32.S: Likewise. + src/sh64/sysv.S: Likewise. + src/sh/sysv.S: Likewise. + +commit 7c3b7fd6b5db746b5b09a718f3044f811372f941 +Author: aph +Date: Thu Jun 4 14:39:20 2009 +0000 + + 2009-06-04 Andrew Haley + + * src/sh64/ffi.c: Remove lint directives. Was missing from merge + of Andreas Tobler's patch from 2006-04-22. + +commit 1a2f93a8b362db13638afd9fcb3f2650180bfa17 +Author: aph +Date: Thu Jun 4 10:45:51 2009 +0000 + + 2009-06-04 Andrew Haley + + * src/sh/ffi.c: Apply missing hunk from Alexandre Oliva's patch of + 2007-03-07. + +commit 944c95cf7aaaaf7c5fa368cda4673dd38f45020e +Author: aph +Date: Wed Jun 3 17:42:56 2009 +0000 + + 2009-05-22 Dave Korn + + * src/x86/win32.S (_ffi_closure_STDCALL): New function. + (.eh_frame): Add FDE for it. + + 2009-05-22 Dave Korn + + * configure.ac: Also check if assembler supports pc-relative + relocs on X86_WIN32 targets. + * configure: Regenerate. + * src/x86/win32.S (ffi_prep_args): Declare extern, not global. + (_ffi_call_SYSV): Add missing function type symbol .def and + add EH markup labels. + (_ffi_call_STDCALL): Likewise. + (_ffi_closure_SYSV): Likewise. + (_ffi_closure_raw_SYSV): Likewise. + (.eh_frame): Add hand-crafted EH data. + + 2008-11-21 Eric Botcazou + + * src/sparc/ffi.c (ffi_prep_cif_machdep): Add support for + signed/unsigned int8/16 return values. + * src/sparc/v8.S (ffi_call_v8): Likewise. + (ffi_closure_v8): Likewise. + + 2008-03-26 Kaz Kojima + + * src/sh/sysv.S: Add .note.GNU-stack on Linux. + * src/sh64/sysv.S: Likewise. + + 2008-03-26 Daniel Jacobowitz + + * src/arm/sysv.S: Fix ARM comment marker. + +commit 00fa972430bb1535a4b34bf029ebcad500027b0c +Author: twall +Date: Sat Dec 27 16:59:05 2008 +0000 + + properly glob-match + +commit f5179e6794ac35af26fe86e468b8508a7a570c55 +Author: twall +Date: Fri Dec 26 19:06:28 2008 +0000 + + Mark XFAIL on longdouble tests for x86_64/mingw + +commit 80e2b5a749208c8a18f994ec5bee84594d051cc8 +Author: twall +Date: Mon Dec 22 15:21:15 2008 +0000 + + clean up tests for win64 use + +commit 7063d9996f742576095c7b0eb5016c0f9a670aec +Author: green +Date: Fri Dec 19 16:13:46 2008 +0000 + + Version 3.0.8 with x86-solaris support + +commit bdfeb13f0df0a63b19d62597517237b54d92228b +Author: green +Date: Fri Dec 19 15:47:44 2008 +0000 + + Bump to 3.0.7 + +commit 69205de17d6ac4c11d4ba92d6a5b40a0c5f246b2 +Author: green +Date: Thu Jul 24 18:03:48 2008 +0000 + + Many test fixes (failures due to excessive compiler warnings). + +commit 260d513fea00b3613fe957a44a157fe72c4ca29e +Author: green +Date: Thu Jul 17 13:13:52 2008 +0000 + + Version 3.0.6. sh/sh64 fixes. + +commit 3704031875feabb74e3655ed03cff4c2b3c76ac6 +Author: green +Date: Thu Apr 3 18:57:57 2008 +0000 + + Rev 3.0.5. + +commit 8406f5f48f7f58a1c982a93a95d521cf82b3241f +Author: green +Date: Thu Apr 3 18:57:34 2008 +0000 + + 3.0.5 + +commit 23a9e73212b62f9684cedb0ce70e92c59cfdaffa +Author: green +Date: Wed Mar 5 00:07:02 2008 +0000 + + 2008-03-04 Anthony Green + Blake Chaffin + hos@tamanegi.org + + * testsuite/libffi.call/cls_align_longdouble_split2.c + testsuite/libffi.call/cls_align_longdouble_split.c + testsuite/libffi.call/cls_dbls_struct.c + testsuite/libffi.call/cls_double_va.c + testsuite/libffi.call/cls_longdouble.c + testsuite/libffi.call/cls_longdouble_va.c + testsuite/libffi.call/cls_pointer.c + testsuite/libffi.call/cls_pointer_stack.c + testsuite/libffi.call/err_bad_abi.c + testsuite/libffi.call/err_bad_typedef.c + testsuite/libffi.call/huge_struct.c + testsuite/libffi.call/stret_large2.c + testsuite/libffi.call/stret_large.c + testsuite/libffi.call/stret_medium2.c + testsuite/libffi.call/stret_medium.c: New tests from Apple. + +commit 429e37d3ad653e52e75bf725c883ab79e859f89a +Author: green +Date: Thu Feb 28 04:50:19 2008 +0000 + + clicky + +commit 51e79c428348c033314f54bcb30f7e388c59e347 +Author: green +Date: Thu Feb 28 04:47:35 2008 +0000 + + getclicky + +commit affcab04e280efeace45a72c4dc6152c0e4f1b7f +Author: green +Date: Tue Feb 26 19:01:53 2008 +0000 + + 2008-02-26 Jakub Jelinek + Anthony Green + + * src/alpha/osf.S: Add .note.GNU-stack on Linux. + * src/s390/sysv.S: Likewise. + * src/powerpc/linux64.S: Likewise. + * src/powerpc/linux64_closure.S: Likewise. + * src/powerpc/ppc_closure.S: Likewise. + * src/powerpc/sysv.S: Likewise. + * src/x86/unix64.S: Likewise. + * src/x86/sysv.S: Likewise. + * src/sparc/v8.S: Likewise. + * src/sparc/v9.S: Likewise. + * src/m68k/sysv.S: Likewise. + * src/ia64/unix.S: Likewise. + * src/arm/sysv.S: Likewise. + +commit 59689d5522c159a3ac967adb6b891cf5f22c890f +Author: green +Date: Tue Feb 26 17:40:51 2008 +0000 + + 2008-02-26 Anthony Green + Thomas Heller + + * src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C + comment. + +commit b13c84cf4668828ff8429ba4a2f94cd1eb574ae0 +Author: green +Date: Tue Feb 26 17:38:15 2008 +0000 + + 2008-02-26 Anthony Green + Thomas Heller + + * include/ffi.h.in: Change void (*)() to void (*)(void). + +commit 265289f679ffd24a88ae1aa2cef0e4aa14703cd8 +Author: green +Date: Tue Feb 26 17:34:36 2008 +0000 + + 2008-02-26 Anthony Green + + * src/alpha/ffi.c: Change void (*)() to void (*)(void). + src/alpha/osf.S, src/arm/ffi.c, src/frv/ffi.c, src/ia64/ffi.c, + src/ia64/unix.S, src/java_raw_api.c, src/m32r/ffi.c, + src/mips/ffi.c, src/pa/ffi.c, src/pa/hpux32.S, src/pa/linux.S, + src/powerpc/ffi.c, src/powerpc/ffi_darwin.c, src/raw_api.c, + src/s390/ffi.c, src/sh/ffi.c, src/sh64/ffi.c, src/sparc/ffi.c, + src/x86/ffi.c, src/x86/unix64.S, src/x86/darwin64.S,> src/x86/ffi64.c: Ditto. + +commit fb5036cd6d0f909918e90f7d2d9fd80d46682d5d +Author: green +Date: Sun Feb 24 17:25:25 2008 +0000 + + fix date + +commit 40bec108e7d0181e6c9928aa7a33187bcc0f3d6f +Author: green +Date: Sun Feb 24 17:25:02 2008 +0000 + + New release + +commit b922048fa82ea109a4af269ee47bbc2a586bbac2 +Author: green +Date: Sun Feb 24 17:24:00 2008 +0000 + + 2008-02-24 Anthony Green + + * configure.ac: Accept openbsd*, not just openbsd. + Bump version to 3.0.4. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. + +commit affca4b92d06e5554784c7e9b233029ef83f7d8a +Author: green +Date: Fri Feb 22 21:53:29 2008 +0000 + + sync readme with web page. + +commit 3e53d8752ea74859b4c64fbbf935e62a937c4d78 +Author: green +Date: Fri Feb 22 21:52:38 2008 +0000 + + New release + +commit 4d92f6c8e78fe084be65f3e8b58b859901ba796d +Author: green +Date: Fri Feb 22 21:49:46 2008 +0000 + + 2008-02-22 Anthony Green + + * configure.ac: Bump version to 3.0.3. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. Clean up test docs. + +commit 0e185fa11a01f816824ba2687ed3715ab6219bef +Author: green +Date: Fri Feb 22 21:43:18 2008 +0000 + + Update configure script. + +commit f73986bd211cfbbaa593d1309504d0dc68626191 +Author: green +Date: Fri Feb 22 21:40:53 2008 +0000 + + 2008-02-22 Bjoern Koenig + Andreas Tobler + + * configure.ac: Add amd64-*-freebsd* target. + * configure: Regenerate. + +commit 0208f68fe5de30c33e7f70ebc281635917013f5a +Author: green +Date: Fri Feb 22 21:15:44 2008 +0000 + + 2008-02-22 Thomas Heller + + * configure.ac: Add x86 OpenBSD support. + * configure: Rebuilt. + +commit 01adb0e638a86cf0d5e668ed8e08be9b0cd2505f +Author: green +Date: Thu Feb 21 16:17:26 2008 +0000 + + Fix README. + +commit 1edd4563225981a14f7d4fb9919b1ed88e38082f +Author: green +Date: Thu Feb 21 13:39:01 2008 +0000 + + 3.0.2 + +commit c9b542800864e2204db6e83f3843a17813ba6165 +Author: green +Date: Thu Feb 21 13:36:43 2008 +0000 + + add missing file + +commit d5fa5633d5c8d3c212a2267cfa38fba4091baa2c +Author: green +Date: Thu Feb 21 13:36:19 2008 +0000 + + 2008-02-21 Anthony Green + + * configure.ac: Bump version to 3.0.2. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. + + 2008-02-21 Björn König + + * src/x86/freebsd.S: New file. + * configure.ac: Add x86 FreeBSD support. + * Makefile.am: Ditto. + +commit ac35bfc6fcadd8880c1efce36724820f9074b318 +Author: green +Date: Sat Feb 16 01:03:56 2008 +0000 + + Updated + +commit f7942975fee7b0162647dd79e2652615b737e98e +Author: green +Date: Sat Feb 16 01:02:00 2008 +0000 + + 2008-02-15 Anthony Green + + * configure.ac: Bump version to 3.0.1. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * libtool-version: Increment revision. + * README: Update for new release. + + 2008-02-15 David Daney + + * src/mips/ffi.c: Remove extra '>' from include directive. + (ffi_prep_closure_loc): Use clear_location instead of tramp. + +commit 59aa6bb1bfc86a610ac1a8b123443efd75854dd1 +Author: green +Date: Fri Feb 15 20:52:26 2008 +0000 + + Add more platforms. + +commit 45a45ab99074448be0ae1a8d2ade50d28b60f8de +Author: green +Date: Fri Feb 15 19:16:36 2008 +0000 + + 3.0 notes + +commit 4db74cbea888c9f1251b85baf00d99b83d3b994d +Author: green +Date: Fri Feb 15 19:10:26 2008 +0000 + + Update + +commit c3e1101ffabf44d8a2ee46e03ba9ab582050a825 +Author: green +Date: Fri Feb 15 18:43:40 2008 +0000 + + 2008-02-15 Anthony Green + + * configure.ac: Bump version to 3.0.0, + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + + 2008-02-15 David Daney + + * src/mips/ffi.c (USE__BUILTIN___CLEAR_CACHE): + Define (conditionally), and use it to include cachectl.h. + (ffi_prep_closure_loc): Fix cache flushing. + * src/mips/ffitarget.h (_ABIN32, _ABI64, _ABIO32): Define. + +commit 7e0cc12e9233ad285db41ce8dbdda61ed2a7fb06 +Author: green +Date: Fri Feb 15 15:51:03 2008 +0000 + + New release + +commit 2d7dc885ec40d53866f29984d595511942c8b686 +Author: green +Date: Fri Feb 15 15:30:26 2008 +0000 + + * man/ffi_call.3, man/ffi_prep_cif.3, man/ffi.3: + Update dates and remove all references to ffi_prep_closure. + * configure.ac: Bump version to 2.99.9. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + +commit a0525f03eeaaed33b1eac80e0c016455cee3615d +Author: green +Date: Fri Feb 15 15:14:30 2008 +0000 + + New release. + +commit 2b30dfb3146ee26ad956d00ee05eb835ca1a95b4 +Author: green +Date: Fri Feb 15 15:12:43 2008 +0000 + + * man/ffi_prep_closure.3: Delete. + * man/Makefile.am (EXTRA_DIST): Remove ffi_prep_closure.3. + (man_MANS): Ditto. + * man/Makefile.in: Rebuilt. + * configure.ac: Bump version to 2.99.8. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + +commit bf41e64840ebcb6cc31a6f028253c1fde82705d8 +Author: green +Date: Fri Feb 15 01:56:50 2008 +0000 + + Update. + +commit 4d39ddee677bbb61d621893b91e11eac5e7c4af7 +Author: green +Date: Fri Feb 15 01:24:06 2008 +0000 + + * configure.ac: Bump version to 2.99.7. + * configure, doc/stamp-vti, doc/version.texi: Rebuilt. + * include/ffi.h.in LICENSE src/debug.c src/closures.c + src/ffitest.c src/s390/sysv.S src/s390/ffitarget.h + src/types.c src/m68k/ffitarget.h src/raw_api.c src/frv/ffi.c + src/frv/ffitarget.h src/sh/ffi.c src/sh/sysv.S + src/sh/ffitarget.h src/powerpc/ffitarget.h src/pa/ffi.c + src/pa/ffitarget.h src/pa/linux.S src/java_raw_api.c + src/cris/ffitarget.h src/x86/ffi.c src/x86/sysv.S + src/x86/unix64.S src/x86/win32.S src/x86/ffitarget.h + src/x86/ffi64.c src/x86/darwin.S src/ia64/ffi.c + src/ia64/ffitarget.h src/ia64/ia64_flags.h src/ia64/unix.S + src/sparc/ffi.c src/sparc/v9.S src/sparc/ffitarget.h + src/sparc/v8.S src/alpha/ffi.c src/alpha/ffitarget.h + src/alpha/osf.S src/sh64/ffi.c src/sh64/sysv.S + src/sh64/ffitarget.h src/mips/ffi.c src/mips/ffitarget.h + src/mips/n32.S src/mips/o32.S src/arm/ffi.c src/arm/sysv.S + src/arm/ffitarget.h src/prep_cif.c: Update license text. + +commit d58b032b41a12bd3d72148da6822ab59dd698ff9 +Author: green +Date: Fri Feb 15 00:59:25 2008 +0000 + + New release + +commit 91e5478df6d5ac63efbb10f025807b4606afab56 +Author: green +Date: Fri Feb 15 00:50:30 2008 +0000 + + Update supported platforms. Bump version. + +commit bd0768f877c8f7fd0d36af2191b203d4d057b1ce +Author: green +Date: Fri Feb 15 00:45:33 2008 +0000 + + * configure.ac: Bump version to 2.99.5. + * configure: Rebuilt. + * Makefile.am (EXTRA_DIST): Add darwin64.S + * Makefile.in: Rebuilt. + * testsuite/lib/libffi-dg.exp: Remove libstdc++ bits from GCC tree. + * LICENSE: Update WARRANTY. + +commit 49d345f767bd2cfee951bceaab6a1a07986cf293 +Author: green +Date: Thu Feb 14 23:43:27 2008 +0000 + + update license reference + +commit 12ac48fc79b515db7c9accd9fcaa87b0dcefccdb +Author: green +Date: Thu Feb 14 23:42:08 2008 +0000 + + Update WARRANTY + +commit 6b91c41da87e78552f2990dfc504a0a3349f340b +Author: green +Date: Thu Feb 14 23:38:27 2008 +0000 + + fix tarball reference + +commit 2b59579e3533334bee4788e076b4e520c2ab518c +Author: green +Date: Thu Feb 14 23:35:58 2008 +0000 + + First update in 5 years! + +commit 6cbdf3f3a3777a93382a2d508ddef1c353ff0955 +Author: green +Date: Thu Feb 14 22:44:06 2008 +0000 + + Fix .pc file bug and bump version + +commit 1d1dc81104b209df3cfef0840735c59efae2f655 +Author: green +Date: Thu Feb 14 22:03:37 2008 +0000 + + Add man files and info file. Update README. Tag as 2.99.3. + +commit f045a2367f793fa8b01534cf2e25bcc46afc8fa1 +Author: tromey +Date: Thu Feb 14 20:46:57 2008 +0000 + + Move entry from ChangeLog to ChangeLog.libffi + +commit 6257f07d1a9efd27fa83639cfba281f5d3188731 +Author: tromey +Date: Thu Feb 14 20:33:17 2008 +0000 + + * aclocal.m4, Makefile.in, configure, fficonfig.h.in: Rebuilt. + * mdate-sh, texinfo.tex: New files. + * Makefile.am (info_TEXINFOS): New variable. + * doc/libffi.texi: New file. + * doc/version.texi: Likewise. + +commit 4232af563c5509c3760a33e3684a2b958be755e1 +Author: green +Date: Thu Feb 14 16:19:21 2008 +0000 + + * Makefile.am (AM_CFLAGS): Don't compile with -D. + (lib_LTLIBRARIES): Define. + (toolexeclib_LIBRARIES): Undefine. + * Makefile.in: Rebuilt. + * configure.ac: Reset version to 2.99.1. + * configure.in: Rebuilt. + +commit 961543615c31f092b578a4b4cda914db64f9d0fa +Author: green +Date: Thu Feb 14 15:57:40 2008 +0000 + + Fix typo. + +commit aeb0abab87222f637fbf352d4effd3b76b52ed26 +Author: green +Date: Thu Feb 14 15:54:27 2008 +0000 + + * libffi.pc.in: Usse @PACKAGE_NAME@ and @PACKAGE_VERSION@. + * configure.ac: Reset version to 2.99.1. + * configure.in: Rebuilt. + * Makefile.am (EXTRA_DIST): Add ChangeLog.libffi. + * Makefile.in: Rebuilt. + * LICENSE: Update copyright notice. + +commit 77fe243556433eae119d8bd7469bfccdd5bd8a1a +Author: green +Date: Thu Feb 14 15:37:00 2008 +0000 + + Fix make dist again + +commit d4970cf4529459bf0f0e43c602cac396786c6802 +Author: green +Date: Thu Feb 14 15:18:56 2008 +0000 + + Fix make dist + +commit f0b1462f2d3024922ad71421bd5c4311fcb16da5 +Author: green +Date: Thu Feb 14 15:01:41 2008 +0000 + + Use pkgconfig. Increment libtool CURRENT version. + +commit 27e52f33baa069012a5adb2a3807f9ca1f2165ab +Author: green +Date: Sun Feb 3 13:59:48 2008 +0000 + + Fix header installs when using DESTDIR. + +commit fadab28eb6e33fb6dcdd7b9323e147142216d548 +Author: twall +Date: Sun Feb 3 12:32:22 2008 +0000 + + update changelog + +commit b5e44c8dfa92c87b99762c303cf5574a16db8f27 +Author: twall +Date: Sun Feb 3 01:12:32 2008 +0000 + + offset from code base address, not data base address + +commit f359848d1a995c0e44566d815f218729dc996e22 +Author: green +Date: Fri Feb 1 21:29:43 2008 +0000 + + Fix header installs. + +commit c30df49e157c7bfc8e19e3f8a72b9464fe225e54 +Author: green +Date: Fri Feb 1 21:13:55 2008 +0000 + + Revert my broken changes to twall's patch. + +commit 675561bb9aa0732c76698df10dd3007b5d0ec759 +Author: green +Date: Thu Jan 31 13:44:25 2008 +0000 + + Fix make dist . + +commit abc0bbf3813dc43e23d4c23e6fe794dbf287639b +Author: green +Date: Thu Jan 31 11:58:57 2008 +0000 + + Add Tim Wall's x86 windows patch. + +commit e332366d15a31198735b593ec8f7fc0558d783b8 +Author: green +Date: Wed Jan 30 13:21:02 2008 +0000 + + Add HJ's -fomit-frame-pointer struct return fix + +commit d4204240392af5b7750a08671b08e9c22dff5e93 +Author: green +Date: Wed Jan 30 12:42:34 2008 +0000 + + Clean up for new automake. + +commit f4932dd020df574637c9fb3fc1bb18e5a8f304cc +Author: green +Date: Wed Jan 30 12:40:25 2008 +0000 + + Fixes to run testsuite + +commit 085520ddc8db6a916bfc416b871fcb2d00074d40 +Author: green +Date: Tue Jan 29 15:16:43 2008 +0000 + + New files from gcc tree. + +commit 77175b3f7234e4875a4ef554ed1fe9fdc4133794 +Author: green +Date: Tue Jan 29 15:15:20 2008 +0000 + + Latest gcc svn sources + +commit 2544e45a0b2b634053df02da3a2ed9680eeed2a1 +Author: green +Date: Tue Jan 29 14:28:13 2008 +0000 + + Install ffitarget.h in $prefix/include. + +commit 6002211b1cc4daeb587d054b4f83968bda2c981e +Author: green +Date: Tue Jan 29 12:30:10 2008 +0000 + + Add new files. + +commit ccabd2b16be883cd03e5f0cd88ccfdd6ca39239d +Author: green +Date: Tue Jan 29 12:28:15 2008 +0000 + + Merge from gcc + +commit e680ecfbfca1da8d1823e48bc89b8375e66e128b +Author: tromey +Date: Sun Dec 24 23:12:15 2006 +0000 + + Pulled in libffi from gcc trunk. + Fixed build and install for standalone use. + +commit e7ba08965942ce872fdbc69f70f9848cc3d0bad6 +Author: root +Date: Sun Jun 4 23:22:24 2006 +0000 + + sourcware.org + +commit 0cd4aa24e21aaa964dfbdebc25ec5c8188049375 +Author: root +Date: Sun May 30 01:51:57 2004 +0000 + + Add LockDir + +commit 5826120fbd940d26cca76ed2522187505581e1ed +Author: green +Date: Tue Nov 4 06:09:08 2003 +0000 + + Add link to Gianni's web site. + +commit 220aa4b27db42d7ffaac5056000d5179f00d5ea3 +Author: jsm +Date: Tue Jan 21 08:07:42 2003 +0000 + + Newer, better, increased from before! (list of acceptable anon usernames) + +commit 1c3adc892cc1403dc4d3d7003a2385899836612e +Author: green +Date: Fri Dec 6 01:28:03 2002 +0000 + + Fixed Cygnus references. + +commit 4af66bb62fab9a8e318af3bf01e5486596a0c8d4 +Author: green +Date: Sun Oct 21 19:18:42 2001 +0000 + + Testsuite fixes. + +commit 5435965f9015ce40584c98d3816c3d05e7de1d21 +Author: green +Date: Mon Apr 23 00:32:03 2001 +0000 + + * include/ffi_common.h: Delete, after moving contents to... + * include/ffi_private.h: Subsume contents of ffi_common.h. + * include/Makefile.am (noinst_HEADERS): Remove ffi_common.h. + * include/Makefile.in: Rebuilt. + * arm/ffi.c, m68k/ffi.c, mips/ffi.c, powerpc/ffi.c, s390/ffi.c, + ia64/ffi.c: Include ffi_private.h, not ffi_common.h. + * alpha/ffi.c, sparc/ffi.c, x86/ffi.c: Don't include ffi_common.h. + * types.c, raw_api.c, java_raw_api.c, prep_cif.c: Don't include + ffi_common.h. + * debug.c: Include ffi_private.h instead of ffi_common.h. + + * mips/ffi.c (calc_n32_struct_flags): Make static. + (FIX_ARGP): Remove call to debugging routine ffi_stop_here. + + * mips/n32.S: Include ffi_private.h. + * mips/o32.S: Include ffi_private.h. + +commit 6fdb7de0fe3b7385e1fd78812ae69d9b3069d994 +Author: green +Date: Sun Apr 22 19:38:34 2001 +0000 + + * README: Update some comments. + + * Makefile.am (SUBDIRS): Add include so ffi.h gets installed. + * Makefile.in: Rebuilt. + + * include/ffi.h: Change ALPHA to __alpha__ and SPARC to __sparc__. + * types.c: Ditto. + * prep_cif.c (ffi_prep_cif): Ditto. + + * alpha/ffi.c, alpha/osf.S, sparc/ffi.c, sparc/v8.S, sparc/v9.S: + Include ffi_private.h. + + * include/ffi_private.h (FFI_TYPE_LAST): Define. + +commit bc7144b01b9707ef35f1a2e3e6996e005e82953a +Author: green +Date: Sun Apr 22 18:28:36 2001 +0000 + + Moved files from old home + +commit e57279831e20368c1aa1d2b35462b8629be73959 +Author: green +Date: Sun Apr 22 18:23:47 2001 +0000 + + These are dead. + +commit 7247436b5fe71767b29dc02b4da0fe18b08082e6 +Author: green +Date: Sun Apr 22 18:22:43 2001 +0000 + + All these files live somewhere else now. + +commit a8b0d40ff908e275028f676870c31d0d70274a98 +Author: green +Date: Sun Apr 22 18:17:14 2001 +0000 + + Many changes. Not quite there yet. + +commit f893d2273355710a290a26faebf5f12c3a34d0e3 +Author: green +Date: Sun Apr 22 18:13:22 2001 +0000 + + Moved m68k files + +commit 688ddfeced89cbb9d37b53005e1f7f2b9c78a8d7 +Author: green +Date: Sun Apr 22 18:12:33 2001 +0000 + + New, target indepentent, header + +commit f9e40776d488d5ecf43b3ae21444a1a2f6eca528 +Author: green +Date: Sun Apr 22 18:11:57 2001 +0000 + + Many changes. + +commit 8c1d2eb47f6bc314c431b75c85c107e8e43c4a76 +Author: green +Date: Sun Apr 22 18:10:47 2001 +0000 + + Many changes + +commit 1359dfc6582680a158b3caa3efb7a368da4aa12d +Author: green +Date: Sun Apr 22 18:10:20 2001 +0000 + + Moved ia64 files + +commit 6e2de5eee316a4579869aff50c7c5f6f478582d8 +Author: green +Date: Sun Apr 22 18:08:11 2001 +0000 + + Moved arm files + +commit 8807355af34cba8ffe87aee51152dfccec2771fa +Author: green +Date: Mon Apr 9 00:58:38 2001 +0000 + + Many many updates. Merge from gcc and then some. + +commit f7e9f91adec4ff1c2e7a13b3de81d2c5a3f55e7e +Author: green +Date: Mon Apr 17 03:32:37 2000 +0000 + + Mnay fixes. + +commit c4860de618f4956283f5c8230a2544e403dfe390 +Author: green +Date: Mon Apr 17 03:18:46 2000 +0000 + + Merge from libgcj. Merged patches from net. See ChangeLog for details. + +commit c578b58314990c3853429297c38ba14015fec5fa +Author: jsm +Date: Sat Oct 9 20:18:16 1999 +0000 + + 1999-10-09 Jason Molenda (jsm@bugshack.cygnus.com) + + * CVSROOT/auto_checkout, CVSROOT/commit_prep, CVSROOT/log_accum: + Deleted; generic versions now used for all repositories. + + * CVSROOT/commitinfo, CVSROOT/loginfo: Change pathnames to + generic versions. + + * CVSROOT/checkoutlist: Don't try to check out the removed + files any longer. + +commit acdb20051207fed7652dd9f122f65de5458c474c +Author: jsm +Date: Sat Oct 9 20:18:15 1999 +0000 + + 1999-10-09 Jason Molenda (jsm@bugshack.cygnus.com) + + * CVSROOT/auto_checkout, CVSROOT/commit_prep, CVSROOT/log_accum: + Deleted; generic versions now used for all repositories. + + * CVSROOT/commitinfo, CVSROOT/loginfo: Change pathnames to + generic versions. + + * CVSROOT/checkoutlist: Don't try to check out the removed + files any longer. + +commit e75be655ceedf7ab24c4e99d75eec9efeb979bc7 +Author: green +Date: Sun Aug 8 13:16:41 1999 +0000 + + New configury + +commit d6669a0dd5b266005325bbf6d5a8ff34574d809e +Author: green +Date: Sun Aug 8 13:05:12 1999 +0000 + + * include/ffi.h.in: Try to work around messy header problem + with PACKAGE and VERSION. + + * configure: Rebuilt. + * configure.in: Change version to 2.00-beta. + + * fficonfig.h.in: Rebuilt. + * acconfig.h (FFI_NO_STRUCTS, FFI_NO_RAW_API): Define. + + * src/x86/ffi.c (ffi_raw_call): Rename. + +commit 4819d52b007934a40d6d29a75ee30e857c4a93ae +Author: green +Date: Wed Aug 4 18:02:34 1999 +0000 + + New file for Kresten's closure work + +commit 2dbf801eb427cbf5021a9e1e512b5fc523524700 +Author: green +Date: Wed Aug 4 18:00:05 1999 +0000 + + Kresten's closure work. Initial checkin. + +commit d170961701b0f2bf7e824d7caba2ebe10002ed84 +Author: green +Date: Thu Jul 8 14:36:52 1999 +0000 + + * configure.in: Add x86 and powerpc BeOS configurations. + From Makoto Kato . + +commit c7747d976924ec6f2229cbcfbbdb98d364e10de9 +Author: jsm +Date: Wed May 12 23:32:16 1999 +0000 + + 1999-05-12 Jason Molenda (jsm@bugshack.cygnus.com) + * index.html: Add links to libffi* mail list archives. + +commit dd2aa9a8de22e26df3bbc85d068358641f6202f7 +Author: green +Date: Thu May 6 05:34:36 1999 +0000 + + * configure.in: Add warning about this being beta code. + Remove src/Makefile.am from the picture. + * configure: Rebuilt. + * Makefile.am: Move logic from src/Makefile.am. Add changes + to support libffi as a target library. + * Makefile.in: Rebuilt. + * aclocal.m4, config.guess, config.sub, ltconfig, ltmain.sh: + Upgraded to new autoconf, automake, libtool. + * README: Tweaks. + * LICENSE: Update copyright date. + * src/Makefile.am, src/Makefile.in: Removed. + +commit 4e9452abed58a3058ccdb446f96a29d50dda1f34 +Author: green +Date: Wed May 5 22:06:13 1999 +0000 + + Updated to new automake, libtool, autoconf - nothing works :-) + +commit 6d3b2bddaf4967fba8b8656c01bfc77ec0f2800c +Author: jsm +Date: Mon Apr 26 15:55:28 1999 +0000 + + 1999-04-26 Jason Molenda (jsm@bugshack.cygnus.com) + * index.html: Missed a reference to libffi-discuss@cygnus.com. Fixed. + +commit ebc6a9c28af831d3d187af8ff17319f0f309bd98 +Author: jsm +Date: Mon Apr 26 15:53:29 1999 +0000 + + 1999-04-26 Jason Molenda (jsm@bugshack.cygnus.com) + * index.html: Change links to ftp directory to point to sourceware + directory. + Change mailing list subscription forms to point to sourceware lists. + +commit 78ffc52a8b257061348c576ccb6fbbf8b48b0fff +Author: jsm +Date: Sun Apr 18 01:33:21 1999 +0000 + + Standard sourceware setup. + +commit b4d77e827d7ebef7e57ebcd71e71c15c62f1e0a8 +Author: jsm +Date: Mon Nov 30 11:11:25 1998 +0000 + + Small typeo. (I wouldn't bother except that it made the sentence hard + for me to parse on a casual read.) + +commit bfb73f08fdc987e37070c5fb0b196fbd28872888 +Author: jsm +Date: Mon Nov 30 10:44:55 1998 +0000 + + A few cleanups. Most notably, point to the correct subscribe cgi-bin + script. + +commit af8b7f037ccee3b7939ee226a1a2bbc2f057b35c +Author: green +Date: Mon Nov 30 06:20:05 1998 +0000 + + * index.html: Reformatted and updated to reflect hosting on + sourceware.cygnus.com (new mailing lists, etc). + +commit 334f0b060942aff8d26badaf7dde7830450dc5da +Author: green +Date: Sun Nov 29 16:56:12 1998 +0000 + + initial snapshot of documentation + +commit 3ab5cb4a1dcc7ecd7e773c97582b0099976c4753 +Author: green +Date: Sun Nov 29 16:56:10 1998 +0000 + + Initial revision + +commit d2a9eb5a8b7cbc8b769809cad59c82b975c178e2 +Merge: d3782ec bc75c54 +Author: green +Date: Sun Nov 29 16:48:16 1998 +0000 + + This commit was generated by cvs2svn to compensate for changes in r7, which + included commits to RCS files with non-trunk default branches. + +commit bc75c54bd311658005b065f1bf201b204c81cbca +Author: green +Date: Sun Nov 29 16:48:16 1998 +0000 + + Import of v1 code. + +commit d3782ec8160c644421dcea17b605fec6e328f14e +Author: jsm +Date: Fri Nov 20 20:18:00 1998 +0000 + + Send commit messages to mailing lists. + +commit 8d8d3843c484c2bb70d8375b2b799f75eb03f709 +Author: jsm +Date: Thu Oct 1 22:08:36 1998 +0000 + + initial checkin + +commit 49634f3bf221cc1939abafc788f7e4e31293fe73 +Author: jsm +Date: Thu Oct 1 22:08:35 1998 +0000 + + Add standard setup. + +commit c64a84c7693f8cd400fb94bba3c9bcfd9ad1fc36 +Author: jsm +Date: Thu Oct 1 22:08:34 1998 +0000 + + Add readers and standard modules file. + +commit 9813273b07fd082da573b3b6bfb8d23809b59eea +Author: jsm +Date: Thu Oct 1 22:08:33 1998 +0000 + + initial checkin diff --git a/Modules/_ctypes/libffi/ChangeLog.libffi-3.1 b/Modules/_ctypes/libffi/ChangeLog.libffi-3.1 new file mode 100644 index 000000000000..8f7f50d6f993 --- /dev/null +++ b/Modules/_ctypes/libffi/ChangeLog.libffi-3.1 @@ -0,0 +1,6000 @@ +2014-03-16 Josh Triplett + + * ChangeLog: Archive to ChangeLog.libffi-3.1 and delete. Future + changelogs will come from git, with autogenerated snapshots shipped in + distributed tarballs. + +2014-03-16 Josh Triplett + + Add support for stdcall, thiscall, and fastcall on non-Windows + x86-32. + + Linux supports the stdcall calling convention, either via + functions explicitly declared with the stdcall attribute, or via + code compiled with -mrtd which effectively makes stdcall the + default. + + This introduces FFI_STDCALL, FFI_THISCALL, and FFI_FASTCALL on + non-Windows x86-32 platforms, as non-default calling conventions. + + * Makefile.am: Compile in src/x86/win32.S on non-Windows x86-32. + * src/x86/ffitarget.h: Add FFI_STDCALL, FFI_THISCALL, and + FFI_FASTCALL on non-Windows x86-32. Increase trampoline size to + accomodate these calling conventions, and unify some ifdeffery. + * src/x86/ffi.c: Add support for FFI_STDCALL, FFI_THISCALL, and + FFI_FASTCALL on non-Windows x86-32 platforms; update ifdeffery. + * src/x86/win32.S: Support compiling on non-Windows x86-32 + platforms. On those platforms, avoid redefining the SYSV symbols + already provided by src/x86/sysv.S. + * testsuite/libffi.call/closure_stdcall.c: Run on non-Windows. + #define __stdcall if needed. + * testsuite/libffi.call/closure_thiscall.c: Run on non-Windows. + #define __fastcall if needed. + * testsuite/libffi.call/fastthis1_win32.c: Run on non-Windows. + * testsuite/libffi.call/fastthis2_win32.c: Ditto. + * testsuite/libffi.call/fastthis3_win32.c: Ditto. + * testsuite/libffi.call/many2_win32.c: Ditto. + * testsuite/libffi.call/many_win32.c: Ditto. + * testsuite/libffi.call/strlen2_win32.c: Ditto. + * testsuite/libffi.call/strlen_win32.c: Ditto. + * testsuite/libffi.call/struct1_win32.c: Ditto. + * testsuite/libffi.call/struct2_win32.c: Ditto. + +2014-03-16 Josh Triplett + + * prep_cif.c: Remove unnecessary ifdef for X86_WIN32. + ffi_prep_cif_core had a special case for X86_WIN32, checking for + FFI_THISCALL in addition to the FFI_FIRST_ABI-to-FFI_LAST_ABI + range before returning FFI_BAD_ABI. However, on X86_WIN32, + FFI_THISCALL already falls in that range, making the special case + unnecessary. Remove it. + +2014-03-16 Josh Triplett + + * testsuite/libffi.call/closure_stdcall.c, + testsuite/libffi.call/closure_thiscall.c: Remove fragile stack + pointer checks. These files included inline assembly to save the + stack pointer before and after the call, and compare the values. + However, compilers can and do leave the stack in different states + for these two pieces of inline assembly, such as by saving a + temporary value on the stack across the call; observed with gcc + -Os, and verified as spurious through careful inspection of + disassembly. + +2014-03-16 Josh Triplett + + * testsuite/libffi.call/many.c: Avoid spurious failure due to + excess floating-point precision. + * testsuite/libffi.call/many_win32.c: Ditto. + +2014-03-16 Josh Triplett + + * libtool-ldflags: Re-add. + +2014-03-16 Josh Triplett + + * Makefile.in, aclocal.m4, compile, config.guess, config.sub, + configure, depcomp, include/Makefile.in, install-sh, + libtool-ldflags, ltmain.sh, m4/libtool.m4, m4/ltoptions.m4, + m4/ltsugar.m4, m4/ltversion.m4, m4/lt~obsolete.m4, + man/Makefile.in, mdate-sh, missing, testsuite/Makefile.in: Delete + autogenerated files from version control. + * .gitignore: Add autogenerated files. + * autogen.sh: New script to generate the autogenerated files. + * README: Document requirement to run autogen.sh when building + directly from version control. + * .travis.yml: Run autogen.sh + +2014-03-14 Anthony Green + + * configure, Makefile.in: Rebuilt. + +2014-03-10 Mike Hommey + + * configure.ac: Allow building for mipsel with Android NDK r8. + * Makefile.am (AM_MAKEFLAGS): Replace double quotes with single + quotes. + +2014-03-10 Landry Breuil + + * configure.ac: Ensure the linker supports @unwind sections in libffi. + +2014-03-01 Anthony Green + + * Makefile.am (EXTRA_DIST): Replace old scripts with + generate-darwin-source-and-headers.py. + * Makefile.in: Rebuilt. + +2014-02-28 Anthony Green + + * Makefile.am (AM_CFLAGS): Reintroduce missing -DFFI_DEBUG for + --enable-debug builds. + * Makefile.in: Rebuilt. + +2014-02-28 Makoto Kato + + * src/closures.c: Fix build failure when using clang for Android. + +2014-02-28 Marcin Wojdyr + + * libffi.pc.in (toolexeclibdir): use -L${toolexeclibdir} instead + of -L${libdir}. + +2014-02-28 Paulo Pizarro + + * src/bfin/sysv.S: Calling functions in shared libraries requires + considering the GOT. + +2014-02-28 Josh Triplett + + * src/x86/ffi64.c (classify_argument): Handle case where + FFI_TYPE_LONGDOUBLE == FFI_TYPE_DOUBLE. + +2014-02-28 Anthony Green + + * ltmain.sh: Generate with libtool-2.4.2.418. + * m4/libtool.m4, m4/ltoptions.m4, m4/ltversion.m4: Ditto. + * configure: Rebuilt. + +2014-02-28 Dominik Vogt + + * configure.ac (AC_ARG_ENABLE struct): Fix typo in help + message. + (AC_ARG_ENABLE raw_api): Ditto. + * configure, fficonfig.h.in: Rebuilt. + +2014-02-28 Will Newton + + * src/arm/sysv.S: Initialize IP register with FP. + +2014-02-28 Yufeng Zhang + + * src/aarch64/sysv.S (ffi_closure_SYSV): Use x29 as the + main CFA reg; update cfi_rel_offset. + +2014-02-15 Marcus Comstedt + + * src/powerpc/ffi_linux64.c, src/powerpc/linux64_closure.S: Remove + assumption on contents of r11 in closure. + +2014-02-09 Heiher + + * src/mips/n32.S: Fix call floating point va function. + +2014-01-21 Zachary Waldowski + + * src/aarch64/ffi.c: Fix missing semicolons on assertions under + debug mode. + +2013-12-30 Zachary Waldowski + + * .gitignore: Exclude darwin_* generated source and build_* trees. + * src/aarch64/ffi.c, src/arm/ffi.c, src/x86/ffi.c: Inhibit Clang + previous prototype warnings. + * src/arm/ffi.c: Prevent NULL dereference, fix short type warning + * src/dlmalloc.c: Fix warnings from set_segment_flags return type, + and the native use of size_t for malloc on platforms + * src/arm/sysv.S: Use unified syntax. Clang clean-ups for + ARM_FUNC_START. + * generate-osx-source-and-headers.py: Remove. + * build-ios.sh: Remove. + * libffi.xcodeproj/project.pbxproj: Rebuild targets. Include + x86_64+aarch64 pieces in library. Export headers properly. + * src/x86/ffi64.c: More Clang warning clean-ups. + * src/closures.c (open_temp_exec_file_dir): Use size_t. + * src/prep_cif.c (ffi_prep_cif_core): Cast ALIGN result. + * src/aarch64/sysv.S: Use CNAME for global symbols. Only use + .size for ELF targets. + * src/aarch64/ffi.c: Clean up for double == long double. Clean up + from Clang warnings. Use Clang cache invalidation builtin. Use + size_t in place of unsigned in many places. Accommodate for + differences in Apple AArch64 ABI. + +2013-12-02 Daniel Rodríguez Troitiño + + * generate-darwin-source-and-headers.py: Clean up, modernize, + merged version of previous scripts. + +2013-11-21 Anthony Green + + * configure, Makefile.in, include/Makefile.in, include/ffi.h.in, + man/Makefile.in, testsuite/Makefile.in, fficonfig.h.in: Rebuilt. + +2013-11-21 Alan Modra + + * Makefile.am (EXTRA_DIST): Add new src/powerpc files. + (nodist_libffi_la_SOURCES ): Likewise. + * configure.ac (HAVE_LONG_DOUBLE_VARIANT): Define for powerpc. + * include/ffi.h.in (ffi_prep_types): Declare. + * src/prep_cif.c (ffi_prep_cif_core): Call ffi_prep_types. + * src/types.c (FFI_NONCONST_TYPEDEF): Define and use for + HAVE_LONG_DOUBLE_VARIANT. + * src/powerpc/ffi_powerpc.h: New file. + * src/powerpc/ffi.c: Split into.. + * src/powerpc/ffi_sysv.c: ..new file, and.. + * src/powerpc/ffi_linux64.c: ..new file, rewriting parts. + * src/powerpc/ffitarget.h (enum ffi_abi): Rewrite powerpc ABI + selection as bits controlling features. + * src/powerpc/linux64.S: For consistency, use POWERPC64 rather + than __powerpc64__. + * src/powerpc/linux64_closure.S: Likewise. + * src/powerpc/ppc_closure.S: Likewise. Move .note.FNU-stack + inside guard. + * src/powerpc/sysv.S: Likewise. + * configure: Regenerate. + * fficonfig.h.in: Regenerate. + * Makefile.in: Regenerate. + +2013-11-20 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_cif_machdep_core): Use + NUM_FPR_ARG_REGISTERS64 and NUM_GPR_ARG_REGISTERS64 not their + 32-bit versions for 64-bit code. + * src/powerpc/linux64_closure.S: Don't use the return value area + as a parameter save area on ELFv2. + +2013-11-18 Iain Sandoe + + * src/powerpc/darwin.S (EH): Correct use of pcrel FDE encoding. + * src/powerpc/darwin_closure.S (EH): Likewise. Modernise picbase + labels. + +2013-11-18 Anthony Green + + * src/arm/ffi.c (ffi_call): Hoist declaration of temp to top of + function. + * src/arm/ffi.c (ffi_closure_inner): Moderize function declaration + to appease compiler. + Thanks for Gregory P. Smith . + +2013-11-18 Anthony Green + + * README (tested): Mention PowerPC ELFv2. + +2013-11-16 Alan Modra + + * src/powerpc/ppc_closure.S: Move errant #endif to where it belongs. + Don't bl .Luint128. + +2013-11-16 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_cif_machdep_core): Use #if _CALL_ELF + test to select parameter save sizing for ELFv2 vs. ELFv1. + * src/powerpc/ffitarget.h (FFI_V2_TYPE_FLOAT_HOMOG, + FFI_V2_TYPE_DOUBLE_HOMOG, FFI_V2_TYPE_SMALL_STRUCT): Define. + (FFI_TRAMPOLINE_SIZE): Define variant for ELFv2. + * src/powerpc/ffi.c (FLAG_ARG_NEEDS_PSAVE): Define. + (discover_homogeneous_aggregate): New function. + (ffi_prep_args64): Adjust start of param save area for ELFv2. + Handle homogenous floating point struct parms. + (ffi_prep_cif_machdep_core): Adjust space calculation for ELFv2. + Handle ELFv2 return values. Set FLAG_ARG_NEEDS_PSAVE. Handle + homogenous floating point structs. + (ffi_call): Increase size of smst_buffer for ELFv2. Handle ELFv2. + (flush_icache): Compile for ELFv2. + (ffi_prep_closure_loc): Set up ELFv2 trampoline. + (ffi_closure_helper_LINUX64): Don't return all structs directly + to caller. Handle homogenous floating point structs. Handle + ELFv2 struct return values. + * src/powerpc/linux64.S (ffi_call_LINUX64): Set up r2 for + ELFv2. Adjust toc save location. Call function pointer using + r12. Handle FLAG_RETURNS_SMST. Don't predict branches. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Set up r2 + for ELFv2. Define ELFv2 versions of STACKFRAME, PARMSAVE, and + RETVAL. Handle possibly missing parameter save area. Handle + ELFv2 return values. + (.note.GNU-stack): Move inside outer #ifdef. + +2013-11-16 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_cif_machdep): Revert 2013-02-08 + change. Do not consume an int arg when returning a small struct + for FFI_SYSV ABI. + (ffi_call): Only use bounce buffer when FLAG_RETURNS_SMST. + Properly copy bounce buffer to destination. + * src/powerpc/sysv.S: Revert 2013-02-08 change. + * src/powerpc/ppc_closure.S: Remove stray '+'. + +2013-11-16 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_args64): Align struct parameters + according to __STRUCT_PARM_ALIGN__. + (ffi_prep_cif_machdep_core): Likewise. + (ffi_closure_helper_LINUX64): Likewise. + +2013-11-16 Alan Modra + + * src/powerpc/linux64.S (ffi_call_LINUX64): Tweak restore of r28. + (.note.GNU-stack): Move inside outer #ifdef. + * src/powerpc/linux64_closure.S (STACKFRAME, PARMSAVE, + RETVAL): Define and use throughout. + (ffi_closure_LINUX64): Save fprs before buying stack. + (.note.GNU-stack): Move inside outer #ifdef. + +2013-11-16 Alan Modra + + * src/powerpc/ffitarget.h (FFI_TARGET_SPECIFIC_VARIADIC): Define. + (FFI_EXTRA_CIF_FIELDS): Define. + * src/powerpc/ffi.c (ffi_prep_args64): Save fprs as per the + ABI, not to both fpr and param save area. + (ffi_prep_cif_machdep_core): Renamed from ffi_prep_cif_machdep. + Keep initial flags. Formatting. Remove dead FFI_LINUX_SOFT_FLOAT + code. + (ffi_prep_cif_machdep, ffi_prep_cif_machdep_var): New functions. + (ffi_closure_helper_LINUX64): Pass floating point as per ABI, + not to both fpr and parameter save areas. + + * libffi/testsuite/libffi.call/cls_double_va.c (main): Correct + function cast and don't call ffi_prep_cif. + * libffi/testsuite/libffi.call/cls_longdouble_va.c (main): Likewise. + +2013-11-15 Andrew Haley + + * doc/libffi.texi (Closure Example): Fix the sample code. + * doc/libffi.info, doc/stamp-vti, doc/version.texi: Rebuilt. + +2013-11-15 Andrew Haley + + * testsuite/libffi.call/va_struct1.c (main): Fix broken test. + * testsuite/libffi.call/cls_uint_va.c (cls_ret_T_fn): Likewise + * testsuite/libffi.call/cls_struct_va1.c (test_fn): Likewise. + * testsuite/libffi.call/va_1.c (main): Likewise. + +2013-11-14 David Schneider + + * src/arm/ffi.c: Fix register allocation for mixed float and + doubles. + * testsuite/libffi.call/cls_many_mixed_float_double.c: Testcase + for many mixed float and double arguments. + +2013-11-13 Alan Modra + + * doc/libffi.texi (Simple Example): Correct example code. + * doc/libffi.info, doc/stamp-vti, doc/version.texi: Rebuilt. + +2013-11-13 Anthony Green + + * include/ffi_common.h: Respect HAVE_ALLOCA_H for GNU compiler + based build. (Thanks to tmr111116 on github) + +2013-11-09 Anthony Green + + * m4/libtool.m4: Refresh. + * configure, Makefile.in: Rebuilt. + * README: Add more notes about next release. + +2013-11-09 Shigeharu TAKENO + + * m4/ax_gcc_archflag.m4 (ax_gcc_arch): Don't recognize + UltraSPARC-IIi as ultrasparc3. + +2013-11-06 Mark Kettenis + + * src/x86/freebsd.S (ffi_call_SYSV): Align the stack pointer to + 16-bytes. + +2013-11-06 Konstantin Belousov + + * src/x86/freebsd.S (ffi_closure_raw_SYSV): Mark the assembler + source as not requiring executable stack. + +2013-11-02 Anthony Green + + * doc/libffi.texi (The Basics): Clarify return value buffer size + requirements. Also, NULL result buffer pointers are no longer + supported. + * doc/libffi.info: Rebuilt. + +2013-11-02 Mischa Jonker + + * Makefile.am (nodist_libffi_la_SOURCES): Fix build error. + * Makefile.in: Rebuilt. + +2013-11-02 David Schneider + + * src/arm/ffi.c: more robust argument handling for closures on arm hardfloat + * testsuite/libffi.call/many_mixed.c: New file. + * testsuite/libffi.call/cls_many_mixed_args.c: More tests. + +2013-11-02 Vitaly Budovski + + * src/x86/ffi.c (ffi_prep_cif_machdep): Don't align stack for win32. + +2013-10-23 Mark H Weaver + + * src/mips/ffi.c: Fix handling of uint32_t arguments on the + MIPS N32 ABI. + +2013-10-13 Sandra Loosemore + + * README: Add Nios II to table of supported platforms. + * Makefile.am (EXTRA_DIST): Add nios2 files. + (nodist_libffi_la_SOURCES): Likewise. + * Makefile.in: Regenerated. + * configure.ac (nios2*-linux*): New host. + (NIOS2): Add AM_CONDITIONAL. + * configure: Regenerated. + * src/nios2/ffi.c: New. + * src/nios2/ffitarget.h: New. + * src/nios2/sysv.S: New. + * src/prep_cif.c (initialize_aggregate): Handle extra structure + alignment via FFI_AGGREGATE_ALIGNMENT. + (ffi_prep_cif_core): Conditionalize structure return for NIOS2. + +2013-10-10 Sandra Loosemore + + * testsuite/libffi.call/cls_many_mixed_args.c (cls_ret_double_fn): + Fix uninitialized variable. + +2013-10-11 Marcus Shawcroft + + * testsuite/libffi.call/many.c (many): Replace * with +. + +2013-10-08 Ondřej Bílka + + * src/aarch64/ffi.c, src/aarch64/sysv.S, src/arm/ffi.c, + src/arm/gentramp.sh, src/bfin/sysv.S, src/closures.c, + src/dlmalloc.c, src/ia64/ffi.c, src/microblaze/ffi.c, + src/microblaze/sysv.S, src/powerpc/darwin_closure.S, + src/powerpc/ffi.c, src/powerpc/ffi_darwin.c, src/sh/ffi.c, + src/tile/tile.S, testsuite/libffi.call/nested_struct11.c: Fix + spelling errors. + +2013-10-08 Anthony Green + + * aclocal.m4, compile, config.guess, config.sub, depcomp, + install-sh, mdate-sh, missing, texinfo.tex: Update from upstream. + * configure.ac: Update version to 3.0.14-rc0. + * Makefile.in, configure, Makefile.in, include/Makefile.in, + man/Makefile.in, testsuite/Makefile.in: Rebuilt. + * README: Mention M88K and VAX. + +2013-07-15 Miod Vallat + + * Makefile.am, + configure.ac, + src/m88k/ffi.c, + src/m88k/ffitarget.h, + src/m88k/obsd.S, + src/vax/elfbsd.S, + src/vax/ffi.c, + src/vax/ffitarget.h: Add m88k and vax support. + +2013-06-24 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Move var declaration + before statements. + (ffi_prep_args64): Support little-endian. + (ffi_closure_helper_SYSV, ffi_closure_helper_LINUX64): Likewise. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Likewise. + * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Likewise. + +2013-06-12 Mischa Jonker + + * configure.ac: Add support for ARC. + * Makefile.am: Likewise. + * README: Add ARC details. + * src/arc/arcompact.S: New. + * src/arc/ffi.c: Likewise. + * src/arc/ffitarget.h: Likewise. + +2013-03-28 David Schneider + + * src/arm/ffi.c: Fix support for ARM hard-float calling convention. + * src/arm/sysv.S: call different methods for SYSV and VFP ABIs. + * testsuite/libffi.call/cls_many_mixed_args.c: testcase for a closure with + mixed arguments, many doubles. + * testsuite/libffi.call/many_double.c: testcase for calling a function using + more than 8 doubles. + * testcase/libffi.call/many.c: use absolute value to check result against an + epsilon + +2013-03-17 Anthony Green + + * README: Update for 3.0.13. + * configure.ac: Ditto. + * configure: Rebuilt. + * doc/*: Update version. + +2013-03-17 Dave Korn + + * src/closures.c (is_emutramp_enabled + [!FFI_MMAP_EXEC_EMUTRAMP_PAX]): Move default definition outside + enclosing #if scope. + +2013-03-17 Anthony Green + + * configure.ac: Only modify toolexecdir in certain cases. + * configure: Rebuilt. + +2013-03-16 Gilles Talis + + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Don't use + fparg_count,etc on __NO_FPRS__ targets. + +2013-03-16 Alan Hourihane + + * src/m68k/sysv.S (epilogue): Don't use extb instruction on + m680000 machines. + +2013-03-16 Alex Gaynor + + * src/x86/ffi.c (ffi_prep_cif_machdep): Always align stack. + +2013-03-13 Markos Chandras + + * configure.ac: Add support for Imagination Technologies Meta. + * Makefile.am: Likewise. + * README: Add Imagination Technologies Meta details. + * src/metag/ffi.c: New. + * src/metag/ffitarget.h: Likewise. + * src/metag/sysv.S: Likewise. + +2013-02-24 Andreas Schwab + + * doc/libffi.texi (Structures): Fix missing category argument of + @deftp. + +2013-02-11 Anthony Green + + * configure.ac: Update release number to 3.0.12. + * configure: Rebuilt. + * README: Update release info. + +2013-02-10 Anthony Green + + * README: Add Moxie. + * src/moxie/ffi.c: Created. + * src/moxie/eabi.S: Created. + * src/moxie/ffitarget.h: Created. + * Makefile.am (nodist_libffi_la_SOURCES): Add Moxie. + * Makefile.in: Rebuilt. + * configure.ac: Add Moxie. + * configure: Rebuilt. + * testsuite/libffi.call/huge_struct.c: Disable format string + warnings for moxie*-*-elf tests. + +2013-02-10 Anthony Green + + * Makefile.am (LTLDFLAGS): Fix reference. + * Makefile.in: Rebuilt. + +2013-02-10 Anthony Green + + * README: Update supported platforms. Update test results link. + +2013-02-09 Anthony Green + + * testsuite/libffi.call/negint.c: Remove forced -O2. + * testsuite/libffi.call/many2.c (foo): Remove GCCism. + * testsuite/libffi.call/ffitest.h: Add default PRIuPTR definition. + + * src/sparc/v8.S (ffi_closure_v8): Import ancient ulonglong + closure return type fix developed by Martin v. Löwis for cpython + fork. + +2013-02-08 Andreas Tobler + + * src/powerpc/ffi.c (ffi_prep_cif_machdep): Fix small struct + support. + * src/powerpc/sysv.S: Ditto. + +2013-02-08 Anthony Green + + * testsuite/libffi.call/cls_longdouble.c: Remove xfail for + arm*-*-*. + +2013-02-08 Anthony Green + + * src/sparc/ffi.c (ffi_prep_closure_loc): Fix cache flushing for GCC. + +2013-02-08 Matthias Klose + + * man/ffi_prep_cif.3: Clean up for debian linter. + +2013-02-08 Peter Bergner + + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Account for FP args pushed + on the stack. + +2013-02-08 Anthony Green + + * Makefile.am (EXTRA_DIST): Add missing files. + * testsuite/Makefile.am (EXTRA_DIST): Ditto. + * Makefile.in: Rebuilt. + +2013-02-08 Anthony Green + + * configure.ac: Move sparc asm config checks to within functions + for compatibility with sun tools. + * configure: Rebuilt. + * src/sparc/ffi.c (ffi_prep_closure_loc): Flush cache on v9 + systems. + * src/sparc/v8.S (ffi_flush_icache): Implement a sparc v9 cache + flusher. + +2013-02-08 Nathan Rossi + + * src/microblaze/ffi.c (ffi_closure_call_SYSV): Fix handling of + small big-endian structures. + (ffi_prep_args): Ditto. + +2013-02-07 Anthony Green + + * src/sparc/v8.S (ffi_call_v8): Fix typo from last patch + (effectively hiding ffi_call_v8). + +2013-02-07 Anthony Green + + * configure.ac: Update bug reporting address. + * configure.in: Rebuild. + + * src/sparc/v8.S (ffi_flush_icache): Out-of-line cache flusher for + Sun compiler. + * src/sparc/ffi.c (ffi_call): Remove warning. + Call ffi_flush_icache for non-GCC builds. + (ffi_prep_closure_loc): Use ffi_flush_icache. + + * Makefile.am (EXTRA_DIST): Add libtool-ldflags. + * Makefile.in: Rebuilt. + * libtool-ldflags: New file. + +2013-02-07 Daniel Schepler + + * configure.ac: Correctly identify x32 systems as 64-bit. + * m4/libtool.m4: Remove libtool expr error. + * aclocal.m4, configure: Rebuilt. + +2013-02-07 Anthony Green + + * configure.ac: Fix GCC usage test. + * configure: Rebuilt. + * README: Mention LLVM/GCC x86_64 issue. + * testsuite/Makefile.in: Rebuilt. + +2013-02-07 Anthony Green + + * testsuite/libffi.call/cls_double_va.c (main): Replace // style + comments with /* */ for xlc compiler. + * testsuite/libffi.call/stret_large.c (main): Ditto. + * testsuite/libffi.call/stret_large2.c (main): Ditto. + * testsuite/libffi.call/nested_struct1.c (main): Ditto. + * testsuite/libffi.call/huge_struct.c (main): Ditto. + * testsuite/libffi.call/float_va.c (main): Ditto. + * testsuite/libffi.call/cls_struct_va1.c (main): Ditto. + * testsuite/libffi.call/cls_pointer_stack.c (main): Ditto. + * testsuite/libffi.call/cls_pointer.c (main): Ditto. + * testsuite/libffi.call/cls_longdouble_va.c (main): Ditto. + +2013-02-06 Anthony Green + + * man/ffi_prep_cif.3: Clean up for debian lintian checker. + +2013-02-06 Anthony Green + + * Makefile.am (pkgconfigdir): Add missing pkgconfig install bits. + * Makefile.in: Rebuild. + +2013-02-02 Mark H Weaver + + * src/x86/ffi64.c (ffi_call): Sign-extend integer arguments passed + via general purpose registers. + +2013-01-21 Nathan Rossi + + * README: Add MicroBlaze details. + * Makefile.am: Add MicroBlaze support. + * configure.ac: Likewise. + * src/microblaze/ffi.c: New. + * src/microblaze/ffitarget.h: Likewise. + * src/microblaze/sysv.S: Likewise. + +2013-01-21 Nathan Rossi + * testsuite/libffi.call/return_uc.c: Fixed issue. + +2013-01-21 Chris Zankel + + * README: Add Xtensa support. + * Makefile.am: Likewise. + * configure.ac: Likewise. + * Makefile.in Regenerate. + * configure: Likewise. + * src/prep_cif.c: Handle Xtensa. + * src/xtensa: New directory. + * src/xtensa/ffi.c: New file. + * src/xtensa/ffitarget.h: Ditto. + * src/xtensa/sysv.S: Ditto. + +2013-01-11 Anthony Green + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Replace // style + comments with /* */ for xlc compiler. + * src/powerpc/aix.S (ffi_call_AIX): Ditto. + * testsuite/libffi.call/ffitest.h (allocate_mmap): Delete + deprecated inline function. + * testsuite/libffi.special/ffitestcxx.h: Ditto. + * README: Add update for AIX support. + +2013-01-11 Anthony Green + + * configure.ac: Robustify pc relative reloc check. + * m4/ax_cc_maxopt.m4: Don't -malign-double. This is an ABI + changing option for 32-bit x86. + * aclocal.m4, configure: Rebuilt. + * README: Update supported target list. + +2013-01-10 Anthony Green + + * README (tested): Add Compiler column to table. + +2013-01-10 Anthony Green + + * src/x86/ffi64.c (struct register_args): Make sse array and array + of unions for sunpro compiler compatibility. + +2013-01-10 Anthony Green + + * configure.ac: Test target platform size_t size. Handle both 32 + and 64-bit builds for x86_64-* and i?86-* targets (allowing for + CFLAG option to change default settings). + * configure, aclocal.m4: Rebuilt. + +2013-01-10 Anthony Green + + * testsuite/libffi.special/special.exp: Only run exception + handling tests when using GNU compiler. + + * m4/ax_compiler_vendor.m4: New file. + * configure.ac: Test for compiler vendor and don't use + AX_CFLAGS_WARN_ALL with the sun compiler. + * aclocal.m4, configure: Rebuilt. + +2013-01-10 Anthony Green + + * include/ffi_common.h: Don't use GCCisms to define types when + building with the SUNPRO compiler. + +2013-01-10 Anthony Green + + * configure.ac: Put local.exp in the right place. + * configure: Rebuilt. + + * src/x86/ffi.c: Update comment about regparm function attributes. + * src/x86/sysv.S (ffi_closure_SYSV): The SUNPRO compiler requires + that all function arguments be passed on the stack (no regparm + support). + +2013-01-08 Anthony Green + + * configure.ac: Generate local.exp. This sets CC_FOR_TARGET + when we are using the vendor compiler. + * testsuite/Makefile.am (EXTRA_DEJAGNU_SITE_CONFIG): Point to + ../local.exp. + * configure, testsuite/Makefile.in: Rebuilt. + + * testsuite/libffi.call/call.exp: Run tests with different + options, depending on whether or not we are using gcc or the + vendor compiler. + * testsuite/lib/libffi.exp (libffi-init): Set using_gcc based on + whether or not we are building/testing with gcc. + +2013-01-08 Anthony Green + + * configure.ac: Switch x86 solaris target to X86 by default. + * configure: Rebuilt. + +2013-01-08 Anthony Green + + * configure.ac: Fix test for read-only eh_frame. + * configure: Rebuilt. + +2013-01-08 Anthony Green + + * src/x86/sysv.S, src/x86/unix64.S: Only emit DWARF unwind info + when building with the GNU toolchain. + * testsuite/libffi.call/ffitest.h (CHECK): Fix for Solaris vendor + compiler. + +2013-01-07 Thorsten Glaser + + * testsuite/libffi.call/cls_uchar_va.c, + testsuite/libffi.call/cls_ushort_va.c, + testsuite/libffi.call/va_1.c: Testsuite fixes. + +2013-01-07 Thorsten Glaser + + * src/m68k/ffi.c (CIF_FLAGS_SINT8, CIF_FLAGS_SINT16): Define. + (ffi_prep_cif_machdep): Fix 8-bit and 16-bit signed calls. + * src/m68k/sysv.S (ffi_call_SYSV, ffi_closure_SYSV): Ditto. + +2013-01-04 Anthony Green + + * Makefile.am (AM_CFLAGS): Don't automatically add -fexceptions + and -Wall. This is set in the configure script after testing for + GCC. + * Makefile.in: Rebuilt. + +2013-01-02 rofl0r + + * src/powerpc/ffi.c (ffi_prep_cif_machdep): Fix build error on ppc + when long double == double. + +2013-01-02 Reini Urban + + * Makefile.am (libffi_la_LDFLAGS): Add -no-undefined to LDFLAGS + (required for shared libs on cygwin/mingw). + * Makefile.in: Rebuilt. + +2012-10-31 Alan Modra + + * src/powerpc/linux64_closure.S: Add new ABI support. + * src/powerpc/linux64.S: Likewise. + +2012-10-30 Magnus Granberg + Pavel Labushev + + * configure.ac: New options pax_emutramp + * configure, fficonfig.h.in: Regenerated + * src/closures.c: New function emutramp_enabled_check() and + checks. + +2012-10-30 Frederick Cheung + + * configure.ac: Enable FFI_MAP_EXEC_WRIT for Darwin 12 (mountain + lion) and future version. + * configure: Rebuild. + +2012-10-30 James Greenhalgh + Marcus Shawcroft + + * README: Add details of aarch64 port. + * src/aarch64/ffi.c: New. + * src/aarch64/ffitarget.h: Likewise. + * src/aarch64/sysv.S: Likewise. + * Makefile.am: Support aarch64. + * configure.ac: Support aarch64. + * Makefile.in, configure: Rebuilt. + +2012-10-30 James Greenhalgh + Marcus Shawcroft + + * testsuite/lib/libffi.exp: Add support for aarch64. + * testsuite/libffi.call/cls_struct_va1.c: New. + * testsuite/libffi.call/cls_uchar_va.c: Likewise. + * testsuite/libffi.call/cls_uint_va.c: Likewise. + * testsuite/libffi.call/cls_ulong_va.c: Likewise. + * testsuite/libffi.call/cls_ushort_va.c: Likewise. + * testsuite/libffi.call/nested_struct11.c: Likewise. + * testsuite/libffi.call/uninitialized.c: Likewise. + * testsuite/libffi.call/va_1.c: Likewise. + * testsuite/libffi.call/va_struct1.c: Likewise. + * testsuite/libffi.call/va_struct2.c: Likewise. + * testsuite/libffi.call/va_struct3.c: Likewise. + +2012-10-12 Walter Lee + + * Makefile.am: Add TILE-Gx/TILEPro support. + * configure.ac: Likewise. + * Makefile.in: Regenerate. + * configure: Likewise. + * src/prep_cif.c (ffi_prep_cif_core): Handle TILE-Gx/TILEPro. + * src/tile: New directory. + * src/tile/ffi.c: New file. + * src/tile/ffitarget.h: Ditto. + * src/tile/tile.S: Ditto. + +2012-10-12 Matthias Klose + + * generate-osx-source-and-headers.py: Normalize whitespace. + +2012-09-14 David Edelsohn + + * configure: Regenerated. + +2012-08-26 Andrew Pinski + + PR libffi/53014 + * src/mips/ffi.c (ffi_prep_closure_loc): Allow n32 with soft-float and n64 with + soft-float. + +2012-08-08 Uros Bizjak + + * src/s390/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, + just return FFI_BAD_ABI when things are wrong. + +2012-07-18 H.J. Lu + + PR libffi/53982 + PR libffi/53973 + * src/x86/ffitarget.h: Check __ILP32__ instead of __LP64__ for x32. + (FFI_SIZEOF_JAVA_RAW): Defined to 4 for x32. + +2012-05-16 H.J. Lu + + * configure: Regenerated. + +2012-05-05 Nicolas Lelong + + * libffi.xcodeproj/project.pbxproj: Fixes. + * README: Update for iOS builds. + +2012-04-23 Alexandre Keunecke I. de Mendonca + + * configure.ac: Add Blackfin/sysv support + * Makefile.am: Add Blackfin/sysv support + * src/bfin/ffi.c: Add Blackfin/sysv support + * src/bfin/ffitarget.h: Add Blackfin/sysv support + +2012-04-11 Anthony Green + + * Makefile.am (EXTRA_DIST): Add new script. + * Makefile.in: Rebuilt. + +2012-04-11 Zachary Waldowski + + * generate-ios-source-and-headers.py, + libffi.xcodeproj/project.pbxproj: Support a Mac static library via + Xcode. Set iOS compatibility to 4.0. Move iOS trampoline + generation into an Xcode "run script" phase. Include both as + Xcode build scripts. Don't always regenerate config files. + +2012-04-10 Anthony Green + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Add missing semicolon. + +2012-04-06 Anthony Green + + * Makefile.am (EXTRA_DIST): Add new iOS/xcode files. + * Makefile.in: Rebuilt. + +2012-04-06 Mike Lewis + + * generate-ios-source-and-headers.py: New file. + * libffi.xcodeproj/project.pbxproj: New file. + * README: Update instructions on building iOS binary. + * build-ios.sh: Delete. + +2012-04-06 Anthony Green + + * src/x86/ffi64.c (UINT128): Define differently for Intel and GNU + compilers, then use it. + +2012-04-06 H.J. Lu + + * m4/libtool.m4 (_LT_ENABLE_LOCK): Support x32. + +2012-04-06 Anthony Green + + * testsuite/Makefile.am (EXTRA_DIST): Add missing test cases. + * testsuite/Makefile.in: Rebuilt. + +2012-04-05 Zachary Waldowski + + * include/ffi.h.in: Add missing trampoline table fields. + * src/arm/sysv.S: Fix ENTRY definition, and wrap symbol references + in CNAME. + * src/x86/ffi.c: Wrap Windows specific code in ifdefs. + +2012-04-02 Peter Bergner + + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Declare double_tmp. + Silence casting pointer to integer of different size warning. + Delete goto to previously deleted label. + (ffi_call): Silence possibly undefined warning. + (ffi_closure_helper_SYSV): Declare variable type. + +2012-04-02 Peter Rosin + + * src/x86/win32.S (ffi_call_win32): Sign/zero extend the return + value in the Intel version as is already done for the AT&T version. + (ffi_closure_SYSV): Likewise. + (ffi_closure_raw_SYSV): Likewise. + (ffi_closure_STDCALL): Likewise. + +2012-03-29 Peter Rosin + + * src/x86/win32.S (ffi_closure_raw_THISCALL): Unify the frame + generation, fix the ENDP label and remove the surplus third arg + from the 'lea' insn. + +2012-03-29 Peter Rosin + + * src/x86/win32.S (ffi_closure_raw_SYSV): Make the 'stubraw' label + visible outside the PROC, so that ffi_closure_raw_THISCALL can see + it. Also instruct the assembler to add a frame to the function. + +2012-03-23 Peter Rosin + + * Makefile.am (AM_CPPFLAGS): Add -DFFI_BUILDING. + * Makefile.in: Rebuilt. + * include/ffi.h.in [MSVC]: Add __declspec(dllimport) decorations + to all data exports, when compiling libffi clients using MSVC. + +2012-03-29 Peter Rosin + + * src/x86/ffitarget.h (ffi_abi): Add new ABI FFI_MS_CDECL and + make it the default for MSVC. + (FFI_TYPE_MS_STRUCT): New structure return convention. + * src/x86/ffi.c (ffi_prep_cif_machdep): Tweak the structure + return convention for FFI_MS_CDECL to be FFI_TYPE_MS_STRUCT + instead of an ordinary FFI_TYPE_STRUCT. + (ffi_prep_args): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT. + (ffi_call): Likewise. + (ffi_prep_incoming_args_SYSV): Likewise. + (ffi_raw_call): Likewise. + (ffi_prep_closure_loc): Treat FFI_MS_CDECL as FFI_SYSV. + * src/x86/win32.S (ffi_closure_SYSV): For FFI_TYPE_MS_STRUCT, + return a pointer to the result structure in eax and don't pop + that pointer from the stack, the caller takes care of it. + (ffi_call_win32): Treat FFI_TYPE_MS_STRUCT as FFI_TYPE_STRUCT. + (ffi_closure_raw_SYSV): Likewise. + +2012-03-22 Peter Rosin + + * testsuite/libffi.call/closure_stdcall.c [MSVC]: Add inline + assembly version with Intel syntax. + * testsuite/libffi.call/closure_thiscall.c [MSVC]: Likewise. + +2012-03-23 Peter Rosin + + * testsuite/libffi.call/ffitest.h: Provide abstration of + __attribute__((fastcall)) in the form of a __FASTCALL__ + define. Define it to __fastcall for MSVC. + * testsuite/libffi.call/fastthis1_win32.c: Use the above. + * testsuite/libffi.call/fastthis2_win32.c: Likewise. + * testsuite/libffi.call/fastthis3_win32.c: Likewise. + * testsuite/libffi.call/strlen2_win32.c: Likewise. + * testsuite/libffi.call/struct1_win32.c: Likewise. + * testsuite/libffi.call/struct2_win32.c: Likewise. + +2012-03-22 Peter Rosin + + * src/x86/win32.S [MSVC] (ffi_closure_THISCALL): Remove the manual + frame on function entry, MASM adds one automatically. + +2012-03-22 Peter Rosin + + * testsuite/libffi.call/ffitest.h [MSVC]: Add kludge for missing + bits in the MSVC headers. + +2012-03-22 Peter Rosin + + * testsuite/libffi.call/cls_12byte.c: Adjust to the C89 style + with no declarations after statements. + * testsuite/libffi.call/cls_16byte.c: Likewise. + * testsuite/libffi.call/cls_18byte.c: Likewise. + * testsuite/libffi.call/cls_19byte.c: Likewise. + * testsuite/libffi.call/cls_1_1byte.c: Likewise. + * testsuite/libffi.call/cls_20byte.c: Likewise. + * testsuite/libffi.call/cls_20byte1.c: Likewise. + * testsuite/libffi.call/cls_24byte.c: Likewise. + * testsuite/libffi.call/cls_2byte.c: Likewise. + * testsuite/libffi.call/cls_3_1byte.c: Likewise. + * testsuite/libffi.call/cls_3byte1.c: Likewise. + * testsuite/libffi.call/cls_3byte2.c: Likewise. + * testsuite/libffi.call/cls_4_1byte.c: Likewise. + * testsuite/libffi.call/cls_4byte.c: Likewise. + * testsuite/libffi.call/cls_5_1_byte.c: Likewise. + * testsuite/libffi.call/cls_5byte.c: Likewise. + * testsuite/libffi.call/cls_64byte.c: Likewise. + * testsuite/libffi.call/cls_6_1_byte.c: Likewise. + * testsuite/libffi.call/cls_6byte.c: Likewise. + * testsuite/libffi.call/cls_7_1_byte.c: Likewise. + * testsuite/libffi.call/cls_7byte.c: Likewise. + * testsuite/libffi.call/cls_8byte.c: Likewise. + * testsuite/libffi.call/cls_9byte1.c: Likewise. + * testsuite/libffi.call/cls_9byte2.c: Likewise. + * testsuite/libffi.call/cls_align_double.c: Likewise. + * testsuite/libffi.call/cls_align_float.c: Likewise. + * testsuite/libffi.call/cls_align_longdouble.c: Likewise. + * testsuite/libffi.call/cls_align_longdouble_split.c: Likewise. + * testsuite/libffi.call/cls_align_longdouble_split2.c: Likewise. + * testsuite/libffi.call/cls_align_pointer.c: Likewise. + * testsuite/libffi.call/cls_align_sint16.c: Likewise. + * testsuite/libffi.call/cls_align_sint32.c: Likewise. + * testsuite/libffi.call/cls_align_sint64.c: Likewise. + * testsuite/libffi.call/cls_align_uint16.c: Likewise. + * testsuite/libffi.call/cls_align_uint32.c: Likewise. + * testsuite/libffi.call/cls_align_uint64.c: Likewise. + * testsuite/libffi.call/cls_dbls_struct.c: Likewise. + * testsuite/libffi.call/cls_pointer_stack.c: Likewise. + * testsuite/libffi.call/err_bad_typedef.c: Likewise. + * testsuite/libffi.call/huge_struct.c: Likewise. + * testsuite/libffi.call/nested_struct.c: Likewise. + * testsuite/libffi.call/nested_struct1.c: Likewise. + * testsuite/libffi.call/nested_struct10.c: Likewise. + * testsuite/libffi.call/nested_struct2.c: Likewise. + * testsuite/libffi.call/nested_struct3.c: Likewise. + * testsuite/libffi.call/nested_struct4.c: Likewise. + * testsuite/libffi.call/nested_struct5.c: Likewise. + * testsuite/libffi.call/nested_struct6.c: Likewise. + * testsuite/libffi.call/nested_struct7.c: Likewise. + * testsuite/libffi.call/nested_struct8.c: Likewise. + * testsuite/libffi.call/nested_struct9.c: Likewise. + * testsuite/libffi.call/stret_large.c: Likewise. + * testsuite/libffi.call/stret_large2.c: Likewise. + * testsuite/libffi.call/stret_medium.c: Likewise. + * testsuite/libffi.call/stret_medium2.c: Likewise. + * testsuite/libffi.call/struct1.c: Likewise. + * testsuite/libffi.call/struct1_win32.c: Likewise. + * testsuite/libffi.call/struct2.c: Likewise. + * testsuite/libffi.call/struct2_win32.c: Likewise. + * testsuite/libffi.call/struct3.c: Likewise. + * testsuite/libffi.call/struct4.c: Likewise. + * testsuite/libffi.call/struct5.c: Likewise. + * testsuite/libffi.call/struct6.c: Likewise. + * testsuite/libffi.call/struct7.c: Likewise. + * testsuite/libffi.call/struct8.c: Likewise. + * testsuite/libffi.call/struct9.c: Likewise. + * testsuite/libffi.call/testclosure.c: Likewise. + +2012-03-21 Peter Rosin + + * testsuite/libffi.call/float_va.c (float_va_fn): Use %f when + printing doubles (%lf is for long doubles). + (main): Likewise. + +2012-03-21 Peter Rosin + + * testsuite/lib/target-libpath.exp [*-*-cygwin*, *-*-mingw*] + (set_ld_library_path_env_vars): Add the library search dir to PATH + (and save PATH for later). + (restore_ld_library_path_env_vars): Restore PATH. + +2012-03-21 Peter Rosin + + * testsuite/lib/target-libpath.exp [*-*-cygwin*, *-*-mingw*] + (set_ld_library_path_env_vars): Add the library search dir to PATH + (and save PATH for later). + (restore_ld_library_path_env_vars): Restore PATH. + +2012-03-20 Peter Rosin + + * testsuite/libffi.call/strlen2_win32.c (main): Remove bug. + * src/x86/win32.S [MSVC] (ffi_closure_SYSV): Make the 'stub' label + visible outside the PROC, so that ffi_closure_THISCALL can see it. + +2012-03-20 Peter Rosin + + * testsuite/libffi.call/strlen2_win32.c (main): Remove bug. + * src/x86/win32.S [MSVC] (ffi_closure_SYSV): Make the 'stub' label + visible outside the PROC, so that ffi_closure_THISCALL can see it. + +2012-03-19 Alan Hourihane + + * src/m68k/ffi.c: Add MINT support. + * src/m68k/sysv.S: Ditto. + +2012-03-06 Chung-Lin Tang + + * src/arm/ffi.c (ffi_call): Add __ARM_EABI__ guard around call to + ffi_call_VFP(). + (ffi_prep_closure_loc): Add __ARM_EABI__ guard around use of + ffi_closure_VFP. + * src/arm/sysv.S: Add __ARM_EABI__ guard around VFP code. + +2012-03-19 chennam + + * src/powerpc/ffi_darwin.c (ffi_prep_closure_loc): Fix AIX closure + support. + +2012-03-13 Kaz Kojima + + * src/sh/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, + just return FFI_BAD_ABI when things are wrong. + * src/sh64/ffi.c (ffi_prep_closure_loc): Ditto. + +2012-03-09 David Edelsohn + + * src/powerpc/aix_closure.S (ffi_closure_ASM): Adjust for Darwin64 + change to return value of ffi_closure_helper_DARWIN and load type + from return type. + +2012-03-03 H.J. Lu + + * src/x86/ffi64.c (ffi_call): Cast the return value to unsigned + long. + (ffi_prep_closure_loc): Cast to 64bit address in trampoline. + (ffi_closure_unix64_inner): Cast return pointer to unsigned long + first. + + * src/x86/ffitarget.h (FFI_SIZEOF_ARG): Defined to 8 for x32. + (ffi_arg): Set to unsigned long long for x32. + (ffi_sarg): Set to long long for x32. + +2012-03-03 H.J. Lu + + * src/prep_cif.c (ffi_prep_cif_core): Properly check bad ABI. + +2012-03-03 Andoni Morales Alastruey + + * configure.ac: Add -no-undefined for both 32- and 64-bit x86 + windows-like hosts. + * configure: Rebuilt. + +2012-02-27 Mikael Pettersson + + PR libffi/52223 + * Makefile.am (FLAGS_TO_PASS): Define. + * Makefile.in: Regenerate. + +2012-02-23 Anthony Green + + * src/*/ffitarget.h: Ensure that users never include ffitarget.h + directly. + +2012-02-23 Kai Tietz + + PR libffi/52221 + * src/x86/ffi.c (ffi_closure_raw_THISCALL): New + prototype. + (ffi_prep_raw_closure_loc): Use ffi_closure_raw_THISCALL for + thiscall-convention. + (ffi_raw_call): Use ffi_prep_args_raw. + * src/x86/win32.S (ffi_closure_raw_THISCALL): Add + implementation for stub. + +2012-02-10 Kai Tietz + + * configure.ac (AM_LTLDFLAGS): Add -no-undefine for x64 + windows target. + * configure: Regenerated. + +2012-02-08 Kai Tietz + + * src/prep_cif.c (ffi_prep_cif): Allow for X86_WIN32 + also FFI_THISCALL. + * src/x86/ffi.c (ffi_closure_THISCALL): Add prototype. + (FFI_INIT_TRAMPOLINE_THISCALL): New trampoline code. + (ffi_prep_closure_loc): Add FFI_THISCALL support. + * src/x86/ffitarget.h (FFI_TRAMPOLINE_SIZE): Adjust size. + * src/x86/win32.S (ffi_closure_THISCALL): New closure code + for thiscall-calling convention. + * testsuite/libffi.call/closure_thiscall.c: New test. + +2012-01-28 Kai Tietz + + * src/libffi/src/x86/ffi.c (ffi_call_win32): Add new + argument to prototype for specify calling-convention. + (ffi_call): Add support for stdcall/thiscall convention. + (ffi_prep_args): Likewise. + (ffi_raw_call): Likewise. + * src/x86/ffitarget.h (ffi_abi): Add FFI_THISCALL and + FFI_FASTCALL. + * src/x86/win32.S (_ffi_call_win32): Add support for + fastcall/thiscall calling-convention calls. + * testsuite/libffi.call/fastthis1_win32.c: New test. + * testsuite/libffi.call/fastthis2_win32.c: New test. + * testsuite/libffi.call/fastthis3_win32.c: New test. + * testsuite/libffi.call/strlen2_win32.c: New test. + * testsuite/libffi.call/many2_win32.c: New test. + * testsuite/libffi.call/struct1_win32.c: New test. + * testsuite/libffi.call/struct2_win32.c: New test. + +2012-01-23 Uros Bizjak + + * src/alpha/ffi.c (ffi_prep_closure_loc): Check for bad ABI. + +2012-01-23 Anthony Green + Chris Young + + * configure.ac: Add Amiga support. + * configure: Rebuilt. + +2012-01-23 Dmitry Nadezhin + + * include/ffi_common.h (LIKELY, UNLIKELY): Fix definitions. + +2012-01-23 Andreas Schwab + + * src/m68k/sysv.S (ffi_call_SYSV): Properly test for plain + mc68000. Test for __HAVE_68881__ in addition to __MC68881__. + +2012-01-19 Jakub Jelinek + + PR rtl-optimization/48496 + * src/ia64/ffi.c (ffi_call): Fix up aliasing violations. + +2012-01-09 Rainer Orth + + * configure.ac (i?86-*-*): Set TARGET to X86_64. + * configure: Regenerate. + +2011-12-07 Andrew Pinski + + PR libffi/50051 + * src/mips/n32.S: Add ".set mips4". + +2011-11-21 Andreas Tobler + + * configure: Regenerate. + +2011-11-12 David Gilbert + + * doc/libffi.texi, include/ffi.h.in, include/ffi_common.h, + man/Makefile.am, man/ffi.3, man/ffi_prep_cif.3, + man/ffi_prep_cif_var.3, src/arm/ffi.c, src/arm/ffitarget.h, + src/cris/ffi.c, src/prep_cif.c, + testsuite/libffi.call/cls_double_va.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/float_va.c: Many changes to support variadic + function calls. + +2011-11-12 Kyle Moffett + + * src/powerpc/ffi.c, src/powerpc/ffitarget.h, + src/powerpc/ppc_closure.S, src/powerpc/sysv.S: Many changes for + softfloat powerpc variants. + +2011-11-12 Petr Salinger + + * configure.ac (FFI_EXEC_TRAMPOLINE_TABLE): Fix kfreebsd support. + * configure: Rebuilt. + +2011-11-12 Timothy Wall + + * src/arm/ffi.c (ffi_prep_args, ffi_prep_incoming_args_SYSV): Max + alignment of 4 for wince on ARM. + +2011-11-12 Kyle Moffett + Anthony Green + + * src/ppc/sysv.S, src/ppc/ffi.c: Remove use of ppc string + instructions (not available on some cores, like the PPC440). + +2011-11-12 Kimura Wataru + + * m4/ax_enable_builddir: Change from string comparison to numeric + comparison for wc output. + * configure.ac: Enable FFI_MMAP_EXEC_WRIT for darwin11 aka Mac OS + X 10.7. + * configure: Rebuilt. + +2011-11-12 Anthony Green + + * Makefile.am (AM_CCASFLAGS): Add -g option to build assembly + files with debug info. + * Makefile.in: Rebuilt. + +2011-11-12 Jasper Lievisse Adriaanse + + * README: Update list of supported OpenBSD systems. + +2011-11-12 Anthony Green + + * libtool-version: Update. + * Makefile.am (nodist_libffi_la_SOURCES): Add src/debug.c if + FFI_DEBUG. + (libffi_la_SOURCES): Remove src/debug.c + (EXTRA_DIST): Add src/debug.c + * Makefile.in: Rebuilt. + * README: Update for 3.0.11. + +2011-11-10 Richard Henderson + + * configure.ac (GCC_AS_CFI_PSEUDO_OP): Use it instead of inline check. + * configure, aclocal.m4: Rebuild. + +2011-09-04 Iain Sandoe + + PR libffi/49594 + * src/powerpc/darwin_closure.S (stubs): Make the stub binding + helper reference track the architecture pointer size. + +2011-08-25 Andrew Haley + + * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Remove hard-coded assembly + instructions. + * src/arm/sysv.S (ffi_arm_trampoline): Put them here instead. + +2011-07-11 Andrew Haley + + * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Clear icache. + +2011-06-29 Rainer Orth + + * testsuite/libffi.call/cls_double_va.c: Move PR number to comment. + * testsuite/libffi.call/cls_longdouble_va.c: Likewise. + +2011-06-29 Rainer Orth + + PR libffi/46660 + * testsuite/libffi.call/cls_double_va.c: xfail dg-output on + mips-sgi-irix6*. + * testsuite/libffi.call/cls_longdouble_va.c: Likewise. + +2011-06-14 Rainer Orth + + * testsuite/libffi.call/huge_struct.c (test_large_fn): Use PRIu8, + PRId8 instead of %hhu, %hhd. + * testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRId8, + PRIu8): Define. + [__sgi__] (PRId8, PRIu8): Define. + +2011-04-29 Rainer Orth + + * src/alpha/osf.S (UA_SI, FDE_ENCODING, FDE_ENCODE, FDE_ARANGE): + Define. + Use them to handle ELF vs. ECOFF differences. + [__osf__] (_GLOBAL__F_ffi_call_osf): Define. + +2011-03-30 Timothy Wall + + * src/powerpc/darwin.S: Fix unknown FDE encoding. + * src/powerpc/darwin_closure.S: ditto. + +2011-02-25 Anthony Green + + * src/powerpc/ffi.c (ffi_prep_closure_loc): Allow for more + 32-bit ABIs. + +2011-02-15 Anthony Green + + * m4/ax_cc_maxopt.m4: Don't -malign-double or use -ffast-math. + * configure: Rebuilt. + +2011-02-13 Ralf Wildenhues + + * configure: Regenerate. + +2011-02-13 Anthony Green + + * include/ffi_common.h (UNLIKELY, LIKELY): Define. + * src/x86/ffi64.c (UNLIKELY, LIKELY): Remove definition. + * src/prep_cif.c (UNLIKELY, LIKELY): Remove definition. + + * src/prep_cif.c (initialize_aggregate): Convert assertion into + FFI_BAD_TYPEDEF return. Initialize arg size and alignment to 0. + + * src/pa/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, + just return FFI_BAD_ABI when things are wrong. + * src/arm/ffi.c (ffi_prep_closure_loc): Ditto. + * src/powerpc/ffi.c (ffi_prep_closure_loc): Ditto. + * src/mips/ffi.c (ffi_prep_closure_loc): Ditto. + * src/ia64/ffi.c (ffi_prep_closure_loc): Ditto. + * src/avr32/ffi.c (ffi_prep_closure_loc): Ditto. + +2011-02-11 Anthony Green + + * src/sparc/ffi.c (ffi_prep_closure_loc): Don't ASSERT ABI test, + just return FFI_BAD_ABI when things are wrong. + +2012-02-11 Eric Botcazou + + * src/sparc/v9.S (STACKFRAME): Bump to 176. + +2011-02-09 Stuart Shelton + + http://bugs.gentoo.org/show_bug.cgi?id=286911 + * src/mips/ffitarget.h: Clean up error messages. + * src/java_raw_api.c (ffi_java_translate_args): Cast raw arg to + ffi_raw*. + * include/ffi.h.in: Add pragma for SGI compiler. + +2011-02-09 Anthony Green + + * configure.ac: Add powerpc64-*-darwin* support. + +2011-02-09 Anthony Green + + * README: Mention Interix. + +2011-02-09 Jonathan Callen + + * configure.ac: Add Interix to win32/cygwin/mingw case. + * configure: Ditto. + * src/closures.c: Treat Interix like Cygwin, instead of as a + generic win32. + +2011-02-09 Anthony Green + + * testsuite/libffi.call/err_bad_typedef.c: Remove xfail. + * testsuite/libffi.call/err_bad_abi.c: Remove xfail. + * src/x86/ffi64.c (UNLIKELY, LIKELY): Define. + (ffi_prep_closure_loc): Check for bad ABI. + * src/prep_cif.c (UNLIKELY, LIKELY): Define. + (initialize_aggregate): Check for bad types. + +2011-02-09 Landon Fuller + + * Makefile.am (EXTRA_DIST): Add build-ios.sh, src/arm/gentramp.sh, + src/arm/trampoline.S. + (nodist_libffi_la_SOURCES): Add src/arc/trampoline.S. + * configure.ac (FFI_EXEC_TRAMPOLINE_TABLE): Define. + * src/arm/ffi.c (ffi_trampoline_table) + (ffi_closure_trampoline_table_page, ffi_trampoline_table_entry) + (FFI_TRAMPOLINE_CODELOC_CONFIG, FFI_TRAMPOLINE_CONFIG_PAGE_OFFSET) + (FFI_TRAMPOLINE_COUNT, ffi_trampoline_lock, ffi_trampoline_tables) + (ffi_trampoline_table_alloc, ffi_closure_alloc, ffi_closure_free): + Define for FFI_EXEC_TRAMPOLINE_TABLE case (iOS). + (ffi_prep_closure_loc): Handl FFI_EXEC_TRAMPOLINE_TABLE case + separately. + * src/arm/sysv.S: Handle Apple iOS host. + * src/closures.c: Handle FFI_EXEC_TRAMPOLINE_TABLE case. + * build-ios.sh: New file. + * fficonfig.h.in, configure, Makefile.in: Rebuilt. + * README: Mention ARM iOS. + +2011-02-08 Oren Held + + * src/dlmalloc.c (_STRUCT_MALLINFO): Define in order to avoid + redefinition of mallinfo on HP-UX. + +2011-02-08 Ginn Chen + + * src/sparc/ffi.c (ffi_call): Make compatible with Solaris Studio + aggregate return ABI. Flush cache. + (ffi_prep_closure_loc): Flush cache. + +2011-02-11 Anthony Green + + From Tom Honermann : + * src/powerpc/aix.S (ffi_call_AIX): Support for xlc toolchain on + AIX. Declare .ffi_prep_args. Insert nops after branch + instructions so that the AIX linker can insert TOC reload + instructions. + * src/powerpc/aix_closure.S: Declare .ffi_closure_helper_DARWIN. + +2011-02-08 Ed + + * src/powerpc/asm.h: Fix grammar nit in comment. + +2011-02-08 Uli Link + + * include/ffi.h.in (FFI_64_BIT_MAX): Define and use. + +2011-02-09 Rainer Orth + + PR libffi/46661 + * testsuite/libffi.call/cls_pointer.c (main): Cast void * to + uintptr_t first. + * testsuite/libffi.call/cls_pointer_stack.c (main): Likewise. + +2011-02-08 Rafael Avila de Espindola + + * configure.ac: Fix x86 test for pc related relocs. + * configure: Rebuilt. + +2011-02-07 Joel Sherrill + + * libffi/src/m68k/ffi.c: Add RTEMS support for cache flushing. + Handle case when CPU variant does not have long double support. + * libffi/src/m68k/sysv.S: Add support for mc68000, Coldfire, + and cores with soft floating point. + +2011-02-07 Joel Sherrill + + * configure.ac: Add mips*-*-rtems* support. + * configure: Regenerate. + * src/mips/ffitarget.h: Ensure needed constants are available + for targets which do not have sgidefs.h. + +2011-01-26 Dave Korn + + PR target/40125 + * configure.ac (AM_LTLDFLAGS): Add -bindir option for windows DLLs. + * configure: Regenerate. + +2010-12-18 Iain Sandoe + + PR libffi/29152 + PR libffi/42378 + * src/powerpc/darwin_closure.S: Provide Darwin64 implementation, + update comments. + * src/powerpc/ffitarget.h (POWERPC_DARWIN64): New, + (FFI_TRAMPOLINE_SIZE): Update for Darwin64. + * src/powerpc/darwin.S: Provide Darwin64 implementation, + update comments. + * src/powerpc/ffi_darwin.c: Likewise. + +2010-12-06 Rainer Orth + + * configure.ac (libffi_cv_as_ascii_pseudo_op): Use double + backslashes. + (libffi_cv_as_string_pseudo_op): Likewise. + * configure: Regenerate. + +2010-12-03 Chung-Lin Tang + + * src/arm/sysv.S (ffi_closure_SYSV): Add UNWIND to .pad directive. + (ffi_closure_VFP): Same. + (ffi_call_VFP): Move down to before ffi_closure_VFP. Add '.fpu vfp' + directive. + +2010-12-01 Rainer Orth + + * testsuite/libffi.call/ffitest.h [__sgi] (PRId64, PRIu64): Define. + (PRIuPTR): Define. + +2010-11-29 Richard Henderson + Rainer Orth + + * src/x86/sysv.S (FDE_ENCODING, FDE_ENCODE): Define. + (.eh_frame): Use FDE_ENCODING. + (.LASFDE1, .LASFDE2, LASFDE3): Simplify with FDE_ENCODE. + +2010-11-22 Jacek Caban + + * configure.ac: Check for symbol underscores on mingw-w64. + * configure: Rebuilt. + * src/x86/win64.S: Correctly access extern symbols in respect to + underscores. + +2010-11-15 Rainer Orth + + * testsuite/lib/libffi-dg.exp: Rename ... + * testsuite/lib/libffi.exp: ... to this. + * libffi/testsuite/libffi.call/call.exp: Don't load libffi-dg.exp. + * libffi/testsuite/libffi.special/special.exp: Likewise. + +2010-10-28 Chung-Lin Tang + + * src/arm/ffi.c (ffi_prep_args): Add VFP register argument handling + code, new parameter, and return value. Update comments. + (ffi_prep_cif_machdep): Add case for VFP struct return values. Add + call to layout_vfp_args(). + (ffi_call_SYSV): Update declaration. + (ffi_call_VFP): New declaration. + (ffi_call): Add VFP struct return conditions. Call ffi_call_VFP() + when ABI is FFI_VFP. + (ffi_closure_VFP): New declaration. + (ffi_closure_SYSV_inner): Add new vfp_args parameter, update call to + ffi_prep_incoming_args_SYSV(). + (ffi_prep_incoming_args_SYSV): Update parameters. Add VFP argument + case handling. + (ffi_prep_closure_loc): Pass ffi_closure_VFP to trampoline + construction under VFP hard-float. + (rec_vfp_type_p): New function. + (vfp_type_p): Same. + (place_vfp_arg): Same. + (layout_vfp_args): Same. + * src/arm/ffitarget.h (ffi_abi): Add FFI_VFP. Define FFI_DEFAULT_ABI + based on __ARM_PCS_VFP. + (FFI_EXTRA_CIF_FIELDS): Define for adding VFP hard-float specific + fields. + (FFI_TYPE_STRUCT_VFP_FLOAT): Define internally used type code. + (FFI_TYPE_STRUCT_VFP_DOUBLE): Same. + * src/arm/sysv.S (ffi_call_SYSV): Change call of ffi_prep_args() to + direct call. Move function pointer load upwards. + (ffi_call_VFP): New function. + (ffi_closure_VFP): Same. + + * testsuite/lib/libffi-dg.exp (check-flags): New function. + (dg-skip-if): New function. + * testsuite/libffi.call/cls_double_va.c: Skip if target is arm*-*-* + and compiler options include -mfloat-abi=hard. + * testsuite/libffi.call/cls_longdouble_va.c: Same. + +2010-10-01 Jakub Jelinek + + PR libffi/45677 + * src/x86/ffi64.c (ffi_prep_cif_machdep): Ensure cif->bytes is + a multiple of 8. + * testsuite/libffi.call/many2.c: New test. + +2010-08-20 Mark Wielaard + + * src/closures.c (open_temp_exec_file_mnt): Check if getmntent_r + returns NULL. + +2010-08-09 Andreas Tobler + + * configure.ac: Add target powerpc64-*-freebsd*. + * configure: Regenerate. + * testsuite/libffi.call/cls_align_longdouble_split.c: Pass + -mlong-double-128 only to linux targets. + * testsuite/libffi.call/cls_align_longdouble_split2.c: Likewise. + * testsuite/libffi.call/cls_longdouble.c: Likewise. + * testsuite/libffi.call/huge_struct.c: Likewise. + +2010-08-05 Dan Witte + + * Makefile.am: Pass FFI_DEBUG define to msvcc.sh for linking to the + debug CRT when --enable-debug is given. + * configure.ac: Define it. + * msvcc.sh: Translate -g and -DFFI_DEBUG appropriately. + +2010-08-04 Dan Witte + + * src/x86/ffitarget.h: Add X86_ANY define for all x86/x86_64 + platforms. + * src/x86/ffi.c: Remove redundant ifdef checks. + * src/prep_cif.c: Push stack space computation into src/x86/ffi.c + for X86_ANY so return value space doesn't get added twice. + +2010-08-03 Neil Rashbrooke + + * msvcc.sh: Don't pass -safeseh to ml64 because behavior is buggy. + +2010-07-22 Dan Witte + + * src/*/ffitarget.h: Make FFI_LAST_ABI one past the last valid ABI. + * src/prep_cif.c: Fix ABI assertion. + * src/cris/ffi.c: Ditto. + +2010-07-10 Evan Phoenix + + * src/closures.c (selinux_enabled_check): Fix strncmp usage bug. + +2010-07-07 Dan Horák + + * include/ffi.h.in: Protect #define with #ifndef. + * src/powerpc/ffitarget.h: Ditto. + * src/s390/ffitarget.h: Ditto. + * src/sparc/ffitarget.h: Ditto. + +2010-07-07 Neil Roberts + + * src/x86/sysv.S (ffi_call_SYSV): Align the stack pointer to + 16-bytes. + +2010-07-02 Jakub Jelinek + + * Makefile.am (AM_MAKEFLAGS): Pass also mandir to submakes. + * Makefile.in: Regenerated. + +2010-05-19 Rainer Orth + + * configure.ac (libffi_cv_as_x86_pcrel): Check for illegal in as + output, too. + (libffi_cv_as_ascii_pseudo_op): Check for .ascii. + (libffi_cv_as_string_pseudo_op): Check for .string. + * configure: Regenerate. + * fficonfig.h.in: Regenerate. + * src/x86/sysv.S (.eh_frame): Use .ascii, .string or error. + +2010-05-11 Dan Witte + + * doc/libffi.tex: Document previous change. + +2010-05-11 Makoto Kato + + * src/x86/ffi.c (ffi_call): Don't copy structs passed by value. + +2010-05-05 Michael Kohler + + * src/dlmalloc.c (dlfree): Fix spelling. + * src/ia64/ffi.c (ffi_prep_cif_machdep): Ditto. + * configure.ac: Ditto. + * configure: Rebuilt. + +2010-04-13 Dan Witte + + * msvcc.sh: Build with -W3 instead of -Wall. + * src/powerpc/ffi_darwin.c: Remove build warnings. + * src/x86/ffi.c: Ditto. + * src/x86/ffitarget.h: Ditto. + +2010-04-12 Dan Witte + Walter Meinl + + * configure.ac: Add OS/2 support. + * configure: Rebuilt. + * src/closures.c: Ditto. + * src/dlmalloc.c: Ditto. + * src/x86/win32.S: Ditto. + +2010-04-07 Jakub Jelinek + + * testsuite/libffi.call/err_bad_abi.c: Remove unused args variable. + +2010-04-02 Ralf Wildenhues + + * Makefile.in: Regenerate. + * aclocal.m4: Regenerate. + * include/Makefile.in: Regenerate. + * man/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2010-03-30 Dan Witte + + * msvcc.sh: Disable build warnings. + * README (tested): Clarify windows build procedure. + +2010-03-15 Rainer Orth + + * configure.ac (libffi_cv_as_x86_64_unwind_section_type): New test. + * configure: Regenerate. + * fficonfig.h.in: Regenerate. + * libffi/src/x86/unix64.S (.eh_frame) + [HAVE_AS_X86_64_UNWIND_SECTION_TYPE]: Use @unwind section type. + +2010-03-14 Matthias Klose + + * src/x86/ffi64.c: Fix typo in comment. + * src/x86/ffi.c: Use /* ... */ comment style. + +2010-02-24 Rainer Orth + + * doc/libffi.texi (The Closure API): Fix typo. + * doc/libffi.info: Remove. + +2010-02-15 Matthias Klose + + * src/arm/sysv.S (__ARM_ARCH__): Define for processor + __ARM_ARCH_7EM__. + +2010-01-15 Anthony Green + + * README: Add notes on building with Microsoft Visual C++. + +2010-01-15 Daniel Witte + + * msvcc.sh: New file. + + * src/x86/win32.S: Port assembly routines to MSVC and #ifdef. + * src/x86/ffi.c: Tweak function declaration and remove excess + parens. + * include/ffi.h.in: Add __declspec(align(8)) to typedef struct + ffi_closure. + + * src/x86/ffi.c: Merge ffi_call_SYSV and ffi_call_STDCALL into new + function ffi_call_win32 on X86_WIN32. + * src/x86/win32.S (ffi_call_SYSV): Rename to ffi_call_win32. + (ffi_call_STDCALL): Remove. + + * src/prep_cif.c (ffi_prep_cif): Move stack space allocation code + to ffi_prep_cif_machdep for x86. + * src/x86/ffi.c (ffi_prep_cif_machdep): To here. + +2010-01-15 Oliver Kiddle + + * src/x86/ffitarget.h (ffi_abi): Check for __i386 and __amd64 for + Sun Studio compiler compatibility. + +2010-01-12 Conrad Irwin + + * doc/libffi.texi: Add closure example. + +2010-01-07 Rainer Orth + + PR libffi/40701 + * testsuite/libffi.call/ffitest.h [__alpha__ && __osf__] (PRIdLL, + PRIuLL, PRId64, PRIu64, PRIuPTR): Define. + * testsuite/libffi.call/cls_align_sint64.c: Add -Wno-format on + alpha*-dec-osf*. + * testsuite/libffi.call/cls_align_uint64.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/return_ll1.c: Likewise. + * testsuite/libffi.call/stret_medium2.c: Likewise. + * testsuite/libffi.special/ffitestcxx.h (allocate_mmap): Cast + MAP_FAILED to char *. + +2010-01-06 Rainer Orth + + * src/mips/n32.S: Use .abicalls and .eh_frame with __GNUC__. + +2009-12-31 Anthony Green + + * README: Update for libffi 3.0.9. + +2009-12-27 Matthias Klose + + * configure.ac (HAVE_LONG_DOUBLE): Define for mips when + appropriate. + * configure: Rebuilt. + +2009-12-26 Anthony Green + + * testsuite/libffi.call/cls_longdouble_va.c: Mark as xfail for + avr32*-*-*. + * testsuite/libffi.call/cls_double_va.c: Ditto. + +2009-12-26 Andreas Tobler + + * testsuite/libffi.call/ffitest.h: Conditionally include stdint.h + and inttypes.h. + * testsuite/libffi.special/unwindtest.cc: Ditto. + +2009-12-26 Andreas Tobler + + * configure.ac: Add amd64-*-openbsd*. + * configure: Rebuilt. + * testsuite/lib/libffi-dg.exp (libffi_target_compile): Link + openbsd programs with -lpthread. + +2009-12-26 Anthony Green + + * testsuite/libffi.call/cls_double_va.c, + testsuite/libffi.call/cls_longdouble.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_pointer.c, + testsuite/libffi.call/cls_pointer_stack.c: Remove xfail for + mips*-*-* and arm*-*-*. + * testsuite/libffi.call/cls_align_longdouble_split.c, + testsuite/libffi.call/cls_align_longdouble_split2.c, + testsuite/libffi.call/stret_medium2.c, + testsuite/libffi.call/stret_medium.c, + testsuite/libffi.call/stret_large.c, + testsuite/libffi.call/stret_large2.c: Remove xfail for arm*-*-*. + +2009-12-31 Kay Tietz + + * testsuite/libffi.call/ffitest.h, + testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRuLL): Fix + definitions. + +2009-12-31 Carlo Bramini + + * configure.ac (AM_LTLDFLAGS): Define for windows hosts. + * Makefile.am (libffi_la_LDFLAGS): Add AM_LTLDFLAGS. + * configure: Rebuilt. + * Makefile.in: Rebuilt. + +2009-12-31 Anthony Green + Blake Chaffin. + + * testsuite/libffi.call/huge_struct.c: New test case from Blake + Chaffin @ Apple. + +2009-12-28 David Edelsohn + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Copy abi and nargs to + local variables. + (aix_adjust_aggregate_sizes): New function. + (ffi_prep_cif_machdep): Call it. + +2009-12-26 Andreas Tobler + + * configure.ac: Define FFI_MMAP_EXEC_WRIT for the given targets. + * configure: Regenerate. + * fficonfig.h.in: Likewise. + * src/closures.c: Remove the FFI_MMAP_EXEC_WRIT definition for + Solaris/x86. + +2009-12-26 Andreas Schwab + + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Advance intarg_count + when a float arguments is passed in memory. + (ffi_closure_helper_SYSV): Mark general registers as used up when + a 64bit or soft-float long double argument is passed in memory. + +2009-12-25 Matthias Klose + + * man/ffi_call.3: Fix #include in examples. + * doc/libffi.texi: Add dircategory. + +2009-12-25 Frank Everdij + + * include/ffi.h.in: Placed '__GNUC__' ifdef around + '__attribute__((aligned(8)))' in ffi_closure, fixes compile for + IRIX MIPSPro c99. + * include/ffi_common.h: Added '__sgi' define to non + '__attribute__((__mode__()))' integer typedefs. + * src/mips/ffi.c (ffi_call, ffi_closure_mips_inner_O32, + ffi_closure_mips_inner_N32): Added 'defined(_MIPSEB)' to BE check. + (ffi_closure_mips_inner_O32, ffi_closure_mips_inner_N32): Added + FFI_LONGDOUBLE support and alignment(N32 only). + * src/mips/ffitarget.h: Corrected '#include ' for IRIX and + fixed non '__attribute__((__mode__()))' integer typedefs. + * src/mips/n32.S: Put '#ifdef linux' around '.abicalls' and '.eh_frame' + since they are Linux/GNU Assembler specific. + +2009-12-25 Bradley Smith + + * configure.ac, Makefile.am, src/avr32/ffi.c, + src/avr32/ffitarget.h, + src/avr32/sysv.S: Add AVR32 port. + * configure, Makefile.in: Rebuilt. + +2009-12-21 Andreas Tobler + + * configure.ac: Make i?86 build on FreeBSD and OpenBSD. + * configure: Regenerate. + +2009-12-15 John David Anglin + + * testsuite/libffi.call/ffitest.h: Define PRIuPTR on PA HP-UX. + +2009-12-13 John David Anglin + + * src/pa/ffi.c (ffi_closure_inner_pa32): Handle FFI_TYPE_LONGDOUBLE + type on HP-UX. + +2012-02-13 Kai Tietz + + PR libffi/52221 + * src/x86/ffi.c (ffi_prep_raw_closure_loc): Add thiscall + support for X86_WIN32. + (FFI_INIT_TRAMPOLINE_THISCALL): Fix displacement. + +2009-12-11 Eric Botcazou + + * src/sparc/ffi.c (ffi_closure_sparc_inner_v9): Properly align 'long + double' arguments. + +2009-12-11 Eric Botcazou + + * testsuite/libffi.call/ffitest.h: Define PRIuPTR on Solaris < 10. + +2009-12-10 Rainer Orth + + PR libffi/40700 + * src/closures.c [X86_64 && __sun__ && __svr4__] + (FFI_MMAP_EXEC_WRIT): Define. + +2009-12-08 David Daney + + * testsuite/libffi.call/stret_medium.c: Remove xfail for mips*-*-* + * testsuite/libffi.call/cls_align_longdouble_split2.c: Same. + * testsuite/libffi.call/stret_large.c: Same. + * testsuite/libffi.call/cls_align_longdouble_split.c: Same. + * testsuite/libffi.call/stret_large2.c: Same. + * testsuite/libffi.call/stret_medium2.c: Same. + +2009-12-07 David Edelsohn + + * src/powerpc/aix_closure.S (libffi_closure_ASM): Fix tablejump + typo. + +2009-12-05 David Edelsohn + + * src/powerpc/aix.S: Update AIX32 code to be consistent with AIX64 + code. + * src/powerpc/aix_closure.S: Same. + +2009-12-05 Ralf Wildenhues + + * Makefile.in: Regenerate. + * configure: Regenerate. + * include/Makefile.in: Regenerate. + * man/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2009-12-04 David Edelsohn + + * src/powerpc/aix_closure.S: Reorganize 64-bit code to match + linux64_closure.S. + +2009-12-04 Uros Bizjak + + PR libffi/41908 + * src/x86/ffi64.c (classify_argument): Update from + gcc/config/i386/i386.c. + (ffi_closure_unix64_inner): Do not use the address of two consecutive + SSE registers directly. + * testsuite/libffi.call/cls_dbls_struct.c (main): Remove xfail + for x86_64 linux targets. + +2009-12-04 David Edelsohn + + * src/powerpc/ffi_darwin.c (ffi_closure_helper_DARWIN): Increment + pfr for long double split between fpr13 and stack. + +2009-12-03 David Edelsohn + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Increment next_arg and + fparg_count twice for long double. + +2009-12-03 David Edelsohn + + PR libffi/42243 + * src/powerpc/ffi_darwin.c (ffi_prep_args): Remove extra parentheses. + +2009-12-03 Uros Bizjak + + * testsuite/libffi.call/cls_longdouble_va.c (main): Fix format string. + Remove xfails for x86 linux targets. + +2009-12-02 David Edelsohn + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Fix typo in INT64 + case. + +2009-12-01 David Edelsohn + + * src/powerpc/aix.S (ffi_call_AIX): Convert to more standard + register usage. Call ffi_prep_args directly. Add long double + return value support. + * src/powerpc/ffi_darwin.c (ffi_prep_args): Double arg increment + applies to FFI_TYPE_DOUBLE. Correct fpr_base increment typo. + Separate FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases. + (ffi_prep_cif_machdep): Only 16 byte stack alignment in 64 bit + mode. + (ffi_closure_helper_DARWIN): Remove nf and ng counters. Move temp + into case. + * src/powerpc/aix_closure.S: Maintain 16 byte stack alignment. + Allocate result area between params and FPRs. + +2009-11-30 David Edelsohn + + PR target/35484 + * src/powerpc/ffitarget.h (POWERPC64): Define for PPC64 Linux and + AIX64. + * src/powerpc/aix.S: Implement AIX64 version. + * src/powerpc/aix_closure.S: Implement AIX64 version. + (ffi_closure_ASM): Use extsb, lha and displament addresses. + * src/powerpc/ffi_darwin.c (ffi_prep_args): Implement AIX64 + support. + (ffi_prep_cif_machdep): Same. + (ffi_call): Same. + (ffi_closure_helper_DARWIN): Same. + +2009-11-02 Andreas Tobler + + PR libffi/41908 + * testsuite/libffi.call/testclosure.c: New test. + +2009-09-28 Kai Tietz + + * src/x86/win64.S (_ffi_call_win64 stack): Remove for gnu + assembly version use of ___chkstk. + +2009-09-23 Matthias Klose + + PR libffi/40242, PR libffi/41443 + * src/arm/sysv.S (__ARM_ARCH__): Define for processors + __ARM_ARCH_6T2__, __ARM_ARCH_6M__, __ARM_ARCH_7__, + __ARM_ARCH_7A__, __ARM_ARCH_7R__, __ARM_ARCH_7M__. + Change the conditionals to __SOFTFP__ || __ARM_EABI__ + for -mfloat-abi=softfp to work. + +2009-09-17 Loren J. Rittle + + PR testsuite/32843 (strikes again) + * src/x86/ffi.c (ffi_prep_cif_machdep): Add X86_FREEBSD to + enable proper extension on char and short. + +2009-09-15 David Daney + + * src/java_raw_api.c (ffi_java_raw_to_rvalue): Remove special + handling for FFI_TYPE_POINTER. + * src/mips/ffitarget.h (FFI_TYPE_STRUCT_D_SOFT, + FFI_TYPE_STRUCT_F_SOFT, FFI_TYPE_STRUCT_DD_SOFT, + FFI_TYPE_STRUCT_FF_SOFT, FFI_TYPE_STRUCT_FD_SOFT, + FFI_TYPE_STRUCT_DF_SOFT, FFI_TYPE_STRUCT_SOFT): New defines. + (FFI_N32_SOFT_FLOAT, FFI_N64_SOFT_FLOAT): New ffi_abi enumerations. + (enum ffi_abi): Set FFI_DEFAULT_ABI for soft-float. + * src/mips/n32.S (ffi_call_N32): Add handling for soft-float + structure and pointer returns. + (ffi_closure_N32): Add handling for pointer returns. + * src/mips/ffi.c (ffi_prep_args, calc_n32_struct_flags, + calc_n32_return_struct_flags): Handle soft-float. + (ffi_prep_cif_machdep): Handle soft-float, fix pointer handling. + (ffi_call_N32): Declare proper argument types. + (ffi_call, copy_struct_N32, ffi_closure_mips_inner_N32): Handle + soft-float. + +2009-08-24 Ralf Wildenhues + + * configure.ac (AC_PREREQ): Bump to 2.64. + +2009-08-22 Ralf Wildenhues + + * Makefile.am (install-html, install-pdf): Remove. + * Makefile.in: Regenerate. + + * Makefile.in: Regenerate. + * aclocal.m4: Regenerate. + * configure: Regenerate. + * fficonfig.h.in: Regenerate. + * include/Makefile.in: Regenerate. + * man/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2011-08-22 Jasper Lievisse Adriaanse + + * configure.ac: Add OpenBSD/hppa and OpenBSD/powerpc support. + * configure: Rebuilt. + +2009-07-30 Ralf Wildenhues + + * configure.ac (_AC_ARG_VAR_PRECIOUS): Use m4_rename_force. + +2009-07-24 Dave Korn + + PR libffi/40807 + * src/x86/ffi.c (ffi_prep_cif_machdep): Also use sign/zero-extending + return types for X86_WIN32. + * src/x86/win32.S (_ffi_call_SYSV): Handle omitted return types. + (_ffi_call_STDCALL, _ffi_closure_SYSV, _ffi_closure_raw_SYSV, + _ffi_closure_STDCALL): Likewise. + + * src/closures.c (is_selinux_enabled): Define to const 0 for Cygwin. + (dlmmap, dlmunmap): Also use these functions on Cygwin. + +2009-07-11 Richard Sandiford + + PR testsuite/40699 + PR testsuite/40707 + PR testsuite/40709 + * testsuite/lib/libffi-dg.exp: Revert 2009-07-02, 2009-07-01 and + 2009-06-30 commits. + +2009-07-01 Richard Sandiford + + * testsuite/lib/libffi-dg.exp (libffi-init): Set ld_library_path + to "" before adding paths. (This reinstates an assignment that + was removed by my 2009-06-30 commit, but changes the initial + value from "." to "".) + +2009-07-01 H.J. Lu + + PR testsuite/40601 + * testsuite/lib/libffi-dg.exp (libffi-init): Properly set + gccdir. Adjust ld_library_path for gcc only if gccdir isn't + empty. + +2009-06-30 Richard Sandiford + + * testsuite/lib/libffi-dg.exp (libffi-init): Don't add "." + to ld_library_path. Use add_path. Add just find_libgcc_s + to ld_library_path, not every libgcc multilib directory. + +2009-06-16 Wim Lewis + + * src/powerpc/ffi.c: Avoid clobbering cr3 and cr4, which are + supposed to be callee-saved. + * src/powerpc/sysv.S (small_struct_return_value): Fix overrun of + return buffer for odd-size structs. + +2009-06-16 Andreas Tobler + + PR libffi/40444 + * testsuite/lib/libffi-dg.exp (libffi_target_compile): Add + allow_stack_execute for Darwin. + +2009-06-16 Andrew Haley + + * configure.ac (TARGETDIR): Add missing blank lines. + * configure: Regenerate. + +2009-06-16 Andrew Haley + + * testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/return_ll1.c, + testsuite/libffi.call/stret_medium2.c: Fix printf format + specifiers. + * testsuite/libffi.call/ffitest.h, + testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRIuLL): Define. + +2009-06-15 Andrew Haley + + * testsuite/libffi.call/err_bad_typedef.c: xfail everywhere. + * testsuite/libffi.call/err_bad_abi.c: Likewise. + +2009-06-12 Andrew Haley + + * Makefile.am: Remove info_TEXINFOS. + +2009-06-12 Andrew Haley + + * ChangeLog.libffi: testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/return_ll1.c, + testsuite/libffi.call/stret_medium2.c: Fix printf format + specifiers. + testsuite/libffi.special/unwindtest.cc: include stdint.h. + +2009-06-11 Timothy Wall + + * Makefile.am, + configure.ac, + include/ffi.h.in, + include/ffi_common.h, + src/closures.c, + src/dlmalloc.c, + src/x86/ffi.c, + src/x86/ffitarget.h, + src/x86/win64.S (new), + README: Added win64 support (mingw or MSVC) + * Makefile.in, + include/Makefile.in, + man/Makefile.in, + testsuite/Makefile.in, + configure, + aclocal.m4: Regenerated + * ltcf-c.sh: properly escape cygwin/w32 path + * man/ffi_call.3: Clarify size requirements for return value. + * src/x86/ffi64.c: Fix filename in comment. + * src/x86/win32.S: Remove unused extern. + + * testsuite/libffi.call/closure_fn0.c, + testsuite/libffi.call/closure_fn1.c, + testsuite/libffi.call/closure_fn2.c, + testsuite/libffi.call/closure_fn3.c, + testsuite/libffi.call/closure_fn4.c, + testsuite/libffi.call/closure_fn5.c, + testsuite/libffi.call/closure_fn6.c, + testsuite/libffi.call/closure_stdcall.c, + testsuite/libffi.call/cls_12byte.c, + testsuite/libffi.call/cls_16byte.c, + testsuite/libffi.call/cls_18byte.c, + testsuite/libffi.call/cls_19byte.c, + testsuite/libffi.call/cls_1_1byte.c, + testsuite/libffi.call/cls_20byte.c, + testsuite/libffi.call/cls_20byte1.c, + testsuite/libffi.call/cls_24byte.c, + testsuite/libffi.call/cls_2byte.c, + testsuite/libffi.call/cls_3_1byte.c, + testsuite/libffi.call/cls_3byte1.c, + testsuite/libffi.call/cls_3byte2.c, + testsuite/libffi.call/cls_4_1byte.c, + testsuite/libffi.call/cls_4byte.c, + testsuite/libffi.call/cls_5_1_byte.c, + testsuite/libffi.call/cls_5byte.c, + testsuite/libffi.call/cls_64byte.c, + testsuite/libffi.call/cls_6_1_byte.c, + testsuite/libffi.call/cls_6byte.c, + testsuite/libffi.call/cls_7_1_byte.c, + testsuite/libffi.call/cls_7byte.c, + testsuite/libffi.call/cls_8byte.c, + testsuite/libffi.call/cls_9byte1.c, + testsuite/libffi.call/cls_9byte2.c, + testsuite/libffi.call/cls_align_double.c, + testsuite/libffi.call/cls_align_float.c, + testsuite/libffi.call/cls_align_longdouble.c, + testsuite/libffi.call/cls_align_longdouble_split.c, + testsuite/libffi.call/cls_align_longdouble_split2.c, + testsuite/libffi.call/cls_align_pointer.c, + testsuite/libffi.call/cls_align_sint16.c, + testsuite/libffi.call/cls_align_sint32.c, + testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_align_uint16.c, + testsuite/libffi.call/cls_align_uint32.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_dbls_struct.c, + testsuite/libffi.call/cls_double.c, + testsuite/libffi.call/cls_double_va.c, + testsuite/libffi.call/cls_float.c, + testsuite/libffi.call/cls_longdouble.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_multi_schar.c, + testsuite/libffi.call/cls_multi_sshort.c, + testsuite/libffi.call/cls_multi_sshortchar.c, + testsuite/libffi.call/cls_multi_uchar.c, + testsuite/libffi.call/cls_multi_ushort.c, + testsuite/libffi.call/cls_multi_ushortchar.c, + testsuite/libffi.call/cls_pointer.c, + testsuite/libffi.call/cls_pointer_stack.c, + testsuite/libffi.call/cls_schar.c, + testsuite/libffi.call/cls_sint.c, + testsuite/libffi.call/cls_sshort.c, + testsuite/libffi.call/cls_uchar.c, + testsuite/libffi.call/cls_uint.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/cls_ushort.c, + testsuite/libffi.call/err_bad_abi.c, + testsuite/libffi.call/err_bad_typedef.c, + testsuite/libffi.call/float2.c, + testsuite/libffi.call/huge_struct.c, + testsuite/libffi.call/nested_struct.c, + testsuite/libffi.call/nested_struct1.c, + testsuite/libffi.call/nested_struct10.c, + testsuite/libffi.call/nested_struct2.c, + testsuite/libffi.call/nested_struct3.c, + testsuite/libffi.call/nested_struct4.c, + testsuite/libffi.call/nested_struct5.c, + testsuite/libffi.call/nested_struct6.c, + testsuite/libffi.call/nested_struct7.c, + testsuite/libffi.call/nested_struct8.c, + testsuite/libffi.call/nested_struct9.c, + testsuite/libffi.call/problem1.c, + testsuite/libffi.call/return_ldl.c, + testsuite/libffi.call/return_ll1.c, + testsuite/libffi.call/stret_large.c, + testsuite/libffi.call/stret_large2.c, + testsuite/libffi.call/stret_medium.c, + testsuite/libffi.call/stret_medium2.c, + testsuite/libffi.special/unwindtest.cc: use ffi_closure_alloc instead + of checking for MMAP. Use intptr_t instead of long casts. + +2009-06-11 Kaz Kojima + + * testsuite/libffi.call/cls_longdouble_va.c: Add xfail sh*-*-linux-*. + * testsuite/libffi.call/err_bad_abi.c: Add xfail sh*-*-*. + * testsuite/libffi.call/err_bad_typedef.c: Likewise. + +2009-06-09 Andrew Haley + + * src/x86/freebsd.S: Add missing file. + +2009-06-08 Andrew Haley + + Import from libffi 3.0.8: + + * doc/libffi.texi: New file. + * doc/libffi.info: Likewise. + * doc/stamp-vti: Likewise. + * man/Makefile.am: New file. + * man/ffi_call.3: New file. + + * Makefile.am (EXTRA_DIST): Add src/x86/darwin64.S, + src/dlmalloc.c. + (nodist_libffi_la_SOURCES): Add X86_FREEBSD. + + * configure.ac: Bump version to 3.0.8. + parisc*-*-linux*: Add. + i386-*-freebsd* | i386-*-openbsd*: Add. + powerpc-*-beos*: Add. + AM_CONDITIONAL X86_FREEBSD: Add. + AC_CONFIG_FILES: Add man/Makefile. + + * include/ffi.h.in (FFI_FN): Change void (*)() to void (*)(void). + +2009-06-08 Andrew Haley + + * README: Import from libffi 3.0.8. + +2009-06-08 Andrew Haley + + * testsuite/libffi.call/err_bad_abi.c: Add xfails. + * testsuite/libffi.call/cls_longdouble_va.c: Add xfails. + * testsuite/libffi.call/cls_dbls_struct.c: Add xfail x86_64-*-linux-*. + * testsuite/libffi.call/err_bad_typedef.c: Add xfails. + + * testsuite/libffi.call/stret_medium2.c: Add __UNUSED__ to args. + * testsuite/libffi.call/stret_medium.c: Likewise. + * testsuite/libffi.call/stret_large2.c: Likewise. + * testsuite/libffi.call/stret_large.c: Likewise. + +2008-12-26 Timothy Wall + + * testsuite/libffi.call/cls_longdouble.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_align_longdouble.c, + testsuite/libffi.call/cls_align_longdouble_split.c, + testsuite/libffi.call/cls_align_longdouble_split2.c: mark expected + failures on x86_64 cygwin/mingw. + +2008-12-22 Timothy Wall + + * testsuite/libffi.call/closure_fn0.c, + testsuite/libffi.call/closure_fn1.c, + testsuite/libffi.call/closure_fn2.c, + testsuite/libffi.call/closure_fn3.c, + testsuite/libffi.call/closure_fn4.c, + testsuite/libffi.call/closure_fn5.c, + testsuite/libffi.call/closure_fn6.c, + testsuite/libffi.call/closure_loc_fn0.c, + testsuite/libffi.call/closure_stdcall.c, + testsuite/libffi.call/cls_align_pointer.c, + testsuite/libffi.call/cls_pointer.c, + testsuite/libffi.call/cls_pointer_stack.c: use portable cast from + pointer to integer (intptr_t). + * testsuite/libffi.call/cls_longdouble.c: disable for win64. + +2008-07-24 Anthony Green + + * testsuite/libffi.call/cls_dbls_struct.c, + testsuite/libffi.call/cls_double_va.c, + testsuite/libffi.call/cls_longdouble.c, + testsuite/libffi.call/cls_longdouble_va.c, + testsuite/libffi.call/cls_pointer.c, + testsuite/libffi.call/cls_pointer_stack.c, + testsuite/libffi.call/err_bad_abi.c: Clean up failures from + compiler warnings. + +2008-03-04 Anthony Green + Blake Chaffin + hos@tamanegi.org + + * testsuite/libffi.call/cls_align_longdouble_split2.c + testsuite/libffi.call/cls_align_longdouble_split.c + testsuite/libffi.call/cls_dbls_struct.c + testsuite/libffi.call/cls_double_va.c + testsuite/libffi.call/cls_longdouble.c + testsuite/libffi.call/cls_longdouble_va.c + testsuite/libffi.call/cls_pointer.c + testsuite/libffi.call/cls_pointer_stack.c + testsuite/libffi.call/err_bad_abi.c + testsuite/libffi.call/err_bad_typedef.c + testsuite/libffi.call/stret_large2.c + testsuite/libffi.call/stret_large.c + testsuite/libffi.call/stret_medium2.c + testsuite/libffi.call/stret_medium.c: New tests from Apple. + +2009-06-05 Andrew Haley + + * src/x86/ffitarget.h, src/x86/ffi.c: Merge stdcall changes from + libffi. + +2009-06-04 Andrew Haley + + * src/x86/ffitarget.h, src/x86/win32.S, src/x86/ffi.c: Back out + stdcall changes. + +2008-02-26 Anthony Green + Thomas Heller + + * src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C + comment. + +2008-02-03 Timothy Wall + + * src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL): Calculate jump return + offset based on code pointer, not data pointer. + +2008-01-31 Timothy Wall + + * testsuite/libffi.call/closure_stdcall.c: Add test for stdcall + closures. + * src/x86/ffitarget.h: Increase size of trampoline for stdcall + closures. + * src/x86/win32.S: Add assembly for stdcall closure. + * src/x86/ffi.c: Initialize stdcall closure trampoline. + +2009-06-04 Andrew Haley + + * include/ffi.h.in: Change void (*)() to void (*)(void). + * src/x86/ffi.c: Likewise. + +2009-06-04 Andrew Haley + + * src/powerpc/ppc_closure.S: Insert licence header. + * src/powerpc/linux64_closure.S: Likewise. + * src/m68k/sysv.S: Likewise. + + * src/sh64/ffi.c: Change void (*)() to void (*)(void). + * src/powerpc/ffi.c: Likewise. + * src/powerpc/ffi_darwin.c: Likewise. + * src/m32r/ffi.c: Likewise. + * src/sh64/ffi.c: Likewise. + * src/x86/ffi64.c: Likewise. + * src/alpha/ffi.c: Likewise. + * src/alpha/osf.S: Likewise. + * src/frv/ffi.c: Likewise. + * src/s390/ffi.c: Likewise. + * src/pa/ffi.c: Likewise. + * src/pa/hpux32.S: Likewise. + * src/ia64/unix.S: Likewise. + * src/ia64/ffi.c: Likewise. + * src/sparc/ffi.c: Likewise. + * src/mips/ffi.c: Likewise. + * src/sh/ffi.c: Likewise. + +2008-02-15 David Daney + + * src/mips/ffi.c (USE__BUILTIN___CLEAR_CACHE): + Define (conditionally), and use it to include cachectl.h. + (ffi_prep_closure_loc): Fix cache flushing. + * src/mips/ffitarget.h (_ABIN32, _ABI64, _ABIO32): Define. + +2009-06-04 Andrew Haley + + include/ffi.h.in, + src/arm/ffitarget.h, + src/arm/ffi.c, + src/arm/sysv.S, + src/powerpc/ffitarget.h, + src/closures.c, + src/sh64/ffitarget.h, + src/sh64/ffi.c, + src/sh64/sysv.S, + src/types.c, + src/x86/ffi64.c, + src/x86/ffitarget.h, + src/x86/win32.S, + src/x86/darwin.S, + src/x86/ffi.c, + src/x86/sysv.S, + src/x86/unix64.S, + src/alpha/ffitarget.h, + src/alpha/ffi.c, + src/alpha/osf.S, + src/m68k/ffitarget.h, + src/frv/ffitarget.h, + src/frv/ffi.c, + src/s390/ffitarget.h, + src/s390/sysv.S, + src/cris/ffitarget.h, + src/pa/linux.S, + src/pa/ffitarget.h, + src/pa/ffi.c, + src/raw_api.c, + src/ia64/ffitarget.h, + src/ia64/unix.S, + src/ia64/ffi.c, + src/ia64/ia64_flags.h, + src/java_raw_api.c, + src/debug.c, + src/sparc/v9.S, + src/sparc/ffitarget.h, + src/sparc/ffi.c, + src/sparc/v8.S, + src/mips/ffitarget.h, + src/mips/n32.S, + src/mips/o32.S, + src/mips/ffi.c, + src/prep_cif.c, + src/sh/ffitarget.h, + src/sh/ffi.c, + src/sh/sysv.S: Update license text. + +2009-05-22 Dave Korn + + * src/x86/win32.S (_ffi_closure_STDCALL): New function. + (.eh_frame): Add FDE for it. + +2009-05-22 Dave Korn + + * configure.ac: Also check if assembler supports pc-relative + relocs on X86_WIN32 targets. + * configure: Regenerate. + * src/x86/win32.S (ffi_prep_args): Declare extern, not global. + (_ffi_call_SYSV): Add missing function type symbol .def and + add EH markup labels. + (_ffi_call_STDCALL): Likewise. + (_ffi_closure_SYSV): Likewise. + (_ffi_closure_raw_SYSV): Likewise. + (.eh_frame): Add hand-crafted EH data. + +2009-04-09 Jakub Jelinek + + * testsuite/lib/libffi-dg.exp: Change copyright header to refer to + version 3 of the GNU General Public License and to point readers + at the COPYING3 file and the FSF's license web page. + * testsuite/libffi.call/call.exp: Likewise. + * testsuite/libffi.special/special.exp: Likewise. + +2009-03-01 Ralf Wildenhues + + * configure: Regenerate. + +2008-12-18 Rainer Orth + + PR libffi/26048 + * configure.ac (HAVE_AS_X86_PCREL): New test. + * configure: Regenerate. + * fficonfig.h.in: Regenerate. + * src/x86/sysv.S [!FFI_NO_RAW_API]: Precalculate + RAW_CLOSURE_CIF_OFFSET, RAW_CLOSURE_FUN_OFFSET, + RAW_CLOSURE_USER_DATA_OFFSET for the Solaris 10/x86 assembler. + (.eh_frame): Only use SYMBOL-. iff HAVE_AS_X86_PCREL. + * src/x86/unix64.S (.Lstore_table): Move to .text section. + (.Lload_table): Likewise. + (.eh_frame): Only use SYMBOL-. iff HAVE_AS_X86_PCREL. + +2008-12-18 Ralf Wildenhues + + * configure: Regenerate. + +2008-11-21 Eric Botcazou + + * src/sparc/ffi.c (ffi_prep_cif_machdep): Add support for + signed/unsigned int8/16 return values. + * src/sparc/v8.S (ffi_call_v8): Likewise. + (ffi_closure_v8): Likewise. + +2008-09-26 Peter O'Gorman + Steve Ellcey + + * configure: Regenerate for new libtool. + * Makefile.in: Ditto. + * include/Makefile.in: Ditto. + * aclocal.m4: Ditto. + +2008-08-25 Andreas Tobler + + * src/powerpc/ffitarget.h (ffi_abi): Add FFI_LINUX and + FFI_LINUX_SOFT_FLOAT to the POWERPC_FREEBSD enum. + Add note about flag bits used for FFI_SYSV_TYPE_SMALL_STRUCT. + Adjust copyright notice. + * src/powerpc/ffi.c: Add two new flags to indicate if we have one + register or two register to use for FFI_SYSV structs. + (ffi_prep_cif_machdep): Pass the right register flag introduced above. + (ffi_closure_helper_SYSV): Fix the return type for + FFI_SYSV_TYPE_SMALL_STRUCT. Comment. + Adjust copyright notice. + +2008-07-16 Kaz Kojima + + * src/sh/ffi.c (ffi_prep_closure_loc): Turn INSN into an unsigned + int. + +2008-06-17 Ralf Wildenhues + + * configure: Regenerate. + * include/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2008-06-07 Joseph Myers + + * configure.ac (parisc*-*-linux*, powerpc-*-sysv*, + powerpc-*-beos*): Remove. + * configure: Regenerate. + +2008-05-09 Julian Brown + + * Makefile.am (LTLDFLAGS): New. + (libffi_la_LDFLAGS): Use above. + * Makefile.in: Regenerate. + +2008-04-18 Paolo Bonzini + + PR bootstrap/35457 + * aclocal.m4: Regenerate. + * configure: Regenerate. + +2008-03-26 Kaz Kojima + + * src/sh/sysv.S: Add .note.GNU-stack on Linux. + * src/sh64/sysv.S: Likewise. + +2008-03-26 Daniel Jacobowitz + + * src/arm/sysv.S: Fix ARM comment marker. + +2008-03-26 Jakub Jelinek + + * src/alpha/osf.S: Add .note.GNU-stack on Linux. + * src/s390/sysv.S: Likewise. + * src/powerpc/ppc_closure.S: Likewise. + * src/powerpc/sysv.S: Likewise. + * src/x86/unix64.S: Likewise. + * src/x86/sysv.S: Likewise. + * src/sparc/v8.S: Likewise. + * src/sparc/v9.S: Likewise. + * src/m68k/sysv.S: Likewise. + * src/arm/sysv.S: Likewise. + +2008-03-16 Ralf Wildenhues + + * aclocal.m4: Regenerate. + * configure: Likewise. + * Makefile.in: Likewise. + * include/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + +2008-02-12 Bjoern Koenig + Andreas Tobler + + * configure.ac: Add amd64-*-freebsd* target. + * configure: Regenerate. + +2008-01-30 H.J. Lu + + PR libffi/34612 + * src/x86/sysv.S (ffi_closure_SYSV): Pop 4 byte from stack when + returning struct. + + * testsuite/libffi.call/call.exp: Add "-O2 -fomit-frame-pointer" + tests. + +2008-01-24 David Edelsohn + + * configure: Regenerate. + +2008-01-06 Andreas Tobler + + * src/x86/ffi.c (ffi_prep_cif_machdep): Fix thinko. + +2008-01-05 Andreas Tobler + + PR testsuite/32843 + * src/x86/ffi.c (ffi_prep_cif_machdep): Add code for + signed/unsigned int8/16 for X86_DARWIN. + Updated copyright info. + Handle one and two byte structs with special cif->flags. + * src/x86/ffitarget.h: Add special types for one and two byte structs. + Updated copyright info. + * src/x86/darwin.S (ffi_call_SYSV): Rewrite to use a jump table like + sysv.S + Remove code to pop args from the stack after call. + Special-case signed/unsigned for int8/16, one and two byte structs. + (ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8, + FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32, + FFI_TYPE_SINT32. + Updated copyright info. + +2007-12-08 David Daney + + * src/mips/n32.S (ffi_call_N32): Replace dadd with ADDU, dsub with + SUBU, add with ADDU and use smaller code sequences. + +2007-12-07 David Daney + + * src/mips/ffi.c (ffi_prep_cif_machdep): Handle long double return + type. + +2007-12-06 David Daney + + * include/ffi.h.in (FFI_SIZEOF_JAVA_RAW): Define if not already + defined. + (ffi_java_raw): New typedef. + (ffi_java_raw_call, ffi_java_ptrarray_to_raw, + ffi_java_raw_to_ptrarray): Change parameter types from ffi_raw to + ffi_java_raw. + (ffi_java_raw_closure) : Same. + (ffi_prep_java_raw_closure, ffi_prep_java_raw_closure_loc): Change + parameter types. + * src/java_raw_api.c (ffi_java_raw_size): Replace FFI_SIZEOF_ARG with + FFI_SIZEOF_JAVA_RAW. + (ffi_java_raw_to_ptrarray): Change type of raw to ffi_java_raw. + Replace FFI_SIZEOF_ARG with FFI_SIZEOF_JAVA_RAW. Use + sizeof(ffi_java_raw) for alignment calculations. + (ffi_java_ptrarray_to_raw): Same. + (ffi_java_rvalue_to_raw): Add special handling for FFI_TYPE_POINTER + if FFI_SIZEOF_JAVA_RAW == 4. + (ffi_java_raw_to_rvalue): Same. + (ffi_java_raw_call): Change type of raw to ffi_java_raw. + (ffi_java_translate_args): Same. + (ffi_prep_java_raw_closure_loc, ffi_prep_java_raw_closure): Change + parameter types. + * src/mips/ffitarget.h (FFI_SIZEOF_JAVA_RAW): Define for N32 ABI. + +2007-12-06 David Daney + + * src/mips/n32.S (ffi_closure_N32): Use 64-bit add instruction on + pointer values. + +2007-12-01 Andreas Tobler + + PR libffi/31937 + * src/powerpc/ffitarget.h: Introduce new ABI FFI_LINUX_SOFT_FLOAT. + Add local FFI_TYPE_UINT128 to handle soft-float long-double-128. + * src/powerpc/ffi.c: Distinguish between __NO_FPRS__ and not and + set the NUM_FPR_ARG_REGISTERS according to. + Add support for potential soft-float support under hard-float + architecture. + (ffi_prep_args_SYSV): Set NUM_FPR_ARG_REGISTERS to 0 in case of + FFI_LINUX_SOFT_FLOAT, handle float, doubles and long-doubles according + to the FFI_LINUX_SOFT_FLOAT ABI. + (ffi_prep_cif_machdep): Likewise. + (ffi_closure_helper_SYSV): Likewise. + * src/powerpc/ppc_closure.S: Make sure not to store float/double + on archs where __NO_FPRS__ is true. + Add FFI_TYPE_UINT128 support. + * src/powerpc/sysv.S: Add support for soft-float long-double-128. + Adjust copyright notice. + +2007-11-25 Andreas Tobler + + * src/closures.c: Move defintion of MAYBE_UNUSED from here to ... + * include/ffi_common.h: ... here. + Update copyright. + +2007-11-17 Andreas Tobler + + * src/powerpc/sysv.S: Load correct cr to compare if we have long double. + * src/powerpc/linux64.S: Likewise. + * src/powerpc/ffi.c: Add a comment to show which part goes into cr6. + * testsuite/libffi.call/return_ldl.c: New test. + +2007-09-04 + + * src/arm/sysv.S (UNWIND): New. + (Whole file): Conditionally compile unwinder directives. + * src/arm/sysv.S: Add unwinder directives. + + * src/arm/ffi.c (ffi_prep_args): Align structs by at least 4 bytes. + Only treat r0 as a struct address if we're actually returning a + struct by address. + Only copy the bytes that are actually within a struct. + (ffi_prep_cif_machdep): A Composite Type not larger than 4 bytes + is returned in r0, not passed by address. + (ffi_call): Allocate a word-sized temporary for the case where + a composite is returned in r0. + (ffi_prep_incoming_args_SYSV): Align as necessary. + +2007-08-05 Steven Newbury + + * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Use __clear_cache instead of + directly using the sys_cacheflush syscall. + +2007-07-27 Andrew Haley + + * src/arm/sysv.S (ffi_closure_SYSV): Add soft-float. + +2007-09-03 Maciej W. Rozycki + + * Makefile.am: Unify MIPS_IRIX and MIPS_LINUX into MIPS. + * configure.ac: Likewise. + * Makefile.in: Regenerate. + * include/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + * configure: Likewise. + +2007-08-24 David Daney + + * testsuite/libffi.call/return_sl.c: New test. + +2007-08-10 David Daney + + * testsuite/libffi.call/cls_multi_ushort.c, + testsuite/libffi.call/cls_align_uint16.c, + testsuite/libffi.call/nested_struct1.c, + testsuite/libffi.call/nested_struct3.c, + testsuite/libffi.call/cls_7_1_byte.c, + testsuite/libffi.call/nested_struct5.c, + testsuite/libffi.call/cls_double.c, + testsuite/libffi.call/nested_struct7.c, + testsuite/libffi.call/cls_sint.c, + testsuite/libffi.call/nested_struct9.c, + testsuite/libffi.call/cls_20byte1.c, + testsuite/libffi.call/cls_multi_sshortchar.c, + testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_3byte2.c, + testsuite/libffi.call/cls_multi_schar.c, + testsuite/libffi.call/cls_multi_uchar.c, + testsuite/libffi.call/cls_19byte.c, + testsuite/libffi.call/cls_9byte1.c, + testsuite/libffi.call/cls_align_float.c, + testsuite/libffi.call/closure_fn1.c, + testsuite/libffi.call/problem1.c, + testsuite/libffi.call/closure_fn3.c, + testsuite/libffi.call/cls_sshort.c, + testsuite/libffi.call/closure_fn5.c, + testsuite/libffi.call/cls_align_double.c, + testsuite/libffi.call/nested_struct.c, + testsuite/libffi.call/cls_2byte.c, + testsuite/libffi.call/nested_struct10.c, + testsuite/libffi.call/cls_4byte.c, + testsuite/libffi.call/cls_6byte.c, + testsuite/libffi.call/cls_8byte.c, + testsuite/libffi.call/cls_multi_sshort.c, + testsuite/libffi.call/cls_align_sint16.c, + testsuite/libffi.call/cls_align_uint32.c, + testsuite/libffi.call/cls_20byte.c, + testsuite/libffi.call/cls_float.c, + testsuite/libffi.call/nested_struct2.c, + testsuite/libffi.call/cls_5_1_byte.c, + testsuite/libffi.call/nested_struct4.c, + testsuite/libffi.call/cls_24byte.c, + testsuite/libffi.call/nested_struct6.c, + testsuite/libffi.call/cls_64byte.c, + testsuite/libffi.call/nested_struct8.c, + testsuite/libffi.call/cls_uint.c, + testsuite/libffi.call/cls_multi_ushortchar.c, + testsuite/libffi.call/cls_schar.c, + testsuite/libffi.call/cls_uchar.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/cls_align_longdouble.c, + testsuite/libffi.call/cls_1_1byte.c, + testsuite/libffi.call/cls_12byte.c, + testsuite/libffi.call/cls_3_1byte.c, + testsuite/libffi.call/cls_3byte1.c, + testsuite/libffi.call/cls_4_1byte.c, + testsuite/libffi.call/cls_6_1_byte.c, + testsuite/libffi.call/cls_16byte.c, + testsuite/libffi.call/cls_18byte.c, + testsuite/libffi.call/closure_fn0.c, + testsuite/libffi.call/cls_9byte2.c, + testsuite/libffi.call/closure_fn2.c, + testsuite/libffi.call/closure_fn4.c, + testsuite/libffi.call/cls_ushort.c, + testsuite/libffi.call/closure_fn6.c, + testsuite/libffi.call/cls_5byte.c, + testsuite/libffi.call/cls_align_pointer.c, + testsuite/libffi.call/cls_7byte.c, + testsuite/libffi.call/cls_align_sint32.c, + testsuite/libffi.special/unwindtest_ffi_call.cc, + testsuite/libffi.special/unwindtest.cc: Remove xfail for mips64*-*-*. + +2007-08-10 David Daney + + PR libffi/28313 + * configure.ac: Don't treat mips64 as a special case. + * Makefile.am (nodist_libffi_la_SOURCES): Add n32.S. + * configure: Regenerate + * Makefile.in: Ditto. + * fficonfig.h.in: Ditto. + * src/mips/ffitarget.h (REG_L, REG_S, SUBU, ADDU, SRL, LI): Indent. + (LA, EH_FRAME_ALIGN, FDE_ADDR_BYTES): New preprocessor macros. + (FFI_DEFAULT_ABI): Set for n64 case. + (FFI_CLOSURES, FFI_TRAMPOLINE_SIZE): Define for n32 and n64 cases. + * src/mips/n32.S (ffi_call_N32): Add debug macros and labels for FDE. + (ffi_closure_N32): New function. + (.eh_frame): New section + * src/mips/o32.S: Clean up comments. + (ffi_closure_O32): Pass ffi_closure parameter in $12. + * src/mips/ffi.c: Use FFI_MIPS_N32 instead of + _MIPS_SIM == _ABIN32 throughout. + (FFI_MIPS_STOP_HERE): New, use in place of + ffi_stop_here. + (ffi_prep_args): Use unsigned long to hold pointer values. Rewrite + to support n32/n64 ABIs. + (calc_n32_struct_flags): Rewrite. + (calc_n32_return_struct_flags): Remove unused variable. Reverse + position of flag bits. + (ffi_prep_cif_machdep): Rewrite n32 portion. + (ffi_call): Enable for n64. Add special handling for small structure + return values. + (ffi_prep_closure_loc): Add n32 and n64 support. + (ffi_closure_mips_inner_O32): Add cast to silence warning. + (copy_struct_N32, ffi_closure_mips_inner_N32): New functions. + +2007-08-08 David Daney + + * testsuite/libffi.call/ffitest.h (ffi_type_mylong): Remove definition. + * testsuite/libffi.call/cls_align_uint16.c (main): Use correct type + specifiers. + * testsuite/libffi.call/nested_struct1.c (main): Ditto. + * testsuite/libffi.call/cls_sint.c (main): Ditto. + * testsuite/libffi.call/nested_struct9.c (main): Ditto. + * testsuite/libffi.call/cls_20byte1.c (main): Ditto. + * testsuite/libffi.call/cls_9byte1.c (main): Ditto. + * testsuite/libffi.call/closure_fn1.c (main): Ditto. + * testsuite/libffi.call/closure_fn3.c (main): Ditto. + * testsuite/libffi.call/return_dbl2.c (main): Ditto. + * testsuite/libffi.call/cls_sshort.c (main): Ditto. + * testsuite/libffi.call/return_fl3.c (main): Ditto. + * testsuite/libffi.call/closure_fn5.c (main): Ditto. + * testsuite/libffi.call/nested_struct.c (main): Ditto. + * testsuite/libffi.call/nested_struct10.c (main): Ditto. + * testsuite/libffi.call/return_ll1.c (main): Ditto. + * testsuite/libffi.call/cls_8byte.c (main): Ditto. + * testsuite/libffi.call/cls_align_uint32.c (main): Ditto. + * testsuite/libffi.call/cls_align_sint16.c (main): Ditto. + * testsuite/libffi.call/cls_20byte.c (main): Ditto. + * testsuite/libffi.call/nested_struct2.c (main): Ditto. + * testsuite/libffi.call/cls_24byte.c (main): Ditto. + * testsuite/libffi.call/nested_struct6.c (main): Ditto. + * testsuite/libffi.call/cls_uint.c (main): Ditto. + * testsuite/libffi.call/cls_12byte.c (main): Ditto. + * testsuite/libffi.call/cls_16byte.c (main): Ditto. + * testsuite/libffi.call/closure_fn0.c (main): Ditto. + * testsuite/libffi.call/cls_9byte2.c (main): Ditto. + * testsuite/libffi.call/closure_fn2.c (main): Ditto. + * testsuite/libffi.call/return_dbl1.c (main): Ditto. + * testsuite/libffi.call/closure_fn4.c (main): Ditto. + * testsuite/libffi.call/closure_fn6.c (main): Ditto. + * testsuite/libffi.call/cls_align_sint32.c (main): Ditto. + +2007-08-07 Andrew Haley + + * src/x86/sysv.S (ffi_closure_raw_SYSV): Fix typo in previous + checkin. + +2007-08-06 Andrew Haley + + PR testsuite/32843 + * src/x86/sysv.S (ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8, + FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32, + FFI_TYPE_SINT32. + +2007-08-02 David Daney + + * testsuite/libffi.call/return_ul.c (main): Define return type as + ffi_arg. Use proper printf conversion specifier. + +2007-07-30 Andrew Haley + + PR testsuite/32843 + * src/x86/ffi.c (ffi_prep_cif_machdep): in x86 case, add code for + signed/unsigned int8/16. + * src/x86/sysv.S (ffi_call_SYSV): Rewrite to: + Use a jump table. + Remove code to pop args from the stack after call. + Special-case signed/unsigned int8/16. + * testsuite/libffi.call/return_sc.c (main): Revert. + +2007-07-26 Richard Guenther + + PR testsuite/32843 + * testsuite/libffi.call/return_sc.c (main): Verify call + result as signed char, not ffi_arg. + +2007-07-16 Rainer Orth + + * configure.ac (i?86-*-solaris2.1[0-9]): Set TARGET to X86_64. + * configure: Regenerate. + +2007-07-11 David Daney + + * src/mips/ffi.c: Don't include sys/cachectl.h. + (ffi_prep_closure_loc): Use __builtin___clear_cache() instead of + cacheflush(). + +2007-05-18 Aurelien Jarno + + * src/arm/ffi.c (ffi_prep_closure_loc): Renamed and ajusted + from (ffi_prep_closure): ... this. + (FFI_INIT_TRAMPOLINE): Adjust. + +2005-12-31 Phil Blundell + + * src/arm/ffi.c (ffi_prep_incoming_args_SYSV, + ffi_closure_SYSV_inner, ffi_prep_closure): New, add closure support. + * src/arm/sysv.S(ffi_closure_SYSV): Likewise. + * src/arm/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise. + (FFI_CLOSURES): Enable closure support. + +2007-07-03 Andrew Haley + + * testsuite/libffi.call/cls_multi_ushort.c, + testsuite/libffi.call/cls_align_uint16.c, + testsuite/libffi.call/nested_struct1.c, + testsuite/libffi.call/nested_struct3.c, + testsuite/libffi.call/cls_7_1_byte.c, + testsuite/libffi.call/cls_double.c, + testsuite/libffi.call/nested_struct5.c, + testsuite/libffi.call/nested_struct7.c, + testsuite/libffi.call/cls_sint.c, + testsuite/libffi.call/nested_struct9.c, + testsuite/libffi.call/cls_20byte1.c, + testsuite/libffi.call/cls_multi_sshortchar.c, + testsuite/libffi.call/cls_align_sint64.c, + testsuite/libffi.call/cls_3byte2.c, + testsuite/libffi.call/cls_multi_schar.c, + testsuite/libffi.call/cls_multi_uchar.c, + testsuite/libffi.call/cls_19byte.c, + testsuite/libffi.call/cls_9byte1.c, + testsuite/libffi.call/cls_align_float.c, + testsuite/libffi.call/closure_fn1.c, + testsuite/libffi.call/problem1.c, + testsuite/libffi.call/closure_fn3.c, + testsuite/libffi.call/cls_sshort.c, + testsuite/libffi.call/closure_fn5.c, + testsuite/libffi.call/cls_align_double.c, + testsuite/libffi.call/cls_2byte.c, + testsuite/libffi.call/nested_struct.c, + testsuite/libffi.call/nested_struct10.c, + testsuite/libffi.call/cls_4byte.c, + testsuite/libffi.call/cls_6byte.c, + testsuite/libffi.call/cls_8byte.c, + testsuite/libffi.call/cls_multi_sshort.c, + testsuite/libffi.call/cls_align_uint32.c, + testsuite/libffi.call/cls_align_sint16.c, + testsuite/libffi.call/cls_float.c, + testsuite/libffi.call/cls_20byte.c, + testsuite/libffi.call/cls_5_1_byte.c, + testsuite/libffi.call/nested_struct2.c, + testsuite/libffi.call/cls_24byte.c, + testsuite/libffi.call/nested_struct4.c, + testsuite/libffi.call/nested_struct6.c, + testsuite/libffi.call/cls_64byte.c, + testsuite/libffi.call/nested_struct8.c, + testsuite/libffi.call/cls_uint.c, + testsuite/libffi.call/cls_multi_ushortchar.c, + testsuite/libffi.call/cls_schar.c, + testsuite/libffi.call/cls_uchar.c, + testsuite/libffi.call/cls_align_uint64.c, + testsuite/libffi.call/cls_ulonglong.c, + testsuite/libffi.call/cls_align_longdouble.c, + testsuite/libffi.call/cls_1_1byte.c, + testsuite/libffi.call/cls_12byte.c, + testsuite/libffi.call/cls_3_1byte.c, + testsuite/libffi.call/cls_3byte1.c, + testsuite/libffi.call/cls_4_1byte.c, + testsuite/libffi.call/cls_6_1_byte.c, + testsuite/libffi.call/cls_16byte.c, + testsuite/libffi.call/cls_18byte.c, + testsuite/libffi.call/closure_fn0.c, + testsuite/libffi.call/cls_9byte2.c, + testsuite/libffi.call/closure_fn2.c, + testsuite/libffi.call/closure_fn4.c, + testsuite/libffi.call/cls_ushort.c, + testsuite/libffi.call/closure_fn6.c, + testsuite/libffi.call/cls_5byte.c, + testsuite/libffi.call/cls_align_pointer.c, + testsuite/libffi.call/cls_7byte.c, + testsuite/libffi.call/cls_align_sint32.c, + testsuite/libffi.special/unwindtest_ffi_call.cc, + testsuite/libffi.special/unwindtest.cc: Enable for ARM. + +2007-07-05 H.J. Lu + + * aclocal.m4: Regenerated. + +2007-06-02 Paolo Bonzini + + * configure: Regenerate. + +2007-05-23 Steve Ellcey + + * Makefile.in: Regenerate. + * configure: Regenerate. + * aclocal.m4: Regenerate. + * include/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2007-05-10 Roman Zippel + + * src/m68k/ffi.c (ffi_prep_incoming_args_SYSV, + ffi_closure_SYSV_inner,ffi_prep_closure): New, add closure support. + * src/m68k/sysv.S(ffi_closure_SYSV,ffi_closure_struct_SYSV): Likewise. + * src/m68k/ffitarget.h (FFI_TRAMPOLINE_SIZE): Likewise. + (FFI_CLOSURES): Enable closure support. + +2007-05-10 Roman Zippel + + * configure.ac (HAVE_AS_CFI_PSEUDO_OP): New test. + * configure: Regenerate. + * fficonfig.h.in: Regenerate. + * src/m68k/sysv.S (CFI_STARTPROC,CFI_ENDPROC, + CFI_OFFSET,CFI_DEF_CFA): New macros. + (ffi_call_SYSV): Add callframe annotation. + +2007-05-10 Roman Zippel + + * src/m68k/ffi.c (ffi_prep_args,ffi_prep_cif_machdep): Fix + numerous test suite failures. + * src/m68k/sysv.S (ffi_call_SYSV): Likewise. + +2007-04-11 Paolo Bonzini + + * Makefile.am (EXTRA_DIST): Bring up to date. + * Makefile.in: Regenerate. + * src/frv/eabi.S: Remove RCS keyword. + +2007-04-06 Richard Henderson + + * configure.ac: Tidy target case. + (HAVE_LONG_DOUBLE): Allow the target to override. + * configure: Regenerate. + * include/ffi.h.in: Don't define ffi_type_foo if + LIBFFI_HIDE_BASIC_TYPES is defined. + (ffi_type_longdouble): If not HAVE_LONG_DOUBLE, define + to ffi_type_double. + * types.c (LIBFFI_HIDE_BASIC_TYPES): Define. + (FFI_TYPEDEF, ffi_type_void): Mark the data const. + (ffi_type_longdouble): Special case for Alpha. Don't define + if long double == double. + + * src/alpha/ffi.c (FFI_TYPE_LONGDOUBLE): Assert unique value. + (ffi_prep_cif_machdep): Handle it as the 128-bit type. + (ffi_call, ffi_closure_osf_inner): Likewise. + (ffi_closure_osf_inner): Likewise. Mark hidden. + (ffi_call_osf, ffi_closure_osf): Mark hidden. + * src/alpha/ffitarget.h (FFI_LAST_ABI): Tidy definition. + * src/alpha/osf.S (ffi_call_osf, ffi_closure_osf): Mark hidden. + (load_table): Handle 128-bit long double. + + * testsuite/libffi.call/float4.c: Add -mieee for alpha. + +2007-04-06 Tom Tromey + + PR libffi/31491: + * README: Fixed bug in example. + +2007-04-03 Jakub Jelinek + + * src/closures.c: Include sys/statfs.h. + (_GNU_SOURCE): Define on Linux. + (FFI_MMAP_EXEC_SELINUX): Define. + (selinux_enabled): New variable. + (selinux_enabled_check): New function. + (is_selinux_enabled): Define. + (dlmmap): Use it. + +2007-03-24 Uros Bizjak + + * testsuite/libffi.call/return_fl2.c (return_fl): Mark as static. + Use 'volatile float sum' to create sum of floats to avoid false + negative due to excess precision on ix86 targets. + (main): Ditto. + +2007-03-08 Alexandre Oliva + + * src/powerpc/ffi.c (flush_icache): Fix left-over from previous + patch. + (ffi_prep_closure_loc): Remove unneeded casts. Add needed ones. + +2007-03-07 Alexandre Oliva + + * include/ffi.h.in (ffi_closure_alloc, ffi_closure_free): New. + (ffi_prep_closure_loc): New. + (ffi_prep_raw_closure_loc): New. + (ffi_prep_java_raw_closure_loc): New. + * src/closures.c: New file. + * src/dlmalloc.c [FFI_MMAP_EXEC_WRIT] (struct malloc_segment): + Replace sflags with exec_offset. + [FFI_MMAP_EXEC_WRIT] (mmap_exec_offset, add_segment_exec_offset, + sub_segment_exec_offset): New macros. + (get_segment_flags, set_segment_flags, check_segment_merge): New + macros. + (is_mmapped_segment, is_extern_segment): Use get_segment_flags. + (add_segment, sys_alloc, create_mspace, create_mspace_with_base, + destroy_mspace): Use new macros. + (sys_alloc): Silence warning. + * Makefile.am (libffi_la_SOURCES): Add src/closures.c. + * Makefile.in: Rebuilt. + * src/prep_cif [FFI_CLOSURES] (ffi_prep_closure): Implement in + terms of ffi_prep_closure_loc. + * src/raw_api.c (ffi_prep_raw_closure_loc): Renamed and adjusted + from... + (ffi_prep_raw_closure): ... this. Re-implement in terms of the + renamed version. + * src/java_raw_api (ffi_prep_java_raw_closure_loc): Renamed and + adjusted from... + (ffi_prep_java_raw_closure): ... this. Re-implement in terms of + the renamed version. + * src/alpha/ffi.c (ffi_prep_closure_loc): Renamed from + (ffi_prep_closure): ... this. + * src/pa/ffi.c: Likewise. + * src/cris/ffi.c: Likewise. Adjust. + * src/frv/ffi.c: Likewise. + * src/ia64/ffi.c: Likewise. + * src/mips/ffi.c: Likewise. + * src/powerpc/ffi_darwin.c: Likewise. + * src/s390/ffi.c: Likewise. + * src/sh/ffi.c: Likewise. + * src/sh64/ffi.c: Likewise. + * src/sparc/ffi.c: Likewise. + * src/x86/ffi64.c: Likewise. + * src/x86/ffi.c: Likewise. + (FFI_INIT_TRAMPOLINE): Adjust. + (ffi_prep_raw_closure_loc): Renamed and adjusted from... + (ffi_prep_raw_closure): ... this. + * src/powerpc/ffi.c (ffi_prep_closure_loc): Renamed from + (ffi_prep_closure): ... this. + (flush_icache): Adjust. + +2007-03-07 Alexandre Oliva + + * src/dlmalloc.c: New file, imported version 2.8.3 of Doug + Lea's malloc. + +2007-03-01 Brooks Moses + + * Makefile.am: Add dummy install-pdf target. + * Makefile.in: Regenerate + +2007-02-13 Andreas Krebbel + + * src/s390/ffi.c (ffi_prep_args, ffi_prep_cif_machdep, + ffi_closure_helper_SYSV): Add long double handling. + +2007-02-02 Jakub Jelinek + + * src/powerpc/linux64.S (ffi_call_LINUX64): Move restore of r2 + immediately after bctrl instruction. + +2007-01-18 Alexandre Oliva + + * Makefile.am (all-recursive, install-recursive, + mostlyclean-recursive, clean-recursive, distclean-recursive, + maintainer-clean-recursive): Add missing targets. + * Makefile.in: Rebuilt. + +2006-12-14 Andreas Tobler + + * configure.ac: Add TARGET for x86_64-*-darwin*. + * Makefile.am (nodist_libffi_la_SOURCES): Add rules for 64-bit sources + for X86_DARWIN. + * src/x86/ffitarget.h: Set trampoline size for x86_64-*-darwin*. + * src/x86/darwin64.S: New file for x86_64-*-darwin* support. + * configure: Regenerate. + * Makefile.in: Regenerate. + * include/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + * testsuite/libffi.special/unwindtest_ffi_call.cc: New test case for + ffi_call only. + +2006-12-13 Andreas Tobler + + * aclocal.m4: Regenerate with aclocal -I .. as written in the + Makefile.am. + +2006-10-31 Geoffrey Keating + + * src/powerpc/ffi_darwin.c (darwin_adjust_aggregate_sizes): New. + (ffi_prep_cif_machdep): Call darwin_adjust_aggregate_sizes for + Darwin. + * testsuite/libffi.call/nested_struct4.c: Remove Darwin XFAIL. + * testsuite/libffi.call/nested_struct6.c: Remove Darwin XFAIL. + +2006-10-10 Paolo Bonzini + Sandro Tolaini + + * configure.ac [i*86-*-darwin*]: Set X86_DARWIN symbol and + conditional. + * configure: Regenerated. + * Makefile.am (nodist_libffi_la_SOURCES) [X86_DARWIN]: New case. + (EXTRA_DIST): Add src/x86/darwin.S. + * Makefile.in: Regenerated. + * include/Makefile.in: Regenerated. + * testsuite/Makefile.in: Regenerated. + + * src/x86/ffi.c (ffi_prep_cif_machdep) [X86_DARWIN]: Treat like + X86_WIN32, and additionally align stack to 16 bytes. + * src/x86/darwin.S: New, based on sysv.S. + * src/prep_cif.c (ffi_prep_cif) [X86_DARWIN]: Align > 8-byte structs. + +2006-09-12 David Daney + + PR libffi/23935 + * include/Makefile.am: Install both ffi.h and ffitarget.h in + $(libdir)/gcc/$(target_alias)/$(gcc_version)/include. + * aclocal.m4: Regenerated for automake 1.9.6. + * Makefile.in: Regenerated. + * include/Makefile.in: Regenerated. + * testsuite/Makefile.in: Regenerated. + +2006-08-17 Andreas Tobler + + * include/ffi_common.h (struct): Revert accidental commit. + +2006-08-15 Andreas Tobler + + * include/ffi_common.h: Remove lint directives. + * include/ffi.h.in: Likewise. + +2006-07-25 Torsten Schoenfeld + + * include/ffi.h.in (ffi_type_ulong, ffi_type_slong): Define correctly + for 32-bit architectures. + * testsuite/libffi.call/return_ul.c: New test case. + +2006-07-19 David Daney + + * testsuite/libffi.call/closure_fn6.c: Remove xfail for mips, + xfail remains for mips64. + +2006-05-23 Carlos O'Donell + + * Makefile.am: Add install-html target. Add install-html to .PHONY + * Makefile.in: Regenerate. + * aclocal.m4: Regenerate. + * include/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2006-05-18 John David Anglin + + * pa/ffi.c (ffi_prep_args_pa32): Load floating point arguments from + stack slot. + +2006-04-22 Andreas Tobler + + * README: Remove notice about 'Crazy Comments'. + * src/debug.c: Remove lint directives. Cleanup white spaces. + * src/java_raw_api.c: Likewise. + * src/prep_cif.c: Likewise. + * src/raw_api.c: Likewise. + * src/ffitest.c: Delete. No longer needed, all test cases migrated + to the testsuite. + * src/arm/ffi.c: Remove lint directives. + * src/m32r/ffi.c: Likewise. + * src/pa/ffi.c: Likewise. + * src/powerpc/ffi.c: Likewise. + * src/powerpc/ffi_darwin.c: Likewise. + * src/sh/ffi.c: Likewise. + * src/sh64/ffi.c: Likewise. + * src/x86/ffi.c: Likewise. + * testsuite/libffi.call/float2.c: Likewise. + * testsuite/libffi.call/promotion.c: Likewise. + * testsuite/libffi.call/struct1.c: Likewise. + +2006-04-13 Andreas Tobler + + * src/pa/hpux32.S: Correct unwind offset calculation for + ffi_closure_pa32. + * src/pa/linux.S: Likewise. + +2006-04-12 James E Wilson + + PR libgcj/26483 + * src/ia64/ffi.c (stf_spill, ldf_fill): Rewrite as macros. + (hfa_type_load): Call stf_spill. + (hfa_type_store): Call ldf_fill. + (ffi_call): Adjust calls to above routines. Add local temps for + macro result. + +2006-04-10 Matthias Klose + + * testsuite/lib/libffi-dg.exp (libffi-init): Recognize multilib + directory names containing underscores. + +2006-04-07 James E Wilson + + * testsuite/libffi.call/float4.c: New testcase. + +2006-04-05 John David Anglin + Andreas Tobler + + * Makefile.am: Add PA_HPUX port. + * Makefile.in: Regenerate. + * include/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + * configure.ac: Add PA_HPUX rules. + * configure: Regenerate. + * src/pa/ffitarget.h: Rename linux target to PA_LINUX. + Add PA_HPUX and PA64_HPUX. + Rename FFI_LINUX ABI to FFI_PA32 ABI. + (FFI_TRAMPOLINE_SIZE): Define for 32-bit HP-UX targets. + (FFI_TYPE_SMALL_STRUCT2): Define. + (FFI_TYPE_SMALL_STRUCT4): Likewise. + (FFI_TYPE_SMALL_STRUCT8): Likewise. + (FFI_TYPE_SMALL_STRUCT3): Redefine. + (FFI_TYPE_SMALL_STRUCT5): Likewise. + (FFI_TYPE_SMALL_STRUCT6): Likewise. + (FFI_TYPE_SMALL_STRUCT7): Likewise. + * src/pa/ffi.c (ROUND_DOWN): Delete. + (fldw, fstw, fldd, fstd): Use '__asm__'. + (ffi_struct_type): Add support for FFI_TYPE_SMALL_STRUCT2, + FFI_TYPE_SMALL_STRUCT4 and FFI_TYPE_SMALL_STRUCT8. + (ffi_prep_args_LINUX): Rename to ffi_prep_args_pa32. Update comment. + Simplify incrementing of stack slot variable. Change type of local + 'n' to unsigned int. + (ffi_size_stack_LINUX): Rename to ffi_size_stack_pa32. Handle long + double on PA_HPUX. + (ffi_prep_cif_machdep): Likewise. + (ffi_call): Likewise. + (ffi_closure_inner_LINUX): Rename to ffi_closure_inner_pa32. Change + return type to ffi_status. Simplify incrementing of stack slot + variable. Only copy floating point argument registers when PA_LINUX + is true. Reformat debug statement. + Add support for FFI_TYPE_SMALL_STRUCT2, FFI_TYPE_SMALL_STRUCT4 and + FFI_TYPE_SMALL_STRUCT8. + (ffi_closure_LINUX): Rename to ffi_closure_pa32. Add 'extern' to + declaration. + (ffi_prep_closure): Make linux trampoline conditional on PA_LINUX. + Add nops to cache flush. Add trampoline for PA_HPUX. + * src/pa/hpux32.S: New file. + * src/pa/linux.S (ffi_call_LINUX): Rename to ffi_call_pa32. Rename + ffi_prep_args_LINUX to ffi_prep_args_pa32. + Localize labels. Add support for 2, 4 and 8-byte small structs. Handle + unaligned destinations in 3, 5, 6 and 7-byte small structs. Order + argument type checks so that common argument types appear first. + (ffi_closure_LINUX): Rename to ffi_closure_pa32. Rename + ffi_closure_inner_LINUX to ffi_closure_inner_pa32. + +2006-03-24 Alan Modra + + * src/powerpc/ffitarget.h (enum ffi_abi): Add FFI_LINUX. Default + for 32-bit using IBM extended double format. Fix FFI_LAST_ABI. + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Handle linux variant of + FFI_TYPE_LONGDOUBLE. + (ffi_prep_args64): Assert using IBM extended double. + (ffi_prep_cif_machdep): Don't munge FFI_TYPE_LONGDOUBLE type. + Handle FFI_LINUX FFI_TYPE_LONGDOUBLE return and args. + (ffi_call): Handle FFI_LINUX. + (ffi_closure_helper_SYSV): Non FFI_LINUX long double return needs + gpr3 return pointer as for struct return. Handle FFI_LINUX + FFI_TYPE_LONGDOUBLE return and args. Don't increment "nf" + unnecessarily. + * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Load both f1 and f2 + for FFI_TYPE_LONGDOUBLE. Move epilogue insns into case table. + Don't use r6 as pointer to results, instead use sp offset. Don't + make a special call to load lr with case table address, instead + use offset from previous call. + * src/powerpc/sysv.S (ffi_call_SYSV): Save long double return. + * src/powerpc/linux64.S (ffi_call_LINUX64): Simplify long double + return. + +2006-03-15 Kaz Kojima + + * src/sh64/ffi.c (ffi_prep_cif_machdep): Handle float arguments + passed with FP registers correctly. + (ffi_closure_helper_SYSV): Likewise. + * src/sh64/sysv.S: Likewise. + +2006-03-01 Andreas Tobler + + * testsuite/libffi.special/unwindtest.cc (closure_test_fn): Mark cif, + args and userdata unused. + (closure_test_fn1): Mark cif and userdata unused. + (main): Remove unused res. + +2006-02-28 Andreas Tobler + + * testsuite/libffi.call/call.exp: Adjust FSF address. Add test runs for + -O2, -O3, -Os and the warning flags -W -Wall. + * testsuite/libffi.special/special.exp: Likewise. + * testsuite/libffi.call/ffitest.h: Add an __UNUSED__ macro to mark + unused parameter unused for gcc or else do nothing. + * testsuite/libffi.special/ffitestcxx.h: Likewise. + * testsuite/libffi.call/cls_12byte.c (cls_struct_12byte_gn): Mark cif + and userdata unused. + * testsuite/libffi.call/cls_16byte.c (cls_struct_16byte_gn): Likewise. + * testsuite/libffi.call/cls_18byte.c (cls_struct_18byte_gn): Likewise. + * testsuite/libffi.call/cls_19byte.c (cls_struct_19byte_gn): Likewise. + * testsuite/libffi.call/cls_1_1byte.c (cls_struct_1_1byte_gn): Likewise. + * testsuite/libffi.call/cls_20byte.c (cls_struct_20byte_gn): Likewise. + * testsuite/libffi.call/cls_20byte1.c (cls_struct_20byte_gn): Likewise. + * testsuite/libffi.call/cls_24byte.c (cls_struct_24byte_gn): Likewise. + * testsuite/libffi.call/cls_2byte.c (cls_struct_2byte_gn): Likewise. + * testsuite/libffi.call/cls_3_1byte.c (cls_struct_3_1byte_gn): Likewise. + * testsuite/libffi.call/cls_3byte1.c (cls_struct_3byte_gn): Likewise. + * testsuite/libffi.call/cls_3byte2.c (cls_struct_3byte_gn1): Likewise. + * testsuite/libffi.call/cls_4_1byte.c (cls_struct_4_1byte_gn): Likewise. + * testsuite/libffi.call/cls_4byte.c (cls_struct_4byte_gn): Likewise. + * testsuite/libffi.call/cls_5_1_byte.c (cls_struct_5byte_gn): Likewise. + * testsuite/libffi.call/cls_5byte.c (cls_struct_5byte_gn): Likewise. + * testsuite/libffi.call/cls_64byte.c (cls_struct_64byte_gn): Likewise. + * testsuite/libffi.call/cls_6_1_byte.c (cls_struct_6byte_gn): Likewise. + * testsuite/libffi.call/cls_6byte.c (cls_struct_6byte_gn): Likewise. + * testsuite/libffi.call/cls_7_1_byte.c (cls_struct_7byte_gn): Likewise. + * testsuite/libffi.call/cls_7byte.c (cls_struct_7byte_gn): Likewise. + * testsuite/libffi.call/cls_8byte.c (cls_struct_8byte_gn): Likewise. + * testsuite/libffi.call/cls_9byte1.c (cls_struct_9byte_gn): Likewise. + * testsuite/libffi.call/cls_9byte2.c (cls_struct_9byte_gn): Likewise. + * testsuite/libffi.call/cls_align_double.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_float.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_longdouble.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_pointer.c (cls_struct_align_fn): Cast + void* to avoid compiler warning. + (main): Likewise. + (cls_struct_align_gn): Mark cif and userdata unused. + * testsuite/libffi.call/cls_align_sint16.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_sint32.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_sint64.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_uint16.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_align_uint32.c (cls_struct_align_gn): + Likewise. + * testsuite/libffi.call/cls_double.c (cls_ret_double_fn): Likewise. + * testsuite/libffi.call/cls_float.c (cls_ret_float_fn): Likewise. + * testsuite/libffi.call/cls_multi_schar.c (test_func_gn): Mark cif and + data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_multi_sshort.c (test_func_gn): Mark cif and + data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_multi_sshortchar.c (test_func_gn): Mark cif + and data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_multi_uchar.c (test_func_gn): Mark cif and + data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_multi_ushort.c (test_func_gn): Mark cif and + data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_multi_ushortchar.c (test_func_gn): Mark cif + and data unused. + (main): Cast res_call to silence gcc. + * testsuite/libffi.call/cls_schar.c (cls_ret_schar_fn): Mark cif and + userdata unused. + (cls_ret_schar_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/cls_sint.c (cls_ret_sint_fn): Mark cif and + userdata unused. + (cls_ret_sint_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/cls_sshort.c (cls_ret_sshort_fn): Mark cif and + userdata unused. + (cls_ret_sshort_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/cls_uchar.c (cls_ret_uchar_fn): Mark cif and + userdata unused. + (cls_ret_uchar_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/cls_uint.c (cls_ret_uint_fn): Mark cif and + userdata unused. + (cls_ret_uint_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/cls_ulonglong.c (cls_ret_ulonglong_fn): Mark cif + and userdata unused. + * testsuite/libffi.call/cls_ushort.c (cls_ret_ushort_fn): Mark cif and + userdata unused. + (cls_ret_ushort_fn): Cast printf parameter to silence gcc. + * testsuite/libffi.call/float.c (floating): Remove unused parameter e. + * testsuite/libffi.call/float1.c (main): Remove unused variable i. + Cleanup white spaces. + * testsuite/libffi.call/negint.c (checking): Remove unused variable i. + * testsuite/libffi.call/nested_struct.c (cls_struct_combined_gn): Mark + cif and userdata unused. + * testsuite/libffi.call/nested_struct1.c (cls_struct_combined_gn): + Likewise. + * testsuite/libffi.call/nested_struct10.c (B_gn): Likewise. + * testsuite/libffi.call/nested_struct2.c (B_fn): Adjust printf + formatters to silence gcc. + (B_gn): Mark cif and userdata unused. + * testsuite/libffi.call/nested_struct3.c (B_gn): Mark cif and userdata + unused. + * testsuite/libffi.call/nested_struct4.c: Mention related PR. + (B_gn): Mark cif and userdata unused. + * testsuite/libffi.call/nested_struct5.c (B_gn): Mark cif and userdata + unused. + * testsuite/libffi.call/nested_struct6.c: Mention related PR. + (B_gn): Mark cif and userdata unused. + * testsuite/libffi.call/nested_struct7.c (B_gn): Mark cif and userdata + unused. + * testsuite/libffi.call/nested_struct8.c (B_gn): Likewise. + * testsuite/libffi.call/nested_struct9.c (B_gn): Likewise. + * testsuite/libffi.call/problem1.c (stub): Likewise. + * testsuite/libffi.call/pyobjc-tc.c (main): Cast the result to silence + gcc. + * testsuite/libffi.call/return_fl2.c (return_fl): Add the note mentioned + in the last commit for this test case in the test case itself. + * testsuite/libffi.call/closure_fn0.c (closure_test_fn0): Mark cif as + unused. + * testsuite/libffi.call/closure_fn1.c (closure_test_fn1): Likewise. + * testsuite/libffi.call/closure_fn2.c (closure_test_fn2): Likewise. + * testsuite/libffi.call/closure_fn3.c (closure_test_fn3): Likewise. + * testsuite/libffi.call/closure_fn4.c (closure_test_fn0): Likewise. + * testsuite/libffi.call/closure_fn5.c (closure_test_fn5): Likewise. + * testsuite/libffi.call/closure_fn6.c (closure_test_fn0): Likewise. + +2006-02-22 Kaz Kojima + + * src/sh/sysv.S: Fix register numbers in the FDE for + ffi_closure_SYSV. + +2006-02-20 Andreas Tobler + + * testsuite/libffi.call/return_fl2.c (return_fl): Remove static + declaration to avoid a false negative on ix86. See PR323. + +2006-02-18 Kaz Kojima + + * src/sh/ffi.c (ffi_closure_helper_SYSV): Remove unused variable + and cast integer to void * if needed. Update the pointer to + the FP register saved area correctly. + +2006-02-17 Andreas Tobler + + * testsuite/libffi.call/nested_struct6.c: XFAIL this test until PR25630 + is fixed. + * testsuite/libffi.call/nested_struct4.c: Likewise. + +2006-02-16 Andreas Tobler + + * testsuite/libffi.call/return_dbl.c: New test case. + * testsuite/libffi.call/return_dbl1.c: Likewise. + * testsuite/libffi.call/return_dbl2.c: Likewise. + * testsuite/libffi.call/return_fl.c: Likewise. + * testsuite/libffi.call/return_fl1.c: Likewise. + * testsuite/libffi.call/return_fl2.c: Likewise. + * testsuite/libffi.call/return_fl3.c: Likewise. + * testsuite/libffi.call/closure_fn6.c: Likewise. + + * testsuite/libffi.call/nested_struct2.c: Remove ffi_type_mylong + definition. + * testsuite/libffi.call/ffitest.h: Add ffi_type_mylong definition + here to be used by other test cases too. + + * testsuite/libffi.call/nested_struct10.c: New test case. + * testsuite/libffi.call/nested_struct9.c: Likewise. + * testsuite/libffi.call/nested_struct8.c: Likewise. + * testsuite/libffi.call/nested_struct7.c: Likewise. + * testsuite/libffi.call/nested_struct6.c: Likewise. + * testsuite/libffi.call/nested_struct5.c: Likewise. + * testsuite/libffi.call/nested_struct4.c: Likewise. + +2006-01-21 Andreas Tobler + + * configure.ac: Enable libffi for sparc64-*-freebsd*. + * configure: Rebuilt. + +2006-01-18 Jakub Jelinek + + * src/powerpc/sysv.S (smst_two_register): Don't call __ashldi3, + instead do the shifting inline. + * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't compute %r5 + shift count unconditionally. Simplify load sequences for 1, 2, 3, 4 + and 8 byte structs, for the remaining struct sizes don't call + __lshrdi3, instead do the shifting inline. + +2005-12-07 Thiemo Seufer + + * src/mips/ffitarget.h: Remove obsolete sgidefs.h include. Add + missing parentheses. + * src/mips/o32.S (ffi_call_O32): Code formatting. Define + and use A3_OFF, FP_OFF, RA_OFF. Micro-optimizations. + (ffi_closure_O32): Likewise, but with newly defined A3_OFF2, + A2_OFF2, A1_OFF2, A0_OFF2, RA_OFF2, FP_OFF2, S0_OFF2, GP_OFF2, + V1_OFF2, V0_OFF2, FA_1_1_OFF2, FA_1_0_OFF2, FA_0_1_OFF2, + FA_0_0_OFF2. + * src/mips/ffi.c (ffi_prep_args): Code formatting. Fix + endianness bugs. + (ffi_prep_closure): Improve trampoline instruction scheduling. + (ffi_closure_mips_inner_O32): Fix endianness bugs. + +2005-12-03 Alan Modra + + * src/powerpc/ffi.c: Formatting. + (ffi_prep_args_SYSV): Avoid possible aliasing problems by using unions. + (ffi_prep_args64): Likewise. + +2005-09-30 Geoffrey Keating + + * testsuite/lib/libffi-dg.exp (libffi_target_compile): For + darwin, use -shared-libgcc not -lgcc_s, and explain why. + +2005-09-26 Tom Tromey + + * testsuite/libffi.call/float1.c (value_type): New typedef. + (CANARY): New define. + (main): Check for result buffer overflow. + * src/powerpc/linux64.S: Handle linux64 long double returns. + * src/powerpc/ffi.c (FLAG_RETURNS_128BITS): New constant. + (ffi_prep_cif_machdep): Handle linux64 long double returns. + +2005-08-25 Alan Modra + + PR target/23404 + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Correct placement of stack + homed fp args. + (ffi_status ffi_prep_cif_machdep): Correct stack sizing for same. + +2005-08-11 Jakub Jelinek + + * configure.ac (HAVE_HIDDEN_VISIBILITY_ATTRIBUTE): New test. + (AH_BOTTOM): Add FFI_HIDDEN definition. + * configure: Rebuilt. + * fficonfig.h.in: Rebuilt. + * src/powerpc/ffi.c (hidden): Remove. + (ffi_closure_LINUX64, ffi_prep_args64, ffi_call_LINUX64, + ffi_closure_helper_LINUX64): Use FFI_HIDDEN instead of hidden. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64, + .ffi_closure_LINUX64): Use FFI_HIDDEN instead of .hidden. + * src/x86/ffi.c (ffi_closure_SYSV, ffi_closure_raw_SYSV): Remove, + add FFI_HIDDEN to its prototype. + (ffi_closure_SYSV_inner): New. + * src/x86/sysv.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New. + * src/x86/win32.S (ffi_closure_SYSV, ffi_closure_raw_SYSV): New. + +2005-08-10 Alfred M. Szmidt + + PR libffi/21819: + * configure: Rebuilt. + * configure.ac: Handle i*86-*-gnu*. + +2005-08-09 Jakub Jelinek + + * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Use + DW_CFA_offset_extended_sf rather than + DW_CFA_GNU_negative_offset_extended. + * src/powerpc/sysv.S (ffi_call_SYSV): Likewise. + +2005-07-22 SUGIOKA Toshinobu + + * src/sh/sysv.S (ffi_call_SYSV): Stop argument popping correctly + on sh3. + (ffi_closure_SYSV): Change the stack layout for sh3 struct argument. + * src/sh/ffi.c (ffi_prep_args): Fix sh3 argument copy, when it is + partially on register. + (ffi_closure_helper_SYSV): Likewise. + (ffi_prep_cif_machdep): Don't set too many cif->flags. + +2005-07-20 Kaz Kojima + + * src/sh/ffi.c (ffi_call): Handle small structures correctly. + Remove empty line. + * src/sh64/ffi.c (simple_type): Remove. + (return_type): Handle small structures correctly. + (ffi_prep_args): Likewise. + (ffi_call): Likewise. + (ffi_closure_helper_SYSV): Likewise. + * src/sh64/sysv.S (ffi_call_SYSV): Handle 1, 2 and 4-byte return. + Emit position independent code if PIC and remove wrong datalabel + prefixes from EH data. + +2005-07-19 Andreas Tobler + + * Makefile.am (nodist_libffi_la_SOURCES): Add POWERPC_FREEBSD. + * Makefile.in: Regenerate. + * include/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + * configure.ac: Add POWERPC_FREEBSD rules. + * configure: Regenerate. + * src/powerpc/ffitarget.h: Add POWERPC_FREEBSD rules. + (FFI_SYSV_TYPE_SMALL_STRUCT): Define. + * src/powerpc/ffi.c: Add flags to handle small structure returns + in ffi_call_SYSV. + (ffi_prep_cif_machdep): Handle small structures for SYSV 4 ABI. + Aka FFI_SYSV. + (ffi_closure_helper_SYSV): Likewise. + * src/powerpc/ppc_closure.S: Add return types for small structures. + * src/powerpc/sysv.S: Add bits to handle small structures for + final SYSV 4 ABI. + +2005-07-10 Andreas Tobler + + * testsuite/libffi.call/cls_5_1_byte.c: New test file. + * testsuite/libffi.call/cls_6_1_byte.c: Likewise. + * testsuite/libffi.call/cls_7_1_byte.c: Likewise. + +2005-07-05 Randolph Chung + + * src/pa/ffi.c (ffi_struct_type): Rename FFI_TYPE_SMALL_STRUCT1 + as FFI_TYPE_SMALL_STRUCT3. Break out handling for 5-7 byte + structures. Kill compilation warnings. + (ffi_closure_inner_LINUX): Print return values as hex in debug + message. Rename FFI_TYPE_SMALL_STRUCT1 as FFI_TYPE_SMALL_STRUCT3. + Properly handle 5-7 byte structure returns. + * src/pa/ffitarget.h (FFI_TYPE_SMALL_STRUCT1) + (FFI_TYPE_SMALL_STRUCT2): Remove. + (FFI_TYPE_SMALL_STRUCT3, FFI_TYPE_SMALL_STRUCT5) + (FFI_TYPE_SMALL_STRUCT6, FFI_TYPE_SMALL_STRUCT7): Define. + * src/pa/linux.S: Mark source file as using PA1.1 assembly. + (checksmst1, checksmst2): Remove. + (checksmst3): Optimize handling of 3-byte struct returns. + (checksmst567): Properly handle 5-7 byte struct returns. + +2005-06-15 Rainer Orth + + PR libgcj/21943 + * src/mips/n32.S: Enforce PIC code. + * src/mips/o32.S: Likewise. + +2005-06-15 Rainer Orth + + * configure.ac: Treat i*86-*-solaris2.10 and up as X86_64. + * configure: Regenerate. + +2005-06-01 Alan Modra + + * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't use JUMPTARGET + to call ffi_closure_helper_SYSV. Append @local instead. + * src/powerpc/sysv.S (ffi_call_SYSV): Likewise for ffi_prep_args_SYSV. + +2005-05-17 Kelley Cook + + * configure.ac: Use AC_C_BIGENDIAN instead of AC_C_BIGENDIAN_CROSS. + Use AC_CHECK_SIZEOF instead of AC_COMPILE_CHECK_SIZEOF. + * Makefile.am (ACLOCAL_AMFLAGS): Remove -I ../config. + * aclocal.m4, configure, fficonfig.h.in, Makefile.in, + include/Makefile.in, testsuite/Makefile.in: Regenerate. + +2005-05-09 Mike Stump + + * configure: Regenerate. + +2005-05-08 Richard Henderson + + PR libffi/21285 + * src/alpha/osf.S: Update unwind into to match code. + +2005-05-04 Andreas Degert + Richard Henderson + + * src/x86/ffi64.c (ffi_prep_cif_machdep): Save sse-used flag in + bit 11 of flags. + (ffi_call): Mask return type field. Pass ssecount to ffi_call_unix64. + (ffi_prep_closure): Set carry bit if sse-used flag set. + * src/x86/unix64.S (ffi_call_unix64): Add ssecount argument. + Only load sse registers if ssecount non-zero. + (ffi_closure_unix64): Only save sse registers if carry set on entry. + +2005-04-29 Ralf Corsepius + + * configure.ac: Add i*86-*-rtems*, sparc*-*-rtems*, + powerpc-*rtems*, arm*-*-rtems*, sh-*-rtems*. + * configure: Regenerate. + +2005-04-20 Hans-Peter Nilsson + + * testsuite/lib/libffi-dg.exp (libffi-dg-test-1): In regsub use, + have Tcl8.3-compatible intermediate variable. + +2005-04-18 Simon Posnjak + Hans-Peter Nilsson + + * Makefile.am: Add CRIS support. + * configure.ac: Likewise. + * Makefile.in, configure, testsuite/Makefile.in, + include/Makefile.in: Regenerate. + * src/cris: New directory. + * src/cris/ffi.c, src/cris/sysv.S, src/cris/ffitarget.h: New files. + * src/prep_cif.c (ffi_prep_cif): Wrap in #ifndef __CRIS__. + + * testsuite/lib/libffi-dg.exp (libffi-dg-test-1): Replace \n with + \r?\n in output tests. + +2005-04-12 Mike Stump + + * configure: Regenerate. + +2005-03-30 Hans Boehm + + * src/ia64/ffitarget.h (ffi_arg): Use long long instead of DI. + +2005-03-30 Steve Ellcey + + * src/ia64/ffitarget.h (ffi_arg) ADD DI attribute. + (ffi_sarg) Ditto. + * src/ia64/unix.S (ffi_closure_unix): Extend gp + to 64 bits in ILP32 mode. + Load 64 bits even for short data. + +2005-03-23 Mike Stump + + * src/powerpc/darwin.S: Update for -m64 multilib. + * src/powerpc/darwin_closure.S: Likewise. + +2005-03-21 Zack Weinberg + + * configure.ac: Do not invoke TL_AC_GCC_VERSION. + Do not set tool_include_dir. + * aclocal.m4, configure, Makefile.in, testsuite/Makefile.in: + Regenerate. + * include/Makefile.am: Set gcc_version and toollibffidir. + * include/Makefile.in: Regenerate. + +2005-02-22 Andrew Haley + + * src/powerpc/ffi.c (ffi_prep_cif_machdep): Bump alignment to + odd-numbered register pairs for 64-bit integer types. + +2005-02-23 Andreas Tobler + + PR libffi/20104 + * testsuite/libffi.call/return_ll1.c: New test case. + +2005-02-11 Janis Johnson + + * testsuite/libffi.call/cls_align_longdouble.c: Remove dg-options. + * testsuite/libffi.call/float.c: Ditto. + * testsuite/libffi.call/float2.c: Ditto. + * testsuite/libffi.call/float3.c: Ditto. + +2005-02-08 Andreas Tobler + + * src/frv/ffitarget.h: Remove PPC stuff which does not belong to frv. + +2005-01-12 Eric Botcazou + + * testsuite/libffi.special/special.exp (cxx_options): Add + -shared-libgcc. + +2004-12-31 Richard Henderson + + * src/types.c (FFI_AGGREGATE_TYPEDEF): Remove. + (FFI_TYPEDEF): Rename from FFI_INTEGRAL_TYPEDEF. Replace size and + offset parameters with a type parameter; deduce size and structure + alignment. Update all users. + +2004-12-31 Richard Henderson + + * src/types.c (FFI_TYPE_POINTER): Define with sizeof. + (FFI_TYPE_LONGDOUBLE): Fix for ia64. + * src/ia64/ffitarget.h (struct ffi_ia64_trampoline_struct): Move + into ffi_prep_closure. + * src/ia64/ia64_flags.h, src/ia64/ffi.c, src/ia64/unix.S: Rewrite + from scratch. + +2004-12-27 Richard Henderson + + * src/x86/unix64.S: Fix typo in unwind info. + +2004-12-25 Richard Henderson + + * src/x86/ffi64.c (struct register_args): Rename from stackLayout. + (enum x86_64_reg_class): Add X86_64_COMPLEX_X87_CLASS. + (merge_classes): Check for it. + (SSE_CLASS_P): New. + (classify_argument): Pass byte_offset by value; perform all updates + inside struct case. + (examine_argument): Add classes argument; handle + X86_64_COMPLEX_X87_CLASS. + (ffi_prep_args): Merge into ... + (ffi_call): ... here. Share stack frame with ffi_call_unix64. + (ffi_prep_cif_machdep): Setup cif->flags for proper structure return. + (ffi_fill_return_value): Remove. + (ffi_prep_closure): Remove dead assert. + (ffi_closure_unix64_inner): Rename from ffi_closure_UNIX64_inner. + Rewrite to use struct register_args instead of va_list. Create + flags for handling structure returns. + * src/x86/unix64.S: Remove dead strings. + (ffi_call_unix64): Rename from ffi_call_UNIX64. Rewrite to share + stack frame with ffi_call. Handle structure returns properly. + (float2sse, floatfloat2sse, double2sse): Remove. + (sse2float, sse2double, sse2floatfloat): Remove. + (ffi_closure_unix64): Rename from ffi_closure_UNIX64. Rewrite + to handle structure returns properly. + +2004-12-08 David Edelsohn + + * Makefile.am (AM_MAKEFLAGS): Remove duplicate LIBCFLAGS and + PICFLAG. + * Makefile.in: Regenerated. + +2004-12-02 Richard Sandiford + + * configure.ac: Use TL_AC_GCC_VERSION to set gcc_version. + * configure, aclocal.m4, Makefile.in: Regenerate. + * include/Makefile.in, testsuite/Makefile.in: Regenerate. + +2004-11-29 Kelley Cook + + * configure: Regenerate for libtool change. + +2004-11-25 Kelley Cook + + * configure: Regenerate for libtool reversion. + +2004-11-24 Kelley Cook + + * configure: Regenerate for libtool change. + +2004-11-23 John David Anglin + + * testsuite/lib/libffi-dg.exp: Use new procs in target-libpath.exp. + +2004-11-23 Richard Sandiford + + * src/mips/o32.S (ffi_call_O32, ffi_closure_O32): Use jalr instead + of jal. Use an absolute encoding for the frame information. + +2004-11-23 Kelley Cook + + * Makefile.am: Remove no-dependencies. Add ACLOCAL_AMFLAGS. + * acinclude.m4: Delete logic for sincludes. + * aclocal.m4, Makefile.in, configure: Regenerate. + * include/Makefile: Likewise. + * testsuite/Makefile: Likewise. + +2004-11-22 Eric Botcazou + + * src/sparc/ffi.c (ffi_prep_closure): Align doubles and 64-bit integers + on a 8-byte boundary. + * src/sparc/v8.S (ffi_closure_v8): Reserve frame space for arguments. + +2004-10-27 Richard Earnshaw + + * src/arm/ffi.c (ffi_prep_cif_machdep): Handle functions that return + long long values. Round stack allocation to a multiple of 8 bytes + for ATPCS compatibility. + * src/arm/sysv.S (ffi_call_SYSV): Rework to avoid use of APCS register + names. Handle returning long long types. Add Thumb and interworking + support. Improve soft-float code. + +2004-10-27 Richard Earnshaw + + * testsuite/lib/libffi-db.exp (load_gcc_lib): New function. + (libffi_exit): New function. + (libffi_init): Build the testglue wrapper if needed. + +2004-10-25 Eric Botcazou + + PR other/18138 + * testsuite/lib/libffi-dg.exp: Accept more than one multilib libgcc. + +2004-10-25 Kazuhiro Inaoka + + * src/m32r/libffitarget.h (FFI_CLOSURES): Set to 0. + +2004-10-20 Kaz Kojima + + * src/sh/sysv.S (ffi_call_SYSV): Don't align for double data. + * testsuite/libffi.call/float3.c: New test case. + +2004-10-18 Kaz Kojima + + * src/sh/ffi.c (ffi_prep_closure): Set T bit in trampoline for + the function returning a structure pointed with R2. + * src/sh/sysv.S (ffi_closure_SYSV): Use R2 as the pointer to + the structure return value if T bit set. Emit position + independent code and EH data if PIC. + +2004-10-13 Kazuhiro Inaoka + + * Makefile.am: Add m32r support. + * configure.ac: Likewise. + * Makefile.in: Regenerate. + * confiugre: Regenerate. + * src/types.c: Add m32r port to FFI_INTERNAL_TYPEDEF + (uint64, sint64, double, longdouble) + * src/m32r: New directory. + * src/m32r/ffi.c: New file. + * src/m32r/sysv.S: Likewise. + * src/m32r/ffitarget.h: Likewise. + +2004-10-02 Kaz Kojima + + * testsuite/libffi.call/negint.c: New test case. + +2004-09-14 H.J. Lu + + PR libgcj/17465 + * testsuite/lib/libffi-dg.exp: Don't use global ld_library_path. + Set up LD_LIBRARY_PATH, SHLIB_PATH, LD_LIBRARYN32_PATH, + LD_LIBRARY64_PATH, LD_LIBRARY_PATH_32, LD_LIBRARY_PATH_64 and + DYLD_LIBRARY_PATH. + +2004-09-05 Andreas Tobler + + * testsuite/libffi.call/many_win32.c: Remove whitespaces. + * testsuite/libffi.call/promotion.c: Likewise. + * testsuite/libffi.call/return_ll.c: Remove unused var. Cleanup + whitespaces. + * testsuite/libffi.call/return_sc.c: Likewise. + * testsuite/libffi.call/return_uc.c: Likewise. + +2004-09-05 Andreas Tobler + + * src/powerpc/darwin.S: Fix comments and identation. + * src/powerpc/darwin_closure.S: Likewise. + +2004-09-02 Andreas Tobler + + * src/powerpc/ffi_darwin.c: Add flag for longdouble return values. + (ffi_prep_args): Handle longdouble arguments. + (ffi_prep_cif_machdep): Set flags for longdouble. Calculate space for + longdouble. + (ffi_closure_helper_DARWIN): Add closure handling for longdouble. + * src/powerpc/darwin.S (_ffi_call_DARWIN): Add handling of longdouble + values. + * src/powerpc/darwin_closure.S (_ffi_closure_ASM): Likewise. + * src/types.c: Defined longdouble size and alignment for darwin. + +2004-09-02 Andreas Tobler + + * src/powerpc/aix.S: Remove whitespaces. + * src/powerpc/aix_closure.S: Likewise. + * src/powerpc/asm.h: Likewise. + * src/powerpc/ffi.c: Likewise. + * src/powerpc/ffitarget.h: Likewise. + * src/powerpc/linux64.S: Likewise. + * src/powerpc/linux64_closure.S: Likewise. + * src/powerpc/ppc_closure.S: Likewise. + * src/powerpc/sysv.S: Likewise. + +2004-08-30 Anthony Green + + * Makefile.am: Add frv support. + * Makefile.in, testsuite/Makefile.in: Rebuilt. + * configure.ac: Read configure.host. + * configure.in: Read configure.host. + * configure.host: New file. frv-elf needs libgloss. + * include/ffi.h.in: Force ffi_closure to have a nice big (8) + alignment. This is needed to frv and shouldn't harm the others. + * include/ffi_common.h (ALIGN_DOWN): New macro. + * src/frv/ffi.c, src/frv/ffitarget.h, src/frv/eabi.S: New files. + +2004-08-24 David Daney + + * testsuite/libffi.call/closure_fn0.c: Xfail mips64* instead of mips*. + * testsuite/libffi.call/closure_fn1.c: Likewise. + * testsuite/libffi.call/closure_fn2.c Likewise. + * testsuite/libffi.call/closure_fn3.c: Likewise. + * testsuite/libffi.call/closure_fn4.c: Likewise. + * testsuite/libffi.call/closure_fn5.c: Likewise. + * testsuite/libffi.call/cls_18byte.c: Likewise. + * testsuite/libffi.call/cls_19byte.c: Likewise. + * testsuite/libffi.call/cls_1_1byte.c: Likewise. + * testsuite/libffi.call/cls_20byte.c: Likewise. + * testsuite/libffi.call/cls_20byte1.c: Likewise. + * testsuite/libffi.call/cls_24byte.c: Likewise. + * testsuite/libffi.call/cls_2byte.c: Likewise. + * testsuite/libffi.call/cls_3_1byte.c: Likewise. + * testsuite/libffi.call/cls_3byte1.c: Likewise. + * testsuite/libffi.call/cls_3byte2.c: Likewise. + * testsuite/libffi.call/cls_4_1byte.c: Likewise. + * testsuite/libffi.call/cls_4byte.c: Likewise. + * testsuite/libffi.call/cls_64byte.c: Likewise. + * testsuite/libffi.call/cls_6byte.c: Likewise. + * testsuite/libffi.call/cls_7byte.c: Likewise. + * testsuite/libffi.call/cls_8byte.c: Likewise. + * testsuite/libffi.call/cls_9byte1.c: Likewise. + * testsuite/libffi.call/cls_9byte2.c: Likewise. + * testsuite/libffi.call/cls_align_double.c: Likewise. + * testsuite/libffi.call/cls_align_float.c: Likewise. + * testsuite/libffi.call/cls_align_longdouble.c: Likewise. + * testsuite/libffi.call/cls_align_pointer.c: Likewise. + * testsuite/libffi.call/cls_align_sint16.c: Likewise. + * testsuite/libffi.call/cls_align_sint32.c: Likewise. + * testsuite/libffi.call/cls_align_sint64.c: Likewise. + * testsuite/libffi.call/cls_align_uint16.c: Likewise. + * testsuite/libffi.call/cls_align_uint32.c: Likewise. + * testsuite/libffi.call/cls_align_uint64.c: Likewise. + * testsuite/libffi.call/cls_double.c: Likewise. + * testsuite/libffi.call/cls_float.c: Likewise. + * testsuite/libffi.call/cls_multi_schar.c: Likewise. + * testsuite/libffi.call/cls_multi_sshort.c: Likewise. + * testsuite/libffi.call/cls_multi_sshortchar.c: Likewise. + * testsuite/libffi.call/cls_multi_uchar.c: Likewise. + * testsuite/libffi.call/cls_multi_ushort.c: Likewise. + * testsuite/libffi.call/cls_multi_ushortchar.c: Likewise. + * testsuite/libffi.call/cls_schar.c: Likewise. + * testsuite/libffi.call/cls_sint.c: Likewise. + * testsuite/libffi.call/cls_sshort.c: Likewise. + * testsuite/libffi.call/cls_uchar.c: Likewise. + * testsuite/libffi.call/cls_uint.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/cls_ushort.c: Likewise. + * testsuite/libffi.call/nested_struct.c: Likewise. + * testsuite/libffi.call/nested_struct1.c: Likewise. + * testsuite/libffi.call/nested_struct2.c: Likewise. + * testsuite/libffi.call/nested_struct3.c: Likewise. + * testsuite/libffi.call/problem1.c: Likewise. + * testsuite/libffi.special/unwindtest.cc: Likewise. + * testsuite/libffi.call/cls_12byte.c: Likewise and set return value + to zero. + * testsuite/libffi.call/cls_16byte.c: Likewise. + * testsuite/libffi.call/cls_5byte.c: Likewise. + +2004-08-23 David Daney + + PR libgcj/13141 + * src/mips/ffitarget.h (FFI_O32_SOFT_FLOAT): New ABI. + * src/mips/ffi.c (ffi_prep_args): Fix alignment calculation. + (ffi_prep_cif_machdep): Handle FFI_O32_SOFT_FLOAT floating point + parameters and return types. + (ffi_call): Handle FFI_O32_SOFT_FLOAT ABI. + (ffi_prep_closure): Ditto. + (ffi_closure_mips_inner_O32): Handle FFI_O32_SOFT_FLOAT ABI, fix + alignment calculations. + * src/mips/o32.S (ffi_closure_O32): Don't use floating point + instructions if FFI_O32_SOFT_FLOAT, make stack frame ABI compliant. + +2004-08-14 Casey Marshall + + * src/mips/ffi.c (ffi_pref_cif_machdep): set `cif->flags' to + contain `FFI_TYPE_UINT64' as return type for any 64-bit + integer (O32 ABI only). + (ffi_prep_closure): new function. + (ffi_closure_mips_inner_O32): new function. + * src/mips/ffitarget.h: Define `FFI_CLOSURES' and + `FFI_TRAMPOLINE_SIZE' appropriately if the ABI is o32. + * src/mips/o32.S (ffi_call_O32): add labels for .eh_frame. Return + 64 bit integers correctly. + (ffi_closure_O32): new function. + Added DWARF-2 unwind info for both functions. + +2004-08-10 Andrew Haley + + * src/x86/ffi64.c (ffi_prep_args ): 8-align all stack arguments. + +2004-08-01 Robert Millan + + * configure.ac: Detect knetbsd-gnu and kfreebsd-gnu. + * configure: Regenerate. + +2004-07-30 Maciej W. Rozycki + + * acinclude.m4 (AC_FUNC_MMAP_BLACKLIST): Check for + and mmap() explicitly instead of relying on preset autoconf cache + variables. + * aclocal.m4: Regenerate. + * configure: Regenerate. + +2004-07-11 Ulrich Weigand + + * src/s390/ffi.c (ffi_prep_args): Fix C aliasing violation. + (ffi_check_float_struct): Remove unused prototype. + +2004-06-30 Geoffrey Keating + + * src/powerpc/ffi_darwin.c (flush_icache): ';' is a comment + character on Darwin, use '\n\t' instead. + +2004-06-26 Matthias Klose + + * libtool-version: Fix typo in revision/age. + +2004-06-17 Matthias Klose + + * libtool-version: New. + * Makefile.am (libffi_la_LDFLAGS): Use -version-info for soname. + * Makefile.in: Regenerate. + +2004-06-15 Paolo Bonzini + + * Makefile.am: Remove useless multilib rules. + * Makefile.in: Regenerate. + * aclocal.m4: Regenerate with automake 1.8.5. + * configure.ac: Remove useless multilib configury. + * configure: Regenerate. + +2004-06-15 Paolo Bonzini + + * .cvsignore: New file. + +2004-06-10 Jakub Jelinek + + * src/ia64/unix.S (ffi_call_unix): Insert group barrier break + fp_done. + (ffi_closure_UNIX): Fix f14/f15 adjustment if FLOAT_SZ is ever + changed from 8. + +2004-06-06 Sean McNeil + + * configure.ac: Add x86_64-*-freebsd* support. + * configure: Regenerate. + +2004-04-26 Joe Buck + + Bug 15093 + * configure.ac: Test for existence of mmap and sys/mman.h before + checking blacklist. Fix suggested by Jim Wilson. + * configure: Regenerate. + +2004-04-26 Matt Austern + + * src/powerpc/darwin.S: Go through a non-lazy pointer for initial + FDE location. + * src/powerpc/darwin_closure.S: Likewise. + +2004-04-24 Andreas Tobler + + * testsuite/libffi.call/cls_multi_schar.c (main): Fix initialization + error. Reported by Thomas Heller . + * testsuite/libffi.call/cls_multi_sshort.c (main): Likewise. + * testsuite/libffi.call/cls_multi_ushort.c (main): Likewise. + +2004-03-20 Matthias Klose + + * src/pa/linux.S: Fix typo. + +2004-03-19 Matthias Klose + + * Makefile.am: Update. + * Makefile.in: Regenerate. + * src/pa/ffi.h.in: Remove. + * src/pa/ffitarget.h: New file. + +2004-02-10 Randolph Chung + + * Makefile.am: Add PA support. + * Makefile.in: Regenerate. + * include/Makefile.in: Regenerate. + * configure.ac: Add PA target. + * configure: Regenerate. + * src/pa/ffi.c: New file. + * src/pa/ffi.h.in: Add PA support. + * src/pa/linux.S: New file. + * prep_cif.c: Add PA support. + +2004-03-16 Hosaka Yuji + + * src/types.c: Fix alignment size of X86_WIN32 case int64 and + double. + * src/x86/ffi.c (ffi_prep_args): Replace ecif->cif->rtype->type + with ecif->cif->flags. + (ffi_call, ffi_prep_incoming_args_SYSV): Replace cif->rtype->type + with cif->flags. + (ffi_prep_cif_machdep): Add X86_WIN32 struct case. + (ffi_closure_SYSV): Add 1 or 2-bytes struct case for X86_WIN32. + * src/x86/win32.S (retstruct1b, retstruct2b, sc_retstruct1b, + sc_retstruct2b): Add for 1 or 2-bytes struct case. + +2004-03-15 Kelley Cook + + * configure.in: Rename file to ... + * configure.ac: ... this. + * fficonfig.h.in: Regenerate. + * Makefile.in: Regenerate. + * include/Makefile.in: Regenerate. + * testsuite/Makefile.in: Regenerate. + +2004-03-12 Matt Austern + + * src/powerpc/darwin.S: Fix EH information so it corresponds to + changes in EH format resulting from addition of linkonce support. + * src/powerpc/darwin_closure.S: Likewise. + +2004-03-11 Andreas Tobler + Paolo Bonzini + + * Makefile.am (AUTOMAKE_OPTIONS): Set them. + Remove VPATH. Remove rules for object files. Remove multilib support. + (AM_CCASFLAGS): Add. + * configure.in (AC_CONFIG_HEADERS): Relace AM_CONFIG_HEADER. + (AC_PREREQ): Bump version to 2.59. + (AC_INIT): Fill with version info and bug address. + (ORIGINAL_LD_FOR_MULTILIBS): Remove. + (AM_ENABLE_MULTILIB): Use this instead of AC_ARG_ENABLE. + De-precious CC so that the right flags are passed down to multilibs. + (AC_MSG_ERROR): Replace obsolete macro AC_ERROR. + (AC_CONFIG_FILES): Replace obsolete macro AC_LINK_FILES. + (AC_OUTPUT): Reorganize the output with AC_CONFIG_COMMANDS. + * configure: Rebuilt. + * aclocal.m4: Likewise. + * Makefile.in, include/Makefile.in, testsuite/Makefile.in: Likewise. + * fficonfig.h.in: Likewise. + +2004-03-11 Andreas Schwab + + * src/ia64/ffi.c (ffi_prep_incoming_args_UNIX): Get floating point + arguments from fp registers only for the first 8 parameter slots. + Don't convert a float parameter when passed in memory. + +2004-03-09 Hans-Peter Nilsson + + * configure: Regenerate for config/accross.m4 correction. + +2004-02-25 Matt Kraai + + * src/powerpc/ffi.c (ffi_prep_args_SYSV): Change + ecif->cif->bytes to bytes. + (ffi_prep_cif_machdep): Add braces around nested if statement. + +2004-02-09 Alan Modra + + * src/types.c (pointer): POWERPC64 has 8 byte pointers. + + * src/powerpc/ffi.c (ffi_prep_args64): Correct long double handling. + (ffi_closure_helper_LINUX64): Fix typo. + * testsuite/libffi.call/cls_align_longdouble.c: Pass -mlong-double-128 + for powerpc64-*-*. + * testsuite/libffi.call/float.c: Likewise. + * testsuite/libffi.call/float2.c: Likewise. + +2004-02-08 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_cif_machdep ): Correct + long double function return and long double arg handling. + (ffi_closure_helper_LINUX64): Formatting. Delete unused "ng" var. + Use "end_pfr" instead of "nf". Correct long double handling. + Localise "temp". + * src/powerpc/linux64.S (ffi_call_LINUX64): Save f2 long double + return value. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Allocate + space for long double return value. Adjust stack frame and offsets. + Load f2 long double return. + +2004-02-07 Alan Modra + + * src/types.c: Use 16 byte long double for POWERPC64. + +2004-01-25 Eric Botcazou + + * src/sparc/ffi.c (ffi_prep_args_v9): Shift the parameter array + when the structure return address is passed in %o0. + (ffi_V9_return_struct): Rename into ffi_v9_layout_struct. + (ffi_v9_layout_struct): Align the field following a nested structure + on a word boundary. Use memmove instead of memcpy. + (ffi_call): Update call to ffi_V9_return_struct. + (ffi_prep_closure): Define 'ctx' only for V8. + (ffi_closure_sparc_inner): Clone into ffi_closure_sparc_inner_v8 + and ffi_closure_sparc_inner_v9. + (ffi_closure_sparc_inner_v8): Return long doubles by reference. + Always skip the structure return address. For structures and long + doubles, copy the argument directly. + (ffi_closure_sparc_inner_v9): Skip the structure return address only + if required. Shift the maximum floating-point slot accordingly. For + big structures, copy the argument directly; otherwise, left-justify the + argument and call ffi_v9_layout_struct to lay out the structure on + the stack. + * src/sparc/v8.S: Undef STACKFRAME before defining it. + (ffi_closure_v8): Pass the structure return address. Update call to + ffi_closure_sparc_inner_v8. Short-circuit FFI_TYPE_INT handling. + Skip the 'unimp' insn when returning long doubles and structures. + * src/sparc/v9.S: Undef STACKFRAME before defining it. + (ffi_closure_v9): Increase the frame size by 2 words. Short-circuit + FFI_TYPE_INT handling. Load structures both in integers and + floating-point registers on return. + * README: Update status of the SPARC port. + +2004-01-24 Andreas Tobler + + * testsuite/libffi.call/pyobjc-tc.c (main): Treat result value + as of type ffi_arg. + * testsuite/libffi.call/struct3.c (main): Fix CHECK. + +2004-01-22 Ulrich Weigand + + * testsuite/libffi.call/cls_uint.c (cls_ret_uint_fn): Treat result + value as of type ffi_arg, not unsigned int. + +2004-01-21 Michael Ritzert + + * ffi64.c (ffi_prep_args): Cast the RHS of an assignment instead + of the LHS. + +2004-01-12 Andreas Tobler + + * testsuite/lib/libffi-dg.exp: Set LD_LIBRARY_PATH_32 for + Solaris. + +2004-01-08 Rainer Orth + + * testsuite/libffi.call/ffitest.h (allocate_mmap): Cast MAP_FAILED + to void *. + +2003-12-10 Richard Henderson + + * testsuite/libffi.call/cls_align_pointer.c: Cast pointers to + size_t instead of int. + +2003-12-04 Hosaka Yuji + + * testsuite/libffi.call/many_win32.c: Include . + * testsuite/libffi.call/many_win32.c (main): Replace variable + int i with unsigned long ul. + + * testsuite/libffi.call/cls_align_uint64.c: New test case. + * testsuite/libffi.call/cls_align_sint64.c: Likewise. + * testsuite/libffi.call/cls_align_uint32.c: Likewise. + * testsuite/libffi.call/cls_align_sint32.c: Likewise. + * testsuite/libffi.call/cls_align_uint16.c: Likewise. + * testsuite/libffi.call/cls_align_sint16.c: Likewise. + * testsuite/libffi.call/cls_align_float.c: Likewise. + * testsuite/libffi.call/cls_align_double.c: Likewise. + * testsuite/libffi.call/cls_align_longdouble.c: Likewise. + * testsuite/libffi.call/cls_align_pointer.c: Likewise. + +2003-12-02 Hosaka Yuji + + PR other/13221 + * src/x86/ffi.c (ffi_prep_args, ffi_prep_incoming_args_SYSV): + Align arguments to 32 bits. + +2003-12-01 Andreas Tobler + + PR other/13221 + * testsuite/libffi.call/cls_multi_sshort.c: New test case. + * testsuite/libffi.call/cls_multi_sshortchar.c: Likewise. + * testsuite/libffi.call/cls_multi_uchar.c: Likewise. + * testsuite/libffi.call/cls_multi_schar.c: Likewise. + * testsuite/libffi.call/cls_multi_ushortchar.c: Likewise. + * testsuite/libffi.call/cls_multi_ushort.c: Likewise. + + * testsuite/libffi.special/unwindtest.cc: Cosmetics. + +2003-11-26 Kaveh R. Ghazi + + * testsuite/libffi.call/ffitest.h: Include . + * testsuite/libffi.special/ffitestcxx.h: Likewise. + +2003-11-22 Andreas Tobler + + * Makefile.in: Rebuilt. + * configure: Likewise. + * testsuite/libffi.special/unwindtest.cc: Convert the mmap to + the right type. + +2003-11-21 Andreas Jaeger + Andreas Tobler + + * acinclude.m4: Add AC_FUNC_MMAP_BLACKLIST. + * configure.in: Call AC_FUNC_MMAP_BLACKLIST. + * Makefile.in: Rebuilt. + * aclocal.m4: Likewise. + * configure: Likewise. + * fficonfig.h.in: Likewise. + * testsuite/lib/libffi-dg.exp: Add include dir. + * testsuite/libffi.call/ffitest.h: Add MMAP definitions. + * testsuite/libffi.special/ffitestcxx.h: Likewise. + * testsuite/libffi.call/closure_fn0.c: Use MMAP functionality + for ffi_closure if available. + * testsuite/libffi.call/closure_fn1.c: Likewise. + * testsuite/libffi.call/closure_fn2.c: Likewise. + * testsuite/libffi.call/closure_fn3.c: Likewise. + * testsuite/libffi.call/closure_fn4.c: Likewise. + * testsuite/libffi.call/closure_fn5.c: Likewise. + * testsuite/libffi.call/cls_12byte.c: Likewise. + * testsuite/libffi.call/cls_16byte.c: Likewise. + * testsuite/libffi.call/cls_18byte.c: Likewise. + * testsuite/libffi.call/cls_19byte.c: Likewise. + * testsuite/libffi.call/cls_1_1byte.c: Likewise. + * testsuite/libffi.call/cls_20byte.c: Likewise. + * testsuite/libffi.call/cls_20byte1.c: Likewise. + * testsuite/libffi.call/cls_24byte.c: Likewise. + * testsuite/libffi.call/cls_2byte.c: Likewise. + * testsuite/libffi.call/cls_3_1byte.c: Likewise. + * testsuite/libffi.call/cls_3byte1.c: Likewise. + * testsuite/libffi.call/cls_3byte2.c: Likewise. + * testsuite/libffi.call/cls_4_1byte.c: Likewise. + * testsuite/libffi.call/cls_4byte.c: Likewise. + * testsuite/libffi.call/cls_5byte.c: Likewise. + * testsuite/libffi.call/cls_64byte.c: Likewise. + * testsuite/libffi.call/cls_6byte.c: Likewise. + * testsuite/libffi.call/cls_7byte.c: Likewise. + * testsuite/libffi.call/cls_8byte.c: Likewise. + * testsuite/libffi.call/cls_9byte1.c: Likewise. + * testsuite/libffi.call/cls_9byte2.c: Likewise. + * testsuite/libffi.call/cls_double.c: Likewise. + * testsuite/libffi.call/cls_float.c: Likewise. + * testsuite/libffi.call/cls_schar.c: Likewise. + * testsuite/libffi.call/cls_sint.c: Likewise. + * testsuite/libffi.call/cls_sshort.c: Likewise. + * testsuite/libffi.call/cls_uchar.c: Likewise. + * testsuite/libffi.call/cls_uint.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/cls_ushort.c: Likewise. + * testsuite/libffi.call/nested_struct.c: Likewise. + * testsuite/libffi.call/nested_struct1.c: Likewise. + * testsuite/libffi.call/nested_struct2.c: Likewise. + * testsuite/libffi.call/nested_struct3.c: Likewise. + * testsuite/libffi.call/problem1.c: Likewise. + * testsuite/libffi.special/unwindtest.cc: Likewise. + +2003-11-20 Andreas Tobler + + * testsuite/lib/libffi-dg.exp: Make the -lgcc_s conditional. + +2003-11-19 Andreas Tobler + + * testsuite/lib/libffi-dg.exp: Add DYLD_LIBRARY_PATH for darwin. + Add -lgcc_s to additional flags. + +2003-11-12 Andreas Tobler + + * configure.in, include/Makefile.am: PR libgcj/11147, install + the ffitarget.h header file in a gcc versioned and target + dependent place. + * configure: Regenerated. + * Makefile.in, include/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + +2003-11-09 Andreas Tobler + + * testsuite/libffi.call/closure_fn0.c: Print result and check + with dg-output to make debugging easier. + * testsuite/libffi.call/closure_fn1.c: Likewise. + * testsuite/libffi.call/closure_fn2.c: Likewise. + * testsuite/libffi.call/closure_fn3.c: Likewise. + * testsuite/libffi.call/closure_fn4.c: Likewise. + * testsuite/libffi.call/closure_fn5.c: Likewise. + * testsuite/libffi.call/cls_12byte.c: Likewise. + * testsuite/libffi.call/cls_16byte.c: Likewise. + * testsuite/libffi.call/cls_18byte.c: Likewise. + * testsuite/libffi.call/cls_19byte.c: Likewise. + * testsuite/libffi.call/cls_1_1byte.c: Likewise. + * testsuite/libffi.call/cls_20byte.c: Likewise. + * testsuite/libffi.call/cls_20byte1.c: Likewise. + * testsuite/libffi.call/cls_24byte.c: Likewise. + * testsuite/libffi.call/cls_2byte.c: Likewise. + * testsuite/libffi.call/cls_3_1byte.c: Likewise. + * testsuite/libffi.call/cls_3byte1.c: Likewise. + * testsuite/libffi.call/cls_3byte2.c: Likewise. + * testsuite/libffi.call/cls_4_1byte.c: Likewise. + * testsuite/libffi.call/cls_4byte.c: Likewise. + * testsuite/libffi.call/cls_5byte.c: Likewise. + * testsuite/libffi.call/cls_64byte.c: Likewise. + * testsuite/libffi.call/cls_6byte.c: Likewise. + * testsuite/libffi.call/cls_7byte.c: Likewise. + * testsuite/libffi.call/cls_8byte.c: Likewise. + * testsuite/libffi.call/cls_9byte1.c: Likewise. + * testsuite/libffi.call/cls_9byte2.c: Likewise. + * testsuite/libffi.call/cls_double.c: Likewise. + * testsuite/libffi.call/cls_float.c: Likewise. + * testsuite/libffi.call/cls_schar.c: Likewise. + * testsuite/libffi.call/cls_sint.c: Likewise. + * testsuite/libffi.call/cls_sshort.c: Likewise. + * testsuite/libffi.call/cls_uchar.c: Likewise. + * testsuite/libffi.call/cls_uint.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/cls_ushort.c: Likewise. + * testsuite/libffi.call/problem1.c: Likewise. + + * testsuite/libffi.special/unwindtest.cc: Make ffi_closure + static. + +2003-11-08 Andreas Tobler + + * testsuite/libffi.call/cls_9byte2.c: New test case. + * testsuite/libffi.call/cls_9byte1.c: Likewise. + * testsuite/libffi.call/cls_64byte.c: Likewise. + * testsuite/libffi.call/cls_20byte1.c: Likewise. + * testsuite/libffi.call/cls_19byte.c: Likewise. + * testsuite/libffi.call/cls_18byte.c: Likewise. + * testsuite/libffi.call/closure_fn4.c: Likewise. + * testsuite/libffi.call/closure_fn5.c: Likewise. + * testsuite/libffi.call/cls_schar.c: Likewise. + * testsuite/libffi.call/cls_sint.c: Likewise. + * testsuite/libffi.call/cls_sshort.c: Likewise. + * testsuite/libffi.call/nested_struct2.c: Likewise. + * testsuite/libffi.call/nested_struct3.c: Likewise. + +2003-11-08 Andreas Tobler + + * testsuite/libffi.call/cls_double.c: Do a check on the result. + * testsuite/libffi.call/cls_uchar.c: Likewise. + * testsuite/libffi.call/cls_uint.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/cls_ushort.c: Likewise. + * testsuite/libffi.call/return_sc.c: Cleanup whitespaces. + +2003-11-06 Andreas Tobler + + * src/prep_cif.c (ffi_prep_cif): Move the validity check after + the initialization. + +2003-10-23 Andreas Tobler + + * src/java_raw_api.c (ffi_java_ptrarray_to_raw): Replace + FFI_ASSERT(FALSE) with FFI_ASSERT(0). + +2003-10-22 David Daney + + * src/mips/ffitarget.h: Replace undefined UINT32 and friends with + __attribute__((__mode__(__SI__))) and friends. + +2003-10-22 Andreas Schwab + + * src/ia64/ffi.c: Replace FALSE/TRUE with false/true. + +2003-10-21 Andreas Tobler + + * configure.in: AC_LINK_FILES(ffitarget.h). + * configure: Regenerate. + * Makefile.in: Likewise. + * include/Makefile.in: Likewise. + * testsuite/Makefile.in: Likewise. + * fficonfig.h.in: Likewise. + +2003-10-21 Paolo Bonzini + Richard Henderson + + Avoid that ffi.h includes fficonfig.h. + + * Makefile.am (EXTRA_DIST): Include ffitarget.h files + (TARGET_SRC_MIPS_GCC): Renamed to TARGET_SRC_MIPS_IRIX. + (TARGET_SRC_MIPS_SGI): Removed. + (MIPS_GCC): Renamed to TARGET_SRC_MIPS_IRIX. + (MIPS_SGI): Removed. + (CLEANFILES): Removed. + (mostlyclean-am, clean-am, mostlyclean-sub, clean-sub): New + targets. + * acconfig.h: Removed. + * configure.in: Compute sizeofs only for double and long double. + Use them to define and subst HAVE_LONG_DOUBLE. Include comments + into AC_DEFINE instead of using acconfig.h. Create + include/ffitarget.h instead of include/fficonfig.h. Rename + MIPS_GCC to MIPS_IRIX, drop MIPS_SGI since we are in gcc's tree. + AC_DEFINE EH_FRAME_FLAGS. + * include/Makefile.am (DISTCLEANFILES): New automake macro. + (hack_DATA): Add ffitarget.h. + * include/ffi.h.in: Remove all system specific definitions. + Declare raw API even if it is not installed, why bother? + Use limits.h instead of SIZEOF_* to define ffi_type_*. Do + not define EH_FRAME_FLAGS, it is in fficonfig.h now. Include + ffitarget.h instead of fficonfig.h. Remove ALIGN macro. + (UINT_ARG, INT_ARG): Removed, use ffi_arg and ffi_sarg instead. + * include/ffi_common.h (bool): Do not define. + (ffi_assert): Accept failed assertion. + (ffi_type_test): Return void and accept file/line. + (FFI_ASSERT): Pass stringized failed assertion. + (FFI_ASSERT_AT): New macro. + (FFI_ASSERT_VALID_TYPE): New macro. + (UINT8, SINT8, UINT16, SINT16, UINT32, SINT32, + UINT64, SINT64): Define here with gcc's __attribute__ macro + instead of in ffi.h + (FLOAT32, ALIGN): Define here instead of in ffi.h + * include/ffi-mips.h: Removed. Its content moved to + src/mips/ffitarget.h after separating assembly and C sections. + * src/alpha/ffi.c, src/alpha/ffi.c, src/java_raw_api.c + src/prep_cif.c, src/raw_api.c, src/ia64/ffi.c, + src/mips/ffi.c, src/mips/n32.S, src/mips/o32.S, + src/mips/ffitarget.h, src/sparc/ffi.c, src/x86/ffi64.c: + SIZEOF_ARG -> FFI_SIZEOF_ARG. + * src/ia64/ffi.c: Include stdbool.h (provided by GCC 2.95+). + * src/debug.c (ffi_assert): Accept stringized failed assertion. + (ffi_type_test): Rewritten. + * src/prep-cif.c (initialize_aggregate, ffi_prep_cif): Call + FFI_ASSERT_VALID_TYPE. + * src/alpha/ffitarget.h, src/arm/ffitarget.h, + src/ia64/ffitarget.h, src/m68k/ffitarget.h, + src/mips/ffitarget.h, src/powerpc/ffitarget.h, + src/s390/ffitarget.h, src/sh/ffitarget.h, + src/sh64/ffitarget.h, src/sparc/ffitarget.h, + src/x86/ffitarget.h: New files. + * src/alpha/osf.S, src/arm/sysv.S, src/ia64/unix.S, + src/m68k/sysv.S, src/mips/n32.S, src/mips/o32.S, + src/powerpc/aix.S, src/powerpc/darwin.S, + src/powerpc/ffi_darwin.c, src/powerpc/linux64.S, + src/powerpc/linux64_closure.S, src/powerpc/ppc_closure.S, + src/powerpc/sysv.S, src/s390/sysv.S, src/sh/sysv.S, + src/sh64/sysv.S, src/sparc/v8.S, src/sparc/v9.S, + src/x86/sysv.S, src/x86/unix64.S, src/x86/win32.S: + include fficonfig.h + +2003-10-20 Rainer Orth + + * src/mips/ffi.c: Use _ABIN32, _ABIO32 instead of external + _MIPS_SIM_NABI32, _MIPS_SIM_ABI32. + +2003-10-19 Andreas Tobler + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Declare bytes again. + Used when FFI_DEBUG = 1. + +2003-10-14 Alan Modra + + * src/types.c (double, longdouble): Default POWERPC64 to 8 byte size + and align. + +2003-10-06 Rainer Orth + + * include/ffi_mips.h: Define FFI_MIPS_N32 for N32/N64 ABIs, + FFI_MIPS_O32 for O32 ABI. + +2003-10-01 Andreas Tobler + + * testsuite/lib/libffi-dg.exp: Set LD_LIBRARY_PATH_64 for + SPARC64. Cleanup whitespaces. + +2003-09-19 Andreas Tobler + + * testsuite/libffi.call/closure_fn0.c: Xfail mips, arm, + strongarm, xscale. Cleanup whitespaces. + * testsuite/libffi.call/closure_fn1.c: Likewise. + * testsuite/libffi.call/closure_fn2.c: Likewise. + * testsuite/libffi.call/closure_fn3.c: Likewise. + * testsuite/libffi.call/cls_12byte.c: Likewise. + * testsuite/libffi.call/cls_16byte.c: Likewise. + * testsuite/libffi.call/cls_1_1byte.c: Likewise. + * testsuite/libffi.call/cls_20byte.c: Likewise. + * testsuite/libffi.call/cls_24byte.c: Likewise. + * testsuite/libffi.call/cls_2byte.c: Likewise. + * testsuite/libffi.call/cls_3_1byte.c: Likewise. + * testsuite/libffi.call/cls_3byte1.c: Likewise. + * testsuite/libffi.call/cls_3byte2.c: Likewise. + * testsuite/libffi.call/cls_4_1byte.c: Likewise. + * testsuite/libffi.call/cls_4byte.c: Likewise. + * testsuite/libffi.call/cls_5byte.c: Likewise. + * testsuite/libffi.call/cls_6byte.c: Likewise. + * testsuite/libffi.call/cls_7byte.c: Likewise. + * testsuite/libffi.call/cls_8byte.c: Likewise. + * testsuite/libffi.call/cls_double.c: Likewise. + * testsuite/libffi.call/cls_float.c: Likewise. + * testsuite/libffi.call/cls_uchar.c: Likewise. + * testsuite/libffi.call/cls_uint.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/cls_ushort.c: Likewise. + * testsuite/libffi.call/nested_struct.c: Likewise. + * testsuite/libffi.call/nested_struct1.c: Likewise. + * testsuite/libffi.call/problem1.c: Likewise. + * testsuite/libffi.special/unwindtest.cc: Likewise. + * testsuite/libffi.call/pyobjc-tc.c: Cleanup whitespaces. + +2003-09-18 David Edelsohn + + * src/powerpc/aix.S: Cleanup whitespaces. + * src/powerpc/aix_closure.S: Likewise. + +2003-09-18 Andreas Tobler + + * src/powerpc/darwin.S: Cleanup whitespaces, comment formatting. + * src/powerpc/darwin_closure.S: Likewise. + * src/powerpc/ffi_darwin.c: Likewise. + +2003-09-18 Andreas Tobler + David Edelsohn + + * src/types.c (double): Add AIX and Darwin to the right TYPEDEF. + * src/powerpc/aix_closure.S: Remove the pointer to the outgoing + parameter stack. + * src/powerpc/darwin_closure.S: Likewise. + * src/powerpc/ffi_darwin.c (ffi_prep_args): Handle structures + according to the Darwin/AIX ABI. + (ffi_prep_cif_machdep): Likewise. + (ffi_closure_helper_DARWIN): Likewise. + Remove the outgoing parameter stack logic. Simplify the evaluation + of the different CASE types. + (ffi_prep_clousure): Avoid the casts on lvalues. Change the branch + statement in the trampoline code. + +2003-09-18 Kaz Kojima + + * src/sh/ffi.c (ffi_prep_args): Take account into the alignement + for the register size. + (ffi_closure_helper_SYSV): Handle the structure return value + address correctly. + (ffi_closure_helper_SYSV): Return the appropriate type when + the registers are used for the structure return value. + * src/sh/sysv.S (ffi_closure_SYSV): Fix the stack layout for + the 64-bit return value. Update copyright years. + +2003-09-17 Rainer Orth + + * testsuite/lib/libffi-dg.exp (libffi_target_compile): Search in + srcdir for ffi_mips.h. + +2003-09-12 Alan Modra + + * src/prep_cif.c (initialize_aggregate): Include tail padding in + structure size. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Correct + placement of float result. + * testsuite/libffi.special/unwindtest.cc (closure_test_fn1): Correct + cast of "resp" for big-endian 64 bit machines. + +2003-09-11 Alan Modra + + * src/types.c (double, longdouble): Merge identical SH and ARM + typedefs, and add POWERPC64. + * src/powerpc/ffi.c (ffi_prep_args64): Correct next_arg calc for + struct split over gpr and rest. + (ffi_prep_cif_machdep): Correct intarg_count for structures. + * src/powerpc/linux64.S (ffi_call_LINUX64): Fix gpr offsets. + +2003-09-09 Andreas Tobler + + * src/powerpc/ffi.c (ffi_closure_helper_SYSV) Handle struct + passing correctly. + +2003-09-09 Alan Modra + + * configure: Regenerate. + +2003-09-04 Andreas Tobler + + * Makefile.am: Remove build rules for ffitest. + * Makefile.in: Rebuilt. + +2003-09-04 Andreas Tobler + + * src/java_raw_api.c: Include to fix compiler warning + about implicit declaration of abort(). + +2003-09-04 Andreas Tobler + + * Makefile.am: Add dejagnu test framework. Fixes PR other/11411. + * Makefile.in: Rebuilt. + * configure.in: Add dejagnu test framework. + * configure: Rebuilt. + + * testsuite/Makefile.am: New file. + * testsuite/Makefile.in: Built + * testsuite/lib/libffi-dg.exp: New file. + * testsuite/config/default.exp: Likewise. + * testsuite/libffi.call/call.exp: Likewise. + * testsuite/libffi.call/ffitest.h: Likewise. + * testsuite/libffi.call/closure_fn0.c: Likewise. + * testsuite/libffi.call/closure_fn1.c: Likewise. + * testsuite/libffi.call/closure_fn2.c: Likewise. + * testsuite/libffi.call/closure_fn3.c: Likewise. + * testsuite/libffi.call/cls_1_1byte.c: Likewise. + * testsuite/libffi.call/cls_3_1byte.c: Likewise. + * testsuite/libffi.call/cls_4_1byte.c: Likewise. + * testsuite/libffi.call/cls_2byte.c: Likewise. + * testsuite/libffi.call/cls_3byte1.c: Likewise. + * testsuite/libffi.call/cls_3byte2.c: Likewise. + * testsuite/libffi.call/cls_4byte.c: Likewise. + * testsuite/libffi.call/cls_5byte.c: Likewise. + * testsuite/libffi.call/cls_6byte.c: Likewise. + * testsuite/libffi.call/cls_7byte.c: Likewise. + * testsuite/libffi.call/cls_8byte.c: Likewise. + * testsuite/libffi.call/cls_12byte.c: Likewise. + * testsuite/libffi.call/cls_16byte.c: Likewise. + * testsuite/libffi.call/cls_20byte.c: Likewise. + * testsuite/libffi.call/cls_24byte.c: Likewise. + * testsuite/libffi.call/cls_double.c: Likewise. + * testsuite/libffi.call/cls_float.c: Likewise. + * testsuite/libffi.call/cls_uchar.c: Likewise. + * testsuite/libffi.call/cls_uint.c: Likewise. + * testsuite/libffi.call/cls_ulonglong.c: Likewise. + * testsuite/libffi.call/cls_ushort.c: Likewise. + * testsuite/libffi.call/float.c: Likewise. + * testsuite/libffi.call/float1.c: Likewise. + * testsuite/libffi.call/float2.c: Likewise. + * testsuite/libffi.call/many.c: Likewise. + * testsuite/libffi.call/many_win32.c: Likewise. + * testsuite/libffi.call/nested_struct.c: Likewise. + * testsuite/libffi.call/nested_struct1.c: Likewise. + * testsuite/libffi.call/pyobjc-tc.c: Likewise. + * testsuite/libffi.call/problem1.c: Likewise. + * testsuite/libffi.call/promotion.c: Likewise. + * testsuite/libffi.call/return_ll.c: Likewise. + * testsuite/libffi.call/return_sc.c: Likewise. + * testsuite/libffi.call/return_uc.c: Likewise. + * testsuite/libffi.call/strlen.c: Likewise. + * testsuite/libffi.call/strlen_win32.c: Likewise. + * testsuite/libffi.call/struct1.c: Likewise. + * testsuite/libffi.call/struct2.c: Likewise. + * testsuite/libffi.call/struct3.c: Likewise. + * testsuite/libffi.call/struct4.c: Likewise. + * testsuite/libffi.call/struct5.c: Likewise. + * testsuite/libffi.call/struct6.c: Likewise. + * testsuite/libffi.call/struct7.c: Likewise. + * testsuite/libffi.call/struct8.c: Likewise. + * testsuite/libffi.call/struct9.c: Likewise. + * testsuite/libffi.special/special.exp: New file. + * testsuite/libffi.special/ffitestcxx.h: Likewise. + * testsuite/libffi.special/unwindtest.cc: Likewise. + + +2003-08-13 Kaz Kojima + + * src/sh/ffi.c (OFS_INT16): Set 0 for little endian case. Update + copyright years. + +2003-08-02 Alan Modra + + * src/powerpc/ffi.c (ffi_prep_args64): Modify for changed gcc + structure passing. + (ffi_closure_helper_LINUX64): Likewise. + * src/powerpc/linux64.S: Remove code writing to parm save area. + * src/powerpc/linux64_closure.S (ffi_closure_LINUX64): Use return + address in lr from ffi_closure_helper_LINUX64 call to calculate + table address. Optimize function tail. + +2003-07-28 Andreas Tobler + + * src/sparc/ffi.c: Handle all floating point registers. + * src/sparc/v9.S: Likewise. Fixes second part of PR target/11410. + +2003-07-11 Gerald Pfeifer + + * README: Note that libffi is not part of GCC. Update the project + URL and status. + +2003-06-19 Franz Sirl + + * src/powerpc/ppc_closure.S: Include ffi.h. + +2003-06-13 Rainer Orth + + * src/x86/sysv.S: Avoid gas-only .uleb128/.sleb128 directives. + Use C style comments. + +2003-06-13 Kaz Kojima + + * Makefile.am: Add SHmedia support. Fix a typo of SH support. + * Makefile.in: Regenerate. + * configure.in (sh64-*-linux*, sh5*-*-linux*): Add target. + * configure: Regenerate. + * include/ffi.h.in: Add SHmedia support. + * src/sh64/ffi.c: New file. + * src/sh64/sysv.S: New file. + +2003-05-16 Jakub Jelinek + + * configure.in (HAVE_RO_EH_FRAME): Check whether .eh_frame section + should be read-only. + * configure: Rebuilt. + * fficonfig.h.in: Rebuilt. + * include/ffi.h.in (EH_FRAME_FLAGS): Define. + * src/alpha/osf.S: Use EH_FRAME_FLAGS. + * src/powerpc/linux64.S: Likewise. + * src/powerpc/linux64_closure.S: Likewise. Include ffi.h. + * src/powerpc/sysv.S: Use EH_FRAME_FLAGS. Use pcrel encoding + if -fpic/-fPIC/-mrelocatable. + * src/powerpc/powerpc_closure.S: Likewise. + * src/sparc/v8.S: If HAVE_RO_EH_FRAME is defined, don't include + #write in .eh_frame flags. + * src/sparc/v9.S: Likewise. + * src/x86/unix64.S: Use EH_FRAME_FLAGS. + * src/x86/sysv.S: Likewise. Use pcrel encoding if -fpic/-fPIC. + * src/s390/sysv.S: Use EH_FRAME_FLAGS. Include ffi.h. + +2003-05-07 Jeff Sturm + + Fixes PR bootstrap/10656 + * configure.in (HAVE_AS_REGISTER_PSEUDO_OP): Test assembler + support for .register pseudo-op. + * src/sparc/v8.S: Use it. + * fficonfig.h.in: Rebuilt. + * configure: Rebuilt. + +2003-04-18 Jakub Jelinek + + * include/ffi.h.in (POWERPC64): Define if 64-bit. + (enum ffi_abi): Add FFI_LINUX64 on POWERPC. + Make it the default on POWERPC64. + (FFI_TRAMPOLINE_SIZE): Define to 24 on POWERPC64. + * configure.in: Change powerpc-*-linux* into powerpc*-*-linux*. + * configure: Rebuilt. + * src/powerpc/ffi.c (hidden): Define. + (ffi_prep_args_SYSV): Renamed from + ffi_prep_args. Cast pointers to unsigned long to shut up warnings. + (NUM_GPR_ARG_REGISTERS64, NUM_FPR_ARG_REGISTERS64, + ASM_NEEDS_REGISTERS64): New. + (ffi_prep_args64): New function. + (ffi_prep_cif_machdep): Handle FFI_LINUX64 ABI. + (ffi_call): Likewise. + (ffi_prep_closure): Likewise. + (flush_icache): Surround by #ifndef POWERPC64. + (ffi_dblfl): New union type. + (ffi_closure_helper_SYSV): Use it to avoid aliasing problems. + (ffi_closure_helper_LINUX64): New function. + * src/powerpc/ppc_closure.S: Surround whole file by #ifndef + __powerpc64__. + * src/powerpc/sysv.S: Likewise. + (ffi_call_SYSV): Rename ffi_prep_args to ffi_prep_args_SYSV. + * src/powerpc/linux64.S: New file. + * src/powerpc/linux64_closure.S: New file. + * Makefile.am (EXTRA_DIST): Add src/powerpc/linux64.S and + src/powerpc/linux64_closure.S. + (TARGET_SRC_POWERPC): Likewise. + + * src/ffitest.c (closure_test_fn, closure_test_fn1, closure_test_fn2, + closure_test_fn3): Fix result printing on big-endian 64-bit + machines. + (main): Print tst2_arg instead of uninitialized tst2_result. + + * src/ffitest.c (main): Hide what closure pointer really points to + from the compiler. + +2003-04-16 Richard Earnshaw + + * configure.in (arm-*-netbsdelf*): Add configuration. + (configure): Regenerated. + +2003-04-04 Loren J. Rittle + + * include/Makefile.in: Regenerate. + +2003-03-21 Zdenek Dvorak + + * libffi/include/ffi.h.in: Define X86 instead of X86_64 in 32 + bit mode. + * libffi/src/x86/ffi.c (ffi_closure_SYSV, ffi_closure_raw_SYSV): + Receive closure pointer through parameter, read args using + __builtin_dwarf_cfa. + (FFI_INIT_TRAMPOLINE): Send closure reference through eax. + +2003-03-12 Andreas Schwab + + * configure.in: Avoid trailing /. in toolexeclibdir. + * configure: Rebuilt. + +2003-03-03 Andreas Tobler + + * src/powerpc/darwin_closure.S: Recode to fit dynamic libraries. + +2003-02-06 Andreas Tobler + + * libffi/src/powerpc/darwin_closure.S: + Fix alignement bug, allocate 8 bytes for the result. + * libffi/src/powerpc/aix_closure.S: + Likewise. + * libffi/src/powerpc/ffi_darwin.c: + Update stackframe description for aix/darwin_closure.S. + +2003-02-06 Jakub Jelinek + + * src/s390/ffi.c (ffi_closure_helper_SYSV): Add hidden visibility + attribute. + +2003-01-31 Christian Cornelssen , + Andreas Schwab + + * configure.in: Adjust command to source config-ml.in to account + for changes to the libffi_basedir definition. + (libffi_basedir): Remove ${srcdir} from value and include trailing + slash if nonempty. + + * configure: Regenerate. + +2003-01-29 Franz Sirl + + * src/powerpc/ppc_closure.S: Recode to fit shared libs. + +2003-01-28 Andrew Haley + + * include/ffi.h.in: Enable FFI_CLOSURES for x86_64. + * src/x86/ffi64.c (ffi_prep_closure): New. + (ffi_closure_UNIX64_inner): New. + * src/x86/unix64.S (ffi_closure_UNIX64): New. + +2003-01-27 Alexandre Oliva + + * configure.in (toolexecdir, toolexeclibdir): Set and AC_SUBST. + Remove USE_LIBDIR conditional. + * Makefile.am (toolexecdir, toolexeclibdir): Don't override. + * Makefile.in, configure: Rebuilt. + +2003-01027 David Edelsohn + + * Makefile.am (TARGET_SRC_POWERPC_AIX): Fix typo. + * Makefile.in: Regenerate. + +2003-01-22 Andrew Haley + + * src/powerpc/darwin.S (_ffi_call_AIX): Add Augmentation size to + unwind info. + +2003-01-21 Andreas Tobler + + * src/powerpc/darwin.S: Add unwind info. + * src/powerpc/darwin_closure.S: Likewise. + +2003-01-14 Andrew Haley + + * src/x86/ffi64.c (ffi_prep_args): Check for void retval. + (ffi_prep_cif_machdep): Likewise. + * src/x86/unix64.S: Add unwind info. + +2003-01-14 Andreas Jaeger + + * src/ffitest.c (main): Only use ffi_closures if those are + supported. + +2003-01-13 Andreas Tobler + + * libffi/src/ffitest.c + add closure testcases + +2003-01-13 Kevin B. Hendricks + + * libffi/src/powerpc/ffi.c + fix alignment bug for float (4 byte aligned iso 8 byte) + +2003-01-09 Geoffrey Keating + + * src/powerpc/ffi_darwin.c: Remove RCS version string. + * src/powerpc/darwin.S: Remove RCS version string. + +2003-01-03 Jeff Sturm + + * include/ffi.h.in: Add closure defines for SPARC, SPARC64. + * src/ffitest.c (main): Use static storage for closure. + * src/sparc/ffi.c (ffi_prep_closure, ffi_closure_sparc_inner): New. + * src/sparc/v8.S (ffi_closure_v8): New. + * src/sparc/v9.S (ffi_closure_v9): New. + +2002-11-10 Ranjit Mathew + + * include/ffi.h.in: Added FFI_STDCALL ffi_type + enumeration for X86_WIN32. + * src/x86/win32.S: Added ffi_call_STDCALL function + definition. + * src/x86/ffi.c (ffi_call/ffi_raw_call): Added + switch cases for recognising FFI_STDCALL and + calling ffi_call_STDCALL if target is X86_WIN32. + * src/ffitest.c (my_stdcall_strlen/stdcall_many): + stdcall versions of the "my_strlen" and "many" + test functions (for X86_WIN32). + Added test cases to test stdcall invocation using + these functions. + +2002-12-02 Kaz Kojima + + * src/sh/sysv.S: Add DWARF2 unwind info. + +2002-11-27 Ulrich Weigand + + * src/s390/sysv.S (.eh_frame section): Make section read-only. + +2002-11-26 Jim Wilson + + * src/types.c (FFI_TYPE_POINTER): Has size 8 on IA64. + +2002-11-23 H.J. Lu + + * acinclude.m4: Add dummy AM_PROG_LIBTOOL. + Include ../config/accross.m4. + * aclocal.m4; Rebuild. + * configure: Likewise. + +2002-11-15 Ulrich Weigand + + * src/s390/sysv.S (.eh_frame section): Adapt to pcrel FDE encoding. + +2002-11-11 DJ Delorie + + * configure.in: Look for common files in the right place. + +2002-10-08 Ulrich Weigand + + * src/java_raw_api.c (ffi_java_raw_to_ptrarray): Interpret + raw data as _Jv_word values, not ffi_raw. + (ffi_java_ptrarray_to_raw): Likewise. + (ffi_java_rvalue_to_raw): New function. + (ffi_java_raw_call): Call it. + (ffi_java_raw_to_rvalue): New function. + (ffi_java_translate_args): Call it. + * src/ffitest.c (closure_test_fn): Interpret return value + as ffi_arg, not int. + * src/s390/ffi.c (ffi_prep_cif_machdep): Add missing + FFI_TYPE_POINTER case. + (ffi_closure_helper_SYSV): Likewise. Also, assume return + values extended to word size. + +2002-10-02 Andreas Jaeger + + * src/x86/ffi64.c (ffi_prep_cif_machdep): Remove debug output. + +2002-10-01 Bo Thorsen + + * include/ffi.h.in: Fix i386 win32 compilation. + +2002-09-30 Ulrich Weigand + + * configure.in: Add s390x-*-linux-* target. + * configure: Regenerate. + * include/ffi.h.in: Define S390X for s390x targets. + (FFI_CLOSURES): Define for s390/s390x. + (FFI_TRAMPOLINE_SIZE): Likewise. + (FFI_NATIVE_RAW_API): Likewise. + * src/prep_cif.c (ffi_prep_cif): Do not compute stack space for s390. + * src/types.c (FFI_TYPE_POINTER): Use 8-byte pointers on s390x. + * src/s390/ffi.c: Major rework of existing code. Add support for + s390x targets. Add closure support. + * src/s390/sysv.S: Likewise. + +2002-09-29 Richard Earnshaw + + * src/arm/sysv.S: Fix typo. + +2002-09-28 Richard Earnshaw + + * src/arm/sysv.S: If we don't have machine/asm.h and the pre-processor + has defined __USER_LABEL_PREFIX__, then use it in CNAME. + (ffi_call_SYSV): Handle soft-float. + +2002-09-27 Bo Thorsen + + * include/ffi.h.in: Fix multilib x86-64 support. + +2002-09-22 Kaveh R. Ghazi + + * Makefile.am (all-multi): Fix multilib parallel build. + +2002-07-19 Kaz Kojima + + * configure.in (sh[34]*-*-linux*): Add brackets. + * configure: Regenerate. + +2002-07-18 Kaz Kojima + + * Makefile.am: Add SH support. + * Makefile.in: Regenerate. + * configure.in (sh-*-linux*, sh[34]*-*-linux*): Add target. + * configure: Regenerate. + * include/ffi.h.in: Add SH support. + * src/sh/ffi.c: New file. + * src/sh/sysv.S: New file. + * src/types.c: Add SH support. + +2002-07-16 Bo Thorsen + + * src/x86/ffi64.c: New file that adds x86-64 support. + * src/x86/unix64.S: New file that handles argument setup for + x86-64. + * src/x86/sysv.S: Don't use this on x86-64. + * src/x86/ffi.c: Don't use this on x86-64. + Remove unused vars. + * src/prep_cif.c (ffi_prep_cif): Don't do stack size calculation + for x86-64. + * src/ffitest.c (struct6): New test that tests a special case in + the x86-64 ABI. + (struct7): Likewise. + (struct8): Likewise. + (struct9): Likewise. + (closure_test_fn): Silence warning about this when it's not used. + (main): Add the new tests. + (main): Fix a couple of wrong casts and silence some compiler warnings. + * include/ffi.h.in: Add x86-64 ABI definition. + * fficonfig.h.in: Regenerate. + * Makefile.am: Add x86-64 support. + * configure.in: Likewise. + * Makefile.in: Regenerate. + * configure: Likewise. + +2002-06-24 Bo Thorsen + + * src/types.c: Merge settings for similar architectures. + Add x86-64 sizes and alignments. + +2002-06-23 Bo Thorsen + + * src/arm/ffi.c (ffi_prep_args): Remove unused vars. + * src/sparc/ffi.c (ffi_prep_args_v8): Likewise. + * src/mips/ffi.c (ffi_prep_args): Likewise. + * src/m68k/ffi.c (ffi_prep_args): Likewise. + +2002-07-18 H.J. Lu (hjl@gnu.org) + + * Makefile.am (TARGET_SRC_MIPS_LINUX): New. + (libffi_la_SOURCES): Support MIPS_LINUX. + (libffi_convenience_la_SOURCES): Likewise. + * Makefile.in: Regenerated. + + * configure.in (mips64*-*): Skip. + (mips*-*-linux*): New. + * configure: Regenerated. + + * src/mips/ffi.c: Include . + +2002-06-06 Ulrich Weigand + + * src/s390/sysv.S: Save/restore %r6. Add DWARF-2 unwind info. + +2002-05-27 Roger Sayle + + * src/x86/ffi.c (ffi_prep_args): Remove reference to avn. + +2002-05-27 Bo Thorsen + + * src/x86/ffi.c (ffi_prep_args): Remove unused variable and + fix formatting. + +2002-05-13 Andreas Tobler + + * src/powerpc/ffi_darwin.c (ffi_prep_closure): Declare fd at + beginning of function (for older apple cc). + +2002-05-08 Alexandre Oliva + + * configure.in (ORIGINAL_LD_FOR_MULTILIBS): Preserve LD at + script entry, and set LD to it when configuring multilibs. + * configure: Rebuilt. + +2002-05-05 Jason Thorpe + + * configure.in (sparc64-*-netbsd*): Add target. + (sparc-*-netbsdelf*): Likewise. + * configure: Regenerate. + +2002-04-28 David S. Miller + + * configure.in, configure: Fix SPARC test in previous change. + +2002-04-29 Gerhard Tonn + + * Makefile.am: Add Linux for S/390 support. + * Makefile.in: Regenerate. + * configure.in: Add Linux for S/390 support. + * configure: Regenerate. + * include/ffi.h.in: Add Linux for S/390 support. + * src/s390/ffi.c: New file from libffi CVS tree. + * src/s390/sysv.S: New file from libffi CVS tree. + +2002-04-28 Jakub Jelinek + + * configure.in (HAVE_AS_SPARC_UA_PCREL): Check for working + %r_disp32(). + * src/sparc/v8.S: Use it. + * src/sparc/v9.S: Likewise. + * fficonfig.h.in: Rebuilt. + * configure: Rebuilt. + +2002-04-08 Hans Boehm + + * src/java_raw_api.c (ffi_java_raw_size): Handle FFI_TYPE_DOUBLE + correctly. + * src/ia64/unix.S: Add unwind information. Fix comments. + Save sp in a way that's compatible with unwind info. + (ffi_call_unix): Correctly restore sp in all cases. + * src/ia64/ffi.c: Add, fix comments. + +2002-04-08 Jakub Jelinek + + * src/sparc/v8.S: Make .eh_frame dependent on target word size. + +2002-04-06 Jason Thorpe + + * configure.in (alpha*-*-netbsd*): Add target. + * configure: Regenerate. + +2002-04-04 Jeff Sturm + + * src/sparc/v8.S: Add unwind info. + * src/sparc/v9.S: Likewise. + +2002-03-30 Krister Walfridsson + + * configure.in: Enable i*86-*-netbsdelf*. + * configure: Rebuilt. + +2002-03-29 David Billinghurst + + PR other/2620 + * src/mips/n32.s: Delete + * src/mips/o32.s: Delete + +2002-03-21 Loren J. Rittle + + * configure.in: Enable alpha*-*-freebsd*. + * configure: Rebuilt. + +2002-03-17 Bryce McKinlay + + * Makefile.am: libfficonvenience -> libffi_convenience. + * Makefile.in: Rebuilt. + + * Makefile.am: Define ffitest_OBJECTS. + * Makefile.in: Rebuilt. + +2002-03-07 Andreas Tobler + David Edelsohn + + * Makefile.am (EXTRA_DIST): Add Darwin and AIX closure files. + (TARGET_SRC_POWERPC_AIX): Add aix_closure.S. + (TARGET_SRC_POWERPC_DARWIN): Add darwin_closure.S. + * Makefile.in: Regenerate. + * include/ffi.h.in: Add AIX and Darwin closure definitions. + * src/powerpc/ffi_darwin.c (ffi_prep_closure): New function. + (flush_icache, flush_range): New functions. + (ffi_closure_helper_DARWIN): New function. + * src/powerpc/aix_closure.S: New file. + * src/powerpc/darwin_closure.S: New file. + +2002-02-24 Jeff Sturm + + * include/ffi.h.in: Add typedef for ffi_arg. + * src/ffitest.c (main): Declare rint with ffi_arg. + +2002-02-21 Andreas Tobler + + * src/powerpc/ffi_darwin.c (ffi_prep_args): Skip appropriate + number of GPRs for floating-point arguments. + +2002-01-31 Anthony Green + + * configure: Rebuilt. + * configure.in: Replace CHECK_SIZEOF and endian tests with + cross-compiler friendly macros. + * aclocal.m4 (AC_COMPILE_CHECK_SIZEOF, AC_C_BIGENDIAN_CROSS): New + macros. + +2002-01-18 David Edelsohn + + * src/powerpc/darwin.S (_ffi_call_AIX): New. + * src/powerpc/aix.S (ffi_call_DARWIN): New. + +2002-01-17 David Edelsohn + + * Makefile.am (EXTRA_DIST): Add Darwin and AIX files. + (TARGET_SRC_POWERPC_AIX): New. + (POWERPC_AIX): New stanza. + * Makefile.in: Regenerate. + * configure.in: Add AIX case. + * configure: Regenerate. + * include/ffi.h.in (ffi_abi): Add FFI_AIX. + * src/powerpc/ffi_darwin.c (ffi_status): Use "long" to scale frame + size. Fix "long double" support. + (ffi_call): Add FFI_AIX case. + * src/powerpc/aix.S: New. + +2001-10-09 John Hornkvist + + Implement Darwin PowerPC ABI. + * configure.in: Handle powerpc-*-darwin*. + * Makefile.am: Set source files for POWERPC_DARWIN. + * configure: Rebuilt. + * Makefile.in: Rebuilt. + * include/ffi.h.in: Define FFI_DARWIN and FFI_DEFAULT_ABI for + POWERPC_DARWIN. + * src/powerpc/darwin.S: New file. + * src/powerpc/ffi_darwin.c: New file. + +2001-10-07 Joseph S. Myers + + * src/x86/ffi.c: Fix spelling error of "separate" as "seperate". + +2001-07-16 Rainer Orth + + * src/x86/sysv.S: Avoid gas-only .balign directive. + Use C style comments. + +2001-07-16 Rainer Orth + + * src/alpha/ffi.c (ffi_prep_closure): Avoid gas-only mnemonic. + Fixes PR bootstrap/3563. + +2001-06-26 Rainer Orth + + * src/alpha/osf.S (ffi_closure_osf): Use .rdata for ECOFF. + +2001-06-25 Rainer Orth + + * configure.in: Recognize sparc*-sun-* host. + * configure: Regenerate. + +2001-06-06 Andrew Haley + + * src/alpha/osf.S (__FRAME_BEGIN__): Conditionalize for ELF. + +2001-06-03 Andrew Haley + + * src/alpha/osf.S: Add unwind info. + * src/powerpc/sysv.S: Add unwind info. + * src/powerpc/ppc_closure.S: Likewise. + +2000-05-31 Jeff Sturm + + * configure.in: Fix AC_ARG_ENABLE usage. + * configure: Rebuilt. + +2001-05-06 Bryce McKinlay + + * configure.in: Remove warning about beta code. + * configure: Rebuilt. + +2001-04-25 Hans Boehm + + * src/ia64/unix.S: Restore stack pointer when returning from + ffi_closure_UNIX. + * src/ia64/ffi.c: Fix typo in comment. + +2001-04-18 Jim Wilson + + * src/ia64/unix.S: Delete unnecessary increment and decrement of loc2 + to eliminate RAW DV. + +2001-04-12 Bryce McKinlay + + * Makefile.am: Make a libtool convenience library. + * Makefile.in: Rebuilt. + +2001-03-29 Bryce McKinlay + + * configure.in: Use different syntax for subdirectory creation. + * configure: Rebuilt. + +2001-03-27 Jon Beniston + + * configure.in: Added X86_WIN32 target (Win32, CygWin, MingW). + * configure: Rebuilt. + * Makefile.am: Added X86_WIN32 target support. + * Makefile.in: Rebuilt. + + * include/ffi.h.in: Added X86_WIN32 target support. + + * src/ffitest.c: Doesn't run structure tests for X86_WIN32 targets. + * src/types.c: Added X86_WIN32 target support. + + * src/x86/win32.S: New file. Based on sysv.S, but with EH + stuff removed and made to work with CygWin's gas. + +2001-03-26 Bryce McKinlay + + * configure.in: Make target subdirectory in build dir. + * Makefile.am: Override suffix based rules to specify correct output + subdirectory. + * Makefile.in: Rebuilt. + * configure: Rebuilt. + +2001-03-23 Kevin B Hendricks + + * src/powerpc/ppc_closure.S: New file. + * src/powerpc/ffi.c (ffi_prep_args): Fixed ABI compatibility bug + involving long long and register pairs. + (ffi_prep_closure): New function. + (flush_icache): Likewise. + (ffi_closure_helper_SYSV): Likewise. + * include/ffi.h.in (FFI_CLOSURES): Define on PPC. + (FFI_TRAMPOLINE_SIZE): Likewise. + (FFI_NATIVE_RAW_API): Likewise. + * Makefile.in: Rebuilt. + * Makefile.am (EXTRA_DIST): Added src/powerpc/ppc_closure.S. + (TARGET_SRC_POWERPC): Likewise. + +2001-03-19 Tom Tromey + + * Makefile.in: Rebuilt. + * Makefile.am (ffitest_LDFLAGS): New macro. + +2001-03-02 Nick Clifton + + * include/ffi.h.in: Remove RCS ident string. + * include/ffi_mips.h: Remove RCS ident string. + * src/debug.c: Remove RCS ident string. + * src/ffitest.c: Remove RCS ident string. + * src/prep_cif.c: Remove RCS ident string. + * src/types.c: Remove RCS ident string. + * src/alpha/ffi.c: Remove RCS ident string. + * src/alpha/osf.S: Remove RCS ident string. + * src/arm/ffi.c: Remove RCS ident string. + * src/arm/sysv.S: Remove RCS ident string. + * src/mips/ffi.c: Remove RCS ident string. + * src/mips/n32.S: Remove RCS ident string. + * src/mips/o32.S: Remove RCS ident string. + * src/sparc/ffi.c: Remove RCS ident string. + * src/sparc/v8.S: Remove RCS ident string. + * src/sparc/v9.S: Remove RCS ident string. + * src/x86/ffi.c: Remove RCS ident string. + * src/x86/sysv.S: Remove RCS ident string. + +2001-02-08 Joseph S. Myers + + * include/ffi.h.in: Change sourceware.cygnus.com references to + gcc.gnu.org. + +2000-12-09 Richard Henderson + + * src/alpha/ffi.c (ffi_call): Simplify struct return test. + (ffi_closure_osf_inner): Index rather than increment avalue + and arg_types. Give ffi_closure_osf the raw return value type. + * src/alpha/osf.S (ffi_closure_osf): Handle return value type + promotion. + +2000-12-07 Richard Henderson + + * src/raw_api.c (ffi_translate_args): Fix typo. + (ffi_prep_closure): Likewise. + + * include/ffi.h.in [ALPHA]: Define FFI_CLOSURES and + FFI_TRAMPOLINE_SIZE. + * src/alpha/ffi.c (ffi_prep_cif_machdep): Adjust minimal + cif->bytes for new ffi_call_osf implementation. + (ffi_prep_args): Absorb into ... + (ffi_call): ... here. Do all stack allocation here and + avoid a callback function. + (ffi_prep_closure, ffi_closure_osf_inner): New. + * src/alpha/osf.S (ffi_call_osf): Reimplement with no callback. + (ffi_closure_osf): New. + +2000-09-10 Alexandre Oliva + + * config.guess, config.sub, install-sh: Removed. + * ltconfig, ltmain.sh, missing, mkinstalldirs: Likewise. + * Makefile.in: Rebuilt. + + * acinclude.m4: Include libtool macros from the top level. + * aclocal.m4, configure: Rebuilt. + +2000-08-22 Alexandre Oliva + + * configure.in [i*86-*-freebsd*] (TARGET, TARGETDIR): Set. + * configure: Rebuilt. + +2000-05-11 Scott Bambrough + + * libffi/src/arm/sysv.S (ffi_call_SYSV): Doubles are not saved to + memory correctly. Use conditional instructions, not branches where + possible. + +2000-05-04 Tom Tromey + + * configure: Rebuilt. + * configure.in: Match `arm*-*-linux-*'. + From Chris Dornan . + +2000-04-28 Jakub Jelinek + + * Makefile.am (SUBDIRS): Define. + (AM_MAKEFLAGS): Likewise. + (Multilib support.): Add section. + * Makefile.in: Rebuilt. + * ltconfig (extra_compiler_flags, extra_compiler_flags_value): + New variables. Set for gcc using -print-multi-lib. Export them + to libtool. + (sparc64-*-linux-gnu*): Use libsuff 64 for search paths. + * ltmain.sh (B|b|V): Don't throw away gcc's -B, -b and -V options + for -shared links. + (extra_compiler_flags_value, extra_compiler_flags): Check these + for extra compiler options which need to be passed down in + compiler_flags. + +2000-04-16 Anthony Green + + * configure: Rebuilt. + * configure.in: Change i*86-pc-linux* to i*86-*-linux*. + +2000-04-14 Jakub Jelinek + + * include/ffi.h.in (SPARC64): Define for 64bit SPARC builds. + Set SPARC FFI_DEFAULT_ABI based on SPARC64 define. + * src/sparc/ffi.c (ffi_prep_args_v8): Renamed from ffi_prep_args. + Replace all void * sizeofs with sizeof(int). + Only compare type with FFI_TYPE_LONGDOUBLE if LONGDOUBLE is + different than DOUBLE. + Remove FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases (handled elsewhere). + (ffi_prep_args_v9): New function. + (ffi_prep_cif_machdep): Handle V9 ABI and long long on V8. + (ffi_V9_return_struct): New function. + (ffi_call): Handle FFI_V9 ABI from 64bit code and FFI_V8 ABI from + 32bit code (not yet cross-arch calls). + * src/sparc/v8.S: Add struct return delay nop. + Handle long long. + * src/sparc/v9.S: New file. + * src/prep_cif.c (ffi_prep_cif): Return structure pointer + is used on sparc64 only for structures larger than 32 bytes. + Pass by reference for structures is done for structure arguments + larger than 16 bytes. + * src/ffitest.c (main): Use 64bit rint on sparc64. + Run long long tests on sparc. + * src/types.c (FFI_TYPE_POINTER): Pointer is 64bit on alpha and + sparc64. + (FFI_TYPE_LONGDOUBLE): long double is 128 bit aligned to 128 bits + on sparc64. + * configure.in (sparc-*-linux*): New supported target. + (sparc64-*-linux*): Likewise. + * configure: Rebuilt. + * Makefile.am: Add v9.S to SPARC files. + * Makefile.in: Likewise. + (LINK): Surround $(CCLD) into double quotes, so that multilib + compiles work correctly. + +2000-04-04 Alexandre Petit-Bianco + + * configure: Rebuilt. + * configure.in: (i*86-*-solaris*): New libffi target. Patch + proposed by Bryce McKinlay. + +2000-03-20 Tom Tromey + + * Makefile.in: Hand edit for java_raw_api.lo. + +2000-03-08 Bryce McKinlay + + * config.guess, config.sub: Update from the gcc tree. + Fix for PR libgcj/168. + +2000-03-03 Tom Tromey + + * Makefile.in: Fixed ia64 by hand. + + * configure: Rebuilt. + * configure.in (--enable-multilib): New option. + (libffi_basedir): New subst. + (AC_OUTPUT): Added multilib code. + +2000-03-02 Tom Tromey + + * Makefile.in: Rebuilt. + * Makefile.am (TARGET_SRC_IA64): Use `ia64', not `alpha', as + directory name. + +2000-02-25 Hans Boehm + + * src/ia64/ffi.c, src/ia64/ia64_flags.h, src/ia64/unix.S: New + files. + * src/raw_api.c (ffi_translate_args): Fixed typo in argument + list. + (ffi_prep_raw_closure): Use ffi_translate_args, not + ffi_closure_translate. + * src/java_raw_api.c: New file. + * src/ffitest.c (closure_test_fn): New function. + (main): Define `rint' as long long on IA64. Added new test when + FFI_CLOSURES is defined. + * include/ffi.h.in (ALIGN): Use size_t, not unsigned. + (ffi_abi): Recognize IA64. + (ffi_raw): Added `flt' field. + Added "Java raw API" code. + * configure.in: Recognize ia64. + * Makefile.am (TARGET_SRC_IA64): New macro. + (libffi_la_common_SOURCES): Added java_raw_api.c. + (libffi_la_SOURCES): Define in IA64 case. + +2000-01-04 Tom Tromey + + * Makefile.in: Rebuilt with newer automake. + +1999-12-31 Tom Tromey + + * Makefile.am (INCLUDES): Added -I$(top_srcdir)/src. + +1999-09-01 Tom Tromey + + * include/ffi.h.in: Removed PACKAGE and VERSION defines and + undefs. + * fficonfig.h.in: Rebuilt. + * configure: Rebuilt. + * configure.in: Pass 3rd argument to AM_INIT_AUTOMAKE. + Use AM_PROG_LIBTOOL (automake 1.4 compatibility). + * acconfig.h: Don't #undef PACKAGE or VERSION. + +1999-08-09 Anthony Green + + * include/ffi.h.in: Try to work around messy header problem + with PACKAGE and VERSION. + + * configure: Rebuilt. + * configure.in: Change version to 2.00-beta. + + * fficonfig.h.in: Rebuilt. + * acconfig.h (FFI_NO_STRUCTS, FFI_NO_RAW_API): Define. + + * src/x86/ffi.c (ffi_raw_call): Rename. + +1999-08-02 Kresten Krab Thorup + + * src/x86/ffi.c (ffi_closure_SYSV): New function. + (ffi_prep_incoming_args_SYSV): Ditto. + (ffi_prep_closure): Ditto. + (ffi_closure_raw_SYSV): Ditto. + (ffi_prep_raw_closure): More ditto. + (ffi_call_raw): Final ditto. + + * include/ffi.h.in: Add definitions for closure and raw API. + + * src/x86/ffi.c (ffi_prep_cif_machdep): Added case for + FFI_TYPE_UINT64. + + * Makefile.am (libffi_la_common_SOURCES): Added raw_api.c + + * src/raw_api.c: New file. + + * include/ffi.h.in (ffi_raw): New type. + (UINT_ARG, SINT_ARG): New defines. + (ffi_closure, ffi_raw_closure): New types. + (ffi_prep_closure, ffi_prep_raw_closure): New declarations. + + * configure.in: Add check for endianness and sizeof void*. + + * src/x86/sysv.S (ffi_call_SYSV): Call fixup routine via argument, + instead of directly. + + * configure: Rebuilt. + +Thu Jul 8 14:28:42 1999 Anthony Green + + * configure.in: Add x86 and powerpc BeOS configurations. + From Makoto Kato . + +1999-05-09 Anthony Green + + * configure.in: Add warning about this being beta code. + Remove src/Makefile.am from the picture. + * configure: Rebuilt. + + * Makefile.am: Move logic from src/Makefile.am. Add changes + to support libffi as a target library. + * Makefile.in: Rebuilt. + + * aclocal.m4, config.guess, config.sub, ltconfig, ltmain.sh: + Upgraded to new autoconf, automake, libtool. + + * README: Tweaks. + + * LICENSE: Update copyright date. + + * src/Makefile.am, src/Makefile.in: Removed. + +1998-11-29 Anthony Green + + * include/ChangeLog: Removed. + * src/ChangeLog: Removed. + * src/mips/ChangeLog: Removed. + * src/sparc/ChangeLog: Remboved. + * src/x86/ChangeLog: Removed. + + * ChangeLog.v1: Created. diff --git a/Modules/_ctypes/libffi/ChangeLog.v1 b/Modules/_ctypes/libffi/ChangeLog.v1 index 369820cbdb02..af3a37756868 100644 --- a/Modules/_ctypes/libffi/ChangeLog.v1 +++ b/Modules/_ctypes/libffi/ChangeLog.v1 @@ -2,7 +2,7 @@ The libffi version 1 ChangeLog archive. Version 1 of libffi had per-directory ChangeLogs. Current and future versions have a single ChangeLog file in the root directory. The -version 1 ChangeLogs have all been concatonated into this file for +version 1 ChangeLogs have all been concatenated into this file for future reference only. --- libffi ---------------------------------------------------------------- diff --git a/Modules/_ctypes/libffi/LICENSE b/Modules/_ctypes/libffi/LICENSE index aa60342dfcc1..a66fab4f25a0 100644 --- a/Modules/_ctypes/libffi/LICENSE +++ b/Modules/_ctypes/libffi/LICENSE @@ -1,4 +1,4 @@ -libffi - Copyright (c) 1996-2012 Anthony Green, Red Hat, Inc and others. +libffi - Copyright (c) 1996-2014 Anthony Green, Red Hat, Inc and others. See source files for details. Permission is hereby granted, free of charge, to any person obtaining diff --git a/Modules/_ctypes/libffi/Makefile.am b/Modules/_ctypes/libffi/Makefile.am index bf0156fc170a..1dcdc8110e69 100644 --- a/Modules/_ctypes/libffi/Makefile.am +++ b/Modules/_ctypes/libffi/Makefile.am @@ -6,10 +6,11 @@ ACLOCAL_AMFLAGS = -I m4 SUBDIRS = include testsuite man -EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \ +EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj \ src/aarch64/ffi.c src/aarch64/ffitarget.h src/aarch64/sysv.S \ - build-ios.sh src/alpha/ffi.c src/alpha/osf.S \ - src/alpha/ffitarget.h src/arm/ffi.c src/arm/sysv.S \ + src/alpha/ffi.c src/alpha/osf.S \ + src/alpha/ffitarget.h src/arc/ffi.c src/arc/arcompact.S \ + src/arc/ffitarget.h src/arm/ffi.c src/arm/sysv.S \ src/arm/ffitarget.h src/avr32/ffi.c src/avr32/sysv.S \ src/avr32/ffitarget.h src/cris/ffi.c src/cris/sysv.S \ src/cris/ffitarget.h src/ia64/ffi.c src/ia64/ffitarget.h \ @@ -19,8 +20,12 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \ src/moxie/ffitarget.h src/moxie/eabi.S src/mips/ffitarget.h \ src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h \ src/m68k/ffi.c src/m68k/sysv.S src/m68k/ffitarget.h \ + src/m88k/ffi.c src/m88k/obsd.S src/m88k/ffitarget.h \ src/microblaze/ffi.c src/microblaze/sysv.S \ - src/microblaze/ffitarget.h src/powerpc/ffi.c \ + src/microblaze/ffitarget.h \ + src/nios2/ffi.c src/nios2/ffitarget.h src/nios2/sysv.S \ + src/powerpc/ffi.c src/powerpc/ffi_powerpc.h \ + src/powerpc/ffi_sysv.c src/powerpc/ffi_linux64.c \ src/powerpc/sysv.S src/powerpc/linux64.S \ src/powerpc/linux64_closure.S src/powerpc/ppc_closure.S \ src/powerpc/asm.h src/powerpc/aix.S src/powerpc/darwin.S \ @@ -38,14 +43,14 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \ src/bfin/ffitarget.h src/bfin/sysv.S src/frv/eabi.S \ src/frv/ffitarget.h src/dlmalloc.c src/tile/ffi.c \ src/tile/ffitarget.h src/tile/tile.S libtool-version \ + src/vax/ffi.c src/vax/ffitarget.h src/vax/elfbsd.S \ src/xtensa/ffitarget.h src/xtensa/ffi.c src/xtensa/sysv.S \ ChangeLog.libffi m4/libtool.m4 m4/lt~obsolete.m4 \ m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 \ m4/ltversion.m4 src/arm/gentramp.sh src/debug.c msvcc.sh \ - generate-ios-source-and-headers.py \ - generate-osx-source-and-headers.py \ + generate-darwin-source-and-headers.py \ libffi.xcodeproj/project.pbxproj src/arm/trampoline.S \ - libtool-ldflags + libtool-ldflags ChangeLog.libffi-3.1 info_TEXINFOS = doc/libffi.texi @@ -59,39 +64,39 @@ info_TEXINFOS = doc/libffi.texi # values defined in terms of make variables, as is the case for CC and # friends when we are called from the top level Makefile. AM_MAKEFLAGS = \ - "AR_FLAGS=$(AR_FLAGS)" \ - "CC_FOR_BUILD=$(CC_FOR_BUILD)" \ - "CFLAGS=$(CFLAGS)" \ - "CXXFLAGS=$(CXXFLAGS)" \ - "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \ - "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \ - "INSTALL=$(INSTALL)" \ - "INSTALL_DATA=$(INSTALL_DATA)" \ - "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \ - "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \ - "JC1FLAGS=$(JC1FLAGS)" \ - "LDFLAGS=$(LDFLAGS)" \ - "LIBCFLAGS=$(LIBCFLAGS)" \ - "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \ - "MAKE=$(MAKE)" \ - "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \ - "PICFLAG=$(PICFLAG)" \ - "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \ - "RUNTESTFLAGS=$(RUNTESTFLAGS)" \ - "SHELL=$(SHELL)" \ - "exec_prefix=$(exec_prefix)" \ - "infodir=$(infodir)" \ - "libdir=$(libdir)" \ - "mandir=$(mandir)" \ - "prefix=$(prefix)" \ - "AR=$(AR)" \ - "AS=$(AS)" \ - "CC=$(CC)" \ - "CXX=$(CXX)" \ - "LD=$(LD)" \ - "NM=$(NM)" \ - "RANLIB=$(RANLIB)" \ - "DESTDIR=$(DESTDIR)" + 'AR_FLAGS=$(AR_FLAGS)' \ + 'CC_FOR_BUILD=$(CC_FOR_BUILD)' \ + 'CFLAGS=$(CFLAGS)' \ + 'CXXFLAGS=$(CXXFLAGS)' \ + 'CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)' \ + 'CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)' \ + 'INSTALL=$(INSTALL)' \ + 'INSTALL_DATA=$(INSTALL_DATA)' \ + 'INSTALL_PROGRAM=$(INSTALL_PROGRAM)' \ + 'INSTALL_SCRIPT=$(INSTALL_SCRIPT)' \ + 'JC1FLAGS=$(JC1FLAGS)' \ + 'LDFLAGS=$(LDFLAGS)' \ + 'LIBCFLAGS=$(LIBCFLAGS)' \ + 'LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)' \ + 'MAKE=$(MAKE)' \ + 'MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)' \ + 'PICFLAG=$(PICFLAG)' \ + 'PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)' \ + 'RUNTESTFLAGS=$(RUNTESTFLAGS)' \ + 'SHELL=$(SHELL)' \ + 'exec_prefix=$(exec_prefix)' \ + 'infodir=$(infodir)' \ + 'libdir=$(libdir)' \ + 'mandir=$(mandir)' \ + 'prefix=$(prefix)' \ + 'AR=$(AR)' \ + 'AS=$(AS)' \ + 'CC=$(CC)' \ + 'CXX=$(CXX)' \ + 'LD=$(LD)' \ + 'NM=$(NM)' \ + 'RANLIB=$(RANLIB)' \ + 'DESTDIR=$(DESTDIR)' # Subdir rules rely on $(FLAGS_TO_PASS) FLAGS_TO_PASS = $(AM_MAKEFLAGS) @@ -120,10 +125,10 @@ if BFIN nodist_libffi_la_SOURCES += src/bfin/ffi.c src/bfin/sysv.S endif if X86 -nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S +nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S src/x86/win32.S endif if X86_FREEBSD -nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/freebsd.S +nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/freebsd.S src/x86/win32.S endif if X86_WIN32 nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win32.S @@ -133,6 +138,9 @@ nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win64.S endif if X86_DARWIN nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S +if X86_DARWIN32 +nodist_libffi_la_SOURCES += src/x86/win32.S +endif endif if SPARC nodist_libffi_la_SOURCES += src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S @@ -149,14 +157,20 @@ endif if M68K nodist_libffi_la_SOURCES += src/m68k/ffi.c src/m68k/sysv.S endif +if M88K +nodist_libffi_la_SOURCES += src/m88k/ffi.c src/m88k/obsd.S +endif if MOXIE nodist_libffi_la_SOURCES += src/moxie/ffi.c src/moxie/eabi.S endif if MICROBLAZE nodist_libffi_la_SOURCES += src/microblaze/ffi.c src/microblaze/sysv.S endif +if NIOS2 +nodist_libffi_la_SOURCES += src/nios2/sysv.S src/nios2/ffi.c +endif if POWERPC -nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S +nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/ffi_sysv.c src/powerpc/ffi_linux64.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S endif if POWERPC_AIX nodist_libffi_la_SOURCES += src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S @@ -165,11 +179,14 @@ if POWERPC_DARWIN nodist_libffi_la_SOURCES += src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S endif if POWERPC_FREEBSD -nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S +nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/ffi_sysv.c src/powerpc/sysv.S src/powerpc/ppc_closure.S endif if AARCH64 nodist_libffi_la_SOURCES += src/aarch64/sysv.S src/aarch64/ffi.c endif +if ARC +nodist_libffi_la_SOURCES += src/arc/arcompact.S src/arc/ffi.c +endif if ARM nodist_libffi_la_SOURCES += src/arm/sysv.S src/arm/ffi.c if FFI_EXEC_TRAMPOLINE_TABLE @@ -212,14 +229,26 @@ endif if METAG nodist_libffi_la_SOURCES += src/metag/sysv.S src/metag/ffi.c endif +if VAX +nodist_libffi_la_SOURCES += src/vax/elfbsd.S src/vax/ffi.c +endif libffi_convenience_la_SOURCES = $(libffi_la_SOURCES) nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES) LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/libtool-ldflags $(LDFLAGS)) +AM_CFLAGS = +if FFI_DEBUG +# Build debug. Define FFI_DEBUG on the commandline so that, when building with +# MSVC, it can link against the debug CRT. +AM_CFLAGS += -DFFI_DEBUG +endif + libffi_la_LDFLAGS = -no-undefined -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS) AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src AM_CCASFLAGS = $(AM_CPPFLAGS) +dist-hook: + if [ -d $(top_srcdir)/.git ] ; then (cd $(top_srcdir); git log --no-decorate) ; else echo 'See git log for history.' ; fi > $(distdir)/ChangeLog diff --git a/Modules/_ctypes/libffi/Makefile.in b/Modules/_ctypes/libffi/Makefile.in index 4b6abe5d901c..4a57abd3c11d 100644 --- a/Modules/_ctypes/libffi/Makefile.in +++ b/Modules/_ctypes/libffi/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.12.2 from Makefile.am. +# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2012 Free Software Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -16,23 +16,51 @@ VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ - test $$am__dry = yes; \ - } + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -55,44 +83,52 @@ target_triplet = @target@ @FFI_DEBUG_TRUE@am__append_1 = src/debug.c @MIPS_TRUE@am__append_2 = src/mips/ffi.c src/mips/o32.S src/mips/n32.S @BFIN_TRUE@am__append_3 = src/bfin/ffi.c src/bfin/sysv.S -@X86_TRUE@am__append_4 = src/x86/ffi.c src/x86/sysv.S -@X86_FREEBSD_TRUE@am__append_5 = src/x86/ffi.c src/x86/freebsd.S +@X86_TRUE@am__append_4 = src/x86/ffi.c src/x86/sysv.S src/x86/win32.S +@X86_FREEBSD_TRUE@am__append_5 = src/x86/ffi.c src/x86/freebsd.S src/x86/win32.S @X86_WIN32_TRUE@am__append_6 = src/x86/ffi.c src/x86/win32.S @X86_WIN64_TRUE@am__append_7 = src/x86/ffi.c src/x86/win64.S @X86_DARWIN_TRUE@am__append_8 = src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S -@SPARC_TRUE@am__append_9 = src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S -@ALPHA_TRUE@am__append_10 = src/alpha/ffi.c src/alpha/osf.S -@IA64_TRUE@am__append_11 = src/ia64/ffi.c src/ia64/unix.S -@M32R_TRUE@am__append_12 = src/m32r/sysv.S src/m32r/ffi.c -@M68K_TRUE@am__append_13 = src/m68k/ffi.c src/m68k/sysv.S -@MOXIE_TRUE@am__append_14 = src/moxie/ffi.c src/moxie/eabi.S -@MICROBLAZE_TRUE@am__append_15 = src/microblaze/ffi.c src/microblaze/sysv.S -@POWERPC_TRUE@am__append_16 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S -@POWERPC_AIX_TRUE@am__append_17 = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S -@POWERPC_DARWIN_TRUE@am__append_18 = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S -@POWERPC_FREEBSD_TRUE@am__append_19 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S -@AARCH64_TRUE@am__append_20 = src/aarch64/sysv.S src/aarch64/ffi.c -@ARM_TRUE@am__append_21 = src/arm/sysv.S src/arm/ffi.c -@ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE@am__append_22 = src/arm/trampoline.S -@AVR32_TRUE@am__append_23 = src/avr32/sysv.S src/avr32/ffi.c -@LIBFFI_CRIS_TRUE@am__append_24 = src/cris/sysv.S src/cris/ffi.c -@FRV_TRUE@am__append_25 = src/frv/eabi.S src/frv/ffi.c -@S390_TRUE@am__append_26 = src/s390/sysv.S src/s390/ffi.c -@X86_64_TRUE@am__append_27 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S -@SH_TRUE@am__append_28 = src/sh/sysv.S src/sh/ffi.c -@SH64_TRUE@am__append_29 = src/sh64/sysv.S src/sh64/ffi.c -@PA_LINUX_TRUE@am__append_30 = src/pa/linux.S src/pa/ffi.c -@PA_HPUX_TRUE@am__append_31 = src/pa/hpux32.S src/pa/ffi.c -@TILE_TRUE@am__append_32 = src/tile/tile.S src/tile/ffi.c -@XTENSA_TRUE@am__append_33 = src/xtensa/sysv.S src/xtensa/ffi.c -@METAG_TRUE@am__append_34 = src/metag/sysv.S src/metag/ffi.c +@X86_DARWIN32_TRUE@@X86_DARWIN_TRUE@am__append_9 = src/x86/win32.S +@SPARC_TRUE@am__append_10 = src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S +@ALPHA_TRUE@am__append_11 = src/alpha/ffi.c src/alpha/osf.S +@IA64_TRUE@am__append_12 = src/ia64/ffi.c src/ia64/unix.S +@M32R_TRUE@am__append_13 = src/m32r/sysv.S src/m32r/ffi.c +@M68K_TRUE@am__append_14 = src/m68k/ffi.c src/m68k/sysv.S +@M88K_TRUE@am__append_15 = src/m88k/ffi.c src/m88k/obsd.S +@MOXIE_TRUE@am__append_16 = src/moxie/ffi.c src/moxie/eabi.S +@MICROBLAZE_TRUE@am__append_17 = src/microblaze/ffi.c src/microblaze/sysv.S +@NIOS2_TRUE@am__append_18 = src/nios2/sysv.S src/nios2/ffi.c +@POWERPC_TRUE@am__append_19 = src/powerpc/ffi.c src/powerpc/ffi_sysv.c src/powerpc/ffi_linux64.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S +@POWERPC_AIX_TRUE@am__append_20 = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S +@POWERPC_DARWIN_TRUE@am__append_21 = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S +@POWERPC_FREEBSD_TRUE@am__append_22 = src/powerpc/ffi.c src/powerpc/ffi_sysv.c src/powerpc/sysv.S src/powerpc/ppc_closure.S +@AARCH64_TRUE@am__append_23 = src/aarch64/sysv.S src/aarch64/ffi.c +@ARC_TRUE@am__append_24 = src/arc/arcompact.S src/arc/ffi.c +@ARM_TRUE@am__append_25 = src/arm/sysv.S src/arm/ffi.c +@ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE@am__append_26 = src/arm/trampoline.S +@AVR32_TRUE@am__append_27 = src/avr32/sysv.S src/avr32/ffi.c +@LIBFFI_CRIS_TRUE@am__append_28 = src/cris/sysv.S src/cris/ffi.c +@FRV_TRUE@am__append_29 = src/frv/eabi.S src/frv/ffi.c +@S390_TRUE@am__append_30 = src/s390/sysv.S src/s390/ffi.c +@X86_64_TRUE@am__append_31 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S +@SH_TRUE@am__append_32 = src/sh/sysv.S src/sh/ffi.c +@SH64_TRUE@am__append_33 = src/sh64/sysv.S src/sh64/ffi.c +@PA_LINUX_TRUE@am__append_34 = src/pa/linux.S src/pa/ffi.c +@PA_HPUX_TRUE@am__append_35 = src/pa/hpux32.S src/pa/ffi.c +@TILE_TRUE@am__append_36 = src/tile/tile.S src/tile/ffi.c +@XTENSA_TRUE@am__append_37 = src/xtensa/sysv.S src/xtensa/ffi.c +@METAG_TRUE@am__append_38 = src/metag/sysv.S src/metag/ffi.c +@VAX_TRUE@am__append_39 = src/vax/elfbsd.S src/vax/ffi.c +# Build debug. Define FFI_DEBUG on the commandline so that, when building with +# MSVC, it can link against the debug CRT. +@FFI_DEBUG_TRUE@am__append_40 = -DFFI_DEBUG subdir = . -DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in $(srcdir)/doc/stamp-vti \ - $(srcdir)/doc/version.texi $(srcdir)/fficonfig.h.in \ - $(srcdir)/libffi.pc.in $(top_srcdir)/configure ChangeLog \ - compile config.guess config.sub depcomp install-sh ltmain.sh \ - mdate-sh missing texinfo.tex +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/configure $(am__configure_deps) \ + $(srcdir)/fficonfig.h.in $(srcdir)/libffi.pc.in depcomp \ + mdate-sh $(srcdir)/doc/version.texi $(srcdir)/doc/stamp-vti \ + texinfo.tex README compile config.guess config.sub install-sh \ + missing ltmain.sh ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \ $(top_srcdir)/m4/ax_append_flag.m4 \ @@ -154,50 +190,60 @@ am_libffi_la_OBJECTS = src/prep_cif.lo src/types.lo src/raw_api.lo \ @MIPS_TRUE@am__objects_2 = src/mips/ffi.lo src/mips/o32.lo \ @MIPS_TRUE@ src/mips/n32.lo @BFIN_TRUE@am__objects_3 = src/bfin/ffi.lo src/bfin/sysv.lo -@X86_TRUE@am__objects_4 = src/x86/ffi.lo src/x86/sysv.lo -@X86_FREEBSD_TRUE@am__objects_5 = src/x86/ffi.lo src/x86/freebsd.lo +@X86_TRUE@am__objects_4 = src/x86/ffi.lo src/x86/sysv.lo \ +@X86_TRUE@ src/x86/win32.lo +@X86_FREEBSD_TRUE@am__objects_5 = src/x86/ffi.lo src/x86/freebsd.lo \ +@X86_FREEBSD_TRUE@ src/x86/win32.lo @X86_WIN32_TRUE@am__objects_6 = src/x86/ffi.lo src/x86/win32.lo @X86_WIN64_TRUE@am__objects_7 = src/x86/ffi.lo src/x86/win64.lo @X86_DARWIN_TRUE@am__objects_8 = src/x86/ffi.lo src/x86/darwin.lo \ @X86_DARWIN_TRUE@ src/x86/ffi64.lo src/x86/darwin64.lo -@SPARC_TRUE@am__objects_9 = src/sparc/ffi.lo src/sparc/v8.lo \ +@X86_DARWIN32_TRUE@@X86_DARWIN_TRUE@am__objects_9 = src/x86/win32.lo +@SPARC_TRUE@am__objects_10 = src/sparc/ffi.lo src/sparc/v8.lo \ @SPARC_TRUE@ src/sparc/v9.lo -@ALPHA_TRUE@am__objects_10 = src/alpha/ffi.lo src/alpha/osf.lo -@IA64_TRUE@am__objects_11 = src/ia64/ffi.lo src/ia64/unix.lo -@M32R_TRUE@am__objects_12 = src/m32r/sysv.lo src/m32r/ffi.lo -@M68K_TRUE@am__objects_13 = src/m68k/ffi.lo src/m68k/sysv.lo -@MOXIE_TRUE@am__objects_14 = src/moxie/ffi.lo src/moxie/eabi.lo -@MICROBLAZE_TRUE@am__objects_15 = src/microblaze/ffi.lo \ +@ALPHA_TRUE@am__objects_11 = src/alpha/ffi.lo src/alpha/osf.lo +@IA64_TRUE@am__objects_12 = src/ia64/ffi.lo src/ia64/unix.lo +@M32R_TRUE@am__objects_13 = src/m32r/sysv.lo src/m32r/ffi.lo +@M68K_TRUE@am__objects_14 = src/m68k/ffi.lo src/m68k/sysv.lo +@M88K_TRUE@am__objects_15 = src/m88k/ffi.lo src/m88k/obsd.lo +@MOXIE_TRUE@am__objects_16 = src/moxie/ffi.lo src/moxie/eabi.lo +@MICROBLAZE_TRUE@am__objects_17 = src/microblaze/ffi.lo \ @MICROBLAZE_TRUE@ src/microblaze/sysv.lo -@POWERPC_TRUE@am__objects_16 = src/powerpc/ffi.lo src/powerpc/sysv.lo \ +@NIOS2_TRUE@am__objects_18 = src/nios2/sysv.lo src/nios2/ffi.lo +@POWERPC_TRUE@am__objects_19 = src/powerpc/ffi.lo \ +@POWERPC_TRUE@ src/powerpc/ffi_sysv.lo \ +@POWERPC_TRUE@ src/powerpc/ffi_linux64.lo src/powerpc/sysv.lo \ @POWERPC_TRUE@ src/powerpc/ppc_closure.lo \ @POWERPC_TRUE@ src/powerpc/linux64.lo \ @POWERPC_TRUE@ src/powerpc/linux64_closure.lo -@POWERPC_AIX_TRUE@am__objects_17 = src/powerpc/ffi_darwin.lo \ +@POWERPC_AIX_TRUE@am__objects_20 = src/powerpc/ffi_darwin.lo \ @POWERPC_AIX_TRUE@ src/powerpc/aix.lo \ @POWERPC_AIX_TRUE@ src/powerpc/aix_closure.lo -@POWERPC_DARWIN_TRUE@am__objects_18 = src/powerpc/ffi_darwin.lo \ +@POWERPC_DARWIN_TRUE@am__objects_21 = src/powerpc/ffi_darwin.lo \ @POWERPC_DARWIN_TRUE@ src/powerpc/darwin.lo \ @POWERPC_DARWIN_TRUE@ src/powerpc/darwin_closure.lo -@POWERPC_FREEBSD_TRUE@am__objects_19 = src/powerpc/ffi.lo \ +@POWERPC_FREEBSD_TRUE@am__objects_22 = src/powerpc/ffi.lo \ +@POWERPC_FREEBSD_TRUE@ src/powerpc/ffi_sysv.lo \ @POWERPC_FREEBSD_TRUE@ src/powerpc/sysv.lo \ @POWERPC_FREEBSD_TRUE@ src/powerpc/ppc_closure.lo -@AARCH64_TRUE@am__objects_20 = src/aarch64/sysv.lo src/aarch64/ffi.lo -@ARM_TRUE@am__objects_21 = src/arm/sysv.lo src/arm/ffi.lo -@ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE@am__objects_22 = src/arm/trampoline.lo -@AVR32_TRUE@am__objects_23 = src/avr32/sysv.lo src/avr32/ffi.lo -@LIBFFI_CRIS_TRUE@am__objects_24 = src/cris/sysv.lo src/cris/ffi.lo -@FRV_TRUE@am__objects_25 = src/frv/eabi.lo src/frv/ffi.lo -@S390_TRUE@am__objects_26 = src/s390/sysv.lo src/s390/ffi.lo -@X86_64_TRUE@am__objects_27 = src/x86/ffi64.lo src/x86/unix64.lo \ +@AARCH64_TRUE@am__objects_23 = src/aarch64/sysv.lo src/aarch64/ffi.lo +@ARC_TRUE@am__objects_24 = src/arc/arcompact.lo src/arc/ffi.lo +@ARM_TRUE@am__objects_25 = src/arm/sysv.lo src/arm/ffi.lo +@ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE@am__objects_26 = src/arm/trampoline.lo +@AVR32_TRUE@am__objects_27 = src/avr32/sysv.lo src/avr32/ffi.lo +@LIBFFI_CRIS_TRUE@am__objects_28 = src/cris/sysv.lo src/cris/ffi.lo +@FRV_TRUE@am__objects_29 = src/frv/eabi.lo src/frv/ffi.lo +@S390_TRUE@am__objects_30 = src/s390/sysv.lo src/s390/ffi.lo +@X86_64_TRUE@am__objects_31 = src/x86/ffi64.lo src/x86/unix64.lo \ @X86_64_TRUE@ src/x86/ffi.lo src/x86/sysv.lo -@SH_TRUE@am__objects_28 = src/sh/sysv.lo src/sh/ffi.lo -@SH64_TRUE@am__objects_29 = src/sh64/sysv.lo src/sh64/ffi.lo -@PA_LINUX_TRUE@am__objects_30 = src/pa/linux.lo src/pa/ffi.lo -@PA_HPUX_TRUE@am__objects_31 = src/pa/hpux32.lo src/pa/ffi.lo -@TILE_TRUE@am__objects_32 = src/tile/tile.lo src/tile/ffi.lo -@XTENSA_TRUE@am__objects_33 = src/xtensa/sysv.lo src/xtensa/ffi.lo -@METAG_TRUE@am__objects_34 = src/metag/sysv.lo src/metag/ffi.lo +@SH_TRUE@am__objects_32 = src/sh/sysv.lo src/sh/ffi.lo +@SH64_TRUE@am__objects_33 = src/sh64/sysv.lo src/sh64/ffi.lo +@PA_LINUX_TRUE@am__objects_34 = src/pa/linux.lo src/pa/ffi.lo +@PA_HPUX_TRUE@am__objects_35 = src/pa/hpux32.lo src/pa/ffi.lo +@TILE_TRUE@am__objects_36 = src/tile/tile.lo src/tile/ffi.lo +@XTENSA_TRUE@am__objects_37 = src/xtensa/sysv.lo src/xtensa/ffi.lo +@METAG_TRUE@am__objects_38 = src/metag/sysv.lo src/metag/ffi.lo +@VAX_TRUE@am__objects_39 = src/vax/elfbsd.lo src/vax/ffi.lo nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \ $(am__objects_3) $(am__objects_4) $(am__objects_5) \ $(am__objects_6) $(am__objects_7) $(am__objects_8) \ @@ -209,17 +255,23 @@ nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \ $(am__objects_24) $(am__objects_25) $(am__objects_26) \ $(am__objects_27) $(am__objects_28) $(am__objects_29) \ $(am__objects_30) $(am__objects_31) $(am__objects_32) \ - $(am__objects_33) $(am__objects_34) + $(am__objects_33) $(am__objects_34) $(am__objects_35) \ + $(am__objects_36) $(am__objects_37) $(am__objects_38) \ + $(am__objects_39) libffi_la_OBJECTS = $(am_libffi_la_OBJECTS) \ $(nodist_libffi_la_OBJECTS) -libffi_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libffi_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libffi_la_LDFLAGS) $(LDFLAGS) -o $@ libffi_convenience_la_LIBADD = -am__objects_35 = src/prep_cif.lo src/types.lo src/raw_api.lo \ +am__objects_40 = src/prep_cif.lo src/types.lo src/raw_api.lo \ src/java_raw_api.lo src/closures.lo -am_libffi_convenience_la_OBJECTS = $(am__objects_35) -am__objects_36 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \ +am_libffi_convenience_la_OBJECTS = $(am__objects_40) +am__objects_41 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \ $(am__objects_4) $(am__objects_5) $(am__objects_6) \ $(am__objects_7) $(am__objects_8) $(am__objects_9) \ $(am__objects_10) $(am__objects_11) $(am__objects_12) \ @@ -230,32 +282,87 @@ am__objects_36 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \ $(am__objects_25) $(am__objects_26) $(am__objects_27) \ $(am__objects_28) $(am__objects_29) $(am__objects_30) \ $(am__objects_31) $(am__objects_32) $(am__objects_33) \ - $(am__objects_34) -nodist_libffi_convenience_la_OBJECTS = $(am__objects_36) + $(am__objects_34) $(am__objects_35) $(am__objects_36) \ + $(am__objects_37) $(am__objects_38) $(am__objects_39) +nodist_libffi_convenience_la_OBJECTS = $(am__objects_41) libffi_convenience_la_OBJECTS = $(am_libffi_convenience_la_OBJECTS) \ $(nodist_libffi_convenience_la_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -LTCPPASCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) +LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CCASFLAGS) $(CCASFLAGS) +AM_V_CPPAS = $(am__v_CPPAS_@AM_V@) +am__v_CPPAS_ = $(am__v_CPPAS_@AM_DEFAULT_V@) +am__v_CPPAS_0 = @echo " CPPAS " $@; +am__v_CPPAS_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = SOURCES = $(libffi_la_SOURCES) $(nodist_libffi_la_SOURCES) \ $(libffi_convenience_la_SOURCES) \ $(nodist_libffi_convenience_la_SOURCES) DIST_SOURCES = $(libffi_la_SOURCES) $(libffi_convenience_la_SOURCES) +AM_V_DVIPS = $(am__v_DVIPS_@AM_V@) +am__v_DVIPS_ = $(am__v_DVIPS_@AM_DEFAULT_V@) +am__v_DVIPS_0 = @echo " DVIPS " $@; +am__v_DVIPS_1 = +AM_V_MAKEINFO = $(am__v_MAKEINFO_@AM_V@) +am__v_MAKEINFO_ = $(am__v_MAKEINFO_@AM_DEFAULT_V@) +am__v_MAKEINFO_0 = @echo " MAKEINFO" $@; +am__v_MAKEINFO_1 = +AM_V_INFOHTML = $(am__v_INFOHTML_@AM_V@) +am__v_INFOHTML_ = $(am__v_INFOHTML_@AM_DEFAULT_V@) +am__v_INFOHTML_0 = @echo " INFOHTML" $@; +am__v_INFOHTML_1 = +AM_V_TEXI2DVI = $(am__v_TEXI2DVI_@AM_V@) +am__v_TEXI2DVI_ = $(am__v_TEXI2DVI_@AM_DEFAULT_V@) +am__v_TEXI2DVI_0 = @echo " TEXI2DVI" $@; +am__v_TEXI2DVI_1 = +AM_V_TEXI2PDF = $(am__v_TEXI2PDF_@AM_V@) +am__v_TEXI2PDF_ = $(am__v_TEXI2PDF_@AM_DEFAULT_V@) +am__v_TEXI2PDF_0 = @echo " TEXI2PDF" $@; +am__v_TEXI2PDF_1 = +AM_V_texinfo = $(am__v_texinfo_@AM_V@) +am__v_texinfo_ = $(am__v_texinfo_@AM_DEFAULT_V@) +am__v_texinfo_0 = -q +am__v_texinfo_1 = +AM_V_texidevnull = $(am__v_texidevnull_@AM_V@) +am__v_texidevnull_ = $(am__v_texidevnull_@AM_DEFAULT_V@) +am__v_texidevnull_0 = > /dev/null +am__v_texidevnull_1 = INFO_DEPS = $(srcdir)/doc/libffi.info am__TEXINFO_TEX_DIR = $(srcdir) DVIS = doc/libffi.dvi @@ -268,13 +375,14 @@ TEXI2PDF = $(TEXI2DVI) --pdf --batch MAKEINFOHTML = $(MAKEINFO) --html AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS) DVIPS = dvips -RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ - html-recursive info-recursive install-data-recursive \ - install-dvi-recursive install-exec-recursive \ - install-html-recursive install-info-recursive \ - install-pdf-recursive install-ps-recursive install-recursive \ - installcheck-recursive installdirs-recursive pdf-recursive \ - ps-recursive uninstall-recursive +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -283,9 +391,30 @@ am__can_run_installinfo = \ DATA = $(pkgconfig_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive -AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ - $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)fficonfig.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope @@ -335,6 +464,7 @@ distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LTLDFLAGS = @AM_LTLDFLAGS@ AM_RUNTESTFLAGS = @AM_RUNTESTFLAGS@ AR = @AR@ @@ -350,6 +480,10 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ @@ -365,6 +499,7 @@ FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@ +HAVE_LONG_DOUBLE_VARIANT = @HAVE_LONG_DOUBLE_VARIANT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -411,6 +546,7 @@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ @@ -468,10 +604,11 @@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign subdir-objects ACLOCAL_AMFLAGS = -I m4 SUBDIRS = include testsuite man -EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \ +EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj \ src/aarch64/ffi.c src/aarch64/ffitarget.h src/aarch64/sysv.S \ - build-ios.sh src/alpha/ffi.c src/alpha/osf.S \ - src/alpha/ffitarget.h src/arm/ffi.c src/arm/sysv.S \ + src/alpha/ffi.c src/alpha/osf.S \ + src/alpha/ffitarget.h src/arc/ffi.c src/arc/arcompact.S \ + src/arc/ffitarget.h src/arm/ffi.c src/arm/sysv.S \ src/arm/ffitarget.h src/avr32/ffi.c src/avr32/sysv.S \ src/avr32/ffitarget.h src/cris/ffi.c src/cris/sysv.S \ src/cris/ffitarget.h src/ia64/ffi.c src/ia64/ffitarget.h \ @@ -481,8 +618,12 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \ src/moxie/ffitarget.h src/moxie/eabi.S src/mips/ffitarget.h \ src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h \ src/m68k/ffi.c src/m68k/sysv.S src/m68k/ffitarget.h \ + src/m88k/ffi.c src/m88k/obsd.S src/m88k/ffitarget.h \ src/microblaze/ffi.c src/microblaze/sysv.S \ - src/microblaze/ffitarget.h src/powerpc/ffi.c \ + src/microblaze/ffitarget.h \ + src/nios2/ffi.c src/nios2/ffitarget.h src/nios2/sysv.S \ + src/powerpc/ffi.c src/powerpc/ffi_powerpc.h \ + src/powerpc/ffi_sysv.c src/powerpc/ffi_linux64.c \ src/powerpc/sysv.S src/powerpc/linux64.S \ src/powerpc/linux64_closure.S src/powerpc/ppc_closure.S \ src/powerpc/asm.h src/powerpc/aix.S src/powerpc/darwin.S \ @@ -500,14 +641,14 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \ src/bfin/ffitarget.h src/bfin/sysv.S src/frv/eabi.S \ src/frv/ffitarget.h src/dlmalloc.c src/tile/ffi.c \ src/tile/ffitarget.h src/tile/tile.S libtool-version \ + src/vax/ffi.c src/vax/ffitarget.h src/vax/elfbsd.S \ src/xtensa/ffitarget.h src/xtensa/ffi.c src/xtensa/sysv.S \ ChangeLog.libffi m4/libtool.m4 m4/lt~obsolete.m4 \ m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 \ m4/ltversion.m4 src/arm/gentramp.sh src/debug.c msvcc.sh \ - generate-ios-source-and-headers.py \ - generate-osx-source-and-headers.py \ + generate-darwin-source-and-headers.py \ libffi.xcodeproj/project.pbxproj src/arm/trampoline.S \ - libtool-ldflags + libtool-ldflags ChangeLog.libffi-3.1 info_TEXINFOS = doc/libffi.texi @@ -515,39 +656,39 @@ info_TEXINFOS = doc/libffi.texi # values defined in terms of make variables, as is the case for CC and # friends when we are called from the top level Makefile. AM_MAKEFLAGS = \ - "AR_FLAGS=$(AR_FLAGS)" \ - "CC_FOR_BUILD=$(CC_FOR_BUILD)" \ - "CFLAGS=$(CFLAGS)" \ - "CXXFLAGS=$(CXXFLAGS)" \ - "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \ - "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \ - "INSTALL=$(INSTALL)" \ - "INSTALL_DATA=$(INSTALL_DATA)" \ - "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \ - "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \ - "JC1FLAGS=$(JC1FLAGS)" \ - "LDFLAGS=$(LDFLAGS)" \ - "LIBCFLAGS=$(LIBCFLAGS)" \ - "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \ - "MAKE=$(MAKE)" \ - "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \ - "PICFLAG=$(PICFLAG)" \ - "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \ - "RUNTESTFLAGS=$(RUNTESTFLAGS)" \ - "SHELL=$(SHELL)" \ - "exec_prefix=$(exec_prefix)" \ - "infodir=$(infodir)" \ - "libdir=$(libdir)" \ - "mandir=$(mandir)" \ - "prefix=$(prefix)" \ - "AR=$(AR)" \ - "AS=$(AS)" \ - "CC=$(CC)" \ - "CXX=$(CXX)" \ - "LD=$(LD)" \ - "NM=$(NM)" \ - "RANLIB=$(RANLIB)" \ - "DESTDIR=$(DESTDIR)" + 'AR_FLAGS=$(AR_FLAGS)' \ + 'CC_FOR_BUILD=$(CC_FOR_BUILD)' \ + 'CFLAGS=$(CFLAGS)' \ + 'CXXFLAGS=$(CXXFLAGS)' \ + 'CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)' \ + 'CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)' \ + 'INSTALL=$(INSTALL)' \ + 'INSTALL_DATA=$(INSTALL_DATA)' \ + 'INSTALL_PROGRAM=$(INSTALL_PROGRAM)' \ + 'INSTALL_SCRIPT=$(INSTALL_SCRIPT)' \ + 'JC1FLAGS=$(JC1FLAGS)' \ + 'LDFLAGS=$(LDFLAGS)' \ + 'LIBCFLAGS=$(LIBCFLAGS)' \ + 'LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)' \ + 'MAKE=$(MAKE)' \ + 'MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)' \ + 'PICFLAG=$(PICFLAG)' \ + 'PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)' \ + 'RUNTESTFLAGS=$(RUNTESTFLAGS)' \ + 'SHELL=$(SHELL)' \ + 'exec_prefix=$(exec_prefix)' \ + 'infodir=$(infodir)' \ + 'libdir=$(libdir)' \ + 'mandir=$(mandir)' \ + 'prefix=$(prefix)' \ + 'AR=$(AR)' \ + 'AS=$(AS)' \ + 'CC=$(CC)' \ + 'CXX=$(CXX)' \ + 'LD=$(LD)' \ + 'NM=$(NM)' \ + 'RANLIB=$(RANLIB)' \ + 'DESTDIR=$(DESTDIR)' # Subdir rules rely on $(FLAGS_TO_PASS) @@ -571,10 +712,13 @@ nodist_libffi_la_SOURCES = $(am__append_1) $(am__append_2) \ $(am__append_24) $(am__append_25) $(am__append_26) \ $(am__append_27) $(am__append_28) $(am__append_29) \ $(am__append_30) $(am__append_31) $(am__append_32) \ - $(am__append_33) $(am__append_34) + $(am__append_33) $(am__append_34) $(am__append_35) \ + $(am__append_36) $(am__append_37) $(am__append_38) \ + $(am__append_39) libffi_convenience_la_SOURCES = $(libffi_la_SOURCES) nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES) LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/libtool-ldflags $(LDFLAGS)) +AM_CFLAGS = $(am__append_40) libffi_la_LDFLAGS = -no-undefined -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS) AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src AM_CCASFLAGS = $(AM_CPPFLAGS) @@ -645,6 +789,7 @@ clean-noinstLTLIBRARIES: echo rm -f $${locs}; \ rm -f $${locs}; \ } + install-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \ @@ -723,10 +868,10 @@ src/x86/ffi.lo: src/x86/$(am__dirstamp) \ src/x86/$(DEPDIR)/$(am__dirstamp) src/x86/sysv.lo: src/x86/$(am__dirstamp) \ src/x86/$(DEPDIR)/$(am__dirstamp) -src/x86/freebsd.lo: src/x86/$(am__dirstamp) \ - src/x86/$(DEPDIR)/$(am__dirstamp) src/x86/win32.lo: src/x86/$(am__dirstamp) \ src/x86/$(DEPDIR)/$(am__dirstamp) +src/x86/freebsd.lo: src/x86/$(am__dirstamp) \ + src/x86/$(DEPDIR)/$(am__dirstamp) src/x86/win64.lo: src/x86/$(am__dirstamp) \ src/x86/$(DEPDIR)/$(am__dirstamp) src/x86/darwin.lo: src/x86/$(am__dirstamp) \ @@ -787,6 +932,16 @@ src/m68k/ffi.lo: src/m68k/$(am__dirstamp) \ src/m68k/$(DEPDIR)/$(am__dirstamp) src/m68k/sysv.lo: src/m68k/$(am__dirstamp) \ src/m68k/$(DEPDIR)/$(am__dirstamp) +src/m88k/$(am__dirstamp): + @$(MKDIR_P) src/m88k + @: > src/m88k/$(am__dirstamp) +src/m88k/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/m88k/$(DEPDIR) + @: > src/m88k/$(DEPDIR)/$(am__dirstamp) +src/m88k/ffi.lo: src/m88k/$(am__dirstamp) \ + src/m88k/$(DEPDIR)/$(am__dirstamp) +src/m88k/obsd.lo: src/m88k/$(am__dirstamp) \ + src/m88k/$(DEPDIR)/$(am__dirstamp) src/moxie/$(am__dirstamp): @$(MKDIR_P) src/moxie @: > src/moxie/$(am__dirstamp) @@ -807,6 +962,16 @@ src/microblaze/ffi.lo: src/microblaze/$(am__dirstamp) \ src/microblaze/$(DEPDIR)/$(am__dirstamp) src/microblaze/sysv.lo: src/microblaze/$(am__dirstamp) \ src/microblaze/$(DEPDIR)/$(am__dirstamp) +src/nios2/$(am__dirstamp): + @$(MKDIR_P) src/nios2 + @: > src/nios2/$(am__dirstamp) +src/nios2/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/nios2/$(DEPDIR) + @: > src/nios2/$(DEPDIR)/$(am__dirstamp) +src/nios2/sysv.lo: src/nios2/$(am__dirstamp) \ + src/nios2/$(DEPDIR)/$(am__dirstamp) +src/nios2/ffi.lo: src/nios2/$(am__dirstamp) \ + src/nios2/$(DEPDIR)/$(am__dirstamp) src/powerpc/$(am__dirstamp): @$(MKDIR_P) src/powerpc @: > src/powerpc/$(am__dirstamp) @@ -815,6 +980,10 @@ src/powerpc/$(DEPDIR)/$(am__dirstamp): @: > src/powerpc/$(DEPDIR)/$(am__dirstamp) src/powerpc/ffi.lo: src/powerpc/$(am__dirstamp) \ src/powerpc/$(DEPDIR)/$(am__dirstamp) +src/powerpc/ffi_sysv.lo: src/powerpc/$(am__dirstamp) \ + src/powerpc/$(DEPDIR)/$(am__dirstamp) +src/powerpc/ffi_linux64.lo: src/powerpc/$(am__dirstamp) \ + src/powerpc/$(DEPDIR)/$(am__dirstamp) src/powerpc/sysv.lo: src/powerpc/$(am__dirstamp) \ src/powerpc/$(DEPDIR)/$(am__dirstamp) src/powerpc/ppc_closure.lo: src/powerpc/$(am__dirstamp) \ @@ -843,6 +1012,16 @@ src/aarch64/sysv.lo: src/aarch64/$(am__dirstamp) \ src/aarch64/$(DEPDIR)/$(am__dirstamp) src/aarch64/ffi.lo: src/aarch64/$(am__dirstamp) \ src/aarch64/$(DEPDIR)/$(am__dirstamp) +src/arc/$(am__dirstamp): + @$(MKDIR_P) src/arc + @: > src/arc/$(am__dirstamp) +src/arc/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/arc/$(DEPDIR) + @: > src/arc/$(DEPDIR)/$(am__dirstamp) +src/arc/arcompact.lo: src/arc/$(am__dirstamp) \ + src/arc/$(DEPDIR)/$(am__dirstamp) +src/arc/ffi.lo: src/arc/$(am__dirstamp) \ + src/arc/$(DEPDIR)/$(am__dirstamp) src/arm/$(am__dirstamp): @$(MKDIR_P) src/arm @: > src/arm/$(am__dirstamp) @@ -957,10 +1136,22 @@ src/metag/sysv.lo: src/metag/$(am__dirstamp) \ src/metag/$(DEPDIR)/$(am__dirstamp) src/metag/ffi.lo: src/metag/$(am__dirstamp) \ src/metag/$(DEPDIR)/$(am__dirstamp) +src/vax/$(am__dirstamp): + @$(MKDIR_P) src/vax + @: > src/vax/$(am__dirstamp) +src/vax/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/vax/$(DEPDIR) + @: > src/vax/$(DEPDIR)/$(am__dirstamp) +src/vax/elfbsd.lo: src/vax/$(am__dirstamp) \ + src/vax/$(DEPDIR)/$(am__dirstamp) +src/vax/ffi.lo: src/vax/$(am__dirstamp) \ + src/vax/$(DEPDIR)/$(am__dirstamp) + libffi.la: $(libffi_la_OBJECTS) $(libffi_la_DEPENDENCIES) $(EXTRA_libffi_la_DEPENDENCIES) - $(libffi_la_LINK) -rpath $(toolexeclibdir) $(libffi_la_OBJECTS) $(libffi_la_LIBADD) $(LIBS) + $(AM_V_CCLD)$(libffi_la_LINK) -rpath $(toolexeclibdir) $(libffi_la_OBJECTS) $(libffi_la_LIBADD) $(LIBS) + libffi_convenience.la: $(libffi_convenience_la_OBJECTS) $(libffi_convenience_la_DEPENDENCIES) $(EXTRA_libffi_convenience_la_DEPENDENCIES) - $(LINK) $(libffi_convenience_la_OBJECTS) $(libffi_convenience_la_LIBADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(libffi_convenience_la_OBJECTS) $(libffi_convenience_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -970,6 +1161,8 @@ mostlyclean-compile: -rm -f src/aarch64/*.lo -rm -f src/alpha/*.$(OBJEXT) -rm -f src/alpha/*.lo + -rm -f src/arc/*.$(OBJEXT) + -rm -f src/arc/*.lo -rm -f src/arm/*.$(OBJEXT) -rm -f src/arm/*.lo -rm -f src/avr32/*.$(OBJEXT) @@ -986,6 +1179,8 @@ mostlyclean-compile: -rm -f src/m32r/*.lo -rm -f src/m68k/*.$(OBJEXT) -rm -f src/m68k/*.lo + -rm -f src/m88k/*.$(OBJEXT) + -rm -f src/m88k/*.lo -rm -f src/metag/*.$(OBJEXT) -rm -f src/metag/*.lo -rm -f src/microblaze/*.$(OBJEXT) @@ -994,6 +1189,8 @@ mostlyclean-compile: -rm -f src/mips/*.lo -rm -f src/moxie/*.$(OBJEXT) -rm -f src/moxie/*.lo + -rm -f src/nios2/*.$(OBJEXT) + -rm -f src/nios2/*.lo -rm -f src/pa/*.$(OBJEXT) -rm -f src/pa/*.lo -rm -f src/powerpc/*.$(OBJEXT) @@ -1008,6 +1205,8 @@ mostlyclean-compile: -rm -f src/sparc/*.lo -rm -f src/tile/*.$(OBJEXT) -rm -f src/tile/*.lo + -rm -f src/vax/*.$(OBJEXT) + -rm -f src/vax/*.lo -rm -f src/x86/*.$(OBJEXT) -rm -f src/x86/*.lo -rm -f src/xtensa/*.$(OBJEXT) @@ -1026,6 +1225,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/aarch64/$(DEPDIR)/sysv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/alpha/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/alpha/$(DEPDIR)/osf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/arc/$(DEPDIR)/arcompact.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/arc/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/arm/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/arm/$(DEPDIR)/sysv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/arm/$(DEPDIR)/trampoline.Plo@am__quote@ @@ -1043,6 +1244,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/m32r/$(DEPDIR)/sysv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/m68k/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/m68k/$(DEPDIR)/sysv.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/m88k/$(DEPDIR)/ffi.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/m88k/$(DEPDIR)/obsd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/metag/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/metag/$(DEPDIR)/sysv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/microblaze/$(DEPDIR)/ffi.Plo@am__quote@ @@ -1052,6 +1255,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/mips/$(DEPDIR)/o32.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/moxie/$(DEPDIR)/eabi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/moxie/$(DEPDIR)/ffi.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/nios2/$(DEPDIR)/ffi.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/nios2/$(DEPDIR)/sysv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/hpux32.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/linux.Plo@am__quote@ @@ -1061,6 +1266,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/darwin_closure.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/ffi_darwin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/ffi_linux64.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/ffi_sysv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/linux64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/linux64_closure.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/ppc_closure.Plo@am__quote@ @@ -1076,6 +1283,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/sparc/$(DEPDIR)/v9.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tile/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tile/$(DEPDIR)/tile.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/vax/$(DEPDIR)/elfbsd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/vax/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/darwin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/darwin64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/ffi.Plo@am__quote@ @@ -1089,52 +1298,52 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/xtensa/$(DEPDIR)/sysv.Plo@am__quote@ .S.o: -@am__fastdepCCAS_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCCAS_TRUE@ $(CPPASCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCCAS_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCCAS_FALSE@ $(CPPASCOMPILE) -c -o $@ $< +@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ $< .S.obj: -@am__fastdepCCAS_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCCAS_TRUE@ $(CPPASCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCCAS_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCCAS_FALSE@ $(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .S.lo: -@am__fastdepCCAS_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCCAS_TRUE@ $(LTCPPASCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCCAS_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCCAS_FALSE@ $(LTCPPASCOMPILE) -c -o $@ $< +@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(LTCPPASCOMPILE) -c -o $@ $< .c.o: -@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo @@ -1144,6 +1353,7 @@ clean-libtool: -rm -rf src/.libs src/_libs -rm -rf src/aarch64/.libs src/aarch64/_libs -rm -rf src/alpha/.libs src/alpha/_libs + -rm -rf src/arc/.libs src/arc/_libs -rm -rf src/arm/.libs src/arm/_libs -rm -rf src/avr32/.libs src/avr32/_libs -rm -rf src/bfin/.libs src/bfin/_libs @@ -1152,10 +1362,12 @@ clean-libtool: -rm -rf src/ia64/.libs src/ia64/_libs -rm -rf src/m32r/.libs src/m32r/_libs -rm -rf src/m68k/.libs src/m68k/_libs + -rm -rf src/m88k/.libs src/m88k/_libs -rm -rf src/metag/.libs src/metag/_libs -rm -rf src/microblaze/.libs src/microblaze/_libs -rm -rf src/mips/.libs src/mips/_libs -rm -rf src/moxie/.libs src/moxie/_libs + -rm -rf src/nios2/.libs src/nios2/_libs -rm -rf src/pa/.libs src/pa/_libs -rm -rf src/powerpc/.libs src/powerpc/_libs -rm -rf src/s390/.libs src/s390/_libs @@ -1163,6 +1375,7 @@ clean-libtool: -rm -rf src/sh64/.libs src/sh64/_libs -rm -rf src/sparc/.libs src/sparc/_libs -rm -rf src/tile/.libs src/tile/_libs + -rm -rf src/vax/.libs src/vax/_libs -rm -rf src/x86/.libs src/x86/_libs -rm -rf src/xtensa/.libs src/xtensa/_libs @@ -1173,7 +1386,7 @@ doc/$(am__dirstamp): @: > doc/$(am__dirstamp) $(srcdir)/doc/libffi.info: doc/libffi.texi $(srcdir)/doc/version.texi - restore=: && backupdir="$(am__leading_dot)am$$$$" && \ + $(AM_V_MAKEINFO)restore=: && backupdir="$(am__leading_dot)am$$$$" && \ am__cwd=`pwd` && $(am__cd) $(srcdir) && \ rm -rf $$backupdir && mkdir $$backupdir && \ if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ @@ -1195,18 +1408,20 @@ $(srcdir)/doc/libffi.info: doc/libffi.texi $(srcdir)/doc/version.texi rm -rf $$backupdir; exit $$rc doc/libffi.dvi: doc/libffi.texi $(srcdir)/doc/version.texi doc/$(am__dirstamp) - TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + $(AM_V_TEXI2DVI)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I doc -I $(srcdir)/doc' \ - $(TEXI2DVI) --clean -o $@ `test -f 'doc/libffi.texi' || echo '$(srcdir)/'`doc/libffi.texi + $(TEXI2DVI) $(AM_V_texinfo) --build-dir=$(@:.dvi=.t2d) -o $@ $(AM_V_texidevnull) \ + `test -f 'doc/libffi.texi' || echo '$(srcdir)/'`doc/libffi.texi doc/libffi.pdf: doc/libffi.texi $(srcdir)/doc/version.texi doc/$(am__dirstamp) - TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + $(AM_V_TEXI2PDF)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I doc -I $(srcdir)/doc' \ - $(TEXI2PDF) --clean -o $@ `test -f 'doc/libffi.texi' || echo '$(srcdir)/'`doc/libffi.texi + $(TEXI2PDF) $(AM_V_texinfo) --build-dir=$(@:.pdf=.t2p) -o $@ $(AM_V_texidevnull) \ + `test -f 'doc/libffi.texi' || echo '$(srcdir)/'`doc/libffi.texi doc/libffi.html: doc/libffi.texi $(srcdir)/doc/version.texi doc/$(am__dirstamp) - rm -rf $(@:.html=.htp) - if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I doc -I $(srcdir)/doc \ + $(AM_V_MAKEINFO)rm -rf $(@:.html=.htp) + $(AM_V_at)if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I doc -I $(srcdir)/doc \ -o $(@:.html=.htp) `test -f 'doc/libffi.texi' || echo '$(srcdir)/'`doc/libffi.texi; \ then \ rm -rf $@; \ @@ -1238,8 +1453,8 @@ mostlyclean-vti: maintainer-clean-vti: @MAINTAINER_MODE_TRUE@ -rm -f $(srcdir)/doc/stamp-vti $(srcdir)/doc/version.texi .dvi.ps: - TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ - $(DVIPS) -o $@ $< + $(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + $(DVIPS) $(AM_V_texinfo) -o $@ $< uninstall-dvi-am: @$(NORMAL_UNINSTALL) @@ -1318,8 +1533,7 @@ dist-info: $(INFO_DEPS) done mostlyclean-aminfo: - -rm -rf libffi.aux libffi.cp libffi.cps libffi.fn libffi.ky libffi.log \ - libffi.pg libffi.tmp libffi.toc libffi.tp libffi.vr + -rm -rf doc/libffi.t2d doc/libffi.t2p clean-aminfo: -test -z "doc/libffi.dvi doc/libffi.pdf doc/libffi.ps doc/libffi.html" \ @@ -1359,14 +1573,13 @@ uninstall-pkgconfigDATA: # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. -$(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS): - @fail= failcom='exit 1'; \ - for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=* | --[!k]*);; \ - *k*) failcom='fail=yes';; \ - esac; \ - done; \ +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ @@ -1387,31 +1600,13 @@ $(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS): if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done -ctags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ - done -cscopelist-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) cscopelist); \ - done -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: tags-recursive $(HEADERS) $(SOURCES) fficonfig.h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ @@ -1427,12 +1622,7 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) fficonfig.h.in $(TAGS_DEPENDENCIES) \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ - list='$(SOURCES) $(HEADERS) fficonfig.h.in $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -1444,15 +1634,11 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) fficonfig.h.in $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: ctags-recursive $(HEADERS) $(SOURCES) fficonfig.h.in $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) fficonfig.h.in $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -1461,18 +1647,16 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" - cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) - clean-cscope: -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive -cscope.files: clean-cscope cscopelist-recursive cscopelist - -cscopelist: cscopelist-recursive $(HEADERS) $(SOURCES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP)'; \ +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ @@ -1548,7 +1732,7 @@ distdir: $(DISTFILES) done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ - dist-info + dist-info dist-hook -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ @@ -1609,9 +1793,9 @@ distcheck: dist *.zip*) \ unzip $(distdir).zip ;;\ esac - chmod -R a-w $(distdir); chmod u+w $(distdir) - mkdir $(distdir)/_build - mkdir $(distdir)/_inst + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ @@ -1714,6 +1898,8 @@ distclean-generic: -rm -f src/aarch64/$(am__dirstamp) -rm -f src/alpha/$(DEPDIR)/$(am__dirstamp) -rm -f src/alpha/$(am__dirstamp) + -rm -f src/arc/$(DEPDIR)/$(am__dirstamp) + -rm -f src/arc/$(am__dirstamp) -rm -f src/arm/$(DEPDIR)/$(am__dirstamp) -rm -f src/arm/$(am__dirstamp) -rm -f src/avr32/$(DEPDIR)/$(am__dirstamp) @@ -1730,6 +1916,8 @@ distclean-generic: -rm -f src/m32r/$(am__dirstamp) -rm -f src/m68k/$(DEPDIR)/$(am__dirstamp) -rm -f src/m68k/$(am__dirstamp) + -rm -f src/m88k/$(DEPDIR)/$(am__dirstamp) + -rm -f src/m88k/$(am__dirstamp) -rm -f src/metag/$(DEPDIR)/$(am__dirstamp) -rm -f src/metag/$(am__dirstamp) -rm -f src/microblaze/$(DEPDIR)/$(am__dirstamp) @@ -1738,6 +1926,8 @@ distclean-generic: -rm -f src/mips/$(am__dirstamp) -rm -f src/moxie/$(DEPDIR)/$(am__dirstamp) -rm -f src/moxie/$(am__dirstamp) + -rm -f src/nios2/$(DEPDIR)/$(am__dirstamp) + -rm -f src/nios2/$(am__dirstamp) -rm -f src/pa/$(DEPDIR)/$(am__dirstamp) -rm -f src/pa/$(am__dirstamp) -rm -f src/powerpc/$(DEPDIR)/$(am__dirstamp) @@ -1752,6 +1942,8 @@ distclean-generic: -rm -f src/sparc/$(am__dirstamp) -rm -f src/tile/$(DEPDIR)/$(am__dirstamp) -rm -f src/tile/$(am__dirstamp) + -rm -f src/vax/$(DEPDIR)/$(am__dirstamp) + -rm -f src/vax/$(am__dirstamp) -rm -f src/x86/$(DEPDIR)/$(am__dirstamp) -rm -f src/x86/$(am__dirstamp) -rm -f src/xtensa/$(DEPDIR)/$(am__dirstamp) @@ -1768,7 +1960,7 @@ clean-am: clean-aminfo clean-generic clean-libtool \ distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/metag/$(DEPDIR) src/microblaze/$(DEPDIR) src/mips/$(DEPDIR) src/moxie/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR) + -rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arc/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/m88k/$(DEPDIR) src/metag/$(DEPDIR) src/microblaze/$(DEPDIR) src/mips/$(DEPDIR) src/moxie/$(DEPDIR) src/nios2/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/vax/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags @@ -1907,7 +2099,7 @@ installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/metag/$(DEPDIR) src/microblaze/$(DEPDIR) src/mips/$(DEPDIR) src/moxie/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR) + -rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arc/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/m88k/$(DEPDIR) src/metag/$(DEPDIR) src/microblaze/$(DEPDIR) src/mips/$(DEPDIR) src/moxie/$(DEPDIR) src/nios2/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/vax/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-aminfo \ maintainer-clean-generic maintainer-clean-vti @@ -1929,35 +2121,35 @@ uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \ uninstall-pdf-am uninstall-pkgconfigDATA uninstall-ps-am \ uninstall-toolexeclibLTLIBRARIES -.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ - cscopelist-recursive ctags-recursive install-am install-strip \ - tags-recursive - -.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ - all all-am am--refresh check check-am clean clean-aminfo \ - clean-cscope clean-generic clean-libtool \ - clean-noinstLTLIBRARIES clean-toolexeclibLTLIBRARIES cscope \ - cscopelist cscopelist-recursive ctags ctags-recursive dist \ - dist-all dist-bzip2 dist-gzip dist-info dist-lzip dist-shar \ - dist-tarZ dist-xz dist-zip distcheck distclean \ - distclean-compile distclean-generic distclean-hdr \ - distclean-libtool distclean-tags distcleancheck distdir \ - distuninstallcheck dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-pkgconfigDATA install-ps \ - install-ps-am install-strip install-toolexeclibLTLIBRARIES \ - installcheck installcheck-am installdirs installdirs-am \ - maintainer-clean maintainer-clean-aminfo \ - maintainer-clean-generic maintainer-clean-vti mostlyclean \ - mostlyclean-aminfo mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool mostlyclean-vti pdf pdf-am ps ps-am tags \ - tags-recursive uninstall uninstall-am uninstall-dvi-am \ - uninstall-html-am uninstall-info-am uninstall-pdf-am \ - uninstall-pkgconfigDATA uninstall-ps-am \ - uninstall-toolexeclibLTLIBRARIES - +.MAKE: $(am__recursive_targets) all install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-aminfo clean-cscope \ + clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-toolexeclibLTLIBRARIES cscope cscopelist-am ctags \ + ctags-am dist dist-all dist-bzip2 dist-gzip dist-hook \ + dist-info dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ + distcheck distclean distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-tags distcleancheck \ + distdir distuninstallcheck dvi dvi-am html html-am info \ + info-am install install-am install-data install-data-am \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-pkgconfigDATA \ + install-ps install-ps-am install-strip \ + install-toolexeclibLTLIBRARIES installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-aminfo maintainer-clean-generic \ + maintainer-clean-vti mostlyclean mostlyclean-aminfo \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + mostlyclean-vti pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-dvi-am uninstall-html-am \ + uninstall-info-am uninstall-pdf-am uninstall-pkgconfigDATA \ + uninstall-ps-am uninstall-toolexeclibLTLIBRARIES + + +dist-hook: + if [ -d $(top_srcdir)/.git ] ; then (cd $(top_srcdir); git log --no-decorate) ; else echo 'See git log for history.' ; fi > $(distdir)/ChangeLog # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/Modules/_ctypes/libffi/README b/Modules/_ctypes/libffi/README index 19156fe56e1e..84b942677adb 100644 --- a/Modules/_ctypes/libffi/README +++ b/Modules/_ctypes/libffi/README @@ -1,8 +1,8 @@ Status ====== -libffi-3.0.13 was released on March 17, 2013. Check the libffi web -page for updates: . +libffi-3.1 was released on May 19, 2014. Check the libffi web page +for updates: . What is libffi? @@ -43,7 +43,7 @@ Libffi has been ported to many different platforms. For specific configuration details and testing status, please refer to the wiki page here: - http://www.moxielogic.org/wiki/index.php?title=Libffi_3.0.13 + http://www.moxielogic.org/wiki/index.php?title=Libffi_3.1 At the time of release, the following basic configurations have been tested: @@ -51,9 +51,11 @@ tested: |-----------------+------------------+-------------------------| | Architecture | Operating System | Compiler | |-----------------+------------------+-------------------------| +| AArch64 (ARM64) | iOS | Clang | | AArch64 | Linux | GCC | | Alpha | Linux | GCC | | Alpha | Tru64 | GCC | +| ARC | Linux | GCC | | ARM | Linux | GCC | | ARM | iOS | GCC | | AVR32 | Linux | GCC | @@ -61,15 +63,17 @@ tested: | HPPA | HPUX | GCC | | IA-64 | Linux | GCC | | M68K | FreeMiNT | GCC | -| M68K | Linux | GCC | +| M68K | Linux | GCC | | M68K | RTEMS | GCC | +| M88K | OpenBSD/mvme88k | GCC | | Meta | Linux | GCC | | MicroBlaze | Linux | GCC | | MIPS | IRIX | GCC | | MIPS | Linux | GCC | | MIPS | RTEMS | GCC | | MIPS64 | Linux | GCC | -| Moxie | Bare metal | GCC +| Moxie | Bare metal | GCC | +| Nios II | Linux | GCC | | PowerPC 32-bit | AIX | IBM XL C | | PowerPC 64-bit | AIX | IBM XL C | | PowerPC | AMIGA | GCC | @@ -77,7 +81,8 @@ tested: | PowerPC | Mac OSX | GCC | | PowerPC | FreeBSD | GCC | | PowerPC 64-bit | FreeBSD | GCC | -| PowerPC 64-bit | Linux | GCC | +| PowerPC 64-bit | Linux ELFv1 | GCC | +| PowerPC 64-bit | Linux ELFv2 | GCC | | S390 | Linux | GCC | | S390X | Linux | GCC | | SPARC | Linux | GCC | @@ -87,6 +92,7 @@ tested: | SPARC64 | FreeBSD | GCC | | SPARC64 | Solaris | Oracle Solaris Studio C | | TILE-Gx/TILEPro | Linux | GCC | +| VAX | OpenBSD/vax | GCC | | X86 | FreeBSD | GCC | | X86 | GNU HURD | GCC | | X86 | Interix | GCC | @@ -120,6 +126,9 @@ 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. +If you're building libffi directly from version control, configure won't +exist yet; run ./autogen.sh first. + 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. @@ -137,13 +146,16 @@ It's also possible to build libffi on Windows platforms with Microsoft's Visual C++ compiler. In this case, use the msvcc.sh wrapper script during configuration like so: -path/to/configure CC=path/to/msvcc.sh LD=link CPP=\"cl -nologo -EP\" +path/to/configure CC=path/to/msvcc.sh CXX=path/to/msvcc.sh LD=link CPP=\"cl -nologo -EP\" + +For 64-bit Windows builds, use CC="path/to/msvcc.sh -m64" and +CXX="path/to/msvcc.sh -m64". You may also need to specify --build +appropriately. -For 64-bit Windows builds, use CC="path/to/msvcc.sh -m64". -You may also need to specify --build appropriately. When building with MSVC -under a MingW environment, you may need to remove the line in configure -that sets 'fix_srcfile_path' to a 'cygpath' command. ('cygpath' is not -present in MingW, and is not required when using MingW-style paths.) +When building with MSVC under a MingW environment, you may need to +remove the line in configure that sets 'fix_srcfile_path' to a 'cygpath' +command. ('cygpath' is not present in MingW, and is not required when +using MingW-style paths.) For iOS builds, the 'libffi.xcodeproj' Xcode project is available. @@ -161,7 +173,20 @@ To install the library and header files, type "make install". History ======= -See the ChangeLog files for details. +See the git log for details at http://github.com/atgreen/libffi. + +3.1 May-19-14 + Add AArch64 (ARM64) iOS support. + Add Nios II support. + Add m88k and DEC VAX support. + Add support for stdcall, thiscall, and fastcall on non-Windows + 32-bit x86 targets such as Linux. + Various Android, MIPS N32, x86, FreeBSD and UltraSPARC IIi + fixes. + Make the testsuite more robust: eliminate several spurious + failures, and respect the $CC and $CXX environment variables. + Archive off the manually maintained ChangeLog in favor of git + log. 3.0.13 Mar-17-13 Add Meta support. @@ -187,7 +212,6 @@ See the ChangeLog files for details. 3.0.11 Apr-11-12 Lots of build fixes. - Add Amiga newer MacOS support. Add support for variadic functions (ffi_prep_cif_var). Add Linux/x32 support. Add thiscall, fastcall and MSVC cdecl support on Windows. @@ -339,7 +363,7 @@ See the ChangeLog files for details. Authors & Credits ================= -libffi was originally written by Anthony Green . +libffi was originally written by Anthony Green . The developers of the GNU Compiler Collection project have made innumerable valuable contributions. See the ChangeLog file for @@ -363,10 +387,12 @@ frv Anthony Green ia64 Hans Boehm m32r Kazuhiro Inaoka m68k Andreas Schwab +m88k Miod Vallat microblaze Nathan Rossi mips Anthony Green, Casey Marshall mips64 David Daney moxie Anthony Green +nios ii Sandra Loosemore pa Randolph Chung, Dave Anglin, Andreas Tobler powerpc Geoffrey Keating, Andreas Tobler, David Edelsohn, John Hornkvist @@ -376,6 +402,7 @@ sh Kaz Kojima sh64 Kaz Kojima sparc Anthony Green, Gordon Irlam tile-gx/tilepro Walter Lee +vax Miod Vallat x86 Anthony Green, Jon Beniston x86-64 Bo Thorsen xtensa Chris Zankel diff --git a/Modules/_ctypes/libffi/aclocal.m4 b/Modules/_ctypes/libffi/aclocal.m4 index c3ab272061d9..6292fbab7aa0 100644 --- a/Modules/_ctypes/libffi/aclocal.m4 +++ b/Modules/_ctypes/libffi/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.12.2 -*- Autoconf -*- +# generated automatically by aclocal 1.13.4 -*- Autoconf -*- -# Copyright (C) 1996-2012 Free Software Foundation, Inc. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -11,6 +11,7 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, @@ -837,24 +838,22 @@ AU_ALIAS([AC_LTDL_DLSYM_USCORE], [LT_FUNC_DLSYM_USCORE]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_DLSYM_USCORE], []) -# Copyright (C) 2002-2012 Free Software Foundation, Inc. +# Copyright (C) 2002-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 8 - # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.12' +[am__api_version='1.13' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.12.2], [], +m4_if([$1], [1.13.4], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -870,21 +869,19 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.12.2])dnl +[AM_AUTOMAKE_VERSION([1.13.4])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Figure out how to run the assembler. -*- Autoconf -*- -# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 5 - # AM_PROG_AS # ---------- AC_DEFUN([AM_PROG_AS], @@ -899,14 +896,12 @@ _AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 - # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. @@ -954,14 +949,12 @@ am_aux_dir=`cd $ac_aux_dir && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2012 Free Software Foundation, Inc. +# Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 10 - # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. @@ -987,13 +980,12 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2012 Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 17 # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, @@ -1179,19 +1171,18 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2012 Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 6 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ - # Autoconf 2.62 quotes --file arguments for eval, but not when files + # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in @@ -1220,7 +1211,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue + test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the @@ -1256,14 +1247,12 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2012 Free Software Foundation, Inc. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 19 - # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. @@ -1279,7 +1268,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.62])dnl +[AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl @@ -1309,8 +1298,7 @@ AC_SUBST([CYGPATH_W]) dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], -[$0: two- and three-arguments forms are deprecated. For more info, see: -http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_INIT_AUTOMAKE-invocation]) + [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], @@ -1364,18 +1352,15 @@ AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl -dnl Support for Objective C++ was only introduced in Autoconf 2.65, -dnl but we still cater to Autoconf 2.62. -m4_ifdef([AC_PROG_OBJCXX], -[AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], - m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])])dnl + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) -_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl -dnl The 'parallel-tests' driver may need to know about EXEEXT, so add the -dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro -dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl @@ -1409,14 +1394,12 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 8 - # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. @@ -1432,14 +1415,12 @@ if test x"${install_sh}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2012 Free Software Foundation, Inc. +# Copyright (C) 2003-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 - # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], @@ -1456,14 +1437,12 @@ AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering -# Copyright (C) 1996-2012 Free Software Foundation, Inc. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 7 - # AM_MAINTAINER_MODE([DEFAULT-MODE]) # ---------------------------------- # Control maintainer-specific portions of Makefiles. @@ -1491,18 +1470,14 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) ] ) -AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) - # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 5 - # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. @@ -1545,14 +1520,12 @@ AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) -# Copyright (C) 1999-2012 Free Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 6 - # AM_PROG_CC_C_O # -------------- # Like AC_PROG_CC_C_O, but changed for automake. @@ -1581,14 +1554,12 @@ m4_define([AC_PROG_CC], # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2012 Free Software Foundation, Inc. +# Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 7 - # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], @@ -1596,11 +1567,10 @@ AC_DEFUN([AM_MISSING_PROG], $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) - # AM_MISSING_HAS_RUN # ------------------ -# Define MISSING if not defined so far and test if it supports --run. -# If it does, set am_missing_run to use it, otherwise, to nothing. +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl @@ -1613,8 +1583,8 @@ if test x"${MISSING+set}" != xset; then esac fi # Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) @@ -1623,14 +1593,12 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 6 - # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], @@ -1656,14 +1624,12 @@ AC_DEFUN([_AM_IF_OPTION], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2012 Free Software Foundation, Inc. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 9 - # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], @@ -1739,13 +1705,71 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2001-2012 Free Software Foundation, Inc. +# Copyright (C) 2009-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 2 +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2013 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- @@ -1769,14 +1793,12 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2012 Free Software Foundation, Inc. +# Copyright (C) 2006-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 3 - # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. @@ -1790,14 +1812,12 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2012 Free Software Foundation, Inc. +# Copyright (C) 2004-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# serial 3 - # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. @@ -1811,76 +1831,114 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar +# AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) -m4_if([$1], [v7], - [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - [m4_case([$1], [ustar],, [pax],, - [m4_fatal([Unknown tar format])]) -AC_MSG_CHECKING([how to create a $1 tar archive]) -# Loop over all known methods to create a tar archive until one works. + +# We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' -_am_tools=${am_cv_prog_tar_$1-$_am_tools} -# Do not fold the above two line into one, because Tru64 sh and -# Solaris sh will not grok spaces in the rhs of '-'. -for _am_tool in $_am_tools -do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; - do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], - # tar/untar a dummy directory, and stop if the command works - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi -done -rm -rf conftest.dir -AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) -AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR diff --git a/Modules/_ctypes/libffi/build-ios.sh b/Modules/_ctypes/libffi/build-ios.sh deleted file mode 100644 index 3dea242255ee..000000000000 --- a/Modules/_ctypes/libffi/build-ios.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/sh - -PLATFORM_IOS=/Developer/Platforms/iPhoneOS.platform/ -PLATFORM_IOS_SIM=/Developer/Platforms/iPhoneSimulator.platform/ -SDK_IOS_VERSION="4.2" -MIN_IOS_VERSION="3.0" -OUTPUT_DIR="universal-ios" - -build_target () { - local platform=$1 - local sdk=$2 - local arch=$3 - local triple=$4 - local builddir=$5 - - mkdir -p "${builddir}" - pushd "${builddir}" - export CC="${platform}"/Developer/usr/bin/gcc-4.2 - export CFLAGS="-arch ${arch} -isysroot ${sdk} -miphoneos-version-min=${MIN_IOS_VERSION}" - ../configure --host=${triple} && make - popd -} - -# Build all targets -build_target "${PLATFORM_IOS}" "${PLATFORM_IOS}/Developer/SDKs/iPhoneOS${SDK_IOS_VERSION}.sdk/" armv6 arm-apple-darwin10 armv6-ios -build_target "${PLATFORM_IOS}" "${PLATFORM_IOS}/Developer/SDKs/iPhoneOS${SDK_IOS_VERSION}.sdk/" armv7 arm-apple-darwin10 armv7-ios -build_target "${PLATFORM_IOS_SIM}" "${PLATFORM_IOS_SIM}/Developer/SDKs/iPhoneSimulator${SDK_IOS_VERSION}.sdk/" i386 i386-apple-darwin10 i386-ios-sim - -# Create universal output directories -mkdir -p "${OUTPUT_DIR}" -mkdir -p "${OUTPUT_DIR}/include" -mkdir -p "${OUTPUT_DIR}/include/armv6" -mkdir -p "${OUTPUT_DIR}/include/armv7" -mkdir -p "${OUTPUT_DIR}/include/i386" - -# Create the universal binary -lipo -create armv6-ios/.libs/libffi.a armv7-ios/.libs/libffi.a i386-ios-sim/.libs/libffi.a -output "${OUTPUT_DIR}/libffi.a" - -# Copy in the headers -copy_headers () { - local src=$1 - local dest=$2 - - # Fix non-relative header reference - sed 's//"ffitarget.h"/' < "${src}/include/ffi.h" > "${dest}/ffi.h" - cp "${src}/include/ffitarget.h" "${dest}" -} - -copy_headers armv6-ios "${OUTPUT_DIR}/include/armv6" -copy_headers armv7-ios "${OUTPUT_DIR}/include/armv7" -copy_headers i386-ios-sim "${OUTPUT_DIR}/include/i386" - -# Create top-level header -( -cat << EOF -#ifdef __arm__ - #include - #ifdef _ARM_ARCH_6 - #include "include/armv6/ffi.h" - #elif _ARM_ARCH_7 - #include "include/armv7/ffi.h" - #endif -#elif defined(__i386__) - #include "include/i386/ffi.h" -#endif -EOF -) > "${OUTPUT_DIR}/ffi.h" diff --git a/Modules/_ctypes/libffi/compile b/Modules/_ctypes/libffi/compile index c0096a7b5632..531136b068ef 100755 --- a/Modules/_ctypes/libffi/compile +++ b/Modules/_ctypes/libffi/compile @@ -1,10 +1,9 @@ #! /bin/sh -# Wrapper for compilers which do not understand `-c -o'. +# Wrapper for compilers which do not understand '-c -o'. -scriptversion=2009-10-06.20; # UTC +scriptversion=2012-10-14.11; # UTC -# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009 Free Software -# Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify @@ -29,21 +28,224 @@ scriptversion=2009-10-06.20; # UTC # bugs to or send patches to # . +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + case $1 in '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] -Wrapper for compilers which do not understand `-c -o'. -Remove `-o dest.o' from ARGS, run PROGRAM with the remaining +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the -right script to run: please start by reading the file `INSTALL'. +right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF @@ -53,11 +255,13 @@ EOF echo "compile $scriptversion" exit $? ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; esac ofile= cfile= -eat= for arg do @@ -66,8 +270,8 @@ do else case $1 in -o) - # configure might choose to run compile as `compile cc -o foo foo.c'. - # So we strip `-o arg' only if arg is an object. + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) @@ -94,10 +298,10 @@ do done if test -z "$ofile" || test -z "$cfile"; then - # If no `-o' option was seen then we might have been invoked from a + # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no - # `.c' file was seen then we are probably linking. That is also + # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi @@ -106,7 +310,7 @@ fi cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. -# Note: use `[/\\:.-]' here to ensure that we don't use the same name +# Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d diff --git a/Modules/_ctypes/libffi/config.guess b/Modules/_ctypes/libffi/config.guess index 1804e9fcdcbc..b79252d6b103 100755 --- a/Modules/_ctypes/libffi/config.guess +++ b/Modules/_ctypes/libffi/config.guess @@ -1,10 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -# 2011, 2012, 2013 Free Software Foundation, Inc. +# Copyright 1992-2013 Free Software Foundation, Inc. -timestamp='2012-12-29' +timestamp='2013-06-10' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -26,7 +24,7 @@ timestamp='2012-12-29' # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # -# Originally written by Per Bothner. +# Originally written by Per Bothner. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD @@ -52,9 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -2012, 2013 Free Software Foundation, Inc. +Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -136,6 +132,27 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + ;; +esac + # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in @@ -857,21 +874,21 @@ EOF exit ;; *:GNU:*:*) # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in @@ -884,59 +901,54 @@ EOF EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo ${UNAME_MACHINE}-unknown-linux-gnueabi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else - echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu + echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-gnu + echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) - LIBC=gnu - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build @@ -955,54 +967,63 @@ EOF #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; + or1k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; or32:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) - echo sparc-unknown-linux-gnu + echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu + echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu + echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu + echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. @@ -1235,19 +1256,21 @@ EOF exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - i386) - eval $set_cc_for_build - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - UNAME_PROCESSOR="x86_64" - fi - fi ;; - unknown) UNAME_PROCESSOR=powerpc ;; - esac + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) diff --git a/Modules/_ctypes/libffi/config.sub b/Modules/_ctypes/libffi/config.sub index 802a224de605..c765b34b7b0e 100755 --- a/Modules/_ctypes/libffi/config.sub +++ b/Modules/_ctypes/libffi/config.sub @@ -1,10 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -# 2011, 2012, 2013 Free Software Foundation, Inc. +# Copyright 1992-2013 Free Software Foundation, Inc. -timestamp='2012-12-29' +timestamp='2013-04-24' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -70,9 +68,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -2012, 2013 Free Software Foundation, Inc. +Copyright 1992-2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -256,7 +252,7 @@ case $basic_machine in | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ - | arc \ + | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ @@ -290,16 +286,17 @@ case $basic_machine in | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ - | nios | nios2 \ + | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 \ - | or32 \ + | or1k | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ @@ -369,7 +366,7 @@ case $basic_machine in | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ @@ -407,12 +404,13 @@ case $basic_machine in | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ @@ -1008,7 +1006,7 @@ case $basic_machine in ;; ppc64) basic_machine=powerpc64-unknown ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ppc64-* | ppc64p7-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown @@ -1354,7 +1352,7 @@ case $os in -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* \ + | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ @@ -1500,9 +1498,6 @@ case $os in -aros*) os=-aros ;; - -kaos*) - os=-kaos - ;; -zvmoe) os=-zvmoe ;; @@ -1594,6 +1589,9 @@ case $basic_machine in mips*-*) os=-elf ;; + or1k-*) + os=-elf + ;; or32-*) os=-coff ;; diff --git a/Modules/_ctypes/libffi/configure b/Modules/_ctypes/libffi/configure index 823083063f07..75f62a7c4ca2 100755 --- a/Modules/_ctypes/libffi/configure +++ b/Modules/_ctypes/libffi/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for libffi 3.0.13. +# Generated by GNU Autoconf 2.69 for libffi 3.1. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libffi' PACKAGE_TARNAME='libffi' -PACKAGE_VERSION='3.0.13' -PACKAGE_STRING='libffi 3.0.13' +PACKAGE_VERSION='3.1' +PACKAGE_STRING='libffi 3.1' PACKAGE_BUGREPORT='http://github.com/atgreen/libffi/issues' PACKAGE_URL='' @@ -645,10 +645,13 @@ FFI_EXEC_TRAMPOLINE_TABLE FFI_EXEC_TRAMPOLINE_TABLE_FALSE FFI_EXEC_TRAMPOLINE_TABLE_TRUE sys_symbol_underscore +HAVE_LONG_DOUBLE_VARIANT HAVE_LONG_DOUBLE ALLOCA XTENSA_FALSE XTENSA_TRUE +VAX_FALSE +VAX_TRUE TILE_FALSE TILE_TRUE PA64_HPUX_FALSE @@ -673,6 +676,8 @@ AVR32_FALSE AVR32_TRUE ARM_FALSE ARM_TRUE +ARC_FALSE +ARC_TRUE AARCH64_FALSE AARCH64_TRUE POWERPC_FREEBSD_FALSE @@ -683,12 +688,16 @@ POWERPC_AIX_FALSE POWERPC_AIX_TRUE POWERPC_FALSE POWERPC_TRUE +NIOS2_FALSE +NIOS2_TRUE MOXIE_FALSE MOXIE_TRUE METAG_FALSE METAG_TRUE MICROBLAZE_FALSE MICROBLAZE_TRUE +M88K_FALSE +M88K_TRUE M68K_FALSE M68K_TRUE M32R_FALSE @@ -697,6 +706,10 @@ IA64_FALSE IA64_TRUE ALPHA_FALSE ALPHA_TRUE +X86_DARWIN64_FALSE +X86_DARWIN64_TRUE +X86_DARWIN32_FALSE +X86_DARWIN32_TRUE X86_DARWIN_FALSE X86_DARWIN_TRUE X86_WIN64_FALSE @@ -721,6 +734,7 @@ MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE PRTDIAG +CXXCPP CPP OTOOL64 OTOOL @@ -748,6 +762,12 @@ am__fastdepCCAS_TRUE CCASDEPMODE CCASFLAGS CCAS +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +ac_ct_CXX +CXXFLAGS +CXX am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE @@ -765,6 +785,10 @@ CPPFLAGS LDFLAGS CFLAGS CC +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V am__untar am__tar AMTAR @@ -843,6 +867,7 @@ ac_subst_files='' ac_user_opts=' enable_option_checking enable_builddir +enable_silent_rules enable_dependency_tracking enable_shared enable_static @@ -866,7 +891,8 @@ target_alias CCAS CCASFLAGS CPP -CPPFLAGS' +CPPFLAGS +CXXCPP' # Initialize some variables set by options. @@ -1407,7 +1433,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libffi 3.0.13 to adapt to many kinds of systems. +\`configure' configures libffi 3.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1478,7 +1504,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libffi 3.0.13:";; + short | recursive ) echo "Configuration of libffi 3.1:";; esac cat <<\_ACEOF @@ -1488,6 +1514,8 @@ Optional Features: --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-builddir disable automatic build in subdir of sources + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking @@ -1515,8 +1543,8 @@ Optional Packages: --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] - --with-sysroot=DIR Search for dependent libraries within DIR - (or the compiler's sysroot if not specified). + --with-sysroot[=DIR] Search for dependent libraries within DIR (or the + compiler's sysroot if not specified). --with-gcc-arch= use architecture for gcc -march/-mtune, instead of guessing @@ -1528,9 +1556,12 @@ Some influential environment variables: LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory + CXX C++ compiler command + CXXFLAGS C++ compiler flags CCAS assembler compiler command (defaults to CC) CCASFLAGS assembler compiler flags (defaults to CFLAGS) CPP C preprocessor + CXXCPP C++ preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -1598,7 +1629,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libffi configure 3.0.13 +libffi configure 3.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1650,6 +1681,44 @@ fi } # ac_fn_c_try_compile +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. @@ -1873,6 +1942,89 @@ $as_echo "$ac_res" >&6; } } # ac_fn_c_check_func +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link + # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes @@ -2204,7 +2356,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libffi $as_me 3.0.13, which was +It was created by libffi $as_me 3.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2697,7 +2849,11 @@ test -n "$target_alias" && target_alias=${target_alias-$host_alias} -. ${srcdir}/configure.host +case "${host}" in + frv*-elf) + LDFLAGS=`echo $LDFLAGS | sed "s/\-B^ *libgloss\/frv\///"`\ -B`pwd`/../libgloss/frv/ + ;; +esac # [$]@ is unsable in 2.60+ but earlier autoconf had no ac_configure_args @@ -2803,7 +2959,7 @@ ax_enable_builddir_auxdir="$am_aux_dir" ac_config_commands="$ac_config_commands buildir" -am__api_version='1.12' +am__api_version='1.13' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or @@ -2984,8 +3140,8 @@ if test x"${MISSING+set}" != xset; then esac fi # Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 @@ -3225,6 +3381,45 @@ else fi rmdir .tst 2>/dev/null +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." @@ -3247,7 +3442,7 @@ fi # Define the identity of the package. PACKAGE='libffi' - VERSION='3.0.13' + VERSION='3.1' cat >>confdefs.h <<_ACEOF @@ -3287,6 +3482,10 @@ mkdir_p='$(MKDIR_P)' # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' @@ -3294,6 +3493,7 @@ am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + # The same as in boehm-gc and libstdc++. Have to borrow it from there. # We must force CC to /not/ be precious variables; otherwise # the wrong, non-multilib-adjusted value will be used in multilibs. @@ -4284,54 +4484,439 @@ else fi -CFLAGS=$save_CFLAGS - +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS -# By default we simply use the C compiler to build assembly code. +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi -test "${CCAS+set}" = set || CCAS=$CC -test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS + test -n "$ac_ct_CXX" && break +done + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi -depcc="$CCAS" am_compiler_list= + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CCAS_dependencies_compiler_type+:} false; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CCAS_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ - for depmode in $am_compiler_list; do +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + +CFLAGS=$save_CFLAGS + + + + + +# By default we simply use the C compiler to build assembly code. + +test "${CCAS+set}" = set || CCAS=$CC +test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS + + + +depcc="$CCAS" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CCAS_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CCAS_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + + + for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. @@ -4557,8 +5142,8 @@ esac -macro_version='2.4.2' -macro_revision='1.3337' +macro_version='2.4.2.418' +macro_revision='2.4.2.418' @@ -4572,7 +5157,7 @@ macro_revision='1.3337' -ltmain="$ac_aux_dir/ltmain.sh" +ltmain=$ac_aux_dir/ltmain.sh # Backslashify metacharacters that are still active within # double-quoted strings. @@ -4621,7 +5206,7 @@ func_echo_all () $ECHO "" } -case "$ECHO" in +case $ECHO in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 @@ -4944,19 +5529,19 @@ test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : - withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld -if test "$GCC" = yes; then +if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw + # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; @@ -4970,7 +5555,7 @@ $as_echo_n "checking for ld used by $CC... " >&6; } while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done - test -z "$LD" && LD="$ac_prog" + test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. @@ -4981,7 +5566,7 @@ $as_echo_n "checking for ld used by $CC... " >&6; } with_gnu_ld=unknown ;; esac -elif test "$with_gnu_ld" = yes; then +elif test yes = "$with_gnu_ld"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else @@ -4992,32 +5577,32 @@ if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" + lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } @@ -5060,33 +5645,33 @@ if ${lt_cv_path_NM+:} false; then : else if test -n "$NM"; then # Let the user override the test. - lt_cv_path_NM="$NM" + lt_cv_path_NM=$NM else - lt_nm_to_check="${ac_tool_prefix}nm" + lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" - break + break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" - break + break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but @@ -5097,15 +5682,15 @@ else esac fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : @@ -5211,9 +5796,9 @@ esac fi fi - case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) - DUMPBIN="$DUMPBIN -symbols" + DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: @@ -5221,8 +5806,8 @@ fi esac fi - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" + if test : != "$DUMPBIN"; then + NM=$DUMPBIN fi fi test -z "$NM" && NM=nm @@ -5273,7 +5858,7 @@ if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 - teststring="ABCD" + teststring=ABCD case $build_os in msdosdjgpp*) @@ -5313,7 +5898,7 @@ else lt_cv_sys_max_cmd_len=8192; ;; - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` @@ -5364,22 +5949,22 @@ else *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ - test undefined != "$lt_cv_sys_max_cmd_len"; then + test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do + for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. - while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough + test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring @@ -5397,7 +5982,7 @@ else fi -if test -n $lt_cv_sys_max_cmd_len ; then +if test -n "$lt_cv_sys_max_cmd_len"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else @@ -5415,30 +6000,6 @@ max_cmd_len=$lt_cv_sys_max_cmd_len : ${MV="mv -f"} : ${RM="rm -f"} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 -$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,b/c, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 -$as_echo "$xsi_shell" >&6; } - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 -$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } -lt_shell_append=no -( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 -$as_echo "$lt_shell_append" >&6; } - - if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else @@ -5561,13 +6122,13 @@ esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) - if test "$GCC" != yes; then + if test yes != "$GCC"; then reload_cmds=false fi ;; darwin*) - if test "$GCC" = yes; then - reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi @@ -5695,13 +6256,13 @@ lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. -# `unknown' -- same as none, but documents that we really don't know. +# 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path -# which responds to the $file_magic_cmd with a given extended regex. -# If you have `file' or equivalent on your system and you're not sure -# whether `pass_all' will *always* work, you probably want this one. +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) @@ -5728,8 +6289,7 @@ mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. - # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. - if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else @@ -5765,10 +6325,6 @@ freebsd* | dragonfly*) fi ;; -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - haiku*) lt_cv_deplibs_check_method=pass_all ;; @@ -5807,7 +6363,7 @@ irix5* | irix6* | nonstopux*) ;; # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; @@ -5829,8 +6385,8 @@ newos6*) lt_cv_deplibs_check_method=pass_all ;; -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' @@ -6040,8 +6596,8 @@ else case $host_os in cygwin* | mingw* | pw32* | cegcc*) - # two different shell functions defined in ltmain.sh - # decide which to use based on capabilities of $DLLTOOL + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib @@ -6053,7 +6609,7 @@ cygwin* | mingw* | pw32* | cegcc*) ;; *) # fallback: assume linklib IS sharedlib - lt_cv_sharedlib_from_linklib_cmd="$ECHO" + lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac @@ -6208,7 +6764,7 @@ if ac_fn_c_try_compile "$LINENO"; then : ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } - if test "$ac_status" -eq 0; then + if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 @@ -6216,7 +6772,7 @@ if ac_fn_c_try_compile "$LINENO"; then : ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } - if test "$ac_status" -ne 0; then + if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi @@ -6229,7 +6785,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } -if test "x$lt_cv_ar_at_file" = xno; then +if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file @@ -6446,7 +7002,7 @@ old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in - openbsd*) + bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) @@ -6536,7 +7092,7 @@ cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then symcode='[ABCDEGRST]' fi ;; @@ -6569,14 +7125,44 @@ case `$NM -V 2>&1` in symcode='[ABCDGIRSTW]' ;; esac +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= @@ -6594,21 +7180,24 @@ for ac_symprfx in "" "_"; do # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" @@ -6656,11 +7245,11 @@ _LT_EOF if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST -#elif defined(__osf__) +#elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else @@ -6686,7 +7275,7 @@ lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; @@ -6706,13 +7295,13 @@ _LT_EOF mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS - LIBS="conftstm.$ac_objext" + LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext}; then + test $ac_status = 0; } && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS @@ -6733,7 +7322,7 @@ _LT_EOF rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then + if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= @@ -6786,21 +7375,31 @@ fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 -$as_echo_n "checking for sysroot... " >&6; } -# Check whether --with-sysroot was given. -if test "${with_sysroot+set}" = set; then : - withval=$with_sysroot; + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= -case ${with_sysroot} in #( +case $with_sysroot in #( yes) - if test "$GCC" = yes; then + if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( @@ -6810,8 +7409,8 @@ case ${with_sysroot} in #( no|'') ;; #( *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 -$as_echo "${with_sysroot}" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 +$as_echo "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac @@ -6828,13 +7427,14 @@ if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes +test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 @@ -6843,24 +7443,25 @@ ia64-*-hpux*) test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) - HPUX_IA64_MODE="32" + HPUX_IA64_MODE=32 ;; *ELF-64*) - HPUX_IA64_MODE="64" + HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - if test "$lt_cv_prog_gnu_ld" = yes; then + if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" @@ -6889,9 +7490,50 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 @@ -6907,14 +7549,17 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) - LD="${LD-ld} -m elf32_x86_64" - ;; + LD="${LD-ld} -m elf32_x86_64" + ;; *) - LD="${LD-ld} -m elf_i386" - ;; + LD="${LD-ld} -m elf_i386" + ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -6933,7 +7578,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -6951,7 +7599,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" + SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } @@ -6991,13 +7639,14 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } - if test x"$lt_cv_cc_needs_belf" != x"yes"; then + if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" + CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 @@ -7009,7 +7658,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; } case $lt_cv_prog_gnu_ld in yes*) case $host in - i?86-*-solaris*) + i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) @@ -7018,7 +7667,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; } esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then - LD="${LD-ld}_sol2" + LD=${LD-ld}_sol2 fi ;; *) @@ -7034,7 +7683,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; } ;; esac -need_locks="$enable_libtool_lock" +need_locks=$enable_libtool_lock if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. @@ -7145,7 +7794,7 @@ else fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } -if test "x$lt_cv_path_mainfest_tool" != xyes; then +if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi @@ -7648,7 +8297,7 @@ if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then + if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the @@ -7666,7 +8315,7 @@ else cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. - elif test -f libconftest.dylib && test $_lt_result -eq 0; then + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 @@ -7705,7 +8354,7 @@ else fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 @@ -7734,7 +8383,7 @@ _LT_EOF _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 - elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&5 @@ -7747,32 +8396,32 @@ fi $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[012]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then + if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi - if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= @@ -8063,6 +8712,17 @@ done +func_stripname_cnf () +{ + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; + esac +} # func_stripname_cnf + + + + # Set options @@ -8083,14 +8743,14 @@ if test "${enable_shared+set}" = set; then : *) enable_shared=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac else @@ -8114,14 +8774,14 @@ if test "${enable_static+set}" = set; then : *) enable_static=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac else @@ -8145,14 +8805,14 @@ if test "${with_pic+set}" = set; then : *) pic_mode=default # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac else @@ -8160,8 +8820,6 @@ else fi -test -z "$pic_mode" && pic_mode=default - @@ -8177,14 +8835,14 @@ if test "${enable_fast_install+set}" = set; then : *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac else @@ -8202,7 +8860,7 @@ fi # This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" +LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' @@ -8251,7 +8909,7 @@ test -z "$LN_S" && LN_S="ln -s" -if test -n "${ZSH_VERSION+set}" ; then +if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi @@ -8290,7 +8948,7 @@ aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then + if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi @@ -8301,14 +8959,14 @@ esac ofile=libtool can_build_shared=yes -# All known linkers require a `.a' archive for static linking (except MSVC, +# All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a -with_gnu_ld="$lt_cv_prog_gnu_ld" +with_gnu_ld=$lt_cv_prog_gnu_ld -old_CC="$CC" -old_CFLAGS="$CFLAGS" +old_CC=$CC +old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc @@ -8340,22 +8998,22 @@ if ${lt_cv_path_MAGIC_CMD+:} false; then : else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/${ac_tool_prefix}file; then - lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -f "$ac_dir/${ac_tool_prefix}file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : @@ -8378,13 +9036,13 @@ _LT_EOF break fi done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } @@ -8406,22 +9064,22 @@ if ${lt_cv_path_MAGIC_CMD+:} false; then : else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/file; then - lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -f "$ac_dir/file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : @@ -8444,13 +9102,13 @@ _LT_EOF break fi done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } @@ -8471,7 +9129,7 @@ esac # Use C for the default configuration in the libtool script -lt_save_CC="$CC" +lt_save_CC=$CC ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -8533,7 +9191,7 @@ if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= -if test "$GCC" = yes; then +if test yes = "$GCC"; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; @@ -8549,7 +9207,7 @@ else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="-fno-rtti -fno-exceptions" + lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins @@ -8579,7 +9237,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } -if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then +if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : @@ -8597,17 +9255,18 @@ lt_prog_compiler_pic= lt_prog_compiler_static= - if test "$GCC" = yes; then + if test yes = "$GCC"; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi + lt_prog_compiler_pic='-fPIC' ;; amigaos*) @@ -8618,8 +9277,8 @@ lt_prog_compiler_static= ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac @@ -8705,7 +9364,7 @@ lt_prog_compiler_static= case $host_os in aix*) lt_prog_compiler_wl='-Wl,' - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else @@ -8713,6 +9372,20 @@ lt_prog_compiler_static= fi ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). @@ -8732,7 +9405,7 @@ lt_prog_compiler_static= ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? - lt_prog_compiler_static='${wl}-a ${wl}archive' + lt_prog_compiler_static='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) @@ -8741,9 +9414,9 @@ lt_prog_compiler_static= lt_prog_compiler_static='-non_shared' ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. + # old Intel for x86_64, which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' @@ -8768,6 +9441,12 @@ lt_prog_compiler_static= lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) @@ -8865,7 +9544,7 @@ lt_prog_compiler_static= ;; sysv4*MP*) - if test -d /usr/nec ;then + if test -d /usr/nec; then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi @@ -8894,7 +9573,7 @@ lt_prog_compiler_static= fi case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: + # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; @@ -8926,7 +9605,7 @@ else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins @@ -8956,7 +9635,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } -if test x"$lt_cv_prog_compiler_pic_works" = xyes; then +if test yes = "$lt_cv_prog_compiler_pic_works"; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; @@ -8988,7 +9667,7 @@ if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no - save_LDFLAGS="$LDFLAGS" + save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then @@ -9007,13 +9686,13 @@ else fi fi $RM -r conftest* - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } -if test x"$lt_cv_prog_compiler_static_works" = xyes; then +if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= @@ -9133,8 +9812,8 @@ $as_echo "$lt_cv_prog_compiler_c_o" >&6; } -hard_links="nottested" -if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } @@ -9146,9 +9825,9 @@ $as_echo_n "checking if we can lock with hard links... " >&6; } ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } - if test "$hard_links" = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 -$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else @@ -9191,9 +9870,9 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if @@ -9208,7 +9887,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. - if test "$GCC" != yes; then + if test yes != "$GCC"; then with_gnu_ld=no fi ;; @@ -9216,7 +9895,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; - openbsd*) + openbsd* | bitrig*) with_gnu_ld=no ;; esac @@ -9226,7 +9905,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility @@ -9248,24 +9927,24 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie esac fi - if test "$lt_use_gnu_ld_interface" = yes; then + if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' + wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - export_dynamic_flag_spec='${wl}--export-dynamic' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + export_dynamic_flag_spec='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no - case `$LD -v 2>&1` in + case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... @@ -9278,7 +9957,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then + if test ia64 != "$host_cpu"; then ld_shlibs=no cat <<_LT_EOF 1>&2 @@ -9297,7 +9976,7 @@ _LT_EOF case $host_cpu in powerpc) # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) @@ -9313,7 +9992,7 @@ _LT_EOF allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME - archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs=no fi @@ -9323,7 +10002,7 @@ _LT_EOF # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' - export_dynamic_flag_spec='${wl}--export-all-symbols' + export_dynamic_flag_spec='$wl--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes @@ -9331,61 +10010,61 @@ _LT_EOF exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no - if test "$host_os" = linux-dietlibc; then + if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no + && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; @@ -9396,42 +10075,44 @@ _LT_EOF lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 - whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac - archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then + if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then + if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac @@ -9445,8 +10126,8 @@ _LT_EOF archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; @@ -9464,8 +10145,8 @@ _LT_EOF _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi @@ -9477,7 +10158,7 @@ _LT_EOF ld_shlibs=no cat <<_LT_EOF 1>&2 -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify @@ -9492,9 +10173,9 @@ _LT_EOF # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi @@ -9511,15 +10192,15 @@ _LT_EOF *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac - if test "$ld_shlibs" = no; then + if test no = "$ld_shlibs"; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= @@ -9535,7 +10216,7 @@ _LT_EOF # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported @@ -9543,12 +10224,12 @@ _LT_EOF ;; aix[4-9]*) - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' - no_entry_flag="" + no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm @@ -9566,7 +10247,7 @@ _LT_EOF # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi @@ -9589,13 +10270,13 @@ _LT_EOF hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes - file_list_spec='${wl}-f,' + file_list_spec='$wl-f,' - if test "$GCC" = yes; then + if test yes = "$GCC"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` + collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then @@ -9614,35 +10295,35 @@ _LT_EOF ;; esac shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' fi else # not using gcc - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' else - shared_flag='${wl}-bM:SRE' + shared_flag='$wl-bM:SRE' fi fi fi - export_dynamic_flag_spec='${wl}-bexpall' + export_dynamic_flag_spec='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes - if test "$aix_use_runtimelinking" = yes; then + if test yes = "$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. - if test "${lt_cv_aix_libpath+set}" = set; then + if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : @@ -9677,7 +10358,7 @@ fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_="/usr/lib:/lib" + lt_cv_aix_libpath_=/usr/lib:/lib fi fi @@ -9685,17 +10366,17 @@ fi aix_libpath=$lt_cv_aix_libpath_ fi - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. - if test "${lt_cv_aix_libpath+set}" = set; then + if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : @@ -9730,7 +10411,7 @@ fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_="/usr/lib:/lib" + lt_cv_aix_libpath_=/usr/lib:/lib fi fi @@ -9738,21 +10419,21 @@ fi aix_libpath=$lt_cv_aix_libpath_ fi - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. - no_undefined_flag=' ${wl}-bernotok' - allow_undefined_flag=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then + no_undefined_flag=' $wl-bernotok' + allow_undefined_flag=' $wl-berok' + if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. - whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $wl-bnoentry $compiler_flags $wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; @@ -9761,7 +10442,7 @@ fi case $host_cpu in powerpc) # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) @@ -9791,16 +10472,17 @@ fi # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" + shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes @@ -9809,18 +10491,18 @@ fi # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' ;; *) # Assume MSVC wrapper @@ -9829,7 +10511,7 @@ fi # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" + shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. @@ -9848,24 +10530,24 @@ fi hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported - if test "$lt_cv_ld_force_load" = "yes"; then - whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes - allow_undefined_flag="$_lt_dar_allow_undefined" + allow_undefined_flag=$_lt_dar_allow_undefined case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; + ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac - if test "$_lt_dar_can_shared" = "yes"; then + if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all - archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no @@ -9907,33 +10589,33 @@ fi ;; hpux9*) - if test "$GCC" = yes; then - archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + if test yes = "$GCC"; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else - archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes - export_dynamic_flag_spec='${wl}-E' + export_dynamic_flag_spec='$wl-E' ;; hpux10*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + if test yes,no = "$GCC,$with_gnu_ld"; then + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes - export_dynamic_flag_spec='${wl}-E' + export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes @@ -9941,25 +10623,25 @@ fi ;; hpux11*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then + if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) - archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) - archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) - archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) @@ -9971,7 +10653,7 @@ if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no - save_LDFLAGS="$LDFLAGS" + save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then @@ -9990,14 +10672,14 @@ else fi fi $RM -r conftest* - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } -if test x"$lt_cv_prog_compiler__b" = xyes; then - archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +if test yes = "$lt_cv_prog_compiler__b"; then + archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi @@ -10005,8 +10687,8 @@ fi ;; esac fi - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: case $host_cpu in @@ -10017,7 +10699,7 @@ fi *) hardcode_direct=yes hardcode_direct_absolute=yes - export_dynamic_flag_spec='${wl}-E' + export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. @@ -10028,8 +10710,8 @@ fi ;; irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + if test yes = "$GCC"; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. @@ -10039,8 +10721,8 @@ $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " > if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } @@ -10052,19 +10734,19 @@ else fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } - if test "$lt_cv_irix_exported_symbol" = yes; then - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + if test yes = "$lt_cv_irix_exported_symbol"; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi else - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes @@ -10084,7 +10766,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; @@ -10092,27 +10774,19 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } *nto* | *qnx*) ;; - openbsd*) + openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' else - case $host_os in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' fi else ld_shlibs=no @@ -10128,28 +10802,28 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } ;; osf3*) - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' else allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' @@ -10160,24 +10834,24 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } solaris*) no_undefined_flag=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + wlarc='$wl' + archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) - wlarc='${wl}' - archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + wlarc='$wl' + archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi @@ -10187,11 +10861,11 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', + # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + if test yes = "$GCC"; then + whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi @@ -10201,10 +10875,10 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } ;; sunos4*) - if test "x$host_vendor" = xsequent; then + if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. - archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi @@ -10253,43 +10927,43 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) - no_undefined_flag='${wl}-z,text' + no_undefined_flag='$wl-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not + # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. - no_undefined_flag='${wl}-z,text' - allow_undefined_flag='${wl}-z,nodefs' + no_undefined_flag='$wl-z,text' + allow_undefined_flag='$wl-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_flag_spec='$wl-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes - export_dynamic_flag_spec='${wl}-Bexport' + export_dynamic_flag_spec='$wl-Bexport' runpath_var='LD_RUN_PATH' - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; @@ -10304,10 +10978,10 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } ;; esac - if test x$host_vendor = xsni; then + if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - export_dynamic_flag_spec='${wl}-Blargedynsym' + export_dynamic_flag_spec='$wl-Blargedynsym' ;; esac fi @@ -10315,7 +10989,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } -test "$ld_shlibs" = no && can_build_shared=no +test no = "$ld_shlibs" && can_build_shared=no with_gnu_ld=$with_gnu_ld @@ -10341,7 +11015,7 @@ x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes - if test "$enable_shared" = yes && test "$GCC" = yes; then + if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. @@ -10556,14 +11230,14 @@ esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } -if test "$GCC" = yes; then +if test yes = "$GCC"; then case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in - mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; - *) lt_sed_strip_eq="s,=/,/,g" ;; + mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in @@ -10579,28 +11253,35 @@ if test "$GCC" = yes; then ;; esac # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary. + # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= - lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path/$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" - else + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; + lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } @@ -10614,7 +11295,7 @@ BEGIN {RS=" "; FS="/|\n";} { # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ - $SED 's,/\([A-Za-z]:\),\1,g'` ;; + $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else @@ -10623,7 +11304,7 @@ fi library_names_spec= libname_spec='lib$name' soname_spec= -shrext_cmds=".so" +shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= @@ -10643,11 +11324,11 @@ need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' + soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) @@ -10655,40 +11336,40 @@ aix[4-9]*) need_lib_prefix=no need_version=no hardcode_into_libs=yes - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then + if test yes = "$aix_use_runtimelinking"; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' fi shlibpath_var=LIBPATH fi @@ -10699,18 +11380,18 @@ amigaos*) powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) - library_names_spec='${libname}${shared_ext}' + library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; @@ -10718,8 +11399,8 @@ beos*) bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" @@ -10731,7 +11412,7 @@ bsdi[45]*) cygwin* | mingw* | pw32* | cegcc*) version_type=windows - shrext_cmds=".dll" + shrext_cmds=.dll need_version=no need_lib_prefix=no @@ -10740,8 +11421,8 @@ cygwin* | mingw* | pw32* | cegcc*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ @@ -10757,17 +11438,17 @@ cygwin* | mingw* | pw32* | cegcc*) case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' @@ -10776,8 +11457,8 @@ cygwin* | mingw* | pw32* | cegcc*) *,cl*) # Native MSVC libname_spec='$name' - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - library_names_spec='${libname}.dll.lib' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' case $build_os in mingw*) @@ -10804,7 +11485,7 @@ cygwin* | mingw* | pw32* | cegcc*) sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) - sys_lib_search_path_spec="$LIB" + sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` @@ -10817,8 +11498,8 @@ cygwin* | mingw* | pw32* | cegcc*) esac # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' @@ -10831,7 +11512,7 @@ cygwin* | mingw* | pw32* | cegcc*) *) # Assume MSVC wrapper - library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac @@ -10844,8 +11525,8 @@ darwin* | rhapsody*) version_type=darwin need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' @@ -10858,8 +11539,8 @@ dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; @@ -10877,12 +11558,12 @@ freebsd* | dragonfly*) version_type=freebsd-$objformat case $version_type in freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' need_version=no need_lib_prefix=no ;; freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac @@ -10907,26 +11588,15 @@ freebsd* | dragonfly*) esac ;; -gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=yes + shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; @@ -10944,9 +11614,9 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" @@ -10959,8 +11629,8 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; @@ -10969,8 +11639,8 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... @@ -10983,8 +11653,8 @@ interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no @@ -10995,7 +11665,7 @@ irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) - if test "$lt_cv_prog_gnu_ld" = yes; then + if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix @@ -11003,8 +11673,8 @@ irix5* | irix6* | nonstopux*) esac need_lib_prefix=no need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= @@ -11023,8 +11693,8 @@ irix5* | irix6* | nonstopux*) esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; @@ -11033,13 +11703,33 @@ linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec='-L$libdir' + ;; + # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no @@ -11083,14 +11773,10 @@ fi # before this can be enabled. hardcode_into_libs=yes - # Add ABI-specific directories to the system library path. - sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" - # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" - + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on @@ -11107,12 +11793,12 @@ netbsd*) need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH @@ -11122,7 +11808,7 @@ netbsd*) newsos6) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; @@ -11131,45 +11817,34 @@ newsos6) version_type=qnx need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; -openbsd*) +openbsd* | bitrig*) version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" + sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no else - shlibpath_overrides_runpath=yes + need_version=yes fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' - shrext_cmds=".dll" + shrext_cmds=.dll need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' + library_names_spec='$libname$shared_ext $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; @@ -11178,11 +11853,11 @@ osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) @@ -11193,8 +11868,8 @@ solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes @@ -11204,11 +11879,11 @@ solaris*) sunos4*) version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes @@ -11216,8 +11891,8 @@ sunos4*) sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) @@ -11238,10 +11913,10 @@ sysv4 | sysv4.3*) ;; sysv4*MP*) - if test -d /usr/nec ;then + if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; @@ -11250,12 +11925,12 @@ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' @@ -11273,7 +11948,7 @@ tpf*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes @@ -11281,8 +11956,8 @@ tpf*) uts4*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; @@ -11292,18 +11967,18 @@ uts4*) esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } -test "$dynamic_linker" = no && can_build_shared=no +test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then +if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi @@ -11402,15 +12077,15 @@ $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || - test "X$hardcode_automatic" = "Xyes" ; then + test yes = "$hardcode_automatic"; then # We can hardcode non-existent directories. - if test "$hardcode_direct" != no && + if test no != "$hardcode_direct" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && - test "$hardcode_minus_L" != no; then + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && + test no != "$hardcode_minus_L"; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else @@ -11425,12 +12100,12 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } -if test "$hardcode_action" = relink || - test "$inherit_rpath" = yes; then +if test relink = "$hardcode_action" || + test yes = "$inherit_rpath"; then # Fast installation is not supported enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi @@ -11440,7 +12115,7 @@ fi - if test "x$enable_dlopen" != xyes; then + if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown @@ -11450,23 +12125,23 @@ else case $host_os in beos*) - lt_cv_dlopen="load_add_on" + lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) - lt_cv_dlopen="dlopen" + lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) - # if libdl is installed we need to link against it + # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : @@ -11504,10 +12179,10 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else - lt_cv_dlopen="dyld" + lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes @@ -11515,10 +12190,18 @@ fi ;; + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : - lt_cv_dlopen="shl_load" + lt_cv_dlopen=shl_load else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } @@ -11557,11 +12240,11 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" + lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" + lt_cv_dlopen=dlopen else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } @@ -11600,7 +12283,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } @@ -11639,7 +12322,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } @@ -11678,7 +12361,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" + lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld fi @@ -11699,21 +12382,21 @@ fi ;; esac - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else + if test no = "$lt_cv_dlopen"; then enable_dlopen=no + else + enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - save_LDFLAGS="$LDFLAGS" + save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - save_LIBS="$LIBS" + save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 @@ -11721,7 +12404,7 @@ $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else - if test "$cross_compiling" = yes; then : + if test yes = "$cross_compiling"; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 @@ -11770,7 +12453,7 @@ else /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif @@ -11800,7 +12483,7 @@ _LT_EOF (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in @@ -11820,14 +12503,14 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } - if test "x$lt_cv_dlopen_self" = xyes; then + if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else - if test "$cross_compiling" = yes; then : + if test yes = "$cross_compiling"; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 @@ -11876,7 +12559,7 @@ else /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif @@ -11906,7 +12589,7 @@ _LT_EOF (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in @@ -11923,26 +12606,3214 @@ rm -fr conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 -$as_echo "$lt_cv_dlopen_self_static" >&6; } - fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report what library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test ia64 != "$host_cpu" && test no = "$aix_use_runtimelinking"; then + test yes = "$enable_shared" && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC=$lt_save_CC + + if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +reload_flag_CXX=$reload_flag +reload_cmds_CXX=$reload_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + compiler_CXX=$CC + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD=$ac_prog + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test yes = "$with_gnu_ld"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='$wl-f,' + + if test yes = "$GXX"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec_CXX='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test yes = "$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' $wl-bernotok' + allow_undefined_flag_CXX=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + fi + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $wl-bnoentry $compiler_flags $wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_CXX=' ' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=yes + file_list_spec_CXX='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' + enable_shared_with_static_runtimes_CXX=yes + # Don't use ranlib + old_postinstall_cmds_CXX='chmod 644 $oldlib' + postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + export_dynamic_flag_spec_CXX='$wl--export-all-symbols' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec_CXX='' + fi + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + if test yes != "$lt_cv_apple_cc_single_mod"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + haiku*) + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs_CXX=yes + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='$wl-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5].* | *pgcpp\ [1-5].*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='$wl-E' + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + no_undefined_flag_CXX=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='$wl-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='$wl-z,text' + allow_undefined_flag_CXX='$wl-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='$wl-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ + '"$old_archive_cmds_CXX" + reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ + '"$reload_cmds_CXX" + ;; + *) + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test no = "$ld_shlibs_CXX" && can_build_shared=no + + GCC_CXX=$GXX + LD_CXX=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX=$prev$p + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX=$prev$p + else + postdeps_CXX="${postdeps_CXX} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX=$p + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX=$p + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test yes != "$solaris_use_stlport4"; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test yes != "$solaris_use_stlport4"; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + + + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + lt_prog_compiler_pic_CXX='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } +lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + ;; + esac + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test no = "$ld_shlibs_CXX" && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc_CXX=no + else + lt_cv_archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } + archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test yes = "$aix_use_runtimelinking"; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec_CXX='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + shrext_cmds=.dll + need_lib_prefix=no + library_names_spec='$libname$shared_ext $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi @@ -11960,35 +15831,6 @@ fi -striplib= -old_striplib= -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 -$as_echo_n "checking whether stripping libraries is possible... " >&6; } -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - ;; - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - ;; - esac -fi @@ -12001,55 +15843,76 @@ fi - # Report which library types will actually be built - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 -$as_echo_n "checking if libtool supports shared libraries... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 -$as_echo "$can_build_shared" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 -$as_echo_n "checking whether to build shared libraries... " >&6; } - test "$can_build_shared" = "no" && enable_shared=no - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - aix[4-9]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 -$as_echo "$enable_shared" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 -$as_echo_n "checking whether to build static libraries... " >&6; } - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 -$as_echo "$enable_static" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test yes = "$hardcode_automatic_CXX"; then + # We can hardcode non-existent directories. + if test no != "$hardcode_direct_CXX" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && + test no != "$hardcode_minus_L_CXX"; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } +if test relink = "$hardcode_action_CXX" || + test yes = "$inherit_rpath_CXX"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -CC="$lt_save_CC" - @@ -12811,7 +16674,7 @@ fi cputype=`(((grep cpu /proc/cpuinfo | cut -d: -f2) ; ($PRTDIAG -v |grep -i sparc) ; grep -i cpu /var/run/dmesg.boot ) | head -n 1) 2> /dev/null` - cputype=`echo "$cputype" | tr -d ' -' |tr $as_cr_LETTERS $as_cr_letters` + cputype=`echo "$cputype" | tr -d ' -' | sed 's/SPARCIIi/SPARCII/' | tr $as_cr_LETTERS $as_cr_letters` case $cputype in *ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;; *ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;; @@ -13082,12 +16945,12 @@ fi if test "x$GCC" = "xyes"; then CFLAGS="$CFLAGS -fexceptions" - touch local.exp -else - cat > local.exp < local.exp <&5 @@ -13288,6 +17151,7 @@ fi TARGETDIR="unknown" +HAVE_LONG_DOUBLE_VARIANT=0 case "$host" in aarch64*-*-*) TARGET=AARCH64; TARGETDIR=aarch64 @@ -13299,6 +17163,10 @@ case "$host" in HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)' ;; + arc*-*-*) + TARGET=ARC; TARGETDIR=arc + ;; + arm*-*-*) TARGET=ARM; TARGETDIR=arm ;; @@ -13417,6 +17285,10 @@ case "$host" in TARGET=M68K; TARGETDIR=m68k ;; + m88k-*-*) + TARGET=M88K; TARGETDIR=m88k + ;; + microblaze*-*-*) TARGET=MICROBLAZE; TARGETDIR=microblaze ;; @@ -13432,14 +17304,19 @@ case "$host" in mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*) TARGET=MIPS_IRIX; TARGETDIR=mips ;; - mips*-*-linux* | mips*-*-openbsd*) + mips*-*linux* | mips*-*-openbsd*) # Support 128-bit long double for NewABI. HAVE_LONG_DOUBLE='defined(__mips64)' - TARGET=MIPS_IRIX; TARGETDIR=mips + TARGET=MIPS_LINUX; TARGETDIR=mips + ;; + + nios2*-linux*) + TARGET=NIOS2; TARGETDIR=nios2 ;; powerpc*-*-linux* | powerpc-*-sysv*) TARGET=POWERPC; TARGETDIR=powerpc + HAVE_LONG_DOUBLE_VARIANT=1 ;; powerpc-*-amigaos*) TARGET=POWERPC; TARGETDIR=powerpc @@ -13455,6 +17332,7 @@ case "$host" in ;; powerpc-*-freebsd* | powerpc-*-openbsd*) TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc + HAVE_LONG_DOUBLE_VARIANT=1 ;; powerpc64-*-freebsd*) TARGET=POWERPC; TARGETDIR=powerpc @@ -13482,6 +17360,10 @@ case "$host" in TARGET=TILE; TARGETDIR=tile ;; + vax-*-*) + TARGET=VAX; TARGETDIR=vax + ;; + xtensa*-*) TARGET=XTENSA; TARGETDIR=xtensa ;; @@ -13559,6 +17441,22 @@ else X86_DARWIN_FALSE= fi + if test x$TARGET = xX86_DARWIN && test $ac_cv_sizeof_size_t = 4; then + X86_DARWIN32_TRUE= + X86_DARWIN32_FALSE='#' +else + X86_DARWIN32_TRUE='#' + X86_DARWIN32_FALSE= +fi + + if test x$TARGET = xX86_DARWIN && test $ac_cv_sizeof_size_t = 8; then + X86_DARWIN64_TRUE= + X86_DARWIN64_FALSE='#' +else + X86_DARWIN64_TRUE='#' + X86_DARWIN64_FALSE= +fi + if test x$TARGET = xALPHA; then ALPHA_TRUE= ALPHA_FALSE='#' @@ -13591,6 +17489,14 @@ else M68K_FALSE= fi + if test x$TARGET = xM88K; then + M88K_TRUE= + M88K_FALSE='#' +else + M88K_TRUE='#' + M88K_FALSE= +fi + if test x$TARGET = xMICROBLAZE; then MICROBLAZE_TRUE= MICROBLAZE_FALSE='#' @@ -13615,6 +17521,14 @@ else MOXIE_FALSE= fi + if test x$TARGET = xNIOS2; then + NIOS2_TRUE= + NIOS2_FALSE='#' +else + NIOS2_TRUE='#' + NIOS2_FALSE= +fi + if test x$TARGET = xPOWERPC; then POWERPC_TRUE= POWERPC_FALSE='#' @@ -13655,6 +17569,14 @@ else AARCH64_FALSE= fi + if test x$TARGET = xARC; then + ARC_TRUE= + ARC_FALSE='#' +else + ARC_TRUE='#' + ARC_FALSE= +fi + if test x$TARGET = xARM; then ARM_TRUE= ARM_FALSE='#' @@ -13751,6 +17673,14 @@ else TILE_FALSE= fi + if test x$TARGET = xVAX; then + VAX_TRUE= + VAX_FALSE='#' +else + VAX_TRUE='#' + VAX_FALSE= +fi + if test x$TARGET = xXTENSA; then XTENSA_TRUE= XTENSA_FALSE='#' @@ -14151,17 +18081,25 @@ _ACEOF # Also AC_SUBST this variable for ffi.h. if test -z "$HAVE_LONG_DOUBLE"; then HAVE_LONG_DOUBLE=0 - if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then - if test $ac_cv_sizeof_long_double != 0; then + if test $ac_cv_sizeof_long_double != 0; then + if test $HAVE_LONG_DOUBLE_VARIANT != 0; then + +$as_echo "#define HAVE_LONG_DOUBLE_VARIANT 1" >>confdefs.h + HAVE_LONG_DOUBLE=1 + else + if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then + HAVE_LONG_DOUBLE=1 $as_echo "#define HAVE_LONG_DOUBLE 1" >>confdefs.h + fi fi fi fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } if ${ac_cv_c_bigendian+:} false; then : @@ -14602,8 +18540,7 @@ $as_echo "#define FFI_MMAP_EXEC_EMUTRAMP_PAX 1" >>confdefs.h fi -if test x$TARGET = xX86_WIN64; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _ prefix in compiled symbols" >&5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _ prefix in compiled symbols" >&5 $as_echo_n "checking for _ prefix in compiled symbols... " >&6; } if ${lt_cv_sys_symbol_underscore+:} false; then : $as_echo_n "(cached) " >&6 @@ -14650,11 +18587,10 @@ $as_echo "$lt_cv_sys_symbol_underscore" >&6; } sys_symbol_underscore=$lt_cv_sys_symbol_underscore - if test "x$sys_symbol_underscore" = xyes; then +if test "x$sys_symbol_underscore" = xyes; then $as_echo "#define SYMBOL_UNDERSCORE 1" >>confdefs.h - fi fi FFI_EXEC_TRAMPOLINE_TABLE=0 @@ -14682,16 +18618,32 @@ fi if test x$TARGET = xX86_64; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler supports unwind section type" >&5 -$as_echo_n "checking assembler supports unwind section type... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking toolchain supports unwind section type" >&5 +$as_echo_n "checking toolchain supports unwind section type... " >&6; } if ${libffi_cv_as_x86_64_unwind_section_type+:} false; then : $as_echo_n "(cached) " >&6 else - libffi_cv_as_x86_64_unwind_section_type=yes - echo '.section .eh_frame,"a",@unwind' > conftest.s - if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then - libffi_cv_as_x86_64_unwind_section_type=no + cat > conftest1.s << EOF +.text +.globl foo +foo: +jmp bar +.section .eh_frame,"a",@unwind +bar: +EOF + + cat > conftest2.c << EOF +extern void foo(); +int main(){foo();} +EOF + + libffi_cv_as_x86_64_unwind_section_type=no + # we ensure that we can compile _and_ link an assembly file containing an @unwind section + # since the compiler can support it and not the linker (ie old binutils) + if $CC -Wa,--fatal-warnings $CFLAGS -c conftest1.s > /dev/null 2>&1 && \ + $CC conftest2.c conftest1.o > /dev/null 2>&1 ; then + libffi_cv_as_x86_64_unwind_section_type=yes fi fi @@ -14844,7 +18796,7 @@ if test "x$GCC" = "xyes"; then toolexecdir='$(libdir)/gcc-lib/$(target_alias)' toolexeclibdir='$(libdir)' fi - multi_os_directory=`$CC -print-multi-os-directory` + multi_os_directory=`$CC $CFLAGS -print-multi-os-directory` case $multi_os_directory in .) ;; # Avoid trailing /. ../*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;; @@ -15005,6 +18957,10 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -15049,6 +19005,14 @@ if test -z "${X86_DARWIN_TRUE}" && test -z "${X86_DARWIN_FALSE}"; then as_fn_error $? "conditional \"X86_DARWIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${X86_DARWIN32_TRUE}" && test -z "${X86_DARWIN32_FALSE}"; then + as_fn_error $? "conditional \"X86_DARWIN32\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${X86_DARWIN64_TRUE}" && test -z "${X86_DARWIN64_FALSE}"; then + as_fn_error $? "conditional \"X86_DARWIN64\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${ALPHA_TRUE}" && test -z "${ALPHA_FALSE}"; then as_fn_error $? "conditional \"ALPHA\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -15065,6 +19029,10 @@ if test -z "${M68K_TRUE}" && test -z "${M68K_FALSE}"; then as_fn_error $? "conditional \"M68K\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${M88K_TRUE}" && test -z "${M88K_FALSE}"; then + as_fn_error $? "conditional \"M88K\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MICROBLAZE_TRUE}" && test -z "${MICROBLAZE_FALSE}"; then as_fn_error $? "conditional \"MICROBLAZE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -15077,6 +19045,10 @@ if test -z "${MOXIE_TRUE}" && test -z "${MOXIE_FALSE}"; then as_fn_error $? "conditional \"MOXIE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${NIOS2_TRUE}" && test -z "${NIOS2_FALSE}"; then + as_fn_error $? "conditional \"NIOS2\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${POWERPC_TRUE}" && test -z "${POWERPC_FALSE}"; then as_fn_error $? "conditional \"POWERPC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -15097,6 +19069,10 @@ if test -z "${AARCH64_TRUE}" && test -z "${AARCH64_FALSE}"; then as_fn_error $? "conditional \"AARCH64\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${ARC_TRUE}" && test -z "${ARC_FALSE}"; then + as_fn_error $? "conditional \"ARC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${ARM_TRUE}" && test -z "${ARM_FALSE}"; then as_fn_error $? "conditional \"ARM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -15145,6 +19121,10 @@ if test -z "${TILE_TRUE}" && test -z "${TILE_FALSE}"; then as_fn_error $? "conditional \"TILE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${VAX_TRUE}" && test -z "${VAX_FALSE}"; then + as_fn_error $? "conditional \"VAX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${XTENSA_TRUE}" && test -z "${XTENSA_FALSE}"; then as_fn_error $? "conditional \"XTENSA\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -15559,7 +19539,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libffi $as_me 3.0.13, which was +This file was extended by libffi $as_me 3.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -15629,7 +19609,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -libffi config.status 3.0.13 +libffi config.status 3.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -15821,8 +19801,10 @@ compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' @@ -15896,6 +19878,60 @@ enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_sub enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' +predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' +predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' +postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' +reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' +reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' @@ -15940,8 +19976,10 @@ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_import \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +lt_cv_nm_interface \ nm_file_list_spec \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ @@ -15974,10 +20012,41 @@ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ -striplib; do +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +reload_flag_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_separator_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" @@ -16004,10 +20073,21 @@ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ -sys_lib_dlsearch_path_spec; do +sys_lib_dlsearch_path_spec \ +reload_cmds_CXX \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX \ +postlink_cmds_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" @@ -16016,24 +20096,23 @@ sys_lib_dlsearch_path_spec; do done ac_aux_dir='$ac_aux_dir' -xsi_shell='$xsi_shell' -lt_shell_append='$lt_shell_append' -# See if we are running on zsh, and set the options which allow our +# See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then +if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile' + + TARGETDIR="$TARGETDIR" _ACEOF @@ -16831,7 +20910,7 @@ $as_echo "$as_me: build in $ax_enable_builddir (HOST=$ax_enable_builddir_host)" fi ;; "depfiles":C) test x"$AMDEP_TRUE" != x"" || { - # Autoconf 2.62 quotes --file arguments for eval, but not when files + # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in @@ -16882,7 +20961,7 @@ $as_echo X"$mf" | DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue + test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the @@ -16925,13 +21004,13 @@ $as_echo X"$file" | ;; "libtool":C) - # See if we are running on zsh, and set the options which allow our + # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then + if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi - cfgfile="${ofile}T" + cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" @@ -16939,7 +21018,7 @@ $as_echo X"$file" | #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Generated automatically by $as_me ($PACKAGE) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # @@ -16973,7 +21052,7 @@ $as_echo X"$file" | # The names of the tagged configurations supported by this script. -available_tags="" +available_tags='CXX ' # ### BEGIN LIBTOOL CONFIG @@ -17110,16 +21189,22 @@ global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl +# Transform the output of nm into a list of symbols to manually relocate. +global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import + # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix +# The name lister interface. +nm_interface=$lt_lt_cv_nm_interface + # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec -# The root where to search for dependent libraries,and in which our libraries should be installed. +# The root where to search for dependent libraries,and where our libraries should be installed. lt_sysroot=$lt_sysroot # The name of the directory that contains temporary libtool files. @@ -17306,13 +21391,13 @@ hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is -# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute @@ -17360,6 +21445,20 @@ file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + # ### END LIBTOOL CONFIG _LT_EOF @@ -17370,7 +21469,7 @@ _LT_EOF # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then +if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi @@ -17379,7 +21478,7 @@ _LT_EOF esac -ltmain="$ac_aux_dir/ltmain.sh" +ltmain=$ac_aux_dir/ltmain.sh # We use sed instead of cat because bash on DJGPP gets confused if @@ -17389,169 +21488,163 @@ ltmain="$ac_aux_dir/ltmain.sh" sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) - if test x"$xsi_shell" = xyes; then - sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ -func_dirname ()\ -{\ -\ case ${1} in\ -\ */*) func_dirname_result="${1%/*}${2}" ;;\ -\ * ) func_dirname_result="${3}" ;;\ -\ esac\ -} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_basename ()$/,/^} # func_basename /c\ -func_basename ()\ -{\ -\ func_basename_result="${1##*/}"\ -} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ -func_dirname_and_basename ()\ -{\ -\ case ${1} in\ -\ */*) func_dirname_result="${1%/*}${2}" ;;\ -\ * ) func_dirname_result="${3}" ;;\ -\ esac\ -\ func_basename_result="${1##*/}"\ -} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ -func_stripname ()\ -{\ -\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ -\ # positional parameters, so assign one to ordinary parameter first.\ -\ func_stripname_result=${3}\ -\ func_stripname_result=${func_stripname_result#"${1}"}\ -\ func_stripname_result=${func_stripname_result%"${2}"}\ -} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ -func_split_long_opt ()\ -{\ -\ func_split_long_opt_name=${1%%=*}\ -\ func_split_long_opt_arg=${1#*=}\ -} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ -func_split_short_opt ()\ -{\ -\ func_split_short_opt_arg=${1#??}\ -\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ -} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ -func_lo2o ()\ -{\ -\ case ${1} in\ -\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ -\ *) func_lo2o_result=${1} ;;\ -\ esac\ -} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_xform ()$/,/^} # func_xform /c\ -func_xform ()\ -{\ - func_xform_result=${1%.*}.lo\ -} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_arith ()$/,/^} # func_arith /c\ -func_arith ()\ -{\ - func_arith_result=$(( $* ))\ -} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_len ()$/,/^} # func_len /c\ -func_len ()\ -{\ - func_len_result=${#1}\ -} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - -fi - -if test x"$lt_shell_append" = xyes; then - sed -e '/^func_append ()$/,/^} # func_append /c\ -func_append ()\ -{\ - eval "${1}+=\\${2}"\ -} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ -func_append_quoted ()\ -{\ -\ func_quote_for_eval "${2}"\ -\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ -} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - # Save a `func_append' function call where possible by direct use of '+=' - sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -else - # Save a `func_append' function call even when '+=' is not available - sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -fi - -if test x"$_lt_function_replace_fail" = x":"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 -$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} -fi - - mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_CXX +reload_cmds=$lt_reload_cmds_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + ;; "include":C) test -d include || mkdir include ;; "src":C) diff --git a/Modules/_ctypes/libffi/configure.ac b/Modules/_ctypes/libffi/configure.ac index 7fe5ff5f8d80..5c8885fa634b 100644 --- a/Modules/_ctypes/libffi/configure.ac +++ b/Modules/_ctypes/libffi/configure.ac @@ -5,13 +5,17 @@ dnl Process this with autoconf to create configure AC_PREREQ(2.68) -AC_INIT([libffi], [3.0.13], [http://github.com/atgreen/libffi/issues]) +AC_INIT([libffi], [3.1], [http://github.com/atgreen/libffi/issues]) AC_CONFIG_HEADERS([fficonfig.h]) AC_CANONICAL_SYSTEM target_alias=${target_alias-$host_alias} -. ${srcdir}/configure.host +case "${host}" in + frv*-elf) + LDFLAGS=`echo $LDFLAGS | sed "s/\-B[^ ]*libgloss\/frv\///"`\ -B`pwd`/../libgloss/frv/ + ;; +esac AX_ENABLE_BUILDDIR @@ -28,6 +32,7 @@ m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS]) m4_define([_AC_ARG_VAR_PRECIOUS],[]) save_CFLAGS=$CFLAGS AC_PROG_CC +AC_PROG_CXX CFLAGS=$save_CFLAGS m4_undefine([_AC_ARG_VAR_PRECIOUS]) m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS]) @@ -52,12 +57,12 @@ fi if test "x$GCC" = "xyes"; then CFLAGS="$CFLAGS -fexceptions" - touch local.exp -else - cat > local.exp < local.exp < conftest.s - if $CC $CFLAGS -c conftest.s 2>&1 | grep -i warning > /dev/null; then - libffi_cv_as_x86_64_unwind_section_type=no + cat > conftest1.s << EOF +.text +.globl foo +foo: +jmp bar +.section .eh_frame,"a",@unwind +bar: +EOF + + cat > conftest2.c << EOF +extern void foo(); +int main(){foo();} +EOF + + libffi_cv_as_x86_64_unwind_section_type=no + # we ensure that we can compile _and_ link an assembly file containing an @unwind section + # since the compiler can support it and not the linker (ie old binutils) + if $CC -Wa,--fatal-warnings $CFLAGS -c conftest1.s > /dev/null 2>&1 && \ + $CC conftest2.c conftest1.o > /dev/null 2>&1 ; then + libffi_cv_as_x86_64_unwind_section_type=yes fi ]) if test "x$libffi_cv_as_x86_64_unwind_section_type" = xyes; then @@ -526,14 +575,14 @@ AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes") AC_ARG_ENABLE(structs, [ --disable-structs omit code for struct support], if test "$enable_structs" = "no"; then - AC_DEFINE(FFI_NO_STRUCTS, 1, [Define this is you do not want support for aggregate types.]) + AC_DEFINE(FFI_NO_STRUCTS, 1, [Define this if you do not want support for aggregate types.]) fi) AM_CONDITIONAL(FFI_DEBUG, test "$enable_debug" = "yes") AC_ARG_ENABLE(raw-api, [ --disable-raw-api make the raw api unavailable], if test "$enable_raw_api" = "no"; then - AC_DEFINE(FFI_NO_RAW_API, 1, [Define this is you do not want support for the raw API.]) + AC_DEFINE(FFI_NO_RAW_API, 1, [Define this if you do not want support for the raw API.]) fi) AC_ARG_ENABLE(purify-safety, @@ -553,7 +602,7 @@ if test "x$GCC" = "xyes"; then toolexecdir='$(libdir)/gcc-lib/$(target_alias)' toolexeclibdir='$(libdir)' fi - multi_os_directory=`$CC -print-multi-os-directory` + multi_os_directory=`$CC $CFLAGS -print-multi-os-directory` case $multi_os_directory in .) ;; # Avoid trailing /. ../*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;; diff --git a/Modules/_ctypes/libffi/configure.host b/Modules/_ctypes/libffi/configure.host deleted file mode 100644 index f52457b39fd4..000000000000 --- a/Modules/_ctypes/libffi/configure.host +++ /dev/null @@ -1,11 +0,0 @@ -# configure.host -# -# This shell script handles all host based configuration for libffi. -# - -# THIS TABLE IS SORTED. KEEP IT THAT WAY. -case "${host}" in - frv*-elf) - LDFLAGS=`echo $LDFLAGS | sed "s/\-B[^ ]*libgloss\/frv\///"`\ -B`pwd`/../libgloss/frv/ - ;; -esac diff --git a/Modules/_ctypes/libffi/depcomp b/Modules/_ctypes/libffi/depcomp index df8eea7e4ce8..4ebd5b3a2f2d 100755 --- a/Modules/_ctypes/libffi/depcomp +++ b/Modules/_ctypes/libffi/depcomp @@ -1,10 +1,9 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2009-04-28.21; # UTC +scriptversion=2013-05-30.07; # UTC -# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free -# Software Foundation, Inc. +# Copyright (C) 1999-2013 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -28,9 +27,9 @@ scriptversion=2009-04-28.21; # UTC case $1 in '') - echo "$0: No command. Try \`$0 --help' for more information." 1>&2 - exit 1; - ;; + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] @@ -40,11 +39,11 @@ as side-effects. Environment variables: depmode Dependency tracking mode. - source Source file read by `PROGRAMS ARGS'. - object Object file output by `PROGRAMS ARGS'. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. - tmpdepfile Temporary file to use when outputing dependencies. + tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . @@ -57,6 +56,66 @@ EOF ;; esac +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 @@ -69,6 +128,9 @@ tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" +# Avoid interferences from the environment. +gccflag= dashmflag= + # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case @@ -80,18 +142,32 @@ if test "$depmode" = hp; then fi if test "$depmode" = dashXmstdout; then - # This is just like dashmstdout with a different argument. - dashmflag=-xM - depmode=dashmstdout + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then - # This is just like msvisualcpp but w/o cygpath translation. - # Just convert the backslash-escaped backslashes to single forward - # slashes to satisfy depend.m4 - cygpath_u="sed s,\\\\\\\\,/,g" - depmode=msvisualcpp + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc fi case "$depmode" in @@ -114,8 +190,7 @@ gcc3) done "$@" stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -123,13 +198,17 @@ gcc3) ;; gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like -## -MM, not -M (despite what the docs say). +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then @@ -137,31 +216,31 @@ gcc) fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" - alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz -## The second -e expression handles DOS-style file names with drive letters. + # The second -e expression handles DOS-style file names with drive + # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" -## This next piece of magic avoids the `deleted header file' problem. +## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. - tr ' ' ' -' < "$tmpdepfile" | -## Some versions of gcc put a space before the `:'. On the theory +## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as -## well. +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -179,8 +258,7 @@ sgi) "$@" -MDupdate "$tmpdepfile" fi stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -188,43 +266,41 @@ sgi) if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" - # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; - # the IRIX cc adds comments like `#:fec' to the end of the + # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ - tr ' -' ' ' >> "$depfile" + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" - # The second pass generates a dummy entry for each header file. - tr ' ' ' -' < "$tmpdepfile" \ - | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ - >> "$depfile" + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" + make_dummy_depfile fi rm -f "$tmpdepfile" ;; +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the - # current directory. Also, the AIX compiler puts `$object:' at the + # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + set_dir_from "$object" + set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u @@ -237,9 +313,7 @@ aix) "$@" -M fi stat=$? - - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi @@ -248,44 +322,100 @@ aix) do test -f "$tmpdepfile" && break done - if test -f "$tmpdepfile"; then - # Each line is of the form `foo.o: dependent.h'. - # Do two passes, one to just change these to - # `$object: dependent.h' and one to simply `dependent.h:'. - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - # The sourcefile does not contain any dependencies, so just - # store a dummy comment line, to avoid errors with the Makefile - # "include basename.Plo" scheme. - echo "#dummy" > "$depfile" + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; -icc) - # Intel's C compiler understands `-MD -MF file'. However on - # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c - # ICC 7.0 will fill foo.d with something like - # foo.o: sub/foo.c - # foo.o: sub/foo.h - # which is wrong. We want: - # sub/foo.o: sub/foo.c - # sub/foo.o: sub/foo.h - # sub/foo.c: - # sub/foo.h: - # ICC 7.1 will output +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h - # and will wrap long lines using \ : + # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi - "$@" -MD -MF "$tmpdepfile" - stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi @@ -297,8 +427,8 @@ icc) sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. - sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | - sed -e 's/$/ :/' >> "$depfile" + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -309,9 +439,8 @@ hp2) # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + set_dir_from "$object" + set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d @@ -322,8 +451,7 @@ hp2) "$@" +Maked fi stat=$? - if test $stat -eq 0; then : - else + if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi @@ -333,77 +461,107 @@ hp2) test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" - # Add `dependent.h:' lines. + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. sed -ne '2,${ - s/^ *// - s/ \\*$// - s/$/:/ - p - }' "$tmpdepfile" >> "$depfile" + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" else - echo "#dummy" > "$depfile" + make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) - # The Tru64 compiler uses -MD to generate dependencies as a side - # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. - # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put - # dependencies in `foo.d' instead, so we check for that too. - # Subdirectories are respected. - dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` - test "x$dir" = "x$object" && dir= - base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` - - if test "$libtool" = yes; then - # With Tru64 cc, shared objects can also be used to make a - # static library. This mechanism is used in libtool 1.4 series to - # handle both shared and static libraries in a single compilation. - # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. - # - # With libtool 1.5 this exception was removed, and libtool now - # generates 2 separate objects for the 2 libraries. These two - # compilations output dependencies in $dir.libs/$base.o.d and - # in $dir$base.o.d. We have to check for both files, because - # one of the two compilations can be disabled. We should prefer - # $dir$base.o.d over $dir.libs/$base.o.d because the latter is - # automatically cleaned when .libs/ is deleted, while ignoring - # the former would cause a distcleancheck panic. - tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 - tmpdepfile2=$dir$base.o.d # libtool 1.5 - tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 - tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 - "$@" -Wc,-MD - else - tmpdepfile1=$dir$base.o.d - tmpdepfile2=$dir$base.d - tmpdepfile3=$dir$base.d - tmpdepfile4=$dir$base.d - "$@" -MD - fi - - stat=$? - if test $stat -eq 0; then : - else - rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - exit $stat - fi - - for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" - do - test -f "$tmpdepfile" && break - done - if test -f "$tmpdepfile"; then - sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" - # That's a tab and a space in the []. - sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" - else - echo "#dummy" > "$depfile" - fi - rm -f "$tmpdepfile" - ;; + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; #nosideeffect) # This comment above is used by automake to tell side-effect @@ -422,7 +580,7 @@ dashmstdout) shift fi - # Remove `-o $object'. + # Remove '-o $object'. IFS=" " for arg do @@ -442,18 +600,18 @@ dashmstdout) done test -z "$dashmflag" && dashmflag=-M - # Require at least two characters before searching for `:' + # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: - # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | - sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" - tr ' ' ' -' < "$tmpdepfile" | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; @@ -503,12 +661,15 @@ makedepend) touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" - cat < "$tmpdepfile" > "$depfile" - sed '1,2d' "$tmpdepfile" | tr ' ' ' -' | \ -## Some versions of the HPUX 10.20 sed can't process this invocation -## correctly. Breaking it into two sed invocations is a workaround. - sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; @@ -525,7 +686,7 @@ cpp) shift fi - # Remove `-o $object'. + # Remove '-o $object'. IFS=" " for arg do @@ -544,10 +705,10 @@ cpp) esac done - "$@" -E | - sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ - -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | - sed '$ s: \\$::' > "$tmpdepfile" + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" @@ -579,23 +740,23 @@ msvisualcpp) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") - set fnord "$@" - shift - shift - ;; + set fnord "$@" + shift + shift + ;; *) - set fnord "$@" "$arg" - shift - shift - ;; + set fnord "$@" "$arg" + shift + shift + ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" - sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" - echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; diff --git a/Modules/_ctypes/libffi/doc/libffi.info b/Modules/_ctypes/libffi/doc/libffi.info index 6d5acf830ac9..3990939473b5 100644 --- a/Modules/_ctypes/libffi/doc/libffi.info +++ b/Modules/_ctypes/libffi/doc/libffi.info @@ -1,5 +1,4 @@ -This is ../libffi/doc/libffi.info, produced by makeinfo version 4.13 -from ../libffi/doc/libffi.texi. +This is libffi.info, produced by makeinfo version 5.1 from libffi.texi. This manual is for Libffi, a portable foreign-function interface library. @@ -8,10 +7,9 @@ library. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or - (at your option) any later version. A copy of the license is - included in the section entitled "GNU General Public License". - + published by the Free Software Foundation; either version 2, or (at + your option) any later version. A copy of the license is included + in the section entitled "GNU General Public License". INFO-DIR-SECTION Development START-INFO-DIR-ENTRY @@ -31,10 +29,9 @@ library. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or - (at your option) any later version. A copy of the license is - included in the section entitled "GNU General Public License". - + published by the Free Software Foundation; either version 2, or (at + your option) any later version. A copy of the license is included + in the section entitled "GNU General Public License". * Menu: @@ -56,25 +53,25 @@ The calling convention is 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. The calling convention is also sometimes called the "ABI" or -"Application Binary Interface". +"Application Binary Interface". 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 +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 + 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. +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.  File: libffi.info, Node: Using libffi, Next: Missing Features, Prev: Introduction, Up: Top @@ -97,45 +94,45 @@ File: libffi.info, Node: The Basics, Next: Simple Example, Up: Using libffi 2.1 The Basics ============== -`Libffi' assumes that you have a pointer to the function you wish to +'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 + The first thing you must do is create an 'ffi_cif' object that matches the signature of the function you wish to call. This is a -separate step because it is common to make multiple calls using a -single `ffi_cif'. The "cif" in `ffi_cif' stands for Call InterFace. -To prepare a call interface object, use the function `ffi_prep_cif'. +separate step because it is common to make multiple calls using a single +'ffi_cif'. The "cif" in 'ffi_cif' stands for Call InterFace. To +prepare a call interface object, use the function 'ffi_prep_cif'. -- Function: ffi_status ffi_prep_cif (ffi_cif *CIF, ffi_abi ABI, unsigned int NARGS, ffi_type *RTYPE, ffi_type **ARGTYPES) This initializes CIF according to the given parameters. - ABI is the ABI to use; normally `FFI_DEFAULT_ABI' is what you - want. *note Multiple ABIs:: for more information. + ABI is the ABI to use; normally 'FFI_DEFAULT_ABI' is what you want. + *note Multiple ABIs:: for more information. NARGS is the number of arguments that this function accepts. - RTYPE is a pointer to an `ffi_type' structure that describes the + RTYPE is a pointer to an 'ffi_type' structure that describes the return type of the function. *Note Types::. - ARGTYPES is a vector of `ffi_type' pointers. ARGTYPES must have + ARGTYPES is a vector of 'ffi_type' pointers. ARGTYPES must have NARGS elements. If NARGS is 0, this argument is ignored. - `ffi_prep_cif' returns a `libffi' status code, of type - `ffi_status'. This will be either `FFI_OK' if everything worked - properly; `FFI_BAD_TYPEDEF' if one of the `ffi_type' objects is - incorrect; or `FFI_BAD_ABI' if the ABI parameter is invalid. + 'ffi_prep_cif' returns a 'libffi' status code, of type + 'ffi_status'. This will be either 'FFI_OK' if everything worked + properly; 'FFI_BAD_TYPEDEF' if one of the 'ffi_type' objects is + incorrect; or 'FFI_BAD_ABI' if the ABI parameter is invalid. If the function being called is variadic (varargs) then -`ffi_prep_cif_var' must be used instead of `ffi_prep_cif'. +'ffi_prep_cif_var' must be used instead of 'ffi_prep_cif'. - -- Function: ffi_status ffi_prep_cif_var (ffi_cif *CIF, ffi_abi - varabi, unsigned int NFIXEDARGS, unsigned int varntotalargs, - ffi_type *RTYPE, ffi_type **ARGTYPES) + -- Function: ffi_status ffi_prep_cif_var (ffi_cif *CIF, ffi_abi varabi, + unsigned int NFIXEDARGS, unsigned int varntotalargs, ffi_type + *RTYPE, ffi_type **ARGTYPES) This initializes CIF according to the given parameters for a call to a variadic function. In general it's operation is the same as - for `ffi_prep_cif' except that: + for 'ffi_prep_cif' except that: NFIXEDARGS is the number of fixed arguments, prior to any variadic arguments. It must be greater than zero. @@ -146,27 +143,26 @@ To prepare a call interface object, use the function `ffi_prep_cif'. Note that, different cif's must be prepped for calls to the same function when different numbers of arguments are passed. - Also note that a call to `ffi_prep_cif_var' with + Also note that a call to 'ffi_prep_cif_var' with NFIXEDARGS=NOTOTALARGS is NOT equivalent to a call to - `ffi_prep_cif'. + 'ffi_prep_cif'. - - To call a function using an initialized `ffi_cif', use the -`ffi_call' function: + To call a function using an initialized 'ffi_cif', use the 'ffi_call' +function: -- Function: void ffi_call (ffi_cif *CIF, void *FN, void *RVALUE, void **AVALUES) This calls the function FN according to the description given in - CIF. CIF must have already been prepared using `ffi_prep_cif'. + CIF. CIF must have already been prepared using 'ffi_prep_cif'. RVALUE is a pointer to a chunk of memory that will hold the result of the function call. This must be large enough to hold the - result and must be suitably aligned; it is the caller's + result, no smaller than the system register size (generally 32 or + 64 bits), and must be suitably aligned; it is the caller's responsibility to ensure this. If CIF declares that the function - returns `void' (using `ffi_type_void'), then RVALUE is ignored. - If RVALUE is `NULL', then the return value is discarded. + returns 'void' (using 'ffi_type_void'), then RVALUE is ignored. - AVALUES is a vector of `void *' pointers that point to the memory + AVALUES is a vector of 'void *' pointers that point to the memory locations holding the argument values for a call. If CIF declares that the function has no arguments (i.e., NARGS was 0), then AVALUES is ignored. Note that argument values may be modified by @@ -179,7 +175,7 @@ File: libffi.info, Node: Simple Example, Next: Types, Prev: The Basics, Up: 2.2 Simple Example ================== -Here is a trivial example that calls `puts' a few times. +Here is a trivial example that calls 'puts' a few times. #include #include @@ -190,7 +186,7 @@ Here is a trivial example that calls `puts' a few times. ffi_type *args[1]; void *values[1]; char *s; - int rc; + ffi_arg rc; /* Initialize the argument info vectors */ args[0] = &ffi_type_pointer; @@ -198,7 +194,7 @@ Here is a trivial example that calls `puts' a few times. /* Initialize the cif */ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_uint, args) == FFI_OK) + &ffi_type_sint, args) == FFI_OK) { s = "Hello World!"; ffi_call(&cif, puts, &rc, values); @@ -232,80 +228,80 @@ File: libffi.info, Node: Primitive Types, Next: Structures, Up: Types 2.3.1 Primitive Types --------------------- -`Libffi' provides a number of built-in type descriptors that can be -used to describe argument and return types: +'Libffi' provides a number of built-in type descriptors that can be used +to describe argument and return types: -`ffi_type_void' - The type `void'. This cannot be used for argument types, only for +'ffi_type_void' + The type 'void'. This cannot be used for argument types, only for return values. -`ffi_type_uint8' +'ffi_type_uint8' An unsigned, 8-bit integer type. -`ffi_type_sint8' +'ffi_type_sint8' A signed, 8-bit integer type. -`ffi_type_uint16' +'ffi_type_uint16' An unsigned, 16-bit integer type. -`ffi_type_sint16' +'ffi_type_sint16' A signed, 16-bit integer type. -`ffi_type_uint32' +'ffi_type_uint32' An unsigned, 32-bit integer type. -`ffi_type_sint32' +'ffi_type_sint32' A signed, 32-bit integer type. -`ffi_type_uint64' +'ffi_type_uint64' An unsigned, 64-bit integer type. -`ffi_type_sint64' +'ffi_type_sint64' A signed, 64-bit integer type. -`ffi_type_float' - The C `float' type. +'ffi_type_float' + The C 'float' type. -`ffi_type_double' - The C `double' type. +'ffi_type_double' + The C 'double' type. -`ffi_type_uchar' - The C `unsigned char' type. +'ffi_type_uchar' + The C 'unsigned char' type. -`ffi_type_schar' - The C `signed char' type. (Note that there is not an exact - equivalent to the C `char' type in `libffi'; ordinarily you should - either use `ffi_type_schar' or `ffi_type_uchar' depending on - whether `char' is signed.) +'ffi_type_schar' + The C 'signed char' type. (Note that there is not an exact + equivalent to the C 'char' type in 'libffi'; ordinarily you should + either use 'ffi_type_schar' or 'ffi_type_uchar' depending on + whether 'char' is signed.) -`ffi_type_ushort' - The C `unsigned short' type. +'ffi_type_ushort' + The C 'unsigned short' type. -`ffi_type_sshort' - The C `short' type. +'ffi_type_sshort' + The C 'short' type. -`ffi_type_uint' - The C `unsigned int' type. +'ffi_type_uint' + The C 'unsigned int' type. -`ffi_type_sint' - The C `int' type. +'ffi_type_sint' + The C 'int' type. -`ffi_type_ulong' - The C `unsigned long' type. +'ffi_type_ulong' + The C 'unsigned long' type. -`ffi_type_slong' - The C `long' type. +'ffi_type_slong' + The C 'long' type. -`ffi_type_longdouble' - On platforms that have a C `long double' type, this is defined. - On other platforms, it is not. +'ffi_type_longdouble' + On platforms that have a C 'long double' type, this is defined. On + other platforms, it is not. -`ffi_type_pointer' - A generic `void *' pointer. You should use this for all pointers, +'ffi_type_pointer' + A generic 'void *' pointer. You should use this for all pointers, regardless of their real type. - Each of these is of type `ffi_type', so you must take the address -when passing to `ffi_prep_cif'. + Each of these is of type 'ffi_type', so you must take the address +when passing to 'ffi_prep_cif'.  File: libffi.info, Node: Structures, Next: Type Example, Prev: Primitive Types, Up: Types @@ -313,24 +309,24 @@ File: libffi.info, Node: Structures, Next: Type Example, Prev: Primitive Type 2.3.2 Structures ---------------- -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 +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. -- Data type: ffi_type - The `ffi_type' has the following members: - `size_t size' - This is set by `libffi'; you should initialize it to zero. + The 'ffi_type' has the following members: + 'size_t size' + This is set by 'libffi'; you should initialize it to zero. - `unsigned short alignment' - This is set by `libffi'; you should initialize it to zero. + 'unsigned short alignment' + This is set by 'libffi'; you should initialize it to zero. - `unsigned short type' - For a structure, this should be set to `FFI_TYPE_STRUCT'. + 'unsigned short type' + For a structure, this should be set to 'FFI_TYPE_STRUCT'. - `ffi_type **elements' - This is a `NULL'-terminated array of pointers to `ffi_type' + 'ffi_type **elements' + This is a 'NULL'-terminated array of pointers to 'ffi_type' objects. There is one element per field of the struct.  @@ -339,8 +335,8 @@ File: libffi.info, Node: Type Example, Prev: Structures, Up: Types 2.3.3 Type Example ------------------ -The following example initializes a `ffi_type' object representing the -`tm' struct from Linux's `time.h'. +The following example initializes a 'ffi_type' object representing the +'tm' struct from Linux's 'time.h'. Here is how the struct is defined: @@ -359,7 +355,7 @@ The following example initializes a `ffi_type' object representing the __const char *__tm_zone__; }; - Here is the corresponding code to describe this struct to `libffi': + Here is the corresponding code to describe this struct to 'libffi': { ffi_type tm_type; @@ -367,6 +363,7 @@ The following example initializes a `ffi_type' object representing the int i; tm_type.size = tm_type.alignment = 0; + tm_type.type = FFI_TYPE_STRUCT; tm_type.elements = &tm_type_elements; for (i = 0; i < 9; i++) @@ -387,9 +384,9 @@ File: libffi.info, Node: Multiple ABIs, Next: The Closure API, Prev: Types, ================= A given platform may provide multiple different ABIs at once. For -instance, the x86 platform has both `stdcall' and `fastcall' functions. +instance, the x86 platform has both 'stdcall' and 'fastcall' functions. - `libffi' provides some support for this. However, this is + 'libffi' provides some support for this. However, this is necessarily platform-specific.  @@ -398,32 +395,32 @@ File: libffi.info, Node: The Closure API, Next: Closure Example, Prev: Multip 2.5 The Closure API =================== -`libffi' also provides a way to write a generic function - a function +'libffi' also provides a way to write a generic function - a function that can accept and decode any combination of arguments. This can be -useful when writing an interpreter, or to provide wrappers for -arbitrary functions. +useful when writing an interpreter, or to provide wrappers for arbitrary +functions. - This facility is called the "closure API". Closures are not -supported on all platforms; you can check the `FFI_CLOSURES' define to -determine whether they are supported on the current platform. + This facility is called the "closure API". Closures are not supported +on all platforms; you can check the 'FFI_CLOSURES' define to determine +whether they are supported on the current platform. Because closures work by assembling a tiny function at runtime, they -require special allocation on platforms that have a non-executable -heap. Memory management for closures is handled by a pair of functions: +require special allocation on platforms that have a non-executable heap. +Memory management for closures is handled by a pair of functions: -- Function: void *ffi_closure_alloc (size_t SIZE, void **CODE) Allocate a chunk of memory holding SIZE bytes. This returns a pointer to the writable address, and sets *CODE to the corresponding executable address. - SIZE should be sufficient to hold a `ffi_closure' object. + SIZE should be sufficient to hold a 'ffi_closure' object. -- Function: void ffi_closure_free (void *WRITABLE) - Free memory allocated using `ffi_closure_alloc'. The argument is + Free memory allocated using 'ffi_closure_alloc'. The argument is the writable address that was returned. Once you have allocated the memory for a closure, you must construct -a `ffi_cif' describing the function call. Finally you can prepare the +a 'ffi_cif' describing the function call. Finally you can prepare the closure function: -- Function: ffi_status ffi_prep_closure_loc (ffi_closure *CLOSURE, @@ -431,40 +428,40 @@ closure function: **ARGS, void *USER_DATA), void *USER_DATA, void *CODELOC) Prepare a closure function. - CLOSURE is the address of a `ffi_closure' object; this is the - writable address returned by `ffi_closure_alloc'. + CLOSURE is the address of a 'ffi_closure' object; this is the + writable address returned by 'ffi_closure_alloc'. - CIF is the `ffi_cif' describing the function parameters. + CIF is the 'ffi_cif' describing the function parameters. USER_DATA is an arbitrary datum that is passed, uninterpreted, to your closure function. - CODELOC is the executable address returned by `ffi_closure_alloc'. + CODELOC is the executable address returned by 'ffi_closure_alloc'. FUN is the function which will be called when the closure is invoked. It is called with the arguments: - CIF - The `ffi_cif' passed to `ffi_prep_closure_loc'. + CIF + The 'ffi_cif' passed to 'ffi_prep_closure_loc'. - RET + RET A pointer to the memory used for the function's return value. FUN must fill this, unless the function is declared as - returning `void'. + returning 'void'. - ARGS + ARGS A vector of pointers to memory holding the arguments to the function. - USER_DATA - The same USER_DATA that was passed to `ffi_prep_closure_loc'. + USER_DATA + The same USER_DATA that was passed to 'ffi_prep_closure_loc'. - `ffi_prep_closure_loc' will return `FFI_OK' if everything went ok, + 'ffi_prep_closure_loc' will return 'FFI_OK' if everything went ok, and something else on error. - After calling `ffi_prep_closure_loc', you can cast CODELOC to the + After calling 'ffi_prep_closure_loc', you can cast CODELOC to the appropriate pointer-to-function type. - You may see old code referring to `ffi_prep_closure'. This function + You may see old code referring to 'ffi_prep_closure'. This function is deprecated, as it cannot handle the need for separate writable and executable addresses. @@ -474,26 +471,28 @@ File: libffi.info, Node: Closure Example, Prev: The Closure API, Up: Using li 2.6 Closure Example =================== -A trivial example that creates a new `puts' by binding `fputs' with -`stdin'. +A trivial example that creates a new 'puts' by binding 'fputs' with +'stdout'. #include #include /* Acts like puts with the file given at time of enclosure. */ - void puts_binding(ffi_cif *cif, unsigned int *ret, void* args[], - FILE *stream) + void puts_binding(ffi_cif *cif, void *ret, void* args[], + void *stream) { - *ret = fputs(*(char **)args[0], stream); + *(ffi_arg *)ret = fputs(*(char **)args[0], (FILE *)stream); } + typedef int (*puts_t)(char *); + int main() { ffi_cif cif; ffi_type *args[1]; ffi_closure *closure; - int (*bound_puts)(char *); + void *bound_puts; int rc; /* Allocate closure and bound_puts */ @@ -506,13 +505,13 @@ A trivial example that creates a new `puts' by binding `fputs' with /* Initialize the cif */ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_uint, args) == FFI_OK) + &ffi_type_sint, args) == FFI_OK) { /* Initialize the closure, setting stream to stdout */ if (ffi_prep_closure_loc(closure, &cif, puts_binding, stdout, bound_puts) == FFI_OK) { - rc = bound_puts("Hello World!"); + rc = ((puts_t)bound_puts)("Hello World!"); /* rc now holds the result of the call to fputs */ } } @@ -530,7 +529,7 @@ File: libffi.info, Node: Missing Features, Next: Index, Prev: Using libffi, 3 Missing Features ****************** -`libffi' is missing a few features. We welcome patches to add support +'libffi' is missing a few features. We welcome patches to add support for these. * Variadic closures. @@ -560,16 +559,18 @@ Index * closure API: The Closure API. (line 13) * closures: The Closure API. (line 13) * FFI: Introduction. (line 31) -* ffi_call: The Basics. (line 63) +* ffi_call: The Basics. (line 62) +* FFI_CLOSURES: The Closure API. (line 13) * ffi_closure_alloc: The Closure API. (line 19) * ffi_closure_free: The Closure API. (line 26) -* FFI_CLOSURES: The Closure API. (line 13) * ffi_prep_cif: The Basics. (line 16) * ffi_prep_cif_var: The Basics. (line 39) * ffi_prep_closure_loc: The Closure API. (line 34) -* ffi_status <1>: The Closure API. (line 37) -* ffi_status: The Basics. (line 18) +* ffi_status: The Basics. (line 16) +* ffi_status <1>: The Basics. (line 39) +* ffi_status <2>: The Closure API. (line 34) * ffi_type: Structures. (line 11) +* ffi_type <1>: Structures. (line 11) * ffi_type_double: Primitive Types. (line 41) * ffi_type_float: Primitive Types. (line 38) * ffi_type_longdouble: Primitive Types. (line 71) @@ -592,25 +593,26 @@ Index * ffi_type_ushort: Primitive Types. (line 53) * ffi_type_void: Primitive Types. (line 10) * Foreign Function Interface: Introduction. (line 31) -* void <1>: The Closure API. (line 20) -* void: The Basics. (line 65) +* void: The Basics. (line 62) +* void <1>: The Closure API. (line 19) +* void <2>: The Closure API. (line 26)  Tag Table: -Node: Top712 -Node: Introduction1460 -Node: Using libffi3096 -Node: The Basics3582 -Node: Simple Example7224 -Node: Types8251 -Node: Primitive Types8534 -Node: Structures10354 -Node: Type Example11224 -Node: Multiple ABIs12447 -Node: The Closure API12818 -Node: Closure Example15762 -Node: Missing Features17321 -Node: Index17774 +Node: Top682 +Node: Introduction1429 +Node: Using libffi3061 +Node: The Basics3547 +Node: Simple Example7198 +Node: Types8229 +Node: Primitive Types8512 +Node: Structures10333 +Node: Type Example11207 +Node: Multiple ABIs12473 +Node: The Closure API12844 +Node: Closure Example15788 +Node: Missing Features17397 +Node: Index17850  End Tag Table diff --git a/Modules/_ctypes/libffi/doc/libffi.texi b/Modules/_ctypes/libffi/doc/libffi.texi index 5c0552b0c973..a2b1242802d7 100644 --- a/Modules/_ctypes/libffi/doc/libffi.texi +++ b/Modules/_ctypes/libffi/doc/libffi.texi @@ -184,11 +184,11 @@ This calls the function @var{fn} according to the description given in @var{rvalue} is a pointer to a chunk of memory that will hold the result of the function call. This must be large enough to hold the -result and must be suitably aligned; it is the caller's responsibility +result, no smaller than the system register size (generally 32 or 64 +bits), and must be suitably aligned; it is the caller's responsibility to ensure this. If @var{cif} declares that the function returns @code{void} (using @code{ffi_type_void}), then @var{rvalue} is -ignored. If @var{rvalue} is @samp{NULL}, then the return value is -discarded. +ignored. @var{avalues} is a vector of @code{void *} pointers that point to the memory locations holding the argument values for a call. If @var{cif} @@ -214,7 +214,7 @@ int main() ffi_type *args[1]; void *values[1]; char *s; - int rc; + ffi_arg rc; /* Initialize the argument info vectors */ args[0] = &ffi_type_pointer; @@ -222,7 +222,7 @@ int main() /* Initialize the cif */ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_uint, args) == FFI_OK) + &ffi_type_sint, args) == FFI_OK) @{ s = "Hello World!"; ffi_call(&cif, puts, &rc, values); @@ -414,6 +414,7 @@ Here is the corresponding code to describe this struct to int i; tm_type.size = tm_type.alignment = 0; + tm_type.type = FFI_TYPE_STRUCT; tm_type.elements = &tm_type_elements; for (i = 0; i < 9; i++) @@ -533,28 +534,30 @@ writable and executable addresses. @section Closure Example A trivial example that creates a new @code{puts} by binding -@code{fputs} with @code{stdin}. +@code{fputs} with @code{stdout}. @example #include #include /* Acts like puts with the file given at time of enclosure. */ -void puts_binding(ffi_cif *cif, unsigned int *ret, void* args[], - FILE *stream) +void puts_binding(ffi_cif *cif, void *ret, void* args[], + void *stream) @{ - *ret = fputs(*(char **)args[0], stream); + *(ffi_arg *)ret = fputs(*(char **)args[0], (FILE *)stream); @} +typedef int (*puts_t)(char *); + int main() @{ ffi_cif cif; ffi_type *args[1]; ffi_closure *closure; - int (*bound_puts)(char *); + void *bound_puts; int rc; - + /* Allocate closure and bound_puts */ closure = ffi_closure_alloc(sizeof(ffi_closure), &bound_puts); @@ -565,13 +568,13 @@ int main() /* Initialize the cif */ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_uint, args) == FFI_OK) + &ffi_type_sint, args) == FFI_OK) @{ /* Initialize the closure, setting stream to stdout */ - if (ffi_prep_closure_loc(closure, &cif, puts_binding, + if (ffi_prep_closure_loc(closure, &cif, puts_binding, stdout, bound_puts) == FFI_OK) @{ - rc = bound_puts("Hello World!"); + rc = ((puts_t)bound_puts)("Hello World!"); /* rc now holds the result of the call to fputs */ @} @} diff --git a/Modules/_ctypes/libffi/doc/stamp-vti b/Modules/_ctypes/libffi/doc/stamp-vti index 54255ba45d81..378595332fdc 100644 --- a/Modules/_ctypes/libffi/doc/stamp-vti +++ b/Modules/_ctypes/libffi/doc/stamp-vti @@ -1,4 +1,4 @@ -@set UPDATED 16 March 2013 -@set UPDATED-MONTH March 2013 -@set EDITION 3.0.13 -@set VERSION 3.0.13 +@set UPDATED 25 April 2014 +@set UPDATED-MONTH April 2014 +@set EDITION 3.1 +@set VERSION 3.1 diff --git a/Modules/_ctypes/libffi/doc/version.texi b/Modules/_ctypes/libffi/doc/version.texi index 54255ba45d81..378595332fdc 100644 --- a/Modules/_ctypes/libffi/doc/version.texi +++ b/Modules/_ctypes/libffi/doc/version.texi @@ -1,4 +1,4 @@ -@set UPDATED 16 March 2013 -@set UPDATED-MONTH March 2013 -@set EDITION 3.0.13 -@set VERSION 3.0.13 +@set UPDATED 25 April 2014 +@set UPDATED-MONTH April 2014 +@set EDITION 3.1 +@set VERSION 3.1 diff --git a/Modules/_ctypes/libffi/fficonfig.h.in b/Modules/_ctypes/libffi/fficonfig.h.in index c77585da4b45..cdef91b88feb 100644 --- a/Modules/_ctypes/libffi/fficonfig.h.in +++ b/Modules/_ctypes/libffi/fficonfig.h.in @@ -26,10 +26,10 @@ /* Cannot use malloc on this target, so, we revert to alternative means */ #undef FFI_MMAP_EXEC_WRIT -/* Define this is you do not want support for the raw API. */ +/* Define this if you do not want support for the raw API. */ #undef FFI_NO_RAW_API -/* Define this is you do not want support for aggregate types. */ +/* 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. */ @@ -73,6 +73,9 @@ /* Define if you have the long double type and it is bigger than a double */ #undef HAVE_LONG_DOUBLE +/* Define if you support more than one size of the long double type */ +#undef HAVE_LONG_DOUBLE_VARIANT + /* Define to 1 if you have the `memcpy' function. */ #undef HAVE_MEMCPY @@ -118,8 +121,7 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ +/* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Define to 1 if your C compiler doesn't accept -c and -o together. */ @@ -152,6 +154,9 @@ /* The size of `long double', as computed by sizeof. */ #undef SIZEOF_LONG_DOUBLE +/* The size of `size_t', as computed by sizeof. */ +#undef SIZEOF_SIZE_T + /* 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 runtime. diff --git a/Modules/_ctypes/libffi/fficonfig.py.in b/Modules/_ctypes/libffi/fficonfig.py.in index 35be29cb3a69..d10249866d3c 100644 --- a/Modules/_ctypes/libffi/fficonfig.py.in +++ b/Modules/_ctypes/libffi/fficonfig.py.in @@ -6,7 +6,7 @@ src/closures.c ffi_platforms = { 'MIPS_IRIX': ['src/mips/ffi.c', 'src/mips/o32.S', 'src/mips/n32.S'], 'MIPS_LINUX': ['src/mips/ffi.c', 'src/mips/o32.S'], - 'X86': ['src/x86/ffi.c', 'src/x86/sysv.S'], + 'X86': ['src/x86/ffi.c', 'src/x86/sysv.S', 'src/x86/win32.S'], 'X86_FREEBSD': ['src/x86/ffi.c', 'src/x86/freebsd.S'], 'X86_WIN32': ['src/x86/ffi.c', 'src/x86/win32.S'], 'SPARC': ['src/sparc/ffi.c', 'src/sparc/v8.S', 'src/sparc/v9.S'], @@ -14,9 +14,10 @@ ffi_platforms = { 'IA64': ['src/ia64/ffi.c', 'src/ia64/unix.S'], 'M32R': ['src/m32r/sysv.S', 'src/m32r/ffi.c'], 'M68K': ['src/m68k/ffi.c', 'src/m68k/sysv.S'], - 'POWERPC': ['src/powerpc/ffi.c', 'src/powerpc/sysv.S', 'src/powerpc/ppc_closure.S', 'src/powerpc/linux64.S', 'src/powerpc/linux64_closure.S'], + 'POWERPC': ['src/powerpc/ffi.c', 'src/powerpc/ffi_sysv.c', 'src/powerpc/ffi_linux64.c', 'src/powerpc/sysv.S', 'src/powerpc/ppc_closure.S', 'src/powerpc/linux64.S', 'src/powerpc/linux64_closure.S'], 'POWERPC_AIX': ['src/powerpc/ffi_darwin.c', 'src/powerpc/aix.S', 'src/powerpc/aix_closure.S'], 'POWERPC_FREEBSD': ['src/powerpc/ffi.c', 'src/powerpc/sysv.S', 'src/powerpc/ppc_closure.S'], + 'AARCH64': ['src/aarch64/sysv.S', 'src/aarch64/ffi.c'], 'ARM': ['src/arm/sysv.S', 'src/arm/ffi.c'], 'LIBFFI_CRIS': ['src/cris/sysv.S', 'src/cris/ffi.c'], 'FRV': ['src/frv/eabi.S', 'src/frv/ffi.c'], diff --git a/Modules/_ctypes/libffi/generate-darwin-source-and-headers.py b/Modules/_ctypes/libffi/generate-darwin-source-and-headers.py new file mode 100644 index 000000000000..964e861d43c8 --- /dev/null +++ b/Modules/_ctypes/libffi/generate-darwin-source-and-headers.py @@ -0,0 +1,209 @@ +#!/usr/bin/env python +import subprocess +import os +import errno +import collections +import glob +import argparse + +class Platform(object): + pass + +class simulator_platform(Platform): + directory = 'darwin_ios' + sdk = 'iphonesimulator' + arch = 'i386' + triple = 'i386-apple-darwin11' + version_min = '-miphoneos-version-min=5.1.1' + + prefix = "#ifdef __i386__\n\n" + suffix = "\n\n#endif" + src_dir = 'x86' + src_files = ['darwin.S', 'win32.S', 'ffi.c'] + + +class simulator64_platform(Platform): + directory = 'darwin_ios' + sdk = 'iphonesimulator' + arch = 'x86_64' + triple = 'x86_64-apple-darwin13' + version_min = '-miphoneos-version-min=7.0' + + prefix = "#ifdef __x86_64__\n\n" + suffix = "\n\n#endif" + src_dir = 'x86' + src_files = ['darwin64.S', 'ffi64.c'] + + +class device_platform(Platform): + directory = 'darwin_ios' + sdk = 'iphoneos' + arch = 'armv7' + triple = 'arm-apple-darwin11' + version_min = '-miphoneos-version-min=5.1.1' + + prefix = "#ifdef __arm__\n\n" + suffix = "\n\n#endif" + src_dir = 'arm' + src_files = ['sysv.S', 'trampoline.S', 'ffi.c'] + + +class device64_platform(Platform): + directory = 'darwin_ios' + sdk = 'iphoneos' + arch = 'arm64' + triple = 'aarch64-apple-darwin13' + version_min = '-miphoneos-version-min=7.0' + + prefix = "#ifdef __arm64__\n\n" + suffix = "\n\n#endif" + src_dir = 'aarch64' + src_files = ['sysv.S', 'ffi.c'] + + +class desktop32_platform(Platform): + directory = 'darwin_osx' + sdk = 'macosx' + arch = 'i386' + triple = 'i386-apple-darwin10' + version_min = '-mmacosx-version-min=10.6' + src_dir = 'x86' + src_files = ['darwin.S', 'win32.S', 'ffi.c'] + + prefix = "#ifdef __i386__\n\n" + suffix = "\n\n#endif" + + +class desktop64_platform(Platform): + directory = 'darwin_osx' + sdk = 'macosx' + arch = 'x86_64' + triple = 'x86_64-apple-darwin10' + version_min = '-mmacosx-version-min=10.6' + + prefix = "#ifdef __x86_64__\n\n" + suffix = "\n\n#endif" + src_dir = 'x86' + src_files = ['darwin64.S', 'ffi64.c'] + + +def mkdir_p(path): + try: + os.makedirs(path) + except OSError as exc: # Python >2.5 + if exc.errno == errno.EEXIST: + pass + else: + raise + + +def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''): + mkdir_p(dst_dir) + out_filename = filename + + if file_suffix: + split_name = os.path.splitext(filename) + out_filename = "%s_%s%s" % (split_name[0], file_suffix, split_name[1]) + + with open(os.path.join(src_dir, filename)) as in_file: + with open(os.path.join(dst_dir, out_filename), 'w') as out_file: + if prefix: + out_file.write(prefix) + + out_file.write(in_file.read()) + + if suffix: + out_file.write(suffix) + + +def list_files(src_dir, pattern=None, filelist=None): + if pattern: filelist = glob.iglob(os.path.join(src_dir, pattern)) + for file in filelist: + yield os.path.basename(file) + + +def copy_files(src_dir, dst_dir, pattern=None, filelist=None, file_suffix=None, prefix=None, suffix=None): + for filename in list_files(src_dir, pattern=pattern, filelist=filelist): + move_file(src_dir, dst_dir, filename, file_suffix=file_suffix, prefix=prefix, suffix=suffix) + + +def copy_src_platform_files(platform): + src_dir = os.path.join('src', platform.src_dir) + dst_dir = os.path.join(platform.directory, 'src', platform.src_dir) + copy_files(src_dir, dst_dir, filelist=platform.src_files, file_suffix=platform.arch, prefix=platform.prefix, suffix=platform.suffix) + + +def build_target(platform, platform_headers): + def xcrun_cmd(cmd): + return 'xcrun -sdk %s %s -arch %s' % (platform.sdk, cmd, platform.arch) + + tag='%s-%s' % (platform.sdk, platform.arch) + build_dir = 'build_%s' % tag + mkdir_p(build_dir) + env = dict(CC=xcrun_cmd('clang'), + LD=xcrun_cmd('ld'), + CFLAGS='%s' % (platform.version_min)) + working_dir = os.getcwd() + try: + os.chdir(build_dir) + subprocess.check_call(['../configure', '-host', platform.triple], env=env) + finally: + os.chdir(working_dir) + + for src_dir in [build_dir, os.path.join(build_dir, 'include')]: + copy_files(src_dir, + os.path.join(platform.directory, 'include'), + pattern='*.h', + file_suffix=platform.arch, + prefix=platform.prefix, + suffix=platform.suffix) + + for filename in list_files(src_dir, pattern='*.h'): + platform_headers[filename].add((platform.prefix, platform.arch, platform.suffix)) + + +def make_tramp(): + with open('src/arm/trampoline.S', 'w') as tramp_out: + p = subprocess.Popen(['bash', 'src/arm/gentramp.sh'], stdout=tramp_out) + p.wait() + + +def generate_source_and_headers(generate_osx=True, generate_ios=True): + copy_files('src', 'darwin_common/src', pattern='*.c') + copy_files('include', 'darwin_common/include', pattern='*.h') + + if generate_ios: + make_tramp() + copy_src_platform_files(simulator_platform) + copy_src_platform_files(simulator64_platform) + copy_src_platform_files(device_platform) + copy_src_platform_files(device64_platform) + if generate_osx: + copy_src_platform_files(desktop32_platform) + copy_src_platform_files(desktop64_platform) + + platform_headers = collections.defaultdict(set) + + if generate_ios: + build_target(simulator_platform, platform_headers) + build_target(simulator64_platform, platform_headers) + build_target(device_platform, platform_headers) + build_target(device64_platform, platform_headers) + if generate_osx: + build_target(desktop32_platform, platform_headers) + build_target(desktop64_platform, platform_headers) + + mkdir_p('darwin_common/include') + for header_name, tag_tuples in platform_headers.iteritems(): + basename, suffix = os.path.splitext(header_name) + with open(os.path.join('darwin_common/include', header_name), 'w') as header: + for tag_tuple in tag_tuples: + header.write('%s#include <%s_%s%s>\n%s\n' % (tag_tuple[0], basename, tag_tuple[1], suffix, tag_tuple[2])) + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--only-ios', action='http://github.com/store_true', default=False) + parser.add_argument('--only-osx', action='http://github.com/store_true', default=False) + args = parser.parse_args() + + generate_source_and_headers(generate_osx=not args.only_ios, generate_ios=not args.only_osx) diff --git a/Modules/_ctypes/libffi/generate-ios-source-and-headers.py b/Modules/_ctypes/libffi/generate-ios-source-and-headers.py deleted file mode 100644 index c2bca734ef17..000000000000 --- a/Modules/_ctypes/libffi/generate-ios-source-and-headers.py +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env python - -import subprocess -import re -import os -import errno -import collections -import sys - -class Platform(object): - pass - -sdk_re = re.compile(r'.*-sdk ([a-zA-Z0-9.]*)') - -def sdkinfo(sdkname): - ret = {} - for line in subprocess.Popen(['xcodebuild', '-sdk', sdkname, '-version'], stdout=subprocess.PIPE).stdout: - kv = line.strip().split(': ', 1) - if len(kv) == 2: - k,v = kv - ret[k] = v - return ret - -sim_sdk_info = sdkinfo('iphonesimulator') -device_sdk_info = sdkinfo('iphoneos') - -def latest_sdks(): - latest_sim = None - latest_device = None - for line in subprocess.Popen(['xcodebuild', '-showsdks'], stdout=subprocess.PIPE).stdout: - match = sdk_re.match(line) - if match: - if 'Simulator' in line: - latest_sim = match.group(1) - elif 'iOS' in line: - latest_device = match.group(1) - - return latest_sim, latest_device - -sim_sdk, device_sdk = latest_sdks() - -class simulator_platform(Platform): - sdk='iphonesimulator' - arch = 'i386' - name = 'simulator' - triple = 'i386-apple-darwin10' - sdkroot = sim_sdk_info['Path'] - - prefix = "#if !defined(__arm__) && defined(__i386__)\n\n" - suffix = "\n\n#endif" - -class device_platform(Platform): - sdk='iphoneos' - name = 'ios' - arch = 'armv7' - triple = 'arm-apple-darwin10' - sdkroot = device_sdk_info['Path'] - - prefix = "#ifdef __arm__\n\n" - suffix = "\n\n#endif" - - -def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''): - if not os.path.exists(dst_dir): - os.makedirs(dst_dir) - - out_filename = filename - - if file_suffix: - split_name = os.path.splitext(filename) - out_filename = "%s_%s%s" % (split_name[0], file_suffix, split_name[1]) - - with open(os.path.join(src_dir, filename)) as in_file: - with open(os.path.join(dst_dir, out_filename), 'w') as out_file: - if prefix: - out_file.write(prefix) - - out_file.write(in_file.read()) - - if suffix: - out_file.write(suffix) - -headers_seen = collections.defaultdict(set) - -def move_source_tree(src_dir, dest_dir, dest_include_dir, arch=None, prefix=None, suffix=None): - for root, dirs, files in os.walk(src_dir, followlinks=True): - relroot = os.path.relpath(root,src_dir) - - def move_dir(arch, prefix='', suffix='', files=[]): - for file in files: - file_suffix = None - if file.endswith('.h'): - if dest_include_dir: - file_suffix = arch - if arch: - headers_seen[file].add(arch) - move_file(root, dest_include_dir, file, arch, prefix=prefix, suffix=suffix) - - elif dest_dir: - outroot = os.path.join(dest_dir, relroot) - move_file(root, outroot, file, prefix=prefix, suffix=suffix) - - if relroot == '.': - move_dir(arch=arch, - files=files, - prefix=prefix, - suffix=suffix) - elif relroot == 'arm': - move_dir(arch='arm', - prefix="#ifdef __arm__\n\n", - suffix="\n\n#endif", - files=files) - elif relroot == 'x86': - move_dir(arch='i386', - prefix="#if !defined(__arm__) && defined(__i386__)\n\n", - suffix="\n\n#endif", - files=files) - -def build_target(platform): - def xcrun_cmd(cmd): - return subprocess.check_output(['xcrun', '-sdk', platform.sdkroot, '-find', cmd]).strip() - - build_dir = 'build_' + platform.name - if not os.path.exists(build_dir): - os.makedirs(build_dir) - env = dict(CC=xcrun_cmd('clang'), - LD=xcrun_cmd('ld'), - CFLAGS='-arch %s -isysroot %s -miphoneos-version-min=4.0' % (platform.arch, platform.sdkroot)) - working_dir=os.getcwd() - try: - os.chdir(build_dir) - subprocess.check_call(['../configure', '-host', platform.triple], env=env) - move_source_tree('.', None, '../ios/include', - arch=platform.arch, - prefix=platform.prefix, - suffix=platform.suffix) - move_source_tree('./include', None, '../ios/include', - arch=platform.arch, - prefix=platform.prefix, - suffix=platform.suffix) - finally: - os.chdir(working_dir) - - for header_name, archs in headers_seen.iteritems(): - basename, suffix = os.path.splitext(header_name) - -def main(): - move_source_tree('src', 'ios/src', 'ios/include') - move_source_tree('include', None, 'ios/include') - build_target(simulator_platform) - build_target(device_platform) - - for header_name, archs in headers_seen.iteritems(): - basename, suffix = os.path.splitext(header_name) - with open(os.path.join('ios/include', header_name), 'w') as header: - for arch in archs: - header.write('#include <%s_%s%s>\n' % (basename, arch, suffix)) - -if __name__ == '__main__': - main() diff --git a/Modules/_ctypes/libffi/generate-osx-source-and-headers.py b/Modules/_ctypes/libffi/generate-osx-source-and-headers.py deleted file mode 100644 index 64313c1a3640..000000000000 --- a/Modules/_ctypes/libffi/generate-osx-source-and-headers.py +++ /dev/null @@ -1,153 +0,0 @@ -#!/usr/bin/env python -import subprocess -import re -import os -import errno -import collections -import sys - -class Platform(object): - pass - -sdk_re = re.compile(r'.*-sdk ([a-zA-Z0-9.]*)') - -def sdkinfo(sdkname): - ret = {} - for line in subprocess.Popen(['xcodebuild', '-sdk', sdkname, '-version'], stdout=subprocess.PIPE).stdout: - kv = line.strip().split(': ', 1) - if len(kv) == 2: - k,v = kv - ret[k] = v - return ret - -desktop_sdk_info = sdkinfo('macosx') - -def latest_sdks(): - latest_desktop = None - for line in subprocess.Popen(['xcodebuild', '-showsdks'], stdout=subprocess.PIPE).stdout: - match = sdk_re.match(line) - if match: - if 'OS X' in line: - latest_desktop = match.group(1) - - return latest_desktop - -desktop_sdk = latest_sdks() - -class desktop_platform_32(Platform): - sdk='macosx' - arch = 'i386' - name = 'mac32' - triple = 'i386-apple-darwin10' - sdkroot = desktop_sdk_info['Path'] - - prefix = "#if defined(__i386__) && !defined(__x86_64__)\n\n" - suffix = "\n\n#endif" - -class desktop_platform_64(Platform): - sdk='macosx' - arch = 'x86_64' - name = 'mac' - triple = 'x86_64-apple-darwin10' - sdkroot = desktop_sdk_info['Path'] - - prefix = "#if !defined(__i386__) && defined(__x86_64__)\n\n" - suffix = "\n\n#endif" - -def move_file(src_dir, dst_dir, filename, file_suffix=None, prefix='', suffix=''): - if not os.path.exists(dst_dir): - os.makedirs(dst_dir) - - out_filename = filename - - if file_suffix: - split_name = os.path.splitext(filename) - out_filename = "%s_%s%s" % (split_name[0], file_suffix, split_name[1]) - - with open(os.path.join(src_dir, filename)) as in_file: - with open(os.path.join(dst_dir, out_filename), 'w') as out_file: - if prefix: - out_file.write(prefix) - - out_file.write(in_file.read()) - - if suffix: - out_file.write(suffix) - -headers_seen = collections.defaultdict(set) - -def move_source_tree(src_dir, dest_dir, dest_include_dir, arch=None, prefix=None, suffix=None): - for root, dirs, files in os.walk(src_dir, followlinks=True): - relroot = os.path.relpath(root,src_dir) - - def move_dir(arch, prefix='', suffix='', files=[]): - for file in files: - file_suffix = None - if file.endswith('.h'): - if dest_include_dir: - file_suffix = arch - if arch: - headers_seen[file].add(arch) - move_file(root, dest_include_dir, file, arch, prefix=prefix, suffix=suffix) - - elif dest_dir: - outroot = os.path.join(dest_dir, relroot) - move_file(root, outroot, file, prefix=prefix, suffix=suffix) - - if relroot == '.': - move_dir(arch=arch, - files=files, - prefix=prefix, - suffix=suffix) - elif relroot == 'x86': - move_dir(arch='i386', - prefix="#if defined(__i386__) && !defined(__x86_64__)\n\n", - suffix="\n\n#endif", - files=files) - move_dir(arch='x86_64', - prefix="#if !defined(__i386__) && defined(__x86_64__)\n\n", - suffix="\n\n#endif", - files=files) - -def build_target(platform): - def xcrun_cmd(cmd): - return subprocess.check_output(['xcrun', '-sdk', platform.sdkroot, '-find', cmd]).strip() - - build_dir = 'build_' + platform.name - if not os.path.exists(build_dir): - os.makedirs(build_dir) - env = dict(CC=xcrun_cmd('clang'), - LD=xcrun_cmd('ld'), - CFLAGS='-arch %s -isysroot %s -mmacosx-version-min=10.6' % (platform.arch, platform.sdkroot)) - working_dir=os.getcwd() - try: - os.chdir(build_dir) - subprocess.check_call(['../configure', '-host', platform.triple], env=env) - move_source_tree('.', None, '../osx/include', - arch=platform.arch, - prefix=platform.prefix, - suffix=platform.suffix) - move_source_tree('./include', None, '../osx/include', - arch=platform.arch, - prefix=platform.prefix, - suffix=platform.suffix) - finally: - os.chdir(working_dir) - - for header_name, archs in headers_seen.iteritems(): - basename, suffix = os.path.splitext(header_name) - -def main(): - move_source_tree('src', 'osx/src', 'osx/include') - move_source_tree('include', None, 'osx/include') - build_target(desktop_platform_32) - build_target(desktop_platform_64) - - for header_name, archs in headers_seen.iteritems(): - basename, suffix = os.path.splitext(header_name) - with open(os.path.join('osx/include', header_name), 'w') as header: - for arch in archs: - header.write('#include <%s_%s%s>\n' % (basename, arch, suffix)) - -if __name__ == '__main__': - main() diff --git a/Modules/_ctypes/libffi/include/Makefile.in b/Modules/_ctypes/libffi/include/Makefile.in index 2c36e36d07bb..9d747e80e54e 100644 --- a/Modules/_ctypes/libffi/include/Makefile.in +++ b/Modules/_ctypes/libffi/include/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.12.2 from Makefile.am. +# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2012 Free Software Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -15,23 +15,51 @@ @SET_MAKE@ VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ - test $$am__dry = yes; \ - } + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -52,7 +80,7 @@ build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = include -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/ffi.h.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \ @@ -75,6 +103,18 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/fficonfig.h CONFIG_CLEAN_FILES = ffi.h ffitarget.h CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ @@ -111,12 +151,30 @@ am__uninstall_files_from_dir = { \ } am__installdirs = "$(DESTDIR)$(includesdir)" HEADERS = $(nodist_includes_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LTLDFLAGS = @AM_LTLDFLAGS@ AM_RUNTESTFLAGS = @AM_RUNTESTFLAGS@ AR = @AR@ @@ -132,6 +190,10 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ @@ -147,6 +209,7 @@ FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@ +HAVE_LONG_DOUBLE_VARIANT = @HAVE_LONG_DOUBLE_VARIANT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -193,6 +256,7 @@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ @@ -315,26 +379,15 @@ uninstall-nodist_includesHEADERS: files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(includesdir)'; $(am__uninstall_files_from_dir) -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ @@ -346,15 +399,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $$unique; \ fi; \ fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique @@ -363,9 +412,10 @@ GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am -cscopelist: $(HEADERS) $(SOURCES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP)'; \ +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ @@ -517,18 +567,19 @@ uninstall-am: uninstall-nodist_includesHEADERS .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool cscopelist ctags distclean distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-nodist_includesHEADERS \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am uninstall-nodist_includesHEADERS +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man \ + install-nodist_includesHEADERS install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-nodist_includesHEADERS # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/Modules/_ctypes/libffi/include/ffi.h.in b/Modules/_ctypes/libffi/include/ffi.h.in index a51583bcd326..93c776fbbee3 100644 --- a/Modules/_ctypes/libffi/include/ffi.h.in +++ b/Modules/_ctypes/libffi/include/ffi.h.in @@ -221,6 +221,11 @@ typedef struct { #endif } ffi_cif; +#if HAVE_LONG_DOUBLE_VARIANT +/* Used to adjust size/alignment of ffi types. */ +void ffi_prep_types (ffi_abi abi); +# endif + /* Used internally, but overridden by some architectures */ ffi_status ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, diff --git a/Modules/_ctypes/libffi/include/ffi_common.h b/Modules/_ctypes/libffi/include/ffi_common.h index 650ca6997df9..37f5a9e92494 100644 --- a/Modules/_ctypes/libffi/include/ffi_common.h +++ b/Modules/_ctypes/libffi/include/ffi_common.h @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - ffi_common.h - Copyright (C) 2011, 2012 Anthony Green + ffi_common.h - Copyright (C) 2011, 2012, 2013 Anthony Green Copyright (C) 2007 Free Software Foundation, Inc Copyright (c) 1996 Red Hat, Inc. @@ -19,10 +19,14 @@ extern "C" { /* Do not move this. Some versions of AIX are very picky about where this is positioned. */ #ifdef __GNUC__ -/* mingw64 defines this already in malloc.h. */ -#ifndef alloca -# define alloca __builtin_alloca -#endif +# if HAVE_ALLOCA_H +# include +# else + /* mingw64 defines this already in malloc.h. */ +# ifndef alloca +# define alloca __builtin_alloca +# endif +# endif # define MAYBE_UNUSED __attribute__((__unused__)) #else # define MAYBE_UNUSED @@ -30,17 +34,17 @@ extern "C" { # include # else # ifdef _AIX - #pragma alloca +# pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ # ifdef _MSC_VER # define alloca _alloca # else char *alloca (); -# endif # endif # endif # endif +# endif #endif /* Check for the existence of memcpy. */ diff --git a/Modules/_ctypes/libffi/install-sh b/Modules/_ctypes/libffi/install-sh index 6781b987bdbc..377bb8687ffe 100755 --- a/Modules/_ctypes/libffi/install-sh +++ b/Modules/_ctypes/libffi/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2009-04-28.21; # UTC +scriptversion=2011-11-20.07; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -35,7 +35,7 @@ scriptversion=2009-04-28.21; # UTC # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it +# 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written @@ -156,6 +156,10 @@ while test $# -ne 0; do -s) stripcmd=$stripprog;; -t) dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac shift;; -T) no_target_directory=true;; @@ -186,6 +190,10 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then fi shift # arg dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac done fi @@ -194,13 +202,17 @@ if test $# -eq 0; then echo "$0: no input file specified." >&2 exit 1 fi - # It's OK to call `install-sh -d' without argument. + # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then - trap '(exit $?); exit' 1 2 13 15 + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. @@ -228,9 +240,9 @@ fi for src do - # Protect names starting with `-'. + # Protect names problematic for 'test' and other utilities. case $src in - -*) src=./$src;; + -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then @@ -252,12 +264,7 @@ do echo "$0: no destination specified." >&2 exit 1 fi - dst=$dst_arg - # Protect names starting with `-'. - case $dst in - -*) dst=./$dst;; - esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. @@ -347,7 +354,7 @@ do if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writeable bit of parent directory when it shouldn't. + # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in @@ -385,7 +392,7 @@ do case $dstdir in /*) prefix='/';; - -*) prefix='./';; + [-=\(\)!]*) prefix='./';; *) prefix='';; esac @@ -403,7 +410,7 @@ do for d do - test -z "$d" && continue + test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then diff --git a/Modules/_ctypes/libffi/libffi.pc.in b/Modules/_ctypes/libffi/libffi.pc.in index c2e1c7b33cdf..edf6fde5e2be 100644 --- a/Modules/_ctypes/libffi/libffi.pc.in +++ b/Modules/_ctypes/libffi/libffi.pc.in @@ -1,10 +1,11 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ +toolexeclibdir=@toolexeclibdir@ includedir=${libdir}/@PACKAGE_NAME@-@PACKAGE_VERSION@/include Name: @PACKAGE_NAME@ Description: Library supporting Foreign Function Interfaces Version: @PACKAGE_VERSION@ -Libs: -L${libdir} -lffi +Libs: -L${toolexeclibdir} -lffi Cflags: -I${includedir} diff --git a/Modules/_ctypes/libffi/libffi.xcodeproj/project.pbxproj b/Modules/_ctypes/libffi/libffi.xcodeproj/project.pbxproj index 14c39a2a4e13..1cf396ffa1e4 100644 --- a/Modules/_ctypes/libffi/libffi.xcodeproj/project.pbxproj +++ b/Modules/_ctypes/libffi/libffi.xcodeproj/project.pbxproj @@ -7,473 +7,448 @@ objects = { /* Begin PBXBuildFile section */ - 6C43CBDC1534F76F00162364 /* ffi.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBBD1534F76F00162364 /* ffi.c */; }; - 6C43CBDD1534F76F00162364 /* sysv.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBBF1534F76F00162364 /* sysv.S */; }; - 6C43CBDE1534F76F00162364 /* trampoline.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBC01534F76F00162364 /* trampoline.S */; }; - 6C43CBE61534F76F00162364 /* darwin.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBC91534F76F00162364 /* darwin.S */; }; - 6C43CBE81534F76F00162364 /* ffi.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CBCB1534F76F00162364 /* ffi.c */; }; - 6C43CC1F1534F77800162364 /* darwin.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC051534F77800162364 /* darwin.S */; }; - 6C43CC201534F77800162364 /* darwin64.S in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC061534F77800162364 /* darwin64.S */; }; - 6C43CC211534F77800162364 /* ffi.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC071534F77800162364 /* ffi.c */; }; - 6C43CC221534F77800162364 /* ffi64.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC081534F77800162364 /* ffi64.c */; }; - 6C43CC2F1534F7BE00162364 /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC281534F7BE00162364 /* closures.c */; }; - 6C43CC301534F7BE00162364 /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC281534F7BE00162364 /* closures.c */; }; - 6C43CC351534F7BE00162364 /* java_raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2B1534F7BE00162364 /* java_raw_api.c */; }; - 6C43CC361534F7BE00162364 /* java_raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2B1534F7BE00162364 /* java_raw_api.c */; }; - 6C43CC371534F7BE00162364 /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2C1534F7BE00162364 /* prep_cif.c */; }; - 6C43CC381534F7BE00162364 /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2C1534F7BE00162364 /* prep_cif.c */; }; - 6C43CC391534F7BE00162364 /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2D1534F7BE00162364 /* raw_api.c */; }; - 6C43CC3A1534F7BE00162364 /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2D1534F7BE00162364 /* raw_api.c */; }; - 6C43CC3B1534F7BE00162364 /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2E1534F7BE00162364 /* types.c */; }; - 6C43CC3C1534F7BE00162364 /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = 6C43CC2E1534F7BE00162364 /* types.c */; }; - 6C43CC971535032600162364 /* ffi.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC8D1535032600162364 /* ffi.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CC981535032600162364 /* ffi_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC8E1535032600162364 /* ffi_common.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CC991535032600162364 /* ffi_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC8F1535032600162364 /* ffi_i386.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CC9A1535032600162364 /* ffi_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC901535032600162364 /* ffi_x86_64.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CC9B1535032600162364 /* fficonfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC911535032600162364 /* fficonfig.h */; }; - 6C43CC9C1535032600162364 /* fficonfig_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC921535032600162364 /* fficonfig_i386.h */; }; - 6C43CC9D1535032600162364 /* fficonfig_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC931535032600162364 /* fficonfig_x86_64.h */; }; - 6C43CC9E1535032600162364 /* ffitarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC941535032600162364 /* ffitarget.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CC9F1535032600162364 /* ffitarget_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC951535032600162364 /* ffitarget_i386.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CCA01535032600162364 /* ffitarget_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CC961535032600162364 /* ffitarget_x86_64.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CCAD1535039600162364 /* ffi.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA21535039600162364 /* ffi.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CCAE1535039600162364 /* ffi_armv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA31535039600162364 /* ffi_armv7.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CCAF1535039600162364 /* ffi_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA41535039600162364 /* ffi_common.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CCB01535039600162364 /* ffi_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA51535039600162364 /* ffi_i386.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CCB11535039600162364 /* fficonfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA61535039600162364 /* fficonfig.h */; }; - 6C43CCB21535039600162364 /* fficonfig_armv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA71535039600162364 /* fficonfig_armv7.h */; }; - 6C43CCB31535039600162364 /* fficonfig_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA81535039600162364 /* fficonfig_i386.h */; }; - 6C43CCB41535039600162364 /* ffitarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCA91535039600162364 /* ffitarget.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CCB51535039600162364 /* ffitarget_arm.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCAA1535039600162364 /* ffitarget_arm.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CCB61535039600162364 /* ffitarget_armv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCAB1535039600162364 /* ffitarget_armv7.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6C43CCB71535039600162364 /* ffitarget_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C43CCAC1535039600162364 /* ffitarget_i386.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DBFA714A187F1D8600A76262 /* ffi.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA713E187F1D8600A76262 /* ffi.h */; }; + DBFA714B187F1D8600A76262 /* ffi_common.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA713F187F1D8600A76262 /* ffi_common.h */; }; + DBFA714C187F1D8600A76262 /* fficonfig.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7140187F1D8600A76262 /* fficonfig.h */; }; + DBFA714D187F1D8600A76262 /* ffitarget.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7141187F1D8600A76262 /* ffitarget.h */; }; + DBFA714E187F1D8600A76262 /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7143187F1D8600A76262 /* closures.c */; }; + DBFA714F187F1D8600A76262 /* closures.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7143187F1D8600A76262 /* closures.c */; }; + DBFA7156187F1D8600A76262 /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7147187F1D8600A76262 /* prep_cif.c */; }; + DBFA7157187F1D8600A76262 /* prep_cif.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7147187F1D8600A76262 /* prep_cif.c */; }; + DBFA7158187F1D8600A76262 /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7148187F1D8600A76262 /* raw_api.c */; }; + DBFA7159187F1D8600A76262 /* raw_api.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7148187F1D8600A76262 /* raw_api.c */; }; + DBFA715A187F1D8600A76262 /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7149187F1D8600A76262 /* types.c */; }; + DBFA715B187F1D8600A76262 /* types.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7149187F1D8600A76262 /* types.c */; }; + DBFA7177187F1D9B00A76262 /* ffi_arm64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716C187F1D9B00A76262 /* ffi_arm64.c */; }; + DBFA7178187F1D9B00A76262 /* sysv_arm64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716D187F1D9B00A76262 /* sysv_arm64.S */; }; + DBFA7179187F1D9B00A76262 /* ffi_armv7.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA716F187F1D9B00A76262 /* ffi_armv7.c */; }; + DBFA717A187F1D9B00A76262 /* sysv_armv7.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7170187F1D9B00A76262 /* sysv_armv7.S */; }; + DBFA717B187F1D9B00A76262 /* trampoline_armv7.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7171187F1D9B00A76262 /* trampoline_armv7.S */; }; + DBFA717C187F1D9B00A76262 /* darwin64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7173187F1D9B00A76262 /* darwin64_x86_64.S */; }; + DBFA717D187F1D9B00A76262 /* darwin_i386.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7174187F1D9B00A76262 /* darwin_i386.S */; }; + DBFA717E187F1D9B00A76262 /* ffi64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7175187F1D9B00A76262 /* ffi64_x86_64.c */; }; + DBFA717F187F1D9B00A76262 /* ffi_i386.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA7176187F1D9B00A76262 /* ffi_i386.c */; }; + DBFA718E187F1DA100A76262 /* ffi_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7182187F1DA100A76262 /* ffi_i386.h */; }; + DBFA718F187F1DA100A76262 /* ffi_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7183187F1DA100A76262 /* ffi_x86_64.h */; }; + DBFA7190187F1DA100A76262 /* fficonfig_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7184187F1DA100A76262 /* fficonfig_i386.h */; }; + DBFA7191187F1DA100A76262 /* fficonfig_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7185187F1DA100A76262 /* fficonfig_x86_64.h */; }; + DBFA7192187F1DA100A76262 /* ffitarget_i386.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7186187F1DA100A76262 /* ffitarget_i386.h */; }; + DBFA7193187F1DA100A76262 /* ffitarget_x86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = DBFA7187187F1DA100A76262 /* ffitarget_x86_64.h */; }; + DBFA7194187F1DA100A76262 /* darwin64_x86_64.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718A187F1DA100A76262 /* darwin64_x86_64.S */; }; + DBFA7195187F1DA100A76262 /* darwin_i386.S in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718B187F1DA100A76262 /* darwin_i386.S */; }; + DBFA7196187F1DA100A76262 /* ffi64_x86_64.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */; }; + DBFA7197187F1DA100A76262 /* ffi_i386.c in Sources */ = {isa = PBXBuildFile; fileRef = DBFA718D187F1DA100A76262 /* ffi_i386.c */; }; /* End PBXBuildFile section */ +/* Begin PBXCopyFilesBuildPhase section */ + DB13B1641849DF1E0010F42D /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = "include/$(PRODUCT_NAME)"; + dstSubfolderSpec = 16; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ - 6C43CB3D1534E9D100162364 /* libffi.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 6C43CBBD1534F76F00162364 /* ffi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi.c; sourceTree = ""; }; - 6C43CBBF1534F76F00162364 /* sysv.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sysv.S; sourceTree = ""; }; - 6C43CBC01534F76F00162364 /* trampoline.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = trampoline.S; sourceTree = ""; }; - 6C43CBC91534F76F00162364 /* darwin.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin.S; sourceTree = ""; }; - 6C43CBCB1534F76F00162364 /* ffi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi.c; sourceTree = ""; }; - 6C43CC051534F77800162364 /* darwin.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin.S; sourceTree = ""; }; - 6C43CC061534F77800162364 /* darwin64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin64.S; sourceTree = ""; }; - 6C43CC071534F77800162364 /* ffi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi.c; sourceTree = ""; }; - 6C43CC081534F77800162364 /* ffi64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi64.c; sourceTree = ""; }; - 6C43CC281534F7BE00162364 /* closures.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = closures.c; path = src/closures.c; sourceTree = SOURCE_ROOT; }; - 6C43CC2B1534F7BE00162364 /* java_raw_api.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = java_raw_api.c; path = src/java_raw_api.c; sourceTree = SOURCE_ROOT; }; - 6C43CC2C1534F7BE00162364 /* prep_cif.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = prep_cif.c; path = src/prep_cif.c; sourceTree = SOURCE_ROOT; }; - 6C43CC2D1534F7BE00162364 /* raw_api.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = raw_api.c; path = src/raw_api.c; sourceTree = SOURCE_ROOT; }; - 6C43CC2E1534F7BE00162364 /* types.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = types.c; path = src/types.c; sourceTree = SOURCE_ROOT; }; - 6C43CC8D1535032600162364 /* ffi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi.h; sourceTree = ""; }; - 6C43CC8E1535032600162364 /* ffi_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_common.h; sourceTree = ""; }; - 6C43CC8F1535032600162364 /* ffi_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_i386.h; sourceTree = ""; }; - 6C43CC901535032600162364 /* ffi_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_x86_64.h; sourceTree = ""; }; - 6C43CC911535032600162364 /* fficonfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig.h; sourceTree = ""; }; - 6C43CC921535032600162364 /* fficonfig_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_i386.h; sourceTree = ""; }; - 6C43CC931535032600162364 /* fficonfig_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_x86_64.h; sourceTree = ""; }; - 6C43CC941535032600162364 /* ffitarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget.h; sourceTree = ""; }; - 6C43CC951535032600162364 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = ""; }; - 6C43CC961535032600162364 /* ffitarget_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_x86_64.h; sourceTree = ""; }; - 6C43CCA21535039600162364 /* ffi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi.h; sourceTree = ""; }; - 6C43CCA31535039600162364 /* ffi_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_armv7.h; sourceTree = ""; }; - 6C43CCA41535039600162364 /* ffi_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_common.h; sourceTree = ""; }; - 6C43CCA51535039600162364 /* ffi_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_i386.h; sourceTree = ""; }; - 6C43CCA61535039600162364 /* fficonfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig.h; sourceTree = ""; }; - 6C43CCA71535039600162364 /* fficonfig_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_armv7.h; sourceTree = ""; }; - 6C43CCA81535039600162364 /* fficonfig_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_i386.h; sourceTree = ""; }; - 6C43CCA91535039600162364 /* ffitarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget.h; sourceTree = ""; }; - 6C43CCAA1535039600162364 /* ffitarget_arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_arm.h; sourceTree = ""; }; - 6C43CCAB1535039600162364 /* ffitarget_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_armv7.h; sourceTree = ""; }; - 6C43CCAC1535039600162364 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = ""; }; - F6F980BA147386130008F121 /* libffi.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; }; + DB13B1661849DF1E0010F42D /* libffi.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libffi.a; sourceTree = BUILT_PRODUCTS_DIR; }; + DB13B1911849DF510010F42D /* ffi.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = ffi.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; + DBFA713E187F1D8600A76262 /* ffi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi.h; sourceTree = ""; }; + DBFA713F187F1D8600A76262 /* ffi_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_common.h; sourceTree = ""; }; + DBFA7140187F1D8600A76262 /* fficonfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig.h; sourceTree = ""; }; + DBFA7141187F1D8600A76262 /* ffitarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget.h; sourceTree = ""; }; + DBFA7143187F1D8600A76262 /* closures.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = closures.c; sourceTree = ""; }; + DBFA7145187F1D8600A76262 /* dlmalloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dlmalloc.c; sourceTree = ""; }; + DBFA7147187F1D8600A76262 /* prep_cif.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = prep_cif.c; sourceTree = ""; }; + DBFA7148187F1D8600A76262 /* raw_api.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = raw_api.c; sourceTree = ""; }; + DBFA7149187F1D8600A76262 /* types.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = types.c; sourceTree = ""; }; + DBFA715E187F1D9B00A76262 /* ffi_arm64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_arm64.h; sourceTree = ""; }; + DBFA715F187F1D9B00A76262 /* ffi_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_armv7.h; sourceTree = ""; }; + DBFA7160187F1D9B00A76262 /* ffi_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_i386.h; sourceTree = ""; }; + DBFA7161187F1D9B00A76262 /* ffi_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_x86_64.h; sourceTree = ""; }; + DBFA7162187F1D9B00A76262 /* fficonfig_arm64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_arm64.h; sourceTree = ""; }; + DBFA7163187F1D9B00A76262 /* fficonfig_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_armv7.h; sourceTree = ""; }; + DBFA7164187F1D9B00A76262 /* fficonfig_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_i386.h; sourceTree = ""; }; + DBFA7165187F1D9B00A76262 /* fficonfig_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_x86_64.h; sourceTree = ""; }; + DBFA7166187F1D9B00A76262 /* ffitarget_arm64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_arm64.h; sourceTree = ""; }; + DBFA7167187F1D9B00A76262 /* ffitarget_armv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_armv7.h; sourceTree = ""; }; + DBFA7168187F1D9B00A76262 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = ""; }; + DBFA7169187F1D9B00A76262 /* ffitarget_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_x86_64.h; sourceTree = ""; }; + DBFA716C187F1D9B00A76262 /* ffi_arm64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_arm64.c; sourceTree = ""; }; + DBFA716D187F1D9B00A76262 /* sysv_arm64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sysv_arm64.S; sourceTree = ""; }; + DBFA716F187F1D9B00A76262 /* ffi_armv7.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_armv7.c; sourceTree = ""; }; + DBFA7170187F1D9B00A76262 /* sysv_armv7.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = sysv_armv7.S; sourceTree = ""; }; + DBFA7171187F1D9B00A76262 /* trampoline_armv7.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = trampoline_armv7.S; sourceTree = ""; }; + DBFA7173187F1D9B00A76262 /* darwin64_x86_64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin64_x86_64.S; sourceTree = ""; }; + DBFA7174187F1D9B00A76262 /* darwin_i386.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin_i386.S; sourceTree = ""; }; + DBFA7175187F1D9B00A76262 /* ffi64_x86_64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi64_x86_64.c; sourceTree = ""; }; + DBFA7176187F1D9B00A76262 /* ffi_i386.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_i386.c; sourceTree = ""; }; + DBFA7182187F1DA100A76262 /* ffi_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_i386.h; sourceTree = ""; }; + DBFA7183187F1DA100A76262 /* ffi_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffi_x86_64.h; sourceTree = ""; }; + DBFA7184187F1DA100A76262 /* fficonfig_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_i386.h; sourceTree = ""; }; + DBFA7185187F1DA100A76262 /* fficonfig_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fficonfig_x86_64.h; sourceTree = ""; }; + DBFA7186187F1DA100A76262 /* ffitarget_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_i386.h; sourceTree = ""; }; + DBFA7187187F1DA100A76262 /* ffitarget_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ffitarget_x86_64.h; sourceTree = ""; }; + DBFA718A187F1DA100A76262 /* darwin64_x86_64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin64_x86_64.S; sourceTree = ""; }; + DBFA718B187F1DA100A76262 /* darwin_i386.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = darwin_i386.S; sourceTree = ""; }; + DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi64_x86_64.c; sourceTree = ""; }; + DBFA718D187F1DA100A76262 /* ffi_i386.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffi_i386.c; sourceTree = ""; }; /* End PBXFileReference section */ -/* Begin PBXFrameworksBuildPhase section */ - 6C43CB3A1534E9D100162364 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( +/* Begin PBXGroup section */ + DB13B15B1849DEB70010F42D = { + isa = PBXGroup; + children = ( + DBFA713C187F1D8600A76262 /* darwin_common */, + DBFA715C187F1D9B00A76262 /* darwin_ios */, + DBFA7180187F1DA100A76262 /* darwin_osx */, + DB13B1671849DF1E0010F42D /* Products */, ); - runOnlyForDeploymentPostprocessing = 0; + sourceTree = ""; }; - F6F980B7147386130008F121 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( + DB13B1671849DF1E0010F42D /* Products */ = { + isa = PBXGroup; + children = ( + DB13B1661849DF1E0010F42D /* libffi.a */, + DB13B1911849DF510010F42D /* ffi.dylib */, ); - runOnlyForDeploymentPostprocessing = 0; + name = Products; + sourceTree = ""; }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 6C43CBAF1534F76F00162364 /* iOS */ = { + DBFA713C187F1D8600A76262 /* darwin_common */ = { isa = PBXGroup; children = ( - 6C43CCA11535039600162364 /* include */, - 6C43CBBB1534F76F00162364 /* src */, + DBFA713D187F1D8600A76262 /* include */, + DBFA7142187F1D8600A76262 /* src */, ); - name = iOS; - path = ios; + path = "darwin_common"; sourceTree = ""; }; - 6C43CBBB1534F76F00162364 /* src */ = { + DBFA713D187F1D8600A76262 /* include */ = { isa = PBXGroup; children = ( - 6C43CBC81534F76F00162364 /* x86 */, - 6C43CBBC1534F76F00162364 /* arm */, + DBFA713E187F1D8600A76262 /* ffi.h */, + DBFA713F187F1D8600A76262 /* ffi_common.h */, + DBFA7140187F1D8600A76262 /* fficonfig.h */, + DBFA7141187F1D8600A76262 /* ffitarget.h */, ); - path = src; + path = include; sourceTree = ""; }; - 6C43CBBC1534F76F00162364 /* arm */ = { + DBFA7142187F1D8600A76262 /* src */ = { isa = PBXGroup; children = ( - 6C43CBBD1534F76F00162364 /* ffi.c */, - 6C43CBBF1534F76F00162364 /* sysv.S */, - 6C43CBC01534F76F00162364 /* trampoline.S */, + DBFA7143187F1D8600A76262 /* closures.c */, + DBFA7145187F1D8600A76262 /* dlmalloc.c */, + DBFA7147187F1D8600A76262 /* prep_cif.c */, + DBFA7148187F1D8600A76262 /* raw_api.c */, + DBFA7149187F1D8600A76262 /* types.c */, ); - path = arm; + path = src; sourceTree = ""; }; - 6C43CBC81534F76F00162364 /* x86 */ = { + DBFA715C187F1D9B00A76262 /* darwin_ios */ = { isa = PBXGroup; children = ( - 6C43CBC91534F76F00162364 /* darwin.S */, - 6C43CBCB1534F76F00162364 /* ffi.c */, + DBFA715D187F1D9B00A76262 /* include */, + DBFA716A187F1D9B00A76262 /* src */, ); - path = x86; + path = "darwin_ios"; sourceTree = ""; }; - 6C43CBF01534F77800162364 /* OS X */ = { + DBFA715D187F1D9B00A76262 /* include */ = { isa = PBXGroup; children = ( - 6C43CC8C1535032600162364 /* include */, - 6C43CBFC1534F77800162364 /* src */, + DBFA715E187F1D9B00A76262 /* ffi_arm64.h */, + DBFA715F187F1D9B00A76262 /* ffi_armv7.h */, + DBFA7160187F1D9B00A76262 /* ffi_i386.h */, + DBFA7161187F1D9B00A76262 /* ffi_x86_64.h */, + DBFA7162187F1D9B00A76262 /* fficonfig_arm64.h */, + DBFA7163187F1D9B00A76262 /* fficonfig_armv7.h */, + DBFA7164187F1D9B00A76262 /* fficonfig_i386.h */, + DBFA7165187F1D9B00A76262 /* fficonfig_x86_64.h */, + DBFA7166187F1D9B00A76262 /* ffitarget_arm64.h */, + DBFA7167187F1D9B00A76262 /* ffitarget_armv7.h */, + DBFA7168187F1D9B00A76262 /* ffitarget_i386.h */, + DBFA7169187F1D9B00A76262 /* ffitarget_x86_64.h */, ); - name = "OS X"; - path = osx; + path = include; sourceTree = ""; }; - 6C43CBFC1534F77800162364 /* src */ = { + DBFA716A187F1D9B00A76262 /* src */ = { isa = PBXGroup; children = ( - 6C43CC041534F77800162364 /* x86 */, + DBFA716B187F1D9B00A76262 /* aarch64 */, + DBFA716E187F1D9B00A76262 /* arm */, + DBFA7172187F1D9B00A76262 /* x86 */, ); path = src; sourceTree = ""; }; - 6C43CC041534F77800162364 /* x86 */ = { + DBFA716B187F1D9B00A76262 /* aarch64 */ = { isa = PBXGroup; children = ( - 6C43CC051534F77800162364 /* darwin.S */, - 6C43CC061534F77800162364 /* darwin64.S */, - 6C43CC071534F77800162364 /* ffi.c */, - 6C43CC081534F77800162364 /* ffi64.c */, + DBFA716C187F1D9B00A76262 /* ffi_arm64.c */, + DBFA716D187F1D9B00A76262 /* sysv_arm64.S */, ); - path = x86; + path = aarch64; sourceTree = ""; }; - 6C43CC3D1534F7C400162364 /* src */ = { + DBFA716E187F1D9B00A76262 /* arm */ = { isa = PBXGroup; children = ( - 6C43CC281534F7BE00162364 /* closures.c */, - 6C43CC2B1534F7BE00162364 /* java_raw_api.c */, - 6C43CC2C1534F7BE00162364 /* prep_cif.c */, - 6C43CC2D1534F7BE00162364 /* raw_api.c */, - 6C43CC2E1534F7BE00162364 /* types.c */, - ); - name = src; - path = ios; + DBFA716F187F1D9B00A76262 /* ffi_armv7.c */, + DBFA7170187F1D9B00A76262 /* sysv_armv7.S */, + DBFA7171187F1D9B00A76262 /* trampoline_armv7.S */, + ); + path = arm; sourceTree = ""; }; - 6C43CC8C1535032600162364 /* include */ = { + DBFA7172187F1D9B00A76262 /* x86 */ = { isa = PBXGroup; children = ( - 6C43CC8D1535032600162364 /* ffi.h */, - 6C43CC8E1535032600162364 /* ffi_common.h */, - 6C43CC8F1535032600162364 /* ffi_i386.h */, - 6C43CC901535032600162364 /* ffi_x86_64.h */, - 6C43CC911535032600162364 /* fficonfig.h */, - 6C43CC921535032600162364 /* fficonfig_i386.h */, - 6C43CC931535032600162364 /* fficonfig_x86_64.h */, - 6C43CC941535032600162364 /* ffitarget.h */, - 6C43CC951535032600162364 /* ffitarget_i386.h */, - 6C43CC961535032600162364 /* ffitarget_x86_64.h */, + DBFA7173187F1D9B00A76262 /* darwin64_x86_64.S */, + DBFA7174187F1D9B00A76262 /* darwin_i386.S */, + DBFA7175187F1D9B00A76262 /* ffi64_x86_64.c */, + DBFA7176187F1D9B00A76262 /* ffi_i386.c */, ); - path = include; + path = x86; + sourceTree = ""; + }; + DBFA7180187F1DA100A76262 /* darwin_osx */ = { + isa = PBXGroup; + children = ( + DBFA7181187F1DA100A76262 /* include */, + DBFA7188187F1DA100A76262 /* src */, + ); + path = "darwin_osx"; sourceTree = ""; }; - 6C43CCA11535039600162364 /* include */ = { + DBFA7181187F1DA100A76262 /* include */ = { isa = PBXGroup; children = ( - 6C43CCA21535039600162364 /* ffi.h */, - 6C43CCA31535039600162364 /* ffi_armv7.h */, - 6C43CCA41535039600162364 /* ffi_common.h */, - 6C43CCA51535039600162364 /* ffi_i386.h */, - 6C43CCA61535039600162364 /* fficonfig.h */, - 6C43CCA71535039600162364 /* fficonfig_armv7.h */, - 6C43CCA81535039600162364 /* fficonfig_i386.h */, - 6C43CCA91535039600162364 /* ffitarget.h */, - 6C43CCAA1535039600162364 /* ffitarget_arm.h */, - 6C43CCAB1535039600162364 /* ffitarget_armv7.h */, - 6C43CCAC1535039600162364 /* ffitarget_i386.h */, + DBFA7182187F1DA100A76262 /* ffi_i386.h */, + DBFA7183187F1DA100A76262 /* ffi_x86_64.h */, + DBFA7184187F1DA100A76262 /* fficonfig_i386.h */, + DBFA7185187F1DA100A76262 /* fficonfig_x86_64.h */, + DBFA7186187F1DA100A76262 /* ffitarget_i386.h */, + DBFA7187187F1DA100A76262 /* ffitarget_x86_64.h */, ); path = include; sourceTree = ""; }; - F6B0839514721EE50031D8A1 = { + DBFA7188187F1DA100A76262 /* src */ = { isa = PBXGroup; children = ( - 6C43CC3D1534F7C400162364 /* src */, - 6C43CBAF1534F76F00162364 /* iOS */, - 6C43CBF01534F77800162364 /* OS X */, - F6F980C6147386260008F121 /* Products */, + DBFA7189187F1DA100A76262 /* x86 */, ); + path = src; sourceTree = ""; }; - F6F980C6147386260008F121 /* Products */ = { + DBFA7189187F1DA100A76262 /* x86 */ = { isa = PBXGroup; children = ( - F6F980BA147386130008F121 /* libffi.a */, - 6C43CB3D1534E9D100162364 /* libffi.a */, + DBFA718A187F1DA100A76262 /* darwin64_x86_64.S */, + DBFA718B187F1DA100A76262 /* darwin_i386.S */, + DBFA718C187F1DA100A76262 /* ffi64_x86_64.c */, + DBFA718D187F1DA100A76262 /* ffi_i386.c */, ); - name = Products; - path = ../..; - sourceTree = BUILT_PRODUCTS_DIR; + path = x86; + sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 6C43CB3B1534E9D100162364 /* Headers */ = { + DB13B18F1849DF510010F42D /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 6C43CC971535032600162364 /* ffi.h in Headers */, - 6C43CC981535032600162364 /* ffi_common.h in Headers */, - 6C43CC991535032600162364 /* ffi_i386.h in Headers */, - 6C43CC9A1535032600162364 /* ffi_x86_64.h in Headers */, - 6C43CC9E1535032600162364 /* ffitarget.h in Headers */, - 6C43CC9F1535032600162364 /* ffitarget_i386.h in Headers */, - 6C43CCA01535032600162364 /* ffitarget_x86_64.h in Headers */, - 6C43CC9B1535032600162364 /* fficonfig.h in Headers */, - 6C43CC9C1535032600162364 /* fficonfig_i386.h in Headers */, - 6C43CC9D1535032600162364 /* fficonfig_x86_64.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - F6F980B8147386130008F121 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 6C43CCAD1535039600162364 /* ffi.h in Headers */, - 6C43CCAE1535039600162364 /* ffi_armv7.h in Headers */, - 6C43CCAF1535039600162364 /* ffi_common.h in Headers */, - 6C43CCB01535039600162364 /* ffi_i386.h in Headers */, - 6C43CCB41535039600162364 /* ffitarget.h in Headers */, - 6C43CCB51535039600162364 /* ffitarget_arm.h in Headers */, - 6C43CCB61535039600162364 /* ffitarget_armv7.h in Headers */, - 6C43CCB71535039600162364 /* ffitarget_i386.h in Headers */, - 6C43CCB11535039600162364 /* fficonfig.h in Headers */, - 6C43CCB21535039600162364 /* fficonfig_armv7.h in Headers */, - 6C43CCB31535039600162364 /* fficonfig_i386.h in Headers */, + DBFA714C187F1D8600A76262 /* fficonfig.h in Headers */, + DBFA714D187F1D8600A76262 /* ffitarget.h in Headers */, + DBFA714A187F1D8600A76262 /* ffi.h in Headers */, + DBFA718F187F1DA100A76262 /* ffi_x86_64.h in Headers */, + DBFA7191187F1DA100A76262 /* fficonfig_x86_64.h in Headers */, + DBFA718E187F1DA100A76262 /* ffi_i386.h in Headers */, + DBFA7190187F1DA100A76262 /* fficonfig_i386.h in Headers */, + DBFA714B187F1D8600A76262 /* ffi_common.h in Headers */, + DBFA7193187F1DA100A76262 /* ffitarget_x86_64.h in Headers */, + DBFA7192187F1DA100A76262 /* ffitarget_i386.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 6C43CB3C1534E9D100162364 /* libffi OS X */ = { + DB13B1651849DF1E0010F42D /* libffi-iOS */ = { isa = PBXNativeTarget; - buildConfigurationList = 6C43CB4A1534E9D100162364 /* Build configuration list for PBXNativeTarget "libffi OS X" */; + buildConfigurationList = DB13B18B1849DF1E0010F42D /* Build configuration list for PBXNativeTarget "libffi-iOS" */; buildPhases = ( - 6C43CC401534FF3B00162364 /* Generate Source and Headers */, - 6C43CB391534E9D100162364 /* Sources */, - 6C43CB3A1534E9D100162364 /* Frameworks */, - 6C43CB3B1534E9D100162364 /* Headers */, + DB13B3051849E01C0010F42D /* ShellScript */, + DB13B1621849DF1E0010F42D /* Sources */, + DB13B1641849DF1E0010F42D /* CopyFiles */, ); buildRules = ( ); dependencies = ( ); - name = "libffi OS X"; - productName = "ffi OS X"; - productReference = 6C43CB3D1534E9D100162364 /* libffi.a */; + name = "libffi-iOS"; + productName = ffi; + productReference = DB13B1661849DF1E0010F42D /* libffi.a */; productType = "com.apple.product-type.library.static"; }; - F6F980B9147386130008F121 /* libffi iOS */ = { + DB13B1901849DF510010F42D /* libffi-Mac */ = { isa = PBXNativeTarget; - buildConfigurationList = F6F980C4147386130008F121 /* Build configuration list for PBXNativeTarget "libffi iOS" */; + buildConfigurationList = DB13B1B01849DF520010F42D /* Build configuration list for PBXNativeTarget "libffi-Mac" */; buildPhases = ( - 6C43CC3E1534F8E200162364 /* Generate Trampoline */, - 6C43CC3F1534FF1B00162364 /* Generate Source and Headers */, - F6F980B6147386130008F121 /* Sources */, - F6F980B7147386130008F121 /* Frameworks */, - F6F980B8147386130008F121 /* Headers */, + DB13B3061849E0490010F42D /* ShellScript */, + DB13B18D1849DF510010F42D /* Sources */, + DB13B18F1849DF510010F42D /* Headers */, ); buildRules = ( ); dependencies = ( ); - name = "libffi iOS"; + name = "libffi-Mac"; productName = ffi; - productReference = F6F980BA147386130008F121 /* libffi.a */; - productType = "com.apple.product-type.library.static"; + productReference = DB13B1911849DF510010F42D /* ffi.dylib */; + productType = "com.apple.product-type.library.dynamic"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ - F6B0839714721EE50031D8A1 /* Project object */ = { + DB13B15C1849DEB70010F42D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0430; + LastUpgradeCheck = 0510; }; - buildConfigurationList = F6B0839A14721EE50031D8A1 /* Build configuration list for PBXProject "libffi" */; + buildConfigurationList = DB13B15F1849DEB70010F42D /* Build configuration list for PBXProject "libffi" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, ); - mainGroup = F6B0839514721EE50031D8A1; - productRefGroup = F6B0839514721EE50031D8A1; + mainGroup = DB13B15B1849DEB70010F42D; + productRefGroup = DB13B1671849DF1E0010F42D /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - F6F980B9147386130008F121 /* libffi iOS */, - 6C43CB3C1534E9D100162364 /* libffi OS X */, + DB13B1651849DF1E0010F42D /* libffi-iOS */, + DB13B1901849DF510010F42D /* libffi-Mac */, ); }; /* End PBXProject section */ /* Begin PBXShellScriptBuildPhase section */ - 6C43CC3E1534F8E200162364 /* Generate Trampoline */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Generate Trampoline"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /usr/bin/python; - shellScript = "import subprocess\nimport re\nimport os\nimport errno\nimport sys\n\ndef main():\n with open('src/arm/trampoline.S', 'w') as tramp_out:\n p = subprocess.Popen(['bash', 'src/arm/gentramp.sh'], stdout=tramp_out)\n p.wait()\n\nif __name__ == '__main__':\n main()"; - }; - 6C43CC3F1534FF1B00162364 /* Generate Source and Headers */ = { + DB13B3051849E01C0010F42D /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Generate Source and Headers"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/usr/bin/python generate-ios-source-and-headers.py"; + shellScript = "/usr/bin/python generate-darwin-source-and-headers.py --only-ios"; }; - 6C43CC401534FF3B00162364 /* Generate Source and Headers */ = { + DB13B3061849E0490010F42D /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Generate Source and Headers"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/usr/bin/python generate-osx-source-and-headers.py"; + shellScript = "/usr/bin/python generate-darwin-source-and-headers.py --only-osx"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 6C43CB391534E9D100162364 /* Sources */ = { + DB13B1621849DF1E0010F42D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6C43CC1F1534F77800162364 /* darwin.S in Sources */, - 6C43CC201534F77800162364 /* darwin64.S in Sources */, - 6C43CC211534F77800162364 /* ffi.c in Sources */, - 6C43CC221534F77800162364 /* ffi64.c in Sources */, - 6C43CC301534F7BE00162364 /* closures.c in Sources */, - 6C43CC361534F7BE00162364 /* java_raw_api.c in Sources */, - 6C43CC381534F7BE00162364 /* prep_cif.c in Sources */, - 6C43CC3A1534F7BE00162364 /* raw_api.c in Sources */, - 6C43CC3C1534F7BE00162364 /* types.c in Sources */, + DBFA717E187F1D9B00A76262 /* ffi64_x86_64.c in Sources */, + DBFA7179187F1D9B00A76262 /* ffi_armv7.c in Sources */, + DBFA717B187F1D9B00A76262 /* trampoline_armv7.S in Sources */, + DBFA714E187F1D8600A76262 /* closures.c in Sources */, + DBFA717A187F1D9B00A76262 /* sysv_armv7.S in Sources */, + DBFA717D187F1D9B00A76262 /* darwin_i386.S in Sources */, + DBFA7156187F1D8600A76262 /* prep_cif.c in Sources */, + DBFA717F187F1D9B00A76262 /* ffi_i386.c in Sources */, + DBFA7158187F1D8600A76262 /* raw_api.c in Sources */, + DBFA7178187F1D9B00A76262 /* sysv_arm64.S in Sources */, + DBFA717C187F1D9B00A76262 /* darwin64_x86_64.S in Sources */, + DBFA715A187F1D8600A76262 /* types.c in Sources */, + DBFA7177187F1D9B00A76262 /* ffi_arm64.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - F6F980B6147386130008F121 /* Sources */ = { + DB13B18D1849DF510010F42D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6C43CBDC1534F76F00162364 /* ffi.c in Sources */, - 6C43CBDD1534F76F00162364 /* sysv.S in Sources */, - 6C43CBDE1534F76F00162364 /* trampoline.S in Sources */, - 6C43CBE61534F76F00162364 /* darwin.S in Sources */, - 6C43CBE81534F76F00162364 /* ffi.c in Sources */, - 6C43CC2F1534F7BE00162364 /* closures.c in Sources */, - 6C43CC351534F7BE00162364 /* java_raw_api.c in Sources */, - 6C43CC371534F7BE00162364 /* prep_cif.c in Sources */, - 6C43CC391534F7BE00162364 /* raw_api.c in Sources */, - 6C43CC3B1534F7BE00162364 /* types.c in Sources */, + DBFA7196187F1DA100A76262 /* ffi64_x86_64.c in Sources */, + DBFA7195187F1DA100A76262 /* darwin_i386.S in Sources */, + DBFA7157187F1D8600A76262 /* prep_cif.c in Sources */, + DBFA7197187F1DA100A76262 /* ffi_i386.c in Sources */, + DBFA715B187F1D8600A76262 /* types.c in Sources */, + DBFA7159187F1D8600A76262 /* raw_api.c in Sources */, + DBFA714F187F1D8600A76262 /* closures.c in Sources */, + DBFA7194187F1DA100A76262 /* darwin64_x86_64.S in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ - 6C43CB4B1534E9D100162364 /* Debug */ = { + DB13B1601849DEB70010F42D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - DSTROOT = /tmp/ffi.dst; - FRAMEWORK_SEARCH_PATHS = ( + HEADER_SEARCH_PATHS = ( "$(inherited)", - "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"", + "darwin_common/include", ); - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; ONLY_ACTIVE_ARCH = YES; - PRODUCT_NAME = ffi; - SDKROOT = macosx; }; name = Debug; }; - 6C43CB4C1534E9D100162364 /* Release */ = { + DB13B1611849DEB70010F42D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DSTROOT = /tmp/ffi.dst; - FRAMEWORK_SEARCH_PATHS = ( + HEADER_SEARCH_PATHS = ( "$(inherited)", - "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"", + "darwin_common/include", ); - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - MACOSX_DEPLOYMENT_TARGET = 10.6; - PRODUCT_NAME = ffi; - SDKROOT = macosx; }; name = Release; }; - F6B083AB14721EE50031D8A1 /* Debug */ = { + DB13B1871849DF1E0010F42D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; + DSTROOT = /tmp/ffi.dst; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -482,98 +457,181 @@ "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VALUE = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ios/include; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "darwin_ios/include", + ); + IPHONEOS_DEPLOYMENT_TARGET = 5.0; + "IPHONEOS_DEPLOYMENT_TARGET[arch=arm64]" = 7.0; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = ffi; SDKROOT = iphoneos; + SKIP_INSTALL = YES; }; name = Debug; }; - F6B083AC14721EE50031D8A1 /* Release */ = { + DB13B1881849DF1E0010F42D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; + DSTROOT = /tmp/ffi.dst; + ENABLE_NS_ASSERTIONS = NO; GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_PREPROCESSOR_DEFINITIONS = ""; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VALUE = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ios/include; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "darwin_ios/include", + ); + IPHONEOS_DEPLOYMENT_TARGET = 5.0; + "IPHONEOS_DEPLOYMENT_TARGET[arch=arm64]" = 7.0; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = ffi; SDKROOT = iphoneos; + SKIP_INSTALL = YES; VALIDATE_PRODUCT = YES; }; name = Release; }; - F6F980C2147386130008F121 /* Debug */ = { + DB13B1B11849DF520010F42D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - armv6, - armv7, + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", ); - DSTROOT = /tmp/ffi.dst; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_THUMB_SUPPORT = NO; - IPHONEOS_DEPLOYMENT_TARGET = 4.0; - OTHER_LDFLAGS = "-ObjC"; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "darwin_osx/include", + ); + MACOSX_DEPLOYMENT_TARGET = 10.6; + ONLY_ACTIVE_ARCH = YES; + OTHER_LDFLAGS = "-Wl,-no_compact_unwind"; PRODUCT_NAME = ffi; - SKIP_INSTALL = YES; + SDKROOT = macosx; }; name = Debug; }; - F6F980C3147386130008F121 /* Release */ = { + DB13B1B21849DF520010F42D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = ( - armv6, - armv7, + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "darwin_osx/include", ); - DSTROOT = /tmp/ffi.dst; - GCC_PRECOMPILE_PREFIX_HEADER = YES; - GCC_THUMB_SUPPORT = NO; - IPHONEOS_DEPLOYMENT_TARGET = 4.0; - OTHER_LDFLAGS = "-ObjC"; + MACOSX_DEPLOYMENT_TARGET = 10.6; + OTHER_LDFLAGS = "-Wl,-no_compact_unwind"; PRODUCT_NAME = ffi; - SKIP_INSTALL = YES; + SDKROOT = macosx; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 6C43CB4A1534E9D100162364 /* Build configuration list for PBXNativeTarget "libffi OS X" */ = { + DB13B15F1849DEB70010F42D /* Build configuration list for PBXProject "libffi" */ = { isa = XCConfigurationList; buildConfigurations = ( - 6C43CB4B1534E9D100162364 /* Debug */, - 6C43CB4C1534E9D100162364 /* Release */, + DB13B1601849DEB70010F42D /* Debug */, + DB13B1611849DEB70010F42D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - F6B0839A14721EE50031D8A1 /* Build configuration list for PBXProject "libffi" */ = { + DB13B18B1849DF1E0010F42D /* Build configuration list for PBXNativeTarget "libffi-iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - F6B083AB14721EE50031D8A1 /* Debug */, - F6B083AC14721EE50031D8A1 /* Release */, + DB13B1871849DF1E0010F42D /* Debug */, + DB13B1881849DF1E0010F42D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - F6F980C4147386130008F121 /* Build configuration list for PBXNativeTarget "libffi iOS" */ = { + DB13B1B01849DF520010F42D /* Build configuration list for PBXNativeTarget "libffi-Mac" */ = { isa = XCConfigurationList; buildConfigurations = ( - F6F980C2147386130008F121 /* Debug */, - F6F980C3147386130008F121 /* Release */, + DB13B1B11849DF520010F42D /* Debug */, + DB13B1B21849DF520010F42D /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; - rootObject = F6B0839714721EE50031D8A1 /* Project object */; + rootObject = DB13B15C1849DEB70010F42D /* Project object */; } diff --git a/Modules/_ctypes/libffi/libtool-version b/Modules/_ctypes/libffi/libtool-version index e784fc48fb73..d4f501c4d094 100644 --- a/Modules/_ctypes/libffi/libtool-version +++ b/Modules/_ctypes/libffi/libtool-version @@ -26,4 +26,4 @@ # release, then set age to 0. # # CURRENT:REVISION:AGE -6:1:0 +6:2:0 diff --git a/Modules/_ctypes/libffi/ltmain.sh b/Modules/_ctypes/libffi/ltmain.sh old mode 100755 new mode 100644 index 63ae69dc6fec..059598045ef5 --- a/Modules/_ctypes/libffi/ltmain.sh +++ b/Modules/_ctypes/libffi/ltmain.sh @@ -1,9 +1,10 @@ +#! /bin/sh -# libtool (GNU libtool) 2.4.2 +# libtool (GNU libtool) 2.4.2.418 +# Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, -# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. @@ -23,881 +24,2013 @@ # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, -# or obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# along with this program. If not, see . -# Usage: $progname [OPTION]... [MODE-ARG]... -# -# Provide generalized library-building support services. -# -# --config show all configuration variables -# --debug enable verbose shell tracing -# -n, --dry-run display commands without modifying any files -# --features display basic configuration information and exit -# --mode=MODE use operation mode MODE -# --preserve-dup-deps don't remove duplicate dependency libraries -# --quiet, --silent don't print informational messages -# --no-quiet, --no-silent -# print informational messages (default) -# --no-warn don't display warning messages -# --tag=TAG use configuration variables from tag TAG -# -v, --verbose print more informational messages than default -# --no-verbose don't print the extra informational messages -# --version print version information -# -h, --help, --help-all print short, long, or detailed help message -# -# MODE must be one of the following: -# -# clean remove files from the build directory -# compile compile a source file into a libtool object -# execute automatically set library path, then run a program -# finish complete the installation of libtool libraries -# install install libraries or executables -# link create a library or an executable -# uninstall remove libraries from an installed directory -# -# MODE-ARGS vary depending on the MODE. When passed as first option, -# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. -# Try `$progname --help --mode=MODE' for a more detailed description of MODE. -# -# When reporting a bug, please describe a test case to reproduce it and -# include the following information: -# -# host-triplet: $host -# shell: $SHELL -# compiler: $LTCC -# compiler flags: $LTCFLAGS -# linker: $LD (gnu? $with_gnu_ld) -# $progname: (GNU libtool) 2.4.2 -# automake: $automake_version -# autoconf: $autoconf_version -# -# Report bugs to . -# GNU libtool home page: . -# General help using GNU software: . PROGRAM=libtool PACKAGE=libtool -VERSION=2.4.2 -TIMESTAMP="" -package_revision=1.3337 +VERSION=2.4.2.418 +package_revision=2.4.2.418 -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + +## ------ ## +## Usage. ## +## ------ ## + +# Run './libtool --help' for help with using this script from the +# command line. + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# After configure completes, it has a better idea of some of the +# shell tools we need than the defaults used by the functions shared +# with bootstrap, so set those here where they can still be over- +# ridden by the user, but otherwise take precedence. + +: ${AUTOCONF="autoconf"} +: ${AUTOMAKE="automake"} + + +## -------------------------- ## +## Source external libraries. ## +## -------------------------- ## + +# Much of our low-level functionality needs to be sourced from external +# libraries, which are installed to $pkgauxdir. + +# Set a version string for this script. +scriptversion=2013-08-23.20; # UTC + +# General shell script boiler plate, and helper functions. +# Written by Gary V. Vaughan, 2004 + +# Copyright (C) 2004-2013 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# As a special exception to the GNU General Public License, if you distribute +# this file as part of a program or library that is built using GNU Libtool, +# you may include this file under the same distribution terms that you use +# for the rest of that program. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# Evaluate this file near the top of your script to gain access to +# the functions and variables defined here: +# +# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh +# +# If you need to override any of the default environment variable +# settings, do that before evaluating this file. + + +## -------------------- ## +## Shell normalisation. ## +## -------------------- ## + +# Some shells need a little help to be as Bourne compatible as possible. +# Before doing anything else, make sure all that help has been provided! + +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac + case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -$1 -_LTECHO_EOF' -} -# NLS nuisances: We save the old values to restore during execute mode. -lt_user_locale= -lt_safe_locale= -for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +# NLS nuisances: We save the old values in case they are required later. +_G_user_locale= +_G_safe_locale= +for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do - eval "if test \"\${$lt_var+set}\" = set; then - save_$lt_var=\$$lt_var - $lt_var=C - export $lt_var - lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" - lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + eval "if test set = \"\${$_G_var+set}\"; then + save_$_G_var=\$$_G_var + $_G_var=C + export $_G_var + _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" + _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done -LC_ALL=C -LANGUAGE=C -export LANGUAGE LC_ALL -$lt_unset CDPATH +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH +# Make sure IFS has a sensible default +sp=' ' +nl=' +' +IFS="$sp $nl" + +# There are still modern systems that have problems with 'echo' mis- +# handling backslashes, among others, so make sure $bs_echo is set to a +# command that correctly interprets backslashes. +# (this code from Autoconf 2.68) + +# Printing a long string crashes Solaris 7 /usr/bin/printf. +bs_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +bs_echo=$bs_echo$bs_echo$bs_echo$bs_echo$bs_echo +bs_echo=$bs_echo$bs_echo$bs_echo$bs_echo$bs_echo$bs_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $bs_echo`" = "X$bs_echo") 2>/dev/null; then + bs_echo='print -r --' + bs_echo_n='print -rn --' +elif (test "X`printf %s $bs_echo`" = "X$bs_echo") 2>/dev/null; then + bs_echo='printf %s\n' + bs_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $bs_echo) 2>/dev/null`" = "X-n $bs_echo"; then + bs_echo_body='eval /usr/ucb/echo -n "$1$nl"' + bs_echo_n='/usr/ucb/echo -n' + else + bs_echo_body='eval expr "X$1" : "X\\(.*\\)"' + bs_echo_n_body='eval + arg=$1; + case $arg in #( + *"$nl"*) + expr "X$arg" : "X\\(.*\\)$nl"; + arg=`expr "X$arg" : ".*$nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$nl" + ' + export bs_echo_n_body + bs_echo_n='sh -c $bs_echo_n_body bs_echo' + fi + export bs_echo_body + bs_echo='sh -c $bs_echo_body bs_echo' +fi -# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh -# is ksh but when the shell is invoked as "sh" and the current value of -# the _XPG environment variable is not equal to 1 (one), the special -# positional parameter $0, within a function call, is the name of the -# function. -progpath="$0" +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## +# All uppercase variable names are used for environment variables. These +# variables can be overridden by the user before calling a script that +# uses them if a suitable command of that name is not already available +# in the command search PATH. : ${CP="cp -f"} -test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} +: ${ECHO="$bs_echo"} +: ${EGREP="grep -E"} +: ${FGREP="grep -F"} +: ${GREP="grep"} +: ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} +: ${SED="sed"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} -: ${Xsed="$SED -e 1s/^X//"} - -# Global variables: -EXIT_SUCCESS=0 -EXIT_FAILURE=1 -EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. -EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. - -exit_status=$EXIT_SUCCESS - -# Make sure IFS has a sensible default -lt_nl=' -' -IFS=" $lt_nl" -dirname="s,/[^/]*$,," -basename="s,^.*/,," -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi -} # func_dirname may be replaced by extended shell implementation +## -------------------- ## +## Useful sed snippets. ## +## -------------------- ## +sed_dirname='s|/[^/]*$||' +sed_basename='s|^.*/||' -# func_basename file -func_basename () -{ - func_basename_result=`$ECHO "${1}" | $SED "$basename"` -} # func_basename may be replaced by extended shell implementation +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s|\([`"$\\]\)|\\\1|g' +# Same as above, but do not quote variable references. +sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' -# func_dirname_and_basename file append nondir_replacement -# perform func_basename and func_dirname in a single function -# call: -# dirname: Compute the dirname of FILE. If nonempty, -# add APPEND to the result, otherwise set result -# to NONDIR_REPLACEMENT. -# value returned in "$func_dirname_result" -# basename: Compute filename of FILE. -# value retuned in "$func_basename_result" -# Implementation must be kept synchronized with func_dirname -# and func_basename. For efficiency, we do not delegate to -# those functions but instead duplicate the functionality here. -func_dirname_and_basename () -{ - # Extract subdirectory from the argument. - func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi - func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` -} # func_dirname_and_basename may be replaced by extended shell implementation +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' +# Sed substitution that converts a w32 file name or path +# that contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-'\' parameter expansions in output of sed_double_quote_subst that +# were '\'-ed in input to the same. If an odd number of '\' preceded a +# '$' in input to sed_double_quote_subst, that '$' was protected from +# expansion. Since each input '\' is now two '\'s, look for any number +# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. +_G_bs='\\' +_G_bs2='\\\\' +_G_bs4='\\\\\\\\' +_G_dollar='\$' +sed_double_backslash="\ + s/$_G_bs4/&\\ +/g + s/^$_G_bs2$_G_dollar/$_G_bs&/ + s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g + s/\n//g" -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# func_strip_suffix prefix name -func_stripname () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; - esac -} # func_stripname may be replaced by extended shell implementation +## ----------------- ## +## Global variables. ## +## ----------------- ## -# These SED scripts presuppose an absolute path with a trailing slash. -pathcar='s,^/\([^/]*\).*$,\1,' -pathcdr='s,^/[^/]*,,' -removedotparts=':dotsl - s@/\./@/@g - t dotsl - s,/\.$,/,' -collapseslashes='s@/\{1,\}@/@g' -finalslash='s,/*$,/,' +# Except for the global variables explicitly listed below, the following +# functions in the '^func_' namespace, and the '^require_' namespace +# variables initialised in the 'Resource management' section, sourcing +# this file will not pollute your global namespace with anything +# else. There's no portable way to scope variables in Bourne shell +# though, so actually running these functions will sometimes place +# results into a variable named after the function, and often use +# temporary variables in the '^_G_' namespace. If you are careful to +# avoid using those namespaces casually in your sourcing script, things +# should continue to work as you expect. And, of course, you can freely +# overwrite any of the functions or variables defined here before +# calling anything to customize them. -# func_normal_abspath PATH -# Remove doubled-up and trailing slashes, "." path components, -# and cancel out any ".." path components in PATH after making -# it an absolute path. -# value returned in "$func_normal_abspath_result" -func_normal_abspath () -{ - # Start from root dir and reassemble the path. - func_normal_abspath_result= - func_normal_abspath_tpath=$1 - func_normal_abspath_altnamespace= - case $func_normal_abspath_tpath in - "") - # Empty path, that just means $cwd. - func_stripname '' '/' "`pwd`" - func_normal_abspath_result=$func_stripname_result - return - ;; - # The next three entries are used to spot a run of precisely - # two leading slashes without using negated character classes; - # we take advantage of case's first-match behaviour. - ///*) - # Unusual form of absolute path, do nothing. - ;; - //*) - # Not necessarily an ordinary path; POSIX reserves leading '//' - # and for example Cygwin uses it to access remote file shares - # over CIFS/SMB, so we conserve a leading double slash if found. - func_normal_abspath_altnamespace=/ - ;; - /*) - # Absolute path, do nothing. - ;; - *) - # Relative path, prepend $cwd. - func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath - ;; - esac - # Cancel out all the simple stuff to save iterations. We also want - # the path to end with a slash for ease of parsing, so make sure - # there is one (and only one) here. - func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` - while :; do - # Processed it all yet? - if test "$func_normal_abspath_tpath" = / ; then - # If we ascended to the root using ".." the result may be empty now. - if test -z "$func_normal_abspath_result" ; then - func_normal_abspath_result=/ - fi - break - fi - func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$pathcar"` - func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$pathcdr"` - # Figure out what to do with it - case $func_normal_abspath_tcomponent in - "") - # Trailing empty path component, ignore it. - ;; - ..) - # Parent dir; strip last assembled component from result. - func_dirname "$func_normal_abspath_result" - func_normal_abspath_result=$func_dirname_result - ;; - *) - # Actual path component, append it. - func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent - ;; - esac - done - # Restore leading double-slash if one was found on entry. - func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result -} +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. -# func_relative_path SRCDIR DSTDIR -# generates a relative path from SRCDIR to DSTDIR, with a trailing -# slash if non-empty, suitable for immediately appending a filename -# without needing to append a separator. -# value returned in "$func_relative_path_result" -func_relative_path () -{ - func_relative_path_result= - func_normal_abspath "$1" - func_relative_path_tlibdir=$func_normal_abspath_result - func_normal_abspath "$2" - func_relative_path_tbindir=$func_normal_abspath_result - - # Ascend the tree starting from libdir - while :; do - # check if we have found a prefix of bindir - case $func_relative_path_tbindir in - $func_relative_path_tlibdir) - # found an exact match - func_relative_path_tcancelled= - break - ;; - $func_relative_path_tlibdir*) - # found a matching prefix - func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" - func_relative_path_tcancelled=$func_stripname_result - if test -z "$func_relative_path_result"; then - func_relative_path_result=. - fi - break - ;; - *) - func_dirname $func_relative_path_tlibdir - func_relative_path_tlibdir=${func_dirname_result} - if test "x$func_relative_path_tlibdir" = x ; then - # Have to descend all the way to the root! - func_relative_path_result=../$func_relative_path_result - func_relative_path_tcancelled=$func_relative_path_tbindir - break - fi - func_relative_path_result=../$func_relative_path_result - ;; - esac - done +# Allow overriding, eg assuming that you follow the convention of +# putting '$debug_cmd' at the start of all your functions, you can get +# bash to show function call trace with: +# +# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name +debug_cmd=${debug_cmd-":"} +exit_cmd=: - # Now calculate path; take care to avoid doubling-up slashes. - func_stripname '' '/' "$func_relative_path_result" - func_relative_path_result=$func_stripname_result - func_stripname '/' '/' "$func_relative_path_tcancelled" - if test "x$func_stripname_result" != x ; then - func_relative_path_result=${func_relative_path_result}/${func_stripname_result} - fi +# By convention, finish your script with: +# +# exit $exit_status +# +# so that you can set exit_status to non-zero if you want to indicate +# something went wrong during execution without actually bailing out at +# the point of failure. +exit_status=$EXIT_SUCCESS - # Normalisation. If bindir is libdir, return empty string, - # else relative path ending with a slash; either way, target - # file name can be directly appended. - if test ! -z "$func_relative_path_result"; then - func_stripname './' '' "$func_relative_path_result/" - func_relative_path_result=$func_stripname_result - fi -} +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath=$0 -# The name of this program: -func_dirname_and_basename "$progpath" -progname=$func_basename_result +# The name of this program. +progname=`$bs_echo "$progpath" |$SED "$sed_basename"` -# Make sure we have an absolute path for reexecution: +# Make sure we have an absolute progpath for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) - progdir=$func_dirname_result + progdir=`$bs_echo "$progpath" |$SED "$sed_dirname"` progdir=`cd "$progdir" && pwd` - progpath="$progdir/$progname" + progpath=$progdir/$progname ;; *) - save_IFS="$IFS" + _G_IFS=$IFS IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do - IFS="$save_IFS" + IFS=$_G_IFS test -x "$progdir/$progname" && break done - IFS="$save_IFS" + IFS=$_G_IFS test -n "$progdir" || progdir=`pwd` - progpath="$progdir/$progname" + progpath=$progdir/$progname ;; esac -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed="${SED}"' -e 1s/^X//' -sed_quote_subst='s/\([`"$\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\(["`\\]\)/\\\1/g' -# Sed substitution that turns a string into a regex matching for the -# string literally. -sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' +## ----------------- ## +## Standard options. ## +## ----------------- ## -# Sed substitution that converts a w32 file name or path -# which contains forward slashes, into one that contains -# (escaped) backslashes. A very naive implementation. -lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' - -# Re-`\' parameter expansions in output of double_quote_subst that were -# `\'-ed in input to the same. If an odd number of `\' preceded a '$' -# in input to double_quote_subst, that '$' was protected from expansion. -# Since each input `\' is now two `\'s, look for any number of runs of -# four `\'s followed by two `\'s and then a '$'. `\' that '$'. -bs='\\' -bs2='\\\\' -bs4='\\\\\\\\' -dollar='\$' -sed_double_backslash="\ - s/$bs4/&\\ -/g - s/^$bs2$dollar/$bs&/ - s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g - s/\n//g" +# The following options affect the operation of the functions defined +# below, and should be set appropriately depending on run-time para- +# meters passed on the command line. -# Standard options: opt_dry_run=false -opt_help=false opt_quiet=false opt_verbose=false -opt_warning=: -# func_echo arg... -# Echo program name prefixed message, along with the current mode -# name if it has been set yet. -func_echo () +# Categories 'all' and 'none' are always available. Append any others +# you will pass as the first argument to func_warning from your own +# code. +warning_categories= + +# By default, display warnings according to 'opt_warning_types'. Set +# 'warning_func' to ':' to elide all warnings, or func_fatal_error to +# treat the next displayed warning as a fatal error. +warning_func=func_warn_and_continue + +# Set to 'all' to display all warnings, 'none' to suppress all +# warnings, or a space delimited list of some subset of +# 'warning_categories' to display only the listed warnings. +opt_warning_types=all + + +## -------------------- ## +## Resource management. ## +## -------------------- ## + +# This section contains definitions for functions that each ensure a +# particular resource (a file, or a non-empty configuration variable for +# example) is available, and if appropriate to extract default values +# from pertinent package files. Call them using their associated +# 'require_*' variable to ensure that they are executed, at most, once. +# +# It's entirely deliberate that calling these functions can set +# variables that don't obey the namespace limitations obeyed by the rest +# of this file, in order that that they be as useful as possible to +# callers. + + +# require_term_colors +# ------------------- +# Allow display of bold text on terminals that support it. +require_term_colors=func_require_term_colors +func_require_term_colors () { - $ECHO "$progname: ${opt_mode+$opt_mode: }$*" + $debug_cmd + + test -t 1 && { + # COLORTERM and USE_ANSI_COLORS environment variables take + # precedence, because most terminfo databases neglect to describe + # whether color sequences are supported. + test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} + + if test 1 = "$USE_ANSI_COLORS"; then + # Standard ANSI escape sequences + tc_reset='' + tc_bold=''; tc_standout='' + tc_red=''; tc_green='' + tc_blue=''; tc_cyan='' + else + # Otherwise trust the terminfo database after all. + test -n "`tput sgr0 2>/dev/null`" && { + tc_reset=`tput sgr0` + test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` + tc_standout=$tc_bold + test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` + test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` + test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` + test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` + test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` + } + fi + } + + require_term_colors=: } -# func_verbose arg... -# Echo program name prefixed message in verbose mode only. -func_verbose () + +## ----------------- ## +## Function library. ## +## ----------------- ## + +# This section contains a variety of useful functions to call in your +# scripts. Take note of the portable wrappers for features provided by +# some modern shells, which will fall back to slower equivalents on +# less featureful shells. + + +# func_append VAR VALUE +# --------------------- +# Append VALUE onto the existing contents of VAR. + + # We should try to minimise forks, especially on Windows where they are + # unreasonably slow, so skip the feature probes when bash or zsh are + # being used: + if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then + : ${_G_HAVE_ARITH_OP="yes"} + : ${_G_HAVE_XSI_OPS="yes"} + # The += operator was introduced in bash 3.1 + case $BASH_VERSION in + [12].* | 3.0 | 3.0*) ;; + *) + : ${_G_HAVE_PLUSEQ_OP="yes"} + ;; + esac + fi + + # _G_HAVE_PLUSEQ_OP + # Can be empty, in which case the shell is probed, "yes" if += is + # useable or anything else if it does not work. + test -z "$_G_HAVE_PLUSEQ_OP" \ + && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ + && _G_HAVE_PLUSEQ_OP=yes + +if test yes = "$_G_HAVE_PLUSEQ_OP" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_append () + { + $debug_cmd + + eval "$1+=\$2" + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_append () + { + $debug_cmd + + eval "$1=\$$1\$2" + } +fi + + +# func_append_quoted VAR VALUE +# ---------------------------- +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +if test yes = "$_G_HAVE_PLUSEQ_OP"; then + eval 'func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1+=\\ \$func_quote_for_eval_result" + }' +else + func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1=\$$1\\ \$func_quote_for_eval_result" + } +fi + + +# func_append_uniq VAR VALUE +# -------------------------- +# Append unique VALUE onto the existing contents of VAR, assuming +# entries are delimited by the first character of VALUE. For example: +# +# func_append_uniq options " --another-option option-argument" +# +# will only append to $options if " --another-option option-argument " +# is not already present somewhere in $options already (note spaces at +# each end implied by leading space in second argument). +func_append_uniq () { - $opt_verbose && func_echo ${1+"$@"} + $debug_cmd - # A bug in bash halts the script if the last line of a function - # fails when set -e is in force, so we need another command to - # work around that: - : + eval _G_current_value='`$bs_echo $'$1'`' + _G_delim=`expr "$2" : '\(.\)'` + + case $_G_delim$_G_current_value$_G_delim in + *"$2$_G_delim"*) ;; + *) func_append "$@" ;; + esac } -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () + +# func_arith TERM... +# ------------------ +# Set func_arith_result to the result of evaluating TERMs. + test -z "$_G_HAVE_ARITH_OP" \ + && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ + && _G_HAVE_ARITH_OP=yes + +if test yes = "$_G_HAVE_ARITH_OP"; then + eval 'func_arith () + { + $debug_cmd + + func_arith_result=$(( $* )) + }' +else + func_arith () + { + $debug_cmd + + func_arith_result=`expr "$@"` + } +fi + + +# func_basename FILE +# ------------------ +# Set func_basename_result to FILE with everything up to and including +# the last / stripped. +if test yes = "$_G_HAVE_XSI_OPS"; then + # If this shell supports suffix pattern removal, then use it to avoid + # forking. Hide the definitions single quotes in case the shell chokes + # on unsupported syntax... + _b='func_basename_result=${1##*/}' + _d='case $1 in + */*) func_dirname_result=${1%/*}$2 ;; + * ) func_dirname_result=$3 ;; + esac' + +else + # ...otherwise fall back to using sed. + _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' + _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` + if test "X$func_dirname_result" = "X$1"; then + func_dirname_result=$3 + else + func_append func_dirname_result "$2" + fi' +fi + +eval 'func_basename () { - $ECHO "$*" -} + $debug_cmd + + '"$_b"' +}' + + +# func_dirname FILE APPEND NONDIR_REPLACEMENT +# ------------------------------------------- +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +eval 'func_dirname () +{ + $debug_cmd + + '"$_d"' +}' + + +# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT +# -------------------------------------------------------- +# Perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# For efficiency, we do not delegate to the functions above but instead +# duplicate the functionality here. +eval 'func_dirname_and_basename () +{ + $debug_cmd + + '"$_b"' + '"$_d"' +}' + + +# func_echo ARG... +# ---------------- +# Echo program name prefixed message. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $bs_echo "$progname: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_echo_all ARG... +# -------------------- +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + + +# func_echo_infix_1 INFIX ARG... +# ------------------------------ +# Echo program name, followed by INFIX on the first line, with any +# additional lines not showing INFIX. +func_echo_infix_1 () +{ + $debug_cmd + + $require_term_colors + + _G_infix=$1; shift + _G_indent=$_G_infix + _G_prefix="$progname: $_G_infix: " + _G_message=$* + + # Strip color escape sequences before counting printable length + for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" + do + test -n "$_G_tc" && { + _G_esc_tc=`$bs_echo "$_G_tc" | sed "$sed_make_literal_regex"` + _G_indent=`$bs_echo "$_G_indent" | sed "s|$_G_esc_tc||g"` + } + done + _G_indent="$progname: "`echo "$_G_indent" | sed 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes + + func_echo_infix_1_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_infix_1_IFS + $bs_echo "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 + _G_prefix=$_G_indent + done + IFS=$func_echo_infix_1_IFS +} + + +# func_error ARG... +# ----------------- +# Echo program name prefixed message to standard error. +func_error () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 +} + + +# func_fatal_error ARG... +# ----------------------- +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + $debug_cmd + + func_error "$*" + exit $EXIT_FAILURE +} + + +# func_grep EXPRESSION FILENAME +# ----------------------------- +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $debug_cmd + + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_len STRING +# --------------- +# Set func_len_result to the length of STRING. STRING may not +# start with a hyphen. + test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_len () + { + $debug_cmd + + func_len_result=${#1} + }' +else + func_len () + { + $debug_cmd + + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` + } +fi + + +# func_mkdir_p DIRECTORY-PATH +# --------------------------- +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + $debug_cmd + + _G_directory_path=$1 + _G_dir_list= + + if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then + + # Protect directory names starting with '-' + case $_G_directory_path in + -*) _G_directory_path=./$_G_directory_path ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$_G_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + _G_dir_list=$_G_directory_path:$_G_dir_list + + # If the last portion added has no slash in it, the list is done + case $_G_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` + done + _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` + + func_mkdir_p_IFS=$IFS; IFS=: + for _G_dir in $_G_dir_list; do + IFS=$func_mkdir_p_IFS + # mkdir can fail with a 'File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$_G_dir" 2>/dev/null || : + done + IFS=$func_mkdir_p_IFS + + # Bail out if we (or some other process) failed to create a directory. + test -d "$_G_directory_path" || \ + func_fatal_error "Failed to create '$1'" + fi +} + + +# func_mktempdir [BASENAME] +# ------------------------- +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, BASENAME is the basename for that directory. +func_mktempdir () +{ + $debug_cmd + + _G_template=${TMPDIR-/tmp}/${1-$progname} + + if test : = "$opt_dry_run"; then + # Return a directory name, but don't create it in dry-run mode + _G_tmpdir=$_G_template-$$ + else + + # If mktemp works, use that first and foremost + _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` + + if test ! -d "$_G_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + _G_tmpdir=$_G_template-${RANDOM-0}$$ + + func_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$_G_tmpdir" + umask $func_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$_G_tmpdir" || \ + func_fatal_error "cannot create temporary directory '$_G_tmpdir'" + fi + + $ECHO "$_G_tmpdir" +} + + +# func_normal_abspath PATH +# ------------------------ +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +func_normal_abspath () +{ + $debug_cmd + + # These SED scripts presuppose an absolute path with a trailing slash. + _G_pathcar='s|^/\([^/]*\).*$|\1|' + _G_pathcdr='s|^/[^/]*||' + _G_removedotparts=':dotsl + s|/\./|/|g + t dotsl + s|/\.$|/|' + _G_collapseslashes='s|/\{1,\}|/|g' + _G_finalslash='s|/*$|/|' + + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` + while :; do + # Processed it all yet? + if test / = "$func_normal_abspath_tpath"; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result"; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + + +# func_notquiet ARG... +# -------------------- +# Echo program name prefixed message only when not in quiet mode. +func_notquiet () +{ + $debug_cmd + + $opt_quiet || func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + + +# func_relative_path SRCDIR DSTDIR +# -------------------------------- +# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. +func_relative_path () +{ + $debug_cmd + + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=$func_dirname_result + if test -z "$func_relative_path_tlibdir"; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test -n "$func_stripname_result"; then + func_append func_relative_path_result "/$func_stripname_result" + fi + + # Normalisation. If bindir is libdir, return '.' else relative path. + if test -n "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + fi + + test -n "$func_relative_path_result" || func_relative_path_result=. + + : +} + + +# func_quote_for_eval ARG... +# -------------------------- +# Aesthetically quote ARGs to be evaled later. +# This function returns two values: +# i) func_quote_for_eval_result +# double-quoted, suitable for a subsequent eval +# ii) func_quote_for_eval_unquoted_result +# has all characters that are still active within double +# quotes backslashified. +func_quote_for_eval () +{ + $debug_cmd + + func_quote_for_eval_unquoted_result= + func_quote_for_eval_result= + while test 0 -lt $#; do + case $1 in + *[\\\`\"\$]*) + _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; + *) + _G_unquoted_arg=$1 ;; + esac + if test -n "$func_quote_for_eval_unquoted_result"; then + func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" + else + func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" + fi + + case $_G_unquoted_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and variable expansion + # for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_quoted_arg=\"$_G_unquoted_arg\" + ;; + *) + _G_quoted_arg=$_G_unquoted_arg + ;; + esac + + if test -n "$func_quote_for_eval_result"; then + func_append func_quote_for_eval_result " $_G_quoted_arg" + else + func_append func_quote_for_eval_result "$_G_quoted_arg" + fi + shift + done +} + + +# func_quote_for_expand ARG +# ------------------------- +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + $debug_cmd + + case $1 in + *[\\\`\"]*) + _G_arg=`$ECHO "$1" | $SED \ + -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; + *) + _G_arg=$1 ;; + esac + + case $_G_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_arg=\"$_G_arg\" + ;; + esac + + func_quote_for_expand_result=$_G_arg +} + + +# func_stripname PREFIX SUFFIX NAME +# --------------------------------- +# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_stripname () + { + $debug_cmd + + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary variable first. + func_stripname_result=$3 + func_stripname_result=${func_stripname_result#"$1"} + func_stripname_result=${func_stripname_result%"$2"} + }' +else + func_stripname () + { + $debug_cmd + + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; + esac + } +fi + + +# func_show_eval CMD [FAIL_EXP] +# ----------------------------- +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + func_quote_for_expand "$_G_cmd" + eval "func_notquiet $func_quote_for_expand_result" + + $opt_dry_run || { + eval "$_G_cmd" + _G_status=$? + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_show_eval_locale CMD [FAIL_EXP] +# ------------------------------------ +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + $opt_quiet || { + func_quote_for_expand "$_G_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + $opt_dry_run || { + eval "$_G_user_locale + $_G_cmd" + _G_status=$? + eval "$_G_safe_locale" + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_tr_sh +# ---------- +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + $debug_cmd + + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_verbose ARG... +# ------------------- +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $debug_cmd + + $opt_verbose && func_echo "$*" + + : +} + + +# func_warn_and_continue ARG... +# ----------------------------- +# Echo program name prefixed warning message to standard error. +func_warn_and_continue () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 +} + + +# func_warning CATEGORY ARG... +# ---------------------------- +# Echo program name prefixed warning message to standard error. Warning +# messages can be filtered according to CATEGORY, where this function +# elides messages where CATEGORY is not listed in the global variable +# 'opt_warning_types'. +func_warning () +{ + $debug_cmd + + # CATEGORY must be in the warning_categories list! + case " $warning_categories " in + *" $1 "*) ;; + *) func_internal_error "invalid warning category '$1'" ;; + esac + + _G_category=$1 + shift + + case " $opt_warning_types " in + *" $_G_category "*) $warning_func ${1+"$@"} ;; + esac +} + + +# func_sort_ver VER1 VER2 +# ----------------------- +# 'sort -V' is not generally available. +# Note this deviates from the version comparison in automake +# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a +# but this should suffice as we won't be specifying old +# version formats or redundant trailing .0 in bootstrap.conf. +# If we did want full compatibility then we should probably +# use m4_version_compare from autoconf. +func_sort_ver () +{ + $debug_cmd + + ver1=$1 + ver2=$2 + + # Split on '.' and compare each component. + i=1 + while :; do + p1=`echo "$ver1" |cut -d. -f$i` + p2=`echo "$ver2" |cut -d. -f$i` + if test ! "$p1"; then + echo "$1 $2" + break + elif test ! "$p2"; then + echo "$2 $1" + break + elif test ! "$p1" = "$p2"; then + if test "$p1" -gt "$p2" 2>/dev/null; then # numeric comparison + echo "$2 $1" + elif test "$p2" -gt "$p1" 2>/dev/null; then # numeric comparison + echo "$1 $2" + else # numeric, then lexicographic comparison + lp=`printf "$p1\n$p2\n" |sort -n |tail -n1` + if test "$lp" = "$p2"; then + echo "$1 $2" + else + echo "$2 $1" + fi + fi + break + fi + i=`expr $i + 1` + done +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: +#! /bin/sh + +# Set a version string for this script. +scriptversion=2012-10-21.11; # UTC + +# A portable, pluggable option parser for Bourne shell. +# Written by Gary V. Vaughan, 2010 + +# Copyright (C) 2010-2013 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# This file is a library for parsing options in your shell scripts along +# with assorted other useful supporting features that you can make use +# of too. +# +# For the simplest scripts you might need only: +# +# #!/bin/sh +# . relative/path/to/funclib.sh +# . relative/path/to/options-parser +# scriptversion=1.0 +# func_options ${1+"$@"} +# eval set dummy "$func_options_result"; shift +# ...rest of your script... +# +# In order for the '--version' option to work, you will need to have a +# suitably formatted comment like the one at the top of this file +# starting with '# Written by ' and ending with '# warranty; '. +# +# For '-h' and '--help' to work, you will also need a one line +# description of your script's purpose in a comment directly above the +# '# Written by ' line, like the one at the top of this file. +# +# The default options also support '--debug', which will turn on shell +# execution tracing (see the comment above debug_cmd below for another +# use), and '--verbose' and the func_verbose function to allow your script +# to display verbose messages only when your user has specified +# '--verbose'. +# +# After sourcing this file, you can plug processing for additional +# options by amending the variables from the 'Configuration' section +# below, and following the instructions in the 'Option parsing' +# section further down. + +## -------------- ## +## Configuration. ## +## -------------- ## + +# You should override these variables in your script after sourcing this +# file so that they reflect the customisations you have added to the +# option parser. + +# The usage line for option parsing errors and the start of '-h' and +# '--help' output messages. You can embed shell variables for delayed +# expansion at the time the message is displayed, but you will need to +# quote other shell meta-characters carefully to prevent them being +# expanded when the contents are evaled. +usage='$progpath [OPTION]...' + +# Short help message in response to '-h' and '--help'. Add to this or +# override it after sourcing this library to reflect the full set of +# options your script accepts. +usage_message="\ + --debug enable verbose shell tracing + -W, --warnings=CATEGORY + report the warnings falling in CATEGORY [all] + -v, --verbose verbosely report processing + --version print version information and exit + -h, --help print short or long help message and exit +" + +# Additional text appended to 'usage_message' in response to '--help'. +long_help_message=" +Warning categories include: + 'all' show all warnings + 'none' turn off all the warnings + 'error' warnings are treated as fatal errors" + +# Help message printed before fatal option parsing errors. +fatal_help="Try '\$progname --help' for more information." + + + +## ------------------------- ## +## Hook function management. ## +## ------------------------- ## + +# This section contains functions for adding, removing, and running hooks +# to the main code. A hook is just a named list of of function, that can +# be run in order later on. + +# func_hookable FUNC_NAME +# ----------------------- +# Declare that FUNC_NAME will run hooks added with +# 'func_add_hook FUNC_NAME ...'. +func_hookable () +{ + $debug_cmd + + func_append hookable_fns " $1" +} + + +# func_add_hook FUNC_NAME HOOK_FUNC +# --------------------------------- +# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must +# first have been declared "hookable" by a call to 'func_hookable'. +func_add_hook () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not accept hook functions." ;; + esac + + eval func_append ${1}_hooks '" $2"' +} + + +# func_remove_hook FUNC_NAME HOOK_FUNC +# ------------------------------------ +# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. +func_remove_hook () +{ + $debug_cmd + + eval ${1}_hooks='`$bs_echo "\$'$1'_hooks" |$SED "s| '$2'||"`' +} + + +# func_run_hooks FUNC_NAME [ARG]... +# --------------------------------- +# Run all hook functions registered to FUNC_NAME. +# It is assumed that the list of hook functions contains nothing more +# than a whitespace-delimited list of legal shell function names, and +# no effort is wasted trying to catch shell meta-characters or preserve +# whitespace. +func_run_hooks () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not support hook functions." ;; + esac + + eval _G_hook_fns=\$$1_hooks; shift + + for _G_hook in $_G_hook_fns; do + eval $_G_hook '"$@"' + + # store returned options list back into positional + # parameters for next 'cmd' execution. + eval _G_hook_result=\$${_G_hook}_result + eval set dummy "$_G_hook_result"; shift + done + + func_quote_for_eval ${1+"$@"} + func_run_hooks_result=$func_quote_for_eval_result +} + + + +## --------------- ## +## Option parsing. ## +## --------------- ## + +# In order to add your own option parsing hooks, you must accept the +# full positional parameter list in your hook function, remove any +# options that you action, and then pass back the remaining unprocessed +# options in '_result', escaped suitably for +# 'eval'. Like this: +# +# my_options_prep () +# { +# $debug_cmd +# +# # Extend the existing usage message. +# usage_message=$usage_message' +# -s, --silent don'\''t print informational messages +# ' +# +# func_quote_for_eval ${1+"$@"} +# my_options_prep_result=$func_quote_for_eval_result +# } +# func_add_hook func_options_prep my_options_prep +# +# +# my_silent_option () +# { +# $debug_cmd +# +# # Note that for efficiency, we parse as many options as we can +# # recognise in a loop before passing the remainder back to the +# # caller on the first unrecognised argument we encounter. +# while test $# -gt 0; do +# opt=$1; shift +# case $opt in +# --silent|-s) opt_silent=: ;; +# # Separate non-argument short options: +# -s*) func_split_short_opt "$_G_opt" +# set dummy "$func_split_short_opt_name" \ +# "-$func_split_short_opt_arg" ${1+"$@"} +# shift +# ;; +# *) set dummy "$_G_opt" "$*"; shift; break ;; +# esac +# done +# +# func_quote_for_eval ${1+"$@"} +# my_silent_option_result=$func_quote_for_eval_result +# } +# func_add_hook func_parse_options my_silent_option +# +# +# my_option_validation () +# { +# $debug_cmd +# +# $opt_silent && $opt_verbose && func_fatal_help "\ +# '--silent' and '--verbose' options are mutually exclusive." +# +# func_quote_for_eval ${1+"$@"} +# my_option_validation_result=$func_quote_for_eval_result +# } +# func_add_hook func_validate_options my_option_validation +# +# You'll alse need to manually amend $usage_message to reflect the extra +# options you parse. It's preferable to append if you can, so that +# multiple option parsing hooks can be added safely. -# func_error arg... -# Echo program name prefixed message to standard error. -func_error () -{ - $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 -} -# func_warning arg... -# Echo program name prefixed warning message to standard error. -func_warning () +# func_options [ARG]... +# --------------------- +# All the functions called inside func_options are hookable. See the +# individual implementations for details. +func_hookable func_options +func_options () { - $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 + $debug_cmd - # bash bug again: - : -} + func_options_prep ${1+"$@"} + eval func_parse_options \ + ${func_options_prep_result+"$func_options_prep_result"} + eval func_validate_options \ + ${func_parse_options_result+"$func_parse_options_result"} -# func_fatal_error arg... -# Echo program name prefixed message to standard error, and exit. -func_fatal_error () -{ - func_error ${1+"$@"} - exit $EXIT_FAILURE -} + eval func_run_hooks func_options \ + ${func_validate_options_result+"$func_validate_options_result"} -# func_fatal_help arg... -# Echo program name prefixed message to standard error, followed by -# a help hint, and exit. -func_fatal_help () -{ - func_error ${1+"$@"} - func_fatal_error "$help" + # save modified positional parameters for caller + func_options_result=$func_run_hooks_result } -help="Try \`$progname --help' for more information." ## default -# func_grep expression filename -# Check whether EXPRESSION matches any line of FILENAME, without output. -func_grep () +# func_options_prep [ARG]... +# -------------------------- +# All initialisations required before starting the option parse loop. +# Note that when calling hook functions, we pass through the list of +# positional parameters. If a hook function modifies that list, and +# needs to propogate that back to rest of this script, then the complete +# modified list must be put in 'func_run_hooks_result' before +# returning. +func_hookable func_options_prep +func_options_prep () { - $GREP "$1" "$2" >/dev/null 2>&1 + $debug_cmd + + # Option defaults: + opt_verbose=false + opt_warning_types= + + func_run_hooks func_options_prep ${1+"$@"} + + # save modified positional parameters for caller + func_options_prep_result=$func_run_hooks_result } -# func_mkdir_p directory-path -# Make sure the entire path to DIRECTORY-PATH is available. -func_mkdir_p () +# func_parse_options [ARG]... +# --------------------------- +# The main option parsing loop. +func_hookable func_parse_options +func_parse_options () { - my_directory_path="$1" - my_dir_list= + $debug_cmd - if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + func_parse_options_result= - # Protect directory names starting with `-' - case $my_directory_path in - -*) my_directory_path="./$my_directory_path" ;; - esac + # this just eases exit handling + while test $# -gt 0; do + # Defer to hook functions for initial option parsing, so they + # get priority in the event of reusing an option name. + func_run_hooks func_parse_options ${1+"$@"} - # While some portion of DIR does not yet exist... - while test ! -d "$my_directory_path"; do - # ...make a list in topmost first order. Use a colon delimited - # list incase some portion of path contains whitespace. - my_dir_list="$my_directory_path:$my_dir_list" + # Adjust func_parse_options positional parameters to match + eval set dummy "$func_run_hooks_result"; shift - # If the last portion added has no slash in it, the list is done - case $my_directory_path in */*) ;; *) break ;; esac + # Break out of the loop if we already parsed every option. + test $# -gt 0 || break - # ...otherwise throw away the child directory and loop - my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` - done - my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` + _G_opt=$1 + shift + case $_G_opt in + --debug|-x) debug_cmd='set -x' + func_echo "enabling shell trace mode" + $debug_cmd + ;; + + --no-warnings|--no-warning|--no-warn) + set dummy --warnings none ${1+"$@"} + shift + ;; - save_mkdir_p_IFS="$IFS"; IFS=':' - for my_dir in $my_dir_list; do - IFS="$save_mkdir_p_IFS" - # mkdir can fail with a `File exist' error if two processes - # try to create one of the directories concurrently. Don't - # stop in that case! - $MKDIR "$my_dir" 2>/dev/null || : - done - IFS="$save_mkdir_p_IFS" + --warnings|--warning|-W) + test $# = 0 && func_missing_arg $_G_opt && break + case " $warning_categories $1" in + *" $1 "*) + # trailing space prevents matching last $1 above + func_append_uniq opt_warning_types " $1" + ;; + *all) + opt_warning_types=$warning_categories + ;; + *none) + opt_warning_types=none + warning_func=: + ;; + *error) + opt_warning_types=$warning_categories + warning_func=func_fatal_error + ;; + *) + func_fatal_error \ + "unsupported warning category: '$1'" + ;; + esac + shift + ;; + + --verbose|-v) opt_verbose=: ;; + --version) func_version ;; + -\?|-h) func_usage ;; + --help) func_help ;; + + # Separate optargs to long options (plugins may need this): + --*=*) func_split_equals "$_G_opt" + set dummy "$func_split_equals_lhs" \ + "$func_split_equals_rhs" ${1+"$@"} + shift + ;; + + # Separate optargs to short options: + -W*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-v*|-x*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done - # Bail out if we (or some other process) failed to create a directory. - test -d "$my_directory_path" || \ - func_fatal_error "Failed to create \`$1'" - fi + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + func_parse_options_result=$func_quote_for_eval_result } -# func_mktempdir [string] -# Make a temporary directory that won't clash with other running -# libtool processes, and avoids race conditions if possible. If -# given, STRING is the basename for that directory. -func_mktempdir () +# func_validate_options [ARG]... +# ------------------------------ +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +func_hookable func_validate_options +func_validate_options () { - my_template="${TMPDIR-/tmp}/${1-$progname}" + $debug_cmd - if test "$opt_dry_run" = ":"; then - # Return a directory name, but don't create it in dry-run mode - my_tmpdir="${my_template}-$$" - else + # Display all warnings if -W was not given. + test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" - # If mktemp works, use that first and foremost - my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + func_run_hooks func_validate_options ${1+"$@"} - if test ! -d "$my_tmpdir"; then - # Failing that, at least try and use $RANDOM to avoid a race - my_tmpdir="${my_template}-${RANDOM-0}$$" + # Bail if the options were screwed! + $exit_cmd $EXIT_FAILURE - save_mktempdir_umask=`umask` - umask 0077 - $MKDIR "$my_tmpdir" - umask $save_mktempdir_umask - fi + # save modified positional parameters for caller + func_validate_options_result=$func_run_hooks_result +} - # If we're not in dry-run mode, bomb out on failure - test -d "$my_tmpdir" || \ - func_fatal_error "cannot create temporary directory \`$my_tmpdir'" - fi - $ECHO "$my_tmpdir" -} +## ------------------## +## Helper functions. ## +## ------------------## -# func_quote_for_eval arg -# Aesthetically quote ARG to be evaled later. -# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT -# is double-quoted, suitable for a subsequent eval, whereas -# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters -# which are still active within double quotes backslashified. -func_quote_for_eval () +# This section contains the helper functions used by the rest of the +# hookable option parser framework in ascii-betical order. + + +# func_fatal_help ARG... +# ---------------------- +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () { - case $1 in - *[\\\`\"\$]*) - func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; - *) - func_quote_for_eval_unquoted_result="$1" ;; - esac + $debug_cmd - case $func_quote_for_eval_unquoted_result in - # Double-quote args containing shell metacharacters to delay - # word splitting, command substitution and and variable - # expansion for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" - ;; - *) - func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" - esac + eval \$bs_echo \""Usage: $usage"\" + eval \$bs_echo \""$fatal_help"\" + func_error ${1+"$@"} + exit $EXIT_FAILURE } -# func_quote_for_expand arg -# Aesthetically quote ARG to be evaled later; same as above, -# but do not quote variable references. -func_quote_for_expand () +# func_help +# --------- +# Echo long help message to standard output and exit. +func_help () { - case $1 in - *[\\\`\"]*) - my_arg=`$ECHO "$1" | $SED \ - -e "$double_quote_subst" -e "$sed_double_backslash"` ;; - *) - my_arg="$1" ;; - esac - - case $my_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting and command substitution for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - my_arg="\"$my_arg\"" - ;; - esac + $debug_cmd - func_quote_for_expand_result="$my_arg" + func_usage_message + $bs_echo "$long_help_message" + exit 0 } -# func_show_eval cmd [fail_exp] -# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. -func_show_eval () +# func_missing_arg ARGNAME +# ------------------------ +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () { - my_cmd="$1" - my_fail_exp="${2-:}" - - ${opt_silent-false} || { - func_quote_for_expand "$my_cmd" - eval "func_echo $func_quote_for_expand_result" - } + $debug_cmd - if ${opt_dry_run-false}; then :; else - eval "$my_cmd" - my_status=$? - if test "$my_status" -eq 0; then :; else - eval "(exit $my_status); $my_fail_exp" - fi - fi + func_error "Missing argument for '$1'." + exit_cmd=exit } -# func_show_eval_locale cmd [fail_exp] -# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. Use the saved locale for evaluation. -func_show_eval_locale () -{ - my_cmd="$1" - my_fail_exp="${2-:}" +# func_split_equals STRING +# ------------------------ +# Set func_split_equals_lhs and func_split_equals_rhs shell variables after +# splitting STRING at the '=' sign. +test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes - ${opt_silent-false} || { - func_quote_for_expand "$my_cmd" - eval "func_echo $func_quote_for_expand_result" - } +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_equals () + { + $debug_cmd - if ${opt_dry_run-false}; then :; else - eval "$lt_user_locale - $my_cmd" - my_status=$? - eval "$lt_safe_locale" - if test "$my_status" -eq 0; then :; else - eval "(exit $my_status); $my_fail_exp" - fi - fi -} + func_split_equals_lhs=${1%%=*} + func_split_equals_rhs=${1#*=} + test "x$func_split_equals_lhs" = "x$1" \ + && func_split_equals_rhs= + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_equals () + { + $debug_cmd -# func_tr_sh -# Turn $1 into a string suitable for a shell variable name. -# Result is stored in $func_tr_sh_result. All characters -# not in the set a-zA-Z0-9_ are replaced with '_'. Further, -# if $1 begins with a digit, a '_' is prepended as well. -func_tr_sh () -{ - case $1 in - [0-9]* | *[!a-zA-Z0-9_]*) - func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` - ;; - * ) - func_tr_sh_result=$1 - ;; - esac -} + func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` + func_split_equals_rhs= + test "x$func_split_equals_lhs" = "x$1" \ + || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` + } +fi #func_split_equals -# func_version -# Echo version message to standard output and exit. -func_version () -{ - $opt_debug +# func_split_short_opt SHORTOPT +# ----------------------------- +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"} + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` + func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` + } +fi #func_split_short_opt - $SED -n '/(C)/!b go - :more - /\./!{ - N - s/\n# / / - b more - } - :go - /^# '$PROGRAM' (GNU /,/# warranty; / { - s/^# // - s/^# *$// - s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ - p - }' < "$progpath" - exit $? -} # func_usage +# ---------- # Echo short help message to standard output and exit. func_usage () { - $opt_debug + $debug_cmd - $SED -n '/^# Usage:/,/^# *.*--help/ { - s/^# // - s/^# *$// - s/\$progname/'$progname'/ - p - }' < "$progpath" - echo - $ECHO "run \`$progname --help | more' for full usage" - exit $? + func_usage_message + $bs_echo "Run '$progname --help |${PAGER-more}' for full usage" + exit 0 } -# func_help [NOEXIT] -# Echo long help message to standard output and exit, -# unless 'noexit' is passed as argument. -func_help () + +# func_usage_message +# ------------------ +# Echo short help message to standard output. +func_usage_message () { - $opt_debug - - $SED -n '/^# Usage:/,/# Report bugs to/ { - :print - s/^# // - s/^# *$// - s*\$progname*'$progname'* - s*\$host*'"$host"'* - s*\$SHELL*'"$SHELL"'* - s*\$LTCC*'"$LTCC"'* - s*\$LTCFLAGS*'"$LTCFLAGS"'* - s*\$LD*'"$LD"'* - s/\$with_gnu_ld/'"$with_gnu_ld"'/ - s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ - s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ - p - d - } - /^# .* home page:/b print - /^# General help using/b print - ' < "$progpath" - ret=$? - if test -z "$1"; then - exit $ret - fi + $debug_cmd + + eval \$bs_echo \""Usage: $usage"\" + echo + $SED -n 's|^# || + /^Written by/{ + x;p;x + } + h + /^Written by/q' < "$progpath" + echo + eval \$bs_echo \""$usage_message"\" } -# func_missing_arg argname -# Echo program name prefixed message to standard error and set global -# exit_cmd. -func_missing_arg () + +# func_version +# ------------ +# Echo version message to standard output and exit. +func_version () { - $opt_debug + $debug_cmd + + printf '%s\n' "$progname $scriptversion" + $SED -n '/^##/q + /(C)/!b go + :more + /\./!{ + N + s|\n# | | + b more + } + :go + /^# Written by /,/# warranty; / { + s|^# || + s|^# *$|| + s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| + p + } + /^# Written by / { + s|^# || + p + } + /^warranty; /q' < "$progpath" - func_error "missing argument for $1." - exit_cmd=exit + exit $? } -# func_split_short_opt shortopt -# Set func_split_short_opt_name and func_split_short_opt_arg shell -# variables after splitting SHORTOPT after the 2nd character. -func_split_short_opt () -{ - my_sed_short_opt='1s/^\(..\).*$/\1/;q' - my_sed_short_rest='1s/^..\(.*\)$/\1/;q' +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: - func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` - func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` -} # func_split_short_opt may be replaced by extended shell implementation +# Set a version string. +scriptversion='(GNU libtool) 2.4.2.418' -# func_split_long_opt longopt -# Set func_split_long_opt_name and func_split_long_opt_arg shell -# variables after splitting LONGOPT at the `=' sign. -func_split_long_opt () +# func_echo ARG... +# ---------------- +# Libtool also displays the current mode in messages, so override +# funclib.sh func_echo with this custom definition. +func_echo () { - my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' - my_sed_long_arg='1s/^--[^=]*=//' + $debug_cmd - func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` - func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` -} # func_split_long_opt may be replaced by extended shell implementation + _G_message=$* -exit_cmd=: + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $bs_echo "$progname${opt_mode+: $opt_mode}: $_G_line" + done + IFS=$func_echo_IFS +} +# func_warning ARG... +# ------------------- +# Libtool warnings are not categorized, so override funclib.sh +# func_warning with this simpler definition. +func_warning () +{ + $debug_cmd + $warning_func ${1+"$@"} +} -magic="%%%MAGIC variable%%%" -magic_exe="%%%MAGIC EXE variable%%%" +## ---------------- ## +## Options parsing. ## +## ---------------- ## + +# Hook in the functions to make sure our own options are parsed during +# the option parsing loop. + +usage='$progpath [OPTION]... [MODE-ARG]...' + +# Short help message in response to '-h'. +usage_message="Options: + --config show all configuration variables + --debug enable verbose shell tracing + -n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --mode=MODE use operation mode MODE + --no-warnings equivalent to '-Wnone' + --preserve-dup-deps don't remove duplicate dependency libraries + --quiet, --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + -v, --verbose print more informational messages than default + --version print version information + -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] + -h, --help, --help-all print short, long, or detailed help message +" -# Global variables. -nonopt= -preserve_args= -lo2o="s/\\.lo\$/.${objext}/" -o2lo="s/\\.${objext}\$/.lo/" -extracted_archives= -extracted_serial=0 +# Additional text appended to 'usage_message' in response to '--help'. +long_help_message=$long_help_message" -# If this variable is set in any of the actions, the command in it -# will be execed at the end. This prevents here-documents from being -# left over by shells. -exec_cmd= +MODE must be one of the following: -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "${1}=\$${1}\${2}" -} # func_append may be replaced by extended shell implementation + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory -# func_append_quoted var value -# Quote VALUE and append to the end of shell variable VAR, separated -# by a space. -func_append_quoted () -{ - func_quote_for_eval "${2}" - eval "${1}=\$${1}\\ \$func_quote_for_eval_result" -} # func_append_quoted may be replaced by extended shell implementation +MODE-ARGS vary depending on the MODE. When passed as first option, +'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. +Try '$progname --help --mode=MODE' for a more detailed description of MODE. +When reporting a bug, please describe a test case to reproduce it and +include the following information: -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=`expr "${@}"` -} # func_arith may be replaced by extended shell implementation + host-triplet: $host + shell: $SHELL + compiler: $LTCC + compiler flags: $LTCFLAGS + linker: $LD (gnu? $with_gnu_ld) + version: $progname (GNU libtool) 2.4.2.418 + automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` + autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` +Report bugs to . +GNU libtool home page: . +General help using GNU software: ." -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` -} # func_len may be replaced by extended shell implementation +# func_lo2o OBJECT-NAME +# --------------------- +# Transform OBJECT-NAME from a '.lo' suffix to the platform specific +# object suffix. -# func_lo2o object -func_lo2o () -{ - func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` -} # func_lo2o may be replaced by extended shell implementation +lo2o=s/\\.lo\$/.$objext/ +o2lo=s/\\.$objext\$/.lo/ + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_lo2o () + { + case $1 in + *.lo) func_lo2o_result=${1%.lo}.$objext ;; + * ) func_lo2o_result=$1 ;; + esac + }' + # func_xform LIBOBJ-OR-SOURCE + # --------------------------- + # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) + # suffix to a '.lo' libtool-object suffix. + eval 'func_xform () + { + func_xform_result=${1%.*}.lo + }' +else + # ...otherwise fall back to using sed. + func_lo2o () + { + func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` + } -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` -} # func_xform may be replaced by extended shell implementation + func_xform () + { + func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` + } +fi -# func_fatal_configuration arg... +# func_fatal_configuration ARG... +# ------------------------------- # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { - func_error ${1+"$@"} - func_error "See the $PACKAGE documentation for more information." - func_fatal_error "Fatal configuration error." + func__fatal_error ${1+"$@"} \ + "See the $PACKAGE documentation for more information." \ + "Fatal configuration error." } # func_config +# ----------- # Display the configuration for all the tags in this script. func_config () { @@ -915,17 +2048,19 @@ func_config () exit $? } + # func_features +# ------------- # Display the features supported by this script. func_features () { echo "host: $host" - if test "$build_libtool_libs" = yes; then + if test yes = "$build_libtool_libs"; then echo "enable shared libraries" else echo "disable shared libraries" fi - if test "$build_old_libs" = yes; then + if test yes = "$build_old_libs"; then echo "enable static libraries" else echo "disable static libraries" @@ -934,289 +2069,295 @@ func_features () exit $? } -# func_enable_tag tagname + +# func_enable_tag TAGNAME +# ----------------------- # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { - # Global variable: - tagname="$1" + # Global variable: + tagname=$1 - re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" - re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" - sed_extractcf="/$re_begincf/,/$re_endcf/p" + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf=/$re_begincf/,/$re_endcf/p - # Validate tagname. - case $tagname in - *[!-_A-Za-z0-9,/]*) - func_fatal_error "invalid tag name: $tagname" - ;; - esac + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac - # Don't test for the "default" C tag, as we know it's - # there but not specially marked. - case $tagname in - CC) ;; + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; *) - if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then - taglist="$taglist $tagname" - - # Evaluate the configuration. Be careful to quote the path - # and the sed script, to avoid splitting on whitespace, but - # also don't use non-portable quotes within backquotes within - # quotes we have to do it in 2 steps: - extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` - eval "$extractedcf" - else - func_error "ignoring unknown tag $tagname" - fi - ;; - esac + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac } + # func_check_version_match +# ------------------------ # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { - if test "$package_revision" != "$macro_revision"; then - if test "$VERSION" != "$macro_version"; then - if test -z "$macro_version"; then - cat >&2 <<_LT_EOF + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF - else - cat >&2 <<_LT_EOF + else + cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF - fi - else - cat >&2 <<_LT_EOF + fi + else + cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF - fi + fi - exit $EXIT_MISMATCH - fi + exit $EXIT_MISMATCH + fi } -# Shorthand for --mode=foo, only valid as the first argument -case $1 in -clean|clea|cle|cl) - shift; set dummy --mode clean ${1+"$@"}; shift - ;; -compile|compil|compi|comp|com|co|c) - shift; set dummy --mode compile ${1+"$@"}; shift - ;; -execute|execut|execu|exec|exe|ex|e) - shift; set dummy --mode execute ${1+"$@"}; shift - ;; -finish|finis|fini|fin|fi|f) - shift; set dummy --mode finish ${1+"$@"}; shift - ;; -install|instal|insta|inst|ins|in|i) - shift; set dummy --mode install ${1+"$@"}; shift - ;; -link|lin|li|l) - shift; set dummy --mode link ${1+"$@"}; shift - ;; -uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) - shift; set dummy --mode uninstall ${1+"$@"}; shift - ;; -esac +# libtool_options_prep [ARG]... +# ----------------------------- +# Preparation for options parsed by libtool. +libtool_options_prep () +{ + $debug_mode + # Option defaults: + opt_config=false + opt_dlopen= + opt_dry_run=false + opt_help=false + opt_mode= + opt_preserve_dup_deps=false + opt_quiet=false + nonopt= + preserve_args= -# Option defaults: -opt_debug=: -opt_dry_run=false -opt_config=false -opt_preserve_dup_deps=false -opt_features=false -opt_finish=false -opt_help=false -opt_help_all=false -opt_silent=: -opt_warning=: -opt_verbose=: -opt_silent=false -opt_verbose=false + # Shorthand for --mode=foo, only valid as the first argument + case $1 in + clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; + compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; + execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; + finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; + install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; + link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; + uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; + esac + + # Pass back the list of options. + func_quote_for_eval ${1+"$@"} + libtool_options_prep_result=$func_quote_for_eval_result +} +func_add_hook func_options_prep libtool_options_prep -# Parse options once, thoroughly. This comes as soon as possible in the -# script to make things like `--version' happen as quickly as we can. +# libtool_parse_options [ARG]... +# --------------------------------- +# Provide handling for libtool specific options. +libtool_parse_options () { - # this just eases exit handling - while test $# -gt 0; do - opt="$1" - shift - case $opt in - --debug|-x) opt_debug='set -x' - func_echo "enabling shell trace mode" - $opt_debug - ;; - --dry-run|--dryrun|-n) - opt_dry_run=: - ;; - --config) - opt_config=: -func_config - ;; - --dlopen|-dlopen) - optarg="$1" - opt_dlopen="${opt_dlopen+$opt_dlopen -}$optarg" - shift - ;; - --preserve-dup-deps) - opt_preserve_dup_deps=: - ;; - --features) - opt_features=: -func_features - ;; - --finish) - opt_finish=: -set dummy --mode finish ${1+"$@"}; shift - ;; - --help) - opt_help=: - ;; - --help-all) - opt_help_all=: -opt_help=': help-all' - ;; - --mode) - test $# = 0 && func_missing_arg $opt && break - optarg="$1" - opt_mode="$optarg" -case $optarg in - # Valid mode arguments: - clean|compile|execute|finish|install|link|relink|uninstall) ;; - - # Catch anything else as an error - *) func_error "invalid argument for $opt" - exit_cmd=exit - break - ;; -esac - shift - ;; - --no-silent|--no-quiet) - opt_silent=false -func_append preserve_args " $opt" - ;; - --no-warning|--no-warn) - opt_warning=false -func_append preserve_args " $opt" - ;; - --no-verbose) - opt_verbose=false -func_append preserve_args " $opt" - ;; - --silent|--quiet) - opt_silent=: -func_append preserve_args " $opt" - opt_verbose=false - ;; - --verbose|-v) - opt_verbose=: -func_append preserve_args " $opt" -opt_silent=false - ;; - --tag) - test $# = 0 && func_missing_arg $opt && break - optarg="$1" - opt_tag="$optarg" -func_append preserve_args " $opt $optarg" -func_enable_tag "$optarg" - shift - ;; - - -\?|-h) func_usage ;; - --help) func_help ;; - --version) func_version ;; - - # Separate optargs to long options: - --*=*) - func_split_long_opt "$opt" - set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} - shift - ;; - - # Separate non-argument short options: - -\?*|-h*|-n*|-v*) - func_split_short_opt "$opt" - set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} - shift - ;; - - --) break ;; - -*) func_fatal_help "unrecognized option \`$opt'" ;; - *) set dummy "$opt" ${1+"$@"}; shift; break ;; - esac - done + $debug_cmd + + # Perform our own loop to consume as many options as possible in + # each iteration. + while test $# -gt 0; do + _G_opt=$1 + shift + case $_G_opt in + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + + --config) func_config ;; + + --dlopen|-dlopen) + opt_dlopen="${opt_dlopen+$opt_dlopen +}$1" + shift + ;; + + --preserve-dup-deps) + opt_preserve_dup_deps=: ;; + + --features) func_features ;; + + --finish) set dummy --mode finish ${1+"$@"}; shift ;; + + --help) opt_help=: ;; + + --help-all) opt_help=': help-all' ;; + + --mode) test $# = 0 && func_missing_arg $_G_opt && break + opt_mode=$1 + case $1 in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $_G_opt" + exit_cmd=exit + break + ;; + esac + shift + ;; + + --no-silent|--no-quiet) + opt_quiet=false + func_append preserve_args " $_G_opt" + ;; + + --no-warnings|--no-warning|--no-warn) + opt_warning=false + func_append preserve_args " $_G_opt" + ;; + + --no-verbose) + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --silent|--quiet) + opt_quiet=: + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --tag) test $# = 0 && func_missing_arg $_G_opt && break + opt_tag=$1 + func_append preserve_args " $_G_opt $1" + func_enable_tag "$1" + shift + ;; + + --verbose|-v) opt_quiet=false + opt_verbose=: + func_append preserve_args " $_G_opt" + ;; + + # An option not handled by this hook function: + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done + + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + libtool_parse_options_result=$func_quote_for_eval_result +} +func_add_hook func_parse_options libtool_parse_options - # Validate options: - # save first non-option argument - if test "$#" -gt 0; then - nonopt="$opt" - shift - fi - # preserve --debug - test "$opt_debug" = : || func_append preserve_args " --debug" +# libtool_validate_options [ARG]... +# --------------------------------- +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +libtool_validate_options () +{ + # save first non-option argument + if test 0 -lt $#; then + nonopt=$1 + shift + fi - case $host in - *cygwin* | *mingw* | *pw32* | *cegcc*) - # don't eliminate duplications in $postdeps and $predeps - opt_duplicate_compiler_generated_deps=: - ;; - *) - opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps - ;; - esac + # preserve --debug + test : = "$debug_cmd" || func_append preserve_args " --debug" - $opt_help || { - # Sanity checks first: - func_check_version_match + case $host in + *cygwin* | *mingw* | *pw32* | *cegcc*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac - if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then - func_fatal_configuration "not configured to build any kind of library" - fi + $opt_help || { + # Sanity checks first: + func_check_version_match - # Darwin sucks - eval std_shrext=\"$shrext_cmds\" + test yes != "$build_libtool_libs" \ + && test yes != "$build_old_libs" \ + && func_fatal_configuration "not configured to build any kind of library" - # Only execute mode is allowed to have -dlopen flags. - if test -n "$opt_dlopen" && test "$opt_mode" != execute; then - func_error "unrecognized option \`-dlopen'" - $ECHO "$help" 1>&2 - exit $EXIT_FAILURE - fi + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" - # Change the help message to a mode-specific one. - generic_help="$help" - help="Try \`$progname --help --mode=$opt_mode' for more information." - } + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test execute != "$opt_mode"; then + func_error "unrecognized option '-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + # Change the help message to a mode-specific one. + generic_help=$help + help="Try '$progname --help --mode=$opt_mode' for more information." + } - # Bail if the options were screwed - $exit_cmd $EXIT_FAILURE + # Pass back the unparsed argument list + func_quote_for_eval ${1+"$@"} + libtool_validate_options_result=$func_quote_for_eval_result } +func_add_hook func_validate_options libtool_validate_options + +# Process options as early as possible so that --help and --version +# can return quickly. +func_options ${1+"$@"} +eval set dummy "$func_options_result"; shift @@ -1224,8 +2365,29 @@ func_enable_tag "$optarg" ## Main. ## ## ----------- ## +magic='%%%MAGIC variable%%%' +magic_exe='%%%MAGIC EXE variable%%%' + +# Global variables. +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + # func_lalib_p file -# True iff FILE is a libtool `.la' library or `.lo' object file. +# True iff FILE is a libtool '.la' library or '.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () @@ -1236,12 +2398,12 @@ func_lalib_p () } # func_lalib_unsafe_p file -# True iff FILE is a libtool `.la' library or `.lo' object file. +# True iff FILE is a libtool '.la' library or '.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be -# fatal anyway. Works if `file' does not exist. +# fatal anyway. Works if 'file' does not exist. func_lalib_unsafe_p () { lalib_p=no @@ -1249,13 +2411,13 @@ func_lalib_unsafe_p () for lalib_p_l in 1 2 3 4 do read lalib_p_line - case "$lalib_p_line" in + case $lalib_p_line in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi - test "$lalib_p" = yes + test yes = "$lalib_p" } # func_ltwrapper_script_p file @@ -1289,7 +2451,7 @@ func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" - func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" + func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper } # func_ltwrapper_p file @@ -1308,11 +2470,13 @@ func_ltwrapper_p () # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { - $opt_debug + $debug_cmd + save_ifs=$IFS; IFS='~' for cmd in $1; do - IFS=$save_ifs + IFS=$sp$nl eval cmd=\"$cmd\" + IFS=$save_ifs func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs @@ -1324,10 +2488,11 @@ func_execute_cmds () # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing -# `FILE.' does not work on cygwin managed mounts. +# 'FILE.' does not work on cygwin managed mounts. func_source () { - $opt_debug + $debug_cmd + case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; @@ -1354,10 +2519,10 @@ func_resolve_sysroot () # store the result into func_replace_sysroot_result. func_replace_sysroot () { - case "$lt_sysroot:$1" in + case $lt_sysroot:$1 in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" - func_replace_sysroot_result="=$func_stripname_result" + func_replace_sysroot_result='='$func_stripname_result ;; *) # Including no sysroot. @@ -1374,7 +2539,8 @@ func_replace_sysroot () # arg is usually of the form 'gcc ...' func_infer_tag () { - $opt_debug + $debug_cmd + if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do @@ -1393,7 +2559,7 @@ func_infer_tag () for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. - eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. @@ -1418,7 +2584,7 @@ func_infer_tag () # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" - func_fatal_error "specify a tag with \`--tag'" + func_fatal_error "specify a tag with '--tag'" # else # func_verbose "using $tagname tagged configuration" fi @@ -1434,15 +2600,15 @@ func_infer_tag () # but don't create it if we're doing a dry run. func_write_libtool_object () { - write_libobj=${1} - if test "$build_libtool_libs" = yes; then - write_lobj=\'${2}\' + write_libobj=$1 + if test yes = "$build_libtool_libs"; then + write_lobj=\'$2\' else write_lobj=none fi - if test "$build_old_libs" = yes; then - write_oldobj=\'${3}\' + if test yes = "$build_old_libs"; then + write_oldobj=\'$3\' else write_oldobj=none fi @@ -1450,7 +2616,7 @@ func_write_libtool_object () $opt_dry_run || { cat >${write_libobj}T </dev/null` - if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then + if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | - $SED -e "$lt_sed_naive_backslashify"` + $SED -e "$sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi @@ -1514,18 +2681,19 @@ func_convert_core_file_wine_to_w32 () # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { - $opt_debug + $debug_cmd + # unfortunately, winepath doesn't convert paths, only file names - func_convert_core_path_wine_to_w32_result="" + func_convert_core_path_wine_to_w32_result= if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" - if test -n "$func_convert_core_file_wine_to_w32_result" ; then + if test -n "$func_convert_core_file_wine_to_w32_result"; then if test -z "$func_convert_core_path_wine_to_w32_result"; then - func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" + func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi @@ -1554,7 +2722,8 @@ func_convert_core_path_wine_to_w32 () # environment variable; do not put it in $PATH. func_cygpath () { - $opt_debug + $debug_cmd + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then @@ -1563,7 +2732,7 @@ func_cygpath () fi else func_cygpath_result= - func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" + func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" fi } #end: func_cygpath @@ -1574,10 +2743,11 @@ func_cygpath () # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { - $opt_debug + $debug_cmd + # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | - $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` + $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 @@ -1588,13 +2758,14 @@ func_convert_core_msys_to_w32 () # func_to_host_file_result to ARG1). func_convert_file_check () { - $opt_debug - if test -z "$2" && test -n "$1" ; then + $debug_cmd + + if test -z "$2" && test -n "$1"; then func_error "Could not determine host file name corresponding to" - func_error " \`$1'" + func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: - func_to_host_file_result="$1" + func_to_host_file_result=$1 fi } # end func_convert_file_check @@ -1606,10 +2777,11 @@ func_convert_file_check () # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { - $opt_debug + $debug_cmd + if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" - func_error " \`$3'" + func_error " '$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. @@ -1618,7 +2790,7 @@ func_convert_path_check () func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else - func_to_host_path_result="$3" + func_to_host_path_result=$3 fi fi } @@ -1630,9 +2802,10 @@ func_convert_path_check () # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { - $opt_debug + $debug_cmd + case $4 in - $1 ) func_to_host_path_result="$3$func_to_host_path_result" + $1 ) func_to_host_path_result=$3$func_to_host_path_result ;; esac case $4 in @@ -1646,7 +2819,7 @@ func_convert_path_front_back_pathsep () ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## -# invoked via `$to_host_file_cmd ARG' +# invoked via '$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. @@ -1657,7 +2830,8 @@ func_convert_path_front_back_pathsep () # in func_to_host_file_result. func_to_host_file () { - $opt_debug + $debug_cmd + $to_host_file_cmd "$1" } # end func_to_host_file @@ -1669,7 +2843,8 @@ func_to_host_file () # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { - $opt_debug + $debug_cmd + case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 @@ -1687,7 +2862,7 @@ func_to_tool_file () # Copy ARG to func_to_host_file_result. func_convert_file_noop () { - func_to_host_file_result="$1" + func_to_host_file_result=$1 } # end func_convert_file_noop @@ -1698,11 +2873,12 @@ func_convert_file_noop () # func_to_host_file_result. func_convert_file_msys_to_w32 () { - $opt_debug - func_to_host_file_result="$1" + $debug_cmd + + func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" - func_to_host_file_result="$func_convert_core_msys_to_w32_result" + func_to_host_file_result=$func_convert_core_msys_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } @@ -1714,8 +2890,9 @@ func_convert_file_msys_to_w32 () # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { - $opt_debug - func_to_host_file_result="$1" + $debug_cmd + + func_to_host_file_result=$1 if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. @@ -1731,11 +2908,12 @@ func_convert_file_cygwin_to_w32 () # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { - $opt_debug - func_to_host_file_result="$1" + $debug_cmd + + func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" - func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result=$func_convert_core_file_wine_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } @@ -1747,12 +2925,13 @@ func_convert_file_nix_to_w32 () # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { - $opt_debug - func_to_host_file_result="$1" + $debug_cmd + + func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" - func_to_host_file_result="$func_cygpath_result" + func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } @@ -1765,13 +2944,14 @@ func_convert_file_msys_to_cygwin () # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { - $opt_debug - func_to_host_file_result="$1" + $debug_cmd + + func_to_host_file_result=$1 if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" - func_to_host_file_result="$func_cygpath_result" + func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } @@ -1781,7 +2961,7 @@ func_convert_file_nix_to_cygwin () ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# -# invoked via `$to_host_path_cmd ARG' +# invoked via '$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. @@ -1805,10 +2985,11 @@ func_convert_file_nix_to_cygwin () to_host_path_cmd= func_init_to_host_path_cmd () { - $opt_debug + $debug_cmd + if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" - to_host_path_cmd="func_convert_path_${func_stripname_result}" + to_host_path_cmd=func_convert_path_$func_stripname_result fi } @@ -1818,7 +2999,8 @@ func_init_to_host_path_cmd () # in func_to_host_path_result. func_to_host_path () { - $opt_debug + $debug_cmd + func_init_to_host_path_cmd $to_host_path_cmd "$1" } @@ -1829,7 +3011,7 @@ func_to_host_path () # Copy ARG to func_to_host_path_result. func_convert_path_noop () { - func_to_host_path_result="$1" + func_to_host_path_result=$1 } # end func_convert_path_noop @@ -1840,8 +3022,9 @@ func_convert_path_noop () # func_to_host_path_result. func_convert_path_msys_to_w32 () { - $opt_debug - func_to_host_path_result="$1" + $debug_cmd + + func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; @@ -1849,7 +3032,7 @@ func_convert_path_msys_to_w32 () func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" - func_to_host_path_result="$func_convert_core_msys_to_w32_result" + func_to_host_path_result=$func_convert_core_msys_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" @@ -1863,8 +3046,9 @@ func_convert_path_msys_to_w32 () # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { - $opt_debug - func_to_host_path_result="$1" + $debug_cmd + + func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" @@ -1883,14 +3067,15 @@ func_convert_path_cygwin_to_w32 () # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { - $opt_debug - func_to_host_path_result="$1" + $debug_cmd + + func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" - func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result=$func_convert_core_path_wine_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" @@ -1904,15 +3089,16 @@ func_convert_path_nix_to_w32 () # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { - $opt_debug - func_to_host_path_result="$1" + $debug_cmd + + func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" - func_to_host_path_result="$func_cygpath_result" + func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" @@ -1927,8 +3113,9 @@ func_convert_path_msys_to_cygwin () # func_to_host_file_result. func_convert_path_nix_to_cygwin () { - $opt_debug - func_to_host_path_result="$1" + $debug_cmd + + func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them @@ -1937,7 +3124,7 @@ func_convert_path_nix_to_cygwin () func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" - func_to_host_path_result="$func_cygpath_result" + func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" @@ -1946,13 +3133,31 @@ func_convert_path_nix_to_cygwin () # end func_convert_path_nix_to_cygwin +# func_dll_def_p FILE +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with _LT_DLL_DEF_P in libtool.m4 +func_dll_def_p () +{ + $debug_cmd + + func_dll_def_p_tmp=`$SED -n \ + -e 's/^[ ]*//' \ + -e '/^\(;.*\)*$/d' \ + -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ + -e q \ + "$1"` + test DEF = "$func_dll_def_p_tmp" +} + + # func_mode_compile arg... func_mode_compile () { - $opt_debug + $debug_cmd + # Get the compilation command and the source file. base_compile= - srcfile="$nonopt" # always keep a non-empty value in "srcfile" + srcfile=$nonopt # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal @@ -1965,12 +3170,12 @@ func_mode_compile () case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile - lastarg="$arg" + lastarg=$arg arg_mode=normal ;; target ) - libobj="$arg" + libobj=$arg arg_mode=normal continue ;; @@ -1980,7 +3185,7 @@ func_mode_compile () case $arg in -o) test -n "$libobj" && \ - func_fatal_error "you cannot specify \`-o' more than once" + func_fatal_error "you cannot specify '-o' more than once" arg_mode=target continue ;; @@ -2009,12 +3214,12 @@ func_mode_compile () func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= - save_ifs="$IFS"; IFS=',' + save_ifs=$IFS; IFS=, for arg in $args; do - IFS="$save_ifs" + IFS=$save_ifs func_append_quoted lastarg "$arg" done - IFS="$save_ifs" + IFS=$save_ifs func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result @@ -2027,8 +3232,8 @@ func_mode_compile () # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # - lastarg="$srcfile" - srcfile="$arg" + lastarg=$srcfile + srcfile=$arg ;; esac # case $arg ;; @@ -2043,13 +3248,13 @@ func_mode_compile () func_fatal_error "you must specify an argument for -Xcompile" ;; target) - func_fatal_error "you must specify a target with \`-o'" + func_fatal_error "you must specify a target with '-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" - libobj="$func_basename_result" + libobj=$func_basename_result } ;; esac @@ -2069,7 +3274,7 @@ func_mode_compile () case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) - func_fatal_error "cannot determine name of library object from \`$libobj'" + func_fatal_error "cannot determine name of library object from '$libobj'" ;; esac @@ -2078,8 +3283,8 @@ func_mode_compile () for arg in $later; do case $arg in -shared) - test "$build_libtool_libs" != yes && \ - func_fatal_configuration "can not build a shared library" + test yes = "$build_libtool_libs" \ + || func_fatal_configuration "cannot build a shared library" build_old_libs=no continue ;; @@ -2105,17 +3310,17 @@ func_mode_compile () func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ - && func_warning "libobj name \`$libobj' may not contain shell special characters." + && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" - objname="$func_basename_result" - xdir="$func_dirname_result" - lobj=${xdir}$objdir/$objname + objname=$func_basename_result + xdir=$func_dirname_result + lobj=$xdir$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. - if test "$build_old_libs" = yes; then + if test yes = "$build_old_libs"; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" @@ -2127,16 +3332,16 @@ func_mode_compile () pic_mode=default ;; esac - if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c - if test "$compiler_c_o" = no; then - output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} - lockfile="$output_obj.lock" + if test no = "$compiler_c_o"; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext + lockfile=$output_obj.lock else output_obj= need_locks=no @@ -2145,12 +3350,12 @@ func_mode_compile () # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file - if test "$need_locks" = yes; then + if test yes = "$need_locks"; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done - elif test "$need_locks" = warn; then + elif test warn = "$need_locks"; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: @@ -2158,7 +3363,7 @@ func_mode_compile () This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you +your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." @@ -2180,11 +3385,11 @@ compiler." qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. - if test "$build_libtool_libs" = yes; then + if test yes = "$build_libtool_libs"; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile - if test "$pic_mode" != no; then + if test no != "$pic_mode"; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code @@ -2201,7 +3406,7 @@ compiler." func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' - if test "$need_locks" = warn && + if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: @@ -2212,7 +3417,7 @@ $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you +your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." @@ -2228,20 +3433,20 @@ compiler." fi # Allow error messages only from the first compilation. - if test "$suppress_opt" = yes; then + if test yes = "$suppress_opt"; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. - if test "$build_old_libs" = yes; then - if test "$pic_mode" != yes; then + if test yes = "$build_old_libs"; then + if test yes != "$pic_mode"; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi - if test "$compiler_c_o" = yes; then + if test yes = "$compiler_c_o"; then func_append command " -o $obj" fi @@ -2250,7 +3455,7 @@ compiler." func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' - if test "$need_locks" = warn && + if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: @@ -2261,7 +3466,7 @@ $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you +your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." @@ -2281,7 +3486,7 @@ compiler." func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked - if test "$need_locks" != no; then + if test no != "$need_locks"; then removelist=$lockfile $RM "$lockfile" fi @@ -2291,7 +3496,7 @@ compiler." } $opt_help || { - test "$opt_mode" = compile && func_mode_compile ${1+"$@"} + test compile = "$opt_mode" && func_mode_compile ${1+"$@"} } func_mode_help () @@ -2311,7 +3516,7 @@ func_mode_help () Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated @@ -2330,16 +3535,16 @@ This mode accepts the following additional options: -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only - -shared do not build a \`.o' file suitable for static linking - -static only build a \`.o' file suitable for static linking + -shared do not build a '.o' file suitable for static linking + -static only build a '.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler -COMPILE-COMMAND is a command to be used in creating a \`standard' object file +COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from -SOURCEFILE, then substituting the C source code suffix \`.c' with the -library object suffix, \`.lo'." +SOURCEFILE, then substituting the C source code suffix '.c' with the +library object suffix, '.lo'." ;; execute) @@ -2352,7 +3557,7 @@ This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path -This mode sets the library path environment variable according to \`-dlopen' +This mode sets the library path environment variable according to '-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated @@ -2371,7 +3576,7 @@ Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use -the \`--dry-run' option if you just want to see what would be executed." +the '--dry-run' option if you just want to see what would be executed." ;; install) @@ -2381,7 +3586,7 @@ the \`--dry-run' option if you just want to see what would be executed." Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be -either the \`install' or \`cp' program. +either the 'install' or 'cp' program. The following components of INSTALL-COMMAND are treated specially: @@ -2407,7 +3612,7 @@ The following components of LINK-COMMAND are treated specially: -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) - -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE @@ -2441,20 +3646,20 @@ The following components of LINK-COMMAND are treated specially: -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) -All other options (arguments beginning with \`-') are ignored. +All other options (arguments beginning with '-') are ignored. -Every other argument is treated as a filename. Files ending in \`.la' are +Every other argument is treated as a filename. Files ending in '.la' are treated as uninstalled libtool libraries, other files are standard or library object files. -If the OUTPUT-FILE ends in \`.la', then a libtool library is created, -only library objects (\`.lo' files) may be specified, and \`-rpath' is +If the OUTPUT-FILE ends in '.la', then a libtool library is created, +only library objects ('.lo' files) may be specified, and '-rpath' is required, except when creating a convenience library. -If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created -using \`ar' and \`ranlib', or on Windows using \`lib'. +If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created +using 'ar' and 'ranlib', or on Windows using 'lib'. -If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file is created, otherwise an executable program is created." ;; @@ -2465,7 +3670,7 @@ is created, otherwise an executable program is created." Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. @@ -2473,17 +3678,17 @@ Otherwise, only FILE itself is deleted using RM." ;; *) - func_fatal_help "invalid operation mode \`$opt_mode'" + func_fatal_help "invalid operation mode '$opt_mode'" ;; esac echo - $ECHO "Try \`$progname --help' for more information about other modes." + $ECHO "Try '$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then - if test "$opt_help" = :; then + if test : = "$opt_help"; then func_mode_help else { @@ -2516,16 +3721,17 @@ fi # func_mode_execute arg... func_mode_execute () { - $opt_debug + $debug_cmd + # The first argument is the command name. - cmd="$nonopt" + cmd=$nonopt test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ - || func_fatal_help "\`$file' is not a file" + || func_fatal_help "'$file' is not a file" dir= case $file in @@ -2535,7 +3741,7 @@ func_mode_execute () # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ - || func_fatal_help "\`$lib' is not a valid libtool archive" + || func_fatal_help "'$lib' is not a valid libtool archive" # Read the libtool library. dlname= @@ -2546,18 +3752,18 @@ func_mode_execute () if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ - func_warning "\`$file' was not linked with \`-export-dynamic'" + func_warning "'$file' was not linked with '-export-dynamic'" continue fi func_dirname "$file" "" "." - dir="$func_dirname_result" + dir=$func_dirname_result if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then - func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" fi fi ;; @@ -2565,18 +3771,18 @@ func_mode_execute () *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." - dir="$func_dirname_result" + dir=$func_dirname_result ;; *) - func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + func_warning "'-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` - test -n "$absdir" && dir="$absdir" + test -n "$absdir" && dir=$absdir # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then @@ -2588,7 +3794,7 @@ func_mode_execute () # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. - libtool_execute_magic="$magic" + libtool_execute_magic=$magic # Check if any of the arguments is a wrapper script. args= @@ -2601,12 +3807,12 @@ func_mode_execute () if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. - file="$progdir/$program" + file=$progdir/$program elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. - file="$progdir/$program" + file=$progdir/$program fi ;; esac @@ -2614,7 +3820,15 @@ func_mode_execute () func_append_quoted args "$file" done - if test "X$opt_dry_run" = Xfalse; then + if $opt_dry_run; then + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + else if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" @@ -2631,25 +3845,18 @@ func_mode_execute () done # Now prepare to actually exec the command. - exec_cmd="\$cmd$args" - else - # Display what would be done. - if test -n "$shlibpath_var"; then - eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" - echo "export $shlibpath_var" - fi - $ECHO "$cmd$args" - exit $EXIT_SUCCESS + exec_cmd=\$cmd$args fi } -test "$opt_mode" = execute && func_mode_execute ${1+"$@"} +test execute = "$opt_mode" && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { - $opt_debug + $debug_cmd + libs= libdirs= admincmds= @@ -2663,11 +3870,11 @@ func_mode_finish () if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else - func_warning "\`$opt' is not a valid libtool archive" + func_warning "'$opt' is not a valid libtool archive" fi else - func_fatal_error "invalid argument \`$opt'" + func_fatal_error "invalid argument '$opt'" fi done @@ -2682,12 +3889,12 @@ func_mode_finish () # Remove sysroot references if $opt_dry_run; then for lib in $libs; do - echo "removing references to $lt_sysroot and \`=' prefixes from $lib" + echo "removing references to $lt_sysroot and '=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do - sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + sed -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done @@ -2712,7 +3919,7 @@ func_mode_finish () fi # Exit here if they wanted silent mode. - $opt_silent && exit $EXIT_SUCCESS + $opt_quiet && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" @@ -2723,27 +3930,27 @@ func_mode_finish () echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" - echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "specify the full pathname of the library, or use the '-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then - echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " - add LIBDIR to the '$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then - echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " - add LIBDIR to the '$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" - $ECHO " - use the \`$flag' linker flag" + $ECHO " - use the '$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then - echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" fi echo @@ -2762,18 +3969,20 @@ func_mode_finish () exit $EXIT_SUCCESS } -test "$opt_mode" = finish && func_mode_finish ${1+"$@"} +test finish = "$opt_mode" && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { - $opt_debug + $debug_cmd + # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). - if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || # Allow the use of GNU shtool's install command. - case $nonopt in *shtool*) :;; *) false;; esac; then + case $nonopt in *shtool*) :;; *) false;; esac + then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " @@ -2800,7 +4009,7 @@ func_mode_install () opts= prev= install_type= - isdir=no + isdir=false stripme= no_mode=: for arg @@ -2813,7 +4022,7 @@ func_mode_install () fi case $arg in - -d) isdir=yes ;; + -d) isdir=: ;; -f) if $install_cp; then :; else prev=$arg @@ -2831,7 +4040,7 @@ func_mode_install () *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then - if test "x$prev" = x-m && test -n "$install_override_mode"; then + if test X-m = "X$prev" && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi @@ -2856,7 +4065,7 @@ func_mode_install () func_fatal_help "you must specify an install program" test -n "$prev" && \ - func_fatal_help "the \`$prev' option requires an argument" + func_fatal_help "the '$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else @@ -2878,19 +4087,19 @@ func_mode_install () dest=$func_stripname_result # Check to see that the destination is a directory. - test -d "$dest" && isdir=yes - if test "$isdir" = yes; then - destdir="$dest" + test -d "$dest" && isdir=: + if $isdir; then + destdir=$dest destname= else func_dirname_and_basename "$dest" "" "." - destdir="$func_dirname_result" - destname="$func_basename_result" + destdir=$func_dirname_result + destname=$func_basename_result # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ - func_fatal_help "\`$dest' is not a directory" + func_fatal_help "'$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; @@ -2899,7 +4108,7 @@ func_mode_install () case $file in *.lo) ;; *) - func_fatal_help "\`$destdir' must be an absolute directory name" + func_fatal_help "'$destdir' must be an absolute directory name" ;; esac done @@ -2908,7 +4117,7 @@ func_mode_install () # This variable tells wrapper scripts just to set variables rather # than running their programs. - libtool_install_magic="$magic" + libtool_install_magic=$magic staticlibs= future_libdirs= @@ -2928,7 +4137,7 @@ func_mode_install () # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ - || func_fatal_help "\`$file' is not a valid libtool archive" + || func_fatal_help "'$file' is not a valid libtool archive" library_names= old_library= @@ -2950,7 +4159,7 @@ func_mode_install () fi func_dirname "$file" "/" "" - dir="$func_dirname_result" + dir=$func_dirname_result func_append dir "$objdir" if test -n "$relink_command"; then @@ -2964,7 +4173,7 @@ func_mode_install () # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ - func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. @@ -2973,29 +4182,29 @@ func_mode_install () relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi - func_warning "relinking \`$file'" + func_warning "relinking '$file'" func_show_eval "$relink_command" \ - 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then - realname="$1" + realname=$1 shift - srcname="$realname" - test -n "$relink_command" && srcname="$realname"T + srcname=$realname + test -n "$relink_command" && srcname=${realname}T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' - tstripme="$stripme" + tstripme=$stripme case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) - tstripme="" + tstripme= ;; esac ;; @@ -3006,7 +4215,7 @@ func_mode_install () if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. - # Try `ln -sf' first, because the `ln' binary might depend on + # Try 'ln -sf' first, because the 'ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname @@ -3017,14 +4226,14 @@ func_mode_install () fi # Do each command in the postinstall commands. - lib="$destdir/$realname" + lib=$destdir/$realname func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" - name="$func_basename_result" - instname="$dir/$name"i + name=$func_basename_result + instname=$dir/${name}i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. @@ -3036,11 +4245,11 @@ func_mode_install () # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then - destfile="$destdir/$destname" + destfile=$destdir/$destname else func_basename "$file" - destfile="$func_basename_result" - destfile="$destdir/$destfile" + destfile=$func_basename_result + destfile=$destdir/$destfile fi # Deduce the name of the destination old-style object file. @@ -3050,11 +4259,11 @@ func_mode_install () staticdest=$func_lo2o_result ;; *.$objext) - staticdest="$destfile" + staticdest=$destfile destfile= ;; *) - func_fatal_help "cannot copy a libtool object to \`$destfile'" + func_fatal_help "cannot copy a libtool object to '$destfile'" ;; esac @@ -3063,7 +4272,7 @@ func_mode_install () func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. - if test "$build_old_libs" = yes; then + if test yes = "$build_old_libs"; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result @@ -3075,23 +4284,23 @@ func_mode_install () *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then - destfile="$destdir/$destname" + destfile=$destdir/$destname else func_basename "$file" - destfile="$func_basename_result" - destfile="$destdir/$destfile" + destfile=$func_basename_result + destfile=$destdir/$destfile fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install - stripped_ext="" + stripped_ext= case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result - stripped_ext=".exe" + stripped_ext=.exe fi ;; esac @@ -3119,19 +4328,19 @@ func_mode_install () # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ - func_fatal_error "invalid libtool wrapper script \`$wrapper'" + func_fatal_error "invalid libtool wrapper script '$wrapper'" - finalize=yes + finalize=: for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi - libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test + libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` if test -n "$libdir" && test ! -f "$libfile"; then - func_warning "\`$lib' has not been installed in \`$libdir'" - finalize=no + func_warning "'$lib' has not been installed in '$libdir'" + finalize=false fi done @@ -3139,29 +4348,29 @@ func_mode_install () func_source "$wrapper" outputname= - if test "$fast_install" = no && test -n "$relink_command"; then + if test no = "$fast_install" && test -n "$relink_command"; then $opt_dry_run || { - if test "$finalize" = yes; then + if $finalize; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" - file="$func_basename_result" - outputname="$tmpdir/$file" + file=$func_basename_result + outputname=$tmpdir/$file # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` - $opt_silent || { + $opt_quiet || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else - func_error "error: relink \`$file' with the above command before installing it" + func_error "error: relink '$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi - file="$outputname" + file=$outputname else - func_warning "cannot relink \`$file'" + func_warning "cannot relink '$file'" fi } else @@ -3198,10 +4407,10 @@ func_mode_install () for file in $staticlibs; do func_basename "$file" - name="$func_basename_result" + name=$func_basename_result # Set up the ranlib parameters. - oldlib="$destdir/$name" + oldlib=$destdir/$name func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result @@ -3216,18 +4425,18 @@ func_mode_install () done test -n "$future_libdirs" && \ - func_warning "remember to run \`$progname --finish$future_libdirs'" + func_warning "remember to run '$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" - exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } -test "$opt_mode" = install && func_mode_install ${1+"$@"} +test install = "$opt_mode" && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p @@ -3235,16 +4444,17 @@ test "$opt_mode" = install && func_mode_install ${1+"$@"} # a dlpreopen symbol table. func_generate_dlsyms () { - $opt_debug - my_outputname="$1" - my_originator="$2" - my_pic_p="${3-no}" + $debug_cmd + + my_outputname=$1 + my_originator=$2 + my_pic_p=${3-false} my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then if test -n "$NM" && test -n "$global_symbol_pipe"; then - my_dlsyms="${my_outputname}S.c" + my_dlsyms=${my_outputname}S.c else func_error "not configured to extract global symbols from dlpreopened files" fi @@ -3255,7 +4465,7 @@ func_generate_dlsyms () "") ;; *.c) # Discover the nlist of each of the dlfiles. - nlist="$output_objdir/${my_outputname}.nm" + nlist=$output_objdir/$my_outputname.nm func_show_eval "$RM $nlist ${nlist}S ${nlist}T" @@ -3263,34 +4473,36 @@ func_generate_dlsyms () func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ -/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ -/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ +/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif -#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST -#elif defined(__osf__) +#elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + /* External symbol declarations for the compiler. */\ " - if test "$dlself" = yes; then - func_verbose "generating symbol list for \`$output'" + if test yes = "$dlself"; then + func_verbose "generating symbol list for '$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" @@ -3298,7 +4510,7 @@ extern \"C\" { progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 - func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" + func_verbose "extracting global C symbols from '$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done @@ -3318,10 +4530,10 @@ extern \"C\" { # Prepare the list of exported symbols if test -z "$export_symbols"; then - export_symbols="$output_objdir/$outputname.exp" + export_symbols=$output_objdir/$outputname.exp $opt_dry_run || { $RM $export_symbols - eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' @@ -3331,7 +4543,7 @@ extern \"C\" { } else $opt_dry_run || { - eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in @@ -3345,22 +4557,22 @@ extern \"C\" { fi for dlprefile in $dlprefiles; do - func_verbose "extracting global C symbols from \`$dlprefile'" + func_verbose "extracting global C symbols from '$dlprefile'" func_basename "$dlprefile" - name="$func_basename_result" + name=$func_basename_result case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" - dlprefile_dlbasename="" + dlprefile_dlbasename= if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` - if test -n "$dlprefile_dlname" ; then + if test -n "$dlprefile_dlname"; then func_basename "$dlprefile_dlname" - dlprefile_dlbasename="$func_basename_result" + dlprefile_dlbasename=$func_basename_result else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" @@ -3368,7 +4580,7 @@ extern \"C\" { fi fi $opt_dry_run || { - if test -n "$dlprefile_dlbasename" ; then + if test -n "$dlprefile_dlbasename"; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" @@ -3424,6 +4636,11 @@ extern \"C\" { echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi + func_show_eval '$RM "${nlist}I"' + if test -n "$global_symbol_to_import"; then + eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' + fi + echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ @@ -3432,11 +4649,30 @@ typedef struct { void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist -lt_${my_prefix}_LTX_preloaded_symbols[]; +lt_${my_prefix}_LTX_preloaded_symbols[];\ +" + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ +static void lt_syminit(void) +{ + LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; + for (; symbol->name; ++symbol) + {" + $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" + echo >> "$output_objdir/$my_dlsyms" "\ + } +}" + fi + echo >> "$output_objdir/$my_dlsyms" "\ LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = -{\ - { \"$my_originator\", (void *) 0 }," +{ {\"$my_originator\", (void *) 0}," + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ + {\"@INIT@\", (void *) <_syminit}," + fi case $need_lib_prefix in no) @@ -3478,9 +4714,7 @@ static const void *lt_preloaded_setup() { *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) - if test "X$my_pic_p" != Xno; then - pic_flag_for_symtable=" $pic_flag" - fi + $my_pic_p && pic_flag_for_symtable=" $pic_flag" ;; esac ;; @@ -3497,10 +4731,10 @@ static const void *lt_preloaded_setup() { func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. - func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' # Transform the symbol file into the correct name. - symfileobj="$output_objdir/${my_outputname}S.$objext" + symfileobj=$output_objdir/${my_outputname}S.$objext case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then @@ -3518,7 +4752,7 @@ static const void *lt_preloaded_setup() { esac ;; *) - func_fatal_error "unknown suffix for \`$my_dlsyms'" + func_fatal_error "unknown suffix for '$my_dlsyms'" ;; esac else @@ -3532,6 +4766,32 @@ static const void *lt_preloaded_setup() { fi } +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + # func_win32_libid arg # return the library type of file 'arg' # @@ -3541,8 +4801,9 @@ static const void *lt_preloaded_setup() { # Despite the name, also deal with 64 bit binaries. func_win32_libid () { - $opt_debug - win32_libid_type="unknown" + $debug_cmd + + win32_libid_type=unknown win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import @@ -3552,16 +4813,29 @@ func_win32_libid () # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then - func_to_tool_file "$1" func_convert_file_msys_to_w32 - win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | - $SED -n -e ' + case $nm_interface in + "MS dumpbin") + if func_cygming_ms_implib_p "$1" || + func_cygming_gnu_implib_p "$1" + then + win32_nmres=import + else + win32_nmres= + fi + ;; + *) + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' 1,100{ / I /{ - s,.*,import, + s|.*|import| p q } }'` + ;; + esac case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; @@ -3593,7 +4867,8 @@ func_win32_libid () # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { - $opt_debug + $debug_cmd + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } @@ -3610,7 +4885,8 @@ func_cygming_dll_for_implib () # specified import library. func_cygming_dll_for_implib_fallback_core () { - $opt_debug + $debug_cmd + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ @@ -3646,8 +4922,8 @@ func_cygming_dll_for_implib_fallback_core () /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the - # archive which possess that section. Heuristic: eliminate - # all those which have a first or second character that is + # archive that possess that section. Heuristic: eliminate + # all those that have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually @@ -3658,30 +4934,6 @@ func_cygming_dll_for_implib_fallback_core () $SED -e '/^\./d;/^.\./d;q' } -# func_cygming_gnu_implib_p ARG -# This predicate returns with zero status (TRUE) if -# ARG is a GNU/binutils-style import library. Returns -# with nonzero status (FALSE) otherwise. -func_cygming_gnu_implib_p () -{ - $opt_debug - func_to_tool_file "$1" func_convert_file_msys_to_w32 - func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` - test -n "$func_cygming_gnu_implib_tmp" -} - -# func_cygming_ms_implib_p ARG -# This predicate returns with zero status (TRUE) if -# ARG is an MS-style import library. Returns -# with nonzero status (FALSE) otherwise. -func_cygming_ms_implib_p () -{ - $opt_debug - func_to_tool_file "$1" func_convert_file_msys_to_w32 - func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` - test -n "$func_cygming_ms_implib_tmp" -} - # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified @@ -3695,16 +4947,17 @@ func_cygming_ms_implib_p () # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { - $opt_debug - if func_cygming_gnu_implib_p "$1" ; then + $debug_cmd + + if func_cygming_gnu_implib_p "$1"; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` - elif func_cygming_ms_implib_p "$1" ; then + elif func_cygming_ms_implib_p "$1"; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown - sharedlib_from_linklib_result="" + sharedlib_from_linklib_result= fi } @@ -3712,10 +4965,11 @@ func_cygming_dll_for_implib_fallback () # func_extract_an_archive dir oldlib func_extract_an_archive () { - $opt_debug - f_ex_an_ar_dir="$1"; shift - f_ex_an_ar_oldlib="$1" - if test "$lock_old_archive_extraction" = yes; then + $debug_cmd + + f_ex_an_ar_dir=$1; shift + f_ex_an_ar_oldlib=$1 + if test yes = "$lock_old_archive_extraction"; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" @@ -3724,7 +4978,7 @@ func_extract_an_archive () fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' - if test "$lock_old_archive_extraction" = yes; then + if test yes = "$lock_old_archive_extraction"; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then @@ -3738,22 +4992,23 @@ func_extract_an_archive () # func_extract_archives gentop oldlib ... func_extract_archives () { - $opt_debug - my_gentop="$1"; shift + $debug_cmd + + my_gentop=$1; shift my_oldlibs=${1+"$@"} - my_oldobjs="" - my_xlib="" - my_xabs="" - my_xdir="" + my_oldobjs= + my_xlib= + my_xabs= + my_xdir= for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in - [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" - my_xlib="$func_basename_result" + my_xlib=$func_basename_result my_xlib_u=$my_xlib while :; do case " $extracted_archives " in @@ -3765,7 +5020,7 @@ func_extract_archives () esac done extracted_archives="$extracted_archives $my_xlib_u" - my_xdir="$my_gentop/$my_xlib_u" + my_xdir=$my_gentop/$my_xlib_u func_mkdir_p "$my_xdir" @@ -3778,19 +5033,20 @@ func_extract_archives () cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` - darwin_base_archive=`basename "$darwin_archive"` + func_basename "$darwin_archive" + darwin_base_archive=$func_basename_result darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" - for darwin_arch in $darwin_arches ; do - func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" - $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" - cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" - func_extract_an_archive "`pwd`" "${darwin_base_archive}" + for darwin_arch in $darwin_arches; do + func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" + $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" + cd "unfat-$$/$darwin_base_archive-$darwin_arch" + func_extract_an_archive "`pwd`" "$darwin_base_archive" cd "$darwin_curdir" - $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` @@ -3815,7 +5071,7 @@ func_extract_archives () my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done - func_extract_archives_result="$my_oldobjs" + func_extract_archives_result=$my_oldobjs } @@ -3830,7 +5086,7 @@ func_extract_archives () # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script -# will assume that the directory in which it is stored is +# will assume that the directory where it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () @@ -3841,7 +5097,7 @@ func_emit_wrapper () #! $SHELL # $output - temporary wrapper script for $objdir/$outputname -# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. @@ -3898,9 +5154,9 @@ _LTECHO_EOF' # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper -# /script/ and the wrapper /executable/ which is used only on +# /script/ and the wrapper /executable/ that is used only on # windows platforms, and (c) all begin with the string "--lt-" -# (application programs are unlikely to have options which match +# (application programs are unlikely to have options that match # this pattern). # # There are only two supported options: --lt-debug and @@ -3933,7 +5189,7 @@ func_parse_lt_options () # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then - echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 + echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 fi } @@ -3944,7 +5200,7 @@ func_lt_dump_args () lt_dump_args_N=1; for lt_arg do - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" + \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } @@ -3958,7 +5214,7 @@ func_exec_program_core () *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} @@ -3968,7 +5224,7 @@ func_exec_program_core () *) $ECHO "\ if test -n \"\$lt_option_debug\"; then - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} @@ -4043,13 +5299,13 @@ func_exec_program () test -n \"\$absdir\" && thisdir=\"\$absdir\" " - if test "$fast_install" = yes; then + if test yes = "$fast_install"; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || - { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" @@ -4101,7 +5357,7 @@ func_exec_program () fi # Export our shlibpath_var if we have one. - if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" @@ -4121,7 +5377,7 @@ func_exec_program () fi else # The program doesn't exist. - \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 @@ -4140,7 +5396,7 @@ func_emit_cwrapperexe_src () cat < #include +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + /* declarations of non-ANSI functions */ -#if defined(__MINGW32__) +#if defined __MINGW32__ # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif -#elif defined(__CYGWIN__) +#elif defined __CYGWIN__ # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif -/* #elif defined (other platforms) ... */ +/* #elif defined other_platform || defined ... */ #endif /* portability defines, excluding path handling macros */ -#if defined(_MSC_VER) +#if defined _MSC_VER # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC -# ifndef _INTPTR_T_DEFINED -# define _INTPTR_T_DEFINED -# define intptr_t int -# endif -#elif defined(__MINGW32__) +#elif defined __MINGW32__ # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv -#elif defined(__CYGWIN__) +#elif defined __CYGWIN__ # define HAVE_SETENV # define FOPEN_WB "wb" -/* #elif defined (other platforms) ... */ +/* #elif defined other platforms ... */ #endif -#if defined(PATH_MAX) +#if defined PATH_MAX # define LT_PATHMAX PATH_MAX -#elif defined(MAXPATHLEN) +#elif defined MAXPATHLEN # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 @@ -4234,8 +5488,8 @@ int setenv (const char *, const char *, int); # define PATH_SEPARATOR ':' #endif -#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ - defined (__OS2__) +#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ + defined __OS2__ # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 @@ -4268,10 +5522,10 @@ int setenv (const char *, const char *, int); #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ - if (stale) { free ((void *) stale); stale = 0; } \ + if (stale) { free (stale); stale = 0; } \ } while (0) -#if defined(LT_DEBUGWRAPPER) +#if defined LT_DEBUGWRAPPER static int lt_debug = 1; #else static int lt_debug = 0; @@ -4304,7 +5558,7 @@ volatile const char * MAGIC_EXE = "$magic_exe"; const char * LIB_PATH_VARNAME = "$shlibpath_var"; EOF - if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then func_to_host_path "$temp_rpath" cat < 0) && IS_PATH_SEPARATOR (new_value[len-1])) + size_t len = strlen (new_value); + while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { - new_value[len-1] = '\0'; + new_value[--len] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); @@ -5082,7 +6336,8 @@ EOF # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { - $opt_debug + $debug_cmd + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; @@ -5092,17 +6347,18 @@ func_win32_import_lib_p () # func_mode_link arg... func_mode_link () { - $opt_debug + $debug_cmd + case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out - # which system we are compiling for in order to pass an extra + # what system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying - # to make a dll which has undefined symbols, in which case not + # to make a dll that has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. @@ -5149,7 +6405,7 @@ func_mode_link () non_pic_objects= precious_files_regex= prefer_static_libs=no - preload=no + preload=false prev= prevarg= release= @@ -5161,7 +6417,7 @@ func_mode_link () vinfo= vinfo_number=no weak_libs= - single_module="${wl}-single_module" + single_module=$wl-single_module func_infer_tag $base_compile # We need to know -static, to get the right output filenames. @@ -5169,15 +6425,15 @@ func_mode_link () do case $arg in -shared) - test "$build_libtool_libs" != yes && \ - func_fatal_configuration "can not build a shared library" + test yes != "$build_libtool_libs" \ + && func_fatal_configuration "cannot build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) - if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then @@ -5210,7 +6466,7 @@ func_mode_link () # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do - arg="$1" + arg=$1 shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result @@ -5227,21 +6483,21 @@ func_mode_link () case $prev in bindir) - bindir="$arg" + bindir=$arg prev= continue ;; dlfiles|dlprefiles) - if test "$preload" = no; then + $preload || { # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" - preload=yes - fi + preload=: + } case $arg in *.la | *.lo) ;; # We handle these cases below. force) - if test "$dlself" = no; then + if test no = "$dlself"; then dlself=needless export_dynamic=yes fi @@ -5249,9 +6505,9 @@ func_mode_link () continue ;; self) - if test "$prev" = dlprefiles; then + if test dlprefiles = "$prev"; then dlself=yes - elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then dlself=yes else dlself=needless @@ -5261,7 +6517,7 @@ func_mode_link () continue ;; *) - if test "$prev" = dlfiles; then + if test dlfiles = "$prev"; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" @@ -5272,14 +6528,14 @@ func_mode_link () esac ;; expsyms) - export_symbols="$arg" + export_symbols=$arg test -f "$arg" \ - || func_fatal_error "symbol file \`$arg' does not exist" + || func_fatal_error "symbol file '$arg' does not exist" prev= continue ;; expsyms_regex) - export_symbols_regex="$arg" + export_symbols_regex=$arg prev= continue ;; @@ -5297,7 +6553,13 @@ func_mode_link () continue ;; inst_prefix) - inst_prefix_dir="$arg" + inst_prefix_dir=$arg + prev= + continue + ;; + mllvm) + # Clang does not use LLVM to link, so we can simply discard any + # '-mllvm $arg' options when doing the link step. prev= continue ;; @@ -5321,21 +6583,21 @@ func_mode_link () if test -z "$pic_object" || test -z "$non_pic_object" || - test "$pic_object" = none && - test "$non_pic_object" = none; then - func_fatal_error "cannot find name of object for \`$arg'" + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" - xdir="$func_dirname_result" + xdir=$func_dirname_result - if test "$pic_object" != none; then + if test none != "$pic_object"; then # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" + pic_object=$xdir$pic_object - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue @@ -5346,7 +6608,7 @@ func_mode_link () fi # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then + if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= @@ -5354,23 +6616,23 @@ func_mode_link () # A PIC object. func_append libobjs " $pic_object" - arg="$pic_object" + arg=$pic_object fi # Non-PIC object. - if test "$non_pic_object" != none; then + if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" + non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. - non_pic_object="$pic_object" + non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else @@ -5378,7 +6640,7 @@ func_mode_link () if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" - xdir="$func_dirname_result" + xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result @@ -5386,24 +6648,24 @@ func_mode_link () func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else - func_fatal_error "\`$arg' is not a valid libtool object" + func_fatal_error "'$arg' is not a valid libtool object" fi fi done else - func_fatal_error "link input file \`$arg' does not exist" + func_fatal_error "link input file '$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) - precious_files_regex="$arg" + precious_files_regex=$arg prev= continue ;; release) - release="-$arg" + release=-$arg prev= continue ;; @@ -5415,7 +6677,7 @@ func_mode_link () func_fatal_error "only absolute run-paths are allowed" ;; esac - if test "$prev" = rpath; then + if test rpath = "$prev"; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; @@ -5430,7 +6692,7 @@ func_mode_link () continue ;; shrext) - shrext_cmds="$arg" + shrext_cmds=$arg prev= continue ;; @@ -5470,7 +6732,7 @@ func_mode_link () esac fi # test -n "$prev" - prevarg="$arg" + prevarg=$arg case $arg in -all-static) @@ -5484,7 +6746,7 @@ func_mode_link () -allow-undefined) # FIXME: remove this flag sometime in the future. - func_fatal_error "\`-allow-undefined' must not be used because it is the default" + func_fatal_error "'-allow-undefined' must not be used because it is the default" ;; -avoid-version) @@ -5516,7 +6778,7 @@ func_mode_link () if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi - if test "X$arg" = "X-export-symbols"; then + if test X-export-symbols = "X$arg"; then prev=expsyms else prev=expsyms_regex @@ -5550,9 +6812,9 @@ func_mode_link () func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then - func_fatal_error "require no space between \`-L' and \`$1'" + func_fatal_error "require no space between '-L' and '$1'" else - func_fatal_error "need path for \`-L' option" + func_fatal_error "need path for '-L' option" fi fi func_resolve_sysroot "$func_stripname_result" @@ -5563,8 +6825,8 @@ func_mode_link () *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ - func_fatal_error "cannot determine absolute directory name of \`$dir'" - dir="$absdir" + func_fatal_error "cannot determine absolute directory name of '$dir'" + dir=$absdir ;; esac case "$deplibs " in @@ -5599,7 +6861,7 @@ func_mode_link () ;; -l*) - if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + if test X-lc = "X$arg" || test X-lm = "X$arg"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) @@ -5607,11 +6869,11 @@ func_mode_link () ;; *-*-os2*) # These systems don't actually have a C library (as such) - test "X$arg" = "X-lc" && continue + test X-lc = "X$arg" && continue ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc due to us having libc/libc_r. - test "X$arg" = "X-lc" && continue + test X-lc = "X$arg" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework @@ -5620,16 +6882,16 @@ func_mode_link () ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype - test "X$arg" = "X-lc" && continue + test X-lc = "X$arg" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work - test "X$arg" = "X-lc" && continue + test X-lc = "X$arg" && continue ;; esac - elif test "X$arg" = "X-lc_r"; then + elif test X-lc_r = "X$arg"; then case $host in - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) # Do not include libc_r directly, use -pthread flag. continue ;; @@ -5639,6 +6901,11 @@ func_mode_link () continue ;; + -mllvm) + prev=mllvm + continue + ;; + -module) module=yes continue @@ -5668,7 +6935,7 @@ func_mode_link () ;; -multi_module) - single_module="${wl}-multi_module" + single_module=$wl-multi_module continue ;; @@ -5682,8 +6949,8 @@ func_mode_link () *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. - func_warning "\`-no-install' is ignored for $host" - func_warning "assuming \`-no-fast-install' instead" + func_warning "'-no-install' is ignored for $host" + func_warning "assuming '-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; @@ -5788,14 +7055,14 @@ func_mode_link () func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= - save_ifs="$IFS"; IFS=',' + save_ifs=$IFS; IFS=, for flag in $args; do - IFS="$save_ifs" + IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done - IFS="$save_ifs" + IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; @@ -5804,15 +7071,15 @@ func_mode_link () func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= - save_ifs="$IFS"; IFS=',' + save_ifs=$IFS; IFS=, for flag in $args; do - IFS="$save_ifs" + IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done - IFS="$save_ifs" + IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; @@ -5835,7 +7102,7 @@ func_mode_link () # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" + arg=$func_quote_for_eval_result ;; # Flags to be passed through unchanged, with rationale: @@ -5850,12 +7117,13 @@ func_mode_link () # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support - # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -stdlib=* select c++ std lib with clang -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ - -O*|-flto*|-fwhopr*|-fuse-linker-plugin) + -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-stdlib=*) func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" + arg=$func_quote_for_eval_result func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" @@ -5865,7 +7133,7 @@ func_mode_link () # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" + arg=$func_quote_for_eval_result ;; *.$objext) @@ -5886,21 +7154,21 @@ func_mode_link () if test -z "$pic_object" || test -z "$non_pic_object" || - test "$pic_object" = none && - test "$non_pic_object" = none; then - func_fatal_error "cannot find name of object for \`$arg'" + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" - xdir="$func_dirname_result" + xdir=$func_dirname_result - if test "$pic_object" != none; then + test none = "$pic_object" || { # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" + pic_object=$xdir$pic_object - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue @@ -5911,7 +7179,7 @@ func_mode_link () fi # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then + if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= @@ -5919,23 +7187,23 @@ func_mode_link () # A PIC object. func_append libobjs " $pic_object" - arg="$pic_object" - fi + arg=$pic_object + } # Non-PIC object. - if test "$non_pic_object" != none; then + if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" + non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. - non_pic_object="$pic_object" + non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else @@ -5943,7 +7211,7 @@ func_mode_link () if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" - xdir="$func_dirname_result" + xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result @@ -5951,7 +7219,7 @@ func_mode_link () func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else - func_fatal_error "\`$arg' is not a valid libtool object" + func_fatal_error "'$arg' is not a valid libtool object" fi fi ;; @@ -5967,11 +7235,11 @@ func_mode_link () # A libtool-controlled library. func_resolve_sysroot "$arg" - if test "$prev" = dlfiles; then + if test dlfiles = "$prev"; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= - elif test "$prev" = dlprefiles; then + elif test dlprefiles = "$prev"; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= @@ -5986,7 +7254,7 @@ func_mode_link () # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" + arg=$func_quote_for_eval_result ;; esac # arg @@ -5998,9 +7266,9 @@ func_mode_link () done # argument parsing loop test -n "$prev" && \ - func_fatal_help "the \`$prevarg' option requires an argument" + func_fatal_help "the '$prevarg' option requires an argument" - if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" @@ -6009,12 +7277,12 @@ func_mode_link () oldlibs= # calculate the name of the file, without its directory func_basename "$output" - outputname="$func_basename_result" - libobjs_save="$libobjs" + outputname=$func_basename_result + libobjs_save=$libobjs if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var - eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` + eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi @@ -6022,7 +7290,7 @@ func_mode_link () eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" func_dirname "$output" "/" "" - output_objdir="$func_dirname_result$objdir" + output_objdir=$func_dirname_result$objdir func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. @@ -6045,7 +7313,7 @@ func_mode_link () # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do - if $opt_preserve_dup_deps ; then + if $opt_preserve_dup_deps; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac @@ -6053,7 +7321,7 @@ func_mode_link () func_append libs " $deplib" done - if test "$linkmode" = lib; then + if test lib = "$linkmode"; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps @@ -6085,7 +7353,7 @@ func_mode_link () case $file in *.la) ;; *) - func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" ;; esac done @@ -6093,7 +7361,7 @@ func_mode_link () prog) compile_deplibs= finalize_deplibs= - alldeplibs=no + alldeplibs=false newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" @@ -6105,29 +7373,29 @@ func_mode_link () for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... - if test "$linkmode,$pass" = "lib,link"; then + if test lib,link = "$linkmode,$pass"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done - deplibs="$tmp_deplibs" + deplibs=$tmp_deplibs fi - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan"; then - libs="$deplibs" + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass"; then + libs=$deplibs deplibs= fi - if test "$linkmode" = prog; then + if test prog = "$linkmode"; then case $pass in - dlopen) libs="$dlfiles" ;; - dlpreopen) libs="$dlprefiles" ;; + dlopen) libs=$dlfiles ;; + dlpreopen) libs=$dlprefiles ;; link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; esac fi - if test "$linkmode,$pass" = "lib,dlpreopen"; then + if test lib,dlpreopen = "$linkmode,$pass"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs @@ -6148,26 +7416,26 @@ func_mode_link () esac done done - libs="$dlprefiles" + libs=$dlprefiles fi - if test "$pass" = dlopen; then + if test dlopen = "$pass"; then # Collect dlpreopened libraries - save_deplibs="$deplibs" + save_deplibs=$deplibs deplibs= fi for deplib in $libs; do lib= - found=no + found=false case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) - if test "$linkmode,$pass" = "prog,link"; then + if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" - if test "$linkmode" = lib ; then + if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; @@ -6177,13 +7445,13 @@ func_mode_link () continue ;; -l*) - if test "$linkmode" != lib && test "$linkmode" != prog; then - func_warning "\`-l' is ignored for archives/objects" + if test lib != "$linkmode" && test prog != "$linkmode"; then + func_warning "'-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result - if test "$linkmode" = lib; then + if test lib = "$linkmode"; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" @@ -6191,31 +7459,22 @@ func_mode_link () for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library - lib="$searchdir/lib${name}${search_ext}" + lib=$searchdir/lib$name$search_ext if test -f "$lib"; then - if test "$search_ext" = ".la"; then - found=yes + if test .la = "$search_ext"; then + found=: else - found=no + found=false fi break 2 fi done done - if test "$found" != yes; then - # deplib doesn't seem to be a libtool library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - else # deplib is a libtool library + if $found; then + # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then @@ -6223,19 +7482,19 @@ func_mode_link () old_library= func_source "$lib" for l in $old_library $library_names; do - ll="$l" + ll=$l done - if test "X$ll" = "X$old_library" ; then # only static version available - found=no + if test "X$ll" = "X$old_library"; then # only static version available + found=false func_dirname "$lib" "" "." - ladir="$func_dirname_result" + ladir=$func_dirname_result lib=$ladir/$old_library - if test "$linkmode,$pass" = "prog,link"; then + if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi @@ -6244,15 +7503,25 @@ func_mode_link () *) ;; esac fi + else + # deplib doesn't seem to be a libtool library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue fi ;; # -l *.ltframework) - if test "$linkmode,$pass" = "prog,link"; then + if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" - if test "$linkmode" = lib ; then + if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; @@ -6265,18 +7534,18 @@ func_mode_link () case $linkmode in lib) deplibs="$deplib $deplibs" - test "$pass" = conv && continue + test conv = "$pass" && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) - if test "$pass" = conv; then + if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi - if test "$pass" = scan; then + if test scan = "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" @@ -6287,13 +7556,13 @@ func_mode_link () func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) - func_warning "\`-L' is ignored for archives/objects" + func_warning "'-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) - if test "$pass" = link; then + if test link = "$pass"; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result @@ -6311,7 +7580,7 @@ func_mode_link () lib=$func_resolve_sysroot_result ;; *.$libext) - if test "$pass" = conv; then + if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi @@ -6322,21 +7591,26 @@ func_mode_link () case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) - valid_a_lib=no + valid_a_lib=false case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then - valid_a_lib=yes + valid_a_lib=: fi ;; pass_all) - valid_a_lib=yes + valid_a_lib=: ;; esac - if test "$valid_a_lib" != yes; then + if $valid_a_lib; then + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + else echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" @@ -6344,18 +7618,13 @@ func_mode_link () echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." - else - echo - $ECHO "*** Warning: Linking the shared library $output against the" - $ECHO "*** static library $deplib is not portable!" - deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) - if test "$pass" != link; then + if test link != "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" @@ -6366,10 +7635,10 @@ func_mode_link () esac # linkmode ;; # *.$libext *.lo | *.$objext) - if test "$pass" = conv; then + if test conv = "$pass"; then deplibs="$deplib $deplibs" - elif test "$linkmode" = prog; then - if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + elif test prog = "$linkmode"; then + if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" @@ -6382,22 +7651,20 @@ func_mode_link () continue ;; %DEPLIBS%) - alldeplibs=yes + alldeplibs=: continue ;; esac # case $deplib - if test "$found" = yes || test -f "$lib"; then : - else - func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" - fi + $found || test -f "$lib" \ + || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ - || func_fatal_error "\`$lib' is not a valid libtool archive" + || func_fatal_error "'$lib' is not a valid libtool archive" func_dirname "$lib" "" "." - ladir="$func_dirname_result" + ladir=$func_dirname_result dlname= dlopen= @@ -6427,30 +7694,30 @@ func_mode_link () done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan" || - { test "$linkmode" != prog && test "$linkmode" != lib; }; then + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass" || + { test prog != "$linkmode" && test lib != "$linkmode"; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi - if test "$pass" = conv; then + if test conv = "$pass"; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then - func_fatal_error "cannot find name of link library for \`$lib'" + func_fatal_error "cannot find name of link library for '$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" - elif test "$linkmode" != prog && test "$linkmode" != lib; then - func_fatal_error "\`$lib' is not a convenience library" + elif test prog != "$linkmode" && test lib != "$linkmode"; then + func_fatal_error "'$lib' is not a convenience library" fi tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" - if $opt_preserve_dup_deps ; then + if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac @@ -6464,26 +7731,26 @@ func_mode_link () # Get the name of the library we link against. linklib= if test -n "$old_library" && - { test "$prefer_static_libs" = yes || - test "$prefer_static_libs,$installed" = "built,no"; }; then + { test yes = "$prefer_static_libs" || + test built,no = "$prefer_static_libs,$installed"; }; then linklib=$old_library else for l in $old_library $library_names; do - linklib="$l" + linklib=$l done fi if test -z "$linklib"; then - func_fatal_error "cannot find name of link library for \`$lib'" + func_fatal_error "cannot find name of link library for '$lib'" fi # This library was specified with -dlopen. - if test "$pass" = dlopen; then - if test -z "$libdir"; then - func_fatal_error "cannot -dlopen a convenience library: \`$lib'" - fi + if test dlopen = "$pass"; then + test -z "$libdir" \ + && func_fatal_error "cannot -dlopen a convenience library: '$lib'" if test -z "$dlname" || - test "$dlopen_support" != yes || - test "$build_libtool_libs" = no; then + test yes != "$dlopen_support" || + test no = "$build_libtool_libs" + then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't @@ -6497,40 +7764,40 @@ func_mode_link () # We need an absolute path. case $ladir in - [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then - func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "cannot determine absolute directory name of '$ladir'" func_warning "passing it literally to the linker, although it might fail" - abs_ladir="$ladir" + abs_ladir=$ladir fi ;; esac func_basename "$lib" - laname="$func_basename_result" + laname=$func_basename_result # Find the relevant object directory and library name. - if test "X$installed" = Xyes; then + if test yes = "$installed"; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then - func_warning "library \`$lib' was moved." - dir="$ladir" - absdir="$abs_ladir" - libdir="$abs_ladir" + func_warning "library '$lib' was moved." + dir=$ladir + absdir=$abs_ladir + libdir=$abs_ladir else - dir="$lt_sysroot$libdir" - absdir="$lt_sysroot$libdir" + dir=$lt_sysroot$libdir + absdir=$lt_sysroot$libdir fi - test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + test yes = "$hardcode_automatic" && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then - dir="$ladir" - absdir="$abs_ladir" + dir=$ladir + absdir=$abs_ladir # Remove this search path later func_append notinst_path " $abs_ladir" else - dir="$ladir/$objdir" - absdir="$abs_ladir/$objdir" + dir=$ladir/$objdir + absdir=$abs_ladir/$objdir # Remove this search path later func_append notinst_path " $abs_ladir" fi @@ -6539,11 +7806,11 @@ func_mode_link () name=$func_stripname_result # This library was specified with -dlpreopen. - if test "$pass" = dlpreopen; then - if test -z "$libdir" && test "$linkmode" = prog; then - func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + if test dlpreopen = "$pass"; then + if test -z "$libdir" && test prog = "$linkmode"; then + func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" fi - case "$host" in + case $host in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both @@ -6587,9 +7854,9 @@ func_mode_link () if test -z "$libdir"; then # Link the convenience library - if test "$linkmode" = lib; then + if test lib = "$linkmode"; then deplibs="$dir/$old_library $deplibs" - elif test "$linkmode,$pass" = "prog,link"; then + elif test prog,link = "$linkmode,$pass"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else @@ -6599,14 +7866,14 @@ func_mode_link () fi - if test "$linkmode" = prog && test "$pass" != link; then + if test prog = "$linkmode" && test link != "$pass"; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" - linkalldeplibs=no - if test "$link_all_deplibs" != no || test -z "$library_names" || - test "$build_libtool_libs" = no; then - linkalldeplibs=yes + linkalldeplibs=false + if test no != "$link_all_deplibs" || test -z "$library_names" || + test no = "$build_libtool_libs"; then + linkalldeplibs=: fi tmp_libs= @@ -6618,14 +7885,14 @@ func_mode_link () ;; esac # Need to link against all dependency_libs? - if test "$linkalldeplibs" = yes; then + if $linkalldeplibs; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi - if $opt_preserve_dup_deps ; then + if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac @@ -6635,15 +7902,15 @@ func_mode_link () continue fi # $linkmode = prog... - if test "$linkmode,$pass" = "prog,link"; then + if test prog,link = "$linkmode,$pass"; then if test -n "$library_names" && - { { test "$prefer_static_libs" = no || - test "$prefer_static_libs,$installed" = "built,yes"; } || + { { test no = "$prefer_static_libs" || + test built,yes = "$prefer_static_libs,$installed"; } || test -z "$old_library"; }; then # We need to hardcode the library path - if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then # Make sure the rpath contains only unique directories. - case "$temp_rpath:" in + case $temp_rpath: in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac @@ -6672,9 +7939,9 @@ func_mode_link () esac fi # $linkmode,$pass = prog,link... - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && + if $alldeplibs && + { test pass_all = "$deplibs_check_method" || + { test yes = "$build_libtool_libs" && test -n "$library_names"; }; }; then # We only need to search for static libraries continue @@ -6683,11 +7950,11 @@ func_mode_link () link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs - if test "$use_static_libs" = built && test "$installed" = yes; then + if test built = "$use_static_libs" && test yes = "$installed"; then use_static_libs=no fi if test -n "$library_names" && - { test "$use_static_libs" = no || test -z "$old_library"; }; then + { test no = "$use_static_libs" || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded @@ -6695,7 +7962,7 @@ func_mode_link () need_relink=no ;; *) - if test "$installed" = no; then + if test no = "$installed"; then func_append notinst_deplibs " $lib" need_relink=yes fi @@ -6705,24 +7972,24 @@ func_mode_link () # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! - dlopenmodule="" + dlopenmodule= for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then - dlopenmodule="$dlpremoduletest" + dlopenmodule=$dlpremoduletest break fi done - if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then echo - if test "$linkmode" = prog; then + if test prog = "$linkmode"; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi - if test "$linkmode" = lib && - test "$hardcode_into_libs" = yes; then + if test lib = "$linkmode" && + test yes = "$hardcode_into_libs"; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. @@ -6750,43 +8017,43 @@ func_mode_link () # figure out the soname set dummy $library_names shift - realname="$1" + realname=$1 shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then - soname="$dlname" + soname=$dlname elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc*) func_arith $current - $age major=$func_arith_result - versuffix="-$major" + versuffix=-$major ;; esac eval soname=\"$soname_spec\" else - soname="$realname" + soname=$realname fi # Make a new name for the extract_expsyms_cmds to use - soroot="$soname" + soroot=$soname func_basename "$soroot" - soname="$func_basename_result" + soname=$func_basename_result func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else - func_verbose "extracting exported symbol list from \`$soname'" + func_verbose "extracting exported symbol list from '$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else - func_verbose "generating import library for \`$soname'" + func_verbose "generating import library for '$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library @@ -6794,58 +8061,58 @@ func_mode_link () linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" - if test "$linkmode" = prog || test "$opt_mode" != relink; then + if test prog = "$linkmode" || test relink != "$opt_mode"; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) - if test "$hardcode_direct" = no; then - add="$dir/$linklib" + if test no = "$hardcode_direct"; then + add=$dir/$linklib case $host in - *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; - *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; + *-*-sysv4*uw2*) add_dir=-L$dir ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ - *-*-unixware7*) add_dir="-L$dir" ;; + *-*-unixware7*) add_dir=-L$dir ;; *-*-darwin* ) - # if the lib is a (non-dlopened) module then we can not + # if the lib is a (non-dlopened) module then we cannot # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | - $GREP ": [^:]* bundle" >/dev/null ; then + $GREP ": [^:]* bundle" >/dev/null; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" - if test -z "$old_library" ; then + if test -z "$old_library"; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else - add="$dir/$old_library" + add=$dir/$old_library fi elif test -n "$old_library"; then - add="$dir/$old_library" + add=$dir/$old_library fi fi esac - elif test "$hardcode_minus_L" = no; then + elif test no = "$hardcode_minus_L"; then case $host in - *-*-sunos*) add_shlibpath="$dir" ;; + *-*-sunos*) add_shlibpath=$dir ;; esac - add_dir="-L$dir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = no; then - add_shlibpath="$dir" - add="-l$name" + add_dir=-L$dir + add=-l$name + elif test no = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name else lib_linked=no fi ;; relink) - if test "$hardcode_direct" = yes && - test "$hardcode_direct_absolute" = no; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$absdir" + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$dir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$absdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in @@ -6854,10 +8121,10 @@ func_mode_link () ;; esac fi - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - add_shlibpath="$dir" - add="-l$name" + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name else lib_linked=no fi @@ -6865,7 +8132,7 @@ func_mode_link () *) lib_linked=no ;; esac - if test "$lib_linked" != yes; then + if test yes != "$lib_linked"; then func_fatal_configuration "unsupported hardcode properties" fi @@ -6875,15 +8142,15 @@ func_mode_link () *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi - if test "$linkmode" = prog; then + if test prog = "$linkmode"; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" - if test "$hardcode_direct" != yes && - test "$hardcode_minus_L" != yes && - test "$hardcode_shlibpath_var" = yes; then + if test yes != "$hardcode_direct" && + test yes != "$hardcode_minus_L" && + test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; @@ -6892,33 +8159,33 @@ func_mode_link () fi fi - if test "$linkmode" = prog || test "$opt_mode" = relink; then + if test prog = "$linkmode" || test relink = "$opt_mode"; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. - if test "$hardcode_direct" = yes && - test "$hardcode_direct_absolute" = no; then - add="$libdir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$libdir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$libdir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$libdir + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac - add="-l$name" - elif test "$hardcode_automatic" = yes; then + add=-l$name + elif test yes = "$hardcode_automatic"; then if test -n "$inst_prefix_dir" && - test -f "$inst_prefix_dir$libdir/$linklib" ; then - add="$inst_prefix_dir$libdir/$linklib" + test -f "$inst_prefix_dir$libdir/$linklib"; then + add=$inst_prefix_dir$libdir/$linklib else - add="$libdir/$linklib" + add=$libdir/$linklib fi else # We cannot seem to hardcode it, guess we'll fake it. - add_dir="-L$libdir" + add_dir=-L$libdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in @@ -6927,10 +8194,10 @@ func_mode_link () ;; esac fi - add="-l$name" + add=-l$name fi - if test "$linkmode" = prog; then + if test prog = "$linkmode"; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else @@ -6938,43 +8205,43 @@ func_mode_link () test -n "$add" && deplibs="$add $deplibs" fi fi - elif test "$linkmode" = prog; then + elif test prog = "$linkmode"; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. - if test "$hardcode_direct" != unsupported; then - test -n "$old_library" && linklib="$old_library" + if test unsupported != "$hardcode_direct"; then + test -n "$old_library" && linklib=$old_library compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi - elif test "$build_libtool_libs" = yes; then + elif test yes = "$build_libtool_libs"; then # Not a shared library - if test "$deplibs_check_method" != pass_all; then + if test pass_all != "$deplibs_check_method"; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo - $ECHO "*** Warning: This system can not link to static lib archive $lib." + $ECHO "*** Warning: This system cannot link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." - if test "$module" = yes; then + if test yes = "$module"; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." + echo "*** 'nm' from GNU binutils and a full rebuild may help." fi - if test "$build_old_libs" = no; then + if test no = "$build_old_libs"; then build_libtool_libs=module build_old_libs=yes else @@ -6987,11 +8254,11 @@ func_mode_link () fi fi # link shared/static library? - if test "$linkmode" = lib; then + if test lib = "$linkmode"; then if test -n "$dependency_libs" && - { test "$hardcode_into_libs" != yes || - test "$build_old_libs" = yes || - test "$link_static" = yes; }; then + { test yes != "$hardcode_into_libs" || + test yes = "$build_old_libs" || + test yes = "$link_static"; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do @@ -7005,12 +8272,12 @@ func_mode_link () *) func_append temp_deplibs " $libdir";; esac done - dependency_libs="$temp_deplibs" + dependency_libs=$temp_deplibs fi func_append newlib_search_path " $absdir" # Link against this library - test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do @@ -7020,7 +8287,7 @@ func_mode_link () func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac - if $opt_preserve_dup_deps ; then + if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; @@ -7029,12 +8296,12 @@ func_mode_link () func_append tmp_libs " $func_resolve_sysroot_result" done - if test "$link_all_deplibs" != no; then + if test no != "$link_all_deplibs"; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in - -L*) path="$deplib" ;; + -L*) path=$deplib ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result @@ -7042,12 +8309,12 @@ func_mode_link () dir=$func_dirname_result # We need an absolute path. case $dir in - [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then - func_warning "cannot determine absolute directory name of \`$dir'" - absdir="$dir" + func_warning "cannot determine absolute directory name of '$dir'" + absdir=$dir fi ;; esac @@ -7055,35 +8322,35 @@ func_mode_link () case $host in *-*-darwin*) depdepl= - eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` - if test -n "$deplibrary_names" ; then - for tmp in $deplibrary_names ; do + eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names"; then + for tmp in $deplibrary_names; do depdepl=$tmp done - if test -f "$absdir/$objdir/$depdepl" ; then - depdepl="$absdir/$objdir/$depdepl" - darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -f "$absdir/$objdir/$depdepl"; then + depdepl=$absdir/$objdir/$depdepl + darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then - darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi - func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" - func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" + func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" + func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" path= fi fi ;; *) - path="-L$absdir/$objdir" + path=-L$absdir/$objdir ;; esac else - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ - func_fatal_error "\`$deplib' is not a valid libtool archive" + func_fatal_error "'$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ - func_warning "\`$deplib' seems to be moved" + func_warning "'$deplib' seems to be moved" - path="-L$absdir" + path=-L$absdir fi ;; esac @@ -7095,23 +8362,23 @@ func_mode_link () fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs - if test "$pass" = link; then - if test "$linkmode" = "prog"; then + if test link = "$pass"; then + if test prog = "$linkmode"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi - dependency_libs="$newdependency_libs" - if test "$pass" = dlpreopen; then + dependency_libs=$newdependency_libs + if test dlpreopen = "$pass"; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi - if test "$pass" != dlopen; then - if test "$pass" != conv; then + if test dlopen != "$pass"; then + test conv = "$pass" || { # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do @@ -7121,12 +8388,12 @@ func_mode_link () esac done newlib_search_path= - fi + } - if test "$linkmode,$pass" != "prog,link"; then - vars="deplibs" - else + if test prog,link = "$linkmode,$pass"; then vars="compile_deplibs finalize_deplibs" + else + vars=deplibs fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order @@ -7187,59 +8454,59 @@ func_mode_link () # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= - for i in $dependency_libs ; do + for i in $dependency_libs; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) - i="" + i= ;; esac - if test -n "$i" ; then + if test -n "$i"; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass - if test "$linkmode" = prog; then - dlfiles="$newdlfiles" + if test prog = "$linkmode"; then + dlfiles=$newdlfiles fi - if test "$linkmode" = prog || test "$linkmode" = lib; then - dlprefiles="$newdlprefiles" + if test prog = "$linkmode" || test lib = "$linkmode"; then + dlprefiles=$newdlprefiles fi case $linkmode in oldlib) - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - func_warning "\`-dlopen' is ignored for archives" + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) - func_warning "\`-l' and \`-L' are ignored for archives" ;; + func_warning "'-l' and '-L' are ignored for archives" ;; esac test -n "$rpath" && \ - func_warning "\`-rpath' is ignored for archives" + func_warning "'-rpath' is ignored for archives" test -n "$xrpath" && \ - func_warning "\`-R' is ignored for archives" + func_warning "'-R' is ignored for archives" test -n "$vinfo" && \ - func_warning "\`-version-info/-version-number' is ignored for archives" + func_warning "'-version-info/-version-number' is ignored for archives" test -n "$release" && \ - func_warning "\`-release' is ignored for archives" + func_warning "'-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ - func_warning "\`-export-symbols' is ignored for archives" + func_warning "'-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no - oldlibs="$output" + oldlibs=$output func_append objs "$old_deplibs" ;; lib) - # Make sure we only generate libraries of the form `libNAME.la'. + # Make sure we only generate libraries of the form 'libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" @@ -7248,10 +8515,10 @@ func_mode_link () eval libname=\"$libname_spec\" ;; *) - test "$module" = no && \ - func_fatal_help "libtool library \`$output' must begin with \`lib'" + test no = "$module" \ + && func_fatal_help "libtool library '$output' must begin with 'lib'" - if test "$need_lib_prefix" != no; then + if test no != "$need_lib_prefix"; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result @@ -7265,8 +8532,8 @@ func_mode_link () esac if test -n "$objs"; then - if test "$deplibs_check_method" != pass_all; then - func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + if test pass_all != "$deplibs_check_method"; then + func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" @@ -7275,21 +8542,21 @@ func_mode_link () fi fi - test "$dlself" != no && \ - func_warning "\`-dlopen self' is ignored for libtool libraries" + test no = "$dlself" \ + || func_warning "'-dlopen self' is ignored for libtool libraries" set dummy $rpath shift - test "$#" -gt 1 && \ - func_warning "ignoring multiple \`-rpath's for a libtool library" + test 1 -lt "$#" \ + && func_warning "ignoring multiple '-rpath's for a libtool library" - install_libdir="$1" + install_libdir=$1 oldlibs= if test -z "$rpath"; then - if test "$build_libtool_libs" = yes; then + if test yes = "$build_libtool_libs"; then # Building a libtool convenience library. - # Some compilers have problems with a `.al' extension so + # Some compilers have problems with a '.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" @@ -7298,20 +8565,20 @@ func_mode_link () fi test -n "$vinfo" && \ - func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + func_warning "'-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ - func_warning "\`-release' is ignored for convenience libraries" + func_warning "'-release' is ignored for convenience libraries" else # Parse the version information argument. - save_ifs="$IFS"; IFS=':' + save_ifs=$IFS; IFS=: set dummy $vinfo 0 0 0 shift - IFS="$save_ifs" + IFS=$save_ifs test -n "$7" && \ - func_fatal_help "too many parameters to \`-version-info'" + func_fatal_help "too many parameters to '-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts @@ -7319,42 +8586,42 @@ func_mode_link () case $vinfo_number in yes) - number_major="$1" - number_minor="$2" - number_revision="$3" + number_major=$1 + number_minor=$2 + number_revision=$3 # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix - # which has an extra 1 added just for fun + # that has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result - age="$number_minor" - revision="$number_revision" + age=$number_minor + revision=$number_revision ;; freebsd-aout|freebsd-elf|qnx|sunos) - current="$number_major" - revision="$number_minor" - age="0" + current=$number_major + revision=$number_minor + age=0 ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result - age="$number_minor" - revision="$number_minor" + age=$number_minor + revision=$number_minor lt_irix_increment=no ;; esac ;; no) - current="$1" - revision="$2" - age="$3" + current=$1 + revision=$2 + age=$3 ;; esac @@ -7362,30 +8629,30 @@ func_mode_link () case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) - func_error "CURRENT \`$current' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" + func_error "CURRENT '$current' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) - func_error "REVISION \`$revision' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" + func_error "REVISION '$revision' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) - func_error "AGE \`$age' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" + func_error "AGE '$age' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then - func_error "AGE \`$age' is greater than the current interface number \`$current'" - func_fatal_error "\`$vinfo' is not valid version information" + func_error "AGE '$age' is greater than the current interface number '$current'" + func_fatal_error "'$vinfo' is not valid version information" fi # Calculate the version variables. @@ -7400,26 +8667,35 @@ func_mode_link () # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result - versuffix="$major.$age.$revision" + versuffix=$major.$age.$revision # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result - xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + # On Darwin other compilers + case $CC in + nagfor*) + verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + ;; + *) + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + esac ;; freebsd-aout) - major=".$current" - versuffix=".$current.$revision"; + major=.$current + versuffix=.$current.$revision ;; freebsd-elf) - major=".$current" - versuffix=".$current" + major=.$current + versuffix=.$current ;; irix | nonstopux) - if test "X$lt_irix_increment" = "Xno"; then + if test no = "$lt_irix_increment"; then func_arith $current - $age else func_arith $current - $age + 1 @@ -7430,69 +8706,69 @@ func_mode_link () nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac - verstring="$verstring_prefix$major.$revision" + verstring=$verstring_prefix$major.$revision # Add in all the interfaces that we are compatible with. loop=$revision - while test "$loop" -ne 0; do + while test 0 -ne "$loop"; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result - verstring="$verstring_prefix$major.$iface:$verstring" + verstring=$verstring_prefix$major.$iface:$verstring done - # Before this point, $major must not contain `.'. + # Before this point, $major must not contain '.'. major=.$major - versuffix="$major.$revision" + versuffix=$major.$revision ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result - versuffix="$major.$age.$revision" + versuffix=$major.$age.$revision ;; osf) func_arith $current - $age major=.$func_arith_result - versuffix=".$current.$age.$revision" - verstring="$current.$age.$revision" + versuffix=.$current.$age.$revision + verstring=$current.$age.$revision # Add in all the interfaces that we are compatible with. loop=$age - while test "$loop" -ne 0; do + while test 0 -ne "$loop"; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result - verstring="$verstring:${iface}.0" + verstring=$verstring:$iface.0 done # Make executables depend on our current version. - func_append verstring ":${current}.0" + func_append verstring ":$current.0" ;; qnx) - major=".$current" - versuffix=".$current" + major=.$current + versuffix=.$current ;; sunos) - major=".$current" - versuffix=".$current.$revision" + major=.$current + versuffix=.$current.$revision ;; windows) # Use '-' rather than '.', since we only want one - # extension on DOS 8.3 filesystems. + # extension on DOS 8.3 file systems. func_arith $current - $age major=$func_arith_result - versuffix="-$major" + versuffix=-$major ;; *) - func_fatal_configuration "unknown library version type \`$version_type'" + func_fatal_configuration "unknown library version type '$version_type'" ;; esac @@ -7506,42 +8782,45 @@ func_mode_link () verstring= ;; *) - verstring="0.0" + verstring=0.0 ;; esac - if test "$need_version" = no; then + if test no = "$need_version"; then versuffix= else - versuffix=".0.0" + versuffix=.0.0 fi fi # Remove version info from name if versioning should be avoided - if test "$avoid_version" = yes && test "$need_version" = no; then + if test yes,no = "$avoid_version,$need_version"; then major= versuffix= - verstring="" + verstring= fi # Check to see if the archive will have undefined symbols. - if test "$allow_undefined" = yes; then - if test "$allow_undefined_flag" = unsupported; then - func_warning "undefined symbols not allowed in $host shared libraries" - build_libtool_libs=no - build_old_libs=yes + if test yes = "$allow_undefined"; then + if test unsupported = "$allow_undefined_flag"; then + if test yes = "$build_old_libs"; then + func_warning "undefined symbols not allowed in $host shared libraries; building static only" + build_libtool_libs=no + else + func_fatal_error "can't build $host shared library unless -no-undefined is specified" + fi fi else # Don't allow undefined symbols. - allow_undefined_flag="$no_undefined_flag" + allow_undefined_flag=$no_undefined_flag fi fi - func_generate_dlsyms "$libname" "$libname" "yes" + func_generate_dlsyms "$libname" "$libname" : func_append libobjs " $symfileobj" - test "X$libobjs" = "X " && libobjs= + test " " = "$libobjs" && libobjs= - if test "$opt_mode" != relink; then + if test relink != "$opt_mode"; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= @@ -7550,8 +8829,8 @@ func_mode_link () case $p in *.$objext | *.gcno) ;; - $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) - if test "X$precious_files_regex" != "X"; then + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) + if test -n "$precious_files_regex"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue @@ -7567,11 +8846,11 @@ func_mode_link () fi # Now set the variables for building old libraries. - if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. - oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. @@ -7592,13 +8871,13 @@ func_mode_link () *) func_append finalize_rpath " $libdir" ;; esac done - if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened - old_dlfiles="$dlfiles" + old_dlfiles=$dlfiles dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in @@ -7608,7 +8887,7 @@ func_mode_link () done # Make sure dlprefiles contains only unique files - old_dlprefiles="$dlprefiles" + old_dlprefiles=$dlprefiles dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in @@ -7617,7 +8896,7 @@ func_mode_link () esac done - if test "$build_libtool_libs" = yes; then + if test yes = "$build_libtool_libs"; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) @@ -7641,7 +8920,7 @@ func_mode_link () ;; *) # Add libc to deplibs on all other systems if necessary. - if test "$build_libtool_need_lc" = "yes"; then + if test yes = "$build_libtool_need_lc"; then func_append deplibs " -lc" fi ;; @@ -7657,9 +8936,9 @@ func_mode_link () # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? - release="" - versuffix="" - major="" + release= + versuffix= + major= newdeplibs= droppeddeps=no case $deplibs_check_method in @@ -7688,20 +8967,20 @@ EOF -l*) func_stripname -l '' "$i" name=$func_stripname_result - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $i "*) func_append newdeplibs " $i" - i="" + i= ;; esac fi - if test -n "$i" ; then + if test -n "$i"; then libname=`eval "\\$ECHO \"$libname_spec\""` deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` set dummy $deplib_matches; shift deplib_match=$1 - if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then + if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then func_append newdeplibs " $i" else droppeddeps=yes @@ -7731,20 +9010,20 @@ EOF $opt_dry_run || $RM conftest if $LTCC $LTCFLAGS -o conftest conftest.c $i; then ldd_output=`ldd conftest` - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $i "*) func_append newdeplibs " $i" - i="" + i= ;; esac fi - if test -n "$i" ; then + if test -n "$i"; then libname=`eval "\\$ECHO \"$libname_spec\""` deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` set dummy $deplib_matches; shift deplib_match=$1 - if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then + if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then func_append newdeplibs " $i" else droppeddeps=yes @@ -7781,24 +9060,24 @@ EOF -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" - a_deplib="" + a_deplib= ;; esac fi - if test -n "$a_deplib" ; then + if test -n "$a_deplib"; then libname=`eval "\\$ECHO \"$libname_spec\""` if test -n "$file_magic_glob"; then libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob` else libnameglob=$libname fi - test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob` + test yes = "$want_nocaseglob" && nocaseglob=`shopt -p nocaseglob` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - if test "$want_nocaseglob" = yes; then + if test yes = "$want_nocaseglob"; then shopt -s nocaseglob potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` $nocaseglob @@ -7816,25 +9095,25 @@ EOF # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? - potlib="$potent_lib" + potlib=$potent_lib while test -h "$potlib" 2>/dev/null; do - potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + potliblink=`ls -ld $potlib | $SED 's/.* -> //'` case $potliblink in - [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; - *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; + [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; + *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" - a_deplib="" + a_deplib= break 2 fi done done fi - if test -n "$a_deplib" ; then + if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." @@ -7842,7 +9121,7 @@ EOF echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then + if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" @@ -7865,30 +9144,30 @@ EOF -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" - a_deplib="" + a_deplib= ;; esac fi - if test -n "$a_deplib" ; then + if test -n "$a_deplib"; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do - potlib="$potent_lib" # see symlink-check above in file_magic test + potlib=$potent_lib # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" - a_deplib="" + a_deplib= break 2 fi done done fi - if test -n "$a_deplib" ; then + if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." @@ -7896,7 +9175,7 @@ EOF echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then + if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" @@ -7912,18 +9191,18 @@ EOF done # Gone through all deplibs. ;; none | unknown | *) - newdeplibs="" + newdeplibs= tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - for i in $predeps $postdeps ; do + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + for i in $predeps $postdeps; do # can't use Xsed below, because $i might contain '/' - tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` done fi case $tmp_deplibs in *[!\ \ ]*) echo - if test "X$deplibs_check_method" = "Xnone"; then + if test none = "$deplibs_check_method"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." @@ -7947,8 +9226,8 @@ EOF ;; esac - if test "$droppeddeps" = yes; then - if test "$module" = yes; then + if test yes = "$droppeddeps"; then + if test yes = "$module"; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" @@ -7957,12 +9236,12 @@ EOF if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." + echo "*** 'nm' from GNU binutils and a full rebuild may help." fi - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else @@ -7973,14 +9252,14 @@ EOF echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." - if test "$allow_undefined" = no; then + if test no = "$allow_undefined"; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else @@ -8026,7 +9305,7 @@ EOF *) func_append new_libs " $deplib" ;; esac done - deplibs="$new_libs" + deplibs=$new_libs # All the library-specific variables (install_libdir is set above). library_names= @@ -8034,25 +9313,25 @@ EOF dlname= # Test again, we may have decided not to build it any more - if test "$build_libtool_libs" = yes; then - # Remove ${wl} instances when linking with ld. + if test yes = "$build_libtool_libs"; then + # Remove $wl instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac - if test "$hardcode_into_libs" = yes; then + if test yes = "$hardcode_into_libs"; then # Hardcode the library paths hardcode_libdirs= dep_rpath= - rpath="$finalize_rpath" - test "$opt_mode" != relink && rpath="$compile_rpath$rpath" + rpath=$finalize_rpath + test relink = "$opt_mode" || rpath=$compile_rpath$rpath for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" + hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in @@ -8077,7 +9356,7 @@ EOF # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" + libdir=$hardcode_libdirs eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then @@ -8091,8 +9370,8 @@ EOF test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi - shlibpath="$finalize_shlibpath" - test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + shlibpath=$finalize_shlibpath + test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi @@ -8102,19 +9381,19 @@ EOF eval library_names=\"$library_names_spec\" set dummy $library_names shift - realname="$1" + realname=$1 shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else - soname="$realname" + soname=$realname fi if test -z "$dlname"; then dlname=$soname fi - lib="$output_objdir/$realname" + lib=$output_objdir/$realname linknames= for link do @@ -8128,7 +9407,7 @@ EOF delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" - export_symbols="$output_objdir/$libname.uexp" + export_symbols=$output_objdir/$libname.uexp func_append delfiles " $export_symbols" fi @@ -8137,31 +9416,31 @@ EOF cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile - if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + func_dll_def_p "$export_symbols" || { # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. - orig_export_symbols="$export_symbols" + orig_export_symbols=$export_symbols export_symbols= always_export_symbols=yes - fi + } fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then - if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then - func_verbose "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" + if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds - save_ifs="$IFS"; IFS='~' + save_ifs=$IFS; IFS='~' for cmd1 in $cmds; do - IFS="$save_ifs" + IFS=$save_ifs # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in @@ -8175,7 +9454,7 @@ EOF try_normal_branch=no ;; esac - if test "$try_normal_branch" = yes \ + if test yes = "$try_normal_branch" \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then @@ -8186,7 +9465,7 @@ EOF output_la=$func_basename_result save_libobjs=$libobjs save_output=$output - output=${output_objdir}/${output_la}.nm + output=$output_objdir/$output_la.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" @@ -8209,8 +9488,8 @@ EOF break fi done - IFS="$save_ifs" - if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + IFS=$save_ifs + if test -n "$export_symbols_regex" && test : != "$skipped_export"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi @@ -8218,16 +9497,16 @@ EOF fi if test -n "$export_symbols" && test -n "$include_expsyms"; then - tmp_export_symbols="$export_symbols" - test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi - if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + if test : != "$skipped_export" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. - func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of - # 's' commands which not all seds can handle. GNU sed should be fine + # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. @@ -8246,11 +9525,11 @@ EOF ;; esac done - deplibs="$tmp_deplibs" + deplibs=$tmp_deplibs if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && - test "$compiler_needs_object" = yes && + test yes = "$compiler_needs_object" && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. @@ -8261,7 +9540,7 @@ EOF eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else - gentop="$output_objdir/${outputname}x" + gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $convenience @@ -8270,18 +9549,18 @@ EOF fi fi - if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking - if test "$opt_mode" = relink; then + if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then + if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds @@ -8299,7 +9578,7 @@ EOF fi fi - if test "X$skipped_export" != "X:" && + if test : != "$skipped_export" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then @@ -8332,8 +9611,8 @@ EOF last_robj= k=1 - if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then - output=${output_objdir}/${output_la}.lnkscript + if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then + output=$output_objdir/$output_la.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs @@ -8345,14 +9624,14 @@ EOF func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result - elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then - output=${output_objdir}/${output_la}.lnk + elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then + output=$output_objdir/$output_la.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= - if test "$compiler_needs_object" = yes; then + if test yes = "$compiler_needs_object"; then firstobj="$1 " shift fi @@ -8367,7 +9646,7 @@ EOF else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." - output=$output_objdir/$output_la-${k}.$objext + output=$output_objdir/$output_la-$k.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result @@ -8379,13 +9658,13 @@ EOF func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result - if test "X$objlist" = X || + if test -z "$objlist" || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. - if test "$k" -eq 1 ; then + if test 1 -eq "$k"; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" @@ -8395,10 +9674,10 @@ EOF reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi - last_robj=$output_objdir/$output_la-${k}.$objext + last_robj=$output_objdir/$output_la-$k.$objext func_arith $k + 1 k=$func_arith_result - output=$output_objdir/$output_la-${k}.$objext + output=$output_objdir/$output_la-$k.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result @@ -8410,9 +9689,9 @@ EOF # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" - eval concat_cmds=\"\${concat_cmds}$reload_cmds\" + eval concat_cmds=\"\$concat_cmds$reload_cmds\" if test -n "$last_robj"; then - eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi func_append delfiles " $output" @@ -8420,9 +9699,9 @@ EOF output= fi - if ${skipped_export-false}; then - func_verbose "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" + ${skipped_export-false} && { + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. @@ -8431,16 +9710,16 @@ EOF if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi - fi + } test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. - save_ifs="$IFS"; IFS='~' + save_ifs=$IFS; IFS='~' for cmd in $concat_cmds; do - IFS="$save_ifs" - $opt_silent || { + IFS=$save_ifs + $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } @@ -8448,7 +9727,7 @@ EOF lt_exit=$? # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then + if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) @@ -8457,7 +9736,7 @@ EOF exit $lt_exit } done - IFS="$save_ifs" + IFS=$save_ifs if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' @@ -8465,18 +9744,18 @@ EOF fi fi - if ${skipped_export-false}; then + ${skipped_export-false} && { if test -n "$export_symbols" && test -n "$include_expsyms"; then - tmp_export_symbols="$export_symbols" - test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. - func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of - # 's' commands which not all seds can handle. GNU sed should be fine + # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. @@ -8485,7 +9764,7 @@ EOF export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi - fi + } libobjs=$output # Restore the value of output. @@ -8499,7 +9778,7 @@ EOF # value of $libobjs for piecewise linking. # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then + if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else @@ -8521,7 +9800,7 @@ EOF # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then - gentop="$output_objdir/${outputname}x" + gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles @@ -8529,11 +9808,12 @@ EOF test "X$libobjs" = "X " && libobjs= fi - save_ifs="$IFS"; IFS='~' + save_ifs=$IFS; IFS='~' for cmd in $cmds; do - IFS="$save_ifs" + IFS=$sp$nl eval cmd=\"$cmd\" - $opt_silent || { + IFS=$save_ifs + $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } @@ -8541,7 +9821,7 @@ EOF lt_exit=$? # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then + if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) @@ -8550,10 +9830,10 @@ EOF exit $lt_exit } done - IFS="$save_ifs" + IFS=$save_ifs # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then + if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then @@ -8573,39 +9853,39 @@ EOF done # If -module or -export-dynamic was specified, set the dlname. - if test "$module" = yes || test "$export_dynamic" = yes; then + if test yes = "$module" || test yes = "$export_dynamic"; then # On all known operating systems, these are identical. - dlname="$soname" + dlname=$soname fi fi ;; obj) - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - func_warning "\`-dlopen' is ignored for objects" + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) - func_warning "\`-l' and \`-L' are ignored for objects" ;; + func_warning "'-l' and '-L' are ignored for objects" ;; esac test -n "$rpath" && \ - func_warning "\`-rpath' is ignored for objects" + func_warning "'-rpath' is ignored for objects" test -n "$xrpath" && \ - func_warning "\`-R' is ignored for objects" + func_warning "'-R' is ignored for objects" test -n "$vinfo" && \ - func_warning "\`-version-info' is ignored for objects" + func_warning "'-version-info' is ignored for objects" test -n "$release" && \ - func_warning "\`-release' is ignored for objects" + func_warning "'-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ - func_fatal_error "cannot build library object \`$output' from non-libtool objects" + func_fatal_error "cannot build library object '$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" @@ -8613,7 +9893,7 @@ EOF ;; *) libobj= - obj="$output" + obj=$output ;; esac @@ -8636,7 +9916,7 @@ EOF eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` else - gentop="$output_objdir/${obj}x" + gentop=$output_objdir/${obj}x func_append generated " $gentop" func_extract_archives $gentop $convenience @@ -8645,12 +9925,12 @@ EOF fi # If we're not building shared, we need to use non_pic_objs - test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" + test yes = "$build_libtool_libs" || libobjs=$non_pic_objects # Create the old-style object. - reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs - output="$obj" + output=$obj func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. @@ -8662,7 +9942,7 @@ EOF exit $EXIT_SUCCESS fi - if test "$build_libtool_libs" != yes; then + test yes = "$build_libtool_libs" || { if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi @@ -8672,12 +9952,12 @@ EOF # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS - fi + } - if test -n "$pic_flag" || test "$pic_mode" != default; then + if test -n "$pic_flag" || test default != "$pic_mode"; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" - output="$libobj" + output=$libobj func_execute_cmds "$reload_cmds" 'exit $?' fi @@ -8694,16 +9974,14 @@ EOF output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ - func_warning "\`-version-info' is ignored for programs" + func_warning "'-version-info' is ignored for programs" test -n "$release" && \ - func_warning "\`-release' is ignored for programs" + func_warning "'-release' is ignored for programs" - test "$preload" = yes \ - && test "$dlopen_support" = unknown \ - && test "$dlopen_self" = unknown \ - && test "$dlopen_self_static" = unknown && \ - func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + $preload \ + && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ + && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) @@ -8717,11 +9995,11 @@ EOF *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). - if test "$tagname" = CXX ; then + if test CXX = "$tagname"; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) - func_append compile_command " ${wl}-bind_at_load" - func_append finalize_command " ${wl}-bind_at_load" + func_append compile_command " $wl-bind_at_load" + func_append finalize_command " $wl-bind_at_load" ;; esac fi @@ -8757,7 +10035,7 @@ EOF *) func_append new_libs " $deplib" ;; esac done - compile_deplibs="$new_libs" + compile_deplibs=$new_libs func_append compile_command " $compile_deplibs" @@ -8781,7 +10059,7 @@ EOF if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" + hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in @@ -8804,7 +10082,7 @@ EOF fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; @@ -8821,10 +10099,10 @@ EOF # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" + libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi - compile_rpath="$rpath" + compile_rpath=$rpath rpath= hardcode_libdirs= @@ -8832,7 +10110,7 @@ EOF if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" + hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in @@ -8857,45 +10135,43 @@ EOF # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" + libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi - finalize_rpath="$rpath" + finalize_rpath=$rpath - if test -n "$libobjs" && test "$build_old_libs" = yes; then + if test -n "$libobjs" && test yes = "$build_old_libs"; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi - func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + func_generate_dlsyms "$outputname" "@PROGRAM@" false # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi - wrappers_required=yes + wrappers_required=: case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. - wrappers_required=no + wrappers_required=false ;; *cygwin* | *mingw* ) - if test "$build_libtool_libs" != yes; then - wrappers_required=no - fi + test yes = "$build_libtool_libs" || wrappers_required=false ;; *) - if test "$need_relink" = no || test "$build_libtool_libs" != yes; then - wrappers_required=no + if test no = "$need_relink" || test yes != "$build_libtool_libs"; then + wrappers_required=false fi ;; esac - if test "$wrappers_required" = no; then + $wrappers_required || { # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` - link_command="$compile_command$compile_rpath" + link_command=$compile_command$compile_rpath # We have no uninstalled library dependencies, so finalize right now. exit_status=0 @@ -8908,12 +10184,12 @@ EOF fi # Delete the generated files. - if test -f "$output_objdir/${outputname}S.${objext}"; then - func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + if test -f "$output_objdir/${outputname}S.$objext"; then + func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' fi exit $exit_status - fi + } if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" @@ -8943,9 +10219,9 @@ EOF fi fi - if test "$no_install" = yes; then + if test yes = "$no_install"; then # We don't need to create a wrapper script. - link_command="$compile_var$compile_command$compile_rpath" + link_command=$compile_var$compile_command$compile_rpath # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. @@ -8962,27 +10238,28 @@ EOF exit $EXIT_SUCCESS fi - if test "$hardcode_action" = relink; then - # Fast installation is not supported - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" + case $hardcode_action,$fast_install in + relink,*) + # Fast installation is not supported + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath - func_warning "this platform does not like uninstalled shared libraries" - func_warning "\`$output' will be relinked during installation" - else - if test "$fast_install" != no; then - link_command="$finalize_var$compile_command$finalize_rpath" - if test "$fast_install" = yes; then - relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` - else - # fast_install is set to needless - relink_command= - fi - else - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - fi - fi + func_warning "this platform does not like uninstalled shared libraries" + func_warning "'$output' will be relinked during installation" + ;; + *,yes) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + ;; + *,no) + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + ;; + *,needless) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command= + ;; + esac # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` @@ -9039,8 +10316,8 @@ EOF func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result - cwrappersource="$output_path/$objdir/lt-$output_name.c" - cwrapper="$output_path/$output_name.exe" + cwrappersource=$output_path/$objdir/lt-$output_name.c + cwrapper=$output_path/$output_name.exe $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 @@ -9061,7 +10338,7 @@ EOF trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. - if test "x$build" = "x$host" ; then + if test "x$build" = "x$host"; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result @@ -9084,25 +10361,27 @@ EOF # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do - if test "$build_libtool_libs" = convenience; then - oldobjs="$libobjs_save $symfileobj" - addlibs="$convenience" - build_libtool_libs=no - else - if test "$build_libtool_libs" = module; then - oldobjs="$libobjs_save" + case $build_libtool_libs in + convenience) + oldobjs="$libobjs_save $symfileobj" + addlibs=$convenience build_libtool_libs=no - else + ;; + module) + oldobjs=$libobjs_save + addlibs=$old_convenience + build_libtool_libs=no + ;; + *) oldobjs="$old_deplibs $non_pic_objects" - if test "$preload" = yes && test -f "$symfileobj"; then - func_append oldobjs " $symfileobj" - fi - fi - addlibs="$old_convenience" - fi + $preload && test -f "$symfileobj" \ + && func_append oldobjs " $symfileobj" + addlibs=$old_convenience + ;; + esac if test -n "$addlibs"; then - gentop="$output_objdir/${outputname}x" + gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $addlibs @@ -9110,13 +10389,13 @@ EOF fi # Do each command in the archive commands. - if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then - gentop="$output_objdir/${outputname}x" + gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles @@ -9137,7 +10416,7 @@ EOF : else echo "copying selected object files to avoid basename conflicts..." - gentop="$output_objdir/${outputname}x" + gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs @@ -9146,7 +10425,7 @@ EOF for obj in $save_oldobjs do func_basename "$obj" - objbase="$func_basename_result" + objbase=$func_basename_result case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) @@ -9215,18 +10494,18 @@ EOF else # the above command should be used before it gets too long oldobjs=$objlist - if test "$obj" = "$last_oldobj" ; then + if test "$obj" = "$last_oldobj"; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist - if test "X$oldobjs" = "X" ; then + if test -z "$oldobjs"; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" @@ -9243,7 +10522,7 @@ EOF case $output in *.la) old_library= - test "$build_old_libs" = yes && old_library="$libname.$libext" + test yes = "$build_old_libs" && old_library=$libname.$libext func_verbose "creating $output" # Preserve any variables that may affect compiler behavior @@ -9258,31 +10537,31 @@ EOF fi done # Quote the link command for shipping. - relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` - if test "$hardcode_automatic" = yes ; then + if test yes = "$hardcode_automatic"; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do - if test "$installed" = yes; then + if test yes = "$installed"; then if test -z "$install_libdir"; then break fi - output="$output_objdir/$outputname"i + output=$output_objdir/${outputname}i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" - name="$func_basename_result" + name=$func_basename_result func_resolve_sysroot "$deplib" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ - func_fatal_error "\`$deplib' is not a valid libtool archive" + func_fatal_error "'$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) @@ -9298,23 +10577,23 @@ EOF *) func_append newdependency_libs " $deplib" ;; esac done - dependency_libs="$newdependency_libs" + dependency_libs=$newdependency_libs newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" - name="$func_basename_result" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ - func_fatal_error "\`$lib' is not a valid libtool archive" + func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done - dlfiles="$newdlfiles" + dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in @@ -9324,34 +10603,34 @@ EOF # didn't already link the preopened objects directly into # the library: func_basename "$lib" - name="$func_basename_result" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ - func_fatal_error "\`$lib' is not a valid libtool archive" + func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done - dlprefiles="$newdlprefiles" + dlprefiles=$newdlprefiles else newdlfiles= for lib in $dlfiles; do case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done - dlfiles="$newdlfiles" + dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done - dlprefiles="$newdlprefiles" + dlprefiles=$newdlprefiles fi $RM $output # place dlname in correct position for cygwin @@ -9367,10 +10646,9 @@ EOF case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. - if test "x$bindir" != x ; - then + if test -n "$bindir"; then func_relative_path "$install_libdir" "$bindir" - tdlname=$func_relative_path_result$dlname + tdlname=$func_relative_path_result/$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname @@ -9379,7 +10657,7 @@ EOF esac $ECHO > $output "\ # $outputname - a libtool library file -# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. @@ -9393,7 +10671,7 @@ library_names='$library_names' # The name of the static archive. old_library='$old_library' -# Linker flags that can not go in dependency_libs. +# Linker flags that cannot go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. @@ -9419,7 +10697,7 @@ dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" - if test "$installed" = no && test "$need_relink" = yes; then + if test no,yes = "$installed,$need_relink"; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi @@ -9434,27 +10712,29 @@ relink_command=\"$relink_command\"" exit $EXIT_SUCCESS } -{ test "$opt_mode" = link || test "$opt_mode" = relink; } && - func_mode_link ${1+"$@"} +if test link = "$opt_mode" || test relink = "$opt_mode"; then + func_mode_link ${1+"$@"} +fi # func_mode_uninstall arg... func_mode_uninstall () { - $opt_debug - RM="$nonopt" + $debug_cmd + + RM=$nonopt files= - rmforce= + rmforce=false exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. - libtool_install_magic="$magic" + libtool_install_magic=$magic for arg do case $arg in - -f) func_append RM " $arg"; rmforce=yes ;; + -f) func_append RM " $arg"; rmforce=: ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac @@ -9467,18 +10747,18 @@ func_mode_uninstall () for file in $files; do func_dirname "$file" "" "." - dir="$func_dirname_result" - if test "X$dir" = X.; then - odir="$objdir" + dir=$func_dirname_result + if test . = "$dir"; then + odir=$objdir else - odir="$dir/$objdir" + odir=$dir/$objdir fi func_basename "$file" - name="$func_basename_result" - test "$opt_mode" = uninstall && odir="$dir" + name=$func_basename_result + test uninstall = "$opt_mode" && odir=$dir # Remember odir for removal later, being careful to avoid duplicates - if test "$opt_mode" = clean; then + if test clean = "$opt_mode"; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; @@ -9493,11 +10773,11 @@ func_mode_uninstall () elif test -d "$file"; then exit_status=1 continue - elif test "$rmforce" = yes; then + elif $rmforce; then continue fi - rmfiles="$file" + rmfiles=$file case $name in *.la) @@ -9511,7 +10791,7 @@ func_mode_uninstall () done test -n "$old_library" && func_append rmfiles " $odir/$old_library" - case "$opt_mode" in + case $opt_mode in clean) case " $library_names " in *" $dlname "*) ;; @@ -9522,12 +10802,12 @@ func_mode_uninstall () uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. - func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. - func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; @@ -9543,21 +10823,19 @@ func_mode_uninstall () func_source $dir/$name # Add PIC object to the list of files to remove. - if test -n "$pic_object" && - test "$pic_object" != none; then + if test -n "$pic_object" && test none != "$pic_object"; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. - if test -n "$non_pic_object" && - test "$non_pic_object" != none; then + if test -n "$non_pic_object" && test none != "$non_pic_object"; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) - if test "$opt_mode" = clean ; then + if test clean = "$opt_mode"; then noexename=$name case $file in *.exe) @@ -9584,12 +10862,12 @@ func_mode_uninstall () # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles - func_append rmfiles " $odir/$name $odir/${name}S.${objext}" - if test "$fast_install" = yes && test -n "$relink_command"; then + func_append rmfiles " $odir/$name $odir/${name}S.$objext" + if test yes = "$fast_install" && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi - if test "X$noexename" != "X$name" ; then - func_append rmfiles " $odir/lt-${noexename}.c" + if test "X$noexename" != "X$name"; then + func_append rmfiles " $odir/lt-$noexename.c" fi fi fi @@ -9598,7 +10876,7 @@ func_mode_uninstall () func_show_eval "$RM $rmfiles" 'exit_status=1' done - # Try to remove the ${objdir}s in the directories where we deleted files + # Try to remove the $objdir's in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" @@ -9608,16 +10886,17 @@ func_mode_uninstall () exit $exit_status } -{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && - func_mode_uninstall ${1+"$@"} +if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then + func_mode_uninstall ${1+"$@"} +fi test -z "$opt_mode" && { - help="$generic_help" + help=$generic_help func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ - func_fatal_help "invalid operation mode \`$opt_mode'" + func_fatal_help "invalid operation mode '$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" @@ -9628,7 +10907,7 @@ exit $exit_status # The TAGs below are defined such that we never get into a situation -# in which we disable both kinds of libraries. Given conflicting +# where we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support @@ -9651,5 +10930,3 @@ build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # mode:shell-script # sh-indentation:2 # End: -# vi:sw=2 - diff --git a/Modules/_ctypes/libffi/m4/ax_gcc_archflag.m4 b/Modules/_ctypes/libffi/m4/ax_gcc_archflag.m4 index 3fd050e7a95d..aab2661c3066 100644 --- a/Modules/_ctypes/libffi/m4/ax_gcc_archflag.m4 +++ b/Modules/_ctypes/libffi/m4/ax_gcc_archflag.m4 @@ -155,7 +155,7 @@ case $host_cpu in sparc*) AC_PATH_PROG([PRTDIAG], [prtdiag], [prtdiag], [$PATH:/usr/platform/`uname -i`/sbin/:/usr/platform/`uname -m`/sbin/]) cputype=`(((grep cpu /proc/cpuinfo | cut -d: -f2) ; ($PRTDIAG -v |grep -i sparc) ; grep -i cpu /var/run/dmesg.boot ) | head -n 1) 2> /dev/null` - cputype=`echo "$cputype" | tr -d ' -' |tr $as_cr_LETTERS $as_cr_letters` + cputype=`echo "$cputype" | tr -d ' -' | sed 's/SPARCIIi/SPARCII/' | tr $as_cr_LETTERS $as_cr_letters` case $cputype in *ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;; *ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;; diff --git a/Modules/_ctypes/libffi/m4/libtool.m4 b/Modules/_ctypes/libffi/m4/libtool.m4 index 3318f27a46b2..4bc6b22c80fc 100644 --- a/Modules/_ctypes/libffi/m4/libtool.m4 +++ b/Modules/_ctypes/libffi/m4/libtool.m4 @@ -1,8 +1,6 @@ # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1996-2001, 2003-2013 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives @@ -39,7 +37,7 @@ m4_define([_LT_COPYING], [dnl # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) -# serial 57 LT_INIT +# serial 58 LT_INIT # LT_PREREQ(VERSION) @@ -91,7 +89,7 @@ dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" +LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' @@ -130,7 +128,7 @@ cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set -# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} @@ -179,13 +177,13 @@ m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl _LT_CONFIG_LIBTOOL_INIT([ -# See if we are running on zsh, and set the options which allow our +# See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then +if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi ]) -if test -n "${ZSH_VERSION+set}" ; then +if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi @@ -198,7 +196,7 @@ aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then + if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi @@ -209,14 +207,14 @@ esac ofile=libtool can_build_shared=yes -# All known linkers require a `.a' archive for static linking (except MSVC, +# All known linkers require a '.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a -with_gnu_ld="$lt_cv_prog_gnu_ld" +with_gnu_ld=$lt_cv_prog_gnu_ld -old_CC="$CC" -old_CFLAGS="$CFLAGS" +old_CC=$CC +old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc @@ -269,14 +267,14 @@ no_glob_subst='s/\*/\\\*/g' # _LT_PROG_LTMAIN # --------------- -# Note that this code is called both from `configure', and `config.status' +# Note that this code is called both from 'configure', and 'config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, -# `config.status' has no value for ac_aux_dir unless we are using Automake, +# 'config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) -ltmain="$ac_aux_dir/ltmain.sh" +ltmain=$ac_aux_dir/ltmain.sh ])# _LT_PROG_LTMAIN @@ -286,7 +284,7 @@ ltmain="$ac_aux_dir/ltmain.sh" # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS -# in macros and then make a single call at the end using the `libtool' +# in macros and then make a single call at the end using the 'libtool' # label. @@ -421,8 +419,8 @@ m4_define([_lt_decl_all_varnames], # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ -# Quote a variable value, and forward it to `config.status' so that its -# declaration there will have the same value as in `configure'. VARNAME +# Quote a variable value, and forward it to 'config.status' so that its +# declaration there will have the same value as in 'configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) @@ -446,7 +444,7 @@ m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl -available_tags="_LT_TAGS"dnl +available_tags='_LT_TAGS'dnl ]) @@ -474,7 +472,7 @@ m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables -# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], @@ -500,8 +498,8 @@ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations -# into `config.status', and then the shell code to quote escape them in -# for loops in `config.status'. Finally, any additional code accumulated +# into 'config.status', and then the shell code to quote escape them in +# for loops in 'config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], @@ -547,7 +545,7 @@ for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" @@ -560,7 +558,7 @@ for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" @@ -576,7 +574,7 @@ _LT_OUTPUT_LIBTOOL_INIT # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the -# `#!' sequence but before initialization text begins. After this +# '#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). @@ -598,7 +596,7 @@ AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF -test $lt_write_fail = 0 && chmod +x $1[]dnl +test 0 = "$lt_write_fail" && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT @@ -621,7 +619,7 @@ exec AS_MESSAGE_LOG_FD>>config.log } >&AS_MESSAGE_LOG_FD lt_cl_help="\ -\`$as_me' creates a local libtool stub from the current configuration, +'$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. @@ -643,7 +641,7 @@ Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." -while test $[#] != 0 +while test 0 != $[#] do case $[1] in --version | --v* | -V ) @@ -656,10 +654,10 @@ do lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] -Try \`$[0] --help' for more information.]) ;; +Try '$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] -Try \`$[0] --help' for more information.]) ;; +Try '$[0] --help' for more information.]) ;; esac shift done @@ -685,7 +683,7 @@ chmod +x "$CONFIG_LT" # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: -test "$silent" = yes && +test yes = "$silent" && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false @@ -705,13 +703,13 @@ m4_defun([_LT_CONFIG], _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ - # See if we are running on zsh, and set the options which allow our + # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then + if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi - cfgfile="${ofile}T" + cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" @@ -719,7 +717,7 @@ _LT_CONFIG_SAVE_COMMANDS([ #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Generated automatically by $as_me ($PACKAGE) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # @@ -739,7 +737,7 @@ _LT_EOF # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then +if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi @@ -756,8 +754,6 @@ _LT_EOF sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) - _LT_PROG_REPLACE_SHELLFNS - mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" @@ -775,7 +771,6 @@ _LT_EOF [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS @@ -974,7 +969,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then + if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the @@ -992,7 +987,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. - elif test -f libconftest.dylib && test $_lt_result -eq 0; then + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD @@ -1010,7 +1005,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], @@ -1032,7 +1027,7 @@ _LT_EOF _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD - elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD @@ -1042,32 +1037,32 @@ _LT_EOF ]) case $host_os in rhapsody* | darwin1.[[012]]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then + if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi - if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= @@ -1087,29 +1082,29 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES], _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - if test "$lt_cv_ld_force_load" = "yes"; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + if test yes = "$lt_cv_ld_force_load"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; + ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac - if test "$_lt_dar_can_shared" = "yes"; then + if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all - _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], -[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then - _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" +[ if test yes != "$lt_cv_apple_cc_single_mod"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else @@ -1129,7 +1124,7 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES], # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl -if test "${lt_cv_aix_libpath+set}" = set; then +if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], @@ -1147,7 +1142,7 @@ else _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) @@ -1167,8 +1162,8 @@ m4_define([_LT_SHELL_INIT], # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start -# of the generated configure script which will find a shell with a builtin -# printf (which we can use as an echo command). +# of the generated configure script that will find a shell with a builtin +# printf (that we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO @@ -1196,10 +1191,10 @@ fi # Invoke $ECHO with all args, space-separated. func_echo_all () { - $ECHO "$*" + $ECHO "$*" } -case "$ECHO" in +case $ECHO in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; @@ -1225,16 +1220,17 @@ _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], -[ --with-sysroot[=DIR] Search for dependent libraries within DIR - (or the compiler's sysroot if not specified).], +[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], + [Search for dependent libraries within DIR (or the compiler's sysroot + if not specified).])], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= -case ${with_sysroot} in #( +case $with_sysroot in #( yes) - if test "$GCC" = yes; then + if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( @@ -1244,14 +1240,14 @@ case ${with_sysroot} in #( no|'') ;; #( *) - AC_MSG_RESULT([${with_sysroot}]) + AC_MSG_RESULT([$with_sysroot]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl -[dependent libraries, and in which our libraries should be installed.])]) +[dependent libraries, and where our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- @@ -1259,31 +1255,33 @@ m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes +test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) - HPUX_IA64_MODE="32" + HPUX_IA64_MODE=32 ;; *ELF-64*) - HPUX_IA64_MODE="64" + HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - if test "$lt_cv_prog_gnu_ld" = yes; then + if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" @@ -1312,9 +1310,46 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in @@ -1326,14 +1361,17 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) - LD="${LD-ld} -m elf32_x86_64" - ;; + LD="${LD-ld} -m elf32_x86_64" + ;; *) - LD="${LD-ld} -m elf_i386" - ;; + LD="${LD-ld} -m elf_i386" + ;; esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -1352,7 +1390,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - ppc*-*linux*|powerpc*-*linux*) + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -1370,19 +1411,20 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" + SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) - if test x"$lt_cv_cc_needs_belf" != x"yes"; then + if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" + CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in @@ -1390,7 +1432,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) case $lt_cv_prog_gnu_ld in yes*) case $host in - i?86-*-solaris*) + i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) @@ -1399,7 +1441,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then - LD="${LD-ld}_sol2" + LD=${LD-ld}_sol2 fi ;; *) @@ -1415,7 +1457,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac -need_locks="$enable_libtool_lock" +need_locks=$enable_libtool_lock ])# _LT_ENABLE_LOCK @@ -1434,11 +1476,11 @@ AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) - if test "$ac_status" -eq 0; then + if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) - if test "$ac_status" -ne 0; then + if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi @@ -1446,7 +1488,7 @@ AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], ]) ]) -if test "x$lt_cv_ar_at_file" = xno; then +if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file @@ -1477,7 +1519,7 @@ old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in - openbsd*) + bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) @@ -1513,7 +1555,7 @@ AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$3" + lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins @@ -1540,7 +1582,7 @@ AC_CACHE_CHECK([$1], [$2], $RM conftest* ]) -if test x"[$]$2" = xyes; then +if test yes = "[$]$2"; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) @@ -1562,7 +1604,7 @@ AC_DEFUN([_LT_LINKER_OPTION], m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no - save_LDFLAGS="$LDFLAGS" + save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then @@ -1581,10 +1623,10 @@ AC_CACHE_CHECK([$1], [$2], fi fi $RM -r conftest* - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS ]) -if test x"[$]$2" = xyes; then +if test yes = "[$]$2"; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) @@ -1605,7 +1647,7 @@ AC_DEFUN([LT_CMD_MAX_LEN], AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 - teststring="ABCD" + teststring=ABCD case $build_os in msdosdjgpp*) @@ -1645,7 +1687,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl lt_cv_sys_max_cmd_len=8192; ;; - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` @@ -1696,22 +1738,22 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ - test undefined != "$lt_cv_sys_max_cmd_len"; then + test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do + for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. - while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough + test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring @@ -1727,7 +1769,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl ;; esac ]) -if test -n $lt_cv_sys_max_cmd_len ; then +if test -n "$lt_cv_sys_max_cmd_len"; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) @@ -1755,7 +1797,7 @@ m4_defun([_LT_HEADER_DLFCN], # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl -if test "$cross_compiling" = yes; then : +if test yes = "$cross_compiling"; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 @@ -1804,7 +1846,7 @@ else /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif @@ -1830,7 +1872,7 @@ int main () return status; }] _LT_EOF - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in @@ -1851,7 +1893,7 @@ rm -fr conftest* # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl -if test "x$enable_dlopen" != xyes; then +if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown @@ -1861,44 +1903,52 @@ else case $host_os in beos*) - lt_cv_dlopen="load_add_on" + lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) - lt_cv_dlopen="dlopen" + lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) - # if libdl is installed we need to link against it + # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ - lt_cv_dlopen="dyld" + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ + lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + *) AC_CHECK_FUNC([shl_load], - [lt_cv_dlopen="shl_load"], + [lt_cv_dlopen=shl_load], [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], [AC_CHECK_FUNC([dlopen], - [lt_cv_dlopen="dlopen"], + [lt_cv_dlopen=dlopen], [AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], [AC_CHECK_LIB([svld], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ]) ]) ]) @@ -1907,21 +1957,21 @@ else ;; esac - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else + if test no = "$lt_cv_dlopen"; then enable_dlopen=no + else + enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - save_LDFLAGS="$LDFLAGS" + save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - save_LIBS="$LIBS" + save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], @@ -1931,7 +1981,7 @@ else lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) - if test "x$lt_cv_dlopen_self" = xyes; then + if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl @@ -1941,9 +1991,9 @@ else ]) fi - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS ;; esac @@ -2035,8 +2085,8 @@ m4_defun([_LT_COMPILER_FILE_LOCKS], m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) -hard_links="nottested" -if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then +hard_links=nottested +if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes @@ -2046,8 +2096,8 @@ if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) - if test "$hard_links" = no; then - AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + if test no = "$hard_links"; then + AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) need_locks=warn fi else @@ -2074,8 +2124,8 @@ objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl -AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", - [Define to the sub-directory in which libtool stores uninstalled libraries.]) +AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", + [Define to the sub-directory where libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR @@ -2087,15 +2137,15 @@ m4_defun([_LT_LINKER_HARDCODE_LIBPATH], _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || - test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then # We can hardcode non-existent directories. - if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && - test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && + test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else @@ -2109,12 +2159,12 @@ else fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) -if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || - test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then +if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || + test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then # Fast installation is not supported enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi @@ -2138,7 +2188,7 @@ else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) - if test -n "$STRIP" ; then + if test -n "$STRIP"; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) @@ -2169,14 +2219,14 @@ m4_require([_LT_CHECK_SHELL_FEATURES])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ -if test "$GCC" = yes; then +if test yes = "$GCC"; then case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in - mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; - *) lt_sed_strip_eq="s,=/,/,g" ;; + mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in @@ -2192,28 +2242,35 @@ if test "$GCC" = yes; then ;; esac # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary. + # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= - lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path/$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" - else + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; + lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } @@ -2227,7 +2284,7 @@ BEGIN {RS=" "; FS="/|\n";} { # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ - $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; + $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else @@ -2236,7 +2293,7 @@ fi]) library_names_spec= libname_spec='lib$name' soname_spec= -shrext_cmds=".so" +shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= @@ -2256,11 +2313,11 @@ need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' + soname_spec='$libname$release$shared_ext$major' ;; aix[[4-9]]*) @@ -2268,40 +2325,40 @@ aix[[4-9]]*) need_lib_prefix=no need_version=no hardcode_into_libs=yes - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then + if test yes = "$aix_use_runtimelinking"; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' fi shlibpath_var=LIBPATH fi @@ -2312,18 +2369,18 @@ amigaos*) powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) - library_names_spec='${libname}${shared_ext}' + library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; @@ -2331,8 +2388,8 @@ beos*) bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" @@ -2344,7 +2401,7 @@ bsdi[[45]]*) cygwin* | mingw* | pw32* | cegcc*) version_type=windows - shrext_cmds=".dll" + shrext_cmds=.dll need_version=no need_lib_prefix=no @@ -2353,8 +2410,8 @@ cygwin* | mingw* | pw32* | cegcc*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ @@ -2370,17 +2427,17 @@ cygwin* | mingw* | pw32* | cegcc*) case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' @@ -2389,8 +2446,8 @@ m4_if([$1], [],[ *,cl*) # Native MSVC libname_spec='$name' - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - library_names_spec='${libname}.dll.lib' + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' case $build_os in mingw*) @@ -2417,7 +2474,7 @@ m4_if([$1], [],[ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) - sys_lib_search_path_spec="$LIB" + sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` @@ -2430,8 +2487,8 @@ m4_if([$1], [],[ esac # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' @@ -2444,7 +2501,7 @@ m4_if([$1], [],[ *) # Assume MSVC wrapper - library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac @@ -2457,8 +2514,8 @@ darwin* | rhapsody*) version_type=darwin need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' @@ -2471,8 +2528,8 @@ dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; @@ -2490,12 +2547,12 @@ freebsd* | dragonfly*) version_type=freebsd-$objformat case $version_type in freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' need_version=no need_lib_prefix=no ;; freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac @@ -2520,26 +2577,15 @@ freebsd* | dragonfly*) esac ;; -gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=yes + shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; @@ -2557,9 +2603,9 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" @@ -2572,8 +2618,8 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; @@ -2582,8 +2628,8 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... @@ -2596,8 +2642,8 @@ interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no @@ -2608,7 +2654,7 @@ irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) - if test "$lt_cv_prog_gnu_ld" = yes; then + if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix @@ -2616,8 +2662,8 @@ irix5* | irix6* | nonstopux*) esac need_lib_prefix=no need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= @@ -2636,8 +2682,8 @@ irix5* | irix6* | nonstopux*) esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; @@ -2646,13 +2692,33 @@ linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + ;; + # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no @@ -2677,14 +2743,10 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu) # before this can be enabled. hardcode_into_libs=yes - # Add ABI-specific directories to the system library path. - sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" - # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" - + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on @@ -2701,12 +2763,12 @@ netbsd*) need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH @@ -2716,7 +2778,7 @@ netbsd*) newsos6) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; @@ -2725,45 +2787,34 @@ newsos6) version_type=qnx need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; -openbsd*) +openbsd* | bitrig*) version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" + sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[[89]] | openbsd2.[[89]].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no else - shlibpath_overrides_runpath=yes + need_version=yes fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' - shrext_cmds=".dll" + shrext_cmds=.dll need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' + library_names_spec='$libname$shared_ext $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; @@ -2772,11 +2823,11 @@ osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) @@ -2787,8 +2838,8 @@ solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes @@ -2798,11 +2849,11 @@ solaris*) sunos4*) version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes @@ -2810,8 +2861,8 @@ sunos4*) sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) @@ -2832,10 +2883,10 @@ sysv4 | sysv4.3*) ;; sysv4*MP*) - if test -d /usr/nec ;then + if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; @@ -2844,12 +2895,12 @@ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' @@ -2867,7 +2918,7 @@ tpf*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes @@ -2875,8 +2926,8 @@ tpf*) uts4*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; @@ -2885,18 +2936,18 @@ uts4*) ;; esac AC_MSG_RESULT([$dynamic_linker]) -test "$dynamic_linker" = no && can_build_shared=no +test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then +if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi _LT_DECL([], [variables_saved_for_relink], [1], @@ -2938,32 +2989,32 @@ _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- -# find a file program which can recognize shared library +# find a file program that can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$1; then - lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -f "$ac_dir/$1"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : @@ -2986,11 +3037,11 @@ _LT_EOF break fi done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac]) -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else @@ -3008,7 +3059,7 @@ dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- -# find a file program which can recognize a shared library +# find a file program that can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then @@ -3035,16 +3086,16 @@ m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], - [test "$withval" = no || with_gnu_ld=yes], + [test no = "$withval" || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld -if test "$GCC" = yes; then +if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw + # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; @@ -3058,7 +3109,7 @@ if test "$GCC" = yes; then while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done - test -z "$LD" && LD="$ac_prog" + test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. @@ -3069,37 +3120,37 @@ if test "$GCC" = yes; then with_gnu_ld=unknown ;; esac -elif test "$with_gnu_ld" = yes; then +elif test yes = "$with_gnu_ld"; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" + lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 /dev/null 2>&1; then + if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else @@ -3255,10 +3305,6 @@ freebsd* | dragonfly*) fi ;; -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - haiku*) lt_cv_deplibs_check_method=pass_all ;; @@ -3297,7 +3343,7 @@ irix5* | irix6* | nonstopux*) ;; # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; @@ -3319,8 +3365,8 @@ newos6*) lt_cv_deplibs_check_method=pass_all ;; -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' @@ -3413,33 +3459,33 @@ AC_DEFUN([LT_PATH_NM], AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. - lt_cv_path_NM="$NM" + lt_cv_path_NM=$NM else - lt_nm_to_check="${ac_tool_prefix}nm" + lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" - break + break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" - break + break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but @@ -3450,21 +3496,21 @@ else esac fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi]) -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) - case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) - DUMPBIN="$DUMPBIN -symbols" + DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: @@ -3472,8 +3518,8 @@ else esac fi AC_SUBST([DUMPBIN]) - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" + if test : != "$DUMPBIN"; then + NM=$DUMPBIN fi fi test -z "$NM" && NM=nm @@ -3519,8 +3565,8 @@ lt_cv_sharedlib_from_linklib_cmd, case $host_os in cygwin* | mingw* | pw32* | cegcc*) - # two different shell functions defined in ltmain.sh - # decide which to use based on capabilities of $DLLTOOL + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib @@ -3532,7 +3578,7 @@ cygwin* | mingw* | pw32* | cegcc*) ;; *) # fallback: assume linklib IS sharedlib - lt_cv_sharedlib_from_linklib_cmd="$ECHO" + lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac ]) @@ -3559,13 +3605,28 @@ AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) -if test "x$lt_cv_path_mainfest_tool" != xyes; then +if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL +# _LT_DLL_DEF_P([FILE]) +# --------------------- +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with func_dll_def_p in the libtool script +AC_DEFUN([_LT_DLL_DEF_P], +[dnl + test DEF = "`$SED -n dnl + -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace + -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments + -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl + -e q dnl Only consider the first "real" line + $1`" dnl +])# _LT_DLL_DEF_P + + # LT_LIB_M # -------- # check for math library @@ -3577,11 +3638,11 @@ case $host in # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) - AC_CHECK_LIB(m, cos, LIBM="-lm") + AC_CHECK_LIB(m, cos, LIBM=-lm) ;; esac AC_SUBST([LIBM]) @@ -3600,7 +3661,7 @@ m4_defun([_LT_COMPILER_NO_RTTI], _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= -if test "$GCC" = yes; then +if test yes = "$GCC"; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; @@ -3652,7 +3713,7 @@ cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then symcode='[[ABCDEGRST]]' fi ;; @@ -3685,14 +3746,44 @@ case `$NM -V 2>&1` in symcode='[[ABCDGIRSTW]]' ;; esac +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= @@ -3710,21 +3801,24 @@ for ac_symprfx in "" "_"; do # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" @@ -3764,11 +3858,11 @@ _LT_EOF if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST -#elif defined(__osf__) +#elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else @@ -3794,7 +3888,7 @@ lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; @@ -3814,9 +3908,9 @@ _LT_EOF mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS - LIBS="conftstm.$ac_objext" + LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS @@ -3837,7 +3931,7 @@ _LT_EOF rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then + if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= @@ -3864,12 +3958,16 @@ _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], + [Transform the output of nm into a list of symbols to manually relocate]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([nm_interface], [lt_cv_nm_interface], [1], + [The name lister interface]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS @@ -3885,17 +3983,18 @@ _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then + if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) @@ -3906,8 +4005,8 @@ m4_if([$1], [CXX], [ ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac @@ -3972,7 +4071,7 @@ m4_if([$1], [CXX], [ case $host_os in aix[[4-9]]*) # All AIX code is PIC. - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else @@ -4013,14 +4112,14 @@ m4_if([$1], [CXX], [ case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default @@ -4049,7 +4148,7 @@ m4_if([$1], [CXX], [ ;; esac ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler @@ -4057,7 +4156,7 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) - # old Intel C++ for x86_64 which still supported -KPIC. + # old Intel C++ for x86_64, which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' @@ -4202,17 +4301,18 @@ m4_if([$1], [CXX], [ fi ], [ - if test "$GCC" = yes; then + if test yes = "$GCC"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) @@ -4223,8 +4323,8 @@ m4_if([$1], [CXX], [ ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac @@ -4311,7 +4411,7 @@ m4_if([$1], [CXX], [ case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else @@ -4319,6 +4419,20 @@ m4_if([$1], [CXX], [ fi ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). @@ -4339,7 +4453,7 @@ m4_if([$1], [CXX], [ ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) @@ -4348,9 +4462,9 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. + # old Intel for x86_64, which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' @@ -4375,6 +4489,12 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) @@ -4472,7 +4592,7 @@ m4_if([$1], [CXX], [ ;; sysv4*MP*) - if test -d /usr/nec ;then + if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi @@ -4501,7 +4621,7 @@ m4_if([$1], [CXX], [ fi ]) case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: + # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; @@ -4577,7 +4697,7 @@ m4_if([$1], [CXX], [ fi ;; pw32*) - _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in @@ -4623,9 +4743,9 @@ m4_if([$1], [CXX], [ # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if @@ -4641,7 +4761,7 @@ dnl Note also adjust exclude_expsyms for C++ above. # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. - if test "$GCC" != yes; then + if test yes != "$GCC"; then with_gnu_ld=no fi ;; @@ -4649,7 +4769,7 @@ dnl Note also adjust exclude_expsyms for C++ above. # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; - openbsd*) + openbsd* | bitrig*) with_gnu_ld=no ;; esac @@ -4659,7 +4779,7 @@ dnl Note also adjust exclude_expsyms for C++ above. # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility @@ -4681,24 +4801,24 @@ dnl Note also adjust exclude_expsyms for C++ above. esac fi - if test "$lt_use_gnu_ld_interface" = yes; then + if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' + wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no - case `$LD -v 2>&1` in + case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... @@ -4711,7 +4831,7 @@ dnl Note also adjust exclude_expsyms for C++ above. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then + if test ia64 != "$host_cpu"; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 @@ -4730,7 +4850,7 @@ _LT_EOF case $host_cpu in powerpc) # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) @@ -4746,7 +4866,7 @@ _LT_EOF _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -4756,7 +4876,7 @@ _LT_EOF # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes @@ -4764,61 +4884,61 @@ _LT_EOF _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no - if test "$host_os" = linux-dietlibc; then + if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no + && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; @@ -4829,42 +4949,44 @@ _LT_EOF lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac - _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then + if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then + if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac @@ -4878,8 +5000,8 @@ _LT_EOF _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; @@ -4897,8 +5019,8 @@ _LT_EOF _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -4910,7 +5032,7 @@ _LT_EOF _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify @@ -4925,9 +5047,9 @@ _LT_EOF # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -4944,15 +5066,15 @@ _LT_EOF *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac - if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= @@ -4968,7 +5090,7 @@ _LT_EOF # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported @@ -4976,12 +5098,12 @@ _LT_EOF ;; aix[[4-9]]*) - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' - no_entry_flag="" + no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm @@ -4999,7 +5121,7 @@ _LT_EOF # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi @@ -5022,13 +5144,13 @@ _LT_EOF _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' - if test "$GCC" = yes; then + if test yes = "$GCC"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` + collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then @@ -5047,61 +5169,61 @@ _LT_EOF ;; esac shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' fi else # not using gcc - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' else - shared_flag='${wl}-bM:SRE' + shared_flag='$wl-bM:SRE' fi fi fi - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then + if test yes = "$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $wl-bnoentry $compiler_flags $wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; @@ -5110,7 +5232,7 @@ _LT_EOF case $host_cpu in powerpc) # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) @@ -5140,16 +5262,17 @@ _LT_EOF # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" + shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes @@ -5158,18 +5281,18 @@ _LT_EOF # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' ;; *) # Assume MSVC wrapper @@ -5178,7 +5301,7 @@ _LT_EOF # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" + shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. @@ -5228,33 +5351,33 @@ _LT_EOF ;; hpux9*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; hpux10*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + if test yes,no = "$GCC,$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes @@ -5262,25 +5385,25 @@ _LT_EOF ;; hpux11*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then + if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ @@ -5288,14 +5411,14 @@ _LT_EOF # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in @@ -5306,7 +5429,7 @@ _LT_EOF *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. @@ -5317,16 +5440,16 @@ _LT_EOF ;; irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], - [save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + [save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], @@ -5339,16 +5462,16 @@ _LT_EOF end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) - LDFLAGS="$save_LDFLAGS"]) - if test "$lt_cv_irix_exported_symbol" = yes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + LDFLAGS=$save_LDFLAGS]) + if test yes = "$lt_cv_irix_exported_symbol"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes @@ -5368,7 +5491,7 @@ _LT_EOF newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; @@ -5376,27 +5499,19 @@ _LT_EOF *nto* | *qnx*) ;; - openbsd*) + openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' else - case $host_os in - openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - ;; - esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' fi else _LT_TAGVAR(ld_shlibs, $1)=no @@ -5412,28 +5527,28 @@ _LT_EOF ;; osf3*) - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' @@ -5444,24 +5559,24 @@ _LT_EOF solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' - _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi @@ -5471,11 +5586,11 @@ _LT_EOF solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', + # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + if test yes = "$GCC"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi @@ -5485,10 +5600,10 @@ _LT_EOF ;; sunos4*) - if test "x$host_vendor" = xsequent; then + if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi @@ -5537,43 +5652,43 @@ _LT_EOF ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not + # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; @@ -5588,17 +5703,17 @@ _LT_EOF ;; esac - if test x$host_vendor = xsni; then + if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) -test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no +test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld @@ -5615,7 +5730,7 @@ x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - if test "$enable_shared" = yes && test "$GCC" = yes; then + if test yes,yes = "$GCC,$enable_shared"; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. @@ -5695,12 +5810,12 @@ _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary and the resulting library dependency is - "absolute", i.e impossible to change by setting ${shlibpath_var} if the + "absolute", i.e impossible to change by setting $shlibpath_var if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR @@ -5741,10 +5856,10 @@ dnl [Compiler flag to generate thread safe objects]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. +# the compiler configuration to 'libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl -lt_save_CC="$CC" +lt_save_CC=$CC AC_LANG_PUSH(C) # Source file extension for C test sources. @@ -5784,18 +5899,18 @@ if test -n "$compiler"; then LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB - # Report which library types will actually be built + # Report what library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no + test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) - test "$enable_shared" = yes && enable_static=no + test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' @@ -5803,8 +5918,8 @@ if test -n "$compiler"; then ;; aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no + if test ia64 != "$host_cpu" && test no = "$aix_use_runtimelinking"; then + test yes = "$enable_shared" && enable_static=no fi ;; esac @@ -5812,13 +5927,13 @@ if test -n "$compiler"; then AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes + test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP -CC="$lt_save_CC" +CC=$lt_save_CC ])# _LT_LANG_C_CONFIG @@ -5826,14 +5941,14 @@ CC="$lt_save_CC" # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. +# the compiler configuration to 'libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl -if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then +if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes @@ -5875,7 +5990,7 @@ _LT_TAGVAR(objext, $1)=$objext # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_caught_CXX_error" != yes; then +if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" @@ -5917,35 +6032,35 @@ if test "$_lt_caught_CXX_error" != yes; then if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately - if test "$GXX" = yes; then + if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi - if test "$GXX" = yes; then + if test yes = "$GXX"; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + if test yes = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) - wlarc='${wl}' + wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi @@ -5981,12 +6096,12 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' - no_entry_flag="" + no_entry_flag= else aix_use_runtimelinking=no @@ -6020,13 +6135,13 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' - if test "$GXX" = yes; then + if test yes = "$GXX"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` + collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then @@ -6044,56 +6159,56 @@ if test "$_lt_caught_CXX_error" != yes; then fi esac shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' fi else # not using gcc - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' else - shared_flag='${wl}-bM:SRE' + shared_flag='$wl-bM:SRE' fi fi fi - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then + if test yes = "$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' @@ -6101,7 +6216,7 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $wl-bnoentry $compiler_flags $wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; @@ -6111,7 +6226,7 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -6139,57 +6254,58 @@ if test "$_lt_caught_CXX_error" != yes; then # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" + shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - func_to_tool_file "$lt_outputfile"~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -6234,18 +6350,15 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(ld_shlibs, $1)=yes ;; - gnu*) - ;; - haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default @@ -6257,7 +6370,7 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. @@ -6266,11 +6379,11 @@ if test "$_lt_caught_CXX_error" != yes; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) - if test "$GXX" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + if test yes = "$GXX"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no @@ -6280,15 +6393,15 @@ if test "$_lt_caught_CXX_error" != yes; then ;; hpux10*|hpux11*) - if test $with_gnu_ld = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; esac fi @@ -6314,13 +6427,13 @@ if test "$_lt_caught_CXX_error" != yes; then aCC*) case $host_cpu in hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists @@ -6331,20 +6444,20 @@ if test "$_lt_caught_CXX_error" != yes; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi @@ -6359,22 +6472,22 @@ if test "$_lt_caught_CXX_error" != yes; then interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is @@ -6383,22 +6496,22 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler @@ -6406,8 +6519,8 @@ if test "$_lt_caught_CXX_error" != yes; then # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. @@ -6416,10 +6529,10 @@ if test "$_lt_caught_CXX_error" != yes; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. @@ -6433,59 +6546,59 @@ if test "$_lt_caught_CXX_error" != yes; then # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac - _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ - compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ - $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ - $RANLIB $oldlib' + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' @@ -6499,18 +6612,18 @@ if test "$_lt_caught_CXX_error" != yes; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) @@ -6518,10 +6631,10 @@ if test "$_lt_caught_CXX_error" != yes; then *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on @@ -6579,22 +6692,17 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(ld_shlibs, $1)=yes ;; - openbsd2*) - # C++ shared libraries are fairly broken - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - openbsd*) + openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else @@ -6610,9 +6718,9 @@ if test "$_lt_caught_CXX_error" != yes; then # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using @@ -6630,17 +6738,17 @@ if test "$_lt_caught_CXX_error" != yes; then cxx*) case $host in osf3*) - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ - $RM $lib.exp' + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac @@ -6655,21 +6763,21 @@ if test "$_lt_caught_CXX_error" != yes; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' case $host in osf3*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists @@ -6715,9 +6823,9 @@ if test "$_lt_caught_CXX_error" != yes; then # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no @@ -6725,7 +6833,7 @@ if test "$_lt_caught_CXX_error" != yes; then solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. + # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; @@ -6742,30 +6850,30 @@ if test "$_lt_caught_CXX_error" != yes; then ;; gcx*) # Green Hills C++ Compiler - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else - # g++ 2.7 appears to require `-G' NOT `-shared' on this + # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. - _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when @@ -6773,11 +6881,11 @@ if test "$_lt_caught_CXX_error" != yes; then output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi @@ -6786,52 +6894,52 @@ if test "$_lt_caught_CXX_error" != yes; then ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not + # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ - '"$_LT_TAGVAR(old_archive_cmds, $1)" + '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ - '"$_LT_TAGVAR(reload_cmds, $1)" + '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; @@ -6862,10 +6970,10 @@ if test "$_lt_caught_CXX_error" != yes; then esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) - test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no - _LT_TAGVAR(GCC, $1)="$GXX" - _LT_TAGVAR(LD, $1)="$LD" + _LT_TAGVAR(GCC, $1)=$GXX + _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change @@ -6892,7 +7000,7 @@ if test "$_lt_caught_CXX_error" != yes; then lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -fi # test "$_lt_caught_CXX_error" != yes +fi # test yes != "$_lt_caught_CXX_error" AC_LANG_POP ])# _LT_LANG_CXX_CONFIG @@ -6914,9 +7022,9 @@ AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + case @S|@2 in + .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; + *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF @@ -7004,13 +7112,13 @@ if AC_TRY_EVAL(ac_compile); then pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do - case ${prev}${p} in + case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. - if test $p = "-L" || - test $p = "-R"; then + if test x-L = "$p" || + test x-R = "$p"; then prev=$p continue fi @@ -7026,16 +7134,16 @@ if AC_TRY_EVAL(ac_compile); then case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac - if test "$pre_test_object_deps_done" = no; then - case ${prev} in + if test no = "$pre_test_object_deps_done"; then + case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then - _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p else - _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" fi ;; # The "-l" case would never come before the object being @@ -7043,9 +7151,9 @@ if AC_TRY_EVAL(ac_compile); then esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then - _LT_TAGVAR(postdeps, $1)="${prev}${p}" + _LT_TAGVAR(postdeps, $1)=$prev$p else - _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" fi fi prev= @@ -7060,15 +7168,15 @@ if AC_TRY_EVAL(ac_compile); then continue fi - if test "$pre_test_object_deps_done" = no; then + if test no = "$pre_test_object_deps_done"; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then - _LT_TAGVAR(predep_objects, $1)="$p" + _LT_TAGVAR(predep_objects, $1)=$p else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then - _LT_TAGVAR(postdep_objects, $1)="$p" + _LT_TAGVAR(postdep_objects, $1)=$p else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi @@ -7115,7 +7223,7 @@ linux*) ;; esac - if test "$solaris_use_stlport4" != yes; then + if test yes != "$solaris_use_stlport4"; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; @@ -7138,7 +7246,7 @@ solaris*) # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. - if test "$solaris_use_stlport4" != yes; then + if test yes != "$solaris_use_stlport4"; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; @@ -7152,7 +7260,7 @@ case " $_LT_TAGVAR(postdeps, $1) " in esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then - _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) @@ -7172,10 +7280,10 @@ _LT_TAGDECL([], [compiler_lib_search_path], [1], # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. +# to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) -if test -z "$F77" || test "X$F77" = "Xno"; then +if test -z "$F77" || test no = "$F77"; then _lt_disable_F77=yes fi @@ -7212,7 +7320,7 @@ _LT_TAGVAR(objext, $1)=$objext # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_F77" != yes; then +if test yes != "$_lt_disable_F77"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t @@ -7234,7 +7342,7 @@ if test "$_lt_disable_F77" != yes; then _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. - lt_save_CC="$CC" + lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} @@ -7248,21 +7356,21 @@ if test "$_lt_disable_F77" != yes; then AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no + test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) - test "$enable_shared" = yes && enable_static=no + test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no + if test ia64 != "$host_cpu" && test no = "$aix_use_runtimelinking"; then + test yes = "$enable_shared" && enable_static=no fi ;; esac @@ -7270,11 +7378,11 @@ if test "$_lt_disable_F77" != yes; then AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes + test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) - _LT_TAGVAR(GCC, $1)="$G77" - _LT_TAGVAR(LD, $1)="$LD" + _LT_TAGVAR(GCC, $1)=$G77 + _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change @@ -7291,9 +7399,9 @@ if test "$_lt_disable_F77" != yes; then fi # test -n "$compiler" GCC=$lt_save_GCC - CC="$lt_save_CC" - CFLAGS="$lt_save_CFLAGS" -fi # test "$_lt_disable_F77" != yes + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_F77" AC_LANG_POP ])# _LT_LANG_F77_CONFIG @@ -7303,11 +7411,11 @@ AC_LANG_POP # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. +# to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) -if test -z "$FC" || test "X$FC" = "Xno"; then +if test -z "$FC" || test no = "$FC"; then _lt_disable_FC=yes fi @@ -7344,7 +7452,7 @@ _LT_TAGVAR(objext, $1)=$objext # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_FC" != yes; then +if test yes != "$_lt_disable_FC"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t @@ -7366,7 +7474,7 @@ if test "$_lt_disable_FC" != yes; then _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. - lt_save_CC="$CC" + lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} @@ -7382,21 +7490,21 @@ if test "$_lt_disable_FC" != yes; then AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no + test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) - test "$enable_shared" = yes && enable_static=no + test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no + if test ia64 != "$host_cpu" && test no = "$aix_use_runtimelinking"; then + test yes = "$enable_shared" && enable_static=no fi ;; esac @@ -7404,11 +7512,11 @@ if test "$_lt_disable_FC" != yes; then AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes + test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) - _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" - _LT_TAGVAR(LD, $1)="$LD" + _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu + _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change @@ -7428,7 +7536,7 @@ if test "$_lt_disable_FC" != yes; then GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS -fi # test "$_lt_disable_FC" != yes +fi # test yes != "$_lt_disable_FC" AC_LANG_POP ])# _LT_LANG_FC_CONFIG @@ -7438,7 +7546,7 @@ AC_LANG_POP # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. +# to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE @@ -7472,7 +7580,7 @@ CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" +_LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. @@ -7509,7 +7617,7 @@ CFLAGS=$lt_save_CFLAGS # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. +# to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE @@ -7543,7 +7651,7 @@ CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" +_LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. @@ -7580,7 +7688,7 @@ CFLAGS=$lt_save_CFLAGS # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. +# to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE @@ -7596,7 +7704,7 @@ _LT_TAGVAR(objext, $1)=$objext lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests -lt_simple_link_test_code="$lt_simple_compile_test_code" +lt_simple_link_test_code=$lt_simple_compile_test_code # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER @@ -7606,7 +7714,7 @@ _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. -lt_save_CC="$CC" +lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= @@ -7635,7 +7743,7 @@ AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) - test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) @@ -7746,7 +7854,7 @@ lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f $lt_ac_sed && continue + test ! -f "$lt_ac_sed" && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in @@ -7763,9 +7871,9 @@ for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough - test $lt_ac_count -gt 10 && break + test 10 -lt "$lt_ac_count" && break lt_ac_count=`expr $lt_ac_count + 1` - if test $lt_ac_count -gt $lt_ac_max; then + if test "$lt_ac_count" -gt "$lt_ac_max"; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi @@ -7789,27 +7897,7 @@ dnl AC_DEFUN([LT_AC_PROG_SED], []) # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], -[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,b/c, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -AC_MSG_RESULT([$xsi_shell]) -_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) - -AC_MSG_CHECKING([whether the shell understands "+="]) -lt_shell_append=no -( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -AC_MSG_RESULT([$lt_shell_append]) -_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then +[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false @@ -7833,102 +7921,9 @@ _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES -# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) -# ------------------------------------------------------ -# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and -# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. -m4_defun([_LT_PROG_FUNCTION_REPLACE], -[dnl { -sed -e '/^$1 ()$/,/^} # $1 /c\ -$1 ()\ -{\ -m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) -} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: -]) - - -# _LT_PROG_REPLACE_SHELLFNS -# ------------------------- -# Replace existing portable implementations of several shell functions with -# equivalent extended shell implementations where those features are available.. -m4_defun([_LT_PROG_REPLACE_SHELLFNS], -[if test x"$xsi_shell" = xyes; then - _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac]) - - _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl - func_basename_result="${1##*/}"]) - - _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac - func_basename_result="${1##*/}"]) - - _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl - # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are - # positional parameters, so assign one to ordinary parameter first. - func_stripname_result=${3} - func_stripname_result=${func_stripname_result#"${1}"} - func_stripname_result=${func_stripname_result%"${2}"}]) - - _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl - func_split_long_opt_name=${1%%=*} - func_split_long_opt_arg=${1#*=}]) - - _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl - func_split_short_opt_arg=${1#??} - func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) - - _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl - case ${1} in - *.lo) func_lo2o_result=${1%.lo}.${objext} ;; - *) func_lo2o_result=${1} ;; - esac]) - - _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) - - _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) - - _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) -fi - -if test x"$lt_shell_append" = xyes; then - _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) - - _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl - func_quote_for_eval "${2}" -dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ - eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) - - # Save a `func_append' function call where possible by direct use of '+=' - sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -else - # Save a `func_append' function call even when '+=' is not available - sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -fi - -if test x"$_lt_function_replace_fail" = x":"; then - AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) -fi -]) - # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- -# Determine which file name conversion functions should be used by +# Determine what file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], diff --git a/Modules/_ctypes/libffi/m4/ltoptions.m4 b/Modules/_ctypes/libffi/m4/ltoptions.m4 index 5d9acd8e23bc..50c77236c688 100644 --- a/Modules/_ctypes/libffi/m4/ltoptions.m4 +++ b/Modules/_ctypes/libffi/m4/ltoptions.m4 @@ -1,14 +1,14 @@ # Helper functions for option handling. -*- Autoconf -*- # -# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 2004-2005, 2007-2009, 2011-2013 Free Software +# Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. -# serial 7 ltoptions.m4 +# serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) @@ -29,7 +29,7 @@ m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), - [m4_warning([Unknown $1 option `$2'])])[]dnl + [m4_warning([Unknown $1 option '$2'])])[]dnl ]) @@ -75,13 +75,13 @@ m4_if([$1],[LT_INIT],[ dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither - dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], - [_LT_ENABLE_FAST_INSTALL]) + [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS @@ -112,7 +112,7 @@ AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `dlopen' option into LT_INIT's first parameter.]) +put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: @@ -148,7 +148,7 @@ AU_DEFUN([AC_LIBTOOL_WIN32_DLL], _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `win32-dll' option into LT_INIT's first parameter.]) +put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: @@ -157,9 +157,9 @@ dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- -# implement the --enable-shared flag, and supports the `shared' and -# `disable-shared' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +# implement the --enable-shared flag, and supports the 'shared' and +# 'disable-shared' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], @@ -172,14 +172,14 @@ AC_ARG_ENABLE([shared], *) enable_shared=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) @@ -211,9 +211,9 @@ dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- -# implement the --enable-static flag, and support the `static' and -# `disable-static' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +# implement the --enable-static flag, and support the 'static' and +# 'disable-static' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], @@ -226,14 +226,14 @@ AC_ARG_ENABLE([static], *) enable_static=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) @@ -265,9 +265,9 @@ dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- -# implement the --enable-fast-install flag, and support the `fast-install' -# and `disable-fast-install' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +# implement the --enable-fast-install flag, and support the 'fast-install' +# and 'disable-fast-install' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], @@ -280,14 +280,14 @@ AC_ARG_ENABLE([fast-install], *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) @@ -304,14 +304,14 @@ AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `fast-install' option into LT_INIT's first parameter.]) +the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `disable-fast-install' option into LT_INIT's first parameter.]) +the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: @@ -321,9 +321,9 @@ dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- -# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. -# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], @@ -334,19 +334,17 @@ m4_define([_LT_WITH_PIC], *) pic_mode=default # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac], - [pic_mode=default]) - -test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC @@ -359,7 +357,7 @@ AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `pic-only' option into LT_INIT's first parameter.]) +put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: diff --git a/Modules/_ctypes/libffi/m4/ltsugar.m4 b/Modules/_ctypes/libffi/m4/ltsugar.m4 index 9000a057d31d..7cbc638b699a 100644 --- a/Modules/_ctypes/libffi/m4/ltsugar.m4 +++ b/Modules/_ctypes/libffi/m4/ltsugar.m4 @@ -1,6 +1,7 @@ # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # -# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Copyright (C) 2004-2005, 2007-2008, 2011-2013 Free Software +# Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives @@ -33,7 +34,7 @@ m4_define([_lt_join], # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support -# Autoconf-2.59 which quotes differently. +# Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], @@ -44,7 +45,7 @@ m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ -# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different diff --git a/Modules/_ctypes/libffi/m4/ltversion.m4 b/Modules/_ctypes/libffi/m4/ltversion.m4 index 07a8602d48d6..daeb0af7af79 100644 --- a/Modules/_ctypes/libffi/m4/ltversion.m4 +++ b/Modules/_ctypes/libffi/m4/ltversion.m4 @@ -1,6 +1,6 @@ # ltversion.m4 -- version numbers -*- Autoconf -*- # -# Copyright (C) 2004 Free Software Foundation, Inc. +# Copyright (C) 2004, 2011-2013 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives @@ -9,15 +9,15 @@ # @configure_input@ -# serial 3337 ltversion.m4 +# serial 4038 ltversion.m4 # This file is part of GNU Libtool -m4_define([LT_PACKAGE_VERSION], [2.4.2]) -m4_define([LT_PACKAGE_REVISION], [1.3337]) +m4_define([LT_PACKAGE_VERSION], [2.4.2.418]) +m4_define([LT_PACKAGE_REVISION], [2.4.2.418]) AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.4.2' -macro_revision='1.3337' +[macro_version='2.4.2.418' +macro_revision='2.4.2.418' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) diff --git a/Modules/_ctypes/libffi/m4/lt~obsolete.m4 b/Modules/_ctypes/libffi/m4/lt~obsolete.m4 index c573da90c5cc..59461e458cc9 100644 --- a/Modules/_ctypes/libffi/m4/lt~obsolete.m4 +++ b/Modules/_ctypes/libffi/m4/lt~obsolete.m4 @@ -1,6 +1,7 @@ # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # -# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Copyright (C) 2004-2005, 2007, 2009, 2011-2013 Free Software +# Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives @@ -11,7 +12,7 @@ # These exist entirely to fool aclocal when bootstrapping libtool. # -# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # @@ -25,7 +26,7 @@ # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. -# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until diff --git a/Modules/_ctypes/libffi/man/Makefile.in b/Modules/_ctypes/libffi/man/Makefile.in index c02e1f26a206..d92af74fb692 100644 --- a/Modules/_ctypes/libffi/man/Makefile.in +++ b/Modules/_ctypes/libffi/man/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.12.2 from Makefile.am. +# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2012 Free Software Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -14,23 +14,51 @@ @SET_MAKE@ VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ - test $$am__dry = yes; \ - } + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -51,7 +79,7 @@ build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = man -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \ $(top_srcdir)/m4/ax_append_flag.m4 \ @@ -73,6 +101,18 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/fficonfig.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ @@ -111,10 +151,12 @@ man3dir = $(mandir)/man3 am__installdirs = "$(DESTDIR)$(man3dir)" NROFF = nroff MANS = $(man_MANS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LTLDFLAGS = @AM_LTLDFLAGS@ AM_RUNTESTFLAGS = @AM_RUNTESTFLAGS@ AR = @AR@ @@ -130,6 +172,10 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ @@ -145,6 +191,7 @@ FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@ +HAVE_LONG_DOUBLE_VARIANT = @HAVE_LONG_DOUBLE_VARIANT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -191,6 +238,7 @@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ @@ -330,29 +378,14 @@ uninstall-man3: } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) -tags: TAGS -TAGS: +tags TAGS: -ctags: CTAGS -CTAGS: +ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) - @list='$(MANS)'; if test -n "$$list"; then \ - list=`for p in $$list; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ - if test -n "$$list" && \ - grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ - echo "error: found man pages containing the 'missing help2man' replacement text:" >&2; \ - grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ - echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ - echo " typically 'make maintainer-clean' will remove them" >&2; \ - exit 1; \ - else :; fi; \ - else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -490,16 +523,17 @@ uninstall-man: uninstall-man3 .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ - distclean distclean-generic distclean-libtool distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-man3 \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - uninstall uninstall-am uninstall-man uninstall-man3 + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-man3 install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags-am uninstall uninstall-am uninstall-man \ + uninstall-man3 # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/Modules/_ctypes/libffi/mdate-sh b/Modules/_ctypes/libffi/mdate-sh index cd916c0a3400..b3719cf76191 100755 --- a/Modules/_ctypes/libffi/mdate-sh +++ b/Modules/_ctypes/libffi/mdate-sh @@ -1,10 +1,9 @@ #!/bin/sh # Get modification time of a file or directory and pretty-print it. -scriptversion=2005-06-29.22 +scriptversion=2010-08-21.06; # UTC -# Copyright (C) 1995, 1996, 1997, 2003, 2004, 2005 Free Software -# Foundation, Inc. +# Copyright (C) 1995-2013 Free Software Foundation, Inc. # written by Ulrich Drepper , June 1995 # # This program is free software; you can redistribute it and/or modify @@ -18,8 +17,7 @@ scriptversion=2005-06-29.22 # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -30,16 +28,26 @@ scriptversion=2005-06-29.22 # bugs to or send patches to # . +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +fi + case $1 in '') - echo "$0: No file. Try \`$0 --help' for more information." 1>&2 + echo "$0: No file. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: mdate-sh [--help] [--version] FILE -Pretty-print the modification time of FILE. +Pretty-print the modification day of FILE, in the format: +1 January 1970 Report bugs to . EOF @@ -51,6 +59,13 @@ EOF ;; esac +error () +{ + echo "$0: $1" >&2 + exit 1 +} + + # Prevent date giving response in another language. LANG=C export LANG @@ -60,7 +75,7 @@ LC_TIME=C export LC_TIME # GNU ls changes its time format in response to the TIME_STYLE -# variable. Since we cannot assume `unset' works, revert this +# variable. Since we cannot assume 'unset' works, revert this # variable to its documented default. if test "${TIME_STYLE+set}" = set; then TIME_STYLE=posix-long-iso @@ -75,27 +90,32 @@ if ls -L /dev/null 1>/dev/null 2>&1; then else ls_command='ls -l -d' fi +# Avoid user/group names that might have spaces, when possible. +if ls -n /dev/null 1>/dev/null 2>&1; then + ls_command="$ls_command -n" +fi -# A `ls -l' line looks as follows on OS/2. +# A 'ls -l' line looks as follows on OS/2. # drwxrwx--- 0 Aug 11 2001 foo # This differs from Unix, which adds ownership information. # drwxrwx--- 2 root root 4096 Aug 11 2001 foo # # To find the date, we split the line on spaces and iterate on words # until we find a month. This cannot work with files whose owner is a -# user named `Jan', or `Feb', etc. However, it's unlikely that `/' +# user named "Jan", or "Feb", etc. However, it's unlikely that '/' # will be owned by a user whose name is a month. So we first look at # the extended ls output of the root directory to decide how many # words should be skipped to get the date. # On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below. -set x`ls -l -d /` +set x`$ls_command /` # Find which argument is the month. month= command= until test $month do + test $# -gt 0 || error "failed parsing '$ls_command /' output" shift # Add another shift to the command. command="$command shift;" @@ -115,8 +135,10 @@ do esac done +test -n "$month" || error "failed parsing '$ls_command /' output" + # Get the extended ls output of the file or directory. -set dummy x`eval "$ls_command \"\$save_arg1\""` +set dummy x`eval "$ls_command \"\\\$save_arg1\""` # Remove all preceding arguments eval $command @@ -197,5 +219,6 @@ echo $day $month $year # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" # End: diff --git a/Modules/_ctypes/libffi/missing b/Modules/_ctypes/libffi/missing index 28055d2ae6f2..cdea514931f5 100755 --- a/Modules/_ctypes/libffi/missing +++ b/Modules/_ctypes/libffi/missing @@ -1,11 +1,10 @@ #! /bin/sh -# Common stub for a few missing GNU programs while installing. +# Common wrapper for a few potentially missing GNU programs. -scriptversion=2009-04-28.21; # UTC +scriptversion=2012-06-26.16; # UTC -# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, -# 2008, 2009 Free Software Foundation, Inc. -# Originally by Fran,cois Pinard , 1996. +# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -26,69 +25,40 @@ scriptversion=2009-04-28.21; # UTC # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" + echo 1>&2 "Try '$0 --help' for more information" exit 1 fi -run=: -sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' -sed_minuso='s/.* -o \([^ ]*\).*/\1/p' - -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.ac; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi +case $1 in -msg="missing on your system" + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; -case $1 in ---run) - # Try to run requested program, and just exit if it succeeds. - run= - shift - "$@" && exit 0 - # Exit code 63 means version mismatch. This often happens - # when the user try to use an ancient version of a tool on - # a file that requires a minimum version. In this case we - # we should proceed has if the program had been absent, or - # if --run hadn't been passed. - if test $? = 63; then - run=: - msg="probably too old" - fi - ;; + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit - --run try to run the given command, and emulate it if it fails Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - autom4te touch the output file, or create a stub one - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - help2man touch the output file - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - tar try tar, gnutar, gtar, then tar without non-portable flags - yacc create \`y.tab.[ch]', if possible, from existing .[ch] + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man -Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and -\`g' are ignored when checking the name. +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. Send bug reports to ." exit $? @@ -100,272 +70,141 @@ Send bug reports to ." ;; -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac -# normalize program name to check for. -program=`echo "$1" | sed ' - s/^gnu-//; t - s/^gnu//; t - s/^g//; t'` - -# Now exit if we have it, but it failed. Also exit now if we -# don't have it and --version was passed (most likely to detect -# the program). This is about non-GNU programs, so use $1 not -# $program. -case $1 in - lex*|yacc*) - # Not GNU programs, they don't have --version. - ;; - - tar*) - if test -n "$run"; then - echo 1>&2 "ERROR: \`tar' requires --run" - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - exit 1 - fi - ;; - - *) - if test -z "$run" && ($1 --version) > /dev/null 2>&1; then - # We have it, but it failed. - exit 1 - elif test "x$2" = "x--version" || test "x$2" = "x--help"; then - # Could not run --version or --help. This is probably someone - # running `$TOOL --version' or `$TOOL --help' to check whether - # $TOOL exists and not knowing $TOOL uses missing. - exit 1 - fi - ;; -esac - -# If it does not exist, or fails to run (possibly an outdated version), -# try to emulate it. -case $program in - aclocal*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acinclude.m4' or \`${configure_ac}'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`${configure_ac}'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`acconfig.h' or \`${configure_ac}'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case $f in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - autom4te*) - echo 1>&2 "\ -WARNING: \`$1' is needed, but is $msg. - You might have modified some files without having the - proper tools for further handling them. - You can get \`$1' as part of \`Autoconf' from any GNU - archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo "#! /bin/sh" - echo "# Created by GNU Automake missing as a replacement of" - echo "# $ $@" - echo "exit 0" - chmod +x $file - exit 1 - fi - ;; - - bison*|yacc*) - echo 1>&2 "\ -WARNING: \`$1' $msg. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if test $# -ne 1; then - eval LASTARG="\${$#}" - case $LASTARG in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if test ! -f y.tab.h; then - echo >y.tab.h - fi - if test ! -f y.tab.c; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex*|flex*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if test $# -ne 1; then - eval LASTARG="\${$#}" - case $LASTARG in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if test -f "$SRCFILE"; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if test ! -f lex.yy.c; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - help2man*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a dependency of a manual page. You may need the - \`Help2man' package in order for those modifications to take - effect. You can get \`Help2man' from any GNU archive site." - - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -f "$file"; then - touch $file - else - test -z "$file" || exec >$file - echo ".ab help2man is required to generate this page" - exit $? - fi - ;; - - makeinfo*) - echo 1>&2 "\ -WARNING: \`$1' is $msg. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - # The file to touch is that specified with -o ... - file=`echo "$*" | sed -n "$sed_output"` - test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` - if test -z "$file"; then - # ... or it is the one specified with @setfilename ... - infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n ' - /^@setfilename/{ - s/.* \([^ ]*\) *$/\1/ - p - q - }' $infile` - # ... or it is derived from the source name (dir/f.texi becomes f.info) - test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info - fi - # If the file does not exist, the user really needs makeinfo; - # let's fail without touching anything. - test -f $file || exit 1 - touch $file - ;; - - tar*) - shift - - # We have already tried tar in the generic part. - # Look for gnutar/gtar before invocation to avoid ugly error - # messages. - if (gnutar --version > /dev/null 2>&1); then - gnutar "$@" && exit 0 - fi - if (gtar --version > /dev/null 2>&1); then - gtar "$@" && exit 0 - fi - firstarg="$1" - if shift; then - case $firstarg in - *o*) - firstarg=`echo "$firstarg" | sed s/o//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - case $firstarg in - *h*) - firstarg=`echo "$firstarg" | sed s/h//` - tar "$firstarg" "$@" && exit 0 - ;; - esac - fi - - echo 1>&2 "\ -WARNING: I can't seem to be able to run \`tar' with the given arguments. - You may want to install GNU tar or Free paxutils, or check the - command line arguments." - exit 1 - ;; - - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and is $msg. - You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequisites for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 - ;; -esac +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi -exit 0 +perl_URL=http://www.perl.org/ +flex_URL=http://flex.sourceforge.net/ +gnu_software_URL=http://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'automa4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) diff --git a/Modules/_ctypes/libffi/msvcc.sh b/Modules/_ctypes/libffi/msvcc.sh old mode 100644 new mode 100755 index dcdbeab16aea..7440deb34036 --- a/Modules/_ctypes/libffi/msvcc.sh +++ b/Modules/_ctypes/libffi/msvcc.sh @@ -42,6 +42,7 @@ # format and translated into something sensible for cl or ml. # +args_orig=$@ args="-nologo -W3" md=-MD cl="cl" @@ -72,14 +73,35 @@ do shift 1 ;; -O*) - # If we're optimizing, make sure we explicitly turn on some optimizations - # that are implicitly disabled by debug symbols (-Zi). - args="$args $1 -OPT:REF -OPT:ICF -INCREMENTAL:NO" + # Runtime error checks (enabled by setting -RTC1 in the -DFFI_DEBUG + # case below) are not compatible with optimization flags and will + # cause the build to fail. Therefore, drop the optimization flag if + # -DFFI_DEBUG is also set. + case $args_orig in + *-DFFI_DEBUG*) + args="$args" + ;; + *) + # The ax_cc_maxopt.m4 macro from the upstream autoconf-archive + # project doesn't support MSVC and therefore ends up trying to + # use -O3. Use the equivalent "max optimization" flag for MSVC + # instead of erroring out. + case $1 in + -O3) + args="$args -O2" + ;; + *) + args="$args $1" + ;; + esac + opt="true" + ;; + esac shift 1 ;; -g) # Enable debug symbol generation. - args="$args -Zi -DEBUG" + args="$args -Zi" shift 1 ;; -DFFI_DEBUG) @@ -126,6 +148,10 @@ do # to do here. shift 1 ;; + -pedantic) + # libffi tests -pedantic with -Wall, so drop it also. + shift 1 + ;; -Werror) args="$args -WX" shift 1 @@ -170,6 +196,13 @@ do esac done +# If -Zi is specified, certain optimizations are implicitly disabled +# by MSVC. Add back those optimizations if this is an optimized build. +# NOTE: These arguments must come after all others. +if [ -n "$opt" ]; then + args="$args -link -OPT:REF -OPT:ICF -INCREMENTAL:NO" +fi + if [ -n "$assembly" ]; then if [ -z "$outdir" ]; then outdir="." @@ -189,7 +222,10 @@ if [ -n "$assembly" ]; then else args="$md $args" echo "$cl $args" - eval "\"$cl\" $args" + # Return an error code of 1 if an invalid command line parameter is passed + # instead of just ignoring it. + eval "(\"$cl\" $args 2>&1 1>&3 | \ + awk '{print \$0} /D9002/ {error=1} END{exit error}' >&2) 3>&1" result=$? fi diff --git a/Modules/_ctypes/libffi/src/aarch64/ffi.c b/Modules/_ctypes/libffi/src/aarch64/ffi.c index 140566569511..b807a2d3813e 100644 --- a/Modules/_ctypes/libffi/src/aarch64/ffi.c +++ b/Modules/_ctypes/libffi/src/aarch64/ffi.c @@ -27,7 +27,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include /* Stack alignment requirement in bytes */ +#if defined (__APPLE__) +#define AARCH64_STACK_ALIGN 1 +#else #define AARCH64_STACK_ALIGN 16 +#endif #define N_X_ARG_REG 8 #define N_V_ARG_REG 8 @@ -49,6 +53,23 @@ struct call_context } v [AARCH64_N_VREG]; }; +#if defined (__clang__) && defined (__APPLE__) +extern void +sys_icache_invalidate (void *start, size_t len); +#endif + +static inline void +ffi_clear_cache (void *start, void *end) +{ +#if defined (__clang__) && defined (__APPLE__) + sys_icache_invalidate (start, (char *)end - (char *)start); +#elif defined (__GNUC__) + __builtin___clear_cache (start, end); +#else +#error "Missing builtin to flush instruction cache" +#endif +} + static void * get_x_addr (struct call_context *context, unsigned n) { @@ -94,8 +115,10 @@ get_basic_type_addr (unsigned short type, struct call_context *context, return get_s_addr (context, n); case FFI_TYPE_DOUBLE: return get_d_addr (context, n); +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: return get_v_addr (context, n); +#endif case FFI_TYPE_UINT8: case FFI_TYPE_SINT8: case FFI_TYPE_UINT16: @@ -107,6 +130,8 @@ get_basic_type_addr (unsigned short type, struct call_context *context, case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: return get_x_addr (context, n); + case FFI_TYPE_VOID: + return NULL; default: FFI_ASSERT (0); return NULL; @@ -123,15 +148,26 @@ get_basic_type_alignment (unsigned short type) case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: return sizeof (UINT64); +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: return sizeof (long double); +#endif case FFI_TYPE_UINT8: case FFI_TYPE_SINT8: +#if defined (__APPLE__) + return sizeof (UINT8); +#endif case FFI_TYPE_UINT16: case FFI_TYPE_SINT16: +#if defined (__APPLE__) + return sizeof (UINT16); +#endif case FFI_TYPE_UINT32: case FFI_TYPE_INT: case FFI_TYPE_SINT32: +#if defined (__APPLE__) + return sizeof (UINT32); +#endif case FFI_TYPE_POINTER: case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: @@ -154,8 +190,10 @@ get_basic_type_size (unsigned short type) return sizeof (UINT32); case FFI_TYPE_DOUBLE: return sizeof (UINT64); +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: return sizeof (long double); +#endif case FFI_TYPE_UINT8: return sizeof (UINT8); case FFI_TYPE_SINT8: @@ -186,7 +224,7 @@ ffi_call_SYSV (unsigned (*)(struct call_context *context, unsigned char *, extended_cif *), struct call_context *context, extended_cif *, - unsigned, + size_t, void (*fn)(void)); extern void @@ -305,7 +343,9 @@ is_register_candidate (ffi_type *ty) case FFI_TYPE_VOID: case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: +#endif case FFI_TYPE_UINT8: case FFI_TYPE_UINT16: case FFI_TYPE_UINT32: @@ -367,16 +407,24 @@ struct arg_state { unsigned ngrn; /* Next general-purpose register number. */ unsigned nsrn; /* Next vector register number. */ - unsigned nsaa; /* Next stack offset. */ + size_t nsaa; /* Next stack offset. */ + +#if defined (__APPLE__) + unsigned allocating_variadic; +#endif }; /* Initialize a procedure call argument marshalling state. */ static void -arg_init (struct arg_state *state, unsigned call_frame_size) +arg_init (struct arg_state *state, size_t call_frame_size) { state->ngrn = 0; state->nsrn = 0; state->nsaa = 0; + +#if defined (__APPLE__) + state->allocating_variadic = 0; +#endif } /* Return the number of available consecutive core argument @@ -400,35 +448,35 @@ available_v (struct arg_state *state) static void * allocate_to_x (struct call_context *context, struct arg_state *state) { - FFI_ASSERT (state->ngrn < N_X_ARG_REG) + FFI_ASSERT (state->ngrn < N_X_ARG_REG); return get_x_addr (context, (state->ngrn)++); } static void * allocate_to_s (struct call_context *context, struct arg_state *state) { - FFI_ASSERT (state->nsrn < N_V_ARG_REG) + FFI_ASSERT (state->nsrn < N_V_ARG_REG); return get_s_addr (context, (state->nsrn)++); } static void * allocate_to_d (struct call_context *context, struct arg_state *state) { - FFI_ASSERT (state->nsrn < N_V_ARG_REG) + FFI_ASSERT (state->nsrn < N_V_ARG_REG); return get_d_addr (context, (state->nsrn)++); } static void * allocate_to_v (struct call_context *context, struct arg_state *state) { - FFI_ASSERT (state->nsrn < N_V_ARG_REG) + FFI_ASSERT (state->nsrn < N_V_ARG_REG); return get_v_addr (context, (state->nsrn)++); } /* Allocate an aligned slot on the stack and return a pointer to it. */ static void * -allocate_to_stack (struct arg_state *state, void *stack, unsigned alignment, - unsigned size) +allocate_to_stack (struct arg_state *state, void *stack, size_t alignment, + size_t size) { void *allocation; @@ -436,7 +484,12 @@ allocate_to_stack (struct arg_state *state, void *stack, unsigned alignment, alignment of the argument's type. */ state->nsaa = ALIGN (state->nsaa, alignment); state->nsaa = ALIGN (state->nsaa, alignment); +#if defined (__APPLE__) + if (state->allocating_variadic) + state->nsaa = ALIGN (state->nsaa, 8); +#else state->nsaa = ALIGN (state->nsaa, 8); +#endif allocation = stack + state->nsaa; @@ -447,7 +500,7 @@ allocate_to_stack (struct arg_state *state, void *stack, unsigned alignment, static void copy_basic_type (void *dest, void *source, unsigned short type) { - /* This is neccessary to ensure that basic types are copied + /* This is necessary to ensure that basic types are copied sign extended to 64-bits as libffi expects. */ switch (type) { @@ -457,9 +510,11 @@ copy_basic_type (void *dest, void *source, unsigned short type) case FFI_TYPE_DOUBLE: *(double *) dest = *(double *) source; break; +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: *(long double *) dest = *(long double *) source; break; +#endif case FFI_TYPE_UINT8: *(ffi_arg *) dest = *(UINT8 *) source; break; @@ -486,6 +541,8 @@ copy_basic_type (void *dest, void *source, unsigned short type) case FFI_TYPE_SINT64: *(ffi_sarg *) dest = *(SINT64 *) source; break; + case FFI_TYPE_VOID: + break; default: FFI_ASSERT (0); @@ -514,7 +571,6 @@ copy_hfa_to_reg_or_stack (void *memory, { int i; unsigned short type = get_homogeneous_type (ty); - unsigned elems = element_count (ty); for (i = 0; i < elems; i++) { void *reg = allocate_to_v (context, state); @@ -548,11 +604,13 @@ allocate_to_register_or_stack (struct call_context *context, return allocate_to_d (context, state); state->nsrn = N_V_ARG_REG; break; +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: if (state->nsrn < N_V_ARG_REG) return allocate_to_v (context, state); state->nsrn = N_V_ARG_REG; break; +#endif case FFI_TYPE_UINT8: case FFI_TYPE_SINT8: case FFI_TYPE_UINT16: @@ -615,7 +673,9 @@ aarch64_prep_args (struct call_context *context, unsigned char *stack, appropriate register, or if none are available, to the stack. */ case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: +#endif case FFI_TYPE_UINT8: case FFI_TYPE_SINT8: case FFI_TYPE_UINT16: @@ -676,6 +736,16 @@ aarch64_prep_args (struct call_context *context, unsigned char *stack, FFI_ASSERT (0); break; } + +#if defined (__APPLE__) + if (i + 1 == ecif->cif->aarch64_nfixedargs) + { + state.ngrn = N_X_ARG_REG; + state.nsrn = N_V_ARG_REG; + + state.allocating_variadic = 1; + } +#endif } return ecif->cif->aarch64_flags; @@ -712,6 +782,20 @@ ffi_prep_cif_machdep (ffi_cif *cif) return FFI_OK; } +#if defined (__APPLE__) + +/* Perform Apple-specific cif processing for variadic calls */ +ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif, + unsigned int nfixedargs, + unsigned int ntotalargs) +{ + cif->aarch64_nfixedargs = nfixedargs; + + return ffi_prep_cif_machdep(cif); +} + +#endif + /* Call a function with the provided arguments and capture the return value. */ void @@ -728,7 +812,7 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) case FFI_SYSV: { struct call_context context; - unsigned stack_bytes; + size_t stack_bytes; /* Figure out the total amount of stack space we need, the above call frame space needs to be 16 bytes aligned to @@ -745,7 +829,9 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) case FFI_TYPE_VOID: case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: +#endif case FFI_TYPE_UINT8: case FFI_TYPE_SINT8: case FFI_TYPE_UINT16: @@ -778,7 +864,7 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) } else if ((cif->rtype->size + 7) / 8 < N_X_ARG_REG) { - unsigned size = ALIGN (cif->rtype->size, sizeof (UINT64)); + size_t size = ALIGN (cif->rtype->size, sizeof (UINT64)); memcpy (rvalue, get_x_addr (&context, 0), size); } else @@ -824,7 +910,7 @@ static unsigned char trampoline [] = memcpy (__tramp + 12, &__fun, sizeof (__fun)); \ memcpy (__tramp + 20, &__ctx, sizeof (__ctx)); \ memcpy (__tramp + 28, &__flags, sizeof (__flags)); \ - __clear_cache(__tramp, __tramp + FFI_TRAMPOLINE_SIZE); \ + ffi_clear_cache(__tramp, __tramp + FFI_TRAMPOLINE_SIZE); \ }) ffi_status @@ -857,13 +943,13 @@ ffi_prep_closure_loc (ffi_closure* closure, the stack at the point ffi_closure_SYSV() was invoked. On the return path the assembler wrapper will reload call context - regsiters. + registers. ffi_closure_SYSV_inner() marshalls the call context into ffi value - desriptors, invokes the wrapped function, then marshalls the return + descriptors, invokes the wrapped function, then marshalls the return value back into the call context. */ -void +void FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, void *stack) { @@ -897,10 +983,12 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, case FFI_TYPE_SINT64: case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: avalue[i] = allocate_to_register_or_stack (context, stack, &state, ty->type); break; +#endif case FFI_TYPE_STRUCT: if (is_hfa (ty)) @@ -924,7 +1012,7 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, therefore the structure is not represented as a contiguous sequence of bytes in our saved register context. We need to fake up a copy - of the structure layed out in memory + of the structure laid out in memory correctly. The fake can be tossed once the closure function has returned hence alloca() is sufficient. */ @@ -945,7 +1033,7 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, therefore the structure is not represented as a contiguous sequence of bytes in our saved register context. We need to fake up a copy - of the structure layed out in memory + of the structure laid out in memory correctly. The fake can be tossed once the closure function has returned hence alloca() is sufficient. */ @@ -958,11 +1046,13 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, break; } +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: memcpy (&avalue[i], allocate_to_v (context, &state), sizeof (*avalue)); break; +#endif default: FFI_ASSERT (0); @@ -1033,7 +1123,9 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, case FFI_TYPE_SINT64: case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: +#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE case FFI_TYPE_LONGDOUBLE: +#endif { void *addr = get_basic_type_addr (cif->rtype->type, context, 0); copy_basic_type (addr, rvalue, cif->rtype->type); @@ -1042,19 +1134,19 @@ ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context, case FFI_TYPE_STRUCT: if (is_hfa (cif->rtype)) { - int i; + int j; unsigned short type = get_homogeneous_type (cif->rtype); unsigned elems = element_count (cif->rtype); - for (i = 0; i < elems; i++) + for (j = 0; j < elems; j++) { - void *reg = get_basic_type_addr (type, context, i); + void *reg = get_basic_type_addr (type, context, j); copy_basic_type (reg, rvalue, type); rvalue += get_basic_type_size (type); } } else if ((cif->rtype->size + 7) / 8 < N_X_ARG_REG) { - unsigned size = ALIGN (cif->rtype->size, sizeof (UINT64)) ; + size_t size = ALIGN (cif->rtype->size, sizeof (UINT64)) ; memcpy (get_x_addr (context, 0), rvalue, size); } else diff --git a/Modules/_ctypes/libffi/src/aarch64/ffitarget.h b/Modules/_ctypes/libffi/src/aarch64/ffitarget.h index 6f1a348f5322..4bbced26f005 100644 --- a/Modules/_ctypes/libffi/src/aarch64/ffitarget.h +++ b/Modules/_ctypes/libffi/src/aarch64/ffitarget.h @@ -47,8 +47,12 @@ typedef enum ffi_abi /* ---- Internal ---- */ - +#if defined (__APPLE__) +#define FFI_TARGET_SPECIFIC_VARIADIC +#define FFI_EXTRA_CIF_FIELDS unsigned aarch64_flags; unsigned aarch64_nfixedargs +#else #define FFI_EXTRA_CIF_FIELDS unsigned aarch64_flags +#endif #define AARCH64_FFI_WITH_V_BIT 0 diff --git a/Modules/_ctypes/libffi/src/aarch64/sysv.S b/Modules/_ctypes/libffi/src/aarch64/sysv.S index b8cd421a8a5c..169eab804e17 100644 --- a/Modules/_ctypes/libffi/src/aarch64/sysv.S +++ b/Modules/_ctypes/libffi/src/aarch64/sysv.S @@ -23,14 +23,33 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include +#ifdef HAVE_MACHINE_ASM_H +#include +#else +#ifdef __USER_LABEL_PREFIX__ +#define CONCAT1(a, b) CONCAT2(a, b) +#define CONCAT2(a, b) a ## b + +/* Use the right prefix for global labels. */ +#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x) +#else +#define CNAME(x) x +#endif +#endif + #define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off #define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off #define cfi_restore(reg) .cfi_restore reg #define cfi_def_cfa_register(reg) .cfi_def_cfa_register reg .text - .globl ffi_call_SYSV - .type ffi_call_SYSV, #function + .globl CNAME(ffi_call_SYSV) +#ifdef __ELF__ + .type CNAME(ffi_call_SYSV), #function +#endif +#ifdef __APPLE__ + .align 2 +#endif /* ffi_call_SYSV() @@ -53,7 +72,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ extended_cif *), struct call_context *context, extended_cif *, - unsigned required_stack_size, + size_t required_stack_size, void (*fn)(void)); Therefore on entry we have: @@ -82,7 +101,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define ffi_call_SYSV_FS (8 * 4) .cfi_startproc -ffi_call_SYSV: +CNAME(ffi_call_SYSV): stp x29, x30, [sp, #-16]! cfi_adjust_cfa_offset (16) cfi_rel_offset (x29, 0) @@ -92,11 +111,11 @@ ffi_call_SYSV: cfi_def_cfa_register (x29) sub sp, sp, #ffi_call_SYSV_FS - stp x21, x22, [sp, 0] + stp x21, x22, [sp, #0] cfi_rel_offset (x21, 0 - ffi_call_SYSV_FS) cfi_rel_offset (x22, 8 - ffi_call_SYSV_FS) - stp x23, x24, [sp, 16] + stp x23, x24, [sp, #16] cfi_rel_offset (x23, 16 - ffi_call_SYSV_FS) cfi_rel_offset (x24, 24 - ffi_call_SYSV_FS) @@ -180,7 +199,9 @@ ffi_call_SYSV: ret .cfi_endproc - .size ffi_call_SYSV, .-ffi_call_SYSV +#ifdef __ELF__ + .size CNAME(ffi_call_SYSV), .-CNAME(ffi_call_SYSV) +#endif #define ffi_closure_SYSV_FS (8 * 2 + AARCH64_CALL_CONTEXT_SIZE) @@ -222,22 +243,25 @@ ffi_call_SYSV: Voila! */ .text - .globl ffi_closure_SYSV + .globl CNAME(ffi_closure_SYSV) +#ifdef __APPLE__ + .align 2 +#endif .cfi_startproc -ffi_closure_SYSV: +CNAME(ffi_closure_SYSV): stp x29, x30, [sp, #-16]! cfi_adjust_cfa_offset (16) cfi_rel_offset (x29, 0) cfi_rel_offset (x30, 8) mov x29, sp + cfi_def_cfa_register (x29) sub sp, sp, #ffi_closure_SYSV_FS - cfi_adjust_cfa_offset (ffi_closure_SYSV_FS) stp x21, x22, [x29, #-16] - cfi_rel_offset (x21, 0) - cfi_rel_offset (x22, 8) + cfi_rel_offset (x21, -16) + cfi_rel_offset (x22, -8) /* Load x21 with &call_context. */ mov x21, sp @@ -270,7 +294,7 @@ ffi_closure_SYSV: trampoline was called. */ add x2, x29, #16 - bl ffi_closure_SYSV_inner + bl CNAME(ffi_closure_SYSV_inner) /* Figure out if we should touch the vector registers. */ ldr x0, [x22, #8] @@ -287,7 +311,7 @@ ffi_closure_SYSV: ldp x2, x3, [x21, #16] ldp x4, x5, [x21, #32] ldp x6, x7, [x21, #48] - /* Note nothing usefull is returned in x8. */ + /* Note nothing useful is returned in x8. */ /* We are done, unwind our frame. */ ldp x21, x22, [x29, #-16] @@ -295,7 +319,7 @@ ffi_closure_SYSV: cfi_restore (x22) mov sp, x29 - cfi_adjust_cfa_offset (-ffi_closure_SYSV_FS) + cfi_def_cfa_register (sp) ldp x29, x30, [sp], #16 cfi_adjust_cfa_offset (-16) @@ -304,4 +328,6 @@ ffi_closure_SYSV: ret .cfi_endproc - .size ffi_closure_SYSV, .-ffi_closure_SYSV +#ifdef __ELF__ + .size CNAME(ffi_closure_SYSV), .-CNAME(ffi_closure_SYSV) +#endif diff --git a/Modules/_ctypes/libffi/src/arc/arcompact.S b/Modules/_ctypes/libffi/src/arc/arcompact.S new file mode 100644 index 000000000000..03715fde49f7 --- /dev/null +++ b/Modules/_ctypes/libffi/src/arc/arcompact.S @@ -0,0 +1,135 @@ +/* ----------------------------------------------------------------------- + arcompact.S - Copyright (c) 2013 Synposys, Inc. (www.synopsys.com) + + ARCompact 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 RENESAS TECHNOLOGY 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 +#ifdef HAVE_MACHINE_ASM_H +#include +#else +#define CNAME(x) x +#define ENTRY(x) .globl CNAME(x)` .type CNAME(x),%function` CNAME(x): +#endif + +.text + + /* R0: ffi_prep_args */ + /* R1: &ecif */ + /* R2: cif->bytes */ + /* R3: fig->flags */ + /* R4: ecif.rvalue */ + /* R5: fn */ +ENTRY(ffi_call_ARCompact) + /* Save registers. */ + st.a fp, [sp, -4] /* fp + 20, fp */ + push_s blink /* fp + 16, blink */ + st.a r4, [sp, -4] /* fp + 12, ecif.rvalue */ + push_s r3 /* fp + 8, fig->flags */ + st.a r5, [sp, -4] /* fp + 4, fn */ + push_s r2 /* fp + 0, cif->bytes */ + mov fp, sp + + /* Make room for all of the new args. */ + sub sp, sp, r2 + + /* Place all of the ffi_prep_args in position. */ + /* ffi_prep_args(char *stack, extended_cif *ecif) */ + /* R1 already set. */ + + /* And call. */ + jl_s.d [r0] + mov_s r0, sp + + ld.ab r12, [fp, 4] /* cif->bytes */ + ld.ab r11, [fp, 4] /* fn */ + + /* Move first 8 parameters in registers... */ + ld_s r0, [sp] + ld_s r1, [sp, 4] + ld_s r2, [sp, 8] + ld_s r3, [sp, 12] + ld r4, [sp, 16] + ld r5, [sp, 20] + ld r6, [sp, 24] + ld r7, [sp, 28] + + /* ...and adjust the stack. */ + min r12, r12, 32 + + /* Call the function. */ + jl.d [r11] + add sp, sp, r12 + + mov sp, fp + pop_s r3 /* fig->flags, return type */ + pop_s r2 /* ecif.rvalue, pointer for return value */ + + /* If the return value pointer is NULL, assume no return value. */ + breq.d r2, 0, epilogue + pop_s blink + + /* Return INT. */ + brne r3, FFI_TYPE_INT, return_double + b.d epilogue + st_s r0, [r2] + +return_double: + brne r3, FFI_TYPE_DOUBLE, epilogue + st_s r0, [r2] + st_s r1, [r2,4] + +epilogue: + j_s.d [blink] + ld.ab fp, [sp, 4] + +ENTRY(ffi_closure_ARCompact) + st.a r0, [sp, -32] + st_s r1, [sp, 4] + st_s r2, [sp, 8] + st_s r3, [sp, 12] + st r4, [sp, 16] + st r5, [sp, 20] + st r6, [sp, 24] + st r7, [sp, 28] + + /* pointer to arguments */ + mov_s r2, sp + + /* return value goes here */ + sub sp, sp, 8 + mov_s r1, sp + + push_s blink + + bl.d ffi_closure_inner_ARCompact + mov_s r0, r8 /* codeloc, set by trampoline */ + + pop_s blink + + /* set return value to r1:r0 */ + pop_s r0 + pop_s r1 + j_s.d [blink] + add_s sp, sp, 32 diff --git a/Modules/_ctypes/libffi/src/arc/ffi.c b/Modules/_ctypes/libffi/src/arc/ffi.c new file mode 100644 index 000000000000..32f82a7d5bb5 --- /dev/null +++ b/Modules/_ctypes/libffi/src/arc/ffi.c @@ -0,0 +1,268 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2013 Synopsys, Inc. (www.synopsys.com) + + ARC 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 RENESAS TECHNOLOGY 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 + +/* for little endian ARC, the code is in fact stored as mixed endian for + performance reasons */ +#if __BIG_ENDIAN__ +#define CODE_ENDIAN(x) (x) +#else +#define CODE_ENDIAN(x) ( (((uint32_t) (x)) << 16) | (((uint32_t) (x)) >> 16)) +#endif + +/* 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) +{ + unsigned int i; + int tmp; + void **p_argv; + char *argp; + ffi_type **p_arg; + + tmp = 0; + argp = stack; + + if (ecif->cif->rtype->type == 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; + int alignment; + + /* align alignment to 4 */ + alignment = (((*p_arg)->alignment - 1) | 3) + 1; + + /* Align if necessary. */ + if ((alignment - 1) & (unsigned) argp) + argp = (char *) ALIGN (argp, alignment); + + 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_STRUCT: + memcpy (argp, *p_argv, (*p_arg)->size); + break; + + default: + FFI_ASSERT (0); + } + } + else if (z == sizeof (int)) + { + *(unsigned int *) argp = (unsigned int) *(UINT32 *) (*p_argv); + } + else + { + if ((*p_arg)->type == FFI_TYPE_STRUCT) + { + memcpy (argp, *p_argv, z); + } + else + { + /* Double or long long 64bit. */ + 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: + cif->flags = (unsigned) cif->rtype->type; + break; + + case FFI_TYPE_STRUCT: + cif->flags = (unsigned) cif->rtype->type; + break; + + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + case FFI_TYPE_DOUBLE: + cif->flags = FFI_TYPE_DOUBLE; + break; + + case FFI_TYPE_FLOAT: + default: + cif->flags = FFI_TYPE_INT; + break; + } + + return FFI_OK; +} + +extern void ffi_call_ARCompact (void (*)(char *, extended_cif *), + extended_cif *, unsigned, unsigned, + unsigned *, void (*fn) (void)); + +void +ffi_call (ffi_cif * cif, void (*fn) (void), 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->rtype->type == FFI_TYPE_STRUCT)) + { + ecif.rvalue = alloca (cif->rtype->size); + } + else + ecif.rvalue = rvalue; + + switch (cif->abi) + { + case FFI_ARCOMPACT: + ffi_call_ARCompact (ffi_prep_args, &ecif, cif->bytes, + cif->flags, ecif.rvalue, fn); + break; + + default: + FFI_ASSERT (0); + break; + } +} + +int +ffi_closure_inner_ARCompact (ffi_closure * closure, void *rvalue, + ffi_arg * args) +{ + void **arg_area, **p_argv; + ffi_cif *cif = closure->cif; + char *argp = (char *) args; + ffi_type **p_argt; + int i; + + arg_area = (void **) alloca (cif->nargs * sizeof (void *)); + + /* handle hidden argument */ + if (cif->flags == FFI_TYPE_STRUCT) + { + rvalue = *(void **) argp; + argp += 4; + } + + p_argv = arg_area; + + for (i = 0, p_argt = cif->arg_types; i < cif->nargs; + i++, p_argt++, p_argv++) + { + size_t z; + int alignment; + + /* align alignment to 4 */ + alignment = (((*p_argt)->alignment - 1) | 3) + 1; + + /* Align if necessary. */ + if ((alignment - 1) & (unsigned) argp) + argp = (char *) ALIGN (argp, alignment); + + z = (*p_argt)->size; + *p_argv = (void *) argp; + argp += z; + } + + (closure->fun) (cif, rvalue, arg_area, closure->user_data); + + return cif->flags; +} + +extern void ffi_closure_ARCompact (void); + +ffi_status +ffi_prep_closure_loc (ffi_closure * closure, ffi_cif * cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, void *codeloc) +{ + uint32_t *tramp = (uint32_t *) & (closure->tramp[0]); + + switch (cif->abi) + { + case FFI_ARCOMPACT: + FFI_ASSERT (tramp == codeloc); + tramp[0] = CODE_ENDIAN (0x200a1fc0); /* mov r8, pcl */ + tramp[1] = CODE_ENDIAN (0x20200f80); /* j [long imm] */ + tramp[2] = CODE_ENDIAN (ffi_closure_ARCompact); + break; + + default: + return FFI_BAD_ABI; + } + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + cacheflush (codeloc, FFI_TRAMPOLINE_SIZE, BCACHE); + + return FFI_OK; +} diff --git a/Modules/_ctypes/libffi/src/arc/ffitarget.h b/Modules/_ctypes/libffi/src/arc/ffitarget.h new file mode 100644 index 000000000000..bf8311bc832c --- /dev/null +++ b/Modules/_ctypes/libffi/src/arc/ffitarget.h @@ -0,0 +1,53 @@ +/* ----------------------------------------------------------------------- + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (c) 2013 Synopsys, Inc. (www.synopsys.com) + Target configuration macros for ARC. + + 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 RENESAS TECHNOLOGY 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 + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#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, + FFI_ARCOMPACT, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_ARCOMPACT +} ffi_abi; +#endif + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 12 +#define FFI_NATIVE_RAW_API 0 + +#endif diff --git a/Modules/_ctypes/libffi/src/arm/ffi.c b/Modules/_ctypes/libffi/src/arm/ffi.c index 7fd7f44c4d4c..6691ab57daa2 100644 --- a/Modules/_ctypes/libffi/src/arm/ffi.c +++ b/Modules/_ctypes/libffi/src/arm/ffi.c @@ -4,8 +4,8 @@ Copyright (c) 2011 Anthony Green Copyright (c) 2011 Free Software Foundation Copyright (c) 1998, 2008, 2011 Red Hat, Inc. - - ARM Foreign Function Interface + + ARM Foreign Function Interface Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -37,6 +37,87 @@ static int vfp_type_p (ffi_type *); static void layout_vfp_args (ffi_cif *); +int ffi_prep_args_SYSV(char *stack, extended_cif *ecif, float *vfp_space); +int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space); + +static char* ffi_align(ffi_type **p_arg, char *argp) +{ + /* Align if necessary */ + register size_t alignment = (*p_arg)->alignment; + if (alignment < 4) + { + alignment = 4; + } +#ifdef _WIN32_WCE + if (alignment > 4) + { + alignment = 4; + } +#endif + if ((alignment - 1) & (unsigned) argp) + { + argp = (char *) ALIGN(argp, alignment); + } + + if ((*p_arg)->type == FFI_TYPE_STRUCT) + { + argp = (char *) ALIGN(argp, 4); + } + return argp; +} + +static size_t ffi_put_arg(ffi_type **arg_type, void **arg, char *stack) +{ + register char* argp = stack; + register ffi_type **p_arg = arg_type; + register void **p_argv = arg; + register size_t 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_STRUCT: + memcpy(argp, *p_argv, (*p_arg)->size); + break; + + default: + FFI_ASSERT(0); + } + } + else if (z == sizeof(int)) + { + if ((*p_arg)->type == FFI_TYPE_FLOAT) + *(float *) argp = *(float *)(* p_argv); + else + *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + } + else if (z == sizeof(double) && (*p_arg)->type == FFI_TYPE_DOUBLE) + { + *(double *) argp = *(double *)(* p_argv); + } + else + { + memcpy(argp, *p_argv, z); + } + return z; +} /* ffi_prep_args is called by the assembly routine once stack space has been allocated for the function's arguments @@ -44,14 +125,14 @@ static void layout_vfp_args (ffi_cif *); value is cif->vfp_used (word bitset of VFP regs used for passing arguments). These are only used for the VFP hard-float ABI. */ -int ffi_prep_args(char *stack, extended_cif *ecif, float *vfp_space) +int ffi_prep_args_SYSV(char *stack, extended_cif *ecif, float *vfp_space) { - register unsigned int i, vi = 0; + 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; @@ -62,81 +143,89 @@ int ffi_prep_args(char *stack, extended_cif *ecif, float *vfp_space) for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; (i != 0); - i--, p_arg++) + i--, p_arg++, p_argv++) { - size_t z; - size_t alignment; + argp = ffi_align(p_arg, argp); + argp += ffi_put_arg(p_arg, p_argv, argp); + } - /* Allocated in VFP registers. */ - if (ecif->cif->abi == FFI_VFP - && vi < ecif->cif->vfp_nargs && vfp_type_p (*p_arg)) - { - float* vfp_slot = vfp_space + ecif->cif->vfp_args[vi++]; - if ((*p_arg)->type == FFI_TYPE_FLOAT) - *((float*)vfp_slot) = *((float*)*p_argv); - else if ((*p_arg)->type == FFI_TYPE_DOUBLE) - *((double*)vfp_slot) = *((double*)*p_argv); - else - memcpy(vfp_slot, *p_argv, (*p_arg)->size); - p_argv++; - continue; - } + return 0; +} - /* Align if necessary */ - alignment = (*p_arg)->alignment; -#ifdef _WIN32_WCE - if (alignment > 4) - alignment = 4; -#endif - if ((alignment - 1) & (unsigned) argp) { - argp = (char *) ALIGN(argp, alignment); - } +int ffi_prep_args_VFP(char *stack, extended_cif *ecif, float *vfp_space) +{ + register unsigned int i, vi = 0; + register void **p_argv; + register char *argp, *regp, *eo_regp; + register ffi_type **p_arg; + char stack_used = 0; + char done_with_regs = 0; + char is_vfp_type; - if ((*p_arg)->type == FFI_TYPE_STRUCT) - argp = (char *) ALIGN(argp, 4); + // make sure we are using FFI_VFP + FFI_ASSERT(ecif->cif->abi == FFI_VFP); - 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_STRUCT: - memcpy(argp, *p_argv, (*p_arg)->size); - break; - - default: - FFI_ASSERT(0); - } - } - else if (z == sizeof(int)) - { - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); - } - else - { - memcpy(argp, *p_argv, z); - } - p_argv++; - argp += z; - } + /* the first 4 words on the stack are used for values passed in core + * registers. */ + regp = stack; + eo_regp = argp = regp + 16; + + /* if the function returns an FFI_TYPE_STRUCT in memory, that address is + * passed in r0 to the function */ + if ( ecif->cif->flags == FFI_TYPE_STRUCT ) { + *(void **) regp = ecif->rvalue; + regp += 4; + } + + p_argv = ecif->avalue; + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; + (i != 0); + i--, p_arg++, p_argv++) + { + is_vfp_type = vfp_type_p (*p_arg); + + /* Allocated in VFP registers. */ + if(vi < ecif->cif->vfp_nargs && is_vfp_type) + { + char *vfp_slot = (char *)(vfp_space + ecif->cif->vfp_args[vi++]); + ffi_put_arg(p_arg, p_argv, vfp_slot); + continue; + } + /* Try allocating in core registers. */ + else if (!done_with_regs && !is_vfp_type) + { + char *tregp = ffi_align(p_arg, regp); + size_t size = (*p_arg)->size; + size = (size < 4)? 4 : size; // pad + /* Check if there is space left in the aligned register area to place + * the argument */ + if(tregp + size <= eo_regp) + { + regp = tregp + ffi_put_arg(p_arg, p_argv, tregp); + done_with_regs = (regp == argp); + // ensure we did not write into the stack area + FFI_ASSERT(regp <= argp); + continue; + } + /* In case there are no arguments in the stack area yet, + the argument is passed in the remaining core registers and on the + stack. */ + else if (!stack_used) + { + stack_used = 1; + done_with_regs = 1; + argp = tregp + ffi_put_arg(p_arg, p_argv, tregp); + FFI_ASSERT(eo_regp < argp); + continue; + } + } + /* Base case, arguments are passed on the stack */ + stack_used = 1; + argp = ffi_align(p_arg, argp); + argp += ffi_put_arg(p_arg, p_argv, argp); + } /* Indicate the VFP registers used. */ return ecif->cif->vfp_used; } @@ -227,7 +316,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) 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 */ + /* value address then we need to make one */ if ((rvalue == NULL) && (cif->flags == FFI_TYPE_STRUCT)) @@ -261,9 +350,17 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) break; } if (small_struct) - memcpy (rvalue, &temp, cif->rtype->size); + { + FFI_ASSERT(rvalue != NULL); + memcpy (rvalue, &temp, cif->rtype->size); + } + else if (vfp_struct) - memcpy (rvalue, ecif.rvalue, cif->rtype->size); + { + FFI_ASSERT(rvalue != NULL); + memcpy (rvalue, ecif.rvalue, cif->rtype->size); + } + } /** private members **/ @@ -271,18 +368,18 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, void** args, ffi_cif* cif, float *vfp_stack); +static void ffi_prep_incoming_args_VFP (char *stack, void **ret, + void** args, ffi_cif* cif, float *vfp_stack); + void ffi_closure_SYSV (ffi_closure *); void ffi_closure_VFP (ffi_closure *); /* This function is jumped to by the trampoline */ -unsigned int -ffi_closure_SYSV_inner( - ffi_closure *closure, - void **respp, - void *args, - void *vfp_args) +unsigned int FFI_HIDDEN +ffi_closure_inner (ffi_closure *closure, + void **respp, void *args, void *vfp_args) { // our various things... ffi_cif *cif; @@ -296,8 +393,10 @@ ffi_closure_SYSV_inner( * 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, vfp_args); + if (cif->abi == FFI_VFP) + ffi_prep_incoming_args_VFP(args, respp, arg_area, cif, vfp_args); + else + ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif, vfp_args); (closure->fun) (cif, *respp, arg_area, closure->user_data); @@ -312,7 +411,7 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, float *vfp_stack) /*@=exportheader@*/ { - register unsigned int i, vi = 0; + register unsigned int i; register void **p_argv; register char *argp; register ffi_type **p_arg; @@ -329,27 +428,8 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) { size_t z; - size_t alignment; - - if (cif->abi == FFI_VFP - && vi < cif->vfp_nargs && vfp_type_p (*p_arg)) - { - *p_argv++ = (void*)(vfp_stack + cif->vfp_args[vi++]); - continue; - } - alignment = (*p_arg)->alignment; - if (alignment < 4) - alignment = 4; -#ifdef _WIN32_WCE - else - if (alignment > 4) - alignment = 4; -#endif - /* Align if necessary */ - if ((alignment - 1) & (unsigned) argp) { - argp = (char *) ALIGN(argp, alignment); - } + argp = ffi_align(p_arg, argp); z = (*p_arg)->size; @@ -364,6 +444,95 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, return; } +/*@-exportheader@*/ +static void +ffi_prep_incoming_args_VFP(char *stack, void **rvalue, + void **avalue, ffi_cif *cif, + /* Used only under VFP hard-float ABI. */ + float *vfp_stack) +/*@=exportheader@*/ +{ + register unsigned int i, vi = 0; + register void **p_argv; + register char *argp, *regp, *eo_regp; + register ffi_type **p_arg; + char done_with_regs = 0; + char stack_used = 0; + char is_vfp_type; + + FFI_ASSERT(cif->abi == FFI_VFP); + regp = stack; + eo_regp = argp = regp + 16; + + if ( cif->flags == FFI_TYPE_STRUCT ) { + *rvalue = *(void **) regp; + regp += 4; + } + + p_argv = avalue; + + for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) + { + size_t z; + is_vfp_type = vfp_type_p (*p_arg); + + if(vi < cif->vfp_nargs && is_vfp_type) + { + *p_argv++ = (void*)(vfp_stack + cif->vfp_args[vi++]); + continue; + } + else if (!done_with_regs && !is_vfp_type) + { + char* tregp = ffi_align(p_arg, regp); + + z = (*p_arg)->size; + z = (z < 4)? 4 : z; // pad + + /* if the arguments either fits into the registers or uses registers + * and stack, while we haven't read other things from the stack */ + if(tregp + z <= eo_regp || !stack_used) + { + /* because we're little endian, this is what it turns into. */ + *p_argv = (void*) tregp; + + p_argv++; + regp = tregp + z; + // if we read past the last core register, make sure we have not read + // from the stack before and continue reading after regp + if(regp > eo_regp) + { + if(stack_used) + { + abort(); // we should never read past the end of the register + // are if the stack is already in use + } + argp = regp; + } + if(regp >= eo_regp) + { + done_with_regs = 1; + stack_used = 1; + } + continue; + } + } + stack_used = 1; + + argp = ffi_align(p_arg, argp); + + 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. */ extern unsigned int ffi_arm_trampoline[3]; @@ -381,7 +550,7 @@ typedef struct ffi_trampoline_table ffi_trampoline_table; typedef struct ffi_trampoline_table_entry ffi_trampoline_table_entry; struct ffi_trampoline_table { - /* contigious writable and executable pages */ + /* contiguous writable and executable pages */ vm_address_t config_page; vm_address_t trampoline_page; @@ -421,7 +590,7 @@ ffi_trampoline_table_alloc () { ffi_trampoline_table *table = NULL; - /* Loop until we can allocate two contigious pages */ + /* Loop until we can allocate two contiguous pages */ while (table == NULL) { vm_address_t config_page = 0x0; kern_return_t kt; @@ -617,7 +786,7 @@ ffi_prep_closure_loc (ffi_closure* closure, #endif else return FFI_BAD_ABI; - + #if FFI_EXEC_TRAMPOLINE_TABLE void **config = FFI_TRAMPOLINE_CODELOC_CONFIG(codeloc); config[0] = closure; @@ -700,9 +869,9 @@ static int vfp_type_p (ffi_type *t) return 0; } -static void place_vfp_arg (ffi_cif *cif, ffi_type *t) +static int place_vfp_arg (ffi_cif *cif, ffi_type *t) { - int reg = cif->vfp_reg_free; + short reg = cif->vfp_reg_free; int nregs = t->size / sizeof (float); int align = ((t->type == FFI_TYPE_STRUCT_VFP_FLOAT || t->type == FFI_TYPE_FLOAT) ? 1 : 2); @@ -733,9 +902,13 @@ static void place_vfp_arg (ffi_cif *cif, ffi_type *t) reg += 1; cif->vfp_reg_free = reg; } - return; + return 0; next_reg: ; } + // done, mark all regs as used + cif->vfp_reg_free = 16; + cif->vfp_used = 0xFFFF; + return 1; } static void layout_vfp_args (ffi_cif *cif) @@ -750,7 +923,9 @@ static void layout_vfp_args (ffi_cif *cif) for (i = 0; i < cif->nargs; i++) { ffi_type *t = cif->arg_types[i]; - if (vfp_type_p (t)) - place_vfp_arg (cif, t); + if (vfp_type_p (t) && place_vfp_arg (cif, t) == 1) + { + break; + } } } diff --git a/Modules/_ctypes/libffi/src/arm/gentramp.sh b/Modules/_ctypes/libffi/src/arm/gentramp.sh old mode 100644 new mode 100755 index 74f0b867daec..05c43a30fc49 --- a/Modules/_ctypes/libffi/src/arm/gentramp.sh +++ b/Modules/_ctypes/libffi/src/arm/gentramp.sh @@ -84,7 +84,7 @@ EOF } -# WARNING - Don't modify the trampoline code size without also updating the relevent libffi code +# WARNING - Don't modify the trampoline code size without also updating the relevant libffi code trampoline () { cat << END diff --git a/Modules/_ctypes/libffi/src/arm/sysv.S b/Modules/_ctypes/libffi/src/arm/sysv.S index fb38cd6406ad..541bbe923002 100644 --- a/Modules/_ctypes/libffi/src/arm/sysv.S +++ b/Modules/_ctypes/libffi/src/arm/sysv.S @@ -109,42 +109,27 @@ #define UNWIND @ #endif - +.syntax unified + #if defined(__thumb__) && !defined(__THUMB_INTERWORK__) -.macro ARM_FUNC_START name - .text - .align 0 - .thumb - .thumb_func -#ifdef __APPLE__ - ENTRY($0) +#define ARM_FUNC_START(name) \ + .text; \ + .align 2; \ + .thumb; \ + .thumb_func; \ + ENTRY(name); \ + bx pc; \ + nop; \ + .arm; \ + UNWIND .fnstart; \ +_L__##name: #else - ENTRY(\name) -#endif - bx pc - nop - .arm +#define ARM_FUNC_START(name) \ + .text; \ + .align 2; \ + .arm; \ + ENTRY(name); \ UNWIND .fnstart -/* A hook to tell gdb that we've switched to ARM mode. Also used to call - directly from other local arm routines. */ -#ifdef __APPLE__ -_L__$0: -#else -_L__\name: -#endif -.endm -#else -.macro ARM_FUNC_START name - .text - .align 0 - .arm -#ifdef __APPLE__ - ENTRY($0) -#else - ENTRY(\name) -#endif - UNWIND .fnstart -.endm #endif .macro RETLDM regs=, cond=, dirn=ia @@ -171,7 +156,7 @@ _L__\name: @ sp+0: ecif.rvalue @ This assumes we are using gas. -ARM_FUNC_START ffi_call_SYSV +ARM_FUNC_START(ffi_call_SYSV) @ Save registers stmfd sp!, {r0-r3, fp, lr} UNWIND .save {r0-r3, fp, lr} @@ -187,7 +172,7 @@ ARM_FUNC_START ffi_call_SYSV @ r1 already set @ Call ffi_prep_args(stack, &ecif) - bl CNAME(ffi_prep_args) + bl CNAME(ffi_prep_args_SYSV) @ move first 4 parameters in registers ldmia sp, {r0-r3} @@ -228,7 +213,7 @@ ARM_FUNC_START ffi_call_SYSV #if defined(__SOFTFP__) || defined(__ARM_EABI__) cmpne r3, #FFI_TYPE_DOUBLE #endif - stmeqia r2, {r0, r1} + stmiaeq r2, {r0, r1} #if !defined(__SOFTFP__) && !defined(__ARM_EABI__) beq LSYM(Lepilogue) @@ -260,13 +245,13 @@ LSYM(Lepilogue): /* unsigned int FFI_HIDDEN - ffi_closure_SYSV_inner (closure, respp, args) + ffi_closure_inner (closure, respp, args) ffi_closure *closure; void **respp; void *args; */ -ARM_FUNC_START ffi_closure_SYSV +ARM_FUNC_START(ffi_closure_SYSV) UNWIND .pad #16 add ip, sp, #16 stmfd sp!, {ip, lr} @@ -276,7 +261,7 @@ ARM_FUNC_START ffi_closure_SYSV sub sp, sp, #16 str sp, [sp, #8] add r1, sp, #8 - bl CNAME(ffi_closure_SYSV_inner) + bl CNAME(ffi_closure_inner) cmp r0, #FFI_TYPE_INT beq .Lretint @@ -345,7 +330,7 @@ ARM_FUNC_START ffi_closure_SYSV @ r3: fig->flags @ sp+0: ecif.rvalue -ARM_FUNC_START ffi_call_VFP +ARM_FUNC_START(ffi_call_VFP) @ Save registers stmfd sp!, {r0-r3, fp, lr} UNWIND .save {r0-r3, fp, lr} @@ -364,10 +349,11 @@ ARM_FUNC_START ffi_call_VFP sub r2, fp, #64 @ VFP scratch space @ Call ffi_prep_args(stack, &ecif, vfp_space) - bl CNAME(ffi_prep_args) + bl CNAME(ffi_prep_args_VFP) @ Load VFP register args if needed cmp r0, #0 + mov ip, fp beq LSYM(Lbase_args) @ Load only d0 if possible @@ -433,7 +419,7 @@ LSYM(Lepilogue_vfp): .size CNAME(ffi_call_VFP),.ffi_call_VFP_end-CNAME(ffi_call_VFP) -ARM_FUNC_START ffi_closure_VFP +ARM_FUNC_START(ffi_closure_VFP) fstmfdd sp!, {d0-d7} @ r0-r3, then d0-d7 UNWIND .pad #80 @@ -446,7 +432,7 @@ ARM_FUNC_START ffi_closure_VFP sub sp, sp, #72 str sp, [sp, #64] add r1, sp, #64 - bl CNAME(ffi_closure_SYSV_inner) + bl CNAME(ffi_closure_inner) cmp r0, #FFI_TYPE_INT beq .Lretint_vfp diff --git a/Modules/_ctypes/libffi/src/bfin/ffi.c b/Modules/_ctypes/libffi/src/bfin/ffi.c index 0beccc14c932..22a2acdac192 100644 --- a/Modules/_ctypes/libffi/src/bfin/ffi.c +++ b/Modules/_ctypes/libffi/src/bfin/ffi.c @@ -1,5 +1,6 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 2012 Alexandre K. I. de Mendonca + ffi.c - Copyright (c) 2012 Alexandre K. I. de Mendonca , + Paulo Pizarro Blackfin Foreign Function Interface diff --git a/Modules/_ctypes/libffi/src/bfin/sysv.S b/Modules/_ctypes/libffi/src/bfin/sysv.S index ae7a1529b123..f4278be2426d 100644 --- a/Modules/_ctypes/libffi/src/bfin/sysv.S +++ b/Modules/_ctypes/libffi/src/bfin/sysv.S @@ -1,5 +1,6 @@ /* ----------------------------------------------------------------------- - sysv.S - Copyright (c) 2012 Alexandre K. I. de Mendonca + sysv.S - Copyright (c) 2012 Alexandre K. I. de Mendonca , + Paulo Pizarro Blackfin Foreign Function Interface @@ -32,7 +33,7 @@ .align 4 /* - There is a "feature" in the bfin toolchain that it puts a _ before funcion names + There is a "feature" in the bfin toolchain that it puts a _ before function names that's why the function here it's called _ffi_call_SYSV and not ffi_call_SYSV */ .global _ffi_call_SYSV; @@ -40,25 +41,26 @@ .func ffi_call_SYSV /* - cif->bytes = R0 (fp+8) - &ecif = R1 (fp+12) - ffi_prep_args = R2 (fp+16) - ret_type = stack (fp+20) - ecif.rvalue = stack (fp+24) - fn = stack (fp+28) - got (fp+32) - There is room for improvement here (we can use temporary registers + cif->bytes = R0 (fp+8) + &ecif = R1 (fp+12) + ffi_prep_args = R2 (fp+16) + ret_type = stack (fp+20) + ecif.rvalue = stack (fp+24) + fn = stack (fp+28) + got (fp+32) + + There is room for improvement here (we can use temporary registers instead of saving the values in the memory) - REGS: - P5 => Stack pointer (function arguments) - R5 => cif->bytes - R4 => ret->type - - FP-20 = P3 - FP-16 = SP (parameters area) - FP-12 = SP (temp) - FP-08 = function return part 1 [R0] - FP-04 = function return part 2 [R1] + REGS: + P5 => Stack pointer (function arguments) + R5 => cif->bytes + R4 => ret->type + + FP-20 = P3 + FP-16 = SP (parameters area) + FP-12 = SP (temp) + FP-08 = function return part 1 [R0] + FP-04 = function return part 2 [R1] */ _ffi_call_SYSV: diff --git a/Modules/_ctypes/libffi/src/closures.c b/Modules/_ctypes/libffi/src/closures.c index 6298d6f0c4de..c7863f3d0ae1 100644 --- a/Modules/_ctypes/libffi/src/closures.c +++ b/Modules/_ctypes/libffi/src/closures.c @@ -34,7 +34,7 @@ #include #if !FFI_MMAP_EXEC_WRIT && !FFI_EXEC_TRAMPOLINE_TABLE -# if __gnu_linux__ +# if __gnu_linux__ && !defined(__ANDROID__) /* This macro indicates it may be forbidden to map anonymous memory with both write and execute permission. Code compiled when this option is defined will attempt to map such pages once, but if it @@ -181,10 +181,26 @@ static int emutramp_enabled = -1; static int emutramp_enabled_check (void) { - if (getenv ("FFI_DISABLE_EMUTRAMP") == NULL) - return 1; - else + char *buf = NULL; + size_t len = 0; + FILE *f; + int ret; + f = fopen ("/proc/self/status", "r"); + if (f == NULL) return 0; + ret = 0; + + while (getline (&buf, &len, f) != -1) + if (!strncmp (buf, "PaX:", 4)) + { + char emutramp; + if (sscanf (buf, "%*s %*c%c", &emutramp) == 1) + ret = (emutramp == 'E'); + break; + } + free (buf); + fclose (f); + return ret; } #define is_emutramp_enabled() (emutramp_enabled >= 0 ? emutramp_enabled \ @@ -264,7 +280,7 @@ static int open_temp_exec_file_dir (const char *dir) { static const char suffix[] = "/ffiXXXXXX"; - int lendir = strlen (dir); + size_t lendir = strlen (dir); char *tempname = __builtin_alloca (lendir + sizeof (suffix)); if (!tempname) @@ -382,7 +398,7 @@ open_temp_exec_file_opts_next (void) } /* Return a file descriptor of a temporary zero-sized file in a - writable and exexutable filesystem. */ + writable and executable filesystem. */ static int open_temp_exec_file (void) { diff --git a/Modules/_ctypes/libffi/src/dlmalloc.c b/Modules/_ctypes/libffi/src/dlmalloc.c index 2773953590e5..6e474b7c4f02 100644 --- a/Modules/_ctypes/libffi/src/dlmalloc.c +++ b/Modules/_ctypes/libffi/src/dlmalloc.c @@ -1260,7 +1260,7 @@ extern void* sbrk(ptrdiff_t); #define SIZE_T_BITSIZE (sizeof(size_t) << 3) /* Some constants coerced to size_t */ -/* Annoying but necessary to avoid errors on some plaftorms */ +/* Annoying but necessary to avoid errors on some platforms */ #define SIZE_T_ZERO ((size_t)0) #define SIZE_T_ONE ((size_t)1) #define SIZE_T_TWO ((size_t)2) @@ -1414,7 +1414,7 @@ static int win32munmap(void* ptr, size_t size) { #define CALL_MORECORE(S) MFAIL #endif /* HAVE_MORECORE */ -/* mstate bit set if continguous morecore disabled or failed */ +/* mstate bit set if contiguous morecore disabled or failed */ #define USE_NONCONTIGUOUS_BIT (4U) /* segment bit set in create_mspace_with_base */ @@ -1666,7 +1666,7 @@ struct malloc_chunk { typedef struct malloc_chunk mchunk; typedef struct malloc_chunk* mchunkptr; typedef struct malloc_chunk* sbinptr; /* The type of bins of chunks */ -typedef unsigned int bindex_t; /* Described below */ +typedef size_t bindex_t; /* Described below */ typedef unsigned int binmap_t; /* Described below */ typedef unsigned int flag_t; /* The type of various bit flag sets */ @@ -3095,8 +3095,8 @@ static void internal_malloc_stats(mstate m) { and choose its bk node as its replacement. 2. If x was the last node of its size, but not a leaf node, it must be replaced with a leaf node (not merely one with an open left or - right), to make sure that lefts and rights of descendents - correspond properly to bit masks. We use the rightmost descendent + right), to make sure that lefts and rights of descendants + correspond properly to bit masks. We use the rightmost descendant of x. We could use any other leaf, but this is easy to locate and tends to counteract removal of leftmosts elsewhere, and so keeps paths shorter than minimally guaranteed. This doesn't loop much @@ -3393,7 +3393,7 @@ static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) { *ss = m->seg; /* Push current record */ m->seg.base = tbase; m->seg.size = tsize; - set_segment_flags(&m->seg, mmapped); + (void)set_segment_flags(&m->seg, mmapped); m->seg.next = ss; /* Insert trailing fenceposts */ @@ -3553,7 +3553,7 @@ static void* sys_alloc(mstate m, size_t nb) { if (!is_initialized(m)) { /* first-time initialization */ m->seg.base = m->least_addr = tbase; m->seg.size = tsize; - set_segment_flags(&m->seg, mmap_flag); + (void)set_segment_flags(&m->seg, mmap_flag); m->magic = mparams.magic; init_bins(m); if (is_global(m)) @@ -4502,7 +4502,7 @@ mspace create_mspace(size_t capacity, int locked) { char* tbase = (char*)(CALL_MMAP(tsize)); if (tbase != CMFAIL) { m = init_user_mstate(tbase, tsize); - set_segment_flags(&m->seg, IS_MMAPPED_BIT); + (void)set_segment_flags(&m->seg, IS_MMAPPED_BIT); set_lock(m, locked); } } @@ -4517,7 +4517,7 @@ mspace create_mspace_with_base(void* base, size_t capacity, int locked) { if (capacity > msize + TOP_FOOT_SIZE && capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { m = init_user_mstate((char*)base, capacity); - set_segment_flags(&m->seg, EXTERN_BIT); + (void)set_segment_flags(&m->seg, EXTERN_BIT); set_lock(m, locked); } return (mspace)m; @@ -5096,10 +5096,10 @@ int mspace_mallopt(int param_number, int value) { Wolfram Gloger (Gloger@lrz.uni-muenchen.de). * Use last_remainder in more cases. * Pack bins using idea from colin@nyx10.cs.du.edu - * Use ordered bins instead of best-fit threshhold + * Use ordered bins instead of best-fit threshold * Eliminate block-local decls to simplify tracing and debugging. * Support another case of realloc via move into top - * Fix error occuring when initial sbrk_base not word-aligned. + * Fix error occurring when initial sbrk_base not word-aligned. * Rely on page size for units instead of SBRK_UNIT to avoid surprises about sbrk alignment conventions. * Add mallinfo, mallopt. Thanks to Raymond Nijssen diff --git a/Modules/_ctypes/libffi/src/ia64/ffi.c b/Modules/_ctypes/libffi/src/ia64/ffi.c index 9533ef68b584..b77a836ddcf7 100644 --- a/Modules/_ctypes/libffi/src/ia64/ffi.c +++ b/Modules/_ctypes/libffi/src/ia64/ffi.c @@ -401,7 +401,7 @@ ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) the closure (in the "trampoline" area), but we replace the gp pointer with a pointer to the closure itself. We also add the real gp pointer to the closure. This allows the function entry code to - both retrieve the user data, and to restire the correct gp pointer. */ + both retrieve the user data, and to restore the correct gp pointer. */ extern void ffi_closure_unix (); diff --git a/Modules/_ctypes/libffi/src/m88k/ffi.c b/Modules/_ctypes/libffi/src/m88k/ffi.c new file mode 100644 index 000000000000..68df494955e4 --- /dev/null +++ b/Modules/_ctypes/libffi/src/m88k/ffi.c @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * 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. + */ + +/* + * m88k Foreign Function Interface + * + * This file attempts to provide all the FFI entry points which can reliably + * be implemented in C. + * + * Only OpenBSD/m88k is currently supported; other platforms (such as + * Motorola's SysV/m88k) could be supported with the following tweaks: + * + * - non-OpenBSD systems use an `outgoing parameter area' as part of the + * 88BCS calling convention, which is not supported under OpenBSD from + * release 3.6 onwards. Supporting it should be as easy as taking it + * into account when adjusting the stack, in the assembly code. + * + * - the logic deciding whether a function argument gets passed through + * registers, or on the stack, has changed several times in OpenBSD in + * edge cases (especially for structs larger than 32 bytes being passed + * by value). The code below attemps to match the logic used by the + * system compiler of OpenBSD 5.3, i.e. gcc 3.3.6 with many m88k backend + * fixes. + */ + +#include +#include + +#include +#include + +void ffi_call_OBSD (unsigned int, extended_cif *, unsigned int, void *, + void (*fn) ()); +void *ffi_prep_args (void *, extended_cif *); +void ffi_closure_OBSD (ffi_closure *); +void ffi_closure_struct_OBSD (ffi_closure *); +unsigned int ffi_closure_OBSD_inner (ffi_closure *, void *, unsigned int *, + char *); +void ffi_cacheflush_OBSD (unsigned int, unsigned int); + +#define CIF_FLAGS_INT (1 << 0) +#define CIF_FLAGS_DINT (1 << 1) + +/* + * Foreign Function Interface API + */ + +/* ffi_prep_args is called by the assembly routine once stack space has + been allocated for the function's arguments. */ + +void * +ffi_prep_args (void *stack, extended_cif *ecif) +{ + unsigned int i; + void **p_argv; + char *argp, *stackp; + unsigned int *regp; + unsigned int regused; + ffi_type **p_arg; + void *struct_value_ptr; + + regp = (unsigned int *)stack; + stackp = (char *)(regp + 8); + regused = 0; + + if (ecif->cif->rtype->type == FFI_TYPE_STRUCT + && !ecif->cif->flags) + struct_value_ptr = ecif->rvalue; + else + struct_value_ptr = NULL; + + p_argv = ecif->avalue; + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i != 0; i--, p_arg++) + { + size_t z; + unsigned short t, a; + + z = (*p_arg)->size; + t = (*p_arg)->type; + a = (*p_arg)->alignment; + + /* + * Figure out whether the argument can be passed through registers + * or on the stack. + * The rule is that registers can only receive simple types not larger + * than 64 bits, or structs the exact size of a register and aligned to + * the size of a register. + */ + if (t == FFI_TYPE_STRUCT) + { + if (z == sizeof (int) && a == sizeof (int) && regused < 8) + argp = (char *)regp; + else + argp = stackp; + } + else + { + if (z > sizeof (int) && regused < 8 - 1) + { + /* align to an even register pair */ + if (regused & 1) + { + regp++; + regused++; + } + } + if (regused < 8) + argp = (char *)regp; + else + argp = stackp; + } + + /* Enforce proper stack alignment of 64-bit types */ + if (argp == stackp && a > sizeof (int)) + { + stackp = (char *) ALIGN(stackp, a); + argp = stackp; + } + + switch (t) + { + 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_INT: + case FFI_TYPE_FLOAT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_POINTER: + *(unsigned int *) argp = *(unsigned int *) *p_argv; + break; + + case FFI_TYPE_DOUBLE: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_STRUCT: + memcpy (argp, *p_argv, z); + break; + + default: + FFI_ASSERT (0); + } + + /* Align if necessary. */ + if ((sizeof (int) - 1) & z) + z = ALIGN(z, sizeof (int)); + + p_argv++; + + /* Be careful, once all registers are filled, and about to continue + on stack, regp == stackp. Therefore the check for regused as well. */ + if (argp == (char *)regp && regused < 8) + { + regp += z / sizeof (int); + regused += z / sizeof (int); + } + else + stackp += z; + } + + return struct_value_ptr; +} + +/* 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: + cif->flags = 0; + break; + + case FFI_TYPE_STRUCT: + if (cif->rtype->size == sizeof (int) && + cif->rtype->alignment == sizeof (int)) + cif->flags = CIF_FLAGS_INT; + else + cif->flags = 0; + break; + + case FFI_TYPE_DOUBLE: + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + cif->flags = CIF_FLAGS_DINT; + break; + + default: + cif->flags = CIF_FLAGS_INT; + break; + } + + return FFI_OK; +} + +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->rtype->type == FFI_TYPE_STRUCT + && (cif->rtype->size != sizeof (int) + || cif->rtype->alignment != sizeof (int))) + ecif.rvalue = alloca (cif->rtype->size); + else + ecif.rvalue = rvalue; + + switch (cif->abi) + { + case FFI_OBSD: + ffi_call_OBSD (cif->bytes, &ecif, cif->flags, ecif.rvalue, fn); + break; + + default: + FFI_ASSERT (0); + break; + } +} + +/* + * Closure API + */ + +static void +ffi_prep_closure_args_OBSD (ffi_cif *cif, void **avalue, unsigned int *regp, + char *stackp) +{ + unsigned int i; + void **p_argv; + char *argp; + unsigned int regused; + ffi_type **p_arg; + + regused = 0; + + p_argv = avalue; + + for (i = cif->nargs, p_arg = cif->arg_types; i != 0; i--, p_arg++) + { + size_t z; + unsigned short t, a; + + z = (*p_arg)->size; + t = (*p_arg)->type; + a = (*p_arg)->alignment; + + /* + * Figure out whether the argument has been passed through registers + * or on the stack. + * The rule is that registers can only receive simple types not larger + * than 64 bits, or structs the exact size of a register and aligned to + * the size of a register. + */ + if (t == FFI_TYPE_STRUCT) + { + if (z == sizeof (int) && a == sizeof (int) && regused < 8) + argp = (char *)regp; + else + argp = stackp; + } + else + { + if (z > sizeof (int) && regused < 8 - 1) + { + /* align to an even register pair */ + if (regused & 1) + { + regp++; + regused++; + } + } + if (regused < 8) + argp = (char *)regp; + else + argp = stackp; + } + + /* Enforce proper stack alignment of 64-bit types */ + if (argp == stackp && a > sizeof (int)) + { + stackp = (char *) ALIGN(stackp, a); + argp = stackp; + } + + if (z < sizeof (int) && t != FFI_TYPE_STRUCT) + *p_argv = (void *) (argp + sizeof (int) - z); + else + *p_argv = (void *) argp; + + /* Align if necessary */ + if ((sizeof (int) - 1) & z) + z = ALIGN(z, sizeof (int)); + + p_argv++; + + /* Be careful, once all registers are exhausted, and about to fetch from + stack, regp == stackp. Therefore the check for regused as well. */ + if (argp == (char *)regp && regused < 8) + { + regp += z / sizeof (int); + regused += z / sizeof (int); + } + else + stackp += z; + } +} + +unsigned int +ffi_closure_OBSD_inner (ffi_closure *closure, void *resp, unsigned int *regp, + char *stackp) +{ + ffi_cif *cif; + void **arg_area; + + cif = closure->cif; + arg_area = (void**) alloca (cif->nargs * sizeof (void *)); + + ffi_prep_closure_args_OBSD(cif, arg_area, regp, stackp); + + (closure->fun) (cif, resp, arg_area, closure->user_data); + + return cif->flags; +} + +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, ffi_cif* cif, + void (*fun)(ffi_cif*,void*,void**,void*), + void *user_data, void *codeloc) +{ + unsigned int *tramp = (unsigned int *) codeloc; + void *fn; + + FFI_ASSERT (cif->abi == FFI_OBSD); + + if (cif->rtype->type == FFI_TYPE_STRUCT && !cif->flags) + fn = &ffi_closure_struct_OBSD; + else + fn = &ffi_closure_OBSD; + + /* or.u %r10, %r0, %hi16(fn) */ + tramp[0] = 0x5d400000 | (((unsigned int)fn) >> 16); + /* or.u %r13, %r0, %hi16(closure) */ + tramp[1] = 0x5da00000 | ((unsigned int)closure >> 16); + /* or %r10, %r10, %lo16(fn) */ + tramp[2] = 0x594a0000 | (((unsigned int)fn) & 0xffff); + /* jmp.n %r10 */ + tramp[3] = 0xf400c40a; + /* or %r13, %r13, %lo16(closure) */ + tramp[4] = 0x59ad0000 | ((unsigned int)closure & 0xffff); + + ffi_cacheflush_OBSD((unsigned int)codeloc, FFI_TRAMPOLINE_SIZE); + + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + return FFI_OK; +} diff --git a/Modules/_ctypes/libffi/src/m88k/ffitarget.h b/Modules/_ctypes/libffi/src/m88k/ffitarget.h new file mode 100644 index 000000000000..e52bf9fa30a4 --- /dev/null +++ b/Modules/_ctypes/libffi/src/m88k/ffitarget.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * 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. + */ + +/* + * m88k Foreign Function Interface + */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_OBSD, + FFI_DEFAULT_ABI = FFI_OBSD, + FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 0x14 +#define FFI_NATIVE_RAW_API 0 + +#endif diff --git a/Modules/_ctypes/libffi/src/m88k/obsd.S b/Modules/_ctypes/libffi/src/m88k/obsd.S new file mode 100644 index 000000000000..1944a23de424 --- /dev/null +++ b/Modules/_ctypes/libffi/src/m88k/obsd.S @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * 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. + */ + +/* + * m88k Foreign Function Interface + */ + +#define LIBFFI_ASM +#include +#include + + .text + +/* + * ffi_cacheflush_OBSD(unsigned int addr, %r2 + * unsigned int size); %r3 + */ + .align 4 + .globl ffi_cacheflush_OBSD + .type ffi_cacheflush_OBSD,@function +ffi_cacheflush_OBSD: + tb0 0, %r0, 451 + or %r0, %r0, %r0 + jmp %r1 + .size ffi_cacheflush_OBSD, . - ffi_cacheflush_OBSD + +/* + * ffi_call_OBSD(unsigned bytes, %r2 + * extended_cif *ecif, %r3 + * unsigned flags, %r4 + * void *rvalue, %r5 + * void (*fn)()); %r6 + */ + .align 4 + .globl ffi_call_OBSD + .type ffi_call_OBSD,@function +ffi_call_OBSD: + subu %r31, %r31, 32 + st %r30, %r31, 4 + st %r1, %r31, 0 + addu %r30, %r31, 32 + + | Save the few arguments we'll need after ffi_prep_args() + st.d %r4, %r31, 8 + st %r6, %r31, 16 + + | Allocate room for the image of r2-r9, and the stack space for + | the args (rounded to a 16-byte boundary) + addu %r2, %r2, (8 * 4) + 15 + clr %r2, %r2, 4<0> + subu %r31, %r31, %r2 + + | Fill register and stack image + or %r2, %r31, %r0 +#ifdef PIC + bsr ffi_prep_args#plt +#else + bsr ffi_prep_args +#endif + + | Save pointer to return struct address, if any + or %r12, %r2, %r0 + + | Get function pointer + subu %r4, %r30, 32 + ld %r1, %r4, 16 + + | Fetch the register arguments + ld.d %r2, %r31, (0 * 4) + ld.d %r4, %r31, (2 * 4) + ld.d %r6, %r31, (4 * 4) + ld.d %r8, %r31, (6 * 4) + addu %r31, %r31, (8 * 4) + + | Invoke the function + jsr %r1 + + | Restore stack now that we don't need the args anymore + subu %r31, %r30, 32 + + | Figure out what to return as the function's return value + ld %r5, %r31, 12 | rvalue + ld %r4, %r31, 8 | flags + + bcnd eq0, %r5, 9f + + bb0 0, %r4, 1f | CIF_FLAGS_INT + st %r2, %r5, 0 + br 9f + +1: + bb0 1, %r4, 1f | CIF_FLAGS_DINT + st.d %r2, %r5, 0 + br 9f + +1: +9: + ld %r1, %r31, 0 + ld %r30, %r31, 4 + jmp.n %r1 + addu %r31, %r31, 32 + .size ffi_call_OBSD, . - ffi_call_OBSD + +/* + * ffi_closure_OBSD(ffi_closure *closure); %r13 + */ + .align 4 + .globl ffi_closure_OBSD + .type ffi_closure_OBSD, @function +ffi_closure_OBSD: + subu %r31, %r31, 16 + st %r30, %r31, 4 + st %r1, %r31, 0 + addu %r30, %r31, 16 + + | Make room on the stack for saved register arguments and return + | value + subu %r31, %r31, (8 * 4) + (2 * 4) + st.d %r2, %r31, (0 * 4) + st.d %r4, %r31, (2 * 4) + st.d %r6, %r31, (4 * 4) + st.d %r8, %r31, (6 * 4) + + | Invoke the closure function + or %r5, %r30, 0 | calling stack + addu %r4, %r31, 0 | saved registers + addu %r3, %r31, (8 * 4) | return value + or %r2, %r13, %r0 | closure +#ifdef PIC + bsr ffi_closure_OBSD_inner#plt +#else + bsr ffi_closure_OBSD_inner +#endif + + | Figure out what to return as the function's return value + bb0 0, %r2, 1f | CIF_FLAGS_INT + ld %r2, %r31, (8 * 4) + br 9f + +1: + bb0 1, %r2, 1f | CIF_FLAGS_DINT + ld.d %r2, %r31, (8 * 4) + br 9f + +1: +9: + subu %r31, %r30, 16 + ld %r1, %r31, 0 + ld %r30, %r31, 4 + jmp.n %r1 + addu %r31, %r31, 16 + .size ffi_closure_OBSD,.-ffi_closure_OBSD + +/* + * ffi_closure_struct_OBSD(ffi_closure *closure); %r13 + */ + .align 4 + .globl ffi_closure_struct_OBSD + .type ffi_closure_struct_OBSD, @function +ffi_closure_struct_OBSD: + subu %r31, %r31, 16 + st %r30, %r31, 4 + st %r1, %r31, 0 + addu %r30, %r31, 16 + + | Make room on the stack for saved register arguments + subu %r31, %r31, (8 * 4) + st.d %r2, %r31, (0 * 4) + st.d %r4, %r31, (2 * 4) + st.d %r6, %r31, (4 * 4) + st.d %r8, %r31, (6 * 4) + + | Invoke the closure function + or %r5, %r30, 0 | calling stack + addu %r4, %r31, 0 | saved registers + or %r3, %r12, 0 | return value + or %r2, %r13, %r0 | closure +#ifdef PIC + bsr ffi_closure_OBSD_inner#plt +#else + bsr ffi_closure_OBSD_inner +#endif + + subu %r31, %r30, 16 + ld %r1, %r31, 0 + ld %r30, %r31, 4 + jmp.n %r1 + addu %r31, %r31, 16 + .size ffi_closure_struct_OBSD,.-ffi_closure_struct_OBSD diff --git a/Modules/_ctypes/libffi/src/microblaze/ffi.c b/Modules/_ctypes/libffi/src/microblaze/ffi.c index 5c155c5bc5d8..ea962ea4837d 100644 --- a/Modules/_ctypes/libffi/src/microblaze/ffi.c +++ b/Modules/_ctypes/libffi/src/microblaze/ffi.c @@ -183,7 +183,7 @@ void ffi_closure_call_SYSV(void* register_args, void* stack_args, ffi_type** arg_types = cif->arg_types; /* re-allocate data for the args. This needs to be done in order to keep - * multi-word objects (e.g. structs) in contigious memory. Callers are not + * multi-word objects (e.g. structs) in contiguous memory. Callers are not * required to store the value of args in the lower 6 words in the stack * (although they are allocated in the stack). */ diff --git a/Modules/_ctypes/libffi/src/microblaze/sysv.S b/Modules/_ctypes/libffi/src/microblaze/sysv.S index 7a195a634c2f..ea43e9d54539 100644 --- a/Modules/_ctypes/libffi/src/microblaze/sysv.S +++ b/Modules/_ctypes/libffi/src/microblaze/sysv.S @@ -134,7 +134,7 @@ ffi_call_SYSV: rsubi r11, r23, 8 beqi r11, ffi_call_SYSV_store64 - /* Didnt match anything */ + /* Didn't match anything */ bri ffi_call_SYSV_end ffi_call_SYSV_store64: @@ -210,7 +210,7 @@ ffi_closure_SYSV: addik r7, r12, 0 /* closure object */ addik r1, r1, -8 /* allocate return value */ addik r8, r1, 0 /* void* rvalue */ - addik r1, r1, -8 /* allocate for reutrn type/size values */ + addik r1, r1, -8 /* allocate for return type/size values */ addik r9, r1, 0 /* void* rtype */ addik r10, r1, 4 /* void* rsize */ @@ -247,7 +247,7 @@ ffi_closure_SYSV_prepare_return: rsubi r11, r10, 8 beqi r11, ffi_closure_SYSV_store64 - /* Didnt match anything */ + /* Didn't match anything */ bri ffi_closure_SYSV_end ffi_closure_SYSV_store64: diff --git a/Modules/_ctypes/libffi/src/mips/ffi.c b/Modules/_ctypes/libffi/src/mips/ffi.c index 03121e39222e..5d0dd70cb328 100644 --- a/Modules/_ctypes/libffi/src/mips/ffi.c +++ b/Modules/_ctypes/libffi/src/mips/ffi.c @@ -170,7 +170,14 @@ static void ffi_prep_args(char *stack, break; case FFI_TYPE_UINT32: +#ifdef FFI_MIPS_N32 + /* The N32 ABI requires that 32-bit integers + be sign-extended to 64-bits, regardless of + whether they are signed or unsigned. */ + *(ffi_arg *)argp = *(SINT32 *)(* p_argv); +#else *(ffi_arg *)argp = *(UINT32 *)(* p_argv); +#endif break; /* This can only happen with 64bit slots. */ diff --git a/Modules/_ctypes/libffi/src/mips/n32.S b/Modules/_ctypes/libffi/src/mips/n32.S index ff4bbce1decb..c6985d30a6f6 100644 --- a/Modules/_ctypes/libffi/src/mips/n32.S +++ b/Modules/_ctypes/libffi/src/mips/n32.S @@ -108,10 +108,8 @@ loadregs: REG_L t6, 3*FFI_SIZEOF_ARG($fp) # load the flags word into t6. and t4, t6, ((1< +#include + +#include + +/* The Nios II Processor Reference Handbook defines the procedure call + ABI as follows. + + Arguments are passed as if a structure containing the types of + the arguments were constructed. The first 16 bytes are passed in r4 + through r7, the remainder on the stack. The first 16 bytes of a function + taking variable arguments are passed in r4-r7 in the same way. + + Return values of types up to 8 bytes are returned in r2 and r3. For + return values greater than 8 bytes, the caller must allocate memory for + the result and pass the address as if it were argument 0. + + While this isn't specified explicitly in the ABI documentation, GCC + promotes integral arguments smaller than int size to 32 bits. + + Also of note, the ABI specifies that all structure objects are + aligned to 32 bits even if all their fields have a smaller natural + alignment. See FFI_AGGREGATE_ALIGNMENT. */ + + +/* Declare the assembly language hooks. */ + +extern UINT64 ffi_call_sysv (void (*) (char *, extended_cif *), + extended_cif *, + unsigned, + void (*fn) (void)); +extern void ffi_closure_sysv (void); + +/* Perform machine-dependent cif processing. */ + +ffi_status ffi_prep_cif_machdep (ffi_cif *cif) +{ + /* We always want at least 16 bytes in the parameter block since it + simplifies the low-level call function. Also round the parameter + block size up to a multiple of 4 bytes to preserve + 32-bit alignment of the stack pointer. */ + if (cif->bytes < 16) + cif->bytes = 16; + else + cif->bytes = (cif->bytes + 3) & ~3; + + return FFI_OK; +} + + +/* ffi_prep_args is called by the assembly routine to transfer arguments + to the stack using the pointers in the ecif array. + Note that the stack buffer is big enough to fit all the arguments, + but the first 16 bytes will be copied to registers for the actual + call. */ + +void ffi_prep_args (char *stack, extended_cif *ecif) +{ + char *argp = stack; + unsigned int i; + + /* The implicit return value pointer is passed as if it were a hidden + first argument. */ + if (ecif->cif->rtype->type == FFI_TYPE_STRUCT + && ecif->cif->rtype->size > 8) + { + (*(void **) argp) = ecif->rvalue; + argp += 4; + } + + for (i = 0; i < ecif->cif->nargs; i++) + { + void *avalue = ecif->avalue[i]; + ffi_type *atype = ecif->cif->arg_types[i]; + size_t size = atype->size; + size_t alignment = atype->alignment; + + /* Align argp as appropriate for the argument type. */ + if ((alignment - 1) & (unsigned) argp) + argp = (char *) ALIGN (argp, alignment); + + /* Copy the argument, promoting integral types smaller than a + word to word size. */ + if (size < sizeof (int)) + { + size = sizeof (int); + switch (atype->type) + { + case FFI_TYPE_SINT8: + *(signed int *) argp = (signed int) *(SINT8 *) avalue; + break; + + case FFI_TYPE_UINT8: + *(unsigned int *) argp = (unsigned int) *(UINT8 *) avalue; + break; + + case FFI_TYPE_SINT16: + *(signed int *) argp = (signed int) *(SINT16 *) avalue; + break; + + case FFI_TYPE_UINT16: + *(unsigned int *) argp = (unsigned int) *(UINT16 *) avalue; + break; + + case FFI_TYPE_STRUCT: + memcpy (argp, avalue, atype->size); + break; + + default: + FFI_ASSERT(0); + } + } + else if (size == sizeof (int)) + *(unsigned int *) argp = (unsigned int) *(UINT32 *) avalue; + else + memcpy (argp, avalue, size); + argp += size; + } +} + + +/* Call FN using the prepared CIF. RVALUE points to space allocated by + the caller for the return value, and AVALUE is an array of argument + pointers. */ + +void ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue) +{ + + extended_cif ecif; + UINT64 result; + + /* If bigret is true, this is the case where a return value of larger + than 8 bytes is handled by being passed by reference as an implicit + argument. */ + int bigret = (cif->rtype->type == FFI_TYPE_STRUCT + && cif->rtype->size > 8); + + ecif.cif = cif; + ecif.avalue = avalue; + + /* Allocate space for return value if this is the pass-by-reference case + and the caller did not provide a buffer. */ + if (rvalue == NULL && bigret) + ecif.rvalue = alloca (cif->rtype->size); + else + ecif.rvalue = rvalue; + + result = ffi_call_sysv (ffi_prep_args, &ecif, cif->bytes, fn); + + /* Now result contains the 64 bit contents returned from fn in + r2 and r3. Copy the value of the appropriate size to the user-provided + rvalue buffer. */ + if (rvalue && !bigret) + switch (cif->rtype->size) + { + case 1: + *(UINT8 *)rvalue = (UINT8) result; + break; + case 2: + *(UINT16 *)rvalue = (UINT16) result; + break; + case 4: + *(UINT32 *)rvalue = (UINT32) result; + break; + case 8: + *(UINT64 *)rvalue = (UINT64) result; + break; + default: + memcpy (rvalue, (void *)&result, cif->rtype->size); + break; + } +} + +/* This function is invoked from the closure trampoline to invoke + CLOSURE with argument block ARGS. Parse ARGS according to + CLOSURE->cfi and invoke CLOSURE->fun. */ + +static UINT64 +ffi_closure_helper (unsigned char *args, + ffi_closure *closure) +{ + ffi_cif *cif = closure->cif; + unsigned char *argp = args; + void **parsed_args = alloca (cif->nargs * sizeof (void *)); + UINT64 result; + void *retptr; + unsigned int i; + + /* First figure out what to do about the return type. If this is the + big-structure-return case, the first arg is the hidden return buffer + allocated by the caller. */ + if (cif->rtype->type == FFI_TYPE_STRUCT + && cif->rtype->size > 8) + { + retptr = *((void **) argp); + argp += 4; + } + else + retptr = (void *) &result; + + /* Fill in the array of argument pointers. */ + for (i = 0; i < cif->nargs; i++) + { + size_t size = cif->arg_types[i]->size; + size_t alignment = cif->arg_types[i]->alignment; + + /* Align argp as appropriate for the argument type. */ + if ((alignment - 1) & (unsigned) argp) + argp = (char *) ALIGN (argp, alignment); + + /* Arguments smaller than an int are promoted to int. */ + if (size < sizeof (int)) + size = sizeof (int); + + /* Store the pointer. */ + parsed_args[i] = argp; + argp += size; + } + + /* Call the user-supplied function. */ + (closure->fun) (cif, retptr, parsed_args, closure->user_data); + return result; +} + + +/* Initialize CLOSURE with a trampoline to call FUN with + CIF and USER_DATA. */ +ffi_status +ffi_prep_closure_loc (ffi_closure* closure, + ffi_cif* cif, + void (*fun) (ffi_cif*, void*, void**, void*), + void *user_data, + void *codeloc) +{ + unsigned int *tramp = (unsigned int *) &closure->tramp[0]; + int i; + + if (cif->abi != FFI_SYSV) + return FFI_BAD_ABI; + + /* The trampoline looks like: + movhi r8, %hi(ffi_closure_sysv) + ori r8, r8, %lo(ffi_closure_sysv) + movhi r9, %hi(ffi_closure_helper) + ori r0, r9, %lo(ffi_closure_helper) + movhi r10, %hi(closure) + ori r10, r10, %lo(closure) + jmp r8 + and then ffi_closure_sysv retrieves the closure pointer out of r10 + in addition to the arguments passed in the normal way for the call, + and invokes ffi_closure_helper. We encode the pointer to + ffi_closure_helper in the trampoline because making a PIC call + to it in ffi_closure_sysv would be messy (it would have to indirect + through the GOT). */ + +#define HI(x) ((((unsigned int) (x)) >> 16) & 0xffff) +#define LO(x) (((unsigned int) (x)) & 0xffff) + tramp[0] = (0 << 27) | (8 << 22) | (HI (ffi_closure_sysv) << 6) | 0x34; + tramp[1] = (8 << 27) | (8 << 22) | (LO (ffi_closure_sysv) << 6) | 0x14; + tramp[2] = (0 << 27) | (9 << 22) | (HI (ffi_closure_helper) << 6) | 0x34; + tramp[3] = (9 << 27) | (9 << 22) | (LO (ffi_closure_helper) << 6) | 0x14; + tramp[4] = (0 << 27) | (10 << 22) | (HI (closure) << 6) | 0x34; + tramp[5] = (10 << 27) | (10 << 22) | (LO (closure) << 6) | 0x14; + tramp[6] = (8 << 27) | (0x0d << 11) | 0x3a; +#undef HI +#undef LO + + /* Flush the caches. + See Example 9-4 in the Nios II Software Developer's Handbook. */ + for (i = 0; i < 7; i++) + asm volatile ("flushd 0(%0); flushi %0" :: "r"(tramp + i) : "memory"); + asm volatile ("flushp" ::: "memory"); + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + return FFI_OK; +} + diff --git a/Modules/_ctypes/libffi/src/nios2/ffitarget.h b/Modules/_ctypes/libffi/src/nios2/ffitarget.h new file mode 100644 index 000000000000..134d118c12a2 --- /dev/null +++ b/Modules/_ctypes/libffi/src/nios2/ffitarget.h @@ -0,0 +1,52 @@ +/* libffi target includes for Altera Nios II. + + Copyright (c) 2013 Mentor Graphics. + + 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 LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_SYSV, + FFI_LAST_ABI, + FFI_DEFAULT_ABI = FFI_SYSV +} ffi_abi; +#endif + +/* Structures have a 4-byte alignment even if all the fields have lesser + alignment requirements. */ +#define FFI_AGGREGATE_ALIGNMENT 4 + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 28 /* 7 instructions */ +#define FFI_NATIVE_RAW_API 0 + +#endif diff --git a/Modules/_ctypes/libffi/src/nios2/sysv.S b/Modules/_ctypes/libffi/src/nios2/sysv.S new file mode 100644 index 000000000000..75f442bbeeb9 --- /dev/null +++ b/Modules/_ctypes/libffi/src/nios2/sysv.S @@ -0,0 +1,136 @@ +/* Low-level libffi support for Altera Nios II. + + Copyright (c) 2013 Mentor Graphics. + + 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. */ + +/* This function is declared on the C side as + + extern UINT64 ffi_call_sysv (void (*arghook) (char *, extended_cif *), + extended_cif *ecif, + unsigned nbytes, + void (*fn) (void)); + + On input, the arguments appear as + r4 = arghook + r5 = ecif + r6 = nbytes + r7 = fn +*/ + + .section .text + .align 2 + .global ffi_call_sysv + .type ffi_call_sysv, @function + +ffi_call_sysv: + .cfi_startproc + + /* Create the stack frame, saving r16 so we can use it locally. */ + addi sp, sp, -12 + .cfi_def_cfa_offset 12 + stw ra, 8(sp) + stw fp, 4(sp) + stw r16, 0(sp) + .cfi_offset 31, -4 + .cfi_offset 28, -8 + .cfi_offset 16, -12 + mov fp, sp + .cfi_def_cfa_register 28 + mov r16, r7 + + /* Adjust the stack pointer to create the argument buffer + nbytes long. */ + sub sp, sp, r6 + + /* Call the arghook function. */ + mov r2, r4 /* fn */ + mov r4, sp /* argbuffer */ + callr r2 /* r5 already contains ecif */ + + /* Pop off the first 16 bytes of the argument buffer on the stack, + transferring the contents to the argument registers. */ + ldw r4, 0(sp) + ldw r5, 4(sp) + ldw r6, 8(sp) + ldw r7, 12(sp) + addi sp, sp, 16 + + /* Call the user function, which leaves its result in r2 and r3. */ + callr r16 + + /* Pop off the stack frame. */ + mov sp, fp + ldw ra, 8(sp) + ldw fp, 4(sp) + ldw r16, 0(sp) + addi sp, sp, 12 + ret + .cfi_endproc + .size ffi_call_sysv, .-ffi_call_sysv + + +/* Closure trampolines jump here after putting the C helper address + in r9 and the closure pointer in r10. The user-supplied arguments + to the closure are in the normal places, in r4-r7 and on the + stack. Push the register arguments on the stack too and then call the + C helper function to deal with them. */ + + .section .text + .align 2 + .global ffi_closure_sysv + .type ffi_closure_sysv, @function + +ffi_closure_sysv: + .cfi_startproc + + /* Create the stack frame, pushing the register args on the stack + just below the stack args. This is the same trick illustrated + in Figure 7-3 in the Nios II Processor Reference Handbook, used + for variable arguments and structures passed by value. */ + addi sp, sp, -20 + .cfi_def_cfa_offset 20 + stw ra, 0(sp) + .cfi_offset 31, -20 + stw r4, 4(sp) + .cfi_offset 4, -16 + stw r5, 8(sp) + .cfi_offset 5, -12 + stw r6, 12(sp) + .cfi_offset 6, -8 + stw r7, 16(sp) + .cfi_offset 7, -4 + + /* Call the helper. + r4 = pointer to arguments on stack + r5 = closure pointer (loaded in r10 by the trampoline) + r9 = address of helper function (loaded by trampoline) */ + addi r4, sp, 4 + mov r5, r10 + callr r9 + + /* Pop the stack and return. */ + ldw ra, 0(sp) + addi sp, sp, 20 + .cfi_def_cfa_offset -20 + ret + .cfi_endproc + .size ffi_closure_sysv, .-ffi_closure_sysv + diff --git a/Modules/_ctypes/libffi/src/powerpc/darwin.S b/Modules/_ctypes/libffi/src/powerpc/darwin.S index 4f987dc74824..066eb82efe93 100644 --- a/Modules/_ctypes/libffi/src/powerpc/darwin.S +++ b/Modules/_ctypes/libffi/src/powerpc/darwin.S @@ -318,11 +318,6 @@ _ffi_call_AIX: #define EH_DATA_ALIGN_FACT MODE_CHOICE(0x7c,0x78) - .static_data - .align LOG2_GPR_BYTES -LLFB0$non_lazy_ptr: - .g_long Lstartcode - .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support EH_frame1: .set L$set$0,LECIE1-LSCIE1 @@ -335,7 +330,7 @@ LSCIE1: .byte EH_DATA_ALIGN_FACT ; sleb128 -4; CIE Data Alignment Factor .byte 0x41 ; CIE RA Column .byte 0x1 ; uleb128 0x1; Augmentation size - .byte 0x10 ; FDE Encoding (indirect pcrel) + .byte 0x10 ; FDE Encoding (pcrel) .byte 0xc ; DW_CFA_def_cfa .byte 0x1 ; uleb128 0x1 .byte 0x0 ; uleb128 0x0 @@ -349,7 +344,7 @@ LSFDE1: .long L$set$1 ; FDE Length LASFDE1: .long LASFDE1-EH_frame1 ; FDE CIE offset - .g_long LLFB0$non_lazy_ptr-. ; FDE initial location + .g_long Lstartcode-. ; FDE initial location .set L$set$3,LFE1-Lstartcode .g_long L$set$3 ; FDE address range .byte 0x0 ; uleb128 0x0; Augmentation size diff --git a/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S b/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S index 3f6790f6bb39..c7734d419861 100644 --- a/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S +++ b/Modules/_ctypes/libffi/src/powerpc/darwin_closure.S @@ -192,7 +192,7 @@ LCFI1: lg r0,0(r3) ; size => r0 lhz r3,FFI_TYPE_TYPE(r3) ; type => r3 - /* The helper will have intercepted struture returns and inserted + /* The helper will have intercepted structure returns and inserted the caller`s destination address for structs returned by ref. */ /* r3 contains the return type so use it to look up in a table @@ -467,11 +467,6 @@ Lendcode: #define EH_FRAME_OFFSETA MODE_CHOICE(176,0x90) #define EH_FRAME_OFFSETB MODE_CHOICE(1,3) - .static_data - .align LOG2_GPR_BYTES -LLFB1$non_lazy_ptr: - .g_long Lstartcode - .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support EH_frame1: .set L$set$0,LECIE1-LSCIE1 @@ -484,7 +479,7 @@ LSCIE1: .byte EH_DATA_ALIGN_FACT ; sleb128 -4; CIE Data Alignment Factor .byte 0x41 ; CIE RA Column .byte 0x1 ; uleb128 0x1; Augmentation size - .byte 0x10 ; FDE Encoding (indirect pcrel) + .byte 0x10 ; FDE Encoding (pcrel) .byte 0xc ; DW_CFA_def_cfa .byte 0x1 ; uleb128 0x1 .byte 0x0 ; uleb128 0x0 @@ -498,7 +493,7 @@ LSFDE1: LASFDE1: .long LASFDE1-EH_frame1 ; FDE CIE offset - .g_long LLFB1$non_lazy_ptr-. ; FDE initial location + .g_long Lstartcode-. ; FDE initial location .set L$set$3,LFE1-Lstartcode .g_long L$set$3 ; FDE address range .byte 0x0 ; uleb128 0x0; Augmentation size @@ -523,12 +518,12 @@ LEFDE1: L_ffi_closure_helper_DARWIN$stub: .indirect_symbol _ffi_closure_helper_DARWIN mflr r0 - bcl 20,31,"L00000000001$spb" -"L00000000001$spb": + bcl 20,31,"L1$spb" +"L1$spb": mflr r11 - addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L00000000001$spb") + addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L1$spb") mtlr r0 - lwzu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L00000000001$spb")(r11) + lwzu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L1$spb")(r11) mtctr r12 bctr .lazy_symbol_pointer @@ -542,12 +537,12 @@ L_ffi_closure_helper_DARWIN$lazy_ptr: L_darwin64_struct_ret_by_value_p$stub: .indirect_symbol _darwin64_struct_ret_by_value_p mflr r0 - bcl 20,31,"L00000000002$spb" -"L00000000002$spb": + bcl 20,31,"L2$spb" +"L2$spb": mflr r11 - addis r11,r11,ha16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L00000000002$spb") + addis r11,r11,ha16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L2$spb") mtlr r0 - lwzu r12,lo16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L00000000002$spb")(r11) + lwzu r12,lo16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L2$spb")(r11) mtctr r12 bctr .lazy_symbol_pointer @@ -560,12 +555,12 @@ L_darwin64_struct_ret_by_value_p$lazy_ptr: L_darwin64_pass_struct_floats$stub: .indirect_symbol _darwin64_pass_struct_floats mflr r0 - bcl 20,31,"L00000000003$spb" -"L00000000003$spb": + bcl 20,31,"L3$spb" +"L3$spb": mflr r11 - addis r11,r11,ha16(L_darwin64_pass_struct_floats$lazy_ptr-"L00000000003$spb") + addis r11,r11,ha16(L_darwin64_pass_struct_floats$lazy_ptr-"L3$spb") mtlr r0 - lwzu r12,lo16(L_darwin64_pass_struct_floats$lazy_ptr-"L00000000003$spb")(r11) + lwzu r12,lo16(L_darwin64_pass_struct_floats$lazy_ptr-"L3$spb")(r11) mtctr r12 bctr .lazy_symbol_pointer diff --git a/Modules/_ctypes/libffi/src/powerpc/ffi.c b/Modules/_ctypes/libffi/src/powerpc/ffi.c index 5381d3d10d22..efb441bbfc03 100644 --- a/Modules/_ctypes/libffi/src/powerpc/ffi.c +++ b/Modules/_ctypes/libffi/src/powerpc/ffi.c @@ -1,5 +1,6 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (C) 2011 Anthony Green + ffi.c - Copyright (C) 2013 IBM + Copyright (C) 2011 Anthony Green Copyright (C) 2011 Kyle Moffett Copyright (C) 2008 Red Hat, Inc Copyright (C) 2007, 2008 Free Software Foundation, Inc @@ -27,993 +28,104 @@ OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ -#include -#include - -#include -#include - - -extern void ffi_closure_SYSV (void); -extern void FFI_HIDDEN ffi_closure_LINUX64 (void); - -enum { - /* The assembly depends on these exact flags. */ - FLAG_RETURNS_SMST = 1 << (31-31), /* Used for FFI_SYSV small structs. */ - FLAG_RETURNS_NOTHING = 1 << (31-30), /* These go in cr7 */ -#ifndef __NO_FPRS__ - FLAG_RETURNS_FP = 1 << (31-29), -#endif - FLAG_RETURNS_64BITS = 1 << (31-28), - - FLAG_RETURNS_128BITS = 1 << (31-27), /* cr6 */ - - FLAG_SYSV_SMST_R4 = 1 << (31-26), /* use r4 for FFI_SYSV 8 byte - structs. */ - FLAG_SYSV_SMST_R3 = 1 << (31-25), /* use r3 for FFI_SYSV 4 byte - structs. */ - - FLAG_ARG_NEEDS_COPY = 1 << (31- 7), -#ifndef __NO_FPRS__ - FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */ -#endif - FLAG_4_GPR_ARGUMENTS = 1 << (31- 5), - FLAG_RETVAL_REFERENCE = 1 << (31- 4) -}; - -/* About the SYSV ABI. */ -#define ASM_NEEDS_REGISTERS 4 -#define NUM_GPR_ARG_REGISTERS 8 -#ifndef __NO_FPRS__ -# define NUM_FPR_ARG_REGISTERS 8 -#endif - -/* ffi_prep_args_SYSV 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_SYSV 4bytes | higher addresses - |--------------------------------------------| - | Previous backchain pointer 4 | stack pointer here - |--------------------------------------------|<+ <<< on entry to - | Saved r28-r31 4*4 | | ffi_call_SYSV - |--------------------------------------------| | - | GPR registers r3-r10 8*4 | | ffi_call_SYSV - |--------------------------------------------| | - | FPR registers f1-f8 (optional) 8*8 | | - |--------------------------------------------| | stack | - | Space for copied structures | | grows | - |--------------------------------------------| | down V - | Parameters that didn't fit in registers | | - |--------------------------------------------| | lower addresses - | Space for callee's LR 4 | | - |--------------------------------------------| | stack pointer here - | Current backchain pointer 4 |-/ during - |--------------------------------------------| <<< ffi_call_SYSV - -*/ - -void -ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack) -{ - const unsigned bytes = ecif->cif->bytes; - const unsigned flags = ecif->cif->flags; - - typedef union { - char *c; - unsigned *u; - long long *ll; - float *f; - double *d; - } valp; - - /* 'stacktop' points at the previous backchain pointer. */ - valp stacktop; - - /* 'gpr_base' points at the space for gpr3, and grows upwards as - we use GPR registers. */ - valp gpr_base; - int intarg_count; - -#ifndef __NO_FPRS__ - /* 'fpr_base' points at the space for fpr1, and grows upwards as - we use FPR registers. */ - valp fpr_base; - int fparg_count; -#endif - - /* 'copy_space' grows down as we put structures in it. It should - stay 16-byte aligned. */ - valp copy_space; - - /* 'next_arg' grows up as we put parameters in it. */ - valp next_arg; - - int i; - ffi_type **ptr; - union { - void **v; - char **c; - signed char **sc; - unsigned char **uc; - signed short **ss; - unsigned short **us; - unsigned int **ui; - long long **ll; - float **f; - double **d; - } p_argv; - size_t struct_copy_size; - unsigned gprvalue; -#ifndef __NO_FPRS__ - double double_tmp; -#endif - - stacktop.c = (char *) stack + bytes; - gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS; - intarg_count = 0; -#ifndef __NO_FPRS__ - fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS; - fparg_count = 0; - copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c); -#else - copy_space.c = gpr_base.c; -#endif - next_arg.u = stack + 2; - - /* Check that everything starts aligned properly. */ - FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0); - FFI_ASSERT (((unsigned long) copy_space.c & 0xF) == 0); - FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0); - FFI_ASSERT ((bytes & 0xF) == 0); - FFI_ASSERT (copy_space.c >= next_arg.c); - - /* Deal with return values that are actually pass-by-reference. */ - if (flags & FLAG_RETVAL_REFERENCE) - { - *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue; - intarg_count++; - } - - /* Now for the arguments. */ - p_argv.v = ecif->avalue; - for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs; - i > 0; - i--, ptr++, p_argv.v++) - { - unsigned short typenum = (*ptr)->type; - - /* We may need to handle some values depending on ABI */ - if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT) { - if (typenum == FFI_TYPE_FLOAT) - typenum = FFI_TYPE_UINT32; - if (typenum == FFI_TYPE_DOUBLE) - typenum = FFI_TYPE_UINT64; - if (typenum == FFI_TYPE_LONGDOUBLE) - typenum = FFI_TYPE_UINT128; - } else if (ecif->cif->abi != FFI_LINUX) { -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - if (typenum == FFI_TYPE_LONGDOUBLE) - typenum = FFI_TYPE_STRUCT; -#endif - } - - /* Now test the translated value */ - switch (typenum) { -#ifndef __NO_FPRS__ - case FFI_TYPE_FLOAT: - /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32. */ - double_tmp = **p_argv.f; - if (fparg_count >= NUM_FPR_ARG_REGISTERS) - { - *next_arg.f = (float) double_tmp; - next_arg.u += 1; - intarg_count++; - } - else - *fpr_base.d++ = double_tmp; - fparg_count++; - FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); - break; - - case FFI_TYPE_DOUBLE: - /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64. */ - double_tmp = **p_argv.d; - - if (fparg_count >= NUM_FPR_ARG_REGISTERS) - { - if (intarg_count >= NUM_GPR_ARG_REGISTERS - && intarg_count % 2 != 0) - { - intarg_count++; - next_arg.u++; - } - *next_arg.d = double_tmp; - next_arg.u += 2; - } - else - *fpr_base.d++ = double_tmp; - fparg_count++; - FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); - break; - -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - double_tmp = (*p_argv.d)[0]; - - if (fparg_count >= NUM_FPR_ARG_REGISTERS - 1) - { - if (intarg_count >= NUM_GPR_ARG_REGISTERS - && intarg_count % 2 != 0) - { - intarg_count++; - next_arg.u++; - } - *next_arg.d = double_tmp; - next_arg.u += 2; - double_tmp = (*p_argv.d)[1]; - *next_arg.d = double_tmp; - next_arg.u += 2; - } - else - { - *fpr_base.d++ = double_tmp; - double_tmp = (*p_argv.d)[1]; - *fpr_base.d++ = double_tmp; - } - - fparg_count += 2; - FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); - break; -#endif -#endif /* have FPRs */ - - /* - * The soft float ABI for long doubles works like this, a long double - * is passed in four consecutive GPRs if available. A maximum of 2 - * long doubles can be passed in gprs. If we do not have 4 GPRs - * left, the long double is passed on the stack, 4-byte aligned. - */ - case FFI_TYPE_UINT128: { - unsigned int int_tmp = (*p_argv.ui)[0]; - unsigned int ii; - if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3) { - if (intarg_count < NUM_GPR_ARG_REGISTERS) - intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count; - *(next_arg.u++) = int_tmp; - for (ii = 1; ii < 4; ii++) { - int_tmp = (*p_argv.ui)[ii]; - *(next_arg.u++) = int_tmp; - } - } else { - *(gpr_base.u++) = int_tmp; - for (ii = 1; ii < 4; ii++) { - int_tmp = (*p_argv.ui)[ii]; - *(gpr_base.u++) = int_tmp; - } - } - intarg_count += 4; - break; - } - - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - if (intarg_count == NUM_GPR_ARG_REGISTERS-1) - intarg_count++; - if (intarg_count >= NUM_GPR_ARG_REGISTERS) - { - if (intarg_count % 2 != 0) - { - intarg_count++; - next_arg.u++; - } - *next_arg.ll = **p_argv.ll; - next_arg.u += 2; - } - else - { - /* whoops: abi states only certain register pairs - * can be used for passing long long int - * specifically (r3,r4), (r5,r6), (r7,r8), - * (r9,r10) and if next arg is long long but - * not correct starting register of pair then skip - * until the proper starting register - */ - if (intarg_count % 2 != 0) - { - intarg_count ++; - gpr_base.u++; - } - *gpr_base.ll++ = **p_argv.ll; - } - intarg_count += 2; - break; - - case FFI_TYPE_STRUCT: - struct_copy_size = ((*ptr)->size + 15) & ~0xF; - copy_space.c -= struct_copy_size; - memcpy (copy_space.c, *p_argv.c, (*ptr)->size); - - gprvalue = (unsigned long) copy_space.c; - - FFI_ASSERT (copy_space.c > next_arg.c); - FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY); - goto putgpr; - - case FFI_TYPE_UINT8: - gprvalue = **p_argv.uc; - goto putgpr; - case FFI_TYPE_SINT8: - gprvalue = **p_argv.sc; - goto putgpr; - case FFI_TYPE_UINT16: - gprvalue = **p_argv.us; - goto putgpr; - case FFI_TYPE_SINT16: - gprvalue = **p_argv.ss; - goto putgpr; - - case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - case FFI_TYPE_POINTER: - - gprvalue = **p_argv.ui; - - putgpr: - if (intarg_count >= NUM_GPR_ARG_REGISTERS) - *next_arg.u++ = gprvalue; - else - *gpr_base.u++ = gprvalue; - intarg_count++; - break; - } - } - - /* Check that we didn't overrun the stack... */ - FFI_ASSERT (copy_space.c >= next_arg.c); - FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS); - /* The assert below is testing that the number of integer arguments agrees - with the number found in ffi_prep_cif_machdep(). However, intarg_count - is incremeneted whenever we place an FP arg on the stack, so account for - that before our assert test. */ -#ifndef __NO_FPRS__ - if (fparg_count > NUM_FPR_ARG_REGISTERS) - intarg_count -= fparg_count - NUM_FPR_ARG_REGISTERS; - FFI_ASSERT (fpr_base.u - <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS); -#endif - FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4); -} - -/* About the LINUX64 ABI. */ -enum { - NUM_GPR_ARG_REGISTERS64 = 8, - NUM_FPR_ARG_REGISTERS64 = 13 -}; -enum { ASM_NEEDS_REGISTERS64 = 4 }; - -/* ffi_prep_args64 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: - - | Ret addr from ffi_call_LINUX64 8bytes | higher addresses - |--------------------------------------------| - | CR save area 8bytes | - |--------------------------------------------| - | Previous backchain pointer 8 | stack pointer here - |--------------------------------------------|<+ <<< on entry to - | Saved r28-r31 4*8 | | ffi_call_LINUX64 - |--------------------------------------------| | - | GPR registers r3-r10 8*8 | | - |--------------------------------------------| | - | FPR registers f1-f13 (optional) 13*8 | | - |--------------------------------------------| | - | Parameter save area | | - |--------------------------------------------| | - | TOC save area 8 | | - |--------------------------------------------| | stack | - | Linker doubleword 8 | | grows | - |--------------------------------------------| | down V - | Compiler doubleword 8 | | - |--------------------------------------------| | lower addresses - | Space for callee's LR 8 | | - |--------------------------------------------| | - | CR save area 8 | | - |--------------------------------------------| | stack pointer here - | Current backchain pointer 8 |-/ during - |--------------------------------------------| <<< ffi_call_LINUX64 - -*/ +#include "ffi.h" +#include "ffi_common.h" +#include "ffi_powerpc.h" +#if HAVE_LONG_DOUBLE_VARIANT +/* Adjust ffi_type_longdouble. */ void FFI_HIDDEN -ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack) +ffi_prep_types (ffi_abi abi) { - const unsigned long bytes = ecif->cif->bytes; - const unsigned long flags = ecif->cif->flags; - - typedef union { - char *c; - unsigned long *ul; - float *f; - double *d; - } valp; - - /* 'stacktop' points at the previous backchain pointer. */ - valp stacktop; - - /* 'next_arg' points at the space for gpr3, and grows upwards as - we use GPR registers, then continues at rest. */ - valp gpr_base; - valp gpr_end; - valp rest; - valp next_arg; - - /* 'fpr_base' points at the space for fpr3, and grows upwards as - we use FPR registers. */ - valp fpr_base; - int fparg_count; - - int i, words; - ffi_type **ptr; - double double_tmp; - union { - void **v; - char **c; - signed char **sc; - unsigned char **uc; - signed short **ss; - unsigned short **us; - signed int **si; - unsigned int **ui; - unsigned long **ul; - float **f; - double **d; - } p_argv; - unsigned long gprvalue; - - stacktop.c = (char *) stack + bytes; - gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64; - gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64; - rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64; - fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64; - fparg_count = 0; - next_arg.ul = gpr_base.ul; - - /* Check that everything starts aligned properly. */ - FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0); - FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0); - FFI_ASSERT ((bytes & 0xF) == 0); - - /* Deal with return values that are actually pass-by-reference. */ - if (flags & FLAG_RETVAL_REFERENCE) - *next_arg.ul++ = (unsigned long) (char *) ecif->rvalue; - - /* Now for the arguments. */ - p_argv.v = ecif->avalue; - for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs; - i > 0; - i--, ptr++, p_argv.v++) - { - switch ((*ptr)->type) - { - case FFI_TYPE_FLOAT: - double_tmp = **p_argv.f; - *next_arg.f = (float) double_tmp; - if (++next_arg.ul == gpr_end.ul) - next_arg.ul = rest.ul; - if (fparg_count < NUM_FPR_ARG_REGISTERS64) - *fpr_base.d++ = double_tmp; - fparg_count++; - FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); - break; - - case FFI_TYPE_DOUBLE: - double_tmp = **p_argv.d; - *next_arg.d = double_tmp; - if (++next_arg.ul == gpr_end.ul) - next_arg.ul = rest.ul; - if (fparg_count < NUM_FPR_ARG_REGISTERS64) - *fpr_base.d++ = double_tmp; - fparg_count++; - FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); - break; - -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - double_tmp = (*p_argv.d)[0]; - *next_arg.d = double_tmp; - if (++next_arg.ul == gpr_end.ul) - next_arg.ul = rest.ul; - if (fparg_count < NUM_FPR_ARG_REGISTERS64) - *fpr_base.d++ = double_tmp; - fparg_count++; - double_tmp = (*p_argv.d)[1]; - *next_arg.d = double_tmp; - if (++next_arg.ul == gpr_end.ul) - next_arg.ul = rest.ul; - if (fparg_count < NUM_FPR_ARG_REGISTERS64) - *fpr_base.d++ = double_tmp; - fparg_count++; - FFI_ASSERT (__LDBL_MANT_DIG__ == 106); - FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); - break; -#endif - - case FFI_TYPE_STRUCT: - words = ((*ptr)->size + 7) / 8; - if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul) - { - size_t first = gpr_end.c - next_arg.c; - memcpy (next_arg.c, *p_argv.c, first); - memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first); - next_arg.c = rest.c + words * 8 - first; - } - else - { - char *where = next_arg.c; - - /* Structures with size less than eight bytes are passed - left-padded. */ - if ((*ptr)->size < 8) - where += 8 - (*ptr)->size; - - memcpy (where, *p_argv.c, (*ptr)->size); - next_arg.ul += words; - if (next_arg.ul == gpr_end.ul) - next_arg.ul = rest.ul; - } - break; - - case FFI_TYPE_UINT8: - gprvalue = **p_argv.uc; - goto putgpr; - case FFI_TYPE_SINT8: - gprvalue = **p_argv.sc; - goto putgpr; - case FFI_TYPE_UINT16: - gprvalue = **p_argv.us; - goto putgpr; - case FFI_TYPE_SINT16: - gprvalue = **p_argv.ss; - goto putgpr; - case FFI_TYPE_UINT32: - gprvalue = **p_argv.ui; - goto putgpr; - case FFI_TYPE_INT: - case FFI_TYPE_SINT32: - gprvalue = **p_argv.si; - goto putgpr; - - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - case FFI_TYPE_POINTER: - gprvalue = **p_argv.ul; - putgpr: - *next_arg.ul++ = gprvalue; - if (next_arg.ul == gpr_end.ul) - next_arg.ul = rest.ul; - break; - } - } - - FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS - || (next_arg.ul >= gpr_base.ul - && next_arg.ul <= gpr_base.ul + 4)); +# if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE +# ifdef POWERPC64 + ffi_prep_types_linux64 (abi); +# else + ffi_prep_types_sysv (abi); +# endif +# endif } - - +#endif /* Perform machine dependent cif processing */ -ffi_status +ffi_status FFI_HIDDEN ffi_prep_cif_machdep (ffi_cif *cif) { - /* All this is for the SYSV and LINUX64 ABI. */ - int i; - ffi_type **ptr; - unsigned bytes; - int fparg_count = 0, intarg_count = 0; - unsigned flags = 0; - unsigned struct_copy_size = 0; - unsigned type = cif->rtype->type; - unsigned size = cif->rtype->size; - - if (cif->abi != FFI_LINUX64) - { - /* All the machine-independent calculation of cif->bytes will be wrong. - Redo the calculation for SYSV. */ - - /* Space for the frame pointer, callee's LR, and the asm's temp regs. */ - bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int); - - /* Space for the GPR registers. */ - bytes += NUM_GPR_ARG_REGISTERS * sizeof (int); - } - else - { - /* 64-bit ABI. */ - - /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp - regs. */ - bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long); - - /* Space for the mandatory parm save area and general registers. */ - bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long); - } - - /* Return value handling. The rules for SYSV 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; - - Larger structures are allocated space and a pointer is passed as - the first argument. - - long doubles (if not equivalent to double) are returned in - fpr1,fpr2 for Linux and as for large structs for SysV. - For LINUX64: - - integer values in gpr3; - - Structures/Unions by reference; - - Single/double FP values in fpr1, long double in fpr1,fpr2. - - soft-float float/doubles are treated as UINT32/UINT64 respectivley. - - soft-float long doubles are returned in gpr3-gpr6. */ - /* First translate for softfloat/nonlinux */ - if (cif->abi == FFI_LINUX_SOFT_FLOAT) { - if (type == FFI_TYPE_FLOAT) - type = FFI_TYPE_UINT32; - if (type == FFI_TYPE_DOUBLE) - type = FFI_TYPE_UINT64; - if (type == FFI_TYPE_LONGDOUBLE) - type = FFI_TYPE_UINT128; - } else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) { -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - if (type == FFI_TYPE_LONGDOUBLE) - type = FFI_TYPE_STRUCT; -#endif - } - - switch (type) - { -#ifndef __NO_FPRS__ -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - flags |= FLAG_RETURNS_128BITS; - /* Fall through. */ -#endif - case FFI_TYPE_DOUBLE: - flags |= FLAG_RETURNS_64BITS; - /* Fall through. */ - case FFI_TYPE_FLOAT: - flags |= FLAG_RETURNS_FP; - break; -#endif - - case FFI_TYPE_UINT128: - flags |= FLAG_RETURNS_128BITS; - /* Fall through. */ - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - flags |= FLAG_RETURNS_64BITS; - break; - - case FFI_TYPE_STRUCT: - if (cif->abi == FFI_SYSV) - { - /* The final SYSV ABI says that structures smaller or equal 8 bytes - are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them - in memory. */ - - /* Treat structs with size <= 8 bytes. */ - if (size <= 8) - { - flags |= FLAG_RETURNS_SMST; - /* These structs are returned in r3. We pack the type and the - precalculated shift value (needed in the sysv.S) into flags. - The same applies for the structs returned in r3/r4. */ - if (size <= 4) - { - flags |= FLAG_SYSV_SMST_R3; - flags |= 8 * (4 - size) << 8; - break; - } - /* These structs are returned in r3 and r4. See above. */ - if (size <= 8) - { - flags |= FLAG_SYSV_SMST_R3 | FLAG_SYSV_SMST_R4; - flags |= 8 * (8 - size) << 8; - break; - } - } - } - - intarg_count++; - flags |= FLAG_RETVAL_REFERENCE; - /* Fall through. */ - case FFI_TYPE_VOID: - flags |= FLAG_RETURNS_NOTHING; - break; - - default: - /* Returns 32-bit integer, or similar. Nothing to do here. */ - break; - } - - if (cif->abi != FFI_LINUX64) - /* 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 and long doubles (if not equivalent - to double) 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++) - { - unsigned short typenum = (*ptr)->type; - - /* We may need to handle some values depending on ABI */ - if (cif->abi == FFI_LINUX_SOFT_FLOAT) { - if (typenum == FFI_TYPE_FLOAT) - typenum = FFI_TYPE_UINT32; - if (typenum == FFI_TYPE_DOUBLE) - typenum = FFI_TYPE_UINT64; - if (typenum == FFI_TYPE_LONGDOUBLE) - typenum = FFI_TYPE_UINT128; - } else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) { -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - if (typenum == FFI_TYPE_LONGDOUBLE) - typenum = FFI_TYPE_STRUCT; -#endif - } - - switch (typenum) { -#ifndef __NO_FPRS__ - case FFI_TYPE_FLOAT: - fparg_count++; - /* floating singles are not 8-aligned on stack */ - break; - -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - fparg_count++; - /* Fall thru */ -#endif - 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 >= NUM_GPR_ARG_REGISTERS - && intarg_count % 2 != 0) - intarg_count++; - break; -#endif - case FFI_TYPE_UINT128: - /* - * A long double in FFI_LINUX_SOFT_FLOAT can use only a set - * of four consecutive gprs. If we do not have enough, we - * have to adjust the intarg_count value. - */ - if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3 - && intarg_count < NUM_GPR_ARG_REGISTERS) - intarg_count = NUM_GPR_ARG_REGISTERS; - intarg_count += 4; - break; - - 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. - - Also, only certain register pairs can be used for - passing long long int -- specifically (r3,r4), (r5,r6), - (r7,r8), (r9,r10). - */ - if (intarg_count == NUM_GPR_ARG_REGISTERS-1 - || intarg_count % 2 != 0) - intarg_count++; - intarg_count += 2; - break; - - case FFI_TYPE_STRUCT: - /* We must allocate space for a copy of these to enforce - pass-by-value. Pad the space up to a multiple of 16 - bytes (the maximum alignment required for anything under - the SYSV ABI). */ - struct_copy_size += ((*ptr)->size + 15) & ~0xF; - /* Fall through (allocate space for the pointer). */ - - case FFI_TYPE_POINTER: - case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - /* Everything else is passed as a 4-byte word in a GPR, either - the object itself or a pointer to it. */ - intarg_count++; - break; - default: - FFI_ASSERT (0); - } - } - else - for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) - { - switch ((*ptr)->type) - { -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - if (cif->abi == FFI_LINUX_SOFT_FLOAT) - intarg_count += 4; - else - { - fparg_count += 2; - intarg_count += 2; - } - break; -#endif - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - fparg_count++; - intarg_count++; - break; - - case FFI_TYPE_STRUCT: - intarg_count += ((*ptr)->size + 7) / 8; - break; - - case FFI_TYPE_POINTER: - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - /* Everything else is passed as a 8-byte word in a GPR, either - the object itself or a pointer to it. */ - intarg_count++; - break; - default: - FFI_ASSERT (0); - } - } - -#ifndef __NO_FPRS__ - if (fparg_count != 0) - flags |= FLAG_FP_ARGUMENTS; -#endif - if (intarg_count > 4) - flags |= FLAG_4_GPR_ARGUMENTS; - if (struct_copy_size != 0) - flags |= FLAG_ARG_NEEDS_COPY; - - if (cif->abi != FFI_LINUX64) - { -#ifndef __NO_FPRS__ - /* Space for the FPR registers, if needed. */ - if (fparg_count != 0) - bytes += NUM_FPR_ARG_REGISTERS * sizeof (double); +#ifdef POWERPC64 + return ffi_prep_cif_linux64 (cif); +#else + return ffi_prep_cif_sysv (cif); #endif +} - /* Stack space. */ - if (intarg_count > NUM_GPR_ARG_REGISTERS) - bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int); -#ifndef __NO_FPRS__ - if (fparg_count > NUM_FPR_ARG_REGISTERS) - bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double); -#endif - } - else - { -#ifndef __NO_FPRS__ - /* Space for the FPR registers, if needed. */ - if (fparg_count != 0) - bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double); +ffi_status FFI_HIDDEN +ffi_prep_cif_machdep_var (ffi_cif *cif, + unsigned int nfixedargs MAYBE_UNUSED, + unsigned int ntotalargs MAYBE_UNUSED) +{ +#ifdef POWERPC64 + return ffi_prep_cif_linux64_var (cif, nfixedargs, ntotalargs); +#else + return ffi_prep_cif_sysv (cif); #endif - - /* Stack space. */ - if (intarg_count > NUM_GPR_ARG_REGISTERS64) - bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long); - } - - /* The stack space allocated needs to be a multiple of 16 bytes. */ - bytes = (bytes + 15) & ~0xF; - - /* Add in the space for the copied structures. */ - bytes += struct_copy_size; - - cif->flags = flags; - cif->bytes = bytes; - - return FFI_OK; } -extern void ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *, - void (*fn)(void)); -extern void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long, - unsigned long, unsigned long *, - void (*fn)(void)); - void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) { - /* - * The final SYSV ABI says that structures smaller or equal 8 bytes - * are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them - * in memory. - * - * Just to keep things simple for the assembly code, we will always - * bounce-buffer struct return values less than or equal to 8 bytes. - * This allows the ASM to handle SYSV small structures by directly - * writing r3 and r4 to memory without worrying about struct size. - */ - unsigned int smst_buffer[2]; + /* The final SYSV ABI says that structures smaller or equal 8 bytes + are returned in r3/r4. A draft ABI used by linux instead returns + them in memory. + + We bounce-buffer SYSV small struct return values so that sysv.S + can write r3 and r4 to memory without worrying about struct size. + + For ELFv2 ABI, use a bounce buffer for homogeneous structs too, + for similar reasons. */ + unsigned long smst_buffer[8]; extended_cif ecif; - unsigned int rsize = 0; ecif.cif = cif; ecif.avalue = avalue; - /* Ensure that we have a valid struct return value */ ecif.rvalue = rvalue; - if (cif->rtype->type == FFI_TYPE_STRUCT) { - rsize = cif->rtype->size; - if (rsize <= 8) - ecif.rvalue = smst_buffer; - else if (!rvalue) - ecif.rvalue = alloca(rsize); - } + if ((cif->flags & FLAG_RETURNS_SMST) != 0) + ecif.rvalue = smst_buffer; + /* Ensure that we have a valid struct return value. + FIXME: Isn't this just papering over a user problem? */ + else if (!rvalue && cif->rtype->type == FFI_TYPE_STRUCT) + ecif.rvalue = alloca (cif->rtype->size); - switch (cif->abi) - { -#ifndef POWERPC64 -# ifndef __NO_FPRS__ - case FFI_SYSV: - case FFI_GCC_SYSV: - case FFI_LINUX: -# endif - case FFI_LINUX_SOFT_FLOAT: - ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn); - break; +#ifdef POWERPC64 + ffi_call_LINUX64 (&ecif, -(long) cif->bytes, cif->flags, ecif.rvalue, fn); #else - case FFI_LINUX64: - ffi_call_LINUX64 (&ecif, -(long) cif->bytes, cif->flags, ecif.rvalue, fn); - break; + ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn); #endif - default: - FFI_ASSERT (0); - break; - } /* Check for a bounce-buffered return value */ if (rvalue && ecif.rvalue == smst_buffer) - memcpy(rvalue, smst_buffer, rsize); + { + unsigned int rsize = cif->rtype->size; +#ifndef __LITTLE_ENDIAN__ + /* The SYSV ABI returns a structure of up to 4 bytes in size + left-padded in r3. */ +# ifndef POWERPC64 + if (rsize <= 4) + memcpy (rvalue, (char *) smst_buffer + 4 - rsize, rsize); + else +# endif + /* The SYSV ABI returns a structure of up to 8 bytes in size + left-padded in r3/r4, and the ELFv2 ABI similarly returns a + structure of up to 8 bytes in size left-padded in r3. */ + if (rsize <= 8) + memcpy (rvalue, (char *) smst_buffer + 8 - rsize, rsize); + else +#endif + memcpy (rvalue, smst_buffer, rsize); + } } -#ifndef POWERPC64 -#define MIN_CACHE_LINE_SIZE 8 - -static void -flush_icache (char *wraddr, char *xaddr, int size) -{ - int i; - for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) - __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" - : : "r" (xaddr + i), "r" (wraddr + i) : "memory"); - __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;" - : : "r"(xaddr + size - 1), "r"(wraddr + size - 1) - : "memory"); -} -#endif - ffi_status ffi_prep_closure_loc (ffi_closure *closure, ffi_cif *cif, @@ -1022,480 +134,8 @@ ffi_prep_closure_loc (ffi_closure *closure, void *codeloc) { #ifdef POWERPC64 - void **tramp = (void **) &closure->tramp[0]; - - if (cif->abi != FFI_LINUX64) - return FFI_BAD_ABI; - /* Copy function address and TOC from ffi_closure_LINUX64. */ - memcpy (tramp, (char *) ffi_closure_LINUX64, 16); - tramp[2] = codeloc; + return ffi_prep_closure_loc_linux64 (closure, cif, fun, user_data, codeloc); #else - unsigned int *tramp; - - if (! (cif->abi == FFI_GCC_SYSV - || cif->abi == FFI_SYSV - || cif->abi == FFI_LINUX - || cif->abi == FFI_LINUX_SOFT_FLOAT)) - return FFI_BAD_ABI; - - tramp = (unsigned int *) &closure->tramp[0]; - tramp[0] = 0x7c0802a6; /* mflr r0 */ - tramp[1] = 0x4800000d; /* bl 10 */ - tramp[4] = 0x7d6802a6; /* mflr r11 */ - tramp[5] = 0x7c0803a6; /* mtlr r0 */ - tramp[6] = 0x800b0000; /* lwz r0,0(r11) */ - tramp[7] = 0x816b0004; /* lwz r11,4(r11) */ - tramp[8] = 0x7c0903a6; /* mtctr r0 */ - tramp[9] = 0x4e800420; /* bctr */ - *(void **) &tramp[2] = (void *) ffi_closure_SYSV; /* function */ - *(void **) &tramp[3] = codeloc; /* context */ - - /* Flush the icache. */ - flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE); -#endif - - closure->cif = cif; - closure->fun = fun; - closure->user_data = user_data; - - return FFI_OK; -} - -typedef union -{ - float f; - double d; -} ffi_dblfl; - -int ffi_closure_helper_SYSV (ffi_closure *, void *, unsigned long *, - ffi_dblfl *, unsigned long *); - -/* Basically the trampoline invokes ffi_closure_SYSV, 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_SYSV invokes the - * following helper function to do most of the work - */ - -int -ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, - unsigned long *pgr, ffi_dblfl *pfr, - unsigned long *pst) -{ - /* 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_SYSV */ - /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV */ - /* pst is the pointer to outgoing parameter stack in original caller */ - - void ** avalue; - ffi_type ** arg_types; - long i, avn; -#ifndef __NO_FPRS__ - long nf = 0; /* number of floating registers already used */ -#endif - long ng = 0; /* number of general registers already used */ - - ffi_cif *cif = closure->cif; - unsigned size = cif->rtype->size; - unsigned short rtypenum = cif->rtype->type; - - avalue = alloca (cif->nargs * sizeof (void *)); - - /* First translate for softfloat/nonlinux */ - if (cif->abi == FFI_LINUX_SOFT_FLOAT) { - if (rtypenum == FFI_TYPE_FLOAT) - rtypenum = FFI_TYPE_UINT32; - if (rtypenum == FFI_TYPE_DOUBLE) - rtypenum = FFI_TYPE_UINT64; - if (rtypenum == FFI_TYPE_LONGDOUBLE) - rtypenum = FFI_TYPE_UINT128; - } else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) { -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - if (rtypenum == FFI_TYPE_LONGDOUBLE) - rtypenum = FFI_TYPE_STRUCT; + return ffi_prep_closure_loc_sysv (closure, cif, fun, user_data, codeloc); #endif - } - - - /* Copy the caller's structure return value address so that the closure - returns the data directly to the caller. - For FFI_SYSV the result is passed in r3/r4 if the struct size is less - or equal 8 bytes. */ - if (rtypenum == FFI_TYPE_STRUCT && ((cif->abi != FFI_SYSV) || (size > 8))) { - rvalue = (void *) *pgr; - ng++; - pgr++; - } - - i = 0; - avn = cif->nargs; - arg_types = cif->arg_types; - - /* Grab the addresses of the arguments from the stack frame. */ - while (i < avn) { - unsigned short typenum = arg_types[i]->type; - - /* We may need to handle some values depending on ABI */ - if (cif->abi == FFI_LINUX_SOFT_FLOAT) { - if (typenum == FFI_TYPE_FLOAT) - typenum = FFI_TYPE_UINT32; - if (typenum == FFI_TYPE_DOUBLE) - typenum = FFI_TYPE_UINT64; - if (typenum == FFI_TYPE_LONGDOUBLE) - typenum = FFI_TYPE_UINT128; - } else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) { -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - if (typenum == FFI_TYPE_LONGDOUBLE) - typenum = FFI_TYPE_STRUCT; -#endif - } - - switch (typenum) { -#ifndef __NO_FPRS__ - case FFI_TYPE_FLOAT: - /* unfortunately float values are stored as doubles - * in the ffi_closure_SYSV code (since we don't check - * the type in that routine). - */ - - /* there are 8 64bit floating point registers */ - - if (nf < 8) - { - double temp = pfr->d; - pfr->f = (float) temp; - avalue[i] = pfr; - nf++; - pfr++; - } - else - { - /* FIXME? here we are really changing the values - * stored in the original calling routines outgoing - * parameter stack. This is probably a really - * naughty thing to do but... - */ - avalue[i] = pst; - pst += 1; - } - break; - - case FFI_TYPE_DOUBLE: - /* On the outgoing stack all values are aligned to 8 */ - /* there are 8 64bit floating point registers */ - - if (nf < 8) - { - avalue[i] = pfr; - nf++; - pfr++; - } - else - { - if (((long) pst) & 4) - pst++; - avalue[i] = pst; - pst += 2; - } - break; - -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - if (nf < 7) - { - avalue[i] = pfr; - pfr += 2; - nf += 2; - } - else - { - if (((long) pst) & 4) - pst++; - avalue[i] = pst; - pst += 4; - nf = 8; - } - break; -#endif -#endif /* have FPRS */ - - case FFI_TYPE_UINT128: - /* - * Test if for the whole long double, 4 gprs are available. - * otherwise the stuff ends up on the stack. - */ - if (ng < 5) { - avalue[i] = pgr; - pgr += 4; - ng += 4; - } else { - avalue[i] = pst; - pst += 4; - ng = 8+4; - } - break; - - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT8: - /* there are 8 gpr registers used to pass values */ - if (ng < 8) - { - avalue[i] = (char *) pgr + 3; - ng++; - pgr++; - } - else - { - avalue[i] = (char *) pst + 3; - pst++; - } - break; - - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT16: - /* there are 8 gpr registers used to pass values */ - if (ng < 8) - { - avalue[i] = (char *) pgr + 2; - ng++; - pgr++; - } - else - { - avalue[i] = (char *) pst + 2; - pst++; - } - break; - - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT32: - case FFI_TYPE_POINTER: - /* there are 8 gpr registers used to pass values */ - if (ng < 8) - { - avalue[i] = pgr; - ng++; - pgr++; - } - else - { - avalue[i] = pst; - pst++; - } - break; - - case FFI_TYPE_STRUCT: - /* Structs are passed by reference. The address will appear in a - gpr if it is one of the first 8 arguments. */ - if (ng < 8) - { - avalue[i] = (void *) *pgr; - ng++; - pgr++; - } - else - { - avalue[i] = (void *) *pst; - pst++; - } - break; - - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - /* passing long long ints are complex, they must - * be passed in suitable register pairs such as - * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10) - * and if the entire pair aren't available then the outgoing - * parameter stack is used for both but an alignment of 8 - * must will be kept. So we must either look in pgr - * or pst to find the correct address for this type - * of parameter. - */ - if (ng < 7) - { - if (ng & 0x01) - { - /* skip r4, r6, r8 as starting points */ - ng++; - pgr++; - } - avalue[i] = pgr; - ng += 2; - pgr += 2; - } - else - { - if (((long) pst) & 4) - pst++; - avalue[i] = pst; - pst += 2; - ng = 8; - } - break; - - default: - FFI_ASSERT (0); - } - - i++; - } - - - (closure->fun) (cif, rvalue, avalue, closure->user_data); - - /* Tell ffi_closure_SYSV how to perform return type promotions. - Because the FFI_SYSV ABI returns the structures <= 8 bytes in r3/r4 - we have to tell ffi_closure_SYSV how to treat them. We combine the base - type FFI_SYSV_TYPE_SMALL_STRUCT - 1 with the size of the struct. - So a one byte struct gets the return type 16. Return type 1 to 15 are - already used and we never have a struct with size zero. That is the reason - for the subtraction of 1. See the comment in ffitarget.h about ordering. - */ - if (cif->abi == FFI_SYSV && rtypenum == FFI_TYPE_STRUCT && size <= 8) - return (FFI_SYSV_TYPE_SMALL_STRUCT - 1) + size; - return rtypenum; -} - -int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *, - unsigned long *, ffi_dblfl *); - -int FFI_HIDDEN -ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue, - unsigned long *pst, ffi_dblfl *pfr) -{ - /* rvalue is the pointer to space for return value in closure assembly */ - /* pst is the pointer to parameter save area - (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */ - /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */ - - void **avalue; - ffi_type **arg_types; - long i, avn; - ffi_cif *cif; - ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64; - - cif = closure->cif; - avalue = alloca (cif->nargs * sizeof (void *)); - - /* Copy the caller's structure return value address so that the closure - returns the data directly to the caller. */ - if (cif->rtype->type == FFI_TYPE_STRUCT) - { - rvalue = (void *) *pst; - pst++; - } - - i = 0; - avn = cif->nargs; - arg_types = cif->arg_types; - - /* Grab the addresses of the arguments from the stack frame. */ - while (i < avn) - { - switch (arg_types[i]->type) - { - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT8: - avalue[i] = (char *) pst + 7; - pst++; - break; - - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT16: - avalue[i] = (char *) pst + 6; - pst++; - break; - - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT32: - avalue[i] = (char *) pst + 4; - pst++; - break; - - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - case FFI_TYPE_POINTER: - avalue[i] = pst; - pst++; - break; - - case FFI_TYPE_STRUCT: - /* Structures with size less than eight bytes are passed - left-padded. */ - if (arg_types[i]->size < 8) - avalue[i] = (char *) pst + 8 - arg_types[i]->size; - else - avalue[i] = pst; - pst += (arg_types[i]->size + 7) / 8; - break; - - case FFI_TYPE_FLOAT: - /* unfortunately float values are stored as doubles - * in the ffi_closure_LINUX64 code (since we don't check - * the type in that routine). - */ - - /* there are 13 64bit floating point registers */ - - if (pfr < end_pfr) - { - double temp = pfr->d; - pfr->f = (float) temp; - avalue[i] = pfr; - pfr++; - } - else - avalue[i] = pst; - pst++; - break; - - case FFI_TYPE_DOUBLE: - /* On the outgoing stack all values are aligned to 8 */ - /* there are 13 64bit floating point registers */ - - if (pfr < end_pfr) - { - avalue[i] = pfr; - pfr++; - } - else - avalue[i] = pst; - pst++; - break; - -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - if (pfr + 1 < end_pfr) - { - avalue[i] = pfr; - pfr += 2; - } - else - { - if (pfr < end_pfr) - { - /* Passed partly in f13 and partly on the stack. - Move it all to the stack. */ - *pst = *(unsigned long *) pfr; - pfr++; - } - avalue[i] = pst; - } - pst += 2; - break; -#endif - - default: - FFI_ASSERT (0); - } - - i++; - } - - - (closure->fun) (cif, rvalue, avalue, closure->user_data); - - /* Tell ffi_closure_LINUX64 how to perform return type promotions. */ - return cif->rtype->type; } diff --git a/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c b/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c index 1d1d48c2ec33..cf6fb6d4b7ca 100644 --- a/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c +++ b/Modules/_ctypes/libffi/src/powerpc/ffi_darwin.c @@ -593,7 +593,7 @@ darwin_adjust_aggregate_sizes (ffi_type *s) /* Natural alignment for all items. */ align = p->alignment; #else - /* Natrual alignment for the first item... */ + /* Natural alignment for the first item... */ if (i == 0) align = p->alignment; else if (p->alignment == 16 || p->alignment < 4) diff --git a/Modules/_ctypes/libffi/src/powerpc/ffi_linux64.c b/Modules/_ctypes/libffi/src/powerpc/ffi_linux64.c new file mode 100644 index 000000000000..b087af8c607b --- /dev/null +++ b/Modules/_ctypes/libffi/src/powerpc/ffi_linux64.c @@ -0,0 +1,943 @@ +/* ----------------------------------------------------------------------- + ffi_linux64.c - Copyright (C) 2013 IBM + Copyright (C) 2011 Anthony Green + Copyright (C) 2011 Kyle Moffett + Copyright (C) 2008 Red Hat, Inc + Copyright (C) 2007, 2008 Free Software Foundation, Inc + Copyright (c) 1998 Geoffrey Keating + + PowerPC 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 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 "ffi.h" + +#ifdef POWERPC64 +#include "ffi_common.h" +#include "ffi_powerpc.h" + + +/* About the LINUX64 ABI. */ +enum { + NUM_GPR_ARG_REGISTERS64 = 8, + NUM_FPR_ARG_REGISTERS64 = 13 +}; +enum { ASM_NEEDS_REGISTERS64 = 4 }; + + +#if HAVE_LONG_DOUBLE_VARIANT && FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE +/* Adjust size of ffi_type_longdouble. */ +void FFI_HIDDEN +ffi_prep_types_linux64 (ffi_abi abi) +{ + if ((abi & (FFI_LINUX | FFI_LINUX_LONG_DOUBLE_128)) == FFI_LINUX) + { + ffi_type_longdouble.size = 8; + ffi_type_longdouble.alignment = 8; + } + else + { + ffi_type_longdouble.size = 16; + ffi_type_longdouble.alignment = 16; + } +} +#endif + + +#if _CALL_ELF == 2 +static unsigned int +discover_homogeneous_aggregate (const ffi_type *t, unsigned int *elnum) +{ + switch (t->type) + { + case FFI_TYPE_FLOAT: + case FFI_TYPE_DOUBLE: + *elnum = 1; + return (int) t->type; + + case FFI_TYPE_STRUCT:; + { + unsigned int base_elt = 0, total_elnum = 0; + ffi_type **el = t->elements; + while (*el) + { + unsigned int el_elt, el_elnum = 0; + el_elt = discover_homogeneous_aggregate (*el, &el_elnum); + if (el_elt == 0 + || (base_elt && base_elt != el_elt)) + return 0; + base_elt = el_elt; + total_elnum += el_elnum; + if (total_elnum > 8) + return 0; + el++; + } + *elnum = total_elnum; + return base_elt; + } + + default: + return 0; + } +} +#endif + + +/* Perform machine dependent cif processing */ +static ffi_status +ffi_prep_cif_linux64_core (ffi_cif *cif) +{ + ffi_type **ptr; + unsigned bytes; + unsigned i, fparg_count = 0, intarg_count = 0; + unsigned flags = cif->flags; +#if _CALL_ELF == 2 + unsigned int elt, elnum; +#endif + +#if FFI_TYPE_LONGDOUBLE == FFI_TYPE_DOUBLE + /* If compiled without long double support.. */ + if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0) + return FFI_BAD_ABI; +#endif + + /* The machine-independent calculation of cif->bytes doesn't work + for us. Redo the calculation. */ +#if _CALL_ELF == 2 + /* Space for backchain, CR, LR, TOC and the asm's temp regs. */ + bytes = (4 + ASM_NEEDS_REGISTERS64) * sizeof (long); + + /* Space for the general registers. */ + bytes += NUM_GPR_ARG_REGISTERS64 * sizeof (long); +#else + /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp + regs. */ + bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long); + + /* Space for the mandatory parm save area and general registers. */ + bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long); +#endif + + /* Return value handling. */ + switch (cif->rtype->type) + { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0) + flags |= FLAG_RETURNS_128BITS; + /* Fall through. */ +#endif + case FFI_TYPE_DOUBLE: + flags |= FLAG_RETURNS_64BITS; + /* Fall through. */ + case FFI_TYPE_FLOAT: + flags |= FLAG_RETURNS_FP; + break; + + case FFI_TYPE_UINT128: + flags |= FLAG_RETURNS_128BITS; + /* Fall through. */ + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + flags |= FLAG_RETURNS_64BITS; + break; + + case FFI_TYPE_STRUCT: +#if _CALL_ELF == 2 + elt = discover_homogeneous_aggregate (cif->rtype, &elnum); + if (elt) + { + if (elt == FFI_TYPE_DOUBLE) + flags |= FLAG_RETURNS_64BITS; + flags |= FLAG_RETURNS_FP | FLAG_RETURNS_SMST; + break; + } + if (cif->rtype->size <= 16) + { + flags |= FLAG_RETURNS_SMST; + break; + } +#endif + intarg_count++; + flags |= FLAG_RETVAL_REFERENCE; + /* Fall through. */ + case FFI_TYPE_VOID: + flags |= FLAG_RETURNS_NOTHING; + break; + + default: + /* Returns 32-bit integer, or similar. Nothing to do here. */ + break; + } + + for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) + { + unsigned int align; + + switch ((*ptr)->type) + { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0) + { + fparg_count++; + intarg_count++; + } + /* Fall through. */ +#endif + case FFI_TYPE_DOUBLE: + case FFI_TYPE_FLOAT: + fparg_count++; + intarg_count++; + if (fparg_count > NUM_FPR_ARG_REGISTERS64) + flags |= FLAG_ARG_NEEDS_PSAVE; + break; + + case FFI_TYPE_STRUCT: + if ((cif->abi & FFI_LINUX_STRUCT_ALIGN) != 0) + { + align = (*ptr)->alignment; + if (align > 16) + align = 16; + align = align / 8; + if (align > 1) + intarg_count = ALIGN (intarg_count, align); + } + intarg_count += ((*ptr)->size + 7) / 8; +#if _CALL_ELF == 2 + elt = discover_homogeneous_aggregate (*ptr, &elnum); + if (elt) + { + fparg_count += elnum; + if (fparg_count > NUM_FPR_ARG_REGISTERS64) + flags |= FLAG_ARG_NEEDS_PSAVE; + } + else +#endif + { + if (intarg_count > NUM_GPR_ARG_REGISTERS64) + flags |= FLAG_ARG_NEEDS_PSAVE; + } + break; + + case FFI_TYPE_POINTER: + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + /* Everything else is passed as a 8-byte word in a GPR, either + the object itself or a pointer to it. */ + intarg_count++; + if (intarg_count > NUM_GPR_ARG_REGISTERS64) + flags |= FLAG_ARG_NEEDS_PSAVE; + break; + default: + FFI_ASSERT (0); + } + } + + if (fparg_count != 0) + flags |= FLAG_FP_ARGUMENTS; + if (intarg_count > 4) + flags |= FLAG_4_GPR_ARGUMENTS; + + /* Space for the FPR registers, if needed. */ + if (fparg_count != 0) + bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double); + + /* Stack space. */ +#if _CALL_ELF == 2 + if ((flags & FLAG_ARG_NEEDS_PSAVE) != 0) + bytes += intarg_count * sizeof (long); +#else + if (intarg_count > NUM_GPR_ARG_REGISTERS64) + bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long); +#endif + + /* The stack space allocated needs to be a multiple of 16 bytes. */ + bytes = (bytes + 15) & ~0xF; + + cif->flags = flags; + cif->bytes = bytes; + + return FFI_OK; +} + +ffi_status FFI_HIDDEN +ffi_prep_cif_linux64 (ffi_cif *cif) +{ + if ((cif->abi & FFI_LINUX) != 0) + cif->nfixedargs = cif->nargs; +#if _CALL_ELF != 2 + else if (cif->abi == FFI_COMPAT_LINUX64) + { + /* This call is from old code. Don't touch cif->nfixedargs + since old code will be using a smaller cif. */ + cif->flags |= FLAG_COMPAT; + /* Translate to new abi value. */ + cif->abi = FFI_LINUX | FFI_LINUX_LONG_DOUBLE_128; + } +#endif + else + return FFI_BAD_ABI; + return ffi_prep_cif_linux64_core (cif); +} + +ffi_status FFI_HIDDEN +ffi_prep_cif_linux64_var (ffi_cif *cif, + unsigned int nfixedargs, + unsigned int ntotalargs MAYBE_UNUSED) +{ + if ((cif->abi & FFI_LINUX) != 0) + cif->nfixedargs = nfixedargs; +#if _CALL_ELF != 2 + else if (cif->abi == FFI_COMPAT_LINUX64) + { + /* This call is from old code. Don't touch cif->nfixedargs + since old code will be using a smaller cif. */ + cif->flags |= FLAG_COMPAT; + /* Translate to new abi value. */ + cif->abi = FFI_LINUX | FFI_LINUX_LONG_DOUBLE_128; + } +#endif + else + return FFI_BAD_ABI; +#if _CALL_ELF == 2 + cif->flags |= FLAG_ARG_NEEDS_PSAVE; +#endif + return ffi_prep_cif_linux64_core (cif); +} + + +/* ffi_prep_args64 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: + + | Ret addr from ffi_call_LINUX64 8bytes | higher addresses + |--------------------------------------------| + | CR save area 8bytes | + |--------------------------------------------| + | Previous backchain pointer 8 | stack pointer here + |--------------------------------------------|<+ <<< on entry to + | Saved r28-r31 4*8 | | ffi_call_LINUX64 + |--------------------------------------------| | + | GPR registers r3-r10 8*8 | | + |--------------------------------------------| | + | FPR registers f1-f13 (optional) 13*8 | | + |--------------------------------------------| | + | Parameter save area | | + |--------------------------------------------| | + | TOC save area 8 | | + |--------------------------------------------| | stack | + | Linker doubleword 8 | | grows | + |--------------------------------------------| | down V + | Compiler doubleword 8 | | + |--------------------------------------------| | lower addresses + | Space for callee's LR 8 | | + |--------------------------------------------| | + | CR save area 8 | | + |--------------------------------------------| | stack pointer here + | Current backchain pointer 8 |-/ during + |--------------------------------------------| <<< ffi_call_LINUX64 + +*/ + +void FFI_HIDDEN +ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack) +{ + const unsigned long bytes = ecif->cif->bytes; + const unsigned long flags = ecif->cif->flags; + + typedef union + { + char *c; + unsigned long *ul; + float *f; + double *d; + size_t p; + } valp; + + /* 'stacktop' points at the previous backchain pointer. */ + valp stacktop; + + /* 'next_arg' points at the space for gpr3, and grows upwards as + we use GPR registers, then continues at rest. */ + valp gpr_base; + valp gpr_end; + valp rest; + valp next_arg; + + /* 'fpr_base' points at the space for fpr3, and grows upwards as + we use FPR registers. */ + valp fpr_base; + unsigned int fparg_count; + + unsigned int i, words, nargs, nfixedargs; + ffi_type **ptr; + double double_tmp; + union + { + void **v; + char **c; + signed char **sc; + unsigned char **uc; + signed short **ss; + unsigned short **us; + signed int **si; + unsigned int **ui; + unsigned long **ul; + float **f; + double **d; + } p_argv; + unsigned long gprvalue; + unsigned long align; + + stacktop.c = (char *) stack + bytes; + gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64; + gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64; +#if _CALL_ELF == 2 + rest.ul = stack + 4 + NUM_GPR_ARG_REGISTERS64; +#else + rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64; +#endif + fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64; + fparg_count = 0; + next_arg.ul = gpr_base.ul; + + /* Check that everything starts aligned properly. */ + FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0); + FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0); + FFI_ASSERT ((bytes & 0xF) == 0); + + /* Deal with return values that are actually pass-by-reference. */ + if (flags & FLAG_RETVAL_REFERENCE) + *next_arg.ul++ = (unsigned long) (char *) ecif->rvalue; + + /* Now for the arguments. */ + p_argv.v = ecif->avalue; + nargs = ecif->cif->nargs; +#if _CALL_ELF != 2 + nfixedargs = (unsigned) -1; + if ((flags & FLAG_COMPAT) == 0) +#endif + nfixedargs = ecif->cif->nfixedargs; + for (ptr = ecif->cif->arg_types, i = 0; + i < nargs; + i++, ptr++, p_argv.v++) + { +#if _CALL_ELF == 2 + unsigned int elt, elnum; +#endif + + switch ((*ptr)->type) + { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + if ((ecif->cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0) + { + double_tmp = (*p_argv.d)[0]; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + { + *fpr_base.d++ = double_tmp; +# if _CALL_ELF != 2 + if ((flags & FLAG_COMPAT) != 0) + *next_arg.d = double_tmp; +# endif + } + else + *next_arg.d = double_tmp; + if (++next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + fparg_count++; + double_tmp = (*p_argv.d)[1]; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + { + *fpr_base.d++ = double_tmp; +# if _CALL_ELF != 2 + if ((flags & FLAG_COMPAT) != 0) + *next_arg.d = double_tmp; +# endif + } + else + *next_arg.d = double_tmp; + if (++next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + fparg_count++; + FFI_ASSERT (__LDBL_MANT_DIG__ == 106); + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + break; + } + /* Fall through. */ +#endif + case FFI_TYPE_DOUBLE: + double_tmp = **p_argv.d; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + { + *fpr_base.d++ = double_tmp; +#if _CALL_ELF != 2 + if ((flags & FLAG_COMPAT) != 0) + *next_arg.d = double_tmp; +#endif + } + else + *next_arg.d = double_tmp; + if (++next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + fparg_count++; + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + break; + + case FFI_TYPE_FLOAT: + double_tmp = **p_argv.f; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + { + *fpr_base.d++ = double_tmp; +#if _CALL_ELF != 2 + if ((flags & FLAG_COMPAT) != 0) + *next_arg.f = (float) double_tmp; +#endif + } + else + *next_arg.f = (float) double_tmp; + if (++next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + fparg_count++; + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + break; + + case FFI_TYPE_STRUCT: + if ((ecif->cif->abi & FFI_LINUX_STRUCT_ALIGN) != 0) + { + align = (*ptr)->alignment; + if (align > 16) + align = 16; + if (align > 1) + next_arg.p = ALIGN (next_arg.p, align); + } +#if _CALL_ELF == 2 + elt = discover_homogeneous_aggregate (*ptr, &elnum); + if (elt) + { + union { + void *v; + float *f; + double *d; + } arg; + + arg.v = *p_argv.v; + if (elt == FFI_TYPE_FLOAT) + { + do + { + double_tmp = *arg.f++; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 + && i < nfixedargs) + *fpr_base.d++ = double_tmp; + else + *next_arg.f = (float) double_tmp; + if (++next_arg.f == gpr_end.f) + next_arg.f = rest.f; + fparg_count++; + } + while (--elnum != 0); + if ((next_arg.p & 3) != 0) + { + if (++next_arg.f == gpr_end.f) + next_arg.f = rest.f; + } + } + else + do + { + double_tmp = *arg.d++; + if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs) + *fpr_base.d++ = double_tmp; + else + *next_arg.d = double_tmp; + if (++next_arg.d == gpr_end.d) + next_arg.d = rest.d; + fparg_count++; + } + while (--elnum != 0); + } + else +#endif + { + words = ((*ptr)->size + 7) / 8; + if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul) + { + size_t first = gpr_end.c - next_arg.c; + memcpy (next_arg.c, *p_argv.c, first); + memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first); + next_arg.c = rest.c + words * 8 - first; + } + else + { + char *where = next_arg.c; + +#ifndef __LITTLE_ENDIAN__ + /* Structures with size less than eight bytes are passed + left-padded. */ + if ((*ptr)->size < 8) + where += 8 - (*ptr)->size; +#endif + memcpy (where, *p_argv.c, (*ptr)->size); + next_arg.ul += words; + if (next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + } + } + break; + + case FFI_TYPE_UINT8: + gprvalue = **p_argv.uc; + goto putgpr; + case FFI_TYPE_SINT8: + gprvalue = **p_argv.sc; + goto putgpr; + case FFI_TYPE_UINT16: + gprvalue = **p_argv.us; + goto putgpr; + case FFI_TYPE_SINT16: + gprvalue = **p_argv.ss; + goto putgpr; + case FFI_TYPE_UINT32: + gprvalue = **p_argv.ui; + goto putgpr; + case FFI_TYPE_INT: + case FFI_TYPE_SINT32: + gprvalue = **p_argv.si; + goto putgpr; + + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + case FFI_TYPE_POINTER: + gprvalue = **p_argv.ul; + putgpr: + *next_arg.ul++ = gprvalue; + if (next_arg.ul == gpr_end.ul) + next_arg.ul = rest.ul; + break; + } + } + + FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS + || (next_arg.ul >= gpr_base.ul + && next_arg.ul <= gpr_base.ul + 4)); +} + + +#if _CALL_ELF == 2 +#define MIN_CACHE_LINE_SIZE 8 + +static void +flush_icache (char *wraddr, char *xaddr, int size) +{ + int i; + for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) + __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" + : : "r" (xaddr + i), "r" (wraddr + i) : "memory"); + __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;" + : : "r"(xaddr + size - 1), "r"(wraddr + size - 1) + : "memory"); +} +#endif + +ffi_status +ffi_prep_closure_loc_linux64 (ffi_closure *closure, + ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, + void *codeloc) +{ +#if _CALL_ELF == 2 + unsigned int *tramp = (unsigned int *) &closure->tramp[0]; + + if (cif->abi < FFI_LINUX || cif->abi >= FFI_LAST_ABI) + return FFI_BAD_ABI; + + tramp[0] = 0xe96c0018; /* 0: ld 11,2f-0b(12) */ + tramp[1] = 0xe98c0010; /* ld 12,1f-0b(12) */ + tramp[2] = 0x7d8903a6; /* mtctr 12 */ + tramp[3] = 0x4e800420; /* bctr */ + /* 1: .quad function_addr */ + /* 2: .quad context */ + *(void **) &tramp[4] = (void *) ffi_closure_LINUX64; + *(void **) &tramp[6] = codeloc; + flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE); +#else + void **tramp = (void **) &closure->tramp[0]; + + if (cif->abi < FFI_LINUX || cif->abi >= FFI_LAST_ABI) + return FFI_BAD_ABI; + + /* Copy function address and TOC from ffi_closure_LINUX64. */ + memcpy (tramp, (char *) ffi_closure_LINUX64, 16); + tramp[2] = tramp[1]; + tramp[1] = codeloc; +#endif + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + return FFI_OK; +} + + +int FFI_HIDDEN +ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue, + unsigned long *pst, ffi_dblfl *pfr) +{ + /* rvalue is the pointer to space for return value in closure assembly */ + /* pst is the pointer to parameter save area + (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */ + /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */ + + void **avalue; + ffi_type **arg_types; + unsigned long i, avn, nfixedargs; + ffi_cif *cif; + ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64; + unsigned long align; + + cif = closure->cif; + avalue = alloca (cif->nargs * sizeof (void *)); + + /* Copy the caller's structure return value address so that the + closure returns the data directly to the caller. */ + if (cif->rtype->type == FFI_TYPE_STRUCT + && (cif->flags & FLAG_RETURNS_SMST) == 0) + { + rvalue = (void *) *pst; + pst++; + } + + i = 0; + avn = cif->nargs; +#if _CALL_ELF != 2 + nfixedargs = (unsigned) -1; + if ((cif->flags & FLAG_COMPAT) == 0) +#endif + nfixedargs = cif->nfixedargs; + arg_types = cif->arg_types; + + /* Grab the addresses of the arguments from the stack frame. */ + while (i < avn) + { + unsigned int elt, elnum; + + switch (arg_types[i]->type) + { + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: +#ifndef __LITTLE_ENDIAN__ + avalue[i] = (char *) pst + 7; + pst++; + break; +#endif + + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: +#ifndef __LITTLE_ENDIAN__ + avalue[i] = (char *) pst + 6; + pst++; + break; +#endif + + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: +#ifndef __LITTLE_ENDIAN__ + avalue[i] = (char *) pst + 4; + pst++; + break; +#endif + + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + case FFI_TYPE_POINTER: + avalue[i] = pst; + pst++; + break; + + case FFI_TYPE_STRUCT: + if ((cif->abi & FFI_LINUX_STRUCT_ALIGN) != 0) + { + align = arg_types[i]->alignment; + if (align > 16) + align = 16; + if (align > 1) + pst = (unsigned long *) ALIGN ((size_t) pst, align); + } + elt = 0; +#if _CALL_ELF == 2 + elt = discover_homogeneous_aggregate (arg_types[i], &elnum); +#endif + if (elt) + { + union { + void *v; + unsigned long *ul; + float *f; + double *d; + size_t p; + } to, from; + + /* Repackage the aggregate from its parts. The + aggregate size is not greater than the space taken by + the registers so store back to the register/parameter + save arrays. */ + if (pfr + elnum <= end_pfr) + to.v = pfr; + else + to.v = pst; + + avalue[i] = to.v; + from.ul = pst; + if (elt == FFI_TYPE_FLOAT) + { + do + { + if (pfr < end_pfr && i < nfixedargs) + { + *to.f = (float) pfr->d; + pfr++; + } + else + *to.f = *from.f; + to.f++; + from.f++; + } + while (--elnum != 0); + } + else + { + do + { + if (pfr < end_pfr && i < nfixedargs) + { + *to.d = pfr->d; + pfr++; + } + else + *to.d = *from.d; + to.d++; + from.d++; + } + while (--elnum != 0); + } + } + else + { +#ifndef __LITTLE_ENDIAN__ + /* Structures with size less than eight bytes are passed + left-padded. */ + if (arg_types[i]->size < 8) + avalue[i] = (char *) pst + 8 - arg_types[i]->size; + else +#endif + avalue[i] = pst; + } + pst += (arg_types[i]->size + 7) / 8; + break; + +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + if ((cif->abi & FFI_LINUX_LONG_DOUBLE_128) != 0) + { + if (pfr + 1 < end_pfr && i + 1 < nfixedargs) + { + avalue[i] = pfr; + pfr += 2; + } + else + { + if (pfr < end_pfr && i < nfixedargs) + { + /* Passed partly in f13 and partly on the stack. + Move it all to the stack. */ + *pst = *(unsigned long *) pfr; + pfr++; + } + avalue[i] = pst; + } + pst += 2; + break; + } + /* Fall through. */ +#endif + case FFI_TYPE_DOUBLE: + /* On the outgoing stack all values are aligned to 8 */ + /* there are 13 64bit floating point registers */ + + if (pfr < end_pfr && i < nfixedargs) + { + avalue[i] = pfr; + pfr++; + } + else + avalue[i] = pst; + pst++; + break; + + case FFI_TYPE_FLOAT: + if (pfr < end_pfr && i < nfixedargs) + { + /* Float values are stored as doubles in the + ffi_closure_LINUX64 code. Fix them here. */ + pfr->f = (float) pfr->d; + avalue[i] = pfr; + pfr++; + } + else + avalue[i] = pst; + pst++; + break; + + default: + FFI_ASSERT (0); + } + + i++; + } + + + (closure->fun) (cif, rvalue, avalue, closure->user_data); + + /* Tell ffi_closure_LINUX64 how to perform return type promotions. */ + if ((cif->flags & FLAG_RETURNS_SMST) != 0) + { + if ((cif->flags & FLAG_RETURNS_FP) == 0) + return FFI_V2_TYPE_SMALL_STRUCT + cif->rtype->size - 1; + else if ((cif->flags & FLAG_RETURNS_64BITS) != 0) + return FFI_V2_TYPE_DOUBLE_HOMOG; + else + return FFI_V2_TYPE_FLOAT_HOMOG; + } + return cif->rtype->type; +} +#endif diff --git a/Modules/_ctypes/libffi/src/powerpc/ffi_powerpc.h b/Modules/_ctypes/libffi/src/powerpc/ffi_powerpc.h new file mode 100644 index 000000000000..2e61653d1a78 --- /dev/null +++ b/Modules/_ctypes/libffi/src/powerpc/ffi_powerpc.h @@ -0,0 +1,77 @@ +/* ----------------------------------------------------------------------- + ffi_powerpc.h - Copyright (C) 2013 IBM + Copyright (C) 2011 Anthony Green + Copyright (C) 2011 Kyle Moffett + Copyright (C) 2008 Red Hat, Inc + Copyright (C) 2007, 2008 Free Software Foundation, Inc + Copyright (c) 1998 Geoffrey Keating + + PowerPC 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 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. + ----------------------------------------------------------------------- */ + +enum { + /* The assembly depends on these exact flags. */ + /* These go in cr7 */ + FLAG_RETURNS_SMST = 1 << (31-31), /* Used for FFI_SYSV small structs. */ + FLAG_RETURNS_NOTHING = 1 << (31-30), + FLAG_RETURNS_FP = 1 << (31-29), + FLAG_RETURNS_64BITS = 1 << (31-28), + + /* This goes in cr6 */ + FLAG_RETURNS_128BITS = 1 << (31-27), + + FLAG_COMPAT = 1 << (31- 8), /* Not used by assembly */ + + /* These go in cr1 */ + FLAG_ARG_NEEDS_COPY = 1 << (31- 7), /* Used by sysv code */ + FLAG_ARG_NEEDS_PSAVE = FLAG_ARG_NEEDS_COPY, /* Used by linux64 code */ + FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */ + FLAG_4_GPR_ARGUMENTS = 1 << (31- 5), + FLAG_RETVAL_REFERENCE = 1 << (31- 4) +}; + +typedef union +{ + float f; + double d; +} ffi_dblfl; + +void FFI_HIDDEN ffi_closure_SYSV (void); +void FFI_HIDDEN ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *, + void (*)(void)); + +void FFI_HIDDEN ffi_prep_types_sysv (ffi_abi); +ffi_status FFI_HIDDEN ffi_prep_cif_sysv (ffi_cif *); +int FFI_HIDDEN ffi_closure_helper_SYSV (ffi_closure *, void *, unsigned long *, + ffi_dblfl *, unsigned long *); + +void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long, unsigned long, + unsigned long *, void (*)(void)); +void FFI_HIDDEN ffi_closure_LINUX64 (void); + +void FFI_HIDDEN ffi_prep_types_linux64 (ffi_abi); +ffi_status FFI_HIDDEN ffi_prep_cif_linux64 (ffi_cif *); +ffi_status FFI_HIDDEN ffi_prep_cif_linux64_var (ffi_cif *, unsigned int, + unsigned int); +void FFI_HIDDEN ffi_prep_args64 (extended_cif *, unsigned long *const); +int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *, + unsigned long *, ffi_dblfl *); diff --git a/Modules/_ctypes/libffi/src/powerpc/ffi_sysv.c b/Modules/_ctypes/libffi/src/powerpc/ffi_sysv.c new file mode 100644 index 000000000000..fbe85fe91409 --- /dev/null +++ b/Modules/_ctypes/libffi/src/powerpc/ffi_sysv.c @@ -0,0 +1,931 @@ +/* ----------------------------------------------------------------------- + ffi_sysv.c - Copyright (C) 2013 IBM + Copyright (C) 2011 Anthony Green + Copyright (C) 2011 Kyle Moffett + Copyright (C) 2008 Red Hat, Inc + Copyright (C) 2007, 2008 Free Software Foundation, Inc + Copyright (c) 1998 Geoffrey Keating + + PowerPC 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 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 "ffi.h" + +#ifndef POWERPC64 +#include "ffi_common.h" +#include "ffi_powerpc.h" + + +/* About the SYSV ABI. */ +#define ASM_NEEDS_REGISTERS 4 +#define NUM_GPR_ARG_REGISTERS 8 +#define NUM_FPR_ARG_REGISTERS 8 + + +#if HAVE_LONG_DOUBLE_VARIANT && FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE +/* Adjust size of ffi_type_longdouble. */ +void FFI_HIDDEN +ffi_prep_types_sysv (ffi_abi abi) +{ + if ((abi & (FFI_SYSV | FFI_SYSV_LONG_DOUBLE_128)) == FFI_SYSV) + { + ffi_type_longdouble.size = 8; + ffi_type_longdouble.alignment = 8; + } + else + { + ffi_type_longdouble.size = 16; + ffi_type_longdouble.alignment = 16; + } +} +#endif + +/* Transform long double, double and float to other types as per abi. */ +static int +translate_float (int abi, int type) +{ +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + if (type == FFI_TYPE_LONGDOUBLE + && (abi & FFI_SYSV_LONG_DOUBLE_128) == 0) + type = FFI_TYPE_DOUBLE; +#endif + if ((abi & FFI_SYSV_SOFT_FLOAT) != 0) + { + if (type == FFI_TYPE_FLOAT) + type = FFI_TYPE_UINT32; + else if (type == FFI_TYPE_DOUBLE) + type = FFI_TYPE_UINT64; +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + else if (type == FFI_TYPE_LONGDOUBLE) + type = FFI_TYPE_UINT128; + } + else if ((abi & FFI_SYSV_IBM_LONG_DOUBLE) == 0) + { + if (type == FFI_TYPE_LONGDOUBLE) + type = FFI_TYPE_STRUCT; +#endif + } + return type; +} + +/* Perform machine dependent cif processing */ +static ffi_status +ffi_prep_cif_sysv_core (ffi_cif *cif) +{ + ffi_type **ptr; + unsigned bytes; + unsigned i, fparg_count = 0, intarg_count = 0; + unsigned flags = cif->flags; + unsigned struct_copy_size = 0; + unsigned type = cif->rtype->type; + unsigned size = cif->rtype->size; + + /* The machine-independent calculation of cif->bytes doesn't work + for us. Redo the calculation. */ + + /* Space for the frame pointer, callee's LR, and the asm's temp regs. */ + bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int); + + /* Space for the GPR registers. */ + bytes += NUM_GPR_ARG_REGISTERS * sizeof (int); + + /* Return value handling. The rules for SYSV 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; + - Larger structures are allocated space and a pointer is passed as + the first argument. + - Single/double FP values are returned in fpr1; + - long doubles (if not equivalent to double) are returned in + fpr1,fpr2 for Linux and as for large structs for SysV. */ + + type = translate_float (cif->abi, type); + + switch (type) + { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + flags |= FLAG_RETURNS_128BITS; + /* Fall through. */ +#endif + case FFI_TYPE_DOUBLE: + flags |= FLAG_RETURNS_64BITS; + /* Fall through. */ + case FFI_TYPE_FLOAT: + flags |= FLAG_RETURNS_FP; +#ifdef __NO_FPRS__ + return FFI_BAD_ABI; +#endif + break; + + case FFI_TYPE_UINT128: + flags |= FLAG_RETURNS_128BITS; + /* Fall through. */ + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + flags |= FLAG_RETURNS_64BITS; + break; + + case FFI_TYPE_STRUCT: + /* The final SYSV ABI says that structures smaller or equal 8 bytes + are returned in r3/r4. A draft ABI used by linux instead + returns them in memory. */ + if ((cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8) + { + flags |= FLAG_RETURNS_SMST; + break; + } + intarg_count++; + flags |= FLAG_RETVAL_REFERENCE; + /* Fall through. */ + 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 and long doubles (if not equivalent + to double) 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++) + { + unsigned short typenum = (*ptr)->type; + + typenum = translate_float (cif->abi, typenum); + + switch (typenum) + { +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + fparg_count++; + /* Fall thru */ +#endif + 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 >= NUM_GPR_ARG_REGISTERS + && intarg_count % 2 != 0) + intarg_count++; +#ifdef __NO_FPRS__ + return FFI_BAD_ABI; +#endif + break; + + case FFI_TYPE_FLOAT: + fparg_count++; +#ifdef __NO_FPRS__ + return FFI_BAD_ABI; +#endif + break; + + case FFI_TYPE_UINT128: + /* A long double in FFI_LINUX_SOFT_FLOAT can use only a set + of four consecutive gprs. If we do not have enough, we + have to adjust the intarg_count value. */ + if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3 + && intarg_count < NUM_GPR_ARG_REGISTERS) + intarg_count = NUM_GPR_ARG_REGISTERS; + intarg_count += 4; + break; + + 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. + + Also, only certain register pairs can be used for + passing long long int -- specifically (r3,r4), (r5,r6), + (r7,r8), (r9,r10). */ + if (intarg_count == NUM_GPR_ARG_REGISTERS-1 + || intarg_count % 2 != 0) + intarg_count++; + intarg_count += 2; + break; + + case FFI_TYPE_STRUCT: + /* We must allocate space for a copy of these to enforce + pass-by-value. Pad the space up to a multiple of 16 + bytes (the maximum alignment required for anything under + the SYSV ABI). */ + struct_copy_size += ((*ptr)->size + 15) & ~0xF; + /* Fall through (allocate space for the pointer). */ + + case FFI_TYPE_POINTER: + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT16: + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT8: + case FFI_TYPE_SINT8: + /* Everything else is passed as a 4-byte word in a GPR, either + the object itself or a pointer to it. */ + intarg_count++; + break; + + default: + FFI_ASSERT (0); + } + } + + if (fparg_count != 0) + flags |= FLAG_FP_ARGUMENTS; + if (intarg_count > 4) + flags |= FLAG_4_GPR_ARGUMENTS; + if (struct_copy_size != 0) + flags |= FLAG_ARG_NEEDS_COPY; + + /* Space for the FPR registers, if needed. */ + if (fparg_count != 0) + bytes += NUM_FPR_ARG_REGISTERS * sizeof (double); + + /* Stack space. */ + if (intarg_count > NUM_GPR_ARG_REGISTERS) + bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int); + if (fparg_count > NUM_FPR_ARG_REGISTERS) + bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double); + + /* The stack space allocated needs to be a multiple of 16 bytes. */ + bytes = (bytes + 15) & ~0xF; + + /* Add in the space for the copied structures. */ + bytes += struct_copy_size; + + cif->flags = flags; + cif->bytes = bytes; + + return FFI_OK; +} + +ffi_status FFI_HIDDEN +ffi_prep_cif_sysv (ffi_cif *cif) +{ + if ((cif->abi & FFI_SYSV) == 0) + { + /* This call is from old code. Translate to new ABI values. */ + cif->flags |= FLAG_COMPAT; + switch (cif->abi) + { + default: + return FFI_BAD_ABI; + + case FFI_COMPAT_SYSV: + cif->abi = FFI_SYSV | FFI_SYSV_STRUCT_RET | FFI_SYSV_LONG_DOUBLE_128; + break; + + case FFI_COMPAT_GCC_SYSV: + cif->abi = FFI_SYSV | FFI_SYSV_LONG_DOUBLE_128; + break; + + case FFI_COMPAT_LINUX: + cif->abi = (FFI_SYSV | FFI_SYSV_IBM_LONG_DOUBLE + | FFI_SYSV_LONG_DOUBLE_128); + break; + + case FFI_COMPAT_LINUX_SOFT_FLOAT: + cif->abi = (FFI_SYSV | FFI_SYSV_SOFT_FLOAT | FFI_SYSV_IBM_LONG_DOUBLE + | FFI_SYSV_LONG_DOUBLE_128); + break; + } + } + return ffi_prep_cif_sysv_core (cif); +} + +/* ffi_prep_args_SYSV 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_SYSV 4bytes | higher addresses + |--------------------------------------------| + | Previous backchain pointer 4 | stack pointer here + |--------------------------------------------|<+ <<< on entry to + | Saved r28-r31 4*4 | | ffi_call_SYSV + |--------------------------------------------| | + | GPR registers r3-r10 8*4 | | ffi_call_SYSV + |--------------------------------------------| | + | FPR registers f1-f8 (optional) 8*8 | | + |--------------------------------------------| | stack | + | Space for copied structures | | grows | + |--------------------------------------------| | down V + | Parameters that didn't fit in registers | | + |--------------------------------------------| | lower addresses + | Space for callee's LR 4 | | + |--------------------------------------------| | stack pointer here + | Current backchain pointer 4 |-/ during + |--------------------------------------------| <<< ffi_call_SYSV + +*/ + +void FFI_HIDDEN +ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack) +{ + const unsigned bytes = ecif->cif->bytes; + const unsigned flags = ecif->cif->flags; + + typedef union + { + char *c; + unsigned *u; + long long *ll; + float *f; + double *d; + } valp; + + /* 'stacktop' points at the previous backchain pointer. */ + valp stacktop; + + /* 'gpr_base' points at the space for gpr3, and grows upwards as + we use GPR registers. */ + valp gpr_base; + int intarg_count; + +#ifndef __NO_FPRS__ + /* 'fpr_base' points at the space for fpr1, and grows upwards as + we use FPR registers. */ + valp fpr_base; + int fparg_count; +#endif + + /* 'copy_space' grows down as we put structures in it. It should + stay 16-byte aligned. */ + valp copy_space; + + /* 'next_arg' grows up as we put parameters in it. */ + valp next_arg; + + int i; + ffi_type **ptr; +#ifndef __NO_FPRS__ + double double_tmp; +#endif + union + { + void **v; + char **c; + signed char **sc; + unsigned char **uc; + signed short **ss; + unsigned short **us; + unsigned int **ui; + long long **ll; + float **f; + double **d; + } p_argv; + size_t struct_copy_size; + unsigned gprvalue; + + stacktop.c = (char *) stack + bytes; + gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS; + intarg_count = 0; +#ifndef __NO_FPRS__ + fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS; + fparg_count = 0; + copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c); +#else + copy_space.c = gpr_base.c; +#endif + next_arg.u = stack + 2; + + /* Check that everything starts aligned properly. */ + FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0); + FFI_ASSERT (((unsigned long) copy_space.c & 0xF) == 0); + FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0); + FFI_ASSERT ((bytes & 0xF) == 0); + FFI_ASSERT (copy_space.c >= next_arg.c); + + /* Deal with return values that are actually pass-by-reference. */ + if (flags & FLAG_RETVAL_REFERENCE) + { + *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue; + intarg_count++; + } + + /* Now for the arguments. */ + p_argv.v = ecif->avalue; + for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs; + i > 0; + i--, ptr++, p_argv.v++) + { + unsigned int typenum = (*ptr)->type; + + typenum = translate_float (ecif->cif->abi, typenum); + + /* Now test the translated value */ + switch (typenum) + { +#ifndef __NO_FPRS__ +# if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + double_tmp = (*p_argv.d)[0]; + + if (fparg_count >= NUM_FPR_ARG_REGISTERS - 1) + { + if (intarg_count >= NUM_GPR_ARG_REGISTERS + && intarg_count % 2 != 0) + { + intarg_count++; + next_arg.u++; + } + *next_arg.d = double_tmp; + next_arg.u += 2; + double_tmp = (*p_argv.d)[1]; + *next_arg.d = double_tmp; + next_arg.u += 2; + } + else + { + *fpr_base.d++ = double_tmp; + double_tmp = (*p_argv.d)[1]; + *fpr_base.d++ = double_tmp; + } + + fparg_count += 2; + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + break; +# endif + case FFI_TYPE_DOUBLE: + double_tmp = **p_argv.d; + + if (fparg_count >= NUM_FPR_ARG_REGISTERS) + { + if (intarg_count >= NUM_GPR_ARG_REGISTERS + && intarg_count % 2 != 0) + { + intarg_count++; + next_arg.u++; + } + *next_arg.d = double_tmp; + next_arg.u += 2; + } + else + *fpr_base.d++ = double_tmp; + fparg_count++; + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + break; + + case FFI_TYPE_FLOAT: + double_tmp = **p_argv.f; + if (fparg_count >= NUM_FPR_ARG_REGISTERS) + { + *next_arg.f = (float) double_tmp; + next_arg.u += 1; + intarg_count++; + } + else + *fpr_base.d++ = double_tmp; + fparg_count++; + FFI_ASSERT (flags & FLAG_FP_ARGUMENTS); + break; +#endif /* have FPRs */ + + case FFI_TYPE_UINT128: + /* The soft float ABI for long doubles works like this, a long double + is passed in four consecutive GPRs if available. A maximum of 2 + long doubles can be passed in gprs. If we do not have 4 GPRs + left, the long double is passed on the stack, 4-byte aligned. */ + { + unsigned int int_tmp; + unsigned int ii; + if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3) + { + if (intarg_count < NUM_GPR_ARG_REGISTERS) + intarg_count = NUM_GPR_ARG_REGISTERS; + for (ii = 0; ii < 4; ii++) + { + int_tmp = (*p_argv.ui)[ii]; + *next_arg.u++ = int_tmp; + } + } + else + { + for (ii = 0; ii < 4; ii++) + { + int_tmp = (*p_argv.ui)[ii]; + *gpr_base.u++ = int_tmp; + } + } + intarg_count += 4; + break; + } + + case FFI_TYPE_UINT64: + case FFI_TYPE_SINT64: + if (intarg_count == NUM_GPR_ARG_REGISTERS-1) + intarg_count++; + if (intarg_count >= NUM_GPR_ARG_REGISTERS) + { + if (intarg_count % 2 != 0) + { + intarg_count++; + next_arg.u++; + } + *next_arg.ll = **p_argv.ll; + next_arg.u += 2; + } + else + { + /* The abi states only certain register pairs can be + used for passing long long int specifically (r3,r4), + (r5,r6), (r7,r8), (r9,r10). If next arg is long long + but not correct starting register of pair then skip + until the proper starting register. */ + if (intarg_count % 2 != 0) + { + intarg_count ++; + gpr_base.u++; + } + *gpr_base.ll++ = **p_argv.ll; + } + intarg_count += 2; + break; + + case FFI_TYPE_STRUCT: + struct_copy_size = ((*ptr)->size + 15) & ~0xF; + copy_space.c -= struct_copy_size; + memcpy (copy_space.c, *p_argv.c, (*ptr)->size); + + gprvalue = (unsigned long) copy_space.c; + + FFI_ASSERT (copy_space.c > next_arg.c); + FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY); + goto putgpr; + + case FFI_TYPE_UINT8: + gprvalue = **p_argv.uc; + goto putgpr; + case FFI_TYPE_SINT8: + gprvalue = **p_argv.sc; + goto putgpr; + case FFI_TYPE_UINT16: + gprvalue = **p_argv.us; + goto putgpr; + case FFI_TYPE_SINT16: + gprvalue = **p_argv.ss; + goto putgpr; + + case FFI_TYPE_INT: + case FFI_TYPE_UINT32: + case FFI_TYPE_SINT32: + case FFI_TYPE_POINTER: + + gprvalue = **p_argv.ui; + + putgpr: + if (intarg_count >= NUM_GPR_ARG_REGISTERS) + *next_arg.u++ = gprvalue; + else + *gpr_base.u++ = gprvalue; + intarg_count++; + break; + } + } + + /* Check that we didn't overrun the stack... */ + FFI_ASSERT (copy_space.c >= next_arg.c); + FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS); + /* The assert below is testing that the number of integer arguments agrees + with the number found in ffi_prep_cif_machdep(). However, intarg_count + is incremented whenever we place an FP arg on the stack, so account for + that before our assert test. */ +#ifndef __NO_FPRS__ + if (fparg_count > NUM_FPR_ARG_REGISTERS) + intarg_count -= fparg_count - NUM_FPR_ARG_REGISTERS; + FFI_ASSERT (fpr_base.u + <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS); +#endif + FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4); +} + +#define MIN_CACHE_LINE_SIZE 8 + +static void +flush_icache (char *wraddr, char *xaddr, int size) +{ + int i; + for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) + __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" + : : "r" (xaddr + i), "r" (wraddr + i) : "memory"); + __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;" + : : "r"(xaddr + size - 1), "r"(wraddr + size - 1) + : "memory"); +} + +ffi_status FFI_HIDDEN +ffi_prep_closure_loc_sysv (ffi_closure *closure, + ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, + void *codeloc) +{ + unsigned int *tramp; + + if (cif->abi < FFI_SYSV || cif->abi >= FFI_LAST_ABI) + return FFI_BAD_ABI; + + tramp = (unsigned int *) &closure->tramp[0]; + tramp[0] = 0x7c0802a6; /* mflr r0 */ + tramp[1] = 0x4800000d; /* bl 10 */ + tramp[4] = 0x7d6802a6; /* mflr r11 */ + tramp[5] = 0x7c0803a6; /* mtlr r0 */ + tramp[6] = 0x800b0000; /* lwz r0,0(r11) */ + tramp[7] = 0x816b0004; /* lwz r11,4(r11) */ + tramp[8] = 0x7c0903a6; /* mtctr r0 */ + tramp[9] = 0x4e800420; /* bctr */ + *(void **) &tramp[2] = (void *) ffi_closure_SYSV; /* function */ + *(void **) &tramp[3] = codeloc; /* context */ + + /* Flush the icache. */ + flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE); + + closure->cif = cif; + closure->fun = fun; + closure->user_data = user_data; + + return FFI_OK; +} + +/* Basically the trampoline invokes ffi_closure_SYSV, 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_SYSV invokes the + following helper function to do most of the work. */ + +int +ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, + unsigned long *pgr, ffi_dblfl *pfr, + unsigned long *pst) +{ + /* 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_SYSV */ + /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV */ + /* pst is the pointer to outgoing parameter stack in original caller */ + + void ** avalue; + ffi_type ** arg_types; + long i, avn; +#ifndef __NO_FPRS__ + long nf = 0; /* number of floating registers already used */ +#endif + long ng = 0; /* number of general registers already used */ + + ffi_cif *cif = closure->cif; + unsigned size = cif->rtype->size; + unsigned short rtypenum = cif->rtype->type; + + avalue = alloca (cif->nargs * sizeof (void *)); + + /* First translate for softfloat/nonlinux */ + rtypenum = translate_float (cif->abi, rtypenum); + + /* Copy the caller's structure return value address so that the closure + returns the data directly to the caller. + For FFI_SYSV the result is passed in r3/r4 if the struct size is less + or equal 8 bytes. */ + if (rtypenum == FFI_TYPE_STRUCT + && !((cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8)) + { + rvalue = (void *) *pgr; + ng++; + pgr++; + } + + i = 0; + avn = cif->nargs; + arg_types = cif->arg_types; + + /* Grab the addresses of the arguments from the stack frame. */ + while (i < avn) { + unsigned short typenum = arg_types[i]->type; + + /* We may need to handle some values depending on ABI. */ + typenum = translate_float (cif->abi, typenum); + + switch (typenum) + { +#ifndef __NO_FPRS__ + case FFI_TYPE_FLOAT: + /* Unfortunately float values are stored as doubles + in the ffi_closure_SYSV code (since we don't check + the type in that routine). */ + if (nf < NUM_FPR_ARG_REGISTERS) + { + /* FIXME? here we are really changing the values + stored in the original calling routines outgoing + parameter stack. This is probably a really + naughty thing to do but... */ + double temp = pfr->d; + pfr->f = (float) temp; + avalue[i] = pfr; + nf++; + pfr++; + } + else + { + avalue[i] = pst; + pst += 1; + } + break; + + case FFI_TYPE_DOUBLE: + if (nf < NUM_FPR_ARG_REGISTERS) + { + avalue[i] = pfr; + nf++; + pfr++; + } + else + { + if (((long) pst) & 4) + pst++; + avalue[i] = pst; + pst += 2; + } + break; + +# if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE + case FFI_TYPE_LONGDOUBLE: + if (nf < NUM_FPR_ARG_REGISTERS - 1) + { + avalue[i] = pfr; + pfr += 2; + nf += 2; + } + else + { + if (((long) pst) & 4) + pst++; + avalue[i] = pst; + pst += 4; + nf = 8; + } + break; +# endif +#endif + + case FFI_TYPE_UINT128: + /* Test if for the whole long double, 4 gprs are available. + otherwise the stuff ends up on the stack. */ + if (ng < NUM_GPR_ARG_REGISTERS - 3) + { + avalue[i] = pgr; + pgr += 4; + ng += 4; + } + else + { + avalue[i] = pst; + pst += 4; + ng = 8+4; + } + break; + + case FFI_TYPE_SINT8: + case FFI_TYPE_UINT8: +#ifndef __LITTLE_ENDIAN__ + if (ng < NUM_GPR_ARG_REGISTERS) + { + avalue[i] = (char *) pgr + 3; + ng++; + pgr++; + } + else + { + avalue[i] = (char *) pst + 3; + pst++; + } + break; +#endif + + case FFI_TYPE_SINT16: + case FFI_TYPE_UINT16: +#ifndef __LITTLE_ENDIAN__ + if (ng < NUM_GPR_ARG_REGISTERS) + { + avalue[i] = (char *) pgr + 2; + ng++; + pgr++; + } + else + { + avalue[i] = (char *) pst + 2; + pst++; + } + break; +#endif + + case FFI_TYPE_SINT32: + case FFI_TYPE_UINT32: + case FFI_TYPE_POINTER: + if (ng < NUM_GPR_ARG_REGISTERS) + { + avalue[i] = pgr; + ng++; + pgr++; + } + else + { + avalue[i] = pst; + pst++; + } + break; + + case FFI_TYPE_STRUCT: + /* Structs are passed by reference. The address will appear in a + gpr if it is one of the first 8 arguments. */ + if (ng < NUM_GPR_ARG_REGISTERS) + { + avalue[i] = (void *) *pgr; + ng++; + pgr++; + } + else + { + avalue[i] = (void *) *pst; + pst++; + } + break; + + case FFI_TYPE_SINT64: + case FFI_TYPE_UINT64: + /* Passing long long ints are complex, they must + be passed in suitable register pairs such as + (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10) + and if the entire pair aren't available then the outgoing + parameter stack is used for both but an alignment of 8 + must will be kept. So we must either look in pgr + or pst to find the correct address for this type + of parameter. */ + if (ng < NUM_GPR_ARG_REGISTERS - 1) + { + if (ng & 1) + { + /* skip r4, r6, r8 as starting points */ + ng++; + pgr++; + } + avalue[i] = pgr; + ng += 2; + pgr += 2; + } + else + { + if (((long) pst) & 4) + pst++; + avalue[i] = pst; + pst += 2; + ng = NUM_GPR_ARG_REGISTERS; + } + break; + + default: + FFI_ASSERT (0); + } + + i++; + } + + (closure->fun) (cif, rvalue, avalue, closure->user_data); + + /* Tell ffi_closure_SYSV how to perform return type promotions. + Because the FFI_SYSV ABI returns the structures <= 8 bytes in + r3/r4 we have to tell ffi_closure_SYSV how to treat them. We + combine the base type FFI_SYSV_TYPE_SMALL_STRUCT with the size of + the struct less one. We never have a struct with size zero. + See the comment in ffitarget.h about ordering. */ + if (rtypenum == FFI_TYPE_STRUCT + && (cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8) + return FFI_SYSV_TYPE_SMALL_STRUCT - 1 + size; + return rtypenum; +} +#endif diff --git a/Modules/_ctypes/libffi/src/powerpc/ffitarget.h b/Modules/_ctypes/libffi/src/powerpc/ffitarget.h index 3c9db495f49b..b47b0f5d3a2d 100644 --- a/Modules/_ctypes/libffi/src/powerpc/ffitarget.h +++ b/Modules/_ctypes/libffi/src/powerpc/ffitarget.h @@ -60,45 +60,76 @@ typedef signed long ffi_sarg; typedef enum ffi_abi { FFI_FIRST_ABI = 0, -#ifdef POWERPC - FFI_SYSV, - FFI_GCC_SYSV, - FFI_LINUX64, - FFI_LINUX, - FFI_LINUX_SOFT_FLOAT, -# if defined(POWERPC64) - FFI_DEFAULT_ABI = FFI_LINUX64, -# elif defined(__NO_FPRS__) - FFI_DEFAULT_ABI = FFI_LINUX_SOFT_FLOAT, -# elif (__LDBL_MANT_DIG__ == 106) - FFI_DEFAULT_ABI = FFI_LINUX, -# else - FFI_DEFAULT_ABI = FFI_GCC_SYSV, -# endif -#endif - -#ifdef POWERPC_AIX +#if defined (POWERPC_AIX) FFI_AIX, FFI_DARWIN, FFI_DEFAULT_ABI = FFI_AIX, -#endif + FFI_LAST_ABI -#ifdef POWERPC_DARWIN +#elif defined (POWERPC_DARWIN) FFI_AIX, FFI_DARWIN, FFI_DEFAULT_ABI = FFI_DARWIN, -#endif + FFI_LAST_ABI + +#else + /* The FFI_COMPAT values are used by old code. Since libffi may be + a shared library we have to support old values for backwards + compatibility. */ + FFI_COMPAT_SYSV, + FFI_COMPAT_GCC_SYSV, + FFI_COMPAT_LINUX64, + FFI_COMPAT_LINUX, + FFI_COMPAT_LINUX_SOFT_FLOAT, + +# if defined (POWERPC64) + /* This bit, always set in new code, must not be set in any of the + old FFI_COMPAT values that might be used for 64-bit linux. We + only need worry about FFI_COMPAT_LINUX64, but to be safe avoid + all old values. */ + FFI_LINUX = 8, + /* This and following bits can reuse FFI_COMPAT values. */ + FFI_LINUX_STRUCT_ALIGN = 1, + FFI_LINUX_LONG_DOUBLE_128 = 2, + FFI_DEFAULT_ABI = (FFI_LINUX +# ifdef __STRUCT_PARM_ALIGN__ + | FFI_LINUX_STRUCT_ALIGN +# endif +# ifdef __LONG_DOUBLE_128__ + | FFI_LINUX_LONG_DOUBLE_128 +# endif + ), + FFI_LAST_ABI = 12 -#ifdef POWERPC_FREEBSD - FFI_SYSV, - FFI_GCC_SYSV, - FFI_LINUX64, - FFI_LINUX, - FFI_LINUX_SOFT_FLOAT, - FFI_DEFAULT_ABI = FFI_SYSV, +# else + /* This bit, always set in new code, must not be set in any of the + old FFI_COMPAT values that might be used for 32-bit linux/sysv/bsd. */ + FFI_SYSV = 8, + /* This and following bits can reuse FFI_COMPAT values. */ + FFI_SYSV_SOFT_FLOAT = 1, + FFI_SYSV_STRUCT_RET = 2, + FFI_SYSV_IBM_LONG_DOUBLE = 4, + FFI_SYSV_LONG_DOUBLE_128 = 16, + + FFI_DEFAULT_ABI = (FFI_SYSV +# ifdef __NO_FPRS__ + | FFI_SYSV_SOFT_FLOAT +# endif +# if (defined (__SVR4_STRUCT_RETURN) \ + || defined (POWERPC_FREEBSD) && !defined (__AIX_STRUCT_RETURN)) + | FFI_SYSV_STRUCT_RET +# endif +# if __LDBL_MANT_DIG__ == 106 + | FFI_SYSV_IBM_LONG_DOUBLE +# endif +# ifdef __LONG_DOUBLE_128__ + | FFI_SYSV_LONG_DOUBLE_128 +# endif + ), + FFI_LAST_ABI = 32 +# endif #endif - FFI_LAST_ABI } ffi_abi; #endif @@ -106,6 +137,10 @@ typedef enum ffi_abi { #define FFI_CLOSURES 1 #define FFI_NATIVE_RAW_API 0 +#if defined (POWERPC) || defined (POWERPC_FREEBSD) +# define FFI_TARGET_SPECIFIC_VARIADIC 1 +# define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs +#endif /* For additional types like the below, take care about the order in ppc_closures.S. They must follow after the FFI_TYPE_LAST. */ @@ -113,19 +148,26 @@ typedef enum ffi_abi { /* Needed for soft-float long-double-128 support. */ #define FFI_TYPE_UINT128 (FFI_TYPE_LAST + 1) -/* Needed for FFI_SYSV small structure returns. - We use two flag bits, (FLAG_SYSV_SMST_R3, FLAG_SYSV_SMST_R4) which are - defined in ffi.c, to determine the exact return type and its size. */ +/* Needed for FFI_SYSV small structure returns. */ #define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 2) -#if defined(POWERPC64) || defined(POWERPC_AIX) +/* Used by ELFv2 for homogenous structure returns. */ +#define FFI_V2_TYPE_FLOAT_HOMOG (FFI_TYPE_LAST + 1) +#define FFI_V2_TYPE_DOUBLE_HOMOG (FFI_TYPE_LAST + 2) +#define FFI_V2_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 3) + +#if _CALL_ELF == 2 +# define FFI_TRAMPOLINE_SIZE 32 +#else +# if defined(POWERPC64) || defined(POWERPC_AIX) # if defined(POWERPC_DARWIN64) # define FFI_TRAMPOLINE_SIZE 48 # else # define FFI_TRAMPOLINE_SIZE 24 # endif -#else /* POWERPC || POWERPC_AIX */ +# else /* POWERPC || POWERPC_AIX */ # define FFI_TRAMPOLINE_SIZE 40 +# endif #endif #ifndef LIBFFI_ASM diff --git a/Modules/_ctypes/libffi/src/powerpc/linux64.S b/Modules/_ctypes/libffi/src/powerpc/linux64.S index f28da8120b78..c4d01d8e3f7a 100644 --- a/Modules/_ctypes/libffi/src/powerpc/linux64.S +++ b/Modules/_ctypes/libffi/src/powerpc/linux64.S @@ -29,18 +29,25 @@ #include #include -#ifdef __powerpc64__ +#ifdef POWERPC64 .hidden ffi_call_LINUX64 .globl ffi_call_LINUX64 +# if _CALL_ELF == 2 + .text +ffi_call_LINUX64: + addis %r2, %r12, .TOC.-ffi_call_LINUX64@ha + addi %r2, %r2, .TOC.-ffi_call_LINUX64@l + .localentry ffi_call_LINUX64, . - ffi_call_LINUX64 +# else .section ".opd","aw" .align 3 ffi_call_LINUX64: -#ifdef _CALL_LINUX +# ifdef _CALL_LINUX .quad .L.ffi_call_LINUX64,.TOC.@tocbase,0 .type ffi_call_LINUX64,@function .text .L.ffi_call_LINUX64: -#else +# else .hidden .ffi_call_LINUX64 .globl .ffi_call_LINUX64 .quad .ffi_call_LINUX64,.TOC.@tocbase,0 @@ -48,7 +55,8 @@ ffi_call_LINUX64: .type .ffi_call_LINUX64,@function .text .ffi_call_LINUX64: -#endif +# endif +# endif .LFB1: mflr %r0 std %r28, -32(%r1) @@ -63,26 +71,35 @@ ffi_call_LINUX64: mr %r31, %r5 /* flags, */ mr %r30, %r6 /* rvalue, */ mr %r29, %r7 /* function address. */ +/* Save toc pointer, not for the ffi_prep_args64 call, but for the later + bctrl function call. */ +# if _CALL_ELF == 2 + std %r2, 24(%r1) +# else std %r2, 40(%r1) +# endif /* Call ffi_prep_args64. */ mr %r4, %r1 -#ifdef _CALL_LINUX +# if defined _CALL_LINUX || _CALL_ELF == 2 bl ffi_prep_args64 -#else +# else bl .ffi_prep_args64 -#endif +# endif - ld %r0, 0(%r29) +# if _CALL_ELF == 2 + mr %r12, %r29 +# else + ld %r12, 0(%r29) ld %r2, 8(%r29) ld %r11, 16(%r29) - +# endif /* Now do the call. */ /* Set up cr1 with bits 4-7 of the flags. */ mtcrf 0x40, %r31 /* Get the address to call into CTR. */ - mtctr %r0 + mtctr %r12 /* Load all those argument registers. */ ld %r3, -32-(8*8)(%r28) ld %r4, -32-(7*8)(%r28) @@ -117,12 +134,17 @@ ffi_call_LINUX64: /* This must follow the call immediately, the unwinder uses this to find out if r2 has been saved or not. */ +# if _CALL_ELF == 2 + ld %r2, 24(%r1) +# else ld %r2, 40(%r1) +# endif /* Now, deal with the return value. */ mtcrf 0x01, %r31 - bt- 30, .Ldone_return_value - bt- 29, .Lfp_return_value + bt 31, .Lstruct_return_value + bt 30, .Ldone_return_value + bt 29, .Lfp_return_value std %r3, 0(%r30) /* Fall through... */ @@ -130,7 +152,7 @@ ffi_call_LINUX64: /* Restore the registers we used and return. */ mr %r1, %r28 ld %r0, 16(%r28) - ld %r28, -32(%r1) + ld %r28, -32(%r28) mtlr %r0 ld %r29, -24(%r1) ld %r30, -16(%r1) @@ -147,14 +169,48 @@ ffi_call_LINUX64: .Lfloat_return_value: stfs %f1, 0(%r30) b .Ldone_return_value + +.Lstruct_return_value: + bf 29, .Lsmall_struct + bf 28, .Lfloat_homog_return_value + stfd %f1, 0(%r30) + stfd %f2, 8(%r30) + stfd %f3, 16(%r30) + stfd %f4, 24(%r30) + stfd %f5, 32(%r30) + stfd %f6, 40(%r30) + stfd %f7, 48(%r30) + stfd %f8, 56(%r30) + b .Ldone_return_value + +.Lfloat_homog_return_value: + stfs %f1, 0(%r30) + stfs %f2, 4(%r30) + stfs %f3, 8(%r30) + stfs %f4, 12(%r30) + stfs %f5, 16(%r30) + stfs %f6, 20(%r30) + stfs %f7, 24(%r30) + stfs %f8, 28(%r30) + b .Ldone_return_value + +.Lsmall_struct: + std %r3, 0(%r30) + std %r4, 8(%r30) + b .Ldone_return_value + .LFE1: .long 0 .byte 0,12,0,1,128,4,0,0 -#ifdef _CALL_LINUX +# if _CALL_ELF == 2 + .size ffi_call_LINUX64,.-ffi_call_LINUX64 +# else +# ifdef _CALL_LINUX .size ffi_call_LINUX64,.-.L.ffi_call_LINUX64 -#else +# else .size .ffi_call_LINUX64,.-.ffi_call_LINUX64 -#endif +# endif +# endif .section .eh_frame,EH_FRAME_FLAGS,@progbits .Lframe1: @@ -197,8 +253,8 @@ ffi_call_LINUX64: .uleb128 0x4 .align 3 .LEFDE1: -#endif -#if defined __ELF__ && defined __linux__ +# if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2 .section .note.GNU-stack,"",@progbits +# endif #endif diff --git a/Modules/_ctypes/libffi/src/powerpc/linux64_closure.S b/Modules/_ctypes/libffi/src/powerpc/linux64_closure.S index b1e12197a2b2..bc61b5ed946b 100644 --- a/Modules/_ctypes/libffi/src/powerpc/linux64_closure.S +++ b/Modules/_ctypes/libffi/src/powerpc/linux64_closure.S @@ -30,18 +30,25 @@ .file "linux64_closure.S" -#ifdef __powerpc64__ +#ifdef POWERPC64 FFI_HIDDEN (ffi_closure_LINUX64) .globl ffi_closure_LINUX64 +# if _CALL_ELF == 2 + .text +ffi_closure_LINUX64: + addis %r2, %r12, .TOC.-ffi_closure_LINUX64@ha + addi %r2, %r2, .TOC.-ffi_closure_LINUX64@l + .localentry ffi_closure_LINUX64, . - ffi_closure_LINUX64 +# else .section ".opd","aw" .align 3 ffi_closure_LINUX64: -#ifdef _CALL_LINUX +# ifdef _CALL_LINUX .quad .L.ffi_closure_LINUX64,.TOC.@tocbase,0 .type ffi_closure_LINUX64,@function .text .L.ffi_closure_LINUX64: -#else +# else FFI_HIDDEN (.ffi_closure_LINUX64) .globl .ffi_closure_LINUX64 .quad .ffi_closure_LINUX64,.TOC.@tocbase,0 @@ -49,61 +56,105 @@ ffi_closure_LINUX64: .type .ffi_closure_LINUX64,@function .text .ffi_closure_LINUX64: -#endif +# endif +# endif + +# if _CALL_ELF == 2 +# 32 byte special reg save area + 64 byte parm save area +# + 64 byte retval area + 13*8 fpr save area + round to 16 +# define STACKFRAME 272 +# define PARMSAVE 32 +# define RETVAL PARMSAVE+64 +# else +# 48 bytes special reg save area + 64 bytes parm save area +# + 16 bytes retval area + 13*8 bytes fpr save area + round to 16 +# define STACKFRAME 240 +# define PARMSAVE 48 +# define RETVAL PARMSAVE+64 +# endif + .LFB1: - # save general regs into parm save area - std %r3, 48(%r1) - std %r4, 56(%r1) - std %r5, 64(%r1) - std %r6, 72(%r1) +# if _CALL_ELF == 2 + ld %r12, FFI_TRAMPOLINE_SIZE(%r11) # closure->cif + mflr %r0 + lwz %r12, 28(%r12) # cif->flags + mtcrf 0x40, %r12 + addi %r12, %r1, PARMSAVE + bt 7, .Lparmsave + # Our caller has not allocated a parameter save area. + # We need to allocate one here and use it to pass gprs to + # ffi_closure_helper_LINUX64. + addi %r12, %r1, -STACKFRAME+PARMSAVE +.Lparmsave: + std %r0, 16(%r1) + # Save general regs into parm save area + std %r3, 0(%r12) + std %r4, 8(%r12) + std %r5, 16(%r12) + std %r6, 24(%r12) + std %r7, 32(%r12) + std %r8, 40(%r12) + std %r9, 48(%r12) + std %r10, 56(%r12) + + # load up the pointer to the parm save area + mr %r5, %r12 +# else + # copy r2 to r11 and load TOC into r2 + mr %r11, %r2 + ld %r2, 16(%r11) + mflr %r0 + # Save general regs into parm save area + # This is the parameter save area set up by our caller. + std %r3, PARMSAVE+0(%r1) + std %r4, PARMSAVE+8(%r1) + std %r5, PARMSAVE+16(%r1) + std %r6, PARMSAVE+24(%r1) + std %r7, PARMSAVE+32(%r1) + std %r8, PARMSAVE+40(%r1) + std %r9, PARMSAVE+48(%r1) + std %r10, PARMSAVE+56(%r1) - std %r7, 80(%r1) - std %r8, 88(%r1) - std %r9, 96(%r1) - std %r10, 104(%r1) std %r0, 16(%r1) - # mandatory 48 bytes special reg save area + 64 bytes parm save area - # + 16 bytes retval area + 13*8 bytes fpr save area + round to 16 - stdu %r1, -240(%r1) -.LCFI0: + # load up the pointer to the parm save area + addi %r5, %r1, PARMSAVE +# endif # next save fpr 1 to fpr 13 - stfd %f1, 128+(0*8)(%r1) - stfd %f2, 128+(1*8)(%r1) - stfd %f3, 128+(2*8)(%r1) - stfd %f4, 128+(3*8)(%r1) - stfd %f5, 128+(4*8)(%r1) - stfd %f6, 128+(5*8)(%r1) - stfd %f7, 128+(6*8)(%r1) - stfd %f8, 128+(7*8)(%r1) - stfd %f9, 128+(8*8)(%r1) - stfd %f10, 128+(9*8)(%r1) - stfd %f11, 128+(10*8)(%r1) - stfd %f12, 128+(11*8)(%r1) - stfd %f13, 128+(12*8)(%r1) - - # set up registers for the routine that actually does the work - # get the context pointer from the trampoline - mr %r3, %r11 + stfd %f1, -104+(0*8)(%r1) + stfd %f2, -104+(1*8)(%r1) + stfd %f3, -104+(2*8)(%r1) + stfd %f4, -104+(3*8)(%r1) + stfd %f5, -104+(4*8)(%r1) + stfd %f6, -104+(5*8)(%r1) + stfd %f7, -104+(6*8)(%r1) + stfd %f8, -104+(7*8)(%r1) + stfd %f9, -104+(8*8)(%r1) + stfd %f10, -104+(9*8)(%r1) + stfd %f11, -104+(10*8)(%r1) + stfd %f12, -104+(11*8)(%r1) + stfd %f13, -104+(12*8)(%r1) - # now load up the pointer to the result storage - addi %r4, %r1, 112 + # load up the pointer to the saved fpr registers */ + addi %r6, %r1, -104 - # now load up the pointer to the parameter save area - # in the previous frame - addi %r5, %r1, 240 + 48 + # load up the pointer to the result storage + addi %r4, %r1, -STACKFRAME+RETVAL - # now load up the pointer to the saved fpr registers */ - addi %r6, %r1, 128 + stdu %r1, -STACKFRAME(%r1) +.LCFI0: + + # get the context pointer from the trampoline + mr %r3, %r11 # make the call -#ifdef _CALL_LINUX +# if defined _CALL_LINUX || _CALL_ELF == 2 bl ffi_closure_helper_LINUX64 -#else +# else bl .ffi_closure_helper_LINUX64 -#endif +# endif .Lret: # now r3 contains the return type @@ -112,10 +163,12 @@ ffi_closure_LINUX64: # look up the proper starting point in table # by using return type as offset + ld %r0, STACKFRAME+16(%r1) + cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT + bge .Lsmall mflr %r4 # move address of .Lret to r4 sldi %r3, %r3, 4 # now multiply return type by 16 addi %r4, %r4, .Lret_type0 - .Lret - ld %r0, 240+16(%r1) add %r3, %r3, %r4 # add contents of table to table address mtctr %r3 bctr # jump to it @@ -128,89 +181,175 @@ ffi_closure_LINUX64: .Lret_type0: # case FFI_TYPE_VOID mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr nop # case FFI_TYPE_INT - lwa %r3, 112+4(%r1) +# ifdef __LITTLE_ENDIAN__ + lwa %r3, RETVAL+0(%r1) +# else + lwa %r3, RETVAL+4(%r1) +# endif mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr # case FFI_TYPE_FLOAT - lfs %f1, 112+0(%r1) + lfs %f1, RETVAL+0(%r1) mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr # case FFI_TYPE_DOUBLE - lfd %f1, 112+0(%r1) + lfd %f1, RETVAL+0(%r1) mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr # case FFI_TYPE_LONGDOUBLE - lfd %f1, 112+0(%r1) + lfd %f1, RETVAL+0(%r1) mtlr %r0 - lfd %f2, 112+8(%r1) + lfd %f2, RETVAL+8(%r1) b .Lfinish # case FFI_TYPE_UINT8 - lbz %r3, 112+7(%r1) +# ifdef __LITTLE_ENDIAN__ + lbz %r3, RETVAL+0(%r1) +# else + lbz %r3, RETVAL+7(%r1) +# endif mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr # case FFI_TYPE_SINT8 - lbz %r3, 112+7(%r1) +# ifdef __LITTLE_ENDIAN__ + lbz %r3, RETVAL+0(%r1) +# else + lbz %r3, RETVAL+7(%r1) +# endif extsb %r3,%r3 mtlr %r0 b .Lfinish # case FFI_TYPE_UINT16 - lhz %r3, 112+6(%r1) +# ifdef __LITTLE_ENDIAN__ + lhz %r3, RETVAL+0(%r1) +# else + lhz %r3, RETVAL+6(%r1) +# endif mtlr %r0 .Lfinish: - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr # case FFI_TYPE_SINT16 - lha %r3, 112+6(%r1) +# ifdef __LITTLE_ENDIAN__ + lha %r3, RETVAL+0(%r1) +# else + lha %r3, RETVAL+6(%r1) +# endif mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr # case FFI_TYPE_UINT32 - lwz %r3, 112+4(%r1) +# ifdef __LITTLE_ENDIAN__ + lwz %r3, RETVAL+0(%r1) +# else + lwz %r3, RETVAL+4(%r1) +# endif mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr # case FFI_TYPE_SINT32 - lwa %r3, 112+4(%r1) +# ifdef __LITTLE_ENDIAN__ + lwa %r3, RETVAL+0(%r1) +# else + lwa %r3, RETVAL+4(%r1) +# endif mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr # case FFI_TYPE_UINT64 - ld %r3, 112+0(%r1) + ld %r3, RETVAL+0(%r1) mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr # case FFI_TYPE_SINT64 - ld %r3, 112+0(%r1) + ld %r3, RETVAL+0(%r1) mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr # case FFI_TYPE_STRUCT mtlr %r0 - addi %r1, %r1, 240 + addi %r1, %r1, STACKFRAME blr nop # case FFI_TYPE_POINTER - ld %r3, 112+0(%r1) + ld %r3, RETVAL+0(%r1) + mtlr %r0 + addi %r1, %r1, STACKFRAME + blr +# case FFI_V2_TYPE_FLOAT_HOMOG + lfs %f1, RETVAL+0(%r1) + lfs %f2, RETVAL+4(%r1) + lfs %f3, RETVAL+8(%r1) + b .Lmorefloat +# case FFI_V2_TYPE_DOUBLE_HOMOG + lfd %f1, RETVAL+0(%r1) + lfd %f2, RETVAL+8(%r1) + lfd %f3, RETVAL+16(%r1) + lfd %f4, RETVAL+24(%r1) + mtlr %r0 + lfd %f5, RETVAL+32(%r1) + lfd %f6, RETVAL+40(%r1) + lfd %f7, RETVAL+48(%r1) + lfd %f8, RETVAL+56(%r1) + addi %r1, %r1, STACKFRAME + blr +.Lmorefloat: + lfs %f4, RETVAL+12(%r1) + mtlr %r0 + lfs %f5, RETVAL+16(%r1) + lfs %f6, RETVAL+20(%r1) + lfs %f7, RETVAL+24(%r1) + lfs %f8, RETVAL+28(%r1) + addi %r1, %r1, STACKFRAME + blr +.Lsmall: +# ifdef __LITTLE_ENDIAN__ + ld %r3,RETVAL+0(%r1) mtlr %r0 - addi %r1, %r1, 240 + ld %r4,RETVAL+8(%r1) + addi %r1, %r1, STACKFRAME blr -# esac +# else + # A struct smaller than a dword is returned in the low bits of r3 + # ie. right justified. Larger structs are passed left justified + # in r3 and r4. The return value area on the stack will have + # the structs as they are usually stored in memory. + cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT + 7 # size 8 bytes? + neg %r5, %r3 + ld %r3,RETVAL+0(%r1) + blt .Lsmalldown + mtlr %r0 + ld %r4,RETVAL+8(%r1) + addi %r1, %r1, STACKFRAME + blr +.Lsmalldown: + addi %r5, %r5, FFI_V2_TYPE_SMALL_STRUCT + 7 + mtlr %r0 + sldi %r5, %r5, 3 + addi %r1, %r1, STACKFRAME + srd %r3, %r3, %r5 + blr +# endif + .LFE1: .long 0 .byte 0,12,0,1,128,0,0,0 -#ifdef _CALL_LINUX +# if _CALL_ELF == 2 + .size ffi_closure_LINUX64,.-ffi_closure_LINUX64 +# else +# ifdef _CALL_LINUX .size ffi_closure_LINUX64,.-.L.ffi_closure_LINUX64 -#else +# else .size .ffi_closure_LINUX64,.-.ffi_closure_LINUX64 -#endif +# endif +# endif .section .eh_frame,EH_FRAME_FLAGS,@progbits .Lframe1: @@ -239,14 +378,14 @@ ffi_closure_LINUX64: .byte 0x2 # DW_CFA_advance_loc1 .byte .LCFI0-.LFB1 .byte 0xe # DW_CFA_def_cfa_offset - .uleb128 240 + .uleb128 STACKFRAME .byte 0x11 # DW_CFA_offset_extended_sf .uleb128 0x41 .sleb128 -2 .align 3 .LEFDE1: -#endif -#if defined __ELF__ && defined __linux__ +# if defined __ELF__ && defined __linux__ .section .note.GNU-stack,"",@progbits +# endif #endif diff --git a/Modules/_ctypes/libffi/src/powerpc/ppc_closure.S b/Modules/_ctypes/libffi/src/powerpc/ppc_closure.S index 41fb8851b624..075922cbb07e 100644 --- a/Modules/_ctypes/libffi/src/powerpc/ppc_closure.S +++ b/Modules/_ctypes/libffi/src/powerpc/ppc_closure.S @@ -31,7 +31,7 @@ .file "ppc_closure.S" -#ifndef __powerpc64__ +#ifndef POWERPC64 ENTRY(ffi_closure_SYSV) .LFB1: @@ -159,25 +159,41 @@ ENTRY(ffi_closure_SYSV) #endif # case FFI_TYPE_UINT8 +#ifdef __LITTLE_ENDIAN__ + lbz %r3,112+0(%r1) +#else lbz %r3,112+3(%r1) +#endif mtlr %r0 addi %r1,%r1,144 blr # case FFI_TYPE_SINT8 +#ifdef __LITTLE_ENDIAN__ + lbz %r3,112+0(%r1) +#else lbz %r3,112+3(%r1) +#endif extsb %r3,%r3 mtlr %r0 b .Lfinish # case FFI_TYPE_UINT16 +#ifdef __LITTLE_ENDIAN__ + lhz %r3,112+0(%r1) +#else lhz %r3,112+2(%r1) +#endif mtlr %r0 addi %r1,%r1,144 blr # case FFI_TYPE_SINT16 +#ifdef __LITTLE_ENDIAN__ + lha %r3,112+0(%r1) +#else lha %r3,112+2(%r1) +#endif mtlr %r0 addi %r1,%r1,144 blr @@ -222,7 +238,7 @@ ENTRY(ffi_closure_SYSV) lwz %r3,112+0(%r1) lwz %r4,112+4(%r1) lwz %r5,112+8(%r1) - bl .Luint128 + b .Luint128 # The return types below are only used when the ABI type is FFI_SYSV. # case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct. @@ -239,9 +255,15 @@ ENTRY(ffi_closure_SYSV) # case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct. lwz %r3,112+0(%r1) +#ifdef __LITTLE_ENDIAN__ + mtlr %r0 + addi %r1,%r1,144 + blr +#else srwi %r3,%r3,8 mtlr %r0 b .Lfinish +#endif # case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct. lwz %r3,112+0(%r1) @@ -252,20 +274,35 @@ ENTRY(ffi_closure_SYSV) # case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct. lwz %r3,112+0(%r1) lwz %r4,112+4(%r1) +#ifdef __LITTLE_ENDIAN__ + mtlr %r0 + b .Lfinish +#else li %r5,24 b .Lstruct567 +#endif # case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct. lwz %r3,112+0(%r1) lwz %r4,112+4(%r1) +#ifdef __LITTLE_ENDIAN__ + mtlr %r0 + b .Lfinish +#else li %r5,16 b .Lstruct567 +#endif # case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct. lwz %r3,112+0(%r1) lwz %r4,112+4(%r1) +#ifdef __LITTLE_ENDIAN__ + mtlr %r0 + b .Lfinish +#else li %r5,8 b .Lstruct567 +#endif # case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct. lwz %r3,112+0(%r1) @@ -273,6 +310,7 @@ ENTRY(ffi_closure_SYSV) mtlr %r0 b .Lfinish +#ifndef __LITTLE_ENDIAN__ .Lstruct567: subfic %r6,%r5,32 srw %r4,%r4,%r5 @@ -282,13 +320,14 @@ ENTRY(ffi_closure_SYSV) mtlr %r0 addi %r1,%r1,144 blr +#endif .Luint128: lwz %r6,112+12(%r1) mtlr %r0 addi %r1,%r1,144 blr - + END(ffi_closure_SYSV) .section ".eh_frame",EH_FRAME_FLAGS,@progbits @@ -339,8 +378,7 @@ END(ffi_closure_SYSV) .align 2 .LEFDE1: -#endif - #if defined __ELF__ && defined __linux__ .section .note.GNU-stack,"",@progbits #endif +#endif diff --git a/Modules/_ctypes/libffi/src/powerpc/sysv.S b/Modules/_ctypes/libffi/src/powerpc/sysv.S index 5ee3a19fc189..fed2380c9fac 100644 --- a/Modules/_ctypes/libffi/src/powerpc/sysv.S +++ b/Modules/_ctypes/libffi/src/powerpc/sysv.S @@ -30,7 +30,7 @@ #include #include -#ifndef __powerpc64__ +#ifndef POWERPC64 .globl ffi_prep_args_SYSV ENTRY(ffi_call_SYSV) .LFB1: @@ -142,19 +142,14 @@ L(float_return_value): #endif L(small_struct_return_value): - extrwi %r6,%r31,2,19 /* number of bytes padding = shift/8 */ - mtcrf 0x02,%r31 /* copy flags to cr[24:27] (cr6) */ - extrwi %r5,%r31,5,19 /* r5 <- number of bits of padding */ - subfic %r6,%r6,4 /* r6 <- number of useful bytes in r3 */ - bf- 25,L(done_return_value) /* struct in r3 ? if not, done. */ -/* smst_one_register: */ - slw %r3,%r3,%r5 /* Left-justify value in r3 */ - mtxer %r6 /* move byte count to XER ... */ - stswx %r3,0,%r30 /* ... and store that many bytes */ - bf+ 26,L(done_return_value) /* struct in r3:r4 ? */ - add %r6,%r6,%r30 /* adjust pointer */ - stswi %r4,%r6,4 /* store last four bytes */ - b L(done_return_value) + /* + * The C code always allocates a properly-aligned 8-byte bounce + * buffer to make this assembly code very simple. Just write out + * r3 and r4 to the buffer to allow the C code to handle the rest. + */ + stw %r3, 0(%r30) + stw %r4, 4(%r30) + b L(done_return_value) .LFE1: END(ffi_call_SYSV) @@ -218,8 +213,8 @@ END(ffi_call_SYSV) .uleb128 0x1c .align 2 .LEFDE1: -#endif #if defined __ELF__ && defined __linux__ .section .note.GNU-stack,"",@progbits #endif +#endif diff --git a/Modules/_ctypes/libffi/src/prep_cif.c b/Modules/_ctypes/libffi/src/prep_cif.c index e8ec5cf1e6c4..55ceed8c5e70 100644 --- a/Modules/_ctypes/libffi/src/prep_cif.c +++ b/Modules/_ctypes/libffi/src/prep_cif.c @@ -76,6 +76,13 @@ static ffi_status initialize_aggregate(ffi_type *arg) total size of 3*sizeof(long). */ arg->size = ALIGN (arg->size, arg->alignment); + /* On some targets, the ABI defines that structures have an additional + alignment beyond the "natural" one based on their elements. */ +#ifdef FFI_AGGREGATE_ALIGNMENT + if (FFI_AGGREGATE_ALIGNMENT > arg->alignment) + arg->alignment = FFI_AGGREGATE_ALIGNMENT; +#endif + if (arg->size == 0) return FFI_BAD_TYPEDEF; else @@ -111,13 +118,8 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, FFI_ASSERT((!isvariadic) || (nfixedargs >= 1)); FFI_ASSERT(nfixedargs <= ntotalargs); -#ifndef X86_WIN32 if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI)) return FFI_BAD_ABI; -#else - if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI || abi == FFI_THISCALL)) - return FFI_BAD_ABI; -#endif cif->abi = abi; cif->arg_types = atypes; @@ -126,6 +128,10 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, cif->flags = 0; +#if HAVE_LONG_DOUBLE_VARIANT + ffi_prep_types (abi); +#endif + /* Initialize the return type if necessary */ if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK)) return FFI_BAD_TYPEDEF; @@ -146,7 +152,9 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, #ifdef XTENSA && (cif->rtype->size > 16) #endif - +#ifdef NIOS2 + && (cif->rtype->size > 8) +#endif ) bytes = STACK_ARG_SIZE(sizeof(void*)); #endif @@ -174,7 +182,7 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi, { /* Add any padding if necessary */ if (((*ptr)->alignment - 1) & bytes) - bytes = ALIGN(bytes, (*ptr)->alignment); + bytes = (unsigned)ALIGN(bytes, (*ptr)->alignment); #ifdef TILE if (bytes < 10 * FFI_SIZEOF_ARG && diff --git a/Modules/_ctypes/libffi/src/sh/ffi.c b/Modules/_ctypes/libffi/src/sh/ffi.c index 3515b91b1d07..9ec86bfb205c 100644 --- a/Modules/_ctypes/libffi/src/sh/ffi.c +++ b/Modules/_ctypes/libffi/src/sh/ffi.c @@ -41,7 +41,7 @@ #define STRUCT_VALUE_ADDRESS_WITH_ARG 0 #endif -/* If the structure has essentialy an unique element, return its type. */ +/* If the structure has essentially an unique element, return its type. */ static int simple_type (ffi_type *arg) { diff --git a/Modules/_ctypes/libffi/src/tile/tile.S b/Modules/_ctypes/libffi/src/tile/tile.S index a186e1f8f008..d1f82cb3dbfa 100644 --- a/Modules/_ctypes/libffi/src/tile/tile.S +++ b/Modules/_ctypes/libffi/src/tile/tile.S @@ -60,7 +60,7 @@ void (*fnaddr)(void)); On entry, REG_ARGS contain the outgoing register values, - and STACK_ARGS containts STACK_ARG_BYTES of additional values + and STACK_ARGS contains STACK_ARG_BYTES of additional values to be passed on the stack. If STACK_ARG_BYTES is zero, then STACK_ARGS is ignored. diff --git a/Modules/_ctypes/libffi/src/types.c b/Modules/_ctypes/libffi/src/types.c index 0a11eb0fb4b0..0de59942396c 100644 --- a/Modules/_ctypes/libffi/src/types.c +++ b/Modules/_ctypes/libffi/src/types.c @@ -44,6 +44,17 @@ const ffi_type ffi_type_##name = { \ id, NULL \ } +#define FFI_NONCONST_TYPEDEF(name, type, id) \ +struct struct_align_##name { \ + char c; \ + type x; \ +}; \ +ffi_type ffi_type_##name = { \ + sizeof(type), \ + offsetof(struct struct_align_##name, x), \ + id, NULL \ +} + /* Size and alignment are fake here. They must not be 0. */ const ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID, NULL @@ -73,5 +84,9 @@ FFI_TYPEDEF(double, double, FFI_TYPE_DOUBLE); # endif const ffi_type ffi_type_longdouble = { 16, 16, 4, NULL }; #elif FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE +# if HAVE_LONG_DOUBLE_VARIANT +FFI_NONCONST_TYPEDEF(longdouble, long double, FFI_TYPE_LONGDOUBLE); +# else FFI_TYPEDEF(longdouble, long double, FFI_TYPE_LONGDOUBLE); +# endif #endif diff --git a/Modules/_ctypes/libffi/src/vax/elfbsd.S b/Modules/_ctypes/libffi/src/vax/elfbsd.S new file mode 100644 index 000000000000..01ca313402b2 --- /dev/null +++ b/Modules/_ctypes/libffi/src/vax/elfbsd.S @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * 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. + */ + +/* + * vax Foreign Function Interface + */ + +#define LIBFFI_ASM +#include +#include + + .text + +/* + * void * %r0 + * ffi_call_elfbsd(extended_cif *ecif, 4(%ap) + * unsigned bytes, 8(%ap) + * unsigned flags, 12(%ap) + * void *rvalue, 16(%ap) + * void (*fn)()); 20(%ap) + */ + .globl ffi_call_elfbsd + .type ffi_call_elfbsd,@function + .align 2 +ffi_call_elfbsd: + .word 0x00c # save R2 and R3 + + # Allocate stack space for the args + subl2 8(%ap), %sp + + # Call ffi_prep_args + pushl %sp + pushl 4(%ap) + calls $2, ffi_prep_args + + # Get function pointer + movl 20(%ap), %r1 + + # Build a CALLS frame + ashl $-2, 8(%ap), %r0 + pushl %r0 # argument stack usage + movl %sp, %r0 # future %ap + # saved registers + bbc $11, 0(%r1), 1f + pushl %r11 +1: bbc $10, 0(%r1), 1f + pushl %r10 +1: bbc $9, 0(%r1), 1f + pushl %r9 +1: bbc $8, 0(%r1), 1f + pushl %r8 +1: bbc $7, 0(%r1), 1f + pushl %r7 +1: bbc $6, 0(%r1), 1f + pushl %r6 +1: bbc $5, 0(%r1), 1f + pushl %r5 +1: bbc $4, 0(%r1), 1f + pushl %r4 +1: bbc $3, 0(%r1), 1f + pushl %r3 +1: bbc $2, 0(%r1), 1f + pushl %r2 +1: + pushal 9f + pushl %fp + pushl %ap + movl 16(%ap), %r3 # struct return address, if needed + movl %r0, %ap + movzwl 4(%fp), %r0 # previous PSW, without the saved registers mask + bisl2 $0x20000000, %r0 # calls frame + movzwl 0(%r1), %r2 + bicw2 $0xf003, %r2 # only keep R11-R2 + ashl $16, %r2, %r2 + bisl2 %r2, %r0 # saved register mask of the called function + pushl %r0 + pushl $0 + movl %sp, %fp + + # Invoke the function + pushal 2(%r1) # skip procedure entry mask + movl %r3, %r1 + bicpsw $0x000f + rsb + +9: + # Copy return value if necessary + tstl 16(%ap) + jeql 9f + movl 16(%ap), %r2 + + bbc $0, 12(%ap), 1f # CIF_FLAGS_CHAR + movb %r0, 0(%r2) + brb 9f +1: + bbc $1, 12(%ap), 1f # CIF_FLAGS_SHORT + movw %r0, 0(%r2) + brb 9f +1: + bbc $2, 12(%ap), 1f # CIF_FLAGS_INT + movl %r0, 0(%r2) + brb 9f +1: + bbc $3, 12(%ap), 1f # CIF_FLAGS_DINT + movq %r0, 0(%r2) + brb 9f +1: + movl %r1, %r0 # might have been a struct + #brb 9f + +9: + ret + +/* + * ffi_closure_elfbsd(void); + * invoked with %r0: ffi_closure *closure + */ + .globl ffi_closure_elfbsd + .type ffi_closure_elfbsd, @function + .align 2 +ffi_closure_elfbsd: + .word 0 + + # Allocate room on stack for return value + subl2 $8, %sp + + # Invoke the closure function + pushal 4(%ap) # calling stack + pushal 4(%sp) # return value + pushl %r0 # closure + calls $3, ffi_closure_elfbsd_inner + + # Copy return value if necessary + bitb $1, %r0 # CIF_FLAGS_CHAR + beql 1f + movb 0(%sp), %r0 + brb 9f +1: + bitb $2, %r0 # CIF_FLAGS_SHORT + beql 1f + movw 0(%sp), %r0 + brb 9f +1: + bitb $4, %r0 # CIF_FLAGS_INT + beql 1f + movl 0(%sp), %r0 + brb 9f +1: + bitb $8, %r0 # CIF_FLAGS_DINT + beql 1f + movq 0(%sp), %r0 + #brb 9f +1: + +9: + ret + +/* + * ffi_closure_struct_elfbsd(void); + * invoked with %r0: ffi_closure *closure + * %r1: struct return address + */ + .globl ffi_closure_struct_elfbsd + .type ffi_closure_struct_elfbsd, @function + .align 2 +ffi_closure_struct_elfbsd: + .word 0 + + # Invoke the closure function + pushal 4(%ap) # calling stack + pushl %r1 # return value + pushl %r0 # closure + calls $3, ffi_closure_elfbsd_inner + + ret diff --git a/Modules/_ctypes/libffi/src/vax/ffi.c b/Modules/_ctypes/libffi/src/vax/ffi.c new file mode 100644 index 000000000000..f4d6bbb4f404 --- /dev/null +++ b/Modules/_ctypes/libffi/src/vax/ffi.c @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * 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. + */ + +/* + * vax Foreign Function Interface + * + * This file attempts to provide all the FFI entry points which can reliably + * be implemented in C. + */ + +#include +#include + +#include +#include + +#define CIF_FLAGS_CHAR 1 /* for struct only */ +#define CIF_FLAGS_SHORT 2 /* for struct only */ +#define CIF_FLAGS_INT 4 +#define CIF_FLAGS_DINT 8 + +/* + * Foreign Function Interface API + */ + +void ffi_call_elfbsd (extended_cif *, unsigned, unsigned, void *, + void (*) ()); +void *ffi_prep_args (extended_cif *ecif, void *stack); + +void * +ffi_prep_args (extended_cif *ecif, void *stack) +{ + unsigned int i; + void **p_argv; + char *argp; + ffi_type **p_arg; + void *struct_value_ptr; + + argp = stack; + + if (ecif->cif->rtype->type == FFI_TYPE_STRUCT + && !ecif->cif->flags) + struct_value_ptr = ecif->rvalue; + else + struct_value_ptr = NULL; + + p_argv = ecif->avalue; + + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; + i != 0; + i--, p_arg++) + { + size_t z; + + z = (*p_arg)->size; + if (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_STRUCT: + memcpy (argp, *p_argv, z); + break; + + default: + FFI_ASSERT (0); + } + z = sizeof (int); + } + else + { + memcpy (argp, *p_argv, z); + + /* Align if necessary. */ + if ((sizeof(int) - 1) & z) + z = ALIGN(z, sizeof(int)); + } + + p_argv++; + argp += z; + } + + return struct_value_ptr; +} + +ffi_status +ffi_prep_cif_machdep (ffi_cif *cif) +{ + /* Set the return type flag */ + switch (cif->rtype->type) + { + case FFI_TYPE_VOID: + cif->flags = 0; + break; + + case FFI_TYPE_STRUCT: + if (cif->rtype->elements[0]->type == FFI_TYPE_STRUCT && + cif->rtype->elements[1]) + { + cif->flags = 0; + break; + } + + if (cif->rtype->size == sizeof (char)) + cif->flags = CIF_FLAGS_CHAR; + else if (cif->rtype->size == sizeof (short)) + cif->flags = CIF_FLAGS_SHORT; + else if (cif->rtype->size == sizeof (int)) + cif->flags = CIF_FLAGS_INT; + else if (cif->rtype->size == 2 * sizeof (int)) + cif->flags = CIF_FLAGS_DINT; + else + cif->flags = 0; + break; + + default: + if (cif->rtype->size <= sizeof (int)) + cif->flags = CIF_FLAGS_INT; + else + cif->flags = CIF_FLAGS_DINT; + break; + } + + return FFI_OK; +} + +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->rtype->type == FFI_TYPE_STRUCT + && cif->flags == 0) + ecif.rvalue = alloca (cif->rtype->size); + else + ecif.rvalue = rvalue; + + switch (cif->abi) + { + case FFI_ELFBSD: + ffi_call_elfbsd (&ecif, cif->bytes, cif->flags, ecif.rvalue, fn); + break; + + default: + FFI_ASSERT (0); + break; + } +} + +/* + * Closure API + */ + +void ffi_closure_elfbsd (void); +void ffi_closure_struct_elfbsd (void); +unsigned int ffi_closure_elfbsd_inner (ffi_closure *, void *, char *); + +static void +ffi_prep_closure_elfbsd (ffi_cif *cif, void **avalue, char *stackp) +{ + unsigned int i; + void **p_argv; + ffi_type **p_arg; + + p_argv = avalue; + + for (i = cif->nargs, p_arg = cif->arg_types; i != 0; i--, p_arg++) + { + size_t z; + + z = (*p_arg)->size; + *p_argv = stackp; + + /* Align if necessary */ + if ((sizeof (int) - 1) & z) + z = ALIGN(z, sizeof (int)); + + p_argv++; + stackp += z; + } +} + +unsigned int +ffi_closure_elfbsd_inner (ffi_closure *closure, void *resp, char *stack) +{ + ffi_cif *cif; + void **arg_area; + + cif = closure->cif; + arg_area = (void **) alloca (cif->nargs * sizeof (void *)); + + ffi_prep_closure_elfbsd (cif, arg_area, stack); + + (closure->fun) (cif, resp, arg_area, closure->user_data); + + return cif->flags; +} + +ffi_status +ffi_prep_closure_loc (ffi_closure *closure, ffi_cif *cif, + void (*fun)(ffi_cif *, void *, void **, void *), + void *user_data, void *codeloc) +{ + char *tramp = (char *) codeloc; + void *fn; + + FFI_ASSERT (cif->abi == FFI_ELFBSD); + + /* entry mask */ + *(unsigned short *)(tramp + 0) = 0x0000; + /* movl #closure, r0 */ + tramp[2] = 0xd0; + tramp[3] = 0x8f; + *(unsigned int *)(tramp + 4) = (unsigned int) closure; + tramp[8] = 0x50; + + if (cif->rtype->type == FFI_TYPE_STRUCT + && !cif->flags) + fn = &ffi_closure_struct_elfbsd; + else + fn = &ffi_closure_elfbsd; + + /* jmpl #fn */ + tramp[9] = 0x17; + tramp[10] = 0xef; + *(unsigned int *)(tramp + 11) = (unsigned int)fn + 2 - + (unsigned int)tramp - 9 - 6; + + closure->cif = cif; + closure->user_data = user_data; + closure->fun = fun; + + return FFI_OK; +} diff --git a/Modules/_ctypes/libffi/src/vax/ffitarget.h b/Modules/_ctypes/libffi/src/vax/ffitarget.h new file mode 100644 index 000000000000..2fc94881abbc --- /dev/null +++ b/Modules/_ctypes/libffi/src/vax/ffitarget.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 Miodrag Vallat. + * + * 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. + */ + +/* + * vax Foreign Function Interface + */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_ELFBSD, + FFI_DEFAULT_ABI = FFI_ELFBSD, + FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_TRAMPOLINE_SIZE 15 +#define FFI_NATIVE_RAW_API 0 + +#endif diff --git a/Modules/_ctypes/libffi/src/x86/ffi.c b/Modules/_ctypes/libffi/src/x86/ffi.c index 0600414d458e..dbf9c8e3263b 100644 --- a/Modules/_ctypes/libffi/src/x86/ffi.c +++ b/Modules/_ctypes/libffi/src/x86/ffi.c @@ -39,16 +39,18 @@ #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; -#ifdef X86_WIN32 +#ifndef X86_WIN64 size_t p_stack_args[2]; void *p_stack_data[2]; char *argp2 = stack; @@ -67,7 +69,7 @@ void ffi_prep_args(char *stack, extended_cif *ecif) ) { *(void **) argp = ecif->rvalue; -#ifdef X86_WIN32 +#ifndef X86_WIN64 /* For fastcall/thiscall this is first register-passed argument. */ if (cabi == FFI_THISCALL || cabi == FFI_FASTCALL) @@ -153,7 +155,7 @@ void ffi_prep_args(char *stack, extended_cif *ecif) memcpy(argp, *p_argv, z); } -#ifdef X86_WIN32 +#ifndef X86_WIN64 /* For thiscall/fastcall convention register-passed arguments are the first two none-floating-point arguments with a size smaller or equal to sizeof (void*). */ @@ -178,7 +180,7 @@ void ffi_prep_args(char *stack, extended_cif *ecif) #endif } -#ifdef X86_WIN32 +#ifndef X86_WIN64 /* We need to move the register-passed arguments for thiscall/fastcall on top of stack, so that those can be moved to registers ecx/edx by call-handler. */ @@ -307,7 +309,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) { if (((*ptr)->alignment - 1) & cif->bytes) cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment); - cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG); + cif->bytes += (unsigned)ALIGN((*ptr)->size, FFI_SIZEOF_ARG); } #ifdef X86_WIN64 @@ -315,7 +317,12 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) cif->bytes += 4 * sizeof(ffi_arg); #endif - cif->bytes = (cif->bytes + 15) & ~0xF; +#ifndef X86_WIN32 +#ifndef X86_WIN64 + if (cif->abi != FFI_STDCALL && cif->abi != FFI_THISCALL && cif->abi != FFI_FASTCALL) +#endif + cif->bytes = (cif->bytes + 15) & ~0xF; +#endif return FFI_OK; } @@ -372,8 +379,8 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) break; #elif defined(X86_WIN32) case FFI_SYSV: - case FFI_STDCALL: case FFI_MS_CDECL: + case FFI_STDCALL: ffi_call_win32(ffi_prep_args, &ecif, cif->abi, cif->bytes, cif->flags, ecif.rvalue, fn); break; @@ -434,12 +441,15 @@ void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *) #ifdef X86_WIN32 void FFI_HIDDEN ffi_closure_raw_THISCALL (ffi_raw_closure *) __attribute__ ((regparm(1))); +#endif +#ifndef X86_WIN64 void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *) __attribute__ ((regparm(1))); void FFI_HIDDEN ffi_closure_THISCALL (ffi_closure *) __attribute__ ((regparm(1))); -#endif -#ifdef X86_WIN64 +void FFI_HIDDEN ffi_closure_FASTCALL (ffi_closure *) + __attribute__ ((regparm(1))); +#else void FFI_HIDDEN ffi_closure_win64 (ffi_closure *); #endif @@ -598,7 +608,7 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \ } -#define FFI_INIT_TRAMPOLINE_THISCALL(TRAMP,FUN,CTX,SIZE) \ +#define FFI_INIT_TRAMPOLINE_RAW_THISCALL(TRAMP,FUN,CTX,SIZE) \ { unsigned char *__tramp = (unsigned char*)(TRAMP); \ unsigned int __fun = (unsigned int)(FUN); \ unsigned int __ctx = (unsigned int)(CTX); \ @@ -625,18 +635,15 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, *(unsigned short*) &__tramp[50] = (__size + 8); /* ret (__size + 8) */ \ } -#define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \ +#define FFI_INIT_TRAMPOLINE_STDCALL(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 + 10); \ - unsigned short __size = (unsigned short)(SIZE); \ *(unsigned char*) &__tramp[0] = 0xb8; \ *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \ *(unsigned char *) &__tramp[5] = 0xe8; \ *(unsigned int*) &__tramp[6] = __dis; /* call __fun */ \ - *(unsigned char *) &__tramp[10] = 0xc2; \ - *(unsigned short*) &__tramp[11] = __size; /* ret __size */ \ } /* the cif must already be prep'ed */ @@ -666,20 +673,25 @@ ffi_prep_closure_loc (ffi_closure* closure, &ffi_closure_SYSV, (void*)codeloc); } -#ifdef X86_WIN32 + else if (cif->abi == FFI_FASTCALL) + { + FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0], + &ffi_closure_FASTCALL, + (void*)codeloc); + } else if (cif->abi == FFI_THISCALL) { - FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0], - &ffi_closure_THISCALL, - (void*)codeloc, - cif->bytes); + FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0], + &ffi_closure_THISCALL, + (void*)codeloc); } else if (cif->abi == FFI_STDCALL) { FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0], &ffi_closure_STDCALL, - (void*)codeloc, cif->bytes); + (void*)codeloc); } +#ifdef X86_WIN32 else if (cif->abi == FFI_MS_CDECL) { FFI_INIT_TRAMPOLINE (&closure->tramp[0], @@ -713,12 +725,12 @@ ffi_prep_raw_closure_loc (ffi_raw_closure* closure, { int i; - if (cif->abi != FFI_SYSV) { + if (cif->abi != FFI_SYSV #ifdef X86_WIN32 - if (cif->abi != FFI_THISCALL) + && cif->abi != FFI_THISCALL #endif + ) return FFI_BAD_ABI; - } /* we currently don't support certain kinds of arguments for raw closures. This should be implemented by a separate assembly @@ -741,8 +753,7 @@ ffi_prep_raw_closure_loc (ffi_raw_closure* closure, } else if (cif->abi == FFI_THISCALL) { - FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0], &ffi_closure_raw_THISCALL, - codeloc, cif->bytes); + FFI_INIT_TRAMPOLINE_RAW_THISCALL (&closure->tramp[0], &ffi_closure_raw_THISCALL, codeloc, cif->bytes); } #endif closure->cif = cif; @@ -775,22 +786,37 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue) /* If the return value is a struct and we don't have a return */ /* value address then we need to make one */ +#ifdef X86_WIN64 + if (rvalue == NULL + && cif->flags == FFI_TYPE_STRUCT + && cif->rtype->size != 1 && cif->rtype->size != 2 + && cif->rtype->size != 4 && cif->rtype->size != 8) + { + ecif.rvalue = alloca((cif->rtype->size + 0xF) & ~0xF); + } +#else if (rvalue == NULL && (cif->flags == FFI_TYPE_STRUCT || cif->flags == FFI_TYPE_MS_STRUCT)) { ecif.rvalue = alloca(cif->rtype->size); } +#endif else ecif.rvalue = rvalue; switch (cif->abi) { -#ifdef X86_WIN32 +#ifdef X86_WIN64 + case FFI_WIN64: + ffi_call_win64(ffi_prep_args_raw, &ecif, cif->bytes, + cif->flags, ecif.rvalue, fn); + break; +#elif defined(X86_WIN32) case FFI_SYSV: - case FFI_STDCALL: case FFI_MS_CDECL: + case FFI_STDCALL: ffi_call_win32(ffi_prep_args_raw, &ecif, cif->abi, cif->bytes, cif->flags, ecif.rvalue, fn); break; @@ -816,17 +842,17 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue) ++passed_regs; } if (passed_regs < 2 && abi == FFI_FASTCALL) - cif->abi = abi = FFI_THISCALL; + abi = FFI_THISCALL; if (passed_regs < 1 && abi == FFI_THISCALL) - cif->abi = abi = FFI_STDCALL; + abi = FFI_STDCALL; ffi_call_win32(ffi_prep_args_raw, &ecif, abi, cif->bytes, cif->flags, ecif.rvalue, fn); } break; #else case FFI_SYSV: - ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, - ecif.rvalue, fn); + ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, ecif.rvalue, + fn); break; #endif default: diff --git a/Modules/_ctypes/libffi/src/x86/ffi64.c b/Modules/_ctypes/libffi/src/x86/ffi64.c index 2014af24c655..5a5e04383548 100644 --- a/Modules/_ctypes/libffi/src/x86/ffi64.c +++ b/Modules/_ctypes/libffi/src/x86/ffi64.c @@ -3,8 +3,8 @@ Copyright (c) 2011 Anthony Green Copyright (c) 2008, 2010 Red Hat, Inc. Copyright (c) 2002, 2007 Bo Thorsen - - x86-64 Foreign Function Interface + + 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 @@ -39,6 +39,7 @@ #define MAX_SSE_REGS 8 #if defined(__INTEL_COMPILER) +#include "xmmintrin.h" #define UINT128 __m128 #else #if defined(__SUNPRO_C) @@ -60,7 +61,7 @@ struct register_args { /* Registers for argument passing. */ UINT64 gpr[MAX_GPR_REGS]; - union big_int_union sse[MAX_SSE_REGS]; + union big_int_union sse[MAX_SSE_REGS]; }; extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags, @@ -151,7 +152,7 @@ merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2) See the x86-64 PS ABI for details. */ -static int +static size_t classify_argument (ffi_type *type, enum x86_64_reg_class classes[], size_t byte_offset) { @@ -167,7 +168,7 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[], case FFI_TYPE_SINT64: case FFI_TYPE_POINTER: { - int size = byte_offset + type->size; + size_t size = byte_offset + type->size; if (size <= 4) { @@ -202,15 +203,17 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[], case FFI_TYPE_DOUBLE: classes[0] = X86_64_SSEDF_CLASS; return 1; +#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE case FFI_TYPE_LONGDOUBLE: classes[0] = X86_64_X87_CLASS; classes[1] = X86_64_X87UP_CLASS; return 2; +#endif case FFI_TYPE_STRUCT: { - const int UNITS_PER_WORD = 8; - int words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; - ffi_type **ptr; + const size_t UNITS_PER_WORD = 8; + size_t words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; + ffi_type **ptr; int i; enum x86_64_reg_class subclasses[MAX_CLASSES]; @@ -232,7 +235,7 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[], /* Merge the fields of structure. */ for (ptr = type->elements; *ptr != NULL; ptr++) { - int num; + size_t num; byte_offset = ALIGN (byte_offset, (*ptr)->alignment); @@ -241,7 +244,7 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[], return 0; for (i = 0; i < num; i++) { - int pos = byte_offset / 8; + size_t pos = byte_offset / 8; classes[i + pos] = merge_classes (subclasses[i], classes[i + pos]); } @@ -305,11 +308,12 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[], class. Return zero iff parameter should be passed in memory, otherwise the number of registers. */ -static int +static size_t examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES], _Bool in_return, int *pngpr, int *pnsse) { - int i, n, ngpr, nsse; + size_t n; + int i, ngpr, nsse; n = classify_argument (type, classes, 0); if (n == 0) @@ -350,9 +354,9 @@ examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES], ffi_status ffi_prep_cif_machdep (ffi_cif *cif) { - int gprcount, ssecount, i, avn, n, ngpr, nsse, flags; + int gprcount, ssecount, i, avn, ngpr, nsse, flags; enum x86_64_reg_class classes[MAX_CLASSES]; - size_t bytes; + size_t bytes, n; gprcount = ssecount = 0; @@ -410,7 +414,7 @@ ffi_prep_cif_machdep (ffi_cif *cif) if (ssecount) flags |= 1 << 11; cif->flags = flags; - cif->bytes = ALIGN (bytes, 8); + cif->bytes = (unsigned)ALIGN (bytes, 8); return FFI_OK; } @@ -453,8 +457,7 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) for (i = 0; i < avn; ++i) { - size_t size = arg_types[i]->size; - int n; + size_t n, size = arg_types[i]->size; n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse); if (n == 0 @@ -583,7 +586,7 @@ ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue, if (ret != FFI_TYPE_VOID) { enum x86_64_reg_class classes[MAX_CLASSES]; - int n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse); + size_t n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse); if (n == 0) { /* The return value goes in memory. Arrange for the closure @@ -606,11 +609,11 @@ ffi_closure_unix64_inner(ffi_closure *closure, void *rvalue, avn = cif->nargs; arg_types = cif->arg_types; - + for (i = 0; i < avn; ++i) { enum x86_64_reg_class classes[MAX_CLASSES]; - int n; + size_t n; n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse); if (n == 0 diff --git a/Modules/_ctypes/libffi/src/x86/ffitarget.h b/Modules/_ctypes/libffi/src/x86/ffitarget.h index 46f294cea723..b2afe9112372 100644 --- a/Modules/_ctypes/libffi/src/x86/ffitarget.h +++ b/Modules/_ctypes/libffi/src/x86/ffitarget.h @@ -98,6 +98,9 @@ typedef enum ffi_abi { /* ---- Intel x86 and AMD x86-64 - */ FFI_SYSV, FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */ + FFI_THISCALL, + FFI_FASTCALL, + FFI_STDCALL, FFI_LAST_ABI, #if defined(__i386__) || defined(__i386) FFI_DEFAULT_ABI = FFI_SYSV diff --git a/Modules/_ctypes/libffi/src/x86/freebsd.S b/Modules/_ctypes/libffi/src/x86/freebsd.S index afde513164e4..97e0b4eb81bc 100644 --- a/Modules/_ctypes/libffi/src/x86/freebsd.S +++ b/Modules/_ctypes/libffi/src/x86/freebsd.S @@ -49,6 +49,9 @@ ffi_call_SYSV: movl 16(%ebp),%ecx subl %ecx,%esp + /* Align the stack pointer to 16-bytes */ + andl $0xfffffff0, %esp + movl %esp,%eax /* Place all of the ffi_prep_args in position */ @@ -456,3 +459,5 @@ ffi_closure_raw_SYSV: #endif #endif /* ifndef __x86_64__ */ + + .section .note.GNU-stack,"",%progbits diff --git a/Modules/_ctypes/libffi/src/x86/win32.S b/Modules/_ctypes/libffi/src/x86/win32.S index 24b7bbd04235..daf0e799ca46 100644 --- a/Modules/_ctypes/libffi/src/x86/win32.S +++ b/Modules/_ctypes/libffi/src/x86/win32.S @@ -33,8 +33,13 @@ #include #include +#define CIF_ABI_OFFSET 0 +#define CIF_BYTES_OFFSET 16 + #ifdef _MSC_VER +#define CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) AND NOT 3) + .386 .MODEL FLAT, C @@ -188,14 +193,23 @@ ca_epilogue: ret ffi_call_win32 ENDP -ffi_closure_THISCALL PROC NEAR FORCEFRAME - sub esp, 40 - lea edx, [ebp -24] - mov [ebp - 12], edx /* resp */ - lea edx, [ebp + 12] /* account for stub return address on stack */ - jmp stub +ffi_closure_THISCALL PROC NEAR + ;; Insert the register argument on the stack as the first argument + xchg DWORD PTR [esp+4], ecx + xchg DWORD PTR [esp], ecx + push ecx + jmp ffi_closure_STDCALL ffi_closure_THISCALL ENDP +ffi_closure_FASTCALL PROC NEAR + ;; Insert the register argument on the stack as the first argument + xchg DWORD PTR [esp+4], edx + xchg DWORD PTR [esp], ecx + push edx + push ecx + jmp ffi_closure_STDCALL +ffi_closure_FASTCALL ENDP + ffi_closure_SYSV PROC NEAR FORCEFRAME ;; the ffi_closure ctx is passed in eax by the trampoline. @@ -464,8 +478,23 @@ cd_retlongdouble: jmp cd_epilogue cd_epilogue: - ;; Epilogue code is autogenerated. - ret + mov esp, ebp + pop ebp + pop ecx + pop edx + mov ecx, DWORD PTR [ecx + (CLOSURE_CIF_OFFSET-10)] + add esp, DWORD PTR [ecx + CIF_BYTES_OFFSET] + mov ecx, DWORD PTR [ecx + CIF_ABI_OFFSET] + cmp ecx, 3 + je cd_thiscall + cmp ecx, 4 + jne cd_not_fastcall + + add esp, 4 +cd_thiscall: + add esp, 4 +cd_not_fastcall: + jmp edx ffi_closure_STDCALL ENDP _TEXT ENDS @@ -473,15 +502,23 @@ END #else +#define CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3) + +#if defined(SYMBOL_UNDERSCORE) +#define USCORE_SYMBOL(x) _##x +#else +#define USCORE_SYMBOL(x) x +#endif .text # This assumes we are using gas. .balign 16 - .globl _ffi_call_win32 -#ifndef __OS2__ +FFI_HIDDEN(ffi_call_win32) + .globl USCORE_SYMBOL(ffi_call_win32) +#if defined(X86_WIN32) && !defined(__OS2__) .def _ffi_call_win32; .scl 2; .type 32; .endef #endif -_ffi_call_win32: +USCORE_SYMBOL(ffi_call_win32): .LFB1: pushl %ebp .LCFI0: @@ -542,31 +579,32 @@ _ffi_call_win32: call 1f # Do not insert anything here between the call and the jump table. .Lstore_table: - .long .Lnoretval /* FFI_TYPE_VOID */ - .long .Lretint /* FFI_TYPE_INT */ - .long .Lretfloat /* FFI_TYPE_FLOAT */ - .long .Lretdouble /* FFI_TYPE_DOUBLE */ - .long .Lretlongdouble /* FFI_TYPE_LONGDOUBLE */ - .long .Lretuint8 /* FFI_TYPE_UINT8 */ - .long .Lretsint8 /* FFI_TYPE_SINT8 */ - .long .Lretuint16 /* FFI_TYPE_UINT16 */ - .long .Lretsint16 /* FFI_TYPE_SINT16 */ - .long .Lretint /* FFI_TYPE_UINT32 */ - .long .Lretint /* FFI_TYPE_SINT32 */ - .long .Lretint64 /* FFI_TYPE_UINT64 */ - .long .Lretint64 /* FFI_TYPE_SINT64 */ - .long .Lretstruct /* FFI_TYPE_STRUCT */ - .long .Lretint /* FFI_TYPE_POINTER */ - .long .Lretstruct1b /* FFI_TYPE_SMALL_STRUCT_1B */ - .long .Lretstruct2b /* FFI_TYPE_SMALL_STRUCT_2B */ - .long .Lretstruct4b /* FFI_TYPE_SMALL_STRUCT_4B */ - .long .Lretstruct /* FFI_TYPE_MS_STRUCT */ + .long .Lnoretval-.Lstore_table /* FFI_TYPE_VOID */ + .long .Lretint-.Lstore_table /* FFI_TYPE_INT */ + .long .Lretfloat-.Lstore_table /* FFI_TYPE_FLOAT */ + .long .Lretdouble-.Lstore_table /* FFI_TYPE_DOUBLE */ + .long .Lretlongdouble-.Lstore_table /* FFI_TYPE_LONGDOUBLE */ + .long .Lretuint8-.Lstore_table /* FFI_TYPE_UINT8 */ + .long .Lretsint8-.Lstore_table /* FFI_TYPE_SINT8 */ + .long .Lretuint16-.Lstore_table /* FFI_TYPE_UINT16 */ + .long .Lretsint16-.Lstore_table /* FFI_TYPE_SINT16 */ + .long .Lretint-.Lstore_table /* FFI_TYPE_UINT32 */ + .long .Lretint-.Lstore_table /* FFI_TYPE_SINT32 */ + .long .Lretint64-.Lstore_table /* FFI_TYPE_UINT64 */ + .long .Lretint64-.Lstore_table /* FFI_TYPE_SINT64 */ + .long .Lretstruct-.Lstore_table /* FFI_TYPE_STRUCT */ + .long .Lretint-.Lstore_table /* FFI_TYPE_POINTER */ + .long .Lretstruct1b-.Lstore_table /* FFI_TYPE_SMALL_STRUCT_1B */ + .long .Lretstruct2b-.Lstore_table /* FFI_TYPE_SMALL_STRUCT_2B */ + .long .Lretstruct4b-.Lstore_table /* FFI_TYPE_SMALL_STRUCT_4B */ + .long .Lretstruct-.Lstore_table /* FFI_TYPE_MS_STRUCT */ 1: - add %ecx, %ecx - add %ecx, %ecx + shl $2, %ecx + add (%esp),%ecx + mov (%ecx),%ecx add (%esp),%ecx add $4, %esp - jmp *(%ecx) + jmp *%ecx /* Sign/zero extend as appropriate. */ .Lretsint8: @@ -644,27 +682,43 @@ _ffi_call_win32: ret .ffi_call_win32_end: .balign 16 - .globl _ffi_closure_THISCALL -#ifndef __OS2__ +FFI_HIDDEN(ffi_closure_THISCALL) + .globl USCORE_SYMBOL(ffi_closure_THISCALL) +#if defined(X86_WIN32) && !defined(__OS2__) .def _ffi_closure_THISCALL; .scl 2; .type 32; .endef #endif -_ffi_closure_THISCALL: - pushl %ebp - movl %esp, %ebp - subl $40, %esp - leal -24(%ebp), %edx - movl %edx, -12(%ebp) /* resp */ - leal 12(%ebp), %edx /* account for stub return address on stack */ - jmp .stub +USCORE_SYMBOL(ffi_closure_THISCALL): + /* Insert the register argument on the stack as the first argument */ + xchg %ecx, 4(%esp) + xchg %ecx, (%esp) + push %ecx + jmp .ffi_closure_STDCALL_internal + + .balign 16 +FFI_HIDDEN(ffi_closure_FASTCALL) + .globl USCORE_SYMBOL(ffi_closure_FASTCALL) +#if defined(X86_WIN32) && !defined(__OS2__) + .def _ffi_closure_FASTCALL; .scl 2; .type 32; .endef +#endif +USCORE_SYMBOL(ffi_closure_FASTCALL): + /* Insert the register arguments on the stack as the first two arguments */ + xchg %edx, 4(%esp) + xchg %ecx, (%esp) + push %edx + push %ecx + jmp .ffi_closure_STDCALL_internal .LFE1: # This assumes we are using gas. .balign 16 - .globl _ffi_closure_SYSV -#ifndef __OS2__ +FFI_HIDDEN(ffi_closure_SYSV) +#if defined(X86_WIN32) + .globl USCORE_SYMBOL(ffi_closure_SYSV) +#if defined(X86_WIN32) && !defined(__OS2__) .def _ffi_closure_SYSV; .scl 2; .type 32; .endef #endif -_ffi_closure_SYSV: +USCORE_SYMBOL(ffi_closure_SYSV): +#endif .LFB3: pushl %ebp .LCFI4: @@ -674,43 +728,54 @@ _ffi_closure_SYSV: leal -24(%ebp), %edx movl %edx, -12(%ebp) /* resp */ leal 8(%ebp), %edx -.stub: movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */ leal -12(%ebp), %edx movl %edx, (%esp) /* &resp */ - call _ffi_closure_SYSV_inner +#if defined(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE) || !defined(__PIC__) + call USCORE_SYMBOL(ffi_closure_SYSV_inner) +#elif defined(X86_DARWIN) + calll L_ffi_closure_SYSV_inner$stub +#else + movl %ebx, 8(%esp) + call 1f +1: popl %ebx + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx + call ffi_closure_SYSV_inner@PLT + movl 8(%esp), %ebx +#endif movl -12(%ebp), %ecx 0: call 1f # Do not insert anything here between the call and the jump table. .Lcls_store_table: - .long .Lcls_noretval /* FFI_TYPE_VOID */ - .long .Lcls_retint /* FFI_TYPE_INT */ - .long .Lcls_retfloat /* FFI_TYPE_FLOAT */ - .long .Lcls_retdouble /* FFI_TYPE_DOUBLE */ - .long .Lcls_retldouble /* FFI_TYPE_LONGDOUBLE */ - .long .Lcls_retuint8 /* FFI_TYPE_UINT8 */ - .long .Lcls_retsint8 /* FFI_TYPE_SINT8 */ - .long .Lcls_retuint16 /* FFI_TYPE_UINT16 */ - .long .Lcls_retsint16 /* FFI_TYPE_SINT16 */ - .long .Lcls_retint /* FFI_TYPE_UINT32 */ - .long .Lcls_retint /* FFI_TYPE_SINT32 */ - .long .Lcls_retllong /* FFI_TYPE_UINT64 */ - .long .Lcls_retllong /* FFI_TYPE_SINT64 */ - .long .Lcls_retstruct /* FFI_TYPE_STRUCT */ - .long .Lcls_retint /* FFI_TYPE_POINTER */ - .long .Lcls_retstruct1 /* FFI_TYPE_SMALL_STRUCT_1B */ - .long .Lcls_retstruct2 /* FFI_TYPE_SMALL_STRUCT_2B */ - .long .Lcls_retstruct4 /* FFI_TYPE_SMALL_STRUCT_4B */ - .long .Lcls_retmsstruct /* FFI_TYPE_MS_STRUCT */ + .long .Lcls_noretval-.Lcls_store_table /* FFI_TYPE_VOID */ + .long .Lcls_retint-.Lcls_store_table /* FFI_TYPE_INT */ + .long .Lcls_retfloat-.Lcls_store_table /* FFI_TYPE_FLOAT */ + .long .Lcls_retdouble-.Lcls_store_table /* FFI_TYPE_DOUBLE */ + .long .Lcls_retldouble-.Lcls_store_table /* FFI_TYPE_LONGDOUBLE */ + .long .Lcls_retuint8-.Lcls_store_table /* FFI_TYPE_UINT8 */ + .long .Lcls_retsint8-.Lcls_store_table /* FFI_TYPE_SINT8 */ + .long .Lcls_retuint16-.Lcls_store_table /* FFI_TYPE_UINT16 */ + .long .Lcls_retsint16-.Lcls_store_table /* FFI_TYPE_SINT16 */ + .long .Lcls_retint-.Lcls_store_table /* FFI_TYPE_UINT32 */ + .long .Lcls_retint-.Lcls_store_table /* FFI_TYPE_SINT32 */ + .long .Lcls_retllong-.Lcls_store_table /* FFI_TYPE_UINT64 */ + .long .Lcls_retllong-.Lcls_store_table /* FFI_TYPE_SINT64 */ + .long .Lcls_retstruct-.Lcls_store_table /* FFI_TYPE_STRUCT */ + .long .Lcls_retint-.Lcls_store_table /* FFI_TYPE_POINTER */ + .long .Lcls_retstruct1-.Lcls_store_table /* FFI_TYPE_SMALL_STRUCT_1B */ + .long .Lcls_retstruct2-.Lcls_store_table /* FFI_TYPE_SMALL_STRUCT_2B */ + .long .Lcls_retstruct4-.Lcls_store_table /* FFI_TYPE_SMALL_STRUCT_4B */ + .long .Lcls_retmsstruct-.Lcls_store_table /* FFI_TYPE_MS_STRUCT */ 1: - add %eax, %eax - add %eax, %eax + shl $2, %eax + add (%esp),%eax + mov (%eax),%eax add (%esp),%eax add $4, %esp - jmp *(%eax) + jmp *%eax /* Sign/zero extend as appropriate. */ .Lcls_retsint8: @@ -788,12 +853,15 @@ _ffi_closure_SYSV: #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 + +#ifdef X86_WIN32 .balign 16 - .globl _ffi_closure_raw_THISCALL -#ifndef __OS2__ +FFI_HIDDEN(ffi_closure_raw_THISCALL) + .globl USCORE_SYMBOL(ffi_closure_raw_THISCALL) +#if defined(X86_WIN32) && !defined(__OS2__) .def _ffi_closure_raw_THISCALL; .scl 2; .type 32; .endef #endif -_ffi_closure_raw_THISCALL: +USCORE_SYMBOL(ffi_closure_raw_THISCALL): pushl %ebp movl %esp, %ebp pushl %esi @@ -803,13 +871,17 @@ _ffi_closure_raw_THISCALL: movl %edx, 12(%esp) /* user_data */ leal 12(%ebp), %edx /* __builtin_dwarf_cfa () */ jmp .stubraw +#endif /* X86_WIN32 */ + # This assumes we are using gas. .balign 16 - .globl _ffi_closure_raw_SYSV -#ifndef __OS2__ +#if defined(X86_WIN32) + .globl USCORE_SYMBOL(ffi_closure_raw_SYSV) +#if defined(X86_WIN32) && !defined(__OS2__) .def _ffi_closure_raw_SYSV; .scl 2; .type 32; .endef #endif -_ffi_closure_raw_SYSV: +USCORE_SYMBOL(ffi_closure_raw_SYSV): +#endif /* defined(X86_WIN32) */ .LFB4: pushl %ebp .LCFI6: @@ -833,31 +905,32 @@ _ffi_closure_raw_SYSV: call 1f # Do not insert anything here between the call and the jump table. .Lrcls_store_table: - .long .Lrcls_noretval /* FFI_TYPE_VOID */ - .long .Lrcls_retint /* FFI_TYPE_INT */ - .long .Lrcls_retfloat /* FFI_TYPE_FLOAT */ - .long .Lrcls_retdouble /* FFI_TYPE_DOUBLE */ - .long .Lrcls_retldouble /* FFI_TYPE_LONGDOUBLE */ - .long .Lrcls_retuint8 /* FFI_TYPE_UINT8 */ - .long .Lrcls_retsint8 /* FFI_TYPE_SINT8 */ - .long .Lrcls_retuint16 /* FFI_TYPE_UINT16 */ - .long .Lrcls_retsint16 /* FFI_TYPE_SINT16 */ - .long .Lrcls_retint /* FFI_TYPE_UINT32 */ - .long .Lrcls_retint /* FFI_TYPE_SINT32 */ - .long .Lrcls_retllong /* FFI_TYPE_UINT64 */ - .long .Lrcls_retllong /* FFI_TYPE_SINT64 */ - .long .Lrcls_retstruct /* FFI_TYPE_STRUCT */ - .long .Lrcls_retint /* FFI_TYPE_POINTER */ - .long .Lrcls_retstruct1 /* FFI_TYPE_SMALL_STRUCT_1B */ - .long .Lrcls_retstruct2 /* FFI_TYPE_SMALL_STRUCT_2B */ - .long .Lrcls_retstruct4 /* FFI_TYPE_SMALL_STRUCT_4B */ - .long .Lrcls_retstruct /* FFI_TYPE_MS_STRUCT */ + .long .Lrcls_noretval-.Lrcls_store_table /* FFI_TYPE_VOID */ + .long .Lrcls_retint-.Lrcls_store_table /* FFI_TYPE_INT */ + .long .Lrcls_retfloat-.Lrcls_store_table /* FFI_TYPE_FLOAT */ + .long .Lrcls_retdouble-.Lrcls_store_table /* FFI_TYPE_DOUBLE */ + .long .Lrcls_retldouble-.Lrcls_store_table /* FFI_TYPE_LONGDOUBLE */ + .long .Lrcls_retuint8-.Lrcls_store_table /* FFI_TYPE_UINT8 */ + .long .Lrcls_retsint8-.Lrcls_store_table /* FFI_TYPE_SINT8 */ + .long .Lrcls_retuint16-.Lrcls_store_table /* FFI_TYPE_UINT16 */ + .long .Lrcls_retsint16-.Lrcls_store_table /* FFI_TYPE_SINT16 */ + .long .Lrcls_retint-.Lrcls_store_table /* FFI_TYPE_UINT32 */ + .long .Lrcls_retint-.Lrcls_store_table /* FFI_TYPE_SINT32 */ + .long .Lrcls_retllong-.Lrcls_store_table /* FFI_TYPE_UINT64 */ + .long .Lrcls_retllong-.Lrcls_store_table /* FFI_TYPE_SINT64 */ + .long .Lrcls_retstruct-.Lrcls_store_table /* FFI_TYPE_STRUCT */ + .long .Lrcls_retint-.Lrcls_store_table /* FFI_TYPE_POINTER */ + .long .Lrcls_retstruct1-.Lrcls_store_table /* FFI_TYPE_SMALL_STRUCT_1B */ + .long .Lrcls_retstruct2-.Lrcls_store_table /* FFI_TYPE_SMALL_STRUCT_2B */ + .long .Lrcls_retstruct4-.Lrcls_store_table /* FFI_TYPE_SMALL_STRUCT_4B */ + .long .Lrcls_retstruct-.Lrcls_store_table /* FFI_TYPE_MS_STRUCT */ 1: - add %eax, %eax - add %eax, %eax + shl $2, %eax + add (%esp),%eax + mov (%eax),%eax add (%esp),%eax add $4, %esp - jmp *(%eax) + jmp *%eax /* Sign/zero extend as appropriate. */ .Lrcls_retsint8: @@ -925,11 +998,13 @@ _ffi_closure_raw_SYSV: # This assumes we are using gas. .balign 16 - .globl _ffi_closure_STDCALL -#ifndef __OS2__ +FFI_HIDDEN(ffi_closure_STDCALL) + .globl USCORE_SYMBOL(ffi_closure_STDCALL) +#if defined(X86_WIN32) && !defined(__OS2__) .def _ffi_closure_STDCALL; .scl 2; .type 32; .endef #endif -_ffi_closure_STDCALL: +USCORE_SYMBOL(ffi_closure_STDCALL): +.ffi_closure_STDCALL_internal: .LFB5: pushl %ebp .LCFI9: @@ -942,36 +1017,48 @@ _ffi_closure_STDCALL: movl %edx, 4(%esp) /* args */ leal -12(%ebp), %edx movl %edx, (%esp) /* &resp */ - call _ffi_closure_SYSV_inner +#if defined(HAVE_HIDDEN_VISIBILITY_ATTRIBUTE) || !defined(__PIC__) + call USCORE_SYMBOL(ffi_closure_SYSV_inner) +#elif defined(X86_DARWIN) + calll L_ffi_closure_SYSV_inner$stub +#else + movl %ebx, 8(%esp) + call 1f +1: popl %ebx + addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx + call ffi_closure_SYSV_inner@PLT + movl 8(%esp), %ebx +#endif movl -12(%ebp), %ecx 0: call 1f # Do not insert anything here between the call and the jump table. .Lscls_store_table: - .long .Lscls_noretval /* FFI_TYPE_VOID */ - .long .Lscls_retint /* FFI_TYPE_INT */ - .long .Lscls_retfloat /* FFI_TYPE_FLOAT */ - .long .Lscls_retdouble /* FFI_TYPE_DOUBLE */ - .long .Lscls_retldouble /* FFI_TYPE_LONGDOUBLE */ - .long .Lscls_retuint8 /* FFI_TYPE_UINT8 */ - .long .Lscls_retsint8 /* FFI_TYPE_SINT8 */ - .long .Lscls_retuint16 /* FFI_TYPE_UINT16 */ - .long .Lscls_retsint16 /* FFI_TYPE_SINT16 */ - .long .Lscls_retint /* FFI_TYPE_UINT32 */ - .long .Lscls_retint /* FFI_TYPE_SINT32 */ - .long .Lscls_retllong /* FFI_TYPE_UINT64 */ - .long .Lscls_retllong /* FFI_TYPE_SINT64 */ - .long .Lscls_retstruct /* FFI_TYPE_STRUCT */ - .long .Lscls_retint /* FFI_TYPE_POINTER */ - .long .Lscls_retstruct1 /* FFI_TYPE_SMALL_STRUCT_1B */ - .long .Lscls_retstruct2 /* FFI_TYPE_SMALL_STRUCT_2B */ - .long .Lscls_retstruct4 /* FFI_TYPE_SMALL_STRUCT_4B */ + .long .Lscls_noretval-.Lscls_store_table /* FFI_TYPE_VOID */ + .long .Lscls_retint-.Lscls_store_table /* FFI_TYPE_INT */ + .long .Lscls_retfloat-.Lscls_store_table /* FFI_TYPE_FLOAT */ + .long .Lscls_retdouble-.Lscls_store_table /* FFI_TYPE_DOUBLE */ + .long .Lscls_retldouble-.Lscls_store_table /* FFI_TYPE_LONGDOUBLE */ + .long .Lscls_retuint8-.Lscls_store_table /* FFI_TYPE_UINT8 */ + .long .Lscls_retsint8-.Lscls_store_table /* FFI_TYPE_SINT8 */ + .long .Lscls_retuint16-.Lscls_store_table /* FFI_TYPE_UINT16 */ + .long .Lscls_retsint16-.Lscls_store_table /* FFI_TYPE_SINT16 */ + .long .Lscls_retint-.Lscls_store_table /* FFI_TYPE_UINT32 */ + .long .Lscls_retint-.Lscls_store_table /* FFI_TYPE_SINT32 */ + .long .Lscls_retllong-.Lscls_store_table /* FFI_TYPE_UINT64 */ + .long .Lscls_retllong-.Lscls_store_table /* FFI_TYPE_SINT64 */ + .long .Lscls_retstruct-.Lscls_store_table /* FFI_TYPE_STRUCT */ + .long .Lscls_retint-.Lscls_store_table /* FFI_TYPE_POINTER */ + .long .Lscls_retstruct1-.Lscls_store_table /* FFI_TYPE_SMALL_STRUCT_1B */ + .long .Lscls_retstruct2-.Lscls_store_table /* FFI_TYPE_SMALL_STRUCT_2B */ + .long .Lscls_retstruct4-.Lscls_store_table /* FFI_TYPE_SMALL_STRUCT_4B */ 1: - add %eax, %eax - add %eax, %eax + shl $2, %eax + add (%esp),%eax + mov (%eax),%eax add (%esp),%eax add $4, %esp - jmp *(%eax) + jmp *%eax /* Sign/zero extend as appropriate. */ .Lscls_retsint8: @@ -1030,11 +1117,30 @@ _ffi_closure_STDCALL: .Lscls_epilogue: movl %ebp, %esp popl %ebp - ret + popl %ecx + popl %edx + movl (CLOSURE_CIF_OFFSET-10)(%ecx), %ecx + addl CIF_BYTES_OFFSET(%ecx), %esp + movl CIF_ABI_OFFSET(%ecx), %ecx + cmpl $3, %ecx /* FFI_THISCALL */ + je 1f + cmpl $4, %ecx /* FFI_FASTCALL */ + jne 2f + + addl $4, %esp +1: addl $4, %esp +2: jmp *%edx .ffi_closure_STDCALL_end: .LFE5: -#ifndef __OS2__ +#if defined(X86_DARWIN) +.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 +#endif + +#if defined(X86_WIN32) && !defined(__OS2__) .section .eh_frame,"w" #endif .Lframe1: @@ -1094,7 +1200,6 @@ _ffi_closure_STDCALL: .align 4 .LEFDE1: - .LSFDE3: .long .LEFDE3-.LASFDE3 /* FDE Length */ .LASFDE3: diff --git a/Modules/_ctypes/libffi/stamp-h.in b/Modules/_ctypes/libffi/stamp-h.in deleted file mode 100644 index 9788f70238c9..000000000000 --- a/Modules/_ctypes/libffi/stamp-h.in +++ /dev/null @@ -1 +0,0 @@ -timestamp diff --git a/Modules/_ctypes/libffi/testsuite/Makefile.am b/Modules/_ctypes/libffi/testsuite/Makefile.am index edc6e61ae4db..da10465d283c 100644 --- a/Modules/_ctypes/libffi/testsuite/Makefile.am +++ b/Modules/_ctypes/libffi/testsuite/Makefile.am @@ -2,17 +2,6 @@ AUTOMAKE_OPTIONS = foreign dejagnu -# Setup the testing framework, if you have one -EXPECT = `if [ -f $(top_builddir)/../expect/expect ] ; then \ - echo $(top_builddir)/../expect/expect ; \ - else echo expect ; fi` - -RUNTEST = `if [ -f $(top_srcdir)/../dejagnu/runtest ] ; then \ - echo $(top_srcdir)/../dejagnu/runtest ; \ - else echo runtest; fi` - -AM_RUNTESTFLAGS = - EXTRA_DEJAGNU_SITE_CONFIG=../local.exp CLEANFILES = *.exe core* *.log *.sum @@ -20,7 +9,7 @@ CLEANFILES = *.exe core* *.log *.sum EXTRA_DIST = config/default.exp libffi.call/cls_19byte.c \ libffi.call/cls_align_longdouble_split.c \ libffi.call/closure_loc_fn0.c libffi.call/cls_schar.c \ -libffi.call/closure_fn1.c libffi.call/many2_win32.c \ +libffi.call/closure_fn1.c \ libffi.call/return_ul.c libffi.call/cls_align_double.c \ libffi.call/return_fl2.c libffi.call/cls_1_1byte.c \ libffi.call/cls_64byte.c libffi.call/nested_struct7.c \ @@ -30,7 +19,7 @@ libffi.call/cls_multi_ushort.c libffi.call/struct3.c \ libffi.call/cls_3byte1.c libffi.call/cls_16byte.c \ libffi.call/struct8.c libffi.call/nested_struct8.c \ libffi.call/cls_multi_sshort.c libffi.call/cls_3byte2.c \ -libffi.call/fastthis2_win32.c libffi.call/cls_pointer.c \ +libffi.call/cls_pointer.c \ libffi.call/err_bad_typedef.c libffi.call/cls_4_1byte.c \ libffi.call/cls_9byte2.c libffi.call/cls_multi_schar.c \ libffi.call/stret_medium2.c libffi.call/cls_5_1_byte.c \ @@ -46,16 +35,16 @@ libffi.call/cls_align_longdouble_split2.c libffi.call/return_dbl2.c \ libffi.call/return_fl3.c libffi.call/stret_medium.c \ libffi.call/nested_struct6.c libffi.call/closure_fn3.c \ libffi.call/float3.c libffi.call/many2.c \ -libffi.call/closure_stdcall.c libffi.call/cls_align_uint16.c \ +libffi.call/closure_simple.c libffi.call/cls_align_uint16.c \ libffi.call/cls_9byte1.c libffi.call/closure_fn6.c \ libffi.call/cls_double_va.c libffi.call/cls_align_pointer.c \ libffi.call/cls_align_longdouble.c libffi.call/closure_fn2.c \ -libffi.call/cls_sshort.c libffi.call/many_win32.c \ +libffi.call/cls_sshort.c \ libffi.call/nested_struct.c libffi.call/cls_20byte.c \ libffi.call/cls_longdouble.c libffi.call/cls_multi_uchar.c \ -libffi.call/return_uc.c libffi.call/closure_thiscall.c \ +libffi.call/return_uc.c \ libffi.call/cls_18byte.c libffi.call/cls_8byte.c \ -libffi.call/promotion.c libffi.call/struct1_win32.c \ +libffi.call/promotion.c \ libffi.call/return_dbl.c libffi.call/cls_24byte.c \ libffi.call/struct4.c libffi.call/cls_6byte.c \ libffi.call/cls_align_uint32.c libffi.call/float.c \ @@ -63,7 +52,7 @@ libffi.call/float1.c libffi.call/float_va.c libffi.call/negint.c \ libffi.call/return_dbl1.c libffi.call/cls_3_1byte.c \ libffi.call/cls_align_float.c libffi.call/return_fl1.c \ libffi.call/nested_struct10.c libffi.call/nested_struct5.c \ -libffi.call/fastthis1_win32.c libffi.call/cls_align_sint64.c \ +libffi.call/cls_align_sint64.c \ libffi.call/stret_large2.c libffi.call/return_sl.c \ libffi.call/closure_fn0.c libffi.call/cls_5byte.c \ libffi.call/cls_2byte.c libffi.call/float2.c \ @@ -75,20 +64,22 @@ libffi.call/cls_float.c libffi.call/cls_pointer_stack.c \ libffi.call/pyobjc-tc.c libffi.call/cls_multi_ushortchar.c \ libffi.call/struct1.c libffi.call/nested_struct9.c \ libffi.call/huge_struct.c libffi.call/problem1.c \ -libffi.call/float4.c libffi.call/fastthis3_win32.c \ -libffi.call/return_ldl.c libffi.call/strlen2_win32.c \ -libffi.call/closure_fn5.c libffi.call/struct2_win32.c \ +libffi.call/float4.c \ +libffi.call/return_ldl.c \ +libffi.call/closure_fn5.c \ libffi.call/struct6.c libffi.call/return_ll.c libffi.call/struct9.c \ libffi.call/return_sc.c libffi.call/struct7.c \ libffi.call/cls_align_uint64.c libffi.call/cls_4byte.c \ -libffi.call/strlen_win32.c libffi.call/cls_6_1_byte.c \ -libffi.call/cls_7_1_byte.c libffi.special/unwindtest.cc \ -libffi.special/special.exp libffi.special/unwindtest_ffi_call.cc \ -libffi.special/ffitestcxx.h lib/wrapper.exp lib/target-libpath.exp \ +libffi.call/cls_6_1_byte.c \ +libffi.call/cls_7_1_byte.c libffi.call/unwindtest.cc \ +libffi.call/unwindtest_ffi_call.cc \ +lib/wrapper.exp lib/target-libpath.exp \ lib/libffi.exp libffi.call/cls_struct_va1.c \ libffi.call/cls_uchar_va.c libffi.call/cls_uint_va.c \ libffi.call/cls_ulong_va.c libffi.call/cls_ushort_va.c \ libffi.call/nested_struct11.c libffi.call/uninitialized.c \ libffi.call/va_1.c libffi.call/va_struct1.c libffi.call/va_struct2.c \ -libffi.call/va_struct3.c - +libffi.call/va_struct3.c \ +libffi.call/strlen2.c \ +libffi.call/strlen3.c \ +libffi.call/strlen4.c diff --git a/Modules/_ctypes/libffi/testsuite/Makefile.in b/Modules/_ctypes/libffi/testsuite/Makefile.in index a3ba066dfa4b..99e226c409ad 100644 --- a/Modules/_ctypes/libffi/testsuite/Makefile.in +++ b/Modules/_ctypes/libffi/testsuite/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.12.2 from Makefile.am. +# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2012 Free Software Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -14,23 +14,51 @@ @SET_MAKE@ VPATH = @srcdir@ -am__make_dryrun = \ - { \ - am__dry=no; \ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ esac; \ - test $$am__dry = yes; \ - } + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -51,7 +79,7 @@ build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = testsuite -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \ $(top_srcdir)/m4/ax_append_flag.m4 \ @@ -73,6 +101,18 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/fficonfig.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ @@ -80,14 +120,18 @@ am__can_run_installinfo = \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DEJATOOL = $(PACKAGE) RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir +EXPECT = expect +RUNTEST = runtest DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AM_LTLDFLAGS = @AM_LTLDFLAGS@ -AM_RUNTESTFLAGS = +AM_RUNTESTFLAGS = @AM_RUNTESTFLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ @@ -101,6 +145,10 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ @@ -116,6 +164,7 @@ FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@ FGREP = @FGREP@ GREP = @GREP@ HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@ +HAVE_LONG_DOUBLE_VARIANT = @HAVE_LONG_DOUBLE_VARIANT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -162,6 +211,7 @@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ @@ -217,22 +267,12 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign dejagnu - -# Setup the testing framework, if you have one -EXPECT = `if [ -f $(top_builddir)/../expect/expect ] ; then \ - echo $(top_builddir)/../expect/expect ; \ - else echo expect ; fi` - -RUNTEST = `if [ -f $(top_srcdir)/../dejagnu/runtest ] ; then \ - echo $(top_srcdir)/../dejagnu/runtest ; \ - else echo runtest; fi` - EXTRA_DEJAGNU_SITE_CONFIG = ../local.exp CLEANFILES = *.exe core* *.log *.sum EXTRA_DIST = config/default.exp libffi.call/cls_19byte.c \ libffi.call/cls_align_longdouble_split.c \ libffi.call/closure_loc_fn0.c libffi.call/cls_schar.c \ -libffi.call/closure_fn1.c libffi.call/many2_win32.c \ +libffi.call/closure_fn1.c \ libffi.call/return_ul.c libffi.call/cls_align_double.c \ libffi.call/return_fl2.c libffi.call/cls_1_1byte.c \ libffi.call/cls_64byte.c libffi.call/nested_struct7.c \ @@ -242,7 +282,7 @@ libffi.call/cls_multi_ushort.c libffi.call/struct3.c \ libffi.call/cls_3byte1.c libffi.call/cls_16byte.c \ libffi.call/struct8.c libffi.call/nested_struct8.c \ libffi.call/cls_multi_sshort.c libffi.call/cls_3byte2.c \ -libffi.call/fastthis2_win32.c libffi.call/cls_pointer.c \ +libffi.call/cls_pointer.c \ libffi.call/err_bad_typedef.c libffi.call/cls_4_1byte.c \ libffi.call/cls_9byte2.c libffi.call/cls_multi_schar.c \ libffi.call/stret_medium2.c libffi.call/cls_5_1_byte.c \ @@ -258,16 +298,16 @@ libffi.call/cls_align_longdouble_split2.c libffi.call/return_dbl2.c \ libffi.call/return_fl3.c libffi.call/stret_medium.c \ libffi.call/nested_struct6.c libffi.call/closure_fn3.c \ libffi.call/float3.c libffi.call/many2.c \ -libffi.call/closure_stdcall.c libffi.call/cls_align_uint16.c \ +libffi.call/closure_simple.c libffi.call/cls_align_uint16.c \ libffi.call/cls_9byte1.c libffi.call/closure_fn6.c \ libffi.call/cls_double_va.c libffi.call/cls_align_pointer.c \ libffi.call/cls_align_longdouble.c libffi.call/closure_fn2.c \ -libffi.call/cls_sshort.c libffi.call/many_win32.c \ +libffi.call/cls_sshort.c \ libffi.call/nested_struct.c libffi.call/cls_20byte.c \ libffi.call/cls_longdouble.c libffi.call/cls_multi_uchar.c \ -libffi.call/return_uc.c libffi.call/closure_thiscall.c \ +libffi.call/return_uc.c \ libffi.call/cls_18byte.c libffi.call/cls_8byte.c \ -libffi.call/promotion.c libffi.call/struct1_win32.c \ +libffi.call/promotion.c \ libffi.call/return_dbl.c libffi.call/cls_24byte.c \ libffi.call/struct4.c libffi.call/cls_6byte.c \ libffi.call/cls_align_uint32.c libffi.call/float.c \ @@ -275,7 +315,7 @@ libffi.call/float1.c libffi.call/float_va.c libffi.call/negint.c \ libffi.call/return_dbl1.c libffi.call/cls_3_1byte.c \ libffi.call/cls_align_float.c libffi.call/return_fl1.c \ libffi.call/nested_struct10.c libffi.call/nested_struct5.c \ -libffi.call/fastthis1_win32.c libffi.call/cls_align_sint64.c \ +libffi.call/cls_align_sint64.c \ libffi.call/stret_large2.c libffi.call/return_sl.c \ libffi.call/closure_fn0.c libffi.call/cls_5byte.c \ libffi.call/cls_2byte.c libffi.call/float2.c \ @@ -287,22 +327,25 @@ libffi.call/cls_float.c libffi.call/cls_pointer_stack.c \ libffi.call/pyobjc-tc.c libffi.call/cls_multi_ushortchar.c \ libffi.call/struct1.c libffi.call/nested_struct9.c \ libffi.call/huge_struct.c libffi.call/problem1.c \ -libffi.call/float4.c libffi.call/fastthis3_win32.c \ -libffi.call/return_ldl.c libffi.call/strlen2_win32.c \ -libffi.call/closure_fn5.c libffi.call/struct2_win32.c \ +libffi.call/float4.c \ +libffi.call/return_ldl.c \ +libffi.call/closure_fn5.c \ libffi.call/struct6.c libffi.call/return_ll.c libffi.call/struct9.c \ libffi.call/return_sc.c libffi.call/struct7.c \ libffi.call/cls_align_uint64.c libffi.call/cls_4byte.c \ -libffi.call/strlen_win32.c libffi.call/cls_6_1_byte.c \ -libffi.call/cls_7_1_byte.c libffi.special/unwindtest.cc \ -libffi.special/special.exp libffi.special/unwindtest_ffi_call.cc \ -libffi.special/ffitestcxx.h lib/wrapper.exp lib/target-libpath.exp \ +libffi.call/cls_6_1_byte.c \ +libffi.call/cls_7_1_byte.c libffi.call/unwindtest.cc \ +libffi.call/unwindtest_ffi_call.cc \ +lib/wrapper.exp lib/target-libpath.exp \ lib/libffi.exp libffi.call/cls_struct_va1.c \ libffi.call/cls_uchar_va.c libffi.call/cls_uint_va.c \ libffi.call/cls_ulong_va.c libffi.call/cls_ushort_va.c \ libffi.call/nested_struct11.c libffi.call/uninitialized.c \ libffi.call/va_1.c libffi.call/va_struct1.c libffi.call/va_struct2.c \ -libffi.call/va_struct3.c +libffi.call/va_struct3.c \ +libffi.call/strlen2.c \ +libffi.call/strlen3.c \ +libffi.call/strlen4.c all: all-am @@ -343,11 +386,9 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs -tags: TAGS -TAGS: +tags TAGS: -ctags: CTAGS -CTAGS: +ctags CTAGS: cscope cscopelist: @@ -355,13 +396,12 @@ cscope cscopelist: check-DEJAGNU: site.exp srcdir='$(srcdir)'; export srcdir; \ EXPECT=$(EXPECT); export EXPECT; \ - runtest=$(RUNTEST); \ - if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \ + if $(SHELL) -c "$(RUNTEST) --version" > /dev/null 2>&1; then \ exit_status=0; l='$(DEJATOOL)'; for tool in $$l; do \ - if $$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \ + if $(RUNTEST) $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \ then :; else exit_status=1; fi; \ done; \ - else echo "WARNING: could not find 'runtest'" 1>&2; :;\ + else echo "WARNING: could not find '$(RUNTEST)'" 1>&2; :;\ fi; \ exit $$exit_status site.exp: Makefile $(EXTRA_DEJAGNU_SITE_CONFIG) @@ -532,16 +572,17 @@ uninstall-am: .MAKE: check-am install-am install-strip .PHONY: all all-am check check-DEJAGNU check-am clean clean-generic \ - clean-libtool distclean distclean-DEJAGNU distclean-generic \ - distclean-libtool distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - uninstall uninstall-am + clean-libtool cscopelist-am ctags-am distclean \ + distclean-DEJAGNU distclean-generic distclean-libtool distdir \ + dvi dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ + uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/Modules/_ctypes/libffi/testsuite/lib/libffi.exp b/Modules/_ctypes/libffi/testsuite/lib/libffi.exp index 1ac2c3608872..dbdd1a2f27c2 100644 --- a/Modules/_ctypes/libffi/testsuite/lib/libffi.exp +++ b/Modules/_ctypes/libffi/testsuite/lib/libffi.exp @@ -222,6 +222,10 @@ proc libffi_target_compile { source dest type options } { lappend options "libs= -lpthread" } + if { [string match "*.cc" $source] } { + lappend options "c++" + } + verbose "options: $options" return [target_compile $source $dest $type $options] } @@ -273,6 +277,46 @@ proc libffi-dg-runtest { testcases default-extra-flags } { } } +proc run-many-tests { testcases extra_flags } { + global using_gcc + if { [string match $using_gcc "yes"] } { + set common "-W -Wall" + set optimizations { "-O0" "-O2" "-O3" "-Os" "-O2 -fomit-frame-pointer" } + } else { + # Assume we are using the vendor compiler. + set common "" + set optimizations { "" } + } + + set targetabis { "" } + if [string match $using_gcc "yes"] { + if [istarget "i?86-*-*"] { + set targetabis { + "" + "-DABI_NUM=FFI_STDCALL -DABI_ATTR=__STDCALL__" + "-DABI_NUM=FFI_THISCALL -DABI_ATTR=__THISCALL__" + "-DABI_NUM=FFI_FASTCALL -DABI_ATTR=__FASTCALL__" + } + } + } + + set common [ concat $common $extra_flags ] + foreach test $testcases { + set testname [file tail $test] + if [search_for $test "ABI_NUM"] { + set abis $targetabis + } else { + set abis { "" } + } + foreach opt $optimizations { + foreach abi $abis { + set options [concat $common $opt $abi] + verbose "Testing $testname, $options" 1 + dg-test $test $options "" + } + } + } +} # Like check_conditional_xfail, but callable from a dg test. diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/call.exp b/Modules/_ctypes/libffi/testsuite/libffi.call/call.exp index c3346850a96b..36d13d8e08d7 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/call.exp +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/call.exp @@ -19,20 +19,7 @@ libffi-init global srcdir subdir -if { [string match $using_gcc "yes"] } { - - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O0 -W -Wall" "" - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O2" "" - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O3" "" - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-Os" "" - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O2 -fomit-frame-pointer" "" - -} else { - - # Assume we are using the vendor compiler. - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "" "" - -} +run-many-tests [lsort [glob -nocomplain -- $srcdir/$subdir/*.{c,cc}]] "" dg-finish diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/closure_stdcall.c b/Modules/_ctypes/libffi/testsuite/libffi.call/closure_simple.c similarity index 55% rename from Modules/_ctypes/libffi/testsuite/libffi.call/closure_stdcall.c rename to Modules/_ctypes/libffi/testsuite/libffi.call/closure_simple.c index 1407f024c170..5a4e728d4a42 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/closure_stdcall.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/closure_simple.c @@ -1,15 +1,14 @@ -/* Area: closure_call (stdcall convention) - Purpose: Check handling when caller expects stdcall callee +/* Area: closure_call + Purpose: Check simple closure handling with all ABIs Limitations: none. PR: none. Originator: */ -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ +/* { dg-do run } */ #include "ffitest.h" static void -closure_test_stdcall(ffi_cif* cif __UNUSED__, void* resp, void** args, - void* userdata) +closure_test(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata) { *(ffi_arg*)resp = (int)*(int *)args[0] + (int)(*(int *)args[1]) @@ -23,7 +22,7 @@ closure_test_stdcall(ffi_cif* cif __UNUSED__, void* resp, void** args, } -typedef int (__stdcall *closure_test_type0)(int, int, int, int); +typedef int (ABI_ATTR *closure_test_type0)(int, int, int, int); int main (void) { @@ -32,9 +31,6 @@ int main (void) ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); ffi_type * cl_arg_types[17]; int res; - void* sp_pre; - void* sp_post; - char buf[1024]; cl_arg_types[0] = &ffi_type_uint; cl_arg_types[1] = &ffi_type_uint; @@ -43,30 +39,17 @@ int main (void) cl_arg_types[4] = NULL; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 4, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 4, &ffi_type_sint, cl_arg_types) == FFI_OK); - CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_stdcall, + CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test, (void *) 3 /* userdata */, code) == FFI_OK); -#ifdef _MSC_VER - __asm { mov sp_pre, esp } -#else - asm volatile (" movl %%esp,%0" : "=g" (sp_pre)); -#endif res = (*(closure_test_type0)code)(0, 1, 2, 3); -#ifdef _MSC_VER - __asm { mov sp_post, esp } -#else - asm volatile (" movl %%esp,%0" : "=g" (sp_post)); -#endif /* { dg-output "0 1 2 3: 9" } */ printf("res: %d\n",res); /* { dg-output "\nres: 9" } */ - sprintf(buf, "mismatch: pre=%p vs post=%p", sp_pre, sp_post); - printf("stack pointer %s\n", (sp_pre == sp_post ? "match" : buf)); - /* { dg-output "\nstack pointer match" } */ exit(0); } diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/closure_thiscall.c b/Modules/_ctypes/libffi/testsuite/libffi.call/closure_thiscall.c deleted file mode 100644 index 0f93649ff752..000000000000 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/closure_thiscall.c +++ /dev/null @@ -1,72 +0,0 @@ -/* Area: closure_call (thiscall convention) - Purpose: Check handling when caller expects thiscall callee - Limitations: none. - PR: none. - Originator: */ - -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ -#include "ffitest.h" - -static void -closure_test_thiscall(ffi_cif* cif __UNUSED__, void* resp, void** args, - void* userdata) -{ - *(ffi_arg*)resp = - (int)*(int *)args[0] + (int)(*(int *)args[1]) - + (int)(*(int *)args[2]) + (int)(*(int *)args[3]) - + (int)(intptr_t)userdata; - - printf("%d %d %d %d: %d\n", - (int)*(int *)args[0], (int)(*(int *)args[1]), - (int)(*(int *)args[2]), (int)(*(int *)args[3]), - (int)*(ffi_arg *)resp); - -} - -typedef int (__thiscall *closure_test_type0)(int, int, int, int); - -int main (void) -{ - ffi_cif cif; - void *code; - ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code); - ffi_type * cl_arg_types[17]; - int res; - void* sp_pre; - void* sp_post; - char buf[1024]; - - cl_arg_types[0] = &ffi_type_uint; - cl_arg_types[1] = &ffi_type_uint; - cl_arg_types[2] = &ffi_type_uint; - cl_arg_types[3] = &ffi_type_uint; - cl_arg_types[4] = NULL; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_THISCALL, 4, - &ffi_type_sint, cl_arg_types) == FFI_OK); - - CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_thiscall, - (void *) 3 /* userdata */, code) == FFI_OK); - -#ifdef _MSC_VER - __asm { mov sp_pre, esp } -#else - asm volatile (" movl %%esp,%0" : "=g" (sp_pre)); -#endif - res = (*(closure_test_type0)code)(0, 1, 2, 3); -#ifdef _MSC_VER - __asm { mov sp_post, esp } -#else - asm volatile (" movl %%esp,%0" : "=g" (sp_post)); -#endif - /* { dg-output "0 1 2 3: 9" } */ - - printf("res: %d\n",res); - /* { dg-output "\nres: 9" } */ - - sprintf(buf, "mismatch: pre=%p vs post=%p", sp_pre, sp_post); - printf("stack pointer %s\n", (sp_pre == sp_post ? "match" : buf)); - /* { dg-output "\nstack pointer match" } */ - exit(0); -} diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/cls_double_va.c b/Modules/_ctypes/libffi/testsuite/libffi.call/cls_double_va.c index 43167b6f6312..e077f92b8638 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/cls_double_va.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/cls_double_va.c @@ -38,7 +38,7 @@ int main (void) /* This printf call is variadic */ CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint, - arg_types) == FFI_OK); + arg_types) == FFI_OK); args[0] = &format; args[1] = &doubleArg; @@ -49,12 +49,10 @@ int main (void) printf("res: %d\n", (int) res); /* { dg-output "\nres: 4" } */ - /* The call to cls_double_va_fn is static, so have to use a normal prep_cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint, arg_types) == FFI_OK); + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_double_va_fn, NULL, + code) == FFI_OK); - CHECK(ffi_prep_closure_loc(pcl, &cif, cls_double_va_fn, NULL, code) == FFI_OK); - - res = ((int(*)(char*, double))(code))(format, doubleArg); + res = ((int(*)(char*, ...))(code))(format, doubleArg); /* { dg-output "\n7.0" } */ printf("res: %d\n", (int) res); /* { dg-output "\nres: 4" } */ diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/cls_longdouble_va.c b/Modules/_ctypes/libffi/testsuite/libffi.call/cls_longdouble_va.c index 7126b13816da..39b438b289a8 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/cls_longdouble_va.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/cls_longdouble_va.c @@ -38,7 +38,7 @@ int main (void) /* This printf call is variadic */ CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint, - arg_types) == FFI_OK); + arg_types) == FFI_OK); args[0] = &format; args[1] = &ldArg; @@ -49,13 +49,10 @@ int main (void) printf("res: %d\n", (int) res); /* { dg-output "\nres: 4" } */ - /* The call to cls_longdouble_va_fn is static, so have to use a normal prep_cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint, - arg_types) == FFI_OK); + CHECK(ffi_prep_closure_loc(pcl, &cif, cls_longdouble_va_fn, NULL, + code) == FFI_OK); - CHECK(ffi_prep_closure_loc(pcl, &cif, cls_longdouble_va_fn, NULL, code) == FFI_OK); - - res = ((int(*)(char*, long double))(code))(format, ldArg); + res = ((int(*)(char*, ...))(code))(format, ldArg); /* { dg-output "\n7.0" } */ printf("res: %d\n", (int) res); /* { dg-output "\nres: 4" } */ diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/cls_struct_va1.c b/Modules/_ctypes/libffi/testsuite/libffi.call/cls_struct_va1.c index 175ed9617802..6d1fdaeb606a 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/cls_struct_va1.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/cls_struct_va1.c @@ -35,7 +35,7 @@ test_fn (ffi_cif* cif __UNUSED__, void* resp, printf ("%d %d %d %d %d %d %d %d %d %d\n", n, s1.a, s1.b, l1.a, l1.b, l1.c, l1.d, l1.e, s2.a, s2.b); - * (int*) resp = 42; + * (ffi_arg*) resp = 42; } int diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/cls_uint_va.c b/Modules/_ctypes/libffi/testsuite/libffi.call/cls_uint_va.c index 150fddd515db..b04cfd19c2ce 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/cls_uint_va.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/cls_uint_va.c @@ -13,9 +13,9 @@ typedef unsigned int T; static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__) { - *(T *)resp = *(T *)args[0]; + *(ffi_arg *)resp = *(T *)args[0]; - printf("%d: %d %d\n", *(T *)resp, *(T *)args[0], *(T *)args[1]); + printf("%d: %d %d\n", (int)*(ffi_arg *)resp, *(T *)args[0], *(T *)args[1]); } typedef T (*cls_ret_T)(T, ...); diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/ffitest.h b/Modules/_ctypes/libffi/testsuite/libffi.call/ffitest.h index 136a7a6ba1d3..15d5e4412348 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/ffitest.h +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/ffitest.h @@ -15,22 +15,25 @@ #define MAX_ARGS 256 -#define CHECK(x) !(x) ? (abort(), 1) : 0 +#define CHECK(x) (void)(!(x) ? (abort(), 1) : 0) -/* Define __UNUSED__ that also other compilers than gcc can run the tests. */ +/* Define macros so that compilers other than gcc can run the tests. */ #undef __UNUSED__ #if defined(__GNUC__) #define __UNUSED__ __attribute__((__unused__)) +#define __STDCALL__ __attribute__((stdcall)) +#define __THISCALL__ __attribute__((thiscall)) +#define __FASTCALL__ __attribute__((fastcall)) #else #define __UNUSED__ +#define __STDCALL__ __stdcall +#define __THISCALL__ __thiscall +#define __FASTCALL__ __fastcall #endif -/* Define __FASTCALL__ so that other compilers than gcc can run the tests. */ -#undef __FASTCALL__ -#if defined _MSC_VER -#define __FASTCALL__ __fastcall -#else -#define __FASTCALL__ __attribute__((fastcall)) +#ifndef ABI_NUM +#define ABI_NUM FFI_DEFAULT_ABI +#define ABI_ATTR #endif /* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/many.c b/Modules/_ctypes/libffi/testsuite/libffi.call/many.c index 4869ba9dde07..336968c77a2b 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/many.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/many.c @@ -7,21 +7,11 @@ /* { dg-do run } */ #include "ffitest.h" +#include #include +#include -static float many(float f1, - float f2, - float f3, - float f4, - float f5, - float f6, - float f7, - float f8, - float f9, - float f10, - float f11, - float f12, - float f13) +static float ABI_ATTR many(float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8, float f9, float f10, float f11, float f12, float f13) { #if 0 printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n", @@ -30,7 +20,7 @@ static float many(float f1, (double) f11, (double) f12, (double) f13); #endif - return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13); + return f1+f2+f3+f4+f5+f6+f7+f8+f9+f10+f11+f12+f13; } int main (void) @@ -50,7 +40,7 @@ int main (void) } /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 13, &ffi_type_float, args) == FFI_OK); ffi_call(&cif, FFI_FN(many), &f, values); @@ -62,7 +52,7 @@ int main (void) fa[8], fa[9], fa[10],fa[11],fa[12]); - if (f - ff < FLT_EPSILON) + if (fabs(f - ff) < FLT_EPSILON) exit(0); else abort(); diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/many2.c b/Modules/_ctypes/libffi/testsuite/libffi.call/many2.c index 98eac6013a43..1c85746e4c4b 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/many2.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/many2.c @@ -22,7 +22,7 @@ foo (uint8_t a, uint8_t b, uint8_t c, uint8_t d, return a + b + c + d + e + f + g; } -uint8_t +uint8_t ABI_ATTR bar (uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e, uint8_t f, uint8_t g) { @@ -42,7 +42,7 @@ main (void) for (i = 0; i < NARGS; ++i) ffitypes[i] = &ffi_type_uint8; - CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, NARGS, + CHECK (ffi_prep_cif (&cif, ABI_NUM, NARGS, &ffi_type_uint8, ffitypes) == FFI_OK); for (i = 0; i < NARGS; ++i) diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/many2_win32.c b/Modules/_ctypes/libffi/testsuite/libffi.call/many2_win32.c deleted file mode 100644 index 4adbe4d705f8..000000000000 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/many2_win32.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Area: ffi_call - Purpose: Check stdcall many call on X86_WIN32 systems. - Limitations: none. - PR: none. - Originator: From the original ffitest.c */ - -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ - -#include "ffitest.h" -#include - -static float __attribute__((fastcall)) fastcall_many(float f1, - float f2, - float f3, - float f4, - float f5, - float f6, - float f7, - float f8, - float f9, - float f10, - float f11, - float f12, - float f13) -{ - return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13); -} - -int main (void) -{ - ffi_cif cif; - ffi_type *args[13]; - void *values[13]; - float fa[13]; - float f, ff; - unsigned long ul; - - for (ul = 0; ul < 13; ul++) - { - args[ul] = &ffi_type_float; - values[ul] = &fa[ul]; - fa[ul] = (float) ul; - } - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 13, - &ffi_type_float, args) == FFI_OK); - - ff = fastcall_many(fa[0], fa[1], - fa[2], fa[3], - fa[4], fa[5], - fa[6], fa[7], - fa[8], fa[9], - fa[10], fa[11], fa[12]); - - ffi_call(&cif, FFI_FN(fastcall_many), &f, values); - - if (f - ff < FLT_EPSILON) - printf("fastcall many arg tests ok!\n"); - else - CHECK(0); - exit(0); -} diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/many_win32.c b/Modules/_ctypes/libffi/testsuite/libffi.call/many_win32.c deleted file mode 100644 index 1b2633227ad9..000000000000 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/many_win32.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Area: ffi_call - Purpose: Check stdcall many call on X86_WIN32 systems. - Limitations: none. - PR: none. - Originator: From the original ffitest.c */ - -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ - -#include "ffitest.h" -#include - -static float __attribute__((stdcall)) stdcall_many(float f1, - float f2, - float f3, - float f4, - float f5, - float f6, - float f7, - float f8, - float f9, - float f10, - float f11, - float f12, - float f13) -{ - return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13); -} - -int main (void) -{ - ffi_cif cif; - ffi_type *args[13]; - void *values[13]; - float fa[13]; - float f, ff; - unsigned long ul; - - for (ul = 0; ul < 13; ul++) - { - args[ul] = &ffi_type_float; - values[ul] = &fa[ul]; - fa[ul] = (float) ul; - } - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 13, - &ffi_type_float, args) == FFI_OK); - - ff = stdcall_many(fa[0], fa[1], - fa[2], fa[3], - fa[4], fa[5], - fa[6], fa[7], - fa[8], fa[9], - fa[10], fa[11], fa[12]); - - ffi_call(&cif, FFI_FN(stdcall_many), &f, values); - - if (f - ff < FLT_EPSILON) - printf("stdcall many arg tests ok!\n"); - else - CHECK(0); - exit(0); -} diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/nested_struct11.c b/Modules/_ctypes/libffi/testsuite/libffi.call/nested_struct11.c index fce69481888f..351049382c62 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/nested_struct11.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/nested_struct11.c @@ -1,7 +1,7 @@ /* Area: ffi_call, closure_call Purpose: Check parameter passing with nested structs of a single type. This tests the special cases - for homogenous floating-point aggregates in the + for homogeneous floating-point aggregates in the AArch64 PCS. Limitations: none. PR: none. diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/strlen.c b/Modules/_ctypes/libffi/testsuite/libffi.call/strlen.c index 3de45de7aaac..35b70ea4e2e1 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/strlen.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/strlen.c @@ -7,7 +7,7 @@ /* { dg-do run } */ #include "ffitest.h" -static size_t my_strlen(char *s) +static size_t ABI_ATTR my_strlen(char *s) { return (strlen(s)); } @@ -24,7 +24,7 @@ int main (void) values[0] = (void*) &s; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ffi_type_sint, args) == FFI_OK); s = "a"; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/fastthis1_win32.c b/Modules/_ctypes/libffi/testsuite/libffi.call/strlen2.c similarity index 61% rename from Modules/_ctypes/libffi/testsuite/libffi.call/fastthis1_win32.c rename to Modules/_ctypes/libffi/testsuite/libffi.call/strlen2.c index cbc4724ef8c1..96282bc0a1fa 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/fastthis1_win32.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/strlen2.c @@ -1,14 +1,14 @@ /* Area: ffi_call - Purpose: Check fastcall fct call on X86_WIN32 systems. + Purpose: Check strlen function call with additional arguments. Limitations: none. PR: none. Originator: From the original ffitest.c */ -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ +/* { dg-do run } */ #include "ffitest.h" -static size_t __FASTCALL__ my_fastcall_f(char *s, float a) +static size_t ABI_ATTR my_f(char *s, float a) { return (size_t) ((int) strlen(s) + (int) a); } @@ -27,24 +27,23 @@ int main (void) values[1] = (void*) &v2; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 2, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, &ffi_type_sint, args) == FFI_OK); s = "a"; v2 = 0.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 1); s = "1234567"; v2 = -1.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 6); s = "1234567890123456789012345"; v2 = 1.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 26); - printf("fastcall fct1 tests passed\n"); exit(0); } diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/strlen2_win32.c b/Modules/_ctypes/libffi/testsuite/libffi.call/strlen2_win32.c deleted file mode 100644 index 0d81061e7585..000000000000 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/strlen2_win32.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Area: ffi_call - Purpose: Check fastcall strlen call on X86_WIN32 systems. - Limitations: none. - PR: none. - Originator: From the original ffitest.c */ - -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ - -#include "ffitest.h" - -static size_t __FASTCALL__ my_fastcall_strlen(char *s) -{ - return (strlen(s)); -} - -int main (void) -{ - ffi_cif cif; - ffi_type *args[MAX_ARGS]; - void *values[MAX_ARGS]; - ffi_arg rint; - char *s; - args[0] = &ffi_type_pointer; - values[0] = (void*) &s; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 1, - &ffi_type_sint, args) == FFI_OK); - - s = "a"; - ffi_call(&cif, FFI_FN(my_fastcall_strlen), &rint, values); - CHECK(rint == 1); - - s = "1234567"; - ffi_call(&cif, FFI_FN(my_fastcall_strlen), &rint, values); - CHECK(rint == 7); - - s = "1234567890123456789012345"; - ffi_call(&cif, FFI_FN(my_fastcall_strlen), &rint, values); - CHECK(rint == 25); - - printf("fastcall strlen tests passed\n"); - exit(0); -} diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/fastthis2_win32.c b/Modules/_ctypes/libffi/testsuite/libffi.call/strlen3.c similarity index 61% rename from Modules/_ctypes/libffi/testsuite/libffi.call/fastthis2_win32.c rename to Modules/_ctypes/libffi/testsuite/libffi.call/strlen3.c index 7bdd0e17584c..beba86e9eacf 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/fastthis2_win32.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/strlen3.c @@ -1,14 +1,14 @@ /* Area: ffi_call - Purpose: Check fastcall fct call on X86_WIN32 systems. + Purpose: Check strlen function call with additional arguments. Limitations: none. PR: none. Originator: From the original ffitest.c */ -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ +/* { dg-do run } */ #include "ffitest.h" -static size_t __FASTCALL__ my_fastcall_f(float a, char *s) +static size_t ABI_ATTR my_f(float a, char *s) { return (size_t) ((int) strlen(s) + (int) a); } @@ -27,24 +27,23 @@ int main (void) values[0] = (void*) &v2; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 2, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, &ffi_type_sint, args) == FFI_OK); s = "a"; v2 = 0.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 1); s = "1234567"; v2 = -1.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 6); s = "1234567890123456789012345"; v2 = 1.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 26); - printf("fastcall fct2 tests passed\n"); exit(0); } diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/fastthis3_win32.c b/Modules/_ctypes/libffi/testsuite/libffi.call/strlen4.c similarity index 63% rename from Modules/_ctypes/libffi/testsuite/libffi.call/fastthis3_win32.c rename to Modules/_ctypes/libffi/testsuite/libffi.call/strlen4.c index b5d606d9a15e..d5d42b4f6ddf 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/fastthis3_win32.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/strlen4.c @@ -1,14 +1,14 @@ /* Area: ffi_call - Purpose: Check fastcall f call on X86_WIN32 systems. + Purpose: Check strlen function call with additional arguments. Limitations: none. PR: none. Originator: From the original ffitest.c */ -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ +/* { dg-do run } */ #include "ffitest.h" -static size_t __FASTCALL__ my_fastcall_f(float a, char *s, int i) +static size_t ABI_ATTR my_f(float a, char *s, int i) { return (size_t) ((int) strlen(s) + (int) a + i); } @@ -30,27 +30,26 @@ int main (void) values[0] = (void*) &v2; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 3, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 3, &ffi_type_sint, args) == FFI_OK); s = "a"; v1 = 1; v2 = 0.0; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 2); s = "1234567"; v2 = -1.0; v1 = -2; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 4); s = "1234567890123456789012345"; v2 = 1.0; v1 = 2; - ffi_call(&cif, FFI_FN(my_fastcall_f), &rint, values); + ffi_call(&cif, FFI_FN(my_f), &rint, values); CHECK(rint == 28); - printf("fastcall fct3 tests passed\n"); exit(0); } diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/strlen_win32.c b/Modules/_ctypes/libffi/testsuite/libffi.call/strlen_win32.c deleted file mode 100644 index 6fbcc87400a6..000000000000 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/strlen_win32.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Area: ffi_call - Purpose: Check stdcall strlen call on X86_WIN32 systems. - Limitations: none. - PR: none. - Originator: From the original ffitest.c */ - -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ - -#include "ffitest.h" - -static size_t __attribute__((stdcall)) my_stdcall_strlen(char *s) -{ - return (strlen(s)); -} - -int main (void) -{ - ffi_cif cif; - ffi_type *args[MAX_ARGS]; - void *values[MAX_ARGS]; - ffi_arg rint; - char *s; - args[0] = &ffi_type_pointer; - values[0] = (void*) &s; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 1, - &ffi_type_sint, args) == FFI_OK); - - s = "a"; - ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values); - CHECK(rint == 1); - - s = "1234567"; - ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values); - CHECK(rint == 7); - - s = "1234567890123456789012345"; - ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values); - CHECK(rint == 25); - - printf("stdcall strlen tests passed\n"); - exit(0); -} diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct1.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct1.c index bfc23f642cc8..c13e23f87273 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct1.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/struct1.c @@ -14,7 +14,7 @@ typedef struct unsigned int ui; } test_structure_1; -static test_structure_1 struct1(test_structure_1 ts) +static test_structure_1 ABI_ATTR struct1(test_structure_1 ts) { ts.uc++; ts.d--; @@ -50,7 +50,7 @@ int main (void) values[0] = &ts1_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts1_type, args) == FFI_OK); ts1_arg.uc = '\x01'; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct1_win32.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct1_win32.c deleted file mode 100644 index b756f5ad8b52..000000000000 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct1_win32.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Area: ffi_call - Purpose: Check structures with fastcall/thiscall convention. - Limitations: none. - PR: none. - Originator: From the original ffitest.c */ - -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ -#include "ffitest.h" - -typedef struct -{ - unsigned char uc; - double d; - unsigned int ui; -} test_structure_1; - -static test_structure_1 __FASTCALL__ struct1(test_structure_1 ts) -{ - ts.uc++; - ts.d--; - ts.ui++; - - return ts; -} - -int main (void) -{ - ffi_cif cif; - ffi_type *args[MAX_ARGS]; - void *values[MAX_ARGS]; - ffi_type ts1_type; - ffi_type *ts1_type_elements[4]; - - test_structure_1 ts1_arg; - - /* This is a hack to get a properly aligned result buffer */ - test_structure_1 *ts1_result = - (test_structure_1 *) malloc (sizeof(test_structure_1)); - - ts1_type.size = 0; - ts1_type.alignment = 0; - ts1_type.type = FFI_TYPE_STRUCT; - ts1_type.elements = ts1_type_elements; - ts1_type_elements[0] = &ffi_type_uchar; - ts1_type_elements[1] = &ffi_type_double; - ts1_type_elements[2] = &ffi_type_uint; - ts1_type_elements[3] = NULL; - - args[0] = &ts1_type; - values[0] = &ts1_arg; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 1, - &ts1_type, args) == FFI_OK); - - ts1_arg.uc = '\x01'; - ts1_arg.d = 3.14159; - ts1_arg.ui = 555; - - ffi_call(&cif, FFI_FN(struct1), ts1_result, values); - - CHECK(ts1_result->ui == 556); - CHECK(ts1_result->d == 3.14159 - 1); - - free (ts1_result); - exit(0); -} diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct2.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct2.c index d85385e7d3f2..5077a5ee45a5 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct2.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/struct2.c @@ -13,7 +13,7 @@ typedef struct double d2; } test_structure_2; -static test_structure_2 struct2(test_structure_2 ts) +static test_structure_2 ABI_ATTR struct2(test_structure_2 ts) { ts.d1--; ts.d2--; @@ -46,7 +46,7 @@ int main (void) values[0] = &ts2_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts2_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts2_type, args) == FFI_OK); ts2_arg.d1 = 5.55; ts2_arg.d2 = 6.66; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct2_win32.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct2_win32.c deleted file mode 100644 index 5d022855c574..000000000000 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct2_win32.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Area: ffi_call - Purpose: Check structures in fastcall/stdcall function - Limitations: none. - PR: none. - Originator: From the original ffitest.c */ - -/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */ -#include "ffitest.h" - -typedef struct -{ - double d1; - double d2; -} test_structure_2; - -static test_structure_2 __FASTCALL__ struct2(test_structure_2 ts) -{ - ts.d1--; - ts.d2--; - - return ts; -} - -int main (void) -{ - ffi_cif cif; - ffi_type *args[MAX_ARGS]; - void *values[MAX_ARGS]; - test_structure_2 ts2_arg; - ffi_type ts2_type; - ffi_type *ts2_type_elements[3]; - - /* This is a hack to get a properly aligned result buffer */ - test_structure_2 *ts2_result = - (test_structure_2 *) malloc (sizeof(test_structure_2)); - - ts2_type.size = 0; - ts2_type.alignment = 0; - ts2_type.type = FFI_TYPE_STRUCT; - ts2_type.elements = ts2_type_elements; - ts2_type_elements[0] = &ffi_type_double; - ts2_type_elements[1] = &ffi_type_double; - ts2_type_elements[2] = NULL; - - args[0] = &ts2_type; - values[0] = &ts2_arg; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_FASTCALL, 1, &ts2_type, args) == FFI_OK); - - ts2_arg.d1 = 5.55; - ts2_arg.d2 = 6.66; - - printf ("%g\n", ts2_arg.d1); - printf ("%g\n", ts2_arg.d2); - - ffi_call(&cif, FFI_FN(struct2), ts2_result, values); - - printf ("%g\n", ts2_result->d1); - printf ("%g\n", ts2_result->d2); - - CHECK(ts2_result->d1 == 5.55 - 1); - CHECK(ts2_result->d2 == 6.66 - 1); - - free (ts2_result); - exit(0); -} diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct3.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct3.c index de883c2638e0..7eba0ead6d6a 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct3.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/struct3.c @@ -12,7 +12,7 @@ typedef struct int si; } test_structure_3; -static test_structure_3 struct3(test_structure_3 ts) +static test_structure_3 ABI_ATTR struct3(test_structure_3 ts) { ts.si = -(ts.si*2); @@ -43,7 +43,7 @@ int main (void) values[0] = &ts3_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts3_type, args) == FFI_OK); ts3_arg.si = -123; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct4.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct4.c index 48e03495441c..66a9551dd650 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct4.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/struct4.c @@ -14,7 +14,7 @@ typedef struct unsigned ui3; } test_structure_4; -static test_structure_4 struct4(test_structure_4 ts) +static test_structure_4 ABI_ATTR struct4(test_structure_4 ts) { ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3; @@ -48,7 +48,7 @@ int main (void) values[0] = &ts4_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts4_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts4_type, args) == FFI_OK); ts4_arg.ui1 = 2; ts4_arg.ui2 = 3; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct5.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct5.c index 28b1f0c4265e..23e2a3f745c8 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct5.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/struct5.c @@ -12,7 +12,7 @@ typedef struct char c2; } test_structure_5; -static test_structure_5 struct5(test_structure_5 ts1, test_structure_5 ts2) +static test_structure_5 ABI_ATTR struct5(test_structure_5 ts1, test_structure_5 ts2) { ts1.c1 += ts2.c1; ts1.c2 -= ts2.c2; @@ -48,7 +48,7 @@ int main (void) values[1] = &ts5_arg2; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ts5_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, &ts5_type, args) == FFI_OK); ts5_arg1.c1 = 2; ts5_arg1.c2 = 6; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct6.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct6.c index 0e267467a7b0..173c66eb4d2b 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct6.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/struct6.c @@ -12,7 +12,7 @@ typedef struct double d; } test_structure_6; -static test_structure_6 struct6 (test_structure_6 ts) +static test_structure_6 ABI_ATTR struct6 (test_structure_6 ts) { ts.f += 1; ts.d += 1; @@ -46,7 +46,7 @@ int main (void) values[0] = &ts6_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts6_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts6_type, args) == FFI_OK); ts6_arg.f = 5.55f; ts6_arg.d = 6.66; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct7.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct7.c index 8f2bbfd949c5..badc7e055609 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct7.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/struct7.c @@ -13,7 +13,7 @@ typedef struct double d; } test_structure_7; -static test_structure_7 struct7 (test_structure_7 ts) +static test_structure_7 ABI_ATTR struct7 (test_structure_7 ts) { ts.f1 += 1; ts.f2 += 1; @@ -49,7 +49,7 @@ int main (void) values[0] = &ts7_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts7_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts7_type, args) == FFI_OK); ts7_arg.f1 = 5.55f; ts7_arg.f2 = 55.5f; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct8.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct8.c index 266e1f0ad606..ef204ecbbce5 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct8.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/struct8.c @@ -14,7 +14,7 @@ typedef struct float f4; } test_structure_8; -static test_structure_8 struct8 (test_structure_8 ts) +static test_structure_8 ABI_ATTR struct8 (test_structure_8 ts) { ts.f1 += 1; ts.f2 += 1; @@ -52,7 +52,7 @@ int main (void) values[0] = &ts8_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts8_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts8_type, args) == FFI_OK); ts8_arg.f1 = 5.55f; ts8_arg.f2 = 55.5f; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/struct9.c b/Modules/_ctypes/libffi/testsuite/libffi.call/struct9.c index efeb7161b845..4a13b818c4ee 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/struct9.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/struct9.c @@ -13,7 +13,7 @@ typedef struct int i; } test_structure_9; -static test_structure_9 struct9 (test_structure_9 ts) +static test_structure_9 ABI_ATTR struct9 (test_structure_9 ts) { ts.f += 1; ts.i += 1; @@ -47,7 +47,7 @@ int main (void) values[0] = &ts9_arg; /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts9_type, args) == FFI_OK); + CHECK(ffi_prep_cif(&cif, ABI_NUM, 1, &ts9_type, args) == FFI_OK); ts9_arg.f = 5.55f; ts9_arg.i = 5; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.special/unwindtest.cc b/Modules/_ctypes/libffi/testsuite/libffi.call/unwindtest.cc similarity index 96% rename from Modules/_ctypes/libffi/testsuite/libffi.special/unwindtest.cc rename to Modules/_ctypes/libffi/testsuite/libffi.call/unwindtest.cc index a78f4e72cdc3..67cfefeca636 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.special/unwindtest.cc +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/unwindtest.cc @@ -6,17 +6,9 @@ /* { dg-do run } */ -#include "ffitestcxx.h" +#include "ffitest.h" -#if defined HAVE_STDINT_H -#include -#endif - -#if defined HAVE_INTTYPES_H -#include -#endif - -void +void ABI_ATTR closure_test_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, void** args __UNUSED__, void* userdata __UNUSED__) { diff --git a/Modules/_ctypes/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc b/Modules/_ctypes/libffi/testsuite/libffi.call/unwindtest_ffi_call.cc similarity index 97% rename from Modules/_ctypes/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc rename to Modules/_ctypes/libffi/testsuite/libffi.call/unwindtest_ffi_call.cc index 57191f2a607a..ec611647e3dc 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/unwindtest_ffi_call.cc @@ -6,7 +6,7 @@ /* { dg-do run } */ -#include "ffitestcxx.h" +#include "ffitest.h" static int checking(int a __UNUSED__, short b __UNUSED__, signed char c __UNUSED__) diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/va_1.c b/Modules/_ctypes/libffi/testsuite/libffi.call/va_1.c index cf4dd85cedef..7f96809ea9ec 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/va_1.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/va_1.c @@ -94,7 +94,7 @@ main (void) struct large_tag l1; int n; - int res; + ffi_arg res; unsigned char uc; signed char sc; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.call/va_struct1.c b/Modules/_ctypes/libffi/testsuite/libffi.call/va_struct1.c index 11d1f10e5c69..e6452061c1d3 100644 --- a/Modules/_ctypes/libffi/testsuite/libffi.call/va_struct1.c +++ b/Modules/_ctypes/libffi/testsuite/libffi.call/va_struct1.c @@ -61,7 +61,7 @@ main (void) struct large_tag l1; int n; - int res; + ffi_arg res; s_type.size = 0; s_type.alignment = 0; diff --git a/Modules/_ctypes/libffi/testsuite/libffi.special/ffitestcxx.h b/Modules/_ctypes/libffi/testsuite/libffi.special/ffitestcxx.h deleted file mode 100644 index c6da7efd49e7..000000000000 --- a/Modules/_ctypes/libffi/testsuite/libffi.special/ffitestcxx.h +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include -#include -#include -#include "fficonfig.h" - -#define MAX_ARGS 256 - - -/* Define __UNUSED__ that also other compilers than gcc can run the tests. */ -#undef __UNUSED__ -#if defined(__GNUC__) -#define __UNUSED__ __attribute__((__unused__)) -#else -#define __UNUSED__ -#endif - -#define CHECK(x) (!(x) ? abort() : (void)0) - -/* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a - file open. */ -#ifdef HAVE_MMAP_ANON -# undef HAVE_MMAP_DEV_ZERO - -# include -# ifndef MAP_FAILED -# define MAP_FAILED -1 -# endif -# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON) -# define MAP_ANONYMOUS MAP_ANON -# endif -# define USING_MMAP - -#endif - -#ifdef HAVE_MMAP_DEV_ZERO - -# include -# ifndef MAP_FAILED -# define MAP_FAILED -1 -# endif -# define USING_MMAP - -#endif - - -/* MinGW kludge. */ -#ifdef _WIN64 -#define PRIdLL "I64d" -#define PRIuLL "I64u" -#else -#define PRIdLL "lld" -#define PRIuLL "llu" -#endif - diff --git a/Modules/_ctypes/libffi/testsuite/libffi.special/special.exp b/Modules/_ctypes/libffi/testsuite/libffi.special/special.exp deleted file mode 100644 index f1a5fa6d8f5f..000000000000 --- a/Modules/_ctypes/libffi/testsuite/libffi.special/special.exp +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (C) 2003, 2006, 2009, 2010 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING3. If not see -# . - -dg-init -libffi-init - -global srcdir subdir - -global cxx_options - -set cxx_options " -shared-libgcc -lstdc++" - -if { [string match $using_gcc "yes"] } { - - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "-O0 -W -Wall" - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "-O2" - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "-O3" - dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.cc]] $cxx_options "-Os" - -} - -dg-finish - -# Local Variables: -# tcl-indent-level:4 -# End: diff --git a/Modules/_ctypes/libffi/texinfo.tex b/Modules/_ctypes/libffi/texinfo.tex index a5a7b2beac73..85f184cc4cbb 100644 --- a/Modules/_ctypes/libffi/texinfo.tex +++ b/Modules/_ctypes/libffi/texinfo.tex @@ -3,11 +3,11 @@ % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % -\def\texinfoversion{2012-06-05.14} +\def\texinfoversion{2013-02-01.11} % % Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, -% 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. +% 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. % % This texinfo.tex file is free software: you can redistribute it and/or % modify it under the terms of the GNU General Public License as @@ -24,7 +24,8 @@ % % As a special exception, when this file is read by TeX when processing % a Texinfo source document, you may use the result without -% restriction. (This has been our intent since Texinfo was invented.) +% restriction. This Exception is an additional permission under section 7 +% of the GNU General Public License, version 3 ("GPLv3"). % % Please try the latest version of texinfo.tex before submitting bug % reports; you can get the latest version from: @@ -594,7 +595,7 @@ \def\:{\spacefactor=1000 } % @* forces a line break. -\def\*{\hfil\break\hbox{}\ignorespaces} +\def\*{\unskip\hfil\break\hbox{}\ignorespaces} % @/ allows a line break. \let\/=\allowbreak @@ -2272,8 +2273,6 @@ \gdef\markupsetcodequoteleft{\let`\codequoteleft} \gdef\markupsetcodequoteright{\let'\codequoteright} - -\gdef\markupsetnoligaturesquoteleft{\let`\noligaturesquoteleft} } \let\markupsetuplqcode \markupsetcodequoteleft @@ -2282,6 +2281,9 @@ \let\markupsetuplqexample \markupsetcodequoteleft \let\markupsetuprqexample \markupsetcodequoteright % +\let\markupsetuplqkbd \markupsetcodequoteleft +\let\markupsetuprqkbd \markupsetcodequoteright +% \let\markupsetuplqsamp \markupsetcodequoteleft \let\markupsetuprqsamp \markupsetcodequoteright % @@ -2291,8 +2293,6 @@ \let\markupsetuplqverbatim \markupsetcodequoteleft \let\markupsetuprqverbatim \markupsetcodequoteright -\let\markupsetuplqkbd \markupsetnoligaturesquoteleft - % Allow an option to not use regular directed right quote/apostrophe % (char 0x27), but instead the undirected quote from cmtt (char 0x0d). % The undirected quote is ugly, so don't make it the default, but it @@ -2382,8 +2382,7 @@ \aftersmartic } -% like \smartslanted except unconditionally uses \ttsl, and no ic. -% @var is set to this for defun arguments. +% Unconditional use \ttsl, and no ic. @var is set to this for defuns. \def\ttslanted#1{{\ttsl #1}} % @cite is like \smartslanted except unconditionally use \sl. We never want @@ -2448,34 +2447,12 @@ % @samp. \def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}} -% definition of @key that produces a lozenge. Doesn't adjust to text size. -%\setfont\keyrm\rmshape{8}{1000}{OT1} -%\font\keysy=cmsy9 -%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% -% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% -% \vbox{\hrule\kern-0.4pt -% \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% -% \kern-0.4pt\hrule}% -% \kern-.06em\raise0.4pt\hbox{\angleright}}}} - -% definition of @key with no lozenge. If the current font is already -% monospace, don't change it; that way, we respect @kbdinputstyle. But -% if it isn't monospace, then use \tt. -% -\def\key#1{{\setupmarkupstyle{key}% - \nohyphenation - \ifmonospace\else\tt\fi - #1}\null} - -% ctrl is no longer a Texinfo command. -\def\ctrl #1{{\tt \rawbackslash \hat}#1} - -% @file, @option are the same as @samp. -\let\file=\samp -\let\option=\samp +% @indicateurl is \samp, that is, with quotes. +\let\indicateurl=\samp -% @code is a modification of @t, -% which makes spaces the same size as normal in the surrounding text. +% @code (and similar) prints in typewriter, but with spaces the same +% size as normal in the surrounding text, without hyphenation, etc. +% This is a subroutine for that. \def\tclose#1{% {% % Change normal interword space to be same as for the current font. @@ -2500,7 +2477,7 @@ % We *must* turn on hyphenation at `-' and `_' in @code. % Otherwise, it is too hard to avoid overfull hboxes % in the Emacs manual, the Library manual, etc. - +% % Unfortunately, TeX uses one parameter (\hyphenchar) to control % both hyphenation at - and hyphenation within words. % We must therefore turn them both off (\tclose does that) @@ -2519,7 +2496,7 @@ \let-\codedash \let_\codeunder \else - \let-\realdash + \let-\normaldash \let_\realunder \fi \codex @@ -2528,7 +2505,7 @@ \def\codex #1{\tclose{#1}\endgroup} -\def\realdash{-} +\def\normaldash{-} \def\codedash{-\discretionary{}{}{}} \def\codeunder{% % this is all so @math{@code{var_name}+1} can work. In math mode, _ @@ -2543,9 +2520,9 @@ } % An additional complication: the above will allow breaks after, e.g., -% each of the four underscores in __typeof__. This is undesirable in -% some manuals, especially if they don't have long identifiers in -% general. @allowcodebreaks provides a way to control this. +% each of the four underscores in __typeof__. This is bad. +% @allowcodebreaks provides a document-level way to turn breaking at - +% and _ on and off. % \newif\ifallowcodebreaks \allowcodebreakstrue @@ -2564,6 +2541,13 @@ \fi\fi } +% For @command, @env, @file, @option quotes seem unnecessary, +% so use \code rather than \samp. +\let\command=\code +\let\env=\code +\let\file=\code +\let\option=\code + % @uref (abbreviation for `urlref') takes an optional (comma-separated) % second argument specifying the text to display and an optional third % arg as text to display instead of (rather than in addition to) the url @@ -2710,10 +2694,6 @@ \let\email=\uref \fi -% @kbd is like @code, except that if the argument is just one @key command, -% then @kbd has no effect. -\def\kbd#1{{\setupmarkupstyle{kbd}\def\look{#1}\expandafter\kbdfoo\look??\par}} - % @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), % `example' (@kbd uses ttsl only inside of @example and friends), % or `code' (@kbd uses normal tty font always). @@ -2737,16 +2717,36 @@ % Default is `distinct'. \kbdinputstyle distinct +% @kbd is like @code, except that if the argument is just one @key command, +% then @kbd has no effect. +\def\kbd#1{{\def\look{#1}\expandafter\kbdsub\look??\par}} + \def\xkey{\key} -\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}% -\ifx\one\xkey\ifx\threex\three \key{#2}% -\else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi -\else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi} +\def\kbdsub#1#2#3\par{% + \def\one{#1}\def\three{#3}\def\threex{??}% + \ifx\one\xkey\ifx\threex\three \key{#2}% + \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi + \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi +} -% For @indicateurl, @env, @command quotes seem unnecessary, so use \code. -\let\indicateurl=\code -\let\env=\code -\let\command=\code +% definition of @key that produces a lozenge. Doesn't adjust to text size. +%\setfont\keyrm\rmshape{8}{1000}{OT1} +%\font\keysy=cmsy9 +%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% +% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% +% \vbox{\hrule\kern-0.4pt +% \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% +% \kern-0.4pt\hrule}% +% \kern-.06em\raise0.4pt\hbox{\angleright}}}} + +% definition of @key with no lozenge. If the current font is already +% monospace, don't change it; that way, we respect @kbdinputstyle. But +% if it isn't monospace, then use \tt. +% +\def\key#1{{\setupmarkupstyle{key}% + \nohyphenation + \ifmonospace\else\tt\fi + #1}\null} % @clicksequence{File @click{} Open ...} \def\clicksequence#1{\begingroup #1\endgroup} @@ -2854,6 +2854,9 @@ } } +% ctrl is no longer a Texinfo command, but leave this definition for fun. +\def\ctrl #1{{\tt \rawbackslash \hat}#1} + % @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}. % Ignore unless FMTNAME == tex; then it is like @iftex and @tex, % except specified as a normal braced arg, so no newlines to worry about. @@ -3144,12 +3147,17 @@ % hopefully nobody will notice/care. \edef\ecsize{\csname\curfontsize ecsize\endcsname}% \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}% - \ifx\curfontstyle\bfstylename - % bold: - \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize + \ifmonospace + % typewriter: + \font\thisecfont = ectt\ecsize \space at \nominalsize \else - % regular: - \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize + \ifx\curfontstyle\bfstylename + % bold: + \font\thisecfont = ecb\ifusingit{i}{x}\ecsize \space at \nominalsize + \else + % regular: + \font\thisecfont = ec\ifusingit{ti}{rm}\ecsize \space at \nominalsize + \fi \fi \thisecfont } @@ -3262,6 +3270,20 @@ \finishedtitlepagetrue } +% Settings used for typesetting titles: no hyphenation, no indentation, +% don't worry much about spacing, ragged right. This should be used +% inside a \vbox, and fonts need to be set appropriately first. Because +% it is always used for titles, nothing else, we call \rmisbold. \par +% should be specified before the end of the \vbox, since a vbox is a group. +% +\def\raggedtitlesettings{% + \rmisbold + \hyphenpenalty=10000 + \parindent=0pt + \tolerance=5000 + \ptexraggedright +} + % Macros to be used within @titlepage: \let\subtitlerm=\tenrm @@ -3269,7 +3291,7 @@ \parseargdef\title{% \checkenv\titlepage - \leftline{\titlefonts\rmisbold #1} + \vbox{\titlefonts \raggedtitlesettings #1\par}% % print a rule at the page bottom also. \finishedtitlepagefalse \vskip4pt \hrule height 4pt width \hsize \vskip4pt @@ -4166,7 +4188,7 @@ % ..., but we might end up with active ones in the argument if % we're called from @code, as @code{@value{foo-bar_}}, though. % So \let them to their normal equivalents. - \let-\realdash \let_\normalunderscore + \let-\normaldash \let_\normalunderscore } } @@ -4206,7 +4228,7 @@ } \def\ifsetfail{\doignore{ifset}} -% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been +% @ifclear VAR ... @end executes the `...' iff VAR has never been % defined with @set, or has been undefined with @clear. % % The `\else' inside the `\doifset' parameter is a trick to reuse the @@ -4217,6 +4239,35 @@ \def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}} \def\ifclearfail{\doignore{ifclear}} +% @ifcommandisdefined CMD ... @end executes the `...' if CMD (written +% without the @) is in fact defined. We can only feasibly check at the +% TeX level, so something like `mathcode' is going to considered +% defined even though it is not a Texinfo command. +% +\makecond{ifcommanddefined} +\def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}} +% +\def\doifcmddefined#1#2{{% + \makevalueexpandable + \let\next=\empty + \expandafter\ifx\csname #2\endcsname\relax + #1% If not defined, \let\next as above. + \fi + \expandafter + }\next +} +\def\ifcmddefinedfail{\doignore{ifcommanddefined}} + +% @ifcommandnotdefined CMD ... handled similar to @ifclear above. +\makecond{ifcommandnotdefined} +\def\ifcommandnotdefined{% + \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}} +\def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}} + +% Set the `txicommandconditionals' variable, so documents have a way to +% test if the @ifcommand...defined conditionals are available. +\set txicommandconditionals + % @dircategory CATEGORY -- specify a category of the dir file % which this file should belong to. Ignore this in TeX. \let\dircategory=\comment @@ -5543,14 +5594,6 @@ % Define @majorheading, @heading and @subheading -% NOTE on use of \vbox for chapter headings, section headings, and such: -% 1) We use \vbox rather than the earlier \line to permit -% overlong headings to fold. -% 2) \hyphenpenalty is set to 10000 because hyphenation in a -% heading is obnoxious; this forbids it. -% 3) Likewise, headings look best if no \parindent is used, and -% if justification is not attempted. Hence \raggedright. - \def\majorheading{% {\advance\chapheadingskip by 10pt \chapbreak }% \parsearg\chapheadingzzz @@ -5558,10 +5601,8 @@ \def\chapheading{\chapbreak \parsearg\chapheadingzzz} \def\chapheadingzzz#1{% - {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\ptexraggedright - \rmisbold #1\hfill}}% - \bigskip \par\penalty 200\relax + \vbox{\chapfonts \raggedtitlesettings #1\par}% + \nobreak\bigskip \nobreak \suppressfirstparagraphindent } @@ -5720,8 +5761,7 @@ % % Typeset the actual heading. \nobreak % Avoid page breaks at the interline glue. - \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright - \hangindent=\wd0 \centerparametersmaybe + \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe \unhbox0 #1\par}% }% \nobreak\bigskip % no page break after a chapter title @@ -5743,18 +5783,18 @@ \def\setchapterstyle #1 {\csname CHAPF#1\endcsname} % \def\unnchfopen #1{% -\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt\ptexraggedright - \rmisbold #1\hfill}}\bigskip \par\nobreak + \chapoddpage + \vbox{\chapfonts \raggedtitlesettings #1\par}% + \nobreak\bigskip\nobreak } \def\chfopen #1#2{\chapoddpage {\chapfonts \vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}% \par\penalty 5000 % } \def\centerchfopen #1{% -\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000 - \parindent=0pt - \hfill {\rmisbold #1}\hfill}}\bigskip \par\nobreak + \chapoddpage + \vbox{\chapfonts \raggedtitlesettings \hfill #1\hfill}% + \nobreak\bigskip \nobreak } \def\CHAPFopen{% \global\let\chapmacro=\chfopen @@ -6520,16 +6560,9 @@ \makedispenvdef{quotation}{\quotationstart} % \def\quotationstart{% - {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip - \parindent=0pt - % - % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \indentedblockstart % same as \indentedblock, but increase right margin too. \ifx\nonarrowing\relax - \advance\leftskip by \lispnarrowing \advance\rightskip by \lispnarrowing - \exdentamount = \lispnarrowing - \else - \let\nonarrowing = \relax \fi \parsearg\quotationlabel } @@ -6555,6 +6588,32 @@ \fi } +% @indentedblock is like @quotation, but indents only on the left and +% has no optional argument. +% +\makedispenvdef{indentedblock}{\indentedblockstart} +% +\def\indentedblockstart{% + {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip + \parindent=0pt + % + % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \ifx\nonarrowing\relax + \advance\leftskip by \lispnarrowing + \exdentamount = \lispnarrowing + \else + \let\nonarrowing = \relax + \fi +} + +% Keep a nonzero parskip for the environment, since we're doing normal filling. +% +\def\Eindentedblock{% + \par + {\parskip=0pt \afterenvbreak}% +} +\def\Esmallindentedblock{\Eindentedblock} + % LaTeX-like @verbatim...@end verbatim and @verb{...} % If we want to allow any as delimiter, @@ -7033,7 +7092,10 @@ \df \sl \hyphenchar\font=0 % % On the other hand, if an argument has two dashes (for instance), we - % want a way to get ttsl. Let's try @var for that. + % want a way to get ttsl. We used to recommend @var for that, so + % leave the code in, but it's strange for @var to lead to typewriter. + % Nowadays we recommend @code, since the difference between a ttsl hyphen + % and a tt hyphen is pretty tiny. @code also disables ?` !`. \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}% #1% \sl\hyphenchar\font=45 @@ -9931,22 +9993,26 @@ @gdef@otherbackslash{@let\=@realbackslash} % Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of -% the literal character `\'. -% -@def@normalturnoffactive{% - @let"=@normaldoublequote - @let$=@normaldollar %$ font-lock fix - @let+=@normalplus - @let<=@normalless - @let>=@normalgreater - @let\=@normalbackslash - @let^=@normalcaret - @let_=@normalunderscore - @let|=@normalverticalbar - @let~=@normaltilde - @markupsetuplqdefault - @markupsetuprqdefault - @unsepspaces +% the literal character `\'. Also revert - to its normal character, in +% case the active - from code has slipped in. +% +{@catcode`- = @active + @gdef@normalturnoffactive{% + @let-=@normaldash + @let"=@normaldoublequote + @let$=@normaldollar %$ font-lock fix + @let+=@normalplus + @let<=@normalless + @let>=@normalgreater + @let\=@normalbackslash + @let^=@normalcaret + @let_=@normalunderscore + @let|=@normalverticalbar + @let~=@normaltilde + @markupsetuplqdefault + @markupsetuprqdefault + @unsepspaces + } } % Make _ and + \other characters, temporarily. diff --git a/Modules/_ctypes/libffi_msvc/ffi.c b/Modules/_ctypes/libffi_msvc/ffi.c index 6e595e9fe741..b7586c70ebc1 100644 --- a/Modules/_ctypes/libffi_msvc/ffi.c +++ b/Modules/_ctypes/libffi_msvc/ffi.c @@ -65,43 +65,71 @@ void ffi_prep_args(char *stack, extended_cif *ecif) argp = (char *) ALIGN(argp, sizeof(void *)); z = (*p_arg)->size; - if (z < sizeof(int)) + if (z < sizeof(intptr_t)) { - z = sizeof(int); + z = sizeof(intptr_t); switch ((*p_arg)->type) { case FFI_TYPE_SINT8: - *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); + *(intptr_t *) argp = (intptr_t)*(SINT8 *)(* p_argv); break; case FFI_TYPE_UINT8: - *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); + *(uintptr_t *) argp = (uintptr_t)*(UINT8 *)(* p_argv); break; case FFI_TYPE_SINT16: - *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); + *(intptr_t *) argp = (intptr_t)*(SINT16 *)(* p_argv); break; case FFI_TYPE_UINT16: - *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); + *(uintptr_t *) argp = (uintptr_t)*(UINT16 *)(* p_argv); break; case FFI_TYPE_SINT32: - *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv); + *(intptr_t *) argp = (intptr_t)*(SINT32 *)(* p_argv); break; case FFI_TYPE_UINT32: - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + *(uintptr_t *) argp = (uintptr_t)*(UINT32 *)(* p_argv); + break; + + case FFI_TYPE_FLOAT: + *(uintptr_t *) argp = 0; + *(float *) argp = *(float *)(* p_argv); + break; + + // 64-bit value cases should never be used for x86 and AMD64 builds + case FFI_TYPE_SINT64: + *(intptr_t *) argp = (intptr_t)*(SINT64 *)(* p_argv); + break; + + case FFI_TYPE_UINT64: + *(uintptr_t *) argp = (uintptr_t)*(UINT64 *)(* p_argv); break; case FFI_TYPE_STRUCT: - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); + *(uintptr_t *) argp = (uintptr_t)*(UINT32 *)(* p_argv); + break; + + case FFI_TYPE_DOUBLE: + *(uintptr_t *) argp = 0; + *(double *) argp = *(double *)(* p_argv); break; default: FFI_ASSERT(0); } } +#ifdef _WIN64 + else if (z > 8) + { + /* On Win64, if a single argument takes more than 8 bytes, + then it is always passed by reference. */ + *(void **)argp = *p_argv; + z = 8; + } +#endif else { memcpy(argp, *p_argv, z); @@ -124,7 +152,6 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) switch (cif->rtype->type) { case FFI_TYPE_VOID: - case FFI_TYPE_STRUCT: case FFI_TYPE_SINT64: case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: @@ -132,6 +159,18 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) cif->flags = (unsigned) cif->rtype->type; break; + case FFI_TYPE_STRUCT: + /* MSVC returns small structures in registers. Put in cif->flags + the value FFI_TYPE_STRUCT only if the structure is big enough; + otherwise, put the 4- or 8-bytes integer type. */ + if (cif->rtype->size <= 4) + cif->flags = FFI_TYPE_INT; + else if (cif->rtype->size <= 8) + cif->flags = FFI_TYPE_SINT64; + else + cif->flags = FFI_TYPE_STRUCT; + break; + case FFI_TYPE_UINT64: #ifdef _WIN64 case FFI_TYPE_POINTER: @@ -201,8 +240,7 @@ ffi_call(/*@dependent@*/ ffi_cif *cif, #else case FFI_SYSV: /*@-usedef@*/ - /* Function call needs at least 40 bytes stack size, on win64 AMD64 */ - return ffi_call_AMD64(ffi_prep_args, &ecif, cif->bytes ? cif->bytes : 40, + return ffi_call_AMD64(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); /*@=usedef@*/ break; @@ -227,7 +265,7 @@ void * #else static void __fastcall #endif -ffi_closure_SYSV (ffi_closure *closure, int *argp) +ffi_closure_SYSV (ffi_closure *closure, char *argp) { // this is our return value storage long double res; @@ -237,7 +275,7 @@ ffi_closure_SYSV (ffi_closure *closure, int *argp) void **arg_area; unsigned short rtype; void *resp = (void*)&res; - void *args = &argp[1]; + void *args = argp + sizeof(void*); cif = closure->cif; arg_area = (void**) alloca (cif->nargs * sizeof (void*)); diff --git a/Modules/_ctypes/libffi_msvc/prep_cif.c b/Modules/_ctypes/libffi_msvc/prep_cif.c index 2650fa05254e..b07a2e6db271 100644 --- a/Modules/_ctypes/libffi_msvc/prep_cif.c +++ b/Modules/_ctypes/libffi_msvc/prep_cif.c @@ -116,9 +116,9 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, #if !defined M68K && !defined __x86_64__ && !defined S390 /* Make space for the return structure pointer */ if (cif->rtype->type == FFI_TYPE_STRUCT - /* MSVC returns small structures in registers. But we have a different - workaround: pretend int32 or int64 return type, and converting to - structure afterwards. */ +#ifdef _WIN32 + && (cif->rtype->size > 8) /* MSVC returns small structs in registers */ +#endif #ifdef SPARC && (cif->abi != FFI_V9 || cif->rtype->size > 32) #endif @@ -145,6 +145,10 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, && cif->abi != FFI_V9)) bytes += sizeof(void*); else +#elif defined (_WIN64) + if ((*ptr)->type == FFI_TYPE_STRUCT && ((*ptr)->size > 8)) + bytes += sizeof(void*); + else #endif { #if !defined(_MSC_VER) && !defined(__MINGW32__) @@ -168,6 +172,12 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, #endif } +#ifdef _WIN64 + /* Function call needs at least 40 bytes stack size, on win64 AMD64 */ + if (bytes < 40) + bytes = 40; +#endif + cif->bytes = bytes; /* Perform machine dependent cif processing */ diff --git a/Modules/_ctypes/libffi_msvc/types.c b/Modules/_ctypes/libffi_msvc/types.c index df32190d115b..4433ac28c8c8 100644 --- a/Modules/_ctypes/libffi_msvc/types.c +++ b/Modules/_ctypes/libffi_msvc/types.c @@ -43,7 +43,7 @@ FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32); FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT); #if defined ALPHA || defined SPARC64 || defined X86_64 || defined S390X \ - || defined IA64 + || defined IA64 || defined _WIN64 FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER); diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index b95b0a423178..879afb8424fc 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -76,14 +76,18 @@ PyCStgDict_clone(StgDictObject *dst, StgDictObject *src) if (src->format) { dst->format = PyMem_Malloc(strlen(src->format) + 1); - if (dst->format == NULL) + 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) + if (dst->shape == NULL) { + PyErr_NoMemory(); return -1; + } memcpy(dst->shape, src->shape, sizeof(Py_ssize_t) * src->ndim); } @@ -380,7 +384,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct union_size = 0; total_align = align ? align : 1; stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT; - stgdict->ffi_type_pointer.elements = PyMem_Malloc(sizeof(ffi_type *) * (basedict->length + len + 1)); + stgdict->ffi_type_pointer.elements = PyMem_New(ffi_type *, basedict->length + len + 1); if (stgdict->ffi_type_pointer.elements == NULL) { PyErr_NoMemory(); return -1; @@ -398,7 +402,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct union_size = 0; total_align = 1; stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT; - stgdict->ffi_type_pointer.elements = PyMem_Malloc(sizeof(ffi_type *) * (len + 1)); + stgdict->ffi_type_pointer.elements = PyMem_New(ffi_type *, len + 1); if (stgdict->ffi_type_pointer.elements == NULL) { PyErr_NoMemory(); return -1; @@ -505,7 +509,12 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct sprintf(buf, "%s:%s:", fieldfmt, fieldname); ptr = stgdict->format; - stgdict->format = _ctypes_alloc_format_string(stgdict->format, buf); + 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); diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 98b81fef6e22..d64bdc74e916 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -134,11 +134,13 @@ typedef chtype attr_t; /* No attr_t type is available */ #define STRICT_SYSV_CURSES #endif -/*[clinic] +/*[clinic input] module curses -class curses.window -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +class curses.window "PyCursesWindowObject *" "&PyCursesWindow_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=88c860abdbb50e0c]*/ + +#include "clinic/_cursesmodule.c.h" /* Definition of exception curses.error */ @@ -555,15 +557,15 @@ PyCursesWindow_Dealloc(PyCursesWindowObject *wo) /* Addch, Addstr, Addnstr */ -/*[clinic] +/*[clinic input] curses.window.addch [ - x: int - X-coordinate. y: int Y-coordinate. + x: int + X-coordinate. ] ch: object @@ -581,76 +583,12 @@ 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]*/ - -PyDoc_STRVAR(curses_window_addch__doc__, -"addch([x, y,] ch, [attr])\n" -"Paint character ch at (y, x) with attributes attr.\n" -"\n" -" x\n" -" X-coordinate.\n" -" y\n" -" Y-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(PyObject *self, int group_left_1, int x, int y, PyObject *ch, int group_right_1, long attr); - -static PyObject * -curses_window_addch(PyObject *self, PyObject *args) -{ - PyObject *return_value = NULL; - int group_left_1 = 0; - int x = 0; - int y = 0; - PyObject *ch; - int group_right_1 = 0; - long attr = 0; - - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "O:addch", &ch)) - return NULL; - break; - case 2: - if (!PyArg_ParseTuple(args, "Ol:addch", &ch, &attr)) - return NULL; - group_right_1 = 1; - break; - case 3: - if (!PyArg_ParseTuple(args, "iiO:addch", &x, &y, &ch)) - return NULL; - group_left_1 = 1; - break; - case 4: - if (!PyArg_ParseTuple(args, "iiOl:addch", &x, &y, &ch, &attr)) - return NULL; - group_right_1 = 1; - group_left_1 = 1; - break; - default: - PyErr_SetString(PyExc_TypeError, "curses.window.addch requires 1 to 4 arguments"); - return NULL; - } - return_value = curses_window_addch_impl(self, group_left_1, x, y, ch, group_right_1, attr); - - return return_value; -} +[clinic start generated code]*/ static PyObject * -curses_window_addch_impl(PyObject *self, int group_left_1, int x, int y, PyObject *ch, int group_right_1, long attr) -/*[clinic checksum: 44ed958b891cde91205e584c766e048f3999714f]*/ +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=99f7f85078ec06c3 input=5a41efb34a2de338]*/ { PyCursesWindowObject *cwself = (PyCursesWindowObject *)self; int coordinates_group = group_left_1; @@ -1414,7 +1352,8 @@ PyCursesWindow_InsCh(PyCursesWindowObject *self, PyObject *args) static PyObject * PyCursesWindow_InCh(PyCursesWindowObject *self, PyObject *args) { - int x, y, rtn; + int x, y; + unsigned long rtn; switch (PyTuple_Size(args)) { case 0: @@ -1429,7 +1368,7 @@ PyCursesWindow_InCh(PyCursesWindowObject *self, PyObject *args) PyErr_SetString(PyExc_TypeError, "inch requires 0 or 2 arguments"); return NULL; } - return PyLong_FromLong((long) rtn); + return PyLong_FromUnsignedLong(rtn); } static PyObject * @@ -2086,8 +2025,6 @@ static PyMethodDef PyCursesWindow_Methods[] = { {"nodelay", (PyCFunction)PyCursesWindow_nodelay, METH_VARARGS}, {"notimeout", (PyCFunction)PyCursesWindow_notimeout, METH_VARARGS}, {"noutrefresh", (PyCFunction)PyCursesWindow_NoOutRefresh, METH_VARARGS}, - /* Backward compatibility alias -- remove in Python 2.3 */ - {"nooutrefresh", (PyCFunction)PyCursesWindow_NoOutRefresh, METH_VARARGS}, {"overlay", (PyCFunction)PyCursesWindow_Overlay, METH_VARARGS}, {"overwrite", (PyCFunction)PyCursesWindow_Overwrite, METH_VARARGS}, @@ -2675,7 +2612,7 @@ PyCurses_KeyName(PyObject *self, PyObject *args) } knp = keyname(ch); - return PyBytes_FromString((knp == NULL) ? "" : (char *)knp); + return PyBytes_FromString((knp == NULL) ? "" : knp); } #endif @@ -2929,6 +2866,13 @@ update_lines_cols(void) Py_DECREF(m); return 1; } + +static PyObject * +PyCurses_update_lines_cols(PyObject *self) +{ + return PyLong_FromLong((long) update_lines_cols()); +} + #endif #ifdef HAVE_CURSES_RESIZETERM @@ -3331,6 +3275,9 @@ static PyMethodDef PyCurses_methods[] = { {"typeahead", (PyCFunction)PyCurses_TypeAhead, METH_VARARGS}, {"unctrl", (PyCFunction)PyCurses_UnCtrl, METH_VARARGS}, {"ungetch", (PyCFunction)PyCurses_UngetCh, METH_VARARGS}, +#if defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM) + {"update_lines_cols", (PyCFunction)PyCurses_update_lines_cols, METH_NOARGS}, +#endif #ifdef HAVE_NCURSESW {"unget_wch", (PyCFunction)PyCurses_Unget_Wch, METH_VARARGS}, #endif diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index e4dc1bfa73a8..94336cf1462f 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -7,6 +7,10 @@ #include +#ifdef MS_WINDOWS +# include /* struct timeval */ +#endif + /* Differentiate between building the core module and building extension * modules. */ @@ -16,11 +20,13 @@ #include "datetime.h" #undef Py_BUILD_CORE -/*[clinic] +/*[clinic input] module datetime -class datetime.datetime -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +class datetime.datetime "PyDateTime_DateTime *" "&PyDateTime_DateTimeType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=78142cb64b9e98bc]*/ + +#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 @@ -613,7 +619,7 @@ time_alloc(PyTypeObject *type, Py_ssize_t aware) sizeof(_PyDateTime_BaseTime)); if (self == NULL) return (PyObject *)PyErr_NoMemory(); - PyObject_INIT(self, type); + (void)PyObject_INIT(self, type); return self; } @@ -628,7 +634,7 @@ datetime_alloc(PyTypeObject *type, Py_ssize_t aware) sizeof(_PyDateTime_BaseDateTime)); if (self == NULL) return (PyObject *)PyErr_NoMemory(); - PyObject_INIT(self, type); + (void)PyObject_INIT(self, type); return self; } @@ -897,11 +903,11 @@ call_tzinfo_method(PyObject *tzinfo, char *name, PyObject *tzinfoarg) } } else { - Py_DECREF(offset); PyErr_Format(PyExc_TypeError, "tzinfo.%s() must return None or " "timedelta, not '%.200s'", name, Py_TYPE(offset)->tp_name); + Py_DECREF(offset); return NULL; } @@ -2153,7 +2159,7 @@ delta_new(PyTypeObject *type, PyObject *args, PyObject *kw) * 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, one); /* temp <- x & 1 */ + temp = PyNumber_And(x, one); /* temp <- x & 1 */ if (temp == NULL) { Py_DECREF(x); goto Done; @@ -2459,7 +2465,7 @@ date_local_from_object(PyObject *cls, PyObject *obj) struct tm *tm; time_t t; - if (_PyTime_ObjectToTime_t(obj, &t) == -1) + if (_PyTime_ObjectToTime_t(obj, &t, _PyTime_ROUND_FLOOR) == -1) return NULL; tm = localtime(&t); @@ -3040,7 +3046,7 @@ tzinfo_fromutc(PyDateTime_TZInfo *self, PyObject *dt) goto Fail; if (dst == Py_None) goto Inconsistent; - if (delta_bool(delta) != 0) { + if (delta_bool((PyDateTime_Delta *)dst) != 0) { PyObject *temp = result; result = add_datetime_timedelta((PyDateTime_DateTime *)result, (PyDateTime_Delta *)dst, 1); @@ -3224,10 +3230,10 @@ timezone_richcompare(PyDateTime_TimeZone *self, if (op != Py_EQ && op != Py_NE) Py_RETURN_NOTIMPLEMENTED; if (Py_TYPE(other) != &PyDateTime_TimeZoneType) { - if (op == Py_EQ) - Py_RETURN_FALSE; - else - Py_RETURN_TRUE; + if (op == Py_EQ) + Py_RETURN_FALSE; + else + Py_RETURN_TRUE; } return delta_richcompare(self->offset, other->offset, op); } @@ -3281,6 +3287,11 @@ timezone_str(PyDateTime_TimeZone *self) 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 = '-'; @@ -3805,29 +3816,6 @@ time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw) return clone; } -static int -time_bool(PyObject *self) -{ - PyObject *offset, *tzinfo; - int offsecs = 0; - - if (TIME_GET_SECOND(self) || TIME_GET_MICROSECOND(self)) { - /* Since utcoffset is in whole minutes, nothing can - * alter the conclusion that this is nonzero. - */ - return 1; - } - tzinfo = GET_TIME_TZINFO(self); - if (tzinfo != Py_None) { - offset = call_utcoffset(tzinfo, Py_None); - if (offset == NULL) - return -1; - offsecs = GET_TD_DAYS(offset)*86400 + GET_TD_SECONDS(offset); - Py_DECREF(offset); - } - return (TIME_GET_MINUTE(self)*60 - offsecs + TIME_GET_HOUR(self)*3600) != 0; -} - /* Pickle support, a simple use of __reduce__. */ /* Let basestate be the non-tzinfo data string. @@ -3895,19 +3883,6 @@ PyDoc_STR("time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) --> a time All arguments are optional. tzinfo may be None, or an instance of\n\ a tzinfo subclass. The remaining arguments may be ints.\n"); -static PyNumberMethods time_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)time_bool, /* nb_bool */ -}; - static PyTypeObject PyDateTime_TimeType = { PyVarObject_HEAD_INIT(NULL, 0) "datetime.time", /* tp_name */ @@ -3919,7 +3894,7 @@ static PyTypeObject PyDateTime_TimeType = { 0, /* tp_setattr */ 0, /* tp_reserved */ (reprfunc)time_repr, /* tp_repr */ - &time_as_number, /* tp_as_number */ + 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ (hashfunc)time_hash, /* tp_hash */ @@ -4127,8 +4102,10 @@ datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp, time_t timet; long us; - if (_PyTime_ObjectToTimeval(timestamp, &timet, &us) == -1) + 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); } @@ -4139,13 +4116,18 @@ datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp, static PyObject * datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo) { - _PyTime_timeval t; - _PyTime_gettimeofday(&t); - return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec, - 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] +/*[clinic input] @classmethod datetime.datetime.now @@ -4156,43 +4138,11 @@ datetime.datetime.now Returns new datetime object representing current time local to tz. If no tz is specified, uses local timezone. -[clinic]*/ - -PyDoc_STRVAR(datetime_datetime_now__doc__, -"now(tz=None)\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)datetime_datetime_now, METH_VARARGS|METH_KEYWORDS|METH_CLASS, datetime_datetime_now__doc__}, - -static PyObject * -datetime_datetime_now_impl(PyTypeObject *cls, PyObject *tz); - -static PyObject * -datetime_datetime_now(PyTypeObject *cls, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - static char *_keywords[] = {"tz", NULL}; - PyObject *tz = Py_None; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "|O:now", _keywords, - &tz)) - goto exit; - return_value = datetime_datetime_now_impl(cls, tz); - -exit: - return return_value; -} +[clinic start generated code]*/ static PyObject * -datetime_datetime_now_impl(PyTypeObject *cls, PyObject *tz) -/*[clinic checksum: ca3d26a423b3f633b260c7622e303f0915a96f7c]*/ +datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz) +/*[clinic end generated code: output=b3386e5345e2b47a input=80d09869c5267d00]*/ { PyObject *self; @@ -4202,7 +4152,7 @@ datetime_datetime_now_impl(PyTypeObject *cls, PyObject *tz) if (check_tzinfo_subclass(tz) < 0) return NULL; - self = datetime_best_possible((PyObject *)cls, + self = datetime_best_possible((PyObject *)type, tz == Py_None ? localtime : gmtime, tz); if (self != NULL && tz != Py_None) { @@ -4763,7 +4713,7 @@ local_timezone(PyDateTime_DateTime *utc_time) if (seconds == NULL) goto error; Py_DECREF(delta); - timestamp = PyLong_AsLong(seconds); + timestamp = _PyLong_AsTime_t(seconds); Py_DECREF(seconds); if (timestamp == -1 && PyErr_Occurred()) return NULL; @@ -4812,7 +4762,7 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) static char *keywords[] = {"tz", NULL}; if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:astimezone", keywords, - &tzinfo)) + &tzinfo)) return NULL; if (check_tzinfo_subclass(tzinfo) == -1) @@ -5054,8 +5004,7 @@ static PyMethodDef datetime_methods[] = { {"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp, METH_VARARGS | METH_CLASS, - PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp " - "(like time.time()).")}, + PyDoc_STR("Construct a naive UTC datetime from a POSIX timestamp.")}, {"strptime", (PyCFunction)datetime_strptime, METH_VARARGS | METH_CLASS, diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index 10f8fb939ee2..02899e4303e0 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -28,11 +28,11 @@ static char *which_dbm = "Berkeley DB"; #error "No ndbm.h available!" #endif -/*[clinic] -module dbm -class dbm.dbm -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +/*[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 @@ -40,6 +40,8 @@ typedef struct { DBM *di_dbm; } dbmobject; +#include "clinic/_dbmmodule.c.h" + static PyTypeObject Dbmtype; #define is_dbmobject(v) (Py_TYPE(v) == &Dbmtype) @@ -49,14 +51,6 @@ static PyTypeObject Dbmtype; static PyObject *DbmError; -/*[python] -class dbmobject_converter(self_converter): - type = "dbmobject *" - def converter_init(self): - self.name = 'dp' -[python]*/ -/*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ - static PyObject * newdbmobject(const char *file, int flags, int mode) { @@ -66,7 +60,8 @@ newdbmobject(const char *file, int flags, int mode) if (dp == NULL) return NULL; dp->di_size = -1; - if ( (dp->di_dbm = dbm_open(file, flags, mode)) == 0 ) { + /* See issue #19296 */ + if ( (dp->di_dbm = dbm_open((char *)file, flags, mode)) == 0 ) { PyErr_SetFromErrno(DbmError); Py_DECREF(dp); return NULL; @@ -179,29 +174,43 @@ static PyMappingMethods dbm_as_mapping = { (objobjargproc)dbm_ass_sub, /*mp_ass_subscript*/ }; +/*[clinic input] +_dbm.dbm.close + +Close the database. +[clinic start generated code]*/ + static PyObject * -dbm__close(dbmobject *dp, PyObject *unused) +_dbm_dbm_close_impl(dbmobject *self) +/*[clinic end generated code: output=c8dc5b6709600b86 input=046db72377d51be8]*/ { - if (dp->di_dbm) - dbm_close(dp->di_dbm); - dp->di_dbm = NULL; + if (self->di_dbm) + dbm_close(self->di_dbm); + self->di_dbm = NULL; Py_INCREF(Py_None); return Py_None; } +/*[clinic input] +_dbm.dbm.keys + +Return a list of all keys in the database. +[clinic start generated code]*/ + static PyObject * -dbm_keys(dbmobject *dp, PyObject *unused) +_dbm_dbm_keys_impl(dbmobject *self) +/*[clinic end generated code: output=434549f7c121b33c input=d210ba778cd9c68a]*/ { PyObject *v, *item; datum key; int err; - check_dbmobject_open(dp); + check_dbmobject_open(self); v = PyList_New(0); if (v == NULL) return NULL; - for (key = dbm_firstkey(dp->di_dbm); key.dptr; - key = dbm_nextkey(dp->di_dbm)) { + 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); @@ -262,71 +271,28 @@ static PySequenceMethods dbm_as_sequence = { 0, /* sq_inplace_repeat */ }; -/*[clinic] - -dbm.dbm.get +/*[clinic input] +_dbm.dbm.get - self: dbmobject - - key: str(length=True) - [ - default: object - ] + key: str(accept={str, robuffer}, zeroes=True) + default: object(c_default="NULL") = b'' / Return the value for key if present, otherwise default. -[clinic]*/ - -PyDoc_STRVAR(dbm_dbm_get__doc__, -"get(key, [default])\n" -"Return the value for key if present, otherwise default."); - -#define DBM_DBM_GET_METHODDEF \ - {"get", (PyCFunction)dbm_dbm_get, METH_VARARGS, dbm_dbm_get__doc__}, - -static PyObject * -dbm_dbm_get_impl(dbmobject *dp, const char *key, Py_ssize_clean_t key_length, int group_right_1, PyObject *default_value); +[clinic start generated code]*/ static PyObject * -dbm_dbm_get(PyObject *self, PyObject *args) -{ - PyObject *return_value = NULL; - const char *key; - Py_ssize_clean_t key_length; - int group_right_1 = 0; - PyObject *default_value = NULL; - - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "s#:get", &key, &key_length)) - return NULL; - break; - case 2: - if (!PyArg_ParseTuple(args, "s#O:get", &key, &key_length, &default_value)) - return NULL; - group_right_1 = 1; - break; - default: - PyErr_SetString(PyExc_TypeError, "dbm.dbm.get requires 1 to 2 arguments"); - return NULL; - } - return_value = dbm_dbm_get_impl((dbmobject *)self, key, key_length, group_right_1, default_value); - - return return_value; -} - -static PyObject * -dbm_dbm_get_impl(dbmobject *dp, const char *key, Py_ssize_clean_t key_length, int group_right_1, PyObject *default_value) -/*[clinic checksum: 28cf8928811bde51e535d67ae98ea039d79df717]*/ +_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=a3a279957f85eb6d]*/ +/*[clinic end generated code: output=4f5c0e523eaf1251 input=9402c0af8582dc69]*/ { datum dbm_key, val; - if (!group_right_1) - default_value = Py_None; dbm_key.dptr = (char *)key; dbm_key.dsize = key_length; - check_dbmobject_open(dp); - val = dbm_fetch(dp->di_dbm, dbm_key); + check_dbmobject_open(self); + val = dbm_fetch(self->di_dbm, dbm_key); if (val.dptr != NULL) return PyBytes_FromStringAndSize(val.dptr, val.dsize); @@ -334,46 +300,55 @@ dbm_dbm_get_impl(dbmobject *dp, const char *key, Py_ssize_clean_t key_length, in 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_setdefault(dbmobject *dp, PyObject *args) +_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 key, val; - PyObject *defvalue = NULL; - char *tmp_ptr; + datum dbm_key, val; Py_ssize_t tmp_size; - if (!PyArg_ParseTuple(args, "s#|O:setdefault", - &tmp_ptr, &tmp_size, &defvalue)) - return NULL; - key.dptr = tmp_ptr; - key.dsize = tmp_size; - check_dbmobject_open(dp); - val = dbm_fetch(dp->di_dbm, key); + 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 (defvalue == NULL) { - defvalue = PyBytes_FromStringAndSize(NULL, 0); - if (defvalue == NULL) + 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(defvalue, "s#", &val.dptr, &tmp_size) ) { + if ( !PyArg_Parse(default_value, "s#", &val.dptr, &tmp_size) ) { PyErr_SetString(PyExc_TypeError, "dbm mappings have byte string elements only"); return NULL; } val.dsize = tmp_size; - Py_INCREF(defvalue); + Py_INCREF(default_value); } - if (dbm_store(dp->di_dbm, key, val, DBM_INSERT) < 0) { - dbm_clearerr(dp->di_dbm); + 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(defvalue); + Py_DECREF(default_value); return NULL; } - return defvalue; + return default_value; } static PyObject * @@ -392,15 +367,10 @@ dbm__exit__(PyObject *self, PyObject *args) static PyMethodDef dbm_methods[] = { - {"close", (PyCFunction)dbm__close, METH_NOARGS, - "close()\nClose the database."}, - {"keys", (PyCFunction)dbm_keys, METH_NOARGS, - "keys() -> list\nReturn a list of all keys in the database."}, - DBM_DBM_GET_METHODDEF - {"setdefault", (PyCFunction)dbm_setdefault, METH_VARARGS, - "setdefault(key[, default]) -> value\n" - "Return the value for key if present, otherwise default. If key\n" - "is not in the database, it is inserted with default as the value."}, + _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 */ @@ -439,9 +409,9 @@ static PyTypeObject Dbmtype = { /* ----------------------------------------------------------------- */ -/*[clinic] +/*[clinic input] -dbm.open as dbmopen +_dbm.open as dbmopen filename: str The filename to open. @@ -449,7 +419,7 @@ dbm.open as dbmopen flags: str="r" How to open the file. "r" for reading, "w" for writing, etc. - mode: int(doc_default="0o666") = 0o666 + mode: int(py_default="0o666") = 0o666 If creating a new file, the mode bits for the new file (e.g. os.O_RDWR). @@ -457,47 +427,12 @@ dbm.open as dbmopen Return a database object. -[clinic]*/ - -PyDoc_STRVAR(dbmopen__doc__, -"open(filename, flags=\'r\', mode=0o666)\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)dbmopen, METH_VARARGS, dbmopen__doc__}, - -static PyObject * -dbmopen_impl(PyModuleDef *module, const char *filename, const char *flags, int mode); - -static PyObject * -dbmopen(PyModuleDef *module, PyObject *args) -{ - PyObject *return_value = NULL; - const char *filename; - const char *flags = "r"; - int mode = 438; - - if (!PyArg_ParseTuple(args, - "s|si:open", - &filename, &flags, &mode)) - goto exit; - return_value = dbmopen_impl(module, filename, flags, mode); - -exit: - return return_value; -} +[clinic start generated code]*/ static PyObject * -dbmopen_impl(PyModuleDef *module, const char *filename, const char *flags, int mode) -/*[clinic checksum: fb265f75641553ccd963f84c143b35c11f9121fc]*/ +dbmopen_impl(PyModuleDef *module, const char *filename, const char *flags, + int mode) +/*[clinic end generated code: output=e8d4b36f25c733fd input=226334bade5764e6]*/ { int iflags; diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index ac20308953a7..169914c2f749 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -39,8 +39,8 @@ #include "memory.h" -#if MPD_MAJOR_VERSION != 2 - #error "libmpdec major version 2 required" +#if !defined(MPD_VERSION_HEX) || MPD_VERSION_HEX < 0x02040100 + #error "libmpdec version >= 2.4.1 required" #endif @@ -3542,7 +3542,7 @@ PyDec_Round(PyObject *dec, PyObject *args) } } -static PyObject *DecimalTuple = NULL; +static PyTypeObject *DecimalTuple = NULL; /* Return the DecimalTuple representation of a PyDecObject. */ static PyObject * PyDec_AsTuple(PyObject *dec, PyObject *dummy UNUSED) @@ -3625,7 +3625,7 @@ PyDec_AsTuple(PyObject *dec, PyObject *dummy UNUSED) } } - result = PyObject_CallFunctionObjArgs(DecimalTuple, + result = PyObject_CallFunctionObjArgs((PyObject *)DecimalTuple, sign, coeff, expt, NULL); out: @@ -3928,9 +3928,6 @@ nm_mpd_qdivmod(PyObject *v, PyObject *w) return ret; } -static mpd_uint_t data_zero[1] = {0}; -static const mpd_t zero = {MPD_STATIC|MPD_CONST_DATA, 0, 1, 1, 1, data_zero}; - static PyObject * nm_mpd_qpow(PyObject *base, PyObject *exp, PyObject *mod) { @@ -5565,9 +5562,14 @@ PyInit__decimal(void) /* DecimalTuple */ ASSIGN_PTR(collections, PyImport_ImportModule("collections")); - ASSIGN_PTR(DecimalTuple, PyObject_CallMethod(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(MutableMapping, PyObject_GetAttrString(collections, "MutableMapping")); @@ -5594,7 +5596,7 @@ PyInit__decimal(void) CHECK_INT(PyModule_AddObject(m, "Context", (PyObject *)&PyDecContext_Type)); Py_INCREF(DecimalTuple); - CHECK_INT(PyModule_AddObject(m, "DecimalTuple", DecimalTuple)); + CHECK_INT(PyModule_AddObject(m, "DecimalTuple", (PyObject *)DecimalTuple)); /* Create top level exception */ @@ -5638,7 +5640,7 @@ PyInit__decimal(void) goto error; /* GCOV_NOT_REACHED */ } - ASSIGN_PTR(cm->ex, PyErr_NewException((char *)cm->fqname, base, NULL)); + ASSIGN_PTR(cm->ex, PyErr_NewException(cm->fqname, base, NULL)); Py_DECREF(base); /* add to module */ @@ -5670,7 +5672,7 @@ PyInit__decimal(void) goto error; /* GCOV_NOT_REACHED */ } - ASSIGN_PTR(cm->ex, PyErr_NewException((char *)cm->fqname, base, NULL)); + ASSIGN_PTR(cm->ex, PyErr_NewException(cm->fqname, base, NULL)); Py_DECREF(base); Py_INCREF(cm->ex); diff --git a/Modules/_decimal/docstrings.h b/Modules/_decimal/docstrings.h index a6490b982a3a..71029a994bbe 100644 --- a/Modules/_decimal/docstrings.h +++ b/Modules/_decimal/docstrings.h @@ -19,26 +19,30 @@ PyDoc_STRVAR(doc__decimal, "C decimal arithmetic module"); -PyDoc_STRVAR(doc_getcontext,"\n\ -getcontext() - Get the current default context.\n\ +PyDoc_STRVAR(doc_getcontext, +"getcontext($module, /)\n--\n\n\ +Get the current default context.\n\ \n"); -PyDoc_STRVAR(doc_setcontext,"\n\ -setcontext(c) - Set a new default context.\n\ +PyDoc_STRVAR(doc_setcontext, +"setcontext($module, context, /)\n--\n\n\ +Set a new default context.\n\ \n"); -PyDoc_STRVAR(doc_localcontext,"\n\ -localcontext(ctx=None) - Return a context manager that will set the default\n\ -context to a copy of ctx on entry to the with-statement and restore the\n\ -previous default context when exiting the with-statement. If no context is\n\ -specified, a copy of the current default context is used.\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,"\n\ -IEEEContext(bits) - Return a context object initialized to the proper values for\n\ -one of the IEEE interchange formats. The argument must be a multiple of 32 and\n\ -less than IEEE_CONTEXT_MAX_BITS. For the most common values, the constants\n\ +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 @@ -48,32 +52,34 @@ DECIMAL32, DECIMAL64 and DECIMAL128 are provided.\n\ /* Decimal Object and Methods */ /******************************************************************************/ -PyDoc_STRVAR(doc_decimal,"\n\ -Decimal(value=\"0\", context=None): Construct a new Decimal object.\n\ -value can be an integer, string, tuple, or another Decimal object.\n\ -If no value is given, return Decimal('0'). The context does not affect\n\ -the conversion and is only passed to determine if the InvalidOperation\n\ -trap is active.\n\ +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,"\n\ -adjusted() - Return the adjusted exponent of the number.\n\ -\n\ -Defined as exp + digits - 1.\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,"\n\ -as_tuple() - Return a tuple representation of the number.\n\ +PyDoc_STRVAR(doc_as_tuple, +"as_tuple($self, /)\n--\n\n\ +Return a tuple representation of the number.\n\ \n"); -PyDoc_STRVAR(doc_canonical,"\n\ -canonical() - Return the canonical encoding of the argument. Currently,\n\ -the encoding of a Decimal instance is always canonical, so this operation\n\ -returns its argument unchanged.\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,"\n\ -compare(other, context=None) - Compare self to other. Return a decimal value:\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\ @@ -81,17 +87,18 @@ compare(other, context=None) - Compare self to other. Return a decimal value:\n\ a > b ==> Decimal('1')\n\ \n"); -PyDoc_STRVAR(doc_compare_signal,"\n\ -compare_signal(other, context=None) - Identical to compare, except that\n\ -all NaNs signal.\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,"\n\ -compare_total(other, context=None) - Compare two operands using their\n\ -abstract representation rather than their numerical value. Similar to the\n\ -compare() method, but the result gives a total ordering on Decimal instances.\n\ -Two Decimal instances with the same numeric value but different representations\n\ -compare unequal in this ordering:\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\ @@ -107,36 +114,39 @@ 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,"\n\ -compare_total_mag(other, context=None) - Compare two operands using their\n\ -abstract representation rather than their value as in compare_total(), but\n\ -ignoring the sign of each operand. x.compare_total_mag(y) is equivalent to\n\ -x.copy_abs().compare_total(y.copy_abs()).\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,"\n\ -conjugate() - Return self.\n\ +PyDoc_STRVAR(doc_conjugate, +"conjugate($self, /)\n--\n\n\ +Return self.\n\ \n"); -PyDoc_STRVAR(doc_copy_abs,"\n\ -copy_abs() - Return the absolute value of the argument. This operation\n\ -is unaffected by context and is quiet: no flags are changed and no rounding\n\ -is performed.\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,"\n\ -copy_negate() - Return the negation of the argument. This operation is\n\ -unaffected by context and is quiet: no flags are changed and no rounding\n\ -is performed.\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,"\n\ -copy_sign(other, context=None) - Return a copy of the first operand with\n\ -the sign set to be the same as the sign of the second operand. For example:\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\ @@ -146,14 +156,16 @@ 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,"\n\ -exp(context=None) - Return the value of the (natural) exponential function\n\ -e**x at the given number. The function always uses the ROUND_HALF_EVEN mode\n\ -and the result is correctly rounded.\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,"\n\ -from_float(f) - Class method that converts a float to a decimal number, exactly.\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\ @@ -168,155 +180,176 @@ Decimal.from_float(0.1) is not the same as Decimal('0.1').\n\ \n\ \n"); -PyDoc_STRVAR(doc_fma,"\n\ -fma(other, third, context=None) - Fused multiply-add. Return self*other+third\n\ -with no rounding of the intermediate product self*other.\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,"\n\ -is_canonical() - Return True if the argument is canonical and False otherwise.\n\ -Currently, a Decimal instance is always canonical, so this operation always\n\ -returns True.\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,"\n\ -is_finite() - Return True if the argument is a finite number, and False if the\n\ -argument is infinite or a NaN.\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,"\n\ -is_infinite() - Return True if the argument is either positive or negative\n\ -infinity and False otherwise.\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,"\n\ -is_nan() - Return True if the argument is a (quiet or signaling) NaN and\n\ -False otherwise.\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,"\n\ -is_normal(context=None) - Return True if the argument is a normal finite\n\ -non-zero number with an adjusted exponent greater than or equal to Emin.\n\ -Return False if the argument is zero, subnormal, infinite or a NaN.\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,"\n\ -is_qnan() - Return True if the argument is a quiet NaN, and False otherwise.\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,"\n\ -is_signed() - Return True if the argument has a negative sign and\n\ -False otherwise. Note that both zeros and NaNs can carry signs.\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,"\n\ -is_snan() - Return True if the argument is a signaling NaN and False otherwise.\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,"\n\ -is_subnormal(context=None) - Return True if the argument is subnormal, and\n\ -False otherwise. A number is subnormal if it is non-zero, finite, and has an\n\ -adjusted exponent less than Emin.\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,"\n\ -is_zero() - Return True if the argument is a (positive or negative) zero and\n\ -False otherwise.\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,"\n\ -ln(context=None) - Return the natural (base e) logarithm of the operand.\n\ -The function always uses the ROUND_HALF_EVEN mode and the result is\n\ -correctly rounded.\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,"\n\ -log10(context=None) - Return the base ten logarithm of the operand.\n\ -The function always uses the ROUND_HALF_EVEN mode and the result is\n\ -correctly rounded.\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,"\n\ -logb(context=None) - For a non-zero number, return the adjusted exponent\n\ -of the operand as a Decimal instance. If the operand is a zero, then\n\ -Decimal('-Infinity') is returned and the DivisionByZero condition is\n\ -raised. If the operand is an infinity then Decimal('Infinity') is returned.\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,"\n\ -logical_and(other, context=None) - Return the digit-wise and of the two\n\ -(logical) operands.\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,"\n\ -logical_invert(context=None) - Return the digit-wise inversion of the\n\ -(logical) operand.\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,"\n\ -logical_or(other, context=None) - Return the digit-wise or of the two\n\ -(logical) operands.\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,"\n\ -logical_xor(other, context=None) - Return the digit-wise exclusive or of the\n\ -two (logical) operands.\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,"\n\ -max(other, context=None) - Maximum of self and other. If one operand is a\n\ -quiet NaN and the other is numeric, the numeric operand is returned.\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,"\n\ -max_mag(other, context=None) - Similar to the max() method, but the\n\ -comparison is done using the absolute values of the operands.\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,"\n\ -min(other, context=None) - Minimum of self and other. If one operand is a\n\ -quiet NaN and the other is numeric, the numeric operand is returned.\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,"\n\ -min_mag(other, context=None) - Similar to the min() method, but the\n\ -comparison is done using the absolute values of the operands.\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,"\n\ -next_minus(context=None) - Return the largest number representable in the\n\ -given context (or in the current default context if no context is given) that\n\ -is smaller than the given operand.\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,"\n\ -next_plus(context=None) - Return the smallest number representable in the\n\ -given context (or in the current default context if no context is given) that\n\ -is larger than the given operand.\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,"\n\ -next_toward(other, context=None) - If the two operands are unequal, return\n\ -the number closest to the first operand in the direction of the second operand.\n\ -If both operands are numerically equal, return a copy of the first operand\n\ -with the sign set to be the same as the sign of the second operand.\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,"\n\ -normalize(context=None) - Normalize the number by stripping the rightmost\n\ -trailing zeros and converting any result equal to Decimal('0') to Decimal('0e0').\n\ -Used for producing canonical values for members of an equivalence class. For\n\ -example, Decimal('32.100') and Decimal('0.321000e+2') both normalize to the\n\ -equivalent value Decimal('32.1').\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,"\n\ -number_class(context=None) - Return a string describing the class of the\n\ -operand. The returned value is one of the following ten strings:\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\ @@ -331,9 +364,10 @@ operand. The returned value is one of the following ten strings:\n\ \n\ \n"); -PyDoc_STRVAR(doc_quantize,"\n\ -quantize(exp, rounding=None, context=None) - Return a value equal to the\n\ -first operand after rounding and having the exponent of the second operand.\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\ @@ -352,93 +386,98 @@ 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,"\n\ -radix() - Return Decimal(10), the radix (base) in which the Decimal class does\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,"\n\ -remainder_near(other, context=None) - Return the remainder from dividing\n\ -self by other. This differs from self % other in that the sign of the\n\ -remainder is chosen so as to minimize its absolute value. More precisely, the\n\ -return value is self - n * other where n is the integer nearest to the exact\n\ -value of self / other, and if two integers are equally near then the even one\n\ -is chosen.\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,"\n\ -rotate(other, context=None) - Return the result of rotating the digits of the\n\ -first operand by an amount specified by the second operand. The second operand\n\ -must be an integer in the range -precision through precision. The absolute\n\ -value of the second operand gives the number of places to rotate. If the second\n\ -operand is positive then rotation is to the left; otherwise rotation is to the\n\ -right. The coefficient of the first operand is padded on the left with zeros to\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,"\n\ -same_quantum(other, context=None) - Test whether self and other have the\n\ -same exponent or whether both are NaN.\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,"\n\ -scaleb(other, context=None) - Return the first operand with the exponent\n\ -adjusted the second. Equivalently, return the first operand multiplied by\n\ -10**other. The second operand must be an integer.\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,"\n\ -shift(other, context=None) - Return the result of shifting the digits of\n\ -the first operand by an amount specified by the second operand. The second\n\ -operand must be an integer in the range -precision through precision. The\n\ -absolute value of the second operand gives the number of places to shift.\n\ -If the second operand is positive, then the shift is to the left; otherwise\n\ -the shift is to the right. Digits shifted into the coefficient are zeros.\n\ -The sign and exponent of the first operand are unchanged.\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,"\n\ -sqrt(context=None) - Return the square root of the argument to full precision.\n\ -The result is correctly rounded using the ROUND_HALF_EVEN rounding mode.\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,"\n\ -to_eng_string(context=None) - Convert to an engineering-type string.\n\ -Engineering notation has an exponent which is a multiple of 3, so there\n\ -are up to 3 digits left of the decimal place. For example, Decimal('123E+1')\n\ -is converted to Decimal('1.23E+3').\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,"\n\ -to_integral(rounding=None, context=None) - Identical to the\n\ -to_integral_value() method. The to_integral() name has been kept\n\ -for compatibility with older versions.\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,"\n\ -to_integral_exact(rounding=None, context=None) - Round to the nearest\n\ -integer, signaling Inexact or Rounded as appropriate if rounding occurs.\n\ -The rounding mode is determined by the rounding parameter if given, else\n\ -by the given context. If neither parameter is given, then the rounding mode\n\ -of the current default context is used.\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,"\n\ -to_integral_value(rounding=None, context=None) - Round to the nearest\n\ -integer without signaling Inexact or Rounded. The rounding mode is determined\n\ -by the rounding parameter if given, else by the given context. If neither\n\ -parameter is given, then the rounding mode of the current default context is\n\ -used.\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"); @@ -446,9 +485,10 @@ used.\n\ /* Context Object and Methods */ /******************************************************************************/ -PyDoc_STRVAR(doc_context,"\n\ +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\ +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\ @@ -460,308 +500,372 @@ can be constructed as follows:\n\ \n"); #ifdef EXTRA_FUNCTIONALITY -PyDoc_STRVAR(doc_ctx_apply,"\n\ -apply(x) - Apply self to Decimal x.\n\ +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,"\n\ -clear_flags() - Reset all flags to False.\n\ +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,"\n\ -clear_traps() - Set all traps to False.\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,"\n\ -copy() - Return a duplicate of the context with all flags cleared.\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,"\n\ -copy_decimal(x) - Return a copy of Decimal x.\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,"\n\ -create_decimal(x) - Create a new Decimal instance from x, using self as the\n\ -context. Unlike the Decimal constructor, this function observes the context\n\ -limits.\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,"\n\ -create_decimal_from_float(f) - Create a new Decimal instance from float f.\n\ -Unlike the Decimal.from_float() class method, this function observes the\n\ -context limits.\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,"\n\ -Etiny() - Return a value equal to Emin - prec + 1, which is the minimum\n\ -exponent value for subnormal results. When underflow occurs, the exponent\n\ -is set to Etiny.\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,"\n\ -Etop() - 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() must\n\ -not be negative.\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,"\n\ -abs(x) - Return the absolute value of x.\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,"\n\ -add(x, y) - Return the sum of x and y.\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,"\n\ -canonical(x) - Return a new instance of x.\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,"\n\ -compare(x, y) - Compare x and y numerically.\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,"\n\ -compare_signal(x, y) - Compare x and y numerically. All NaNs signal.\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,"\n\ -compare_total(x, y) - Compare x and y using their abstract representation.\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,"\n\ -compare_total_mag(x, y) - Compare x and y using their abstract representation,\n\ -ignoring sign.\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,"\n\ -copy_abs(x) - Return a copy of x with the sign set to 0.\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,"\n\ -copy_negate(x) - Return a copy of x with the sign inverted.\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,"\n\ -copy_sign(x, y) - Copy the sign from y to x.\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,"\n\ -divide(x, y) - Return x divided by y.\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,"\n\ -divide_int(x, y) - Return x divided by y, truncated to an integer.\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,"\n\ -divmod(x, y) - Return quotient and remainder of the division x / y.\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,"\n\ -exp(x) - Return e ** x.\n\ +PyDoc_STRVAR(doc_ctx_exp, +"exp($self, x, /)\n--\n\n\ +Return e ** x.\n\ \n"); -PyDoc_STRVAR(doc_ctx_fma,"\n\ -fma(x, y, z) - Return x multiplied by y, plus z.\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,"\n\ -is_canonical(x) - Return True if x is canonical, False otherwise.\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,"\n\ -is_finite(x) - Return True if x is finite, False otherwise.\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,"\n\ -is_infinite(x) - Return True if x is infinite, False otherwise.\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,"\n\ -is_nan(x) - Return True if x is a qNaN or sNaN, False otherwise.\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,"\n\ -is_normal(x) - Return True if x is a normal number, False otherwise.\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,"\n\ -is_qnan(x) - Return True if x is a quiet NaN, False otherwise.\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,"\n\ -is_signed(x) - Return True if x is negative, False otherwise.\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,"\n\ -is_snan() - Return True if x is a signaling NaN, False otherwise.\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,"\n\ -is_subnormal(x) - Return True if x is subnormal, False otherwise.\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,"\n\ -is_zero(x) - Return True if x is a zero, False otherwise.\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,"\n\ -ln(x) - Return the natural (base e) logarithm of x.\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,"\n\ -log10(x) - Return the base 10 logarithm of x.\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,"\n\ -logb(x) - Return the exponent of the magnitude of the operand's MSD.\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,"\n\ -logical_and(x, y) - Digit-wise and of x and y.\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,"\n\ -logical_invert(x) - Invert all digits of x.\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,"\n\ -logical_or(x, y) - Digit-wise or of x and y.\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,"\n\ -logical_xor(x, y) - Digit-wise xor of x and y.\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,"\n\ -max(x, y) - Compare the values numerically and return the maximum.\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,"\n\ -max_mag(x, y) - Compare the values numerically with their sign ignored.\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,"\n\ -min(x, y) - Compare the values numerically and return the minimum.\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,"\n\ -min_mag(x, y) - Compare the values numerically with their sign ignored.\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,"\n\ -minus(x) - Minus corresponds to the unary prefix minus operator in Python,\n\ -but applies the context to the result.\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,"\n\ -multiply(x, y) - Return the product of x and y.\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,"\n\ -next_minus(x) - Return the largest representable number smaller than x.\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,"\n\ -next_plus(x) - Return the smallest representable number larger than x.\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,"\n\ -next_toward(x) - Return the number closest to x, in the direction towards y.\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,"\n\ -normalize(x) - Reduce x to its simplest form. Alias for reduce(x).\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,"\n\ -number_class(x) - Return an indication of the class of x.\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,"\n\ -plus(x) - Plus corresponds to the unary prefix plus operator in Python,\n\ -but applies the context to the result.\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,"\n\ -power(x, y) - Compute x**y. If x is negative, then y must be integral.\n\ -The result will be inexact unless y is integral and the result is finite\n\ -and can be expressed exactly in 'precision' digits. In the Python version\n\ -the result is always correctly rounded, in the C version the result is\n\ -almost always correctly rounded.\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\ -power(x, y, m) - Compute (x**y) % m. The following restrictions hold:\n\ +If modulo is given, compute (a**b) % modulo. The following restrictions\n\ +hold:\n\ \n\ * all three arguments must be integral\n\ - * y must be nonnegative\n\ - * at least one of x or y must be nonzero\n\ - * m must be nonzero and less than 10**prec in absolute value\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,"\n\ -quantize(x, y) - Return a value equal to x (rounded), having the exponent of y.\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,"\n\ -radix() - Return 10.\n\ +PyDoc_STRVAR(doc_ctx_radix, +"radix($self, /)\n--\n\n\ +Return 10.\n\ \n"); -PyDoc_STRVAR(doc_ctx_remainder,"\n\ -remainder(x, y) - Return the remainder from integer division. The sign of\n\ -the result, if non-zero, is the same as that of the original dividend.\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,"\n\ -remainder_near(x, y) - Return x - y * n, where n is the integer nearest the\n\ -exact value of x / y (if the result is 0 then its sign will be the sign of x).\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,"\n\ -rotate(x, y) - Return a copy of x, rotated by y places.\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,"\n\ -same_quantum(x, y) - Return True if the two operands have the same exponent.\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,"\n\ -scaleb(x, y) - Return the first operand after adding the second value\n\ -to its exp.\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,"\n\ -shift(x, y) - Return a copy of x, shifted by y places.\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,"\n\ -sqrt(x) - Square root of a non-negative number to context precision.\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,"\n\ -subtract(x, y) - Return the difference between x and y.\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,"\n\ -to_eng_string(x) - Convert a number to a string, using engineering notation.\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,"\n\ -to_integral(x) - Identical to to_integral_value(x).\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,"\n\ -to_integral_exact(x) - Round to an integer. Signal if the result is\n\ -rounded or inexact.\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,"\n\ -to_integral_value(x) - Round to an integer.\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,"\n\ -to_sci_string(x) - Convert a number to a string using scientific notation.\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"); diff --git a/Modules/_decimal/libmpdec/basearith.c b/Modules/_decimal/libmpdec/basearith.c index dd21a7a885fb..35de6b828491 100644 --- a/Modules/_decimal/libmpdec/basearith.c +++ b/Modules/_decimal/libmpdec/basearith.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/basearith.h b/Modules/_decimal/libmpdec/basearith.h index 114cef386036..976358a110ec 100644 --- a/Modules/_decimal/libmpdec/basearith.h +++ b/Modules/_decimal/libmpdec/basearith.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/bits.h b/Modules/_decimal/libmpdec/bits.h index 949ec944ca51..b5eaa24976ae 100644 --- a/Modules/_decimal/libmpdec/bits.h +++ b/Modules/_decimal/libmpdec/bits.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/constants.c b/Modules/_decimal/libmpdec/constants.c index 92f5891b56f3..2c2d5ea48103 100644 --- a/Modules/_decimal/libmpdec/constants.c +++ b/Modules/_decimal/libmpdec/constants.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/constants.h b/Modules/_decimal/libmpdec/constants.h index 13df9202123d..c0febfc8772d 100644 --- a/Modules/_decimal/libmpdec/constants.h +++ b/Modules/_decimal/libmpdec/constants.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/context.c b/Modules/_decimal/libmpdec/context.c index 159f88c339e6..24c7b890c1d9 100644 --- a/Modules/_decimal/libmpdec/context.c +++ b/Modules/_decimal/libmpdec/context.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/convolute.c b/Modules/_decimal/libmpdec/convolute.c index b5fe131b07ce..4c62e8bd3abd 100644 --- a/Modules/_decimal/libmpdec/convolute.c +++ b/Modules/_decimal/libmpdec/convolute.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/convolute.h b/Modules/_decimal/libmpdec/convolute.h index c35ed461d3b5..f30a177a6840 100644 --- a/Modules/_decimal/libmpdec/convolute.h +++ b/Modules/_decimal/libmpdec/convolute.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/crt.c b/Modules/_decimal/libmpdec/crt.c index c71c4ee8f80e..4a1e80a23228 100644 --- a/Modules/_decimal/libmpdec/crt.c +++ b/Modules/_decimal/libmpdec/crt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/crt.h b/Modules/_decimal/libmpdec/crt.h index 8909232231ab..f61e77293632 100644 --- a/Modules/_decimal/libmpdec/crt.h +++ b/Modules/_decimal/libmpdec/crt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/difradix2.c b/Modules/_decimal/libmpdec/difradix2.c index 4ebb0b54b0ab..06e5ab5e222e 100644 --- a/Modules/_decimal/libmpdec/difradix2.c +++ b/Modules/_decimal/libmpdec/difradix2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/difradix2.h b/Modules/_decimal/libmpdec/difradix2.h index 81aa598543fd..5e22bcf324fa 100644 --- a/Modules/_decimal/libmpdec/difradix2.h +++ b/Modules/_decimal/libmpdec/difradix2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/fnt.c b/Modules/_decimal/libmpdec/fnt.c index 93116539b9f1..7e924c85242b 100644 --- a/Modules/_decimal/libmpdec/fnt.c +++ b/Modules/_decimal/libmpdec/fnt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/fnt.h b/Modules/_decimal/libmpdec/fnt.h index 1f302cccbfa1..fa2154a798d4 100644 --- a/Modules/_decimal/libmpdec/fnt.h +++ b/Modules/_decimal/libmpdec/fnt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/fourstep.c b/Modules/_decimal/libmpdec/fourstep.c index aa32c0d5cf2e..21d3e7485df4 100644 --- a/Modules/_decimal/libmpdec/fourstep.c +++ b/Modules/_decimal/libmpdec/fourstep.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/fourstep.h b/Modules/_decimal/libmpdec/fourstep.h index 593f27d489f4..80dcd4be3d59 100644 --- a/Modules/_decimal/libmpdec/fourstep.h +++ b/Modules/_decimal/libmpdec/fourstep.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/io.c b/Modules/_decimal/libmpdec/io.c index 36470ca0062d..a45a429dbf1d 100644 --- a/Modules/_decimal/libmpdec/io.c +++ b/Modules/_decimal/libmpdec/io.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 @@ -446,7 +446,7 @@ _mpd_to_string(char **result, const mpd_t *dec, int flags, mpd_ssize_t dplace) if (mpd_isspecial(dec)) { - mem = sizeof "-Infinity"; + mem = sizeof "-Infinity%"; if (mpd_isnan(dec) && dec->len > 0) { /* diagnostic code */ mem += dec->digits; @@ -609,10 +609,10 @@ _mpd_to_string(char **result, const mpd_t *dec, int flags, mpd_ssize_t dplace) *cp++ = (flags&MPD_FMT_UPPER) ? 'E' : 'e'; cp = exp_to_string(cp, ldigits-dplace); } + } - if (flags&MPD_FMT_PERCENT) { - *cp++ = '%'; - } + if (flags&MPD_FMT_PERCENT) { + *cp++ = '%'; } assert(cp < decstring+mem); @@ -1260,6 +1260,9 @@ mpd_qformat_spec(const mpd_t *dec, const mpd_spec_t *spec, stackspec.align = '>'; spec = &stackspec; } + if (type == '%') { + flags |= MPD_FMT_PERCENT; + } } else { uint32_t workstatus = 0; diff --git a/Modules/_decimal/libmpdec/io.h b/Modules/_decimal/libmpdec/io.h index 3dfce732aa4b..de5486a00ca5 100644 --- a/Modules/_decimal/libmpdec/io.h +++ b/Modules/_decimal/libmpdec/io.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/literature/fnt.py b/Modules/_decimal/libmpdec/literature/fnt.py index bf937459f52d..6363536da648 100644 --- a/Modules/_decimal/libmpdec/literature/fnt.py +++ b/Modules/_decimal/libmpdec/literature/fnt.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2008-2012 Stefan Krah. All rights reserved. +# 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 diff --git a/Modules/_decimal/libmpdec/literature/mulmod-64.txt b/Modules/_decimal/libmpdec/literature/mulmod-64.txt index 93bf22e9fed2..029b8de3d7c9 100644 --- a/Modules/_decimal/libmpdec/literature/mulmod-64.txt +++ b/Modules/_decimal/libmpdec/literature/mulmod-64.txt @@ -59,7 +59,7 @@ The reduction step b) preserves congruence: Maximum numbers of step b): --------------------------- -# To avoid unneccessary formalism, define: +# To avoid unnecessary formalism, define: def R(hi, lo, z): return divmod(hi * z - hi + lo, 2**64) diff --git a/Modules/_decimal/libmpdec/literature/umodarith.lisp b/Modules/_decimal/libmpdec/literature/umodarith.lisp index 008e9f4507f4..99d71c373d1a 100644 --- a/Modules/_decimal/libmpdec/literature/umodarith.lisp +++ b/Modules/_decimal/libmpdec/literature/umodarith.lisp @@ -1,5 +1,5 @@ ; -; Copyright (c) 2008-2012 Stefan Krah. All rights reserved. +; 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 diff --git a/Modules/_decimal/libmpdec/memory.c b/Modules/_decimal/libmpdec/memory.c index bf6350f9049c..0f41fe506452 100644 --- a/Modules/_decimal/libmpdec/memory.c +++ b/Modules/_decimal/libmpdec/memory.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/memory.h b/Modules/_decimal/libmpdec/memory.h index 7e73c1305933..9c98d1a4000d 100644 --- a/Modules/_decimal/libmpdec/memory.h +++ b/Modules/_decimal/libmpdec/memory.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/mpdecimal.c b/Modules/_decimal/libmpdec/mpdecimal.c index 287a77ed302e..593f9f5e03a5 100644 --- a/Modules/_decimal/libmpdec/mpdecimal.c +++ b/Modules/_decimal/libmpdec/mpdecimal.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 @@ -43,6 +43,7 @@ #ifdef PPRO #if defined(_MSC_VER) #include + #pragma float_control(precise, on) #pragma fenv_access(on) #elif !defined(__OpenBSD__) && !defined(__NetBSD__) /* C99 */ @@ -392,42 +393,42 @@ mpd_radix(void) /* Dynamic decimal */ ALWAYS_INLINE int -mpd_isdynamic(mpd_t *dec) +mpd_isdynamic(const mpd_t *dec) { return !(dec->flags & MPD_STATIC); } /* Static decimal */ ALWAYS_INLINE int -mpd_isstatic(mpd_t *dec) +mpd_isstatic(const mpd_t *dec) { return dec->flags & MPD_STATIC; } /* Data of decimal is dynamic */ ALWAYS_INLINE int -mpd_isdynamic_data(mpd_t *dec) +mpd_isdynamic_data(const mpd_t *dec) { return !(dec->flags & MPD_DATAFLAGS); } /* Data of decimal is static */ ALWAYS_INLINE int -mpd_isstatic_data(mpd_t *dec) +mpd_isstatic_data(const mpd_t *dec) { return dec->flags & MPD_STATIC_DATA; } /* Data of decimal is shared */ ALWAYS_INLINE int -mpd_isshared_data(mpd_t *dec) +mpd_isshared_data(const mpd_t *dec) { return dec->flags & MPD_SHARED_DATA; } /* Data of decimal is const */ ALWAYS_INLINE int -mpd_isconst_data(mpd_t *dec) +mpd_isconst_data(const mpd_t *dec) { return dec->flags & MPD_CONST_DATA; } @@ -597,7 +598,7 @@ mpd_set_sign(mpd_t *result, uint8_t sign) /* Copy sign from another decimal */ ALWAYS_INLINE void -mpd_signcpy(mpd_t *result, mpd_t *a) +mpd_signcpy(mpd_t *result, const mpd_t *a) { uint8_t sign = a->flags&MPD_NEG; @@ -3202,9 +3203,9 @@ mpd_qabs(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, } static inline void -_mpd_ptrswap(mpd_t **a, mpd_t **b) +_mpd_ptrswap(const mpd_t **a, const mpd_t **b) { - mpd_t *t = *a; + const mpd_t *t = *a; *a = *b; *b = t; } @@ -3232,7 +3233,7 @@ 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) { - mpd_t *big, *small; + 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; @@ -3242,7 +3243,7 @@ _mpd_qaddsub(mpd_t *result, const mpd_t *a, const mpd_t *b, uint8_t sign_b, /* compare exponents */ - big = (mpd_t *)a; small = (mpd_t *)b; + big = a; small = b; if (big->exp != small->exp) { if (small->exp > big->exp) { _mpd_ptrswap(&big, &small); @@ -4421,21 +4422,22 @@ 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 = (mpd_t *)c; + 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, cc, ctx, &workstatus); + mpd_qadd(result, result, c, ctx, &workstatus); } - if (cc != c) mpd_del(cc); + if (cc) mpd_del(cc); *status |= workstatus; } @@ -5727,7 +5729,7 @@ static inline void _mpd_qmul(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status) { - mpd_t *big = (mpd_t *)a, *small = (mpd_t *)b; + const mpd_t *big = a, *small = b; mpd_uint_t *rdata = NULL; mpd_uint_t rbuf[MPD_MINALLOC_MAX]; mpd_size_t rsize, i; diff --git a/Modules/_decimal/libmpdec/mpdecimal.h b/Modules/_decimal/libmpdec/mpdecimal.h index 0f31733cb75e..5ca74135bf9b 100644 --- a/Modules/_decimal/libmpdec/mpdecimal.h +++ b/Modules/_decimal/libmpdec/mpdecimal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 @@ -32,6 +32,10 @@ #ifdef __cplusplus extern "C" { + #ifndef __STDC_LIMIT_MACROS + #define __STDC_LIMIT_MACROS + #define MPD_CLEAR_STDC_LIMIT_MACROS + #endif #endif @@ -55,18 +59,12 @@ extern "C" { #define MPD_HIDE_SYMBOLS_END #define EXTINLINE extern inline #else + #ifdef HAVE_STDINT_H + #include + #endif #ifdef HAVE_INTTYPES_H #include #endif - #ifdef HAVE_STDINT_H - #if defined(__cplusplus) && !defined(__STDC_LIMIT_MACROS) - #define __STDC_LIMIT_MACROS - #include - #undef __STDC_LIMIT_MACROS - #else - #include - #endif - #endif #ifndef __GNUC_STDC_INLINE__ #define __GNUC_STDC_INLINE__ 1 #endif @@ -110,9 +108,13 @@ MPD_PRAGMA(MPD_HIDE_SYMBOLS_START) #define MPD_MAJOR_VERSION 2 #define MPD_MINOR_VERSION 4 -#define MPD_MICRO_VERSION 0 +#define MPD_MICRO_VERSION 1 + +#define MPD_VERSION "2.4.1" -#define MPD_VERSION "2.4.0" +#define MPD_VERSION_HEX ((MPD_MAJOR_VERSION << 24) | \ + (MPD_MINOR_VERSION << 16) | \ + (MPD_MICRO_VERSION << 8)) const char *mpd_version(void); @@ -408,7 +410,7 @@ 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_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 @@ -467,7 +469,7 @@ int mpd_qcheck_nan(mpd_t *nanresult, const mpd_t *a, const mpd_context_t *ctx, u 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); +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); @@ -581,7 +583,7 @@ size_t mpd_qexport_u32(uint32_t **rdata, size_t rlen, uint32_t base, /* Signalling functions */ /******************************************************************************/ -char * mpd_format(const mpd_t *dec, const char *fmt, mpd_context_t *ctx); +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); @@ -752,12 +754,12 @@ 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(mpd_t *dec); -EXTINLINE int mpd_isstatic(mpd_t *dec); -EXTINLINE int mpd_isdynamic_data(mpd_t *dec); -EXTINLINE int mpd_isstatic_data(mpd_t *dec); -EXTINLINE int mpd_isshared_data(mpd_t *dec); -EXTINLINE int mpd_isconst_data(mpd_t *dec); +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); @@ -769,7 +771,7 @@ EXTINLINE mpd_ssize_t mpd_trail_zeros(const mpd_t *dec); 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, mpd_t *a); +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); @@ -835,6 +837,10 @@ 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 diff --git a/Modules/_decimal/libmpdec/numbertheory.c b/Modules/_decimal/libmpdec/numbertheory.c index 10ce6dc1464c..4e035477e280 100644 --- a/Modules/_decimal/libmpdec/numbertheory.c +++ b/Modules/_decimal/libmpdec/numbertheory.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/numbertheory.h b/Modules/_decimal/libmpdec/numbertheory.h index 109225461989..e94c157910c8 100644 --- a/Modules/_decimal/libmpdec/numbertheory.h +++ b/Modules/_decimal/libmpdec/numbertheory.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/sixstep.c b/Modules/_decimal/libmpdec/sixstep.c index 7d0542d641dc..92d513ebe182 100644 --- a/Modules/_decimal/libmpdec/sixstep.c +++ b/Modules/_decimal/libmpdec/sixstep.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/sixstep.h b/Modules/_decimal/libmpdec/sixstep.h index 0467007061b8..4a8b015e3a9b 100644 --- a/Modules/_decimal/libmpdec/sixstep.h +++ b/Modules/_decimal/libmpdec/sixstep.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/transpose.c b/Modules/_decimal/libmpdec/transpose.c index 5e5d4b6625e9..55d6d8992279 100644 --- a/Modules/_decimal/libmpdec/transpose.c +++ b/Modules/_decimal/libmpdec/transpose.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 @@ -169,7 +169,7 @@ squaretrans(mpd_uint_t *buf, mpd_size_t 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 tranposition is done on each individual block. + * then a square transposition is done on each individual block. */ static void squaretrans_pow2(mpd_uint_t *matrix, mpd_size_t size) diff --git a/Modules/_decimal/libmpdec/transpose.h b/Modules/_decimal/libmpdec/transpose.h index 7e349ee08df1..e1cd1fa17dd7 100644 --- a/Modules/_decimal/libmpdec/transpose.h +++ b/Modules/_decimal/libmpdec/transpose.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/typearith.h b/Modules/_decimal/libmpdec/typearith.h index 614812c69e27..405237dac516 100644 --- a/Modules/_decimal/libmpdec/typearith.h +++ b/Modules/_decimal/libmpdec/typearith.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/umodarith.h b/Modules/_decimal/libmpdec/umodarith.h index 436761bc4487..68d15188cb39 100644 --- a/Modules/_decimal/libmpdec/umodarith.h +++ b/Modules/_decimal/libmpdec/umodarith.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/vccompat.h b/Modules/_decimal/libmpdec/vccompat.h index 276e0372cb6a..f58e023c628b 100644 --- a/Modules/_decimal/libmpdec/vccompat.h +++ b/Modules/_decimal/libmpdec/vccompat.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. + * 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 diff --git a/Modules/_decimal/libmpdec/vcdiv64.asm b/Modules/_decimal/libmpdec/vcdiv64.asm index 31bba08b0cb0..6b6645673ab5 100644 --- a/Modules/_decimal/libmpdec/vcdiv64.asm +++ b/Modules/_decimal/libmpdec/vcdiv64.asm @@ -1,5 +1,5 @@ ; -; Copyright (c) 2008-2012 Stefan Krah. All rights reserved. +; 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 diff --git a/Modules/_decimal/tests/bench.py b/Modules/_decimal/tests/bench.py index 7e4a210cd5a8..56566cc33905 100644 --- a/Modules/_decimal/tests/bench.py +++ b/Modules/_decimal/tests/bench.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - # # Copyright (C) 2001-2012 Python Software Foundation. All Rights Reserved. # Modified and extended by Stefan Krah. diff --git a/Modules/_decimal/tests/deccheck.py b/Modules/_decimal/tests/deccheck.py index 7a6b4109c20d..ab7d5bdf4eff 100644 --- a/Modules/_decimal/tests/deccheck.py +++ b/Modules/_decimal/tests/deccheck.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - # # Copyright (c) 2008-2012 Stefan Krah. All rights reserved. # @@ -38,6 +36,7 @@ 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']) @@ -128,7 +127,7 @@ # Functions that require a restricted exponent range for reasonable runtimes. UnaryRestricted = [ - '__ceil__', '__floor__', '__int__', '__long__', '__trunc__', + '__ceil__', '__floor__', '__int__', '__trunc__', 'to_integral', 'to_integral_value' ] @@ -372,7 +371,7 @@ def harrison_ulp(self, dec): return abs(a - b) def standard_ulp(self, dec, prec): - return P._dec_from_triple(0, '1', dec._exp+len(dec._int)-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 @@ -403,10 +402,10 @@ def check_ulpdiff(self, exact, rounded): # Convert infinities to the largest representable number + 1. x = exact if exact.is_infinite(): - x = P._dec_from_triple(exact._sign, '10', context.p.Emax) + x = _dec_from_triple(exact._sign, '10', context.p.Emax) y = rounded if rounded.is_infinite(): - y = P._dec_from_triple(rounded._sign, '10', context.p.Emax) + y = _dec_from_triple(rounded._sign, '10', context.p.Emax) # err = (rounded - exact) / ulp(rounded) self.maxctx.prec = p * 2 diff --git a/Modules/_decimal/tests/randdec.py b/Modules/_decimal/tests/randdec.py index ca0f0d17753c..d667f79f2c92 100644 --- a/Modules/_decimal/tests/randdec.py +++ b/Modules/_decimal/tests/randdec.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - # # Copyright (c) 2008-2012 Stefan Krah. All rights reserved. # diff --git a/Modules/_decimal/tests/runall.bat b/Modules/_decimal/tests/runall.bat index 5bc872a63f83..568f92f6ddf3 100755 --- a/Modules/_decimal/tests/runall.bat +++ b/Modules/_decimal/tests/runall.bat @@ -1,111 +1,111 @@ -@ECHO OFF - -rem Test all machine configurations, pydebug, refleaks, release build. - -cd ..\..\..\ - - -echo. -echo # ====================================================================== -echo # Building Python -echo # ====================================================================== -echo. - -call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x64 -msbuild /noconsolelogger /target:clean PCbuild\pcbuild.sln /p:Configuration=Release /p:PlatformTarget=x64 -msbuild /noconsolelogger /target:clean PCbuild\pcbuild.sln /p:Configuration=Debug /p:PlatformTarget=x64 -msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Release /p:Platform=x64 -msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=x64 - -call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x86 -msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Release /p:Platform=Win32 -msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=Win32 -echo. -echo. - -echo. -echo # ====================================================================== -echo # test_decimal: platform=x64 -echo # ====================================================================== -echo. - -cd PCbuild\amd64 - -echo # ==================== refleak tests ======================= -echo. -python_d.exe -m test -uall -R 2:2 test_decimal -echo. -echo. - -echo # ==================== regular tests ======================= -echo. -python.exe -m test -uall test_decimal -echo. -echo. - -cd .. - -echo. -echo # ====================================================================== -echo # test_decimal: platform=x86 -echo # ====================================================================== -echo. - -echo # ==================== refleak tests ======================= -echo. -python_d.exe -m test -uall -R 2:2 test_decimal -echo. -echo. - -echo # ==================== regular tests ======================= -echo. -python.exe -m test -uall test_decimal -echo. -echo. - -cd amd64 - -echo. -echo # ====================================================================== -echo # deccheck: platform=x64 -echo # ====================================================================== -echo. - -echo # ==================== debug build ======================= -echo. -python_d.exe ..\..\Modules\_decimal\tests\deccheck.py -echo. -echo. - -echo # =================== release build ====================== -echo. -python.exe ..\..\Modules\_decimal\tests\deccheck.py -echo. -echo. - -cd .. - -echo. -echo # ====================================================================== -echo # deccheck: platform=x86 -echo # ====================================================================== -echo. -echo. - -echo # ==================== debug build ======================= -echo. -python_d.exe ..\Modules\_decimal\tests\deccheck.py -echo. -echo. - -echo # =================== release build ====================== -echo. -python.exe ..\Modules\_decimal\tests\deccheck.py -echo. -echo. - - -cd ..\Modules\_decimal\tests - - - +@ECHO OFF + +rem Test all machine configurations, pydebug, refleaks, release build. + +cd ..\..\..\ + + +echo. +echo # ====================================================================== +echo # Building Python +echo # ====================================================================== +echo. + +call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x64 +msbuild /noconsolelogger /target:clean PCbuild\pcbuild.sln /p:Configuration=Release /p:PlatformTarget=x64 +msbuild /noconsolelogger /target:clean PCbuild\pcbuild.sln /p:Configuration=Debug /p:PlatformTarget=x64 +msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Release /p:Platform=x64 +msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=x64 + +call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x86 +msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Release /p:Platform=Win32 +msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=Win32 +echo. +echo. + +echo. +echo # ====================================================================== +echo # test_decimal: platform=x64 +echo # ====================================================================== +echo. + +cd PCbuild\amd64 + +echo # ==================== refleak tests ======================= +echo. +python_d.exe -m test -uall -R 2:2 test_decimal +echo. +echo. + +echo # ==================== regular tests ======================= +echo. +python.exe -m test -uall test_decimal +echo. +echo. + +cd .. + +echo. +echo # ====================================================================== +echo # test_decimal: platform=x86 +echo # ====================================================================== +echo. + +echo # ==================== refleak tests ======================= +echo. +python_d.exe -m test -uall -R 2:2 test_decimal +echo. +echo. + +echo # ==================== regular tests ======================= +echo. +python.exe -m test -uall test_decimal +echo. +echo. + +cd amd64 + +echo. +echo # ====================================================================== +echo # deccheck: platform=x64 +echo # ====================================================================== +echo. + +echo # ==================== debug build ======================= +echo. +python_d.exe ..\..\Modules\_decimal\tests\deccheck.py +echo. +echo. + +echo # =================== release build ====================== +echo. +python.exe ..\..\Modules\_decimal\tests\deccheck.py +echo. +echo. + +cd .. + +echo. +echo # ====================================================================== +echo # deccheck: platform=x86 +echo # ====================================================================== +echo. +echo. + +echo # ==================== debug build ======================= +echo. +python_d.exe ..\Modules\_decimal\tests\deccheck.py +echo. +echo. + +echo # =================== release build ====================== +echo. +python.exe ..\Modules\_decimal\tests\deccheck.py +echo. +echo. + + +cd ..\Modules\_decimal\tests + + + diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index b3b69767086c..911b5ac5a9a9 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -11,6 +11,8 @@ *-------------------------------------------------------------------- */ +#define PY_SSIZE_T_CLEAN + #include "Python.h" #include "structmember.h" @@ -185,8 +187,8 @@ typedef struct { PyObject* attrib; /* child elements */ - int length; /* actual number of items */ - int allocated; /* allocated items */ + 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; @@ -251,7 +253,7 @@ LOCAL(void) dealloc_extra(ElementObject* self) { ElementObjectExtra *myextra; - int i; + Py_ssize_t i; if (!self->extra) return; @@ -368,6 +370,14 @@ get_attrib_from_keywords(PyObject *kwds) 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) { @@ -429,9 +439,9 @@ element_init(PyObject *self, PyObject *args, PyObject *kwds) } LOCAL(int) -element_resize(ElementObject* self, int extra) +element_resize(ElementObject* self, Py_ssize_t extra) { - int size; + Py_ssize_t size; PyObject* *children; /* make sure self->children can hold the given number of extra @@ -442,7 +452,7 @@ element_resize(ElementObject* self, int extra) return -1; } - size = self->extra->length + extra; + size = self->extra->length + extra; /* never overflows */ if (size > self->extra->allocated) { /* use Python 2.4's list growth strategy */ @@ -453,6 +463,8 @@ element_resize(ElementObject* self, int extra) * 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 @@ -613,7 +625,7 @@ element_gc_traverse(ElementObject *self, visitproc visit, void *arg) Py_VISIT(JOIN_OBJ(self->tail)); if (self->extra) { - int i; + Py_ssize_t i; Py_VISIT(self->extra->attrib); for (i = 0; i < self->extra->length; ++i) @@ -654,25 +666,33 @@ element_dealloc(ElementObject* self) /* -------------------------------------------------------------------- */ -static PyObject* -element_append(ElementObject* self, PyObject* args) -{ - PyObject* element; - if (!PyArg_ParseTuple(args, "O!:append", &Element_Type, &element)) - return NULL; +/*[clinic input] +_elementtree.Element.append + + subelement: object(subclass_of='&Element_Type') + / - if (element_add_subelement(self, element) < 0) +[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; } -static PyObject* -element_clearmethod(ElementObject* self, PyObject* args) -{ - if (!PyArg_ParseTuple(args, ":clear")) - return NULL; +/*[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]*/ +{ dealloc_extra(self); Py_INCREF(Py_None); @@ -686,15 +706,18 @@ element_clearmethod(ElementObject* self, PyObject* args) Py_RETURN_NONE; } -static PyObject* -element_copy(ElementObject* self, PyObject* args) +/*[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]*/ { - int i; + Py_ssize_t i; ElementObject* element; - if (!PyArg_ParseTuple(args, ":__copy__")) - return NULL; - element = (ElementObject*) create_new_element( self->tag, (self->extra) ? self->extra->attrib : Py_None); if (!element) @@ -725,10 +748,19 @@ element_copy(ElementObject* self, PyObject* args) return (PyObject*) element; } -static PyObject* -element_deepcopy(ElementObject* self, PyObject* args) +/*[clinic input] +_elementtree.Element.__deepcopy__ + + memo: object + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_Element___deepcopy__(ElementObject *self, PyObject *memo) +/*[clinic end generated code: output=d1f19851d17bf239 input=df24c2b602430b77]*/ { - int i; + Py_ssize_t i; ElementObject* element; PyObject* tag; PyObject* attrib; @@ -736,10 +768,6 @@ element_deepcopy(ElementObject* self, PyObject* args) PyObject* tail; PyObject* id; - PyObject* memo; - if (!PyArg_ParseTuple(args, "O:__deepcopy__", &memo)) - return NULL; - tag = deepcopy(self->tag, memo); if (!tag) return NULL; @@ -810,17 +838,22 @@ element_deepcopy(ElementObject* self, PyObject* args) return NULL; } -static PyObject* -element_sizeof(PyObject* myself, PyObject* args) +/*[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]*/ { - ElementObject *self = (ElementObject*)myself; Py_ssize_t result = sizeof(ElementObject); if (self->extra) { result += sizeof(ElementObjectExtra); if (self->extra->children != self->extra->_children) result += sizeof(PyObject*) * self->extra->allocated; } - return PyLong_FromSsize_t(result); + return result; } /* dict keys for getstate/setstate. */ @@ -836,10 +869,16 @@ element_sizeof(PyObject* myself, PyObject* args) * 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 * -element_getstate(ElementObject *self) +_elementtree_Element___getstate___impl(ElementObject *self) +/*[clinic end generated code: output=37279aeeb6bb5b04 input=f0d16d7ec2f7adc1]*/ { - int i, noattrib; + Py_ssize_t i, noattrib; PyObject *instancedict = NULL, *children; /* Build a list of children. */ @@ -952,6 +991,7 @@ element_setstate_from_attributes(ElementObject *self, /* __setstate__ for Element instance from the Python implementation. * 'state' should be the instance dict. */ + static PyObject * element_setstate_from_Python(ElementObject *self, PyObject *state) { @@ -977,8 +1017,17 @@ element_setstate_from_Python(ElementObject *self, PyObject *state) return retval; } +/*[clinic input] +_elementtree.Element.__setstate__ + + state: object + / + +[clinic start generated code]*/ + static PyObject * -element_setstate(ElementObject *self, PyObject *state) +_elementtree_Element___setstate__(ElementObject *self, PyObject *state) +/*[clinic end generated code: output=ea28bf3491b1f75e input=aaf80abea7c1e3b9]*/ { if (!PyDict_CheckExact(state)) { PyErr_Format(PyExc_TypeError, @@ -1032,41 +1081,49 @@ checkpath(PyObject* tag) return 1; /* unknown type; might be path expression */ } -static PyObject* -element_extend(ElementObject* self, PyObject* args) +/*[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, seqlen = 0; - - PyObject* seq_in; - if (!PyArg_ParseTuple(args, "O:extend", &seq_in)) - return NULL; + Py_ssize_t i; - seq = PySequence_Fast(seq_in, ""); + seq = PySequence_Fast(elements, ""); if (!seq) { PyErr_Format( PyExc_TypeError, - "expected sequence, not \"%.200s\"", Py_TYPE(seq_in)->tp_name + "expected sequence, not \"%.200s\"", Py_TYPE(elements)->tp_name ); return NULL; } - seqlen = PySequence_Size(seq); - for (i = 0; i < seqlen; i++) { + for (i = 0; i < PySequence_Fast_GET_SIZE(seq); i++) { PyObject* element = PySequence_Fast_GET_ITEM(seq, i); - if (!PyObject_IsInstance(element, (PyObject *)&Element_Type)) { - Py_DECREF(seq); + Py_INCREF(element); + if (!PyObject_TypeCheck(element, (PyTypeObject *)&Element_Type)) { PyErr_Format( PyExc_TypeError, "expected an Element, not \"%.200s\"", Py_TYPE(element)->tp_name); + Py_DECREF(seq); + Py_DECREF(element); return NULL; } if (element_add_subelement(self, element) < 0) { Py_DECREF(seq); + Py_DECREF(element); return NULL; } + Py_DECREF(element); } Py_DECREF(seq); @@ -1074,23 +1131,26 @@ element_extend(ElementObject* self, PyObject* args) Py_RETURN_NONE; } -static PyObject* -element_find(ElementObject *self, PyObject *args, PyObject *kwds) +/*[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]*/ { - int i; - PyObject* tag; - PyObject* namespaces = Py_None; - static char *kwlist[] = {"path", "namespaces", 0}; + Py_ssize_t i; elementtreestate *st = ET_STATE_GLOBAL; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:find", kwlist, - &tag, &namespaces)) - return NULL; - - if (checkpath(tag) || namespaces != Py_None) { + if (checkpath(path) || namespaces != Py_None) { _Py_IDENTIFIER(find); return _PyObject_CallMethodId( - st->elementpath_obj, &PyId_find, "OOO", self, tag, namespaces + st->elementpath_obj, &PyId_find, "OOO", self, path, namespaces ); } @@ -1099,34 +1159,43 @@ element_find(ElementObject *self, PyObject *args, PyObject *kwds) for (i = 0; i < self->extra->length; i++) { PyObject* item = self->extra->children[i]; - if (Element_CheckExact(item) && - PyObject_RichCompareBool(((ElementObject*)item)->tag, tag, Py_EQ) == 1) { - Py_INCREF(item); + int rc; + if (!Element_CheckExact(item)) + continue; + 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; } -static PyObject* -element_findtext(ElementObject *self, PyObject *args, PyObject *kwds) +/*[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]*/ { - int i; - PyObject* tag; - PyObject* default_value = Py_None; - PyObject* namespaces = Py_None; + Py_ssize_t i; _Py_IDENTIFIER(findtext); - static char *kwlist[] = {"path", "default", "namespaces", 0}; elementtreestate *st = ET_STATE_GLOBAL; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OO:findtext", kwlist, - &tag, &default_value, &namespaces)) - return NULL; - - if (checkpath(tag) || namespaces != Py_None) + if (checkpath(path) || namespaces != Py_None) return _PyObject_CallMethodId( - st->elementpath_obj, &PyId_findtext, "OOOO", self, tag, default_value, namespaces + st->elementpath_obj, &PyId_findtext, "OOOO", self, path, default_value, namespaces ); if (!self->extra) { @@ -1136,34 +1205,48 @@ element_findtext(ElementObject *self, PyObject *args, PyObject *kwds) for (i = 0; i < self->extra->length; i++) { ElementObject* item = (ElementObject*) self->extra->children[i]; - if (Element_CheckExact(item) && - (PyObject_RichCompareBool(item->tag, tag, Py_EQ) == 1)) { + int rc; + if (!Element_CheckExact(item)) + continue; + Py_INCREF(item); + rc = PyObject_RichCompareBool(item->tag, path, Py_EQ); + if (rc > 0) { PyObject* text = element_get_text(item); - if (text == Py_None) + 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; } -static PyObject* -element_findall(ElementObject *self, PyObject *args, PyObject *kwds) +/*[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]*/ { - int i; + Py_ssize_t i; PyObject* out; - PyObject* tag; - PyObject* namespaces = Py_None; - static char *kwlist[] = {"path", "namespaces", 0}; + PyObject* tag = path; elementtreestate *st = ET_STATE_GLOBAL; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:findall", kwlist, - &tag, &namespaces)) - return NULL; - if (checkpath(tag) || namespaces != Py_None) { _Py_IDENTIFIER(findall); return _PyObject_CallMethodId( @@ -1180,48 +1263,57 @@ element_findall(ElementObject *self, PyObject *args, PyObject *kwds) for (i = 0; i < self->extra->length; i++) { PyObject* item = self->extra->children[i]; - if (Element_CheckExact(item) && - PyObject_RichCompareBool(((ElementObject*)item)->tag, tag, Py_EQ) == 1) { - if (PyList_Append(out, item) < 0) { - Py_DECREF(out); - return NULL; - } + int rc; + if (!Element_CheckExact(item)) + continue; + Py_INCREF(item); + rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, tag, 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; } -static PyObject* -element_iterfind(ElementObject *self, PyObject *args, PyObject *kwds) +/*[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; - PyObject* namespaces = Py_None; + PyObject* tag = path; _Py_IDENTIFIER(iterfind); - static char *kwlist[] = {"path", "namespaces", 0}; elementtreestate *st = ET_STATE_GLOBAL; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:iterfind", kwlist, - &tag, &namespaces)) { - return NULL; - } - return _PyObject_CallMethodId( st->elementpath_obj, &PyId_iterfind, "OOO", self, tag, namespaces); } -static PyObject* -element_get(ElementObject* self, PyObject* args, PyObject* kwds) -{ - PyObject* value; - static char* kwlist[] = {"key", "default", 0}; +/*[clinic input] +_elementtree.Element.get - PyObject* key; - PyObject* default_value = Py_None; + key: object + default: object = None - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:get", kwlist, &key, - &default_value)) - return NULL; +[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; @@ -1235,17 +1327,20 @@ element_get(ElementObject* self, PyObject* args, PyObject* kwds) return value; } -static PyObject* -element_getchildren(ElementObject* self, PyObject* args) +/*[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]*/ { - int i; + Py_ssize_t i; PyObject* list; /* FIXME: report as deprecated? */ - if (!PyArg_ParseTuple(args, ":getchildren")) - return NULL; - if (!self->extra) return PyList_New(0); @@ -1267,25 +1362,30 @@ static PyObject * create_elementiter(ElementObject *self, PyObject *tag, int gettext); -static PyObject * -element_iter(ElementObject *self, PyObject *args, PyObject *kwds) -{ - PyObject* tag = Py_None; - static char* kwlist[] = {"tag", 0}; +/*[clinic input] +_elementtree.Element.iter - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:iter", kwlist, &tag)) - return NULL; + 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]*/ +{ return create_elementiter(self, tag, 0); } -static PyObject* -element_itertext(ElementObject* self, PyObject* args) -{ - if (!PyArg_ParseTuple(args, ":itertext")) - return NULL; +/*[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); } @@ -1307,16 +1407,21 @@ element_getitem(PyObject* self_, Py_ssize_t index) return self->extra->children[index]; } -static PyObject* -element_insert(ElementObject* self, PyObject* args) -{ - int i; +/*[clinic input] +_elementtree.Element.insert - int index; - PyObject* element; - if (!PyArg_ParseTuple(args, "iO!:insert", &index, - &Element_Type, &element)) - return NULL; + 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) @@ -1337,32 +1442,38 @@ element_insert(ElementObject* self, PyObject* args) for (i = self->extra->length; i > index; i--) self->extra->children[i] = self->extra->children[i-1]; - Py_INCREF(element); - self->extra->children[index] = element; + Py_INCREF(subelement); + self->extra->children[index] = subelement; self->extra->length++; Py_RETURN_NONE; } -static PyObject* -element_items(ElementObject* self, PyObject* args) -{ - if (!PyArg_ParseTuple(args, ":items")) - return NULL; +/*[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); } -static PyObject* -element_keys(ElementObject* self, PyObject* args) -{ - if (!PyArg_ParseTuple(args, ":keys")) - return NULL; +/*[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); @@ -1378,16 +1489,22 @@ element_length(ElementObject* self) return self->extra->length; } -static PyObject* -element_makeelement(PyObject* self, PyObject* args, PyObject* kw) +/*[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; - PyObject* tag; - PyObject* attrib; - if (!PyArg_ParseTuple(args, "OO:makeelement", &tag, &attrib)) - return NULL; - attrib = PyDict_Copy(attrib); if (!attrib) return NULL; @@ -1399,14 +1516,21 @@ element_makeelement(PyObject* self, PyObject* args, PyObject* kw) return elem; } -static PyObject* -element_remove(ElementObject* self, PyObject* args) -{ - int i; +/*[clinic input] +_elementtree.Element.remove - PyObject* element; - if (!PyArg_ParseTuple(args, "O!:remove", &Element_Type, &element)) - return NULL; + 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 */ @@ -1418,14 +1542,17 @@ element_remove(ElementObject* self, PyObject* args) } for (i = 0; i < self->extra->length; i++) { - if (self->extra->children[i] == element) + if (self->extra->children[i] == subelement) break; - if (PyObject_RichCompareBool(self->extra->children[i], element, Py_EQ) == 1) + rc = PyObject_RichCompareBool(self->extra->children[i], subelement, Py_EQ); + if (rc > 0) break; + if (rc < 0) + return NULL; } - if (i == self->extra->length) { - /* element is not in children, so raise exception */ + if (i >= self->extra->length) { + /* subelement is not in children, so raise exception */ PyErr_SetString( PyExc_ValueError, "list.remove(x): x not in list" @@ -1433,13 +1560,13 @@ element_remove(ElementObject* self, PyObject* args) return NULL; } - Py_DECREF(self->extra->children[i]); + 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; } @@ -1452,16 +1579,22 @@ element_repr(ElementObject* self) return PyUnicode_FromFormat("", self); } -static PyObject* -element_set(ElementObject* self, PyObject* args) +/*[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; - PyObject* key; - PyObject* value; - if (!PyArg_ParseTuple(args, "OO:set", &key, &value)) - return NULL; - if (!self->extra) { if (create_extra(self, NULL) < 0) return NULL; @@ -1481,7 +1614,7 @@ static int element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item) { ElementObject* self = (ElementObject*) self_; - int i; + Py_ssize_t i; PyObject* old; if (!self->extra || index < 0 || index >= self->extra->length) { @@ -1742,43 +1875,6 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value) } } -static PyMethodDef element_methods[] = { - - {"clear", (PyCFunction) element_clearmethod, METH_VARARGS}, - - {"get", (PyCFunction) element_get, METH_VARARGS | METH_KEYWORDS}, - {"set", (PyCFunction) element_set, METH_VARARGS}, - - {"find", (PyCFunction) element_find, METH_VARARGS | METH_KEYWORDS}, - {"findtext", (PyCFunction) element_findtext, METH_VARARGS | METH_KEYWORDS}, - {"findall", (PyCFunction) element_findall, METH_VARARGS | METH_KEYWORDS}, - - {"append", (PyCFunction) element_append, METH_VARARGS}, - {"extend", (PyCFunction) element_extend, METH_VARARGS}, - {"insert", (PyCFunction) element_insert, METH_VARARGS}, - {"remove", (PyCFunction) element_remove, METH_VARARGS}, - - {"iter", (PyCFunction) element_iter, METH_VARARGS | METH_KEYWORDS}, - {"itertext", (PyCFunction) element_itertext, METH_VARARGS}, - {"iterfind", (PyCFunction) element_iterfind, METH_VARARGS | METH_KEYWORDS}, - - {"getiterator", (PyCFunction) element_iter, METH_VARARGS | METH_KEYWORDS}, - {"getchildren", (PyCFunction) element_getchildren, METH_VARARGS}, - - {"items", (PyCFunction) element_items, METH_VARARGS}, - {"keys", (PyCFunction) element_keys, METH_VARARGS}, - - {"makeelement", (PyCFunction) element_makeelement, METH_VARARGS}, - - {"__copy__", (PyCFunction) element_copy, METH_VARARGS}, - {"__deepcopy__", (PyCFunction) element_deepcopy, METH_VARARGS}, - {"__sizeof__", element_sizeof, METH_NOARGS}, - {"__getstate__", (PyCFunction)element_getstate, METH_NOARGS}, - {"__setstate__", (PyCFunction)element_setstate, METH_O}, - - {NULL, NULL} -}; - static PyObject* element_getattro(ElementObject* self, PyObject* nameobj) { @@ -1875,54 +1971,6 @@ static PySequenceMethods element_as_sequence = { 0, }; -static PyMappingMethods element_as_mapping = { - (lenfunc) element_length, - (binaryfunc) element_subscr, - (objobjargproc) element_ass_subscr, -}; - -static PyTypeObject Element_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "xml.etree.ElementTree.Element", sizeof(ElementObject), 0, - /* methods */ - (destructor)element_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (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 */ - (getattrofunc)element_getattro, /* tp_getattro */ - (setattrofunc)element_setattro, /* 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 */ - 0, /* 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 */ -}; - /******************************* Element iterator ****************************/ /* ElementIterObject represents the iteration state over an XML element in @@ -2012,6 +2060,7 @@ elementiter_next(ElementIterObject *it) */ ElementObject *cur_parent; Py_ssize_t child_index; + int rc; while (1) { /* Handle the case reached in the beginning and end of iteration, where @@ -2033,14 +2082,22 @@ elementiter_next(ElementIterObject *it) } it->root_done = 1; - if (it->sought_tag == Py_None || - PyObject_RichCompareBool(it->root_element->tag, - it->sought_tag, Py_EQ) == 1) { + rc = (it->sought_tag == Py_None); + if (!rc) { + rc = PyObject_RichCompareBool(it->root_element->tag, + it->sought_tag, Py_EQ); + if (rc < 0) + return NULL; + } + if (rc) { if (it->gettext) { PyObject *text = element_get_text(it->root_element); if (!text) return NULL; - if (PyObject_IsTrue(text)) { + rc = PyObject_IsTrue(text); + if (rc < 0) + return NULL; + if (rc) { Py_INCREF(text); return text; } @@ -2072,18 +2129,26 @@ elementiter_next(ElementIterObject *it) PyObject *text = element_get_text(child); if (!text) return NULL; - if (PyObject_IsTrue(text)) { + rc = PyObject_IsTrue(text); + if (rc < 0) + return NULL; + if (rc) { Py_INCREF(text); return text; } - } else if (it->sought_tag == Py_None || - PyObject_RichCompareBool(child->tag, - it->sought_tag, Py_EQ) == 1) { - Py_INCREF(child); - return (PyObject *)child; + } else { + rc = (it->sought_tag == Py_None); + if (!rc) { + rc = PyObject_RichCompareBool(child->tag, + it->sought_tag, Py_EQ); + if (rc < 0) + return NULL; + } + if (rc) { + Py_INCREF(child); + return (PyObject *)child; + } } - else - continue; } else { PyObject *tail; @@ -2103,9 +2168,14 @@ elementiter_next(ElementIterObject *it) * this is because itertext() is supposed to only return *inner* * text, not text following the element it began iteration with. */ - if (it->parent_stack->parent && PyObject_IsTrue(tail)) { - Py_INCREF(tail); - return tail; + if (it->parent_stack->parent) { + rc = PyObject_IsTrue(tail); + if (rc < 0) + return NULL; + if (rc) { + Py_INCREF(tail); + return tail; + } } } } @@ -2163,20 +2233,21 @@ static PyObject * create_elementiter(ElementObject *self, PyObject *tag, int gettext) { ElementIterObject *it; - PyObject *star = NULL; it = PyObject_GC_New(ElementIterObject, &ElementIter_Type); if (!it) return NULL; - if (PyUnicode_Check(tag)) - star = PyUnicode_FromString("*"); - else if (PyBytes_Check(tag)) - star = PyBytes_FromString("*"); - - if (star && PyObject_RichCompareBool(tag, star, Py_EQ) == 1) - tag = Py_None; - Py_XDECREF(star); + 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; + } Py_INCREF(tag); it->sought_tag = tag; @@ -2262,23 +2333,24 @@ treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return (PyObject *)t; } +/*[clinic input] +_elementtree.TreeBuilder.__init__ + + element_factory: object = NULL + +[clinic start generated code]*/ + static int -treebuilder_init(PyObject *self, PyObject *args, PyObject *kwds) +_elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, + PyObject *element_factory) +/*[clinic end generated code: output=91cfa7558970ee96 input=1b424eeefc35249c]*/ { - static char *kwlist[] = {"element_factory", 0}; - PyObject *element_factory = NULL; - TreeBuilderObject *self_tb = (TreeBuilderObject *)self; PyObject *tmp; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:TreeBuilder", kwlist, - &element_factory)) { - return -1; - } - if (element_factory) { Py_INCREF(element_factory); - tmp = self_tb->element_factory; - self_tb->element_factory = element_factory; + tmp = self->element_factory; + self->element_factory = element_factory; Py_XDECREF(tmp); } @@ -2598,23 +2670,33 @@ treebuilder_handle_namespace(TreeBuilderObject* self, int start, /* -------------------------------------------------------------------- */ /* methods (in alphabetical order) */ -static PyObject* -treebuilder_data(TreeBuilderObject* self, PyObject* args) -{ - PyObject* data; - if (!PyArg_ParseTuple(args, "O:data", &data)) - return NULL; +/*[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); } -static PyObject* -treebuilder_end(TreeBuilderObject* self, PyObject* args) -{ - PyObject* tag; - if (!PyArg_ParseTuple(args, "O:end", &tag)) - return NULL; +/*[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); } @@ -2634,75 +2716,34 @@ treebuilder_done(TreeBuilderObject* self) return res; } -static PyObject* -treebuilder_close(TreeBuilderObject* self, PyObject* args) -{ - if (!PyArg_ParseTuple(args, ":close")) - return NULL; +/*[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); } -static PyObject* -treebuilder_start(TreeBuilderObject* self, PyObject* args) -{ - PyObject* tag; - PyObject* attrib = Py_None; - if (!PyArg_ParseTuple(args, "O|O:start", &tag, &attrib)) - return NULL; +/*[clinic input] +_elementtree.TreeBuilder.start - return treebuilder_handle_start(self, tag, attrib); -} + tag: object + attrs: object = None + / -static PyMethodDef treebuilder_methods[] = { - {"data", (PyCFunction) treebuilder_data, METH_VARARGS}, - {"start", (PyCFunction) treebuilder_start, METH_VARARGS}, - {"end", (PyCFunction) treebuilder_end, METH_VARARGS}, - {"close", (PyCFunction) treebuilder_close, METH_VARARGS}, - {NULL, NULL} -}; +[clinic start generated code]*/ -static PyTypeObject TreeBuilder_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "xml.etree.ElementTree.TreeBuilder", sizeof(TreeBuilderObject), 0, - /* methods */ - (destructor)treebuilder_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - 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 */ - (initproc)treebuilder_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - treebuilder_new, /* tp_new */ - 0, /* tp_free */ -}; +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 */ @@ -2741,7 +2782,11 @@ typedef struct { } XMLParserObject; -#define XMLParser_CheckExact(op) (Py_TYPE(op) == &XMLParser_Type) +static PyObject* +_elementtree_XMLParser_doctype(XMLParserObject* self, PyObject* args); +static PyObject * +_elementtree_XMLParser_doctype_impl(XMLParserObject *self, PyObject *name, + PyObject *pubid, PyObject *system); /* helpers */ @@ -2819,12 +2864,13 @@ makeuniversal(XMLParserObject* self, const char* string) * message string is the default for the given error_code. */ static void -expat_set_error(enum XML_Error error_code, int line, int column, char *message) +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 %d, column %d", + errmsg = PyUnicode_FromFormat("%s: line %zd, column %zd", message ? message : EXPAT(ErrorString)(error_code), line, column); if (errmsg == NULL) @@ -2848,7 +2894,7 @@ expat_set_error(enum XML_Error error_code, int line, int column, char *message) } Py_DECREF(code); - position = Py_BuildValue("(ii)", line, column); + position = Py_BuildValue("(nn)", line, column); if (!position) { Py_DECREF(error); return; @@ -3140,20 +3186,22 @@ expat_start_doctype_handler(XMLParserObject *self, doctype_name_obj, pubid_obj, sysid_obj); Py_CLEAR(res); } - - /* Now see if the parser itself has a doctype method. If yes and it's - * a subclass, call it but warn about deprecation. If it's not a subclass - * (i.e. vanilla XMLParser), do nothing. - */ - parser_doctype = PyObject_GetAttrString(self_pyobj, "doctype"); - if (parser_doctype) { - if (!XMLParser_CheckExact(self_pyobj)) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "This method of XMLParser is deprecated. Define" - " doctype() method on the TreeBuilder target.", - 1) < 0) { + else { + /* Now see if the parser itself has a doctype method. If yes and it's + * a custom method, call it but warn about deprecation. If it's only + * the vanilla XMLParser method, do nothing. + */ + parser_doctype = PyObject_GetAttrString(self_pyobj, "doctype"); + if (parser_doctype && + !(PyCFunction_Check(parser_doctype) && + PyCFunction_GET_SELF(parser_doctype) == self_pyobj && + PyCFunction_GET_FUNCTION(parser_doctype) == + (PyCFunction) _elementtree_XMLParser_doctype)) { + res = _elementtree_XMLParser_doctype_impl(self, doctype_name_obj, + pubid_obj, sysid_obj); + if (!res) goto clear; - } + Py_DECREF(res); res = PyObject_CallFunction(parser_doctype, "OOO", doctype_name_obj, pubid_obj, sysid_obj); Py_CLEAR(res); @@ -3209,33 +3257,34 @@ xmlparser_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return (PyObject *)self; } -static int -xmlparser_init(PyObject *self, PyObject *args, PyObject *kwds) -{ - XMLParserObject *self_xp = (XMLParserObject *)self; - PyObject *target = NULL, *html = NULL; - char *encoding = NULL; - static char *kwlist[] = {"html", "target", "encoding", 0}; +/*[clinic input] +_elementtree.XMLParser.__init__ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOz:XMLParser", kwlist, - &html, &target, &encoding)) { - return -1; - } + html: object = NULL + target: object = NULL + encoding: str(accept={str, NoneType}) = NULL + +[clinic start generated code]*/ - self_xp->entity = PyDict_New(); - if (!self_xp->entity) +static int +_elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *html, + PyObject *target, const char *encoding) +/*[clinic end generated code: output=d6a16c63dda54441 input=155bc5695baafffd]*/ +{ + self->entity = PyDict_New(); + if (!self->entity) return -1; - self_xp->names = PyDict_New(); - if (!self_xp->names) { - Py_CLEAR(self_xp->entity); + self->names = PyDict_New(); + if (!self->names) { + Py_CLEAR(self->entity); return -1; } - self_xp->parser = EXPAT(ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}"); - if (!self_xp->parser) { - Py_CLEAR(self_xp->entity); - Py_CLEAR(self_xp->names); + self->parser = EXPAT(ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}"); + if (!self->parser) { + Py_CLEAR(self->entity); + Py_CLEAR(self->names); PyErr_NoMemory(); return -1; } @@ -3245,55 +3294,55 @@ xmlparser_init(PyObject *self, PyObject *args, PyObject *kwds) } else { target = treebuilder_new(&TreeBuilder_Type, NULL, NULL); if (!target) { - Py_CLEAR(self_xp->entity); - Py_CLEAR(self_xp->names); - EXPAT(ParserFree)(self_xp->parser); + Py_CLEAR(self->entity); + Py_CLEAR(self->names); + EXPAT(ParserFree)(self->parser); return -1; } } - self_xp->target = target; + self->target = target; - self_xp->handle_start = PyObject_GetAttrString(target, "start"); - self_xp->handle_data = PyObject_GetAttrString(target, "data"); - self_xp->handle_end = PyObject_GetAttrString(target, "end"); - self_xp->handle_comment = PyObject_GetAttrString(target, "comment"); - self_xp->handle_pi = PyObject_GetAttrString(target, "pi"); - self_xp->handle_close = PyObject_GetAttrString(target, "close"); - self_xp->handle_doctype = PyObject_GetAttrString(target, "doctype"); + self->handle_start = PyObject_GetAttrString(target, "start"); + self->handle_data = PyObject_GetAttrString(target, "data"); + self->handle_end = PyObject_GetAttrString(target, "end"); + self->handle_comment = PyObject_GetAttrString(target, "comment"); + self->handle_pi = PyObject_GetAttrString(target, "pi"); + self->handle_close = PyObject_GetAttrString(target, "close"); + self->handle_doctype = PyObject_GetAttrString(target, "doctype"); PyErr_Clear(); /* configure parser */ - EXPAT(SetUserData)(self_xp->parser, self_xp); + EXPAT(SetUserData)(self->parser, self); EXPAT(SetElementHandler)( - self_xp->parser, + self->parser, (XML_StartElementHandler) expat_start_handler, (XML_EndElementHandler) expat_end_handler ); EXPAT(SetDefaultHandlerExpand)( - self_xp->parser, + self->parser, (XML_DefaultHandler) expat_default_handler ); EXPAT(SetCharacterDataHandler)( - self_xp->parser, + self->parser, (XML_CharacterDataHandler) expat_data_handler ); - if (self_xp->handle_comment) + if (self->handle_comment) EXPAT(SetCommentHandler)( - self_xp->parser, + self->parser, (XML_CommentHandler) expat_comment_handler ); - if (self_xp->handle_pi) + if (self->handle_pi) EXPAT(SetProcessingInstructionHandler)( - self_xp->parser, + self->parser, (XML_ProcessingInstructionHandler) expat_pi_handler ); EXPAT(SetStartDoctypeDeclHandler)( - self_xp->parser, + self->parser, (XML_StartDoctypeDeclHandler) expat_start_doctype_handler ); EXPAT(SetUnknownEncodingHandler)( - self_xp->parser, + self->parser, EXPAT(DefaultUnknownEncodingHandler), NULL ); @@ -3369,15 +3418,18 @@ expat_parse(XMLParserObject* self, const char* data, int data_len, int final) Py_RETURN_NONE; } -static PyObject* -xmlparser_close(XMLParserObject* self, PyObject* args) +/*[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 (!PyArg_ParseTuple(args, ":close")) - return NULL; - res = expat_parse(self, "", 0, 1); if (!res) return NULL; @@ -3395,15 +3447,24 @@ xmlparser_close(XMLParserObject* self, PyObject* args) } } -static PyObject* -xmlparser_feed(XMLParserObject* self, PyObject* arg) +/*[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 (PyUnicode_Check(arg)) { + if (PyUnicode_Check(data)) { Py_ssize_t data_len; - const char *data = PyUnicode_AsUTF8AndSize(arg, &data_len); - if (data == NULL) + 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"); @@ -3411,12 +3472,12 @@ xmlparser_feed(XMLParserObject* self, PyObject* arg) } /* Explicitly set UTF-8 encoding. Return code ignored. */ (void)EXPAT(SetEncoding)(self->parser, "utf-8"); - return expat_parse(self, data, (int)data_len, 0); + return expat_parse(self, data_ptr, (int)data_len, 0); } else { Py_buffer view; PyObject *res; - if (PyObject_GetBuffer(arg, &view, PyBUF_SIMPLE) < 0) + if (PyObject_GetBuffer(data, &view, PyBUF_SIMPLE) < 0) return NULL; if (view.len > INT_MAX) { PyBuffer_Release(&view); @@ -3429,8 +3490,17 @@ xmlparser_feed(XMLParserObject* self, PyObject* arg) } } -static PyObject* -xmlparser_parse_whole(XMLParserObject* self, PyObject* args) +/*[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; @@ -3438,11 +3508,7 @@ xmlparser_parse_whole(XMLParserObject* self, PyObject* args) PyObject* temp; PyObject* res; - PyObject* fileobj; - if (!PyArg_ParseTuple(args, "O:_parse", &fileobj)) - return NULL; - - reader = PyObject_GetAttrString(fileobj, "read"); + reader = PyObject_GetAttrString(file, "read"); if (!reader) return NULL; @@ -3477,8 +3543,14 @@ xmlparser_parse_whole(XMLParserObject* self, PyObject* args) 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), PyBytes_GET_SIZE(buffer), 0 + self, PyBytes_AS_STRING(buffer), (int)PyBytes_GET_SIZE(buffer), 0 ); Py_DECREF(buffer); @@ -3503,25 +3575,49 @@ xmlparser_parse_whole(XMLParserObject* self, PyObject* args) return res; } -static PyObject* -xmlparser_doctype(XMLParserObject *self, PyObject *args) +/*[clinic input] +_elementtree.XMLParser.doctype + + name: object + pubid: object + system: object + / + +[clinic start generated code]*/ + +static PyObject * +_elementtree_XMLParser_doctype_impl(XMLParserObject *self, PyObject *name, + PyObject *pubid, PyObject *system) +/*[clinic end generated code: output=10fb50c2afded88d input=84050276cca045e1]*/ { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "This method of XMLParser is deprecated. Define" + " doctype() method on the TreeBuilder target.", + 1) < 0) { + return NULL; + } Py_RETURN_NONE; } -static PyObject* -xmlparser_setevents(XMLParserObject *self, PyObject* args) +/*[clinic input] +_elementtree.XMLParser._setevents + + events_queue: object(subclass_of='&PyList_Type') + 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=59db9742910c6174]*/ { /* activate element event reporting */ Py_ssize_t i, seqlen; TreeBuilderObject *target; - - PyObject *events_queue; - PyObject *events_to_report = Py_None; PyObject *events_seq; - if (!PyArg_ParseTuple(args, "O!|O:_setevents", &PyList_Type, &events_queue, - &events_to_report)) - return NULL; if (!TreeBuilder_CheckExact(self->target)) { PyErr_SetString( @@ -3605,15 +3701,6 @@ xmlparser_setevents(XMLParserObject *self, PyObject* args) Py_RETURN_NONE; } -static PyMethodDef xmlparser_methods[] = { - {"feed", (PyCFunction) xmlparser_feed, METH_O}, - {"close", (PyCFunction) xmlparser_close, METH_VARARGS}, - {"_parse_whole", (PyCFunction) xmlparser_parse_whole, METH_VARARGS}, - {"_setevents", (PyCFunction) xmlparser_setevents, METH_VARARGS}, - {"doctype", (PyCFunction) xmlparser_doctype, METH_VARARGS}, - {NULL, NULL} -}; - static PyObject* xmlparser_getattro(XMLParserObject* self, PyObject* nameobj) { @@ -3638,6 +3725,152 @@ xmlparser_getattro(XMLParserObject* self, PyObject* nameobj) return PyObject_GenericGetAttr((PyObject*) self, nameobj); } +#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 + + {"getiterator", (PyCFunction)_elementtree_Element_iter, METH_VARARGS|METH_KEYWORDS, _elementtree_Element_iter__doc__}, + _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 PyTypeObject Element_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "xml.etree.ElementTree.Element", sizeof(ElementObject), 0, + /* methods */ + (destructor)element_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (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 */ + (getattrofunc)element_getattro, /* tp_getattro */ + (setattrofunc)element_setattro, /* 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 */ + 0, /* 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_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_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + 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 + _ELEMENTTREE_XMLPARSER_DOCTYPE_METHODDEF + {NULL, NULL} +}; + static PyTypeObject XMLParser_Type = { PyVarObject_HEAD_INIT(NULL, 0) "xml.etree.ElementTree.XMLParser", sizeof(XMLParserObject), 0, @@ -3674,7 +3907,7 @@ static PyTypeObject XMLParser_Type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)xmlparser_init, /* tp_init */ + _elementtree_XMLParser___init__, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ xmlparser_new, /* tp_new */ 0, /* tp_free */ @@ -3741,7 +3974,7 @@ PyInit__elementtree(void) if (expat_capi) { /* check that it's usable */ if (strcmp(expat_capi->magic, PyExpat_CAPI_MAGIC) != 0 || - expat_capi->size < sizeof(struct PyExpat_CAPI) || + (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) { diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 57dfba041013..1f9806728f53 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -25,7 +25,7 @@ static PyTypeObject partial_type; static PyObject * partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) { - PyObject *func; + PyObject *func, *pargs, *nargs, *pkw; partialobject *pto; if (PyTuple_GET_SIZE(args) < 1) { @@ -34,7 +34,16 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) return NULL; } + pargs = pkw = Py_None; 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; + } + } if (!PyCallable_Check(func)) { PyErr_SetString(PyExc_TypeError, "the first argument must be callable"); @@ -48,21 +57,62 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) pto->fn = func; Py_INCREF(func); - pto->args = PyTuple_GetSlice(args, 1, PY_SSIZE_T_MAX); - if (pto->args == NULL) { + + nargs = PyTuple_GetSlice(args, 1, PY_SSIZE_T_MAX); + if (nargs == NULL) { + pto->args = NULL; pto->kw = NULL; Py_DECREF(pto); return NULL; } + if (pargs == Py_None || PyTuple_GET_SIZE(pargs) == 0) { + pto->args = nargs; + Py_INCREF(nargs); + } + else if (PyTuple_GET_SIZE(nargs) == 0) { + pto->args = pargs; + Py_INCREF(pargs); + } + else { + pto->args = PySequence_Concat(pargs, nargs); + if (pto->args == NULL) { + pto->kw = NULL; + Py_DECREF(pto); + return NULL; + } + } + Py_DECREF(nargs); + if (kw != NULL) { - pto->kw = PyDict_Copy(kw); + if (pkw == Py_None) { + pto->kw = PyDict_Copy(kw); + } + else { + pto->kw = PyDict_Copy(pkw); + if (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; } - } else { - pto->kw = Py_None; - Py_INCREF(Py_None); + } + else { + if (pkw == Py_None) { + pto->kw = PyDict_New(); + if (pto->kw == NULL) { + Py_DECREF(pto); + return NULL; + } + } + else { + pto->kw = pkw; + Py_INCREF(pkw); + } } pto->weakreflist = NULL; @@ -540,6 +590,564 @@ For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates\n\ of the sequence in the calculation, and serves as a default when the\n\ sequence is empty."); +/* lru_cache object **********************************************************/ + +/* 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) +{ + _PyObject_GC_UNTRACK(link); + Py_XDECREF(link->key); + Py_XDECREF(link->result); + PyObject_GC_Del(link); +} + +static int +lru_list_elem_traverse(lru_list_elem *link, visitproc visit, void *arg) +{ + Py_VISIT(link->key); + Py_VISIT(link->result); + return 0; +} + +static int +lru_list_elem_clear(lru_list_elem *link) +{ + Py_CLEAR(link->key); + Py_CLEAR(link->result); + return 0; +} + +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_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + 0, /* tp_doc */ + (traverseproc)lru_list_elem_traverse, /* tp_traverse */ + (inquiry)lru_list_elem_clear, /* tp_clear */ +}; + + +typedef PyObject *(*lru_cache_ternaryfunc)(struct lru_cache_object *, PyObject *, PyObject *); + +typedef struct lru_cache_object { + lru_list_elem root; /* includes PyObject_HEAD */ + Py_ssize_t maxsize; + PyObject *maxsize_O; + PyObject *func; + lru_cache_ternaryfunc wrapper; + PyObject *cache; + PyObject *cache_info_type; + Py_ssize_t misses, hits; + int typed; + PyObject *dict; + int full; +} lru_cache_object; + +static PyTypeObject lru_cache_type; + +static PyObject * +lru_cache_make_key(PyObject *args, PyObject *kwds, int typed) +{ + PyObject *key, *sorted_items; + Py_ssize_t key_size, pos, key_pos; + + /* short path, key will match args anyway, which is a tuple */ + if (!typed && !kwds) { + Py_INCREF(args); + return args; + } + + if (kwds && PyDict_Size(kwds) > 0) { + sorted_items = PyDict_Items(kwds); + if (!sorted_items) + return NULL; + if (PyList_Sort(sorted_items) < 0) { + Py_DECREF(sorted_items); + return NULL; + } + } else + sorted_items = NULL; + + key_size = PyTuple_GET_SIZE(args); + if (sorted_items) + key_size += PyList_GET_SIZE(sorted_items); + if (typed) + key_size *= 2; + if (sorted_items) + key_size++; + + key = PyTuple_New(key_size); + if (key == NULL) + goto done; + + 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 (sorted_items) { + Py_INCREF(kwd_mark); + PyTuple_SET_ITEM(key, key_pos++, kwd_mark); + for (pos = 0; pos < PyList_GET_SIZE(sorted_items); ++pos) { + PyObject *item = PyList_GET_ITEM(sorted_items, pos); + Py_INCREF(item); + PyTuple_SET_ITEM(key, key_pos++, item); + } + } + 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 (sorted_items) { + for (pos = 0; pos < PyList_GET_SIZE(sorted_items); ++pos) { + PyObject *tp_items = PyList_GET_ITEM(sorted_items, pos); + PyObject *item = (PyObject *)Py_TYPE(PyTuple_GET_ITEM(tp_items, 1)); + Py_INCREF(item); + PyTuple_SET_ITEM(key, key_pos++, item); + } + } + } + assert(key_pos == key_size); + +done: + if (sorted_items) + Py_DECREF(sorted_items); + return key; +} + +static PyObject * +uncached_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds) +{ + PyObject *result = PyObject_Call(self->func, args, kwds); + if (!result) + return NULL; + self->misses++; + 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) + 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; + } + 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); + self->misses++; + return result; +} + +static void +lru_cache_extricate_link(lru_list_elem *link) +{ + 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 PyObject * +bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds) +{ + lru_list_elem *link; + PyObject *key, *result; + Py_hash_t hash; + + key = lru_cache_make_key(args, kwds, self->typed); + if (!key) + return NULL; + hash = PyObject_Hash(key); + if (hash == -1) + return NULL; + link = (lru_list_elem *)_PyDict_GetItem_KnownHash(self->cache, key, hash); + if (link) { + lru_cache_extricate_link(link); + lru_cache_append_link(self, link); + self->hits++; + result = link->result; + Py_INCREF(result); + Py_DECREF(key); + return result; + } + if (PyErr_Occurred()) { + Py_DECREF(key); + return NULL; + } + result = PyObject_Call(self->func, args, kwds); + if (!result) { + Py_DECREF(key); + return NULL; + } + if (self->full && self->root.next != &self->root) { + /* Use the oldest item to store the new key and result. */ + PyObject *oldkey, *oldresult; + /* Extricate the oldest item. */ + link = self->root.next; + lru_cache_extricate_link(link); + /* Remove it from the cache. + The cache dict holds one reference to the link, + and the linked list holds yet one reference to it. */ + if (_PyDict_DelItem_KnownHash(self->cache, link->key, + link->hash) < 0) { + lru_cache_append_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; + if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link, + hash) < 0) { + Py_DECREF(link); + Py_DECREF(oldkey); + Py_DECREF(oldresult); + return NULL; + } + lru_cache_append_link(self, link); + Py_INCREF(result); /* for return */ + Py_DECREF(oldkey); + Py_DECREF(oldresult); + } else { + /* Put result in a new link at the front of the queue. */ + link = (lru_list_elem *)PyObject_GC_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; + _PyObject_GC_TRACK(link); + 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 */ + self->full = (PyDict_Size(self->cache) >= self->maxsize); + } + self->misses++; + 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) + 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->cache = cachedict; + obj->root.prev = &obj->root; + obj->root.next = &obj->root; + obj->maxsize = maxsize; + Py_INCREF(maxsize_O); + obj->maxsize_O = maxsize_O; + Py_INCREF(func); + obj->func = func; + obj->wrapper = wrapper; + obj->misses = obj->hits = 0; + obj->typed = typed; + 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 = lru_cache_unlink_list(obj); + Py_XDECREF(obj->maxsize_O); + Py_XDECREF(obj->func); + Py_XDECREF(obj->cache); + Py_XDECREF(obj->dict); + Py_XDECREF(obj->cache_info_type); + 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) +{ + return PyObject_CallFunction(self->cache_info_type, "nnOn", + self->hits, self->misses, self->maxsize_O, + PyDict_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; + self->full = 0; + PyDict_Clear(self->cache); + lru_cache_clear_list(list); + Py_RETURN_NONE; +} + +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); + link = next; + } + Py_VISIT(self->maxsize_O); + 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->maxsize_O); + 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}, + {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_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + (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, + /* 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, @@ -552,6 +1160,11 @@ static PyMethodDef module_methods[] = { {NULL, NULL} /* sentinel */ }; +static void +module_free(void *m) +{ + Py_CLEAR(kwd_mark); +} static struct PyModuleDef _functoolsmodule = { PyModuleDef_HEAD_INIT, @@ -562,7 +1175,7 @@ static struct PyModuleDef _functoolsmodule = { NULL, NULL, NULL, - NULL + module_free, }; PyMODINIT_FUNC @@ -573,6 +1186,7 @@ PyInit__functools(void) char *name; PyTypeObject *typelist[] = { &partial_type, + &lru_cache_type, NULL }; @@ -580,6 +1194,12 @@ PyInit__functools(void) if (m == NULL) return NULL; + kwd_mark = PyObject_CallObject((PyObject *)&PyBaseObject_Type, NULL); + if (!kwd_mark) { + Py_DECREF(m); + return NULL; + } + for (i=0 ; typelist[i] != NULL ; i++) { if (PyType_Ready(typelist[i]) < 0) { Py_DECREF(m); diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c index 229e16e627db..f070a140079a 100644 --- a/Modules/_gdbmmodule.c +++ b/Modules/_gdbmmodule.c @@ -16,17 +16,23 @@ 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\ +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 strings. Printing a GDBM object doesn't print the\n\ -keys and values, and the items() and values() methods are not\n\ -supported."); +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 @@ -36,6 +42,8 @@ typedef struct { 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"); \ @@ -48,15 +56,15 @@ 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 strings. Printing a GDBM object doesn't print the\n\ -keys and values, and the items() and values() methods are not\n\ -supported.\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(char *file, int flags, int mode) +newdbmobject(const char *file, int flags, int mode) { dbmobject *dp; @@ -65,7 +73,7 @@ newdbmobject(char *file, int flags, int mode) return NULL; dp->di_size = -1; errno = 0; - if ((dp->di_dbm = gdbm_open(file, 0, flags, mode, NULL)) == 0) { + if ((dp->di_dbm = gdbm_open((char *)file, 0, flags, mode, NULL)) == 0) { if (errno != 0) PyErr_SetFromErrno(DbmError); else @@ -135,24 +143,27 @@ dbm_subscript(dbmobject *dp, PyObject *key) return v; } -PyDoc_STRVAR(dbm_get__doc__, -"get(key[, default]) -> value\n\ -Get the value for key, or default if not present; if not given,\n\ -default is None."); +/*[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 * -dbm_get(dbmobject *dp, PyObject *args) +_gdbm_gdbm_get_impl(dbmobject *self, PyObject *key, PyObject *default_value) +/*[clinic end generated code: output=19b7c585ad4f554a input=a9c20423f34c17b6]*/ { - PyObject *v, *res; - PyObject *def = Py_None; + PyObject *res; - if (!PyArg_UnpackTuple(args, "get", 1, 2, &v, &def)) - return NULL; - res = dbm_subscript(dp, v); + res = dbm_subscript(self, key); if (res == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) { PyErr_Clear(); - Py_INCREF(def); - return def; + Py_INCREF(default_value); + return default_value; } return res; } @@ -198,25 +209,29 @@ dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w) return 0; } -PyDoc_STRVAR(dbm_setdefault__doc__, -"setdefault(key[, default]) -> value\n\ -Get value for key, or set it to default and return default if not present;\n\ -if not given, default is None."); +/*[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 * -dbm_setdefault(dbmobject *dp, PyObject *args) +_gdbm_gdbm_setdefault_impl(dbmobject *self, PyObject *key, + PyObject *default_value) +/*[clinic end generated code: output=88760ee520329012 input=0db46b69e9680171]*/ { - PyObject *v, *res; - PyObject *def = Py_None; + PyObject *res; - if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, &v, &def)) - return NULL; - res = dbm_subscript(dp, v); + res = dbm_subscript(self, key); if (res == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) { PyErr_Clear(); - if (dbm_ass_sub(dp, v, def) < 0) + if (dbm_ass_sub(self, key, default_value) < 0) return NULL; - return dbm_subscript(dp, v); + return dbm_subscript(self, key); } return res; } @@ -227,43 +242,49 @@ static PyMappingMethods dbm_as_mapping = { (objobjargproc)dbm_ass_sub, /*mp_ass_subscript*/ }; -PyDoc_STRVAR(dbm_close__doc__, -"close() -> None\n\ -Closes the database."); +/*[clinic input] +_gdbm.gdbm.close + +Close the database. +[clinic start generated code]*/ static PyObject * -dbm_close(dbmobject *dp, PyObject *unused) +_gdbm_gdbm_close_impl(dbmobject *self) +/*[clinic end generated code: output=23512a594598b563 input=0a203447379b45fd]*/ { - if (dp->di_dbm) - gdbm_close(dp->di_dbm); - dp->di_dbm = NULL; + if (self->di_dbm) + gdbm_close(self->di_dbm); + self->di_dbm = NULL; Py_INCREF(Py_None); return Py_None; } /* XXX Should return a set or a set view */ -PyDoc_STRVAR(dbm_keys__doc__, -"keys() -> list_of_keys\n\ -Get a list of all keys in the database."); +/*[clinic input] +_gdbm.gdbm.keys + +Get a list of all keys in the database. +[clinic start generated code]*/ static PyObject * -dbm_keys(dbmobject *dp, PyObject *unused) +_gdbm_gdbm_keys_impl(dbmobject *self) +/*[clinic end generated code: output=cb4b1776c3645dcc input=1832ee0a3132cfaf]*/ { PyObject *v, *item; datum key, nextkey; int err; - if (dp == NULL || !is_dbmobject(dp)) { + if (self == NULL || !is_dbmobject(self)) { PyErr_BadInternalCall(); return NULL; } - check_dbmobject_open(dp); + check_dbmobject_open(self); v = PyList_New(0); if (v == NULL) return NULL; - key = gdbm_firstkey(dp->di_dbm); + key = gdbm_firstkey(self->di_dbm); while (key.dptr) { item = PyBytes_FromStringAndSize(key.dptr, key.dsize); if (item == NULL) { @@ -278,7 +299,7 @@ dbm_keys(dbmobject *dp, PyObject *unused) Py_DECREF(v); return NULL; } - nextkey = gdbm_nextkey(dp->di_dbm, key); + nextkey = gdbm_nextkey(self->di_dbm, key); free(key.dptr); key = nextkey; } @@ -329,21 +350,25 @@ static PySequenceMethods dbm_as_sequence = { 0, /* sq_inplace_repeat */ }; -PyDoc_STRVAR(dbm_firstkey__doc__, -"firstkey() -> key\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. This method\n\ -returns the starting key."); +/*[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 * -dbm_firstkey(dbmobject *dp, PyObject *unused) +_gdbm_gdbm_firstkey_impl(dbmobject *self) +/*[clinic end generated code: output=9ff85628d84b65d2 input=0dbd6a335d69bba0]*/ { PyObject *v; datum key; - check_dbmobject_open(dp); - key = gdbm_firstkey(dp->di_dbm); + check_dbmobject_open(self); + key = gdbm_firstkey(self->di_dbm); if (key.dptr) { v = PyBytes_FromStringAndSize(key.dptr, key.dsize); free(key.dptr); @@ -355,27 +380,35 @@ dbm_firstkey(dbmobject *dp, PyObject *unused) } } -PyDoc_STRVAR(dbm_nextkey__doc__, -"nextkey(key) -> next_key\n\ -Returns the key that follows key in the traversal.\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)"); +/*[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 * -dbm_nextkey(dbmobject *dp, PyObject *args) +_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 key, nextkey; + datum dbm_key, nextkey; - if (!PyArg_ParseTuple(args, "s#:nextkey", &key.dptr, &key.dsize)) - return NULL; - check_dbmobject_open(dp); - nextkey = gdbm_nextkey(dp->di_dbm, key); + 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); @@ -387,20 +420,25 @@ dbm_nextkey(dbmobject *dp, PyObject *args) } } -PyDoc_STRVAR(dbm_reorganize__doc__, -"reorganize() -> None\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."); +/*[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 * -dbm_reorganize(dbmobject *dp, PyObject *unused) +_gdbm_gdbm_reorganize_impl(dbmobject *self) +/*[clinic end generated code: output=38d9624df92e961d input=f6bea85bcfd40dd2]*/ { - check_dbmobject_open(dp); + check_dbmobject_open(self); errno = 0; - if (gdbm_reorganize(dp->di_dbm) < 0) { + if (gdbm_reorganize(self->di_dbm) < 0) { if (errno != 0) PyErr_SetFromErrno(DbmError); else @@ -411,16 +449,21 @@ dbm_reorganize(dbmobject *dp, PyObject *unused) return Py_None; } -PyDoc_STRVAR(dbm_sync__doc__, -"sync() -> None\n\ -When the database has been opened in fast mode, this method forces\n\ -any unwritten data to be written to the disk."); +/*[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 * -dbm_sync(dbmobject *dp, PyObject *unused) +_gdbm_gdbm_sync_impl(dbmobject *self) +/*[clinic end generated code: output=488b15f47028f125 input=2a47d2c9e153ab8a]*/ { - check_dbmobject_open(dp); - gdbm_sync(dp->di_dbm); + check_dbmobject_open(self); + gdbm_sync(self->di_dbm); Py_INCREF(Py_None); return Py_None; } @@ -440,14 +483,15 @@ dbm__exit__(PyObject *self, PyObject *args) } static PyMethodDef dbm_methods[] = { - {"close", (PyCFunction)dbm_close, METH_NOARGS, dbm_close__doc__}, - {"keys", (PyCFunction)dbm_keys, METH_NOARGS, dbm_keys__doc__}, - {"firstkey", (PyCFunction)dbm_firstkey,METH_NOARGS, dbm_firstkey__doc__}, - {"nextkey", (PyCFunction)dbm_nextkey, METH_VARARGS, dbm_nextkey__doc__}, - {"reorganize",(PyCFunction)dbm_reorganize,METH_NOARGS, dbm_reorganize__doc__}, - {"sync", (PyCFunction)dbm_sync, METH_NOARGS, dbm_sync__doc__}, - {"get", (PyCFunction)dbm_get, METH_VARARGS, dbm_get__doc__}, - {"setdefault",(PyCFunction)dbm_setdefault,METH_VARARGS, dbm_setdefault__doc__}, + _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_GET_METHODDEF + _GDBM_GDBM_SETDEFAULT_METHODDEF {"__enter__", dbm__enter__, METH_NOARGS, NULL}, {"__exit__", dbm__exit__, METH_VARARGS, NULL}, {NULL, NULL} /* sentinel */ @@ -486,40 +530,44 @@ static PyTypeObject Dbmtype = { /* ----------------------------------------------------------------- */ -PyDoc_STRVAR(dbmopen__doc__, -"open(filename, [flags, [mode]]) -> dbm_object\n\ -Open a dbm database and return a dbm object. The filename argument is\n\ -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 0666. "); +/*[clinic input] +_gdbm.open as dbmopen + filename as name: str + 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(PyObject *self, PyObject *args) +dbmopen_impl(PyModuleDef *module, const char *name, const char *flags, + int mode) +/*[clinic end generated code: output=365b31415c03ccd4 input=55563cd60e51984a]*/ { - char *name; - char *flags = "r"; int iflags; - int mode = 0666; - if (!PyArg_ParseTuple(args, "s|si:open", &name, &flags, &mode)) - return NULL; switch (flags[0]) { case 'r': iflags = GDBM_READER; @@ -580,7 +628,7 @@ static char dbmmodule_open_flags[] = "rwcn" ; static PyMethodDef dbmmodule_methods[] = { - { "open", (PyCFunction)dbmopen, METH_VARARGS, dbmopen__doc__}, + DBMOPEN_METHODDEF { 0, 0 }, }; diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index a866fbf7f95d..8ccc2431082a 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -16,6 +16,7 @@ #include "Python.h" #include "structmember.h" #include "hashlib.h" +#include "pystrhex.h" /* EVP is the preferred interface to hashing in OpenSSL */ @@ -31,10 +32,6 @@ #define HASH_OBJ_CONSTRUCTOR 0 #endif -/* Minimum OpenSSL version needed to support sha224 and higher. */ -#if defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x00908000) -#define _OPENSSL_SUPPORTS_SHA2 -#endif typedef struct { PyObject_HEAD @@ -56,12 +53,10 @@ static PyTypeObject EVPtype; DEFINE_CONSTS_FOR_NEW(md5) DEFINE_CONSTS_FOR_NEW(sha1) -#ifdef _OPENSSL_SUPPORTS_SHA2 DEFINE_CONSTS_FOR_NEW(sha224) DEFINE_CONSTS_FOR_NEW(sha256) DEFINE_CONSTS_FOR_NEW(sha384) DEFINE_CONSTS_FOR_NEW(sha512) -#endif static EVPobject * @@ -163,9 +158,7 @@ EVP_hexdigest(EVPobject *self, PyObject *unused) { unsigned char digest[EVP_MAX_MD_SIZE]; EVP_MD_CTX temp_ctx; - PyObject *retval; - char *hex_digest; - unsigned int i, j, digest_size; + unsigned int digest_size; /* Get the raw (binary) digest value */ locked_EVP_MD_CTX_copy(&temp_ctx, self); @@ -174,22 +167,7 @@ EVP_hexdigest(EVPobject *self, PyObject *unused) EVP_MD_CTX_cleanup(&temp_ctx); - /* Allocate a new buffer */ - hex_digest = PyMem_Malloc(digest_size * 2 + 1); - if (!hex_digest) - return PyErr_NoMemory(); - - /* Make hex version of the digest */ - for(i=j=0; i> 4) & 0xf; - hex_digest[j++] = Py_hexdigits[c]; - c = (digest[i] & 0xf); - hex_digest[j++] = Py_hexdigits[c]; - } - retval = PyUnicode_FromStringAndSize(hex_digest, digest_size * 2); - PyMem_Free(hex_digest); - return retval; + return _Py_strhex((const char *)digest, digest_size); } PyDoc_STRVAR(EVP_update__doc__, @@ -508,8 +486,8 @@ PKCS5_PBKDF2_HMAC_fast(const char *pass, int passlen, HMAC_CTX_cleanup(&hctx_tpl); return 0; } - while(tkeylen) { - if(tkeylen > mdlen) + while (tkeylen) { + if (tkeylen > mdlen) cplen = mdlen; else cplen = tkeylen; @@ -557,6 +535,7 @@ PKCS5_PBKDF2_HMAC_fast(const char *pass, int passlen, return 1; } +/* LCOV_EXCL_START */ static PyObject * _setException(PyObject *exc) { @@ -585,6 +564,7 @@ _setException(PyObject *exc) } return NULL; } +/* LCOV_EXCL_STOP */ PyDoc_STRVAR(pbkdf2_hmac__doc__, "pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None) -> key\n\ @@ -796,12 +776,10 @@ generate_hash_name_list(void) GEN_CONSTRUCTOR(md5) GEN_CONSTRUCTOR(sha1) -#ifdef _OPENSSL_SUPPORTS_SHA2 GEN_CONSTRUCTOR(sha224) GEN_CONSTRUCTOR(sha256) GEN_CONSTRUCTOR(sha384) GEN_CONSTRUCTOR(sha512) -#endif /* List of functions exported by this module */ @@ -813,12 +791,10 @@ static struct PyMethodDef EVP_functions[] = { #endif CONSTRUCTOR_METH_DEF(md5), CONSTRUCTOR_METH_DEF(sha1), -#ifdef _OPENSSL_SUPPORTS_SHA2 CONSTRUCTOR_METH_DEF(sha224), CONSTRUCTOR_METH_DEF(sha256), CONSTRUCTOR_METH_DEF(sha384), CONSTRUCTOR_METH_DEF(sha512), -#endif {NULL, NULL} /* Sentinel */ }; @@ -875,11 +851,9 @@ PyInit__hashlib(void) /* these constants are used by the convenience constructors */ INIT_CONSTRUCTOR_CONSTANTS(md5); INIT_CONSTRUCTOR_CONSTANTS(sha1); -#ifdef _OPENSSL_SUPPORTS_SHA2 INIT_CONSTRUCTOR_CONSTANTS(sha224); INIT_CONSTRUCTOR_CONSTANTS(sha256); INIT_CONSTRUCTOR_CONSTANTS(sha384); INIT_CONSTRUCTOR_CONSTANTS(sha512); -#endif return m; } diff --git a/Modules/_heapqmodule.c b/Modules/_heapqmodule.c index 96afcdc1b377..28604afee959 100644 --- a/Modules/_heapqmodule.c +++ b/Modules/_heapqmodule.c @@ -9,12 +9,11 @@ annotated by François Pinard, and converted to C by Raymond Hettinger. #include "Python.h" static int -_siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) +siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) { - PyObject *newitem, *parent, *olditem; + PyObject *newitem, *parent, **arr; + Py_ssize_t parentpos, size; int cmp; - Py_ssize_t parentpos; - Py_ssize_t size; assert(PyList_Check(heap)); size = PyList_GET_SIZE(heap); @@ -23,104 +22,78 @@ _siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) return -1; } - newitem = PyList_GET_ITEM(heap, pos); - Py_INCREF(newitem); /* Follow the path to the root, moving parents down until finding a place newitem fits. */ - while (pos > startpos){ + arr = _PyList_ITEMS(heap); + newitem = arr[pos]; + while (pos > startpos) { parentpos = (pos - 1) >> 1; - parent = PyList_GET_ITEM(heap, parentpos); + parent = arr[parentpos]; cmp = PyObject_RichCompareBool(newitem, parent, Py_LT); - if (cmp == -1) { - Py_DECREF(newitem); + if (cmp < 0) return -1; - } if (size != PyList_GET_SIZE(heap)) { - Py_DECREF(newitem); PyErr_SetString(PyExc_RuntimeError, "list changed size during iteration"); return -1; } if (cmp == 0) break; - Py_INCREF(parent); - olditem = PyList_GET_ITEM(heap, pos); - PyList_SET_ITEM(heap, pos, parent); - Py_DECREF(olditem); + arr = _PyList_ITEMS(heap); + parent = arr[parentpos]; + newitem = arr[pos]; + arr[parentpos] = newitem; + arr[pos] = parent; pos = parentpos; - if (size != PyList_GET_SIZE(heap)) { - PyErr_SetString(PyExc_RuntimeError, - "list changed size during iteration"); - return -1; - } } - Py_DECREF(PyList_GET_ITEM(heap, pos)); - PyList_SET_ITEM(heap, pos, newitem); return 0; } static int -_siftup(PyListObject *heap, Py_ssize_t pos) +siftup(PyListObject *heap, Py_ssize_t pos) { - Py_ssize_t startpos, endpos, childpos, rightpos; + Py_ssize_t startpos, endpos, childpos, limit; + PyObject *tmp1, *tmp2, **arr; int cmp; - PyObject *newitem, *tmp, *olditem; - Py_ssize_t size; assert(PyList_Check(heap)); - size = PyList_GET_SIZE(heap); - endpos = size; + endpos = PyList_GET_SIZE(heap); startpos = pos; if (pos >= endpos) { PyErr_SetString(PyExc_IndexError, "index out of range"); return -1; } - newitem = PyList_GET_ITEM(heap, pos); - Py_INCREF(newitem); /* Bubble up the smaller child until hitting a leaf. */ - childpos = 2*pos + 1; /* leftmost child position */ - while (childpos < endpos) { + arr = _PyList_ITEMS(heap); + limit = endpos >> 1; /* smallest pos that has no child */ + while (pos < limit) { /* Set childpos to index of smaller child. */ - rightpos = childpos + 1; - if (rightpos < endpos) { + childpos = 2*pos + 1; /* leftmost child position */ + if (childpos + 1 < endpos) { cmp = PyObject_RichCompareBool( - PyList_GET_ITEM(heap, childpos), - PyList_GET_ITEM(heap, rightpos), + arr[childpos], + arr[childpos + 1], Py_LT); - if (cmp == -1) { - Py_DECREF(newitem); + if (cmp < 0) + return -1; + childpos += ((unsigned)cmp ^ 1); /* increment when cmp==0 */ + if (endpos != PyList_GET_SIZE(heap)) { + PyErr_SetString(PyExc_RuntimeError, + "list changed size during iteration"); return -1; } - if (cmp == 0) - childpos = rightpos; - } - if (size != PyList_GET_SIZE(heap)) { - Py_DECREF(newitem); - PyErr_SetString(PyExc_RuntimeError, - "list changed size during iteration"); - return -1; } /* Move the smaller child up. */ - tmp = PyList_GET_ITEM(heap, childpos); - Py_INCREF(tmp); - olditem = PyList_GET_ITEM(heap, pos); - PyList_SET_ITEM(heap, pos, tmp); - Py_DECREF(olditem); + arr = _PyList_ITEMS(heap); + tmp1 = arr[childpos]; + tmp2 = arr[pos]; + arr[childpos] = tmp2; + arr[pos] = tmp1; pos = childpos; - childpos = 2*pos + 1; - if (size != PyList_GET_SIZE(heap)) { - PyErr_SetString(PyExc_RuntimeError, - "list changed size during iteration"); - return -1; - } } - - /* The leaf at pos is empty now. Put newitem there, and bubble - it up to its final resting place (by sifting its parents down). */ - Py_DECREF(PyList_GET_ITEM(heap, pos)); - PyList_SET_ITEM(heap, pos, newitem); - return _siftdown(heap, startpos, pos); + /* Bubble it up to its final resting place (by sifting its parents down). */ + return siftdown(heap, startpos, pos); } static PyObject * @@ -136,20 +109,19 @@ heappush(PyObject *self, PyObject *args) return NULL; } - if (PyList_Append(heap, item) == -1) + if (PyList_Append(heap, item)) return NULL; - if (_siftdown((PyListObject *)heap, 0, PyList_GET_SIZE(heap)-1) == -1) + if (siftdown((PyListObject *)heap, 0, PyList_GET_SIZE(heap)-1)) return NULL; - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } PyDoc_STRVAR(heappush_doc, "heappush(heap, item) -> None. Push item onto heap, maintaining the heap invariant."); static PyObject * -heappop(PyObject *self, PyObject *heap) +heappop_internal(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t)) { PyObject *lastelt, *returnitem; Py_ssize_t n; @@ -159,7 +131,7 @@ heappop(PyObject *self, PyObject *heap) return NULL; } - /* # raises appropriate IndexError if heap is empty */ + /* raises IndexError if the heap is empty */ n = PyList_GET_SIZE(heap); if (n == 0) { PyErr_SetString(PyExc_IndexError, "index out of range"); @@ -168,7 +140,7 @@ heappop(PyObject *self, PyObject *heap) lastelt = PyList_GET_ITEM(heap, n-1) ; Py_INCREF(lastelt); - if (PyList_SetSlice(heap, n-1, n, NULL) < 0) { + if (PyList_SetSlice(heap, n-1, n, NULL)) { Py_DECREF(lastelt); return NULL; } @@ -178,18 +150,24 @@ heappop(PyObject *self, PyObject *heap) return lastelt; returnitem = PyList_GET_ITEM(heap, 0); PyList_SET_ITEM(heap, 0, lastelt); - if (_siftup((PyListObject *)heap, 0) == -1) { + if (siftup_func((PyListObject *)heap, 0)) { Py_DECREF(returnitem); return NULL; } return returnitem; } +static PyObject * +heappop(PyObject *self, PyObject *heap) +{ + return heappop_internal(heap, siftup); +} + PyDoc_STRVAR(heappop_doc, "Pop the smallest item off the heap, maintaining the heap invariant."); static PyObject * -heapreplace(PyObject *self, PyObject *args) +heapreplace_internal(PyObject *args, int siftup_func(PyListObject *, Py_ssize_t)) { PyObject *heap, *item, *returnitem; @@ -201,7 +179,7 @@ heapreplace(PyObject *self, PyObject *args) return NULL; } - if (PyList_GET_SIZE(heap) < 1) { + if (PyList_GET_SIZE(heap) == 0) { PyErr_SetString(PyExc_IndexError, "index out of range"); return NULL; } @@ -209,13 +187,19 @@ heapreplace(PyObject *self, PyObject *args) returnitem = PyList_GET_ITEM(heap, 0); Py_INCREF(item); PyList_SET_ITEM(heap, 0, item); - if (_siftup((PyListObject *)heap, 0) == -1) { + if (siftup_func((PyListObject *)heap, 0)) { Py_DECREF(returnitem); return NULL; } return returnitem; } +static PyObject * +heapreplace(PyObject *self, PyObject *args) +{ + return heapreplace_internal(args, siftup); +} + PyDoc_STRVAR(heapreplace_doc, "heapreplace(heap, item) -> value. Pop and return the current smallest value, and add the new item.\n\ \n\ @@ -240,23 +224,28 @@ heappushpop(PyObject *self, PyObject *args) return NULL; } - if (PyList_GET_SIZE(heap) < 1) { + if (PyList_GET_SIZE(heap) == 0) { Py_INCREF(item); return item; } cmp = PyObject_RichCompareBool(PyList_GET_ITEM(heap, 0), item, Py_LT); - if (cmp == -1) + 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) == -1) { + if (siftup((PyListObject *)heap, 0)) { Py_DECREF(returnitem); return NULL; } @@ -268,8 +257,73 @@ PyDoc_STRVAR(heappushpop_doc, from the heap. The combined action runs more efficiently than\n\ heappush() followed by a separate call to heappop()."); +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 * -heapify(PyObject *self, PyObject *heap) +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; @@ -278,7 +332,14 @@ heapify(PyObject *self, PyObject *heap) 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 @@ -286,142 +347,68 @@ heapify(PyObject *self, PyObject *heap) 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/2-1 ; i>=0 ; i--) - if(_siftup((PyListObject *)heap, i) == -1) + for (i = (n >> 1) - 1 ; i >= 0 ; i--) + if (siftup_func((PyListObject *)heap, i)) return NULL; - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(heapify_doc, -"Transform list into a heap, in-place, in O(len(heap)) time."); - static PyObject * -nlargest(PyObject *self, PyObject *args) +heapify(PyObject *self, PyObject *heap) { - PyObject *heap=NULL, *elem, *iterable, *sol, *it, *oldelem; - Py_ssize_t i, n; - int cmp; - - if (!PyArg_ParseTuple(args, "nO:nlargest", &n, &iterable)) - return NULL; - - it = PyObject_GetIter(iterable); - if (it == NULL) - return NULL; - - heap = PyList_New(0); - if (heap == NULL) - goto fail; - - for (i=0 ; i=0 ; i--) - if(_siftup((PyListObject *)heap, i) == -1) - goto fail; - - sol = PyList_GET_ITEM(heap, 0); - while (1) { - elem = PyIter_Next(it); - if (elem == NULL) { - if (PyErr_Occurred()) - goto fail; - else - goto sortit; - } - cmp = PyObject_RichCompareBool(sol, elem, Py_LT); - if (cmp == -1) { - Py_DECREF(elem); - goto fail; - } - if (cmp == 0) { - Py_DECREF(elem); - continue; - } - oldelem = PyList_GET_ITEM(heap, 0); - PyList_SET_ITEM(heap, 0, elem); - Py_DECREF(oldelem); - if (_siftup((PyListObject *)heap, 0) == -1) - goto fail; - sol = PyList_GET_ITEM(heap, 0); - } -sortit: - if (PyList_Sort(heap) == -1) - goto fail; - if (PyList_Reverse(heap) == -1) - goto fail; - Py_DECREF(it); - return heap; - -fail: - Py_DECREF(it); - Py_XDECREF(heap); - return NULL; + return heapify_internal(heap, siftup); } -PyDoc_STRVAR(nlargest_doc, -"Find the n largest elements in a dataset.\n\ -\n\ -Equivalent to: sorted(iterable, reverse=True)[:n]\n"); +PyDoc_STRVAR(heapify_doc, +"Transform list into a heap, in-place, in O(len(heap)) time."); static int -_siftdownmax(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) +siftdown_max(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) { - PyObject *newitem, *parent; + PyObject *newitem, *parent, **arr; + Py_ssize_t parentpos, size; int cmp; - Py_ssize_t parentpos; assert(PyList_Check(heap)); - if (pos >= PyList_GET_SIZE(heap)) { + size = PyList_GET_SIZE(heap); + if (pos >= size) { PyErr_SetString(PyExc_IndexError, "index out of range"); return -1; } - newitem = PyList_GET_ITEM(heap, pos); - Py_INCREF(newitem); /* Follow the path to the root, moving parents down until finding a place newitem fits. */ - while (pos > startpos){ + arr = _PyList_ITEMS(heap); + newitem = arr[pos]; + while (pos > startpos) { parentpos = (pos - 1) >> 1; - parent = PyList_GET_ITEM(heap, parentpos); + parent = arr[parentpos]; cmp = PyObject_RichCompareBool(parent, newitem, Py_LT); - if (cmp == -1) { - 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; - Py_INCREF(parent); - Py_DECREF(PyList_GET_ITEM(heap, pos)); - PyList_SET_ITEM(heap, pos, parent); + arr = _PyList_ITEMS(heap); + parent = arr[parentpos]; + newitem = arr[pos]; + arr[parentpos] = newitem; + arr[pos] = parent; pos = parentpos; } - Py_DECREF(PyList_GET_ITEM(heap, pos)); - PyList_SET_ITEM(heap, pos, newitem); return 0; } static int -_siftupmax(PyListObject *heap, Py_ssize_t pos) +siftup_max(PyListObject *heap, Py_ssize_t pos) { - Py_ssize_t startpos, endpos, childpos, rightpos; + Py_ssize_t startpos, endpos, childpos, limit; + PyObject *tmp1, *tmp2, **arr; int cmp; - PyObject *newitem, *tmp; assert(PyList_Check(heap)); endpos = PyList_GET_SIZE(heap); @@ -430,125 +417,62 @@ _siftupmax(PyListObject *heap, Py_ssize_t pos) PyErr_SetString(PyExc_IndexError, "index out of range"); return -1; } - newitem = PyList_GET_ITEM(heap, pos); - Py_INCREF(newitem); /* Bubble up the smaller child until hitting a leaf. */ - childpos = 2*pos + 1; /* leftmost child position */ - while (childpos < endpos) { + arr = _PyList_ITEMS(heap); + limit = endpos >> 1; /* smallest pos that has no child */ + while (pos < limit) { /* Set childpos to index of smaller child. */ - rightpos = childpos + 1; - if (rightpos < endpos) { + childpos = 2*pos + 1; /* leftmost child position */ + if (childpos + 1 < endpos) { cmp = PyObject_RichCompareBool( - PyList_GET_ITEM(heap, rightpos), - PyList_GET_ITEM(heap, childpos), + arr[childpos + 1], + arr[childpos], Py_LT); - if (cmp == -1) { - Py_DECREF(newitem); + if (cmp < 0) + return -1; + childpos += ((unsigned)cmp ^ 1); /* increment when cmp==0 */ + if (endpos != PyList_GET_SIZE(heap)) { + PyErr_SetString(PyExc_RuntimeError, + "list changed size during iteration"); return -1; } - if (cmp == 0) - childpos = rightpos; } /* Move the smaller child up. */ - tmp = PyList_GET_ITEM(heap, childpos); - Py_INCREF(tmp); - Py_DECREF(PyList_GET_ITEM(heap, pos)); - PyList_SET_ITEM(heap, pos, tmp); + arr = _PyList_ITEMS(heap); + tmp1 = arr[childpos]; + tmp2 = arr[pos]; + arr[childpos] = tmp2; + arr[pos] = tmp1; pos = childpos; - childpos = 2*pos + 1; } - - /* The leaf at pos is empty now. Put newitem there, and bubble - it up to its final resting place (by sifting its parents down). */ - Py_DECREF(PyList_GET_ITEM(heap, pos)); - PyList_SET_ITEM(heap, pos, newitem); - return _siftdownmax(heap, startpos, pos); + /* Bubble it up to its final resting place (by sifting its parents down). */ + return siftdown_max(heap, startpos, pos); } static PyObject * -nsmallest(PyObject *self, PyObject *args) +heappop_max(PyObject *self, PyObject *heap) { - PyObject *heap=NULL, *elem, *iterable, *los, *it, *oldelem; - Py_ssize_t i, n; - int cmp; + return heappop_internal(heap, siftup_max); +} - if (!PyArg_ParseTuple(args, "nO:nsmallest", &n, &iterable)) - return NULL; +PyDoc_STRVAR(heappop_max_doc, "Maxheap variant of heappop."); - it = PyObject_GetIter(iterable); - if (it == NULL) - return NULL; - - heap = PyList_New(0); - if (heap == NULL) - goto fail; - - for (i=0 ; i=0 ; i--) - if(_siftupmax((PyListObject *)heap, i) == -1) - goto fail; - - los = PyList_GET_ITEM(heap, 0); - while (1) { - elem = PyIter_Next(it); - if (elem == NULL) { - if (PyErr_Occurred()) - goto fail; - else - goto sortit; - } - cmp = PyObject_RichCompareBool(elem, los, Py_LT); - if (cmp == -1) { - Py_DECREF(elem); - goto fail; - } - if (cmp == 0) { - Py_DECREF(elem); - continue; - } - - oldelem = PyList_GET_ITEM(heap, 0); - PyList_SET_ITEM(heap, 0, elem); - Py_DECREF(oldelem); - if (_siftupmax((PyListObject *)heap, 0) == -1) - goto fail; - los = PyList_GET_ITEM(heap, 0); - } +static PyObject * +heapreplace_max(PyObject *self, PyObject *args) +{ + return heapreplace_internal(args, siftup_max); +} -sortit: - if (PyList_Sort(heap) == -1) - goto fail; - Py_DECREF(it); - return heap; +PyDoc_STRVAR(heapreplace_max_doc, "Maxheap variant of heapreplace"); -fail: - Py_DECREF(it); - Py_XDECREF(heap); - return NULL; +static PyObject * +heapify_max(PyObject *self, PyObject *heap) +{ + return heapify_internal(heap, siftup_max); } -PyDoc_STRVAR(nsmallest_doc, -"Find the n smallest elements in a dataset.\n\ -\n\ -Equivalent to: sorted(iterable)[:n]\n"); +PyDoc_STRVAR(heapify_max_doc, "Maxheap variant of heapify."); static PyMethodDef heapq_methods[] = { {"heappush", (PyCFunction)heappush, @@ -561,10 +485,12 @@ static PyMethodDef heapq_methods[] = { METH_VARARGS, heapreplace_doc}, {"heapify", (PyCFunction)heapify, METH_O, heapify_doc}, - {"nlargest", (PyCFunction)nlargest, - METH_VARARGS, nlargest_doc}, - {"nsmallest", (PyCFunction)nsmallest, - METH_VARARGS, nsmallest_doc}, + {"_heappop_max", (PyCFunction)heappop_max, + METH_O, heappop_max_doc}, + {"_heapreplace_max",(PyCFunction)heapreplace_max, + METH_VARARGS, heapreplace_max_doc}, + {"_heapify_max", (PyCFunction)heapify_max, + METH_O, heapify_max_doc}, {NULL, NULL} /* sentinel */ }; diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 9866fbe82be9..7428aed13bdd 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -93,164 +93,164 @@ PyDoc_STRVAR(module_doc, /* * The main open() function */ -PyDoc_STRVAR(open_doc, -"open(file, mode='r', buffering=-1, encoding=None,\n" -" errors=None, newline=None, closefd=True, opener=None) -> file object\n" -"\n" -"Open file and return a stream. Raise IOError 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.\n" - ); +/*[clinic input] +module _io + +_io.open + file: object + mode: str = "r" + buffering: int = -1 + encoding: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = NULL + newline: str(accept={str, NoneType}) = NULL + closefd: int(c_default="1") = True + opener: object = None + +Open file and return a stream. Raise IOError 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(PyObject *self, PyObject *args, PyObject *kwds) +_io_open_impl(PyModuleDef *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=7615d0d746eb14d2 input=f4e1ca75223987bc]*/ { - char *kwlist[] = {"file", "mode", "buffering", - "encoding", "errors", "newline", - "closefd", "opener", NULL}; - PyObject *file, *opener = Py_None; - char *mode = "r"; - int buffering = -1, closefd = 1; - char *encoding = NULL, *errors = NULL, *newline = NULL; 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, isatty; + int line_buffering; + long isatty; - PyObject *raw, *modeobj = NULL, *buffer = NULL, *wrapper = NULL; + PyObject *raw, *modeobj = NULL, *buffer, *wrapper, *result = NULL; + _Py_IDENTIFIER(_blksize); _Py_IDENTIFIER(isatty); - _Py_IDENTIFIER(fileno); _Py_IDENTIFIER(mode); - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|sizzziO:open", kwlist, - &file, &mode, &buffering, - &encoding, &errors, &newline, - &closefd, &opener)) { - return NULL; - } + _Py_IDENTIFIER(close); if (!PyUnicode_Check(file) && - !PyBytes_Check(file) && - !PyNumber_Check(file)) { + !PyBytes_Check(file) && + !PyNumber_Check(file)) { PyErr_Format(PyExc_TypeError, "invalid file: %R", file); return NULL; } @@ -308,9 +308,9 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) /* Parameters validation */ if (universal) { - if (writing || appending) { + if (creating || writing || appending || updating) { PyErr_SetString(PyExc_ValueError, - "can't use U and writing mode at once"); + "mode U cannot be combined with x', 'w', 'a', or '+'"); return NULL; } if (PyErr_WarnEx(PyExc_DeprecationWarning, @@ -354,6 +354,7 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) "OsiO", file, rawmode, closefd, opener); if (raw == NULL) return NULL; + result = raw; modeobj = PyUnicode_FromString(mode); if (modeobj == NULL) @@ -378,24 +379,14 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) line_buffering = 0; if (buffering < 0) { - buffering = DEFAULT_BUFFER_SIZE; -#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE - { - struct stat st; - long fileno; - PyObject *res = _PyObject_CallMethodId(raw, &PyId_fileno, NULL); - if (res == NULL) - goto error; - - fileno = PyLong_AsLong(res); - Py_DECREF(res); - if (fileno == -1 && PyErr_Occurred()) - goto error; - - if (fstat(fileno, &st) >= 0 && st.st_blksize > 1) - buffering = st.st_blksize; - } -#endif + 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, @@ -412,7 +403,7 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) } Py_DECREF(modeobj); - return raw; + return result; } /* wraps into a buffered file */ @@ -433,37 +424,44 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) buffer = PyObject_CallFunction(Buffered_class, "Oi", raw, buffering); } - Py_CLEAR(raw); if (buffer == NULL) goto error; + result = buffer; + Py_DECREF(raw); /* if binary, returns the buffered file */ if (binary) { Py_DECREF(modeobj); - return buffer; + return result; } /* wraps into a TextIOWrapper */ wrapper = PyObject_CallFunction((PyObject *)&PyTextIOWrapper_Type, - "Osssi", - buffer, - encoding, errors, newline, - line_buffering); - Py_CLEAR(buffer); + "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 wrapper; + return result; error: - Py_XDECREF(raw); + 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(modeobj); - Py_XDECREF(buffer); - Py_XDECREF(wrapper); return NULL; } @@ -539,6 +537,20 @@ _PyIO_ConvertSsize_t(PyObject *obj, void *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) { @@ -598,8 +610,10 @@ iomodule_free(PyObject *mod) { * Module definition */ +#include "clinic/_iomodule.c.h" + static PyMethodDef module_methods[] = { - {"open", (PyCFunction)io_open, METH_VARARGS|METH_KEYWORDS, open_doc}, + _IO_OPEN_METHODDEF {NULL, NULL} }; diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h index b90a658397de..0c6eae26b723 100644 --- a/Modules/_io/_iomodule.h +++ b/Modules/_io/_iomodule.h @@ -52,7 +52,12 @@ extern PyObject *_PyIncrementalNewlineDecoder_decode( 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. */ + 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, char *start, char *end, Py_ssize_t *consumed); @@ -69,7 +74,7 @@ extern int _PyIO_trap_eintr(void); * Offset type for positioning. */ -/* Printing a variable of type off_t (with e.g., PyString_FromFormat) +/* 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 @@ -135,8 +140,9 @@ typedef struct { } _PyIO_State; #define IO_MOD_STATE(mod) ((_PyIO_State *)PyModule_GetState(mod)) -#define IO_STATE IO_MOD_STATE(PyState_FindModule(&_PyIO_Module)) +#define IO_STATE() _PyIO_get_module_state() +extern _PyIO_State *_PyIO_get_module_state(void); extern PyObject *_PyIO_get_locale_module(_PyIO_State *); extern PyObject *_PyIO_str_close; diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index a04b48dd3a98..29e000bde4a6 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -13,6 +13,24 @@ #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]*/ + +/*[python input] +class io_ssize_t_converter(CConverter): + type = 'Py_ssize_t' + converter = '_PyIO_ConvertSsize_t' +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=d0a811d3cbfd1b33]*/ + _Py_IDENTIFIER(close); _Py_IDENTIFIER(_dealloc_warn); _Py_IDENTIFIER(flush); @@ -24,6 +42,7 @@ _Py_IDENTIFIER(read); _Py_IDENTIFIER(read1); _Py_IDENTIFIER(readable); _Py_IDENTIFIER(readinto); +_Py_IDENTIFIER(readinto1); _Py_IDENTIFIER(writable); _Py_IDENTIFIER(write); @@ -47,62 +66,86 @@ PyDoc_STRVAR(bufferediobase_doc, ); static PyObject * -bufferediobase_readinto(PyObject *self, PyObject *args) +_bufferediobase_readinto_generic(PyObject *self, Py_buffer *buffer, char readinto1) { - Py_buffer buf; Py_ssize_t len; PyObject *data; - if (!PyArg_ParseTuple(args, "w*:readinto", &buf)) { - return NULL; - } - - data = _PyObject_CallMethodId(self, &PyId_read, "n", buf.len); + data = _PyObject_CallMethodId(self, + readinto1 ? &PyId_read1 : &PyId_read, + "n", buffer->len); if (data == NULL) - goto error; + return NULL; if (!PyBytes_Check(data)) { Py_DECREF(data); PyErr_SetString(PyExc_TypeError, "read() should return bytes"); - goto error; + return NULL; } len = Py_SIZE(data); - if (len > buf.len) { + if (len > buffer->len) { PyErr_Format(PyExc_ValueError, "read() returned too much data: " "%zd bytes requested, %zd returned", - buf.len, len); + buffer->len, len); Py_DECREF(data); - goto error; + return NULL; } - memcpy(buf.buf, PyBytes_AS_STRING(data), len); + memcpy(buffer->buf, PyBytes_AS_STRING(data), len); - PyBuffer_Release(&buf); Py_DECREF(data); return PyLong_FromSsize_t(len); +} - error: - PyBuffer_Release(&buf); - return NULL; +/*[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) { - PyErr_SetString(IO_STATE->unsupported_operation, message); + _PyIO_State *state = IO_STATE(); + if (state != NULL) + PyErr_SetString(state->unsupported_operation, message); return NULL; } -PyDoc_STRVAR(bufferediobase_detach_doc, - "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.\n"); +/*[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 * -bufferediobase_detach(PyObject *self) +_io__BufferedIOBase_detach_impl(PyObject *self) +/*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/ { return bufferediobase_unsupported("detach"); } @@ -160,68 +203,6 @@ bufferediobase_write(PyObject *self, PyObject *args) } -static PyMethodDef bufferediobase_methods[] = { - {"detach", (PyCFunction)bufferediobase_detach, METH_NOARGS, bufferediobase_detach_doc}, - {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc}, - {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc}, - {"readinto", bufferediobase_readinto, METH_VARARGS, NULL}, - {"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_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 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_FINALIZE, /*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 */ -}; - - typedef struct { PyObject_HEAD @@ -298,14 +279,35 @@ typedef struct { 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_Finalizing != NULL); Py_BEGIN_ALLOW_THREADS - PyThread_acquire_lock(self->lock, 1); + 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); + char *msg = PyUnicode_AsUTF8(msgobj); + Py_FatalError(msg); + } return 1; } @@ -541,19 +543,8 @@ buffered_close(buffered *self, PyObject *args) } if (exc != NULL) { - if (res != NULL) { - Py_CLEAR(res); - PyErr_Restore(exc, val, tb); - } - else { - PyObject *val2; - Py_DECREF(exc); - Py_XDECREF(tb); - PyErr_Fetch(&exc, &val2, &tb); - PyErr_NormalizeException(&exc, &val2, &tb); - PyException_SetContext(val2, val); - PyErr_Restore(exc, val2, tb); - } + _PyErr_ChainExceptions(exc, val, tb); + Py_CLEAR(res); } end: @@ -671,11 +662,7 @@ static void _set_BlockingIOError(char *msg, Py_ssize_t written) { PyObject *err; -#ifdef Py_DEBUG - /* in debug mode, PyEval_EvalFrameEx() fails with an assertion error - if an exception is set when it is called */ PyErr_Clear(); -#endif err = PyObject_CallFunction(PyExc_BlockingIOError, "isn", errno, msg, written); if (err) @@ -870,16 +857,21 @@ buffered_flush(buffered *self, PyObject *args) return res; } +/*[clinic input] +_io._Buffered.peek + size: Py_ssize_t = 0 + / + +[clinic start generated code]*/ + static PyObject * -buffered_peek(buffered *self, PyObject *args) +_io__Buffered_peek_impl(buffered *self, Py_ssize_t size) +/*[clinic end generated code: output=ba7a097ca230102b input=37ffb97d06ff4adb]*/ { - Py_ssize_t n = 0; PyObject *res = NULL; CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "|n:peek", &n)) { - return NULL; - } + CHECK_CLOSED(self, "peek of closed file") if (!ENTER_BUFFERED(self)) return NULL; @@ -897,16 +889,19 @@ buffered_peek(buffered *self, PyObject *args) return res; } +/*[clinic input] +_io._Buffered.read + size as n: io_ssize_t = -1 + / +[clinic start generated code]*/ + static PyObject * -buffered_read(buffered *self, PyObject *args) +_io__Buffered_read_impl(buffered *self, Py_ssize_t n) +/*[clinic end generated code: output=f41c78bb15b9bbe9 input=c0939ec7f9e9354f]*/ { - Py_ssize_t n = -1; PyObject *res; CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) { - return NULL; - } if (n < -1) { PyErr_SetString(PyExc_ValueError, "read length must be positive or -1"); @@ -935,22 +930,28 @@ buffered_read(buffered *self, PyObject *args) return res; } +/*[clinic input] +_io._Buffered.read1 + size as n: Py_ssize_t + / +[clinic start generated code]*/ + static PyObject * -buffered_read1(buffered *self, PyObject *args) +_io__Buffered_read1_impl(buffered *self, Py_ssize_t n) +/*[clinic end generated code: output=bcc4fb4e54d103a3 input=8d2869c18b983184]*/ { - Py_ssize_t n, have, r; + Py_ssize_t have, r; PyObject *res = NULL; CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "n:read1", &n)) { - return NULL; - } - if (n < 0) { PyErr_SetString(PyExc_ValueError, "read length must be positive"); return NULL; } + + CHECK_CLOSED(self, "read of closed file") + if (n == 0) return PyBytes_FromStringAndSize(NULL, 0); @@ -986,32 +987,27 @@ buffered_read1(buffered *self, PyObject *args) } static PyObject * -buffered_readinto(buffered *self, PyObject *args) +_buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1) { - Py_buffer buf; Py_ssize_t n, written = 0, remaining; PyObject *res = NULL; CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "w*:readinto", &buf)) - return NULL; - n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); if (n > 0) { - if (n >= buf.len) { - memcpy(buf.buf, self->buffer + self->pos, buf.len); - self->pos += buf.len; - res = PyLong_FromSsize_t(buf.len); - goto end_unlocked; + if (n >= buffer->len) { + memcpy(buffer->buf, self->buffer + self->pos, buffer->len); + self->pos += buffer->len; + return PyLong_FromSsize_t(buffer->len); } - memcpy(buf.buf, self->buffer + self->pos, n); + memcpy(buffer->buf, self->buffer + self->pos, n); self->pos += n; written = n; } if (!ENTER_BUFFERED(self)) - goto end_unlocked; + return NULL; if (self->writable) { res = buffered_flush_and_rewind_unlocked(self); @@ -1023,26 +1019,32 @@ buffered_readinto(buffered *self, PyObject *args) _bufferedreader_reset_buf(self); self->pos = 0; - for (remaining = buf.len - written; + 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 *) buf.buf + written, + n = _bufferedreader_raw_read(self, (char *) buffer->buf + written, remaining); } - else { + + /* 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 *) buf.buf + written, + 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) { @@ -1052,16 +1054,47 @@ buffered_readinto(buffered *self, PyObject *args) } goto end; } + + /* At most one read in readinto1 mode */ + if (readinto1) { + written += n; + break; + } } res = PyLong_FromSsize_t(written); end: LEAVE_BUFFERED(self); -end_unlocked: - PyBuffer_Release(&buf); 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) { @@ -1173,15 +1206,18 @@ _buffered_readline(buffered *self, Py_ssize_t limit) return res; } +/*[clinic input] +_io._Buffered.readline + size: io_ssize_t = -1 + / +[clinic start generated code]*/ + static PyObject * -buffered_readline(buffered *self, PyObject *args) +_io__Buffered_readline_impl(buffered *self, Py_ssize_t size) +/*[clinic end generated code: output=24dd2aa6e33be83c input=ff1e0df821cb4e5c]*/ { - Py_ssize_t limit = -1; - CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit)) - return NULL; - return _buffered_readline(self, limit); + return _buffered_readline(self, size); } @@ -1199,17 +1235,21 @@ buffered_tell(buffered *self, PyObject *args) return PyLong_FromOff_t(pos); } +/*[clinic input] +_io._Buffered.seek + target as targetobj: object + whence: int = 0 + / +[clinic start generated code]*/ + static PyObject * -buffered_seek(buffered *self, PyObject *args) +_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence) +/*[clinic end generated code: output=7ae0e8dc46efdefb input=a9c4920bfcba6163]*/ { Py_off_t target, n; - int whence = 0; - PyObject *targetobj, *res = NULL; + PyObject *res = NULL; CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "O|i:seek", &targetobj, &whence)) { - return NULL; - } /* Do some error checking instead of trusting OS 'seek()' ** error detection, just in case. @@ -1291,17 +1331,19 @@ buffered_seek(buffered *self, PyObject *args) return res; } +/*[clinic input] +_io._Buffered.truncate + pos: object = None + / +[clinic start generated code]*/ + static PyObject * -buffered_truncate(buffered *self, PyObject *args) +_io__Buffered_truncate_impl(buffered *self, PyObject *pos) +/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/ { - PyObject *pos = Py_None; PyObject *res = NULL; CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) { - return NULL; - } - if (!ENTER_BUFFERED(self)) return NULL; @@ -1368,7 +1410,7 @@ buffered_repr(buffered *self) nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name); if (nameobj == NULL) { - if (PyErr_ExceptionMatches(PyExc_AttributeError)) + if (PyErr_ExceptionMatches(PyExc_Exception)) PyErr_Clear(); else return NULL; @@ -1386,29 +1428,27 @@ buffered_repr(buffered *self) * class BufferedReader */ -PyDoc_STRVAR(bufferedreader_doc, - "Create a new buffered reader using the given readable raw IO object."); - 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 -bufferedreader_init(buffered *self, PyObject *args, PyObject *kwds) +_io_BufferedReader___init___impl(buffered *self, PyObject *raw, + Py_ssize_t buffer_size) +/*[clinic end generated code: output=cddcfefa0ed294c4 input=fb887e06f11b4e48]*/ { - char *kwlist[] = {"raw", "buffer_size", NULL}; - Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; - PyObject *raw; - self->ok = 0; self->detached = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedReader", kwlist, - &raw, &buffer_size)) { - return -1; - } - if (_PyIOBase_check_readable(raw, Py_True) == NULL) return -1; @@ -1729,111 +1769,12 @@ _bufferedreader_peek_unlocked(buffered *self) self->pos = 0; return PyBytes_FromStringAndSize(self->buffer, r); } - -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}, - {"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}, - {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS}, - - {"read", (PyCFunction)buffered_read, METH_VARARGS}, - {"peek", (PyCFunction)buffered_peek, METH_VARARGS}, - {"read1", (PyCFunction)buffered_read1, METH_VARARGS}, - {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS}, - {"readline", (PyCFunction)buffered_readline, METH_VARARGS}, - {"seek", (PyCFunction)buffered_seek, METH_VARARGS}, - {"tell", (PyCFunction)buffered_tell, METH_NOARGS}, - {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS}, - {"__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_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - (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 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ - bufferedreader_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 */ - (initproc)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 */ -}; /* * class BufferedWriter */ -PyDoc_STRVAR(bufferedwriter_doc, - "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.\n" - ); - static void _bufferedwriter_reset_buf(buffered *self) { @@ -1841,21 +1782,26 @@ _bufferedwriter_reset_buf(buffered *self) 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 -bufferedwriter_init(buffered *self, PyObject *args, PyObject *kwds) +_io_BufferedWriter___init___impl(buffered *self, PyObject *raw, + Py_ssize_t buffer_size) +/*[clinic end generated code: output=c8942a020c0dee64 input=914be9b95e16007b]*/ { - char *kwlist[] = {"raw", "buffer_size", NULL}; - Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; - PyObject *raw; - self->ok = 0; self->detached = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedWriter", kwlist, - &raw, &buffer_size)) { - return -1; - } - if (_PyIOBase_check_writable(raw, Py_True) == NULL) return -1; @@ -1976,29 +1922,28 @@ _bufferedwriter_flush_unlocked(buffered *self) return NULL; } +/*[clinic input] +_io.BufferedWriter.write + buffer: Py_buffer + / +[clinic start generated code]*/ + static PyObject * -bufferedwriter_write(buffered *self, PyObject *args) +_io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer) +/*[clinic end generated code: output=7f8d1365759bfc6b input=dd87dd85fc7f8850]*/ { PyObject *res = NULL; - Py_buffer buf; Py_ssize_t written, avail, remaining; Py_off_t offset; CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "y*:write", &buf)) { - return NULL; - } - if (IS_CLOSED(self)) { PyErr_SetString(PyExc_ValueError, "write to closed file"); - PyBuffer_Release(&buf); return NULL; } - if (!ENTER_BUFFERED(self)) { - PyBuffer_Release(&buf); + if (!ENTER_BUFFERED(self)) return NULL; - } /* Fast path: the data to write can be fully buffered. */ if (!VALID_READ_BUFFER(self) && !VALID_WRITE_BUFFER(self)) { @@ -2006,15 +1951,15 @@ bufferedwriter_write(buffered *self, PyObject *args) self->raw_pos = 0; } avail = Py_SAFE_DOWNCAST(self->buffer_size - self->pos, Py_off_t, Py_ssize_t); - if (buf.len <= avail) { - memcpy(self->buffer + self->pos, buf.buf, buf.len); + 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 + buf.len); + ADJUST_POSITION(self, self->pos + buffer->len); if (self->pos > self->write_end) self->write_end = self->pos; - written = buf.len; + written = buffer->len; goto end; } @@ -2037,17 +1982,17 @@ bufferedwriter_write(buffered *self, PyObject *args) self->write_pos = 0; avail = Py_SAFE_DOWNCAST(self->buffer_size - self->write_end, Py_off_t, Py_ssize_t); - if (buf.len <= avail) { + if (buffer->len <= avail) { /* Everything can be buffered */ PyErr_Clear(); - memcpy(self->buffer + self->write_end, buf.buf, buf.len); - self->write_end += buf.len; - self->pos += buf.len; - written = buf.len; + 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, buf.buf, avail); + 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 @@ -2073,11 +2018,11 @@ bufferedwriter_write(buffered *self, PyObject *args) } /* Then write buf itself. At this point the buffer has been emptied. */ - remaining = buf.len; + remaining = buffer->len; written = 0; while (remaining > self->buffer_size) { Py_ssize_t n = _bufferedwriter_raw_write( - self, (char *) buf.buf + written, buf.len - written); + self, (char *) buffer->buf + written, buffer->len - written); if (n == -1) { goto error; } else if (n == -2) { @@ -2085,7 +2030,7 @@ bufferedwriter_write(buffered *self, PyObject *args) if (remaining > self->buffer_size) { /* Can't buffer everything, still buffer as much as possible */ memcpy(self->buffer, - (char *) buf.buf + written, self->buffer_size); + (char *) buffer->buf + written, self->buffer_size); self->raw_pos = 0; ADJUST_POSITION(self, self->buffer_size); self->write_end = self->buffer_size; @@ -2108,7 +2053,7 @@ bufferedwriter_write(buffered *self, PyObject *args) if (self->readable) _bufferedreader_reset_buf(self); if (remaining > 0) { - memcpy(self->buffer, (char *) buf.buf + written, remaining); + memcpy(self->buffer, (char *) buffer->buf + written, remaining); written += remaining; } self->write_pos = 0; @@ -2122,115 +2067,15 @@ bufferedwriter_write(buffered *self, PyObject *args) error: LEAVE_BUFFERED(self) - PyBuffer_Release(&buf); return res; } - -static PyMethodDef bufferedwriter_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}, - {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS}, - - {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS}, - {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS}, - {"flush", (PyCFunction)buffered_flush, METH_NOARGS}, - {"seek", (PyCFunction)buffered_seek, METH_VARARGS}, - {"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_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - (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 | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ - bufferedwriter_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 */ - (initproc)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 */ -}; - + /* * BufferedRWPair */ -PyDoc_STRVAR(bufferedrwpair_doc, - "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.\n" - ); - /* XXX The usefulness of this (compared to having two separate IO objects) is * questionable. */ @@ -2243,17 +2088,29 @@ typedef struct { PyObject *weakreflist; } rwpair; -static int -bufferedrwpair_init(rwpair *self, PyObject *args, PyObject *kwds) -{ - PyObject *reader, *writer; - Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; +/*[clinic input] +_io.BufferedRWPair.__init__ + reader: object + writer: object + buffer_size: Py_ssize_t(c_default="DEFAULT_BUFFER_SIZE") = DEFAULT_BUFFER_SIZE + / - if (!PyArg_ParseTuple(args, "OO|n:BufferedRWPair", &reader, &writer, - &buffer_size)) { - return -1; - } +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) @@ -2294,6 +2151,8 @@ 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); @@ -2303,9 +2162,14 @@ bufferedrwpair_dealloc(rwpair *self) static PyObject * _forward_call(buffered *self, _Py_Identifier *name, PyObject *args) { - PyObject *func = _PyObject_GetAttrId((PyObject *)self, name); - PyObject *ret; + 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; @@ -2340,6 +2204,12 @@ 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) { @@ -2367,12 +2237,18 @@ bufferedrwpair_writable(rwpair *self, PyObject *args) static PyObject * bufferedrwpair_close(rwpair *self, PyObject *args) { + PyObject *exc = NULL, *val, *tb; PyObject *ret = _forward_call(self->writer, &PyId_close, args); if (ret == NULL) - return NULL; - Py_DECREF(ret); - - return _forward_call(self->reader, &PyId_close, args); + PyErr_Fetch(&exc, &val, &tb); + else + Py_DECREF(ret); + ret = _forward_call(self->reader, &PyId_close, args); + if (exc != NULL) { + _PyErr_ChainExceptions(exc, val, tb); + Py_CLEAR(ret); + } + return ret; } static PyObject * @@ -2399,12 +2275,313 @@ bufferedrwpair_closed_get(rwpair *self, void *context) } 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_CLEAR(self->raw); + Py_INCREF(raw); + 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_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare */ + 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_FINALIZE, /*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}, + {"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}, + {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS}, + + _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_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare */ + (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 | Py_TPFLAGS_HAVE_FINALIZE, /*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}, + {"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}, + {"__getstate__", (PyCFunction)buffered_getstate, METH_NOARGS}, + + _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_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare */ + (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 | Py_TPFLAGS_HAVE_FINALIZE, /*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}, @@ -2447,7 +2624,7 @@ PyTypeObject PyBufferedRWPair_Type = { 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ - bufferedrwpair_doc, /* tp_doc */ + _io_BufferedRWPair___init____doc__, /* tp_doc */ (traverseproc)bufferedrwpair_traverse, /* tp_traverse */ (inquiry)bufferedrwpair_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -2462,7 +2639,7 @@ PyTypeObject PyBufferedRWPair_Type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ offsetof(rwpair, dict), /* tp_dictoffset */ - (initproc)bufferedrwpair_init, /* tp_init */ + _io_BufferedRWPair___init__, /* tp_init */ 0, /* tp_alloc */ PyType_GenericNew, /* tp_new */ 0, /* tp_free */ @@ -2476,62 +2653,7 @@ PyTypeObject PyBufferedRWPair_Type = { 0, /* tp_version_tag */ 0, /* tp_finalize */ }; - - - -/* - * BufferedRandom - */ - -PyDoc_STRVAR(bufferedrandom_doc, - "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.\n" - ); - -static int -bufferedrandom_init(buffered *self, PyObject *args, PyObject *kwds) -{ - char *kwlist[] = {"raw", "buffer_size", NULL}; - Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; - PyObject *raw; - - self->ok = 0; - self->detached = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|n:BufferedRandom", kwlist, - &raw, &buffer_size)) { - return -1; - } - 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_CLEAR(self->raw); - Py_INCREF(raw); - 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; -} static PyMethodDef bufferedrandom_methods[] = { /* BufferedIOMixin methods */ @@ -2547,15 +2669,16 @@ static PyMethodDef bufferedrandom_methods[] = { {"flush", (PyCFunction)buffered_flush, METH_NOARGS}, - {"seek", (PyCFunction)buffered_seek, METH_VARARGS}, + _IO__BUFFERED_SEEK_METHODDEF {"tell", (PyCFunction)buffered_tell, METH_NOARGS}, - {"truncate", (PyCFunction)buffered_truncate, METH_VARARGS}, - {"read", (PyCFunction)buffered_read, METH_VARARGS}, - {"read1", (PyCFunction)buffered_read1, METH_VARARGS}, - {"readinto", (PyCFunction)buffered_readinto, METH_VARARGS}, - {"readline", (PyCFunction)buffered_readline, METH_VARARGS}, - {"peek", (PyCFunction)buffered_peek, METH_VARARGS}, - {"write", (PyCFunction)bufferedwriter_write, METH_VARARGS}, + _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} }; @@ -2596,7 +2719,7 @@ PyTypeObject PyBufferedRandom_Type = { 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ - bufferedrandom_doc, /* tp_doc */ + _io_BufferedRandom___init____doc__, /* tp_doc */ (traverseproc)buffered_traverse, /* tp_traverse */ (inquiry)buffered_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -2611,7 +2734,7 @@ PyTypeObject PyBufferedRandom_Type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ offsetof(buffered, dict), /*tp_dictoffset*/ - (initproc)bufferedrandom_init, /* tp_init */ + _io_BufferedRandom___init__, /* tp_init */ 0, /* tp_alloc */ PyType_GenericNew, /* tp_new */ 0, /* tp_free */ diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index 54840bb88a25..31cc1f79a16d 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -2,12 +2,17 @@ #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 - char *buf; + PyObject *buf; Py_ssize_t pos; Py_ssize_t string_size; - size_t buf_size; PyObject *dict; PyObject *weakreflist; Py_ssize_t exports; @@ -18,6 +23,12 @@ typedef struct { 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) { \ @@ -33,40 +44,64 @@ typedef struct { 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 -get_line(bytesio *self, char **output) +scan_eol(bytesio *self, Py_ssize_t len) { - char *n; - const char *str_end; - Py_ssize_t len; + const char *start, *n; + Py_ssize_t maxlen; assert(self->buf != NULL); + assert(self->pos >= 0); - /* Move to the end of the line, up to the end of the string, s. */ - str_end = self->buf + self->string_size; - for (n = self->buf + self->pos; - n < str_end && *n != '\n'; - n++); - - /* Skip the newline character */ - if (n < str_end) - n++; - - /* Get the length from the current position to the end of the line. */ - len = n - (self->buf + self->pos); - *output = self->buf + self->pos; + 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); - self->pos += 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, *old_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); + old_buf = self->buf; + self->buf = new_buf; + Py_DECREF(old_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. */ @@ -75,8 +110,7 @@ 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 = self->buf_size; - char *new_buf = NULL; + size_t alloc = PyBytes_GET_SIZE(self->buf); assert(self->buf != NULL); @@ -104,13 +138,15 @@ resize_buffer(bytesio *self, size_t size) if (alloc > ((size_t)-1) / sizeof(char)) goto overflow; - new_buf = (char *)PyMem_Realloc(self->buf, alloc * sizeof(char)); - if (new_buf == NULL) { - PyErr_NoMemory(); - return -1; + + if (SHARED_BUF(self)) { + if (unshare_buffer(self, alloc) < 0) + return -1; + } + else { + if (_PyBytes_Resize(&self->buf, alloc) < 0) + return -1; } - self->buf_size = alloc; - self->buf = new_buf; return 0; @@ -125,12 +161,18 @@ resize_buffer(bytesio *self, size_t size) 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); - if ((size_t)self->pos + len > self->buf_size) { - if (resize_buffer(self, (size_t)self->pos + 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; } @@ -143,18 +185,18 @@ write_bytes(bytesio *self, const char *bytes, Py_ssize_t len) | | <--to pad-->|<---to write---> | 0 buf position */ - memset(self->buf + self->string_size, '\0', + 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(self->buf + self->pos, bytes, len); - self->pos += len; + 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 (self->string_size < self->pos) { - self->string_size = self->pos; + if ((size_t)self->string_size < endpos) { + self->string_size = endpos; } return len; @@ -171,40 +213,71 @@ bytesio_get_closed(bytesio *self) } } -PyDoc_STRVAR(readable_doc, -"readable() -> bool. Returns True if the IO object can be read."); +/*[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 -PyDoc_STRVAR(writable_doc, -"writable() -> bool. Returns True if the IO object can be written."); +Returns True if the IO object can be written. +[clinic start generated code]*/ -PyDoc_STRVAR(seekable_doc, -"seekable() -> bool. Returns True if the IO object can be seeked."); +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]*/ -/* Generic getter for the writable, readable and seekable properties */ static PyObject * -return_not_closed(bytesio *self) +_io_BytesIO_seekable_impl(bytesio *self) +/*[clinic end generated code: output=6b417f46dcc09b56 input=9421f65627a344dd]*/ { CHECK_CLOSED(self); Py_RETURN_TRUE; } -PyDoc_STRVAR(flush_doc, -"flush() -> None. Does nothing."); +/*[clinic input] +_io.BytesIO.flush + +Does nothing. +[clinic start generated code]*/ static PyObject * -bytesio_flush(bytesio *self) +_io_BytesIO_flush_impl(bytesio *self) +/*[clinic end generated code: output=187e3d781ca134a0 input=561ea490be4581a7]*/ { CHECK_CLOSED(self); Py_RETURN_NONE; } -PyDoc_STRVAR(getbuffer_doc, -"getbuffer() -> bytes.\n" -"\n" -"Get a read-write view over the contents of the BytesIO object."); +/*[clinic input] +_io.BytesIO.getbuffer + +Get a read-write view over the contents of the BytesIO object. +[clinic start generated code]*/ static PyObject * -bytesio_getbuffer(bytesio *self) +_io_BytesIO_getbuffer_impl(bytesio *self) +/*[clinic end generated code: output=72cd7c6e13aa09ed input=8f738ef615865176]*/ { PyTypeObject *type = &_PyBytesIOBuffer_Type; bytesiobuf *buf; @@ -222,59 +295,104 @@ bytesio_getbuffer(bytesio *self) return view; } -PyDoc_STRVAR(getval_doc, -"getvalue() -> bytes.\n" -"\n" -"Retrieve the entire contents of the BytesIO object."); +/*[clinic input] +_io.BytesIO.getvalue + +Retrieve the entire contents of the BytesIO object. +[clinic start generated code]*/ static PyObject * -bytesio_getvalue(bytesio *self) +_io_BytesIO_getvalue_impl(bytesio *self) +/*[clinic end generated code: output=b3f6a3233c8fd628 input=4b403ac0af3973ed]*/ { CHECK_CLOSED(self); - return PyBytes_FromStringAndSize(self->buf, self->string_size); + 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; } -PyDoc_STRVAR(isatty_doc, -"isatty() -> False.\n" -"\n" -"Always returns False since BytesIO objects are not connected\n" -"to a tty-like device."); +/*[clinic input] +_io.BytesIO.isatty + +Always returns False. + +BytesIO objects are not connected to a TTY-like device. +[clinic start generated code]*/ static PyObject * -bytesio_isatty(bytesio *self) +_io_BytesIO_isatty_impl(bytesio *self) +/*[clinic end generated code: output=df67712e669f6c8f input=6f97f0985d13f827]*/ { CHECK_CLOSED(self); Py_RETURN_FALSE; } -PyDoc_STRVAR(tell_doc, -"tell() -> current file position, an integer\n"); +/*[clinic input] +_io.BytesIO.tell + +Current file position, an integer. +[clinic start generated code]*/ static PyObject * -bytesio_tell(bytesio *self) +_io_BytesIO_tell_impl(bytesio *self) +/*[clinic end generated code: output=b54b0f93cd0e5e1d input=b106adf099cb3657]*/ { CHECK_CLOSED(self); return PyLong_FromSsize_t(self->pos); } -PyDoc_STRVAR(read_doc, -"read([size]) -> read at most size bytes, returned as a string.\n" -"\n" -"If the size argument is negative, read until EOF is reached.\n" -"Return an empty string at EOF."); +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 as arg: object = None + / + +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 * -bytesio_read(bytesio *self, PyObject *args) +_io_BytesIO_read_impl(bytesio *self, PyObject *arg) +/*[clinic end generated code: output=85dacb535c1e1781 input=cc7ba4a797bb1555]*/ { Py_ssize_t size, n; - char *output; - PyObject *arg = Py_None; CHECK_CLOSED(self); - if (!PyArg_ParseTuple(args, "|O:read", &arg)) - return NULL; - if (PyLong_Check(arg)) { size = PyLong_AsSsize_t(arg); if (size == -1 && PyErr_Occurred()) @@ -298,52 +416,48 @@ bytesio_read(bytesio *self, PyObject *args) size = 0; } - assert(self->buf != NULL); - output = self->buf + self->pos; - self->pos += size; - - return PyBytes_FromStringAndSize(output, size); + return read_bytes(self, size); } -PyDoc_STRVAR(read1_doc, -"read1(size) -> read at most size bytes, returned as a string.\n" -"\n" -"If the size argument is negative or omitted, read until EOF is reached.\n" -"Return an empty string at EOF."); +/*[clinic input] +_io.BytesIO.read1 + size: object + / + +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 * -bytesio_read1(bytesio *self, PyObject *n) +_io_BytesIO_read1(bytesio *self, PyObject *size) +/*[clinic end generated code: output=16021f5d0ac3d4e2 input=d4f40bb8f2f99418]*/ { - PyObject *arg, *res; - - arg = PyTuple_Pack(1, n); - if (arg == NULL) - return NULL; - res = bytesio_read(self, arg); - Py_DECREF(arg); - return res; + return _io_BytesIO_read_impl(self, size); } -PyDoc_STRVAR(readline_doc, -"readline([size]) -> next line from the file, as a string.\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 string at EOF.\n"); +/*[clinic input] +_io.BytesIO.readline + size as arg: object = None + / + +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 * -bytesio_readline(bytesio *self, PyObject *args) +_io_BytesIO_readline_impl(bytesio *self, PyObject *arg) +/*[clinic end generated code: output=1c2115534a4f9276 input=ca31f06de6eab257]*/ { Py_ssize_t size, n; - char *output; - PyObject *arg = Py_None; CHECK_CLOSED(self); - if (!PyArg_ParseTuple(args, "|O:readline", &arg)) - return NULL; - if (PyLong_Check(arg)) { size = PyLong_AsSsize_t(arg); if (size == -1 && PyErr_Occurred()) @@ -359,37 +473,33 @@ bytesio_readline(bytesio *self, PyObject *args) return NULL; } - n = get_line(self, &output); - - if (size >= 0 && size < n) { - size = n - size; - n -= size; - self->pos -= size; - } + n = scan_eol(self, size); - return PyBytes_FromStringAndSize(output, n); + return read_bytes(self, n); } -PyDoc_STRVAR(readlines_doc, -"readlines([size]) -> list of strings, 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.\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 * -bytesio_readlines(bytesio *self, PyObject *args) +_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; - PyObject *arg = Py_None; CHECK_CLOSED(self); - if (!PyArg_ParseTuple(args, "|O:readlines", &arg)) - return NULL; - if (PyLong_Check(arg)) { maxsize = PyLong_AsSsize_t(arg); if (maxsize == -1 && PyErr_Occurred()) @@ -410,7 +520,9 @@ bytesio_readlines(bytesio *self, PyObject *args) if (!result) return NULL; - while ((n = get_line(self, &output)) != 0) { + 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; @@ -422,6 +534,7 @@ bytesio_readlines(bytesio *self, PyObject *args) size += n; if (maxsize > 0 && size >= maxsize) break; + output += n; } return result; @@ -430,24 +543,27 @@ bytesio_readlines(bytesio *self, PyObject *args) return NULL; } -PyDoc_STRVAR(readinto_doc, -"readinto(bytearray) -> int. Read up to len(b) bytes into b.\n" -"\n" -"Returns number of bytes read (0 for EOF), or None if the object\n" -"is set not to block as has no data to read."); +/*[clinic input] +_io.BytesIO.readinto + buffer: Py_buffer(accept={rwbuffer}) + / + +Read up to len(buffer) bytes into buffer. + +Returns number of bytes read (0 for EOF), or None if the object +is set not to block as has no data to read. +[clinic start generated code]*/ static PyObject * -bytesio_readinto(bytesio *self, PyObject *buffer) +_io_BytesIO_readinto_impl(bytesio *self, Py_buffer *buffer) +/*[clinic end generated code: output=a5d407217dcf0639 input=71581f32635c3a31]*/ { - void *raw_buffer; Py_ssize_t len, n; CHECK_CLOSED(self); - if (PyObject_AsWriteBuffer(buffer, &raw_buffer, &len) == -1) - return NULL; - /* adjust invalid sizes */ + len = buffer->len; n = self->string_size - self->pos; if (len > n) { len = n; @@ -455,7 +571,7 @@ bytesio_readinto(bytesio *self, PyObject *buffer) len = 0; } - memcpy(raw_buffer, self->buf + self->pos, len); + 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; @@ -463,24 +579,26 @@ bytesio_readinto(bytesio *self, PyObject *buffer) return PyLong_FromSsize_t(len); } -PyDoc_STRVAR(truncate_doc, -"truncate([size]) -> int. 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.\n"); +/*[clinic input] +_io.BytesIO.truncate + size as arg: object = 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 * -bytesio_truncate(bytesio *self, PyObject *args) +_io_BytesIO_truncate_impl(bytesio *self, PyObject *arg) +/*[clinic end generated code: output=81e6be60e67ddd66 input=11ed1966835462ba]*/ { Py_ssize_t size; - PyObject *arg = Py_None; CHECK_CLOSED(self); CHECK_EXPORTS(self); - if (!PyArg_ParseTuple(args, "|O:truncate", &arg)) - return NULL; - if (PyLong_Check(arg)) { size = PyLong_AsSsize_t(arg); if (size == -1 && PyErr_Occurred()) @@ -514,49 +632,49 @@ bytesio_truncate(bytesio *self, PyObject *args) static PyObject * bytesio_iternext(bytesio *self) { - char *next; Py_ssize_t n; CHECK_CLOSED(self); - n = get_line(self, &next); + n = scan_eol(self, -1); - if (!next || n == 0) + if (n == 0) return NULL; - return PyBytes_FromStringAndSize(next, n); + return read_bytes(self, n); } -PyDoc_STRVAR(seek_doc, -"seek(pos, whence=0) -> int. 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."); +/*[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 * -bytesio_seek(bytesio *self, PyObject *args) +_io_BytesIO_seek_impl(bytesio *self, Py_ssize_t pos, int whence) +/*[clinic end generated code: output=c26204a68e9190e4 input=1e875e6ebc652948]*/ { - Py_ssize_t pos; - int mode = 0; - CHECK_CLOSED(self); - if (!PyArg_ParseTuple(args, "n|i:seek", &pos, &mode)) - return NULL; - - if (pos < 0 && mode == 0) { + if (pos < 0 && whence == 0) { PyErr_Format(PyExc_ValueError, "negative seek value %zd", pos); return NULL; } - /* mode 0: offset relative to beginning of the string. - mode 1: offset relative to current position. - mode 2: offset relative the end of the string. */ - if (mode == 1) { + /* 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"); @@ -564,7 +682,7 @@ bytesio_seek(bytesio *self, PyObject *args) } pos += self->pos; } - else if (mode == 2) { + else if (whence == 2) { if (pos > PY_SSIZE_T_MAX - self->string_size) { PyErr_SetString(PyExc_OverflowError, "new position too large"); @@ -572,9 +690,9 @@ bytesio_seek(bytesio *self, PyObject *args) } pos += self->string_size; } - else if (mode != 0) { + else if (whence != 0) { PyErr_Format(PyExc_ValueError, - "invalid whence (%i, should be 0, 1 or 2)", mode); + "invalid whence (%i, should be 0, 1 or 2)", whence); return NULL; } @@ -585,54 +703,63 @@ bytesio_seek(bytesio *self, PyObject *args) return PyLong_FromSsize_t(self->pos); } -PyDoc_STRVAR(write_doc, -"write(bytes) -> int. Write bytes to file.\n" -"\n" -"Return the number of bytes written."); +/*[clinic input] +_io.BytesIO.write + b: object + / + +Write bytes to file. + +Return the number of bytes written. +[clinic start generated code]*/ static PyObject * -bytesio_write(bytesio *self, PyObject *obj) +_io_BytesIO_write(bytesio *self, PyObject *b) +/*[clinic end generated code: output=53316d99800a0b95 input=f5ec7c8c64ed720a]*/ { Py_ssize_t n = 0; Py_buffer buf; - PyObject *result = NULL; CHECK_CLOSED(self); CHECK_EXPORTS(self); - if (PyObject_GetBuffer(obj, &buf, PyBUF_CONTIG_RO) < 0) + if (PyObject_GetBuffer(b, &buf, PyBUF_CONTIG_RO) < 0) return NULL; if (buf.len != 0) n = write_bytes(self, buf.buf, buf.len); - if (n >= 0) - result = PyLong_FromSsize_t(n); PyBuffer_Release(&buf); - return result; + return n >= 0 ? PyLong_FromSsize_t(n) : NULL; } -PyDoc_STRVAR(writelines_doc, -"writelines(sequence_of_strings) -> None. Write strings to the file.\n" -"\n" -"Note that newlines are not added. The sequence can be any iterable\n" -"object producing strings. This is equivalent to calling write() for\n" -"each string."); +/*[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 * -bytesio_writelines(bytesio *self, PyObject *v) +_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(v); + it = PyObject_GetIter(lines); if (it == NULL) return NULL; while ((item = PyIter_Next(it)) != NULL) { - ret = bytesio_write(self, item); + ret = _io_BytesIO_write(self, item); Py_DECREF(item); if (ret == NULL) { Py_DECREF(it); @@ -649,16 +776,18 @@ bytesio_writelines(bytesio *self, PyObject *v) Py_RETURN_NONE; } -PyDoc_STRVAR(close_doc, -"close() -> None. Disable all I/O operations."); +/*[clinic input] +_io.BytesIO.close + +Disable all I/O operations. +[clinic start generated code]*/ static PyObject * -bytesio_close(bytesio *self) +_io_BytesIO_close_impl(bytesio *self) +/*[clinic end generated code: output=1471bb9411af84a0 input=37e1f55556e61f60]*/ { - if (self->buf != NULL) { - PyMem_Free(self->buf); - self->buf = NULL; - } + CHECK_EXPORTS(self); + Py_CLEAR(self->buf); Py_RETURN_NONE; } @@ -680,7 +809,7 @@ bytesio_close(bytesio *self) static PyObject * bytesio_getstate(bytesio *self) { - PyObject *initvalue = bytesio_getvalue(self); + PyObject *initvalue = _io_BytesIO_getvalue_impl(self); PyObject *dict; PyObject *state; @@ -730,7 +859,7 @@ bytesio_setstate(bytesio *self, PyObject *state) /* Set the value of the internal buffer. If state[0] does not support the buffer protocol, bytesio_write will raise the appropriate TypeError. */ - result = bytesio_write(self, PyTuple_GET_ITEM(state, 0)); + result = _io_BytesIO_write(self, PyTuple_GET_ITEM(state, 0)); if (result == NULL) return NULL; Py_DECREF(result); @@ -788,10 +917,7 @@ bytesio_dealloc(bytesio *self) "deallocated BytesIO object has exported buffers"); PyErr_Print(); } - if (self->buf != NULL) { - PyMem_Free(self->buf); - self->buf = NULL; - } + Py_CLEAR(self->buf); Py_CLEAR(self->dict); if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) self); @@ -811,7 +937,7 @@ bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) /* tp_alloc initializes all the fields to zero. So we don't have to initialize them here. */ - self->buf = (char *)PyMem_Malloc(0); + self->buf = PyBytes_FromStringAndSize(NULL, 0); if (self->buf == NULL) { Py_DECREF(self); return PyErr_NoMemory(); @@ -820,27 +946,41 @@ bytesio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return (PyObject *)self; } -static int -bytesio_init(bytesio *self, PyObject *args, PyObject *kwds) -{ - char *kwlist[] = {"initial_bytes", NULL}; - PyObject *initvalue = NULL; +/*[clinic input] +_io.BytesIO.__init__ + initial_bytes as initvalue: object(c_default="NULL") = b'' - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:BytesIO", kwlist, - &initvalue)) - return -1; +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) { - PyObject *res; - res = bytesio_write(self, initvalue); - if (res == NULL) - return -1; - Py_DECREF(res); - self->pos = 0; + if (PyBytes_CheckExact(initvalue)) { + Py_INCREF(initvalue); + Py_XDECREF(self->buf); + 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; @@ -852,8 +992,8 @@ bytesio_sizeof(bytesio *self, void *unused) Py_ssize_t res; res = sizeof(bytesio); - if (self->buf) - res += self->buf_size; + if (self->buf && !SHARED_BUF(self)) + res += _PySys_GetSizeOf(self->buf); return PyLong_FromSsize_t(res); } @@ -872,6 +1012,8 @@ bytesio_clear(bytesio *self) } +#include "clinic/bytesio.c.h" + static PyGetSetDef bytesio_getsetlist[] = { {"closed", (getter)bytesio_get_closed, NULL, "True if the file is closed."}, @@ -879,36 +1021,30 @@ static PyGetSetDef bytesio_getsetlist[] = { }; static struct PyMethodDef bytesio_methods[] = { - {"readable", (PyCFunction)return_not_closed, METH_NOARGS, readable_doc}, - {"seekable", (PyCFunction)return_not_closed, METH_NOARGS, seekable_doc}, - {"writable", (PyCFunction)return_not_closed, METH_NOARGS, writable_doc}, - {"close", (PyCFunction)bytesio_close, METH_NOARGS, close_doc}, - {"flush", (PyCFunction)bytesio_flush, METH_NOARGS, flush_doc}, - {"isatty", (PyCFunction)bytesio_isatty, METH_NOARGS, isatty_doc}, - {"tell", (PyCFunction)bytesio_tell, METH_NOARGS, tell_doc}, - {"write", (PyCFunction)bytesio_write, METH_O, write_doc}, - {"writelines", (PyCFunction)bytesio_writelines, METH_O, writelines_doc}, - {"read1", (PyCFunction)bytesio_read1, METH_O, read1_doc}, - {"readinto", (PyCFunction)bytesio_readinto, METH_O, readinto_doc}, - {"readline", (PyCFunction)bytesio_readline, METH_VARARGS, readline_doc}, - {"readlines", (PyCFunction)bytesio_readlines, METH_VARARGS, readlines_doc}, - {"read", (PyCFunction)bytesio_read, METH_VARARGS, read_doc}, - {"getbuffer", (PyCFunction)bytesio_getbuffer, METH_NOARGS, getbuffer_doc}, - {"getvalue", (PyCFunction)bytesio_getvalue, METH_NOARGS, getval_doc}, - {"seek", (PyCFunction)bytesio_seek, METH_VARARGS, seek_doc}, - {"truncate", (PyCFunction)bytesio_truncate, METH_VARARGS, truncate_doc}, + _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 */ }; -PyDoc_STRVAR(bytesio_doc, -"BytesIO([buffer]) -> object\n" -"\n" -"Create a buffered I/O implementation using an in-memory bytes\n" -"buffer, ready for reading and writing."); - PyTypeObject PyBytesIO_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_io.BytesIO", /*tp_name*/ @@ -931,7 +1067,7 @@ PyTypeObject PyBytesIO_Type = { 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - bytesio_doc, /*tp_doc*/ + _io_BytesIO___init____doc__, /*tp_doc*/ (traverseproc)bytesio_traverse, /*tp_traverse*/ (inquiry)bytesio_clear, /*tp_clear*/ 0, /*tp_richcompare*/ @@ -946,7 +1082,7 @@ PyTypeObject PyBytesIO_Type = { 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ offsetof(bytesio, dict), /*tp_dictoffset*/ - (initproc)bytesio_init, /*tp_init*/ + _io_BytesIO___init__, /*tp_init*/ 0, /*tp_alloc*/ bytesio_new, /*tp_new*/ }; @@ -961,18 +1097,24 @@ PyTypeObject PyBytesIO_Type = { static int bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags) { - int ret; bytesio *b = (bytesio *) obj->source; + if (view == NULL) { - b->exports++; - return 0; + PyErr_SetString(PyExc_BufferError, + "bytesiobuf_getbuffer: view==NULL argument is obsolete"); + return -1; } - ret = PyBuffer_FillInfo(view, (PyObject*)obj, b->buf, b->string_size, - 0, flags); - if (ret >= 0) { - b->exports++; + if (SHARED_BUF(b)) { + if (unshare_buffer(b, b->string_size) < 0) + return -1; } - return ret; + + /* 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 diff --git a/Modules/_io/clinic/_iomodule.c.h b/Modules/_io/clinic/_iomodule.c.h new file mode 100644 index 000000000000..a3abb93cc793 --- /dev/null +++ b/Modules/_io/clinic/_iomodule.c.h @@ -0,0 +1,159 @@ +/*[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 IOError 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)_io_open, METH_VARARGS|METH_KEYWORDS, _io_open__doc__}, + +static PyObject * +_io_open_impl(PyModuleDef *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(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"file", "mode", "buffering", "encoding", "errors", "newline", "closefd", "opener", NULL}; + 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; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|sizzziO:open", _keywords, + &file, &mode, &buffering, &encoding, &errors, &newline, &closefd, &opener)) + goto exit; + return_value = _io_open_impl(module, file, mode, buffering, encoding, errors, newline, closefd, opener); + +exit: + return return_value; +} +/*[clinic end generated code: output=97cdc09bf68a8064 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h new file mode 100644 index 000000000000..437e27573082 --- /dev/null +++ b/Modules/_io/clinic/bufferedio.c.h @@ -0,0 +1,454 @@ +/*[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 (!PyArg_Parse(arg, "w*:readinto", &buffer)) + 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 (!PyArg_Parse(arg, "w*:readinto1", &buffer)) + 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)_io__Buffered_peek, METH_VARARGS, _io__Buffered_peek__doc__}, + +static PyObject * +_io__Buffered_peek_impl(buffered *self, Py_ssize_t size); + +static PyObject * +_io__Buffered_peek(buffered *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t size = 0; + + if (!PyArg_ParseTuple(args, "|n:peek", + &size)) + goto exit; + 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)_io__Buffered_read, METH_VARARGS, _io__Buffered_read__doc__}, + +static PyObject * +_io__Buffered_read_impl(buffered *self, Py_ssize_t n); + +static PyObject * +_io__Buffered_read(buffered *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t n = -1; + + if (!PyArg_ParseTuple(args, "|O&:read", + _PyIO_ConvertSsize_t, &n)) + goto exit; + return_value = _io__Buffered_read_impl(self, n); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io__Buffered_read1__doc__, +"read1($self, size, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED_READ1_METHODDEF \ + {"read1", (PyCFunction)_io__Buffered_read1, METH_O, _io__Buffered_read1__doc__}, + +static PyObject * +_io__Buffered_read1_impl(buffered *self, Py_ssize_t n); + +static PyObject * +_io__Buffered_read1(buffered *self, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_ssize_t n; + + if (!PyArg_Parse(arg, "n:read1", &n)) + goto exit; + 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 (!PyArg_Parse(arg, "w*:readinto", &buffer)) + 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 (!PyArg_Parse(arg, "w*:readinto1", &buffer)) + 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)_io__Buffered_readline, METH_VARARGS, _io__Buffered_readline__doc__}, + +static PyObject * +_io__Buffered_readline_impl(buffered *self, Py_ssize_t size); + +static PyObject * +_io__Buffered_readline(buffered *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t size = -1; + + if (!PyArg_ParseTuple(args, "|O&:readline", + _PyIO_ConvertSsize_t, &size)) + goto exit; + 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)_io__Buffered_seek, METH_VARARGS, _io__Buffered_seek__doc__}, + +static PyObject * +_io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence); + +static PyObject * +_io__Buffered_seek(buffered *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *targetobj; + int whence = 0; + + if (!PyArg_ParseTuple(args, "O|i:seek", + &targetobj, &whence)) + goto exit; + 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)_io__Buffered_truncate, METH_VARARGS, _io__Buffered_truncate__doc__}, + +static PyObject * +_io__Buffered_truncate_impl(buffered *self, PyObject *pos); + +static PyObject * +_io__Buffered_truncate(buffered *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *pos = Py_None; + + if (!PyArg_UnpackTuple(args, "truncate", + 0, 1, + &pos)) + goto exit; + 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 char *_keywords[] = {"raw", "buffer_size", NULL}; + PyObject *raw; + Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|n:BufferedReader", _keywords, + &raw, &buffer_size)) + goto exit; + 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 char *_keywords[] = {"raw", "buffer_size", NULL}; + PyObject *raw; + Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|n:BufferedWriter", _keywords, + &raw, &buffer_size)) + goto exit; + 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 (!PyArg_Parse(arg, "y*:write", &buffer)) + 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_ParseTuple(args, "OO|n:BufferedRWPair", + &reader, &writer, &buffer_size)) + goto exit; + 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 char *_keywords[] = {"raw", "buffer_size", NULL}; + PyObject *raw; + Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|n:BufferedRandom", _keywords, + &raw, &buffer_size)) + goto exit; + return_value = _io_BufferedRandom___init___impl((buffered *)self, raw, buffer_size); + +exit: + return return_value; +} +/*[clinic end generated code: output=2bbb5e239b4ffe6f input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/bytesio.c.h b/Modules/_io/clinic/bytesio.c.h new file mode 100644 index 000000000000..1ab1d65a653d --- /dev/null +++ b/Modules/_io/clinic/bytesio.c.h @@ -0,0 +1,422 @@ +/*[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=None, /)\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)_io_BytesIO_read, METH_VARARGS, _io_BytesIO_read__doc__}, + +static PyObject * +_io_BytesIO_read_impl(bytesio *self, PyObject *arg); + +static PyObject * +_io_BytesIO_read(bytesio *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *arg = Py_None; + + if (!PyArg_UnpackTuple(args, "read", + 0, 1, + &arg)) + goto exit; + return_value = _io_BytesIO_read_impl(self, arg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_BytesIO_read1__doc__, +"read1($self, size, /)\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)_io_BytesIO_read1, METH_O, _io_BytesIO_read1__doc__}, + +PyDoc_STRVAR(_io_BytesIO_readline__doc__, +"readline($self, size=None, /)\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)_io_BytesIO_readline, METH_VARARGS, _io_BytesIO_readline__doc__}, + +static PyObject * +_io_BytesIO_readline_impl(bytesio *self, PyObject *arg); + +static PyObject * +_io_BytesIO_readline(bytesio *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *arg = Py_None; + + if (!PyArg_UnpackTuple(args, "readline", + 0, 1, + &arg)) + goto exit; + return_value = _io_BytesIO_readline_impl(self, arg); + +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)_io_BytesIO_readlines, METH_VARARGS, _io_BytesIO_readlines__doc__}, + +static PyObject * +_io_BytesIO_readlines_impl(bytesio *self, PyObject *arg); + +static PyObject * +_io_BytesIO_readlines(bytesio *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *arg = Py_None; + + if (!PyArg_UnpackTuple(args, "readlines", + 0, 1, + &arg)) + goto exit; + 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 up to len(buffer) bytes into buffer.\n" +"\n" +"Returns number of bytes read (0 for EOF), or None if the object\n" +"is set not to block as 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 (!PyArg_Parse(arg, "w*:readinto", &buffer)) + 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)_io_BytesIO_truncate, METH_VARARGS, _io_BytesIO_truncate__doc__}, + +static PyObject * +_io_BytesIO_truncate_impl(bytesio *self, PyObject *arg); + +static PyObject * +_io_BytesIO_truncate(bytesio *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *arg = Py_None; + + if (!PyArg_UnpackTuple(args, "truncate", + 0, 1, + &arg)) + goto exit; + return_value = _io_BytesIO_truncate_impl(self, arg); + +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)_io_BytesIO_seek, METH_VARARGS, _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 *args) +{ + PyObject *return_value = NULL; + Py_ssize_t pos; + int whence = 0; + + if (!PyArg_ParseTuple(args, "n|i:seek", + &pos, &whence)) + goto exit; + 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 char *_keywords[] = {"initial_bytes", NULL}; + PyObject *initvalue = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:BytesIO", _keywords, + &initvalue)) + goto exit; + return_value = _io_BytesIO___init___impl((bytesio *)self, initvalue); + +exit: + return return_value; +} +/*[clinic end generated code: output=500ccc149587fac4 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/fileio.c.h b/Modules/_io/clinic/fileio.c.h new file mode 100644 index 000000000000..4a1205e933b7 --- /dev/null +++ b/Modules/_io/clinic/fileio.c.h @@ -0,0 +1,367 @@ +/*[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 char *_keywords[] = {"file", "mode", "closefd", "opener", NULL}; + PyObject *nameobj; + const char *mode = "r"; + int closefd = 1; + PyObject *opener = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|siO:FileIO", _keywords, + &nameobj, &mode, &closefd, &opener)) + goto exit; + 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 (!PyArg_Parse(arg, "w*:readinto", &buffer)) + 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)_io_FileIO_read, METH_VARARGS, _io_FileIO_read__doc__}, + +static PyObject * +_io_FileIO_read_impl(fileio *self, Py_ssize_t size); + +static PyObject * +_io_FileIO_read(fileio *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t size = -1; + + if (!PyArg_ParseTuple(args, "|O&:read", + _PyIO_ConvertSsize_t, &size)) + goto exit; + 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 bytes b to file, return number 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 (!PyArg_Parse(arg, "y*:write", &b)) + 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)_io_FileIO_seek, METH_VARARGS, _io_FileIO_seek__doc__}, + +static PyObject * +_io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence); + +static PyObject * +_io_FileIO_seek(fileio *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *pos; + int whence = 0; + + if (!PyArg_ParseTuple(args, "O|i:seek", + &pos, &whence)) + goto exit; + 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)_io_FileIO_truncate, METH_VARARGS, _io_FileIO_truncate__doc__}, + +static PyObject * +_io_FileIO_truncate_impl(fileio *self, PyObject *posobj); + +static PyObject * +_io_FileIO_truncate(fileio *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *posobj = NULL; + + if (!PyArg_UnpackTuple(args, "truncate", + 0, 1, + &posobj)) + goto exit; + 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=b1a20b10c81add64 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/iobase.c.h b/Modules/_io/clinic/iobase.c.h new file mode 100644 index 000000000000..3cea079d4545 --- /dev/null +++ b/Modules/_io/clinic/iobase.c.h @@ -0,0 +1,279 @@ +/*[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 UnsupportedOperation.\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 UnsupportedOperation."); + +#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 UnsupportedOperation."); + +#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" +"An IOError 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)_io__IOBase_readline, METH_VARARGS, _io__IOBase_readline__doc__}, + +static PyObject * +_io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit); + +static PyObject * +_io__IOBase_readline(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t limit = -1; + + if (!PyArg_ParseTuple(args, "|O&:readline", + _PyIO_ConvertSsize_t, &limit)) + goto exit; + 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)_io__IOBase_readlines, METH_VARARGS, _io__IOBase_readlines__doc__}, + +static PyObject * +_io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint); + +static PyObject * +_io__IOBase_readlines(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t hint = -1; + + if (!PyArg_ParseTuple(args, "|O&:readlines", + _PyIO_ConvertSsize_t, &hint)) + goto exit; + return_value = _io__IOBase_readlines_impl(self, hint); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io__IOBase_writelines__doc__, +"writelines($self, lines, /)\n" +"--\n" +"\n"); + +#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)_io__RawIOBase_read, METH_VARARGS, _io__RawIOBase_read__doc__}, + +static PyObject * +_io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n); + +static PyObject * +_io__RawIOBase_read(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t n = -1; + + if (!PyArg_ParseTuple(args, "|n:read", + &n)) + goto exit; + 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=fe034152b6884e65 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/stringio.c.h b/Modules/_io/clinic/stringio.c.h new file mode 100644 index 000000000000..a8e32a3376c5 --- /dev/null +++ b/Modules/_io/clinic/stringio.c.h @@ -0,0 +1,286 @@ +/*[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=None, /)\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)_io_StringIO_read, METH_VARARGS, _io_StringIO_read__doc__}, + +static PyObject * +_io_StringIO_read_impl(stringio *self, PyObject *arg); + +static PyObject * +_io_StringIO_read(stringio *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *arg = Py_None; + + if (!PyArg_UnpackTuple(args, "read", + 0, 1, + &arg)) + goto exit; + return_value = _io_StringIO_read_impl(self, arg); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io_StringIO_readline__doc__, +"readline($self, size=None, /)\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)_io_StringIO_readline, METH_VARARGS, _io_StringIO_readline__doc__}, + +static PyObject * +_io_StringIO_readline_impl(stringio *self, PyObject *arg); + +static PyObject * +_io_StringIO_readline(stringio *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *arg = Py_None; + + if (!PyArg_UnpackTuple(args, "readline", + 0, 1, + &arg)) + goto exit; + return_value = _io_StringIO_readline_impl(self, arg); + +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)_io_StringIO_truncate, METH_VARARGS, _io_StringIO_truncate__doc__}, + +static PyObject * +_io_StringIO_truncate_impl(stringio *self, PyObject *arg); + +static PyObject * +_io_StringIO_truncate(stringio *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *arg = Py_None; + + if (!PyArg_UnpackTuple(args, "truncate", + 0, 1, + &arg)) + goto exit; + return_value = _io_StringIO_truncate_impl(self, arg); + +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)_io_StringIO_seek, METH_VARARGS, _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 *args) +{ + PyObject *return_value = NULL; + Py_ssize_t pos; + int whence = 0; + + if (!PyArg_ParseTuple(args, "n|i:seek", + &pos, &whence)) + goto exit; + 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 char *_keywords[] = {"initial_value", "newline", NULL}; + PyObject *value = NULL; + PyObject *newline_obj = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO:StringIO", _keywords, + &value, &newline_obj)) + goto exit; + 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=f061cf3a20cd14ed input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/textio.c.h b/Modules/_io/clinic/textio.c.h new file mode 100644 index 000000000000..dc7e8c75847b --- /dev/null +++ b/Modules/_io/clinic/textio.c.h @@ -0,0 +1,456 @@ +/*[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 char *_keywords[] = {"decoder", "translate", "errors", NULL}; + PyObject *decoder; + int translate; + PyObject *errors = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|O:IncrementalNewlineDecoder", _keywords, + &decoder, &translate, &errors)) + goto exit; + 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)_io_IncrementalNewlineDecoder_decode, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"input", "final", NULL}; + PyObject *input; + int final = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:decode", _keywords, + &input, &final)) + goto exit; + 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, const char *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 char *_keywords[] = {"buffer", "encoding", "errors", "newline", "line_buffering", "write_through", NULL}; + PyObject *buffer; + const char *encoding = NULL; + const char *errors = NULL; + const char *newline = NULL; + int line_buffering = 0; + int write_through = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|zzzii:TextIOWrapper", _keywords, + &buffer, &encoding, &errors, &newline, &line_buffering, &write_through)) + goto exit; + return_value = _io_TextIOWrapper___init___impl((textio *)self, buffer, encoding, errors, newline, line_buffering, write_through); + +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 (!PyArg_Parse(arg, "U:write", &text)) + goto exit; + 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)_io_TextIOWrapper_read, METH_VARARGS, _io_TextIOWrapper_read__doc__}, + +static PyObject * +_io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n); + +static PyObject * +_io_TextIOWrapper_read(textio *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t n = -1; + + if (!PyArg_ParseTuple(args, "|O&:read", + _PyIO_ConvertSsize_t, &n)) + goto exit; + 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)_io_TextIOWrapper_readline, METH_VARARGS, _io_TextIOWrapper_readline__doc__}, + +static PyObject * +_io_TextIOWrapper_readline_impl(textio *self, Py_ssize_t size); + +static PyObject * +_io_TextIOWrapper_readline(textio *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t size = -1; + + if (!PyArg_ParseTuple(args, "|n:readline", + &size)) + goto exit; + 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)_io_TextIOWrapper_seek, METH_VARARGS, _io_TextIOWrapper_seek__doc__}, + +static PyObject * +_io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence); + +static PyObject * +_io_TextIOWrapper_seek(textio *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *cookieObj; + int whence = 0; + + if (!PyArg_ParseTuple(args, "O|i:seek", + &cookieObj, &whence)) + goto exit; + 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)_io_TextIOWrapper_truncate, METH_VARARGS, _io_TextIOWrapper_truncate__doc__}, + +static PyObject * +_io_TextIOWrapper_truncate_impl(textio *self, PyObject *pos); + +static PyObject * +_io_TextIOWrapper_truncate(textio *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *pos = Py_None; + + if (!PyArg_UnpackTuple(args, "truncate", + 0, 1, + &pos)) + goto exit; + 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=690608f85aab8ba5 input=a9049054013a1b77]*/ diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 0e1e709efd94..12e37bbbbe1e 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -43,6 +43,19 @@ #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]*/ + +/*[python input] +class io_ssize_t_converter(CConverter): + type = 'Py_ssize_t' + converter = '_PyIO_ConvertSsize_t' +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=d0a811d3cbfd1b33]*/ + typedef struct { PyObject_HEAD int fd; @@ -53,6 +66,7 @@ typedef struct { signed int seekable : 2; /* -1 means unknown */ unsigned int closefd : 1; char finalizing; + unsigned int blksize; PyObject *weakreflist; PyObject *dict; } fileio; @@ -106,9 +120,11 @@ internal_close(fileio *self) /* fd is accessible and someone else may have closed it */ if (_PyVerify_fd(fd)) { 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 } else { save_errno = errno; @@ -123,14 +139,31 @@ internal_close(fileio *self) 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 * -fileio_close(fileio *self) +_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_CallMethodId((PyObject*)&PyRawIOBase_Type, + &PyId_close, "O", self); if (!self->closefd) { self->fd = -1; - Py_RETURN_NONE; + return res; } + if (res == NULL) + PyErr_Fetch(&exc, &val, &tb); if (self->finalizing) { PyObject *r = fileio_dealloc_warn(self, (PyObject *) self); if (r) @@ -138,12 +171,12 @@ fileio_close(fileio *self) else PyErr_Clear(); } - errno = internal_close(self); - if (errno < 0) - return NULL; - - return _PyObject_CallMethodId((PyObject*)&PyRawIOBase_Type, - &PyId_close, "O", self); + rc = internal_close(self); + if (res == NULL) + _PyErr_ChainExceptions(exc, val, tb); + if (rc < 0) + Py_CLEAR(res); + return res; } static PyObject * @@ -161,6 +194,7 @@ fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->writable = 0; self->appending = 0; self->seekable = -1; + self->blksize = 0; self->closefd = 1; self->weakreflist = NULL; } @@ -168,57 +202,40 @@ fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return (PyObject *) self; } -/* On Unix, open will succeed for directories. - In Python, there should be no file objects referring to - directories, so we need a check. */ - -static int -dircheck(fileio* self, PyObject *nameobj) -{ -#if defined(HAVE_FSTAT) && defined(S_ISDIR) && defined(EISDIR) - struct stat buf; - if (self->fd < 0) - return 0; - if (fstat(self->fd, &buf) == 0 && S_ISDIR(buf.st_mode)) { - errno = EISDIR; - PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj); - return -1; - } -#endif - return 0; -} - -static int -check_fd(int fd) -{ -#if defined(HAVE_FSTAT) - struct stat buf; - if (!_PyVerify_fd(fd) || (fstat(fd, &buf) < 0 && errno == EBADF)) { - PyObject *exc; - char *msg = strerror(EBADF); - exc = PyObject_CallFunction(PyExc_OSError, "(is)", - EBADF, msg); - PyErr_SetObject(PyExc_OSError, exc); - Py_XDECREF(exc); - return -1; - } -#endif - return 0; -} - #ifdef O_CLOEXEC extern int _Py_open_cloexec_works; #endif +/*[clinic input] +_io.FileIO.__init__ + file as nameobj: object + mode: str = "r" + closefd: int(c_default="1") = 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 -fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) +_io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, + int closefd, PyObject *opener) +/*[clinic end generated code: output=23413f68e6484bbd input=193164e293d6c097]*/ { - fileio *self = (fileio *) oself; - static char *kwlist[] = {"file", "mode", "closefd", "opener", NULL}; const char *name = NULL; - PyObject *nameobj, *stringobj = NULL, *opener = Py_None; - char *mode = "r"; - char *s; + PyObject *stringobj = NULL; + const char *s; #ifdef MS_WINDOWS Py_UNICODE *widename = NULL; #endif @@ -226,15 +243,16 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) int rwa = 0, plus = 0; int flags = 0; int fd = -1; - int closefd = 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 async_err = 0; - assert(PyFileIO_Check(oself)); + assert(PyFileIO_Check(self)); if (self->fd >= 0) { if (self->closefd) { /* Have to close the existing file first. */ @@ -245,11 +263,6 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) self->fd = -1; } - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|siO:fileio", - kwlist, &nameobj, &mode, &closefd, - &opener)) - return -1; - if (PyFloat_Check(nameobj)) { PyErr_SetString(PyExc_TypeError, "integer argument expected, got float"); @@ -260,7 +273,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) if (fd < 0) { if (!PyErr_Occurred()) { PyErr_SetString(PyExc_ValueError, - "Negative filedescriptor"); + "negative file descriptor"); return -1; } PyErr_Clear(); @@ -268,15 +281,14 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) #ifdef MS_WINDOWS if (PyUnicode_Check(nameobj)) { - int rv = _PyUnicode_HasNULChars(nameobj); - if (rv) { - if (rv != -1) - PyErr_SetString(PyExc_TypeError, "embedded NUL character"); - return -1; - } - widename = PyUnicode_AsUnicode(nameobj); + Py_ssize_t length; + widename = PyUnicode_AsUnicodeAndSize(nameobj, &length); if (widename == NULL) return -1; + if (wcslen(widename) != length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + return -1; + } } else #endif if (fd < 0) @@ -360,8 +372,6 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) #endif if (fd >= 0) { - if (check_fd(fd)) - goto error; self->fd = fd; self->closefd = closefd; } @@ -375,15 +385,20 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) errno = 0; if (opener == Py_None) { - Py_BEGIN_ALLOW_THREADS + do { + Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS - if (widename != NULL) - self->fd = _wopen(widename, flags, 0666); - else + if (widename != NULL) + self->fd = _wopen(widename, flags, 0666); + else #endif - self->fd = open(name, flags, 0666); + self->fd = open(name, flags, 0666); + Py_END_ALLOW_THREADS + } while (self->fd < 0 && errno == EINTR && + !(async_err = PyErr_CheckSignals())); - Py_END_ALLOW_THREADS + if (async_err) + goto error; } else { PyObject *fdobj; @@ -421,8 +436,24 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) goto error; #endif } - if (dircheck(self, nameobj) < 0) + + self->blksize = DEFAULT_BUFFER_SIZE; + if (_Py_fstat(self->fd, &fdfstat) < 0) goto error; +#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_IOError, 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) */ @@ -493,37 +524,67 @@ err_closed(void) static PyObject * err_mode(char *action) { - PyErr_Format(IO_STATE->unsupported_operation, - "File not open for %s", 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 * -fileio_fileno(fileio *self) +_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 * -fileio_readable(fileio *self) +_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 * -fileio_writable(fileio *self) +_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 * -fileio_seekable(fileio *self) +_io_FileIO_seekable_impl(fileio *self) +/*[clinic end generated code: output=47909ca0a42e9287 input=c8e5554d2fd63c7f]*/ { if (self->fd < 0) return err_closed(); @@ -540,11 +601,19 @@ fileio_seekable(fileio *self) 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 * -fileio_readinto(fileio *self, PyObject *args) +_io_FileIO_readinto_impl(fileio *self, Py_buffer *buffer) +/*[clinic end generated code: output=b01a5a22c8415cb4 input=4721d7b68b154eaf]*/ { - Py_buffer pbuf; - Py_ssize_t n, len; + Py_ssize_t n; int err; if (self->fd < 0) @@ -552,48 +621,21 @@ fileio_readinto(fileio *self, PyObject *args) if (!self->readable) return err_mode("reading"); - if (!PyArg_ParseTuple(args, "w*", &pbuf)) - return NULL; - - if (_PyVerify_fd(self->fd)) { - len = pbuf.len; - Py_BEGIN_ALLOW_THREADS - errno = 0; -#ifdef MS_WINDOWS - if (len > INT_MAX) - len = INT_MAX; - n = read(self->fd, pbuf.buf, (int)len); -#else - n = read(self->fd, pbuf.buf, len); -#endif - Py_END_ALLOW_THREADS - } else - n = -1; + n = _Py_read(self->fd, buffer->buf, buffer->len); + /* copy errno because PyBuffer_Release() can indirectly modify it */ err = errno; - PyBuffer_Release(&pbuf); - if (n < 0) { - if (err == EAGAIN) + + if (n == -1) { + if (err == EAGAIN) { + PyErr_Clear(); Py_RETURN_NONE; - errno = err; - PyErr_SetFromErrno(PyExc_IOError); + } return NULL; } return PyLong_FromSsize_t(n); } -#ifndef HAVE_FSTAT - -static PyObject * -fileio_readall(fileio *self) -{ - _Py_IDENTIFIER(readall); - return _PyObject_CallMethodId((PyObject*)&PyRawIOBase_Type, - &PyId_readall, "O", self); -} - -#else - static size_t new_buffersize(fileio *self, size_t currentsize) { @@ -613,10 +655,20 @@ new_buffersize(fileio *self, size_t currentsize) 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 * -fileio_readall(fileio *self) +_io_FileIO_readall_impl(fileio *self) +/*[clinic end generated code: output=faa0292b213b4022 input=dbdc137f55602834]*/ { - struct stat st; + struct _Py_stat_struct status; Py_off_t pos, end; PyObject *result; Py_ssize_t bytes_read = 0; @@ -628,13 +680,16 @@ fileio_readall(fileio *self) if (!_PyVerify_fd(self->fd)) return PyErr_SetFromErrno(PyExc_IOError); + _Py_BEGIN_SUPPRESS_IPH #ifdef MS_WINDOWS pos = _lseeki64(self->fd, 0L, SEEK_CUR); #else pos = lseek(self->fd, 0L, SEEK_CUR); #endif - if (fstat(self->fd, &st) == 0) - end = st.st_size; + _Py_END_SUPPRESS_IPH + + if (_Py_fstat_noraise(self->fd, &status) == 0) + end = status.st_size; else end = (Py_off_t)-1; @@ -658,7 +713,7 @@ fileio_readall(fileio *self) if (bufsize > PY_SSIZE_T_MAX || bufsize <= 0) { PyErr_SetString(PyExc_OverflowError, "unbounded read returned more bytes " - "than a Python string can hold"); + "than a Python bytes object can hold"); Py_DECREF(result); return NULL; } @@ -668,35 +723,22 @@ fileio_readall(fileio *self) return NULL; } } - Py_BEGIN_ALLOW_THREADS - errno = 0; - n = bufsize - bytes_read; -#ifdef MS_WINDOWS - if (n > INT_MAX) - n = INT_MAX; - n = read(self->fd, PyBytes_AS_STRING(result) + bytes_read, (int)n); -#else - n = read(self->fd, PyBytes_AS_STRING(result) + bytes_read, n); -#endif - Py_END_ALLOW_THREADS + + n = _Py_read(self->fd, + PyBytes_AS_STRING(result) + bytes_read, + bufsize - bytes_read); + if (n == 0) break; - if (n < 0) { - if (errno == EINTR) { - if (PyErr_CheckSignals()) { - Py_DECREF(result); - return NULL; - } - continue; - } - if (bytes_read > 0) - break; + if (n == -1) { if (errno == EAGAIN) { + PyErr_Clear(); + if (bytes_read > 0) + break; Py_DECREF(result); Py_RETURN_NONE; } Py_DECREF(result); - PyErr_SetFromErrno(PyExc_IOError); return NULL; } bytes_read += n; @@ -710,14 +752,24 @@ fileio_readall(fileio *self) return result; } -#endif /* HAVE_FSTAT */ +/*[clinic input] +_io.FileIO.read + size: io_ssize_t = -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 * -fileio_read(fileio *self, PyObject *args) +_io_FileIO_read_impl(fileio *self, Py_ssize_t size) +/*[clinic end generated code: output=42528d39dd0ca641 input=5c6caa5490c13a9b]*/ { char *ptr; Py_ssize_t n; - Py_ssize_t size = -1; PyObject *bytes; if (self->fd < 0) @@ -725,41 +777,29 @@ fileio_read(fileio *self, PyObject *args) if (!self->readable) return err_mode("reading"); - if (!PyArg_ParseTuple(args, "|O&", &_PyIO_ConvertSsize_t, &size)) - return NULL; - - if (size < 0) { - return fileio_readall(self); - } + if (size < 0) + return _io_FileIO_readall_impl(self); #ifdef MS_WINDOWS + /* On Windows, the count parameter of read() is an int */ if (size > INT_MAX) size = INT_MAX; #endif + bytes = PyBytes_FromStringAndSize(NULL, size); if (bytes == NULL) return NULL; ptr = PyBytes_AS_STRING(bytes); - if (_PyVerify_fd(self->fd)) { - Py_BEGIN_ALLOW_THREADS - errno = 0; -#ifdef MS_WINDOWS - n = read(self->fd, ptr, (int)size); -#else - n = read(self->fd, ptr, size); -#endif - Py_END_ALLOW_THREADS - } else - n = -1; - - if (n < 0) { + 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) + if (err == EAGAIN) { + PyErr_Clear(); Py_RETURN_NONE; - errno = err; - PyErr_SetFromErrno(PyExc_IOError); + } return NULL; } @@ -773,11 +813,23 @@ fileio_read(fileio *self, PyObject *args) return (PyObject *) bytes; } +/*[clinic input] +_io.FileIO.write + b: Py_buffer + / + +Write bytes b to file, return number 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 * -fileio_write(fileio *self, PyObject *args) +_io_FileIO_write_impl(fileio *self, Py_buffer *b) +/*[clinic end generated code: output=b4059db3d363a2f7 input=ffbd8834f447ac31]*/ { - Py_buffer pbuf; - Py_ssize_t n, len; + Py_ssize_t n; int err; if (self->fd < 0) @@ -785,39 +837,15 @@ fileio_write(fileio *self, PyObject *args) if (!self->writable) return err_mode("writing"); - if (!PyArg_ParseTuple(args, "y*", &pbuf)) - return NULL; - - if (_PyVerify_fd(self->fd)) { - Py_BEGIN_ALLOW_THREADS - errno = 0; - len = pbuf.len; -#ifdef MS_WINDOWS - if (len > 32767 && isatty(self->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). */ - len = 32767; - } - else if (len > INT_MAX) - len = INT_MAX; - n = write(self->fd, pbuf.buf, (int)len); -#else - n = write(self->fd, pbuf.buf, len); -#endif - Py_END_ALLOW_THREADS - } else - n = -1; + n = _Py_write(self->fd, b->buf, b->len); + /* copy errno because PyBuffer_Release() can indirectly modify it */ err = errno; - PyBuffer_Release(&pbuf); - if (n < 0) { - if (err == EAGAIN) + if (err == EAGAIN) { + PyErr_Clear(); Py_RETURN_NONE; - errno = err; - PyErr_SetFromErrno(PyExc_IOError); + } return NULL; } @@ -865,11 +893,13 @@ portable_lseek(int fd, PyObject *posobj, int whence) if (_PyVerify_fd(fd)) { 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 } else res = -1; @@ -883,23 +913,44 @@ portable_lseek(int fd, PyObject *posobj, int whence) #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 * -fileio_seek(fileio *self, PyObject *args) +_io_FileIO_seek_impl(fileio *self, PyObject *pos, int whence) +/*[clinic end generated code: output=c976acdf054e6655 input=0439194b0774d454]*/ { - PyObject *posobj; - int whence = 0; - if (self->fd < 0) return err_closed(); - if (!PyArg_ParseTuple(args, "O|i", &posobj, &whence)) - return NULL; - - return portable_lseek(self->fd, posobj, whence); + return portable_lseek(self->fd, pos, whence); } +/*[clinic input] +_io.FileIO.tell + +Current file position. + +Can raise OSError for non seekable files. +[clinic start generated code]*/ + static PyObject * -fileio_tell(fileio *self, PyObject *args) +_io_FileIO_tell_impl(fileio *self) +/*[clinic end generated code: output=ffe2147058809d0b input=807e24ead4cec2f9]*/ { if (self->fd < 0) return err_closed(); @@ -908,13 +959,22 @@ fileio_tell(fileio *self, PyObject *args) } #ifdef HAVE_FTRUNCATE +/*[clinic input] +_io.FileIO.truncate + size as posobj: object = NULL + / + +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 * -fileio_truncate(fileio *self, PyObject *args) +_io_FileIO_truncate_impl(fileio *self, PyObject *posobj) +/*[clinic end generated code: output=e49ca7a916c176fa input=9026af44686b7318]*/ { - PyObject *posobj = NULL; /* the new size wanted by the user */ -#ifndef MS_WINDOWS Py_off_t pos; -#endif int ret; int fd; @@ -924,9 +984,6 @@ fileio_truncate(fileio *self, PyObject *args) if (!self->writable) return err_mode("writing"); - if (!PyArg_ParseTuple(args, "|O", &posobj)) - return NULL; - if (posobj == Py_None || posobj == NULL) { /* Get the current position. */ posobj = portable_lseek(fd, NULL, 1); @@ -937,52 +994,6 @@ fileio_truncate(fileio *self, PyObject *args) Py_INCREF(posobj); } -#ifdef MS_WINDOWS - /* MS _chsize doesn't work if newsize doesn't fit in 32 bits, - so don't even try using it. */ - { - PyObject *oldposobj, *tempposobj; - HANDLE hFile; - - /* we save the file pointer position */ - oldposobj = portable_lseek(fd, NULL, 1); - if (oldposobj == NULL) { - Py_DECREF(posobj); - return NULL; - } - - /* we then move to the truncation position */ - tempposobj = portable_lseek(fd, posobj, 0); - if (tempposobj == NULL) { - Py_DECREF(oldposobj); - Py_DECREF(posobj); - return NULL; - } - Py_DECREF(tempposobj); - - /* Truncate. Note that this may grow the file! */ - Py_BEGIN_ALLOW_THREADS - errno = 0; - hFile = (HANDLE)_get_osfhandle(fd); - ret = hFile == (HANDLE)-1; /* testing for INVALID_HANDLE value */ - if (ret == 0) { - ret = SetEndOfFile(hFile) == 0; - if (ret) - errno = EACCES; - } - Py_END_ALLOW_THREADS - - /* we restore the file pointer position in any case */ - tempposobj = portable_lseek(fd, oldposobj, 0); - Py_DECREF(oldposobj); - if (tempposobj == NULL) { - Py_DECREF(posobj); - return NULL; - } - Py_DECREF(tempposobj); - } -#else - #if defined(HAVE_LARGEFILE_SUPPORT) pos = PyLong_AsLongLong(posobj); #else @@ -994,12 +1005,16 @@ fileio_truncate(fileio *self, PyObject *args) } 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 -#endif /* !MS_WINDOWS */ - if (ret != 0) { Py_DECREF(posobj); PyErr_SetFromErrno(PyExc_IOError); @@ -1049,26 +1064,40 @@ fileio_repr(fileio *self) PyErr_Clear(); else return NULL; - res = PyUnicode_FromFormat("<_io.FileIO fd=%d mode='%s'>", - self->fd, mode_string(self)); + res = PyUnicode_FromFormat( + "<_io.FileIO fd=%d mode='%s' closefd=%s>", + self->fd, mode_string(self), self->closefd ? "True" : "False"); } else { - res = PyUnicode_FromFormat("<_io.FileIO name=%R mode='%s'>", - nameobj, mode_string(self)); + res = PyUnicode_FromFormat( + "<_io.FileIO name=%R mode='%s' closefd=%s>", + nameobj, mode_string(self), self->closefd ? "True" : "False"); 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 * -fileio_isatty(fileio *self) +_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 - res = isatty(self->fd); + _Py_BEGIN_SUPPRESS_IPH + if (_PyVerify_fd(self->fd)) + res = isatty(self->fd); + else + res = 0; + _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS return PyBool_FromLong(res); } @@ -1081,105 +1110,22 @@ fileio_getstate(fileio *self) return NULL; } - -PyDoc_STRVAR(fileio_doc, -"file(name: str[, mode: str][, opener: None]) -> file IO object\n" -"\n" -"Open a file. The mode can be 'r', 'w', 'x' or 'a' for reading (default),\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)."); - -PyDoc_STRVAR(read_doc, -"read(size: int) -> bytes. 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" -"On end-of-file, returns ''."); - -PyDoc_STRVAR(readall_doc, -"readall() -> bytes. 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. On end-of-file, returns ''."); - -PyDoc_STRVAR(write_doc, -"write(b: bytes) -> int. Write bytes b to file, return number 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."); - -PyDoc_STRVAR(fileno_doc, -"fileno() -> int. \"file descriptor\".\n" -"\n" -"This is needed for lower-level file interfaces, such the fcntl module."); - -PyDoc_STRVAR(seek_doc, -"seek(offset: int[, whence: int]) -> None. Move to new file position.\n" -"\n" -"Argument offset is a byte count. Optional argument whence defaults to\n" -"0 (offset from start of file, offset should be >= 0); other values are 1\n" -"(move relative to current position, positive or negative), and 2 (move\n" -"relative to end of file, usually negative, although many platforms allow\n" -"seeking beyond the end of a file)." -"\n" -"Note that not all file objects are seekable."); - -#ifdef HAVE_FTRUNCATE -PyDoc_STRVAR(truncate_doc, -"truncate([size: int]) -> None. Truncate the file to at most size bytes.\n" -"\n" -"Size defaults to the current file position, as returned by tell()." -"The current file position is changed to the value of size."); -#endif - -PyDoc_STRVAR(tell_doc, -"tell() -> int. Current file position"); - -PyDoc_STRVAR(readinto_doc, -"readinto() -> Same as RawIOBase.readinto()."); - -PyDoc_STRVAR(close_doc, -"close() -> None. 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. Changes the fileno to -1."); - -PyDoc_STRVAR(isatty_doc, -"isatty() -> bool. True if the file is connected to a tty device."); - -PyDoc_STRVAR(seekable_doc, -"seekable() -> bool. True if file supports random-access."); - -PyDoc_STRVAR(readable_doc, -"readable() -> bool. True if file was opened in a read mode."); - -PyDoc_STRVAR(writable_doc, -"writable() -> bool. True if file was opened in a write mode."); +#include "clinic/fileio.c.h" static PyMethodDef fileio_methods[] = { - {"read", (PyCFunction)fileio_read, METH_VARARGS, read_doc}, - {"readall", (PyCFunction)fileio_readall, METH_NOARGS, readall_doc}, - {"readinto", (PyCFunction)fileio_readinto, METH_VARARGS, readinto_doc}, - {"write", (PyCFunction)fileio_write, METH_VARARGS, write_doc}, - {"seek", (PyCFunction)fileio_seek, METH_VARARGS, seek_doc}, - {"tell", (PyCFunction)fileio_tell, METH_VARARGS, tell_doc}, -#ifdef HAVE_FTRUNCATE - {"truncate", (PyCFunction)fileio_truncate, METH_VARARGS, truncate_doc}, -#endif - {"close", (PyCFunction)fileio_close, METH_NOARGS, close_doc}, - {"seekable", (PyCFunction)fileio_seekable, METH_NOARGS, seekable_doc}, - {"readable", (PyCFunction)fileio_readable, METH_NOARGS, readable_doc}, - {"writable", (PyCFunction)fileio_writable, METH_NOARGS, writable_doc}, - {"fileno", (PyCFunction)fileio_fileno, METH_NOARGS, fileno_doc}, - {"isatty", (PyCFunction)fileio_isatty, METH_NOARGS, isatty_doc}, + _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}, {"__getstate__", (PyCFunction)fileio_getstate, METH_NOARGS, NULL}, {NULL, NULL} /* sentinel */ @@ -1208,12 +1154,13 @@ get_mode(fileio *self, void *closure) 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"}, + "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} }; @@ -1240,7 +1187,7 @@ PyTypeObject PyFileIO_Type = { 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ - fileio_doc, /* tp_doc */ + _io_FileIO___init____doc__, /* tp_doc */ (traverseproc)fileio_traverse, /* tp_traverse */ (inquiry)fileio_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -1255,7 +1202,7 @@ PyTypeObject PyFileIO_Type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ offsetof(fileio, dict), /* tp_dictoffset */ - fileio_init, /* tp_init */ + _io_FileIO___init__, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ fileio_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 1b7cb0ff7027..025007e40dc2 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -13,6 +13,20 @@ #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]*/ + +/*[python input] +class io_ssize_t_converter(CConverter): + type = 'Py_ssize_t' + converter = '_PyIO_ConvertSsize_t' +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=d0a811d3cbfd1b33]*/ + /* * IOBase class, an abstract class */ @@ -42,8 +56,8 @@ PyDoc_STRVAR(iobase_doc, "bytes. bytearrays are accepted too, and in some cases (such as\n" "readinto) needed. Text I/O classes work with str data.\n" "\n" - "Note that calling any method (even inquiries) on a closed stream is\n" - "undefined. Implementations may raise IOError in this case.\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" @@ -69,7 +83,9 @@ _Py_IDENTIFIER(read); static PyObject * iobase_unsupported(const char *message) { - PyErr_SetString(IO_STATE->unsupported_operation, message); + _PyIO_State *state = IO_STATE(); + if (state != NULL) + PyErr_SetString(state->unsupported_operation, message); return NULL; } @@ -94,11 +110,15 @@ iobase_seek(PyObject *self, PyObject *args) return iobase_unsupported("seek"); } -PyDoc_STRVAR(iobase_tell_doc, - "Return current stream position."); +/*[clinic input] +_io._IOBase.tell + +Return current stream position. +[clinic start generated code]*/ static PyObject * -iobase_tell(PyObject *self, PyObject *args) +_io__IOBase_tell_impl(PyObject *self) +/*[clinic end generated code: output=89a1c0807935abe2 input=04e615fec128801f]*/ { _Py_IDENTIFIER(seek); @@ -119,13 +139,17 @@ iobase_truncate(PyObject *self, PyObject *args) /* Flush and close methods */ -PyDoc_STRVAR(iobase_flush_doc, - "Flush write buffers, if applicable.\n" - "\n" - "This is not implemented for read-only and non-blocking streams.\n"); +/*[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 * -iobase_flush(PyObject *self, PyObject *args) +_io__IOBase_flush_impl(PyObject *self) +/*[clinic end generated code: output=7cef4b4d54656a3b input=773be121abe270aa]*/ { /* XXX Should this return the number of bytes written??? */ if (IS_CLOSED(self)) { @@ -135,11 +159,6 @@ iobase_flush(PyObject *self, PyObject *args) Py_RETURN_NONE; } -PyDoc_STRVAR(iobase_close_doc, - "Flush and close the IO object.\n" - "\n" - "This method has no effect if the file is already closed.\n"); - static int iobase_closed(PyObject *self) { @@ -178,8 +197,17 @@ _PyIOBase_check_closed(PyObject *self, PyObject *args) `__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 * -iobase_close(PyObject *self, PyObject *args) +_io__IOBase_close_impl(PyObject *self) +/*[clinic end generated code: output=63c6a6f57d783d6d input=f4494d5c31dbc6b7]*/ { PyObject *res; @@ -302,14 +330,18 @@ iobase_dealloc(iobase *self) /* Inquiry methods */ -PyDoc_STRVAR(iobase_seekable_doc, - "Return whether object supports random access.\n" - "\n" - "If False, seek(), tell() and truncate() will raise UnsupportedOperation.\n" - "This method may need to do a test seek()."); +/*[clinic input] +_io._IOBase.seekable + +Return whether object supports random access. + +If False, seek(), tell() and truncate() will raise UnsupportedOperation. +This method may need to do a test seek(). +[clinic start generated code]*/ static PyObject * -iobase_seekable(PyObject *self, PyObject *args) +_io__IOBase_seekable_impl(PyObject *self) +/*[clinic end generated code: output=4c24c67f5f32a43d input=22676eebb81dcf1e]*/ { Py_RETURN_FALSE; } @@ -331,13 +363,17 @@ _PyIOBase_check_seekable(PyObject *self, PyObject *args) return res; } -PyDoc_STRVAR(iobase_readable_doc, - "Return whether object was opened for reading.\n" - "\n" - "If False, read() will raise UnsupportedOperation."); +/*[clinic input] +_io._IOBase.readable + +Return whether object was opened for reading. + +If False, read() will raise UnsupportedOperation. +[clinic start generated code]*/ static PyObject * -iobase_readable(PyObject *self, PyObject *args) +_io__IOBase_readable_impl(PyObject *self) +/*[clinic end generated code: output=e48089250686388b input=12fc3d8f6be46434]*/ { Py_RETURN_FALSE; } @@ -360,13 +396,17 @@ _PyIOBase_check_readable(PyObject *self, PyObject *args) return res; } -PyDoc_STRVAR(iobase_writable_doc, - "Return whether object was opened for writing.\n" - "\n" - "If False, write() will raise UnsupportedOperation."); +/*[clinic input] +_io._IOBase.writable + +Return whether object was opened for writing. + +If False, write() will raise UnsupportedOperation. +[clinic start generated code]*/ static PyObject * -iobase_writable(PyObject *self, PyObject *args) +_io__IOBase_writable_impl(PyObject *self) +/*[clinic end generated code: output=406001d0985be14f input=c17a0bb6a8dfc590]*/ { Py_RETURN_FALSE; } @@ -411,24 +451,32 @@ iobase_exit(PyObject *self, PyObject *args) /* XXX Should these be present even if unimplemented? */ -PyDoc_STRVAR(iobase_fileno_doc, - "Returns underlying file descriptor if one exists.\n" - "\n" - "An IOError is raised if the IO object does not use a file descriptor.\n"); +/*[clinic input] +_io._IOBase.fileno + +Returns underlying file descriptor if one exists. + +An IOError is raised if the IO object does not use a file descriptor. +[clinic start generated code]*/ static PyObject * -iobase_fileno(PyObject *self, PyObject *args) +_io__IOBase_fileno_impl(PyObject *self) +/*[clinic end generated code: output=7cc0973f0f5f3b73 input=32773c5df4b7eede]*/ { return iobase_unsupported("fileno"); } -PyDoc_STRVAR(iobase_isatty_doc, - "Return whether this is an 'interactive' stream.\n" - "\n" - "Return False if it can't be determined.\n"); +/*[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 * -iobase_isatty(PyObject *self, PyObject *args) +_io__IOBase_isatty_impl(PyObject *self) +/*[clinic end generated code: output=60cab77cede41cdd input=9ef76530d368458b]*/ { if (_PyIOBase_check_closed(self, Py_True) == NULL) return NULL; @@ -437,30 +485,31 @@ iobase_isatty(PyObject *self, PyObject *args) /* Readline(s) and writelines */ -PyDoc_STRVAR(iobase_readline_doc, - "Read and return a line from the stream.\n" - "\n" - "If limit is specified, at most limit 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.\n"); +/*[clinic input] +_io._IOBase.readline + size as limit: io_ssize_t = -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 * -iobase_readline(PyObject *self, PyObject *args) +_io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit) +/*[clinic end generated code: output=4479f79b58187840 input=df4cc8884f553cab]*/ { /* For backwards compatibility, a (slowish) readline(). */ - Py_ssize_t limit = -1; int has_peek = 0; PyObject *buffer, *result; Py_ssize_t old_size = -1; _Py_IDENTIFIER(peek); - if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit)) { - return NULL; - } - if (_PyObject_HasAttrId(self, &PyId_peek)) has_peek = 1; @@ -583,23 +632,25 @@ iobase_iternext(PyObject *self) return line; } -PyDoc_STRVAR(iobase_readlines_doc, - "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."); +/*[clinic input] +_io._IOBase.readlines + hint: io_ssize_t = -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 * -iobase_readlines(PyObject *self, PyObject *args) +_io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) +/*[clinic end generated code: output=2f50421677fa3dea input=1961c4a95e96e661]*/ { - Py_ssize_t hint = -1, length = 0; + Py_ssize_t length = 0; PyObject *result; - if (!PyArg_ParseTuple(args, "|O&:readlines", &_PyIO_ConvertSsize_t, &hint)) { - return NULL; - } - result = PyList_New(0); if (result == NULL) return NULL; @@ -644,14 +695,17 @@ iobase_readlines(PyObject *self, PyObject *args) return result; } +/*[clinic input] +_io._IOBase.writelines + lines: object + / +[clinic start generated code]*/ + static PyObject * -iobase_writelines(PyObject *self, PyObject *args) +_io__IOBase_writelines(PyObject *self, PyObject *lines) +/*[clinic end generated code: output=976eb0a9b60a6628 input=432e729a8450b3cb]*/ { - PyObject *lines, *iter, *res; - - if (!PyArg_ParseTuple(args, "O:writelines", &lines)) { - return NULL; - } + PyObject *iter, *res; if (_PyIOBase_check_closed(self, Py_True) == NULL) return NULL; @@ -686,31 +740,33 @@ iobase_writelines(PyObject *self, PyObject *args) Py_RETURN_NONE; } +#include "clinic/iobase.c.h" + static PyMethodDef iobase_methods[] = { {"seek", iobase_seek, METH_VARARGS, iobase_seek_doc}, - {"tell", iobase_tell, METH_NOARGS, iobase_tell_doc}, + _IO__IOBASE_TELL_METHODDEF {"truncate", iobase_truncate, METH_VARARGS, iobase_truncate_doc}, - {"flush", iobase_flush, METH_NOARGS, iobase_flush_doc}, - {"close", iobase_close, METH_NOARGS, iobase_close_doc}, + _IO__IOBASE_FLUSH_METHODDEF + _IO__IOBASE_CLOSE_METHODDEF - {"seekable", iobase_seekable, METH_NOARGS, iobase_seekable_doc}, - {"readable", iobase_readable, METH_NOARGS, iobase_readable_doc}, - {"writable", iobase_writable, METH_NOARGS, iobase_writable_doc}, + _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}, - {"fileno", iobase_fileno, METH_NOARGS, iobase_fileno_doc}, - {"isatty", iobase_isatty, METH_NOARGS, iobase_isatty_doc}, + _IO__IOBASE_FILENO_METHODDEF + _IO__IOBASE_ISATTY_METHODDEF {"__enter__", iobase_enter, METH_NOARGS}, {"__exit__", iobase_exit, METH_VARARGS}, - {"readline", iobase_readline, METH_VARARGS, iobase_readline_doc}, - {"readlines", iobase_readlines, METH_VARARGS, iobase_readlines_doc}, - {"writelines", iobase_writelines, METH_VARARGS}, + _IO__IOBASE_READLINE_METHODDEF + _IO__IOBASE_READLINES_METHODDEF + _IO__IOBASE_WRITELINES_METHODDEF {NULL, NULL} }; @@ -793,16 +849,18 @@ PyDoc_STRVAR(rawiobase_doc, * either.) */ +/*[clinic input] +_io._RawIOBase.read + size as n: Py_ssize_t = -1 + / +[clinic start generated code]*/ + static PyObject * -rawiobase_read(PyObject *self, PyObject *args) +_io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n) +/*[clinic end generated code: output=6cdeb731e3c9f13c input=b6d0dcf6417d1374]*/ { - Py_ssize_t n = -1; PyObject *b, *res; - if (!PyArg_ParseTuple(args, "|n:read", &n)) { - return NULL; - } - if (n < 0) { _Py_IDENTIFIER(readall); @@ -834,11 +892,15 @@ rawiobase_read(PyObject *self, PyObject *args) } -PyDoc_STRVAR(rawiobase_readall_doc, - "Read until EOF, using multiple read() call."); +/*[clinic input] +_io._RawIOBase.readall + +Read until EOF, using multiple read() call. +[clinic start generated code]*/ static PyObject * -rawiobase_readall(PyObject *self, PyObject *args) +_io__RawIOBase_readall_impl(PyObject *self) +/*[clinic end generated code: output=1987b9ce929425a0 input=688874141213622a]*/ { int r; PyObject *chunks = PyList_New(0); @@ -890,9 +952,25 @@ rawiobase_readall(PyObject *self, PyObject *args) 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[] = { - {"read", rawiobase_read, METH_VARARGS}, - {"readall", rawiobase_readall, METH_NOARGS, rawiobase_readall_doc}, + _IO__RAWIOBASE_READ_METHODDEF + _IO__RAWIOBASE_READALL_METHODDEF + {"readinto", rawiobase_readinto, METH_VARARGS}, + {"write", rawiobase_write, METH_VARARGS}, {NULL, NULL} }; diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c index 9d73884f7317..73018a539071 100644 --- a/Modules/_io/stringio.c +++ b/Modules/_io/stringio.c @@ -11,6 +11,12 @@ #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; @@ -39,6 +45,8 @@ typedef struct { 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, \ @@ -58,12 +66,6 @@ typedef struct { return NULL; \ } -PyDoc_STRVAR(stringio_doc, - "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."); - /* Internal routine for changing the size, in terms of characters, of the buffer of StringIO objects. The caller should ensure that the 'size' @@ -264,11 +266,15 @@ write_str(stringio *self, PyObject *obj) return -1; } -PyDoc_STRVAR(stringio_getvalue_doc, - "Retrieve the entire contents of the object."); +/*[clinic input] +_io.StringIO.getvalue + +Retrieve the entire contents of the object. +[clinic start generated code]*/ static PyObject * -stringio_getvalue(stringio *self) +_io_StringIO_getvalue_impl(stringio *self) +/*[clinic end generated code: output=27b6a7bfeaebce01 input=d23cb81d6791cf88]*/ { CHECK_INITIALIZED(self); CHECK_CLOSED(self); @@ -278,33 +284,40 @@ stringio_getvalue(stringio *self) self->string_size); } -PyDoc_STRVAR(stringio_tell_doc, - "Tell the current file position."); +/*[clinic input] +_io.StringIO.tell + +Tell the current file position. +[clinic start generated code]*/ static PyObject * -stringio_tell(stringio *self) +_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); } -PyDoc_STRVAR(stringio_read_doc, - "Read at most n 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.\n"); +/*[clinic input] +_io.StringIO.read + size as arg: object = None + / + +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 * -stringio_read(stringio *self, PyObject *args) +_io_StringIO_read_impl(stringio *self, PyObject *arg) +/*[clinic end generated code: output=3676864773746f68 input=9a319015f6f3965c]*/ { Py_ssize_t size, n; Py_UCS4 *output; - PyObject *arg = Py_None; CHECK_INITIALIZED(self); - if (!PyArg_ParseTuple(args, "|O:read", &arg)) - return NULL; CHECK_CLOSED(self); if (PyNumber_Check(arg)) { @@ -373,20 +386,23 @@ _stringio_readline(stringio *self, Py_ssize_t limit) return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, start, len); } -PyDoc_STRVAR(stringio_readline_doc, - "Read until newline or EOF.\n" - "\n" - "Returns an empty string if EOF is hit immediately.\n"); +/*[clinic input] +_io.StringIO.readline + size as arg: object = None + / + +Read until newline or EOF. + +Returns an empty string if EOF is hit immediately. +[clinic start generated code]*/ static PyObject * -stringio_readline(stringio *self, PyObject *args) +_io_StringIO_readline_impl(stringio *self, PyObject *arg) +/*[clinic end generated code: output=99fdcac03a3dee81 input=e0e0ed4042040176]*/ { - PyObject *arg = Py_None; Py_ssize_t limit = -1; CHECK_INITIALIZED(self); - if (!PyArg_ParseTuple(args, "|O:readline", &arg)) - return NULL; CHECK_CLOSED(self); ENSURE_REALIZED(self); @@ -441,22 +457,25 @@ stringio_iternext(stringio *self) return line; } -PyDoc_STRVAR(stringio_truncate_doc, - "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.\n"); +/*[clinic input] +_io.StringIO.truncate + pos as arg: object = 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 * -stringio_truncate(stringio *self, PyObject *args) +_io_StringIO_truncate_impl(stringio *self, PyObject *arg) +/*[clinic end generated code: output=6072439c2b01d306 input=748619a494ba53ad]*/ { Py_ssize_t size; - PyObject *arg = Py_None; CHECK_INITIALIZED(self); - if (!PyArg_ParseTuple(args, "|O:truncate", &arg)) - return NULL; CHECK_CLOSED(self); if (PyNumber_Check(arg)) { @@ -490,49 +509,51 @@ stringio_truncate(stringio *self, PyObject *args) return PyLong_FromSsize_t(size); } -PyDoc_STRVAR(stringio_seek_doc, - "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.\n"); +/*[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 * -stringio_seek(stringio *self, PyObject *args) +_io_StringIO_seek_impl(stringio *self, Py_ssize_t pos, int whence) +/*[clinic end generated code: output=e9e0ac9a8ae71c25 input=e3855b24e7cae06a]*/ { - Py_ssize_t pos; - int mode = 0; - CHECK_INITIALIZED(self); - if (!PyArg_ParseTuple(args, "n|i:seek", &pos, &mode)) - return NULL; CHECK_CLOSED(self); - if (mode != 0 && mode != 1 && mode != 2) { + if (whence != 0 && whence != 1 && whence != 2) { PyErr_Format(PyExc_ValueError, - "Invalid whence (%i, should be 0, 1 or 2)", mode); + "Invalid whence (%i, should be 0, 1 or 2)", whence); return NULL; } - else if (pos < 0 && mode == 0) { + else if (pos < 0 && whence == 0) { PyErr_Format(PyExc_ValueError, "Negative seek position %zd", pos); return NULL; } - else if (mode != 0 && pos != 0) { + else if (whence != 0 && pos != 0) { PyErr_SetString(PyExc_IOError, "Can't do nonzero cur-relative seeks"); return NULL; } - /* mode 0: offset relative to beginning of the string. - mode 1: no change to current position. - mode 2: change position to end of file. */ - if (mode == 1) { + /* 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 (mode == 2) { + else if (whence == 2) { pos = self->string_size; } @@ -541,14 +562,20 @@ stringio_seek(stringio *self, PyObject *args) return PyLong_FromSsize_t(self->pos); } -PyDoc_STRVAR(stringio_write_doc, - "Write string to file.\n" - "\n" - "Returns the number of characters written, which is always equal to\n" - "the length of the string.\n"); +/*[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 * -stringio_write(stringio *self, PyObject *obj) +_io_StringIO_write(stringio *self, PyObject *obj) +/*[clinic end generated code: output=0deaba91a15b94da input=cf96f3b16586e669]*/ { Py_ssize_t size; @@ -569,14 +596,20 @@ stringio_write(stringio *self, PyObject *obj) return PyLong_FromSsize_t(size); } -PyDoc_STRVAR(stringio_close_doc, - "Close the IO object. Attempting any further operation after the\n" - "object is closed will raise a ValueError.\n" - "\n" - "This method has no effect if the file is already closed.\n"); +/*[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 * -stringio_close(stringio *self) +_io_StringIO_close_impl(stringio *self) +/*[clinic end generated code: output=04399355cbe518f1 input=cbc10b45f35d6d46]*/ { self->closed = 1; /* Free up some memory */ @@ -644,23 +677,27 @@ stringio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 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 -stringio_init(stringio *self, PyObject *args, PyObject *kwds) +_io_StringIO___init___impl(stringio *self, PyObject *value, + PyObject *newline_obj) +/*[clinic end generated code: output=a421ea023b22ef4e input=cee2d9181b2577a3]*/ { - char *kwlist[] = {"initial_value", "newline", NULL}; - PyObject *value = NULL; - PyObject *newline_obj = NULL; char *newline = "\n"; Py_ssize_t value_len; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:__init__", kwlist, - &value, &newline_obj)) - return -1; - - /* Parse the newline argument. This used to be done with the 'z' - specifier, however this allowed any object with the buffer interface to - be converted. Thus we have to parse it manually since we only want to - allow unicode objects or None. */ + /* Parse the newline argument. We only want to allow unicode objects or + None. */ if (newline_obj == Py_None) { newline = NULL; } @@ -711,7 +748,7 @@ stringio_init(stringio *self, PyObject *args, PyObject *kwds) /* 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.sepline, but it + (for newline == None, TextIOWrapper translates to os.linesep, but it is pointless for StringIO) */ if (newline != NULL && newline[0] == '\r') { @@ -761,33 +798,45 @@ stringio_init(stringio *self, PyObject *args, PyObject *kwds) /* Properties and pseudo-properties */ -PyDoc_STRVAR(stringio_readable_doc, -"readable() -> bool. Returns True if the IO object can be read."); +/*[clinic input] +_io.StringIO.readable -PyDoc_STRVAR(stringio_writable_doc, -"writable() -> bool. Returns True if the IO object can be written."); - -PyDoc_STRVAR(stringio_seekable_doc, -"seekable() -> bool. Returns True if the IO object can be seeked."); +Returns True if the IO object can be read. +[clinic start generated code]*/ static PyObject * -stringio_seekable(stringio *self, PyObject *args) +_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 * -stringio_readable(stringio *self, PyObject *args) +_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 * -stringio_writable(stringio *self, PyObject *args) +_io_StringIO_seekable_impl(stringio *self) +/*[clinic end generated code: output=4d20b4641c756879 input=4c606d05b32952e6]*/ { CHECK_INITIALIZED(self); CHECK_CLOSED(self); @@ -809,7 +858,7 @@ stringio_writable(stringio *self, PyObject *args) static PyObject * stringio_getstate(stringio *self) { - PyObject *initvalue = stringio_getvalue(self); + PyObject *initvalue = _io_StringIO_getvalue_impl(self); PyObject *dict; PyObject *state; @@ -857,7 +906,7 @@ stringio_setstate(stringio *self, PyObject *state) initarg = PyTuple_GetSlice(state, 0, 2); if (initarg == NULL) return NULL; - if (stringio_init(self, initarg, NULL) < 0) { + if (_io_StringIO___init__((PyObject *)self, initarg, NULL) < 0) { Py_DECREF(initarg); return NULL; } @@ -959,19 +1008,21 @@ stringio_newlines(stringio *self, void *context) return PyObject_GetAttr(self->decoder, _PyIO_str_newlines); } +#include "clinic/stringio.c.h" + static struct PyMethodDef stringio_methods[] = { - {"close", (PyCFunction)stringio_close, METH_NOARGS, stringio_close_doc}, - {"getvalue", (PyCFunction)stringio_getvalue, METH_NOARGS, stringio_getvalue_doc}, - {"read", (PyCFunction)stringio_read, METH_VARARGS, stringio_read_doc}, - {"readline", (PyCFunction)stringio_readline, METH_VARARGS, stringio_readline_doc}, - {"tell", (PyCFunction)stringio_tell, METH_NOARGS, stringio_tell_doc}, - {"truncate", (PyCFunction)stringio_truncate, METH_VARARGS, stringio_truncate_doc}, - {"seek", (PyCFunction)stringio_seek, METH_VARARGS, stringio_seek_doc}, - {"write", (PyCFunction)stringio_write, METH_O, stringio_write_doc}, - - {"seekable", (PyCFunction)stringio_seekable, METH_NOARGS, stringio_seekable_doc}, - {"readable", (PyCFunction)stringio_readable, METH_NOARGS, stringio_readable_doc}, - {"writable", (PyCFunction)stringio_writable, METH_NOARGS, stringio_writable_doc}, + _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}, @@ -1013,7 +1064,7 @@ PyTypeObject PyStringIO_Type = { 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - stringio_doc, /*tp_doc*/ + _io_StringIO___init____doc__, /*tp_doc*/ (traverseproc)stringio_traverse, /*tp_traverse*/ (inquiry)stringio_clear, /*tp_clear*/ 0, /*tp_richcompare*/ @@ -1028,7 +1079,7 @@ PyTypeObject PyStringIO_Type = { 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ offsetof(stringio, dict), /*tp_dictoffset*/ - (initproc)stringio_init, /*tp_init*/ + _io_StringIO___init__, /*tp_init*/ 0, /*tp_alloc*/ stringio_new, /*tp_new*/ }; diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index fb89a17927cd..c962c0ba082e 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -11,6 +11,20 @@ #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]*/ + +/*[python input] +class io_ssize_t_converter(CConverter): + type = 'Py_ssize_t' + converter = '_PyIO_ConvertSsize_t' +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=d0a811d3cbfd1b33]*/ + _Py_IDENTIFIER(close); _Py_IDENTIFIER(_dealloc_warn); _Py_IDENTIFIER(decode); @@ -45,7 +59,9 @@ PyDoc_STRVAR(textiobase_doc, static PyObject * _unsupported(const char *message) { - PyErr_SetString(IO_STATE->unsupported_operation, message); + _PyIO_State *state = IO_STATE(); + if (state != NULL) + PyErr_SetString(state->unsupported_operation, message); return NULL; } @@ -208,38 +224,37 @@ PyTypeObject PyTextIOBase_Type = { /* IncrementalNewlineDecoder */ -PyDoc_STRVAR(incrementalnewlinedecoder_doc, - "Codec used when reading a file in universal newlines mode. It wraps\n" - "another incremental decoder, translating \\r\\n and \\r into \\n. It also\n" - "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.\n" - ); - typedef struct { PyObject_HEAD PyObject *decoder; PyObject *errors; - signed int pendingcr: 1; - signed int translate: 1; + unsigned int pendingcr: 1; + unsigned int translate: 1; unsigned int seennl: 3; } nldecoder_object; -static int -incrementalnewlinedecoder_init(nldecoder_object *self, - PyObject *args, PyObject *kwds) -{ - PyObject *decoder; - int translate; - PyObject *errors = NULL; - char *kwlist[] = {"decoder", "translate", "errors", NULL}; +/*[clinic input] +_io.IncrementalNewlineDecoder.__init__ + decoder: object + translate: int + errors: object(c_default="NULL") = "strict" - if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oi|O:IncrementalNewlineDecoder", - kwlist, &decoder, &translate, &errors)) - return -1; +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); @@ -493,22 +508,27 @@ _PyIncrementalNewlineDecoder_decode(PyObject *myself, return NULL; } +/*[clinic input] +_io.IncrementalNewlineDecoder.decode + input: object + final: int(c_default="0") = False +[clinic start generated code]*/ + static PyObject * -incrementalnewlinedecoder_decode(nldecoder_object *self, - PyObject *args, PyObject *kwds) +_io_IncrementalNewlineDecoder_decode_impl(nldecoder_object *self, + PyObject *input, int final) +/*[clinic end generated code: output=0d486755bb37a66e input=d65677385bfd6827]*/ { - char *kwlist[] = {"input", "final", NULL}; - PyObject *input; - int final = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:IncrementalNewlineDecoder", - kwlist, &input, &final)) - return NULL; return _PyIncrementalNewlineDecoder_decode((PyObject *) self, input, final); } +/*[clinic input] +_io.IncrementalNewlineDecoder.getstate +[clinic start generated code]*/ + static PyObject * -incrementalnewlinedecoder_getstate(nldecoder_object *self, PyObject *args) +_io_IncrementalNewlineDecoder_getstate_impl(nldecoder_object *self) +/*[clinic end generated code: output=f0d2c9c136f4e0d0 input=f8ff101825e32e7f]*/ { PyObject *buffer; unsigned PY_LONG_LONG flag; @@ -518,7 +538,7 @@ incrementalnewlinedecoder_getstate(nldecoder_object *self, PyObject *args) _PyIO_str_getstate, NULL); if (state == NULL) return NULL; - if (!PyArg_Parse(state, "(OK)", &buffer, &flag)) { + if (!PyArg_ParseTuple(state, "OK", &buffer, &flag)) { Py_DECREF(state); return NULL; } @@ -535,16 +555,24 @@ incrementalnewlinedecoder_getstate(nldecoder_object *self, PyObject *args) return Py_BuildValue("NK", buffer, flag); } +/*[clinic input] +_io.IncrementalNewlineDecoder.setstate + state: object + / +[clinic start generated code]*/ + static PyObject * -incrementalnewlinedecoder_setstate(nldecoder_object *self, PyObject *state) +_io_IncrementalNewlineDecoder_setstate(nldecoder_object *self, + PyObject *state) +/*[clinic end generated code: output=c10c622508b576cb input=c53fb505a76dbbe2]*/ { PyObject *buffer; unsigned PY_LONG_LONG flag; - if (!PyArg_Parse(state, "(OK)", &buffer, &flag)) + if (!PyArg_ParseTuple(state, "OK", &buffer, &flag)) return NULL; - self->pendingcr = (int) flag & 1; + self->pendingcr = (int) (flag & 1); flag >>= 1; if (self->decoder != Py_None) @@ -554,8 +582,13 @@ incrementalnewlinedecoder_setstate(nldecoder_object *self, PyObject *state) Py_RETURN_NONE; } +/*[clinic input] +_io.IncrementalNewlineDecoder.reset +[clinic start generated code]*/ + static PyObject * -incrementalnewlinedecoder_reset(nldecoder_object *self, PyObject *args) +_io_IncrementalNewlineDecoder_reset_impl(nldecoder_object *self) +/*[clinic end generated code: output=32fa40c7462aa8ff input=728678ddaea776df]*/ { self->seennl = 0; self->pendingcr = 0; @@ -589,95 +622,8 @@ incrementalnewlinedecoder_newlines_get(nldecoder_object *self, void *context) } - -static PyMethodDef incrementalnewlinedecoder_methods[] = { - {"decode", (PyCFunction)incrementalnewlinedecoder_decode, METH_VARARGS|METH_KEYWORDS}, - {"getstate", (PyCFunction)incrementalnewlinedecoder_getstate, METH_NOARGS}, - {"setstate", (PyCFunction)incrementalnewlinedecoder_setstate, METH_O}, - {"reset", (PyCFunction)incrementalnewlinedecoder_reset, METH_NOARGS}, - {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_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare */ - 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*/ - incrementalnewlinedecoder_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 */ - (initproc)incrementalnewlinedecoder_init, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ -}; - - /* TextIOWrapper */ -PyDoc_STRVAR(textiowrapper_doc, - "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." - ); - typedef PyObject * (*encodefunc_t)(PyObject *, PyObject *); @@ -740,7 +686,6 @@ typedef struct PyObject *dict; } textio; - /* A couple of specialized cases in order to bypass the slow incremental encoding methods for the most popular encodings. */ @@ -841,28 +786,59 @@ static encodefuncentry encodefuncs[] = { }; -static int -textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) -{ - char *kwlist[] = {"buffer", "encoding", "errors", - "newline", "line_buffering", "write_through", - NULL}; - PyObject *buffer, *raw; - char *encoding = NULL; - char *errors = NULL; - char *newline = NULL; - int line_buffering = 0, write_through = 0; - _PyIO_State *state = IO_STATE; +/*[clinic input] +_io.TextIOWrapper.__init__ + buffer: object + encoding: str(accept={str, NoneType}) = NULL + errors: str(accept={str, NoneType}) = NULL + newline: str(accept={str, NoneType}) = NULL + line_buffering: int(c_default="0") = False + write_through: int(c_default="0") = 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, const char *errors, + const char *newline, int line_buffering, + int write_through) +/*[clinic end generated code: output=56a83402ce2a8381 input=3126cb3101a2c99b]*/ +{ + PyObject *raw, *codec_info = NULL; + _PyIO_State *state = NULL; PyObject *res; int r; self->ok = 0; self->detached = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|zzzii:fileio", - kwlist, &buffer, &encoding, &errors, - &newline, &line_buffering, &write_through)) - return -1; if (newline && newline[0] != '\0' && !(newline[0] == '\n' && newline[1] == '\0') @@ -891,6 +867,9 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) 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) { @@ -956,6 +935,17 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) "could not determine default encoding"); } + /* 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) + */ + if (errors == NULL) errors = "strict"; self->errors = PyBytes_FromString(errors); @@ -970,7 +960,7 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) if (newline) { self->readnl = PyUnicode_FromString(newline); if (self->readnl == NULL) - return -1; + goto error; } self->writetranslate = (newline == NULL || newline[0] != '\0'); if (!self->readuniversal && self->readnl) { @@ -994,8 +984,8 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) if (r == -1) goto error; if (r == 1) { - self->decoder = PyCodec_IncrementalDecoder( - encoding, errors); + self->decoder = _PyCodecInfo_GetIncrementalDecoder(codec_info, + errors); if (self->decoder == NULL) goto error; @@ -1019,17 +1009,12 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) if (r == -1) goto error; if (r == 1) { - PyObject *ci; - self->encoder = PyCodec_IncrementalEncoder( - encoding, errors); + self->encoder = _PyCodecInfo_GetIncrementalEncoder(codec_info, + errors); if (self->encoder == NULL) goto error; /* Get the normalized named of the codec */ - ci = _PyCodec_Lookup(encoding); - if (ci == NULL) - goto error; - res = _PyObject_GetAttrId(ci, &PyId_name); - Py_DECREF(ci); + res = _PyObject_GetAttrId(codec_info, &PyId_name); if (res == NULL) { if (PyErr_ExceptionMatches(PyExc_AttributeError)) PyErr_Clear(); @@ -1049,6 +1034,9 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) Py_XDECREF(res); } + /* Finished sorting out the codec details */ + Py_CLEAR(codec_info); + self->buffer = buffer; Py_INCREF(buffer); @@ -1111,6 +1099,7 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) return 0; error: + Py_XDECREF(codec_info); return -1; } @@ -1204,34 +1193,41 @@ textiowrapper_closed_get(textio *self, void *context); #define CHECK_INITIALIZED(self) \ if (self->ok <= 0) { \ - if (self->detached) { \ - PyErr_SetString(PyExc_ValueError, \ - "underlying buffer has been detached"); \ - } else { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - } \ + PyErr_SetString(PyExc_ValueError, \ + "I/O operation on uninitialized object"); \ return NULL; \ } -#define CHECK_INITIALIZED_INT(self) \ +#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) { \ - if (self->detached) { \ - PyErr_SetString(PyExc_ValueError, \ - "underlying buffer has been detached"); \ - } else { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - } \ + 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 * -textiowrapper_detach(textio *self) +_io_TextIOWrapper_detach_impl(textio *self) +/*[clinic end generated code: output=7ba3715cd032d5f2 input=e5a71fbda9e1d9f9]*/ { PyObject *buffer, *res; - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL); if (res == NULL) return NULL; @@ -1239,7 +1235,6 @@ textiowrapper_detach(textio *self) buffer = self->buffer; self->buffer = NULL; self->detached = 1; - self->ok = 0; return buffer; } @@ -1274,25 +1269,26 @@ _textiowrapper_writeflush(textio *self) return 0; } +/*[clinic input] +_io.TextIOWrapper.write + text: unicode + / +[clinic start generated code]*/ + static PyObject * -textiowrapper_write(textio *self, PyObject *args) +_io_TextIOWrapper_write_impl(textio *self, PyObject *text) +/*[clinic end generated code: output=d2deb0d50771fcec input=fdf19153584a0e44]*/ { PyObject *ret; - PyObject *text; /* owned reference */ PyObject *b; Py_ssize_t textlen; int haslf = 0; - int needflush = 0; - - CHECK_INITIALIZED(self); - - if (!PyArg_ParseTuple(args, "U:write", &text)) { - return NULL; - } + int needflush = 0, text_needflush = 0; if (PyUnicode_READY(text) == -1) return NULL; + CHECK_ATTACHED(self); CHECK_CLOSED(self); if (self->encoder == NULL) @@ -1316,8 +1312,8 @@ textiowrapper_write(textio *self, PyObject *args) } if (self->write_through) - needflush = 1; - else if (self->line_buffering && + text_needflush = 1; + if (self->line_buffering && (haslf || PyUnicode_FindChar(text, '\r', 0, PyUnicode_GET_LENGTH(text), 1) != -1)) needflush = 1; @@ -1348,7 +1344,8 @@ textiowrapper_write(textio *self, PyObject *args) } self->pending_bytes_count += PyBytes_GET_SIZE(b); Py_DECREF(b); - if (self->pending_bytes_count > self->chunk_size || needflush) { + if (self->pending_bytes_count > self->chunk_size || needflush || + text_needflush) { if (_textiowrapper_writeflush(self) < 0) return NULL; } @@ -1424,6 +1421,7 @@ 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; @@ -1451,7 +1449,16 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) /* Given this, we know there was a valid snapshot point * len(dec_buffer) bytes ago with decoder state (b'', dec_flags). */ - if (PyArg_Parse(state, "(OO)", &dec_buffer, &dec_flags) < 0) { + if (PyArg_ParseTuple(state, "OO", &dec_buffer, &dec_flags) < 0) { + Py_DECREF(state); + return -1; + } + + if (!PyBytes_Check(dec_buffer)) { + PyErr_Format(PyExc_TypeError, + "decoder getstate() should have returned a bytes " + "object, not '%.200s'", + Py_TYPE(dec_buffer)->tp_name); Py_DECREF(state); return -1; } @@ -1467,23 +1474,24 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t 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 (!PyBytes_Check(input_chunk)) { + + if (PyObject_GetBuffer(input_chunk, &input_chunk_buf, 0) != 0) { PyErr_Format(PyExc_TypeError, - "underlying %s() should have returned a bytes object, " + "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 = PyBytes_Size(input_chunk); + nbytes = input_chunk_buf.len; eof = (nbytes == 0); - if (Py_TYPE(self->decoder) == &PyIncrementalNewlineDecoder_Type) { decoded_chars = _PyIncrementalNewlineDecoder_decode( self->decoder, input_chunk, eof); @@ -1492,6 +1500,7 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) decoded_chars = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_decode, input_chunk, eof ? Py_True : Py_False, NULL); } + PyBuffer_Release(&input_chunk_buf); if (check_decoded(decoded_chars) < 0) goto fail; @@ -1508,18 +1517,12 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) /* 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 = PyNumber_Add(dec_buffer, input_chunk); - if (next_input == NULL) - goto fail; - if (!PyBytes_Check(next_input)) { - PyErr_Format(PyExc_TypeError, - "decoder getstate() should have returned a bytes " - "object, not '%.200s'", - Py_TYPE(next_input)->tp_name); - Py_DECREF(next_input); + PyObject *next_input = dec_buffer; + PyBytes_Concat(&next_input, input_chunk); + if (next_input == NULL) { + dec_buffer = NULL; /* Reference lost to PyBytes_Concat */ goto fail; } - Py_DECREF(dec_buffer); Py_CLEAR(self->snapshot); self->snapshot = Py_BuildValue("NN", dec_flags, next_input); } @@ -1534,17 +1537,19 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) return -1; } +/*[clinic input] +_io.TextIOWrapper.read + size as n: io_ssize_t = -1 + / +[clinic start generated code]*/ + static PyObject * -textiowrapper_read(textio *self, PyObject *args) +_io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n) +/*[clinic end generated code: output=7e651ce6cc6a25a6 input=8c09398424085cca]*/ { - Py_ssize_t n = -1; PyObject *result = NULL, *chunks = NULL; - CHECK_INITIALIZED(self); - - if (!PyArg_ParseTuple(args, "|O&:read", &_PyIO_ConvertSsize_t, &n)) - return NULL; - + CHECK_ATTACHED(self); CHECK_CLOSED(self); if (self->decoder == NULL) @@ -1708,7 +1713,7 @@ _PyIO_find_line_ending( else { /* Non-universal mode. */ Py_ssize_t readnl_len = PyUnicode_GET_LENGTH(readnl); - char *nl = PyUnicode_DATA(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) { @@ -1910,16 +1915,18 @@ _textiowrapper_readline(textio *self, Py_ssize_t limit) return NULL; } +/*[clinic input] +_io.TextIOWrapper.readline + size: Py_ssize_t = -1 + / +[clinic start generated code]*/ + static PyObject * -textiowrapper_readline(textio *self, PyObject *args) +_io_TextIOWrapper_readline_impl(textio *self, Py_ssize_t size) +/*[clinic end generated code: output=344afa98804e8b25 input=56c7172483b36db6]*/ { - Py_ssize_t limit = -1; - - CHECK_INITIALIZED(self); - if (!PyArg_ParseTuple(args, "|n:readline", &limit)) { - return NULL; - } - return _textiowrapper_readline(self, limit); + CHECK_ATTACHED(self); + return _textiowrapper_readline(self, size); } /* Seek and Tell */ @@ -2025,11 +2032,10 @@ _textiowrapper_decoder_setstate(textio *self, cookie_type *cookie) } static int -_textiowrapper_encoder_setstate(textio *self, cookie_type *cookie) +_textiowrapper_encoder_reset(textio *self, int start_of_stream) { PyObject *res; - /* Same as _textiowrapper_decoder_setstate() above. */ - if (cookie->start_pos == 0 && cookie->dec_flags == 0) { + if (start_of_stream) { res = PyObject_CallMethodObjArgs(self->encoder, _PyIO_str_reset, NULL); self->encoding_start_of_stream = 1; } @@ -2044,19 +2050,31 @@ _textiowrapper_encoder_setstate(textio *self, cookie_type *cookie) 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 * -textiowrapper_seek(textio *self, PyObject *args) +_io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) +/*[clinic end generated code: output=0a15679764e2d04d input=0458abeb3d7842be]*/ { - PyObject *cookieObj, *posobj; + PyObject *posobj; cookie_type cookie; - int whence = 0; PyObject *res; int cmp; - CHECK_INITIALIZED(self); - - if (!PyArg_ParseTuple(args, "O|i:seek", &cookieObj, &whence)) - return NULL; + CHECK_ATTACHED(self); CHECK_CLOSED(self); Py_INCREF(cookieObj); @@ -2111,7 +2129,17 @@ textiowrapper_seek(textio *self, PyObject *args) } res = _PyObject_CallMethodId(self->buffer, &PyId_seek, "ii", 0, 2); - Py_XDECREF(cookieObj); + 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, _PyIO_zero, Py_EQ); + if (cmp < 0 || _textiowrapper_encoder_reset(self, cmp)) { + Py_DECREF(res); + goto fail; + } + } return res; } else if (whence != 0) { @@ -2218,8 +2246,13 @@ textiowrapper_seek(textio *self, PyObject *args) } +/*[clinic input] +_io.TextIOWrapper.tell +[clinic start generated code]*/ + static PyObject * -textiowrapper_tell(textio *self, PyObject *args) +_io_TextIOWrapper_tell_impl(textio *self) +/*[clinic end generated code: output=4f168c08bf34ad5f input=9a2caf88c24f9ddf]*/ { PyObject *res; PyObject *posobj = NULL; @@ -2229,11 +2262,10 @@ textiowrapper_tell(textio *self, PyObject *args) Py_ssize_t skip_bytes, skip_back; PyObject *saved_state = NULL; char *input, *input_end; - char *dec_buffer; Py_ssize_t dec_buffer_len; int dec_flags; - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); CHECK_CLOSED(self); if (!self->seekable) { @@ -2272,7 +2304,7 @@ textiowrapper_tell(textio *self, PyObject *args) goto fail; /* Skip backward to the snapshot point (see _read_chunk). */ - if (!PyArg_Parse(self->snapshot, "(iO)", &cookie.dec_flags, &next_input)) + if (!PyArg_ParseTuple(self->snapshot, "iO", &cookie.dec_flags, &next_input)) goto fail; assert (PyBytes_Check(next_input)); @@ -2294,14 +2326,24 @@ textiowrapper_tell(textio *self, PyObject *args) 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 (!PyArg_Parse(_state, "(y#i)", &dec_buffer, &dec_buffer_len, &dec_flags)) { \ + if (!PyArg_ParseTuple(_state, "Oi", &dec_buffer, &dec_flags)) { \ + Py_DECREF(_state); \ + goto fail; \ + } \ + if (!PyBytes_Check(dec_buffer)) { \ + PyErr_Format(PyExc_TypeError, \ + "decoder getstate() should have returned 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) @@ -2418,28 +2460,27 @@ textiowrapper_tell(textio *self, PyObject *args) if (saved_state) { PyObject *type, *value, *traceback; PyErr_Fetch(&type, &value, &traceback); - res = _PyObject_CallMethodId(self->decoder, &PyId_setstate, "(O)", saved_state); + _PyErr_ChainExceptions(type, value, traceback); Py_DECREF(saved_state); - if (res == NULL) - return NULL; - Py_DECREF(res); - - PyErr_Restore(type, value, traceback); + Py_XDECREF(res); } return NULL; } +/*[clinic input] +_io.TextIOWrapper.truncate + pos: object = None + / +[clinic start generated code]*/ + static PyObject * -textiowrapper_truncate(textio *self, PyObject *args) +_io_TextIOWrapper_truncate_impl(textio *self, PyObject *pos) +/*[clinic end generated code: output=90ec2afb9bb7745f input=56ec8baa65aea377]*/ { - PyObject *pos = Py_None; PyObject *res; - CHECK_INITIALIZED(self) - if (!PyArg_ParseTuple(args, "|O:truncate", &pos)) { - return NULL; - } + CHECK_ATTACHED(self) res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_flush, NULL); if (res == NULL) @@ -2459,9 +2500,10 @@ textiowrapper_repr(textio *self) res = PyUnicode_FromString("<_io.TextIOWrapper"); if (res == NULL) return NULL; + nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name); if (nameobj == NULL) { - if (PyErr_ExceptionMatches(PyExc_AttributeError)) + if (PyErr_ExceptionMatches(PyExc_Exception)) PyErr_Clear(); else goto error; @@ -2477,7 +2519,7 @@ textiowrapper_repr(textio *self) } modeobj = _PyObject_GetAttrId((PyObject *) self, &PyId_mode); if (modeobj == NULL) { - if (PyErr_ExceptionMatches(PyExc_AttributeError)) + if (PyErr_ExceptionMatches(PyExc_Exception)) PyErr_Clear(); else goto error; @@ -2503,38 +2545,63 @@ textiowrapper_repr(textio *self) /* Inquiries */ +/*[clinic input] +_io.TextIOWrapper.fileno +[clinic start generated code]*/ + static PyObject * -textiowrapper_fileno(textio *self, PyObject *args) +_io_TextIOWrapper_fileno_impl(textio *self) +/*[clinic end generated code: output=21490a4c3da13e6c input=c488ca83d0069f9b]*/ { - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); return _PyObject_CallMethodId(self->buffer, &PyId_fileno, NULL); } +/*[clinic input] +_io.TextIOWrapper.seekable +[clinic start generated code]*/ + static PyObject * -textiowrapper_seekable(textio *self, PyObject *args) +_io_TextIOWrapper_seekable_impl(textio *self) +/*[clinic end generated code: output=ab223dbbcffc0f00 input=8b005ca06e1fca13]*/ { - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); return _PyObject_CallMethodId(self->buffer, &PyId_seekable, NULL); } +/*[clinic input] +_io.TextIOWrapper.readable +[clinic start generated code]*/ + static PyObject * -textiowrapper_readable(textio *self, PyObject *args) +_io_TextIOWrapper_readable_impl(textio *self) +/*[clinic end generated code: output=72ff7ba289a8a91b input=0704ea7e01b0d3eb]*/ { - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); return _PyObject_CallMethodId(self->buffer, &PyId_readable, NULL); } +/*[clinic input] +_io.TextIOWrapper.writable +[clinic start generated code]*/ + static PyObject * -textiowrapper_writable(textio *self, PyObject *args) +_io_TextIOWrapper_writable_impl(textio *self) +/*[clinic end generated code: output=a728c71790d03200 input=c41740bc9d8636e8]*/ { - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); return _PyObject_CallMethodId(self->buffer, &PyId_writable, NULL); } +/*[clinic input] +_io.TextIOWrapper.isatty +[clinic start generated code]*/ + static PyObject * -textiowrapper_isatty(textio *self, PyObject *args) +_io_TextIOWrapper_isatty_impl(textio *self) +/*[clinic end generated code: output=12be1a35bace882e input=fb68d9f2c99bbfff]*/ { - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); return _PyObject_CallMethodId(self->buffer, &PyId_isatty, NULL); } @@ -2546,10 +2613,15 @@ textiowrapper_getstate(textio *self, PyObject *args) return NULL; } +/*[clinic input] +_io.TextIOWrapper.flush +[clinic start generated code]*/ + static PyObject * -textiowrapper_flush(textio *self, PyObject *args) +_io_TextIOWrapper_flush_impl(textio *self) +/*[clinic end generated code: output=59de9165f9c2e4d2 input=928c60590694ab85]*/ { - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); CHECK_CLOSED(self); self->telling = self->seekable; if (_textiowrapper_writeflush(self) < 0) @@ -2557,12 +2629,17 @@ textiowrapper_flush(textio *self, PyObject *args) return _PyObject_CallMethodId(self->buffer, &PyId_flush, NULL); } +/*[clinic input] +_io.TextIOWrapper.close +[clinic start generated code]*/ + static PyObject * -textiowrapper_close(textio *self, PyObject *args) +_io_TextIOWrapper_close_impl(textio *self) +/*[clinic end generated code: output=056ccf8b4876e4f4 input=9c2114315eae1948]*/ { PyObject *res; int r; - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); res = textiowrapper_closed_get(self, NULL); if (res == NULL) @@ -2592,19 +2669,8 @@ textiowrapper_close(textio *self, PyObject *args) res = _PyObject_CallMethodId(self->buffer, &PyId_close, NULL); if (exc != NULL) { - if (res != NULL) { - Py_CLEAR(res); - PyErr_Restore(exc, val, tb); - } - else { - PyObject *val2; - Py_DECREF(exc); - Py_XDECREF(tb); - PyErr_Fetch(&exc, &val2, &tb); - PyErr_NormalizeException(&exc, &val2, &tb); - PyException_SetContext(val2, val); - PyErr_Restore(exc, val2, tb); - } + _PyErr_ChainExceptions(exc, val, tb); + Py_CLEAR(res); } return res; } @@ -2615,7 +2681,7 @@ textiowrapper_iternext(textio *self) { PyObject *line; - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); self->telling = 0; if (Py_TYPE(self) == &PyTextIOWrapper_Type) { @@ -2651,14 +2717,14 @@ textiowrapper_iternext(textio *self) static PyObject * textiowrapper_name_get(textio *self, void *context) { - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); return _PyObject_GetAttrId(self->buffer, &PyId_name); } static PyObject * textiowrapper_closed_get(textio *self, void *context) { - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); return PyObject_GetAttr(self->buffer, _PyIO_str_closed); } @@ -2666,7 +2732,7 @@ static PyObject * textiowrapper_newlines_get(textio *self, void *context) { PyObject *res; - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); if (self->decoder == NULL) Py_RETURN_NONE; res = PyObject_GetAttr(self->decoder, _PyIO_str_newlines); @@ -2692,7 +2758,7 @@ textiowrapper_errors_get(textio *self, void *context) static PyObject * textiowrapper_chunk_size_get(textio *self, void *context) { - CHECK_INITIALIZED(self); + CHECK_ATTACHED(self); return PyLong_FromSsize_t(self->chunk_size); } @@ -2700,7 +2766,7 @@ static int textiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context) { Py_ssize_t n; - CHECK_INITIALIZED_INT(self); + CHECK_ATTACHED_INT(self); n = PyNumber_AsSsize_t(arg, PyExc_ValueError); if (n == -1 && PyErr_Occurred()) return -1; @@ -2713,24 +2779,81 @@ textiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context) 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_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare */ + 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[] = { - {"detach", (PyCFunction)textiowrapper_detach, METH_NOARGS}, - {"write", (PyCFunction)textiowrapper_write, METH_VARARGS}, - {"read", (PyCFunction)textiowrapper_read, METH_VARARGS}, - {"readline", (PyCFunction)textiowrapper_readline, METH_VARARGS}, - {"flush", (PyCFunction)textiowrapper_flush, METH_NOARGS}, - {"close", (PyCFunction)textiowrapper_close, METH_NOARGS}, - - {"fileno", (PyCFunction)textiowrapper_fileno, METH_NOARGS}, - {"seekable", (PyCFunction)textiowrapper_seekable, METH_NOARGS}, - {"readable", (PyCFunction)textiowrapper_readable, METH_NOARGS}, - {"writable", (PyCFunction)textiowrapper_writable, METH_NOARGS}, - {"isatty", (PyCFunction)textiowrapper_isatty, METH_NOARGS}, + _IO_TEXTIOWRAPPER_DETACH_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 {"__getstate__", (PyCFunction)textiowrapper_getstate, METH_NOARGS}, - {"seek", (PyCFunction)textiowrapper_seek, METH_VARARGS}, - {"tell", (PyCFunction)textiowrapper_tell, METH_NOARGS}, - {"truncate", (PyCFunction)textiowrapper_truncate, METH_VARARGS}, + _IO_TEXTIOWRAPPER_SEEK_METHODDEF + _IO_TEXTIOWRAPPER_TELL_METHODDEF + _IO_TEXTIOWRAPPER_TRUNCATE_METHODDEF {NULL, NULL} }; @@ -2776,7 +2899,7 @@ PyTypeObject PyTextIOWrapper_Type = { 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ - textiowrapper_doc, /* tp_doc */ + _io_TextIOWrapper___init____doc__, /* tp_doc */ (traverseproc)textiowrapper_traverse, /* tp_traverse */ (inquiry)textiowrapper_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -2791,7 +2914,7 @@ PyTypeObject PyTextIOWrapper_Type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ offsetof(textio, dict), /*tp_dictoffset*/ - (initproc)textiowrapper_init, /* tp_init */ + _io_TextIOWrapper___init__, /* tp_init */ 0, /* tp_alloc */ PyType_GenericNew, /* tp_new */ 0, /* tp_free */ diff --git a/Modules/_json.c b/Modules/_json.c index 125101fa7c38..f63d758348d3 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -47,7 +47,7 @@ typedef struct _PyEncoderObject { PyObject *item_separator; PyObject *sort_keys; PyObject *skipkeys; - int fast_encode; + PyCFunction fast_encode; int allow_nan; } PyEncoderObject; @@ -182,17 +182,24 @@ ascii_escape_unicode(PyObject *pystr) /* Compute the output size */ for (i = 0, output_size = 2; i < input_chars; i++) { Py_UCS4 c = PyUnicode_READ(kind, input, i); - if (S_CHAR(c)) - output_size++; + 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': - output_size += 2; break; + d = 2; break; default: - output_size += c >= 0x10000 ? 12 : 6; + 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); @@ -218,26 +225,122 @@ ascii_escape_unicode(PyObject *pystr) 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(char *msg, PyObject *s, Py_ssize_t end) { - /* Use the Python function json.decoder.errmsg to raise a nice - looking ValueError exception */ - static PyObject *errmsg_fn = NULL; - PyObject *pymsg; - if (errmsg_fn == NULL) { + /* 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; - errmsg_fn = PyObject_GetAttrString(decoder, "errmsg"); + JSONDecodeError = PyObject_GetAttrString(decoder, "JSONDecodeError"); Py_DECREF(decoder); - if (errmsg_fn == NULL) + if (JSONDecodeError == NULL) return; } - pymsg = PyObject_CallFunction(errmsg_fn, "(zOn)", msg, s, end); - if (pymsg) { - PyErr_SetObject(PyExc_ValueError, pymsg); - Py_DECREF(pymsg); + exc = PyObject_CallFunction(JSONDecodeError, "(zOn)", msg, s, end); + if (exc) { + PyErr_SetObject(JSONDecodeError, exc); + Py_DECREF(exc); } } @@ -287,7 +390,7 @@ _build_rval_index_tuple(PyObject *rval, Py_ssize_t idx) { } \ } \ if (PyList_Append(chunks, chunk)) { \ - Py_DECREF(chunk); \ + Py_CLEAR(chunk); \ goto bail; \ } \ Py_CLEAR(chunk); \ @@ -530,6 +633,31 @@ py_encode_basestring_ascii(PyObject* self UNUSED, PyObject *pystr) 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) { @@ -588,6 +716,9 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss int has_pairs_hook = (s->object_pairs_hook != Py_None); Py_ssize_t next_idx; + if (strict < 0) + return NULL; + if (PyUnicode_READY(pystr) == -1) return NULL; @@ -705,7 +836,7 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss static PyObject * _parse_array_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { - /* Read a JSON array from PyString pystr. + /* 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. @@ -777,8 +908,8 @@ _parse_array_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssi } static PyObject * -_parse_constant(PyScannerObject *s, char *constant, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { - /* Read a JSON constant from PyString pystr. +_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 @@ -810,7 +941,7 @@ _match_number_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_ the number. Returns a new PyObject representation of that number: - PyInt, PyLong, or PyFloat. + PyLong, or PyFloat. May return other types if parse_int or parse_float are set */ void *str; @@ -933,6 +1064,7 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ void *str; int kind; Py_ssize_t length; + int strict; if (PyUnicode_READY(pystr) == -1) return NULL; @@ -941,6 +1073,10 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ 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; @@ -949,9 +1085,10 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_ switch (PyUnicode_READ(kind, str, idx)) { case '"': /* string */ - return scanstring_unicode(pystr, idx + 1, - PyObject_IsTrue(s->strict), - next_idx_ptr); + strict = PyObject_IsTrue(s->strict); + if (strict < 0) + return NULL; + return scanstring_unicode(pystr, idx + 1, strict, next_idx_ptr); case '{': /* object */ if (Py_EnterRecursiveCall(" while decoding a JSON object " @@ -1201,16 +1338,25 @@ encoder_init(PyObject *self, PyObject *args, PyObject *kwds) PyEncoderObject *s; PyObject *markers, *defaultfn, *encoder, *indent, *key_separator; - PyObject *item_separator, *sort_keys, *skipkeys, *allow_nan; + PyObject *item_separator, *sort_keys, *skipkeys; + int allow_nan; assert(PyEncoder_Check(self)); s = (PyEncoderObject *)self; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOOOOOO:make_encoder", kwlist, - &markers, &defaultfn, &encoder, &indent, &key_separator, &item_separator, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOUUOOp:make_encoder", kwlist, + &markers, &defaultfn, &encoder, &indent, + &key_separator, &item_separator, &sort_keys, &skipkeys, &allow_nan)) return -1; + 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 -1; + } + s->markers = markers; s->defaultfn = defaultfn; s->encoder = encoder; @@ -1219,8 +1365,15 @@ encoder_init(PyObject *self, PyObject *args, PyObject *kwds) s->item_separator = item_separator; s->sort_keys = sort_keys; s->skipkeys = skipkeys; - s->fast_encode = (PyCFunction_Check(s->encoder) && PyCFunction_GetFunction(s->encoder) == (PyCFunction)py_encode_basestring_ascii); - s->allow_nan = PyObject_IsTrue(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; + } + } + s->allow_nan = allow_nan; Py_INCREF(s->markers); Py_INCREF(s->defaultfn); @@ -1368,7 +1521,7 @@ encoder_encode_string(PyEncoderObject *s, PyObject *obj) { /* Return the JSON representation of a string */ if (s->fast_encode) - return py_encode_basestring_ascii(NULL, obj); + return s->fast_encode(NULL, obj); else return PyObject_CallFunctionObjArgs(s->encoder, obj, NULL); } @@ -1489,6 +1642,7 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, PyObject *items; PyObject *item = NULL; int skipkeys; + int sortkeys; Py_ssize_t idx; if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) { @@ -1530,40 +1684,19 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, */ } - if (PyObject_IsTrue(s->sort_keys)) { - /* First sort the keys then replace them with (key, value) tuples. */ - Py_ssize_t i, nitems; - items = PyMapping_Keys(dct); - if (items == NULL) - goto bail; - if (!PyList_Check(items)) { - PyErr_SetString(PyExc_ValueError, "keys must return list"); - goto bail; - } - if (PyList_Sort(items) < 0) - goto bail; - nitems = PyList_GET_SIZE(items); - for (i = 0; i < nitems; i++) { - PyObject *key, *value; - key = PyList_GET_ITEM(items, i); - value = PyDict_GetItem(dct, key); - item = PyTuple_Pack(2, key, value); - if (item == NULL) - goto bail; - PyList_SET_ITEM(items, i, item); - Py_DECREF(key); - } - } - else { - items = PyMapping_Items(dct); - } + items = PyMapping_Items(dct); if (items == NULL) goto bail; + sortkeys = PyObject_IsTrue(s->sort_keys); + if (sortkeys < 0 || (sortkeys && PyList_Sort(items) < 0)) + goto bail; it = PyObject_GetIter(items); Py_DECREF(items); if (it == NULL) goto bail; skipkeys = PyObject_IsTrue(s->skipkeys); + if (skipkeys < 0) + goto bail; idx = 0; while ((item = PyIter_Next(it)) != NULL) { PyObject *encoded, *key, *value; @@ -1835,6 +1968,10 @@ static PyMethodDef speedups_methods[] = { (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, @@ -1857,7 +1994,7 @@ static struct PyModuleDef jsonmodule = { NULL }; -PyObject* +PyMODINIT_FUNC PyInit__json(void) { PyObject *m = PyModule_Create(&jsonmodule); diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c index 400c3448baba..b1d6add477a6 100644 --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -254,7 +254,7 @@ PyLocale_strxfrm(PyObject* self, PyObject* args) /* assume no change in size, first */ n1 = n1 + 1; - buf = PyMem_Malloc(n1 * sizeof(wchar_t)); + buf = PyMem_New(wchar_t, n1); if (!buf) { PyErr_NoMemory(); goto exit; diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index 894788916d7e..66e534f2a843 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -202,6 +202,8 @@ normalizeUserObj(PyObject *obj) */ 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); @@ -213,9 +215,14 @@ normalizeUserObj(PyObject *obj) return res; } } + /* Otherwise, use __module__ */ PyErr_Clear(); - return PyUnicode_FromFormat("", - fn->m_ml->ml_name); + if (modname != NULL && PyUnicode_Check(modname)) + return PyUnicode_FromFormat("", + modname, fn->m_ml->ml_name); + else + return PyUnicode_FromFormat("", + fn->m_ml->ml_name); } } @@ -451,7 +458,6 @@ profiler_callback(PyObject *self, PyFrameObject *frame, int what, PyTrace_RETURN event will be generated, so we don't need to handle it. */ -#ifdef PyTrace_C_CALL /* not defined in Python <= 2.3 */ /* the Python function 'frame' is issuing a call to the built-in function 'arg' */ case PyTrace_C_CALL: @@ -473,7 +479,6 @@ profiler_callback(PyObject *self, PyFrameObject *frame, int what, ((PyCFunctionObject *)arg)->m_ml); } break; -#endif default: break; @@ -663,13 +668,7 @@ setBuiltins(ProfilerObject *pObj, int nvalue) if (nvalue == 0) pObj->flags &= ~POF_BUILTINS; else if (nvalue > 0) { -#ifndef PyTrace_C_CALL - PyErr_SetString(PyExc_ValueError, - "builtins=True requires Python >= 2.4"); - return -1; -#else pObj->flags |= POF_BUILTINS; -#endif } return 0; } @@ -767,11 +766,7 @@ profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw) PyObject *timer = NULL; double timeunit = 0.0; int subcalls = 1; -#ifdef PyTrace_C_CALL int builtins = 1; -#else - int builtins = 0; -#endif static char *kwlist[] = {"timer", "timeunit", "subcalls", "builtins", 0}; diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c index 1217ed4d1c09..7e4e2dfa8e9e 100644 --- a/Modules/_lzmamodule.c +++ b/Modules/_lzmamodule.c @@ -66,6 +66,9 @@ typedef struct { int check; char eof; PyObject *unused_data; + char needs_input; + uint8_t *input_buffer; + size_t input_buffer_size; #ifdef WITH_THREAD PyThread_type_lock lock; #endif @@ -142,10 +145,15 @@ PyLzma_Free(void *opaque, void *ptr) #endif static int -grow_buffer(PyObject **buf) +grow_buffer(PyObject **buf, Py_ssize_t max_length) { - size_t size = PyBytes_GET_SIZE(*buf); - return _PyBytes_Resize(buf, size + (size >> 3) + 6); + 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); } @@ -298,36 +306,37 @@ parse_filter_spec_bcj(PyObject *spec) return options; } -static void * -parse_filter_spec(lzma_filter *f, PyObject *spec) +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 NULL; + 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 NULL; + return 0; } f->id = PyLong_AsUnsignedLongLong(id_obj); Py_DECREF(id_obj); if (PyErr_Occurred()) - return NULL; + return 0; switch (f->id) { case LZMA_FILTER_LZMA1: case LZMA_FILTER_LZMA2: f->options = parse_filter_spec_lzma(spec); - return f->options; + return f->options != NULL; case LZMA_FILTER_DELTA: f->options = parse_filter_spec_delta(spec); - return f->options; + return f->options != NULL; case LZMA_FILTER_X86: case LZMA_FILTER_POWERPC: case LZMA_FILTER_IA64: @@ -335,10 +344,10 @@ parse_filter_spec(lzma_filter *f, PyObject *spec) case LZMA_FILTER_ARMTHUMB: case LZMA_FILTER_SPARC: f->options = parse_filter_spec_bcj(spec); - return f->options; + return f->options != NULL; default: PyErr_Format(PyExc_ValueError, "Invalid filter ID: %llu", f->id); - return NULL; + return 0; } } @@ -369,7 +378,7 @@ parse_filter_chain_spec(lzma_filter filters[], PyObject *filterspecs) for (i = 0; i < num_filters; i++) { int ok = 1; PyObject *spec = PySequence_GetItem(filterspecs, i); - if (spec == NULL || parse_filter_spec(&filters[i], spec) == NULL) + if (spec == NULL || !lzma_filter_converter(spec, &filters[i])) ok = 0; Py_XDECREF(spec); if (!ok) { @@ -468,12 +477,41 @@ build_filter_spec(const lzma_filter *f) } +/*[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) { - size_t data_size = 0; + Py_ssize_t data_size = 0; PyObject *result; result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE); @@ -496,7 +534,7 @@ compress(Compressor *c, uint8_t *data, size_t len, lzma_action action) (action == LZMA_FINISH && lzret == LZMA_STREAM_END)) { break; } else if (c->lzs.avail_out == 0) { - if (grow_buffer(&result) == -1) + 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; @@ -512,44 +550,51 @@ compress(Compressor *c, uint8_t *data, size_t len, lzma_action action) return NULL; } -PyDoc_STRVAR(Compressor_compress_doc, -"compress(data) -> bytes\n" -"\n" -"Provide data to the compressor object. Returns a chunk of\n" -"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 conversion process.\n"); +/*[clinic input] +_lzma.LZMACompressor.compress + + self: self(type="Compressor *") + 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 * -Compressor_compress(Compressor *self, PyObject *args) +_lzma_LZMACompressor_compress_impl(Compressor *self, Py_buffer *data) +/*[clinic end generated code: output=31f615136963e00f input=8b60cb13e0ce6420]*/ { - Py_buffer buffer; PyObject *result = NULL; - if (!PyArg_ParseTuple(args, "y*:compress", &buffer)) - return NULL; - ACQUIRE_LOCK(self); if (self->flushed) PyErr_SetString(PyExc_ValueError, "Compressor has been flushed"); else - result = compress(self, buffer.buf, buffer.len, LZMA_RUN); + result = compress(self, data->buf, data->len, LZMA_RUN); RELEASE_LOCK(self); - PyBuffer_Release(&buffer); return result; } -PyDoc_STRVAR(Compressor_flush_doc, -"flush() -> bytes\n" -"\n" -"Finish the compression process. Returns the compressed data left\n" -"in internal buffers.\n" -"\n" -"The compressor object cannot be used after this method is called.\n"); +/*[clinic input] +_lzma.LZMACompressor.flush + + self: self(type="Compressor *") + +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 * -Compressor_flush(Compressor *self, PyObject *noargs) +_lzma_LZMACompressor_flush_impl(Compressor *self) +/*[clinic end generated code: output=fec21f3e22504f50 input=3060fb26f9b4042c]*/ { PyObject *result = NULL; @@ -650,6 +695,39 @@ Compressor_init_raw(lzma_stream *lzs, PyObject *filterspecs) return 0; } +/*[-clinic input] +_lzma.LZMACompressor.__init__ + + self: self(type="Compressor *") + 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 suport 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) { @@ -739,10 +817,8 @@ Compressor_dealloc(Compressor *self) } static PyMethodDef Compressor_methods[] = { - {"compress", (PyCFunction)Compressor_compress, METH_VARARGS, - Compressor_compress_doc}, - {"flush", (PyCFunction)Compressor_flush, METH_NOARGS, - Compressor_flush_doc}, + _LZMA_LZMACOMPRESSOR_COMPRESS_METHODDEF + _LZMA_LZMACOMPRESSOR_FLUSH_METHODDEF {"__getstate__", (PyCFunction)Compressor_getstate, METH_NOARGS}, {NULL} }; @@ -819,25 +895,33 @@ static PyTypeObject Compressor_type = { /* LZMADecompressor class. */ -static PyObject * -decompress(Decompressor *d, uint8_t *data, size_t len) +/* 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) { - size_t data_size = 0; + Py_ssize_t data_size = 0; PyObject *result; + lzma_stream *lzs = &d->lzs; - result = PyBytes_FromStringAndSize(NULL, INITIAL_BUFFER_SIZE); + 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; - d->lzs.next_in = data; - d->lzs.avail_in = len; - d->lzs.next_out = (uint8_t *)PyBytes_AS_STRING(result); - d->lzs.avail_out = PyBytes_GET_SIZE(result); + + 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(&d->lzs, LZMA_RUN); - data_size = (char *)d->lzs.next_out - PyBytes_AS_STRING(result); + lzret = lzma_code(lzs, LZMA_RUN); + data_size = (char *)lzs->next_out - PyBytes_AS_STRING(result); Py_END_ALLOW_THREADS if (catch_lzma_error(lzret)) goto error; @@ -845,26 +929,22 @@ decompress(Decompressor *d, uint8_t *data, size_t len) d->check = lzma_get_check(&d->lzs); if (lzret == LZMA_STREAM_END) { d->eof = 1; - if (d->lzs.avail_in > 0) { - Py_CLEAR(d->unused_data); - d->unused_data = PyBytes_FromStringAndSize( - (char *)d->lzs.next_in, d->lzs.avail_in); - if (d->unused_data == NULL) - goto error; - } break; - } else if (d->lzs.avail_in == 0) { + } else if (lzs->avail_in == 0) { break; - } else if (d->lzs.avail_out == 0) { - if (grow_buffer(&result) == -1) + } else if (lzs->avail_out == 0) { + if (data_size == max_length) + break; + if (grow_buffer(&result, max_length) == -1) goto error; - d->lzs.next_out = (uint8_t *)PyBytes_AS_STRING(result) + data_size; - d->lzs.avail_out = PyBytes_GET_SIZE(result) - data_size; + lzs->next_out = (uint8_t *)PyBytes_AS_STRING(result) + data_size; + 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: @@ -872,32 +952,151 @@ decompress(Decompressor *d, uint8_t *data, size_t len) return NULL; } -PyDoc_STRVAR(Decompressor_decompress_doc, -"decompress(data) -> bytes\n" -"\n" -"Provide data to the decompressor object. Returns a chunk of\n" -"decompressed data if possible, or b\"\" otherwise.\n" -"\n" -"Attempting to decompress data after the end of the stream is\n" -"reached raises an EOFError. Any data found after the end of the\n" -"stream is ignored, and saved in the unused_data attribute.\n"); - static PyObject * -Decompressor_decompress(Decompressor *self, PyObject *args) +decompress(Decompressor *d, uint8_t *data, size_t len, Py_ssize_t max_length) { - Py_buffer buffer; - PyObject *result = NULL; + 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; + } - if (!PyArg_ParseTuple(args, "y*:decompress", &buffer)) + result = decompress_buf(d, max_length); + if(result == NULL) return NULL; + if (d->eof) { + d->needs_input = 0; + if (lzs->avail_in > 0) { + Py_CLEAR(d->unused_data); + 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; + 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 + + self: self(type="Decompressor *") + 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=f2bb902cc1caf203]*/ +{ + PyObject *result = NULL; + ACQUIRE_LOCK(self); if (self->eof) PyErr_SetString(PyExc_EOFError, "Already at end of stream"); else - result = decompress(self, buffer.buf, buffer.len); + result = decompress(self, data->buf, data->len, max_length); RELEASE_LOCK(self); - PyBuffer_Release(&buffer); return result; } @@ -925,38 +1124,57 @@ Decompressor_init_raw(lzma_stream *lzs, PyObject *filterspecs) return 0; } +/*[clinic input] +_lzma.LZMADecompressor.__init__ + + self: self(type="Decompressor *") + 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 -Decompressor_init(Decompressor *self, PyObject *args, PyObject *kwargs) +_lzma_LZMADecompressor___init___impl(Decompressor *self, int format, + PyObject *memlimit, PyObject *filters) +/*[clinic end generated code: output=3e1821f8aa36564c input=458ca6132ef29801]*/ { - static char *arg_names[] = {"format", "memlimit", "filters", NULL}; const uint32_t decoder_flags = LZMA_TELL_ANY_CHECK | LZMA_TELL_NO_CHECK; - int format = FORMAT_AUTO; - uint64_t memlimit = UINT64_MAX; - PyObject *memlimit_obj = Py_None; - PyObject *filterspecs = Py_None; + uint64_t memlimit_ = UINT64_MAX; lzma_ret lzret; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "|iOO:LZMADecompressor", arg_names, - &format, &memlimit_obj, &filterspecs)) - return -1; - - if (memlimit_obj != Py_None) { + 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_obj); + memlimit_ = PyLong_AsUnsignedLongLong(memlimit); if (PyErr_Occurred()) return -1; } - if (format == FORMAT_RAW && filterspecs == Py_None) { + if (format == FORMAT_RAW && filters == Py_None) { PyErr_SetString(PyExc_ValueError, "Must specify filters for FORMAT_RAW"); return -1; - } else if (format != FORMAT_RAW && filterspecs != Py_None) { + } else if (format != FORMAT_RAW && filters != Py_None) { PyErr_SetString(PyExc_ValueError, "Cannot specify filters except with FORMAT_RAW"); return -1; @@ -966,6 +1184,7 @@ Decompressor_init(Decompressor *self, PyObject *args, PyObject *kwargs) self->alloc.alloc = PyLzma_Malloc; self->alloc.free = PyLzma_Free; self->lzs.allocator = &self->alloc; + self->lzs.next_in = NULL; #ifdef WITH_THREAD self->lock = PyThread_allocate_lock(); @@ -976,33 +1195,36 @@ Decompressor_init(Decompressor *self, PyObject *args, PyObject *kwargs) #endif self->check = LZMA_CHECK_UNKNOWN; + self->needs_input = 1; + self->input_buffer = NULL; + self->input_buffer_size = 0; 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); + 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); + 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); + 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, filterspecs) == -1) + if (Decompressor_init_raw(&self->lzs, filters) == -1) break; return 0; @@ -1024,6 +1246,9 @@ Decompressor_init(Decompressor *self, PyObject *args, PyObject *kwargs) 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); #ifdef WITH_THREAD @@ -1034,8 +1259,7 @@ Decompressor_dealloc(Decompressor *self) } static PyMethodDef Decompressor_methods[] = { - {"decompress", (PyCFunction)Decompressor_decompress, METH_VARARGS, - Decompressor_decompress_doc}, + _LZMA_LZMADECOMPRESSOR_DECOMPRESS_METHODDEF {"__getstate__", (PyCFunction)Decompressor_getstate, METH_NOARGS}, {NULL} }; @@ -1046,6 +1270,9 @@ PyDoc_STRVAR(Decompressor_check_doc, 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."); @@ -1054,32 +1281,13 @@ static PyMemberDef Decompressor_members[] = { 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} }; -PyDoc_STRVAR(Decompressor_doc, -"LZMADecompressor(format=FORMAT_AUTO, memlimit=None, filters=None)\n" -"\n" -"Create a decompressor object for decompressing data incrementally.\n" -"\n" -"format 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" -"\n" -"memlimit can be specified to limit the amount of memory used by the\n" -"decompressor. This will cause decompression to fail if the input\n" -"cannot be decompressed within the given limit.\n" -"\n" -"filters specifies a custom filter chain. This argument is required for\n" -"FORMAT_RAW, and not accepted with any other format. When provided,\n" -"this should be a sequence of dicts, each indicating the ID and options\n" -"for a single filter.\n" -"\n" -"For one-shot decompression, use the decompress() function instead.\n"); - static PyTypeObject Decompressor_type = { PyVarObject_HEAD_INIT(NULL, 0) "_lzma.LZMADecompressor", /* tp_name */ @@ -1101,7 +1309,7 @@ static PyTypeObject Decompressor_type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ - Decompressor_doc, /* tp_doc */ + _lzma_LZMADecompressor___init____doc__, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ @@ -1116,7 +1324,7 @@ static PyTypeObject Decompressor_type = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)Decompressor_init, /* tp_init */ + _lzma_LZMADecompressor___init__, /* tp_init */ 0, /* tp_alloc */ PyType_GenericNew, /* tp_new */ }; @@ -1124,48 +1332,42 @@ static PyTypeObject Decompressor_type = { /* Module-level functions. */ -PyDoc_STRVAR(is_check_supported_doc, -"is_check_supported(check_id) -> bool\n" -"\n" -"Test whether the given integrity check is supported.\n" -"\n" -"Always returns True for CHECK_NONE and CHECK_CRC32.\n"); +/*[clinic input] +_lzma.is_check_supported + check_id: int + / -static PyObject * -is_check_supported(PyObject *self, PyObject *args) -{ - int check_id; +Test whether the given integrity check is supported. - if (!PyArg_ParseTuple(args, "i:is_check_supported", &check_id)) - return NULL; +Always returns True for CHECK_NONE and CHECK_CRC32. +[clinic start generated code]*/ +static PyObject * +_lzma_is_check_supported_impl(PyModuleDef *module, int check_id) +/*[clinic end generated code: output=bb828e90e00ad96e input=5518297b97b2318f]*/ +{ return PyBool_FromLong(lzma_check_is_supported(check_id)); } -PyDoc_STRVAR(_encode_filter_properties_doc, -"_encode_filter_properties(filter) -> bytes\n" -"\n" -"Return a bytes object encoding the options (properties) of the filter\n" -"specified by *filter* (a dict).\n" -"\n" -"The result does not include the filter ID itself, only the options.\n"); +/*[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 * -_encode_filter_properties(PyObject *self, PyObject *args) +_lzma__encode_filter_properties_impl(PyModuleDef *module, lzma_filter filter) +/*[clinic end generated code: output=b5fe690acd6b61d1 input=d4c64f1b557c77d4]*/ { - PyObject *filterspec; - lzma_filter filter; lzma_ret lzret; uint32_t encoded_size; PyObject *result = NULL; - if (!PyArg_ParseTuple(args, "O:_encode_filter_properties", &filterspec)) - return NULL; - - if (parse_filter_spec(&filter, filterspec) == NULL) - return NULL; - lzret = lzma_properties_size(&encoded_size, &filter); if (catch_lzma_error(lzret)) goto error; @@ -1179,37 +1381,37 @@ _encode_filter_properties(PyObject *self, PyObject *args) if (catch_lzma_error(lzret)) goto error; - PyMem_Free(filter.options); return result; error: Py_XDECREF(result); - PyMem_Free(filter.options); return NULL; } -PyDoc_STRVAR(_decode_filter_properties_doc, -"_decode_filter_properties(filter_id, encoded_props) -> dict\n" -"\n" -"Return a dict describing a filter with ID *filter_id*, and options\n" -"(properties) decoded from the bytes object *encoded_props*.\n"); +/*[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 * -_decode_filter_properties(PyObject *self, PyObject *args) +_lzma__decode_filter_properties_impl(PyModuleDef *module, lzma_vli filter_id, + Py_buffer *encoded_props) +/*[clinic end generated code: output=af248f570746668b input=246410800782160c]*/ { - Py_buffer encoded_props; lzma_filter filter; lzma_ret lzret; PyObject *result = NULL; - - if (!PyArg_ParseTuple(args, "O&y*:_decode_filter_properties", - lzma_vli_converter, &filter.id, &encoded_props)) - return NULL; + filter.id = filter_id; lzret = lzma_properties_decode( - &filter, NULL, encoded_props.buf, encoded_props.len); - PyBuffer_Release(&encoded_props); + &filter, NULL, encoded_props->buf, encoded_props->len); if (catch_lzma_error(lzret)) return NULL; @@ -1225,12 +1427,9 @@ _decode_filter_properties(PyObject *self, PyObject *args) /* Module initialization. */ static PyMethodDef module_methods[] = { - {"is_check_supported", (PyCFunction)is_check_supported, - METH_VARARGS, is_check_supported_doc}, - {"_encode_filter_properties", (PyCFunction)_encode_filter_properties, - METH_VARARGS, _encode_filter_properties_doc}, - {"_decode_filter_properties", (PyCFunction)_decode_filter_properties, - METH_VARARGS, _decode_filter_properties_doc}, + _LZMA_IS_CHECK_SUPPORTED_METHODDEF + _LZMA__ENCODE_FILTER_PROPERTIES_METHODDEF + _LZMA__DECODE_FILTER_PROPERTIES_METHODDEF {NULL} }; diff --git a/Modules/_math.c b/Modules/_math.c index fe75a36ec517..a0022082908d 100644 --- a/Modules/_math.c +++ b/Modules/_math.c @@ -22,7 +22,9 @@ static const double ln2 = 6.93147180559945286227E-01; static const double two_pow_m28 = 3.7252902984619141E-09; /* 2**-28 */ static const double two_pow_p28 = 268435456.0; /* 2**28 */ +#ifndef Py_NAN static const double zero = 0.0; +#endif /* acosh(x) * Method : @@ -238,7 +240,7 @@ _Py_log1p(double x) return x; } else if (-0.5 <= x && x <= 1.) { - /* WARNING: it's possible than an overeager compiler + /* 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 diff --git a/Modules/_multiprocessing/multiprocessing.c b/Modules/_multiprocessing/multiprocessing.c index 1aaf3605714e..4ae638eea5cc 100644 --- a/Modules/_multiprocessing/multiprocessing.c +++ b/Modules/_multiprocessing/multiprocessing.c @@ -128,7 +128,9 @@ static PyMethodDef module_methods[] = { {"recv", multiprocessing_recv, METH_VARARGS, ""}, {"send", multiprocessing_send, METH_VARARGS, ""}, #endif +#ifndef POSIX_SEMAPHORES_NOT_ENABLED {"sem_unlink", _PyMp_sem_unlink, METH_VARARGS, ""}, +#endif {NULL} }; diff --git a/Modules/_opcode.c b/Modules/_opcode.c index 55cffe1ab59f..663bb21a5fbc 100644 --- a/Modules/_opcode.c +++ b/Modules/_opcode.c @@ -1,85 +1,46 @@ #include "Python.h" #include "opcode.h" -/*[clinic] +/*[clinic input] module _opcode -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=117442e66eb376e6]*/ -/*[clinic] +#include "clinic/_opcode.c.h" + +/*[clinic input] _opcode.stack_effect -> int opcode: int - - [ - oparg: int - ] + oparg: object = None / Compute the stack effect of the opcode. -[clinic]*/ - -PyDoc_STRVAR(_opcode_stack_effect__doc__, -"stack_effect(opcode, [oparg])\n" -"Compute the stack effect of the opcode."); - -#define _OPCODE_STACK_EFFECT_METHODDEF \ - {"stack_effect", (PyCFunction)_opcode_stack_effect, METH_VARARGS, _opcode_stack_effect__doc__}, +[clinic start generated code]*/ static int -_opcode_stack_effect_impl(PyModuleDef *module, int opcode, int group_right_1, int oparg); - -static PyObject * -_opcode_stack_effect(PyModuleDef *module, PyObject *args) -{ - PyObject *return_value = NULL; - int opcode; - int group_right_1 = 0; - int oparg = 0; - int _return_value; - - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "i:stack_effect", &opcode)) - return NULL; - break; - case 2: - if (!PyArg_ParseTuple(args, "ii:stack_effect", &opcode, &oparg)) - return NULL; - group_right_1 = 1; - break; - default: - PyErr_SetString(PyExc_TypeError, "_opcode.stack_effect requires 1 to 2 arguments"); - return NULL; - } - _return_value = _opcode_stack_effect_impl(module, opcode, group_right_1, oparg); - if ((_return_value == -1) && PyErr_Occurred()) - goto exit; - return_value = PyLong_FromLong((long)_return_value); - -exit: - return return_value; -} - -static int -_opcode_stack_effect_impl(PyModuleDef *module, int opcode, int group_right_1, int oparg) -/*[clinic checksum: e880e62dc7b0de73403026eaf4f8074aa106358b]*/ +_opcode_stack_effect_impl(PyModuleDef *module, int opcode, PyObject *oparg) +/*[clinic end generated code: output=1fcafd5596c6b050 input=2d0a9ee53c0418f5]*/ { int effect; - if (HAS_ARG(opcode)) { - if (!group_right_1) { + int oparg_int = 0; + 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 (group_right_1) { + else if (oparg != Py_None) { PyErr_SetString(PyExc_ValueError, "stack_effect: opcode does not permit oparg but oparg was specified"); return -1; } - effect = PyCompile_OpcodeStackEffect(opcode, oparg); + effect = PyCompile_OpcodeStackEffect(opcode, oparg_int); if (effect == PY_INVALID_STACK_EFFECT) { PyErr_SetString(PyExc_ValueError, "invalid opcode or oparg"); diff --git a/Modules/_operator.c b/Modules/_operator.c index e8bef04f84af..735affcdbb61 100644 --- a/Modules/_operator.c +++ b/Modules/_operator.c @@ -69,6 +69,7 @@ spami(truth , PyObject_IsTrue) spam2(op_add , PyNumber_Add) spam2(op_sub , PyNumber_Subtract) spam2(op_mul , PyNumber_Multiply) +spam2(op_matmul , PyNumber_MatrixMultiply) spam2(op_floordiv , PyNumber_FloorDivide) spam2(op_truediv , PyNumber_TrueDivide) spam2(op_mod , PyNumber_Remainder) @@ -86,6 +87,7 @@ spam2(op_or_ , PyNumber_Or) spam2(op_iadd , PyNumber_InPlaceAdd) spam2(op_isub , PyNumber_InPlaceSubtract) spam2(op_imul , PyNumber_InPlaceMultiply) +spam2(op_imatmul , PyNumber_InPlaceMatrixMultiply) spam2(op_ifloordiv , PyNumber_InPlaceFloorDivide) spam2(op_itruediv , PyNumber_InPlaceTrueDivide) spam2(op_imod , PyNumber_InPlaceRemainder) @@ -239,7 +241,7 @@ PyDoc_STRVAR(compare_digest__doc__, "Return 'a == b'. This function uses an approach designed to prevent\n" "timing analysis, making it appropriate for cryptography.\n" "a and b must both be of the same type: either str (ASCII only),\n" -"or any type that supports the buffer protocol (e.g. bytes).\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" @@ -277,7 +279,7 @@ compare_digest(PyObject *self, PyObject *args) Py_buffer view_a; Py_buffer view_b; - if ((PyObject_CheckBuffer(a) == 0) & (PyObject_CheckBuffer(b) == 0)) { + if (PyObject_CheckBuffer(a) == 0 && PyObject_CheckBuffer(b) == 0) { PyErr_Format(PyExc_TypeError, "unsupported operand types(s) or combination of types: " "'%.100s' and '%.100s'", @@ -343,6 +345,7 @@ spam2o(index, "index(a) -- Same as a.__index__()") spam2(add, "add(a, b) -- Same as a + b.") spam2(sub, "sub(a, b) -- Same as a - b.") spam2(mul, "mul(a, b) -- Same as a * b.") +spam2(matmul, "matmul(a, b) -- Same as a @ b.") spam2(floordiv, "floordiv(a, b) -- Same as a // b.") spam2(truediv, "truediv(a, b) -- Same as a / b.") spam2(mod, "mod(a, b) -- Same as a % b.") @@ -360,6 +363,7 @@ spam2(or_, "or_(a, b) -- Same as a | b.") spam2(iadd, "a = iadd(a, b) -- Same as a += b.") spam2(isub, "a = isub(a, b) -- Same as a -= b.") spam2(imul, "a = imul(a, b) -- Same as a *= b.") +spam2(imatmul, "a = imatmul(a, b) -- Same as a @= b.") spam2(ifloordiv, "a = ifloordiv(a, b) -- Same as a //= b.") spam2(itruediv, "a = itruediv(a, b) -- Same as a /= b") spam2(imod, "a = imod(a, b) -- Same as a %= b.") @@ -481,6 +485,41 @@ itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw) 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) +{ + 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\ @@ -499,7 +538,7 @@ static PyTypeObject itemgetter_type = { 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ - 0, /* tp_repr */ + (reprfunc)itemgetter_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ @@ -517,7 +556,7 @@ static PyTypeObject itemgetter_type = { 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - 0, /* tp_methods */ + itemgetter_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ @@ -733,6 +772,93 @@ attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw) 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 *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\ @@ -753,7 +879,7 @@ static PyTypeObject attrgetter_type = { 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ - 0, /* tp_repr */ + (reprfunc)attrgetter_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ @@ -771,7 +897,7 @@ static PyTypeObject attrgetter_type = { 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - 0, /* tp_methods */ + attrgetter_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ @@ -809,6 +935,13 @@ methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 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) @@ -821,8 +954,8 @@ methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } mc->args = newargs; - name = PyTuple_GET_ITEM(args, 0); Py_INCREF(name); + PyUnicode_InternInPlace(&name); mc->name = name; Py_XINCREF(kwds); @@ -865,6 +998,142 @@ methodcaller_call(methodcallerobject *mc, PyObject *args, PyObject *kw) 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); + } + + if (mc->kwds != NULL) { + numkwdargs = PyDict_Size(mc->kwds); + if (numkwdargs < 0) { + Py_ReprLeave((PyObject *)mc); + return NULL; + } + } else { + numkwdargs = 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; + 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 *newargs; + if (!mc->kwds || PyDict_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; + _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 = PyTuple_New(2); + if (newargs == NULL) { + Py_DECREF(partial); + return NULL; + } + Py_INCREF(Py_TYPE(mc)); + PyTuple_SET_ITEM(newargs, 0, (PyObject *)Py_TYPE(mc)); + Py_INCREF(mc->name); + PyTuple_SET_ITEM(newargs, 1, mc->name); + constructor = PyObject_Call(partial, newargs, mc->kwds); + Py_DECREF(newargs); + 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\ @@ -884,7 +1153,7 @@ static PyTypeObject methodcaller_type = { 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_reserved */ - 0, /* tp_repr */ + (reprfunc)methodcaller_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ @@ -902,7 +1171,7 @@ static PyTypeObject methodcaller_type = { 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - 0, /* tp_methods */ + methodcaller_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ diff --git a/Modules/_pickle.c b/Modules/_pickle.c index c8afa8e47c3c..341ac0d6c087 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -4,29 +4,14 @@ PyDoc_STRVAR(pickle_module_doc, "Optimized C implementation for the Python pickle module."); -/*[clinic] +/*[clinic input] module _pickle -class _pickle.Pickler -class _pickle.PicklerMemoProxy -class _pickle.Unpickler -class _pickle.UnpicklerMemoProxy -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ - -/*[python] -class PicklerObject_converter(self_converter): - type = "PicklerObject *" - -class PicklerMemoProxyObject_converter(self_converter): - type = "PicklerMemoProxyObject *" - -class UnpicklerObject_converter(self_converter): - type = "UnpicklerObject *" - -class UnpicklerMemoProxyObject_converter(self_converter): - type = "UnpicklerMemoProxyObject *" -[python]*/ -/*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +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 this when new opcodes are added to the pickle protocol. */ enum { @@ -140,7 +125,7 @@ typedef struct { PyObject *PickleError; PyObject *PicklingError; PyObject *UnpicklingError; - + /* copyreg.dispatch_table, {type_object: pickling_function} */ PyObject *dispatch_table; @@ -166,6 +151,11 @@ typedef struct { /* 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. */ @@ -202,15 +192,26 @@ _Pickle_ClearState(PickleState *st) Py_CLEAR(st->name_mapping_3to2); Py_CLEAR(st->import_mapping_3to2); Py_CLEAR(st->codecs_encode); + Py_CLEAR(st->getattr); } /* Initialize the given pickle module state. */ static int _Pickle_InitState(PickleState *st) { + PyObject *builtins; PyObject *copyreg = NULL; PyObject *compat_pickle = NULL; PyObject *codecs = NULL; + PyObject *functools = NULL; + + builtins = PyEval_GetBuiltins(); + if (builtins == NULL) + goto error; + st->getattr = PyDict_GetItemString(builtins, "getattr"); + if (st->getattr == NULL) + goto error; + Py_INCREF(st->getattr); copyreg = PyImport_ImportModule("copyreg"); if (!copyreg) @@ -317,12 +318,21 @@ _Pickle_InitState(PickleState *st) } 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; } @@ -389,7 +399,7 @@ static PyTypeObject Pdata_Type = { PyVarObject_HEAD_INIT(NULL, 0) "_pickle.Pdata", /*tp_name*/ sizeof(Pdata), /*tp_basicsize*/ - 0, /*tp_itemsize*/ + sizeof(PyObject *), /*tp_itemsize*/ (destructor)Pdata_dealloc, /*tp_dealloc*/ }; @@ -434,22 +444,20 @@ static int Pdata_grow(Pdata *self) { PyObject **data = self->data; - Py_ssize_t allocated = self->allocated; - Py_ssize_t new_allocated; + size_t allocated = (size_t)self->allocated; + size_t new_allocated; new_allocated = (allocated >> 3) + 6; /* check for integer overflow */ - if (new_allocated > PY_SSIZE_T_MAX - allocated) + if (new_allocated > (size_t)PY_SSIZE_T_MAX - allocated) goto nomemory; new_allocated += allocated; - if (new_allocated > (PY_SSIZE_T_MAX / sizeof(PyObject *))) - goto nomemory; - data = PyMem_REALLOC(data, new_allocated * sizeof(PyObject *)); + PyMem_RESIZE(data, PyObject *, new_allocated); if (data == NULL) goto nomemory; self->data = data; - self->allocated = new_allocated; + self->allocated = (Py_ssize_t)new_allocated; return 0; nomemory: @@ -609,12 +617,23 @@ typedef struct UnpicklerObject { 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 @@ -663,7 +682,7 @@ PyMemoTable_Copy(PyMemoTable *self) /* 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_MALLOC(self->mt_allocated * sizeof(PyMemoEntry)); + new->mt_table = PyMem_NEW(PyMemoEntry, self->mt_allocated); if (new->mt_table == NULL) { PyMem_FREE(new); PyErr_NoMemory(); @@ -758,7 +777,7 @@ _PyMemoTable_ResizeTable(PyMemoTable *self, Py_ssize_t min_size) /* Allocate new table. */ oldtable = self->mt_table; - self->mt_table = PyMem_MALLOC(new_size * sizeof(PyMemoEntry)); + self->mt_table = PyMem_NEW(PyMemoEntry, new_size); if (self->mt_table == NULL) { self->mt_table = oldtable; PyErr_NoMemory(); @@ -853,7 +872,7 @@ _Pickler_ClearBuffer(PicklerObject *self) static void _write_size64(char *out, size_t value) { - int i; + size_t i; assert(sizeof(size_t) <= 8); @@ -1187,6 +1206,13 @@ _Unpickler_Read(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; + } if (self->next_read_idx + n <= self->input_len) { *s = self->input_buffer + self->next_read_idx; self->next_read_idx += n; @@ -1264,16 +1290,14 @@ static int _Unpickler_ResizeMemoList(UnpicklerObject *self, Py_ssize_t new_size) { Py_ssize_t i; - PyObject **memo; assert(new_size > self->memo_size); - memo = PyMem_REALLOC(self->memo, new_size * sizeof(PyObject *)); - if (memo == NULL) { + PyMem_RESIZE(self->memo, PyObject *, new_size); + if (self->memo == NULL) { PyErr_NoMemory(); return -1; } - self->memo = memo; for (i = self->memo_size; i < new_size; i++) self->memo[i] = NULL; self->memo_size = new_size; @@ -1317,7 +1341,7 @@ _Unpickler_MemoPut(UnpicklerObject *self, Py_ssize_t idx, PyObject *value) static PyObject ** _Unpickler_NewMemo(Py_ssize_t new_size) { - PyObject **memo = PyMem_MALLOC(new_size * sizeof(PyObject *)); + PyObject **memo = PyMem_NEW(PyObject *, new_size); if (memo == NULL) { PyErr_NoMemory(); return NULL; @@ -1459,7 +1483,7 @@ memo_get(PicklerObject *self, PyObject *key) pdata[1] = (unsigned char)(*value & 0xff); len = 2; } - else if (*value <= 0xffffffffL) { + else if ((size_t)*value <= 0xffffffffUL) { pdata[0] = LONG_BINGET; pdata[1] = (unsigned char)(*value & 0xff); pdata[2] = (unsigned char)((*value >> 8) & 0xff); @@ -1516,7 +1540,7 @@ memo_put(PicklerObject *self, PyObject *obj) pdata[1] = (unsigned char)idx; len = 2; } - else if (idx <= 0xffffffffL) { + else if ((size_t)idx <= 0xffffffffUL) { pdata[0] = LONG_BINPUT; pdata[1] = (unsigned char)(idx & 0xff); pdata[2] = (unsigned char)((idx >> 8) & 0xff); @@ -1538,66 +1562,101 @@ memo_put(PicklerObject *self, PyObject *obj) } static PyObject * -getattribute(PyObject *obj, PyObject *name, int allow_qualname) { - PyObject *dotted_path; - Py_ssize_t i; +get_dotted_path(PyObject *obj, PyObject *name) { _Py_static_string(PyId_dot, "."); _Py_static_string(PyId_locals, ""); + PyObject *dotted_path; + Py_ssize_t i, n; dotted_path = PyUnicode_Split(name, _PyUnicode_FromId(&PyId_dot), -1); - if (dotted_path == NULL) { + if (dotted_path == NULL) return NULL; - } - assert(Py_SIZE(dotted_path) >= 1); - if (!allow_qualname && Py_SIZE(dotted_path) > 1) { - PyErr_Format(PyExc_AttributeError, - "Can't get qualified attribute %R on %R;" - "use protocols >= 4 to enable support", - name, obj); - Py_DECREF(dotted_path); - return NULL; - } - Py_INCREF(obj); - for (i = 0; i < Py_SIZE(dotted_path); i++) { + n = PyList_GET_SIZE(dotted_path); + assert(n >= 1); + for (i = 0; i < n; i++) { PyObject *subpath = PyList_GET_ITEM(dotted_path, i); - PyObject *tmp; PyObject *result = PyUnicode_RichCompare( subpath, _PyUnicode_FromId(&PyId_locals), Py_EQ); int is_equal = (result == Py_True); assert(PyBool_Check(result)); Py_DECREF(result); if (is_equal) { - PyErr_Format(PyExc_AttributeError, - "Can't get local attribute %R on %R", name, obj); + 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); - Py_DECREF(obj); return NULL; } - tmp = PyObject_GetAttr(obj, subpath); - Py_DECREF(obj); - if (tmp == NULL) { - if (PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - PyErr_Format(PyExc_AttributeError, - "Can't get attribute %R on %R", name, obj); - } - Py_DECREF(dotted_path); + } + 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; + obj = PyObject_GetAttr(parent, name); + if (obj == NULL) { + Py_DECREF(parent); return NULL; } - obj = tmp; } - Py_DECREF(dotted_path); + if (pparent != NULL) + *pparent = parent; + else + Py_XDECREF(parent); return obj; } +static void +reformat_attribute_error(PyObject *obj, PyObject *name) +{ + if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + PyErr_Format(PyExc_AttributeError, + "Can't get attribute %R on %R", name, 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 + attr = PyObject_GetAttr(obj, name); + if (attr == NULL) + reformat_attribute_error(obj, name); + return attr; +} + static PyObject * -whichmodule(PyObject *global, PyObject *global_name, int allow_qualname) +whichmodule(PyObject *global, PyObject *dotted_path) { PyObject *module_name; PyObject *modules_dict; PyObject *module; - PyObject *obj; - Py_ssize_t i, j; + Py_ssize_t i; _Py_IDENTIFIER(__module__); _Py_IDENTIFIER(modules); _Py_IDENTIFIER(__main__); @@ -1619,6 +1678,7 @@ whichmodule(PyObject *global, PyObject *global_name, int allow_qualname) } assert(module_name == NULL); + /* Fallback on walking sys.modules */ modules_dict = _PySys_GetObjectId(&PyId_modules); if (modules_dict == NULL) { PyErr_SetString(PyExc_RuntimeError, "unable to get sys.modules"); @@ -1626,31 +1686,28 @@ whichmodule(PyObject *global, PyObject *global_name, int allow_qualname) } i = 0; - while ((j = PyDict_Next(modules_dict, &i, &module_name, &module))) { - PyObject *result = PyUnicode_RichCompare( - module_name, _PyUnicode_FromId(&PyId___main__), Py_EQ); - int is_equal = (result == Py_True); - assert(PyBool_Check(result)); - Py_DECREF(result); - if (is_equal) + while (PyDict_Next(modules_dict, &i, &module_name, &module)) { + PyObject *candidate; + if (PyUnicode_Check(module_name) && + !PyUnicode_CompareWithASCIIString(module_name, "__main__")) continue; if (module == Py_None) continue; - obj = getattribute(module, global_name, allow_qualname); - if (obj == NULL) { + candidate = get_deep_attribute(module, dotted_path, NULL); + if (candidate == NULL) { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return NULL; PyErr_Clear(); continue; } - if (obj == global) { - Py_DECREF(obj); + if (candidate == global) { Py_INCREF(module_name); + Py_DECREF(candidate); return module_name; } - Py_DECREF(obj); + Py_DECREF(candidate); } /* If no module is found, use __main__. */ @@ -1770,7 +1827,7 @@ save_long(PicklerObject *self, PyObject *obj) else if (self->bin && (sizeof(long) <= 4 || (val <= 0x7fffffffL && val >= (-0x7fffffffL - 1)))) { - /* result fits in a signed 4-byte integer. + /* 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 @@ -1936,7 +1993,7 @@ save_float(PicklerObject *self, PyObject *obj) if (_Pickler_Write(self, &op, 1) < 0) goto done; - buf = PyOS_double_to_string(x, 'g', 17, 0, NULL); + buf = PyOS_double_to_string(x, 'r', 0, Py_DTSF_ADD_DOT_0, NULL); if (!buf) { PyErr_NoMemory(); goto done; @@ -2016,7 +2073,7 @@ save_bytes(PicklerObject *self, PyObject *obj) header[1] = (unsigned char)size; len = 2; } - else if (size <= 0xffffffffL) { + else if ((size_t)size <= 0xffffffffUL) { header[0] = BINBYTES; header[1] = (unsigned char)(size & 0xff); header[2] = (unsigned char)((size >> 8) & 0xff); @@ -2027,7 +2084,7 @@ save_bytes(PicklerObject *self, PyObject *obj) else if (self->proto >= 4) { header[0] = BINBYTES8; _write_size64(header + 1, size); - len = 8; + len = 9; } else { PyErr_SetString(PyExc_OverflowError, @@ -2053,36 +2110,35 @@ save_bytes(PicklerObject *self, PyObject *obj) static PyObject * raw_unicode_escape(PyObject *obj) { - PyObject *repr, *result; char *p; - Py_ssize_t i, size, expandsize; + 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); - if (kind == PyUnicode_4BYTE_KIND) - expandsize = 10; - else - expandsize = 6; - if (size > PY_SSIZE_T_MAX / expandsize) - return PyErr_NoMemory(); - repr = PyByteArray_FromStringAndSize(NULL, expandsize * size); - if (repr == NULL) - return NULL; - if (size == 0) - goto done; + p = _PyBytesWriter_Alloc(&writer, size); + if (p == NULL) + goto error; + writer.overallocate = 1; - p = PyByteArray_AS_STRING(repr); for (i=0; i < size; i++) { Py_UCS4 ch = PyUnicode_READ(kind, data, i); /* Map 32-bit characters to '\Uxxxxxxxx' */ if (ch >= 0x10000) { + /* -1: substract 1 preallocated byte */ + p = _PyBytesWriter_Prepare(&writer, p, 10-1); + if (p == NULL) + goto error; + *p++ = '\\'; *p++ = 'U'; *p++ = Py_hexdigits[(ch >> 28) & 0xf]; @@ -2094,8 +2150,13 @@ raw_unicode_escape(PyObject *obj) *p++ = Py_hexdigits[(ch >> 4) & 0xf]; *p++ = Py_hexdigits[ch & 15]; } - /* Map 16-bit characters to '\uxxxx' */ + /* Map 16-bit characters, '\\' and '\n' to '\uxxxx' */ else if (ch >= 256 || ch == '\\' || ch == '\n') { + /* -1: substract 1 preallocated byte */ + p = _PyBytesWriter_Prepare(&writer, p, 6-1); + if (p == NULL) + goto error; + *p++ = '\\'; *p++ = 'u'; *p++ = Py_hexdigits[(ch >> 12) & 0xf]; @@ -2107,12 +2168,12 @@ raw_unicode_escape(PyObject *obj) else *p++ = (char) ch; } - size = p - PyByteArray_AS_STRING(repr); -done: - result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(repr), size); - Py_DECREF(repr); - return result; + return _PyBytesWriter_Finish(&writer, p); + +error: + _PyBytesWriter_Dealloc(&writer); + return NULL; } static int @@ -2121,12 +2182,13 @@ write_utf8(PicklerObject *self, char *data, Py_ssize_t size) char header[9]; Py_ssize_t len; + assert(size >= 0); if (size <= 0xff && self->proto >= 4) { header[0] = SHORT_BINUNICODE; header[1] = (unsigned char)(size & 0xff); len = 2; } - else if (size <= 0xffffffffUL) { + else if ((size_t)size <= 0xffffffffUL) { header[0] = BINUNICODE; header[1] = (unsigned char)(size & 0xff); header[2] = (unsigned char)((size >> 8) & 0xff); @@ -3029,6 +3091,7 @@ fix_imports(PyObject **module_name, PyObject **global_name) Py_INCREF(fixed_global_name); *module_name = fixed_module_name; *global_name = fixed_global_name; + return 0; } else if (PyErr_Occurred()) { return -1; @@ -3060,6 +3123,9 @@ 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; @@ -3073,13 +3139,11 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name) global_name = name; } else { - if (self->proto >= 4) { - global_name = _PyObject_GetAttrId(obj, &PyId___qualname__); - if (global_name == NULL) { - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) - goto error; - PyErr_Clear(); - } + global_name = _PyObject_GetAttrId(obj, &PyId___qualname__); + if (global_name == NULL) { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) + goto error; + PyErr_Clear(); } if (global_name == NULL) { global_name = _PyObject_GetAttrId(obj, &PyId___name__); @@ -3088,7 +3152,10 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name) } } - module_name = whichmodule(obj, global_name, self->proto >= 4); + 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; @@ -3107,7 +3174,10 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name) obj, module_name); goto error; } - cls = getattribute(module, global_name, self->proto >= 4); + 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", @@ -3194,6 +3264,11 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name) } 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; @@ -3205,6 +3280,15 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name) 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); + 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 @@ -3283,6 +3367,9 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name) Py_XDECREF(module_name); Py_XDECREF(global_name); Py_XDECREF(module); + Py_XDECREF(parent); + Py_XDECREF(dotted_path); + Py_XDECREF(lastname); return status; } @@ -3462,20 +3549,17 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) } PyErr_Clear(); } - else if (self->proto >= 4) { + else if (PyUnicode_Check(name)) { _Py_IDENTIFIER(__newobj_ex__); - use_newobj_ex = PyUnicode_Check(name) && - PyUnicode_Compare( + use_newobj_ex = PyUnicode_Compare( name, _PyUnicode_FromId(&PyId___newobj_ex__)) == 0; - Py_DECREF(name); - } - else { - _Py_IDENTIFIER(__newobj__); - use_newobj = PyUnicode_Check(name) && - PyUnicode_Compare( - name, _PyUnicode_FromId(&PyId___newobj__)) == 0; - Py_DECREF(name); + if (!use_newobj_ex) { + _Py_IDENTIFIER(__newobj__); + use_newobj = PyUnicode_Compare( + name, _PyUnicode_FromId(&PyId___newobj__)) == 0; + } } + Py_XDECREF(name); } if (use_newobj_ex) { @@ -3492,31 +3576,78 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) cls = PyTuple_GET_ITEM(argtup, 0); if (!PyType_Check(cls)) { - PyErr_Format(st->PicklingError, + 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, + 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, + 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 (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; + 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(Py_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 < Py_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) { @@ -3560,7 +3691,7 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) >>> pickle.dumps(1+2j) Traceback (most recent call last): ... - RuntimeError: maximum recursion depth exceeded + RecursionError: maximum recursion depth exceeded Removing the complex class from copyreg.dispatch_table made the __reduce_ex__() method emit another complex object: @@ -3874,35 +4005,21 @@ dump(PicklerObject *self, PyObject *obj) return 0; } -/*[clinic] +/*[clinic input] _pickle.Pickler.clear_memo - self: PicklerObject - 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]*/ - -PyDoc_STRVAR(_pickle_Pickler_clear_memo__doc__, -"clear_memo()\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__}, +[clinic start generated code]*/ static PyObject * -_pickle_Pickler_clear_memo(PicklerObject *self) -/*[clinic checksum: 9c32be7e7a17ff82a81aae409d0d4f469033a5b2]*/ +_pickle_Pickler_clear_memo_impl(PicklerObject *self) +/*[clinic end generated code: output=8665c8658aaa094b input=01bdad52f3d93e56]*/ { if (self->memo) PyMemoTable_Clear(self->memo); @@ -3910,27 +4027,19 @@ _pickle_Pickler_clear_memo(PicklerObject *self) Py_RETURN_NONE; } -/*[clinic] +/*[clinic input] _pickle.Pickler.dump - self: PicklerObject obj: object / Write a pickled representation of the given object to the open file. -[clinic]*/ - -PyDoc_STRVAR(_pickle_Pickler_dump__doc__, -"dump(obj)\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__}, +[clinic start generated code]*/ static PyObject * _pickle_Pickler_dump(PicklerObject *self, PyObject *obj) -/*[clinic checksum: b72a69ec98737fabf66dae7c5a3210178bdbd3e6]*/ +/*[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 @@ -3955,9 +4064,37 @@ _pickle_Pickler_dump(PicklerObject *self, PyObject *obj) 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 = sizeof(PicklerObject); + 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 */ }; @@ -4005,88 +4142,38 @@ Pickler_clear(PicklerObject *self) } -/*[clinic] +/*[clinic input] _pickle.Pickler.__init__ - self: PicklerObject file: object protocol: object = NULL fix_imports: bool = True 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 and 4. The -default protocol is 3; a backward-incompatible protocol designed for -Python 3. +The optional *protocol* argument tells the pickler to use the given +protocol; supported protocols are 0, 1, 2, 3 and 4. The default +protocol is 3; a backward-incompatible protocol designed for Python 3. -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. +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 +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, a 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. -[clinic]*/ - -PyDoc_STRVAR(_pickle_Pickler___init____doc__, -"__init__(file, protocol=None, fix_imports=True)\n" -"This takes a binary file for writing a pickle data stream.\n" -"\n" -"The optional protocol argument tells the pickler to use the\n" -"given protocol; supported protocols are 0, 1, 2, 3 and 4. The\n" -"default protocol is 3; a backward-incompatible protocol designed for\n" -"Python 3.\n" -"\n" -"Specifying a negative protocol version selects the highest\n" -"protocol version supported. The higher the protocol used, the\n" -"more recent the version of Python needed to read the pickle\n" -"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, a io.BytesIO instance, or any other custom object that\n" -"meets this interface.\n" -"\n" -"If fix_imports is True and protocol is less than 3, pickle will try to\n" -"map the new Python 3 names to the old module names used in Python 2,\n" -"so that the pickle data stream is readable with Python 2."); - -#define _PICKLE_PICKLER___INIT___METHODDEF \ - {"__init__", (PyCFunction)_pickle_Pickler___init__, METH_VARARGS|METH_KEYWORDS, _pickle_Pickler___init____doc__}, - -static PyObject * -_pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *protocol, int fix_imports); - -static PyObject * -_pickle_Pickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - static char *_keywords[] = {"file", "protocol", "fix_imports", NULL}; - PyObject *file; - PyObject *protocol = NULL; - int fix_imports = 1; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "O|Op:__init__", _keywords, - &file, &protocol, &fix_imports)) - goto exit; - return_value = _pickle_Pickler___init___impl((PicklerObject *)self, file, protocol, fix_imports); +writing, a io.BytesIO instance, or any other custom object that meets +this interface. -exit: - return return_value; -} +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. +[clinic start generated code]*/ -static PyObject * -_pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *protocol, int fix_imports) -/*[clinic checksum: c99ff417bd703a74affc4b708167e56e135e8969]*/ +static int +_pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, + PyObject *protocol, int fix_imports) +/*[clinic end generated code: output=b5f31078dab17fb0 input=b8cdeb7e3f5ee674]*/ { _Py_IDENTIFIER(persistent_id); _Py_IDENTIFIER(dispatch_table); @@ -4096,16 +4183,16 @@ _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *pro (void)Pickler_clear(self); if (_Pickler_SetProtocol(self, protocol, fix_imports) < 0) - return NULL; + return -1; if (_Pickler_SetOutputStream(self, file) < 0) - return NULL; + 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 NULL; + return -1; } self->output_len = 0; if (self->output_buffer == NULL) { @@ -4113,7 +4200,7 @@ _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *pro self->output_buffer = PyBytes_FromStringAndSize(NULL, self->max_output_len); if (self->output_buffer == NULL) - return NULL; + return -1; } self->fast = 0; @@ -4124,31 +4211,20 @@ _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *pro self->pers_func = _PyObject_GetAttrId((PyObject *)self, &PyId_persistent_id); if (self->pers_func == NULL) - return NULL; + return -1; } self->dispatch_table = NULL; if (_PyObject_HasAttrId((PyObject *)self, &PyId_dispatch_table)) { self->dispatch_table = _PyObject_GetAttrId((PyObject *)self, &PyId_dispatch_table); if (self->dispatch_table == NULL) - return NULL; + return -1; } - Py_RETURN_NONE; -} - -/* Wrap the Clinic generated signature to slot it in tp_init. */ -static int -Pickler_init(PyObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *result = _pickle_Pickler___init__(self, args, kwargs); - if (result == NULL) { - return -1; - } - Py_DECREF(result); return 0; } + /* Define a proxy object for the Pickler's internal memo object. This is to * avoid breaking code like: * pickler.memo.clear() @@ -4159,53 +4235,30 @@ Pickler_init(PyObject *self, PyObject *args, PyObject *kwargs) * intentional, as these should be treated as black-box implementation details. */ -typedef struct { - PyObject_HEAD - PicklerObject *pickler; /* Pickler whose memo table we're proxying. */ -} PicklerMemoProxyObject; - -/*[clinic] +/*[clinic input] _pickle.PicklerMemoProxy.clear - self: PicklerMemoProxyObject - Remove all items from memo. -[clinic]*/ - -PyDoc_STRVAR(_pickle_PicklerMemoProxy_clear__doc__, -"clear()\n" -"Remove all items from memo."); - -#define _PICKLE_PICKLERMEMOPROXY_CLEAR_METHODDEF \ - {"clear", (PyCFunction)_pickle_PicklerMemoProxy_clear, METH_NOARGS, _pickle_PicklerMemoProxy_clear__doc__}, +[clinic start generated code]*/ static PyObject * -_pickle_PicklerMemoProxy_clear(PicklerMemoProxyObject *self) -/*[clinic checksum: 507f13938721992e175a3e58b5ad02620045a1cc]*/ +_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] +/*[clinic input] _pickle.PicklerMemoProxy.copy - self: PicklerMemoProxyObject - Copy the memo to a new object. -[clinic]*/ - -PyDoc_STRVAR(_pickle_PicklerMemoProxy_copy__doc__, -"copy()\n" -"Copy the memo to a new object."); - -#define _PICKLE_PICKLERMEMOPROXY_COPY_METHODDEF \ - {"copy", (PyCFunction)_pickle_PicklerMemoProxy_copy, METH_NOARGS, _pickle_PicklerMemoProxy_copy__doc__}, +[clinic start generated code]*/ static PyObject * -_pickle_PicklerMemoProxy_copy(PicklerMemoProxyObject *self) -/*[clinic checksum: 73a5117ab354290ebdbe07bd0bf7232d0936a69d]*/ +_pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self) +/*[clinic end generated code: output=bb83a919d29225ef input=b73043485ac30b36]*/ { Py_ssize_t i; PyMemoTable *memo; @@ -4242,27 +4295,18 @@ _pickle_PicklerMemoProxy_copy(PicklerMemoProxyObject *self) return NULL; } -/*[clinic] +/*[clinic input] _pickle.PicklerMemoProxy.__reduce__ - self: PicklerMemoProxyObject - Implement pickle support. -[clinic]*/ - -PyDoc_STRVAR(_pickle_PicklerMemoProxy___reduce____doc__, -"__reduce__()\n" -"Implement pickle support."); - -#define _PICKLE_PICKLERMEMOPROXY___REDUCE___METHODDEF \ - {"__reduce__", (PyCFunction)_pickle_PicklerMemoProxy___reduce__, METH_NOARGS, _pickle_PicklerMemoProxy___reduce____doc__}, +[clinic start generated code]*/ static PyObject * -_pickle_PicklerMemoProxy___reduce__(PicklerMemoProxyObject *self) -/*[clinic checksum: 40f0bf7a9b161e77130674f0481bda0a0184dcce]*/ +_pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self) +/*[clinic end generated code: output=bebba1168863ab1d input=2f7c540e24b7aae4]*/ { PyObject *reduce_value, *dict_args; - PyObject *contents = _pickle_PicklerMemoProxy_copy(self); + PyObject *contents = _pickle_PicklerMemoProxy_copy_impl(self); if (contents == NULL) return NULL; @@ -4514,7 +4558,7 @@ static PyTypeObject Pickler_Type = { 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ - Pickler_init, /*tp_init*/ + _pickle_Pickler___init__, /*tp_init*/ PyType_GenericAlloc, /*tp_alloc*/ PyType_GenericNew, /*tp_new*/ PyObject_GC_Del, /*tp_free*/ @@ -4627,7 +4671,17 @@ calc_binsize(char *bytes, int nbytes) int i; size_t x = 0; - for (i = 0; i < nbytes && i < sizeof(size_t); i++) { + 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); } @@ -4646,7 +4700,7 @@ static long calc_binint(char *bytes, int nbytes) { unsigned char *s = (unsigned char *)bytes; - int i; + Py_ssize_t i; long x = 0; for (i = 0; i < nbytes; i++) { @@ -4831,7 +4885,7 @@ static int load_string(UnpicklerObject *self) { PyObject *bytes; - PyObject *str = NULL; + PyObject *obj; Py_ssize_t len; char *s, *p; @@ -4857,19 +4911,28 @@ load_string(UnpicklerObject *self) bytes = PyBytes_DecodeEscape(p, len, NULL, 0, NULL); if (bytes == NULL) return -1; - str = PyUnicode_FromEncodedObject(bytes, self->encoding, self->errors); - Py_DECREF(bytes); - if (str == NULL) - return -1; - PDATA_PUSH(self->stack, str, -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_binbytes(UnpicklerObject *self, int nbytes) +load_counted_binstring(UnpicklerObject *self, int nbytes) { - PyObject *bytes; + PyObject *obj; Py_ssize_t size; char *s; @@ -4878,8 +4941,9 @@ load_counted_binbytes(UnpicklerObject *self, int nbytes) size = calc_binsize(s, nbytes); if (size < 0) { - PyErr_Format(PyExc_OverflowError, - "BINBYTES exceeds system's maximum size of %zd bytes", + PickleState *st = _Pickle_GetGlobalState(); + PyErr_Format(st->UnpicklingError, + "BINSTRING exceeds system's maximum size of %zd bytes", PY_SSIZE_T_MAX); return -1; } @@ -4887,18 +4951,26 @@ load_counted_binbytes(UnpicklerObject *self, int nbytes) if (_Unpickler_Read(self, &s, size) < 0) return -1; - bytes = PyBytes_FromStringAndSize(s, size); - if (bytes == NULL) + /* 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, bytes, -1); + PDATA_PUSH(self->stack, obj, -1); return 0; } static int -load_counted_binstring(UnpicklerObject *self, int nbytes) +load_counted_binbytes(UnpicklerObject *self, int nbytes) { - PyObject *str; + PyObject *bytes; Py_ssize_t size; char *s; @@ -4907,21 +4979,20 @@ load_counted_binstring(UnpicklerObject *self, int nbytes) 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", + PyErr_Format(PyExc_OverflowError, + "BINBYTES 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 unicode. */ - str = PyUnicode_Decode(s, size, self->encoding, self->errors); - if (str == NULL) + + bytes = PyBytes_FromStringAndSize(s, size); + if (bytes == NULL) return -1; - PDATA_PUSH(self->stack, str, -1); + PDATA_PUSH(self->stack, bytes, -1); return 0; } @@ -5283,14 +5354,14 @@ load_newobj_ex(UnpicklerObject *self) Py_DECREF(args); return -1; } - + if (!PyType_Check(cls)) { Py_DECREF(kwargs); Py_DECREF(args); - Py_DECREF(cls); - PyErr_Format(st->UnpicklingError, + PyErr_Format(st->UnpicklingError, "NEWOBJ_EX class argument must be a type, not %.200s", Py_TYPE(cls)->tp_name); + Py_DECREF(cls); return -1; } @@ -6036,7 +6107,6 @@ load_mark(UnpicklerObject *self) if ((self->num_marks + 1) >= self->marks_size) { size_t alloc; - Py_ssize_t *marks; /* Use the size_t type to check for overflow. */ alloc = ((size_t)self->num_marks << 1) + 20; @@ -6047,15 +6117,14 @@ load_mark(UnpicklerObject *self) } if (self->marks == NULL) - marks = (Py_ssize_t *) PyMem_Malloc(alloc * sizeof(Py_ssize_t)); + self->marks = PyMem_NEW(Py_ssize_t, alloc); else - marks = (Py_ssize_t *) PyMem_Realloc(self->marks, - alloc * sizeof(Py_ssize_t)); - if (marks == NULL) { + PyMem_RESIZE(self->marks, Py_ssize_t, alloc); + if (self->marks == NULL) { + self->marks_size = 0; PyErr_NoMemory(); return -1; } - self->marks = marks; self->marks_size = (Py_ssize_t)alloc; } @@ -6139,7 +6208,7 @@ static PyObject * load(UnpicklerObject *self) { PyObject *value = NULL; - char *s; + char *s = NULL; self->num_marks = 0; self->proto = 0; @@ -6252,31 +6321,20 @@ load(UnpicklerObject *self) return value; } -/*[clinic] +/*[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]*/ - -PyDoc_STRVAR(_pickle_Unpickler_load__doc__, -"load()\n" -"Load a pickle.\n" -"\n" -"Read a pickled object representation from the open file object given in\n" -"the constructor, and return the reconstituted object hierarchy specified\n" -"therein."); - -#define _PICKLE_UNPICKLER_LOAD_METHODDEF \ - {"load", (PyCFunction)_pickle_Unpickler_load, METH_NOARGS, _pickle_Unpickler_load__doc__}, +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(PyObject *self) -/*[clinic checksum: 9a30ba4e4d9221d4dcd705e1471ab11b2c9e3ac6]*/ +_pickle_Unpickler_load_impl(UnpicklerObject *self) +/*[clinic end generated code: output=fdcc488aad675b14 input=acbb91a42fa9b7b9]*/ { UnpicklerObject *unpickler = (UnpicklerObject*)self; @@ -6299,60 +6357,29 @@ _pickle_Unpickler_load(PyObject *self) function is used for loading any global (i.e., functions), not just classes. The name is kept only for backward compatibility. */ -/*[clinic] +/*[clinic input] _pickle.Unpickler.find_class - self: UnpicklerObject 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). +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]*/ - -PyDoc_STRVAR(_pickle_Unpickler_find_class__doc__, -"find_class(module_name, global_name)\n" -"Return an object from a specified module.\n" -"\n" -"If necessary, the module will be imported. Subclasses may override this\n" -"method (e.g. to restrict unpickling of arbitrary classes and 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)_pickle_Unpickler_find_class, METH_VARARGS, _pickle_Unpickler_find_class__doc__}, - -static PyObject * -_pickle_Unpickler_find_class_impl(UnpicklerObject *self, PyObject *module_name, PyObject *global_name); +[clinic start generated code]*/ static PyObject * -_pickle_Unpickler_find_class(PyObject *self, PyObject *args) -{ - PyObject *return_value = NULL; - PyObject *module_name; - PyObject *global_name; - - if (!PyArg_ParseTuple(args, - "OO:find_class", - &module_name, &global_name)) - goto exit; - return_value = _pickle_Unpickler_find_class_impl((UnpicklerObject *)self, module_name, global_name); - -exit: - return return_value; -} - -static PyObject * -_pickle_Unpickler_find_class_impl(UnpicklerObject *self, PyObject *module_name, PyObject *global_name) -/*[clinic checksum: b7d05d4dd8adc698e5780c1ac2be0f5062d33915]*/ +_pickle_Unpickler_find_class_impl(UnpicklerObject *self, + PyObject *module_name, + PyObject *global_name) +/*[clinic end generated code: output=becc08d7f9ed41e3 input=e2e6a865de093ef4]*/ { PyObject *global; PyObject *modules_dict; @@ -6396,20 +6423,21 @@ _pickle_Unpickler_find_class_impl(UnpicklerObject *self, PyObject *module_name, else if (PyErr_Occurred()) { return NULL; } - - /* 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); + 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; } - module_name = item; - } - else if (PyErr_Occurred()) { - return NULL; } } @@ -6435,9 +6463,37 @@ _pickle_Unpickler_find_class_impl(UnpicklerObject *self, PyObject *module_name, 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 = sizeof(UnpicklerObject); + 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 */ }; @@ -6501,11 +6557,10 @@ Unpickler_clear(UnpicklerObject *self) return 0; } -/*[clinic] +/*[clinic input] _pickle.Unpickler.__init__ - self: UnpicklerObject file: object * fix_imports: bool = True @@ -6515,76 +6570,30 @@ _pickle.Unpickler.__init__ This takes a binary file for reading a pickle data stream. The protocol version of the pickle is detected automatically, so no -proto argument is needed. +protocol argument is needed. Bytes past the pickled object's +representation are ignored. -The file-like object 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-like object can be a binary file object opened for -reading, a BytesIO object, or any other custom object that -meets this interface. +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, a 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 compatiblity support for pickle stream -generated by Python 2.x. If *fix_imports* is True, pickle will try to -map the old Python 2.x names to the new names used in Python 3.x. The +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.x; these default to 'ASCII' and -'strict', respectively. - -[clinic]*/ - -PyDoc_STRVAR(_pickle_Unpickler___init____doc__, -"__init__(file, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\')\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" -"proto argument is needed.\n" -"\n" -"The file-like object must have two methods, a read() method\n" -"that takes an integer argument, and a readline() method that\n" -"requires no arguments. Both methods should return bytes.\n" -"Thus file-like object can be a binary file object opened for\n" -"reading, a BytesIO object, or any other custom object that\n" -"meets this interface.\n" -"\n" -"Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n" -"which are used to control compatiblity support for pickle stream\n" -"generated by Python 2.x. If *fix_imports* is True, pickle will try to\n" -"map the old Python 2.x names to the new names used in Python 3.x. The\n" -"*encoding* and *errors* tell pickle how to decode 8-bit string\n" -"instances pickled by Python 2.x; these default to \'ASCII\' and\n" -"\'strict\', respectively."); - -#define _PICKLE_UNPICKLER___INIT___METHODDEF \ - {"__init__", (PyCFunction)_pickle_Unpickler___init__, METH_VARARGS|METH_KEYWORDS, _pickle_Unpickler___init____doc__}, +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_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, int fix_imports, const char *encoding, const char *errors); - -static PyObject * -_pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - static char *_keywords[] = {"file", "fix_imports", "encoding", "errors", NULL}; - PyObject *file; - int fix_imports = 1; - const char *encoding = "ASCII"; - const char *errors = "strict"; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "O|$pss:__init__", _keywords, - &file, &fix_imports, &encoding, &errors)) - goto exit; - return_value = _pickle_Unpickler___init___impl((UnpicklerObject *)self, file, fix_imports, encoding, errors); - -exit: - return return_value; -} - -static PyObject * -_pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, int fix_imports, const char *encoding, const char *errors) -/*[clinic checksum: bed0d8bbe1c647960ccc6f997b33bf33935fa56f]*/ +static int +_pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, + int fix_imports, const char *encoding, + const char *errors) +/*[clinic end generated code: output=e2c8ce748edc57b0 input=30b4dc9e976b890c]*/ { _Py_IDENTIFIER(persistent_load); @@ -6593,20 +6602,20 @@ _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, int fix_i (void)Unpickler_clear(self); if (_Unpickler_SetInputStream(self, file) < 0) - return NULL; + return -1; if (_Unpickler_SetInputEncoding(self, encoding, errors) < 0) - return NULL; + return -1; self->fix_imports = fix_imports; if (self->fix_imports == -1) - return NULL; + return -1; if (_PyObject_HasAttrId((PyObject *)self, &PyId_persistent_load)) { self->pers_func = _PyObject_GetAttrId((PyObject *)self, &PyId_persistent_load); if (self->pers_func == NULL) - return NULL; + return 1; } else { self->pers_func = NULL; @@ -6614,30 +6623,19 @@ _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, int fix_i self->stack = (Pdata *)Pdata_New(); if (self->stack == NULL) - return NULL; + return 1; self->memo_size = 32; self->memo = _Unpickler_NewMemo(self->memo_size); if (self->memo == NULL) - return NULL; + return -1; self->proto = 0; - Py_RETURN_NONE; -} - -/* Wrap the Clinic generated signature to slot it in tp_init. */ -static int -Unpickler_init(PyObject *self, PyObject *args, PyObject *kwargs) -{ - PyObject *result = _pickle_Unpickler___init__(self, args, kwargs); - if (result == NULL) { - return -1; - } - Py_DECREF(result); return 0; } + /* Define a proxy object for the Unpickler's internal memo object. This is to * avoid breaking code like: * unpickler.memo.clear() @@ -6651,29 +6649,15 @@ Unpickler_init(PyObject *self, PyObject *args, PyObject *kwargs) * real-world code like cvs2svn. */ -typedef struct { - PyObject_HEAD - UnpicklerObject *unpickler; -} UnpicklerMemoProxyObject; - -/*[clinic] +/*[clinic input] _pickle.UnpicklerMemoProxy.clear - self: UnpicklerMemoProxyObject - Remove all items from memo. -[clinic]*/ - -PyDoc_STRVAR(_pickle_UnpicklerMemoProxy_clear__doc__, -"clear()\n" -"Remove all items from memo."); - -#define _PICKLE_UNPICKLERMEMOPROXY_CLEAR_METHODDEF \ - {"clear", (PyCFunction)_pickle_UnpicklerMemoProxy_clear, METH_NOARGS, _pickle_UnpicklerMemoProxy_clear__doc__}, +[clinic start generated code]*/ static PyObject * -_pickle_UnpicklerMemoProxy_clear(UnpicklerMemoProxyObject *self) -/*[clinic checksum: 46fecf4e33c0c873124f845edf6cc3a2e9864bd5]*/ +_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); @@ -6682,24 +6666,15 @@ _pickle_UnpicklerMemoProxy_clear(UnpicklerMemoProxyObject *self) Py_RETURN_NONE; } -/*[clinic] +/*[clinic input] _pickle.UnpicklerMemoProxy.copy - self: UnpicklerMemoProxyObject - Copy the memo to a new object. -[clinic]*/ - -PyDoc_STRVAR(_pickle_UnpicklerMemoProxy_copy__doc__, -"copy()\n" -"Copy the memo to a new object."); - -#define _PICKLE_UNPICKLERMEMOPROXY_COPY_METHODDEF \ - {"copy", (PyCFunction)_pickle_UnpicklerMemoProxy_copy, METH_NOARGS, _pickle_UnpicklerMemoProxy_copy__doc__}, +[clinic start generated code]*/ static PyObject * -_pickle_UnpicklerMemoProxy_copy(UnpicklerMemoProxyObject *self) -/*[clinic checksum: f8856c4e8a33540886dfbb245f286af3008fa0ad]*/ +_pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self) +/*[clinic end generated code: output=e12af7e9bc1e4c77 input=97769247ce032c1d]*/ { Py_ssize_t i; PyObject *new_memo = PyDict_New(); @@ -6729,28 +6704,19 @@ _pickle_UnpicklerMemoProxy_copy(UnpicklerMemoProxyObject *self) return NULL; } -/*[clinic] +/*[clinic input] _pickle.UnpicklerMemoProxy.__reduce__ - self: UnpicklerMemoProxyObject - Implement pickling support. -[clinic]*/ - -PyDoc_STRVAR(_pickle_UnpicklerMemoProxy___reduce____doc__, -"__reduce__()\n" -"Implement pickling support."); - -#define _PICKLE_UNPICKLERMEMOPROXY___REDUCE___METHODDEF \ - {"__reduce__", (PyCFunction)_pickle_UnpicklerMemoProxy___reduce__, METH_NOARGS, _pickle_UnpicklerMemoProxy___reduce____doc__}, +[clinic start generated code]*/ static PyObject * -_pickle_UnpicklerMemoProxy___reduce__(UnpicklerMemoProxyObject *self) -/*[clinic checksum: ab5516a77659144e1191c7dd70a0c6c7455660bc]*/ +_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(self); + PyObject *contents = _pickle_UnpicklerMemoProxy_copy_impl(self); if (contents == NULL) return NULL; @@ -7014,14 +6980,14 @@ static PyTypeObject Unpickler_Type = { 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ - Unpickler_init, /*tp_init*/ + _pickle_Unpickler___init__, /*tp_init*/ PyType_GenericAlloc, /*tp_alloc*/ PyType_GenericNew, /*tp_new*/ PyObject_GC_Del, /*tp_free*/ 0, /*tp_is_gc*/ }; -/*[clinic] +/*[clinic input] _pickle.dump @@ -7033,78 +6999,31 @@ _pickle.dump 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. +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. The default protocol is 3; a -backward-incompatible protocol designed for Python 3.0. - -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, a -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.x names to the old module names used in Python 2.x, -so that the pickle data stream is readable with Python 2.x. -[clinic]*/ - -PyDoc_STRVAR(_pickle_dump__doc__, -"dump(obj, file, protocol=None, *, fix_imports=True)\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 be more\n" -"efficient.\n" -"\n" -"The optional protocol argument tells the pickler to use the given protocol\n" -"supported protocols are 0, 1, 2, 3. The default protocol is 3; a\n" -"backward-incompatible protocol designed for Python 3.0.\n" -"\n" -"Specifying a negative protocol version selects the highest protocol version\n" -"supported. The higher the protocol used, the more recent the version of\n" -"Python needed to read the pickle produced.\n" -"\n" -"The file argument must have a write() method that accepts a single bytes\n" -"argument. It can thus be a file object opened for binary writing, a\n" -"io.BytesIO instance, or any other custom object that meets this interface.\n" -"\n" -"If fix_imports is True and protocol is less than 3, pickle will try to\n" -"map the new Python 3.x names to the old module names used in Python 2.x,\n" -"so that the pickle data stream is readable with Python 2.x."); - -#define _PICKLE_DUMP_METHODDEF \ - {"dump", (PyCFunction)_pickle_dump, METH_VARARGS|METH_KEYWORDS, _pickle_dump__doc__}, +The optional *protocol* argument tells the pickler to use the given +protocol supported protocols are 0, 1, 2, 3 and 4. The default +protocol is 3; a backward-incompatible protocol designed for Python 3. -static PyObject * -_pickle_dump_impl(PyModuleDef *module, PyObject *obj, PyObject *file, PyObject *protocol, int fix_imports); +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. -static PyObject * -_pickle_dump(PyModuleDef *module, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - static char *_keywords[] = {"obj", "file", "protocol", "fix_imports", NULL}; - PyObject *obj; - PyObject *file; - PyObject *protocol = NULL; - int fix_imports = 1; +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, a io.BytesIO instance, or any other custom object that meets +this interface. - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "OO|O$p:dump", _keywords, - &obj, &file, &protocol, &fix_imports)) - goto exit; - return_value = _pickle_dump_impl(module, obj, file, protocol, fix_imports); - -exit: - return return_value; -} +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. +[clinic start generated code]*/ static PyObject * -_pickle_dump_impl(PyModuleDef *module, PyObject *obj, PyObject *file, PyObject *protocol, int fix_imports) -/*[clinic checksum: e442721b16052d921b5e3fbd146d0a62e94a459e]*/ +_pickle_dump_impl(PyModuleDef *module, PyObject *obj, PyObject *file, + PyObject *protocol, int fix_imports) +/*[clinic end generated code: output=0de7dff89c406816 input=e9e5fdd48de92eae]*/ { PicklerObject *pickler = _Pickler_New(); @@ -7131,7 +7050,7 @@ _pickle_dump_impl(PyModuleDef *module, PyObject *obj, PyObject *file, PyObject * return NULL; } -/*[clinic] +/*[clinic input] _pickle.dumps @@ -7142,63 +7061,23 @@ _pickle.dumps 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. The default protocol is 3; a -backward-incompatible protocol designed for Python 3.0. - -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.x names to the old module names used in Python 2.x, -so that the pickle data stream is readable with Python 2.x. -[clinic]*/ - -PyDoc_STRVAR(_pickle_dumps__doc__, -"dumps(obj, protocol=None, *, fix_imports=True)\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 protocol;\n" -"supported protocols are 0, 1, 2, 3. The default protocol is 3; a\n" -"backward-incompatible protocol designed for Python 3.0.\n" -"\n" -"Specifying a negative protocol version selects the highest protocol version\n" -"supported. The higher the protocol used, the more recent the version of\n" -"Python needed to read the pickle produced.\n" -"\n" -"If fix_imports is True and *protocol* is less than 3, pickle will try to\n" -"map the new Python 3.x names to the old module names used in Python 2.x,\n" -"so that the pickle data stream is readable with Python 2.x."); - -#define _PICKLE_DUMPS_METHODDEF \ - {"dumps", (PyCFunction)_pickle_dumps, METH_VARARGS|METH_KEYWORDS, _pickle_dumps__doc__}, +The optional *protocol* argument tells the pickler to use the given +protocol; supported protocols are 0, 1, 2, 3 and 4. The default +protocol is 3; a backward-incompatible protocol designed for Python 3. -static PyObject * -_pickle_dumps_impl(PyModuleDef *module, PyObject *obj, PyObject *protocol, int fix_imports); +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. -static PyObject * -_pickle_dumps(PyModuleDef *module, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - static char *_keywords[] = {"obj", "protocol", "fix_imports", NULL}; - PyObject *obj; - PyObject *protocol = NULL; - int fix_imports = 1; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "O|O$p:dumps", _keywords, - &obj, &protocol, &fix_imports)) - goto exit; - return_value = _pickle_dumps_impl(module, obj, protocol, fix_imports); - -exit: - return return_value; -} +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. +[clinic start generated code]*/ static PyObject * -_pickle_dumps_impl(PyModuleDef *module, PyObject *obj, PyObject *protocol, int fix_imports) -/*[clinic checksum: df6262c4c487f537f47aec8a1709318204c1e174]*/ +_pickle_dumps_impl(PyModuleDef *module, PyObject *obj, PyObject *protocol, + int fix_imports) +/*[clinic end generated code: output=daa380db56fe07b9 input=293dbeda181580b7]*/ { PyObject *result; PicklerObject *pickler = _Pickler_New(); @@ -7221,7 +7100,7 @@ _pickle_dumps_impl(PyModuleDef *module, PyObject *obj, PyObject *protocol, int f return NULL; } -/*[clinic] +/*[clinic input] _pickle.load @@ -7231,80 +7110,35 @@ _pickle.load encoding: str = 'ASCII' errors: str = 'strict' -Return a reconstituted 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, a 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 compatiblity support for pickle stream generated -by Python 2.x. If fix_imports is True, pickle will try to map the old -Python 2.x names to the new names used in Python 3.x. The encoding and -errors tell pickle how to decode 8-bit string instances pickled by Python -2.x; these default to 'ASCII' and 'strict', respectively. -[clinic]*/ - -PyDoc_STRVAR(_pickle_load__doc__, -"load(file, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\')\n" -"Return a reconstituted object from the pickle data stored in a file.\n" -"\n" -"This is equivalent to ``Unpickler(file).load()``, but may be more efficient.\n" -"\n" -"The protocol version of the pickle is detected automatically, so no protocol\n" -"argument is needed. Bytes past the pickled object\'s representation are\n" -"ignored.\n" -"\n" -"The argument file must have two methods, a read() method that takes an\n" -"integer argument, and a readline() method that requires no arguments. Both\n" -"methods should return bytes. Thus *file* can be a binary file object opened\n" -"for reading, a BytesIO object, or any other custom object that meets this\n" -"interface.\n" -"\n" -"Optional keyword arguments are fix_imports, encoding and errors,\n" -"which are used to control compatiblity support for pickle stream generated\n" -"by Python 2.x. If fix_imports is True, pickle will try to map the old\n" -"Python 2.x names to the new names used in Python 3.x. The encoding and\n" -"errors tell pickle how to decode 8-bit string instances pickled by Python\n" -"2.x; these default to \'ASCII\' and \'strict\', respectively."); - -#define _PICKLE_LOAD_METHODDEF \ - {"load", (PyCFunction)_pickle_load, METH_VARARGS|METH_KEYWORDS, _pickle_load__doc__}, +Read and return an object from the pickle data stored in a file. -static PyObject * -_pickle_load_impl(PyModuleDef *module, PyObject *file, int fix_imports, const char *encoding, const char *errors); +This is equivalent to ``Unpickler(file).load()``, but may be more +efficient. -static PyObject * -_pickle_load(PyModuleDef *module, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - static char *_keywords[] = {"file", "fix_imports", "encoding", "errors", NULL}; - PyObject *file; - int fix_imports = 1; - const char *encoding = "ASCII"; - const char *errors = "strict"; +The protocol version of the pickle is detected automatically, so no +protocol argument is needed. Bytes past the pickled object's +representation are ignored. - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "O|$pss:load", _keywords, - &file, &fix_imports, &encoding, &errors)) - goto exit; - return_value = _pickle_load_impl(module, file, fix_imports, encoding, errors); +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, a io.BytesIO object, or any +other custom object that meets this interface. -exit: - return return_value; -} +Optional keyword arguments are *fix_imports*, *encoding* and *errors*, +which are used to control compatiblity 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(PyModuleDef *module, PyObject *file, int fix_imports, const char *encoding, const char *errors) -/*[clinic checksum: e10796f6765b22ce48dca6940f11b3933853ca35]*/ +_pickle_load_impl(PyModuleDef *module, PyObject *file, int fix_imports, + const char *encoding, const char *errors) +/*[clinic end generated code: output=798f1c57cb2b4eb1 input=da97372e38e510a6]*/ { PyObject *result; UnpicklerObject *unpickler = _Unpickler_New(); @@ -7329,7 +7163,7 @@ _pickle_load_impl(PyModuleDef *module, PyObject *file, int fix_imports, const ch return NULL; } -/*[clinic] +/*[clinic input] _pickle.loads @@ -7339,64 +7173,26 @@ _pickle.loads encoding: str = 'ASCII' errors: str = 'strict' -Return a reconstituted 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 compatiblity support for pickle stream generated -by Python 2.x. If fix_imports is True, pickle will try to map the old -Python 2.x names to the new names used in Python 3.x. The encoding and -errors tell pickle how to decode 8-bit string instances pickled by Python -2.x; these default to 'ASCII' and 'strict', respectively. -[clinic]*/ - -PyDoc_STRVAR(_pickle_loads__doc__, -"loads(data, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\')\n" -"Return a reconstituted object from the given pickle data.\n" -"\n" -"The protocol version of the pickle is detected automatically, so no protocol\n" -"argument is needed. Bytes past the pickled object\'s representation are\n" -"ignored.\n" -"\n" -"Optional keyword arguments are fix_imports, encoding and errors, which\n" -"are used to control compatiblity support for pickle stream generated\n" -"by Python 2.x. If fix_imports is True, pickle will try to map the old\n" -"Python 2.x names to the new names used in Python 3.x. The encoding and\n" -"errors tell pickle how to decode 8-bit string instances pickled by Python\n" -"2.x; these default to \'ASCII\' and \'strict\', respectively."); - -#define _PICKLE_LOADS_METHODDEF \ - {"loads", (PyCFunction)_pickle_loads, METH_VARARGS|METH_KEYWORDS, _pickle_loads__doc__}, - -static PyObject * -_pickle_loads_impl(PyModuleDef *module, PyObject *data, int fix_imports, const char *encoding, const char *errors); +Read and return an object from the given pickle data. -static PyObject * -_pickle_loads(PyModuleDef *module, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - static char *_keywords[] = {"data", "fix_imports", "encoding", "errors", NULL}; - PyObject *data; - int fix_imports = 1; - const char *encoding = "ASCII"; - const char *errors = "strict"; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "O|$pss:loads", _keywords, - &data, &fix_imports, &encoding, &errors)) - goto exit; - return_value = _pickle_loads_impl(module, data, fix_imports, encoding, errors); +The protocol version of the pickle is detected automatically, so no +protocol argument is needed. Bytes past the pickled object's +representation are ignored. -exit: - return return_value; -} +Optional keyword arguments are *fix_imports*, *encoding* and *errors*, +which are used to control compatiblity 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(PyModuleDef *module, PyObject *data, int fix_imports, const char *encoding, const char *errors) -/*[clinic checksum: 29ee725efcbf51a3533c19cb8261a8e267b7080a]*/ +_pickle_loads_impl(PyModuleDef *module, PyObject *data, int fix_imports, + const char *encoding, const char *errors) +/*[clinic end generated code: output=61e9cdb01e36a736 input=f57f0fdaa2b4cb8b]*/ { PyObject *result; UnpicklerObject *unpickler = _Unpickler_New(); @@ -7436,6 +7232,12 @@ pickle_clear(PyObject *m) return 0; } +static void +pickle_free(PyObject *m) +{ + _Pickle_ClearState(_Pickle_GetState(m)); +} + static int pickle_traverse(PyObject *m, visitproc visit, void *arg) { @@ -7452,19 +7254,20 @@ pickle_traverse(PyObject *m, visitproc visit, void *arg) Py_VISIT(st->name_mapping_3to2); Py_VISIT(st->import_mapping_3to2); Py_VISIT(st->codecs_encode); + Py_VISIT(st->getattr); 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 */ - NULL /* m_free */ + "_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 diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index a2d702299260..800b3019c8fd 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -14,10 +14,19 @@ #ifdef HAVE_SYS_SYSCALL_H #include #endif +#if defined(HAVE_SYS_RESOURCE_H) +#include +#endif #ifdef HAVE_DIRENT_H #include #endif +#if defined(__ANDROID__) && !defined(SYS_getdents64) +/* Android doesn't expose syscalls, add the definition manually. */ +# include +# define SYS_getdents64 __NR_getdents64 +#endif + #if defined(sun) /* readdir64 is used to work around Solaris 9 bug 6395699. */ # define readdir readdir64 @@ -38,10 +47,6 @@ #define POSIX_CALL(call) do { if ((call) == -1) goto error; } while (0) -/* Maximum file descriptor, initialized on module load. */ -static long max_fd; - - /* Given the gc module call gc.enable() and return 0 on success. */ static int _enable_gc(PyObject *gc_module) @@ -160,14 +165,46 @@ make_inheritable(PyObject *py_fds_to_keep, int errpipe_write) } -/* Close all file descriptors in the range start_fd inclusive to - * end_fd exclusive except for those in py_fds_to_keep. If the - * range defined by [start_fd, end_fd) is large this will take a - * long time as it calls close() on EVERY possible fd. +/* 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(int start_fd, int end_fd, PyObject *py_fds_to_keep) +_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 = PySequence_Length(py_fds_to_keep); Py_ssize_t keep_seq_idx; int fd_num; @@ -180,13 +217,13 @@ _close_fds_by_brute_force(int start_fd, int end_fd, PyObject *py_fds_to_keep) if (keep_fd < start_fd) continue; for (fd_num = start_fd; fd_num < keep_fd; ++fd_num) { - while (close(fd_num) < 0 && errno == EINTR); + close(fd_num); } start_fd = keep_fd + 1; } if (start_fd <= end_fd) { for (fd_num = start_fd; fd_num < end_fd; ++fd_num) { - while (close(fd_num) < 0 && errno == EINTR); + close(fd_num); } } } @@ -207,8 +244,8 @@ struct linux_dirent64 { char d_name[256]; /* Filename (null-terminated) */ }; -/* Close all open file descriptors in the range start_fd inclusive to end_fd - * exclusive. Do not close any in the sorted py_fds_to_keep list. +/* 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 @@ -223,16 +260,14 @@ struct linux_dirent64 { * it with some cpp #define magic to work on other OSes as well if you want. */ static void -_close_open_fd_range_safe(int start_fd, int end_fd, PyObject* py_fds_to_keep) +_close_open_fds_safe(int start_fd, PyObject* py_fds_to_keep) { int fd_dir_fd; - if (start_fd >= end_fd) - return; - fd_dir_fd = _Py_open(FD_DIR, O_RDONLY); + 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, end_fd, py_fds_to_keep); + _close_fds_by_brute_force(start_fd, py_fds_to_keep); return; } else { char buffer[sizeof(struct linux_dirent64)]; @@ -247,9 +282,9 @@ _close_open_fd_range_safe(int start_fd, int end_fd, PyObject* py_fds_to_keep) 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 && fd < end_fd && + if (fd != fd_dir_fd && fd >= start_fd && !_is_fd_in_sorted_fd_sequence(fd, py_fds_to_keep)) { - while (close(fd) < 0 && errno == EINTR); + close(fd); } } } @@ -257,13 +292,13 @@ _close_open_fd_range_safe(int start_fd, int end_fd, PyObject* py_fds_to_keep) } } -#define _close_open_fd_range _close_open_fd_range_safe +#define _close_open_fds _close_open_fds_safe #else /* NOT (defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)) */ -/* Close all open file descriptors in the range start_fd inclusive to end_fd - * exclusive. Do not close any in the sorted py_fds_to_keep list. +/* Close all open file descriptors from start_fd and higher. + * Do not close any in the sorted py_fds_to_keep list. * * This function violates the strict use of async signal safe functions. :( * It calls opendir(), readdir() and closedir(). Of these, the one most @@ -276,26 +311,20 @@ _close_open_fd_range_safe(int start_fd, int end_fd, PyObject* py_fds_to_keep) * http://womble.decadent.org.uk/readdir_r-advisory.html */ static void -_close_open_fd_range_maybe_unsafe(int start_fd, int end_fd, - PyObject* py_fds_to_keep) +_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 < end_fd)) { + while (_is_fd_in_sorted_fd_sequence(start_fd, py_fds_to_keep)) { ++start_fd; } - if (start_fd >= end_fd) - return; /* 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. */ - while (close(start_fd) < 0 && errno == EINTR); + close(start_fd); ++start_fd; #endif - if (start_fd >= end_fd) - return; #if defined(__FreeBSD__) if (!_is_fdescfs_mounted_on_dev_fd()) @@ -305,7 +334,7 @@ _close_open_fd_range_maybe_unsafe(int start_fd, int end_fd, 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, end_fd, py_fds_to_keep); + _close_fds_by_brute_force(start_fd, py_fds_to_keep); } else { struct dirent *dir_entry; #ifdef HAVE_DIRFD @@ -318,21 +347,21 @@ _close_open_fd_range_maybe_unsafe(int start_fd, int end_fd, 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 && fd < end_fd && + if (fd != fd_used_by_opendir && fd >= start_fd && !_is_fd_in_sorted_fd_sequence(fd, py_fds_to_keep)) { - while (close(fd) < 0 && errno == EINTR); + close(fd); } errno = 0; } if (errno) { /* readdir error, revert behavior. Highly Unlikely. */ - _close_fds_by_brute_force(start_fd, end_fd, py_fds_to_keep); + _close_fds_by_brute_force(start_fd, py_fds_to_keep); } closedir(proc_fd_dir); } } -#define _close_open_fd_range _close_open_fd_range_maybe_unsafe +#define _close_open_fds _close_open_fds_maybe_unsafe #endif /* else NOT (defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)) */ @@ -363,7 +392,7 @@ child_exec(char *const exec_array[], PyObject *preexec_fn, PyObject *preexec_fn_args_tuple) { - int i, saved_errno, unused, reached_preexec = 0; + 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. */ @@ -451,14 +480,8 @@ child_exec(char *const exec_array[], /* close FDs after executing preexec_fn, which might open FDs */ if (close_fds) { - int local_max_fd = max_fd; -#if defined(__NetBSD__) - local_max_fd = fcntl(0, F_MAXFD); - if (local_max_fd < 0) - local_max_fd = max_fd; -#endif /* TODO HP-UX could use pstat_getproc() if anyone cares about it. */ - _close_open_fd_range(3, local_max_fd, py_fds_to_keep); + _close_open_fds(3, py_fds_to_keep); } /* This loop matches the Lib/os.py _execvpe()'s PATH search when */ @@ -483,28 +506,29 @@ child_exec(char *const exec_array[], 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. */ + 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; - unused = write(errpipe_write, "OSError:", 8); + _Py_write_noraise(errpipe_write, "OSError:", 8); cur = hex_errno + sizeof(hex_errno); while (saved_errno != 0 && cur > hex_errno) { - *--cur = "0123456789ABCDEF"[saved_errno % 16]; + *--cur = Py_hexdigits[saved_errno % 16]; saved_errno /= 16; } - unused = write(errpipe_write, cur, hex_errno + sizeof(hex_errno) - cur); - unused = write(errpipe_write, ":", 1); + _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(). */ - unused = write(errpipe_write, "noexec", 6); + _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 { - unused = write(errpipe_write, "SubprocessError:0:", 18); - unused = write(errpipe_write, err_msg, strlen(err_msg)); + _Py_write_noraise(errpipe_write, "SubprocessError:0:", 18); + _Py_write_noraise(errpipe_write, err_msg, strlen(err_msg)); } - if (unused) return; /* silly? yes! avoids gcc compiler warning. */ } @@ -525,6 +549,9 @@ subprocess_fork_exec(PyObject* self, PyObject *args) int need_to_reenable_gc = 0; char *const *exec_array, *const *argv = NULL, *const *envp = NULL; Py_ssize_t arg_num; +#ifdef WITH_THREAD + int import_lock_held = 0; +#endif if (!PyArg_ParseTuple( args, "OOpOOOiiiiiiiiiiO:fork_exec", @@ -577,10 +604,8 @@ subprocess_fork_exec(PyObject* self, PyObject *args) } exec_array = _PySequence_BytesToCharpArray(executable_list); - if (!exec_array) { - Py_XDECREF(gc_module); - return NULL; - } + 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 @@ -621,7 +646,10 @@ subprocess_fork_exec(PyObject* self, PyObject *args) preexec_fn_args_tuple = PyTuple_New(0); if (!preexec_fn_args_tuple) goto cleanup; +#ifdef WITH_THREAD _PyImport_AcquireLock(); + import_lock_held = 1; +#endif } if (cwd_obj != Py_None) { @@ -664,11 +692,14 @@ subprocess_fork_exec(PyObject* self, PyObject *args) /* Capture the errno exception before errno can be clobbered. */ PyErr_SetFromErrno(PyExc_OSError); } - if (preexec_fn != Py_None && - _PyImport_ReleaseLock() < 0 && !PyErr_Occurred()) { +#ifdef WITH_THREAD + if (preexec_fn != Py_None + && _PyImport_ReleaseLock() < 0 && !PyErr_Occurred()) { PyErr_SetString(PyExc_RuntimeError, "not holding the import lock"); } + import_lock_held = 0; +#endif /* Parent process */ if (envp) @@ -691,18 +722,27 @@ subprocess_fork_exec(PyObject* self, PyObject *args) return PyLong_FromPid(pid); cleanup: +#ifdef WITH_THREAD + if (import_lock_held) + _PyImport_ReleaseLock(); +#endif if (envp) _Py_FreeCharPArray(envp); if (argv) _Py_FreeCharPArray(argv); - _Py_FreeCharPArray(exec_array); + if (exec_array) + _Py_FreeCharPArray(exec_array); Py_XDECREF(converted_args); Py_XDECREF(fast_args); Py_XDECREF(preexec_fn_args_tuple); /* Reenable gc if it was disabled. */ - if (need_to_reenable_gc) + if (need_to_reenable_gc) { + PyObject *exctype, *val, *tb; + PyErr_Fetch(&exctype, &val, &tb); _enable_gc(gc_module); + PyErr_Restore(exctype, val, tb); + } Py_XDECREF(gc_module); return NULL; } @@ -753,11 +793,5 @@ static struct PyModuleDef _posixsubprocessmodule = { PyMODINIT_FUNC PyInit__posixsubprocess(void) { -#ifdef _SC_OPEN_MAX - max_fd = sysconf(_SC_OPEN_MAX); - if (max_fd == -1) -#endif - max_fd = 256; /* Matches Lib/subprocess.py */ - return PyModule_Create(&_posixsubprocessmodule); } diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index 4377ee0cf4d9..95ad4a429a04 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -69,17 +69,21 @@ #include "Python.h" #include /* for seeding to current time */ +#ifndef PY_UINT32_T +# error "Failed to find an exact-width 32-bit integer type" +#endif + /* Period parameters -- These are all magic. Don't change. */ #define N 624 #define M 397 -#define MATRIX_A 0x9908b0dfUL /* constant vector a */ -#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ -#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ +#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 - unsigned long state[N]; int index; + PY_UINT32_T state[N]; } RandomObject; static PyTypeObject Random_Type; @@ -91,13 +95,13 @@ static PyTypeObject Random_Type; /* generates a random number on [0,0xffffffff]-interval */ -static unsigned long +static PY_UINT32_T genrand_int32(RandomObject *self) { - unsigned long y; - static unsigned long mag01[2]={0x0UL, MATRIX_A}; + PY_UINT32_T y; + static PY_UINT32_T mag01[2]={0x0U, MATRIX_A}; /* mag01[x] = x * MATRIX_A for x=0,1 */ - unsigned long *mt; + PY_UINT32_T *mt; mt = self->state; if (self->index >= N) { /* generate N words at one time */ @@ -105,22 +109,22 @@ genrand_int32(RandomObject *self) for (kk=0;kk> 1) ^ mag01[y & 0x1UL]; + mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1U]; } for (;kk> 1) ^ mag01[y & 0x1UL]; + mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1U]; } y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); - mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; + mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1U]; self->index = 0; } y = mt[self->index++]; y ^= (y >> 11); - y ^= (y << 7) & 0x9d2c5680UL; - y ^= (y << 15) & 0xefc60000UL; + y ^= (y << 7) & 0x9d2c5680U; + y ^= (y << 15) & 0xefc60000U; y ^= (y >> 18); return y; } @@ -137,28 +141,26 @@ genrand_int32(RandomObject *self) static PyObject * random_random(RandomObject *self) { - unsigned long a=genrand_int32(self)>>5, b=genrand_int32(self)>>6; + PY_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, unsigned long s) +init_genrand(RandomObject *self, PY_UINT32_T s) { int mti; - unsigned long *mt; + PY_UINT32_T *mt; mt = self->state; - mt[0]= s & 0xffffffffUL; + mt[0]= s; for (mti=1; mti> 30)) + mti); + (1812433253U * (mt[mti-1] ^ (mt[mti-1] >> 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 */ - mt[mti] &= 0xffffffffUL; - /* for >32 bit machines */ } self->index = mti; return; @@ -168,32 +170,30 @@ init_genrand(RandomObject *self, unsigned long s) /* init_key is the array for initializing keys */ /* key_length is its length */ static PyObject * -init_by_array(RandomObject *self, unsigned long init_key[], size_t key_length) +init_by_array(RandomObject *self, PY_UINT32_T init_key[], size_t key_length) { size_t i, j, k; /* was signed in the original code. RDH 12/16/2002 */ - unsigned long *mt; + PY_UINT32_T *mt; mt = self->state; - init_genrand(self, 19650218UL); + 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)) * 1664525UL)) - + init_key[j] + (unsigned long)j; /* non linear */ - mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525U)) + + init_key[j] + (PY_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)) * 1566083941UL)) - - (unsigned long)i; /* non linear */ - mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941U)) + - (PY_UINT32_T)i; /* non linear */ i++; if (i>=N) { mt[0] = mt[N-1]; i=1; } } - mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ + mt[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */ Py_INCREF(Py_None); return Py_None; } @@ -208,9 +208,8 @@ random_seed(RandomObject *self, PyObject *args) { PyObject *result = NULL; /* guilty until proved innocent */ PyObject *n = NULL; - unsigned long *key = NULL; - unsigned char *key_as_bytes = NULL; - size_t bits, keyused, i; + PY_UINT32_T *key = NULL; + size_t bits, keyused; int res; PyObject *arg = NULL; @@ -221,7 +220,7 @@ random_seed(RandomObject *self, PyObject *args) time_t now; time(&now); - init_genrand(self, (unsigned long)now); + init_genrand(self, (PY_UINT32_T)now); Py_INCREF(Py_None); return Py_None; } @@ -249,35 +248,31 @@ random_seed(RandomObject *self, PyObject *args) keyused = bits == 0 ? 1 : (bits - 1) / 32 + 1; /* Convert seed to byte sequence. */ - key_as_bytes = (unsigned char *)PyMem_Malloc((size_t)4 * keyused); - if (key_as_bytes == NULL) { + key = (PY_UINT32_T *)PyMem_Malloc((size_t)4 * keyused); + if (key == NULL) { PyErr_NoMemory(); goto Done; } res = _PyLong_AsByteArray((PyLongObject *)n, - key_as_bytes, keyused * 4, - 1, /* little-endian */ + (unsigned char *)key, keyused * 4, + PY_LITTLE_ENDIAN, 0); /* unsigned */ if (res == -1) { - PyMem_Free(key_as_bytes); + PyMem_Free(key); goto Done; } - /* Fill array of unsigned longs from byte sequence. */ - key = (unsigned long *)PyMem_Malloc(sizeof(unsigned long) * keyused); - if (key == NULL) { - PyErr_NoMemory(); - PyMem_Free(key_as_bytes); - goto Done; - } - for (i = 0; i < keyused; i++) { - key[i] = - ((unsigned long)key_as_bytes[4*i + 0] << 0) + - ((unsigned long)key_as_bytes[4*i + 1] << 8) + - ((unsigned long)key_as_bytes[4*i + 2] << 16) + - ((unsigned long)key_as_bytes[4*i + 3] << 24); +#if PY_BIG_ENDIAN + { + size_t i, j; + /* Reverse an array. */ + for (i = 0, j = keyused - 1; i < j; i++, j--) { + PY_UINT32_T tmp = key[i]; + key[i] = key[j]; + key[j] = tmp; + } } - PyMem_Free(key_as_bytes); +#endif result = init_by_array(self, key, keyused); Done: Py_XDECREF(n); @@ -334,12 +329,16 @@ random_setstate(RandomObject *self, PyObject *state) element = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(state, i)); if (element == (unsigned long)-1 && PyErr_Occurred()) return NULL; - self->state[i] = element & 0xffffffffUL; /* Make sure we get sane state */ + self->state[i] = (PY_UINT32_T)element; } index = PyLong_AsLong(PyTuple_GET_ITEM(state, i)); if (index == -1 && PyErr_Occurred()) return NULL; + if (index < 0 || index > N) { + PyErr_SetString(PyExc_ValueError, "invalid state"); + return NULL; + } self->index = (int)index; Py_INCREF(Py_None); @@ -349,9 +348,9 @@ random_setstate(RandomObject *self, PyObject *state) static PyObject * random_getrandbits(RandomObject *self, PyObject *args) { - int k, i, bytes; - unsigned long r; - unsigned char *bytearray; + int k, i, words; + PY_UINT32_T r; + PY_UINT32_T *wordarray; PyObject *result; if (!PyArg_ParseTuple(args, "i:getrandbits", &k)) @@ -366,27 +365,30 @@ random_getrandbits(RandomObject *self, PyObject *args) if (k <= 32) /* Fast path */ return PyLong_FromUnsignedLong(genrand_int32(self) >> (32 - k)); - bytes = ((k - 1) / 32 + 1) * 4; - bytearray = (unsigned char *)PyMem_Malloc(bytes); - if (bytearray == NULL) { + words = (k - 1) / 32 + 1; + wordarray = (PY_UINT32_T *)PyMem_Malloc(words * 4); + if (wordarray == NULL) { PyErr_NoMemory(); return NULL; } - /* Fill-out whole words, byte-by-byte to avoid endianness issues */ - for (i=0 ; i= 0; i--, k -= 32) +#endif + { r = genrand_int32(self); if (k < 32) - r >>= (32 - k); - bytearray[i+0] = (unsigned char)r; - bytearray[i+1] = (unsigned char)(r >> 8); - bytearray[i+2] = (unsigned char)(r >> 16); - bytearray[i+3] = (unsigned char)(r >> 24); + r >>= (32 - k); /* Drop least significant bits */ + wordarray[i] = r; } - /* little endian order to match bytearray assignment order */ - result = _PyLong_FromByteArray(bytearray, bytes, 1, 0); - PyMem_Free(bytearray); + result = _PyLong_FromByteArray((unsigned char *)wordarray, words * 4, + PY_LITTLE_ENDIAN, 0 /* unsigned */); + PyMem_Free(wordarray); return result; } diff --git a/Modules/_scproxy.c b/Modules/_scproxy.c index 3b2a38ea32fa..66b6e3439f20 100644 --- a/Modules/_scproxy.c +++ b/Modules/_scproxy.c @@ -249,7 +249,7 @@ static struct PyModuleDef mod_module = { extern "C" { #endif -PyObject* +PyMODINIT_FUNC PyInit__scproxy(void) { return PyModule_Create(&mod_module); diff --git a/Modules/_sha3/cleanup.py b/Modules/_sha3/cleanup.py deleted file mode 100755 index aabcb0442cef..000000000000 --- a/Modules/_sha3/cleanup.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/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("\ //(.*)") - -STATICS = ("void ", "int ", "HashReturn ", "const UINT64 ", "UINT16 ") - -HERE = os.path.dirname(os.path.abspath(__file__)) -KECCAK = os.path.join(HERE, "keccak") - -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 */", line) - line = CPP2.sub(r" /* \1 */", 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/Modules/_sha3/keccak/KeccakF-1600-32-rvk.macros b/Modules/_sha3/keccak/KeccakF-1600-32-rvk.macros deleted file mode 100644 index c0c902987376..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-32-rvk.macros +++ /dev/null @@ -1,555 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by Ronny Van Keer, -hereby denoted as "the implementer". - -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/ -*/ - -static const UINT32 KeccakF1600RoundConstants_int2[2*24] = -{ - 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 -}; - -#undef rounds - -#define rounds \ -{ \ - UINT32 Da0, De0, Di0, Do0, Du0; \ - UINT32 Da1, De1, Di1, Do1, Du1; \ - UINT32 Ba, Be, Bi, Bo, Bu; \ - UINT32 Aba0, Abe0, Abi0, Abo0, Abu0; \ - UINT32 Aba1, Abe1, Abi1, Abo1, Abu1; \ - UINT32 Aga0, Age0, Agi0, Ago0, Agu0; \ - UINT32 Aga1, Age1, Agi1, Ago1, Agu1; \ - UINT32 Aka0, Ake0, Aki0, Ako0, Aku0; \ - UINT32 Aka1, Ake1, Aki1, Ako1, Aku1; \ - UINT32 Ama0, Ame0, Ami0, Amo0, Amu0; \ - UINT32 Ama1, Ame1, Ami1, Amo1, Amu1; \ - UINT32 Asa0, Ase0, Asi0, Aso0, Asu0; \ - UINT32 Asa1, Ase1, Asi1, Aso1, Asu1; \ - UINT32 Cw, Cx, Cy, Cz; \ - UINT32 Eba0, Ebe0, Ebi0, Ebo0, Ebu0; \ - UINT32 Eba1, Ebe1, Ebi1, Ebo1, Ebu1; \ - UINT32 Ega0, Ege0, Egi0, Ego0, Egu0; \ - UINT32 Ega1, Ege1, Egi1, Ego1, Egu1; \ - UINT32 Eka0, Eke0, Eki0, Eko0, Eku0; \ - UINT32 Eka1, Eke1, Eki1, Eko1, Eku1; \ - UINT32 Ema0, Eme0, Emi0, Emo0, Emu0; \ - UINT32 Ema1, Eme1, Emi1, Emo1, Emu1; \ - UINT32 Esa0, Ese0, Esi0, Eso0, Esu0; \ - UINT32 Esa1, Ese1, Esi1, Eso1, Esu1; \ - const UINT32 * pRoundConstants = KeccakF1600RoundConstants_int2; \ - UINT32 i; \ -\ - copyFromState(A, state) \ -\ - for( i = 12; i != 0; --i ) { \ - 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; \ -\ - Aba0 ^= Da0; \ - Ba = Aba0; \ - Age0 ^= De0; \ - Be = ROL32(Age0, 22); \ - Aki1 ^= Di1; \ - Bi = ROL32(Aki1, 22); \ - Amo1 ^= Do1; \ - Bo = ROL32(Amo1, 11); \ - Asu0 ^= Du0; \ - Bu = ROL32(Asu0, 7); \ - Eba0 = Ba ^((~Be)& Bi ) ^ *(pRoundConstants++); \ - Ebe0 = Be ^((~Bi)& Bo ); \ - Ebi0 = Bi ^((~Bo)& Bu ); \ - Ebo0 = Bo ^((~Bu)& Ba ); \ - Ebu0 = Bu ^((~Ba)& Be ); \ -\ - Abo0 ^= Do0; \ - Ba = ROL32(Abo0, 14); \ - Agu0 ^= Du0; \ - Be = ROL32(Agu0, 10); \ - Aka1 ^= Da1; \ - Bi = ROL32(Aka1, 2); \ - Ame1 ^= De1; \ - Bo = ROL32(Ame1, 23); \ - Asi1 ^= Di1; \ - Bu = ROL32(Asi1, 31); \ - Ega0 = Ba ^((~Be)& Bi ); \ - Ege0 = Be ^((~Bi)& Bo ); \ - Egi0 = Bi ^((~Bo)& Bu ); \ - Ego0 = Bo ^((~Bu)& Ba ); \ - Egu0 = Bu ^((~Ba)& Be ); \ -\ - Abe1 ^= De1; \ - Ba = ROL32(Abe1, 1); \ - Agi0 ^= Di0; \ - Be = ROL32(Agi0, 3); \ - Ako1 ^= Do1; \ - Bi = ROL32(Ako1, 13); \ - Amu0 ^= Du0; \ - Bo = ROL32(Amu0, 4); \ - Asa0 ^= Da0; \ - Bu = ROL32(Asa0, 9); \ - Eka0 = Ba ^((~Be)& Bi ); \ - Eke0 = Be ^((~Bi)& Bo ); \ - Eki0 = Bi ^((~Bo)& Bu ); \ - Eko0 = Bo ^((~Bu)& Ba ); \ - Eku0 = Bu ^((~Ba)& Be ); \ -\ - Abu1 ^= Du1; \ - Ba = ROL32(Abu1, 14); \ - Aga0 ^= Da0; \ - Be = ROL32(Aga0, 18); \ - Ake0 ^= De0; \ - Bi = ROL32(Ake0, 5); \ - Ami1 ^= Di1; \ - Bo = ROL32(Ami1, 8); \ - Aso0 ^= Do0; \ - Bu = ROL32(Aso0, 28); \ - Ema0 = Ba ^((~Be)& Bi ); \ - Eme0 = Be ^((~Bi)& Bo ); \ - Emi0 = Bi ^((~Bo)& Bu ); \ - Emo0 = Bo ^((~Bu)& Ba ); \ - Emu0 = Bu ^((~Ba)& Be ); \ -\ - Abi0 ^= Di0; \ - Ba = ROL32(Abi0, 31); \ - Ago1 ^= Do1; \ - Be = ROL32(Ago1, 28); \ - Aku1 ^= Du1; \ - Bi = ROL32(Aku1, 20); \ - Ama1 ^= Da1; \ - Bo = ROL32(Ama1, 21); \ - Ase0 ^= De0; \ - Bu = ROL32(Ase0, 1); \ - Esa0 = Ba ^((~Be)& Bi ); \ - Ese0 = Be ^((~Bi)& Bo ); \ - Esi0 = Bi ^((~Bo)& Bu ); \ - Eso0 = Bo ^((~Bu)& Ba ); \ - Esu0 = Bu ^((~Ba)& Be ); \ -\ - Aba1 ^= Da1; \ - Ba = Aba1; \ - Age1 ^= De1; \ - Be = ROL32(Age1, 22); \ - Aki0 ^= Di0; \ - Bi = ROL32(Aki0, 21); \ - Amo0 ^= Do0; \ - Bo = ROL32(Amo0, 10); \ - Asu1 ^= Du1; \ - Bu = ROL32(Asu1, 7); \ - Eba1 = Ba ^((~Be)& Bi ); \ - Eba1 ^= *(pRoundConstants++); \ - Ebe1 = Be ^((~Bi)& Bo ); \ - Ebi1 = Bi ^((~Bo)& Bu ); \ - Ebo1 = Bo ^((~Bu)& Ba ); \ - Ebu1 = Bu ^((~Ba)& Be ); \ -\ - Abo1 ^= Do1; \ - Ba = ROL32(Abo1, 14); \ - Agu1 ^= Du1; \ - Be = ROL32(Agu1, 10); \ - Aka0 ^= Da0; \ - Bi = ROL32(Aka0, 1); \ - Ame0 ^= De0; \ - Bo = ROL32(Ame0, 22); \ - Asi0 ^= Di0; \ - Bu = ROL32(Asi0, 30); \ - Ega1 = Ba ^((~Be)& Bi ); \ - Ege1 = Be ^((~Bi)& Bo ); \ - Egi1 = Bi ^((~Bo)& Bu ); \ - Ego1 = Bo ^((~Bu)& Ba ); \ - Egu1 = Bu ^((~Ba)& Be ); \ -\ - Abe0 ^= De0; \ - Ba = Abe0; \ - Agi1 ^= Di1; \ - Be = ROL32(Agi1, 3); \ - Ako0 ^= Do0; \ - Bi = ROL32(Ako0, 12); \ - Amu1 ^= Du1; \ - Bo = ROL32(Amu1, 4); \ - Asa1 ^= Da1; \ - Bu = ROL32(Asa1, 9); \ - Eka1 = Ba ^((~Be)& Bi ); \ - Eke1 = Be ^((~Bi)& Bo ); \ - Eki1 = Bi ^((~Bo)& Bu ); \ - Eko1 = Bo ^((~Bu)& Ba ); \ - Eku1 = Bu ^((~Ba)& Be ); \ -\ - Abu0 ^= Du0; \ - Ba = ROL32(Abu0, 13); \ - Aga1 ^= Da1; \ - Be = ROL32(Aga1, 18); \ - Ake1 ^= De1; \ - Bi = ROL32(Ake1, 5); \ - Ami0 ^= Di0; \ - Bo = ROL32(Ami0, 7); \ - Aso1 ^= Do1; \ - Bu = ROL32(Aso1, 28); \ - Ema1 = Ba ^((~Be)& Bi ); \ - Eme1 = Be ^((~Bi)& Bo ); \ - Emi1 = Bi ^((~Bo)& Bu ); \ - Emo1 = Bo ^((~Bu)& Ba ); \ - Emu1 = Bu ^((~Ba)& Be ); \ -\ - Abi1 ^= Di1; \ - Ba = ROL32(Abi1, 31); \ - Ago0 ^= Do0; \ - Be = ROL32(Ago0, 27); \ - Aku0 ^= Du0; \ - Bi = ROL32(Aku0, 19); \ - Ama0 ^= Da0; \ - Bo = ROL32(Ama0, 20); \ - Ase1 ^= De1; \ - Bu = ROL32(Ase1, 1); \ - Esa1 = Ba ^((~Be)& Bi ); \ - Ese1 = Be ^((~Bi)& Bo ); \ - Esi1 = Bi ^((~Bo)& Bu ); \ - Eso1 = Bo ^((~Bu)& Ba ); \ - Esu1 = Bu ^((~Ba)& Be ); \ -\ - Cx = Ebu0^Egu0^Eku0^Emu0^Esu0; \ - Du1 = Ebe1^Ege1^Eke1^Eme1^Ese1; \ - Da0 = Cx^ROL32(Du1, 1); \ - Cz = Ebu1^Egu1^Eku1^Emu1^Esu1; \ - Du0 = Ebe0^Ege0^Eke0^Eme0^Ese0; \ - Da1 = Cz^Du0; \ -\ - Cw = Ebi0^Egi0^Eki0^Emi0^Esi0; \ - Do0 = Cw^ROL32(Cz, 1); \ - Cy = Ebi1^Egi1^Eki1^Emi1^Esi1; \ - Do1 = Cy^Cx; \ -\ - Cx = Eba0^Ega0^Eka0^Ema0^Esa0; \ - De0 = Cx^ROL32(Cy, 1); \ - Cz = Eba1^Ega1^Eka1^Ema1^Esa1; \ - De1 = Cz^Cw; \ -\ - Cy = Ebo1^Ego1^Eko1^Emo1^Eso1; \ - Di0 = Du0^ROL32(Cy, 1); \ - Cw = Ebo0^Ego0^Eko0^Emo0^Eso0; \ - Di1 = Du1^Cw; \ -\ - Du0 = Cw^ROL32(Cz, 1); \ - Du1 = Cy^Cx; \ -\ - Eba0 ^= Da0; \ - Ba = Eba0; \ - Ege0 ^= De0; \ - Be = ROL32(Ege0, 22); \ - Eki1 ^= Di1; \ - Bi = ROL32(Eki1, 22); \ - Emo1 ^= Do1; \ - Bo = ROL32(Emo1, 11); \ - Esu0 ^= Du0; \ - Bu = ROL32(Esu0, 7); \ - Aba0 = Ba ^((~Be)& Bi ); \ - Aba0 ^= *(pRoundConstants++); \ - Abe0 = Be ^((~Bi)& Bo ); \ - Abi0 = Bi ^((~Bo)& Bu ); \ - Abo0 = Bo ^((~Bu)& Ba ); \ - Abu0 = Bu ^((~Ba)& Be ); \ -\ - Ebo0 ^= Do0; \ - Ba = ROL32(Ebo0, 14); \ - Egu0 ^= Du0; \ - Be = ROL32(Egu0, 10); \ - Eka1 ^= Da1; \ - Bi = ROL32(Eka1, 2); \ - Eme1 ^= De1; \ - Bo = ROL32(Eme1, 23); \ - Esi1 ^= Di1; \ - Bu = ROL32(Esi1, 31); \ - Aga0 = Ba ^((~Be)& Bi ); \ - Age0 = Be ^((~Bi)& Bo ); \ - Agi0 = Bi ^((~Bo)& Bu ); \ - Ago0 = Bo ^((~Bu)& Ba ); \ - Agu0 = Bu ^((~Ba)& Be ); \ -\ - Ebe1 ^= De1; \ - Ba = ROL32(Ebe1, 1); \ - Egi0 ^= Di0; \ - Be = ROL32(Egi0, 3); \ - Eko1 ^= Do1; \ - Bi = ROL32(Eko1, 13); \ - Emu0 ^= Du0; \ - Bo = ROL32(Emu0, 4); \ - Esa0 ^= Da0; \ - Bu = ROL32(Esa0, 9); \ - Aka0 = Ba ^((~Be)& Bi ); \ - Ake0 = Be ^((~Bi)& Bo ); \ - Aki0 = Bi ^((~Bo)& Bu ); \ - Ako0 = Bo ^((~Bu)& Ba ); \ - Aku0 = Bu ^((~Ba)& Be ); \ -\ - Ebu1 ^= Du1; \ - Ba = ROL32(Ebu1, 14); \ - Ega0 ^= Da0; \ - Be = ROL32(Ega0, 18); \ - Eke0 ^= De0; \ - Bi = ROL32(Eke0, 5); \ - Emi1 ^= Di1; \ - Bo = ROL32(Emi1, 8); \ - Eso0 ^= Do0; \ - Bu = ROL32(Eso0, 28); \ - Ama0 = Ba ^((~Be)& Bi ); \ - Ame0 = Be ^((~Bi)& Bo ); \ - Ami0 = Bi ^((~Bo)& Bu ); \ - Amo0 = Bo ^((~Bu)& Ba ); \ - Amu0 = Bu ^((~Ba)& Be ); \ -\ - Ebi0 ^= Di0; \ - Ba = ROL32(Ebi0, 31); \ - Ego1 ^= Do1; \ - Be = ROL32(Ego1, 28); \ - Eku1 ^= Du1; \ - Bi = ROL32(Eku1, 20); \ - Ema1 ^= Da1; \ - Bo = ROL32(Ema1, 21); \ - Ese0 ^= De0; \ - Bu = ROL32(Ese0, 1); \ - Asa0 = Ba ^((~Be)& Bi ); \ - Ase0 = Be ^((~Bi)& Bo ); \ - Asi0 = Bi ^((~Bo)& Bu ); \ - Aso0 = Bo ^((~Bu)& Ba ); \ - Asu0 = Bu ^((~Ba)& Be ); \ -\ - Eba1 ^= Da1; \ - Ba = Eba1; \ - Ege1 ^= De1; \ - Be = ROL32(Ege1, 22); \ - Eki0 ^= Di0; \ - Bi = ROL32(Eki0, 21); \ - Emo0 ^= Do0; \ - Bo = ROL32(Emo0, 10); \ - Esu1 ^= Du1; \ - Bu = ROL32(Esu1, 7); \ - Aba1 = Ba ^((~Be)& Bi ); \ - Aba1 ^= *(pRoundConstants++); \ - Abe1 = Be ^((~Bi)& Bo ); \ - Abi1 = Bi ^((~Bo)& Bu ); \ - Abo1 = Bo ^((~Bu)& Ba ); \ - Abu1 = Bu ^((~Ba)& Be ); \ -\ - Ebo1 ^= Do1; \ - Ba = ROL32(Ebo1, 14); \ - Egu1 ^= Du1; \ - Be = ROL32(Egu1, 10); \ - Eka0 ^= Da0; \ - Bi = ROL32(Eka0, 1); \ - Eme0 ^= De0; \ - Bo = ROL32(Eme0, 22); \ - Esi0 ^= Di0; \ - Bu = ROL32(Esi0, 30); \ - Aga1 = Ba ^((~Be)& Bi ); \ - Age1 = Be ^((~Bi)& Bo ); \ - Agi1 = Bi ^((~Bo)& Bu ); \ - Ago1 = Bo ^((~Bu)& Ba ); \ - Agu1 = Bu ^((~Ba)& Be ); \ -\ - Ebe0 ^= De0; \ - Ba = Ebe0; \ - Egi1 ^= Di1; \ - Be = ROL32(Egi1, 3); \ - Eko0 ^= Do0; \ - Bi = ROL32(Eko0, 12); \ - Emu1 ^= Du1; \ - Bo = ROL32(Emu1, 4); \ - Esa1 ^= Da1; \ - Bu = ROL32(Esa1, 9); \ - Aka1 = Ba ^((~Be)& Bi ); \ - Ake1 = Be ^((~Bi)& Bo ); \ - Aki1 = Bi ^((~Bo)& Bu ); \ - Ako1 = Bo ^((~Bu)& Ba ); \ - Aku1 = Bu ^((~Ba)& Be ); \ -\ - Ebu0 ^= Du0; \ - Ba = ROL32(Ebu0, 13); \ - Ega1 ^= Da1; \ - Be = ROL32(Ega1, 18); \ - Eke1 ^= De1; \ - Bi = ROL32(Eke1, 5); \ - Emi0 ^= Di0; \ - Bo = ROL32(Emi0, 7); \ - Eso1 ^= Do1; \ - Bu = ROL32(Eso1, 28); \ - Ama1 = Ba ^((~Be)& Bi ); \ - Ame1 = Be ^((~Bi)& Bo ); \ - Ami1 = Bi ^((~Bo)& Bu ); \ - Amo1 = Bo ^((~Bu)& Ba ); \ - Amu1 = Bu ^((~Ba)& Be ); \ -\ - Ebi1 ^= Di1; \ - Ba = ROL32(Ebi1, 31); \ - Ego0 ^= Do0; \ - Be = ROL32(Ego0, 27); \ - Eku0 ^= Du0; \ - Bi = ROL32(Eku0, 19); \ - Ema0 ^= Da0; \ - Bo = ROL32(Ema0, 20); \ - Ese1 ^= De1; \ - Bu = ROL32(Ese1, 1); \ - Asa1 = Ba ^((~Be)& Bi ); \ - Ase1 = Be ^((~Bi)& Bo ); \ - Asi1 = Bi ^((~Bo)& Bu ); \ - Aso1 = Bo ^((~Bu)& Ba ); \ - Asu1 = Bu ^((~Ba)& Be ); \ - } \ - copyToState(state, A) \ -} - -#define copyFromState(X, state) \ - X##ba0 = state[ 0]; \ - X##ba1 = state[ 1]; \ - X##be0 = state[ 2]; \ - X##be1 = state[ 3]; \ - X##bi0 = state[ 4]; \ - X##bi1 = state[ 5]; \ - X##bo0 = state[ 6]; \ - X##bo1 = state[ 7]; \ - X##bu0 = state[ 8]; \ - X##bu1 = state[ 9]; \ - X##ga0 = state[10]; \ - X##ga1 = state[11]; \ - X##ge0 = state[12]; \ - X##ge1 = state[13]; \ - X##gi0 = state[14]; \ - X##gi1 = state[15]; \ - X##go0 = state[16]; \ - X##go1 = state[17]; \ - X##gu0 = state[18]; \ - X##gu1 = state[19]; \ - X##ka0 = state[20]; \ - X##ka1 = state[21]; \ - X##ke0 = state[22]; \ - X##ke1 = state[23]; \ - X##ki0 = state[24]; \ - X##ki1 = state[25]; \ - X##ko0 = state[26]; \ - X##ko1 = state[27]; \ - X##ku0 = state[28]; \ - X##ku1 = state[29]; \ - X##ma0 = state[30]; \ - X##ma1 = state[31]; \ - X##me0 = state[32]; \ - X##me1 = state[33]; \ - X##mi0 = state[34]; \ - X##mi1 = state[35]; \ - X##mo0 = state[36]; \ - X##mo1 = state[37]; \ - X##mu0 = state[38]; \ - X##mu1 = state[39]; \ - X##sa0 = state[40]; \ - X##sa1 = state[41]; \ - X##se0 = state[42]; \ - X##se1 = state[43]; \ - X##si0 = state[44]; \ - X##si1 = state[45]; \ - X##so0 = state[46]; \ - X##so1 = state[47]; \ - X##su0 = state[48]; \ - X##su1 = state[49]; \ - -#define copyToState(state, X) \ - state[ 0] = X##ba0; \ - state[ 1] = X##ba1; \ - state[ 2] = X##be0; \ - state[ 3] = X##be1; \ - state[ 4] = X##bi0; \ - state[ 5] = X##bi1; \ - state[ 6] = X##bo0; \ - state[ 7] = X##bo1; \ - state[ 8] = X##bu0; \ - state[ 9] = X##bu1; \ - state[10] = X##ga0; \ - state[11] = X##ga1; \ - state[12] = X##ge0; \ - state[13] = X##ge1; \ - state[14] = X##gi0; \ - state[15] = X##gi1; \ - state[16] = X##go0; \ - state[17] = X##go1; \ - state[18] = X##gu0; \ - state[19] = X##gu1; \ - state[20] = X##ka0; \ - state[21] = X##ka1; \ - state[22] = X##ke0; \ - state[23] = X##ke1; \ - state[24] = X##ki0; \ - state[25] = X##ki1; \ - state[26] = X##ko0; \ - state[27] = X##ko1; \ - state[28] = X##ku0; \ - state[29] = X##ku1; \ - state[30] = X##ma0; \ - state[31] = X##ma1; \ - state[32] = X##me0; \ - state[33] = X##me1; \ - state[34] = X##mi0; \ - state[35] = X##mi1; \ - state[36] = X##mo0; \ - state[37] = X##mo1; \ - state[38] = X##mu0; \ - state[39] = X##mu1; \ - state[40] = X##sa0; \ - state[41] = X##sa1; \ - state[42] = X##se0; \ - state[43] = X##se1; \ - state[44] = X##si0; \ - state[45] = X##si1; \ - state[46] = X##so0; \ - state[47] = X##so1; \ - state[48] = X##su0; \ - state[49] = X##su1; \ - diff --git a/Modules/_sha3/keccak/KeccakF-1600-32-s1.macros b/Modules/_sha3/keccak/KeccakF-1600-32-s1.macros deleted file mode 100644 index 373d61df6e66..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-32-s1.macros +++ /dev/null @@ -1,1187 +0,0 @@ -/* -Code automatically generated by KeccakTools! - -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -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 \ - UINT32 Aba0, Abe0, Abi0, Abo0, Abu0; \ - UINT32 Aba1, Abe1, Abi1, Abo1, Abu1; \ - UINT32 Aga0, Age0, Agi0, Ago0, Agu0; \ - UINT32 Aga1, Age1, Agi1, Ago1, Agu1; \ - UINT32 Aka0, Ake0, Aki0, Ako0, Aku0; \ - UINT32 Aka1, Ake1, Aki1, Ako1, Aku1; \ - UINT32 Ama0, Ame0, Ami0, Amo0, Amu0; \ - UINT32 Ama1, Ame1, Ami1, Amo1, Amu1; \ - UINT32 Asa0, Ase0, Asi0, Aso0, Asu0; \ - UINT32 Asa1, Ase1, Asi1, Aso1, Asu1; \ - UINT32 Bba0, Bbe0, Bbi0, Bbo0, Bbu0; \ - UINT32 Bba1, Bbe1, Bbi1, Bbo1, Bbu1; \ - UINT32 Bga0, Bge0, Bgi0, Bgo0, Bgu0; \ - UINT32 Bga1, Bge1, Bgi1, Bgo1, Bgu1; \ - UINT32 Bka0, Bke0, Bki0, Bko0, Bku0; \ - UINT32 Bka1, Bke1, Bki1, Bko1, Bku1; \ - UINT32 Bma0, Bme0, Bmi0, Bmo0, Bmu0; \ - UINT32 Bma1, Bme1, Bmi1, Bmo1, Bmu1; \ - UINT32 Bsa0, Bse0, Bsi0, Bso0, Bsu0; \ - UINT32 Bsa1, Bse1, Bsi1, Bso1, Bsu1; \ - UINT32 Ca0, Ce0, Ci0, Co0, Cu0; \ - UINT32 Ca1, Ce1, Ci1, Co1, Cu1; \ - UINT32 Da0, De0, Di0, Do0, Du0; \ - UINT32 Da1, De1, Di1, Do1, Du1; \ - UINT32 Eba0, Ebe0, Ebi0, Ebo0, Ebu0; \ - UINT32 Eba1, Ebe1, Ebi1, Ebo1, Ebu1; \ - UINT32 Ega0, Ege0, Egi0, Ego0, Egu0; \ - UINT32 Ega1, Ege1, Egi1, Ego1, Egu1; \ - UINT32 Eka0, Eke0, Eki0, Eko0, Eku0; \ - UINT32 Eka1, Eke1, Eki1, Eko1, Eku1; \ - UINT32 Ema0, Eme0, Emi0, Emo0, Emu0; \ - UINT32 Ema1, Eme1, Emi1, Emo1, Emu1; \ - UINT32 Esa0, Ese0, Esi0, Eso0, Esu0; \ - UINT32 Esa1, Ese1, Esi1, Eso1, Esu1; \ - -#define prepareTheta \ - Ca0 = Aba0^Aga0^Aka0^Ama0^Asa0; \ - Ca1 = Aba1^Aga1^Aka1^Ama1^Asa1; \ - Ce0 = Abe0^Age0^Ake0^Ame0^Ase0; \ - Ce1 = Abe1^Age1^Ake1^Ame1^Ase1; \ - Ci0 = Abi0^Agi0^Aki0^Ami0^Asi0; \ - Ci1 = Abi1^Agi1^Aki1^Ami1^Asi1; \ - Co0 = Abo0^Ago0^Ako0^Amo0^Aso0; \ - Co1 = Abo1^Ago1^Ako1^Amo1^Aso1; \ - Cu0 = Abu0^Agu0^Aku0^Amu0^Asu0; \ - Cu1 = Abu1^Agu1^Aku1^Amu1^Asu1; \ - -#ifdef UseBebigokimisa -/* --- Code for round, with prepare-theta (lane complementing pattern 'bebigokimisa') */ -/* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - Da0 = Cu0^ROL32(Ce1, 1); \ - Da1 = Cu1^Ce0; \ - De0 = Ca0^ROL32(Ci1, 1); \ - De1 = Ca1^Ci0; \ - Di0 = Ce0^ROL32(Co1, 1); \ - Di1 = Ce1^Co0; \ - Do0 = Ci0^ROL32(Cu1, 1); \ - Do1 = Ci1^Cu0; \ - Du0 = Co0^ROL32(Ca1, 1); \ - Du1 = Co1^Ca0; \ -\ - A##ba0 ^= Da0; \ - Bba0 = A##ba0; \ - A##ge0 ^= De0; \ - Bbe0 = ROL32(A##ge0, 22); \ - A##ki1 ^= Di1; \ - Bbi0 = ROL32(A##ki1, 22); \ - A##mo1 ^= Do1; \ - Bbo0 = ROL32(A##mo1, 11); \ - A##su0 ^= Du0; \ - Bbu0 = ROL32(A##su0, 7); \ - E##ba0 = Bba0 ^( Bbe0 | Bbi0 ); \ - E##ba0 ^= KeccakF1600RoundConstants_int2_0[i]; \ - Ca0 = E##ba0; \ - E##be0 = Bbe0 ^((~Bbi0)| Bbo0 ); \ - Ce0 = E##be0; \ - E##bi0 = Bbi0 ^( Bbo0 & Bbu0 ); \ - Ci0 = E##bi0; \ - E##bo0 = Bbo0 ^( Bbu0 | Bba0 ); \ - Co0 = E##bo0; \ - E##bu0 = Bbu0 ^( Bba0 & Bbe0 ); \ - Cu0 = E##bu0; \ -\ - A##ba1 ^= Da1; \ - Bba1 = A##ba1; \ - A##ge1 ^= De1; \ - Bbe1 = ROL32(A##ge1, 22); \ - A##ki0 ^= Di0; \ - Bbi1 = ROL32(A##ki0, 21); \ - A##mo0 ^= Do0; \ - Bbo1 = ROL32(A##mo0, 10); \ - A##su1 ^= Du1; \ - Bbu1 = ROL32(A##su1, 7); \ - E##ba1 = Bba1 ^( Bbe1 | Bbi1 ); \ - E##ba1 ^= KeccakF1600RoundConstants_int2_1[i]; \ - Ca1 = E##ba1; \ - E##be1 = Bbe1 ^((~Bbi1)| Bbo1 ); \ - Ce1 = E##be1; \ - E##bi1 = Bbi1 ^( Bbo1 & Bbu1 ); \ - Ci1 = E##bi1; \ - E##bo1 = Bbo1 ^( Bbu1 | Bba1 ); \ - Co1 = E##bo1; \ - E##bu1 = Bbu1 ^( Bba1 & Bbe1 ); \ - Cu1 = E##bu1; \ -\ - A##bo0 ^= Do0; \ - Bga0 = ROL32(A##bo0, 14); \ - A##gu0 ^= Du0; \ - Bge0 = ROL32(A##gu0, 10); \ - A##ka1 ^= Da1; \ - Bgi0 = ROL32(A##ka1, 2); \ - A##me1 ^= De1; \ - Bgo0 = ROL32(A##me1, 23); \ - A##si1 ^= Di1; \ - Bgu0 = ROL32(A##si1, 31); \ - E##ga0 = Bga0 ^( Bge0 | Bgi0 ); \ - Ca0 ^= E##ga0; \ - E##ge0 = Bge0 ^( Bgi0 & Bgo0 ); \ - Ce0 ^= E##ge0; \ - E##gi0 = Bgi0 ^( Bgo0 |(~Bgu0)); \ - Ci0 ^= E##gi0; \ - E##go0 = Bgo0 ^( Bgu0 | Bga0 ); \ - Co0 ^= E##go0; \ - E##gu0 = Bgu0 ^( Bga0 & Bge0 ); \ - Cu0 ^= E##gu0; \ -\ - A##bo1 ^= Do1; \ - Bga1 = ROL32(A##bo1, 14); \ - A##gu1 ^= Du1; \ - Bge1 = ROL32(A##gu1, 10); \ - A##ka0 ^= Da0; \ - Bgi1 = ROL32(A##ka0, 1); \ - A##me0 ^= De0; \ - Bgo1 = ROL32(A##me0, 22); \ - A##si0 ^= Di0; \ - Bgu1 = ROL32(A##si0, 30); \ - E##ga1 = Bga1 ^( Bge1 | Bgi1 ); \ - Ca1 ^= E##ga1; \ - E##ge1 = Bge1 ^( Bgi1 & Bgo1 ); \ - Ce1 ^= E##ge1; \ - E##gi1 = Bgi1 ^( Bgo1 |(~Bgu1)); \ - Ci1 ^= E##gi1; \ - E##go1 = Bgo1 ^( Bgu1 | Bga1 ); \ - Co1 ^= E##go1; \ - E##gu1 = Bgu1 ^( Bga1 & Bge1 ); \ - Cu1 ^= E##gu1; \ -\ - A##be1 ^= De1; \ - Bka0 = ROL32(A##be1, 1); \ - A##gi0 ^= Di0; \ - Bke0 = ROL32(A##gi0, 3); \ - A##ko1 ^= Do1; \ - Bki0 = ROL32(A##ko1, 13); \ - A##mu0 ^= Du0; \ - Bko0 = ROL32(A##mu0, 4); \ - A##sa0 ^= Da0; \ - Bku0 = ROL32(A##sa0, 9); \ - E##ka0 = Bka0 ^( Bke0 | Bki0 ); \ - Ca0 ^= E##ka0; \ - E##ke0 = Bke0 ^( Bki0 & Bko0 ); \ - Ce0 ^= E##ke0; \ - E##ki0 = Bki0 ^((~Bko0)& Bku0 ); \ - Ci0 ^= E##ki0; \ - E##ko0 = (~Bko0)^( Bku0 | Bka0 ); \ - Co0 ^= E##ko0; \ - E##ku0 = Bku0 ^( Bka0 & Bke0 ); \ - Cu0 ^= E##ku0; \ -\ - A##be0 ^= De0; \ - Bka1 = A##be0; \ - A##gi1 ^= Di1; \ - Bke1 = ROL32(A##gi1, 3); \ - A##ko0 ^= Do0; \ - Bki1 = ROL32(A##ko0, 12); \ - A##mu1 ^= Du1; \ - Bko1 = ROL32(A##mu1, 4); \ - A##sa1 ^= Da1; \ - Bku1 = ROL32(A##sa1, 9); \ - E##ka1 = Bka1 ^( Bke1 | Bki1 ); \ - Ca1 ^= E##ka1; \ - E##ke1 = Bke1 ^( Bki1 & Bko1 ); \ - Ce1 ^= E##ke1; \ - E##ki1 = Bki1 ^((~Bko1)& Bku1 ); \ - Ci1 ^= E##ki1; \ - E##ko1 = (~Bko1)^( Bku1 | Bka1 ); \ - Co1 ^= E##ko1; \ - E##ku1 = Bku1 ^( Bka1 & Bke1 ); \ - Cu1 ^= E##ku1; \ -\ - A##bu1 ^= Du1; \ - Bma0 = ROL32(A##bu1, 14); \ - A##ga0 ^= Da0; \ - Bme0 = ROL32(A##ga0, 18); \ - A##ke0 ^= De0; \ - Bmi0 = ROL32(A##ke0, 5); \ - A##mi1 ^= Di1; \ - Bmo0 = ROL32(A##mi1, 8); \ - A##so0 ^= Do0; \ - Bmu0 = ROL32(A##so0, 28); \ - E##ma0 = Bma0 ^( Bme0 & Bmi0 ); \ - Ca0 ^= E##ma0; \ - E##me0 = Bme0 ^( Bmi0 | Bmo0 ); \ - Ce0 ^= E##me0; \ - E##mi0 = Bmi0 ^((~Bmo0)| Bmu0 ); \ - Ci0 ^= E##mi0; \ - E##mo0 = (~Bmo0)^( Bmu0 & Bma0 ); \ - Co0 ^= E##mo0; \ - E##mu0 = Bmu0 ^( Bma0 | Bme0 ); \ - Cu0 ^= E##mu0; \ -\ - A##bu0 ^= Du0; \ - Bma1 = ROL32(A##bu0, 13); \ - A##ga1 ^= Da1; \ - Bme1 = ROL32(A##ga1, 18); \ - A##ke1 ^= De1; \ - Bmi1 = ROL32(A##ke1, 5); \ - A##mi0 ^= Di0; \ - Bmo1 = ROL32(A##mi0, 7); \ - A##so1 ^= Do1; \ - Bmu1 = ROL32(A##so1, 28); \ - E##ma1 = Bma1 ^( Bme1 & Bmi1 ); \ - Ca1 ^= E##ma1; \ - E##me1 = Bme1 ^( Bmi1 | Bmo1 ); \ - Ce1 ^= E##me1; \ - E##mi1 = Bmi1 ^((~Bmo1)| Bmu1 ); \ - Ci1 ^= E##mi1; \ - E##mo1 = (~Bmo1)^( Bmu1 & Bma1 ); \ - Co1 ^= E##mo1; \ - E##mu1 = Bmu1 ^( Bma1 | Bme1 ); \ - Cu1 ^= E##mu1; \ -\ - A##bi0 ^= Di0; \ - Bsa0 = ROL32(A##bi0, 31); \ - A##go1 ^= Do1; \ - Bse0 = ROL32(A##go1, 28); \ - A##ku1 ^= Du1; \ - Bsi0 = ROL32(A##ku1, 20); \ - A##ma1 ^= Da1; \ - Bso0 = ROL32(A##ma1, 21); \ - A##se0 ^= De0; \ - Bsu0 = ROL32(A##se0, 1); \ - E##sa0 = Bsa0 ^((~Bse0)& Bsi0 ); \ - Ca0 ^= E##sa0; \ - E##se0 = (~Bse0)^( Bsi0 | Bso0 ); \ - Ce0 ^= E##se0; \ - E##si0 = Bsi0 ^( Bso0 & Bsu0 ); \ - Ci0 ^= E##si0; \ - E##so0 = Bso0 ^( Bsu0 | Bsa0 ); \ - Co0 ^= E##so0; \ - E##su0 = Bsu0 ^( Bsa0 & Bse0 ); \ - Cu0 ^= E##su0; \ -\ - A##bi1 ^= Di1; \ - Bsa1 = ROL32(A##bi1, 31); \ - A##go0 ^= Do0; \ - Bse1 = ROL32(A##go0, 27); \ - A##ku0 ^= Du0; \ - Bsi1 = ROL32(A##ku0, 19); \ - A##ma0 ^= Da0; \ - Bso1 = ROL32(A##ma0, 20); \ - A##se1 ^= De1; \ - Bsu1 = ROL32(A##se1, 1); \ - E##sa1 = Bsa1 ^((~Bse1)& Bsi1 ); \ - Ca1 ^= E##sa1; \ - E##se1 = (~Bse1)^( Bsi1 | Bso1 ); \ - Ce1 ^= E##se1; \ - E##si1 = Bsi1 ^( Bso1 & Bsu1 ); \ - Ci1 ^= E##si1; \ - E##so1 = Bso1 ^( Bsu1 | Bsa1 ); \ - Co1 ^= E##so1; \ - E##su1 = Bsu1 ^( Bsa1 & Bse1 ); \ - Cu1 ^= E##su1; \ -\ - -/* --- Code for round (lane complementing pattern 'bebigokimisa') */ -/* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ -#define thetaRhoPiChiIota(i, A, E) \ - Da0 = Cu0^ROL32(Ce1, 1); \ - Da1 = Cu1^Ce0; \ - De0 = Ca0^ROL32(Ci1, 1); \ - De1 = Ca1^Ci0; \ - Di0 = Ce0^ROL32(Co1, 1); \ - Di1 = Ce1^Co0; \ - Do0 = Ci0^ROL32(Cu1, 1); \ - Do1 = Ci1^Cu0; \ - Du0 = Co0^ROL32(Ca1, 1); \ - Du1 = Co1^Ca0; \ -\ - A##ba0 ^= Da0; \ - Bba0 = A##ba0; \ - A##ge0 ^= De0; \ - Bbe0 = ROL32(A##ge0, 22); \ - A##ki1 ^= Di1; \ - Bbi0 = ROL32(A##ki1, 22); \ - A##mo1 ^= Do1; \ - Bbo0 = ROL32(A##mo1, 11); \ - A##su0 ^= Du0; \ - Bbu0 = ROL32(A##su0, 7); \ - E##ba0 = Bba0 ^( Bbe0 | Bbi0 ); \ - E##ba0 ^= KeccakF1600RoundConstants_int2_0[i]; \ - E##be0 = Bbe0 ^((~Bbi0)| Bbo0 ); \ - E##bi0 = Bbi0 ^( Bbo0 & Bbu0 ); \ - E##bo0 = Bbo0 ^( Bbu0 | Bba0 ); \ - E##bu0 = Bbu0 ^( Bba0 & Bbe0 ); \ -\ - A##ba1 ^= Da1; \ - Bba1 = A##ba1; \ - A##ge1 ^= De1; \ - Bbe1 = ROL32(A##ge1, 22); \ - A##ki0 ^= Di0; \ - Bbi1 = ROL32(A##ki0, 21); \ - A##mo0 ^= Do0; \ - Bbo1 = ROL32(A##mo0, 10); \ - A##su1 ^= Du1; \ - Bbu1 = ROL32(A##su1, 7); \ - E##ba1 = Bba1 ^( Bbe1 | Bbi1 ); \ - E##ba1 ^= KeccakF1600RoundConstants_int2_1[i]; \ - E##be1 = Bbe1 ^((~Bbi1)| Bbo1 ); \ - E##bi1 = Bbi1 ^( Bbo1 & Bbu1 ); \ - E##bo1 = Bbo1 ^( Bbu1 | Bba1 ); \ - E##bu1 = Bbu1 ^( Bba1 & Bbe1 ); \ -\ - A##bo0 ^= Do0; \ - Bga0 = ROL32(A##bo0, 14); \ - A##gu0 ^= Du0; \ - Bge0 = ROL32(A##gu0, 10); \ - A##ka1 ^= Da1; \ - Bgi0 = ROL32(A##ka1, 2); \ - A##me1 ^= De1; \ - Bgo0 = ROL32(A##me1, 23); \ - A##si1 ^= Di1; \ - Bgu0 = ROL32(A##si1, 31); \ - E##ga0 = Bga0 ^( Bge0 | Bgi0 ); \ - E##ge0 = Bge0 ^( Bgi0 & Bgo0 ); \ - E##gi0 = Bgi0 ^( Bgo0 |(~Bgu0)); \ - E##go0 = Bgo0 ^( Bgu0 | Bga0 ); \ - E##gu0 = Bgu0 ^( Bga0 & Bge0 ); \ -\ - A##bo1 ^= Do1; \ - Bga1 = ROL32(A##bo1, 14); \ - A##gu1 ^= Du1; \ - Bge1 = ROL32(A##gu1, 10); \ - A##ka0 ^= Da0; \ - Bgi1 = ROL32(A##ka0, 1); \ - A##me0 ^= De0; \ - Bgo1 = ROL32(A##me0, 22); \ - A##si0 ^= Di0; \ - Bgu1 = ROL32(A##si0, 30); \ - E##ga1 = Bga1 ^( Bge1 | Bgi1 ); \ - E##ge1 = Bge1 ^( Bgi1 & Bgo1 ); \ - E##gi1 = Bgi1 ^( Bgo1 |(~Bgu1)); \ - E##go1 = Bgo1 ^( Bgu1 | Bga1 ); \ - E##gu1 = Bgu1 ^( Bga1 & Bge1 ); \ -\ - A##be1 ^= De1; \ - Bka0 = ROL32(A##be1, 1); \ - A##gi0 ^= Di0; \ - Bke0 = ROL32(A##gi0, 3); \ - A##ko1 ^= Do1; \ - Bki0 = ROL32(A##ko1, 13); \ - A##mu0 ^= Du0; \ - Bko0 = ROL32(A##mu0, 4); \ - A##sa0 ^= Da0; \ - Bku0 = ROL32(A##sa0, 9); \ - E##ka0 = Bka0 ^( Bke0 | Bki0 ); \ - E##ke0 = Bke0 ^( Bki0 & Bko0 ); \ - E##ki0 = Bki0 ^((~Bko0)& Bku0 ); \ - E##ko0 = (~Bko0)^( Bku0 | Bka0 ); \ - E##ku0 = Bku0 ^( Bka0 & Bke0 ); \ -\ - A##be0 ^= De0; \ - Bka1 = A##be0; \ - A##gi1 ^= Di1; \ - Bke1 = ROL32(A##gi1, 3); \ - A##ko0 ^= Do0; \ - Bki1 = ROL32(A##ko0, 12); \ - A##mu1 ^= Du1; \ - Bko1 = ROL32(A##mu1, 4); \ - A##sa1 ^= Da1; \ - Bku1 = ROL32(A##sa1, 9); \ - E##ka1 = Bka1 ^( Bke1 | Bki1 ); \ - E##ke1 = Bke1 ^( Bki1 & Bko1 ); \ - E##ki1 = Bki1 ^((~Bko1)& Bku1 ); \ - E##ko1 = (~Bko1)^( Bku1 | Bka1 ); \ - E##ku1 = Bku1 ^( Bka1 & Bke1 ); \ -\ - A##bu1 ^= Du1; \ - Bma0 = ROL32(A##bu1, 14); \ - A##ga0 ^= Da0; \ - Bme0 = ROL32(A##ga0, 18); \ - A##ke0 ^= De0; \ - Bmi0 = ROL32(A##ke0, 5); \ - A##mi1 ^= Di1; \ - Bmo0 = ROL32(A##mi1, 8); \ - A##so0 ^= Do0; \ - Bmu0 = ROL32(A##so0, 28); \ - E##ma0 = Bma0 ^( Bme0 & Bmi0 ); \ - E##me0 = Bme0 ^( Bmi0 | Bmo0 ); \ - E##mi0 = Bmi0 ^((~Bmo0)| Bmu0 ); \ - E##mo0 = (~Bmo0)^( Bmu0 & Bma0 ); \ - E##mu0 = Bmu0 ^( Bma0 | Bme0 ); \ -\ - A##bu0 ^= Du0; \ - Bma1 = ROL32(A##bu0, 13); \ - A##ga1 ^= Da1; \ - Bme1 = ROL32(A##ga1, 18); \ - A##ke1 ^= De1; \ - Bmi1 = ROL32(A##ke1, 5); \ - A##mi0 ^= Di0; \ - Bmo1 = ROL32(A##mi0, 7); \ - A##so1 ^= Do1; \ - Bmu1 = ROL32(A##so1, 28); \ - E##ma1 = Bma1 ^( Bme1 & Bmi1 ); \ - E##me1 = Bme1 ^( Bmi1 | Bmo1 ); \ - E##mi1 = Bmi1 ^((~Bmo1)| Bmu1 ); \ - E##mo1 = (~Bmo1)^( Bmu1 & Bma1 ); \ - E##mu1 = Bmu1 ^( Bma1 | Bme1 ); \ -\ - A##bi0 ^= Di0; \ - Bsa0 = ROL32(A##bi0, 31); \ - A##go1 ^= Do1; \ - Bse0 = ROL32(A##go1, 28); \ - A##ku1 ^= Du1; \ - Bsi0 = ROL32(A##ku1, 20); \ - A##ma1 ^= Da1; \ - Bso0 = ROL32(A##ma1, 21); \ - A##se0 ^= De0; \ - Bsu0 = ROL32(A##se0, 1); \ - E##sa0 = Bsa0 ^((~Bse0)& Bsi0 ); \ - E##se0 = (~Bse0)^( Bsi0 | Bso0 ); \ - E##si0 = Bsi0 ^( Bso0 & Bsu0 ); \ - E##so0 = Bso0 ^( Bsu0 | Bsa0 ); \ - E##su0 = Bsu0 ^( Bsa0 & Bse0 ); \ -\ - A##bi1 ^= Di1; \ - Bsa1 = ROL32(A##bi1, 31); \ - A##go0 ^= Do0; \ - Bse1 = ROL32(A##go0, 27); \ - A##ku0 ^= Du0; \ - Bsi1 = ROL32(A##ku0, 19); \ - A##ma0 ^= Da0; \ - Bso1 = ROL32(A##ma0, 20); \ - A##se1 ^= De1; \ - Bsu1 = ROL32(A##se1, 1); \ - E##sa1 = Bsa1 ^((~Bse1)& Bsi1 ); \ - E##se1 = (~Bse1)^( Bsi1 | Bso1 ); \ - E##si1 = Bsi1 ^( Bso1 & Bsu1 ); \ - E##so1 = Bso1 ^( Bsu1 | Bsa1 ); \ - E##su1 = Bsu1 ^( Bsa1 & Bse1 ); \ -\ - -#else /* UseBebigokimisa */ -/* --- Code for round, with prepare-theta */ -/* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - Da0 = Cu0^ROL32(Ce1, 1); \ - Da1 = Cu1^Ce0; \ - De0 = Ca0^ROL32(Ci1, 1); \ - De1 = Ca1^Ci0; \ - Di0 = Ce0^ROL32(Co1, 1); \ - Di1 = Ce1^Co0; \ - Do0 = Ci0^ROL32(Cu1, 1); \ - Do1 = Ci1^Cu0; \ - Du0 = Co0^ROL32(Ca1, 1); \ - Du1 = Co1^Ca0; \ -\ - A##ba0 ^= Da0; \ - Bba0 = A##ba0; \ - A##ge0 ^= De0; \ - Bbe0 = ROL32(A##ge0, 22); \ - A##ki1 ^= Di1; \ - Bbi0 = ROL32(A##ki1, 22); \ - A##mo1 ^= Do1; \ - Bbo0 = ROL32(A##mo1, 11); \ - A##su0 ^= Du0; \ - Bbu0 = ROL32(A##su0, 7); \ - E##ba0 = Bba0 ^((~Bbe0)& Bbi0 ); \ - E##ba0 ^= KeccakF1600RoundConstants_int2_0[i]; \ - Ca0 = E##ba0; \ - E##be0 = Bbe0 ^((~Bbi0)& Bbo0 ); \ - Ce0 = E##be0; \ - E##bi0 = Bbi0 ^((~Bbo0)& Bbu0 ); \ - Ci0 = E##bi0; \ - E##bo0 = Bbo0 ^((~Bbu0)& Bba0 ); \ - Co0 = E##bo0; \ - E##bu0 = Bbu0 ^((~Bba0)& Bbe0 ); \ - Cu0 = E##bu0; \ -\ - A##ba1 ^= Da1; \ - Bba1 = A##ba1; \ - A##ge1 ^= De1; \ - Bbe1 = ROL32(A##ge1, 22); \ - A##ki0 ^= Di0; \ - Bbi1 = ROL32(A##ki0, 21); \ - A##mo0 ^= Do0; \ - Bbo1 = ROL32(A##mo0, 10); \ - A##su1 ^= Du1; \ - Bbu1 = ROL32(A##su1, 7); \ - E##ba1 = Bba1 ^((~Bbe1)& Bbi1 ); \ - E##ba1 ^= KeccakF1600RoundConstants_int2_1[i]; \ - Ca1 = E##ba1; \ - E##be1 = Bbe1 ^((~Bbi1)& Bbo1 ); \ - Ce1 = E##be1; \ - E##bi1 = Bbi1 ^((~Bbo1)& Bbu1 ); \ - Ci1 = E##bi1; \ - E##bo1 = Bbo1 ^((~Bbu1)& Bba1 ); \ - Co1 = E##bo1; \ - E##bu1 = Bbu1 ^((~Bba1)& Bbe1 ); \ - Cu1 = E##bu1; \ -\ - A##bo0 ^= Do0; \ - Bga0 = ROL32(A##bo0, 14); \ - A##gu0 ^= Du0; \ - Bge0 = ROL32(A##gu0, 10); \ - A##ka1 ^= Da1; \ - Bgi0 = ROL32(A##ka1, 2); \ - A##me1 ^= De1; \ - Bgo0 = ROL32(A##me1, 23); \ - A##si1 ^= Di1; \ - Bgu0 = ROL32(A##si1, 31); \ - E##ga0 = Bga0 ^((~Bge0)& Bgi0 ); \ - Ca0 ^= E##ga0; \ - E##ge0 = Bge0 ^((~Bgi0)& Bgo0 ); \ - Ce0 ^= E##ge0; \ - E##gi0 = Bgi0 ^((~Bgo0)& Bgu0 ); \ - Ci0 ^= E##gi0; \ - E##go0 = Bgo0 ^((~Bgu0)& Bga0 ); \ - Co0 ^= E##go0; \ - E##gu0 = Bgu0 ^((~Bga0)& Bge0 ); \ - Cu0 ^= E##gu0; \ -\ - A##bo1 ^= Do1; \ - Bga1 = ROL32(A##bo1, 14); \ - A##gu1 ^= Du1; \ - Bge1 = ROL32(A##gu1, 10); \ - A##ka0 ^= Da0; \ - Bgi1 = ROL32(A##ka0, 1); \ - A##me0 ^= De0; \ - Bgo1 = ROL32(A##me0, 22); \ - A##si0 ^= Di0; \ - Bgu1 = ROL32(A##si0, 30); \ - E##ga1 = Bga1 ^((~Bge1)& Bgi1 ); \ - Ca1 ^= E##ga1; \ - E##ge1 = Bge1 ^((~Bgi1)& Bgo1 ); \ - Ce1 ^= E##ge1; \ - E##gi1 = Bgi1 ^((~Bgo1)& Bgu1 ); \ - Ci1 ^= E##gi1; \ - E##go1 = Bgo1 ^((~Bgu1)& Bga1 ); \ - Co1 ^= E##go1; \ - E##gu1 = Bgu1 ^((~Bga1)& Bge1 ); \ - Cu1 ^= E##gu1; \ -\ - A##be1 ^= De1; \ - Bka0 = ROL32(A##be1, 1); \ - A##gi0 ^= Di0; \ - Bke0 = ROL32(A##gi0, 3); \ - A##ko1 ^= Do1; \ - Bki0 = ROL32(A##ko1, 13); \ - A##mu0 ^= Du0; \ - Bko0 = ROL32(A##mu0, 4); \ - A##sa0 ^= Da0; \ - Bku0 = ROL32(A##sa0, 9); \ - E##ka0 = Bka0 ^((~Bke0)& Bki0 ); \ - Ca0 ^= E##ka0; \ - E##ke0 = Bke0 ^((~Bki0)& Bko0 ); \ - Ce0 ^= E##ke0; \ - E##ki0 = Bki0 ^((~Bko0)& Bku0 ); \ - Ci0 ^= E##ki0; \ - E##ko0 = Bko0 ^((~Bku0)& Bka0 ); \ - Co0 ^= E##ko0; \ - E##ku0 = Bku0 ^((~Bka0)& Bke0 ); \ - Cu0 ^= E##ku0; \ -\ - A##be0 ^= De0; \ - Bka1 = A##be0; \ - A##gi1 ^= Di1; \ - Bke1 = ROL32(A##gi1, 3); \ - A##ko0 ^= Do0; \ - Bki1 = ROL32(A##ko0, 12); \ - A##mu1 ^= Du1; \ - Bko1 = ROL32(A##mu1, 4); \ - A##sa1 ^= Da1; \ - Bku1 = ROL32(A##sa1, 9); \ - E##ka1 = Bka1 ^((~Bke1)& Bki1 ); \ - Ca1 ^= E##ka1; \ - E##ke1 = Bke1 ^((~Bki1)& Bko1 ); \ - Ce1 ^= E##ke1; \ - E##ki1 = Bki1 ^((~Bko1)& Bku1 ); \ - Ci1 ^= E##ki1; \ - E##ko1 = Bko1 ^((~Bku1)& Bka1 ); \ - Co1 ^= E##ko1; \ - E##ku1 = Bku1 ^((~Bka1)& Bke1 ); \ - Cu1 ^= E##ku1; \ -\ - A##bu1 ^= Du1; \ - Bma0 = ROL32(A##bu1, 14); \ - A##ga0 ^= Da0; \ - Bme0 = ROL32(A##ga0, 18); \ - A##ke0 ^= De0; \ - Bmi0 = ROL32(A##ke0, 5); \ - A##mi1 ^= Di1; \ - Bmo0 = ROL32(A##mi1, 8); \ - A##so0 ^= Do0; \ - Bmu0 = ROL32(A##so0, 28); \ - E##ma0 = Bma0 ^((~Bme0)& Bmi0 ); \ - Ca0 ^= E##ma0; \ - E##me0 = Bme0 ^((~Bmi0)& Bmo0 ); \ - Ce0 ^= E##me0; \ - E##mi0 = Bmi0 ^((~Bmo0)& Bmu0 ); \ - Ci0 ^= E##mi0; \ - E##mo0 = Bmo0 ^((~Bmu0)& Bma0 ); \ - Co0 ^= E##mo0; \ - E##mu0 = Bmu0 ^((~Bma0)& Bme0 ); \ - Cu0 ^= E##mu0; \ -\ - A##bu0 ^= Du0; \ - Bma1 = ROL32(A##bu0, 13); \ - A##ga1 ^= Da1; \ - Bme1 = ROL32(A##ga1, 18); \ - A##ke1 ^= De1; \ - Bmi1 = ROL32(A##ke1, 5); \ - A##mi0 ^= Di0; \ - Bmo1 = ROL32(A##mi0, 7); \ - A##so1 ^= Do1; \ - Bmu1 = ROL32(A##so1, 28); \ - E##ma1 = Bma1 ^((~Bme1)& Bmi1 ); \ - Ca1 ^= E##ma1; \ - E##me1 = Bme1 ^((~Bmi1)& Bmo1 ); \ - Ce1 ^= E##me1; \ - E##mi1 = Bmi1 ^((~Bmo1)& Bmu1 ); \ - Ci1 ^= E##mi1; \ - E##mo1 = Bmo1 ^((~Bmu1)& Bma1 ); \ - Co1 ^= E##mo1; \ - E##mu1 = Bmu1 ^((~Bma1)& Bme1 ); \ - Cu1 ^= E##mu1; \ -\ - A##bi0 ^= Di0; \ - Bsa0 = ROL32(A##bi0, 31); \ - A##go1 ^= Do1; \ - Bse0 = ROL32(A##go1, 28); \ - A##ku1 ^= Du1; \ - Bsi0 = ROL32(A##ku1, 20); \ - A##ma1 ^= Da1; \ - Bso0 = ROL32(A##ma1, 21); \ - A##se0 ^= De0; \ - Bsu0 = ROL32(A##se0, 1); \ - E##sa0 = Bsa0 ^((~Bse0)& Bsi0 ); \ - Ca0 ^= E##sa0; \ - E##se0 = Bse0 ^((~Bsi0)& Bso0 ); \ - Ce0 ^= E##se0; \ - E##si0 = Bsi0 ^((~Bso0)& Bsu0 ); \ - Ci0 ^= E##si0; \ - E##so0 = Bso0 ^((~Bsu0)& Bsa0 ); \ - Co0 ^= E##so0; \ - E##su0 = Bsu0 ^((~Bsa0)& Bse0 ); \ - Cu0 ^= E##su0; \ -\ - A##bi1 ^= Di1; \ - Bsa1 = ROL32(A##bi1, 31); \ - A##go0 ^= Do0; \ - Bse1 = ROL32(A##go0, 27); \ - A##ku0 ^= Du0; \ - Bsi1 = ROL32(A##ku0, 19); \ - A##ma0 ^= Da0; \ - Bso1 = ROL32(A##ma0, 20); \ - A##se1 ^= De1; \ - Bsu1 = ROL32(A##se1, 1); \ - E##sa1 = Bsa1 ^((~Bse1)& Bsi1 ); \ - Ca1 ^= E##sa1; \ - E##se1 = Bse1 ^((~Bsi1)& Bso1 ); \ - Ce1 ^= E##se1; \ - E##si1 = Bsi1 ^((~Bso1)& Bsu1 ); \ - Ci1 ^= E##si1; \ - E##so1 = Bso1 ^((~Bsu1)& Bsa1 ); \ - Co1 ^= E##so1; \ - E##su1 = Bsu1 ^((~Bsa1)& Bse1 ); \ - Cu1 ^= E##su1; \ -\ - -/* --- Code for round */ -/* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ -#define thetaRhoPiChiIota(i, A, E) \ - Da0 = Cu0^ROL32(Ce1, 1); \ - Da1 = Cu1^Ce0; \ - De0 = Ca0^ROL32(Ci1, 1); \ - De1 = Ca1^Ci0; \ - Di0 = Ce0^ROL32(Co1, 1); \ - Di1 = Ce1^Co0; \ - Do0 = Ci0^ROL32(Cu1, 1); \ - Do1 = Ci1^Cu0; \ - Du0 = Co0^ROL32(Ca1, 1); \ - Du1 = Co1^Ca0; \ -\ - A##ba0 ^= Da0; \ - Bba0 = A##ba0; \ - A##ge0 ^= De0; \ - Bbe0 = ROL32(A##ge0, 22); \ - A##ki1 ^= Di1; \ - Bbi0 = ROL32(A##ki1, 22); \ - A##mo1 ^= Do1; \ - Bbo0 = ROL32(A##mo1, 11); \ - A##su0 ^= Du0; \ - Bbu0 = ROL32(A##su0, 7); \ - E##ba0 = Bba0 ^((~Bbe0)& Bbi0 ); \ - E##ba0 ^= KeccakF1600RoundConstants_int2_0[i]; \ - E##be0 = Bbe0 ^((~Bbi0)& Bbo0 ); \ - E##bi0 = Bbi0 ^((~Bbo0)& Bbu0 ); \ - E##bo0 = Bbo0 ^((~Bbu0)& Bba0 ); \ - E##bu0 = Bbu0 ^((~Bba0)& Bbe0 ); \ -\ - A##ba1 ^= Da1; \ - Bba1 = A##ba1; \ - A##ge1 ^= De1; \ - Bbe1 = ROL32(A##ge1, 22); \ - A##ki0 ^= Di0; \ - Bbi1 = ROL32(A##ki0, 21); \ - A##mo0 ^= Do0; \ - Bbo1 = ROL32(A##mo0, 10); \ - A##su1 ^= Du1; \ - Bbu1 = ROL32(A##su1, 7); \ - E##ba1 = Bba1 ^((~Bbe1)& Bbi1 ); \ - E##ba1 ^= KeccakF1600RoundConstants_int2_1[i]; \ - E##be1 = Bbe1 ^((~Bbi1)& Bbo1 ); \ - E##bi1 = Bbi1 ^((~Bbo1)& Bbu1 ); \ - E##bo1 = Bbo1 ^((~Bbu1)& Bba1 ); \ - E##bu1 = Bbu1 ^((~Bba1)& Bbe1 ); \ -\ - A##bo0 ^= Do0; \ - Bga0 = ROL32(A##bo0, 14); \ - A##gu0 ^= Du0; \ - Bge0 = ROL32(A##gu0, 10); \ - A##ka1 ^= Da1; \ - Bgi0 = ROL32(A##ka1, 2); \ - A##me1 ^= De1; \ - Bgo0 = ROL32(A##me1, 23); \ - A##si1 ^= Di1; \ - Bgu0 = ROL32(A##si1, 31); \ - E##ga0 = Bga0 ^((~Bge0)& Bgi0 ); \ - E##ge0 = Bge0 ^((~Bgi0)& Bgo0 ); \ - E##gi0 = Bgi0 ^((~Bgo0)& Bgu0 ); \ - E##go0 = Bgo0 ^((~Bgu0)& Bga0 ); \ - E##gu0 = Bgu0 ^((~Bga0)& Bge0 ); \ -\ - A##bo1 ^= Do1; \ - Bga1 = ROL32(A##bo1, 14); \ - A##gu1 ^= Du1; \ - Bge1 = ROL32(A##gu1, 10); \ - A##ka0 ^= Da0; \ - Bgi1 = ROL32(A##ka0, 1); \ - A##me0 ^= De0; \ - Bgo1 = ROL32(A##me0, 22); \ - A##si0 ^= Di0; \ - Bgu1 = ROL32(A##si0, 30); \ - E##ga1 = Bga1 ^((~Bge1)& Bgi1 ); \ - E##ge1 = Bge1 ^((~Bgi1)& Bgo1 ); \ - E##gi1 = Bgi1 ^((~Bgo1)& Bgu1 ); \ - E##go1 = Bgo1 ^((~Bgu1)& Bga1 ); \ - E##gu1 = Bgu1 ^((~Bga1)& Bge1 ); \ -\ - A##be1 ^= De1; \ - Bka0 = ROL32(A##be1, 1); \ - A##gi0 ^= Di0; \ - Bke0 = ROL32(A##gi0, 3); \ - A##ko1 ^= Do1; \ - Bki0 = ROL32(A##ko1, 13); \ - A##mu0 ^= Du0; \ - Bko0 = ROL32(A##mu0, 4); \ - A##sa0 ^= Da0; \ - Bku0 = ROL32(A##sa0, 9); \ - E##ka0 = Bka0 ^((~Bke0)& Bki0 ); \ - E##ke0 = Bke0 ^((~Bki0)& Bko0 ); \ - E##ki0 = Bki0 ^((~Bko0)& Bku0 ); \ - E##ko0 = Bko0 ^((~Bku0)& Bka0 ); \ - E##ku0 = Bku0 ^((~Bka0)& Bke0 ); \ -\ - A##be0 ^= De0; \ - Bka1 = A##be0; \ - A##gi1 ^= Di1; \ - Bke1 = ROL32(A##gi1, 3); \ - A##ko0 ^= Do0; \ - Bki1 = ROL32(A##ko0, 12); \ - A##mu1 ^= Du1; \ - Bko1 = ROL32(A##mu1, 4); \ - A##sa1 ^= Da1; \ - Bku1 = ROL32(A##sa1, 9); \ - E##ka1 = Bka1 ^((~Bke1)& Bki1 ); \ - E##ke1 = Bke1 ^((~Bki1)& Bko1 ); \ - E##ki1 = Bki1 ^((~Bko1)& Bku1 ); \ - E##ko1 = Bko1 ^((~Bku1)& Bka1 ); \ - E##ku1 = Bku1 ^((~Bka1)& Bke1 ); \ -\ - A##bu1 ^= Du1; \ - Bma0 = ROL32(A##bu1, 14); \ - A##ga0 ^= Da0; \ - Bme0 = ROL32(A##ga0, 18); \ - A##ke0 ^= De0; \ - Bmi0 = ROL32(A##ke0, 5); \ - A##mi1 ^= Di1; \ - Bmo0 = ROL32(A##mi1, 8); \ - A##so0 ^= Do0; \ - Bmu0 = ROL32(A##so0, 28); \ - E##ma0 = Bma0 ^((~Bme0)& Bmi0 ); \ - E##me0 = Bme0 ^((~Bmi0)& Bmo0 ); \ - E##mi0 = Bmi0 ^((~Bmo0)& Bmu0 ); \ - E##mo0 = Bmo0 ^((~Bmu0)& Bma0 ); \ - E##mu0 = Bmu0 ^((~Bma0)& Bme0 ); \ -\ - A##bu0 ^= Du0; \ - Bma1 = ROL32(A##bu0, 13); \ - A##ga1 ^= Da1; \ - Bme1 = ROL32(A##ga1, 18); \ - A##ke1 ^= De1; \ - Bmi1 = ROL32(A##ke1, 5); \ - A##mi0 ^= Di0; \ - Bmo1 = ROL32(A##mi0, 7); \ - A##so1 ^= Do1; \ - Bmu1 = ROL32(A##so1, 28); \ - E##ma1 = Bma1 ^((~Bme1)& Bmi1 ); \ - E##me1 = Bme1 ^((~Bmi1)& Bmo1 ); \ - E##mi1 = Bmi1 ^((~Bmo1)& Bmu1 ); \ - E##mo1 = Bmo1 ^((~Bmu1)& Bma1 ); \ - E##mu1 = Bmu1 ^((~Bma1)& Bme1 ); \ -\ - A##bi0 ^= Di0; \ - Bsa0 = ROL32(A##bi0, 31); \ - A##go1 ^= Do1; \ - Bse0 = ROL32(A##go1, 28); \ - A##ku1 ^= Du1; \ - Bsi0 = ROL32(A##ku1, 20); \ - A##ma1 ^= Da1; \ - Bso0 = ROL32(A##ma1, 21); \ - A##se0 ^= De0; \ - Bsu0 = ROL32(A##se0, 1); \ - E##sa0 = Bsa0 ^((~Bse0)& Bsi0 ); \ - E##se0 = Bse0 ^((~Bsi0)& Bso0 ); \ - E##si0 = Bsi0 ^((~Bso0)& Bsu0 ); \ - E##so0 = Bso0 ^((~Bsu0)& Bsa0 ); \ - E##su0 = Bsu0 ^((~Bsa0)& Bse0 ); \ -\ - A##bi1 ^= Di1; \ - Bsa1 = ROL32(A##bi1, 31); \ - A##go0 ^= Do0; \ - Bse1 = ROL32(A##go0, 27); \ - A##ku0 ^= Du0; \ - Bsi1 = ROL32(A##ku0, 19); \ - A##ma0 ^= Da0; \ - Bso1 = ROL32(A##ma0, 20); \ - A##se1 ^= De1; \ - Bsu1 = ROL32(A##se1, 1); \ - E##sa1 = Bsa1 ^((~Bse1)& Bsi1 ); \ - E##se1 = Bse1 ^((~Bsi1)& Bso1 ); \ - E##si1 = Bsi1 ^((~Bso1)& Bsu1 ); \ - E##so1 = Bso1 ^((~Bsu1)& Bsa1 ); \ - E##su1 = Bsu1 ^((~Bsa1)& Bse1 ); \ -\ - -#endif /* UseBebigokimisa */ - -const UINT32 KeccakF1600RoundConstants_int2_0[24] = { - 0x00000001UL, - 0x00000000UL, - 0x00000000UL, - 0x00000000UL, - 0x00000001UL, - 0x00000001UL, - 0x00000001UL, - 0x00000001UL, - 0x00000000UL, - 0x00000000UL, - 0x00000001UL, - 0x00000000UL, - 0x00000001UL, - 0x00000001UL, - 0x00000001UL, - 0x00000001UL, - 0x00000000UL, - 0x00000000UL, - 0x00000000UL, - 0x00000000UL, - 0x00000001UL, - 0x00000000UL, - 0x00000001UL, - 0x00000000UL }; - -const UINT32 KeccakF1600RoundConstants_int2_1[24] = { - 0x00000000UL, - 0x00000089UL, - 0x8000008bUL, - 0x80008080UL, - 0x0000008bUL, - 0x00008000UL, - 0x80008088UL, - 0x80000082UL, - 0x0000000bUL, - 0x0000000aUL, - 0x00008082UL, - 0x00008003UL, - 0x0000808bUL, - 0x8000000bUL, - 0x8000008aUL, - 0x80000081UL, - 0x80000081UL, - 0x80000008UL, - 0x00000083UL, - 0x80008003UL, - 0x80008088UL, - 0x80000088UL, - 0x00008000UL, - 0x80008082UL }; - -#define copyFromStateAndXor1024bits(X, state, input) \ - X##ba0 = state[ 0]^input[ 0]; \ - X##ba1 = state[ 1]^input[ 1]; \ - X##be0 = state[ 2]^input[ 2]; \ - X##be1 = state[ 3]^input[ 3]; \ - X##bi0 = state[ 4]^input[ 4]; \ - X##bi1 = state[ 5]^input[ 5]; \ - X##bo0 = state[ 6]^input[ 6]; \ - X##bo1 = state[ 7]^input[ 7]; \ - X##bu0 = state[ 8]^input[ 8]; \ - X##bu1 = state[ 9]^input[ 9]; \ - X##ga0 = state[10]^input[10]; \ - X##ga1 = state[11]^input[11]; \ - X##ge0 = state[12]^input[12]; \ - X##ge1 = state[13]^input[13]; \ - X##gi0 = state[14]^input[14]; \ - X##gi1 = state[15]^input[15]; \ - X##go0 = state[16]^input[16]; \ - X##go1 = state[17]^input[17]; \ - X##gu0 = state[18]^input[18]; \ - X##gu1 = state[19]^input[19]; \ - X##ka0 = state[20]^input[20]; \ - X##ka1 = state[21]^input[21]; \ - X##ke0 = state[22]^input[22]; \ - X##ke1 = state[23]^input[23]; \ - X##ki0 = state[24]^input[24]; \ - X##ki1 = state[25]^input[25]; \ - X##ko0 = state[26]^input[26]; \ - X##ko1 = state[27]^input[27]; \ - X##ku0 = state[28]^input[28]; \ - X##ku1 = state[29]^input[29]; \ - X##ma0 = state[30]^input[30]; \ - X##ma1 = state[31]^input[31]; \ - X##me0 = state[32]; \ - X##me1 = state[33]; \ - X##mi0 = state[34]; \ - X##mi1 = state[35]; \ - X##mo0 = state[36]; \ - X##mo1 = state[37]; \ - X##mu0 = state[38]; \ - X##mu1 = state[39]; \ - X##sa0 = state[40]; \ - X##sa1 = state[41]; \ - X##se0 = state[42]; \ - X##se1 = state[43]; \ - X##si0 = state[44]; \ - X##si1 = state[45]; \ - X##so0 = state[46]; \ - X##so1 = state[47]; \ - X##su0 = state[48]; \ - X##su1 = state[49]; \ - -#define copyFromStateAndXor1088bits(X, state, input) \ - X##ba0 = state[ 0]^input[ 0]; \ - X##ba1 = state[ 1]^input[ 1]; \ - X##be0 = state[ 2]^input[ 2]; \ - X##be1 = state[ 3]^input[ 3]; \ - X##bi0 = state[ 4]^input[ 4]; \ - X##bi1 = state[ 5]^input[ 5]; \ - X##bo0 = state[ 6]^input[ 6]; \ - X##bo1 = state[ 7]^input[ 7]; \ - X##bu0 = state[ 8]^input[ 8]; \ - X##bu1 = state[ 9]^input[ 9]; \ - X##ga0 = state[10]^input[10]; \ - X##ga1 = state[11]^input[11]; \ - X##ge0 = state[12]^input[12]; \ - X##ge1 = state[13]^input[13]; \ - X##gi0 = state[14]^input[14]; \ - X##gi1 = state[15]^input[15]; \ - X##go0 = state[16]^input[16]; \ - X##go1 = state[17]^input[17]; \ - X##gu0 = state[18]^input[18]; \ - X##gu1 = state[19]^input[19]; \ - X##ka0 = state[20]^input[20]; \ - X##ka1 = state[21]^input[21]; \ - X##ke0 = state[22]^input[22]; \ - X##ke1 = state[23]^input[23]; \ - X##ki0 = state[24]^input[24]; \ - X##ki1 = state[25]^input[25]; \ - X##ko0 = state[26]^input[26]; \ - X##ko1 = state[27]^input[27]; \ - X##ku0 = state[28]^input[28]; \ - X##ku1 = state[29]^input[29]; \ - X##ma0 = state[30]^input[30]; \ - X##ma1 = state[31]^input[31]; \ - X##me0 = state[32]^input[32]; \ - X##me1 = state[33]^input[33]; \ - X##mi0 = state[34]; \ - X##mi1 = state[35]; \ - X##mo0 = state[36]; \ - X##mo1 = state[37]; \ - X##mu0 = state[38]; \ - X##mu1 = state[39]; \ - X##sa0 = state[40]; \ - X##sa1 = state[41]; \ - X##se0 = state[42]; \ - X##se1 = state[43]; \ - X##si0 = state[44]; \ - X##si1 = state[45]; \ - X##so0 = state[46]; \ - X##so1 = state[47]; \ - X##su0 = state[48]; \ - X##su1 = state[49]; \ - -#define copyFromState(X, state) \ - X##ba0 = state[ 0]; \ - X##ba1 = state[ 1]; \ - X##be0 = state[ 2]; \ - X##be1 = state[ 3]; \ - X##bi0 = state[ 4]; \ - X##bi1 = state[ 5]; \ - X##bo0 = state[ 6]; \ - X##bo1 = state[ 7]; \ - X##bu0 = state[ 8]; \ - X##bu1 = state[ 9]; \ - X##ga0 = state[10]; \ - X##ga1 = state[11]; \ - X##ge0 = state[12]; \ - X##ge1 = state[13]; \ - X##gi0 = state[14]; \ - X##gi1 = state[15]; \ - X##go0 = state[16]; \ - X##go1 = state[17]; \ - X##gu0 = state[18]; \ - X##gu1 = state[19]; \ - X##ka0 = state[20]; \ - X##ka1 = state[21]; \ - X##ke0 = state[22]; \ - X##ke1 = state[23]; \ - X##ki0 = state[24]; \ - X##ki1 = state[25]; \ - X##ko0 = state[26]; \ - X##ko1 = state[27]; \ - X##ku0 = state[28]; \ - X##ku1 = state[29]; \ - X##ma0 = state[30]; \ - X##ma1 = state[31]; \ - X##me0 = state[32]; \ - X##me1 = state[33]; \ - X##mi0 = state[34]; \ - X##mi1 = state[35]; \ - X##mo0 = state[36]; \ - X##mo1 = state[37]; \ - X##mu0 = state[38]; \ - X##mu1 = state[39]; \ - X##sa0 = state[40]; \ - X##sa1 = state[41]; \ - X##se0 = state[42]; \ - X##se1 = state[43]; \ - X##si0 = state[44]; \ - X##si1 = state[45]; \ - X##so0 = state[46]; \ - X##so1 = state[47]; \ - X##su0 = state[48]; \ - X##su1 = state[49]; \ - -#define copyToState(state, X) \ - state[ 0] = X##ba0; \ - state[ 1] = X##ba1; \ - state[ 2] = X##be0; \ - state[ 3] = X##be1; \ - state[ 4] = X##bi0; \ - state[ 5] = X##bi1; \ - state[ 6] = X##bo0; \ - state[ 7] = X##bo1; \ - state[ 8] = X##bu0; \ - state[ 9] = X##bu1; \ - state[10] = X##ga0; \ - state[11] = X##ga1; \ - state[12] = X##ge0; \ - state[13] = X##ge1; \ - state[14] = X##gi0; \ - state[15] = X##gi1; \ - state[16] = X##go0; \ - state[17] = X##go1; \ - state[18] = X##gu0; \ - state[19] = X##gu1; \ - state[20] = X##ka0; \ - state[21] = X##ka1; \ - state[22] = X##ke0; \ - state[23] = X##ke1; \ - state[24] = X##ki0; \ - state[25] = X##ki1; \ - state[26] = X##ko0; \ - state[27] = X##ko1; \ - state[28] = X##ku0; \ - state[29] = X##ku1; \ - state[30] = X##ma0; \ - state[31] = X##ma1; \ - state[32] = X##me0; \ - state[33] = X##me1; \ - state[34] = X##mi0; \ - state[35] = X##mi1; \ - state[36] = X##mo0; \ - state[37] = X##mo1; \ - state[38] = X##mu0; \ - state[39] = X##mu1; \ - state[40] = X##sa0; \ - state[41] = X##sa1; \ - state[42] = X##se0; \ - state[43] = X##se1; \ - state[44] = X##si0; \ - state[45] = X##si1; \ - state[46] = X##so0; \ - state[47] = X##so1; \ - state[48] = X##su0; \ - state[49] = X##su1; \ - -#define copyStateVariables(X, Y) \ - X##ba0 = Y##ba0; \ - X##ba1 = Y##ba1; \ - X##be0 = Y##be0; \ - X##be1 = Y##be1; \ - X##bi0 = Y##bi0; \ - X##bi1 = Y##bi1; \ - X##bo0 = Y##bo0; \ - X##bo1 = Y##bo1; \ - X##bu0 = Y##bu0; \ - X##bu1 = Y##bu1; \ - X##ga0 = Y##ga0; \ - X##ga1 = Y##ga1; \ - X##ge0 = Y##ge0; \ - X##ge1 = Y##ge1; \ - X##gi0 = Y##gi0; \ - X##gi1 = Y##gi1; \ - X##go0 = Y##go0; \ - X##go1 = Y##go1; \ - X##gu0 = Y##gu0; \ - X##gu1 = Y##gu1; \ - X##ka0 = Y##ka0; \ - X##ka1 = Y##ka1; \ - X##ke0 = Y##ke0; \ - X##ke1 = Y##ke1; \ - X##ki0 = Y##ki0; \ - X##ki1 = Y##ki1; \ - X##ko0 = Y##ko0; \ - X##ko1 = Y##ko1; \ - X##ku0 = Y##ku0; \ - X##ku1 = Y##ku1; \ - X##ma0 = Y##ma0; \ - X##ma1 = Y##ma1; \ - X##me0 = Y##me0; \ - X##me1 = Y##me1; \ - X##mi0 = Y##mi0; \ - X##mi1 = Y##mi1; \ - X##mo0 = Y##mo0; \ - X##mo1 = Y##mo1; \ - X##mu0 = Y##mu0; \ - X##mu1 = Y##mu1; \ - X##sa0 = Y##sa0; \ - X##sa1 = Y##sa1; \ - X##se0 = Y##se0; \ - X##se1 = Y##se1; \ - X##si0 = Y##si0; \ - X##si1 = Y##si1; \ - X##so0 = Y##so0; \ - X##so1 = Y##so1; \ - X##su0 = Y##su0; \ - X##su1 = Y##su1; \ - diff --git a/Modules/_sha3/keccak/KeccakF-1600-32-s2.macros b/Modules/_sha3/keccak/KeccakF-1600-32-s2.macros deleted file mode 100644 index fa1176219a4b..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-32-s2.macros +++ /dev/null @@ -1,1187 +0,0 @@ -/* -Code automatically generated by KeccakTools! - -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -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 \ - UINT32 Aba0, Abe0, Abi0, Abo0, Abu0; \ - UINT32 Aba1, Abe1, Abi1, Abo1, Abu1; \ - UINT32 Aga0, Age0, Agi0, Ago0, Agu0; \ - UINT32 Aga1, Age1, Agi1, Ago1, Agu1; \ - UINT32 Aka0, Ake0, Aki0, Ako0, Aku0; \ - UINT32 Aka1, Ake1, Aki1, Ako1, Aku1; \ - UINT32 Ama0, Ame0, Ami0, Amo0, Amu0; \ - UINT32 Ama1, Ame1, Ami1, Amo1, Amu1; \ - UINT32 Asa0, Ase0, Asi0, Aso0, Asu0; \ - UINT32 Asa1, Ase1, Asi1, Aso1, Asu1; \ - UINT32 Bba0, Bbe0, Bbi0, Bbo0, Bbu0; \ - UINT32 Bba1, Bbe1, Bbi1, Bbo1, Bbu1; \ - UINT32 Bga0, Bge0, Bgi0, Bgo0, Bgu0; \ - UINT32 Bga1, Bge1, Bgi1, Bgo1, Bgu1; \ - UINT32 Bka0, Bke0, Bki0, Bko0, Bku0; \ - UINT32 Bka1, Bke1, Bki1, Bko1, Bku1; \ - UINT32 Bma0, Bme0, Bmi0, Bmo0, Bmu0; \ - UINT32 Bma1, Bme1, Bmi1, Bmo1, Bmu1; \ - UINT32 Bsa0, Bse0, Bsi0, Bso0, Bsu0; \ - UINT32 Bsa1, Bse1, Bsi1, Bso1, Bsu1; \ - UINT32 Ca0, Ce0, Ci0, Co0, Cu0; \ - UINT32 Ca1, Ce1, Ci1, Co1, Cu1; \ - UINT32 Da0, De0, Di0, Do0, Du0; \ - UINT32 Da1, De1, Di1, Do1, Du1; \ - UINT32 Eba0, Ebe0, Ebi0, Ebo0, Ebu0; \ - UINT32 Eba1, Ebe1, Ebi1, Ebo1, Ebu1; \ - UINT32 Ega0, Ege0, Egi0, Ego0, Egu0; \ - UINT32 Ega1, Ege1, Egi1, Ego1, Egu1; \ - UINT32 Eka0, Eke0, Eki0, Eko0, Eku0; \ - UINT32 Eka1, Eke1, Eki1, Eko1, Eku1; \ - UINT32 Ema0, Eme0, Emi0, Emo0, Emu0; \ - UINT32 Ema1, Eme1, Emi1, Emo1, Emu1; \ - UINT32 Esa0, Ese0, Esi0, Eso0, Esu0; \ - UINT32 Esa1, Ese1, Esi1, Eso1, Esu1; \ - -#define prepareTheta \ - Ca0 = Aba0^Aga0^Aka0^Ama0^Asa0; \ - Ca1 = Aba1^Aga1^Aka1^Ama1^Asa1; \ - Ce0 = Abe0^Age0^Ake0^Ame0^Ase0; \ - Ce1 = Abe1^Age1^Ake1^Ame1^Ase1; \ - Ci0 = Abi0^Agi0^Aki0^Ami0^Asi0; \ - Ci1 = Abi1^Agi1^Aki1^Ami1^Asi1; \ - Co0 = Abo0^Ago0^Ako0^Amo0^Aso0; \ - Co1 = Abo1^Ago1^Ako1^Amo1^Aso1; \ - Cu0 = Abu0^Agu0^Aku0^Amu0^Asu0; \ - Cu1 = Abu1^Agu1^Aku1^Amu1^Asu1; \ - -#ifdef UseBebigokimisa -/* --- Code for round, with prepare-theta (lane complementing pattern 'bebigokimisa') */ -/* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - Da0 = Cu0^ROL32(Ce1, 1); \ - Da1 = Cu1^Ce0; \ - De0 = Ca0^ROL32(Ci1, 1); \ - De1 = Ca1^Ci0; \ - Di0 = Ce0^ROL32(Co1, 1); \ - Di1 = Ce1^Co0; \ - Do0 = Ci0^ROL32(Cu1, 1); \ - Do1 = Ci1^Cu0; \ - Du0 = Co0^ROL32(Ca1, 1); \ - Du1 = Co1^Ca0; \ -\ - A##ba0 ^= Da0; \ - Bba0 = A##ba0; \ - A##ge0 ^= De0; \ - Bbe0 = ROL32(A##ge0, 22); \ - A##ki1 ^= Di1; \ - Bbi0 = ROL32(A##ki1, 22); \ - E##ba0 = Bba0 ^( Bbe0 | Bbi0 ); \ - E##ba0 ^= KeccakF1600RoundConstants_int2_0[i]; \ - Ca0 = E##ba0; \ - A##mo1 ^= Do1; \ - Bbo0 = ROL32(A##mo1, 11); \ - E##be0 = Bbe0 ^((~Bbi0)| Bbo0 ); \ - Ce0 = E##be0; \ - A##su0 ^= Du0; \ - Bbu0 = ROL32(A##su0, 7); \ - E##bi0 = Bbi0 ^( Bbo0 & Bbu0 ); \ - Ci0 = E##bi0; \ - E##bo0 = Bbo0 ^( Bbu0 | Bba0 ); \ - Co0 = E##bo0; \ - E##bu0 = Bbu0 ^( Bba0 & Bbe0 ); \ - Cu0 = E##bu0; \ -\ - A##ba1 ^= Da1; \ - Bba1 = A##ba1; \ - A##ge1 ^= De1; \ - Bbe1 = ROL32(A##ge1, 22); \ - A##ki0 ^= Di0; \ - Bbi1 = ROL32(A##ki0, 21); \ - E##ba1 = Bba1 ^( Bbe1 | Bbi1 ); \ - E##ba1 ^= KeccakF1600RoundConstants_int2_1[i]; \ - Ca1 = E##ba1; \ - A##mo0 ^= Do0; \ - Bbo1 = ROL32(A##mo0, 10); \ - E##be1 = Bbe1 ^((~Bbi1)| Bbo1 ); \ - Ce1 = E##be1; \ - A##su1 ^= Du1; \ - Bbu1 = ROL32(A##su1, 7); \ - E##bi1 = Bbi1 ^( Bbo1 & Bbu1 ); \ - Ci1 = E##bi1; \ - E##bo1 = Bbo1 ^( Bbu1 | Bba1 ); \ - Co1 = E##bo1; \ - E##bu1 = Bbu1 ^( Bba1 & Bbe1 ); \ - Cu1 = E##bu1; \ -\ - A##bo0 ^= Do0; \ - Bga0 = ROL32(A##bo0, 14); \ - A##gu0 ^= Du0; \ - Bge0 = ROL32(A##gu0, 10); \ - A##ka1 ^= Da1; \ - Bgi0 = ROL32(A##ka1, 2); \ - E##ga0 = Bga0 ^( Bge0 | Bgi0 ); \ - Ca0 ^= E##ga0; \ - A##me1 ^= De1; \ - Bgo0 = ROL32(A##me1, 23); \ - E##ge0 = Bge0 ^( Bgi0 & Bgo0 ); \ - Ce0 ^= E##ge0; \ - A##si1 ^= Di1; \ - Bgu0 = ROL32(A##si1, 31); \ - E##gi0 = Bgi0 ^( Bgo0 |(~Bgu0)); \ - Ci0 ^= E##gi0; \ - E##go0 = Bgo0 ^( Bgu0 | Bga0 ); \ - Co0 ^= E##go0; \ - E##gu0 = Bgu0 ^( Bga0 & Bge0 ); \ - Cu0 ^= E##gu0; \ -\ - A##bo1 ^= Do1; \ - Bga1 = ROL32(A##bo1, 14); \ - A##gu1 ^= Du1; \ - Bge1 = ROL32(A##gu1, 10); \ - A##ka0 ^= Da0; \ - Bgi1 = ROL32(A##ka0, 1); \ - E##ga1 = Bga1 ^( Bge1 | Bgi1 ); \ - Ca1 ^= E##ga1; \ - A##me0 ^= De0; \ - Bgo1 = ROL32(A##me0, 22); \ - E##ge1 = Bge1 ^( Bgi1 & Bgo1 ); \ - Ce1 ^= E##ge1; \ - A##si0 ^= Di0; \ - Bgu1 = ROL32(A##si0, 30); \ - E##gi1 = Bgi1 ^( Bgo1 |(~Bgu1)); \ - Ci1 ^= E##gi1; \ - E##go1 = Bgo1 ^( Bgu1 | Bga1 ); \ - Co1 ^= E##go1; \ - E##gu1 = Bgu1 ^( Bga1 & Bge1 ); \ - Cu1 ^= E##gu1; \ -\ - A##be1 ^= De1; \ - Bka0 = ROL32(A##be1, 1); \ - A##gi0 ^= Di0; \ - Bke0 = ROL32(A##gi0, 3); \ - A##ko1 ^= Do1; \ - Bki0 = ROL32(A##ko1, 13); \ - E##ka0 = Bka0 ^( Bke0 | Bki0 ); \ - Ca0 ^= E##ka0; \ - A##mu0 ^= Du0; \ - Bko0 = ROL32(A##mu0, 4); \ - E##ke0 = Bke0 ^( Bki0 & Bko0 ); \ - Ce0 ^= E##ke0; \ - A##sa0 ^= Da0; \ - Bku0 = ROL32(A##sa0, 9); \ - E##ki0 = Bki0 ^((~Bko0)& Bku0 ); \ - Ci0 ^= E##ki0; \ - E##ko0 = (~Bko0)^( Bku0 | Bka0 ); \ - Co0 ^= E##ko0; \ - E##ku0 = Bku0 ^( Bka0 & Bke0 ); \ - Cu0 ^= E##ku0; \ -\ - A##be0 ^= De0; \ - Bka1 = A##be0; \ - A##gi1 ^= Di1; \ - Bke1 = ROL32(A##gi1, 3); \ - A##ko0 ^= Do0; \ - Bki1 = ROL32(A##ko0, 12); \ - E##ka1 = Bka1 ^( Bke1 | Bki1 ); \ - Ca1 ^= E##ka1; \ - A##mu1 ^= Du1; \ - Bko1 = ROL32(A##mu1, 4); \ - E##ke1 = Bke1 ^( Bki1 & Bko1 ); \ - Ce1 ^= E##ke1; \ - A##sa1 ^= Da1; \ - Bku1 = ROL32(A##sa1, 9); \ - E##ki1 = Bki1 ^((~Bko1)& Bku1 ); \ - Ci1 ^= E##ki1; \ - E##ko1 = (~Bko1)^( Bku1 | Bka1 ); \ - Co1 ^= E##ko1; \ - E##ku1 = Bku1 ^( Bka1 & Bke1 ); \ - Cu1 ^= E##ku1; \ -\ - A##bu1 ^= Du1; \ - Bma0 = ROL32(A##bu1, 14); \ - A##ga0 ^= Da0; \ - Bme0 = ROL32(A##ga0, 18); \ - A##ke0 ^= De0; \ - Bmi0 = ROL32(A##ke0, 5); \ - E##ma0 = Bma0 ^( Bme0 & Bmi0 ); \ - Ca0 ^= E##ma0; \ - A##mi1 ^= Di1; \ - Bmo0 = ROL32(A##mi1, 8); \ - E##me0 = Bme0 ^( Bmi0 | Bmo0 ); \ - Ce0 ^= E##me0; \ - A##so0 ^= Do0; \ - Bmu0 = ROL32(A##so0, 28); \ - E##mi0 = Bmi0 ^((~Bmo0)| Bmu0 ); \ - Ci0 ^= E##mi0; \ - E##mo0 = (~Bmo0)^( Bmu0 & Bma0 ); \ - Co0 ^= E##mo0; \ - E##mu0 = Bmu0 ^( Bma0 | Bme0 ); \ - Cu0 ^= E##mu0; \ -\ - A##bu0 ^= Du0; \ - Bma1 = ROL32(A##bu0, 13); \ - A##ga1 ^= Da1; \ - Bme1 = ROL32(A##ga1, 18); \ - A##ke1 ^= De1; \ - Bmi1 = ROL32(A##ke1, 5); \ - E##ma1 = Bma1 ^( Bme1 & Bmi1 ); \ - Ca1 ^= E##ma1; \ - A##mi0 ^= Di0; \ - Bmo1 = ROL32(A##mi0, 7); \ - E##me1 = Bme1 ^( Bmi1 | Bmo1 ); \ - Ce1 ^= E##me1; \ - A##so1 ^= Do1; \ - Bmu1 = ROL32(A##so1, 28); \ - E##mi1 = Bmi1 ^((~Bmo1)| Bmu1 ); \ - Ci1 ^= E##mi1; \ - E##mo1 = (~Bmo1)^( Bmu1 & Bma1 ); \ - Co1 ^= E##mo1; \ - E##mu1 = Bmu1 ^( Bma1 | Bme1 ); \ - Cu1 ^= E##mu1; \ -\ - A##bi0 ^= Di0; \ - Bsa0 = ROL32(A##bi0, 31); \ - A##go1 ^= Do1; \ - Bse0 = ROL32(A##go1, 28); \ - A##ku1 ^= Du1; \ - Bsi0 = ROL32(A##ku1, 20); \ - E##sa0 = Bsa0 ^((~Bse0)& Bsi0 ); \ - Ca0 ^= E##sa0; \ - A##ma1 ^= Da1; \ - Bso0 = ROL32(A##ma1, 21); \ - E##se0 = (~Bse0)^( Bsi0 | Bso0 ); \ - Ce0 ^= E##se0; \ - A##se0 ^= De0; \ - Bsu0 = ROL32(A##se0, 1); \ - E##si0 = Bsi0 ^( Bso0 & Bsu0 ); \ - Ci0 ^= E##si0; \ - E##so0 = Bso0 ^( Bsu0 | Bsa0 ); \ - Co0 ^= E##so0; \ - E##su0 = Bsu0 ^( Bsa0 & Bse0 ); \ - Cu0 ^= E##su0; \ -\ - A##bi1 ^= Di1; \ - Bsa1 = ROL32(A##bi1, 31); \ - A##go0 ^= Do0; \ - Bse1 = ROL32(A##go0, 27); \ - A##ku0 ^= Du0; \ - Bsi1 = ROL32(A##ku0, 19); \ - E##sa1 = Bsa1 ^((~Bse1)& Bsi1 ); \ - Ca1 ^= E##sa1; \ - A##ma0 ^= Da0; \ - Bso1 = ROL32(A##ma0, 20); \ - E##se1 = (~Bse1)^( Bsi1 | Bso1 ); \ - Ce1 ^= E##se1; \ - A##se1 ^= De1; \ - Bsu1 = ROL32(A##se1, 1); \ - E##si1 = Bsi1 ^( Bso1 & Bsu1 ); \ - Ci1 ^= E##si1; \ - E##so1 = Bso1 ^( Bsu1 | Bsa1 ); \ - Co1 ^= E##so1; \ - E##su1 = Bsu1 ^( Bsa1 & Bse1 ); \ - Cu1 ^= E##su1; \ -\ - -/* --- Code for round (lane complementing pattern 'bebigokimisa') */ -/* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ -#define thetaRhoPiChiIota(i, A, E) \ - Da0 = Cu0^ROL32(Ce1, 1); \ - Da1 = Cu1^Ce0; \ - De0 = Ca0^ROL32(Ci1, 1); \ - De1 = Ca1^Ci0; \ - Di0 = Ce0^ROL32(Co1, 1); \ - Di1 = Ce1^Co0; \ - Do0 = Ci0^ROL32(Cu1, 1); \ - Do1 = Ci1^Cu0; \ - Du0 = Co0^ROL32(Ca1, 1); \ - Du1 = Co1^Ca0; \ -\ - A##ba0 ^= Da0; \ - Bba0 = A##ba0; \ - A##ge0 ^= De0; \ - Bbe0 = ROL32(A##ge0, 22); \ - A##ki1 ^= Di1; \ - Bbi0 = ROL32(A##ki1, 22); \ - E##ba0 = Bba0 ^( Bbe0 | Bbi0 ); \ - E##ba0 ^= KeccakF1600RoundConstants_int2_0[i]; \ - A##mo1 ^= Do1; \ - Bbo0 = ROL32(A##mo1, 11); \ - E##be0 = Bbe0 ^((~Bbi0)| Bbo0 ); \ - A##su0 ^= Du0; \ - Bbu0 = ROL32(A##su0, 7); \ - E##bi0 = Bbi0 ^( Bbo0 & Bbu0 ); \ - E##bo0 = Bbo0 ^( Bbu0 | Bba0 ); \ - E##bu0 = Bbu0 ^( Bba0 & Bbe0 ); \ -\ - A##ba1 ^= Da1; \ - Bba1 = A##ba1; \ - A##ge1 ^= De1; \ - Bbe1 = ROL32(A##ge1, 22); \ - A##ki0 ^= Di0; \ - Bbi1 = ROL32(A##ki0, 21); \ - E##ba1 = Bba1 ^( Bbe1 | Bbi1 ); \ - E##ba1 ^= KeccakF1600RoundConstants_int2_1[i]; \ - A##mo0 ^= Do0; \ - Bbo1 = ROL32(A##mo0, 10); \ - E##be1 = Bbe1 ^((~Bbi1)| Bbo1 ); \ - A##su1 ^= Du1; \ - Bbu1 = ROL32(A##su1, 7); \ - E##bi1 = Bbi1 ^( Bbo1 & Bbu1 ); \ - E##bo1 = Bbo1 ^( Bbu1 | Bba1 ); \ - E##bu1 = Bbu1 ^( Bba1 & Bbe1 ); \ -\ - A##bo0 ^= Do0; \ - Bga0 = ROL32(A##bo0, 14); \ - A##gu0 ^= Du0; \ - Bge0 = ROL32(A##gu0, 10); \ - A##ka1 ^= Da1; \ - Bgi0 = ROL32(A##ka1, 2); \ - E##ga0 = Bga0 ^( Bge0 | Bgi0 ); \ - A##me1 ^= De1; \ - Bgo0 = ROL32(A##me1, 23); \ - E##ge0 = Bge0 ^( Bgi0 & Bgo0 ); \ - A##si1 ^= Di1; \ - Bgu0 = ROL32(A##si1, 31); \ - E##gi0 = Bgi0 ^( Bgo0 |(~Bgu0)); \ - E##go0 = Bgo0 ^( Bgu0 | Bga0 ); \ - E##gu0 = Bgu0 ^( Bga0 & Bge0 ); \ -\ - A##bo1 ^= Do1; \ - Bga1 = ROL32(A##bo1, 14); \ - A##gu1 ^= Du1; \ - Bge1 = ROL32(A##gu1, 10); \ - A##ka0 ^= Da0; \ - Bgi1 = ROL32(A##ka0, 1); \ - E##ga1 = Bga1 ^( Bge1 | Bgi1 ); \ - A##me0 ^= De0; \ - Bgo1 = ROL32(A##me0, 22); \ - E##ge1 = Bge1 ^( Bgi1 & Bgo1 ); \ - A##si0 ^= Di0; \ - Bgu1 = ROL32(A##si0, 30); \ - E##gi1 = Bgi1 ^( Bgo1 |(~Bgu1)); \ - E##go1 = Bgo1 ^( Bgu1 | Bga1 ); \ - E##gu1 = Bgu1 ^( Bga1 & Bge1 ); \ -\ - A##be1 ^= De1; \ - Bka0 = ROL32(A##be1, 1); \ - A##gi0 ^= Di0; \ - Bke0 = ROL32(A##gi0, 3); \ - A##ko1 ^= Do1; \ - Bki0 = ROL32(A##ko1, 13); \ - E##ka0 = Bka0 ^( Bke0 | Bki0 ); \ - A##mu0 ^= Du0; \ - Bko0 = ROL32(A##mu0, 4); \ - E##ke0 = Bke0 ^( Bki0 & Bko0 ); \ - A##sa0 ^= Da0; \ - Bku0 = ROL32(A##sa0, 9); \ - E##ki0 = Bki0 ^((~Bko0)& Bku0 ); \ - E##ko0 = (~Bko0)^( Bku0 | Bka0 ); \ - E##ku0 = Bku0 ^( Bka0 & Bke0 ); \ -\ - A##be0 ^= De0; \ - Bka1 = A##be0; \ - A##gi1 ^= Di1; \ - Bke1 = ROL32(A##gi1, 3); \ - A##ko0 ^= Do0; \ - Bki1 = ROL32(A##ko0, 12); \ - E##ka1 = Bka1 ^( Bke1 | Bki1 ); \ - A##mu1 ^= Du1; \ - Bko1 = ROL32(A##mu1, 4); \ - E##ke1 = Bke1 ^( Bki1 & Bko1 ); \ - A##sa1 ^= Da1; \ - Bku1 = ROL32(A##sa1, 9); \ - E##ki1 = Bki1 ^((~Bko1)& Bku1 ); \ - E##ko1 = (~Bko1)^( Bku1 | Bka1 ); \ - E##ku1 = Bku1 ^( Bka1 & Bke1 ); \ -\ - A##bu1 ^= Du1; \ - Bma0 = ROL32(A##bu1, 14); \ - A##ga0 ^= Da0; \ - Bme0 = ROL32(A##ga0, 18); \ - A##ke0 ^= De0; \ - Bmi0 = ROL32(A##ke0, 5); \ - E##ma0 = Bma0 ^( Bme0 & Bmi0 ); \ - A##mi1 ^= Di1; \ - Bmo0 = ROL32(A##mi1, 8); \ - E##me0 = Bme0 ^( Bmi0 | Bmo0 ); \ - A##so0 ^= Do0; \ - Bmu0 = ROL32(A##so0, 28); \ - E##mi0 = Bmi0 ^((~Bmo0)| Bmu0 ); \ - E##mo0 = (~Bmo0)^( Bmu0 & Bma0 ); \ - E##mu0 = Bmu0 ^( Bma0 | Bme0 ); \ -\ - A##bu0 ^= Du0; \ - Bma1 = ROL32(A##bu0, 13); \ - A##ga1 ^= Da1; \ - Bme1 = ROL32(A##ga1, 18); \ - A##ke1 ^= De1; \ - Bmi1 = ROL32(A##ke1, 5); \ - E##ma1 = Bma1 ^( Bme1 & Bmi1 ); \ - A##mi0 ^= Di0; \ - Bmo1 = ROL32(A##mi0, 7); \ - E##me1 = Bme1 ^( Bmi1 | Bmo1 ); \ - A##so1 ^= Do1; \ - Bmu1 = ROL32(A##so1, 28); \ - E##mi1 = Bmi1 ^((~Bmo1)| Bmu1 ); \ - E##mo1 = (~Bmo1)^( Bmu1 & Bma1 ); \ - E##mu1 = Bmu1 ^( Bma1 | Bme1 ); \ -\ - A##bi0 ^= Di0; \ - Bsa0 = ROL32(A##bi0, 31); \ - A##go1 ^= Do1; \ - Bse0 = ROL32(A##go1, 28); \ - A##ku1 ^= Du1; \ - Bsi0 = ROL32(A##ku1, 20); \ - E##sa0 = Bsa0 ^((~Bse0)& Bsi0 ); \ - A##ma1 ^= Da1; \ - Bso0 = ROL32(A##ma1, 21); \ - E##se0 = (~Bse0)^( Bsi0 | Bso0 ); \ - A##se0 ^= De0; \ - Bsu0 = ROL32(A##se0, 1); \ - E##si0 = Bsi0 ^( Bso0 & Bsu0 ); \ - E##so0 = Bso0 ^( Bsu0 | Bsa0 ); \ - E##su0 = Bsu0 ^( Bsa0 & Bse0 ); \ -\ - A##bi1 ^= Di1; \ - Bsa1 = ROL32(A##bi1, 31); \ - A##go0 ^= Do0; \ - Bse1 = ROL32(A##go0, 27); \ - A##ku0 ^= Du0; \ - Bsi1 = ROL32(A##ku0, 19); \ - E##sa1 = Bsa1 ^((~Bse1)& Bsi1 ); \ - A##ma0 ^= Da0; \ - Bso1 = ROL32(A##ma0, 20); \ - E##se1 = (~Bse1)^( Bsi1 | Bso1 ); \ - A##se1 ^= De1; \ - Bsu1 = ROL32(A##se1, 1); \ - E##si1 = Bsi1 ^( Bso1 & Bsu1 ); \ - E##so1 = Bso1 ^( Bsu1 | Bsa1 ); \ - E##su1 = Bsu1 ^( Bsa1 & Bse1 ); \ -\ - -#else /* UseBebigokimisa */ -/* --- Code for round, with prepare-theta */ -/* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - Da0 = Cu0^ROL32(Ce1, 1); \ - Da1 = Cu1^Ce0; \ - De0 = Ca0^ROL32(Ci1, 1); \ - De1 = Ca1^Ci0; \ - Di0 = Ce0^ROL32(Co1, 1); \ - Di1 = Ce1^Co0; \ - Do0 = Ci0^ROL32(Cu1, 1); \ - Do1 = Ci1^Cu0; \ - Du0 = Co0^ROL32(Ca1, 1); \ - Du1 = Co1^Ca0; \ -\ - A##ba0 ^= Da0; \ - Bba0 = A##ba0; \ - A##ge0 ^= De0; \ - Bbe0 = ROL32(A##ge0, 22); \ - A##ki1 ^= Di1; \ - Bbi0 = ROL32(A##ki1, 22); \ - E##ba0 = Bba0 ^((~Bbe0)& Bbi0 ); \ - E##ba0 ^= KeccakF1600RoundConstants_int2_0[i]; \ - Ca0 = E##ba0; \ - A##mo1 ^= Do1; \ - Bbo0 = ROL32(A##mo1, 11); \ - E##be0 = Bbe0 ^((~Bbi0)& Bbo0 ); \ - Ce0 = E##be0; \ - A##su0 ^= Du0; \ - Bbu0 = ROL32(A##su0, 7); \ - E##bi0 = Bbi0 ^((~Bbo0)& Bbu0 ); \ - Ci0 = E##bi0; \ - E##bo0 = Bbo0 ^((~Bbu0)& Bba0 ); \ - Co0 = E##bo0; \ - E##bu0 = Bbu0 ^((~Bba0)& Bbe0 ); \ - Cu0 = E##bu0; \ -\ - A##ba1 ^= Da1; \ - Bba1 = A##ba1; \ - A##ge1 ^= De1; \ - Bbe1 = ROL32(A##ge1, 22); \ - A##ki0 ^= Di0; \ - Bbi1 = ROL32(A##ki0, 21); \ - E##ba1 = Bba1 ^((~Bbe1)& Bbi1 ); \ - E##ba1 ^= KeccakF1600RoundConstants_int2_1[i]; \ - Ca1 = E##ba1; \ - A##mo0 ^= Do0; \ - Bbo1 = ROL32(A##mo0, 10); \ - E##be1 = Bbe1 ^((~Bbi1)& Bbo1 ); \ - Ce1 = E##be1; \ - A##su1 ^= Du1; \ - Bbu1 = ROL32(A##su1, 7); \ - E##bi1 = Bbi1 ^((~Bbo1)& Bbu1 ); \ - Ci1 = E##bi1; \ - E##bo1 = Bbo1 ^((~Bbu1)& Bba1 ); \ - Co1 = E##bo1; \ - E##bu1 = Bbu1 ^((~Bba1)& Bbe1 ); \ - Cu1 = E##bu1; \ -\ - A##bo0 ^= Do0; \ - Bga0 = ROL32(A##bo0, 14); \ - A##gu0 ^= Du0; \ - Bge0 = ROL32(A##gu0, 10); \ - A##ka1 ^= Da1; \ - Bgi0 = ROL32(A##ka1, 2); \ - E##ga0 = Bga0 ^((~Bge0)& Bgi0 ); \ - Ca0 ^= E##ga0; \ - A##me1 ^= De1; \ - Bgo0 = ROL32(A##me1, 23); \ - E##ge0 = Bge0 ^((~Bgi0)& Bgo0 ); \ - Ce0 ^= E##ge0; \ - A##si1 ^= Di1; \ - Bgu0 = ROL32(A##si1, 31); \ - E##gi0 = Bgi0 ^((~Bgo0)& Bgu0 ); \ - Ci0 ^= E##gi0; \ - E##go0 = Bgo0 ^((~Bgu0)& Bga0 ); \ - Co0 ^= E##go0; \ - E##gu0 = Bgu0 ^((~Bga0)& Bge0 ); \ - Cu0 ^= E##gu0; \ -\ - A##bo1 ^= Do1; \ - Bga1 = ROL32(A##bo1, 14); \ - A##gu1 ^= Du1; \ - Bge1 = ROL32(A##gu1, 10); \ - A##ka0 ^= Da0; \ - Bgi1 = ROL32(A##ka0, 1); \ - E##ga1 = Bga1 ^((~Bge1)& Bgi1 ); \ - Ca1 ^= E##ga1; \ - A##me0 ^= De0; \ - Bgo1 = ROL32(A##me0, 22); \ - E##ge1 = Bge1 ^((~Bgi1)& Bgo1 ); \ - Ce1 ^= E##ge1; \ - A##si0 ^= Di0; \ - Bgu1 = ROL32(A##si0, 30); \ - E##gi1 = Bgi1 ^((~Bgo1)& Bgu1 ); \ - Ci1 ^= E##gi1; \ - E##go1 = Bgo1 ^((~Bgu1)& Bga1 ); \ - Co1 ^= E##go1; \ - E##gu1 = Bgu1 ^((~Bga1)& Bge1 ); \ - Cu1 ^= E##gu1; \ -\ - A##be1 ^= De1; \ - Bka0 = ROL32(A##be1, 1); \ - A##gi0 ^= Di0; \ - Bke0 = ROL32(A##gi0, 3); \ - A##ko1 ^= Do1; \ - Bki0 = ROL32(A##ko1, 13); \ - E##ka0 = Bka0 ^((~Bke0)& Bki0 ); \ - Ca0 ^= E##ka0; \ - A##mu0 ^= Du0; \ - Bko0 = ROL32(A##mu0, 4); \ - E##ke0 = Bke0 ^((~Bki0)& Bko0 ); \ - Ce0 ^= E##ke0; \ - A##sa0 ^= Da0; \ - Bku0 = ROL32(A##sa0, 9); \ - E##ki0 = Bki0 ^((~Bko0)& Bku0 ); \ - Ci0 ^= E##ki0; \ - E##ko0 = Bko0 ^((~Bku0)& Bka0 ); \ - Co0 ^= E##ko0; \ - E##ku0 = Bku0 ^((~Bka0)& Bke0 ); \ - Cu0 ^= E##ku0; \ -\ - A##be0 ^= De0; \ - Bka1 = A##be0; \ - A##gi1 ^= Di1; \ - Bke1 = ROL32(A##gi1, 3); \ - A##ko0 ^= Do0; \ - Bki1 = ROL32(A##ko0, 12); \ - E##ka1 = Bka1 ^((~Bke1)& Bki1 ); \ - Ca1 ^= E##ka1; \ - A##mu1 ^= Du1; \ - Bko1 = ROL32(A##mu1, 4); \ - E##ke1 = Bke1 ^((~Bki1)& Bko1 ); \ - Ce1 ^= E##ke1; \ - A##sa1 ^= Da1; \ - Bku1 = ROL32(A##sa1, 9); \ - E##ki1 = Bki1 ^((~Bko1)& Bku1 ); \ - Ci1 ^= E##ki1; \ - E##ko1 = Bko1 ^((~Bku1)& Bka1 ); \ - Co1 ^= E##ko1; \ - E##ku1 = Bku1 ^((~Bka1)& Bke1 ); \ - Cu1 ^= E##ku1; \ -\ - A##bu1 ^= Du1; \ - Bma0 = ROL32(A##bu1, 14); \ - A##ga0 ^= Da0; \ - Bme0 = ROL32(A##ga0, 18); \ - A##ke0 ^= De0; \ - Bmi0 = ROL32(A##ke0, 5); \ - E##ma0 = Bma0 ^((~Bme0)& Bmi0 ); \ - Ca0 ^= E##ma0; \ - A##mi1 ^= Di1; \ - Bmo0 = ROL32(A##mi1, 8); \ - E##me0 = Bme0 ^((~Bmi0)& Bmo0 ); \ - Ce0 ^= E##me0; \ - A##so0 ^= Do0; \ - Bmu0 = ROL32(A##so0, 28); \ - E##mi0 = Bmi0 ^((~Bmo0)& Bmu0 ); \ - Ci0 ^= E##mi0; \ - E##mo0 = Bmo0 ^((~Bmu0)& Bma0 ); \ - Co0 ^= E##mo0; \ - E##mu0 = Bmu0 ^((~Bma0)& Bme0 ); \ - Cu0 ^= E##mu0; \ -\ - A##bu0 ^= Du0; \ - Bma1 = ROL32(A##bu0, 13); \ - A##ga1 ^= Da1; \ - Bme1 = ROL32(A##ga1, 18); \ - A##ke1 ^= De1; \ - Bmi1 = ROL32(A##ke1, 5); \ - E##ma1 = Bma1 ^((~Bme1)& Bmi1 ); \ - Ca1 ^= E##ma1; \ - A##mi0 ^= Di0; \ - Bmo1 = ROL32(A##mi0, 7); \ - E##me1 = Bme1 ^((~Bmi1)& Bmo1 ); \ - Ce1 ^= E##me1; \ - A##so1 ^= Do1; \ - Bmu1 = ROL32(A##so1, 28); \ - E##mi1 = Bmi1 ^((~Bmo1)& Bmu1 ); \ - Ci1 ^= E##mi1; \ - E##mo1 = Bmo1 ^((~Bmu1)& Bma1 ); \ - Co1 ^= E##mo1; \ - E##mu1 = Bmu1 ^((~Bma1)& Bme1 ); \ - Cu1 ^= E##mu1; \ -\ - A##bi0 ^= Di0; \ - Bsa0 = ROL32(A##bi0, 31); \ - A##go1 ^= Do1; \ - Bse0 = ROL32(A##go1, 28); \ - A##ku1 ^= Du1; \ - Bsi0 = ROL32(A##ku1, 20); \ - E##sa0 = Bsa0 ^((~Bse0)& Bsi0 ); \ - Ca0 ^= E##sa0; \ - A##ma1 ^= Da1; \ - Bso0 = ROL32(A##ma1, 21); \ - E##se0 = Bse0 ^((~Bsi0)& Bso0 ); \ - Ce0 ^= E##se0; \ - A##se0 ^= De0; \ - Bsu0 = ROL32(A##se0, 1); \ - E##si0 = Bsi0 ^((~Bso0)& Bsu0 ); \ - Ci0 ^= E##si0; \ - E##so0 = Bso0 ^((~Bsu0)& Bsa0 ); \ - Co0 ^= E##so0; \ - E##su0 = Bsu0 ^((~Bsa0)& Bse0 ); \ - Cu0 ^= E##su0; \ -\ - A##bi1 ^= Di1; \ - Bsa1 = ROL32(A##bi1, 31); \ - A##go0 ^= Do0; \ - Bse1 = ROL32(A##go0, 27); \ - A##ku0 ^= Du0; \ - Bsi1 = ROL32(A##ku0, 19); \ - E##sa1 = Bsa1 ^((~Bse1)& Bsi1 ); \ - Ca1 ^= E##sa1; \ - A##ma0 ^= Da0; \ - Bso1 = ROL32(A##ma0, 20); \ - E##se1 = Bse1 ^((~Bsi1)& Bso1 ); \ - Ce1 ^= E##se1; \ - A##se1 ^= De1; \ - Bsu1 = ROL32(A##se1, 1); \ - E##si1 = Bsi1 ^((~Bso1)& Bsu1 ); \ - Ci1 ^= E##si1; \ - E##so1 = Bso1 ^((~Bsu1)& Bsa1 ); \ - Co1 ^= E##so1; \ - E##su1 = Bsu1 ^((~Bsa1)& Bse1 ); \ - Cu1 ^= E##su1; \ -\ - -/* --- Code for round */ -/* --- using factor 2 interleaving, 64-bit lanes mapped to 32-bit words */ -#define thetaRhoPiChiIota(i, A, E) \ - Da0 = Cu0^ROL32(Ce1, 1); \ - Da1 = Cu1^Ce0; \ - De0 = Ca0^ROL32(Ci1, 1); \ - De1 = Ca1^Ci0; \ - Di0 = Ce0^ROL32(Co1, 1); \ - Di1 = Ce1^Co0; \ - Do0 = Ci0^ROL32(Cu1, 1); \ - Do1 = Ci1^Cu0; \ - Du0 = Co0^ROL32(Ca1, 1); \ - Du1 = Co1^Ca0; \ -\ - A##ba0 ^= Da0; \ - Bba0 = A##ba0; \ - A##ge0 ^= De0; \ - Bbe0 = ROL32(A##ge0, 22); \ - A##ki1 ^= Di1; \ - Bbi0 = ROL32(A##ki1, 22); \ - E##ba0 = Bba0 ^((~Bbe0)& Bbi0 ); \ - E##ba0 ^= KeccakF1600RoundConstants_int2_0[i]; \ - A##mo1 ^= Do1; \ - Bbo0 = ROL32(A##mo1, 11); \ - E##be0 = Bbe0 ^((~Bbi0)& Bbo0 ); \ - A##su0 ^= Du0; \ - Bbu0 = ROL32(A##su0, 7); \ - E##bi0 = Bbi0 ^((~Bbo0)& Bbu0 ); \ - E##bo0 = Bbo0 ^((~Bbu0)& Bba0 ); \ - E##bu0 = Bbu0 ^((~Bba0)& Bbe0 ); \ -\ - A##ba1 ^= Da1; \ - Bba1 = A##ba1; \ - A##ge1 ^= De1; \ - Bbe1 = ROL32(A##ge1, 22); \ - A##ki0 ^= Di0; \ - Bbi1 = ROL32(A##ki0, 21); \ - E##ba1 = Bba1 ^((~Bbe1)& Bbi1 ); \ - E##ba1 ^= KeccakF1600RoundConstants_int2_1[i]; \ - A##mo0 ^= Do0; \ - Bbo1 = ROL32(A##mo0, 10); \ - E##be1 = Bbe1 ^((~Bbi1)& Bbo1 ); \ - A##su1 ^= Du1; \ - Bbu1 = ROL32(A##su1, 7); \ - E##bi1 = Bbi1 ^((~Bbo1)& Bbu1 ); \ - E##bo1 = Bbo1 ^((~Bbu1)& Bba1 ); \ - E##bu1 = Bbu1 ^((~Bba1)& Bbe1 ); \ -\ - A##bo0 ^= Do0; \ - Bga0 = ROL32(A##bo0, 14); \ - A##gu0 ^= Du0; \ - Bge0 = ROL32(A##gu0, 10); \ - A##ka1 ^= Da1; \ - Bgi0 = ROL32(A##ka1, 2); \ - E##ga0 = Bga0 ^((~Bge0)& Bgi0 ); \ - A##me1 ^= De1; \ - Bgo0 = ROL32(A##me1, 23); \ - E##ge0 = Bge0 ^((~Bgi0)& Bgo0 ); \ - A##si1 ^= Di1; \ - Bgu0 = ROL32(A##si1, 31); \ - E##gi0 = Bgi0 ^((~Bgo0)& Bgu0 ); \ - E##go0 = Bgo0 ^((~Bgu0)& Bga0 ); \ - E##gu0 = Bgu0 ^((~Bga0)& Bge0 ); \ -\ - A##bo1 ^= Do1; \ - Bga1 = ROL32(A##bo1, 14); \ - A##gu1 ^= Du1; \ - Bge1 = ROL32(A##gu1, 10); \ - A##ka0 ^= Da0; \ - Bgi1 = ROL32(A##ka0, 1); \ - E##ga1 = Bga1 ^((~Bge1)& Bgi1 ); \ - A##me0 ^= De0; \ - Bgo1 = ROL32(A##me0, 22); \ - E##ge1 = Bge1 ^((~Bgi1)& Bgo1 ); \ - A##si0 ^= Di0; \ - Bgu1 = ROL32(A##si0, 30); \ - E##gi1 = Bgi1 ^((~Bgo1)& Bgu1 ); \ - E##go1 = Bgo1 ^((~Bgu1)& Bga1 ); \ - E##gu1 = Bgu1 ^((~Bga1)& Bge1 ); \ -\ - A##be1 ^= De1; \ - Bka0 = ROL32(A##be1, 1); \ - A##gi0 ^= Di0; \ - Bke0 = ROL32(A##gi0, 3); \ - A##ko1 ^= Do1; \ - Bki0 = ROL32(A##ko1, 13); \ - E##ka0 = Bka0 ^((~Bke0)& Bki0 ); \ - A##mu0 ^= Du0; \ - Bko0 = ROL32(A##mu0, 4); \ - E##ke0 = Bke0 ^((~Bki0)& Bko0 ); \ - A##sa0 ^= Da0; \ - Bku0 = ROL32(A##sa0, 9); \ - E##ki0 = Bki0 ^((~Bko0)& Bku0 ); \ - E##ko0 = Bko0 ^((~Bku0)& Bka0 ); \ - E##ku0 = Bku0 ^((~Bka0)& Bke0 ); \ -\ - A##be0 ^= De0; \ - Bka1 = A##be0; \ - A##gi1 ^= Di1; \ - Bke1 = ROL32(A##gi1, 3); \ - A##ko0 ^= Do0; \ - Bki1 = ROL32(A##ko0, 12); \ - E##ka1 = Bka1 ^((~Bke1)& Bki1 ); \ - A##mu1 ^= Du1; \ - Bko1 = ROL32(A##mu1, 4); \ - E##ke1 = Bke1 ^((~Bki1)& Bko1 ); \ - A##sa1 ^= Da1; \ - Bku1 = ROL32(A##sa1, 9); \ - E##ki1 = Bki1 ^((~Bko1)& Bku1 ); \ - E##ko1 = Bko1 ^((~Bku1)& Bka1 ); \ - E##ku1 = Bku1 ^((~Bka1)& Bke1 ); \ -\ - A##bu1 ^= Du1; \ - Bma0 = ROL32(A##bu1, 14); \ - A##ga0 ^= Da0; \ - Bme0 = ROL32(A##ga0, 18); \ - A##ke0 ^= De0; \ - Bmi0 = ROL32(A##ke0, 5); \ - E##ma0 = Bma0 ^((~Bme0)& Bmi0 ); \ - A##mi1 ^= Di1; \ - Bmo0 = ROL32(A##mi1, 8); \ - E##me0 = Bme0 ^((~Bmi0)& Bmo0 ); \ - A##so0 ^= Do0; \ - Bmu0 = ROL32(A##so0, 28); \ - E##mi0 = Bmi0 ^((~Bmo0)& Bmu0 ); \ - E##mo0 = Bmo0 ^((~Bmu0)& Bma0 ); \ - E##mu0 = Bmu0 ^((~Bma0)& Bme0 ); \ -\ - A##bu0 ^= Du0; \ - Bma1 = ROL32(A##bu0, 13); \ - A##ga1 ^= Da1; \ - Bme1 = ROL32(A##ga1, 18); \ - A##ke1 ^= De1; \ - Bmi1 = ROL32(A##ke1, 5); \ - E##ma1 = Bma1 ^((~Bme1)& Bmi1 ); \ - A##mi0 ^= Di0; \ - Bmo1 = ROL32(A##mi0, 7); \ - E##me1 = Bme1 ^((~Bmi1)& Bmo1 ); \ - A##so1 ^= Do1; \ - Bmu1 = ROL32(A##so1, 28); \ - E##mi1 = Bmi1 ^((~Bmo1)& Bmu1 ); \ - E##mo1 = Bmo1 ^((~Bmu1)& Bma1 ); \ - E##mu1 = Bmu1 ^((~Bma1)& Bme1 ); \ -\ - A##bi0 ^= Di0; \ - Bsa0 = ROL32(A##bi0, 31); \ - A##go1 ^= Do1; \ - Bse0 = ROL32(A##go1, 28); \ - A##ku1 ^= Du1; \ - Bsi0 = ROL32(A##ku1, 20); \ - E##sa0 = Bsa0 ^((~Bse0)& Bsi0 ); \ - A##ma1 ^= Da1; \ - Bso0 = ROL32(A##ma1, 21); \ - E##se0 = Bse0 ^((~Bsi0)& Bso0 ); \ - A##se0 ^= De0; \ - Bsu0 = ROL32(A##se0, 1); \ - E##si0 = Bsi0 ^((~Bso0)& Bsu0 ); \ - E##so0 = Bso0 ^((~Bsu0)& Bsa0 ); \ - E##su0 = Bsu0 ^((~Bsa0)& Bse0 ); \ -\ - A##bi1 ^= Di1; \ - Bsa1 = ROL32(A##bi1, 31); \ - A##go0 ^= Do0; \ - Bse1 = ROL32(A##go0, 27); \ - A##ku0 ^= Du0; \ - Bsi1 = ROL32(A##ku0, 19); \ - E##sa1 = Bsa1 ^((~Bse1)& Bsi1 ); \ - A##ma0 ^= Da0; \ - Bso1 = ROL32(A##ma0, 20); \ - E##se1 = Bse1 ^((~Bsi1)& Bso1 ); \ - A##se1 ^= De1; \ - Bsu1 = ROL32(A##se1, 1); \ - E##si1 = Bsi1 ^((~Bso1)& Bsu1 ); \ - E##so1 = Bso1 ^((~Bsu1)& Bsa1 ); \ - E##su1 = Bsu1 ^((~Bsa1)& Bse1 ); \ -\ - -#endif /* UseBebigokimisa */ - -const UINT32 KeccakF1600RoundConstants_int2_0[24] = { - 0x00000001UL, - 0x00000000UL, - 0x00000000UL, - 0x00000000UL, - 0x00000001UL, - 0x00000001UL, - 0x00000001UL, - 0x00000001UL, - 0x00000000UL, - 0x00000000UL, - 0x00000001UL, - 0x00000000UL, - 0x00000001UL, - 0x00000001UL, - 0x00000001UL, - 0x00000001UL, - 0x00000000UL, - 0x00000000UL, - 0x00000000UL, - 0x00000000UL, - 0x00000001UL, - 0x00000000UL, - 0x00000001UL, - 0x00000000UL }; - -const UINT32 KeccakF1600RoundConstants_int2_1[24] = { - 0x00000000UL, - 0x00000089UL, - 0x8000008bUL, - 0x80008080UL, - 0x0000008bUL, - 0x00008000UL, - 0x80008088UL, - 0x80000082UL, - 0x0000000bUL, - 0x0000000aUL, - 0x00008082UL, - 0x00008003UL, - 0x0000808bUL, - 0x8000000bUL, - 0x8000008aUL, - 0x80000081UL, - 0x80000081UL, - 0x80000008UL, - 0x00000083UL, - 0x80008003UL, - 0x80008088UL, - 0x80000088UL, - 0x00008000UL, - 0x80008082UL }; - -#define copyFromStateAndXor1024bits(X, state, input) \ - X##ba0 = state[ 0]^input[ 0]; \ - X##ba1 = state[ 1]^input[ 1]; \ - X##be0 = state[ 2]^input[ 2]; \ - X##be1 = state[ 3]^input[ 3]; \ - X##bi0 = state[ 4]^input[ 4]; \ - X##bi1 = state[ 5]^input[ 5]; \ - X##bo0 = state[ 6]^input[ 6]; \ - X##bo1 = state[ 7]^input[ 7]; \ - X##bu0 = state[ 8]^input[ 8]; \ - X##bu1 = state[ 9]^input[ 9]; \ - X##ga0 = state[10]^input[10]; \ - X##ga1 = state[11]^input[11]; \ - X##ge0 = state[12]^input[12]; \ - X##ge1 = state[13]^input[13]; \ - X##gi0 = state[14]^input[14]; \ - X##gi1 = state[15]^input[15]; \ - X##go0 = state[16]^input[16]; \ - X##go1 = state[17]^input[17]; \ - X##gu0 = state[18]^input[18]; \ - X##gu1 = state[19]^input[19]; \ - X##ka0 = state[20]^input[20]; \ - X##ka1 = state[21]^input[21]; \ - X##ke0 = state[22]^input[22]; \ - X##ke1 = state[23]^input[23]; \ - X##ki0 = state[24]^input[24]; \ - X##ki1 = state[25]^input[25]; \ - X##ko0 = state[26]^input[26]; \ - X##ko1 = state[27]^input[27]; \ - X##ku0 = state[28]^input[28]; \ - X##ku1 = state[29]^input[29]; \ - X##ma0 = state[30]^input[30]; \ - X##ma1 = state[31]^input[31]; \ - X##me0 = state[32]; \ - X##me1 = state[33]; \ - X##mi0 = state[34]; \ - X##mi1 = state[35]; \ - X##mo0 = state[36]; \ - X##mo1 = state[37]; \ - X##mu0 = state[38]; \ - X##mu1 = state[39]; \ - X##sa0 = state[40]; \ - X##sa1 = state[41]; \ - X##se0 = state[42]; \ - X##se1 = state[43]; \ - X##si0 = state[44]; \ - X##si1 = state[45]; \ - X##so0 = state[46]; \ - X##so1 = state[47]; \ - X##su0 = state[48]; \ - X##su1 = state[49]; \ - -#define copyFromStateAndXor1088bits(X, state, input) \ - X##ba0 = state[ 0]^input[ 0]; \ - X##ba1 = state[ 1]^input[ 1]; \ - X##be0 = state[ 2]^input[ 2]; \ - X##be1 = state[ 3]^input[ 3]; \ - X##bi0 = state[ 4]^input[ 4]; \ - X##bi1 = state[ 5]^input[ 5]; \ - X##bo0 = state[ 6]^input[ 6]; \ - X##bo1 = state[ 7]^input[ 7]; \ - X##bu0 = state[ 8]^input[ 8]; \ - X##bu1 = state[ 9]^input[ 9]; \ - X##ga0 = state[10]^input[10]; \ - X##ga1 = state[11]^input[11]; \ - X##ge0 = state[12]^input[12]; \ - X##ge1 = state[13]^input[13]; \ - X##gi0 = state[14]^input[14]; \ - X##gi1 = state[15]^input[15]; \ - X##go0 = state[16]^input[16]; \ - X##go1 = state[17]^input[17]; \ - X##gu0 = state[18]^input[18]; \ - X##gu1 = state[19]^input[19]; \ - X##ka0 = state[20]^input[20]; \ - X##ka1 = state[21]^input[21]; \ - X##ke0 = state[22]^input[22]; \ - X##ke1 = state[23]^input[23]; \ - X##ki0 = state[24]^input[24]; \ - X##ki1 = state[25]^input[25]; \ - X##ko0 = state[26]^input[26]; \ - X##ko1 = state[27]^input[27]; \ - X##ku0 = state[28]^input[28]; \ - X##ku1 = state[29]^input[29]; \ - X##ma0 = state[30]^input[30]; \ - X##ma1 = state[31]^input[31]; \ - X##me0 = state[32]^input[32]; \ - X##me1 = state[33]^input[33]; \ - X##mi0 = state[34]; \ - X##mi1 = state[35]; \ - X##mo0 = state[36]; \ - X##mo1 = state[37]; \ - X##mu0 = state[38]; \ - X##mu1 = state[39]; \ - X##sa0 = state[40]; \ - X##sa1 = state[41]; \ - X##se0 = state[42]; \ - X##se1 = state[43]; \ - X##si0 = state[44]; \ - X##si1 = state[45]; \ - X##so0 = state[46]; \ - X##so1 = state[47]; \ - X##su0 = state[48]; \ - X##su1 = state[49]; \ - -#define copyFromState(X, state) \ - X##ba0 = state[ 0]; \ - X##ba1 = state[ 1]; \ - X##be0 = state[ 2]; \ - X##be1 = state[ 3]; \ - X##bi0 = state[ 4]; \ - X##bi1 = state[ 5]; \ - X##bo0 = state[ 6]; \ - X##bo1 = state[ 7]; \ - X##bu0 = state[ 8]; \ - X##bu1 = state[ 9]; \ - X##ga0 = state[10]; \ - X##ga1 = state[11]; \ - X##ge0 = state[12]; \ - X##ge1 = state[13]; \ - X##gi0 = state[14]; \ - X##gi1 = state[15]; \ - X##go0 = state[16]; \ - X##go1 = state[17]; \ - X##gu0 = state[18]; \ - X##gu1 = state[19]; \ - X##ka0 = state[20]; \ - X##ka1 = state[21]; \ - X##ke0 = state[22]; \ - X##ke1 = state[23]; \ - X##ki0 = state[24]; \ - X##ki1 = state[25]; \ - X##ko0 = state[26]; \ - X##ko1 = state[27]; \ - X##ku0 = state[28]; \ - X##ku1 = state[29]; \ - X##ma0 = state[30]; \ - X##ma1 = state[31]; \ - X##me0 = state[32]; \ - X##me1 = state[33]; \ - X##mi0 = state[34]; \ - X##mi1 = state[35]; \ - X##mo0 = state[36]; \ - X##mo1 = state[37]; \ - X##mu0 = state[38]; \ - X##mu1 = state[39]; \ - X##sa0 = state[40]; \ - X##sa1 = state[41]; \ - X##se0 = state[42]; \ - X##se1 = state[43]; \ - X##si0 = state[44]; \ - X##si1 = state[45]; \ - X##so0 = state[46]; \ - X##so1 = state[47]; \ - X##su0 = state[48]; \ - X##su1 = state[49]; \ - -#define copyToState(state, X) \ - state[ 0] = X##ba0; \ - state[ 1] = X##ba1; \ - state[ 2] = X##be0; \ - state[ 3] = X##be1; \ - state[ 4] = X##bi0; \ - state[ 5] = X##bi1; \ - state[ 6] = X##bo0; \ - state[ 7] = X##bo1; \ - state[ 8] = X##bu0; \ - state[ 9] = X##bu1; \ - state[10] = X##ga0; \ - state[11] = X##ga1; \ - state[12] = X##ge0; \ - state[13] = X##ge1; \ - state[14] = X##gi0; \ - state[15] = X##gi1; \ - state[16] = X##go0; \ - state[17] = X##go1; \ - state[18] = X##gu0; \ - state[19] = X##gu1; \ - state[20] = X##ka0; \ - state[21] = X##ka1; \ - state[22] = X##ke0; \ - state[23] = X##ke1; \ - state[24] = X##ki0; \ - state[25] = X##ki1; \ - state[26] = X##ko0; \ - state[27] = X##ko1; \ - state[28] = X##ku0; \ - state[29] = X##ku1; \ - state[30] = X##ma0; \ - state[31] = X##ma1; \ - state[32] = X##me0; \ - state[33] = X##me1; \ - state[34] = X##mi0; \ - state[35] = X##mi1; \ - state[36] = X##mo0; \ - state[37] = X##mo1; \ - state[38] = X##mu0; \ - state[39] = X##mu1; \ - state[40] = X##sa0; \ - state[41] = X##sa1; \ - state[42] = X##se0; \ - state[43] = X##se1; \ - state[44] = X##si0; \ - state[45] = X##si1; \ - state[46] = X##so0; \ - state[47] = X##so1; \ - state[48] = X##su0; \ - state[49] = X##su1; \ - -#define copyStateVariables(X, Y) \ - X##ba0 = Y##ba0; \ - X##ba1 = Y##ba1; \ - X##be0 = Y##be0; \ - X##be1 = Y##be1; \ - X##bi0 = Y##bi0; \ - X##bi1 = Y##bi1; \ - X##bo0 = Y##bo0; \ - X##bo1 = Y##bo1; \ - X##bu0 = Y##bu0; \ - X##bu1 = Y##bu1; \ - X##ga0 = Y##ga0; \ - X##ga1 = Y##ga1; \ - X##ge0 = Y##ge0; \ - X##ge1 = Y##ge1; \ - X##gi0 = Y##gi0; \ - X##gi1 = Y##gi1; \ - X##go0 = Y##go0; \ - X##go1 = Y##go1; \ - X##gu0 = Y##gu0; \ - X##gu1 = Y##gu1; \ - X##ka0 = Y##ka0; \ - X##ka1 = Y##ka1; \ - X##ke0 = Y##ke0; \ - X##ke1 = Y##ke1; \ - X##ki0 = Y##ki0; \ - X##ki1 = Y##ki1; \ - X##ko0 = Y##ko0; \ - X##ko1 = Y##ko1; \ - X##ku0 = Y##ku0; \ - X##ku1 = Y##ku1; \ - X##ma0 = Y##ma0; \ - X##ma1 = Y##ma1; \ - X##me0 = Y##me0; \ - X##me1 = Y##me1; \ - X##mi0 = Y##mi0; \ - X##mi1 = Y##mi1; \ - X##mo0 = Y##mo0; \ - X##mo1 = Y##mo1; \ - X##mu0 = Y##mu0; \ - X##mu1 = Y##mu1; \ - X##sa0 = Y##sa0; \ - X##sa1 = Y##sa1; \ - X##se0 = Y##se0; \ - X##se1 = Y##se1; \ - X##si0 = Y##si0; \ - X##si1 = Y##si1; \ - X##so0 = Y##so0; \ - X##so1 = Y##so1; \ - X##su0 = Y##su0; \ - X##su1 = Y##su1; \ - diff --git a/Modules/_sha3/keccak/KeccakF-1600-32.macros b/Modules/_sha3/keccak/KeccakF-1600-32.macros deleted file mode 100644 index 9ade6000678f..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-32.macros +++ /dev/null @@ -1,26 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -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/ -*/ - -#ifdef UseSchedule - #if (UseSchedule == 1) - #include "KeccakF-1600-32-s1.macros" - #elif (UseSchedule == 2) - #include "KeccakF-1600-32-s2.macros" - #elif (UseSchedule == 3) - #include "KeccakF-1600-32-rvk.macros" - #else - #error "This schedule is not supported." - #endif -#else - #include "KeccakF-1600-32-s1.macros" -#endif diff --git a/Modules/_sha3/keccak/KeccakF-1600-64.macros b/Modules/_sha3/keccak/KeccakF-1600-64.macros deleted file mode 100644 index dc0f78924d4b..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-64.macros +++ /dev/null @@ -1,728 +0,0 @@ -/* -Code automatically generated by KeccakTools! - -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -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 */ - -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 }; - -#define copyFromStateAndXor576bits(X, state, input) \ - 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]; \ - 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 copyFromStateAndXor832bits(X, state, input) \ - 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]; \ - 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 copyFromStateAndXor1024bits(X, state, input) \ - 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]; \ - 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 copyFromStateAndXor1088bits(X, state, input) \ - 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]; \ - X##me = state[16]^input[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 copyFromStateAndXor1152bits(X, state, input) \ - 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]; \ - X##me = state[16]^input[16]; \ - X##mi = state[17]^input[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 copyFromStateAndXor1344bits(X, state, input) \ - 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]; \ - 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]; \ - X##si = state[22]; \ - X##so = state[23]; \ - X##su = state[24]; \ - -#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; \ - diff --git a/Modules/_sha3/keccak/KeccakF-1600-int-set.h b/Modules/_sha3/keccak/KeccakF-1600-int-set.h deleted file mode 100644 index 0ed1d802e3e3..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-int-set.h +++ /dev/null @@ -1,6 +0,0 @@ -#define ProvideFast576 -#define ProvideFast832 -#define ProvideFast1024 -#define ProvideFast1088 -#define ProvideFast1152 -#define ProvideFast1344 diff --git a/Modules/_sha3/keccak/KeccakF-1600-interface.h b/Modules/_sha3/keccak/KeccakF-1600-interface.h deleted file mode 100644 index ce2710eeb22d..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-interface.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -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 _KeccakPermutationInterface_h_ -#define _KeccakPermutationInterface_h_ - -#include "KeccakF-1600-int-set.h" - -static void KeccakInitialize( void ); -static void KeccakInitializeState(unsigned char *state); -static void KeccakPermutation(unsigned char *state); -#ifdef ProvideFast576 -static void KeccakAbsorb576bits(unsigned char *state, const unsigned char *data); -#endif -#ifdef ProvideFast832 -static void KeccakAbsorb832bits(unsigned char *state, const unsigned char *data); -#endif -#ifdef ProvideFast1024 -static void KeccakAbsorb1024bits(unsigned char *state, const unsigned char *data); -#endif -#ifdef ProvideFast1088 -static void KeccakAbsorb1088bits(unsigned char *state, const unsigned char *data); -#endif -#ifdef ProvideFast1152 -static void KeccakAbsorb1152bits(unsigned char *state, const unsigned char *data); -#endif -#ifdef ProvideFast1344 -static void KeccakAbsorb1344bits(unsigned char *state, const unsigned char *data); -#endif -static void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsigned int laneCount); -#ifdef ProvideFast1024 -static void KeccakExtract1024bits(const unsigned char *state, unsigned char *data); -#endif -static void KeccakExtract(const unsigned char *state, unsigned char *data, unsigned int laneCount); - -#endif diff --git a/Modules/_sha3/keccak/KeccakF-1600-opt32-settings.h b/Modules/_sha3/keccak/KeccakF-1600-opt32-settings.h deleted file mode 100644 index 615c78217e3c..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-opt32-settings.h +++ /dev/null @@ -1,6 +0,0 @@ -/* -#define Unrolling 2 -#define UseBebigokimisa -#define UseInterleaveTables -#define UseSchedule 3 -*/ diff --git a/Modules/_sha3/keccak/KeccakF-1600-opt32.c b/Modules/_sha3/keccak/KeccakF-1600-opt32.c deleted file mode 100644 index c52bfb7fd7c0..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-opt32.c +++ /dev/null @@ -1,524 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -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 "KeccakF-1600-opt32-settings.h" -#include "KeccakF-1600-interface.h" - -typedef unsigned char UINT8; -typedef unsigned short UINT16; -typedef unsigned int UINT32; -/* typedef unsigned long long int UINT64; */ - -#ifdef UseInterleaveTables -static int interleaveTablesBuilt = 0; -static UINT16 interleaveTable[65536]; -static UINT16 deinterleaveTable[65536]; - -static void buildInterleaveTables() -{ - UINT32 i, j; - UINT16 x; - - if (!interleaveTablesBuilt) { - for(i=0; i<65536; i++) { - x = 0; - for(j=0; j<16; j++) { - if (i & (1 << j)) - x |= (1 << (j/2 + 8*(j%2))); - } - interleaveTable[i] = x; - deinterleaveTable[x] = (UINT16)i; - } - interleaveTablesBuilt = 1; - } -} - -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - -#define xor2bytesIntoInterleavedWords(even, odd, source, j) \ - i##j = interleaveTable[((const UINT16*)source)[j]]; \ - ((UINT8*)even)[j] ^= i##j & 0xFF; \ - ((UINT8*)odd)[j] ^= i##j >> 8; - -#define setInterleavedWordsInto2bytes(dest, even, odd, j) \ - d##j = deinterleaveTable[((even >> (j*8)) & 0xFF) ^ (((odd >> (j*8)) & 0xFF) << 8)]; \ - ((UINT16*)dest)[j] = d##j; - -#else /* (PLATFORM_BYTE_ORDER == IS_BIG_ENDIAN) */ - -#define xor2bytesIntoInterleavedWords(even, odd, source, j) \ - i##j = interleaveTable[source[2*j] ^ ((UINT16)source[2*j+1] << 8)]; \ - *even ^= (i##j & 0xFF) << (j*8); \ - *odd ^= ((i##j >> 8) & 0xFF) << (j*8); - -#define setInterleavedWordsInto2bytes(dest, even, odd, j) \ - d##j = deinterleaveTable[((even >> (j*8)) & 0xFF) ^ (((odd >> (j*8)) & 0xFF) << 8)]; \ - dest[2*j] = d##j & 0xFF; \ - dest[2*j+1] = d##j >> 8; - -#endif /* Endianness */ - -static void xor8bytesIntoInterleavedWords(UINT32 *even, UINT32 *odd, const UINT8* source) -{ - UINT16 i0, i1, i2, i3; - - xor2bytesIntoInterleavedWords(even, odd, source, 0) - xor2bytesIntoInterleavedWords(even, odd, source, 1) - xor2bytesIntoInterleavedWords(even, odd, source, 2) - xor2bytesIntoInterleavedWords(even, odd, source, 3) -} - -#define xorLanesIntoState(laneCount, state, input) \ - { \ - int i; \ - for(i=0; i<(laneCount); i++) \ - xor8bytesIntoInterleavedWords(state+i*2, state+i*2+1, input+i*8); \ - } - -static void setInterleavedWordsInto8bytes(UINT8* dest, UINT32 even, UINT32 odd) -{ - UINT16 d0, d1, d2, d3; - - setInterleavedWordsInto2bytes(dest, even, odd, 0) - setInterleavedWordsInto2bytes(dest, even, odd, 1) - setInterleavedWordsInto2bytes(dest, even, odd, 2) - setInterleavedWordsInto2bytes(dest, even, odd, 3) -} - -#define extractLanes(laneCount, state, data) \ - { \ - int i; \ - for(i=0; i<(laneCount); i++) \ - setInterleavedWordsInto8bytes(data+i*8, ((UINT32*)state)[i*2], ((UINT32*)state)[i*2+1]); \ - } - -#else /* No interleaving tables */ - -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - -/* Credit: Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ -#define xorInterleavedLE(rateInLanes, state, input) \ - { \ - const UINT32 * pI = (const UINT32 *)input; \ - UINT32 * pS = state; \ - UINT32 t, x0, x1; \ - int i; \ - for (i = (rateInLanes)-1; i >= 0; --i) \ - { \ - x0 = *(pI++); \ - t = (x0 ^ (x0 >> 1)) & 0x22222222UL; x0 = x0 ^ t ^ (t << 1); \ - t = (x0 ^ (x0 >> 2)) & 0x0C0C0C0CUL; x0 = x0 ^ t ^ (t << 2); \ - t = (x0 ^ (x0 >> 4)) & 0x00F000F0UL; x0 = x0 ^ t ^ (t << 4); \ - t = (x0 ^ (x0 >> 8)) & 0x0000FF00UL; x0 = x0 ^ t ^ (t << 8); \ - x1 = *(pI++); \ - t = (x1 ^ (x1 >> 1)) & 0x22222222UL; x1 = x1 ^ t ^ (t << 1); \ - t = (x1 ^ (x1 >> 2)) & 0x0C0C0C0CUL; x1 = x1 ^ t ^ (t << 2); \ - t = (x1 ^ (x1 >> 4)) & 0x00F000F0UL; x1 = x1 ^ t ^ (t << 4); \ - t = (x1 ^ (x1 >> 8)) & 0x0000FF00UL; x1 = x1 ^ t ^ (t << 8); \ - *(pS++) ^= (UINT16)x0 | (x1 << 16); \ - *(pS++) ^= (x0 >> 16) | (x1 & 0xFFFF0000); \ - } \ - } - -#define xorLanesIntoState(laneCount, state, input) \ - xorInterleavedLE(laneCount, state, input) - -#else /* (PLATFORM_BYTE_ORDER == IS_BIG_ENDIAN) */ - -/* Credit: Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ -UINT64 toInterleaving(UINT64 x) -{ - UINT64 t; - - t = (x ^ (x >> 1)) & 0x2222222222222222ULL; x = x ^ t ^ (t << 1); - t = (x ^ (x >> 2)) & 0x0C0C0C0C0C0C0C0CULL; x = x ^ t ^ (t << 2); - t = (x ^ (x >> 4)) & 0x00F000F000F000F0ULL; x = x ^ t ^ (t << 4); - t = (x ^ (x >> 8)) & 0x0000FF000000FF00ULL; x = x ^ t ^ (t << 8); - t = (x ^ (x >> 16)) & 0x00000000FFFF0000ULL; x = x ^ t ^ (t << 16); - - return x; -} - -static void xor8bytesIntoInterleavedWords(UINT32* evenAndOdd, const UINT8* source) -{ - /* This can be optimized */ - UINT64 sourceWord = - (UINT64)source[0] - ^ (((UINT64)source[1]) << 8) - ^ (((UINT64)source[2]) << 16) - ^ (((UINT64)source[3]) << 24) - ^ (((UINT64)source[4]) << 32) - ^ (((UINT64)source[5]) << 40) - ^ (((UINT64)source[6]) << 48) - ^ (((UINT64)source[7]) << 56); - UINT64 evenAndOddWord = toInterleaving(sourceWord); - evenAndOdd[0] ^= (UINT32)evenAndOddWord; - evenAndOdd[1] ^= (UINT32)(evenAndOddWord >> 32); -} - -#define xorLanesIntoState(laneCount, state, input) \ - { \ - int i; \ - for(i=0; i<(laneCount); i++) \ - xor8bytesIntoInterleavedWords(state+i*2, input+i*8); \ - } - -#endif /* Endianness */ - -/* Credit: Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ -UINT64 fromInterleaving(UINT64 x) -{ - UINT64 t; - - t = (x ^ (x >> 16)) & 0x00000000FFFF0000ULL; x = x ^ t ^ (t << 16); - t = (x ^ (x >> 8)) & 0x0000FF000000FF00ULL; x = x ^ t ^ (t << 8); - t = (x ^ (x >> 4)) & 0x00F000F000F000F0ULL; x = x ^ t ^ (t << 4); - t = (x ^ (x >> 2)) & 0x0C0C0C0C0C0C0C0CULL; x = x ^ t ^ (t << 2); - t = (x ^ (x >> 1)) & 0x2222222222222222ULL; x = x ^ t ^ (t << 1); - - return x; -} - -static void setInterleavedWordsInto8bytes(UINT8* dest, UINT32* evenAndOdd) -{ -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - ((UINT64*)dest)[0] = fromInterleaving(*(UINT64*)evenAndOdd); -#else /* (PLATFORM_BYTE_ORDER == IS_BIG_ENDIAN) */ - /* This can be optimized */ - UINT64 evenAndOddWord = (UINT64)evenAndOdd[0] ^ ((UINT64)evenAndOdd[1] << 32); - UINT64 destWord = fromInterleaving(evenAndOddWord); - dest[0] = destWord & 0xFF; - dest[1] = (destWord >> 8) & 0xFF; - dest[2] = (destWord >> 16) & 0xFF; - dest[3] = (destWord >> 24) & 0xFF; - dest[4] = (destWord >> 32) & 0xFF; - dest[5] = (destWord >> 40) & 0xFF; - dest[6] = (destWord >> 48) & 0xFF; - dest[7] = (destWord >> 56) & 0xFF; -#endif /* Endianness */ -} - -#define extractLanes(laneCount, state, data) \ - { \ - unsigned int i; \ - for(i=0; i<(laneCount); i++) \ - setInterleavedWordsInto8bytes(data+i*8, (UINT32*)state+i*2); \ - } - -#endif /* With or without interleaving tables */ - -#if defined(_MSC_VER) -#define ROL32(a, offset) _rotl(a, offset) -#elif (defined (__arm__) && defined(__ARMCC_VERSION)) -#define ROL32(a, offset) __ror(a, 32-(offset)) -#else -#define ROL32(a, offset) ((((UINT32)a) << (offset)) ^ (((UINT32)a) >> (32-(offset)))) -#endif - -#include "KeccakF-1600-unrolling.macros" -#include "KeccakF-1600-32.macros" - -#if (UseSchedule == 3) - -#ifdef UseBebigokimisa -#error "No lane complementing with schedule 3." -#endif - -#if (Unrolling != 2) -#error "Only unrolling 2 is supported by schedule 3." -#endif - -static void KeccakPermutationOnWords(UINT32 *state) -{ - rounds -} - -static void KeccakPermutationOnWordsAfterXoring(UINT32 *state, const UINT8 *input, unsigned int laneCount) -{ - xorLanesIntoState(laneCount, state, input) - rounds -} - -#ifdef ProvideFast576 -static void KeccakPermutationOnWordsAfterXoring576bits(UINT32 *state, const UINT8 *input) -{ - xorLanesIntoState(9, state, input) - rounds -} -#endif - -#ifdef ProvideFast832 -static void KeccakPermutationOnWordsAfterXoring832bits(UINT32 *state, const UINT8 *input) -{ - xorLanesIntoState(13, state, input) - rounds -} -#endif - -#ifdef ProvideFast1024 -static void KeccakPermutationOnWordsAfterXoring1024bits(UINT32 *state, const UINT8 *input) -{ - xorLanesIntoState(16, state, input) - rounds -} -#endif - -#ifdef ProvideFast1088 -static void KeccakPermutationOnWordsAfterXoring1088bits(UINT32 *state, const UINT8 *input) -{ - xorLanesIntoState(17, state, input) - rounds -} -#endif - -#ifdef ProvideFast1152 -static void KeccakPermutationOnWordsAfterXoring1152bits(UINT32 *state, const UINT8 *input) -{ - xorLanesIntoState(18, state, input) - rounds -} -#endif - -#ifdef ProvideFast1344 -static void KeccakPermutationOnWordsAfterXoring1344bits(UINT32 *state, const UINT8 *input) -{ - xorLanesIntoState(21, state, input) - rounds -} -#endif - -#else /* (Schedule != 3) */ - -static void KeccakPermutationOnWords(UINT32 *state) -{ - declareABCDE -#if (Unrolling != 24) - unsigned int i; -#endif - - copyFromState(A, state) - rounds -} - -static void KeccakPermutationOnWordsAfterXoring(UINT32 *state, const UINT8 *input, unsigned int laneCount) -{ - declareABCDE - unsigned int i; - - xorLanesIntoState(laneCount, state, input) - copyFromState(A, state) - rounds -} - -#ifdef ProvideFast576 -static void KeccakPermutationOnWordsAfterXoring576bits(UINT32 *state, const UINT8 *input) -{ - declareABCDE - unsigned int i; - - xorLanesIntoState(9, state, input) - copyFromState(A, state) - rounds -} -#endif - -#ifdef ProvideFast832 -static void KeccakPermutationOnWordsAfterXoring832bits(UINT32 *state, const UINT8 *input) -{ - declareABCDE - unsigned int i; - - xorLanesIntoState(13, state, input) - copyFromState(A, state) - rounds -} -#endif - -#ifdef ProvideFast1024 -static void KeccakPermutationOnWordsAfterXoring1024bits(UINT32 *state, const UINT8 *input) -{ - declareABCDE - unsigned int i; - - xorLanesIntoState(16, state, input) - copyFromState(A, state) - rounds -} -#endif - -#ifdef ProvideFast1088 -static void KeccakPermutationOnWordsAfterXoring1088bits(UINT32 *state, const UINT8 *input) -{ - declareABCDE - unsigned int i; - - xorLanesIntoState(17, state, input) - copyFromState(A, state) - rounds -} -#endif - -#ifdef ProvideFast1152 -static void KeccakPermutationOnWordsAfterXoring1152bits(UINT32 *state, const UINT8 *input) -{ - declareABCDE - unsigned int i; - - xorLanesIntoState(18, state, input) - copyFromState(A, state) - rounds -} -#endif - -#ifdef ProvideFast1344 -static void KeccakPermutationOnWordsAfterXoring1344bits(UINT32 *state, const UINT8 *input) -{ - declareABCDE - unsigned int i; - - xorLanesIntoState(21, state, input) - copyFromState(A, state) - rounds -} -#endif - -#endif - -static void KeccakInitialize() -{ -#ifdef UseInterleaveTables - buildInterleaveTables(); -#endif -} - -static void KeccakInitializeState(unsigned char *state) -{ - memset(state, 0, 200); -#ifdef UseBebigokimisa - ((UINT32*)state)[ 2] = ~(UINT32)0; - ((UINT32*)state)[ 3] = ~(UINT32)0; - ((UINT32*)state)[ 4] = ~(UINT32)0; - ((UINT32*)state)[ 5] = ~(UINT32)0; - ((UINT32*)state)[16] = ~(UINT32)0; - ((UINT32*)state)[17] = ~(UINT32)0; - ((UINT32*)state)[24] = ~(UINT32)0; - ((UINT32*)state)[25] = ~(UINT32)0; - ((UINT32*)state)[34] = ~(UINT32)0; - ((UINT32*)state)[35] = ~(UINT32)0; - ((UINT32*)state)[40] = ~(UINT32)0; - ((UINT32*)state)[41] = ~(UINT32)0; -#endif -} - -static void KeccakPermutation(unsigned char *state) -{ - /* We assume the state is always stored as interleaved 32-bit words */ - KeccakPermutationOnWords((UINT32*)state); -} - -#ifdef ProvideFast576 -static void KeccakAbsorb576bits(unsigned char *state, const unsigned char *data) -{ - KeccakPermutationOnWordsAfterXoring576bits((UINT32*)state, data); -} -#endif - -#ifdef ProvideFast832 -static void KeccakAbsorb832bits(unsigned char *state, const unsigned char *data) -{ - KeccakPermutationOnWordsAfterXoring832bits((UINT32*)state, data); -} -#endif - -#ifdef ProvideFast1024 -static void KeccakAbsorb1024bits(unsigned char *state, const unsigned char *data) -{ - KeccakPermutationOnWordsAfterXoring1024bits((UINT32*)state, data); -} -#endif - -#ifdef ProvideFast1088 -static void KeccakAbsorb1088bits(unsigned char *state, const unsigned char *data) -{ - KeccakPermutationOnWordsAfterXoring1088bits((UINT32*)state, data); -} -#endif - -#ifdef ProvideFast1152 -static void KeccakAbsorb1152bits(unsigned char *state, const unsigned char *data) -{ - KeccakPermutationOnWordsAfterXoring1152bits((UINT32*)state, data); -} -#endif - -#ifdef ProvideFast1344 -static void KeccakAbsorb1344bits(unsigned char *state, const unsigned char *data) -{ - KeccakPermutationOnWordsAfterXoring1344bits((UINT32*)state, data); -} -#endif - -static void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsigned int laneCount) -{ - KeccakPermutationOnWordsAfterXoring((UINT32*)state, data, laneCount); -} - -#ifdef ProvideFast1024 -static void KeccakExtract1024bits(const unsigned char *state, unsigned char *data) -{ - extractLanes(16, state, data) -#ifdef UseBebigokimisa - ((UINT32*)data)[ 2] = ~((UINT32*)data)[ 2]; - ((UINT32*)data)[ 3] = ~((UINT32*)data)[ 3]; - ((UINT32*)data)[ 4] = ~((UINT32*)data)[ 4]; - ((UINT32*)data)[ 5] = ~((UINT32*)data)[ 5]; - ((UINT32*)data)[16] = ~((UINT32*)data)[16]; - ((UINT32*)data)[17] = ~((UINT32*)data)[17]; - ((UINT32*)data)[24] = ~((UINT32*)data)[24]; - ((UINT32*)data)[25] = ~((UINT32*)data)[25]; -#endif -} -#endif - -static void KeccakExtract(const unsigned char *state, unsigned char *data, unsigned int laneCount) -{ - extractLanes(laneCount, state, data) -#ifdef UseBebigokimisa - if (laneCount > 1) { - ((UINT32*)data)[ 2] = ~((UINT32*)data)[ 2]; - ((UINT32*)data)[ 3] = ~((UINT32*)data)[ 3]; - if (laneCount > 2) { - ((UINT32*)data)[ 4] = ~((UINT32*)data)[ 4]; - ((UINT32*)data)[ 5] = ~((UINT32*)data)[ 5]; - if (laneCount > 8) { - ((UINT32*)data)[16] = ~((UINT32*)data)[16]; - ((UINT32*)data)[17] = ~((UINT32*)data)[17]; - if (laneCount > 12) { - ((UINT32*)data)[24] = ~((UINT32*)data)[24]; - ((UINT32*)data)[25] = ~((UINT32*)data)[25]; - if (laneCount > 17) { - ((UINT32*)data)[34] = ~((UINT32*)data)[34]; - ((UINT32*)data)[35] = ~((UINT32*)data)[35]; - if (laneCount > 20) { - ((UINT32*)data)[40] = ~((UINT32*)data)[40]; - ((UINT32*)data)[41] = ~((UINT32*)data)[41]; - } - } - } - } - } - } -#endif -} diff --git a/Modules/_sha3/keccak/KeccakF-1600-opt64-settings.h b/Modules/_sha3/keccak/KeccakF-1600-opt64-settings.h deleted file mode 100644 index df83e6331fcc..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-opt64-settings.h +++ /dev/null @@ -1,9 +0,0 @@ -/* -#define Unrolling 24 -#define UseBebigokimisa -#define UseSSE -#define UseOnlySIMD64 -#define UseMMX -#define UseSHLD -#define UseXOP -*/ diff --git a/Modules/_sha3/keccak/KeccakF-1600-opt64.c b/Modules/_sha3/keccak/KeccakF-1600-opt64.c deleted file mode 100644 index f19b18b36ac4..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-opt64.c +++ /dev/null @@ -1,510 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -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 "KeccakF-1600-opt64-settings.h" -#include "KeccakF-1600-interface.h" - -typedef unsigned char UINT8; -/* typedef unsigned long long int UINT64; */ - -#if defined(__GNUC__) -#define ALIGN __attribute__ ((aligned(32))) -#elif defined(_MSC_VER) -#define ALIGN __declspec(align(32)) -#else -#define ALIGN -#endif - -#if defined(UseSSE) - #include - typedef __m128i V64; - typedef __m128i V128; - typedef union { - V128 v128; - UINT64 v64[2]; - } V6464; - - #define ANDnu64(a, b) _mm_andnot_si128(a, b) - #define LOAD64(a) _mm_loadl_epi64((const V64 *)&(a)) - #define CONST64(a) _mm_loadl_epi64((const V64 *)&(a)) - #define ROL64(a, o) _mm_or_si128(_mm_slli_epi64(a, o), _mm_srli_epi64(a, 64-(o))) - #define STORE64(a, b) _mm_storel_epi64((V64 *)&(a), b) - #define XOR64(a, b) _mm_xor_si128(a, b) - #define XOReq64(a, b) a = _mm_xor_si128(a, b) - #define SHUFFLEBYTES128(a, b) _mm_shuffle_epi8(a, b) - - #define ANDnu128(a, b) _mm_andnot_si128(a, b) - #define LOAD6464(a, b) _mm_set_epi64((__m64)(a), (__m64)(b)) - #define CONST128(a) _mm_load_si128((const V128 *)&(a)) - #define LOAD128(a) _mm_load_si128((const V128 *)&(a)) - #define LOAD128u(a) _mm_loadu_si128((const V128 *)&(a)) - #define ROL64in128(a, o) _mm_or_si128(_mm_slli_epi64(a, o), _mm_srli_epi64(a, 64-(o))) - #define STORE128(a, b) _mm_store_si128((V128 *)&(a), b) - #define XOR128(a, b) _mm_xor_si128(a, b) - #define XOReq128(a, b) a = _mm_xor_si128(a, b) - #define GET64LOLO(a, b) _mm_unpacklo_epi64(a, b) - #define GET64HIHI(a, b) _mm_unpackhi_epi64(a, b) - #define COPY64HI2LO(a) _mm_shuffle_epi32(a, 0xEE) - #define COPY64LO2HI(a) _mm_shuffle_epi32(a, 0x44) - #define ZERO128() _mm_setzero_si128() - - #ifdef UseOnlySIMD64 - #include "KeccakF-1600-simd64.macros" - #else -ALIGN const UINT64 rho8_56[2] = {0x0605040302010007, 0x080F0E0D0C0B0A09}; - #include "KeccakF-1600-simd128.macros" - #endif - - #ifdef UseBebigokimisa - #error "UseBebigokimisa cannot be used in combination with UseSSE" - #endif -#elif defined(UseXOP) - #include - typedef __m128i V64; - typedef __m128i V128; - - #define LOAD64(a) _mm_loadl_epi64((const V64 *)&(a)) - #define CONST64(a) _mm_loadl_epi64((const V64 *)&(a)) - #define STORE64(a, b) _mm_storel_epi64((V64 *)&(a), b) - #define XOR64(a, b) _mm_xor_si128(a, b) - #define XOReq64(a, b) a = _mm_xor_si128(a, b) - - #define ANDnu128(a, b) _mm_andnot_si128(a, b) - #define LOAD6464(a, b) _mm_set_epi64((__m64)(a), (__m64)(b)) - #define CONST128(a) _mm_load_si128((const V128 *)&(a)) - #define LOAD128(a) _mm_load_si128((const V128 *)&(a)) - #define LOAD128u(a) _mm_loadu_si128((const V128 *)&(a)) - #define STORE128(a, b) _mm_store_si128((V128 *)&(a), b) - #define XOR128(a, b) _mm_xor_si128(a, b) - #define XOReq128(a, b) a = _mm_xor_si128(a, b) - #define ZERO128() _mm_setzero_si128() - - #define SWAP64(a) _mm_shuffle_epi32(a, 0x4E) - #define GET64LOLO(a, b) _mm_unpacklo_epi64(a, b) - #define GET64HIHI(a, b) _mm_unpackhi_epi64(a, b) - #define GET64LOHI(a, b) ((__m128i)_mm_blend_pd((__m128d)a, (__m128d)b, 2)) - #define GET64HILO(a, b) SWAP64(GET64LOHI(b, a)) - #define COPY64HI2LO(a) _mm_shuffle_epi32(a, 0xEE) - #define COPY64LO2HI(a) _mm_shuffle_epi32(a, 0x44) - - #define ROL6464same(a, o) _mm_roti_epi64(a, o) - #define ROL6464(a, r1, r2) _mm_rot_epi64(a, CONST128( rot_##r1##_##r2 )) -ALIGN const UINT64 rot_0_20[2] = { 0, 20}; -ALIGN const UINT64 rot_44_3[2] = {44, 3}; -ALIGN const UINT64 rot_43_45[2] = {43, 45}; -ALIGN const UINT64 rot_21_61[2] = {21, 61}; -ALIGN const UINT64 rot_14_28[2] = {14, 28}; -ALIGN const UINT64 rot_1_36[2] = { 1, 36}; -ALIGN const UINT64 rot_6_10[2] = { 6, 10}; -ALIGN const UINT64 rot_25_15[2] = {25, 15}; -ALIGN const UINT64 rot_8_56[2] = { 8, 56}; -ALIGN const UINT64 rot_18_27[2] = {18, 27}; -ALIGN const UINT64 rot_62_55[2] = {62, 55}; -ALIGN const UINT64 rot_39_41[2] = {39, 41}; - -#if defined(UseSimulatedXOP) - /* For debugging purposes, when XOP is not available */ - #undef ROL6464 - #undef ROL6464same - #define ROL6464same(a, o) _mm_or_si128(_mm_slli_epi64(a, o), _mm_srli_epi64(a, 64-(o))) - V128 ROL6464(V128 a, int r0, int r1) - { - V128 a0 = ROL64(a, r0); - V128 a1 = COPY64HI2LO(ROL64(a, r1)); - return GET64LOLO(a0, a1); - } -#endif - - #include "KeccakF-1600-xop.macros" - - #ifdef UseBebigokimisa - #error "UseBebigokimisa cannot be used in combination with UseXOP" - #endif -#elif defined(UseMMX) - #include - typedef __m64 V64; - #define ANDnu64(a, b) _mm_andnot_si64(a, b) - - #if (defined(_MSC_VER) || defined (__INTEL_COMPILER)) - #define LOAD64(a) *(V64*)&(a) - #define CONST64(a) *(V64*)&(a) - #define STORE64(a, b) *(V64*)&(a) = b - #else - #define LOAD64(a) (V64)a - #define CONST64(a) (V64)a - #define STORE64(a, b) a = (UINT64)b - #endif - #define ROL64(a, o) _mm_or_si64(_mm_slli_si64(a, o), _mm_srli_si64(a, 64-(o))) - #define XOR64(a, b) _mm_xor_si64(a, b) - #define XOReq64(a, b) a = _mm_xor_si64(a, b) - - #include "KeccakF-1600-simd64.macros" - - #ifdef UseBebigokimisa - #error "UseBebigokimisa cannot be used in combination with UseMMX" - #endif -#else - #if defined(_MSC_VER) - #define ROL64(a, offset) _rotl64(a, offset) - #elif defined(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 "KeccakF-1600-64.macros" -#endif - -#include "KeccakF-1600-unrolling.macros" - -static void KeccakPermutationOnWords(UINT64 *state) -{ - declareABCDE -#if (Unrolling != 24) - unsigned int i; -#endif - - copyFromState(A, state) - rounds -#if defined(UseMMX) - _mm_empty(); -#endif -} - -static void KeccakPermutationOnWordsAfterXoring(UINT64 *state, const UINT64 *input, unsigned int laneCount) -{ - declareABCDE -#if (Unrolling != 24) - unsigned int i; -#endif - unsigned int j; - - for(j=0; j> (8*i)) & 0xFF; -} -#endif - - -#ifdef ProvideFast1024 -static void KeccakExtract1024bits(const unsigned char *state, unsigned char *data) -{ -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) - memcpy(data, state, 128); -#else - unsigned int i; - - for(i=0; i<16; i++) - fromWordToBytes(data+(i*8), ((const UINT64*)state)[i]); -#endif -#ifdef UseBebigokimisa - ((UINT64*)data)[ 1] = ~((UINT64*)data)[ 1]; - ((UINT64*)data)[ 2] = ~((UINT64*)data)[ 2]; - ((UINT64*)data)[ 8] = ~((UINT64*)data)[ 8]; - ((UINT64*)data)[12] = ~((UINT64*)data)[12]; -#endif -} -#endif - -static void KeccakExtract(const unsigned char *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 -} diff --git a/Modules/_sha3/keccak/KeccakF-1600-simd128.macros b/Modules/_sha3/keccak/KeccakF-1600-simd128.macros deleted file mode 100644 index 98e47f5a59a5..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-simd128.macros +++ /dev/null @@ -1,651 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -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 \ - V6464 Abage, Abegi, Abigo, Abogu, Abuga; \ - V6464 Akame, Akemi, Akimo, Akomu, Akuma; \ - V6464 Abae, Abio, Agae, Agio, Akae, Akio, Amae, Amio, Asae, Asio; \ - V64 Aba, Abe, Abi, Abo, Abu; \ - V64 Aga, Age, Agi, Ago, Agu; \ - V64 Aka, Ake, Aki, Ako, Aku; \ - V64 Ama, Ame, Ami, Amo, Amu; \ - V64 Asa, Ase, Asi, Aso, Asu; \ - V128 Bbage, Bbegi, Bbigo, Bbogu, Bbuga; \ - V128 Bkame, Bkemi, Bkimo, Bkomu, Bkuma; \ - V64 Bba, Bbe, Bbi, Bbo, Bbu; \ - V64 Bga, Bge, Bgi, Bgo, Bgu; \ - V64 Bka, Bke, Bki, Bko, Bku; \ - V64 Bma, Bme, Bmi, Bmo, Bmu; \ - V64 Bsa, Bse, Bsi, Bso, Bsu; \ - V128 Cae, Cei, Cio, Cou, Cua, Dei, Dou; \ - V64 Ca, Ce, Ci, Co, Cu; \ - V64 Da, De, Di, Do, Du; \ - V6464 Ebage, Ebegi, Ebigo, Ebogu, Ebuga; \ - V6464 Ekame, Ekemi, Ekimo, Ekomu, Ekuma; \ - V64 Eba, Ebe, Ebi, Ebo, Ebu; \ - V64 Ega, Ege, Egi, Ego, Egu; \ - V64 Eka, Eke, Eki, Eko, Eku; \ - V64 Ema, Eme, Emi, Emo, Emu; \ - V64 Esa, Ese, Esi, Eso, Esu; \ - V128 Zero; - -#define prepareTheta - -#define computeD \ - Cua = GET64LOLO(Cu, Cae); \ - Dei = XOR128(Cae, ROL64in128(Cio, 1)); \ - Dou = XOR128(Cio, ROL64in128(Cua, 1)); \ - Da = XOR64(Cu, ROL64in128(COPY64HI2LO(Cae), 1)); \ - De = Dei; \ - Di = COPY64HI2LO(Dei); \ - Do = Dou; \ - Du = COPY64HI2LO(Dou); - -/* --- Theta Rho Pi Chi Iota Prepare-theta */ -/* --- 64-bit lanes mapped to 64-bit and 128-bit words */ -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - computeD \ - \ - A##ba = LOAD64(A##bage.v64[0]); \ - XOReq64(A##ba, Da); \ - Bba = A##ba; \ - XOReq64(A##gu, Du); \ - Bge = ROL64(A##gu, 20); \ - Bbage = GET64LOLO(Bba, Bge); \ - A##ge = LOAD64(A##bage.v64[1]); \ - XOReq64(A##ge, De); \ - Bbe = ROL64(A##ge, 44); \ - A##ka = LOAD64(A##kame.v64[0]); \ - XOReq64(A##ka, Da); \ - Bgi = ROL64(A##ka, 3); \ - Bbegi = GET64LOLO(Bbe, Bgi); \ - XOReq64(A##ki, Di); \ - Bbi = ROL64(A##ki, 43); \ - A##me = LOAD64(A##kame.v64[1]); \ - XOReq64(A##me, De); \ - Bgo = ROL64(A##me, 45); \ - Bbigo = GET64LOLO(Bbi, Bgo); \ - E##bage.v128 = XOR128(Bbage, ANDnu128(Bbegi, Bbigo)); \ - XOReq128(E##bage.v128, CONST64(KeccakF1600RoundConstants[i])); \ - Cae = E##bage.v128; \ - XOReq64(A##mo, Do); \ - Bbo = ROL64(A##mo, 21); \ - XOReq64(A##si, Di); \ - Bgu = ROL64(A##si, 61); \ - Bbogu = GET64LOLO(Bbo, Bgu); \ - E##begi.v128 = XOR128(Bbegi, ANDnu128(Bbigo, Bbogu)); \ - Cei = E##begi.v128; \ - XOReq64(A##su, Du); \ - Bbu = ROL64(A##su, 14); \ - XOReq64(A##bo, Do); \ - Bga = ROL64(A##bo, 28); \ - Bbuga = GET64LOLO(Bbu, Bga); \ - E##bigo.v128 = XOR128(Bbigo, ANDnu128(Bbogu, Bbuga)); \ - E##bi = E##bigo.v128; \ - E##go = GET64HIHI(E##bigo.v128, E##bigo.v128); \ - Cio = E##bigo.v128; \ - E##bogu.v128 = XOR128(Bbogu, ANDnu128(Bbuga, Bbage)); \ - E##bo = E##bogu.v128; \ - E##gu = GET64HIHI(E##bogu.v128, E##bogu.v128); \ - Cou = E##bogu.v128; \ - E##buga.v128 = XOR128(Bbuga, ANDnu128(Bbage, Bbegi)); \ - E##bu = E##buga.v128; \ - E##ga = GET64HIHI(E##buga.v128, E##buga.v128); \ - Cua = E##buga.v128; \ -\ - A##be = LOAD64(A##begi.v64[0]); \ - XOReq64(A##be, De); \ - Bka = ROL64(A##be, 1); \ - XOReq64(A##ga, Da); \ - Bme = ROL64(A##ga, 36); \ - Bkame = GET64LOLO(Bka, Bme); \ - A##gi = LOAD64(A##begi.v64[1]); \ - XOReq64(A##gi, Di); \ - Bke = ROL64(A##gi, 6); \ - A##ke = LOAD64(A##kemi.v64[0]); \ - XOReq64(A##ke, De); \ - Bmi = ROL64(A##ke, 10); \ - Bkemi = GET64LOLO(Bke, Bmi); \ - XOReq64(A##ko, Do); \ - Bki = ROL64(A##ko, 25); \ - A##mi = LOAD64(A##kemi.v64[1]); \ - XOReq64(A##mi, Di); \ - Bmo = ROL64(A##mi, 15); \ - Bkimo = GET64LOLO(Bki, Bmo); \ - E##kame.v128 = XOR128(Bkame, ANDnu128(Bkemi, Bkimo)); \ - XOReq128(Cae, E##kame.v128); \ - Bkomu = GET64LOLO(XOR64(A##mu, Du), XOR64(A##so, Do)); \ - Bkomu = SHUFFLEBYTES128(Bkomu, CONST128(rho8_56)); \ - E##kemi.v128 = XOR128(Bkemi, ANDnu128(Bkimo, Bkomu)); \ - XOReq128(Cei, E##kemi.v128); \ - XOReq64(A##sa, Da); \ - Bku = ROL64(A##sa, 18); \ - XOReq64(A##bu, Du); \ - Bma = ROL64(A##bu, 27); \ - Bkuma = GET64LOLO(Bku, Bma); \ - E##kimo.v128 = XOR128(Bkimo, ANDnu128(Bkomu, Bkuma)); \ - E##ki = E##kimo.v128; \ - E##mo = GET64HIHI(E##kimo.v128, E##kimo.v128); \ - XOReq128(Cio, E##kimo.v128); \ - E##komu.v128 = XOR128(Bkomu, ANDnu128(Bkuma, Bkame)); \ - E##ko = E##komu.v128; \ - E##mu = GET64HIHI(E##komu.v128, E##komu.v128); \ - XOReq128(Cou, E##komu.v128); \ - E##kuma.v128 = XOR128(Bkuma, ANDnu128(Bkame, Bkemi)); \ - E##ku = E##kuma.v128; \ - E##ma = GET64HIHI(E##kuma.v128, E##kuma.v128); \ - XOReq128(Cua, E##kuma.v128); \ -\ - XOReq64(A##bi, Di); \ - Bsa = ROL64(A##bi, 62); \ - XOReq64(A##go, Do); \ - Bse = ROL64(A##go, 55); \ - XOReq64(A##ku, Du); \ - Bsi = ROL64(A##ku, 39); \ - E##sa = XOR64(Bsa, ANDnu64(Bse, Bsi)); \ - Ca = E##sa; \ - XOReq64(A##ma, Da); \ - Bso = ROL64(A##ma, 41); \ - E##se = XOR64(Bse, ANDnu64(Bsi, Bso)); \ - Ce = E##se; \ - XOReq128(Cae, GET64LOLO(Ca, Ce)); \ - XOReq64(A##se, De); \ - Bsu = ROL64(A##se, 2); \ - E##si = XOR64(Bsi, ANDnu64(Bso, Bsu)); \ - Ci = E##si; \ - E##so = XOR64(Bso, ANDnu64(Bsu, Bsa)); \ - Co = E##so; \ - XOReq128(Cio, GET64LOLO(Ci, Co)); \ - E##su = XOR64(Bsu, ANDnu64(Bsa, Bse)); \ - Cu = E##su; \ -\ - Zero = ZERO128(); \ - XOReq128(Cae, GET64HIHI(Cua, Zero)); \ - XOReq128(Cae, GET64LOLO(Zero, Cei)); \ - XOReq128(Cio, GET64HIHI(Cei, Zero)); \ - XOReq128(Cio, GET64LOLO(Zero, Cou)); \ - XOReq128(Cua, GET64HIHI(Cou, Zero)); \ - XOReq64(Cu, Cua); \ - -/* --- Theta Rho Pi Chi Iota */ -/* --- 64-bit lanes mapped to 64-bit and 128-bit words */ -#define thetaRhoPiChiIota(i, A, E) thetaRhoPiChiIotaPrepareTheta(i, A, E) - -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 }; - -#define copyFromStateAndXor576bits(X, state, input) \ - X##bae.v128 = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae.v128; \ - X##be = GET64HIHI(X##bae.v128, X##bae.v128); \ - Cae = X##bae.v128; \ - X##bio.v128 = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio.v128; \ - X##bo = GET64HIHI(X##bio.v128, X##bio.v128); \ - Cio = X##bio.v128; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cu = X##bu; \ - X##gae.v128 = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae.v128; \ - X##ge = GET64HIHI(X##gae.v128, X##gae.v128); \ - X##bage.v128 = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae.v128); \ - X##gio.v128 = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio.v128; \ - X##begi.v128 = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio.v128, X##gio.v128); \ - XOReq128(Cio, X##gio.v128); \ - X##gu = LOAD64(state[ 9]); \ - XOReq64(Cu, X##gu); \ - X##kae.v128 = LOAD128(state[10]); \ - X##ka = X##kae.v128; \ - X##ke = GET64HIHI(X##kae.v128, X##kae.v128); \ - XOReq128(Cae, X##kae.v128); \ - X##kio.v128 = LOAD128(state[12]); \ - X##ki = X##kio.v128; \ - X##ko = GET64HIHI(X##kio.v128, X##kio.v128); \ - XOReq128(Cio, X##kio.v128); \ - X##ku = LOAD64(state[14]); \ - XOReq64(Cu, X##ku); \ - X##mae.v128 = LOAD128u(state[15]); \ - X##ma = X##mae.v128; \ - X##me = GET64HIHI(X##mae.v128, X##mae.v128); \ - X##kame.v128 = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, X##mae.v128); \ - X##mio.v128 = LOAD128u(state[17]); \ - X##mi = X##mio.v128; \ - X##kemi.v128 = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio.v128, X##mio.v128); \ - XOReq128(Cio, X##mio.v128); \ - X##mu = LOAD64(state[19]); \ - XOReq64(Cu, X##mu); \ - X##sae.v128 = LOAD128(state[20]); \ - X##sa = X##sae.v128; \ - X##se = GET64HIHI(X##sae.v128, X##sae.v128); \ - XOReq128(Cae, X##sae.v128); \ - X##sio.v128 = LOAD128(state[22]); \ - X##si = X##sio.v128; \ - X##so = GET64HIHI(X##sio.v128, X##sio.v128); \ - XOReq128(Cio, X##sio.v128); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cu, X##su); \ - -#define copyFromStateAndXor832bits(X, state, input) \ - X##bae.v128 = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae.v128; \ - X##be = GET64HIHI(X##bae.v128, X##bae.v128); \ - Cae = X##bae.v128; \ - X##bio.v128 = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio.v128; \ - X##bo = GET64HIHI(X##bio.v128, X##bio.v128); \ - Cio = X##bio.v128; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cu = X##bu; \ - X##gae.v128 = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae.v128; \ - X##ge = GET64HIHI(X##gae.v128, X##gae.v128); \ - X##bage.v128 = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae.v128); \ - X##gio.v128 = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio.v128; \ - X##begi.v128 = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio.v128, X##gio.v128); \ - XOReq128(Cio, X##gio.v128); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - XOReq64(Cu, X##gu); \ - X##kae.v128 = XOR128(LOAD128(state[10]), LOAD128u(input[10])); \ - X##ka = X##kae.v128; \ - X##ke = GET64HIHI(X##kae.v128, X##kae.v128); \ - XOReq128(Cae, X##kae.v128); \ - X##kio.v128 = XOR128(LOAD128(state[12]), LOAD64(input[12])); \ - X##ki = X##kio.v128; \ - X##ko = GET64HIHI(X##kio.v128, X##kio.v128); \ - XOReq128(Cio, X##kio.v128); \ - X##ku = LOAD64(state[14]); \ - XOReq64(Cu, X##ku); \ - X##mae.v128 = LOAD128u(state[15]); \ - X##ma = X##mae.v128; \ - X##me = GET64HIHI(X##mae.v128, X##mae.v128); \ - X##kame.v128 = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, X##mae.v128); \ - X##mio.v128 = LOAD128u(state[17]); \ - X##mi = X##mio.v128; \ - X##kemi.v128 = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio.v128, X##mio.v128); \ - XOReq128(Cio, X##mio.v128); \ - X##mu = LOAD64(state[19]); \ - XOReq64(Cu, X##mu); \ - X##sae.v128 = LOAD128(state[20]); \ - X##sa = X##sae.v128; \ - X##se = GET64HIHI(X##sae.v128, X##sae.v128); \ - XOReq128(Cae, X##sae.v128); \ - X##sio.v128 = LOAD128(state[22]); \ - X##si = X##sio.v128; \ - X##so = GET64HIHI(X##sio.v128, X##sio.v128); \ - XOReq128(Cio, X##sio.v128); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cu, X##su); \ - -#define copyFromStateAndXor1024bits(X, state, input) \ - X##bae.v128 = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae.v128; \ - X##be = GET64HIHI(X##bae.v128, X##bae.v128); \ - Cae = X##bae.v128; \ - X##bio.v128 = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio.v128; \ - X##bo = GET64HIHI(X##bio.v128, X##bio.v128); \ - Cio = X##bio.v128; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cu = X##bu; \ - X##gae.v128 = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae.v128; \ - X##ge = GET64HIHI(X##gae.v128, X##gae.v128); \ - X##bage.v128 = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae.v128); \ - X##gio.v128 = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio.v128; \ - X##begi.v128 = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio.v128, X##gio.v128); \ - XOReq128(Cio, X##gio.v128); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - XOReq64(Cu, X##gu); \ - X##kae.v128 = XOR128(LOAD128(state[10]), LOAD128u(input[10])); \ - X##ka = X##kae.v128; \ - X##ke = GET64HIHI(X##kae.v128, X##kae.v128); \ - XOReq128(Cae, X##kae.v128); \ - X##kio.v128 = XOR128(LOAD128(state[12]), LOAD128u(input[12])); \ - X##ki = X##kio.v128; \ - X##ko = GET64HIHI(X##kio.v128, X##kio.v128); \ - XOReq128(Cio, X##kio.v128); \ - X##ku = XOR64(LOAD64(state[14]), LOAD64(input[14])); \ - XOReq64(Cu, X##ku); \ - X##mae.v128 = XOR128(LOAD128u(state[15]), LOAD64(input[15])); \ - X##ma = X##mae.v128; \ - X##me = GET64HIHI(X##mae.v128, X##mae.v128); \ - X##kame.v128 = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, X##mae.v128); \ - X##mio.v128 = LOAD128u(state[17]); \ - X##mi = X##mio.v128; \ - X##kemi.v128 = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio.v128, X##mio.v128); \ - XOReq128(Cio, X##mio.v128); \ - X##mu = LOAD64(state[19]); \ - XOReq64(Cu, X##mu); \ - X##sae.v128 = LOAD128(state[20]); \ - X##sa = X##sae.v128; \ - X##se = GET64HIHI(X##sae.v128, X##sae.v128); \ - XOReq128(Cae, X##sae.v128); \ - X##sio.v128 = LOAD128(state[22]); \ - X##si = X##sio.v128; \ - X##so = GET64HIHI(X##sio.v128, X##sio.v128); \ - XOReq128(Cio, X##sio.v128); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cu, X##su); \ - -#define copyFromStateAndXor1088bits(X, state, input) \ - X##bae.v128 = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae.v128; \ - X##be = GET64HIHI(X##bae.v128, X##bae.v128); \ - Cae = X##bae.v128; \ - X##bio.v128 = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio.v128; \ - X##bo = GET64HIHI(X##bio.v128, X##bio.v128); \ - Cio = X##bio.v128; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cu = X##bu; \ - X##gae.v128 = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae.v128; \ - X##ge = GET64HIHI(X##gae.v128, X##gae.v128); \ - X##bage.v128 = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae.v128); \ - X##gio.v128 = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio.v128; \ - X##begi.v128 = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio.v128, X##gio.v128); \ - XOReq128(Cio, X##gio.v128); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - XOReq64(Cu, X##gu); \ - X##kae.v128 = XOR128(LOAD128(state[10]), LOAD128u(input[10])); \ - X##ka = X##kae.v128; \ - X##ke = GET64HIHI(X##kae.v128, X##kae.v128); \ - XOReq128(Cae, X##kae.v128); \ - X##kio.v128 = XOR128(LOAD128(state[12]), LOAD128u(input[12])); \ - X##ki = X##kio.v128; \ - X##ko = GET64HIHI(X##kio.v128, X##kio.v128); \ - XOReq128(Cio, X##kio.v128); \ - X##ku = XOR64(LOAD64(state[14]), LOAD64(input[14])); \ - XOReq64(Cu, X##ku); \ - X##mae.v128 = XOR128(LOAD128u(state[15]), LOAD128u(input[15])); \ - X##ma = X##mae.v128; \ - X##me = GET64HIHI(X##mae.v128, X##mae.v128); \ - X##kame.v128 = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, X##mae.v128); \ - X##mio.v128 = LOAD128u(state[17]); \ - X##mi = X##mio.v128; \ - X##kemi.v128 = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio.v128, X##mio.v128); \ - XOReq128(Cio, X##mio.v128); \ - X##mu = LOAD64(state[19]); \ - XOReq64(Cu, X##mu); \ - X##sae.v128 = LOAD128(state[20]); \ - X##sa = X##sae.v128; \ - X##se = GET64HIHI(X##sae.v128, X##sae.v128); \ - XOReq128(Cae, X##sae.v128); \ - X##sio.v128 = LOAD128(state[22]); \ - X##si = X##sio.v128; \ - X##so = GET64HIHI(X##sio.v128, X##sio.v128); \ - XOReq128(Cio, X##sio.v128); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cu, X##su); \ - -#define copyFromStateAndXor1152bits(X, state, input) \ - X##bae.v128 = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae.v128; \ - X##be = GET64HIHI(X##bae.v128, X##bae.v128); \ - Cae = X##bae.v128; \ - X##bio.v128 = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio.v128; \ - X##bo = GET64HIHI(X##bio.v128, X##bio.v128); \ - Cio = X##bio.v128; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cu = X##bu; \ - X##gae.v128 = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae.v128; \ - X##ge = GET64HIHI(X##gae.v128, X##gae.v128); \ - X##bage.v128 = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae.v128); \ - X##gio.v128 = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio.v128; \ - X##begi.v128 = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio.v128, X##gio.v128); \ - XOReq128(Cio, X##gio.v128); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - XOReq64(Cu, X##gu); \ - X##kae.v128 = XOR128(LOAD128(state[10]), LOAD128u(input[10])); \ - X##ka = X##kae.v128; \ - X##ke = GET64HIHI(X##kae.v128, X##kae.v128); \ - XOReq128(Cae, X##kae.v128); \ - X##kio.v128 = XOR128(LOAD128(state[12]), LOAD128u(input[12])); \ - X##ki = X##kio.v128; \ - X##ko = GET64HIHI(X##kio.v128, X##kio.v128); \ - XOReq128(Cio, X##kio.v128); \ - X##ku = XOR64(LOAD64(state[14]), LOAD64(input[14])); \ - XOReq64(Cu, X##ku); \ - X##mae.v128 = XOR128(LOAD128u(state[15]), LOAD128u(input[15])); \ - X##ma = X##mae.v128; \ - X##me = GET64HIHI(X##mae.v128, X##mae.v128); \ - X##kame.v128 = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, X##mae.v128); \ - X##mio.v128 = XOR128(LOAD128u(state[17]), LOAD64(input[17])); \ - X##mi = X##mio.v128; \ - X##kemi.v128 = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio.v128, X##mio.v128); \ - XOReq128(Cio, X##mio.v128); \ - X##mu = LOAD64(state[19]); \ - XOReq64(Cu, X##mu); \ - X##sae.v128 = LOAD128(state[20]); \ - X##sa = X##sae.v128; \ - X##se = GET64HIHI(X##sae.v128, X##sae.v128); \ - XOReq128(Cae, X##sae.v128); \ - X##sio.v128 = LOAD128(state[22]); \ - X##si = X##sio.v128; \ - X##so = GET64HIHI(X##sio.v128, X##sio.v128); \ - XOReq128(Cio, X##sio.v128); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cu, X##su); \ - -#define copyFromStateAndXor1344bits(X, state, input) \ - X##bae.v128 = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae.v128; \ - X##be = GET64HIHI(X##bae.v128, X##bae.v128); \ - Cae = X##bae.v128; \ - X##bio.v128 = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio.v128; \ - X##bo = GET64HIHI(X##bio.v128, X##bio.v128); \ - Cio = X##bio.v128; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cu = X##bu; \ - X##gae.v128 = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae.v128; \ - X##ge = GET64HIHI(X##gae.v128, X##gae.v128); \ - X##bage.v128 = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae.v128); \ - X##gio.v128 = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio.v128; \ - X##begi.v128 = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio.v128, X##gio.v128); \ - XOReq128(Cio, X##gio.v128); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - XOReq64(Cu, X##gu); \ - X##kae.v128 = XOR128(LOAD128(state[10]), LOAD128u(input[10])); \ - X##ka = X##kae.v128; \ - X##ke = GET64HIHI(X##kae.v128, X##kae.v128); \ - XOReq128(Cae, X##kae.v128); \ - X##kio.v128 = XOR128(LOAD128(state[12]), LOAD128u(input[12])); \ - X##ki = X##kio.v128; \ - X##ko = GET64HIHI(X##kio.v128, X##kio.v128); \ - XOReq128(Cio, X##kio.v128); \ - X##ku = XOR64(LOAD64(state[14]), LOAD64(input[14])); \ - XOReq64(Cu, X##ku); \ - X##mae.v128 = XOR128(LOAD128u(state[15]), LOAD128u(input[15])); \ - X##ma = X##mae.v128; \ - X##me = GET64HIHI(X##mae.v128, X##mae.v128); \ - X##kame.v128 = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, X##mae.v128); \ - X##mio.v128 = XOR128(LOAD128u(state[17]), LOAD128u(input[17])); \ - X##mi = X##mio.v128; \ - X##kemi.v128 = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio.v128, X##mio.v128); \ - XOReq128(Cio, X##mio.v128); \ - X##mu = XOR64(LOAD64(state[19]), LOAD64(input[19])); \ - XOReq64(Cu, X##mu); \ - X##sae.v128 = XOR128(LOAD128(state[20]), LOAD64(input[20])); \ - X##sa = X##sae.v128; \ - X##se = GET64HIHI(X##sae.v128, X##sae.v128); \ - XOReq128(Cae, X##sae.v128); \ - X##sio.v128 = LOAD128(state[22]); \ - X##si = X##sio.v128; \ - X##so = GET64HIHI(X##sio.v128, X##sio.v128); \ - XOReq128(Cio, X##sio.v128); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cu, X##su); \ - -#define copyFromState(X, state) \ - X##bae.v128 = LOAD128(state[ 0]); \ - X##ba = X##bae.v128; \ - X##be = GET64HIHI(X##bae.v128, X##bae.v128); \ - Cae = X##bae.v128; \ - X##bio.v128 = LOAD128(state[ 2]); \ - X##bi = X##bio.v128; \ - X##bo = GET64HIHI(X##bio.v128, X##bio.v128); \ - Cio = X##bio.v128; \ - X##bu = LOAD64(state[ 4]); \ - Cu = X##bu; \ - X##gae.v128 = LOAD128u(state[ 5]); \ - X##ga = X##gae.v128; \ - X##ge = GET64HIHI(X##gae.v128, X##gae.v128); \ - X##bage.v128 = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae.v128); \ - X##gio.v128 = LOAD128u(state[ 7]); \ - X##gi = X##gio.v128; \ - X##begi.v128 = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio.v128, X##gio.v128); \ - XOReq128(Cio, X##gio.v128); \ - X##gu = LOAD64(state[ 9]); \ - XOReq64(Cu, X##gu); \ - X##kae.v128 = LOAD128(state[10]); \ - X##ka = X##kae.v128; \ - X##ke = GET64HIHI(X##kae.v128, X##kae.v128); \ - XOReq128(Cae, X##kae.v128); \ - X##kio.v128 = LOAD128(state[12]); \ - X##ki = X##kio.v128; \ - X##ko = GET64HIHI(X##kio.v128, X##kio.v128); \ - XOReq128(Cio, X##kio.v128); \ - X##ku = LOAD64(state[14]); \ - XOReq64(Cu, X##ku); \ - X##mae.v128 = LOAD128u(state[15]); \ - X##ma = X##mae.v128; \ - X##me = GET64HIHI(X##mae.v128, X##mae.v128); \ - X##kame.v128 = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, X##mae.v128); \ - X##mio.v128 = LOAD128u(state[17]); \ - X##mi = X##mio.v128; \ - X##kemi.v128 = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio.v128, X##mio.v128); \ - XOReq128(Cio, X##mio.v128); \ - X##mu = LOAD64(state[19]); \ - XOReq64(Cu, X##mu); \ - X##sae.v128 = LOAD128(state[20]); \ - X##sa = X##sae.v128; \ - X##se = GET64HIHI(X##sae.v128, X##sae.v128); \ - XOReq128(Cae, X##sae.v128); \ - X##sio.v128 = LOAD128(state[22]); \ - X##si = X##sio.v128; \ - X##so = GET64HIHI(X##sio.v128, X##sio.v128); \ - XOReq128(Cio, X##sio.v128); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cu, X##su); \ - -#define copyToState(state, X) \ - state[ 0] = A##bage.v64[0]; \ - state[ 1] = A##begi.v64[0]; \ - STORE64(state[ 2], X##bi); \ - STORE64(state[ 3], X##bo); \ - STORE64(state[ 4], X##bu); \ - STORE64(state[ 5], X##ga); \ - state[ 6] = A##bage.v64[1]; \ - state[ 7] = A##begi.v64[1]; \ - STORE64(state[ 8], X##go); \ - STORE64(state[ 9], X##gu); \ - state[10] = X##kame.v64[0]; \ - state[11] = X##kemi.v64[0]; \ - STORE64(state[12], X##ki); \ - STORE64(state[13], X##ko); \ - STORE64(state[14], X##ku); \ - STORE64(state[15], X##ma); \ - state[16] = X##kame.v64[1]; \ - state[17] = X##kemi.v64[1]; \ - STORE64(state[18], X##mo); \ - STORE64(state[19], X##mu); \ - STORE64(state[20], X##sa); \ - STORE64(state[21], X##se); \ - STORE64(state[22], X##si); \ - STORE64(state[23], X##so); \ - STORE64(state[24], X##su); \ - -#define copyStateVariables(X, Y) \ - X##bage = Y##bage; \ - X##begi = Y##begi; \ - X##bi = Y##bi; \ - X##bo = Y##bo; \ - X##bu = Y##bu; \ - X##ga = Y##ga; \ - X##go = Y##go; \ - X##gu = Y##gu; \ - X##kame = Y##kame; \ - X##kemi = Y##kemi; \ - X##ki = Y##ki; \ - X##ko = Y##ko; \ - X##ku = Y##ku; \ - X##ma = Y##ma; \ - 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; \ - diff --git a/Modules/_sha3/keccak/KeccakF-1600-simd64.macros b/Modules/_sha3/keccak/KeccakF-1600-simd64.macros deleted file mode 100644 index 06a30e2ae060..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-simd64.macros +++ /dev/null @@ -1,517 +0,0 @@ -/* -Code automatically generated by KeccakTools! - -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -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 \ - V64 Aba, Abe, Abi, Abo, Abu; \ - V64 Aga, Age, Agi, Ago, Agu; \ - V64 Aka, Ake, Aki, Ako, Aku; \ - V64 Ama, Ame, Ami, Amo, Amu; \ - V64 Asa, Ase, Asi, Aso, Asu; \ - V64 Bba, Bbe, Bbi, Bbo, Bbu; \ - V64 Bga, Bge, Bgi, Bgo, Bgu; \ - V64 Bka, Bke, Bki, Bko, Bku; \ - V64 Bma, Bme, Bmi, Bmo, Bmu; \ - V64 Bsa, Bse, Bsi, Bso, Bsu; \ - V64 Ca, Ce, Ci, Co, Cu; \ - V64 Da, De, Di, Do, Du; \ - V64 Eba, Ebe, Ebi, Ebo, Ebu; \ - V64 Ega, Ege, Egi, Ego, Egu; \ - V64 Eka, Eke, Eki, Eko, Eku; \ - V64 Ema, Eme, Emi, Emo, Emu; \ - V64 Esa, Ese, Esi, Eso, Esu; \ - -#define prepareTheta \ - Ca = XOR64(Aba, XOR64(Aga, XOR64(Aka, XOR64(Ama, Asa)))); \ - Ce = XOR64(Abe, XOR64(Age, XOR64(Ake, XOR64(Ame, Ase)))); \ - Ci = XOR64(Abi, XOR64(Agi, XOR64(Aki, XOR64(Ami, Asi)))); \ - Co = XOR64(Abo, XOR64(Ago, XOR64(Ako, XOR64(Amo, Aso)))); \ - Cu = XOR64(Abu, XOR64(Agu, XOR64(Aku, XOR64(Amu, Asu)))); \ - -/* --- Code for round, with prepare-theta */ -/* --- 64-bit lanes mapped to 64-bit words */ -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - Da = XOR64(Cu, ROL64(Ce, 1)); \ - De = XOR64(Ca, ROL64(Ci, 1)); \ - Di = XOR64(Ce, ROL64(Co, 1)); \ - Do = XOR64(Ci, ROL64(Cu, 1)); \ - Du = XOR64(Co, ROL64(Ca, 1)); \ -\ - XOReq64(A##ba, Da); \ - Bba = A##ba; \ - XOReq64(A##ge, De); \ - Bbe = ROL64(A##ge, 44); \ - XOReq64(A##ki, Di); \ - Bbi = ROL64(A##ki, 43); \ - E##ba = XOR64(Bba, ANDnu64(Bbe, Bbi)); \ - XOReq64(E##ba, CONST64(KeccakF1600RoundConstants[i])); \ - Ca = E##ba; \ - XOReq64(A##mo, Do); \ - Bbo = ROL64(A##mo, 21); \ - E##be = XOR64(Bbe, ANDnu64(Bbi, Bbo)); \ - Ce = E##be; \ - XOReq64(A##su, Du); \ - Bbu = ROL64(A##su, 14); \ - E##bi = XOR64(Bbi, ANDnu64(Bbo, Bbu)); \ - Ci = E##bi; \ - E##bo = XOR64(Bbo, ANDnu64(Bbu, Bba)); \ - Co = E##bo; \ - E##bu = XOR64(Bbu, ANDnu64(Bba, Bbe)); \ - Cu = E##bu; \ -\ - XOReq64(A##bo, Do); \ - Bga = ROL64(A##bo, 28); \ - XOReq64(A##gu, Du); \ - Bge = ROL64(A##gu, 20); \ - XOReq64(A##ka, Da); \ - Bgi = ROL64(A##ka, 3); \ - E##ga = XOR64(Bga, ANDnu64(Bge, Bgi)); \ - XOReq64(Ca, E##ga); \ - XOReq64(A##me, De); \ - Bgo = ROL64(A##me, 45); \ - E##ge = XOR64(Bge, ANDnu64(Bgi, Bgo)); \ - XOReq64(Ce, E##ge); \ - XOReq64(A##si, Di); \ - Bgu = ROL64(A##si, 61); \ - E##gi = XOR64(Bgi, ANDnu64(Bgo, Bgu)); \ - XOReq64(Ci, E##gi); \ - E##go = XOR64(Bgo, ANDnu64(Bgu, Bga)); \ - XOReq64(Co, E##go); \ - E##gu = XOR64(Bgu, ANDnu64(Bga, Bge)); \ - XOReq64(Cu, E##gu); \ -\ - XOReq64(A##be, De); \ - Bka = ROL64(A##be, 1); \ - XOReq64(A##gi, Di); \ - Bke = ROL64(A##gi, 6); \ - XOReq64(A##ko, Do); \ - Bki = ROL64(A##ko, 25); \ - E##ka = XOR64(Bka, ANDnu64(Bke, Bki)); \ - XOReq64(Ca, E##ka); \ - XOReq64(A##mu, Du); \ - Bko = ROL64(A##mu, 8); \ - E##ke = XOR64(Bke, ANDnu64(Bki, Bko)); \ - XOReq64(Ce, E##ke); \ - XOReq64(A##sa, Da); \ - Bku = ROL64(A##sa, 18); \ - E##ki = XOR64(Bki, ANDnu64(Bko, Bku)); \ - XOReq64(Ci, E##ki); \ - E##ko = XOR64(Bko, ANDnu64(Bku, Bka)); \ - XOReq64(Co, E##ko); \ - E##ku = XOR64(Bku, ANDnu64(Bka, Bke)); \ - XOReq64(Cu, E##ku); \ -\ - XOReq64(A##bu, Du); \ - Bma = ROL64(A##bu, 27); \ - XOReq64(A##ga, Da); \ - Bme = ROL64(A##ga, 36); \ - XOReq64(A##ke, De); \ - Bmi = ROL64(A##ke, 10); \ - E##ma = XOR64(Bma, ANDnu64(Bme, Bmi)); \ - XOReq64(Ca, E##ma); \ - XOReq64(A##mi, Di); \ - Bmo = ROL64(A##mi, 15); \ - E##me = XOR64(Bme, ANDnu64(Bmi, Bmo)); \ - XOReq64(Ce, E##me); \ - XOReq64(A##so, Do); \ - Bmu = ROL64(A##so, 56); \ - E##mi = XOR64(Bmi, ANDnu64(Bmo, Bmu)); \ - XOReq64(Ci, E##mi); \ - E##mo = XOR64(Bmo, ANDnu64(Bmu, Bma)); \ - XOReq64(Co, E##mo); \ - E##mu = XOR64(Bmu, ANDnu64(Bma, Bme)); \ - XOReq64(Cu, E##mu); \ -\ - XOReq64(A##bi, Di); \ - Bsa = ROL64(A##bi, 62); \ - XOReq64(A##go, Do); \ - Bse = ROL64(A##go, 55); \ - XOReq64(A##ku, Du); \ - Bsi = ROL64(A##ku, 39); \ - E##sa = XOR64(Bsa, ANDnu64(Bse, Bsi)); \ - XOReq64(Ca, E##sa); \ - XOReq64(A##ma, Da); \ - Bso = ROL64(A##ma, 41); \ - E##se = XOR64(Bse, ANDnu64(Bsi, Bso)); \ - XOReq64(Ce, E##se); \ - XOReq64(A##se, De); \ - Bsu = ROL64(A##se, 2); \ - E##si = XOR64(Bsi, ANDnu64(Bso, Bsu)); \ - XOReq64(Ci, E##si); \ - E##so = XOR64(Bso, ANDnu64(Bsu, Bsa)); \ - XOReq64(Co, E##so); \ - E##su = XOR64(Bsu, ANDnu64(Bsa, Bse)); \ - XOReq64(Cu, E##su); \ -\ - -/* --- Code for round */ -/* --- 64-bit lanes mapped to 64-bit words */ -#define thetaRhoPiChiIota(i, A, E) \ - Da = XOR64(Cu, ROL64(Ce, 1)); \ - De = XOR64(Ca, ROL64(Ci, 1)); \ - Di = XOR64(Ce, ROL64(Co, 1)); \ - Do = XOR64(Ci, ROL64(Cu, 1)); \ - Du = XOR64(Co, ROL64(Ca, 1)); \ -\ - XOReq64(A##ba, Da); \ - Bba = A##ba; \ - XOReq64(A##ge, De); \ - Bbe = ROL64(A##ge, 44); \ - XOReq64(A##ki, Di); \ - Bbi = ROL64(A##ki, 43); \ - E##ba = XOR64(Bba, ANDnu64(Bbe, Bbi)); \ - XOReq64(E##ba, CONST64(KeccakF1600RoundConstants[i])); \ - XOReq64(A##mo, Do); \ - Bbo = ROL64(A##mo, 21); \ - E##be = XOR64(Bbe, ANDnu64(Bbi, Bbo)); \ - XOReq64(A##su, Du); \ - Bbu = ROL64(A##su, 14); \ - E##bi = XOR64(Bbi, ANDnu64(Bbo, Bbu)); \ - E##bo = XOR64(Bbo, ANDnu64(Bbu, Bba)); \ - E##bu = XOR64(Bbu, ANDnu64(Bba, Bbe)); \ -\ - XOReq64(A##bo, Do); \ - Bga = ROL64(A##bo, 28); \ - XOReq64(A##gu, Du); \ - Bge = ROL64(A##gu, 20); \ - XOReq64(A##ka, Da); \ - Bgi = ROL64(A##ka, 3); \ - E##ga = XOR64(Bga, ANDnu64(Bge, Bgi)); \ - XOReq64(A##me, De); \ - Bgo = ROL64(A##me, 45); \ - E##ge = XOR64(Bge, ANDnu64(Bgi, Bgo)); \ - XOReq64(A##si, Di); \ - Bgu = ROL64(A##si, 61); \ - E##gi = XOR64(Bgi, ANDnu64(Bgo, Bgu)); \ - E##go = XOR64(Bgo, ANDnu64(Bgu, Bga)); \ - E##gu = XOR64(Bgu, ANDnu64(Bga, Bge)); \ -\ - XOReq64(A##be, De); \ - Bka = ROL64(A##be, 1); \ - XOReq64(A##gi, Di); \ - Bke = ROL64(A##gi, 6); \ - XOReq64(A##ko, Do); \ - Bki = ROL64(A##ko, 25); \ - E##ka = XOR64(Bka, ANDnu64(Bke, Bki)); \ - XOReq64(A##mu, Du); \ - Bko = ROL64(A##mu, 8); \ - E##ke = XOR64(Bke, ANDnu64(Bki, Bko)); \ - XOReq64(A##sa, Da); \ - Bku = ROL64(A##sa, 18); \ - E##ki = XOR64(Bki, ANDnu64(Bko, Bku)); \ - E##ko = XOR64(Bko, ANDnu64(Bku, Bka)); \ - E##ku = XOR64(Bku, ANDnu64(Bka, Bke)); \ -\ - XOReq64(A##bu, Du); \ - Bma = ROL64(A##bu, 27); \ - XOReq64(A##ga, Da); \ - Bme = ROL64(A##ga, 36); \ - XOReq64(A##ke, De); \ - Bmi = ROL64(A##ke, 10); \ - E##ma = XOR64(Bma, ANDnu64(Bme, Bmi)); \ - XOReq64(A##mi, Di); \ - Bmo = ROL64(A##mi, 15); \ - E##me = XOR64(Bme, ANDnu64(Bmi, Bmo)); \ - XOReq64(A##so, Do); \ - Bmu = ROL64(A##so, 56); \ - E##mi = XOR64(Bmi, ANDnu64(Bmo, Bmu)); \ - E##mo = XOR64(Bmo, ANDnu64(Bmu, Bma)); \ - E##mu = XOR64(Bmu, ANDnu64(Bma, Bme)); \ -\ - XOReq64(A##bi, Di); \ - Bsa = ROL64(A##bi, 62); \ - XOReq64(A##go, Do); \ - Bse = ROL64(A##go, 55); \ - XOReq64(A##ku, Du); \ - Bsi = ROL64(A##ku, 39); \ - E##sa = XOR64(Bsa, ANDnu64(Bse, Bsi)); \ - XOReq64(A##ma, Da); \ - Bso = ROL64(A##ma, 41); \ - E##se = XOR64(Bse, ANDnu64(Bsi, Bso)); \ - XOReq64(A##se, De); \ - Bsu = ROL64(A##se, 2); \ - E##si = XOR64(Bsi, ANDnu64(Bso, Bsu)); \ - E##so = XOR64(Bso, ANDnu64(Bsu, Bsa)); \ - E##su = XOR64(Bsu, ANDnu64(Bsa, Bse)); \ -\ - -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 }; - -#define copyFromStateAndXor576bits(X, state, input) \ - X##ba = XOR64(LOAD64(state[ 0]), LOAD64(input[ 0])); \ - X##be = XOR64(LOAD64(state[ 1]), LOAD64(input[ 1])); \ - X##bi = XOR64(LOAD64(state[ 2]), LOAD64(input[ 2])); \ - X##bo = XOR64(LOAD64(state[ 3]), LOAD64(input[ 3])); \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - X##ga = XOR64(LOAD64(state[ 5]), LOAD64(input[ 5])); \ - X##ge = XOR64(LOAD64(state[ 6]), LOAD64(input[ 6])); \ - X##gi = XOR64(LOAD64(state[ 7]), LOAD64(input[ 7])); \ - X##go = XOR64(LOAD64(state[ 8]), LOAD64(input[ 8])); \ - X##gu = LOAD64(state[ 9]); \ - X##ka = LOAD64(state[10]); \ - X##ke = LOAD64(state[11]); \ - X##ki = LOAD64(state[12]); \ - X##ko = LOAD64(state[13]); \ - X##ku = LOAD64(state[14]); \ - X##ma = LOAD64(state[15]); \ - X##me = LOAD64(state[16]); \ - X##mi = LOAD64(state[17]); \ - X##mo = LOAD64(state[18]); \ - X##mu = LOAD64(state[19]); \ - X##sa = LOAD64(state[20]); \ - X##se = LOAD64(state[21]); \ - X##si = LOAD64(state[22]); \ - X##so = LOAD64(state[23]); \ - X##su = LOAD64(state[24]); \ - -#define copyFromStateAndXor832bits(X, state, input) \ - X##ba = XOR64(LOAD64(state[ 0]), LOAD64(input[ 0])); \ - X##be = XOR64(LOAD64(state[ 1]), LOAD64(input[ 1])); \ - X##bi = XOR64(LOAD64(state[ 2]), LOAD64(input[ 2])); \ - X##bo = XOR64(LOAD64(state[ 3]), LOAD64(input[ 3])); \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - X##ga = XOR64(LOAD64(state[ 5]), LOAD64(input[ 5])); \ - X##ge = XOR64(LOAD64(state[ 6]), LOAD64(input[ 6])); \ - X##gi = XOR64(LOAD64(state[ 7]), LOAD64(input[ 7])); \ - X##go = XOR64(LOAD64(state[ 8]), LOAD64(input[ 8])); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - X##ka = XOR64(LOAD64(state[10]), LOAD64(input[10])); \ - X##ke = XOR64(LOAD64(state[11]), LOAD64(input[11])); \ - X##ki = XOR64(LOAD64(state[12]), LOAD64(input[12])); \ - X##ko = LOAD64(state[13]); \ - X##ku = LOAD64(state[14]); \ - X##ma = LOAD64(state[15]); \ - X##me = LOAD64(state[16]); \ - X##mi = LOAD64(state[17]); \ - X##mo = LOAD64(state[18]); \ - X##mu = LOAD64(state[19]); \ - X##sa = LOAD64(state[20]); \ - X##se = LOAD64(state[21]); \ - X##si = LOAD64(state[22]); \ - X##so = LOAD64(state[23]); \ - X##su = LOAD64(state[24]); \ - -#define copyFromStateAndXor1024bits(X, state, input) \ - X##ba = XOR64(LOAD64(state[ 0]), LOAD64(input[ 0])); \ - X##be = XOR64(LOAD64(state[ 1]), LOAD64(input[ 1])); \ - X##bi = XOR64(LOAD64(state[ 2]), LOAD64(input[ 2])); \ - X##bo = XOR64(LOAD64(state[ 3]), LOAD64(input[ 3])); \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - X##ga = XOR64(LOAD64(state[ 5]), LOAD64(input[ 5])); \ - X##ge = XOR64(LOAD64(state[ 6]), LOAD64(input[ 6])); \ - X##gi = XOR64(LOAD64(state[ 7]), LOAD64(input[ 7])); \ - X##go = XOR64(LOAD64(state[ 8]), LOAD64(input[ 8])); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - X##ka = XOR64(LOAD64(state[10]), LOAD64(input[10])); \ - X##ke = XOR64(LOAD64(state[11]), LOAD64(input[11])); \ - X##ki = XOR64(LOAD64(state[12]), LOAD64(input[12])); \ - X##ko = XOR64(LOAD64(state[13]), LOAD64(input[13])); \ - X##ku = XOR64(LOAD64(state[14]), LOAD64(input[14])); \ - X##ma = XOR64(LOAD64(state[15]), LOAD64(input[15])); \ - X##me = LOAD64(state[16]); \ - X##mi = LOAD64(state[17]); \ - X##mo = LOAD64(state[18]); \ - X##mu = LOAD64(state[19]); \ - X##sa = LOAD64(state[20]); \ - X##se = LOAD64(state[21]); \ - X##si = LOAD64(state[22]); \ - X##so = LOAD64(state[23]); \ - X##su = LOAD64(state[24]); \ - -#define copyFromStateAndXor1088bits(X, state, input) \ - X##ba = XOR64(LOAD64(state[ 0]), LOAD64(input[ 0])); \ - X##be = XOR64(LOAD64(state[ 1]), LOAD64(input[ 1])); \ - X##bi = XOR64(LOAD64(state[ 2]), LOAD64(input[ 2])); \ - X##bo = XOR64(LOAD64(state[ 3]), LOAD64(input[ 3])); \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - X##ga = XOR64(LOAD64(state[ 5]), LOAD64(input[ 5])); \ - X##ge = XOR64(LOAD64(state[ 6]), LOAD64(input[ 6])); \ - X##gi = XOR64(LOAD64(state[ 7]), LOAD64(input[ 7])); \ - X##go = XOR64(LOAD64(state[ 8]), LOAD64(input[ 8])); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - X##ka = XOR64(LOAD64(state[10]), LOAD64(input[10])); \ - X##ke = XOR64(LOAD64(state[11]), LOAD64(input[11])); \ - X##ki = XOR64(LOAD64(state[12]), LOAD64(input[12])); \ - X##ko = XOR64(LOAD64(state[13]), LOAD64(input[13])); \ - X##ku = XOR64(LOAD64(state[14]), LOAD64(input[14])); \ - X##ma = XOR64(LOAD64(state[15]), LOAD64(input[15])); \ - X##me = XOR64(LOAD64(state[16]), LOAD64(input[16])); \ - X##mi = LOAD64(state[17]); \ - X##mo = LOAD64(state[18]); \ - X##mu = LOAD64(state[19]); \ - X##sa = LOAD64(state[20]); \ - X##se = LOAD64(state[21]); \ - X##si = LOAD64(state[22]); \ - X##so = LOAD64(state[23]); \ - X##su = LOAD64(state[24]); \ - -#define copyFromStateAndXor1152bits(X, state, input) \ - X##ba = XOR64(LOAD64(state[ 0]), LOAD64(input[ 0])); \ - X##be = XOR64(LOAD64(state[ 1]), LOAD64(input[ 1])); \ - X##bi = XOR64(LOAD64(state[ 2]), LOAD64(input[ 2])); \ - X##bo = XOR64(LOAD64(state[ 3]), LOAD64(input[ 3])); \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - X##ga = XOR64(LOAD64(state[ 5]), LOAD64(input[ 5])); \ - X##ge = XOR64(LOAD64(state[ 6]), LOAD64(input[ 6])); \ - X##gi = XOR64(LOAD64(state[ 7]), LOAD64(input[ 7])); \ - X##go = XOR64(LOAD64(state[ 8]), LOAD64(input[ 8])); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - X##ka = XOR64(LOAD64(state[10]), LOAD64(input[10])); \ - X##ke = XOR64(LOAD64(state[11]), LOAD64(input[11])); \ - X##ki = XOR64(LOAD64(state[12]), LOAD64(input[12])); \ - X##ko = XOR64(LOAD64(state[13]), LOAD64(input[13])); \ - X##ku = XOR64(LOAD64(state[14]), LOAD64(input[14])); \ - X##ma = XOR64(LOAD64(state[15]), LOAD64(input[15])); \ - X##me = XOR64(LOAD64(state[16]), LOAD64(input[16])); \ - X##mi = XOR64(LOAD64(state[17]), LOAD64(input[17])); \ - X##mo = LOAD64(state[18]); \ - X##mu = LOAD64(state[19]); \ - X##sa = LOAD64(state[20]); \ - X##se = LOAD64(state[21]); \ - X##si = LOAD64(state[22]); \ - X##so = LOAD64(state[23]); \ - X##su = LOAD64(state[24]); \ - -#define copyFromStateAndXor1344bits(X, state, input) \ - X##ba = XOR64(LOAD64(state[ 0]), LOAD64(input[ 0])); \ - X##be = XOR64(LOAD64(state[ 1]), LOAD64(input[ 1])); \ - X##bi = XOR64(LOAD64(state[ 2]), LOAD64(input[ 2])); \ - X##bo = XOR64(LOAD64(state[ 3]), LOAD64(input[ 3])); \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - X##ga = XOR64(LOAD64(state[ 5]), LOAD64(input[ 5])); \ - X##ge = XOR64(LOAD64(state[ 6]), LOAD64(input[ 6])); \ - X##gi = XOR64(LOAD64(state[ 7]), LOAD64(input[ 7])); \ - X##go = XOR64(LOAD64(state[ 8]), LOAD64(input[ 8])); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - X##ka = XOR64(LOAD64(state[10]), LOAD64(input[10])); \ - X##ke = XOR64(LOAD64(state[11]), LOAD64(input[11])); \ - X##ki = XOR64(LOAD64(state[12]), LOAD64(input[12])); \ - X##ko = XOR64(LOAD64(state[13]), LOAD64(input[13])); \ - X##ku = XOR64(LOAD64(state[14]), LOAD64(input[14])); \ - X##ma = XOR64(LOAD64(state[15]), LOAD64(input[15])); \ - X##me = XOR64(LOAD64(state[16]), LOAD64(input[16])); \ - X##mi = XOR64(LOAD64(state[17]), LOAD64(input[17])); \ - X##mo = XOR64(LOAD64(state[18]), LOAD64(input[18])); \ - X##mu = XOR64(LOAD64(state[19]), LOAD64(input[19])); \ - X##sa = XOR64(LOAD64(state[20]), LOAD64(input[20])); \ - X##se = LOAD64(state[21]); \ - X##si = LOAD64(state[22]); \ - X##so = LOAD64(state[23]); \ - X##su = LOAD64(state[24]); \ - -#define copyFromState(X, state) \ - X##ba = LOAD64(state[ 0]); \ - X##be = LOAD64(state[ 1]); \ - X##bi = LOAD64(state[ 2]); \ - X##bo = LOAD64(state[ 3]); \ - X##bu = LOAD64(state[ 4]); \ - X##ga = LOAD64(state[ 5]); \ - X##ge = LOAD64(state[ 6]); \ - X##gi = LOAD64(state[ 7]); \ - X##go = LOAD64(state[ 8]); \ - X##gu = LOAD64(state[ 9]); \ - X##ka = LOAD64(state[10]); \ - X##ke = LOAD64(state[11]); \ - X##ki = LOAD64(state[12]); \ - X##ko = LOAD64(state[13]); \ - X##ku = LOAD64(state[14]); \ - X##ma = LOAD64(state[15]); \ - X##me = LOAD64(state[16]); \ - X##mi = LOAD64(state[17]); \ - X##mo = LOAD64(state[18]); \ - X##mu = LOAD64(state[19]); \ - X##sa = LOAD64(state[20]); \ - X##se = LOAD64(state[21]); \ - X##si = LOAD64(state[22]); \ - X##so = LOAD64(state[23]); \ - X##su = LOAD64(state[24]); \ - -#define copyToState(state, X) \ - STORE64(state[ 0], X##ba); \ - STORE64(state[ 1], X##be); \ - STORE64(state[ 2], X##bi); \ - STORE64(state[ 3], X##bo); \ - STORE64(state[ 4], X##bu); \ - STORE64(state[ 5], X##ga); \ - STORE64(state[ 6], X##ge); \ - STORE64(state[ 7], X##gi); \ - STORE64(state[ 8], X##go); \ - STORE64(state[ 9], X##gu); \ - STORE64(state[10], X##ka); \ - STORE64(state[11], X##ke); \ - STORE64(state[12], X##ki); \ - STORE64(state[13], X##ko); \ - STORE64(state[14], X##ku); \ - STORE64(state[15], X##ma); \ - STORE64(state[16], X##me); \ - STORE64(state[17], X##mi); \ - STORE64(state[18], X##mo); \ - STORE64(state[19], X##mu); \ - STORE64(state[20], X##sa); \ - STORE64(state[21], X##se); \ - STORE64(state[22], X##si); \ - STORE64(state[23], X##so); \ - STORE64(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; \ - diff --git a/Modules/_sha3/keccak/KeccakF-1600-unrolling.macros b/Modules/_sha3/keccak/KeccakF-1600-unrolling.macros deleted file mode 100644 index 83c694ca4893..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-unrolling.macros +++ /dev/null @@ -1,124 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -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 (Unrolling == 24) -#define rounds \ - 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) \ - copyToState(state, A) -#elif (Unrolling == 12) -#define rounds \ - 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) \ - } \ - copyToState(state, A) -#elif (Unrolling == 8) -#define rounds \ - prepareTheta \ - for(i=0; i<24; i+=8) { \ - 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) \ - } \ - copyToState(state, A) -#elif (Unrolling == 6) -#define rounds \ - 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) \ - } \ - copyToState(state, A) -#elif (Unrolling == 4) -#define rounds \ - 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) \ - } \ - copyToState(state, A) -#elif (Unrolling == 3) -#define rounds \ - 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) \ - } \ - copyToState(state, A) -#elif (Unrolling == 2) -#define rounds \ - prepareTheta \ - for(i=0; i<24; i+=2) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ - } \ - copyToState(state, A) -#elif (Unrolling == 1) -#define rounds \ - prepareTheta \ - for(i=0; i<24; i++) { \ - thetaRhoPiChiIotaPrepareTheta(i , A, E) \ - copyStateVariables(A, E) \ - } \ - copyToState(state, A) -#else -#error "Unrolling is not correctly specified!" -#endif diff --git a/Modules/_sha3/keccak/KeccakF-1600-xop.macros b/Modules/_sha3/keccak/KeccakF-1600-xop.macros deleted file mode 100644 index 823c946fff4e..000000000000 --- a/Modules/_sha3/keccak/KeccakF-1600-xop.macros +++ /dev/null @@ -1,573 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -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 \ - V128 Abage, Abegi, Abigo, Abogu, Abuga; \ - V128 Akame, Akemi, Akimo, Akomu, Akuma; \ - V128 Abae, Abio, Agae, Agio, Akae, Akio, Amae, Amio; \ - V64 Aba, Abe, Abi, Abo, Abu; \ - V64 Aga, Age, Agi, Ago, Agu; \ - V64 Aka, Ake, Aki, Ako, Aku; \ - V64 Ama, Ame, Ami, Amo, Amu; \ - V128 Asase, Asiso; \ - V64 Asu; \ - V128 Bbage, Bbegi, Bbigo, Bbogu, Bbuga; \ - V128 Bkame, Bkemi, Bkimo, Bkomu, Bkuma; \ - V128 Bsase, Bsesi, Bsiso, Bsosu, Bsusa; \ - V128 Cae, Cei, Cio, Cou, Cua; \ - V128 Dau, Dea, Die, Doi, Duo; \ - V128 Dua, Dae, Dei, Dio, Dou; \ - V128 Ebage, Ebegi, Ebigo, Ebogu, Ebuga; \ - V128 Ekame, Ekemi, Ekimo, Ekomu, Ekuma; \ - V128 Esase, Esiso; \ - V64 Esu; \ - V128 Zero; - -#define prepareTheta - -#define computeD \ - Cua = GET64LOLO(Cua, Cae); \ - Dei = XOR128(Cae, ROL6464same(Cio, 1)); \ - Dou = XOR128(Cio, ROL6464same(Cua, 1)); \ - Cei = GET64HILO(Cae, Cio); \ - Dae = XOR128(Cua, ROL6464same(Cei, 1)); \ - Dau = GET64LOHI(Dae, Dou); \ - Dea = SWAP64(Dae); \ - Die = SWAP64(Dei); \ - Doi = GET64LOLO(Dou, Die); \ - Duo = SWAP64(Dou); - -/* --- Theta Rho Pi Chi Iota Prepare-theta */ -/* --- 64-bit lanes mapped to 64-bit and 128-bit words */ -#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ - computeD \ - \ - Bbage = XOR128(GET64LOHI(A##bage, A##bogu), Dau); \ - Bbage = ROL6464(Bbage, 0, 20); \ - Bbegi = XOR128(GET64HILO(A##bage, A##kame), Dea); \ - Bbegi = ROL6464(Bbegi, 44, 3); \ - Bbigo = XOR128(GET64LOHI(A##kimo, A##kame), Die); \ - Bbigo = ROL6464(Bbigo, 43, 45); \ - E##bage = XOR128(Bbage, ANDnu128(Bbegi, Bbigo)); \ - XOReq128(E##bage, CONST64(KeccakF1600RoundConstants[i])); \ - Cae = E##bage; \ - Bbogu = XOR128(GET64HILO(A##kimo, A##siso), Doi); \ - Bbogu = ROL6464(Bbogu, 21, 61); \ - E##begi = XOR128(Bbegi, ANDnu128(Bbigo, Bbogu)); \ - Cei = E##begi; \ - Bbuga = XOR128(GET64LOLO(A##su, A##bogu), Duo); \ - Bbuga = ROL6464(Bbuga, 14, 28); \ - E##bigo = XOR128(Bbigo, ANDnu128(Bbogu, Bbuga)); \ - Cio = E##bigo; \ - E##bogu = XOR128(Bbogu, ANDnu128(Bbuga, Bbage)); \ - Cou = E##bogu; \ - E##buga = XOR128(Bbuga, ANDnu128(Bbage, Bbegi)); \ - Cua = E##buga; \ -\ - Bkame = XOR128(GET64LOHI(A##begi, A##buga), Dea); \ - Bkame = ROL6464(Bkame, 1, 36); \ - Bkemi = XOR128(GET64HILO(A##begi, A##kemi), Die); \ - Bkemi = ROL6464(Bkemi, 6, 10); \ - Bkimo = XOR128(GET64LOHI(A##komu, A##kemi), Doi); \ - Bkimo = ROL6464(Bkimo, 25, 15); \ - E##kame = XOR128(Bkame, ANDnu128(Bkemi, Bkimo)); \ - XOReq128(Cae, E##kame); \ - Bkomu = XOR128(GET64HIHI(A##komu, A##siso), Duo); \ - Bkomu = ROL6464(Bkomu, 8, 56); \ - E##kemi = XOR128(Bkemi, ANDnu128(Bkimo, Bkomu)); \ - XOReq128(Cei, E##kemi); \ - Bkuma = XOR128(GET64LOLO(A##sase, A##buga), Dau); \ - Bkuma = ROL6464(Bkuma, 18, 27); \ - E##kimo = XOR128(Bkimo, ANDnu128(Bkomu, Bkuma)); \ - XOReq128(Cio, E##kimo); \ - E##komu = XOR128(Bkomu, ANDnu128(Bkuma, Bkame)); \ - XOReq128(Cou, E##komu); \ - E##kuma = XOR128(Bkuma, ANDnu128(Bkame, Bkemi)); \ - XOReq128(Cua, E##kuma); \ -\ - Bsase = XOR128(A##bigo, SWAP64(Doi)); \ - Bsase = ROL6464(Bsase, 62, 55); \ - Bsiso = XOR128(A##kuma, SWAP64(Dau)); \ - Bsiso = ROL6464(Bsiso, 39, 41); \ - Bsusa = XOR64(COPY64HI2LO(A##sase), Dei); \ - Bsusa = ROL6464same(Bsusa, 2); \ - Bsusa = GET64LOLO(Bsusa, Bsase); \ - Bsesi = GET64HILO(Bsase, Bsiso); \ - Bsosu = GET64HILO(Bsiso, Bsusa); \ - E##sase = XOR128(Bsase, ANDnu128(Bsesi, Bsiso)); \ - XOReq128(Cae, E##sase); \ - E##siso = XOR128(Bsiso, ANDnu128(Bsosu, Bsusa)); \ - XOReq128(Cio, E##siso); \ - E##su = GET64LOLO(XOR128(Bsusa, ANDnu128(Bsase, Bsesi)), Zero); \ - XOReq128(Cua, E##su); \ -\ - Zero = ZERO128(); \ - XOReq128(Cae, GET64HIHI(Cua, Zero)); \ - XOReq128(Cae, GET64LOLO(Zero, Cei)); \ - XOReq128(Cio, GET64HIHI(Cei, Zero)); \ - XOReq128(Cio, GET64LOLO(Zero, Cou)); \ - XOReq128(Cua, GET64HIHI(Cou, Zero)); \ - -/* --- Theta Rho Pi Chi Iota */ -/* --- 64-bit lanes mapped to 64-bit and 128-bit words */ -#define thetaRhoPiChiIota(i, A, E) thetaRhoPiChiIotaPrepareTheta(i, A, E) - -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 }; - -#define copyFromStateAndXor576bits(X, state, input) \ - X##bae = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae; \ - X##be = GET64HIHI(X##bae, X##bae); \ - Cae = X##bae; \ - X##bio = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio; \ - X##bo = GET64HIHI(X##bio, X##bio); \ - Cio = X##bio; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cua = X##bu; \ - X##gae = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae; \ - X##buga = GET64LOLO(X##bu, X##ga); \ - X##ge = GET64HIHI(X##gae, X##gae); \ - X##bage = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae); \ - X##gio = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio; \ - X##begi = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio, X##gio); \ - X##bigo = GET64LOLO(X##bi, X##go); \ - XOReq128(Cio, X##gio); \ - X##gu = LOAD64(state[ 9]); \ - X##bogu = GET64LOLO(X##bo, X##gu); \ - XOReq64(Cua, X##gu); \ - X##kae = LOAD128(state[10]); \ - X##ka = X##kae; \ - X##ke = GET64HIHI(X##kae, X##kae); \ - XOReq128(Cae, X##kae); \ - X##kio = LOAD128(state[12]); \ - X##ki = X##kio; \ - X##ko = GET64HIHI(X##kio, X##kio); \ - XOReq128(Cio, X##kio); \ - X##kuma = LOAD128(state[14]); \ - XOReq64(Cua, X##kuma); \ - X##me = LOAD64(state[16]); \ - X##kame = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, GET64HIHI(X##kuma, X##kame)); \ - X##mio = LOAD128u(state[17]); \ - X##mi = X##mio; \ - X##kemi = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio, X##mio); \ - X##kimo = GET64LOLO(X##ki, X##mo); \ - XOReq128(Cio, X##mio); \ - X##mu = LOAD64(state[19]); \ - X##komu = GET64LOLO(X##ko, X##mu); \ - XOReq64(Cua, X##mu); \ - X##sase = LOAD128(state[20]); \ - XOReq128(Cae, X##sase); \ - X##siso = LOAD128(state[22]); \ - XOReq128(Cio, X##siso); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cua, X##su); \ - -#define copyFromStateAndXor832bits(X, state, input) \ - X##bae = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae; \ - X##be = GET64HIHI(X##bae, X##bae); \ - Cae = X##bae; \ - X##bio = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio; \ - X##bo = GET64HIHI(X##bio, X##bio); \ - Cio = X##bio; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cua = X##bu; \ - X##gae = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae; \ - X##buga = GET64LOLO(X##bu, X##ga); \ - X##ge = GET64HIHI(X##gae, X##gae); \ - X##bage = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae); \ - X##gio = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio; \ - X##begi = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio, X##gio); \ - X##bigo = GET64LOLO(X##bi, X##go); \ - XOReq128(Cio, X##gio); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - X##bogu = GET64LOLO(X##bo, X##gu); \ - XOReq64(Cua, X##gu); \ - X##kae = XOR128(LOAD128(state[10]), LOAD128u(input[10])); \ - X##ka = X##kae; \ - X##ke = GET64HIHI(X##kae, X##kae); \ - XOReq128(Cae, X##kae); \ - X##kio = XOR128(LOAD128(state[12]), LOAD64(input[12])); \ - X##ki = X##kio; \ - X##ko = GET64HIHI(X##kio, X##kio); \ - XOReq128(Cio, X##kio); \ - X##kuma = LOAD128(state[14]); \ - XOReq64(Cua, X##kuma); \ - X##me = LOAD64(state[16]); \ - X##kame = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, GET64HIHI(X##kuma, X##kame)); \ - X##mio = LOAD128u(state[17]); \ - X##mi = X##mio; \ - X##kemi = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio, X##mio); \ - X##kimo = GET64LOLO(X##ki, X##mo); \ - XOReq128(Cio, X##mio); \ - X##mu = LOAD64(state[19]); \ - X##komu = GET64LOLO(X##ko, X##mu); \ - XOReq64(Cua, X##mu); \ - X##sase = LOAD128(state[20]); \ - XOReq128(Cae, X##sase); \ - X##siso = LOAD128(state[22]); \ - XOReq128(Cio, X##siso); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cua, X##su); \ - -#define copyFromStateAndXor1024bits(X, state, input) \ - X##bae = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae; \ - X##be = GET64HIHI(X##bae, X##bae); \ - Cae = X##bae; \ - X##bio = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio; \ - X##bo = GET64HIHI(X##bio, X##bio); \ - Cio = X##bio; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cua = X##bu; \ - X##gae = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae; \ - X##buga = GET64LOLO(X##bu, X##ga); \ - X##ge = GET64HIHI(X##gae, X##gae); \ - X##bage = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae); \ - X##gio = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio; \ - X##begi = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio, X##gio); \ - X##bigo = GET64LOLO(X##bi, X##go); \ - XOReq128(Cio, X##gio); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - X##bogu = GET64LOLO(X##bo, X##gu); \ - XOReq64(Cua, X##gu); \ - X##kae = XOR128(LOAD128(state[10]), LOAD128u(input[10])); \ - X##ka = X##kae; \ - X##ke = GET64HIHI(X##kae, X##kae); \ - XOReq128(Cae, X##kae); \ - X##kio = XOR128(LOAD128(state[12]), LOAD128u(input[12])); \ - X##ki = X##kio; \ - X##ko = GET64HIHI(X##kio, X##kio); \ - XOReq128(Cio, X##kio); \ - X##kuma = XOR128(LOAD128(state[14]), LOAD128(input[14])); \ - XOReq64(Cua, X##kuma); \ - X##me = LOAD64(state[16]); \ - X##kame = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, GET64HIHI(X##kuma, X##kame)); \ - X##mio = LOAD128u(state[17]); \ - X##mi = X##mio; \ - X##kemi = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio, X##mio); \ - X##kimo = GET64LOLO(X##ki, X##mo); \ - XOReq128(Cio, X##mio); \ - X##mu = LOAD64(state[19]); \ - X##komu = GET64LOLO(X##ko, X##mu); \ - XOReq64(Cua, X##mu); \ - X##sase = LOAD128(state[20]); \ - XOReq128(Cae, X##sase); \ - X##siso = LOAD128(state[22]); \ - XOReq128(Cio, X##siso); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cua, X##su); \ - -#define copyFromStateAndXor1088bits(X, state, input) \ - X##bae = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae; \ - X##be = GET64HIHI(X##bae, X##bae); \ - Cae = X##bae; \ - X##bio = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio; \ - X##bo = GET64HIHI(X##bio, X##bio); \ - Cio = X##bio; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cua = X##bu; \ - X##gae = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae; \ - X##buga = GET64LOLO(X##bu, X##ga); \ - X##ge = GET64HIHI(X##gae, X##gae); \ - X##bage = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae); \ - X##gio = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio; \ - X##begi = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio, X##gio); \ - X##bigo = GET64LOLO(X##bi, X##go); \ - XOReq128(Cio, X##gio); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - X##bogu = GET64LOLO(X##bo, X##gu); \ - XOReq64(Cua, X##gu); \ - X##kae = XOR128(LOAD128(state[10]), LOAD128u(input[10])); \ - X##ka = X##kae; \ - X##ke = GET64HIHI(X##kae, X##kae); \ - XOReq128(Cae, X##kae); \ - X##kio = XOR128(LOAD128(state[12]), LOAD128u(input[12])); \ - X##ki = X##kio; \ - X##ko = GET64HIHI(X##kio, X##kio); \ - XOReq128(Cio, X##kio); \ - X##kuma = XOR128(LOAD128(state[14]), LOAD128(input[14])); \ - XOReq64(Cua, X##kuma); \ - X##me = XOR64(LOAD64(state[16]), LOAD64(input[16])); \ - X##kame = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, GET64HIHI(X##kuma, X##kame)); \ - X##mio = LOAD128u(state[17]); \ - X##mi = X##mio; \ - X##kemi = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio, X##mio); \ - X##kimo = GET64LOLO(X##ki, X##mo); \ - XOReq128(Cio, X##mio); \ - X##mu = LOAD64(state[19]); \ - X##komu = GET64LOLO(X##ko, X##mu); \ - XOReq64(Cua, X##mu); \ - X##sase = LOAD128(state[20]); \ - XOReq128(Cae, X##sase); \ - X##siso = LOAD128(state[22]); \ - XOReq128(Cio, X##siso); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cua, X##su); \ - -#define copyFromStateAndXor1152bits(X, state, input) \ - X##bae = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae; \ - X##be = GET64HIHI(X##bae, X##bae); \ - Cae = X##bae; \ - X##bio = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio; \ - X##bo = GET64HIHI(X##bio, X##bio); \ - Cio = X##bio; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cua = X##bu; \ - X##gae = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae; \ - X##buga = GET64LOLO(X##bu, X##ga); \ - X##ge = GET64HIHI(X##gae, X##gae); \ - X##bage = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae); \ - X##gio = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio; \ - X##begi = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio, X##gio); \ - X##bigo = GET64LOLO(X##bi, X##go); \ - XOReq128(Cio, X##gio); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - X##bogu = GET64LOLO(X##bo, X##gu); \ - XOReq64(Cua, X##gu); \ - X##kae = XOR128(LOAD128(state[10]), LOAD128u(input[10])); \ - X##ka = X##kae; \ - X##ke = GET64HIHI(X##kae, X##kae); \ - XOReq128(Cae, X##kae); \ - X##kio = XOR128(LOAD128(state[12]), LOAD128u(input[12])); \ - X##ki = X##kio; \ - X##ko = GET64HIHI(X##kio, X##kio); \ - XOReq128(Cio, X##kio); \ - X##kuma = XOR128(LOAD128(state[14]), LOAD128(input[14])); \ - XOReq64(Cua, X##kuma); \ - X##me = XOR64(LOAD64(state[16]), LOAD64(input[16])); \ - X##kame = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, GET64HIHI(X##kuma, X##kame)); \ - X##mio = XOR128(LOAD128u(state[17]), LOAD64(input[17])); \ - X##mi = X##mio; \ - X##kemi = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio, X##mio); \ - X##kimo = GET64LOLO(X##ki, X##mo); \ - XOReq128(Cio, X##mio); \ - X##mu = LOAD64(state[19]); \ - X##komu = GET64LOLO(X##ko, X##mu); \ - XOReq64(Cua, X##mu); \ - X##sase = LOAD128(state[20]); \ - XOReq128(Cae, X##sase); \ - X##siso = LOAD128(state[22]); \ - XOReq128(Cio, X##siso); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cua, X##su); \ - -#define copyFromStateAndXor1344bits(X, state, input) \ - X##bae = XOR128(LOAD128(state[ 0]), LOAD128u(input[ 0])); \ - X##ba = X##bae; \ - X##be = GET64HIHI(X##bae, X##bae); \ - Cae = X##bae; \ - X##bio = XOR128(LOAD128(state[ 2]), LOAD128u(input[ 2])); \ - X##bi = X##bio; \ - X##bo = GET64HIHI(X##bio, X##bio); \ - Cio = X##bio; \ - X##bu = XOR64(LOAD64(state[ 4]), LOAD64(input[ 4])); \ - Cua = X##bu; \ - X##gae = XOR128(LOAD128u(state[ 5]), LOAD128u(input[ 5])); \ - X##ga = X##gae; \ - X##buga = GET64LOLO(X##bu, X##ga); \ - X##ge = GET64HIHI(X##gae, X##gae); \ - X##bage = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae); \ - X##gio = XOR128(LOAD128u(state[ 7]), LOAD128u(input[ 7])); \ - X##gi = X##gio; \ - X##begi = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio, X##gio); \ - X##bigo = GET64LOLO(X##bi, X##go); \ - XOReq128(Cio, X##gio); \ - X##gu = XOR64(LOAD64(state[ 9]), LOAD64(input[ 9])); \ - X##bogu = GET64LOLO(X##bo, X##gu); \ - XOReq64(Cua, X##gu); \ - X##kae = XOR128(LOAD128(state[10]), LOAD128u(input[10])); \ - X##ka = X##kae; \ - X##ke = GET64HIHI(X##kae, X##kae); \ - XOReq128(Cae, X##kae); \ - X##kio = XOR128(LOAD128(state[12]), LOAD128u(input[12])); \ - X##ki = X##kio; \ - X##ko = GET64HIHI(X##kio, X##kio); \ - XOReq128(Cio, X##kio); \ - X##kuma = XOR128(LOAD128(state[14]), LOAD128(input[14])); \ - XOReq64(Cua, X##kuma); \ - X##me = XOR64(LOAD64(state[16]), LOAD64(input[16])); \ - X##kame = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, GET64HIHI(X##kuma, X##kame)); \ - X##mio = XOR128(LOAD128u(state[17]), LOAD128u(input[17])); \ - X##mi = X##mio; \ - X##kemi = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio, X##mio); \ - X##kimo = GET64LOLO(X##ki, X##mo); \ - XOReq128(Cio, X##mio); \ - X##mu = XOR64(LOAD64(state[19]), LOAD64(input[19])); \ - X##komu = GET64LOLO(X##ko, X##mu); \ - XOReq64(Cua, X##mu); \ - X##sase = XOR128(LOAD128(state[20]), LOAD64(input[20])); \ - XOReq128(Cae, X##sase); \ - X##siso = LOAD128(state[22]); \ - XOReq128(Cio, X##siso); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cua, X##su); \ - -#define copyFromState(X, state) \ - X##bae = LOAD128(state[ 0]); \ - X##ba = X##bae; \ - X##be = GET64HIHI(X##bae, X##bae); \ - Cae = X##bae; \ - X##bio = LOAD128(state[ 2]); \ - X##bi = X##bio; \ - X##bo = GET64HIHI(X##bio, X##bio); \ - Cio = X##bio; \ - X##bu = LOAD64(state[ 4]); \ - Cua = X##bu; \ - X##gae = LOAD128u(state[ 5]); \ - X##ga = X##gae; \ - X##buga = GET64LOLO(X##bu, X##ga); \ - X##ge = GET64HIHI(X##gae, X##gae); \ - X##bage = GET64LOLO(X##ba, X##ge); \ - XOReq128(Cae, X##gae); \ - X##gio = LOAD128u(state[ 7]); \ - X##gi = X##gio; \ - X##begi = GET64LOLO(X##be, X##gi); \ - X##go = GET64HIHI(X##gio, X##gio); \ - X##bigo = GET64LOLO(X##bi, X##go); \ - XOReq128(Cio, X##gio); \ - X##gu = LOAD64(state[ 9]); \ - X##bogu = GET64LOLO(X##bo, X##gu); \ - XOReq64(Cua, X##gu); \ - X##kae = LOAD128(state[10]); \ - X##ka = X##kae; \ - X##ke = GET64HIHI(X##kae, X##kae); \ - XOReq128(Cae, X##kae); \ - X##kio = LOAD128(state[12]); \ - X##ki = X##kio; \ - X##ko = GET64HIHI(X##kio, X##kio); \ - XOReq128(Cio, X##kio); \ - X##kuma = LOAD128(state[14]); \ - XOReq64(Cua, X##kuma); \ - X##me = LOAD64(state[16]); \ - X##kame = GET64LOLO(X##ka, X##me); \ - XOReq128(Cae, GET64HIHI(X##kuma, X##kame)); \ - X##mio = LOAD128u(state[17]); \ - X##mi = X##mio; \ - X##kemi = GET64LOLO(X##ke, X##mi); \ - X##mo = GET64HIHI(X##mio, X##mio); \ - X##kimo = GET64LOLO(X##ki, X##mo); \ - XOReq128(Cio, X##mio); \ - X##mu = LOAD64(state[19]); \ - X##komu = GET64LOLO(X##ko, X##mu); \ - XOReq64(Cua, X##mu); \ - X##sase = LOAD128(state[20]); \ - XOReq128(Cae, X##sase); \ - X##siso = LOAD128(state[22]); \ - XOReq128(Cio, X##siso); \ - X##su = LOAD64(state[24]); \ - XOReq64(Cua, X##su); \ - -#define copyToState(state, X) \ - STORE64(state[ 0], X##bage); \ - STORE64(state[ 1], X##begi); \ - STORE64(state[ 2], X##bigo); \ - STORE64(state[ 3], X##bogu); \ - STORE128(state[ 4], X##buga); \ - STORE64(state[ 6], COPY64HI2LO(X##bage)); \ - STORE64(state[ 7], COPY64HI2LO(X##begi)); \ - STORE64(state[ 8], COPY64HI2LO(X##bigo)); \ - STORE64(state[ 9], COPY64HI2LO(X##bogu)); \ - STORE64(state[10], X##kame); \ - STORE64(state[11], X##kemi); \ - STORE64(state[12], X##kimo); \ - STORE64(state[13], X##komu); \ - STORE128(state[14], X##kuma); \ - STORE64(state[16], COPY64HI2LO(X##kame)); \ - STORE64(state[17], COPY64HI2LO(X##kemi)); \ - STORE64(state[18], COPY64HI2LO(X##kimo)); \ - STORE64(state[19], COPY64HI2LO(X##komu)); \ - STORE128(state[20], X##sase); \ - STORE128(state[22], X##siso); \ - STORE64(state[24], X##su); \ - -#define copyStateVariables(X, Y) \ - X##bage = Y##bage; \ - X##begi = Y##begi; \ - X##bigo = Y##bigo; \ - X##bogu = Y##bogu; \ - X##buga = Y##buga; \ - X##kame = Y##kame; \ - X##kemi = Y##kemi; \ - X##kimo = Y##kimo; \ - X##komu = Y##komu; \ - X##kuma = Y##kuma; \ - X##sase = Y##sase; \ - X##siso = Y##siso; \ - X##su = Y##su; \ - diff --git a/Modules/_sha3/keccak/KeccakNISTInterface.c b/Modules/_sha3/keccak/KeccakNISTInterface.c deleted file mode 100644 index e94082bc24de..000000000000 --- a/Modules/_sha3/keccak/KeccakNISTInterface.c +++ /dev/null @@ -1,83 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -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 "KeccakNISTInterface.h" -#include "KeccakF-1600-interface.h" - -static HashReturn Init(hashState *state, int hashbitlen) -{ - switch(hashbitlen) { - case 0: /* Default parameters, arbitrary length output */ - InitSponge((spongeState*)state, 1024, 576); - break; - case 224: - InitSponge((spongeState*)state, 1152, 448); - break; - case 256: - InitSponge((spongeState*)state, 1088, 512); - break; - case 384: - InitSponge((spongeState*)state, 832, 768); - break; - case 512: - InitSponge((spongeState*)state, 576, 1024); - break; - default: - return BAD_HASHLEN; - } - state->fixedOutputLength = hashbitlen; - return SUCCESS; -} - -static HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen) -{ - if ((databitlen % 8) == 0) - return Absorb((spongeState*)state, data, databitlen); - else { - HashReturn ret = Absorb((spongeState*)state, data, databitlen - (databitlen % 8)); - if (ret == SUCCESS) { - unsigned char lastByte; - /* Align the last partial byte to the least significant bits */ - lastByte = data[databitlen/8] >> (8 - (databitlen % 8)); - return Absorb((spongeState*)state, &lastByte, databitlen % 8); - } - else - return ret; - } -} - -static HashReturn Final(hashState *state, BitSequence *hashval) -{ - return Squeeze(state, hashval, state->fixedOutputLength); -} - -/* -static HashReturn Hash(int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval) -{ - hashState state; - HashReturn result; - - if ((hashbitlen != 224) && (hashbitlen != 256) && (hashbitlen != 384) && (hashbitlen != 512)) - return BAD_HASHLEN; * Only the four fixed output lengths available through this API * - result = Init(&state, hashbitlen); - if (result != SUCCESS) - return result; - result = Update(&state, data, databitlen); - if (result != SUCCESS) - return result; - result = Final(&state, hashval); - return result; -} -*/ - diff --git a/Modules/_sha3/keccak/KeccakNISTInterface.h b/Modules/_sha3/keccak/KeccakNISTInterface.h deleted file mode 100644 index 244431b1eb84..000000000000 --- a/Modules/_sha3/keccak/KeccakNISTInterface.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -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 _KeccakNISTInterface_h_ -#define _KeccakNISTInterface_h_ - -#include "KeccakSponge.h" - -typedef unsigned char BitSequence; -typedef unsigned long long DataLength; -typedef enum { SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2 } HashReturn; - -typedef spongeState hashState; - -/** - * Function to initialize the state of the Keccak[r, c] sponge function. - * The rate r and capacity c values are determined from @a hashbitlen. - * @param state Pointer to the state of the sponge function to be initialized. - * @param hashbitlen The desired number of output bits, - * or 0 for Keccak[] with default parameters - * and arbitrarily-long output. - * @pre The value of hashbitlen must be one of 0, 224, 256, 384 and 512. - * @return SUCCESS if successful, BAD_HASHLEN if the value of hashbitlen is incorrect. - */ -static HashReturn Init(hashState *state, int hashbitlen); -/** - * Function to give input data for the sponge function to absorb. - * @param state Pointer to the state of the sponge function initialized by Init(). - * @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 most significant bits of the last byte. - * @param databitLen The number of input bits provided in the input data. - * @pre In the previous call to Absorb(), databitLen was a multiple of 8. - * @return SUCCESS if successful, FAIL otherwise. - */ -static HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen); -/** - * Function to squeeze output data from the sponge function. - * If @a hashbitlen was not 0 in the call to Init(), the number of output bits is equal to @a hashbitlen. - * If @a hashbitlen was 0 in the call to Init(), the output bits must be extracted using the Squeeze() 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. - */ -static HashReturn Final(hashState *state, BitSequence *hashval); -/** - * Function to compute a hash using the Keccak[r, c] sponge function. - * The rate r and capacity c values are determined from @a hashbitlen. - * @param hashbitlen The desired number of output bits. - * @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 most significant bits of the last byte. - * @param databitLen The number of input bits provided in the input data. - * @param hashval Pointer to the buffer where to store the output data. - * @pre The value of hashbitlen must be one of 224, 256, 384 and 512. - * @return SUCCESS if successful, BAD_HASHLEN if the value of hashbitlen is incorrect. - */ -/* -static HashReturn Hash(int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval); -*/ - -#endif diff --git a/Modules/_sha3/keccak/KeccakSponge.c b/Modules/_sha3/keccak/KeccakSponge.c deleted file mode 100644 index 1ca6bf00100e..000000000000 --- a/Modules/_sha3/keccak/KeccakSponge.c +++ /dev/null @@ -1,266 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -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 "KeccakSponge.h" -#include "KeccakF-1600-interface.h" -#ifdef KeccakReference -#include "displayIntermediateValues.h" -#endif - -static int InitSponge(spongeState *state, unsigned int rate, unsigned int capacity) -{ - if (rate+capacity != 1600) - return 1; - if ((rate <= 0) || (rate >= 1600) || ((rate % 64) != 0)) - return 1; - KeccakInitialize(); - state->rate = rate; - state->capacity = capacity; - state->fixedOutputLength = 0; - KeccakInitializeState(state->state); - memset(state->dataQueue, 0, KeccakMaximumRateInBytes); - state->bitsInQueue = 0; - state->squeezing = 0; - state->bitsAvailableForSqueezing = 0; - - return 0; -} - -static void AbsorbQueue(spongeState *state) -{ - /* state->bitsInQueue is assumed to be equal to state->rate */ - #ifdef KeccakReference - displayBytes(1, "Block to be absorbed", state->dataQueue, state->rate/8); - #endif -#ifdef ProvideFast576 - if (state->rate == 576) - KeccakAbsorb576bits(state->state, state->dataQueue); - else -#endif -#ifdef ProvideFast832 - if (state->rate == 832) - KeccakAbsorb832bits(state->state, state->dataQueue); - else -#endif -#ifdef ProvideFast1024 - if (state->rate == 1024) - KeccakAbsorb1024bits(state->state, state->dataQueue); - else -#endif -#ifdef ProvideFast1088 - if (state->rate == 1088) - KeccakAbsorb1088bits(state->state, state->dataQueue); - else -#endif -#ifdef ProvideFast1152 - if (state->rate == 1152) - KeccakAbsorb1152bits(state->state, state->dataQueue); - else -#endif -#ifdef ProvideFast1344 - if (state->rate == 1344) - KeccakAbsorb1344bits(state->state, state->dataQueue); - else -#endif - KeccakAbsorb(state->state, state->dataQueue, state->rate/64); - state->bitsInQueue = 0; -} - -static int Absorb(spongeState *state, const unsigned char *data, unsigned long long databitlen) -{ - unsigned long long i, j, wholeBlocks; - unsigned int partialBlock, partialByte; - const unsigned char *curData; - - if ((state->bitsInQueue % 8) != 0) - return 1; /* Only the last call may contain a partial byte */ - if (state->squeezing) - return 1; /* Too late for additional input */ - - i = 0; - while(i < databitlen) { - if ((state->bitsInQueue == 0) && (databitlen >= state->rate) && (i <= (databitlen-state->rate))) { - wholeBlocks = (databitlen-i)/state->rate; - curData = data+i/8; -#ifdef ProvideFast576 - if (state->rate == 576) { - for(j=0; jrate/8); - #endif - KeccakAbsorb576bits(state->state, curData); - } - } - else -#endif -#ifdef ProvideFast832 - if (state->rate == 832) { - for(j=0; jrate/8); - #endif - KeccakAbsorb832bits(state->state, curData); - } - } - else -#endif -#ifdef ProvideFast1024 - if (state->rate == 1024) { - for(j=0; jrate/8); - #endif - KeccakAbsorb1024bits(state->state, curData); - } - } - else -#endif -#ifdef ProvideFast1088 - if (state->rate == 1088) { - for(j=0; jrate/8); - #endif - KeccakAbsorb1088bits(state->state, curData); - } - } - else -#endif -#ifdef ProvideFast1152 - if (state->rate == 1152) { - for(j=0; jrate/8); - #endif - KeccakAbsorb1152bits(state->state, curData); - } - } - else -#endif -#ifdef ProvideFast1344 - if (state->rate == 1344) { - for(j=0; jrate/8); - #endif - KeccakAbsorb1344bits(state->state, curData); - } - } - else -#endif - { - for(j=0; jrate/8) { - #ifdef KeccakReference - displayBytes(1, "Block to be absorbed", curData, state->rate/8); - #endif - KeccakAbsorb(state->state, curData, state->rate/64); - } - } - i += wholeBlocks*state->rate; - } - else { - partialBlock = (unsigned int)(databitlen - i); - if (partialBlock+state->bitsInQueue > state->rate) - partialBlock = state->rate-state->bitsInQueue; - partialByte = partialBlock % 8; - partialBlock -= partialByte; - memcpy(state->dataQueue+state->bitsInQueue/8, data+i/8, partialBlock/8); - state->bitsInQueue += partialBlock; - i += partialBlock; - if (state->bitsInQueue == state->rate) - AbsorbQueue(state); - if (partialByte > 0) { - unsigned char mask = (1 << partialByte)-1; - state->dataQueue[state->bitsInQueue/8] = data[i/8] & mask; - state->bitsInQueue += partialByte; - i += partialByte; - } - } - } - return 0; -} - -static void PadAndSwitchToSqueezingPhase(spongeState *state) -{ - /* Note: the bits are numbered from 0=LSB to 7=MSB */ - if (state->bitsInQueue + 1 == state->rate) { - state->dataQueue[state->bitsInQueue/8 ] |= 1 << (state->bitsInQueue % 8); - AbsorbQueue(state); - memset(state->dataQueue, 0, state->rate/8); - } - else { - memset(state->dataQueue + (state->bitsInQueue+7)/8, 0, state->rate/8 - (state->bitsInQueue+7)/8); - state->dataQueue[state->bitsInQueue/8 ] |= 1 << (state->bitsInQueue % 8); - } - state->dataQueue[(state->rate-1)/8] |= 1 << ((state->rate-1) % 8); - AbsorbQueue(state); - - #ifdef KeccakReference - displayText(1, "--- Switching to squeezing phase ---"); - #endif -#ifdef ProvideFast1024 - if (state->rate == 1024) { - KeccakExtract1024bits(state->state, state->dataQueue); - state->bitsAvailableForSqueezing = 1024; - } - else -#endif - { - KeccakExtract(state->state, state->dataQueue, state->rate/64); - state->bitsAvailableForSqueezing = state->rate; - } - #ifdef KeccakReference - displayBytes(1, "Block available for squeezing", state->dataQueue, state->bitsAvailableForSqueezing/8); - #endif - state->squeezing = 1; -} - -static int Squeeze(spongeState *state, unsigned char *output, unsigned long long outputLength) -{ - unsigned long long i; - unsigned int partialBlock; - - if (!state->squeezing) - PadAndSwitchToSqueezingPhase(state); - if ((outputLength % 8) != 0) - return 1; /* Only multiple of 8 bits are allowed, truncation can be done at user level */ - - i = 0; - while(i < outputLength) { - if (state->bitsAvailableForSqueezing == 0) { - KeccakPermutation(state->state); -#ifdef ProvideFast1024 - if (state->rate == 1024) { - KeccakExtract1024bits(state->state, state->dataQueue); - state->bitsAvailableForSqueezing = 1024; - } - else -#endif - { - KeccakExtract(state->state, state->dataQueue, state->rate/64); - state->bitsAvailableForSqueezing = state->rate; - } - #ifdef KeccakReference - displayBytes(1, "Block available for squeezing", state->dataQueue, state->bitsAvailableForSqueezing/8); - #endif - } - partialBlock = state->bitsAvailableForSqueezing; - if ((unsigned long long)partialBlock > outputLength - i) - partialBlock = (unsigned int)(outputLength - i); - memcpy(output+i/8, state->dataQueue+(state->rate-state->bitsAvailableForSqueezing)/8, partialBlock/8); - state->bitsAvailableForSqueezing -= partialBlock; - i += partialBlock; - } - return 0; -} diff --git a/Modules/_sha3/keccak/KeccakSponge.h b/Modules/_sha3/keccak/KeccakSponge.h deleted file mode 100644 index a545cacb3035..000000000000 --- a/Modules/_sha3/keccak/KeccakSponge.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, -Michaël Peeters and Gilles Van Assche. For more information, feedback or -questions, please refer to our website: http://keccak.noekeon.org/ - -Implementation by the designers, -hereby denoted as "the implementer". - -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_ - -#define KeccakPermutationSize 1600 -#define KeccakPermutationSizeInBytes (KeccakPermutationSize/8) -#define KeccakMaximumRate 1536 -#define KeccakMaximumRateInBytes (KeccakMaximumRate/8) - -#if defined(__GNUC__) -#define ALIGN __attribute__ ((aligned(32))) -#elif defined(_MSC_VER) -#define ALIGN __declspec(align(32)) -#else -#define ALIGN -#endif - -ALIGN typedef struct spongeStateStruct { - ALIGN unsigned char state[KeccakPermutationSizeInBytes]; - ALIGN unsigned char dataQueue[KeccakMaximumRateInBytes]; - unsigned int rate; - unsigned int capacity; - unsigned int bitsInQueue; - unsigned int fixedOutputLength; - int squeezing; - unsigned int bitsAvailableForSqueezing; -} spongeState; - -/** - * Function to initialize the state of the Keccak[r, c] sponge function. - * The sponge function is set to the absorbing phase. - * @param state Pointer to the state of the sponge function 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=1600 and the rate a multiple of 64 bits in this implementation. - * @return Zero if successful, 1 otherwise. - */ -static int InitSponge(spongeState *state, unsigned int rate, unsigned int capacity); -/** - * Function to give input data for the sponge function to absorb. - * @param state Pointer to the state of the sponge function initialized by InitSponge(). - * @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. - * @param databitLen The number of input bits provided in the input data. - * @pre In the previous call to Absorb(), databitLen was a multiple of 8. - * @pre The sponge function must be in the absorbing phase, - * i.e., Squeeze() must not have been called before. - * @return Zero if successful, 1 otherwise. - */ -static int Absorb(spongeState *state, const unsigned char *data, unsigned long long databitlen); -/** - * 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. - * @param state Pointer to the state of the sponge function initialized by InitSponge(). - * @param output Pointer to the buffer where to store the output data. - * @param outputLength The number of output bits desired. - * It must be a multiple of 8. - * @return Zero if successful, 1 otherwise. - */ -static int Squeeze(spongeState *state, unsigned char *output, unsigned long long outputLength); - -#endif diff --git a/Modules/_sha3/keccak/brg_endian.h b/Modules/_sha3/keccak/brg_endian.h deleted file mode 100755 index 7226eb3bec51..000000000000 --- a/Modules/_sha3/keccak/brg_endian.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - --------------------------------------------------------------------------- - Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. - - LICENSE TERMS - - The redistribution and use of this software (with or without changes) - is allowed without the payment of fees or royalties provided that: - - 1. source code distributions include the above copyright notice, this - list of conditions and the following disclaimer; - - 2. binary distributions include the above copyright notice, this list - of conditions and the following disclaimer in their documentation; - - 3. the name of the copyright holder is not used to endorse products - built using this software without specific written permission. - - DISCLAIMER - - This software is provided 'as is' with no explicit or implied warranties - in respect of its properties, including, but not limited to, correctness - and/or fitness for purpose. - --------------------------------------------------------------------------- - Issue Date: 20/12/2007 - Changes for ARM 9/9/2010 -*/ - -#ifndef _BRG_ENDIAN_H -#define _BRG_ENDIAN_H - -#define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ -#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ - -#if 0 -/* Include files where endian defines and byteswap functions may reside */ -#if defined( __sun ) -# include -#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ ) -# include -#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \ - defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ ) -# include -#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ ) -# if !defined( __MINGW32__ ) && !defined( _AIX ) -# include -# if !defined( __BEOS__ ) -# include -# endif -# endif -#endif -#endif - -/* Now attempt to set the define for platform byte order using any */ -/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */ -/* seem to encompass most endian symbol definitions */ - -#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN ) -# if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -# elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -# endif -#elif defined( BIG_ENDIAN ) -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -#elif defined( LITTLE_ENDIAN ) -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -#endif - -#if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN ) -# if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -# elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -# endif -#elif defined( _BIG_ENDIAN ) -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -#elif defined( _LITTLE_ENDIAN ) -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -#endif - -#if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN ) -# if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -# elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -# endif -#elif defined( __BIG_ENDIAN ) -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -#elif defined( __LITTLE_ENDIAN ) -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -#endif - -#if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ ) -# if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__ -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -# elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__ -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -# endif -#elif defined( __BIG_ENDIAN__ ) -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -#elif defined( __LITTLE_ENDIAN__ ) -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -#endif - -/* if the platform byte order could not be determined, then try to */ -/* set this define using common machine defines */ -#if !defined(PLATFORM_BYTE_ORDER) - -#if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \ - defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \ - defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \ - defined( vax ) || defined( vms ) || defined( VMS ) || \ - defined( __VMS ) || defined( _M_X64 ) -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN - -#elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \ - defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \ - defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \ - defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \ - defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \ - defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \ - defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX ) -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN - -#elif defined(__arm__) -# ifdef __BIG_ENDIAN -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -# else -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -# endif -#elif 1 /* **** EDIT HERE IF NECESSARY **** */ -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -#elif 0 /* **** EDIT HERE IF NECESSARY **** */ -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -#else -# error Please edit lines 132 or 134 in brg_endian.h to set the platform byte order -#endif - -#endif - -#endif diff --git a/Modules/_sha3/keccak/crypto_hash.h b/Modules/_sha3/keccak/crypto_hash.h deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c deleted file mode 100644 index 71127d0b76c5..000000000000 --- a/Modules/_sha3/sha3module.c +++ /dev/null @@ -1,593 +0,0 @@ -/* 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 Christian Heimes (christian@python.org) - * Licensed to PSF under a Contributor Agreement. - * - */ - -#include "Python.h" -#include "../hashlib.h" - -/* ************************************************************************** - * SHA-3 (Keccak) - * - * The code is based on KeccakReferenceAndOptimized-3.2.zip from 29 May 2012. - * - * The reference implementation is altered in this points: - * - C++ comments are converted to ANSI C comments. - * - All functions and globals are declared static. - * - The typedef for UINT64 is commented out. - * - KeccakF-1600-opt[32|64]-settings.h are commented out - * - Some unused functions are commented out to silence compiler warnings. - * - * In order to avoid name clashes with other software I have to declare all - * Keccak functions and global data as static. The C code is directly - * included into this file in order to access the static functions. - * - * Keccak can be tuned with several paramenters. I try to explain all options - * as far as I understand them. The reference implementation also contains - * assembler code for ARM platforms (NEON instructions). - * - * Common - * ====== - * - * Options: - * UseBebigokimisa, Unrolling - * - * - Unrolling: loop unrolling (24, 12, 8, 6, 4, 3, 2, 1) - * - UseBebigokimisa: lane complementing - * - * 64bit platforms - * =============== - * - * Additional options: - * UseSSE, UseOnlySIMD64, UseMMX, UseXOP, UseSHLD - * - * Optimized instructions (disabled by default): - * - UseSSE: use Stream SIMD extensions - * o UseOnlySIMD64: limit to 64bit instructions, otherwise 128bit - * o w/o UseOnlySIMD64: requires compiler agument -mssse3 or -mtune - * - UseMMX: use 64bit MMX instructions - * - UseXOP: use AMD's eXtended Operations (128bit SSE extension) - * - * Other: - * - Unrolling: default 24 - * - UseBebigokimisa: default 1 - * - * When neither UseSSE, UseMMX nor UseXOP is configured, ROL64 (rotate left - * 64) is implemented as: - * - Windows: _rotl64() - * - UseSHLD: use shld (shift left) asm optimization - * - otherwise: shift and xor - * - * UseBebigokimisa can't be used in combination with UseSSE, UseMMX or - * UseXOP. UseOnlySIMD64 has no effect unless UseSSE is specified. - * - * Tests have shown that UseSSE + UseOnlySIMD64 is about three to four - * times SLOWER than UseBebigokimisa. UseSSE and UseMMX are about two times - * slower. (tested by CH and AP) - * - * 32bit platforms - * =============== - * - * Additional options: - * UseInterleaveTables, UseSchedule - * - * - Unrolling: default 2 - * - UseBebigokimisa: default n/a - * - UseSchedule: ???, (1, 2, 3; default 3) - * - UseInterleaveTables: use two 64k lookup tables for (de)interleaving - * default: n/a - * - * schedules: - * - 3: no UseBebigokimisa, Unrolling must be 2 - * - 2 + 1: ??? - * - * *************************************************************************/ - -#ifdef __sparc - /* opt64 uses un-aligned memory access that causes a BUS error with msg - * 'invalid address alignment' on SPARC. */ - #define KeccakOpt 32 -#elif SIZEOF_VOID_P == 8 && defined(PY_UINT64_T) - /* opt64 works only for 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 */ - #define Unrolling 24 - #define UseBebigokimisa - typedef PY_UINT64_T UINT64; -#elif KeccakOpt == 32 && defined(PY_UINT64_T) - /* 32bit platforms with unsigned int64 */ - #define Unrolling 2 - #define UseSchedule 3 - typedef PY_UINT64_T UINT64; -#else - /* 32 or 64bit platforms without unsigned int64 */ - #define Unrolling 2 - #define UseSchedule 3 - #define UseInterleaveTables -#endif - -/* replacement for brg_endian.h */ -#define IS_BIG_ENDIAN 4321 -#define IS_LITTLE_ENDIAN 1234 -#if PY_BIG_ENDIAN -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -#else -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -#endif - -/* inline all Keccak dependencies */ -#include "keccak/KeccakNISTInterface.h" -#include "keccak/KeccakNISTInterface.c" -#include "keccak/KeccakSponge.c" -#if KeccakOpt == 64 - #include "keccak/KeccakF-1600-opt64.c" -#elif KeccakOpt == 32 - #include "keccak/KeccakF-1600-opt32.c" -#endif - -/* #define SHA3_BLOCKSIZE 200 // 1600 bits */ -#define SHA3_MAX_DIGESTSIZE 64 /* 512 bits */ -#define SHA3_state hashState -#define SHA3_init Init -#define SHA3_process Update -#define SHA3_done Final -#define SHA3_copystate(dest, src) memcpy(&(dest), &(src), sizeof(SHA3_state)) -#define SHA3_clearstate(state) memset(&(state), 0, sizeof(SHA3_state)) - -/* The structure for storing SHA3 info */ - -typedef struct { - PyObject_HEAD - int hashbitlen; - SHA3_state hash_state; -#ifdef WITH_THREAD - PyThread_type_lock lock; -#endif - -} SHA3object; - -static PyTypeObject SHA3type; - - -static SHA3object * -newSHA3object(int hashbitlen) -{ - SHA3object *newobj; - - /* check hashbitlen */ - switch(hashbitlen) { - /* supported hash length */ - case 224: - break; - case 256: - break; - case 384: - break; - case 512: - break; - case 0: - /* arbitrarily-long output isn't supported by this module */ - default: - /* everything else is an error */ - PyErr_SetString(PyExc_ValueError, - "hashbitlen must be one of 224, 256, 384 or 512."); - return NULL; - } - newobj = (SHA3object *)PyObject_New(SHA3object, &SHA3type); - if (newobj == NULL) { - return NULL; - } - newobj->hashbitlen = hashbitlen; -#ifdef WITH_THREAD - newobj->lock = NULL; -#endif - return newobj; -} - - -/* Internal methods for a hash object */ - -static void -SHA3_dealloc(SHA3object *self) -{ - SHA3_clearstate(self->hash_state); -#ifdef WITH_THREAD - if (self->lock) { - PyThread_free_lock(self->lock); - } -#endif - PyObject_Del(self); -} - - -/* External methods for a hash object */ - -PyDoc_STRVAR(SHA3_copy__doc__, "Return a copy of the hash object."); - -static PyObject * -SHA3_copy(SHA3object *self, PyObject *unused) -{ - SHA3object *newobj; - - if ((newobj = newSHA3object(self->hashbitlen)) == NULL) { - return NULL; - } - ENTER_HASHLIB(self); - SHA3_copystate(newobj->hash_state, self->hash_state); - LEAVE_HASHLIB(self); - return (PyObject *)newobj; -} - - -PyDoc_STRVAR(SHA3_digest__doc__, -"Return the digest value as a string of binary data."); - -static PyObject * -SHA3_digest(SHA3object *self, PyObject *unused) -{ - unsigned char digest[SHA3_MAX_DIGESTSIZE]; - SHA3_state temp; - HashReturn res; - - ENTER_HASHLIB(self); - SHA3_copystate(temp, self->hash_state); - LEAVE_HASHLIB(self); - res = SHA3_done(&temp, digest); - SHA3_clearstate(temp); - if (res != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Final()"); - return NULL; - } - return PyBytes_FromStringAndSize((const char *)digest, - self->hashbitlen / 8); -} - - -PyDoc_STRVAR(SHA3_hexdigest__doc__, -"Return the digest value as a string of hexadecimal digits."); - -static PyObject * -SHA3_hexdigest(SHA3object *self, PyObject *unused) -{ - unsigned char digest[SHA3_MAX_DIGESTSIZE]; - SHA3_state temp; - HashReturn res; - PyObject *retval; - Py_UCS1 *hex_digest; - int digestlen, i, j; - - /* Get the raw (binary) digest value */ - ENTER_HASHLIB(self); - SHA3_copystate(temp, self->hash_state); - LEAVE_HASHLIB(self); - res = SHA3_done(&temp, digest); - SHA3_clearstate(temp); - if (res != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Final()"); - return NULL; - } - - /* Create a new string */ - digestlen = self->hashbitlen / 8; - retval = PyUnicode_New(digestlen * 2, 127); - if (!retval) - return NULL; - hex_digest = PyUnicode_1BYTE_DATA(retval); - - /* Make hex version of the digest */ - for(i=j=0; i < digestlen; i++) { - unsigned char c; - c = (digest[i] >> 4) & 0xf; - hex_digest[j++] = Py_hexdigits[c]; - c = (digest[i] & 0xf); - hex_digest[j++] = Py_hexdigits[c]; - } -#ifdef Py_DEBUG - assert(_PyUnicode_CheckConsistency(retval, 1)); -#endif - return retval; -} - -PyDoc_STRVAR(SHA3_update__doc__, -"Update this hash object's state with the provided string."); - -static PyObject * -SHA3_update(SHA3object *self, PyObject *args) -{ - PyObject *obj; - Py_buffer buf; - HashReturn res; - - if (!PyArg_ParseTuple(args, "O:update", &obj)) - return NULL; - - GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); - - /* add new data, the function takes the length in bits not bytes */ -#ifdef WITH_THREAD - 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); - } -#else - res = SHA3_process(&self->hash_state, buf.buf, buf.len * 8); -#endif - LEAVE_HASHLIB(self); - - if (res != SUCCESS) { - PyBuffer_Release(&buf); - PyErr_SetString(PyExc_RuntimeError, - "internal error in SHA3 Update()"); - return NULL; - } - - PyBuffer_Release(&buf); - Py_INCREF(Py_None); - return Py_None; -} - -static PyMethodDef SHA3_methods[] = { - {"copy", (PyCFunction)SHA3_copy, METH_NOARGS, - SHA3_copy__doc__}, - {"digest", (PyCFunction)SHA3_digest, METH_NOARGS, - SHA3_digest__doc__}, - {"hexdigest", (PyCFunction)SHA3_hexdigest, METH_NOARGS, - SHA3_hexdigest__doc__}, - {"update", (PyCFunction)SHA3_update, METH_VARARGS, - SHA3_update__doc__}, - {NULL, NULL} /* sentinel */ -}; - -static PyObject * -SHA3_get_block_size(SHA3object *self, void *closure) -{ - /* HMAC-SHA3 hasn't been specified yet and no official test vectors are - * available. Thus block_size returns NotImplemented to prevent people - * from using SHA3 with the hmac module. - */ - Py_RETURN_NOTIMPLEMENTED; -} - -static PyObject * -SHA3_get_name(SHA3object *self, void *closure) -{ - return PyUnicode_FromFormat("sha3_%i", self->hashbitlen); -} - -static PyObject * -SHA3_get_digest_size(SHA3object *self, void *closure) -{ - return PyLong_FromLong(self->hashbitlen / 8); -} - - -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}, - {NULL} /* Sentinel */ -}; - -static PyTypeObject SHA3type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_sha3.SHA3", /* tp_name */ - sizeof(SHA3object), /* tp_size */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)SHA3_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - 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 */ - SHA3_methods, /* tp_methods */ - NULL, /* tp_members */ - SHA3_getseters, /* tp_getset */ -}; - - -/* constructor helper */ -static PyObject * -SHA3_factory(PyObject *args, PyObject *kwdict, const char *fmt, - int hashbitlen) -{ - SHA3object *newobj = NULL; - static char *kwlist[] = {"string", NULL}; - PyObject *data_obj = NULL; - Py_buffer buf; - HashReturn res; - - if (!PyArg_ParseTupleAndKeywords(args, kwdict, fmt, kwlist, - &data_obj)) { - return NULL; - } - - if (data_obj) - GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf); - - if ((newobj = newSHA3object(hashbitlen)) == NULL) { - goto error; - } - - if (SHA3_init(&newobj->hash_state, hashbitlen) != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, - "internal error in SHA3 Update()"); - goto error; - } - - if (data_obj) { -#ifdef WITH_THREAD - 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(&newobj->hash_state, buf.buf, buf.len * 8); - Py_END_ALLOW_THREADS - } - else { - res = SHA3_process(&newobj->hash_state, buf.buf, buf.len * 8); - } -#else - res = SHA3_process(&newobj->hash_state, buf.buf, buf.len * 8); -#endif - if (res != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, - "internal error in SHA3 Update()"); - goto error; - } - PyBuffer_Release(&buf); - } - - return (PyObject *)newobj; - - error: - if (newobj) { - SHA3_dealloc(newobj); - } - if (data_obj) { - PyBuffer_Release(&buf); - } - return NULL; - -} - -PyDoc_STRVAR(sha3_224__doc__, -"sha3_224([string]) -> SHA3 object\n\ -\n\ -Return a new SHA3 hash object with a hashbit length of 28 bytes."); - -static PyObject * -sha3_224(PyObject *self, PyObject *args, PyObject *kwdict) -{ - return SHA3_factory(args, kwdict, "|O:sha3_224", 224); -} - - -PyDoc_STRVAR(sha3_256__doc__, -"sha3_256([string]) -> SHA3 object\n\ -\n\ -Return a new SHA3 hash object with a hashbit length of 32 bytes."); - -static PyObject * -sha3_256(PyObject *self, PyObject *args, PyObject *kwdict) -{ - return SHA3_factory(args, kwdict, "|O:sha3_256", 256); -} - -PyDoc_STRVAR(sha3_384__doc__, -"sha3_384([string]) -> SHA3 object\n\ -\n\ -Return a new SHA3 hash object with a hashbit length of 48 bytes."); - -static PyObject * -sha3_384(PyObject *self, PyObject *args, PyObject *kwdict) -{ - return SHA3_factory(args, kwdict, "|O:sha3_384", 384); -} - -PyDoc_STRVAR(sha3_512__doc__, -"sha3_512([string]) -> SHA3 object\n\ -\n\ -Return a new SHA3 hash object with a hashbit length of 64 bytes."); - -static PyObject * -sha3_512(PyObject *self, PyObject *args, PyObject *kwdict) -{ - return SHA3_factory(args, kwdict, "|O:sha3_512", 512); -} - - -/* List of functions exported by this module */ -static struct PyMethodDef SHA3_functions[] = { - {"sha3_224", (PyCFunction)sha3_224, METH_VARARGS|METH_KEYWORDS, - sha3_224__doc__}, - {"sha3_256", (PyCFunction)sha3_256, METH_VARARGS|METH_KEYWORDS, - sha3_256__doc__}, - {"sha3_384", (PyCFunction)sha3_384, METH_VARARGS|METH_KEYWORDS, - sha3_384__doc__}, - {"sha3_512", (PyCFunction)sha3_512, METH_VARARGS|METH_KEYWORDS, - sha3_512__doc__}, - {NULL, NULL} /* Sentinel */ -}; - - -/* Initialize this module. */ -static struct PyModuleDef _SHA3module = { - PyModuleDef_HEAD_INIT, - "_sha3", - NULL, - -1, - SHA3_functions, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__sha3(void) -{ - PyObject *m; - - Py_TYPE(&SHA3type) = &PyType_Type; - if (PyType_Ready(&SHA3type) < 0) { - return NULL; - } - - m = PyModule_Create(&_SHA3module); - if (m == NULL) - return NULL; - - Py_INCREF((PyObject *)&SHA3type); - PyModule_AddObject(m, "SHA3Type", (PyObject *)&SHA3type); - return m; -} diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 50c6f0a8d597..a08ebfe8c474 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -128,7 +128,10 @@ int pysqlite_connection_init(pysqlite_Connection* self, PyObject* args, PyObject Py_INCREF(isolation_level); } self->isolation_level = NULL; - pysqlite_connection_set_isolation_level(self, isolation_level); + if (pysqlite_connection_set_isolation_level(self, isolation_level) < 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); @@ -519,19 +522,20 @@ _pysqlite_set_result(sqlite3_context* context, PyObject* py_val) return -1; sqlite3_result_text(context, str, -1, SQLITE_TRANSIENT); } else if (PyObject_CheckBuffer(py_val)) { - const char* buffer; - Py_ssize_t buflen; - if (PyObject_AsCharBuffer(py_val, &buffer, &buflen) != 0) { + 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 (buflen > INT_MAX) { + if (view.len > INT_MAX) { PyErr_SetString(PyExc_OverflowError, "BLOB longer than INT_MAX bytes"); + PyBuffer_Release(&view); return -1; } - sqlite3_result_blob(context, buffer, (int)buflen, SQLITE_TRANSIENT); + sqlite3_result_blob(context, view.buf, (int)view.len, SQLITE_TRANSIENT); + PyBuffer_Release(&view); } else { return -1; } @@ -1237,6 +1241,9 @@ PyObject* pysqlite_connection_call(pysqlite_Connection* self, PyObject* args, Py return NULL; } + if (!_PyArg_NoKeywords(MODULE_NAME ".Connection()", kwargs)) + return NULL; + if (!PyArg_ParseTuple(args, "O", &sql)) return NULL; @@ -1258,7 +1265,8 @@ PyObject* pysqlite_connection_call(pysqlite_Connection* self, PyObject* args, Py 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) { - PyErr_SetString(pysqlite_Warning, "SQL is of wrong type. Must be string or unicode."); + 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); @@ -1282,7 +1290,7 @@ PyObject* pysqlite_connection_call(pysqlite_Connection* self, PyObject* args, Py return NULL; } -PyObject* pysqlite_connection_execute(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) +PyObject* pysqlite_connection_execute(pysqlite_Connection* self, PyObject* args) { PyObject* cursor = 0; PyObject* result = 0; @@ -1311,7 +1319,7 @@ PyObject* pysqlite_connection_execute(pysqlite_Connection* self, PyObject* args, return cursor; } -PyObject* pysqlite_connection_executemany(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) +PyObject* pysqlite_connection_executemany(pysqlite_Connection* self, PyObject* args) { PyObject* cursor = 0; PyObject* result = 0; @@ -1340,7 +1348,7 @@ PyObject* pysqlite_connection_executemany(pysqlite_Connection* self, PyObject* a return cursor; } -PyObject* pysqlite_connection_executescript(pysqlite_Connection* self, PyObject* args, PyObject* kwargs) +PyObject* pysqlite_connection_executescript(pysqlite_Connection* self, PyObject* args) { PyObject* cursor = 0; PyObject* result = 0; diff --git a/Modules/_sqlite/connection.h b/Modules/_sqlite/connection.h index 0c9734caf710..fbd906377952 100644 --- a/Modules/_sqlite/connection.h +++ b/Modules/_sqlite/connection.h @@ -52,7 +52,7 @@ typedef struct * first get called with count=0? */ double timeout_started; - /* None for autocommit, otherwise a PyString with the isolation level */ + /* None for autocommit, otherwise a PyUnicode with the isolation level */ PyObject* isolation_level; /* NULL for autocommit, otherwise a string with the BEGIN statement; will be diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 8d10890eb022..c1599c02df0a 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -46,7 +46,7 @@ static pysqlite_StatementKind detect_statement_type(const char* statement) dst = buf; *dst = 0; - while (Py_ISALPHA(*src) && dst - buf < sizeof(buf) - 2) { + while (Py_ISALPHA(*src) && (dst - buf) < ((Py_ssize_t)sizeof(buf) - 2)) { *dst++ = Py_TOLOWER(*src++); } @@ -229,8 +229,7 @@ int pysqlite_build_row_cast_map(pysqlite_Cursor* self) if (converter != Py_None) { Py_DECREF(converter); } - Py_XDECREF(self->row_cast_map); - self->row_cast_map = NULL; + Py_CLEAR(self->row_cast_map); return -1; } @@ -290,9 +289,8 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) Py_END_ALLOW_THREADS row = PyTuple_New(numcols); - if (!row) { + if (!row) return NULL; - } for (i = 0; i < numcols; i++) { if (self->connection->detect_types) { @@ -312,14 +310,12 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) converted = Py_None; } else { item = PyBytes_FromStringAndSize(val_str, nbytes); - if (!item) { - return NULL; - } + if (!item) + goto error; converted = PyObject_CallFunction(converter, "O", item); Py_DECREF(item); - if (!converted) { + if (!converted) break; - } } } else { Py_BEGIN_ALLOW_THREADS @@ -338,11 +334,7 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) if (self->connection->text_factory == (PyObject*)&PyUnicode_Type) { converted = PyUnicode_FromStringAndSize(val_str, nbytes); if (!converted) { -#ifdef Py_DEBUG - /* in debug mode, type_call() fails with an assertion - error if an exception is set when it is called */ PyErr_Clear(); -#endif colname = sqlite3_column_name(self->statement->st, i); if (!colname) { colname = ""; @@ -375,9 +367,8 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) nbytes = sqlite3_column_bytes(self->statement->st, i); buffer = PyBytes_FromStringAndSize( sqlite3_column_blob(self->statement->st, i), nbytes); - if (!buffer) { + if (!buffer) break; - } converted = buffer; } } @@ -390,12 +381,14 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) } } - if (PyErr_Occurred()) { - Py_DECREF(row); - row = NULL; - } + if (PyErr_Occurred()) + goto error; return row; + +error: + Py_DECREF(row); + return NULL; } /* @@ -447,8 +440,7 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* self->locked = 1; self->reset = 0; - Py_XDECREF(self->next_row); - self->next_row = NULL; + Py_CLEAR(self->next_row); if (multiple) { /* executemany() */ @@ -614,6 +606,10 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* while (1) { /* Actually execute the SQL statement. */ rc = pysqlite_step(self->statement->st, self->connection); + if (PyErr_Occurred()) { + (void)pysqlite_statement_reset(self->statement); + goto error; + } if (rc == SQLITE_DONE || rc == SQLITE_ROW) { /* If it worked, let's get out of the loop */ break; @@ -687,6 +683,8 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* } 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); @@ -809,7 +807,10 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args) rc = SQLITE_ROW; while (rc == SQLITE_ROW) { rc = pysqlite_step(statement, self->connection); - /* TODO: we probably need more error handling here */ + if (PyErr_Occurred()) { + (void)sqlite3_finalize(statement); + goto error; + } } if (rc != SQLITE_DONE) { @@ -864,8 +865,7 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self) if (!self->next_row) { if (self->statement) { (void)pysqlite_statement_reset(self->statement); - Py_DECREF(self->statement); - self->statement = NULL; + Py_CLEAR(self->statement); } return NULL; } @@ -887,6 +887,11 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self) 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); @@ -898,8 +903,6 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self) self->next_row = _pysqlite_fetch_one_row(self); if (self->next_row == NULL) { (void)pysqlite_statement_reset(self->statement); - Py_DECREF(next_row); - _pysqlite_seterror(self->connection->db, NULL); return NULL; } } diff --git a/Modules/_sqlite/microprotocols.h b/Modules/_sqlite/microprotocols.h index 3a9944fc7947..6941716c4cf7 100644 --- a/Modules/_sqlite/microprotocols.h +++ b/Modules/_sqlite/microprotocols.h @@ -48,7 +48,7 @@ extern PyObject *pysqlite_microprotocols_adapt( PyObject *obj, PyObject *proto, PyObject *alt); extern PyObject * - pysqlite_adapt(pysqlite_Cursor* self, PyObject *args); + pysqlite_adapt(pysqlite_Cursor* self, PyObject *args); #define pysqlite_adapt_doc \ "adapt(obj, protocol, alternate) -> adapt obj to given protocol. Non-standard." diff --git a/Modules/_sqlite/row.c b/Modules/_sqlite/row.c index 4a87a048fd2b..07584e30e5ff 100644 --- a/Modules/_sqlite/row.c +++ b/Modules/_sqlite/row.c @@ -32,40 +32,53 @@ void pysqlite_row_dealloc(pysqlite_Row* self) Py_TYPE(self)->tp_free((PyObject*)self); } -int pysqlite_row_init(pysqlite_Row* self, PyObject* args, PyObject* kwargs) +static PyObject * +pysqlite_row_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { + pysqlite_Row *self; PyObject* data; pysqlite_Cursor* cursor; - self->data = 0; - self->description = 0; + assert(type != NULL && type->tp_alloc != NULL); - if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) { - return -1; - } + if (!_PyArg_NoKeywords("Row()", kwargs)) + return NULL; + if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) + return NULL; - if (!PyObject_IsInstance((PyObject*)cursor, (PyObject*)&pysqlite_CursorType)) { + if (!PyObject_TypeCheck((PyObject*)cursor, &pysqlite_CursorType)) { PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument"); - return -1; + return NULL; } if (!PyTuple_Check(data)) { PyErr_SetString(PyExc_TypeError, "tuple required for second argument"); - return -1; + 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 0; + 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; } PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx) { - long _idx; + Py_ssize_t _idx; char* key; Py_ssize_t nitems, i; char* compare_key; @@ -76,7 +89,11 @@ PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx) PyObject* item; if (PyLong_Check(idx)) { - _idx = PyLong_AsLong(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; @@ -125,8 +142,7 @@ PyObject* pysqlite_row_subscript(pysqlite_Row* self, PyObject* idx) return NULL; } else if (PySlice_Check(idx)) { - PyErr_SetString(PyExc_ValueError, "slices not implemented, yet"); - return NULL; + return PyObject_GetItem(self->data, idx); } else { PyErr_SetString(PyExc_IndexError, "Index must be int or string"); @@ -142,7 +158,7 @@ Py_ssize_t pysqlite_row_length(pysqlite_Row* self, PyObject* args, PyObject* kwa PyObject* pysqlite_row_keys(pysqlite_Row* self, PyObject* args, PyObject* kwargs) { PyObject* list; - int nitems, i; + Py_ssize_t nitems, i; list = PyList_New(0); if (!list) { @@ -198,6 +214,14 @@ PyMappingMethods pysqlite_row_as_mapping = { /* 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.")}, @@ -241,7 +265,7 @@ PyTypeObject pysqlite_RowType = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - (initproc)pysqlite_row_init, /* tp_init */ + 0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0 /* tp_free */ @@ -249,7 +273,8 @@ PyTypeObject pysqlite_RowType = { extern int pysqlite_row_setup_types(void) { - pysqlite_RowType.tp_new = PyType_GenericNew; + 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/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index 66b4a5256524..e87063341db6 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -63,6 +63,10 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con 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); @@ -90,7 +94,6 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter) { int rc = SQLITE_OK; - const char* buffer; char* string; Py_ssize_t buflen; parameter_type paramtype; @@ -141,18 +144,22 @@ int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObjec } rc = sqlite3_bind_text(self->st, pos, string, (int)buflen, SQLITE_TRANSIENT); break; - case TYPE_BUFFER: - if (PyObject_AsCharBuffer(parameter, &buffer, &buflen) != 0) { + 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 (buflen > INT_MAX) { + 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, buffer, buflen, SQLITE_TRANSIENT); + rc = sqlite3_bind_blob(self->st, pos, view.buf, (int)view.len, SQLITE_TRANSIENT); + PyBuffer_Release(&view); break; + } case TYPE_UNKNOWN: rc = -1; } diff --git a/Modules/_sre.c b/Modules/_sre.c index 55a86c290181..6a3d81122678 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -62,9 +62,6 @@ static char copyright[] = /* -------------------------------------------------------------------- */ /* optional features */ -/* enables fast searching */ -#define USE_FAST_SEARCH - /* enables copy/deepcopy handling (work in progress) */ #undef USE_BUILTIN_COPY @@ -97,48 +94,25 @@ static char copyright[] = /* -------------------------------------------------------------------- */ /* search engine state */ -/* default character predicates (run sre_chars.py to regenerate tables) */ - -#define SRE_DIGIT_MASK 1 -#define SRE_SPACE_MASK 2 -#define SRE_LINEBREAK_MASK 4 -#define SRE_ALNUM_MASK 8 -#define SRE_WORD_MASK 16 - -/* FIXME: this assumes ASCII. create tables in init_sre() instead */ - -static char sre_char_info[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 2, -2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, -0, 0, 16, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0 }; - -static char sre_char_lower[128] = { 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, 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, 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 }; - #define SRE_IS_DIGIT(ch)\ - ((ch) < 128 ? (sre_char_info[(ch)] & SRE_DIGIT_MASK) : 0) + ((ch) < 128 && Py_ISDIGIT(ch)) #define SRE_IS_SPACE(ch)\ - ((ch) < 128 ? (sre_char_info[(ch)] & SRE_SPACE_MASK) : 0) + ((ch) < 128 && Py_ISSPACE(ch)) #define SRE_IS_LINEBREAK(ch)\ - ((ch) < 128 ? (sre_char_info[(ch)] & SRE_LINEBREAK_MASK) : 0) + ((ch) == '\n') #define SRE_IS_ALNUM(ch)\ - ((ch) < 128 ? (sre_char_info[(ch)] & SRE_ALNUM_MASK) : 0) + ((ch) < 128 && Py_ISALNUM(ch)) #define SRE_IS_WORD(ch)\ - ((ch) < 128 ? (sre_char_info[(ch)] & SRE_WORD_MASK) : 0) + ((ch) < 128 && (Py_ISALNUM(ch) || (ch) == '_')) static unsigned int sre_lower(unsigned int ch) { - return ((ch) < 128 ? (unsigned int)sre_char_lower[ch] : ch); + return ((ch) < 128 ? Py_TOLOWER(ch) : ch); +} + +static unsigned int sre_upper(unsigned int ch) +{ + return ((ch) < 128 ? Py_TOUPPER(ch) : ch); } /* locale-specific character predicates */ @@ -152,6 +126,11 @@ 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) @@ -165,6 +144,11 @@ 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) { @@ -271,25 +255,50 @@ data_stack_grow(SRE_STATE* state, Py_ssize_t size) /* see sre.h for object declarations */ static PyObject*pattern_new_match(PatternObject*, SRE_STATE*, Py_ssize_t); -static PyObject*pattern_scanner(PatternObject*, PyObject*, PyObject* kw); +static PyObject *pattern_scanner(PatternObject *, PyObject *, Py_ssize_t, Py_ssize_t); -static PyObject * -sre_codesize(PyObject* self, PyObject *unused) + +/*[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(PyModuleDef *module) +/*[clinic end generated code: output=794f1f98ef4883e5 input=bd6f6ecf4916bb2b]*/ { - return PyLong_FromSize_t(sizeof(SRE_CODE)); + return sizeof(SRE_CODE); } -static PyObject * -sre_getlower(PyObject* self, PyObject* args) +/*[clinic input] +_sre.getlower -> int + + character: int + flags: int + / + +[clinic start generated code]*/ + +static int +_sre_getlower_impl(PyModuleDef *module, int character, int flags) +/*[clinic end generated code: output=5fc3616ae2a4c306 input=087d2f1c44bbca6f]*/ { - int character, flags; - if (!PyArg_ParseTuple(args, "ii", &character, &flags)) - return NULL; if (flags & SRE_FLAG_LOCALE) - return Py_BuildValue("i", sre_lower_locale(character)); + return sre_lower_locale(character); if (flags & SRE_FLAG_UNICODE) - return Py_BuildValue("i", sre_lower_unicode(character)); - return Py_BuildValue("i", sre_lower(character)); + return sre_lower_unicode(character); + return sre_lower(character); } LOCAL(void) @@ -328,7 +337,7 @@ getstring(PyObject* string, Py_ssize_t* p_length, /* get pointer to byte string buffer */ if (PyObject_GetBuffer(string, view, PyBUF_SIMPLE) != 0) { - PyErr_SetString(PyExc_TypeError, "expected string or buffer"); + PyErr_SetString(PyExc_TypeError, "expected string or bytes-like object"); return NULL; } @@ -357,6 +366,11 @@ state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string, 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; @@ -367,12 +381,12 @@ state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string, if (isbytes && pattern->isbytes == 0) { PyErr_SetString(PyExc_TypeError, - "can't use a string pattern on a bytes-like object"); + "cannot use a string pattern on a bytes-like object"); goto err; } if (!isbytes && pattern->isbytes > 0) { PyErr_SetString(PyExc_TypeError, - "can't use a bytes pattern on a string-like object"); + "cannot use a bytes pattern on a string-like object"); goto err; } @@ -400,15 +414,23 @@ state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string, state->pos = start; state->endpos = end; - if (pattern->flags & SRE_FLAG_LOCALE) + if (pattern->flags & SRE_FLAG_LOCALE) { state->lower = sre_lower_locale; - else if (pattern->flags & SRE_FLAG_UNICODE) + state->upper = sre_upper_locale; + } + else if (pattern->flags & SRE_FLAG_UNICODE) { state->lower = sre_lower_unicode; - else + state->upper = sre_upper_unicode; + } + else { state->lower = sre_lower; + state->upper = sre_upper; + } return string; err: + PyMem_Del(state->mark); + state->mark = NULL; if (state->buffer.buf) PyBuffer_Release(&state->buffer); return NULL; @@ -421,6 +443,8 @@ state_fini(SRE_STATE* state) 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 */ @@ -473,8 +497,9 @@ pattern_error(Py_ssize_t status) { switch (status) { case SRE_ERROR_RECURSION_LIMIT: + /* This error code seems to be unused. */ PyErr_SetString( - PyExc_RuntimeError, + PyExc_RecursionError, "maximum recursion limit exceeded" ); break; @@ -505,14 +530,14 @@ pattern_dealloc(PatternObject* self) } LOCAL(Py_ssize_t) -sre_match(SRE_STATE* state, SRE_CODE* pattern) +sre_match(SRE_STATE* state, SRE_CODE* pattern, int match_all) { if (state->charsize == 1) - return sre_ucs1_match(state, pattern); + return sre_ucs1_match(state, pattern, match_all); if (state->charsize == 2) - return sre_ucs2_match(state, pattern); + return sre_ucs2_match(state, pattern, match_all); assert(state->charsize == 4); - return sre_ucs4_match(state, pattern); + return sre_ucs4_match(state, pattern, match_all); } LOCAL(Py_ssize_t) @@ -526,89 +551,150 @@ sre_search(SRE_STATE* state, SRE_CODE* pattern) return sre_ucs4_search(state, pattern); } -static PyObject* -pattern_match(PatternObject* self, PyObject* args, PyObject* kw) +static PyObject * +fix_string_param(PyObject *string, PyObject *string2, const char *oldname) +{ + if (string2 != NULL) { + if (string != NULL) { + PyErr_Format(PyExc_TypeError, + "Argument given by name ('%s') and position (1)", + oldname); + return NULL; + } + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "The '%s' keyword parameter name is deprecated. " + "Use 'string' instead.", oldname) < 0) + return NULL; + return string2; + } + if (string == NULL) { + PyErr_SetString(PyExc_TypeError, + "Required argument 'string' (pos 1) not found"); + return NULL; + } + return string; +} + +/*[clinic input] +_sre.SRE_Pattern.match + + string: object = NULL + pos: Py_ssize_t = 0 + endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize + * + pattern: object = NULL + +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, + PyObject *pattern) +/*[clinic end generated code: output=74b4b1da3bb2d84e input=3d079aa99979b81d]*/ { SRE_STATE state; Py_ssize_t status; + PyObject *match; - PyObject* string; - Py_ssize_t start = 0; - Py_ssize_t end = PY_SSIZE_T_MAX; - static char* kwlist[] = { "pattern", "pos", "endpos", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:match", kwlist, - &string, &start, &end)) - return NULL; - - string = state_init(&state, self, string, start, end); + string = fix_string_param(string, pattern, "pattern"); if (!string) return NULL; + 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)); + status = sre_match(&state, PatternObject_GetCode(self), 0); TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr)); - if (PyErr_Occurred()) + if (PyErr_Occurred()) { + state_fini(&state); return NULL; + } + match = pattern_new_match(self, &state, status); state_fini(&state); - - return pattern_new_match(self, &state, status); + return match; } -static PyObject* -pattern_fullmatch(PatternObject* self, PyObject* args, PyObject* kw) +/*[clinic input] +_sre.SRE_Pattern.fullmatch + + string: object = NULL + pos: Py_ssize_t = 0 + endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize + * + pattern: object = NULL + +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, + PyObject *pattern) +/*[clinic end generated code: output=1c98bc5da744ea94 input=d4228606cc12580f]*/ { SRE_STATE state; Py_ssize_t status; + PyObject *match; - PyObject* string; - Py_ssize_t start = 0; - Py_ssize_t end = PY_SSIZE_T_MAX; - static char* kwlist[] = { "pattern", "pos", "endpos", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:fullmatch", kwlist, - &string, &start, &end)) + string = fix_string_param(string, pattern, "pattern"); + if (!string) return NULL; - string = state_init(&state, self, string, start, end); - if (!string) + if (!state_init(&state, self, string, pos, endpos)) return NULL; - state.match_all = 1; state.ptr = state.start; TRACE(("|%p|%p|FULLMATCH\n", PatternObject_GetCode(self), state.ptr)); - status = sre_match(&state, PatternObject_GetCode(self)); + status = sre_match(&state, PatternObject_GetCode(self), 1); TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr)); - if (PyErr_Occurred()) + if (PyErr_Occurred()) { + state_fini(&state); return NULL; + } + match = pattern_new_match(self, &state, status); state_fini(&state); - - return pattern_new_match(self, &state, status); + return match; } -static PyObject* -pattern_search(PatternObject* self, PyObject* args, PyObject* kw) +/*[clinic input] +_sre.SRE_Pattern.search + + string: object = NULL + pos: Py_ssize_t = 0 + endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize + * + pattern: object = NULL + +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, + PyObject *pattern) +/*[clinic end generated code: output=3839394a18e5ea4f input=dab42720f4be3a4b]*/ { SRE_STATE state; Py_ssize_t status; + PyObject *match; - PyObject* string; - Py_ssize_t start = 0; - Py_ssize_t end = PY_SSIZE_T_MAX; - static char* kwlist[] = { "pattern", "pos", "endpos", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:search", kwlist, - &string, &start, &end)) + string = fix_string_param(string, pattern, "pattern"); + if (!string) return NULL; - string = state_init(&state, self, string, start, end); - if (!string) + if (!state_init(&state, self, string, pos, endpos)) return NULL; TRACE(("|%p|%p|SEARCH\n", PatternObject_GetCode(self), state.ptr)); @@ -617,12 +703,14 @@ pattern_search(PatternObject* self, PyObject* args, PyObject* kw) TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr)); - state_fini(&state); - - if (PyErr_Occurred()) + if (PyErr_Occurred()) { + state_fini(&state); return NULL; + } - return pattern_new_match(self, &state, status); + match = pattern_new_match(self, &state, status); + state_fini(&state); + return match; } static PyObject* @@ -672,24 +760,34 @@ deepcopy(PyObject** object, PyObject* memo) } #endif -static PyObject* -pattern_findall(PatternObject* self, PyObject* args, PyObject* kw) +/*[clinic input] +_sre.SRE_Pattern.findall + + string: object = NULL + pos: Py_ssize_t = 0 + endpos: Py_ssize_t(c_default="PY_SSIZE_T_MAX") = sys.maxsize + * + source: object = NULL + +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, + PyObject *source) +/*[clinic end generated code: output=51295498b300639d input=df688355c056b9de]*/ { SRE_STATE state; PyObject* list; Py_ssize_t status; Py_ssize_t i, b, e; - PyObject* string; - Py_ssize_t start = 0; - Py_ssize_t end = PY_SSIZE_T_MAX; - static char* kwlist[] = { "source", "pos", "endpos", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:findall", kwlist, - &string, &start, &end)) + string = fix_string_param(string, source, "source"); + if (!string) return NULL; - string = state_init(&state, self, string, start, end); - if (!string) + if (!state_init(&state, self, string, pos, endpos)) return NULL; list = PyList_New(0); @@ -769,14 +867,28 @@ pattern_findall(PatternObject* self, PyObject* args, PyObject* kw) } -static PyObject* -pattern_finditer(PatternObject* pattern, PyObject* args, PyObject* kw) +/*[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(pattern, args, kw); + scanner = pattern_scanner(self, string, pos, endpos); if (!scanner) return NULL; @@ -791,8 +903,38 @@ pattern_finditer(PatternObject* pattern, PyObject* args, PyObject* kw) return iterator; } -static PyObject* -pattern_split(PatternObject* self, PyObject* args, PyObject* kw) +/*[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 = NULL + maxsplit: Py_ssize_t = 0 + * + source: object = NULL + +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, PyObject *source) +/*[clinic end generated code: output=20bac2ff55b9f84c input=41e0b2e35e599d7b]*/ { SRE_STATE state; PyObject* list; @@ -802,15 +944,24 @@ pattern_split(PatternObject* self, PyObject* args, PyObject* kw) Py_ssize_t i; void* last; - PyObject* string; - Py_ssize_t maxsplit = 0; - static char* kwlist[] = { "source", "maxsplit", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kw, "O|n:split", kwlist, - &string, &maxsplit)) + string = fix_string_param(string, source, "source"); + if (!string) return NULL; - string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX); - if (!string) + assert(self->codesize != 0); + if (self->code[0] != SRE_OP_INFO || self->code[3] == 0) { + if (self->code[0] == SRE_OP_INFO && self->code[4] == 0) { + PyErr_SetString(PyExc_ValueError, + "split() requires a non-empty pattern match."); + return NULL; + } + if (PyErr_WarnEx(PyExc_FutureWarning, + "split() requires a non-empty pattern match.", + 1) < 0) + return NULL; + } + + if (!state_init(&state, self, string, 0, PY_SSIZE_T_MAX)) return NULL; list = PyList_New(0); @@ -840,7 +991,7 @@ pattern_split(PatternObject* self, PyObject* args, PyObject* kw) } if (state.start == state.ptr) { - if (last == state.end) + if (last == state.end || state.ptr == state.end) break; /* skip one character */ state.start = (void*) ((char*) state.ptr + state.charsize); @@ -954,8 +1105,7 @@ pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string, } } - string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX); - if (!string) { + if (!state_init(&state, self, string, 0, PY_SSIZE_T_MAX)) { Py_DECREF(filter); return NULL; } @@ -1038,6 +1188,8 @@ pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string, next: /* move on */ + if (state.ptr == state.end) + break; if (state.ptr == state.start) state.start = (void*) ((char*) state.ptr + state.charsize); else @@ -1095,36 +1247,50 @@ pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string, } -static PyObject* -pattern_sub(PatternObject* self, PyObject* args, PyObject* kw) -{ - PyObject* ptemplate; - PyObject* string; - Py_ssize_t count = 0; - static char* kwlist[] = { "repl", "string", "count", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|n:sub", kwlist, - &ptemplate, &string, &count)) - return NULL; +/*[clinic input] +_sre.SRE_Pattern.sub - return pattern_subx(self, ptemplate, string, count, 0); + 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); } -static PyObject* -pattern_subn(PatternObject* self, PyObject* args, PyObject* kw) -{ - PyObject* ptemplate; - PyObject* string; - Py_ssize_t count = 0; - static char* kwlist[] = { "repl", "string", "count", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|n:subn", kwlist, - &ptemplate, &string, &count)) - return NULL; +/*[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]*/ - return pattern_subx(self, ptemplate, string, count, 1); +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); } -static PyObject* -pattern_copy(PatternObject* self, PyObject *unused) +/*[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]*/ { #ifdef USE_BUILTIN_COPY PatternObject* copy; @@ -1151,8 +1317,16 @@ pattern_copy(PatternObject* self, PyObject *unused) #endif } -static PyObject* -pattern_deepcopy(PatternObject* self, PyObject* memo) +/*[clinic input] +_sre.SRE_Pattern.__deepcopy__ + + memo: object + +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Pattern___deepcopy___impl(PatternObject *self, PyObject *memo) +/*[clinic end generated code: output=75efe69bd12c5d7d input=3959719482c07f70]*/ { #ifdef USE_BUILTIN_COPY PatternObject* copy; @@ -1193,7 +1367,7 @@ pattern_repr(PatternObject *obj) }; PyObject *result = NULL; PyObject *flag_items; - int i; + size_t i; int flags = obj->flags; /* Omit re.UNICODE for valid string patterns. */ @@ -1254,131 +1428,40 @@ pattern_repr(PatternObject *obj) return result; } -PyDoc_STRVAR(pattern_match_doc, -"match(string[, pos[, endpos]]) -> match object or None.\n\ - Matches zero or more characters at the beginning of the string"); - -PyDoc_STRVAR(pattern_fullmatch_doc, -"fullmatch(string[, pos[, endpos]]) -> match object or None.\n\ - Matches against all of the string"); - -PyDoc_STRVAR(pattern_search_doc, -"search(string[, pos[, endpos]]) -> match object or None.\n\ - Scan through string looking for a match, and return a corresponding\n\ - match object instance. Return None if no position in the string matches."); - -PyDoc_STRVAR(pattern_split_doc, -"split(string[, maxsplit = 0]) -> list.\n\ - Split string by the occurrences of pattern."); - -PyDoc_STRVAR(pattern_findall_doc, -"findall(string[, pos[, endpos]]) -> list.\n\ - Return a list of all non-overlapping matches of pattern in string."); - -PyDoc_STRVAR(pattern_finditer_doc, -"finditer(string[, pos[, endpos]]) -> iterator.\n\ - Return an iterator over all non-overlapping matches for the \n\ - RE pattern in string. For each match, the iterator returns a\n\ - match object."); - -PyDoc_STRVAR(pattern_sub_doc, -"sub(repl, string[, count = 0]) -> newstring.\n\ - Return the string obtained by replacing the leftmost non-overlapping\n\ - occurrences of pattern in string by the replacement repl."); - -PyDoc_STRVAR(pattern_subn_doc, -"subn(repl, string[, count = 0]) -> (newstring, number of subs)\n\ - Return the tuple (new_string, number_of_subs_made) found by replacing\n\ - the leftmost non-overlapping occurrences of pattern with the\n\ - replacement repl."); - PyDoc_STRVAR(pattern_doc, "Compiled regular expression objects"); -static PyMethodDef pattern_methods[] = { - {"match", (PyCFunction) pattern_match, METH_VARARGS|METH_KEYWORDS, - pattern_match_doc}, - {"fullmatch", (PyCFunction) pattern_fullmatch, METH_VARARGS|METH_KEYWORDS, - pattern_fullmatch_doc}, - {"search", (PyCFunction) pattern_search, METH_VARARGS|METH_KEYWORDS, - pattern_search_doc}, - {"sub", (PyCFunction) pattern_sub, METH_VARARGS|METH_KEYWORDS, - pattern_sub_doc}, - {"subn", (PyCFunction) pattern_subn, METH_VARARGS|METH_KEYWORDS, - pattern_subn_doc}, - {"split", (PyCFunction) pattern_split, METH_VARARGS|METH_KEYWORDS, - pattern_split_doc}, - {"findall", (PyCFunction) pattern_findall, METH_VARARGS|METH_KEYWORDS, - pattern_findall_doc}, - {"finditer", (PyCFunction) pattern_finditer, METH_VARARGS|METH_KEYWORDS, - pattern_finditer_doc}, - {"scanner", (PyCFunction) pattern_scanner, METH_VARARGS|METH_KEYWORDS}, - {"__copy__", (PyCFunction) pattern_copy, METH_NOARGS}, - {"__deepcopy__", (PyCFunction) pattern_deepcopy, METH_O}, - {NULL, NULL} -}; +/* PatternObject's 'groupindex' method. */ +static PyObject * +pattern_groupindex(PatternObject *self) +{ + return PyDictProxy_New(self->groupindex); +} -#define PAT_OFF(x) offsetof(PatternObject, x) -static PyMemberDef pattern_members[] = { - {"pattern", T_OBJECT, PAT_OFF(pattern), READONLY}, - {"flags", T_INT, PAT_OFF(flags), READONLY}, - {"groups", T_PYSSIZET, PAT_OFF(groups), READONLY}, - {"groupindex", T_OBJECT, PAT_OFF(groupindex), READONLY}, - {NULL} /* Sentinel */ -}; +static int _validate(PatternObject *self); /* Forward */ -static PyTypeObject Pattern_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_" SRE_MODULE ".SRE_Pattern", - sizeof(PatternObject), sizeof(SRE_CODE), - (destructor)pattern_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (reprfunc)pattern_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 */ - pattern_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(PatternObject, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - pattern_methods, /* tp_methods */ - pattern_members, /* tp_members */ -}; +/*[clinic input] +_sre.compile -static int _validate(PatternObject *self); /* Forward */ + pattern: object + flags: int + code: object(subclass_of='&PyList_Type') + groups: Py_ssize_t + groupindex: object + indexgroup: object + +[clinic start generated code]*/ static PyObject * -_compile(PyObject* self_, PyObject* args) +_sre_compile_impl(PyModuleDef *module, PyObject *pattern, int flags, + PyObject *code, Py_ssize_t groups, PyObject *groupindex, + PyObject *indexgroup) +/*[clinic end generated code: output=3004b293730bf309 input=7d059ec8ae1edb85]*/ { /* "compile" pattern descriptor to pattern object */ PatternObject* self; Py_ssize_t i, n; - PyObject* pattern; - int flags = 0; - PyObject* code; - Py_ssize_t groups = 0; - PyObject* groupindex = NULL; - PyObject* indexgroup = NULL; - - if (!PyArg_ParseTuple(args, "OiO!|nOO", &pattern, &flags, - &PyList_Type, &code, &groups, - &groupindex, &indexgroup)) - return NULL; - n = PyList_GET_SIZE(code); /* coverity[ampersand_in_size] */ self = PyObject_NEW_VAR(PatternObject, &Pattern_Type, n); @@ -1534,6 +1617,7 @@ _validate_charset(SRE_CODE *code, SRE_CODE *end) break; case SRE_OP_RANGE: + case SRE_OP_RANGE_IGNORE: GET_ARG; GET_ARG; break; @@ -1890,10 +1974,9 @@ _validate_inner(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) static int _validate_outer(SRE_CODE *code, SRE_CODE *end, Py_ssize_t groups) { - if (groups < 0 || groups > 100 || code >= end || end[-1] != SRE_OP_SUCCESS) + if (groups < 0 || (size_t)groups > SRE_MAXGROUPS || + code >= end || end[-1] != SRE_OP_SUCCESS) FAIL; - if (groups == 0) /* fix for simplejson */ - groups = 100; /* 100 groups should always be safe */ return _validate_inner(code, end-1, groups); } @@ -1991,13 +2074,22 @@ match_getslice(MatchObject* self, PyObject* index, PyObject* def) return match_getslice_by_index(self, match_getindex(self, index), def); } -static PyObject* -match_expand(MatchObject* self, PyObject* ptemplate) +/*[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, ptemplate) + PyTuple_Pack(3, self->pattern, self, template) ); } @@ -2036,24 +2128,29 @@ match_group(MatchObject* self, PyObject* args) return result; } -static PyObject* -match_groups(MatchObject* self, PyObject* args, PyObject* kw) +/*[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; - PyObject* def = Py_None; - static char* kwlist[] = { "default", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:groups", kwlist, &def)) - return NULL; - 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, def); + item = match_getslice_by_index(self, index, default_value); if (!item) { Py_DECREF(result); return NULL; @@ -2064,18 +2161,23 @@ match_groups(MatchObject* self, PyObject* args, PyObject* kw) return result; } -static PyObject* -match_groupdict(MatchObject* self, PyObject* args, PyObject* kw) +/*[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* keys; Py_ssize_t index; - PyObject* def = Py_None; - static char* kwlist[] = { "default", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:groupdict", kwlist, &def)) - return NULL; - result = PyDict_New(); if (!result || !self->pattern->groupindex) return result; @@ -2091,7 +2193,7 @@ match_groupdict(MatchObject* self, PyObject* args, PyObject* kw) key = PyList_GET_ITEM(keys, index); if (!key) goto failed; - value = match_getslice(self, key, def); + value = match_getslice(self, key, default_value); if (!value) { Py_DECREF(key); goto failed; @@ -2112,50 +2214,58 @@ match_groupdict(MatchObject* self, PyObject* args, PyObject* kw) return NULL; } -static PyObject* -match_start(MatchObject* self, PyObject* args) -{ - Py_ssize_t index; +/*[clinic input] +_sre.SRE_Match.start -> Py_ssize_t - PyObject* index_ = NULL; - if (!PyArg_UnpackTuple(args, "start", 0, 1, &index_)) - return NULL; + group: object(c_default="NULL") = 0 + / + +Return index of the start of the substring matched by group. +[clinic start generated code]*/ - index = match_getindex(self, index_); +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 || index >= self->groups) { PyErr_SetString( PyExc_IndexError, "no such group" ); - return NULL; + return -1; } /* mark is -1 if group is undefined */ - return PyLong_FromSsize_t(self->mark[index*2]); + return self->mark[index*2]; } -static PyObject* -match_end(MatchObject* self, PyObject* args) -{ - Py_ssize_t index; +/*[clinic input] +_sre.SRE_Match.end -> Py_ssize_t - PyObject* index_ = NULL; - if (!PyArg_UnpackTuple(args, "end", 0, 1, &index_)) - return NULL; + group: object(c_default="NULL") = 0 + / - index = match_getindex(self, index_); +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 || index >= self->groups) { PyErr_SetString( PyExc_IndexError, "no such group" ); - return NULL; + return -1; } /* mark is -1 if group is undefined */ - return PyLong_FromSsize_t(self->mark[index*2+1]); + return self->mark[index*2+1]; } LOCAL(PyObject*) @@ -2185,16 +2295,20 @@ _pair(Py_ssize_t i1, Py_ssize_t i2) return NULL; } -static PyObject* -match_span(MatchObject* self, PyObject* args) -{ - Py_ssize_t index; +/*[clinic input] +_sre.SRE_Match.span - PyObject* index_ = NULL; - if (!PyArg_UnpackTuple(args, "span", 0, 1, &index_)) - return NULL; + group: object(c_default="NULL") = 0 + / + +For MatchObject m, return the 2-tuple (m.start(group), m.end(group)). +[clinic start generated code]*/ - index = match_getindex(self, index_); +static PyObject * +_sre_SRE_Match_span_impl(MatchObject *self, PyObject *group) +/*[clinic end generated code: output=f02ae40594d14fe6 input=49092b6008d176d3]*/ +{ + Py_ssize_t index = match_getindex(self, group); if (index < 0 || index >= self->groups) { PyErr_SetString( @@ -2234,8 +2348,14 @@ match_regs(MatchObject* self) return regs; } -static PyObject* -match_copy(MatchObject* self, PyObject *unused) +/*[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]*/ { #ifdef USE_BUILTIN_COPY MatchObject* copy; @@ -2265,8 +2385,16 @@ match_copy(MatchObject* self, PyObject *unused) #endif } -static PyObject* -match_deepcopy(MatchObject* self, PyObject* memo) +/*[clinic input] +_sre.SRE_Match.__deepcopy__ + + memo: object + +[clinic start generated code]*/ + +static PyObject * +_sre_SRE_Match___deepcopy___impl(MatchObject *self, PyObject *memo) +/*[clinic end generated code: output=2b657578eb03f4a3 input=b65b72489eac64cc]*/ { #ifdef USE_BUILTIN_COPY MatchObject* copy; @@ -2297,50 +2425,6 @@ PyDoc_STRVAR(match_group_doc, Return subgroup(s) of the match by indices or names.\n\ For 0 returns the entire match."); -PyDoc_STRVAR(match_start_doc, -"start([group=0]) -> int.\n\ - Return index of the start of the substring matched by group."); - -PyDoc_STRVAR(match_end_doc, -"end([group=0]) -> int.\n\ - Return index of the end of the substring matched by group."); - -PyDoc_STRVAR(match_span_doc, -"span([group]) -> tuple.\n\ - For MatchObject m, return the 2-tuple (m.start(group), m.end(group))."); - -PyDoc_STRVAR(match_groups_doc, -"groups([default=None]) -> tuple.\n\ - Return a tuple containing all the subgroups of the match, from 1.\n\ - The default argument is used for groups\n\ - that did not participate in the match"); - -PyDoc_STRVAR(match_groupdict_doc, -"groupdict([default=None]) -> dict.\n\ - Return a dictionary containing all the named subgroups of the match,\n\ - keyed by the subgroup name. The default argument is used for groups\n\ - that did not participate in the match"); - -PyDoc_STRVAR(match_expand_doc, -"expand(template) -> str.\n\ - Return the string obtained by doing backslash substitution\n\ - on the string template, as done by the sub() method."); - -static PyMethodDef match_methods[] = { - {"group", (PyCFunction) match_group, METH_VARARGS, match_group_doc}, - {"start", (PyCFunction) match_start, METH_VARARGS, match_start_doc}, - {"end", (PyCFunction) match_end, METH_VARARGS, match_end_doc}, - {"span", (PyCFunction) match_span, METH_VARARGS, match_span_doc}, - {"groups", (PyCFunction) match_groups, METH_VARARGS|METH_KEYWORDS, - match_groups_doc}, - {"groupdict", (PyCFunction) match_groupdict, METH_VARARGS|METH_KEYWORDS, - match_groupdict_doc}, - {"expand", (PyCFunction) match_expand, METH_O, match_expand_doc}, - {"__copy__", (PyCFunction) match_copy, METH_NOARGS}, - {"__deepcopy__", (PyCFunction) match_deepcopy, METH_O}, - {NULL, NULL} -}; - static PyObject * match_lastindex_get(MatchObject *self) { @@ -2391,57 +2475,6 @@ match_repr(MatchObject *self) } -static PyGetSetDef match_getset[] = { - {"lastindex", (getter)match_lastindex_get, (setter)NULL}, - {"lastgroup", (getter)match_lastgroup_get, (setter)NULL}, - {"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}, - {"re", T_OBJECT, MATCH_OFF(pattern), READONLY}, - {"pos", T_PYSSIZET, MATCH_OFF(pos), READONLY}, - {"endpos", T_PYSSIZET, MATCH_OFF(endpos), READONLY}, - {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) - "_" SRE_MODULE ".SRE_Match", - sizeof(MatchObject), sizeof(Py_ssize_t), - (destructor)match_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - (reprfunc)match_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 */ - 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 PyObject* pattern_new_match(PatternObject* pattern, SRE_STATE* state, Py_ssize_t status) { @@ -2517,40 +2550,62 @@ scanner_dealloc(ScannerObject* self) PyObject_DEL(self); } -static PyObject* -scanner_match(ScannerObject* self, PyObject *unused) +/*[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)); + status = sre_match(state, PatternObject_GetCode(self->pattern), 0); if (PyErr_Occurred()) return NULL; match = pattern_new_match((PatternObject*) self->pattern, state, status); - if (status == 0 || state->ptr == state->start) + if (status == 0) + state->start = NULL; + else if (state->ptr != state->start) + state->start = state->ptr; + else if (state->ptr != state->end) state->start = (void*) ((char*) state->ptr + state->charsize); else - state->start = state->ptr; + state->start = NULL; return match; } -static PyObject* -scanner_search(ScannerObject* self, PyObject *unused) +/*[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; @@ -2562,17 +2617,172 @@ scanner_search(ScannerObject* self, PyObject *unused) match = pattern_new_match((PatternObject*) self->pattern, state, status); - if (status == 0 || state->ptr == state->start) + if (status == 0) + state->start = NULL; + else if (state->ptr != state->start) + state->start = state->ptr; + else if (state->ptr != state->end) state->start = (void*) ((char*) state->ptr + state->charsize); else - state->start = state->ptr; + state->start = NULL; 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; +} + +#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}, + {"flags", T_INT, PAT_OFF(flags), READONLY}, + {"groups", T_PYSSIZET, PAT_OFF(groups), READONLY}, + {NULL} /* Sentinel */ +}; + +static PyTypeObject Pattern_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_" SRE_MODULE ".SRE_Pattern", + sizeof(PatternObject), sizeof(SRE_CODE), + (destructor)pattern_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)pattern_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 */ + pattern_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* 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 */ +}; + + +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}, + {"lastgroup", (getter)match_lastgroup_get, (setter)NULL}, + {"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}, + {"re", T_OBJECT, MATCH_OFF(pattern), READONLY}, + {"pos", T_PYSSIZET, MATCH_OFF(pos), READONLY}, + {"endpos", T_PYSSIZET, MATCH_OFF(endpos), READONLY}, + {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) + "_" SRE_MODULE ".SRE_Match", + sizeof(MatchObject), sizeof(Py_ssize_t), + (destructor)match_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc)match_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 */ + 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[] = { - {"match", (PyCFunction) scanner_match, METH_NOARGS}, - {"search", (PyCFunction) scanner_search, METH_NOARGS}, + _SRE_SRE_SCANNER_MATCH_METHODDEF + _SRE_SRE_SCANNER_SEARCH_METHODDEF {NULL, NULL} }; @@ -2614,43 +2824,10 @@ static PyTypeObject Scanner_Type = { 0, /* tp_getset */ }; -static PyObject* -pattern_scanner(PatternObject* pattern, PyObject* args, PyObject* kw) -{ - /* create search state object */ - - ScannerObject* self; - - PyObject* string; - Py_ssize_t start = 0; - Py_ssize_t end = PY_SSIZE_T_MAX; - static char* kwlist[] = { "source", "pos", "endpos", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:scanner", kwlist, - &string, &start, &end)) - return NULL; - - /* create scanner object */ - self = PyObject_NEW(ScannerObject, &Scanner_Type); - if (!self) - return NULL; - self->pattern = NULL; - - string = state_init(&self->state, pattern, string, start, end); - if (!string) { - Py_DECREF(self); - return NULL; - } - - Py_INCREF(pattern); - self->pattern = (PyObject*) pattern; - - return (PyObject*) self; -} - static PyMethodDef _functions[] = { - {"compile", _compile, METH_VARARGS}, - {"getcodesize", sre_codesize, METH_NOARGS}, - {"getlower", sre_getlower, METH_VARARGS}, + _SRE_COMPILE_METHODDEF + _SRE_GETCODESIZE_METHODDEF + _SRE_GETLOWER_METHODDEF {NULL, NULL} }; @@ -2700,6 +2877,12 @@ PyMODINIT_FUNC PyInit__sre(void) 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); diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 6b0d67a3a644..e43c5026b77c 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -14,6 +14,8 @@ http://bugs.python.org/issue8108#msg102867 ? */ +#define PY_SSIZE_T_CLEAN + #include "Python.h" #ifdef WITH_THREAD @@ -62,6 +64,7 @@ static PySocketModule_APIObject PySocketModule; #include "openssl/ssl.h" #include "openssl/err.h" #include "openssl/rand.h" +#include "openssl/bio.h" /* SSL error object */ static PyObject *PySSLErrorObject; @@ -106,6 +109,10 @@ struct py_ssl_library_code { # define HAVE_SNI 0 #endif +#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation +# define HAVE_ALPN +#endif + enum py_ssl_error { /* these mirror ssl.h */ PY_SSL_ERROR_NONE, @@ -134,9 +141,7 @@ enum py_ssl_cert_requirements { }; enum py_ssl_version { -#ifndef OPENSSL_NO_SSL2 PY_SSL_VERSION_SSL2, -#endif PY_SSL_VERSION_SSL3=1, PY_SSL_VERSION_SSL23, #if HAVE_TLSv1_2 @@ -161,13 +166,6 @@ static unsigned int _ssl_locks_count = 0; #define X509_NAME_MAXLEN 256 -/* RAND_* APIs got added to OpenSSL in 0.9.5 */ -#if OPENSSL_VERSION_NUMBER >= 0x0090500fL -# define HAVE_OPENSSL_RAND 1 -#else -# undef HAVE_OPENSSL_RAND -#endif - /* 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. */ @@ -181,36 +179,18 @@ static unsigned int _ssl_locks_count = 0; * older SSL, but let's be safe */ #define PySSL_CB_MAXLEN 128 -/* SSL_get_finished got added to OpenSSL in 0.9.5 */ -#if OPENSSL_VERSION_NUMBER >= 0x0090500fL -# define HAVE_OPENSSL_FINISHED 1 -#else -# define HAVE_OPENSSL_FINISHED 0 -#endif - -/* ECDH support got added to OpenSSL in 0.9.8 */ -#if OPENSSL_VERSION_NUMBER < 0x0090800fL && !defined(OPENSSL_NO_ECDH) -# define OPENSSL_NO_ECDH -#endif - -/* compression support got added to OpenSSL in 0.9.8 */ -#if OPENSSL_VERSION_NUMBER < 0x0090800fL && !defined(OPENSSL_NO_COMP) -# define OPENSSL_NO_COMP -#endif - -/* X509_VERIFY_PARAM got added to OpenSSL in 0.9.8 */ -#if OPENSSL_VERSION_NUMBER >= 0x0090800fL -# define HAVE_OPENSSL_VERIFY_PARAM -#endif - typedef struct { PyObject_HEAD SSL_CTX *ctx; #ifdef OPENSSL_NPN_NEGOTIATED - char *npn_protocols; + unsigned char *npn_protocols; int npn_protocols_len; #endif +#ifdef HAVE_ALPN + unsigned char *alpn_protocols; + int alpn_protocols_len; +#endif #ifndef OPENSSL_NO_TLSEXT PyObject *set_hostname; #endif @@ -226,20 +206,35 @@ typedef struct { char shutdown_seen_zero; char handshake_done; enum py_ssl_server_or_client socket_type; + PyObject *owner; /* Python level "owner" passed to servername callback */ + PyObject *server_hostname; } PySSLSocket; +typedef struct { + PyObject_HEAD + BIO *bio; + int eof_written; +} PySSLMemoryBIO; + static PyTypeObject PySSLContext_Type; static PyTypeObject PySSLSocket_Type; +static PyTypeObject PySSLMemoryBIO_Type; + +/*[clinic input] +module _ssl +class _ssl._SSLContext "PySSLContext *" "&PySSLContext_Type" +class _ssl._SSLSocket "PySSLSocket *" "&PySSLSocket_Type" +class _ssl.MemoryBIO "PySSLMemoryBIO *" "&PySSLMemoryBIO_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7bf7cb832638e2e1]*/ -static PyObject *PySSL_SSLwrite(PySSLSocket *self, PyObject *args); -static PyObject *PySSL_SSLread(PySSLSocket *self, PyObject *args); -static int check_socket_and_wait_for_timeout(PySocketSockObject *s, - int writing); -static PyObject *PySSL_peercert(PySSLSocket *self, PyObject *args); -static PyObject *PySSL_cipher(PySSLSocket *self); +#include "clinic/_ssl.c.h" + +static int PySSL_select(PySocketSockObject *s, int writing, _PyTime_t timeout); #define PySSLContext_Check(v) (Py_TYPE(v) == &PySSLContext_Type) #define PySSLSocket_Check(v) (Py_TYPE(v) == &PySSLSocket_Type) +#define PySSLMemoryBIO_Check(v) (Py_TYPE(v) == &PySSLMemoryBIO_Type) typedef enum { SOCKET_IS_NONBLOCKING, @@ -251,11 +246,16 @@ typedef enum { } timeout_state; /* Wrap error strings with filename and line # */ -#define STRINGIFY1(x) #x -#define STRINGIFY2(x) STRINGIFY1(x) #define ERRSTR1(x,y,z) (x ":" y ": " z) -#define ERRSTR(x) ERRSTR1("_ssl.c", STRINGIFY2(__LINE__), x) +#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) /* * SSL errors. @@ -419,13 +419,12 @@ PySSL_SetError(PySSLSocket *obj, int ret, char *filename, int lineno) case SSL_ERROR_SYSCALL: { if (e == 0) { - PySocketSockObject *s - = (PySocketSockObject *) PyWeakref_GetObject(obj->Socket); + PySocketSockObject *s = GET_SOCKET(obj); if (ret == 0 || (((PyObject *)s) == Py_None)) { p = PY_SSL_ERROR_EOF; type = PySSLEOFErrorObject; errstr = "EOF occurred in violation of protocol"; - } else if (ret == -1) { + } else if (s && ret == -1) { /* underlying BIO reported an I/O error */ Py_INCREF(s); ERR_clear_error(); @@ -479,10 +478,12 @@ _setSSLError (char *errstr, int errcode, char *filename, int lineno) { static PySSLSocket * newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, enum py_ssl_server_or_client socket_type, - char *server_hostname) + char *server_hostname, + PySSLMemoryBIO *inbio, PySSLMemoryBIO *outbio) { PySSLSocket *self; SSL_CTX *ctx = sslctx->ctx; + PyObject *hostname; long mode; self = PyObject_New(PySSLSocket, &PySSLSocket_Type); @@ -495,6 +496,18 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, self->ctx = sslctx; self->shutdown_seen_zero = 0; self->handshake_done = 0; + self->owner = NULL; + if (server_hostname != NULL) { + hostname = PyUnicode_Decode(server_hostname, strlen(server_hostname), + "idna", "strict"); + if (hostname == NULL) { + Py_DECREF(self); + return NULL; + } + self->server_hostname = hostname; + } else + self->server_hostname = NULL; + Py_INCREF(sslctx); /* Make sure the SSL error state is initialized */ @@ -504,8 +517,17 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, PySSL_BEGIN_ALLOW_THREADS self->ssl = SSL_new(ctx); PySSL_END_ALLOW_THREADS - SSL_set_app_data(self->ssl,self); - SSL_set_fd(self->ssl, Py_SAFE_DOWNCAST(sock->sock_fd, SOCKET_T, int)); + 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. */ + CRYPTO_add(&inbio->bio->references, 1, CRYPTO_LOCK_BIO); + CRYPTO_add(&outbio->bio->references, 1, CRYPTO_LOCK_BIO); + SSL_set_bio(self->ssl, inbio->bio, outbio->bio); + } mode = SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER; #ifdef SSL_MODE_AUTO_RETRY mode |= SSL_MODE_AUTO_RETRY; @@ -520,7 +542,7 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, /* 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_timeout >= 0.0) { + if (sock && sock->sock_timeout >= 0) { BIO_set_nbio(SSL_get_rbio(self->ssl), 1); BIO_set_nbio(SSL_get_wbio(self->ssl), 1); } @@ -533,35 +555,52 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, PySSL_END_ALLOW_THREADS self->socket_type = socket_type; - self->Socket = PyWeakref_NewRef((PyObject *) sock, NULL); - if (self->Socket == NULL) { - Py_DECREF(self); - return NULL; + if (sock != NULL) { + self->Socket = PyWeakref_NewRef((PyObject *) sock, NULL); + if (self->Socket == NULL) { + Py_DECREF(self); + Py_XDECREF(self->server_hostname); + return NULL; + } } return self; } /* SSL object methods */ -static PyObject *PySSL_SSLdo_handshake(PySSLSocket *self) +/*[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; int err; int sockstate, nonblocking; - PySocketSockObject *sock - = (PySocketSockObject *) PyWeakref_GetObject(self->Socket); + 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); - if (((PyObject*)sock) == Py_None) { - _setSSLError("Underlying socket connection gone", - PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); - return 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); } - Py_INCREF(sock); - /* just in case the blocking state of the socket has been changed */ - nonblocking = (sock->sock_timeout >= 0.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. */ @@ -570,15 +609,21 @@ static PyObject *PySSL_SSLdo_handshake(PySSLSocket *self) ret = SSL_do_handshake(self->ssl); err = SSL_get_error(self->ssl, ret); PySSL_END_ALLOW_THREADS + if (PyErr_CheckSignals()) goto error; + + if (has_timeout) + timeout = deadline - _PyTime_GetMonotonicClock(); + if (err == SSL_ERROR_WANT_READ) { - sockstate = check_socket_and_wait_for_timeout(sock, 0); + sockstate = PySSL_select(sock, 0, timeout); } else if (err == SSL_ERROR_WANT_WRITE) { - sockstate = check_socket_and_wait_for_timeout(sock, 1); + 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")); @@ -595,7 +640,7 @@ static PyObject *PySSL_SSLdo_handshake(PySSLSocket *self) break; } } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE); - Py_DECREF(sock); + Py_XDECREF(sock); if (ret < 1) return PySSL_SetError(self, ret, __FILE__, __LINE__); @@ -610,7 +655,7 @@ static PyObject *PySSL_SSLdo_handshake(PySSLSocket *self) return Py_None; error: - Py_DECREF(sock); + Py_XDECREF(sock); return NULL; } @@ -779,12 +824,7 @@ _get_peer_alt_names (X509 *certificate) { char buf[2048]; char *vptr; int len; - /* Issue #2973: ASN1_item_d2i() API changed in OpenSSL 0.9.6m */ -#if OPENSSL_VERSION_NUMBER >= 0x009060dfL const unsigned char *p; -#else - unsigned char *p; -#endif if (certificate == NULL) return peer_alt_names; @@ -1274,25 +1314,28 @@ _certificate_to_der(X509 *certificate) return retval; } -static PyObject * -PySSL_test_decode_certificate (PyObject *mod, PyObject *args) { +/*[clinic input] +_ssl._test_decode_cert + path: object(converter="PyUnicode_FSConverter") + / +[clinic start generated code]*/ + +static PyObject * +_ssl__test_decode_cert_impl(PyModuleDef *module, PyObject *path) +/*[clinic end generated code: output=679e01db282804e9 input=cdeaaf02d4346628]*/ +{ PyObject *retval = NULL; - PyObject *filename; X509 *x=NULL; BIO *cert; - if (!PyArg_ParseTuple(args, "O&:test_decode_certificate", - PyUnicode_FSConverter, &filename)) - return NULL; - 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(filename)) <= 0) { + if (BIO_read_filename(cert, PyBytes_AsString(path)) <= 0) { PyErr_SetString(PySSLErrorObject, "Can't open file"); goto fail0; @@ -1309,20 +1352,33 @@ PySSL_test_decode_certificate (PyObject *mod, PyObject *args) { X509_free(x); fail0: - Py_DECREF(filename); + Py_DECREF(path); if (cert != NULL) BIO_free(cert); return retval; } +/*[clinic input] +_ssl._SSLSocket.peer_certificate + 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 * -PySSL_peercert(PySSLSocket *self, PyObject *args) +_ssl__SSLSocket_peer_certificate_impl(PySSLSocket *self, int binary_mode) +/*[clinic end generated code: output=f0dc3e4d1d818a1d input=8281bd1d193db843]*/ { int verification; - int binary_mode = 0; - - if (!PyArg_ParseTuple(args, "|p:peer_certificate", &binary_mode)) - return NULL; if (!self->handshake_done) { PyErr_SetString(PyExc_ValueError, @@ -1344,68 +1400,123 @@ PySSL_peercert(PySSLSocket *self, PyObject *args) } } -PyDoc_STRVAR(PySSL_peercert_doc, -"peer_certificate([der=False]) -> certificate\n\ -\n\ -Returns the certificate for the peer. If no certificate was provided,\n\ -returns None. If a certificate was provided, but not validated, returns\n\ -an empty dictionary. Otherwise returns a dict containing information\n\ -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."); - -static PyObject *PySSL_cipher (PySSLSocket *self) { - - PyObject *retval, *v; - const SSL_CIPHER *current; - char *cipher_name; - char *cipher_protocol; - - if (self->ssl == NULL) - Py_RETURN_NONE; - current = SSL_get_current_cipher(self->ssl); - if (current == NULL) - Py_RETURN_NONE; - - retval = PyTuple_New(3); +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 = (char *) SSL_CIPHER_get_name(current); + 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 fail0; + goto fail; PyTuple_SET_ITEM(retval, 0, v); } - cipher_protocol = SSL_CIPHER_get_version(current); + + 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 fail0; + goto fail; PyTuple_SET_ITEM(retval, 1, v); } - v = PyLong_FromLong(SSL_CIPHER_get_bits(current, NULL)); + + v = PyLong_FromLong(SSL_CIPHER_get_bits(cipher, NULL)); if (v == NULL) - goto fail0; + goto fail; PyTuple_SET_ITEM(retval, 2, v); + return retval; - fail0: + fail: Py_DECREF(retval); return NULL; } +/*[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]*/ +{ + SSL_SESSION *sess = SSL_get_session(self->ssl); + STACK_OF(SSL_CIPHER) *ciphers; + int i; + PyObject *res; + + if (!sess || !sess->ciphers) + Py_RETURN_NONE; + ciphers = sess->ciphers; + 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; + version = SSL_get_version(self->ssl); + if (!strcmp(version, "unknown")) + Py_RETURN_NONE; + return PyUnicode_FromString(version); +} + #ifdef OPENSSL_NPN_NEGOTIATED -static PyObject *PySSL_selected_npn_protocol(PySSLSocket *self) { +/*[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; @@ -1414,11 +1525,38 @@ static PyObject *PySSL_selected_npn_protocol(PySSLSocket *self) { if (out == NULL) Py_RETURN_NONE; - return PyUnicode_FromStringAndSize((char *) out, outlen); + return PyUnicode_FromStringAndSize((char *)out, outlen); } #endif -static PyObject *PySSL_compression(PySSLSocket *self) { +#ifdef 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 @@ -1473,6 +1611,54 @@ 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_XDECREF(self->owner); + 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 void PySSL_dealloc(PySSLSocket *self) { @@ -1482,6 +1668,8 @@ static void PySSL_dealloc(PySSLSocket *self) SSL_free(self->ssl); Py_XDECREF(self->Socket); Py_XDECREF(self->ctx); + Py_XDECREF(self->server_hostname); + Py_XDECREF(self->owner); PyObject_Del(self); } @@ -1491,17 +1679,27 @@ static void PySSL_dealloc(PySSLSocket *self) */ static int -check_socket_and_wait_for_timeout(PySocketSockObject *s, int writing) +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; - int rc; +#endif /* Nothing to do unless we're in timeout mode (not non-blocking) */ - if (s->sock_timeout < 0.0) - return SOCKET_IS_BLOCKING; - else if (s->sock_timeout == 0.0) + 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 < 0) @@ -1510,85 +1708,91 @@ check_socket_and_wait_for_timeout(PySocketSockObject *s, int writing) /* Prefer poll, if available, since you can poll() any fd * which can't be done with select(). */ #ifdef HAVE_POLL - { - struct pollfd pollfd; - int timeout; + pollfd.fd = s->sock_fd; + pollfd.events = writing ? POLLOUT : POLLIN; - pollfd.fd = s->sock_fd; - pollfd.events = writing ? POLLOUT : POLLIN; - - /* s->sock_timeout is in seconds, timeout in ms */ - timeout = (int)(s->sock_timeout * 1000 + 0.5); - PySSL_BEGIN_ALLOW_THREADS - rc = poll(&pollfd, 1, timeout); - PySSL_END_ALLOW_THREADS - - goto normal_return; - } -#endif + /* 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; - /* Construct the arguments to select */ - tv.tv_sec = (int)s->sock_timeout; - tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6); + _PyTime_AsTimeval_noraise(timeout, &tv, _PyTime_ROUND_CEILING); + FD_ZERO(&fds); FD_SET(s->sock_fd, &fds); - /* See if the socket is ready */ + /* 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(Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int), - NULL, &fds, NULL, &tv); + rc = select(nfds, NULL, &fds, NULL, &tv); else - rc = select(Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int), - &fds, NULL, NULL, &tv); + rc = select(nfds, &fds, NULL, NULL, &tv); PySSL_END_ALLOW_THREADS - -#ifdef HAVE_POLL -normal_return: #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; } -static PyObject *PySSL_SSLwrite(PySSLSocket *self, PyObject *args) +/*[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]*/ { - Py_buffer buf; int len; int sockstate; int err; int nonblocking; - PySocketSockObject *sock - = (PySocketSockObject *) PyWeakref_GetObject(self->Socket); - - if (((PyObject*)sock) == Py_None) { - _setSSLError("Underlying socket connection gone", - PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); - return NULL; - } - Py_INCREF(sock); - - if (!PyArg_ParseTuple(args, "y*:write", &buf)) { - Py_DECREF(sock); - return NULL; + 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 (buf.len > INT_MAX) { + if (b->len > INT_MAX) { PyErr_Format(PyExc_OverflowError, "string longer than %d bytes", INT_MAX); goto error; } - /* just in case the blocking state of the socket has been changed */ - nonblocking = (sock->sock_timeout >= 0.0); - BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); - BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); + 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 = check_socket_and_wait_for_timeout(sock, 1); + sockstate = PySSL_select(sock, 1, timeout); if (sockstate == SOCKET_HAS_TIMED_OUT) { PyErr_SetString(PySocketModule.timeout_error, "The write operation timed out"); @@ -1602,21 +1806,27 @@ static PyObject *PySSL_SSLwrite(PySSLSocket *self, PyObject *args) "Underlying socket too large for select()."); goto error; } + do { PySSL_BEGIN_ALLOW_THREADS - len = SSL_write(self->ssl, buf.buf, (int)buf.len); + len = SSL_write(self->ssl, b->buf, (int)b->len); err = SSL_get_error(self->ssl, len); PySSL_END_ALLOW_THREADS - if (PyErr_CheckSignals()) { + + if (PyErr_CheckSignals()) goto error; - } + + if (has_timeout) + timeout = deadline - _PyTime_GetMonotonicClock(); + if (err == SSL_ERROR_WANT_READ) { - sockstate = check_socket_and_wait_for_timeout(sock, 0); + sockstate = PySSL_select(sock, 0, timeout); } else if (err == SSL_ERROR_WANT_WRITE) { - sockstate = check_socket_and_wait_for_timeout(sock, 1); + 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"); @@ -1630,26 +1840,26 @@ static PyObject *PySSL_SSLwrite(PySSLSocket *self, PyObject *args) } } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE); - Py_DECREF(sock); - PyBuffer_Release(&buf); + Py_XDECREF(sock); if (len > 0) return PyLong_FromLong(len); else return PySSL_SetError(self, len, __FILE__, __LINE__); error: - Py_DECREF(sock); - PyBuffer_Release(&buf); + Py_XDECREF(sock); return NULL; } -PyDoc_STRVAR(PySSL_SSLwrite_doc, -"write(s) -> len\n\ -\n\ -Writes the string s into the SSL object. Returns the number\n\ -of bytes written."); +/*[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 *PySSL_SSLpending(PySSLSocket *self) +static PyObject * +_ssl__SSLSocket_pending_impl(PySSLSocket *self) +/*[clinic end generated code: output=983d9fecdc308a83 input=2b77487d6dfd597f]*/ { int count = 0; @@ -1662,49 +1872,52 @@ static PyObject *PySSL_SSLpending(PySSLSocket *self) return PyLong_FromLong(count); } -PyDoc_STRVAR(PySSL_SSLpending_doc, -"pending() -> count\n\ -\n\ -Returns the number of already decrypted bytes available for read,\n\ -pending on the connection.\n"); +/*[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 *PySSL_SSLread(PySSLSocket *self, PyObject *args) +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; - Py_buffer buf; char *mem; - int len, count; - int buf_passed = 0; + int count; int sockstate; int err; int nonblocking; - PySocketSockObject *sock - = (PySocketSockObject *) PyWeakref_GetObject(self->Socket); - - if (((PyObject*)sock) == Py_None) { - _setSSLError("Underlying socket connection gone", - PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); - return NULL; + 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); } - Py_INCREF(sock); - - buf.obj = NULL; - buf.buf = NULL; - if (!PyArg_ParseTuple(args, "i|w*:read", &len, &buf)) - goto error; - if ((buf.buf == NULL) && (buf.obj == NULL)) { + if (!group_right_1) { dest = PyBytes_FromStringAndSize(NULL, len); if (dest == NULL) goto error; mem = PyBytes_AS_STRING(dest); } else { - buf_passed = 1; - mem = buf.buf; - if (len <= 0 || len > buf.len) { - len = (int) buf.len; - if (buf.len != len) { + 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; @@ -1712,51 +1925,43 @@ static PyObject *PySSL_SSLread(PySSLSocket *self, PyObject *args) } } - /* just in case the blocking state of the socket has been changed */ - nonblocking = (sock->sock_timeout >= 0.0); - BIO_set_nbio(SSL_get_rbio(self->ssl), nonblocking); - BIO_set_nbio(SSL_get_wbio(self->ssl), nonblocking); + 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); + } - /* first check if there are bytes ready to be read */ - PySSL_BEGIN_ALLOW_THREADS - count = SSL_pending(self->ssl); - PySSL_END_ALLOW_THREADS + timeout = GET_SOCKET_TIMEOUT(sock); + has_timeout = (timeout > 0); + if (has_timeout) + deadline = _PyTime_GetMonotonicClock() + timeout; - if (!count) { - sockstate = check_socket_and_wait_for_timeout(sock, 0); - if (sockstate == SOCKET_HAS_TIMED_OUT) { - PyErr_SetString(PySocketModule.timeout_error, - "The read 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_HAS_BEEN_CLOSED) { - count = 0; - goto done; - } - } do { PySSL_BEGIN_ALLOW_THREADS count = SSL_read(self->ssl, mem, len); err = SSL_get_error(self->ssl, count); PySSL_END_ALLOW_THREADS + if (PyErr_CheckSignals()) goto error; + + if (has_timeout) + timeout = deadline - _PyTime_GetMonotonicClock(); + if (err == SSL_ERROR_WANT_READ) { - sockstate = check_socket_and_wait_for_timeout(sock, 0); + sockstate = PySSL_select(sock, 0, timeout); } else if (err == SSL_ERROR_WANT_WRITE) { - sockstate = check_socket_and_wait_for_timeout(sock, 1); - } else if ((err == SSL_ERROR_ZERO_RETURN) && - (SSL_get_shutdown(self->ssl) == - SSL_RECEIVED_SHUTDOWN)) + sockstate = PySSL_select(sock, 1, timeout); + } else if (err == SSL_ERROR_ZERO_RETURN && + SSL_get_shutdown(self->ssl) == SSL_RECEIVED_SHUTDOWN) { count = 0; goto done; - } else { - sockstate = SOCKET_OPERATION_OK; } + else + sockstate = SOCKET_OPERATION_OK; + if (sockstate == SOCKET_HAS_TIMED_OUT) { PyErr_SetString(PySocketModule.timeout_error, "The read operation timed out"); @@ -1765,55 +1970,66 @@ static PyObject *PySSL_SSLread(PySSLSocket *self, PyObject *args) break; } } while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE); + if (count <= 0) { PySSL_SetError(self, count, __FILE__, __LINE__); goto error; } done: - Py_DECREF(sock); - if (!buf_passed) { + Py_XDECREF(sock); + if (!group_right_1) { _PyBytes_Resize(&dest, count); return dest; } else { - PyBuffer_Release(&buf); return PyLong_FromLong(count); } error: - Py_DECREF(sock); - if (!buf_passed) + Py_XDECREF(sock); + if (!group_right_1) Py_XDECREF(dest); - else - PyBuffer_Release(&buf); return NULL; } -PyDoc_STRVAR(PySSL_SSLread_doc, -"read([len]) -> string\n\ -\n\ -Read up to len bytes from the SSL socket."); +/*[clinic input] +_ssl._SSLSocket.shutdown + +Does the SSL shutdown handshake with the remote end. + +Returns the underlying socket object. +[clinic start generated code]*/ -static PyObject *PySSL_SSLshutdown(PySSLSocket *self) +static PyObject * +_ssl__SSLSocket_shutdown_impl(PySSLSocket *self) +/*[clinic end generated code: output=ca1aa7ed9d25ca42 input=ede2cc1a2ddf0ee4]*/ { int err, ssl_err, sockstate, nonblocking; int zeros = 0; - PySocketSockObject *sock - = (PySocketSockObject *) PyWeakref_GetObject(self->Socket); + 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 < 0)) { + _setSSLError("Underlying socket connection gone", + PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); + return NULL; + } + Py_INCREF(sock); - /* Guard against closed socket */ - if ((((PyObject*)sock) == Py_None) || (sock->sock_fd < 0)) { - _setSSLError("Underlying socket connection gone", - PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__); - return 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); } - Py_INCREF(sock); - /* Just in case the blocking state of the socket has been changed */ - nonblocking = (sock->sock_timeout >= 0.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 @@ -1829,6 +2045,7 @@ static PyObject *PySSL_SSLshutdown(PySSLSocket *self) SSL_set_read_ahead(self->ssl, 0); err = SSL_shutdown(self->ssl); PySSL_END_ALLOW_THREADS + /* If err == 1, a secure shutdown with SSL_shutdown() is complete */ if (err > 0) break; @@ -1843,14 +2060,18 @@ static PyObject *PySSL_SSLshutdown(PySSLSocket *self) continue; } + if (has_timeout) + timeout = deadline - _PyTime_GetMonotonicClock(); + /* Possibly retry shutdown until timeout or failure */ ssl_err = SSL_get_error(self->ssl, err); if (ssl_err == SSL_ERROR_WANT_READ) - sockstate = check_socket_and_wait_for_timeout(sock, 0); + sockstate = PySSL_select(sock, 0, timeout); else if (ssl_err == SSL_ERROR_WANT_WRITE) - sockstate = check_socket_and_wait_for_timeout(sock, 1); + sockstate = PySSL_select(sock, 1, timeout); else break; + if (sockstate == SOCKET_HAS_TIMED_OUT) { if (ssl_err == SSL_ERROR_WANT_READ) PyErr_SetString(PySocketModule.timeout_error, @@ -1871,27 +2092,31 @@ static PyObject *PySSL_SSLshutdown(PySSLSocket *self) } if (err < 0) { - Py_DECREF(sock); + Py_XDECREF(sock); return PySSL_SetError(self, err, __FILE__, __LINE__); } - else + if (sock) /* It's already INCREF'ed */ return (PyObject *) sock; + else + Py_RETURN_NONE; error: - Py_DECREF(sock); + Py_XDECREF(sock); return NULL; } -PyDoc_STRVAR(PySSL_SSLshutdown_doc, -"shutdown(s) -> socket\n\ -\n\ -Does the SSL shutdown handshake with the remote end, and returns\n\ -the underlying socket object."); +/*[clinic input] +_ssl._SSLSocket.tls_unique_cb + +Returns the 'tls-unique' channel binding data, as defined by RFC 5929. + +If the TLS handshake is not yet complete, None is returned. +[clinic start generated code]*/ -#if HAVE_OPENSSL_FINISHED static PyObject * -PySSL_tls_unique_cb(PySSLSocket *self) +_ssl__SSLSocket_tls_unique_cb_impl(PySSLSocket *self) +/*[clinic end generated code: output=f3a832d603f586af input=439525c7b3d8d34d]*/ { PyObject *retval = NULL; char buf[PySSL_CB_MAXLEN]; @@ -1915,42 +2140,32 @@ PySSL_tls_unique_cb(PySSLSocket *self) return retval; } -PyDoc_STRVAR(PySSL_tls_unique_cb_doc, -"tls_unique_cb() -> bytes\n\ -\n\ -Returns the 'tls-unique' channel binding data, as defined by RFC 5929.\n\ -\n\ -If the TLS handshake is not yet complete, None is returned"); - -#endif /* HAVE_OPENSSL_FINISHED */ - 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}, {NULL}, /* sentinel */ }; static PyMethodDef PySSLMethods[] = { - {"do_handshake", (PyCFunction)PySSL_SSLdo_handshake, METH_NOARGS}, - {"write", (PyCFunction)PySSL_SSLwrite, METH_VARARGS, - PySSL_SSLwrite_doc}, - {"read", (PyCFunction)PySSL_SSLread, METH_VARARGS, - PySSL_SSLread_doc}, - {"pending", (PyCFunction)PySSL_SSLpending, METH_NOARGS, - PySSL_SSLpending_doc}, - {"peer_certificate", (PyCFunction)PySSL_peercert, METH_VARARGS, - PySSL_peercert_doc}, - {"cipher", (PyCFunction)PySSL_cipher, METH_NOARGS}, -#ifdef OPENSSL_NPN_NEGOTIATED - {"selected_npn_protocol", (PyCFunction)PySSL_selected_npn_protocol, METH_NOARGS}, -#endif - {"compression", (PyCFunction)PySSL_compression, METH_NOARGS}, - {"shutdown", (PyCFunction)PySSL_SSLshutdown, METH_NOARGS, - PySSL_SSLshutdown_doc}, -#if HAVE_OPENSSL_FINISHED - {"tls_unique_cb", (PyCFunction)PySSL_tls_unique_cb, METH_NOARGS, - PySSL_tls_unique_cb_doc}, -#endif + _SSL__SSLSOCKET_DO_HANDSHAKE_METHODDEF + _SSL__SSLSOCKET_WRITE_METHODDEF + _SSL__SSLSOCKET_READ_METHODDEF + _SSL__SSLSOCKET_PENDING_METHODDEF + _SSL__SSLSOCKET_PEER_CERTIFICATE_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_TLS_UNIQUE_CB_METHODDEF {NULL, NULL} }; @@ -1993,19 +2208,21 @@ static PyTypeObject PySSLSocket_Type = { * _SSLContext objects */ +/*[clinic input] +@classmethod +_ssl._SSLContext.__new__ + protocol as proto_version: int + / +[clinic start generated code]*/ + static PyObject * -context_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +_ssl__SSLContext_impl(PyTypeObject *type, int proto_version) +/*[clinic end generated code: output=2cf0d7a0741b6bd1 input=8d58a805b95fc534]*/ { - char *kwlist[] = {"protocol", NULL}; PySSLContext *self; - int proto_version = PY_SSL_VERSION_SSL23; + long options; SSL_CTX *ctx = NULL; - if (!PyArg_ParseTupleAndKeywords( - args, kwds, "i:_SSLContext", kwlist, - &proto_version)) - return NULL; - PySSL_BEGIN_ALLOW_THREADS if (proto_version == PY_SSL_VERSION_TLS1) ctx = SSL_CTX_new(TLSv1_method()); @@ -2015,8 +2232,10 @@ context_new(PyTypeObject *type, PyObject *args, PyObject *kwds) else if (proto_version == PY_SSL_VERSION_TLS1_2) ctx = SSL_CTX_new(TLSv1_2_method()); #endif +#ifndef OPENSSL_NO_SSL3 else if (proto_version == PY_SSL_VERSION_SSL3) ctx = SSL_CTX_new(SSLv3_method()); +#endif #ifndef OPENSSL_NO_SSL2 else if (proto_version == PY_SSL_VERSION_SSL2) ctx = SSL_CTX_new(SSLv2_method()); @@ -2048,6 +2267,9 @@ context_new(PyTypeObject *type, PyObject *args, PyObject *kwds) #ifdef OPENSSL_NPN_NEGOTIATED self->npn_protocols = NULL; #endif +#ifdef HAVE_ALPN + self->alpn_protocols = NULL; +#endif #ifndef OPENSSL_NO_TLSEXT self->set_hostname = NULL; #endif @@ -2055,14 +2277,40 @@ context_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->check_hostname = 0; /* Defaults */ SSL_CTX_set_verify(self->ctx, SSL_VERIFY_NONE, NULL); - SSL_CTX_set_options(self->ctx, - SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); + options = SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; + if (proto_version != PY_SSL_VERSION_SSL2) + options |= SSL_OP_NO_SSLv2; + SSL_CTX_set_options(self->ctx, options); -#define SID_CTX "Python" +#ifndef OPENSSL_NO_ECDH + /* 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. */ +#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 +#ifdef X509_V_FLAG_TRUSTED_FIRST + { + /* Improve trust chain building when cross-signed intermediate + certificates are present. See https://bugs.python.org/issue23476. */ + X509_STORE *store = SSL_CTX_get_cert_store(self->ctx); + X509_STORE_set_flags(store, X509_V_FLAG_TRUSTED_FIRST); + } +#endif + return (PyObject *)self; } @@ -2090,20 +2338,25 @@ context_dealloc(PySSLContext *self) context_clear(self); SSL_CTX_free(self->ctx); #ifdef OPENSSL_NPN_NEGOTIATED - PyMem_Free(self->npn_protocols); + PyMem_FREE(self->npn_protocols); +#endif +#ifdef 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 * -set_ciphers(PySSLContext *self, PyObject *args) +_ssl__SSLContext_set_ciphers_impl(PySSLContext *self, const char *cipherlist) +/*[clinic end generated code: output=3a3162f3557c0f3f input=a7ac931b9f3ca7fc]*/ { - int ret; - const char *cipherlist; - - if (!PyArg_ParseTuple(args, "s:set_ciphers", &cipherlist)) - return NULL; - ret = SSL_CTX_set_cipher_list(self->ctx, cipherlist); + 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 @@ -2117,6 +2370,30 @@ set_ciphers(PySSLContext *self, PyObject *args) } #ifdef OPENSSL_NPN_NEGOTIATED +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; +} + /* this callback gets passed to SSL_CTX_set_next_protos_advertise_cb */ static int _advertiseNPN_cb(SSL *s, @@ -2126,10 +2403,10 @@ _advertiseNPN_cb(SSL *s, PySSLContext *ssl_ctx = (PySSLContext *) args; if (ssl_ctx->npn_protocols == NULL) { - *data = (unsigned char *) ""; + *data = (unsigned char *)""; *len = 0; } else { - *data = (unsigned char *) ssl_ctx->npn_protocols; + *data = ssl_ctx->npn_protocols; *len = ssl_ctx->npn_protocols_len; } @@ -2142,46 +2419,30 @@ _selectNPN_cb(SSL *s, const unsigned char *server, unsigned int server_len, void *args) { - PySSLContext *ssl_ctx = (PySSLContext *) args; - - unsigned char *client = (unsigned char *) ssl_ctx->npn_protocols; - int client_len; - - if (client == NULL) { - client = (unsigned char *) ""; - client_len = 0; - } else { - client_len = ssl_ctx->npn_protocols_len; - } - - SSL_select_next_proto(out, outlen, - server, server_len, - client, client_len); - - return SSL_TLSEXT_ERR_OK; + 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 * -_set_npn_protocols(PySSLContext *self, PyObject *args) +_ssl__SSLContext__set_npn_protocols_impl(PySSLContext *self, + Py_buffer *protos) +/*[clinic end generated code: output=72b002c3324390c6 input=319fcb66abf95bd7]*/ { #ifdef OPENSSL_NPN_NEGOTIATED - Py_buffer protos; - - if (!PyArg_ParseTuple(args, "y*:set_npn_protocols", &protos)) - return NULL; - - if (self->npn_protocols != NULL) { - PyMem_Free(self->npn_protocols); - } - - self->npn_protocols = PyMem_Malloc(protos.len); - if (self->npn_protocols == NULL) { - PyBuffer_Release(&protos); + 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; + 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 */ @@ -2192,7 +2453,6 @@ _set_npn_protocols(PySSLContext *self, PyObject *args) _selectNPN_cb, self); - PyBuffer_Release(&protos); Py_RETURN_NONE; #else PyErr_SetString(PyExc_NotImplementedError, @@ -2201,6 +2461,51 @@ _set_npn_protocols(PySSLContext *self, PyObject *args) #endif } +#ifdef 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]*/ +{ +#ifdef HAVE_ALPN + 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 = 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) { @@ -2244,7 +2549,6 @@ set_verify_mode(PySSLContext *self, PyObject *arg, void *c) return 0; } -#ifdef HAVE_OPENSSL_VERIFY_PARAM static PyObject * get_verify_flags(PySSLContext *self, void *c) { @@ -2282,7 +2586,6 @@ set_verify_flags(PySSLContext *self, PyObject *arg, void *c) } return 0; } -#endif static PyObject * get_options(PySSLContext *self, void *c) @@ -2439,11 +2742,19 @@ _password_callback(char *buf, int size, int rwflag, void *userdata) return -1; } +/*[clinic input] +_ssl._SSLContext.load_cert_chain + certfile: object + keyfile: object = NULL + password: object = NULL + +[clinic start generated code]*/ + static PyObject * -load_cert_chain(PySSLContext *self, PyObject *args, PyObject *kwds) +_ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, + PyObject *keyfile, PyObject *password) +/*[clinic end generated code: output=9480bc1c380e2095 input=7cf9ac673cbee6fc]*/ { - char *kwlist[] = {"certfile", "keyfile", "password", NULL}; - PyObject *certfile, *keyfile = NULL, *password = NULL; PyObject *certfile_bytes = NULL, *keyfile_bytes = NULL; pem_password_cb *orig_passwd_cb = self->ctx->default_passwd_callback; void *orig_passwd_userdata = self->ctx->default_passwd_callback_userdata; @@ -2452,10 +2763,6 @@ load_cert_chain(PySSLContext *self, PyObject *args, PyObject *kwds) errno = 0; ERR_clear_error(); - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "O|OO:load_cert_chain", kwlist, - &certfile, &keyfile, &password)) - return NULL; if (keyfile == Py_None) keyfile = NULL; if (!PyUnicode_FSConverter(certfile, &certfile_bytes)) { @@ -2623,21 +2930,26 @@ _add_ca_certs(PySSLContext *self, void *data, Py_ssize_t len, } +/*[clinic input] +_ssl._SSLContext.load_verify_locations + cafile: object = NULL + capath: object = NULL + cadata: object = NULL + +[clinic start generated code]*/ + static PyObject * -load_verify_locations(PySSLContext *self, PyObject *args, PyObject *kwds) +_ssl__SSLContext_load_verify_locations_impl(PySSLContext *self, + PyObject *cafile, + PyObject *capath, + PyObject *cadata) +/*[clinic end generated code: output=454c7e41230ca551 input=997f1fb3a784ef88]*/ { - char *kwlist[] = {"cafile", "capath", "cadata", NULL}; - PyObject *cafile = NULL, *capath = NULL, *cadata = NULL; PyObject *cafile_bytes = NULL, *capath_bytes = NULL; const char *cafile_buf = NULL, *capath_buf = NULL; int r = 0, ok = 1; errno = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "|OOO:load_verify_locations", kwlist, - &cafile, &capath, &cadata)) - return NULL; - if (cafile == Py_None) cafile = NULL; if (capath == Py_None) @@ -2734,18 +3046,24 @@ load_verify_locations(PySSLContext *self, PyObject *args, PyObject *kwds) } } +/*[clinic input] +_ssl._SSLContext.load_dh_params + path as filepath: object + / + +[clinic start generated code]*/ + static PyObject * -load_dh_params(PySSLContext *self, PyObject *filepath) +_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) { - if (!PyErr_Occurred()) - PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, filepath); + if (f == NULL) return NULL; - } + errno = 0; PySSL_BEGIN_ALLOW_THREADS dh = PEM_read_DHparams(f, NULL, NULL, NULL); @@ -2767,44 +3085,76 @@ load_dh_params(PySSLContext *self, PyObject *filepath) 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 + +[clinic start generated code]*/ + static PyObject * -context_wrap_socket(PySSLContext *self, PyObject *args, PyObject *kwds) +_ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock, + int server_side, PyObject *hostname_obj) +/*[clinic end generated code: output=6973e4b60995e933 input=83859b9156ddfc63]*/ { - char *kwlist[] = {"sock", "server_side", "server_hostname", NULL}; - PySocketSockObject *sock; - int server_side = 0; char *hostname = NULL; - PyObject *hostname_obj, *res; + PyObject *res; /* server_hostname is either None (or absent), or to be encoded using the idna encoding. */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!i|O!:_wrap_socket", kwlist, - PySocketModule.Sock_Type, - &sock, &server_side, - Py_TYPE(Py_None), &hostname_obj)) { - PyErr_Clear(); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!iet:_wrap_socket", kwlist, - PySocketModule.Sock_Type, - &sock, &server_side, - "idna", &hostname)) + if (hostname_obj != Py_None) { + if (!PyArg_Parse(hostname_obj, "et", "idna", &hostname)) return NULL; -#if !HAVE_SNI - PyMem_Free(hostname); - PyErr_SetString(PyExc_ValueError, "server_hostname is not supported " - "by your OpenSSL library"); - return NULL; -#endif } - res = (PyObject *) newPySSLSocket(self, sock, server_side, - hostname); + res = (PyObject *) newPySSLSocket(self, (PySocketSockObject *)sock, + server_side, hostname, + 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 + +[clinic start generated code]*/ + +static PyObject * +_ssl__SSLContext__wrap_bio_impl(PySSLContext *self, PySSLMemoryBIO *incoming, + PySSLMemoryBIO *outgoing, int server_side, + PyObject *hostname_obj) +/*[clinic end generated code: output=4fe4ba75ad95940d input=17725ecdac0bf220]*/ +{ + char *hostname = NULL; + PyObject *res; + + /* server_hostname is either None (or absent), or to be encoded + using the idna encoding. */ + if (hostname_obj != Py_None) { + if (!PyArg_Parse(hostname_obj, "et", "idna", &hostname)) + return NULL; + } + + res = (PyObject *) newPySSLSocket(self, NULL, server_side, hostname, + incoming, outgoing); + + PyMem_Free(hostname); + return res; +} + +/*[clinic input] +_ssl._SSLContext.session_stats +[clinic start generated code]*/ + static PyObject * -session_stats(PySSLContext *self, PyObject *unused) +_ssl__SSLContext_session_stats_impl(PySSLContext *self) +/*[clinic end generated code: output=0d96411c42893bfb input=7e0a81fb11102c8b]*/ { int r; PyObject *value, *stats = PyDict_New(); @@ -2842,8 +3192,13 @@ session_stats(PySSLContext *self, PyObject *unused) return NULL; } +/*[clinic input] +_ssl._SSLContext.set_default_verify_paths +[clinic start generated code]*/ + static PyObject * -set_default_verify_paths(PySSLContext *self, PyObject *unused) +_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__); @@ -2853,8 +3208,16 @@ set_default_verify_paths(PySSLContext *self, PyObject *unused) } #ifndef OPENSSL_NO_ECDH +/*[clinic input] +_ssl._SSLContext.set_ecdh_curve + name: object + / + +[clinic start generated code]*/ + static PyObject * -set_ecdh_curve(PySSLContext *self, PyObject *name) +_ssl__SSLContext_set_ecdh_curve(PySSLContext *self, PyObject *name) +/*[clinic end generated code: output=23022c196e40d7d2 input=c2bafb6f6e34726b]*/ { PyObject *name_bytes; int nid; @@ -2909,11 +3272,25 @@ _servername_callback(SSL *s, int *al, void *args) ssl = SSL_get_app_data(s); assert(PySSLSocket_Check(ssl)); - ssl_socket = PyWeakref_GetObject(ssl->Socket); + + /* The servername callback expects a 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) { + if (ssl_socket == Py_None) goto error; - } if (servername == NULL) { result = PyObject_CallFunctionObjArgs(ssl_ctx->set_hostname, ssl_socket, @@ -2974,25 +3351,23 @@ _servername_callback(SSL *s, int *al, void *args) } #endif -PyDoc_STRVAR(PySSL_set_servername_callback_doc, -"set_servername_callback(method)\n\ -\n\ -This sets a callback that will be called when a server name is provided by\n\ -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.set_servername_callback + method as cb: object + / + +Set a callback that will be called when a server name is provided by the SSL/TLS client in the SNI extension. + +If the argument is None then the callback is disabled. The method is called +with the SSLSocket, the server name as a string, and the SSLContext object. +See RFC 6066 for details of the SNI extension. +[clinic start generated code]*/ static PyObject * -set_servername_callback(PySSLContext *self, PyObject *args) +_ssl__SSLContext_set_servername_callback(PySSLContext *self, PyObject *cb) +/*[clinic end generated code: output=3439a1b2d5d3b7ea input=a2a83620197d602b]*/ { #if HAVE_SNI && !defined(OPENSSL_NO_TLSEXT) - PyObject *cb; - - if (!PyArg_ParseTuple(args, "O", &cb)) - return NULL; - Py_CLEAR(self->set_hostname); if (cb == Py_None) { SSL_CTX_set_tlsext_servername_callback(self->ctx, NULL); @@ -3019,17 +3394,21 @@ set_servername_callback(PySSLContext *self, PyObject *args) #endif } -PyDoc_STRVAR(PySSL_get_stats_doc, -"cert_store_stats() -> {'crl': int, 'x509_ca': int, 'x509': int}\n\ -\n\ -Returns quantities of loaded X.509 certificates. X.509 certificates with a\n\ -CA extension and certificate revocation lists inside the context's cert\n\ -store.\n\ -NOTE: Certificates in a capath directory aren't loaded unless they have\n\ -been used at least once."); +/*[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 * -cert_store_stats(PySSLContext *self) +_ssl__SSLContext_cert_store_stats_impl(PySSLContext *self) +/*[clinic end generated code: output=5f356f4d9cca874d input=eb40dd0f6d0e40cf]*/ { X509_STORE *store; X509_OBJECT *obj; @@ -3062,27 +3441,26 @@ cert_store_stats(PySSLContext *self) "x509_ca", ca); } -PyDoc_STRVAR(PySSL_get_ca_certs_doc, -"get_ca_certs(binary_form=False) -> list of loaded certificate\n\ -\n\ -Returns a list of dicts with information of loaded CA certs. If the\n\ -optional argument is True, returns a DER-encoded copy of the CA certificate.\n\ -NOTE: Certificates in a capath directory aren't loaded unless they have\n\ -been used at least once."); +/*[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 * -get_ca_certs(PySSLContext *self, PyObject *args, PyObject *kwds) +_ssl__SSLContext_get_ca_certs_impl(PySSLContext *self, int binary_form) +/*[clinic end generated code: output=0d58f148f37e2938 input=6887b5a09b7f9076]*/ { - char *kwlist[] = {"binary_form", NULL}; X509_STORE *store; PyObject *ci = NULL, *rlist = NULL; int i; - int binary_mode = 0; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|p:get_ca_certs", - kwlist, &binary_mode)) { - return NULL; - } if ((rlist = PyList_New(0)) == NULL) { return NULL; @@ -3103,7 +3481,7 @@ get_ca_certs(PySSLContext *self, PyObject *args, PyObject *kwds) if (!X509_check_ca(cert)) { continue; } - if (binary_mode) { + if (binary_form) { ci = _certificate_to_der(cert); } else { ci = _decode_certificate(cert); @@ -3130,42 +3508,28 @@ static PyGetSetDef context_getsetlist[] = { (setter) set_check_hostname, NULL}, {"options", (getter) get_options, (setter) set_options, NULL}, -#ifdef HAVE_OPENSSL_VERIFY_PARAM {"verify_flags", (getter) get_verify_flags, (setter) set_verify_flags, NULL}, -#endif {"verify_mode", (getter) get_verify_mode, (setter) set_verify_mode, NULL}, {NULL}, /* sentinel */ }; static struct PyMethodDef context_methods[] = { - {"_wrap_socket", (PyCFunction) context_wrap_socket, - METH_VARARGS | METH_KEYWORDS, NULL}, - {"set_ciphers", (PyCFunction) set_ciphers, - METH_VARARGS, NULL}, - {"_set_npn_protocols", (PyCFunction) _set_npn_protocols, - METH_VARARGS, NULL}, - {"load_cert_chain", (PyCFunction) load_cert_chain, - METH_VARARGS | METH_KEYWORDS, NULL}, - {"load_dh_params", (PyCFunction) load_dh_params, - METH_O, NULL}, - {"load_verify_locations", (PyCFunction) load_verify_locations, - METH_VARARGS | METH_KEYWORDS, NULL}, - {"session_stats", (PyCFunction) session_stats, - METH_NOARGS, NULL}, - {"set_default_verify_paths", (PyCFunction) set_default_verify_paths, - METH_NOARGS, NULL}, -#ifndef OPENSSL_NO_ECDH - {"set_ecdh_curve", (PyCFunction) set_ecdh_curve, - METH_O, NULL}, -#endif - {"set_servername_callback", (PyCFunction) set_servername_callback, - METH_VARARGS, PySSL_set_servername_callback_doc}, - {"cert_store_stats", (PyCFunction) cert_store_stats, - METH_NOARGS, PySSL_get_stats_doc}, - {"get_ca_certs", (PyCFunction) get_ca_certs, - METH_VARARGS | METH_KEYWORDS, PySSL_get_ca_certs_doc}, + _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_SET_SERVERNAME_CALLBACK_METHODDEF + _SSL__SSLCONTEXT_CERT_STORE_STATS_METHODDEF + _SSL__SSLCONTEXT_GET_CA_CERTS_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -3207,34 +3571,262 @@ static PyTypeObject PySSLContext_Type = { 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ - context_new, /*tp_new*/ + _ssl__SSLContext, /*tp_new*/ }; +/* + * MemoryBIO objects + */ -#ifdef HAVE_OPENSSL_RAND +/*[clinic input] +@classmethod +_ssl.MemoryBIO.__new__ + +[clinic start generated code]*/ -/* helper routines for seeding the SSL PRNG */ static PyObject * -PySSL_RAND_add(PyObject *self, PyObject *args) +_ssl_MemoryBIO_impl(PyTypeObject *type) +/*[clinic end generated code: output=8820a58db78330ac input=26d22e4909ecb1b5]*/ { - char *buf; - int len; - double entropy; + BIO *bio; + PySSLMemoryBIO *self; - if (!PyArg_ParseTuple(args, "s#d:RAND_add", &buf, &len, &entropy)) + 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; - RAND_add(buf, len, entropy); + } + 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_FromLong(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 = BIO_ctrl_pending(self->bio); + 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); + /* There should never be any short reads but check anyway. */ + if ((nbytes < len) && (_PyBytes_Resize(&result, len) < 0)) { + Py_DECREF(result); + return NULL; + } + + 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, 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_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_reserved*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + 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*/ +}; + + +/* 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 1750. +[clinic start generated code]*/ + +static PyObject * +_ssl_RAND_add_impl(PyModuleDef *module, Py_buffer *view, double entropy) +/*[clinic end generated code: output=0f8d5c8cce328958 input=580c85e6a3a4fe29]*/ +{ + 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_INCREF(Py_None); return Py_None; } -PyDoc_STRVAR(PySSL_RAND_add_doc, -"RAND_add(string, entropy)\n\ -\n\ -Mix string into the OpenSSL PRNG state. entropy (a float) is a lower\n\ -bound on the entropy contained in string. See RFC 1750."); - static PyObject * PySSL_RAND(int len, int pseudo) { @@ -3244,6 +3836,11 @@ PySSL_RAND(int len, int pseudo) 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; @@ -3269,59 +3866,72 @@ PySSL_RAND(int len, int pseudo) return NULL; } +/*[clinic input] +_ssl.RAND_bytes + n: int + / + +Generate n cryptographically strong pseudo-random bytes. +[clinic start generated code]*/ + static PyObject * -PySSL_RAND_bytes(PyObject *self, PyObject *args) +_ssl_RAND_bytes_impl(PyModuleDef *module, int n) +/*[clinic end generated code: output=7d8741bdc1d435f3 input=678ddf2872dfebfc]*/ { - int len; - if (!PyArg_ParseTuple(args, "i:RAND_bytes", &len)) - return NULL; - return PySSL_RAND(len, 0); + return PySSL_RAND(n, 0); } -PyDoc_STRVAR(PySSL_RAND_bytes_doc, -"RAND_bytes(n) -> bytes\n\ -\n\ -Generate n cryptographically strong pseudo-random bytes."); +/*[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 * -PySSL_RAND_pseudo_bytes(PyObject *self, PyObject *args) +_ssl_RAND_pseudo_bytes_impl(PyModuleDef *module, int n) +/*[clinic end generated code: output=dd673813107f3875 input=58312bd53f9bbdd0]*/ { - int len; - if (!PyArg_ParseTuple(args, "i:RAND_pseudo_bytes", &len)) - return NULL; - return PySSL_RAND(len, 1); + return PySSL_RAND(n, 1); } -PyDoc_STRVAR(PySSL_RAND_pseudo_bytes_doc, -"RAND_pseudo_bytes(n) -> (bytes, is_cryptographic)\n\ -\n\ -Generate n pseudo-random bytes. is_cryptographic is True if the bytes\ -generated are cryptographically strong."); +/*[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 * -PySSL_RAND_status(PyObject *self) +_ssl_RAND_status_impl(PyModuleDef *module) +/*[clinic end generated code: output=7f7ef57bc7dd1d1c input=8a774b02d1dc81f3]*/ { return PyLong_FromLong(RAND_status()); } -PyDoc_STRVAR(PySSL_RAND_status_doc, -"RAND_status() -> 0 or 1\n\ -\n\ -Returns 1 if the OpenSSL PRNG has been seeded with enough data and 0 if not.\n\ -It is necessary to seed the PRNG with RAND_add() on some platforms before\n\ -using the ssl() function."); +#ifdef HAVE_RAND_EGD +/*[clinic input] +_ssl.RAND_egd + path: object(converter="PyUnicode_FSConverter") + / -static PyObject * -PySSL_RAND_egd(PyObject *self, PyObject *args) -{ - PyObject *path; - int bytes; +Queries the entropy gather daemon (EGD) on the socket named by 'path'. - if (!PyArg_ParseTuple(args, "O&:RAND_egd", - PyUnicode_FSConverter, &path)) - return NULL; +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]*/ - bytes = RAND_egd(PyBytes_AsString(path)); +static PyObject * +_ssl_RAND_egd_impl(PyModuleDef *module, PyObject *path) +/*[clinic end generated code: output=8e728e501e28541b input=1aeb7eb948312195]*/ +{ + int bytes = RAND_egd(PyBytes_AsString(path)); Py_DECREF(path); if (bytes == -1) { PyErr_SetString(PySSLErrorObject, @@ -3331,46 +3941,41 @@ PySSL_RAND_egd(PyObject *self, PyObject *args) } return PyLong_FromLong(bytes); } +#endif /* HAVE_RAND_EGD */ -PyDoc_STRVAR(PySSL_RAND_egd_doc, -"RAND_egd(path) -> bytes\n\ -\n\ -Queries the entropy gather daemon (EGD) on the socket named by 'path'.\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."); -#endif /* HAVE_OPENSSL_RAND */ +/*[clinic input] +_ssl.get_default_verify_paths -PyDoc_STRVAR(PySSL_get_default_verify_paths_doc, -"get_default_verify_paths() -> tuple\n\ -\n\ -Return search paths and environment vars that are used by SSLContext's\n\ -set_default_verify_paths() to load default CAs. The values are\n\ -'cert_file_env', 'cert_file', 'cert_dir_env', 'cert_dir'."); +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 * -PySSL_get_default_verify_paths(PyObject *self) +_ssl_get_default_verify_paths_impl(PyModuleDef *module) +/*[clinic end generated code: output=5a2820ce7e3304d3 input=5210c953d98c3eb5]*/ { PyObject *ofile_env = NULL; PyObject *ofile = NULL; PyObject *odir_env = NULL; PyObject *odir = NULL; -#define convert(info, target) { \ +#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; \ - } while(0) + } - 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 + 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); @@ -3388,7 +3993,7 @@ asn1obj2py(ASN1_OBJECT *obj) int nid; const char *ln, *sn; char buf[100]; - int buflen; + Py_ssize_t buflen; nid = OBJ_obj2nid(obj); if (nid == NID_undef) { @@ -3409,26 +4014,24 @@ asn1obj2py(ASN1_OBJECT *obj) } } -PyDoc_STRVAR(PySSL_txt2obj_doc, -"txt2obj(txt, name=False) -> (nid, shortname, longname, oid)\n\ -\n\ -Lookup NID, short name, long name and OID of an ASN1_OBJECT. By default\n\ -objects are looked up by OID. With name=True short and long name are also\n\ -matched."); +/*[clinic input] +_ssl.txt2obj + txt: str + name: bool = False -static PyObject* -PySSL_txt2obj(PyObject *self, PyObject *args, PyObject *kwds) +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(PyModuleDef *module, const char *txt, int name) +/*[clinic end generated code: output=2ae2c30531b8809f input=1c1e7d0aa7c48602]*/ { - char *kwlist[] = {"txt", "name", NULL}; PyObject *result = NULL; - char *txt; - int name = 0; ASN1_OBJECT *obj; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|p:txt2obj", - kwlist, &txt, &name)) { - return NULL; - } obj = OBJ_txt2obj(txt, name ? 0 : 1); if (obj == NULL) { PyErr_Format(PyExc_ValueError, "unknown object '%.100s'", txt); @@ -3439,21 +4042,21 @@ PySSL_txt2obj(PyObject *self, PyObject *args, PyObject *kwds) return result; } -PyDoc_STRVAR(PySSL_nid2obj_doc, -"nid2obj(nid) -> (nid, shortname, longname, oid)\n\ -\n\ -Lookup NID, short name, long name and OID of an ASN1_OBJECT by NID."); +/*[clinic input] +_ssl.nid2obj + nid: int + / -static PyObject* -PySSL_nid2obj(PyObject *self, PyObject *args) +Lookup NID, short name, long name and OID of an ASN1_OBJECT by NID. +[clinic start generated code]*/ + +static PyObject * +_ssl_nid2obj_impl(PyModuleDef *module, int nid) +/*[clinic end generated code: output=8db1df89e44badb8 input=51787a3bee7d8f98]*/ { PyObject *result = NULL; - int nid; ASN1_OBJECT *obj; - if (!PyArg_ParseTuple(args, "i:nid2obj", &nid)) { - return NULL; - } if (nid < NID_undef) { PyErr_SetString(PyExc_ValueError, "NID must be positive."); return NULL; @@ -3553,30 +4156,28 @@ parseKeyUsage(PCCERT_CONTEXT pCertCtx, DWORD flags) return retval; } -PyDoc_STRVAR(PySSL_enum_certificates_doc, -"enum_certificates(store_name) -> []\n\ -\n\ -Retrieve certificates from Windows' cert store. store_name may be one of\n\ -'CA', 'ROOT' or 'MY'. The system may provide more cert storages, too.\n\ -The function returns a list of (bytes, encoding_type, trust) tuples. The\n\ -encoding_type flag can be interpreted with X509_ASN_ENCODING or\n\ -PKCS_7_ASN_ENCODING. The trust setting is either a set of OIDs or the\n\ -boolean True."); +/*[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 * -PySSL_enum_certificates(PyObject *self, PyObject *args, PyObject *kwds) +_ssl_enum_certificates_impl(PyModuleDef *module, const char *store_name) +/*[clinic end generated code: output=cc4ebc10b8adacfc input=915f60d70461ea4e]*/ { - char *kwlist[] = {"store_name", NULL}; - char *store_name; HCERTSTORE hStore = NULL; PCCERT_CONTEXT pCertCtx = NULL; PyObject *keyusage = NULL, *cert = NULL, *enc = NULL, *tup = NULL; PyObject *result = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s:enum_certificates", - kwlist, &store_name)) { - return NULL; - } result = PyList_New(0); if (result == NULL) { return NULL; @@ -3642,29 +4243,27 @@ PySSL_enum_certificates(PyObject *self, PyObject *args, PyObject *kwds) return result; } -PyDoc_STRVAR(PySSL_enum_crls_doc, -"enum_crls(store_name) -> []\n\ -\n\ -Retrieve CRLs from Windows' cert store. store_name may be one of\n\ -'CA', 'ROOT' or 'MY'. The system may provide more cert storages, too.\n\ -The function returns a list of (bytes, encoding_type) tuples. The\n\ -encoding_type flag can be interpreted with X509_ASN_ENCODING or\n\ -PKCS_7_ASN_ENCODING."); +/*[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 * -PySSL_enum_crls(PyObject *self, PyObject *args, PyObject *kwds) +_ssl_enum_crls_impl(PyModuleDef *module, const char *store_name) +/*[clinic end generated code: output=763490a2aa1c50d5 input=a1f1d7629f1c5d3d]*/ { - char *kwlist[] = {"store_name", NULL}; - char *store_name; HCERTSTORE hStore = NULL; PCCRL_CONTEXT pCrlCtx = NULL; PyObject *crl = NULL, *enc = NULL, *tup = NULL; PyObject *result = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|s:enum_crls", - kwlist, &store_name)) { - return NULL; - } result = PyList_New(0); if (result == NULL) { return NULL; @@ -3722,34 +4321,18 @@ PySSL_enum_crls(PyObject *self, PyObject *args, PyObject *kwds) #endif /* _MSC_VER */ /* List of functions exported by this module. */ - static PyMethodDef PySSL_methods[] = { - {"_test_decode_cert", PySSL_test_decode_certificate, - METH_VARARGS}, -#ifdef HAVE_OPENSSL_RAND - {"RAND_add", PySSL_RAND_add, METH_VARARGS, - PySSL_RAND_add_doc}, - {"RAND_bytes", PySSL_RAND_bytes, METH_VARARGS, - PySSL_RAND_bytes_doc}, - {"RAND_pseudo_bytes", PySSL_RAND_pseudo_bytes, METH_VARARGS, - PySSL_RAND_pseudo_bytes_doc}, - {"RAND_egd", PySSL_RAND_egd, METH_VARARGS, - PySSL_RAND_egd_doc}, - {"RAND_status", (PyCFunction)PySSL_RAND_status, METH_NOARGS, - PySSL_RAND_status_doc}, -#endif - {"get_default_verify_paths", (PyCFunction)PySSL_get_default_verify_paths, - METH_NOARGS, PySSL_get_default_verify_paths_doc}, -#ifdef _MSC_VER - {"enum_certificates", (PyCFunction)PySSL_enum_certificates, - METH_VARARGS | METH_KEYWORDS, PySSL_enum_certificates_doc}, - {"enum_crls", (PyCFunction)PySSL_enum_crls, - METH_VARARGS | METH_KEYWORDS, PySSL_enum_crls_doc}, -#endif - {"txt2obj", (PyCFunction)PySSL_txt2obj, - METH_VARARGS | METH_KEYWORDS, PySSL_txt2obj_doc}, - {"nid2obj", (PyCFunction)PySSL_nid2obj, - METH_VARARGS, PySSL_nid2obj_doc}, + _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 */ }; @@ -3810,10 +4393,11 @@ static int _setup_ssl_threads(void) { if (_ssl_locks == NULL) { _ssl_locks_count = CRYPTO_num_locks(); - _ssl_locks = (PyThread_type_lock *) - PyMem_Malloc(sizeof(PyThread_type_lock) * _ssl_locks_count); - if (_ssl_locks == NULL) + _ssl_locks = PyMem_New(PyThread_type_lock, _ssl_locks_count); + if (_ssl_locks == NULL) { + PyErr_NoMemory(); return 0; + } memset(_ssl_locks, 0, sizeof(PyThread_type_lock) * _ssl_locks_count); for (i = 0; i < _ssl_locks_count; i++) { @@ -3888,6 +4472,8 @@ PyInit__ssl(void) return NULL; if (PyType_Ready(&PySSLSocket_Type) < 0) return NULL; + if (PyType_Ready(&PySSLMemoryBIO_Type) < 0) + return NULL; m = PyModule_Create(&_sslmodule); if (m == NULL) @@ -3951,6 +4537,9 @@ PyInit__ssl(void) if (PyDict_SetItemString(d, "_SSLSocket", (PyObject *)&PySSLSocket_Type) != 0) return NULL; + if (PyDict_SetItemString(d, "MemoryBIO", + (PyObject *)&PySSLMemoryBIO_Type) != 0) + return NULL; PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN", PY_SSL_ERROR_ZERO_RETURN); PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ", @@ -3986,6 +4575,10 @@ PyInit__ssl(void) 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 */ @@ -4043,8 +4636,10 @@ PyInit__ssl(void) 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_SSL23); PyModule_AddIntConstant(m, "PROTOCOL_TLSv1", @@ -4085,11 +4680,7 @@ PyInit__ssl(void) Py_INCREF(r); PyModule_AddObject(m, "HAS_SNI", r); -#if HAVE_OPENSSL_FINISHED r = Py_True; -#else - r = Py_False; -#endif Py_INCREF(r); PyModule_AddObject(m, "HAS_TLS_UNIQUE", r); @@ -4109,6 +4700,14 @@ PyInit__ssl(void) Py_INCREF(r); PyModule_AddObject(m, "HAS_NPN", r); +#ifdef HAVE_ALPN + r = Py_True; +#else + r = Py_False; +#endif + Py_INCREF(r); + PyModule_AddObject(m, "HAS_ALPN", r); + /* Mappings for error codes */ err_codes_to_names = PyDict_New(); err_names_to_codes = PyDict_New(); diff --git a/Modules/_ssl_data.h b/Modules/_ssl_data.h index 81a8d7ba169e..85165b90bc38 100644 --- a/Modules/_ssl_data.h +++ b/Modules/_ssl_data.h @@ -1,5 +1,5 @@ /* File generated by Tools/ssl/make_ssl_data.py */ -/* Generated on 2012-05-16T23:56:40.981382 */ +/* Generated on 2015-01-17T20:33:43.377453 */ static struct py_ssl_library_code library_codes[] = { {"PEM", ERR_LIB_PEM}, @@ -179,6 +179,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"BAD_CHECKSUM", ERR_LIB_SSL, 104}, #endif + #ifdef SSL_R_BAD_DATA + {"BAD_DATA", ERR_LIB_SSL, SSL_R_BAD_DATA}, + #else + {"BAD_DATA", ERR_LIB_SSL, 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 @@ -309,6 +314,46 @@ static struct py_ssl_error_code error_codes[] = { #else {"BAD_SIGNATURE", ERR_LIB_SSL, 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", ERR_LIB_SSL, 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", ERR_LIB_SSL, 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", ERR_LIB_SSL, 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", ERR_LIB_SSL, 350}, + #endif + #ifdef SSL_R_BAD_SRP_PARAMETERS + {"BAD_SRP_PARAMETERS", ERR_LIB_SSL, SSL_R_BAD_SRP_PARAMETERS}, + #else + {"BAD_SRP_PARAMETERS", ERR_LIB_SSL, 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", ERR_LIB_SSL, 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", ERR_LIB_SSL, 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", ERR_LIB_SSL, 353}, + #endif #ifdef SSL_R_BAD_SSL_FILETYPE {"BAD_SSL_FILETYPE", ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE}, #else @@ -324,6 +369,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"BAD_STATE", ERR_LIB_SSL, 126}, #endif + #ifdef SSL_R_BAD_VALUE + {"BAD_VALUE", ERR_LIB_SSL, SSL_R_BAD_VALUE}, + #else + {"BAD_VALUE", ERR_LIB_SSL, 384}, + #endif #ifdef SSL_R_BAD_WRITE_RETRY {"BAD_WRITE_RETRY", ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY}, #else @@ -354,6 +404,16 @@ static struct py_ssl_error_code error_codes[] = { #else {"CA_DN_TOO_LONG", ERR_LIB_SSL, 132}, #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", ERR_LIB_SSL, 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", ERR_LIB_SSL, 398}, + #endif #ifdef SSL_R_CCS_RECEIVED_EARLY {"CCS_RECEIVED_EARLY", ERR_LIB_SSL, SSL_R_CCS_RECEIVED_EARLY}, #else @@ -364,6 +424,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"CERTIFICATE_VERIFY_FAILED", ERR_LIB_SSL, 134}, #endif + #ifdef SSL_R_CERT_CB_ERROR + {"CERT_CB_ERROR", ERR_LIB_SSL, SSL_R_CERT_CB_ERROR}, + #else + {"CERT_CB_ERROR", ERR_LIB_SSL, 377}, + #endif #ifdef SSL_R_CERT_LENGTH_MISMATCH {"CERT_LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_CERT_LENGTH_MISMATCH}, #else @@ -454,6 +519,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"DECRYPTION_FAILED_OR_BAD_RECORD_MAC", ERR_LIB_SSL, 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", ERR_LIB_SSL, 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 @@ -494,11 +564,26 @@ static struct py_ssl_error_code error_codes[] = { #else {"ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE", ERR_LIB_SSL, 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", ERR_LIB_SSL, 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", ERR_LIB_SSL, 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", ERR_LIB_SSL, 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", ERR_LIB_SSL, 354}, + #endif #ifdef SSL_R_ENCRYPTED_LENGTH_TOO_LONG {"ENCRYPTED_LENGTH_TOO_LONG", ERR_LIB_SSL, SSL_R_ENCRYPTED_LENGTH_TOO_LONG}, #else @@ -529,6 +614,16 @@ static struct py_ssl_error_code error_codes[] = { #else {"GOT_A_FIN_BEFORE_A_CCS", ERR_LIB_SSL, 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", ERR_LIB_SSL, 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", ERR_LIB_SSL, 356}, + #endif #ifdef SSL_R_HTTPS_PROXY_REQUEST {"HTTPS_PROXY_REQUEST", ERR_LIB_SSL, SSL_R_HTTPS_PROXY_REQUEST}, #else @@ -544,6 +639,16 @@ static struct py_ssl_error_code error_codes[] = { #else {"ILLEGAL_PADDING", ERR_LIB_SSL, 283}, #endif + #ifdef SSL_R_ILLEGAL_SUITEB_DIGEST + {"ILLEGAL_SUITEB_DIGEST", ERR_LIB_SSL, SSL_R_ILLEGAL_SUITEB_DIGEST}, + #else + {"ILLEGAL_SUITEB_DIGEST", ERR_LIB_SSL, 380}, + #endif + #ifdef SSL_R_INAPPROPRIATE_FALLBACK + {"INAPPROPRIATE_FALLBACK", ERR_LIB_SSL, SSL_R_INAPPROPRIATE_FALLBACK}, + #else + {"INAPPROPRIATE_FALLBACK", ERR_LIB_SSL, 373}, + #endif #ifdef SSL_R_INCONSISTENT_COMPRESSION {"INCONSISTENT_COMPRESSION", ERR_LIB_SSL, SSL_R_INCONSISTENT_COMPRESSION}, #else @@ -564,11 +669,26 @@ static struct py_ssl_error_code error_codes[] = { #else {"INVALID_COMPRESSION_ALGORITHM", ERR_LIB_SSL, 341}, #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", ERR_LIB_SSL, 385}, + #endif #ifdef SSL_R_INVALID_PURPOSE {"INVALID_PURPOSE", ERR_LIB_SSL, SSL_R_INVALID_PURPOSE}, #else {"INVALID_PURPOSE", ERR_LIB_SSL, 278}, #endif + #ifdef SSL_R_INVALID_SERVERINFO_DATA + {"INVALID_SERVERINFO_DATA", ERR_LIB_SSL, SSL_R_INVALID_SERVERINFO_DATA}, + #else + {"INVALID_SERVERINFO_DATA", ERR_LIB_SSL, 388}, + #endif + #ifdef SSL_R_INVALID_SRP_USERNAME + {"INVALID_SRP_USERNAME", ERR_LIB_SSL, SSL_R_INVALID_SRP_USERNAME}, + #else + {"INVALID_SRP_USERNAME", ERR_LIB_SSL, 357}, + #endif #ifdef SSL_R_INVALID_STATUS_RESPONSE {"INVALID_STATUS_RESPONSE", ERR_LIB_SSL, SSL_R_INVALID_STATUS_RESPONSE}, #else @@ -689,6 +809,16 @@ static struct py_ssl_error_code error_codes[] = { #else {"MISSING_DSA_SIGNING_CERT", ERR_LIB_SSL, 165}, #endif + #ifdef SSL_R_MISSING_ECDH_CERT + {"MISSING_ECDH_CERT", ERR_LIB_SSL, SSL_R_MISSING_ECDH_CERT}, + #else + {"MISSING_ECDH_CERT", ERR_LIB_SSL, 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", ERR_LIB_SSL, 381}, + #endif #ifdef SSL_R_MISSING_EXPORT_TMP_DH_KEY {"MISSING_EXPORT_TMP_DH_KEY", ERR_LIB_SSL, SSL_R_MISSING_EXPORT_TMP_DH_KEY}, #else @@ -714,6 +844,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"MISSING_RSA_SIGNING_CERT", ERR_LIB_SSL, 170}, #endif + #ifdef SSL_R_MISSING_SRP_PARAM + {"MISSING_SRP_PARAM", ERR_LIB_SSL, SSL_R_MISSING_SRP_PARAM}, + #else + {"MISSING_SRP_PARAM", ERR_LIB_SSL, 358}, + #endif #ifdef SSL_R_MISSING_TMP_DH_KEY {"MISSING_TMP_DH_KEY", ERR_LIB_SSL, SSL_R_MISSING_TMP_DH_KEY}, #else @@ -739,6 +874,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"MISSING_VERIFY_MESSAGE", ERR_LIB_SSL, 174}, #endif + #ifdef SSL_R_MULTIPLE_SGC_RESTARTS + {"MULTIPLE_SGC_RESTARTS", ERR_LIB_SSL, SSL_R_MULTIPLE_SGC_RESTARTS}, + #else + {"MULTIPLE_SGC_RESTARTS", ERR_LIB_SSL, 346}, + #endif #ifdef SSL_R_NON_SSLV2_INITIAL_PACKET {"NON_SSLV2_INITIAL_PACKET", ERR_LIB_SSL, SSL_R_NON_SSLV2_INITIAL_PACKET}, #else @@ -819,6 +959,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"NO_METHOD_SPECIFIED", ERR_LIB_SSL, 188}, #endif + #ifdef SSL_R_NO_PEM_EXTENSIONS + {"NO_PEM_EXTENSIONS", ERR_LIB_SSL, SSL_R_NO_PEM_EXTENSIONS}, + #else + {"NO_PEM_EXTENSIONS", ERR_LIB_SSL, 389}, + #endif #ifdef SSL_R_NO_PRIVATEKEY {"NO_PRIVATEKEY", ERR_LIB_SSL, SSL_R_NO_PRIVATEKEY}, #else @@ -854,6 +999,16 @@ static struct py_ssl_error_code error_codes[] = { #else {"NO_SHARED_CIPHER", ERR_LIB_SSL, 193}, #endif + #ifdef SSL_R_NO_SHARED_SIGATURE_ALGORITHMS + {"NO_SHARED_SIGATURE_ALGORITHMS", ERR_LIB_SSL, SSL_R_NO_SHARED_SIGATURE_ALGORITHMS}, + #else + {"NO_SHARED_SIGATURE_ALGORITHMS", ERR_LIB_SSL, 376}, + #endif + #ifdef SSL_R_NO_SRTP_PROFILES + {"NO_SRTP_PROFILES", ERR_LIB_SSL, SSL_R_NO_SRTP_PROFILES}, + #else + {"NO_SRTP_PROFILES", ERR_LIB_SSL, 359}, + #endif #ifdef SSL_R_NO_VERIFY_CALLBACK {"NO_VERIFY_CALLBACK", ERR_LIB_SSL, SSL_R_NO_VERIFY_CALLBACK}, #else @@ -879,6 +1034,16 @@ static struct py_ssl_error_code error_codes[] = { #else {"OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED", ERR_LIB_SSL, 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", ERR_LIB_SSL, 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", ERR_LIB_SSL, 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 @@ -934,6 +1099,16 @@ static struct py_ssl_error_code error_codes[] = { #else {"PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE", ERR_LIB_SSL, 204}, #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", ERR_LIB_SSL, 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", ERR_LIB_SSL, 392}, + #endif #ifdef SSL_R_PRE_MAC_LENGTH_TOO_LONG {"PRE_MAC_LENGTH_TOO_LONG", ERR_LIB_SSL, SSL_R_PRE_MAC_LENGTH_TOO_LONG}, #else @@ -1069,11 +1244,36 @@ static struct py_ssl_error_code error_codes[] = { #else {"SHORT_READ", ERR_LIB_SSL, 219}, #endif + #ifdef SSL_R_SIGNATURE_ALGORITHMS_ERROR + {"SIGNATURE_ALGORITHMS_ERROR", ERR_LIB_SSL, SSL_R_SIGNATURE_ALGORITHMS_ERROR}, + #else + {"SIGNATURE_ALGORITHMS_ERROR", ERR_LIB_SSL, 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", ERR_LIB_SSL, 220}, #endif + #ifdef SSL_R_SRP_A_CALC + {"SRP_A_CALC", ERR_LIB_SSL, SSL_R_SRP_A_CALC}, + #else + {"SRP_A_CALC", ERR_LIB_SSL, 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", ERR_LIB_SSL, 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", ERR_LIB_SSL, 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", ERR_LIB_SSL, 364}, + #endif #ifdef SSL_R_SSL23_DOING_SESSION_ID_REUSE {"SSL23_DOING_SESSION_ID_REUSE", ERR_LIB_SSL, SSL_R_SSL23_DOING_SESSION_ID_REUSE}, #else @@ -1179,6 +1379,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"SSL_LIBRARY_HAS_NO_CIPHERS", ERR_LIB_SSL, 230}, #endif + #ifdef SSL_R_SSL_NEGATIVE_LENGTH + {"SSL_NEGATIVE_LENGTH", ERR_LIB_SSL, SSL_R_SSL_NEGATIVE_LENGTH}, + #else + {"SSL_NEGATIVE_LENGTH", ERR_LIB_SSL, 372}, + #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 @@ -1229,6 +1434,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"TLSV1_ALERT_EXPORT_RESTRICTION", ERR_LIB_SSL, 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", ERR_LIB_SSL, 1086}, + #endif #ifdef SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY {"TLSV1_ALERT_INSUFFICIENT_SECURITY", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY}, #else @@ -1294,6 +1504,21 @@ static struct py_ssl_error_code error_codes[] = { #else {"TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER", ERR_LIB_SSL, 232}, #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", ERR_LIB_SSL, 365}, + #endif + #ifdef SSL_R_TLS_HEARTBEAT_PENDING + {"TLS_HEARTBEAT_PENDING", ERR_LIB_SSL, SSL_R_TLS_HEARTBEAT_PENDING}, + #else + {"TLS_HEARTBEAT_PENDING", ERR_LIB_SSL, 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", ERR_LIB_SSL, 367}, + #endif #ifdef SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST {"TLS_INVALID_ECPOINTFORMAT_LIST", ERR_LIB_SSL, SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST}, #else @@ -1399,6 +1624,16 @@ static struct py_ssl_error_code error_codes[] = { #else {"UNKNOWN_CIPHER_TYPE", ERR_LIB_SSL, 249}, #endif + #ifdef SSL_R_UNKNOWN_CMD_NAME + {"UNKNOWN_CMD_NAME", ERR_LIB_SSL, SSL_R_UNKNOWN_CMD_NAME}, + #else + {"UNKNOWN_CMD_NAME", ERR_LIB_SSL, 386}, + #endif + #ifdef SSL_R_UNKNOWN_DIGEST + {"UNKNOWN_DIGEST", ERR_LIB_SSL, SSL_R_UNKNOWN_DIGEST}, + #else + {"UNKNOWN_DIGEST", ERR_LIB_SSL, 368}, + #endif #ifdef SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE {"UNKNOWN_KEY_EXCHANGE_TYPE", ERR_LIB_SSL, SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE}, #else @@ -1469,16 +1704,36 @@ static struct py_ssl_error_code error_codes[] = { #else {"UNSUPPORTED_STATUS_TYPE", ERR_LIB_SSL, 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", ERR_LIB_SSL, 369}, + #endif + #ifdef SSL_R_VERSION_TOO_LOW + {"VERSION_TOO_LOW", ERR_LIB_SSL, SSL_R_VERSION_TOO_LOW}, + #else + {"VERSION_TOO_LOW", ERR_LIB_SSL, 396}, + #endif #ifdef SSL_R_WRITE_BIO_NOT_SET {"WRITE_BIO_NOT_SET", ERR_LIB_SSL, SSL_R_WRITE_BIO_NOT_SET}, #else {"WRITE_BIO_NOT_SET", ERR_LIB_SSL, 260}, #endif + #ifdef SSL_R_WRONG_CERTIFICATE_TYPE + {"WRONG_CERTIFICATE_TYPE", ERR_LIB_SSL, SSL_R_WRONG_CERTIFICATE_TYPE}, + #else + {"WRONG_CERTIFICATE_TYPE", ERR_LIB_SSL, 383}, + #endif #ifdef SSL_R_WRONG_CIPHER_RETURNED {"WRONG_CIPHER_RETURNED", ERR_LIB_SSL, SSL_R_WRONG_CIPHER_RETURNED}, #else {"WRONG_CIPHER_RETURNED", ERR_LIB_SSL, 261}, #endif + #ifdef SSL_R_WRONG_CURVE + {"WRONG_CURVE", ERR_LIB_SSL, SSL_R_WRONG_CURVE}, + #else + {"WRONG_CURVE", ERR_LIB_SSL, 378}, + #endif #ifdef SSL_R_WRONG_MESSAGE_TYPE {"WRONG_MESSAGE_TYPE", ERR_LIB_SSL, SSL_R_WRONG_MESSAGE_TYPE}, #else @@ -1499,6 +1754,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"WRONG_SIGNATURE_SIZE", ERR_LIB_SSL, 265}, #endif + #ifdef SSL_R_WRONG_SIGNATURE_TYPE + {"WRONG_SIGNATURE_TYPE", ERR_LIB_SSL, SSL_R_WRONG_SIGNATURE_TYPE}, + #else + {"WRONG_SIGNATURE_TYPE", ERR_LIB_SSL, 370}, + #endif #ifdef SSL_R_WRONG_SSL_VERSION {"WRONG_SSL_VERSION", ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION}, #else @@ -1519,6 +1779,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"X509_VERIFICATION_SETUP_PROBLEMS", ERR_LIB_SSL, 269}, #endif + #ifdef X509_R_AKID_MISMATCH + {"AKID_MISMATCH", ERR_LIB_X509, X509_R_AKID_MISMATCH}, + #else + {"AKID_MISMATCH", ERR_LIB_X509, 110}, + #endif #ifdef X509_R_BAD_X509_FILETYPE {"BAD_X509_FILETYPE", ERR_LIB_X509, X509_R_BAD_X509_FILETYPE}, #else @@ -1539,11 +1804,26 @@ static struct py_ssl_error_code error_codes[] = { #else {"CERT_ALREADY_IN_HASH_TABLE", ERR_LIB_X509, 101}, #endif + #ifdef X509_R_CRL_ALREADY_DELTA + {"CRL_ALREADY_DELTA", ERR_LIB_X509, X509_R_CRL_ALREADY_DELTA}, + #else + {"CRL_ALREADY_DELTA", ERR_LIB_X509, 127}, + #endif + #ifdef X509_R_CRL_VERIFY_FAILURE + {"CRL_VERIFY_FAILURE", ERR_LIB_X509, X509_R_CRL_VERIFY_FAILURE}, + #else + {"CRL_VERIFY_FAILURE", ERR_LIB_X509, 131}, + #endif #ifdef X509_R_ERR_ASN1_LIB {"ERR_ASN1_LIB", ERR_LIB_X509, X509_R_ERR_ASN1_LIB}, #else {"ERR_ASN1_LIB", ERR_LIB_X509, 102}, #endif + #ifdef X509_R_IDP_MISMATCH + {"IDP_MISMATCH", ERR_LIB_X509, X509_R_IDP_MISMATCH}, + #else + {"IDP_MISMATCH", ERR_LIB_X509, 128}, + #endif #ifdef X509_R_INVALID_DIRECTORY {"INVALID_DIRECTORY", ERR_LIB_X509, X509_R_INVALID_DIRECTORY}, #else @@ -1559,6 +1839,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"INVALID_TRUST", ERR_LIB_X509, 123}, #endif + #ifdef X509_R_ISSUER_MISMATCH + {"ISSUER_MISMATCH", ERR_LIB_X509, X509_R_ISSUER_MISMATCH}, + #else + {"ISSUER_MISMATCH", ERR_LIB_X509, 129}, + #endif #ifdef X509_R_KEY_TYPE_MISMATCH {"KEY_TYPE_MISMATCH", ERR_LIB_X509, X509_R_KEY_TYPE_MISMATCH}, #else @@ -1584,11 +1869,21 @@ static struct py_ssl_error_code error_codes[] = { #else {"METHOD_NOT_SUPPORTED", ERR_LIB_X509, 124}, #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", ERR_LIB_X509, 132}, + #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", ERR_LIB_X509, 105}, #endif + #ifdef X509_R_NO_CRL_NUMBER + {"NO_CRL_NUMBER", ERR_LIB_X509, X509_R_NO_CRL_NUMBER}, + #else + {"NO_CRL_NUMBER", ERR_LIB_X509, 130}, + #endif #ifdef X509_R_PUBLIC_KEY_DECODE_ERROR {"PUBLIC_KEY_DECODE_ERROR", ERR_LIB_X509, X509_R_PUBLIC_KEY_DECODE_ERROR}, #else diff --git a/Modules/_stat.c b/Modules/_stat.c index a301fa8840c5..f6cb303500cd 100644 --- a/Modules/_stat.c +++ b/Modules/_stat.c @@ -27,9 +27,21 @@ extern "C" { #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 +#endif /* MS_WINDOWS */ + /* From Python's stat.py */ #ifndef S_IMODE # define S_IMODE 07777 @@ -473,6 +485,10 @@ 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\ "); @@ -555,6 +571,26 @@ PyInit__stat(void) 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; +#endif + return m; } diff --git a/Modules/_struct.c b/Modules/_struct.c index 1de94e406e18..068c5d1e1d83 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -85,8 +85,6 @@ typedef struct { char c; _Bool x; } s_bool; #define BOOL_ALIGN 0 #endif -#define STRINGIFY(x) #x - #ifdef __powerc #pragma options align=reset #endif @@ -546,8 +544,8 @@ np_short(char *p, PyObject *v, const formatdef *f) return -1; if (x < SHRT_MIN || x > SHRT_MAX){ PyErr_SetString(StructError, - "short format requires " STRINGIFY(SHRT_MIN) - " <= number <= " STRINGIFY(SHRT_MAX)); + "short format requires " Py_STRINGIFY(SHRT_MIN) + " <= number <= " Py_STRINGIFY(SHRT_MAX)); return -1; } y = (short)x; @@ -564,7 +562,8 @@ np_ushort(char *p, PyObject *v, const formatdef *f) return -1; if (x < 0 || x > USHRT_MAX){ PyErr_SetString(StructError, - "ushort format requires 0 <= number <= " STRINGIFY(USHRT_MAX)); + "ushort format requires 0 <= number <= " + Py_STRINGIFY(USHRT_MAX)); return -1; } y = (unsigned short)x; @@ -1264,7 +1263,8 @@ prepare_s(PyStructObject *self) const char *s; const char *fmt; char c; - Py_ssize_t size, len, ncodes, num, itemsize; + Py_ssize_t size, len, num, itemsize; + size_t ncodes; fmt = PyBytes_AS_STRING(self->s_format); @@ -1320,7 +1320,7 @@ prepare_s(PyStructObject *self) } /* check for overflow */ - if ((ncodes + 1) > (PY_SSIZE_T_MAX / sizeof(formatcode))) { + if ((ncodes + 1) > ((size_t)PY_SSIZE_T_MAX / sizeof(formatcode))) { PyErr_NoMemory(); return -1; } @@ -1842,8 +1842,8 @@ static PyObject * s_pack_into(PyObject *self, PyObject *args) { PyStructObject *soself; - char *buffer; - Py_ssize_t buffer_len, offset; + Py_buffer buffer; + Py_ssize_t offset; /* Validate arguments. +1 is for the first arg as buffer. */ soself = (PyStructObject *)self; @@ -1868,34 +1868,37 @@ s_pack_into(PyObject *self, PyObject *args) } /* Extract a writable memory buffer from the first argument */ - if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0), - (void**)&buffer, &buffer_len) == -1 ) { + if (!PyArg_Parse(PyTuple_GET_ITEM(args, 0), "w*", &buffer)) return NULL; - } - assert( buffer_len >= 0 ); + assert(buffer.len >= 0); /* Extract the offset from the first argument */ offset = PyNumber_AsSsize_t(PyTuple_GET_ITEM(args, 1), PyExc_IndexError); - if (offset == -1 && PyErr_Occurred()) + if (offset == -1 && PyErr_Occurred()) { + PyBuffer_Release(&buffer); return NULL; + } /* Support negative offsets. */ if (offset < 0) - offset += buffer_len; + offset += buffer.len; /* Check boundaries */ - if (offset < 0 || (buffer_len - offset) < soself->s_size) { + if (offset < 0 || (buffer.len - offset) < soself->s_size) { PyErr_Format(StructError, "pack_into requires a buffer of at least %zd bytes", soself->s_size); + PyBuffer_Release(&buffer); return NULL; } /* Call the guts */ - if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) { + if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset) != 0) { + PyBuffer_Release(&buffer); return NULL; } + PyBuffer_Release(&buffer); Py_RETURN_NONE; } diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index 0c6ef16f175f..43db8a8e53a3 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -190,7 +190,7 @@ ndbuf_delete(NDArrayObject *nd, ndbuf_t *elt) elt->prev->next = elt->next; else nd->head = elt->next; - + if (elt->next) elt->next->prev = elt->prev; @@ -767,7 +767,7 @@ ndarray_as_list(NDArrayObject *nd) +-----------------+-----------+-------------+----------------+ | base.readonly | 0 | OK | OK | +-----------------+-----------+-------------+----------------+ - | base.format | NULL | OK | OK | + | base.format | NULL | OK | OK | +-----------------+-----------+-------------+----------------+ | base.ndim | 1 | 1 | OK | +-----------------+-----------+-------------+----------------+ @@ -850,7 +850,7 @@ seq_as_ssize_array(PyObject *seq, Py_ssize_t len, int is_shape) Py_ssize_t *dest; Py_ssize_t x, i; - dest = PyMem_Malloc(len * (sizeof *dest)); + dest = PyMem_New(Py_ssize_t, len); if (dest == NULL) { PyErr_NoMemory(); return NULL; @@ -1510,6 +1510,19 @@ ndarray_getbuf(NDArrayObject *self, Py_buffer *view, int flags) 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++; @@ -2005,7 +2018,7 @@ ndarray_get_obj(NDArrayObject *self, void *closure) { Py_buffer *base = &self->head->base; - if (base->obj == NULL) { + if (base->obj == NULL) { Py_RETURN_NONE; } Py_INCREF(base->obj); @@ -2206,6 +2219,8 @@ ndarray_add_suboffsets(PyObject *self, PyObject *dummy) for (i = 0; i < base->ndim; i++) base->suboffsets[i] = -1; + nd->head->flags &= ~(ND_C|ND_FORTRAN); + Py_RETURN_NONE; } @@ -2469,13 +2484,12 @@ arraycmp(const Py_ssize_t *a1, const Py_ssize_t *a2, const Py_ssize_t *shape, { Py_ssize_t i; - if (ndim == 1 && shape && shape[0] == 1) { - /* This is for comparing strides: For example, the array - [175], shape=[1], strides=[-5] is considered contiguous. */ - return 1; - } 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; } @@ -2544,7 +2558,7 @@ cmp_contig(PyObject *self, PyObject *args) PyBuffer_Release(&v1); PyBuffer_Release(&v2); - ret = equal ? Py_True : Py_False; + ret = equal ? Py_True : Py_False; Py_INCREF(ret); return ret; } @@ -2555,30 +2569,35 @@ is_contiguous(PyObject *self, PyObject *args) PyObject *obj; PyObject *order; PyObject *ret = NULL; - Py_buffer view; + Py_buffer view, *base; char ord; if (!PyArg_ParseTuple(args, "OO", &obj, &order)) { return NULL; } - if (PyObject_GetBuffer(obj, &view, PyBUF_FULL_RO) < 0) { - PyErr_SetString(PyExc_TypeError, - "is_contiguous: object does not implement the buffer " - "protocol"); + ord = get_ascii_order(order); + if (ord == CHAR_MAX) { return NULL; } - ord = get_ascii_order(order); - if (ord == CHAR_MAX) { - goto release; + 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); } - ret = PyBuffer_IsContiguous(&view, ord) ? Py_True : Py_False; Py_INCREF(ret); - -release: - PyBuffer_Release(&view); return ret; } diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 9662eb8f9e40..a896af0cc0ed 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -11,6 +11,12 @@ #include #include "structmember.h" #include "datetime.h" +#include "marshal.h" +#include + +#ifdef MS_WINDOWS +# include /* struct timeval */ +#endif #ifdef WITH_THREAD #include "pythread.h" @@ -67,6 +73,10 @@ test_config(PyObject *self) static PyObject* test_sizeof_c_types(PyObject *self) { +#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, \ @@ -124,6 +134,9 @@ test_sizeof_c_types(PyObject *self) #undef IS_SIGNED #undef CHECK_SIGNESS #undef CHECK_SIZEOF +#if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))) +#pragma GCC diagnostic pop +#endif } @@ -1515,7 +1528,7 @@ unicode_aswidechar(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "Un", &unicode, &buflen)) return NULL; - buffer = PyMem_Malloc(buflen * sizeof(wchar_t)); + buffer = PyMem_New(wchar_t, buflen); if (buffer == NULL) return PyErr_NoMemory(); @@ -1718,7 +1731,7 @@ test_long_numbits(PyObject *self) {-0xffffL, 16, -1}, {0xfffffffL, 28, 1}, {-0xfffffffL, 28, -1}}; - int i; + size_t i; for (i = 0; i < Py_ARRAY_LENGTH(testcases); ++i) { size_t nbits; @@ -1782,6 +1795,18 @@ raise_exception(PyObject *self, PyObject *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) { @@ -2468,6 +2493,108 @@ make_memoryview_from_NULL_pointer(PyObject *self) return PyMemoryView_FromBuffer(&info); } +static PyObject * +test_from_contiguous(PyObject* self, PyObject *noargs) +{ + 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 *noargs) +{ + 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 * @@ -2516,14 +2643,29 @@ run_in_subinterp(PyObject *self, PyObject *args) 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) { + 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; - if (!PyArg_ParseTuple(args, "O:pytime_object_to_time_t", &obj)) + 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) == -1) + if (_PyTime_ObjectToTime_t(obj, &sec, round) == -1) return NULL; return _PyLong_FromTime_t(sec); } @@ -2534,9 +2676,12 @@ test_pytime_object_to_timeval(PyObject *self, PyObject *args) PyObject *obj; time_t sec; long usec; - if (!PyArg_ParseTuple(args, "O:pytime_object_to_timeval", &obj)) + int round; + if (!PyArg_ParseTuple(args, "Oi:pytime_object_to_timeval", &obj, &round)) return NULL; - if (_PyTime_ObjectToTimeval(obj, &sec, &usec) == -1) + 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); } @@ -2547,9 +2692,12 @@ test_pytime_object_to_timespec(PyObject *self, PyObject *args) PyObject *obj; time_t sec; long nsec; - if (!PyArg_ParseTuple(args, "O:pytime_object_to_timespec", &obj)) + 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) == -1) + if (_PyTime_ObjectToTimespec(obj, &sec, &nsec, round) == -1) return NULL; return Py_BuildValue("Nl", _PyLong_FromTime_t(sec), nsec); } @@ -2633,6 +2781,21 @@ with_tp_del(PyObject *self, PyObject *args) 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) { @@ -2680,7 +2843,7 @@ static PyObject * test_incref_decref_API(PyObject *ob) { PyObject *obj = PyLong_FromLong(0); - Py_IncRef(ob); + Py_IncRef(obj); Py_DecRef(obj); Py_DecRef(obj); Py_RETURN_NONE; @@ -2691,6 +2854,20 @@ test_pymem_alloc0(PyObject *self) { 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"); @@ -2698,6 +2875,13 @@ test_pymem_alloc0(PyObject *self) } 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"); @@ -2705,13 +2889,22 @@ test_pymem_alloc0(PyObject *self) } 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 { - PyMemAllocator alloc; + 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; @@ -2724,6 +2917,14 @@ static void* hook_malloc (void* ctx, size_t 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->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; @@ -2745,17 +2946,15 @@ test_setallocators(PyMemAllocatorDomain domain) PyObject *res = NULL; const char *error_msg; alloc_hook_t hook; - PyMemAllocator alloc; - size_t size, size2; + PyMemAllocatorEx alloc; + size_t size, size2, nelem, elsize; void *ptr, *ptr2; - hook.malloc_size = 0; - hook.realloc_ptr = NULL; - hook.realloc_new_size = 0; - hook.free_ptr = NULL; + 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); @@ -2812,6 +3011,33 @@ test_setallocators(PyMemAllocatorDomain domain) goto fail; } + 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; + } + + if (hook.calloc_nelem != nelem || hook.calloc_elsize != elsize) { + error_msg = "calloc invalid nelem or elsize"; + goto fail; + } + + 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; + } + Py_INCREF(Py_None); res = Py_None; goto finally; @@ -2851,27 +3077,463 @@ PyDoc_STRVAR(docstring_no_signature, ); PyDoc_STRVAR(docstring_with_invalid_signature, -"docstring_with_invalid_signature (boo)\n" +"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(sig)\n" +"docstring_with_signature($module, /, sig)\n" +"--\n" +"\n" "This docstring has a valid signature." ); -PyDoc_STRVAR(docstring_with_signature_and_extra_newlines, -"docstring_with_signature_and_extra_newlines(parameter)\n" +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." +); + +#ifdef WITH_THREAD +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_CallFunction(test_c_thread->callback, "", NULL); + 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; +} +#endif /* WITH_THREAD */ + +static PyObject* +test_raise_signal(PyObject* self, PyObject *args) +{ + int signum, err; + + if (PyArg_ParseTuple(args, "i:raise_signal", &signum) < 0) + return NULL; + + err = raise(signum); + if (err) + return PyErr_SetFromErrno(PyExc_OSError); + + if (PyErr_CheckSignals() < 0) + return NULL; + + Py_RETURN_NONE; +} + +/* 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) +{ + PY_LONG_LONG ns; + _PyTime_t ts; + double d; + + if (!PyArg_ParseTuple(args, "L", &ns)) + return NULL; + ts = _PyTime_FromNanoseconds(ns); + d = _PyTime_AsSecondsDouble(ts); + return PyFloat_FromDouble(d); +} + +static PyObject * +test_PyTime_AsTimeval(PyObject *self, PyObject *args) +{ + PY_LONG_LONG ns; + int round; + _PyTime_t t; + struct timeval tv; + PyObject *seconds; + + if (!PyArg_ParseTuple(args, "Li", &ns, &round)) + return NULL; + if (check_time_rounding(round) < 0) + return NULL; + t = _PyTime_FromNanoseconds(ns); + if (_PyTime_AsTimeval(t, &tv, round) < 0) + return NULL; + + seconds = PyLong_FromLong((PY_LONG_LONG)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) +{ + PY_LONG_LONG ns; + _PyTime_t t; + struct timespec ts; + + if (!PyArg_ParseTuple(args, "L", &ns)) + return NULL; + t = _PyTime_FromNanoseconds(ns); + 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) +{ + PY_LONG_LONG ns; + int round; + _PyTime_t t, ms; + + if (!PyArg_ParseTuple(args, "Li", &ns, &round)) + return NULL; + if (check_time_rounding(round) < 0) + return NULL; + t = _PyTime_FromNanoseconds(ns); + 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) +{ + PY_LONG_LONG ns; + int round; + _PyTime_t t, ms; + + if (!PyArg_ParseTuple(args, "Li", &ns, &round)) + return NULL; + if (check_time_rounding(round) < 0) + return NULL; + t = _PyTime_FromNanoseconds(ns); + 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(); + + /* substract one to ignore the frame of the get_recursion_depth() call */ + return PyLong_FromLong(tstate->recursion_depth - 1); +} + + static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, {"raise_memoryerror", (PyCFunction)raise_memoryerror, METH_NOARGS}, + {"set_errno", set_errno, METH_VARARGS}, {"test_config", (PyCFunction)test_config, METH_NOARGS}, {"test_sizeof_c_types", (PyCFunction)test_sizeof_c_types, METH_NOARGS}, {"test_datetime_capi", test_datetime_capi, METH_NOARGS}, @@ -2899,6 +3561,11 @@ static PyMethodDef TestMethods[] = { {"test_string_to_double", (PyCFunction)test_string_to_double, METH_NOARGS}, {"test_unicode_compare_with_ascii", (PyCFunction)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}, {"getargs_tuple", getargs_tuple, METH_VARARGS}, {"getargs_keywords", (PyCFunction)getargs_keywords, METH_VARARGS|METH_KEYWORDS}, @@ -2972,9 +3639,10 @@ static PyMethodDef TestMethods[] = { {"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}, - {"test_pymem", - (PyCFunction)test_pymem_alloc0, METH_NOARGS}, + {"create_cfunction", create_cfunction, METH_NOARGS}, {"test_pymem_alloc0", + (PyCFunction)test_pymem_alloc0, METH_NOARGS}, + {"test_pymem_setrawallocators", (PyCFunction)test_pymem_setrawallocators, METH_NOARGS}, {"test_pymem_setallocators", (PyCFunction)test_pymem_setallocators, METH_NOARGS}, @@ -2991,12 +3659,53 @@ static PyMethodDef TestMethods[] = { {"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}, + {"raise_signal", + (PyCFunction)test_raise_signal, METH_VARARGS}, +#ifdef WITH_THREAD + {"call_in_temporary_c_thread", call_in_temporary_c_thread, METH_O, + PyDoc_STR("set_error_class(error_class) -> None")}, +#endif + {"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}, {NULL, NULL} /* sentinel */ }; @@ -3156,6 +3865,201 @@ static PyTypeObject test_structmembersType = { }; +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_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 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 + 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_print */ + 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 struct PyModuleDef _testcapimodule = { PyModuleDef_HEAD_INIT, @@ -3169,6 +4073,9 @@ static struct PyModuleDef _testcapimodule = { NULL }; +/* Per PEP 489, this module will not be converted to multi-phase initialization + */ + PyMODINIT_FUNC PyInit__testcapi(void) { @@ -3185,6 +4092,15 @@ PyInit__testcapi(void) /* 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(&awaitType) < 0) + return NULL; + Py_INCREF(&awaitType); + PyModule_AddObject(m, "awaitType", (PyObject *)&awaitType); PyModule_AddObject(m, "CHAR_MAX", PyLong_FromLong(CHAR_MAX)); PyModule_AddObject(m, "CHAR_MIN", PyLong_FromLong(CHAR_MIN)); @@ -3208,9 +4124,12 @@ PyInit__testcapi(void) 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); + TestError = PyErr_NewException("_testcapi.error", NULL, NULL); Py_INCREF(TestError); PyModule_AddObject(m, "error", TestError); diff --git a/Modules/_testmultiphase.c b/Modules/_testmultiphase.c new file mode 100644 index 000000000000..2005205d3358 --- /dev/null +++ b/Modules/_testmultiphase.c @@ -0,0 +1,594 @@ + +/* 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; + +/* Example methods */ + +static int +Example_traverse(ExampleObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->x_attr); + return 0; +} + +static int +Example_finalize(ExampleObject *self) +{ + Py_CLEAR(self->x_attr); + return 0; +} + +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_INCREF(Py_None); + return Py_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_GetItem(self->x_attr, name); + if (v != NULL) { + Py_INCREF(v); + return v; + } + } + return PyObject_GenericGetAttr((PyObject *)self, name); +} + +static int +Example_setattr(ExampleObject *self, 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_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 | Py_TPFLAGS_HAVE_FINALIZE, + 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(name, slots, methods) { \ + PyModuleDef_HEAD_INIT, /* m_base */ \ + name, /* m_name */ \ + PyDoc_STR("Test module " name), /* m_doc */ \ + 0, /* m_size */ \ + methods, /* m_methods */ \ + slots, /* m_slots */ \ + NULL, /* m_traverse */ \ + NULL, /* m_clear */ \ + NULL, /* m_free */ \ +} + +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; + +/* Create a SimpleNamespace(three=3) */ +static PyObject* +createfunc_nonmodule(PyObject *spec, PyModuleDef *def) +{ + PyObject *dct, *ns, *three; + + if (def != &def_nonmodule) { + 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); +} + +/**** 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; +} + +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); +} + +/*** 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/Modules/_threadmodule.c b/Modules/_threadmodule.c index ab0fea44e419..bcb3aeeb22a0 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -49,21 +49,18 @@ lock_dealloc(lockobject *self) * timeout. */ static PyLockStatus -acquire_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds) +acquire_timed(PyThread_type_lock lock, _PyTime_t timeout) { PyLockStatus r; - _PyTime_timeval curtime; - _PyTime_timeval endtime; - - - if (microseconds > 0) { - _PyTime_gettimeofday(&endtime); - endtime.tv_sec += microseconds / (1000 * 1000); - endtime.tv_usec += microseconds % (1000 * 1000); - } + _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) { @@ -82,14 +79,12 @@ acquire_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds) /* If we're using a timeout, recompute the timeout after processing * signals, since those can take time. */ - if (microseconds > 0) { - _PyTime_gettimeofday(&curtime); - microseconds = ((endtime.tv_sec - curtime.tv_sec) * 1000000 + - (endtime.tv_usec - curtime.tv_usec)); + if (timeout > 0) { + timeout = endtime - _PyTime_GetMonotonicClock(); /* Check for negative values, since those mean block forever. */ - if (microseconds <= 0) { + if (timeout < 0) { r = PY_LOCK_FAILURE; } } @@ -99,44 +94,61 @@ acquire_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds) return r; } -static PyObject * -lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds) +static int +lock_acquire_parse_args(PyObject *args, PyObject *kwds, + _PyTime_t *timeout) { char *kwlist[] = {"blocking", "timeout", NULL}; int blocking = 1; - double timeout = -1; - PY_TIMEOUT_T microseconds; - PyLockStatus r; + PyObject *timeout_obj = NULL; + const _PyTime_t unset_timeout = _PyTime_FromSeconds(-1); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|id:acquire", kwlist, - &blocking, &timeout)) - return NULL; + *timeout = unset_timeout ; - if (!blocking && timeout != -1) { - PyErr_SetString(PyExc_ValueError, "can't specify a timeout " - "for a non-blocking call"); - return NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO:acquire", kwlist, + &blocking, &timeout_obj)) + return -1; + + if (timeout_obj + && _PyTime_FromSecondsObject(timeout, + timeout_obj, _PyTime_ROUND_CEILING) < 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 != -1) { - PyErr_SetString(PyExc_ValueError, "timeout value must be " - "strictly positive"); - return NULL; + if (*timeout < 0 && *timeout != unset_timeout) { + PyErr_SetString(PyExc_ValueError, + "timeout value must be positive"); + return -1; } if (!blocking) - microseconds = 0; - else if (timeout == -1) - microseconds = -1; - else { - timeout *= 1e6; - if (timeout >= (double) PY_TIMEOUT_MAX) { + *timeout = 0; + else if (*timeout != unset_timeout) { + _PyTime_t microseconds; + + microseconds = _PyTime_AsMicroseconds(*timeout, _PyTime_ROUND_CEILING); + if (microseconds >= PY_TIMEOUT_MAX) { PyErr_SetString(PyExc_OverflowError, "timeout value is too large"); - return NULL; + return -1; } - microseconds = (PY_TIMEOUT_T) timeout; } + 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, microseconds); + r = acquire_timed(self->lock_lock, timeout); if (r == PY_LOCK_INTR) { return NULL; } @@ -192,6 +204,13 @@ PyDoc_STRVAR(locked_doc, \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)lock_PyThread_acquire_lock, METH_VARARGS | METH_KEYWORDS, acquire_doc}, @@ -223,7 +242,7 @@ static PyTypeObject Locktype = { 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_reserved*/ - 0, /*tp_repr*/ + (reprfunc)lock_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ @@ -274,41 +293,13 @@ rlock_dealloc(rlockobject *self) static PyObject * rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds) { - char *kwlist[] = {"blocking", "timeout", NULL}; - int blocking = 1; - double timeout = -1; - PY_TIMEOUT_T microseconds; + _PyTime_t timeout; long tid; PyLockStatus r = PY_LOCK_ACQUIRED; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|id:acquire", kwlist, - &blocking, &timeout)) + if (lock_acquire_parse_args(args, kwds, &timeout) < 0) return NULL; - if (!blocking && timeout != -1) { - PyErr_SetString(PyExc_ValueError, "can't specify a timeout " - "for a non-blocking call"); - return NULL; - } - if (timeout < 0 && timeout != -1) { - PyErr_SetString(PyExc_ValueError, "timeout value must be " - "strictly positive"); - return NULL; - } - if (!blocking) - microseconds = 0; - else if (timeout == -1) - microseconds = -1; - else { - timeout *= 1e6; - if (timeout >= (double) PY_TIMEOUT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "timeout value is too large"); - return NULL; - } - microseconds = (PY_TIMEOUT_T) timeout; - } - tid = PyThread_get_thread_ident(); if (self->rlock_count > 0 && tid == self->rlock_owner) { unsigned long count = self->rlock_count + 1; @@ -320,7 +311,7 @@ rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds) self->rlock_count = count; Py_RETURN_TRUE; } - r = acquire_timed(self->rlock_lock, microseconds); + r = acquire_timed(self->rlock_lock, timeout); if (r == PY_LOCK_ACQUIRED) { assert(self->rlock_count == 0); self->rlock_owner = tid; @@ -379,13 +370,13 @@ 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 *arg) +rlock_acquire_restore(rlockobject *self, PyObject *args) { long owner; unsigned long count; int r = 1; - if (!PyArg_ParseTuple(arg, "kl:_acquire_restore", &count, &owner)) + if (!PyArg_ParseTuple(args, "(kl):_acquire_restore", &count, &owner)) return NULL; if (!PyThread_acquire_lock(self->rlock_lock, 0)) { @@ -475,8 +466,10 @@ rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static PyObject * rlock_repr(rlockobject *self) { - return PyUnicode_FromFormat("<%s owner=%ld count=%lu>", - Py_TYPE(self)->tp_name, self->rlock_owner, self->rlock_count); + 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); } @@ -488,7 +481,7 @@ static PyMethodDef rlock_methods[] = { {"_is_owned", (PyCFunction)rlock_is_owned, METH_NOARGS, rlock_is_owned_doc}, {"_acquire_restore", (PyCFunction)rlock_acquire_restore, - METH_O, rlock_acquire_restore_doc}, + METH_VARARGS, rlock_acquire_restore_doc}, {"_release_save", (PyCFunction)rlock_release_save, METH_NOARGS, rlock_release_save_doc}, {"__enter__", (PyCFunction)rlock_acquire, @@ -718,12 +711,18 @@ local_new(PyTypeObject *type, PyObject *args, PyObject *kw) "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O }; - if (type->tp_init == PyBaseObject_Type.tp_init - && ((args && PyObject_IsTrue(args)) - || (kw && PyObject_IsTrue(kw)))) { - PyErr_SetString(PyExc_TypeError, - "Initialization arguments are not supported"); - return NULL; + 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); @@ -1353,7 +1352,9 @@ static struct PyModuleDef threadmodule = { PyMODINIT_FUNC PyInit__thread(void) { - PyObject *m, *d, *timeout_max; + PyObject *m, *d, *v; + double time_max; + double timeout_max; /* Initialize types: */ if (PyType_Ready(&localdummytype) < 0) @@ -1370,10 +1371,14 @@ PyInit__thread(void) if (m == NULL) return NULL; - timeout_max = PyFloat_FromDouble(PY_TIMEOUT_MAX / 1000000); - if (!timeout_max) + timeout_max = PY_TIMEOUT_MAX / 1000000; + time_max = floor(_PyTime_AsSecondsDouble(_PyTime_MAX)); + timeout_max = Py_MIN(timeout_max, time_max); + + v = PyFloat_FromDouble(timeout_max); + if (!v) return NULL; - if (PyModule_AddObject(m, "TIMEOUT_MAX", timeout_max) < 0) + if (PyModule_AddObject(m, "TIMEOUT_MAX", v) < 0) return NULL; /* Add a symbolic constant */ diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index e022a7a7e156..41ad5f91f7e6 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -9,8 +9,8 @@ Copyright (C) 1994 Steen Lumholt. /* TCL/TK VERSION INFO: - Only Tcl/Tk 8.3.1 and later are supported. Older versions are not - supported. Use Python 2.6 or older if you cannot upgrade your + 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. */ @@ -21,6 +21,7 @@ Copyright (C) 1994 Steen Lumholt. */ +#define PY_SSIZE_T_CLEAN #include "Python.h" #include @@ -33,29 +34,8 @@ Copyright (C) 1994 Steen Lumholt. #include #endif -/* Allow using this code in Python 2.[12] */ -#ifndef PyDoc_STRVAR -#define PyDoc_STRVAR(name,str) static char name[] = str -#endif - -#ifndef PyMODINIT_FUNC -#define PyMODINIT_FUNC void -#endif - -#ifndef PyBool_Check -#define PyBool_Check(o) 0 -#define PyBool_FromLong PyLong_FromLong -#endif - #define CHECK_SIZE(size, elemsize) \ - ((size_t)(size) <= Py_MAX((size_t)INT_MAX, UINT_MAX / (size_t)(elemsize))) - -/* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately, - making _tkinter correct for this API means to break earlier - versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and - earlier versions. Once Tcl releases before 8.4 don't need to be supported - anymore, this should go. */ -#define USE_COMPAT_CONST + ((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 @@ -72,15 +52,14 @@ Copyright (C) 1994 Steen Lumholt. #include "tkinter.h" -/* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */ -#ifndef CONST84_RETURN -#define CONST84_RETURN -#undef CONST -#define CONST +#if TK_HEX_VERSION < 0x08040200 +#error "Tk older than 8.4 not supported" #endif -#if TK_VERSION_HEX < 0x08030102 -#error "Tk older than 8.3.1 not supported" +#if TK_HEX_VERSION >= 0x08050208 && TK_HEX_VERSION < 0x08060000 || \ + TK_HEX_VERSION >= 0x08060200 +#define HAVE_LIBTOMMAMTH +#include #endif #if !(defined(MS_WINDOWS) || defined(__CYGWIN__)) @@ -122,7 +101,65 @@ Copyright (C) 1994 Steen Lumholt. #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 */ #ifdef WITH_THREAD @@ -256,13 +293,16 @@ typedef struct { int dispatching; /* We cannot include tclInt.h, as this is internal. So we cache interesting types here. */ - Tcl_ObjType *BooleanType; - Tcl_ObjType *ByteArrayType; - Tcl_ObjType *DoubleType; - Tcl_ObjType *IntType; - Tcl_ObjType *ListType; - Tcl_ObjType *ProcBodyType; - Tcl_ObjType *StringType; + 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) @@ -343,10 +383,57 @@ WaitForMainloop(TkappObject* self) static PyObject * -Split(char *list) +unicodeFromTclStringAndSize(const char *s, Py_ssize_t size) +{ + PyObject *r = PyUnicode_DecodeUTF8(s, size, NULL); + if (!r && PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { + /* Tcl encodes null character as \xc0\x80 */ + if (memchr(s, '\xc0', size)) { + char *buf, *q; + const char *e = s + size; + PyErr_Clear(); + 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, NULL); + PyMem_Free(buf); + } + } + return r; +} + +static PyObject * +unicodeFromTclString(const char *s) +{ + return unicodeFromTclStringAndSize(s, strlen(s)); +} + +static PyObject * +unicodeFromTclObj(Tcl_Obj *value) +{ + int len; + char *s = Tcl_GetStringFromObj(value, &len); + return unicodeFromTclStringAndSize(s, len); +} + + +static PyObject * +Split(const char *list) { int argc; - char **argv; + const char **argv; PyObject *v; if (list == NULL) { @@ -358,13 +445,13 @@ Split(char *list) * Could be a quoted string containing funnies, e.g. {"}. * Return the string itself. */ - return PyUnicode_FromString(list); + return unicodeFromTclString(list); } if (argc == 0) v = PyUnicode_FromString(""); else if (argc == 1) - v = PyUnicode_FromString(argv[0]); + v = unicodeFromTclString(argv[0]); else if ((v = PyTuple_New(argc)) != NULL) { int i; PyObject *w; @@ -390,7 +477,7 @@ static PyObject * SplitObj(PyObject *arg) { if (PyTuple_Check(arg)) { - int i, size; + Py_ssize_t i, size; PyObject *elem, *newelem, *result; size = PyTuple_Size(arg); @@ -406,7 +493,7 @@ SplitObj(PyObject *arg) return NULL; } if (!result) { - int k; + Py_ssize_t k; if (newelem == elem) { Py_DECREF(newelem); continue; @@ -426,9 +513,29 @@ SplitObj(PyObject *arg) 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_SetItem(result, i, newelem); + } + return result; + } else if (PyUnicode_Check(arg)) { int argc; - char **argv; + const char **argv; char *list = PyUnicode_AsUTF8(arg); if (list == NULL || @@ -443,7 +550,7 @@ SplitObj(PyObject *arg) } else if (PyBytes_Check(arg)) { int argc; - char **argv; + const char **argv; char *list = PyBytes_AsString(arg); if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) { @@ -460,6 +567,14 @@ SplitObj(PyObject *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 @@ -510,8 +625,9 @@ static void EnableEventHook(void); /* Forward */ static void DisableEventHook(void); /* Forward */ static TkappObject * -Tkapp_New(char *screenName, char *className, - int interactive, int wantobjects, int wantTk, int sync, char *use) +Tkapp_New(const char *screenName, const char *className, + int interactive, int wantobjects, int wantTk, int sync, + const char *use) { TkappObject *v; char *argv0; @@ -544,10 +660,13 @@ Tkapp_New(char *screenName, char *className, } #endif - v->BooleanType = Tcl_GetObjType("boolean"); + 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"); @@ -565,7 +684,7 @@ Tkapp_New(char *screenName, char *className, 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*)ckalloc(strlen(className) + 1); + argv0 = (char*)PyMem_Malloc(strlen(className) + 1); if (!argv0) { PyErr_NoMemory(); Py_DECREF(v); @@ -576,7 +695,7 @@ Tkapp_New(char *screenName, char *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); - ckfree(argv0); + PyMem_Free(argv0); if (! wantTk) { Tcl_SetVar(v->interp, @@ -592,14 +711,14 @@ Tkapp_New(char *screenName, char *className, /* some initial arguments need to be in argv */ if (sync || use) { char *args; - int len = 0; + Py_ssize_t len = 0; if (sync) len += sizeof "-sync"; if (use) - len += strlen(use) + sizeof "-use "; + len += strlen(use) + sizeof "-use "; /* never overflows */ - args = (char*)ckalloc(len); + args = (char*)PyMem_Malloc(len); if (!args) { PyErr_NoMemory(); Py_DECREF(v); @@ -617,8 +736,35 @@ Tkapp_New(char *screenName, char *className, } Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY); - ckfree(args); + 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_AsString(utf8_path), + TCL_GLOBAL_ONLY); + Py_DECREF(utf8_path); + } + } } +#endif if (Tcl_AppInit(v->interp) != TCL_OK) { PyObject *result = Tkinter_Error((PyObject *)v); @@ -708,11 +854,8 @@ PyDoc_STRVAR(PyTclObject_string__doc__, static PyObject * PyTclObject_string(PyTclObject *self, void *ignored) { - char *s; - int len; if (!self->string) { - s = Tcl_GetStringFromObj(self->value, &len); - self->string = PyUnicode_FromStringAndSize(s, len); + self->string = unicodeFromTclObj(self->value); if (!self->string) return NULL; } @@ -723,15 +866,12 @@ PyTclObject_string(PyTclObject *self, void *ignored) static PyObject * PyTclObject_str(PyTclObject *self, void *ignored) { - char *s; - int len; - if (self->string && PyUnicode_Check(self->string)) { + if (self->string) { Py_INCREF(self->string); return self->string; } /* XXX Could chache result if it is non-ASCII. */ - s = Tcl_GetStringFromObj(self->value, &len); - return PyUnicode_DecodeUTF8(s, len, "strict"); + return unicodeFromTclObj(self->value); } static PyObject * @@ -806,7 +946,7 @@ PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type"); static PyObject* get_typename(PyTclObject* obj, void* ignored) { - return PyUnicode_FromString(obj->value->typePtr->name); + return unicodeFromTclString(obj->value->typePtr->name); } @@ -836,46 +976,132 @@ static PyType_Spec PyTclObject_Type_spec = { }; +#if PY_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; + 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; - long longVal; - int overflow; - if (PyBytes_Check(value)) - return Tcl_NewStringObj(PyBytes_AS_STRING(value), - PyBytes_GET_SIZE(value)); - else if (PyBool_Check(value)) + 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)); - else if (PyLong_CheckExact(value) && - ((longVal = PyLong_AsLongAndOverflow(value, &overflow)), - !overflow)) { + + 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. */ - return Tcl_NewLongObj(longVal); } - else if (PyFloat_Check(value)) + + if (PyFloat_Check(value)) return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value)); - else if (PyTuple_Check(value)) { + + if (PyTuple_Check(value) || PyList_Check(value)) { Tcl_Obj **argv; Py_ssize_t size, i; - size = PyTuple_Size(value); + 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, "tuple is too long"); + PyErr_SetString(PyExc_OverflowError, + PyTuple_Check(value) ? "tuple is too long" : + "list is too long"); return NULL; } - argv = (Tcl_Obj **) ckalloc(((size_t)size) * sizeof(Tcl_Obj *)); - if(!argv) - return 0; + 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(PyTuple_GetItem(value,i)); - result = Tcl_NewListObj(PyTuple_Size(value), argv); - ckfree(FREECAST argv); + argv[i] = AsObj(PySequence_Fast_GET_ITEM(value,i)); + result = Tcl_NewListObj((int)size, argv); + PyMem_Free(argv); return result; } - else if (PyUnicode_Check(value)) { + + if (PyUnicode_Check(value)) { void *inbuf; Py_ssize_t size; int kind; @@ -888,13 +1114,17 @@ AsObj(PyObject *value) inbuf = PyUnicode_DATA(value); size = PyUnicode_GET_LENGTH(value); + if (size == 0) + return Tcl_NewUnicodeObj((const void *)"", 0); if (!CHECK_SIZE(size, sizeof(Tcl_UniChar))) { PyErr_SetString(PyExc_OverflowError, "string is too long"); return NULL; } kind = PyUnicode_KIND(value); + if (kind == sizeof(Tcl_UniChar)) + return Tcl_NewUnicodeObj(inbuf, (int)size); allocsize = ((size_t)size) * sizeof(Tcl_UniChar); - outbuf = (Tcl_UniChar*)ckalloc(allocsize); + outbuf = (Tcl_UniChar*)PyMem_Malloc(allocsize); /* Else overflow occurred, and we take the next exit */ if (!outbuf) { PyErr_NoMemory(); @@ -911,22 +1141,24 @@ AsObj(PyObject *value) "character U+%x is above the range " "(U+0000-U+FFFF) allowed by Tcl", ch); - ckfree(FREECAST outbuf); + PyMem_Free(outbuf); return NULL; } #endif outbuf[i] = ch; } - result = Tcl_NewUnicodeObj(outbuf, size); - ckfree(FREECAST outbuf); + result = Tcl_NewUnicodeObj(outbuf, (int)size); + PyMem_Free(outbuf); return result; } - else if(PyTclObject_Check(value)) { + + if (PyTclObject_Check(value)) { Tcl_Obj *v = ((PyTclObject*)value)->value; Tcl_IncrRefCount(v); return v; } - else { + + { PyObject *v = PyObject_Str(value); if (!v) return 0; @@ -936,21 +1168,83 @@ AsObj(PyObject *value) } } +static PyObject * +fromBoolean(PyObject* 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(PyObject* tkapp, Tcl_Obj *value) +{ + Tcl_WideInt wideValue; + if (Tcl_GetWideIntFromObj(Tkapp_Interp(tkapp), value, &wideValue) == TCL_OK) { +#ifdef HAVE_LONG_LONG + if (sizeof(wideValue) <= SIZEOF_LONG_LONG) + return PyLong_FromLongLong(wideValue); +#endif + return _PyLong_FromByteArray((unsigned char *)(void *)&wideValue, + sizeof(wideValue), + PY_LITTLE_ENDIAN, + /* signed */ 1); + } + return NULL; +} + +#ifdef HAVE_LIBTOMMAMTH +static PyObject* +fromBignumObj(PyObject* 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(PyObject* tkapp, Tcl_Obj *value) { PyObject *result = NULL; TkappObject *app = (TkappObject*)tkapp; + Tcl_Interp *interp = Tkapp_Interp(tkapp); if (value->typePtr == NULL) { - return PyUnicode_FromStringAndSize(value->bytes, - value->length); + return unicodeFromTclStringAndSize(value->bytes, value->length); } - if (value->typePtr == app->BooleanType) { - result = value->internalRep.longValue ? Py_True : Py_False; - Py_INCREF(result); - return result; + if (value->typePtr == app->BooleanType || + value->typePtr == app->OldBooleanType) { + return fromBoolean(tkapp, value); } if (value->typePtr == app->ByteArrayType) { @@ -964,8 +1258,30 @@ FromObj(PyObject* tkapp, Tcl_Obj *value) } if (value->typePtr == app->IntType) { - return PyLong_FromLong(value->internalRep.longValue); + 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 == app->IntType || + value->typePtr == app->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 == app->IntType || + value->typePtr == app->WideIntType || + value->typePtr == app->BignumType) { + return fromBignumObj(tkapp, value); } +#endif if (value->typePtr == app->ListType) { int size; @@ -973,15 +1289,14 @@ FromObj(PyObject* tkapp, Tcl_Obj *value) PyObject *elem; Tcl_Obj *tcl_elem; - status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size); + 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(Tkapp_Interp(tkapp), - value, i, &tcl_elem); + status = Tcl_ListObjIndex(interp, value, i, &tcl_elem); if (status == TCL_ERROR) { Py_DECREF(result); return Tkinter_Error(tkapp); @@ -1001,16 +1316,28 @@ FromObj(PyObject* tkapp, Tcl_Obj *value) } if (value->typePtr == app->StringType) { -#if TCL_UTF_MAX==3 return PyUnicode_FromKindAndData( - PyUnicode_2BYTE_KIND, Tcl_GetUnicode(value), - Tcl_GetCharLength(value)); -#else - return PyUnicode_FromKindAndData( - PyUnicode_4BYTE_KIND, Tcl_GetUnicode(value), + sizeof(Tcl_UniChar), Tcl_GetUnicode(value), Tcl_GetCharLength(value)); + } + +#if TK_HEX_VERSION >= 0x08050000 + if (app->BooleanType == NULL && + strcmp(value->typePtr->name, "booleanString") == 0) { + /* booleanString type is not registered in Tcl */ + app->BooleanType = value->typePtr; + return fromBoolean(tkapp, value); + } #endif + +#ifdef HAVE_LIBTOMMAMTH + if (app->BignumType == NULL && + strcmp(value->typePtr->name, "bignum") == 0) { + /* bignum type is not registered in Tcl */ + app->BignumType = value->typePtr; + return fromBignumObj(tkapp, value); } +#endif return newPyTclObject(value); } @@ -1037,7 +1364,7 @@ Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc) for (i = 0; i < objc; i++) Tcl_DecrRefCount(objv[i]); if (objv != objStore) - ckfree(FREECAST objv); + PyMem_Free(objv); } /* Convert Python objects to Tcl objects. This must happen in the @@ -1051,7 +1378,7 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc) if (args == NULL) /* do nothing */; - else if (!PyTuple_Check(args)) { + else if (!(PyTuple_Check(args) || PyList_Check(args))) { objv[0] = AsObj(args); if (objv[0] == 0) goto finally; @@ -1059,14 +1386,16 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc) Tcl_IncrRefCount(objv[0]); } else { - objc = PyTuple_Size(args); + objc = PySequence_Fast_GET_SIZE(args); if (objc > ARGSZ) { if (!CHECK_SIZE(objc, sizeof(Tcl_Obj *))) { - PyErr_SetString(PyExc_OverflowError, "tuple is too long"); + PyErr_SetString(PyExc_OverflowError, + PyTuple_Check(args) ? "tuple is too long" : + "list is too long"); return NULL; } - objv = (Tcl_Obj **)ckalloc(((size_t)objc) * sizeof(Tcl_Obj *)); + objv = (Tcl_Obj **)PyMem_Malloc(((size_t)objc) * sizeof(Tcl_Obj *)); if (objv == NULL) { PyErr_NoMemory(); objc = 0; @@ -1075,7 +1404,7 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc) } for (i = 0; i < objc; i++) { - PyObject *v = PyTuple_GetItem(args, i); + PyObject *v = PySequence_Fast_GET_ITEM(args, i); if (v == Py_None) { objc = i; break; @@ -1090,10 +1419,10 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc) Tcl_IncrRefCount(objv[i]); } } - *pobjc = objc; + *pobjc = (int)objc; return objv; finally: - Tkapp_CallDeallocArgs(objv, objStore, objc); + Tkapp_CallDeallocArgs(objv, objStore, (int)objc); return NULL; } @@ -1103,8 +1432,8 @@ static PyObject* Tkapp_CallResult(TkappObject *self) { PyObject *res = NULL; + Tcl_Obj *value = Tcl_GetObjResult(self->interp); if(self->wantobjects) { - Tcl_Obj *value = Tcl_GetObjResult(self->interp); /* Not sure whether the IncrRef is necessary, but something may overwrite the interpreter result while we are converting it. */ @@ -1112,7 +1441,7 @@ Tkapp_CallResult(TkappObject *self) res = FromObj((PyObject*)self, value); Tcl_DecrRefCount(value); } else { - res = PyUnicode_FromString(Tcl_GetStringResult(self->interp)); + res = unicodeFromTclObj(value); } return res; } @@ -1202,7 +1531,11 @@ Tkapp_Call(PyObject *selfptr, PyObject *args) PyObject *exc_type, *exc_value, *exc_tb; if (!WaitForMainloop(self)) return NULL; - ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent)); + 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; @@ -1249,83 +1582,106 @@ Tkapp_Call(PyObject *selfptr, PyObject *args) } +/*[clinic input] +_tkinter.tkapp.eval + + script: str + / + +[clinic start generated code]*/ + static PyObject * -Tkapp_Eval(PyObject *self, PyObject *args) +_tkinter_tkapp_eval_impl(TkappObject *self, const char *script) +/*[clinic end generated code: output=24b79831f700dea0 input=481484123a455f22]*/ { - char *script; PyObject *res = NULL; int err; - if (!PyArg_ParseTuple(args, "s:eval", &script)) - return NULL; - + 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); + res = Tkinter_Error((PyObject *)self); else - res = PyUnicode_FromString(Tkapp_Result(self)); + res = unicodeFromTclString(Tkapp_Result(self)); LEAVE_OVERLAP_TCL return res; } +/*[clinic input] +_tkinter.tkapp.evalfile + + fileName: str + / + +[clinic start generated code]*/ + static PyObject * -Tkapp_EvalFile(PyObject *self, PyObject *args) +_tkinter_tkapp_evalfile_impl(TkappObject *self, const char *fileName) +/*[clinic end generated code: output=63be88dcee4f11d3 input=873ab707e5e947e1]*/ { - char *fileName; PyObject *res = NULL; int err; - if (!PyArg_ParseTuple(args, "s:evalfile", &fileName)) - return NULL; - + 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); - + res = Tkinter_Error((PyObject *)self); else - res = PyUnicode_FromString(Tkapp_Result(self)); + res = unicodeFromTclString(Tkapp_Result(self)); LEAVE_OVERLAP_TCL return res; } +/*[clinic input] +_tkinter.tkapp.record + + script: str + / + +[clinic start generated code]*/ + static PyObject * -Tkapp_Record(PyObject *self, PyObject *args) +_tkinter_tkapp_record_impl(TkappObject *self, const char *script) +/*[clinic end generated code: output=0ffe08a0061730df input=c0b0db5a21412cac]*/ { - char *script; PyObject *res = NULL; int err; - if (!PyArg_ParseTuple(args, "s", &script)) - return NULL; - + 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); + res = Tkinter_Error((PyObject *)self); else - res = PyUnicode_FromString(Tkapp_Result(self)); + res = unicodeFromTclString(Tkapp_Result(self)); LEAVE_OVERLAP_TCL return res; } +/*[clinic input] +_tkinter.tkapp.adderrinfo + + msg: str + / + +[clinic start generated code]*/ + static PyObject * -Tkapp_AddErrorInfo(PyObject *self, PyObject *args) +_tkinter_tkapp_adderrinfo_impl(TkappObject *self, const char *msg) +/*[clinic end generated code: output=0e222ee2050eb357 input=4971399317d4c136]*/ { - char *msg; - - if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg)) - return NULL; + CHECK_STRING_LENGTH(msg); CHECK_TCL_APPARTMENT; ENTER_TCL @@ -1357,23 +1713,57 @@ typedef struct VarEvent { } VarEvent; #endif +/*[python] + +class varname_converter(CConverter): + type = 'const char *' + converter = 'varname_converter' + +[python]*/ +/*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + static int varname_converter(PyObject *in, void *_out) { + char *s; char **out = (char**)_out; if (PyBytes_Check(in)) { - *out = PyBytes_AsString(in); + if (PyBytes_Size(in) > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, "bytes object is too long"); + return 0; + } + s = PyBytes_AsString(in); + if (strlen(s) != (size_t)PyBytes_Size(in)) { + PyErr_SetString(PyExc_ValueError, "embedded null byte"); + return 0; + } + *out = s; return 1; } if (PyUnicode_Check(in)) { - *out = _PyUnicode_AsString(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 = PyTclObject_TclString(in); return 1; } - /* XXX: Should give diagnostics. */ + PyErr_Format(PyExc_TypeError, + "must be str, bytes or Tcl_Obj, not %.50s", + in->ob_type->tp_name); return 0; } @@ -1414,7 +1804,6 @@ var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags) #ifdef WITH_THREAD TkappObject *self = (TkappObject*)selfptr; if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { - TkappObject *self = (TkappObject*)selfptr; VarEvent *ev; PyObject *res, *exc_type, *exc_val; Tcl_Condition cond = NULL; @@ -1425,8 +1814,11 @@ var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags) if (!WaitForMainloop(self)) return NULL; - ev = (VarEvent*)ckalloc(sizeof(VarEvent)); - + ev = (VarEvent*)attemptckalloc(sizeof(VarEvent)); + if (ev == NULL) { + PyErr_NoMemory(); + return NULL; + } ev->self = selfptr; ev->args = args; ev->flags = flags; @@ -1459,8 +1851,11 @@ SetVar(PyObject *self, PyObject *args, int flags) PyObject *res = NULL; Tcl_Obj *newval, *ok; - if (PyArg_ParseTuple(args, "O&O:setvar", - varname_converter, &name1, &newValue)) { + 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) @@ -1476,27 +1871,29 @@ SetVar(PyObject *self, PyObject *args, int flags) Py_INCREF(res); } LEAVE_OVERLAP_TCL - } - else { - PyErr_Clear(); - if (PyArg_ParseTuple(args, "ssO:setvar", - &name1, &name2, &newValue)) { - /* 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 - } - else { + 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; } @@ -1526,6 +1923,7 @@ GetVar(PyObject *self, PyObject *args, int flags) varname_converter, &name1, &name2)) return NULL; + CHECK_STRING_LENGTH(name2); ENTER_TCL tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags); ENTER_OVERLAP @@ -1537,7 +1935,7 @@ GetVar(PyObject *self, PyObject *args, int flags) res = FromObj(self, tres); } else { - res = PyUnicode_FromString(Tcl_GetString(tres)); + res = unicodeFromTclObj(tres); } } LEAVE_OVERLAP_TCL @@ -1568,6 +1966,8 @@ UnsetVar(PyObject *self, PyObject *args, int flags) 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 @@ -1598,123 +1998,207 @@ Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args) /** Tcl to Python **/ +/*[clinic input] +_tkinter.tkapp.getint + + arg: object + / + +[clinic start generated code]*/ + static PyObject * -Tkapp_GetInt(PyObject *self, PyObject *args) +_tkinter_tkapp_getint(TkappObject *self, PyObject *arg) +/*[clinic end generated code: output=88cf293fae307cfe input=034026997c5b91f8]*/ { char *s; - int v; + Tcl_Obj *value; + PyObject *result; - if (PyTuple_Size(args) == 1) { - PyObject* o = PyTuple_GetItem(args, 0); - if (PyLong_Check(o)) { - Py_INCREF(o); - return o; - } + if (PyLong_Check(arg)) { + Py_INCREF(arg); + return arg; } - if (!PyArg_ParseTuple(args, "s:getint", &s)) - return NULL; - if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR) - return Tkinter_Error(self); - return Py_BuildValue("i", v); + + 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((PyObject *)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((PyObject *)self, value); +#else + result = fromWideIntObj((PyObject *)self, value); +#endif + Tcl_DecrRefCount(value); + if (result != NULL || PyErr_Occurred()) + return result; + return Tkinter_Error((PyObject *)self); } +/*[clinic input] +_tkinter.tkapp.getdouble + + arg: object + / + +[clinic start generated code]*/ + static PyObject * -Tkapp_GetDouble(PyObject *self, PyObject *args) +_tkinter_tkapp_getdouble(TkappObject *self, PyObject *arg) +/*[clinic end generated code: output=c52b138bd8b956b9 input=22015729ce9ef7f8]*/ { char *s; double v; - if (PyTuple_Size(args) == 1) { - PyObject *o = PyTuple_GetItem(args, 0); - if (PyFloat_Check(o)) { - Py_INCREF(o); - return o; - } + if (PyFloat_Check(arg)) { + Py_INCREF(arg); + return arg; } - if (!PyArg_ParseTuple(args, "s:getdouble", &s)) + + 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((PyObject *)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 Py_BuildValue("d", v); + return Tkinter_Error((PyObject *)self); + return PyFloat_FromDouble(v); } +/*[clinic input] +_tkinter.tkapp.getboolean + + arg: object + / + +[clinic start generated code]*/ + static PyObject * -Tkapp_GetBoolean(PyObject *self, PyObject *args) +_tkinter_tkapp_getboolean(TkappObject *self, PyObject *arg) +/*[clinic end generated code: output=726a9ae445821d91 input=7f11248ef8f8776e]*/ { char *s; int v; - if (PyTuple_Size(args) == 1) { - PyObject *o = PyTuple_GetItem(args, 0); - if (PyLong_Check(o)) { - Py_INCREF(o); - return o; - } + 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((PyObject *)self); + return PyBool_FromLong(v); } - if (!PyArg_ParseTuple(args, "s:getboolean", &s)) + + 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 Tkinter_Error((PyObject *)self); return PyBool_FromLong(v); } +/*[clinic input] +_tkinter.tkapp.exprstring + + s: str + / + +[clinic start generated code]*/ + static PyObject * -Tkapp_ExprString(PyObject *self, PyObject *args) +_tkinter_tkapp_exprstring_impl(TkappObject *self, const char *s) +/*[clinic end generated code: output=beda323d3ed0abb1 input=fa78f751afb2f21b]*/ { - char *s; PyObject *res = NULL; int retval; - if (!PyArg_ParseTuple(args, "s:exprstring", &s)) - return NULL; - + 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); + res = Tkinter_Error((PyObject *)self); else - res = Py_BuildValue("s", Tkapp_Result(self)); + res = unicodeFromTclString(Tkapp_Result(self)); LEAVE_OVERLAP_TCL return res; } +/*[clinic input] +_tkinter.tkapp.exprlong + + s: str + / + +[clinic start generated code]*/ + static PyObject * -Tkapp_ExprLong(PyObject *self, PyObject *args) +_tkinter_tkapp_exprlong_impl(TkappObject *self, const char *s) +/*[clinic end generated code: output=5d6a46b63c6ebcf9 input=11bd7eee0c57b4dc]*/ { - char *s; PyObject *res = NULL; int retval; long v; - if (!PyArg_ParseTuple(args, "s:exprlong", &s)) - return NULL; - + 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); + res = Tkinter_Error((PyObject *)self); else - res = Py_BuildValue("l", v); + res = PyLong_FromLong(v); LEAVE_OVERLAP_TCL return res; } +/*[clinic input] +_tkinter.tkapp.exprdouble + + s: str + / + +[clinic start generated code]*/ + static PyObject * -Tkapp_ExprDouble(PyObject *self, PyObject *args) +_tkinter_tkapp_exprdouble_impl(TkappObject *self, const char *s) +/*[clinic end generated code: output=ff78df1081ea4158 input=ff02bc11798832d5]*/ { - char *s; PyObject *res = NULL; double v; int retval; - if (!PyArg_ParseTuple(args, "s:exprdouble", &s)) - return NULL; + CHECK_STRING_LENGTH(s); CHECK_TCL_APPARTMENT; PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0) ENTER_TCL @@ -1722,60 +2206,74 @@ Tkapp_ExprDouble(PyObject *self, PyObject *args) ENTER_OVERLAP PyFPE_END_PROTECT(retval) if (retval == TCL_ERROR) - res = Tkinter_Error(self); + res = Tkinter_Error((PyObject *)self); else - res = Py_BuildValue("d", v); + res = PyFloat_FromDouble(v); LEAVE_OVERLAP_TCL return res; } +/*[clinic input] +_tkinter.tkapp.exprboolean + + s: str + / + +[clinic start generated code]*/ + static PyObject * -Tkapp_ExprBoolean(PyObject *self, PyObject *args) +_tkinter_tkapp_exprboolean_impl(TkappObject *self, const char *s) +/*[clinic end generated code: output=8b28038c22887311 input=c8c66022bdb8d5d3]*/ { - char *s; PyObject *res = NULL; int retval; int v; - if (!PyArg_ParseTuple(args, "s:exprboolean", &s)) - return NULL; + 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); + res = Tkinter_Error((PyObject *)self); else - res = Py_BuildValue("i", v); + res = PyLong_FromLong(v); LEAVE_OVERLAP_TCL return res; } +/*[clinic input] +_tkinter.tkapp.splitlist + + arg: object + / + +[clinic start generated code]*/ + static PyObject * -Tkapp_SplitList(PyObject *self, PyObject *args) +_tkinter_tkapp_splitlist(TkappObject *self, PyObject *arg) +/*[clinic end generated code: output=13b51d34386d36fb input=2b2e13351e3c0b53]*/ { char *list; int argc; - char **argv; - PyObject *arg, *v; + const char **argv; + PyObject *v; int i; - if (!PyArg_ParseTuple(args, "O:splitlist", &arg)) - return NULL; 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); + return Tkinter_Error((PyObject *)self); } if (!(v = PyTuple_New(objc))) return NULL; for (i = 0; i < objc; i++) { - PyObject *s = FromObj(self, objv[i]); + PyObject *s = FromObj((PyObject*)self, objv[i]); if (!s || PyTuple_SetItem(v, i, s)) { Py_DECREF(v); return NULL; @@ -1787,21 +2285,25 @@ Tkapp_SplitList(PyObject *self, PyObject *args) Py_INCREF(arg); return arg; } + if (PyList_Check(arg)) { + return PySequence_Tuple(arg); + } - if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list)) + if (!PyArg_Parse(arg, "et:splitlist", "utf-8", &list)) return NULL; + CHECK_STRING_LENGTH(list); if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR) { PyMem_Free(list); - return Tkinter_Error(self); + return Tkinter_Error((PyObject *)self); } if (!(v = PyTuple_New(argc))) goto finally; for (i = 0; i < argc; i++) { - PyObject *s = PyUnicode_FromString(argv[i]); + PyObject *s = unicodeFromTclString(argv[i]); if (!s || PyTuple_SetItem(v, i, s)) { Py_DECREF(v); v = NULL; @@ -1815,14 +2317,21 @@ Tkapp_SplitList(PyObject *self, PyObject *args) return v; } +/*[clinic input] +_tkinter.tkapp.split + + arg: object + / + +[clinic start generated code]*/ + static PyObject * -Tkapp_Split(PyObject *self, PyObject *args) +_tkinter_tkapp_split(TkappObject *self, PyObject *arg) +/*[clinic end generated code: output=e08ad832363facfd input=a1c78349eacaa140]*/ { - PyObject *arg, *v; + PyObject *v; char *list; - if (!PyArg_ParseTuple(args, "O:split", &arg)) - return NULL; if (PyTclObject_Check(arg)) { Tcl_Obj *value = ((PyTclObject*)arg)->value; int objc; @@ -1830,16 +2339,16 @@ Tkapp_Split(PyObject *self, PyObject *args) int i; if (Tcl_ListObjGetElements(Tkapp_Interp(self), value, &objc, &objv) == TCL_ERROR) { - return FromObj(self, value); + return FromObj((PyObject*)self, value); } if (objc == 0) return PyUnicode_FromString(""); if (objc == 1) - return FromObj(self, objv[0]); + return FromObj((PyObject*)self, objv[0]); if (!(v = PyTuple_New(objc))) return NULL; for (i = 0; i < objc; i++) { - PyObject *s = FromObj(self, objv[i]); + PyObject *s = FromObj((PyObject*)self, objv[i]); if (!s || PyTuple_SetItem(v, i, s)) { Py_DECREF(v); return NULL; @@ -1847,11 +2356,12 @@ Tkapp_Split(PyObject *self, PyObject *args) } return v; } - if (PyTuple_Check(arg)) + if (PyTuple_Check(arg) || PyList_Check(arg)) return SplitObj(arg); - if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list)) + if (!PyArg_Parse(arg, "et:split", "utf-8", &list)) return NULL; + CHECK_STRING_LENGTH(list); v = Split(list); PyMem_Free(list); return v; @@ -1880,7 +2390,7 @@ PythonCmd_Error(Tcl_Interp *interp) * function or method. */ static int -PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) +PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[]) { PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData; PyObject *func, *arg, *res; @@ -1899,20 +2409,8 @@ PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) return PythonCmd_Error(interp); for (i = 0; i < (argc - 1); i++) { - PyObject *s = PyUnicode_FromString(argv[i + 1]); - if (!s) { - /* Is Tk leaking 0xC080 in %A - a "modified" utf-8 null? */ - if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError) && - !strcmp(argv[i + 1], "\xC0\x80")) { - PyErr_Clear(); - /* Convert to "strict" utf-8 null */ - s = PyUnicode_FromString("\0"); - } else { - Py_DECREF(arg); - return PythonCmd_Error(interp); - } - } - if (PyTuple_SetItem(arg, i, s)) { + PyObject *s = unicodeFromTclString(argv[i + 1]); + if (!s || PyTuple_SetItem(arg, i, s)) { Py_DECREF(arg); return PythonCmd_Error(interp); } @@ -1961,7 +2459,7 @@ TCL_DECLARE_MUTEX(command_mutex) typedef struct CommandEvent{ Tcl_Event ev; Tcl_Interp* interp; - char *name; + const char *name; int create; int *status; ClientData *data; @@ -1984,17 +2482,25 @@ Tkapp_CommandProc(CommandEvent *ev, int flags) } #endif +/*[clinic input] +_tkinter.tkapp.createcommand + + self: self(type="TkappObject *") + name: str + func: object + / + +[clinic start generated code]*/ + static PyObject * -Tkapp_CreateCommand(PyObject *selfptr, PyObject *args) +_tkinter_tkapp_createcommand_impl(TkappObject *self, const char *name, + PyObject *func) +/*[clinic end generated code: output=2a1c79a4ee2af410 input=2bc2c046a0914234]*/ { - TkappObject *self = (TkappObject*)selfptr; PythonCmd_ClientData *data; - char *cmdName; - PyObject *func; int err; - if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func)) - return NULL; + CHECK_STRING_LENGTH(name); if (!PyCallable_Check(func)) { PyErr_SetString(PyExc_TypeError, "command not callable"); return NULL; @@ -2011,16 +2517,21 @@ Tkapp_CreateCommand(PyObject *selfptr, PyObject *args) return PyErr_NoMemory(); Py_INCREF(self); Py_INCREF(func); - data->self = selfptr; + data->self = (PyObject *) self; data->func = func; #ifdef WITH_THREAD if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { Tcl_Condition cond = NULL; - CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent)); + 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 = cmdName; + ev->name = name; ev->data = (ClientData)data; ev->status = &err; ev->done = &cond; @@ -2032,7 +2543,7 @@ Tkapp_CreateCommand(PyObject *selfptr, PyObject *args) { ENTER_TCL err = Tcl_CreateCommand( - Tkapp_Interp(self), cmdName, PythonCmd, + Tkapp_Interp(self), name, PythonCmd, (ClientData)data, PythonCmdDelete) == NULL; LEAVE_TCL } @@ -2047,25 +2558,36 @@ Tkapp_CreateCommand(PyObject *selfptr, PyObject *args) +/*[clinic input] +_tkinter.tkapp.deletecommand + + self: self(type="TkappObject *") + name: str + / + +[clinic start generated code]*/ + static PyObject * -Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args) +_tkinter_tkapp_deletecommand_impl(TkappObject *self, const char *name) +/*[clinic end generated code: output=a67e8cb5845e0d2d input=b6306468f10b219c]*/ { - TkappObject *self = (TkappObject*)selfptr; - char *cmdName; int err; - if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName)) - return NULL; + CHECK_STRING_LENGTH(name); #ifdef WITH_THREAD if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { Tcl_Condition cond = NULL; CommandEvent *ev; - ev = (CommandEvent*)ckalloc(sizeof(CommandEvent)); + 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 = cmdName; + ev->name = name; ev->status = &err; ev->done = &cond; Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, @@ -2076,7 +2598,7 @@ Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args) #endif { ENTER_TCL - err = Tcl_DeleteCommand(self->interp, cmdName); + err = Tcl_DeleteCommand(self->interp, name); LEAVE_TCL } if (err == -1) { @@ -2157,17 +2679,23 @@ FileHandler(ClientData clientData, int mask) LEAVE_PYTHON } +/*[clinic input] +_tkinter.tkapp.createfilehandler + + file: object + mask: int + func: object + / + +[clinic start generated code]*/ + static PyObject * -Tkapp_CreateFileHandler(PyObject *self, PyObject *args) - /* args is (file, mask, func) */ +_tkinter_tkapp_createfilehandler_impl(TkappObject *self, PyObject *file, + int mask, PyObject *func) +/*[clinic end generated code: output=f73ce82de801c353 input=84943a5286e47947]*/ { FileHandler_ClientData *data; - PyObject *file, *func; - int mask, tfile; - - if (!PyArg_ParseTuple(args, "OiO:createfilehandler", - &file, &mask, &func)) - return NULL; + int tfile; CHECK_TCL_APPARTMENT; @@ -2190,15 +2718,20 @@ Tkapp_CreateFileHandler(PyObject *self, PyObject *args) Py_RETURN_NONE; } +/*[clinic input] +_tkinter.tkapp.deletefilehandler + + file: object + / + +[clinic start generated code]*/ + static PyObject * -Tkapp_DeleteFileHandler(PyObject *self, PyObject *args) +_tkinter_tkapp_deletefilehandler(TkappObject *self, PyObject *file) +/*[clinic end generated code: output=b53cc96ebf9476fd input=abbec19d66312e2a]*/ { - PyObject *file; int tfile; - if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file)) - return NULL; - CHECK_TCL_APPARTMENT; tfile = PyObject_AsFileDescriptor(file); @@ -2226,14 +2759,20 @@ typedef struct { PyObject *func; } TkttObject; +/*[clinic input] +_tkinter.tktimertoken.deletetimerhandler + + self: self(type="TkttObject *") + +[clinic start generated code]*/ + static PyObject * -Tktt_DeleteTimerHandler(PyObject *self, PyObject *args) +_tkinter_tktimertoken_deletetimerhandler_impl(TkttObject *self) +/*[clinic end generated code: output=bd7fe17f328cfa55 input=25ba5dd594e52084]*/ { - TkttObject *v = (TkttObject *)self; + TkttObject *v = self; PyObject *func = v->func; - if (!PyArg_ParseTuple(args, ":deletetimerhandler")) - return NULL; if (v->token != NULL) { Tcl_DeleteTimerHandler(v->token); v->token = NULL; @@ -2246,12 +2785,6 @@ Tktt_DeleteTimerHandler(PyObject *self, PyObject *args) Py_RETURN_NONE; } -static PyMethodDef Tktt_methods[] = -{ - {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS}, - {NULL, NULL} -}; - static TkttObject * Tktt_New(PyObject *func) { @@ -2293,22 +2826,6 @@ Tktt_Repr(PyObject *self) v->func == NULL ? ", handler deleted" : ""); } -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 = { - "tktimertoken", - sizeof(TkttObject), - 0, - Py_TPFLAGS_DEFAULT, - Tktt_Type_slots, -}; - - /** Timer Handler **/ static void @@ -2339,16 +2856,22 @@ TimerHandler(ClientData clientData) LEAVE_PYTHON } +/*[clinic input] +_tkinter.tkapp.createtimerhandler + + milliseconds: int + func: object + / + +[clinic start generated code]*/ + static PyObject * -Tkapp_CreateTimerHandler(PyObject *self, PyObject *args) +_tkinter_tkapp_createtimerhandler_impl(TkappObject *self, int milliseconds, + PyObject *func) +/*[clinic end generated code: output=2da5959b9d031911 input=ba6729f32f0277a5]*/ { - int milliseconds; - PyObject *func; TkttObject *v; - if (!PyArg_ParseTuple(args, "iO:createtimerhandler", - &milliseconds, &func)) - return NULL; if (!PyCallable_Check(func)) { PyErr_SetString(PyExc_TypeError, "bad argument list"); return NULL; @@ -2368,18 +2891,23 @@ Tkapp_CreateTimerHandler(PyObject *self, PyObject *args) /** Event Loop **/ +/*[clinic input] +_tkinter.tkapp.mainloop + + self: self(type="TkappObject *") + threshold: int = 0 + / + +[clinic start generated code]*/ + static PyObject * -Tkapp_MainLoop(PyObject *selfptr, PyObject *args) +_tkinter_tkapp_mainloop_impl(TkappObject *self, int threshold) +/*[clinic end generated code: output=0ba8eabbe57841b0 input=ad57c9c1dd2b9470]*/ { - int threshold = 0; - TkappObject *self = (TkappObject*)selfptr; #ifdef WITH_THREAD PyThreadState *tstate = PyThreadState_Get(); #endif - if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold)) - return NULL; - CHECK_TCL_APPARTMENT; self->dispatching = 1; @@ -2431,44 +2959,56 @@ Tkapp_MainLoop(PyObject *selfptr, PyObject *args) Py_RETURN_NONE; } +/*[clinic input] +_tkinter.tkapp.dooneevent + + flags: int = 0 + / + +[clinic start generated code]*/ + static PyObject * -Tkapp_DoOneEvent(PyObject *self, PyObject *args) +_tkinter_tkapp_dooneevent_impl(TkappObject *self, int flags) +/*[clinic end generated code: output=27c6b2aa464cac29 input=6542b928e364b793]*/ { - int flags = 0; int rv; - if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags)) - return NULL; - ENTER_TCL rv = Tcl_DoOneEvent(flags); LEAVE_TCL - return Py_BuildValue("i", rv); + return PyLong_FromLong(rv); } +/*[clinic input] +_tkinter.tkapp.quit +[clinic start generated code]*/ + static PyObject * -Tkapp_Quit(PyObject *self, PyObject *args) +_tkinter_tkapp_quit_impl(TkappObject *self) +/*[clinic end generated code: output=7f21eeff481f754f input=e03020dc38aff23c]*/ { - - if (!PyArg_ParseTuple(args, ":quit")) - return NULL; - quitMainLoop = 1; Py_RETURN_NONE; } +/*[clinic input] +_tkinter.tkapp.interpaddr +[clinic start generated code]*/ + static PyObject * -Tkapp_InterpAddr(PyObject *self, PyObject *args) +_tkinter_tkapp_interpaddr_impl(TkappObject *self) +/*[clinic end generated code: output=6caaae3273b3c95a input=2dd32cbddb55a111]*/ { - - if (!PyArg_ParseTuple(args, ":interpaddr")) - return NULL; - return PyLong_FromVoidPtr(Tkapp_Interp(self)); } +/*[clinic input] +_tkinter.tkapp.loadtk +[clinic start generated code]*/ + static PyObject * -Tkapp_TkInit(PyObject *self, PyObject *args) +_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; @@ -2494,7 +3034,7 @@ Tkapp_TkInit(PyObject *self, PyObject *args) 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); + Tkinter_Error((PyObject *)self); } else { _tk_exists = Tkapp_Result(self); } @@ -2529,57 +3069,21 @@ Tkapp_WantObjects(PyObject *self, PyObject *args) Py_RETURN_NONE; } -static PyObject * -Tkapp_WillDispatch(PyObject *self, PyObject *args) -{ +/*[clinic input] +_tkinter.tkapp.willdispatch - ((TkappObject*)self)->dispatching = 1; + self: self(type="TkappObject *") - Py_RETURN_NONE; -} +[clinic start generated code]*/ - -/**** Tkapp Method List ****/ - -static PyMethodDef Tkapp_methods[] = +static PyObject * +_tkinter_tkapp_willdispatch_impl(TkappObject *self) +/*[clinic end generated code: output=0e3f46d244642155 input=2630699767808970]*/ { - {"willdispatch", Tkapp_WillDispatch, METH_NOARGS}, - {"wantobjects", Tkapp_WantObjects, METH_VARARGS}, - {"call", Tkapp_Call, METH_VARARGS}, - {"eval", Tkapp_Eval, METH_VARARGS}, - {"evalfile", Tkapp_EvalFile, METH_VARARGS}, - {"record", Tkapp_Record, METH_VARARGS}, - {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS}, - {"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}, - {"getint", Tkapp_GetInt, METH_VARARGS}, - {"getdouble", Tkapp_GetDouble, METH_VARARGS}, - {"getboolean", Tkapp_GetBoolean, METH_VARARGS}, - {"exprstring", Tkapp_ExprString, METH_VARARGS}, - {"exprlong", Tkapp_ExprLong, METH_VARARGS}, - {"exprdouble", Tkapp_ExprDouble, METH_VARARGS}, - {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS}, - {"splitlist", Tkapp_SplitList, METH_VARARGS}, - {"split", Tkapp_Split, METH_VARARGS}, - {"createcommand", Tkapp_CreateCommand, METH_VARARGS}, - {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS}, -#ifdef HAVE_CREATEFILEHANDLER - {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS}, - {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS}, -#endif - {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS}, - {"mainloop", Tkapp_MainLoop, METH_VARARGS}, - {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS}, - {"quit", Tkapp_Quit, METH_VARARGS}, - {"interpaddr", Tkapp_InterpAddr, METH_VARARGS}, - {"loadtk", Tkapp_TkInit, METH_NOARGS}, - {NULL, NULL} -}; + self->dispatching = 1; + Py_RETURN_NONE; +} /**** Tkapp Type Methods ****/ @@ -2597,41 +3101,26 @@ Tkapp_Dealloc(PyObject *self) DisableEventHook(); } -static PyType_Slot Tkapp_Type_slots[] = { - {Py_tp_dealloc, Tkapp_Dealloc}, - {Py_tp_methods, Tkapp_methods}, - {0, 0} -}; - - -static PyType_Spec Tkapp_Type_spec = { - "tkapp", - sizeof(TkappObject), - 0, - Py_TPFLAGS_DEFAULT, - Tkapp_Type_slots, -}; - /**** Tkinter Module ****/ typedef struct { PyObject* tuple; - int size; /* current size */ - int maxsize; /* allocated size */ + Py_ssize_t size; /* current size */ + Py_ssize_t maxsize; /* allocated size */ } FlattenContext; static int -_bump(FlattenContext* context, int size) +_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 */ - int maxsize = context->maxsize * 2; + Py_ssize_t maxsize = context->maxsize * 2; /* never overflows */ if (maxsize < context->size + size) - maxsize = context->size + size; + maxsize = context->size + size; /* never overflows */ context->maxsize = maxsize; @@ -2643,41 +3132,21 @@ _flatten1(FlattenContext* context, PyObject* item, int depth) { /* add tuple or list to argument tuple (recursively) */ - int i, size; + Py_ssize_t i, size; if (depth > 1000) { PyErr_SetString(PyExc_ValueError, "nesting too deep in _flatten"); return 0; - } else if (PyList_Check(item)) { - size = PyList_GET_SIZE(item); + } 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 = PyList_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 if (PyTuple_Check(item)) { - /* same, for tuples */ - size = PyTuple_GET_SIZE(item); - if (context->size + size > context->maxsize && - !_bump(context, size)) - return 0; - for (i = 0; i < size; i++) { - PyObject *o = PyTuple_GET_ITEM(item, i); + PyObject *o = PySequence_Fast_GET_ITEM(item, i); if (PyList_Check(o) || PyTuple_Check(o)) { if (!_flatten1(context, o, depth + 1)) return 0; @@ -2697,14 +3166,19 @@ _flatten1(FlattenContext* context, PyObject* item, int depth) return 1; } +/*[clinic input] +_tkinter._flatten + + item: object + / + +[clinic start generated code]*/ + static PyObject * -Tkinter_Flatten(PyObject* self, PyObject* args) +_tkinter__flatten(PyModuleDef *module, PyObject *item) +/*[clinic end generated code: output=9505049ec74c3480 input=6b9c12260aa1157f]*/ { FlattenContext context; - PyObject* item; - - if (!PyArg_ParseTuple(args, "O:_flatten", &item)) - return NULL; context.maxsize = PySequence_Size(item); if (context.maxsize < 0) @@ -2727,38 +3201,58 @@ Tkinter_Flatten(PyObject* self, PyObject* args) return context.tuple; } +/*[clinic input] +_tkinter.create + + screenName: str(accept={str, NoneType}) = NULL + baseName: str = NULL + className: str = "Tk" + interactive: int(c_default="0") = False + wantobjects: int(c_default="0") = False + wantTk: int(c_default="1") = True + if false, then Tk_Init() doesn't get called + sync: int(c_default="0") = False + if true, then pass -sync to wish + use: str(accept={str, NoneType}) = NULL + if not None, then pass -use to wish + / + +[clinic start generated code]*/ + static PyObject * -Tkinter_Create(PyObject *self, PyObject *args) -{ - char *screenName = NULL; - char *baseName = NULL; /* XXX this is not used anymore; - try getting rid of it. */ - char *className = NULL; - int interactive = 0; - int wantobjects = 0; - int wantTk = 1; /* If false, then Tk_Init() doesn't get called */ - int sync = 0; /* pass -sync to wish */ - char *use = NULL; /* pass -use to wish */ - - className = "Tk"; - - if (!PyArg_ParseTuple(args, "|zssiiiiz:create", - &screenName, &baseName, &className, - &interactive, &wantobjects, &wantTk, - &sync, &use)) - return NULL; +_tkinter_create_impl(PyModuleDef *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=b8847800fc3b27eb input=0d522aad1cb0ca0e]*/ +{ + /* 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(PyObject *self, PyObject *args) +_tkinter_setbusywaitinterval_impl(PyModuleDef *module, int new_val) +/*[clinic end generated code: output=0b9d7ef7940461ea input=deca1d6f9e6dae47]*/ { - int new_val; - if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val)) - return NULL; if (new_val < 0) { PyErr_SetString(PyExc_ValueError, "busywaitinterval must be >= 0"); @@ -2768,34 +3262,103 @@ Tkinter_setbusywaitinterval(PyObject *self, PyObject *args) Py_RETURN_NONE; } -static char setbusywaitinterval_doc[] = -"setbusywaitinterval(n) -> None\n\ -\n\ -Set the busy-wait interval in milliseconds between successive\n\ -calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\ -It should be set to a divisor of the maximum time between\n\ -frames in an animation."; +/*[clinic input] +_tkinter.getbusywaitinterval -> int -static PyObject * -Tkinter_getbusywaitinterval(PyObject *self, PyObject *args) +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(PyModuleDef *module) +/*[clinic end generated code: output=9d09eee026e96971 input=a695878d2d576a84]*/ { - return PyLong_FromLong(Tkinter_busywaitinterval); + return Tkinter_busywaitinterval; } -static char getbusywaitinterval_doc[] = -"getbusywaitinterval() -> int\n\ -\n\ -Return the current busy-wait interval between successive\n\ -calls to Tcl_DoOneEvent in a threaded Python interpreter."; +#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_ADDERRINFO_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[] = { - {"_flatten", Tkinter_Flatten, METH_VARARGS}, - {"create", Tkinter_Create, METH_VARARGS}, - {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS, - setbusywaitinterval_doc}, - {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval, - METH_NOARGS, getbusywaitinterval_doc}, + _TKINTER__FLATTEN_METHODDEF + _TKINTER_CREATE_METHODDEF + _TKINTER_SETBUSYWAITINTERVAL_METHODDEF + _TKINTER_GETBUSYWAITINTERVAL_METHODDEF {NULL, NULL} }; @@ -3039,8 +3602,40 @@ PyInit__tkinter(void) uexe = PyUnicode_FromWideChar(Py_GetProgramName(), -1); if (uexe) { cexe = PyUnicode_EncodeFSDefault(uexe); - if (cexe) + 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()) { + return NULL; + } + if (str_path != NULL) { + wcs_path = PyUnicode_AsWideCharString(str_path, NULL); + if (wcs_path == NULL) { + return NULL; + } + SetEnvironmentVariableW(L"TCL_LIBRARY", wcs_path); + set_var = 1; + } + } + + Tcl_FindExecutable(PyBytes_AsString(cexe)); + + if (set_var) { + SetEnvironmentVariableW(L"TCL_LIBRARY", NULL); + PyMem_Free(wcs_path); + } +#else Tcl_FindExecutable(PyBytes_AsString(cexe)); +#endif /* MS_WINDOWS */ + } Py_XDECREF(cexe); Py_DECREF(uexe); } diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index 7b88a7459482..226a473b4c74 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -16,14 +16,11 @@ static void raw_free(void *ptr); # define TRACE_DEBUG #endif -#define _STR(VAL) #VAL -#define STR(VAL) _STR(VAL) - /* Protected by the GIL */ static struct { - PyMemAllocator mem; - PyMemAllocator raw; - PyMemAllocator obj; + PyMemAllocatorEx mem; + PyMemAllocatorEx raw; + PyMemAllocatorEx obj; } allocators; static struct { @@ -60,11 +57,12 @@ static PyThread_type_lock tables_lock; /* Pack the frame_t structure to reduce the memory footprint on 64-bit architectures: 12 bytes instead of 16. This optimization might produce SIGBUS on architectures not supporting unaligned memory accesses (64-bit - IPS CPU?): on such architecture, the structure must not be packed. */ -#pragma pack(4) + MIPS CPU?): on such architecture, the structure must not be packed. */ typedef struct #ifdef __GNUC__ __attribute__((packed)) +#elif defined(_MSC_VER) +_declspec(align(4)) #endif { PyObject *filename; @@ -81,7 +79,7 @@ typedef struct { (sizeof(traceback_t) + sizeof(frame_t) * (NFRAME - 1)) #define MAX_NFRAME \ - ((INT_MAX - sizeof(traceback_t)) / sizeof(frame_t) + 1) + ((INT_MAX - (int)sizeof(traceback_t)) / (int)sizeof(frame_t) + 1) static PyObject *unknown_filename = NULL; static traceback_t tracemalloc_empty_traceback; @@ -103,7 +101,7 @@ static size_t tracemalloc_traced_memory = 0; Protected by TABLES_LOCK(). */ static size_t tracemalloc_peak_traced_memory = 0; -/* Hash table used as a set to to intern filenames: +/* Hash table used as a set to intern filenames: PyObject* => PyObject*. Protected by the GIL */ static _Py_hashtable_t *tracemalloc_filenames = NULL; @@ -168,14 +166,11 @@ set_reentrant(int reentrant) assert(reentrant == 0 || reentrant == 1); if (reentrant) { assert(PyThread_get_key_value(tracemalloc_reentrant_key) == NULL); - PyThread_set_key_value(tracemalloc_reentrant_key, - REENTRANT); + PyThread_set_key_value(tracemalloc_reentrant_key, REENTRANT); } else { - /* FIXME: PyThread_set_key_value() cannot be used to set the flag - to zero, because it does nothing if the variable has already - a value set. */ - PyThread_delete_key_value(tracemalloc_reentrant_key); + assert(PyThread_get_key_value(tracemalloc_reentrant_key) == REENTRANT); + PyThread_set_key_value(tracemalloc_reentrant_key, NULL); } } @@ -339,8 +334,7 @@ static Py_uhash_t traceback_hash(traceback_t *traceback) { /* code based on tuplehash() of Objects/tupleobject.c */ - Py_uhash_t x; /* Unsigned for defined overflow behavior. */ - Py_hash_t y; + Py_uhash_t x, y; /* Unsigned for defined overflow behavior. */ int len = traceback->nframe; Py_uhash_t mult = _PyHASH_MULTIPLIER; frame_t *frame; @@ -348,13 +342,13 @@ traceback_hash(traceback_t *traceback) x = 0x345678UL; frame = traceback->frames; while (--len >= 0) { - y = PyObject_Hash(frame->filename); - y ^= frame->lineno; + 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_hash_t)(82520UL + len + len); + mult += (Py_uhash_t)(82520UL + len + len); } x += 97531UL; return x; @@ -439,7 +433,7 @@ traceback_new(void) } static int -tracemalloc_log_alloc(void *ptr, size_t size) +tracemalloc_add_trace(void *ptr, size_t size) { traceback_t *traceback; trace_t trace; @@ -456,7 +450,6 @@ tracemalloc_log_alloc(void *ptr, size_t size) trace.size = size; trace.traceback = traceback; - TABLES_LOCK(); res = _Py_HASHTABLE_SET(tracemalloc_traces, ptr, trace); if (res == 0) { assert(tracemalloc_traced_memory <= PY_SIZE_MAX - size); @@ -464,144 +457,96 @@ tracemalloc_log_alloc(void *ptr, size_t size) if (tracemalloc_traced_memory > tracemalloc_peak_traced_memory) tracemalloc_peak_traced_memory = tracemalloc_traced_memory; } - TABLES_UNLOCK(); return res; } static void -tracemalloc_log_free(void *ptr) +tracemalloc_remove_trace(void *ptr) { trace_t trace; - TABLES_LOCK(); if (_Py_hashtable_pop(tracemalloc_traces, ptr, &trace, sizeof(trace))) { assert(tracemalloc_traced_memory >= trace.size); tracemalloc_traced_memory -= trace.size; } - TABLES_UNLOCK(); } static void* -tracemalloc_malloc(void *ctx, size_t size, int gil_held) +tracemalloc_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) { - PyMemAllocator *alloc = (PyMemAllocator *)ctx; -#if defined(TRACE_RAW_MALLOC) && defined(WITH_THREAD) - PyGILState_STATE gil_state; -#endif + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; void *ptr; - if (get_reentrant()) { - return alloc->malloc(alloc->ctx, size); - } + assert(elsize == 0 || nelem <= PY_SIZE_MAX / elsize); - /* Ignore reentrant call. PyObjet_Malloc() calls PyMem_Malloc() - for allocations larger than 512 bytes. PyGILState_Ensure() may call - PyMem_RawMalloc() indirectly which would call PyGILState_Ensure() if - reentrant are not disabled. */ - set_reentrant(1); -#ifdef WITH_THREAD -#ifdef TRACE_RAW_MALLOC - if (!gil_held) - gil_state = PyGILState_Ensure(); -#else - assert(gil_held); -#endif -#endif - ptr = alloc->malloc(alloc->ctx, size); + if (use_calloc) + ptr = alloc->calloc(alloc->ctx, nelem, elsize); + else + ptr = alloc->malloc(alloc->ctx, nelem * elsize); + if (ptr == NULL) + return NULL; - if (ptr != NULL) { - if (tracemalloc_log_alloc(ptr, size) < 0) { - /* Memory allocation failed */ - alloc->free(alloc->ctx, ptr); - ptr = NULL; - } + TABLES_LOCK(); + if (tracemalloc_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; } - set_reentrant(0); - -#if defined(TRACE_RAW_MALLOC) && defined(WITH_THREAD) - if (!gil_held) - PyGILState_Release(gil_state); -#endif - + TABLES_UNLOCK(); return ptr; } static void* -tracemalloc_realloc(void *ctx, void *ptr, size_t new_size, int gil_held) +tracemalloc_realloc(void *ctx, void *ptr, size_t new_size) { - PyMemAllocator *alloc = (PyMemAllocator *)ctx; -#if defined(TRACE_RAW_MALLOC) && defined(WITH_THREAD) - PyGILState_STATE gil_state; -#endif + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; 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()). */ - ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); - - if (ptr2 != NULL && ptr != NULL) - tracemalloc_log_free(ptr); + ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); + if (ptr2 == NULL) + return NULL; - return ptr2; - } + if (ptr != NULL) { + /* an existing memory block has been resized */ - /* Ignore reentrant call. PyObjet_Realloc() calls PyMem_Realloc() for - allocations larger than 512 bytes. PyGILState_Ensure() may call - PyMem_RawMalloc() indirectly which would call PyGILState_Ensure() if - reentrant are not disabled. */ - set_reentrant(1); -#ifdef WITH_THREAD -#ifdef TRACE_RAW_MALLOC - if (!gil_held) - gil_state = PyGILState_Ensure(); -#else - assert(gil_held); -#endif -#endif - ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); + TABLES_LOCK(); + tracemalloc_remove_trace(ptr); - if (ptr2 != NULL) { - if (ptr != NULL) { - /* resize */ - tracemalloc_log_free(ptr); + if (tracemalloc_add_trace(ptr2, new_size) < 0) { + /* Memory allocation failed. The error cannot be reported to + the caller, because realloc() may already have shrinked the + memory block and so removed bytes. - if (tracemalloc_log_alloc(ptr2, new_size) < 0) { - /* Memory allocation failed. The error cannot be reported to - the caller, because realloc() may already have shrinked the - memory block and so removed bytes. + This case is very unlikely: an hash entry has just been + released, so the hash table should have at least one free entry. - This case is very unlikely since we just released an hash - entry, so we have enough free bytes to allocate the new - entry. */ - } - } - else { - /* new allocation */ - if (tracemalloc_log_alloc(ptr2, new_size) < 0) { - /* Memory allocation failed */ - alloc->free(alloc->ctx, ptr2); - ptr2 = NULL; - } + The GIL and the table lock ensures that only one thread is + allocating memory. */ + assert(0 && "should never happen"); } + TABLES_UNLOCK(); } - set_reentrant(0); - -#if defined(TRACE_RAW_MALLOC) && defined(WITH_THREAD) - if (!gil_held) - PyGILState_Release(gil_state); -#endif + else { + /* new allocation */ + TABLES_LOCK(); + if (tracemalloc_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) { - PyMemAllocator *alloc = (PyMemAllocator *)ctx; + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; if (ptr == NULL) return; @@ -610,35 +555,166 @@ tracemalloc_free(void *ctx, void *ptr) a deadlock in PyThreadState_DeleteCurrent(). */ alloc->free(alloc->ctx, ptr); - tracemalloc_log_free(ptr); + + TABLES_LOCK(); + tracemalloc_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_malloc(ctx, size, 1); + 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) { - return tracemalloc_realloc(ctx, ptr, new_size, 1); + 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(); + tracemalloc_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) +{ +#ifdef WITH_THREAD + PyGILState_STATE gil_state; +#endif + 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); + +#ifdef WITH_THREAD + gil_state = PyGILState_Ensure(); + ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize); + PyGILState_Release(gil_state); +#else + ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize); +#endif + + set_reentrant(0); + return ptr; +} + static void* tracemalloc_raw_malloc(void *ctx, size_t size) { - return tracemalloc_malloc(ctx, size, 0); + return tracemalloc_raw_alloc(0, ctx, 1, size); } static void* -tracemalloc_raw_realloc(void *ctx, void *ptr, size_t new_size) +tracemalloc_raw_calloc(void *ctx, size_t nelem, size_t elsize) { - return tracemalloc_realloc(ctx, ptr, new_size, 0); + return tracemalloc_raw_alloc(1, ctx, nelem, elsize); } + +static void* +tracemalloc_raw_realloc(void *ctx, void *ptr, size_t new_size) +{ +#ifdef WITH_THREAD + PyGILState_STATE gil_state; +#endif + 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(); + tracemalloc_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); + +#ifdef WITH_THREAD + gil_state = PyGILState_Ensure(); + ptr2 = tracemalloc_realloc(ctx, ptr, new_size); + PyGILState_Release(gil_state); +#else + ptr2 = tracemalloc_realloc(ctx, ptr, new_size); #endif + set_reentrant(0); + return ptr2; +} +#endif /* TRACE_RAW_MALLOC */ + static int tracemalloc_clear_filename(_Py_hashtable_entry_t *entry, void *user_data) { @@ -787,7 +863,7 @@ tracemalloc_deinit(void) static int tracemalloc_start(int max_nframe) { - PyMemAllocator alloc; + PyMemAllocatorEx alloc; size_t size; if (tracemalloc_init() < 0) @@ -812,6 +888,7 @@ tracemalloc_start(int max_nframe) #ifdef TRACE_RAW_MALLOC alloc.malloc = tracemalloc_raw_malloc; + alloc.calloc = tracemalloc_raw_calloc; alloc.realloc = tracemalloc_raw_realloc; alloc.free = tracemalloc_free; @@ -821,6 +898,7 @@ tracemalloc_start(int max_nframe) #endif alloc.malloc = tracemalloc_malloc_gil; + alloc.calloc = tracemalloc_calloc_gil; alloc.realloc = tracemalloc_realloc_gil; alloc.free = tracemalloc_free; @@ -1008,7 +1086,7 @@ tracemalloc_get_traces_fill(_Py_hashtable_entry_t *entry, void *user_data) PyObject *tracemalloc_obj; int res; - trace = (trace_t *)_PY_HASHTABLE_ENTRY_DATA(entry); + trace = (trace_t *)_Py_HASHTABLE_ENTRY_DATA(entry); tracemalloc_obj = trace_to_pyobject(trace, get_traces->tracebacks); if (tracemalloc_obj == NULL) @@ -1151,7 +1229,7 @@ py_tracemalloc_start(PyObject *self, PyObject *args) if (nframe < 1 || nframe > MAX_NFRAME) { PyErr_Format(PyExc_ValueError, "the number of frames must be in range [1; %i]", - (int)MAX_NFRAME); + MAX_NFRAME); return NULL; } nframe_int = Py_SAFE_DOWNCAST(nframe, Py_ssize_t, int); @@ -1330,11 +1408,12 @@ _PyTraceMalloc_Init(void) char *endptr = p; long value; + errno = 0; value = strtol(p, &endptr, 10); if (*endptr != '\0' || value < 1 || value > MAX_NFRAME - || (errno == ERANGE && value == ULONG_MAX)) + || errno == ERANGE) { Py_FatalError("PYTHONTRACEMALLOC: invalid number of frames"); return -1; diff --git a/Modules/_weakref.c b/Modules/_weakref.c index 80de5da4d539..7c99d7e7865b 100644 --- a/Modules/_weakref.c +++ b/Modules/_weakref.c @@ -4,12 +4,14 @@ #define GET_WEAKREFS_LISTPTR(o) \ ((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o)) -/*[clinic] +/*[clinic input] module _weakref -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ffec73b85846596d]*/ -/*[clinic] +#include "clinic/_weakref.c.h" + +/*[clinic input] _weakref.getweakrefcount -> Py_ssize_t @@ -17,41 +19,17 @@ _weakref.getweakrefcount -> Py_ssize_t / Return the number of weak references to 'object'. -[clinic]*/ - -PyDoc_STRVAR(_weakref_getweakrefcount__doc__, -"getweakrefcount(object)\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(PyModuleDef *module, PyObject *object); - -static PyObject * -_weakref_getweakrefcount(PyModuleDef *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; -} +[clinic start generated code]*/ static Py_ssize_t _weakref_getweakrefcount_impl(PyModuleDef *module, PyObject *object) -/*[clinic checksum: 436e8fbe0297434375f039d8c2d9fc3a9bbe773c]*/ +/*[clinic end generated code: output=6a6ad0b98285e468 input=cedb69711b6a2507]*/ { PyWeakReference **list; if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) return 0; - + list = GET_WEAKREFS_LISTPTR(object); return _PyWeakref_GetWeakrefCount(*list); } diff --git a/Modules/_winapi.c b/Modules/_winapi.c index 724a4789f49f..3e7f18741fe8 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -40,6 +40,7 @@ #define WINDOWS_LEAN_AND_MEAN #include "windows.h" #include +#include "winreparse.h" #if defined(MS_WIN32) && !defined(MS_WIN64) #define HANDLE_TO_PYNUM(handle) \ @@ -57,8 +58,6 @@ #define F_HANDLE F_POINTER #define F_DWORD "k" -#define F_BOOL "i" -#define F_UINT "I" #define T_HANDLE T_POINTER @@ -146,17 +145,68 @@ overlapped_dealloc(OverlappedObject *self) 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('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('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') + 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 == DWORD_MAX", data) + data.return_conversion.append( + 'return_value = Py_BuildValue("k", _return_value);\n') +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=374076979596ebba]*/ + +#include "clinic/_winapi.c.h" + +/*[clinic input] +_winapi.Overlapped.GetOverlappedResult + + wait: bool + / +[clinic start generated code]*/ + static PyObject * -overlapped_GetOverlappedResult(OverlappedObject *self, PyObject *waitobj) +_winapi_Overlapped_GetOverlappedResult_impl(OverlappedObject *self, int wait) +/*[clinic end generated code: output=bdd0c1ed6518cd03 input=194505ee8e0e3565]*/ { - int wait; BOOL res; DWORD transferred = 0; DWORD err; - wait = PyObject_IsTrue(waitobj); - if (wait < 0) - return NULL; Py_BEGIN_ALLOW_THREADS res = GetOverlappedResult(self->handle, &self->overlapped, &transferred, wait != 0); @@ -185,8 +235,13 @@ overlapped_GetOverlappedResult(OverlappedObject *self, PyObject *waitobj) return Py_BuildValue("II", (unsigned) transferred, (unsigned) err); } +/*[clinic input] +_winapi.Overlapped.getbuffer +[clinic start generated code]*/ + static PyObject * -overlapped_getbuffer(OverlappedObject *self) +_winapi_Overlapped_getbuffer_impl(OverlappedObject *self) +/*[clinic end generated code: output=95a3eceefae0f748 input=347fcfd56b4ceabd]*/ { PyObject *res; if (!self->completed) { @@ -200,8 +255,13 @@ overlapped_getbuffer(OverlappedObject *self) return res; } +/*[clinic input] +_winapi.Overlapped.cancel +[clinic start generated code]*/ + static PyObject * -overlapped_cancel(OverlappedObject *self) +_winapi_Overlapped_cancel_impl(OverlappedObject *self) +/*[clinic end generated code: output=fcb9ab5df4ebdae5 input=cbf3da142290039f]*/ { BOOL res = TRUE; @@ -222,10 +282,9 @@ overlapped_cancel(OverlappedObject *self) } static PyMethodDef overlapped_methods[] = { - {"GetOverlappedResult", (PyCFunction) overlapped_GetOverlappedResult, - METH_O, NULL}, - {"getbuffer", (PyCFunction) overlapped_getbuffer, METH_NOARGS, NULL}, - {"cancel", (PyCFunction) overlapped_cancel, METH_NOARGS, NULL}, + _WINAPI_OVERLAPPED_GETOVERLAPPEDRESULT_METHODDEF + _WINAPI_OVERLAPPED_GETBUFFER_METHODDEF + _WINAPI_OVERLAPPED_CANCEL_METHODDEF {NULL} }; @@ -299,22 +358,23 @@ new_overlapped(HANDLE handle) /* -------------------------------------------------------------------- */ /* windows API functions */ -PyDoc_STRVAR(CloseHandle_doc, -"CloseHandle(handle) -> None\n\ -\n\ -Close handle."); +/*[clinic input] +_winapi.CloseHandle + + handle: HANDLE + / + +Close handle. +[clinic start generated code]*/ static PyObject * -winapi_CloseHandle(PyObject *self, PyObject *args) +_winapi_CloseHandle_impl(PyModuleDef *module, HANDLE handle) +/*[clinic end generated code: output=0548595c71cb4bf7 input=7f0e4ac36e0352b8]*/ { - HANDLE hObject; BOOL success; - if (!PyArg_ParseTuple(args, F_HANDLE ":CloseHandle", &hObject)) - return NULL; - Py_BEGIN_ALLOW_THREADS - success = CloseHandle(hObject); + success = CloseHandle(handle); Py_END_ALLOW_THREADS if (!success) @@ -323,28 +383,29 @@ winapi_CloseHandle(PyObject *self, PyObject *args) Py_RETURN_NONE; } +/*[clinic input] +_winapi.ConnectNamedPipe + + handle: HANDLE + overlapped as use_overlapped: int(c_default='0') = False +[clinic start generated code]*/ + static PyObject * -winapi_ConnectNamedPipe(PyObject *self, PyObject *args, PyObject *kwds) +_winapi_ConnectNamedPipe_impl(PyModuleDef *module, HANDLE handle, + int use_overlapped) +/*[clinic end generated code: output=fed3b165d1bca95a input=edc83da007ebf3be]*/ { - HANDLE hNamedPipe; - int use_overlapped = 0; BOOL success; OverlappedObject *overlapped = NULL; - static char *kwlist[] = {"handle", "overlapped", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, - F_HANDLE "|" F_BOOL, kwlist, - &hNamedPipe, &use_overlapped)) - return NULL; if (use_overlapped) { - overlapped = new_overlapped(hNamedPipe); + overlapped = new_overlapped(handle); if (!overlapped) return NULL; } Py_BEGIN_ALLOW_THREADS - success = ConnectNamedPipe(hNamedPipe, + success = ConnectNamedPipe(handle, overlapped ? &overlapped->overlapped : NULL); Py_END_ALLOW_THREADS @@ -368,94 +429,238 @@ winapi_ConnectNamedPipe(PyObject *self, PyObject *args, PyObject *kwds) Py_RETURN_NONE; } -static PyObject * -winapi_CreateFile(PyObject *self, PyObject *args) +/*[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(PyModuleDef *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=c6e1d78f8affd10c input=6423c3e40372dbd5]*/ { - LPCTSTR lpFileName; - DWORD dwDesiredAccess; - DWORD dwShareMode; - LPSECURITY_ATTRIBUTES lpSecurityAttributes; - DWORD dwCreationDisposition; - DWORD dwFlagsAndAttributes; - HANDLE hTemplateFile; HANDLE handle; - if (!PyArg_ParseTuple(args, "s" F_DWORD F_DWORD F_POINTER - F_DWORD F_DWORD F_HANDLE, - &lpFileName, &dwDesiredAccess, &dwShareMode, - &lpSecurityAttributes, &dwCreationDisposition, - &dwFlagsAndAttributes, &hTemplateFile)) - return NULL; - Py_BEGIN_ALLOW_THREADS - handle = CreateFile(lpFileName, dwDesiredAccess, - dwShareMode, lpSecurityAttributes, - dwCreationDisposition, - dwFlagsAndAttributes, hTemplateFile); + 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) - return PyErr_SetFromWindowsErr(0); + PyErr_SetFromWindowsErr(0); - return Py_BuildValue(F_HANDLE, handle); + return handle; } +/*[clinic input] +_winapi.CreateJunction + + src_path: LPWSTR + dst_path: LPWSTR + / +[clinic start generated code]*/ + static PyObject * -winapi_CreateNamedPipe(PyObject *self, PyObject *args) +_winapi_CreateJunction_impl(PyModuleDef *module, LPWSTR src_path, + LPWSTR dst_path) +/*[clinic end generated code: output=eccae9364e46f6da input=8cd1f9964b6e3d36]*/ { - LPCTSTR lpName; - DWORD dwOpenMode; - DWORD dwPipeMode; - DWORD nMaxInstances; - DWORD nOutBufferSize; - DWORD nInBufferSize; - DWORD nDefaultTimeOut; - LPSECURITY_ATTRIBUTES lpSecurityAttributes; - HANDLE handle; + /* Privilege adjustment */ + HANDLE token = NULL; + TOKEN_PRIVILEGES tp; + + /* Reparse data buffer */ + const USHORT prefix_len = 4; + USHORT print_len = 0; + USHORT rdb_size = 0; + 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); + + /* 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 = 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 = (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 - 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); - if (!PyArg_ParseTuple(args, "s" F_DWORD F_DWORD F_DWORD - F_DWORD F_DWORD F_DWORD F_POINTER, - &lpName, &dwOpenMode, &dwPipeMode, - &nMaxInstances, &nOutBufferSize, - &nInBufferSize, &nDefaultTimeOut, - &lpSecurityAttributes)) - return NULL; + 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(PyModuleDef *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=44ca2a06a219b523 input=5a73530b84d8bc37]*/ +{ + HANDLE handle; Py_BEGIN_ALLOW_THREADS - handle = CreateNamedPipe(lpName, dwOpenMode, dwPipeMode, - nMaxInstances, nOutBufferSize, - nInBufferSize, nDefaultTimeOut, - lpSecurityAttributes); + 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) - return PyErr_SetFromWindowsErr(0); + PyErr_SetFromWindowsErr(0); - return Py_BuildValue(F_HANDLE, handle); + return handle; } -PyDoc_STRVAR(CreatePipe_doc, -"CreatePipe(pipe_attrs, size) -> (read_handle, write_handle)\n\ -\n\ -Create an anonymous pipe, and return handles to the read and\n\ -write ends of the pipe.\n\ -\n\ -pipe_attrs is ignored internally and can be None."); +/*[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(PyObject* self, PyObject* args) +_winapi_CreatePipe_impl(PyModuleDef *module, PyObject *pipe_attrs, + DWORD size) +/*[clinic end generated code: output=fef99f3b4222bc78 input=c4f2cfa56ef68d90]*/ { HANDLE read_pipe; HANDLE write_pipe; BOOL result; - PyObject* pipe_attributes; /* ignored */ - DWORD size; - - if (! PyArg_ParseTuple(args, "O" F_DWORD ":CreatePipe", - &pipe_attributes, &size)) - return NULL; - Py_BEGIN_ALLOW_THREADS result = CreatePipe(&read_pipe, &write_pipe, NULL, size); Py_END_ALLOW_THREADS @@ -535,13 +740,23 @@ getenvironment(PyObject* environment) "environment can only contain strings"); goto error; } + if (totalsize > PY_SSIZE_T_MAX - PyUnicode_GET_LENGTH(key) - 1) { + PyErr_SetString(PyExc_OverflowError, "environment too long"); + goto error; + } totalsize += PyUnicode_GET_LENGTH(key) + 1; /* +1 for '=' */ + if (totalsize > PY_SSIZE_T_MAX - PyUnicode_GET_LENGTH(value) - 1) { + PyErr_SetString(PyExc_OverflowError, "environment too long"); + goto error; + } totalsize += PyUnicode_GET_LENGTH(value) + 1; /* +1 for '\0' */ } - buffer = PyMem_Malloc(totalsize * sizeof(Py_UCS4)); - if (! buffer) + buffer = PyMem_NEW(Py_UCS4, totalsize); + if (! buffer) { + PyErr_NoMemory(); goto error; + } p = buffer; end = buffer + totalsize; @@ -576,20 +791,36 @@ getenvironment(PyObject* environment) return NULL; } -PyDoc_STRVAR(CreateProcess_doc, -"CreateProcess(app_name, cmd_line, proc_attrs, thread_attrs,\n\ - inherit, flags, env_mapping, curdir,\n\ - startup_info) -> (proc_handle, thread_handle,\n\ - pid, tid)\n\ -\n\ -Create a new process and its primary thread. The return\n\ -value is a tuple of the process handle, thread handle,\n\ -process ID, and thread ID.\n\ -\n\ -proc_attrs and thread_attrs are ignored internally and can be None."); +/*[clinic input] +_winapi.CreateProcess + + application_name: Py_UNICODE(accept={str, NoneType}) + command_line: Py_UNICODE(accept={str, NoneType}) + 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(PyObject* self, PyObject* args) +_winapi_CreateProcess_impl(PyModuleDef *module, Py_UNICODE *application_name, + Py_UNICODE *command_line, PyObject *proc_attrs, + PyObject *thread_attrs, BOOL inherit_handles, + DWORD creation_flags, PyObject *env_mapping, + Py_UNICODE *current_directory, + PyObject *startup_info) +/*[clinic end generated code: output=874bb350ff9ed4ef input=4a43b05038d639bb]*/ { BOOL result; PROCESS_INFORMATION pi; @@ -597,28 +828,6 @@ winapi_CreateProcess(PyObject* self, PyObject* args) PyObject* environment; wchar_t *wenvironment; - wchar_t* application_name; - wchar_t* command_line; - PyObject* process_attributes; /* ignored */ - PyObject* thread_attributes; /* ignored */ - BOOL inherit_handles; - DWORD creation_flags; - PyObject* env_mapping; - wchar_t* current_directory; - PyObject* startup_info; - - if (! PyArg_ParseTuple(args, "ZZOO" F_BOOL F_DWORD "OZO:CreateProcess", - &application_name, - &command_line, - &process_attributes, - &thread_attributes, - &inherit_handles, - &creation_flags, - &env_mapping, - ¤t_directory, - &startup_info)) - return NULL; - ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); @@ -672,41 +881,36 @@ winapi_CreateProcess(PyObject* self, PyObject* args) pi.dwThreadId); } -PyDoc_STRVAR(DuplicateHandle_doc, -"DuplicateHandle(source_proc_handle, source_handle,\n\ - target_proc_handle, target_handle, access,\n\ - inherit[, options]) -> handle\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."); +/*[clinic input] +_winapi.DuplicateHandle -> HANDLE -static PyObject * -winapi_DuplicateHandle(PyObject* self, PyObject* args) + 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(PyModuleDef *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=0799515b68b5237b input=b933e3f2356a8c12]*/ { HANDLE target_handle; BOOL result; - HANDLE source_process_handle; - HANDLE source_handle; - HANDLE target_process_handle; - DWORD desired_access; - BOOL inherit_handle; - DWORD options = 0; - - if (! PyArg_ParseTuple(args, - F_HANDLE F_HANDLE F_HANDLE F_DWORD F_BOOL F_DWORD - ":DuplicateHandle", - &source_process_handle, - &source_handle, - &target_process_handle, - &desired_access, - &inherit_handle, - &options)) - return NULL; - Py_BEGIN_ALLOW_THREADS result = DuplicateHandle( source_process_handle, @@ -719,98 +923,111 @@ winapi_DuplicateHandle(PyObject* self, PyObject* args) ); Py_END_ALLOW_THREADS - if (! result) - return PyErr_SetFromWindowsErr(GetLastError()); + if (! result) { + PyErr_SetFromWindowsErr(GetLastError()); + return INVALID_HANDLE_VALUE; + } - return HANDLE_TO_PYNUM(target_handle); + return target_handle; } -static PyObject * -winapi_ExitProcess(PyObject *self, PyObject *args) -{ - UINT uExitCode; +/*[clinic input] +_winapi.ExitProcess - if (!PyArg_ParseTuple(args, F_UINT, &uExitCode)) - return NULL; + ExitCode: UINT + / + +[clinic start generated code]*/ +static PyObject * +_winapi_ExitProcess_impl(PyModuleDef *module, UINT ExitCode) +/*[clinic end generated code: output=25f3b499c24cedc8 input=4f05466a9406c558]*/ +{ #if defined(Py_DEBUG) SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOALIGNMENTFAULTEXCEPT| SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX); _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); #endif - ExitProcess(uExitCode); + ExitProcess(ExitCode); return NULL; } -PyDoc_STRVAR(GetCurrentProcess_doc, -"GetCurrentProcess() -> handle\n\ -\n\ -Return a handle object for the current process."); +/*[clinic input] +_winapi.GetCurrentProcess -> HANDLE -static PyObject * -winapi_GetCurrentProcess(PyObject* self, PyObject* args) -{ - if (! PyArg_ParseTuple(args, ":GetCurrentProcess")) - return NULL; +Return a handle object for the current process. +[clinic start generated code]*/ - return HANDLE_TO_PYNUM(GetCurrentProcess()); +static HANDLE +_winapi_GetCurrentProcess_impl(PyModuleDef *module) +/*[clinic end generated code: output=be29ac3ad5f8291e input=b213403fd4b96b41]*/ +{ + return GetCurrentProcess(); } -PyDoc_STRVAR(GetExitCodeProcess_doc, -"GetExitCodeProcess(handle) -> Exit code\n\ -\n\ -Return the termination status of the specified process."); +/*[clinic input] +_winapi.GetExitCodeProcess -> DWORD -static PyObject * -winapi_GetExitCodeProcess(PyObject* self, PyObject* args) + process: HANDLE + / + +Return the termination status of the specified process. +[clinic start generated code]*/ + +static DWORD +_winapi_GetExitCodeProcess_impl(PyModuleDef *module, HANDLE process) +/*[clinic end generated code: output=0b10f0848a410f65 input=61b6bfc7dc2ee374]*/ { DWORD exit_code; BOOL result; - HANDLE process; - if (! PyArg_ParseTuple(args, F_HANDLE ":GetExitCodeProcess", &process)) - return NULL; - result = GetExitCodeProcess(process, &exit_code); - if (! result) - return PyErr_SetFromWindowsErr(GetLastError()); + if (! result) { + PyErr_SetFromWindowsErr(GetLastError()); + exit_code = DWORD_MAX; + } - return PyLong_FromUnsignedLong(exit_code); + return exit_code; } -static PyObject * -winapi_GetLastError(PyObject *self, PyObject *args) +/*[clinic input] +_winapi.GetLastError -> DWORD +[clinic start generated code]*/ + +static DWORD +_winapi_GetLastError_impl(PyModuleDef *module) +/*[clinic end generated code: output=0ea00d8e67bdd056 input=62d47fb9bce038ba]*/ { - return Py_BuildValue(F_DWORD, GetLastError()); + return GetLastError(); } -PyDoc_STRVAR(GetModuleFileName_doc, -"GetModuleFileName(module) -> path\n\ -\n\ -Return the fully-qualified path for the file that contains\n\ -the specified module. The module must have been loaded by the\n\ -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."); +/*[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(PyObject* self, PyObject* args) +_winapi_GetModuleFileName_impl(PyModuleDef *module, HMODULE module_handle) +/*[clinic end generated code: output=90063dc63bdbfa18 input=6d66ff7deca5d11f]*/ { BOOL result; - HMODULE module; WCHAR filename[MAX_PATH]; - if (! PyArg_ParseTuple(args, F_HANDLE ":GetModuleFileName", - &module)) - return NULL; - - result = GetModuleFileNameW(module, filename, MAX_PATH); + result = GetModuleFileNameW(module_handle, filename, MAX_PATH); filename[MAX_PATH-1] = '\0'; if (! result) @@ -819,83 +1036,96 @@ winapi_GetModuleFileName(PyObject* self, PyObject* args) return PyUnicode_FromWideChar(filename, wcslen(filename)); } -PyDoc_STRVAR(GetStdHandle_doc, -"GetStdHandle(handle) -> integer\n\ -\n\ -Return a handle to the specified standard device\n\ -(STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE).\n\ -The integer associated with the handle object is returned."); +/*[clinic input] +_winapi.GetStdHandle -> HANDLE -static PyObject * -winapi_GetStdHandle(PyObject* self, PyObject* args) + 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(PyModuleDef *module, DWORD std_handle) +/*[clinic end generated code: output=5f5ca28b28c6fad2 input=07016b06a2fc8826]*/ { HANDLE handle; - DWORD std_handle; - - if (! PyArg_ParseTuple(args, F_DWORD ":GetStdHandle", &std_handle)) - return NULL; Py_BEGIN_ALLOW_THREADS handle = GetStdHandle(std_handle); Py_END_ALLOW_THREADS if (handle == INVALID_HANDLE_VALUE) - return PyErr_SetFromWindowsErr(GetLastError()); - - if (! handle) { - Py_INCREF(Py_None); - return Py_None; - } + PyErr_SetFromWindowsErr(GetLastError()); - /* note: returns integer, not handle object */ - return HANDLE_TO_PYNUM(handle); + return handle; } -PyDoc_STRVAR(GetVersion_doc, -"GetVersion() -> version\n\ -\n\ -Return the version number of the current operating system."); +/*[clinic input] +_winapi.GetVersion -> long -static PyObject * -winapi_GetVersion(PyObject* self, PyObject* args) -{ - if (! PyArg_ParseTuple(args, ":GetVersion")) - return NULL; +Return the version number of the current operating system. +[clinic start generated code]*/ - return PyLong_FromUnsignedLong(GetVersion()); +static long +_winapi_GetVersion_impl(PyModuleDef *module) +/*[clinic end generated code: output=95a2f8ad3b948ca8 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(); } -static PyObject * -winapi_OpenProcess(PyObject *self, PyObject *args) +#pragma warning(pop) + +/*[clinic input] +_winapi.OpenProcess -> HANDLE + + desired_access: DWORD + inherit_handle: BOOL + process_id: DWORD + / +[clinic start generated code]*/ + +static HANDLE +_winapi_OpenProcess_impl(PyModuleDef *module, DWORD desired_access, + BOOL inherit_handle, DWORD process_id) +/*[clinic end generated code: output=6bc52eda82a3d226 input=ec98c4cf4ea2ec36]*/ { - DWORD dwDesiredAccess; - BOOL bInheritHandle; - DWORD dwProcessId; HANDLE handle; - if (!PyArg_ParseTuple(args, F_DWORD F_BOOL F_DWORD, - &dwDesiredAccess, &bInheritHandle, &dwProcessId)) - return NULL; - - handle = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId); - if (handle == NULL) - return PyErr_SetFromWindowsErr(0); + handle = OpenProcess(desired_access, inherit_handle, process_id); + if (handle == NULL) { + PyErr_SetFromWindowsErr(0); + handle = INVALID_HANDLE_VALUE; + } - return Py_BuildValue(F_HANDLE, handle); + return handle; } +/*[clinic input] +_winapi.PeekNamedPipe + + handle: HANDLE + size: int = 0 + / +[clinic start generated code]*/ + static PyObject * -winapi_PeekNamedPipe(PyObject *self, PyObject *args) +_winapi_PeekNamedPipe_impl(PyModuleDef *module, HANDLE handle, int size) +/*[clinic end generated code: output=e6c908e2fb63c798 input=c7aa53bfbce69d70]*/ { - HANDLE handle; - int size = 0; PyObject *buf = NULL; DWORD nread, navail, nleft; BOOL ret; - if (!PyArg_ParseTuple(args, F_HANDLE "|i:PeekNamedPipe" , &handle, &size)) - return NULL; - if (size < 0) { PyErr_SetString(PyExc_ValueError, "negative size"); return NULL; @@ -928,23 +1158,24 @@ winapi_PeekNamedPipe(PyObject *self, PyObject *args) } } +/*[clinic input] +_winapi.ReadFile + + handle: HANDLE + size: int + overlapped as use_overlapped: int(c_default='0') = False +[clinic start generated code]*/ + static PyObject * -winapi_ReadFile(PyObject *self, PyObject *args, PyObject *kwds) +_winapi_ReadFile_impl(PyModuleDef *module, HANDLE handle, int size, + int use_overlapped) +/*[clinic end generated code: output=d7695db4db97b135 input=8dd810194e86ac7d]*/ { - HANDLE handle; - int size; DWORD nread; PyObject *buf; BOOL ret; - int use_overlapped = 0; DWORD err; OverlappedObject *overlapped = NULL; - static char *kwlist[] = {"handle", "size", "overlapped", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, - F_HANDLE "i|i:ReadFile", kwlist, - &handle, &size, &use_overlapped)) - return NULL; buf = PyBytes_FromStringAndSize(NULL, size); if (!buf) @@ -987,18 +1218,27 @@ winapi_ReadFile(PyObject *self, PyObject *args, PyObject *kwds) 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(PyObject *self, PyObject *args) +_winapi_SetNamedPipeHandleState_impl(PyModuleDef *module, HANDLE named_pipe, + PyObject *mode, + PyObject *max_collection_count, + PyObject *collect_data_timeout) +/*[clinic end generated code: output=25aa3c28dee223ce input=9142d72163d0faa6]*/ { - HANDLE hNamedPipe; - PyObject *oArgs[3]; + PyObject *oArgs[3] = {mode, max_collection_count, collect_data_timeout}; DWORD dwArgs[3], *pArgs[3] = {NULL, NULL, NULL}; int i; - if (!PyArg_ParseTuple(args, F_HANDLE "OOO", - &hNamedPipe, &oArgs[0], &oArgs[1], &oArgs[2])) - return NULL; - PyErr_Clear(); for (i = 0 ; i < 3 ; i++) { @@ -1010,49 +1250,54 @@ winapi_SetNamedPipeHandleState(PyObject *self, PyObject *args) } } - if (!SetNamedPipeHandleState(hNamedPipe, pArgs[0], pArgs[1], pArgs[2])) + if (!SetNamedPipeHandleState(named_pipe, pArgs[0], pArgs[1], pArgs[2])) return PyErr_SetFromWindowsErr(0); Py_RETURN_NONE; } -PyDoc_STRVAR(TerminateProcess_doc, -"TerminateProcess(handle, exit_code) -> None\n\ -\n\ -Terminate the specified process and all of its threads."); + +/*[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(PyObject* self, PyObject* args) +_winapi_TerminateProcess_impl(PyModuleDef *module, HANDLE handle, + UINT exit_code) +/*[clinic end generated code: output=937c1bb6219aca8b input=d6bc0aa1ee3bb4df]*/ { BOOL result; - HANDLE process; - UINT exit_code; - if (! PyArg_ParseTuple(args, F_HANDLE F_UINT ":TerminateProcess", - &process, &exit_code)) - return NULL; - - result = TerminateProcess(process, exit_code); + result = TerminateProcess(handle, exit_code); if (! result) return PyErr_SetFromWindowsErr(GetLastError()); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } +/*[clinic input] +_winapi.WaitNamedPipe + + name: LPCTSTR + timeout: DWORD + / +[clinic start generated code]*/ + static PyObject * -winapi_WaitNamedPipe(PyObject *self, PyObject *args) +_winapi_WaitNamedPipe_impl(PyModuleDef *module, LPCTSTR name, DWORD timeout) +/*[clinic end generated code: output=5bca5e02f448c9d7 input=36fc781291b1862c]*/ { - LPCTSTR lpNamedPipeName; - DWORD nTimeOut; BOOL success; - if (!PyArg_ParseTuple(args, "s" F_DWORD, &lpNamedPipeName, &nTimeOut)) - return NULL; - Py_BEGIN_ALLOW_THREADS - success = WaitNamedPipe(lpNamedPipeName, nTimeOut); + success = WaitNamedPipe(name, timeout); Py_END_ALLOW_THREADS if (!success) @@ -1061,21 +1306,25 @@ winapi_WaitNamedPipe(PyObject *self, PyObject *args) 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(PyObject* self, PyObject* args) +_winapi_WaitForMultipleObjects_impl(PyModuleDef *module, + PyObject *handle_seq, BOOL wait_flag, + DWORD milliseconds) +/*[clinic end generated code: output=acb440728d06d130 input=36f76ca057cd28a0]*/ { DWORD result; - PyObject *handle_seq; HANDLE handles[MAXIMUM_WAIT_OBJECTS]; HANDLE sigint_event = NULL; Py_ssize_t nhandles, i; - BOOL wait_flag; - DWORD milliseconds = INFINITE; - - if (!PyArg_ParseTuple(args, "O" F_BOOL "|" F_DWORD - ":WaitForMultipleObjects", - &handle_seq, &wait_flag, &milliseconds)) - return NULL; if (!PySequence_Check(handle_seq)) { PyErr_Format(PyExc_TypeError, @@ -1129,53 +1378,57 @@ winapi_WaitForMultipleObjects(PyObject* self, PyObject* args) return PyLong_FromLong((int) result); } -PyDoc_STRVAR(WaitForSingleObject_doc, -"WaitForSingleObject(handle, timeout) -> result\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."); +/*[clinic input] +_winapi.WaitForSingleObject -> long -static PyObject * -winapi_WaitForSingleObject(PyObject* self, PyObject* args) + 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(PyModuleDef *module, HANDLE handle, + DWORD milliseconds) +/*[clinic end generated code: output=34ae40c269749c48 input=443d1ab076edc7b1]*/ { DWORD result; - HANDLE handle; - DWORD milliseconds; - if (! PyArg_ParseTuple(args, F_HANDLE F_DWORD ":WaitForSingleObject", - &handle, - &milliseconds)) - return NULL; - Py_BEGIN_ALLOW_THREADS result = WaitForSingleObject(handle, milliseconds); Py_END_ALLOW_THREADS - if (result == WAIT_FAILED) - return PyErr_SetFromWindowsErr(GetLastError()); + if (result == WAIT_FAILED) { + PyErr_SetFromWindowsErr(GetLastError()); + return -1; + } - return PyLong_FromUnsignedLong(result); + return result; } +/*[clinic input] +_winapi.WriteFile + + handle: HANDLE + buffer: object + overlapped as use_overlapped: int(c_default='0') = False +[clinic start generated code]*/ + static PyObject * -winapi_WriteFile(PyObject *self, PyObject *args, PyObject *kwds) +_winapi_WriteFile_impl(PyModuleDef *module, HANDLE handle, PyObject *buffer, + int use_overlapped) +/*[clinic end generated code: output=65e70ea41f4d2a1d input=51846a5af52053fd]*/ { - HANDLE handle; Py_buffer _buf, *buf; - PyObject *bufobj; DWORD len, written; BOOL ret; - int use_overlapped = 0; DWORD err; OverlappedObject *overlapped = NULL; - static char *kwlist[] = {"handle", "buffer", "overlapped", NULL}; - - /* First get handle and use_overlapped to know which Py_buffer to use */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, - F_HANDLE "O|i:WriteFile", kwlist, - &handle, &bufobj, &use_overlapped)) - return NULL; if (use_overlapped) { overlapped = new_overlapped(handle); @@ -1186,7 +1439,7 @@ winapi_WriteFile(PyObject *self, PyObject *args, PyObject *kwds) else buf = &_buf; - if (!PyArg_Parse(bufobj, "y*", buf)) { + if (!PyArg_Parse(buffer, "y*", buf)) { Py_XDECREF(overlapped); return NULL; } @@ -1219,52 +1472,30 @@ winapi_WriteFile(PyObject *self, PyObject *args, PyObject *kwds) static PyMethodDef winapi_functions[] = { - {"CloseHandle", winapi_CloseHandle, METH_VARARGS, - CloseHandle_doc}, - {"ConnectNamedPipe", (PyCFunction)winapi_ConnectNamedPipe, - METH_VARARGS | METH_KEYWORDS, ""}, - {"CreateFile", winapi_CreateFile, METH_VARARGS, - ""}, - {"CreateNamedPipe", winapi_CreateNamedPipe, METH_VARARGS, - ""}, - {"CreatePipe", winapi_CreatePipe, METH_VARARGS, - CreatePipe_doc}, - {"CreateProcess", winapi_CreateProcess, METH_VARARGS, - CreateProcess_doc}, - {"DuplicateHandle", winapi_DuplicateHandle, METH_VARARGS, - DuplicateHandle_doc}, - {"ExitProcess", winapi_ExitProcess, METH_VARARGS, - ""}, - {"GetCurrentProcess", winapi_GetCurrentProcess, METH_VARARGS, - GetCurrentProcess_doc}, - {"GetExitCodeProcess", winapi_GetExitCodeProcess, METH_VARARGS, - GetExitCodeProcess_doc}, - {"GetLastError", winapi_GetLastError, METH_NOARGS, - GetCurrentProcess_doc}, - {"GetModuleFileName", winapi_GetModuleFileName, METH_VARARGS, - GetModuleFileName_doc}, - {"GetStdHandle", winapi_GetStdHandle, METH_VARARGS, - GetStdHandle_doc}, - {"GetVersion", winapi_GetVersion, METH_VARARGS, - GetVersion_doc}, - {"OpenProcess", winapi_OpenProcess, METH_VARARGS, - ""}, - {"PeekNamedPipe", winapi_PeekNamedPipe, METH_VARARGS, - ""}, - {"ReadFile", (PyCFunction)winapi_ReadFile, METH_VARARGS | METH_KEYWORDS, - ""}, - {"SetNamedPipeHandleState", winapi_SetNamedPipeHandleState, METH_VARARGS, - ""}, - {"TerminateProcess", winapi_TerminateProcess, METH_VARARGS, - TerminateProcess_doc}, - {"WaitNamedPipe", winapi_WaitNamedPipe, METH_VARARGS, - ""}, - {"WaitForMultipleObjects", winapi_WaitForMultipleObjects, METH_VARARGS, - ""}, - {"WaitForSingleObject", winapi_WaitForSingleObject, METH_VARARGS, - WaitForSingleObject_doc}, - {"WriteFile", (PyCFunction)winapi_WriteFile, METH_VARARGS | METH_KEYWORDS, - ""}, + _WINAPI_CLOSEHANDLE_METHODDEF + _WINAPI_CONNECTNAMEDPIPE_METHODDEF + _WINAPI_CREATEFILE_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_OPENPROCESS_METHODDEF + _WINAPI_PEEKNAMEDPIPE_METHODDEF + _WINAPI_READFILE_METHODDEF + _WINAPI_SETNAMEDPIPEHANDLESTATE_METHODDEF + _WINAPI_TERMINATEPROCESS_METHODDEF + _WINAPI_WAITNAMEDPIPE_METHODDEF + _WINAPI_WAITFORMULTIPLEOBJECTS_METHODDEF + _WINAPI_WAITFORSINGLEOBJECT_METHODDEF + _WINAPI_WRITEFILE_METHODDEF {NULL, NULL} }; @@ -1343,6 +1574,7 @@ PyInit__winapi(void) 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("i", NULL); diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 3b013acf6467..a3ccf9344ff3 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -15,6 +15,11 @@ #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" @@ -42,6 +47,63 @@ typedef struct 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) @@ -471,6 +533,10 @@ static struct arraydescr descriptors[] = { /**************************************************************************** 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, struct arraydescr *descr) @@ -684,16 +750,35 @@ array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh) return (PyObject *)np; } + +/*[clinic input] +array.array.__copy__ + +Return a copy of the array. +[clinic start generated code]*/ + static PyObject * -array_copy(arrayobject *a, PyObject *unused) +array_array___copy___impl(arrayobject *self) +/*[clinic end generated code: output=dec7c3f925d9619e input=ad1ee5b086965f09]*/ { - return array_slice(a, 0, Py_SIZE(a)); + return array_slice(self, 0, Py_SIZE(self)); } -PyDoc_STRVAR(copy_doc, -"copy(array)\n\ -\n\ - Return a copy of the array."); +/*[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) @@ -961,8 +1046,18 @@ ins(arrayobject *self, Py_ssize_t where, PyObject *v) return Py_None; } +/*[clinic input] +array.array.count + + v: object + / + +Return number of occurrences of v in the array. +[clinic start generated code]*/ + static PyObject * -array_count(arrayobject *self, PyObject *v) +array_array_count(arrayobject *self, PyObject *v) +/*[clinic end generated code: output=3dd3624bf7135a3a input=d9bce9d65e39d1f5]*/ { Py_ssize_t count = 0; Py_ssize_t i; @@ -984,13 +1079,19 @@ array_count(arrayobject *self, PyObject *v) return PyLong_FromSsize_t(count); } -PyDoc_STRVAR(count_doc, -"count(x)\n\ -\n\ -Return number of occurrences of x in the array."); + +/*[clinic input] +array.array.index + + v: object + / + +Return index of first occurrence of v in the array. +[clinic start generated code]*/ static PyObject * -array_index(arrayobject *self, PyObject *v) +array_array_index(arrayobject *self, PyObject *v) +/*[clinic end generated code: output=d48498d325602167 input=cf619898c6649d08]*/ { Py_ssize_t i; @@ -1013,11 +1114,6 @@ array_index(arrayobject *self, PyObject *v) return NULL; } -PyDoc_STRVAR(index_doc, -"index(x)\n\ -\n\ -Return index of first occurrence of x in the array."); - static int array_contains(arrayobject *self, PyObject *v) { @@ -1034,8 +1130,18 @@ array_contains(arrayobject *self, PyObject *v) 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_remove(arrayobject *self, PyObject *v) +array_array_remove(arrayobject *self, PyObject *v) +/*[clinic end generated code: output=bef06be9fdf9dceb input=0b1e5aed25590027]*/ { int i; @@ -1062,18 +1168,23 @@ array_remove(arrayobject *self, PyObject *v) return NULL; } -PyDoc_STRVAR(remove_doc, -"remove(x)\n\ -\n\ -Remove the first occurrence of x in the array."); +/*[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_pop(arrayobject *self, PyObject *args) +array_array_pop_impl(arrayobject *self, Py_ssize_t i) +/*[clinic end generated code: output=bc1f0c54fe5308e4 input=8e5feb4c1a11cd44]*/ { - Py_ssize_t i = -1; PyObject *v; - if (!PyArg_ParseTuple(args, "|n:pop", &i)) - return NULL; + if (Py_SIZE(self) == 0) { /* Special-case most common failure cause */ PyErr_SetString(PyExc_IndexError, "pop from empty array"); @@ -1095,13 +1206,18 @@ array_pop(arrayobject *self, PyObject *args) return v; } -PyDoc_STRVAR(pop_doc, -"pop([i])\n\ -\n\ -Return the i-th element and delete it from the array. i defaults to -1."); +/*[clinic input] +array.array.extend + + bb: object + / + +Append items to the end of the array. +[clinic start generated code]*/ static PyObject * -array_extend(arrayobject *self, PyObject *bb) +array_array_extend(arrayobject *self, PyObject *bb) +/*[clinic end generated code: output=bbddbc8e8bef871d input=43be86aba5c31e44]*/ { if (array_do_extend(self, bb) == -1) return NULL; @@ -1109,29 +1225,35 @@ array_extend(arrayobject *self, PyObject *bb) return Py_None; } -PyDoc_STRVAR(extend_doc, -"extend(array or iterable)\n\ -\n\ - Append items to the end of the array."); +/*[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_insert(arrayobject *self, PyObject *args) +array_array_insert_impl(arrayobject *self, Py_ssize_t i, PyObject *v) +/*[clinic end generated code: output=5a3648e278348564 input=5577d1b4383e9313]*/ { - Py_ssize_t i; - PyObject *v; - if (!PyArg_ParseTuple(args, "nO:insert", &i, &v)) - return NULL; return ins(self, i, v); } -PyDoc_STRVAR(insert_doc, -"insert(i,x)\n\ -\n\ -Insert a new item x into the array before position i."); +/*[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_buffer_info(arrayobject *self, PyObject *unused) +array_array_buffer_info_impl(arrayobject *self) +/*[clinic end generated code: output=9b2a4ec3ae7e98e7 input=a58bae5c6e1ac6a6]*/ { PyObject *retval = NULL, *v; @@ -1156,29 +1278,34 @@ array_buffer_info(arrayobject *self, PyObject *unused) return retval; } -PyDoc_STRVAR(buffer_info_doc, -"buffer_info() -> (address, length)\n\ -\n\ -Return a tuple (address, length) giving the current memory address and\n\ -the length in items of the buffer used to hold array's contents\n\ -The length should be multiplied by the itemsize attribute to calculate\n\ -the buffer length in bytes."); +/*[clinic input] +array.array.append + + v: object + / +Append new value v to the end of the array. +[clinic start generated code]*/ static PyObject * -array_append(arrayobject *self, PyObject *v) +array_array_append(arrayobject *self, PyObject *v) +/*[clinic end generated code: output=745a0669bf8db0e2 input=0b98d9d78e78f0fa]*/ { return ins(self, Py_SIZE(self), v); } -PyDoc_STRVAR(append_doc, -"append(x)\n\ -\n\ -Append new value x to the end of the array."); +/*[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_byteswap(arrayobject *self, PyObject *unused) +array_array_byteswap_impl(arrayobject *self) +/*[clinic end generated code: output=5f8236cbdf0d90b5 input=6a85591b950a0186]*/ { char *p; Py_ssize_t i; @@ -1228,14 +1355,15 @@ array_byteswap(arrayobject *self, PyObject *unused) return Py_None; } -PyDoc_STRVAR(byteswap_doc, -"byteswap()\n\ -\n\ -Byteswap all items of the array. If the items in the array are not 1, 2,\n\ -4, or 8 bytes in size, RuntimeError is raised."); +/*[clinic input] +array.array.reverse + +Reverse the order of the items in the array. +[clinic start generated code]*/ static PyObject * -array_reverse(arrayobject *self, PyObject *unused) +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; @@ -1261,27 +1389,26 @@ array_reverse(arrayobject *self, PyObject *unused) return Py_None; } -PyDoc_STRVAR(reverse_doc, -"reverse()\n\ -\n\ -Reverse the order of the items in the array."); +/*[clinic input] +array.array.fromfile + f: object + n: Py_ssize_t + / -/* Forward */ -static PyObject *array_frombytes(arrayobject *self, PyObject *args); +Read n objects from the file object f and append them to the end of the array. +[clinic start generated code]*/ static PyObject * -array_fromfile(arrayobject *self, PyObject *args) +array_array_fromfile_impl(arrayobject *self, PyObject *f, Py_ssize_t n) +/*[clinic end generated code: output=ec9f600e10f53510 input=e188afe8e58adf40]*/ { - PyObject *f, *b, *res; + PyObject *b, *res; Py_ssize_t itemsize = self->ob_descr->itemsize; - Py_ssize_t n, nbytes; + Py_ssize_t nbytes; _Py_IDENTIFIER(read); int not_enough_bytes; - if (!PyArg_ParseTuple(args, "On:fromfile", &f, &n)) - return NULL; - if (n < 0) { PyErr_SetString(PyExc_ValueError, "negative count"); return NULL; @@ -1305,13 +1432,8 @@ array_fromfile(arrayobject *self, PyObject *args) not_enough_bytes = (PyBytes_GET_SIZE(b) != nbytes); - args = Py_BuildValue("(O)", b); + res = array_array_frombytes(self, b); Py_DECREF(b); - if (args == NULL) - return NULL; - - res = array_frombytes(self, args); - Py_DECREF(args); if (res == NULL) return NULL; @@ -1325,15 +1447,18 @@ array_fromfile(arrayobject *self, PyObject *args) return res; } -PyDoc_STRVAR(fromfile_doc, -"fromfile(f, n)\n\ -\n\ -Read n objects from the file object f and append them to the end of the\n\ -array."); +/*[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_tofile(arrayobject *self, PyObject *f) +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 */ @@ -1368,14 +1493,18 @@ array_tofile(arrayobject *self, PyObject *f) return Py_None; } -PyDoc_STRVAR(tofile_doc, -"tofile(f)\n\ -\n\ -Write all items (as machine values) to the file object f."); +/*[clinic input] +array.array.fromlist + list: object + / + +Append items to array from list. +[clinic start generated code]*/ static PyObject * -array_fromlist(arrayobject *self, PyObject *list) +array_array_fromlist(arrayobject *self, PyObject *list) +/*[clinic end generated code: output=26411c2d228a3e3f input=be2605a96c49680f]*/ { Py_ssize_t n; @@ -1402,13 +1531,15 @@ array_fromlist(arrayobject *self, PyObject *list) return Py_None; } -PyDoc_STRVAR(fromlist_doc, -"fromlist(list)\n\ -\n\ -Append items to array from list."); +/*[clinic input] +array.array.tolist + +Convert array to an ordinary list with the same items. +[clinic start generated code]*/ static PyObject * -array_tolist(arrayobject *self, PyObject *unused) +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; @@ -1429,11 +1560,6 @@ array_tolist(arrayobject *self, PyObject *unused) return NULL; } -PyDoc_STRVAR(tolist_doc, -"tolist() -> list\n\ -\n\ -Convert array to an ordinary list with the same items."); - static PyObject * frombytes(arrayobject *self, Py_buffer *buffer) { @@ -1441,14 +1567,14 @@ frombytes(arrayobject *self, Py_buffer *buffer) Py_ssize_t n; if (buffer->itemsize != 1) { PyBuffer_Release(buffer); - PyErr_SetString(PyExc_TypeError, "string/buffer of bytes required."); + 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, - "string length not a multiple of item size"); + "bytes length not a multiple of item size"); return NULL; } n = n / itemsize; @@ -1471,47 +1597,52 @@ frombytes(arrayobject *self, Py_buffer *buffer) return Py_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_fromstring(arrayobject *self, PyObject *args) +array_array_fromstring_impl(arrayobject *self, Py_buffer *buffer) +/*[clinic end generated code: output=31c4baa779df84ce input=a3341a512e11d773]*/ { - Py_buffer buffer; if (PyErr_WarnEx(PyExc_DeprecationWarning, "fromstring() is deprecated. Use frombytes() instead.", 2) != 0) return NULL; - if (!PyArg_ParseTuple(args, "s*:fromstring", &buffer)) - return NULL; - else - return frombytes(self, &buffer); + return frombytes(self, buffer); } -PyDoc_STRVAR(fromstring_doc, -"fromstring(string)\n\ -\n\ -Appends items from the string, interpreting it as an array of machine\n\ -values, as if it had been read from a file using the fromfile() method).\n\ -\n\ -This method is deprecated. Use frombytes instead."); +/*[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_frombytes(arrayobject *self, PyObject *args) +array_array_frombytes_impl(arrayobject *self, Py_buffer *buffer) +/*[clinic end generated code: output=d9842c8f7510a516 input=2bbf2b53ebfcc988]*/ { - Py_buffer buffer; - if (!PyArg_ParseTuple(args, "y*:frombytes", &buffer)) - return NULL; - else - return frombytes(self, &buffer); + return frombytes(self, buffer); } -PyDoc_STRVAR(frombytes_doc, -"frombytes(bytestring)\n\ -\n\ -Appends items from the string, interpreting it as an array of machine\n\ -values, as if it had been read from a file using the fromfile() method)."); +/*[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_tobytes(arrayobject *self, PyObject *unused) +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, @@ -1521,40 +1652,44 @@ array_tobytes(arrayobject *self, PyObject *unused) } } -PyDoc_STRVAR(tobytes_doc, -"tobytes() -> bytes\n\ -\n\ -Convert the array to an array of machine values and return the bytes\n\ -representation."); +/*[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_tostring(arrayobject *self, PyObject *unused) +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_tobytes(self, unused); + return array_array_tobytes_impl(self); } -PyDoc_STRVAR(tostring_doc, -"tostring() -> bytes\n\ -\n\ -Convert the array to an array of machine values and return the bytes\n\ -representation.\n\ -\n\ -This method is deprecated. Use tobytes instead."); +/*[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_fromunicode(arrayobject *self, PyObject *args) +array_array_fromunicode_impl(arrayobject *self, Py_UNICODE *ustr, + Py_ssize_clean_t ustr_length) +/*[clinic end generated code: output=ebb72fc16975e06d input=150f00566ffbca6e]*/ { - Py_UNICODE *ustr; - Py_ssize_t n; char typecode; - if (!PyArg_ParseTuple(args, "u#:fromunicode", &ustr, &n)) - return NULL; typecode = self->ob_descr->typecode; if (typecode != 'u') { PyErr_SetString(PyExc_ValueError, @@ -1562,29 +1697,30 @@ array_fromunicode(arrayobject *self, PyObject *args) "unicode type arrays"); return NULL; } - if (n > 0) { + if (ustr_length > 0) { Py_ssize_t old_size = Py_SIZE(self); - if (array_resize(self, old_size + n) == -1) + if (array_resize(self, old_size + ustr_length) == -1) return NULL; memcpy(self->ob_item + old_size * sizeof(Py_UNICODE), - ustr, n * sizeof(Py_UNICODE)); + ustr, ustr_length * sizeof(Py_UNICODE)); } - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(fromunicode_doc, -"fromunicode(ustr)\n\ -\n\ -Extends this array with data from the unicode string ustr.\n\ -The array must be a unicode type array; otherwise a ValueError\n\ -is raised. Use array.frombytes(ustr.encode(...)) to\n\ -append Unicode data to an array of some other type."); +/*[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_tounicode(arrayobject *self, PyObject *unused) +array_array_tounicode_impl(arrayobject *self) +/*[clinic end generated code: output=08e442378336e1ef input=127242eebe70b66d]*/ { char typecode; typecode = self->ob_descr->typecode; @@ -1596,70 +1732,24 @@ array_tounicode(arrayobject *self, PyObject *unused) return PyUnicode_FromUnicode((Py_UNICODE *) self->ob_item, Py_SIZE(self)); } -PyDoc_STRVAR(tounicode_doc, -"tounicode() -> unicode\n\ -\n\ -Convert the array to a unicode string. The array must be\n\ -a unicode type array; otherwise a ValueError is raised. Use\n\ -array.tobytes().decode() to obtain a unicode string from\n\ -an array of some other type."); +/*[clinic input] +array.array.__sizeof__ +Size of the array in memory, in bytes. +[clinic start generated code]*/ static PyObject * -array_sizeof(arrayobject *self, PyObject *unused) +array_array___sizeof___impl(arrayobject *self) +/*[clinic end generated code: output=d8e1c61ebbe3eaed input=805586565bf2b3c6]*/ { Py_ssize_t res; res = sizeof(arrayobject) + self->allocated * self->ob_descr->itemsize; return PyLong_FromSsize_t(res); } -PyDoc_STRVAR(sizeof_doc, -"__sizeof__() -> int\n\ -\n\ -Size of the array in memory, in bytes."); - /*********************** Pickling support ************************/ -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 - static const struct mformatdescr { size_t size; int is_signed; @@ -1835,21 +1925,29 @@ make_array(PyTypeObject *arraytype, char typecode, PyObject *items) * 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_reconstructor(PyObject *self, PyObject *args) +array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, + int typecode, + enum machine_format_code mformat_code, + PyObject *items) +/*[clinic end generated code: output=6ecbf0e8e4d92ab9 input=2464dc8f4c7736b5]*/ { - PyTypeObject *arraytype; - PyObject *items; PyObject *converted_items; PyObject *result; - int typecode; - enum machine_format_code mformat_code; struct arraydescr *descr; - if (!PyArg_ParseTuple(args, "OCiO:array._array_reconstructor", - &arraytype, &typecode, &mformat_code, &items)) - return NULL; - if (!PyType_Check(arraytype)) { PyErr_Format(PyExc_TypeError, "first argument must a type object, not %.200s", @@ -2000,7 +2098,7 @@ array_reconstructor(PyObject *self, PyObject *args) */ for (descr = descriptors; descr->typecode != '\0'; descr++) { if (descr->is_integer_type && - descr->itemsize == mf_descr.size && + (size_t)descr->itemsize == mf_descr.size && descr->is_signed == mf_descr.is_signed) typecode = descr->typecode; } @@ -2038,13 +2136,23 @@ array_reconstructor(PyObject *self, PyObject *args) return result; } +/*[clinic input] +array.array.__reduce_ex__ + + value: object + / + +Return state information for pickling. +[clinic start generated code]*/ + static PyObject * -array_reduce_ex(arrayobject *array, PyObject *value) +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 = array->ob_descr->typecode; + int typecode = self->ob_descr->typecode; int mformat_code; static PyObject *array_reconstructor = NULL; long protocol; @@ -2072,7 +2180,7 @@ array_reduce_ex(arrayobject *array, PyObject *value) if (protocol == -1 && PyErr_Occurred()) return NULL; - dict = _PyObject_GetAttrId((PyObject *)array, &PyId___dict__); + dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__); if (dict == NULL) { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return NULL; @@ -2095,32 +2203,30 @@ array_reduce_ex(arrayobject *array, PyObject *value) * coercing unicode objects to bytes in array_reconstructor. */ PyObject *list; - list = array_tolist(array, NULL); + list = array_array_tolist_impl(self); if (list == NULL) { Py_DECREF(dict); return NULL; } result = Py_BuildValue( - "O(CO)O", Py_TYPE(array), typecode, list, dict); + "O(CO)O", Py_TYPE(self), typecode, list, dict); Py_DECREF(list); Py_DECREF(dict); return result; } - array_str = array_tobytes(array, NULL); + 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(array), typecode, + "O(OCiN)O", array_reconstructor, Py_TYPE(self), typecode, mformat_code, array_str, dict); Py_DECREF(dict); return result; } -PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); - static PyObject * array_get_typecode(arrayobject *a, void *closure) { @@ -2143,55 +2249,31 @@ static PyGetSetDef array_getsets [] = { }; static PyMethodDef array_methods[] = { - {"append", (PyCFunction)array_append, METH_O, - append_doc}, - {"buffer_info", (PyCFunction)array_buffer_info, METH_NOARGS, - buffer_info_doc}, - {"byteswap", (PyCFunction)array_byteswap, METH_NOARGS, - byteswap_doc}, - {"__copy__", (PyCFunction)array_copy, METH_NOARGS, - copy_doc}, - {"count", (PyCFunction)array_count, METH_O, - count_doc}, - {"__deepcopy__", (PyCFunction)array_copy, METH_O, - copy_doc}, - {"extend", (PyCFunction)array_extend, METH_O, - extend_doc}, - {"fromfile", (PyCFunction)array_fromfile, METH_VARARGS, - fromfile_doc}, - {"fromlist", (PyCFunction)array_fromlist, METH_O, - fromlist_doc}, - {"fromstring", (PyCFunction)array_fromstring, METH_VARARGS, - fromstring_doc}, - {"frombytes", (PyCFunction)array_frombytes, METH_VARARGS, - frombytes_doc}, - {"fromunicode", (PyCFunction)array_fromunicode, METH_VARARGS, - fromunicode_doc}, - {"index", (PyCFunction)array_index, METH_O, - index_doc}, - {"insert", (PyCFunction)array_insert, METH_VARARGS, - insert_doc}, - {"pop", (PyCFunction)array_pop, METH_VARARGS, - pop_doc}, - {"__reduce_ex__", (PyCFunction)array_reduce_ex, METH_O, - reduce_doc}, - {"remove", (PyCFunction)array_remove, METH_O, - remove_doc}, - {"reverse", (PyCFunction)array_reverse, METH_NOARGS, - reverse_doc}, - {"tofile", (PyCFunction)array_tofile, METH_O, - tofile_doc}, - {"tolist", (PyCFunction)array_tolist, METH_NOARGS, - tolist_doc}, - {"tostring", (PyCFunction)array_tostring, METH_NOARGS, - tostring_doc}, - {"tobytes", (PyCFunction)array_tobytes, METH_NOARGS, - tobytes_doc}, - {"tounicode", (PyCFunction)array_tounicode, METH_NOARGS, - tounicode_doc}, - {"__sizeof__", (PyCFunction)array_sizeof, METH_NOARGS, - sizeof_doc}, - {NULL, NULL} /* sentinel */ + 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 * @@ -2207,9 +2289,9 @@ array_repr(arrayobject *a) return PyUnicode_FromFormat("array('%c')", (int)typecode); } if (typecode == 'u') { - v = array_tounicode(a, NULL); + v = array_array_tounicode_impl(a); } else { - v = array_tolist(a, NULL); + v = array_array_tolist_impl(a); } if (v == NULL) return NULL; @@ -2446,7 +2528,11 @@ static const void *emptybuf = ""; static int array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags) { - if (view==NULL) goto finish; + 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; @@ -2476,7 +2562,6 @@ array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags) #endif } - finish: self->ob_exports++; return 0; } @@ -2586,15 +2671,9 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } else if (initial != NULL && (PyByteArray_Check(initial) || PyBytes_Check(initial))) { - PyObject *t_initial, *v; - t_initial = PyTuple_Pack(1, initial); - if (t_initial == NULL) { - Py_DECREF(a); - return NULL; - } - v = array_frombytes((arrayobject *)a, - t_initial); - Py_DECREF(t_initial); + PyObject *v; + v = array_array_frombytes((arrayobject *)a, + initial); if (v == NULL) { Py_DECREF(a); return NULL; @@ -2628,7 +2707,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->allocated = Py_SIZE(self); } } - else if (initial != NULL && array_Check(initial)) { + 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); @@ -2766,16 +2845,10 @@ static PyTypeObject Arraytype = { /*********************** Array Iterator **************************/ -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) +/*[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) @@ -2823,31 +2896,47 @@ arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg) return 0; } +/*[clinic input] +array.arrayiterator.__reduce__ + +Return state information for pickling. +[clinic start generated code]*/ + static PyObject * -arrayiter_reduce(arrayiterobject *it) +array_arrayiterator___reduce___impl(arrayiterobject *self) +/*[clinic end generated code: output=7898a52e8e66e016 input=a062ea1e9951417a]*/ { return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), - it->ao, it->index); + self->ao, self->index); } +/*[clinic input] +array.arrayiterator.__setstate__ + + state: object + / + +Set state information for unpickling. +[clinic start generated code]*/ + static PyObject * -arrayiter_setstate(arrayiterobject *it, PyObject *state) +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; - it->index = index; + else if (index > Py_SIZE(self->ao)) + index = Py_SIZE(self->ao); /* iterator exhausted */ + self->index = index; Py_RETURN_NONE; } -PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); static PyMethodDef arrayiter_methods[] = { - {"__reduce__", (PyCFunction)arrayiter_reduce, METH_NOARGS, - reduce_doc}, - {"__setstate__", (PyCFunction)arrayiter_setstate, METH_O, - setstate_doc}, + ARRAY_ARRAYITERATOR___REDUCE___METHODDEF + ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF {NULL, NULL} /* sentinel */ }; @@ -2888,39 +2977,21 @@ static PyTypeObject PyArrayIter_Type = { /* No functions in array module. */ static PyMethodDef a_methods[] = { - {"_array_reconstructor", array_reconstructor, METH_VARARGS, - PyDoc_STR("Internal. Used for pickling support.")}, + ARRAY__ARRAY_RECONSTRUCTOR_METHODDEF {NULL, NULL, 0, NULL} /* Sentinel */ }; -static struct PyModuleDef arraymodule = { - PyModuleDef_HEAD_INIT, - "array", - module_doc, - -1, - a_methods, - NULL, - NULL, - NULL, - NULL -}; - - -PyMODINIT_FUNC -PyInit_array(void) +static int +array_modexec(PyObject *m) { - PyObject *m; char buffer[Py_ARRAY_LENGTH(descriptors)], *p; PyObject *typecodes; Py_ssize_t size = 0; struct arraydescr *descr; if (PyType_Ready(&Arraytype) < 0) - return NULL; + return -1; Py_TYPE(&PyArrayIter_Type) = &PyType_Type; - m = PyModule_Create(&arraymodule); - if (m == NULL) - return NULL; Py_INCREF((PyObject *)&Arraytype); PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype); @@ -2943,5 +3014,30 @@ PyInit_array(void) Py_DECREF(m); m = NULL; } - return m; + 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/Modules/atexitmodule.c b/Modules/atexitmodule.c index 98870141dda9..739c18836f98 100644 --- a/Modules/atexitmodule.c +++ b/Modules/atexitmodule.c @@ -60,7 +60,7 @@ atexit_cleanup(atexitmodule_state *modstate) modstate->ncallbacks = 0; } -/* Installed into pythonrun.c's atexit mechanism */ +/* Installed into pylifecycle.c's atexit mechanism */ static void atexit_callfuncs(void) @@ -94,7 +94,7 @@ atexit_callfuncs(void) if (exc_type) { Py_DECREF(exc_type); Py_XDECREF(exc_value); - Py_XDECREF(exc_tb); + Py_XDECREF(exc_tb); } PyErr_Fetch(&exc_type, &exc_value, &exc_tb); if (!PyErr_ExceptionMatches(PyExc_SystemExit)) { @@ -147,7 +147,7 @@ atexit_register(PyObject *self, PyObject *args, PyObject *kwargs) if (PyTuple_GET_SIZE(args) == 0) { PyErr_SetString(PyExc_TypeError, "register() takes at least 1 argument (0 given)"); - return NULL; + return NULL; } func = PyTuple_GET_ITEM(args, 0); @@ -159,7 +159,7 @@ atexit_register(PyObject *self, PyObject *args, PyObject *kwargs) new_callback = PyMem_Malloc(sizeof(atexit_callback)); if (new_callback == NULL) - return PyErr_NoMemory(); + return PyErr_NoMemory(); new_callback->args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args)); if (new_callback->args == NULL) { @@ -336,7 +336,7 @@ PyInit_atexit(void) modstate = GET_ATEXIT_STATE(m); modstate->callback_len = 32; modstate->ncallbacks = 0; - modstate->atexit_callbacks = PyMem_New(atexit_callback*, + modstate->atexit_callbacks = PyMem_New(atexit_callback*, modstate->callback_len); if (modstate->atexit_callbacks == NULL) return NULL; diff --git a/Modules/audioop.c b/Modules/audioop.c index ae3ff060b474..bbc458f9b71f 100644 --- a/Modules/audioop.c +++ b/Modules/audioop.c @@ -390,128 +390,153 @@ audioop_check_parameters(Py_ssize_t len, int size) 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(PyObject *self, PyObject *args) +audioop_getsample_impl(PyModuleDef *module, Py_buffer *fragment, int width, + Py_ssize_t index) +/*[clinic end generated code: output=3995e189fdc8ec16 input=88edbe2871393549]*/ { - Py_buffer view; - Py_ssize_t i; - int size; int val; - if (!PyArg_ParseTuple(args, "y*in:getsample", &view, &size, &i)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) - goto error; - if (i < 0 || i >= view.len/size) { + if (index < 0 || index >= fragment->len/width) { PyErr_SetString(AudioopError, "Index out of range"); - goto error; + return NULL; } - val = GETRAWSAMPLE(size, view.buf, i*size); - PyBuffer_Release(&view); + val = GETRAWSAMPLE(width, fragment->buf, index*width); return PyLong_FromLong(val); - - error: - PyBuffer_Release(&view); - return NULL; } +/*[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(PyObject *self, PyObject *args) +audioop_max_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=85047ee1001f2305 input=32bea5ea0ac8c223]*/ { - Py_buffer view; Py_ssize_t i; - int size; unsigned int absval, max = 0; - if (!PyArg_ParseTuple(args, "y*i:max", &view, &size)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) { - PyBuffer_Release(&view); - return NULL; - } - for (i = 0; i < view.len; i += size) { - int val = GETRAWSAMPLE(size, view.buf, i); + for (i = 0; i < fragment->len; i += width) { + int val = GETRAWSAMPLE(width, fragment->buf, i); if (val < 0) absval = (-val); else absval = val; if (absval > max) max = absval; } - PyBuffer_Release(&view); 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(PyObject *self, PyObject *args) +audioop_minmax_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=ae8f5513c64fd569 input=89848e9b927a0696]*/ { - Py_buffer view; Py_ssize_t i; - int size; /* -1 trick below is needed on Windows to support -0x80000000 without a warning */ int min = 0x7fffffff, max = -0x7FFFFFFF-1; - if (!PyArg_ParseTuple(args, "y*i:minmax", &view, &size)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) { - PyBuffer_Release(&view); - return NULL; - } - for (i = 0; i < view.len; i += size) { - int val = GETRAWSAMPLE(size, view.buf, i); + 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; } - PyBuffer_Release(&view); 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(PyObject *self, PyObject *args) +audioop_avg_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=7fccd645c95f4860 input=1114493c7611334d]*/ { - Py_buffer view; Py_ssize_t i; - int size, avg; + int avg; double sum = 0.0; - if (!PyArg_ParseTuple(args, "y*i:avg", &view, &size)) - return NULL; - if (!audioop_check_parameters(view.len, size)) { - PyBuffer_Release(&view); + if (!audioop_check_parameters(fragment->len, width)) return NULL; - } - for (i = 0; i < view.len; i += size) - sum += GETRAWSAMPLE(size, view.buf, i); - if (view.len == 0) + 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)(view.len/size)); - PyBuffer_Release(&view); + 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(PyObject *self, PyObject *args) +audioop_rms_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=7b398702c81b709d input=4cc57c6c94219d78]*/ { - Py_buffer view; Py_ssize_t i; - int size; unsigned int res; double sum_squares = 0.0; - if (!PyArg_ParseTuple(args, "y*i:rms", &view, &size)) - return NULL; - if (!audioop_check_parameters(view.len, size)) { - PyBuffer_Release(&view); + if (!audioop_check_parameters(fragment->len, width)) return NULL; - } - for (i = 0; i < view.len; i += size) { - double val = GETRAWSAMPLE(size, view.buf, i); + for (i = 0; i < fragment->len; i += width) { + double val = GETRAWSAMPLE(width, fragment->buf, i); sum_squares += val*val; } - if (view.len == 0) + if (fragment->len == 0) res = 0; else - res = (unsigned int)sqrt(sum_squares / (double)(view.len/size)); - PyBuffer_Release(&view); + res = (unsigned int)sqrt(sum_squares / (double)(fragment->len/width)); return PyLong_FromUnsignedLong(res); } @@ -558,31 +583,39 @@ static double _sum2(const short *a, const short *b, Py_ssize_t len) ** 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(PyObject *self, PyObject *args) +audioop_findfit_impl(PyModuleDef *module, Py_buffer *fragment, + Py_buffer *reference) +/*[clinic end generated code: output=609eedf5d823d6dd input=62c305605e183c9a]*/ { - Py_buffer view1; - Py_buffer view2; const short *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 (!PyArg_ParseTuple(args, "y*y*:findfit", &view1, &view2)) - return NULL; - if (view1.len & 1 || view2.len & 1) { + if (fragment->len & 1 || reference->len & 1) { PyErr_SetString(AudioopError, "Strings should be even-sized"); - goto error; + return NULL; } - cp1 = (const short *)view1.buf; - len1 = view1.len >> 1; - cp2 = (const short *)view2.buf; - len2 = view2.len >> 1; + cp1 = (const short *)fragment->buf; + len1 = fragment->len >> 1; + cp2 = (const short *)reference->buf; + len2 = reference->len >> 1; if (len1 < len2) { PyErr_SetString(AudioopError, "First sample should be longer"); - goto error; + return NULL; } sum_ri_2 = _sum2(cp2, cp2, len2); sum_aij_2 = _sum2(cp1, cp1, len2); @@ -612,93 +645,96 @@ audioop_findfit(PyObject *self, PyObject *args) factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2; - PyBuffer_Release(&view1); - PyBuffer_Release(&view2); return Py_BuildValue("(nf)", best_j, factor); - - error: - PyBuffer_Release(&view1); - PyBuffer_Release(&view2); - return NULL; } /* ** 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(PyObject *self, PyObject *args) +audioop_findfactor_impl(PyModuleDef *module, Py_buffer *fragment, + Py_buffer *reference) +/*[clinic end generated code: output=5566a8c55de54f99 input=816680301d012b21]*/ { - Py_buffer view1; - Py_buffer view2; const short *cp1, *cp2; Py_ssize_t len; double sum_ri_2, sum_aij_ri, result; - if (!PyArg_ParseTuple(args, "y*y*:findfactor", &view1, &view2)) - return NULL; - if (view1.len & 1 || view2.len & 1) { + if (fragment->len & 1 || reference->len & 1) { PyErr_SetString(AudioopError, "Strings should be even-sized"); - goto error; + return NULL; } - if (view1.len != view2.len) { + if (fragment->len != reference->len) { PyErr_SetString(AudioopError, "Samples should be same size"); - goto error; + return NULL; } - cp1 = (const short *)view1.buf; - cp2 = (const short *)view2.buf; - len = view1.len >> 1; + cp1 = (const short *)fragment->buf; + cp2 = (const short *)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; - PyBuffer_Release(&view1); - PyBuffer_Release(&view2); return PyFloat_FromDouble(result); - - error: - PyBuffer_Release(&view1); - PyBuffer_Release(&view2); - return NULL; } /* ** 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(PyObject *self, PyObject *args) +audioop_findmax_impl(PyModuleDef *module, Py_buffer *fragment, + Py_ssize_t length) +/*[clinic end generated code: output=01fe796fad2573bb input=2f304801ed42383c]*/ { - Py_buffer view; const short *cp1; - Py_ssize_t len1, len2; + Py_ssize_t len1; Py_ssize_t j, best_j; double aj_m1, aj_lm1; double result, best_result; - if (!PyArg_ParseTuple(args, "y*n:findmax", &view, &len2)) - return NULL; - if (view.len & 1) { + if (fragment->len & 1) { PyErr_SetString(AudioopError, "Strings should be even-sized"); - goto error; + return NULL; } - cp1 = (const short *)view.buf; - len1 = view.len >> 1; + cp1 = (const short *)fragment->buf; + len1 = fragment->len >> 1; - if (len2 < 0 || len1 < len2) { + if (length < 0 || len1 < length) { PyErr_SetString(AudioopError, "Input sample should be longer"); - goto error; + return NULL; } - result = _sum2(cp1, cp1, len2); + result = _sum2(cp1, cp1, length); best_result = result; best_j = 0; - for ( j=1; j<=len1-len2; j++) { + for ( j=1; j<=len1-length; j++) { aj_m1 = (double)cp1[j-1]; - aj_lm1 = (double)cp1[j+len2-1]; + aj_lm1 = (double)cp1[j+length-1]; result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1; @@ -709,39 +745,37 @@ audioop_findmax(PyObject *self, PyObject *args) } - PyBuffer_Release(&view); return PyLong_FromSsize_t(best_j); - - error: - PyBuffer_Release(&view); - return NULL; } +/*[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(PyObject *self, PyObject *args) +audioop_avgpp_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=06c8380fd6e34207 input=0b3cceeae420a7d9]*/ { - Py_buffer view; Py_ssize_t i; - int size, prevval, prevextremevalid = 0, - prevextreme = 0; + int prevval, prevextremevalid = 0, prevextreme = 0; double sum = 0.0; unsigned int avg; int diff, prevdiff, nextreme = 0; - if (!PyArg_ParseTuple(args, "y*i:avgpp", &view, &size)) - return NULL; - if (!audioop_check_parameters(view.len, size)) { - PyBuffer_Release(&view); + if (!audioop_check_parameters(fragment->len, width)) return NULL; - } - if (view.len <= size) { - PyBuffer_Release(&view); + if (fragment->len <= width) return PyLong_FromLong(0); - } - prevval = GETRAWSAMPLE(size, view.buf, 0); + prevval = GETRAWSAMPLE(width, fragment->buf, 0); prevdiff = 17; /* Anything != 0, 1 */ - for (i = size; i < view.len; i += size) { - int val = GETRAWSAMPLE(size, view.buf, i); + for (i = width; i < fragment->len; i += width) { + int val = GETRAWSAMPLE(width, fragment->buf, i); if (val != prevval) { diff = val < prevval; if (prevdiff == !diff) { @@ -768,34 +802,36 @@ audioop_avgpp(PyObject *self, PyObject *args) avg = 0; else avg = (unsigned int)(sum / (double)nextreme); - PyBuffer_Release(&view); 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(PyObject *self, PyObject *args) +audioop_maxpp_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=c300c0bd7e8535c0 input=671a13e1518f80a1]*/ { - Py_buffer view; Py_ssize_t i; - int size, prevval, prevextremevalid = 0, - prevextreme = 0; + int prevval, prevextremevalid = 0, prevextreme = 0; unsigned int max = 0, extremediff; int diff, prevdiff; - if (!PyArg_ParseTuple(args, "y*i:maxpp", &view, &size)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) { - PyBuffer_Release(&view); - return NULL; - } - if (view.len <= size) { - PyBuffer_Release(&view); + if (fragment->len <= width) return PyLong_FromLong(0); - } - prevval = GETRAWSAMPLE(size, view.buf, 0); + prevval = GETRAWSAMPLE(width, fragment->buf, 0); prevdiff = 17; /* Anything != 0, 1 */ - for (i = size; i < view.len; i += size) { - int val = GETRAWSAMPLE(size, view.buf, i); + for (i = width; i < fragment->len; i += width) { + int val = GETRAWSAMPLE(width, fragment->buf, i); if (val != prevval) { diff = val < prevval; if (prevdiff == !diff) { @@ -819,187 +855,219 @@ audioop_maxpp(PyObject *self, PyObject *args) prevdiff = diff; } } - PyBuffer_Release(&view); 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(PyObject *self, PyObject *args) +audioop_cross_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=99e6572d7d7cdbf1 input=b1b3f15b83f6b41a]*/ { - Py_buffer view; Py_ssize_t i; - int size; int prevval; Py_ssize_t ncross; - if (!PyArg_ParseTuple(args, "y*i:cross", &view, &size)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) { - PyBuffer_Release(&view); - return NULL; - } ncross = -1; prevval = 17; /* Anything <> 0,1 */ - for (i = 0; i < view.len; i += size) { - int val = GETRAWSAMPLE(size, view.buf, i) < 0; + for (i = 0; i < fragment->len; i += width) { + int val = GETRAWSAMPLE(width, fragment->buf, i) < 0; if (val != prevval) ncross++; prevval = val; } - PyBuffer_Release(&view); 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(PyObject *self, PyObject *args) +audioop_mul_impl(PyModuleDef *module, Py_buffer *fragment, int width, + double factor) +/*[clinic end generated code: output=1c7c31191ac86b10 input=c726667baa157d3c]*/ { - Py_buffer view; signed char *ncp; Py_ssize_t i; - int size; - double factor, maxval, minval; - PyObject *rv = NULL; + double maxval, minval; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*id:mul", &view, &size, &factor)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) - goto exit; - maxval = (double) maxvals[size]; - minval = (double) minvals[size]; + maxval = (double) maxvals[width]; + minval = (double) minvals[width]; - rv = PyBytes_FromStringAndSize(NULL, view.len); + rv = PyBytes_FromStringAndSize(NULL, fragment->len); if (rv == NULL) - goto exit; + return NULL; ncp = (signed char *)PyBytes_AsString(rv); - for (i = 0; i < view.len; i += size) { - double val = GETRAWSAMPLE(size, view.buf, i); + for (i = 0; i < fragment->len; i += width) { + double val = GETRAWSAMPLE(width, fragment->buf, i); val *= factor; val = floor(fbound(val, minval, maxval)); - SETRAWSAMPLE(size, ncp, i, (int)val); + SETRAWSAMPLE(width, ncp, i, (int)val); } - exit: - PyBuffer_Release(&view); 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(PyObject *self, PyObject *args) +audioop_tomono_impl(PyModuleDef *module, Py_buffer *fragment, int width, + double lfactor, double rfactor) +/*[clinic end generated code: output=553f547c5e29e3b6 input=c4ec949b3f4dddfa]*/ { - Py_buffer pcp; signed char *cp, *ncp; Py_ssize_t len, i; - int size; - double fac1, fac2, maxval, minval; - PyObject *rv = NULL; + double maxval, minval; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*idd:tomono", - &pcp, &size, &fac1, &fac2)) + cp = fragment->buf; + len = fragment->len; + if (!audioop_check_parameters(len, width)) return NULL; - cp = pcp.buf; - len = pcp.len; - if (!audioop_check_parameters(len, size)) - goto exit; - if (((len / size) & 1) != 0) { + if (((len / width) & 1) != 0) { PyErr_SetString(AudioopError, "not a whole number of frames"); - goto exit; + return NULL; } - maxval = (double) maxvals[size]; - minval = (double) minvals[size]; + maxval = (double) maxvals[width]; + minval = (double) minvals[width]; rv = PyBytes_FromStringAndSize(NULL, len/2); if (rv == NULL) - goto exit; + return NULL; ncp = (signed char *)PyBytes_AsString(rv); - for (i = 0; i < len; i += size*2) { - double val1 = GETRAWSAMPLE(size, cp, i); - double val2 = GETRAWSAMPLE(size, cp, i + size); - double val = val1*fac1 + val2*fac2; + 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; val = floor(fbound(val, minval, maxval)); - SETRAWSAMPLE(size, ncp, i/2, val); + SETRAWSAMPLE(width, ncp, i/2, val); } - exit: - PyBuffer_Release(&pcp); 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(PyObject *self, PyObject *args) +audioop_tostereo_impl(PyModuleDef *module, Py_buffer *fragment, int width, + double lfactor, double rfactor) +/*[clinic end generated code: output=697bb6ba41e9dd2c input=27b6395ebfdff37a]*/ { - Py_buffer view; signed char *ncp; Py_ssize_t i; - int size; - double fac1, fac2, maxval, minval; - PyObject *rv = NULL; + double maxval, minval; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*idd:tostereo", - &view, &size, &fac1, &fac2)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) - goto exit; - maxval = (double) maxvals[size]; - minval = (double) minvals[size]; + maxval = (double) maxvals[width]; + minval = (double) minvals[width]; - if (view.len > PY_SSIZE_T_MAX/2) { + if (fragment->len > PY_SSIZE_T_MAX/2) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); - goto exit; + return NULL; } - rv = PyBytes_FromStringAndSize(NULL, view.len*2); + rv = PyBytes_FromStringAndSize(NULL, fragment->len*2); if (rv == NULL) - goto exit; + return NULL; ncp = (signed char *)PyBytes_AsString(rv); - for (i = 0; i < view.len; i += size) { - double val = GETRAWSAMPLE(size, view.buf, i); - int val1 = (int)floor(fbound(val*fac1, minval, maxval)); - int val2 = (int)floor(fbound(val*fac2, minval, maxval)); - SETRAWSAMPLE(size, ncp, i*2, val1); - SETRAWSAMPLE(size, ncp, i*2 + size, val2); + for (i = 0; i < fragment->len; i += width) { + double val = GETRAWSAMPLE(width, fragment->buf, i); + int val1 = (int)floor(fbound(val*lfactor, minval, maxval)); + int val2 = (int)floor(fbound(val*rfactor, minval, maxval)); + SETRAWSAMPLE(width, ncp, i*2, val1); + SETRAWSAMPLE(width, ncp, i*2 + width, val2); } - exit: - PyBuffer_Release(&view); 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(PyObject *self, PyObject *args) +audioop_add_impl(PyModuleDef *module, Py_buffer *fragment1, + Py_buffer *fragment2, int width) +/*[clinic end generated code: output=fe6c12f143e0b027 input=4a8d4bae4c1605c7]*/ { - Py_buffer view1; - Py_buffer view2; signed char *ncp; Py_ssize_t i; - int size, minval, maxval, newval; - PyObject *rv = NULL; + int minval, maxval, newval; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*y*i:add", - &view1, &view2, &size)) + if (!audioop_check_parameters(fragment1->len, width)) return NULL; - if (!audioop_check_parameters(view1.len, size)) - goto exit; - if (view1.len != view2.len) { + if (fragment1->len != fragment2->len) { PyErr_SetString(AudioopError, "Lengths should be the same"); - goto exit; + return NULL; } - maxval = maxvals[size]; - minval = minvals[size]; + maxval = maxvals[width]; + minval = minvals[width]; - rv = PyBytes_FromStringAndSize(NULL, view1.len); + rv = PyBytes_FromStringAndSize(NULL, fragment1->len); if (rv == NULL) - goto exit; + return NULL; ncp = (signed char *)PyBytes_AsString(rv); - for (i = 0; i < view1.len; i += size) { - int val1 = GETRAWSAMPLE(size, view1.buf, i); - int val2 = GETRAWSAMPLE(size, view2.buf, i); + for (i = 0; i < fragment1->len; i += width) { + int val1 = GETRAWSAMPLE(width, fragment1->buf, i); + int val2 = GETRAWSAMPLE(width, fragment2->buf, i); - if (size < 4) { + if (width < 4) { newval = val1 + val2; /* truncate in case of overflow */ if (newval > maxval) @@ -1013,165 +1081,178 @@ audioop_add(PyObject *self, PyObject *args) newval = (int)floor(fbound(fval, minval, maxval)); } - SETRAWSAMPLE(size, ncp, i, newval); + SETRAWSAMPLE(width, ncp, i, newval); } - exit: - PyBuffer_Release(&view1); - PyBuffer_Release(&view2); 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(PyObject *self, PyObject *args) +audioop_bias_impl(PyModuleDef *module, Py_buffer *fragment, int width, + int bias) +/*[clinic end generated code: output=ac1f4dda20a01c26 input=2b5cce5c3bb4838c]*/ { - Py_buffer view; signed char *ncp; Py_ssize_t i; - int size, bias; unsigned int val = 0, mask; - PyObject *rv = NULL; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*ii:bias", - &view, &size, &bias)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) - goto exit; - - rv = PyBytes_FromStringAndSize(NULL, view.len); + rv = PyBytes_FromStringAndSize(NULL, fragment->len); if (rv == NULL) - goto exit; + return NULL; ncp = (signed char *)PyBytes_AsString(rv); - mask = masks[size]; + mask = masks[width]; - for (i = 0; i < view.len; i += size) { - if (size == 1) - val = GETINTX(unsigned char, view.buf, i); - else if (size == 2) - val = GETINTX(unsigned short, view.buf, i); - else if (size == 3) - val = ((unsigned int)GETINT24(view.buf, i)) & 0xffffffu; + for (i = 0; i < fragment->len; i += width) { + if (width == 1) + val = GETINTX(unsigned char, fragment->buf, i); + else if (width == 2) + val = GETINTX(unsigned short, fragment->buf, i); + else if (width == 3) + val = ((unsigned int)GETINT24(fragment->buf, i)) & 0xffffffu; else { - assert(size == 4); - val = GETINTX(PY_UINT32_T, view.buf, i); + assert(width == 4); + val = GETINTX(PY_UINT32_T, fragment->buf, i); } val += (unsigned int)bias; /* wrap around in case of overflow */ val &= mask; - if (size == 1) + if (width == 1) SETINTX(unsigned char, ncp, i, val); - else if (size == 2) + else if (width == 2) SETINTX(unsigned short, ncp, i, val); - else if (size == 3) + else if (width == 3) SETINT24(ncp, i, (int)val); else { - assert(size == 4); + assert(width == 4); SETINTX(PY_UINT32_T, ncp, i, val); } } - exit: - PyBuffer_Release(&view); 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(PyObject *self, PyObject *args) +audioop_reverse_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=6ec3c91337f5925e input=668f890cf9f9d225]*/ { - Py_buffer view; unsigned char *ncp; Py_ssize_t i; - int size; - PyObject *rv = NULL; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*i:reverse", - &view, &size)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) - goto exit; - - rv = PyBytes_FromStringAndSize(NULL, view.len); + rv = PyBytes_FromStringAndSize(NULL, fragment->len); if (rv == NULL) - goto exit; + return NULL; ncp = (unsigned char *)PyBytes_AsString(rv); - for (i = 0; i < view.len; i += size) { - int val = GETRAWSAMPLE(size, view.buf, i); - SETRAWSAMPLE(size, ncp, view.len - i - size, val); + for (i = 0; i < fragment->len; i += width) { + int val = GETRAWSAMPLE(width, fragment->buf, i); + SETRAWSAMPLE(width, ncp, fragment->len - i - width, val); } - exit: - PyBuffer_Release(&view); 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(PyObject *self, PyObject *args) +audioop_byteswap_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=bfe4aa584b7a3f5b input=fae7611ceffa5c82]*/ { - Py_buffer view; unsigned char *ncp; Py_ssize_t i; - int size; - PyObject *rv = NULL; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*i:swapbytes", - &view, &size)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) - goto exit; - - rv = PyBytes_FromStringAndSize(NULL, view.len); + rv = PyBytes_FromStringAndSize(NULL, fragment->len); if (rv == NULL) - goto exit; + return NULL; ncp = (unsigned char *)PyBytes_AsString(rv); - for (i = 0; i < view.len; i += size) { + for (i = 0; i < fragment->len; i += width) { int j; - for (j = 0; j < size; j++) - ncp[i + size - 1 - j] = ((unsigned char *)view.buf)[i + j]; + for (j = 0; j < width; j++) + ncp[i + width - 1 - j] = ((unsigned char *)fragment->buf)[i + j]; } - exit: - PyBuffer_Release(&view); 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(PyObject *self, PyObject *args) +audioop_lin2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width, + int newwidth) +/*[clinic end generated code: output=cb6ca950d1df9898 input=5ce08c8aa2f24d96]*/ { - Py_buffer view; unsigned char *ncp; Py_ssize_t i, j; - int size, size2; - PyObject *rv = NULL; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*ii:lin2lin", - &view, &size, &size2)) + if (!audioop_check_parameters(fragment->len, width)) + return NULL; + if (!audioop_check_size(newwidth)) return NULL; - if (!audioop_check_parameters(view.len, size)) - goto exit; - if (!audioop_check_size(size2)) - goto exit; - - if (view.len/size > PY_SSIZE_T_MAX/size2) { + if (fragment->len/width > PY_SSIZE_T_MAX/newwidth) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); - goto exit; + return NULL; } - rv = PyBytes_FromStringAndSize(NULL, (view.len/size)*size2); + rv = PyBytes_FromStringAndSize(NULL, (fragment->len/width)*newwidth); if (rv == NULL) - goto exit; + return NULL; ncp = (unsigned char *)PyBytes_AsString(rv); - for (i = j = 0; i < view.len; i += size, j += size2) { - int val = GETSAMPLE32(size, view.buf, i); - SETSAMPLE32(size2, ncp, j, val); + for (i = j = 0; i < fragment->len; i += width, j += newwidth) { + int val = GETSAMPLE32(width, fragment->buf, i); + SETSAMPLE32(newwidth, ncp, j, val); } - exit: - PyBuffer_Release(&view); return rv; } @@ -1186,50 +1267,62 @@ gcd(int a, int b) 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(PyObject *self, PyObject *args) +audioop_ratecv_impl(PyModuleDef *module, Py_buffer *fragment, int width, + int nchannels, int inrate, int outrate, PyObject *state, + int weightA, int weightB) +/*[clinic end generated code: output=59e1787bfa49b9d9 input=aff3acdc94476191]*/ { - Py_buffer view; char *cp, *ncp; Py_ssize_t len; - int size, nchannels, inrate, outrate, weightA, weightB; int chan, d, *prev_i, *cur_i, cur_o; - PyObject *state, *samps, *str, *rv = NULL; + PyObject *samps, *str, *rv = NULL; int bytes_per_frame; - weightA = 1; - weightB = 0; - if (!PyArg_ParseTuple(args, "y*iiiiO|ii:ratecv", &view, &size, - &nchannels, &inrate, &outrate, &state, - &weightA, &weightB)) + if (!audioop_check_size(width)) return NULL; - if (!audioop_check_size(size)) - goto exit2; if (nchannels < 1) { PyErr_SetString(AudioopError, "# of channels should be >= 1"); - goto exit2; + return NULL; } - if (size > INT_MAX / nchannels) { + 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"); - goto exit2; + return NULL; } - bytes_per_frame = size * nchannels; + bytes_per_frame = width * nchannels; if (weightA < 1 || weightB < 0) { PyErr_SetString(AudioopError, "weightA should be >= 1, weightB should be >= 0"); - goto exit2; + return NULL; } - if (view.len % bytes_per_frame != 0) { + assert(fragment->len >= 0); + if (fragment->len % bytes_per_frame != 0) { PyErr_SetString(AudioopError, "not a whole number of frames"); - goto exit2; + return NULL; } if (inrate <= 0 || outrate <= 0) { PyErr_SetString(AudioopError, "sampling rate not > 0"); - goto exit2; + return NULL; } /* divide inrate and outrate by their greatest common divisor */ d = gcd(inrate, outrate); @@ -1238,12 +1331,12 @@ audioop_ratecv(PyObject *self, PyObject *args) /* divide weightA and weightB by their greatest common divisor */ d = gcd(weightA, weightB); weightA /= d; - weightA /= d; + weightB /= d; if ((size_t)nchannels > PY_SIZE_MAX/sizeof(int)) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); - goto exit2; + return NULL; } prev_i = (int *) PyMem_Malloc(nchannels * sizeof(int)); cur_i = (int *) PyMem_Malloc(nchannels * sizeof(int)); @@ -1252,7 +1345,7 @@ audioop_ratecv(PyObject *self, PyObject *args) goto exit; } - len = view.len / bytes_per_frame; /* # of frames */ + len = fragment->len / bytes_per_frame; /* # of frames */ if (state == Py_None) { d = -outrate; @@ -1289,7 +1382,7 @@ audioop_ratecv(PyObject *self, PyObject *args) case ceiling(len/inrate) * outrate. */ /* compute ceiling(len/inrate) without overflow */ - Py_ssize_t q = len > 0 ? 1 + (len - 1) / inrate : 0; + Py_ssize_t q = 1 + (len - 1) / inrate; if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame) str = NULL; else @@ -1302,7 +1395,7 @@ audioop_ratecv(PyObject *self, PyObject *args) goto exit; } ncp = PyBytes_AsString(str); - cp = view.buf; + cp = fragment->buf; for (;;) { while (d < 0) { @@ -1333,8 +1426,8 @@ audioop_ratecv(PyObject *self, PyObject *args) } for (chan = 0; chan < nchannels; chan++) { prev_i[chan] = cur_i[chan]; - cur_i[chan] = GETSAMPLE32(size, cp, 0); - cp += size; + cur_i[chan] = GETSAMPLE32(width, cp, 0); + cp += width; /* implements a simple digital filter */ cur_i[chan] = (int)( ((double)weightA * (double)cur_i[chan] + @@ -1349,8 +1442,8 @@ audioop_ratecv(PyObject *self, PyObject *args) cur_o = (int)(((double)prev_i[chan] * (double)d + (double)cur_i[chan] * (double)(outrate - d)) / (double)outrate); - SETSAMPLE32(size, ncp, 0, cur_o); - ncp += size; + SETSAMPLE32(width, ncp, 0, cur_o); + ncp += width; } d -= inrate; } @@ -1358,181 +1451,211 @@ audioop_ratecv(PyObject *self, PyObject *args) exit: PyMem_Free(prev_i); PyMem_Free(cur_i); - exit2: - PyBuffer_Release(&view); 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(PyObject *self, PyObject *args) +audioop_lin2ulaw_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=26263cc877c5e1bc input=2450d1b870b6bac2]*/ { - Py_buffer view; unsigned char *ncp; Py_ssize_t i; - int size; - PyObject *rv = NULL; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*i:lin2ulaw", - &view, &size)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) - goto exit; - - rv = PyBytes_FromStringAndSize(NULL, view.len/size); + rv = PyBytes_FromStringAndSize(NULL, fragment->len/width); if (rv == NULL) - goto exit; + return NULL; ncp = (unsigned char *)PyBytes_AsString(rv); - for (i = 0; i < view.len; i += size) { - int val = GETSAMPLE32(size, view.buf, i); + for (i = 0; i < fragment->len; i += width) { + int val = GETSAMPLE32(width, fragment->buf, i); *ncp++ = st_14linear2ulaw(val >> 18); } - exit: - PyBuffer_Release(&view); 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(PyObject *self, PyObject *args) +audioop_ulaw2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=9864cb34e3a1d876 input=45d53ddce5be7d06]*/ { - Py_buffer view; unsigned char *cp; signed char *ncp; Py_ssize_t i; - int size; - PyObject *rv = NULL; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*i:ulaw2lin", - &view, &size)) + if (!audioop_check_size(width)) return NULL; - if (!audioop_check_size(size)) - goto exit; - - if (view.len > PY_SSIZE_T_MAX/size) { + if (fragment->len > PY_SSIZE_T_MAX/width) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); - goto exit; + return NULL; } - rv = PyBytes_FromStringAndSize(NULL, view.len*size); + rv = PyBytes_FromStringAndSize(NULL, fragment->len*width); if (rv == NULL) - goto exit; + return NULL; ncp = (signed char *)PyBytes_AsString(rv); - cp = view.buf; - for (i = 0; i < view.len*size; i += size) { + cp = fragment->buf; + for (i = 0; i < fragment->len*width; i += width) { int val = st_ulaw2linear16(*cp++) << 16; - SETSAMPLE32(size, ncp, i, val); + SETSAMPLE32(width, ncp, i, val); } - exit: - PyBuffer_Release(&view); 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(PyObject *self, PyObject *args) +audioop_lin2alaw_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=d5bf14bd0fe6fdcd input=ffb1ef8bb39da945]*/ { - Py_buffer view; unsigned char *ncp; Py_ssize_t i; - int size; - PyObject *rv = NULL; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*i:lin2alaw", - &view, &size)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) - goto exit; - - rv = PyBytes_FromStringAndSize(NULL, view.len/size); + rv = PyBytes_FromStringAndSize(NULL, fragment->len/width); if (rv == NULL) - goto exit; + return NULL; ncp = (unsigned char *)PyBytes_AsString(rv); - for (i = 0; i < view.len; i += size) { - int val = GETSAMPLE32(size, view.buf, i); + for (i = 0; i < fragment->len; i += width) { + int val = GETSAMPLE32(width, fragment->buf, i); *ncp++ = st_linear2alaw(val >> 19); } - exit: - PyBuffer_Release(&view); 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(PyObject *self, PyObject *args) +audioop_alaw2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width) +/*[clinic end generated code: output=d2b604ddd036e1cd input=4140626046cd1772]*/ { - Py_buffer view; unsigned char *cp; signed char *ncp; Py_ssize_t i; - int size, val; - PyObject *rv = NULL; + int val; + PyObject *rv; - if (!PyArg_ParseTuple(args, "y*i:alaw2lin", - &view, &size)) + if (!audioop_check_size(width)) return NULL; - if (!audioop_check_size(size)) - goto exit; - - if (view.len > PY_SSIZE_T_MAX/size) { + if (fragment->len > PY_SSIZE_T_MAX/width) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); - goto exit; + return NULL; } - rv = PyBytes_FromStringAndSize(NULL, view.len*size); + rv = PyBytes_FromStringAndSize(NULL, fragment->len*width); if (rv == NULL) - goto exit; + return NULL; ncp = (signed char *)PyBytes_AsString(rv); - cp = view.buf; + cp = fragment->buf; - for (i = 0; i < view.len*size; i += size) { + for (i = 0; i < fragment->len*width; i += width) { val = st_alaw2linear16(*cp++) << 16; - SETSAMPLE32(size, ncp, i, val); + SETSAMPLE32(width, ncp, i, val); } - exit: - PyBuffer_Release(&view); 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(PyObject *self, PyObject *args) +audioop_lin2adpcm_impl(PyModuleDef *module, Py_buffer *fragment, int width, + PyObject *state) +/*[clinic end generated code: output=93f0996f592b5ce5 input=12919d549b90c90a]*/ { - Py_buffer view; signed char *ncp; Py_ssize_t i; - int size, step, valpred, delta, + int step, valpred, delta, index, sign, vpdiff, diff; - PyObject *rv = NULL, *state, *str; + PyObject *rv = NULL, *str; int outputbuffer = 0, bufferstep; - if (!PyArg_ParseTuple(args, "y*iO:lin2adpcm", - &view, &size, &state)) + if (!audioop_check_parameters(fragment->len, width)) return NULL; - if (!audioop_check_parameters(view.len, size)) - goto exit; - - str = PyBytes_FromStringAndSize(NULL, view.len/(size*2)); - if (str == NULL) - goto exit; - ncp = (signed char *)PyBytes_AsString(str); - /* Decode state, should have (value, step) */ if ( state == Py_None ) { /* First time, it seems. Set defaults */ valpred = 0; index = 0; - } else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) - goto exit; + } + else if (!PyTuple_Check(state)) { + PyErr_SetString(PyExc_TypeError, "state must be a tuple or None"); + return NULL; + } + else if (!PyArg_ParseTuple(state, "ii", &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 < view.len; i += size) { - int val = GETSAMPLE32(size, view.buf, i) >> 16; + 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) { @@ -1603,53 +1726,70 @@ audioop_lin2adpcm(PyObject *self, PyObject *args) } rv = Py_BuildValue("(O(ii))", str, valpred, index); Py_DECREF(str); - exit: - PyBuffer_Release(&view); 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(PyObject *self, PyObject *args) +audioop_adpcm2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width, + PyObject *state) +/*[clinic end generated code: output=236cf6dc2c829181 input=f5221144f5ca9ef0]*/ { - Py_buffer view; signed char *cp; signed char *ncp; Py_ssize_t i, outlen; - int size, valpred, step, delta, index, sign, vpdiff; - PyObject *rv = NULL, *str, *state; + int valpred, step, delta, index, sign, vpdiff; + PyObject *rv, *str; int inputbuffer = 0, bufferstep; - if (!PyArg_ParseTuple(args, "y*iO:adpcm2lin", - &view, &size, &state)) + if (!audioop_check_size(width)) return NULL; - if (!audioop_check_size(size)) - goto exit; - /* Decode state, should have (value, step) */ if ( state == Py_None ) { /* First time, it seems. Set defaults */ valpred = 0; index = 0; - } else if (!PyArg_ParseTuple(state, "ii", &valpred, &index)) - goto exit; + } + else if (!PyTuple_Check(state)) { + PyErr_SetString(PyExc_TypeError, "state must be a tuple or None"); + return NULL; + } + else if (!PyArg_ParseTuple(state, "ii", &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 (view.len > (PY_SSIZE_T_MAX/2)/size) { + if (fragment->len > (PY_SSIZE_T_MAX/2)/width) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); - goto exit; + return NULL; } - outlen = view.len*size*2; + outlen = fragment->len*width*2; str = PyBytes_FromStringAndSize(NULL, outlen); if (str == NULL) - goto exit; + return NULL; ncp = (signed char *)PyBytes_AsString(str); - cp = view.buf; + cp = fragment->buf; step = stepsizeTable[index]; bufferstep = 0; - for (i = 0; i < outlen; i += size) { + for (i = 0; i < outlen; i += width) { /* Step 1 - get the delta value and compute next index */ if ( bufferstep ) { delta = inputbuffer & 0xf; @@ -1694,43 +1834,43 @@ audioop_adpcm2lin(PyObject *self, PyObject *args) step = stepsizeTable[index]; /* Step 6 - Output value */ - SETSAMPLE32(size, ncp, i, valpred << 16); + SETSAMPLE32(width, ncp, i, valpred << 16); } rv = Py_BuildValue("(O(ii))", str, valpred, index); Py_DECREF(str); - exit: - PyBuffer_Release(&view); return rv; } +#include "clinic/audioop.c.h" + static PyMethodDef audioop_methods[] = { - { "max", audioop_max, METH_VARARGS }, - { "minmax", audioop_minmax, METH_VARARGS }, - { "avg", audioop_avg, METH_VARARGS }, - { "maxpp", audioop_maxpp, METH_VARARGS }, - { "avgpp", audioop_avgpp, METH_VARARGS }, - { "rms", audioop_rms, METH_VARARGS }, - { "findfit", audioop_findfit, METH_VARARGS }, - { "findmax", audioop_findmax, METH_VARARGS }, - { "findfactor", audioop_findfactor, METH_VARARGS }, - { "cross", audioop_cross, METH_VARARGS }, - { "mul", audioop_mul, METH_VARARGS }, - { "add", audioop_add, METH_VARARGS }, - { "bias", audioop_bias, METH_VARARGS }, - { "ulaw2lin", audioop_ulaw2lin, METH_VARARGS }, - { "lin2ulaw", audioop_lin2ulaw, METH_VARARGS }, - { "alaw2lin", audioop_alaw2lin, METH_VARARGS }, - { "lin2alaw", audioop_lin2alaw, METH_VARARGS }, - { "lin2lin", audioop_lin2lin, METH_VARARGS }, - { "adpcm2lin", audioop_adpcm2lin, METH_VARARGS }, - { "lin2adpcm", audioop_lin2adpcm, METH_VARARGS }, - { "tomono", audioop_tomono, METH_VARARGS }, - { "tostereo", audioop_tostereo, METH_VARARGS }, - { "getsample", audioop_getsample, METH_VARARGS }, - { "reverse", audioop_reverse, METH_VARARGS }, - { "byteswap", audioop_byteswap, METH_VARARGS }, - { "ratecv", audioop_ratecv, METH_VARARGS }, + 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 } }; diff --git a/Modules/binascii.c b/Modules/binascii.c index 0f4970141d3b..ccd81faf94ce 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -56,6 +56,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "pystrhex.h" #ifdef USE_ZLIB_CRC32 #include "zlib.h" #endif @@ -183,6 +184,26 @@ static unsigned short crctab_hqx[256] = { 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) { @@ -207,26 +228,34 @@ ascii_buffer_converter(PyObject *arg, Py_buffer *buf) if (PyObject_GetBuffer(arg, buf, PyBUF_SIMPLE) != 0) { PyErr_Format(PyExc_TypeError, "argument should be bytes, buffer or ASCII string, " - "not %R", Py_TYPE(arg)); + "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 %R", Py_TYPE(arg)); + "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 -PyDoc_STRVAR(doc_a2b_uu, "(ascii) -> bin. Decode a line of uuencoded data"); + data: ascii_buffer + / + +Decode a line of uuencoded data. +[clinic start generated code]*/ static PyObject * -binascii_a2b_uu(PyObject *self, PyObject *args) +binascii_a2b_uu_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=5779f39b0b48459f input=7cafeaf73df63d1c]*/ { - Py_buffer pascii; unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; @@ -234,10 +263,8 @@ binascii_a2b_uu(PyObject *self, PyObject *args) PyObject *rv; Py_ssize_t ascii_len, bin_len; - if ( !PyArg_ParseTuple(args, "O&:a2b_uu", ascii_buffer_converter, &pascii) ) - return NULL; - ascii_data = pascii.buf; - ascii_len = pascii.len; + ascii_data = data->buf; + ascii_len = data->len; assert(ascii_len >= 0); @@ -246,10 +273,8 @@ binascii_a2b_uu(PyObject *self, PyObject *args) ascii_len--; /* Allocate the buffer */ - if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) { - PyBuffer_Release(&pascii); + 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++ ) { @@ -269,7 +294,6 @@ binascii_a2b_uu(PyObject *self, PyObject *args) */ if ( this_ch < ' ' || this_ch > (' ' + 64)) { PyErr_SetString(Error, "Illegal char"); - PyBuffer_Release(&pascii); Py_DECREF(rv); return NULL; } @@ -298,45 +322,47 @@ binascii_a2b_uu(PyObject *self, PyObject *args) if ( this_ch != ' ' && this_ch != ' '+64 && this_ch != '\n' && this_ch != '\r' ) { PyErr_SetString(Error, "Trailing garbage"); - PyBuffer_Release(&pascii); Py_DECREF(rv); return NULL; } } - PyBuffer_Release(&pascii); return rv; } -PyDoc_STRVAR(doc_b2a_uu, "(bin) -> ascii. Uuencode line of data"); +/*[clinic input] +binascii.b2a_uu + + data: Py_buffer + / + +Uuencode line of data. +[clinic start generated code]*/ static PyObject * -binascii_b2a_uu(PyObject *self, PyObject *args) +binascii_b2a_uu_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=181021b69bb9a414 input=00fdf458ce8b465b]*/ { - Py_buffer pbin; unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; unsigned int leftchar = 0; - PyObject *rv; - Py_ssize_t bin_len; + Py_ssize_t bin_len, out_len; + _PyBytesWriter writer; - if ( !PyArg_ParseTuple(args, "y*:b2a_uu", &pbin) ) - return NULL; - bin_data = pbin.buf; - bin_len = pbin.len; + _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 */ PyErr_SetString(Error, "At most 45 bytes at once"); - PyBuffer_Release(&pbin); return NULL; } /* We're lazy and allocate to much (fixed up later) */ - if ( (rv=PyBytes_FromStringAndSize(NULL, 2 + (bin_len+2)/3*4)) == NULL ) { - PyBuffer_Release(&pbin); + out_len = 2 + (bin_len + 2) / 3 * 4; + ascii_data = _PyBytesWriter_Alloc(&writer, out_len); + if (ascii_data == NULL) return NULL; - } - ascii_data = (unsigned char *)PyBytes_AS_STRING(rv); /* Store the length */ *ascii_data++ = ' ' + (bin_len & 077); @@ -358,13 +384,7 @@ binascii_b2a_uu(PyObject *self, PyObject *args) } *ascii_data++ = '\n'; /* Append a courtesy newline */ - if (_PyBytes_Resize(&rv, - (ascii_data - - (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { - Py_CLEAR(rv); - } - PyBuffer_Release(&pbin); - return rv; + return _PyBytesWriter_Finish(&writer, ascii_data); } @@ -393,41 +413,43 @@ binascii_find_valid(unsigned char *s, Py_ssize_t slen, int num) return ret; } -PyDoc_STRVAR(doc_a2b_base64, "(ascii) -> bin. Decode a line of base64 data"); +/*[clinic input] +binascii.a2b_base64 + + data: ascii_buffer + / + +Decode a line of base64 data. +[clinic start generated code]*/ static PyObject * -binascii_a2b_base64(PyObject *self, PyObject *args) +binascii_a2b_base64_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=3e351b702bed56d2 input=5872acf6e1cac243]*/ { - Py_buffer pascii; unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; unsigned int leftchar = 0; - PyObject *rv; Py_ssize_t ascii_len, bin_len; int quad_pos = 0; + _PyBytesWriter writer; - if ( !PyArg_ParseTuple(args, "O&:a2b_base64", ascii_buffer_converter, &pascii) ) - return NULL; - ascii_data = pascii.buf; - ascii_len = pascii.len; + ascii_data = data->buf; + ascii_len = data->len; assert(ascii_len >= 0); - if (ascii_len > PY_SSIZE_T_MAX - 3) { - PyBuffer_Release(&pascii); + 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 */ - if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) { - PyBuffer_Release(&pascii); + bin_data = _PyBytesWriter_Alloc(&writer, bin_len); + if (bin_data == NULL) return NULL; - } - bin_data = (unsigned char *)PyBytes_AS_STRING(rv); - bin_len = 0; for( ; ascii_len > 0; ascii_len--, ascii_data++) { this_ch = *ascii_data; @@ -472,69 +494,61 @@ binascii_a2b_base64(PyObject *self, PyObject *args) if ( leftbits >= 8 ) { leftbits -= 8; *bin_data++ = (leftchar >> leftbits) & 0xff; - bin_len++; leftchar &= ((1 << leftbits) - 1); } } if (leftbits != 0) { - PyBuffer_Release(&pascii); PyErr_SetString(Error, "Incorrect padding"); - Py_DECREF(rv); + _PyBytesWriter_Dealloc(&writer); return NULL; } - /* And set string size correctly. If the result string is empty - ** (because the input was all invalid) return the shared empty - ** string instead; _PyBytes_Resize() won't do this for us. - */ - if (bin_len > 0) { - if (_PyBytes_Resize(&rv, bin_len) < 0) { - Py_CLEAR(rv); - } - } - else { - Py_DECREF(rv); - rv = PyBytes_FromStringAndSize("", 0); - } - PyBuffer_Release(&pascii); - return rv; + return _PyBytesWriter_Finish(&writer, bin_data); } -PyDoc_STRVAR(doc_b2a_base64, "(bin) -> ascii. Base64-code line of data"); + +/*[clinic input] +binascii.b2a_base64 + + data: Py_buffer + * + newline: int(c_default="1") = True + +Base64-code line of data. +[clinic start generated code]*/ static PyObject * -binascii_b2a_base64(PyObject *self, PyObject *args) +binascii_b2a_base64_impl(PyModuleDef *module, Py_buffer *data, int newline) +/*[clinic end generated code: output=19e1dd719a890b50 input=7b2ea6fa38d8924c]*/ { - Py_buffer pbuf; unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; unsigned int leftchar = 0; - PyObject *rv; - Py_ssize_t bin_len; + Py_ssize_t bin_len, out_len; + _PyBytesWriter writer; - if ( !PyArg_ParseTuple(args, "y*:b2a_base64", &pbuf) ) - return NULL; - bin_data = pbuf.buf; - bin_len = pbuf.len; + bin_data = data->buf; + bin_len = data->len; + _PyBytesWriter_Init(&writer); assert(bin_len >= 0); if ( bin_len > BASE64_MAXBIN ) { PyErr_SetString(Error, "Too much data for base64 line"); - PyBuffer_Release(&pbuf); return NULL; } /* We're lazy and allocate too much (fixed up later). - "+3" leaves room for up to two pad characters and a trailing - newline. Note that 'b' gets encoded as 'Yg==\n' (1 in, 5 out). */ - if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len*2 + 3)) == NULL ) { - PyBuffer_Release(&pbuf); + "+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; - } - ascii_data = (unsigned char *)PyBytes_AS_STRING(rv); for( ; bin_len > 0 ; bin_len--, bin_data++ ) { /* Shift the data into our buffer */ @@ -556,51 +570,49 @@ binascii_b2a_base64(PyObject *self, PyObject *args) *ascii_data++ = table_b2a_base64[(leftchar&0xf) << 2]; *ascii_data++ = BASE64_PAD; } - *ascii_data++ = '\n'; /* Append a courtesy newline */ + if (newline) + *ascii_data++ = '\n'; /* Append a courtesy newline */ - if (_PyBytes_Resize(&rv, - (ascii_data - - (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { - Py_CLEAR(rv); - } - PyBuffer_Release(&pbuf); - return rv; + return _PyBytesWriter_Finish(&writer, ascii_data); } -PyDoc_STRVAR(doc_a2b_hqx, "ascii -> bin, done. Decode .hqx coding"); +/*[clinic input] +binascii.a2b_hqx + + data: ascii_buffer + / + +Decode .hqx coding. +[clinic start generated code]*/ static PyObject * -binascii_a2b_hqx(PyObject *self, PyObject *args) +binascii_a2b_hqx_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=60bcdbbd28b105cd input=0d914c680e0eed55]*/ { - Py_buffer pascii; unsigned char *ascii_data, *bin_data; int leftbits = 0; unsigned char this_ch; unsigned int leftchar = 0; - PyObject *rv; + PyObject *res; Py_ssize_t len; int done = 0; + _PyBytesWriter writer; - if ( !PyArg_ParseTuple(args, "O&:a2b_hqx", ascii_buffer_converter, &pascii) ) - return NULL; - ascii_data = pascii.buf; - len = pascii.len; + ascii_data = data->buf; + len = data->len; + _PyBytesWriter_Init(&writer); assert(len >= 0); - if (len > PY_SSIZE_T_MAX - 2) { - PyBuffer_Release(&pascii); + 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. */ - if ( (rv=PyBytes_FromStringAndSize(NULL, len+2)) == NULL ) { - PyBuffer_Release(&pascii); + bin_data = _PyBytesWriter_Alloc(&writer, len + 2); + if (bin_data == NULL) return NULL; - } - bin_data = (unsigned char *)PyBytes_AS_STRING(rv); for( ; len > 0 ; len--, ascii_data++ ) { /* Get the byte and look it up */ @@ -609,8 +621,7 @@ binascii_a2b_hqx(PyObject *self, PyObject *args) continue; if ( this_ch == FAIL ) { PyErr_SetString(Error, "Illegal char"); - PyBuffer_Release(&pascii); - Py_DECREF(rv); + _PyBytesWriter_Dealloc(&writer); return NULL; } if ( this_ch == DONE ) { @@ -632,55 +643,48 @@ binascii_a2b_hqx(PyObject *self, PyObject *args) if ( leftbits && !done ) { PyErr_SetString(Incomplete, "String has incomplete number of bytes"); - PyBuffer_Release(&pascii); - Py_DECREF(rv); + _PyBytesWriter_Dealloc(&writer); return NULL; } - if (_PyBytes_Resize(&rv, - (bin_data - - (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { - Py_CLEAR(rv); - } - if (rv) { - PyObject *rrv = Py_BuildValue("Oi", rv, done); - PyBuffer_Release(&pascii); - Py_DECREF(rv); - return rrv; - } - PyBuffer_Release(&pascii); - return NULL; + res = _PyBytesWriter_Finish(&writer, bin_data); + if (res == NULL) + return NULL; + return Py_BuildValue("Ni", res, done); } -PyDoc_STRVAR(doc_rlecode_hqx, "Binhex RLE-code binary data"); + +/*[clinic input] +binascii.rlecode_hqx + + data: Py_buffer + / + +Binhex RLE-code binary data. +[clinic start generated code]*/ static PyObject * -binascii_rlecode_hqx(PyObject *self, PyObject *args) +binascii_rlecode_hqx_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=0905da344dbf0648 input=e1f1712447a82b09]*/ { - Py_buffer pbuf; unsigned char *in_data, *out_data; - PyObject *rv; unsigned char ch; Py_ssize_t in, inend, len; + _PyBytesWriter writer; - if ( !PyArg_ParseTuple(args, "y*:rlecode_hqx", &pbuf) ) - return NULL; - in_data = pbuf.buf; - len = pbuf.len; + _PyBytesWriter_Init(&writer); + in_data = data->buf; + len = data->len; assert(len >= 0); - if (len > PY_SSIZE_T_MAX / 2 - 2) { - PyBuffer_Release(&pbuf); + if (len > PY_SSIZE_T_MAX / 2 - 2) return PyErr_NoMemory(); - } /* Worst case: output is twice as big as input (fixed later) */ - if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) { - PyBuffer_Release(&pbuf); + out_data = _PyBytesWriter_Alloc(&writer, len * 2 + 2); + if (out_data == NULL) return NULL; - } - out_data = (unsigned char *)PyBytes_AS_STRING(rv); for( in=0; inbuf; + len = data->len; + _PyBytesWriter_Init(&writer); assert(len >= 0); - if (len > PY_SSIZE_T_MAX / 2 - 2) { - PyBuffer_Release(&pbin); + if (len > PY_SSIZE_T_MAX / 2 - 2) return PyErr_NoMemory(); - } /* Allocate a buffer that is at least large enough */ - if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) { - PyBuffer_Release(&pbin); + ascii_data = _PyBytesWriter_Alloc(&writer, len * 2 + 2); + if (ascii_data == NULL) return NULL; - } - ascii_data = (unsigned char *)PyBytes_AS_STRING(rv); for( ; len > 0 ; len--, bin_data++ ) { /* Shift into our buffer, and output any 6bits ready */ @@ -762,101 +764,84 @@ binascii_b2a_hqx(PyObject *self, PyObject *args) leftchar <<= (6-leftbits); *ascii_data++ = table_b2a_hqx[leftchar & 0x3f]; } - if (_PyBytes_Resize(&rv, - (ascii_data - - (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { - Py_CLEAR(rv); - } - PyBuffer_Release(&pbin); - return rv; + + return _PyBytesWriter_Finish(&writer, ascii_data); } -PyDoc_STRVAR(doc_rledecode_hqx, "Decode hexbin RLE-coded string"); + +/*[clinic input] +binascii.rledecode_hqx + + data: Py_buffer + / + +Decode hexbin RLE-coded string. +[clinic start generated code]*/ static PyObject * -binascii_rledecode_hqx(PyObject *self, PyObject *args) +binascii_rledecode_hqx_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=f7afd89b789946ab input=54cdd49fc014402c]*/ { - Py_buffer pin; unsigned char *in_data, *out_data; unsigned char in_byte, in_repeat; - PyObject *rv; - Py_ssize_t in_len, out_len, out_len_left; + Py_ssize_t in_len; + _PyBytesWriter writer; - if ( !PyArg_ParseTuple(args, "y*:rledecode_hqx", &pin) ) - return NULL; - in_data = pin.buf; - in_len = pin.len; + in_data = data->buf; + in_len = data->len; + _PyBytesWriter_Init(&writer); assert(in_len >= 0); /* Empty string is a special case */ - if ( in_len == 0 ) { - PyBuffer_Release(&pin); + if ( in_len == 0 ) return PyBytes_FromStringAndSize("", 0); - } - else if (in_len > PY_SSIZE_T_MAX / 2) { - PyBuffer_Release(&pin); + else if (in_len > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); - } /* Allocate a buffer of reasonable size. Resized when needed */ - out_len = in_len*2; - if ( (rv=PyBytes_FromStringAndSize(NULL, out_len)) == NULL ) { - PyBuffer_Release(&pin); + out_data = _PyBytesWriter_Alloc(&writer, in_len); + if (out_data == NULL) return NULL; - } - out_len_left = out_len; - out_data = (unsigned char *)PyBytes_AS_STRING(rv); + + /* 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 ) { \ - PyErr_SetString(Incomplete, ""); \ - Py_DECREF(rv); \ - PyBuffer_Release(&pin); \ - return NULL; \ - } \ - b = *in_data++; \ - } while(0) - -#define OUTBYTE(b) \ - do { \ - if ( --out_len_left < 0 ) { \ - if ( out_len > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); \ - if (_PyBytes_Resize(&rv, 2*out_len) < 0) \ - { Py_XDECREF(rv); PyBuffer_Release(&pin); return NULL; } \ - out_data = (unsigned char *)PyBytes_AS_STRING(rv) \ - + out_len; \ - out_len_left = out_len-1; \ - out_len = out_len * 2; \ - } \ - *out_data++ = b; \ +#define INBYTE(b) \ + do { \ + if ( --in_len < 0 ) { \ + PyErr_SetString(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); + /* + ** 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: + substract 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. */ PyErr_SetString(Error, "Orphaned RLE code at start"); - PyBuffer_Release(&pin); - Py_DECREF(rv); - return NULL; + goto error; } - OUTBYTE(RUNCHAR); + *out_data++ = RUNCHAR; } else { - OUTBYTE(in_byte); + *out_data++ = in_byte; } while( in_len > 0 ) { @@ -864,76 +849,71 @@ binascii_rledecode_hqx(PyObject *self, PyObject *args) if (in_byte == RUNCHAR) { INBYTE(in_repeat); + /* only 1 byte will be written, but 2 bytes were preallocated: + substract 1 byte to prevent overallocation */ + writer.min_size--; + if ( in_repeat == 0 ) { /* Just an escaped RUNCHAR value */ - OUTBYTE(RUNCHAR); + *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 ) - OUTBYTE(in_byte); + *out_data++ = in_byte; } } else { /* Normal byte */ - OUTBYTE(in_byte); + *out_data++ = in_byte; } } - if (_PyBytes_Resize(&rv, - (out_data - - (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { - Py_CLEAR(rv); - } - PyBuffer_Release(&pin); - return rv; + return _PyBytesWriter_Finish(&writer, out_data); + +error: + _PyBytesWriter_Dealloc(&writer); + return NULL; } -PyDoc_STRVAR(doc_crc_hqx, -"(data, oldcrc) -> newcrc. Compute hqx CRC incrementally"); -static PyObject * -binascii_crc_hqx(PyObject *self, PyObject *args) +/*[clinic input] +binascii.crc_hqx -> unsigned_int + + data: Py_buffer + crc: unsigned_int(bitwise=True) + / + +Compute hqx CRC incrementally. +[clinic start generated code]*/ + +static unsigned int +binascii_crc_hqx_impl(PyModuleDef *module, Py_buffer *data, unsigned int crc) +/*[clinic end generated code: output=167c2dac62625717 input=add8c53712ccceda]*/ { - Py_buffer pin; unsigned char *bin_data; - unsigned int crc; Py_ssize_t len; - if ( !PyArg_ParseTuple(args, "y*i:crc_hqx", &pin, &crc) ) - return NULL; - bin_data = pin.buf; - len = pin.len; + crc &= 0xffff; + bin_data = data->buf; + len = data->len; while(len-- > 0) { - crc=((crc<<8)&0xff00)^crctab_hqx[((crc>>8)&0xff)^*bin_data++]; + crc = ((crc<<8)&0xff00) ^ crctab_hqx[(crc>>8)^*bin_data++]; } - PyBuffer_Release(&pin); - return Py_BuildValue("i", crc); + return crc; } -PyDoc_STRVAR(doc_crc32, -"(data, oldcrc = 0) -> newcrc. Compute CRC-32 incrementally"); - -#ifdef USE_ZLIB_CRC32 -/* This was taken from zlibmodule.c PyZlib_crc32 (but is PY_SSIZE_T_CLEAN) */ -static PyObject * -binascii_crc32(PyObject *self, PyObject *args) -{ - unsigned int crc32val = 0; /* crc32(0L, Z_NULL, 0) */ - Py_buffer pbuf; - Byte *buf; - Py_ssize_t len; - int signed_val; - - if (!PyArg_ParseTuple(args, "y*|I:crc32", &pbuf, &crc32val)) - return NULL; - buf = (Byte*)pbuf.buf; - len = pbuf.len; - signed_val = crc32(crc32val, buf, len); - PyBuffer_Release(&pbuf); - return PyLong_FromUnsignedLong(signed_val & 0xffffffffU); -} -#else /* USE_ZLIB_CRC32 */ +#ifndef USE_ZLIB_CRC32 /* Crc - 32 BIT ANSI X3.66 CRC checksum files Also known as: ISO 3307 **********************************************************************| @@ -1051,20 +1031,42 @@ static unsigned int crc_32_tab[256] = { 0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, 0x2d02ef8dU }; +#endif /* USE_ZLIB_CRC32 */ -static PyObject * -binascii_crc32(PyObject *self, PyObject *args) +/*[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(PyModuleDef *module, Py_buffer *data, unsigned int crc) +/*[clinic end generated code: output=620a961643393c4f input=bbe340bc99d25aa8]*/ + +#ifdef USE_ZLIB_CRC32 +/* This was taken from zlibmodule.c PyZlib_crc32 (but is PY_SSIZE_T_CLEAN) */ +{ + 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 */ - Py_buffer pbin; unsigned char *bin_data; - unsigned int crc = 0; /* initial value of CRC */ Py_ssize_t len; unsigned int result; - if ( !PyArg_ParseTuple(args, "y*|I:crc32", &pbin, &crc) ) - return NULL; - bin_data = pbin.buf; - len = pbin.len; + bin_data = data->buf; + len = data->len; crc = ~ crc; while (len-- > 0) { @@ -1073,59 +1075,44 @@ binascii_crc32(PyObject *self, PyObject *args) } result = (crc ^ 0xFFFFFFFF); - PyBuffer_Release(&pbin); - return PyLong_FromUnsignedLong(result & 0xffffffff); + return result & 0xffffffff; } #endif /* USE_ZLIB_CRC32 */ +/*[clinic input] +binascii.b2a_hex + + data: Py_buffer + / + +Hexadecimal representation of binary data. + +The return value is a bytes object. This function is also +available as "hexlify()". +[clinic start generated code]*/ static PyObject * -binascii_hexlify(PyObject *self, PyObject *args) +binascii_b2a_hex_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=179318922c2f8fda input=96423cfa299ff3b1]*/ { - Py_buffer parg; - char* argbuf; - Py_ssize_t arglen; - PyObject *retval; - char* retbuf; - Py_ssize_t i, j; + return _Py_strhex_bytes((const char *)data->buf, data->len); +} - if (!PyArg_ParseTuple(args, "y*:b2a_hex", &parg)) - return NULL; - argbuf = parg.buf; - arglen = parg.len; +/*[clinic input] +binascii.hexlify = binascii.b2a_hex - assert(arglen >= 0); - if (arglen > PY_SSIZE_T_MAX / 2) { - PyBuffer_Release(&parg); - return PyErr_NoMemory(); - } +Hexadecimal representation of binary data. - retval = PyBytes_FromStringAndSize(NULL, arglen*2); - if (!retval) { - PyBuffer_Release(&parg); - return NULL; - } - retbuf = PyBytes_AS_STRING(retval); +The return value is a bytes object. +[clinic start generated code]*/ - /* make hex version of string, taken from shamodule.c */ - for (i=j=0; i < arglen; i++) { - unsigned char c; - c = (argbuf[i] >> 4) & 0xf; - retbuf[j++] = Py_hexdigits[c]; - c = argbuf[i] & 0xf; - retbuf[j++] = Py_hexdigits[c]; - } - PyBuffer_Release(&parg); - return retval; +static PyObject * +binascii_hexlify_impl(PyModuleDef *module, Py_buffer *data) +/*[clinic end generated code: output=6098440091fb61dc input=2e3afae7f083f061]*/ +{ + return _Py_strhex_bytes((const char *)data->buf, data->len); } -PyDoc_STRVAR(doc_hexlify, -"b2a_hex(data) -> s; Hexadecimal representation of binary data.\n\ -\n\ -The return value is a bytes object. This function is also\n\ -available as \"hexlify()\"."); - - static int to_int(int c) { @@ -1141,20 +1128,30 @@ to_int(int c) } +/*[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_unhexlify(PyObject *self, PyObject *args) +binascii_a2b_hex_impl(PyModuleDef *module, Py_buffer *hexstr) +/*[clinic end generated code: output=d61da452b5c6d290 input=9e1e7f2f94db24fd]*/ { - Py_buffer parg; char* argbuf; Py_ssize_t arglen; PyObject *retval; char* retbuf; Py_ssize_t i, j; - if (!PyArg_ParseTuple(args, "O&:a2b_hex", ascii_buffer_converter, &parg)) - return NULL; - argbuf = parg.buf; - arglen = parg.len; + argbuf = hexstr->buf; + arglen = hexstr->len; assert(arglen >= 0); @@ -1163,16 +1160,13 @@ binascii_unhexlify(PyObject *self, PyObject *args) * raise an exception. */ if (arglen % 2) { - PyBuffer_Release(&parg); PyErr_SetString(Error, "Odd-length string"); return NULL; } retval = PyBytes_FromStringAndSize(NULL, (arglen/2)); - if (!retval) { - PyBuffer_Release(&parg); + if (!retval) return NULL; - } retbuf = PyBytes_AS_STRING(retval); for (i=j=0; i < arglen; i += 2) { @@ -1185,20 +1179,27 @@ binascii_unhexlify(PyObject *self, PyObject *args) } retbuf[j++] = (top << 4) + bot; } - PyBuffer_Release(&parg); return retval; finally: - PyBuffer_Release(&parg); Py_DECREF(retval); return NULL; } -PyDoc_STRVAR(doc_unhexlify, -"a2b_hex(hexstr) -> s; 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()\""); +/*[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(PyModuleDef *module, Py_buffer *hexstr) +/*[clinic end generated code: output=17cec7544499803e input=dd8c012725f462da]*/ +{ + return binascii_a2b_hex_impl(module, hexstr); +} static int table_hex[128] = { -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, @@ -1215,25 +1216,28 @@ static int table_hex[128] = { #define MAXLINESIZE 76 -PyDoc_STRVAR(doc_a2b_qp, "Decode a string of qp-encoded data"); -static PyObject* -binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs) +/*[clinic input] +binascii.a2b_qp + + data: ascii_buffer + header: int(c_default="0") = False + +Decode a string of qp-encoded data. +[clinic start generated code]*/ + +static PyObject * +binascii_a2b_qp_impl(PyModuleDef *module, Py_buffer *data, int header) +/*[clinic end generated code: output=a44ef88270352114 input=5187a0d3d8e54f3b]*/ { Py_ssize_t in, out; char ch; - Py_buffer pdata; - unsigned char *data, *odata; + unsigned char *ascii_data, *odata; Py_ssize_t datalen = 0; PyObject *rv; - static char *kwlist[] = {"data", "header", NULL}; - int header = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i:a2b_qp", kwlist, - ascii_buffer_converter, &pdata, &header)) - return NULL; - data = pdata.buf; - datalen = pdata.len; + 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 @@ -1241,7 +1245,6 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs) */ odata = (unsigned char *) PyMem_Malloc(datalen); if (odata == NULL) { - PyBuffer_Release(&pdata); PyErr_NoMemory(); return NULL; } @@ -1249,31 +1252,31 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs) in = out = 0; while (in < datalen) { - if (data[in] == '=') { + if (ascii_data[in] == '=') { in++; if (in >= datalen) break; /* Soft line breaks */ - if ((data[in] == '\n') || (data[in] == '\r')) { - if (data[in] != '\n') { - while (in < datalen && data[in] != '\n') in++; + 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 (data[in] == '=') { + else if (ascii_data[in] == '=') { /* broken case from broken python qp */ odata[out++] = '='; in++; } - else if (((data[in] >= 'A' && data[in] <= 'F') || - (data[in] >= 'a' && data[in] <= 'f') || - (data[in] >= '0' && data[in] <= '9')) && - ((data[in+1] >= 'A' && data[in+1] <= 'F') || - (data[in+1] >= 'a' && data[in+1] <= 'f') || - (data[in+1] >= '0' && data[in+1] <= '9'))) { + else if (((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 = hexval(data[in]) << 4; + ch = hexval(ascii_data[in]) << 4; in++; - ch |= hexval(data[in]); + ch |= hexval(ascii_data[in]); in++; odata[out++] = ch; } @@ -1281,22 +1284,20 @@ binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs) odata[out++] = '='; } } - else if (header && data[in] == '_') { + else if (header && ascii_data[in] == '_') { odata[out++] = ' '; in++; } else { - odata[out] = data[in]; + odata[out] = ascii_data[in]; in++; out++; } } if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) { - PyBuffer_Release(&pdata); PyMem_Free(odata); return NULL; } - PyBuffer_Release(&pdata); PyMem_Free(odata); return rv; } @@ -1312,62 +1313,63 @@ to_hex (unsigned char ch, unsigned char *s) return 0; } -PyDoc_STRVAR(doc_b2a_qp, -"b2a_qp(data, quotetabs=0, istext=1, header=0) -> s; \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) are \n\ -both encoded. When quotetabs is set, space and tabs are encoded."); - /* 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 */ -static PyObject* -binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) + +/*[clinic input] +binascii.b2a_qp + + data: Py_buffer + quotetabs: int(c_default="0") = False + istext: int(c_default="1") = True + header: int(c_default="0") = 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(PyModuleDef *module, Py_buffer *data, int quotetabs, + int istext, int header) +/*[clinic end generated code: output=a87ca9ccb94e2a9f input=7f2a9aaa008e92b2]*/ { Py_ssize_t in, out; - Py_buffer pdata; - unsigned char *data, *odata; + unsigned char *databuf, *odata; Py_ssize_t datalen = 0, odatalen = 0; PyObject *rv; unsigned int linelen = 0; - static char *kwlist[] = {"data", "quotetabs", "istext", - "header", NULL}; - int istext = 1; - int quotetabs = 0; - int header = 0; unsigned char ch; int crlf = 0; unsigned char *p; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|iii", kwlist, &pdata, - "etabs, &istext, &header)) - return NULL; - data = pdata.buf; - datalen = pdata.len; + 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 = (unsigned char *) memchr(data, '\n', datalen); - if ((p != NULL) && (p > data) && (*(p-1) == '\r')) + p = (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) { - if ((data[in] > 126) || - (data[in] == '=') || - (header && data[in] == '_') || - ((data[in] == '.') && (linelen == 0) && - (data[in+1] == '\n' || data[in+1] == '\r' || data[in+1] == 0)) || - (!istext && ((data[in] == '\r') || (data[in] == '\n'))) || - ((data[in] == '\t' || data[in] == ' ') && (in + 1 == datalen)) || - ((data[in] < 33) && - (data[in] != '\r') && (data[in] != '\n') && - (quotetabs || ((data[in] != '\t') && (data[in] != ' '))))) + if ((databuf[in] > 126) || + (databuf[in] == '=') || + (header && databuf[in] == '_') || + ((databuf[in] == '.') && (linelen == 0) && + (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; @@ -1382,26 +1384,26 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) } else { if (istext && - ((data[in] == '\n') || - ((in+1 < datalen) && (data[in] == '\r') && - (data[in+1] == '\n')))) + ((databuf[in] == '\n') || + ((in+1 < datalen) && (databuf[in] == '\r') && + (databuf[in+1] == '\n')))) { linelen = 0; /* Protect against whitespace on end of line */ - if (in && ((data[in-1] == ' ') || (data[in-1] == '\t'))) + if (in && ((databuf[in-1] == ' ') || (databuf[in-1] == '\t'))) odatalen += 2; if (crlf) odatalen += 2; else odatalen += 1; - if (data[in] == '\r') + if (databuf[in] == '\r') in += 2; else in++; } else { if ((in + 1 != datalen) && - (data[in+1] != '\n') && + (databuf[in+1] != '\n') && (linelen + 1) >= MAXLINESIZE) { linelen = 0; if (crlf) @@ -1422,7 +1424,6 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) */ odata = (unsigned char *) PyMem_Malloc(odatalen); if (odata == NULL) { - PyBuffer_Release(&pdata); PyErr_NoMemory(); return NULL; } @@ -1430,17 +1431,17 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) in = out = linelen = 0; while (in < datalen) { - if ((data[in] > 126) || - (data[in] == '=') || - (header && data[in] == '_') || - ((data[in] == '.') && (linelen == 0) && - (data[in+1] == '\n' || data[in+1] == '\r' || data[in+1] == 0)) || - (!istext && ((data[in] == '\r') || (data[in] == '\n'))) || - ((data[in] == '\t' || data[in] == ' ') && (in + 1 == datalen)) || - ((data[in] < 33) && - (data[in] != '\r') && (data[in] != '\n') && + if ((databuf[in] > 126) || + (databuf[in] == '=') || + (header && databuf[in] == '_') || + ((databuf[in] == '.') && (linelen == 0) && + (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 || - (!quotetabs && ((data[in] != '\t') && (data[in] != ' ')))))) + (!quotetabs && ((databuf[in] != '\t') && (databuf[in] != ' ')))))) { if ((linelen + 3 )>= MAXLINESIZE) { odata[out++] = '='; @@ -1449,16 +1450,16 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) linelen = 0; } odata[out++] = '='; - to_hex(data[in], &odata[out]); + to_hex(databuf[in], &odata[out]); out += 2; in++; linelen += 3; } else { if (istext && - ((data[in] == '\n') || - ((in+1 < datalen) && (data[in] == '\r') && - (data[in+1] == '\n')))) + ((databuf[in] == '\n') || + ((in+1 < datalen) && (databuf[in] == '\r') && + (databuf[in+1] == '\n')))) { linelen = 0; /* Protect against whitespace on end of line */ @@ -1471,14 +1472,14 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) if (crlf) odata[out++] = '\r'; odata[out++] = '\n'; - if (data[in] == '\r') + if (databuf[in] == '\r') in += 2; else in++; } else { if ((in + 1 != datalen) && - (data[in+1] != '\n') && + (databuf[in+1] != '\n') && (linelen + 1) >= MAXLINESIZE) { odata[out++] = '='; if (crlf) odata[out++] = '\r'; @@ -1486,22 +1487,20 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) linelen = 0; } linelen++; - if (header && data[in] == ' ') { + if (header && databuf[in] == ' ') { odata[out++] = '_'; in++; } else { - odata[out++] = data[in++]; + odata[out++] = databuf[in++]; } } } } if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) { - PyBuffer_Release(&pdata); PyMem_Free(odata); return NULL; } - PyBuffer_Release(&pdata); PyMem_Free(odata); return rv; } @@ -1509,25 +1508,22 @@ binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) /* List of functions defined in the module */ static struct PyMethodDef binascii_module_methods[] = { - {"a2b_uu", binascii_a2b_uu, METH_VARARGS, doc_a2b_uu}, - {"b2a_uu", binascii_b2a_uu, METH_VARARGS, doc_b2a_uu}, - {"a2b_base64", binascii_a2b_base64, METH_VARARGS, doc_a2b_base64}, - {"b2a_base64", binascii_b2a_base64, METH_VARARGS, doc_b2a_base64}, - {"a2b_hqx", binascii_a2b_hqx, METH_VARARGS, doc_a2b_hqx}, - {"b2a_hqx", binascii_b2a_hqx, METH_VARARGS, doc_b2a_hqx}, - {"b2a_hex", binascii_hexlify, METH_VARARGS, doc_hexlify}, - {"a2b_hex", binascii_unhexlify, METH_VARARGS, doc_unhexlify}, - {"hexlify", binascii_hexlify, METH_VARARGS, doc_hexlify}, - {"unhexlify", binascii_unhexlify, METH_VARARGS, doc_unhexlify}, - {"rlecode_hqx", binascii_rlecode_hqx, METH_VARARGS, doc_rlecode_hqx}, - {"rledecode_hqx", binascii_rledecode_hqx, METH_VARARGS, - doc_rledecode_hqx}, - {"crc_hqx", binascii_crc_hqx, METH_VARARGS, doc_crc_hqx}, - {"crc32", binascii_crc32, METH_VARARGS, doc_crc32}, - {"a2b_qp", (PyCFunction)binascii_a2b_qp, METH_VARARGS | METH_KEYWORDS, - doc_a2b_qp}, - {"b2a_qp", (PyCFunction)binascii_b2a_qp, METH_VARARGS | METH_KEYWORDS, - doc_b2a_qp}, + 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 */ }; diff --git a/Modules/cjkcodecs/_codecs_cn.c b/Modules/cjkcodecs/_codecs_cn.c index 013c3fb6b77b..1a070f2f3932 100644 --- a/Modules/cjkcodecs/_codecs_cn.c +++ b/Modules/cjkcodecs/_codecs_cn.c @@ -15,7 +15,7 @@ #undef hz #endif -/* GBK and GB2312 map differently in few codepoints that are listed below: +/* 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 diff --git a/Modules/cjkcodecs/_codecs_hk.c b/Modules/cjkcodecs/_codecs_hk.c index b7a7ebd6e12d..4f21569a0ce7 100644 --- a/Modules/cjkcodecs/_codecs_hk.c +++ b/Modules/cjkcodecs/_codecs_hk.c @@ -171,7 +171,7 @@ DECODER(big5hkscs) default: return 1; } - NEXT_IN(2); /* all decoded codepoints are pairs, above. */ + NEXT_IN(2); /* all decoded code points are pairs, above. */ } return 0; diff --git a/Modules/cjkcodecs/_codecs_iso2022.c b/Modules/cjkcodecs/_codecs_iso2022.c index 5c401aaf8e93..1ce4218f3089 100644 --- a/Modules/cjkcodecs/_codecs_iso2022.c +++ b/Modules/cjkcodecs/_codecs_iso2022.c @@ -292,7 +292,7 @@ iso2022processesc(const void *config, MultibyteCodec_State *state, const unsigned char **inbuf, Py_ssize_t *inleft) { unsigned char charset, designation; - Py_ssize_t i, esclen; + Py_ssize_t i, esclen = 0; for (i = 1;i < MAX_ESCSEQLEN;i++) { if (i >= *inleft) @@ -307,10 +307,9 @@ iso2022processesc(const void *config, MultibyteCodec_State *state, } } - if (i >= MAX_ESCSEQLEN) - return 1; /* unterminated escape sequence */ - switch (esclen) { + case 0: + return 1; /* unterminated escape sequence */ case 3: if (INBYTE2 == '$') { charset = INBYTE3 | CHARSET_DBCS; diff --git a/Modules/cjkcodecs/_codecs_kr.c b/Modules/cjkcodecs/_codecs_kr.c index 1ad41a7851f1..6d6acb5c4be4 100644 --- a/Modules/cjkcodecs/_codecs_kr.c +++ b/Modules/cjkcodecs/_codecs_kr.c @@ -69,7 +69,7 @@ ENCODER(euc_kr) OUTBYTE1(EUCKR_JAMO_FIRSTBYTE); OUTBYTE2(EUCKR_JAMO_FILLER); - /* All codepoints in CP949 extension are in unicode + /* All code points in CP949 extension are in unicode * Hangul Syllable area. */ assert(0xac00 <= c && c <= 0xd7a3); c -= 0xac00; diff --git a/Modules/cjkcodecs/cjkcodecs.h b/Modules/cjkcodecs/cjkcodecs.h index 25bab41cf3f8..23642df9aff9 100644 --- a/Modules/cjkcodecs/cjkcodecs.h +++ b/Modules/cjkcodecs/cjkcodecs.h @@ -12,10 +12,10 @@ #include "multibytecodec.h" -/* a unicode "undefined" codepoint */ +/* a unicode "undefined" code point */ #define UNIINV 0xFFFE -/* internal-use DBCS codepoints which aren't used by any charsets */ +/* internal-use DBCS code points which aren't used by any charsets */ #define NOCHAR 0xFFFF #define MULTIC 0xFFFE #define DBCINV 0xFFFD @@ -362,7 +362,7 @@ importmap(const char *modname, const char *symbol, if (mod == NULL) return -1; - o = PyObject_GetAttrString(mod, (char*)symbol); + o = PyObject_GetAttrString(mod, symbol); if (o == NULL) goto errorexit; else if (!PyCapsule_IsValid(o, PyMultibyteCodec_CAPSULE_NAME)) { @@ -401,7 +401,7 @@ importmap(const char *modname, const char *symbol, NULL, \ NULL \ }; \ - PyObject* \ + PyMODINIT_FUNC \ PyInit__codecs_##loc(void) \ { \ PyObject *m = PyModule_Create(&__module); \ diff --git a/Modules/cjkcodecs/clinic/multibytecodec.c.h b/Modules/cjkcodecs/clinic/multibytecodec.c.h new file mode 100644 index 000000000000..8a47ff88a68e --- /dev/null +++ b/Modules/cjkcodecs/clinic/multibytecodec.c.h @@ -0,0 +1,320 @@ +/*[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)_multibytecodec_MultibyteCodec_encode, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"input", "errors", NULL}; + PyObject *input; + const char *errors = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|z:encode", _keywords, + &input, &errors)) + goto exit; + 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)_multibytecodec_MultibyteCodec_decode, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"input", "errors", NULL}; + Py_buffer input = {NULL, NULL}; + const char *errors = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|z:decode", _keywords, + &input, &errors)) + goto exit; + 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)_multibytecodec_MultibyteIncrementalEncoder_encode, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"input", "final", NULL}; + PyObject *input; + int final = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:encode", _keywords, + &input, &final)) + goto exit; + return_value = _multibytecodec_MultibyteIncrementalEncoder_encode_impl(self, input, final); + +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)_multibytecodec_MultibyteIncrementalDecoder_decode, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"input", "final", NULL}; + Py_buffer input = {NULL, NULL}; + int final = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|i:decode", _keywords, + &input, &final)) + goto exit; + 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_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)_multibytecodec_MultibyteStreamReader_read, METH_VARARGS, _multibytecodec_MultibyteStreamReader_read__doc__}, + +static PyObject * +_multibytecodec_MultibyteStreamReader_read_impl(MultibyteStreamReaderObject *self, + PyObject *sizeobj); + +static PyObject * +_multibytecodec_MultibyteStreamReader_read(MultibyteStreamReaderObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *sizeobj = Py_None; + + if (!PyArg_UnpackTuple(args, "read", + 0, 1, + &sizeobj)) + goto exit; + 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)_multibytecodec_MultibyteStreamReader_readline, METH_VARARGS, _multibytecodec_MultibyteStreamReader_readline__doc__}, + +static PyObject * +_multibytecodec_MultibyteStreamReader_readline_impl(MultibyteStreamReaderObject *self, + PyObject *sizeobj); + +static PyObject * +_multibytecodec_MultibyteStreamReader_readline(MultibyteStreamReaderObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *sizeobj = Py_None; + + if (!PyArg_UnpackTuple(args, "readline", + 0, 1, + &sizeobj)) + goto exit; + 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)_multibytecodec_MultibyteStreamReader_readlines, METH_VARARGS, _multibytecodec_MultibyteStreamReader_readlines__doc__}, + +static PyObject * +_multibytecodec_MultibyteStreamReader_readlines_impl(MultibyteStreamReaderObject *self, + PyObject *sizehintobj); + +static PyObject * +_multibytecodec_MultibyteStreamReader_readlines(MultibyteStreamReaderObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *sizehintobj = Py_None; + + if (!PyArg_UnpackTuple(args, "readlines", + 0, 1, + &sizehintobj)) + goto exit; + 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=eebb21e18c3043d1 input=a9049054013a1b77]*/ diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 087ae9b1aff5..e4547f75c991 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -8,6 +8,13 @@ #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; @@ -22,27 +29,7 @@ typedef struct { _PyUnicodeWriter writer; } MultibyteDecodeBuffer; -PyDoc_STRVAR(MultibyteCodec_Encode__doc__, -"I.encode(unicode[, errors]) -> (string, length consumed)\n\ -\n\ -Return an encoded string version of `unicode'. errors may be given to\n\ -set a different error handling scheme. Default is 'strict' meaning that\n\ -encoding errors raise a UnicodeEncodeError. Other possible values are\n\ -'ignore', 'replace' and 'xmlcharrefreplace' as well as any other name\n\ -registered with codecs.register_error that can handle UnicodeEncodeErrors."); - -PyDoc_STRVAR(MultibyteCodec_Decode__doc__, -"I.decode(string[, errors]) -> (unicodeobject, length consumed)\n\ -\n\ -Decodes `string' using I, an MultibyteCodec instance. errors may be given\n\ -to set a different error handling scheme. Default is 'strict' meaning\n\ -that encoding errors raise a UnicodeDecodeError. Other possible values\n\ -are 'ignore' and 'replace' as well as any other name registered with\n\ -codecs.register_error that is able to handle UnicodeDecodeErrors."); - -static char *codeckwarglist[] = {"input", "errors", NULL}; static char *incnewkwarglist[] = {"errors", NULL}; -static char *incrementalkwarglist[] = {"input", "final", NULL}; static char *streamkwarglist[] = {"stream", "errors", NULL}; static PyObject *multibytecodec_encode(MultibyteCodec *, @@ -182,8 +169,10 @@ expand_encodebuffer(MultibyteEncodeBuffer *buf, Py_ssize_t esize) orgsize = PyBytes_GET_SIZE(buf->outobj); incsize = (esize < (orgsize >> 1) ? (orgsize >> 1) | 1 : esize); - if (orgsize > PY_SSIZE_T_MAX - incsize) + if (orgsize > PY_SSIZE_T_MAX - incsize) { + PyErr_NoMemory(); return -1; + } if (_PyBytes_Resize(&buf->outobj, orgsize + incsize) == -1) return -1; @@ -194,11 +183,11 @@ expand_encodebuffer(MultibyteEncodeBuffer *buf, Py_ssize_t esize) return 0; } -#define REQUIRE_ENCODEBUFFER(buf, s) { \ - if ((s) < 1 || (buf)->outbuf + (s) > (buf)->outbuf_end) \ +#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) /** @@ -332,10 +321,11 @@ multibytecodec_encerror(MultibyteCodec *codec, assert(PyBytes_Check(retstr)); retstrsize = PyBytes_GET_SIZE(retstr); - REQUIRE_ENCODEBUFFER(buf, retstrsize); - - memcpy(buf->outbuf, PyBytes_AS_STRING(retstr), retstrsize); - buf->outbuf += retstrsize; + 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()) @@ -550,26 +540,37 @@ multibytecodec_encode(MultibyteCodec *codec, return NULL; } +/*[clinic input] +_multibytecodec.MultibyteCodec.encode + + input: object + errors: str(accept={str, NoneType}) = NULL + +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_Encode(MultibyteCodecObject *self, - PyObject *args, PyObject *kwargs) +_multibytecodec_MultibyteCodec_encode_impl(MultibyteCodecObject *self, + PyObject *input, + const char *errors) +/*[clinic end generated code: output=7b26652045ba56a9 input=05f6ced3c8dd0582]*/ { MultibyteCodec_State state; - PyObject *errorcb, *r, *arg, *ucvt; - const char *errors = NULL; + PyObject *errorcb, *r, *ucvt; Py_ssize_t datalen; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|z:encode", - codeckwarglist, &arg, &errors)) - return NULL; - - if (PyUnicode_Check(arg)) + if (PyUnicode_Check(input)) ucvt = NULL; else { - arg = ucvt = PyObject_Str(arg); - if (arg == NULL) + input = ucvt = PyObject_Str(input); + if (input == NULL) return NULL; - else if (!PyUnicode_Check(arg)) { + else if (!PyUnicode_Check(input)) { PyErr_SetString(PyExc_TypeError, "couldn't convert the object to unicode."); Py_DECREF(ucvt); @@ -577,11 +578,11 @@ MultibyteCodec_Encode(MultibyteCodecObject *self, } } - if (PyUnicode_READY(arg) < 0) { + if (PyUnicode_READY(input) < 0) { Py_XDECREF(ucvt); return NULL; } - datalen = PyUnicode_GET_LENGTH(arg); + datalen = PyUnicode_GET_LENGTH(input); errorcb = internal_error_callback(errors); if (errorcb == NULL) { @@ -593,7 +594,7 @@ MultibyteCodec_Encode(MultibyteCodecObject *self, self->codec->encinit(&state, self->codec->config) != 0) goto errorexit; r = multibytecodec_encode(self->codec, &state, - arg, NULL, errorcb, + input, NULL, errorcb, MBENC_FLUSH | MBENC_RESET); if (r == NULL) goto errorexit; @@ -608,31 +609,41 @@ MultibyteCodec_Encode(MultibyteCodecObject *self, return NULL; } +/*[clinic input] +_multibytecodec.MultibyteCodec.decode + + input: Py_buffer + errors: str(accept={str, NoneType}) = NULL + +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_Decode(MultibyteCodecObject *self, - PyObject *args, PyObject *kwargs) +_multibytecodec_MultibyteCodec_decode_impl(MultibyteCodecObject *self, + Py_buffer *input, + const char *errors) +/*[clinic end generated code: output=ff419f65bad6cc77 input=a7d45f87f75e5e02]*/ { MultibyteCodec_State state; MultibyteDecodeBuffer buf; PyObject *errorcb, *res; - Py_buffer pdata; - const char *data, *errors = NULL; + const char *data; Py_ssize_t datalen; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|z:decode", - codeckwarglist, &pdata, &errors)) - return NULL; - data = pdata.buf; - datalen = pdata.len; + data = input->buf; + datalen = input->len; errorcb = internal_error_callback(errors); if (errorcb == NULL) { - PyBuffer_Release(&pdata); return NULL; } if (datalen == 0) { - PyBuffer_Release(&pdata); ERROR_DECREF(errorcb); return make_tuple(PyUnicode_New(0, 0), 0); } @@ -665,13 +676,11 @@ MultibyteCodec_Decode(MultibyteCodecObject *self, if (res == NULL) goto errorexit; - PyBuffer_Release(&pdata); Py_XDECREF(buf.excobj); ERROR_DECREF(errorcb); return make_tuple(res, datalen); errorexit: - PyBuffer_Release(&pdata); ERROR_DECREF(errorcb); Py_XDECREF(buf.excobj); _PyUnicodeWriter_Dealloc(&buf.writer); @@ -680,13 +689,9 @@ MultibyteCodec_Decode(MultibyteCodecObject *self, } static struct PyMethodDef multibytecodec_methods[] = { - {"encode", (PyCFunction)MultibyteCodec_Encode, - METH_VARARGS | METH_KEYWORDS, - MultibyteCodec_Encode__doc__}, - {"decode", (PyCFunction)MultibyteCodec_Decode, - METH_VARARGS | METH_KEYWORDS, - MultibyteCodec_Decode__doc__}, - {NULL, NULL}, + _MULTIBYTECODEC_MULTIBYTECODEC_ENCODE_METHODDEF + _MULTIBYTECODEC_MULTIBYTECODEC_DECODE_METHODDEF + {NULL, NULL}, }; static void @@ -870,26 +875,34 @@ decoder_feed_buffer(MultibyteStatefulDecoderContext *ctx, } -/** - * MultibyteIncrementalEncoder object - */ +/*[clinic input] + class _multibytecodec.MultibyteIncrementalEncoder "MultibyteIncrementalEncoderObject *" "&MultibyteIncrementalEncoder_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3be82909cd08924d]*/ -static PyObject * -mbiencoder_encode(MultibyteIncrementalEncoderObject *self, - PyObject *args, PyObject *kwargs) -{ - PyObject *data; - int final = 0; +/*[clinic input] +_multibytecodec.MultibyteIncrementalEncoder.encode - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:encode", - incrementalkwarglist, &data, &final)) - return NULL; + input: object + final: int(c_default="0") = False +[clinic start generated code]*/ - return encoder_encode_stateful(STATEFUL_ECTX(self), data, final); +static PyObject * +_multibytecodec_MultibyteIncrementalEncoder_encode_impl(MultibyteIncrementalEncoderObject *self, + PyObject *input, + int final) +/*[clinic end generated code: output=123361b6c505e2c1 input=a345c688fa664f92]*/ +{ + return encoder_encode_stateful(STATEFUL_ECTX(self), input, final); } +/*[clinic input] +_multibytecodec.MultibyteIncrementalEncoder.reset +[clinic start generated code]*/ + static PyObject * -mbiencoder_reset(MultibyteIncrementalEncoderObject *self) +_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; @@ -906,11 +919,9 @@ mbiencoder_reset(MultibyteIncrementalEncoderObject *self) } static struct PyMethodDef mbiencoder_methods[] = { - {"encode", (PyCFunction)mbiencoder_encode, - METH_VARARGS | METH_KEYWORDS, NULL}, - {"reset", (PyCFunction)mbiencoder_reset, - METH_NOARGS, NULL}, - {NULL, NULL}, + _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_ENCODE_METHODDEF + _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_RESET_METHODDEF + {NULL, NULL}, }; static PyObject * @@ -1021,26 +1032,31 @@ static PyTypeObject MultibyteIncrementalEncoder_Type = { }; -/** - * MultibyteIncrementalDecoder object - */ +/*[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: int(c_default="0") = False +[clinic start generated code]*/ static PyObject * -mbidecoder_decode(MultibyteIncrementalDecoderObject *self, - PyObject *args, PyObject *kwargs) +_multibytecodec_MultibyteIncrementalDecoder_decode_impl(MultibyteIncrementalDecoderObject *self, + Py_buffer *input, + int final) +/*[clinic end generated code: output=b9b9090e8a9ce2ba input=576631c61906d39d]*/ { MultibyteDecodeBuffer buf; char *data, *wdata = NULL; - Py_buffer pdata; Py_ssize_t wsize, size, origpending; - int final = 0; PyObject *res; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|i:decode", - incrementalkwarglist, &pdata, &final)) - return NULL; - data = pdata.buf; - size = pdata.len; + data = input->buf; + size = input->len; _PyUnicodeWriter_Init(&buf.writer); buf.excobj = NULL; @@ -1091,14 +1107,12 @@ mbidecoder_decode(MultibyteIncrementalDecoderObject *self, if (res == NULL) goto errorexit; - PyBuffer_Release(&pdata); if (wdata != data) PyMem_Del(wdata); Py_XDECREF(buf.excobj); return res; errorexit: - PyBuffer_Release(&pdata); if (wdata != NULL && wdata != data) PyMem_Del(wdata); Py_XDECREF(buf.excobj); @@ -1106,8 +1120,13 @@ mbidecoder_decode(MultibyteIncrementalDecoderObject *self, return NULL; } +/*[clinic input] +_multibytecodec.MultibyteIncrementalDecoder.reset +[clinic start generated code]*/ + static PyObject * -mbidecoder_reset(MultibyteIncrementalDecoderObject *self) +_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) @@ -1118,11 +1137,9 @@ mbidecoder_reset(MultibyteIncrementalDecoderObject *self) } static struct PyMethodDef mbidecoder_methods[] = { - {"decode", (PyCFunction)mbidecoder_decode, - METH_VARARGS | METH_KEYWORDS, NULL}, - {"reset", (PyCFunction)mbidecoder_reset, - METH_NOARGS, NULL}, - {NULL, NULL}, + _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_DECODE_METHODDEF + _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_RESET_METHODDEF + {NULL, NULL}, }; static PyObject * @@ -1233,9 +1250,10 @@ static PyTypeObject MultibyteIncrementalDecoder_Type = { }; -/** - * MultibyteStreamReader object - */ +/*[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, @@ -1257,10 +1275,10 @@ mbstreamreader_iread(MultibyteStreamReaderObject *self, if (sizehint < 0) cres = PyObject_CallMethod(self->stream, - (char *)method, NULL); + method, NULL); else cres = PyObject_CallMethod(self->stream, - (char *)method, "i", sizehint); + method, "i", sizehint); if (cres == NULL) goto errorexit; @@ -1342,16 +1360,21 @@ mbstreamreader_iread(MultibyteStreamReaderObject *self, return NULL; } +/*[clinic input] + _multibytecodec.MultibyteStreamReader.read + + sizeobj: object = None + / +[clinic start generated code]*/ + static PyObject * -mbstreamreader_read(MultibyteStreamReaderObject *self, PyObject *args) +_multibytecodec_MultibyteStreamReader_read_impl(MultibyteStreamReaderObject *self, + PyObject *sizeobj) +/*[clinic end generated code: output=35621eb75355d5b8 input=015b0d3ff2fca485]*/ { - PyObject *sizeobj = NULL; Py_ssize_t size; - if (!PyArg_UnpackTuple(args, "read", 0, 1, &sizeobj)) - return NULL; - - if (sizeobj == Py_None || sizeobj == NULL) + if (sizeobj == Py_None) size = -1; else if (PyLong_Check(sizeobj)) size = PyLong_AsSsize_t(sizeobj); @@ -1366,16 +1389,21 @@ mbstreamreader_read(MultibyteStreamReaderObject *self, PyObject *args) return mbstreamreader_iread(self, "read", size); } +/*[clinic input] + _multibytecodec.MultibyteStreamReader.readline + + sizeobj: object = None + / +[clinic start generated code]*/ + static PyObject * -mbstreamreader_readline(MultibyteStreamReaderObject *self, PyObject *args) +_multibytecodec_MultibyteStreamReader_readline_impl(MultibyteStreamReaderObject *self, + PyObject *sizeobj) +/*[clinic end generated code: output=4fbfaae1ed457a11 input=41ccc64f9bb0cec3]*/ { - PyObject *sizeobj = NULL; Py_ssize_t size; - if (!PyArg_UnpackTuple(args, "readline", 0, 1, &sizeobj)) - return NULL; - - if (sizeobj == Py_None || sizeobj == NULL) + if (sizeobj == Py_None) size = -1; else if (PyLong_Check(sizeobj)) size = PyLong_AsSsize_t(sizeobj); @@ -1390,16 +1418,22 @@ mbstreamreader_readline(MultibyteStreamReaderObject *self, PyObject *args) return mbstreamreader_iread(self, "readline", size); } +/*[clinic input] + _multibytecodec.MultibyteStreamReader.readlines + + sizehintobj: object = None + / +[clinic start generated code]*/ + static PyObject * -mbstreamreader_readlines(MultibyteStreamReaderObject *self, PyObject *args) +_multibytecodec_MultibyteStreamReader_readlines_impl(MultibyteStreamReaderObject *self, + PyObject *sizehintobj) +/*[clinic end generated code: output=e7c4310768ed2ad4 input=54932f5d4d88e880]*/ { - PyObject *sizehintobj = NULL, *r, *sr; + PyObject *r, *sr; Py_ssize_t sizehint; - if (!PyArg_UnpackTuple(args, "readlines", 0, 1, &sizehintobj)) - return NULL; - - if (sizehintobj == Py_None || sizehintobj == NULL) + if (sizehintobj == Py_None) sizehint = -1; else if (PyLong_Check(sizehintobj)) sizehint = PyLong_AsSsize_t(sizehintobj); @@ -1420,8 +1454,13 @@ mbstreamreader_readlines(MultibyteStreamReaderObject *self, PyObject *args) return sr; } +/*[clinic input] + _multibytecodec.MultibyteStreamReader.reset +[clinic start generated code]*/ + static PyObject * -mbstreamreader_reset(MultibyteStreamReaderObject *self) +_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) @@ -1432,14 +1471,10 @@ mbstreamreader_reset(MultibyteStreamReaderObject *self) } static struct PyMethodDef mbstreamreader_methods[] = { - {"read", (PyCFunction)mbstreamreader_read, - METH_VARARGS, NULL}, - {"readline", (PyCFunction)mbstreamreader_readline, - METH_VARARGS, NULL}, - {"readlines", (PyCFunction)mbstreamreader_readlines, - METH_VARARGS, NULL}, - {"reset", (PyCFunction)mbstreamreader_reset, - METH_NOARGS, NULL}, + _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READ_METHODDEF + _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINE_METHODDEF + _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINES_METHODDEF + _MULTIBYTECODEC_MULTIBYTESTREAMREADER_RESET_METHODDEF {NULL, NULL}, }; @@ -1562,9 +1597,10 @@ static PyTypeObject MultibyteStreamReader_Type = { }; -/** - * MultibyteStreamWriter object - */ +/*[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, @@ -1585,8 +1621,17 @@ mbstreamwriter_iwrite(MultibyteStreamWriterObject *self, return 0; } +/*[clinic input] + _multibytecodec.MultibyteStreamWriter.write + + strobj: object + / +[clinic start generated code]*/ + static PyObject * -mbstreamwriter_write(MultibyteStreamWriterObject *self, PyObject *strobj) +_multibytecodec_MultibyteStreamWriter_write(MultibyteStreamWriterObject *self, + PyObject *strobj) +/*[clinic end generated code: output=e13ae841c895251e input=551dc4c018c10a2b]*/ { if (mbstreamwriter_iwrite(self, strobj)) return NULL; @@ -1594,8 +1639,17 @@ mbstreamwriter_write(MultibyteStreamWriterObject *self, PyObject *strobj) Py_RETURN_NONE; } +/*[clinic input] + _multibytecodec.MultibyteStreamWriter.writelines + + lines: object + / +[clinic start generated code]*/ + static PyObject * -mbstreamwriter_writelines(MultibyteStreamWriterObject *self, PyObject *lines) +_multibytecodec_MultibyteStreamWriter_writelines(MultibyteStreamWriterObject *self, + PyObject *lines) +/*[clinic end generated code: output=e5c4285ac8e7d522 input=57797fe7008d4e96]*/ { PyObject *strobj; int i, r; @@ -1621,11 +1675,19 @@ mbstreamwriter_writelines(MultibyteStreamWriterObject *self, PyObject *lines) Py_RETURN_NONE; } +/*[clinic input] + _multibytecodec.MultibyteStreamWriter.reset +[clinic start generated code]*/ + static PyObject * -mbstreamwriter_reset(MultibyteStreamWriterObject *self) +_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); @@ -1721,13 +1783,10 @@ mbstreamwriter_dealloc(MultibyteStreamWriterObject *self) } static struct PyMethodDef mbstreamwriter_methods[] = { - {"write", (PyCFunction)mbstreamwriter_write, - METH_O, NULL}, - {"writelines", (PyCFunction)mbstreamwriter_writelines, - METH_O, NULL}, - {"reset", (PyCFunction)mbstreamwriter_reset, - METH_NOARGS, NULL}, - {NULL, NULL}, + _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITE_METHODDEF + _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITELINES_METHODDEF + _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_RESET_METHODDEF + {NULL, NULL}, }; static PyMemberDef mbstreamwriter_members[] = { @@ -1781,12 +1840,16 @@ static PyTypeObject MultibyteStreamWriter_Type = { }; -/** - * Exposed factory function - */ +/*[clinic input] +_multibytecodec.__create_codec + + arg: object + / +[clinic start generated code]*/ static PyObject * -__create_codec(PyObject *ignore, PyObject *arg) +_multibytecodec___create_codec(PyModuleDef *module, PyObject *arg) +/*[clinic end generated code: output=fbe74f6510640163 input=6840b2a6b183fcfa]*/ { MultibyteCodecObject *self; MultibyteCodec *codec; @@ -1809,7 +1872,7 @@ __create_codec(PyObject *ignore, PyObject *arg) } static struct PyMethodDef __methods[] = { - {"__create_codec", (PyCFunction)__create_codec, METH_O}, + _MULTIBYTECODEC___CREATE_CODEC_METHODDEF {NULL, NULL}, }; diff --git a/Modules/clinic/_bz2module.c.h b/Modules/clinic/_bz2module.c.h new file mode 100644 index 000000000000..3ed8303e95f2 --- /dev/null +++ b/Modules/clinic/_bz2module.c.h @@ -0,0 +1,168 @@ +/*[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 (!PyArg_Parse(arg, "y*:compress", &data)) + 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_ParseTuple(args, "|i:BZ2Compressor", + &compresslevel)) + goto exit; + 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)_bz2_BZ2Decompressor_decompress, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"data", "max_length", NULL}; + Py_buffer data = {NULL, NULL}; + Py_ssize_t max_length = -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|n:decompress", _keywords, + &data, &max_length)) + goto exit; + 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=fef29b76b3314fc7 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_codecsmodule.c.h b/Modules/clinic/_codecsmodule.c.h new file mode 100644 index 000000000000..e94be1176e9e --- /dev/null +++ b/Modules/clinic/_codecsmodule.c.h @@ -0,0 +1,1396 @@ +/*[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(PyModuleDef *module, const char *encoding); + +static PyObject * +_codecs_lookup(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *encoding; + + if (!PyArg_Parse(arg, "s:lookup", &encoding)) + 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)_codecs_encode, METH_VARARGS|METH_KEYWORDS, _codecs_encode__doc__}, + +static PyObject * +_codecs_encode_impl(PyModuleDef *module, PyObject *obj, const char *encoding, + const char *errors); + +static PyObject * +_codecs_encode(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"obj", "encoding", "errors", NULL}; + PyObject *obj; + const char *encoding = NULL; + const char *errors = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|ss:encode", _keywords, + &obj, &encoding, &errors)) + goto exit; + 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)_codecs_decode, METH_VARARGS|METH_KEYWORDS, _codecs_decode__doc__}, + +static PyObject * +_codecs_decode_impl(PyModuleDef *module, PyObject *obj, const char *encoding, + const char *errors); + +static PyObject * +_codecs_decode(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"obj", "encoding", "errors", NULL}; + PyObject *obj; + const char *encoding = NULL; + const char *errors = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|ss:decode", _keywords, + &obj, &encoding, &errors)) + goto exit; + 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(PyModuleDef *module, const char *encoding); + +static PyObject * +_codecs__forget_codec(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *encoding; + + if (!PyArg_Parse(arg, "s:_forget_codec", &encoding)) + 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)_codecs_escape_decode, METH_VARARGS, _codecs_escape_decode__doc__}, + +static PyObject * +_codecs_escape_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors); + +static PyObject * +_codecs_escape_decode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "s*|z:escape_decode", + &data, &errors)) + goto exit; + 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)_codecs_escape_encode, METH_VARARGS, _codecs_escape_encode__doc__}, + +static PyObject * +_codecs_escape_encode_impl(PyModuleDef *module, PyObject *data, + const char *errors); + +static PyObject * +_codecs_escape_encode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *data; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "O!|z:escape_encode", + &PyBytes_Type, &data, &errors)) + goto exit; + return_value = _codecs_escape_encode_impl(module, data, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(_codecs_unicode_internal_decode__doc__, +"unicode_internal_decode($module, obj, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_UNICODE_INTERNAL_DECODE_METHODDEF \ + {"unicode_internal_decode", (PyCFunction)_codecs_unicode_internal_decode, METH_VARARGS, _codecs_unicode_internal_decode__doc__}, + +static PyObject * +_codecs_unicode_internal_decode_impl(PyModuleDef *module, PyObject *obj, + const char *errors); + +static PyObject * +_codecs_unicode_internal_decode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *obj; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "O|z:unicode_internal_decode", + &obj, &errors)) + goto exit; + return_value = _codecs_unicode_internal_decode_impl(module, obj, 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)_codecs_utf_7_decode, METH_VARARGS, _codecs_utf_7_decode__doc__}, + +static PyObject * +_codecs_utf_7_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int final); + +static PyObject * +_codecs_utf_7_decode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + + if (!PyArg_ParseTuple(args, "y*|zi:utf_7_decode", + &data, &errors, &final)) + goto exit; + 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)_codecs_utf_8_decode, METH_VARARGS, _codecs_utf_8_decode__doc__}, + +static PyObject * +_codecs_utf_8_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int final); + +static PyObject * +_codecs_utf_8_decode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + + if (!PyArg_ParseTuple(args, "y*|zi:utf_8_decode", + &data, &errors, &final)) + goto exit; + 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)_codecs_utf_16_decode, METH_VARARGS, _codecs_utf_16_decode__doc__}, + +static PyObject * +_codecs_utf_16_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int final); + +static PyObject * +_codecs_utf_16_decode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + + if (!PyArg_ParseTuple(args, "y*|zi:utf_16_decode", + &data, &errors, &final)) + goto exit; + 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)_codecs_utf_16_le_decode, METH_VARARGS, _codecs_utf_16_le_decode__doc__}, + +static PyObject * +_codecs_utf_16_le_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int final); + +static PyObject * +_codecs_utf_16_le_decode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + + if (!PyArg_ParseTuple(args, "y*|zi:utf_16_le_decode", + &data, &errors, &final)) + goto exit; + 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)_codecs_utf_16_be_decode, METH_VARARGS, _codecs_utf_16_be_decode__doc__}, + +static PyObject * +_codecs_utf_16_be_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int final); + +static PyObject * +_codecs_utf_16_be_decode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + + if (!PyArg_ParseTuple(args, "y*|zi:utf_16_be_decode", + &data, &errors, &final)) + goto exit; + 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)_codecs_utf_16_ex_decode, METH_VARARGS, _codecs_utf_16_ex_decode__doc__}, + +static PyObject * +_codecs_utf_16_ex_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int byteorder, int final); + +static PyObject * +_codecs_utf_16_ex_decode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int byteorder = 0; + int final = 0; + + if (!PyArg_ParseTuple(args, "y*|zii:utf_16_ex_decode", + &data, &errors, &byteorder, &final)) + goto exit; + 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)_codecs_utf_32_decode, METH_VARARGS, _codecs_utf_32_decode__doc__}, + +static PyObject * +_codecs_utf_32_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int final); + +static PyObject * +_codecs_utf_32_decode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + + if (!PyArg_ParseTuple(args, "y*|zi:utf_32_decode", + &data, &errors, &final)) + goto exit; + 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)_codecs_utf_32_le_decode, METH_VARARGS, _codecs_utf_32_le_decode__doc__}, + +static PyObject * +_codecs_utf_32_le_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int final); + +static PyObject * +_codecs_utf_32_le_decode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + + if (!PyArg_ParseTuple(args, "y*|zi:utf_32_le_decode", + &data, &errors, &final)) + goto exit; + 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)_codecs_utf_32_be_decode, METH_VARARGS, _codecs_utf_32_be_decode__doc__}, + +static PyObject * +_codecs_utf_32_be_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int final); + +static PyObject * +_codecs_utf_32_be_decode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + + if (!PyArg_ParseTuple(args, "y*|zi:utf_32_be_decode", + &data, &errors, &final)) + goto exit; + 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)_codecs_utf_32_ex_decode, METH_VARARGS, _codecs_utf_32_ex_decode__doc__}, + +static PyObject * +_codecs_utf_32_ex_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int byteorder, int final); + +static PyObject * +_codecs_utf_32_ex_decode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int byteorder = 0; + int final = 0; + + if (!PyArg_ParseTuple(args, "y*|zii:utf_32_ex_decode", + &data, &errors, &byteorder, &final)) + goto exit; + 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)_codecs_unicode_escape_decode, METH_VARARGS, _codecs_unicode_escape_decode__doc__}, + +static PyObject * +_codecs_unicode_escape_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors); + +static PyObject * +_codecs_unicode_escape_decode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "s*|z:unicode_escape_decode", + &data, &errors)) + goto exit; + 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)_codecs_raw_unicode_escape_decode, METH_VARARGS, _codecs_raw_unicode_escape_decode__doc__}, + +static PyObject * +_codecs_raw_unicode_escape_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors); + +static PyObject * +_codecs_raw_unicode_escape_decode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "s*|z:raw_unicode_escape_decode", + &data, &errors)) + goto exit; + 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)_codecs_latin_1_decode, METH_VARARGS, _codecs_latin_1_decode__doc__}, + +static PyObject * +_codecs_latin_1_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors); + +static PyObject * +_codecs_latin_1_decode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "y*|z:latin_1_decode", + &data, &errors)) + goto exit; + 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)_codecs_ascii_decode, METH_VARARGS, _codecs_ascii_decode__doc__}, + +static PyObject * +_codecs_ascii_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors); + +static PyObject * +_codecs_ascii_decode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "y*|z:ascii_decode", + &data, &errors)) + goto exit; + 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)_codecs_charmap_decode, METH_VARARGS, _codecs_charmap_decode__doc__}, + +static PyObject * +_codecs_charmap_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, PyObject *mapping); + +static PyObject * +_codecs_charmap_decode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + PyObject *mapping = NULL; + + if (!PyArg_ParseTuple(args, "y*|zO:charmap_decode", + &data, &errors, &mapping)) + goto exit; + 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(HAVE_MBCS) + +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)_codecs_mbcs_decode, METH_VARARGS, _codecs_mbcs_decode__doc__}, + +static PyObject * +_codecs_mbcs_decode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors, int final); + +static PyObject * +_codecs_mbcs_decode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + + if (!PyArg_ParseTuple(args, "y*|zi:mbcs_decode", + &data, &errors, &final)) + goto exit; + 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(HAVE_MBCS) */ + +#if defined(HAVE_MBCS) + +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)_codecs_code_page_decode, METH_VARARGS, _codecs_code_page_decode__doc__}, + +static PyObject * +_codecs_code_page_decode_impl(PyModuleDef *module, int codepage, + Py_buffer *data, const char *errors, int final); + +static PyObject * +_codecs_code_page_decode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int codepage; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + int final = 0; + + if (!PyArg_ParseTuple(args, "iy*|zi:code_page_decode", + &codepage, &data, &errors, &final)) + goto exit; + 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(HAVE_MBCS) */ + +PyDoc_STRVAR(_codecs_readbuffer_encode__doc__, +"readbuffer_encode($module, data, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_READBUFFER_ENCODE_METHODDEF \ + {"readbuffer_encode", (PyCFunction)_codecs_readbuffer_encode, METH_VARARGS, _codecs_readbuffer_encode__doc__}, + +static PyObject * +_codecs_readbuffer_encode_impl(PyModuleDef *module, Py_buffer *data, + const char *errors); + +static PyObject * +_codecs_readbuffer_encode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "s*|z:readbuffer_encode", + &data, &errors)) + goto exit; + 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_unicode_internal_encode__doc__, +"unicode_internal_encode($module, obj, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_UNICODE_INTERNAL_ENCODE_METHODDEF \ + {"unicode_internal_encode", (PyCFunction)_codecs_unicode_internal_encode, METH_VARARGS, _codecs_unicode_internal_encode__doc__}, + +static PyObject * +_codecs_unicode_internal_encode_impl(PyModuleDef *module, PyObject *obj, + const char *errors); + +static PyObject * +_codecs_unicode_internal_encode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *obj; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "O|z:unicode_internal_encode", + &obj, &errors)) + goto exit; + return_value = _codecs_unicode_internal_encode_impl(module, obj, errors); + +exit: + 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)_codecs_utf_7_encode, METH_VARARGS, _codecs_utf_7_encode__doc__}, + +static PyObject * +_codecs_utf_7_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_utf_7_encode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "O|z:utf_7_encode", + &str, &errors)) + goto exit; + 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)_codecs_utf_8_encode, METH_VARARGS, _codecs_utf_8_encode__doc__}, + +static PyObject * +_codecs_utf_8_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_utf_8_encode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "O|z:utf_8_encode", + &str, &errors)) + goto exit; + 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)_codecs_utf_16_encode, METH_VARARGS, _codecs_utf_16_encode__doc__}, + +static PyObject * +_codecs_utf_16_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors, int byteorder); + +static PyObject * +_codecs_utf_16_encode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + int byteorder = 0; + + if (!PyArg_ParseTuple(args, "O|zi:utf_16_encode", + &str, &errors, &byteorder)) + goto exit; + 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)_codecs_utf_16_le_encode, METH_VARARGS, _codecs_utf_16_le_encode__doc__}, + +static PyObject * +_codecs_utf_16_le_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_utf_16_le_encode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "O|z:utf_16_le_encode", + &str, &errors)) + goto exit; + 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)_codecs_utf_16_be_encode, METH_VARARGS, _codecs_utf_16_be_encode__doc__}, + +static PyObject * +_codecs_utf_16_be_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_utf_16_be_encode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "O|z:utf_16_be_encode", + &str, &errors)) + goto exit; + 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)_codecs_utf_32_encode, METH_VARARGS, _codecs_utf_32_encode__doc__}, + +static PyObject * +_codecs_utf_32_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors, int byteorder); + +static PyObject * +_codecs_utf_32_encode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + int byteorder = 0; + + if (!PyArg_ParseTuple(args, "O|zi:utf_32_encode", + &str, &errors, &byteorder)) + goto exit; + 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)_codecs_utf_32_le_encode, METH_VARARGS, _codecs_utf_32_le_encode__doc__}, + +static PyObject * +_codecs_utf_32_le_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_utf_32_le_encode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "O|z:utf_32_le_encode", + &str, &errors)) + goto exit; + 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)_codecs_utf_32_be_encode, METH_VARARGS, _codecs_utf_32_be_encode__doc__}, + +static PyObject * +_codecs_utf_32_be_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_utf_32_be_encode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "O|z:utf_32_be_encode", + &str, &errors)) + goto exit; + 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)_codecs_unicode_escape_encode, METH_VARARGS, _codecs_unicode_escape_encode__doc__}, + +static PyObject * +_codecs_unicode_escape_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_unicode_escape_encode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "O|z:unicode_escape_encode", + &str, &errors)) + goto exit; + 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)_codecs_raw_unicode_escape_encode, METH_VARARGS, _codecs_raw_unicode_escape_encode__doc__}, + +static PyObject * +_codecs_raw_unicode_escape_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_raw_unicode_escape_encode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "O|z:raw_unicode_escape_encode", + &str, &errors)) + goto exit; + 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)_codecs_latin_1_encode, METH_VARARGS, _codecs_latin_1_encode__doc__}, + +static PyObject * +_codecs_latin_1_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_latin_1_encode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "O|z:latin_1_encode", + &str, &errors)) + goto exit; + 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)_codecs_ascii_encode, METH_VARARGS, _codecs_ascii_encode__doc__}, + +static PyObject * +_codecs_ascii_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_ascii_encode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "O|z:ascii_encode", + &str, &errors)) + goto exit; + 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)_codecs_charmap_encode, METH_VARARGS, _codecs_charmap_encode__doc__}, + +static PyObject * +_codecs_charmap_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors, PyObject *mapping); + +static PyObject * +_codecs_charmap_encode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + PyObject *mapping = NULL; + + if (!PyArg_ParseTuple(args, "O|zO:charmap_encode", + &str, &errors, &mapping)) + goto exit; + 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(PyModuleDef *module, PyObject *map); + +static PyObject * +_codecs_charmap_build(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *map; + + if (!PyArg_Parse(arg, "U:charmap_build", &map)) + goto exit; + return_value = _codecs_charmap_build_impl(module, map); + +exit: + return return_value; +} + +#if defined(HAVE_MBCS) + +PyDoc_STRVAR(_codecs_mbcs_encode__doc__, +"mbcs_encode($module, str, errors=None, /)\n" +"--\n" +"\n"); + +#define _CODECS_MBCS_ENCODE_METHODDEF \ + {"mbcs_encode", (PyCFunction)_codecs_mbcs_encode, METH_VARARGS, _codecs_mbcs_encode__doc__}, + +static PyObject * +_codecs_mbcs_encode_impl(PyModuleDef *module, PyObject *str, + const char *errors); + +static PyObject * +_codecs_mbcs_encode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *str; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "O|z:mbcs_encode", + &str, &errors)) + goto exit; + return_value = _codecs_mbcs_encode_impl(module, str, errors); + +exit: + return return_value; +} + +#endif /* defined(HAVE_MBCS) */ + +#if defined(HAVE_MBCS) + +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)_codecs_code_page_encode, METH_VARARGS, _codecs_code_page_encode__doc__}, + +static PyObject * +_codecs_code_page_encode_impl(PyModuleDef *module, int code_page, + PyObject *str, const char *errors); + +static PyObject * +_codecs_code_page_encode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int code_page; + PyObject *str; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "iO|z:code_page_encode", + &code_page, &str, &errors)) + goto exit; + return_value = _codecs_code_page_encode_impl(module, code_page, str, errors); + +exit: + return return_value; +} + +#endif /* defined(HAVE_MBCS) */ + +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)_codecs_register_error, METH_VARARGS, _codecs_register_error__doc__}, + +static PyObject * +_codecs_register_error_impl(PyModuleDef *module, const char *errors, + PyObject *handler); + +static PyObject * +_codecs_register_error(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + const char *errors; + PyObject *handler; + + if (!PyArg_ParseTuple(args, "sO:register_error", + &errors, &handler)) + goto exit; + 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(PyModuleDef *module, const char *name); + +static PyObject * +_codecs_lookup_error(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *name; + + if (!PyArg_Parse(arg, "s:lookup_error", &name)) + 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_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_CODE_PAGE_ENCODE_METHODDEF + #define _CODECS_CODE_PAGE_ENCODE_METHODDEF +#endif /* !defined(_CODECS_CODE_PAGE_ENCODE_METHODDEF) */ +/*[clinic end generated code: output=9c9967048027c1c7 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_cryptmodule.c.h b/Modules/clinic/_cryptmodule.c.h new file mode 100644 index 000000000000..b8ec31e0032b --- /dev/null +++ b/Modules/clinic/_cryptmodule.c.h @@ -0,0 +1,37 @@ +/*[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)crypt_crypt, METH_VARARGS, crypt_crypt__doc__}, + +static PyObject * +crypt_crypt_impl(PyModuleDef *module, const char *word, const char *salt); + +static PyObject * +crypt_crypt(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + const char *word; + const char *salt; + + if (!PyArg_ParseTuple(args, "ss:crypt", + &word, &salt)) + goto exit; + return_value = crypt_crypt_impl(module, word, salt); + +exit: + return return_value; +} +/*[clinic end generated code: output=22c295c9bce018c4 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_cursesmodule.c.h b/Modules/clinic/_cursesmodule.c.h new file mode 100644 index 000000000000..5e1174249901 --- /dev/null +++ b/Modules/clinic/_cursesmodule.c.h @@ -0,0 +1,71 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(curses_window_addch__doc__, +"addch([y, x,] ch, [attr])\n" +"Paint character ch at (y, x) with attributes attr.\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 = 0; + + 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; +} +/*[clinic end generated code: output=982b1e709577f3ec input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_datetimemodule.c.h b/Modules/clinic/_datetimemodule.c.h new file mode 100644 index 000000000000..688c903e2faf --- /dev/null +++ b/Modules/clinic/_datetimemodule.c.h @@ -0,0 +1,37 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +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)datetime_datetime_now, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"tz", NULL}; + PyObject *tz = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:now", _keywords, + &tz)) + goto exit; + return_value = datetime_datetime_now_impl(type, tz); + +exit: + return return_value; +} +/*[clinic end generated code: output=7f45c670d6e4953a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_dbmmodule.c.h b/Modules/clinic/_dbmmodule.c.h new file mode 100644 index 000000000000..8474e0282897 --- /dev/null +++ b/Modules/clinic/_dbmmodule.c.h @@ -0,0 +1,141 @@ +/*[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=b\'\', /)\n" +"--\n" +"\n" +"Return the value for key if present, otherwise default."); + +#define _DBM_DBM_GET_METHODDEF \ + {"get", (PyCFunction)_dbm_dbm_get, METH_VARARGS, _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 *args) +{ + PyObject *return_value = NULL; + const char *key; + Py_ssize_clean_t key_length; + PyObject *default_value = NULL; + + if (!PyArg_ParseTuple(args, "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)_dbm_dbm_setdefault, METH_VARARGS, _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 *args) +{ + PyObject *return_value = NULL; + const char *key; + Py_ssize_clean_t key_length; + PyObject *default_value = NULL; + + if (!PyArg_ParseTuple(args, "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)dbmopen, METH_VARARGS, dbmopen__doc__}, + +static PyObject * +dbmopen_impl(PyModuleDef *module, const char *filename, const char *flags, + int mode); + +static PyObject * +dbmopen(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + const char *filename; + const char *flags = "r"; + int mode = 438; + + if (!PyArg_ParseTuple(args, "s|si:open", + &filename, &flags, &mode)) + goto exit; + return_value = dbmopen_impl(module, filename, flags, mode); + +exit: + return return_value; +} +/*[clinic end generated code: output=1d92e81b28c558d0 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_elementtree.c.h b/Modules/clinic/_elementtree.c.h new file mode 100644 index 000000000000..86b4c4cec755 --- /dev/null +++ b/Modules/clinic/_elementtree.c.h @@ -0,0 +1,679 @@ +/*[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 (!PyArg_Parse(arg, "O!:append", &Element_Type, &subelement)) + goto exit; + 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__}, + +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)_elementtree_Element_find, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "namespaces", NULL}; + PyObject *path; + PyObject *namespaces = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:find", _keywords, + &path, &namespaces)) + goto exit; + 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)_elementtree_Element_findtext, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "default", "namespaces", NULL}; + PyObject *path; + PyObject *default_value = Py_None; + PyObject *namespaces = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OO:findtext", _keywords, + &path, &default_value, &namespaces)) + goto exit; + 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)_elementtree_Element_findall, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "namespaces", NULL}; + PyObject *path; + PyObject *namespaces = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:findall", _keywords, + &path, &namespaces)) + goto exit; + 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)_elementtree_Element_iterfind, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "namespaces", NULL}; + PyObject *path; + PyObject *namespaces = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:iterfind", _keywords, + &path, &namespaces)) + goto exit; + 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)_elementtree_Element_get, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"key", "default", NULL}; + PyObject *key; + PyObject *default_value = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:get", _keywords, + &key, &default_value)) + goto exit; + 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)_elementtree_Element_iter, METH_VARARGS|METH_KEYWORDS, _elementtree_Element_iter__doc__}, + +static PyObject * +_elementtree_Element_iter_impl(ElementObject *self, PyObject *tag); + +static PyObject * +_elementtree_Element_iter(ElementObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"tag", NULL}; + PyObject *tag = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:iter", _keywords, + &tag)) + goto exit; + return_value = _elementtree_Element_iter_impl(self, tag); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_Element_itertext__doc__, +"itertext($self, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_ITERTEXT_METHODDEF \ + {"itertext", (PyCFunction)_elementtree_Element_itertext, METH_NOARGS, _elementtree_Element_itertext__doc__}, + +static PyObject * +_elementtree_Element_itertext_impl(ElementObject *self); + +static PyObject * +_elementtree_Element_itertext(ElementObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _elementtree_Element_itertext_impl(self); +} + +PyDoc_STRVAR(_elementtree_Element_insert__doc__, +"insert($self, index, subelement, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_ELEMENT_INSERT_METHODDEF \ + {"insert", (PyCFunction)_elementtree_Element_insert, METH_VARARGS, _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 *args) +{ + PyObject *return_value = NULL; + Py_ssize_t index; + PyObject *subelement; + + if (!PyArg_ParseTuple(args, "nO!:insert", + &index, &Element_Type, &subelement)) + goto exit; + 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)_elementtree_Element_makeelement, METH_VARARGS, _elementtree_Element_makeelement__doc__}, + +static PyObject * +_elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag, + PyObject *attrib); + +static PyObject * +_elementtree_Element_makeelement(ElementObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *tag; + PyObject *attrib; + + if (!PyArg_UnpackTuple(args, "makeelement", + 2, 2, + &tag, &attrib)) + goto exit; + 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 (!PyArg_Parse(arg, "O!:remove", &Element_Type, &subelement)) + goto exit; + 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)_elementtree_Element_set, METH_VARARGS, _elementtree_Element_set__doc__}, + +static PyObject * +_elementtree_Element_set_impl(ElementObject *self, PyObject *key, + PyObject *value); + +static PyObject * +_elementtree_Element_set(ElementObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *value; + + if (!PyArg_UnpackTuple(args, "set", + 2, 2, + &key, &value)) + goto exit; + return_value = _elementtree_Element_set_impl(self, key, value); + +exit: + return return_value; +} + +static int +_elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, + PyObject *element_factory); + +static int +_elementtree_TreeBuilder___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static char *_keywords[] = {"element_factory", NULL}; + PyObject *element_factory = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:TreeBuilder", _keywords, + &element_factory)) + goto exit; + return_value = _elementtree_TreeBuilder___init___impl((TreeBuilderObject *)self, element_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_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)_elementtree_TreeBuilder_start, METH_VARARGS, _elementtree_TreeBuilder_start__doc__}, + +static PyObject * +_elementtree_TreeBuilder_start_impl(TreeBuilderObject *self, PyObject *tag, + PyObject *attrs); + +static PyObject * +_elementtree_TreeBuilder_start(TreeBuilderObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *tag; + PyObject *attrs = Py_None; + + if (!PyArg_UnpackTuple(args, "start", + 1, 2, + &tag, &attrs)) + goto exit; + return_value = _elementtree_TreeBuilder_start_impl(self, tag, attrs); + +exit: + return return_value; +} + +static int +_elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *html, + PyObject *target, const char *encoding); + +static int +_elementtree_XMLParser___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static char *_keywords[] = {"html", "target", "encoding", NULL}; + PyObject *html = NULL; + PyObject *target = NULL; + const char *encoding = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOz:XMLParser", _keywords, + &html, &target, &encoding)) + goto exit; + return_value = _elementtree_XMLParser___init___impl((XMLParserObject *)self, html, 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_doctype__doc__, +"doctype($self, name, pubid, system, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_XMLPARSER_DOCTYPE_METHODDEF \ + {"doctype", (PyCFunction)_elementtree_XMLParser_doctype, METH_VARARGS, _elementtree_XMLParser_doctype__doc__}, + +static PyObject * +_elementtree_XMLParser_doctype_impl(XMLParserObject *self, PyObject *name, + PyObject *pubid, PyObject *system); + +static PyObject * +_elementtree_XMLParser_doctype(XMLParserObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *name; + PyObject *pubid; + PyObject *system; + + if (!PyArg_UnpackTuple(args, "doctype", + 3, 3, + &name, &pubid, &system)) + goto exit; + return_value = _elementtree_XMLParser_doctype_impl(self, name, pubid, system); + +exit: + return return_value; +} + +PyDoc_STRVAR(_elementtree_XMLParser__setevents__doc__, +"_setevents($self, events_queue, events_to_report=None, /)\n" +"--\n" +"\n"); + +#define _ELEMENTTREE_XMLPARSER__SETEVENTS_METHODDEF \ + {"_setevents", (PyCFunction)_elementtree_XMLParser__setevents, METH_VARARGS, _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 *args) +{ + PyObject *return_value = NULL; + PyObject *events_queue; + PyObject *events_to_report = Py_None; + + if (!PyArg_ParseTuple(args, "O!|O:_setevents", + &PyList_Type, &events_queue, &events_to_report)) + goto exit; + return_value = _elementtree_XMLParser__setevents_impl(self, events_queue, events_to_report); + +exit: + return return_value; +} +/*[clinic end generated code: output=25b8bf7e7f2151ca input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_gdbmmodule.c.h b/Modules/clinic/_gdbmmodule.c.h new file mode 100644 index 000000000000..110ad9a539c1 --- /dev/null +++ b/Modules/clinic/_gdbmmodule.c.h @@ -0,0 +1,253 @@ +/*[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)_gdbm_gdbm_get, METH_VARARGS, _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 *args) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *default_value = Py_None; + + if (!PyArg_UnpackTuple(args, "get", + 1, 2, + &key, &default_value)) + goto exit; + 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)_gdbm_gdbm_setdefault, METH_VARARGS, _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 *args) +{ + PyObject *return_value = NULL; + PyObject *key; + PyObject *default_value = Py_None; + + if (!PyArg_UnpackTuple(args, "setdefault", + 1, 2, + &key, &default_value)) + goto exit; + 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)dbmopen, METH_VARARGS, dbmopen__doc__}, + +static PyObject * +dbmopen_impl(PyModuleDef *module, const char *name, const char *flags, + int mode); + +static PyObject * +dbmopen(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + const char *name; + const char *flags = "r"; + int mode = 438; + + if (!PyArg_ParseTuple(args, "s|si:open", + &name, &flags, &mode)) + goto exit; + return_value = dbmopen_impl(module, name, flags, mode); + +exit: + return return_value; +} +/*[clinic end generated code: output=d3d8d871bcccb68a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_lzmamodule.c.h b/Modules/clinic/_lzmamodule.c.h new file mode 100644 index 000000000000..59d9d51026e8 --- /dev/null +++ b/Modules/clinic/_lzmamodule.c.h @@ -0,0 +1,248 @@ +/*[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 (!PyArg_Parse(arg, "y*:compress", &data)) + 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)_lzma_LZMADecompressor_decompress, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"data", "max_length", NULL}; + Py_buffer data = {NULL, NULL}; + Py_ssize_t max_length = -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|n:decompress", _keywords, + &data, &max_length)) + goto exit; + 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 char *_keywords[] = {"format", "memlimit", "filters", NULL}; + int format = FORMAT_AUTO; + PyObject *memlimit = Py_None; + PyObject *filters = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iOO:LZMADecompressor", _keywords, + &format, &memlimit, &filters)) + goto exit; + 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(PyModuleDef *module, int check_id); + +static PyObject * +_lzma_is_check_supported(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int check_id; + + if (!PyArg_Parse(arg, "i:is_check_supported", &check_id)) + 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(PyModuleDef *module, lzma_filter filter); + +static PyObject * +_lzma__encode_filter_properties(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + lzma_filter filter = {LZMA_VLI_UNKNOWN, NULL}; + + if (!PyArg_Parse(arg, "O&:_encode_filter_properties", lzma_filter_converter, &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)_lzma__decode_filter_properties, METH_VARARGS, _lzma__decode_filter_properties__doc__}, + +static PyObject * +_lzma__decode_filter_properties_impl(PyModuleDef *module, lzma_vli filter_id, + Py_buffer *encoded_props); + +static PyObject * +_lzma__decode_filter_properties(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + lzma_vli filter_id; + Py_buffer encoded_props = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, "O&y*:_decode_filter_properties", + lzma_vli_converter, &filter_id, &encoded_props)) + 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=2d3e0842be3d3fe1 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_opcode.c.h b/Modules/clinic/_opcode.c.h new file mode 100644 index 000000000000..196a2eefd374 --- /dev/null +++ b/Modules/clinic/_opcode.c.h @@ -0,0 +1,36 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(_opcode_stack_effect__doc__, +"stack_effect($module, opcode, oparg=None, /)\n" +"--\n" +"\n" +"Compute the stack effect of the opcode."); + +#define _OPCODE_STACK_EFFECT_METHODDEF \ + {"stack_effect", (PyCFunction)_opcode_stack_effect, METH_VARARGS, _opcode_stack_effect__doc__}, + +static int +_opcode_stack_effect_impl(PyModuleDef *module, int opcode, PyObject *oparg); + +static PyObject * +_opcode_stack_effect(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int opcode; + PyObject *oparg = Py_None; + int _return_value; + + if (!PyArg_ParseTuple(args, "i|O:stack_effect", + &opcode, &oparg)) + goto exit; + _return_value = _opcode_stack_effect_impl(module, opcode, oparg); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} +/*[clinic end generated code: output=8ee7cb735705e8b3 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_pickle.c.h b/Modules/clinic/_pickle.c.h new file mode 100644 index 000000000000..b698ce81bd34 --- /dev/null +++ b/Modules/clinic/_pickle.c.h @@ -0,0 +1,548 @@ +/*[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)\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 and 4. The default\n" +"protocol is 3; a backward-incompatible protocol designed for Python 3.\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, a 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."); + +static int +_pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, + PyObject *protocol, int fix_imports); + +static int +_pickle_Pickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static char *_keywords[] = {"file", "protocol", "fix_imports", NULL}; + PyObject *file; + PyObject *protocol = NULL; + int fix_imports = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Op:Pickler", _keywords, + &file, &protocol, &fix_imports)) + goto exit; + return_value = _pickle_Pickler___init___impl((PicklerObject *)self, file, protocol, fix_imports); + +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)_pickle_Unpickler_find_class, METH_VARARGS, _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 *args) +{ + PyObject *return_value = NULL; + PyObject *module_name; + PyObject *global_name; + + if (!PyArg_UnpackTuple(args, "find_class", + 2, 2, + &module_name, &global_name)) + goto exit; + 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" +"--\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, a 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 compatiblity 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); + +static int +_pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + static char *_keywords[] = {"file", "fix_imports", "encoding", "errors", NULL}; + PyObject *file; + int fix_imports = 1; + const char *encoding = "ASCII"; + const char *errors = "strict"; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|$pss:Unpickler", _keywords, + &file, &fix_imports, &encoding, &errors)) + goto exit; + return_value = _pickle_Unpickler___init___impl((UnpicklerObject *)self, file, fix_imports, encoding, errors); + +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" +"--\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 and 4. The default\n" +"protocol is 3; a backward-incompatible protocol designed for Python 3.\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, a 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."); + +#define _PICKLE_DUMP_METHODDEF \ + {"dump", (PyCFunction)_pickle_dump, METH_VARARGS|METH_KEYWORDS, _pickle_dump__doc__}, + +static PyObject * +_pickle_dump_impl(PyModuleDef *module, PyObject *obj, PyObject *file, + PyObject *protocol, int fix_imports); + +static PyObject * +_pickle_dump(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"obj", "file", "protocol", "fix_imports", NULL}; + PyObject *obj; + PyObject *file; + PyObject *protocol = NULL; + int fix_imports = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O$p:dump", _keywords, + &obj, &file, &protocol, &fix_imports)) + goto exit; + return_value = _pickle_dump_impl(module, obj, file, protocol, fix_imports); + +exit: + return return_value; +} + +PyDoc_STRVAR(_pickle_dumps__doc__, +"dumps($module, /, obj, protocol=None, *, fix_imports=True)\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 and 4. The default\n" +"protocol is 3; a backward-incompatible protocol designed for Python 3.\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."); + +#define _PICKLE_DUMPS_METHODDEF \ + {"dumps", (PyCFunction)_pickle_dumps, METH_VARARGS|METH_KEYWORDS, _pickle_dumps__doc__}, + +static PyObject * +_pickle_dumps_impl(PyModuleDef *module, PyObject *obj, PyObject *protocol, + int fix_imports); + +static PyObject * +_pickle_dumps(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"obj", "protocol", "fix_imports", NULL}; + PyObject *obj; + PyObject *protocol = NULL; + int fix_imports = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O$p:dumps", _keywords, + &obj, &protocol, &fix_imports)) + goto exit; + return_value = _pickle_dumps_impl(module, obj, protocol, fix_imports); + +exit: + return return_value; +} + +PyDoc_STRVAR(_pickle_load__doc__, +"load($module, /, file, *, fix_imports=True, encoding=\'ASCII\',\n" +" errors=\'strict\')\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, a 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 compatiblity 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)_pickle_load, METH_VARARGS|METH_KEYWORDS, _pickle_load__doc__}, + +static PyObject * +_pickle_load_impl(PyModuleDef *module, PyObject *file, int fix_imports, + const char *encoding, const char *errors); + +static PyObject * +_pickle_load(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"file", "fix_imports", "encoding", "errors", NULL}; + PyObject *file; + int fix_imports = 1; + const char *encoding = "ASCII"; + const char *errors = "strict"; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|$pss:load", _keywords, + &file, &fix_imports, &encoding, &errors)) + goto exit; + return_value = _pickle_load_impl(module, file, fix_imports, encoding, errors); + +exit: + return return_value; +} + +PyDoc_STRVAR(_pickle_loads__doc__, +"loads($module, /, data, *, fix_imports=True, encoding=\'ASCII\',\n" +" errors=\'strict\')\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 compatiblity 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)_pickle_loads, METH_VARARGS|METH_KEYWORDS, _pickle_loads__doc__}, + +static PyObject * +_pickle_loads_impl(PyModuleDef *module, PyObject *data, int fix_imports, + const char *encoding, const char *errors); + +static PyObject * +_pickle_loads(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"data", "fix_imports", "encoding", "errors", NULL}; + PyObject *data; + int fix_imports = 1; + const char *encoding = "ASCII"; + const char *errors = "strict"; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|$pss:loads", _keywords, + &data, &fix_imports, &encoding, &errors)) + goto exit; + return_value = _pickle_loads_impl(module, data, fix_imports, encoding, errors); + +exit: + return return_value; +} +/*[clinic end generated code: output=06f3a5233298448e input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_sre.c.h b/Modules/clinic/_sre.c.h new file mode 100644 index 000000000000..6de470847ec5 --- /dev/null +++ b/Modules/clinic/_sre.c.h @@ -0,0 +1,693 @@ +/*[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(PyModuleDef *module); + +static PyObject * +_sre_getcodesize(PyModuleDef *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_getlower__doc__, +"getlower($module, character, flags, /)\n" +"--\n" +"\n"); + +#define _SRE_GETLOWER_METHODDEF \ + {"getlower", (PyCFunction)_sre_getlower, METH_VARARGS, _sre_getlower__doc__}, + +static int +_sre_getlower_impl(PyModuleDef *module, int character, int flags); + +static PyObject * +_sre_getlower(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int character; + int flags; + int _return_value; + + if (!PyArg_ParseTuple(args, "ii:getlower", + &character, &flags)) + goto exit; + _return_value = _sre_getlower_impl(module, character, flags); + 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=None, pos=0, endpos=sys.maxsize, *, pattern=None)\n" +"--\n" +"\n" +"Matches zero or more characters at the beginning of the string."); + +#define _SRE_SRE_PATTERN_MATCH_METHODDEF \ + {"match", (PyCFunction)_sre_SRE_Pattern_match, METH_VARARGS|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, + PyObject *pattern); + +static PyObject * +_sre_SRE_Pattern_match(PatternObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"string", "pos", "endpos", "pattern", NULL}; + PyObject *string = NULL; + Py_ssize_t pos = 0; + Py_ssize_t endpos = PY_SSIZE_T_MAX; + PyObject *pattern = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Onn$O:match", _keywords, + &string, &pos, &endpos, &pattern)) + goto exit; + return_value = _sre_SRE_Pattern_match_impl(self, string, pos, endpos, pattern); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_SRE_Pattern_fullmatch__doc__, +"fullmatch($self, /, string=None, pos=0, endpos=sys.maxsize, *,\n" +" pattern=None)\n" +"--\n" +"\n" +"Matches against all of the string"); + +#define _SRE_SRE_PATTERN_FULLMATCH_METHODDEF \ + {"fullmatch", (PyCFunction)_sre_SRE_Pattern_fullmatch, METH_VARARGS|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, + PyObject *pattern); + +static PyObject * +_sre_SRE_Pattern_fullmatch(PatternObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"string", "pos", "endpos", "pattern", NULL}; + PyObject *string = NULL; + Py_ssize_t pos = 0; + Py_ssize_t endpos = PY_SSIZE_T_MAX; + PyObject *pattern = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Onn$O:fullmatch", _keywords, + &string, &pos, &endpos, &pattern)) + goto exit; + return_value = _sre_SRE_Pattern_fullmatch_impl(self, string, pos, endpos, pattern); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_SRE_Pattern_search__doc__, +"search($self, /, string=None, pos=0, endpos=sys.maxsize, *,\n" +" pattern=None)\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)_sre_SRE_Pattern_search, METH_VARARGS|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, + PyObject *pattern); + +static PyObject * +_sre_SRE_Pattern_search(PatternObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"string", "pos", "endpos", "pattern", NULL}; + PyObject *string = NULL; + Py_ssize_t pos = 0; + Py_ssize_t endpos = PY_SSIZE_T_MAX; + PyObject *pattern = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Onn$O:search", _keywords, + &string, &pos, &endpos, &pattern)) + goto exit; + return_value = _sre_SRE_Pattern_search_impl(self, string, pos, endpos, pattern); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_SRE_Pattern_findall__doc__, +"findall($self, /, string=None, pos=0, endpos=sys.maxsize, *,\n" +" source=None)\n" +"--\n" +"\n" +"Return a list of all non-overlapping matches of pattern in string."); + +#define _SRE_SRE_PATTERN_FINDALL_METHODDEF \ + {"findall", (PyCFunction)_sre_SRE_Pattern_findall, METH_VARARGS|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, + PyObject *source); + +static PyObject * +_sre_SRE_Pattern_findall(PatternObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"string", "pos", "endpos", "source", NULL}; + PyObject *string = NULL; + Py_ssize_t pos = 0; + Py_ssize_t endpos = PY_SSIZE_T_MAX; + PyObject *source = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Onn$O:findall", _keywords, + &string, &pos, &endpos, &source)) + goto exit; + return_value = _sre_SRE_Pattern_findall_impl(self, string, pos, endpos, source); + +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)_sre_SRE_Pattern_finditer, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"string", "pos", "endpos", NULL}; + PyObject *string; + Py_ssize_t pos = 0; + Py_ssize_t endpos = PY_SSIZE_T_MAX; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|nn:finditer", _keywords, + &string, &pos, &endpos)) + goto exit; + 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)_sre_SRE_Pattern_scanner, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"string", "pos", "endpos", NULL}; + PyObject *string; + Py_ssize_t pos = 0; + Py_ssize_t endpos = PY_SSIZE_T_MAX; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|nn:scanner", _keywords, + &string, &pos, &endpos)) + goto exit; + 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=None, maxsplit=0, *, source=None)\n" +"--\n" +"\n" +"Split string by the occurrences of pattern."); + +#define _SRE_SRE_PATTERN_SPLIT_METHODDEF \ + {"split", (PyCFunction)_sre_SRE_Pattern_split, METH_VARARGS|METH_KEYWORDS, _sre_SRE_Pattern_split__doc__}, + +static PyObject * +_sre_SRE_Pattern_split_impl(PatternObject *self, PyObject *string, + Py_ssize_t maxsplit, PyObject *source); + +static PyObject * +_sre_SRE_Pattern_split(PatternObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"string", "maxsplit", "source", NULL}; + PyObject *string = NULL; + Py_ssize_t maxsplit = 0; + PyObject *source = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|On$O:split", _keywords, + &string, &maxsplit, &source)) + goto exit; + return_value = _sre_SRE_Pattern_split_impl(self, string, maxsplit, source); + +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)_sre_SRE_Pattern_sub, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"repl", "string", "count", NULL}; + PyObject *repl; + PyObject *string; + Py_ssize_t count = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|n:sub", _keywords, + &repl, &string, &count)) + goto exit; + 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)_sre_SRE_Pattern_subn, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"repl", "string", "count", NULL}; + PyObject *repl; + PyObject *string; + Py_ssize_t count = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|n:subn", _keywords, + &repl, &string, &count)) + goto exit; + 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_VARARGS|METH_KEYWORDS, _sre_SRE_Pattern___deepcopy____doc__}, + +static PyObject * +_sre_SRE_Pattern___deepcopy___impl(PatternObject *self, PyObject *memo); + +static PyObject * +_sre_SRE_Pattern___deepcopy__(PatternObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"memo", NULL}; + PyObject *memo; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:__deepcopy__", _keywords, + &memo)) + goto exit; + return_value = _sre_SRE_Pattern___deepcopy___impl(self, memo); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sre_compile__doc__, +"compile($module, /, pattern, flags, code, groups, groupindex,\n" +" indexgroup)\n" +"--\n" +"\n"); + +#define _SRE_COMPILE_METHODDEF \ + {"compile", (PyCFunction)_sre_compile, METH_VARARGS|METH_KEYWORDS, _sre_compile__doc__}, + +static PyObject * +_sre_compile_impl(PyModuleDef *module, PyObject *pattern, int flags, + PyObject *code, Py_ssize_t groups, PyObject *groupindex, + PyObject *indexgroup); + +static PyObject * +_sre_compile(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"pattern", "flags", "code", "groups", "groupindex", "indexgroup", NULL}; + PyObject *pattern; + int flags; + PyObject *code; + Py_ssize_t groups; + PyObject *groupindex; + PyObject *indexgroup; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiO!nOO:compile", _keywords, + &pattern, &flags, &PyList_Type, &code, &groups, &groupindex, &indexgroup)) + goto exit; + 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)_sre_SRE_Match_expand, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"template", NULL}; + PyObject *template; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:expand", _keywords, + &template)) + goto exit; + 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)_sre_SRE_Match_groups, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"default", NULL}; + PyObject *default_value = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:groups", _keywords, + &default_value)) + goto exit; + 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)_sre_SRE_Match_groupdict, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"default", NULL}; + PyObject *default_value = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:groupdict", _keywords, + &default_value)) + goto exit; + 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)_sre_SRE_Match_start, METH_VARARGS, _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 *args) +{ + PyObject *return_value = NULL; + PyObject *group = NULL; + Py_ssize_t _return_value; + + if (!PyArg_UnpackTuple(args, "start", + 0, 1, + &group)) + goto exit; + _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)_sre_SRE_Match_end, METH_VARARGS, _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 *args) +{ + PyObject *return_value = NULL; + PyObject *group = NULL; + Py_ssize_t _return_value; + + if (!PyArg_UnpackTuple(args, "end", + 0, 1, + &group)) + goto exit; + _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 MatchObject m, return the 2-tuple (m.start(group), m.end(group))."); + +#define _SRE_SRE_MATCH_SPAN_METHODDEF \ + {"span", (PyCFunction)_sre_SRE_Match_span, METH_VARARGS, _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 *args) +{ + PyObject *return_value = NULL; + PyObject *group = NULL; + + if (!PyArg_UnpackTuple(args, "span", + 0, 1, + &group)) + goto exit; + 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_VARARGS|METH_KEYWORDS, _sre_SRE_Match___deepcopy____doc__}, + +static PyObject * +_sre_SRE_Match___deepcopy___impl(MatchObject *self, PyObject *memo); + +static PyObject * +_sre_SRE_Match___deepcopy__(MatchObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"memo", NULL}; + PyObject *memo; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:__deepcopy__", _keywords, + &memo)) + goto exit; + return_value = _sre_SRE_Match___deepcopy___impl(self, memo); + +exit: + return return_value; +} + +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=d1d73ab2c5008bd4 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h new file mode 100644 index 000000000000..4dbc5d001079 --- /dev/null +++ b/Modules/clinic/_ssl.c.h @@ -0,0 +1,1105 @@ +/*[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(PyModuleDef *module, PyObject *path); + +static PyObject * +_ssl__test_decode_cert(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *path; + + if (!PyArg_Parse(arg, "O&:_test_decode_cert", PyUnicode_FSConverter, &path)) + goto exit; + return_value = _ssl__test_decode_cert_impl(module, path); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLSocket_peer_certificate__doc__, +"peer_certificate($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_PEER_CERTIFICATE_METHODDEF \ + {"peer_certificate", (PyCFunction)_ssl__SSLSocket_peer_certificate, METH_VARARGS, _ssl__SSLSocket_peer_certificate__doc__}, + +static PyObject * +_ssl__SSLSocket_peer_certificate_impl(PySSLSocket *self, int binary_mode); + +static PyObject * +_ssl__SSLSocket_peer_certificate(PySSLSocket *self, PyObject *args) +{ + PyObject *return_value = NULL; + int binary_mode = 0; + + if (!PyArg_ParseTuple(args, "|p:peer_certificate", + &binary_mode)) + goto exit; + return_value = _ssl__SSLSocket_peer_certificate_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 defined(OPENSSL_NPN_NEGOTIATED) + +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 /* defined(OPENSSL_NPN_NEGOTIATED) */ + +#if defined(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 /* defined(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 (!PyArg_Parse(arg, "y*:write", &b)) + 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.\n" +"\n" +"Returns the underlying socket object."); + +#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_tls_unique_cb__doc__, +"tls_unique_cb($self, /)\n" +"--\n" +"\n" +"Returns the \'tls-unique\' channel binding data, as defined by RFC 5929.\n" +"\n" +"If the TLS handshake is not yet complete, None is returned."); + +#define _SSL__SSLSOCKET_TLS_UNIQUE_CB_METHODDEF \ + {"tls_unique_cb", (PyCFunction)_ssl__SSLSocket_tls_unique_cb, METH_NOARGS, _ssl__SSLSocket_tls_unique_cb__doc__}, + +static PyObject * +_ssl__SSLSocket_tls_unique_cb_impl(PySSLSocket *self); + +static PyObject * +_ssl__SSLSocket_tls_unique_cb(PySSLSocket *self, PyObject *Py_UNUSED(ignored)) +{ + return _ssl__SSLSocket_tls_unique_cb_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_ParseTuple(args, "i:_SSLContext", + &proto_version)) + 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 (!PyArg_Parse(arg, "s:set_ciphers", &cipherlist)) + goto exit; + return_value = _ssl__SSLContext_set_ciphers_impl(self, cipherlist); + +exit: + return return_value; +} + +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 (!PyArg_Parse(arg, "y*:_set_npn_protocols", &protos)) + 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 (!PyArg_Parse(arg, "y*:_set_alpn_protocols", &protos)) + 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)_ssl__SSLContext_load_cert_chain, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"certfile", "keyfile", "password", NULL}; + PyObject *certfile; + PyObject *keyfile = NULL; + PyObject *password = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OO:load_cert_chain", _keywords, + &certfile, &keyfile, &password)) + goto exit; + 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)_ssl__SSLContext_load_verify_locations, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"cafile", "capath", "cadata", NULL}; + PyObject *cafile = NULL; + PyObject *capath = NULL; + PyObject *cadata = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOO:load_verify_locations", _keywords, + &cafile, &capath, &cadata)) + goto exit; + 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" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT__WRAP_SOCKET_METHODDEF \ + {"_wrap_socket", (PyCFunction)_ssl__SSLContext__wrap_socket, METH_VARARGS|METH_KEYWORDS, _ssl__SSLContext__wrap_socket__doc__}, + +static PyObject * +_ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock, + int server_side, PyObject *hostname_obj); + +static PyObject * +_ssl__SSLContext__wrap_socket(PySSLContext *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"sock", "server_side", "server_hostname", NULL}; + PyObject *sock; + int server_side; + PyObject *hostname_obj = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!i|O:_wrap_socket", _keywords, + PySocketModule.Sock_Type, &sock, &server_side, &hostname_obj)) + goto exit; + return_value = _ssl__SSLContext__wrap_socket_impl(self, sock, server_side, hostname_obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_ssl__SSLContext__wrap_bio__doc__, +"_wrap_bio($self, /, incoming, outgoing, server_side,\n" +" server_hostname=None)\n" +"--\n" +"\n"); + +#define _SSL__SSLCONTEXT__WRAP_BIO_METHODDEF \ + {"_wrap_bio", (PyCFunction)_ssl__SSLContext__wrap_bio, METH_VARARGS|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); + +static PyObject * +_ssl__SSLContext__wrap_bio(PySSLContext *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"incoming", "outgoing", "server_side", "server_hostname", NULL}; + PySSLMemoryBIO *incoming; + PySSLMemoryBIO *outgoing; + int server_side; + PyObject *hostname_obj = Py_None; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!i|O:_wrap_bio", _keywords, + &PySSLMemoryBIO_Type, &incoming, &PySSLMemoryBIO_Type, &outgoing, &server_side, &hostname_obj)) + goto exit; + return_value = _ssl__SSLContext__wrap_bio_impl(self, incoming, outgoing, server_side, hostname_obj); + +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_set_servername_callback__doc__, +"set_servername_callback($self, method, /)\n" +"--\n" +"\n" +"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."); + +#define _SSL__SSLCONTEXT_SET_SERVERNAME_CALLBACK_METHODDEF \ + {"set_servername_callback", (PyCFunction)_ssl__SSLContext_set_servername_callback, METH_O, _ssl__SSLContext_set_servername_callback__doc__}, + +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)_ssl__SSLContext_get_ca_certs, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"binary_form", NULL}; + int binary_form = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|p:get_ca_certs", _keywords, + &binary_form)) + goto exit; + 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)_ssl_MemoryBIO_read, METH_VARARGS, _ssl_MemoryBIO_read__doc__}, + +static PyObject * +_ssl_MemoryBIO_read_impl(PySSLMemoryBIO *self, int len); + +static PyObject * +_ssl_MemoryBIO_read(PySSLMemoryBIO *self, PyObject *args) +{ + PyObject *return_value = NULL; + int len = -1; + + if (!PyArg_ParseTuple(args, "|i:read", + &len)) + goto exit; + 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 (!PyArg_Parse(arg, "y*:write", &b)) + 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 1750."); + +#define _SSL_RAND_ADD_METHODDEF \ + {"RAND_add", (PyCFunction)_ssl_RAND_add, METH_VARARGS, _ssl_RAND_add__doc__}, + +static PyObject * +_ssl_RAND_add_impl(PyModuleDef *module, Py_buffer *view, double entropy); + +static PyObject * +_ssl_RAND_add(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer view = {NULL, NULL}; + double entropy; + + if (!PyArg_ParseTuple(args, "s*d:RAND_add", + &view, &entropy)) + 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(PyModuleDef *module, int n); + +static PyObject * +_ssl_RAND_bytes(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int n; + + if (!PyArg_Parse(arg, "i:RAND_bytes", &n)) + 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(PyModuleDef *module, int n); + +static PyObject * +_ssl_RAND_pseudo_bytes(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int n; + + if (!PyArg_Parse(arg, "i:RAND_pseudo_bytes", &n)) + 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(PyModuleDef *module); + +static PyObject * +_ssl_RAND_status(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return _ssl_RAND_status_impl(module); +} + +#if defined(HAVE_RAND_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(PyModuleDef *module, PyObject *path); + +static PyObject * +_ssl_RAND_egd(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *path; + + if (!PyArg_Parse(arg, "O&:RAND_egd", PyUnicode_FSConverter, &path)) + goto exit; + return_value = _ssl_RAND_egd_impl(module, path); + +exit: + return return_value; +} + +#endif /* defined(HAVE_RAND_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(PyModuleDef *module); + +static PyObject * +_ssl_get_default_verify_paths(PyModuleDef *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)_ssl_txt2obj, METH_VARARGS|METH_KEYWORDS, _ssl_txt2obj__doc__}, + +static PyObject * +_ssl_txt2obj_impl(PyModuleDef *module, const char *txt, int name); + +static PyObject * +_ssl_txt2obj(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"txt", "name", NULL}; + const char *txt; + int name = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|p:txt2obj", _keywords, + &txt, &name)) + goto exit; + 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(PyModuleDef *module, int nid); + +static PyObject * +_ssl_nid2obj(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int nid; + + if (!PyArg_Parse(arg, "i:nid2obj", &nid)) + 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)_ssl_enum_certificates, METH_VARARGS|METH_KEYWORDS, _ssl_enum_certificates__doc__}, + +static PyObject * +_ssl_enum_certificates_impl(PyModuleDef *module, const char *store_name); + +static PyObject * +_ssl_enum_certificates(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"store_name", NULL}; + const char *store_name; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s:enum_certificates", _keywords, + &store_name)) + 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)_ssl_enum_crls, METH_VARARGS|METH_KEYWORDS, _ssl_enum_crls__doc__}, + +static PyObject * +_ssl_enum_crls_impl(PyModuleDef *module, const char *store_name); + +static PyObject * +_ssl_enum_crls(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"store_name", NULL}; + const char *store_name; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s:enum_crls", _keywords, + &store_name)) + 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_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=a14999cb565a69a2 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_tkinter.c.h b/Modules/clinic/_tkinter.c.h new file mode 100644 index 000000000000..7917dec9c41c --- /dev/null +++ b/Modules/clinic/_tkinter.c.h @@ -0,0 +1,624 @@ +/*[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 (!PyArg_Parse(arg, "s:eval", &script)) + 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 (!PyArg_Parse(arg, "s:evalfile", &fileName)) + 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 (!PyArg_Parse(arg, "s:record", &script)) + goto exit; + return_value = _tkinter_tkapp_record_impl(self, script); + +exit: + return return_value; +} + +PyDoc_STRVAR(_tkinter_tkapp_adderrinfo__doc__, +"adderrinfo($self, msg, /)\n" +"--\n" +"\n"); + +#define _TKINTER_TKAPP_ADDERRINFO_METHODDEF \ + {"adderrinfo", (PyCFunction)_tkinter_tkapp_adderrinfo, METH_O, _tkinter_tkapp_adderrinfo__doc__}, + +static PyObject * +_tkinter_tkapp_adderrinfo_impl(TkappObject *self, const char *msg); + +static PyObject * +_tkinter_tkapp_adderrinfo(TkappObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *msg; + + if (!PyArg_Parse(arg, "s:adderrinfo", &msg)) + goto exit; + return_value = _tkinter_tkapp_adderrinfo_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 (!PyArg_Parse(arg, "s:exprstring", &s)) + 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 (!PyArg_Parse(arg, "s:exprlong", &s)) + 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 (!PyArg_Parse(arg, "s:exprdouble", &s)) + 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 (!PyArg_Parse(arg, "s:exprboolean", &s)) + 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)_tkinter_tkapp_createcommand, METH_VARARGS, _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 *args) +{ + PyObject *return_value = NULL; + const char *name; + PyObject *func; + + if (!PyArg_ParseTuple(args, "sO:createcommand", + &name, &func)) + goto exit; + 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 (!PyArg_Parse(arg, "s:deletecommand", &name)) + 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)_tkinter_tkapp_createfilehandler, METH_VARARGS, _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 *args) +{ + PyObject *return_value = NULL; + PyObject *file; + int mask; + PyObject *func; + + if (!PyArg_ParseTuple(args, "OiO:createfilehandler", + &file, &mask, &func)) + goto exit; + 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)_tkinter_tkapp_createtimerhandler, METH_VARARGS, _tkinter_tkapp_createtimerhandler__doc__}, + +static PyObject * +_tkinter_tkapp_createtimerhandler_impl(TkappObject *self, int milliseconds, + PyObject *func); + +static PyObject * +_tkinter_tkapp_createtimerhandler(TkappObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int milliseconds; + PyObject *func; + + if (!PyArg_ParseTuple(args, "iO:createtimerhandler", + &milliseconds, &func)) + goto exit; + 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)_tkinter_tkapp_mainloop, METH_VARARGS, _tkinter_tkapp_mainloop__doc__}, + +static PyObject * +_tkinter_tkapp_mainloop_impl(TkappObject *self, int threshold); + +static PyObject * +_tkinter_tkapp_mainloop(TkappObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int threshold = 0; + + if (!PyArg_ParseTuple(args, "|i:mainloop", + &threshold)) + goto exit; + 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)_tkinter_tkapp_dooneevent, METH_VARARGS, _tkinter_tkapp_dooneevent__doc__}, + +static PyObject * +_tkinter_tkapp_dooneevent_impl(TkappObject *self, int flags); + +static PyObject * +_tkinter_tkapp_dooneevent(TkappObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int flags = 0; + + if (!PyArg_ParseTuple(args, "|i:dooneevent", + &flags)) + goto exit; + 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=None, 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)_tkinter_create, METH_VARARGS, _tkinter_create__doc__}, + +static PyObject * +_tkinter_create_impl(PyModuleDef *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(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + const char *screenName = NULL; + const char *baseName = NULL; + const char *className = "Tk"; + int interactive = 0; + int wantobjects = 0; + int wantTk = 1; + int sync = 0; + const char *use = NULL; + + if (!PyArg_ParseTuple(args, "|zssiiiiz:create", + &screenName, &baseName, &className, &interactive, &wantobjects, &wantTk, &sync, &use)) + goto exit; + 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(PyModuleDef *module, int new_val); + +static PyObject * +_tkinter_setbusywaitinterval(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int new_val; + + if (!PyArg_Parse(arg, "i:setbusywaitinterval", &new_val)) + 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(PyModuleDef *module); + +static PyObject * +_tkinter_getbusywaitinterval(PyModuleDef *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=6dd667b91cf8addd input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_weakref.c.h b/Modules/clinic/_weakref.c.h new file mode 100644 index 000000000000..87c701c52f65 --- /dev/null +++ b/Modules/clinic/_weakref.c.h @@ -0,0 +1,31 @@ +/*[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(PyModuleDef *module, PyObject *object); + +static PyObject * +_weakref_getweakrefcount(PyModuleDef *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; +} +/*[clinic end generated code: output=4da9aade63eed77f input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_winapi.c.h b/Modules/clinic/_winapi.c.h new file mode 100644 index 000000000000..34518e836bcd --- /dev/null +++ b/Modules/clinic/_winapi.c.h @@ -0,0 +1,854 @@ +/*[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; + + if (!PyArg_Parse(arg, "p:GetOverlappedResult", &wait)) + 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(PyModuleDef *module, HANDLE handle); + +static PyObject * +_winapi_CloseHandle(PyModuleDef *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)_winapi_ConnectNamedPipe, METH_VARARGS|METH_KEYWORDS, _winapi_ConnectNamedPipe__doc__}, + +static PyObject * +_winapi_ConnectNamedPipe_impl(PyModuleDef *module, HANDLE handle, + int use_overlapped); + +static PyObject * +_winapi_ConnectNamedPipe(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"handle", "overlapped", NULL}; + HANDLE handle; + int use_overlapped = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "" F_HANDLE "|i:ConnectNamedPipe", _keywords, + &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)_winapi_CreateFile, METH_VARARGS, _winapi_CreateFile__doc__}, + +static HANDLE +_winapi_CreateFile_impl(PyModuleDef *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(PyModuleDef *module, PyObject *args) +{ + 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_ParseTuple(args, "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_CreateJunction__doc__, +"CreateJunction($module, src_path, dst_path, /)\n" +"--\n" +"\n"); + +#define _WINAPI_CREATEJUNCTION_METHODDEF \ + {"CreateJunction", (PyCFunction)_winapi_CreateJunction, METH_VARARGS, _winapi_CreateJunction__doc__}, + +static PyObject * +_winapi_CreateJunction_impl(PyModuleDef *module, LPWSTR src_path, + LPWSTR dst_path); + +static PyObject * +_winapi_CreateJunction(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + LPWSTR src_path; + LPWSTR dst_path; + + if (!PyArg_ParseTuple(args, "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)_winapi_CreateNamedPipe, METH_VARARGS, _winapi_CreateNamedPipe__doc__}, + +static HANDLE +_winapi_CreateNamedPipe_impl(PyModuleDef *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(PyModuleDef *module, PyObject *args) +{ + 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_ParseTuple(args, "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)_winapi_CreatePipe, METH_VARARGS, _winapi_CreatePipe__doc__}, + +static PyObject * +_winapi_CreatePipe_impl(PyModuleDef *module, PyObject *pipe_attrs, + DWORD size); + +static PyObject * +_winapi_CreatePipe(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *pipe_attrs; + DWORD size; + + if (!PyArg_ParseTuple(args, "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" +" 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)_winapi_CreateProcess, METH_VARARGS, _winapi_CreateProcess__doc__}, + +static PyObject * +_winapi_CreateProcess_impl(PyModuleDef *module, Py_UNICODE *application_name, + Py_UNICODE *command_line, PyObject *proc_attrs, + PyObject *thread_attrs, BOOL inherit_handles, + DWORD creation_flags, PyObject *env_mapping, + Py_UNICODE *current_directory, + PyObject *startup_info); + +static PyObject * +_winapi_CreateProcess(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_UNICODE *application_name; + Py_UNICODE *command_line; + PyObject *proc_attrs; + PyObject *thread_attrs; + BOOL inherit_handles; + DWORD creation_flags; + PyObject *env_mapping; + Py_UNICODE *current_directory; + PyObject *startup_info; + + if (!PyArg_ParseTuple(args, "ZZOOikOZO: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)_winapi_DuplicateHandle, METH_VARARGS, _winapi_DuplicateHandle__doc__}, + +static HANDLE +_winapi_DuplicateHandle_impl(PyModuleDef *module, + HANDLE source_process_handle, + HANDLE source_handle, + HANDLE target_process_handle, + DWORD desired_access, BOOL inherit_handle, + DWORD options); + +static PyObject * +_winapi_DuplicateHandle(PyModuleDef *module, PyObject *args) +{ + 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_ParseTuple(args, "" 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(PyModuleDef *module, UINT ExitCode); + +static PyObject * +_winapi_ExitProcess(PyModuleDef *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(PyModuleDef *module); + +static PyObject * +_winapi_GetCurrentProcess(PyModuleDef *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(PyModuleDef *module, HANDLE process); + +static PyObject * +_winapi_GetExitCodeProcess(PyModuleDef *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 == 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(PyModuleDef *module); + +static PyObject * +_winapi_GetLastError(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + DWORD _return_value; + + _return_value = _winapi_GetLastError_impl(module); + if ((_return_value == 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(PyModuleDef *module, HMODULE module_handle); + +static PyObject * +_winapi_GetModuleFileName(PyModuleDef *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(PyModuleDef *module, DWORD std_handle); + +static PyObject * +_winapi_GetStdHandle(PyModuleDef *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(PyModuleDef *module); + +static PyObject * +_winapi_GetVersion(PyModuleDef *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_OpenProcess__doc__, +"OpenProcess($module, desired_access, inherit_handle, process_id, /)\n" +"--\n" +"\n"); + +#define _WINAPI_OPENPROCESS_METHODDEF \ + {"OpenProcess", (PyCFunction)_winapi_OpenProcess, METH_VARARGS, _winapi_OpenProcess__doc__}, + +static HANDLE +_winapi_OpenProcess_impl(PyModuleDef *module, DWORD desired_access, + BOOL inherit_handle, DWORD process_id); + +static PyObject * +_winapi_OpenProcess(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + DWORD desired_access; + BOOL inherit_handle; + DWORD process_id; + HANDLE _return_value; + + if (!PyArg_ParseTuple(args, "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)_winapi_PeekNamedPipe, METH_VARARGS, _winapi_PeekNamedPipe__doc__}, + +static PyObject * +_winapi_PeekNamedPipe_impl(PyModuleDef *module, HANDLE handle, int size); + +static PyObject * +_winapi_PeekNamedPipe(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + HANDLE handle; + int size = 0; + + if (!PyArg_ParseTuple(args, "" 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)_winapi_ReadFile, METH_VARARGS|METH_KEYWORDS, _winapi_ReadFile__doc__}, + +static PyObject * +_winapi_ReadFile_impl(PyModuleDef *module, HANDLE handle, int size, + int use_overlapped); + +static PyObject * +_winapi_ReadFile(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"handle", "size", "overlapped", NULL}; + HANDLE handle; + int size; + int use_overlapped = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "" F_HANDLE "i|i:ReadFile", _keywords, + &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)_winapi_SetNamedPipeHandleState, METH_VARARGS, _winapi_SetNamedPipeHandleState__doc__}, + +static PyObject * +_winapi_SetNamedPipeHandleState_impl(PyModuleDef *module, HANDLE named_pipe, + PyObject *mode, + PyObject *max_collection_count, + PyObject *collect_data_timeout); + +static PyObject * +_winapi_SetNamedPipeHandleState(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + HANDLE named_pipe; + PyObject *mode; + PyObject *max_collection_count; + PyObject *collect_data_timeout; + + if (!PyArg_ParseTuple(args, "" 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)_winapi_TerminateProcess, METH_VARARGS, _winapi_TerminateProcess__doc__}, + +static PyObject * +_winapi_TerminateProcess_impl(PyModuleDef *module, HANDLE handle, + UINT exit_code); + +static PyObject * +_winapi_TerminateProcess(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + HANDLE handle; + UINT exit_code; + + if (!PyArg_ParseTuple(args, "" 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_WaitNamedPipe__doc__, +"WaitNamedPipe($module, name, timeout, /)\n" +"--\n" +"\n"); + +#define _WINAPI_WAITNAMEDPIPE_METHODDEF \ + {"WaitNamedPipe", (PyCFunction)_winapi_WaitNamedPipe, METH_VARARGS, _winapi_WaitNamedPipe__doc__}, + +static PyObject * +_winapi_WaitNamedPipe_impl(PyModuleDef *module, LPCTSTR name, DWORD timeout); + +static PyObject * +_winapi_WaitNamedPipe(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + LPCTSTR name; + DWORD timeout; + + if (!PyArg_ParseTuple(args, "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)_winapi_WaitForMultipleObjects, METH_VARARGS, _winapi_WaitForMultipleObjects__doc__}, + +static PyObject * +_winapi_WaitForMultipleObjects_impl(PyModuleDef *module, + PyObject *handle_seq, BOOL wait_flag, + DWORD milliseconds); + +static PyObject * +_winapi_WaitForMultipleObjects(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *handle_seq; + BOOL wait_flag; + DWORD milliseconds = INFINITE; + + if (!PyArg_ParseTuple(args, "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)_winapi_WaitForSingleObject, METH_VARARGS, _winapi_WaitForSingleObject__doc__}, + +static long +_winapi_WaitForSingleObject_impl(PyModuleDef *module, HANDLE handle, + DWORD milliseconds); + +static PyObject * +_winapi_WaitForSingleObject(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + HANDLE handle; + DWORD milliseconds; + long _return_value; + + if (!PyArg_ParseTuple(args, "" 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)_winapi_WriteFile, METH_VARARGS|METH_KEYWORDS, _winapi_WriteFile__doc__}, + +static PyObject * +_winapi_WriteFile_impl(PyModuleDef *module, HANDLE handle, PyObject *buffer, + int use_overlapped); + +static PyObject * +_winapi_WriteFile(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"handle", "buffer", "overlapped", NULL}; + HANDLE handle; + PyObject *buffer; + int use_overlapped = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "" F_HANDLE "O|i:WriteFile", _keywords, + &handle, &buffer, &use_overlapped)) + goto exit; + return_value = _winapi_WriteFile_impl(module, handle, buffer, use_overlapped); + +exit: + return return_value; +} +/*[clinic end generated code: output=98771c6584056d19 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/arraymodule.c.h b/Modules/clinic/arraymodule.c.h new file mode 100644 index 000000000000..fdf247e2ca60 --- /dev/null +++ b/Modules/clinic/arraymodule.c.h @@ -0,0 +1,499 @@ +/*[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)array_array_pop, METH_VARARGS, array_array_pop__doc__}, + +static PyObject * +array_array_pop_impl(arrayobject *self, Py_ssize_t i); + +static PyObject * +array_array_pop(arrayobject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t i = -1; + + if (!PyArg_ParseTuple(args, "|n:pop", + &i)) + goto exit; + 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)array_array_insert, METH_VARARGS, 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 *args) +{ + PyObject *return_value = NULL; + Py_ssize_t i; + PyObject *v; + + if (!PyArg_ParseTuple(args, "nO:insert", + &i, &v)) + goto exit; + 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)array_array_fromfile, METH_VARARGS, 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 *args) +{ + PyObject *return_value = NULL; + PyObject *f; + Py_ssize_t n; + + if (!PyArg_ParseTuple(args, "On:fromfile", + &f, &n)) + goto exit; + 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 (!PyArg_Parse(arg, "s*:fromstring", &buffer)) + 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 (!PyArg_Parse(arg, "y*:frombytes", &buffer)) + 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, Py_UNICODE *ustr, + Py_ssize_clean_t ustr_length); + +static PyObject * +array_array_fromunicode(arrayobject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + 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)array__array_reconstructor, METH_VARARGS, array__array_reconstructor__doc__}, + +static PyObject * +array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, + int typecode, + enum machine_format_code mformat_code, + PyObject *items); + +static PyObject * +array__array_reconstructor(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyTypeObject *arraytype; + int typecode; + enum machine_format_code mformat_code; + PyObject *items; + + if (!PyArg_ParseTuple(args, "OCiO:_array_reconstructor", + &arraytype, &typecode, &mformat_code, &items)) + goto exit; + 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=d2e82c65ea841cfc input=a9049054013a1b77]*/ diff --git a/Modules/clinic/audioop.c.h b/Modules/clinic/audioop.c.h new file mode 100644 index 000000000000..3ee29666cc3e --- /dev/null +++ b/Modules/clinic/audioop.c.h @@ -0,0 +1,877 @@ +/*[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)audioop_getsample, METH_VARARGS, audioop_getsample__doc__}, + +static PyObject * +audioop_getsample_impl(PyModuleDef *module, Py_buffer *fragment, int width, + Py_ssize_t index); + +static PyObject * +audioop_getsample(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + Py_ssize_t index; + + if (!PyArg_ParseTuple(args, "y*in:getsample", + &fragment, &width, &index)) + goto exit; + 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)audioop_max, METH_VARARGS, audioop_max__doc__}, + +static PyObject * +audioop_max_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_max(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, "y*i:max", + &fragment, &width)) + 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)audioop_minmax, METH_VARARGS, audioop_minmax__doc__}, + +static PyObject * +audioop_minmax_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_minmax(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, "y*i:minmax", + &fragment, &width)) + 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)audioop_avg, METH_VARARGS, audioop_avg__doc__}, + +static PyObject * +audioop_avg_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_avg(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, "y*i:avg", + &fragment, &width)) + 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)audioop_rms, METH_VARARGS, audioop_rms__doc__}, + +static PyObject * +audioop_rms_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_rms(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, "y*i:rms", + &fragment, &width)) + 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)audioop_findfit, METH_VARARGS, audioop_findfit__doc__}, + +static PyObject * +audioop_findfit_impl(PyModuleDef *module, Py_buffer *fragment, + Py_buffer *reference); + +static PyObject * +audioop_findfit(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + Py_buffer reference = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, "y*y*:findfit", + &fragment, &reference)) + 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)audioop_findfactor, METH_VARARGS, audioop_findfactor__doc__}, + +static PyObject * +audioop_findfactor_impl(PyModuleDef *module, Py_buffer *fragment, + Py_buffer *reference); + +static PyObject * +audioop_findfactor(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + Py_buffer reference = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, "y*y*:findfactor", + &fragment, &reference)) + 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)audioop_findmax, METH_VARARGS, audioop_findmax__doc__}, + +static PyObject * +audioop_findmax_impl(PyModuleDef *module, Py_buffer *fragment, + Py_ssize_t length); + +static PyObject * +audioop_findmax(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + Py_ssize_t length; + + if (!PyArg_ParseTuple(args, "y*n:findmax", + &fragment, &length)) + goto exit; + 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)audioop_avgpp, METH_VARARGS, audioop_avgpp__doc__}, + +static PyObject * +audioop_avgpp_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_avgpp(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, "y*i:avgpp", + &fragment, &width)) + 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)audioop_maxpp, METH_VARARGS, audioop_maxpp__doc__}, + +static PyObject * +audioop_maxpp_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_maxpp(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, "y*i:maxpp", + &fragment, &width)) + 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)audioop_cross, METH_VARARGS, audioop_cross__doc__}, + +static PyObject * +audioop_cross_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_cross(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, "y*i:cross", + &fragment, &width)) + 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)audioop_mul, METH_VARARGS, audioop_mul__doc__}, + +static PyObject * +audioop_mul_impl(PyModuleDef *module, Py_buffer *fragment, int width, + double factor); + +static PyObject * +audioop_mul(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + double factor; + + if (!PyArg_ParseTuple(args, "y*id:mul", + &fragment, &width, &factor)) + 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)audioop_tomono, METH_VARARGS, audioop_tomono__doc__}, + +static PyObject * +audioop_tomono_impl(PyModuleDef *module, Py_buffer *fragment, int width, + double lfactor, double rfactor); + +static PyObject * +audioop_tomono(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + double lfactor; + double rfactor; + + if (!PyArg_ParseTuple(args, "y*idd:tomono", + &fragment, &width, &lfactor, &rfactor)) + 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)audioop_tostereo, METH_VARARGS, audioop_tostereo__doc__}, + +static PyObject * +audioop_tostereo_impl(PyModuleDef *module, Py_buffer *fragment, int width, + double lfactor, double rfactor); + +static PyObject * +audioop_tostereo(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + double lfactor; + double rfactor; + + if (!PyArg_ParseTuple(args, "y*idd:tostereo", + &fragment, &width, &lfactor, &rfactor)) + 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)audioop_add, METH_VARARGS, audioop_add__doc__}, + +static PyObject * +audioop_add_impl(PyModuleDef *module, Py_buffer *fragment1, + Py_buffer *fragment2, int width); + +static PyObject * +audioop_add(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment1 = {NULL, NULL}; + Py_buffer fragment2 = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, "y*y*i:add", + &fragment1, &fragment2, &width)) + 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)audioop_bias, METH_VARARGS, audioop_bias__doc__}, + +static PyObject * +audioop_bias_impl(PyModuleDef *module, Py_buffer *fragment, int width, + int bias); + +static PyObject * +audioop_bias(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + int bias; + + if (!PyArg_ParseTuple(args, "y*ii:bias", + &fragment, &width, &bias)) + 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)audioop_reverse, METH_VARARGS, audioop_reverse__doc__}, + +static PyObject * +audioop_reverse_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_reverse(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, "y*i:reverse", + &fragment, &width)) + 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)audioop_byteswap, METH_VARARGS, audioop_byteswap__doc__}, + +static PyObject * +audioop_byteswap_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_byteswap(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, "y*i:byteswap", + &fragment, &width)) + 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)audioop_lin2lin, METH_VARARGS, audioop_lin2lin__doc__}, + +static PyObject * +audioop_lin2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width, + int newwidth); + +static PyObject * +audioop_lin2lin(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + int newwidth; + + if (!PyArg_ParseTuple(args, "y*ii:lin2lin", + &fragment, &width, &newwidth)) + 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)audioop_ratecv, METH_VARARGS, audioop_ratecv__doc__}, + +static PyObject * +audioop_ratecv_impl(PyModuleDef *module, Py_buffer *fragment, int width, + int nchannels, int inrate, int outrate, PyObject *state, + int weightA, int weightB); + +static PyObject * +audioop_ratecv(PyModuleDef *module, PyObject *args) +{ + 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_ParseTuple(args, "y*iiiiO|ii:ratecv", + &fragment, &width, &nchannels, &inrate, &outrate, &state, &weightA, &weightB)) + goto exit; + 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)audioop_lin2ulaw, METH_VARARGS, audioop_lin2ulaw__doc__}, + +static PyObject * +audioop_lin2ulaw_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_lin2ulaw(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, "y*i:lin2ulaw", + &fragment, &width)) + 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)audioop_ulaw2lin, METH_VARARGS, audioop_ulaw2lin__doc__}, + +static PyObject * +audioop_ulaw2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_ulaw2lin(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, "y*i:ulaw2lin", + &fragment, &width)) + 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)audioop_lin2alaw, METH_VARARGS, audioop_lin2alaw__doc__}, + +static PyObject * +audioop_lin2alaw_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_lin2alaw(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, "y*i:lin2alaw", + &fragment, &width)) + 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)audioop_alaw2lin, METH_VARARGS, audioop_alaw2lin__doc__}, + +static PyObject * +audioop_alaw2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width); + +static PyObject * +audioop_alaw2lin(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + + if (!PyArg_ParseTuple(args, "y*i:alaw2lin", + &fragment, &width)) + 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)audioop_lin2adpcm, METH_VARARGS, audioop_lin2adpcm__doc__}, + +static PyObject * +audioop_lin2adpcm_impl(PyModuleDef *module, Py_buffer *fragment, int width, + PyObject *state); + +static PyObject * +audioop_lin2adpcm(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + PyObject *state; + + if (!PyArg_ParseTuple(args, "y*iO:lin2adpcm", + &fragment, &width, &state)) + goto exit; + 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)audioop_adpcm2lin, METH_VARARGS, audioop_adpcm2lin__doc__}, + +static PyObject * +audioop_adpcm2lin_impl(PyModuleDef *module, Py_buffer *fragment, int width, + PyObject *state); + +static PyObject * +audioop_adpcm2lin(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer fragment = {NULL, NULL}; + int width; + PyObject *state; + + if (!PyArg_ParseTuple(args, "y*iO:adpcm2lin", + &fragment, &width, &state)) + goto exit; + 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=a076e1b213a8727b input=a9049054013a1b77]*/ diff --git a/Modules/clinic/binascii.c.h b/Modules/clinic/binascii.c.h new file mode 100644 index 000000000000..46cfb8ec3d84 --- /dev/null +++ b/Modules/clinic/binascii.c.h @@ -0,0 +1,522 @@ +/*[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(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_a2b_uu(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_Parse(arg, "O&:a2b_uu", ascii_buffer_converter, &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, /)\n" +"--\n" +"\n" +"Uuencode line of data."); + +#define BINASCII_B2A_UU_METHODDEF \ + {"b2a_uu", (PyCFunction)binascii_b2a_uu, METH_O, binascii_b2a_uu__doc__}, + +static PyObject * +binascii_b2a_uu_impl(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_b2a_uu(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_Parse(arg, "y*:b2a_uu", &data)) + goto exit; + return_value = binascii_b2a_uu_impl(module, &data); + +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(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_a2b_base64(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_Parse(arg, "O&:a2b_base64", ascii_buffer_converter, &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)binascii_b2a_base64, METH_VARARGS|METH_KEYWORDS, binascii_b2a_base64__doc__}, + +static PyObject * +binascii_b2a_base64_impl(PyModuleDef *module, Py_buffer *data, int newline); + +static PyObject * +binascii_b2a_base64(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"data", "newline", NULL}; + Py_buffer data = {NULL, NULL}; + int newline = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|$i:b2a_base64", _keywords, + &data, &newline)) + goto exit; + 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(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_a2b_hqx(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_Parse(arg, "O&:a2b_hqx", ascii_buffer_converter, &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(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_rlecode_hqx(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_Parse(arg, "y*:rlecode_hqx", &data)) + 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(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_b2a_hqx(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_Parse(arg, "y*:b2a_hqx", &data)) + 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(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_rledecode_hqx(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_Parse(arg, "y*:rledecode_hqx", &data)) + 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 hqx CRC incrementally."); + +#define BINASCII_CRC_HQX_METHODDEF \ + {"crc_hqx", (PyCFunction)binascii_crc_hqx, METH_VARARGS, binascii_crc_hqx__doc__}, + +static unsigned int +binascii_crc_hqx_impl(PyModuleDef *module, Py_buffer *data, unsigned int crc); + +static PyObject * +binascii_crc_hqx(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + unsigned int crc; + unsigned int _return_value; + + if (!PyArg_ParseTuple(args, "y*I:crc_hqx", + &data, &crc)) + 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)binascii_crc32, METH_VARARGS, binascii_crc32__doc__}, + +static unsigned int +binascii_crc32_impl(PyModuleDef *module, Py_buffer *data, unsigned int crc); + +static PyObject * +binascii_crc32(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + unsigned int crc = 0; + unsigned int _return_value; + + if (!PyArg_ParseTuple(args, "y*|I:crc32", + &data, &crc)) + goto exit; + _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, /)\n" +"--\n" +"\n" +"Hexadecimal representation of binary data.\n" +"\n" +"The return value is a bytes object. This function is also\n" +"available as \"hexlify()\"."); + +#define BINASCII_B2A_HEX_METHODDEF \ + {"b2a_hex", (PyCFunction)binascii_b2a_hex, METH_O, binascii_b2a_hex__doc__}, + +static PyObject * +binascii_b2a_hex_impl(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_b2a_hex(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_Parse(arg, "y*:b2a_hex", &data)) + goto exit; + return_value = binascii_b2a_hex_impl(module, &data); + +exit: + /* Cleanup for data */ + if (data.obj) + PyBuffer_Release(&data); + + return return_value; +} + +PyDoc_STRVAR(binascii_hexlify__doc__, +"hexlify($module, data, /)\n" +"--\n" +"\n" +"Hexadecimal representation of binary data.\n" +"\n" +"The return value is a bytes object."); + +#define BINASCII_HEXLIFY_METHODDEF \ + {"hexlify", (PyCFunction)binascii_hexlify, METH_O, binascii_hexlify__doc__}, + +static PyObject * +binascii_hexlify_impl(PyModuleDef *module, Py_buffer *data); + +static PyObject * +binascii_hexlify(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + + if (!PyArg_Parse(arg, "y*:hexlify", &data)) + goto exit; + return_value = binascii_hexlify_impl(module, &data); + +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(PyModuleDef *module, Py_buffer *hexstr); + +static PyObject * +binascii_a2b_hex(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer hexstr = {NULL, NULL}; + + if (!PyArg_Parse(arg, "O&:a2b_hex", ascii_buffer_converter, &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(PyModuleDef *module, Py_buffer *hexstr); + +static PyObject * +binascii_unhexlify(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_buffer hexstr = {NULL, NULL}; + + if (!PyArg_Parse(arg, "O&:unhexlify", ascii_buffer_converter, &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)binascii_a2b_qp, METH_VARARGS|METH_KEYWORDS, binascii_a2b_qp__doc__}, + +static PyObject * +binascii_a2b_qp_impl(PyModuleDef *module, Py_buffer *data, int header); + +static PyObject * +binascii_a2b_qp(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"data", "header", NULL}; + Py_buffer data = {NULL, NULL}; + int header = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i:a2b_qp", _keywords, + ascii_buffer_converter, &data, &header)) + goto exit; + 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)binascii_b2a_qp, METH_VARARGS|METH_KEYWORDS, binascii_b2a_qp__doc__}, + +static PyObject * +binascii_b2a_qp_impl(PyModuleDef *module, Py_buffer *data, int quotetabs, + int istext, int header); + +static PyObject * +binascii_b2a_qp(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"data", "quotetabs", "istext", "header", NULL}; + Py_buffer data = {NULL, NULL}; + int quotetabs = 0; + int istext = 1; + int header = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*|iii:b2a_qp", _keywords, + &data, "etabs, &istext, &header)) + goto exit; + 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=b15a24350d105251 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/cmathmodule.c.h b/Modules/clinic/cmathmodule.c.h new file mode 100644 index 000000000000..7d61649783ff --- /dev/null +++ b/Modules/clinic/cmathmodule.c.h @@ -0,0 +1,860 @@ +/*[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(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_acos(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_Parse(arg, "D:acos", &z)) + 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(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_acosh(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_Parse(arg, "D:acosh", &z)) + 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(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_asin(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_Parse(arg, "D:asin", &z)) + 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(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_asinh(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_Parse(arg, "D:asinh", &z)) + 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(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_atan(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_Parse(arg, "D:atan", &z)) + 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(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_atanh(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_Parse(arg, "D:atanh", &z)) + 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(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_cos(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_Parse(arg, "D:cos", &z)) + 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(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_cosh(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_Parse(arg, "D:cosh", &z)) + 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(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_exp(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_Parse(arg, "D:exp", &z)) + 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(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_log10(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_Parse(arg, "D:log10", &z)) + 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(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_sin(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_Parse(arg, "D:sin", &z)) + 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(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_sinh(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_Parse(arg, "D:sinh", &z)) + 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(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_sqrt(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_Parse(arg, "D:sqrt", &z)) + 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(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_tan(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_Parse(arg, "D:tan", &z)) + 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(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_tanh(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + Py_complex _return_value; + + if (!PyArg_Parse(arg, "D:tanh", &z)) + 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, x, y_obj=None, /)\n" +"--\n" +"\n" +"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)cmath_log, METH_VARARGS, cmath_log__doc__}, + +static PyObject * +cmath_log_impl(PyModuleDef *module, Py_complex x, PyObject *y_obj); + +static PyObject * +cmath_log(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_complex x; + PyObject *y_obj = NULL; + + if (!PyArg_ParseTuple(args, "D|O:log", + &x, &y_obj)) + goto exit; + 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(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_phase(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + + if (!PyArg_Parse(arg, "D:phase", &z)) + goto exit; + return_value = cmath_phase_impl(module, z); + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_polar__doc__, +"polar($module, z, /)\n" +"--\n" +"\n" +"Convert a complex from rectangular coordinates to polar coordinates.\n" +"\n" +"r is the distance from 0 and phi the phase angle."); + +#define CMATH_POLAR_METHODDEF \ + {"polar", (PyCFunction)cmath_polar, METH_O, cmath_polar__doc__}, + +static PyObject * +cmath_polar_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_polar(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + + if (!PyArg_Parse(arg, "D:polar", &z)) + 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)cmath_rect, METH_VARARGS, cmath_rect__doc__}, + +static PyObject * +cmath_rect_impl(PyModuleDef *module, double r, double phi); + +static PyObject * +cmath_rect(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + double r; + double phi; + + if (!PyArg_ParseTuple(args, "dd:rect", + &r, &phi)) + 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(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_isfinite(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + + if (!PyArg_Parse(arg, "D:isfinite", &z)) + goto exit; + return_value = cmath_isfinite_impl(module, z); + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_isnan__doc__, +"isnan($module, z, /)\n" +"--\n" +"\n" +"Checks if the real or imaginary part of z not a number (NaN)."); + +#define CMATH_ISNAN_METHODDEF \ + {"isnan", (PyCFunction)cmath_isnan, METH_O, cmath_isnan__doc__}, + +static PyObject * +cmath_isnan_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_isnan(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + + if (!PyArg_Parse(arg, "D:isnan", &z)) + goto exit; + return_value = cmath_isnan_impl(module, z); + +exit: + return return_value; +} + +PyDoc_STRVAR(cmath_isinf__doc__, +"isinf($module, z, /)\n" +"--\n" +"\n" +"Checks if the real or imaginary part of z is infinite."); + +#define CMATH_ISINF_METHODDEF \ + {"isinf", (PyCFunction)cmath_isinf, METH_O, cmath_isinf__doc__}, + +static PyObject * +cmath_isinf_impl(PyModuleDef *module, Py_complex z); + +static PyObject * +cmath_isinf(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_complex z; + + if (!PyArg_Parse(arg, "D:isinf", &z)) + 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)cmath_isclose, METH_VARARGS|METH_KEYWORDS, cmath_isclose__doc__}, + +static int +cmath_isclose_impl(PyModuleDef *module, Py_complex a, Py_complex b, + double rel_tol, double abs_tol); + +static PyObject * +cmath_isclose(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL}; + Py_complex a; + Py_complex b; + double rel_tol = 1e-09; + double abs_tol = 0.0; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "DD|$dd:isclose", _keywords, + &a, &b, &rel_tol, &abs_tol)) + goto exit; + _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=229e9c48c9d27362 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/fcntlmodule.c.h b/Modules/clinic/fcntlmodule.c.h new file mode 100644 index 000000000000..5e3b1c06f69a --- /dev/null +++ b/Modules/clinic/fcntlmodule.c.h @@ -0,0 +1,185 @@ +/*[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)fcntl_fcntl, METH_VARARGS, fcntl_fcntl__doc__}, + +static PyObject * +fcntl_fcntl_impl(PyModuleDef *module, int fd, int code, PyObject *arg); + +static PyObject * +fcntl_fcntl(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + int code; + PyObject *arg = NULL; + + if (!PyArg_ParseTuple(args, "O&i|O:fcntl", + conv_descriptor, &fd, &code, &arg)) + goto exit; + 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)fcntl_ioctl, METH_VARARGS, fcntl_ioctl__doc__}, + +static PyObject * +fcntl_ioctl_impl(PyModuleDef *module, int fd, unsigned int code, + PyObject *ob_arg, int mutate_arg); + +static PyObject * +fcntl_ioctl(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + unsigned int code; + PyObject *ob_arg = NULL; + int mutate_arg = 1; + + if (!PyArg_ParseTuple(args, "O&I|Op:ioctl", + conv_descriptor, &fd, &code, &ob_arg, &mutate_arg)) + goto exit; + 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)fcntl_flock, METH_VARARGS, fcntl_flock__doc__}, + +static PyObject * +fcntl_flock_impl(PyModuleDef *module, int fd, int code); + +static PyObject * +fcntl_flock(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + int code; + + if (!PyArg_ParseTuple(args, "O&i:flock", + conv_descriptor, &fd, &code)) + 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 IOError 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)fcntl_lockf, METH_VARARGS, fcntl_lockf__doc__}, + +static PyObject * +fcntl_lockf_impl(PyModuleDef *module, int fd, int code, PyObject *lenobj, + PyObject *startobj, int whence); + +static PyObject * +fcntl_lockf(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + int code; + PyObject *lenobj = NULL; + PyObject *startobj = NULL; + int whence = 0; + + if (!PyArg_ParseTuple(args, "O&i|OOi:lockf", + conv_descriptor, &fd, &code, &lenobj, &startobj, &whence)) + goto exit; + return_value = fcntl_lockf_impl(module, fd, code, lenobj, startobj, whence); + +exit: + return return_value; +} +/*[clinic end generated code: output=92963b631d00f0fe input=a9049054013a1b77]*/ diff --git a/Modules/clinic/grpmodule.c.h b/Modules/clinic/grpmodule.c.h new file mode 100644 index 000000000000..eb5b59d29bb1 --- /dev/null +++ b/Modules/clinic/grpmodule.c.h @@ -0,0 +1,85 @@ +/*[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)grp_getgrgid, METH_VARARGS|METH_KEYWORDS, grp_getgrgid__doc__}, + +static PyObject * +grp_getgrgid_impl(PyModuleDef *module, PyObject *id); + +static PyObject * +grp_getgrgid(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"id", NULL}; + PyObject *id; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:getgrgid", _keywords, + &id)) + goto exit; + 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)grp_getgrnam, METH_VARARGS|METH_KEYWORDS, grp_getgrnam__doc__}, + +static PyObject * +grp_getgrnam_impl(PyModuleDef *module, PyObject *name); + +static PyObject * +grp_getgrnam(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"name", NULL}; + PyObject *name; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U:getgrnam", _keywords, + &name)) + goto exit; + 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(PyModuleDef *module); + +static PyObject * +grp_getgrall(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return grp_getgrall_impl(module); +} +/*[clinic end generated code: output=5191c25600afb1bd input=a9049054013a1b77]*/ diff --git a/Modules/clinic/md5module.c.h b/Modules/clinic/md5module.c.h new file mode 100644 index 000000000000..f5a3117f1045 --- /dev/null +++ b/Modules/clinic/md5module.c.h @@ -0,0 +1,95 @@ +/*[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 string of binary data."); + +#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)_md5_md5, METH_VARARGS|METH_KEYWORDS, _md5_md5__doc__}, + +static PyObject * +_md5_md5_impl(PyModuleDef *module, PyObject *string); + +static PyObject * +_md5_md5(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"string", NULL}; + PyObject *string = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:md5", _keywords, + &string)) + goto exit; + return_value = _md5_md5_impl(module, string); + +exit: + return return_value; +} +/*[clinic end generated code: output=0f803ded701aca54 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h new file mode 100644 index 000000000000..a48de6ac882b --- /dev/null +++ b/Modules/clinic/posixmodule.c.h @@ -0,0 +1,5795 @@ +/*[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, 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 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)os_stat, METH_VARARGS|METH_KEYWORDS, os_stat__doc__}, + +static PyObject * +os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, + int follow_symlinks); + +static PyObject * +os_stat(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "dir_fd", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("stat", "path", 0, 1); + int dir_fd = DEFAULT_DIR_FD; + int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&p:stat", _keywords, + path_converter, &path, FSTATAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) + goto exit; + 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)os_lstat, METH_VARARGS|METH_KEYWORDS, os_lstat__doc__}, + +static PyObject * +os_lstat_impl(PyModuleDef *module, path_t *path, int dir_fd); + +static PyObject * +os_lstat(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("lstat", "path", 0, 0); + int dir_fd = DEFAULT_DIR_FD; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", _keywords, + path_converter, &path, FSTATAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + 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 open-file-descriptor int.\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)os_access, METH_VARARGS|METH_KEYWORDS, os_access__doc__}, + +static int +os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, + int effective_ids, int follow_symlinks); + +static PyObject * +os_access(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("access", "path", 0, 1); + int mode; + int dir_fd = DEFAULT_DIR_FD; + int effective_ids = 0; + int follow_symlinks = 1; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&pp:access", _keywords, + path_converter, &path, &mode, FACCESSAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks)) + goto exit; + _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 char * +os_ttyname_impl(PyModuleDef *module, int fd); + +static PyObject * +os_ttyname(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + char *_return_value; + + if (!PyArg_Parse(arg, "i:ttyname", &fd)) + goto exit; + _return_value = os_ttyname_impl(module, fd); + if (_return_value == NULL) + goto exit; + return_value = PyUnicode_DecodeFSDefault(_return_value); + +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(PyModuleDef *module); + +static PyObject * +os_ctermid(PyModuleDef *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)os_chdir, METH_VARARGS|METH_KEYWORDS, os_chdir__doc__}, + +static PyObject * +os_chdir_impl(PyModuleDef *module, path_t *path); + +static PyObject * +os_chdir(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", NULL}; + path_t path = PATH_T_INITIALIZE("chdir", "path", 0, PATH_HAVE_FCHDIR); + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", _keywords, + path_converter, &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)os_fchdir, METH_VARARGS|METH_KEYWORDS, os_fchdir__doc__}, + +static PyObject * +os_fchdir_impl(PyModuleDef *module, int fd); + +static PyObject * +os_fchdir(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", NULL}; + int fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:fchdir", _keywords, + fildes_converter, &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 or bytes.\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)os_chmod, METH_VARARGS|METH_KEYWORDS, os_chmod__doc__}, + +static PyObject * +os_chmod_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, + int follow_symlinks); + +static PyObject * +os_chmod(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "mode", "dir_fd", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("chmod", "path", 0, PATH_HAVE_FCHMOD); + int mode; + int dir_fd = DEFAULT_DIR_FD; + int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", _keywords, + path_converter, &path, &mode, FCHMODAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) + goto exit; + 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)os_fchmod, METH_VARARGS|METH_KEYWORDS, os_fchmod__doc__}, + +static PyObject * +os_fchmod_impl(PyModuleDef *module, int fd, int mode); + +static PyObject * +os_fchmod(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", "mode", NULL}; + int fd; + int mode; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:fchmod", _keywords, + &fd, &mode)) + 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)os_lchmod, METH_VARARGS|METH_KEYWORDS, os_lchmod__doc__}, + +static PyObject * +os_lchmod_impl(PyModuleDef *module, path_t *path, int mode); + +static PyObject * +os_lchmod(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "mode", NULL}; + path_t path = PATH_T_INITIALIZE("lchmod", "path", 0, 0); + int mode; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i:lchmod", _keywords, + path_converter, &path, &mode)) + 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)os_chflags, METH_VARARGS|METH_KEYWORDS, os_chflags__doc__}, + +static PyObject * +os_chflags_impl(PyModuleDef *module, path_t *path, unsigned long flags, + int follow_symlinks); + +static PyObject * +os_chflags(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "flags", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("chflags", "path", 0, 0); + unsigned long flags; + int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|p:chflags", _keywords, + path_converter, &path, &flags, &follow_symlinks)) + goto exit; + 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)os_lchflags, METH_VARARGS|METH_KEYWORDS, os_lchflags__doc__}, + +static PyObject * +os_lchflags_impl(PyModuleDef *module, path_t *path, unsigned long flags); + +static PyObject * +os_lchflags(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "flags", NULL}; + path_t path = PATH_T_INITIALIZE("lchflags", "path", 0, 0); + unsigned long flags; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k:lchflags", _keywords, + path_converter, &path, &flags)) + goto exit; + 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)os_chroot, METH_VARARGS|METH_KEYWORDS, os_chroot__doc__}, + +static PyObject * +os_chroot_impl(PyModuleDef *module, path_t *path); + +static PyObject * +os_chroot(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", NULL}; + path_t path = PATH_T_INITIALIZE("chroot", "path", 0, 0); + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chroot", _keywords, + path_converter, &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)os_fsync, METH_VARARGS|METH_KEYWORDS, os_fsync__doc__}, + +static PyObject * +os_fsync_impl(PyModuleDef *module, int fd); + +static PyObject * +os_fsync(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", NULL}; + int fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:fsync", _keywords, + fildes_converter, &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(PyModuleDef *module); + +static PyObject * +os_sync(PyModuleDef *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)os_fdatasync, METH_VARARGS|METH_KEYWORDS, os_fdatasync__doc__}, + +static PyObject * +os_fdatasync_impl(PyModuleDef *module, int fd); + +static PyObject * +os_fdatasync(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", NULL}; + int fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:fdatasync", _keywords, + fildes_converter, &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, 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)os_chown, METH_VARARGS|METH_KEYWORDS, os_chown__doc__}, + +static PyObject * +os_chown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid, + int dir_fd, int follow_symlinks); + +static PyObject * +os_chown(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "uid", "gid", "dir_fd", "follow_symlinks", NULL}; + 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; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", _keywords, + path_converter, &path, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &gid, FCHOWNAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) + goto exit; + 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)os_fchown, METH_VARARGS|METH_KEYWORDS, os_fchown__doc__}, + +static PyObject * +os_fchown_impl(PyModuleDef *module, int fd, uid_t uid, gid_t gid); + +static PyObject * +os_fchown(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", "uid", "gid", NULL}; + int fd; + uid_t uid; + gid_t gid; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO&O&:fchown", _keywords, + &fd, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &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)os_lchown, METH_VARARGS|METH_KEYWORDS, os_lchown__doc__}, + +static PyObject * +os_lchown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid); + +static PyObject * +os_lchown(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "uid", "gid", NULL}; + path_t path = PATH_T_INITIALIZE("lchown", "path", 0, 0); + uid_t uid; + gid_t gid; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&:lchown", _keywords, + path_converter, &path, _Py_Uid_Converter, &uid, _Py_Gid_Converter, &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(PyModuleDef *module); + +static PyObject * +os_getcwd(PyModuleDef *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(PyModuleDef *module); + +static PyObject * +os_getcwdb(PyModuleDef *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)os_link, METH_VARARGS|METH_KEYWORDS, os_link__doc__}, + +static PyObject * +os_link_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, + int dst_dir_fd, int follow_symlinks); + +static PyObject * +os_link(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", "follow_symlinks", NULL}; + 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; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$O&O&p:link", _keywords, + path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd, &follow_symlinks)) + goto exit; + 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 or bytes. 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)os_listdir, METH_VARARGS|METH_KEYWORDS, os_listdir__doc__}, + +static PyObject * +os_listdir_impl(PyModuleDef *module, path_t *path); + +static PyObject * +os_listdir(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", NULL}; + path_t path = PATH_T_INITIALIZE("listdir", "path", 1, PATH_HAVE_FDOPENDIR); + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", _keywords, + path_converter, &path)) + goto exit; + 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(PyModuleDef *module, path_t *path); + +static PyObject * +os__getfullpathname(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + path_t path = PATH_T_INITIALIZE("_getfullpathname", "path", 0, 0); + + if (!PyArg_Parse(arg, "O&:_getfullpathname", path_converter, &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(PyModuleDef *module, PyObject *path); + +static PyObject * +os__getfinalpathname(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *path; + + if (!PyArg_Parse(arg, "U:_getfinalpathname", &path)) + goto exit; + return_value = os__getfinalpathname_impl(module, path); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os__isdir__doc__, +"_isdir($module, path, /)\n" +"--\n" +"\n"); + +#define OS__ISDIR_METHODDEF \ + {"_isdir", (PyCFunction)os__isdir, METH_O, os__isdir__doc__}, + +static PyObject * +os__isdir_impl(PyModuleDef *module, path_t *path); + +static PyObject * +os__isdir(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + path_t path = PATH_T_INITIALIZE("_isdir", "path", 0, 0); + + if (!PyArg_Parse(arg, "O&:_isdir", path_converter, &path)) + goto exit; + return_value = os__isdir_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)os__getvolumepathname, METH_VARARGS|METH_KEYWORDS, os__getvolumepathname__doc__}, + +static PyObject * +os__getvolumepathname_impl(PyModuleDef *module, PyObject *path); + +static PyObject * +os__getvolumepathname(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", NULL}; + PyObject *path; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U:_getvolumepathname", _keywords, + &path)) + goto exit; + return_value = os__getvolumepathname_impl(module, path); + +exit: + 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)os_mkdir, METH_VARARGS|METH_KEYWORDS, os_mkdir__doc__}, + +static PyObject * +os_mkdir_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd); + +static PyObject * +os_mkdir(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "mode", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("mkdir", "path", 0, 0); + int mode = 511; + int dir_fd = DEFAULT_DIR_FD; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", _keywords, + path_converter, &path, &mode, MKDIRAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + 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(PyModuleDef *module, int increment); + +static PyObject * +os_nice(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int increment; + + if (!PyArg_Parse(arg, "i:nice", &increment)) + 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)os_getpriority, METH_VARARGS|METH_KEYWORDS, os_getpriority__doc__}, + +static PyObject * +os_getpriority_impl(PyModuleDef *module, int which, int who); + +static PyObject * +os_getpriority(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"which", "who", NULL}; + int which; + int who; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:getpriority", _keywords, + &which, &who)) + 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)os_setpriority, METH_VARARGS|METH_KEYWORDS, os_setpriority__doc__}, + +static PyObject * +os_setpriority_impl(PyModuleDef *module, int which, int who, int priority); + +static PyObject * +os_setpriority(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"which", "who", "priority", NULL}; + int which; + int who; + int priority; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iii:setpriority", _keywords, + &which, &who, &priority)) + 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)os_rename, METH_VARARGS|METH_KEYWORDS, os_rename__doc__}, + +static PyObject * +os_rename_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, + int dst_dir_fd); + +static PyObject * +os_rename(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; + 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; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$O&O&:rename", _keywords, + path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd)) + goto exit; + 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)os_replace, METH_VARARGS|METH_KEYWORDS, os_replace__doc__}, + +static PyObject * +os_replace_impl(PyModuleDef *module, path_t *src, path_t *dst, + int src_dir_fd, int dst_dir_fd); + +static PyObject * +os_replace(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; + 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; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$O&O&:replace", _keywords, + path_converter, &src, path_converter, &dst, dir_fd_converter, &src_dir_fd, dir_fd_converter, &dst_dir_fd)) + goto exit; + 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)os_rmdir, METH_VARARGS|METH_KEYWORDS, os_rmdir__doc__}, + +static PyObject * +os_rmdir_impl(PyModuleDef *module, path_t *path, int dir_fd); + +static PyObject * +os_rmdir(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("rmdir", "path", 0, 0); + int dir_fd = DEFAULT_DIR_FD; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", _keywords, + path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + 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)os_system, METH_VARARGS|METH_KEYWORDS, os_system__doc__}, + +static long +os_system_impl(PyModuleDef *module, Py_UNICODE *command); + +static PyObject * +os_system(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"command", NULL}; + Py_UNICODE *command; + long _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "u:system", _keywords, + &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)os_system, METH_VARARGS|METH_KEYWORDS, os_system__doc__}, + +static long +os_system_impl(PyModuleDef *module, PyObject *command); + +static PyObject * +os_system(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"command", NULL}; + PyObject *command = NULL; + long _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:system", _keywords, + PyUnicode_FSConverter, &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(PyModuleDef *module, int mask); + +static PyObject * +os_umask(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int mask; + + if (!PyArg_Parse(arg, "i:umask", &mask)) + 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)os_unlink, METH_VARARGS|METH_KEYWORDS, os_unlink__doc__}, + +static PyObject * +os_unlink_impl(PyModuleDef *module, path_t *path, int dir_fd); + +static PyObject * +os_unlink(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("unlink", "path", 0, 0); + int dir_fd = DEFAULT_DIR_FD; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", _keywords, + path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + 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)os_remove, METH_VARARGS|METH_KEYWORDS, os_remove__doc__}, + +static PyObject * +os_remove_impl(PyModuleDef *module, path_t *path, int dir_fd); + +static PyObject * +os_remove(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("remove", "path", 0, 0); + int dir_fd = DEFAULT_DIR_FD; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:remove", _keywords, + path_converter, &path, UNLINKAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + 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(PyModuleDef *module); + +static PyObject * +os_uname(PyModuleDef *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=None, dir_fd=None,\n" +" 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)os_utime, METH_VARARGS|METH_KEYWORDS, os_utime__doc__}, + +static PyObject * +os_utime_impl(PyModuleDef *module, path_t *path, PyObject *times, + PyObject *ns, int dir_fd, int follow_symlinks); + +static PyObject * +os_utime(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "times", "ns", "dir_fd", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("utime", "path", 0, PATH_UTIME_HAVE_FD); + PyObject *times = NULL; + PyObject *ns = NULL; + int dir_fd = DEFAULT_DIR_FD; + int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|O$OO&p:utime", _keywords, + path_converter, &path, ×, &ns, FUTIMENSAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) + goto exit; + 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)os__exit, METH_VARARGS|METH_KEYWORDS, os__exit__doc__}, + +static PyObject * +os__exit_impl(PyModuleDef *module, int status); + +static PyObject * +os__exit(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:_exit", _keywords, + &status)) + 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)os_execv, METH_VARARGS, os_execv__doc__}, + +static PyObject * +os_execv_impl(PyModuleDef *module, PyObject *path, PyObject *argv); + +static PyObject * +os_execv(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *path = NULL; + PyObject *argv; + + if (!PyArg_ParseTuple(args, "O&O:execv", + PyUnicode_FSConverter, &path, &argv)) + goto exit; + return_value = os_execv_impl(module, path, argv); + +exit: + /* Cleanup for path */ + Py_XDECREF(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)os_execve, METH_VARARGS|METH_KEYWORDS, os_execve__doc__}, + +static PyObject * +os_execve_impl(PyModuleDef *module, path_t *path, PyObject *argv, + PyObject *env); + +static PyObject * +os_execve(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "argv", "env", NULL}; + path_t path = PATH_T_INITIALIZE("execve", "path", 0, PATH_HAVE_FEXECVE); + PyObject *argv; + PyObject *env; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", _keywords, + path_converter, &path, &argv, &env)) + goto exit; + 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_SPAWNV) + +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)os_spawnv, METH_VARARGS, os_spawnv__doc__}, + +static PyObject * +os_spawnv_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv); + +static PyObject * +os_spawnv(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int mode; + PyObject *path = NULL; + PyObject *argv; + + if (!PyArg_ParseTuple(args, "iO&O:spawnv", + &mode, PyUnicode_FSConverter, &path, &argv)) + goto exit; + return_value = os_spawnv_impl(module, mode, path, argv); + +exit: + /* Cleanup for path */ + Py_XDECREF(path); + + return return_value; +} + +#endif /* defined(HAVE_SPAWNV) */ + +#if defined(HAVE_SPAWNV) + +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)os_spawnve, METH_VARARGS, os_spawnve__doc__}, + +static PyObject * +os_spawnve_impl(PyModuleDef *module, int mode, PyObject *path, + PyObject *argv, PyObject *env); + +static PyObject * +os_spawnve(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int mode; + PyObject *path = NULL; + PyObject *argv; + PyObject *env; + + if (!PyArg_ParseTuple(args, "iO&OO:spawnve", + &mode, PyUnicode_FSConverter, &path, &argv, &env)) + goto exit; + return_value = os_spawnve_impl(module, mode, path, argv, env); + +exit: + /* Cleanup for path */ + Py_XDECREF(path); + + return return_value; +} + +#endif /* defined(HAVE_SPAWNV) */ + +#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(PyModuleDef *module); + +static PyObject * +os_fork1(PyModuleDef *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(PyModuleDef *module); + +static PyObject * +os_fork(PyModuleDef *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)os_sched_get_priority_max, METH_VARARGS|METH_KEYWORDS, os_sched_get_priority_max__doc__}, + +static PyObject * +os_sched_get_priority_max_impl(PyModuleDef *module, int policy); + +static PyObject * +os_sched_get_priority_max(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"policy", NULL}; + int policy; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:sched_get_priority_max", _keywords, + &policy)) + 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)os_sched_get_priority_min, METH_VARARGS|METH_KEYWORDS, os_sched_get_priority_min__doc__}, + +static PyObject * +os_sched_get_priority_min_impl(PyModuleDef *module, int policy); + +static PyObject * +os_sched_get_priority_min(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"policy", NULL}; + int policy; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:sched_get_priority_min", _keywords, + &policy)) + 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(PyModuleDef *module, pid_t pid); + +static PyObject * +os_sched_getscheduler(PyModuleDef *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_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)) + +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 char *_keywords[] = {"sched_priority", NULL}; + PyObject *sched_priority; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", _keywords, + &sched_priority)) + goto exit; + return_value = os_sched_param_impl(type, sched_priority); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SCHED_H) && (defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)) */ + +#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)os_sched_setscheduler, METH_VARARGS, os_sched_setscheduler__doc__}, + +static PyObject * +os_sched_setscheduler_impl(PyModuleDef *module, pid_t pid, int policy, + struct sched_param *param); + +static PyObject * +os_sched_setscheduler(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + pid_t pid; + int policy; + struct sched_param param; + + if (!PyArg_ParseTuple(args, "" _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(PyModuleDef *module, pid_t pid); + +static PyObject * +os_sched_getparam(PyModuleDef *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)os_sched_setparam, METH_VARARGS, os_sched_setparam__doc__}, + +static PyObject * +os_sched_setparam_impl(PyModuleDef *module, pid_t pid, + struct sched_param *param); + +static PyObject * +os_sched_setparam(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + pid_t pid; + struct sched_param param; + + if (!PyArg_ParseTuple(args, "" _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(PyModuleDef *module, pid_t pid); + +static PyObject * +os_sched_rr_get_interval(PyModuleDef *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(PyModuleDef *module); + +static PyObject * +os_sched_yield(PyModuleDef *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)os_sched_setaffinity, METH_VARARGS, os_sched_setaffinity__doc__}, + +static PyObject * +os_sched_setaffinity_impl(PyModuleDef *module, pid_t pid, PyObject *mask); + +static PyObject * +os_sched_setaffinity(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + pid_t pid; + PyObject *mask; + + if (!PyArg_ParseTuple(args, "" _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(PyModuleDef *module, pid_t pid); + +static PyObject * +os_sched_getaffinity(PyModuleDef *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(PyModuleDef *module); + +static PyObject * +os_openpty(PyModuleDef *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(PyModuleDef *module); + +static PyObject * +os_forkpty(PyModuleDef *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(PyModuleDef *module); + +static PyObject * +os_getegid(PyModuleDef *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(PyModuleDef *module); + +static PyObject * +os_geteuid(PyModuleDef *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(PyModuleDef *module); + +static PyObject * +os_getgid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getgid_impl(module); +} + +#endif /* defined(HAVE_GETGID) */ + +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(PyModuleDef *module); + +static PyObject * +os_getpid(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_getpid_impl(module); +} + +#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(PyModuleDef *module); + +static PyObject * +os_getgroups(PyModuleDef *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)os_getpgid, METH_VARARGS|METH_KEYWORDS, os_getpgid__doc__}, + +static PyObject * +os_getpgid_impl(PyModuleDef *module, pid_t pid); + +static PyObject * +os_getpgid(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"pid", NULL}; + pid_t pid; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "" _Py_PARSE_PID ":getpgid", _keywords, + &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(PyModuleDef *module); + +static PyObject * +os_getpgrp(PyModuleDef *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(PyModuleDef *module); + +static PyObject * +os_setpgrp(PyModuleDef *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(PyModuleDef *module); + +static PyObject * +os_getppid(PyModuleDef *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(PyModuleDef *module); + +static PyObject * +os_getlogin(PyModuleDef *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(PyModuleDef *module); + +static PyObject * +os_getuid(PyModuleDef *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)os_kill, METH_VARARGS, os_kill__doc__}, + +static PyObject * +os_kill_impl(PyModuleDef *module, pid_t pid, Py_ssize_t signal); + +static PyObject * +os_kill(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + pid_t pid; + Py_ssize_t signal; + + if (!PyArg_ParseTuple(args, "" _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)os_killpg, METH_VARARGS, os_killpg__doc__}, + +static PyObject * +os_killpg_impl(PyModuleDef *module, pid_t pgid, int signal); + +static PyObject * +os_killpg(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + pid_t pgid; + int signal; + + if (!PyArg_ParseTuple(args, "" _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(PyModuleDef *module, int op); + +static PyObject * +os_plock(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int op; + + if (!PyArg_Parse(arg, "i:plock", &op)) + 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(PyModuleDef *module, uid_t uid); + +static PyObject * +os_setuid(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + uid_t uid; + + if (!PyArg_Parse(arg, "O&:setuid", _Py_Uid_Converter, &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(PyModuleDef *module, uid_t euid); + +static PyObject * +os_seteuid(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + uid_t euid; + + if (!PyArg_Parse(arg, "O&:seteuid", _Py_Uid_Converter, &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(PyModuleDef *module, gid_t egid); + +static PyObject * +os_setegid(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + gid_t egid; + + if (!PyArg_Parse(arg, "O&:setegid", _Py_Gid_Converter, &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)os_setreuid, METH_VARARGS, os_setreuid__doc__}, + +static PyObject * +os_setreuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid); + +static PyObject * +os_setreuid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + uid_t ruid; + uid_t euid; + + if (!PyArg_ParseTuple(args, "O&O&:setreuid", + _Py_Uid_Converter, &ruid, _Py_Uid_Converter, &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)os_setregid, METH_VARARGS, os_setregid__doc__}, + +static PyObject * +os_setregid_impl(PyModuleDef *module, gid_t rgid, gid_t egid); + +static PyObject * +os_setregid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + gid_t rgid; + gid_t egid; + + if (!PyArg_ParseTuple(args, "O&O&:setregid", + _Py_Gid_Converter, &rgid, _Py_Gid_Converter, &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(PyModuleDef *module, gid_t gid); + +static PyObject * +os_setgid(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + gid_t gid; + + if (!PyArg_Parse(arg, "O&:setgid", _Py_Gid_Converter, &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)os_wait3, METH_VARARGS|METH_KEYWORDS, os_wait3__doc__}, + +static PyObject * +os_wait3_impl(PyModuleDef *module, int options); + +static PyObject * +os_wait3(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"options", NULL}; + int options; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:wait3", _keywords, + &options)) + 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)os_wait4, METH_VARARGS|METH_KEYWORDS, os_wait4__doc__}, + +static PyObject * +os_wait4_impl(PyModuleDef *module, pid_t pid, int options); + +static PyObject * +os_wait4(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"pid", "options", NULL}; + pid_t pid; + int options; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "" _Py_PARSE_PID "i:wait4", _keywords, + &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)os_waitid, METH_VARARGS, os_waitid__doc__}, + +static PyObject * +os_waitid_impl(PyModuleDef *module, idtype_t idtype, id_t id, int options); + +static PyObject * +os_waitid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + idtype_t idtype; + id_t id; + int options; + + if (!PyArg_ParseTuple(args, "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)os_waitpid, METH_VARARGS, os_waitpid__doc__}, + +static PyObject * +os_waitpid_impl(PyModuleDef *module, pid_t pid, int options); + +static PyObject * +os_waitpid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + pid_t pid; + int options; + + if (!PyArg_ParseTuple(args, "" _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_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)os_waitpid, METH_VARARGS, os_waitpid__doc__}, + +static PyObject * +os_waitpid_impl(PyModuleDef *module, Py_intptr_t pid, int options); + +static PyObject * +os_waitpid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_intptr_t pid; + int options; + + if (!PyArg_ParseTuple(args, "" _Py_PARSE_INTPTR "i:waitpid", + &pid, &options)) + goto exit; + return_value = os_waitpid_impl(module, pid, options); + +exit: + return return_value; +} + +#endif /* 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(PyModuleDef *module); + +static PyObject * +os_wait(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_wait_impl(module); +} + +#endif /* defined(HAVE_WAIT) */ + +#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)os_symlink, METH_VARARGS|METH_KEYWORDS, os_symlink__doc__}, + +static PyObject * +os_symlink_impl(PyModuleDef *module, path_t *src, path_t *dst, + int target_is_directory, int dir_fd); + +static PyObject * +os_symlink(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"src", "dst", "target_is_directory", "dir_fd", NULL}; + 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; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|p$O&:symlink", _keywords, + path_converter, &src, path_converter, &dst, &target_is_directory, SYMLINKAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + 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(PyModuleDef *module); + +static PyObject * +os_times(PyModuleDef *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(PyModuleDef *module, pid_t pid); + +static PyObject * +os_getsid(PyModuleDef *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(PyModuleDef *module); + +static PyObject * +os_setsid(PyModuleDef *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)os_setpgid, METH_VARARGS, os_setpgid__doc__}, + +static PyObject * +os_setpgid_impl(PyModuleDef *module, pid_t pid, pid_t pgrp); + +static PyObject * +os_setpgid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + pid_t pid; + pid_t pgrp; + + if (!PyArg_ParseTuple(args, "" _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(PyModuleDef *module, int fd); + +static PyObject * +os_tcgetpgrp(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!PyArg_Parse(arg, "i:tcgetpgrp", &fd)) + 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)os_tcsetpgrp, METH_VARARGS, os_tcsetpgrp__doc__}, + +static PyObject * +os_tcsetpgrp_impl(PyModuleDef *module, int fd, pid_t pgid); + +static PyObject * +os_tcsetpgrp(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + pid_t pgid; + + if (!PyArg_ParseTuple(args, "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)os_open, METH_VARARGS|METH_KEYWORDS, os_open__doc__}, + +static int +os_open_impl(PyModuleDef *module, path_t *path, int flags, int mode, + int dir_fd); + +static PyObject * +os_open(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "flags", "mode", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("open", "path", 0, 0); + int flags; + int mode = 511; + int dir_fd = DEFAULT_DIR_FD; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", _keywords, + path_converter, &path, &flags, &mode, OPENAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + _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)os_close, METH_VARARGS|METH_KEYWORDS, os_close__doc__}, + +static PyObject * +os_close_impl(PyModuleDef *module, int fd); + +static PyObject * +os_close(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", NULL}; + int fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:close", _keywords, + &fd)) + 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)os_closerange, METH_VARARGS, os_closerange__doc__}, + +static PyObject * +os_closerange_impl(PyModuleDef *module, int fd_low, int fd_high); + +static PyObject * +os_closerange(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd_low; + int fd_high; + + if (!PyArg_ParseTuple(args, "ii:closerange", + &fd_low, &fd_high)) + 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(PyModuleDef *module, int fd); + +static PyObject * +os_dup(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + int _return_value; + + if (!PyArg_Parse(arg, "i:dup", &fd)) + 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)os_dup2, METH_VARARGS|METH_KEYWORDS, os_dup2__doc__}, + +static PyObject * +os_dup2_impl(PyModuleDef *module, int fd, int fd2, int inheritable); + +static PyObject * +os_dup2(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", "fd2", "inheritable", NULL}; + int fd; + int fd2; + int inheritable = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|p:dup2", _keywords, + &fd, &fd2, &inheritable)) + goto exit; + return_value = os_dup2_impl(module, fd, fd2, inheritable); + +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)os_lockf, METH_VARARGS, os_lockf__doc__}, + +static PyObject * +os_lockf_impl(PyModuleDef *module, int fd, int command, Py_off_t length); + +static PyObject * +os_lockf(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + int command; + Py_off_t length; + + if (!PyArg_ParseTuple(args, "iiO&:lockf", + &fd, &command, Py_off_t_converter, &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)os_lseek, METH_VARARGS, os_lseek__doc__}, + +static Py_off_t +os_lseek_impl(PyModuleDef *module, int fd, Py_off_t position, int how); + +static PyObject * +os_lseek(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + Py_off_t position; + int how; + Py_off_t _return_value; + + if (!PyArg_ParseTuple(args, "iO&i:lseek", + &fd, Py_off_t_converter, &position, &how)) + 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)os_read, METH_VARARGS, os_read__doc__}, + +static PyObject * +os_read_impl(PyModuleDef *module, int fd, Py_ssize_t length); + +static PyObject * +os_read(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + Py_ssize_t length; + + if (!PyArg_ParseTuple(args, "in:read", + &fd, &length)) + goto exit; + 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)os_readv, METH_VARARGS, os_readv__doc__}, + +static Py_ssize_t +os_readv_impl(PyModuleDef *module, int fd, PyObject *buffers); + +static PyObject * +os_readv(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + PyObject *buffers; + Py_ssize_t _return_value; + + if (!PyArg_ParseTuple(args, "iO:readv", + &fd, &buffers)) + goto exit; + _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)os_pread, METH_VARARGS, os_pread__doc__}, + +static PyObject * +os_pread_impl(PyModuleDef *module, int fd, int length, Py_off_t offset); + +static PyObject * +os_pread(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + int length; + Py_off_t offset; + + if (!PyArg_ParseTuple(args, "iiO&:pread", + &fd, &length, Py_off_t_converter, &offset)) + goto exit; + return_value = os_pread_impl(module, fd, length, offset); + +exit: + return return_value; +} + +#endif /* defined(HAVE_PREAD) */ + +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)os_write, METH_VARARGS, os_write__doc__}, + +static Py_ssize_t +os_write_impl(PyModuleDef *module, int fd, Py_buffer *data); + +static PyObject * +os_write(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + Py_buffer data = {NULL, NULL}; + Py_ssize_t _return_value; + + if (!PyArg_ParseTuple(args, "iy*:write", + &fd, &data)) + 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; +} + +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)os_fstat, METH_VARARGS|METH_KEYWORDS, os_fstat__doc__}, + +static PyObject * +os_fstat_impl(PyModuleDef *module, int fd); + +static PyObject * +os_fstat(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", NULL}; + int fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:fstat", _keywords, + &fd)) + 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(PyModuleDef *module, int fd); + +static PyObject * +os_isatty(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + int _return_value; + + if (!PyArg_Parse(arg, "i:isatty", &fd)) + 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(PyModuleDef *module); + +static PyObject * +os_pipe(PyModuleDef *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(PyModuleDef *module, int flags); + +static PyObject * +os_pipe2(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int flags; + + if (!PyArg_Parse(arg, "i:pipe2", &flags)) + 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)os_writev, METH_VARARGS, os_writev__doc__}, + +static Py_ssize_t +os_writev_impl(PyModuleDef *module, int fd, PyObject *buffers); + +static PyObject * +os_writev(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + PyObject *buffers; + Py_ssize_t _return_value; + + if (!PyArg_ParseTuple(args, "iO:writev", + &fd, &buffers)) + goto exit; + _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)os_pwrite, METH_VARARGS, os_pwrite__doc__}, + +static Py_ssize_t +os_pwrite_impl(PyModuleDef *module, int fd, Py_buffer *buffer, + Py_off_t offset); + +static PyObject * +os_pwrite(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + Py_buffer buffer = {NULL, NULL}; + Py_off_t offset; + Py_ssize_t _return_value; + + if (!PyArg_ParseTuple(args, "iy*O&:pwrite", + &fd, &buffer, Py_off_t_converter, &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_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)os_mkfifo, METH_VARARGS|METH_KEYWORDS, os_mkfifo__doc__}, + +static PyObject * +os_mkfifo_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd); + +static PyObject * +os_mkfifo(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "mode", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("mkfifo", "path", 0, 0); + int mode = 438; + int dir_fd = DEFAULT_DIR_FD; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", _keywords, + path_converter, &path, &mode, MKFIFOAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + 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)os_mknod, METH_VARARGS|METH_KEYWORDS, os_mknod__doc__}, + +static PyObject * +os_mknod_impl(PyModuleDef *module, path_t *path, int mode, dev_t device, + int dir_fd); + +static PyObject * +os_mknod(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "mode", "device", "dir_fd", NULL}; + path_t path = PATH_T_INITIALIZE("mknod", "path", 0, 0); + int mode = 384; + dev_t device = 0; + int dir_fd = DEFAULT_DIR_FD; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|iO&$O&:mknod", _keywords, + path_converter, &path, &mode, _Py_Dev_Converter, &device, MKNODAT_DIR_FD_CONVERTER, &dir_fd)) + goto exit; + 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(PyModuleDef *module, dev_t device); + +static PyObject * +os_major(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + dev_t device; + unsigned int _return_value; + + if (!PyArg_Parse(arg, "O&:major", _Py_Dev_Converter, &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(PyModuleDef *module, dev_t device); + +static PyObject * +os_minor(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + dev_t device; + unsigned int _return_value; + + if (!PyArg_Parse(arg, "O&:minor", _Py_Dev_Converter, &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)os_makedev, METH_VARARGS, os_makedev__doc__}, + +static dev_t +os_makedev_impl(PyModuleDef *module, int major, int minor); + +static PyObject * +os_makedev(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int major; + int minor; + dev_t _return_value; + + if (!PyArg_ParseTuple(args, "ii:makedev", + &major, &minor)) + 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)os_ftruncate, METH_VARARGS, os_ftruncate__doc__}, + +static PyObject * +os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length); + +static PyObject * +os_ftruncate(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + Py_off_t length; + + if (!PyArg_ParseTuple(args, "iO&:ftruncate", + &fd, Py_off_t_converter, &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)os_truncate, METH_VARARGS|METH_KEYWORDS, os_truncate__doc__}, + +static PyObject * +os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length); + +static PyObject * +os_truncate(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "length", NULL}; + path_t path = PATH_T_INITIALIZE("truncate", "path", 0, PATH_HAVE_FTRUNCATE); + Py_off_t length; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", _keywords, + path_converter, &path, Py_off_t_converter, &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)os_posix_fallocate, METH_VARARGS, os_posix_fallocate__doc__}, + +static PyObject * +os_posix_fallocate_impl(PyModuleDef *module, int fd, Py_off_t offset, + Py_off_t length); + +static PyObject * +os_posix_fallocate(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + Py_off_t offset; + Py_off_t length; + + if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate", + &fd, Py_off_t_converter, &offset, Py_off_t_converter, &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)os_posix_fadvise, METH_VARARGS, os_posix_fadvise__doc__}, + +static PyObject * +os_posix_fadvise_impl(PyModuleDef *module, int fd, Py_off_t offset, + Py_off_t length, int advice); + +static PyObject * +os_posix_fadvise(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + Py_off_t offset; + Py_off_t length; + int advice; + + if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise", + &fd, Py_off_t_converter, &offset, Py_off_t_converter, &length, &advice)) + 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)os_putenv, METH_VARARGS, os_putenv__doc__}, + +static PyObject * +os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value); + +static PyObject * +os_putenv(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *name; + PyObject *value; + + if (!PyArg_ParseTuple(args, "UU:putenv", + &name, &value)) + goto exit; + 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)os_putenv, METH_VARARGS, os_putenv__doc__}, + +static PyObject * +os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value); + +static PyObject * +os_putenv(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *name = NULL; + PyObject *value = NULL; + + if (!PyArg_ParseTuple(args, "O&O&:putenv", + PyUnicode_FSConverter, &name, PyUnicode_FSConverter, &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(PyModuleDef *module, PyObject *name); + +static PyObject * +os_unsetenv(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *name = NULL; + + if (!PyArg_Parse(arg, "O&:unsetenv", PyUnicode_FSConverter, &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(PyModuleDef *module, int code); + +static PyObject * +os_strerror(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int code; + + if (!PyArg_Parse(arg, "i:strerror", &code)) + 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(PyModuleDef *module, int status); + +static PyObject * +os_WCOREDUMP(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int status; + int _return_value; + + if (!PyArg_Parse(arg, "i:WCOREDUMP", &status)) + 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)os_WIFCONTINUED, METH_VARARGS|METH_KEYWORDS, os_WIFCONTINUED__doc__}, + +static int +os_WIFCONTINUED_impl(PyModuleDef *module, int status); + +static PyObject * +os_WIFCONTINUED(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:WIFCONTINUED", _keywords, + &status)) + 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)os_WIFSTOPPED, METH_VARARGS|METH_KEYWORDS, os_WIFSTOPPED__doc__}, + +static int +os_WIFSTOPPED_impl(PyModuleDef *module, int status); + +static PyObject * +os_WIFSTOPPED(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:WIFSTOPPED", _keywords, + &status)) + 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)os_WIFSIGNALED, METH_VARARGS|METH_KEYWORDS, os_WIFSIGNALED__doc__}, + +static int +os_WIFSIGNALED_impl(PyModuleDef *module, int status); + +static PyObject * +os_WIFSIGNALED(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:WIFSIGNALED", _keywords, + &status)) + 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)os_WIFEXITED, METH_VARARGS|METH_KEYWORDS, os_WIFEXITED__doc__}, + +static int +os_WIFEXITED_impl(PyModuleDef *module, int status); + +static PyObject * +os_WIFEXITED(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:WIFEXITED", _keywords, + &status)) + 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)os_WEXITSTATUS, METH_VARARGS|METH_KEYWORDS, os_WEXITSTATUS__doc__}, + +static int +os_WEXITSTATUS_impl(PyModuleDef *module, int status); + +static PyObject * +os_WEXITSTATUS(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:WEXITSTATUS", _keywords, + &status)) + 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)os_WTERMSIG, METH_VARARGS|METH_KEYWORDS, os_WTERMSIG__doc__}, + +static int +os_WTERMSIG_impl(PyModuleDef *module, int status); + +static PyObject * +os_WTERMSIG(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:WTERMSIG", _keywords, + &status)) + 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)os_WSTOPSIG, METH_VARARGS|METH_KEYWORDS, os_WSTOPSIG__doc__}, + +static int +os_WSTOPSIG_impl(PyModuleDef *module, int status); + +static PyObject * +os_WSTOPSIG(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"status", NULL}; + int status; + int _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:WSTOPSIG", _keywords, + &status)) + 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(PyModuleDef *module, int fd); + +static PyObject * +os_fstatvfs(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!PyArg_Parse(arg, "i:fstatvfs", &fd)) + 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)os_statvfs, METH_VARARGS|METH_KEYWORDS, os_statvfs__doc__}, + +static PyObject * +os_statvfs_impl(PyModuleDef *module, path_t *path); + +static PyObject * +os_statvfs(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", NULL}; + path_t path = PATH_T_INITIALIZE("statvfs", "path", 0, PATH_HAVE_FSTATVFS); + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", _keywords, + path_converter, &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)os__getdiskusage, METH_VARARGS|METH_KEYWORDS, os__getdiskusage__doc__}, + +static PyObject * +os__getdiskusage_impl(PyModuleDef *module, Py_UNICODE *path); + +static PyObject * +os__getdiskusage(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", NULL}; + Py_UNICODE *path; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "u:_getdiskusage", _keywords, + &path)) + goto exit; + return_value = os__getdiskusage_impl(module, path); + +exit: + 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)os_fpathconf, METH_VARARGS, os_fpathconf__doc__}, + +static long +os_fpathconf_impl(PyModuleDef *module, int fd, int name); + +static PyObject * +os_fpathconf(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + int name; + long _return_value; + + if (!PyArg_ParseTuple(args, "iO&:fpathconf", + &fd, conv_path_confname, &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)os_pathconf, METH_VARARGS|METH_KEYWORDS, os_pathconf__doc__}, + +static long +os_pathconf_impl(PyModuleDef *module, path_t *path, int name); + +static PyObject * +os_pathconf(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "name", NULL}; + path_t path = PATH_T_INITIALIZE("pathconf", "path", 0, PATH_HAVE_FPATHCONF); + int name; + long _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", _keywords, + path_converter, &path, conv_path_confname, &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(PyModuleDef *module, int name); + +static PyObject * +os_confstr(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int name; + + if (!PyArg_Parse(arg, "O&:confstr", conv_confstr_confname, &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(PyModuleDef *module, int name); + +static PyObject * +os_sysconf(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int name; + long _return_value; + + if (!PyArg_Parse(arg, "O&:sysconf", conv_sysconf_confname, &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(PyModuleDef *module); + +static PyObject * +os_abort(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return os_abort_impl(module); +} + +#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(PyModuleDef *module); + +static PyObject * +os_getloadavg(PyModuleDef *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)os_device_encoding, METH_VARARGS|METH_KEYWORDS, os_device_encoding__doc__}, + +static PyObject * +os_device_encoding_impl(PyModuleDef *module, int fd); + +static PyObject * +os_device_encoding(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"fd", NULL}; + int fd; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:device_encoding", _keywords, + &fd)) + 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)os_setresuid, METH_VARARGS, os_setresuid__doc__}, + +static PyObject * +os_setresuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid, uid_t suid); + +static PyObject * +os_setresuid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + uid_t ruid; + uid_t euid; + uid_t suid; + + if (!PyArg_ParseTuple(args, "O&O&O&:setresuid", + _Py_Uid_Converter, &ruid, _Py_Uid_Converter, &euid, _Py_Uid_Converter, &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)os_setresgid, METH_VARARGS, os_setresgid__doc__}, + +static PyObject * +os_setresgid_impl(PyModuleDef *module, gid_t rgid, gid_t egid, gid_t sgid); + +static PyObject * +os_setresgid(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + gid_t rgid; + gid_t egid; + gid_t sgid; + + if (!PyArg_ParseTuple(args, "O&O&O&:setresgid", + _Py_Gid_Converter, &rgid, _Py_Gid_Converter, &egid, _Py_Gid_Converter, &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(PyModuleDef *module); + +static PyObject * +os_getresuid(PyModuleDef *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(PyModuleDef *module); + +static PyObject * +os_getresgid(PyModuleDef *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 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)os_getxattr, METH_VARARGS|METH_KEYWORDS, os_getxattr__doc__}, + +static PyObject * +os_getxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, + int follow_symlinks); + +static PyObject * +os_getxattr(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "attribute", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("getxattr", "path", 0, 1); + path_t attribute = PATH_T_INITIALIZE("getxattr", "attribute", 0, 0); + int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", _keywords, + path_converter, &path, path_converter, &attribute, &follow_symlinks)) + goto exit; + 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 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)os_setxattr, METH_VARARGS|METH_KEYWORDS, os_setxattr__doc__}, + +static PyObject * +os_setxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, + Py_buffer *value, int flags, int follow_symlinks); + +static PyObject * +os_setxattr(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "attribute", "value", "flags", "follow_symlinks", NULL}; + 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; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr", _keywords, + path_converter, &path, path_converter, &attribute, &value, &flags, &follow_symlinks)) + goto exit; + 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 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)os_removexattr, METH_VARARGS|METH_KEYWORDS, os_removexattr__doc__}, + +static PyObject * +os_removexattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, + int follow_symlinks); + +static PyObject * +os_removexattr(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "attribute", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("removexattr", "path", 0, 1); + path_t attribute = PATH_T_INITIALIZE("removexattr", "attribute", 0, 0); + int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr", _keywords, + path_converter, &path, path_converter, &attribute, &follow_symlinks)) + goto exit; + 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, 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)os_listxattr, METH_VARARGS|METH_KEYWORDS, os_listxattr__doc__}, + +static PyObject * +os_listxattr_impl(PyModuleDef *module, path_t *path, int follow_symlinks); + +static PyObject * +os_listxattr(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"path", "follow_symlinks", NULL}; + path_t path = PATH_T_INITIALIZE("listxattr", "path", 1, 1); + int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", _keywords, + path_converter, &path, &follow_symlinks)) + goto exit; + 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(PyModuleDef *module, Py_ssize_t size); + +static PyObject * +os_urandom(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_ssize_t size; + + if (!PyArg_Parse(arg, "n:urandom", &size)) + goto exit; + return_value = os_urandom_impl(module, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(os_cpu_count__doc__, +"cpu_count($module, /)\n" +"--\n" +"\n" +"Return the number of CPUs in the system; return None if indeterminable.\n" +"\n" +"This number is not equivalent to the number of CPUs the current process can\n" +"use. The number of usable CPUs can be obtained with\n" +"``len(os.sched_getaffinity(0))``"); + +#define OS_CPU_COUNT_METHODDEF \ + {"cpu_count", (PyCFunction)os_cpu_count, METH_NOARGS, os_cpu_count__doc__}, + +static PyObject * +os_cpu_count_impl(PyModuleDef *module); + +static PyObject * +os_cpu_count(PyModuleDef *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(PyModuleDef *module, int fd); + +static PyObject * +os_get_inheritable(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + int _return_value; + + if (!PyArg_Parse(arg, "i:get_inheritable", &fd)) + 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)os_set_inheritable, METH_VARARGS, os_set_inheritable__doc__}, + +static PyObject * +os_set_inheritable_impl(PyModuleDef *module, int fd, int inheritable); + +static PyObject * +os_set_inheritable(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + int inheritable; + + if (!PyArg_ParseTuple(args, "ii:set_inheritable", + &fd, &inheritable)) + 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(PyModuleDef *module, Py_intptr_t handle); + +static PyObject * +os_get_handle_inheritable(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_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)os_set_handle_inheritable, METH_VARARGS, os_set_handle_inheritable__doc__}, + +static PyObject * +os_set_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle, + int inheritable); + +static PyObject * +os_set_handle_inheritable(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_intptr_t handle; + int inheritable; + + if (!PyArg_ParseTuple(args, "" _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) */ + +#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__ISDIR_METHODDEF + #define OS__ISDIR_METHODDEF +#endif /* !defined(OS__ISDIR_METHODDEF) */ + +#ifndef OS__GETVOLUMEPATHNAME_METHODDEF + #define OS__GETVOLUMEPATHNAME_METHODDEF +#endif /* !defined(OS__GETVOLUMEPATHNAME_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_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_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_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_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_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_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_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_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) */ +/*[clinic end generated code: output=a5c9bef9ad11a20b input=a9049054013a1b77]*/ diff --git a/Modules/clinic/pwdmodule.c.h b/Modules/clinic/pwdmodule.c.h new file mode 100644 index 000000000000..9de2e4ff2a00 --- /dev/null +++ b/Modules/clinic/pwdmodule.c.h @@ -0,0 +1,71 @@ +/*[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, arg, /)\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(PyModuleDef *module, PyObject *arg); + +static PyObject * +pwd_getpwnam(PyModuleDef *module, PyObject *arg_) +{ + PyObject *return_value = NULL; + PyObject *arg; + + if (!PyArg_Parse(arg_, "U:getpwnam", &arg)) + goto exit; + return_value = pwd_getpwnam_impl(module, arg); + +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(PyModuleDef *module); + +static PyObject * +pwd_getpwall(PyModuleDef *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=2ed0ecf34fd3f98f input=a9049054013a1b77]*/ diff --git a/Modules/clinic/pyexpat.c.h b/Modules/clinic/pyexpat.c.h new file mode 100644 index 000000000000..379c5db637dc --- /dev/null +++ b/Modules/clinic/pyexpat.c.h @@ -0,0 +1,284 @@ +/*[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)pyexpat_xmlparser_Parse, METH_VARARGS, pyexpat_xmlparser_Parse__doc__}, + +static PyObject * +pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyObject *data, + int isfinal); + +static PyObject * +pyexpat_xmlparser_Parse(xmlparseobject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *data; + int isfinal = 0; + + if (!PyArg_ParseTuple(args, "O|i:Parse", + &data, &isfinal)) + goto exit; + 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 (!PyArg_Parse(arg, "s:SetBase", &base)) + 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=None, /)\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)pyexpat_xmlparser_ExternalEntityParserCreate, METH_VARARGS, 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 *args) +{ + PyObject *return_value = NULL; + const char *context; + const char *encoding = NULL; + + if (!PyArg_ParseTuple(args, "z|s:ExternalEntityParserCreate", + &context, &encoding)) + goto exit; + 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 (!PyArg_Parse(arg, "i:SetParamEntityParsing", &flag)) + 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)pyexpat_xmlparser_UseForeignDTD, METH_VARARGS, pyexpat_xmlparser_UseForeignDTD__doc__}, + +static PyObject * +pyexpat_xmlparser_UseForeignDTD_impl(xmlparseobject *self, int flag); + +static PyObject * +pyexpat_xmlparser_UseForeignDTD(xmlparseobject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int flag = 1; + + if (!PyArg_ParseTuple(args, "|p:UseForeignDTD", + &flag)) + goto exit; + return_value = pyexpat_xmlparser_UseForeignDTD_impl(self, flag); + +exit: + return return_value; +} + +#endif /* (XML_COMBINED_VERSION >= 19505) */ + +PyDoc_STRVAR(pyexpat_xmlparser___dir____doc__, +"__dir__($self, /)\n" +"--\n" +"\n"); + +#define PYEXPAT_XMLPARSER___DIR___METHODDEF \ + {"__dir__", (PyCFunction)pyexpat_xmlparser___dir__, METH_NOARGS, pyexpat_xmlparser___dir____doc__}, + +static PyObject * +pyexpat_xmlparser___dir___impl(xmlparseobject *self); + +static PyObject * +pyexpat_xmlparser___dir__(xmlparseobject *self, PyObject *Py_UNUSED(ignored)) +{ + return pyexpat_xmlparser___dir___impl(self); +} + +PyDoc_STRVAR(pyexpat_ParserCreate__doc__, +"ParserCreate($module, /, encoding=None, namespace_separator=None,\n" +" intern=None)\n" +"--\n" +"\n" +"Return a new XML parser object."); + +#define PYEXPAT_PARSERCREATE_METHODDEF \ + {"ParserCreate", (PyCFunction)pyexpat_ParserCreate, METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__}, + +static PyObject * +pyexpat_ParserCreate_impl(PyModuleDef *module, const char *encoding, + const char *namespace_separator, PyObject *intern); + +static PyObject * +pyexpat_ParserCreate(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"encoding", "namespace_separator", "intern", NULL}; + const char *encoding = NULL; + const char *namespace_separator = NULL; + PyObject *intern = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zzO:ParserCreate", _keywords, + &encoding, &namespace_separator, &intern)) + goto exit; + 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(PyModuleDef *module, long code); + +static PyObject * +pyexpat_ErrorString(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + long code; + + if (!PyArg_Parse(arg, "l:ErrorString", &code)) + 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=bf4d99c9702d8a6c input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha1module.c.h b/Modules/clinic/sha1module.c.h new file mode 100644 index 000000000000..fa865baec800 --- /dev/null +++ b/Modules/clinic/sha1module.c.h @@ -0,0 +1,95 @@ +/*[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 string of binary data."); + +#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)_sha1_sha1, METH_VARARGS|METH_KEYWORDS, _sha1_sha1__doc__}, + +static PyObject * +_sha1_sha1_impl(PyModuleDef *module, PyObject *string); + +static PyObject * +_sha1_sha1(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"string", NULL}; + PyObject *string = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:sha1", _keywords, + &string)) + goto exit; + return_value = _sha1_sha1_impl(module, string); + +exit: + return return_value; +} +/*[clinic end generated code: output=be19102f3120490a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha256module.c.h b/Modules/clinic/sha256module.c.h new file mode 100644 index 000000000000..c5fe188a9c36 --- /dev/null +++ b/Modules/clinic/sha256module.c.h @@ -0,0 +1,123 @@ +/*[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 string of binary data."); + +#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)_sha256_sha256, METH_VARARGS|METH_KEYWORDS, _sha256_sha256__doc__}, + +static PyObject * +_sha256_sha256_impl(PyModuleDef *module, PyObject *string); + +static PyObject * +_sha256_sha256(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"string", NULL}; + PyObject *string = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:sha256", _keywords, + &string)) + goto exit; + 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)_sha256_sha224, METH_VARARGS|METH_KEYWORDS, _sha256_sha224__doc__}, + +static PyObject * +_sha256_sha224_impl(PyModuleDef *module, PyObject *string); + +static PyObject * +_sha256_sha224(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"string", NULL}; + PyObject *string = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:sha224", _keywords, + &string)) + goto exit; + return_value = _sha256_sha224_impl(module, string); + +exit: + return return_value; +} +/*[clinic end generated code: output=354cedf3b632c7b2 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha512module.c.h b/Modules/clinic/sha512module.c.h new file mode 100644 index 000000000000..c308739d4483 --- /dev/null +++ b/Modules/clinic/sha512module.c.h @@ -0,0 +1,171 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(PY_LONG_LONG) + +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); +} + +#endif /* defined(PY_LONG_LONG) */ + +#if defined(PY_LONG_LONG) + +PyDoc_STRVAR(SHA512Type_digest__doc__, +"digest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a string of binary data."); + +#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); +} + +#endif /* defined(PY_LONG_LONG) */ + +#if defined(PY_LONG_LONG) + +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); +} + +#endif /* defined(PY_LONG_LONG) */ + +#if defined(PY_LONG_LONG) + +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__}, + +#endif /* defined(PY_LONG_LONG) */ + +#if defined(PY_LONG_LONG) + +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)_sha512_sha512, METH_VARARGS|METH_KEYWORDS, _sha512_sha512__doc__}, + +static PyObject * +_sha512_sha512_impl(PyModuleDef *module, PyObject *string); + +static PyObject * +_sha512_sha512(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"string", NULL}; + PyObject *string = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:sha512", _keywords, + &string)) + goto exit; + return_value = _sha512_sha512_impl(module, string); + +exit: + return return_value; +} + +#endif /* defined(PY_LONG_LONG) */ + +#if defined(PY_LONG_LONG) + +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)_sha512_sha384, METH_VARARGS|METH_KEYWORDS, _sha512_sha384__doc__}, + +static PyObject * +_sha512_sha384_impl(PyModuleDef *module, PyObject *string); + +static PyObject * +_sha512_sha384(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"string", NULL}; + PyObject *string = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:sha384", _keywords, + &string)) + goto exit; + return_value = _sha512_sha384_impl(module, string); + +exit: + return return_value; +} + +#endif /* defined(PY_LONG_LONG) */ + +#ifndef SHA512TYPE_COPY_METHODDEF + #define SHA512TYPE_COPY_METHODDEF +#endif /* !defined(SHA512TYPE_COPY_METHODDEF) */ + +#ifndef SHA512TYPE_DIGEST_METHODDEF + #define SHA512TYPE_DIGEST_METHODDEF +#endif /* !defined(SHA512TYPE_DIGEST_METHODDEF) */ + +#ifndef SHA512TYPE_HEXDIGEST_METHODDEF + #define SHA512TYPE_HEXDIGEST_METHODDEF +#endif /* !defined(SHA512TYPE_HEXDIGEST_METHODDEF) */ + +#ifndef SHA512TYPE_UPDATE_METHODDEF + #define SHA512TYPE_UPDATE_METHODDEF +#endif /* !defined(SHA512TYPE_UPDATE_METHODDEF) */ + +#ifndef _SHA512_SHA512_METHODDEF + #define _SHA512_SHA512_METHODDEF +#endif /* !defined(_SHA512_SHA512_METHODDEF) */ + +#ifndef _SHA512_SHA384_METHODDEF + #define _SHA512_SHA384_METHODDEF +#endif /* !defined(_SHA512_SHA384_METHODDEF) */ +/*[clinic end generated code: output=1c7d385731fee7c0 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/signalmodule.c.h b/Modules/clinic/signalmodule.c.h new file mode 100644 index 000000000000..ec07ef1f8e7c --- /dev/null +++ b/Modules/clinic/signalmodule.c.h @@ -0,0 +1,432 @@ +/*[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(PyModuleDef *module, int seconds); + +static PyObject * +signal_alarm(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int seconds; + long _return_value; + + if (!PyArg_Parse(arg, "i:alarm", &seconds)) + 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(PyModuleDef *module); + +static PyObject * +signal_pause(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return signal_pause_impl(module); +} + +#endif /* defined(HAVE_PAUSE) */ + +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)signal_signal, METH_VARARGS, signal_signal__doc__}, + +static PyObject * +signal_signal_impl(PyModuleDef *module, int signalnum, PyObject *handler); + +static PyObject * +signal_signal(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int signalnum; + PyObject *handler; + + if (!PyArg_ParseTuple(args, "iO:signal", + &signalnum, &handler)) + goto exit; + 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(PyModuleDef *module, int signalnum); + +static PyObject * +signal_getsignal(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int signalnum; + + if (!PyArg_Parse(arg, "i:getsignal", &signalnum)) + goto exit; + return_value = signal_getsignal_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)signal_siginterrupt, METH_VARARGS, signal_siginterrupt__doc__}, + +static PyObject * +signal_siginterrupt_impl(PyModuleDef *module, int signalnum, int flag); + +static PyObject * +signal_siginterrupt(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int signalnum; + int flag; + + if (!PyArg_ParseTuple(args, "ii:siginterrupt", + &signalnum, &flag)) + 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)signal_setitimer, METH_VARARGS, signal_setitimer__doc__}, + +static PyObject * +signal_setitimer_impl(PyModuleDef *module, int which, double seconds, + double interval); + +static PyObject * +signal_setitimer(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int which; + double seconds; + double interval = 0.0; + + if (!PyArg_ParseTuple(args, "id|d:setitimer", + &which, &seconds, &interval)) + goto exit; + 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(PyModuleDef *module, int which); + +static PyObject * +signal_getitimer(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int which; + + if (!PyArg_Parse(arg, "i:getitimer", &which)) + 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)signal_pthread_sigmask, METH_VARARGS, signal_pthread_sigmask__doc__}, + +static PyObject * +signal_pthread_sigmask_impl(PyModuleDef *module, int how, PyObject *mask); + +static PyObject * +signal_pthread_sigmask(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int how; + PyObject *mask; + + if (!PyArg_ParseTuple(args, "iO:pthread_sigmask", + &how, &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(PyModuleDef *module); + +static PyObject * +signal_sigpending(PyModuleDef *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__}, + +#endif /* defined(HAVE_SIGWAIT) */ + +#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__}, + +#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)signal_sigtimedwait, METH_VARARGS, signal_sigtimedwait__doc__}, + +static PyObject * +signal_sigtimedwait_impl(PyModuleDef *module, PyObject *sigset, + PyObject *timeout_obj); + +static PyObject * +signal_sigtimedwait(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *sigset; + PyObject *timeout_obj; + + if (!PyArg_UnpackTuple(args, "sigtimedwait", + 2, 2, + &sigset, &timeout_obj)) + goto exit; + return_value = signal_sigtimedwait_impl(module, sigset, timeout_obj); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SIGTIMEDWAIT) */ + +#if (defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD)) + +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)signal_pthread_kill, METH_VARARGS, signal_pthread_kill__doc__}, + +static PyObject * +signal_pthread_kill_impl(PyModuleDef *module, long thread_id, int signalnum); + +static PyObject * +signal_pthread_kill(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + long thread_id; + int signalnum; + + if (!PyArg_ParseTuple(args, "li:pthread_kill", + &thread_id, &signalnum)) + goto exit; + return_value = signal_pthread_kill_impl(module, thread_id, signalnum); + +exit: + return return_value; +} + +#endif /* (defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD)) */ + +#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_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=b99278c16c40ea43 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/spwdmodule.c.h b/Modules/clinic/spwdmodule.c.h new file mode 100644 index 000000000000..c0d18db58904 --- /dev/null +++ b/Modules/clinic/spwdmodule.c.h @@ -0,0 +1,68 @@ +/*[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(PyModuleDef *module, PyObject *arg); + +static PyObject * +spwd_getspnam(PyModuleDef *module, PyObject *arg_) +{ + PyObject *return_value = NULL; + PyObject *arg; + + if (!PyArg_Parse(arg_, "U:getspnam", &arg)) + goto exit; + 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(PyModuleDef *module); + +static PyObject * +spwd_getspall(PyModuleDef *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=6c178830413f7763 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/unicodedata.c.h b/Modules/clinic/unicodedata.c.h new file mode 100644 index 000000000000..d520c1e3dd40 --- /dev/null +++ b/Modules/clinic/unicodedata.c.h @@ -0,0 +1,368 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(unicodedata_UCD_decimal__doc__, +"decimal($self, chr, default=None, /)\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)unicodedata_UCD_decimal, METH_VARARGS, 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 *args) +{ + PyObject *return_value = NULL; + int chr; + PyObject *default_value = NULL; + + if (!PyArg_ParseTuple(args, "C|O:decimal", + &chr, &default_value)) + goto exit; + return_value = unicodedata_UCD_decimal_impl(self, chr, default_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicodedata_UCD_digit__doc__, +"digit($self, chr, default=None, /)\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)unicodedata_UCD_digit, METH_VARARGS, 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 *args) +{ + PyObject *return_value = NULL; + int chr; + PyObject *default_value = NULL; + + if (!PyArg_ParseTuple(args, "C|O:digit", + &chr, &default_value)) + goto exit; + return_value = unicodedata_UCD_digit_impl(self, chr, default_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicodedata_UCD_numeric__doc__, +"numeric($self, chr, default=None, /)\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)unicodedata_UCD_numeric, METH_VARARGS, 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 *args) +{ + PyObject *return_value = NULL; + int chr; + PyObject *default_value = NULL; + + if (!PyArg_ParseTuple(args, "C|O:numeric", + &chr, &default_value)) + goto exit; + 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 (!PyArg_Parse(arg, "C:category", &chr)) + goto exit; + 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 (!PyArg_Parse(arg, "C:bidirectional", &chr)) + goto exit; + 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 (!PyArg_Parse(arg, "C:combining", &chr)) + goto exit; + _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 (!PyArg_Parse(arg, "C:mirrored", &chr)) + goto exit; + _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 (!PyArg_Parse(arg, "C:east_asian_width", &chr)) + goto exit; + 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 (!PyArg_Parse(arg, "C:decomposition", &chr)) + goto exit; + return_value = unicodedata_UCD_decomposition_impl(self, chr); + +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)unicodedata_UCD_normalize, METH_VARARGS, unicodedata_UCD_normalize__doc__}, + +static PyObject * +unicodedata_UCD_normalize_impl(PyObject *self, const char *form, + PyObject *input); + +static PyObject * +unicodedata_UCD_normalize(PyObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + const char *form; + PyObject *input; + + if (!PyArg_ParseTuple(args, "sO!:normalize", + &form, &PyUnicode_Type, &input)) + goto exit; + return_value = unicodedata_UCD_normalize_impl(self, form, input); + +exit: + return return_value; +} + +PyDoc_STRVAR(unicodedata_UCD_name__doc__, +"name($self, chr, default=None, /)\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)unicodedata_UCD_name, METH_VARARGS, 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 *args) +{ + PyObject *return_value = NULL; + int chr; + PyObject *default_value = NULL; + + if (!PyArg_ParseTuple(args, "C|O:name", + &chr, &default_value)) + goto exit; + 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=4f8da33c6bc6efc9 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h new file mode 100644 index 000000000000..35661a5a46ee --- /dev/null +++ b/Modules/clinic/zlibmodule.c.h @@ -0,0 +1,441 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(zlib_compress__doc__, +"compress($module, bytes, level=Z_DEFAULT_COMPRESSION, /)\n" +"--\n" +"\n" +"Returns a bytes object containing compressed data.\n" +"\n" +" bytes\n" +" Binary data to be compressed.\n" +" level\n" +" Compression level, in 0-9."); + +#define ZLIB_COMPRESS_METHODDEF \ + {"compress", (PyCFunction)zlib_compress, METH_VARARGS, zlib_compress__doc__}, + +static PyObject * +zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int level); + +static PyObject * +zlib_compress(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer bytes = {NULL, NULL}; + int level = Z_DEFAULT_COMPRESSION; + + if (!PyArg_ParseTuple(args, "y*|i:compress", + &bytes, &level)) + goto exit; + return_value = zlib_compress_impl(module, &bytes, level); + +exit: + /* Cleanup for bytes */ + if (bytes.obj) + PyBuffer_Release(&bytes); + + 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.\n" +" bufsize\n" +" The initial output buffer size."); + +#define ZLIB_DECOMPRESS_METHODDEF \ + {"decompress", (PyCFunction)zlib_decompress, METH_VARARGS, zlib_decompress__doc__}, + +static PyObject * +zlib_decompress_impl(PyModuleDef *module, Py_buffer *data, int wbits, + unsigned int bufsize); + +static PyObject * +zlib_decompress(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + int wbits = MAX_WBITS; + unsigned int bufsize = DEF_BUF_SIZE; + + if (!PyArg_ParseTuple(args, "y*|iO&:decompress", + &data, &wbits, uint_converter, &bufsize)) + goto exit; + 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; default is 6).\n" +" Higher compression levels are slower, but produce smaller results.\n" +" method\n" +" The compression algorithm. If given, this must be DEFLATED.\n" +" wbits\n" +" The base two logarithm of the window size (range: 8..15).\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)zlib_compressobj, METH_VARARGS|METH_KEYWORDS, zlib_compressobj__doc__}, + +static PyObject * +zlib_compressobj_impl(PyModuleDef *module, int level, int method, int wbits, + int memLevel, int strategy, Py_buffer *zdict); + +static PyObject * +zlib_compressobj(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"level", "method", "wbits", "memLevel", "strategy", "zdict", NULL}; + int level = Z_DEFAULT_COMPRESSION; + int method = DEFLATED; + int wbits = MAX_WBITS; + int memLevel = DEF_MEM_LEVEL; + int strategy = Z_DEFAULT_STRATEGY; + Py_buffer zdict = {NULL, NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iiiiiy*:compressobj", _keywords, + &level, &method, &wbits, &memLevel, &strategy, &zdict)) + goto exit; + 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.\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)zlib_decompressobj, METH_VARARGS|METH_KEYWORDS, zlib_decompressobj__doc__}, + +static PyObject * +zlib_decompressobj_impl(PyModuleDef *module, int wbits, PyObject *zdict); + +static PyObject * +zlib_decompressobj(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"wbits", "zdict", NULL}; + int wbits = MAX_WBITS; + PyObject *zdict = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iO:decompressobj", _keywords, + &wbits, &zdict)) + goto exit; + 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 (!PyArg_Parse(arg, "y*:compress", &data)) + 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)zlib_Decompress_decompress, METH_VARARGS, zlib_Decompress_decompress__doc__}, + +static PyObject * +zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, + unsigned int max_length); + +static PyObject * +zlib_Decompress_decompress(compobject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + unsigned int max_length = 0; + + if (!PyArg_ParseTuple(args, "y*|O&:decompress", + &data, uint_converter, &max_length)) + goto exit; + 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)zlib_Compress_flush, METH_VARARGS, zlib_Compress_flush__doc__}, + +static PyObject * +zlib_Compress_flush_impl(compobject *self, int mode); + +static PyObject * +zlib_Compress_flush(compobject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int mode = Z_FINISH; + + if (!PyArg_ParseTuple(args, "|i:flush", + &mode)) + goto exit; + 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_Decompress_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the decompression object."); + +#define ZLIB_DECOMPRESS_COPY_METHODDEF \ + {"copy", (PyCFunction)zlib_Decompress_copy, METH_NOARGS, zlib_Decompress_copy__doc__}, + +static PyObject * +zlib_Decompress_copy_impl(compobject *self); + +static PyObject * +zlib_Decompress_copy(compobject *self, PyObject *Py_UNUSED(ignored)) +{ + return zlib_Decompress_copy_impl(self); +} + +#endif /* defined(HAVE_ZLIB_COPY) */ + +PyDoc_STRVAR(zlib_Decompress_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)zlib_Decompress_flush, METH_VARARGS, zlib_Decompress_flush__doc__}, + +static PyObject * +zlib_Decompress_flush_impl(compobject *self, unsigned int length); + +static PyObject * +zlib_Decompress_flush(compobject *self, PyObject *args) +{ + PyObject *return_value = NULL; + unsigned int length = DEF_BUF_SIZE; + + if (!PyArg_ParseTuple(args, "|O&:flush", + uint_converter, &length)) + goto exit; + 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)zlib_adler32, METH_VARARGS, zlib_adler32__doc__}, + +static PyObject * +zlib_adler32_impl(PyModuleDef *module, Py_buffer *data, unsigned int value); + +static PyObject * +zlib_adler32(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + unsigned int value = 1; + + if (!PyArg_ParseTuple(args, "y*|I:adler32", + &data, &value)) + goto exit; + 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)zlib_crc32, METH_VARARGS, zlib_crc32__doc__}, + +static PyObject * +zlib_crc32_impl(PyModuleDef *module, Py_buffer *data, unsigned int value); + +static PyObject * +zlib_crc32(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer data = {NULL, NULL}; + unsigned int value = 0; + + if (!PyArg_ParseTuple(args, "y*|I:crc32", + &data, &value)) + goto exit; + 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) */ +/*[clinic end generated code: output=56ed1147bbbb4788 input=a9049054013a1b77]*/ diff --git a/Modules/cmathmodule.c b/Modules/cmathmodule.c index 36bf4a1e3df8..7f6c2c9df4f7 100644 --- a/Modules/cmathmodule.c +++ b/Modules/cmathmodule.c @@ -8,6 +8,40 @@ 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=231019039a6fbb9a]*/ + #if (FLT_RADIX != 2 && FLT_RADIX != 16) #error "Modules/cmathmodule.c expects FLT_RADIX to be 2 or 16" #endif @@ -48,12 +82,12 @@ #define CM_SCALE_DOWN (-(CM_SCALE_UP+1)/2) /* forward declarations */ -static Py_complex c_asinh(Py_complex); -static Py_complex c_atanh(Py_complex); -static Py_complex c_cosh(Py_complex); -static Py_complex c_sinh(Py_complex); -static Py_complex c_sqrt(Py_complex); -static Py_complex c_tanh(Py_complex); +static Py_complex cmath_asinh_impl(PyModuleDef *, Py_complex); +static Py_complex cmath_atanh_impl(PyModuleDef *, Py_complex); +static Py_complex cmath_cosh_impl(PyModuleDef *, Py_complex); +static Py_complex cmath_sinh_impl(PyModuleDef *, Py_complex); +static Py_complex cmath_sqrt_impl(PyModuleDef *, Py_complex); +static Py_complex cmath_tanh_impl(PyModuleDef *, Py_complex); static PyObject * math_error(void); /* Code to deal with special values (infinities, NaNs, etc.). */ @@ -123,8 +157,18 @@ special_type(double d) 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 -c_acos(Py_complex z) +cmath_acos_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=7c1dd21ff818db6b input=bd6cbd78ae851927]*/ { Py_complex s1, s2, r; @@ -145,10 +189,10 @@ c_acos(Py_complex z) } else { s1.real = 1.-z.real; s1.imag = -z.imag; - s1 = c_sqrt(s1); + s1 = cmath_sqrt_impl(module, s1); s2.real = 1.+z.real; s2.imag = z.imag; - s2 = c_sqrt(s2); + 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); } @@ -156,16 +200,18 @@ c_acos(Py_complex z) return r; } -PyDoc_STRVAR(c_acos_doc, -"acos(x)\n" -"\n" -"Return the arc cosine of x."); - 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 -c_acosh(Py_complex z) +cmath_acosh_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=c23c776429def981 input=3f61bee7d703e53c]*/ { Py_complex s1, s2, r; @@ -178,10 +224,10 @@ c_acosh(Py_complex z) } else { s1.real = z.real - 1.; s1.imag = z.imag; - s1 = c_sqrt(s1); + s1 = cmath_sqrt_impl(module, s1); s2.real = z.real + 1.; s2.imag = z.imag; - s2 = c_sqrt(s2); + 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); } @@ -189,35 +235,38 @@ c_acosh(Py_complex z) return r; } -PyDoc_STRVAR(c_acosh_doc, -"acosh(x)\n" -"\n" -"Return the hyperbolic arccosine of x."); +/*[clinic input] +cmath.asin = cmath.acos +Return the arc sine of z. +[clinic start generated code]*/ static Py_complex -c_asin(Py_complex z) +cmath_asin_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=42d2346d46690826 input=be0bf0cfdd5239c5]*/ { /* asin(z) = -i asinh(iz) */ Py_complex s, r; s.real = -z.imag; s.imag = z.real; - s = c_asinh(s); + s = cmath_asinh_impl(module, s); r.real = s.imag; r.imag = -s.real; return r; } -PyDoc_STRVAR(c_asin_doc, -"asin(x)\n" -"\n" -"Return the arc sine of x."); - 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 -c_asinh(Py_complex z) +cmath_asinh_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=0c6664823c7b1b35 input=5c09448fcfc89a79]*/ { Py_complex s1, s2, r; @@ -235,10 +284,10 @@ c_asinh(Py_complex z) } else { s1.real = 1.+z.imag; s1.imag = -z.real; - s1 = c_sqrt(s1); + s1 = cmath_sqrt_impl(module, s1); s2.real = 1.-z.imag; s2.imag = z.real; - s2 = c_sqrt(s2); + 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); } @@ -246,20 +295,22 @@ c_asinh(Py_complex z) return r; } -PyDoc_STRVAR(c_asinh_doc, -"asinh(x)\n" -"\n" -"Return the hyperbolic arc sine of x."); +/*[clinic input] +cmath.atan = cmath.acos + +Return the arc tangent of z. +[clinic start generated code]*/ static Py_complex -c_atan(Py_complex z) +cmath_atan_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=b7d44f02c6a5c3b5 input=3b21ff7d5eac632a]*/ { /* atan(z) = -i atanh(iz) */ Py_complex s, r; s.real = -z.imag; s.imag = z.real; - s = c_atanh(s); + s = cmath_atanh_impl(module, s); r.real = s.imag; r.imag = -s.real; return r; @@ -295,16 +346,18 @@ c_atan2(Py_complex z) return atan2(z.imag, z.real); } -PyDoc_STRVAR(c_atan_doc, -"atan(x)\n" -"\n" -"Return the arc tangent of x."); - 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 -c_atanh(Py_complex z) +cmath_atanh_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=279e0b9fefc8da7c input=2b3fdb82fb34487b]*/ { Py_complex r; double ay, h; @@ -313,7 +366,7 @@ c_atanh(Py_complex z) /* Reduce to case where z.real >= 0., using atanh(z) = -atanh(-z). */ if (z.real < 0.) { - return c_neg(c_atanh(c_neg(z))); + return _Py_c_neg(cmath_atanh_impl(module, _Py_c_neg(z))); } ay = fabs(z.imag); @@ -350,34 +403,38 @@ c_atanh(Py_complex z) return r; } -PyDoc_STRVAR(c_atanh_doc, -"atanh(x)\n" -"\n" -"Return the hyperbolic arc tangent of x."); +/*[clinic input] +cmath.cos = cmath.acos + +Return the cosine of z. +[clinic start generated code]*/ static Py_complex -c_cos(Py_complex z) +cmath_cos_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=9d1cdc1b5e761667 input=6022e39b77127ac7]*/ { /* cos(z) = cosh(iz) */ Py_complex r; r.real = -z.imag; r.imag = z.real; - r = c_cosh(r); + r = cmath_cosh_impl(module, r); return r; } -PyDoc_STRVAR(c_cos_doc, -"cos(x)\n" -"\n" -"Return the cosine of x."); - /* 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 -c_cosh(Py_complex z) +cmath_cosh_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=f3b5d3282b3024d3 input=d6b66339e9cc332b]*/ { Py_complex r; double x_minus_one; @@ -426,18 +483,20 @@ c_cosh(Py_complex z) return r; } -PyDoc_STRVAR(c_cosh_doc, -"cosh(x)\n" -"\n" -"Return the hyperbolic cosine of x."); - /* 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 -c_exp(Py_complex z) +cmath_exp_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=6f8825eb2bcad9ba input=8b9e6cf8a92174c3]*/ { Py_complex r; double l; @@ -486,12 +545,6 @@ c_exp(Py_complex z) return r; } -PyDoc_STRVAR(c_exp_doc, -"exp(x)\n" -"\n" -"Return the exponential value e**x."); - - static Py_complex log_special_values[7][7]; static Py_complex @@ -564,8 +617,15 @@ c_log(Py_complex z) } +/*[clinic input] +cmath.log10 = cmath.acos + +Return the base-10 logarithm of z. +[clinic start generated code]*/ + static Py_complex -c_log10(Py_complex z) +cmath_log10_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=c7c426ca0e782341 input=cff5644f73c1519c]*/ { Py_complex r; int errno_save; @@ -578,36 +638,40 @@ c_log10(Py_complex z) return r; } -PyDoc_STRVAR(c_log10_doc, -"log10(x)\n" -"\n" -"Return the base-10 logarithm of x."); +/*[clinic input] +cmath.sin = cmath.acos + +Return the sine of z. +[clinic start generated code]*/ static Py_complex -c_sin(Py_complex z) +cmath_sin_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=e7f5e2b253825ac7 input=2d3519842a8b4b85]*/ { /* sin(z) = -i sin(iz) */ Py_complex s, r; s.real = -z.imag; s.imag = z.real; - s = c_sinh(s); + s = cmath_sinh_impl(module, s); r.real = s.imag; r.imag = -s.real; return r; } -PyDoc_STRVAR(c_sin_doc, -"sin(x)\n" -"\n" -"Return the sine of x."); - /* 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 -c_sinh(Py_complex z) +cmath_sinh_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=d71fff8298043a95 input=d2d3fc8c1ddfd2dd]*/ { Py_complex r; double x_minus_one; @@ -655,16 +719,18 @@ c_sinh(Py_complex z) return r; } -PyDoc_STRVAR(c_sinh_doc, -"sinh(x)\n" -"\n" -"Return the hyperbolic sine of x."); - 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 -c_sqrt(Py_complex z) +cmath_sqrt_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=b6bda283d0c5a7b4 input=7088b166fc9a58c7]*/ { /* Method: use symmetries to reduce to the case when x = z.real and y @@ -730,36 +796,40 @@ c_sqrt(Py_complex z) return r; } -PyDoc_STRVAR(c_sqrt_doc, -"sqrt(x)\n" -"\n" -"Return the square root of x."); +/*[clinic input] +cmath.tan = cmath.acos + +Return the tangent of z. +[clinic start generated code]*/ static Py_complex -c_tan(Py_complex z) +cmath_tan_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=df374bacf36d99b4 input=fc167e528767888e]*/ { /* tan(z) = -i tanh(iz) */ Py_complex s, r; s.real = -z.imag; s.imag = z.real; - s = c_tanh(s); + s = cmath_tanh_impl(module, s); r.real = s.imag; r.imag = -s.real; return r; } -PyDoc_STRVAR(c_tan_doc, -"tan(x)\n" -"\n" -"Return the tangent of x."); - /* 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 -c_tanh(Py_complex z) +cmath_tanh_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=f578773d27a18e96 input=22f67f9dc6d29685]*/ { /* Formula: @@ -822,27 +892,35 @@ c_tanh(Py_complex z) return r; } -PyDoc_STRVAR(c_tanh_doc, -"tanh(x)\n" -"\n" -"Return the hyperbolic tangent of x."); +/*[clinic input] +cmath.log + + x: Py_complex + y_obj: object = NULL + / + +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(PyObject *self, PyObject *args) +cmath_log_impl(PyModuleDef *module, Py_complex x, PyObject *y_obj) +/*[clinic end generated code: output=35e2a1e5229b5a46 input=ee0e823a7c6e68ea]*/ { - Py_complex x; Py_complex y; - if (!PyArg_ParseTuple(args, "D|D", &x, &y)) - return NULL; - errno = 0; PyFPE_START_PROTECT("complex function", return 0) x = c_log(x); - if (PyTuple_GET_SIZE(args) == 2) { + if (y_obj != NULL) { + y = PyComplex_AsCComplex(y_obj); + if (PyErr_Occurred()) { + return NULL; + } y = c_log(y); - x = c_quot(x, y); + x = _Py_c_quot(x, y); } PyFPE_END_PROTECT(x) if (errno != 0) @@ -850,10 +928,6 @@ cmath_log(PyObject *self, PyObject *args) return PyComplex_FromCComplex(x); } -PyDoc_STRVAR(cmath_log_doc, -"log(x[, base]) -> the logarithm of x to the given base.\n\ -If the base not specified, returns the natural logarithm (base e) of x."); - /* And now the glue to make them available from Python: */ @@ -869,57 +943,22 @@ math_error(void) return NULL; } -static PyObject * -math_1(PyObject *args, Py_complex (*func)(Py_complex)) -{ - Py_complex x,r ; - if (!PyArg_ParseTuple(args, "D", &x)) - return NULL; - errno = 0; - PyFPE_START_PROTECT("complex function", return 0); - r = (*func)(x); - PyFPE_END_PROTECT(r); - if (errno == EDOM) { - PyErr_SetString(PyExc_ValueError, "math domain error"); - return NULL; - } - else if (errno == ERANGE) { - PyErr_SetString(PyExc_OverflowError, "math range error"); - return NULL; - } - else { - return PyComplex_FromCComplex(r); - } -} -#define FUNC1(stubname, func) \ - static PyObject * stubname(PyObject *self, PyObject *args) { \ - return math_1(args, func); \ - } +/*[clinic input] +cmath.phase + + z: Py_complex + / -FUNC1(cmath_acos, c_acos) -FUNC1(cmath_acosh, c_acosh) -FUNC1(cmath_asin, c_asin) -FUNC1(cmath_asinh, c_asinh) -FUNC1(cmath_atan, c_atan) -FUNC1(cmath_atanh, c_atanh) -FUNC1(cmath_cos, c_cos) -FUNC1(cmath_cosh, c_cosh) -FUNC1(cmath_exp, c_exp) -FUNC1(cmath_log10, c_log10) -FUNC1(cmath_sin, c_sin) -FUNC1(cmath_sinh, c_sinh) -FUNC1(cmath_sqrt, c_sqrt) -FUNC1(cmath_tan, c_tan) -FUNC1(cmath_tanh, c_tanh) +Return argument, also known as the phase angle, of a complex. +[clinic start generated code]*/ static PyObject * -cmath_phase(PyObject *self, PyObject *args) +cmath_phase_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=e09eaf373cb624c3 input=5cf75228ba94b69d]*/ { - Py_complex z; double phi; - if (!PyArg_ParseTuple(args, "D:phase", &z)) - return NULL; + errno = 0; PyFPE_START_PROTECT("arg function", return 0) phi = c_atan2(z); @@ -930,20 +969,27 @@ cmath_phase(PyObject *self, PyObject *args) return PyFloat_FromDouble(phi); } -PyDoc_STRVAR(cmath_phase_doc, -"phase(z) -> float\n\n\ -Return argument, also known as the phase angle, of a complex."); +/*[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(PyObject *self, PyObject *args) +cmath_polar_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=07d41b16c877875a input=26c353574fd1a861]*/ { - Py_complex z; double r, phi; - if (!PyArg_ParseTuple(args, "D:polar", &z)) - return NULL; + + errno = 0; PyFPE_START_PROTECT("polar function", return 0) phi = c_atan2(z); /* should not cause any exception */ - r = c_abs(z); /* sets errno to ERANGE on overflow; otherwise 0 */ + r = _Py_c_abs(z); /* sets errno to ERANGE on overflow */ PyFPE_END_PROTECT(r) if (errno != 0) return math_error(); @@ -951,11 +997,6 @@ cmath_polar(PyObject *self, PyObject *args) return Py_BuildValue("dd", r, phi); } -PyDoc_STRVAR(cmath_polar_doc, -"polar(z) -> r: float, phi: float\n\n\ -Convert a complex from rectangular coordinates to polar coordinates. r is\n\ -the distance from 0 and phi the phase angle."); - /* 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: @@ -969,13 +1010,21 @@ the distance from 0 and phi the phase angle."); 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(PyObject *self, PyObject *args) +cmath_rect_impl(PyModuleDef *module, double r, double phi) +/*[clinic end generated code: output=d97a8749bd63e9d5 input=24c5646d147efd69]*/ { Py_complex z; - double r, phi; - if (!PyArg_ParseTuple(args, "dd:rect", &r, &phi)) - return NULL; errno = 0; PyFPE_START_PROTECT("rect function", return 0) @@ -1026,79 +1075,143 @@ cmath_rect(PyObject *self, PyObject *args) return PyComplex_FromCComplex(z); } -PyDoc_STRVAR(cmath_rect_doc, -"rect(r, phi) -> z: complex\n\n\ -Convert from polar coordinates to rectangular coordinates."); +/*[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(PyObject *self, PyObject *args) +cmath_isfinite_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=8f6682fa93de45d6 input=848e7ee701895815]*/ { - Py_complex z; - if (!PyArg_ParseTuple(args, "D:isfinite", &z)) - return NULL; return PyBool_FromLong(Py_IS_FINITE(z.real) && Py_IS_FINITE(z.imag)); } -PyDoc_STRVAR(cmath_isfinite_doc, -"isfinite(z) -> bool\n\ -Return True if both the real and imaginary parts of z are finite, else False."); +/*[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(PyObject *self, PyObject *args) +cmath_isnan_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=b85fe8c2047718ee input=71799f5d284c9baf]*/ { - Py_complex z; - if (!PyArg_ParseTuple(args, "D:isnan", &z)) - return NULL; return PyBool_FromLong(Py_IS_NAN(z.real) || Py_IS_NAN(z.imag)); } -PyDoc_STRVAR(cmath_isnan_doc, -"isnan(z) -> bool\n\ -Checks if the real or imaginary part of z not a number (NaN)"); +/*[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(PyObject *self, PyObject *args) +cmath_isinf_impl(PyModuleDef *module, Py_complex z) +/*[clinic end generated code: output=8ca9c6109e468bf4 input=363df155c7181329]*/ { - Py_complex z; - if (!PyArg_ParseTuple(args, "D:isnan", &z)) - return NULL; return PyBool_FromLong(Py_IS_INFINITY(z.real) || Py_IS_INFINITY(z.imag)); } -PyDoc_STRVAR(cmath_isinf_doc, -"isinf(z) -> bool\n\ -Checks if the real or imaginary part of z is infinite."); +/*[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(PyModuleDef *module, Py_complex a, Py_complex b, + double rel_tol, double abs_tol) +/*[clinic end generated code: output=da0c535fb54e2310 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 is always available. It provides access to mathematical\n" "functions for complex numbers."); static PyMethodDef cmath_methods[] = { - {"acos", cmath_acos, METH_VARARGS, c_acos_doc}, - {"acosh", cmath_acosh, METH_VARARGS, c_acosh_doc}, - {"asin", cmath_asin, METH_VARARGS, c_asin_doc}, - {"asinh", cmath_asinh, METH_VARARGS, c_asinh_doc}, - {"atan", cmath_atan, METH_VARARGS, c_atan_doc}, - {"atanh", cmath_atanh, METH_VARARGS, c_atanh_doc}, - {"cos", cmath_cos, METH_VARARGS, c_cos_doc}, - {"cosh", cmath_cosh, METH_VARARGS, c_cosh_doc}, - {"exp", cmath_exp, METH_VARARGS, c_exp_doc}, - {"isfinite", cmath_isfinite, METH_VARARGS, cmath_isfinite_doc}, - {"isinf", cmath_isinf, METH_VARARGS, cmath_isinf_doc}, - {"isnan", cmath_isnan, METH_VARARGS, cmath_isnan_doc}, - {"log", cmath_log, METH_VARARGS, cmath_log_doc}, - {"log10", cmath_log10, METH_VARARGS, c_log10_doc}, - {"phase", cmath_phase, METH_VARARGS, cmath_phase_doc}, - {"polar", cmath_polar, METH_VARARGS, cmath_polar_doc}, - {"rect", cmath_rect, METH_VARARGS, cmath_rect_doc}, - {"sin", cmath_sin, METH_VARARGS, c_sin_doc}, - {"sinh", cmath_sinh, METH_VARARGS, c_sinh_doc}, - {"sqrt", cmath_sqrt, METH_VARARGS, c_sqrt_doc}, - {"tan", cmath_tan, METH_VARARGS, c_tan_doc}, - {"tanh", cmath_tanh, METH_VARARGS, c_tanh_doc}, - {NULL, NULL} /* sentinel */ + 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 */ }; diff --git a/Modules/config.c.in b/Modules/config.c.in index 7a24e2dc8964..7b77199c2e93 100644 --- a/Modules/config.c.in +++ b/Modules/config.c.in @@ -13,7 +13,7 @@ redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. /* !!! !!! !!! This file is edited by the makesetup script !!! !!! !!! */ /* This file contains the table of built-in modules. - See init_builtin() in import.c. */ + See create_builtin() in import.c. */ #include "Python.h" diff --git a/Modules/expat/expat_external.h b/Modules/expat/expat_external.h index 2c03284ea265..f337e1c5622a 100644 --- a/Modules/expat/expat_external.h +++ b/Modules/expat/expat_external.h @@ -7,6 +7,10 @@ /* External API definitions */ +/* Namespace external symbols to allow multiple libexpat version to + co-exist. */ +#include "pyexpatns.h" + #if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) #define XML_USE_MSC_EXTENSIONS 1 #endif diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c index f35aa36ba8a7..0ac0317b8e14 100644 --- a/Modules/expat/xmlparse.c +++ b/Modules/expat/xmlparse.c @@ -2,12 +2,6 @@ See the file COPYING for copying permission. */ -#include -#include /* memset(), memcpy() */ -#include -#include /* UINT_MAX */ -#include /* time() */ - #define XML_BUILDING_EXPAT 1 #ifdef COMPILED_FROM_DSP @@ -22,6 +16,12 @@ #include #endif /* ndef COMPILED_FROM_DSP */ +#include +#include /* memset(), memcpy() */ +#include +#include /* UINT_MAX */ +#include /* time() */ + #include "ascii.h" #include "expat.h" diff --git a/Modules/expat/xmlrole.c b/Modules/expat/xmlrole.c index 44772e21dd33..9a8f85dd2535 100644 --- a/Modules/expat/xmlrole.c +++ b/Modules/expat/xmlrole.c @@ -2,8 +2,6 @@ See the file COPYING for copying permission. */ -#include - #ifdef COMPILED_FROM_DSP #include "winconfig.h" #elif defined(MACOS_CLASSIC) @@ -18,6 +16,8 @@ #endif #endif /* ndef COMPILED_FROM_DSP */ +#include + #include "expat_external.h" #include "internal.h" #include "xmlrole.h" diff --git a/Modules/expat/xmltok.c b/Modules/expat/xmltok.c index b9cd7a451300..fd6bf7a3d18d 100644 --- a/Modules/expat/xmltok.c +++ b/Modules/expat/xmltok.c @@ -2,8 +2,6 @@ See the file COPYING for copying permission. */ -#include - #ifdef COMPILED_FROM_DSP #include "winconfig.h" #elif defined(MACOS_CLASSIC) @@ -18,6 +16,8 @@ #endif #endif /* ndef COMPILED_FROM_DSP */ +#include + #include "expat_external.h" #include "internal.h" #include "xmltok.h" diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 27b1d54c60cc..530ddc7efd67 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -5,7 +5,13 @@ #include #include #if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) -#include +# include +#endif +#ifdef MS_WINDOWS +# include +#endif +#ifdef HAVE_SYS_RESOURCE_H +# include #endif /* Allocate at maximum 100 MB of the stack to raise the stack overflow */ @@ -22,9 +28,7 @@ # define FAULTHANDLER_USER #endif -/* cast size_t to int because write() takes an int on Windows - (anyway, the length is smaller than 30 characters) */ -#define PUTS(fd, str) write(fd, str, (int)strlen(str)) +#define PUTS(fd, str) _Py_write_noraise(fd, str, strlen(str)) _Py_IDENTIFIER(enable); _Py_IDENTIFIER(fileno); @@ -127,28 +131,46 @@ static stack_t stack; 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 new file and write the file descriptor into *p_fd. - On error, return NULL. */ + On success, return the file descriptor and write the new file into *file_ptr. + On error, return -1. */ -static PyObject* -faulthandler_get_fileno(PyObject *file, int *p_fd) +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 NULL; + 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 || !_PyVerify_fd(fd)) { + PyErr_SetString(PyExc_ValueError, + "file is not a valid file descripter"); + return -1; + } + *file_ptr = NULL; + return fd; + } result = _PyObject_CallMethodId(file, &PyId_fileno, ""); if (result == NULL) - return NULL; + return -1; fd = -1; if (PyLong_Check(result)) { @@ -161,7 +183,7 @@ faulthandler_get_fileno(PyObject *file, int *p_fd) if (fd == -1) { PyErr_SetString(PyExc_RuntimeError, "file.fileno() is not a valid file descriptor"); - return NULL; + return -1; } result = _PyObject_CallMethodId(file, &PyId_flush, ""); @@ -171,8 +193,8 @@ faulthandler_get_fileno(PyObject *file, int *p_fd) /* ignore flush() error */ PyErr_Clear(); } - *p_fd = fd; - return file; + *file_ptr = file; + return fd; } /* Get the state of the current thread: only call this function if the current @@ -189,6 +211,42 @@ get_thread_state(void) 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; + +#ifdef WITH_THREAD + /* 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 local storage (TLS) instead: call + PyGILState_GetThisThreadState(). */ + tstate = PyGILState_GetThisThreadState(); +#else + tstate = PyThreadState_Get(); +#endif + + if (all_threads) + _Py_DumpTracebackThreads(fd, interp, tstate); + else { + if (tstate != NULL) + _Py_DumpTraceback(fd, tstate); + } + + reentrant = 0; +} + static PyObject* faulthandler_dump_traceback_py(PyObject *self, PyObject *args, PyObject *kwargs) @@ -205,8 +263,8 @@ faulthandler_dump_traceback_py(PyObject *self, &file, &all_threads)) return NULL; - file = faulthandler_get_fileno(file, &fd); - if (file == NULL) + fd = faulthandler_get_fileno(&file); + if (fd < 0) return NULL; tstate = get_thread_state(); @@ -223,6 +281,10 @@ faulthandler_dump_traceback_py(PyObject *self, else { _Py_DumpTraceback(fd, tstate); } + + if (PyErr_CheckSignals()) + return NULL; + Py_RETURN_NONE; } @@ -246,7 +308,6 @@ faulthandler_fatal_error(int signum) const int fd = fatal_error.fd; unsigned int i; fault_handler_t *handler = NULL; - PyThreadState *tstate; int save_errno = errno; if (!fatal_error.enabled) @@ -274,26 +335,8 @@ faulthandler_fatal_error(int signum) PUTS(fd, handler->name); PUTS(fd, "\n\n"); -#ifdef WITH_THREAD - /* 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 local storage (TLS) instead: call - PyGILState_GetThisThreadState(). */ - tstate = PyGILState_GetThisThreadState(); -#else - tstate = PyThreadState_Get(); -#endif - - if (fatal_error.all_threads) - _Py_DumpTracebackThreads(fd, fatal_error.interp, tstate); - else { - if (tstate != NULL) - _Py_DumpTraceback(fd, tstate); - } + faulthandler_dump_traceback(fd, fatal_error.all_threads, + fatal_error.interp); errno = save_errno; #ifdef MS_WINDOWS @@ -303,7 +346,7 @@ faulthandler_fatal_error(int signum) return; } #endif - /* call the previous signal handler: it is called immediatly if we use + /* call the previous signal handler: it is called immediately if we use sigaction() thanks to SA_NODEFER flag, otherwise it is deferred */ raise(signum); } @@ -329,8 +372,8 @@ faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs) "|Oi:enable", kwlist, &file, &all_threads)) return NULL; - file = faulthandler_get_fileno(file, &fd); - if (file == NULL) + fd = faulthandler_get_fileno(&file); + if (fd < 0) return NULL; tstate = get_thread_state(); @@ -338,7 +381,7 @@ faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs) return NULL; Py_XDECREF(fatal_error.file); - Py_INCREF(file); + Py_XINCREF(file); fatal_error.file = file; fatal_error.fd = fd; fatal_error.all_threads = all_threads; @@ -448,9 +491,9 @@ faulthandler_thread(void *unused) assert(st == PY_LOCK_FAILURE); /* get the thread holding the GIL, NULL if no thread hold the GIL */ - current = _Py_atomic_load_relaxed(&_PyThreadState_Current); + current = (PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current); - write(thread.fd, thread.header, (int)thread.header_len); + _Py_write_noraise(thread.fd, thread.header, (int)thread.header_len); errmsg = _Py_DumpTracebackThreads(thread.fd, thread.interp, current); ok = (errmsg == NULL); @@ -543,8 +586,8 @@ faulthandler_dump_traceback_later(PyObject *self, if (tstate == NULL) return NULL; - file = faulthandler_get_fileno(file, &fd); - if (file == NULL) + fd = faulthandler_get_fileno(&file); + if (fd < 0) return NULL; /* format the timeout */ @@ -557,7 +600,7 @@ faulthandler_dump_traceback_later(PyObject *self, cancel_dump_traceback_later(); Py_XDECREF(thread.file); - Py_INCREF(file); + Py_XINCREF(file); thread.file = file; thread.fd = fd; thread.timeout_us = timeout_us; @@ -636,28 +679,14 @@ static void faulthandler_user(int signum) { user_signal_t *user; - PyThreadState *tstate; int save_errno = errno; user = &user_signals[signum]; if (!user->enabled) return; -#ifdef WITH_THREAD - /* PyThreadState_Get() doesn't give the state of the current thread if - the thread doesn't hold the GIL. Read the thread local storage (TLS) - instead: call PyGILState_GetThisThreadState(). */ - tstate = PyGILState_GetThisThreadState(); -#else - tstate = PyThreadState_Get(); -#endif + faulthandler_dump_traceback(user->fd, user->all_threads, user->interp); - if (user->all_threads) - _Py_DumpTracebackThreads(user->fd, user->interp, tstate); - else { - if (tstate != NULL) - _Py_DumpTraceback(user->fd, tstate); - } #ifdef HAVE_SIGACTION if (user->chain) { (void)sigaction(signum, &user->previous, NULL); @@ -727,8 +756,8 @@ faulthandler_register_py(PyObject *self, if (tstate == NULL) return NULL; - file = faulthandler_get_fileno(file, &fd); - if (file == NULL) + fd = faulthandler_get_fileno(&file); + if (fd < 0) return NULL; if (user_signals == NULL) { @@ -750,7 +779,7 @@ faulthandler_register_py(PyObject *self, } Py_XDECREF(user->file); - Py_INCREF(file); + Py_XINCREF(file); user->file = file; user->fd = fd; user->all_threads = all_threads; @@ -800,29 +829,51 @@ faulthandler_unregister_py(PyObject *self, PyObject *args) #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; - int release_gil = 0; - if (!PyArg_ParseTuple(args, "|i:_read_null", &release_gil)) - return NULL; + faulthandler_suppress_crash_report(); x = NULL; - if (release_gil) { - Py_BEGIN_ALLOW_THREADS - y = *x; - Py_END_ALLOW_THREADS - } else - y = *x; + y = *x; return PyLong_FromLong(y); } -static PyObject * -faulthandler_sigsegv(PyObject *self, PyObject *args) +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 @@ -840,6 +891,22 @@ faulthandler_sigsegv(PyObject *self, PyObject *args) #else raise(SIGSEGV); #endif +} + +static PyObject * +faulthandler_sigsegv(PyObject *self, PyObject *args) +{ + int release_gil = 0; + if (!PyArg_ParseTuple(args, "|i:_read_null", &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; } @@ -849,6 +916,7 @@ 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. */ @@ -861,50 +929,36 @@ faulthandler_sigfpe(PyObject *self, PyObject *args) static PyObject * faulthandler_sigabrt(PyObject *self, PyObject *args) { -#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 + faulthandler_suppress_crash_report(); abort(); Py_RETURN_NONE; } -#ifdef SIGBUS -static PyObject * -faulthandler_sigbus(PyObject *self, PyObject *args) -{ - raise(SIGBUS); - Py_RETURN_NONE; -} -#endif - -#ifdef SIGILL -static PyObject * -faulthandler_sigill(PyObject *self, PyObject *args) -{ - raise(SIGILL); - Py_RETURN_NONE; -} -#endif - static PyObject * faulthandler_fatal_error_py(PyObject *self, PyObject *args) { char *message; if (!PyArg_ParseTuple(args, "y:fatal_error", &message)) return NULL; + faulthandler_suppress_crash_report(); Py_FatalError(message); Py_RETURN_NONE; } #if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) -static void* -stack_overflow(void *min_sp, void *max_sp, size_t *depth) +#ifdef __INTEL_COMPILER + /* Issue #23654: Turn off ICC's tail call optimization for the + * stack_overflow generator. ICC turns the recursive tail call into + * a loop. */ +# pragma intel optimization_level 0 +#endif +static +Py_uintptr_t +stack_overflow(Py_uintptr_t min_sp, Py_uintptr_t max_sp, size_t *depth) { /* allocate 4096 bytes on the stack at each call */ unsigned char buffer[4096]; - void *sp = &buffer; + Py_uintptr_t sp = (Py_uintptr_t)&buffer; *depth += 1; if (sp < min_sp || max_sp < sp) return sp; @@ -917,8 +971,10 @@ static PyObject * faulthandler_stack_overflow(PyObject *self) { size_t depth, size; - char *sp = (char *)&depth, *stop; + Py_uintptr_t sp = (Py_uintptr_t)&depth; + Py_uintptr_t stop; + faulthandler_suppress_crash_report(); depth = 0; stop = stack_overflow(sp - STACK_OVERFLOW_MAX_SIZE, sp + STACK_OVERFLOW_MAX_SIZE, @@ -999,23 +1055,15 @@ static PyMethodDef module_methods[] = { "'signum' registered by register()")}, #endif - {"_read_null", faulthandler_read_null, METH_VARARGS, - PyDoc_STR("_read_null(release_gil=False): read from NULL, raise " + {"_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(): raise a SIGSEGV signal")}, - {"_sigabrt", faulthandler_sigabrt, METH_VARARGS, + PyDoc_STR("_sigsegv(release_gil=False): raise a SIGSEGV signal")}, + {"_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")}, -#ifdef SIGBUS - {"_sigbus", (PyCFunction)faulthandler_sigbus, METH_NOARGS, - PyDoc_STR("_sigbus(): raise a SIGBUS signal")}, -#endif -#ifdef SIGILL - {"_sigill", (PyCFunction)faulthandler_sigill, METH_NOARGS, - PyDoc_STR("_sigill(): raise a SIGILL signal")}, -#endif {"_fatal_error", faulthandler_fatal_error_py, METH_VARARGS, PyDoc_STR("_fatal_error(message): call Py_FatalError(message)")}, #if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) @@ -1067,8 +1115,8 @@ faulthandler_env_options(void) has_key = PyDict_Contains(xoptions, key); Py_DECREF(key); - if (!has_key) - return 0; + if (has_key <= 0) + return has_key; } module = PyImport_ImportModule("faulthandler"); diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c index 79d292f1ae44..97ff07c12e98 100644 --- a/Modules/fcntlmodule.c +++ b/Modules/fcntlmodule.c @@ -15,6 +15,11 @@ #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) { @@ -26,48 +31,72 @@ conv_descriptor(PyObject *object, int *target) 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 + / -/* fcntl(fd, op, [arg]) */ +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(PyObject *self, PyObject *args) +fcntl_fcntl_impl(PyModuleDef *module, int fd, int code, PyObject *arg) +/*[clinic end generated code: output=afc5bfa74a03ef0d input=8cefbe59b29efbe2]*/ { - int fd; - int code; - long arg; + unsigned int int_arg = 0; int ret; char *str; Py_ssize_t len; char buf[1024]; - if (PyArg_ParseTuple(args, "O&is#:fcntl", - conv_descriptor, &fd, &code, &str, &len)) { - if (len > sizeof buf) { - PyErr_SetString(PyExc_ValueError, - "fcntl string arg too long"); - 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); + Py_BEGIN_ALLOW_THREADS + ret = fcntl(fd, code, buf); + Py_END_ALLOW_THREADS + if (ret < 0) { + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } + return PyBytes_FromStringAndSize(buf, len); } - memcpy(buf, str, len); - Py_BEGIN_ALLOW_THREADS - ret = fcntl(fd, code, buf); - Py_END_ALLOW_THREADS - if (ret < 0) { - PyErr_SetFromErrno(PyExc_IOError); - return NULL; + + 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; } - return PyBytes_FromStringAndSize(buf, len); } - PyErr_Clear(); - arg = 0; - if (!PyArg_ParseTuple(args, - "O&i|l;fcntl requires a file or file descriptor," - " an integer and optionally a third integer or a string", - conv_descriptor, &fd, &code, &arg)) { - return NULL; - } Py_BEGIN_ALLOW_THREADS - ret = fcntl(fd, code, arg); + ret = fcntl(fd, code, (int)int_arg); Py_END_ALLOW_THREADS if (ret < 0) { PyErr_SetFromErrno(PyExc_IOError); @@ -76,33 +105,54 @@ fcntl_fcntl(PyObject *self, PyObject *args) return PyLong_FromLong((long)ret); } -PyDoc_STRVAR(fcntl_doc, -"fcntl(fd, op, [arg])\n\ -\n\ -Perform the operation op on file descriptor fd. The values used\n\ -for op 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."); +/*[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`. -/* ioctl(fd, op, [arg]) */ +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(PyObject *self, PyObject *args) +fcntl_ioctl_impl(PyModuleDef *module, int fd, unsigned int code, + PyObject *ob_arg, int mutate_arg) +/*[clinic end generated code: output=102faa0f7ebe2210 input=ede70c433cccbbb2]*/ { #define IOCTL_BUFSZ 1024 - int fd; - /* In PyArg_ParseTuple below, we use the unsigned non-checked 'I' - format for the 'code' parameter because Python turns 0x8000000 - into either a large positive number (PyLong or PyInt on 64-bit - platforms) or a negative number on others (32-bit PyInt) - whereas the system expects it to be a 32bit bit field value + /* 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. @@ -111,108 +161,101 @@ fcntl_ioctl(PyObject *self, PyObject *args) in their unsigned long ioctl codes this will break and need special casing based on the platform being built on. */ - unsigned int code; - int arg; + int arg = 0; int ret; Py_buffer pstr; char *str; Py_ssize_t len; - int mutate_arg = 1; char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */ - if (PyArg_ParseTuple(args, "O&Iw*|i:ioctl", - conv_descriptor, &fd, &code, - &pstr, &mutate_arg)) { - char *arg; - str = pstr.buf; - len = pstr.len; - - if (mutate_arg) { - if (len <= IOCTL_BUFSZ) { - memcpy(buf, str, len); - buf[len] = '\0'; - arg = buf; + 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_IOError); + return NULL; + } + if (mutate_arg) { + return PyLong_FromLong(ret); } else { - arg = str; + return PyBytes_FromStringAndSize(buf, len); } } - else { + + 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"); + "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); + memcpy(buf, str, len); + buf[len] = '\0'; + Py_BEGIN_ALLOW_THREADS + ret = ioctl(fd, code, buf); 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_IOError); - return NULL; - } - if (mutate_arg) { - return PyLong_FromLong(ret); - } - else { + if (ret < 0) { + PyBuffer_Release(&pstr); + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } + PyBuffer_Release(&pstr); return PyBytes_FromStringAndSize(buf, len); } - } - PyErr_Clear(); - if (PyArg_ParseTuple(args, "O&Is*:ioctl", - conv_descriptor, &fd, &code, &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_IOError); - return NULL; + 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; } - PyBuffer_Release(&pstr); - return PyBytes_FromStringAndSize(buf, len); - } - - PyErr_Clear(); - arg = 0; - if (!PyArg_ParseTuple(args, - "O&I|i;ioctl requires a file or file descriptor," - " an integer and optionally an integer or buffer argument", - conv_descriptor, &fd, &code, &arg)) { - return NULL; + // Fall-through to outside the 'if' statement. } Py_BEGIN_ALLOW_THREADS -#ifdef __VMS - ret = ioctl(fd, code, (void *)arg); -#else ret = ioctl(fd, code, arg); -#endif Py_END_ALLOW_THREADS if (ret < 0) { PyErr_SetFromErrno(PyExc_IOError); @@ -222,52 +265,25 @@ fcntl_ioctl(PyObject *self, PyObject *args) #undef IOCTL_BUFSZ } -PyDoc_STRVAR(ioctl_doc, -"ioctl(fd, op[, arg[, mutate_flag]])\n\ -\n\ -Perform the operation op on file descriptor fd. The values used for op\n\ -are operating system dependent, and are available as constants in the\n\ -fcntl or termios library modules, using the same names as used in the\n\ -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 not\n\ -passed or is false, the behavior is as if a string had been passed. This\n\ -behavior will change in future releases of Python.\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."); - - -/* flock(fd, operation) */ +/*[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(PyObject *self, PyObject *args) +fcntl_flock_impl(PyModuleDef *module, int fd, int code) +/*[clinic end generated code: output=c9035133a7dbfc96 input=b70a0a41ca22a8a0]*/ { - int fd; - int code; int ret; - if (!PyArg_ParseTuple(args, "O&i:flock", - conv_descriptor, &fd, &code)) - return NULL; - #ifdef HAVE_FLOCK Py_BEGIN_ALLOW_THREADS ret = flock(fd, code); @@ -303,29 +319,50 @@ fcntl_flock(PyObject *self, PyObject *args) PyErr_SetFromErrno(PyExc_IOError); return NULL; } - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(flock_doc, -"flock(fd, operation)\n\ -\n\ -Perform the lock operation op on file descriptor fd. See the Unix \n\ -manual page for flock(2) for details. (On some systems, this function is\n\ -emulated using fcntl().)"); +/*[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 IOError 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]*/ -/* lockf(fd, operation) */ static PyObject * -fcntl_lockf(PyObject *self, PyObject *args) +fcntl_lockf_impl(PyModuleDef *module, int fd, int code, PyObject *lenobj, + PyObject *startobj, int whence) +/*[clinic end generated code: output=31af35eba08b9af7 input=9c594391de821f24]*/ { - int fd, code, ret, whence = 0; - PyObject *lenobj = NULL, *startobj = NULL; - - if (!PyArg_ParseTuple(args, "O&i|OOi:lockf", - conv_descriptor, &fd, &code, - &lenobj, &startobj, &whence)) - return NULL; + int ret; #ifndef LOCK_SH #define LOCK_SH 1 /* shared lock */ @@ -378,43 +415,17 @@ fcntl_lockf(PyObject *self, PyObject *args) PyErr_SetFromErrno(PyExc_IOError); return NULL; } - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(lockf_doc, -"lockf (fd, operation, length=0, start=0, whence=0)\n\ -\n\ -This is essentially a wrapper around the fcntl() locking calls. fd is the\n\ -file descriptor of the file to lock or unlock, and operation is one of the\n\ -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 IOError 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\ -length 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)"); - /* List of functions */ static PyMethodDef fcntl_methods[] = { - {"fcntl", fcntl_fcntl, METH_VARARGS, fcntl_doc}, - {"ioctl", fcntl_ioctl, METH_VARARGS, ioctl_doc}, - {"flock", fcntl_flock, METH_VARARGS, flock_doc}, - {"lockf", fcntl_lockf, METH_VARARGS, lockf_doc}, - {NULL, NULL} /* sentinel */ + FCNTL_FCNTL_METHODDEF + FCNTL_IOCTL_METHODDEF + FCNTL_FLOCK_METHODDEF + FCNTL_LOCKF_METHODDEF + {NULL, NULL} /* sentinel */ }; diff --git a/Modules/fpectlmodule.c b/Modules/fpectlmodule.c index 6af2f82f7073..052b83480daa 100644 --- a/Modules/fpectlmodule.c +++ b/Modules/fpectlmodule.c @@ -70,10 +70,6 @@ extern "C" { #if defined(__FreeBSD__) # include -#elif defined(__VMS) -#define __NEW_STARLET -#include -#include #endif #ifndef WANT_SIGFPE_HANDLER @@ -182,23 +178,6 @@ static void fpe_reset(Sigfunc *handler) ieee_set_fp_control(fp_control); PyOS_setsig(SIGFPE, handler); -/*-- DEC ALPHA VMS --------------------------------------------------------*/ -#elif defined(__ALPHA) && defined(__VMS) - IEEE clrmsk; - IEEE setmsk; - clrmsk.ieee$q_flags = - IEEE$M_TRAP_ENABLE_UNF | IEEE$M_TRAP_ENABLE_INE | - IEEE$M_MAP_UMZ; - setmsk.ieee$q_flags = - IEEE$M_TRAP_ENABLE_INV | IEEE$M_TRAP_ENABLE_DZE | - IEEE$M_TRAP_ENABLE_OVF; - sys$ieee_set_fp_control(&clrmsk, &setmsk, 0); - PyOS_setsig(SIGFPE, handler); - -/*-- HP IA64 VMS --------------------------------------------------------*/ -#elif defined(__ia64) && defined(__VMS) - PyOS_setsig(SIGFPE, handler); - /*-- Cray Unicos ----------------------------------------------------------*/ #elif defined(cray) /* UNICOS delivers SIGFPE by default, but no matherr */ @@ -251,14 +230,6 @@ static PyObject *turnoff_sigfpe(PyObject *self,PyObject *args) #ifdef __FreeBSD__ fpresetsticky(fpgetsticky()); fpsetmask(0); -#elif defined(__VMS) - IEEE clrmsk; - clrmsk.ieee$q_flags = - IEEE$M_TRAP_ENABLE_UNF | IEEE$M_TRAP_ENABLE_INE | - IEEE$M_MAP_UMZ | IEEE$M_TRAP_ENABLE_INV | - IEEE$M_TRAP_ENABLE_DZE | IEEE$M_TRAP_ENABLE_OVF | - IEEE$M_INHERIT; - sys$ieee_set_fp_control(&clrmsk, 0, 0); #else fputs("Operation not implemented\n", stderr); #endif diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index a84d752ffa6c..cb7222db89a6 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -25,6 +25,7 @@ #include "Python.h" #include "frameobject.h" /* for PyFrame_ClearFreeList */ +#include "pytime.h" /* for _PyTime_GetMonotonicClock() */ /* Get an object's GC head */ #define AS_GC(o) ((PyGC_Head *)(o)-1) @@ -166,7 +167,6 @@ static Py_ssize_t long_lived_pending = 0; DEBUG_UNCOLLECTABLE | \ DEBUG_SAVEALL static int debug; -static PyObject *tmod = NULL; /* Running stats per generation */ struct gc_generation_stats { @@ -776,28 +776,40 @@ handle_legacy_finalizers(PyGC_Head *finalizers, PyGC_Head *old) return 0; } +/* 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, PyGC_Head *old) +finalize_garbage(PyGC_Head *collectable) { destructor finalize; - PyGC_Head *gc = collectable->gc.gc_next; + 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); - for (; gc != collectable; gc = gc->gc.gc_next) { + while (!gc_list_is_empty(collectable)) { + PyGC_Head *gc = collectable->gc.gc_next; PyObject *op = FROM_GC(gc); - + gc_list_move(gc, &seen); if (!_PyGCHead_FINALIZED(gc) && - PyType_HasFeature(Py_TYPE(op), Py_TPFLAGS_HAVE_FINALIZE) && - (finalize = Py_TYPE(op)->tp_finalize) != NULL) { + PyType_HasFeature(Py_TYPE(op), Py_TPFLAGS_HAVE_FINALIZE) && + (finalize = Py_TYPE(op)->tp_finalize) != NULL) { _PyGCHead_SET_FINALIZED(gc, 1); Py_INCREF(op); finalize(op); - if (Py_REFCNT(op) == 1) { - /* op will be destroyed */ - gc = gc->gc.gc_prev; - } Py_DECREF(op); } } + gc_list_merge(&seen, collectable); } /* Walk the collectable list and check that they are really unreachable @@ -882,26 +894,6 @@ clear_freelists(void) (void)PySet_ClearFreeList(); } -static double -get_time(void) -{ - double result = 0; - if (tmod != NULL) { - _Py_IDENTIFIER(time); - - PyObject *f = _PyObject_CallMethodId(tmod, &PyId_time, NULL); - if (f == NULL) { - PyErr_Clear(); - } - else { - if (PyFloat_Check(f)) - result = PyFloat_AsDouble(f); - Py_DECREF(f); - } - } - return result; -} - /* This is the main function. Read this to understand how the * collection process works. */ static Py_ssize_t @@ -916,7 +908,8 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, PyGC_Head unreachable; /* non-problematic unreachable trash */ PyGC_Head finalizers; /* objects with, & reachable from, __del__ */ PyGC_Head *gc; - double t1 = 0.0; + _PyTime_t t1 = 0; /* initialize to prevent a compiler warning */ + struct gc_generation_stats *stats = &generation_stats[generation]; if (debug & DEBUG_STATS) { @@ -924,9 +917,10 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, generation); PySys_WriteStderr("gc: objects in each generation:"); for (i = 0; i < NUM_GENERATIONS; i++) - PySys_WriteStderr(" %" PY_FORMAT_SIZE_T "d", + PySys_FormatStderr(" %zd", gc_list_size(GEN_HEAD(i))); - t1 = get_time(); + t1 = _PyTime_GetMonotonicClock(); + PySys_WriteStderr("\n"); } @@ -1006,7 +1000,7 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, m += handle_weakrefs(&unreachable, old); /* Call tp_finalize on objects which have one. */ - finalize_garbage(&unreachable, old); + finalize_garbage(&unreachable); if (check_garbage(&unreachable)) { revive_garbage(&unreachable); @@ -1030,19 +1024,16 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable, debug_cycle("uncollectable", FROM_GC(gc)); } if (debug & DEBUG_STATS) { - double t2 = get_time(); + _PyTime_t t2 = _PyTime_GetMonotonicClock(); + if (m == 0 && n == 0) PySys_WriteStderr("gc: done"); else - PySys_WriteStderr( - "gc: done, " - "%" PY_FORMAT_SIZE_T "d unreachable, " - "%" PY_FORMAT_SIZE_T "d uncollectable", + PySys_FormatStderr( + "gc: done, %zd unreachable, %zd uncollectable", n+m, n); - if (t1 && t2) { - PySys_WriteStderr(", %.4fs elapsed", t2-t1); - } - PySys_WriteStderr(".\n"); + PySys_WriteStderr(", %.4fs elapsed\n", + _PyTime_AsSecondsDouble(t2 - t1)); } /* Append instances in the uncollectable set to a Python @@ -1498,6 +1489,7 @@ PyDoc_STRVAR(gc__doc__, "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" @@ -1568,18 +1560,6 @@ PyInit_gc(void) if (PyModule_AddObject(m, "callbacks", callbacks) < 0) return NULL; - /* Importing can't be done in collect() because collect() - * can be called via PyGC_Collect() in Py_Finalize(). - * This wouldn't be a problem, except that is - * reset to 0 before calling collect which trips up - * the import and triggers an assertion. - */ - if (tmod == NULL) { - tmod = PyImport_ImportModuleNoBlock("time"); - if (tmod == NULL) - PyErr_Clear(); - } - #define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) return NULL ADD_INT(DEBUG_STATS); ADD_INT(DEBUG_COLLECTABLE); @@ -1668,7 +1648,6 @@ void _PyGC_Fini(void) { Py_CLEAR(callbacks); - Py_CLEAR(tmod); } /* for debugging */ @@ -1692,13 +1671,6 @@ PyObject_GC_Track(void *op) _PyObject_GC_TRACK(op); } -/* for binary compatibility with 2.2 */ -void -_PyObject_GC_Track(PyObject *op) -{ - PyObject_GC_Track(op); -} - void PyObject_GC_UnTrack(void *op) { @@ -1709,22 +1681,19 @@ PyObject_GC_UnTrack(void *op) _PyObject_GC_UNTRACK(op); } -/* for binary compatibility with 2.2 */ -void -_PyObject_GC_UnTrack(PyObject *op) -{ - PyObject_GC_UnTrack(op); -} - -PyObject * -_PyObject_GC_Malloc(size_t basicsize) +static PyObject * +_PyObject_GC_Alloc(int use_calloc, size_t basicsize) { PyObject *op; PyGC_Head *g; + size_t size; if (basicsize > PY_SSIZE_T_MAX - sizeof(PyGC_Head)) return PyErr_NoMemory(); - g = (PyGC_Head *)PyObject_MALLOC( - sizeof(PyGC_Head) + basicsize); + 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(); g->gc.gc_refs = 0; @@ -1743,6 +1712,18 @@ _PyObject_GC_Malloc(size_t basicsize) 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) { diff --git a/Modules/getpath.c b/Modules/getpath.c index 9e79c26b9e4a..03d292c18b59 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -110,11 +110,7 @@ #endif #ifndef PREFIX -# ifdef __VMS -# define PREFIX "" -# else -# define PREFIX "/usr/local" -# endif +# define PREFIX "/usr/local" #endif #ifndef EXEC_PREFIX @@ -135,6 +131,23 @@ static wchar_t exec_prefix[MAXPATHLEN+1]; static wchar_t progpath[MAXPATHLEN+1]; static wchar_t *module_search_path = NULL; +/* 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_EncodeLocale(path, NULL); + if (fname == NULL) { + errno = EINVAL; + return -1; + } + err = stat(fname, buf); + PyMem_Free(fname); + return err; +} + static void reduce(wchar_t *dir) { @@ -157,14 +170,14 @@ isfile(wchar_t *filename) /* Is file, not directory */ static int -ismodule(wchar_t *filename) /* Is module -- check for .pyc/.pyo too */ +ismodule(wchar_t *filename) /* Is module -- check for .pyc too */ { if (isfile(filename)) return 1; /* Check for the compiled version of prefix. */ if (wcslen(filename) < MAXPATHLEN) { - wcscat(filename, Py_OptimizeFlag ? L"o" : L"c"); + wcscat(filename, L"c"); if (isfile(filename)) return 1; } @@ -340,7 +353,7 @@ search_for_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_prefix, joinpath(prefix, L"Modules/Setup"); if (isfile(prefix)) { /* Check VPATH to see if argv0_path is in the build directory. */ - vpath = _Py_char2wchar(VPATH, NULL); + vpath = Py_DecodeLocale(VPATH, NULL); if (vpath != NULL) { wcsncpy(prefix, argv0_path, MAXPATHLEN); prefix[MAXPATHLEN] = L'\0'; @@ -495,10 +508,10 @@ calculate_path(void) wchar_t *_pythonpath, *_prefix, *_exec_prefix; wchar_t *lib_python; - _pythonpath = _Py_char2wchar(PYTHONPATH, NULL); - _prefix = _Py_char2wchar(PREFIX, NULL); - _exec_prefix = _Py_char2wchar(EXEC_PREFIX, NULL); - lib_python = _Py_char2wchar("lib/python" VERSION, NULL); + _pythonpath = Py_DecodeLocale(PYTHONPATH, NULL); + _prefix = Py_DecodeLocale(PREFIX, NULL); + _exec_prefix = Py_DecodeLocale(EXEC_PREFIX, NULL); + lib_python = Py_DecodeLocale("lib/python" VERSION, NULL); if (!_pythonpath || !_prefix || !_exec_prefix || !lib_python) { Py_FatalError( @@ -507,7 +520,7 @@ calculate_path(void) } if (_path) { - path_buffer = _Py_char2wchar(_path, NULL); + path_buffer = Py_DecodeLocale(_path, NULL); path = path_buffer; } @@ -588,7 +601,7 @@ calculate_path(void) ** be running the interpreter in the build directory, so we use the ** build-directory-specific logic to find Lib and such. */ - wchar_t* wbuf = _Py_char2wchar(modPath, NULL); + wchar_t* wbuf = Py_DecodeLocale(modPath, NULL); if (wbuf == NULL) { Py_FatalError("Cannot decode framework location"); } @@ -713,7 +726,7 @@ calculate_path(void) if (_rtpypath && _rtpypath[0] != '\0') { size_t rtpypath_len; - rtpypath = _Py_char2wchar(_rtpypath, &rtpypath_len); + rtpypath = Py_DecodeLocale(_rtpypath, &rtpypath_len); if (rtpypath != NULL) bufsz += rtpypath_len + 1; } @@ -739,7 +752,7 @@ calculate_path(void) bufsz += wcslen(zip_path) + 1; bufsz += wcslen(exec_prefix) + 1; - buf = (wchar_t *)PyMem_Malloc(bufsz * sizeof(wchar_t)); + buf = PyMem_New(wchar_t, bufsz); if (buf == NULL) { Py_FatalError( "Not enough memory for dynamic PYTHONPATH"); @@ -878,4 +891,3 @@ Py_GetProgramFullPath(void) #ifdef __cplusplus } #endif - diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c index a85a2715e91f..403e434697b0 100644 --- a/Modules/grpmodule.c +++ b/Modules/grpmodule.c @@ -6,6 +6,12 @@ #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"}, @@ -58,17 +64,12 @@ mkgrent(struct group *p) #define SET(i,val) PyStructSequence_SET_ITEM(v, i, val) SET(setIndex++, PyUnicode_DecodeFSDefault(p->gr_name)); -#ifdef __VMS - SET(setIndex++, Py_None); - Py_INCREF(Py_None); -#else if (p->gr_passwd) SET(setIndex++, PyUnicode_DecodeFSDefault(p->gr_passwd)); else { SET(setIndex++, Py_None); Py_INCREF(Py_None); } -#endif SET(setIndex++, _PyLong_FromGid(p->gr_gid)); SET(setIndex++, w); #undef SET @@ -81,14 +82,25 @@ mkgrent(struct group *p) 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(PyObject *self, PyObject *pyo_id) +grp_getgrgid_impl(PyModuleDef *module, PyObject *id) +/*[clinic end generated code: output=8a11f5fdeb8c78a0 input=15fa0e2ccf5cda25]*/ { PyObject *py_int_id; gid_t gid; struct group *p; - py_int_id = PyNumber_Long(pyo_id); + py_int_id = PyNumber_Long(id); if (!py_int_id) return NULL; if (!_Py_Gid_Converter(py_int_id, &gid)) { @@ -108,22 +120,31 @@ grp_getgrgid(PyObject *self, PyObject *pyo_id) return mkgrent(p); } +/*[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(PyObject *self, PyObject *args) +grp_getgrnam_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: output=cd47511f4854da8e input=08ded29affa3c863]*/ { - char *name; + char *name_chars; struct group *p; - PyObject *arg, *bytes, *retval = NULL; + PyObject *bytes, *retval = NULL; - if (!PyArg_ParseTuple(args, "U:getgrnam", &arg)) - return NULL; - if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL) + if ((bytes = PyUnicode_EncodeFSDefault(name)) == NULL) return NULL; - if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1) + if (PyBytes_AsStringAndSize(bytes, &name_chars, NULL) == -1) goto out; - if ((p = getgrnam(name)) == NULL) { - PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name); + if ((p = getgrnam(name_chars)) == NULL) { + PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name_chars); goto out; } retval = mkgrent(p); @@ -132,8 +153,18 @@ grp_getgrnam(PyObject *self, PyObject *args) 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(PyObject *self, PyObject *ignore) +grp_getgrall_impl(PyModuleDef *module) +/*[clinic end generated code: output=add9037a20c202de input=d7df76c825c367df]*/ { PyObject *d; struct group *p; @@ -156,20 +187,10 @@ grp_getgrall(PyObject *self, PyObject *ignore) } static PyMethodDef grp_methods[] = { - {"getgrgid", grp_getgrgid, METH_O, - "getgrgid(id) -> tuple\n\ -Return the group database entry for the given numeric group ID. If\n\ -id is not valid, raise KeyError."}, - {"getgrnam", grp_getgrnam, METH_VARARGS, - "getgrnam(name) -> tuple\n\ -Return the group database entry for the given group name. If\n\ -name is not valid, raise KeyError."}, - {"getgrall", grp_getgrall, METH_NOARGS, - "getgrall() -> list of tuples\n\ -Return a list of all available group entries, in arbitrary order.\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."}, - {NULL, NULL} /* sentinel */ + GRP_GETGRGID_METHODDEF + GRP_GETGRNAM_METHODDEF + GRP_GETGRALL_METHODDEF + {NULL, NULL} }; PyDoc_STRVAR(grp__doc__, @@ -178,10 +199,10 @@ PyDoc_STRVAR(grp__doc__, Group entries are reported as 4-tuples containing the following fields\n\ from the group database, in order:\n\ \n\ - name - name of the group\n\ - passwd - group password (encrypted); often empty\n\ - gid - numeric ID of the group\n\ - mem - list of members\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\ diff --git a/Modules/hashtable.c b/Modules/hashtable.c index 221ed53b9f60..133f3133ef37 100644 --- a/Modules/hashtable.c +++ b/Modules/hashtable.c @@ -233,11 +233,12 @@ _Py_hashtable_print_stats(_Py_hashtable_t *ht) nchains++; } } - printf("hash table %p: entries=%zu/%zu (%.0f%%), ", + printf("hash table %p: entries=%" + PY_FORMAT_SIZE_T "u/%" PY_FORMAT_SIZE_T "u (%.0f%%), ", 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=%zu, %zu kB\n", + printf("max_chain_len=%" PY_FORMAT_SIZE_T "u, %" PY_FORMAT_SIZE_T "u kB\n", max_chain_len, size / 1024); } #endif @@ -326,7 +327,7 @@ _Py_hashtable_set(_Py_hashtable_t *ht, const void *key, entry->key_hash = key_hash; assert(data_size == ht->data_size); - memcpy(_PY_HASHTABLE_ENTRY_DATA(entry), data, data_size); + memcpy(_Py_HASHTABLE_ENTRY_DATA(entry), data, data_size); _Py_slist_prepend(&ht->buckets[index], (_Py_slist_item_t*)entry); ht->entries++; @@ -504,7 +505,7 @@ _Py_hashtable_copy(_Py_hashtable_t *src) err = 1; } else { - data = _PY_HASHTABLE_ENTRY_DATA(entry); + data = _Py_HASHTABLE_ENTRY_DATA(entry); err = _Py_hashtable_set(dst, entry->key, data, src->data_size); } if (err) { diff --git a/Modules/hashtable.h b/Modules/hashtable.h index 539e490c3197..a9f9993bfd7b 100644 --- a/Modules/hashtable.h +++ b/Modules/hashtable.h @@ -26,16 +26,16 @@ typedef struct { /* data follows */ } _Py_hashtable_entry_t; -#define _PY_HASHTABLE_ENTRY_DATA(ENTRY) \ +#define _Py_HASHTABLE_ENTRY_DATA(ENTRY) \ ((char *)(ENTRY) + sizeof(_Py_hashtable_entry_t)) #define _Py_HASHTABLE_ENTRY_DATA_AS_VOID_P(ENTRY) \ - (*(void **)_PY_HASHTABLE_ENTRY_DATA(ENTRY)) + (*(void **)_Py_HASHTABLE_ENTRY_DATA(ENTRY)) #define _Py_HASHTABLE_ENTRY_READ_DATA(TABLE, DATA, DATA_SIZE, ENTRY) \ do { \ assert((DATA_SIZE) == (TABLE)->data_size); \ - memcpy(DATA, _PY_HASHTABLE_ENTRY_DATA(ENTRY), DATA_SIZE); \ + memcpy(DATA, _Py_HASHTABLE_ENTRY_DATA(ENTRY), DATA_SIZE); \ } while (0) typedef Py_uhash_t (*_Py_hashtable_hash_func) (const void *key); diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 8be62ce94c04..ff7867d5bcb0 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -1,15 +1,16 @@ +#define PY_SSIZE_T_CLEAN #include "Python.h" #include "structmember.h" /* Itertools module written and maintained by Raymond D. Hettinger - Copyright (c) 2003-2013 Python Software Foundation. + Copyright (c) 2003-2015 Python Software Foundation. All rights reserved. */ -/* groupby object ***********************************************************/ +/* groupby object ************************************************************/ typedef struct { PyObject_HEAD @@ -87,8 +88,7 @@ groupby_next(groupbyobject *gbo) else { int rcmp; - rcmp = PyObject_RichCompareBool(gbo->tgtkey, - gbo->currkey, Py_EQ); + rcmp = PyObject_RichCompareBool(gbo->tgtkey, gbo->currkey, Py_EQ); if (rcmp == -1) return NULL; else if (rcmp == 0) @@ -103,8 +103,7 @@ groupby_next(groupbyobject *gbo) newkey = newvalue; Py_INCREF(newvalue); } else { - newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, - newvalue, NULL); + newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, newvalue, NULL); if (newkey == NULL) { Py_DECREF(newvalue); return NULL; @@ -178,7 +177,7 @@ static PyMethodDef groupby_methods[] = { reduce_doc}, {"__setstate__", (PyCFunction)groupby_setstate, METH_O, setstate_doc}, - {NULL, NULL} /* sentinel */ + {NULL, NULL} /* sentinel */ }; PyDoc_STRVAR(groupby_doc, @@ -301,8 +300,7 @@ _grouper_next(_grouperobject *igo) newkey = newvalue; Py_INCREF(newvalue); } else { - newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, - newvalue, NULL); + newkey = PyObject_CallFunctionObjArgs(gbo->keyfunc, newvalue, NULL); if (newkey == NULL) { Py_DECREF(newvalue); return NULL; @@ -330,8 +328,7 @@ _grouper_next(_grouperobject *igo) static PyObject * _grouper_reduce(_grouperobject *lz) { - return Py_BuildValue("O(OO)", Py_TYPE(lz), - lz->parent, lz->tgtkey); + return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->parent, lz->tgtkey); } static PyMethodDef _grouper_methods[] = { @@ -364,7 +361,7 @@ static PyTypeObject _grouper_type = { 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ - (traverseproc)_grouper_traverse,/* tp_traverse */ + (traverseproc)_grouper_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ @@ -385,8 +382,7 @@ static PyTypeObject _grouper_type = { }; - -/* tee object and with supporting function and objects ***************/ +/* 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 @@ -401,7 +397,7 @@ static PyTypeObject _grouper_type = { typedef struct { PyObject_HEAD PyObject *it; - int numread; /* 0 <= numread <= LINKCELLS */ + int numread; /* 0 <= numread <= LINKCELLS */ PyObject *nextlink; PyObject *(values[LINKCELLS]); } teedataobject; @@ -409,7 +405,7 @@ typedef struct { typedef struct { PyObject_HEAD teedataobject *dataobj; - int index; /* 0 <= index <= LINKCELLS */ + int index; /* 0 <= index <= LINKCELLS */ PyObject *weakreflist; } teeobject; @@ -466,6 +462,7 @@ 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]); @@ -515,6 +512,7 @@ teedataobject_reduce(teedataobject *tdo) 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++) { @@ -582,7 +580,7 @@ static PyMethodDef teedataobject_methods[] = { PyDoc_STRVAR(teedataobject_doc, "Data container common to multiple tee objects."); static PyTypeObject teedataobject_type = { - PyVarObject_HEAD_INIT(0, 0) /* Must fill in type value later */ + PyVarObject_HEAD_INIT(0, 0) /* Must fill in type value later */ "itertools._tee_dataobject", /* tp_name */ sizeof(teedataobject), /* tp_basicsize */ 0, /* tp_itemsize */ @@ -602,7 +600,7 @@ static PyTypeObject teedataobject_type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ teedataobject_doc, /* tp_doc */ (traverseproc)teedataobject_traverse, /* tp_traverse */ (inquiry)teedataobject_clear, /* tp_clear */ @@ -759,9 +757,9 @@ PyDoc_STRVAR(teeobject_doc, "Iterator wrapped to make it copyable"); 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}, + {"__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 */ }; @@ -791,7 +789,7 @@ static PyTypeObject tee_type = { (traverseproc)tee_traverse, /* tp_traverse */ (inquiry)tee_clear, /* tp_clear */ 0, /* tp_richcompare */ - offsetof(teeobject, weakreflist), /* tp_weaklistoffset */ + offsetof(teeobject, weakreflist), /* tp_weaklistoffset */ PyObject_SelfIter, /* tp_iter */ (iternextfunc)tee_next, /* tp_iternext */ tee_methods, /* tp_methods */ @@ -857,12 +855,13 @@ PyDoc_STRVAR(tee_doc, "tee(iterable, n=2) --> tuple of n independent iterators."); -/* cycle object **********************************************************/ +/* cycle object **************************************************************/ typedef struct { PyObject_HEAD PyObject *it; PyObject *saved; + Py_ssize_t index; int firstpass; } cycleobject; @@ -902,6 +901,7 @@ cycle_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } lz->it = it; lz->saved = saved; + lz->index = 0; lz->firstpass = 0; return (PyObject *)lz; @@ -911,15 +911,16 @@ static void cycle_dealloc(cycleobject *lz) { PyObject_GC_UnTrack(lz); - Py_XDECREF(lz->saved); Py_XDECREF(lz->it); + Py_XDECREF(lz->saved); Py_TYPE(lz)->tp_free(lz); } static int cycle_traverse(cycleobject *lz, visitproc visit, void *arg) { - Py_VISIT(lz->it); + if (lz->it) + Py_VISIT(lz->it); Py_VISIT(lz->saved); return 0; } @@ -928,57 +929,70 @@ static PyObject * cycle_next(cycleobject *lz) { PyObject *item; - PyObject *it; - PyObject *tmp; - while (1) { + if (lz->it != NULL) { item = PyIter_Next(lz->it); if (item != NULL) { - if (!lz->firstpass && PyList_Append(lz->saved, item)) { + if (lz->firstpass) + return item; + if (PyList_Append(lz->saved, item)) { Py_DECREF(item); return NULL; } return item; } - if (PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_StopIteration)) - PyErr_Clear(); - else - return NULL; - } - if (PyList_Size(lz->saved) == 0) + /* Note: StopIteration is already cleared by PyIter_Next() */ + if (PyErr_Occurred()) return NULL; - it = PyObject_GetIter(lz->saved); - if (it == NULL) - return NULL; - tmp = lz->it; - lz->it = it; - lz->firstpass = 1; - Py_DECREF(tmp); + Py_CLEAR(lz->it); } + if (Py_SIZE(lz->saved) == 0) + return NULL; + item = PyList_GET_ITEM(lz->saved, lz->index); + lz->index++; + if (lz->index >= Py_SIZE(lz->saved)) + lz->index = 0; + Py_INCREF(item); + return item; } static PyObject * cycle_reduce(cycleobject *lz) { - /* Create a new cycle with the iterator tuple, then set - * the saved state on it. - */ - return Py_BuildValue("O(O)(Oi)", Py_TYPE(lz), - lz->it, lz->saved, lz->firstpass); + /* 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 (!PyArg_ParseTuple(state, "Oi", &saved, &firstpass)) + + if (!PyArg_ParseTuple(state, "O!i", &PyList_Type, &saved, &firstpass)) return NULL; + Py_INCREF(saved); Py_CLEAR(lz->saved); lz->saved = saved; - Py_XINCREF(lz->saved); lz->firstpass = firstpass != 0; + lz->index = 0; Py_RETURN_NONE; } @@ -1047,7 +1061,7 @@ typedef struct { PyObject_HEAD PyObject *func; PyObject *it; - long start; + long start; } dropwhileobject; static PyTypeObject dropwhile_type; @@ -1137,8 +1151,7 @@ dropwhile_next(dropwhileobject *lz) static PyObject * dropwhile_reduce(dropwhileobject *lz) { - return Py_BuildValue("O(OO)l", Py_TYPE(lz), - lz->func, lz->it, lz->start); + return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->start); } static PyObject * @@ -1189,13 +1202,13 @@ static PyTypeObject dropwhile_type = { Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ dropwhile_doc, /* tp_doc */ - (traverseproc)dropwhile_traverse, /* tp_traverse */ + (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 */ + dropwhile_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ @@ -1216,7 +1229,7 @@ typedef struct { PyObject_HEAD PyObject *func; PyObject *it; - long stop; + long stop; } takewhileobject; static PyTypeObject takewhile_type; @@ -1291,7 +1304,7 @@ takewhile_next(takewhileobject *lz) } ok = PyObject_IsTrue(good); Py_DECREF(good); - if (ok == 1) + if (ok > 0) return item; Py_DECREF(item); if (ok == 0) @@ -1302,14 +1315,14 @@ takewhile_next(takewhileobject *lz) static PyObject * takewhile_reduce(takewhileobject *lz) { - return Py_BuildValue("O(OO)l", Py_TYPE(lz), - lz->func, lz->it, lz->stop); + 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; @@ -1353,7 +1366,7 @@ static PyTypeObject takewhile_type = { Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ takewhile_doc, /* tp_doc */ - (traverseproc)takewhile_traverse, /* tp_traverse */ + (traverseproc)takewhile_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ @@ -1374,7 +1387,7 @@ static PyTypeObject takewhile_type = { }; -/* islice object ************************************************************/ +/* islice object *************************************************************/ typedef struct { PyObject_HEAD @@ -1410,7 +1423,8 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (PyErr_Occurred()) PyErr_Clear(); PyErr_SetString(PyExc_ValueError, - "Stop argument for islice() must be None or an integer: 0 <= x <= sys.maxsize."); + "Stop argument for islice() must be None or " + "an integer: 0 <= x <= sys.maxsize."); return NULL; } } @@ -1425,14 +1439,16 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (PyErr_Occurred()) PyErr_Clear(); PyErr_SetString(PyExc_ValueError, - "Stop argument for islice() must be None or an integer: 0 <= x <= sys.maxsize."); + "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."); + "Indices for islice() must be None or " + "an integer: 0 <= x <= sys.maxsize."); return NULL; } @@ -1492,19 +1508,22 @@ islice_next(isliceobject *lz) 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) - return NULL; + goto empty; Py_DECREF(item); lz->cnt++; } if (stop != -1 && lz->cnt >= stop) - return NULL; + goto empty; item = iternext(it); if (item == NULL) - return NULL; + goto empty; lz->cnt++; oldnext = lz->next; /* The (size_t) cast below avoids the danger of undefined @@ -1513,6 +1532,10 @@ islice_next(isliceobject *lz) if (lz->next < oldnext || (stop != -1 && lz->next > stop)) lz->next = stop; return item; + +empty: + Py_CLEAR(lz->it); + return NULL; } static PyObject * @@ -1522,6 +1545,19 @@ islice_reduce(isliceobject *lz) * 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); @@ -1539,6 +1575,7 @@ 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; @@ -1753,7 +1790,7 @@ static PyTypeObject starmap_type = { }; -/* chain object ************************************************************/ +/* chain object **************************************************************/ typedef struct { PyObject_HEAD @@ -1829,32 +1866,32 @@ chain_next(chainobject *lz) PyObject *item; if (lz->source == NULL) - return NULL; /* already stopped */ + return NULL; /* already stopped */ if (lz->active == NULL) { PyObject *iterable = PyIter_Next(lz->source); if (iterable == NULL) { Py_CLEAR(lz->source); - return NULL; /* no more input sources */ + 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 */ + return NULL; /* input not iterable */ } } - item = PyIter_Next(lz->active); + 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 */ + return NULL; /* input raised an exception */ } Py_CLEAR(lz->active); - return chain_next(lz); /* recurse and use next active */ + return chain_next(lz); /* recurse and use next active */ } static PyObject * @@ -1880,6 +1917,7 @@ static PyObject * chain_setstate(chainobject *lz, PyObject *state) { PyObject *source, *active=NULL; + if (! PyArg_ParseTuple(state, "O|O", &source, &active)) return NULL; @@ -1906,13 +1944,13 @@ Alternate chain() contructor taking a single iterable argument\n\ that evaluates lazily."); static PyMethodDef chain_methods[] = { - {"from_iterable", (PyCFunction) chain_new_from_iterable, METH_O | METH_CLASS, - chain_from_iterable_doc}, + {"from_iterable", (PyCFunction) chain_new_from_iterable, METH_O | METH_CLASS, + chain_from_iterable_doc}, {"__reduce__", (PyCFunction)chain_reduce, METH_NOARGS, reduce_doc}, {"__setstate__", (PyCFunction)chain_setstate, METH_O, setstate_doc}, - {NULL, NULL} /* sentinel */ + {NULL, NULL} /* sentinel */ }; static PyTypeObject chain_type = { @@ -1964,10 +2002,10 @@ static PyTypeObject chain_type = { 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 product iterator is exhausted */ + 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; @@ -1986,7 +2024,8 @@ product_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyObject *tmpargs = PyTuple_New(0); if (tmpargs == NULL) return NULL; - if (!PyArg_ParseTupleAndKeywords(tmpargs, kwds, "|n:product", kwlist, &repeat)) { + if (!PyArg_ParseTupleAndKeywords(tmpargs, kwds, "|n:product", + kwlist, &repeat)) { Py_DECREF(tmpargs); return NULL; } @@ -1998,11 +2037,19 @@ product_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } } - assert(PyTuple_Check(args)); - nargs = (repeat == 0) ? 0 : PyTuple_GET_SIZE(args); + 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_Malloc(npools * sizeof(Py_ssize_t)); + indices = PyMem_New(Py_ssize_t, npools); if (indices == NULL) { PyErr_NoMemory(); goto error; @@ -2057,6 +2104,18 @@ product_dealloc(productobject *lz) Py_TYPE(lz)->tp_free(lz); } +static PyObject * +product_sizeof(productobject *lz, void *unused) +{ + Py_ssize_t res; + + res = sizeof(productobject); + 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) { @@ -2197,13 +2256,21 @@ product_setstate(productobject *lz, PyObject *state) { PyObject* indexObject = PyTuple_GET_ITEM(state, i); Py_ssize_t index = PyLong_AsSsize_t(indexObject); + PyObject* pool; + Py_ssize_t poolsize; if (index < 0 && PyErr_Occurred()) return NULL; /* not an integer */ + pool = PyTuple_GET_ITEM(lz->pools, 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 > n-1) - index = n-1; + else if (index > poolsize-1) + index = poolsize-1; lz->indices[i] = index; } @@ -2226,6 +2293,8 @@ static PyMethodDef product_methods[] = { reduce_doc}, {"__setstate__", (PyCFunction)product_setstate, METH_O, setstate_doc}, + {"__sizeof__", (PyCFunction)product_sizeof, METH_NOARGS, + sizeof_doc}, {NULL, NULL} /* sentinel */ }; @@ -2246,7 +2315,7 @@ 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 */ + sizeof(productobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)product_dealloc, /* tp_dealloc */ @@ -2288,15 +2357,15 @@ static PyTypeObject product_type = { }; -/* combinations object ************************************************************/ +/* 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 combinations iterator is exhausted */ + 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; @@ -2326,7 +2395,7 @@ combinations_new(PyTypeObject *type, PyObject *args, PyObject *kwds) goto error; } - indices = PyMem_Malloc(r * sizeof(Py_ssize_t)); + indices = PyMem_New(Py_ssize_t, r); if (indices == NULL) { PyErr_NoMemory(); goto error; @@ -2366,6 +2435,16 @@ combinations_dealloc(combinationsobject *co) Py_TYPE(co)->tp_free(co); } +static PyObject * +combinations_sizeof(combinationsobject *co, void *unused) +{ + Py_ssize_t res; + + res = sizeof(combinationsobject); + res += co->r * sizeof(Py_ssize_t); + return PyLong_FromSsize_t(res); +} + static int combinations_traverse(combinationsobject *co, visitproc visit, void *arg) { @@ -2496,17 +2575,16 @@ combinations_setstate(combinationsobject *lz, PyObject *state) Py_ssize_t i; Py_ssize_t n = PyTuple_GET_SIZE(lz->pool); - if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != lz->r) - { + if (!PyTuple_Check(state) || PyTuple_GET_SIZE(state) != lz->r) { PyErr_SetString(PyExc_ValueError, "invalid arguments"); return NULL; } - for (i=0; ir; i++) - { + 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; @@ -2537,6 +2615,8 @@ static PyMethodDef combinations_methods[] = { reduce_doc}, {"__setstate__", (PyCFunction)combinations_setstate, METH_O, setstate_doc}, + {"__sizeof__", (PyCFunction)combinations_sizeof, METH_NOARGS, + sizeof_doc}, {NULL, NULL} /* sentinel */ }; @@ -2591,7 +2671,7 @@ static PyTypeObject combinations_type = { }; -/* combinations with replacement object *******************************************/ +/* combinations with replacement object **************************************/ /* Equivalent to: @@ -2621,11 +2701,11 @@ static PyTypeObject combinations_type = { */ typedef struct { PyObject_HEAD - PyObject *pool; /* input converted to a tuple */ + 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 */ + Py_ssize_t r; /* size of result tuple */ + int stopped; /* set to 1 when the cwr iterator is exhausted */ } cwrobject; static PyTypeObject cwr_type; @@ -2642,8 +2722,9 @@ cwr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) Py_ssize_t i; static char *kwargs[] = {"iterable", "r", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:combinations_with_replacement", kwargs, - &iterable, &r)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "On:combinations_with_replacement", + kwargs, &iterable, &r)) return NULL; pool = PySequence_Tuple(iterable); @@ -2655,7 +2736,7 @@ cwr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) goto error; } - indices = PyMem_Malloc(r * sizeof(Py_ssize_t)); + indices = PyMem_New(Py_ssize_t, r); if (indices == NULL) { PyErr_NoMemory(); goto error; @@ -2695,6 +2776,16 @@ cwr_dealloc(cwrobject *co) Py_TYPE(co)->tp_free(co); } +static PyObject * +cwr_sizeof(cwrobject *co, void *unused) +{ + Py_ssize_t res; + + res = sizeof(cwrobject); + res += co->r * sizeof(Py_ssize_t); + return PyLong_FromSsize_t(res); +} + static int cwr_traverse(cwrobject *co, visitproc visit, void *arg) { @@ -2724,11 +2815,13 @@ cwr_next(cwrobject *co) if (result == NULL) goto empty; co->result = result; - elem = PyTuple_GET_ITEM(pool, 0); - for (i=0; i 0) { + elem = PyTuple_GET_ITEM(pool, 0); + for (i=0; ir); if (!indices) return NULL; - for (i=0; ir; i++) - { + for (i=0; ir; i++) { PyObject* index = PyLong_FromSsize_t(lz->indices[i]); if (!index) { Py_DECREF(indices); @@ -2823,10 +2915,10 @@ cwr_setstate(cwrobject *lz, PyObject *state) } n = PyTuple_GET_SIZE(lz->pool); - for (i=0; ir; i++) - { + 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 */ @@ -2854,6 +2946,8 @@ static PyMethodDef cwr_methods[] = { reduce_doc}, {"__setstate__", (PyCFunction)cwr_setstate, METH_O, setstate_doc}, + {"__sizeof__", (PyCFunction)cwr_sizeof, METH_NOARGS, + sizeof_doc}, {NULL, NULL} /* sentinel */ }; @@ -2909,7 +3003,7 @@ static PyTypeObject cwr_type = { }; -/* permutations object ************************************************************ +/* permutations object ******************************************************** def permutations(iterable, r=None): 'permutations(range(3), 2) --> (0,1) (0,2) (1,0) (1,2) (2,0) (2,1)' @@ -2920,28 +3014,28 @@ def permutations(iterable, r=None): 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 + 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: - j = cycles[i] - indices[i], indices[-j] = indices[-j], indices[i] - yield tuple(pool[i] for i in indices[:r]) - break - else: - return + 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 permutations iterator is exhausted */ + 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; @@ -2984,8 +3078,8 @@ permutations_new(PyTypeObject *type, PyObject *args, PyObject *kwds) goto error; } - indices = PyMem_Malloc(n * sizeof(Py_ssize_t)); - cycles = PyMem_Malloc(r * sizeof(Py_ssize_t)); + indices = PyMem_New(Py_ssize_t, n); + cycles = PyMem_New(Py_ssize_t, r); if (indices == NULL || cycles == NULL) { PyErr_NoMemory(); goto error; @@ -3030,6 +3124,17 @@ permutations_dealloc(permutationsobject *po) Py_TYPE(po)->tp_free(po); } +static PyObject * +permutations_sizeof(permutationsobject *po, void *unused) +{ + Py_ssize_t res; + + res = sizeof(permutationsobject); + 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) { @@ -3145,7 +3250,7 @@ permutations_reduce(permutationsobject *po) indices = PyTuple_New(n); if (indices == NULL) goto err; - for (i=0; iindices[i]); if (!index) goto err; @@ -3155,8 +3260,7 @@ permutations_reduce(permutationsobject *po) cycles = PyTuple_New(po->r); if (cycles == NULL) goto err; - for (i=0; ir; i++) - { + for (i=0 ; ir ; i++) { PyObject* index = PyLong_FromSsize_t(po->cycles[i]); if (!index) goto err; @@ -3184,15 +3288,12 @@ permutations_setstate(permutationsobject *po, PyObject *state) return NULL; n = PyTuple_GET_SIZE(po->pool); - if (PyTuple_GET_SIZE(indices) != n || - PyTuple_GET_SIZE(cycles) != po->r) - { + if (PyTuple_GET_SIZE(indices) != n || PyTuple_GET_SIZE(cycles) != po->r) { PyErr_SetString(PyExc_ValueError, "invalid arguments"); return NULL; } - for (i=0; iindices[i] = index; } - for (i=0; ir; i++) - { + 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()) @@ -3235,6 +3335,8 @@ static PyMethodDef permuations_methods[] = { reduce_doc}, {"__setstate__", (PyCFunction)permutations_setstate, METH_O, setstate_doc}, + {"__sizeof__", (PyCFunction)permutations_sizeof, METH_NOARGS, + sizeof_doc}, {NULL, NULL} /* sentinel */ }; @@ -3246,11 +3348,11 @@ permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)"); static PyTypeObject permutations_type = { PyVarObject_HEAD_INIT(NULL, 0) - "itertools.permutations", /* tp_name */ + "itertools.permutations", /* tp_name */ sizeof(permutationsobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ - (destructor)permutations_dealloc, /* tp_dealloc */ + (destructor)permutations_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -3267,13 +3369,13 @@ static PyTypeObject permutations_type = { 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ - permutations_doc, /* tp_doc */ - (traverseproc)permutations_traverse, /* tp_traverse */ + 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 */ + (iternextfunc)permutations_next, /* tp_iternext */ permuations_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ @@ -3284,11 +3386,11 @@ static PyTypeObject permutations_type = { 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - permutations_new, /* tp_new */ + permutations_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ }; -/* accumulate object ************************************************************/ +/* accumulate object ********************************************************/ typedef struct { PyObject_HEAD @@ -3357,7 +3459,7 @@ accumulate_next(accumulateobject *lz) { PyObject *val, *oldtotal, *newtotal; - val = PyIter_Next(lz->it); + val = (*Py_TYPE(lz->it)->tp_iternext)(lz->it); if (val == NULL) return NULL; @@ -3389,7 +3491,7 @@ accumulate_reduce(accumulateobject *lz) 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) @@ -3552,7 +3654,7 @@ compress_next(compressobject *lz) ok = PyObject_IsTrue(selector); Py_DECREF(selector); - if (ok == 1) + if (ok > 0) return datum; Py_DECREF(datum); if (ok < 0) @@ -3565,7 +3667,7 @@ compress_reduce(compressobject *lz) { return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->data, lz->selectors); - } +} static PyMethodDef compress_methods[] = { {"__reduce__", (PyCFunction)compress_reduce, METH_NOARGS, @@ -3584,44 +3686,44 @@ static PyTypeObject compress_type = { PyVarObject_HEAD_INIT(NULL, 0) "itertools.compress", /* tp_name */ sizeof(compressobject), /* tp_basicsize */ - 0, /* tp_itemsize */ + 0, /* tp_itemsize */ /* methods */ (destructor)compress_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_reserved */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - compress_doc, /* tp_doc */ - (traverseproc)compress_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ + Py_TPFLAGS_BASETYPE, /* tp_flags */ + 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 */ - compress_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ + 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 */ + compress_new, /* tp_new */ + PyObject_GC_Del, /* tp_free */ }; @@ -3702,8 +3804,7 @@ filterfalse_next(filterfalseobject *lz) ok = PyObject_IsTrue(item); } else { PyObject *good; - good = PyObject_CallFunctionObjArgs(lz->func, - item, NULL); + good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); if (good == NULL) { Py_DECREF(item); return NULL; @@ -3722,9 +3823,8 @@ filterfalse_next(filterfalseobject *lz) static PyObject * filterfalse_reduce(filterfalseobject *lz) { - return Py_BuildValue("O(OO)", Py_TYPE(lz), - lz->func, lz->it); - } + return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); +} static PyMethodDef filterfalse_methods[] = { {"__reduce__", (PyCFunction)filterfalse_reduce, METH_NOARGS, @@ -3744,7 +3844,7 @@ static PyTypeObject filterfalse_type = { sizeof(filterfalseobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ - (destructor)filterfalse_dealloc, /* tp_dealloc */ + (destructor)filterfalse_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -3762,7 +3862,7 @@ static PyTypeObject filterfalse_type = { Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ filterfalse_doc, /* tp_doc */ - (traverseproc)filterfalse_traverse, /* tp_traverse */ + (traverseproc)filterfalse_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ @@ -3796,7 +3896,7 @@ typedef struct { 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==PyInt(1)); + 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. @@ -4001,15 +4101,15 @@ static PyTypeObject count_type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_BASETYPE, /* tp_flags */ count_doc, /* tp_doc */ - (traverseproc)count_traverse, /* tp_traverse */ + (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 */ + count_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ @@ -4039,14 +4139,17 @@ repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { repeatobject *ro; PyObject *element; - Py_ssize_t cnt = -1; + 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 (PyTuple_Size(args) == 2 && cnt < 0) + if (kwds != NULL) + n_kwds = PyDict_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); @@ -4172,9 +4275,7 @@ static PyTypeObject repeat_type = { PyObject_GC_Del, /* tp_free */ }; -/* ziplongest object ************************************************************/ - -#include "Python.h" +/* ziplongest object *********************************************************/ typedef struct { PyObject_HEAD @@ -4213,7 +4314,7 @@ zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ittuple = PyTuple_New(tuplesize); if (ittuple == NULL) return NULL; - for (i=0; i < tuplesize; ++i) { + for (i=0; i < tuplesize; i++) { PyObject *item = PyTuple_GET_ITEM(args, i); PyObject *it = PyObject_GetIter(item); if (it == NULL) { @@ -4354,6 +4455,7 @@ zip_longest_reduce(ziplongestobject *lz) */ int i; PyObject *args = PyTuple_New(PyTuple_GET_SIZE(lz->ittuple)); + if (args == NULL) return NULL; for (i=0; iittuple); i++) { @@ -4405,7 +4507,7 @@ static PyTypeObject ziplongest_type = { sizeof(ziplongestobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ - (destructor)zip_longest_dealloc, /* tp_dealloc */ + (destructor)zip_longest_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -4422,8 +4524,8 @@ static PyTypeObject ziplongest_type = { 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 */ + zip_longest_doc, /* tp_doc */ + (traverseproc)zip_longest_traverse, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ @@ -4439,7 +4541,7 @@ static PyTypeObject ziplongest_type = { 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ - zip_longest_new, /* tp_new */ + zip_longest_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ }; diff --git a/Modules/ld_so_aix.in b/Modules/ld_so_aix.in index 86a9f7e15e64..961532bb918d 100644 --- a/Modules/ld_so_aix.in +++ b/Modules/ld_so_aix.in @@ -5,7 +5,7 @@ # TYPE: executable, uses makexp_aix # SYSTEM: AIX # -# DESCRIPTION: Creates a shareable .o from a set of pre-compiled +# DESCRIPTION: Creates a shareable .o from a set of pre-compiled # (unshared) .o files # # USAGE: ld_so_aix [CC] [arguments] @@ -46,7 +46,7 @@ # 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 @@ -132,7 +132,7 @@ do done if test "$objfile" = "libpython@VERSION@@ABIFLAGS@.so"; then - ldsocoremode="true" + ldsocoremode="true" fi if test -z "$objs"; then diff --git a/Modules/main.c b/Modules/main.c index 9171070ab5dd..2a9ea2882c28 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -5,16 +5,10 @@ #include -#ifdef __VMS -#error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4" -#include -#endif - #if defined(MS_WINDOWS) || defined(__CYGWIN__) #include #ifdef HAVE_FCNTL_H #include -#define PATH_MAX MAXPATHLEN #endif #endif @@ -124,19 +118,7 @@ usage(int exitcode, wchar_t* program) fprintf(f, usage_5, DELIM, PYTHONHOMEHELP); fputs(usage_6, f); } -#if defined(__VMS) - if (exitcode == 0) { - /* suppress 'error' message */ - return 1; - } - else { - /* STS$M_INHIB_MSG + SS$_ABORT */ - return 0x1000002c; - } -#else return exitcode; -#endif - /*NOTREACHED*/ } static void RunStartupFile(PyCompilerFlags *cf) @@ -360,6 +342,8 @@ Py_Main(int argc, wchar_t **argv) int version = 0; int saw_unbuffered_flag = 0; PyCompilerFlags cf; + PyObject *warning_option = NULL; + PyObject *warning_options = NULL; cf.cf_flags = 0; @@ -482,7 +466,15 @@ Py_Main(int argc, wchar_t **argv) break; case 'W': - PySys_AddWarnOption(_PyOS_optarg); + if (warning_options == NULL) + warning_options = PyList_New(0); + if (warning_options == NULL) + Py_FatalError("failure in handling of -W argument"); + warning_option = PyUnicode_FromWideChar(_PyOS_optarg, -1); + if (warning_option == NULL) + Py_FatalError("failure in handling of -W argument"); + PyList_Append(warning_options, warning_option); + Py_DECREF(warning_option); break; case 'X': @@ -528,16 +520,16 @@ Py_Main(int argc, wchar_t **argv) #ifdef MS_WINDOWS if (!Py_IgnoreEnvironmentFlag && (wp = _wgetenv(L"PYTHONWARNINGS")) && *wp != L'\0') { - wchar_t *buf, *warning; + wchar_t *buf, *warning, *context = NULL; buf = (wchar_t *)PyMem_RawMalloc((wcslen(wp) + 1) * sizeof(wchar_t)); if (buf == NULL) Py_FatalError( "not enough memory to copy PYTHONWARNINGS"); wcscpy(buf, wp); - for (warning = wcstok(buf, L","); + for (warning = wcstok_s(buf, L",", &context); warning != NULL; - warning = wcstok(NULL, L",")) { + warning = wcstok_s(NULL, L",", &context)) { PySys_AddWarnOption(warning); } PyMem_RawFree(buf); @@ -576,18 +568,17 @@ Py_Main(int argc, wchar_t **argv) PyMem_RawFree(buf); } #endif + if (warning_options != NULL) { + Py_ssize_t i; + for (i = 0; i < PyList_GET_SIZE(warning_options); i++) { + PySys_AddWarnOptionUnicode(PyList_GET_ITEM(warning_options, i)); + } + } if (command == NULL && module == NULL && _PyOS_optind < argc && wcscmp(argv[_PyOS_optind], L"-") != 0) { -#ifdef __VMS - filename = decc$translate_vms(argv[_PyOS_optind]); - if (filename == (char *)0 || filename == (char *)-1) - filename = argv[_PyOS_optind]; - -#else filename = argv[_PyOS_optind]; -#endif } stdin_is_interactive = Py_FdIsInteractive(stdin, (char *)0); @@ -623,11 +614,6 @@ Py_Main(int argc, wchar_t **argv) #endif /* !MS_WINDOWS */ /* Leave stderr alone - it should be unbuffered anyway. */ } -#ifdef __VMS - else { - setvbuf (stdout, (char *)NULL, _IOLBF, BUFSIZ); - } -#endif /* __VMS */ #ifdef __APPLE__ /* On MacOS X, when the Python interpreter is embedded in an @@ -660,7 +646,7 @@ Py_Main(int argc, wchar_t **argv) /* Used by Mac/Tools/pythonw.c to forward * the argv0 of the stub executable */ - wchar_t* wbuf = _Py_char2wchar(pyvenv_launcher, NULL); + wchar_t* wbuf = Py_DecodeLocale(pyvenv_launcher, NULL); if (wbuf == NULL) { Py_FatalError("Cannot decode __PYVENV_LAUNCHER__"); @@ -681,6 +667,7 @@ Py_Main(int argc, wchar_t **argv) Py_SetProgramName(argv[0]); #endif Py_Initialize(); + Py_XDECREF(warning_options); if (!Py_QuietFlag && (Py_VerboseFlag || (command == NULL && filename == NULL && @@ -742,7 +729,7 @@ Py_Main(int argc, wchar_t **argv) char *cfilename_buffer; const char *cfilename; int err = errno; - cfilename_buffer = _Py_wchar2char(filename, NULL); + cfilename_buffer = Py_EncodeLocale(filename, NULL); if (cfilename_buffer != NULL) cfilename = cfilename_buffer; else @@ -765,11 +752,12 @@ Py_Main(int argc, wchar_t **argv) } } { - /* XXX: does this work on Win/Win64? (see posix_fstat) */ - struct stat sb; - if (fstat(fileno(fp), &sb) == 0 && + 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", argv[0], filename); + fprintf(stderr, + "%ls: '%ls' is a directory, cannot continue\n", + argv[0], filename); fclose(fp); return 1; } diff --git a/Modules/makesetup b/Modules/makesetup index 40dfa9db488a..90db42e4b20d 100755 --- a/Modules/makesetup +++ b/Modules/makesetup @@ -217,7 +217,7 @@ sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' | *) src='http://github.com/$(srcdir)/'"$srcdir/$src";; esac case $doconfig in - no) cc="$cc \$(CCSHARED) \$(CFLAGS) \$(CPPFLAGS)";; + no) cc="$cc \$(CCSHARED) \$(PY_CFLAGS) \$(PY_CPPFLAGS)";; *) cc="$cc \$(PY_CORE_CFLAGS)";; esac @@ -229,11 +229,7 @@ sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' | esac for mod in $mods do - case $objs in - *$mod.o*) base=$mod;; - *) base=${mod}module;; - esac - file="$srcdir/$base\$(SO)" + file="$srcdir/$mod\$(EXT_SUFFIX)" case $doconfig in no) SHAREDMODS="$SHAREDMODS $file";; esac @@ -270,7 +266,7 @@ sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' | *) sed -e " 1i$NL/* Generated automatically from $config by makesetup. */ /MARKER 1/i$NL$EXTDECLS - + /MARKER 2/i$NL$INITBITS " $config >config.c diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 4b3e642ff60a..9359eb2b3a0f 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -223,6 +223,35 @@ lanczos_sum(double x) 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) { @@ -656,6 +685,33 @@ m_log10(double x) } +static PyObject * +math_gcd(PyObject *self, PyObject *args) +{ + PyObject *a, *b, *g; + + if (!PyArg_ParseTuple(args, "OO:gcd", &a, &b)) + return NULL; + + 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; +} + +PyDoc_STRVAR(math_gcd_doc, +"gcd(x, y) -> int\n\ +greatest common divisor of x and y"); + + /* 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. @@ -873,18 +929,18 @@ math_2(PyObject *args, double (*func) (double, double), char *funcname) FUNC1(acos, acos, 0, "acos(x)\n\nReturn the arc cosine (measured in radians) of x.") FUNC1(acosh, m_acosh, 0, - "acosh(x)\n\nReturn the hyperbolic arc cosine (measured in radians) of x.") + "acosh(x)\n\nReturn the inverse hyperbolic cosine of x.") FUNC1(asin, asin, 0, "asin(x)\n\nReturn the arc sine (measured in radians) of x.") FUNC1(asinh, m_asinh, 0, - "asinh(x)\n\nReturn the hyperbolic arc sine (measured in radians) of x.") + "asinh(x)\n\nReturn the inverse hyperbolic sine of x.") FUNC1(atan, atan, 0, "atan(x)\n\nReturn the arc tangent (measured in radians) of x.") FUNC2(atan2, m_atan2, "atan2(y, x)\n\nReturn the arc tangent (measured in radians) of y/x.\n" "Unlike atan(y/x), the signs of both x and y are considered.") FUNC1(atanh, m_atanh, 0, - "atanh(x)\n\nReturn the hyperbolic arc tangent (measured in radians) of x.") + "atanh(x)\n\nReturn the inverse hyperbolic tangent of x.") static PyObject * math_ceil(PyObject *self, PyObject *number) { _Py_IDENTIFIER(__ceil__); @@ -906,7 +962,9 @@ PyDoc_STRVAR(math_ceil_doc, "This is the smallest integral value >= x."); FUNC2(copysign, copysign, - "copysign(x, y)\n\nReturn x with the sign of y.") + "copysign(x, y)\n\nReturn a float with the magnitude (absolute value) " + "of x but the sign \nof y. On platforms that support signed zeros, " + "copysign(1.0, -0.0) \nreturns -1.0.\n") FUNC1(cos, cos, 0, "cos(x)\n\nReturn the cosine of x (measured in radians).") FUNC1(cosh, cosh, 1, @@ -990,7 +1048,7 @@ FUNC1(tanh, tanh, 0, 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 __builtin__.sum() + 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 @@ -1008,7 +1066,7 @@ _fsum_realloc(double **p_ptr, Py_ssize_t n, Py_ssize_t m = *m_ptr; m += m; /* double */ - if (n < m && m < (PY_SSIZE_T_MAX / sizeof(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); @@ -1406,6 +1464,7 @@ static PyObject * math_factorial(PyObject *self, PyObject *arg) { long x; + int overflow; PyObject *result, *odd_part, *two_valuation; if (PyFloat_Check(arg)) { @@ -1419,15 +1478,22 @@ math_factorial(PyObject *self, PyObject *arg) lx = PyLong_FromDouble(dx); if (lx == NULL) return NULL; - x = PyLong_AsLong(lx); + x = PyLong_AsLongAndOverflow(lx, &overflow); Py_DECREF(lx); } else - x = PyLong_AsLong(arg); + x = PyLong_AsLongAndOverflow(arg, &overflow); - if (x == -1 && PyErr_Occurred()) + if (x == -1 && PyErr_Occurred()) { return NULL; - if (x < 0) { + } + 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; @@ -1924,6 +1990,83 @@ PyDoc_STRVAR(math_isinf_doc, "isinf(x) -> bool\n\n\ Return True if x is a positive or negative infinity, and False otherwise."); +static PyObject * +math_isclose(PyObject *self, PyObject *args, PyObject *kwargs) +{ + double a, b; + double rel_tol = 1e-9; + double abs_tol = 0.0; + double diff = 0.0; + long result = 0; + + static char *keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL}; + + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "dd|$dd:isclose", + keywords, + &a, &b, &rel_tol, &abs_tol + )) + return NULL; + + /* sanity check on the inputs */ + if (rel_tol < 0.0 || abs_tol < 0.0 ) { + PyErr_SetString(PyExc_ValueError, + "tolerances must be non-negative"); + return NULL; + } + + if ( a == b ) { + /* short circuit exact equality -- needed to catch two infinities of + the same sign. And perhaps speeds things up a bit sometimes. + */ + Py_RETURN_TRUE; + } + + /* 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)) { + Py_RETURN_FALSE; + } + + /* now do the regular computation + this is essentially the "weak" test from the Boost library + */ + + diff = fabs(b - a); + + result = (((diff <= fabs(rel_tol * b)) || + (diff <= fabs(rel_tol * a))) || + (diff <= abs_tol)); + + return PyBool_FromLong(result); +} + +PyDoc_STRVAR(math_isclose_doc, +"is_close(a, b, *, rel_tol=1e-09, abs_tol=0.0) -> bool\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."); + static PyMethodDef math_methods[] = { {"acos", math_acos, METH_O, math_acos_doc}, {"acosh", math_acosh, METH_O, math_acosh_doc}, @@ -1948,7 +2091,10 @@ static PyMethodDef math_methods[] = { {"frexp", math_frexp, METH_O, math_frexp_doc}, {"fsum", math_fsum, METH_O, math_fsum_doc}, {"gamma", math_gamma, METH_O, math_gamma_doc}, + {"gcd", math_gcd, METH_VARARGS, math_gcd_doc}, {"hypot", math_hypot, METH_VARARGS, math_hypot_doc}, + {"isclose", (PyCFunction) math_isclose, METH_VARARGS | METH_KEYWORDS, + math_isclose_doc}, {"isfinite", math_isfinite, METH_O, math_isfinite_doc}, {"isinf", math_isinf, METH_O, math_isinf_doc}, {"isnan", math_isnan, METH_O, math_isnan_doc}, @@ -1999,7 +2145,11 @@ PyInit_math(void) PyModule_AddObject(m, "pi", PyFloat_FromDouble(Py_MATH_PI)); PyModule_AddObject(m, "e", PyFloat_FromDouble(Py_MATH_E)); + 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: + finally: return m; } diff --git a/Modules/md5module.c b/Modules/md5module.c index 5cb3d36c9b09..a9ebc8cc51c5 100644 --- a/Modules/md5module.c +++ b/Modules/md5module.c @@ -18,7 +18,13 @@ #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 */ @@ -48,6 +54,7 @@ typedef struct { struct md5_state hash_state; } MD5object; +#include "clinic/md5module.c.h" /* ------------------------------------------------------------------------ * @@ -332,30 +339,34 @@ MD5_dealloc(PyObject *ptr) /* External methods for a hash object */ -PyDoc_STRVAR(MD5_copy__doc__, "Return a copy of the hash object."); +/*[clinic input] +MD5Type.copy + +Return a copy of the hash object. +[clinic start generated code]*/ static PyObject * -MD5_copy(MD5object *self, PyObject *unused) +MD5Type_copy_impl(MD5object *self) +/*[clinic end generated code: output=596eb36852f02071 input=2c09e6d2493f3079]*/ { MD5object *newobj; - if (Py_TYPE(self) == &MD5type) { - if ( (newobj = newMD5object())==NULL) - return NULL; - } else { - if ( (newobj = newMD5object())==NULL) - return NULL; - } + if ((newobj = newMD5object())==NULL) + return NULL; newobj->hash_state = self->hash_state; return (PyObject *)newobj; } -PyDoc_STRVAR(MD5_digest__doc__, -"Return the digest value as a string of binary data."); +/*[clinic input] +MD5Type.digest + +Return the digest value as a string of binary data. +[clinic start generated code]*/ static PyObject * -MD5_digest(MD5object *self, PyObject *unused) +MD5Type_digest_impl(MD5object *self) +/*[clinic end generated code: output=eb691dc4190a07ec input=7b96e65389412a34]*/ { unsigned char digest[MD5_DIGESTSIZE]; struct md5_state temp; @@ -365,54 +376,41 @@ MD5_digest(MD5object *self, PyObject *unused) return PyBytes_FromStringAndSize((const char *)digest, MD5_DIGESTSIZE); } -PyDoc_STRVAR(MD5_hexdigest__doc__, -"Return the digest value as a string of hexadecimal digits."); +/*[clinic input] +MD5Type.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ static PyObject * -MD5_hexdigest(MD5object *self, PyObject *unused) +MD5Type_hexdigest_impl(MD5object *self) +/*[clinic end generated code: output=17badced1f3ac932 input=b60b19de644798dd]*/ { unsigned char digest[MD5_DIGESTSIZE]; struct md5_state temp; - PyObject *retval; - Py_UCS1 *hex_digest; - int i, j; /* Get the raw (binary) digest value */ temp = self->hash_state; md5_done(&temp, digest); - /* Create a new string */ - retval = PyUnicode_New(MD5_DIGESTSIZE * 2, 127); - if (!retval) - return NULL; - hex_digest = PyUnicode_1BYTE_DATA(retval); - - /* Make hex version of the digest */ - for(i=j=0; i> 4) & 0xf; - hex_digest[j++] = Py_hexdigits[c]; - c = (digest[i] & 0xf); - hex_digest[j++] = Py_hexdigits[c]; - } -#ifdef Py_DEBUG - assert(_PyUnicode_CheckConsistency(retval, 1)); -#endif - return retval; + return _Py_strhex((const char*)digest, MD5_DIGESTSIZE); } -PyDoc_STRVAR(MD5_update__doc__, -"Update this hash object's state with the provided string."); +/*[clinic input] +MD5Type.update + + obj: object + / + +Update this hash object's state with the provided string. +[clinic start generated code]*/ static PyObject * -MD5_update(MD5object *self, PyObject *args) +MD5Type_update(MD5object *self, PyObject *obj) +/*[clinic end generated code: output=f6ad168416338423 input=6e1efcd9ecf17032]*/ { - PyObject *obj; Py_buffer buf; - if (!PyArg_ParseTuple(args, "O:update", &obj)) - return NULL; - GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); md5_process(&self->hash_state, buf.buf, buf.len); @@ -423,10 +421,10 @@ MD5_update(MD5object *self, PyObject *args) } static PyMethodDef MD5_methods[] = { - {"copy", (PyCFunction)MD5_copy, METH_NOARGS, MD5_copy__doc__}, - {"digest", (PyCFunction)MD5_digest, METH_NOARGS, MD5_digest__doc__}, - {"hexdigest", (PyCFunction)MD5_hexdigest, METH_NOARGS, MD5_hexdigest__doc__}, - {"update", (PyCFunction)MD5_update, METH_VARARGS, MD5_update__doc__}, + MD5TYPE_COPY_METHODDEF + MD5TYPE_DIGEST_METHODDEF + MD5TYPE_HEXDIGEST_METHODDEF + MD5TYPE_UPDATE_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -502,27 +500,26 @@ static PyTypeObject MD5type = { /* The single module-level function: new() */ -PyDoc_STRVAR(MD5_new__doc__, -"Return a new MD5 hash object; optionally initialized with a string."); +/*[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_new(PyObject *self, PyObject *args, PyObject *kwdict) +_md5_md5_impl(PyModuleDef *module, PyObject *string) +/*[clinic end generated code: output=3527436a2090b956 input=d12ef8f72d684f7b]*/ { - static char *kwlist[] = {"string", NULL}; MD5object *new; - PyObject *data_obj = NULL; Py_buffer buf; - if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|O:new", kwlist, - &data_obj)) { - return NULL; - } - - if (data_obj) - GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf); + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); if ((new = newMD5object()) == NULL) { - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } @@ -531,11 +528,11 @@ MD5_new(PyObject *self, PyObject *args, PyObject *kwdict) if (PyErr_Occurred()) { Py_DECREF(new); - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } - if (data_obj) { + if (string) { md5_process(&new->hash_state, buf.buf, buf.len); PyBuffer_Release(&buf); } @@ -547,7 +544,7 @@ MD5_new(PyObject *self, PyObject *args, PyObject *kwdict) /* List of functions exported by this module */ static struct PyMethodDef MD5_functions[] = { - {"md5", (PyCFunction)MD5_new, METH_VARARGS|METH_KEYWORDS, MD5_new__doc__}, + _MD5_MD5_METHODDEF {NULL, NULL} /* Sentinel */ }; diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 366dac15e675..daab52b3880b 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -24,9 +24,9 @@ #ifndef MS_WINDOWS #define UNIX -# ifdef __APPLE__ +# ifdef HAVE_FCNTL_H # include -# endif +# endif /* HAVE_FCNTL_H */ #endif #ifdef MS_WINDOWS @@ -301,16 +301,17 @@ mmap_gfind(mmap_object *self, { Py_ssize_t start = self->pos; Py_ssize_t end = self->size; - const char *needle; - Py_ssize_t len; + Py_buffer view; CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, reverse ? "y#|nn:rfind" : "y#|nn:find", - &needle, &len, &start, &end)) { + 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; @@ -335,9 +336,11 @@ mmap_gfind(mmap_object *self, 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); } } @@ -385,22 +388,25 @@ static PyObject * mmap_write_method(mmap_object *self, PyObject *args) { - Py_ssize_t length; - char *data; + Py_buffer data; CHECK_VALID(NULL); - if (!PyArg_ParseTuple(args, "y#:write", &data, &length)) + if (!PyArg_ParseTuple(args, "y*:write", &data)) return(NULL); - if (!is_writable(self)) + if (!is_writable(self)) { + PyBuffer_Release(&data); return NULL; + } - if ((self->pos + length) > self->size) { + if ((self->pos + data.len) > self->size) { PyErr_SetString(PyExc_ValueError, "data out of range"); + PyBuffer_Release(&data); return NULL; } - memcpy(self->data+self->pos, data, length); - self->pos = self->pos+length; + memcpy(self->data + self->pos, data.buf, data.len); + self->pos = self->pos + data.len; + PyBuffer_Release(&data); Py_INCREF(Py_None); return Py_None; } @@ -459,15 +465,13 @@ mmap_size_method(mmap_object *self, #ifdef UNIX { - struct stat buf; - if (-1 == fstat(self->fd, &buf)) { - PyErr_SetFromErrno(PyExc_OSError); + struct _Py_stat_struct status; + if (_Py_fstat(self->fd, &status) == -1) return NULL; - } #ifdef HAVE_LARGEFILE_SUPPORT - return PyLong_FromLongLong(buf.st_size); + return PyLong_FromLongLong(status.st_size); #else - return PyLong_FromLong(buf.st_size); + return PyLong_FromLong(status.st_size); #endif } #endif /* UNIX */ @@ -709,6 +713,19 @@ mmap__exit__method(PyObject *self, PyObject *args) 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 = sizeof(mmap_object); + if (self->tagname) + res += strlen(self->tagname) + 1; + return PyLong_FromSsize_t(res); +} +#endif + static struct PyMethodDef mmap_object_methods[] = { {"close", (PyCFunction) mmap_close_method, METH_NOARGS}, {"find", (PyCFunction) mmap_find_method, METH_VARARGS}, @@ -726,6 +743,9 @@ static struct PyMethodDef mmap_object_methods[] = { {"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 */ }; @@ -1090,9 +1110,7 @@ _GetMapSize(PyObject *o, const char* param) static PyObject * new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) { -#ifdef HAVE_FSTAT - struct stat st; -#endif + struct _Py_stat_struct status; mmap_object *m_obj; PyObject *map_size_obj = NULL; Py_ssize_t map_size; @@ -1157,38 +1175,31 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) if (fd != -1) (void)fcntl(fd, F_FULLFSYNC); #endif -#ifdef HAVE_FSTAT -# ifdef __VMS - /* on OpenVMS we must ensure that all bytes are written to the file */ - if (fd != -1) { - fsync(fd); - } -# endif - if (fd != -1 && fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) { + if (fd != -1 && _Py_fstat_noraise(fd, &status) == 0 + && S_ISREG(status.st_mode)) { if (map_size == 0) { - if (st.st_size == 0) { + if (status.st_size == 0) { PyErr_SetString(PyExc_ValueError, "cannot mmap an empty file"); return NULL; } - if (offset >= st.st_size) { + if (offset >= status.st_size) { PyErr_SetString(PyExc_ValueError, "mmap offset is greater than file size"); return NULL; } - if (st.st_size - offset > PY_SSIZE_T_MAX) { + 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) (st.st_size - offset); - } else if (offset + (size_t)map_size > st.st_size) { + map_size = (Py_ssize_t) (status.st_size - offset); + } else if (offset + map_size > status.st_size) { PyErr_SetString(PyExc_ValueError, "mmap length is greater than file size"); return NULL; } } -#endif m_obj = (mmap_object *)type->tp_alloc(type, 0); if (m_obj == NULL) {return NULL;} m_obj->data = NULL; @@ -1211,7 +1222,6 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) fd = devzero = _Py_open("/dev/zero", O_RDWR); if (devzero == -1) { Py_DECREF(m_obj); - PyErr_SetFromErrno(PyExc_OSError); return NULL; } #endif @@ -1315,11 +1325,13 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) */ if (fileno != -1 && fileno != 0) { /* Ensure that fileno is within the CRT's valid range */ - if (_PyVerify_fd(fileno) == 0) { + if (!_PyVerify_fd(fileno)) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } + _Py_BEGIN_SUPPRESS_IPH fh = (HANDLE)_get_osfhandle(fileno); + _Py_END_SUPPRESS_IPH if (fh==(HANDLE)-1) { PyErr_SetFromErrno(PyExc_OSError); return NULL; diff --git a/Modules/nismodule.c b/Modules/nismodule.c index 0af495fa538c..b6a855c5775c 100644 --- a/Modules/nismodule.c +++ b/Modules/nismodule.c @@ -76,11 +76,7 @@ nis_mapname (char *map, int *pfix) *pfix = 0; for (i=0; aliases[i].alias != 0L; i++) { - if (!strcmp (aliases[i].alias, map)) { - *pfix = aliases[i].fix; - return aliases[i].map; - } - if (!strcmp (aliases[i].map, map)) { + if (!strcmp (aliases[i].alias, map) || !strcmp (aliases[i].map, map)) { *pfix = aliases[i].fix; return aliases[i].map; } @@ -456,8 +452,8 @@ static struct PyModuleDef nismodule = { NULL }; -PyObject* -PyInit_nis (void) +PyMODINIT_FUNC +PyInit_nis(void) { PyObject *m, *d; m = PyModule_Create(&nismodule); diff --git a/Modules/ossaudiodev.c b/Modules/ossaudiodev.c index b0a16dbf0d76..d2fd5c81d1be 100644 --- a/Modules/ossaudiodev.c +++ b/Modules/ossaudiodev.c @@ -19,6 +19,7 @@ * $Id$ */ +#define PY_SSIZE_T_CLEAN #include "Python.h" #include "structmember.h" @@ -51,8 +52,8 @@ typedef struct { char *devicename; /* name of the device file */ int fd; /* file descriptor */ int mode; /* file mode (O_RDONLY, etc.) */ - int icount; /* input count */ - int ocount; /* output count */ + Py_ssize_t icount; /* input count */ + Py_ssize_t ocount; /* output count */ uint32_t afmts; /* audio formats supported by hardware */ } oss_audio_t; @@ -116,11 +117,8 @@ newossobject(PyObject *arg) 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) { - PyErr_SetFromErrnoWithFilename(PyExc_IOError, devicename); + if (fd == -1) return NULL; - } /* And (try to) put it back in blocking mode so we get the expected write() semantics. */ @@ -180,10 +178,8 @@ newossmixerobject(PyObject *arg) } fd = _Py_open(devicename, O_RDWR); - if (fd == -1) { - PyErr_SetFromErrnoWithFilename(PyExc_IOError, devicename); + if (fd == -1) return NULL; - } if ((self = PyObject_New(oss_mixer_t, &OSSMixerType)) == NULL) { close(fd); @@ -404,29 +400,25 @@ oss_post(oss_audio_t *self, PyObject *args) static PyObject * oss_read(oss_audio_t *self, PyObject *args) { - int size, count; - char *cp; + Py_ssize_t size, count; PyObject *rv; if (!_is_fd_valid(self->fd)) return NULL; - if (!PyArg_ParseTuple(args, "i:read", &size)) + if (!PyArg_ParseTuple(args, "n:read", &size)) return NULL; + rv = PyBytes_FromStringAndSize(NULL, size); if (rv == NULL) return NULL; - cp = PyBytes_AS_STRING(rv); - - Py_BEGIN_ALLOW_THREADS - count = read(self->fd, cp, size); - Py_END_ALLOW_THREADS - if (count < 0) { - PyErr_SetFromErrno(PyExc_IOError); + 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; @@ -435,33 +427,32 @@ oss_read(oss_audio_t *self, PyObject *args) static PyObject * oss_write(oss_audio_t *self, PyObject *args) { - char *cp; - int rv, size; + Py_buffer data; + Py_ssize_t rv; if (!_is_fd_valid(self->fd)) return NULL; - if (!PyArg_ParseTuple(args, "y#:write", &cp, &size)) { + if (!PyArg_ParseTuple(args, "y*:write", &data)) { return NULL; } - Py_BEGIN_ALLOW_THREADS - rv = write(self->fd, cp, size); - Py_END_ALLOW_THREADS + rv = _Py_write(self->fd, data.buf, data.len); + PyBuffer_Release(&data); + if (rv == -1) + return NULL; - if (rv == -1) { - return PyErr_SetFromErrno(PyExc_IOError); - } else { - self->ocount += rv; - } + self->ocount += rv; return PyLong_FromLong(rv); } static PyObject * oss_writeall(oss_audio_t *self, PyObject *args) { - char *cp; - int rv, size; + Py_buffer data; + const char *cp; + Py_ssize_t size; + Py_ssize_t rv; fd_set write_set_fds; int select_rv; @@ -475,41 +466,50 @@ oss_writeall(oss_audio_t *self, PyObject *args) if (!_is_fd_valid(self->fd)) return NULL; - if (!PyArg_ParseTuple(args, "y#:write", &cp, &size)) + 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) + + assert(select_rv != 0); /* no timeout, can't expire */ + if (select_rv == -1) { + PyBuffer_Release(&data); return PyErr_SetFromErrno(PyExc_IOError); + } - Py_BEGIN_ALLOW_THREADS - rv = write(self->fd, cp, size); - Py_END_ALLOW_THREADS + rv = _Py_write(self->fd, cp, Py_MIN(size, INT_MAX)); if (rv == -1) { - if (errno == EAGAIN) { /* buffer is full, try again */ - errno = 0; + /* buffer is full, try again */ + if (errno == EAGAIN) { + PyErr_Clear(); continue; - } else /* it's a real error */ - return PyErr_SetFromErrno(PyExc_IOError); - } else { /* wrote rv bytes */ - self->ocount += rv; - size -= rv; - cp += rv; + } + /* it's a real error */ + PyBuffer_Release(&data); + return NULL; } + + /* wrote rv bytes */ + self->ocount += rv; + size -= rv; + cp += rv; } + PyBuffer_Release(&data); Py_INCREF(Py_None); return Py_None; } @@ -564,7 +564,6 @@ oss_setparameters(oss_audio_t *self, PyObject *args) { int wanted_fmt, wanted_channels, wanted_rate, strict=0; int fmt, channels, rate; - PyObject * rv; /* return tuple (fmt, channels, rate) */ if (!_is_fd_valid(self->fd)) return NULL; @@ -609,13 +608,7 @@ oss_setparameters(oss_audio_t *self, PyObject *args) /* Construct the return value: a (fmt, channels, rate) tuple that tells what the audio hardware was actually set to. */ - rv = PyTuple_New(3); - if (rv == NULL) - return NULL; - PyTuple_SET_ITEM(rv, 0, PyLong_FromLong(fmt)); - PyTuple_SET_ITEM(rv, 1, PyLong_FromLong(channels)); - PyTuple_SET_ITEM(rv, 2, PyLong_FromLong(rate)); - return rv; + return Py_BuildValue("(iii)", fmt, channels, rate); } static int @@ -901,7 +894,7 @@ static PyMethodDef oss_methods[] = { /* Aliases for backwards compatibility */ { "flush", (PyCFunction)oss_sync, METH_VARARGS }, - /* Support for the context manager protocol */ + /* Support for the context management protocol */ { "__enter__", oss_self, METH_NOARGS }, { "__exit__", oss_exit, METH_VARARGS }, @@ -913,7 +906,7 @@ static PyMethodDef oss_mixer_methods[] = { { "close", (PyCFunction)oss_mixer_close, METH_NOARGS }, { "fileno", (PyCFunction)oss_mixer_fileno, METH_NOARGS }, - /* Support for the context manager protocol */ + /* Support for the context management protocol */ { "__enter__", oss_self, METH_NOARGS }, { "__exit__", oss_exit, METH_VARARGS }, diff --git a/Modules/overlapped.c b/Modules/overlapped.c index 625c76eff4e6..ef77c8875aa3 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -45,19 +45,13 @@ typedef struct { /* Type of operation */ DWORD type; union { - /* Buffer used for reading (optional) */ + /* Buffer used for reading: TYPE_READ and TYPE_ACCEPT */ PyObject *read_buffer; - /* Buffer used for writing (optional) */ + /* Buffer used for writing: TYPE_WRITE */ Py_buffer write_buffer; }; } OverlappedObject; -typedef struct { - OVERLAPPED *Overlapped; - HANDLE IocpHandle; - char Address[1]; -} WaitNamedPipeAndConnectContext; - /* * Map Windows error codes to subclasses of OSError */ @@ -309,6 +303,29 @@ overlapped_UnregisterWait(PyObject *self, PyObject *args) 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 */ @@ -568,13 +585,15 @@ Overlapped_dealloc(OverlappedObject *self) if (self->overlapped.hEvent != NULL) CloseHandle(self->overlapped.hEvent); - if (self->write_buffer.obj) - PyBuffer_Release(&self->write_buffer); - switch (self->type) { - case TYPE_READ: - case TYPE_ACCEPT: - Py_CLEAR(self->read_buffer); + case TYPE_READ: + case TYPE_ACCEPT: + Py_CLEAR(self->read_buffer); + break; + case TYPE_WRITE: + if (self->write_buffer.obj) + PyBuffer_Release(&self->write_buffer); + break; } PyObject_Del(self); SetLastError(olderr); @@ -648,7 +667,7 @@ Overlapped_getresult(OverlappedObject *self, PyObject *args) case ERROR_MORE_DATA: break; case ERROR_BROKEN_PIPE: - if (self->read_buffer != NULL) + if ((self->type == TYPE_READ || self->type == TYPE_ACCEPT) && self->read_buffer != NULL) break; /* fall through */ default: @@ -711,7 +730,7 @@ Overlapped_ReadFile(OverlappedObject *self, PyObject *args) switch (err) { case ERROR_BROKEN_PIPE: mark_as_completed(&self->overlapped); - Py_RETURN_NONE; + return SetFromWindowsErr(err); case ERROR_SUCCESS: case ERROR_MORE_DATA: case ERROR_IO_PENDING: @@ -770,7 +789,7 @@ Overlapped_WSARecv(OverlappedObject *self, PyObject *args) switch (err) { case ERROR_BROKEN_PIPE: mark_as_completed(&self->overlapped); - Py_RETURN_NONE; + return SetFromWindowsErr(err); case ERROR_SUCCESS: case ERROR_MORE_DATA: case ERROR_IO_PENDING: @@ -1098,109 +1117,46 @@ Overlapped_ConnectNamedPipe(OverlappedObject *self, PyObject *args) switch (err) { case ERROR_PIPE_CONNECTED: mark_as_completed(&self->overlapped); - Py_RETURN_NONE; + Py_RETURN_TRUE; case ERROR_SUCCESS: case ERROR_IO_PENDING: - Py_RETURN_NONE; + Py_RETURN_FALSE; default: self->type = TYPE_NOT_STARTED; return SetFromWindowsErr(err); } } -/* Unfortunately there is no way to do an overlapped connect to a - pipe. We instead use WaitNamedPipe() and CreateFile() in a thread - pool thread. If a connection succeeds within a time limit (10 - seconds) then PostQueuedCompletionStatus() is used to return the - pipe handle to the completion port. */ - -static DWORD WINAPI -WaitNamedPipeAndConnectInThread(WaitNamedPipeAndConnectContext *ctx) -{ - HANDLE PipeHandle = INVALID_HANDLE_VALUE; - DWORD Start = GetTickCount(); - DWORD Deadline = Start + 10*1000; - DWORD Error = 0; - DWORD Timeout; - BOOL Success; - - for ( ; ; ) { - Timeout = Deadline - GetTickCount(); - if ((int)Timeout < 0) - break; - Success = WaitNamedPipe(ctx->Address, Timeout); - Error = Success ? ERROR_SUCCESS : GetLastError(); - switch (Error) { - case ERROR_SUCCESS: - PipeHandle = CreateFile(ctx->Address, - GENERIC_READ | GENERIC_WRITE, - 0, NULL, OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, NULL); - if (PipeHandle == INVALID_HANDLE_VALUE) - continue; - break; - case ERROR_SEM_TIMEOUT: - continue; - } - break; - } - if (!PostQueuedCompletionStatus(ctx->IocpHandle, Error, - (ULONG_PTR)PipeHandle, ctx->Overlapped)) - CloseHandle(PipeHandle); - free(ctx); - return 0; -} - PyDoc_STRVAR( - Overlapped_WaitNamedPipeAndConnect_doc, - "WaitNamedPipeAndConnect(addr, iocp_handle) -> Overlapped[pipe_handle]\n\n" - "Start overlapped connection to address, notifying iocp_handle when\n" - "finished"); + ConnectPipe_doc, + "ConnectPipe(addr) -> pipe_handle\n\n" + "Connect to the pipe for asynchronous I/O (overlapped)."); static PyObject * -Overlapped_WaitNamedPipeAndConnect(OverlappedObject *self, PyObject *args) +ConnectPipe(OverlappedObject *self, PyObject *args) { - char *Address; - Py_ssize_t AddressLength; - HANDLE IocpHandle; - OVERLAPPED Overlapped; - BOOL ret; - DWORD err; - WaitNamedPipeAndConnectContext *ctx; - Py_ssize_t ContextLength; + PyObject *AddressObj; + wchar_t *Address; + HANDLE PipeHandle; - if (!PyArg_ParseTuple(args, "s#" F_HANDLE F_POINTER, - &Address, &AddressLength, &IocpHandle, &Overlapped)) + if (!PyArg_ParseTuple(args, "U", &AddressObj)) return NULL; - if (self->type != TYPE_NONE) { - PyErr_SetString(PyExc_ValueError, "operation already attempted"); + Address = PyUnicode_AsWideCharString(AddressObj, NULL); + if (Address == NULL) return NULL; - } - - ContextLength = (AddressLength + - offsetof(WaitNamedPipeAndConnectContext, Address)); - ctx = calloc(1, ContextLength + 1); - if (ctx == NULL) - return PyErr_NoMemory(); - memcpy(ctx->Address, Address, AddressLength + 1); - ctx->Overlapped = &self->overlapped; - ctx->IocpHandle = IocpHandle; - - self->type = TYPE_WAIT_NAMED_PIPE_AND_CONNECT; - self->handle = NULL; Py_BEGIN_ALLOW_THREADS - ret = QueueUserWorkItem(WaitNamedPipeAndConnectInThread, ctx, - WT_EXECUTELONGFUNCTION); + PipeHandle = CreateFileW(Address, + GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, NULL); Py_END_ALLOW_THREADS - mark_as_completed(&self->overlapped); - - self->error = err = ret ? ERROR_SUCCESS : GetLastError(); - if (!ret) - return SetFromWindowsErr(err); - Py_RETURN_NONE; + PyMem_Free(Address); + if (PipeHandle == INVALID_HANDLE_VALUE) + return SetFromWindowsErr(0); + return Py_BuildValue(F_HANDLE, PipeHandle); } static PyObject* @@ -1237,9 +1193,6 @@ static PyMethodDef Overlapped_methods[] = { METH_VARARGS, Overlapped_DisconnectEx_doc}, {"ConnectNamedPipe", (PyCFunction) Overlapped_ConnectNamedPipe, METH_VARARGS, Overlapped_ConnectNamedPipe_doc}, - {"WaitNamedPipeAndConnect", - (PyCFunction) Overlapped_WaitNamedPipeAndConnect, - METH_VARARGS, Overlapped_WaitNamedPipeAndConnect_doc}, {NULL} }; @@ -1317,12 +1270,17 @@ static PyMethodDef overlapped_functions[] = { 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", + (PyCFunction) ConnectPipe, + METH_VARARGS, ConnectPipe_doc}, {NULL} }; @@ -1367,6 +1325,7 @@ PyInit__overlapped(void) WINAPI_CONSTANT(F_DWORD, ERROR_IO_PENDING); WINAPI_CONSTANT(F_DWORD, ERROR_NETNAME_DELETED); 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); diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index 537a2e9e6d2c..8023558fd151 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -23,6 +23,11 @@ * 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(...)". + * + * To debug parser errors like + * "parser.ParserError: Expected node type 12, got 333." + * decode symbol numbers using the automatically-generated files + * Lib/symbol.h and Include/token.h. */ #include "Python.h" /* general Python API */ @@ -785,7 +790,7 @@ build_node_children(PyObject *tuple, node *root, int *line_num) } } if (!ok) { - PyObject *err = Py_BuildValue("os", elem, + PyObject *err = Py_BuildValue("Os", elem, "Illegal node construct."); PyErr_SetObject(parser_error, err); Py_XDECREF(err); @@ -1036,6 +1041,8 @@ VALIDATER(testlist_comp); VALIDATER(yield_expr); VALIDATER(or_test); VALIDATER(test_nocond); VALIDATER(lambdef_nocond); VALIDATER(yield_arg); +VALIDATER(async_funcdef); VALIDATER(async_stmt); +VALIDATER(atom_expr); #undef VALIDATER @@ -1087,30 +1094,56 @@ validate_terminal(node *terminal, int type, char *string) return (res); } +/* X (',' X) [','] */ +static int +validate_repeating_list_variable(node *tree, + int list_node_type, + int (*validate_child_func_inc)(node *, int *), + int *pos, + const char *const list_node_type_name) +{ + int nch = NCH(tree); + int res = (nch && validate_ntype(tree, list_node_type)); -/* X (',' X) [','] - */ + if (!res && !PyErr_Occurred()) { + /* Unconditionally raise. */ + (void) validate_numnodes(tree, 1, list_node_type_name); + } + else { + for ( ; res && *pos < nch; ) { + res = validate_child_func_inc(tree, pos); + if (!res || *pos >= nch) + break; + res = validate_comma(CHILD(tree, (*pos)++)); + } + } + return res; +} + +/* X (',' X) [','] */ static int -validate_repeating_list(node *tree, int ntype, int (*vfunc)(node *), - const char *const name) +validate_repeating_list(node *tree, + int list_node_type, + int (*validate_child_func)(node *), + const char *const list_node_type_name) { int nch = NCH(tree); - int res = (nch && validate_ntype(tree, ntype) - && vfunc(CHILD(tree, 0))); + int res = (nch && validate_ntype(tree, list_node_type)); + int pos = 0; - if (!res && !PyErr_Occurred()) - (void) validate_numnodes(tree, 1, name); + if (!res && !PyErr_Occurred()) { + /* Unconditionally raise. */ + (void) validate_numnodes(tree, 1, list_node_type_name); + } else { - if (is_even(nch)) - res = validate_comma(CHILD(tree, --nch)); - if (res && nch > 1) { - int pos = 1; - for ( ; res && pos < nch; pos += 2) - res = (validate_comma(CHILD(tree, pos)) - && vfunc(CHILD(tree, pos + 1))); + for ( ; res && pos < nch; ) { + res = validate_child_func(CHILD(tree, pos++)); + if (!res || pos >= nch) + break; + res = validate_comma(CHILD(tree, pos++)); } } - return (res); + return res; } @@ -1577,6 +1610,7 @@ validate_compound_stmt(node *tree) || (ntype == try_stmt) || (ntype == with_stmt) || (ntype == funcdef) + || (ntype == async_stmt) || (ntype == classdef) || (ntype == decorated)) res = validate_node(tree); @@ -2409,27 +2443,60 @@ validate_factor(node *tree) /* power: * - * power: atom trailer* ('**' factor)* + * power: atom_expr trailer* ['**' factor] */ static int validate_power(node *tree) { - int pos = 1; int nch = NCH(tree); int res = (validate_ntype(tree, power) && (nch >= 1) - && validate_atom(CHILD(tree, 0))); + && validate_atom_expr(CHILD(tree, 0))); - while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer)) - res = validate_trailer(CHILD(tree, pos++)); - if (res && (pos < nch)) { - if (!is_even(nch - pos)) { + if (nch > 1) { + if (nch != 3) { err_string("illegal number of nodes for 'power'"); return (0); } - for ( ; res && (pos < (nch - 1)); pos += 2) - res = (validate_doublestar(CHILD(tree, pos)) - && validate_factor(CHILD(tree, pos + 1))); + res = (validate_doublestar(CHILD(tree, 1)) + && validate_factor(CHILD(tree, 2))); } + + return (res); +} + + +/* atom_expr: + * + * atom_expr: [AWAIT] atom trailer* + */ +static int +validate_atom_expr(node *tree) +{ + int start = 0; + int nch = NCH(tree); + int res; + int pos; + + res = validate_ntype(tree, atom_expr) && (nch >= 1); + if (!res) { + return (res); + } + + if (TYPE(CHILD(tree, 0)) == AWAIT) { + start = 1; + if (nch < 2) { + err_string("illegal number of nodes for 'atom_expr'"); + return (0); + } + } + + res = validate_atom(CHILD(tree, start)); + if (res) { + pos = start + 1; + while (res && (pos < nch) && (TYPE(CHILD(tree, pos)) == trailer)) + res = validate_trailer(CHILD(tree, pos++)); + } + return (res); } @@ -2493,39 +2560,28 @@ validate_atom(node *tree) /* testlist_comp: - * test ( comp_for | (',' test)* [','] ) + * (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] ) */ static int validate_testlist_comp(node *tree) { int nch = NCH(tree); - int ok = nch; + int ok; - if (nch == 0) + if (nch == 0) { err_string("missing child nodes of testlist_comp"); - else { - ok = validate_test_or_star_expr(CHILD(tree, 0)); + return 0; } - /* - * comp_for | (',' test)* [','] - */ - if (nch == 2 && TYPE(CHILD(tree, 1)) == comp_for) - ok = validate_comp_for(CHILD(tree, 1)); + if (nch == 2 && TYPE(CHILD(tree, 1)) == comp_for) { + ok = (validate_test(CHILD(tree, 0)) + && validate_comp_for(CHILD(tree, 1))); + } else { - /* (',' test)* [','] */ - int i = 1; - while (ok && nch - i >= 2) { - ok = (validate_comma(CHILD(tree, i)) - && validate_test_or_star_expr(CHILD(tree, i+1))); - i += 2; - } - if (ok && i == nch-1) - ok = validate_comma(CHILD(tree, i)); - else if (i != nch) { - ok = 0; - err_string("illegal trailing nodes for testlist_comp"); - } + ok = validate_repeating_list(tree, + testlist_comp, + validate_test_or_star_expr, + "testlist_comp"); } return ok; } @@ -2638,6 +2694,55 @@ validate_funcdef(node *tree) return res; } +/* async_funcdef: ASYNC funcdef */ + +static int +validate_async_funcdef(node *tree) +{ + int nch = NCH(tree); + int res = validate_ntype(tree, async_funcdef); + if (res) { + if (nch == 2) { + res = (validate_ntype(CHILD(tree, 0), ASYNC) + && validate_funcdef(CHILD(tree, 1))); + } + else { + res = 0; + err_string("illegal number of children for async_funcdef"); + } + } + return res; +} + + +/* async_stmt: ASYNC (funcdef | with_stmt | for_stmt) */ + +static int +validate_async_stmt(node *tree) +{ + int nch = NCH(tree); + int res = (validate_ntype(tree, async_stmt) + && validate_ntype(CHILD(tree, 0), ASYNC)); + + if (nch != 2) { + res = 0; + err_string("illegal number of children for async_stmt"); + } else { + if (TYPE(CHILD(tree, 1)) == funcdef) { + res = validate_funcdef(CHILD(tree, 1)); + } + else if (TYPE(CHILD(tree, 1)) == with_stmt) { + res = validate_with_stmt(CHILD(tree, 1)); + } + else if (TYPE(CHILD(tree, 1)) == for_stmt) { + res = validate_for(CHILD(tree, 1)); + } + } + + return res; +} + + /* decorated * decorators (classdef | funcdef) @@ -2732,9 +2837,6 @@ validate_arglist(node *tree) } ok = 1; if (nch-i > 0) { - /* - * argument | '*' test [',' '**' test] | '**' test - */ int sym = TYPE(CHILD(tree, i)); if (sym == argument) { @@ -2745,30 +2847,7 @@ validate_arglist(node *tree) ok = 0; } } - else if (sym == STAR) { - ok = validate_star(CHILD(tree, i)); - if (ok && (nch-i == 2)) - ok = validate_test(CHILD(tree, i+1)); - else if (ok && (nch-i == 5)) - ok = (validate_test(CHILD(tree, i+1)) - && validate_comma(CHILD(tree, i+2)) - && validate_doublestar(CHILD(tree, i+3)) - && validate_test(CHILD(tree, i+4))); - else { - err_string("illegal use of '*' in arglist"); - ok = 0; - } - } - else if (sym == DOUBLESTAR) { - if (nch-i == 2) - ok = (validate_doublestar(CHILD(tree, i)) - && validate_test(CHILD(tree, i+1))); - else { - err_string("illegal use of '**' in arglist"); - ok = 0; - } - } - else { + else { err_string("illegal arglist specification"); ok = 0; } @@ -2778,9 +2857,10 @@ validate_arglist(node *tree) -/* argument: - * - * [test '='] test [comp_for] +/* argument: ( test [comp_for] | + * test '=' test | + * '**' test | + * '*' test ) */ static int validate_argument(node *tree) @@ -2788,14 +2868,27 @@ validate_argument(node *tree) int nch = NCH(tree); int res = (validate_ntype(tree, argument) && ((nch == 1) || (nch == 2) || (nch == 3))); - if (res) - res = validate_test(CHILD(tree, 0)); - if (res && (nch == 2)) - res = validate_comp_for(CHILD(tree, 1)); - else if (res && (nch == 3)) - res = (validate_equal(CHILD(tree, 1)) - && validate_test(CHILD(tree, 2))); + if (res) { + if (TYPE(CHILD(tree, 0)) == DOUBLESTAR) { + res = validate_test(CHILD(tree, 1)); + } + else if (TYPE(CHILD(tree, 0)) == STAR) { + res = validate_test(CHILD(tree, 1)); + } + else if (nch == 1) { + res = validate_test(CHILD(tree, 0)); + } + else if (nch == 2) { + res = (validate_test(CHILD(tree, 0)) + && validate_comp_for(CHILD(tree, 1))); + } + else if (res && (nch == 3)) { + res = (validate_test(CHILD(tree, 0)) + && validate_equal(CHILD(tree, 1)) + && validate_test(CHILD(tree, 2))); + } + } return (res); } @@ -2948,11 +3041,44 @@ validate_exprlist(node *tree) validate_expr_or_star_expr, "exprlist")); } +/* Incrementing validate functions returns nonzero iff success (like other + * validate functions, and advance *i by the length of the matched pattern. */ + +/* test ':' test */ +static int +validate_test_colon_test_inc(node *tree, int *i) +{ + return (validate_test(CHILD(tree, (*i)++)) + && validate_colon(CHILD(tree, (*i)++)) + && validate_test(CHILD(tree, (*i)++))); +} + +/* test ':' test | '**' expr */ +static int +validate_dict_element_inc(node *tree, int *i) +{ + int nch = NCH(tree); + int res = 0; + if (nch - *i >= 2) { + if (TYPE(CHILD(tree, *i+1)) == COLON) { + /* test ':' test */ + res = validate_test_colon_test_inc(tree, i); + } else { + /* '**' expr */ + res = (validate_doublestar(CHILD(tree, (*i)++)) + && validate_expr(CHILD(tree, (*i)++))); + } + } + return res; +} + /* * dictorsetmaker: * - * (test ':' test (comp_for | (',' test ':' test)* [','])) | - * (test (comp_for | (',' test)* [','])) + * ( ((test ':' test | '**' expr) + * (comp_for | (',' (test ':' test | '**' expr))* [','])) | + * ((test | '*' test) + * (comp_for | (',' (test | '*' test))* [','])) ) */ static int validate_dictorsetmaker(node *tree) @@ -2966,65 +3092,44 @@ validate_dictorsetmaker(node *tree) return 0; if (nch - i < 1) { + /* Unconditionally raise. */ (void) validate_numnodes(tree, 1, "dictorsetmaker"); return 0; } - res = validate_test(CHILD(tree, i++)); - if (!res) - return 0; - - if (nch - i >= 2 && TYPE(CHILD(tree, i)) == COLON) { + if (nch - i >= 2 + && ((TYPE(CHILD(tree, i+1)) == COLON) || + (TYPE(CHILD(tree, i)) == DOUBLESTAR))) { /* Dictionary display or dictionary comprehension. */ - res = (validate_colon(CHILD(tree, i++)) - && validate_test(CHILD(tree, i++))); - if (!res) - return 0; - - if (nch - i >= 1 && TYPE(CHILD(tree, i)) == comp_for) { + if (nch - i >= 4 && TYPE(CHILD(tree, i+3)) == comp_for) { /* Dictionary comprehension. */ - res = validate_comp_for(CHILD(tree, i++)); + res = (validate_test_colon_test_inc(tree, &i) + && validate_comp_for(CHILD(tree, i++))); if (!res) return 0; - } - else { + } else { /* Dictionary display. */ - while (nch - i >= 4) { - res = (validate_comma(CHILD(tree, i++)) - && validate_test(CHILD(tree, i++)) - && validate_colon(CHILD(tree, i++)) - && validate_test(CHILD(tree, i++))); - if (!res) - return 0; - } - if (nch - i == 1) { - res = validate_comma(CHILD(tree, i++)); - if (!res) - return 0; - } + return validate_repeating_list_variable( + tree, + dictorsetmaker, + validate_dict_element_inc, + &i, + "dictorsetmaker"); } - } - else { + } else { /* Set display or set comprehension. */ - if (nch - i >= 1 && TYPE(CHILD(tree, i)) == comp_for) { + if (nch - i >= 2 && TYPE(CHILD(tree, i + 1)) == comp_for) { /* Set comprehension. */ - res = validate_comp_for(CHILD(tree, i++)); + res = (validate_test(CHILD(tree, i++)) + && validate_comp_for(CHILD(tree, i++))); if (!res) return 0; - } - else { + } else { /* Set display. */ - while (nch - i >= 2) { - res = (validate_comma(CHILD(tree, i++)) - && validate_test(CHILD(tree, i++))); - if (!res) - return 0; - } - if (nch - i == 1) { - res = validate_comma(CHILD(tree, i++)); - if (!res) - return 0; - } + return validate_repeating_list(tree, + dictorsetmaker, + validate_test_or_star_expr, + "dictorsetmaker"); } } @@ -3068,6 +3173,12 @@ validate_node(node *tree) /* * Definition nodes. */ + case async_funcdef: + res = validate_async_funcdef(tree); + break; + case async_stmt: + res = validate_async_stmt(tree); + break; case funcdef: res = validate_funcdef(tree); break; diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 2f21ceb6f7ca..467ce2c576b3 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -6,7 +6,7 @@ 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. '__BORLANDC__' or '_MSC_VER'. */ + test macro, e.g. '_MSC_VER'. */ @@ -25,15 +25,13 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "structmember.h" #ifndef MS_WINDOWS #include "posixmodule.h" +#else +#include "winreparse.h" #endif -#if defined(__VMS) -# error "PEP 11: VMS is now unsupported, code will be removed in Python 3.4" -# include -#endif /* defined(__VMS) */ - #ifdef __cplusplus extern "C" { #endif @@ -97,7 +95,7 @@ corresponding Unix manual entries for more information on calls."); #undef HAVE_SCHED_SETAFFINITY #endif -#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) +#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__) #define USE_XATTRS #endif @@ -146,13 +144,6 @@ corresponding Unix manual entries for more information on calls."); #define HAVE_SYSTEM 1 #include #else -#ifdef __BORLANDC__ /* Borland compiler */ -#define HAVE_EXECV 1 -#define HAVE_OPENDIR 1 -#define HAVE_PIPE 1 -#define HAVE_SYSTEM 1 -#define HAVE_WAIT 1 -#else #ifdef _MSC_VER /* Microsoft compiler */ #define HAVE_GETPPID 1 #define HAVE_GETLOGIN 1 @@ -164,9 +155,6 @@ corresponding Unix manual entries for more information on calls."); #define HAVE_FSYNC 1 #define fsync _commit #else -#if defined(__VMS) -/* Everything needed is defined in vms/pyconfig.h */ -#else /* all other compilers */ /* Unix functions that the configure script doesn't check for */ #define HAVE_EXECV 1 #define HAVE_FORK 1 @@ -184,16 +172,15 @@ corresponding Unix manual entries for more information on calls."); #define HAVE_SYSTEM 1 #define HAVE_WAIT 1 #define HAVE_TTYNAME 1 -#endif /* __VMS */ #endif /* _MSC_VER */ -#endif /* __BORLANDC__ */ #endif /* ! __WATCOMC__ || __QNX__ */ -/*[clinic] +/*[clinic input] +# one of the few times we lie about this name! module os -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/ #ifndef _MSC_VER @@ -220,11 +207,7 @@ extern int rmdir(char *); extern int chdir(const char *); extern int rmdir(const char *); #endif -#ifdef __BORLANDC__ -extern int chmod(const char *, int); -#else extern int chmod(const char *, mode_t); -#endif /*#ifdef HAVE_FCHMOD extern int fchmod(int, mode_t); #endif*/ @@ -310,6 +293,9 @@ extern int lstat(const char *, struct stat *); #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 @@ -365,8 +351,8 @@ static int win32_can_symlink = 0; #ifdef MS_WINDOWS # define STAT win32_stat # define LSTAT win32_lstat -# define FSTAT win32_fstat -# define STRUCT_STAT struct win32_stat +# define FSTAT _Py_fstat_noraise +# define STRUCT_STAT struct _Py_stat_struct #else # define STAT stat # define LSTAT lstat @@ -387,6 +373,20 @@ static int win32_can_symlink = 0; #define DWORD_MAX 4294967295U +#ifdef MS_WINDOWS +#define INITFUNC PyInit_nt +#define MODNAME "nt" +#else +#define INITFUNC PyInit_posix +#define MODNAME "posix" +#endif + +#ifdef MS_WINDOWS +/* defined in fileutils.c */ +PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *); +PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *, + ULONG, struct _Py_stat_struct *); +#endif #ifdef MS_WINDOWS static int @@ -632,6 +632,29 @@ _Py_Gid_Converter(PyObject *obj, void *p) #endif /* MS_WINDOWS */ +#ifdef HAVE_LONG_LONG +# define _PyLong_FromDev PyLong_FromLongLong +#else +# define _PyLong_FromDev PyLong_FromLong +#endif + + +#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) +static int +_Py_Dev_Converter(PyObject *obj, void *p) +{ +#ifdef HAVE_LONG_LONG + *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj); +#else + *((dev_t *)p) = PyLong_AsUnsignedLong(obj); +#endif + 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); @@ -687,7 +710,6 @@ dir_fd_converter(PyObject *o, void *p) } - /* * A PyArg_ParseTuple "converter" function * that handles filesystem paths in the manner @@ -783,14 +805,13 @@ typedef struct { PyObject *cleanup; } path_t; -#define PATH_T_INITIALIZE(function_name, nullable, allow_fd) \ - {function_name, NULL, nullable, allow_fd, NULL, NULL, 0, 0, NULL, NULL} +#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \ + {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL} static void path_cleanup(path_t *path) { if (path->cleanup) { - Py_DECREF(path->cleanup); - path->cleanup = NULL; + Py_CLEAR(path->cleanup); } } @@ -845,6 +866,11 @@ path_converter(PyObject *o, void *p) { Py_DECREF(unicode); return 0; } + if (wcslen(wide) != length) { + FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character"); + Py_DECREF(unicode); + return 0; + } path->wide = wide; path->narrow = NULL; @@ -907,8 +933,8 @@ path_converter(PyObject *o, void *p) { #endif narrow = PyBytes_AS_STRING(bytes); - if (length != strlen(narrow)) { - FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s"); + if ((size_t)length != strlen(narrow)) { + FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s"); Py_DECREF(bytes); return 0; } @@ -1009,97 +1035,46 @@ dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd, return 0; } -/* A helper used by a number of POSIX-only functions */ -#ifndef MS_WINDOWS +#ifdef MS_WINDOWS + typedef PY_LONG_LONG Py_off_t; +#else + typedef off_t Py_off_t; +#endif + static int -_parse_off_t(PyObject* arg, void* addr) +Py_off_t_converter(PyObject *arg, void *addr) { -#if !defined(HAVE_LARGEFILE_SUPPORT) - *((off_t*)addr) = PyLong_AsLong(arg); +#ifdef HAVE_LARGEFILE_SUPPORT + *((Py_off_t *)addr) = PyLong_AsLongLong(arg); #else - *((off_t*)addr) = PyLong_AsLongLong(arg); + *((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 +} -#if defined _MSC_VER && _MSC_VER >= 1400 -/* Microsoft CRT in VS2005 and higher will verify that a filehandle is - * valid and raise an assertion if it isn't. - * Normally, an invalid fd is likely to be a C program error and therefore - * an assertion can be useful, but it does contradict the POSIX standard - * which for write(2) states: - * "Otherwise, -1 shall be returned and errno set to indicate the error." - * "[EBADF] The fildes argument is not a valid file descriptor open for - * writing." - * Furthermore, python allows the user to enter any old integer - * as a fd and should merely raise a python exception on error. - * The Microsoft CRT doesn't provide an official way to check for the - * validity of a file descriptor, but we can emulate its internal behaviour - * by using the exported __pinfo data member and knowledge of the - * internal structures involved. - * The structures below must be updated for each version of visual studio - * according to the file internal.h in the CRT source, until MS comes - * up with a less hacky way to do this. - * (all of this is to avoid globally modifying the CRT behaviour using - * _set_invalid_parameter_handler() and _CrtSetReportMode()) - */ -/* The actual size of the structure is determined at runtime. - * Only the first items must be present. - */ -typedef struct { - intptr_t osfhnd; - char osfile; -} my_ioinfo; -extern __declspec(dllimport) char * __pioinfo[]; +#if defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900 +/* Legacy implementation of _PyVerify_fd_dup2 while transitioning to + * MSVC 14.0. This should eventually be removed. (issue23524) + */ #define IOINFO_L2E 5 -#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) #define IOINFO_ARRAYS 64 +#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) #define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS) -#define FOPEN 0x01 #define _NO_CONSOLE_FILENO (intptr_t)-2 -/* This function emulates what the windows CRT does to validate file handles */ -int -_PyVerify_fd(int fd) -{ - const int i1 = fd >> IOINFO_L2E; - const int i2 = fd & ((1 << IOINFO_L2E) - 1); - - static size_t sizeof_ioinfo = 0; - - /* Determine the actual size of the ioinfo structure, - * as used by the CRT loaded in memory - */ - if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) { - sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS; - } - if (sizeof_ioinfo == 0) { - /* This should not happen... */ - goto fail; - } - - /* See that it isn't a special CLEAR fileno */ - if (fd != _NO_CONSOLE_FILENO) { - /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead - * we check pointer validity and other info - */ - if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) { - /* finally, check that the file is open */ - my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo); - if (info->osfile & FOPEN) { - return 1; - } - } - } - fail: - errno = EBADF; - return 0; -} - /* the special case of checking dup2. The target fd must be in a sensible range */ static int _PyVerify_fd_dup2(int fd1, int fd2) @@ -1114,46 +1089,10 @@ _PyVerify_fd_dup2(int fd1, int fd2) return 0; } #else -/* dummy version. _PyVerify_fd() is already defined in fileobject.h */ -#define _PyVerify_fd_dup2(A, B) (1) +#define _PyVerify_fd_dup2(fd1, fd2) (_PyVerify_fd(fd1) && (fd2) >= 0) #endif #ifdef MS_WINDOWS -/* The following structure was copied from - http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required - include doesn't seem to be present in the Windows SDK (at least as included - with Visual Studio Express). */ -typedef struct _REPARSE_DATA_BUFFER { - 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; - }; -} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; - -#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\ - GenericReparseBuffer) -#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 ) static int win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag) @@ -1323,49 +1262,52 @@ path_error(path_t *path) } +static PyObject * +path_error2(path_t *path, path_t *path2) +{ +#ifdef MS_WINDOWS + return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError, + 0, path->object, path2->object); +#else + return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, + path->object, path2->object); +#endif +} + + /* POSIX generic methods */ -static PyObject * -posix_fildes(PyObject *fdobj, int (*func)(int)) +static int +fildes_converter(PyObject *o, void *p) { int fd; - int res; - fd = PyObject_AsFileDescriptor(fdobj); + int *pointer = (int *)p; + fd = PyObject_AsFileDescriptor(o); if (fd < 0) - return NULL; - if (!_PyVerify_fd(fd)) - return posix_error(); - Py_BEGIN_ALLOW_THREADS - res = (*func)(fd); - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error(); - Py_INCREF(Py_None); - return Py_None; + return 0; + *pointer = fd; + return 1; } static PyObject * -posix_1str(const char *func_name, PyObject *args, char *format, - int (*func)(const char*)) +posix_fildes_fd(int fd, int (*func)(int)) { - path_t path; int res; - memset(&path, 0, sizeof(path)); - path.function_name = func_name; - if (!PyArg_ParseTuple(args, format, - path_converter, &path)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = (*func)(path.narrow); - Py_END_ALLOW_THREADS - if (res < 0) { - path_error(&path); - path_cleanup(&path); - return NULL; - } - path_cleanup(&path); - Py_INCREF(Py_None); - return Py_None; + int async_err = 0; + + if (!_PyVerify_fd(fd)) + return posix_error(); + + 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; } @@ -1444,89 +1386,7 @@ win32_wchdir(LPCWSTR path) Therefore, we implement our own stat, based on the Win32 API directly. */ #define HAVE_STAT_NSEC 1 - -struct win32_stat{ - unsigned long st_dev; - __int64 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; -}; - -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); -} - -static void -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; -} - -static int -attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *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 = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow; - if (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; - } - - return 0; -} +#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1 static BOOL attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag) @@ -1551,6 +1411,25 @@ attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *rep return TRUE; } +static void +find_data_to_file_info_w(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_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag) { @@ -1560,45 +1439,10 @@ attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG * if (hFindFile == INVALID_HANDLE_VALUE) return FALSE; FindClose(hFindFile); - memset(info, 0, sizeof(*info)); - *reparse_tag = 0; - info->dwFileAttributes = FileData.dwFileAttributes; - info->ftCreationTime = FileData.ftCreationTime; - info->ftLastAccessTime = FileData.ftLastAccessTime; - info->ftLastWriteTime = FileData.ftLastWriteTime; - info->nFileSizeHigh = FileData.nFileSizeHigh; - info->nFileSizeLow = FileData.nFileSizeLow; -/* info->nNumberOfLinks = 1; */ - if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) - *reparse_tag = FileData.dwReserved0; + find_data_to_file_info_w(&FileData, info, reparse_tag); return TRUE; } -/* Grab GetFinalPathNameByHandle dynamically from kernel32 */ -static int has_GetFinalPathNameByHandle = -1; -static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD, - DWORD); -static int -check_GetFinalPathNameByHandle() -{ - HINSTANCE hKernel32; - DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD, - DWORD); - - /* only recheck */ - if (-1 == has_GetFinalPathNameByHandle) - { - hKernel32 = GetModuleHandleW(L"KERNEL32"); - *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32, - "GetFinalPathNameByHandleA"); - *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32, - "GetFinalPathNameByHandleW"); - has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA && - Py_GetFinalPathNameByHandleW; - } - return has_GetFinalPathNameByHandle; -} - static BOOL get_target_path(HANDLE hdl, wchar_t **target_path) { @@ -1607,18 +1451,18 @@ get_target_path(HANDLE hdl, wchar_t **target_path) /* We have a good handle to the target, use it to determine the target path name (then we'll call lstat on it). */ - buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0, - VOLUME_NAME_DOS); + buf_size = GetFinalPathNameByHandleW(hdl, 0, 0, + VOLUME_NAME_DOS); if(!buf_size) return FALSE; - buf = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t)); + buf = PyMem_New(wchar_t, buf_size+1); if (!buf) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; } - result_length = Py_GetFinalPathNameByHandleW(hdl, + result_length = GetFinalPathNameByHandleW(hdl, buf, buf_size, VOLUME_NAME_DOS); if(!result_length) { @@ -1638,10 +1482,10 @@ get_target_path(HANDLE hdl, wchar_t **target_path) } static int -win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, +win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse); static int -win32_xstat_impl(const char *path, struct win32_stat *result, +win32_xstat_impl(const char *path, struct _Py_stat_struct *result, BOOL traverse) { int code; @@ -1651,12 +1495,6 @@ win32_xstat_impl(const char *path, struct win32_stat *result, wchar_t *target_path; const char *dot; - if(!check_GetFinalPathNameByHandle()) { - /* If the OS doesn't have GetFinalPathNameByHandle, don't - traverse reparse point. */ - traverse = FALSE; - } - hFile = CreateFileA( path, FILE_READ_ATTRIBUTES, /* desired access */ @@ -1666,7 +1504,7 @@ win32_xstat_impl(const char *path, struct win32_stat *result, /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink. Because of this, calls like GetFinalPathNameByHandle will return - the symlink path agin and not the actual final path. */ + the symlink path again and not the actual final path. */ FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS| FILE_FLAG_OPEN_REPARSE_POINT, NULL); @@ -1724,7 +1562,7 @@ win32_xstat_impl(const char *path, struct win32_stat *result, } else CloseHandle(hFile); } - attribute_data_to_stat(&info, reparse_tag, result); + _Py_attribute_data_to_stat(&info, reparse_tag, result); /* Set S_IEXEC if it is an .exe, .bat, ... */ dot = strrchr(path, '.'); @@ -1737,7 +1575,7 @@ win32_xstat_impl(const char *path, struct win32_stat *result, } static int -win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, +win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse) { int code; @@ -1747,12 +1585,6 @@ win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, wchar_t *target_path; const wchar_t *dot; - if(!check_GetFinalPathNameByHandle()) { - /* If the OS doesn't have GetFinalPathNameByHandle, don't - traverse reparse point. */ - traverse = FALSE; - } - hFile = CreateFileW( path, FILE_READ_ATTRIBUTES, /* desired access */ @@ -1762,7 +1594,7 @@ win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink. Because of this, calls like GetFinalPathNameByHandle will return - the symlink path agin and not the actual final path. */ + the symlink path again and not the actual final path. */ FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS| FILE_FLAG_OPEN_REPARSE_POINT, NULL); @@ -1820,7 +1652,7 @@ win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, } else CloseHandle(hFile); } - attribute_data_to_stat(&info, reparse_tag, result); + _Py_attribute_data_to_stat(&info, reparse_tag, result); /* Set S_IEXEC if it is an .exe, .bat, ... */ dot = wcsrchr(path, '.'); @@ -1833,7 +1665,7 @@ win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, } static int -win32_xstat(const char *path, struct win32_stat *result, BOOL traverse) +win32_xstat(const char *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. */ @@ -1843,7 +1675,7 @@ win32_xstat(const char *path, struct win32_stat *result, BOOL traverse) } static int -win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse) +win32_xstat_w(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. */ @@ -1865,80 +1697,29 @@ win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse) The _w represent Unicode equivalents of the aforementioned ANSI functions. */ static int -win32_lstat(const char* path, struct win32_stat *result) +win32_lstat(const char* path, struct _Py_stat_struct *result) { return win32_xstat(path, result, FALSE); } static int -win32_lstat_w(const wchar_t* path, struct win32_stat *result) +win32_lstat_w(const wchar_t* path, struct _Py_stat_struct *result) { return win32_xstat_w(path, result, FALSE); } static int -win32_stat(const char* path, struct win32_stat *result) +win32_stat(const char* path, struct _Py_stat_struct *result) { return win32_xstat(path, result, TRUE); } static int -win32_stat_w(const wchar_t* path, struct win32_stat *result) +win32_stat_w(const wchar_t* path, struct _Py_stat_struct *result) { return win32_xstat_w(path, result, TRUE); } -static int -win32_fstat(int file_number, struct win32_stat *result) -{ - BY_HANDLE_FILE_INFORMATION info; - HANDLE h; - int type; - - if (!_PyVerify_fd(file_number)) - h = INVALID_HANDLE_VALUE; - else - h = (HANDLE)_get_osfhandle(file_number); - - /* Protocol violation: we explicitly clear errno, instead of - setting it to a POSIX error. Callers should use GetLastError. */ - errno = 0; - - if (h == INVALID_HANDLE_VALUE) { - /* This is really a C library error (invalid file handle). - We set the Win32 error to the closes one matching. */ - SetLastError(ERROR_INVALID_HANDLE); - return -1; - } - memset(result, 0, sizeof(*result)); - - type = GetFileType(h); - if (type == FILE_TYPE_UNKNOWN) { - DWORD error = GetLastError(); - if (error != 0) { - return -1; - } - /* else: valid but unknown file */ - } - - if (type != FILE_TYPE_DISK) { - if (type == FILE_TYPE_CHAR) - result->st_mode = _S_IFCHR; - else if (type == FILE_TYPE_PIPE) - result->st_mode = _S_IFIFO; - return 0; - } - - if (!GetFileInformationByHandle(h, &info)) { - return -1; - } - - attribute_data_to_stat(&info, 0, result); - /* specific to fstat() */ - result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow; - return 0; -} - #endif /* MS_WINDOWS */ PyDoc_STRVAR(stat_result__doc__, @@ -1987,6 +1768,9 @@ static PyStructSequence_Field stat_result_fields[] = { #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 {0} }; @@ -2027,6 +1811,12 @@ static PyStructSequence_Field stat_result_fields[] = { #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 + static PyStructSequence_Desc stat_result_desc = { "stat_result", /* name */ stat_result__doc__, /* doc */ @@ -2128,10 +1918,12 @@ static int _stat_float_times = 1; PyDoc_STRVAR(stat_float_times__doc__, "stat_float_times([newval]) -> oldval\n\n\ Determine whether os.[lf]stat represents time stamps as float objects.\n\ -If newval is True, future calls to stat() return floats, if it is False,\n\ -future calls return ints. \n\ -If newval is omitted, return the current setting.\n"); +\n\ +If value is True, future calls to stat() return floats; if it is False,\n\ +future calls return ints.\n\ +If value is omitted, return the current setting.\n"); +/* AC 3.5: the public default value should be None, not ready for that yet */ static PyObject* stat_float_times(PyObject* self, PyObject *args) { @@ -2215,11 +2007,8 @@ _pystat_fromstructstat(STRUCT_STAT *st) #endif #ifdef MS_WINDOWS PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev)); -#elif defined(HAVE_LONG_LONG) - PyStructSequence_SET_ITEM(v, 2, - PyLong_FromLongLong((PY_LONG_LONG)st->st_dev)); #else - PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev)); + 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) @@ -2294,6 +2083,10 @@ _pystat_fromstructstat(STRUCT_STAT *st) 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 if (PyErr_Occurred()) { Py_DECREF(v); @@ -2357,67 +2150,316 @@ posix_do_stat(char *function_name, path_t *path, return _pystat_fromstructstat(&st); } -#ifdef HAVE_FSTATAT - #define OS_STAT_DIR_FD_CONVERTER dir_fd_converter +/*[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 OS_STAT_DIR_FD_CONVERTER dir_fd_unavailable + #define PATH_HAVE_{s} 0 #endif +""".rstrip().format(s=s)) +[python start generated code]*/ -/*[python] +#ifdef HAVE_FACCESSAT + #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif -class path_t_converter(CConverter): +#ifdef HAVE_FCHMODAT + #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif - type = "path_t" - impl_by_reference = True - parse_by_reference = True +#ifdef HAVE_FCHOWNAT + #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif - converter = 'path_converter' +#ifdef HAVE_FSTATAT + #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif - def converter_init(self, *, allow_fd=False, nullable=False): - def strify(value): - return str(int(bool(value))) +#ifdef HAVE_LINKAT + #define LINKAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif - # right now path_t doesn't support default values. - # to support a default value, you'll need to override initialize(). +#ifdef HAVE_MKDIRAT + #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif - assert self.default is unspecified +#ifdef HAVE_MKFIFOAT + #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif - self.nullable = nullable - self.allow_fd = allow_fd +#ifdef HAVE_MKNODAT + #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif - self.c_default = 'PATH_T_INITIALIZE("{}", {}, {})'.format( - self.function.name, - strify(nullable), - strify(allow_fd), - ) +#ifdef HAVE_OPENAT + #define OPENAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable +#endif - def cleanup(self): - return "path_cleanup(&" + self.name + ");\n" +#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' - converter = 'OS_STAT_DIR_FD_CONVERTER' - def converter_init(self): + 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 "' -[python]*/ -/*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +class idtype_t_converter(int_converter): + type = 'idtype_t' -/*[clinic] +class id_t_converter(CConverter): + type = 'id_t' + format_unit = '" _Py_PARSE_PID "' -os.stat -> object(doc_default='stat_result') +class Py_intptr_t_converter(CConverter): + type = 'Py_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=affe68316f160401]*/ + +/*[clinic input] + +os.stat path : path_t(allow_fd=True) Path to be examined; can be string, bytes, or open-file-descriptor int. * - dir_fd : dir_fd = None + 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. @@ -2436,103 +2478,43 @@ dir_fd and follow_symlinks may not be implemented It's an error to use dir_fd or follow_symlinks when specifying path as an open file descriptor. -[clinic]*/ - -PyDoc_STRVAR(os_stat__doc__, -"stat(path, *, dir_fd=None, follow_symlinks=True)\n" -"Perform a stat system call on the given path.\n" -"\n" -" path\n" -" Path to be examined; can be string, bytes, 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 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)os_stat, METH_VARARGS|METH_KEYWORDS, os_stat__doc__}, - -static PyObject * -os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks); +[clinic start generated code]*/ static PyObject * -os_stat(PyModuleDef *module, PyObject *args, PyObject *kwargs) +os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, + int follow_symlinks) +/*[clinic end generated code: output=e4f7569f95d523ca input=099d356c306fa24a]*/ { - PyObject *return_value = NULL; - static char *_keywords[] = {"path", "dir_fd", "follow_symlinks", NULL}; - path_t path = PATH_T_INITIALIZE("stat", 0, 1); - int dir_fd = DEFAULT_DIR_FD; - int follow_symlinks = 1; + return posix_do_stat("stat", path, dir_fd, follow_symlinks); +} - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "O&|$O&p:stat", _keywords, - path_converter, &path, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) - goto exit; - return_value = os_stat_impl(module, &path, dir_fd, follow_symlinks); -exit: - /* Cleanup for path */ - path_cleanup(&path); +/*[clinic input] +os.lstat - return return_value; -} + path : path_t -static PyObject * -os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks) -/*[clinic checksum: 85a71ad602e89f8e280118da976f70cd2f9abdf1]*/ -{ - return posix_do_stat("stat", path, dir_fd, follow_symlinks); -} + * -PyDoc_STRVAR(posix_lstat__doc__, -"lstat(path, *, dir_fd=None) -> stat result\n\n\ -Like stat(), but do not follow symbolic links.\n\ -Equivalent to stat(path, follow_symlinks=False)."); + 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 * -posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs) +os_lstat_impl(PyModuleDef *module, path_t *path, int dir_fd) +/*[clinic end generated code: output=7a748e333fcb39bd input=0b7474765927b925]*/ { - static char *keywords[] = {"path", "dir_fd", NULL}; - path_t path; - int dir_fd = DEFAULT_DIR_FD; int follow_symlinks = 0; - PyObject *return_value; - - memset(&path, 0, sizeof(path)); - path.function_name = "lstat"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords, - path_converter, &path, -#ifdef HAVE_FSTATAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; - return_value = posix_do_stat("lstat", &path, dir_fd, follow_symlinks); - path_cleanup(&path); - return return_value; + return posix_do_stat("lstat", path, dir_fd, follow_symlinks); } -#ifdef HAVE_FACCESSAT - #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_converter -#else - #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_unavailable -#endif -/*[clinic] -os.access -> object(doc_default='True if granted, False otherwise') +/*[clinic input] +os.access -> bool path: path_t(allow_fd=True) Path to be tested; can be string, bytes, or open-file-descriptor int. @@ -2543,7 +2525,7 @@ os.access -> object(doc_default='True if granted, False otherwise') * - dir_fd : dir_fd = None + 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. @@ -2568,72 +2550,14 @@ 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]*/ - -PyDoc_STRVAR(os_access__doc__, -"access(path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True)\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 open-file-descriptor int.\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)os_access, METH_VARARGS|METH_KEYWORDS, os_access__doc__}, - -static PyObject * -os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks); - -static PyObject * -os_access(PyModuleDef *module, PyObject *args, PyObject *kwargs) -{ - PyObject *return_value = NULL; - static char *_keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL}; - path_t path = PATH_T_INITIALIZE("access", 0, 1); - int mode; - int dir_fd = DEFAULT_DIR_FD; - int effective_ids = 0; - int follow_symlinks = 1; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "O&i|$O&pp:access", _keywords, - path_converter, &path, &mode, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks)) - goto exit; - return_value = os_access_impl(module, &path, mode, dir_fd, effective_ids, follow_symlinks); - -exit: - /* Cleanup for path */ - path_cleanup(&path); - - return return_value; -} +[clinic start generated code]*/ -static PyObject * -os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks) -/*[clinic checksum: 636e835c36562a2fc11acab75314634127fdf769]*/ +static int +os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, + int effective_ids, int follow_symlinks) +/*[clinic end generated code: output=abaa53340210088d input=b75a756797af45ec]*/ { - PyObject *return_value = NULL; + int return_value; #ifdef MS_WINDOWS DWORD attr; @@ -2643,11 +2567,11 @@ os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effe #ifndef HAVE_FACCESSAT if (follow_symlinks_specified("access", follow_symlinks)) - goto exit; + return -1; if (effective_ids) { argument_unavailable_error("access", "effective_ids"); - goto exit; + return -1; } #endif @@ -2667,11 +2591,10 @@ os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effe * * or it's a directory. * (Directories cannot be read-only on Windows.) */ - return_value = PyBool_FromLong( - (attr != INVALID_FILE_ATTRIBUTES) && + return_value = (attr != INVALID_FILE_ATTRIBUTES) && (!(mode & 2) || !(attr & FILE_ATTRIBUTE_READONLY) || - (attr & FILE_ATTRIBUTE_DIRECTORY))); + (attr & FILE_ATTRIBUTE_DIRECTORY)); #else Py_BEGIN_ALLOW_THREADS @@ -2690,12 +2613,9 @@ os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effe #endif result = access(path->narrow, mode); Py_END_ALLOW_THREADS - return_value = PyBool_FromLong(!result); + return_value = !result; #endif -#ifndef HAVE_FACCESSAT -exit: -#endif return return_value; } @@ -2714,8 +2634,7 @@ os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effe #ifdef HAVE_TTYNAME - -/*[clinic] +/*[clinic input] os.ttyname -> DecodeFSDefault fd: int @@ -2724,73 +2643,31 @@ os.ttyname -> DecodeFSDefault / Return the name of the terminal device connected to 'fd'. -[clinic]*/ - -PyDoc_STRVAR(os_ttyname__doc__, -"ttyname(fd)\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_VARARGS, os_ttyname__doc__}, - -static char * -os_ttyname_impl(PyModuleDef *module, int fd); - -static PyObject * -os_ttyname(PyModuleDef *module, PyObject *args) -{ - PyObject *return_value = NULL; - int fd; - char *_return_value; - - if (!PyArg_ParseTuple(args, - "i:ttyname", - &fd)) - goto exit; - _return_value = os_ttyname_impl(module, fd); - if (_return_value == NULL) - goto exit; - return_value = PyUnicode_DecodeFSDefault(_return_value); - -exit: - return return_value; -} +[clinic start generated code]*/ static char * os_ttyname_impl(PyModuleDef *module, int fd) -/*[clinic checksum: 0f368134dc0a7f21f25185e2e6bacf7675fb473a]*/ +/*[clinic end generated code: output=03ad3d5ccaef75c3 input=5f72ca83e76b3b45]*/ { char *ret; -#if defined(__VMS) - /* file descriptor 0 only, the default input device (stdin) */ - if (fd == 0) { - ret = ttyname(); - } - else { - ret = NULL; - } -#else ret = ttyname(fd); -#endif if (ret == NULL) posix_error(); return ret; } -#else -#define OS_TTYNAME_METHODDEF #endif #ifdef HAVE_CTERMID -PyDoc_STRVAR(posix_ctermid__doc__, -"ctermid() -> string\n\n\ -Return the name of the controlling terminal for this process."); +/*[clinic input] +os.ctermid + +Return the name of the controlling terminal for this process. +[clinic start generated code]*/ static PyObject * -posix_ctermid(PyObject *self, PyObject *noargs) +os_ctermid_impl(PyModuleDef *module) +/*[clinic end generated code: output=1b73788201e0aebd input=3b87fdd52556382d]*/ { char *ret; char buffer[L_ctermid]; @@ -2804,106 +2681,112 @@ posix_ctermid(PyObject *self, PyObject *noargs) return posix_error(); return PyUnicode_DecodeFSDefault(buffer); } -#endif +#endif /* HAVE_CTERMID */ -PyDoc_STRVAR(posix_chdir__doc__, -"chdir(path)\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."); + +/*[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 * -posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs) +os_chdir_impl(PyModuleDef *module, path_t *path) +/*[clinic end generated code: output=7358e3a20fb5aa93 input=1a4a15b4d12cb15d]*/ { - path_t path; int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", NULL}; - - memset(&path, 0, sizeof(path)); - path.function_name = "chdir"; -#ifdef HAVE_FCHDIR - path.allow_fd = 1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords, - path_converter, &path - )) - return NULL; Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS - if (path.wide) - result = win32_wchdir(path.wide); + if (path->wide) + result = win32_wchdir(path->wide); else - result = win32_chdir(path.narrow); + result = win32_chdir(path->narrow); result = !result; /* on unix, success = 0, on windows, success = !0 */ #else #ifdef HAVE_FCHDIR - if (path.fd != -1) - result = fchdir(path.fd); + if (path->fd != -1) + result = fchdir(path->fd); else #endif - result = chdir(path.narrow); + result = chdir(path->narrow); #endif Py_END_ALLOW_THREADS if (result) { - return_value = path_error(&path); - goto exit; + return path_error(path); } - return_value = Py_None; - Py_INCREF(Py_None); - -exit: - path_cleanup(&path); - return return_value; + Py_RETURN_NONE; } + #ifdef HAVE_FCHDIR -PyDoc_STRVAR(posix_fchdir__doc__, -"fchdir(fd)\n\n\ -Change to the directory of the given file descriptor. fd must be\n\ -opened on a directory, not a file. Equivalent to os.chdir(fd)."); +/*[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 * -posix_fchdir(PyObject *self, PyObject *fdobj) +os_fchdir_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=361d30df6b2d3418 input=18e816479a2fa985]*/ { - return posix_fildes(fdobj, fchdir); + return posix_fildes_fd(fd, fchdir); } #endif /* HAVE_FCHDIR */ -PyDoc_STRVAR(posix_chmod__doc__, -"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\ -Change the access permissions of a file.\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, chmod 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."); +/*[clinic input] +os.chmod + + path: path_t(allow_fd='PATH_HAVE_FCHMOD') + Path to be modified. May always be specified as a str or bytes. + 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 * -posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs) +os_chmod_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, + int follow_symlinks) +/*[clinic end generated code: output=05e7f73b1a843ba2 input=7f1618e5e15cc196]*/ { - path_t path; - int mode; - int dir_fd = DEFAULT_DIR_FD; - int follow_symlinks = 1; int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "mode", "dir_fd", - "follow_symlinks", NULL}; #ifdef MS_WINDOWS DWORD attr; @@ -2913,33 +2796,17 @@ posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs) int fchmodat_nofollow_unsupported = 0; #endif - memset(&path, 0, sizeof(path)); - path.function_name = "chmod"; -#ifdef HAVE_FCHMOD - path.allow_fd = 1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords, - path_converter, &path, - &mode, -#ifdef HAVE_FCHMODAT - dir_fd_converter, &dir_fd, -#else - dir_fd_unavailable, &dir_fd, -#endif - &follow_symlinks)) - return NULL; - #if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD)) if (follow_symlinks_specified("chmod", follow_symlinks)) - goto exit; + return NULL; #endif #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (path.wide) - attr = GetFileAttributesW(path.wide); + if (path->wide) + attr = GetFileAttributesW(path->wide); else - attr = GetFileAttributesA(path.narrow); + attr = GetFileAttributesA(path->narrow); if (attr == INVALID_FILE_ATTRIBUTES) result = 0; else { @@ -2947,27 +2814,26 @@ posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs) attr &= ~FILE_ATTRIBUTE_READONLY; else attr |= FILE_ATTRIBUTE_READONLY; - if (path.wide) - result = SetFileAttributesW(path.wide, attr); + if (path->wide) + result = SetFileAttributesW(path->wide, attr); else - result = SetFileAttributesA(path.narrow, attr); + result = SetFileAttributesA(path->narrow, attr); } Py_END_ALLOW_THREADS if (!result) { - return_value = path_error(&path); - goto exit; + return path_error(path); } #else /* MS_WINDOWS */ Py_BEGIN_ALLOW_THREADS #ifdef HAVE_FCHMOD - if (path.fd != -1) - result = fchmod(path.fd, mode); + 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); + result = lchmod(path->narrow, mode); else #endif #ifdef HAVE_FCHMODAT @@ -2982,7 +2848,7 @@ posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs) * 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, + result = fchmodat(dir_fd, path->narrow, mode, follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); /* * But wait! We can't throw the exception without allowing threads, @@ -2995,7 +2861,7 @@ posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs) } else #endif - result = chmod(path.narrow, mode); + result = chmod(path->narrow, mode); Py_END_ALLOW_THREADS if (result) { @@ -3009,272 +2875,289 @@ posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs) } else #endif - return_value = path_error(&path); - goto exit; + return path_error(path); } #endif - Py_INCREF(Py_None); - return_value = Py_None; -exit: - path_cleanup(&path); - return return_value; + Py_RETURN_NONE; } #ifdef HAVE_FCHMOD -PyDoc_STRVAR(posix_fchmod__doc__, -"fchmod(fd, mode)\n\n\ -Change the access permissions of the file given by file\n\ -descriptor fd. Equivalent to os.chmod(fd, mode)."); +/*[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 * -posix_fchmod(PyObject *self, PyObject *args) +os_fchmod_impl(PyModuleDef *module, int fd, int mode) +/*[clinic end generated code: output=2ee31ca226d1ed33 input=8ab11975ca01ee5b]*/ { - int fd, mode, res; - if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = fchmod(fd, mode); - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error(); + int res; + int async_err = 0; + + 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 -PyDoc_STRVAR(posix_lchmod__doc__, -"lchmod(path, mode)\n\n\ -Change the access permissions of a file. If path is a symlink, this\n\ -affects the link itself rather than the target.\n\ -Equivalent to chmod(path, mode, follow_symlinks=False)."); +/*[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 * -posix_lchmod(PyObject *self, PyObject *args) +os_lchmod_impl(PyModuleDef *module, path_t *path, int mode) +/*[clinic end generated code: output=7c0cc46588d89e46 input=90c5663c7465d24f]*/ { - path_t path; - int i; int res; - memset(&path, 0, sizeof(path)); - path.function_name = "lchmod"; - if (!PyArg_ParseTuple(args, "O&i:lchmod", - path_converter, &path, &i)) - return NULL; Py_BEGIN_ALLOW_THREADS - res = lchmod(path.narrow, i); + res = lchmod(path->narrow, mode); Py_END_ALLOW_THREADS if (res < 0) { - path_error(&path); - path_cleanup(&path); + path_error(path); return NULL; } - path_cleanup(&path); Py_RETURN_NONE; } #endif /* HAVE_LCHMOD */ #ifdef HAVE_CHFLAGS -PyDoc_STRVAR(posix_chflags__doc__, -"chflags(path, flags, *, follow_symlinks=True)\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."); +/*[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 * -posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs) +os_chflags_impl(PyModuleDef *module, path_t *path, unsigned long flags, + int follow_symlinks) +/*[clinic end generated code: output=ff2d6e73534a95b9 input=0327e29feb876236]*/ { - path_t path; - unsigned long flags; - int follow_symlinks = 1; int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "flags", "follow_symlinks", NULL}; - - memset(&path, 0, sizeof(path)); - path.function_name = "chflags"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords, - path_converter, &path, - &flags, &follow_symlinks)) - return NULL; #ifndef HAVE_LCHFLAGS if (follow_symlinks_specified("chflags", follow_symlinks)) - goto exit; + return NULL; #endif Py_BEGIN_ALLOW_THREADS #ifdef HAVE_LCHFLAGS if (!follow_symlinks) - result = lchflags(path.narrow, flags); + result = lchflags(path->narrow, flags); else #endif - result = chflags(path.narrow, flags); + result = chflags(path->narrow, flags); Py_END_ALLOW_THREADS - if (result) { - return_value = path_error(&path); - goto exit; - } - - return_value = Py_None; - Py_INCREF(Py_None); + if (result) + return path_error(path); -exit: - path_cleanup(&path); - return return_value; + Py_RETURN_NONE; } #endif /* HAVE_CHFLAGS */ + #ifdef HAVE_LCHFLAGS -PyDoc_STRVAR(posix_lchflags__doc__, -"lchflags(path, flags)\n\n\ -Set file flags.\n\ -This function will not follow symbolic links.\n\ -Equivalent to chflags(path, flags, follow_symlinks=False)."); +/*[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 * -posix_lchflags(PyObject *self, PyObject *args) +os_lchflags_impl(PyModuleDef *module, path_t *path, unsigned long flags) +/*[clinic end generated code: output=6741322fb949661b input=f9f82ea8b585ca9d]*/ { - path_t path; - unsigned long flags; int res; - memset(&path, 0, sizeof(path)); - path.function_name = "lchflags"; - if (!PyArg_ParseTuple(args, "O&k:lchflags", - path_converter, &path, &flags)) - return NULL; Py_BEGIN_ALLOW_THREADS - res = lchflags(path.narrow, flags); + res = lchflags(path->narrow, flags); Py_END_ALLOW_THREADS if (res < 0) { - path_error(&path); - path_cleanup(&path); - return NULL; + return path_error(path); } - path_cleanup(&path); Py_RETURN_NONE; } #endif /* HAVE_LCHFLAGS */ + #ifdef HAVE_CHROOT -PyDoc_STRVAR(posix_chroot__doc__, -"chroot(path)\n\n\ -Change root directory to path."); +/*[clinic input] +os.chroot + path: path_t + +Change root directory to path. + +[clinic start generated code]*/ static PyObject * -posix_chroot(PyObject *self, PyObject *args) +os_chroot_impl(PyModuleDef *module, path_t *path) +/*[clinic end generated code: output=b6dbfabe74ecaa9d input=14822965652c3dc3]*/ { - return posix_1str("chroot", args, "O&:chroot", chroot); + 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 +#endif /* HAVE_CHROOT */ + #ifdef HAVE_FSYNC -PyDoc_STRVAR(posix_fsync__doc__, -"fsync(fildes)\n\n\ -force write of file with filedescriptor to disk."); +/*[clinic input] +os.fsync + + fd: fildes + +Force write of fd to disk. +[clinic start generated code]*/ static PyObject * -posix_fsync(PyObject *self, PyObject *fdobj) +os_fsync_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=83a350851064aea7 input=21c3645c056967f2]*/ { - return posix_fildes(fdobj, fsync); + return posix_fildes_fd(fd, fsync); } #endif /* HAVE_FSYNC */ + #ifdef HAVE_SYNC -PyDoc_STRVAR(posix_sync__doc__, -"sync()\n\n\ -Force write of everything to disk."); +/*[clinic input] +os.sync + +Force write of everything to disk. +[clinic start generated code]*/ static PyObject * -posix_sync(PyObject *self, PyObject *noargs) +os_sync_impl(PyModuleDef *module) +/*[clinic end generated code: output=ba524f656c201c40 input=84749fe5e9b404ff]*/ { Py_BEGIN_ALLOW_THREADS sync(); Py_END_ALLOW_THREADS Py_RETURN_NONE; } -#endif +#endif /* HAVE_SYNC */ -#ifdef HAVE_FDATASYNC +#ifdef HAVE_FDATASYNC #ifdef __hpux extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */ #endif -PyDoc_STRVAR(posix_fdatasync__doc__, -"fdatasync(fildes)\n\n\ -force write of file with filedescriptor to disk.\n\ - does not force update of metadata."); +/*[clinic input] +os.fdatasync + + fd: fildes + +Force write of fd to disk without forcing update of metadata. +[clinic start generated code]*/ static PyObject * -posix_fdatasync(PyObject *self, PyObject *fdobj) +os_fdatasync_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=e0f04a3aff515b75 input=bc74791ee54dd291]*/ { - return posix_fildes(fdobj, fdatasync); + return posix_fildes_fd(fd, fdatasync); } #endif /* HAVE_FDATASYNC */ #ifdef HAVE_CHOWN -PyDoc_STRVAR(posix_chown__doc__, -"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\ -Change the owner and group id of path to the numeric uid and gid.\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."); +/*[clinic input] +os.chown + + path : path_t(allow_fd='PATH_HAVE_FCHOWN') + Path to be examined; can be string, bytes, 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 * -posix_chown(PyObject *self, PyObject *args, PyObject *kwargs) +os_chown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid, + int dir_fd, int follow_symlinks) +/*[clinic end generated code: output=e0a4559f394dbd91 input=a61cc35574814d5d]*/ { - path_t path; - uid_t uid; - gid_t gid; - int dir_fd = DEFAULT_DIR_FD; - int follow_symlinks = 1; int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "uid", "gid", "dir_fd", - "follow_symlinks", NULL}; - - memset(&path, 0, sizeof(path)); - path.function_name = "chown"; -#ifdef HAVE_FCHOWN - path.allow_fd = 1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords, - path_converter, &path, - _Py_Uid_Converter, &uid, - _Py_Gid_Converter, &gid, -#ifdef HAVE_FCHOWNAT - dir_fd_converter, &dir_fd, -#else - dir_fd_unavailable, &dir_fd, -#endif - &follow_symlinks)) - return NULL; #if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT)) if (follow_symlinks_specified("chown", follow_symlinks)) - goto exit; + return NULL; #endif - if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) || - fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks)) - goto exit; + 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__ /* @@ -3285,102 +3168,98 @@ posix_chown(PyObject *self, PyObject *args, PyObject *kwargs) */ if ((!follow_symlinks) && (lchown == NULL)) { follow_symlinks_specified("chown", follow_symlinks); - goto exit; + return NULL; } #endif Py_BEGIN_ALLOW_THREADS #ifdef HAVE_FCHOWN - if (path.fd != -1) - result = fchown(path.fd, uid, gid); + 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); + 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, + result = fchownat(dir_fd, path->narrow, uid, gid, follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); else #endif - result = chown(path.narrow, uid, gid); + result = chown(path->narrow, uid, gid); Py_END_ALLOW_THREADS - if (result) { - return_value = path_error(&path); - goto exit; - } - - return_value = Py_None; - Py_INCREF(Py_None); + if (result) + return path_error(path); -exit: - path_cleanup(&path); - return return_value; + Py_RETURN_NONE; } #endif /* HAVE_CHOWN */ + #ifdef HAVE_FCHOWN -PyDoc_STRVAR(posix_fchown__doc__, -"fchown(fd, uid, gid)\n\n\ -Change the owner and group id of the file given by file descriptor\n\ -fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid)."); +/*[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 * -posix_fchown(PyObject *self, PyObject *args) +os_fchown_impl(PyModuleDef *module, int fd, uid_t uid, gid_t gid) +/*[clinic end generated code: output=7545abf8f6086d76 input=3af544ba1b13a0d7]*/ { - int fd; - uid_t uid; - gid_t gid; int res; - if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd, - _Py_Uid_Converter, &uid, - _Py_Gid_Converter, &gid)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = fchown(fd, uid, gid); - Py_END_ALLOW_THREADS - if (res < 0) - return posix_error(); + int async_err = 0; + + do { + Py_BEGIN_ALLOW_THREADS + res = fchown(fd, uid, gid); + Py_END_ALLOW_THREADS + } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (res != 0) + return (!async_err) ? posix_error() : NULL; + Py_RETURN_NONE; } #endif /* HAVE_FCHOWN */ + #ifdef HAVE_LCHOWN -PyDoc_STRVAR(posix_lchown__doc__, -"lchown(path, uid, gid)\n\n\ -Change the owner and group id of path to the numeric uid and gid.\n\ -This function will not follow symbolic links.\n\ -Equivalent to os.chown(path, uid, gid, follow_symlinks=False)."); +/*[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 * -posix_lchown(PyObject *self, PyObject *args) +os_lchown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid) +/*[clinic end generated code: output=bb0d2da1579ac275 input=b1c6014d563a7161]*/ { - path_t path; - uid_t uid; - gid_t gid; int res; - memset(&path, 0, sizeof(path)); - path.function_name = "lchown"; - if (!PyArg_ParseTuple(args, "O&O&O&:lchown", - path_converter, &path, - _Py_Uid_Converter, &uid, - _Py_Gid_Converter, &gid)) - return NULL; Py_BEGIN_ALLOW_THREADS - res = lchown(path.narrow, uid, gid); + res = lchown(path->narrow, uid, gid); Py_END_ALLOW_THREADS if (res < 0) { - path_error(&path); - path_cleanup(&path); - return NULL; + return path_error(path); } - path_cleanup(&path); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } #endif /* HAVE_LCHOWN */ @@ -3388,12 +3267,15 @@ posix_lchown(PyObject *self, PyObject *args) static PyObject * posix_getcwd(int use_bytes) { - char buf[1026]; - char *res; + char *buf, *tmpbuf; + char *cwd; + const size_t chunk = 1024; + size_t buflen = 0; + PyObject *obj; #ifdef MS_WINDOWS if (!use_bytes) { - wchar_t wbuf[1026]; + wchar_t wbuf[MAXPATHLEN]; wchar_t *wbuf2 = wbuf; PyObject *resobj; DWORD len; @@ -3427,158 +3309,152 @@ posix_getcwd(int use_bytes) return NULL; #endif + buf = cwd = NULL; Py_BEGIN_ALLOW_THREADS - res = getcwd(buf, sizeof buf); + do { + buflen += chunk; + tmpbuf = PyMem_RawRealloc(buf, buflen); + if (tmpbuf == NULL) + break; + + buf = tmpbuf; + cwd = getcwd(buf, buflen); + } while (cwd == NULL && errno == ERANGE); Py_END_ALLOW_THREADS - if (res == NULL) + + if (cwd == NULL) { + PyMem_RawFree(buf); return posix_error(); + } + if (use_bytes) - return PyBytes_FromStringAndSize(buf, strlen(buf)); - return PyUnicode_DecodeFSDefault(buf); + obj = PyBytes_FromStringAndSize(buf, strlen(buf)); + else + obj = PyUnicode_DecodeFSDefault(buf); + PyMem_RawFree(buf); + + return obj; } -PyDoc_STRVAR(posix_getcwd__doc__, -"getcwd() -> path\n\n\ -Return a unicode string representing the current working directory."); + +/*[clinic input] +os.getcwd + +Return a unicode string representing the current working directory. +[clinic start generated code]*/ static PyObject * -posix_getcwd_unicode(PyObject *self) +os_getcwd_impl(PyModuleDef *module) +/*[clinic end generated code: output=efe3a8c0121525ea input=f069211bb70e3d39]*/ { return posix_getcwd(0); } -PyDoc_STRVAR(posix_getcwdb__doc__, -"getcwdb() -> path\n\n\ -Return a bytes string representing the current working directory."); + +/*[clinic input] +os.getcwdb + +Return a bytes string representing the current working directory. +[clinic start generated code]*/ static PyObject * -posix_getcwd_bytes(PyObject *self) +os_getcwdb_impl(PyModuleDef *module) +/*[clinic end generated code: output=7fce42ee4b2a296a input=f6f6a378dad3d9cb]*/ { return posix_getcwd(1); } + #if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS)) #define HAVE_LINK 1 #endif #ifdef HAVE_LINK -PyDoc_STRVAR(posix_link__doc__, -"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\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."); - -static PyObject * -posix_link(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t src, dst; - int src_dir_fd = DEFAULT_DIR_FD; - int dst_dir_fd = DEFAULT_DIR_FD; - int follow_symlinks = 1; - PyObject *return_value = NULL; - static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", - "follow_symlinks", NULL}; +/*[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(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, + int dst_dir_fd, int follow_symlinks) +/*[clinic end generated code: output=f47a7e88f7b391b6 input=b0095ebbcbaa7e04]*/ +{ #ifdef MS_WINDOWS BOOL result; #else int result; #endif - memset(&src, 0, sizeof(src)); - memset(&dst, 0, sizeof(dst)); - src.function_name = "link"; - dst.function_name = "link"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords, - path_converter, &src, - path_converter, &dst, - dir_fd_converter, &src_dir_fd, - dir_fd_converter, &dst_dir_fd, - &follow_symlinks)) - return NULL; - #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"); - goto exit; + return NULL; } #endif - if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) { + if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { PyErr_SetString(PyExc_NotImplementedError, "link: src and dst must be the same type"); - goto exit; + return NULL; } #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (src.wide) - result = CreateHardLinkW(dst.wide, src.wide, NULL); + if (src->wide) + result = CreateHardLinkW(dst->wide, src->wide, NULL); else - result = CreateHardLinkA(dst.narrow, src.narrow, NULL); + result = CreateHardLinkA(dst->narrow, src->narrow, NULL); Py_END_ALLOW_THREADS - if (!result) { - return_value = path_error(&src); - goto exit; - } + 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, + result = linkat(src_dir_fd, src->narrow, + dst_dir_fd, dst->narrow, follow_symlinks ? AT_SYMLINK_FOLLOW : 0); else #endif - result = link(src.narrow, dst.narrow); + result = link(src->narrow, dst->narrow); Py_END_ALLOW_THREADS - if (result) { - return_value = path_error(&src); - goto exit; - } + if (result) + return path_error2(src, dst); #endif - return_value = Py_None; - Py_INCREF(Py_None); - -exit: - path_cleanup(&src); - path_cleanup(&dst); - return return_value; + Py_RETURN_NONE; } #endif - -PyDoc_STRVAR(posix_listdir__doc__, -"listdir(path='.') -> list_of_filenames\n\n\ -Return a list containing the names of the files in the directory.\n\ -The list is in arbitrary order. It does not include the special\n\ -entries '.' and '..' even if they are present in the directory.\n\ -\n\ -path can be specified as either str or bytes. If path is bytes,\n\ - the filenames returned will also be bytes; in all other circumstances\n\ - the filenames returned will be str.\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."); - #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) static PyObject * _listdir_windows_no_opendir(path_t *path, PyObject *list) { - static char *keywords[] = {"path", NULL}; PyObject *v; HANDLE hFindFile = INVALID_HANDLE_VALUE; BOOL result; @@ -3602,7 +3478,7 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list) len = wcslen(path->wide); } /* The +5 is so we can append "\\*.*\0" */ - wnamebuf = PyMem_Malloc((len + 5) * sizeof(wchar_t)); + wnamebuf = PyMem_New(wchar_t, len + 5); if (!wnamebuf) { PyErr_NoMemory(); goto exit; @@ -3746,10 +3622,8 @@ _posix_listdir(path_t *path, PyObject *list) if (path->fd != -1) { /* closedir() closes the FD, so we duplicate it */ fd = _Py_dup(path->fd); - if (fd == -1) { - list = posix_error(); - goto exit; - } + if (fd == -1) + return NULL; return_str = 1; @@ -3839,123 +3713,117 @@ _posix_listdir(path_t *path, PyObject *list) } /* end of _posix_listdir */ #endif /* which OS */ -static PyObject * -posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; - PyObject *list = NULL; - static char *keywords[] = {"path", NULL}; - PyObject *return_value; - memset(&path, 0, sizeof(path)); - path.function_name = "listdir"; - path.nullable = 1; -#ifdef HAVE_FDOPENDIR - path.allow_fd = 1; - path.fd = -1; -#endif +/*[clinic input] +os.listdir - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords, - path_converter, &path)) { - return NULL; - } + 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 or bytes. 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(PyModuleDef *module, path_t *path) +/*[clinic end generated code: output=1fbe67c1f780c8b7 input=09e300416e3cd729]*/ +{ #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) - return_value = _listdir_windows_no_opendir(&path, list); + return _listdir_windows_no_opendir(path, NULL); #else - return_value = _posix_listdir(&path, list); + return _posix_listdir(path, NULL); #endif - path_cleanup(&path); - return return_value; } #ifdef MS_WINDOWS /* A helper function for abspath on win32 */ +/*[clinic input] +os._getfullpathname + + path: path_t + / + +[clinic start generated code]*/ + static PyObject * -posix__getfullpathname(PyObject *self, PyObject *args) +os__getfullpathname_impl(PyModuleDef *module, path_t *path) +/*[clinic end generated code: output=b90b1f103b08773f input=332ed537c29d0a3e]*/ { - const char *path; - char outbuf[MAX_PATH]; - char *temp; - PyObject *po; - - if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) + if (!path->narrow) { - wchar_t *wpath; wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf; wchar_t *wtemp; DWORD result; PyObject *v; - wpath = PyUnicode_AsUnicode(po); - if (wpath == NULL) - return NULL; - result = GetFullPathNameW(wpath, + result = GetFullPathNameW(path->wide, Py_ARRAY_LENGTH(woutbuf), woutbuf, &wtemp); if (result > Py_ARRAY_LENGTH(woutbuf)) { - woutbufp = PyMem_Malloc(result * sizeof(wchar_t)); + woutbufp = PyMem_New(wchar_t, result); if (!woutbufp) return PyErr_NoMemory(); - result = GetFullPathNameW(wpath, result, woutbufp, &wtemp); + result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp); } if (result) v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp)); else - v = win32_error_object("GetFullPathNameW", po); + v = win32_error_object("GetFullPathNameW", path->object); if (woutbufp != woutbuf) PyMem_Free(woutbufp); return v; } - /* Drop the argument parsing error as narrow strings - are also valid. */ - PyErr_Clear(); + else { + char outbuf[MAX_PATH]; + char *temp; - if (!PyArg_ParseTuple (args, "y:_getfullpathname", - &path)) - return NULL; - if (win32_warn_bytes_api()) - return NULL; - if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf), - outbuf, &temp)) { - win32_error("GetFullPathName", path); - return NULL; - } - if (PyUnicode_Check(PyTuple_GetItem(args, 0))) { - return PyUnicode_Decode(outbuf, strlen(outbuf), - Py_FileSystemDefaultEncoding, NULL); + if (!GetFullPathName(path->narrow, Py_ARRAY_LENGTH(outbuf), + outbuf, &temp)) { + win32_error_object("GetFullPathName", path->object); + return NULL; + } + return PyBytes_FromString(outbuf); } - return PyBytes_FromString(outbuf); -} /* end of posix__getfullpathname */ +} +/*[clinic input] +os._getfinalpathname -/* A helper function for samepath on windows */ -static PyObject * -posix__getfinalpathname(PyObject *self, PyObject *args) -{ + path: unicode + / + +A helper function for samepath on windows. +[clinic start generated code]*/ + +static PyObject * +os__getfinalpathname_impl(PyModuleDef *module, PyObject *path) +/*[clinic end generated code: output=8be81a5f51a34bcf input=71d5e89334891bf4]*/ +{ HANDLE hFile; int buf_size; wchar_t *target_path; int result_length; - PyObject *po, *result; - wchar_t *path; + PyObject *result; + wchar_t *path_wchar; - if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po)) + path_wchar = PyUnicode_AsUnicode(path); + if (path_wchar == NULL) return NULL; - path = PyUnicode_AsUnicode(po); - if (path == NULL) - return NULL; - - if(!check_GetFinalPathNameByHandle()) { - /* If the OS doesn't have GetFinalPathNameByHandle, return a - NotImplementedError. */ - return PyErr_Format(PyExc_NotImplementedError, - "GetFinalPathNameByHandle not available on this platform"); - } hFile = CreateFileW( - path, + path_wchar, 0, /* desired access */ 0, /* share mode */ NULL, /* security attributes */ @@ -3965,89 +3833,84 @@ posix__getfinalpathname(PyObject *self, PyObject *args) NULL); if(hFile == INVALID_HANDLE_VALUE) - return win32_error_object("CreateFileW", po); + return win32_error_object("CreateFileW", path); /* We have a good handle to the target, use it to determine the target path name. */ - buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT); + buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT); if(!buf_size) - return win32_error_object("GetFinalPathNameByHandle", po); + return win32_error_object("GetFinalPathNameByHandle", path); - target_path = (wchar_t *)PyMem_Malloc((buf_size+1)*sizeof(wchar_t)); + target_path = PyMem_New(wchar_t, buf_size+1); if(!target_path) return PyErr_NoMemory(); - result_length = Py_GetFinalPathNameByHandleW(hFile, target_path, - buf_size, VOLUME_NAME_DOS); + result_length = GetFinalPathNameByHandleW(hFile, target_path, + buf_size, VOLUME_NAME_DOS); if(!result_length) - return win32_error_object("GetFinalPathNamyByHandle", po); + return win32_error_object("GetFinalPathNamyByHandle", path); if(!CloseHandle(hFile)) - return win32_error_object("CloseHandle", po); + return win32_error_object("CloseHandle", path); target_path[result_length] = 0; result = PyUnicode_FromWideChar(target_path, result_length); PyMem_Free(target_path); return result; - -} /* end of posix__getfinalpathname */ +} PyDoc_STRVAR(posix__isdir__doc__, "Return true if the pathname refers to an existing directory."); +/*[clinic input] +os._isdir + + path: path_t + / + +[clinic start generated code]*/ + static PyObject * -posix__isdir(PyObject *self, PyObject *args) +os__isdir_impl(PyModuleDef *module, path_t *path) +/*[clinic end generated code: output=f17b2d4e1994b0ff input=e794f12faab62a2a]*/ { - const char *path; - PyObject *po; DWORD attributes; - if (PyArg_ParseTuple(args, "U|:_isdir", &po)) { - wchar_t *wpath = PyUnicode_AsUnicode(po); - if (wpath == NULL) - return NULL; - - attributes = GetFileAttributesW(wpath); - if (attributes == INVALID_FILE_ATTRIBUTES) - Py_RETURN_FALSE; - goto check; - } - /* Drop the argument parsing error as narrow strings - are also valid. */ - PyErr_Clear(); + if (!path->narrow) + attributes = GetFileAttributesW(path->wide); + else + attributes = GetFileAttributesA(path->narrow); - if (!PyArg_ParseTuple(args, "y:_isdir", &path)) - return NULL; - if (win32_warn_bytes_api()) - return NULL; - attributes = GetFileAttributesA(path); if (attributes == INVALID_FILE_ATTRIBUTES) Py_RETURN_FALSE; -check: if (attributes & FILE_ATTRIBUTE_DIRECTORY) Py_RETURN_TRUE; else Py_RETURN_FALSE; } -PyDoc_STRVAR(posix__getvolumepathname__doc__, -"Return volume mount point of the specified path."); -/* A helper function for ismount on windows */ +/*[clinic input] +os._getvolumepathname + + path: unicode + +A helper function for ismount on Win32. +[clinic start generated code]*/ + static PyObject * -posix__getvolumepathname(PyObject *self, PyObject *args) +os__getvolumepathname_impl(PyModuleDef *module, PyObject *path) +/*[clinic end generated code: output=79a0ba729f956dbe input=7eacadc40acbda6b]*/ { - PyObject *po, *result; - wchar_t *path, *mountpath=NULL; + PyObject *result; + wchar_t *path_wchar, *mountpath=NULL; size_t buflen; BOOL ret; - if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po)) - return NULL; - path = PyUnicode_AsUnicodeAndSize(po, &buflen); - if (path == NULL) + path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen); + if (path_wchar == NULL) return NULL; buflen += 1; @@ -4059,17 +3922,17 @@ posix__getvolumepathname(PyObject *self, PyObject *args) return NULL; } - mountpath = (wchar_t *)PyMem_Malloc(buflen * sizeof(wchar_t)); + mountpath = PyMem_New(wchar_t, buflen); if (mountpath == NULL) return PyErr_NoMemory(); Py_BEGIN_ALLOW_THREADS - ret = GetVolumePathNameW(path, mountpath, + ret = GetVolumePathNameW(path_wchar, mountpath, Py_SAFE_DOWNCAST(buflen, size_t, DWORD)); Py_END_ALLOW_THREADS if (!ret) { - result = win32_error_object("_getvolumepathname", po); + result = win32_error_object("_getvolumepathname", path); goto exit; } result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath)); @@ -4078,78 +3941,66 @@ posix__getvolumepathname(PyObject *self, PyObject *args) PyMem_Free(mountpath); return result; } -/* end of posix__getvolumepathname */ #endif /* MS_WINDOWS */ -PyDoc_STRVAR(posix_mkdir__doc__, -"mkdir(path, mode=0o777, *, dir_fd=None)\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."); + +/*[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 * -posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs) +os_mkdir_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd) +/*[clinic end generated code: output=8bf1f738873ef2c5 input=e965f68377e9b1ce]*/ { - path_t path; - int mode = 0777; - int dir_fd = DEFAULT_DIR_FD; - static char *keywords[] = {"path", "mode", "dir_fd", NULL}; - PyObject *return_value = NULL; int result; - memset(&path, 0, sizeof(path)); - path.function_name = "mkdir"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords, - path_converter, &path, &mode, -#ifdef HAVE_MKDIRAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; - #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (path.wide) - result = CreateDirectoryW(path.wide, NULL); + if (path->wide) + result = CreateDirectoryW(path->wide, NULL); else - result = CreateDirectoryA(path.narrow, NULL); + result = CreateDirectoryA(path->narrow, NULL); Py_END_ALLOW_THREADS - if (!result) { - return_value = path_error(&path); - goto exit; - } + 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); + result = mkdirat(dir_fd, path->narrow, mode); else #endif #if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__) - result = mkdir(path.narrow); + result = mkdir(path->narrow); #else - result = mkdir(path.narrow, mode); + result = mkdir(path->narrow, mode); #endif Py_END_ALLOW_THREADS - if (result < 0) { - return_value = path_error(&path); - goto exit; - } + if (result < 0) + return path_error(path); #endif - return_value = Py_None; - Py_INCREF(Py_None); -exit: - path_cleanup(&path); - return return_value; + Py_RETURN_NONE; } @@ -4160,17 +4011,20 @@ posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs) #ifdef HAVE_NICE -PyDoc_STRVAR(posix_nice__doc__, -"nice(inc) -> new_priority\n\n\ -Decrease the priority of process by inc and return the new priority."); +/*[clinic input] +os.nice + + increment: int + / + +Add increment to the priority of process and return the new priority. +[clinic start generated code]*/ static PyObject * -posix_nice(PyObject *self, PyObject *args) +os_nice_impl(PyModuleDef *module, int increment) +/*[clinic end generated code: output=8870418a3fc07b51 input=864be2d402a21da2]*/ { - int increment, value; - - if (!PyArg_ParseTuple(args, "i:nice", &increment)) - return NULL; + int value; /* There are two flavours of 'nice': one that returns the new priority (as required by almost all standards out there) and the @@ -4197,17 +4051,21 @@ posix_nice(PyObject *self, PyObject *args) #ifdef HAVE_GETPRIORITY -PyDoc_STRVAR(posix_getpriority__doc__, -"getpriority(which, who) -> current_priority\n\n\ -Get program scheduling priority."); +/*[clinic input] +os.getpriority + + which: int + who: int + +Return program scheduling priority. +[clinic start generated code]*/ static PyObject * -posix_getpriority(PyObject *self, PyObject *args) +os_getpriority_impl(PyModuleDef *module, int which, int who) +/*[clinic end generated code: output=4759937aa5b67ed6 input=9be615d40e2544ef]*/ { - int which, who, retval; + int retval; - if (!PyArg_ParseTuple(args, "ii", &which, &who)) - return NULL; errno = 0; retval = getpriority(which, who); if (errno != 0) @@ -4218,18 +4076,23 @@ posix_getpriority(PyObject *self, PyObject *args) #ifdef HAVE_SETPRIORITY -PyDoc_STRVAR(posix_setpriority__doc__, -"setpriority(which, who, prio) -> None\n\n\ -Set program scheduling priority."); +/*[clinic input] +os.setpriority + + which: int + who: int + priority: int + +Set program scheduling priority. +[clinic start generated code]*/ static PyObject * -posix_setpriority(PyObject *self, PyObject *args) +os_setpriority_impl(PyModuleDef *module, int which, int who, int priority) +/*[clinic end generated code: output=6497d3301547e7d5 input=710ccbf65b9dc513]*/ { - int which, who, prio, retval; + int retval; - if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio)) - return NULL; - retval = setpriority(which, who, prio); + retval = setpriority(which, who, priority); if (retval == -1) return posix_error(); Py_RETURN_NONE; @@ -4238,17 +4101,10 @@ posix_setpriority(PyObject *self, PyObject *args) static PyObject * -internal_rename(PyObject *args, PyObject *kwargs, int is_replace) +internal_rename(path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int is_replace) { char *function_name = is_replace ? "replace" : "rename"; - path_t src; - path_t dst; - int src_dir_fd = DEFAULT_DIR_FD; - int dst_dir_fd = DEFAULT_DIR_FD; int dir_fd_specified; - PyObject *return_value = NULL; - char format[24]; - static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; #ifdef MS_WINDOWS BOOL result; @@ -4257,210 +4113,200 @@ internal_rename(PyObject *args, PyObject *kwargs, int is_replace) int result; #endif - memset(&src, 0, sizeof(src)); - memset(&dst, 0, sizeof(dst)); - src.function_name = function_name; - dst.function_name = function_name; - strcpy(format, "O&O&|$O&O&:"); - strcat(format, function_name); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords, - path_converter, &src, - path_converter, &dst, - dir_fd_converter, &src_dir_fd, - dir_fd_converter, &dst_dir_fd)) - return NULL; - 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"); - goto exit; + return NULL; } #endif - if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) { + if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { PyErr_Format(PyExc_ValueError, "%s: src and dst must be the same type", function_name); - goto exit; + return NULL; } #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (src.wide) - result = MoveFileExW(src.wide, dst.wide, flags); + if (src->wide) + result = MoveFileExW(src->wide, dst->wide, flags); else - result = MoveFileExA(src.narrow, dst.narrow, flags); + result = MoveFileExA(src->narrow, dst->narrow, flags); Py_END_ALLOW_THREADS - if (!result) { - return_value = path_error(&src); - goto exit; - } + if (!result) + return path_error2(src, dst); #else Py_BEGIN_ALLOW_THREADS #ifdef HAVE_RENAMEAT if (dir_fd_specified) - result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow); + result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow); else #endif - result = rename(src.narrow, dst.narrow); + result = rename(src->narrow, dst->narrow); Py_END_ALLOW_THREADS - if (result) { - return_value = path_error(&src); - goto exit; - } + if (result) + return path_error2(src, dst); #endif - - Py_INCREF(Py_None); - return_value = Py_None; -exit: - path_cleanup(&src); - path_cleanup(&dst); - return return_value; + Py_RETURN_NONE; } -PyDoc_STRVAR(posix_rename__doc__, -"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\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."); + +/*[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 * -posix_rename(PyObject *self, PyObject *args, PyObject *kwargs) +os_rename_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, + int dst_dir_fd) +/*[clinic end generated code: output=08033bb2ec27fb5f input=faa61c847912c850]*/ { - return internal_rename(args, kwargs, 0); + return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0); } -PyDoc_STRVAR(posix_replace__doc__, -"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\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."); + +/*[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 * -posix_replace(PyObject *self, PyObject *args, PyObject *kwargs) +os_replace_impl(PyModuleDef *module, path_t *src, path_t *dst, + int src_dir_fd, int dst_dir_fd) +/*[clinic end generated code: output=131d012eed8d3b8b input=25515dfb107c8421]*/ { - return internal_rename(args, kwargs, 1); + return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1); } -PyDoc_STRVAR(posix_rmdir__doc__, -"rmdir(path, *, dir_fd=None)\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."); + +/*[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 * -posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs) +os_rmdir_impl(PyModuleDef *module, path_t *path, int dir_fd) +/*[clinic end generated code: output=cabadec80d5a77c7 input=38c8b375ca34a7e2]*/ { - path_t path; - int dir_fd = DEFAULT_DIR_FD; - static char *keywords[] = {"path", "dir_fd", NULL}; int result; - PyObject *return_value = NULL; - - memset(&path, 0, sizeof(path)); - path.function_name = "rmdir"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords, - path_converter, &path, -#ifdef HAVE_UNLINKAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS - if (path.wide) - result = RemoveDirectoryW(path.wide); + if (path->wide) + result = RemoveDirectoryW(path->wide); else - result = RemoveDirectoryA(path.narrow); + result = RemoveDirectoryA(path->narrow); result = !result; /* Windows, success=1, UNIX, success=0 */ #else #ifdef HAVE_UNLINKAT if (dir_fd != DEFAULT_DIR_FD) - result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR); + result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR); else #endif - result = rmdir(path.narrow); + result = rmdir(path->narrow); #endif Py_END_ALLOW_THREADS - if (result) { - return_value = path_error(&path); - goto exit; - } - - return_value = Py_None; - Py_INCREF(Py_None); + if (result) + return path_error(path); -exit: - path_cleanup(&path); - return return_value; + Py_RETURN_NONE; } #ifdef HAVE_SYSTEM -PyDoc_STRVAR(posix_system__doc__, -"system(command) -> exit_status\n\n\ -Execute the command (a string) in a subshell."); - -static PyObject * -posix_system(PyObject *self, PyObject *args) -{ - long sts; #ifdef MS_WINDOWS - wchar_t *command; - if (!PyArg_ParseTuple(args, "u:system", &command)) - return NULL; +/*[clinic input] +os.system -> long + + command: Py_UNICODE + +Execute the command in a subshell. +[clinic start generated code]*/ +static long +os_system_impl(PyModuleDef *module, Py_UNICODE *command) +/*[clinic end generated code: output=4c3bd5abcd9c29e7 input=303f5ce97df606b0]*/ +{ + long result; Py_BEGIN_ALLOW_THREADS - sts = _wsystem(command); + result = _wsystem(command); Py_END_ALLOW_THREADS -#else - PyObject *command_obj; - char *command; - if (!PyArg_ParseTuple(args, "O&:system", - PyUnicode_FSConverter, &command_obj)) - return NULL; + return result; +} +#else /* MS_WINDOWS */ +/*[clinic input] +os.system -> long + + command: FSConverter - command = PyBytes_AsString(command_obj); +Execute the command in a subshell. +[clinic start generated code]*/ + +static long +os_system_impl(PyModuleDef *module, PyObject *command) +/*[clinic end generated code: output=800f775e10b7be55 input=86a58554ba6094af]*/ +{ + long result; + char *bytes = PyBytes_AsString(command); Py_BEGIN_ALLOW_THREADS - sts = system(command); + result = system(bytes); Py_END_ALLOW_THREADS - Py_DECREF(command_obj); -#endif - return PyLong_FromLong(sts); + return result; } #endif +#endif /* HAVE_SYSTEM */ + +/*[clinic input] +os.umask + + mask: int + / -PyDoc_STRVAR(posix_umask__doc__, -"umask(new_mask) -> old_mask\n\n\ -Set the current numeric umask and return the previous umask."); +Set the current numeric umask and return the previous umask. +[clinic start generated code]*/ static PyObject * -posix_umask(PyObject *self, PyObject *args) +os_umask_impl(PyModuleDef *module, int mask) +/*[clinic end generated code: output=9e1fe3c9f14d6a05 input=ab6bfd9b24d8a7e8]*/ { - int i; - if (!PyArg_ParseTuple(args, "i:umask", &i)) - return NULL; - i = (int)umask(i); + int i = (int)umask(mask); if (i < 0) return posix_error(); return PyLong_FromLong((long)i); @@ -4489,7 +4335,10 @@ BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName) find_data_handle = FindFirstFileW(lpFileName, &find_data); if(find_data_handle != INVALID_HANDLE_VALUE) { - is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK; + /* 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); } } @@ -4502,81 +4351,73 @@ BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName) } #endif /* MS_WINDOWS */ -PyDoc_STRVAR(posix_unlink__doc__, -"unlink(path, *, dir_fd=None)\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."); -PyDoc_STRVAR(posix_remove__doc__, -"remove(path, *, dir_fd=None)\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."); +/*[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 * -posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs) +os_unlink_impl(PyModuleDef *module, path_t *path, int dir_fd) +/*[clinic end generated code: output=474afd5cd09b237e input=d7bcde2b1b2a2552]*/ { - path_t path; - int dir_fd = DEFAULT_DIR_FD; - static char *keywords[] = {"path", "dir_fd", NULL}; int result; - PyObject *return_value = NULL; - - memset(&path, 0, sizeof(path)); - path.function_name = "unlink"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords, - path_converter, &path, -#ifdef HAVE_UNLINKAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH #ifdef MS_WINDOWS - if (path.wide) - result = Py_DeleteFileW(path.wide); + if (path->wide) + result = Py_DeleteFileW(path->wide); else - result = DeleteFileA(path.narrow); + result = DeleteFileA(path->narrow); result = !result; /* Windows, success=1, UNIX, success=0 */ #else #ifdef HAVE_UNLINKAT if (dir_fd != DEFAULT_DIR_FD) - result = unlinkat(dir_fd, path.narrow, 0); + result = unlinkat(dir_fd, path->narrow, 0); else #endif /* HAVE_UNLINKAT */ - result = unlink(path.narrow); + result = unlink(path->narrow); #endif + _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS - if (result) { - return_value = path_error(&path); - goto exit; - } - - return_value = Py_None; - Py_INCREF(Py_None); + if (result) + return path_error(path); -exit: - path_cleanup(&path); - return return_value; + Py_RETURN_NONE; } -PyDoc_STRVAR(posix_uname__doc__, -"uname() -> uname_result\n\n\ -Return an object identifying the current operating system.\n\ -The object behaves like a named tuple with the following fields:\n\ - (sysname, nodename, release, version, machine)"); +/*[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(PyModuleDef *module, path_t *path, int dir_fd) +/*[clinic end generated code: output=d0d5149e64832b9e input=e05c5ab55cd30983]*/ +{ + return os_unlink_impl(module, path, dir_fd); +} + static PyStructSequence_Field uname_result_fields[] = { {"sysname", "operating system name"}, @@ -4606,8 +4447,19 @@ 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 * -posix_uname(PyObject *self, PyObject *noargs) +os_uname_impl(PyModuleDef *module) +/*[clinic end generated code: output=01e1421b757e753f input=e68bd246db3043ed]*/ { struct utsname u; int res; @@ -4646,31 +4498,6 @@ posix_uname(PyObject *self, PyObject *noargs) #endif /* HAVE_UNAME */ -PyDoc_STRVAR(posix_utime__doc__, -"utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\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 not None, 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 both times and ns are None, 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."); typedef struct { int now; @@ -4681,64 +4508,62 @@ typedef struct { } utime_t; /* - * these macros assume that "utime" is a pointer to a 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 (utime->now) \ + if (ut->now) \ time = NULL; \ else { \ - ts[0].tv_sec = utime->atime_s; \ - ts[0].tv_nsec = utime->atime_ns; \ - ts[1].tv_sec = utime->mtime_s; \ - ts[1].tv_nsec = utime->mtime_ns; \ + 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 (utime->now) \ + if (ut->now) \ time = NULL; \ else { \ - tv[0].tv_sec = utime->atime_s; \ - tv[0].tv_usec = utime->atime_ns / 1000; \ - tv[1].tv_sec = utime->mtime_s; \ - tv[1].tv_usec = utime->mtime_ns / 1000; \ + 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[2]; \ + struct utimbuf u; \ struct utimbuf *time; \ - if (utime->now) \ + if (ut->now) \ time = NULL; \ else { \ - u.actime = utime->atime_s; \ - u.modtime = utime->mtime_s; \ - time = u; \ + u.actime = ut->atime_s; \ + u.modtime = ut->mtime_s; \ + time = &u; \ } #define UTIME_TO_TIME_T \ time_t timet[2]; \ - struct timet time; \ - if (utime->now) \ + time_t *time; \ + if (ut->now) \ time = NULL; \ else { \ - timet[0] = utime->atime_s; \ - timet[1] = utime->mtime_s; \ - time = &timet; \ + timet[0] = ut->atime_s; \ + timet[1] = ut->mtime_s; \ + time = timet; \ } \ -#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)) - -#if UTIME_HAVE_DIR_FD +#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT) static int -utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks) +utime_dir_fd(utime_t *ut, int dir_fd, char *path, int follow_symlinks) { #ifdef HAVE_UTIMENSAT int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW; @@ -4756,14 +4581,15 @@ utime_dir_fd(utime_t *utime, int dir_fd, char *path, int follow_symlinks) #endif } + #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter +#else + #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable #endif -#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)) - -#if UTIME_HAVE_FD +#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS) static int -utime_fd(utime_t *utime, int fd) +utime_fd(utime_t *ut, int fd) { #ifdef HAVE_FUTIMENS UTIME_TO_TIMESPEC; @@ -4774,16 +4600,19 @@ utime_fd(utime_t *utime, int fd) #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 -#define UTIME_HAVE_NOFOLLOW_SYMLINKS \ - (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)) - -#if UTIME_HAVE_NOFOLLOW_SYMLINKS +#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS static int -utime_nofollow_symlinks(utime_t *utime, char *path) +utime_nofollow_symlinks(utime_t *ut, char *path) { #ifdef HAVE_UTIMENSAT UTIME_TO_TIMESPEC; @@ -4799,7 +4628,7 @@ utime_nofollow_symlinks(utime_t *utime, char *path) #ifndef MS_WINDOWS static int -utime_default(utime_t *utime, char *path) +utime_default(utime_t *ut, char *path) { #ifdef HAVE_UTIMENSAT UTIME_TO_TIMESPEC; @@ -4839,19 +4668,50 @@ split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns) return result; } -static PyObject * -posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; - PyObject *times = NULL; - PyObject *ns = NULL; - int dir_fd = DEFAULT_DIR_FD; - int follow_symlinks = 1; - char *keywords[] = {"path", "times", "ns", "dir_fd", - "follow_symlinks", NULL}; - utime_t utime; +/*[clinic input] +os.utime + + path: path_t(allow_fd='PATH_UTIME_HAVE_FD') + times: object = NULL + * + 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(PyModuleDef *module, path_t *path, PyObject *times, + PyObject *ns, int dir_fd, int follow_symlinks) +/*[clinic end generated code: output=31f3434e560ba2f0 input=081cdc54ca685385]*/ +{ #ifdef MS_WINDOWS HANDLE hFile; FILETIME atime, mtime; @@ -4860,25 +4720,9 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) #endif PyObject *return_value = NULL; + utime_t utime; - memset(&path, 0, sizeof(path)); - path.function_name = "utime"; memset(&utime, 0, sizeof(utime_t)); -#if UTIME_HAVE_FD - path.allow_fd = 1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "O&|O$OO&p:utime", keywords, - path_converter, &path, - ×, &ns, -#if UTIME_HAVE_DIR_FD - dir_fd_converter, &dir_fd, -#else - dir_fd_unavailable, &dir_fd, -#endif - &follow_symlinks - )) - return NULL; if (times && (times != Py_None) && ns) { PyErr_SetString(PyExc_ValueError, @@ -4898,9 +4742,9 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) } utime.now = 0; if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0), - &a_sec, &a_nsec) == -1 || + &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 || _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1), - &m_sec, &m_nsec) == -1) { + &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) { goto exit; } utime.atime_s = a_sec; @@ -4927,14 +4771,14 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) utime.now = 1; } -#if !UTIME_HAVE_NOFOLLOW_SYMLINKS +#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS) if (follow_symlinks_specified("utime", follow_symlinks)) goto exit; #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)) + 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)) goto exit; #if !defined(HAVE_UTIMENSAT) @@ -4948,17 +4792,17 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (path.wide) - hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0, + if (path->wide) + hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); else - hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0, + hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); Py_END_ALLOW_THREADS if (hFile == INVALID_HANDLE_VALUE) { - path_error(&path); + path_error(path); goto exit; } @@ -4967,8 +4811,8 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) atime = mtime; } else { - time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime); - time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime); + _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, @@ -4981,25 +4825,25 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) #else /* MS_WINDOWS */ Py_BEGIN_ALLOW_THREADS -#if UTIME_HAVE_NOFOLLOW_SYMLINKS +#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) - result = utime_nofollow_symlinks(&utime, path.narrow); + result = utime_nofollow_symlinks(&utime, path->narrow); else #endif -#if UTIME_HAVE_DIR_FD +#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); + result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks); else #endif -#if UTIME_HAVE_FD - if (path.fd != -1) - result = utime_fd(&utime, path.fd); +#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); + result = utime_default(&utime, path->narrow); Py_END_ALLOW_THREADS @@ -5015,7 +4859,6 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) return_value = Py_None; exit: - path_cleanup(&path); #ifdef MS_WINDOWS if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); @@ -5025,17 +4868,20 @@ posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) /* Process operations */ -PyDoc_STRVAR(posix__exit__doc__, -"_exit(status)\n\n\ -Exit to the system with specified status, without normal exit processing."); + +/*[clinic input] +os._exit + + status: int + +Exit to the system with specified status, without normal exit processing. +[clinic start generated code]*/ static PyObject * -posix__exit(PyObject *self, PyObject *args) +os__exit_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=472a3cbaf68f3621 input=5e6d57556b0c4a62]*/ { - int sts; - if (!PyArg_ParseTuple(args, "i:_exit", &sts)) - return NULL; - _exit(sts); + _exit(status); return NULL; /* Make gcc -Wall happy */ } @@ -5173,96 +5019,83 @@ parse_arglist(PyObject* argv, Py_ssize_t *argc) } #endif + #ifdef HAVE_EXECV -PyDoc_STRVAR(posix_execv__doc__, -"execv(path, args)\n\n\ -Execute an executable path with arguments, replacing current process.\n\ -\n\ - path: path of executable file\n\ - args: tuple or list of strings"); +/*[clinic input] +os.execv + + path: FSConverter + 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 * -posix_execv(PyObject *self, PyObject *args) +os_execv_impl(PyModuleDef *module, PyObject *path, PyObject *argv) +/*[clinic end generated code: output=9221f08143146fff input=96041559925e5229]*/ { - PyObject *opath; - char *path; - PyObject *argv; + char *path_char; char **argvlist; Py_ssize_t argc; /* execv has two arguments: (path, argv), where argv is a list or tuple of strings. */ - if (!PyArg_ParseTuple(args, "O&O:execv", - PyUnicode_FSConverter, - &opath, &argv)) - return NULL; - path = PyBytes_AsString(opath); + path_char = PyBytes_AsString(path); if (!PyList_Check(argv) && !PyTuple_Check(argv)) { PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list"); - Py_DECREF(opath); return NULL; } argc = PySequence_Size(argv); if (argc < 1) { PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty"); - Py_DECREF(opath); return NULL; } argvlist = parse_arglist(argv, &argc); if (argvlist == NULL) { - Py_DECREF(opath); return NULL; } - execv(path, argvlist); + execv(path_char, argvlist); /* If we get here it's definitely an error */ free_string_array(argvlist, argc); - Py_DECREF(opath); return posix_error(); } -PyDoc_STRVAR(posix_execve__doc__, -"execve(path, args, env)\n\n\ -Execute a path with arguments and environment, replacing current process.\n\ -\n\ - path: path of executable file\n\ - args: tuple or list of arguments\n\ - env: dictionary of strings mapping to strings\n\ -\n\ -On some platforms, you may specify an open file descriptor for path;\n\ - execve will execute the program the file descriptor is open to.\n\ - If this functionality is unavailable, using it raises NotImplementedError."); + +/*[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 * -posix_execve(PyObject *self, PyObject *args, PyObject *kwargs) +os_execve_impl(PyModuleDef *module, path_t *path, PyObject *argv, + PyObject *env) +/*[clinic end generated code: output=181884fcdb21508e input=626804fa092606d9]*/ { - path_t path; - PyObject *argv, *env; char **argvlist = NULL; char **envlist; Py_ssize_t argc, envc; - static char *keywords[] = {"path", "argv", "environment", NULL}; /* execve has three arguments: (path, argv, env), where argv is a list or tuple of strings and env is a dictionary like posix.environ. */ - memset(&path, 0, sizeof(path)); - path.function_name = "execve"; -#ifdef HAVE_FEXECVE - path.allow_fd = 1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords, - path_converter, &path, - &argv, &env - )) - return NULL; - if (!PyList_Check(argv) && !PyTuple_Check(argv)) { PyErr_SetString(PyExc_TypeError, "execve: argv must be a tuple or list"); @@ -5285,15 +5118,15 @@ posix_execve(PyObject *self, PyObject *args, PyObject *kwargs) goto fail; #ifdef HAVE_FEXECVE - if (path.fd > -1) - fexecve(path.fd, argvlist, envlist); + if (path->fd > -1) + fexecve(path->fd, argvlist, envlist); else #endif - execve(path.narrow, argvlist, envlist); + execve(path->narrow, argvlist, envlist); /* If we get here it's definitely an error */ - path_error(&path); + path_error(path); while (--envc >= 0) PyMem_DEL(envlist[envc]); @@ -5301,29 +5134,33 @@ posix_execve(PyObject *self, PyObject *args, PyObject *kwargs) fail: if (argvlist) free_string_array(argvlist, argc); - path_cleanup(&path); return NULL; } #endif /* HAVE_EXECV */ #ifdef HAVE_SPAWNV -PyDoc_STRVAR(posix_spawnv__doc__, -"spawnv(mode, path, args)\n\n\ -Execute the program 'path' in a new process.\n\ -\n\ - mode: mode of process creation\n\ - path: path of executable file\n\ - args: tuple or list of strings"); +/*[clinic input] +os.spawnv + + mode: int + Mode of process creation. + path: FSConverter + 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 * -posix_spawnv(PyObject *self, PyObject *args) +os_spawnv_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv) +/*[clinic end generated code: output=140a7945484c8cc5 input=042c91dfc1e6debc]*/ { - PyObject *opath; - char *path; - PyObject *argv; + char *path_char; char **argvlist; - int mode, i; + int i; Py_ssize_t argc; Py_intptr_t spawnval; PyObject *(*getitem)(PyObject *, Py_ssize_t); @@ -5331,11 +5168,7 @@ posix_spawnv(PyObject *self, PyObject *args) /* spawnv has three arguments: (mode, path, argv), where argv is a list or tuple of strings. */ - if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode, - PyUnicode_FSConverter, - &opath, &argv)) - return NULL; - path = PyBytes_AsString(opath); + path_char = PyBytes_AsString(path); if (PyList_Check(argv)) { argc = PyList_Size(argv); getitem = PyList_GetItem; @@ -5347,13 +5180,11 @@ posix_spawnv(PyObject *self, PyObject *args) else { PyErr_SetString(PyExc_TypeError, "spawnv() arg 2 must be a tuple or list"); - Py_DECREF(opath); return NULL; } argvlist = PyMem_NEW(char *, argc+1); if (argvlist == NULL) { - Py_DECREF(opath); return PyErr_NoMemory(); } for (i = 0; i < argc; i++) { @@ -5363,7 +5194,6 @@ posix_spawnv(PyObject *self, PyObject *args) PyErr_SetString( PyExc_TypeError, "spawnv() arg 2 must contain only strings"); - Py_DECREF(opath); return NULL; } } @@ -5373,11 +5203,10 @@ posix_spawnv(PyObject *self, PyObject *args) mode = _P_OVERLAY; Py_BEGIN_ALLOW_THREADS - spawnval = _spawnv(mode, path, argvlist); + spawnval = _spawnv(mode, path_char, argvlist); Py_END_ALLOW_THREADS free_string_array(argvlist, argc); - Py_DECREF(opath); if (spawnval == -1) return posix_error(); @@ -5386,25 +5215,31 @@ posix_spawnv(PyObject *self, PyObject *args) } -PyDoc_STRVAR(posix_spawnve__doc__, -"spawnve(mode, path, args, env)\n\n\ -Execute the program 'path' in a new process.\n\ -\n\ - mode: mode of process creation\n\ - path: path of executable file\n\ - args: tuple or list of arguments\n\ - env: dictionary of strings mapping to strings"); +/*[clinic input] +os.spawnve + + mode: int + Mode of process creation. + path: FSConverter + 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 * -posix_spawnve(PyObject *self, PyObject *args) +os_spawnve_impl(PyModuleDef *module, int mode, PyObject *path, + PyObject *argv, PyObject *env) +/*[clinic end generated code: output=e7f5f0703610531f input=02362fd937963f8f]*/ { - PyObject *opath; - char *path; - PyObject *argv, *env; + char *path_char; char **argvlist; char **envlist; PyObject *res = NULL; - int mode; Py_ssize_t argc, i, envc; Py_intptr_t spawnval; PyObject *(*getitem)(PyObject *, Py_ssize_t); @@ -5414,11 +5249,7 @@ posix_spawnve(PyObject *self, PyObject *args) argv is a list or tuple of strings and env is a dictionary like posix.environ. */ - if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode, - PyUnicode_FSConverter, - &opath, &argv, &env)) - return NULL; - path = PyBytes_AsString(opath); + path_char = PyBytes_AsString(path); if (PyList_Check(argv)) { argc = PyList_Size(argv); getitem = PyList_GetItem; @@ -5462,7 +5293,7 @@ posix_spawnve(PyObject *self, PyObject *args) mode = _P_OVERLAY; Py_BEGIN_ALLOW_THREADS - spawnval = _spawnve(mode, path, argvlist, envlist); + spawnval = _spawnve(mode, path_char, argvlist, envlist); Py_END_ALLOW_THREADS if (spawnval == -1) @@ -5476,7 +5307,6 @@ posix_spawnve(PyObject *self, PyObject *args) fail_1: free_string_array(argvlist, lastarg); fail_0: - Py_DECREF(opath); return res; } @@ -5484,14 +5314,17 @@ posix_spawnve(PyObject *self, PyObject *args) #ifdef HAVE_FORK1 -PyDoc_STRVAR(posix_fork1__doc__, -"fork1() -> pid\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."); +/*[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 * -posix_fork1(PyObject *self, PyObject *noargs) +os_fork1_impl(PyModuleDef *module) +/*[clinic end generated code: output=e27b4f66419c9dcf input=12db02167893926e]*/ { pid_t pid; int result = 0; @@ -5514,17 +5347,21 @@ posix_fork1(PyObject *self, PyObject *noargs) } return PyLong_FromPid(pid); } -#endif +#endif /* HAVE_FORK1 */ #ifdef HAVE_FORK -PyDoc_STRVAR(posix_fork__doc__, -"fork() -> pid\n\n\ -Fork a child process.\n\ -Return 0 to child process and PID of child to parent process."); +/*[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 * -posix_fork(PyObject *self, PyObject *noargs) +os_fork_impl(PyModuleDef *module) +/*[clinic end generated code: output=898b1ecd3498ba12 input=13c956413110eeaa]*/ { pid_t pid; int result = 0; @@ -5547,92 +5384,106 @@ posix_fork(PyObject *self, PyObject *noargs) } return PyLong_FromPid(pid); } -#endif +#endif /* HAVE_FORK */ -#ifdef HAVE_SCHED_H +#ifdef HAVE_SCHED_H #ifdef HAVE_SCHED_GET_PRIORITY_MAX +/*[clinic input] +os.sched_get_priority_max + + policy: int -PyDoc_STRVAR(posix_sched_get_priority_max__doc__, -"sched_get_priority_max(policy)\n\n\ -Get the maximum scheduling priority for *policy*."); +Get the maximum scheduling priority for policy. +[clinic start generated code]*/ static PyObject * -posix_sched_get_priority_max(PyObject *self, PyObject *args) +os_sched_get_priority_max_impl(PyModuleDef *module, int policy) +/*[clinic end generated code: output=a6a30fa5071f2d81 input=2097b7998eca6874]*/ { - int policy, max; + int max; - if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy)) - return NULL; max = sched_get_priority_max(policy); if (max < 0) return posix_error(); return PyLong_FromLong(max); } -PyDoc_STRVAR(posix_sched_get_priority_min__doc__, -"sched_get_priority_min(policy)\n\n\ -Get the minimum scheduling priority for *policy*."); + +/*[clinic input] +os.sched_get_priority_min + + policy: int + +Get the minimum scheduling priority for policy. +[clinic start generated code]*/ static PyObject * -posix_sched_get_priority_min(PyObject *self, PyObject *args) +os_sched_get_priority_min_impl(PyModuleDef *module, int policy) +/*[clinic end generated code: output=5ca3ed6bc43e9b20 input=21bc8fa0d70983bf]*/ { - int policy, min; - - if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy)) - return NULL; - min = sched_get_priority_min(policy); + 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. -PyDoc_STRVAR(posix_sched_getscheduler__doc__, -"sched_getscheduler(pid)\n\n\ -Get the scheduling policy for the process with a PID of *pid*.\n\ -Passing a PID of 0 returns the scheduling policy for the calling process."); +Passing 0 for pid returns the scheduling policy for the calling process. +[clinic start generated code]*/ static PyObject * -posix_sched_getscheduler(PyObject *self, PyObject *args) +os_sched_getscheduler_impl(PyModuleDef *module, pid_t pid) +/*[clinic end generated code: output=8cd63c15caf54fa9 input=5f14cfd1f189e1a0]*/ { - pid_t pid; int policy; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid)) - return NULL; policy = sched_getscheduler(pid); if (policy < 0) return posix_error(); return PyLong_FromLong(policy); } +#endif /* HAVE_SCHED_SETSCHEDULER */ -#endif #if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) +/*[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 * -sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority) +/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/ { - PyObject *res, *priority; - static char *kwlist[] = {"sched_priority", NULL}; + PyObject *res; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority)) - return NULL; res = PyStructSequence_New(type); if (!res) return NULL; - Py_INCREF(priority); - PyStructSequence_SET_ITEM(res, 0, priority); + Py_INCREF(sched_priority); + PyStructSequence_SET_ITEM(res, 0, sched_priority); return res; } -PyDoc_STRVAR(sched_param__doc__, -"sched_param(sched_priority): A scheduling parameter.\n\n\ -Current has only one field: sched_priority"); + +PyDoc_VAR(os_sched_param__doc__); static PyStructSequence_Field sched_param_fields[] = { {"sched_priority", "the scheduling priority"}, @@ -5641,7 +5492,7 @@ static PyStructSequence_Field sched_param_fields[] = { static PyStructSequence_Desc sched_param_desc = { "sched_param", /* name */ - sched_param__doc__, /* doc */ + os_sched_param__doc__, /* doc */ sched_param_fields, 1 }; @@ -5665,118 +5516,134 @@ convert_sched_param(PyObject *param, struct sched_param *res) res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int); return 1; } +#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */ -#endif #ifdef HAVE_SCHED_SETSCHEDULER +/*[clinic input] +os.sched_setscheduler -PyDoc_STRVAR(posix_sched_setscheduler__doc__, -"sched_setscheduler(pid, policy, param)\n\n\ -Set the scheduling policy, *policy*, for *pid*.\n\ -If *pid* is 0, the calling process is changed.\n\ -*param* is an instance of sched_param."); + pid: pid_t + policy: int + param: sched_param + / -static PyObject * -posix_sched_setscheduler(PyObject *self, PyObject *args) -{ - pid_t pid; - int policy; - struct sched_param param; +Set the scheduling policy for the process identified by pid. - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler", - &pid, &policy, &convert_sched_param, ¶m)) - return NULL; +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(PyModuleDef *module, pid_t pid, int policy, + struct sched_param *param) +/*[clinic end generated code: output=37053e5c528c35c9 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, ¶m) == -1) + if (sched_setscheduler(pid, policy, param) == -1) return posix_error(); Py_RETURN_NONE; } +#endif /* HAVE_SCHED_SETSCHEDULER*/ -#endif #ifdef HAVE_SCHED_SETPARAM +/*[clinic input] +os.sched_getparam + pid: pid_t + / -PyDoc_STRVAR(posix_sched_getparam__doc__, -"sched_getparam(pid) -> sched_param\n\n\ -Returns scheduling parameters for the process with *pid* as an instance of the\n\ -sched_param class. A PID of 0 means the calling process."); +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 * -posix_sched_getparam(PyObject *self, PyObject *args) +os_sched_getparam_impl(PyModuleDef *module, pid_t pid) +/*[clinic end generated code: output=f42c5bd2604ecd08 input=18a1ef9c2efae296]*/ { - pid_t pid; struct sched_param param; - PyObject *res, *priority; + PyObject *result; + PyObject *priority; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid)) - return NULL; if (sched_getparam(pid, ¶m)) return posix_error(); - res = PyStructSequence_New(&SchedParamType); - if (!res) + result = PyStructSequence_New(&SchedParamType); + if (!result) return NULL; priority = PyLong_FromLong(param.sched_priority); if (!priority) { - Py_DECREF(res); + Py_DECREF(result); return NULL; } - PyStructSequence_SET_ITEM(res, 0, priority); - return res; + PyStructSequence_SET_ITEM(result, 0, priority); + return result; } -PyDoc_STRVAR(posix_sched_setparam__doc__, -"sched_setparam(pid, param)\n\n\ -Set scheduling parameters for a process with PID *pid*.\n\ -A PID of 0 means the calling process."); + +/*[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 * -posix_sched_setparam(PyObject *self, PyObject *args) +os_sched_setparam_impl(PyModuleDef *module, pid_t pid, + struct sched_param *param) +/*[clinic end generated code: output=b7a3c589436cec9b input=6b8d6dfcecdc21bd]*/ { - pid_t pid; - struct sched_param param; - - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam", - &pid, &convert_sched_param, ¶m)) - return NULL; - if (sched_setparam(pid, ¶m)) + if (sched_setparam(pid, param)) return posix_error(); Py_RETURN_NONE; } +#endif /* HAVE_SCHED_SETPARAM */ -#endif #ifdef HAVE_SCHED_RR_GET_INTERVAL +/*[clinic input] +os.sched_rr_get_interval -> double + pid: pid_t + / -PyDoc_STRVAR(posix_sched_rr_get_interval__doc__, -"sched_rr_get_interval(pid) -> float\n\n\ -Return the round-robin quantum for the process with PID *pid* in seconds."); +Return the round-robin quantum for the process identified by pid, in seconds. -static PyObject * -posix_sched_rr_get_interval(PyObject *self, PyObject *args) +Value returned is a float. +[clinic start generated code]*/ + +static double +os_sched_rr_get_interval_impl(PyModuleDef *module, pid_t pid) +/*[clinic end generated code: output=7adc137a86dea581 input=2a973da15cca6fae]*/ { - pid_t pid; struct timespec interval; - - if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid)) - return NULL; - if (sched_rr_get_interval(pid, &interval)) - return posix_error(); - return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec); + if (sched_rr_get_interval(pid, &interval)) { + posix_error(); + return -1.0; + } + return (double)interval.tv_sec + 1e-9*interval.tv_nsec; } +#endif /* HAVE_SCHED_RR_GET_INTERVAL */ -#endif -PyDoc_STRVAR(posix_sched_yield__doc__, -"sched_yield()\n\n\ -Voluntarily relinquish the CPU."); +/*[clinic input] +os.sched_yield + +Voluntarily relinquish the CPU. +[clinic start generated code]*/ static PyObject * -posix_sched_yield(PyObject *self, PyObject *noargs) +os_sched_yield_impl(PyModuleDef *module) +/*[clinic end generated code: output=d7bd51869c4cb6a8 input=e54d6f98189391d4]*/ { if (sched_yield()) return posix_error(); @@ -5784,39 +5651,41 @@ posix_sched_yield(PyObject *self, PyObject *noargs) } #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; -PyDoc_STRVAR(posix_sched_setaffinity__doc__, -"sched_setaffinity(pid, cpu_set)\n\n\ -Set the affinity of the process with PID *pid* to *cpu_set*."); +/*[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 * -posix_sched_setaffinity(PyObject *self, PyObject *args) +os_sched_setaffinity_impl(PyModuleDef *module, pid_t pid, PyObject *mask) +/*[clinic end generated code: output=582bcbf40d3253a9 input=a0791a597c7085ba]*/ { - pid_t pid; int ncpus; size_t setsize; - cpu_set_t *mask = NULL; - PyObject *iterable, *iterator = NULL, *item; - - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity", - &pid, &iterable)) - return NULL; + cpu_set_t *cpu_set = NULL; + PyObject *iterator = NULL, *item; - iterator = PyObject_GetIter(iterable); + iterator = PyObject_GetIter(mask); if (iterator == NULL) return NULL; ncpus = NCPUS_START; setsize = CPU_ALLOC_SIZE(ncpus); - mask = CPU_ALLOC(ncpus); - if (mask == NULL) { + cpu_set = CPU_ALLOC(ncpus); + if (cpu_set == NULL) { PyErr_NoMemory(); goto error; } - CPU_ZERO_S(setsize, mask); + CPU_ZERO_S(setsize, cpu_set); while ((item = PyIter_Next(iterator))) { long cpu; @@ -5857,48 +5726,50 @@ posix_sched_setaffinity(PyObject *self, PyObject *args) } newsetsize = CPU_ALLOC_SIZE(newncpus); CPU_ZERO_S(newsetsize, newmask); - memcpy(newmask, mask, setsize); - CPU_FREE(mask); + memcpy(newmask, cpu_set, setsize); + CPU_FREE(cpu_set); setsize = newsetsize; - mask = newmask; + cpu_set = newmask; ncpus = newncpus; } - CPU_SET_S(cpu, setsize, mask); + CPU_SET_S(cpu, setsize, cpu_set); } Py_CLEAR(iterator); - if (sched_setaffinity(pid, setsize, mask)) { + if (sched_setaffinity(pid, setsize, cpu_set)) { posix_error(); goto error; } - CPU_FREE(mask); + CPU_FREE(cpu_set); Py_RETURN_NONE; error: - if (mask) - CPU_FREE(mask); + if (cpu_set) + CPU_FREE(cpu_set); Py_XDECREF(iterator); return NULL; } -PyDoc_STRVAR(posix_sched_getaffinity__doc__, -"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\ -Return the affinity of the process with PID *pid*.\n\ -The returned cpu_set will be of size *ncpus*."); + +/*[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 * -posix_sched_getaffinity(PyObject *self, PyObject *args) +os_sched_getaffinity_impl(PyModuleDef *module, pid_t pid) +/*[clinic end generated code: output=b431a8f310e369e7 input=983ce7cb4a565980]*/ { - pid_t pid; int cpu, ncpus, count; size_t setsize; cpu_set_t *mask = NULL; PyObject *res = NULL; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity", - &pid)) - return NULL; - ncpus = NCPUS_START; while (1) { setsize = CPU_ALLOC_SIZE(ncpus); @@ -5948,6 +5819,7 @@ posix_sched_getaffinity(PyObject *self, PyObject *args) #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) @@ -5974,13 +5846,20 @@ posix_sched_getaffinity(PyObject *self, PyObject *args) #endif #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */ + #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) -PyDoc_STRVAR(posix_openpty__doc__, -"openpty() -> (master_fd, slave_fd)\n\n\ -Open a pseudo-terminal, returning open fd's for both master and slave end.\n"); +/*[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 * -posix_openpty(PyObject *self, PyObject *noargs) +os_openpty_impl(PyModuleDef *module) +/*[clinic end generated code: output=358e571c1ba135ee input=f3d99fd99e762907]*/ { int master_fd = -1, slave_fd = -1; #ifndef HAVE_OPENPTY @@ -6011,7 +5890,7 @@ posix_openpty(PyObject *self, PyObject *noargs) slave_fd = _Py_open(slave_name, O_RDWR); if (slave_fd < 0) - goto posix_error; + goto error; #else master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */ @@ -6039,8 +5918,8 @@ posix_openpty(PyObject *self, PyObject *noargs) goto posix_error; slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */ - if (slave_fd < 0) - goto posix_error; + if (slave_fd == -1) + goto error; if (_Py_set_inheritable(master_fd, 0, NULL) < 0) goto posix_error; @@ -6058,9 +5937,7 @@ posix_openpty(PyObject *self, PyObject *noargs) posix_error: posix_error(); -#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) error: -#endif if (master_fd != -1) close(master_fd); if (slave_fd != -1) @@ -6069,15 +5946,22 @@ posix_openpty(PyObject *self, PyObject *noargs) } #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */ + #ifdef HAVE_FORKPTY -PyDoc_STRVAR(posix_forkpty__doc__, -"forkpty() -> (pid, master_fd)\n\n\ -Fork a new process with a new pseudo-terminal as controlling tty.\n\n\ -Like fork(), return 0 as pid to child process, and PID of child to parent.\n\ -To both, return fd of newly opened pseudo-terminal.\n"); +/*[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 * -posix_forkpty(PyObject *self, PyObject *noargs) +os_forkpty_impl(PyModuleDef *module) +/*[clinic end generated code: output=a11b8391dce3cb57 input=f1f7f4bae3966010]*/ { int master_fd = -1, result = 0; pid_t pid; @@ -6101,59 +5985,73 @@ posix_forkpty(PyObject *self, PyObject *noargs) } return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd); } -#endif +#endif /* HAVE_FORKPTY */ #ifdef HAVE_GETEGID -PyDoc_STRVAR(posix_getegid__doc__, -"getegid() -> egid\n\n\ -Return the current process's effective group id."); +/*[clinic input] +os.getegid + +Return the current process's effective group id. +[clinic start generated code]*/ static PyObject * -posix_getegid(PyObject *self, PyObject *noargs) +os_getegid_impl(PyModuleDef *module) +/*[clinic end generated code: output=90f433a8c0b1d919 input=1596f79ad1107d5d]*/ { return _PyLong_FromGid(getegid()); } -#endif +#endif /* HAVE_GETEGID */ #ifdef HAVE_GETEUID -PyDoc_STRVAR(posix_geteuid__doc__, -"geteuid() -> euid\n\n\ -Return the current process's effective user id."); +/*[clinic input] +os.geteuid + +Return the current process's effective user id. +[clinic start generated code]*/ static PyObject * -posix_geteuid(PyObject *self, PyObject *noargs) +os_geteuid_impl(PyModuleDef *module) +/*[clinic end generated code: output=1a532c4a66874357 input=4644c662d3bd9f19]*/ { return _PyLong_FromUid(geteuid()); } -#endif +#endif /* HAVE_GETEUID */ #ifdef HAVE_GETGID -PyDoc_STRVAR(posix_getgid__doc__, -"getgid() -> gid\n\n\ -Return the current process's group id."); +/*[clinic input] +os.getgid + +Return the current process's group id. +[clinic start generated code]*/ static PyObject * -posix_getgid(PyObject *self, PyObject *noargs) +os_getgid_impl(PyModuleDef *module) +/*[clinic end generated code: output=91a22021b74ea46b input=58796344cd87c0f6]*/ { return _PyLong_FromGid(getgid()); } -#endif +#endif /* HAVE_GETGID */ + +/*[clinic input] +os.getpid -PyDoc_STRVAR(posix_getpid__doc__, -"getpid() -> pid\n\n\ -Return the current process id"); +Return the current process id. +[clinic start generated code]*/ static PyObject * -posix_getpid(PyObject *self, PyObject *noargs) +os_getpid_impl(PyModuleDef *module) +/*[clinic end generated code: output=8fbf3a934ee09e62 input=5a9a00f0ab68aa00]*/ { return PyLong_FromPid(getpid()); } #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\ @@ -6190,9 +6088,9 @@ posix_getgrouplist(PyObject *self, PyObject *args) #endif #ifdef __APPLE__ - groups = PyMem_Malloc(ngroups * sizeof(int)); + groups = PyMem_New(int, ngroups); #else - groups = PyMem_Malloc(ngroups * sizeof(gid_t)); + groups = PyMem_New(gid_t, ngroups); #endif if (groups == NULL) return PyErr_NoMemory(); @@ -6226,15 +6124,19 @@ posix_getgrouplist(PyObject *self, PyObject *args) return list; } -#endif +#endif /* HAVE_GETGROUPLIST */ + #ifdef HAVE_GETGROUPS -PyDoc_STRVAR(posix_getgroups__doc__, -"getgroups() -> list of group IDs\n\n\ -Return list of supplemental group IDs for the process."); +/*[clinic input] +os.getgroups + +Return list of supplemental group IDs for the process. +[clinic start generated code]*/ static PyObject * -posix_getgroups(PyObject *self, PyObject *noargs) +os_getgroups_impl(PyModuleDef *module) +/*[clinic end generated code: output=6e7c4fd2db6d5c60 input=d3f109412e6a155c]*/ { PyObject *result = NULL; @@ -6270,7 +6172,7 @@ posix_getgroups(PyObject *self, PyObject *noargs) /* groups will fit in existing array */ alt_grouplist = grouplist; } else { - alt_grouplist = PyMem_Malloc(n * sizeof(gid_t)); + alt_grouplist = PyMem_New(gid_t, n); if (alt_grouplist == NULL) { errno = EINVAL; return posix_error(); @@ -6296,7 +6198,7 @@ posix_getgroups(PyObject *self, PyObject *noargs) /* Avoid malloc(0) */ alt_grouplist = grouplist; } else { - alt_grouplist = PyMem_Malloc(n * sizeof(gid_t)); + alt_grouplist = PyMem_New(gid_t, n); if (alt_grouplist == NULL) { errno = EINVAL; return posix_error(); @@ -6333,7 +6235,7 @@ posix_getgroups(PyObject *self, PyObject *noargs) return result; } -#endif +#endif /* HAVE_GETGROUPS */ #ifdef HAVE_INITGROUPS PyDoc_STRVAR(posix_initgroups__doc__, @@ -6342,6 +6244,7 @@ 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) { @@ -6374,20 +6277,23 @@ posix_initgroups(PyObject *self, PyObject *args) Py_INCREF(Py_None); return Py_None; } -#endif +#endif /* HAVE_INITGROUPS */ + #ifdef HAVE_GETPGID -PyDoc_STRVAR(posix_getpgid__doc__, -"getpgid(pid) -> pgid\n\n\ -Call the system call getpgid()."); +/*[clinic input] +os.getpgid + + pid: pid_t + +Call the system call getpgid(), and return the result. +[clinic start generated code]*/ static PyObject * -posix_getpgid(PyObject *self, PyObject *args) +os_getpgid_impl(PyModuleDef *module, pid_t pid) +/*[clinic end generated code: output=70e713b4d54b7c61 input=39d710ae3baaf1c7]*/ { - pid_t pid, pgid; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid)) - return NULL; - pgid = getpgid(pid); + pid_t pgid = getpgid(pid); if (pgid < 0) return posix_error(); return PyLong_FromPid(pgid); @@ -6396,12 +6302,15 @@ posix_getpgid(PyObject *self, PyObject *args) #ifdef HAVE_GETPGRP -PyDoc_STRVAR(posix_getpgrp__doc__, -"getpgrp() -> pgrp\n\n\ -Return the current process group id."); +/*[clinic input] +os.getpgrp + +Return the current process group id. +[clinic start generated code]*/ static PyObject * -posix_getpgrp(PyObject *self, PyObject *noargs) +os_getpgrp_impl(PyModuleDef *module) +/*[clinic end generated code: output=cf3403585846811f input=6846fb2bb9a3705e]*/ { #ifdef GETPGRP_HAVE_ARG return PyLong_FromPid(getpgrp(0)); @@ -6413,12 +6322,15 @@ posix_getpgrp(PyObject *self, PyObject *noargs) #ifdef HAVE_SETPGRP -PyDoc_STRVAR(posix_setpgrp__doc__, -"setpgrp()\n\n\ -Make this process the process group leader."); +/*[clinic input] +os.setpgrp + +Make the current process the leader of its process group. +[clinic start generated code]*/ static PyObject * -posix_setpgrp(PyObject *self, PyObject *noargs) +os_setpgrp_impl(PyModuleDef *module) +/*[clinic end generated code: output=59650f55a963d7ac input=1f0619fcb5731e7e]*/ { #ifdef SETPGRP_HAVE_ARG if (setpgrp(0, 0) < 0) @@ -6429,7 +6341,6 @@ posix_setpgrp(PyObject *self, PyObject *noargs) Py_INCREF(Py_None); return Py_None; } - #endif /* HAVE_SETPGRP */ #ifdef HAVE_GETPPID @@ -6476,14 +6387,19 @@ win32_getppid() } #endif /*MS_WINDOWS*/ -PyDoc_STRVAR(posix_getppid__doc__, -"getppid() -> ppid\n\n\ -Return the parent's process id. If the parent process has already exited,\n\ -Windows machines will still return its id; others systems will return the id\n\ -of the 'init' process (1)."); + +/*[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 * -posix_getppid(PyObject *self, PyObject *noargs) +os_getppid_impl(PyModuleDef *module) +/*[clinic end generated code: output=4e49c8e7a8738cd2 input=e637cb87539c030e]*/ { #ifdef MS_WINDOWS return win32_getppid(); @@ -6495,12 +6411,15 @@ posix_getppid(PyObject *self, PyObject *noargs) #ifdef HAVE_GETLOGIN -PyDoc_STRVAR(posix_getlogin__doc__, -"getlogin() -> string\n\n\ -Return the actual login name."); +/*[clinic input] +os.getlogin + +Return the actual login name. +[clinic start generated code]*/ static PyObject * -posix_getlogin(PyObject *self, PyObject *noargs) +os_getlogin_impl(PyModuleDef *module) +/*[clinic end generated code: output=037ebdb3e4b5dac1 input=2a21ab1e917163df]*/ { PyObject *result = NULL; #ifdef MS_WINDOWS @@ -6533,77 +6452,54 @@ posix_getlogin(PyObject *self, PyObject *noargs) } #endif /* HAVE_GETLOGIN */ + #ifdef HAVE_GETUID -PyDoc_STRVAR(posix_getuid__doc__, -"getuid() -> uid\n\n\ -Return the current process's user id."); +/*[clinic input] +os.getuid + +Return the current process's user id. +[clinic start generated code]*/ static PyObject * -posix_getuid(PyObject *self, PyObject *noargs) +os_getuid_impl(PyModuleDef *module) +/*[clinic end generated code: output=03a8b894cefb3fa5 input=b53c8b35f110a516]*/ { return _PyLong_FromUid(getuid()); } -#endif +#endif /* HAVE_GETUID */ +#ifdef MS_WINDOWS +#define HAVE_KILL +#endif /* MS_WINDOWS */ + #ifdef HAVE_KILL -PyDoc_STRVAR(posix_kill__doc__, -"kill(pid, sig)\n\n\ -Kill a process with a signal."); +/*[clinic input] +os.kill -static PyObject * -posix_kill(PyObject *self, PyObject *args) -{ - pid_t pid; - int sig; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig)) - return NULL; - if (kill(pid, sig) == -1) - return posix_error(); - Py_INCREF(Py_None); - return Py_None; -} -#endif + pid: pid_t + signal: Py_ssize_t + / -#ifdef HAVE_KILLPG -PyDoc_STRVAR(posix_killpg__doc__, -"killpg(pgid, sig)\n\n\ -Kill a process group with a signal."); +Kill a process with a signal. +[clinic start generated code]*/ static PyObject * -posix_killpg(PyObject *self, PyObject *args) +os_kill_impl(PyModuleDef *module, pid_t pid, Py_ssize_t signal) +/*[clinic end generated code: output=74f907dd00a83c26 input=61a36b86ca275ab9]*/ +#ifndef MS_WINDOWS { - int sig; - pid_t pgid; - /* 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 (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig)) - return NULL; - if (killpg(pgid, sig) == -1) + if (kill(pid, (int)signal) == -1) return posix_error(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -#endif - -#ifdef MS_WINDOWS -PyDoc_STRVAR(win32_kill__doc__, -"kill(pid, sig)\n\n\ -Kill a process with a signal."); - -static PyObject * -win32_kill(PyObject *self, PyObject *args) +#else /* !MS_WINDOWS */ { PyObject *result; - pid_t pid; - DWORD sig, err; + DWORD sig = (DWORD)signal; + DWORD err; HANDLE handle; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "k:kill", &pid, &sig)) - return NULL; - /* 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) { @@ -6634,103 +6530,138 @@ win32_kill(PyObject *self, PyObject *args) CloseHandle(handle); return result; } -#endif /* MS_WINDOWS */ +#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(PyModuleDef *module, pid_t pgid, int signal) +/*[clinic end generated code: output=3434a766ef945f93 input=38b5449eb8faec19]*/ +{ + /* 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_PLOCK #ifdef HAVE_SYS_LOCK_H #include #endif -PyDoc_STRVAR(posix_plock__doc__, -"plock(op)\n\n\ +/*[clinic input] +os.plock + op: int + / + Lock program segments into memory."); +[clinic start generated code]*/ static PyObject * -posix_plock(PyObject *self, PyObject *args) +os_plock_impl(PyModuleDef *module, int op) +/*[clinic end generated code: output=5cb851f81b914984 input=e6e5e348e1525f60]*/ { - int op; - if (!PyArg_ParseTuple(args, "i:plock", &op)) - return NULL; if (plock(op) == -1) return posix_error(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -#endif +#endif /* HAVE_PLOCK */ + #ifdef HAVE_SETUID -PyDoc_STRVAR(posix_setuid__doc__, -"setuid(uid)\n\n\ -Set the current process's user id."); +/*[clinic input] +os.setuid + + uid: uid_t + / + +Set the current process's user id. +[clinic start generated code]*/ static PyObject * -posix_setuid(PyObject *self, PyObject *args) +os_setuid_impl(PyModuleDef *module, uid_t uid) +/*[clinic end generated code: output=941ea9a8d1e5d565 input=c921a3285aa22256]*/ { - uid_t uid; - if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid)) - return NULL; if (setuid(uid) < 0) return posix_error(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } #endif /* HAVE_SETUID */ #ifdef HAVE_SETEUID -PyDoc_STRVAR(posix_seteuid__doc__, -"seteuid(uid)\n\n\ -Set the current process's effective user id."); +/*[clinic input] +os.seteuid + + euid: uid_t + / + +Set the current process's effective user id. +[clinic start generated code]*/ static PyObject * -posix_seteuid (PyObject *self, PyObject *args) +os_seteuid_impl(PyModuleDef *module, uid_t euid) +/*[clinic end generated code: output=66f4f6823a648d6d input=ba93d927e4781aa9]*/ { - uid_t euid; - if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid)) - return NULL; - if (seteuid(euid) < 0) { + if (seteuid(euid) < 0) return posix_error(); - } else { - Py_INCREF(Py_None); - return Py_None; - } + Py_RETURN_NONE; } #endif /* HAVE_SETEUID */ + #ifdef HAVE_SETEGID -PyDoc_STRVAR(posix_setegid__doc__, -"setegid(gid)\n\n\ -Set the current process's effective group id."); +/*[clinic input] +os.setegid + + egid: gid_t + / + +Set the current process's effective group id. +[clinic start generated code]*/ static PyObject * -posix_setegid (PyObject *self, PyObject *args) +os_setegid_impl(PyModuleDef *module, gid_t egid) +/*[clinic end generated code: output=ca094a69a081a60f input=4080526d0ccd6ce3]*/ { - gid_t egid; - if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid)) - return NULL; - if (setegid(egid) < 0) { + if (setegid(egid) < 0) return posix_error(); - } else { - Py_INCREF(Py_None); - return Py_None; - } + Py_RETURN_NONE; } #endif /* HAVE_SETEGID */ + #ifdef HAVE_SETREUID -PyDoc_STRVAR(posix_setreuid__doc__, -"setreuid(ruid, euid)\n\n\ -Set the current process's real and effective user ids."); +/*[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 * -posix_setreuid (PyObject *self, PyObject *args) +os_setreuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid) +/*[clinic end generated code: output=b2938c3e73d27ec7 input=0ca8978de663880c]*/ { - uid_t ruid, euid; - if (!PyArg_ParseTuple(args, "O&O&:setreuid", - _Py_Uid_Converter, &ruid, - _Py_Uid_Converter, &euid)) - return NULL; if (setreuid(ruid, euid) < 0) { return posix_error(); } else { @@ -6740,53 +6671,62 @@ posix_setreuid (PyObject *self, PyObject *args) } #endif /* HAVE_SETREUID */ + #ifdef HAVE_SETREGID -PyDoc_STRVAR(posix_setregid__doc__, -"setregid(rgid, egid)\n\n\ -Set the current process's real and effective group ids."); +/*[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 * -posix_setregid (PyObject *self, PyObject *args) +os_setregid_impl(PyModuleDef *module, gid_t rgid, gid_t egid) +/*[clinic end generated code: output=db18f1839ababe3d input=c59499f72846db78]*/ { - gid_t rgid, egid; - if (!PyArg_ParseTuple(args, "O&O&:setregid", - _Py_Gid_Converter, &rgid, - _Py_Gid_Converter, &egid)) - return NULL; - if (setregid(rgid, egid) < 0) { + if (setregid(rgid, egid) < 0) return posix_error(); - } else { - Py_INCREF(Py_None); - return Py_None; - } + Py_RETURN_NONE; } #endif /* HAVE_SETREGID */ + #ifdef HAVE_SETGID -PyDoc_STRVAR(posix_setgid__doc__, -"setgid(gid)\n\n\ -Set the current process's group id."); +/*[clinic input] +os.setgid + gid: gid_t + / + +Set the current process's group id. +[clinic start generated code]*/ static PyObject * -posix_setgid(PyObject *self, PyObject *args) +os_setgid_impl(PyModuleDef *module, gid_t gid) +/*[clinic end generated code: output=756cb42c6abd9d87 input=27d30c4059045dc6]*/ { - gid_t gid; - if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid)) - return NULL; if (setgid(gid) < 0) return posix_error(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } #endif /* HAVE_SETGID */ + #ifdef HAVE_SETGROUPS -PyDoc_STRVAR(posix_setgroups__doc__, -"setgroups(list)\n\n\ -Set the groups of the current process to list."); +/*[clinic input] +os.setgroups + + groups: object + / + +Set the groups of the current process to list. +[clinic start generated code]*/ static PyObject * -posix_setgroups(PyObject *self, PyObject *groups) +os_setgroups(PyModuleDef *module, PyObject *groups) +/*[clinic end generated code: output=7945c2e3cc817c58 input=fa742ca3daf85a7e]*/ { int i, len; gid_t grouplist[MAX_GROUPS]; @@ -6887,83 +6827,114 @@ wait_helper(pid_t pid, int status, struct rusage *ru) } #endif /* HAVE_WAIT3 || HAVE_WAIT4 */ + #ifdef HAVE_WAIT3 -PyDoc_STRVAR(posix_wait3__doc__, -"wait3(options) -> (pid, status, rusage)\n\n\ -Wait for completion of a child process."); +/*[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 * -posix_wait3(PyObject *self, PyObject *args) +os_wait3_impl(PyModuleDef *module, int options) +/*[clinic end generated code: output=e18af4924dc54945 input=8ac4c56956b61710]*/ { pid_t pid; - int options; struct rusage ru; + int async_err = 0; WAIT_TYPE status; WAIT_STATUS_INT(status) = 0; - if (!PyArg_ParseTuple(args, "i:wait3", &options)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - pid = wait3(&status, options, &ru); - Py_END_ALLOW_THREADS + 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 -PyDoc_STRVAR(posix_wait4__doc__, -"wait4(pid, options) -> (pid, status, rusage)\n\n\ -Wait for completion of a given child process."); +/*[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 * -posix_wait4(PyObject *self, PyObject *args) +os_wait4_impl(PyModuleDef *module, pid_t pid, int options) +/*[clinic end generated code: output=714f19e6ff01e099 input=d11deed0750600ba]*/ { - pid_t pid; - int options; + pid_t res; struct rusage ru; + int async_err = 0; WAIT_TYPE status; WAIT_STATUS_INT(status) = 0; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - pid = wait4(pid, &status, options, &ru); - Py_END_ALLOW_THREADS + 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(pid, WAIT_STATUS_INT(status), &ru); + return wait_helper(res, WAIT_STATUS_INT(status), &ru); } #endif /* HAVE_WAIT4 */ + #if defined(HAVE_WAITID) && !defined(__APPLE__) -PyDoc_STRVAR(posix_waitid__doc__, -"waitid(idtype, id, options) -> waitid_result\n\n\ -Wait for the completion of one or more child processes.\n\n\ -idtype can be P_PID, P_PGID or P_ALL.\n\ -id specifies the pid to wait on.\n\ -options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\ -or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\ -Returns either waitid_result or None if WNOHANG is specified and there are\n\ -no children in a waitable state."); +/*[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 * -posix_waitid(PyObject *self, PyObject *args) +os_waitid_impl(PyModuleDef *module, idtype_t idtype, id_t id, int options) +/*[clinic end generated code: output=5c0192750e22fa2e input=d8e7f76e052b7920]*/ { PyObject *result; - idtype_t idtype; - id_t id; - int options, res; + int res; + int async_err = 0; siginfo_t si; si.si_pid = 0; - if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = waitid(idtype, id, &si, options); - Py_END_ALLOW_THREADS - if (res == -1) - return posix_error(); + + 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; @@ -6984,79 +6955,111 @@ posix_waitid(PyObject *self, PyObject *args) return result; } -#endif +#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */ + -#ifdef HAVE_WAITPID -PyDoc_STRVAR(posix_waitpid__doc__, -"waitpid(pid, options) -> (pid, status)\n\n\ -Wait for completion of a given child process."); +#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 * -posix_waitpid(PyObject *self, PyObject *args) +os_waitpid_impl(PyModuleDef *module, pid_t pid, int options) +/*[clinic end generated code: output=5e3593353d54b15b input=0bf1666b8758fda3]*/ { - pid_t pid; - int options; + pid_t res; + int async_err = 0; WAIT_TYPE status; WAIT_STATUS_INT(status) = 0; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options)) - return NULL; - Py_BEGIN_ALLOW_THREADS - pid = waitpid(pid, &status, options); - Py_END_ALLOW_THREADS - if (pid == -1) - return posix_error(); + 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(pid), WAIT_STATUS_INT(status)); + 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. */ -PyDoc_STRVAR(posix_waitpid__doc__, -"waitpid(pid, options) -> (pid, status << 8)\n\n" -"Wait for completion of a given process. options is ignored on Windows."); +/*[clinic input] +os.waitpid + pid: Py_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 * -posix_waitpid(PyObject *self, PyObject *args) +os_waitpid_impl(PyModuleDef *module, Py_intptr_t pid, int options) +/*[clinic end generated code: output=fc1d520db019625f input=444c8f51cca5b862]*/ { - Py_intptr_t pid; - int status, options; + int status; + Py_intptr_t res; + int async_err = 0; - if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:waitpid", &pid, &options)) - return NULL; - Py_BEGIN_ALLOW_THREADS - pid = _cwait(&status, pid, options); - Py_END_ALLOW_THREADS - if (pid == -1) - return posix_error(); + do { + Py_BEGIN_ALLOW_THREADS + res = _cwait(&status, pid, options); + Py_END_ALLOW_THREADS + } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + if (res < 0) + return (!async_err) ? posix_error() : NULL; /* shift the status left a byte so this is more like the POSIX waitpid */ - return Py_BuildValue(_Py_PARSE_INTPTR "i", pid, status << 8); + return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8); } -#endif /* HAVE_WAITPID || HAVE_CWAIT */ +#endif + #ifdef HAVE_WAIT -PyDoc_STRVAR(posix_wait__doc__, -"wait() -> (pid, status)\n\n\ -Wait for completion of a child process."); +/*[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 * -posix_wait(PyObject *self, PyObject *noargs) +os_wait_impl(PyModuleDef *module) +/*[clinic end generated code: output=4a7f4978393e0654 input=03b0182d4a4700ce]*/ { pid_t pid; + int async_err = 0; WAIT_TYPE status; WAIT_STATUS_INT(status) = 0; - Py_BEGIN_ALLOW_THREADS - pid = wait(&status); - Py_END_ALLOW_THREADS - if (pid == -1) - return posix_error(); + 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 +#endif /* HAVE_WAIT */ #if defined(HAVE_READLINK) || defined(MS_WINDOWS) @@ -7072,6 +7075,7 @@ dir_fd may not be implemented on your platform.\n\ #ifdef HAVE_READLINK +/* AC 3.5: merge win32 and not together */ static PyObject * posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs) { @@ -7086,12 +7090,7 @@ posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs) path.function_name = "readlink"; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords, path_converter, &path, -#ifdef HAVE_READLINKAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) + READLINKAT_DIR_FD_CONVERTER, &dir_fd)) return NULL; Py_BEGIN_ALLOW_THREADS @@ -7117,23 +7116,86 @@ posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs) return return_value; } - #endif /* HAVE_READLINK */ +#if !defined(HAVE_READLINK) && defined(MS_WINDOWS) + +static PyObject * +win_readlink(PyObject *self, PyObject *args, PyObject *kwargs) +{ + wchar_t *path; + DWORD n_bytes_returned; + DWORD io_result; + PyObject *po, *result; + int dir_fd; + HANDLE reparse_point_handle; + + char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; + REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer; + wchar_t *print_name; + + static char *keywords[] = {"path", "dir_fd", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords, + &po, + dir_fd_unavailable, &dir_fd + )) + return NULL; + + path = PyUnicode_AsUnicode(po); + if (path == NULL) + return NULL; + + /* First get a handle to the reparse point */ + Py_BEGIN_ALLOW_THREADS + reparse_point_handle = CreateFileW( + path, + 0, + 0, + 0, + OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, + 0); + Py_END_ALLOW_THREADS + + if (reparse_point_handle==INVALID_HANDLE_VALUE) + return win32_error_object("readlink", po); + + Py_BEGIN_ALLOW_THREADS + /* 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 win32_error_object("readlink", po); + + if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK) + { + PyErr_SetString(PyExc_ValueError, + "not a symbolic link"); + return NULL; + } + print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer + + rdb->SymbolicLinkReparseBuffer.PrintNameOffset; + + result = PyUnicode_FromWideChar(print_name, + rdb->SymbolicLinkReparseBuffer.PrintNameLength/2); + return result; +} + +#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */ + + #ifdef HAVE_SYMLINK -PyDoc_STRVAR(posix_symlink__doc__, -"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\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."); #if defined(MS_WINDOWS) @@ -7279,189 +7341,102 @@ _check_dirA(char *src, char *dest) && 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 * -posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs) +os_symlink_impl(PyModuleDef *module, path_t *src, path_t *dst, + int target_is_directory, int dir_fd) +/*[clinic end generated code: output=a01b4bcf32403ccd input=e820ec4472547bc3]*/ { - path_t src; - path_t dst; - int dir_fd = DEFAULT_DIR_FD; - int target_is_directory = 0; - static char *keywords[] = {"src", "dst", "target_is_directory", - "dir_fd", NULL}; - PyObject *return_value; #ifdef MS_WINDOWS DWORD result; #else int result; #endif - memset(&src, 0, sizeof(src)); - src.function_name = "symlink"; - src.argument_name = "src"; - memset(&dst, 0, sizeof(dst)); - dst.function_name = "symlink"; - dst.argument_name = "dst"; - #ifdef MS_WINDOWS if (!check_CreateSymbolicLink()) { PyErr_SetString(PyExc_NotImplementedError, "CreateSymbolicLink functions not found"); - return NULL; + return NULL; } if (!win32_can_symlink) { PyErr_SetString(PyExc_OSError, "symbolic link privilege not held"); - return NULL; + return NULL; } #endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink", - keywords, - path_converter, &src, - path_converter, &dst, - &target_is_directory, -#ifdef HAVE_SYMLINKAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; - - if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) { + if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) { PyErr_SetString(PyExc_ValueError, "symlink: src and dst must be the same type"); - return_value = NULL; - goto exit; + return NULL; } #ifdef MS_WINDOWS Py_BEGIN_ALLOW_THREADS - if (dst.wide) { + if (dst->wide) { /* if src is a directory, ensure target_is_directory==1 */ - target_is_directory |= _check_dirW(src.wide, dst.wide); - result = Py_CreateSymbolicLinkW(dst.wide, src.wide, + target_is_directory |= _check_dirW(src->wide, dst->wide); + result = Py_CreateSymbolicLinkW(dst->wide, src->wide, target_is_directory); } else { /* if src is a directory, ensure target_is_directory==1 */ - target_is_directory |= _check_dirA(src.narrow, dst.narrow); - result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow, + target_is_directory |= _check_dirA(src->narrow, dst->narrow); + result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow, target_is_directory); } Py_END_ALLOW_THREADS - if (!result) { - return_value = path_error(&src); - goto exit; - } + if (!result) + return path_error2(src, dst); #else Py_BEGIN_ALLOW_THREADS #if HAVE_SYMLINKAT if (dir_fd != DEFAULT_DIR_FD) - result = symlinkat(src.narrow, dir_fd, dst.narrow); + result = symlinkat(src->narrow, dir_fd, dst->narrow); else #endif - result = symlink(src.narrow, dst.narrow); + result = symlink(src->narrow, dst->narrow); Py_END_ALLOW_THREADS - if (result) { - return_value = path_error(&src); - goto exit; - } + if (result) + return path_error2(src, dst); #endif - return_value = Py_None; - Py_INCREF(Py_None); - goto exit; /* silence "unused label" warning */ -exit: - path_cleanup(&src); - path_cleanup(&dst); - return return_value; + Py_RETURN_NONE; } - #endif /* HAVE_SYMLINK */ -#if !defined(HAVE_READLINK) && defined(MS_WINDOWS) - -static PyObject * -win_readlink(PyObject *self, PyObject *args, PyObject *kwargs) -{ - wchar_t *path; - DWORD n_bytes_returned; - DWORD io_result; - PyObject *po, *result; - int dir_fd; - HANDLE reparse_point_handle; - - char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; - REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer; - wchar_t *print_name; - - static char *keywords[] = {"path", "dir_fd", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords, - &po, - dir_fd_unavailable, &dir_fd - )) - return NULL; - - path = PyUnicode_AsUnicode(po); - if (path == NULL) - return NULL; - - /* First get a handle to the reparse point */ - Py_BEGIN_ALLOW_THREADS - reparse_point_handle = CreateFileW( - path, - 0, - 0, - 0, - OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, - 0); - Py_END_ALLOW_THREADS - - if (reparse_point_handle==INVALID_HANDLE_VALUE) - return win32_error_object("readlink", po); - - Py_BEGIN_ALLOW_THREADS - /* 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 win32_error_object("readlink", po); - - if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK) - { - PyErr_SetString(PyExc_ValueError, - "not a symbolic link"); - return NULL; - } - print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer + - rdb->SymbolicLinkReparseBuffer.PrintNameOffset; - - result = PyUnicode_FromWideChar(print_name, - rdb->SymbolicLinkReparseBuffer.PrintNameLength/2); - return result; -} - -#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */ static PyStructSequence_Field times_result_fields[] = { @@ -7527,15 +7502,26 @@ build_times_result(double user, double system, return value; } -PyDoc_STRVAR(posix_times__doc__, -"times() -> times_result\n\n\ -Return an object containing floating point numbers indicating process\n\ -times. The object behaves like a named tuple with these fields:\n\ - (utime, stime, cutime, cstime, elapsed_time)"); -#if defined(MS_WINDOWS) +#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 * -posix_times(PyObject *self, PyObject *noargs) +os_times_impl(PyModuleDef *module) +/*[clinic end generated code: output=df0a63ebe6e6f091 input=2bf9df3d6ab2e48b]*/ +#ifdef MS_WINDOWS { FILETIME create, exit, kernel, user; HANDLE hProc; @@ -7555,12 +7541,10 @@ posix_times(PyObject *self, PyObject *noargs) (double)0, (double)0); } -#else /* Not Windows */ -#define NEED_TICKS_PER_SECOND -static long ticks_per_second = -1; -static PyObject * -posix_times(PyObject *self, PyObject *noargs) +#else /* MS_WINDOWS */ { + + struct tms t; clock_t c; errno = 0; @@ -7574,23 +7558,25 @@ posix_times(PyObject *self, PyObject *noargs) (double)t.tms_cstime / ticks_per_second, (double)c / ticks_per_second); } -#endif - +#endif /* MS_WINDOWS */ #endif /* HAVE_TIMES */ #ifdef HAVE_GETSID -PyDoc_STRVAR(posix_getsid__doc__, -"getsid(pid) -> sid\n\n\ -Call the system call getsid()."); +/*[clinic input] +os.getsid + + pid: pid_t + / + +Call the system call getsid(pid) and return the result. +[clinic start generated code]*/ static PyObject * -posix_getsid(PyObject *self, PyObject *args) +os_getsid_impl(PyModuleDef *module, pid_t pid) +/*[clinic end generated code: output=a074f80c0e6bfb38 input=eeb2b923a30ce04e]*/ { - pid_t pid; int sid; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid)) - return NULL; sid = getsid(pid); if (sid < 0) return posix_error(); @@ -7600,53 +7586,60 @@ posix_getsid(PyObject *self, PyObject *args) #ifdef HAVE_SETSID -PyDoc_STRVAR(posix_setsid__doc__, -"setsid()\n\n\ -Call the system call setsid()."); +/*[clinic input] +os.setsid + +Call the system call setsid(). +[clinic start generated code]*/ static PyObject * -posix_setsid(PyObject *self, PyObject *noargs) +os_setsid_impl(PyModuleDef *module) +/*[clinic end generated code: output=398fc152ae327330 input=5fff45858e2f0776]*/ { if (setsid() < 0) return posix_error(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } #endif /* HAVE_SETSID */ + #ifdef HAVE_SETPGID -PyDoc_STRVAR(posix_setpgid__doc__, -"setpgid(pid, pgrp)\n\n\ -Call the system call setpgid()."); +/*[clinic input] +os.setpgid + + pid: pid_t + pgrp: pid_t + / + +Call the system call setpgid(pid, pgrp). +[clinic start generated code]*/ static PyObject * -posix_setpgid(PyObject *self, PyObject *args) +os_setpgid_impl(PyModuleDef *module, pid_t pid, pid_t pgrp) +/*[clinic end generated code: output=7079a8e932912841 input=fceb395eca572e1a]*/ { - pid_t pid; - int pgrp; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp)) - return NULL; if (setpgid(pid, pgrp) < 0) return posix_error(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } #endif /* HAVE_SETPGID */ #ifdef HAVE_TCGETPGRP -PyDoc_STRVAR(posix_tcgetpgrp__doc__, -"tcgetpgrp(fd) -> pgid\n\n\ -Return the process group associated with the terminal given by a fd."); +/*[clinic input] +os.tcgetpgrp + + fd: int + / + +Return the process group associated with the terminal specified by fd. +[clinic start generated code]*/ static PyObject * -posix_tcgetpgrp(PyObject *self, PyObject *args) +os_tcgetpgrp_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=ebb6dc5f111c7dc0 input=7f6c18eac10ada86]*/ { - int fd; - pid_t pgid; - if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd)) - return NULL; - pgid = tcgetpgrp(fd); + pid_t pgid = tcgetpgrp(fd); if (pgid < 0) return posix_error(); return PyLong_FromPid(pgid); @@ -7655,21 +7648,23 @@ posix_tcgetpgrp(PyObject *self, PyObject *args) #ifdef HAVE_TCSETPGRP -PyDoc_STRVAR(posix_tcsetpgrp__doc__, -"tcsetpgrp(fd, pgid)\n\n\ -Set the process group associated with the terminal given by a fd."); +/*[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 * -posix_tcsetpgrp(PyObject *self, PyObject *args) +os_tcsetpgrp_impl(PyModuleDef *module, int fd, pid_t pgid) +/*[clinic end generated code: output=3e4b05177462cd22 input=5bdc997c6a619020]*/ { - int fd; - pid_t pgid; - if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid)) - return NULL; if (tcsetpgrp(fd, pgid) < 0) return posix_error(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } #endif /* HAVE_TCSETPGRP */ @@ -7679,154 +7674,166 @@ posix_tcsetpgrp(PyObject *self, PyObject *args) extern int _Py_open_cloexec_works; #endif -PyDoc_STRVAR(posix_open__doc__, -"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\ -Open a file for low level IO. Returns a file handle (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."); -static PyObject * -posix_open(PyObject *self, PyObject *args, PyObject *kwargs) +/*[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(PyModuleDef *module, path_t *path, int flags, int mode, + int dir_fd) +/*[clinic end generated code: output=47e8cc63559f5ddd input=ad8623b29acd2934]*/ { - path_t path; - int flags; - int mode = 0777; - int dir_fd = DEFAULT_DIR_FD; int fd; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL}; + 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 - memset(&path, 0, sizeof(path)); - path.function_name = "open"; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords, - path_converter, &path, - &flags, &mode, -#ifdef HAVE_OPENAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd -#endif - )) - return NULL; - #ifdef MS_WINDOWS flags |= O_NOINHERIT; #elif defined(O_CLOEXEC) flags |= O_CLOEXEC; #endif - Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + do { + Py_BEGIN_ALLOW_THREADS #ifdef MS_WINDOWS - if (path.wide) - fd = _wopen(path.wide, flags, mode); - else + if (path->wide) + fd = _wopen(path->wide, flags, mode); + else #endif #ifdef HAVE_OPENAT - if (dir_fd != DEFAULT_DIR_FD) - fd = openat(dir_fd, path.narrow, flags, mode); - else + if (dir_fd != DEFAULT_DIR_FD) + fd = openat(dir_fd, path->narrow, flags, mode); + else #endif - fd = open(path.narrow, flags, mode); - Py_END_ALLOW_THREADS + fd = open(path->narrow, flags, mode); + Py_END_ALLOW_THREADS + } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + _Py_END_SUPPRESS_IPH - if (fd == -1) { - PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object); - goto exit; + 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); - goto exit; + return -1; } #endif - return_value = PyLong_FromLong((long)fd); - -exit: - path_cleanup(&path); - return return_value; + return fd; } -PyDoc_STRVAR(posix_close__doc__, -"close(fd)\n\n\ -Close a file descriptor (for low level IO)."); + +/*[clinic input] +os.close + + fd: int + +Close a file descriptor. +[clinic start generated code]*/ static PyObject * -posix_close(PyObject *self, PyObject *args) +os_close_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=47bf2ea536445a26 input=2bc42451ca5c3223]*/ { - int fd, res; - if (!PyArg_ParseTuple(args, "i:close", &fd)) - return NULL; + int res; if (!_PyVerify_fd(fd)) return posix_error(); + /* 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_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(posix_closerange__doc__, -"closerange(fd_low, fd_high)\n\n\ -Closes all file descriptors in [fd_low, fd_high), ignoring errors."); +/*[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 * -posix_closerange(PyObject *self, PyObject *args) +os_closerange_impl(PyModuleDef *module, int fd_low, int fd_high) +/*[clinic end generated code: output=70e6adb95220ba96 input=5855a3d053ebd4ec]*/ { - int fd_from, fd_to, i; - if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to)) - return NULL; + int i; Py_BEGIN_ALLOW_THREADS - for (i = fd_from; i < fd_to; i++) + _Py_BEGIN_SUPPRESS_IPH + for (i = fd_low; i < fd_high; i++) if (_PyVerify_fd(i)) close(i); + _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS Py_RETURN_NONE; } -PyDoc_STRVAR(posix_dup__doc__, -"dup(fd) -> fd2\n\n\ -Return a duplicate of a file descriptor."); - -static PyObject * -posix_dup(PyObject *self, PyObject *args) -{ - int fd; +/*[clinic input] +os.dup -> int - if (!PyArg_ParseTuple(args, "i:dup", &fd)) - return NULL; + fd: int + / - fd = _Py_dup(fd); - if (fd == -1) - return NULL; +Return a duplicate of a file descriptor. +[clinic start generated code]*/ - return PyLong_FromLong((long)fd); +static int +os_dup_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=f4bbac8c7652d05e input=6f10f7ea97f7852a]*/ +{ + return _Py_dup(fd); } -PyDoc_STRVAR(posix_dup2__doc__, -"dup2(old_fd, new_fd)\n\n\ -Duplicate file descriptor."); +/*[clinic input] +os.dup2 + fd: int + fd2: int + inheritable: bool=True + +Duplicate file descriptor. +[clinic start generated code]*/ static PyObject * -posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs) +os_dup2_impl(PyModuleDef *module, int fd, int fd2, int inheritable) +/*[clinic end generated code: output=9a099d95881a7923 input=76e96f511be0352f]*/ { - static char *keywords[] = {"fd", "fd2", "inheritable", NULL}; - int fd, fd2; - int inheritable = 1; int res; #if defined(HAVE_DUP3) && \ !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)) @@ -7834,16 +7841,18 @@ posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs) int dup3_works = -1; #endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:dup2", keywords, - &fd, &fd2, &inheritable)) - return NULL; - if (!_PyVerify_fd_dup2(fd, fd2)) return posix_error(); + /* 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) return posix_error(); @@ -7898,30 +7907,34 @@ posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs) #endif - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } + #ifdef HAVE_LOCKF -PyDoc_STRVAR(posix_lockf__doc__, -"lockf(fd, cmd, len)\n\n\ -Apply, test or remove a POSIX lock on an open file descriptor.\n\n\ -fd is an open file descriptor.\n\ -cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\ -F_TEST.\n\ -len specifies the section of the file to lock."); +/*[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 * -posix_lockf(PyObject *self, PyObject *args) +os_lockf_impl(PyModuleDef *module, int fd, int command, Py_off_t length) +/*[clinic end generated code: output=25ff778f9e2fbf1b input=65da41d2106e9b79]*/ { - int fd, cmd, res; - off_t len; - if (!PyArg_ParseTuple(args, "iiO&:lockf", - &fd, &cmd, _parse_off_t, &len)) - return NULL; + int res; Py_BEGIN_ALLOW_THREADS - res = lockf(fd, cmd, len); + res = lockf(fd, command, length); Py_END_ALLOW_THREADS if (res < 0) @@ -7929,95 +7942,105 @@ posix_lockf(PyObject *self, PyObject *args) Py_RETURN_NONE; } -#endif +#endif /* HAVE_LOCKF */ -PyDoc_STRVAR(posix_lseek__doc__, -"lseek(fd, pos, how) -> newpos\n\n\ -Set the current position of a file descriptor.\n\ -Return the new cursor position in bytes, starting from the beginning."); +/*[clinic input] +os.lseek -> Py_off_t -static PyObject * -posix_lseek(PyObject *self, PyObject *args) + 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(PyModuleDef *module, int fd, Py_off_t position, int how) +/*[clinic end generated code: output=65d4ab96d664998c input=902654ad3f96a6d3]*/ { - int fd, how; -#ifdef MS_WINDOWS - PY_LONG_LONG pos, res; -#else - off_t pos, res; -#endif - PyObject *posobj; - if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how)) - return NULL; + Py_off_t result; + + if (!_PyVerify_fd(fd)) { + posix_error(); + return -1; + } #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; + case 0: how = SEEK_SET; break; + case 1: how = SEEK_CUR; break; + case 2: how = SEEK_END; break; } #endif /* SEEK_END */ -#if !defined(HAVE_LARGEFILE_SUPPORT) - pos = PyLong_AsLong(posobj); -#else - pos = PyLong_AsLongLong(posobj); -#endif if (PyErr_Occurred()) - return NULL; + return -1; - if (!_PyVerify_fd(fd)) - return posix_error(); + if (!_PyVerify_fd(fd)) { + posix_error(); + return -1; + } Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH #ifdef MS_WINDOWS - res = _lseeki64(fd, pos, how); + result = _lseeki64(fd, position, how); #else - res = lseek(fd, pos, how); + result = lseek(fd, position, how); #endif + _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS - if (res < 0) - return posix_error(); + if (result < 0) + posix_error(); -#if !defined(HAVE_LARGEFILE_SUPPORT) - return PyLong_FromLong(res); -#else - return PyLong_FromLongLong(res); -#endif + return result; } -PyDoc_STRVAR(posix_read__doc__, -"read(fd, buffersize) -> bytes\n\n\ -Read a file descriptor."); +/*[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 * -posix_read(PyObject *self, PyObject *args) +os_read_impl(PyModuleDef *module, int fd, Py_ssize_t length) +/*[clinic end generated code: output=be24f44178455e8b input=1df2eaa27c0bf1d3]*/ { - int fd, size; Py_ssize_t n; PyObject *buffer; - if (!PyArg_ParseTuple(args, "ii:read", &fd, &size)) - return NULL; - if (size < 0) { + + if (length < 0) { errno = EINVAL; return posix_error(); } - buffer = PyBytes_FromStringAndSize((char *)NULL, size); + +#ifdef MS_WINDOWS + /* On Windows, the count parameter of read() is an int */ + if (length > INT_MAX) + length = INT_MAX; +#endif + + buffer = PyBytes_FromStringAndSize((char *)NULL, length); if (buffer == NULL) return NULL; - if (!_PyVerify_fd(fd)) { - Py_DECREF(buffer); - return posix_error(); - } - Py_BEGIN_ALLOW_THREADS - n = read(fd, PyBytes_AS_STRING(buffer), size); - Py_END_ALLOW_THREADS - if (n < 0) { + + n = _Py_read(fd, PyBytes_AS_STRING(buffer), length); + if (n == -1) { Py_DECREF(buffer); - return posix_error(); + return NULL; } - if (n != size) + + if (n != length) _PyBytes_Resize(&buffer, n); + return buffer; } @@ -8032,14 +8055,14 @@ iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type) *iov = PyMem_New(struct iovec, cnt); if (*iov == NULL) { PyErr_NoMemory(); - return total; + return -1; } *buf = PyMem_New(Py_buffer, cnt); if (*buf == NULL) { PyMem_Del(*iov); PyErr_NoMemory(); - return total; + return -1; } for (i = 0; i < cnt; i++) { @@ -8064,7 +8087,7 @@ iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type) PyBuffer_Release(&(*buf)[j]); } PyMem_Del(*buf); - return 0; + return -1; } static void @@ -8079,128 +8102,151 @@ iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt) } #endif + #ifdef HAVE_READV -PyDoc_STRVAR(posix_readv__doc__, -"readv(fd, buffers) -> bytesread\n\n\ -Read from a file descriptor into a number of writable buffers. buffers\n\ -is an arbitrary sequence of writable buffers.\n\ -Returns the total number of bytes read."); +/*[clinic input] +os.readv -> Py_ssize_t -static PyObject * -posix_readv(PyObject *self, PyObject *args) + 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(PyModuleDef *module, int fd, PyObject *buffers) +/*[clinic end generated code: output=00fc56ff1800059f input=e679eb5dbfa0357d]*/ { - int fd, cnt; + int cnt; Py_ssize_t n; - PyObject *seq; + int async_err = 0; struct iovec *iov; Py_buffer *buf; - if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq)) - return NULL; - if (!PySequence_Check(seq)) { + if (!PySequence_Check(buffers)) { PyErr_SetString(PyExc_TypeError, "readv() arg 2 must be a sequence"); - return NULL; + return -1; } - cnt = PySequence_Size(seq); - if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE)) - return NULL; + cnt = PySequence_Size(buffers); - Py_BEGIN_ALLOW_THREADS - n = readv(fd, iov, cnt); - Py_END_ALLOW_THREADS + 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); - return PyLong_FromSsize_t(n); + if (n < 0) { + if (!async_err) + posix_error(); + return -1; + } + + return n; } -#endif +#endif /* HAVE_READV */ + #ifdef HAVE_PREAD -PyDoc_STRVAR(posix_pread__doc__, -"pread(fd, buffersize, offset) -> string\n\n\ -Read from a file descriptor, fd, at a position of offset. It will read up\n\ -to buffersize number of bytes. The file offset remains unchanged."); +/*[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 * -posix_pread(PyObject *self, PyObject *args) +os_pread_impl(PyModuleDef *module, int fd, int length, Py_off_t offset) +/*[clinic end generated code: output=90d1fed87f68fa33 input=084948dcbaa35d4c]*/ { - int fd, size; - off_t offset; Py_ssize_t n; + int async_err = 0; PyObject *buffer; - if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset)) - return NULL; - if (size < 0) { + if (length < 0) { errno = EINVAL; return posix_error(); } - buffer = PyBytes_FromStringAndSize((char *)NULL, size); + buffer = PyBytes_FromStringAndSize((char *)NULL, length); if (buffer == NULL) return NULL; if (!_PyVerify_fd(fd)) { Py_DECREF(buffer); return posix_error(); } - Py_BEGIN_ALLOW_THREADS - n = pread(fd, PyBytes_AS_STRING(buffer), size, offset); - Py_END_ALLOW_THREADS + + 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 posix_error(); + return (!async_err) ? posix_error() : NULL; } - if (n != size) + if (n != length) _PyBytes_Resize(&buffer, n); return buffer; } -#endif +#endif /* HAVE_PREAD */ -PyDoc_STRVAR(posix_write__doc__, -"write(fd, data) -> byteswritten\n\n\ -Write bytes to a file descriptor."); -static PyObject * -posix_write(PyObject *self, PyObject *args) -{ - Py_buffer pbuf; - int fd; - Py_ssize_t size, len; +/*[clinic input] +os.write -> Py_ssize_t - if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf)) - return NULL; - if (!_PyVerify_fd(fd)) { - PyBuffer_Release(&pbuf); - return posix_error(); - } - len = pbuf.len; - Py_BEGIN_ALLOW_THREADS -#ifdef MS_WINDOWS - if (len > INT_MAX) - len = INT_MAX; - size = write(fd, pbuf.buf, (int)len); -#else - size = write(fd, pbuf.buf, len); -#endif - Py_END_ALLOW_THREADS - PyBuffer_Release(&pbuf); - if (size < 0) - return posix_error(); - return PyLong_FromSsize_t(size); + fd: int + data: Py_buffer + / + +Write a bytes object to a file descriptor. +[clinic start generated code]*/ + +static Py_ssize_t +os_write_impl(PyModuleDef *module, int fd, Py_buffer *data) +/*[clinic end generated code: output=58845c93c9ee1dda input=3207e28963234f3c]*/ +{ + return _Py_write(fd, data->buf, data->len); } #ifdef HAVE_SENDFILE PyDoc_STRVAR(posix_sendfile__doc__, -"sendfile(out, in, offset, nbytes) -> byteswritten\n\ -sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\ +"sendfile(out, in, offset, count) -> byteswritten\n\ +sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\ -> byteswritten\n\ -Copy nbytes bytes from file descriptor in to file descriptor out."); +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__) @@ -8212,6 +8258,7 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) 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}; @@ -8221,24 +8268,24 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) #ifdef __APPLE__ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile", - keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes, + 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, _parse_off_t, &offset, &len, + 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 or None"); + "sendfile() headers must be a sequence"); return NULL; } else { Py_ssize_t i = 0; /* Avoid uninitialized warning */ sf.hdr_cnt = PySequence_Size(headers); if (sf.hdr_cnt > 0 && - !(i = iov_setup(&(sf.headers), &hbuf, - headers, sf.hdr_cnt, PyBUF_SIMPLE))) + (i = iov_setup(&(sf.headers), &hbuf, + headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0) return NULL; #ifdef __APPLE__ sbytes += i; @@ -8248,14 +8295,14 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) if (trailers != NULL) { if (!PySequence_Check(trailers)) { PyErr_SetString(PyExc_TypeError, - "sendfile() trailers must be a sequence or None"); + "sendfile() trailers must be a sequence"); return NULL; } else { Py_ssize_t i = 0; /* Avoid uninitialized warning */ sf.trl_cnt = PySequence_Size(trailers); if (sf.trl_cnt > 0 && - !(i = iov_setup(&(sf.trailers), &tbuf, - trailers, sf.trl_cnt, PyBUF_SIMPLE))) + (i = iov_setup(&(sf.trailers), &tbuf, + trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0) return NULL; #ifdef __APPLE__ sbytes += i; @@ -8263,13 +8310,17 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) } } - Py_BEGIN_ALLOW_THREADS + _Py_BEGIN_SUPPRESS_IPH + do { + Py_BEGIN_ALLOW_THREADS #ifdef __APPLE__ - ret = sendfile(in, out, offset, &sbytes, &sf, flags); + ret = sendfile(in, out, offset, &sbytes, &sf, flags); #else - ret = sendfile(in, out, offset, len, &sf, &sbytes, flags); + ret = sendfile(in, out, offset, len, &sf, &sbytes, flags); #endif - Py_END_ALLOW_THREADS + 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); @@ -8288,7 +8339,7 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) return posix_error(); } } - return posix_error(); + return (!async_err) ? posix_error() : NULL; } goto done; @@ -8309,80 +8360,106 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) return NULL; #ifdef linux if (offobj == Py_None) { - Py_BEGIN_ALLOW_THREADS - ret = sendfile(out, in, NULL, count); - Py_END_ALLOW_THREADS + 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 posix_error(); + return (!async_err) ? posix_error() : NULL; return Py_BuildValue("n", ret); } #endif - if (!_parse_off_t(offobj, &offset)) + if (!Py_off_t_converter(offobj, &offset)) return NULL; - Py_BEGIN_ALLOW_THREADS - ret = sendfile(out, in, &offset, count); - Py_END_ALLOW_THREADS + + do { + Py_BEGIN_ALLOW_THREADS + ret = sendfile(out, in, &offset, count); + Py_END_ALLOW_THREADS + } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (ret < 0) - return posix_error(); + return (!async_err) ? posix_error() : NULL; return Py_BuildValue("n", ret); #endif } -#endif +#endif /* HAVE_SENDFILE */ + + +/*[clinic input] +os.fstat + + fd : int -PyDoc_STRVAR(posix_fstat__doc__, -"fstat(fd) -> stat result\n\n\ -Like stat(), but for an open file descriptor.\n\ -Equivalent to stat(fd=fd)."); +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 * -posix_fstat(PyObject *self, PyObject *args) +os_fstat_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=d71fe98bf042b626 input=27e0e0ebbe5600c9]*/ { - int fd; STRUCT_STAT st; int res; - if (!PyArg_ParseTuple(args, "i:fstat", &fd)) - return NULL; -#ifdef __VMS - /* on OpenVMS we must ensure that all bytes are written to the file */ - fsync(fd); -#endif - Py_BEGIN_ALLOW_THREADS - res = FSTAT(fd, &st); - Py_END_ALLOW_THREADS + 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 posix_error(); + return (!async_err) ? posix_error() : NULL; #endif } return _pystat_fromstructstat(&st); } -PyDoc_STRVAR(posix_isatty__doc__, -"isatty(fd) -> bool\n\n\ -Return True if the file descriptor 'fd' is an open file descriptor\n\ -connected to the slave end of a terminal."); -static PyObject * -posix_isatty(PyObject *self, PyObject *args) +/*[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(PyModuleDef *module, int fd) +/*[clinic end generated code: output=acec9d3c29d16d33 input=08ce94aa1eaf7b5e]*/ { - int fd; - if (!PyArg_ParseTuple(args, "i:isatty", &fd)) - return NULL; + int return_value; if (!_PyVerify_fd(fd)) - return PyBool_FromLong(0); - return PyBool_FromLong(isatty(fd)); + return 0; + _Py_BEGIN_SUPPRESS_IPH + return_value = isatty(fd); + _Py_END_SUPPRESS_IPH + return return_value; } + #ifdef HAVE_PIPE -PyDoc_STRVAR(posix_pipe__doc__, -"pipe() -> (read_end, write_end)\n\n\ -Create a 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 * -posix_pipe(PyObject *self, PyObject *noargs) +os_pipe_impl(PyModuleDef *module) +/*[clinic end generated code: output=6b0cd3f868ec3c40 input=02535e8c8fa6c4d4]*/ { int fds[2]; #ifdef MS_WINDOWS @@ -8450,25 +8527,30 @@ posix_pipe(PyObject *self, PyObject *noargs) } #endif /* HAVE_PIPE */ + #ifdef HAVE_PIPE2 -PyDoc_STRVAR(posix_pipe2__doc__, -"pipe2(flags) -> (read_end, write_end)\n\n\ -Create a pipe with flags set atomically.\n\ -flags can be constructed by ORing together one or more of these values:\n\ -O_NONBLOCK, O_CLOEXEC.\n\ -"); +/*[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 * -posix_pipe2(PyObject *self, PyObject *arg) +os_pipe2_impl(PyModuleDef *module, int flags) +/*[clinic end generated code: output=c15b6075d0c6b2e7 input=f261b6e7e63c6817]*/ { - int flags; int fds[2]; int res; - flags = _PyLong_AsInt(arg); - if (flags == -1 && PyErr_Occurred()) - return NULL; - res = pipe2(fds, flags); if (res != 0) return posix_error(); @@ -8476,483 +8558,554 @@ posix_pipe2(PyObject *self, PyObject *arg) } #endif /* HAVE_PIPE2 */ + #ifdef HAVE_WRITEV -PyDoc_STRVAR(posix_writev__doc__, -"writev(fd, buffers) -> byteswritten\n\n\ -Write the contents of buffers to a file descriptor, where buffers is an\n\ -arbitrary sequence of buffers.\n\ -Returns the total bytes written."); +/*[clinic input] +os.writev -> Py_ssize_t + fd: int + buffers: object + / -static PyObject * -posix_writev(PyObject *self, PyObject *args) +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(PyModuleDef *module, int fd, PyObject *buffers) +/*[clinic end generated code: output=a48925dbf2d5c238 input=5b8d17fe4189d2fe]*/ { - int fd, cnt; - Py_ssize_t res; - PyObject *seq; + int cnt; + Py_ssize_t result; + int async_err = 0; struct iovec *iov; Py_buffer *buf; - if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq)) - return NULL; - if (!PySequence_Check(seq)) { + + if (!PySequence_Check(buffers)) { PyErr_SetString(PyExc_TypeError, "writev() arg 2 must be a sequence"); - return NULL; + return -1; } - cnt = PySequence_Size(seq); + cnt = PySequence_Size(buffers); - if (!iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE)) { - return NULL; + if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) { + return -1; } - Py_BEGIN_ALLOW_THREADS - res = writev(fd, iov, cnt); - Py_END_ALLOW_THREADS + 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); - return PyLong_FromSsize_t(res); + if (result < 0 && !async_err) + posix_error(); + + return result; } -#endif +#endif /* HAVE_WRITEV */ + #ifdef HAVE_PWRITE -PyDoc_STRVAR(posix_pwrite__doc__, -"pwrite(fd, string, offset) -> byteswritten\n\n\ -Write string to a file descriptor, fd, from offset, leaving the file\n\ -offset unchanged."); +/*[clinic input] +os.pwrite -> Py_ssize_t -static PyObject * -posix_pwrite(PyObject *self, PyObject *args) + 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(PyModuleDef *module, int fd, Py_buffer *buffer, + Py_off_t offset) +/*[clinic end generated code: output=93aabdb40e17d325 input=19903f1b3dd26377]*/ { - Py_buffer pbuf; - int fd; - off_t offset; Py_ssize_t size; - - if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset)) - return NULL; + int async_err = 0; if (!_PyVerify_fd(fd)) { - PyBuffer_Release(&pbuf); - return posix_error(); + posix_error(); + return -1; } - Py_BEGIN_ALLOW_THREADS - size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset); - Py_END_ALLOW_THREADS - PyBuffer_Release(&pbuf); - if (size < 0) - return posix_error(); - return PyLong_FromSsize_t(size); + + 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 +#endif /* HAVE_PWRITE */ + #ifdef HAVE_MKFIFO -PyDoc_STRVAR(posix_mkfifo__doc__, -"mkfifo(path, mode=0o666, *, dir_fd=None)\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."); +/*[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 * -posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs) +os_mkfifo_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd) +/*[clinic end generated code: output=8f5f5e72c630049a input=73032e98a36e0e19]*/ { - path_t path; - int mode = 0666; - int dir_fd = DEFAULT_DIR_FD; int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "mode", "dir_fd", NULL}; + int async_err = 0; - memset(&path, 0, sizeof(path)); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords, - path_converter, &path, - &mode, + do { + Py_BEGIN_ALLOW_THREADS #ifdef HAVE_MKFIFOAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd + if (dir_fd != DEFAULT_DIR_FD) + result = mkfifoat(dir_fd, path->narrow, mode); + else #endif - )) - return NULL; + 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_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 + Py_RETURN_NONE; +} +#endif /* HAVE_MKFIFO */ - if (result < 0) { - return_value = posix_error(); - goto exit; - } - return_value = Py_None; - Py_INCREF(Py_None); +#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) +/*[clinic input] +os.mknod -exit: - path_cleanup(&path); - return return_value; -} -#endif + path: path_t + mode: int=0o600 + device: dev_t=0 + * + dir_fd: dir_fd(requires='mknodat')=None -#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) -PyDoc_STRVAR(posix_mknod__doc__, -"mknod(filename, mode=0o600, device=0, *, dir_fd=None)\n\n\ -Create a filesystem node (file, device special file or named pipe)\n\ -named filename. 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. For S_IFCHR and S_IFBLK,\n\ -device defines the newly created device special file (probably using\n\ -os.makedev()), otherwise it 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."); +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 * -posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs) +os_mknod_impl(PyModuleDef *module, path_t *path, int mode, dev_t device, + int dir_fd) +/*[clinic end generated code: output=5151a8a9f754d272 input=ee44531551a4d83b]*/ { - path_t path; - int mode = 0666; - int device = 0; - int dir_fd = DEFAULT_DIR_FD; int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL}; + int async_err = 0; - memset(&path, 0, sizeof(path)); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|ii$O&:mknod", keywords, - path_converter, &path, - &mode, &device, + do { + Py_BEGIN_ALLOW_THREADS #ifdef HAVE_MKNODAT - dir_fd_converter, &dir_fd -#else - dir_fd_unavailable, &dir_fd + if (dir_fd != DEFAULT_DIR_FD) + result = mknodat(dir_fd, path->narrow, mode, device); + else #endif - )) - return NULL; + 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_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 + Py_RETURN_NONE; +} +#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */ - if (result < 0) { - return_value = posix_error(); - goto exit; - } - return_value = Py_None; - Py_INCREF(Py_None); +#ifdef HAVE_DEVICE_MACROS +/*[clinic input] +os.major -> unsigned_int -exit: - path_cleanup(&path); - return return_value; -} -#endif + device: dev_t + / -#ifdef HAVE_DEVICE_MACROS -PyDoc_STRVAR(posix_major__doc__, -"major(device) -> major number\n\ -Extracts a device major number from a raw device number."); +Extracts a device major number from a raw device number. +[clinic start generated code]*/ -static PyObject * -posix_major(PyObject *self, PyObject *args) +static unsigned int +os_major_impl(PyModuleDef *module, dev_t device) +/*[clinic end generated code: output=ba55693ab49bac34 input=1e16a4d30c4d4462]*/ { - int device; - if (!PyArg_ParseTuple(args, "i:major", &device)) - return NULL; - return PyLong_FromLong((long)major(device)); + return major(device); } -PyDoc_STRVAR(posix_minor__doc__, -"minor(device) -> minor number\n\ -Extracts a device minor number from a raw device number."); -static PyObject * -posix_minor(PyObject *self, PyObject *args) -{ - int device; - if (!PyArg_ParseTuple(args, "i:minor", &device)) - return NULL; - return PyLong_FromLong((long)minor(device)); -} +/*[clinic input] +os.minor -> unsigned_int -PyDoc_STRVAR(posix_makedev__doc__, -"makedev(major, minor) -> device number\n\ -Composes a raw device number from the major and minor device numbers."); + device: dev_t + / -static PyObject * -posix_makedev(PyObject *self, PyObject *args) +Extracts a device minor number from a raw device number. +[clinic start generated code]*/ + +static unsigned int +os_minor_impl(PyModuleDef *module, dev_t device) +/*[clinic end generated code: output=2867219ebf274e27 input=0842c6d23f24c65e]*/ { - int major, minor; - if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor)) - return NULL; - return PyLong_FromLong((long)makedev(major, minor)); + return minor(device); } -#endif /* device macros */ -#ifdef HAVE_FTRUNCATE -PyDoc_STRVAR(posix_ftruncate__doc__, -"ftruncate(fd, length)\n\n\ -Truncate a file to a specified length."); +/*[clinic input] +os.makedev -> dev_t -static PyObject * -posix_ftruncate(PyObject *self, PyObject *args) + 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(PyModuleDef *module, int major, int minor) +/*[clinic end generated code: output=7cb6264352437660 input=4b9fd8fc73cbe48f]*/ { - int fd; - off_t length; - int res; + return makedev(major, minor); +} +#endif /* HAVE_DEVICE_MACROS */ - if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = ftruncate(fd, length); - Py_END_ALLOW_THREADS - if (res < 0) +#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(PyModuleDef *module, int fd, Py_off_t length) +/*[clinic end generated code: output=3666f401d76bf834 input=63b43641e52818f2]*/ +{ + int result; + int async_err = 0; + + if (!_PyVerify_fd(fd)) return posix_error(); - Py_INCREF(Py_None); - return Py_None; -} + + 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 */ -#ifdef HAVE_TRUNCATE -PyDoc_STRVAR(posix_truncate__doc__, -"truncate(path, length)\n\n\ -Truncate the file given by path to length bytes.\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."); + +#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 * -posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs) +os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length) +/*[clinic end generated code: output=f60a9e08370e9e2e input=77229cf0b50a9b77]*/ { - path_t path; - off_t length; - int res; - PyObject *result = NULL; - static char *keywords[] = {"path", "length", NULL}; - - memset(&path, 0, sizeof(path)); - path.function_name = "truncate"; -#ifdef HAVE_FTRUNCATE - path.allow_fd = 1; + int result; +#ifdef MS_WINDOWS + int fd; #endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords, - path_converter, &path, - _parse_off_t, &length)) - return NULL; + + if (path->fd != -1) + return os_ftruncate_impl(module, path->fd, length); Py_BEGIN_ALLOW_THREADS -#ifdef HAVE_FTRUNCATE - if (path.fd != -1) - res = ftruncate(path.fd, length); + _Py_BEGIN_SUPPRESS_IPH +#ifdef MS_WINDOWS + if (path->wide) + fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT); else -#endif - res = truncate(path.narrow, length); - Py_END_ALLOW_THREADS - if (res < 0) - result = path_error(&path); + fd = _open(path->narrow, _O_WRONLY | _O_BINARY | _O_NOINHERIT); + if (fd < 0) + result = -1; else { - Py_INCREF(Py_None); - result = Py_None; + result = _chsize_s(fd, length); + close(fd); + if (result < 0) + errno = result; } - path_cleanup(&path); - return result; +#else + result = truncate(path->narrow, length); +#endif + _Py_END_SUPPRESS_IPH + Py_END_ALLOW_THREADS + if (result < 0) + return 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 -#ifdef HAVE_POSIX_FALLOCATE -PyDoc_STRVAR(posix_posix_fallocate__doc__, -"posix_fallocate(fd, offset, len)\n\n\ -Ensures that enough disk space is allocated for the file specified by fd\n\ -starting from offset and continuing for len bytes."); + +#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 * -posix_posix_fallocate(PyObject *self, PyObject *args) +os_posix_fallocate_impl(PyModuleDef *module, int fd, Py_off_t offset, + Py_off_t length) +/*[clinic end generated code: output=7f6f87a8c751e1b4 input=d7a2ef0ab2ca52fb]*/ { - off_t len, offset; - int res, fd; - - if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate", - &fd, _parse_off_t, &offset, _parse_off_t, &len)) - return NULL; + int result; + int async_err = 0; - Py_BEGIN_ALLOW_THREADS - res = posix_fallocate(fd, offset, len); - Py_END_ALLOW_THREADS - if (res != 0) { - errno = res; - return posix_error(); - } + do { + Py_BEGIN_ALLOW_THREADS + result = posix_fallocate(fd, offset, length); + 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 +#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 + / -#ifdef HAVE_POSIX_FADVISE -PyDoc_STRVAR(posix_posix_fadvise__doc__, -"posix_fadvise(fd, offset, len, advice)\n\n\ -Announces 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 len 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."); +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 * -posix_posix_fadvise(PyObject *self, PyObject *args) +os_posix_fadvise_impl(PyModuleDef *module, int fd, Py_off_t offset, + Py_off_t length, int advice) +/*[clinic end generated code: output=457ce6a67189e10d input=0fbe554edc2f04b5]*/ { - off_t len, offset; - int res, fd, advice; - - if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise", - &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice)) - return NULL; + int result; + int async_err = 0; - Py_BEGIN_ALLOW_THREADS - res = posix_fadvise(fd, offset, len, advice); - Py_END_ALLOW_THREADS - if (res != 0) { - errno = res; - return posix_error(); - } + do { + Py_BEGIN_ALLOW_THREADS + result = posix_fadvise(fd, offset, length, advice); + 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 +#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */ #ifdef HAVE_PUTENV -PyDoc_STRVAR(posix_putenv__doc__, -"putenv(key, value)\n\n\ -Change or add an environment variable."); /* 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 PyObject * -posix_putenv(PyObject *self, PyObject *args) +static void +posix_putenv_garbage_setitem(PyObject *name, PyObject *value) { - PyObject *newstr = NULL; + /* 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 - PyObject *os1, *os2; - wchar_t *newenv; +/*[clinic input] +os.putenv - if (!PyArg_ParseTuple(args, - "UU:putenv", - &os1, &os2)) - return NULL; + name: unicode + value: unicode + / + +Change or add an environment variable. +[clinic start generated code]*/ + +static PyObject * +os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value) +/*[clinic end generated code: output=a2438cf95e5a0c1c input=ba586581c2e6105f]*/ +{ + wchar_t *env; - newstr = PyUnicode_FromFormat("%U=%U", os1, os2); - if (newstr == NULL) { + PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value); + if (unicode == NULL) { PyErr_NoMemory(); - goto error; + return NULL; } - if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) { + if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) { PyErr_Format(PyExc_ValueError, "the environment variable is longer than %u characters", _MAX_ENV); goto error; } - newenv = PyUnicode_AsUnicode(newstr); - if (newenv == NULL) + env = PyUnicode_AsUnicode(unicode); + if (env == NULL) goto error; - if (_wputenv(newenv)) { + if (_wputenv(env)) { posix_error(); goto error; } -#else - PyObject *os1, *os2; - char *s1, *s2; - char *newenv; - - if (!PyArg_ParseTuple(args, - "O&O&:putenv", - PyUnicode_FSConverter, &os1, - PyUnicode_FSConverter, &os2)) - return NULL; - s1 = PyBytes_AsString(os1); - s2 = PyBytes_AsString(os2); - newstr = PyBytes_FromFormat("%s=%s", s1, s2); - if (newstr == NULL) { - PyErr_NoMemory(); - goto error; - } + posix_putenv_garbage_setitem(name, unicode); + Py_RETURN_NONE; - newenv = PyBytes_AS_STRING(newstr); - if (putenv(newenv)) { - posix_error(); - goto error; - } -#endif +error: + Py_DECREF(unicode); + return NULL; +} +#else /* MS_WINDOWS */ +/*[clinic input] +os.putenv - /* 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, os1, newstr)) { - /* really not much we can do; just leak */ - PyErr_Clear(); + name: FSConverter + value: FSConverter + / + +Change or add an environment variable. +[clinic start generated code]*/ + +static PyObject * +os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value) +/*[clinic end generated code: output=a2438cf95e5a0c1c input=a97bc6152f688d31]*/ +{ + PyObject *bytes = NULL; + char *env; + char *name_string = PyBytes_AsString(name); + char *value_string = PyBytes_AsString(value); + + bytes = PyBytes_FromFormat("%s=%s", name_string, value_string); + if (bytes == NULL) { + PyErr_NoMemory(); + return NULL; } - else { - Py_DECREF(newstr); + + env = PyBytes_AS_STRING(bytes); + if (putenv(env)) { + Py_DECREF(bytes); + return posix_error(); } -#ifndef MS_WINDOWS - Py_DECREF(os1); - Py_DECREF(os2); -#endif + posix_putenv_garbage_setitem(name, bytes); Py_RETURN_NONE; - -error: -#ifndef MS_WINDOWS - Py_DECREF(os1); - Py_DECREF(os2); -#endif - Py_XDECREF(newstr); - return NULL; } -#endif /* putenv */ +#endif /* MS_WINDOWS */ +#endif /* HAVE_PUTENV */ + #ifdef HAVE_UNSETENV -PyDoc_STRVAR(posix_unsetenv__doc__, -"unsetenv(key)\n\n\ -Delete an environment variable."); +/*[clinic input] +os.unsetenv + name: FSConverter + / + +Delete an environment variable. +[clinic start generated code]*/ static PyObject * -posix_unsetenv(PyObject *self, PyObject *args) +os_unsetenv_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: output=25994b57016a2dc9 input=2bb5288a599c7107]*/ { - PyObject *name; #ifndef HAVE_BROKEN_UNSETENV int err; #endif - if (!PyArg_ParseTuple(args, "O&:unsetenv", - - PyUnicode_FSConverter, &name)) - return NULL; - #ifdef HAVE_BROKEN_UNSETENV unsetenv(PyBytes_AS_STRING(name)); #else err = unsetenv(PyBytes_AS_STRING(name)); - if (err) { - Py_DECREF(name); + if (err) return posix_error(); - } #endif /* Remove the key from posix_putenv_garbage; @@ -8964,23 +9117,25 @@ posix_unsetenv(PyObject *self, PyObject *args) /* really not much we can do; just leak */ PyErr_Clear(); } - Py_DECREF(name); Py_RETURN_NONE; } -#endif /* unsetenv */ +#endif /* HAVE_UNSETENV */ + -PyDoc_STRVAR(posix_strerror__doc__, -"strerror(code) -> string\n\n\ -Translate an error code to a message string."); +/*[clinic input] +os.strerror + + code: int + / + +Translate an error code to a message string. +[clinic start generated code]*/ static PyObject * -posix_strerror(PyObject *self, PyObject *args) +os_strerror_impl(PyModuleDef *module, int code) +/*[clinic end generated code: output=0280c6af51e5c9fe input=75a8673d97915a91]*/ { - int code; - char *message; - if (!PyArg_ParseTuple(args, "i:strerror", &code)) - return NULL; - message = strerror(code); + char *message = strerror(code); if (message == NULL) { PyErr_SetString(PyExc_ValueError, "strerror() argument out of range"); @@ -8991,155 +9146,168 @@ posix_strerror(PyObject *self, PyObject *args) #ifdef HAVE_SYS_WAIT_H - #ifdef WCOREDUMP -PyDoc_STRVAR(posix_WCOREDUMP__doc__, -"WCOREDUMP(status) -> bool\n\n\ -Return True if the process returning 'status' was dumped to a core file."); +/*[clinic input] +os.WCOREDUMP -> bool -static PyObject * -posix_WCOREDUMP(PyObject *self, PyObject *args) -{ - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; + status: int + / - if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status))) - return NULL; +Return True if the process returning status was dumped to a core file. +[clinic start generated code]*/ - return PyBool_FromLong(WCOREDUMP(status)); +static int +os_WCOREDUMP_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=134f70bbe63fbf41 input=8b05e7ab38528d04]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WCOREDUMP(wait_status); } #endif /* WCOREDUMP */ + #ifdef WIFCONTINUED -PyDoc_STRVAR(posix_WIFCONTINUED__doc__, -"WIFCONTINUED(status) -> bool\n\n\ -Return True if the process returning 'status' was continued from a\n\ -job control stop."); +/*[clinic input] +os.WIFCONTINUED -> bool -static PyObject * -posix_WIFCONTINUED(PyObject *self, PyObject *args) -{ - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; + status: int - if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status))) - return NULL; +Return True if a particular process was continued from a job control stop. - return PyBool_FromLong(WIFCONTINUED(status)); +Return True if the process returning status was continued from a +job control stop. +[clinic start generated code]*/ + +static int +os_WIFCONTINUED_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=9cdd26543ebb6dcd input=e777e7d38eb25bd9]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WIFCONTINUED(wait_status); } #endif /* WIFCONTINUED */ + #ifdef WIFSTOPPED -PyDoc_STRVAR(posix_WIFSTOPPED__doc__, -"WIFSTOPPED(status) -> bool\n\n\ -Return True if the process returning 'status' was stopped."); +/*[clinic input] +os.WIFSTOPPED -> bool -static PyObject * -posix_WIFSTOPPED(PyObject *self, PyObject *args) -{ - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; + status: int - if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status))) - return NULL; +Return True if the process returning status was stopped. +[clinic start generated code]*/ - return PyBool_FromLong(WIFSTOPPED(status)); +static int +os_WIFSTOPPED_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=73bf35e44994a724 input=043cb7f1289ef904]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WIFSTOPPED(wait_status); } #endif /* WIFSTOPPED */ + #ifdef WIFSIGNALED -PyDoc_STRVAR(posix_WIFSIGNALED__doc__, -"WIFSIGNALED(status) -> bool\n\n\ -Return True if the process returning 'status' was terminated by a signal."); +/*[clinic input] +os.WIFSIGNALED -> bool -static PyObject * -posix_WIFSIGNALED(PyObject *self, PyObject *args) -{ - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; + status: int - if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status))) - return NULL; +Return True if the process returning status was terminated by a signal. +[clinic start generated code]*/ - return PyBool_FromLong(WIFSIGNALED(status)); +static int +os_WIFSIGNALED_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=2697975771872420 input=d55ba7cc9ce5dc43]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WIFSIGNALED(wait_status); } #endif /* WIFSIGNALED */ + #ifdef WIFEXITED -PyDoc_STRVAR(posix_WIFEXITED__doc__, -"WIFEXITED(status) -> bool\n\n\ -Return true if the process returning 'status' exited using the exit()\n\ -system call."); +/*[clinic input] +os.WIFEXITED -> bool -static PyObject * -posix_WIFEXITED(PyObject *self, PyObject *args) -{ - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; + status: int - if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status))) - return NULL; +Return True if the process returning status exited via the exit() system call. +[clinic start generated code]*/ - return PyBool_FromLong(WIFEXITED(status)); +static int +os_WIFEXITED_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=ca8f8c61f0b8532e input=d63775a6791586c0]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WIFEXITED(wait_status); } #endif /* WIFEXITED */ + #ifdef WEXITSTATUS -PyDoc_STRVAR(posix_WEXITSTATUS__doc__, -"WEXITSTATUS(status) -> integer\n\n\ -Return the process return code from 'status'."); +/*[clinic input] +os.WEXITSTATUS -> int -static PyObject * -posix_WEXITSTATUS(PyObject *self, PyObject *args) -{ - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; + status: int - if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status))) - return NULL; +Return the process return code from status. +[clinic start generated code]*/ - return Py_BuildValue("i", WEXITSTATUS(status)); +static int +os_WEXITSTATUS_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=ea54da23d9e0f6af input=e1fb4944e377585b]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WEXITSTATUS(wait_status); } #endif /* WEXITSTATUS */ + #ifdef WTERMSIG -PyDoc_STRVAR(posix_WTERMSIG__doc__, -"WTERMSIG(status) -> integer\n\n\ -Return the signal that terminated the process that provided the 'status'\n\ -value."); +/*[clinic input] +os.WTERMSIG -> int -static PyObject * -posix_WTERMSIG(PyObject *self, PyObject *args) -{ - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; + status: int - if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status))) - return NULL; +Return the signal that terminated the process that provided the status value. +[clinic start generated code]*/ - return Py_BuildValue("i", WTERMSIG(status)); +static int +os_WTERMSIG_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=4d25367026cb852c input=727fd7f84ec3f243]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WTERMSIG(wait_status); } #endif /* WTERMSIG */ + #ifdef WSTOPSIG -PyDoc_STRVAR(posix_WSTOPSIG__doc__, -"WSTOPSIG(status) -> integer\n\n\ -Return the signal that stopped the process that provided\n\ -the 'status' value."); +/*[clinic input] +os.WSTOPSIG -> int -static PyObject * -posix_WSTOPSIG(PyObject *self, PyObject *args) -{ - WAIT_TYPE status; - WAIT_STATUS_INT(status) = 0; + status: int - if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status))) - return NULL; +Return the signal that stopped the process that provided the status value. +[clinic start generated code]*/ - return Py_BuildValue("i", WSTOPSIG(status)); +static int +os_WSTOPSIG_impl(PyModuleDef *module, int status) +/*[clinic end generated code: output=54eb9c13b001adb4 input=46ebf1d1b293c5c1]*/ +{ + WAIT_TYPE wait_status; + WAIT_STATUS_INT(wait_status) = status; + return WSTOPSIG(wait_status); } #endif /* WSTOPSIG */ - #endif /* HAVE_SYS_WAIT_H */ @@ -9194,104 +9362,101 @@ _pystatvfs_fromstructstatvfs(struct statvfs st) { return v; } -PyDoc_STRVAR(posix_fstatvfs__doc__, -"fstatvfs(fd) -> statvfs result\n\n\ -Perform an fstatvfs system call on the given fd.\n\ -Equivalent to statvfs(fd)."); + +/*[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 * -posix_fstatvfs(PyObject *self, PyObject *args) +os_fstatvfs_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=584a94a754497ac0 input=d8122243ac50975e]*/ { - int fd, res; + int result; + int async_err = 0; struct statvfs st; - if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd)) - return NULL; - Py_BEGIN_ALLOW_THREADS - res = fstatvfs(fd, &st); - Py_END_ALLOW_THREADS - if (res != 0) - return posix_error(); + 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 /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */ +#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */ #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) #include +/*[clinic input] +os.statvfs -PyDoc_STRVAR(posix_statvfs__doc__, -"statvfs(path)\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."); + 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 * -posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs) +os_statvfs_impl(PyModuleDef *module, path_t *path) +/*[clinic end generated code: output=5ced07a2cf931f41 input=3f5c35791c669bd9]*/ { - static char *keywords[] = {"path", NULL}; - path_t path; int result; - PyObject *return_value = NULL; struct statvfs st; - memset(&path, 0, sizeof(path)); - path.function_name = "statvfs"; -#ifdef HAVE_FSTATVFS - path.allow_fd = 1; -#endif - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords, - path_converter, &path - )) - return NULL; - Py_BEGIN_ALLOW_THREADS #ifdef HAVE_FSTATVFS - if (path.fd != -1) { + if (path->fd != -1) { #ifdef __APPLE__ /* handle weak-linking on Mac OS X 10.3 */ if (fstatvfs == NULL) { - fd_specified("statvfs", path.fd); - goto exit; + fd_specified("statvfs", path->fd); + return NULL; } #endif - result = fstatvfs(path.fd, &st); + result = fstatvfs(path->fd, &st); } else #endif - result = statvfs(path.narrow, &st); + result = statvfs(path->narrow, &st); Py_END_ALLOW_THREADS if (result) { - return_value = path_error(&path); - goto exit; + return path_error(path); } - return_value = _pystatvfs_fromstructstatvfs(st); - -exit: - path_cleanup(&path); - return return_value; + return _pystatvfs_fromstructstatvfs(st); } -#endif /* HAVE_STATVFS */ +#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */ + #ifdef MS_WINDOWS -PyDoc_STRVAR(win32__getdiskusage__doc__, -"_getdiskusage(path) -> (total, free)\n\n\ -Return disk usage statistics about the given path as (total, free) tuple."); +/*[clinic input] +os._getdiskusage + + path: Py_UNICODE + +Return disk usage statistics about the given path as a (total, free) tuple. +[clinic start generated code]*/ static PyObject * -win32__getdiskusage(PyObject *self, PyObject *args) +os__getdiskusage_impl(PyModuleDef *module, Py_UNICODE *path) +/*[clinic end generated code: output=60a9cf33449db1dd input=6458133aed893c78]*/ { BOOL retval; ULARGE_INTEGER _, total, free; - const wchar_t *path; - - if (! PyArg_ParseTuple(args, "u", &path)) - return NULL; Py_BEGIN_ALLOW_THREADS retval = GetDiskFreeSpaceExW(path, &_, &total, &free); @@ -9301,7 +9466,7 @@ win32__getdiskusage(PyObject *self, PyObject *args) return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart); } -#endif +#endif /* MS_WINDOWS */ /* This is used for fpathconf(), pathconf(), confstr() and sysconf(). @@ -9317,7 +9482,7 @@ win32__getdiskusage(PyObject *self, PyObject *args) */ struct constdef { char *name; - long value; + int value; }; static int @@ -9325,7 +9490,10 @@ conv_confname(PyObject *arg, int *valuep, struct constdef *table, size_t tablesize) { if (PyLong_Check(arg)) { - *valuep = PyLong_AS_LONG(arg); + int value = _PyLong_AsInt(arg); + if (value == -1 && PyErr_Occurred()) + return 0; + *valuep = value; return 1; } else { @@ -9458,81 +9626,73 @@ conv_path_confname(PyObject *arg, int *valuep) } #endif + #ifdef HAVE_FPATHCONF -PyDoc_STRVAR(posix_fpathconf__doc__, -"fpathconf(fd, name) -> integer\n\n\ -Return the configuration limit name for the file descriptor fd.\n\ -If there is no limit, return -1."); +/*[clinic input] +os.fpathconf -> long -static PyObject * -posix_fpathconf(PyObject *self, PyObject *args) + 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(PyModuleDef *module, int fd, int name) +/*[clinic end generated code: output=082b2922d4441de7 input=5942a024d3777810]*/ { - PyObject *result = NULL; - int name, fd; + long limit; - if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd, - conv_path_confname, &name)) { - long limit; + errno = 0; + limit = fpathconf(fd, name); + if (limit == -1 && errno != 0) + posix_error(); - errno = 0; - limit = fpathconf(fd, name); - if (limit == -1 && errno != 0) - posix_error(); - else - result = PyLong_FromLong(limit); - } - return result; + return limit; } -#endif +#endif /* HAVE_FPATHCONF */ #ifdef HAVE_PATHCONF -PyDoc_STRVAR(posix_pathconf__doc__, -"pathconf(path, name) -> integer\n\n\ -Return the configuration limit name for the file or directory path.\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."); +/*[clinic input] +os.pathconf -> long + path: path_t(allow_fd='PATH_HAVE_FPATHCONF') + name: path_confname -static PyObject * -posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs) -{ - path_t path; - PyObject *result = NULL; - int name; - static char *keywords[] = {"path", "name", NULL}; +Return the configuration limit name for the file or directory path. - memset(&path, 0, sizeof(path)); - path.function_name = "pathconf"; -#ifdef HAVE_FPATHCONF - path.allow_fd = 1; -#endif - if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords, - path_converter, &path, - conv_path_confname, &name)) { +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(PyModuleDef *module, path_t *path, int name) +/*[clinic end generated code: output=3713029e9501f5ab input=bc3e2a985af27e5e]*/ +{ long limit; errno = 0; #ifdef HAVE_FPATHCONF - if (path.fd != -1) - limit = fpathconf(path.fd, name); + if (path->fd != -1) + limit = fpathconf(path->fd, name); else #endif - limit = pathconf(path.narrow, name); + limit = pathconf(path->narrow, name); if (limit == -1 && errno != 0) { if (errno == EINVAL) /* could be a path or name problem */ posix_error(); else - result = path_error(&path); - } - else - result = PyLong_FromLong(limit); + path_error(path); } - path_cleanup(&path); - return result; + + return limit; } -#endif +#endif /* HAVE_PATHCONF */ #ifdef HAVE_CONFSTR static struct constdef posix_constants_confstr[] = { @@ -9696,21 +9856,24 @@ conv_confstr_confname(PyObject *arg, int *valuep) / sizeof(struct constdef)); } -PyDoc_STRVAR(posix_confstr__doc__, -"confstr(name) -> string\n\n\ -Return a string-valued system configuration variable."); + +/*[clinic input] +os.confstr + + name: confstr_confname + / + +Return a string-valued system configuration variable. +[clinic start generated code]*/ static PyObject * -posix_confstr(PyObject *self, PyObject *args) +os_confstr_impl(PyModuleDef *module, int name) +/*[clinic end generated code: output=6ff79c9eed8c2daf input=18fb4d0567242e65]*/ { PyObject *result = NULL; - int name; char buffer[255]; size_t len; - if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) - return NULL; - errno = 0; len = confstr(name, buffer, sizeof(buffer)); if (len == 0) { @@ -9724,18 +9887,20 @@ posix_confstr(PyObject *self, PyObject *args) } if (len >= sizeof(buffer)) { + size_t len2; char *buf = PyMem_Malloc(len); if (buf == NULL) return PyErr_NoMemory(); - confstr(name, buf, len); - result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1); + 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 +#endif /* HAVE_CONFSTR */ #ifdef HAVE_SYSCONF @@ -10242,33 +10407,32 @@ conv_sysconf_confname(PyObject *arg, int *valuep) / sizeof(struct constdef)); } -PyDoc_STRVAR(posix_sysconf__doc__, -"sysconf(name) -> integer\n\n\ -Return an integer-valued system configuration variable."); -static PyObject * -posix_sysconf(PyObject *self, PyObject *args) -{ - PyObject *result = NULL; - int name; +/*[clinic input] +os.sysconf -> long + name: sysconf_confname + / - if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) { - long value; +Return an integer-valued system configuration variable. +[clinic start generated code]*/ - errno = 0; - value = sysconf(name); - if (value == -1 && errno != 0) - posix_error(); - else - result = PyLong_FromLong(value); - } - return result; +static long +os_sysconf_impl(PyModuleDef *module, int name) +/*[clinic end generated code: output=ed567306f58d69c4 input=279e3430a33f29e4]*/ +{ + long value; + + errno = 0; + value = sysconf(name); + if (value == -1 && errno != 0) + posix_error(); + return value; } -#endif +#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 + * 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. * @@ -10341,13 +10505,18 @@ setup_confname_tables(PyObject *module) } -PyDoc_STRVAR(posix_abort__doc__, -"abort() -> does not return!\n\n\ -Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\ -in the hardest way possible on the hosting operating system."); +/*[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 * -posix_abort(PyObject *self, PyObject *noargs) +os_abort_impl(PyModuleDef *module) +/*[clinic end generated code: output=486bb96647c299b3 input=cf2c7d98bc504047]*/ { abort(); /*NOTREACHED*/ @@ -10356,9 +10525,11 @@ posix_abort(PyObject *self, PyObject *noargs) } #ifdef MS_WINDOWS +/* AC 3.5: change to path_t? but that might change exceptions */ PyDoc_STRVAR(win32_startfile__doc__, -"startfile(filepath [, operation]) - Start a file with its associated\n\ -application.\n\ +"startfile(filepath [, operation])\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\ @@ -10375,6 +10546,37 @@ 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."); +/* Grab ShellExecute dynamically from shell32 */ +static int has_ShellExecute = -1; +static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR, + LPCSTR, INT); +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 + hShell32 = LoadLibraryW(L"SHELL32"); + Py_END_ALLOW_THREADS + if (hShell32) { + *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32, + "ShellExecuteA"); + *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32, + "ShellExecuteW"); + has_ShellExecute = Py_ShellExecuteA && + Py_ShellExecuteW; + } else { + has_ShellExecute = 0; + } + } + return has_ShellExecute; +} + + static PyObject * win32_startfile(PyObject *self, PyObject *args) { @@ -10385,6 +10587,14 @@ win32_startfile(PyObject *self, PyObject *args) HINSTANCE rc; PyObject *unipath, *uoperation = NULL; + + 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 (!PyArg_ParseTuple(args, "U|s:startfile", &unipath, &operation)) { PyErr_Clear(); @@ -10413,8 +10623,8 @@ win32_startfile(PyObject *self, PyObject *args) woperation = NULL; Py_BEGIN_ALLOW_THREADS - rc = ShellExecuteW((HWND)0, woperation, wpath, - NULL, NULL, SW_SHOWNORMAL); + rc = Py_ShellExecuteW((HWND)0, woperation, wpath, + NULL, NULL, SW_SHOWNORMAL); Py_END_ALLOW_THREADS Py_XDECREF(uoperation); @@ -10436,8 +10646,8 @@ win32_startfile(PyObject *self, PyObject *args) } filepath = PyBytes_AsString(ofilepath); Py_BEGIN_ALLOW_THREADS - rc = ShellExecute((HWND)0, operation, filepath, - NULL, NULL, SW_SHOWNORMAL); + rc = Py_ShellExecuteA((HWND)0, operation, filepath, + NULL, NULL, SW_SHOWNORMAL); Py_END_ALLOW_THREADS if (rc <= (HINSTANCE)32) { PyObject *errval = win32_error("startfile", filepath); @@ -10448,17 +10658,23 @@ win32_startfile(PyObject *self, PyObject *args) Py_INCREF(Py_None); return Py_None; } -#endif +#endif /* MS_WINDOWS */ + #ifdef HAVE_GETLOADAVG -PyDoc_STRVAR(posix_getloadavg__doc__, -"getloadavg() -> (float, float, float)\n\n\ -Return the number of processes in the system run queue averaged over\n\ -the last 1, 5, and 15 minutes or raises OSError if the load average\n\ -was unobtainable"); +/*[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 * -posix_getloadavg(PyObject *self, PyObject *noargs) +os_getloadavg_impl(PyModuleDef *module) +/*[clinic end generated code: output=2b64c5b675d74c14 input=3d6d826b76d8a34e]*/ { double loadavg[3]; if (getloadavg(loadavg, 3)!=3) { @@ -10467,72 +10683,83 @@ posix_getloadavg(PyObject *self, PyObject *noargs) } else return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]); } -#endif +#endif /* HAVE_GETLOADAVG */ -PyDoc_STRVAR(device_encoding__doc__, -"device_encoding(fd) -> str\n\n\ -Return a string describing the encoding of the device\n\ -if the output is a terminal; else return None."); -static PyObject * -device_encoding(PyObject *self, PyObject *args) -{ - int fd; +/*[clinic input] +os.device_encoding + fd: int - if (!PyArg_ParseTuple(args, "i:device_encoding", &fd)) - return NULL; +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(PyModuleDef *module, int fd) +/*[clinic end generated code: output=34f14e33468419c1 input=9e1d4a42b66df312]*/ +{ return _Py_device_encoding(fd); } + #ifdef HAVE_SETRESUID -PyDoc_STRVAR(posix_setresuid__doc__, -"setresuid(ruid, euid, suid)\n\n\ -Set the current process's real, effective, and saved user ids."); +/*[clinic input] +os.setresuid -static PyObject* -posix_setresuid (PyObject *self, PyObject *args) + 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(PyModuleDef *module, uid_t ruid, uid_t euid, uid_t suid) +/*[clinic end generated code: output=92cc330812c6ed0f input=9e33cb79a82792f3]*/ { - /* We assume uid_t is no larger than a long. */ - uid_t ruid, euid, suid; - if (!PyArg_ParseTuple(args, "O&O&O&:setresuid", - _Py_Uid_Converter, &ruid, - _Py_Uid_Converter, &euid, - _Py_Uid_Converter, &suid)) - return NULL; if (setresuid(ruid, euid, suid) < 0) return posix_error(); Py_RETURN_NONE; } -#endif +#endif /* HAVE_SETRESUID */ + #ifdef HAVE_SETRESGID -PyDoc_STRVAR(posix_setresgid__doc__, -"setresgid(rgid, egid, sgid)\n\n\ -Set the current process's real, effective, and saved group ids."); +/*[clinic input] +os.setresgid -static PyObject* -posix_setresgid (PyObject *self, PyObject *args) + 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(PyModuleDef *module, gid_t rgid, gid_t egid, gid_t sgid) +/*[clinic end generated code: output=e91dc4842a604429 input=33e9e0785ef426b1]*/ { - gid_t rgid, egid, sgid; - if (!PyArg_ParseTuple(args, "O&O&O&:setresgid", - _Py_Gid_Converter, &rgid, - _Py_Gid_Converter, &egid, - _Py_Gid_Converter, &sgid)) - return NULL; if (setresgid(rgid, egid, sgid) < 0) return posix_error(); Py_RETURN_NONE; } -#endif +#endif /* HAVE_SETRESGID */ + #ifdef HAVE_GETRESUID -PyDoc_STRVAR(posix_getresuid__doc__, -"getresuid() -> (ruid, euid, suid)\n\n\ -Get tuple of the current process's real, effective, and saved user ids."); +/*[clinic input] +os.getresuid -static PyObject* -posix_getresuid (PyObject *self, PyObject *noargs) +Return a tuple of the current process's real, effective, and saved user ids. +[clinic start generated code]*/ + +static PyObject * +os_getresuid_impl(PyModuleDef *module) +/*[clinic end generated code: output=9ddef62faae8e477 input=41ccfa8e1f6517ad]*/ { uid_t ruid, euid, suid; if (getresuid(&ruid, &euid, &suid) < 0) @@ -10541,90 +10768,88 @@ posix_getresuid (PyObject *self, PyObject *noargs) _PyLong_FromUid(euid), _PyLong_FromUid(suid)); } -#endif +#endif /* HAVE_GETRESUID */ + #ifdef HAVE_GETRESGID -PyDoc_STRVAR(posix_getresgid__doc__, -"getresgid() -> (rgid, egid, sgid)\n\n\ -Get tuple of the current process's real, effective, and saved group ids."); +/*[clinic input] +os.getresgid -static PyObject* -posix_getresgid (PyObject *self, PyObject *noargs) +Return a tuple of the current process's real, effective, and saved group ids. +[clinic start generated code]*/ + +static PyObject * +os_getresgid_impl(PyModuleDef *module) +/*[clinic end generated code: output=e1a553cbcf16234c input=517e68db9ca32df6]*/ { - uid_t rgid, egid, sgid; + 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 +#endif /* HAVE_GETRESGID */ + #ifdef USE_XATTRS +/*[clinic input] +os.getxattr -PyDoc_STRVAR(posix_getxattr__doc__, -"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\ -Return the value of extended attribute attribute on path.\n\ -\n\ -path may be either a string 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."); + 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 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 * -posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs) +os_getxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, + int follow_symlinks) +/*[clinic end generated code: output=cf2cede74bd5d412 input=8c8ea3bab78d89c2]*/ { - path_t path; - path_t attribute; - int follow_symlinks = 1; + Py_ssize_t i; PyObject *buffer = NULL; - int i; - static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL}; - memset(&path, 0, sizeof(path)); - memset(&attribute, 0, sizeof(attribute)); - path.function_name = "getxattr"; - attribute.function_name = "getxattr"; - path.allow_fd = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords, - path_converter, &path, - path_converter, &attribute, - &follow_symlinks)) + if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks)) return NULL; - if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks)) - goto exit; - for (i = 0; ; i++) { void *ptr; ssize_t result; static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0}; Py_ssize_t buffer_size = buffer_sizes[i]; if (!buffer_size) { - path_error(&path); - goto exit; + path_error(path); + return NULL; } buffer = PyBytes_FromStringAndSize(NULL, buffer_size); if (!buffer) - goto exit; + return NULL; ptr = PyBytes_AS_STRING(buffer); Py_BEGIN_ALLOW_THREADS; - if (path.fd >= 0) - result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size); + 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); + result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size); else - result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size); + result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size); Py_END_ALLOW_THREADS; if (result < 0) { Py_DECREF(buffer); - buffer = NULL; if (errno == ERANGE) continue; - path_error(&path); - goto exit; + path_error(path); + return NULL; } if (result != buffer_size) { @@ -10634,168 +10859,134 @@ posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs) break; } -exit: - path_cleanup(&path); - path_cleanup(&attribute); return buffer; } -PyDoc_STRVAR(posix_setxattr__doc__, -"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\ -Set extended attribute attribute on path to value.\n\ -path may be either a string 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."); + +/*[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 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 * -posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs) +os_setxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, + Py_buffer *value, int flags, int follow_symlinks) +/*[clinic end generated code: output=1b395ef82880fea0 input=f0d26833992015c2]*/ { - path_t path; - path_t attribute; - Py_buffer value; - int flags = 0; - int follow_symlinks = 1; - int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "attribute", "value", - "flags", "follow_symlinks", NULL}; + ssize_t result; - memset(&path, 0, sizeof(path)); - path.function_name = "setxattr"; - path.allow_fd = 1; - memset(&attribute, 0, sizeof(attribute)); - memset(&value, 0, sizeof(value)); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr", - keywords, - path_converter, &path, - path_converter, &attribute, - &value, &flags, - &follow_symlinks)) + if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks)) return NULL; - if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks)) - goto exit; - Py_BEGIN_ALLOW_THREADS; - if (path.fd > -1) - result = fsetxattr(path.fd, attribute.narrow, - value.buf, value.len, flags); + 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); + result = setxattr(path->narrow, attribute->narrow, + value->buf, value->len, flags); else - result = lsetxattr(path.narrow, attribute.narrow, - value.buf, value.len, flags); + result = lsetxattr(path->narrow, attribute->narrow, + value->buf, value->len, flags); Py_END_ALLOW_THREADS; if (result) { - return_value = path_error(&path); - goto exit; + path_error(path); + return NULL; } - return_value = Py_None; - Py_INCREF(return_value); + Py_RETURN_NONE; +} -exit: - path_cleanup(&path); - path_cleanup(&attribute); - PyBuffer_Release(&value); - return return_value; -} +/*[clinic input] +os.removexattr + + path: path_t(allow_fd=True) + attribute: path_t + * + follow_symlinks: bool = True + +Remove extended attribute attribute on path. -PyDoc_STRVAR(posix_removexattr__doc__, -"removexattr(path, attribute, *, follow_symlinks=True)\n\n\ -Remove extended attribute attribute on path.\n\ -path may be either a string 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."); +path may be either a string 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 * -posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs) +os_removexattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, + int follow_symlinks) +/*[clinic end generated code: output=f92bb39ab992650d input=cdb54834161e3329]*/ { - path_t path; - path_t attribute; - int follow_symlinks = 1; - int result; - PyObject *return_value = NULL; - static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL}; + ssize_t result; - memset(&path, 0, sizeof(path)); - path.function_name = "removexattr"; - memset(&attribute, 0, sizeof(attribute)); - attribute.function_name = "removexattr"; - path.allow_fd = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr", - keywords, - path_converter, &path, - path_converter, &attribute, - &follow_symlinks)) + if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks)) return NULL; - if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks)) - goto exit; - Py_BEGIN_ALLOW_THREADS; - if (path.fd > -1) - result = fremovexattr(path.fd, attribute.narrow); + if (path->fd > -1) + result = fremovexattr(path->fd, attribute->narrow); else if (follow_symlinks) - result = removexattr(path.narrow, attribute.narrow); + result = removexattr(path->narrow, attribute->narrow); else - result = lremovexattr(path.narrow, attribute.narrow); + result = lremovexattr(path->narrow, attribute->narrow); Py_END_ALLOW_THREADS; if (result) { - return_value = path_error(&path); - goto exit; + return path_error(path); } - return_value = Py_None; - Py_INCREF(return_value); + Py_RETURN_NONE; +} -exit: - path_cleanup(&path); - path_cleanup(&attribute); - return return_value; -} +/*[clinic input] +os.listxattr -PyDoc_STRVAR(posix_listxattr__doc__, -"listxattr(path='.', *, follow_symlinks=True)\n\n\ -Return a list of extended attributes on path.\n\ -\n\ -path may be either None, a string, 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."); + 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, 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 * -posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs) +os_listxattr_impl(PyModuleDef *module, path_t *path, int follow_symlinks) +/*[clinic end generated code: output=a87ad6ce56e42a4f input=08cca53ac0b07c13]*/ { - path_t path; - int follow_symlinks = 1; Py_ssize_t i; PyObject *result = NULL; + const char *name; char *buffer = NULL; - char *name; - static char *keywords[] = {"path", "follow_symlinks", NULL}; - - memset(&path, 0, sizeof(path)); - path.function_name = "listxattr"; - path.allow_fd = 1; - path.fd = -1; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords, - path_converter, &path, - &follow_symlinks)) - return NULL; - if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks)) + if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks)) goto exit; - name = path.narrow ? path.narrow : "."; + name = path->narrow ? path->narrow : "."; + for (i = 0; ; i++) { char *start, *trace, *end; ssize_t length; @@ -10803,7 +10994,7 @@ posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs) Py_ssize_t buffer_size = buffer_sizes[i]; if (!buffer_size) { /* ERANGE */ - path_error(&path); + path_error(path); break; } buffer = PyMem_MALLOC(buffer_size); @@ -10813,8 +11004,8 @@ posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs) } Py_BEGIN_ALLOW_THREADS; - if (path.fd > -1) - length = flistxattr(path.fd, buffer, buffer_size); + if (path->fd > -1) + length = flistxattr(path->fd, buffer, buffer_size); else if (follow_symlinks) length = listxattr(name, buffer, buffer_size); else @@ -10827,7 +11018,7 @@ posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs) buffer = NULL; continue; } - path_error(&path); + path_error(path); break; } @@ -10860,43 +11051,43 @@ posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs) break; } exit: - path_cleanup(&path); if (buffer) PyMem_FREE(buffer); return result; } - #endif /* USE_XATTRS */ -PyDoc_STRVAR(posix_urandom__doc__, -"urandom(n) -> str\n\n\ -Return n random bytes suitable for cryptographic use."); +/*[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 * -posix_urandom(PyObject *self, PyObject *args) +os_urandom_impl(PyModuleDef *module, Py_ssize_t size) +/*[clinic end generated code: output=e0011f021501f03b input=4067cdb1b6776c29]*/ { - Py_ssize_t size; - PyObject *result; - int ret; + PyObject *bytes; + int result; - /* Read arguments */ - if (!PyArg_ParseTuple(args, "n:urandom", &size)) - return NULL; if (size < 0) return PyErr_Format(PyExc_ValueError, "negative argument not allowed"); - result = PyBytes_FromStringAndSize(NULL, size); - if (result == NULL) + bytes = PyBytes_FromStringAndSize(NULL, size); + if (bytes == NULL) return NULL; - ret = _PyOS_URandom(PyBytes_AS_STRING(result), - PyBytes_GET_SIZE(result)); - if (ret == -1) { - Py_DECREF(result); + result = _PyOS_URandom(PyBytes_AS_STRING(bytes), + PyBytes_GET_SIZE(bytes)); + if (result == -1) { + Py_DECREF(bytes); return NULL; } - return result; + return bytes; } /* Terminal size querying */ @@ -10920,6 +11111,7 @@ static PyStructSequence_Desc TerminalSize_desc = { }; #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" \ @@ -11005,13 +11197,20 @@ get_terminal_size(PyObject *self, PyObject *args) } #endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */ -PyDoc_STRVAR(posix_cpu_count__doc__, -"cpu_count() -> integer\n\n\ -Return the number of CPUs in the system, or None if this value cannot be\n\ -established."); -static PyObject * -posix_cpu_count(PyObject *self) +/*[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(PyModuleDef *module) +/*[clinic end generated code: output=c59ee7f6bce832b8 input=e7c8f4ba6dbbadd3]*/ { int ncpu = 0; #ifdef MS_WINDOWS @@ -11040,102 +11239,943 @@ posix_cpu_count(PyObject *self) Py_RETURN_NONE; } -PyDoc_STRVAR(get_inheritable__doc__, - "get_inheritable(fd) -> bool\n" \ + +/*[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(PyModuleDef *module, int fd) +/*[clinic end generated code: output=36110bb36efaa21e input=89ac008dc9ab6b95]*/ +{ + int return_value; + if (!_PyVerify_fd(fd)) { + posix_error(); + return -1; + } + + _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(PyModuleDef *module, int fd, int inheritable) +/*[clinic end generated code: output=2ac5c6ce8623f045 input=9ceaead87a1e2402]*/ +{ + int result; + if (!_PyVerify_fd(fd)) + return posix_error(); + + _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: Py_intptr_t + / + +Get the close-on-exe flag of the specified file descriptor. +[clinic start generated code]*/ + +static int +os_get_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle) +/*[clinic end generated code: output=3b7b3e1b43f312b6 input=5f7759443aae3dc5]*/ +{ + DWORD flags; + + if (!GetHandleInformation((HANDLE)handle, &flags)) { + PyErr_SetFromWindowsErr(0); + return -1; + } + + return flags & HANDLE_FLAG_INHERIT; +} + + +/*[clinic input] +os.set_handle_inheritable + handle: Py_intptr_t + inheritable: bool + / + +Set the inheritable flag of the specified handle. +[clinic start generated code]*/ + +static PyObject * +os_set_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle, + int inheritable) +/*[clinic end generated code: output=d2e111a96c9eb296 input=e64b2b2730469def]*/ +{ + 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 +PyDoc_STRVAR(get_blocking__doc__, + "get_blocking(fd) -> bool\n" \ "\n" \ - "Get the close-on-exe flag of the specified file descriptor."); + "Get the blocking mode of the file descriptor:\n" \ + "False if the O_NONBLOCK flag is set, True if the flag is cleared."); static PyObject* -posix_get_inheritable(PyObject *self, PyObject *args) +posix_get_blocking(PyObject *self, PyObject *args) { int fd; - int inheritable; + int blocking; - if (!PyArg_ParseTuple(args, "i:get_inheritable", &fd)) + if (!PyArg_ParseTuple(args, "i:get_blocking", &fd)) return NULL; if (!_PyVerify_fd(fd)) return posix_error(); - inheritable = _Py_get_inheritable(fd); - if (inheritable < 0) + _Py_BEGIN_SUPPRESS_IPH + blocking = _Py_get_blocking(fd); + _Py_END_SUPPRESS_IPH + if (blocking < 0) return NULL; - return PyBool_FromLong(inheritable); + return PyBool_FromLong(blocking); } -PyDoc_STRVAR(set_inheritable__doc__, - "set_inheritable(fd, inheritable)\n" \ +PyDoc_STRVAR(set_blocking__doc__, + "set_blocking(fd, blocking)\n" \ "\n" \ - "Set the inheritable flag of the specified file descriptor."); + "Set the blocking mode of the specified file descriptor.\n" \ + "Set the O_NONBLOCK flag if blocking is False,\n" \ + "clear the O_NONBLOCK flag otherwise."); static PyObject* -posix_set_inheritable(PyObject *self, PyObject *args) +posix_set_blocking(PyObject *self, PyObject *args) { - int fd, inheritable; + int fd, blocking, result; - if (!PyArg_ParseTuple(args, "ii:set_inheritable", &fd, &inheritable)) + if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking)) return NULL; if (!_PyVerify_fd(fd)) return posix_error(); - if (_Py_set_inheritable(fd, inheritable, NULL) < 0) + _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 */ + +PyDoc_STRVAR(posix_scandir__doc__, +"scandir(path='.') -> iterator of DirEntry objects for given path"); +static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL}; + +typedef struct { + PyObject_HEAD + PyObject *name; + PyObject *path; + PyObject *stat; + PyObject *lstat; #ifdef MS_WINDOWS -PyDoc_STRVAR(get_handle_inheritable__doc__, - "get_handle_inheritable(fd) -> bool\n" \ - "\n" \ - "Get the close-on-exe flag of the specified file descriptor."); + struct _Py_stat_struct win32_lstat; + __int64 win32_file_index; + int got_file_index; +#else /* POSIX */ +#ifdef HAVE_DIRENT_D_TYPE + unsigned char d_type; +#endif + ino_t d_ino; +#endif +} DirEntry; -static PyObject* -posix_get_handle_inheritable(PyObject *self, PyObject *args) +static void +DirEntry_dealloc(DirEntry *entry) { - Py_intptr_t handle; - DWORD flags; + 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); + +/* Set exception and return -1 on error, 0 for False, 1 for True */ +static int +DirEntry_is_symlink(DirEntry *self) +{ +#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_py_is_symlink(DirEntry *self) +{ + int result; + + result = DirEntry_is_symlink(self); + if (result == -1) + return NULL; + return PyBool_FromLong(result); +} + +static PyObject * +DirEntry_fetch_stat(DirEntry *self, int follow_symlinks) +{ + int result; + struct _Py_stat_struct st; + +#ifdef MS_WINDOWS + wchar_t *path; + + path = PyUnicode_AsUnicode(self->path); + if (!path) + return NULL; + + if (follow_symlinks) + result = win32_stat_w(path, &st); + else + result = win32_lstat_w(path, &st); + + if (result != 0) { + return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, + 0, self->path); + } +#else /* POSIX */ + PyObject *bytes; + char *path; + + if (!PyUnicode_FSConverter(self->path, &bytes)) + return NULL; + path = PyBytes_AS_STRING(bytes); + + if (follow_symlinks) + result = STAT(path, &st); + else + result = LSTAT(path, &st); + Py_DECREF(bytes); + + if (result != 0) + return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path); +#endif + + 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; +} + +static PyObject * +DirEntry_get_stat(DirEntry *self, int follow_symlinks) +{ + if (!follow_symlinks) + return DirEntry_get_lstat(self); + + if (!self->stat) { + int result = DirEntry_is_symlink(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; +} + +static PyObject * +DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs) +{ + int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat", + follow_symlinks_keywords, &follow_symlinks)) + return NULL; + + return DirEntry_get_stat(self, follow_symlinks); +} + +/* 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 = DirEntry_get_stat(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; +} + +static PyObject * +DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits) +{ + int result; + + result = DirEntry_test_mode(self, follow_symlinks, mode_bits); + if (result == -1) + return NULL; + return PyBool_FromLong(result); +} + +static PyObject * +DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs) +{ + int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir", + follow_symlinks_keywords, &follow_symlinks)) + return NULL; + + return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR); +} + +static PyObject * +DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs) +{ + int follow_symlinks = 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file", + follow_symlinks_keywords, &follow_symlinks)) + return NULL; + + return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG); +} + +static PyObject * +DirEntry_inode(DirEntry *self) +{ +#ifdef MS_WINDOWS + if (!self->got_file_index) { + wchar_t *path; + struct _Py_stat_struct stat; + + path = PyUnicode_AsUnicode(self->path); + if (!path) + return NULL; + + if (win32_lstat_w(path, &stat) != 0) { + return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, + 0, self->path); + } + + self->win32_file_index = stat.st_ino; + self->got_file_index = 1; + } + return PyLong_FromLongLong((PY_LONG_LONG)self->win32_file_index); +#else /* POSIX */ +#ifdef HAVE_LARGEFILE_SUPPORT + return PyLong_FromLongLong((PY_LONG_LONG)self->d_ino); +#else + return PyLong_FromLong((long)self->d_ino); +#endif +#endif +} + +static PyObject * +DirEntry_repr(DirEntry *self) +{ + return PyUnicode_FromFormat("", self->name); +} + +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} +}; + +static PyMethodDef DirEntry_methods[] = { + {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS, + "return True if the entry is a directory; cached per entry" + }, + {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS, + "return True if the entry is a file; cached per entry" + }, + {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS, + "return True if the entry is a symbolic link; cached per entry" + }, + {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS, + "return stat_result object for the entry; cached per entry" + }, + {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS, + "return inode of the entry; cached per entry", + }, + {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_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + (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(wchar_t *path_wide, 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; + + 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 (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR ":get_handle_inheritable", &handle)) + find_data_to_file_info_w(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(char *path_narrow, 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, 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; + + joined_path = join_path_filename(path->narrow, name, name_len); + if (!joined_path) + goto error; + + if (!path->narrow || !PyBytes_Check(path->object)) { + entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len); + entry->path = PyUnicode_DecodeFSDefault(joined_path); + } + else { + entry->name = PyBytes_FromStringAndSize(name, name_len); + entry->path = PyBytes_FromString(joined_path); + } + PyMem_Free(joined_path); + if (!entry->name || !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 +} ScandirIterator; + +#ifdef MS_WINDOWS + +static void +ScandirIterator_close(ScandirIterator *iterator) +{ + if (iterator->handle == INVALID_HANDLE_VALUE) + return; + + Py_BEGIN_ALLOW_THREADS + FindClose(iterator->handle); + Py_END_ALLOW_THREADS + iterator->handle = INVALID_HANDLE_VALUE; +} + +static PyObject * +ScandirIterator_iternext(ScandirIterator *iterator) +{ + WIN32_FIND_DATAW *file_data = &iterator->file_data; + BOOL success; + + /* Happens if the iterator is iterated twice */ + if (iterator->handle == INVALID_HANDLE_VALUE) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + + while (1) { + if (!iterator->first_time) { + Py_BEGIN_ALLOW_THREADS + success = FindNextFileW(iterator->handle, file_data); + Py_END_ALLOW_THREADS + if (!success) { + if (GetLastError() != ERROR_NO_MORE_FILES) + return path_error(&iterator->path); + /* No more files found in directory, stop iterating */ + break; + } + } + iterator->first_time = 0; + + /* Skip over . and .. */ + if (wcscmp(file_data->cFileName, L".") != 0 && + wcscmp(file_data->cFileName, L"..") != 0) + return DirEntry_from_find_data(&iterator->path, file_data); + + /* Loop till we get a non-dot directory or finish iterating */ + } + + ScandirIterator_close(iterator); + + PyErr_SetNone(PyExc_StopIteration); + return NULL; +} + +#else /* POSIX */ + +static void +ScandirIterator_close(ScandirIterator *iterator) +{ + if (!iterator->dirp) + return; + + Py_BEGIN_ALLOW_THREADS + closedir(iterator->dirp); + Py_END_ALLOW_THREADS + iterator->dirp = NULL; + return; +} + +static PyObject * +ScandirIterator_iternext(ScandirIterator *iterator) +{ + struct dirent *direntp; + Py_ssize_t name_len; + int is_dot; + + /* Happens if the iterator is iterated twice */ + if (!iterator->dirp) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + + while (1) { + errno = 0; + Py_BEGIN_ALLOW_THREADS + direntp = readdir(iterator->dirp); + Py_END_ALLOW_THREADS + + if (!direntp) { + if (errno != 0) + return path_error(&iterator->path); + /* No more files found in directory, stop iterating */ + 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) { + return DirEntry_from_posix_info(&iterator->path, direntp->d_name, + name_len, direntp->d_ino +#ifdef HAVE_DIRENT_D_TYPE + , direntp->d_type +#endif + ); + } + + /* Loop till we get a non-dot directory or finish iterating */ + } + + ScandirIterator_close(iterator); + + PyErr_SetNone(PyExc_StopIteration); + return NULL; +} + +#endif + +static void +ScandirIterator_dealloc(ScandirIterator *iterator) +{ + ScandirIterator_close(iterator); + Py_XDECREF(iterator->path.object); + path_cleanup(&iterator->path); + Py_TYPE(iterator)->tp_free((PyObject *)iterator); +} + +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_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 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 */ +}; + +static PyObject * +posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs) +{ + ScandirIterator *iterator; + static char *keywords[] = {"path", NULL}; +#ifdef MS_WINDOWS + wchar_t *path_strW; +#else + char *path; +#endif + + iterator = PyObject_New(ScandirIterator, &ScandirIteratorType); + if (!iterator) + return NULL; + memset(&iterator->path, 0, sizeof(path_t)); + iterator->path.function_name = "scandir"; + iterator->path.nullable = 1; + +#ifdef MS_WINDOWS + iterator->handle = INVALID_HANDLE_VALUE; +#else + iterator->dirp = NULL; +#endif + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords, + path_converter, &iterator->path)) + goto error; + + /* path_converter doesn't keep path.object around, so do it + manually for the lifetime of the iterator here (the refcount + is decremented in ScandirIterator_dealloc) + */ + Py_XINCREF(iterator->path.object); + +#ifdef MS_WINDOWS + if (iterator->path.narrow) { + PyErr_SetString(PyExc_TypeError, + "os.scandir() doesn't support bytes path on Windows, use Unicode instead"); + goto error; + } + 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 */ + if (iterator->path.narrow) + path = iterator->path.narrow; + else + path = "."; + + errno = 0; + Py_BEGIN_ALLOW_THREADS + iterator->dirp = opendir(path); + Py_END_ALLOW_THREADS - if (!GetHandleInformation((HANDLE)handle, &flags)) { - PyErr_SetFromWindowsErr(0); - return NULL; + if (!iterator->dirp) { + path_error(&iterator->path); + goto error; } +#endif - return PyBool_FromLong(flags & HANDLE_FLAG_INHERIT); -} - -PyDoc_STRVAR(set_handle_inheritable__doc__, - "set_handle_inheritable(fd, inheritable)\n" \ - "\n" \ - "Set the inheritable flag of the specified handle."); + return (PyObject *)iterator; -static PyObject* -posix_set_handle_inheritable(PyObject *self, PyObject *args) -{ - int inheritable = 1; - Py_intptr_t handle; - DWORD flags; +error: + Py_DECREF(iterator); + return NULL; +} - if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:set_handle_inheritable", - &handle, &inheritable)) - return NULL; - if (inheritable) - flags = HANDLE_FLAG_INHERIT; - else - flags = 0; - if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) { - PyErr_SetFromWindowsErr(0); - return NULL; - } - Py_RETURN_NONE; -} -#endif /* MS_WINDOWS */ +#include "clinic/posixmodule.c.h" +/*[clinic input] +dump buffer +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/ static PyMethodDef posix_methods[] = { @@ -11143,71 +12183,26 @@ static PyMethodDef posix_methods[] = { OS_STAT_METHODDEF OS_ACCESS_METHODDEF OS_TTYNAME_METHODDEF - - {"chdir", (PyCFunction)posix_chdir, - METH_VARARGS | METH_KEYWORDS, - posix_chdir__doc__}, -#ifdef HAVE_CHFLAGS - {"chflags", (PyCFunction)posix_chflags, - METH_VARARGS | METH_KEYWORDS, - posix_chflags__doc__}, -#endif /* HAVE_CHFLAGS */ - {"chmod", (PyCFunction)posix_chmod, - METH_VARARGS | METH_KEYWORDS, - posix_chmod__doc__}, -#ifdef HAVE_FCHMOD - {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__}, -#endif /* HAVE_FCHMOD */ -#ifdef HAVE_CHOWN - {"chown", (PyCFunction)posix_chown, - METH_VARARGS | METH_KEYWORDS, - posix_chown__doc__}, -#endif /* HAVE_CHOWN */ -#ifdef HAVE_LCHMOD - {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__}, -#endif /* HAVE_LCHMOD */ -#ifdef HAVE_FCHOWN - {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__}, -#endif /* HAVE_FCHOWN */ -#ifdef HAVE_LCHFLAGS - {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__}, -#endif /* HAVE_LCHFLAGS */ -#ifdef HAVE_LCHOWN - {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__}, -#endif /* HAVE_LCHOWN */ -#ifdef HAVE_CHROOT - {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__}, -#endif -#ifdef HAVE_CTERMID - {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__}, -#endif - {"getcwd", (PyCFunction)posix_getcwd_unicode, - METH_NOARGS, posix_getcwd__doc__}, - {"getcwdb", (PyCFunction)posix_getcwd_bytes, - METH_NOARGS, posix_getcwdb__doc__}, -#if defined(HAVE_LINK) || defined(MS_WINDOWS) - {"link", (PyCFunction)posix_link, - METH_VARARGS | METH_KEYWORDS, - posix_link__doc__}, -#endif /* HAVE_LINK */ - {"listdir", (PyCFunction)posix_listdir, - METH_VARARGS | METH_KEYWORDS, - posix_listdir__doc__}, - {"lstat", (PyCFunction)posix_lstat, - METH_VARARGS | METH_KEYWORDS, - posix_lstat__doc__}, - {"mkdir", (PyCFunction)posix_mkdir, - METH_VARARGS | METH_KEYWORDS, - posix_mkdir__doc__}, -#ifdef HAVE_NICE - {"nice", posix_nice, METH_VARARGS, posix_nice__doc__}, -#endif /* HAVE_NICE */ -#ifdef HAVE_GETPRIORITY - {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__}, -#endif /* HAVE_GETPRIORITY */ -#ifdef HAVE_SETPRIORITY - {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__}, -#endif /* HAVE_SETPRIORITY */ + 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 #ifdef HAVE_READLINK {"readlink", (PyCFunction)posix_readlink, METH_VARARGS | METH_KEYWORDS, @@ -11218,376 +12213,162 @@ static PyMethodDef posix_methods[] = { METH_VARARGS | METH_KEYWORDS, readlink__doc__}, #endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */ - {"rename", (PyCFunction)posix_rename, - METH_VARARGS | METH_KEYWORDS, - posix_rename__doc__}, - {"replace", (PyCFunction)posix_replace, - METH_VARARGS | METH_KEYWORDS, - posix_replace__doc__}, - {"rmdir", (PyCFunction)posix_rmdir, - METH_VARARGS | METH_KEYWORDS, - posix_rmdir__doc__}, + OS_RENAME_METHODDEF + OS_REPLACE_METHODDEF + OS_RMDIR_METHODDEF {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__}, -#if defined(HAVE_SYMLINK) - {"symlink", (PyCFunction)posix_symlink, - METH_VARARGS | METH_KEYWORDS, - posix_symlink__doc__}, -#endif /* HAVE_SYMLINK */ -#ifdef HAVE_SYSTEM - {"system", posix_system, METH_VARARGS, posix_system__doc__}, -#endif - {"umask", posix_umask, METH_VARARGS, posix_umask__doc__}, -#ifdef HAVE_UNAME - {"uname", posix_uname, METH_NOARGS, posix_uname__doc__}, -#endif /* HAVE_UNAME */ - {"unlink", (PyCFunction)posix_unlink, - METH_VARARGS | METH_KEYWORDS, - posix_unlink__doc__}, - {"remove", (PyCFunction)posix_unlink, - METH_VARARGS | METH_KEYWORDS, - posix_remove__doc__}, - {"utime", (PyCFunction)posix_utime, - METH_VARARGS | METH_KEYWORDS, posix_utime__doc__}, -#ifdef HAVE_TIMES - {"times", posix_times, METH_NOARGS, posix_times__doc__}, -#endif /* HAVE_TIMES */ - {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__}, -#ifdef HAVE_EXECV - {"execv", posix_execv, METH_VARARGS, posix_execv__doc__}, - {"execve", (PyCFunction)posix_execve, - METH_VARARGS | METH_KEYWORDS, - posix_execve__doc__}, -#endif /* HAVE_EXECV */ -#ifdef HAVE_SPAWNV - {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__}, - {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__}, -#endif /* HAVE_SPAWNV */ -#ifdef HAVE_FORK1 - {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__}, -#endif /* HAVE_FORK1 */ -#ifdef HAVE_FORK - {"fork", posix_fork, METH_NOARGS, posix_fork__doc__}, -#endif /* HAVE_FORK */ -#ifdef HAVE_SCHED_H -#ifdef HAVE_SCHED_GET_PRIORITY_MAX - {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__}, - {"sched_get_priority_min", posix_sched_get_priority_min, METH_VARARGS, posix_sched_get_priority_min__doc__}, -#endif -#ifdef HAVE_SCHED_SETPARAM - {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__}, -#endif -#ifdef HAVE_SCHED_SETSCHEDULER - {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__}, -#endif -#ifdef HAVE_SCHED_RR_GET_INTERVAL - {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__}, -#endif -#ifdef HAVE_SCHED_SETPARAM - {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__}, -#endif -#ifdef HAVE_SCHED_SETSCHEDULER - {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__}, -#endif - {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__}, -#ifdef HAVE_SCHED_SETAFFINITY - {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__}, - {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__}, -#endif -#endif /* HAVE_SCHED_H */ -#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) - {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__}, -#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */ -#ifdef HAVE_FORKPTY - {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__}, -#endif /* HAVE_FORKPTY */ -#ifdef HAVE_GETEGID - {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__}, -#endif /* HAVE_GETEGID */ -#ifdef HAVE_GETEUID - {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__}, -#endif /* HAVE_GETEUID */ -#ifdef HAVE_GETGID - {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__}, -#endif /* HAVE_GETGID */ + 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_EXECV_METHODDEF + OS_EXECVE_METHODDEF + OS_SPAWNV_METHODDEF + OS_SPAWNVE_METHODDEF + OS_FORK1_METHODDEF + OS_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 -#ifdef HAVE_GETGROUPS - {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__}, -#endif - {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__}, -#ifdef HAVE_GETPGRP - {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__}, -#endif /* HAVE_GETPGRP */ -#ifdef HAVE_GETPPID - {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__}, -#endif /* HAVE_GETPPID */ -#ifdef HAVE_GETUID - {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__}, -#endif /* HAVE_GETUID */ -#ifdef HAVE_GETLOGIN - {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__}, -#endif -#ifdef HAVE_KILL - {"kill", posix_kill, METH_VARARGS, posix_kill__doc__}, -#endif /* HAVE_KILL */ -#ifdef HAVE_KILLPG - {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__}, -#endif /* HAVE_KILLPG */ -#ifdef HAVE_PLOCK - {"plock", posix_plock, METH_VARARGS, posix_plock__doc__}, -#endif /* HAVE_PLOCK */ + 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 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__}, - {"kill", win32_kill, METH_VARARGS, win32_kill__doc__}, #endif -#ifdef HAVE_SETUID - {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__}, -#endif /* HAVE_SETUID */ -#ifdef HAVE_SETEUID - {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__}, -#endif /* HAVE_SETEUID */ -#ifdef HAVE_SETEGID - {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__}, -#endif /* HAVE_SETEGID */ -#ifdef HAVE_SETREUID - {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__}, -#endif /* HAVE_SETREUID */ -#ifdef HAVE_SETREGID - {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__}, -#endif /* HAVE_SETREGID */ -#ifdef HAVE_SETGID - {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__}, -#endif /* HAVE_SETGID */ -#ifdef HAVE_SETGROUPS - {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__}, -#endif /* HAVE_SETGROUPS */ + 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 */ -#ifdef HAVE_GETPGID - {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__}, -#endif /* HAVE_GETPGID */ -#ifdef HAVE_SETPGRP - {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__}, -#endif /* HAVE_SETPGRP */ -#ifdef HAVE_WAIT - {"wait", posix_wait, METH_NOARGS, posix_wait__doc__}, -#endif /* HAVE_WAIT */ -#ifdef HAVE_WAIT3 - {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__}, -#endif /* HAVE_WAIT3 */ -#ifdef HAVE_WAIT4 - {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__}, -#endif /* HAVE_WAIT4 */ -#if defined(HAVE_WAITID) && !defined(__APPLE__) - {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__}, -#endif -#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT) - {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__}, -#endif /* HAVE_WAITPID */ -#ifdef HAVE_GETSID - {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__}, -#endif /* HAVE_GETSID */ -#ifdef HAVE_SETSID - {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__}, -#endif /* HAVE_SETSID */ -#ifdef HAVE_SETPGID - {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__}, -#endif /* HAVE_SETPGID */ -#ifdef HAVE_TCGETPGRP - {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__}, -#endif /* HAVE_TCGETPGRP */ -#ifdef HAVE_TCSETPGRP - {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__}, -#endif /* HAVE_TCSETPGRP */ - {"open", (PyCFunction)posix_open,\ - METH_VARARGS | METH_KEYWORDS, - posix_open__doc__}, - {"close", posix_close, METH_VARARGS, posix_close__doc__}, - {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__}, - {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__}, - {"dup", posix_dup, METH_VARARGS, posix_dup__doc__}, - {"dup2", (PyCFunction)posix_dup2, - METH_VARARGS | METH_KEYWORDS, posix_dup2__doc__}, -#ifdef HAVE_LOCKF - {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__}, -#endif - {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__}, - {"read", posix_read, METH_VARARGS, posix_read__doc__}, -#ifdef HAVE_READV - {"readv", posix_readv, METH_VARARGS, posix_readv__doc__}, -#endif -#ifdef HAVE_PREAD - {"pread", posix_pread, METH_VARARGS, posix_pread__doc__}, -#endif - {"write", posix_write, METH_VARARGS, posix_write__doc__}, -#ifdef HAVE_WRITEV - {"writev", posix_writev, METH_VARARGS, posix_writev__doc__}, -#endif -#ifdef HAVE_PWRITE - {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__}, -#endif + 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_WRITE_METHODDEF + OS_WRITEV_METHODDEF + OS_PWRITE_METHODDEF #ifdef HAVE_SENDFILE {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS, posix_sendfile__doc__}, #endif - {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__}, - {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__}, -#ifdef HAVE_PIPE - {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__}, -#endif -#ifdef HAVE_PIPE2 - {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__}, -#endif -#ifdef HAVE_MKFIFO - {"mkfifo", (PyCFunction)posix_mkfifo, - METH_VARARGS | METH_KEYWORDS, - posix_mkfifo__doc__}, -#endif -#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) - {"mknod", (PyCFunction)posix_mknod, - METH_VARARGS | METH_KEYWORDS, - posix_mknod__doc__}, -#endif -#ifdef HAVE_DEVICE_MACROS - {"major", posix_major, METH_VARARGS, posix_major__doc__}, - {"minor", posix_minor, METH_VARARGS, posix_minor__doc__}, - {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__}, -#endif -#ifdef HAVE_FTRUNCATE - {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__}, -#endif -#ifdef HAVE_TRUNCATE - {"truncate", (PyCFunction)posix_truncate, - METH_VARARGS | METH_KEYWORDS, - posix_truncate__doc__}, -#endif -#ifdef HAVE_POSIX_FALLOCATE - {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__}, -#endif -#ifdef HAVE_POSIX_FADVISE - {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__}, -#endif -#ifdef HAVE_PUTENV - {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__}, -#endif -#ifdef HAVE_UNSETENV - {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__}, -#endif - {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__}, -#ifdef HAVE_FCHDIR - {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__}, -#endif -#ifdef HAVE_FSYNC - {"fsync", posix_fsync, METH_O, posix_fsync__doc__}, -#endif -#ifdef HAVE_SYNC - {"sync", posix_sync, METH_NOARGS, posix_sync__doc__}, -#endif -#ifdef HAVE_FDATASYNC - {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__}, -#endif -#ifdef HAVE_SYS_WAIT_H -#ifdef WCOREDUMP - {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__}, -#endif /* WCOREDUMP */ -#ifdef WIFCONTINUED - {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__}, -#endif /* WIFCONTINUED */ -#ifdef WIFSTOPPED - {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__}, -#endif /* WIFSTOPPED */ -#ifdef WIFSIGNALED - {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__}, -#endif /* WIFSIGNALED */ -#ifdef WIFEXITED - {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__}, -#endif /* WIFEXITED */ -#ifdef WEXITSTATUS - {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__}, -#endif /* WEXITSTATUS */ -#ifdef WTERMSIG - {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__}, -#endif /* WTERMSIG */ -#ifdef WSTOPSIG - {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__}, -#endif /* WSTOPSIG */ -#endif /* HAVE_SYS_WAIT_H */ -#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) - {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__}, -#endif -#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) - {"statvfs", (PyCFunction)posix_statvfs, - METH_VARARGS | METH_KEYWORDS, - posix_statvfs__doc__}, -#endif -#ifdef HAVE_CONFSTR - {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__}, -#endif -#ifdef HAVE_SYSCONF - {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__}, -#endif -#ifdef HAVE_FPATHCONF - {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__}, -#endif -#ifdef HAVE_PATHCONF - {"pathconf", (PyCFunction)posix_pathconf, - METH_VARARGS | METH_KEYWORDS, - posix_pathconf__doc__}, -#endif - {"abort", posix_abort, METH_NOARGS, posix_abort__doc__}, -#ifdef MS_WINDOWS - {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL}, - {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL}, - {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__}, - {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__}, - {"_getvolumepathname", posix__getvolumepathname, METH_VARARGS, posix__getvolumepathname__doc__}, -#endif -#ifdef HAVE_GETLOADAVG - {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__}, -#endif - {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__}, -#ifdef HAVE_SETRESUID - {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__}, -#endif -#ifdef HAVE_SETRESGID - {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__}, -#endif -#ifdef HAVE_GETRESUID - {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__}, -#endif -#ifdef HAVE_GETRESGID - {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__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__ISDIR_METHODDEF + OS__GETDISKUSAGE_METHODDEF + OS__GETFINALPATHNAME_METHODDEF + OS__GETVOLUMEPATHNAME_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 -#ifdef USE_XATTRS - {"setxattr", (PyCFunction)posix_setxattr, - METH_VARARGS | METH_KEYWORDS, - posix_setxattr__doc__}, - {"getxattr", (PyCFunction)posix_getxattr, - METH_VARARGS | METH_KEYWORDS, - posix_getxattr__doc__}, - {"removexattr", (PyCFunction)posix_removexattr, - METH_VARARGS | METH_KEYWORDS, - posix_removexattr__doc__}, - {"listxattr", (PyCFunction)posix_listxattr, - METH_VARARGS | METH_KEYWORDS, - posix_listxattr__doc__}, -#endif #if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__}, #endif - {"cpu_count", (PyCFunction)posix_cpu_count, - METH_NOARGS, posix_cpu_count__doc__}, - {"get_inheritable", posix_get_inheritable, METH_VARARGS, get_inheritable__doc__}, - {"set_inheritable", posix_set_inheritable, METH_VARARGS, set_inheritable__doc__}, -#ifdef MS_WINDOWS - {"get_handle_inheritable", posix_get_handle_inheritable, - METH_VARARGS, get_handle_inheritable__doc__}, - {"set_handle_inheritable", posix_set_handle_inheritable, - METH_VARARGS, set_handle_inheritable__doc__}, + 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 + {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__}, + {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__}, #endif + {"scandir", (PyCFunction)posix_scandir, + METH_VARARGS | METH_KEYWORDS, + posix_scandir__doc__}, {NULL, NULL} /* Sentinel */ }; @@ -11858,6 +12639,35 @@ all_ins(PyObject *m) 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; @@ -12001,15 +12811,6 @@ all_ins(PyObject *m) } -#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__) -#define INITFUNC PyInit_nt -#define MODNAME "nt" - -#else -#define INITFUNC PyInit_posix -#define MODNAME "posix" -#endif - static struct PyModuleDef posixmodule = { PyModuleDef_HEAD_INIT, MODNAME, @@ -12069,7 +12870,7 @@ static char *have_functions[] = { "HAVE_FSTATVFS", #endif -#ifdef HAVE_FTRUNCATE +#if defined HAVE_FTRUNCATE || defined MS_WINDOWS "HAVE_FTRUNCATE", #endif @@ -12223,13 +13024,19 @@ INITFUNC(void) sched_param_desc.name = MODNAME ".sched_param"; if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0) return NULL; - SchedParamType.tp_new = sched_param_new; + SchedParamType.tp_new = os_sched_param; #endif /* initialize TerminalSize_info */ if (PyStructSequence_InitType2(&TerminalSizeType, &TerminalSize_desc) < 0) 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); diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c index 99094004411f..281c30b26ee8 100644 --- a/Modules/pwdmodule.c +++ b/Modules/pwdmodule.c @@ -6,6 +6,12 @@ #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"}, @@ -69,18 +75,10 @@ mkpwent(struct passwd *p) #define SETS(i,val) sets(v, i, val) SETS(setIndex++, p->pw_name); -#ifdef __VMS - SETS(setIndex++, ""); -#else SETS(setIndex++, p->pw_passwd); -#endif PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid)); PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid)); -#ifdef __VMS - SETS(setIndex++, ""); -#else SETS(setIndex++, p->pw_gecos); -#endif SETS(setIndex++, p->pw_dir); SETS(setIndex++, p->pw_shell); @@ -95,18 +93,25 @@ mkpwent(struct passwd *p) return v; } -PyDoc_STRVAR(pwd_getpwuid__doc__, -"getpwuid(uid) -> (pw_name,pw_passwd,pw_uid,\n\ - pw_gid,pw_gecos,pw_dir,pw_shell)\n\ -Return the password database entry for the given numeric user ID.\n\ -See help(pwd) for more on password database entries."); +/*[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 *self, PyObject *args) +pwd_getpwuid(PyModuleDef *module, PyObject *uidobj) +/*[clinic end generated code: output=cba29ae4c2bcb8e1 input=ae64d507a1c6d3e8]*/ { uid_t uid; struct passwd *p; - if (!PyArg_ParseTuple(args, "O&:getpwuid", _Py_Uid_Converter, &uid)) { + + if (!_Py_Uid_Converter(uidobj, &uid)) { if (PyErr_ExceptionMatches(PyExc_OverflowError)) PyErr_Format(PyExc_KeyError, "getpwuid(): uid not found"); @@ -124,21 +129,25 @@ pwd_getpwuid(PyObject *self, PyObject *args) return mkpwent(p); } -PyDoc_STRVAR(pwd_getpwnam__doc__, -"getpwnam(name) -> (pw_name,pw_passwd,pw_uid,\n\ - pw_gid,pw_gecos,pw_dir,pw_shell)\n\ -Return the password database entry for the given user name.\n\ -See help(pwd) for more on password database entries."); +/*[clinic input] +pwd.getpwnam + + arg: 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(PyObject *self, PyObject *args) +pwd_getpwnam_impl(PyModuleDef *module, PyObject *arg) +/*[clinic end generated code: output=66848d42d386fca3 input=d5f7e700919b02d3]*/ { char *name; struct passwd *p; - PyObject *arg, *bytes, *retval = NULL; + PyObject *bytes, *retval = NULL; - if (!PyArg_ParseTuple(args, "U:getpwnam", &arg)) - return NULL; if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL) return NULL; if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1) @@ -155,14 +164,17 @@ pwd_getpwnam(PyObject *self, PyObject *args) } #ifdef HAVE_GETPWENT -PyDoc_STRVAR(pwd_getpwall__doc__, -"getpwall() -> list_of_entries\n\ -Return a list of all available password database entries, \ -in arbitrary order.\n\ -See help(pwd) for more on password database entries."); +/*[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(PyObject *self) +pwd_getpwall_impl(PyModuleDef *module) +/*[clinic end generated code: output=ab30e37bf26d431d input=d7ecebfd90219b85]*/ { PyObject *d; struct passwd *p; @@ -185,11 +197,10 @@ pwd_getpwall(PyObject *self) #endif static PyMethodDef pwd_methods[] = { - {"getpwuid", pwd_getpwuid, METH_VARARGS, pwd_getpwuid__doc__}, - {"getpwnam", pwd_getpwnam, METH_VARARGS, pwd_getpwnam__doc__}, + PWD_GETPWUID_METHODDEF + PWD_GETPWNAM_METHODDEF #ifdef HAVE_GETPWENT - {"getpwall", (PyCFunction)pwd_getpwall, - METH_NOARGS, pwd_getpwall__doc__}, + PWD_GETPWALL_METHODDEF #endif {NULL, NULL} /* sentinel */ }; diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index 3f51c12cebce..9a6da737fb36 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -6,9 +6,14 @@ #include "pyexpat.h" -#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION) +/* 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 FIX_TRACE +#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}; @@ -63,6 +68,8 @@ typedef struct { PyObject **handlers; } xmlparseobject; +#include "clinic/pyexpat.c.h" + #define CHARACTER_DATA_BUFFER_SIZE 8192 static PyTypeObject Xmlparsetype; @@ -210,122 +217,17 @@ flag_error(xmlparseobject *self) error_external_entity_ref_handler); } -static PyCodeObject* -getcode(enum HandlerTypes slot, char* func_name, int lineno) -{ - if (handler_info[slot].tb_code == NULL) { - handler_info[slot].tb_code = - PyCode_NewEmpty(__FILE__, func_name, lineno); - } - return handler_info[slot].tb_code; -} - -#ifdef FIX_TRACE -static int -trace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val) -{ - int result = 0; - if (!tstate->use_tracing || tstate->tracing) - return 0; - if (tstate->c_profilefunc != NULL) { - tstate->tracing++; - result = tstate->c_profilefunc(tstate->c_profileobj, - f, code , val); - tstate->use_tracing = ((tstate->c_tracefunc != NULL) - || (tstate->c_profilefunc != NULL)); - tstate->tracing--; - if (result) - return result; - } - if (tstate->c_tracefunc != NULL) { - tstate->tracing++; - result = tstate->c_tracefunc(tstate->c_traceobj, - f, code , val); - tstate->use_tracing = ((tstate->c_tracefunc != NULL) - || (tstate->c_profilefunc != NULL)); - tstate->tracing--; - } - return result; -} - -static int -trace_frame_exc(PyThreadState *tstate, PyFrameObject *f) -{ - PyObject *type, *value, *traceback, *arg; - int err; - - if (tstate->c_tracefunc == NULL) - return 0; - - PyErr_Fetch(&type, &value, &traceback); - if (value == NULL) { - value = Py_None; - Py_INCREF(value); - } - arg = PyTuple_Pack(3, type, value, traceback); - if (arg == NULL) { - PyErr_Restore(type, value, traceback); - return 0; - } - err = trace_frame(tstate, f, PyTrace_EXCEPTION, arg); - Py_DECREF(arg); - if (err == 0) - PyErr_Restore(type, value, traceback); - else { - Py_XDECREF(type); - Py_XDECREF(value); - Py_XDECREF(traceback); - } - return err; -} -#endif - static PyObject* -call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args, +call_with_frame(char *funcname, int lineno, PyObject* func, PyObject* args, xmlparseobject *self) { - PyThreadState *tstate = PyThreadState_GET(); - PyFrameObject *f; - PyObject *res, *globals; - - if (c == NULL) - return NULL; + PyObject *res; - globals = PyEval_GetGlobals(); - if (globals == NULL) { - return NULL; - } - - f = PyFrame_New(tstate, c, globals, NULL); - if (f == NULL) - return NULL; - tstate->frame = f; -#ifdef FIX_TRACE - if (trace_frame(tstate, f, PyTrace_CALL, Py_None) < 0) { - return NULL; - } -#endif res = PyEval_CallObject(func, args); if (res == NULL) { - if (tstate->curexc_traceback == NULL) - PyTraceBack_Here(f); + _PyTraceback_Add(funcname, __FILE__, lineno); XML_StopParser(self->itself, XML_FALSE); -#ifdef FIX_TRACE - if (trace_frame_exc(tstate, f) < 0) { - return NULL; - } - } - else { - if (trace_frame(tstate, f, PyTrace_RETURN, res) < 0) { - Py_XDECREF(res); - res = NULL; - } } -#else - } -#endif - tstate->frame = f->f_back; - Py_DECREF(f); return res; } @@ -377,7 +279,7 @@ call_character_handler(xmlparseobject *self, const XML_Char *buffer, int len) PyTuple_SET_ITEM(args, 0, temp); /* temp is now a borrowed reference; consider it unused. */ self->in_callback = 1; - temp = call_with_frame(getcode(CharacterData, "CharacterData", __LINE__), + temp = call_with_frame("CharacterData", __LINE__, self->handlers[CharacterData], args, self); /* temp is an owned reference again, or NULL */ self->in_callback = 0; @@ -509,7 +411,7 @@ my_StartElementHandler(void *userData, } /* Container is now a borrowed reference; ignore it. */ self->in_callback = 1; - rv = call_with_frame(getcode(StartElement, "StartElement", __LINE__), + rv = call_with_frame("StartElement", __LINE__, self->handlers[StartElement], args, self); self->in_callback = 0; Py_DECREF(args); @@ -538,7 +440,7 @@ my_##NAME##Handler PARAMS {\ args = Py_BuildValue PARAM_FORMAT ;\ if (!args) { flag_error(self); return RETURN;} \ self->in_callback = 1; \ - rv = call_with_frame(getcode(NAME,#NAME,__LINE__), \ + rv = call_with_frame(#NAME,__LINE__, \ self->handlers[NAME], args, self); \ self->in_callback = 0; \ Py_DECREF(args); \ @@ -670,7 +572,7 @@ my_ElementDeclHandler(void *userData, goto finally; } self->in_callback = 1; - rv = call_with_frame(getcode(ElementDecl, "ElementDecl", __LINE__), + rv = call_with_frame("ElementDecl", __LINE__, self->handlers[ElementDecl], args, self); self->in_callback = 0; if (rv == NULL) { @@ -778,6 +680,11 @@ VOID_HANDLER(StartDoctypeDecl, 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) @@ -794,25 +701,30 @@ get_parse_result(xmlparseobject *self, int rv) return PyLong_FromLong(rv); } -PyDoc_STRVAR(xmlparse_Parse__doc__, -"Parse(data[, isfinal])\n\ -Parse XML data. `isfinal' should be true at end of input."); - #define MAX_CHUNK_SIZE (1 << 20) +/*[clinic input] +pyexpat.xmlparser.Parse + + data: object + isfinal: int(c_default="0") = False + / + +Parse XML data. + +`isfinal' should be true at end of input. +[clinic start generated code]*/ + static PyObject * -xmlparse_Parse(xmlparseobject *self, PyObject *args) +pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyObject *data, + int isfinal) +/*[clinic end generated code: output=f4db843dd1f4ed4b input=199d9e8e92ebbb4b]*/ { - PyObject *data; - int isFinal = 0; const char *s; Py_ssize_t slen; Py_buffer view; int rc; - if (!PyArg_ParseTuple(args, "O|i:Parse", &data, &isFinal)) - return NULL; - if (PyUnicode_Check(data)) { view.buf = NULL; s = PyUnicode_AsUTF8AndSize(data, &slen); @@ -836,7 +748,7 @@ xmlparse_Parse(xmlparseobject *self, PyObject *args) slen -= MAX_CHUNK_SIZE; } assert(MAX_CHUNK_SIZE < INT_MAX && slen < INT_MAX); - rc = XML_Parse(self->itself, s, (int)slen, isFinal); + rc = XML_Parse(self->itself, s, (int)slen, isfinal); done: if (view.buf != NULL) @@ -887,18 +799,24 @@ readinst(char *buf, int buf_size, PyObject *meth) return -1; } -PyDoc_STRVAR(xmlparse_ParseFile__doc__, -"ParseFile(file)\n\ -Parse XML data from file-like object."); +/*[clinic input] +pyexpat.xmlparser.ParseFile + + file: object + / + +Parse XML data from file-like object. +[clinic start generated code]*/ static PyObject * -xmlparse_ParseFile(xmlparseobject *self, PyObject *f) +pyexpat_xmlparser_ParseFile(xmlparseobject *self, PyObject *file) +/*[clinic end generated code: output=2adc6a13100cc42b input=fbb5a12b6038d735]*/ { int rv = 1; PyObject *readmethod = NULL; _Py_IDENTIFIER(read); - readmethod = _PyObject_GetAttrId(f, &PyId_read); + readmethod = _PyObject_GetAttrId(file, &PyId_read); if (readmethod == NULL) { PyErr_SetString(PyExc_TypeError, "argument must have 'read' attribute"); @@ -909,7 +827,7 @@ xmlparse_ParseFile(xmlparseobject *self, PyObject *f) void *buf = XML_GetBuffer(self->itself, BUF_SIZE); if (buf == NULL) { Py_XDECREF(readmethod); - return PyErr_NoMemory(); + return get_parse_result(self, 0); } bytes_read = readinst(buf, BUF_SIZE, readmethod); @@ -930,42 +848,50 @@ xmlparse_ParseFile(xmlparseobject *self, PyObject *f) return get_parse_result(self, rv); } -PyDoc_STRVAR(xmlparse_SetBase__doc__, -"SetBase(base_url)\n\ -Set the base URL for the parser."); +/*[clinic input] +pyexpat.xmlparser.SetBase + + base: str + / + +Set the base URL for the parser. +[clinic start generated code]*/ static PyObject * -xmlparse_SetBase(xmlparseobject *self, PyObject *args) +pyexpat_xmlparser_SetBase_impl(xmlparseobject *self, const char *base) +/*[clinic end generated code: output=c212ddceb607b539 input=c684e5de895ee1a8]*/ { - char *base; - - if (!PyArg_ParseTuple(args, "s:SetBase", &base)) - return NULL; if (!XML_SetBase(self->itself, base)) { return PyErr_NoMemory(); } - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(xmlparse_GetBase__doc__, -"GetBase() -> url\n\ -Return base URL string for the parser."); +/*[clinic input] +pyexpat.xmlparser.GetBase + +Return base URL string for the parser. +[clinic start generated code]*/ static PyObject * -xmlparse_GetBase(xmlparseobject *self, PyObject *unused) +pyexpat_xmlparser_GetBase_impl(xmlparseobject *self) +/*[clinic end generated code: output=2886cb21f9a8739a input=918d71c38009620e]*/ { return Py_BuildValue("z", XML_GetBase(self->itself)); } -PyDoc_STRVAR(xmlparse_GetInputContext__doc__, -"GetInputContext() -> string\n\ -Return the untranslated text of the input that caused the current event.\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."); +/*[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 * -xmlparse_GetInputContext(xmlparseobject *self, PyObject *unused) +pyexpat_xmlparser_GetInputContext_impl(xmlparseobject *self) +/*[clinic end generated code: output=a88026d683fc22cc input=034df8712db68379]*/ { if (self->in_callback) { int offset, size; @@ -982,24 +908,25 @@ xmlparse_GetInputContext(xmlparseobject *self, PyObject *unused) Py_RETURN_NONE; } -PyDoc_STRVAR(xmlparse_ExternalEntityParserCreate__doc__, -"ExternalEntityParserCreate(context[, encoding])\n\ -Create a parser for parsing an external entity based on the\n\ -information passed to the ExternalEntityRefHandler."); +/*[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 * -xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args) +pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, + const char *context, + const char *encoding) +/*[clinic end generated code: output=535cda9d7a0fbcd6 input=b906714cc122c322]*/ { - char *context; - char *encoding = NULL; xmlparseobject *new_parser; int i; - if (!PyArg_ParseTuple(args, "z|s:ExternalEntityParserCreate", - &context, &encoding)) { - return NULL; - } - new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype); if (new_parser == NULL) return NULL; @@ -1035,7 +962,7 @@ xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args) for (i = 0; handler_info[i].name != NULL; i++) /* do nothing */; - new_parser->handlers = PyMem_Malloc(sizeof(PyObject *) * i); + new_parser->handlers = PyMem_New(PyObject *, i); if (!new_parser->handlers) { Py_DECREF(new_parser); return PyErr_NoMemory(); @@ -1055,41 +982,49 @@ xmlparse_ExternalEntityParserCreate(xmlparseobject *self, PyObject *args) return (PyObject *)new_parser; } -PyDoc_STRVAR(xmlparse_SetParamEntityParsing__doc__, -"SetParamEntityParsing(flag) -> success\n\ -Controls parsing of parameter entities (including the external DTD\n\ -subset). 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."); +/*[clinic input] +pyexpat.xmlparser.SetParamEntityParsing -static PyObject* -xmlparse_SetParamEntityParsing(xmlparseobject *p, PyObject* args) + 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]*/ { - int flag; - if (!PyArg_ParseTuple(args, "i", &flag)) - return NULL; - flag = XML_SetParamEntityParsing(p->itself, flag); + flag = XML_SetParamEntityParsing(self->itself, flag); return PyLong_FromLong(flag); } #if XML_COMBINED_VERSION >= 19505 -PyDoc_STRVAR(xmlparse_UseForeignDTD__doc__, -"UseForeignDTD([flag])\n\ -Allows the application to provide an artificial external subset if one is\n\ -not specified as part of the document instance. This readily allows the\n\ -use of a 'default' document type controlled by the application, while still\n\ -getting the advantage of providing document type information to the parser.\n\ -'flag' defaults to True if not provided."); +/*[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 * -xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args) +pyexpat_xmlparser_UseForeignDTD_impl(xmlparseobject *self, int flag) +/*[clinic end generated code: output=cfaa9aa50bb0f65c input=78144c519d116a6e]*/ { - int flag = 1; enum XML_Error rc; - if (!PyArg_ParseTuple(args, "|p:UseForeignDTD", &flag)) - return NULL; + rc = XML_UseForeignDTD(self->itself, flag ? XML_TRUE : XML_FALSE); if (rc != XML_ERROR_NONE) { return set_error(self, rc); @@ -1099,29 +1034,70 @@ xmlparse_UseForeignDTD(xmlparseobject *self, PyObject *args) } #endif -static PyObject *xmlparse_dir(PyObject *self, PyObject* noargs); +/*[clinic input] +pyexpat.xmlparser.__dir__ +[clinic start generated code]*/ + +static PyObject * +pyexpat_xmlparser___dir___impl(xmlparseobject *self) +/*[clinic end generated code: output=bc22451efb9e4d17 input=76aa455f2a661384]*/ +{ +#define APPEND(list, str) \ + do { \ + PyObject *o = PyUnicode_FromString(str); \ + if (o != NULL) \ + PyList_Append(list, o); \ + Py_XDECREF(o); \ + } while (0) + + int i; + PyObject *rc = PyList_New(0); + if (!rc) + return NULL; + for (i = 0; handler_info[i].name != NULL; i++) { + PyObject *o = get_handler_name(&handler_info[i]); + if (o != NULL) + PyList_Append(rc, o); + Py_XDECREF(o); + } + APPEND(rc, "ErrorCode"); + APPEND(rc, "ErrorLineNumber"); + APPEND(rc, "ErrorColumnNumber"); + APPEND(rc, "ErrorByteIndex"); + APPEND(rc, "CurrentLineNumber"); + APPEND(rc, "CurrentColumnNumber"); + APPEND(rc, "CurrentByteIndex"); + APPEND(rc, "buffer_size"); + APPEND(rc, "buffer_text"); + APPEND(rc, "buffer_used"); + APPEND(rc, "namespace_prefixes"); + APPEND(rc, "ordered_attributes"); + APPEND(rc, "specified_attributes"); + APPEND(rc, "intern"); + +#undef APPEND + + if (PyErr_Occurred()) { + Py_DECREF(rc); + rc = NULL; + } + + return rc; +} static struct PyMethodDef xmlparse_methods[] = { - {"Parse", (PyCFunction)xmlparse_Parse, - METH_VARARGS, xmlparse_Parse__doc__}, - {"ParseFile", (PyCFunction)xmlparse_ParseFile, - METH_O, xmlparse_ParseFile__doc__}, - {"SetBase", (PyCFunction)xmlparse_SetBase, - METH_VARARGS, xmlparse_SetBase__doc__}, - {"GetBase", (PyCFunction)xmlparse_GetBase, - METH_NOARGS, xmlparse_GetBase__doc__}, - {"ExternalEntityParserCreate", (PyCFunction)xmlparse_ExternalEntityParserCreate, - METH_VARARGS, xmlparse_ExternalEntityParserCreate__doc__}, - {"SetParamEntityParsing", (PyCFunction)xmlparse_SetParamEntityParsing, - METH_VARARGS, xmlparse_SetParamEntityParsing__doc__}, - {"GetInputContext", (PyCFunction)xmlparse_GetInputContext, - METH_NOARGS, xmlparse_GetInputContext__doc__}, + 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 - {"UseForeignDTD", (PyCFunction)xmlparse_UseForeignDTD, - METH_VARARGS, xmlparse_UseForeignDTD__doc__}, + PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF #endif - {"__dir__", xmlparse_dir, METH_NOARGS}, - {NULL, NULL} /* sentinel */ + PYEXPAT_XMLPARSER___DIR___METHODDEF + {NULL, NULL} /* sentinel */ }; /* ---------- */ @@ -1184,7 +1160,7 @@ PyUnknownEncodingHandler(void *encodingHandlerData, static PyObject * -newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern) +newxmlparseobject(const char *encoding, const char *namespace_separator, PyObject *intern) { int i; xmlparseobject *self; @@ -1228,7 +1204,7 @@ newxmlparseobject(char *encoding, char *namespace_separator, PyObject *intern) for (i = 0; handler_info[i].name != NULL; i++) /* do nothing */; - self->handlers = PyMem_Malloc(sizeof(PyObject *) * i); + self->handlers = PyMem_New(PyObject *, i); if (!self->handlers) { Py_DECREF(self); return PyErr_NoMemory(); @@ -1362,52 +1338,6 @@ xmlparse_getattro(xmlparseobject *self, PyObject *nameobj) return PyObject_GenericGetAttr((PyObject*)self, nameobj); } -static PyObject * -xmlparse_dir(PyObject *self, PyObject* noargs) -{ -#define APPEND(list, str) \ - do { \ - PyObject *o = PyUnicode_FromString(str); \ - if (o != NULL) \ - PyList_Append(list, o); \ - Py_XDECREF(o); \ - } while (0) - - int i; - PyObject *rc = PyList_New(0); - if (!rc) - return NULL; - for (i = 0; handler_info[i].name != NULL; i++) { - PyObject *o = get_handler_name(&handler_info[i]); - if (o != NULL) - PyList_Append(rc, o); - Py_XDECREF(o); - } - APPEND(rc, "ErrorCode"); - APPEND(rc, "ErrorLineNumber"); - APPEND(rc, "ErrorColumnNumber"); - APPEND(rc, "ErrorByteIndex"); - APPEND(rc, "CurrentLineNumber"); - APPEND(rc, "CurrentColumnNumber"); - APPEND(rc, "CurrentByteIndex"); - APPEND(rc, "buffer_size"); - APPEND(rc, "buffer_text"); - APPEND(rc, "buffer_used"); - APPEND(rc, "namespace_prefixes"); - APPEND(rc, "ordered_attributes"); - APPEND(rc, "specified_attributes"); - APPEND(rc, "intern"); - -#undef APPEND - - if (PyErr_Occurred()) { - Py_DECREF(rc); - rc = NULL; - } - - return rc; -} - static int sethandler(xmlparseobject *self, PyObject *name, PyObject* v) { @@ -1448,11 +1378,16 @@ static int xmlparse_setattro(xmlparseobject *self, PyObject *name, PyObject *v) { /* Set attribute 'name' to value 'v'. v==NULL means delete */ + if (!PyUnicode_Check(name)) { + PyErr_Format(PyExc_TypeError, + "attribute name must be string, not '%.200s'", + name->ob_type->tp_name); + return -1; + } if (v == NULL) { PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute"); return -1; } - assert(PyUnicode_Check(name)); if (PyUnicode_CompareWithASCIIString(name, "buffer_text") == 0) { int b = PyObject_IsTrue(v); if (b < 0) @@ -1505,17 +1440,18 @@ xmlparse_setattro(xmlparseobject *self, PyObject *name, PyObject *v) return -1; } - new_buffer_size=PyLong_AS_LONG(v); + 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; } - if (new_buffer_size <= 0) { - PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than zero"); - return -1; - } - /* check maximum */ if (new_buffer_size > INT_MAX) { char errmsg[100]; @@ -1613,24 +1549,24 @@ static PyTypeObject Xmlparsetype = { /* End of code for xmlparser objects */ /* -------------------------------------------------------- */ -PyDoc_STRVAR(pyexpat_ParserCreate__doc__, -"ParserCreate([encoding[, namespace_separator]]) -> parser\n\ -Return a new XML parser object."); +/*[clinic input] +pyexpat.ParserCreate + + encoding: str(accept={str, NoneType}) = NULL + namespace_separator: str(accept={str, NoneType}) = NULL + intern: object = NULL + +Return a new XML parser object. +[clinic start generated code]*/ static PyObject * -pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw) +pyexpat_ParserCreate_impl(PyModuleDef *module, const char *encoding, + const char *namespace_separator, PyObject *intern) +/*[clinic end generated code: output=81fccd233e1743a8 input=23d29704acad385d]*/ { - char *encoding = NULL; - char *namespace_separator = NULL; - PyObject *intern = NULL; PyObject *result; int intern_decref = 0; - static char *kwlist[] = {"encoding", "namespace_separator", - "intern", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kw, "|zzO:ParserCreate", kwlist, - &encoding, &namespace_separator, &intern)) - return NULL; if (namespace_separator != NULL && strlen(namespace_separator) > 1) { PyErr_SetString(PyExc_ValueError, @@ -1660,29 +1596,28 @@ pyexpat_ParserCreate(PyObject *notused, PyObject *args, PyObject *kw) return result; } -PyDoc_STRVAR(pyexpat_ErrorString__doc__, -"ErrorString(errno) -> string\n\ -Returns string error for given number."); +/*[clinic input] +pyexpat.ErrorString + + code: long + / + +Returns string error for given number. +[clinic start generated code]*/ static PyObject * -pyexpat_ErrorString(PyObject *self, PyObject *args) +pyexpat_ErrorString_impl(PyModuleDef *module, long code) +/*[clinic end generated code: output=d87668108b6868e5 input=cc67de010d9e62b3]*/ { - long code = 0; - - if (!PyArg_ParseTuple(args, "l:ErrorString", &code)) - return NULL; return Py_BuildValue("z", XML_ErrorString((int)code)); } /* List of methods defined in the module */ static struct PyMethodDef pyexpat_methods[] = { - {"ParserCreate", (PyCFunction)pyexpat_ParserCreate, - METH_VARARGS|METH_KEYWORDS, pyexpat_ParserCreate__doc__}, - {"ErrorString", (PyCFunction)pyexpat_ErrorString, - METH_VARARGS, pyexpat_ErrorString__doc__}, - - {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */ + PYEXPAT_PARSERCREATE_METHODDEF + PYEXPAT_ERRORSTRING_METHODDEF + {NULL, NULL} /* sentinel */ }; /* Module docstring */ @@ -1700,16 +1635,6 @@ PyDoc_STRVAR(pyexpat_module_documentation, #define MODULE_INITFUNC PyInit_pyexpat #endif -#ifndef PyMODINIT_FUNC -# ifdef MS_WINDOWS -# define PyMODINIT_FUNC __declspec(dllexport) void -# else -# define PyMODINIT_FUNC void -# endif -#endif - -PyMODINIT_FUNC MODULE_INITFUNC(void); /* avoid compiler warnings */ - static struct PyModuleDef pyexpatmodule = { PyModuleDef_HEAD_INIT, MODULE_NAME, @@ -1767,7 +1692,7 @@ MODULE_INITFUNC(void) PyModule_AddObject(m, "XMLParserType", (PyObject *) &Xmlparsetype); PyModule_AddStringConstant(m, "EXPAT_VERSION", - (char *) XML_ExpatVersion()); + XML_ExpatVersion()); { XML_Expat_Version info = XML_ExpatVersionInfo(); PyModule_AddObject(m, "version_info", @@ -1847,7 +1772,7 @@ MODULE_INITFUNC(void) #define MYCONST(name) \ if (PyModule_AddStringConstant(errors_module, #name, \ - (char *)XML_ErrorString(name)) < 0) \ + XML_ErrorString(name)) < 0) \ return NULL; \ tmpnum = PyLong_FromLong(name); \ if (tmpnum == NULL) return NULL; \ @@ -2058,3 +1983,8 @@ static struct HandlerInfo handler_info[] = { {NULL, NULL, NULL} /* sentinel */ }; + +/*[clinic input] +dump buffer +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/ diff --git a/Modules/readline.c b/Modules/readline.c index f255a8747f9f..451a6ed6729e 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -237,6 +237,43 @@ 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_IOError); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(doc_append_history_file, +"append_history_file(nelements[, filename]) -> None\n\ +Append the last nelements of the history list to file.\n\ +The default filename is ~/.history."); +#endif + + /* Set history length */ static PyObject* @@ -281,8 +318,7 @@ set_hook(const char *funcname, PyObject **hook_var, PyObject *args) if (!PyArg_ParseTuple(args, buf, &function)) return NULL; if (function == Py_None) { - Py_XDECREF(*hook_var); - *hook_var = NULL; + Py_CLEAR(*hook_var); } else if (PyCallable_Check(function)) { PyObject *tmp = *hook_var; @@ -428,10 +464,11 @@ set_completer_delims(PyObject *self, PyObject *args) /* 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). */ - free(completer_word_break_characters); - completer_word_break_characters = strdup(break_chars); - if (completer_word_break_characters) { - rl_completer_word_break_characters = completer_word_break_characters; + break_chars = strdup(break_chars); + 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 @@ -748,6 +785,10 @@ static struct PyMethodDef readline_methods[] = 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, @@ -800,7 +841,7 @@ on_hook(PyObject *func) if (r == Py_None) result = 0; else { - result = PyLong_AsLong(r); + result = _PyLong_AsInt(r); if (result == -1 && PyErr_Occurred()) goto error; } @@ -816,7 +857,11 @@ on_hook(PyObject *func) } static int +#if defined(_RL_FUNCTION_TYPEDEF) on_startup_hook(void) +#else +on_startup_hook() +#endif { int r; #ifdef WITH_THREAD @@ -831,7 +876,11 @@ on_startup_hook(void) #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; #ifdef WITH_THREAD @@ -877,7 +926,7 @@ on_completion_display_matches_hook(char **matches, (r != Py_None && PyLong_AsLong(r) == -1 && PyErr_Occurred())) { goto error; } - Py_XDECREF(r); r=NULL; + Py_CLEAR(r); if (0) { error: @@ -935,7 +984,7 @@ on_completion(const char *text, int state) * before calling the normal completer */ static char ** -flex_complete(char *text, int start, int end) +flex_complete(const char *text, int start, int end) { char **result; #ifdef WITH_THREAD @@ -998,12 +1047,12 @@ setup_readline(readlinestate *mod_state) rl_bind_key_in_map ('\t', rl_complete, emacs_meta_keymap); rl_bind_key_in_map ('\033', rl_complete, emacs_meta_keymap); /* Set our hook functions */ - rl_startup_hook = (Function *)on_startup_hook; + rl_startup_hook = on_startup_hook; #ifdef HAVE_RL_PRE_INPUT_HOOK - rl_pre_input_hook = (Function *)on_pre_input_hook; + rl_pre_input_hook = on_pre_input_hook; #endif /* Set our completion function */ - rl_attempted_completion_function = (CPPFunction *)flex_complete; + rl_attempted_completion_function = flex_complete; /* Set Python word break characters */ completer_word_break_characters = rl_completer_word_break_characters = @@ -1012,6 +1061,21 @@ setup_readline(readlinestate *mod_state) mod_state->begidx = PyLong_FromLong(0L); mod_state->endidx = PyLong_FromLong(0L); + +#ifndef __APPLE__ + if (!isatty(STDOUT_FILENO)) { + /* Issue #19884: stdout is no 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"); + } +#endif + /* Initialize (allows .inputrc to override) * * XXX: A bug in the readline-2.2 library causes a memory leak @@ -1040,8 +1104,6 @@ rlhandler(char *text) rl_callback_handler_remove(); } -extern PyThreadState* _PyOS_ReadlineTState; - static char * readline_until_enter_or_signal(const char *prompt, int *signal) { @@ -1118,7 +1180,7 @@ onintr(int sig) static char * -readline_until_enter_or_signal(char *prompt, int *signal) +readline_until_enter_or_signal(const char *prompt, int *signal) { PyOS_sighandler_t old_inthandler; char *p; @@ -1263,5 +1325,9 @@ PyInit_readline(void) mod_state = (readlinestate *) PyModule_GetState(m); PyOS_ReadlineFunctionPointer = call_readline; setup_readline(mod_state); + + PyModule_AddIntConstant(m, "_READLINE_VERSION", RL_READLINE_VERSION); + PyModule_AddIntConstant(m, "_READLINE_RUNTIME_VERSION", rl_readline_version); + return m; } diff --git a/Modules/resource.c b/Modules/resource.c index c12ce341fee2..3a1cf094c75e 100644 --- a/Modules/resource.c +++ b/Modules/resource.c @@ -424,6 +424,20 @@ PyInit_resource(void) 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 defined(HAVE_LONG_LONG) if (sizeof(RLIM_INFINITY) > sizeof(long)) { v = PyLong_FromLongLong((PY_LONG_LONG) RLIM_INFINITY); diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 6291a2daa929..b3ac8073a916 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -52,9 +52,6 @@ extern void bzero(void *, int); # include #else # define SOCKET int -# if defined(__VMS) -# include -# endif #endif /* list of Python objects and their file descriptor */ @@ -69,8 +66,7 @@ reap_obj(pylist fd2obj[FD_SETSIZE + 1]) { int i; for (i = 0; i < FD_SETSIZE + 1 && fd2obj[i].sentinel >= 0; i++) { - Py_XDECREF(fd2obj[i].obj); - fd2obj[i].obj = NULL; + Py_CLEAR(fd2obj[i].obj); } fd2obj[0].sentinel = -1; } @@ -197,46 +193,32 @@ select_select(PyObject *self, PyObject *args) #endif /* SELECT_USES_HEAP */ PyObject *ifdlist, *ofdlist, *efdlist; PyObject *ret = NULL; - PyObject *tout = Py_None; + PyObject *timeout_obj = Py_None; fd_set ifdset, ofdset, efdset; struct timeval tv, *tvp; int imax, omax, emax, max; int n; + _PyTime_t timeout, deadline = 0; /* convert arguments */ if (!PyArg_UnpackTuple(args, "select", 3, 4, - &ifdlist, &ofdlist, &efdlist, &tout)) + &ifdlist, &ofdlist, &efdlist, &timeout_obj)) return NULL; - if (tout == Py_None) - tvp = (struct timeval *)0; - else if (!PyNumber_Check(tout)) { - PyErr_SetString(PyExc_TypeError, - "timeout must be a float or None"); - return NULL; - } + if (timeout_obj == Py_None) + tvp = (struct timeval *)NULL; else { -#ifdef MS_WINDOWS - time_t sec; - if (_PyTime_ObjectToTimeval(tout, &sec, &tv.tv_usec) == -1) - return NULL; - assert(sizeof(tv.tv_sec) == sizeof(long)); -#if SIZEOF_TIME_T > SIZEOF_LONG - if (sec > LONG_MAX) { - PyErr_SetString(PyExc_OverflowError, - "timeout is too large"); + if (_PyTime_FromSecondsObject(&timeout, timeout_obj, + _PyTime_ROUND_CEILING) < 0) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_SetString(PyExc_TypeError, + "timeout must be a float or None"); + } return NULL; } -#endif - tv.tv_sec = (long)sec; -#else - /* 64-bit OS X has struct timeval.tv_usec as an int (and thus still 4 - bytes as required), but no longer defined by a long. */ - long tv_usec; - if (_PyTime_ObjectToTimeval(tout, &tv.tv_sec, &tv_usec) == -1) + + if (_PyTime_AsTimeval(timeout, &tv, _PyTime_ROUND_CEILING) == -1) return NULL; - tv.tv_usec = tv_usec; -#endif if (tv.tv_sec < 0) { PyErr_SetString(PyExc_ValueError, "timeout must be non-negative"); return NULL; @@ -244,7 +226,6 @@ select_select(PyObject *self, PyObject *args) tvp = &tv; } - #ifdef SELECT_USES_HEAP /* Allocate memory for the lists */ rfd2obj = PyMem_NEW(pylist, FD_SETSIZE + 1); @@ -257,6 +238,7 @@ select_select(PyObject *self, PyObject *args) return PyErr_NoMemory(); } #endif /* SELECT_USES_HEAP */ + /* Convert sequences to fd_sets, and get maximum fd number * propagates the Python exception set in seq2set() */ @@ -269,13 +251,37 @@ select_select(PyObject *self, PyObject *args) goto finally; if ((emax=seq2set(efdlist, &efdset, efd2obj)) < 0) goto finally; + max = imax; if (omax > max) max = omax; if (emax > max) max = emax; - Py_BEGIN_ALLOW_THREADS - n = select(max, &ifdset, &ofdset, &efdset, tvp); - Py_END_ALLOW_THREADS + 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) { + 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) { @@ -356,7 +362,7 @@ update_ufd_array(pollObject *self) assert(i < self->ufd_len); /* Never overflow */ self->ufds[i].fd = (int)PyLong_AsLong(key); - self->ufds[i].events = (short)PyLong_AsLong(value); + self->ufds[i].events = (short)(unsigned short)PyLong_AsLong(value); i++; } assert(i == self->ufd_len); @@ -364,6 +370,24 @@ update_ufd_array(pollObject *self) return 1; } +static int +ushort_converter(PyObject *obj, void *ptr) +{ + unsigned long uval; + + 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; +} + PyDoc_STRVAR(poll_register_doc, "register(fd [, eventmask] ) -> None\n\n\ Register a file descriptor with the polling object.\n\ @@ -376,12 +400,11 @@ poll_register(pollObject *self, PyObject *args) { PyObject *o, *key, *value; int fd; - short events = POLLIN | POLLPRI | POLLOUT; + unsigned short events = POLLIN | POLLPRI | POLLOUT; int err; - if (!PyArg_ParseTuple(args, "O|h:register", &o, &events)) { + if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events)) return NULL; - } fd = PyObject_AsFileDescriptor(o); if (fd == -1) return NULL; @@ -419,12 +442,12 @@ static PyObject * poll_modify(pollObject *self, PyObject *args) { PyObject *o, *key, *value; - int fd, events; + int fd; + unsigned short events; int err; - if (!PyArg_ParseTuple(args, "Oi:modify", &o, &events)) { + if (!PyArg_ParseTuple(args, "OO&:modify", &o, ushort_converter, &events)) return NULL; - } fd = PyObject_AsFileDescriptor(o); if (fd == -1) return NULL; @@ -498,30 +521,39 @@ any descriptors that have events or errors to report."); static PyObject * poll_poll(pollObject *self, PyObject *args) { - PyObject *result_list = NULL, *tout = NULL; - int timeout = 0, poll_result, i, j; + PyObject *result_list = NULL, *timeout_obj = NULL; + int poll_result, i, j; PyObject *value = NULL, *num = NULL; + _PyTime_t timeout, ms, deadline; + int async_err = 0; - if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) { + if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) { return NULL; } /* Check values for timeout */ - if (tout == NULL || tout == Py_None) + if (timeout_obj == NULL || timeout_obj == Py_None) { timeout = -1; - else if (!PyNumber_Check(tout)) { - PyErr_SetString(PyExc_TypeError, - "timeout must be an integer or None"); - return NULL; + ms = -1; + deadline = 0; /* initialize to prevent gcc warning */ } else { - tout = PyNumber_Long(tout); - if (!tout) + if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj, + _PyTime_ROUND_CEILING) < 0) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_SetString(PyExc_TypeError, + "timeout must be an integer or None"); + } return NULL; - timeout = _PyLong_AsInt(tout); - Py_DECREF(tout); - if (timeout == -1 && PyErr_Occurred()) + } + + ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING); + if (ms < INT_MIN || ms > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, "timeout is too large"); return NULL; + } + + deadline = _PyTime_GetMonotonicClock() + timeout; } /* Avoid concurrent poll() invocation, issue 8865 */ @@ -539,14 +571,38 @@ poll_poll(pollObject *self, PyObject *args) self->poll_running = 1; /* call poll() */ - Py_BEGIN_ALLOW_THREADS - poll_result = poll(self->ufds, self->ufd_len, timeout); - Py_END_ALLOW_THREADS + 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) { - PyErr_SetFromErrno(PyExc_OSError); + if (!async_err) + PyErr_SetFromErrno(PyExc_OSError); return NULL; } @@ -555,41 +611,40 @@ poll_poll(pollObject *self, PyObject *args) result_list = PyList_New(poll_result); if (!result_list) return NULL; - else { - 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); - if ((PyList_SetItem(result_list, j, value)) == -1) { - Py_DECREF(value); - goto error; - } + + 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); + if ((PyList_SetItem(result_list, j, value)) == -1) { + Py_DECREF(value); + goto error; + } + i++; } return result_list; @@ -700,14 +755,10 @@ static int devpoll_flush(devpollObject *self) size = sizeof(struct pollfd)*self->n_fds; self->n_fds = 0; - Py_BEGIN_ALLOW_THREADS - n = write(self->fd_devpoll, self->fds, size); - Py_END_ALLOW_THREADS - - if (n == -1 ) { - PyErr_SetFromErrno(PyExc_IOError); + 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 @@ -729,14 +780,14 @@ static PyObject * internal_devpoll_register(devpollObject *self, PyObject *args, int remove) { PyObject *o; - int fd, events = POLLIN | POLLPRI | POLLOUT; + int fd; + unsigned short events = POLLIN | POLLPRI | POLLOUT; if (self->fd_devpoll < 0) return devpoll_err_closed(); - if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) { + if (!PyArg_ParseTuple(args, "O|O&:register", &o, ushort_converter, &events)) return NULL; - } fd = PyObject_AsFileDescriptor(o); if (fd == -1) return NULL; @@ -752,7 +803,7 @@ internal_devpoll_register(devpollObject *self, PyObject *args, int remove) } self->fds[self->n_fds].fd = fd; - self->fds[self->n_fds].events = events; + self->fds[self->n_fds].events = (signed short)events; if (++self->n_fds == self->max_n_fds) { if (devpoll_flush(self)) @@ -825,40 +876,38 @@ static PyObject * devpoll_poll(devpollObject *self, PyObject *args) { struct dvpoll dvp; - PyObject *result_list = NULL, *tout = NULL; + PyObject *result_list = NULL, *timeout_obj = NULL; int poll_result, i; - long timeout; PyObject *value, *num1, *num2; + _PyTime_t timeout, ms, deadline = 0; if (self->fd_devpoll < 0) return devpoll_err_closed(); - if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) { + if (!PyArg_ParseTuple(args, "|O:poll", &timeout_obj)) { return NULL; } /* Check values for timeout */ - if (tout == NULL || tout == Py_None) + if (timeout_obj == NULL || timeout_obj == Py_None) { timeout = -1; - else if (!PyNumber_Check(tout)) { - PyErr_SetString(PyExc_TypeError, - "timeout must be an integer or None"); - return NULL; + ms = -1; } else { - tout = PyNumber_Long(tout); - if (!tout) - return NULL; - timeout = PyLong_AsLong(tout); - Py_DECREF(tout); - if (timeout == -1 && PyErr_Occurred()) + if (_PyTime_FromMillisecondsObject(&timeout, timeout_obj, + _PyTime_ROUND_CEILING) < 0) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_SetString(PyExc_TypeError, + "timeout must be an integer or None"); + } return NULL; - } + } - if ((timeout < -1) || (timeout > INT_MAX)) { - PyErr_SetString(PyExc_OverflowError, - "timeout is out of range"); - return NULL; + ms = _PyTime_AsMilliseconds(timeout, _PyTime_ROUND_CEILING); + if (ms < -1 || ms > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, "timeout is too large"); + return NULL; + } } if (devpoll_flush(self)) @@ -866,12 +915,36 @@ devpoll_poll(devpollObject *self, PyObject *args) dvp.dp_fds = self->fds; dvp.dp_nfds = self->max_n_fds; - dvp.dp_timeout = timeout; + 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; - /* call devpoll() */ - Py_BEGIN_ALLOW_THREADS - poll_result = ioctl(self->fd_devpoll, DP_POLL, &dvp); - Py_END_ALLOW_THREADS + /* 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_IOError); @@ -879,28 +952,26 @@ devpoll_poll(devpollObject *self, PyObject *args) } /* build the result list */ - result_list = PyList_New(poll_result); if (!result_list) return NULL; - else { - 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; - if ((PyList_SetItem(result_list, i, value)) == -1) { - Py_DECREF(value); - goto error; - } + + 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; + if ((PyList_SetItem(result_list, i, value)) == -1) { + Py_DECREF(value); + goto error; } } @@ -995,7 +1066,6 @@ newDevPollObject(void) struct pollfd *fds; struct rlimit limit; - Py_BEGIN_ALLOW_THREADS /* ** If we try to process more that getrlimit() ** fds, the kernel will give an error, so @@ -1003,18 +1073,14 @@ newDevPollObject(void) ** value, because we can change rlimit() anytime. */ limit_result = getrlimit(RLIMIT_NOFILE, &limit); - if (limit_result != -1) - fd_devpoll = _Py_open("/dev/poll", O_RDWR); - Py_END_ALLOW_THREADS - if (limit_result == -1) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } - if (fd_devpoll == -1) { - PyErr_SetFromErrnoWithFilename(PyExc_IOError, "/dev/poll"); + + 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) { @@ -1317,16 +1383,16 @@ pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events) return NULL; } - switch(op) { - case EPOLL_CTL_ADD: - case EPOLL_CTL_MOD: + 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: + 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. */ @@ -1339,7 +1405,7 @@ pyepoll_internal_ctl(int epfd, int op, PyObject *pfd, unsigned int events) } Py_END_ALLOW_THREADS break; - default: + default: result = -1; errno = EINVAL; } @@ -1419,32 +1485,46 @@ fd is the target file descriptor of the operation."); static PyObject * pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds) { - double dtimeout = -1.; - int timeout; + static char *kwlist[] = {"timeout", "maxevents", NULL}; + PyObject *timeout_obj = NULL; int maxevents = -1; int nfds, i; PyObject *elist = NULL, *etuple = NULL; struct epoll_event *evs = NULL; - static char *kwlist[] = {"timeout", "maxevents", NULL}; + _PyTime_t timeout, ms, deadline; if (self->epfd < 0) return pyepoll_err_closed(); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|di:poll", kwlist, - &dtimeout, &maxevents)) { + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:poll", kwlist, + &timeout_obj, &maxevents)) { return NULL; } - if (dtimeout < 0) { + if (timeout_obj == NULL || timeout_obj == Py_None) { timeout = -1; - } - else if (dtimeout * 1000.0 > INT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "timeout is too large"); - return NULL; + ms = -1; + deadline = 0; /* initialize to prevent gcc warning */ } else { - timeout = (int)(dtimeout * 1000.0); + /* 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_CEILING) < 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; + } + + deadline = _PyTime_GetMonotonicClock() + timeout; } if (maxevents == -1) { @@ -1463,9 +1543,30 @@ pyepoll_poll(pyEpoll_Object *self, PyObject *args, PyObject *kwds) return NULL; } - Py_BEGIN_ALLOW_THREADS - nfds = epoll_wait(self->epfd, evs, maxevents, timeout); - Py_END_ALLOW_THREADS + 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; @@ -1691,17 +1792,17 @@ static PyTypeObject kqueue_queue_Type; * kevent is not standard and its members vary across BSDs. */ #if !defined(__OpenBSD__) -# define IDENT_TYPE T_UINTPTRT -# define IDENT_CAST Py_intptr_t -# define DATA_TYPE T_INTPTRT +# define IDENT_TYPE T_UINTPTRT +# define IDENT_CAST Py_intptr_t +# define DATA_TYPE T_INTPTRT # define DATA_FMT_UNIT INTPTRT_FMT_UNIT -# define IDENT_AsType PyLong_AsUintptr_t +# define IDENT_AsType PyLong_AsUintptr_t #else -# define IDENT_TYPE T_UINT -# define IDENT_CAST int -# define DATA_TYPE T_INT +# define IDENT_TYPE T_UINT +# define IDENT_CAST int +# define DATA_TYPE T_INT # define DATA_FMT_UNIT "i" -# define IDENT_AsType PyLong_AsUnsignedLong +# define IDENT_AsType PyLong_AsUnsignedLong #endif /* Unfortunately, we can't store python objects in udata, because @@ -1753,7 +1854,7 @@ kqueue_event_init(kqueue_event_Object *self, PyObject *args, PyObject *kwds) if (PyLong_Check(pfd) #if IDENT_TYPE == T_UINT - && PyLong_AsUnsignedLong(pfd) <= UINT_MAX + && PyLong_AsUnsignedLong(pfd) <= UINT_MAX #endif ) { self->e.ident = IDENT_AsType(pfd); @@ -1795,22 +1896,22 @@ kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o, } switch (op) { - case Py_EQ: + case Py_EQ: result = (result == 0); break; - case Py_NE: + case Py_NE: result = (result != 0); break; - case Py_LE: + case Py_LE: result = (result <= 0); break; - case Py_GE: + case Py_GE: result = (result >= 0); break; - case Py_LT: + case Py_LT: result = (result < 0); break; - case Py_GT: + case Py_GT: result = (result > 0); break; } @@ -2002,8 +2103,9 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) PyObject *result = NULL; struct kevent *evl = NULL; struct kevent *chl = NULL; - struct timespec timeout; + struct timespec timeoutspec; struct timespec *ptimeoutspec; + _PyTime_t timeout, deadline = 0; if (self->kqfd < 0) return kqueue_queue_err_closed(); @@ -2021,24 +2123,25 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) if (otimeout == Py_None || otimeout == NULL) { ptimeoutspec = NULL; } - else if (PyNumber_Check(otimeout)) { - if (_PyTime_ObjectToTimespec(otimeout, - &timeout.tv_sec, &timeout.tv_nsec) == -1) + else { + if (_PyTime_FromSecondsObject(&timeout, + otimeout, _PyTime_ROUND_CEILING) < 0) { + PyErr_Format(PyExc_TypeError, + "timeout argument must be an number " + "or None, got %.200s", + Py_TYPE(otimeout)->tp_name); return NULL; + } - if (timeout.tv_sec < 0) { + 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 = &timeout; - } - else { - PyErr_Format(PyExc_TypeError, - "timeout argument must be an number " - "or None, got %.200s", - Py_TYPE(otimeout)->tp_name); - return NULL; + ptimeoutspec = &timeoutspec; } if (ch != NULL && ch != Py_None) { @@ -2083,10 +2186,34 @@ kqueue_queue_control(kqueue_queue_Object *self, PyObject *args) } } - Py_BEGIN_ALLOW_THREADS - gotevents = kevent(self->kqfd, chl, nchanges, - evl, nevents, ptimeoutspec); - Py_END_ALLOW_THREADS + if (ptimeoutspec) + deadline = _PyTime_GetMonotonicClock() + timeout; + + do { + Py_BEGIN_ALLOW_THREADS + errno = 0; + gotevents = kevent(self->kqfd, chl, nchanges, + evl, nevents, 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); @@ -2236,7 +2363,7 @@ arguments; each contains the subset of the corresponding file descriptors\n\ that are ready.\n\ \n\ *** IMPORTANT NOTICE ***\n\ -On Windows and OpenVMS, only sockets are supported; on Unix, all file\n\ +On Windows, only sockets are supported; on Unix, all file\n\ descriptors can be used."); static PyMethodDef select_methods[] = { @@ -2254,7 +2381,7 @@ PyDoc_STRVAR(module_doc, "This module supports asynchronous I/O on multiple file descriptors.\n\ \n\ *** IMPORTANT NOTICE ***\n\ -On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors."); +On Windows, only sockets are supported; on Unix, all file descriptors."); static struct PyModuleDef selectmodule = { @@ -2352,11 +2479,22 @@ PyInit_select(void) PyModule_AddIntMacro(m, EPOLLONESHOT); #endif /* PyModule_AddIntConstant(m, "EPOLL_RDHUP", EPOLLRDHUP); */ + +#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); diff --git a/Modules/sha1module.c b/Modules/sha1module.c index b44fe189d267..74b94ba270a7 100644 --- a/Modules/sha1module.c +++ b/Modules/sha1module.c @@ -18,7 +18,13 @@ #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 */ @@ -48,6 +54,7 @@ typedef struct { struct sha1_state hash_state; } SHA1object; +#include "clinic/sha1module.c.h" /* ------------------------------------------------------------------------ * @@ -309,10 +316,15 @@ SHA1_dealloc(PyObject *ptr) /* External methods for a hash object */ -PyDoc_STRVAR(SHA1_copy__doc__, "Return a copy of the hash object."); +/*[clinic input] +SHA1Type.copy + +Return a copy of the hash object. +[clinic start generated code]*/ static PyObject * -SHA1_copy(SHA1object *self, PyObject *unused) +SHA1Type_copy_impl(SHA1object *self) +/*[clinic end generated code: output=b4e001264620f02a input=b7eae10df6f89b36]*/ { SHA1object *newobj; @@ -323,11 +335,15 @@ SHA1_copy(SHA1object *self, PyObject *unused) return (PyObject *)newobj; } -PyDoc_STRVAR(SHA1_digest__doc__, -"Return the digest value as a string of binary data."); +/*[clinic input] +SHA1Type.digest + +Return the digest value as a string of binary data. +[clinic start generated code]*/ static PyObject * -SHA1_digest(SHA1object *self, PyObject *unused) +SHA1Type_digest_impl(SHA1object *self) +/*[clinic end generated code: output=2f05302a7aa2b5cb input=205d47e1927fd009]*/ { unsigned char digest[SHA1_DIGESTSIZE]; struct sha1_state temp; @@ -337,54 +353,41 @@ SHA1_digest(SHA1object *self, PyObject *unused) return PyBytes_FromStringAndSize((const char *)digest, SHA1_DIGESTSIZE); } -PyDoc_STRVAR(SHA1_hexdigest__doc__, -"Return the digest value as a string of hexadecimal digits."); +/*[clinic input] +SHA1Type.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ static PyObject * -SHA1_hexdigest(SHA1object *self, PyObject *unused) +SHA1Type_hexdigest_impl(SHA1object *self) +/*[clinic end generated code: output=4161fd71e68c6659 input=97691055c0c74ab0]*/ { unsigned char digest[SHA1_DIGESTSIZE]; struct sha1_state temp; - PyObject *retval; - Py_UCS1 *hex_digest; - int i, j; /* Get the raw (binary) digest value */ temp = self->hash_state; sha1_done(&temp, digest); - /* Create a new string */ - retval = PyUnicode_New(SHA1_DIGESTSIZE * 2, 127); - if (!retval) - return NULL; - hex_digest = PyUnicode_1BYTE_DATA(retval); - - /* Make hex version of the digest */ - for(i=j=0; i> 4) & 0xf; - hex_digest[j++] = Py_hexdigits[c]; - c = (digest[i] & 0xf); - hex_digest[j++] = Py_hexdigits[c]; - } -#ifdef Py_DEBUG - assert(_PyUnicode_CheckConsistency(retval, 1)); -#endif - return retval; + return _Py_strhex((const char *)digest, SHA1_DIGESTSIZE); } -PyDoc_STRVAR(SHA1_update__doc__, -"Update this hash object's state with the provided string."); +/*[clinic input] +SHA1Type.update + + obj: object + / + +Update this hash object's state with the provided string. +[clinic start generated code]*/ static PyObject * -SHA1_update(SHA1object *self, PyObject *args) +SHA1Type_update(SHA1object *self, PyObject *obj) +/*[clinic end generated code: output=d9902f0e5015e9ae input=aad8e07812edbba3]*/ { - PyObject *obj; Py_buffer buf; - if (!PyArg_ParseTuple(args, "O:update", &obj)) - return NULL; - GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); sha1_process(&self->hash_state, buf.buf, buf.len); @@ -395,10 +398,10 @@ SHA1_update(SHA1object *self, PyObject *args) } static PyMethodDef SHA1_methods[] = { - {"copy", (PyCFunction)SHA1_copy, METH_NOARGS, SHA1_copy__doc__}, - {"digest", (PyCFunction)SHA1_digest, METH_NOARGS, SHA1_digest__doc__}, - {"hexdigest", (PyCFunction)SHA1_hexdigest, METH_NOARGS, SHA1_hexdigest__doc__}, - {"update", (PyCFunction)SHA1_update, METH_VARARGS, SHA1_update__doc__}, + SHA1TYPE_COPY_METHODDEF + SHA1TYPE_DIGEST_METHODDEF + SHA1TYPE_HEXDIGEST_METHODDEF + SHA1TYPE_UPDATE_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -474,27 +477,26 @@ static PyTypeObject SHA1type = { /* The single module-level function: new() */ -PyDoc_STRVAR(SHA1_new__doc__, -"Return a new SHA1 hash object; optionally initialized with a string."); +/*[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_new(PyObject *self, PyObject *args, PyObject *kwdict) +_sha1_sha1_impl(PyModuleDef *module, PyObject *string) +/*[clinic end generated code: output=3e4e841386b9e8db input=27ea54281d995ec2]*/ { - static char *kwlist[] = {"string", NULL}; SHA1object *new; - PyObject *data_obj = NULL; Py_buffer buf; - if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|O:new", kwlist, - &data_obj)) { - return NULL; - } - - if (data_obj) - GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf); + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); if ((new = newSHA1object()) == NULL) { - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } @@ -503,11 +505,11 @@ SHA1_new(PyObject *self, PyObject *args, PyObject *kwdict) if (PyErr_Occurred()) { Py_DECREF(new); - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } - if (data_obj) { + if (string) { sha1_process(&new->hash_state, buf.buf, buf.len); PyBuffer_Release(&buf); } @@ -519,7 +521,7 @@ SHA1_new(PyObject *self, PyObject *args, PyObject *kwdict) /* List of functions exported by this module */ static struct PyMethodDef SHA1_functions[] = { - {"sha1",(PyCFunction)SHA1_new, METH_VARARGS|METH_KEYWORDS,SHA1_new__doc__}, + _SHA1_SHA1_METHODDEF {NULL, NULL} /* Sentinel */ }; diff --git a/Modules/sha256module.c b/Modules/sha256module.c index b05bfc172f51..8c4def057260 100644 --- a/Modules/sha256module.c +++ b/Modules/sha256module.c @@ -19,7 +19,13 @@ #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 */ @@ -47,6 +53,8 @@ typedef struct { 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. */ @@ -393,10 +401,15 @@ SHA_dealloc(PyObject *ptr) /* External methods for a hash object */ -PyDoc_STRVAR(SHA256_copy__doc__, "Return a copy of the hash object."); +/*[clinic input] +SHA256Type.copy + +Return a copy of the hash object. +[clinic start generated code]*/ static PyObject * -SHA256_copy(SHAobject *self, PyObject *unused) +SHA256Type_copy_impl(SHAobject *self) +/*[clinic end generated code: output=1a8bbd66a0c9c168 input=f58840a618d4f2a7]*/ { SHAobject *newobj; @@ -412,11 +425,15 @@ SHA256_copy(SHAobject *self, PyObject *unused) return (PyObject *)newobj; } -PyDoc_STRVAR(SHA256_digest__doc__, -"Return the digest value as a string of binary data."); +/*[clinic input] +SHA256Type.digest + +Return the digest value as a string of binary data. +[clinic start generated code]*/ static PyObject * -SHA256_digest(SHAobject *self, PyObject *unused) +SHA256Type_digest_impl(SHAobject *self) +/*[clinic end generated code: output=46616a5e909fbc3d input=1fb752e58954157d]*/ { unsigned char digest[SHA_DIGESTSIZE]; SHAobject temp; @@ -426,54 +443,41 @@ SHA256_digest(SHAobject *self, PyObject *unused) return PyBytes_FromStringAndSize((const char *)digest, self->digestsize); } -PyDoc_STRVAR(SHA256_hexdigest__doc__, -"Return the digest value as a string of hexadecimal digits."); +/*[clinic input] +SHA256Type.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ static PyObject * -SHA256_hexdigest(SHAobject *self, PyObject *unused) +SHA256Type_hexdigest_impl(SHAobject *self) +/*[clinic end generated code: output=725f8a7041ae97f3 input=0cc4c714693010d1]*/ { unsigned char digest[SHA_DIGESTSIZE]; SHAobject temp; - PyObject *retval; - Py_UCS1 *hex_digest; - int i, j; /* Get the raw (binary) digest value */ SHAcopy(self, &temp); sha_final(digest, &temp); - /* Create a new string */ - retval = PyUnicode_New(self->digestsize * 2, 127); - if (!retval) - return NULL; - hex_digest = PyUnicode_1BYTE_DATA(retval); - - /* Make hex version of the digest */ - for(i=j=0; idigestsize; i++) { - unsigned char c; - c = (digest[i] >> 4) & 0xf; - hex_digest[j++] = Py_hexdigits[c]; - c = (digest[i] & 0xf); - hex_digest[j++] = Py_hexdigits[c]; - } -#ifdef Py_DEBUG - assert(_PyUnicode_CheckConsistency(retval, 1)); -#endif - return retval; + return _Py_strhex((const char *)digest, self->digestsize); } -PyDoc_STRVAR(SHA256_update__doc__, -"Update this hash object's state with the provided string."); +/*[clinic input] +SHA256Type.update + + obj: object + / + +Update this hash object's state with the provided string. +[clinic start generated code]*/ static PyObject * -SHA256_update(SHAobject *self, PyObject *args) +SHA256Type_update(SHAobject *self, PyObject *obj) +/*[clinic end generated code: output=0967fb2860c66af7 input=b2d449d5b30f0f5a]*/ { - PyObject *obj; Py_buffer buf; - if (!PyArg_ParseTuple(args, "O:update", &obj)) - return NULL; - GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); sha_update(self, buf.buf, buf.len); @@ -484,10 +488,10 @@ SHA256_update(SHAobject *self, PyObject *args) } static PyMethodDef SHA_methods[] = { - {"copy", (PyCFunction)SHA256_copy, METH_NOARGS, SHA256_copy__doc__}, - {"digest", (PyCFunction)SHA256_digest, METH_NOARGS, SHA256_digest__doc__}, - {"hexdigest", (PyCFunction)SHA256_hexdigest, METH_NOARGS, SHA256_hexdigest__doc__}, - {"update", (PyCFunction)SHA256_update, METH_VARARGS, SHA256_update__doc__}, + SHA256TYPE_COPY_METHODDEF + SHA256TYPE_DIGEST_METHODDEF + SHA256TYPE_HEXDIGEST_METHODDEF + SHA256TYPE_UPDATE_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -594,27 +598,26 @@ static PyTypeObject SHA256type = { /* The single module-level function: new() */ -PyDoc_STRVAR(SHA256_new__doc__, -"Return a new SHA-256 hash object; optionally initialized with a string."); +/*[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_new(PyObject *self, PyObject *args, PyObject *kwdict) +_sha256_sha256_impl(PyModuleDef *module, PyObject *string) +/*[clinic end generated code: output=d70e6e2d97112844 input=09cce3fb855056b2]*/ { - static char *kwlist[] = {"string", NULL}; SHAobject *new; - PyObject *data_obj = NULL; Py_buffer buf; - if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|O:new", kwlist, - &data_obj)) { - return NULL; - } - - if (data_obj) - GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf); + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); if ((new = newSHA256object()) == NULL) { - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } @@ -623,11 +626,11 @@ SHA256_new(PyObject *self, PyObject *args, PyObject *kwdict) if (PyErr_Occurred()) { Py_DECREF(new); - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } - if (data_obj) { + if (string) { sha_update(new, buf.buf, buf.len); PyBuffer_Release(&buf); } @@ -635,27 +638,26 @@ SHA256_new(PyObject *self, PyObject *args, PyObject *kwdict) return (PyObject *)new; } -PyDoc_STRVAR(SHA224_new__doc__, -"Return a new SHA-224 hash object; optionally initialized with a string."); +/*[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 * -SHA224_new(PyObject *self, PyObject *args, PyObject *kwdict) +_sha256_sha224_impl(PyModuleDef *module, PyObject *string) +/*[clinic end generated code: output=f2822bf28416b42a input=27a04ba24c353a73]*/ { - static char *kwlist[] = {"string", NULL}; SHAobject *new; - PyObject *data_obj = NULL; Py_buffer buf; - if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|O:new", kwlist, - &data_obj)) { - return NULL; - } - - if (data_obj) - GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf); + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); if ((new = newSHA224object()) == NULL) { - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } @@ -664,11 +666,11 @@ SHA224_new(PyObject *self, PyObject *args, PyObject *kwdict) if (PyErr_Occurred()) { Py_DECREF(new); - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } - if (data_obj) { + if (string) { sha_update(new, buf.buf, buf.len); PyBuffer_Release(&buf); } @@ -680,8 +682,8 @@ SHA224_new(PyObject *self, PyObject *args, PyObject *kwdict) /* List of functions exported by this module */ static struct PyMethodDef SHA_functions[] = { - {"sha256", (PyCFunction)SHA256_new, METH_VARARGS|METH_KEYWORDS, SHA256_new__doc__}, - {"sha224", (PyCFunction)SHA224_new, METH_VARARGS|METH_KEYWORDS, SHA224_new__doc__}, + _SHA256_SHA256_METHODDEF + _SHA256_SHA224_METHODDEF {NULL, NULL} /* Sentinel */ }; diff --git a/Modules/sha512module.c b/Modules/sha512module.c index 47c57e5c428f..8237d867f4aa 100644 --- a/Modules/sha512module.c +++ b/Modules/sha512module.c @@ -19,6 +19,13 @@ #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]*/ #ifdef PY_LONG_LONG /* If no PY_LONG_LONG, don't compile anything! */ @@ -49,6 +56,8 @@ typedef struct { 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. */ @@ -459,10 +468,15 @@ SHA512_dealloc(PyObject *ptr) /* External methods for a hash object */ -PyDoc_STRVAR(SHA512_copy__doc__, "Return a copy of the hash object."); +/*[clinic input] +SHA512Type.copy + +Return a copy of the hash object. +[clinic start generated code]*/ static PyObject * -SHA512_copy(SHAobject *self, PyObject *unused) +SHA512Type_copy_impl(SHAobject *self) +/*[clinic end generated code: output=adea896ed3164821 input=9f5f31e6c457776a]*/ { SHAobject *newobj; @@ -478,11 +492,15 @@ SHA512_copy(SHAobject *self, PyObject *unused) return (PyObject *)newobj; } -PyDoc_STRVAR(SHA512_digest__doc__, -"Return the digest value as a string of binary data."); +/*[clinic input] +SHA512Type.digest + +Return the digest value as a string of binary data. +[clinic start generated code]*/ static PyObject * -SHA512_digest(SHAobject *self, PyObject *unused) +SHA512Type_digest_impl(SHAobject *self) +/*[clinic end generated code: output=1080bbeeef7dde1b input=60c2cede9e023018]*/ { unsigned char digest[SHA_DIGESTSIZE]; SHAobject temp; @@ -492,54 +510,41 @@ SHA512_digest(SHAobject *self, PyObject *unused) return PyBytes_FromStringAndSize((const char *)digest, self->digestsize); } -PyDoc_STRVAR(SHA512_hexdigest__doc__, -"Return the digest value as a string of hexadecimal digits."); +/*[clinic input] +SHA512Type.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ static PyObject * -SHA512_hexdigest(SHAobject *self, PyObject *unused) +SHA512Type_hexdigest_impl(SHAobject *self) +/*[clinic end generated code: output=7373305b8601e18b input=498b877b25cbe0a2]*/ { unsigned char digest[SHA_DIGESTSIZE]; SHAobject temp; - PyObject *retval; - Py_UCS1 *hex_digest; - int i, j; /* Get the raw (binary) digest value */ SHAcopy(self, &temp); sha512_final(digest, &temp); - /* Create a new string */ - retval = PyUnicode_New(self->digestsize * 2, 127); - if (!retval) - return NULL; - hex_digest = PyUnicode_1BYTE_DATA(retval); - - /* Make hex version of the digest */ - for (i=j=0; idigestsize; i++) { - unsigned char c; - c = (digest[i] >> 4) & 0xf; - hex_digest[j++] = Py_hexdigits[c]; - c = (digest[i] & 0xf); - hex_digest[j++] = Py_hexdigits[c]; - } -#ifdef Py_DEBUG - assert(_PyUnicode_CheckConsistency(retval, 1)); -#endif - return retval; + return _Py_strhex((const char *)digest, self->digestsize); } -PyDoc_STRVAR(SHA512_update__doc__, -"Update this hash object's state with the provided string."); +/*[clinic input] +SHA512Type.update + + obj: object + / + +Update this hash object's state with the provided string. +[clinic start generated code]*/ static PyObject * -SHA512_update(SHAobject *self, PyObject *args) +SHA512Type_update(SHAobject *self, PyObject *obj) +/*[clinic end generated code: output=1cf333e73995a79e input=ded2b46656566283]*/ { - PyObject *obj; Py_buffer buf; - if (!PyArg_ParseTuple(args, "O:update", &obj)) - return NULL; - GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); sha512_update(self, buf.buf, buf.len); @@ -548,12 +553,16 @@ SHA512_update(SHAobject *self, PyObject *args) Py_INCREF(Py_None); return Py_None; } +/*[clinic input] +dump buffer +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/ static PyMethodDef SHA_methods[] = { - {"copy", (PyCFunction)SHA512_copy, METH_NOARGS, SHA512_copy__doc__}, - {"digest", (PyCFunction)SHA512_digest, METH_NOARGS, SHA512_digest__doc__}, - {"hexdigest", (PyCFunction)SHA512_hexdigest, METH_NOARGS, SHA512_hexdigest__doc__}, - {"update", (PyCFunction)SHA512_update, METH_VARARGS, SHA512_update__doc__}, + SHA512TYPE_COPY_METHODDEF + SHA512TYPE_DIGEST_METHODDEF + SHA512TYPE_HEXDIGEST_METHODDEF + SHA512TYPE_UPDATE_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -660,27 +669,26 @@ static PyTypeObject SHA512type = { /* The single module-level function: new() */ -PyDoc_STRVAR(SHA512_new__doc__, -"Return a new SHA-512 hash object; optionally initialized with a string."); +/*[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_new(PyObject *self, PyObject *args, PyObject *kwdict) +_sha512_sha512_impl(PyModuleDef *module, PyObject *string) +/*[clinic end generated code: output=da13bc0a94da6de3 input=e69bad9ae9b6a308]*/ { - static char *kwlist[] = {"string", NULL}; SHAobject *new; - PyObject *data_obj = NULL; Py_buffer buf; - if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|O:new", kwlist, - &data_obj)) { - return NULL; - } - - if (data_obj) - GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf); + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); if ((new = newSHA512object()) == NULL) { - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } @@ -689,11 +697,11 @@ SHA512_new(PyObject *self, PyObject *args, PyObject *kwdict) if (PyErr_Occurred()) { Py_DECREF(new); - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } - if (data_obj) { + if (string) { sha512_update(new, buf.buf, buf.len); PyBuffer_Release(&buf); } @@ -701,27 +709,26 @@ SHA512_new(PyObject *self, PyObject *args, PyObject *kwdict) return (PyObject *)new; } -PyDoc_STRVAR(SHA384_new__doc__, -"Return a new SHA-384 hash object; optionally initialized with a string."); +/*[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 * -SHA384_new(PyObject *self, PyObject *args, PyObject *kwdict) +_sha512_sha384_impl(PyModuleDef *module, PyObject *string) +/*[clinic end generated code: output=ac731aea5509174d input=c9327788d4ea4545]*/ { - static char *kwlist[] = {"string", NULL}; SHAobject *new; - PyObject *data_obj = NULL; Py_buffer buf; - if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|O:new", kwlist, - &data_obj)) { - return NULL; - } - - if (data_obj) - GET_BUFFER_VIEW_OR_ERROUT(data_obj, &buf); + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); if ((new = newSHA384object()) == NULL) { - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } @@ -730,11 +737,11 @@ SHA384_new(PyObject *self, PyObject *args, PyObject *kwdict) if (PyErr_Occurred()) { Py_DECREF(new); - if (data_obj) + if (string) PyBuffer_Release(&buf); return NULL; } - if (data_obj) { + if (string) { sha512_update(new, buf.buf, buf.len); PyBuffer_Release(&buf); } @@ -743,11 +750,16 @@ SHA384_new(PyObject *self, PyObject *args, PyObject *kwdict) } +/*[clinic input] +dump buffer +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/ + /* List of functions exported by this module */ static struct PyMethodDef SHA_functions[] = { - {"sha512", (PyCFunction)SHA512_new, METH_VARARGS|METH_KEYWORDS, SHA512_new__doc__}, - {"sha384", (PyCFunction)SHA384_new, METH_VARARGS|METH_KEYWORDS, SHA384_new__doc__}, + _SHA512_SHA512_METHODDEF + _SHA512_SHA384_METHODDEF {NULL, NULL} /* Sentinel */ }; diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 9a0e8e336516..70f305214988 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -7,6 +7,9 @@ #ifndef MS_WINDOWS #include "posixmodule.h" #endif +#ifdef MS_WINDOWS +#include "socketmodule.h" /* needed for SOCKET_T */ +#endif #ifdef MS_WINDOWS #include @@ -49,6 +52,13 @@ # endif #endif +#include "clinic/signalmodule.c.h" + +/*[clinic input] +module signal +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b0301a3bde5fe9d3]*/ + /* NOTES ON THE INTERACTION BETWEEN SIGNALS AND THREADS @@ -87,7 +97,20 @@ static volatile struct { PyObject *func; } Handlers[NSIG]; +#ifdef MS_WINDOWS +#define INVALID_FD ((SOCKET_T)-1) + +static volatile struct { + SOCKET_T fd; + int use_send; + int send_err_set; + int send_errno; + int send_win_error; +} wakeup = {INVALID_FD, 0, 0}; +#else +#define INVALID_FD (-1) static volatile sig_atomic_t wakeup_fd = -1; +#endif /* Speed up sigcheck() when none tripped */ static volatile sig_atomic_t is_tripped = 0; @@ -172,7 +195,7 @@ checksignals_witharg(void * unused) } static int -report_wakeup_error(void *data) +report_wakeup_write_error(void *data) { int save_errno = errno; errno = (int) (Py_intptr_t) data; @@ -184,25 +207,87 @@ report_wakeup_error(void *data) return 0; } +#ifdef MS_WINDOWS +static int +report_wakeup_send_error(void* Py_UNUSED(data)) +{ + PyObject *res; + + if (wakeup.send_win_error) { + /* PyErr_SetExcFromWindowsErr() invokes FormatMessage() which + recognizes the error codes used by both GetLastError() and + WSAGetLastError */ + res = PyErr_SetExcFromWindowsErr(PyExc_OSError, wakeup.send_win_error); + } + else { + errno = wakeup.send_errno; + res = PyErr_SetFromErrno(PyExc_OSError); + } + + assert(res == NULL); + wakeup.send_err_set = 0; + + PySys_WriteStderr("Exception ignored when trying to send to the " + "signal wakeup fd:\n"); + PyErr_WriteUnraisable(NULL); + + return 0; +} +#endif /* MS_WINDOWS */ + static void trip_signal(int sig_num) { unsigned char byte; - int rc = 0; + int fd; + Py_ssize_t rc; Handlers[sig_num].tripped = 1; - if (wakeup_fd != -1) { + +#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; - while ((rc = write(wakeup_fd, &byte, 1)) == -1 && errno == EINTR); - if (rc == -1) - Py_AddPendingCall(report_wakeup_error, (void *) (Py_intptr_t) errno); +#ifdef MS_WINDOWS + if (wakeup.use_send) { + do { + rc = send(fd, &byte, 1, 0); + } while (rc < 0 && errno == EINTR); + + /* we only have a storage for one error in the wakeup structure */ + if (rc < 0 && !wakeup.send_err_set) { + wakeup.send_err_set = 1; + wakeup.send_errno = errno; + wakeup.send_win_error = GetLastError(); + Py_AddPendingCall(report_wakeup_send_error, NULL); + } + } + else +#endif + { + byte = (unsigned char)sig_num; + + /* _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) { + Py_AddPendingCall(report_wakeup_write_error, + (void *)(Py_intptr_t)errno); + } + } + } + + if (!is_tripped) { + /* Set is_tripped after setting .tripped, as it gets + cleared in PyErr_CheckSignals() before .tripped. */ + is_tripped = 1; + Py_AddPendingCall(checksignals_witharg, NULL); } - if (is_tripped) - return; - /* Set is_tripped after setting .tripped, as it gets - cleared in PyErr_CheckSignals() before .tripped. */ - is_tripped = 1; - Py_AddPendingCall(checksignals_witharg, NULL); } static void @@ -227,7 +312,7 @@ signal_handler(int sig_num) if (sig_num != SIGCHLD) #endif /* If the handler was not set up with sigaction, reinstall it. See - * Python/pythonrun.c for the implementation of PyOS_setsig which + * Python/pylifecycle.c for the implementation of PyOS_setsig which * makes this true. See also issue8354. */ PyOS_setsig(sig_num, signal_handler); #endif @@ -244,25 +329,37 @@ signal_handler(int sig_num) #ifdef HAVE_ALARM -static PyObject * -signal_alarm(PyObject *self, PyObject *args) + +/*[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(PyModuleDef *module, int seconds) +/*[clinic end generated code: output=f5f9badaab25d3e7 input=0d5e97e0e6f39e86]*/ { - int t; - if (!PyArg_ParseTuple(args, "i:alarm", &t)) - return NULL; /* alarm() returns the number of seconds remaining */ - return PyLong_FromLong((long)alarm(t)); + return (long)alarm(seconds); } -PyDoc_STRVAR(alarm_doc, -"alarm(seconds)\n\ -\n\ -Arrange for SIGALRM to arrive after the given number of seconds."); #endif #ifdef HAVE_PAUSE + +/*[clinic input] +signal.pause + +Wait until a signal arrives. +[clinic start generated code]*/ + static PyObject * -signal_pause(PyObject *self) +signal_pause_impl(PyModuleDef *module) +/*[clinic end generated code: output=9245704caa63bbe9 input=f03de0f875752062]*/ { Py_BEGIN_ALLOW_THREADS (void)pause(); @@ -273,29 +370,38 @@ signal_pause(PyObject *self) if (PyErr_CheckSignals()) return NULL; - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(pause_doc, -"pause()\n\ -\n\ -Wait until a signal arrives."); #endif +/*[clinic input] +signal.signal + + signalnum: int + handler: object + / + +Set the action for the given signal. + +The action can be SIG_DFL, SIG_IGN, or a callable Python object. +The previous action is returned. See getsignal() for possible return values. + +*** IMPORTANT NOTICE *** +A signal handler function is called with two arguments: +the first is the signal number, the second is the interrupted stack frame. +[clinic start generated code]*/ + static PyObject * -signal_signal(PyObject *self, PyObject *args) +signal_signal_impl(PyModuleDef *module, int signalnum, PyObject *handler) +/*[clinic end generated code: output=622d7d0beebea546 input=deee84af5fa0432c]*/ { - PyObject *obj; - int sig_num; PyObject *old_handler; void (*func)(int); - if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj)) - return NULL; #ifdef MS_WINDOWS - /* Validate that sig_num is one of the allowable signals */ - switch (sig_num) { + /* 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 @@ -319,61 +425,63 @@ signal_signal(PyObject *self, PyObject *args) return NULL; } #endif - if (sig_num < 1 || sig_num >= NSIG) { + if (signalnum < 1 || signalnum >= NSIG) { PyErr_SetString(PyExc_ValueError, "signal number out of range"); return NULL; } - if (obj == IgnoreHandler) + if (handler == IgnoreHandler) func = SIG_IGN; - else if (obj == DefaultHandler) + else if (handler == DefaultHandler) func = SIG_DFL; - else if (!PyCallable_Check(obj)) { + 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; - if (PyOS_setsig(sig_num, func) == SIG_ERR) { + if (PyOS_setsig(signalnum, func) == SIG_ERR) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } - old_handler = Handlers[sig_num].func; - Handlers[sig_num].tripped = 0; - Py_INCREF(obj); - Handlers[sig_num].func = obj; + old_handler = Handlers[signalnum].func; + Handlers[signalnum].tripped = 0; + Py_INCREF(handler); + Handlers[signalnum].func = handler; if (old_handler != NULL) return old_handler; else Py_RETURN_NONE; } -PyDoc_STRVAR(signal_doc, -"signal(sig, action) -> action\n\ -\n\ -Set the action for the given signal. The action can be SIG_DFL,\n\ -SIG_IGN, or a callable Python object. The previous action is\n\ -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."); +/*[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(PyObject *self, PyObject *args) +signal_getsignal_impl(PyModuleDef *module, int signalnum) +/*[clinic end generated code: output=d50ec355757e360c input=ac23a00f19dfa509]*/ { - int sig_num; PyObject *old_handler; - if (!PyArg_ParseTuple(args, "i:getsignal", &sig_num)) - return NULL; - if (sig_num < 1 || sig_num >= NSIG) { + if (signalnum < 1 || signalnum >= NSIG) { PyErr_SetString(PyExc_ValueError, "signal number out of range"); return NULL; } - old_handler = Handlers[sig_num].func; + old_handler = Handlers[signalnum].func; if (old_handler != NULL) { Py_INCREF(old_handler); return old_handler; @@ -383,53 +491,65 @@ signal_getsignal(PyObject *self, PyObject *args) } } -PyDoc_STRVAR(getsignal_doc, -"getsignal(sig) -> action\n\ -\n\ -Return the current action for the given signal. 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"); - #ifdef HAVE_SIGINTERRUPT -PyDoc_STRVAR(siginterrupt_doc, -"siginterrupt(sig, flag) -> None\n\ -change system call restart behaviour: if flag is False, system calls\n\ -will be restarted when interrupted by signal sig, else system calls\n\ -will be interrupted."); + +/*[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(PyObject *self, PyObject *args) +signal_siginterrupt_impl(PyModuleDef *module, int signalnum, int flag) +/*[clinic end generated code: output=5dcf8b031b0e8044 input=4160acacca3e2099]*/ { - int sig_num; - int flag; - - if (!PyArg_ParseTuple(args, "ii:siginterrupt", &sig_num, &flag)) - return NULL; - if (sig_num < 1 || sig_num >= NSIG) { + if (signalnum < 1 || signalnum >= NSIG) { PyErr_SetString(PyExc_ValueError, "signal number out of range"); return NULL; } - if (siginterrupt(sig_num, flag)<0) { + if (siginterrupt(signalnum, flag)<0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } - - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } #endif -static PyObject * + +static PyObject* signal_set_wakeup_fd(PyObject *self, PyObject *args) { - struct stat buf; + struct _Py_stat_struct status; +#ifdef MS_WINDOWS + PyObject *fdobj; + SOCKET_T sockfd, old_sockfd; + int res; + int res_size = sizeof res; + PyObject *mod; + int is_socket; + + if (!PyArg_ParseTuple(args, "O:set_wakeup_fd", &fdobj)) + return NULL; + + sockfd = PyLong_AsSocket_t(fdobj); + if (sockfd == (SOCKET_T)(-1) && PyErr_Occurred()) + return NULL; +#else int fd, old_fd; + if (!PyArg_ParseTuple(args, "i:set_wakeup_fd", &fd)) return NULL; +#endif + #ifdef WITH_THREAD if (PyThread_get_thread_ident() != main_thread) { PyErr_SetString(PyExc_ValueError, @@ -437,21 +557,90 @@ signal_set_wakeup_fd(PyObject *self, PyObject *args) return NULL; } #endif - if (fd != -1 && (!_PyVerify_fd(fd) || fstat(fd, &buf) != 0)) { - PyErr_SetString(PyExc_ValueError, "invalid fd"); - 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 || !_PyVerify_fd(fd)) { + 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.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 (!_PyVerify_fd(fd)) { + PyErr_SetString(PyExc_ValueError, "invalid fd"); + return NULL; + } + + 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; + return PyLong_FromLong(old_fd); +#endif } PyDoc_STRVAR(set_wakeup_fd_doc, "set_wakeup_fd(fd) -> fd\n\ \n\ -Sets the fd to be written to (with '\\0') when a signal\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 is returned.\n\ +The previous fd or -1 is returned.\n\ \n\ The fd must be non-blocking."); @@ -459,71 +648,85 @@ The fd must be non-blocking."); int PySignal_SetWakeupFd(int fd) { - int old_fd = wakeup_fd; + int old_fd; if (fd < 0) fd = -1; + +#ifdef MS_WINDOWS + old_fd = Py_SAFE_DOWNCAST(wakeup.fd, SOCKET_T, int); + wakeup.fd = fd; +#else + old_fd = wakeup_fd; wakeup_fd = fd; +#endif return old_fd; } #ifdef HAVE_SETITIMER + +/*[clinic input] +signal.setitimer + + which: int + seconds: double + interval: double = 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(PyObject *self, PyObject *args) +signal_setitimer_impl(PyModuleDef *module, int which, double seconds, + double interval) +/*[clinic end generated code: output=9a9227a27bd05988 input=0d27d417cfcbd51a]*/ { - double first; - double interval = 0; - int which; struct itimerval new, old; - if(!PyArg_ParseTuple(args, "id|d:setitimer", &which, &first, &interval)) - return NULL; - - timeval_from_double(first, &new.it_value); + timeval_from_double(seconds, &new.it_value); timeval_from_double(interval, &new.it_interval); /* Let OS check "which" value */ if (setitimer(which, &new, &old) != 0) { - PyErr_SetFromErrno(ItimerError); - return NULL; + PyErr_SetFromErrno(ItimerError); + return NULL; } return itimer_retval(&old); } -PyDoc_STRVAR(setitimer_doc, -"setitimer(which, seconds[, interval])\n\ -\n\ -Sets given itimer (one of ITIMER_REAL, ITIMER_VIRTUAL\n\ -or ITIMER_PROF) to fire after value seconds and after\n\ -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)."); #endif #ifdef HAVE_GETITIMER + +/*[clinic input] +signal.getitimer + + which: int + / + +Returns current value of given itimer. +[clinic start generated code]*/ + static PyObject * -signal_getitimer(PyObject *self, PyObject *args) +signal_getitimer_impl(PyModuleDef *module, int which) +/*[clinic end generated code: output=d1349ab18aadc569 input=f7d21d38f3490627]*/ { - int which; struct itimerval old; - if (!PyArg_ParseTuple(args, "i:getitimer", &which)) - return NULL; - if (getitimer(which, &old) != 0) { - PyErr_SetFromErrno(ItimerError); - return NULL; + PyErr_SetFromErrno(ItimerError); + return NULL; } return itimer_retval(&old); } -PyDoc_STRVAR(getitimer_doc, -"getitimer(which)\n\ -\n\ -Returns current value of given itimer."); #endif #if defined(PYPTHREAD_SIGMASK) || defined(HAVE_SIGWAIT) || \ @@ -614,21 +817,28 @@ sigset_to_set(sigset_t mask) #endif #ifdef PYPTHREAD_SIGMASK + +/*[clinic input] +signal.pthread_sigmask + + how: int + mask: object + / + +Fetch and/or change the signal mask of the calling thread. +[clinic start generated code]*/ + static PyObject * -signal_pthread_sigmask(PyObject *self, PyObject *args) +signal_pthread_sigmask_impl(PyModuleDef *module, int how, PyObject *mask) +/*[clinic end generated code: output=b043a9f0eeb1e075 input=f3b7d7a61b7b8283]*/ { - int how; - PyObject *signals; - sigset_t mask, previous; + sigset_t newmask, previous; int err; - if (!PyArg_ParseTuple(args, "iO:pthread_sigmask", &how, &signals)) - return NULL; - - if (iterable_to_sigset(signals, &mask)) + if (iterable_to_sigset(mask, &newmask)) return NULL; - err = pthread_sigmask(how, &mask, &previous); + err = pthread_sigmask(how, &newmask, &previous); if (err != 0) { errno = err; PyErr_SetFromErrno(PyExc_OSError); @@ -642,16 +852,23 @@ signal_pthread_sigmask(PyObject *self, PyObject *args) return sigset_to_set(previous); } -PyDoc_STRVAR(signal_pthread_sigmask_doc, -"pthread_sigmask(how, mask) -> old mask\n\ -\n\ -Fetch and/or change the signal mask of the calling thread."); #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(PyObject *self) +signal_sigpending_impl(PyModuleDef *module) +/*[clinic end generated code: output=bf4ced803e7e51dd input=e0036c016f874e29]*/ { int err; sigset_t mask; @@ -661,25 +878,32 @@ signal_sigpending(PyObject *self) return sigset_to_set(mask); } -PyDoc_STRVAR(signal_sigpending_doc, -"sigpending() -> list\n\ -\n\ -Examine pending signals."); #endif /* #ifdef HAVE_SIGPENDING */ #ifdef HAVE_SIGWAIT + +/*[clinic input] +signal.sigwait + + sigset: object + / + +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(PyObject *self, PyObject *args) +signal_sigwait(PyModuleDef *module, PyObject *sigset) +/*[clinic end generated code: output=dae53048b0336a5c input=11af2d82d83c2e94]*/ { - PyObject *signals; sigset_t set; int err, signum; - if (!PyArg_ParseTuple(args, "O:sigwait", &signals)) - return NULL; - - if (iterable_to_sigset(signals, &set)) + if (iterable_to_sigset(sigset, &set)) return NULL; Py_BEGIN_ALLOW_THREADS @@ -693,11 +917,8 @@ signal_sigwait(PyObject *self, PyObject *args) return PyLong_FromLong(signum); } -PyDoc_STRVAR(signal_sigwait_doc, -"sigwait(sigset) -> signum\n\ -\n\ -Wait a signal."); -#endif /* #ifdef HAVE_SIGPENDING */ +#endif /* #ifdef HAVE_SIGWAIT */ + #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) static int initialized; @@ -752,99 +973,136 @@ fill_siginfo(siginfo_t *si) #endif #ifdef HAVE_SIGWAITINFO + +/*[clinic input] +signal.sigwaitinfo + + sigset: object + / + +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(PyObject *self, PyObject *args) +signal_sigwaitinfo(PyModuleDef *module, PyObject *sigset) +/*[clinic end generated code: output=0bb53b07e5e926b5 input=f3779a74a991e171]*/ { - PyObject *signals; sigset_t set; siginfo_t si; int err; + int async_err = 0; - if (!PyArg_ParseTuple(args, "O:sigwaitinfo", &signals)) + if (iterable_to_sigset(sigset, &set)) return NULL; - if (iterable_to_sigset(signals, &set)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - err = sigwaitinfo(&set, &si); - Py_END_ALLOW_THREADS + do { + Py_BEGIN_ALLOW_THREADS + err = sigwaitinfo(&set, &si); + Py_END_ALLOW_THREADS + } while (err == -1 + && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (err == -1) - return PyErr_SetFromErrno(PyExc_OSError); + return (!async_err) ? PyErr_SetFromErrno(PyExc_OSError) : NULL; return fill_siginfo(&si); } -PyDoc_STRVAR(signal_sigwaitinfo_doc, -"sigwaitinfo(sigset) -> struct_siginfo\n\ -\n\ -Wait synchronously for a signal until one of the signals in *sigset* is\n\ -delivered.\n\ -Returns a struct_siginfo containing information about the signal."); #endif /* #ifdef HAVE_SIGWAITINFO */ #ifdef HAVE_SIGTIMEDWAIT + +/*[clinic input] +signal.sigtimedwait + + sigset: object + 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(PyObject *self, PyObject *args) +signal_sigtimedwait_impl(PyModuleDef *module, PyObject *sigset, + PyObject *timeout_obj) +/*[clinic end generated code: output=c1960b5cea139929 input=53fd4ea3e3724eb8]*/ { - PyObject *signals, *timeout; - struct timespec buf; + struct timespec ts; sigset_t set; siginfo_t si; - time_t tv_sec; - long tv_nsec; - int err; + int res; + _PyTime_t timeout, deadline, monotonic; - if (!PyArg_ParseTuple(args, "OO:sigtimedwait", - &signals, &timeout)) + if (_PyTime_FromSecondsObject(&timeout, + timeout_obj, _PyTime_ROUND_CEILING) < 0) return NULL; - if (_PyTime_ObjectToTimespec(timeout, &tv_sec, &tv_nsec) == -1) - return NULL; - buf.tv_sec = tv_sec; - buf.tv_nsec = tv_nsec; - - if (buf.tv_sec < 0 || buf.tv_nsec < 0) { + if (timeout < 0) { PyErr_SetString(PyExc_ValueError, "timeout must be non-negative"); return NULL; } - if (iterable_to_sigset(signals, &set)) + if (iterable_to_sigset(sigset, &set)) return NULL; - Py_BEGIN_ALLOW_THREADS - err = sigtimedwait(&set, &si, &buf); - Py_END_ALLOW_THREADS - if (err == -1) { - if (errno == EAGAIN) - Py_RETURN_NONE; - else - return PyErr_SetFromErrno(PyExc_OSError); - } + deadline = _PyTime_GetMonotonicClock() + timeout; + + do { + if (_PyTime_AsTimespec(timeout, &ts) < 0) + return NULL; + + Py_BEGIN_ALLOW_THREADS + res = sigtimedwait(&set, &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); } -PyDoc_STRVAR(signal_sigtimedwait_doc, -"sigtimedwait(sigset, (timeout_sec, timeout_nsec)) -> struct_siginfo\n\ -\n\ -Like sigwaitinfo(), but with a timeout specified as a tuple of (seconds,\n\ -nanoseconds)."); #endif /* #ifdef HAVE_SIGTIMEDWAIT */ #if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD) + +/*[clinic input] +signal.pthread_kill + + thread_id: long + signalnum: int + / + +Send a signal to a thread. +[clinic start generated code]*/ + static PyObject * -signal_pthread_kill(PyObject *self, PyObject *args) +signal_pthread_kill_impl(PyModuleDef *module, long thread_id, int signalnum) +/*[clinic end generated code: output=35aed2713c756d7a input=77ed6a3b6f2a8122]*/ { - long tid; - int signum; int err; - if (!PyArg_ParseTuple(args, "li:pthread_kill", &tid, &signum)) - return NULL; - - err = pthread_kill((pthread_t)tid, signum); + err = pthread_kill((pthread_t)thread_id, signalnum); if (err != 0) { errno = err; PyErr_SetFromErrno(PyExc_OSError); @@ -858,62 +1116,29 @@ signal_pthread_kill(PyObject *self, PyObject *args) Py_RETURN_NONE; } -PyDoc_STRVAR(signal_pthread_kill_doc, -"pthread_kill(thread_id, signum)\n\ -\n\ -Send a signal to a thread."); #endif /* #if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD) */ -/* List of functions defined in the module */ +/* 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[] = { -#ifdef HAVE_ALARM - {"alarm", signal_alarm, METH_VARARGS, alarm_doc}, -#endif -#ifdef HAVE_SETITIMER - {"setitimer", signal_setitimer, METH_VARARGS, setitimer_doc}, -#endif -#ifdef HAVE_GETITIMER - {"getitimer", signal_getitimer, METH_VARARGS, getitimer_doc}, -#endif - {"signal", signal_signal, METH_VARARGS, signal_doc}, - {"getsignal", signal_getsignal, METH_VARARGS, getsignal_doc}, + {"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_GETSIGNAL_METHODDEF {"set_wakeup_fd", signal_set_wakeup_fd, METH_VARARGS, set_wakeup_fd_doc}, -#ifdef HAVE_SIGINTERRUPT - {"siginterrupt", signal_siginterrupt, METH_VARARGS, siginterrupt_doc}, -#endif -#ifdef HAVE_PAUSE - {"pause", (PyCFunction)signal_pause, - METH_NOARGS, pause_doc}, -#endif - {"default_int_handler", signal_default_int_handler, - METH_VARARGS, default_int_handler_doc}, -#if defined(HAVE_PTHREAD_KILL) && defined(WITH_THREAD) - {"pthread_kill", (PyCFunction)signal_pthread_kill, - METH_VARARGS, signal_pthread_kill_doc}, -#endif -#ifdef PYPTHREAD_SIGMASK - {"pthread_sigmask", (PyCFunction)signal_pthread_sigmask, - METH_VARARGS, signal_pthread_sigmask_doc}, -#endif -#ifdef HAVE_SIGPENDING - {"sigpending", (PyCFunction)signal_sigpending, - METH_NOARGS, signal_sigpending_doc}, -#endif -#ifdef HAVE_SIGWAIT - {"sigwait", (PyCFunction)signal_sigwait, - METH_VARARGS, signal_sigwait_doc}, -#endif -#ifdef HAVE_SIGWAITINFO - {"sigwaitinfo", (PyCFunction)signal_sigwaitinfo, - METH_VARARGS, signal_sigwaitinfo_doc}, -#endif -#ifdef HAVE_SIGTIMEDWAIT - {"sigtimedwait", (PyCFunction)signal_sigtimedwait, - METH_VARARGS, signal_sigtimedwait_doc}, -#endif - {NULL, NULL} /* sentinel */ + 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 + {NULL, NULL} /* sentinel */ }; @@ -955,7 +1180,7 @@ the first is the signal number, the second is the interrupted stack frame."); static struct PyModuleDef signalmodule = { PyModuleDef_HEAD_INIT, - "signal", + "_signal", module_doc, -1, signal_methods, @@ -966,7 +1191,7 @@ static struct PyModuleDef signalmodule = { }; PyMODINIT_FUNC -PyInit_signal(void) +PyInit__signal(void) { PyObject *m, *d, *x; int i; @@ -1305,12 +1530,9 @@ finisignal(void) Py_XDECREF(func); } - Py_XDECREF(IntHandler); - IntHandler = NULL; - Py_XDECREF(DefaultHandler); - DefaultHandler = NULL; - Py_XDECREF(IgnoreHandler); - IgnoreHandler = NULL; + Py_CLEAR(IntHandler); + Py_CLEAR(DefaultHandler); + Py_CLEAR(IgnoreHandler); } @@ -1382,7 +1604,7 @@ PyErr_SetInterrupt(void) void PyOS_InitInterrupts(void) { - PyObject *m = PyImport_ImportModule("signal"); + PyObject *m = PyImport_ImportModule("_signal"); if (m) { Py_DECREF(m); } diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 9e0da132688c..bae9634ef2b0 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -33,8 +33,8 @@ Module interface: - 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, socktype, proto, flags]) - --> List of (family, socktype, proto, canonname, sockaddr) +- 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 @@ -121,7 +121,7 @@ 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\ +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\ @@ -188,7 +188,7 @@ if_indextoname(index) -- return the corresponding interface name\n\ #if defined(WITH_THREAD) && (defined(__APPLE__) || \ (defined(__FreeBSD__) && __FreeBSD_version+0 < 503000) || \ defined(__OpenBSD__) || defined(__NetBSD__) || \ - defined(__VMS) || !defined(HAVE_GETADDRINFO)) + !defined(HAVE_GETADDRINFO)) #define USE_GETADDRINFO_LOCK #endif @@ -212,10 +212,6 @@ if_indextoname(index) -- return the corresponding interface name\n\ # include #endif -#if defined(__VMS) -# include -#endif - #ifdef __APPLE__ # include #endif @@ -288,14 +284,15 @@ if_indextoname(index) -- return the corresponding interface name\n\ # include # endif +#if defined(_MSC_VER) && _MSC_VER >= 1800 +/* Provides the IsWindows7SP1OrGreater() function */ +#include #endif -#include - -#ifndef offsetof -# define offsetof(type, member) ((size_t)(&((type *)0)->member)) #endif +#include + #ifndef O_NONBLOCK # define O_NONBLOCK O_NDELAY #endif @@ -403,11 +400,6 @@ const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); #endif #endif -#ifdef __VMS -/* TCP/IP Services for VMS uses a maximum send/recv buffer length */ -#define SEGMENT_SIZE (32 * 1024 -1) -#endif - /* Convert "sock_addr_t *" to "struct sockaddr *". */ #define SAS2SA(x) (&((x)->sa)) @@ -468,7 +460,7 @@ static PyTypeObject sock_type; #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.0) +#define IS_SELECTABLE(s) (_PyIsSelectable_fd((s)->sock_fd) || (s)->sock_timeout <= 0) #endif static PyObject* @@ -489,6 +481,19 @@ select_error(void) (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 MS_WINDOWS /* Does WSASocket() support the WSA_FLAG_NO_HANDLE_INHERIT flag? */ static int support_wsa_no_inherit = -1; @@ -556,37 +561,17 @@ set_gaierror(int error) return NULL; } -#ifdef __VMS -/* Function to send in segments */ -static int -sendsegmented(int sock_fd, char *buf, int len, int flags) -{ - int n = 0; - int remaining = len; - - while (remaining > 0) { - unsigned int segment; - - segment = (remaining >= SEGMENT_SIZE ? SEGMENT_SIZE : remaining); - n = send(sock_fd, buf, segment, flags); - if (n < 0) { - return n; - } - remaining -= segment; - buf += segment; - } /* end while */ - - return len; -} -#endif - /* Function to perform the setting of socket blocking mode internally. block = (1 | 0). */ static int internal_setblocking(PySocketSockObject *s, int block) { -#ifndef MS_WINDOWS - int delay_flag; +#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 #ifdef SOCK_NONBLOCK if (block) @@ -597,20 +582,21 @@ internal_setblocking(PySocketSockObject *s, int block) Py_BEGIN_ALLOW_THREADS #ifndef MS_WINDOWS -#if defined(__VMS) +#if (defined(HAVE_SYS_IOCTL_H) && defined(FIONBIO)) block = !block; ioctl(s->sock_fd, FIONBIO, (unsigned int *)&block); -#else /* !__VMS */ +#else delay_flag = fcntl(s->sock_fd, F_GETFL, 0); if (block) - delay_flag &= (~O_NONBLOCK); + new_delay_flag = delay_flag & (~O_NONBLOCK); else - delay_flag |= O_NONBLOCK; - fcntl(s->sock_fd, F_SETFL, delay_flag); -#endif /* !__VMS */ + new_delay_flag = delay_flag | O_NONBLOCK; + if (new_delay_flag != delay_flag) + fcntl(s->sock_fd, F_SETFL, new_delay_flag); +#endif #else /* MS_WINDOWS */ - block = !block; - ioctlsocket(s->sock_fd, FIONBIO, (u_long*)&block); + arg = !block; + ioctlsocket(s->sock_fd, FIONBIO, &arg); #endif /* MS_WINDOWS */ Py_END_ALLOW_THREADS @@ -618,60 +604,79 @@ internal_setblocking(PySocketSockObject *s, int block) return 1; } -/* Do a select()/poll() on the socket, if necessary (sock_timeout > 0). - The argument writing indicates the direction. - This does not raise an exception; we'll let our caller do that - after they've reacquired the interpreter lock. - Returns 1 on timeout, -1 on error, 0 otherwise. */ static int -internal_select_ex(PySocketSockObject *s, int writing, double interval) +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 - /* Nothing to do unless we're in timeout mode (not non-blocking) */ - if (s->sock_timeout <= 0.0) - return 0; +#ifdef WITH_THREAD + /* must be called with the GIL held */ + assert(PyGILState_Check()); +#endif + + /* Error condition is for output only */ + assert(!(connect && !writing)); /* Guard against closed socket */ if (s->sock_fd < 0) return 0; - /* Handling this condition here simplifies the select loops */ - if (interval < 0.0) - return 1; - /* Prefer poll, if available, since you can poll() any fd * which can't be done with select(). */ #ifdef HAVE_POLL - { - struct pollfd pollfd; - int timeout; + 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; + } - pollfd.fd = s->sock_fd; - pollfd.events = writing ? POLLOUT : POLLIN; + /* s->sock_timeout is in seconds, timeout in ms */ + ms = _PyTime_AsMilliseconds(interval, _PyTime_ROUND_CEILING); + assert(ms <= INT_MAX); - /* s->sock_timeout is in seconds, timeout in ms */ - timeout = (int)(interval * 1000 + 0.5); - n = poll(&pollfd, 1, timeout); - } + Py_BEGIN_ALLOW_THREADS; + n = poll(&pollfd, 1, (int)ms); + Py_END_ALLOW_THREADS; #else - { - /* Construct the arguments to select */ - fd_set fds; - struct timeval tv; - tv.tv_sec = (int)interval; - tv.tv_usec = (int)((interval - tv.tv_sec) * 1e6); - FD_ZERO(&fds); - FD_SET(s->sock_fd, &fds); - - /* See if the socket is ready */ - if (writing) - n = select(Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int), - NULL, &fds, NULL, &tv); - else - n = select(Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int), - &fds, NULL, NULL, &tv); + 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) @@ -681,56 +686,168 @@ internal_select_ex(PySocketSockObject *s, int writing, double interval) 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 -internal_select(PySocketSockObject *s, int writing) +sock_call_ex(PySocketSockObject *s, + int writing, + int (*sock_func) (PySocketSockObject *s, void *data), + void *data, + int connect, + int *err, + _PyTime_t timeout) { - return internal_select_ex(s, writing, s->sock_timeout); -} + int has_timeout = (timeout > 0); + _PyTime_t deadline = 0; + int deadline_initialized = 0; + int res; -/* - Two macros for automatic retry of select() in case of false positives - (for example, select() could indicate a socket is ready for reading - but the data then discarded by the OS because of a wrong checksum). - Here is an example of use: +#ifdef WITH_THREAD + /* sock_call() must be called with the GIL held. */ + assert(PyGILState_Check()); +#endif - BEGIN_SELECT_LOOP(s) - Py_BEGIN_ALLOW_THREADS - timeout = internal_select_ex(s, 0, interval); - if (!timeout) - outlen = recv(s->sock_fd, cbuf, len, flags); - Py_END_ALLOW_THREADS - if (timeout == 1) { - PyErr_SetString(socket_timeout, "timed out"); + /* 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; } - END_SELECT_LOOP(s) -*/ +} + +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); +} -#define BEGIN_SELECT_LOOP(s) \ - { \ - _PyTime_timeval now, deadline = {0, 0}; \ - double interval = s->sock_timeout; \ - int has_timeout = s->sock_timeout > 0.0; \ - if (has_timeout) { \ - _PyTime_gettimeofday(&now); \ - deadline = now; \ - _PyTime_ADD_SECONDS(deadline, s->sock_timeout); \ - } \ - while (1) { \ - errno = 0; \ - -#define END_SELECT_LOOP(s) \ - if (!has_timeout || \ - (!CHECK_ERRNO(EWOULDBLOCK) && !CHECK_ERRNO(EAGAIN))) \ - break; \ - _PyTime_gettimeofday(&now); \ - interval = _PyTime_INTERVAL(now, deadline); \ - } \ - } \ /* Initialize a new socket object. */ -static double defaulttimeout = -1.0; /* Default timeout for new sockets */ +/* Default timeout for new sockets */ +static _PyTime_t defaulttimeout = _PYTIME_FROMSECONDS(-1); static void init_sockobject(PySocketSockObject *s, @@ -744,12 +861,12 @@ init_sockobject(PySocketSockObject *s, s->errorhandler = &set_error; #ifdef SOCK_NONBLOCK if (type & SOCK_NONBLOCK) - s->sock_timeout = 0.0; + s->sock_timeout = 0; else #endif { s->sock_timeout = defaulttimeout; - if (defaulttimeout >= 0.0) + if (defaulttimeout >= 0) internal_setblocking(s, 0); } @@ -1245,6 +1362,71 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) } } +/* 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, *obj3; + 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) && PyUnicode_READY(obj) == 0 && PyUnicode_IS_COMPACT_ASCII(obj)) { + data->buf = PyUnicode_DATA(obj); + len = PyUnicode_GET_LENGTH(obj); + } + else { + obj2 = PyUnicode_FromObject(obj); + if (!obj2) { + PyErr_Format(PyExc_TypeError, "string or unicode text buffer expected, not %s", + obj->ob_type->tp_name); + return 0; + } + obj3 = PyUnicode_AsEncodedString(obj2, "idna", NULL); + Py_DECREF(obj2); + if (!obj3) { + PyErr_SetString(PyExc_TypeError, "encoding of hostname failed"); + return 0; + } + if (!PyBytes_Check(obj3)) { + Py_DECREF(obj3); + PyErr_SetString(PyExc_TypeError, "encoding of hostname failed to return bytes"); + return 0; + } + data->obj = obj3; + data->buf = PyBytes_AS_STRING(obj3); + len = PyBytes_GET_SIZE(obj3); + } + 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, @@ -1261,8 +1443,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, case AF_UNIX: { struct sockaddr_un* addr; - char *path; - int len; + Py_buffer path; int retval = 0; /* PEP 383. Not using PyUnicode_FSConverter since we need to @@ -1273,14 +1454,17 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, } else Py_INCREF(args); - if (!PyArg_Parse(args, "y#", &path, &len)) - goto unix_out; + if (!PyArg_Parse(args, "y*", &path)) { + Py_DECREF(args); + return retval; + } + assert(path.len >= 0); addr = (struct sockaddr_un*)addr_ret; #ifdef linux - if (len > 0 && path[0] == 0) { + if (path.len > 0 && *(const char *)path.buf == 0) { /* Linux abstract namespace extension */ - if (len > sizeof addr->sun_path) { + if ((size_t)path.len > sizeof addr->sun_path) { PyErr_SetString(PyExc_OSError, "AF_UNIX path too long"); goto unix_out; @@ -1290,18 +1474,19 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, #endif /* linux */ { /* regular NULL-terminated string */ - if (len >= sizeof addr->sun_path) { + if ((size_t)path.len >= sizeof addr->sun_path) { PyErr_SetString(PyExc_OSError, "AF_UNIX path too long"); goto unix_out; } - addr->sun_path[len] = 0; + addr->sun_path[path.len] = 0; } addr->sun_family = s->sock_family; - memcpy(addr->sun_path, path, len); - *len_ret = len + offsetof(struct sockaddr_un, sun_path); + 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; } @@ -1339,7 +1524,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, case AF_INET: { struct sockaddr_in* addr; - char *host; + struct maybe_idna host = {NULL, NULL}; int port, result; if (!PyTuple_Check(args)) { PyErr_Format( @@ -1349,13 +1534,13 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, Py_TYPE(args)->tp_name); return 0; } - if (!PyArg_ParseTuple(args, "eti:getsockaddrarg", - "idna", &host, &port)) + if (!PyArg_ParseTuple(args, "O&i:getsockaddrarg", + idna_converter, &host, &port)) return 0; addr=(struct sockaddr_in*)addr_ret; - result = setipaddr(host, (struct sockaddr *)addr, + result = setipaddr(host.buf, (struct sockaddr *)addr, sizeof(*addr), AF_INET); - PyMem_Free(host); + idna_cleanup(&host); if (result < 0) return 0; if (port < 0 || port > 0xffff) { @@ -1374,7 +1559,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, case AF_INET6: { struct sockaddr_in6* addr; - char *host; + struct maybe_idna host = {NULL, NULL}; int port, result; unsigned int flowinfo, scope_id; flowinfo = scope_id = 0; @@ -1386,15 +1571,15 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, Py_TYPE(args)->tp_name); return 0; } - if (!PyArg_ParseTuple(args, "eti|II", - "idna", &host, &port, &flowinfo, + if (!PyArg_ParseTuple(args, "O&i|II", + idna_converter, &host, &port, &flowinfo, &scope_id)) { return 0; } addr = (struct sockaddr_in6*)addr_ret; - result = setipaddr(host, (struct sockaddr *)addr, + result = setipaddr(host.buf, (struct sockaddr *)addr, sizeof(*addr), AF_INET6); - PyMem_Free(host); + idna_cleanup(&host); if (result < 0) return 0; if (port < 0 || port > 0xffff) { @@ -1523,8 +1708,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, int protoNumber; int hatype = 0; int pkttype = 0; - char *haddr = NULL; - unsigned int halen = 0; + Py_buffer haddr = {NULL, NULL}; if (!PyTuple_Check(args)) { PyErr_Format( @@ -1534,25 +1718,28 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, Py_TYPE(args)->tp_name); return 0; } - if (!PyArg_ParseTuple(args, "si|iiy#", &interfaceName, + if (!PyArg_ParseTuple(args, "si|iiy*", &interfaceName, &protoNumber, &pkttype, &hatype, - &haddr, &halen)) + &haddr)) 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 (halen > 8) { - PyErr_SetString(PyExc_ValueError, - "Hardware address must be 8 bytes or less"); - 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_SetString( PyExc_OverflowError, "getsockaddrarg: protoNumber must be 0-65535."); + PyBuffer_Release(&haddr); return 0; } addr = (struct sockaddr_ll*)addr_ret; @@ -1561,11 +1748,14 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, addr->sll_ifindex = ifr.ifr_ifindex; addr->sll_pkttype = pkttype; addr->sll_hatype = hatype; - if (halen != 0) { - memcpy(&addr->sll_addr, haddr, halen); + if (haddr.buf) { + memcpy(&addr->sll_addr, haddr.buf, haddr.len); + addr->sll_halen = haddr.len; } - addr->sll_halen = halen; + else + addr->sll_halen = 0; *len_ret = sizeof *addr; + PyBuffer_Release(&haddr); return 1; } #endif @@ -1620,7 +1810,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, } #endif -#ifdef AF_CAN +#if defined(AF_CAN) && defined(CAN_RAW) && defined(CAN_BCM) case AF_CAN: switch (s->sock_proto) { case CAN_RAW: @@ -1642,7 +1832,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, if (len == 0) { ifr.ifr_ifindex = 0; - } else if (len < sizeof(ifr.ifr_name)) { + } 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) { @@ -1692,7 +1882,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, return 0; } - if (PyBytes_GET_SIZE(ctl_name) > sizeof(info.ctl_name)) { + 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); @@ -1916,8 +2106,29 @@ cmsg_min_space(struct msghdr *msg, struct cmsghdr *cmsgh, size_t space) sizeof(cmsgh->cmsg_len)); /* Note that POSIX allows msg_controllen to be of signed type. */ - if (cmsgh == NULL || msg->msg_control == NULL || msg->msg_controllen < 0) + 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; @@ -1972,22 +2183,56 @@ get_cmsg_data_len(struct msghdr *msg, struct cmsghdr *cmsgh, size_t *data_len) #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; + +#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) + if (accept4_works != 0) { + ctx->result = accept4(s->sock_fd, SAS2SA(ctx->addrbuf), ctx->addrlen, + 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, SAS2SA(ctx->addrbuf), ctx->addrlen); +#else + ctx->result = accept(s->sock_fd, SAS2SA(ctx->addrbuf), ctx->addrlen); +#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) { sock_addr_t addrbuf; - SOCKET_T newfd = INVALID_SOCKET; + SOCKET_T newfd; socklen_t addrlen; PyObject *sock = NULL; PyObject *addr = NULL; PyObject *res = NULL; - int timeout; -#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 + struct sock_accept ctx; if (!getsockaddrlen(s, &addrlen)) return NULL; @@ -1996,36 +2241,11 @@ sock_accept(PySocketSockObject *s) if (!IS_SELECTABLE(s)) return select_error(); - BEGIN_SELECT_LOOP(s) - - Py_BEGIN_ALLOW_THREADS - timeout = internal_select_ex(s, 0, interval); - if (!timeout) { -#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) - if (accept4_works != 0) { - newfd = accept4(s->sock_fd, SAS2SA(&addrbuf), &addrlen, - SOCK_CLOEXEC); - if (newfd == INVALID_SOCKET && accept4_works == -1) { - /* On Linux older than 2.6.28, accept4() fails with ENOSYS */ - accept4_works = (errno != ENOSYS); - } - } - if (accept4_works == 0) - newfd = accept(s->sock_fd, SAS2SA(&addrbuf), &addrlen); -#else - newfd = accept(s->sock_fd, SAS2SA(&addrbuf), &addrlen); -#endif - } - Py_END_ALLOW_THREADS - - if (timeout == 1) { - PyErr_SetString(socket_timeout, "timed out"); + ctx.addrlen = &addrlen; + ctx.addrbuf = &addrbuf; + if (sock_call(s, 0, sock_accept_impl, &ctx) < 0) return NULL; - } - END_SELECT_LOOP(s) - - if (newfd == INVALID_SOCKET) - return s->errorhandler(); + newfd = ctx.result; #ifdef MS_WINDOWS if (!SetHandleInformation((HANDLE)newfd, HANDLE_FLAG_INHERIT, 0)) { @@ -2086,7 +2306,7 @@ sock_setblocking(PySocketSockObject *s, PyObject *arg) if (block == -1 && PyErr_Occurred()) return NULL; - s->sock_timeout = block ? -1.0 : 0.0; + s->sock_timeout = _PyTime_FromSeconds(block ? -1 : 0); internal_setblocking(s, block); Py_INCREF(Py_None); @@ -2100,6 +2320,47 @@ 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)."); +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_CEILING) < 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_CEILING) < 0); +#endif +#ifndef HAVE_POLL + ms = _PyTime_AsMilliseconds(*timeout, _PyTime_ROUND_CEILING); + 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) @@ -2109,22 +2370,13 @@ setblocking(False) is equivalent to settimeout(0.0)."); static PyObject * sock_settimeout(PySocketSockObject *s, PyObject *arg) { - double timeout; + _PyTime_t timeout; - if (arg == Py_None) - timeout = -1.0; - else { - timeout = PyFloat_AsDouble(arg); - if (timeout < 0.0) { - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_ValueError, - "Timeout value out of range"); - return NULL; - } - } + if (socket_parse_timeout(&timeout, arg) < 0) + return NULL; s->sock_timeout = timeout; - internal_setblocking(s, timeout < 0.0); + internal_setblocking(s, timeout < 0); Py_INCREF(Py_None); return Py_None; @@ -2143,12 +2395,14 @@ Setting a timeout of zero is the same as setblocking(0)."); static PyObject * sock_gettimeout(PySocketSockObject *s) { - if (s->sock_timeout < 0.0) { + if (s->sock_timeout < 0) { Py_INCREF(Py_None); return Py_None; } - else - return PyFloat_FromDouble(s->sock_timeout); + else { + double seconds = _PyTime_AsSecondsDouble(s->sock_timeout); + return PyFloat_FromDouble(seconds); + } } PyDoc_STRVAR(gettimeout_doc, @@ -2169,22 +2423,22 @@ sock_setsockopt(PySocketSockObject *s, PyObject *args) int level; int optname; int res; - char *buf; - int buflen; + Py_buffer optval; int flag; if (PyArg_ParseTuple(args, "iii:setsockopt", &level, &optname, &flag)) { - buf = (char *) &flag; - buflen = sizeof flag; + res = setsockopt(s->sock_fd, level, optname, + (char*)&flag, sizeof flag); } else { PyErr_Clear(); - if (!PyArg_ParseTuple(args, "iiy#:setsockopt", - &level, &optname, &buf, &buflen)) + if (!PyArg_ParseTuple(args, "iiy*:setsockopt", + &level, &optname, &optval)) return NULL; + res = setsockopt(s->sock_fd, level, optname, optval.buf, optval.len); + PyBuffer_Release(&optval); } - res = setsockopt(s->sock_fd, level, optname, (void *)buf, buflen); if (res < 0) return s->errorhandler(); Py_INCREF(Py_None); @@ -2225,13 +2479,7 @@ sock_getsockopt(PySocketSockObject *s, PyObject *args) return s->errorhandler(); return PyLong_FromLong(flag); } -#ifdef __VMS - /* socklen_t is unsigned so no negative test is needed, - test buflen == 0 is previously done */ - if (buflen > 1024) { -#else if (buflen <= 0 || buflen > 1024) { -#endif PyErr_SetString(PyExc_OSError, "getsockopt buflen out of range"); return NULL; @@ -2294,6 +2542,10 @@ sock_close(PySocketSockObject *s) { SOCKET_T fd; + /* 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. + */ if ((fd = s->sock_fd) != -1) { s->sock_fd = -1; Py_BEGIN_ALLOW_THREADS @@ -2320,97 +2572,95 @@ sock_detach(PySocketSockObject *s) PyDoc_STRVAR(detach_doc, "detach()\n\ \n\ -Close the socket object without closing the underlying file descriptor.\ -The object cannot be used after this call, but the file descriptor\ +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 *timeoutp) + int raise) { - int res, timeout; + int res, err, wait_connect; - timeout = 0; + Py_BEGIN_ALLOW_THREADS res = connect(s->sock_fd, addr, addrlen); + Py_END_ALLOW_THREADS -#ifdef MS_WINDOWS - - if (s->sock_timeout > 0.0) { - if (res < 0 && WSAGetLastError() == WSAEWOULDBLOCK && - IS_SELECTABLE(s)) { - /* This is a mess. Best solution: trust select */ - fd_set fds; - fd_set fds_exc; - struct timeval tv; - tv.tv_sec = (int)s->sock_timeout; - tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6); - FD_ZERO(&fds); - FD_SET(s->sock_fd, &fds); - FD_ZERO(&fds_exc); - FD_SET(s->sock_fd, &fds_exc); - res = select(Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int), - NULL, &fds, &fds_exc, &tv); - if (res == 0) { - res = WSAEWOULDBLOCK; - timeout = 1; - } else if (res > 0) { - if (FD_ISSET(s->sock_fd, &fds)) - /* The socket is in the writable set - this - means connected */ - res = 0; - else { - /* As per MS docs, we need to call getsockopt() - to get the underlying error */ - int res_size = sizeof res; - /* It must be in the exception set */ - assert(FD_ISSET(s->sock_fd, &fds_exc)); - if (0 == getsockopt(s->sock_fd, SOL_SOCKET, SO_ERROR, - (char *)&res, &res_size)) - /* getsockopt also clears WSAGetLastError, - so reset it back. */ - WSASetLastError(res); - else - res = WSAGetLastError(); - } - } - /* else if (res < 0) an error occurred */ - } + if (!res) { + /* connect() succeeded, the socket is connected */ + return 0; } - if (res < 0) - res = WSAGetLastError(); + /* connect() failed */ -#else + /* save error, PyErr_CheckSignals() can replace it */ + err = GET_SOCK_ERROR; + if (CHECK_ERRNO(EINTR)) { + if (PyErr_CheckSignals()) + return -1; - if (s->sock_timeout > 0.0) { - if (res < 0 && errno == EINPROGRESS && IS_SELECTABLE(s)) { - timeout = internal_select(s, 1); - if (timeout == 0) { - /* Bug #1019808: in case of an EINPROGRESS, - use getsockopt(SO_ERROR) to get the real - error. */ - socklen_t res_size = sizeof res; - (void)getsockopt(s->sock_fd, SOL_SOCKET, - SO_ERROR, &res, &res_size); - if (res == EISCONN) - res = 0; - errno = res; - } - else if (timeout == -1) { - res = errno; /* had error */ - } - else - res = EWOULDBLOCK; /* timed out */ - } - } + /* Issue #23618: when connect() fails with EINTR, the connection is + running asynchronously. - if (res < 0) - res = errno; + 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). -#endif - *timeoutp = timeout; + 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)); + } - return res; + 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 */ @@ -2421,23 +2671,15 @@ sock_connect(PySocketSockObject *s, PyObject *addro) sock_addr_t addrbuf; int addrlen; int res; - int timeout; if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen)) return NULL; - Py_BEGIN_ALLOW_THREADS - res = internal_connect(s, SAS2SA(&addrbuf), addrlen, &timeout); - Py_END_ALLOW_THREADS - - if (timeout == 1) { - PyErr_SetString(socket_timeout, "timed out"); + res = internal_connect(s, SAS2SA(&addrbuf), addrlen, 1); + if (res < 0) return NULL; - } - if (res != 0) - return s->errorhandler(); - Py_INCREF(Py_None); - return Py_None; + + Py_RETURN_NONE; } PyDoc_STRVAR(connect_doc, @@ -2455,21 +2697,13 @@ sock_connect_ex(PySocketSockObject *s, PyObject *addro) sock_addr_t addrbuf; int addrlen; int res; - int timeout; if (!getsockaddrarg(s, addro, SAS2SA(&addrbuf), &addrlen)) return NULL; - Py_BEGIN_ALLOW_THREADS - res = internal_connect(s, SAS2SA(&addrbuf), addrlen, &timeout); - Py_END_ALLOW_THREADS - - /* Signals are not errors (though they may raise exceptions). Adapted - from PyErr_SetFromErrnoWithFilenameObject(). */ -#ifdef EINTR - if (res == EINTR && PyErr_CheckSignals()) + res = internal_connect(s, SAS2SA(&addrbuf), addrlen, 0); + if (res < 0) return NULL; -#endif return PyLong_FromLong((long) res); } @@ -2557,14 +2791,16 @@ info is a pair (hostaddr, port)."); /* s.listen(n) method */ static PyObject * -sock_listen(PySocketSockObject *s, PyObject *arg) +sock_listen(PySocketSockObject *s, PyObject *args) { - int backlog; + /* 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; - backlog = _PyLong_AsInt(arg); - if (backlog == -1 && PyErr_Occurred()) + 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. */ @@ -2579,12 +2815,34 @@ sock_listen(PySocketSockObject *s, PyObject *arg) } PyDoc_STRVAR(listen_doc, -"listen(backlog)\n\ +"listen([backlog])\n\ \n\ -Enable a server to accept connections. The backlog argument must be at\n\ -least 0 (if it is lower, it is set to 0); it specifies the number of\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."); +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); +} /* @@ -2599,12 +2857,7 @@ connections."); static Py_ssize_t sock_recv_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags) { - Py_ssize_t outlen = -1; - int timeout; -#ifdef __VMS - int remaining; - char *read_buf; -#endif + struct sock_recv ctx; if (!IS_SELECTABLE(s)) { select_error(); @@ -2615,75 +2868,13 @@ sock_recv_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags) return 0; } -#ifndef __VMS - BEGIN_SELECT_LOOP(s) - Py_BEGIN_ALLOW_THREADS - timeout = internal_select_ex(s, 0, interval); - if (!timeout) { -#ifdef MS_WINDOWS - if (len > INT_MAX) - len = INT_MAX; - outlen = recv(s->sock_fd, cbuf, (int)len, flags); -#else - outlen = recv(s->sock_fd, cbuf, len, flags); -#endif - } - Py_END_ALLOW_THREADS - - if (timeout == 1) { - PyErr_SetString(socket_timeout, "timed out"); + ctx.cbuf = cbuf; + ctx.len = len; + ctx.flags = flags; + if (sock_call(s, 0, sock_recv_impl, &ctx) < 0) return -1; - } - END_SELECT_LOOP(s) - if (outlen < 0) { - /* Note: the call to errorhandler() ALWAYS indirectly returned - NULL, so ignore its return value */ - s->errorhandler(); - return -1; - } -#else - read_buf = cbuf; - remaining = len; - while (remaining != 0) { - unsigned int segment; - int nread = -1; - - segment = remaining /SEGMENT_SIZE; - if (segment != 0) { - segment = SEGMENT_SIZE; - } - else { - segment = remaining; - } - - BEGIN_SELECT_LOOP(s) - Py_BEGIN_ALLOW_THREADS - timeout = internal_select_ex(s, 0, interval); - if (!timeout) - nread = recv(s->sock_fd, read_buf, segment, flags); - Py_END_ALLOW_THREADS - if (timeout == 1) { - PyErr_SetString(socket_timeout, "timed out"); - return -1; - } - END_SELECT_LOOP(s) - - if (nread < 0) { - s->errorhandler(); - return -1; - } - if (nread != remaining) { - read_buf += nread; - break; - } - remaining -= segment; - read_buf += segment; - } - outlen = read_buf - cbuf; -#endif /* !__VMS */ - - return outlen; + return ctx.result; } @@ -2797,6 +2988,34 @@ 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 @@ -2814,9 +3033,8 @@ sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags, PyObject** addr) { sock_addr_t addrbuf; - int timeout; - Py_ssize_t n = -1; socklen_t addrlen; + struct sock_recvfrom ctx; *addr = NULL; @@ -2828,38 +3046,20 @@ sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, Py_ssize_t len, int flags, return -1; } - BEGIN_SELECT_LOOP(s) - Py_BEGIN_ALLOW_THREADS - memset(&addrbuf, 0, addrlen); - timeout = internal_select_ex(s, 0, interval); - if (!timeout) { -#ifdef MS_WINDOWS - if (len > INT_MAX) - len = INT_MAX; - n = recvfrom(s->sock_fd, cbuf, (int)len, flags, - (void *) &addrbuf, &addrlen); -#else - n = recvfrom(s->sock_fd, cbuf, len, flags, - SAS2SA(&addrbuf), &addrlen); -#endif - } - Py_END_ALLOW_THREADS - - if (timeout == 1) { - PyErr_SetString(socket_timeout, "timed out"); + 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; - } - END_SELECT_LOOP(s) - if (n < 0) { - s->errorhandler(); - return -1; - } - if (!(*addr = makesockaddr(s->sock_fd, SAS2SA(&addrbuf), - addrlen, s->sock_proto))) + *addr = makesockaddr(s->sock_fd, SAS2SA(&addrbuf), addrlen, + s->sock_proto); + if (*addr == NULL) return -1; - return n; + return ctx.result; } /* s.recvfrom(nbytes [,flags]) method */ @@ -2934,7 +3134,6 @@ sock_recvfrom_into(PySocketSockObject *s, PyObject *args, PyObject* kwds) return NULL; buf = pbuf.buf; buflen = pbuf.len; - assert(buf != 0 && buflen > 0); if (recvlen < 0) { PyBuffer_Release(&pbuf); @@ -2945,6 +3144,11 @@ sock_recvfrom_into(PySocketSockObject *s, PyObject *args, PyObject* kwds) 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); @@ -2966,10 +3170,24 @@ PyDoc_STRVAR(recvfrom_into_doc, \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 @@ -2985,8 +3203,6 @@ sock_recvmsg_guts(PySocketSockObject *s, struct iovec *iov, int iovlen, int flags, Py_ssize_t controllen, PyObject *(*makeval)(ssize_t, void *), void *makeval_data) { - ssize_t bytes_received = -1; - int timeout; sock_addr_t addrbuf; socklen_t addrbuflen; struct msghdr msg = {0}; @@ -2995,6 +3211,7 @@ sock_recvmsg_guts(PySocketSockObject *s, struct iovec *iov, int iovlen, 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 @@ -3021,28 +3238,17 @@ sock_recvmsg_guts(PySocketSockObject *s, struct iovec *iov, int iovlen, goto finally; } - BEGIN_SELECT_LOOP(s) - Py_BEGIN_ALLOW_THREADS; 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; - timeout = internal_select_ex(s, 0, interval); - if (!timeout) - bytes_received = recvmsg(s->sock_fd, &msg, flags); - Py_END_ALLOW_THREADS; - if (timeout == 1) { - PyErr_SetString(socket_timeout, "timed out"); - goto finally; - } - END_SELECT_LOOP(s) - if (bytes_received < 0) { - s->errorhandler(); + 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) @@ -3084,7 +3290,7 @@ sock_recvmsg_guts(PySocketSockObject *s, struct iovec *iov, int iovlen, } retval = Py_BuildValue("NOiN", - (*makeval)(bytes_received, makeval_data), + (*makeval)(ctx.result, makeval_data), cmsg_list, (int)msg.msg_flags, makesockaddr(s->sock_fd, SAS2SA(&addrbuf), @@ -3292,15 +3498,36 @@ 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) { - char *buf; - Py_ssize_t len, n = -1; - int flags = 0, timeout; + int flags = 0; Py_buffer pbuf; + struct sock_send ctx; if (!PyArg_ParseTuple(args, "y*|i:send", &pbuf, &flags)) return NULL; @@ -3309,35 +3536,16 @@ sock_send(PySocketSockObject *s, PyObject *args) PyBuffer_Release(&pbuf); return select_error(); } - buf = pbuf.buf; - len = pbuf.len; - - BEGIN_SELECT_LOOP(s) - Py_BEGIN_ALLOW_THREADS - timeout = internal_select_ex(s, 1, interval); - if (!timeout) { -#ifdef __VMS - n = sendsegmented(s->sock_fd, buf, len, flags); -#elif defined(MS_WINDOWS) - if (len > INT_MAX) - len = INT_MAX; - n = send(s->sock_fd, buf, (int)len, flags); -#else - n = send(s->sock_fd, buf, len, flags); -#endif - } - Py_END_ALLOW_THREADS - if (timeout == 1) { + ctx.buf = pbuf.buf; + ctx.len = pbuf.len; + ctx.flags = flags; + if (sock_call(s, 1, sock_send_impl, &ctx) < 0) { PyBuffer_Release(&pbuf); - PyErr_SetString(socket_timeout, "timed out"); return NULL; } - END_SELECT_LOOP(s) - PyBuffer_Release(&pbuf); - if (n < 0) - return s->errorhandler(); - return PyLong_FromSsize_t(n); + + return PyLong_FromSsize_t(ctx.result); } PyDoc_STRVAR(send_doc, @@ -3354,9 +3562,15 @@ static PyObject * sock_sendall(PySocketSockObject *s, PyObject *args) { char *buf; - Py_ssize_t len, n = -1; - int flags = 0, timeout, saved_errno; + 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; @@ -3369,52 +3583,47 @@ sock_sendall(PySocketSockObject *s, PyObject *args) } do { - Py_BEGIN_ALLOW_THREADS - timeout = internal_select(s, 1); - n = -1; - if (!timeout) { -#ifdef __VMS - n = sendsegmented(s->sock_fd, buf, len, flags); -#elif defined(MS_WINDOWS) - if (len > INT_MAX) - len = INT_MAX; - n = send(s->sock_fd, buf, (int)len, flags); -#else - n = send(s->sock_fd, buf, len, flags); -#endif - } - Py_END_ALLOW_THREADS - if (timeout == 1) { - PyBuffer_Release(&pbuf); - PyErr_SetString(socket_timeout, "timed out"); - return NULL; + 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; + } } - /* PyErr_CheckSignals() might change errno */ - saved_errno = errno; + + 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()) { - PyBuffer_Release(&pbuf); - return NULL; - } - if (n < 0) { - /* If interrupted, try again */ - if (saved_errno == EINTR) - continue; - else - break; - } - buf += n; - len -= n; + if (PyErr_CheckSignals()) + goto done; } while (len > 0); PyBuffer_Release(&pbuf); - if (n < 0) - return s->errorhandler(); - Py_INCREF(Py_None); - return Py_None; + res = Py_None; + +done: + PyBuffer_Release(&pbuf); + return res; } PyDoc_STRVAR(sendall_doc, @@ -3426,6 +3635,32 @@ 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 * @@ -3433,10 +3668,10 @@ sock_sendto(PySocketSockObject *s, PyObject *args) { Py_buffer pbuf; PyObject *addro; - char *buf; - Py_ssize_t len, arglen; + Py_ssize_t arglen; sock_addr_t addrbuf; - int addrlen, n = -1, flags, timeout; + int addrlen, flags; + struct sock_sendto ctx; flags = 0; arglen = PyTuple_Size(args); @@ -3457,9 +3692,6 @@ sock_sendto(PySocketSockObject *s, PyObject *args) if (PyErr_Occurred()) return NULL; - buf = pbuf.buf; - len = pbuf.len; - if (!IS_SELECTABLE(s)) { PyBuffer_Release(&pbuf); return select_error(); @@ -3470,32 +3702,18 @@ sock_sendto(PySocketSockObject *s, PyObject *args) return NULL; } - BEGIN_SELECT_LOOP(s) - Py_BEGIN_ALLOW_THREADS - timeout = internal_select_ex(s, 1, interval); - if (!timeout) { -#ifdef MS_WINDOWS - if (len > INT_MAX) - len = INT_MAX; - n = sendto(s->sock_fd, buf, (int)len, flags, - SAS2SA(&addrbuf), addrlen); -#else - n = sendto(s->sock_fd, buf, len, flags, - SAS2SA(&addrbuf), addrlen); -#endif - } - Py_END_ALLOW_THREADS - - if (timeout == 1) { + 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); - PyErr_SetString(socket_timeout, "timed out"); return NULL; } - END_SELECT_LOOP(s) PyBuffer_Release(&pbuf); - if (n < 0) - return s->errorhandler(); - return PyLong_FromSsize_t(n); + + return PyLong_FromSsize_t(ctx.result); } PyDoc_STRVAR(sendto_doc, @@ -3508,6 +3726,21 @@ 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_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 * @@ -3525,10 +3758,10 @@ sock_sendmsg(PySocketSockObject *s, PyObject *args) } *cmsgs = NULL; void *controlbuf = NULL; size_t controllen, controllen_last; - ssize_t bytes_sent = -1; - int addrlen, timeout, flags = 0; + int addrlen, flags = 0; PyObject *data_arg, *cmsg_arg = NULL, *addr_arg = NULL, *data_fast = NULL, *cmsg_fast = NULL, *retval = NULL; + struct sock_sendmsg ctx; if (!PyArg_ParseTuple(args, "O|OiO:sendmsg", &data_arg, &cmsg_arg, &flags, &addr_arg)) @@ -3563,7 +3796,7 @@ sock_sendmsg(PySocketSockObject *s, PyObject *args) for (; ndatabufs < ndataparts; ndatabufs++) { if (!PyArg_Parse(PySequence_Fast_GET_ITEM(data_fast, ndatabufs), "y*;sendmsg() argument 1 must be an iterable of " - "buffer-compatible objects", + "bytes-like objects", &databufs[ndatabufs])) goto finally; iovs[ndatabufs].iov_base = databufs[ndatabufs].buf; @@ -3682,23 +3915,12 @@ sock_sendmsg(PySocketSockObject *s, PyObject *args) goto finally; } - BEGIN_SELECT_LOOP(s) - Py_BEGIN_ALLOW_THREADS; - timeout = internal_select_ex(s, 1, interval); - if (!timeout) - bytes_sent = sendmsg(s->sock_fd, &msg, flags); - Py_END_ALLOW_THREADS; - if (timeout == 1) { - PyErr_SetString(socket_timeout, "timed out"); + ctx.msg = &msg; + ctx.flags = flags; + if (sock_call(s, 1, sock_sendmsg_impl, &ctx) < 0) goto finally; - } - END_SELECT_LOOP(s) - if (bytes_sent < 0) { - s->errorhandler(); - goto finally; - } - retval = PyLong_FromSsize_t(bytes_sent); + retval = PyLong_FromSsize_t(ctx.result); finally: PyMem_Free(controlbuf); @@ -3720,12 +3942,12 @@ PyDoc_STRVAR(sendmsg_doc, 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 buffer-compatible objects (e.g. bytes objects).\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 buffer-compatible object holding the associated data. The flags\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\ @@ -3865,7 +4087,7 @@ static PyMethodDef sock_methods[] = { {"share", (PyCFunction)sock_share, METH_VARARGS, sock_share_doc}, #endif - {"listen", (PyCFunction)sock_listen, METH_O, + {"listen", (PyCFunction)sock_listen, METH_VARARGS, listen_doc}, {"recv", (PyCFunction)sock_recv, METH_VARARGS, recv_doc}, @@ -3907,10 +4129,14 @@ 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"}, - {"timeout", T_DOUBLE, offsetof(PySocketSockObject, sock_timeout), READONLY, "the socket timeout"}, {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. */ @@ -3938,8 +4164,13 @@ sock_dealloc(PySocketSockObject *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 - if (s->sock_fd > LONG_MAX) { + 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*/ @@ -3949,9 +4180,11 @@ sock_repr(PySocketSockObject *s) return NULL; } #endif + else + sock_fd = (long)s->sock_fd; return PyUnicode_FromFormat( "", - (long)s->sock_fd, s->sock_family, + sock_fd, s->sock_family, s->sock_type, s->sock_proto); } @@ -3967,7 +4200,7 @@ sock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) new = type->tp_alloc(type, 0); if (new != NULL) { ((PySocketSockObject *)new)->sock_fd = -1; - ((PySocketSockObject *)new)->sock_timeout = -1.0; + ((PySocketSockObject *)new)->sock_timeout = _PyTime_FromSeconds(-1); ((PySocketSockObject *)new)->errorhandler = &set_error; } return new; @@ -4150,7 +4383,7 @@ static PyTypeObject sock_type = { 0, /* tp_iternext */ sock_methods, /* tp_methods */ sock_memberlist, /* tp_members */ - 0, /* tp_getset */ + sock_getsetlist, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ @@ -4189,9 +4422,11 @@ socket_gethostname(PyObject *self, PyObject *unused) /* MSDN says ERROR_MORE_DATA may occur because DNS allows longer names */ - name = PyMem_Malloc(size * sizeof(wchar_t)); - if (!name) + name = PyMem_New(wchar_t, size); + if (!name) { + PyErr_NoMemory(); return NULL; + } if (!GetComputerNameExW(ComputerNamePhysicalDnsHostname, name, &size)) @@ -4287,7 +4522,7 @@ Return the IP address (a string of the form '255.255.255.255') for a host."); /* Convenience function common to gethostbyname_ex and gethostbyaddr */ static PyObject * -gethost_common(struct hostent *h, struct sockaddr *addr, int alen, int af) +gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af) { char **pch; PyObject *rtn_tuple = (PyObject *)NULL; @@ -5004,21 +5239,22 @@ Convert an IP address from 32-bit packed binary format to string format"); static PyObject* socket_inet_ntoa(PyObject *self, PyObject *args) { - char *packed_str; - int addr_len; + Py_buffer packed_ip; struct in_addr packed_addr; - if (!PyArg_ParseTuple(args, "y#:inet_ntoa", &packed_str, &addr_len)) { + if (!PyArg_ParseTuple(args, "y*:inet_ntoa", &packed_ip)) { return NULL; } - if (addr_len != sizeof(packed_addr)) { + 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_str, addr_len); + memcpy(&packed_addr, packed_ip.buf, packed_ip.len); + PyBuffer_Release(&packed_ip); return PyUnicode_FromString(inet_ntoa(packed_addr)); } @@ -5129,8 +5365,7 @@ static PyObject * socket_inet_ntop(PyObject *self, PyObject *args) { int af; - char* packed; - int len; + Py_buffer packed_ip; const char* retval; #ifdef ENABLE_IPV6 char ip[Py_MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) + 1]; @@ -5141,31 +5376,35 @@ socket_inet_ntop(PyObject *self, PyObject *args) /* Guarantee NUL-termination for PyUnicode_FromString() below */ memset((void *) &ip[0], '\0', sizeof(ip)); - if (!PyArg_ParseTuple(args, "iy#:inet_ntop", &af, &packed, &len)) { + if (!PyArg_ParseTuple(args, "iy*:inet_ntop", &af, &packed_ip)) { return NULL; } if (af == AF_INET) { - if (len != sizeof(struct in_addr)) { + 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 (len != sizeof(struct in6_addr)) { + 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; } - retval = inet_ntop(af, packed, ip, sizeof(ip)); + retval = inet_ntop(af, packed_ip.buf, ip, sizeof(ip)); + PyBuffer_Release(&packed_ip); if (!retval) { PyErr_SetFromErrno(PyExc_OSError); return NULL; @@ -5184,8 +5423,7 @@ static PyObject * socket_inet_ntop(PyObject *self, PyObject *args) { int af; - char* packed; - int len; + Py_buffer packed_ip; struct sockaddr_in6 addr; DWORD addrlen, ret, retlen; #ifdef ENABLE_IPV6 @@ -5197,38 +5435,42 @@ socket_inet_ntop(PyObject *self, PyObject *args) /* Guarantee NUL-termination for PyUnicode_FromString() below */ memset((void *) &ip[0], '\0', sizeof(ip)); - if (!PyArg_ParseTuple(args, "iy#:inet_ntop", &af, &packed, &len)) { + if (!PyArg_ParseTuple(args, "iy*:inet_ntop", &af, &packed_ip)) { return NULL; } if (af == AF_INET) { struct sockaddr_in * addr4 = (struct sockaddr_in *)&addr; - if (len != sizeof(struct in_addr)) { + 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; } memset(addr4, 0, sizeof(struct sockaddr_in)); addr4->sin_family = AF_INET; - memcpy(&(addr4->sin_addr), packed, sizeof(addr4->sin_addr)); + memcpy(&(addr4->sin_addr), packed_ip.buf, sizeof(addr4->sin_addr)); addrlen = sizeof(struct sockaddr_in); } else if (af == AF_INET6) { - if (len != sizeof(struct in6_addr)) { + 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; } memset(&addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; - memcpy(&(addr.sin6_addr), packed, sizeof(addr.sin6_addr)); + memcpy(&(addr.sin6_addr), packed_ip.buf, sizeof(addr.sin6_addr)); addrlen = sizeof(addr); } else { PyErr_Format(PyExc_ValueError, "unknown address family %d", af); + PyBuffer_Release(&packed_ip); return NULL; } + PyBuffer_Release(&packed_ip); retlen = sizeof(ip); ret = WSAAddressToStringA((struct sockaddr*)&addr, addrlen, NULL, @@ -5273,9 +5515,7 @@ socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) if (hobj == Py_None) { hptr = NULL; } else if (PyUnicode_Check(hobj)) { - _Py_IDENTIFIER(encode); - - idna = _PyObject_CallMethodId(hobj, &PyId_encode, "s", "idna"); + idna = PyUnicode_AsEncodedString(hobj, "idna", NULL); if (!idna) return NULL; assert(PyBytes_Check(idna)); @@ -5308,9 +5548,9 @@ socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) #if defined(__APPLE__) && defined(AI_NUMERICSERV) if ((flags & AI_NUMERICSERV) && (pptr == NULL || (pptr[0] == '0' && pptr[1] == 0))) { /* On OSX upto 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. - */ + * if AI_NUMERICSERV is set and the servname is NULL or "0". + * This workaround avoids a segfault in libsystem. + */ pptr = "00"; } #endif @@ -5329,7 +5569,8 @@ socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) goto err; } - if ((all = PyList_New(0)) == NULL) + all = PyList_New(0); + if (all == NULL) goto err; for (res = res0; res; res = res->ai_next) { PyObject *single; @@ -5362,8 +5603,8 @@ socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) } PyDoc_STRVAR(getaddrinfo_doc, -"getaddrinfo(host, port [, family, socktype, proto, flags])\n\ - -> list of (family, socktype, proto, canonname, sockaddr)\n\ +"getaddrinfo(host, port [, family, type, proto, flags])\n\ + -> list of (family, type, proto, canonname, sockaddr)\n\ \n\ Resolve host and port into addrinfo struct."); @@ -5464,12 +5705,14 @@ Get host and port for a sockaddr."); static PyObject * socket_getdefaulttimeout(PyObject *self) { - if (defaulttimeout < 0.0) { + if (defaulttimeout < 0) { Py_INCREF(Py_None); return Py_None; } - else - return PyFloat_FromDouble(defaulttimeout); + else { + double seconds = _PyTime_AsSecondsDouble(defaulttimeout); + return PyFloat_FromDouble(seconds); + } } PyDoc_STRVAR(getdefaulttimeout_doc, @@ -5482,19 +5725,10 @@ When the socket module is first imported, the default is None."); static PyObject * socket_setdefaulttimeout(PyObject *self, PyObject *arg) { - double timeout; + _PyTime_t timeout; - if (arg == Py_None) - timeout = -1.0; - else { - timeout = PyFloat_AsDouble(arg); - if (timeout < 0.0) { - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_ValueError, - "Timeout value out of range"); - return NULL; - } - } + if (socket_parse_timeout(&timeout, arg) < 0) + return NULL; defaulttimeout = timeout; @@ -5841,11 +6075,15 @@ PyInit__socket(void) #ifdef MS_WINDOWS if (support_wsa_no_inherit == -1) { +#if defined(_MSC_VER) && _MSC_VER >= 1800 + support_wsa_no_inherit = IsWindows7SP1OrGreater(); +#else DWORD version = GetVersion(); DWORD major = (DWORD)LOBYTE(LOWORD(version)); DWORD minor = (DWORD)HIBYTE(LOWORD(version)); /* need Windows 7 SP1, 2008 R2 SP1 or later */ - support_wsa_no_inherit = (major >= 6 && minor >= 1); + support_wsa_no_inherit = major > 6 || (major == 6 && minor >= 1); +#endif } #endif @@ -6244,6 +6482,9 @@ PyInit__socket(void) #ifdef SO_PRIORITY PyModule_AddIntMacro(m, SO_PRIORITY); #endif +#ifdef SO_MARK + PyModule_AddIntMacro(m, SO_MARK); +#endif /* Maximum number of connections for "listen" */ #ifdef SOMAXCONN @@ -6381,6 +6622,9 @@ PyInit__socket(void) 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); PyModule_AddIntConstant(m, "CAN_BCM_TX_SETUP", TX_SETUP); diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h index b83f9af3bded..3cce927e0b35 100644 --- a/Modules/socketmodule.h +++ b/Modules/socketmodule.h @@ -14,6 +14,13 @@ #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 @@ -167,7 +174,7 @@ typedef struct { PyObject *(*errorhandler)(void); /* Error handler; checks errno, returns NULL and sets a Python exception */ - double sock_timeout; /* Operation timeout in seconds; + _PyTime_t sock_timeout; /* Operation timeout in seconds; 0.0 means non-blocking */ } PySocketSockObject; diff --git a/Modules/spwdmodule.c b/Modules/spwdmodule.c index 68ea1b5ea4af..49324d50f839 100644 --- a/Modules/spwdmodule.c +++ b/Modules/spwdmodule.c @@ -10,6 +10,12 @@ #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\ @@ -107,20 +113,25 @@ static PyObject *mkspent(struct spwd *p) #ifdef HAVE_GETSPNAM -PyDoc_STRVAR(spwd_getspnam__doc__, -"getspnam(name) -> (sp_namp, sp_pwdp, sp_lstchg, sp_min, sp_max,\n\ - sp_warn, sp_inact, sp_expire, sp_flag)\n\ -Return the shadow password database entry for the given user name.\n\ -See spwd.__doc__ for more on shadow password database entries."); +/*[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(PyObject *self, PyObject *args) +static PyObject * +spwd_getspnam_impl(PyModuleDef *module, PyObject *arg) +/*[clinic end generated code: output=9f6bbe51a4eb3b21 input=dd89429e6167a00f]*/ { char *name; struct spwd *p; - PyObject *arg, *bytes, *retval = NULL; + PyObject *bytes, *retval = NULL; - if (!PyArg_ParseTuple(args, "U:getspnam", &arg)) - return NULL; if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL) return NULL; if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1) @@ -139,14 +150,17 @@ static PyObject* spwd_getspnam(PyObject *self, PyObject *args) #ifdef HAVE_GETSPENT -PyDoc_STRVAR(spwd_getspall__doc__, -"getspall() -> list_of_entries\n\ -Return a list of all available shadow password database entries, \ -in arbitrary order.\n\ -See spwd.__doc__ for more on shadow password database entries."); +/*[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(PyObject *self, PyObject *args) +spwd_getspall_impl(PyModuleDef *module) +/*[clinic end generated code: output=b12d8ec7bdb29612 input=b2c84b7857d622bd]*/ { PyObject *d; struct spwd *p; @@ -171,10 +185,10 @@ spwd_getspall(PyObject *self, PyObject *args) static PyMethodDef spwd_methods[] = { #ifdef HAVE_GETSPNAM - {"getspnam", spwd_getspnam, METH_VARARGS, spwd_getspnam__doc__}, + SPWD_GETSPNAM_METHODDEF #endif #ifdef HAVE_GETSPENT - {"getspall", spwd_getspall, METH_NOARGS, spwd_getspall__doc__}, + SPWD_GETSPALL_METHODDEF #endif {NULL, NULL} /* sentinel */ }; diff --git a/Modules/sre.h b/Modules/sre.h index 621e2d88d53e..b632165a1f51 100644 --- a/Modules/sre.h +++ b/Modules/sre.h @@ -18,8 +18,10 @@ #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 { @@ -52,9 +54,6 @@ typedef struct { typedef unsigned int (*SRE_TOLOWER_HOOK)(unsigned int ch); -/* FIXME: shouldn't be a constant, really... */ -#define SRE_MARK_SIZE 200 - typedef struct SRE_REPEAT_T { Py_ssize_t count; SRE_CODE* pattern; /* points to REPEAT operator arguments */ @@ -76,7 +75,7 @@ typedef struct { /* registers */ Py_ssize_t lastindex; Py_ssize_t lastmark; - void* mark[SRE_MARK_SIZE]; + void** mark; /* dynamically allocated stuff */ char* data_stack; size_t data_stack_size; @@ -85,8 +84,7 @@ typedef struct { /* current repeat context */ SRE_REPEAT *repeat; /* hooks */ - SRE_TOLOWER_HOOK lower; - int match_all; + SRE_TOLOWER_HOOK lower, upper; } SRE_STATE; typedef struct { diff --git a/Modules/sre_constants.h b/Modules/sre_constants.h index 5940d5a50f70..6632442efe56 100644 --- a/Modules/sre_constants.h +++ b/Modules/sre_constants.h @@ -11,7 +11,7 @@ * See the _sre.c file for information on usage and redistribution. */ -#define SRE_MAGIC 20031017 +#define SRE_MAGIC 20140917 #define SRE_OP_FAILURE 0 #define SRE_OP_SUCCESS 1 #define SRE_OP_ANY 2 @@ -44,6 +44,7 @@ #define SRE_OP_REPEAT_ONE 29 #define SRE_OP_SUBPATTERN 30 #define SRE_OP_MIN_REPEAT_ONE 31 +#define SRE_OP_RANGE_IGNORE 32 #define SRE_AT_BEGINNING 0 #define SRE_AT_BEGINNING_LINE 1 #define SRE_AT_BEGINNING_STRING 2 diff --git a/Modules/sre_lib.h b/Modules/sre_lib.h index df86697690ba..6ad2ab72e391 100644 --- a/Modules/sre_lib.h +++ b/Modules/sre_lib.h @@ -30,7 +30,7 @@ SRE(at)(SRE_STATE* state, SRE_CHAR* ptr, SRE_CODE at) SRE_IS_LINEBREAK((int) ptr[-1])); case SRE_AT_END: - return (((void*) (ptr+1) == state->end && + return (((SRE_CHAR *)state->end - ptr == 1 && SRE_IS_LINEBREAK((int) ptr[0])) || ((void*) ptr == state->end)); @@ -101,7 +101,7 @@ SRE(at)(SRE_STATE* state, SRE_CHAR* ptr, SRE_CODE at) } LOCAL(int) -SRE(charset)(SRE_CODE* set, SRE_CODE ch) +SRE(charset)(SRE_STATE* state, SRE_CODE* set, SRE_CODE ch) { /* check if character is a member of the given set */ @@ -142,6 +142,20 @@ SRE(charset)(SRE_CODE* set, SRE_CODE ch) set += 2; break; + case SRE_OP_RANGE_IGNORE: + /* */ + { + SRE_CODE uch; + /* ch is already lower cased */ + if (set[0] <= ch && ch <= set[1]) + return ok; + uch = state->upper(ch); + if (set[0] <= uch && uch <= set[1]) + return ok; + set += 2; + break; + } + case SRE_OP_NEGATE: ok = !ok; break; @@ -173,7 +187,7 @@ SRE(charset)(SRE_CODE* set, SRE_CODE ch) } } -LOCAL(Py_ssize_t) SRE(match)(SRE_STATE* state, SRE_CODE* pattern); +LOCAL(Py_ssize_t) SRE(match)(SRE_STATE* state, SRE_CODE* pattern, int match_all); LOCAL(Py_ssize_t) SRE(count)(SRE_STATE* state, SRE_CODE* pattern, Py_ssize_t maxcount) @@ -193,7 +207,7 @@ SRE(count)(SRE_STATE* state, SRE_CODE* pattern, Py_ssize_t maxcount) case SRE_OP_IN: /* repeated set */ TRACE(("|%p|%p|COUNT IN\n", pattern, ptr)); - while (ptr < end && SRE(charset)(pattern + 2, *ptr)) + while (ptr < end && SRE(charset)(state, pattern + 2, *ptr)) ptr++; break; @@ -259,7 +273,7 @@ SRE(count)(SRE_STATE* state, SRE_CODE* pattern, Py_ssize_t maxcount) /* repeated single character pattern */ TRACE(("|%p|%p|COUNT SUBPATTERN\n", pattern, ptr)); while ((SRE_CHAR*) state->ptr < end) { - i = SRE(match)(state, pattern); + i = SRE(match)(state, pattern, 0); if (i < 0) return i; if (!i) @@ -490,7 +504,7 @@ typedef struct { /* 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) +SRE(match)(SRE_STATE* state, SRE_CODE* pattern, int match_all) { SRE_CHAR* end = (SRE_CHAR *)state->end; Py_ssize_t alloc_pos, ctx_pos = -1; @@ -507,7 +521,7 @@ SRE(match)(SRE_STATE* state, SRE_CODE* pattern) ctx->last_ctx_pos = -1; ctx->jump = JUMP_NONE; ctx->pattern = pattern; - ctx->match_all = state->match_all; + ctx->match_all = match_all; ctx_pos = alloc_pos; entrance: @@ -628,7 +642,8 @@ SRE(match)(SRE_STATE* state, SRE_CODE* pattern) /* match set member (or non_member) */ /* */ TRACE(("|%p|%p|IN\n", ctx->pattern, ctx->ptr)); - if (ctx->ptr >= end || !SRE(charset)(ctx->pattern + 1, *ctx->ptr)) + if (ctx->ptr >= end || + !SRE(charset)(state, ctx->pattern + 1, *ctx->ptr)) RETURN_FAILURE; ctx->pattern += ctx->pattern[0]; ctx->ptr++; @@ -657,7 +672,7 @@ SRE(match)(SRE_STATE* state, SRE_CODE* pattern) case SRE_OP_IN_IGNORE: TRACE(("|%p|%p|IN_IGNORE\n", ctx->pattern, ctx->ptr)); if (ctx->ptr >= end - || !SRE(charset)(ctx->pattern+1, + || !SRE(charset)(state, ctx->pattern+1, (SRE_CODE)state->lower(*ctx->ptr))) RETURN_FAILURE; ctx->pattern += ctx->pattern[0]; @@ -688,7 +703,8 @@ SRE(match)(SRE_STATE* state, SRE_CODE* pattern) continue; if (ctx->pattern[1] == SRE_OP_IN && (ctx->ptr >= end || - !SRE(charset)(ctx->pattern + 3, (SRE_CODE) *ctx->ptr))) + !SRE(charset)(state, ctx->pattern + 3, + (SRE_CODE) *ctx->ptr))) continue; state->ptr = ctx->ptr; DO_JUMP(JUMP_BRANCH, jump_branch, ctx->pattern+1); @@ -739,7 +755,7 @@ SRE(match)(SRE_STATE* state, SRE_CODE* pattern) RETURN_FAILURE; if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS && - (!ctx->match_all || ctx->ptr == state->end)) { + ctx->ptr == state->end) { /* tail is empty. we're finished */ state->ptr = ctx->ptr; RETURN_SUCCESS; @@ -824,7 +840,7 @@ SRE(match)(SRE_STATE* state, SRE_CODE* pattern) } if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS && - (!ctx->match_all || ctx->ptr == state->end)) { + (!match_all || ctx->ptr == state->end)) { /* tail is empty. we're finished */ state->ptr = ctx->ptr; RETURN_SUCCESS; @@ -1093,9 +1109,9 @@ SRE(match)(SRE_STATE* state, SRE_CODE* pattern) /* */ TRACE(("|%p|%p|ASSERT %d\n", ctx->pattern, ctx->ptr, ctx->pattern[1])); - state->ptr = ctx->ptr - ctx->pattern[1]; - if (state->ptr < state->beginning) + 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]; @@ -1106,8 +1122,8 @@ SRE(match)(SRE_STATE* state, SRE_CODE* pattern) /* */ TRACE(("|%p|%p|ASSERT_NOT %d\n", ctx->pattern, ctx->ptr, ctx->pattern[1])); - state->ptr = ctx->ptr - ctx->pattern[1]; - if (state->ptr >= state->beginning) { + 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); @@ -1199,12 +1215,20 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern) 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) */ @@ -1232,7 +1256,32 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern) prefix, prefix_len, prefix_skip)); TRACE(("charset = %p\n", charset)); -#if defined(USE_FAST_SEARCH) + 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; + 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; + } + 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 */ @@ -1269,7 +1318,7 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern) 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); + status = SRE(match)(state, pattern + 2*prefix_skip, 0); if (status != 0) return status; /* close but no cigar -- try again */ @@ -1281,56 +1330,35 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern) } return 0; } -#endif - if (pattern[0] == SRE_OP_LITERAL) { - /* pattern starts with a literal character. this is used - for short prefixes, and if fast search is disabled */ - SRE_CHAR c = (SRE_CHAR) pattern[1]; -#if SIZEOF_SRE_CHAR < 4 - if ((SRE_CODE) c != pattern[1]) - return 0; /* literal can't match: doesn't fit in char width */ -#endif - end = (SRE_CHAR *)state->end; - 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; - if (flags & SRE_INFO_LITERAL) - return 1; /* we got all of it */ - status = SRE(match)(state, pattern + 2); - if (status != 0) - break; - } - } else if (charset) { + if (charset) { /* pattern starts with a character from a known set */ end = (SRE_CHAR *)state->end; for (;;) { - while (ptr < end && !SRE(charset)(charset, *ptr)) + 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); + status = SRE(match)(state, pattern, 0); if (status != 0) break; ptr++; } - } else + } else { /* general case */ - while (ptr <= end) { + assert(ptr <= end); + while (1) { TRACE(("|%p|%p|SEARCH\n", pattern, ptr)); - state->start = state->ptr = ptr++; - status = SRE(match)(state, pattern); - if (status != 0) + state->start = state->ptr = ptr; + status = SRE(match)(state, pattern, 0); + if (status != 0 || ptr >= end) break; + ptr++; } + } return status; } diff --git a/Modules/symtablemodule.c b/Modules/symtablemodule.c index cdb4ffcbd847..f84cc78b739a 100644 --- a/Modules/symtablemodule.c +++ b/Modules/symtablemodule.c @@ -84,9 +84,6 @@ PyInit__symtable(void) PyModule_AddIntConstant(m, "TYPE_CLASS", ClassBlock); PyModule_AddIntConstant(m, "TYPE_MODULE", ModuleBlock); - PyModule_AddIntMacro(m, OPT_IMPORT_STAR); - PyModule_AddIntMacro(m, OPT_TOPLEVEL); - PyModule_AddIntMacro(m, LOCAL); PyModule_AddIntMacro(m, GLOBAL_EXPLICIT); PyModule_AddIntMacro(m, GLOBAL_IMPLICIT); diff --git a/Modules/syslogmodule.c b/Modules/syslogmodule.c index 9d79eec52a38..f2d44ff5e6b1 100644 --- a/Modules/syslogmodule.c +++ b/Modules/syslogmodule.c @@ -197,8 +197,7 @@ syslog_closelog(PyObject *self, PyObject *unused) { if (S_log_open) { closelog(); - Py_XDECREF(S_ident_o); - S_ident_o = NULL; + Py_CLEAR(S_ident_o); S_log_open = 0; } Py_INCREF(Py_None); diff --git a/Modules/timemodule.c b/Modules/timemodule.c index d3878b95d99f..d2caacdc6dd8 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -27,28 +27,13 @@ #define WIN32_LEAN_AND_MEAN #include #include "pythread.h" - -#if defined(__BORLANDC__) -/* These overrides not needed for Win32 */ -#define timezone _timezone -#define tzname _tzname -#define daylight _daylight -#endif /* __BORLANDC__ */ #endif /* MS_WINDOWS */ #endif /* !__WATCOMC__ || __QNX__ */ -#if defined(__APPLE__) -#include -#endif - /* Forward declarations */ -static int floatsleep(double); +static int pysleep(_PyTime_t); static PyObject* floattime(_Py_clock_info_t *info); -#ifdef MS_WINDOWS -static OSVERSIONINFOEX winver; -#endif - static PyObject * time_time(PyObject *self, PyObject *unused) { @@ -92,12 +77,12 @@ floatclock(_Py_clock_info_t *info) } #endif /* HAVE_CLOCK */ -#if defined(MS_WINDOWS) && !defined(__BORLANDC__) +#ifdef MS_WINDOWS #define WIN32_PERF_COUNTER /* Win32 has better clock replacement; we have our own version, due to Mark Hammond and Tim Peters */ -static int -win_perf_counter(_Py_clock_info_t *info, PyObject **result) +static PyObject* +win_perf_counter(_Py_clock_info_t *info) { static LONGLONG cpu_frequency = 0; static LONGLONG ctrStart; @@ -109,10 +94,8 @@ win_perf_counter(_Py_clock_info_t *info, PyObject **result) QueryPerformanceCounter(&now); ctrStart = now.QuadPart; if (!QueryPerformanceFrequency(&freq) || freq.QuadPart == 0) { - /* Unlikely to happen - this works on all intel - machines at least! Revert to clock() */ - *result = NULL; - return -1; + PyErr_SetFromWindowsErr(0); + return NULL; } cpu_frequency = freq.QuadPart; } @@ -124,10 +107,9 @@ win_perf_counter(_Py_clock_info_t *info, PyObject **result) info->monotonic = 1; info->adjustable = 0; } - *result = PyFloat_FromDouble(diff / (double)cpu_frequency); - return 0; + return PyFloat_FromDouble(diff / (double)cpu_frequency); } -#endif +#endif /* MS_WINDOWS */ #if defined(WIN32_PERF_COUNTER) || defined(HAVE_CLOCK) #define PYCLOCK @@ -135,11 +117,10 @@ static PyObject* pyclock(_Py_clock_info_t *info) { #ifdef WIN32_PERF_COUNTER - PyObject *res; - if (win_perf_counter(info, &res) == 0) - return res; -#endif + return win_perf_counter(info); +#else return floatclock(info); +#endif } static PyObject * @@ -169,7 +150,7 @@ time_clock_gettime(PyObject *self, PyObject *args) ret = clock_gettime((clockid_t)clk_id, &tp); if (ret != 0) { - PyErr_SetFromErrno(PyExc_IOError); + PyErr_SetFromErrno(PyExc_OSError); return NULL; } return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); @@ -185,22 +166,22 @@ time_clock_settime(PyObject *self, PyObject *args) { int clk_id; PyObject *obj; - time_t tv_sec; - long tv_nsec; + _PyTime_t t; struct timespec tp; int ret; if (!PyArg_ParseTuple(args, "iO:clock_settime", &clk_id, &obj)) return NULL; - if (_PyTime_ObjectToTimespec(obj, &tv_sec, &tv_nsec) == -1) + if (_PyTime_FromSecondsObject(&t, obj, _PyTime_ROUND_FLOOR) < 0) + return NULL; + + if (_PyTime_AsTimespec(t, &tp) == -1) return NULL; - tp.tv_sec = tv_sec; - tp.tv_nsec = tv_nsec; ret = clock_settime((clockid_t)clk_id, &tp); if (ret != 0) { - PyErr_SetFromErrno(PyExc_IOError); + PyErr_SetFromErrno(PyExc_OSError); return NULL; } Py_RETURN_NONE; @@ -223,7 +204,7 @@ time_clock_getres(PyObject *self, PyObject *args) ret = clock_getres((clockid_t)clk_id, &tp); if (ret != 0) { - PyErr_SetFromErrno(PyExc_IOError); + PyErr_SetFromErrno(PyExc_OSError); return NULL; } @@ -237,17 +218,17 @@ Return the resolution (precision) of the specified clock clk_id."); #endif /* HAVE_CLOCK_GETTIME */ static PyObject * -time_sleep(PyObject *self, PyObject *args) +time_sleep(PyObject *self, PyObject *obj) { - double secs; - if (!PyArg_ParseTuple(args, "d:sleep", &secs)) + _PyTime_t secs; + if (_PyTime_FromSecondsObject(&secs, obj, _PyTime_ROUND_CEILING)) return NULL; if (secs < 0) { PyErr_SetString(PyExc_ValueError, "sleep length must be non-negative"); return NULL; } - if (floatsleep(secs) != 0) + if (pysleep(secs) != 0) return NULL; Py_INCREF(Py_None); return Py_None; @@ -341,7 +322,7 @@ parse_time_t_args(PyObject *args, char *format, time_t *pwhen) whent = time(NULL); } else { - if (_PyTime_ObjectToTime_t(ot, &whent) == -1) + if (_PyTime_ObjectToTime_t(ot, &whent, _PyTime_ROUND_FLOOR) == -1) return 0; } *pwhen = whent; @@ -629,21 +610,15 @@ time_strftime(PyObject *self, PyObject *args) #if defined(MS_WINDOWS) && !defined(HAVE_WCSFTIME) /* check that the format string contains only valid directives */ - for(outbuf = strchr(fmt, '%'); + for (outbuf = strchr(fmt, '%'); outbuf != NULL; outbuf = strchr(outbuf+2, '%')) { - if (outbuf[1]=='#') + if (outbuf[1] == '#') ++outbuf; /* not documented by python, */ - if (outbuf[1]=='\0' || - !strchr("aAbBcdHIjmMpSUwWxXyYzZ%", outbuf[1])) - { - PyErr_SetString(PyExc_ValueError, "Invalid format string"); - Py_DECREF(format); - return NULL; - } - if ((outbuf[1] == 'y') && buf.tm_year < 0) - { + 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); @@ -651,10 +626,12 @@ time_strftime(PyObject *self, PyObject *args) } } #elif (defined(_AIX) || defined(sun)) && defined(HAVE_WCSFTIME) - for(outbuf = wcschr(fmt, '%'); + 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) { @@ -671,17 +648,24 @@ time_strftime(PyObject *self, PyObject *args) * will be ahead of time... */ for (i = 1024; ; i += i) { -#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) - int err; -#endif 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__) - err = errno; + /* 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, @@ -699,13 +683,6 @@ time_strftime(PyObject *self, PyObject *args) break; } PyMem_Free(outbuf); -#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) - /* VisualStudio .NET 2005 does this properly */ - if (buflen == 0 && err == EINVAL) { - PyErr_SetString(PyExc_ValueError, "Invalid format string"); - break; - } -#endif } #ifdef HAVE_WCSFTIME PyMem_Free(format); @@ -823,7 +800,18 @@ time_mktime(PyObject *self, PyObject *tup) time_t tt; if (!gettmarg(tup, &buf)) return NULL; +#ifdef _AIX + /* year < 1902 or year > 2037 */ + if (buf.tm_year < 2 || buf.tm_year > 137) { + /* Issue #19748: On AIX, mktime() doesn't report overflow error for + * timestamp < -2^31 or timestamp > 2**31-1. */ + PyErr_SetString(PyExc_OverflowError, + "mktime argument out of range"); + return NULL; + } +#else buf.tm_wday = -1; /* sentinel; original value ignored */ +#endif tt = mktime(&buf); /* Return value of -1 does not necessarily mean an error, but tm_wday * cannot remain set to -1 if mktime succeeded. */ @@ -892,122 +880,17 @@ the local timezone used by methods such as localtime, but this behaviour\n\ should not be relied on."); #endif /* HAVE_WORKING_TZSET */ -#if defined(MS_WINDOWS) || defined(__APPLE__) \ - || (defined(HAVE_CLOCK_GETTIME) \ - && (defined(CLOCK_HIGHRES) || defined(CLOCK_MONOTONIC))) -#define PYMONOTONIC -#endif - -#ifdef PYMONOTONIC -static PyObject* +static PyObject * pymonotonic(_Py_clock_info_t *info) { -#if defined(MS_WINDOWS) - static ULONGLONG (*GetTickCount64) (void) = NULL; - static ULONGLONG (CALLBACK *Py_GetTickCount64)(void); - static int has_getickcount64 = -1; - double result; - - if (has_getickcount64 == -1) { - /* GetTickCount64() was added to Windows Vista */ - if (winver.dwMajorVersion >= 6) { - HINSTANCE hKernel32; - hKernel32 = GetModuleHandleW(L"KERNEL32"); - *(FARPROC*)&Py_GetTickCount64 = GetProcAddress(hKernel32, - "GetTickCount64"); - has_getickcount64 = (Py_GetTickCount64 != NULL); - } - else - has_getickcount64 = 0; - } - - if (has_getickcount64) { - ULONGLONG ticks; - ticks = Py_GetTickCount64(); - result = (double)ticks * 1e-3; - } - else { - static DWORD last_ticks = 0; - static DWORD n_overflow = 0; - DWORD ticks; - - ticks = GetTickCount(); - if (ticks < last_ticks) - n_overflow++; - last_ticks = ticks; - - result = ldexp(n_overflow, 32); - result += ticks; - result *= 1e-3; - } - - if (info) { - DWORD timeAdjustment, timeIncrement; - BOOL isTimeAdjustmentDisabled, ok; - if (has_getickcount64) - info->implementation = "GetTickCount64()"; - else - info->implementation = "GetTickCount()"; - info->monotonic = 1; - ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement, - &isTimeAdjustmentDisabled); - if (!ok) { - PyErr_SetFromWindowsErr(0); - return NULL; - } - info->resolution = timeIncrement * 1e-7; - info->adjustable = 0; - } - return PyFloat_FromDouble(result); - -#elif defined(__APPLE__) - static mach_timebase_info_data_t timebase; - uint64_t time; - double secs; - - 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); - } - - time = mach_absolute_time(); - secs = (double)time * timebase.numer / timebase.denom * 1e-9; - if (info) { - info->implementation = "mach_absolute_time()"; - info->resolution = (double)timebase.numer / timebase.denom * 1e-9; - info->monotonic = 1; - info->adjustable = 0; - } - return PyFloat_FromDouble(secs); - -#elif defined(HAVE_CLOCK_GETTIME) && (defined(CLOCK_HIGHRES) || defined(CLOCK_MONOTONIC)) - struct timespec tp; -#ifdef CLOCK_HIGHRES - const clockid_t clk_id = CLOCK_HIGHRES; - const char *function = "clock_gettime(CLOCK_HIGHRES)"; -#else - const clockid_t clk_id = CLOCK_MONOTONIC; - const char *function = "clock_gettime(CLOCK_MONOTONIC)"; -#endif - - if (clock_gettime(clk_id, &tp) != 0) { - PyErr_SetFromErrno(PyExc_OSError); + _PyTime_t t; + double d; + if (_PyTime_GetMonotonicClockWithInfo(&t, info) < 0) { + assert(info != NULL); return NULL; } - - if (info) { - struct timespec res; - info->monotonic = 1; - info->implementation = function; - info->adjustable = 0; - if (clock_getres(clk_id, &res) == 0) - info->resolution = res.tv_sec + res.tv_nsec * 1e-9; - else - info->resolution = 1e-9; - } - return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); -#endif + d = _PyTime_AsSecondsDouble(t); + return PyFloat_FromDouble(d); } static PyObject * @@ -1020,40 +903,15 @@ PyDoc_STRVAR(monotonic_doc, "monotonic() -> float\n\ \n\ Monotonic clock, cannot go backward."); -#endif /* PYMONOTONIC */ static PyObject* perf_counter(_Py_clock_info_t *info) { -#if defined(WIN32_PERF_COUNTER) || defined(PYMONOTONIC) - PyObject *res; -#endif -#if defined(WIN32_PERF_COUNTER) - static int use_perf_counter = 1; -#endif -#ifdef PYMONOTONIC - static int use_monotonic = 1; -#endif - #ifdef WIN32_PERF_COUNTER - if (use_perf_counter) { - if (win_perf_counter(info, &res) == 0) - return res; - use_perf_counter = 0; - } -#endif - -#ifdef PYMONOTONIC - if (use_monotonic) { - res = pymonotonic(info); - if (res != NULL) - return res; - use_monotonic = 0; - PyErr_Clear(); - } + return win_perf_counter(info); +#else + return pymonotonic(info); #endif - - return floattime(info); } static PyObject * @@ -1220,10 +1078,8 @@ time_get_clock_info(PyObject *self, PyObject *args) else if (strcmp(name, "clock") == 0) obj = pyclock(&info); #endif -#ifdef PYMONOTONIC else if (strcmp(name, "monotonic") == 0) obj = pymonotonic(&info); -#endif else if (strcmp(name, "perf_counter") == 0) obj = perf_counter(&info); else if (strcmp(name, "process_time") == 0) @@ -1400,7 +1256,7 @@ static PyMethodDef time_methods[] = { {"clock_settime", time_clock_settime, METH_VARARGS, clock_settime_doc}, {"clock_getres", time_clock_getres, METH_VARARGS, clock_getres_doc}, #endif - {"sleep", time_sleep, METH_VARARGS, sleep_doc}, + {"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}, @@ -1415,9 +1271,7 @@ static PyMethodDef time_methods[] = { #ifdef HAVE_WORKING_TZSET {"tzset", time_tzset, METH_NOARGS, tzset_doc}, #endif -#ifdef PYMONOTONIC {"monotonic", time_monotonic, METH_NOARGS, monotonic_doc}, -#endif {"process_time", time_process_time, METH_NOARGS, process_time_doc}, {"perf_counter", time_perf_counter, METH_NOARGS, perf_counter_doc}, {"get_clock_info", time_get_clock_info, METH_VARARGS, get_clock_info_doc}, @@ -1499,15 +1353,6 @@ PyInit_time(void) if (PyStructSequence_InitType2(&StructTimeType, &struct_time_type_desc) < 0) return NULL; - -#ifdef MS_WINDOWS - winver.dwOSVersionInfoSize = sizeof(winver); - if (!GetVersionEx((OSVERSIONINFO*)&winver)) { - Py_DECREF(m); - PyErr_SetFromWindowsErr(0); - return NULL; - } -#endif } Py_INCREF(&StructTimeType); #ifdef HAVE_STRUCT_TM_TM_ZONE @@ -1523,109 +1368,93 @@ PyInit_time(void) static PyObject* floattime(_Py_clock_info_t *info) { - _PyTime_timeval t; -#ifdef HAVE_CLOCK_GETTIME - struct timespec tp; - int ret; - - /* _PyTime_gettimeofday() does not use clock_gettime() - because it would require to link Python to the rt (real-time) - library, at least on Linux */ - ret = clock_gettime(CLOCK_REALTIME, &tp); - if (ret == 0) { - 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; - } - return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9); + _PyTime_t t; + double d; + if (_PyTime_GetSystemClockWithInfo(&t, info) < 0) { + assert(info != NULL); + return NULL; } -#endif - _PyTime_gettimeofday_info(&t, info); - return PyFloat_FromDouble((double)t.tv_sec + t.tv_usec * 1e-6); + d = _PyTime_AsSecondsDouble(t); + return PyFloat_FromDouble(d); } -/* Implement floatsleep() for various platforms. +/* Implement pysleep() for various platforms. When interrupted (or when another error occurs), return -1 and set an exception; else return 0. */ static int -floatsleep(double secs) +pysleep(_PyTime_t secs) { -/* XXX Should test for MS_WINDOWS first! */ -#if defined(HAVE_SELECT) && !defined(__EMX__) - struct timeval t; - double frac; - int err; - - frac = fmod(secs, 1.0); - secs = floor(secs); - t.tv_sec = (long)secs; - t.tv_usec = (long)(frac*1000000.0); - Py_BEGIN_ALLOW_THREADS - err = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t); - Py_END_ALLOW_THREADS - if (err != 0) { -#ifdef EINTR - if (errno == EINTR) { - if (PyErr_CheckSignals()) - return -1; - } - else + _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 - { - PyErr_SetFromErrno(PyExc_IOError); + + deadline = _PyTime_GetMonotonicClock() + secs; + + do { +#ifndef MS_WINDOWS + if (_PyTime_AsTimeval(secs, &timeout, _PyTime_ROUND_CEILING) < 0) return -1; - } - } -#elif defined(__WATCOMC__) && !defined(__QNX__) - /* XXX Can't interrupt this sleep */ - Py_BEGIN_ALLOW_THREADS - delay((int)(secs * 1000 + 0.5)); /* delay() uses milliseconds */ - Py_END_ALLOW_THREADS -#elif defined(MS_WINDOWS) - { - double millisecs = secs * 1000.0; - unsigned long ul_millis; + 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; } - Py_BEGIN_ALLOW_THREADS + /* 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()) + if (ul_millis == 0 || !_PyOS_IsMainThread()) { + Py_BEGIN_ALLOW_THREADS Sleep(ul_millis); - else { - DWORD rc; - HANDLE hInterruptEvent = _PyOS_SigintEvent(); - ResetEvent(hInterruptEvent); - rc = WaitForSingleObjectEx(hInterruptEvent, ul_millis, FALSE); - if (rc == WAIT_OBJECT_0) { - Py_BLOCK_THREADS - errno = EINTR; - PyErr_SetFromErrno(PyExc_IOError); - return -1; - } + Py_END_ALLOW_THREADS + break; } + + hInterruptEvent = _PyOS_SigintEvent(); + ResetEvent(hInterruptEvent); + + Py_BEGIN_ALLOW_THREADS + rc = WaitForSingleObjectEx(hInterruptEvent, ul_millis, FALSE); Py_END_ALLOW_THREADS - } -#else - /* XXX Can't interrupt this sleep */ - Py_BEGIN_ALLOW_THREADS - sleep((int)secs); - 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/Modules/tkappinit.c b/Modules/tkappinit.c index 2ed85949cba0..7616d9d319d2 100644 --- a/Modules/tkappinit.c +++ b/Modules/tkappinit.c @@ -26,9 +26,6 @@ static int tk_load_failed; int Tcl_AppInit(Tcl_Interp *interp) { -#ifdef WITH_MOREBUTTONS - Tk_Window main_window; -#endif const char *_tkinter_skip_tk_init; #ifdef TKINTER_PROTECT_LOADTK const char *_tkinter_tk_failed; @@ -113,29 +110,13 @@ Tcl_AppInit(Tcl_Interp *interp) return TCL_ERROR; } -#ifdef WITH_MOREBUTTONS - main_window = Tk_MainWindow(interp); -#else Tk_MainWindow(interp); -#endif #ifdef TK_AQUA TkMacOSXInitAppleEvents(interp); TkMacOSXInitMenus(interp); #endif -#ifdef WITH_MOREBUTTONS - { - extern Tcl_CmdProc studButtonCmd; - extern Tcl_CmdProc triButtonCmd; - - Tcl_CreateCommand(interp, "studbutton", studButtonCmd, - (ClientData) main_window, NULL); - Tcl_CreateCommand(interp, "tributton", triButtonCmd, - (ClientData) main_window, NULL); - } -#endif - #ifdef WITH_PIL /* 0.2b5 and later -- not yet released as of May 14 */ { extern void TkImaging_Init(Tcl_Interp *); diff --git a/Modules/tkinter.h b/Modules/tkinter.h index f7e50cde0c7e..cb5a806b0c43 100644 --- a/Modules/tkinter.h +++ b/Modules/tkinter.h @@ -4,24 +4,24 @@ /* 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_VERSION_HEX is properly defined. */ + * TK_HEX_VERSION is properly defined. */ /* TK_RELEASE_LEVEL is always one of the following: - * TCL_ALPHA_RELEASE 0 + * TCL_ALPHA_RELEASE 0 * TCL_BETA_RELEASE 1 * TCL_FINAL_RELEASE 2 */ -#define TK_VERSION_HEX ((TK_MAJOR_VERSION << 24) | \ - (TK_MINOR_VERSION << 16) | \ - (TK_RELEASE_SERIAL << 8) | \ - (TK_RELEASE_LEVEL << 0)) +#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_VERSION_HEX < 0x08040e02 +#if TK_HEX_VERSION < 0x0804020e #define TKINTER_PROTECT_LOADTK #define TKINTER_LOADTK_ERRMSG \ - "Calling Tk_Init again after a previous call failed might deadlock" + "Calling Tk_Init again after a previous call failed might deadlock" #endif #endif /* !TKINTER_H */ diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index eca0054b45ae..fe4e90822a30 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -13,15 +13,17 @@ ------------------------------------------------------------------------ */ +#define PY_SSIZE_T_CLEAN + #include "Python.h" #include "ucnhash.h" #include "structmember.h" -/*[clinic] +/*[clinic input] module unicodedata -class unicodedata.UCD -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +class unicodedata.UCD 'PreviousDBVersion *' '&UCD_Type' +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6dac153082d150bc]*/ /* character properties */ @@ -71,6 +73,8 @@ typedef struct previous_version { Py_UCS4 (*normalization)(Py_UCS4); } PreviousDBVersion; +#include "clinic/unicodedata.c.h" + #define get_old_record(self, v) ((((PreviousDBVersion*)self)->getrecord)(v)) static PyMemberDef DB_members[] = { @@ -97,80 +101,31 @@ new_previous_version(const char*name, const change_record* (*getrecord)(Py_UCS4) } -static Py_UCS4 getuchar(PyUnicodeObject *obj) -{ - if (PyUnicode_READY(obj)) - return (Py_UCS4)-1; - if (PyUnicode_GET_LENGTH(obj) == 1) { - if (PyUnicode_READY(obj)) - return (Py_UCS4)-1; - return PyUnicode_READ_CHAR(obj, 0); - } - PyErr_SetString(PyExc_TypeError, - "need a single Unicode character as parameter"); - return (Py_UCS4)-1; -} - /* --- Module API --------------------------------------------------------- */ -/*[clinic] - +/*[clinic input] unicodedata.UCD.decimal - unichr: object(type='str') + 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 Unicode character unichr -as integer. If no such value is defined, default is returned, or, if -not given, ValueError is raised. -[clinic]*/ - -PyDoc_STRVAR(unicodedata_UCD_decimal__doc__, -"decimal(unichr, default=None)\n" -"Converts a Unicode character into its equivalent decimal value.\n" -"\n" -"Returns the decimal value assigned to the Unicode character unichr\n" -"as integer. If no such value is defined, default is returned, or, if\n" -"not given, ValueError is raised."); - -#define UNICODEDATA_UCD_DECIMAL_METHODDEF \ - {"decimal", (PyCFunction)unicodedata_UCD_decimal, METH_VARARGS, unicodedata_UCD_decimal__doc__}, - -static PyObject * -unicodedata_UCD_decimal_impl(PyObject *self, PyObject *unichr, PyObject *default_value); - -static PyObject * -unicodedata_UCD_decimal(PyObject *self, PyObject *args) -{ - PyObject *return_value = NULL; - PyObject *unichr; - PyObject *default_value = NULL; - - if (!PyArg_ParseTuple(args, - "O!|O:decimal", - &PyUnicode_Type, &unichr, &default_value)) - goto exit; - return_value = unicodedata_UCD_decimal_impl(self, unichr, default_value); - -exit: - return return_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, PyObject *unichr, PyObject *default_value) -/*[clinic checksum: 9576fa55f4ea0be82968af39dc9d0283e634beeb]*/ +unicodedata_UCD_decimal_impl(PyObject *self, int chr, + PyObject *default_value) +/*[clinic end generated code: output=be23376e1a185231 input=933f8107993f23d0]*/ { - PyUnicodeObject *v = (PyUnicodeObject *)unichr; int have_old = 0; long rc; - Py_UCS4 c; - - c = getuchar(v); - if (c == (Py_UCS4)-1) - return NULL; + Py_UCS4 c = (Py_UCS4)chr; if (self && UCD_Check(self)) { const change_record *old = get_old_record(self, c); @@ -201,61 +156,64 @@ unicodedata_UCD_decimal_impl(PyObject *self, PyObject *unichr, PyObject *default return PyLong_FromLong(rc); } -PyDoc_STRVAR(unicodedata_digit__doc__, -"digit(unichr[, default])\n\ -\n\ -Returns the digit value assigned to the Unicode character unichr as\n\ -integer. If no such value is defined, default is returned, or, if\n\ -not given, ValueError is raised."); +/*[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_digit(PyObject *self, PyObject *args) +unicodedata_UCD_digit_impl(PyObject *self, int chr, PyObject *default_value) +/*[clinic end generated code: output=96e18c950171fd2f input=e27d6e4565cd29f2]*/ { - PyUnicodeObject *v; - PyObject *defobj = NULL; long rc; - Py_UCS4 c; - - if (!PyArg_ParseTuple(args, "O!|O:digit", &PyUnicode_Type, &v, &defobj)) - return NULL; - c = getuchar(v); - if (c == (Py_UCS4)-1) - return NULL; + Py_UCS4 c = (Py_UCS4)chr; rc = Py_UNICODE_TODIGIT(c); if (rc < 0) { - if (defobj == NULL) { + if (default_value == NULL) { PyErr_SetString(PyExc_ValueError, "not a digit"); return NULL; } else { - Py_INCREF(defobj); - return defobj; + Py_INCREF(default_value); + return default_value; } } return PyLong_FromLong(rc); } -PyDoc_STRVAR(unicodedata_numeric__doc__, -"numeric(unichr[, default])\n\ -\n\ -Returns the numeric value assigned to the Unicode character unichr\n\ -as float. If no such value is defined, default is returned, or, if\n\ -not given, ValueError is raised."); +/*[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_numeric(PyObject *self, PyObject *args) +unicodedata_UCD_numeric_impl(PyObject *self, int chr, + PyObject *default_value) +/*[clinic end generated code: output=53ce281fe85b10c4 input=fdf5871a5542893c]*/ { - PyUnicodeObject *v; - PyObject *defobj = NULL; int have_old = 0; double rc; - Py_UCS4 c; - - if (!PyArg_ParseTuple(args, "O!|O:numeric", &PyUnicode_Type, &v, &defobj)) - return NULL; - c = getuchar(v); - if (c == (Py_UCS4)-1) - return NULL; + Py_UCS4 c = (Py_UCS4)chr; if (self && UCD_Check(self)) { const change_record *old = get_old_record(self, c); @@ -273,37 +231,34 @@ unicodedata_numeric(PyObject *self, PyObject *args) if (!have_old) rc = Py_UNICODE_TONUMERIC(c); if (rc == -1.0) { - if (defobj == NULL) { + if (default_value == NULL) { PyErr_SetString(PyExc_ValueError, "not a numeric character"); return NULL; } else { - Py_INCREF(defobj); - return defobj; + Py_INCREF(default_value); + return default_value; } } return PyFloat_FromDouble(rc); } -PyDoc_STRVAR(unicodedata_category__doc__, -"category(unichr)\n\ -\n\ -Returns the general category assigned to the Unicode character\n\ -unichr as string."); +/*[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_category(PyObject *self, PyObject *args) +unicodedata_UCD_category_impl(PyObject *self, int chr) +/*[clinic end generated code: output=8571539ee2e6783a input=27d6f3d85050bc06]*/ { - PyUnicodeObject *v; int index; - Py_UCS4 c; - - if (!PyArg_ParseTuple(args, "O!:category", - &PyUnicode_Type, &v)) - return NULL; - c = getuchar(v); - if (c == (Py_UCS4)-1) - return NULL; + 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); @@ -313,26 +268,24 @@ unicodedata_category(PyObject *self, PyObject *args) return PyUnicode_FromString(_PyUnicode_CategoryNames[index]); } -PyDoc_STRVAR(unicodedata_bidirectional__doc__, -"bidirectional(unichr)\n\ -\n\ -Returns the bidirectional class assigned to the Unicode character\n\ -unichr as string. If no such value is defined, an empty string is\n\ -returned."); +/*[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_bidirectional(PyObject *self, PyObject *args) +unicodedata_UCD_bidirectional_impl(PyObject *self, int chr) +/*[clinic end generated code: output=d36310ce2039bb92 input=b3d8f42cebfcf475]*/ { - PyUnicodeObject *v; int index; - Py_UCS4 c; - - if (!PyArg_ParseTuple(args, "O!:bidirectional", - &PyUnicode_Type, &v)) - return NULL; - c = getuchar(v); - if (c == (Py_UCS4)-1) - return NULL; + 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); @@ -344,55 +297,52 @@ unicodedata_bidirectional(PyObject *self, PyObject *args) return PyUnicode_FromString(_PyUnicode_BidirectionalNames[index]); } -PyDoc_STRVAR(unicodedata_combining__doc__, -"combining(unichr)\n\ -\n\ -Returns the canonical combining class assigned to the Unicode\n\ -character unichr as integer. Returns 0 if no combining class is\n\ -defined."); +/*[clinic input] +unicodedata.UCD.combining -> int -static PyObject * -unicodedata_combining(PyObject *self, PyObject *args) + 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]*/ { - PyUnicodeObject *v; int index; - Py_UCS4 c; - - if (!PyArg_ParseTuple(args, "O!:combining", - &PyUnicode_Type, &v)) - return NULL; - c = getuchar(v); - if (c == (Py_UCS4)-1) - return NULL; + 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 PyLong_FromLong(index); + return index; } -PyDoc_STRVAR(unicodedata_mirrored__doc__, -"mirrored(unichr)\n\ -\n\ -Returns the mirrored property assigned to the Unicode character\n\ -unichr as integer. Returns 1 if the character has been identified as\n\ -a \"mirrored\" character in bidirectional text, 0 otherwise."); +/*[clinic input] +unicodedata.UCD.mirrored -> int -static PyObject * -unicodedata_mirrored(PyObject *self, PyObject *args) + 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]*/ { - PyUnicodeObject *v; int index; - Py_UCS4 c; - - if (!PyArg_ParseTuple(args, "O!:mirrored", - &PyUnicode_Type, &v)) - return NULL; - c = getuchar(v); - if (c == (Py_UCS4)-1) - return NULL; + 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); @@ -401,28 +351,25 @@ unicodedata_mirrored(PyObject *self, PyObject *args) else if (old->mirrored_changed != 0xFF) index = old->mirrored_changed; } - return PyLong_FromLong(index); + return index; } -PyDoc_STRVAR(unicodedata_east_asian_width__doc__, -"east_asian_width(unichr)\n\ -\n\ -Returns the east asian width assigned to the Unicode character\n\ -unichr as string."); +/*[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_east_asian_width(PyObject *self, PyObject *args) +unicodedata_UCD_east_asian_width_impl(PyObject *self, int chr) +/*[clinic end generated code: output=484e8537d9ee8197 input=c4854798aab026e0]*/ { - PyUnicodeObject *v; int index; - Py_UCS4 c; - - if (!PyArg_ParseTuple(args, "O!:east_asian_width", - &PyUnicode_Type, &v)) - return NULL; - c = getuchar(v); - if (c == (Py_UCS4)-1) - return NULL; + 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); @@ -432,29 +379,27 @@ unicodedata_east_asian_width(PyObject *self, PyObject *args) return PyUnicode_FromString(_PyUnicode_EastAsianWidthNames[index]); } -PyDoc_STRVAR(unicodedata_decomposition__doc__, -"decomposition(unichr)\n\ -\n\ -Returns the character decomposition mapping assigned to the Unicode\n\ -character unichr as string. An empty string is returned in case no\n\ -such mapping is defined."); +/*[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_decomposition(PyObject *self, PyObject *args) +unicodedata_UCD_decomposition_impl(PyObject *self, int chr) +/*[clinic end generated code: output=7d699f3ec7565d27 input=e4c12459ad68507b]*/ { - PyUnicodeObject *v; char decomp[256]; int code, index, count; size_t i; unsigned int prefix_index; - Py_UCS4 c; - - if (!PyArg_ParseTuple(args, "O!:decomposition", - &PyUnicode_Type, &v)) - return NULL; - c = getuchar(v); - if (c == (Py_UCS4)-1) - return NULL; + Py_UCS4 c = (Py_UCS4)chr; code = (int)c; @@ -550,10 +495,17 @@ nfd_nfkd(PyObject *self, PyObject *input, int k) stackptr = 0; isize = PyUnicode_GET_LENGTH(input); + space = isize; /* Overallocate at most 10 characters. */ - space = (isize > 10 ? 10 : isize) + isize; + if (space > 10) { + if (space <= PY_SSIZE_T_MAX - 10) + space += 10; + } + else { + space *= 2; + } osize = space; - output = PyMem_Malloc(space * sizeof(Py_UCS4)); + output = PyMem_NEW(Py_UCS4, space); if (!output) { PyErr_NoMemory(); return NULL; @@ -700,7 +652,7 @@ nfc_nfkc(PyObject *self, PyObject *input, int k) /* We allocate a buffer for the output. If we find that we made no changes, we still return the NFD result. */ - output = PyMem_Malloc(len * sizeof(Py_UCS4)); + output = PyMem_NEW(Py_UCS4, len); if (!output) { PyErr_NoMemory(); Py_DECREF(result); @@ -848,22 +800,24 @@ is_normalized(PyObject *self, PyObject *input, int nfc, int k) return 1; /* certainly normalized */ } -PyDoc_STRVAR(unicodedata_normalize__doc__, -"normalize(form, unistr)\n\ -\n\ -Return the normal form 'form' for the Unicode string unistr. Valid\n\ -values for form are 'NFC', 'NFKC', 'NFD', and 'NFKD'."); +/*[clinic input] +unicodedata.UCD.normalize -static PyObject* -unicodedata_normalize(PyObject *self, PyObject *args) -{ - char *form; - PyObject *input; + self: self + form: str + unistr as input: object(subclass_of='&PyUnicode_Type') + / - if(!PyArg_ParseTuple(args, "sO!:normalize", - &form, &PyUnicode_Type, &input)) - return NULL; +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, const char *form, + PyObject *input) +/*[clinic end generated code: output=62d1f8870027efdc input=cd092e631cf11883]*/ +{ if (PyUnicode_READY(input) == -1) return NULL; @@ -967,13 +921,14 @@ is_unified_ideograph(Py_UCS4 code) { return (0x3400 <= code && code <= 0x4DB5) || /* CJK Ideograph Extension A */ - (0x4E00 <= code && code <= 0x9FCC) || /* CJK Ideograph */ + (0x4E00 <= code && code <= 0x9FD5) || /* 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 */ + (0x2B740 <= code && code <= 0x2B81D) || /* CJK Ideograph Extension D */ + (0x2B820 <= code && code <= 0x2CEA1); /* CJK Ideograph Extension E */ } -/* macros used to determine if the given codepoint is in the PUA range that +/* 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) && \ @@ -983,7 +938,7 @@ static int _getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen, int with_alias_and_seq) { - /* Find the name associated with the given codepoint. + /* 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; @@ -994,7 +949,7 @@ _getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen, if (code >= 0x110000) return 0; - /* XXX should we just skip all the codepoints in the PUAs here? */ + /* 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; @@ -1122,8 +1077,8 @@ _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 codepoint is in the PUA range that we use for aliases, - * convert it to obtain the right codepoint */ + /* 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 @@ -1135,9 +1090,9 @@ static int _getcode(PyObject* self, const char* name, int namelen, Py_UCS4* code, int with_named_seq) { - /* Return the codepoint associated with the given name. + /* 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 codepoint that we are + * 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; @@ -1222,60 +1177,67 @@ static const _PyUnicode_Name_CAPI hashAPI = /* -------------------------------------------------------------------- */ /* Python bindings */ -PyDoc_STRVAR(unicodedata_name__doc__, -"name(unichr[, default])\n\ -Returns the name assigned to the Unicode character unichr as a\n\ -string. If no name is defined, default is returned, or, if not\n\ -given, ValueError is raised."); +/*[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_name(PyObject* self, PyObject* args) +unicodedata_UCD_name_impl(PyObject *self, int chr, PyObject *default_value) +/*[clinic end generated code: output=6bbb37a326407707 input=3e0367f534de56d9]*/ { char name[NAME_MAXLEN]; - Py_UCS4 c; - - PyUnicodeObject* v; - PyObject* defobj = NULL; - if (!PyArg_ParseTuple(args, "O!|O:name", &PyUnicode_Type, &v, &defobj)) - return NULL; - - c = getuchar(v); - if (c == (Py_UCS4)-1) - return NULL; + Py_UCS4 c = (Py_UCS4)chr; if (!_getucname(self, c, name, sizeof(name), 0)) { - if (defobj == NULL) { + if (default_value == NULL) { PyErr_SetString(PyExc_ValueError, "no such name"); return NULL; } else { - Py_INCREF(defobj); - return defobj; + Py_INCREF(default_value); + return default_value; } } return PyUnicode_FromString(name); } -PyDoc_STRVAR(unicodedata_lookup__doc__, -"lookup(name)\n\ -\n\ -Look up character by name. If a character with the\n\ -given name is found, return the corresponding Unicode\n\ -character. If not found, KeyError is raised."); +/*[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_lookup(PyObject* self, PyObject* args) +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; - - char* name; - int namelen; unsigned int index; - if (!PyArg_ParseTuple(args, "s#:lookup", &name, &namelen)) + if (name_length > INT_MAX) { + PyErr_SetString(PyExc_KeyError, "name too long"); return NULL; + } - if (!_getcode(self, name, namelen, &code, 1)) { + if (!_getcode(self, name, (int)name_length, &code, 1)) { PyErr_Format(PyExc_KeyError, "undefined character name '%s'", name); return NULL; } @@ -1294,24 +1256,17 @@ unicodedata_lookup(PyObject* self, PyObject* args) static PyMethodDef unicodedata_functions[] = { UNICODEDATA_UCD_DECIMAL_METHODDEF - {"digit", unicodedata_digit, METH_VARARGS, unicodedata_digit__doc__}, - {"numeric", unicodedata_numeric, METH_VARARGS, unicodedata_numeric__doc__}, - {"category", unicodedata_category, METH_VARARGS, - unicodedata_category__doc__}, - {"bidirectional", unicodedata_bidirectional, METH_VARARGS, - unicodedata_bidirectional__doc__}, - {"combining", unicodedata_combining, METH_VARARGS, - unicodedata_combining__doc__}, - {"mirrored", unicodedata_mirrored, METH_VARARGS, - unicodedata_mirrored__doc__}, - {"east_asian_width", unicodedata_east_asian_width, METH_VARARGS, - unicodedata_east_asian_width__doc__}, - {"decomposition", unicodedata_decomposition, METH_VARARGS, - unicodedata_decomposition__doc__}, - {"name", unicodedata_name, METH_VARARGS, unicodedata_name__doc__}, - {"lookup", unicodedata_lookup, METH_VARARGS, unicodedata_lookup__doc__}, - {"normalize", unicodedata_normalize, METH_VARARGS, - unicodedata_normalize__doc__}, + 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_NORMALIZE_METHODDEF {NULL, NULL} /* sentinel */ }; diff --git a/Modules/unicodedata_db.h b/Modules/unicodedata_db.h index ec11fa1da497..89d8768dd914 100644 --- a/Modules/unicodedata_db.h +++ b/Modules/unicodedata_db.h @@ -1,6 +1,6 @@ /* this file was generated by Tools/unicode/makeunicodedata.py 3.2 */ -#define UNIDATA_VERSION "6.3.0" +#define UNIDATA_VERSION "8.0.0" /* a list of unique database records */ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {0, 0, 0, 0, 0, 0}, @@ -323,7 +323,11 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {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}, {30, 0, 1, 0, 5, 170}, {5, 216, 1, 0, 5, 0}, @@ -335,8 +339,8 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { }; /* Reindexing of NFC first characters. */ -#define TOTAL_FIRST 372 -#define TOTAL_LAST 56 +#define TOTAL_FIRST 376 +#define TOTAL_LAST 62 struct reindex{int start;short count,index;}; static struct reindex nfc_first[] = { { 60, 2, 0}, @@ -546,6 +550,9 @@ static struct reindex nfc_first[] = { { 69787, 0, 368}, { 69797, 0, 369}, { 69937, 1, 370}, + { 70471, 0, 372}, + { 70841, 0, 373}, + { 71096, 1, 374}, {0,0,0} }; @@ -583,6 +590,12 @@ static struct reindex nfc_last[] = { { 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} }; @@ -714,36 +727,43 @@ static unsigned char index1[] = { 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 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, 84, - 138, 139, 140, 141, 142, 84, 84, 84, 84, 84, 84, 143, 84, 144, 145, 146, - 84, 147, 84, 148, 84, 84, 84, 149, 84, 84, 84, 150, 151, 152, 153, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 154, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 41, 41, 41, 41, 41, 41, 155, 84, 156, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 41, 41, 41, 41, 41, 41, 41, 41, 157, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 41, 41, 41, 41, 158, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 159, 160, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 161, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 78, 162, 163, 164, 165, 84, 166, 84, 167, 168, 169, 170, 171, 172, - 173, 174, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 175, 176, 84, 84, 177, 178, 179, - 180, 181, 84, 182, 183, 184, 185, 186, 187, 188, 189, 190, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 101, 101, 101, + 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, 138, 138, 156, 138, 138, 138, 157, + 158, 159, 160, 161, 162, 163, 138, 138, 164, 138, 165, 166, 167, 168, + 138, 138, 169, 138, 138, 138, 170, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 41, 41, 41, 41, 41, 41, 41, 171, 172, 41, 173, 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, 174, 138, 138, + 138, 138, 138, 138, 138, 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, 175, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 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, 176, 177, 178, 179, 138, 138, 138, 138, 138, + 138, 180, 181, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 182, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 183, 184, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 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, 185, + 186, 187, 188, 138, 189, 138, 190, 191, 192, 193, 194, 195, 196, 197, 78, + 78, 78, 78, 198, 199, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 200, 201, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 202, 203, 138, 138, 204, 205, 206, 207, 208, 138, 209, 210, 209, 209, + 211, 212, 209, 213, 214, 215, 216, 217, 218, 219, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, @@ -767,359 +787,459 @@ static unsigned char index1[] = { 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 191, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 220, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 192, - 101, 193, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 122, 122, 122, 122, 194, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 195, 84, 196, 197, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 84, 121, 121, 121, 121, 121, 121, 121, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 221, 101, 222, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 223, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 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, 224, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 225, 138, 226, 227, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 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, @@ -1155,8 +1275,8 @@ static unsigned char index1[] = { 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 228, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 198, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, @@ -1192,7 +1312,7 @@ static unsigned char index1[] = { 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 198, + 121, 228, }; static unsigned short index2[] = { @@ -1244,7 +1364,7 @@ static unsigned short index2[] = { 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, 0, 0, 0, 0, 0, 58, 76, 38, 75, 38, 38, 38, + 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, @@ -1267,97 +1387,98 @@ static unsigned short index2[] = { 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, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 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, 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, 0, 0, 53, 83, 83, 83, 83, 83, 83, 0, 47, 47, 47, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 53, 83, 83, 83, 83, 83, 83, 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, 35, - 0, 83, 84, 0, 0, 0, 0, 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, - 0, 107, 107, 107, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 108, - 108, 108, 108, 0, 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, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 35, 0, 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, 0, 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, 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, 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, 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, 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, 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, + 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, 81, - 81, 81, 81, 81, 81, 81, 86, 81, 137, 137, 26, 138, 138, 138, 137, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 118, + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 0, 135, 135, 135, 139, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 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, 48, - 48, 48, 48, 48, 48, 48, 140, 48, 48, 140, 48, 48, 48, 48, 48, 135, 139, - 141, 48, 139, 139, 139, 135, 135, 135, 135, 135, 135, 135, 135, 139, 139, - 139, 139, 142, 139, 139, 48, 81, 86, 81, 81, 135, 135, 135, 143, 143, - 143, 143, 143, 143, 143, 143, 48, 48, 135, 135, 83, 83, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 83, 53, 48, 48, 48, 48, 48, 48, 0, 48, - 48, 48, 48, 48, 48, 48, 0, 135, 139, 139, 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, 145, 48, 146, 139, 139, 135, 135, 135, - 135, 0, 0, 139, 139, 0, 0, 147, 147, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, - 146, 0, 0, 0, 0, 143, 143, 0, 143, 48, 48, 135, 135, 0, 0, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 48, 48, 85, 85, 148, 148, 148, 148, - 148, 148, 80, 85, 0, 0, 0, 0, 0, 135, 135, 139, 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, 143, 0, 48, 143, 0, 48, 48, 0, 0, 145, 0, 139, 139, 139, 135, - 135, 0, 0, 0, 0, 135, 135, 0, 0, 135, 135, 142, 0, 0, 0, 135, 0, 0, 0, 0, - 0, 0, 0, 143, 143, 143, 48, 0, 143, 0, 0, 0, 0, 0, 0, 0, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 135, 135, 48, 48, 48, 135, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 135, 135, 139, 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, 145, 48, 139, 139, 139, 135, 135, 135, - 135, 135, 0, 135, 135, 139, 0, 139, 139, 142, 0, 0, 48, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 135, 135, 0, 0, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 83, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 135, 139, 139, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 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, 48, 48, 48, 48, 48, 48, 48, + 140, 48, 48, 140, 48, 48, 48, 48, 48, 135, 139, 141, 48, 139, 139, 139, + 135, 135, 135, 135, 135, 135, 135, 135, 139, 139, 139, 139, 142, 139, + 139, 48, 81, 86, 81, 81, 135, 135, 135, 143, 143, 143, 143, 143, 143, + 143, 143, 48, 48, 135, 135, 83, 83, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 83, 53, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 135, 139, 139, 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, 145, 48, 146, 139, 139, 135, 135, 135, 135, 0, 0, + 139, 139, 0, 0, 147, 147, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, + 0, 143, 143, 0, 143, 48, 48, 135, 135, 0, 0, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 48, 48, 85, 85, 148, 148, 148, 148, 148, 148, + 80, 85, 0, 0, 0, 0, 0, 135, 135, 139, 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, + 143, 0, 48, 143, 0, 48, 48, 0, 0, 145, 0, 139, 139, 139, 135, 135, 0, 0, + 0, 0, 135, 135, 0, 0, 135, 135, 142, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, + 143, 143, 143, 48, 0, 143, 0, 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 135, 135, 48, 48, 48, 135, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 135, 135, 139, 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, 145, 48, 139, 139, 139, 135, 135, 135, 135, + 135, 0, 135, 135, 139, 0, 139, 139, 142, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 135, 135, 0, 0, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 83, 85, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, + 0, 0, 135, 139, 139, 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, 145, 48, 146, 135, 139, 135, 135, 135, 135, 0, 0, 139, 147, 0, 0, 147, 147, 142, 0, 0, 0, 0, 0, 0, 0, 0, 149, 146, 0, 0, 0, 0, @@ -1369,123 +1490,124 @@ static unsigned short index2[] = { 48, 0, 0, 0, 0, 146, 139, 135, 139, 139, 0, 0, 0, 139, 139, 139, 0, 147, 147, 147, 142, 0, 0, 48, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 148, - 148, 148, 26, 26, 26, 26, 26, 26, 85, 26, 0, 0, 0, 0, 0, 0, 139, 139, + 148, 148, 26, 26, 26, 26, 26, 26, 85, 26, 0, 0, 0, 0, 0, 135, 139, 139, 139, 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, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 0, + 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, 139, 139, 139, 139, 0, 135, 135, 150, 0, 135, - 135, 135, 142, 0, 0, 0, 0, 0, 0, 0, 151, 152, 0, 48, 48, 0, 0, 0, 0, 0, + 135, 135, 142, 0, 0, 0, 0, 0, 0, 0, 151, 152, 0, 48, 48, 48, 0, 0, 0, 0, 0, 48, 48, 135, 135, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 0, 0, 0, 0, 0, 0, 0, 0, 153, 153, 153, 153, 153, 153, 153, 80, 0, 0, + 144, 0, 0, 0, 0, 0, 0, 0, 0, 153, 153, 153, 153, 153, 153, 153, 80, 0, + 135, 139, 139, 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, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, + 48, 48, 0, 0, 145, 48, 139, 154, 147, 139, 146, 139, 139, 0, 154, 147, + 147, 0, 147, 147, 135, 142, 0, 0, 0, 0, 0, 0, 0, 146, 146, 0, 0, 0, 0, 0, + 0, 0, 48, 0, 48, 48, 135, 135, 0, 0, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 0, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 139, 139, 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, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, - 48, 0, 0, 145, 48, 139, 154, 147, 139, 146, 139, 139, 0, 154, 147, 147, - 0, 147, 147, 135, 142, 0, 0, 0, 0, 0, 0, 0, 146, 146, 0, 0, 0, 0, 0, 0, - 0, 48, 0, 48, 48, 135, 135, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 0, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, - 139, 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, 0, 0, 48, 146, 139, 139, 135, 135, 135, 135, 0, 139, 139, + 139, 0, 147, 147, 147, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 0, + 0, 0, 0, 48, 48, 48, 135, 135, 0, 0, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 148, 148, 148, 148, 148, 148, 0, 0, 0, 80, 48, 48, 48, 48, + 48, 48, 0, 0, 139, 139, 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, 155, 0, 0, 0, 0, 146, 139, 139, 135, 135, 135, 0, 135, 0, 139, 139, + 147, 139, 147, 147, 147, 146, 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 0, 0, 139, 139, 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, 0, 0, 48, 146, 139, 139, 135, 135, 135, 135, 0, 139, 139, 139, 0, - 147, 147, 147, 142, 48, 0, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, - 0, 48, 48, 135, 135, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 148, 148, 148, 148, 148, 148, 0, 0, 0, 80, 48, 48, 48, 48, 48, 48, - 0, 0, 139, 139, 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, - 155, 0, 0, 0, 0, 146, 139, 139, 135, 135, 135, 0, 135, 0, 139, 139, 147, - 139, 147, 147, 147, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 139, 139, 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, 156, 135, 135, 135, 135, 157, - 157, 142, 0, 0, 0, 0, 85, 48, 48, 48, 48, 48, 48, 53, 135, 158, 158, 158, - 158, 135, 135, 135, 83, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 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, 0, 48, 48, - 0, 48, 0, 0, 48, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, - 48, 48, 0, 48, 48, 48, 0, 48, 0, 48, 0, 0, 48, 48, 0, 48, 48, 48, 48, - 135, 48, 156, 135, 135, 135, 135, 159, 159, 0, 135, 135, 48, 0, 0, 48, - 48, 48, 48, 48, 0, 53, 0, 160, 160, 160, 160, 135, 135, 0, 0, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, 0, 0, 156, 156, 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, 161, 83, - 83, 83, 83, 83, 83, 80, 83, 80, 80, 80, 86, 86, 80, 80, 80, 80, 80, 80, - 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 80, 86, 80, 86, 80, 162, 163, 164, 163, - 164, 139, 139, 48, 48, 48, 143, 48, 48, 48, 48, 0, 48, 48, 48, 48, 143, - 48, 48, 48, 48, 143, 48, 48, 48, 48, 143, 48, 48, 48, 48, 143, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 143, 48, 48, 48, 0, 0, 0, 0, 165, - 166, 167, 168, 167, 167, 169, 167, 169, 166, 166, 166, 166, 135, 139, - 166, 167, 81, 81, 142, 83, 81, 81, 48, 48, 48, 48, 48, 135, 135, 135, - 135, 135, 135, 167, 135, 135, 135, 135, 0, 135, 135, 135, 135, 167, 135, - 135, 135, 135, 167, 135, 135, 135, 135, 167, 135, 135, 135, 135, 167, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 167, 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, 135, 48, 156, + 135, 135, 135, 135, 157, 157, 142, 0, 0, 0, 0, 85, 48, 48, 48, 48, 48, + 48, 53, 135, 158, 158, 158, 158, 135, 135, 135, 83, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 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, 0, 48, 48, 0, 48, 0, 0, 48, 0, 0, 0, 0, 0, 0, 48, + 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 0, 48, 0, 48, + 0, 0, 48, 48, 0, 48, 48, 48, 48, 135, 48, 156, 135, 135, 135, 135, 159, + 159, 0, 135, 135, 48, 0, 0, 48, 48, 48, 48, 48, 0, 53, 0, 160, 160, 160, + 160, 135, 135, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, + 0, 156, 156, 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, 161, 83, 83, 83, 83, 83, 83, 80, 83, 80, 80, 80, 86, + 86, 80, 80, 80, 80, 80, 80, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 80, 86, 80, 86, + 80, 162, 163, 164, 163, 164, 139, 139, 48, 48, 48, 143, 48, 48, 48, 48, + 0, 48, 48, 48, 48, 143, 48, 48, 48, 48, 143, 48, 48, 48, 48, 143, 48, 48, + 48, 48, 143, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 143, 48, 48, + 48, 0, 0, 0, 0, 165, 166, 167, 168, 167, 167, 169, 167, 169, 166, 166, + 166, 166, 135, 139, 166, 167, 81, 81, 142, 83, 81, 81, 48, 48, 48, 48, + 48, 135, 135, 135, 135, 135, 135, 167, 135, 135, 135, 135, 0, 135, 135, + 135, 135, 167, 135, 135, 135, 135, 167, 135, 135, 135, 135, 167, 135, + 135, 135, 135, 167, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 167, 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, 140, 48, 48, 48, 48, 139, 139, 135, 149, 135, - 135, 139, 135, 135, 135, 135, 135, 145, 139, 142, 142, 139, 139, 135, - 135, 48, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 83, 83, 83, - 83, 83, 83, 48, 48, 48, 48, 48, 48, 139, 139, 135, 135, 48, 48, 48, 48, - 135, 135, 135, 48, 139, 139, 139, 48, 48, 139, 139, 139, 139, 139, 139, - 139, 48, 48, 48, 135, 135, 135, 135, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 135, 139, 139, 135, 135, 139, 139, 139, 139, 139, 139, - 86, 48, 139, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 139, 139, - 139, 135, 80, 80, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 48, 48, 48, 48, 139, + 139, 135, 149, 135, 135, 139, 135, 135, 135, 135, 135, 145, 139, 142, + 142, 139, 139, 135, 135, 48, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 83, 83, 83, 83, 83, 83, 48, 48, 48, 48, 48, 48, 139, 139, 135, 135, + 48, 48, 48, 48, 135, 135, 135, 48, 139, 139, 139, 48, 48, 139, 139, 139, + 139, 139, 139, 139, 48, 48, 48, 135, 135, 135, 135, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 135, 139, 139, 135, 135, 139, 139, 139, + 139, 139, 139, 86, 48, 139, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 139, 139, 139, 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, 0, 44, 0, 0, 0, 0, 0, 44, 0, 0, 48, 48, 48, 48, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 44, 0, 0, 0, 0, 0, 44, 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, 83, 51, 48, 48, 48, 170, 170, 170, 170, 170, 170, 170, 170, + 48, 48, 48, 48, 48, 48, 48, 83, 51, 48, 48, 48, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 48, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, - 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 48, 48, 48, 48, + 170, 170, 170, 170, 170, 170, 170, 48, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 171, 171, 171, 171, 171, 171, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 171, 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, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 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, 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, 48, 48, 48, 0, 0, 81, 81, - 81, 83, 83, 83, 83, 83, 83, 83, 83, 83, 148, 148, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 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, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 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, @@ -1505,357 +1627,359 @@ static unsigned short index2[] = { 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 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, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 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, 163, 164, + 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, 83, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 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, 163, 164, 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, 83, 83, 83, 173, 173, 173, 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, 142, 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, 142, 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, 83, 83, 83, 173, 173, 173, 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, 0, 48, - 48, 48, 48, 135, 135, 142, 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, - 142, 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, + 139, 135, 135, 135, 135, 135, 135, 135, 139, 139, 139, 139, 139, 139, + 139, 139, 135, 139, 139, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 142, 135, 83, 83, 83, 53, 83, 83, 83, 85, 48, 81, 0, 0, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 0, 0, 0, 0, 0, 0, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 0, 0, 0, 0, 0, 0, 138, 138, 138, 138, 138, + 138, 84, 138, 138, 138, 138, 135, 135, 135, 174, 0, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 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, 135, 135, 139, 135, 135, - 135, 135, 135, 135, 135, 139, 139, 139, 139, 139, 139, 139, 139, 135, - 139, 139, 135, 135, 135, 135, 135, 135, 135, 135, 135, 142, 135, 83, 83, - 83, 53, 83, 83, 83, 85, 48, 81, 0, 0, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 0, 0, 0, 0, 0, 0, 153, 153, 153, 153, 153, 153, 153, 153, - 153, 153, 0, 0, 0, 0, 0, 0, 138, 138, 138, 138, 138, 138, 84, 138, 138, - 138, 138, 135, 135, 135, 174, 0, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 135, 135, 135, 139, 139, 139, 139, + 135, 135, 139, 139, 139, 0, 0, 0, 0, 139, 139, 135, 139, 139, 139, 139, + 139, 139, 87, 81, 86, 0, 0, 0, 0, 26, 0, 0, 0, 138, 138, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 48, 48, 48, 48, 48, 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, 135, 135, 135, 139, 139, 139, 139, 135, 135, 139, 139, - 139, 0, 0, 0, 0, 139, 139, 135, 139, 139, 139, 139, 139, 139, 87, 81, 86, - 0, 0, 0, 0, 26, 0, 0, 0, 138, 138, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 48, 48, 48, 48, 48, 48, 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, 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, 0, 0, 0, 0, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 48, 48, 48, 48, 48, 48, 48, 139, 139, - 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 148, - 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 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, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 148, 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, 139, 139, 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, 81, 86, 139, 139, 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, 139, 135, 139, + 135, 135, 135, 135, 135, 135, 135, 0, 142, 139, 135, 139, 139, 135, 135, + 135, 135, 135, 135, 135, 135, 139, 139, 139, 139, 139, 139, 135, 135, 81, + 81, 81, 81, 81, 81, 81, 81, 0, 0, 86, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 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, + 139, 48, 140, 48, 140, 48, 140, 48, 140, 48, 140, 48, 48, 48, 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, 139, 135, 139, 135, - 135, 135, 135, 135, 135, 135, 0, 142, 139, 135, 139, 139, 135, 135, 135, - 135, 135, 135, 135, 135, 139, 139, 139, 139, 139, 139, 135, 135, 81, 81, - 81, 81, 81, 81, 81, 81, 0, 0, 86, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 0, 0, 0, 0, 0, 0, 83, 83, 83, 83, 83, 83, 83, 53, 83, 83, 83, 83, - 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 139, 48, 140, 48, - 140, 48, 140, 48, 140, 48, 140, 48, 48, 48, 140, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 145, 146, 135, + 135, 135, 135, 135, 147, 135, 147, 139, 139, 147, 147, 135, 147, 175, 48, + 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 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, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 145, 146, 135, 135, 135, 135, 135, - 147, 135, 147, 139, 139, 147, 147, 135, 147, 175, 48, 48, 48, 48, 48, 48, - 48, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 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, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 139, 135, 135, - 135, 135, 139, 139, 135, 135, 175, 142, 139, 139, 48, 48, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 139, 135, 135, 135, 135, 139, 139, 135, 135, 175, 142, 135, + 135, 48, 48, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 145, - 139, 135, 135, 139, 139, 139, 135, 139, 135, 135, 135, 175, 175, 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, 139, 139, 139, 139, 139, 139, 139, 139, - 135, 135, 135, 135, 135, 135, 135, 135, 139, 139, 135, 145, 0, 0, 0, 83, - 83, 83, 83, 83, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, 0, - 0, 48, 48, 48, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 48, 48, + 48, 48, 48, 48, 48, 48, 145, 139, 135, 135, 139, 139, 139, 135, 139, 135, + 135, 135, 175, 175, 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, 139, 139, + 139, 139, 139, 139, 139, 139, 135, 135, 135, 135, 135, 135, 135, 135, + 139, 139, 135, 145, 0, 0, 0, 83, 83, 83, 83, 83, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 0, 0, 0, 48, 48, 48, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 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, + 53, 53, 53, 53, 53, 53, 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, 83, 83, 83, 83, 83, 83, - 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 81, 81, 81, 83, 176, 86, 86, 86, 86, 86, - 81, 81, 86, 86, 86, 86, 81, 139, 176, 176, 176, 176, 176, 176, 176, 48, - 48, 48, 48, 86, 48, 48, 48, 48, 139, 139, 81, 48, 48, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 0, 0, 83, 83, 83, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 81, 81, 81, + 83, 176, 86, 86, 86, 86, 86, 81, 81, 86, 86, 86, 86, 81, 139, 176, 176, + 176, 176, 176, 176, 176, 48, 48, 48, 48, 86, 48, 48, 48, 48, 139, 139, + 81, 48, 48, 0, 81, 81, 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, 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, + 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, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 51, 47, 47, 47, + 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, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 51, 51, 51, 51, 51, + 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, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 81, 81, 86, 81, - 81, 81, 81, 81, 81, 81, 86, 81, 81, 177, 178, 86, 179, 81, 81, 81, 81, + 51, 51, 51, 51, 81, 81, 86, 81, 81, 81, 81, 81, 81, 81, 86, 81, 81, 177, + 178, 86, 179, 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, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 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, 181, 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, + 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 180, 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, 181, 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, 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, 182, 43, 182, 43, 182, 43, 182, 43, 182, - 43, 182, 43, 182, 0, 0, 43, 43, 43, 43, 43, 43, 43, 43, 183, 183, 183, - 183, 183, 183, 183, 183, 43, 43, 43, 43, 43, 43, 43, 43, 183, 183, 183, - 183, 183, 183, 183, 183, 43, 43, 43, 43, 43, 43, 43, 43, 183, 183, 183, - 183, 183, 183, 183, 183, 43, 43, 43, 43, 43, 0, 43, 43, 38, 38, 38, 184, - 183, 58, 182, 58, 58, 76, 43, 43, 43, 0, 43, 43, 38, 184, 38, 184, 183, - 76, 76, 76, 43, 43, 43, 182, 0, 0, 43, 43, 38, 38, 38, 184, 0, 76, 76, - 76, 43, 43, 43, 182, 43, 43, 43, 43, 38, 38, 38, 184, 38, 76, 185, 185, - 0, 0, 43, 43, 43, 0, 43, 43, 38, 184, 38, 184, 183, 185, 58, 0, 186, 186, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 174, 174, 174, 188, 189, - 190, 191, 84, 190, 190, 190, 22, 192, 193, 194, 195, 196, 193, 194, 195, - 196, 22, 22, 22, 138, 197, 197, 197, 22, 198, 199, 200, 201, 202, 203, - 204, 21, 205, 110, 205, 206, 207, 22, 192, 192, 138, 28, 36, 22, 192, - 138, 197, 208, 208, 138, 138, 138, 209, 163, 164, 192, 192, 192, 138, - 138, 138, 138, 138, 138, 138, 138, 78, 138, 208, 138, 138, 192, 138, 138, - 138, 138, 138, 138, 138, 187, 174, 174, 174, 174, 174, 0, 210, 211, 212, - 213, 174, 174, 174, 174, 174, 174, 214, 51, 0, 0, 34, 214, 214, 214, 214, - 214, 215, 215, 216, 217, 218, 219, 214, 34, 34, 34, 34, 214, 214, 214, - 214, 214, 215, 215, 216, 217, 218, 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, 220, 221, 85, - 85, 23, 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, 0, 0, 0, 0, 0, 81, 81, 176, 176, - 81, 81, 81, 81, 176, 176, 176, 81, 81, 82, 82, 82, 82, 81, 82, 82, 82, - 176, 176, 81, 86, 81, 176, 176, 86, 86, 86, 86, 81, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 222, 222, 49, 223, 26, 223, 222, 49, 26, 223, 35, - 49, 49, 49, 35, 35, 49, 49, 49, 46, 26, 49, 223, 26, 78, 49, 49, 49, 49, - 49, 26, 26, 222, 223, 223, 26, 49, 26, 224, 26, 49, 26, 184, 224, 49, 49, - 225, 35, 49, 49, 44, 49, 35, 156, 156, 156, 156, 35, 26, 222, 35, 35, 49, - 49, 226, 78, 78, 78, 78, 49, 35, 35, 35, 35, 26, 78, 26, 26, 47, 80, 227, - 227, 227, 37, 37, 227, 227, 227, 227, 227, 227, 37, 37, 37, 37, 227, 228, - 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 229, 229, 229, - 229, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 229, 229, 229, - 229, 229, 229, 173, 173, 173, 44, 47, 173, 173, 173, 173, 37, 0, 0, 0, 0, - 0, 0, 40, 40, 40, 40, 40, 30, 30, 30, 30, 30, 230, 230, 26, 26, 26, 26, - 78, 26, 26, 78, 26, 26, 78, 26, 26, 26, 26, 26, 26, 26, 230, 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, 231, 230, 230, 26, 26, 40, 26, 40, + 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, + 182, 43, 182, 43, 182, 43, 182, 43, 182, 43, 182, 43, 182, 0, 0, 43, 43, + 43, 43, 43, 43, 43, 43, 183, 183, 183, 183, 183, 183, 183, 183, 43, 43, + 43, 43, 43, 43, 43, 43, 183, 183, 183, 183, 183, 183, 183, 183, 43, 43, + 43, 43, 43, 43, 43, 43, 183, 183, 183, 183, 183, 183, 183, 183, 43, 43, + 43, 43, 43, 0, 43, 43, 38, 38, 38, 184, 183, 58, 182, 58, 58, 76, 43, 43, + 43, 0, 43, 43, 38, 184, 38, 184, 183, 76, 76, 76, 43, 43, 43, 182, 0, 0, + 43, 43, 38, 38, 38, 184, 0, 76, 76, 76, 43, 43, 43, 182, 43, 43, 43, 43, + 38, 38, 38, 184, 38, 76, 185, 185, 0, 0, 43, 43, 43, 0, 43, 43, 38, 184, + 38, 184, 183, 185, 58, 0, 186, 186, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 174, 174, 174, 188, 189, 190, 191, 84, 190, 190, 190, 22, 192, + 193, 194, 195, 196, 193, 194, 195, 196, 22, 22, 22, 138, 197, 197, 197, + 22, 198, 199, 200, 201, 202, 203, 204, 21, 205, 110, 205, 206, 207, 22, + 192, 192, 138, 28, 36, 22, 192, 138, 197, 208, 208, 138, 138, 138, 209, + 163, 164, 192, 192, 192, 138, 138, 138, 138, 138, 138, 138, 138, 78, 138, + 208, 138, 138, 192, 138, 138, 138, 138, 138, 138, 138, 187, 174, 174, + 174, 174, 174, 0, 210, 211, 212, 213, 174, 174, 174, 174, 174, 174, 214, + 51, 0, 0, 34, 214, 214, 214, 214, 214, 215, 215, 216, 217, 218, 219, 214, + 34, 34, 34, 34, 214, 214, 214, 214, 214, 215, 215, 216, 217, 218, 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, 220, 221, 85, 85, 23, 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, 0, 81, 81, 176, 176, 81, 81, 81, 81, 176, 176, 176, 81, 81, + 82, 82, 82, 82, 81, 82, 82, 82, 176, 176, 81, 86, 81, 176, 176, 86, 86, + 86, 86, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 222, 222, 49, + 223, 26, 223, 222, 49, 26, 223, 35, 49, 49, 49, 35, 35, 49, 49, 49, 46, + 26, 49, 223, 26, 78, 49, 49, 49, 49, 49, 26, 26, 222, 223, 223, 26, 49, + 26, 224, 26, 49, 26, 184, 224, 49, 49, 225, 35, 49, 49, 44, 49, 35, 156, + 156, 156, 156, 35, 26, 222, 35, 35, 49, 49, 226, 78, 78, 78, 78, 49, 35, + 35, 35, 35, 26, 78, 26, 26, 47, 80, 227, 227, 227, 37, 37, 227, 227, 227, + 227, 227, 227, 37, 37, 37, 37, 227, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 229, 229, 229, 229, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 229, 229, 229, 229, 229, 229, 173, 173, 173, 44, + 47, 173, 173, 173, 173, 37, 26, 26, 0, 0, 0, 0, 40, 40, 40, 40, 40, 30, + 30, 30, 30, 30, 230, 230, 26, 26, 26, 26, 78, 26, 26, 78, 26, 26, 78, 26, + 26, 26, 26, 26, 26, 26, 230, 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, - 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, 232, 233, 233, 234, 78, 78, 40, 233, 234, - 232, 233, 234, 232, 78, 40, 78, 233, 235, 236, 78, 233, 232, 78, 78, 78, - 233, 232, 232, 233, 40, 233, 233, 232, 232, 40, 234, 40, 234, 40, 40, 40, - 40, 233, 237, 226, 233, 226, 226, 232, 232, 232, 40, 40, 40, 40, 78, 232, - 78, 232, 233, 233, 232, 232, 232, 234, 232, 232, 234, 232, 232, 234, 233, - 234, 232, 232, 233, 78, 78, 78, 78, 78, 233, 232, 232, 232, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 232, 238, 40, 234, 78, 233, 233, 233, 233, 232, - 232, 233, 233, 78, 230, 238, 238, 234, 234, 232, 232, 234, 234, 232, 232, - 234, 234, 232, 232, 232, 232, 232, 232, 234, 234, 233, 233, 234, 234, - 233, 233, 234, 234, 232, 232, 232, 78, 78, 232, 232, 232, 232, 78, 78, - 40, 78, 78, 232, 40, 78, 78, 78, 78, 78, 78, 78, 78, 232, 232, 78, 40, - 232, 232, 232, 232, 232, 232, 234, 234, 234, 234, 232, 232, 232, 232, - 232, 232, 232, 232, 232, 78, 78, 78, 78, 78, 232, 233, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 232, 232, 232, 232, 232, 78, 78, 232, 232, 78, 78, - 78, 78, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 234, 234, 234, - 234, 232, 232, 232, 232, 232, 232, 234, 234, 234, 234, 78, 78, 232, 232, - 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 26, - 26, 26, 26, 26, 26, 26, 26, 163, 164, 163, 164, 26, 26, 26, 26, 26, 26, - 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 232, 232, 26, 26, - 26, 26, 26, 26, 26, 239, 240, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 231, 230, 230, 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, + 232, 233, 233, 234, 78, 78, 40, 233, 234, 232, 233, 234, 232, 78, 40, 78, + 233, 235, 236, 78, 233, 232, 78, 78, 78, 233, 232, 232, 233, 40, 233, + 233, 232, 232, 40, 234, 40, 234, 40, 40, 40, 40, 233, 237, 226, 233, 226, + 226, 232, 232, 232, 40, 40, 40, 40, 78, 232, 78, 232, 233, 233, 232, 232, + 232, 234, 232, 232, 234, 232, 232, 234, 233, 234, 232, 232, 233, 78, 78, + 78, 78, 78, 233, 232, 232, 232, 78, 78, 78, 78, 78, 78, 78, 78, 78, 232, + 238, 40, 234, 78, 233, 233, 233, 233, 232, 232, 233, 233, 78, 230, 238, + 238, 234, 234, 232, 232, 234, 234, 232, 232, 234, 234, 232, 232, 232, + 232, 232, 232, 234, 234, 233, 233, 234, 234, 233, 233, 234, 234, 232, + 232, 232, 78, 78, 232, 232, 232, 232, 78, 78, 40, 78, 78, 232, 40, 78, + 78, 78, 78, 78, 78, 78, 78, 232, 232, 78, 40, 232, 232, 232, 232, 232, + 232, 234, 234, 234, 234, 232, 232, 232, 232, 232, 232, 232, 232, 232, 78, + 78, 78, 78, 78, 232, 233, 78, 78, 78, 78, 78, 78, 78, 78, 78, 232, 232, + 232, 232, 232, 78, 78, 232, 232, 78, 78, 78, 78, 232, 232, 232, 232, 232, + 232, 232, 232, 232, 232, 234, 234, 234, 234, 232, 232, 232, 232, 232, + 232, 234, 234, 234, 234, 78, 78, 232, 232, 232, 232, 232, 232, 232, 232, + 232, 232, 232, 232, 232, 232, 232, 232, 26, 26, 26, 26, 26, 26, 26, 26, + 163, 164, 163, 164, 26, 26, 26, 26, 26, 26, 30, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 232, 232, 26, 26, 26, 26, 26, 26, 26, 239, + 240, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 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, + 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, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 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, 78, 78, 78, 78, 78, 78, 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, 0, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 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, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, - 241, 241, 241, 241, 241, 241, 241, 241, 227, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 241, 241, 241, 241, 241, 241, 227, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 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, 78, 78, 78, 26, 26, 26, 26, 26, 30, 30, 26, 26, 30, 26, 26, - 26, 26, 30, 30, 26, 26, 26, 26, 30, 30, 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, 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, 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, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 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, + 78, 78, 78, 26, 26, 26, 26, 26, 30, 30, 26, 26, 30, 26, 26, 26, 26, 30, + 30, 26, 26, 26, 26, 30, 30, 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, 30, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 80, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, - 26, 26, 26, 26, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 26, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 26, 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, 0, 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, 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, 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, 26, 26, 26, 26, 26, 26, 26, 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, + 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 80, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 30, 30, 26, 26, 26, + 26, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 26, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 26, 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, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 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, 26, 26, 26, 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, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 163, 164, 163, 164, 163, 164, 163, 164, 163, 164, - 163, 164, 163, 164, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 26, 26, 26, 26, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 163, 164, 163, 164, 163, 164, 163, 164, 163, 164, 163, 164, + 163, 164, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, - 153, 153, 153, 153, 153, 153, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 153, 153, 153, 153, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 232, 78, 78, - 232, 232, 163, 164, 78, 232, 232, 78, 232, 232, 232, 78, 78, 78, 78, 78, - 232, 232, 232, 232, 78, 78, 78, 78, 78, 232, 232, 232, 78, 78, 78, 232, - 232, 232, 232, 9, 10, 9, 10, 9, 10, 9, 10, 163, 164, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 80, 80, 80, 80, 80, 80, 80, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 232, 78, 78, 232, + 232, 163, 164, 78, 232, 232, 78, 232, 232, 232, 78, 78, 78, 78, 78, 232, + 232, 232, 232, 78, 78, 78, 78, 78, 232, 232, 232, 78, 78, 78, 232, 232, + 232, 232, 9, 10, 9, 10, 9, 10, 9, 10, 163, 164, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 78, 78, 78, 78, 78, + 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, 163, + 164, 9, 10, 163, 164, 163, 164, 163, 164, 163, 164, 163, 164, 163, 164, + 163, 164, 163, 164, 163, 164, 78, 78, 232, 232, 232, 232, 232, 232, 232, + 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 78, + 78, 78, 78, 78, 78, 78, 78, 232, 78, 78, 78, 78, 78, 78, 78, 232, 232, + 232, 232, 232, 232, 78, 78, 78, 232, 78, 78, 78, 78, 232, 232, 232, 232, + 232, 78, 232, 232, 78, 78, 163, 164, 163, 164, 232, 78, 78, 78, 78, 232, + 78, 232, 232, 232, 78, 78, 232, 232, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 232, 232, 232, 232, 232, 232, 78, 78, 163, 164, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 232, 232, 226, 232, 232, 232, 232, 232, 232, + 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 78, 232, 232, 232, 232, + 78, 78, 232, 78, 232, 78, 78, 232, 78, 232, 232, 232, 232, 78, 78, 78, + 78, 78, 232, 232, 78, 78, 78, 78, 78, 78, 232, 232, 232, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 163, 164, 9, 10, 163, 164, 163, 164, 163, 164, 163, 164, 163, 164, 163, - 164, 163, 164, 163, 164, 163, 164, 78, 78, 232, 232, 232, 232, 232, 232, + 78, 78, 232, 232, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 232, 232, + 78, 78, 78, 78, 232, 232, 232, 232, 78, 232, 232, 78, 78, 232, 226, 216, + 216, 78, 78, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, - 232, 78, 78, 78, 78, 78, 78, 78, 78, 232, 78, 78, 78, 78, 78, 78, 78, - 232, 232, 232, 232, 232, 232, 78, 78, 78, 232, 78, 78, 78, 78, 232, 232, - 232, 232, 232, 78, 232, 232, 78, 78, 163, 164, 163, 164, 232, 78, 78, 78, - 78, 232, 78, 232, 232, 232, 78, 78, 232, 232, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 232, 232, 232, 232, 232, 232, 78, 78, 163, 164, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 232, 232, 226, 232, 232, 232, 232, - 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 78, 232, 232, - 232, 232, 78, 78, 232, 78, 232, 78, 78, 232, 78, 232, 232, 232, 232, 78, - 78, 78, 78, 78, 232, 232, 78, 78, 78, 78, 78, 78, 232, 232, 232, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 232, 232, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 232, 232, 78, 78, 78, 78, 232, 232, 232, 232, 78, 232, 232, 78, 78, 232, - 226, 216, 216, 78, 78, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, + 232, 232, 232, 78, 78, 232, 232, 232, 232, 232, 232, 232, 232, 78, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, - 232, 232, 232, 232, 232, 78, 78, 232, 232, 232, 232, 232, 232, 232, 232, - 78, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, - 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 78, 78, 78, - 78, 78, 243, 78, 232, 78, 78, 78, 232, 232, 232, 232, 232, 78, 78, 78, - 78, 78, 232, 232, 232, 78, 78, 78, 78, 232, 78, 78, 78, 232, 232, 232, - 232, 232, 78, 232, 78, 78, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 78, 78, 78, 78, + 78, 243, 78, 232, 78, 78, 78, 232, 232, 232, 232, 232, 78, 78, 78, 78, + 78, 232, 232, 232, 78, 78, 78, 78, 232, 78, 78, 78, 232, 232, 232, 232, + 232, 78, 232, 78, 78, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 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, 26, 26, 26, 26, 26, + 30, 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, 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, 0, 0, 0, 26, 26, 26, 26, - 26, 30, 30, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 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, + 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, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 0, 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, 26, 26, 26, + 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 47, 47, + 44, 44, 44, 44, 44, 44, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 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, 153, 138, 138, 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, 153, 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, 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, + 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, 0, 0, 0, 0, 0, 0, 0, 51, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 142, 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, + 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, 142, 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, - 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, 163, 164, 163, 164, 163, 164, 163, 164, 138, 138, 138, 138, - 138, 52, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 84, 84, 0, 0, + 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, 163, 164, 163, 164, 163, + 164, 163, 164, 138, 138, 138, 138, 138, 52, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 84, 84, 138, 138, 138, 138, 84, 138, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 244, 244, 244, + 0, 0, 0, 0, 0, 0, 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, 244, 0, 244, 244, 244, 244, 245, 244, + 244, 244, 244, 0, 244, 244, 244, 244, 245, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 245, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 245, 245, 245, 245, 245, 245, 245, 245, + 244, 244, 244, 244, 244, 244, 244, 245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, @@ -1870,81 +1994,81 @@ static unsigned short index2[] = { 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, - 245, 245, 245, 245, 245, 245, 245, 245, 245, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 0, 0, 0, 0, 246, 247, 247, 247, - 244, 248, 170, 249, 250, 251, 250, 251, 250, 251, 250, 251, 250, 251, - 244, 244, 250, 251, 250, 251, 250, 251, 250, 251, 252, 253, 254, 254, - 244, 249, 249, 249, 249, 249, 249, 249, 249, 249, 255, 256, 257, 258, - 259, 259, 252, 248, 248, 248, 248, 248, 245, 244, 260, 260, 260, 248, - 170, 247, 244, 26, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 245, 245, 245, 245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, + 244, 244, 0, 0, 0, 0, 246, 247, 247, 247, 244, 248, 170, 249, 250, 251, + 250, 251, 250, 251, 250, 251, 250, 251, 244, 244, 250, 251, 250, 251, + 250, 251, 250, 251, 252, 253, 254, 254, 244, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 255, 256, 257, 258, 259, 259, 252, 248, 248, 248, + 248, 248, 245, 244, 260, 260, 260, 248, 170, 247, 244, 26, 0, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, - 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 170, 261, 170, - 261, 170, 261, 170, 170, 170, 170, 170, 170, 261, 261, 170, 261, 261, - 170, 261, 261, 170, 261, 261, 170, 261, 261, 170, 170, 170, 170, 170, + 170, 261, 170, 261, 170, 170, 261, 170, 261, 170, 261, 170, 170, 170, + 170, 170, 170, 261, 261, 170, 261, 261, 170, 261, 261, 170, 261, 261, + 170, 261, 261, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 261, 170, 170, 0, + 0, 262, 262, 263, 263, 248, 264, 265, 252, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, + 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, + 170, 170, 261, 170, 261, 170, 261, 170, 170, 170, 170, 170, 170, 261, + 261, 170, 261, 261, 170, 261, 261, 170, 261, 261, 170, 261, 261, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 261, 170, 170, 0, 0, 262, 262, 263, 263, 248, 264, 265, - 252, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 261, 170, - 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, 261, 170, - 261, 170, 261, 170, 261, 170, 261, 170, 170, 261, 170, 261, 170, 261, - 170, 170, 170, 170, 170, 170, 261, 261, 170, 261, 261, 170, 261, 261, - 170, 261, 261, 170, 261, 261, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 261, 170, 170, 261, 261, 261, 261, + 247, 248, 248, 264, 265, 0, 0, 0, 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 261, 170, 170, 261, 261, 261, 261, 247, 248, 248, 264, 265, 0, 0, 0, 0, - 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 0, 0, 0, + 170, 170, 170, 170, 170, 170, 170, 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, 0, 266, 266, 267, 267, - 267, 267, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 170, 170, + 265, 265, 265, 265, 0, 266, 266, 267, 267, 267, 267, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 0, 0, 0, 0, 0, + 170, 170, 170, 170, 170, 0, 0, 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, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 244, 244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 245, 245, 0, + 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 245, 245, 0, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 269, 269, + 269, 269, 269, 269, 269, 269, 245, 270, 270, 270, 270, 270, 270, 270, + 270, 270, 270, 270, 270, 270, 270, 270, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 269, 269, 269, 269, 269, 269, 269, 269, 245, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 245, 245, 245, 266, 267, 267, + 267, 267, 267, 267, 267, 267, 267, 267, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 245, - 245, 245, 266, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 270, 270, 270, 270, 270, 270, 270, 270, 270, + 270, 270, 270, 270, 270, 270, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 245, 245, 245, 245, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 270, 270, 270, 270, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 245, 245, 245, 245, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 0, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 0, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 245, 245, 245, 245, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 245, 245, 245, - 245, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 245, 245, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 245, 245, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 245, 170, 170, 170, 170, 170, 170, + 268, 268, 245, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, @@ -1957,20 +2081,20 @@ static unsigned short index2[] = { 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, + 170, 170, 170, 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, 170, 170, 170, 170, 170, 170, 170, + 26, 26, 26, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 248, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 248, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, @@ -1979,14 +2103,14 @@ static unsigned short index2[] = { 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 0, 0, 0, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, + 170, 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, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 244, 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, 53, 53, 53, 53, 53, - 53, 83, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 53, 138, 138, + 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, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 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, @@ -1994,77 +2118,80 @@ static unsigned short index2[] = { 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, 0, 0, 0, 0, 0, 0, 0, 81, 48, 48, 48, 48, + 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, 173, 173, 173, 173, 173, - 173, 173, 173, 173, 173, 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, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 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, 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, 271, 271, 44, 47, 44, - 47, 0, 44, 47, 44, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 47, 44, - 47, 44, 47, 44, 47, 44, 47, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 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, 271, 271, 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, 0, 0, 44, + 44, 44, 44, 44, 47, 44, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 51, 47, 48, 48, 48, 48, - 48, 48, 48, 135, 48, 48, 48, 142, 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, 139, 139, 135, 135, 139, 26, 26, 26, 26, 0, 0, 0, 0, 148, 148, 148, - 148, 148, 148, 80, 80, 85, 225, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, + 48, 51, 51, 47, 48, 48, 48, 48, 48, 48, 48, 135, 48, 48, 48, 142, 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, 139, 139, 135, 135, 139, 26, 26, 26, 26, + 0, 0, 0, 0, 148, 148, 148, 148, 148, 148, 80, 80, 85, 225, 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, 139, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 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, 139, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 83, 83, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 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, 0, 0, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 83, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 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, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 48, 48, 48, 48, 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, 139, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 170, + 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, 139, 175, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 83, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 0, - 0, 0, 135, 135, 135, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 170, 170, 170, 170, 170, 170, 0, 0, 0, 135, 135, 135, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 145, - 139, 139, 135, 135, 135, 135, 139, 139, 135, 139, 139, 139, 175, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 0, 53, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 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, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 145, 139, 139, 135, 135, 135, 135, 139, + 139, 135, 139, 139, 139, 175, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 83, 0, 53, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, 0, 0, + 0, 83, 83, 48, 48, 48, 48, 48, 135, 53, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 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, 135, 135, 135, 135, 135, 135, 139, 139, 135, 135, + 48, 48, 48, 48, 48, 48, 135, 135, 135, 135, 135, 135, 139, 139, 135, 135, 139, 139, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 135, 48, 48, 48, 48, 48, 48, 48, 48, 135, 139, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 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, 139, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 139, 135, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 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, 139, 135, - 135, 139, 139, 83, 83, 48, 53, 53, 139, 142, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, + 139, 135, 135, 139, 139, 83, 83, 48, 53, 53, 139, 142, 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, 271, + 51, 51, 51, 51, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 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, 139, 139, 135, 139, 139, 135, 139, 139, 83, 139, 142, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, 0, 0, 0, @@ -2159,7 +2286,7 @@ static unsigned short index2[] = { 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 195, 279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 131, 131, 131, 131, 131, 131, 279, 195, 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, @@ -2173,12 +2300,12 @@ static unsigned short index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 280, 26, 0, 0, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 281, 281, 281, 281, 281, 281, 281, 282, 283, 281, 0, 0, - 0, 0, 0, 0, 81, 81, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 281, - 284, 284, 285, 285, 282, 283, 282, 283, 282, 283, 282, 283, 282, 283, - 282, 283, 282, 283, 282, 283, 247, 247, 282, 283, 281, 281, 281, 281, - 285, 285, 285, 286, 281, 286, 0, 281, 286, 281, 281, 284, 287, 288, 287, - 288, 287, 288, 289, 281, 281, 290, 291, 292, 292, 293, 0, 281, 294, 289, - 281, 0, 0, 0, 0, 131, 131, 131, 118, 131, 0, 131, 131, 131, 131, 131, + 0, 0, 0, 0, 81, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 86, 81, + 81, 281, 284, 284, 285, 285, 282, 283, 282, 283, 282, 283, 282, 283, 282, + 283, 282, 283, 282, 283, 282, 283, 247, 247, 282, 283, 281, 281, 281, + 281, 285, 285, 285, 286, 281, 286, 0, 281, 286, 281, 281, 284, 287, 288, + 287, 288, 287, 288, 289, 281, 281, 290, 291, 292, 292, 293, 0, 281, 294, + 289, 281, 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, @@ -2188,72 +2315,79 @@ static unsigned short index2[] = { 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 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, 174, 0, 295, 295, 296, 297, 296, 295, 295, 298, - 299, 295, 300, 301, 302, 301, 301, 303, 303, 303, 303, 303, 303, 303, - 303, 303, 303, 301, 295, 304, 305, 304, 295, 295, 306, 306, 306, 306, + 131, 131, 131, 131, 131, 0, 0, 174, 0, 295, 295, 296, 297, 296, 295, 295, + 298, 299, 295, 300, 301, 302, 301, 301, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 301, 295, 304, 305, 304, 295, 295, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, - 306, 306, 306, 306, 306, 306, 306, 306, 298, 295, 299, 307, 308, 307, - 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, - 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 298, 305, - 299, 305, 298, 299, 310, 311, 312, 310, 310, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 314, 313, 313, 313, 313, 313, 313, 313, 313, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 298, 295, 299, 307, 308, + 307, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, + 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 298, + 305, 299, 305, 298, 299, 310, 311, 312, 310, 310, 313, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 314, 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, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 313, 313, 313, 313, 313, 313, 313, 313, 313, 314, 314, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 314, 314, 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, 313, 313, 313, 313, 0, - 0, 0, 313, 313, 313, 313, 313, 313, 0, 0, 313, 313, 313, 313, 313, 313, - 0, 0, 313, 313, 313, 313, 313, 313, 0, 0, 313, 313, 313, 0, 0, 0, 297, - 297, 305, 307, 315, 297, 297, 0, 316, 317, 317, 317, 317, 316, 316, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 318, 318, 318, 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, + 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, + 313, 0, 0, 0, 313, 313, 313, 313, 313, 313, 0, 0, 313, 313, 313, 313, + 313, 313, 0, 0, 313, 313, 313, 313, 313, 313, 0, 0, 313, 313, 313, 0, 0, + 0, 297, 297, 305, 307, 315, 297, 297, 0, 316, 317, 317, 317, 317, 316, + 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 318, 318, 318, 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, - 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, + 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, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 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, 148, 148, 148, 148, 148, 148, + 48, 48, 48, 48, 0, 0, 0, 0, 0, 83, 138, 83, 0, 0, 0, 0, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 0, 0, 0, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 319, 319, 319, 319, 319, 319, 319, 319, 319, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 0, + 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, - 319, 319, 153, 153, 153, 153, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 153, 0, 0, 0, 0, 0, 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, + 319, 319, 319, 319, 319, 153, 153, 153, 153, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 153, 153, 26, 0, 0, 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, 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, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 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, + 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, 48, 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 320, 320, 320, + 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, + 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 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, 148, 148, 148, 148, 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, 173, 48, 48, 48, 48, 48, 48, 48, 48, 173, 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, 0, 148, 148, 148, 148, 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, 173, 48, - 48, 48, 48, 48, 48, 48, 48, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 0, 83, 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, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, - 48, 83, 173, 173, 173, 173, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, + 48, 48, 83, 173, 173, 173, 173, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 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, @@ -2266,359 +2400,564 @@ static unsigned short index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 0, 0, 107, 0, 107, + 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, 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, 0, 107, 107, 0, 0, 0, 107, 0, 0, 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, 0, 104, 320, 320, 320, 320, 320, 320, 320, 320, 0, 0, 0, 0, 0, - 0, 0, 0, 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, 320, 320, 320, 320, 320, - 320, 0, 0, 0, 138, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 0, 104, 321, 321, 321, 321, 321, 321, 321, 321, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 322, 322, 321, 321, 321, 321, 321, + 321, 321, 107, 107, 107, 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, + 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 321, 321, 321, 321, 321, + 321, 321, 321, 321, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 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, 321, + 321, 321, 321, 321, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 321, 321, + 321, 321, 321, 321, 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, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, - 0, 0, 0, 0, 0, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 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, 0, 0, 0, 0, 321, 321, 107, 107, 321, 321, 321, 321, 321, + 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 0, 0, 321, 321, + 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + 321, 321, 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, 0, 0, 0, 0, 81, 176, 86, 0, 0, 0, 0, 142, - 320, 320, 320, 320, 320, 320, 320, 320, 0, 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, 0, 0, 0, 0, 81, 176, 86, 0, 0, 0, + 0, 142, 321, 321, 321, 321, 321, 321, 321, 321, 0, 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, 320, 320, - 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, + 321, 321, 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, 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, 321, 321, 321, 0, 0, 0, 0, 0, 0, 0, 0, 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, 322, 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, 320, 320, 320, 320, 320, 320, 320, 320, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 81, 86, 0, 0, 0, 0, 321, 321, 321, 321, + 321, 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, 0, 0, 0, 0, 0, 320, 320, 320, 320, 320, 320, 320, 320, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 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, + 321, 321, 321, 321, 321, 321, 321, 321, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, + 0, 0, 321, 321, 321, 321, 321, 321, 321, 321, 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, 321, + 321, 321, 321, 321, 321, 321, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, + 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, + 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, + 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 0, 0, 0, + 0, 0, 0, 0, 321, 321, 321, 321, 321, 321, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 0, 139, 135, 139, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 139, 135, 139, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 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, 142, 83, + 83, 83, 83, 83, 83, 83, 0, 0, 0, 0, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 142, 135, 135, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 48, 140, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 48, 48, 48, 48, + 139, 139, 139, 135, 135, 135, 135, 139, 139, 142, 141, 83, 83, 188, 83, + 83, 83, 83, 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, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 142, 83, 83, 83, 83, 83, 83, - 83, 0, 0, 0, 0, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, - 153, 153, 153, 153, 153, 153, 153, 153, 153, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 135, 135, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 140, 48, 140, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 140, 48, 48, 48, 48, 139, 139, 139, 135, - 135, 135, 135, 139, 139, 142, 141, 83, 83, 188, 83, 83, 83, 83, 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, 0, 0, 0, 0, - 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 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, 0, 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 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, 149, 135, 135, 135, 135, 139, 135, 150, 150, 135, 135, - 135, 142, 142, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 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, 135, 135, 139, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 149, 135, 135, 135, 135, 139, 135, + 150, 150, 135, 135, 135, 142, 142, 0, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 83, 83, 83, 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, 145, 83, + 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 135, 139, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 139, 139, 139, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 139, 175, 48, 48, 48, 48, 83, 83, 83, 83, - 0, 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 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, 139, 139, 139, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 139, 175, 48, 48, 48, 48, 83, 83, 83, 83, 83, 145, 135, 135, + 83, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 48, 83, 48, + 83, 83, 83, 0, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 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, 139, 139, 139, 135, 135, 135, 139, + 139, 135, 175, 145, 135, 83, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 135, - 139, 135, 139, 139, 135, 135, 135, 135, 135, 135, 175, 145, 0, 0, 0, 0, - 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 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, 135, 139, 139, 139, 135, 135, + 135, 135, 135, 135, 145, 142, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 0, 0, 0, 0, 0, 0, 135, 135, 139, 139, 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, 145, 48, 146, + 139, 135, 139, 139, 139, 139, 0, 0, 139, 139, 0, 0, 147, 147, 175, 0, 0, + 48, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 139, 139, + 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, + 146, 139, 139, 135, 135, 135, 135, 135, 135, 139, 149, 147, 147, 146, + 147, 135, 135, 139, 142, 145, 48, 48, 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 146, 139, + 139, 135, 135, 135, 135, 0, 0, 139, 139, 147, 147, 135, 135, 139, 142, + 145, 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, 139, 139, 139, 135, + 135, 135, 135, 135, 135, 135, 135, 139, 139, 135, 139, 142, 135, 83, 83, + 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 135, 139, 135, 139, 139, 135, 135, 135, 135, 135, 135, + 175, 145, 0, 0, 0, 0, 0, 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 135, + 135, 135, 139, 139, 135, 135, 135, 135, 139, 135, 135, 135, 135, 142, 0, + 0, 0, 0, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 148, 148, 83, + 83, 83, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 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, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 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, 0, + 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, + 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, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, - 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 83, 83, 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, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 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, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 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, 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, 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, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 144, 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, 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, 48, 48, + 48, 48, 48, 48, 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, 176, 176, 176, 176, 176, + 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, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 0, 148, 148, 148, 148, 148, 148, 148, 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, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 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, 48, 139, 139, 139, 139, 139, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 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, 48, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 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, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 135, 135, 135, 135, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 170, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 170, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 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, 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, 176, 83, 174, 174, 174, 174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, - 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, 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, - 322, 322, 322, 322, 322, 322, 322, 323, 323, 176, 176, 176, 80, 80, 80, - 324, 323, 323, 323, 323, 323, 174, 174, 174, 174, 174, 174, 174, 174, 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, 326, 326, 326, 326, 326, 326, 326, + 327, 327, 176, 176, 176, 80, 80, 80, 328, 327, 327, 327, 327, 327, 174, + 174, 174, 174, 174, 174, 174, 174, 86, 86, 86, 86, 86, 86, 86, 86, 80, + 80, 81, 81, 81, 81, 81, 86, 86, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 322, 322, 322, 322, 322, 322, 80, 80, + 80, 80, 81, 81, 81, 81, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 326, 326, 326, 326, 326, 326, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 81, 81, 81, 26, 0, 0, 0, 0, 0, 0, + 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, 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, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 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, 148, 148, 148, 148, 148, 148, 148, 148, 148, - 148, 148, 148, 148, 148, 148, 148, 148, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 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, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 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, + 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, 49, 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, 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, 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, 325, + 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, - 35, 35, 35, 35, 35, 35, 35, 226, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, + 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, 325, 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, 226, 35, 35, 35, 35, 35, 35, + 49, 49, 49, 49, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 325, 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, 226, 35, 35, + 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, 325, 35, 35, 35, 35, 35, 35, + 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, 226, 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, 325, 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, 329, 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, 226, 35, 35, 35, 35, 35, 35, 49, 35, 0, 0, 326, 326, - 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 326, 326, 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, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 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, 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, 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, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 0, 0, 0, 0, 0, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 35, 35, 226, 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, 329, 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, 226, 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, 329, 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, 226, 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, 329, 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, 226, 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, 329, 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, + 226, 35, 35, 35, 35, 35, 35, 49, 35, 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, 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, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 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, 321, 321, 321, 321, 321, 321, 321, 321, 321, 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, 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, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 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, 26, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 153, 153, 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, 327, 0, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 331, 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, 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, 222, 222, 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, 241, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 0, - 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, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 222, 222, 0, 0, 0, 0, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 241, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 268, 268, 268, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 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, + 268, 268, 268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 0, 0, 0, 0, 0, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 0, 0, 0, 0, 0, 0, 0, 268, 268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 0, 0, 0, 0, 0, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 0, 0, 0, 0, 0, 0, 0, 268, + 268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, - 26, 26, 26, 26, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 0, 0, 0, 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, 0, - 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, 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, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 0, 26, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 54, 54, + 54, 54, 54, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 0, 26, 26, 26, 26, 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, 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, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 26, 26, 26, 26, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 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, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 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, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 0, 0, 0, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 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, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 0, 0, 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 0, 0, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3146,359 +3485,355 @@ static unsigned int decomp_data[] = { 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, 42863, 259, 294, 259, 339, 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, 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, + 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, 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, 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, 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, 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, @@ -3536,33 +3871,15 @@ static unsigned int decomp_data[] = { 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, + 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, @@ -3578,427 +3895,226 @@ static unsigned int decomp_data[] = { 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, 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, 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, + 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, 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, 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 8 +#define DECOMP_SHIFT 7 static unsigned char decomp_index1[] = { - 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 16, 7, 17, 18, 19, 20, 21, 22, 23, 24, 7, 7, 7, 7, 7, 25, - 7, 26, 27, 28, 29, 30, 31, 32, 33, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 34, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 35, 36, 37, 38, 39, 40, - 41, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 42, 43, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 44, 7, 7, 45, - 46, 47, 48, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 49, 7, 7, 50, 51, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 52, 53, 54, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -}; - -static unsigned short decomp_index2[] = { + 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, @@ -4012,21 +4128,14 @@ static 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, 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, 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, @@ -4036,181 +4145,42 @@ static 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, @@ -4223,35 +4193,19 @@ static 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, 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, @@ -4262,7 +4216,6 @@ static 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4274,62 +4227,585 @@ static 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, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 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, @@ -4370,785 +4846,822 @@ static unsigned short decomp_index2[] = { 6530, 6533, 6536, 6539, 6542, 6545, 6548, 6551, 6554, 6558, 6562, 6566, 6570, 6574, 6578, 6582, 6586, 6590, 6594, 6598, 6602, 6606, 6610, 6614, 6618, 6622, 6626, 6630, 6634, 6638, 6642, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 6646, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 6648, 6650, 0, 0, 0, 0, 0, 0, 6652, 6654, 6656, 6658, 6660, 6662, 6664, - 6666, 6668, 6670, 6672, 6674, 6676, 6678, 6680, 6682, 6684, 6686, 6688, - 6690, 6692, 6694, 6696, 6698, 6700, 6702, 6704, 6706, 6708, 6710, 6712, - 6714, 6716, 6718, 6720, 6722, 6724, 6726, 6728, 6730, 6732, 6734, 6736, - 6738, 6740, 6742, 6744, 6746, 6748, 6750, 6752, 6754, 6756, 6758, 6760, - 6762, 6764, 6766, 6768, 6770, 6772, 6774, 6776, 6778, 6780, 6782, 6784, - 6786, 6788, 6790, 6792, 6794, 6796, 6798, 6800, 6802, 6804, 6806, 6808, - 6810, 6812, 6814, 6816, 6818, 6820, 6822, 6824, 6826, 6828, 6830, 6832, - 6834, 6836, 6838, 6840, 6842, 6844, 6846, 6848, 6850, 6852, 6854, 6856, - 6858, 6860, 6862, 6864, 6866, 6868, 6870, 6872, 6874, 6876, 6878, 6880, - 6882, 6884, 6886, 6888, 6890, 6892, 6894, 6896, 6898, 6900, 6902, 6904, - 6906, 6908, 6910, 6912, 6914, 6916, 6918, 6920, 6922, 6924, 6926, 6928, - 6930, 6932, 6934, 6936, 6938, 6940, 6942, 6944, 6946, 6948, 6950, 6952, - 6954, 6956, 6958, 6960, 6962, 6964, 6966, 6968, 6970, 6972, 6974, 6976, - 6978, 6980, 6982, 6984, 6986, 6988, 6990, 6992, 6994, 6996, 6998, 7000, - 7002, 7004, 7006, 7008, 7010, 7012, 7014, 7016, 7018, 7020, 7022, 7024, - 7026, 7028, 7030, 7032, 7034, 7036, 7038, 7040, 7042, 7044, 7046, 7048, - 7050, 7052, 7054, 7056, 7058, 7060, 7062, 7064, 7066, 7068, 7070, 7072, - 7074, 7076, 7078, 7080, 7082, 7084, 7086, 7088, 7090, 7092, 7094, 7096, - 7098, 7100, 7102, 7104, 7106, 7108, 7110, 7112, 7114, 7116, 7118, 7120, - 7122, 7124, 7126, 7128, 7130, 7132, 7134, 7136, 7138, 7140, 7142, 7144, - 7146, 7148, 7150, 7152, 7154, 7156, 7158, 7160, 7162, 7164, 7166, 7168, - 7170, 7172, 7174, 7176, 7178, 7180, 7182, 7184, 7186, 7188, 7190, 0, 0, - 7192, 0, 7194, 0, 0, 7196, 7198, 7200, 7202, 7204, 7206, 7208, 7210, - 7212, 7214, 0, 7216, 0, 7218, 0, 0, 7220, 7222, 0, 0, 0, 7224, 7226, - 7228, 7230, 7232, 7234, 7236, 7238, 7240, 7242, 7244, 7246, 7248, 7250, - 7252, 7254, 7256, 7258, 7260, 7262, 7264, 7266, 7268, 7270, 7272, 7274, - 7276, 7278, 7280, 7282, 7284, 7286, 7288, 7290, 7292, 7294, 7296, 7298, - 7300, 7302, 7304, 7306, 7308, 7310, 7312, 7314, 7316, 7318, 7320, 7322, - 7324, 7326, 7328, 7330, 7332, 7334, 7336, 7338, 7340, 7342, 7344, 7346, - 7348, 7350, 7352, 7354, 7356, 7358, 0, 0, 7360, 7362, 7364, 7366, 7368, - 7370, 7372, 7374, 7376, 7378, 7380, 7382, 7384, 7386, 7388, 7390, 7392, - 7394, 7396, 7398, 7400, 7402, 7404, 7406, 7408, 7410, 7412, 7414, 7416, - 7418, 7420, 7422, 7424, 7426, 7428, 7430, 7432, 7434, 7436, 7438, 7440, - 7442, 7444, 7446, 7448, 7450, 7452, 7454, 7456, 7458, 7460, 7462, 7464, - 7466, 7468, 7470, 7472, 7474, 7476, 7478, 7480, 7482, 7484, 7486, 7488, - 7490, 7492, 7494, 7496, 7498, 7500, 7502, 7504, 7506, 7508, 7510, 7512, - 7514, 7516, 7518, 7520, 7522, 7524, 7526, 7528, 7530, 7532, 7534, 7536, - 7538, 7540, 7542, 7544, 7546, 7548, 7550, 7552, 7554, 7556, 7558, 7560, - 7562, 7564, 7566, 7568, 7570, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 7572, 7575, 7578, 7581, 7585, 7589, 7592, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 7595, 7598, 7601, 7604, 7607, 0, 0, 0, 0, 0, 7610, 0, 7613, 7616, - 7618, 7620, 7622, 7624, 7626, 7628, 7630, 7632, 7634, 7636, 7639, 7642, - 7645, 7648, 7651, 7654, 7657, 7660, 7663, 7666, 7669, 7672, 0, 7675, - 7678, 7681, 7684, 7687, 0, 7690, 0, 7693, 7696, 0, 7699, 7702, 0, 7705, - 7708, 7711, 7714, 7717, 7720, 7723, 7726, 7729, 7732, 7735, 7737, 7739, - 7741, 7743, 7745, 7747, 7749, 7751, 7753, 7755, 7757, 7759, 7761, 7763, - 7765, 7767, 7769, 7771, 7773, 7775, 7777, 7779, 7781, 7783, 7785, 7787, - 7789, 7791, 7793, 7795, 7797, 7799, 7801, 7803, 7805, 7807, 7809, 7811, - 7813, 7815, 7817, 7819, 7821, 7823, 7825, 7827, 7829, 7831, 7833, 7835, - 7837, 7839, 7841, 7843, 7845, 7847, 7849, 7851, 7853, 7855, 7857, 7859, - 7861, 7863, 7865, 7867, 7869, 7871, 7873, 7875, 7877, 7879, 7881, 7883, - 7885, 7887, 7889, 7891, 7893, 7895, 7897, 7899, 7901, 7903, 7905, 7907, - 7909, 7911, 7913, 7915, 7917, 7919, 7921, 7923, 7925, 7927, 7929, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 7931, 7933, 7935, 7937, 7939, 7941, 7943, 7945, - 7947, 7949, 7951, 7953, 7955, 7957, 7959, 7961, 7963, 7965, 7967, 7969, - 7971, 7973, 7975, 7977, 7980, 7983, 7986, 7989, 7992, 7995, 7998, 8001, - 8004, 8007, 8010, 8013, 8016, 8019, 8022, 8025, 8028, 8031, 8033, 8035, - 8037, 8039, 8042, 8045, 8048, 8051, 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, - 8325, 8329, 8333, 8337, 8341, 8345, 8348, 8351, 8354, 8357, 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, 8775, 8779, 8783, 8786, 8789, 8792, 8795, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9002, 9006, 9010, 9014, 9018, 9022, 9026, 9030, - 9034, 9038, 9042, 9046, 9050, 9054, 9058, 9062, 9066, 9070, 9074, 9078, - 9082, 9086, 9090, 9094, 9098, 9102, 9106, 9110, 9114, 9118, 9122, 9126, - 9130, 9134, 9138, 9142, 9146, 9150, 9154, 9158, 9162, 9166, 9170, 9174, - 9178, 9182, 9186, 9190, 9194, 9198, 9202, 9206, 9210, 9214, 9218, 9222, - 9226, 9230, 9234, 9238, 9242, 9246, 9250, 9254, 0, 0, 9258, 9262, 9266, - 9270, 9274, 9278, 9282, 9286, 9290, 9294, 9298, 9302, 9306, 9310, 9314, - 9318, 9322, 9326, 9330, 9334, 9338, 9342, 9346, 9350, 9354, 9358, 9362, - 9366, 9370, 9374, 9378, 9382, 9386, 9390, 9394, 9398, 9402, 9406, 9410, - 9414, 9418, 9422, 9426, 9430, 9434, 9438, 9442, 9446, 9450, 9454, 9458, - 9462, 9466, 9470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9474, - 9478, 9482, 9487, 9492, 9497, 9502, 9507, 9512, 9517, 9521, 9540, 9549, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9554, 9556, - 9558, 9560, 9562, 9564, 9566, 9568, 9570, 9572, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9574, 9576, 9578, 9580, 9582, - 9584, 9586, 9588, 9590, 9592, 9594, 9596, 9598, 9600, 9602, 9604, 9606, - 9608, 9610, 9612, 9614, 0, 0, 9616, 9618, 9620, 9622, 9624, 9626, 9628, - 9630, 9632, 9634, 9636, 9638, 0, 9640, 9642, 9644, 9646, 9648, 9650, - 9652, 9654, 9656, 9658, 9660, 9662, 9664, 9666, 9668, 9670, 9672, 9674, - 9676, 0, 9678, 9680, 9682, 9684, 0, 0, 0, 0, 9686, 9689, 9692, 0, 9695, - 0, 9698, 9701, 9704, 9707, 9710, 9713, 9716, 9719, 9722, 9725, 9728, - 9730, 9732, 9734, 9736, 9738, 9740, 9742, 9744, 9746, 9748, 9750, 9752, - 9754, 9756, 9758, 9760, 9762, 9764, 9766, 9768, 9770, 9772, 9774, 9776, - 9778, 9780, 9782, 9784, 9786, 9788, 9790, 9792, 9794, 9796, 9798, 9800, - 9802, 9804, 9806, 9808, 9810, 9812, 9814, 9816, 9818, 9820, 9822, 9824, - 9826, 9828, 9830, 9832, 9834, 9836, 9838, 9840, 9842, 9844, 9846, 9848, - 9850, 9852, 9854, 9856, 9858, 9860, 9862, 9864, 9866, 9868, 9870, 9872, - 9874, 9876, 9878, 9880, 9882, 9884, 9886, 9888, 9890, 9892, 9894, 9896, - 9898, 9900, 9902, 9904, 9906, 9908, 9910, 9912, 9914, 9916, 9918, 9920, - 9922, 9924, 9926, 9928, 9930, 9932, 9934, 9936, 9938, 9940, 9942, 9944, - 9946, 9948, 9950, 9952, 9954, 9956, 9958, 9960, 9962, 9965, 9968, 9971, - 9974, 9977, 9980, 9983, 0, 0, 0, 0, 9986, 9988, 9990, 9992, 9994, 9996, - 9998, 10000, 10002, 10004, 10006, 10008, 10010, 10012, 10014, 10016, - 10018, 10020, 10022, 10024, 10026, 10028, 10030, 10032, 10034, 10036, - 10038, 10040, 10042, 10044, 10046, 10048, 10050, 10052, 10054, 10056, - 10058, 10060, 10062, 10064, 10066, 10068, 10070, 10072, 10074, 10076, - 10078, 10080, 10082, 10084, 10086, 10088, 10090, 10092, 10094, 10096, - 10098, 10100, 10102, 10104, 10106, 10108, 10110, 10112, 10114, 10116, - 10118, 10120, 10122, 10124, 10126, 10128, 10130, 10132, 10134, 10136, - 10138, 10140, 10142, 10144, 10146, 10148, 10150, 10152, 10154, 10156, - 10158, 10160, 10162, 10164, 10166, 10168, 10170, 10172, 10174, 10176, - 10178, 10180, 10182, 10184, 10186, 10188, 10190, 10192, 10194, 10196, - 10198, 10200, 10202, 10204, 10206, 10208, 10210, 10212, 10214, 10216, - 10218, 10220, 10222, 10224, 10226, 10228, 10230, 10232, 10234, 10236, - 10238, 10240, 10242, 10244, 10246, 10248, 10250, 10252, 10254, 10256, - 10258, 10260, 10262, 10264, 10266, 10268, 10270, 10272, 10274, 10276, - 10278, 10280, 10282, 10284, 10286, 10288, 10290, 10292, 10294, 10296, - 10298, 10300, 10302, 10304, 10306, 10308, 10310, 10312, 10314, 10316, - 10318, 10320, 10322, 10324, 10326, 10328, 10330, 10332, 10334, 10336, - 10338, 10340, 10342, 10344, 10346, 10348, 10350, 10352, 10354, 10356, - 10358, 10360, 10362, 10364, 0, 0, 0, 10366, 10368, 10370, 10372, 10374, - 10376, 0, 0, 10378, 10380, 10382, 10384, 10386, 10388, 0, 0, 10390, - 10392, 10394, 10396, 10398, 10400, 0, 0, 10402, 10404, 10406, 0, 0, 0, - 10408, 10410, 10412, 10414, 10416, 10418, 10420, 0, 10422, 10424, 10426, - 10428, 10430, 10432, 10434, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10436, 0, 10439, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 10442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10445, 10448, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 10454, 10457, 10460, 10463, - 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, 10472, 10475, - 10478, 10481, 10484, 10487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 10490, 10492, 10494, 10496, 10498, 10500, 10502, 10504, 10506, 10508, - 10510, 10512, 10514, 10516, 10518, 10520, 10522, 10524, 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, 0, 10660, 10662, 10664, 10666, 10668, - 10670, 10672, 10674, 10676, 10678, 10680, 10682, 10684, 10686, 10688, - 10690, 10692, 10694, 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, 0, 10802, 10804, 0, 0, 10806, - 0, 0, 10808, 10810, 0, 0, 10812, 10814, 10816, 10818, 0, 10820, 10822, - 10824, 10826, 10828, 10830, 10832, 10834, 10836, 10838, 10840, 10842, 0, - 10844, 0, 10846, 10848, 10850, 10852, 10854, 10856, 10858, 0, 10860, - 10862, 10864, 10866, 10868, 10870, 10872, 10874, 10876, 10878, 10880, - 10882, 10884, 10886, 10888, 10890, 10892, 10894, 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, 0, 10990, 10992, 10994, 10996, 0, 0, 10998, - 11000, 11002, 11004, 11006, 11008, 11010, 11012, 0, 11014, 11016, 11018, - 11020, 11022, 11024, 11026, 0, 11028, 11030, 11032, 11034, 11036, 11038, - 11040, 11042, 11044, 11046, 11048, 11050, 11052, 11054, 11056, 11058, - 11060, 11062, 11064, 11066, 11068, 11070, 11072, 11074, 11076, 11078, - 11080, 11082, 0, 11084, 11086, 11088, 11090, 0, 11092, 11094, 11096, - 11098, 11100, 0, 11102, 0, 0, 0, 11104, 11106, 11108, 11110, 11112, - 11114, 11116, 0, 11118, 11120, 11122, 11124, 11126, 11128, 11130, 11132, - 11134, 11136, 11138, 11140, 11142, 11144, 11146, 11148, 11150, 11152, - 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, 0, 0, 11798, 11800, 11802, 11804, 11806, 11808, 11810, - 11812, 11814, 11816, 11818, 11820, 11822, 11824, 11826, 11828, 11830, - 11832, 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, 0, 0, 12382, 12384, 12386, 12388, - 12390, 12392, 12394, 12396, 12398, 12400, 12402, 12404, 12406, 12408, - 12410, 12412, 12414, 12416, 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, 0, - 12490, 12492, 12494, 12496, 12498, 12500, 12502, 12504, 12506, 12508, - 12510, 12512, 12514, 12516, 12518, 12520, 12522, 12524, 12526, 12528, - 12530, 12532, 12534, 12536, 12538, 12540, 12542, 0, 12544, 12546, 0, - 12548, 0, 0, 12550, 0, 12552, 12554, 12556, 12558, 12560, 12562, 12564, - 12566, 12568, 12570, 0, 12572, 12574, 12576, 12578, 0, 12580, 0, 12582, - 0, 0, 0, 0, 0, 0, 12584, 0, 0, 0, 0, 12586, 0, 12588, 0, 12590, 0, 12592, - 12594, 12596, 0, 12598, 12600, 0, 12602, 0, 0, 12604, 0, 12606, 0, 12608, - 0, 12610, 0, 12612, 0, 12614, 12616, 0, 12618, 0, 0, 12620, 12622, 12624, - 12626, 0, 12628, 12630, 12632, 12634, 12636, 12638, 12640, 0, 12642, - 12644, 12646, 12648, 0, 12650, 12652, 12654, 12656, 0, 12658, 0, 12660, - 12662, 12664, 12666, 12668, 12670, 12672, 12674, 12676, 12678, 0, 12680, - 12682, 12684, 12686, 12688, 12690, 12692, 12694, 12696, 12698, 12700, - 12702, 12704, 12706, 12708, 12710, 12712, 0, 0, 0, 0, 0, 12714, 12716, - 12718, 0, 12720, 12722, 12724, 12726, 12728, 0, 12730, 12732, 12734, - 12736, 12738, 12740, 12742, 12744, 12746, 12748, 12750, 12752, 12754, - 12756, 12758, 12760, 12762, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12764, 12767, 12770, 12773, 12776, 12779, 12782, 12785, - 12788, 12791, 12794, 0, 0, 0, 0, 0, 12797, 12801, 12805, 12809, 12813, - 12817, 12821, 12825, 12829, 12833, 12837, 12841, 12845, 12849, 12853, - 12857, 12861, 12865, 12869, 12873, 12877, 12881, 12885, 12889, 12893, - 12897, 12901, 12905, 12907, 12909, 12912, 0, 12915, 12917, 12919, 12921, - 12923, 12925, 12927, 12929, 12931, 12933, 12935, 12937, 12939, 12941, - 12943, 12945, 12947, 12949, 12951, 12953, 12955, 12957, 12959, 12961, - 12963, 12965, 12967, 12970, 12973, 12976, 12979, 12983, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12986, 12989, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12992, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12995, 12998, 13001, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 13003, 13005, 13007, 13009, 13011, 13013, 13015, 13017, 13019, 13021, - 13023, 13025, 13027, 13029, 13031, 13033, 13035, 13037, 13039, 13041, - 13043, 13045, 13047, 13049, 13051, 13053, 13055, 13057, 13059, 13061, - 13063, 13065, 13067, 13069, 13071, 13073, 13075, 13077, 13079, 13081, - 13083, 13085, 13087, 0, 0, 0, 0, 0, 13089, 13093, 13097, 13101, 13105, - 13109, 13113, 13117, 13121, 0, 0, 0, 0, 0, 0, 0, 13125, 13127, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 13129, 13131, 13133, 13135, 13137, 13139, 13141, 13143, 13145, - 13147, 13149, 13151, 13153, 13155, 13157, 13159, 13161, 13163, 13165, - 13167, 13169, 13171, 13173, 13175, 13177, 13179, 13181, 13183, 13185, - 13187, 13189, 13191, 13193, 13195, 13197, 13199, 13201, 13203, 13205, - 13207, 13209, 13211, 13213, 13215, 13217, 13219, 13221, 13223, 13225, - 13227, 13229, 13231, 13233, 13235, 13237, 13239, 13241, 13243, 13245, - 13247, 13249, 13251, 13253, 13255, 13257, 13259, 13261, 13263, 13265, - 13267, 13269, 13271, 13273, 13275, 13277, 13279, 13281, 13283, 13285, - 13287, 13289, 13291, 13293, 13295, 13297, 13299, 13301, 13303, 13305, - 13307, 13309, 13311, 13313, 13315, 13317, 13319, 13321, 13323, 13325, - 13327, 13329, 13331, 13333, 13335, 13337, 13339, 13341, 13343, 13345, - 13347, 13349, 13351, 13353, 13355, 13357, 13359, 13361, 13363, 13365, - 13367, 13369, 13371, 13373, 13375, 13377, 13379, 13381, 13383, 13385, - 13387, 13389, 13391, 13393, 13395, 13397, 13399, 13401, 13403, 13405, - 13407, 13409, 13411, 13413, 13415, 13417, 13419, 13421, 13423, 13425, - 13427, 13429, 13431, 13433, 13435, 13437, 13439, 13441, 13443, 13445, - 13447, 13449, 13451, 13453, 13455, 13457, 13459, 13461, 13463, 13465, - 13467, 13469, 13471, 13473, 13475, 13477, 13479, 13481, 13483, 13485, - 13487, 13489, 13491, 13493, 13495, 13497, 13499, 13501, 13503, 13505, - 13507, 13509, 13511, 13513, 13515, 13517, 13519, 13521, 13523, 13525, - 13527, 13529, 13531, 13533, 13535, 13537, 13539, 13541, 13543, 13545, - 13547, 13549, 13551, 13553, 13555, 13557, 13559, 13561, 13563, 13565, - 13567, 13569, 13571, 13573, 13575, 13577, 13579, 13581, 13583, 13585, - 13587, 13589, 13591, 13593, 13595, 13597, 13599, 13601, 13603, 13605, - 13607, 13609, 13611, 13613, 13615, 13617, 13619, 13621, 13623, 13625, - 13627, 13629, 13631, 13633, 13635, 13637, 13639, 13641, 13643, 13645, - 13647, 13649, 13651, 13653, 13655, 13657, 13659, 13661, 13663, 13665, - 13667, 13669, 13671, 13673, 13675, 13677, 13679, 13681, 13683, 13685, - 13687, 13689, 13691, 13693, 13695, 13697, 13699, 13701, 13703, 13705, - 13707, 13709, 13711, 13713, 13715, 13717, 13719, 13721, 13723, 13725, - 13727, 13729, 13731, 13733, 13735, 13737, 13739, 13741, 13743, 13745, - 13747, 13749, 13751, 13753, 13755, 13757, 13759, 13761, 13763, 13765, - 13767, 13769, 13771, 13773, 13775, 13777, 13779, 13781, 13783, 13785, - 13787, 13789, 13791, 13793, 13795, 13797, 13799, 13801, 13803, 13805, - 13807, 13809, 13811, 13813, 13815, 13817, 13819, 13821, 13823, 13825, - 13827, 13829, 13831, 13833, 13835, 13837, 13839, 13841, 13843, 13845, - 13847, 13849, 13851, 13853, 13855, 13857, 13859, 13861, 13863, 13865, - 13867, 13869, 13871, 13873, 13875, 13877, 13879, 13881, 13883, 13885, - 13887, 13889, 13891, 13893, 13895, 13897, 13899, 13901, 13903, 13905, - 13907, 13909, 13911, 13913, 13915, 13917, 13919, 13921, 13923, 13925, - 13927, 13929, 13931, 13933, 13935, 13937, 13939, 13941, 13943, 13945, - 13947, 13949, 13951, 13953, 13955, 13957, 13959, 13961, 13963, 13965, - 13967, 13969, 13971, 13973, 13975, 13977, 13979, 13981, 13983, 13985, - 13987, 13989, 13991, 13993, 13995, 13997, 13999, 14001, 14003, 14005, - 14007, 14009, 14011, 14013, 14015, 14017, 14019, 14021, 14023, 14025, - 14027, 14029, 14031, 14033, 14035, 14037, 14039, 14041, 14043, 14045, - 14047, 14049, 14051, 14053, 14055, 14057, 14059, 14061, 14063, 14065, - 14067, 14069, 14071, 14073, 14075, 14077, 14079, 14081, 14083, 14085, - 14087, 14089, 14091, 14093, 14095, 14097, 14099, 14101, 14103, 14105, - 14107, 14109, 14111, 14113, 14115, 14117, 14119, 14121, 14123, 14125, - 14127, 14129, 14131, 14133, 14135, 14137, 14139, 14141, 14143, 14145, - 14147, 14149, 14151, 14153, 14155, 14157, 14159, 14161, 14163, 14165, - 14167, 14169, 14171, 14173, 14175, 14177, 14179, 14181, 14183, 14185, - 14187, 14189, 14191, 14193, 14195, 14197, 14199, 14201, 14203, 14205, - 14207, 14209, 14211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6646, 6648, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6650, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 6652, 6654, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6656, 6658, 6660, 6662, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 6664, 6666, 6668, 6670, 6672, 6674, 6676, 6678, + 6680, 6682, 6684, 6686, 6688, 6690, 6692, 6694, 6696, 6698, 6700, 6702, + 6704, 6706, 6708, 6710, 6712, 6714, 6716, 6718, 6720, 6722, 6724, 6726, + 6728, 6730, 6732, 6734, 6736, 6738, 6740, 6742, 6744, 6746, 6748, 6750, + 6752, 6754, 6756, 6758, 6760, 6762, 6764, 6766, 6768, 6770, 6772, 6774, + 6776, 6778, 6780, 6782, 6784, 6786, 6788, 6790, 6792, 6794, 6796, 6798, + 6800, 6802, 6804, 6806, 6808, 6810, 6812, 6814, 6816, 6818, 6820, 6822, + 6824, 6826, 6828, 6830, 6832, 6834, 6836, 6838, 6840, 6842, 6844, 6846, + 6848, 6850, 6852, 6854, 6856, 6858, 6860, 6862, 6864, 6866, 6868, 6870, + 6872, 6874, 6876, 6878, 6880, 6882, 6884, 6886, 6888, 6890, 6892, 6894, + 6896, 6898, 6900, 6902, 6904, 6906, 6908, 6910, 6912, 6914, 6916, 6918, + 6920, 6922, 6924, 6926, 6928, 6930, 6932, 6934, 6936, 6938, 6940, 6942, + 6944, 6946, 6948, 6950, 6952, 6954, 6956, 6958, 6960, 6962, 6964, 6966, + 6968, 6970, 6972, 6974, 6976, 6978, 6980, 6982, 6984, 6986, 6988, 6990, + 6992, 6994, 6996, 6998, 7000, 7002, 7004, 7006, 7008, 7010, 7012, 7014, + 7016, 7018, 7020, 7022, 7024, 7026, 7028, 7030, 7032, 7034, 7036, 7038, + 7040, 7042, 7044, 7046, 7048, 7050, 7052, 7054, 7056, 7058, 7060, 7062, + 7064, 7066, 7068, 7070, 7072, 7074, 7076, 7078, 7080, 7082, 7084, 7086, + 7088, 7090, 7092, 7094, 7096, 7098, 7100, 7102, 7104, 7106, 7108, 7110, + 7112, 7114, 7116, 7118, 7120, 7122, 7124, 7126, 7128, 7130, 7132, 7134, + 7136, 7138, 7140, 7142, 7144, 7146, 7148, 7150, 7152, 7154, 7156, 7158, + 7160, 7162, 7164, 7166, 7168, 7170, 7172, 7174, 7176, 7178, 7180, 7182, + 7184, 7186, 7188, 7190, 7192, 7194, 7196, 7198, 7200, 7202, 0, 0, 7204, + 0, 7206, 0, 0, 7208, 7210, 7212, 7214, 7216, 7218, 7220, 7222, 7224, + 7226, 0, 7228, 0, 7230, 0, 0, 7232, 7234, 0, 0, 0, 7236, 7238, 7240, + 7242, 7244, 7246, 7248, 7250, 7252, 7254, 7256, 7258, 7260, 7262, 7264, + 7266, 7268, 7270, 7272, 7274, 7276, 7278, 7280, 7282, 7284, 7286, 7288, + 7290, 7292, 7294, 7296, 7298, 7300, 7302, 7304, 7306, 7308, 7310, 7312, + 7314, 7316, 7318, 7320, 7322, 7324, 7326, 7328, 7330, 7332, 7334, 7336, + 7338, 7340, 7342, 7344, 7346, 7348, 7350, 7352, 7354, 7356, 7358, 7360, + 7362, 7364, 7366, 7368, 7370, 0, 0, 7372, 7374, 7376, 7378, 7380, 7382, + 7384, 7386, 7388, 7390, 7392, 7394, 7396, 7398, 7400, 7402, 7404, 7406, + 7408, 7410, 7412, 7414, 7416, 7418, 7420, 7422, 7424, 7426, 7428, 7430, + 7432, 7434, 7436, 7438, 7440, 7442, 7444, 7446, 7448, 7450, 7452, 7454, + 7456, 7458, 7460, 7462, 7464, 7466, 7468, 7470, 7472, 7474, 7476, 7478, + 7480, 7482, 7484, 7486, 7488, 7490, 7492, 7494, 7496, 7498, 7500, 7502, + 7504, 7506, 7508, 7510, 7512, 7514, 7516, 7518, 7520, 7522, 7524, 7526, + 7528, 7530, 7532, 7534, 7536, 7538, 7540, 7542, 7544, 7546, 7548, 7550, + 7552, 7554, 7556, 7558, 7560, 7562, 7564, 7566, 7568, 7570, 7572, 7574, + 7576, 7578, 7580, 7582, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7584, + 7587, 7590, 7593, 7597, 7601, 7604, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7607, 7610, 7613, 7616, 7619, 0, 0, 0, 0, 0, 7622, 0, 7625, 7628, 7630, + 7632, 7634, 7636, 7638, 7640, 7642, 7644, 7646, 7648, 7651, 7654, 7657, + 7660, 7663, 7666, 7669, 7672, 7675, 7678, 7681, 7684, 0, 7687, 7690, + 7693, 7696, 7699, 0, 7702, 0, 7705, 7708, 0, 7711, 7714, 0, 7717, 7720, + 7723, 7726, 7729, 7732, 7735, 7738, 7741, 7744, 7747, 7749, 7751, 7753, + 7755, 7757, 7759, 7761, 7763, 7765, 7767, 7769, 7771, 7773, 7775, 7777, + 7779, 7781, 7783, 7785, 7787, 7789, 7791, 7793, 7795, 7797, 7799, 7801, + 7803, 7805, 7807, 7809, 7811, 7813, 7815, 7817, 7819, 7821, 7823, 7825, + 7827, 7829, 7831, 7833, 7835, 7837, 7839, 7841, 7843, 7845, 7847, 7849, + 7851, 7853, 7855, 7857, 7859, 7861, 7863, 7865, 7867, 7869, 7871, 7873, + 7875, 7877, 7879, 7881, 7883, 7885, 7887, 7889, 7891, 7893, 7895, 7897, + 7899, 7901, 7903, 7905, 7907, 7909, 7911, 7913, 7915, 7917, 7919, 7921, + 7923, 7925, 7927, 7929, 7931, 7933, 7935, 7937, 7939, 7941, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7943, 7945, 7947, 7949, 7951, 7953, 7955, 7957, 7959, + 7961, 7963, 7965, 7967, 7969, 7971, 7973, 7975, 7977, 7979, 7981, 7983, + 7985, 7987, 7989, 7992, 7995, 7998, 8001, 8004, 8007, 8010, 8013, 8016, + 8019, 8022, 8025, 8028, 8031, 8034, 8037, 8040, 8043, 8045, 8047, 8049, + 8051, 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, 8337, + 8341, 8345, 8349, 8353, 8357, 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, 8787, 8791, 8795, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9014, 9018, 9022, 9026, 9030, 9034, 9038, 9042, 9046, + 9050, 9054, 9058, 9062, 9066, 9070, 9074, 9078, 9082, 9086, 9090, 9094, + 9098, 9102, 9106, 9110, 9114, 9118, 9122, 9126, 9130, 9134, 9138, 9142, + 9146, 9150, 9154, 9158, 9162, 9166, 9170, 9174, 9178, 9182, 9186, 9190, + 9194, 9198, 9202, 9206, 9210, 9214, 9218, 9222, 9226, 9230, 9234, 9238, + 9242, 9246, 9250, 9254, 9258, 9262, 9266, 0, 0, 9270, 9274, 9278, 9282, + 9286, 9290, 9294, 9298, 9302, 9306, 9310, 9314, 9318, 9322, 9326, 9330, + 9334, 9338, 9342, 9346, 9350, 9354, 9358, 9362, 9366, 9370, 9374, 9378, + 9382, 9386, 9390, 9394, 9398, 9402, 9406, 9410, 9414, 9418, 9422, 9426, + 9430, 9434, 9438, 9442, 9446, 9450, 9454, 9458, 9462, 9466, 9470, 9474, + 9478, 9482, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9486, 9490, + 9494, 9499, 9504, 9509, 9514, 9519, 9524, 9529, 9533, 9552, 9561, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9566, 9568, 9570, + 9572, 9574, 9576, 9578, 9580, 9582, 9584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9586, 9588, 9590, 9592, 9594, 9596, + 9598, 9600, 9602, 9604, 9606, 9608, 9610, 9612, 9614, 9616, 9618, 9620, + 9622, 9624, 9626, 0, 0, 9628, 9630, 9632, 9634, 9636, 9638, 9640, 9642, + 9644, 9646, 9648, 9650, 0, 9652, 9654, 9656, 9658, 9660, 9662, 9664, + 9666, 9668, 9670, 9672, 9674, 9676, 9678, 9680, 9682, 9684, 9686, 9688, + 0, 9690, 9692, 9694, 9696, 0, 0, 0, 0, 9698, 9701, 9704, 0, 9707, 0, + 9710, 9713, 9716, 9719, 9722, 9725, 9728, 9731, 9734, 9737, 9740, 9742, + 9744, 9746, 9748, 9750, 9752, 9754, 9756, 9758, 9760, 9762, 9764, 9766, + 9768, 9770, 9772, 9774, 9776, 9778, 9780, 9782, 9784, 9786, 9788, 9790, + 9792, 9794, 9796, 9798, 9800, 9802, 9804, 9806, 9808, 9810, 9812, 9814, + 9816, 9818, 9820, 9822, 9824, 9826, 9828, 9830, 9832, 9834, 9836, 9838, + 9840, 9842, 9844, 9846, 9848, 9850, 9852, 9854, 9856, 9858, 9860, 9862, + 9864, 9866, 9868, 9870, 9872, 9874, 9876, 9878, 9880, 9882, 9884, 9886, + 9888, 9890, 9892, 9894, 9896, 9898, 9900, 9902, 9904, 9906, 9908, 9910, + 9912, 9914, 9916, 9918, 9920, 9922, 9924, 9926, 9928, 9930, 9932, 9934, + 9936, 9938, 9940, 9942, 9944, 9946, 9948, 9950, 9952, 9954, 9956, 9958, + 9960, 9962, 9964, 9966, 9968, 9970, 9972, 9974, 9977, 9980, 9983, 9986, + 9989, 9992, 9995, 0, 0, 0, 0, 9998, 10000, 10002, 10004, 10006, 10008, + 10010, 10012, 10014, 10016, 10018, 10020, 10022, 10024, 10026, 10028, + 10030, 10032, 10034, 10036, 10038, 10040, 10042, 10044, 10046, 10048, + 10050, 10052, 10054, 10056, 10058, 10060, 10062, 10064, 10066, 10068, + 10070, 10072, 10074, 10076, 10078, 10080, 10082, 10084, 10086, 10088, + 10090, 10092, 10094, 10096, 10098, 10100, 10102, 10104, 10106, 10108, + 10110, 10112, 10114, 10116, 10118, 10120, 10122, 10124, 10126, 10128, + 10130, 10132, 10134, 10136, 10138, 10140, 10142, 10144, 10146, 10148, + 10150, 10152, 10154, 10156, 10158, 10160, 10162, 10164, 10166, 10168, + 10170, 10172, 10174, 10176, 10178, 10180, 10182, 10184, 10186, 10188, + 10190, 10192, 10194, 10196, 10198, 10200, 10202, 10204, 10206, 10208, + 10210, 10212, 10214, 10216, 10218, 10220, 10222, 10224, 10226, 10228, + 10230, 10232, 10234, 10236, 10238, 10240, 10242, 10244, 10246, 10248, + 10250, 10252, 10254, 10256, 10258, 10260, 10262, 10264, 10266, 10268, + 10270, 10272, 10274, 10276, 10278, 10280, 10282, 10284, 10286, 10288, + 10290, 10292, 10294, 10296, 10298, 10300, 10302, 10304, 10306, 10308, + 10310, 10312, 10314, 10316, 10318, 10320, 10322, 10324, 10326, 10328, + 10330, 10332, 10334, 10336, 10338, 10340, 10342, 10344, 10346, 10348, + 10350, 10352, 10354, 10356, 10358, 10360, 10362, 10364, 10366, 10368, + 10370, 10372, 10374, 10376, 0, 0, 0, 10378, 10380, 10382, 10384, 10386, + 10388, 0, 0, 10390, 10392, 10394, 10396, 10398, 10400, 0, 0, 10402, + 10404, 10406, 10408, 10410, 10412, 0, 0, 10414, 10416, 10418, 0, 0, 0, + 10420, 10422, 10424, 10426, 10428, 10430, 10432, 0, 10434, 10436, 10438, + 10440, 10442, 10444, 10446, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 10448, 0, 10451, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10457, 10460, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10463, 10466, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10469, + 10472, 0, 10475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 10478, 10481, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 10484, 10487, 10490, 10493, 10496, 10499, 10502, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10505, 10508, 10511, 10514, 10517, + 10520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10523, 10525, 10527, + 10529, 10531, 10533, 10535, 10537, 10539, 10541, 10543, 10545, 10547, + 10549, 10551, 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, + 10569, 10571, 10573, 10575, 10577, 10579, 10581, 10583, 10585, 10587, + 10589, 10591, 10593, 10595, 10597, 10599, 10601, 10603, 10605, 10607, + 10609, 10611, 10613, 10615, 10617, 10619, 10621, 10623, 10625, 10627, + 10629, 10631, 10633, 10635, 10637, 10639, 10641, 10643, 10645, 10647, + 10649, 10651, 10653, 10655, 10657, 10659, 10661, 10663, 10665, 10667, + 10669, 10671, 10673, 10675, 10677, 10679, 10681, 10683, 10685, 10687, + 10689, 10691, 0, 10693, 10695, 10697, 10699, 10701, 10703, 10705, 10707, + 10709, 10711, 10713, 10715, 10717, 10719, 10721, 10723, 10725, 10727, + 10729, 10731, 10733, 10735, 10737, 10739, 10741, 10743, 10745, 10747, + 10749, 10751, 10753, 10755, 10757, 10759, 10761, 10763, 10765, 10767, + 10769, 10771, 10773, 10775, 10777, 10779, 10781, 10783, 10785, 10787, + 10789, 10791, 10793, 10795, 10797, 10799, 10801, 10803, 10805, 10807, + 10809, 10811, 10813, 10815, 10817, 10819, 10821, 10823, 10825, 10827, + 10829, 10831, 10833, 0, 10835, 10837, 0, 0, 10839, 0, 0, 10841, 10843, 0, + 0, 10845, 10847, 10849, 10851, 0, 10853, 10855, 10857, 10859, 10861, + 10863, 10865, 10867, 10869, 10871, 10873, 10875, 0, 10877, 0, 10879, + 10881, 10883, 10885, 10887, 10889, 10891, 0, 10893, 10895, 10897, 10899, + 10901, 10903, 10905, 10907, 10909, 10911, 10913, 10915, 10917, 10919, + 10921, 10923, 10925, 10927, 10929, 10931, 10933, 10935, 10937, 10939, + 10941, 10943, 10945, 10947, 10949, 10951, 10953, 10955, 10957, 10959, + 10961, 10963, 10965, 10967, 10969, 10971, 10973, 10975, 10977, 10979, + 10981, 10983, 10985, 10987, 10989, 10991, 10993, 10995, 10997, 10999, + 11001, 11003, 11005, 11007, 11009, 11011, 11013, 11015, 11017, 11019, + 11021, 0, 11023, 11025, 11027, 11029, 0, 0, 11031, 11033, 11035, 11037, + 11039, 11041, 11043, 11045, 0, 11047, 11049, 11051, 11053, 11055, 11057, + 11059, 0, 11061, 11063, 11065, 11067, 11069, 11071, 11073, 11075, 11077, + 11079, 11081, 11083, 11085, 11087, 11089, 11091, 11093, 11095, 11097, + 11099, 11101, 11103, 11105, 11107, 11109, 11111, 11113, 11115, 0, 11117, + 11119, 11121, 11123, 0, 11125, 11127, 11129, 11131, 11133, 0, 11135, 0, + 0, 0, 11137, 11139, 11141, 11143, 11145, 11147, 11149, 0, 11151, 11153, + 11155, 11157, 11159, 11161, 11163, 11165, 11167, 11169, 11171, 11173, + 11175, 11177, 11179, 11181, 11183, 11185, 11187, 11189, 11191, 11193, + 11195, 11197, 11199, 11201, 11203, 11205, 11207, 11209, 11211, 11213, + 11215, 11217, 11219, 11221, 11223, 11225, 11227, 11229, 11231, 11233, + 11235, 11237, 11239, 11241, 11243, 11245, 11247, 11249, 11251, 11253, + 11255, 11257, 11259, 11261, 11263, 11265, 11267, 11269, 11271, 11273, + 11275, 11277, 11279, 11281, 11283, 11285, 11287, 11289, 11291, 11293, + 11295, 11297, 11299, 11301, 11303, 11305, 11307, 11309, 11311, 11313, + 11315, 11317, 11319, 11321, 11323, 11325, 11327, 11329, 11331, 11333, + 11335, 11337, 11339, 11341, 11343, 11345, 11347, 11349, 11351, 11353, + 11355, 11357, 11359, 11361, 11363, 11365, 11367, 11369, 11371, 11373, + 11375, 11377, 11379, 11381, 11383, 11385, 11387, 11389, 11391, 11393, + 11395, 11397, 11399, 11401, 11403, 11405, 11407, 11409, 11411, 11413, + 11415, 11417, 11419, 11421, 11423, 11425, 11427, 11429, 11431, 11433, + 11435, 11437, 11439, 11441, 11443, 11445, 11447, 11449, 11451, 11453, + 11455, 11457, 11459, 11461, 11463, 11465, 11467, 11469, 11471, 11473, + 11475, 11477, 11479, 11481, 11483, 11485, 11487, 11489, 11491, 11493, + 11495, 11497, 11499, 11501, 11503, 11505, 11507, 11509, 11511, 11513, + 11515, 11517, 11519, 11521, 11523, 11525, 11527, 11529, 11531, 11533, + 11535, 11537, 11539, 11541, 11543, 11545, 11547, 11549, 11551, 11553, + 11555, 11557, 11559, 11561, 11563, 11565, 11567, 11569, 11571, 11573, + 11575, 11577, 11579, 11581, 11583, 11585, 11587, 11589, 11591, 11593, + 11595, 11597, 11599, 11601, 11603, 11605, 11607, 11609, 11611, 11613, + 11615, 11617, 11619, 11621, 11623, 11625, 11627, 11629, 11631, 11633, + 11635, 11637, 11639, 11641, 11643, 11645, 11647, 11649, 11651, 11653, + 11655, 11657, 11659, 11661, 11663, 11665, 11667, 11669, 11671, 11673, + 11675, 11677, 11679, 11681, 11683, 11685, 11687, 11689, 11691, 11693, + 11695, 11697, 11699, 11701, 11703, 11705, 11707, 11709, 11711, 11713, + 11715, 11717, 11719, 11721, 11723, 11725, 11727, 11729, 11731, 11733, + 11735, 11737, 11739, 11741, 11743, 11745, 11747, 11749, 11751, 11753, + 11755, 11757, 11759, 11761, 11763, 11765, 11767, 11769, 11771, 11773, + 11775, 11777, 11779, 11781, 11783, 11785, 11787, 11789, 11791, 11793, + 11795, 11797, 11799, 11801, 11803, 11805, 11807, 11809, 11811, 11813, + 11815, 11817, 11819, 11821, 11823, 11825, 11827, 11829, 0, 0, 11831, + 11833, 11835, 11837, 11839, 11841, 11843, 11845, 11847, 11849, 11851, + 11853, 11855, 11857, 11859, 11861, 11863, 11865, 11867, 11869, 11871, + 11873, 11875, 11877, 11879, 11881, 11883, 11885, 11887, 11889, 11891, + 11893, 11895, 11897, 11899, 11901, 11903, 11905, 11907, 11909, 11911, + 11913, 11915, 11917, 11919, 11921, 11923, 11925, 11927, 11929, 11931, + 11933, 11935, 11937, 11939, 11941, 11943, 11945, 11947, 11949, 11951, + 11953, 11955, 11957, 11959, 11961, 11963, 11965, 11967, 11969, 11971, + 11973, 11975, 11977, 11979, 11981, 11983, 11985, 11987, 11989, 11991, + 11993, 11995, 11997, 11999, 12001, 12003, 12005, 12007, 12009, 12011, + 12013, 12015, 12017, 12019, 12021, 12023, 12025, 12027, 12029, 12031, + 12033, 12035, 12037, 12039, 12041, 12043, 12045, 12047, 12049, 12051, + 12053, 12055, 12057, 12059, 12061, 12063, 12065, 12067, 12069, 12071, + 12073, 12075, 12077, 12079, 12081, 12083, 12085, 12087, 12089, 12091, + 12093, 12095, 12097, 12099, 12101, 12103, 12105, 12107, 12109, 12111, + 12113, 12115, 12117, 12119, 12121, 12123, 12125, 12127, 12129, 12131, + 12133, 12135, 12137, 12139, 12141, 12143, 12145, 12147, 12149, 12151, + 12153, 12155, 12157, 12159, 12161, 12163, 12165, 12167, 12169, 12171, + 12173, 12175, 12177, 12179, 12181, 12183, 12185, 12187, 12189, 12191, + 12193, 12195, 12197, 12199, 12201, 12203, 12205, 12207, 12209, 12211, + 12213, 12215, 12217, 12219, 12221, 12223, 12225, 12227, 12229, 12231, + 12233, 12235, 12237, 12239, 12241, 12243, 12245, 12247, 12249, 12251, + 12253, 12255, 12257, 12259, 12261, 12263, 12265, 12267, 12269, 12271, + 12273, 12275, 12277, 12279, 12281, 12283, 12285, 12287, 12289, 12291, + 12293, 12295, 12297, 12299, 12301, 12303, 12305, 12307, 12309, 12311, + 12313, 12315, 12317, 12319, 12321, 12323, 12325, 12327, 12329, 12331, + 12333, 12335, 12337, 12339, 12341, 12343, 12345, 12347, 12349, 12351, + 12353, 12355, 12357, 12359, 12361, 12363, 12365, 12367, 12369, 12371, + 12373, 12375, 12377, 12379, 12381, 12383, 12385, 12387, 12389, 12391, + 12393, 12395, 12397, 12399, 12401, 12403, 12405, 12407, 12409, 12411, + 12413, 0, 0, 12415, 12417, 12419, 12421, 12423, 12425, 12427, 12429, + 12431, 12433, 12435, 12437, 12439, 12441, 12443, 12445, 12447, 12449, + 12451, 12453, 12455, 12457, 12459, 12461, 12463, 12465, 12467, 12469, + 12471, 12473, 12475, 12477, 12479, 12481, 12483, 12485, 12487, 12489, + 12491, 12493, 12495, 12497, 12499, 12501, 12503, 12505, 12507, 12509, + 12511, 12513, 12515, 12517, 12519, 12521, 0, 12523, 12525, 12527, 12529, + 12531, 12533, 12535, 12537, 12539, 12541, 12543, 12545, 12547, 12549, + 12551, 12553, 12555, 12557, 12559, 12561, 12563, 12565, 12567, 12569, + 12571, 12573, 12575, 0, 12577, 12579, 0, 12581, 0, 0, 12583, 0, 12585, + 12587, 12589, 12591, 12593, 12595, 12597, 12599, 12601, 12603, 0, 12605, + 12607, 12609, 12611, 0, 12613, 0, 12615, 0, 0, 0, 0, 0, 0, 12617, 0, 0, + 0, 0, 12619, 0, 12621, 0, 12623, 0, 12625, 12627, 12629, 0, 12631, 12633, + 0, 12635, 0, 0, 12637, 0, 12639, 0, 12641, 0, 12643, 0, 12645, 0, 12647, + 12649, 0, 12651, 0, 0, 12653, 12655, 12657, 12659, 0, 12661, 12663, + 12665, 12667, 12669, 12671, 12673, 0, 12675, 12677, 12679, 12681, 0, + 12683, 12685, 12687, 12689, 0, 12691, 0, 12693, 12695, 12697, 12699, + 12701, 12703, 12705, 12707, 12709, 12711, 0, 12713, 12715, 12717, 12719, + 12721, 12723, 12725, 12727, 12729, 12731, 12733, 12735, 12737, 12739, + 12741, 12743, 12745, 0, 0, 0, 0, 0, 12747, 12749, 12751, 0, 12753, 12755, + 12757, 12759, 12761, 0, 12763, 12765, 12767, 12769, 12771, 12773, 12775, + 12777, 12779, 12781, 12783, 12785, 12787, 12789, 12791, 12793, 12795, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12797, 12800, + 12803, 12806, 12809, 12812, 12815, 12818, 12821, 12824, 12827, 0, 0, 0, + 0, 0, 12830, 12834, 12838, 12842, 12846, 12850, 12854, 12858, 12862, + 12866, 12870, 12874, 12878, 12882, 12886, 12890, 12894, 12898, 12902, + 12906, 12910, 12914, 12918, 12922, 12926, 12930, 12934, 12938, 12940, + 12942, 12945, 0, 12948, 12950, 12952, 12954, 12956, 12958, 12960, 12962, + 12964, 12966, 12968, 12970, 12972, 12974, 12976, 12978, 12980, 12982, + 12984, 12986, 12988, 12990, 12992, 12994, 12996, 12998, 13000, 13003, + 13006, 13009, 13012, 13016, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13019, 13022, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 13025, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13028, 13031, + 13034, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13036, 13038, 13040, 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, 0, 0, 0, + 0, 0, 13122, 13126, 13130, 13134, 13138, 13142, 13146, 13150, 13154, 0, + 0, 0, 0, 0, 0, 0, 13158, 13160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 13162, 13164, 13166, 13168, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 unsigned short comp_index[] = { - 0, 0, 0, 0, 0, 0, 1, 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, 3, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 0, 12, 0, 0, 0, 0, 0, 0, 0, 13, - 14, 15, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 0, 19, 20, 21, 0, 0, - 0, 0, 0, 0, 0, 22, 23, 24, 25, 26, 27, 28, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 32, 0, 0, 33, 0, 0, 0, 0, 0, 0, - 0, 0, 34, 35, 36, 0, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 40, 41, 42, 43, 44, - 45, 46, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 48, 0, 49, 0, 50, 51, 52, 0, 0, 0, 0, 0, 0, 0, 53, 0, 54, 0, 55, 56, 57, - 0, 0, 0, 0, 0, 0, 0, 58, 59, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 62, - 63, 0, 64, 65, 66, 0, 0, 0, 0, 0, 0, 0, 67, 68, 69, 70, 71, 72, 0, 0, 0, - 0, 0, 0, 0, 0, 73, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 76, 77, - 78, 79, 80, 81, 0, 0, 0, 0, 0, 0, 0, 82, 83, 84, 0, 85, 86, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 87, 88, 0, 89, 90, 91, 0, 0, 0, 0, 0, 0, 0, 92, 93, 94, - 95, 96, 97, 98, 0, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 101, 102, 0, 0, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, 106, 107, 0, 108, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 109, 110, 111, 0, 112, 0, 113, 0, 0, 0, 0, 0, 0, 0, 114, 115, 116, - 117, 118, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 0, 0, 121, 0, 122, 0, 0, - 0, 0, 0, 0, 0, 123, 124, 125, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, - 128, 0, 129, 130, 131, 0, 0, 0, 0, 0, 0, 0, 132, 133, 134, 135, 136, 137, - 138, 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 140, 141, 142, 0, 0, 143, 0, 0, 0, 0, 0, 0, 0, 0, 144, 145, 146, 0, 147, - 148, 149, 0, 0, 0, 0, 0, 0, 0, 150, 151, 152, 153, 154, 155, 156, 0, 0, - 0, 0, 0, 0, 0, 157, 0, 158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 159, 0, 160, - 0, 161, 162, 163, 0, 0, 0, 0, 0, 0, 0, 164, 0, 165, 0, 166, 167, 168, 0, - 0, 0, 0, 0, 0, 0, 169, 170, 0, 0, 171, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, - 173, 174, 0, 175, 176, 177, 0, 0, 0, 0, 0, 0, 0, 178, 179, 180, 181, 182, - 183, 0, 0, 0, 0, 0, 0, 0, 0, 184, 185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 186, 187, 188, 189, 190, 191, 192, 0, 0, 0, 0, 0, 0, 0, 193, 194, 195, - 0, 196, 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 199, 0, 200, 201, 202, 0, 0, - 0, 0, 0, 0, 0, 203, 204, 205, 206, 207, 208, 209, 0, 0, 0, 0, 0, 0, 0, - 210, 0, 0, 0, 211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, 213, 214, 0, 215, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217, - 218, 219, 0, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 222, 223, 0, 224, 0, - 225, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, 0, 227, 0, 0, 0, 0, 0, 0, - 228, 0, 229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 233, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 235, 0, 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 238, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 240, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 242, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 243, 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, 247, 0, 248, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, - 253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 0, 255, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 257, 0, - 258, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, 260, 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, 262, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 263, 264, 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 266, 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, 0, 269, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 271, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 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, 275, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 276, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 278, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 281, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 283, 0, 284, 0, 285, 0, 0, 0, 0, 0, 0, 0, 0, 0, 286, 0, 287, 0, - 288, 0, 0, 0, 0, 0, 0, 0, 0, 0, 289, 0, 290, 0, 291, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 292, 0, 293, 0, 294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 295, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 298, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 302, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 305, 306, 0, 307, - 0, 0, 0, 308, 0, 0, 0, 0, 0, 0, 309, 0, 0, 310, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 311, 0, 0, 312, 0, 0, 0, 313, 0, 0, 0, 0, 0, 0, 314, 315, 0, 316, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 317, 0, 0, 318, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 320, 321, 0, 322, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 323, 0, 0, 324, 0, 0, 0, 325, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 327, 0, 0, - 0, 0, 0, 0, 328, 329, 0, 330, 0, 0, 0, 331, 0, 0, 0, 0, 0, 0, 332, 0, 0, - 333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 334, 0, 0, 335, 0, 0, 0, 336, 0, 0, 0, - 0, 0, 0, 337, 338, 0, 339, 0, 0, 0, 340, 0, 0, 0, 0, 0, 0, 341, 0, 0, - 342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 344, 345, 0, 346, 0, 0, 0, 347, 0, 0, 0, 0, 0, 0, 348, 0, 0, 349, - 0, 0, 0, 350, 0, 0, 0, 0, 0, 0, 351, 0, 0, 0, 0, 0, 0, 352, 0, 0, 0, 0, - 0, 0, 353, 0, 0, 0, 0, 0, 0, 354, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 355, 0, 0, 0, 0, 0, 0, 356, 357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 358, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 359, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 361, 362, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 364, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 365, 366, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 367, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 368, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 369, 370, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 371, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 372, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 373, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 374, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 375, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 376, 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, 379, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 380, - 381, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 388, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 389, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 390, - 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, 392, 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, 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, 0, 0, 0, 0, 396, 397, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 398, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 399, - 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 402, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 405, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 406, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 407, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 408, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 409, 410, 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, 412, 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, 415, 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, 418, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 419, 420, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 421, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 422, 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, 424, 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, 426, 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, 428, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 430, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 431, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 432, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 433, 0, - 0, 434, 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, 436, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 437, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 438, 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, 440, 441, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 442, 443, 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, 445, 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, 447, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 448, 0, 0, 0, 0, 0, 0, 449, 0, 0, 0, 0, 0, 0, 450, - 0, 0, 0, 0, 0, 0, 451, 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, 453, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 454, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 455, 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, 457, 0, 0, - 0, 0, 0, 0, 458, 0, 0, 0, 0, 0, 0, 459, 0, 0, 0, 0, 0, 0, 460, 0, 0, 0, - 0, 0, 0, 461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 462, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 463, 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, 465, 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, 467, 0, 0, 0, 0, 0, - 0, 468, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 469, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 470, 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, 472, 0, 0, 0, 0, 0, 0, 473, 0, 0, 0, 0, - 0, 0, 474, 0, 0, 0, 0, 0, 0, 475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 476, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 477, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 479, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 481, 0, 0, 0, 0, 0, 0, 482, 0, 0, 0, 0, 0, 0, 483, 0, 0, 0, 0, 0, 0, 484, - 0, 0, 0, 0, 0, 0, 485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 486, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 488, 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, 490, 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, 493, 0, 0, 0, 0, 0, 0, 494, 0, 0, 0, - 0, 0, 0, 495, 0, 0, 0, 0, 0, 0, 496, 0, 0, 0, 0, 0, 0, 497, 0, 0, 0, 0, - 0, 0, 498, 0, 0, 0, 0, 0, 0, 499, 0, 0, 0, 0, 0, 0, 500, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 502, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 503, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 504, 0, 0, 0, 0, 0, 0, 505, 0, 0, 0, 0, 0, 0, 506, 0, 0, 0, 0, - 0, 0, 507, 0, 0, 0, 0, 0, 0, 508, 0, 0, 0, 0, 0, 0, 509, 0, 0, 0, 0, 0, - 0, 510, 0, 0, 0, 0, 0, 0, 511, 0, 0, 0, 0, 0, 0, 512, 0, 0, 0, 0, 0, 0, - 513, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 514, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 518, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 519, 0, 0, 0, 0, 0, 0, 520, - 0, 0, 0, 0, 0, 0, 521, 0, 0, 0, 0, 0, 0, 522, 0, 0, 0, 0, 0, 0, 523, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 524, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 525, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 526, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 527, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 528, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 531, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 533, 0, - 0, 0, 0, 0, 0, 534, 0, 0, 0, 0, 0, 0, 535, 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, 537, 0, 0, 0, 0, 0, - 0, 538, 0, 0, 0, 0, 0, 0, 539, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 540, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 541, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 542, 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, 544, 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, 546, 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, 548, 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, 550, - 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, 552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 553, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 554, 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, 556, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 558, 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, 560, - 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, 562, 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, 564, 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, 566, 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, 568, 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, 570, - 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, 572, 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, 574, 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, 576, 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, 578, 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, 580, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 581, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 582, 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, 584, 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, 586, 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, - 588, 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, 590, 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, 592, 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, 594, 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, 596, 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, - 598, 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, 600, 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, 602, 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, 604, 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, 606, 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, - 608, 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, 610, 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, 612, 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, 614, 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, 616, 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, - 618, 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, 620, 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, 622, 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, 624, 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, 626, 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, - 628, 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, 630, 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, 632, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 633, + 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 unsigned int comp_data[] = { - 0, 0, 0, 0, 0, 0, 0, 8814, 0, 0, 0, 8800, 0, 0, 0, 8815, 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, 7682, 0, 0, 7684, 0, 0, 0, 0, 7686, 0, 0, 262, - 264, 0, 0, 0, 266, 0, 0, 0, 0, 268, 0, 199, 0, 0, 0, 0, 7690, 0, 0, 0, 0, - 270, 0, 7692, 0, 0, 0, 7696, 0, 7698, 0, 0, 7694, 0, 200, 201, 202, 7868, - 274, 276, 278, 203, 7866, 0, 0, 282, 516, 518, 0, 0, 0, 7864, 0, 0, 0, - 552, 280, 7704, 0, 7706, 0, 0, 0, 0, 7710, 0, 0, 500, 284, 0, 7712, 286, - 288, 0, 0, 0, 0, 486, 0, 290, 0, 0, 0, 0, 292, 0, 0, 0, 7714, 7718, 0, 0, - 0, 542, 0, 7716, 0, 0, 0, 7720, 0, 0, 7722, 0, 0, 0, 204, 205, 206, 296, - 298, 300, 304, 207, 7880, 0, 0, 463, 520, 522, 0, 0, 0, 7882, 0, 0, 0, 0, - 302, 0, 0, 7724, 0, 0, 0, 0, 308, 0, 0, 7728, 0, 0, 0, 0, 0, 488, 0, - 7730, 0, 0, 0, 310, 0, 0, 0, 0, 7732, 0, 0, 313, 0, 0, 0, 0, 0, 317, 0, - 7734, 0, 0, 0, 315, 0, 7740, 0, 0, 7738, 0, 0, 7742, 0, 0, 0, 0, 7744, 0, - 0, 7746, 0, 0, 504, 323, 0, 209, 0, 0, 7748, 0, 0, 0, 0, 327, 0, 7750, 0, - 0, 0, 325, 0, 7754, 0, 0, 7752, 0, 210, 211, 212, 213, 332, 334, 558, - 214, 7886, 0, 336, 465, 524, 526, 0, 0, 416, 7884, 0, 0, 0, 0, 490, 0, 0, - 7764, 0, 0, 0, 0, 7766, 0, 0, 340, 0, 0, 0, 0, 7768, 0, 0, 0, 0, 344, - 528, 530, 0, 0, 0, 7770, 0, 0, 0, 342, 0, 0, 0, 0, 7774, 0, 0, 346, 348, - 0, 0, 0, 7776, 0, 0, 0, 0, 352, 0, 7778, 0, 0, 536, 350, 0, 0, 0, 0, - 7786, 0, 0, 0, 0, 356, 0, 7788, 0, 0, 538, 354, 0, 7792, 0, 0, 7790, 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, 0, 0, 7804, 0, - 7806, 0, 0, 7808, 7810, 372, 0, 0, 0, 7814, 7812, 0, 7816, 0, 0, 0, 0, - 7818, 7820, 7922, 221, 374, 7928, 562, 0, 7822, 376, 7926, 0, 0, 0, 0, - 7924, 0, 0, 0, 377, 7824, 0, 0, 0, 379, 0, 0, 0, 0, 381, 0, 7826, 0, 0, - 0, 0, 7828, 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, 0, 0, 7683, 0, 0, 7685, - 0, 0, 0, 0, 7687, 0, 0, 263, 265, 0, 0, 0, 267, 0, 0, 0, 0, 269, 0, 231, - 0, 0, 0, 0, 7691, 0, 0, 0, 0, 271, 0, 7693, 0, 0, 0, 7697, 0, 7699, 0, 0, - 7695, 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, 0, 0, 7711, - 0, 0, 501, 285, 0, 7713, 287, 289, 0, 0, 0, 0, 487, 0, 291, 0, 0, 0, 0, - 293, 0, 0, 0, 7715, 7719, 0, 0, 0, 543, 0, 7717, 0, 0, 0, 7721, 0, 0, - 7723, 0, 7830, 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, 0, 0, 309, 0, - 0, 0, 0, 496, 0, 7729, 0, 0, 0, 0, 0, 489, 0, 7731, 0, 0, 0, 311, 0, 0, - 0, 0, 7733, 0, 0, 314, 0, 0, 0, 0, 0, 318, 0, 7735, 0, 0, 0, 316, 0, - 7741, 0, 0, 7739, 0, 0, 7743, 0, 0, 0, 0, 7745, 0, 0, 7747, 0, 0, 505, - 324, 0, 241, 0, 0, 7749, 0, 0, 0, 0, 328, 0, 7751, 0, 0, 0, 326, 0, 7755, - 0, 0, 7753, 0, 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, 7765, 0, 0, 0, 0, 7767, - 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, 347, 349, 0, 0, 0, 7777, 0, 0, 0, 0, - 353, 0, 7779, 0, 0, 537, 351, 0, 0, 0, 0, 7787, 7831, 0, 0, 0, 357, 0, - 7789, 0, 0, 539, 355, 0, 7793, 0, 0, 7791, 0, 249, 250, 251, 361, 363, - 365, 0, 252, 7911, 367, 369, 468, 533, 535, 0, 0, 432, 7909, 7795, 0, 0, - 0, 371, 7799, 0, 7797, 0, 0, 0, 0, 0, 7805, 0, 7807, 0, 0, 7809, 7811, - 373, 0, 0, 0, 7815, 7813, 0, 7832, 0, 0, 0, 7817, 0, 0, 0, 0, 7819, 7821, - 7923, 253, 375, 7929, 563, 0, 7823, 255, 7927, 7833, 0, 0, 0, 7925, 0, 0, - 0, 378, 7825, 0, 0, 0, 380, 0, 0, 0, 0, 382, 0, 7827, 0, 0, 0, 0, 7829, - 0, 8173, 901, 0, 0, 8129, 0, 0, 0, 7846, 7844, 0, 7850, 7848, 0, 0, 0, - 478, 0, 0, 0, 0, 506, 0, 0, 0, 508, 0, 0, 482, 0, 0, 0, 0, 7688, 0, 0, - 7872, 7870, 0, 7876, 7874, 0, 0, 0, 0, 7726, 0, 0, 7890, 7888, 0, 7894, - 7892, 0, 0, 0, 0, 7756, 0, 0, 556, 0, 0, 7758, 554, 0, 0, 0, 0, 510, 0, - 0, 475, 471, 0, 0, 469, 0, 0, 0, 0, 0, 0, 473, 7847, 7845, 0, 7851, 7849, - 0, 0, 0, 479, 0, 0, 0, 0, 507, 0, 0, 0, 509, 0, 0, 483, 0, 0, 0, 0, 7689, - 0, 0, 7873, 7871, 0, 7877, 7875, 0, 0, 0, 0, 7727, 0, 0, 7891, 7889, 0, - 7895, 7893, 0, 0, 0, 0, 7757, 0, 0, 557, 0, 0, 7759, 555, 0, 0, 0, 0, - 511, 0, 0, 476, 472, 0, 0, 470, 0, 0, 0, 0, 0, 0, 474, 7856, 7854, 0, - 7860, 7858, 0, 0, 0, 7857, 7855, 0, 7861, 7859, 0, 0, 0, 7700, 7702, 0, - 0, 7701, 7703, 0, 0, 7760, 7762, 0, 0, 7761, 7763, 0, 0, 0, 0, 7780, 0, - 0, 0, 7781, 0, 0, 0, 7782, 0, 0, 0, 7783, 0, 0, 7800, 0, 0, 0, 7801, 0, - 0, 0, 0, 0, 7802, 0, 0, 0, 7803, 0, 0, 7835, 0, 7900, 7898, 0, 7904, - 7902, 0, 0, 0, 0, 7906, 0, 0, 7901, 7899, 0, 7905, 7903, 0, 0, 0, 0, - 7907, 0, 0, 7914, 7912, 0, 7918, 7916, 0, 0, 0, 0, 7920, 0, 0, 7915, - 7913, 0, 7919, 7917, 0, 0, 0, 0, 7921, 0, 0, 0, 0, 0, 494, 492, 0, 0, 0, - 493, 0, 0, 0, 480, 0, 0, 0, 481, 0, 0, 0, 0, 7708, 0, 0, 0, 7709, 0, 0, - 560, 0, 0, 0, 561, 0, 0, 0, 0, 0, 0, 495, 8122, 902, 0, 0, 8121, 8120, 0, - 0, 0, 0, 7944, 7945, 0, 8124, 0, 0, 8136, 904, 0, 0, 0, 0, 7960, 7961, - 8138, 905, 0, 0, 0, 0, 7976, 7977, 0, 8140, 0, 0, 8154, 906, 0, 0, 8153, - 8152, 0, 938, 0, 0, 7992, 7993, 8184, 908, 0, 0, 0, 0, 8008, 8009, 0, 0, - 0, 8172, 8170, 910, 0, 0, 8169, 8168, 0, 939, 0, 0, 0, 8025, 8186, 911, - 0, 0, 0, 0, 8040, 8041, 0, 8188, 0, 0, 0, 8116, 0, 0, 0, 8132, 0, 0, - 8048, 940, 0, 0, 8113, 8112, 0, 0, 0, 0, 7936, 7937, 8118, 8115, 0, 0, - 8050, 941, 0, 0, 0, 0, 7952, 7953, 8052, 942, 0, 0, 0, 0, 7968, 7969, - 8134, 8131, 0, 0, 8054, 943, 0, 0, 8145, 8144, 0, 970, 0, 0, 7984, 7985, - 8150, 0, 0, 0, 8056, 972, 0, 0, 0, 0, 8000, 8001, 0, 0, 8164, 8165, 8058, - 973, 0, 0, 8161, 8160, 0, 971, 0, 0, 8016, 8017, 8166, 0, 0, 0, 8060, - 974, 0, 0, 0, 0, 8032, 8033, 8182, 8179, 0, 0, 8146, 912, 0, 0, 8151, 0, - 0, 0, 8162, 944, 0, 0, 8167, 0, 0, 0, 0, 8180, 0, 0, 0, 979, 0, 0, 0, 0, - 0, 980, 0, 0, 0, 1031, 0, 1232, 0, 1234, 0, 1027, 0, 0, 1024, 0, 0, 0, 0, - 1238, 0, 1025, 0, 1217, 0, 1244, 0, 0, 0, 1246, 1037, 0, 0, 0, 1250, - 1049, 0, 1252, 0, 1036, 0, 0, 0, 0, 0, 1254, 1262, 1038, 0, 1264, 0, 0, - 1266, 0, 0, 0, 0, 1268, 0, 0, 0, 1272, 0, 0, 0, 1260, 0, 1233, 0, 1235, - 0, 1107, 0, 0, 1104, 0, 0, 0, 0, 1239, 0, 1105, 0, 1218, 0, 1245, 0, 0, - 0, 1247, 1117, 0, 0, 0, 1251, 1081, 0, 1253, 0, 1116, 0, 0, 0, 0, 0, - 1255, 1263, 1118, 0, 1265, 0, 0, 1267, 0, 0, 0, 0, 1269, 0, 0, 0, 1273, - 0, 0, 0, 1261, 0, 0, 0, 1111, 1142, 0, 0, 0, 1143, 0, 0, 0, 0, 0, 0, - 1242, 0, 0, 0, 1243, 0, 0, 0, 1258, 0, 0, 0, 1259, 0, 0, 1570, 1571, - 1573, 0, 0, 0, 0, 0, 0, 1572, 0, 0, 0, 1574, 0, 0, 0, 1730, 0, 0, 0, - 1747, 0, 0, 0, 1728, 0, 2345, 0, 0, 0, 2353, 0, 0, 0, 2356, 0, 0, 0, 0, - 2507, 2508, 2891, 2888, 2892, 0, 2964, 0, 0, 0, 0, 0, 0, 3018, 3020, 0, - 0, 0, 0, 0, 0, 3019, 0, 3144, 0, 0, 0, 0, 0, 3264, 0, 0, 3274, 3271, - 3272, 0, 0, 0, 0, 0, 0, 3275, 0, 3402, 3404, 0, 0, 3403, 0, 0, 0, 0, 0, - 3546, 3548, 3550, 0, 0, 0, 0, 0, 3549, 0, 0, 4134, 0, 0, 0, 0, 6918, 0, - 0, 0, 6920, 0, 0, 0, 6922, 0, 0, 0, 6924, 0, 0, 0, 6926, 0, 0, 0, 6930, - 0, 0, 0, 6971, 0, 0, 0, 6973, 0, 0, 0, 6976, 0, 0, 0, 6977, 0, 0, 0, - 6979, 7736, 0, 0, 0, 7737, 0, 0, 0, 7772, 0, 0, 0, 7773, 0, 0, 0, 0, 0, - 7784, 0, 0, 0, 7785, 0, 0, 0, 7852, 0, 0, 7862, 0, 0, 0, 0, 7853, 0, 0, - 7863, 0, 0, 0, 0, 7878, 0, 0, 0, 7879, 0, 0, 0, 7896, 0, 0, 0, 7897, 0, - 7938, 7940, 0, 0, 7942, 8064, 0, 0, 7939, 7941, 0, 0, 7943, 8065, 0, 0, - 0, 8066, 0, 0, 0, 8067, 0, 0, 0, 8068, 0, 0, 0, 8069, 0, 0, 0, 8070, 0, - 0, 0, 8071, 0, 0, 7946, 7948, 0, 0, 7950, 8072, 0, 0, 7947, 7949, 0, 0, - 7951, 8073, 0, 0, 0, 8074, 0, 0, 0, 8075, 0, 0, 0, 8076, 0, 0, 0, 8077, - 0, 0, 0, 8078, 0, 0, 0, 8079, 0, 0, 7954, 7956, 0, 0, 7955, 7957, 0, 0, - 7962, 7964, 0, 0, 7963, 7965, 0, 0, 7970, 7972, 0, 0, 7974, 8080, 0, 0, - 7971, 7973, 0, 0, 7975, 8081, 0, 0, 0, 8082, 0, 0, 0, 8083, 0, 0, 0, - 8084, 0, 0, 0, 8085, 0, 0, 0, 8086, 0, 0, 0, 8087, 0, 0, 7978, 7980, 0, - 0, 7982, 8088, 0, 0, 7979, 7981, 0, 0, 7983, 8089, 0, 0, 0, 8090, 0, 0, - 0, 8091, 0, 0, 0, 8092, 0, 0, 0, 8093, 0, 0, 0, 8094, 0, 0, 0, 8095, 0, - 0, 7986, 7988, 0, 0, 7990, 0, 0, 0, 7987, 7989, 0, 0, 7991, 0, 0, 0, - 7994, 7996, 0, 0, 7998, 0, 0, 0, 7995, 7997, 0, 0, 7999, 0, 0, 0, 8002, - 8004, 0, 0, 8003, 8005, 0, 0, 8010, 8012, 0, 0, 8011, 8013, 0, 0, 8018, - 8020, 0, 0, 8022, 0, 0, 0, 8019, 8021, 0, 0, 8023, 0, 0, 0, 8027, 8029, - 0, 0, 8031, 0, 0, 0, 8034, 8036, 0, 0, 8038, 8096, 0, 0, 8035, 8037, 0, - 0, 8039, 8097, 0, 0, 0, 8098, 0, 0, 0, 8099, 0, 0, 0, 8100, 0, 0, 0, - 8101, 0, 0, 0, 8102, 0, 0, 0, 8103, 0, 0, 8042, 8044, 0, 0, 8046, 8104, - 0, 0, 8043, 8045, 0, 0, 8047, 8105, 0, 0, 0, 8106, 0, 0, 0, 8107, 0, 0, - 0, 8108, 0, 0, 0, 8109, 0, 0, 0, 8110, 0, 0, 0, 8111, 0, 0, 0, 8114, 0, - 0, 0, 8130, 0, 0, 0, 8178, 0, 0, 0, 8119, 0, 0, 8141, 8142, 0, 0, 8143, - 0, 0, 0, 0, 8135, 0, 0, 0, 8183, 0, 0, 8157, 8158, 0, 0, 8159, 0, 0, 0, - 0, 0, 0, 8602, 0, 0, 0, 8603, 0, 0, 0, 8622, 0, 0, 0, 8653, 0, 0, 0, - 8655, 0, 0, 0, 8654, 0, 0, 0, 8708, 0, 0, 0, 8713, 0, 0, 0, 8716, 0, 0, - 0, 8740, 0, 0, 0, 8742, 0, 0, 0, 8769, 0, 0, 0, 8772, 0, 0, 0, 8775, 0, - 0, 0, 8777, 0, 0, 0, 8813, 0, 0, 0, 8802, 0, 0, 0, 8816, 0, 0, 0, 8817, - 0, 0, 0, 8820, 0, 0, 0, 8821, 0, 0, 0, 8824, 0, 0, 0, 8825, 0, 0, 0, - 8832, 0, 0, 0, 8833, 0, 0, 0, 8928, 0, 0, 0, 8929, 0, 0, 0, 8836, 0, 0, - 0, 8837, 0, 0, 0, 8840, 0, 0, 0, 8841, 0, 0, 0, 8930, 0, 0, 0, 8931, 0, - 0, 0, 8876, 0, 0, 0, 8877, 0, 0, 0, 8878, 0, 0, 0, 8879, 0, 0, 0, 8938, - 0, 0, 0, 8939, 0, 0, 0, 8940, 0, 0, 0, 8941, 12436, 0, 0, 0, 12364, 0, 0, - 0, 12366, 0, 0, 0, 12368, 0, 0, 0, 12370, 0, 0, 0, 12372, 0, 0, 0, 12374, - 0, 0, 0, 12376, 0, 0, 0, 12378, 0, 0, 0, 12380, 0, 0, 0, 12382, 0, 0, 0, - 12384, 0, 0, 0, 12386, 0, 0, 0, 12389, 0, 0, 0, 12391, 0, 0, 0, 12393, 0, - 0, 0, 12400, 12401, 0, 0, 12403, 12404, 0, 0, 12406, 12407, 0, 0, 12409, - 12410, 0, 0, 12412, 12413, 0, 0, 12446, 0, 0, 0, 12532, 0, 0, 0, 12460, - 0, 0, 0, 12462, 0, 0, 0, 12464, 0, 0, 0, 12466, 0, 0, 0, 12468, 0, 0, 0, - 12470, 0, 0, 0, 12472, 0, 0, 0, 12474, 0, 0, 0, 12476, 0, 0, 0, 12478, 0, - 0, 0, 12480, 0, 0, 0, 12482, 0, 0, 0, 12485, 0, 0, 0, 12487, 0, 0, 0, - 12489, 0, 0, 0, 12496, 12497, 0, 0, 12499, 12500, 0, 0, 12502, 12503, 0, - 0, 12505, 12506, 0, 0, 12508, 12509, 0, 0, 12535, 0, 0, 0, 12536, 0, 0, - 0, 12537, 0, 0, 0, 12538, 0, 0, 0, 12542, 0, 0, 0, 0, 0, 69786, 0, 0, 0, - 69788, 0, 0, 0, 69803, 0, 0, 0, 0, 69934, 0, 0, 0, 69935, + 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[] = { @@ -5183,6 +5696,7 @@ static const change_record change_records_3_2_0[] = { { 255, 7, 7, 255, 0 }, { 255, 7, 8, 255, 0 }, { 255, 7, 9, 255, 0 }, + { 255, 19, 255, 255, 0 }, { 1, 5, 255, 255, 0 }, { 255, 10, 255, 255, 0 }, { 18, 255, 255, 255, 0 }, @@ -5204,79 +5718,80 @@ static const change_record change_records_3_2_0[] = { { 255, 20, 255, 255, 0 }, { 255, 255, 255, 255, 1e+16 }, { 255, 255, 255, 255, 1e+20 }, - { 255, 19, 255, 255, 0 }, { 255, 19, 255, 255, -1 }, { 1, 255, 255, 0, 0 }, }; static 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, 2, 2, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 2, 2, 2, 37, 38, 2, 39, 2, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 2, 51, 2, 2, 52, 53, 54, 55, 56, 2, 57, 58, 59, 60, 2, 2, 61, 62, 63, - 64, 65, 65, 2, 2, 2, 2, 66, 2, 67, 68, 69, 70, 71, 2, 2, 2, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 2, 2, 2, 2, 2, 2, 82, 2, 2, 2, 2, 2, 83, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 84, 2, 85, 2, 2, 2, 2, 2, 2, 2, 2, 86, - 87, 2, 2, 2, 2, 2, 2, 2, 88, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 89, 90, + 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, 2, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 2, 52, 2, 2, 53, 54, 55, 56, 57, 2, 58, 59, 60, 61, 2, 2, 62, 63, + 64, 65, 66, 66, 2, 2, 2, 2, 67, 68, 69, 70, 71, 72, 73, 2, 2, 2, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 2, 2, 2, 2, 2, 2, 84, 2, 2, 2, 2, 2, 85, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 91, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 86, 2, 87, 2, 2, 2, 2, 2, 2, 2, 2, + 88, 89, 2, 2, 2, 2, 2, 2, 2, 90, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 91, + 92, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 92, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 94, 95, 2, 2, 2, 2, 2, 2, 2, 2, 96, 49, 49, - 97, 98, 49, 99, 100, 101, 102, 103, 104, 105, 106, 107, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 94, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 95, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 96, 97, 2, 2, 2, 2, 2, 2, 2, 2, 98, 50, 50, + 99, 100, 50, 101, 102, 103, 104, 105, 106, 107, 108, 109, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 108, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 110, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 109, 110, 111, 112, 113, 114, 2, 2, 2, 115, 116, 2, 117, 118, - 119, 120, 121, 122, 2, 123, 124, 125, 126, 127, 2, 2, 2, 2, 2, 2, 128, 2, - 129, 130, 131, 2, 132, 2, 133, 2, 2, 2, 134, 2, 2, 2, 135, 136, 137, 138, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 139, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 49, 49, 49, 49, 49, 49, 140, 2, 141, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 49, 49, 49, 49, 49, 49, 49, - 49, 142, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 111, 112, 113, 114, 115, 116, 2, 2, 117, 118, 119, 2, 120, + 121, 122, 123, 124, 125, 2, 126, 127, 128, 129, 130, 131, 2, 50, 50, 132, + 2, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 2, 2, 143, 2, 2, 2, + 144, 145, 146, 147, 148, 149, 150, 2, 2, 151, 2, 152, 153, 154, 155, 2, + 2, 156, 2, 2, 2, 157, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 50, 50, 50, 50, + 50, 50, 158, 159, 50, 160, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 50, 50, 50, 50, 50, 50, 50, 50, 161, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 50, 50, 50, 50, 162, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 49, 49, 49, 49, 143, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 144, 145, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 50, 50, 50, 50, 163, 164, 165, 166, 2, 2, 2, 2, 2, 2, 167, 168, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 146, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 169, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 170, 171, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 147, 2, 148, 2, 149, 2, 2, 150, 2, 2, 2, 151, 152, - 153, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 154, 155, - 2, 2, 156, 157, 158, 159, 160, 2, 161, 162, 163, 164, 165, 166, 167, 148, - 168, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 169, 170, 93, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 82, 171, 2, 172, 173, 2, 2, 2, + 2, 2, 2, 172, 173, 174, 2, 175, 2, 2, 176, 2, 2, 2, 177, 178, 179, 50, + 50, 50, 50, 50, 180, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 181, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 182, + 183, 2, 2, 184, 185, 186, 187, 188, 2, 50, 50, 50, 50, 189, 190, 50, 191, + 192, 193, 194, 195, 196, 197, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 198, + 199, 95, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 84, 200, 2, 201, + 202, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 174, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 175, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 176, 2, 2, 2, + 2, 203, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 204, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 205, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 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, 206, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 178, 49, 179, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 207, 50, 208, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 209, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 203, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 174, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -5511,7 +6026,7 @@ static unsigned char changes_3_2_0_index[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 49, 180, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 50, 210, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -5575,7 +6090,7 @@ static unsigned char changes_3_2_0_index[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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 unsigned char changes_3_2_0_data[] = { @@ -5611,7 +6126,7 @@ static 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, 9, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, @@ -5623,16 +6138,16 @@ static 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 0, 0, 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, 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, @@ -5660,16 +6175,16 @@ static unsigned char changes_3_2_0_data[] = { 9, 9, 9, 9, 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, 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, 9, 9, 9, 9, 9, 9, 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, 9, 9, 9, 9, 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, 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, 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, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, @@ -5685,7 +6200,7 @@ static unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 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, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, @@ -5696,83 +6211,88 @@ static unsigned char changes_3_2_0_data[] = { 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 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, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 9, 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, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, + 0, 0, 0, 9, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 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, 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, 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, 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, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 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, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, - 9, 9, 9, 9, 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, 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, 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, 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, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 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, 9, 0, 0, 0, 0, 0, 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, 22, 23, 24, 25, 26, 27, 28, 29, 30, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 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, @@ -5781,66 +6301,68 @@ static unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 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, 31, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 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, 9, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 9, 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, 0, 0, 0, 0, 9, 0, 0, 0, 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, 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, 0, 0, 0, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 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, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 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, 9, 9, 9, 9, 9, 9, 9, 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, 9, 9, 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, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, + 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -5850,125 +6372,129 @@ static unsigned char changes_3_2_0_data[] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 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, 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, 35, 4, 0, 0, 36, 37, 38, 39, 40, 41, 1, 1, 0, 0, 0, - 4, 35, 8, 6, 7, 36, 37, 38, 39, 40, 41, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 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, + 35, 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, 36, 4, 0, 0, + 37, 38, 39, 40, 41, 42, 1, 1, 0, 0, 0, 4, 36, 8, 6, 7, 37, 38, 39, 40, + 41, 42, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 42, 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, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 9, - 9, 9, 9, 9, 9, 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, 43, 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, 44, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 44, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 45, 45, 45, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 46, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 47, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, + 48, 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, 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, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 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, 0, 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, + 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, 9, 9, 9, 0, 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, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 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, 0, 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, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 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, 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, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 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, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5976,83 +6502,83 @@ static unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 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, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 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, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 0, 0, 0, 0, 19, + 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, 19, 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, 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, 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, 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, - 50, 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, 19, 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, 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, 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, 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, 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, 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, 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, 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, @@ -6061,35 +6587,36 @@ static unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 0, 0, 0, 0, 19, 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, 19, 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, 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, 0, 0, 0, 0, 0, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6097,303 +6624,426 @@ static unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 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, 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, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 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, - 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, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 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, 9, 9, 9, 9, 9, 9, 9, 9, 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, 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, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 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, 9, 9, 9, 0, 9, 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, 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, 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, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 19, 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, 0, 0, 0, 0, 0, 9, 9, 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, 0, 0, 0, 0, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 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, 9, 9, 9, 9, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 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, 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, 46, 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, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 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, 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, 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, + 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 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, 0, 0, 0, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, 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, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 9, 9, 9, 9, 9, 9, 9, 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, 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, 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, - 53, 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, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 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, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 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, + 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, 9, 9, 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, 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, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 0, + 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, 0, 0, 0, 0, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 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, 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, 0, + 0, 0, 0, 9, 9, 9, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 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, 9, 9, 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, 0, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 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, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 0, 0, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 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, 9, 9, 9, 9, 9, + 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, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, + 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, + 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, - 0, 0, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, + 9, 9, 9, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 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, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 9, 9, 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, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 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, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 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, 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, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -6401,101 +7051,122 @@ static unsigned char changes_3_2_0_data[] = { 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 0, 0, 0, 0, 0, 0, 0, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 9, 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, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 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, 0, 9, 9, 9, 9, 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, 0, 0, 0, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 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, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 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, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 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, + 9, 9, 9, 9, 9, 9, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 9, - 9, 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, 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, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, 0, 0, 0, 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, 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, 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, 9, 9, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 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, 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, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 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, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 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, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 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, 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, 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, @@ -6503,25 +7174,25 @@ static unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 19, 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, 19, 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, @@ -6530,24 +7201,29 @@ static unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 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, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 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, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 9, - 9, 9, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 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, }; static const change_record* get_change_3_2_0(Py_UCS4 n) diff --git a/Modules/unicodename_db.h b/Modules/unicodename_db.h index 7ccb1261f5fc..d0f9cb4dbc33 100644 --- a/Modules/unicodename_db.h +++ b/Modules/unicodename_db.h @@ -4,249 +4,265 @@ /* lexicon */ static unsigned char lexicon[] = { - 76, 69, 84, 84, 69, 210, 87, 73, 84, 200, 83, 89, 76, 76, 65, 66, 76, - 197, 83, 77, 65, 76, 204, 83, 73, 71, 206, 67, 65, 80, 73, 84, 65, 204, - 76, 65, 84, 73, 206, 89, 201, 65, 82, 65, 66, 73, 195, 67, 74, 203, 77, - 65, 84, 72, 69, 77, 65, 84, 73, 67, 65, 204, 69, 71, 89, 80, 84, 73, 65, - 206, 72, 73, 69, 82, 79, 71, 76, 89, 80, 200, 67, 79, 77, 80, 65, 84, 73, - 66, 73, 76, 73, 84, 217, 67, 85, 78, 69, 73, 70, 79, 82, 205, 83, 89, 77, - 66, 79, 204, 70, 79, 82, 77, 128, 67, 65, 78, 65, 68, 73, 65, 206, 83, - 89, 76, 76, 65, 66, 73, 67, 211, 66, 65, 77, 85, 205, 68, 73, 71, 73, - 212, 65, 78, 196, 66, 79, 76, 196, 72, 65, 78, 71, 85, 204, 86, 79, 87, - 69, 204, 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, 84, 73, 77, 69, - 211, 70, 79, 210, 73, 84, 65, 76, 73, 195, 67, 89, 82, 73, 76, 76, 73, - 195, 82, 65, 68, 73, 67, 65, 204, 83, 65, 78, 83, 45, 83, 69, 82, 73, - 198, 84, 65, 77, 73, 204, 67, 73, 82, 67, 76, 69, 196, 67, 79, 77, 66, - 73, 78, 73, 78, 199, 84, 65, 201, 70, 73, 78, 65, 204, 86, 65, 201, 83, - 81, 85, 65, 82, 197, 76, 69, 70, 212, 82, 73, 71, 72, 212, 86, 65, 82, - 73, 65, 84, 73, 79, 206, 66, 82, 65, 73, 76, 76, 197, 80, 65, 84, 84, 69, - 82, 206, 65, 66, 79, 86, 69, 128, 66, 89, 90, 65, 78, 84, 73, 78, 197, - 83, 73, 71, 78, 128, 66, 69, 76, 79, 87, 128, 68, 79, 85, 66, 76, 197, - 73, 83, 79, 76, 65, 84, 69, 196, 78, 85, 77, 66, 69, 210, 75, 65, 84, 65, - 75, 65, 78, 193, 194, 77, 79, 68, 73, 70, 73, 69, 210, 68, 79, 212, 75, - 65, 78, 71, 88, 201, 65, 128, 76, 73, 78, 69, 65, 210, 84, 73, 66, 69, - 84, 65, 206, 79, 198, 73, 78, 73, 84, 73, 65, 204, 77, 69, 69, 205, 86, - 69, 82, 84, 73, 67, 65, 204, 77, 89, 65, 78, 77, 65, 210, 85, 128, 75, - 72, 77, 69, 210, 87, 72, 73, 84, 197, 65, 66, 79, 86, 197, 67, 65, 82, - 82, 73, 69, 210, 73, 128, 65, 82, 82, 79, 87, 128, 89, 69, 200, 79, 128, - 77, 65, 82, 75, 128, 65, 82, 82, 79, 215, 67, 79, 80, 84, 73, 195, 80, - 72, 65, 83, 69, 45, 197, 77, 79, 78, 71, 79, 76, 73, 65, 206, 68, 69, 86, - 65, 78, 65, 71, 65, 82, 201, 66, 76, 65, 67, 203, 84, 73, 76, 197, 83, - 89, 77, 66, 79, 76, 128, 80, 65, 82, 69, 78, 84, 72, 69, 83, 73, 90, 69, - 196, 84, 72, 65, 205, 74, 79, 78, 71, 83, 69, 79, 78, 199, 83, 84, 82, - 79, 75, 69, 128, 83, 81, 85, 65, 82, 69, 196, 66, 79, 216, 72, 69, 66, - 82, 69, 215, 77, 73, 65, 207, 80, 76, 85, 211, 82, 73, 71, 72, 84, 87, - 65, 82, 68, 211, 71, 69, 79, 82, 71, 73, 65, 206, 68, 82, 65, 87, 73, 78, - 71, 211, 67, 72, 79, 83, 69, 79, 78, 199, 72, 65, 76, 70, 87, 73, 68, 84, - 200, 66, 65, 76, 73, 78, 69, 83, 197, 72, 79, 79, 75, 128, 213, 84, 87, - 79, 128, 73, 68, 69, 79, 71, 82, 65, 205, 80, 72, 65, 83, 69, 45, 196, - 65, 76, 67, 72, 69, 77, 73, 67, 65, 204, 65, 76, 69, 198, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 73, 195, 79, 78, 69, 128, 84, 79, 128, 84, 87, 207, - 72, 69, 65, 86, 217, 79, 86, 69, 210, 67, 79, 78, 83, 79, 78, 65, 78, - 212, 66, 82, 65, 72, 77, 201, 83, 67, 82, 73, 80, 212, 85, 208, 76, 79, - 215, 72, 65, 200, 79, 78, 197, 68, 79, 87, 206, 72, 73, 71, 200, 70, 85, - 76, 76, 87, 73, 68, 84, 200, 66, 82, 65, 67, 75, 69, 84, 128, 69, 81, 85, - 65, 204, 84, 65, 199, 66, 65, 82, 128, 68, 79, 77, 73, 78, 207, 78, 85, - 77, 69, 82, 73, 195, 70, 82, 65, 75, 84, 85, 210, 84, 72, 82, 69, 197, - 67, 72, 65, 82, 65, 67, 84, 69, 210, 77, 65, 76, 65, 89, 65, 76, 65, 205, - 80, 72, 65, 83, 69, 45, 195, 84, 79, 78, 197, 68, 79, 85, 66, 76, 69, 45, - 83, 84, 82, 85, 67, 203, 76, 69, 70, 84, 87, 65, 82, 68, 211, 72, 73, 82, - 65, 71, 65, 78, 193, 65, 67, 85, 84, 69, 128, 74, 85, 78, 71, 83, 69, 79, - 78, 199, 71, 76, 65, 71, 79, 76, 73, 84, 73, 195, 66, 69, 78, 71, 65, 76, - 201, 77, 69, 68, 73, 65, 204, 84, 69, 76, 85, 71, 213, 86, 79, 67, 65, - 76, 73, 195, 65, 82, 77, 69, 78, 73, 65, 206, 74, 69, 69, 205, 78, 69, - 71, 65, 84, 73, 86, 197, 73, 68, 69, 79, 71, 82, 65, 80, 200, 74, 65, 86, - 65, 78, 69, 83, 197, 79, 82, 73, 89, 193, 84, 72, 82, 69, 69, 128, 87, - 69, 83, 84, 45, 67, 82, 69, 197, 70, 79, 85, 82, 128, 72, 65, 128, 72, - 65, 76, 198, 77, 65, 82, 203, 75, 65, 78, 78, 65, 68, 193, 78, 69, 215, - 80, 72, 65, 83, 69, 45, 193, 84, 72, 65, 201, 67, 72, 69, 82, 79, 75, 69, - 197, 68, 79, 84, 211, 71, 85, 74, 65, 82, 65, 84, 201, 67, 72, 65, 205, - 76, 85, 197, 83, 72, 65, 82, 65, 68, 193, 83, 73, 78, 72, 65, 76, 193, - 75, 65, 128, 82, 85, 78, 73, 195, 83, 65, 85, 82, 65, 83, 72, 84, 82, - 193, 84, 69, 84, 82, 65, 71, 82, 65, 205, 68, 69, 83, 69, 82, 69, 212, - 72, 65, 77, 90, 193, 83, 89, 82, 73, 65, 195, 84, 73, 76, 68, 69, 128, - 71, 85, 82, 77, 85, 75, 72, 201, 77, 65, 128, 77, 65, 89, 69, 203, 77, - 69, 69, 84, 69, 201, 78, 79, 84, 65, 84, 73, 79, 206, 70, 73, 86, 69, - 128, 80, 65, 128, 89, 65, 128, 76, 73, 71, 72, 212, 83, 73, 88, 128, 69, - 73, 71, 72, 84, 128, 76, 69, 80, 67, 72, 193, 78, 65, 128, 83, 69, 86, - 69, 78, 128, 76, 79, 78, 199, 78, 73, 78, 69, 128, 84, 85, 82, 75, 73, - 195, 72, 79, 82, 73, 90, 79, 78, 84, 65, 204, 79, 80, 69, 206, 82, 65, - 128, 83, 65, 128, 83, 85, 78, 68, 65, 78, 69, 83, 197, 86, 73, 69, 212, - 76, 65, 207, 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, 65, 82, + 76, 69, 84, 84, 69, 210, 83, 73, 71, 206, 87, 73, 84, 200, 83, 89, 76, + 76, 65, 66, 76, 197, 83, 77, 65, 76, 204, 67, 65, 80, 73, 84, 65, 204, + 72, 73, 69, 82, 79, 71, 76, 89, 80, 200, 76, 65, 84, 73, 206, 67, 85, 78, + 69, 73, 70, 79, 82, 205, 65, 82, 65, 66, 73, 195, 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, 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, 86, 79, 87, 69, 204, 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, 71, 82, + 69, 69, 203, 77, 85, 83, 73, 67, 65, 204, 76, 73, 71, 65, 84, 85, 82, + 197, 69, 84, 72, 73, 79, 80, 73, 195, 193, 70, 79, 210, 67, 89, 82, 73, + 76, 76, 73, 195, 73, 84, 65, 76, 73, 195, 67, 79, 77, 66, 73, 78, 73, 78, + 199, 82, 65, 68, 73, 67, 65, 204, 83, 65, 78, 83, 45, 83, 69, 82, 73, + 198, 78, 85, 77, 66, 69, 210, 67, 73, 82, 67, 76, 69, 196, 84, 65, 77, + 73, 204, 84, 65, 201, 70, 73, 78, 65, 204, 65, 82, 82, 79, 87, 128, 86, + 65, 201, 76, 69, 70, 212, 82, 73, 71, 72, 212, 83, 81, 85, 65, 82, 197, + 68, 79, 85, 66, 76, 197, 65, 82, 82, 79, 215, 83, 73, 71, 78, 128, 65, + 66, 79, 86, 69, 128, 66, 69, 76, 79, 87, 128, 86, 65, 82, 73, 65, 84, 73, + 79, 206, 66, 82, 65, 73, 76, 76, 197, 80, 65, 84, 84, 69, 82, 206, 66, + 89, 90, 65, 78, 84, 73, 78, 197, 87, 72, 73, 84, 197, 66, 76, 65, 67, + 203, 65, 128, 73, 83, 79, 76, 65, 84, 69, 196, 77, 79, 68, 73, 70, 73, + 69, 210, 194, 75, 65, 84, 65, 75, 65, 78, 193, 85, 128, 77, 89, 65, 78, + 77, 65, 210, 68, 79, 212, 75, 65, 78, 71, 88, 201, 75, 73, 75, 65, 75, + 85, 201, 77, 69, 78, 68, 197, 73, 128, 79, 198, 84, 73, 66, 69, 84, 65, + 206, 79, 128, 72, 69, 65, 86, 217, 86, 69, 82, 84, 73, 67, 65, 204, 73, + 78, 73, 84, 73, 65, 204, 77, 65, 82, 75, 128, 77, 69, 69, 205, 67, 79, + 80, 84, 73, 195, 75, 72, 77, 69, 210, 82, 73, 71, 72, 84, 87, 65, 82, 68, + 211, 65, 66, 79, 86, 197, 67, 65, 82, 82, 73, 69, 210, 89, 69, 200, 67, + 72, 69, 82, 79, 75, 69, 197, 80, 76, 85, 211, 68, 69, 86, 65, 78, 65, 71, + 65, 82, 201, 80, 72, 65, 83, 69, 45, 197, 77, 79, 78, 71, 79, 76, 73, 65, + 206, 83, 84, 82, 79, 75, 69, 128, 76, 69, 70, 84, 87, 65, 82, 68, 211, + 83, 89, 77, 66, 79, 76, 128, 66, 79, 216, 84, 73, 76, 197, 68, 85, 80, + 76, 79, 89, 65, 206, 77, 73, 68, 68, 76, 197, 80, 65, 82, 69, 78, 84, 72, + 69, 83, 73, 90, 69, 196, 83, 81, 85, 65, 82, 69, 196, 84, 72, 65, 205, + 79, 78, 69, 128, 213, 74, 79, 78, 71, 83, 69, 79, 78, 199, 84, 87, 79, + 128, 67, 79, 78, 83, 79, 78, 65, 78, 212, 72, 69, 66, 82, 69, 215, 77, + 73, 65, 207, 85, 208, 72, 79, 79, 75, 128, 71, 69, 79, 82, 71, 73, 65, + 206, 79, 86, 69, 210, 68, 82, 65, 87, 73, 78, 71, 211, 72, 77, 79, 78, + 199, 79, 78, 197, 80, 65, 72, 65, 87, 200, 84, 87, 207, 68, 79, 87, 206, + 73, 78, 68, 69, 216, 67, 72, 79, 83, 69, 79, 78, 199, 76, 79, 215, 86, + 79, 67, 65, 76, 73, 195, 84, 72, 82, 69, 197, 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, 77, 65, 82, 203, 83, 67, 82, 73, + 80, 212, 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, + 72, 73, 71, 200, 73, 68, 69, 79, 71, 82, 65, 80, 72, 73, 195, 83, 73, 78, + 72, 65, 76, 193, 78, 85, 77, 69, 82, 73, 195, 66, 65, 82, 128, 84, 79, + 78, 197, 66, 82, 65, 72, 77, 201, 72, 85, 78, 71, 65, 82, 73, 65, 206, + 84, 72, 82, 69, 69, 128, 84, 72, 85, 77, 194, 70, 79, 85, 82, 128, 66, + 65, 82, 194, 72, 65, 200, 72, 65, 128, 78, 79, 82, 84, 200, 70, 85, 76, + 76, 87, 73, 68, 84, 200, 66, 82, 65, 67, 75, 69, 84, 128, 69, 81, 85, 65, + 204, 76, 73, 71, 72, 212, 84, 65, 199, 68, 79, 77, 73, 78, 207, 72, 65, + 76, 198, 76, 79, 78, 199, 77, 65, 76, 65, 89, 65, 76, 65, 205, 65, 67, + 85, 84, 69, 128, 70, 82, 65, 75, 84, 85, 210, 67, 72, 65, 82, 65, 67, 84, + 69, 210, 80, 72, 65, 83, 69, 45, 195, 68, 79, 85, 66, 76, 69, 45, 83, 84, + 82, 85, 67, 203, 70, 73, 86, 69, 128, 79, 80, 69, 206, 72, 73, 82, 65, + 71, 65, 78, 193, 75, 65, 128, 77, 69, 68, 73, 65, 204, 84, 69, 76, 85, + 71, 213, 74, 85, 78, 71, 83, 69, 79, 78, 199, 85, 80, 87, 65, 82, 68, + 211, 65, 82, 77, 69, 78, 73, 65, 206, 66, 69, 78, 71, 65, 76, 201, 71, + 76, 65, 71, 79, 76, 73, 84, 73, 195, 83, 72, 65, 82, 65, 68, 193, 78, 69, + 71, 65, 84, 73, 86, 197, 68, 79, 87, 78, 87, 65, 82, 68, 211, 74, 69, 69, + 205, 80, 65, 128, 83, 73, 68, 68, 72, 65, 205, 68, 79, 84, 211, 73, 68, + 69, 79, 71, 82, 65, 80, 200, 74, 65, 86, 65, 78, 69, 83, 197, 67, 85, 82, + 83, 73, 86, 197, 77, 65, 128, 79, 82, 73, 89, 193, 83, 128, 83, 73, 88, + 128, 87, 69, 83, 84, 45, 67, 82, 69, 197, 82, 85, 78, 73, 195, 89, 65, + 128, 69, 73, 71, 72, 84, 128, 75, 65, 78, 78, 65, 68, 193, 78, 65, 128, + 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, 83, 72, 65, 128, 90, 82, - 65, 128, 90, 81, 65, 80, 72, 193, 90, 79, 84, 128, 90, 79, 79, 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, 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, 128, 90, 72, 73, 86, 69, 84, 69, - 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, 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, 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, 50, 128, 90, 197, 90, 65, 89, 78, 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, 81, 69, 198, 90, 65, 77, 88, 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, 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, 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, 128, 89, 213, - 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, 85, 84, 72, 70, 85, 76, 78, 69, 83, 83, 128, 89, 79, 85, - 84, 72, 70, 85, 204, 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, 72, 128, 89, 79, 68, 128, 89, 79, 196, - 89, 79, 65, 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, 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, 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, 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, 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, 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, 72, - 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, 65, 78, 78, 65, - 128, 89, 65, 89, 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, 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, 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, 128, 88, 89, 73, 128, 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, 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, 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, 128, 88, 71, 128, 88, 69, - 83, 84, 69, 211, 88, 69, 72, 128, 88, 69, 69, 128, 88, 69, 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, 87, 90, 128, 87, 89, 78, 78, 128, 87, 89, 78, 206, - 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, 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, 84, 73, 78, 199, 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, 82, 82, 73, 69, 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, 73, 84, 72, 79, 85, 212, 87, 73, 84, 72, 73, 78, 128, 87, 73, 78, 84, - 69, 82, 128, 87, 73, 78, 75, 73, 78, 199, 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, 128, 87, 73, 78, 196, 87, 73, 78, 128, 87, - 73, 71, 78, 89, 65, 78, 128, 87, 73, 71, 71, 76, 217, 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, 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, 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, 71, 128, 87, 69, 88, 128, 87, 69, 85, 88, 128, 87, - 69, 83, 84, 69, 82, 206, 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, 69, - 78, 128, 87, 69, 68, 71, 69, 45, 84, 65, 73, 76, 69, 196, 87, 69, 68, 68, - 73, 78, 71, 128, 87, 69, 65, 82, 217, 87, 69, 65, 80, 79, 78, 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, - 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, 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, 128, 87, 65, 76, 76, 128, 87, 65, 76, 75, 128, 87, 65, - 76, 203, 87, 65, 73, 84, 73, 78, 71, 128, 87, 65, 73, 128, 87, 65, 69, - 78, 128, 87, 65, 69, 128, 87, 65, 65, 86, 85, 128, 87, 48, 50, 53, 128, + 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, 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, + 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, 50, 128, + 90, 197, 90, 65, 89, 78, 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, 77, + 88, 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, 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, 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, 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, 72, 128, 89, 79, 68, + 128, 89, 79, 196, 89, 79, 65, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 83, 84, 69, 82, + 206, 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, 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, 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, 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, 69, 78, 128, 87, 65, 69, 128, + 87, 65, 68, 68, 65, 128, 87, 65, 65, 86, 85, 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, @@ -258,100 +274,102 @@ static unsigned char lexicon[] = { 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, 65, 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, 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, 80, 128, 86, 79, 79, 128, 86, 79, 77, 128, - 86, 79, 76, 85, 77, 197, 86, 79, 76, 84, 65, 71, 197, 86, 79, 76, 67, 65, - 78, 79, 128, 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, 67, 65, 76, - 73, 90, 65, 84, 73, 79, 206, 86, 79, 67, 65, 204, 86, 79, 128, 86, 73, + 80, 128, 86, 89, 128, 86, 87, 74, 128, 86, 87, 65, 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, 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, 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, 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, @@ -360,123 +378,127 @@ static unsigned char lexicon[] = { 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, 128, 86, 73, 76, 76, - 65, 71, 69, 128, 86, 73, 73, 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, 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, 73, 128, 86, 70, 65, 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, 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, 80, 128, 86, 69, 78, 68, 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, 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, 80, 79, 85, 82, 83, 128, 86, 65, 80, 128, 86, 65, 78, - 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, 73, - 128, 86, 65, 72, 128, 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, 51, 128, 85, 90, 179, 85, 89, 65, 78, 78, 65, 128, 85, 89, 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, 82, 73, 71, 72, - 212, 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, - 78, 78, 128, 85, 78, 77, 65, 82, 82, 73, 69, 196, 85, 78, 75, 78, 79, 87, - 78, 128, 85, 78, 73, 86, 69, 82, 83, 65, 204, 85, 78, 73, 84, 89, 128, - 85, 78, 73, 84, 128, 85, 78, 73, 212, 85, 78, 73, 79, 78, 128, 85, 78, - 73, 79, 206, 85, 78, 73, 70, 73, 69, 196, 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, 210, 85, 78, 67, 73, 193, 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, + 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, 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, 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, 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, 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, 80, 79, 85, 82, 83, 128, 86, 65, 80, + 128, 86, 65, 78, 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, 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, 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, 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, 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, 128, 85, + 78, 73, 212, 85, 78, 73, 79, 78, 128, 85, 78, 73, 79, 206, 85, 78, 73, + 70, 73, 69, 196, 85, 78, 73, 67, 79, 82, 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, 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, 71, 65, 82, 73, 84, 73, 195, @@ -499,505 +521,576 @@ static unsigned char lexicon[] = { 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, 73, 45, 73, 128, 85, 45, 69, 79, 45, - 69, 85, 128, 85, 45, 66, 82, 74, 71, 85, 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, 182, - 84, 89, 80, 69, 45, 181, 84, 89, 80, 69, 45, 180, 84, 89, 80, 69, 45, - 179, 84, 89, 80, 69, 45, 178, 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, 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, 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, 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, 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, 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, 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, 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, 78, 69, 196, 84, 85, 82, 206, 84, 85, 82, 75, 73, 83, - 200, 84, 85, 82, 66, 65, 78, 128, 84, 85, 82, 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, 65, 69, 128, 84, 85, 77, 128, 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, 65, 82, 69, 199, 84, 85, - 65, 69, 80, 128, 84, 85, 65, 69, 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, 65, - 128, 84, 83, 86, 128, 84, 83, 83, 69, 128, 84, 83, 83, 65, 128, 84, 83, - 72, 85, 71, 83, 128, 84, 83, 72, 79, 79, 75, 128, 84, 83, 72, 79, 79, - 203, 84, 83, 72, 69, 83, 128, 84, 83, 72, 69, 71, 128, 84, 83, 72, 69, - 199, 84, 83, 72, 69, 128, 84, 83, 72, 65, 128, 84, 83, 69, 82, 69, 128, - 84, 83, 65, 68, 73, 128, 84, 83, 65, 68, 201, 84, 83, 65, 65, 68, 73, 89, - 128, 84, 83, 65, 65, 128, 84, 83, 193, 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, 69, 128, 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, 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, 197, - 84, 82, 73, 79, 206, 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, 65, 68, - 73, 78, 71, 128, 84, 82, 65, 89, 128, 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, 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, 197, 84, 82, 65, 67, 84, 79, 82, 128, 84, - 82, 65, 67, 75, 128, 84, 82, 128, 84, 79, 88, 128, 84, 79, 87, 69, 82, - 128, 84, 79, 85, 82, 78, 79, 73, 211, 84, 79, 84, 65, 204, 84, 79, 84, - 128, 84, 79, 82, 84, 79, 73, 83, 197, 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, 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, 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, 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, 78, 128, 84, 73, 87, 65, 218, 84, 73, 84, 85, 65, 69, 80, 128, 84, - 73, 84, 76, 79, 128, 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, 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, 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, 128, 84, 73, 67, 75, 128, 84, 73, 67, 203, - 84, 73, 65, 82, 65, 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, 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, 80, 69, 82, 45, 69, 205, 84, - 72, 82, 69, 69, 45, 76, 73, 78, 197, 84, 72, 82, 69, 69, 45, 69, 205, 84, - 72, 82, 69, 69, 45, 196, 84, 72, 82, 69, 65, 68, 128, 84, 72, 79, 85, 83, - 65, 78, 68, 211, 84, 72, 79, 85, 83, 65, 78, 68, 128, 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, 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, 196, 84, 72, 73, - 82, 84, 89, 45, 79, 78, 69, 128, 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, 128, 84, 72, 73, - 82, 196, 84, 72, 73, 206, 84, 72, 73, 73, 128, 84, 72, 73, 71, 72, 128, - 84, 72, 73, 69, 85, 84, 200, 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, 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, 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, 76, 128, 84, 72, 65, 204, 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, 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, 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, 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, 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, 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, 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, 73, 87, 83, 128, 84, 69, 71, 69, 72, - 128, 84, 69, 69, 69, 69, 128, 84, 69, 197, 84, 69, 68, 85, 78, 71, 128, - 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, 50, 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, 86, 73, 89, 65, 78, 73, 128, 84, 65, 86, 128, 84, 65, 214, 84, - 65, 85, 82, 85, 83, 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, 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, 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, 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, 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, + 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, + 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, 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, + 78, 69, 196, 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, 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, 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, 128, 84, 85, 65, 82, 69, 199, 84, 85, 65, 69, + 80, 128, 84, 85, 65, 69, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 69, 205, 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, 68, 128, 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, 196, 84, 72, + 73, 82, 84, 89, 45, 79, 78, 69, 128, 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, 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, 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, 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, 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, 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, 50, 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, 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, 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, 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, 199, 84, 65, - 78, 65, 66, 65, 84, 193, 84, 65, 78, 128, 84, 65, 77, 73, 78, 71, 128, - 84, 65, 77, 128, 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, 128, 84, 65, 75, 52, 128, 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, 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, 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, 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, 50, 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, 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, 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, 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, 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, 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, - 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, 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, - 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, 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, 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, - 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, 84, 128, 83, 85, 72, 85, 82, - 128, 83, 85, 69, 128, 83, 85, 68, 50, 128, 83, 85, 68, 128, 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, 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, - 69, 84, 128, 83, 85, 65, 69, 78, 128, 83, 85, 65, 69, 128, 83, 85, 65, - 128, 83, 213, 83, 84, 88, 128, 83, 84, 87, 65, 128, 83, 84, 85, 68, 89, - 128, 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, 68, 69, 128, 83, 84, 82, 73, 67, 84, 76, 217, 83, 84, 82, - 69, 84, 67, 72, 69, 196, 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, 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, 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, 73, 77, 77, 69, 128, 83, 84, 73, 76, - 204, 83, 84, 73, 76, 197, 83, 84, 73, 71, 77, 65, 128, 83, 84, 69, 80, - 128, 83, 84, 69, 77, 128, 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, 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, 65, 82, 196, 83, 84, - 65, 78, 68, 128, 83, 84, 65, 78, 128, 83, 84, 65, 76, 76, 73, 79, 78, - 128, 83, 84, 65, 70, 70, 128, 83, 84, 65, 70, 198, 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, 73, 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, 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, 75, 73, 89, 69, - 79, 75, 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, 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, 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, 79, 85, 84, 73, 78, 199, 83, 80, 79, 84, 128, - 83, 80, 79, 79, 78, 128, 83, 80, 76, 73, 84, 84, 73, 78, 199, 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, 68, 69, - 82, 217, 83, 80, 73, 67, 69, 128, 83, 80, 72, 69, 82, 73, 67, 65, 204, + 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, 128, 84, 65, + 77, 73, 78, 71, 128, 84, 65, 77, 128, 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, 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, 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, + 50, 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, + 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, 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, 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, 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, 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, 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, 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, 84, 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, 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, 213, 83, 84, 88, 128, 83, 84, 87, 65, 128, 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, 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, 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, + 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, 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, + 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, 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, + 73, 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, 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, 75, 73, 89, 69, 79, 75, 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, 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, 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, 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, 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, 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, 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, 212, 83, 79, 198, 83, 79, 67, 73, 69, 84, 89, - 128, 83, 79, 67, 67, 69, 210, 83, 79, 65, 80, 128, 83, 79, 65, 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, 85, 84, 128, 83, 78, 79, - 85, 212, 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, 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, 215, 83, 76, 79, 86, 79, 128, 83, 76, 79, - 212, 83, 76, 79, 80, 73, 78, 199, 83, 76, 79, 80, 69, 128, 83, 76, 73, - 78, 71, 128, 83, 76, 73, 68, 73, 78, 71, 128, 83, 76, 73, 67, 69, 128, - 83, 76, 73, 67, 197, 83, 76, 69, 69, 80, 217, 83, 76, 69, 69, 80, 73, 78, + 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, 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, 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, + 212, 83, 79, 198, 83, 79, 67, 73, 69, 84, 89, 128, 83, 79, 67, 67, 69, + 210, 83, 79, 65, 80, 128, 83, 79, 65, 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, 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, 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, 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, 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, - 128, 83, 75, 128, 83, 74, 69, 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, 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, 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, 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, 67, 75, 78, 69, 83, 83, 128, 83, 73, 67, 75, 76, 69, 128, - 83, 73, 66, 197, 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, 65, 65, 128, - 83, 72, 87, 65, 128, 83, 72, 85, 88, 128, 83, 72, 85, 85, 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, 70, 70, 76, 197, 83, 72, 85, + 128, 83, 75, 128, 83, 74, 69, 128, 83, 73, 90, 197, 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, 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, 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, 65, 77, 128, 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, 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, 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, 50, 128, 83, 72, 85, 178, 83, 72, 85, 128, 83, 72, 213, 83, 72, 84, 65, 80, 73, 67, 128, 83, 72, 84, 65, 128, 83, 72, 82, 73, 78, 69, 128, 83, 72, 82, 73, 77, 80, 128, 83, 72, 82, 73, 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, 84, 128, 83, - 72, 79, 82, 84, 83, 128, 83, 72, 79, 82, 84, 211, 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, 128, 83, 72, 79, 79, 84, - 73, 78, 199, 83, 72, 79, 79, 84, 128, 83, 72, 79, 79, 128, 83, 72, 79, - 71, 201, 83, 72, 79, 199, 83, 72, 79, 69, 128, 83, 72, 79, 197, 83, 72, - 79, 65, 128, 83, 72, 79, 128, 83, 72, 73, 89, 89, 65, 65, 76, 65, 65, + 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, 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, 128, 83, 72, 79, 197, 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, 80, 128, 83, 72, 73, 78, 84, 207, 83, 72, - 73, 78, 73, 71, 128, 83, 72, 73, 78, 68, 193, 83, 72, 73, 78, 128, 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, 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, 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, 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, - 75, 84, 73, 128, 83, 72, 65, 73, 128, 83, 72, 65, 68, 79, 87, 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, 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, 88, 84, 85, 76, 193, 83, 69, 88, + 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, 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, 75, 84, 73, 128, 83, 72, 65, 75, 73, 78, 71, 128, 83, + 72, 65, 75, 73, 78, 199, 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, @@ -1007,1199 +1100,1364 @@ static unsigned char lexicon[] = { 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, 70, 83, 128, 83, 69, 82, 73, 70, 211, - 83, 69, 81, 85, 69, 78, 67, 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, 78, 84, 79, 128, 83, 69, 78, 84, 73, 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, 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, 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, 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, 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, 79, 78, 68, 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, 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, 69, 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, 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, 73, 76, 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, 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, 78, 89, 65, 128, 83, 65, 78, 71, 65, 50, 128, 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, 128, - 83, 65, 76, 45, 65, 77, 77, 79, 78, 73, 65, 67, 128, 83, 65, 76, 128, 83, - 65, 75, 79, 84, 128, 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, 68, 72, 69, 128, 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, 50, 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, 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, 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, 75, 75, 65, 75, 72, 65, 128, 82, 85, 73, 83, 128, 82, 85, - 71, 66, 217, 82, 85, 194, 82, 85, 65, 128, 82, 84, 72, 65, 78, 199, 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, 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, 82, - 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, 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, 75, 128, 82, 79, 79, 70, 128, 82, - 79, 77, 65, 206, 82, 79, 77, 128, 82, 79, 76, 76, 69, 210, 82, 79, 72, - 73, 78, 71, 89, 193, 82, 79, 196, 82, 79, 67, 75, 69, 84, 128, 82, 79, - 67, 203, 82, 79, 67, 128, 82, 79, 66, 65, 84, 128, 82, 79, 65, 83, 84, - 69, 196, 82, 79, 65, 82, 128, 82, 79, 65, 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, 128, 82, 73, 78, 71, 211, 82, 73, 78, 70, - 79, 82, 90, 65, 78, 68, 79, 128, 82, 73, 206, 82, 73, 77, 71, 66, 65, - 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, 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, 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, 69, 77, - 128, 82, 73, 67, 69, 128, 82, 73, 67, 197, 82, 73, 66, 66, 79, 78, 128, - 82, 73, 65, 204, 82, 72, 79, 84, 73, 195, 82, 72, 79, 128, 82, 72, 207, - 82, 72, 65, 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, 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, - 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, 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, 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, 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, 196, 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, 196, 82, 69, 67, 69, 80, 84, 73, 86, - 197, 82, 69, 67, 69, 73, 86, 69, 82, 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, 68, 207, 82, 68, 69, 204, 82, 66, 65, - 83, 193, 82, 65, 89, 83, 128, 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, 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, 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, 50, 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, 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, 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, 82, 84, 69, 210, 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, 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, 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, - 128, 81, 72, 73, 128, 81, 72, 69, 69, 128, 81, 72, 69, 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, 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, 89, 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, 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, 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, 69, 128, 80, 85, 66, 76, - 73, 195, 80, 85, 65, 81, 128, 80, 85, 65, 69, 128, 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, + 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, 78, 84, 79, 128, 83, 69, 78, 84, + 73, 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, 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, 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, 79, 78, 68, 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, 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, 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, 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, 65, + 83, 72, 84, 82, 193, 83, 65, 85, 73, 76, 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, 78, 89, 65, 128, 83, 65, 78, 71, 65, + 50, 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, 128, 83, 65, 76, 45, 65, + 77, 77, 79, 78, 73, 65, 67, 128, 83, 65, 76, 128, 83, 65, 75, 79, 84, + 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, 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, 50, + 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, 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, 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, 84, 72, 65, 78, 199, 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, 75, 128, 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, 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, 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, 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, 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, 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, 72, 79, 84, 73, 195, 82, 72, 79, 128, 82, + 72, 207, 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, 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, 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, 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, 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, 68, 207, 82, 68, 69, 204, 82, 66, 65, 83, 193, 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, 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, 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, 50, 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, 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, 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, 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, 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, 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, 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, 73, 86, 69, 128, 80, 82, - 79, 74, 69, 67, 84, 73, 79, 78, 128, 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, 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, 128, 80, 82, 73, 78, 212, 80, 82, 73, 78, + 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, 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, 77, 69, 128, 80, 82, 73, 77, 197, 80, - 82, 69, 86, 73, 79, 85, 211, 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, 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, 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, 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, 82, 82, 69, 67, 84, 85, 83, 128, 80, 79, 82, 82, - 69, 67, 84, 85, 211, 80, 79, 80, 80, 69, 82, 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, 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, 65, 128, 80, 79, 128, 80, 207, 80, 78, 69, 85, 77, 65, 84, 65, 128, - 80, 76, 85, 84, 79, 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, 69, 84, - 72, 82, 79, 78, 128, 80, 76, 68, 128, 80, 76, 65, 89, 73, 78, 199, 80, + 82, 69, 86, 73, 79, 85, 211, 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, 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, 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, 73, 84, 73, 79, 78, 83, 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, 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, 79, 128, 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, 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, 128, 80, 76, 65, 78, - 197, 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, 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, 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, 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, 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, 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, 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, 65, 82, 75, - 65, 65, 128, 80, 72, 65, 65, 128, 80, 72, 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, 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, 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, 77, 73, 84, 84, 69, 196, 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, 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, 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, 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, - 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, 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, 215, 80, 65, 86, 73, 89, 65, - 78, 73, 128, 80, 65, 85, 128, 80, 65, 84, 84, 69, 82, 78, 128, 80, 65, - 84, 72, 65, 77, 65, 83, 65, 84, 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, 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, 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, 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, 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, - 128, 80, 65, 82, 128, 80, 65, 80, 89, 82, 85, 83, 128, 80, 65, 80, 69, - 82, 67, 76, 73, 80, 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, 65, 69, 76, 65, 69, 78, - 71, 128, 80, 65, 78, 128, 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, 205, 80, - 65, 76, 76, 65, 87, 65, 128, 80, 65, 76, 76, 65, 83, 128, 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, 128, 80, 65, 72, 76, 65, 86, 201, 80, 65, - 72, 128, 80, 65, 71, 69, 82, 128, 80, 65, 71, 197, 80, 65, 68, 77, 193, - 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, 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, 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, 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, 80, 80, 73, - 78, 199, 79, 86, 69, 82, 76, 65, 73, 68, 128, 79, 86, 69, 82, 66, 65, 82, - 128, 79, 86, 65, 204, 79, 86, 128, 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, 65, 86, 193, 79, 84, 84, 128, 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, 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, 128, 79, 82, 78, 65, 77, 69, 78, 212, 79, 82, 75, 72, 79, 206, - 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, 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, + 67, 203, 80, 76, 65, 75, 128, 80, 76, 65, 71, 73, 79, 211, 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, 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, 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, 72, 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, 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, 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, 75, 211, 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, 215, 80, 65, 86, + 73, 89, 65, 78, 73, 128, 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, + 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, 69, 78, 71, 69, 210, 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, 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, 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, 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, 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, 65, 69, 76, 65, 69, 78, 71, 128, 80, 65, 78, 128, 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, 205, 80, 65, + 76, 76, 65, 87, 65, 128, 80, 65, 76, 76, 65, 83, 128, 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, 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, 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, + 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, + 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, 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, 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, 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, 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, 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, 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, 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, 79, 90, 69, - 128, 79, 79, 89, 65, 78, 78, 65, 128, 79, 79, 85, 128, 79, 79, 77, 85, - 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, 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, 76, 73, 78, 197, 79, 78, - 67, 79, 77, 73, 78, 199, 79, 78, 65, 80, 128, 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, 76, 128, 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, 75, 128, 79, 68, 69, 78, 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, 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, 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, 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, + 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, 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, 76, + 73, 78, 197, 79, 78, 67, 79, 77, 73, 78, 199, 79, 78, 65, 80, 128, 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, + 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, 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, 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, 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, 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, 128, 78, 89, 201, 78, - 89, 72, 65, 128, 78, 89, 69, 84, 128, 78, 89, 69, 212, 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, 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, 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, 84, 85, 85, 128, 78, 84, 85, 77, 128, 78, 84, 213, 78, 84, - 79, 81, 80, 69, 78, 128, 78, 84, 73, 69, 197, 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, 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, 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, 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, 79, 89, 128, 78, 79, - 88, 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, 128, 78, 79, 212, 78, - 79, 83, 69, 128, 78, 79, 82, 84, 72, 87, 69, 83, 212, 78, 79, 82, 84, 72, - 69, 82, 206, 78, 79, 82, 84, 200, 78, 79, 82, 77, 65, 204, 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, 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, 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, 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, 65, 82, 65, 69, 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, 77, 128, 78, 73, 205, 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, 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, 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, + 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, + 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, 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, 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, 84, 88, 73, + 86, 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, 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, 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, 79, 89, 128, 78, 79, 88, 128, 78, 79, 87, 67, 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, 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, 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, + 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, 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, 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, 128, 78, 69, 85, 84, 82, 65, 204, - 78, 69, 85, 84, 69, 82, 128, 78, 69, 84, 128, 78, 69, 212, 78, 69, 83, - 84, 69, 196, 78, 69, 81, 85, 68, 65, 65, 128, 78, 69, 80, 84, 85, 78, 69, - 128, 78, 69, 80, 128, 78, 69, 79, 128, 78, 69, 207, 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, 79, 206, 78, 69, 71, 65, 84, 69, 196, 78, 69, 67, - 75, 84, 73, 69, 128, 78, 69, 66, 69, 78, 83, 84, 73, 77, 77, 69, 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, 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, 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, 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, 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, - 128, 78, 65, 78, 65, 128, 78, 65, 77, 69, 128, 78, 65, 77, 197, 78, 65, - 77, 50, 128, 78, 65, 77, 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, 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, 50, 128, 78, 65, 45, 50, 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, 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, 217, 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, 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, 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, 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, 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, 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, 75, 80, 72, 82, 69, 78, 71, - 128, 77, 85, 73, 78, 128, 77, 85, 71, 83, 128, 77, 85, 71, 128, 77, 85, - 199, 77, 85, 69, 128, 77, 85, 67, 72, 128, 77, 85, 67, 200, 77, 85, 67, - 65, 65, 68, 128, 77, 85, 65, 78, 128, 77, 85, 65, 69, 128, 77, 85, 45, - 71, 65, 65, 72, 76, 65, 193, 77, 213, 77, 83, 128, 77, 80, 65, 128, 77, - 79, 89, 65, 73, 128, 77, 79, 88, 128, 77, 79, 86, 73, 197, 77, 79, 86, - 69, 196, 77, 79, 85, 84, 72, 128, 77, 79, 85, 84, 200, 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, 72, 69, 82, 128, 77, 79, 84, 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, - 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, 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, 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, 69, 83, 84, 89, 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, 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, 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, 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, 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, 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, 197, 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, 207, 77, 73, 67, 210, 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, 79, 73, 84, 73, 195, 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, 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, + 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, 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, 84, 128, 78, 69, 212, 78, 69, 83, 84, 69, 196, + 78, 69, 82, 196, 78, 69, 81, 85, 68, 65, 65, 128, 78, 69, 80, 84, 85, 78, + 69, 128, 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, 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, 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, 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, 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, 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, 128, 78, 65, 78, 65, 128, 78, 65, 77, 69, 128, + 78, 65, 77, 197, 78, 65, 77, 50, 128, 78, 65, 77, 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, 50, 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, 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, 217, 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, 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, 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, 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, 213, 77, 83, 128, 77, + 82, 207, 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, 67, 89, 67, 76, 69, 128, 77, 79, 84, 79, 210, 77, 79, 84, 72, 69, 82, + 128, 77, 79, 84, 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, 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, 201, 77, 79, 68, 69, 83, 84, 89, 128, 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, + 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, + 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, 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, 207, 77, 73, 67, 210, 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, 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, 128, 77, 69, 69, - 77, 85, 128, 77, 69, 69, 77, 128, 77, 69, 69, 69, 69, 128, 77, 69, 68, - 73, 85, 77, 128, 77, 69, 68, 73, 85, 205, 77, 69, 68, 73, 67, 73, 78, 69, - 128, 77, 69, 68, 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, 68, 85, 206, 77, 196, 77, 67, 72, 213, 77, 67, - 72, 65, 206, 77, 195, 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, 66, 128, 77, 194, 77, - 65, 89, 65, 78, 78, 65, 128, 77, 65, 89, 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, 82, 89, 128, 77, 65, 82, 85, 75, 85, - 128, 77, 65, 82, 84, 89, 82, 73, 193, 77, 65, 82, 82, 89, 73, 78, 199, - 77, 65, 82, 82, 73, 65, 71, 197, 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, 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, - 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, 71, 65, 76, 65, 77, 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, 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, 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, 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, 67, 73, 78, 69, 128, 77, 69, 68, 73, 67, 65, + 204, 77, 69, 68, 65, 76, 128, 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, 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, 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, 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, 82, 89, 73, + 78, 199, 77, 65, 82, 82, 73, 65, 71, 197, 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, 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, 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, 65, 76, 65, 77, 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, 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, 65, 80, 82, 65, 65, 78, 193, - 77, 65, 72, 128, 77, 65, 71, 78, 73, 70, 89, 73, 78, 199, 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, 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, 48, - 52, 52, 128, 77, 48, 52, 51, 128, 77, 48, 52, 50, 128, 77, 48, 52, 49, - 128, 77, 48, 52, 48, 65, 128, 77, 48, 52, 48, 128, 77, 48, 51, 57, 128, - 77, 48, 51, 56, 128, 77, 48, 51, 55, 128, 77, 48, 51, 54, 128, 77, 48, - 51, 53, 128, 77, 48, 51, 52, 128, 77, 48, 51, 51, 66, 128, 77, 48, 51, - 51, 65, 128, 77, 48, 51, 51, 128, 77, 48, 51, 50, 128, 77, 48, 51, 49, - 65, 128, 77, 48, 51, 49, 128, 77, 48, 51, 48, 128, 77, 48, 50, 57, 128, - 77, 48, 50, 56, 65, 128, 77, 48, 50, 56, 128, 77, 48, 50, 55, 128, 77, - 48, 50, 54, 128, 77, 48, 50, 53, 128, 77, 48, 50, 52, 65, 128, 77, 48, - 50, 52, 128, 77, 48, 50, 51, 128, 77, 48, 50, 50, 65, 128, 77, 48, 50, - 50, 128, 77, 48, 50, 49, 128, 77, 48, 50, 48, 128, 77, 48, 49, 57, 128, - 77, 48, 49, 56, 128, 77, 48, 49, 55, 65, 128, 77, 48, 49, 55, 128, 77, - 48, 49, 54, 65, 128, 77, 48, 49, 54, 128, 77, 48, 49, 53, 65, 128, 77, - 48, 49, 53, 128, 77, 48, 49, 52, 128, 77, 48, 49, 51, 128, 77, 48, 49, + 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, 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, 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, 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, 49, 128, 77, 48, 49, 48, 65, 128, 77, 48, 49, 48, 128, 77, 48, - 48, 57, 128, 77, 48, 48, 56, 128, 77, 48, 48, 55, 128, 77, 48, 48, 54, - 128, 77, 48, 48, 53, 128, 77, 48, 48, 52, 128, 77, 48, 48, 51, 65, 128, - 77, 48, 48, 51, 128, 77, 48, 48, 50, 128, 77, 48, 48, 49, 66, 128, 77, - 48, 48, 49, 65, 128, 77, 48, 48, 49, 128, 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, 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, 71, 71, 65, 71, 69, 128, 76, 85, 71, 65, - 76, 128, 76, 85, 71, 65, 204, 76, 85, 69, 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, 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, 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, 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, 206, 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, 74, 85, 68, - 73, 74, 69, 128, 76, 74, 69, 128, 76, 74, 128, 76, 73, 88, 128, 76, 73, - 87, 78, 128, 76, 73, 86, 82, 197, 76, 73, 84, 84, 76, 197, 76, 73, 84, - 84, 69, 210, 76, 73, 84, 82, 193, 76, 73, 84, 128, 76, 73, 83, 213, 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, 78, 75, 73, 78, 199, 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, 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, 72, 79, 85, 83, - 69, 128, 76, 73, 71, 72, 84, 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, 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, 69, 204, 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, 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, 71, 84, 72, 69, 78, 69, 82, 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, 71, 83, 128, 76, 69, 71, 73, 79, 78, 128, 76, 69, 71, 69, 84, 79, - 211, 76, 69, 71, 128, 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, 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, 128, 76, 69, 65, 198, 76, 69, 65, 68, 73, 78, 199, 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, 84, 73, 78, 65, 84, 197, + 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, 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, 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, + 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, + 206, 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, 74, 85, 68, 73, 74, 69, 128, 76, 74, 69, 128, 76, + 74, 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, 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, 128, + 76, 69, 65, 198, 76, 69, 65, 68, 73, 78, 199, 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, 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, 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, 80, 128, 76, 65, 78, 84, 69, 82, 78, 128, - 76, 65, 78, 71, 85, 65, 71, 197, 76, 65, 78, 69, 83, 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, 74, - 65, 78, 89, 65, 76, 65, 78, 128, 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, 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, 65, 84, 128, 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, 48, 48, 54, 65, 128, 76, 48, 48, + 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, 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, 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, + 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, 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, @@ -2207,72 +2465,82 @@ static unsigned char lexicon[] = { 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, 85, 51, 49, 56, 128, 75, 87, 79, 79, 128, 75, 87, 79, - 128, 75, 87, 73, 73, 128, 75, 87, 73, 128, 75, 87, 69, 69, 128, 75, 87, - 69, 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, 88, 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, 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, 69, 84, 128, 75, 85, 55, 128, 75, 85, 52, 128, 75, 85, 180, 75, 85, - 51, 128, 75, 85, 179, 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, - 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, 128, 75, 79, 88, 128, 75, 79, 86, 85, 85, 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, 80, - 79, 128, 75, 79, 79, 77, 85, 85, 84, 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, 128, 75, 79, 203, 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, 65, 76, 65, 128, 75, 79, 65, 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, 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, 85, 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, 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, 68, 69, 82, 71, 65, - 82, 84, 69, 78, 128, 75, 73, 77, 79, 78, 79, 128, 75, 73, 73, 128, 75, - 73, 72, 128, 75, 73, 69, 88, 128, 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, 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, 77, 128, 75, 72, - 85, 65, 84, 128, 75, 72, 79, 85, 128, 75, 72, 79, 212, 75, 72, 79, 78, - 128, 75, 72, 79, 77, 85, 84, 128, 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, 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, 82, 79, 83, 72, 84, 72, 201, 75, 72, 65, 82, + 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, 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, 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, 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, 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, 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, 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, 128, 75, 78, + 73, 71, 72, 212, 75, 78, 73, 70, 69, 128, 75, 78, 73, 70, 197, 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, 85, 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, 128, 75, 73, 86, 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, 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, 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, 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, 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, 78, 128, 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, 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, 88, + 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, @@ -2285,1560 +2553,1626 @@ static unsigned char lexicon[] = { 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, 83, 85, 128, 75, 69, 69, 80, 73, 78, - 199, 75, 69, 69, 78, 71, 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, 73, 128, 75, 65, 86, 89, 75, 65, 128, 75, - 65, 85, 78, 65, 128, 75, 65, 85, 206, 75, 65, 85, 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, 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, 78, 84, 65, 74, 193, 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, 84, 72, 201, - 75, 65, 73, 82, 73, 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, - 73, 128, 75, 65, 65, 70, 85, 128, 75, 65, 65, 70, 128, 75, 65, 50, 128, - 75, 65, 178, 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, 69, 128, 74, 85, 76, 89, 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, 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, 69, 68, - 128, 74, 79, 73, 78, 128, 74, 79, 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, 128, 74, 73, 72, 86, 65, 77, 85, 76, 73, 89, 65, 128, - 74, 73, 65, 128, 74, 72, 79, 128, 74, 72, 69, 72, 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, 65, 78, 83, - 128, 74, 65, 89, 65, 78, 78, 65, 128, 74, 65, 86, 73, 89, 65, 78, 73, - 128, 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, 128, 74, 65, - 72, 128, 74, 65, 68, 69, 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, 202, 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, 85, 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, 78, 128, 73, 83, 79, 206, 73, 83, - 79, 76, 65, 84, 69, 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, 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, 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, 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, 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, 69, 82, 84, - 73, 79, 206, 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, 73, 128, 73, - 78, 72, 73, 66, 73, 212, 73, 78, 72, 69, 82, 69, 78, 212, 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, 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, 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, 83, 83, 65, 78, 71, 75, 73, 89, 69, 79, - 75, 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, 75, 73, 89, 69, 79, 75, 128, 73, - 69, 85, 78, 71, 45, 75, 72, 73, 69, 85, 75, 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, 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, 78, 84, 73, 70, 73, 67, 65, 84, - 73, 79, 78, 128, 73, 68, 69, 78, 84, 73, 67, 65, 204, 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, 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, 86, 128, 72, 85, 83, 72, 69, 196, 72, 85, - 82, 65, 78, 128, 72, 85, 79, 84, 128, 72, 85, 78, 68, 82, 69, 68, 128, - 72, 85, 78, 68, 82, 69, 196, 72, 85, 78, 128, 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, 66, 50, 128, 72, 85, 66, 178, 72, 85, 66, 128, 72, 85, 65, 82, - 65, 68, 68, 79, 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, 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, 128, 72, 79, 82, - 193, 72, 79, 79, 82, 85, 128, 72, 79, 79, 80, 128, 72, 79, 79, 78, 128, + 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, 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, 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, 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, 66, 65, 128, 75, 65, 65, 66, 128, 75, + 65, 50, 128, 75, 65, 178, 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, 69, 128, 74, 85, 76, + 89, 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, 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, 128, 74, 73, 72, 86, 65, 77, 85, 76, 73, 89, 65, + 128, 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, 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, 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, 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, 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, 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, 73, 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, 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, 83, 83, 65, 78, 71, + 75, 73, 89, 69, 79, 75, 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, 75, 73, 89, + 69, 79, 75, 128, 73, 69, 85, 78, 71, 45, 75, 72, 73, 69, 85, 75, 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, 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, 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, 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, 86, 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, 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, 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, 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, 73, 128, 72, 79, 67, 72, 79, 128, 72, 78, 85, 84, 128, 72, 78, 85, - 79, 88, 128, 72, 78, 85, 79, 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, 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, 84, 128, 72, 76, 65, 80, 128, 72, 76, 65, 128, - 72, 75, 128, 72, 73, 90, 66, 128, 72, 73, 83, 84, 79, 82, 73, 195, 72, - 73, 82, 73, 81, 128, 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, 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, + 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, 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, 78, 71, + 69, 68, 128, 72, 73, 78, 71, 69, 196, 72, 73, 78, 71, 69, 128, 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, 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, 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, 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, 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, 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, 80, 72, 79, 78, 69, 128, 72, 69, 65, - 68, 73, 78, 71, 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, 86, 69, 128, 72, - 65, 85, 80, 84, 83, 84, 73, 77, 77, 69, 128, 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, 80, 80, 217, 72, 65, 78, 85, 78, 79, 207, - 72, 65, 78, 71, 90, 72, 79, 213, 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, 71, 128, 72, 65, 78, 68, 128, 72, 65, 78, 45, 65, 75, - 65, 84, 128, 72, 65, 77, 90, 65, 128, 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, 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, 82, 67, 85, 84, 128, 72, 65, 73, 82, 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, 65, 82, 85, 128, - 72, 65, 65, 77, 128, 72, 65, 193, 72, 65, 45, 72, 65, 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, 128, 71, 85, 82, 85, 83, 72, 128, 71, 85, 82, 85, 78, 128, 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, 205, 71, 85, 76, 128, 71, 85, 73, 84, 65, - 82, 128, 71, 85, 199, 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, 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, 80, 72, 69, 77, 197, 71, 82, - 65, 80, 69, 83, 128, 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, 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, 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, 68, 128, 71, 79, 75, 128, 71, 79, 73, 78, 199, - 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, 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, - 128, 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, - 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, 128, 71, 72, 72, 65, 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, 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, 71, 65, 65, 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, 69, 82, 73, 195, 71, 69, 77, - 73, 78, 73, 128, 71, 69, 77, 73, 78, 65, 84, 73, 79, 206, 71, 69, 205, + 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, 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, 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, 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, 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, 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, 80, 80, 217, 72, 65, 78, 85, 78, 79, 207, 72, 65, 78, 71, + 90, 72, 79, 213, 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, 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, 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, 73, 82, 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, 65, 82, + 85, 128, 72, 65, 65, 77, 128, 72, 65, 193, 72, 65, 45, 72, 65, 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, 205, 71, 85, 76, 128, 71, 85, 74, 65, 82, 65, 84, + 201, 71, 85, 73, 84, 65, 82, 128, 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, 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, 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, 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, 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, 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, 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, 69, 82, 73, 195, 71, 69, 77, 73, 78, 73, 128, 71, + 69, 77, 73, 78, 65, 84, 73, 79, 206, 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, 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, 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, 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, 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, 78, 84, 45, - 84, 73, 76, 84, 69, 196, 70, 82, 79, 78, 84, 45, 70, 65, 67, 73, 78, 199, - 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, 128, 70, 82, 69, 197, 70, 82, 65, 78, - 195, 70, 82, 65, 77, 69, 128, 70, 82, 65, 71, 82, 65, 78, 84, 128, 70, - 82, 65, 71, 77, 69, 78, 84, 128, 70, 82, 65, 67, 84, 73, 79, 206, 70, 79, - 88, 128, 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, 83, 84, 69, 82, 73, 78, 71, 128, 70, 79, 82, 87, 65, - 82, 68, 128, 70, 79, 82, 84, 89, 128, 70, 79, 82, 84, 217, 70, 79, 82, - 84, 69, 128, 70, 79, 82, 77, 211, 70, 79, 82, 77, 65, 84, 84, 73, 78, 71, - 128, 70, 79, 82, 75, 69, 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, 68, 128, 70, 79, 79, 128, 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, 207, 70, 77, 128, 70, 76, 89, 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, 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, - 73, 80, 128, 70, 76, 73, 71, 72, 84, 128, 70, 76, 69, 88, 85, 83, 128, - 70, 76, 69, 88, 69, 196, 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, 128, 70, 76, 65, 212, 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, 86, - 197, 70, 73, 84, 65, 128, 70, 73, 84, 128, 70, 73, 83, 84, 69, 196, 70, - 73, 83, 84, 128, 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, 128, 70, 73, 82, 197, 70, 73, 80, 128, 70, - 73, 78, 73, 84, 197, 70, 73, 78, 71, 69, 82, 78, 65, 73, 76, 83, 128, 70, - 73, 78, 71, 69, 82, 69, 196, 70, 73, 78, 65, 78, 67, 73, 65, 76, 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, 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, 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, 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, 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, 82, 83, 201, 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, 76, 76, - 73, 78, 199, 70, 65, 76, 76, 69, 206, 70, 65, 73, 76, 85, 82, 69, 128, - 70, 65, 73, 72, 85, 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, 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, 200, 69, 90, 69, 78, 128, - 69, 90, 69, 206, 69, 90, 128, 69, 89, 69, 83, 128, 69, 89, 69, 71, 76, - 65, 83, 83, 69, 83, 128, 69, 89, 66, 69, 89, 70, 73, 76, 73, 128, 69, 89, - 65, 78, 78, 65, 128, 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, 69, 78, 83, 73, 79, 78, 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, 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, 67, 76, 65, 77, 65, 84, 73, 79, 78, 128, 69, 88, - 67, 76, 65, 77, 65, 84, 73, 79, 206, 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, 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, 66, 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, - 178, 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, 82, 82, 79, 82, 45, - 66, 65, 82, 82, 69, 196, 69, 82, 82, 128, 69, 82, 73, 78, 50, 128, 69, - 82, 71, 128, 69, 82, 65, 83, 197, 69, 81, 85, 73, 86, 65, 76, 69, 78, - 212, 69, 81, 85, 73, 68, 128, 69, 81, 85, 73, 65, 78, 71, 85, 76, 65, + 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, 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, 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, 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, 82, 65, 67, 84, 73, 79, + 206, 70, 79, 88, 128, 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, 128, 70, 79, 82, 84, 217, 70, + 79, 82, 84, 69, 128, 70, 79, 82, 77, 211, 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, 83, 72, 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, 86, 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, 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, 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, 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, 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, 74, + 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, 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, 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, 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, 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, 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, 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, 81, 85, 73, 82, 89, - 128, 69, 78, 81, 128, 69, 78, 79, 211, 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, 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, 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, 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, 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, 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, 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, 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, 71, 89, 80, 84, 79, 76, - 79, 71, 73, 67, 65, 204, 69, 71, 73, 82, 128, 69, 71, 71, 128, 69, 69, + 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, 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, 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, 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, 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, 66, 69, 70, 73, 76, 73, 128, - 69, 65, 83, 84, 69, 82, 206, 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, 69, 128, 68, 90, 90, 65, 128, 68, 90, 87, 69, 128, 68, 90, - 85, 128, 68, 90, 79, 128, 68, 90, 74, 69, 128, 68, 90, 73, 128, 68, 90, + 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, 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, 65, 128, 68, 90, 65, 128, 68, 90, - 128, 68, 218, 68, 89, 79, 128, 68, 89, 207, 68, 89, 69, 72, 128, 68, 89, - 69, 200, 68, 87, 79, 128, 68, 87, 69, 128, 68, 87, 65, 128, 68, 86, 73, + 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, 128, 68, 85, - 204, 68, 85, 72, 128, 68, 85, 71, 85, 68, 128, 68, 85, 66, 50, 128, 68, - 85, 66, 128, 68, 85, 194, 68, 82, 89, 128, 68, 82, 217, 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, - 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, 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, 45, 80, 79, 73, + 204, 68, 85, 72, 128, 68, 85, 71, 85, 68, 128, 68, 85, 199, 68, 85, 66, + 50, 128, 68, 85, 66, 128, 68, 85, 194, 68, 82, 89, 128, 68, 82, 217, 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, 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, 45, 80, 79, 73, 78, 84, 73, 78, 199, 68, 79, 87, 78, 128, 68, 79, 86, 69, 128, 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, 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, + 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, 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, @@ -3952,392 +4286,436 @@ static unsigned char lexicon[] = { 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, 71, 128, 68, 79, 199, 68, 79, 69, 211, 68, 79, 68, 69, 75, - 65, 84, 65, 128, 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, 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, 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, 65, 84, 73, 79, 78, 128, 68, 73, 86, 73, 68, - 69, 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, 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, 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, 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, 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, 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, 71, 79, 78, 65, 204, 68, 73, 65, 69, 82, 69, 83, 73, 90, 69, - 196, 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, 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, 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, 203, 68, 69, 83, 73, 71, 78, - 128, 68, 69, 83, 73, 128, 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, 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, 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, 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, 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, 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, 73, 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, 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, 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, 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, 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, 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, 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, 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, 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, 128, 67, 89, - 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, 82, 88, 128, 67, 85, 82, 86, 73, 78, 199, 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, 128, - 67, 85, 82, 128, 67, 85, 80, 128, 67, 85, 79, 88, 128, 67, 85, 79, 80, - 128, 67, 85, 79, 128, 67, 85, 205, 67, 85, 66, 69, 68, 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, 128, 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, 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, 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, 67, 85, 211, 67, 82, 79, 67, 79, 68, 73, 76, - 69, 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, 67, 75, 69, 82, 128, 67, 82, 128, 67, 79, - 88, 128, 67, 79, 87, 128, 67, 79, 215, 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, 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, 69, 82, 83, 128, 67, 79, 82, 78, 69, 82, - 128, 67, 79, 82, 78, 69, 210, 67, 79, 80, 89, 82, 73, 71, 72, 84, 128, - 67, 79, 80, 89, 82, 73, 71, 72, 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, 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, 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, 73, 67, 65, 204, 67, 79, 78, 71, 82, 85, 69, 78, + 128, 68, 79, 73, 128, 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, 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, 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, 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, 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, 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, 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, + 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, 73, 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, 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, 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, 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, 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, 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, 128, 67, + 85, 82, 128, 67, 85, 80, 80, 69, 68, 128, 67, 85, 80, 80, 69, 196, 67, + 85, 79, 88, 128, 67, 85, 79, 80, 128, 67, 85, 79, 128, 67, 85, 205, 67, + 85, 66, 69, 68, 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, 85, 128, + 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, 67, 85, 211, 67, 82, 79, 67, 79, 68, 73, 76, 69, 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, 67, 75, 69, 82, 128, 67, 82, 65, 66, + 128, 67, 82, 128, 67, 79, 88, 128, 67, 79, 87, 128, 67, 79, 215, 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, 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, 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, 78, 128, 67, 79, 77, 80, 85, 84, 69, - 82, 128, 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, 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, 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, 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, 75, 84, 65, 73, 204, 67, 79, 65, 83, 84, 69, 82, 128, 67, 79, - 65, 128, 67, 79, 128, 67, 77, 128, 67, 205, 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, 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, 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, 87, 128, 67, 76, 65, 80, 80, 73, 78, 199, 67, 76, 65, 80, 80, 69, - 210, 67, 76, 65, 78, 128, 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, 197, 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, 69, 83, 128, 67, - 73, 82, 67, 76, 69, 128, 67, 73, 80, 128, 67, 73, 78, 78, 65, 66, 65, 82, - 128, 67, 73, 78, 69, 77, 65, 128, 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, 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, 88, 128, 67, 72, 79, 84, 128, 67, 72, - 79, 82, 69, 86, 77, 193, 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, 207, 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, 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, - 211, 67, 72, 69, 82, 82, 217, 67, 72, 69, 82, 82, 73, 69, 83, 128, 67, + 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, 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, 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, 75, 84, + 65, 73, 204, 67, 79, 65, 83, 84, 69, 82, 128, 67, 79, 65, 128, 67, 77, + 128, 67, 205, 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, 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, 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, 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, 207, 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, 206, 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, 82, 73, 78, 199, 67, 72, - 69, 69, 128, 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, 128, 67, 72, 65, 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, 75, 77, 193, 67, 72, 65, 73, 82, 128, 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, 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, 196, 67, - 69, 78, 84, 82, 69, 128, 67, 69, 78, 84, 82, 197, 67, 69, 78, 128, 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, - 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, - 128, 67, 65, 84, 65, 87, 65, 128, 67, 65, 84, 128, 67, 65, 212, 67, 65, - 83, 84, 76, 69, 128, 67, 65, 82, 89, 83, 84, 73, 65, 206, 67, 65, 82, 84, - 128, 67, 65, 82, 211, 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, 79, - 128, 67, 65, 80, 73, 84, 65, 76, 128, 67, 65, 78, 84, 73, 76, 76, 65, 84, - 73, 79, 206, 67, 65, 78, 199, 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, - 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, 78, 85, 195, 67, 65, 77, 69, 82, 65, 128, 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, 69, 78, 68, 65, 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, 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, 212, 66, 85, 83, 84, 211, - 66, 85, 83, 212, 66, 85, 83, 83, 89, 69, 82, 85, 128, 66, 85, 211, 66, - 85, 82, 213, 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, 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, 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, 67, 75, - 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, 72, 128, 66, 82, 85, 83, - 200, 66, 82, 79, 78, 90, 69, 128, 66, 82, 79, 75, 69, 206, 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, 67, 65, 83, 69, 128, 66, 82, 73, 68, 71, - 197, 66, 82, 73, 68, 197, 66, 82, 73, 67, 75, 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, 75, 84, 72, 82, 79, 85, - 71, 72, 128, 66, 82, 69, 65, 68, 128, 66, 82, 68, 193, 66, 82, 65, 78, - 67, 72, 73, 78, 199, 66, 82, 65, 78, 67, 72, 128, 66, 82, 65, 78, 67, - 200, 66, 82, 65, 75, 67, 69, 84, 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, 128, 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, 73, 78, 199, 66, 79, 215, 66, 79, 85, 81, 85, 69, 84, 128, - 66, 79, 85, 78, 68, 65, 82, 217, 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, 65, 82, 128, - 66, 79, 65, 128, 66, 76, 85, 69, 128, 66, 76, 85, 197, 66, 76, 79, 87, - 70, 73, 83, 72, 128, 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, 69, 78, 68, - 69, 196, 66, 76, 65, 78, 75, 128, 66, 76, 65, 78, 203, 66, 76, 65, 68, - 197, 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, 83, 77, 85, 84, 200, 66, 73, 83, - 77, 73, 76, 76, 65, 200, 66, 73, 83, 72, 79, 80, 128, 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, 68, 128, - 66, 73, 79, 72, 65, 90, 65, 82, 196, 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, 65, 82, 68, 83, 128, 66, 73, 76, 65, 66, 73, 65, + 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, 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, 82, 128, 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, 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, + 82, 73, 68, 71, 69, 128, 67, 65, 82, 84, 128, 67, 65, 82, 211, 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, 199, 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, + 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, 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, 78, 90, 69, 128, + 66, 82, 79, 75, 69, 206, 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, 67, 65, + 83, 69, 128, 66, 82, 73, 68, 71, 197, 66, 82, 73, 68, 197, 66, 82, 73, + 67, 75, 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, 75, 84, 72, 82, 79, 85, 71, 72, 128, 66, 82, 69, 65, 68, 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, 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, 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, 69, 78, 68, 69, 196, 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, + 83, 77, 85, 84, 200, 66, 73, 83, 77, 73, 76, 76, 65, 200, 66, 73, 83, 72, + 79, 80, 128, 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, 68, 128, 66, 73, 79, 72, 65, 90, 65, 82, 196, + 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, 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, @@ -4351,178 +4729,186 @@ static unsigned char lexicon[] = { 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, 68, 69, - 128, 66, 69, 78, 68, 128, 66, 69, 206, 66, 69, 76, 84, 128, 66, 69, 76, - 212, 66, 69, 76, 79, 215, 66, 69, 76, 76, 128, 66, 69, 76, 204, 66, 69, - 76, 71, 84, 72, 79, 210, 66, 69, 76, 128, 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, + 66, 69, 78, 90, 69, 78, 197, 66, 69, 78, 84, 207, 66, 69, 78, 84, 128, + 66, 69, 78, 212, 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, 210, 66, 69, 65, - 78, 128, 66, 69, 65, 77, 69, 196, 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, 75, 69, 84, 66, 65, 76, 204, 66, 65, 83, 72, 75, 73, - 210, 66, 65, 83, 72, 128, 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, 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, 194, 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, 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, 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, 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, 128, 66, 65, 71, 71, - 65, 71, 197, 66, 65, 71, 65, 128, 66, 65, 71, 51, 128, 66, 65, 199, 66, - 65, 68, 71, 69, 82, 128, 66, 65, 68, 71, 69, 128, 66, 65, 68, 128, 66, - 65, 67, 84, 82, 73, 65, 206, 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, 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, 57, 128, 66, - 50, 53, 56, 128, 66, 50, 53, 55, 128, 66, 50, 53, 54, 128, 66, 50, 53, - 53, 128, 66, 50, 53, 180, 66, 50, 53, 51, 128, 66, 50, 53, 50, 128, 66, - 50, 53, 49, 128, 66, 50, 53, 48, 128, 66, 50, 52, 57, 128, 66, 50, 52, - 56, 128, 66, 50, 52, 183, 66, 50, 52, 54, 128, 66, 50, 52, 53, 128, 66, - 50, 52, 179, 66, 50, 52, 178, 66, 50, 52, 177, 66, 50, 52, 176, 66, 50, - 51, 54, 128, 66, 50, 51, 52, 128, 66, 50, 51, 179, 66, 50, 51, 50, 128, - 66, 50, 51, 177, 66, 50, 51, 176, 66, 50, 50, 57, 128, 66, 50, 50, 56, - 128, 66, 50, 50, 55, 128, 66, 50, 50, 54, 128, 66, 50, 50, 181, 66, 50, - 50, 50, 128, 66, 50, 50, 49, 128, 66, 50, 50, 176, 66, 50, 49, 57, 128, - 66, 50, 49, 56, 128, 66, 50, 49, 55, 128, 66, 50, 49, 54, 128, 66, 50, - 49, 53, 128, 66, 50, 49, 52, 128, 66, 50, 49, 51, 128, 66, 50, 49, 50, - 128, 66, 50, 49, 49, 128, 66, 50, 49, 48, 128, 66, 50, 48, 57, 128, 66, - 50, 48, 56, 128, 66, 50, 48, 55, 128, 66, 50, 48, 54, 128, 66, 50, 48, - 53, 128, 66, 50, 48, 52, 128, 66, 50, 48, 51, 128, 66, 50, 48, 50, 128, - 66, 50, 48, 49, 128, 66, 50, 48, 48, 128, 66, 49, 57, 177, 66, 49, 57, - 48, 128, 66, 49, 56, 57, 128, 66, 49, 56, 53, 128, 66, 49, 56, 52, 128, - 66, 49, 56, 51, 128, 66, 49, 56, 50, 128, 66, 49, 56, 49, 128, 66, 49, - 56, 48, 128, 66, 49, 55, 57, 128, 66, 49, 55, 56, 128, 66, 49, 55, 55, - 128, 66, 49, 55, 182, 66, 49, 55, 52, 128, 66, 49, 55, 179, 66, 49, 55, - 50, 128, 66, 49, 55, 49, 128, 66, 49, 55, 48, 128, 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, 69, 210, 65, 89, 66, 128, 65, 89, 65, 72, 128, 65, 88, - 69, 128, 65, 87, 69, 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, 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, 79, 205, 65, 84, 78, 65, 200, 65, 84, 77, - 65, 65, 85, 128, 65, 84, 73, 89, 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, 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, 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, 178, 65, 83, 67, 69, 78, 84, + 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, 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, 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, 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, 83, 128, 66, 65, 71, 71, 65, 71, 197, 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, 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, + 57, 128, 66, 50, 53, 56, 128, 66, 50, 53, 55, 128, 66, 50, 53, 54, 128, + 66, 50, 53, 53, 128, 66, 50, 53, 180, 66, 50, 53, 51, 128, 66, 50, 53, + 50, 128, 66, 50, 53, 49, 128, 66, 50, 53, 48, 128, 66, 50, 52, 57, 128, + 66, 50, 52, 56, 128, 66, 50, 52, 183, 66, 50, 52, 54, 128, 66, 50, 52, + 53, 128, 66, 50, 52, 179, 66, 50, 52, 178, 66, 50, 52, 177, 66, 50, 52, + 176, 66, 50, 51, 54, 128, 66, 50, 51, 52, 128, 66, 50, 51, 179, 66, 50, + 51, 50, 128, 66, 50, 51, 177, 66, 50, 51, 176, 66, 50, 50, 57, 128, 66, + 50, 50, 56, 128, 66, 50, 50, 55, 128, 66, 50, 50, 54, 128, 66, 50, 50, + 181, 66, 50, 50, 50, 128, 66, 50, 50, 49, 128, 66, 50, 50, 176, 66, 50, + 49, 57, 128, 66, 50, 49, 56, 128, 66, 50, 49, 55, 128, 66, 50, 49, 54, + 128, 66, 50, 49, 53, 128, 66, 50, 49, 52, 128, 66, 50, 49, 51, 128, 66, + 50, 49, 50, 128, 66, 50, 49, 49, 128, 66, 50, 49, 48, 128, 66, 50, 48, + 57, 128, 66, 50, 48, 56, 128, 66, 50, 48, 55, 128, 66, 50, 48, 54, 128, + 66, 50, 48, 53, 128, 66, 50, 48, 52, 128, 66, 50, 48, 51, 128, 66, 50, + 48, 50, 128, 66, 50, 48, 49, 128, 66, 50, 48, 48, 128, 66, 49, 57, 177, + 66, 49, 57, 48, 128, 66, 49, 56, 57, 128, 66, 49, 56, 53, 128, 66, 49, + 56, 52, 128, 66, 49, 56, 51, 128, 66, 49, 56, 50, 128, 66, 49, 56, 49, + 128, 66, 49, 56, 48, 128, 66, 49, 55, 57, 128, 66, 49, 55, 56, 128, 66, + 49, 55, 55, 128, 66, 49, 55, 182, 66, 49, 55, 52, 128, 66, 49, 55, 179, + 66, 49, 55, 50, 128, 66, 49, 55, 49, 128, 66, 49, 55, 48, 128, 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, 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, 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, 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, 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, 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, 82, 85, 72, 85, 65, 128, 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, 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, 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, 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, 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, + 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, 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, 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, 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, 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, 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, + 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, 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, 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, @@ -4530,15308 +4916,18348 @@ static unsigned char lexicon[] = { 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, 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, 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, - 75, 72, 65, 78, 75, 72, 85, 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, 77, 80, 83, 128, 65, 77, - 80, 69, 82, 83, 65, 78, 68, 128, 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, 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, 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, 77, 128, 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, 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, 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, 84, - 79, 206, 65, 73, 82, 80, 76, 65, 78, 69, 128, 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, 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, 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, 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, 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, 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, 178, 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, 48, 55, 48, 128, 65, 48, - 54, 57, 128, 65, 48, 54, 56, 128, 65, 48, 54, 55, 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, 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, 128, 65, 48, 52, 48, 65, 128, 65, 48, 52, - 48, 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, 49, 55, 65, 128, 65, 48, - 49, 52, 65, 128, 65, 48, 48, 54, 66, 128, 65, 48, 48, 54, 65, 128, 65, - 48, 48, 53, 65, 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, + 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, 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, 69, 68, 128, 65, + 78, 71, 76, 69, 196, 65, 78, 71, 75, 72, 65, 78, 75, 72, 85, 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, 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, + 77, 128, 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, 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, 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, 77, 73, 83, 83, 73, 79, 206, 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, 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, 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, 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 unsigned int lexicon_offset[] = { - 0, 0, 6, 10, 18, 23, 27, 34, 39, 41, 47, 50, 62, 70, 80, 93, 102, 108, - 113, 121, 130, 135, 140, 143, 147, 153, 158, 163, 171, 178, 186, 191, - 194, 200, 208, 215, 225, 230, 237, 246, 249, 254, 257, 263, 267, 272, - 281, 288, 295, 301, 310, 315, 321, 327, 335, 144, 341, 349, 350, 358, - 361, 367, 369, 375, 382, 384, 391, 395, 403, 410, 412, 417, 422, 427, - 434, 436, 299, 442, 445, 447, 452, 457, 463, 470, 479, 489, 494, 498, - 505, 518, 522, 531, 538, 545, 548, 554, 558, 562, 572, 580, 588, 596, - 605, 613, 618, 619, 623, 631, 638, 648, 652, 663, 667, 670, 673, 678, - 348, 682, 691, 697, 703, 705, 708, 711, 714, 718, 722, 731, 739, 744, - 747, 751, 757, 764, 771, 776, 785, 794, 801, 805, 818, 827, 835, 841, - 557, 850, 860, 867, 873, 879, 886, 894, 898, 749, 906, 915, 503, 923, - 928, 934, 17, 943, 948, 951, 955, 959, 966, 969, 976, 980, 988, 992, - 1000, 1004, 1007, 1014, 1021, 192, 1024, 1029, 1039, 1048, 1055, 1060, - 1066, 1072, 1080, 1083, 1088, 1094, 1102, 1107, 1110, 1113, 111, 1118, - 1122, 1128, 1134, 1137, 1143, 1147, 1152, 1158, 1168, 1172, 1175, 1178, - 1187, 1191, 1194, 1199, 1204, 1210, 1215, 1220, 1225, 1229, 1234, 1240, - 1245, 1250, 1254, 1260, 1265, 1270, 1275, 1279, 1284, 1289, 1294, 1300, - 1306, 1312, 1317, 1321, 1326, 1331, 1336, 1340, 1345, 1350, 1355, 1360, - 1195, 1200, 1205, 1211, 1216, 1364, 1226, 1370, 1375, 1380, 1387, 1391, - 1400, 1230, 1404, 1235, 1241, 1246, 1408, 1413, 1418, 1422, 1426, 1432, - 1436, 1251, 1439, 1261, 1444, 1448, 1266, 1454, 1271, 1458, 1462, 1276, - 1466, 1471, 1475, 1478, 1482, 1280, 1285, 1487, 1290, 1493, 1499, 1505, - 1511, 1295, 1307, 1313, 1515, 1519, 1523, 1526, 1318, 1530, 1532, 1537, - 1542, 1548, 1553, 1558, 1562, 1567, 1572, 1577, 1582, 1588, 1593, 1598, - 1604, 1610, 1615, 1619, 1624, 1629, 1634, 1639, 1643, 1651, 1655, 1660, - 1665, 1670, 1675, 1679, 1682, 1687, 1692, 1697, 1702, 1708, 1713, 1717, - 1322, 1720, 1725, 1730, 1327, 1734, 1738, 1745, 1332, 1752, 1337, 1756, - 1758, 1763, 1769, 1341, 1774, 1783, 1346, 1788, 1794, 1351, 1799, 1804, - 1807, 1812, 1816, 1820, 1824, 1827, 1831, 1356, 1361, 1058, 1836, 1842, - 1848, 1854, 1860, 1866, 1872, 1878, 1884, 1889, 1895, 1901, 1907, 1913, - 1919, 1925, 1931, 1937, 1943, 1948, 1953, 1958, 1963, 1968, 1973, 1978, - 1983, 1988, 1993, 1999, 2004, 2010, 2015, 2021, 2027, 2032, 2038, 2044, - 2050, 2056, 2061, 2066, 2068, 2069, 2073, 2077, 2082, 2086, 2090, 2094, - 2099, 2103, 2106, 2111, 2115, 2120, 2124, 2128, 2133, 2137, 2140, 2144, - 2150, 2164, 2168, 2172, 2176, 2179, 2184, 2188, 2192, 2195, 2199, 2204, - 2209, 2214, 2219, 2223, 2227, 2231, 2236, 2240, 2245, 2249, 2254, 2260, - 2267, 2273, 2278, 2283, 2288, 2294, 2299, 2305, 2310, 2313, 1212, 2315, - 2322, 2330, 2340, 2349, 2363, 2367, 2371, 2384, 2392, 2396, 2401, 2405, - 2408, 2412, 2416, 2421, 2426, 2431, 2435, 2438, 2442, 2449, 2456, 2462, - 2467, 2472, 2478, 2484, 2489, 2492, 1760, 2494, 2500, 2504, 2509, 2513, - 2517, 1765, 1771, 2522, 2526, 2529, 2534, 2539, 2544, 2549, 2553, 2560, - 2565, 2568, 2575, 2581, 2585, 2589, 2593, 2598, 2605, 2610, 2615, 2622, - 2628, 2634, 2640, 2654, 2671, 2686, 2701, 2710, 2715, 2719, 2724, 2729, - 2733, 2745, 2752, 2758, 2263, 2764, 2771, 2777, 2781, 2784, 2791, 2797, - 2801, 2805, 2809, 2091, 2813, 2818, 2823, 2827, 2835, 2839, 2843, 2847, - 2851, 2856, 2861, 2866, 2870, 2875, 2880, 2884, 2889, 2893, 2896, 2900, - 2904, 2912, 2917, 2921, 2925, 2931, 2940, 2944, 2948, 2954, 2959, 2966, - 2970, 2980, 2984, 2988, 2993, 2997, 3002, 3008, 3013, 3017, 3021, 3025, - 2452, 3033, 3038, 3044, 3049, 3053, 3058, 3063, 3067, 3073, 3078, 2095, - 3084, 3090, 3095, 3100, 3105, 3110, 3115, 3120, 3125, 3130, 3135, 3141, - 3146, 1227, 92, 3152, 3156, 3160, 3164, 3169, 3173, 3177, 3181, 3185, - 3190, 3194, 3199, 3203, 3206, 3210, 3215, 3219, 3224, 3228, 3232, 3236, - 3241, 3245, 3248, 3261, 3265, 3269, 3273, 3277, 3281, 3284, 3288, 3292, - 3297, 3301, 3306, 3311, 3316, 3320, 3323, 3326, 3332, 3336, 3340, 3343, - 3347, 3351, 3354, 3360, 3365, 3370, 3376, 3381, 3386, 3392, 3398, 3403, - 3408, 3413, 1120, 547, 3418, 3421, 3426, 3430, 3433, 3437, 3442, 3447, - 3451, 3456, 3460, 3465, 3469, 3473, 3479, 3485, 3488, 3491, 3497, 3504, - 3511, 3517, 3524, 3529, 3533, 3540, 3547, 3552, 3556, 3566, 3570, 3574, - 3579, 3584, 3594, 2107, 3599, 3603, 3606, 3612, 3617, 3623, 3629, 3634, - 3641, 3645, 3649, 620, 671, 1388, 3653, 3660, 3667, 3674, 3681, 3687, - 3693, 3698, 3702, 3708, 3713, 3717, 2116, 3721, 3729, 600, 3735, 3746, - 3750, 3760, 2121, 3766, 3771, 3786, 3792, 3799, 3809, 3815, 3820, 3826, - 3832, 3835, 3839, 3844, 3851, 3856, 3860, 3864, 3868, 3872, 3877, 3883, - 3894, 3211, 3899, 3911, 3919, 3924, 1564, 3931, 3934, 3937, 3941, 3944, - 3950, 3954, 3968, 3972, 3975, 3979, 3985, 3991, 3996, 4000, 4004, 4010, - 4021, 4027, 4032, 4038, 4042, 4050, 4060, 4066, 4071, 4080, 4088, 4095, - 4099, 4105, 4114, 4123, 4127, 4132, 4137, 4141, 4149, 4153, 4158, 4162, - 2129, 1401, 4168, 4173, 4179, 4184, 4189, 4194, 4199, 4204, 4209, 4215, - 4220, 4226, 4231, 4236, 4241, 4247, 4252, 4257, 4262, 4267, 4273, 4278, - 4284, 4289, 4294, 4299, 4304, 4309, 4314, 4320, 4325, 4330, 319, 456, - 4335, 4341, 4345, 4349, 4354, 4358, 4362, 4365, 4369, 4373, 4377, 4381, - 4386, 4390, 4394, 4400, 4165, 4405, 4409, 4412, 4417, 4422, 4427, 4432, - 4437, 4442, 4447, 4452, 4457, 4462, 4466, 4471, 4476, 4481, 4486, 4491, - 4496, 4501, 4506, 4511, 4516, 4520, 4525, 4530, 4535, 4540, 4545, 4550, - 4555, 4560, 4565, 4570, 4574, 4579, 4584, 4589, 4594, 4599, 4604, 4609, - 4614, 4619, 4624, 4628, 4633, 4638, 4643, 4648, 4653, 4658, 4663, 4668, - 4673, 4678, 4682, 4687, 4692, 4697, 4702, 4707, 4712, 4717, 4722, 4727, - 4732, 4736, 4741, 4746, 4751, 4756, 4761, 4766, 4771, 4776, 4781, 4786, - 4790, 4795, 4800, 4805, 4810, 4816, 4822, 4828, 4834, 4840, 4846, 4852, - 4857, 4863, 4869, 4875, 4881, 4887, 4893, 4899, 4905, 4911, 4917, 4922, - 4928, 4934, 4940, 4946, 4952, 4958, 4964, 4970, 4976, 4982, 4987, 4993, - 4999, 5005, 5011, 5017, 5023, 5029, 5035, 5041, 5047, 5052, 5058, 5064, - 5070, 5076, 5082, 5088, 5094, 5100, 5106, 5112, 5117, 5123, 5129, 5135, - 5141, 5147, 5153, 5159, 5165, 5171, 5177, 5182, 5186, 5192, 5198, 5204, - 5210, 5216, 5222, 5228, 5234, 5240, 5246, 5251, 5257, 5263, 5269, 5275, - 5281, 5287, 5293, 5299, 5305, 5311, 5316, 5322, 5328, 5334, 5340, 5346, - 5352, 5358, 5364, 5370, 5376, 5381, 5387, 5393, 5399, 5405, 5411, 5417, - 5423, 5429, 5435, 5441, 5446, 5452, 5458, 5464, 5470, 5476, 5482, 5488, - 5494, 5500, 5506, 5511, 5517, 5523, 5529, 5535, 5541, 5547, 5553, 5559, - 5565, 5571, 5576, 5582, 5588, 5594, 5600, 5606, 5612, 5618, 5624, 5630, - 5636, 5641, 5647, 5653, 5659, 5665, 5671, 5677, 5683, 5689, 5695, 5701, - 5706, 5712, 5718, 5724, 5730, 5736, 5742, 5748, 5754, 5760, 5766, 5771, - 5777, 5783, 5789, 5795, 5801, 5807, 5813, 5819, 5825, 5831, 5836, 5840, - 5843, 5850, 5854, 5867, 5871, 5875, 5879, 5883, 5887, 5891, 5897, 5904, - 5912, 5916, 5924, 5933, 5939, 5951, 5956, 5959, 5963, 5973, 5981, 5989, - 5995, 5999, 6009, 6019, 6027, 6034, 6041, 6047, 6053, 6060, 6064, 6071, - 6081, 6091, 6099, 6106, 6111, 6115, 6123, 6127, 6132, 6139, 6147, 6152, - 6157, 6161, 6168, 6173, 6187, 6192, 6197, 6204, 6213, 6216, 6220, 6224, - 6228, 6231, 6236, 6241, 6250, 6256, 6262, 6268, 6272, 6283, 6293, 6308, - 6323, 6338, 6353, 6368, 6383, 6398, 6413, 6428, 6443, 6458, 6473, 6488, - 6503, 6518, 6533, 6548, 6563, 6578, 6593, 6608, 6623, 6638, 6653, 6668, - 6683, 6698, 6713, 6728, 6743, 6758, 6773, 6788, 6803, 6818, 6833, 6848, - 6863, 6878, 6893, 6908, 6923, 6938, 6953, 6968, 6983, 6998, 7013, 7028, - 7037, 7046, 7051, 7057, 7067, 7071, 7076, 7081, 7089, 7093, 7096, 7100, - 2975, 7103, 7108, 298, 425, 7114, 7122, 7126, 7130, 7133, 7137, 7143, - 7147, 7155, 7161, 7166, 7173, 7180, 7186, 7191, 7198, 7204, 7212, 7216, - 7221, 7233, 7244, 7251, 7255, 7259, 7265, 3233, 7269, 7275, 7280, 7285, - 7290, 7296, 7301, 7306, 7311, 7316, 7322, 7327, 7332, 7338, 7343, 7349, - 7354, 7360, 7365, 7371, 7376, 7381, 7386, 7391, 7396, 7402, 7407, 7412, - 7417, 7423, 7429, 7435, 7441, 7447, 7453, 7459, 7465, 7471, 7477, 7483, - 7489, 7494, 7499, 7504, 7509, 7514, 7519, 7524, 7529, 7535, 7541, 7546, - 7552, 7558, 7564, 7569, 7574, 7579, 7584, 7590, 7596, 7601, 7606, 7611, - 7616, 7621, 7627, 7632, 7638, 7644, 7650, 7656, 7662, 7668, 7674, 7680, - 7686, 2138, 7132, 7691, 7695, 7699, 7702, 7709, 7712, 7720, 7725, 7730, - 7721, 7735, 2165, 7739, 7745, 7751, 7756, 7761, 7768, 7776, 7781, 7785, - 7788, 7792, 7798, 7804, 7808, 2173, 560, 7811, 7815, 7820, 7826, 7831, - 7835, 7838, 7842, 7848, 7853, 7857, 7864, 7868, 7872, 7876, 945, 769, - 7879, 7887, 7894, 7901, 7907, 7914, 7922, 7929, 7936, 7941, 7953, 1247, - 1409, 1414, 7964, 1419, 7968, 7972, 7981, 7989, 7998, 8004, 8009, 8013, - 8019, 8024, 2706, 8031, 8035, 8044, 8053, 8062, 8071, 8076, 8081, 8093, - 8098, 8106, 2224, 8110, 8112, 8117, 8121, 8130, 8138, 1423, 133, 3461, - 3466, 8144, 8148, 8157, 8163, 8168, 8171, 8180, 2698, 8186, 8194, 8198, - 8202, 8206, 2237, 8210, 8215, 8222, 8228, 8234, 8237, 8239, 8242, 8250, - 8258, 8266, 8269, 8274, 2250, 8279, 7732, 8282, 8284, 8289, 8294, 8299, - 8304, 8309, 8314, 8319, 8324, 8329, 8334, 8340, 8345, 8350, 8355, 8361, - 8366, 8371, 8376, 8381, 8386, 8391, 8397, 8402, 8407, 8412, 8417, 8422, - 8427, 8432, 8437, 8442, 8447, 8452, 8457, 8462, 8467, 8472, 8477, 8482, - 8488, 8494, 8499, 8504, 8509, 8514, 8519, 2261, 2268, 2274, 8524, 8530, - 8538, 2300, 2306, 8546, 8550, 8555, 8559, 8563, 8567, 8572, 8576, 8581, - 8585, 8588, 8591, 8597, 8603, 8609, 8615, 8621, 8627, 8633, 8637, 8641, - 8645, 8649, 8653, 8658, 8665, 8676, 8684, 8694, 8700, 8707, 8712, 8716, - 8727, 8740, 8751, 8764, 8775, 8787, 8799, 8811, 8824, 8837, 8844, 8850, - 8864, 8871, 8877, 8881, 8886, 8890, 8897, 8905, 8909, 8915, 8919, 8925, - 8935, 8939, 8944, 8949, 8956, 8962, 8972, 7909, 8978, 8982, 8989, 8996, - 768, 9000, 9004, 9009, 9014, 9019, 9023, 9029, 9037, 9043, 9047, 9053, - 9063, 9067, 9073, 9078, 9082, 9088, 9094, 2161, 9099, 9101, 9106, 9114, - 9123, 9127, 9133, 9138, 9143, 9148, 9153, 9159, 9164, 9169, 4006, 9174, - 9179, 9183, 9189, 9194, 9200, 9205, 9210, 9216, 9221, 9128, 9227, 9231, - 9238, 9244, 9249, 9253, 6183, 9258, 9267, 9272, 9277, 8218, 8225, 9282, - 2853, 9286, 9291, 9296, 9139, 9300, 9305, 9144, 9149, 9310, 9317, 9324, - 9330, 9336, 9342, 9347, 9352, 9357, 9154, 9160, 9363, 9369, 9374, 9382, - 9165, 9387, 990, 9390, 9398, 9404, 9410, 9419, 9427, 9432, 9438, 9446, - 9453, 9468, 9485, 9504, 9513, 9521, 9536, 9547, 9557, 9567, 9575, 9581, - 9593, 9602, 9610, 9617, 9624, 9630, 9635, 9643, 9653, 9660, 9670, 9680, - 9690, 9698, 9705, 9714, 9724, 9738, 9753, 9762, 9770, 9775, 9779, 9788, - 9794, 9799, 9809, 9819, 9829, 9834, 9838, 9847, 9852, 9862, 9873, 9886, - 9894, 9907, 9919, 9927, 9932, 9936, 9942, 9947, 9955, 9963, 9970, 9975, - 9983, 9989, 9992, 9996, 10002, 10010, 10015, 10019, 10027, 10036, 10044, - 10050, 10054, 10061, 10072, 10076, 10079, 10085, 9170, 10090, 10096, - 10103, 10109, 10114, 10121, 10128, 10135, 10142, 10149, 10156, 10163, - 10170, 10175, 9481, 10180, 10186, 10193, 10200, 10205, 10212, 10221, - 10225, 10237, 8256, 10241, 10244, 10248, 10252, 10256, 10260, 10266, - 10272, 10277, 10283, 10288, 10293, 10299, 10304, 10309, 8952, 10314, - 10318, 10322, 10326, 10331, 10336, 10344, 10350, 10354, 10358, 10365, - 10370, 10378, 10383, 10387, 10390, 10396, 10403, 10407, 10410, 10415, - 10419, 4045, 10425, 10434, 36, 10442, 10448, 10453, 8967, 10458, 10463, - 10467, 10470, 10485, 10504, 10516, 10529, 10542, 10555, 10569, 10582, - 10597, 10604, 9175, 10610, 10624, 10629, 10635, 10640, 10648, 10653, - 8040, 10658, 10661, 10668, 10673, 10677, 2858, 998, 10683, 10687, 10693, - 10699, 10704, 10710, 10715, 9184, 10721, 10727, 10732, 10737, 10745, - 10751, 10764, 10772, 10779, 9190, 10785, 10793, 10801, 10808, 10821, - 10833, 10843, 10851, 10858, 10865, 10874, 10883, 10891, 10898, 10903, - 10909, 9195, 10914, 10920, 9201, 10925, 10928, 10935, 10941, 10954, 8669, - 10965, 10971, 10980, 10988, 10995, 11001, 11007, 11012, 11016, 11021, - 10477, 11027, 9206, 11034, 11039, 11046, 11052, 11058, 11063, 11071, - 11079, 11086, 11090, 11104, 11114, 11119, 11123, 11134, 11140, 11145, - 11150, 9211, 9217, 11154, 11157, 11162, 11174, 11181, 11186, 11190, - 11195, 11199, 11206, 11212, 9222, 9129, 11219, 2863, 8, 11226, 11231, - 11235, 11241, 11249, 11259, 11264, 11269, 11276, 11283, 11287, 11298, - 11308, 11317, 11329, 11334, 11338, 11346, 11360, 11364, 11367, 11375, - 11382, 11390, 11394, 11405, 11409, 11416, 11421, 11425, 11431, 11436, - 11440, 11446, 11451, 11462, 11466, 11469, 11475, 11480, 11486, 11492, - 11499, 11510, 11520, 11530, 11539, 11546, 11555, 9232, 9239, 9245, 9250, - 11561, 11567, 9254, 11573, 11576, 11583, 11588, 11603, 11619, 11634, - 11642, 11648, 11653, 838, 420, 11658, 11666, 11673, 11679, 11684, 11689, - 9259, 11691, 11695, 11700, 11704, 11714, 11719, 11723, 11732, 11736, - 11739, 9268, 11746, 11749, 11757, 11764, 11772, 11776, 11783, 11792, - 11795, 11799, 11803, 11809, 11813, 11817, 11821, 11827, 11837, 11841, - 11849, 11853, 11860, 11864, 11869, 11873, 11880, 11886, 11894, 11900, - 11905, 11915, 11920, 11925, 11929, 11937, 3905, 11945, 11950, 9273, - 11954, 11958, 11961, 11969, 11976, 11980, 5991, 11984, 11989, 11993, - 12004, 12014, 12019, 12025, 12029, 12032, 12040, 12045, 12050, 12057, - 12062, 9278, 12067, 12071, 12078, 1722, 6145, 12083, 12088, 12093, 12098, - 12104, 12109, 12115, 12120, 12125, 12130, 12135, 12140, 12145, 12150, - 12155, 12160, 12165, 12170, 12175, 12180, 12185, 12190, 12195, 12201, - 12206, 12211, 12216, 12221, 12226, 12232, 12237, 12242, 12248, 12253, - 12259, 12264, 12270, 12275, 12280, 12285, 12290, 12296, 12301, 12306, - 12311, 737, 139, 12319, 12323, 12328, 12333, 12337, 12341, 12345, 12350, - 12354, 12359, 12363, 12366, 12370, 12374, 12380, 12385, 12395, 12401, - 12409, 12413, 12417, 12424, 12432, 12441, 12452, 12459, 12466, 12470, - 12479, 12488, 12496, 12505, 12514, 12523, 12532, 12542, 12552, 12562, - 12572, 12582, 12591, 12601, 12611, 12621, 12631, 12641, 12651, 12661, - 12670, 12680, 12690, 12700, 12710, 12720, 12730, 12739, 12749, 12759, - 12769, 12779, 12789, 12799, 12809, 12819, 12829, 12838, 12848, 12858, - 12868, 12878, 12888, 12898, 12908, 12918, 12928, 12938, 12947, 1256, - 12953, 12956, 12960, 12965, 12972, 12978, 12983, 12987, 12992, 13001, - 13009, 13014, 13018, 13022, 13028, 13033, 13039, 9287, 13044, 13049, - 13058, 9292, 13063, 13066, 13072, 13080, 9297, 13087, 13091, 13095, - 13099, 13109, 13115, 13121, 13126, 13135, 13143, 13150, 13157, 13162, - 13169, 13174, 13178, 13181, 13192, 13202, 13211, 13219, 13230, 13242, - 13252, 13257, 13261, 13266, 13271, 13275, 13281, 13289, 13296, 13307, - 13312, 13322, 13326, 13329, 13336, 13346, 13355, 13362, 13366, 13373, - 13379, 13384, 13389, 13393, 13402, 13407, 13413, 13417, 13422, 13426, - 13435, 13443, 13451, 13458, 13466, 13478, 13489, 13499, 13506, 13512, - 13521, 13532, 13541, 13553, 13565, 13577, 13587, 13596, 13605, 13613, - 13620, 13629, 13637, 13641, 13647, 13653, 13658, 7753, 13662, 13664, - 13668, 13673, 13679, 13688, 13692, 13698, 13706, 13713, 13722, 13731, - 13740, 13749, 13758, 13767, 13776, 13785, 13795, 13805, 13814, 13820, - 13827, 13834, 13840, 13854, 13861, 13869, 13878, 13884, 13893, 13902, - 13913, 13923, 13931, 13938, 13946, 13955, 13968, 13976, 13983, 13996, - 14002, 14008, 14018, 14027, 14036, 14041, 14045, 14051, 14057, 14064, - 8966, 14069, 14074, 14081, 14086, 12376, 14091, 14099, 14105, 14110, - 14118, 14126, 14133, 14141, 14147, 14155, 14163, 14169, 14174, 14180, - 14187, 14193, 14198, 14202, 14213, 14221, 14227, 14232, 14241, 14247, - 14252, 14261, 14275, 3853, 14279, 14284, 14289, 14295, 14300, 14305, - 14309, 14314, 14319, 14324, 7752, 14329, 14334, 14339, 14344, 14349, - 14353, 14358, 14363, 14368, 14373, 14379, 14385, 14390, 14394, 14399, - 14404, 14409, 9301, 14414, 14419, 14424, 14429, 14434, 14451, 14469, - 14481, 14494, 14511, 14527, 14544, 14554, 14573, 14584, 14595, 14606, - 14617, 14629, 14640, 14651, 14668, 14679, 14690, 14695, 9306, 14700, - 14704, 2381, 14708, 14711, 14717, 14725, 14733, 14738, 14746, 14754, - 14761, 14766, 14772, 14779, 14787, 14794, 14806, 14814, 14819, 11597, - 14825, 14834, 14843, 14851, 14858, 14864, 14872, 14879, 14885, 14892, - 14898, 14907, 14915, 14925, 14932, 14938, 14946, 14952, 14960, 14967, - 14980, 14987, 14996, 15005, 15014, 15022, 15032, 15039, 15044, 3560, - 15051, 15056, 1372, 15060, 14330, 15064, 15070, 15074, 15082, 15094, - 15099, 15106, 15112, 15117, 15124, 14335, 15128, 15132, 15136, 14340, - 15140, 14345, 15144, 15151, 15156, 15160, 15167, 15171, 15179, 15186, - 15190, 15197, 15214, 15223, 15227, 15230, 15238, 15244, 15249, 3638, - 15253, 15255, 15263, 15270, 15280, 15292, 15297, 15303, 15308, 15312, - 15318, 15323, 15329, 15332, 15339, 15347, 15354, 15360, 15366, 15371, - 15378, 15384, 15389, 15396, 15400, 15406, 15410, 15417, 15423, 15429, - 15437, 15443, 15448, 15454, 15462, 15470, 15476, 15482, 15487, 15494, - 15499, 15503, 15509, 15514, 15521, 15526, 15532, 15535, 15541, 15547, - 15550, 15554, 15566, 15572, 15577, 15584, 15590, 15596, 15607, 15617, - 15626, 15634, 15641, 15652, 15662, 15672, 15680, 15683, 14359, 15688, - 15693, 14364, 14499, 15701, 15714, 15729, 15740, 14516, 15758, 15771, - 15784, 15795, 10492, 15806, 15819, 15838, 15849, 15860, 15871, 2649, - 15884, 15888, 15896, 15911, 15926, 15937, 15944, 15950, 15958, 15962, - 15968, 15971, 15981, 15989, 15996, 16004, 16014, 16019, 16026, 16031, - 16038, 16049, 16059, 16065, 16070, 16075, 14369, 16079, 16085, 16091, - 16096, 16101, 16106, 16110, 14374, 14380, 16114, 14386, 16119, 16127, - 16136, 16143, 9150, 16147, 16149, 16154, 16159, 16165, 16170, 16175, - 16180, 16185, 16189, 16195, 16201, 16206, 16212, 16217, 16222, 16228, - 16233, 16238, 16243, 16248, 16254, 16259, 16264, 16270, 16276, 16281, - 16286, 16293, 16299, 16310, 16317, 16322, 16326, 16330, 16333, 16341, - 16346, 16353, 16360, 16366, 16371, 16376, 16383, 16393, 16398, 16405, - 16411, 16421, 16431, 16445, 16459, 16473, 16487, 16502, 16517, 16534, - 16552, 16565, 16571, 16576, 16581, 16585, 16590, 16598, 16604, 16609, - 16614, 16618, 16623, 16627, 16632, 16636, 16647, 16653, 16658, 16663, - 16670, 16675, 16679, 16684, 16689, 16695, 16702, 16708, 16713, 16717, - 16723, 16728, 16733, 16737, 16743, 16748, 16753, 16760, 16765, 13111, - 16769, 16774, 16778, 16783, 16789, 16795, 16802, 16812, 16820, 16827, - 16832, 16836, 16845, 16853, 16860, 16867, 16873, 16879, 16884, 16889, - 16895, 16900, 16906, 16911, 16917, 16923, 16930, 16936, 16941, 16946, - 9348, 16955, 16958, 16964, 16969, 16974, 16984, 16991, 16997, 17002, - 17007, 17013, 17018, 17024, 17029, 17035, 17041, 17046, 17054, 17061, - 17066, 17071, 17077, 17082, 17086, 17095, 17106, 17113, 17118, 17126, - 17132, 17139, 17145, 17150, 17154, 17160, 17165, 17170, 17175, 1440, - 7777, 2877, 17179, 17183, 17187, 17191, 17195, 17199, 17202, 17209, - 17217, 14400, 17224, 17234, 17242, 17249, 17257, 17267, 17276, 17289, - 17294, 17299, 17307, 17314, 13207, 13216, 17321, 17331, 17346, 17352, - 17359, 17366, 17372, 17380, 17390, 17400, 14405, 17409, 17415, 17421, - 17429, 17437, 17442, 17451, 17459, 17471, 17481, 17491, 17501, 17510, - 17522, 17532, 17542, 17553, 17558, 17570, 17582, 17594, 17606, 17618, - 17630, 17642, 17654, 17666, 17678, 17689, 17701, 17713, 17725, 17737, - 17749, 17761, 17773, 17785, 17797, 17809, 17820, 17832, 17844, 17856, - 17868, 17880, 17892, 17904, 17916, 17928, 17940, 17951, 17963, 17975, - 17987, 17999, 18011, 18023, 18035, 18047, 18059, 18071, 18082, 18094, - 18106, 18118, 18130, 18142, 18154, 18166, 18178, 18190, 18202, 18213, - 18225, 18237, 18249, 18261, 18273, 18285, 18297, 18309, 18321, 18333, - 18344, 18356, 18368, 18380, 18392, 18404, 18416, 18428, 18440, 18452, - 18464, 18475, 18487, 18499, 18511, 18523, 18536, 18549, 18562, 18575, - 18588, 18601, 18614, 18626, 18639, 18652, 18665, 18678, 18691, 18704, - 18717, 18730, 18743, 18756, 18768, 18781, 18794, 18807, 18820, 18833, - 18846, 18859, 18872, 18885, 18898, 18910, 18923, 18936, 18949, 18962, - 18975, 18988, 19001, 19014, 19027, 19040, 19052, 19065, 19078, 19091, - 19104, 19117, 19130, 19143, 19156, 19169, 19182, 19194, 19207, 19220, - 19233, 19246, 19259, 19272, 19285, 19298, 19311, 19324, 19336, 19347, - 19360, 19373, 19386, 19399, 19412, 19425, 19438, 19451, 19464, 19477, - 19489, 19502, 19515, 19528, 19541, 19554, 19567, 19580, 19593, 19606, - 19619, 19631, 19644, 19657, 19670, 19683, 19696, 19709, 19722, 19735, - 19748, 19761, 19773, 19786, 19799, 19812, 19825, 19838, 19851, 19864, - 19877, 19890, 19903, 19915, 19928, 19941, 19954, 19967, 19980, 19993, - 20006, 20019, 20032, 20045, 20057, 20070, 20083, 20096, 20109, 20122, - 20135, 20148, 20161, 20174, 20187, 20199, 20212, 20225, 20238, 20251, - 20264, 20277, 20290, 20303, 20316, 20329, 20341, 20354, 20367, 20380, - 20393, 20406, 20419, 20432, 20445, 20458, 20471, 20483, 20496, 20509, - 20522, 20535, 20548, 20561, 20574, 20587, 20600, 20613, 20625, 20638, - 20651, 20664, 20677, 20690, 20703, 20716, 20729, 20742, 20755, 20767, - 20778, 20786, 20794, 20801, 20807, 20811, 20817, 20823, 20831, 20837, - 20842, 20846, 20855, 9155, 20866, 20873, 20881, 20888, 20895, 10948, - 20902, 20911, 20916, 20921, 7805, 20928, 20933, 20936, 20941, 20949, - 20956, 20963, 20970, 20976, 20985, 20994, 21000, 21009, 21013, 21019, - 21024, 21034, 21041, 21047, 21055, 21061, 21068, 21078, 21087, 21091, - 21098, 21102, 21107, 21113, 21121, 21125, 21135, 14415, 21144, 21150, - 21154, 21163, 14420, 21169, 21176, 21187, 21195, 21204, 21212, 8931, - 21220, 21225, 21231, 21236, 21240, 21244, 21248, 9639, 21253, 21261, - 21268, 21277, 21284, 21291, 10878, 21298, 21304, 21308, 21314, 21321, - 21327, 21335, 21341, 21348, 21354, 21360, 21369, 21373, 21381, 21390, - 21397, 21402, 21406, 21417, 21422, 21427, 21432, 21445, 7995, 21449, - 21455, 21463, 21467, 21474, 21483, 21488, 14691, 21496, 21500, 21512, - 21517, 21521, 21524, 21530, 21536, 21541, 21545, 21548, 21559, 21564, - 9383, 21571, 21576, 9388, 21581, 21586, 21591, 21596, 21601, 21606, - 21611, 21616, 21621, 21626, 21631, 21636, 21642, 21647, 21652, 21657, - 21662, 21667, 21672, 21677, 21682, 21687, 21693, 21699, 21704, 21709, - 21714, 21719, 21724, 21729, 21734, 21739, 21744, 21750, 21755, 21760, - 21765, 21771, 21777, 21782, 21787, 21792, 21797, 21802, 21807, 21812, - 21817, 21823, 21828, 21833, 21838, 21843, 21849, 21854, 21859, 21863, - 1368, 129, 21871, 21875, 21879, 21883, 21888, 21892, 13117, 12476, 21896, - 21901, 21905, 21910, 21914, 21919, 21923, 21929, 21934, 21938, 21942, - 21950, 21954, 21958, 21963, 21968, 21972, 21978, 21983, 21987, 21992, - 21997, 22001, 22008, 22015, 22022, 22026, 22030, 22035, 22039, 22042, - 22048, 22061, 22066, 22075, 22080, 9428, 22085, 22088, 2712, 2717, 22092, - 22098, 22104, 7209, 22109, 22114, 22119, 22125, 22130, 13909, 22135, - 22140, 22145, 22150, 22156, 22161, 22166, 22172, 22177, 22181, 22186, - 22191, 22196, 22201, 22205, 22210, 22214, 22219, 22224, 22229, 22234, - 22238, 22243, 22247, 22252, 22257, 22262, 22267, 2886, 22182, 22271, - 22279, 22286, 9733, 22298, 22306, 22187, 22313, 22318, 22326, 22192, - 22331, 22336, 22344, 22349, 22197, 22354, 22359, 22363, 22369, 22377, - 22380, 22387, 22391, 22395, 22401, 22408, 22413, 8958, 1727, 1732, 22417, - 22423, 22429, 22434, 22438, 22442, 22446, 22450, 22454, 22458, 22462, - 22466, 22469, 22475, 22482, 22490, 22496, 22502, 22507, 22512, 22516, - 13829, 13836, 22521, 22533, 22536, 22543, 16362, 22550, 22558, 22569, - 22578, 22591, 22601, 22615, 22627, 22641, 22653, 22663, 22675, 22681, - 22696, 22720, 22738, 22757, 22770, 22784, 22802, 22818, 22835, 22853, - 22864, 22883, 22900, 22920, 22938, 22950, 22964, 22978, 22990, 23007, - 23026, 23044, 23056, 23074, 23093, 14559, 23106, 23126, 23138, 10523, - 23150, 23155, 23160, 23165, 23171, 23176, 23180, 23187, 2398, 23191, - 23197, 23201, 23204, 23208, 23216, 23222, 22215, 23226, 23235, 23246, - 23252, 23258, 23267, 23275, 23282, 23287, 23291, 23298, 23304, 23313, - 23321, 23328, 23338, 23347, 23357, 23362, 23371, 23380, 23391, 23402, - 3963, 23412, 23416, 23426, 23434, 23444, 23455, 23460, 23470, 23478, - 23485, 23491, 23498, 23503, 22225, 23507, 23516, 23520, 23523, 23528, - 23535, 23544, 23552, 23560, 23570, 23579, 23585, 23591, 22230, 22235, - 23595, 23605, 23615, 23625, 23633, 23640, 23650, 23658, 23666, 23672, - 23680, 930, 23689, 14750, 542, 23703, 23712, 23720, 23731, 23742, 23752, - 23761, 23773, 23782, 23791, 23797, 23806, 23815, 23825, 23833, 23841, - 9360, 23847, 23850, 23854, 23859, 23864, 9848, 22248, 22253, 23872, - 23878, 23884, 23889, 23894, 23898, 23906, 23912, 23918, 23922, 3525, - 23930, 23935, 23940, 23944, 23948, 9928, 23955, 23963, 23977, 23984, - 23990, 9937, 9943, 23998, 24006, 24013, 24018, 24023, 22258, 24029, - 24040, 24044, 24049, 2601, 24054, 24065, 24071, 24076, 24080, 24084, - 24087, 24094, 24101, 24108, 24114, 24118, 22263, 24123, 24127, 24131, - 1037, 24136, 24141, 24146, 24151, 24156, 24161, 24166, 24171, 24176, - 24181, 24186, 24191, 24196, 24201, 24207, 24212, 24217, 24222, 24227, - 24232, 24237, 24243, 24248, 24253, 24258, 24263, 24268, 24273, 24278, - 24284, 24290, 24295, 24301, 24306, 24311, 5, 24317, 24321, 24325, 24329, - 24334, 24338, 24342, 24346, 24350, 24355, 24359, 24364, 24368, 24371, - 24375, 24380, 24384, 24389, 24393, 24397, 24401, 24406, 24410, 24414, - 24424, 24429, 24433, 24437, 24442, 24447, 24456, 24461, 24466, 24470, - 24474, 24487, 24499, 24508, 24517, 24523, 24528, 24532, 24536, 24546, - 24555, 24563, 24569, 24574, 24578, 24585, 24595, 24604, 24612, 24620, - 24627, 24635, 24644, 24653, 24661, 24666, 24670, 24674, 24677, 24679, - 24683, 24687, 24692, 24697, 24701, 24705, 24708, 24712, 24715, 24719, - 24722, 24725, 24729, 24735, 24739, 24743, 24747, 24752, 24757, 24762, - 24766, 24769, 24774, 24780, 24785, 24791, 24796, 24800, 24804, 24808, - 24813, 24817, 24822, 24826, 24830, 24837, 24841, 24844, 24848, 24854, - 24860, 24864, 24868, 24873, 24880, 24886, 24890, 24899, 24903, 24907, - 24910, 24916, 24921, 24927, 1489, 1791, 24932, 24937, 24942, 24947, - 24952, 24957, 24962, 2148, 2194, 24967, 24970, 24974, 24978, 24983, - 24987, 24991, 24994, 24999, 25004, 25008, 25011, 25016, 25020, 25025, - 25029, 14762, 25034, 25037, 25040, 25044, 25049, 25053, 25066, 25070, - 25073, 25081, 25090, 25097, 25102, 25108, 25114, 25122, 25129, 25136, - 25140, 25144, 25148, 25153, 25158, 25162, 25170, 25175, 25187, 25198, - 25203, 25207, 25211, 25217, 25222, 25227, 25231, 25235, 25238, 25244, - 7915, 2316, 25248, 25253, 25269, 9475, 25289, 25298, 25314, 25318, 25321, - 25327, 25337, 25343, 25352, 25367, 25379, 25390, 25398, 25407, 25413, - 25422, 25432, 25443, 25454, 25463, 25470, 25479, 25487, 25494, 25502, - 25509, 25516, 25529, 25536, 25542, 25547, 25556, 25562, 25567, 25575, - 25582, 23436, 25594, 25606, 25620, 25628, 25635, 25647, 25656, 25665, - 25673, 25681, 25689, 25696, 25705, 25713, 25723, 25732, 25742, 25751, - 25760, 25768, 25773, 25777, 25780, 25784, 25788, 25792, 25796, 25800, - 25806, 25812, 25820, 14807, 25827, 25832, 25839, 25845, 25852, 14815, - 25859, 25862, 25874, 25882, 25888, 25893, 25897, 9878, 25908, 25918, - 25927, 25934, 25938, 14820, 25941, 25948, 25952, 25958, 25961, 25968, - 25974, 25981, 25987, 25991, 25996, 26000, 26009, 26016, 26022, 7956, - 26029, 26037, 26044, 26050, 26055, 26061, 26067, 26075, 26079, 26082, - 26084, 25785, 26093, 26099, 26109, 26114, 26121, 26127, 26132, 26137, - 26142, 26146, 26151, 26158, 26167, 26171, 26178, 26187, 26193, 26198, - 26204, 26209, 26216, 26227, 26232, 26236, 26246, 26252, 26256, 26261, - 26271, 26280, 26284, 26291, 26299, 26306, 26312, 26317, 26325, 26332, - 26344, 26353, 26357, 13053, 26365, 26375, 26379, 25077, 26390, 26395, - 26399, 26406, 26413, 21974, 25710, 26418, 26422, 26425, 22870, 26430, - 26444, 26460, 26478, 26497, 26514, 26532, 22889, 26549, 26569, 22906, - 26581, 26593, 15745, 26605, 22926, 26619, 26631, 10536, 26645, 26650, - 26655, 26660, 26666, 26672, 26678, 26682, 26689, 26694, 26704, 26710, - 10183, 26716, 26718, 26723, 26731, 26735, 26154, 26741, 26748, 11524, - 11534, 26755, 26765, 26770, 26774, 26777, 26783, 26791, 26803, 26813, - 26829, 26842, 26856, 15763, 26870, 26877, 26881, 26884, 26889, 26893, - 26900, 26907, 26917, 26922, 26927, 26932, 26940, 26948, 26957, 26962, - 9572, 26966, 26969, 26972, 26977, 26984, 26989, 27005, 27013, 27021, - 9423, 27029, 27034, 27038, 27044, 27050, 27053, 27059, 27071, 27079, - 27086, 27092, 27099, 27110, 27124, 27137, 27146, 27155, 27167, 27178, - 27188, 27197, 27206, 27214, 27225, 7938, 27232, 27238, 27243, 27249, - 27256, 27266, 27276, 27285, 27291, 27298, 27303, 27310, 27318, 27326, - 27338, 6246, 27345, 27354, 27362, 27368, 27374, 27379, 27383, 27386, - 27392, 27399, 27404, 27409, 27413, 27425, 27436, 27445, 27453, 14947, - 27458, 27464, 27470, 11517, 8635, 27475, 27479, 27483, 27486, 27489, - 27495, 27503, 27511, 27515, 27519, 27524, 27527, 27536, 27540, 27548, - 27559, 27563, 27569, 27575, 27579, 27585, 27593, 27615, 27639, 27646, - 27653, 27659, 27667, 27673, 27678, 27689, 27707, 27714, 27722, 27726, - 27735, 27748, 27756, 27768, 27779, 27789, 27803, 27812, 27820, 27832, - 9492, 27843, 27854, 27866, 27876, 27885, 27890, 27894, 27902, 27912, - 27917, 27921, 27924, 27927, 27935, 27943, 27952, 27962, 27971, 27977, - 27991, 2663, 28013, 28024, 28033, 28043, 28055, 28064, 28073, 28083, - 28091, 28099, 28108, 28113, 28124, 28129, 28140, 28144, 28154, 28163, - 28171, 28181, 28191, 28199, 28208, 28215, 28223, 28230, 28239, 28243, - 28251, 28258, 28266, 28273, 28284, 28299, 28306, 28312, 28322, 28331, - 28337, 28341, 28348, 28352, 14031, 28358, 28362, 28367, 28374, 28378, - 28382, 28390, 28398, 28404, 28413, 28420, 28425, 28430, 28440, 23505, - 28444, 28447, 28452, 28457, 28462, 28467, 28472, 28477, 28482, 28487, - 28493, 28498, 28503, 28509, 1218, 704, 28514, 28523, 2364, 28530, 28535, - 28539, 28545, 1267, 546, 318, 28550, 28559, 28567, 28576, 28584, 28595, - 28604, 28612, 28616, 28619, 28627, 28635, 28640, 14775, 28646, 28652, - 28658, 5872, 28663, 28667, 28673, 28677, 28684, 1455, 28690, 28697, 9579, - 28701, 28711, 28719, 28725, 28734, 28742, 28748, 28756, 28763, 11110, - 28769, 28776, 28781, 28788, 1496, 2147, 28794, 28800, 28807, 28818, - 28829, 28837, 28844, 28854, 28863, 28871, 28880, 28887, 28894, 28907, - 28918, 1272, 28937, 28942, 28950, 3575, 28954, 28959, 28963, 1459, 24706, - 28973, 28977, 28982, 28986, 3493, 28992, 29000, 29007, 29018, 29026, - 29034, 3576, 279, 29039, 29047, 29055, 29062, 29068, 29073, 2216, 29080, - 29086, 25992, 26222, 29092, 106, 29096, 29100, 29106, 615, 9328, 29111, - 29118, 29124, 2327, 29128, 29132, 15187, 29135, 29140, 29147, 29153, - 29158, 29166, 29173, 29179, 22351, 29183, 29187, 3646, 16625, 29191, - 29196, 29199, 29207, 29215, 29220, 29223, 29230, 29240, 29252, 29257, - 29261, 29269, 29276, 29282, 29289, 29296, 29299, 29303, 29307, 1463, - 29317, 29319, 29324, 29330, 29336, 29341, 29346, 29351, 29356, 29361, - 29366, 29371, 29376, 29381, 29386, 29391, 29396, 29401, 29406, 29412, - 29418, 29424, 29430, 29435, 29440, 29445, 29451, 29456, 29461, 29466, - 29472, 29477, 29483, 29488, 29493, 29498, 29503, 29509, 29514, 29520, - 29525, 29530, 29535, 29540, 29546, 29551, 29557, 29562, 29567, 29572, - 29577, 29582, 29587, 29592, 29597, 29602, 29608, 29614, 29620, 29625, - 29630, 29635, 29640, 29646, 29652, 29658, 29664, 29670, 29676, 29681, - 29687, 29692, 29697, 29702, 29707, 29713, 2443, 29718, 2450, 2457, 2754, - 29723, 2463, 2473, 29729, 29733, 29738, 29743, 29749, 29754, 29759, - 29763, 29768, 29774, 29779, 29784, 29789, 29795, 29800, 29804, 29808, - 29813, 29818, 29823, 29828, 29833, 29839, 29845, 29850, 29854, 29859, - 29865, 29869, 29874, 29879, 29884, 29889, 29893, 29896, 29901, 29906, - 29911, 29916, 29921, 29927, 29933, 29938, 29943, 29947, 29952, 29957, - 29962, 29967, 29972, 29976, 29981, 29986, 29991, 29995, 29999, 30003, - 30008, 30016, 30021, 30027, 30033, 30039, 30044, 30048, 30051, 30056, - 30061, 30065, 30070, 30074, 30079, 30083, 30086, 30091, 17302, 30096, - 30101, 30106, 30114, 21280, 28694, 9026, 30119, 30124, 30128, 30133, - 30137, 30141, 30146, 30150, 30153, 30156, 30160, 30165, 30169, 30177, - 30181, 30184, 30189, 30193, 30197, 30202, 30207, 30211, 30217, 30222, - 30227, 30234, 30241, 30245, 30248, 30254, 30263, 30270, 30278, 30285, - 30289, 30294, 30298, 30302, 30308, 30314, 30318, 30324, 30329, 30334, - 30338, 30345, 30351, 30357, 30363, 30369, 30376, 30382, 30388, 30394, - 30400, 30406, 30412, 30418, 30425, 30431, 30438, 30444, 30450, 30456, - 30462, 30468, 30474, 30480, 30486, 30492, 11418, 30498, 30503, 30508, - 30511, 30519, 30524, 30533, 30539, 30544, 30549, 30554, 30558, 30563, - 30568, 30573, 30578, 30583, 30590, 30597, 30603, 30609, 30614, 16303, - 30621, 30627, 30634, 30640, 30646, 30651, 30659, 30664, 16082, 30668, - 30673, 30678, 30684, 30689, 30694, 30698, 30703, 30708, 30714, 30719, - 30724, 30728, 30733, 30738, 30742, 30747, 30752, 30757, 30761, 30766, - 30771, 30776, 30780, 30784, 15293, 30788, 30797, 30803, 30809, 30818, - 30826, 30835, 30843, 30848, 30852, 30859, 30865, 30869, 30872, 30877, - 30886, 30894, 30899, 1495, 30905, 30908, 30912, 22424, 22430, 30918, - 30922, 30933, 30944, 30955, 30967, 30974, 30981, 30986, 30990, 5909, 755, - 21279, 30998, 31003, 31007, 31012, 31016, 31022, 31027, 31033, 31038, - 31044, 31049, 31055, 31060, 31066, 31072, 31078, 31083, 31039, 31045, - 31087, 31092, 31098, 31103, 31109, 31114, 31120, 31125, 31050, 10421, - 31129, 31061, 31067, 31073, 2831, 3423, 31135, 31138, 31144, 31150, - 31156, 31163, 31169, 31175, 31181, 31187, 31193, 31199, 31205, 31211, - 31217, 31223, 31229, 31235, 31242, 31248, 31254, 31260, 31266, 31272, - 31275, 31280, 31283, 31290, 31298, 31303, 31308, 31314, 31319, 31324, - 31328, 31333, 31339, 31344, 31350, 31355, 31361, 31366, 31372, 31378, - 31382, 31387, 31392, 31397, 31402, 31406, 31411, 31416, 31421, 31427, - 31433, 31439, 31445, 31450, 31454, 31457, 31463, 31469, 31478, 31486, - 31493, 31498, 31502, 31506, 31511, 15146, 31516, 31524, 31530, 3683, - 1377, 31535, 31539, 8005, 31545, 31551, 31558, 8014, 31562, 31568, 31575, - 31581, 31590, 31598, 31610, 31614, 31621, 31627, 31631, 31634, 31643, - 31651, 31040, 31656, 31666, 31676, 31686, 31692, 31697, 31707, 31712, - 31725, 31739, 31750, 31762, 31774, 31788, 31801, 31813, 31825, 14600, - 31839, 31844, 31849, 31853, 31857, 31861, 1780, 27176, 31865, 31870, - 31088, 31875, 31878, 31883, 31888, 31893, 31899, 31905, 10098, 31910, - 31917, 15697, 31923, 31928, 31933, 31937, 31942, 31947, 31093, 31952, - 31957, 31962, 31968, 31099, 31973, 31976, 31983, 31991, 31997, 32003, - 32009, 32020, 32025, 32032, 32039, 32046, 32054, 32063, 32072, 32078, - 32084, 32092, 31104, 32097, 32103, 32109, 31110, 32114, 32119, 32127, - 32135, 32141, 32148, 32154, 32161, 32168, 32174, 32182, 32192, 32199, - 32204, 32210, 32215, 32220, 32227, 32236, 32244, 32249, 32255, 32262, - 32270, 32276, 32281, 32287, 32296, 27957, 32303, 32307, 32312, 32321, - 32326, 32331, 32336, 12405, 32344, 32349, 32354, 32359, 32363, 32368, - 32373, 32380, 32385, 32390, 32395, 31115, 21216, 32401, 2519, 244, 32404, - 32407, 32411, 32415, 32425, 32433, 32437, 32444, 32451, 32455, 32458, - 32464, 32472, 32480, 32484, 32488, 32491, 32498, 32502, 32506, 32513, - 32521, 31051, 32528, 32536, 10158, 664, 308, 32548, 32553, 32558, 32564, - 32569, 32574, 3704, 32579, 32582, 32587, 32592, 32597, 32602, 32607, - 32614, 22529, 32619, 32624, 32629, 32634, 32639, 32645, 32650, 32656, - 31286, 32662, 32667, 32673, 32679, 32689, 32694, 32699, 32703, 32708, - 32713, 32718, 32723, 32736, 32741, 22302, 16705, 3710, 32745, 32750, - 32755, 32761, 32766, 32771, 32775, 32780, 32785, 32791, 32796, 32801, - 1382, 32805, 32810, 32815, 32820, 32824, 32829, 32834, 32839, 32845, - 32851, 32856, 32860, 32864, 32869, 32874, 32879, 32883, 32891, 32895, - 32901, 32905, 32912, 16498, 31062, 32918, 32925, 32933, 32940, 32946, - 32959, 32971, 32977, 32981, 2773, 32985, 32989, 32493, 32998, 33009, - 33014, 33019, 33024, 33028, 33033, 22435, 33037, 33041, 33046, 31068, - 21300, 33050, 33055, 33061, 33066, 33070, 33074, 33077, 33081, 33087, - 33098, 33110, 31074, 33115, 33118, 33122, 347, 33127, 33132, 33137, - 33142, 33147, 33152, 33158, 33163, 33168, 33174, 33179, 33185, 33190, - 33196, 33201, 33206, 33211, 33216, 33221, 33226, 33231, 33236, 33242, - 33247, 33252, 33257, 33262, 33267, 33272, 33277, 33283, 33289, 33294, - 33299, 33304, 33309, 33314, 33319, 33324, 33329, 33334, 33339, 33344, - 33349, 33354, 33359, 33364, 33369, 33374, 33379, 33385, 313, 26, 33390, - 33394, 33398, 33406, 33410, 33414, 33417, 33420, 33422, 33427, 33431, - 33436, 33440, 33445, 33449, 33454, 33458, 33461, 33463, 33467, 33472, - 33476, 33487, 33490, 33492, 33496, 33508, 33517, 33521, 33525, 33531, - 33536, 33545, 33551, 33556, 33561, 33565, 33570, 33577, 33582, 33588, - 33593, 33597, 33604, 25718, 25728, 33608, 33613, 33618, 33623, 33630, - 33634, 33641, 8113, 33647, 33656, 33664, 33679, 33693, 33701, 33712, - 33721, 33726, 7227, 33736, 33741, 33746, 33750, 33753, 33757, 33762, - 33766, 33773, 33778, 33783, 8912, 33793, 33795, 33798, 33802, 33808, - 33812, 33817, 33822, 33828, 33833, 33839, 33844, 33854, 33863, 33871, - 33876, 33882, 33887, 33894, 33898, 33906, 33913, 33926, 33934, 33938, - 33948, 33953, 33957, 33965, 33973, 33977, 33986, 33992, 33997, 34005, - 34015, 34024, 34033, 34042, 34053, 34061, 34072, 34081, 34088, 34094, - 34099, 34110, 34115, 34119, 34122, 34126, 34134, 34140, 34148, 34155, - 34161, 34166, 34172, 2418, 34176, 34178, 34183, 34188, 34193, 34196, - 34198, 34202, 34205, 34212, 34216, 9891, 34220, 34226, 34236, 34241, - 34247, 34251, 34256, 34269, 26104, 34275, 34284, 17475, 34291, 34300, - 31672, 34308, 34313, 34317, 34325, 34332, 34337, 34341, 34346, 34350, - 34358, 34364, 34370, 34375, 34379, 34382, 34387, 34400, 34416, 22996, - 34433, 34445, 34462, 34474, 34488, 23013, 23032, 34500, 34512, 2680, - 34526, 34531, 34536, 34541, 34545, 34552, 34564, 34570, 34573, 34584, - 34595, 34600, 32089, 695, 34604, 34608, 34612, 34615, 34620, 34625, - 34631, 34636, 34641, 34647, 34653, 34658, 34662, 34667, 34672, 34677, - 34681, 34684, 34690, 34695, 34700, 34705, 34709, 34714, 34720, 34728, - 26337, 34733, 34738, 34745, 34751, 34757, 34762, 34770, 22538, 34777, - 34782, 34787, 34792, 34796, 34799, 34804, 34808, 34812, 34819, 34825, - 34831, 34837, 34844, 34849, 34855, 33968, 34859, 34863, 34868, 34881, - 34886, 34892, 34900, 34907, 34915, 34925, 34931, 34937, 34943, 34947, - 34956, 34964, 34971, 34976, 34981, 10444, 34986, 34994, 35001, 35007, - 35017, 35022, 35028, 35036, 3608, 35043, 35050, 3614, 35054, 35059, - 35070, 35077, 35083, 35092, 35096, 4015, 35099, 35106, 35112, 35118, - 35126, 35136, 29063, 35143, 35151, 35156, 35162, 35167, 25964, 35173, - 35180, 35186, 35195, 23677, 35202, 35207, 35211, 35219, 35227, 9607, - 5895, 35234, 35238, 35240, 35244, 35249, 35251, 35257, 35262, 35267, - 35274, 32610, 35280, 35285, 35289, 35294, 35298, 35307, 35311, 35317, - 35324, 35330, 35337, 35342, 35351, 35356, 35360, 35365, 35372, 35380, - 35388, 35393, 21356, 35397, 35400, 35404, 35408, 35412, 35415, 35417, - 35425, 35429, 35436, 35440, 35444, 35452, 35459, 35469, 35473, 35477, - 35485, 35493, 35499, 35504, 35513, 13357, 35519, 35528, 35533, 35540, - 35548, 35556, 35564, 35571, 35578, 35585, 35592, 35599, 35604, 35610, - 35627, 35635, 35645, 35653, 35660, 407, 35664, 35670, 35674, 35679, - 33717, 35685, 35688, 35692, 35700, 3619, 35708, 35714, 35720, 35729, - 35739, 35746, 35752, 3625, 3631, 35761, 35768, 35776, 35781, 35785, - 35792, 35800, 35807, 35813, 35822, 35832, 35838, 35846, 35855, 35862, - 35870, 35877, 22032, 35881, 35888, 35894, 35904, 35913, 35924, 35928, - 35938, 35944, 35951, 35959, 35968, 35977, 35987, 35998, 36005, 36010, - 36017, 3029, 36025, 36031, 36036, 36042, 36048, 36053, 36066, 36079, - 36092, 36099, 36105, 36113, 36121, 36126, 36130, 1469, 36134, 36139, - 36144, 36149, 36154, 36160, 36165, 36170, 36175, 36180, 36185, 36190, - 36195, 36201, 36207, 36212, 36217, 36223, 36228, 36233, 36238, 36244, - 36249, 36254, 36259, 36264, 36270, 36275, 36280, 36286, 36291, 36296, - 36301, 36306, 36311, 36317, 36322, 36328, 36333, 36339, 36344, 36349, - 36354, 36360, 36366, 36372, 36378, 36384, 36390, 36396, 36402, 36407, - 36412, 36418, 36423, 36428, 36433, 36438, 36443, 36448, 36453, 36459, - 36464, 36469, 36475, 36481, 101, 36486, 36488, 36492, 36496, 36500, - 36505, 36509, 9528, 36513, 36519, 1741, 6280, 36525, 36528, 36533, 36537, - 36542, 36546, 36550, 36555, 10245, 36559, 36563, 36567, 36571, 15385, - 36576, 36580, 36585, 36590, 36595, 36599, 36606, 26128, 36612, 36615, - 36619, 36624, 36630, 36634, 36642, 36648, 36653, 36657, 36663, 36667, - 36671, 3462, 3467, 29255, 36674, 36678, 36682, 36686, 36690, 36698, - 36705, 36709, 36716, 36721, 317, 36726, 36730, 36736, 36748, 36754, - 36760, 36764, 36770, 36779, 36783, 36787, 36792, 36798, 36803, 36807, - 36812, 36816, 36820, 36827, 36833, 36838, 36853, 36868, 36883, 36899, - 36917, 10195, 36931, 36938, 36942, 36945, 36954, 36959, 36963, 36971, - 33919, 36979, 36983, 36993, 37004, 29225, 37017, 37021, 37030, 37038, - 9785, 14913, 37042, 22447, 37045, 30173, 37050, 9784, 37055, 37061, - 37066, 37072, 37077, 37083, 37088, 37094, 37099, 37105, 37111, 37117, - 37122, 37078, 37084, 37089, 37095, 37100, 37106, 37112, 8126, 3874, - 37126, 37134, 37138, 37141, 37145, 37150, 37155, 37161, 37167, 37172, - 37176, 25976, 37180, 37184, 37190, 37194, 9049, 37203, 37210, 37214, - 11875, 37221, 37227, 37232, 37239, 37246, 37253, 28571, 8049, 37260, - 37267, 37274, 37280, 37285, 37292, 37303, 37309, 37314, 37319, 37324, - 37331, 37079, 37335, 37345, 37356, 37362, 37367, 37372, 37377, 37382, - 37387, 37391, 37395, 37401, 37409, 2319, 865, 10261, 10273, 10278, 10284, - 37418, 10289, 10294, 10300, 37423, 37433, 37437, 10305, 37442, 16903, - 37445, 37450, 37454, 37459, 37464, 37471, 37478, 37482, 37485, 37493, - 10208, 37500, 37503, 37509, 37519, 5929, 37528, 37532, 37540, 37544, - 37554, 37560, 37571, 37577, 37583, 37588, 37594, 37600, 37606, 37611, - 37614, 37621, 37627, 37632, 37639, 37646, 37650, 37660, 37673, 37682, - 37691, 37702, 37715, 37726, 37735, 37746, 37751, 37760, 37765, 10310, - 37771, 37778, 37786, 37791, 37795, 37802, 37809, 3829, 16, 37813, 37818, - 16757, 37822, 37825, 37828, 28077, 37832, 28580, 37840, 37844, 37848, - 37851, 37857, 37101, 37863, 37871, 37877, 37884, 28060, 37888, 28254, - 37892, 37901, 37907, 37913, 37918, 37922, 37928, 37932, 37940, 37948, - 26194, 37954, 37961, 37967, 37972, 37977, 37981, 37987, 37992, 37998, - 4056, 791, 38005, 38009, 38012, 15275, 38024, 35851, 38035, 38038, 38045, - 38049, 38055, 38059, 38065, 38070, 38076, 38081, 38086, 38090, 38094, - 38099, 38104, 38114, 38120, 38133, 38139, 38145, 38152, 38157, 38163, - 38168, 16643, 1472, 1019, 31218, 31224, 38173, 31230, 31243, 31249, - 31255, 38179, 31261, 31267, 38185, 38191, 22, 38199, 38206, 38210, 38214, - 38222, 31978, 38226, 38230, 38237, 38242, 38246, 38251, 38257, 38262, - 38268, 38273, 38277, 38281, 38285, 38290, 38294, 38299, 38303, 38310, - 38315, 38319, 38324, 38328, 38333, 38337, 38342, 38348, 15495, 15500, - 38353, 38357, 38360, 38364, 21183, 38369, 38373, 38379, 38386, 38391, - 38401, 38406, 38414, 38418, 38421, 31993, 38425, 4109, 38430, 38435, - 38439, 38444, 38448, 38453, 13375, 38464, 38468, 38471, 38476, 38480, - 38484, 38487, 38491, 8145, 13391, 38494, 38497, 38503, 38508, 38514, - 38519, 38525, 38530, 38536, 38541, 38547, 38553, 38559, 38564, 38568, - 38572, 38581, 38597, 38613, 38623, 27967, 38630, 38634, 38639, 38644, - 38648, 38652, 35972, 38658, 38663, 38667, 38674, 38679, 38683, 38687, - 26996, 38693, 21451, 38698, 38705, 38713, 38719, 38726, 38734, 38740, - 38744, 38750, 38758, 38762, 38771, 9509, 38779, 38783, 38791, 38798, - 38803, 38808, 38812, 38815, 38819, 38822, 38826, 38833, 38838, 38844, - 26415, 31281, 38848, 38855, 38861, 38867, 38872, 38875, 38877, 38884, - 38891, 38897, 38901, 38904, 38908, 38912, 38916, 38921, 38925, 38929, - 38932, 38936, 38950, 23062, 38969, 38982, 38995, 39008, 23080, 39023, - 10497, 39038, 39044, 39048, 39052, 39059, 39064, 39068, 39075, 39081, - 39086, 39092, 39102, 39114, 39125, 39130, 39137, 39141, 39145, 39148, - 15891, 3677, 39156, 15522, 39169, 39176, 39180, 39184, 39189, 39194, - 39200, 39204, 39208, 39211, 7742, 15533, 39216, 39220, 39226, 39235, - 39240, 39247, 35828, 39253, 39258, 39262, 39267, 39274, 39278, 39281, - 39285, 39290, 14565, 39297, 39304, 1077, 39308, 39313, 39318, 39324, - 39329, 39334, 39338, 39348, 39353, 39359, 39364, 39370, 39375, 39381, - 39391, 39396, 39401, 39405, 7229, 7241, 39410, 39413, 39420, 39426, - 34084, 34091, 39435, 39439, 32041, 39447, 39458, 39466, 36020, 39473, - 39478, 39483, 39494, 39501, 39512, 32065, 21457, 39520, 735, 39525, - 39531, 28051, 39537, 39542, 39552, 39561, 39568, 39574, 39578, 39581, - 39588, 39594, 39601, 39607, 39617, 39625, 39631, 39637, 39642, 39646, - 39653, 39659, 39666, 38917, 535, 13818, 39672, 39677, 39680, 39686, - 39694, 1396, 39699, 39703, 39708, 39715, 39721, 39725, 39729, 39734, - 39743, 39750, 39760, 39766, 28095, 39783, 39792, 39800, 39806, 39811, - 39818, 39824, 39832, 39841, 39849, 39853, 39858, 39866, 32074, 39872, - 39891, 15824, 39905, 39921, 39935, 39941, 39946, 39951, 39956, 39962, - 32080, 39967, 39974, 39979, 39983, 345, 2936, 39990, 39995, 40000, 27322, - 39821, 40004, 40009, 40017, 40021, 40024, 40030, 40036, 40040, 28150, - 40043, 40048, 40052, 40055, 40060, 40064, 40069, 40074, 40078, 40083, - 40087, 40091, 21179, 21190, 40095, 40100, 40106, 26953, 40111, 40115, - 21266, 16072, 40118, 40123, 40128, 40133, 40138, 40143, 40148, 40153, - 450, 49, 31299, 31304, 31309, 31315, 31320, 31325, 40158, 31329, 40162, - 40166, 40170, 31334, 31340, 40184, 31351, 31356, 40192, 40197, 31362, - 40202, 40207, 40212, 40217, 40223, 40229, 40235, 31379, 40248, 40254, - 31383, 40258, 31388, 40263, 31393, 31398, 40266, 40271, 40275, 30948, - 40281, 13599, 40288, 40293, 31403, 40297, 40302, 40307, 40312, 40316, - 40321, 40326, 40332, 40337, 40342, 40348, 40354, 40359, 40363, 40368, - 40373, 40378, 40382, 40387, 40392, 40397, 40403, 40409, 40415, 40420, - 40424, 40429, 40433, 31407, 31412, 31417, 40437, 40441, 40445, 31422, - 31428, 31434, 31446, 40457, 26013, 40461, 40465, 40470, 40475, 40480, - 40485, 40489, 40493, 40503, 40508, 40513, 40517, 40521, 40524, 40532, - 31494, 40537, 1479, 40543, 40551, 40560, 40564, 40568, 40576, 40582, - 40590, 40606, 40610, 40614, 40619, 40634, 31531, 1749, 12055, 40638, - 1378, 40650, 40651, 40659, 40666, 40671, 40678, 40683, 9379, 1119, 10332, - 40690, 40695, 40698, 40701, 40710, 1286, 40715, 39065, 40722, 40727, - 40731, 22503, 2557, 40739, 10741, 40749, 40755, 2337, 2347, 40764, 40773, - 40783, 40794, 3293, 34237, 10384, 3807, 16681, 1291, 40799, 40807, 40814, - 40819, 40823, 40827, 23875, 10411, 40835, 40844, 40853, 40861, 40868, - 40879, 40884, 40897, 40910, 40922, 40934, 40946, 40959, 40970, 40981, - 40991, 40999, 41007, 41019, 41031, 41042, 41051, 41059, 41066, 41078, - 41085, 41094, 41101, 41114, 41119, 41129, 41134, 41140, 41145, 37211, - 41149, 41156, 41160, 41167, 41175, 2518, 41182, 41193, 41203, 41212, - 41220, 41230, 41238, 41248, 41257, 41262, 41268, 41274, 3709, 41285, - 41295, 41304, 41313, 41323, 41331, 41340, 41345, 41350, 41355, 1705, 37, - 41363, 41371, 41382, 41393, 16356, 41403, 41407, 41414, 41420, 41425, - 41429, 41440, 41450, 41459, 41470, 16730, 16735, 41475, 41484, 41489, - 41499, 41504, 41512, 41520, 41527, 41533, 7078, 228, 41537, 41543, 41548, - 41551, 2117, 39181, 41559, 41563, 41566, 1512, 41572, 13980, 1296, 41577, - 41590, 41604, 2643, 41622, 41634, 41646, 2657, 2674, 41660, 41673, 2689, - 41687, 41699, 2704, 41713, 1302, 1308, 1314, 10659, 41718, 41723, 41728, - 41732, 41747, 41762, 41777, 41792, 41807, 41822, 41837, 41852, 41867, - 41882, 41897, 41912, 41927, 41942, 41957, 41972, 41987, 42002, 42017, - 42032, 42047, 42062, 42077, 42092, 42107, 42122, 42137, 42152, 42167, - 42182, 42197, 42212, 42227, 42242, 42257, 42272, 42287, 42302, 42317, - 42332, 42347, 42362, 42377, 42392, 42407, 42422, 42437, 42452, 42467, - 42482, 42497, 42512, 42527, 42542, 42557, 42572, 42587, 42602, 42617, - 42632, 42647, 42662, 42677, 42692, 42707, 42722, 42737, 42752, 42767, - 42782, 42797, 42812, 42827, 42842, 42857, 42872, 42887, 42902, 42917, - 42932, 42947, 42962, 42977, 42992, 43007, 43022, 43037, 43052, 43067, - 43082, 43097, 43112, 43127, 43142, 43157, 43172, 43187, 43202, 43217, - 43232, 43247, 43262, 43277, 43292, 43307, 43322, 43337, 43352, 43367, - 43382, 43397, 43412, 43427, 43442, 43457, 43472, 43487, 43502, 43517, - 43532, 43547, 43562, 43577, 43592, 43607, 43622, 43637, 43652, 43667, - 43682, 43697, 43712, 43727, 43742, 43757, 43772, 43787, 43802, 43817, - 43832, 43847, 43862, 43877, 43892, 43907, 43922, 43937, 43952, 43967, - 43982, 43997, 44012, 44027, 44042, 44057, 44072, 44087, 44102, 44117, - 44132, 44147, 44162, 44177, 44192, 44207, 44222, 44237, 44252, 44267, - 44282, 44297, 44312, 44327, 44342, 44357, 44372, 44387, 44402, 44417, - 44432, 44447, 44462, 44477, 44492, 44507, 44522, 44537, 44552, 44567, - 44582, 44597, 44612, 44627, 44642, 44657, 44672, 44687, 44702, 44717, - 44732, 44747, 44762, 44777, 44792, 44807, 44822, 44837, 44852, 44867, - 44882, 44897, 44912, 44927, 44942, 44957, 44972, 44987, 45002, 45017, - 45032, 45047, 45062, 45077, 45092, 45107, 45122, 45137, 45152, 45167, - 45182, 45197, 45212, 45227, 45242, 45257, 45272, 45287, 45302, 45317, - 45332, 45347, 45362, 45377, 45392, 45407, 45422, 45437, 45452, 45467, - 45482, 45497, 45512, 45527, 45542, 45557, 45572, 45587, 45602, 45617, - 45632, 45647, 45662, 45677, 45692, 45707, 45722, 45737, 45752, 45767, - 45782, 45797, 45812, 45827, 45842, 45857, 45872, 45887, 45902, 45917, - 45932, 45947, 45962, 45977, 45992, 46007, 46022, 46037, 46052, 46067, - 46082, 46097, 46112, 46127, 46142, 46157, 46172, 46187, 46202, 46217, - 46232, 46247, 46262, 46277, 46292, 46307, 46322, 46337, 46352, 46367, - 46382, 46397, 46412, 46427, 46442, 46457, 46472, 46487, 46502, 46517, - 46532, 46547, 46562, 46577, 46592, 46607, 46622, 46637, 46652, 46667, - 46682, 46697, 46712, 46727, 46742, 46757, 46772, 46787, 46802, 46817, - 46832, 46847, 46862, 46877, 46892, 46907, 46922, 46937, 46952, 46967, - 46982, 46997, 47012, 47027, 47042, 47057, 47072, 47087, 47102, 47117, - 47132, 47147, 47162, 47177, 47192, 47207, 47222, 47237, 47252, 47267, - 47282, 47297, 47312, 47327, 47342, 47357, 47372, 47387, 47402, 47417, - 47432, 47447, 47462, 47477, 47492, 47507, 47522, 47537, 47552, 47567, - 47582, 47597, 47612, 47627, 47642, 47657, 47672, 47687, 47702, 47717, - 47732, 47747, 47762, 47777, 47792, 47807, 47822, 47837, 47852, 47867, - 47882, 47897, 47912, 47927, 47942, 47957, 47972, 47987, 48002, 48017, - 48032, 48047, 48062, 48077, 48092, 48107, 48122, 48137, 48152, 48167, - 48182, 48197, 48212, 48227, 48242, 48257, 48272, 48287, 48302, 48317, - 48332, 48347, 48362, 48377, 48392, 48407, 48422, 48437, 48452, 48467, - 48482, 48497, 48512, 48527, 48542, 48557, 48572, 48587, 48602, 48617, - 48632, 48647, 48662, 48677, 48692, 48707, 48722, 48737, 48752, 48767, - 48782, 48797, 48812, 48827, 48842, 48857, 48872, 48887, 48902, 48917, - 48932, 48947, 48962, 48977, 48992, 49007, 49022, 49037, 49052, 49067, - 49082, 49097, 49112, 49127, 49142, 49157, 49172, 49187, 49202, 49217, - 49232, 49247, 49262, 49277, 49292, 49307, 49322, 49337, 49352, 49367, - 49382, 49397, 49412, 49427, 49442, 49457, 49472, 49487, 49502, 49517, - 49532, 49548, 49564, 49580, 49596, 49612, 49628, 49644, 49660, 49676, - 49692, 49708, 49724, 49740, 49756, 49772, 49788, 49804, 49820, 49836, - 49852, 49868, 49884, 49900, 49916, 49932, 49948, 49964, 49980, 49996, - 50012, 50028, 50044, 50060, 50076, 50092, 50108, 50124, 50140, 50156, - 50172, 50188, 50204, 50220, 50236, 50252, 50268, 50284, 50300, 50316, - 50332, 50348, 50364, 50380, 50396, 50412, 50428, 50444, 50460, 50476, - 50492, 50508, 50524, 50540, 50556, 50572, 50588, 50604, 50620, 50636, - 50652, 50668, 50684, 50700, 50716, 50732, 50748, 50764, 50780, 50796, - 50812, 50828, 50844, 50860, 50876, 50892, 50908, 50924, 50940, 50956, - 50972, 50988, 51004, 51020, 51036, 51052, 51068, 51084, 51100, 51116, - 51132, 51148, 51164, 51180, 51196, 51212, 51228, 51244, 51260, 51276, - 51292, 51308, 51324, 51340, 51356, 51372, 51388, 51404, 51420, 51436, - 51452, 51468, 51484, 51500, 51516, 51532, 51548, 51564, 51580, 51596, - 51612, 51628, 51644, 51660, 51676, 51692, 51708, 51724, 51740, 51756, - 51772, 51788, 51804, 51820, 51836, 51852, 51868, 51884, 51900, 51916, - 51932, 51948, 51964, 51980, 51996, 52012, 52028, 52044, 52060, 52076, - 52092, 52108, 52124, 52140, 52156, 52172, 52188, 52204, 52220, 52236, - 52252, 52268, 52284, 52300, 52316, 52332, 52348, 52364, 52380, 52396, - 52412, 52428, 52444, 52460, 52476, 52492, 52508, 52524, 52540, 52556, - 52572, 52588, 52604, 52620, 52636, 52652, 52668, 52684, 52700, 52716, - 52732, 52748, 52764, 52780, 52796, 52812, 52828, 52844, 52860, 52876, - 52892, 52908, 52924, 52940, 52956, 52972, 52988, 53004, 53020, 53036, - 53052, 53068, 53084, 53100, 53116, 53132, 53148, 53164, 53180, 53196, - 53212, 53228, 53244, 53260, 53276, 53292, 53308, 53324, 53340, 53356, - 53372, 53388, 53404, 53420, 53436, 53452, 53468, 53484, 53500, 53516, - 53532, 53548, 53564, 53580, 53596, 53612, 53628, 53644, 53660, 53676, - 53692, 53708, 53724, 53740, 53756, 53772, 53788, 53804, 53820, 53836, - 53852, 53868, 53884, 53900, 53916, 53932, 53948, 53964, 53980, 53996, - 54012, 54028, 54044, 54060, 54076, 54092, 54108, 54124, 54140, 54156, - 54172, 54188, 54204, 54220, 54236, 54252, 54268, 54284, 54300, 54316, - 54332, 54348, 54364, 54380, 54396, 54412, 54428, 54444, 54460, 54476, - 54492, 54508, 54524, 54540, 54556, 54572, 54588, 54604, 54620, 54636, - 54652, 54668, 54684, 54700, 54716, 54732, 54748, 54764, 54780, 54796, - 54812, 54828, 54844, 54860, 54876, 54892, 54908, 54924, 54940, 54956, - 54972, 54988, 55004, 55020, 55036, 55052, 55068, 55084, 55100, 55116, - 55132, 55148, 55164, 55180, 55196, 55212, 55228, 55244, 55260, 55276, - 55292, 55308, 55324, 55340, 55356, 55372, 55388, 55404, 55420, 55436, - 55452, 55468, 55484, 55500, 55516, 55532, 55548, 55564, 55580, 55596, - 55612, 55628, 55644, 55660, 55676, 55692, 55708, 55724, 55740, 55756, - 55772, 55788, 55804, 55820, 55836, 55852, 55868, 55884, 55900, 55916, - 55932, 55948, 55964, 55980, 55996, 56012, 56028, 56044, 56060, 56076, - 56092, 56108, 56124, 56140, 56156, 56172, 56188, 56204, 56220, 56236, - 56252, 56268, 56284, 56300, 56316, 56332, 56348, 56364, 56380, 56396, - 56412, 56428, 56444, 56460, 56476, 56492, 56508, 56524, 56540, 56556, - 56572, 56588, 56604, 56620, 56636, 56652, 56668, 56684, 56700, 56716, - 56732, 56748, 56764, 56780, 56796, 56812, 56828, 56844, 56860, 56876, - 56892, 56908, 56924, 56940, 56956, 56972, 56988, 57004, 57020, 57036, - 57052, 57068, 57084, 57100, 57116, 57132, 57148, 57164, 57180, 57196, - 57212, 57228, 57244, 57260, 57276, 57292, 57308, 57324, 57340, 57356, - 57372, 57388, 57404, 57420, 57436, 57452, 57468, 57484, 57500, 57516, - 57532, 57548, 57564, 57580, 57596, 57612, 57628, 57644, 57660, 57676, - 57692, 57708, 57724, 57740, 57756, 57772, 57788, 57804, 57820, 57836, - 57852, 57868, 57884, 57900, 57916, 57932, 57948, 57964, 57980, 57996, - 58012, 58028, 58044, 58060, 58076, 58092, 58108, 58124, 58140, 58156, - 58172, 58188, 58204, 58219, 16762, 58228, 58234, 58240, 58250, 58258, - 14894, 15445, 9960, 58271, 1520, 58279, 3761, 27432, 7183, 58285, 58290, - 58295, 58300, 58305, 58311, 58316, 58322, 58327, 58333, 58338, 58343, - 58348, 58353, 58359, 58364, 58369, 58374, 58379, 58384, 58389, 58394, - 58400, 58405, 58411, 58418, 2561, 58423, 58429, 8526, 58433, 58438, - 58445, 58453, 40, 58457, 58463, 58468, 58473, 58477, 58482, 58486, 58490, - 10684, 58494, 58504, 58517, 58528, 58541, 58548, 58554, 58559, 58565, - 58571, 58577, 58582, 58587, 58592, 58597, 58601, 58606, 58611, 58616, - 58622, 58628, 58634, 58639, 58643, 58648, 58653, 58657, 58662, 58667, - 58672, 58676, 10700, 10711, 10716, 1563, 58680, 1568, 58686, 16239, - 58689, 58695, 1599, 58701, 1605, 1611, 10746, 58706, 58714, 58721, 58725, - 58731, 58736, 30977, 58741, 58748, 58753, 58757, 58761, 1616, 16331, - 58770, 58774, 16342, 1125, 58778, 58785, 58790, 58794, 16367, 1620, - 37350, 58797, 58802, 58812, 58821, 58826, 58830, 58836, 1625, 39259, - 58841, 58850, 58856, 58861, 10904, 10910, 58867, 58879, 58896, 58913, - 58930, 58947, 58964, 58981, 58998, 59015, 59032, 59049, 59066, 59083, - 59100, 59117, 59134, 59151, 59168, 59185, 59202, 59219, 59236, 59253, - 59270, 59287, 59304, 59321, 59338, 59355, 59372, 59389, 59406, 59423, - 59440, 59457, 59474, 59491, 59508, 59525, 59542, 59559, 59576, 59593, - 59610, 59627, 59644, 59661, 59678, 59695, 59712, 59723, 59728, 1630, - 59732, 59738, 59743, 59748, 9326, 1635, 59754, 59763, 27731, 59768, - 59779, 59789, 59794, 59801, 59807, 59812, 59817, 16619, 59821, 10921, - 1640, 10926, 59827, 59832, 59838, 59843, 59848, 59853, 59858, 59863, - 59868, 59873, 59879, 59885, 59891, 59896, 59900, 59905, 59910, 59914, - 59919, 59924, 59929, 59933, 59938, 59944, 59949, 59954, 59958, 59963, - 59968, 59974, 59979, 59984, 59990, 59996, 60001, 60005, 60010, 60015, - 60020, 60024, 60029, 60034, 60039, 60045, 60051, 60056, 60060, 60064, - 60069, 60074, 60079, 29129, 60083, 60088, 60093, 60099, 60104, 60109, - 60113, 60118, 60123, 60129, 60134, 60139, 60145, 60151, 60156, 60160, - 60165, 60170, 60174, 60179, 60184, 60189, 60195, 60201, 60206, 60210, - 60215, 60220, 60224, 60229, 60234, 60239, 60243, 60246, 31639, 60251, - 60259, 16685, 3663, 11017, 60265, 60275, 60290, 11022, 60301, 60306, - 60317, 60329, 60341, 60353, 2695, 60365, 60370, 60382, 60386, 60392, - 60398, 60403, 1652, 1078, 60412, 60417, 39309, 60421, 60425, 60430, - 60434, 16770, 60439, 60442, 60450, 60458, 1656, 11047, 11053, 1661, - 60466, 60473, 60478, 60487, 60497, 60504, 60509, 60514, 1666, 60521, - 60526, 16885, 60530, 60535, 60542, 60548, 60552, 60563, 60573, 16907, - 9234, 9241, 1671, 60580, 60586, 60594, 60601, 60607, 60614, 60626, 60632, - 60637, 60649, 60660, 60669, 60679, 3740, 30813, 30822, 16947, 1676, 1680, - 60687, 60698, 60703, 1683, 60711, 60716, 16998, 60728, 60734, 60739, - 60747, 1688, 60752, 60757, 60765, 60773, 60780, 60789, 60797, 60806, - 1693, 60810, 1698, 60815, 60822, 17072, 60830, 60836, 60841, 60849, - 60856, 60864, 22574, 60869, 11182, 60878, 60884, 60891, 60898, 60904, - 60914, 60920, 60925, 60936, 60941, 60949, 11191, 11196, 60957, 60963, - 60971, 3805, 17114, 39397, 60976, 60982, 60987, 60995, 61002, 12036, - 61007, 61013, 1709, 61018, 61021, 1132, 61027, 61032, 61037, 61043, - 61048, 61053, 61058, 61063, 61068, 61073, 1718, 9, 61079, 61083, 61088, - 61092, 61096, 61100, 31879, 61105, 61110, 61115, 61119, 61122, 61126, - 61130, 61135, 61139, 61144, 61148, 34616, 34621, 34626, 61151, 61158, - 61164, 39118, 61174, 34632, 32137, 31894, 31900, 34648, 31906, 61179, - 61184, 32170, 61188, 61191, 61195, 61202, 61205, 61210, 61214, 61218, - 61221, 61231, 61243, 61250, 61256, 61263, 33573, 61266, 8543, 877, 61269, - 61273, 61278, 3690, 61282, 61285, 13632, 61292, 61299, 61312, 61320, - 61329, 61338, 61343, 61353, 61366, 61378, 61385, 61390, 61399, 61412, - 36060, 61430, 61435, 61442, 61448, 656, 61453, 61461, 61468, 27271, 627, - 61474, 61480, 61490, 61496, 61501, 31924, 6003, 31938, 61505, 61515, - 61520, 61530, 61545, 61551, 61557, 31948, 61562, 31094, 61566, 61571, - 61576, 61580, 61585, 16950, 61592, 61597, 61601, 6044, 31974, 61605, - 61611, 312, 61621, 61628, 61635, 61640, 61649, 58806, 61655, 61663, - 61667, 61671, 61675, 61679, 61684, 61688, 61694, 61702, 61707, 61712, - 61716, 61721, 61725, 61729, 61735, 61741, 61746, 61750, 32098, 61755, - 32104, 32110, 61760, 61766, 61773, 61778, 61782, 31111, 16612, 61785, - 61789, 61794, 61801, 61807, 61811, 61816, 38828, 61822, 61826, 61830, - 61835, 61841, 61847, 61859, 61868, 61878, 61884, 61891, 61896, 61901, - 61905, 61908, 61914, 61921, 61926, 61931, 61938, 61945, 61951, 61956, - 61961, 61969, 32115, 2423, 61974, 61979, 61985, 61990, 61996, 62001, - 62006, 62011, 62017, 32136, 62022, 62028, 62034, 62040, 32200, 62045, - 62050, 62055, 32211, 62060, 62065, 62070, 62076, 62082, 32216, 62087, - 62092, 62097, 32271, 32277, 62102, 62107, 32282, 62112, 27958, 32304, - 32308, 62117, 62093, 62121, 62129, 62135, 62143, 62150, 62156, 62166, - 62172, 62179, 10631, 32322, 62185, 62198, 62207, 62213, 62222, 62228, - 23512, 62235, 62242, 62252, 32272, 62255, 62262, 62267, 62271, 62275, - 62280, 6120, 62284, 62289, 62294, 34710, 34715, 62298, 34729, 62303, - 34734, 62308, 62314, 34746, 34752, 34758, 62319, 62325, 22539, 62336, - 62339, 62351, 62359, 32345, 62363, 62372, 62382, 62391, 32355, 62396, - 62403, 62412, 62418, 62426, 62433, 6095, 4397, 62438, 32283, 62444, - 62447, 62453, 62460, 62465, 62470, 23422, 62474, 62480, 62486, 62491, - 62496, 62500, 62506, 62512, 33483, 863, 35723, 36644, 36650, 32391, - 62517, 62521, 62525, 62528, 62541, 62547, 62551, 62554, 62559, 33786, - 62563, 31116, 21287, 62569, 6024, 6032, 9075, 62572, 62577, 62582, 62587, - 62592, 62597, 62602, 62607, 62612, 62617, 62623, 62628, 62633, 62639, - 62644, 62649, 62654, 62659, 62664, 62669, 62675, 62680, 62686, 62691, - 62696, 62701, 62706, 62711, 62716, 62721, 62726, 62731, 62736, 62742, - 62747, 62752, 62757, 62762, 62767, 62772, 62778, 62783, 62788, 62793, - 62798, 62803, 62808, 62813, 62818, 62823, 62829, 62834, 62839, 62844, - 62849, 62855, 62861, 62866, 62872, 62877, 62882, 62887, 62892, 62897, - 1513, 245, 62902, 62906, 62910, 62914, 25133, 62918, 62922, 62927, 62931, - 62936, 62940, 62945, 62950, 62955, 62959, 62963, 62968, 62972, 13369, - 62977, 62981, 62988, 62998, 15206, 63007, 63016, 63020, 63025, 63030, - 63034, 24924, 3019, 63038, 63044, 17363, 63048, 63057, 63065, 63071, - 63083, 63095, 63099, 63104, 63108, 63114, 63120, 63125, 63135, 63145, - 63151, 63156, 63160, 63165, 63171, 63180, 63189, 63197, 15560, 63201, - 63210, 63218, 63230, 63241, 63252, 63261, 63265, 63274, 63284, 63292, - 63298, 63303, 63309, 63314, 98, 30925, 63325, 26266, 26276, 63331, 63338, - 63344, 63348, 63358, 63369, 63377, 63386, 63391, 63396, 63400, 17317, - 63408, 63412, 63418, 63428, 63435, 63441, 34809, 63447, 63449, 63452, - 63456, 63466, 63472, 63479, 13315, 63486, 63492, 63501, 63510, 63516, - 63522, 63528, 63533, 63540, 63547, 63553, 63566, 63575, 63584, 63589, - 63593, 63599, 63606, 63613, 63620, 63627, 63634, 63639, 63643, 63647, - 63650, 63660, 63664, 63676, 63685, 63689, 63694, 63698, 63704, 63709, - 63716, 63725, 63733, 63741, 63746, 63750, 63755, 63760, 63770, 63778, - 63783, 63787, 63791, 63797, 63809, 63817, 63827, 63834, 63840, 63845, - 63849, 63853, 63857, 63866, 63875, 63884, 63890, 63896, 63902, 63907, - 63914, 63920, 63928, 63935, 12463, 63941, 63947, 63951, 14244, 63955, - 63960, 63970, 63979, 63985, 63991, 63999, 64006, 64010, 64014, 64020, - 64028, 64035, 64041, 64052, 64056, 64060, 64064, 64067, 64073, 64078, - 64082, 64086, 64095, 64103, 64110, 64116, 64123, 24046, 38870, 64128, - 64136, 64140, 64144, 64147, 64155, 64162, 64168, 64177, 64185, 64191, - 64196, 64200, 64205, 64209, 64213, 64218, 64227, 64231, 64238, 64245, - 64251, 64259, 64265, 64276, 64284, 64290, 22669, 64299, 64306, 64313, - 64320, 64327, 64334, 41907, 13153, 64341, 64348, 64353, 34845, 6217, - 64359, 64364, 64369, 64375, 64381, 64387, 64392, 64397, 64402, 64407, - 64413, 64418, 64424, 64429, 64435, 64440, 64445, 64450, 64455, 64460, - 64465, 64470, 64476, 64481, 64487, 64492, 64497, 64502, 64507, 64512, - 64517, 64523, 64528, 64533, 64538, 64543, 64548, 64553, 64558, 64563, - 64568, 64573, 64579, 64584, 64589, 64594, 64599, 64604, 64609, 64614, - 64619, 64625, 64630, 64635, 64640, 64645, 64650, 64655, 64660, 64665, - 64670, 64675, 64680, 64685, 64691, 1834, 224, 37446, 64696, 64699, 64704, - 64708, 64711, 64716, 63737, 64727, 64737, 64744, 64760, 64769, 64779, - 64789, 64797, 64811, 64819, 64823, 64826, 64833, 64839, 64850, 64862, - 64873, 64882, 64889, 1297, 23311, 64899, 2590, 64903, 64912, 1138, 17290, - 38083, 64920, 64928, 64942, 64955, 64959, 64964, 64969, 64974, 64980, - 64986, 64991, 8535, 64996, 65000, 65008, 11048, 65013, 65019, 65028, - 1721, 11060, 736, 65032, 65041, 65051, 27030, 65060, 65066, 16862, 65072, - 65076, 3964, 11391, 65082, 65089, 60693, 65093, 65097, 3988, 189, 14159, - 65103, 65115, 65119, 65125, 27751, 65129, 11379, 2730, 4, 65134, 65144, - 65150, 65161, 65168, 65174, 65180, 65188, 65195, 65201, 65211, 65221, - 65231, 23499, 1309, 65240, 65244, 65248, 65254, 65258, 2753, 2759, 8532, - 2264, 65262, 65266, 65275, 65283, 65294, 65302, 65310, 65316, 65321, - 65332, 65343, 65351, 65357, 9694, 65362, 65370, 65374, 65378, 65382, - 65394, 28136, 65401, 65411, 65417, 65423, 9796, 65433, 65444, 65454, - 65463, 65467, 65474, 1140, 1170, 65484, 65489, 65497, 65505, 65516, - 65523, 65537, 14088, 393, 65547, 65551, 65559, 65568, 65576, 65582, - 65596, 65603, 65609, 65618, 65625, 65635, 65643, 3812, 156, 65651, 65662, - 65666, 65678, 27949, 161, 65684, 65689, 65693, 65700, 65706, 65714, - 65721, 8818, 65728, 65737, 65745, 3878, 65758, 8199, 65762, 2798, 443, - 65767, 65780, 65785, 1833, 650, 65789, 3895, 65797, 65803, 65807, 931, - 65817, 65826, 65831, 14928, 14935, 45269, 65835, 3822, 13041, 65843, - 65850, 23555, 65854, 65861, 65867, 65872, 65877, 14948, 372, 65882, - 65894, 65900, 65908, 2810, 1753, 65916, 65918, 65923, 65928, 65933, - 65939, 65944, 65949, 65954, 65959, 65964, 65969, 65975, 65980, 65985, - 65990, 65995, 66000, 66005, 66010, 66015, 66021, 66026, 66031, 66036, - 66042, 66047, 66053, 66058, 66063, 66068, 66073, 66078, 66083, 66088, - 66094, 66099, 66105, 66110, 66115, 66120, 66125, 66130, 66135, 66140, - 66145, 66151, 66156, 66161, 66166, 66170, 66174, 66179, 66183, 66188, - 66193, 66199, 66204, 66208, 66213, 66217, 66220, 66222, 66226, 66229, - 66234, 66238, 66242, 66246, 66250, 66259, 66263, 32549, 66266, 32554, - 66273, 66278, 32559, 66287, 66296, 32565, 66301, 32570, 66310, 66315, - 11578, 66319, 66324, 66329, 32575, 66333, 40225, 66337, 66340, 66344, - 8211, 66350, 66355, 66359, 3705, 32580, 66362, 66366, 66369, 66374, - 66378, 66384, 66392, 66405, 66414, 66420, 66425, 66431, 66435, 66441, - 66449, 66454, 66458, 66465, 66471, 66479, 66488, 66496, 32583, 66503, - 66513, 66522, 66535, 66540, 66545, 66554, 66560, 66567, 66578, 66590, - 66597, 66606, 66615, 66624, 66631, 66637, 66644, 66652, 66659, 66667, - 66676, 66684, 66691, 66699, 66708, 66716, 66725, 66735, 66744, 66752, - 66759, 66767, 66776, 66784, 66793, 66803, 66812, 66820, 66829, 66839, - 66848, 66858, 66869, 66879, 66888, 66896, 66903, 66911, 66920, 66928, - 66937, 66947, 66956, 66964, 66973, 66983, 66992, 67002, 67013, 67023, - 67032, 67040, 67049, 67059, 67068, 67078, 67089, 67099, 67108, 67118, - 67129, 67139, 67150, 67162, 67173, 67183, 67192, 67200, 67207, 67215, - 67224, 67232, 67241, 67251, 67260, 67268, 67277, 67287, 67296, 67306, - 67317, 67327, 67336, 67344, 67353, 67363, 67372, 67382, 67393, 67403, - 67412, 67422, 67433, 67443, 67454, 67466, 67477, 67487, 67496, 67504, - 67513, 67523, 67532, 67542, 67553, 67563, 67572, 67582, 67593, 67603, - 67614, 67626, 67637, 67647, 67656, 67666, 67677, 67687, 67698, 67710, - 67721, 67731, 67742, 67754, 67765, 67777, 67790, 67802, 67813, 67823, - 67832, 67840, 67847, 67855, 67864, 67872, 67881, 67891, 67900, 67908, - 67917, 67927, 67936, 67946, 67957, 67967, 67976, 67984, 67993, 68003, - 68012, 68022, 68033, 68043, 68052, 68062, 68073, 68083, 68094, 68106, - 68117, 68127, 68136, 68144, 68153, 68163, 68172, 68182, 68193, 68203, - 68212, 68222, 68233, 68243, 68254, 68266, 68277, 68287, 68296, 68306, - 68317, 68327, 68338, 68350, 68361, 68371, 68382, 68394, 68405, 68417, - 68430, 68442, 68453, 68463, 68472, 68480, 68489, 68499, 68508, 68518, - 68529, 68539, 68548, 68558, 68569, 68579, 68590, 68602, 68613, 68623, - 68632, 68642, 68653, 68663, 68674, 68686, 68697, 68707, 68718, 68730, - 68741, 68753, 68766, 68778, 68789, 68799, 68808, 68818, 68829, 68839, - 68850, 68862, 68873, 68883, 68894, 68906, 68917, 68929, 68942, 68954, - 68965, 68975, 68986, 68998, 69009, 69021, 69034, 69046, 69057, 69069, - 69082, 69094, 69107, 69121, 69134, 69146, 69157, 69167, 69176, 69184, - 69191, 69196, 8058, 69203, 32593, 69208, 69213, 32598, 69219, 20929, - 32603, 69224, 69230, 69238, 69244, 69250, 69257, 69264, 69269, 69273, - 69276, 69280, 69289, 69295, 69307, 69318, 69322, 3081, 8033, 69327, - 69330, 69332, 69336, 69340, 69344, 69350, 69355, 25944, 69360, 69364, - 69367, 69372, 69376, 69383, 69389, 69393, 6170, 69397, 32620, 69402, - 69409, 69418, 69426, 69437, 69445, 69453, 69460, 69467, 69473, 69484, - 32625, 69489, 69500, 69512, 69520, 69531, 69540, 69551, 69556, 69564, - 2556, 69569, 34295, 69582, 69586, 69598, 69606, 69611, 69619, 17485, - 69630, 69636, 69643, 69651, 69657, 32635, 69662, 3914, 58254, 69669, - 69672, 69680, 69693, 69706, 69719, 69732, 69739, 69750, 69759, 41724, - 41729, 69764, 69768, 69776, 69783, 69792, 69800, 69806, 69815, 69823, - 69831, 69835, 69844, 69853, 69863, 69876, 69889, 69899, 32640, 69905, - 69912, 69918, 32646, 69923, 69926, 69930, 69938, 69947, 41462, 69955, - 69964, 69972, 69979, 69987, 69997, 70006, 70015, 70024, 70032, 70043, - 70053, 9366, 21567, 70062, 70067, 70072, 70076, 70080, 70085, 70091, - 70096, 70101, 70107, 70112, 70117, 21532, 70122, 70129, 70137, 70145, - 70150, 70157, 70164, 70169, 70173, 70177, 70185, 70193, 32663, 70199, - 70205, 70217, 70223, 70227, 70234, 70239, 70250, 70260, 70270, 70282, - 70288, 70298, 70308, 32690, 70317, 70326, 70332, 70344, 70355, 70362, - 70367, 70371, 70379, 70385, 70390, 70395, 70402, 70410, 70422, 70432, - 70441, 70450, 70457, 34157, 23851, 70463, 70468, 70472, 70476, 70481, - 70487, 70498, 70511, 70516, 70523, 32695, 70528, 70540, 70549, 70559, - 70570, 70583, 70590, 70599, 70608, 70616, 70621, 70627, 1069, 70632, - 70637, 70642, 70647, 70653, 70658, 70663, 70669, 70675, 70680, 70684, - 70689, 70694, 70699, 58766, 70704, 70709, 70714, 70719, 70725, 70731, - 70736, 70740, 70745, 70750, 70755, 70761, 70766, 70772, 70777, 70782, - 70787, 70792, 70796, 70802, 70807, 70816, 70821, 70826, 70831, 70836, - 70840, 70847, 70853, 17135, 17142, 70858, 70862, 70866, 70870, 70874, - 45524, 70878, 70808, 70880, 70890, 32704, 70893, 70902, 70908, 6143, - 32709, 70912, 70918, 70923, 70929, 70934, 70938, 70945, 70950, 70960, - 70969, 70973, 70979, 70985, 70991, 70995, 71003, 71010, 71018, 71026, - 32714, 71033, 71036, 71043, 71049, 71054, 71058, 71064, 71071, 71076, - 71080, 71089, 71097, 71103, 71108, 32719, 71115, 71122, 71128, 71133, - 71139, 71146, 71152, 21294, 27455, 71158, 71163, 71169, 71181, 70841, - 70848, 21470, 71191, 71196, 71203, 71209, 71216, 71222, 71233, 71238, - 9110, 71246, 71249, 71255, 71259, 71263, 71266, 71272, 32468, 6194, 964, - 13419, 71279, 71285, 71291, 71297, 71303, 71309, 71315, 71321, 71327, - 71332, 71337, 71342, 71347, 71352, 71357, 71362, 71367, 71372, 71377, - 71382, 71387, 71392, 71398, 71403, 71408, 71414, 71419, 71424, 71430, - 71436, 71442, 71448, 71454, 71460, 71466, 71472, 71478, 71483, 71488, - 71494, 71499, 71504, 71510, 71515, 71520, 71525, 71530, 71535, 71540, - 71545, 71550, 71555, 71560, 71565, 71570, 71576, 71581, 71586, 71591, - 71597, 71602, 71607, 71612, 71617, 71623, 71628, 71633, 71638, 71643, - 71648, 71653, 71658, 71663, 71668, 71673, 71678, 71683, 71688, 71693, - 71698, 71703, 71708, 71713, 71718, 71724, 71729, 71734, 71739, 71744, - 71749, 71754, 71759, 1864, 142, 71764, 71768, 71772, 71777, 71785, 71789, - 71796, 71804, 71808, 71821, 71829, 71833, 71836, 71841, 71845, 71850, - 71854, 71862, 71866, 20937, 71871, 71875, 60967, 71879, 71882, 71890, - 71898, 71906, 71911, 71918, 71924, 71930, 71935, 71942, 71947, 71955, - 64947, 71962, 71967, 71972, 71976, 11645, 71980, 71985, 71990, 71994, - 71997, 72003, 72007, 72017, 72026, 72029, 72033, 72040, 72053, 72059, - 72067, 72078, 72089, 72100, 72111, 72120, 72126, 72135, 72143, 72153, - 72166, 72173, 72184, 72190, 72195, 72200, 72206, 72212, 72222, 72231, - 70530, 72239, 72245, 72253, 72259, 72267, 72270, 72274, 72278, 72281, - 72287, 72293, 72301, 72313, 72325, 72332, 72336, 72347, 72355, 72362, - 72374, 72382, 72390, 72397, 72403, 72413, 72422, 72427, 72437, 72446, - 40788, 72453, 72457, 72462, 72470, 72477, 72483, 72487, 72497, 72508, - 72516, 72523, 72535, 72547, 72556, 69572, 72563, 72574, 72588, 72596, - 72606, 72613, 72621, 72633, 72642, 72650, 72660, 72671, 72683, 72692, - 72702, 72709, 72718, 72733, 72741, 72751, 72760, 72768, 72781, 72796, - 72800, 72809, 72821, 72832, 72843, 72854, 72864, 72875, 72883, 72889, - 72899, 72907, 72913, 29028, 72918, 72924, 72929, 72936, 9708, 17505, - 72942, 72951, 72956, 72960, 72967, 72973, 72978, 72983, 72991, 72999, - 73003, 73006, 73009, 73011, 73018, 73024, 73035, 73040, 73044, 73051, - 73057, 73062, 73070, 65446, 65456, 73076, 73083, 73093, 10618, 73100, - 73105, 29224, 73114, 73119, 73126, 73136, 73144, 73152, 73161, 73167, - 73173, 73180, 73187, 73192, 73196, 73204, 73209, 73214, 73222, 73229, - 73234, 73240, 73243, 73247, 73256, 71816, 73265, 73269, 73275, 73286, - 73296, 17514, 73307, 73315, 17526, 73322, 73326, 73335, 27341, 73342, - 73346, 73351, 73368, 73380, 10576, 73392, 73397, 73402, 73407, 21010, - 73411, 73416, 73421, 73427, 73432, 5846, 21014, 73437, 73442, 73448, - 73455, 73460, 73465, 73471, 73477, 73483, 73488, 73494, 73498, 73512, - 73520, 73528, 73534, 73539, 73546, 73556, 73565, 73570, 73575, 73583, - 73588, 73594, 73599, 73608, 59823, 73613, 73616, 73634, 73653, 73666, - 73680, 73696, 73703, 73710, 73716, 73723, 73728, 73734, 73740, 73748, - 73754, 73759, 73764, 73780, 10589, 73794, 73801, 73809, 73815, 73819, - 73822, 73827, 73832, 73839, 73844, 73853, 73858, 73864, 73873, 73882, - 73887, 73891, 73899, 73908, 11674, 73917, 73925, 73930, 73936, 11685, - 73941, 73944, 73949, 73959, 73968, 73973, 73979, 73984, 73992, 73999, - 74010, 74020, 74025, 64875, 74030, 74036, 74041, 74048, 74057, 74065, - 74071, 74077, 74084, 74090, 74094, 16960, 3055, 74099, 74103, 74107, - 74113, 74122, 74128, 74135, 74139, 74160, 74182, 74198, 74215, 74234, - 74243, 74253, 74260, 74267, 27228, 74273, 74277, 74285, 74297, 74303, - 74311, 74315, 74323, 74330, 74334, 74340, 74346, 74351, 3563, 41924, - 74357, 74361, 74365, 74369, 74374, 74379, 74384, 74390, 74396, 74402, - 74409, 74415, 74422, 74428, 74434, 74439, 74445, 74450, 74454, 74459, - 74463, 74468, 41939, 74472, 74477, 74485, 74489, 74494, 74501, 74510, - 74516, 74520, 74527, 74531, 74534, 74541, 74550, 74555, 74559, 74567, - 74576, 74580, 74588, 74594, 74599, 74604, 74610, 74616, 74621, 74625, - 74631, 74636, 74640, 74644, 74647, 74652, 74660, 74670, 74675, 39416, - 74683, 74695, 74699, 74705, 74717, 74728, 74735, 74741, 74748, 74760, - 74767, 74773, 21088, 74777, 74783, 74790, 74796, 74802, 74807, 74812, - 74817, 74826, 7033, 74831, 16426, 74837, 74841, 74845, 74849, 74857, - 74866, 74870, 74877, 74886, 74899, 74905, 74464, 30088, 74910, 74912, - 74917, 74922, 74927, 74932, 74937, 74942, 74947, 74952, 74957, 74962, - 74967, 74972, 74977, 74982, 74988, 74993, 74998, 75003, 75008, 75013, - 75018, 75023, 75028, 75034, 75040, 75046, 75051, 75056, 75068, 75073, - 1870, 46, 75078, 75083, 32746, 75087, 32751, 32756, 32762, 32767, 75091, - 32772, 22083, 75113, 75117, 75121, 75126, 75130, 32776, 75134, 75142, - 32781, 75149, 75152, 75157, 75161, 9543, 75170, 32786, 21945, 75173, - 75177, 1428, 75182, 32797, 75185, 75190, 25737, 25747, 35258, 75195, - 75200, 75205, 75210, 75216, 75221, 75230, 75235, 75242, 75248, 75253, - 75258, 75263, 75273, 75282, 75287, 75295, 75299, 75307, 32611, 37317, - 75314, 75320, 75325, 75330, 12016, 75335, 75341, 75346, 75353, 75359, - 75364, 75372, 75382, 75392, 75398, 75403, 75409, 17536, 75416, 36073, - 75429, 75434, 75440, 30993, 75453, 75459, 75463, 75472, 75479, 75485, - 75493, 75502, 75509, 75515, 75518, 75522, 25878, 75526, 75533, 75539, - 75547, 75552, 23994, 75558, 75561, 75569, 75577, 75591, 75598, 75604, - 75611, 75617, 32811, 75621, 75628, 75636, 75644, 75650, 32816, 75658, - 75664, 75669, 75679, 75685, 75694, 30830, 34716, 75702, 75707, 75712, - 75716, 75721, 75725, 75733, 14920, 39429, 75738, 75743, 32821, 62269, - 75747, 75752, 75756, 75765, 75773, 75779, 75784, 75790, 75797, 75803, - 75808, 75813, 75822, 75834, 75849, 33083, 75855, 16545, 32825, 75859, - 75866, 24104, 75872, 75879, 75888, 75895, 75904, 75910, 75915, 75923, - 75929, 32835, 75934, 75943, 74723, 75952, 75959, 75965, 75971, 75981, - 75989, 75996, 76000, 32840, 76003, 32846, 32852, 76008, 76016, 76024, - 76034, 76043, 76051, 76058, 76068, 32857, 76072, 76074, 76078, 76083, - 76087, 76091, 76097, 76102, 76106, 76117, 76122, 76127, 3060, 76131, - 76138, 76142, 76151, 76159, 76166, 76171, 76176, 62315, 76180, 76183, - 76189, 76197, 76203, 76207, 76212, 76219, 76224, 76230, 34747, 76235, - 76238, 76243, 76247, 76252, 76257, 76261, 76269, 76273, 25756, 25765, - 76279, 76285, 76291, 76296, 76300, 76303, 76313, 76322, 76327, 76333, - 76340, 76346, 76350, 76358, 76363, 34753, 76367, 76375, 76381, 76388, - 76393, 76397, 76402, 58440, 34759, 76408, 76413, 76417, 76422, 76427, - 76432, 76436, 76441, 76446, 76452, 76457, 76462, 76468, 76474, 76479, - 76483, 76488, 76493, 76498, 76502, 24103, 76507, 76512, 76518, 76524, - 76530, 76535, 76539, 76544, 76549, 76554, 76558, 76563, 76568, 76573, - 76578, 76582, 32865, 76590, 76594, 76602, 76610, 76621, 76626, 76630, - 22397, 76635, 76641, 76651, 76658, 76663, 76672, 76677, 76681, 76686, - 76694, 76702, 76709, 65109, 76715, 76723, 76730, 76741, 76747, 76751, - 76757, 32875, 76760, 76767, 76775, 76780, 39620, 76784, 76789, 76796, - 76801, 8992, 76805, 76813, 76820, 76827, 76833, 76847, 63381, 76855, - 76861, 76865, 76868, 76876, 76883, 76888, 76901, 76908, 76912, 76919, - 76924, 60860, 76929, 76932, 76939, 76945, 76949, 76957, 76966, 76976, - 76986, 76995, 77003, 77014, 77019, 77023, 77028, 77032, 35389, 77040, - 21357, 35398, 77045, 77050, 77055, 77060, 77065, 77070, 77075, 77079, - 77084, 77089, 77094, 77099, 77104, 77109, 77113, 77118, 77123, 77127, - 77131, 77135, 77139, 77144, 77149, 77153, 77158, 77162, 77166, 77171, - 77176, 77181, 77186, 77190, 77195, 77200, 77204, 77209, 77214, 77219, - 77224, 77229, 77234, 77239, 77244, 77249, 77254, 77259, 77264, 77269, - 77274, 77279, 77284, 77289, 77294, 77299, 77304, 77308, 77313, 77318, - 77323, 77328, 77333, 77338, 77343, 77348, 77353, 77358, 77363, 77367, - 77372, 77376, 77381, 77386, 77391, 77396, 77401, 77406, 77411, 77416, - 77421, 77425, 77429, 77434, 77439, 77443, 77448, 77453, 77457, 77462, - 77467, 77472, 77477, 77481, 77486, 77491, 77495, 77500, 77504, 77508, - 77512, 77516, 77521, 77525, 77529, 77533, 77537, 77541, 77545, 77549, - 77553, 77557, 77562, 77567, 77572, 77577, 77582, 77587, 77592, 77597, - 77602, 77607, 77611, 77615, 77619, 77623, 77627, 77631, 77636, 77640, - 77645, 77649, 77654, 77659, 77663, 77667, 77672, 77676, 77680, 77684, - 77688, 77692, 77696, 77700, 77704, 77708, 77712, 77716, 77720, 77724, - 77728, 77733, 77738, 77742, 77746, 77750, 77754, 77758, 77762, 77767, - 77771, 77775, 77779, 77783, 77787, 77791, 77796, 77800, 77805, 77809, - 77813, 77817, 77821, 77825, 77829, 77833, 77837, 77841, 77845, 77849, - 77854, 77858, 77862, 77866, 77870, 77874, 77878, 77882, 77886, 77890, - 77894, 77898, 77903, 77907, 77911, 77916, 77921, 77925, 77929, 77933, - 77937, 77941, 77945, 77949, 77953, 77958, 77962, 77967, 77971, 77976, - 77980, 77985, 77989, 77995, 78000, 78004, 78009, 78013, 78018, 78022, - 78027, 78031, 78036, 1521, 78040, 2824, 1759, 1764, 78044, 78048, 2828, - 78052, 1397, 78057, 1342, 78061, 2840, 78065, 78072, 78079, 78093, 2844, - 7131, 78102, 78110, 78117, 78128, 78137, 78144, 78156, 78169, 78182, - 78193, 78198, 78205, 78217, 78221, 2848, 11747, 78231, 78236, 78245, - 78255, 2852, 78260, 78264, 78269, 78276, 78282, 78290, 78302, 1347, - 13042, 78312, 78316, 78322, 78336, 78348, 78360, 78370, 78379, 78388, - 78397, 78405, 78416, 78424, 4051, 78434, 78445, 78454, 78460, 78475, - 78482, 78488, 35514, 78493, 2876, 13046, 78497, 78504, 8930, 78513, 2881, - 32361, 78519, 60609, 78526, 78532, 78543, 78549, 78556, 78562, 78570, - 78577, 78583, 78593, 78602, 78613, 78620, 78626, 78636, 78644, 78650, - 78665, 78671, 78676, 78683, 78686, 78692, 78699, 78705, 78713, 78722, - 78730, 78736, 78745, 41464, 78759, 78764, 78770, 14757, 78775, 78788, - 78797, 78805, 78812, 78816, 78820, 78823, 78830, 78837, 78845, 78853, - 78862, 78870, 14684, 78878, 78883, 78887, 78899, 78906, 78915, 748, - 78925, 78934, 78945, 2897, 78949, 78953, 78959, 78972, 78984, 78994, - 79003, 79015, 26369, 79026, 79034, 79043, 79054, 79065, 79075, 79085, - 79094, 79102, 11312, 79109, 79113, 79116, 79121, 79126, 79130, 79136, - 1352, 11818, 79143, 79154, 79163, 79171, 79180, 79188, 79204, 79215, - 79224, 79232, 79244, 79255, 79271, 79281, 79302, 79315, 79323, 79330, - 14868, 79343, 79348, 79354, 5908, 79360, 79363, 79370, 79380, 8176, - 79387, 79392, 79397, 79402, 79410, 79419, 79427, 9756, 9765, 79432, - 79443, 79448, 79454, 2913, 2918, 79460, 10879, 79466, 79473, 79480, - 79493, 2251, 68, 79498, 79503, 79513, 79519, 79528, 79536, 79546, 79550, - 79555, 79559, 79571, 2941, 79579, 79587, 79592, 79603, 79614, 79623, - 79628, 79634, 79639, 79649, 79659, 79664, 79670, 79674, 79679, 79688, - 21410, 79692, 4128, 20, 79697, 79706, 79713, 79720, 79726, 79732, 864, - 79737, 79742, 60937, 79747, 79752, 79758, 79764, 79772, 79777, 79784, - 79790, 79795, 38030, 41358, 79801, 2945, 32, 79811, 79824, 79829, 79837, - 79842, 79848, 2967, 28310, 79853, 79861, 79868, 79873, 58682, 61940, - 79882, 79886, 1704, 1813, 79891, 79896, 79903, 1817, 247, 79910, 79916, - 2989, 79921, 79926, 79933, 1821, 79938, 79944, 79949, 79961, 6119, 79971, - 1828, 79977, 79982, 79989, 79996, 80011, 80018, 80029, 80037, 2618, - 80041, 80053, 80058, 80062, 80068, 28135, 2256, 80072, 80083, 80087, - 80091, 80097, 80101, 80110, 80114, 80125, 80129, 2302, 32190, 80133, - 80143, 3080, 9371, 80151, 80156, 80160, 80169, 80176, 80182, 3050, 17152, - 80186, 80199, 80217, 80222, 80230, 80238, 80248, 9985, 13154, 80260, - 80273, 80280, 80287, 80303, 80310, 80316, 1064, 80323, 80330, 80340, - 80349, 80361, 42328, 80369, 3064, 12030, 80372, 80380, 80384, 78272, - 3068, 80388, 21191, 12046, 3756, 80392, 3074, 80396, 80406, 80412, 80418, - 80424, 80430, 80436, 80442, 80448, 80454, 80460, 80466, 80472, 80478, - 80484, 80490, 80496, 80502, 80508, 80514, 80520, 80526, 80532, 80538, - 80544, 80550, 80556, 80563, 80570, 80576, 80582, 80588, 80594, 80600, - 80606, 1357, 16062, 12068, 80612, 80617, 80622, 80627, 80632, 80637, - 80642, 80647, 80652, 80657, 80662, 80667, 80672, 80677, 80682, 80687, - 80692, 80697, 80702, 80707, 80712, 80717, 80722, 80727, 80732, 80737, - 80743, 80748, 80753, 80759, 80764, 80770, 80775, 80780, 80786, 80791, - 80796, 80801, 80806, 80811, 80816, 80821, 80826, 80407, 80413, 80419, - 80425, 80431, 80437, 80443, 80449, 80455, 80461, 80467, 80473, 80479, - 80485, 80491, 80832, 80497, 80503, 80509, 80838, 80515, 80521, 80527, - 80533, 80539, 80545, 80551, 80571, 80844, 80850, 80577, 80856, 80583, - 80589, 80595, 80601, 80607, 3091, 3096, 80862, 80867, 80870, 80876, - 80882, 80889, 80894, 80899, 2307, + 0, 0, 6, 10, 14, 22, 27, 34, 44, 49, 58, 64, 66, 69, 81, 89, 102, 108, + 113, 118, 126, 135, 146, 151, 156, 161, 164, 168, 177, 183, 189, 194, + 201, 209, 217, 218, 221, 229, 165, 235, 244, 251, 261, 267, 274, 279, + 282, 287, 293, 296, 300, 305, 311, 317, 322, 327, 333, 339, 348, 355, + 362, 371, 376, 381, 383, 391, 399, 400, 408, 410, 417, 420, 426, 433, + 331, 438, 440, 442, 449, 451, 456, 464, 471, 476, 480, 486, 491, 501, + 506, 513, 516, 524, 528, 538, 545, 554, 561, 570, 577, 580, 584, 592, + 598, 611, 618, 622, 626, 627, 636, 640, 649, 655, 659, 661, 666, 674, + 678, 686, 691, 694, 700, 703, 707, 712, 720, 723, 730, 735, 744, 753, + 761, 769, 773, 779, 787, 794, 797, 807, 811, 815, 826, 833, 840, 844, + 848, 854, 842, 863, 869, 874, 879, 883, 886, 889, 894, 903, 911, 916, + 658, 575, 921, 924, 930, 934, 938, 947, 953, 960, 969, 976, 989, 994, + 998, 1006, 1009, 1015, 1021, 1030, 1037, 1045, 1052, 1062, 1069, 1077, + 1086, 1090, 1093, 1100, 21, 1104, 1113, 1121, 1128, 1131, 1136, 1138, + 1142, 1151, 1156, 1159, 1165, 1172, 1175, 1180, 1185, 1191, 1196, 1201, + 1206, 1210, 1215, 1221, 1226, 1231, 1235, 1241, 1246, 1251, 1256, 1260, + 1265, 1270, 1275, 1281, 1287, 1293, 1298, 1302, 1307, 1312, 1317, 1321, + 1326, 1331, 1336, 1341, 1176, 1181, 1186, 1192, 1197, 1345, 1207, 1351, + 1356, 1361, 1368, 1372, 1375, 1384, 1211, 1388, 1216, 1222, 1227, 1392, + 1397, 1402, 1406, 1410, 1416, 1420, 1232, 1423, 1425, 1242, 1430, 1434, + 1247, 1440, 1252, 1444, 1448, 1257, 1452, 1457, 1461, 1464, 1468, 1261, + 1266, 1473, 1479, 1271, 1491, 1497, 1503, 1509, 1276, 1288, 1294, 1513, + 1517, 1521, 1524, 1299, 1528, 1530, 1535, 1540, 1546, 1551, 1556, 1560, + 1565, 1570, 1575, 1580, 1586, 1591, 1596, 1602, 1608, 1613, 1617, 1622, + 1627, 1632, 1637, 1642, 1646, 1654, 1659, 1663, 1668, 1673, 1678, 1683, + 1687, 1690, 1697, 1702, 1707, 1712, 1717, 1723, 1728, 1732, 1303, 1735, + 1740, 1745, 1308, 1749, 1753, 1760, 1313, 1767, 1318, 1771, 1773, 1778, + 1784, 1322, 1789, 1798, 1327, 1803, 1809, 1814, 1332, 1819, 1824, 1827, + 1832, 1836, 1840, 1844, 1847, 1851, 1337, 1856, 1342, 1860, 1862, 1868, + 1874, 1880, 1886, 1892, 1898, 1904, 1910, 1915, 1921, 1927, 1933, 1939, + 1945, 1951, 1957, 1963, 1969, 1974, 1979, 1984, 1989, 1994, 1999, 2004, + 2009, 2014, 2019, 2025, 2030, 2036, 2041, 2047, 2053, 2058, 2064, 2070, + 2076, 2082, 2087, 2092, 2094, 2095, 2099, 2103, 2108, 2112, 2116, 2120, + 2125, 2129, 2132, 2137, 2141, 2146, 2150, 2154, 2159, 2163, 2166, 2170, + 2176, 2190, 2194, 2198, 2202, 2205, 2210, 2214, 2218, 2221, 2225, 2230, + 2235, 2240, 2245, 2249, 2253, 2257, 2261, 2266, 2270, 2275, 2279, 2284, + 2290, 2297, 2303, 2308, 2313, 2318, 2324, 2329, 2335, 2340, 2343, 2345, + 1193, 2349, 2356, 2364, 2374, 2383, 2397, 2401, 2405, 2410, 2423, 2431, + 2435, 2440, 2444, 2447, 2451, 2455, 2460, 2465, 2470, 2474, 2477, 2481, + 2488, 2495, 2501, 2506, 2511, 2517, 2523, 2528, 2531, 1775, 2533, 2539, + 2543, 2548, 2552, 2556, 1693, 1786, 2561, 2565, 2568, 2573, 2578, 2583, + 2588, 2592, 2599, 2604, 2607, 2614, 2620, 2624, 2628, 2632, 2637, 2644, + 2649, 2654, 2661, 2667, 2673, 2679, 2693, 2710, 2725, 2740, 2749, 2754, + 2758, 2763, 2768, 2772, 2784, 2791, 2797, 2293, 2803, 2810, 2816, 2820, + 2823, 2830, 2836, 2841, 2845, 2850, 2854, 2858, 2117, 2862, 2867, 2872, + 2876, 2881, 2889, 2893, 2898, 2902, 2906, 2910, 2915, 2920, 2925, 2929, + 2934, 2939, 2943, 2948, 2952, 2955, 2959, 2963, 2971, 2976, 2980, 2984, + 2990, 2999, 3003, 3007, 3013, 3018, 3025, 3029, 3039, 3043, 3047, 3052, + 3056, 3061, 3067, 3072, 3076, 3080, 3084, 2491, 3092, 3097, 3103, 3108, + 3112, 3117, 3122, 3126, 3132, 3137, 2121, 3143, 3149, 3154, 3159, 3164, + 3169, 3174, 3179, 3184, 3189, 3194, 3200, 3205, 1208, 101, 3211, 3215, + 3219, 3223, 3228, 3232, 3236, 3242, 3247, 3251, 3255, 3260, 3265, 3269, + 3274, 3278, 3281, 3285, 3290, 3294, 3299, 3303, 3306, 3310, 3314, 3319, + 3323, 3326, 3339, 3343, 3347, 3351, 3356, 3360, 3364, 3367, 3371, 3375, + 3380, 3384, 3389, 3394, 3399, 3403, 3408, 3411, 3414, 3419, 3425, 3429, + 3433, 3436, 3441, 3445, 3450, 3454, 3458, 3461, 3467, 3472, 3477, 3483, + 3488, 3493, 3499, 3505, 3510, 3515, 3520, 3525, 1140, 579, 3528, 3531, + 3536, 3540, 3544, 3548, 3552, 3555, 3559, 3564, 3569, 3573, 3578, 3582, + 3587, 3591, 3595, 3599, 3605, 3611, 3614, 3617, 139, 3623, 3628, 3637, + 3645, 3654, 3661, 3667, 3674, 3679, 3683, 3687, 3695, 3702, 3707, 3714, + 3719, 3723, 3733, 3737, 3741, 3746, 3751, 3761, 2133, 3766, 3770, 3773, + 3779, 3784, 3790, 3796, 3801, 3808, 3812, 3816, 637, 701, 1369, 3820, + 3827, 3834, 3840, 3845, 3852, 3859, 3864, 3870, 3876, 3881, 3885, 3891, + 3898, 3903, 3907, 2142, 3911, 3919, 3925, 3933, 739, 3939, 3947, 3958, + 3962, 3972, 2147, 3978, 3983, 3998, 4004, 4011, 4021, 4027, 4032, 4038, + 4044, 4047, 4050, 4054, 4059, 4066, 4071, 4075, 4079, 4083, 4087, 4092, + 4098, 4109, 4113, 3286, 4118, 4130, 4136, 4144, 4148, 4153, 1562, 4160, + 4163, 4166, 4170, 4173, 4179, 4183, 4197, 4201, 4204, 4208, 4214, 4220, + 4225, 4229, 4233, 4239, 4250, 4256, 4261, 4267, 4271, 4279, 4291, 4301, + 4307, 4312, 4321, 4329, 4336, 4342, 4346, 4352, 4361, 4370, 4374, 4383, + 4388, 4392, 4397, 4401, 4409, 4415, 4419, 4424, 4428, 4434, 2155, 1385, + 4440, 4445, 4451, 4456, 4461, 4466, 4471, 4476, 4481, 4487, 4492, 4498, + 4503, 4508, 4513, 4519, 4524, 4529, 4534, 4539, 4545, 4550, 4556, 4561, + 4566, 4571, 4576, 4581, 4586, 4592, 4597, 4602, 291, 321, 4607, 4613, + 4617, 4621, 4626, 4630, 4634, 4637, 4641, 4645, 4649, 4653, 4657, 4662, + 4666, 4670, 4676, 4437, 4681, 4685, 4688, 4693, 4698, 4703, 4708, 4713, + 4718, 4723, 4728, 4733, 4738, 4742, 4747, 4752, 4757, 4762, 4767, 4772, + 4777, 4782, 4787, 4792, 4796, 4801, 4806, 4811, 4816, 4821, 4826, 4831, + 4836, 4841, 4846, 4850, 4855, 4860, 4865, 4870, 4875, 4880, 4885, 4890, + 4895, 4900, 4904, 4909, 4914, 4919, 4924, 4929, 4934, 4939, 4944, 4949, + 4954, 4958, 4963, 4968, 4973, 4978, 4983, 4988, 4993, 4998, 5003, 5008, + 5012, 5017, 5022, 5027, 5032, 5037, 5042, 5047, 5052, 5057, 5062, 5066, + 5071, 5076, 5081, 5086, 5092, 5098, 5104, 5110, 5116, 5122, 5128, 5133, + 5139, 5145, 5151, 5157, 5163, 5169, 5175, 5181, 5187, 5193, 5198, 5204, + 5210, 5216, 5222, 5228, 5234, 5240, 5246, 5252, 5258, 5263, 5269, 5275, + 5281, 5287, 5293, 5299, 5305, 5311, 5317, 5323, 5328, 5334, 5340, 5346, + 5352, 5358, 5364, 5370, 5376, 5382, 5388, 5393, 5399, 5405, 5411, 5417, + 5423, 5429, 5435, 5441, 5447, 5453, 5458, 5462, 5468, 5474, 5480, 5486, + 5492, 5498, 5504, 5510, 5516, 5522, 5527, 5533, 5539, 5545, 5551, 5557, + 5563, 5569, 5575, 5581, 5587, 5592, 5598, 5604, 5610, 5616, 5622, 5628, + 5634, 5640, 5646, 5652, 5657, 5663, 5669, 5675, 5681, 5687, 5693, 5699, + 5705, 5711, 5717, 5722, 5728, 5734, 5740, 5746, 5752, 5758, 5764, 5770, + 5776, 5782, 5787, 5793, 5799, 5805, 5811, 5817, 5823, 5829, 5835, 5841, + 5847, 5852, 5858, 5864, 5870, 5876, 5882, 5888, 5894, 5900, 5906, 5912, + 5917, 5923, 5929, 5935, 5941, 5947, 5953, 5959, 5965, 5971, 5977, 5982, + 5988, 5994, 6000, 6006, 6012, 6018, 6024, 6030, 6036, 6042, 6047, 6053, + 6059, 6065, 6071, 6077, 6083, 6089, 6095, 6101, 6107, 6112, 6116, 6119, + 6126, 6130, 6143, 6147, 6151, 6155, 6158, 6162, 6167, 6171, 6175, 6181, + 6188, 6199, 6207, 6214, 6218, 6226, 6235, 6241, 6253, 6258, 6261, 6266, + 6270, 6280, 6288, 6296, 6302, 6306, 6316, 6326, 6334, 6341, 6348, 6354, + 6360, 6367, 6371, 6378, 6388, 6398, 6406, 6413, 6418, 6422, 6426, 6434, + 6438, 6443, 6450, 6458, 6463, 6467, 6472, 6476, 6483, 6488, 6502, 6507, + 6512, 6519, 3541, 6528, 6532, 6537, 6541, 6545, 6548, 6553, 6558, 6567, + 6573, 6579, 6585, 6589, 6600, 6610, 6625, 6640, 6655, 6670, 6685, 6700, + 6715, 6730, 6745, 6760, 6775, 6790, 6805, 6820, 6835, 6850, 6865, 6880, + 6895, 6910, 6925, 6940, 6955, 6970, 6985, 7000, 7015, 7030, 7045, 7060, + 7075, 7090, 7105, 7120, 7135, 7150, 7165, 7180, 7195, 7210, 7225, 7240, + 7255, 7270, 7285, 7300, 7315, 7330, 7345, 7354, 7363, 7368, 7374, 7384, + 7388, 7392, 7397, 7402, 7410, 7414, 7417, 7421, 3034, 7424, 7429, 330, + 504, 7435, 7443, 7447, 7451, 7454, 7458, 7464, 7468, 7476, 7482, 7487, + 7494, 7502, 7509, 7515, 7520, 7527, 7533, 7541, 7545, 7550, 7562, 7573, + 7580, 7584, 7588, 7592, 7595, 7601, 3311, 7605, 7611, 7616, 7621, 7626, + 7632, 7637, 7642, 7647, 7652, 7658, 7663, 7668, 7674, 7679, 7685, 7690, + 7696, 7701, 7707, 7712, 7717, 7722, 7727, 7732, 7738, 7743, 7748, 7753, + 7759, 7765, 7771, 7777, 7783, 7789, 7795, 7801, 7807, 7813, 7819, 7825, + 7830, 7835, 7840, 7845, 7850, 7855, 7860, 7865, 7871, 7877, 7882, 7888, + 7894, 7900, 7905, 7910, 7915, 7920, 7926, 7932, 7937, 7942, 7947, 7952, + 7957, 7963, 7968, 7974, 7980, 7986, 7992, 7998, 8004, 8010, 8016, 8022, + 2164, 7453, 8027, 8031, 8035, 8038, 8045, 8048, 8052, 8060, 8065, 8070, + 8061, 8075, 2191, 8079, 8085, 8091, 8096, 8101, 8108, 8116, 8121, 8125, + 8128, 8132, 8138, 8144, 8148, 2199, 526, 8151, 8155, 8160, 8166, 8171, + 8175, 8178, 8182, 8188, 8193, 8197, 8204, 8208, 8212, 8216, 876, 958, + 8219, 8227, 8234, 8240, 8247, 8255, 8262, 8273, 8280, 8286, 8291, 8303, + 1228, 1393, 1398, 8314, 1403, 8318, 8322, 8331, 8339, 8343, 8352, 8358, + 8363, 8367, 8373, 8378, 8385, 2745, 8392, 8396, 8405, 8414, 8423, 8432, + 8438, 8443, 8448, 8459, 8471, 8476, 8484, 2250, 8488, 8490, 8495, 8499, + 8508, 8516, 1407, 159, 3583, 3588, 8522, 8526, 8535, 8541, 8546, 8549, + 8558, 3592, 2737, 8564, 8572, 8576, 8580, 8584, 2267, 8588, 8593, 8600, + 8606, 8612, 8615, 8617, 8620, 8628, 8636, 8644, 8647, 8652, 2280, 8657, + 8072, 8660, 8662, 8667, 8672, 8677, 8682, 8687, 8692, 8697, 8702, 8707, + 8712, 8718, 8723, 8728, 8733, 8739, 8744, 8749, 8754, 8759, 8764, 8769, + 8775, 8780, 8785, 8790, 8795, 8800, 8805, 8810, 8815, 8820, 8825, 8830, + 8835, 8840, 8845, 8850, 8855, 8860, 8866, 8872, 8877, 8882, 8887, 8892, + 8897, 2291, 2298, 2304, 8902, 8910, 8916, 8924, 2330, 2336, 8932, 8936, + 8941, 8945, 8949, 8953, 8958, 8962, 8967, 8971, 8974, 8977, 8983, 8990, + 8996, 9003, 9009, 9016, 9022, 9029, 9035, 9041, 9050, 9056, 9060, 9064, + 9068, 9072, 9077, 9081, 9086, 9090, 9096, 9101, 9108, 9119, 9127, 9137, + 9143, 9153, 9162, 9169, 9174, 9178, 9189, 9202, 9213, 9226, 9237, 9249, + 9261, 9273, 9286, 9299, 9306, 9312, 9326, 9333, 9339, 9348, 9356, 9360, + 9365, 9369, 9376, 9384, 9388, 9394, 9398, 9404, 9414, 9418, 9423, 9428, + 9435, 9441, 9451, 8242, 9457, 9461, 9468, 9474, 9481, 9488, 957, 9492, + 9496, 9501, 9506, 9511, 9515, 9521, 9529, 9535, 9539, 9542, 9548, 9558, + 9562, 9568, 9573, 9577, 9581, 9587, 9593, 2187, 9598, 9600, 9605, 9613, + 9622, 9626, 9632, 9637, 9642, 9647, 9652, 9658, 9663, 9668, 4235, 9673, + 9678, 9682, 9688, 9693, 9699, 9704, 9709, 9715, 9720, 9627, 9726, 9730, + 9737, 9743, 9748, 9752, 6498, 9757, 9766, 9771, 9776, 8596, 8603, 9781, + 2912, 9785, 9790, 9795, 9800, 9638, 9804, 9809, 9814, 9643, 9818, 9648, + 9823, 9830, 9837, 9843, 9850, 9856, 9862, 9867, 9874, 9879, 9884, 9889, + 9895, 9653, 9659, 9901, 9907, 9912, 9917, 9925, 9664, 9930, 1102, 9933, + 9941, 9947, 9953, 9962, 9970, 9978, 9986, 9994, 10002, 10010, 10018, + 10026, 10035, 10044, 10052, 10061, 10070, 10079, 10088, 10097, 10106, + 10115, 10124, 10133, 10142, 10150, 10155, 10161, 10169, 10176, 10191, + 10208, 10227, 10236, 10244, 10259, 10270, 10280, 10290, 10298, 10304, + 10316, 10325, 10333, 10340, 10347, 10354, 10360, 10365, 10375, 10383, + 10393, 10400, 10410, 10420, 10430, 10438, 10445, 10454, 10464, 10478, + 10493, 10502, 10510, 10515, 10519, 10528, 10534, 10539, 10549, 10559, + 10569, 10574, 10578, 10587, 10592, 10608, 10625, 10635, 10646, 10659, + 10667, 10680, 10692, 10700, 10705, 10709, 10715, 10720, 10728, 10736, + 10743, 10748, 10756, 10766, 10772, 10776, 10779, 10783, 10789, 10796, + 10800, 10808, 10817, 10825, 10832, 10837, 10842, 10846, 10850, 10858, + 10873, 10889, 10895, 10903, 10912, 10920, 10926, 10930, 10937, 10948, + 10952, 10955, 10961, 9669, 10966, 10972, 10979, 10985, 10990, 10997, + 11004, 11011, 11018, 11025, 11032, 11039, 11046, 11051, 10204, 11056, + 11062, 11069, 11076, 11081, 11088, 11097, 11101, 11113, 8634, 11117, + 11120, 11124, 11128, 11132, 11136, 11142, 11148, 11153, 11159, 11164, + 11169, 11175, 11180, 11185, 9431, 11190, 11194, 11198, 11202, 11207, + 11212, 11217, 11225, 11231, 11236, 11240, 11244, 11251, 11256, 11264, + 11271, 11276, 11280, 11283, 11289, 11296, 11300, 11303, 11308, 11312, + 4274, 11318, 11327, 46, 11335, 11341, 11346, 11351, 11359, 11366, 11371, + 9446, 11377, 11383, 11388, 11392, 11395, 11410, 11429, 11441, 11454, + 11467, 11480, 11494, 11507, 11522, 11529, 9674, 11535, 11549, 11554, + 11560, 11565, 11573, 11578, 8401, 11583, 11586, 11594, 11601, 11606, + 11610, 11616, 2917, 10278, 11620, 11624, 11630, 11636, 11641, 11647, + 11652, 9683, 11658, 11664, 11669, 11674, 11682, 11688, 11701, 11709, + 11716, 11722, 9689, 11728, 11736, 11744, 11751, 11764, 11777, 11789, + 11799, 11807, 11814, 11826, 11833, 11843, 11852, 11861, 11869, 11876, + 11881, 11887, 9694, 11892, 11898, 11903, 11908, 9700, 11913, 11916, + 11923, 11929, 11942, 9112, 11953, 11959, 11968, 11976, 11983, 11989, + 12000, 12006, 12011, 3836, 12019, 12024, 11402, 12030, 12037, 12042, + 9705, 12048, 12053, 12060, 12066, 12072, 12077, 12085, 12093, 12100, + 12104, 12116, 12130, 12140, 12145, 12149, 12160, 12166, 12171, 12176, + 9710, 12180, 9716, 12185, 12188, 12193, 12205, 12212, 12217, 12221, + 12229, 12234, 12238, 12243, 12247, 12254, 12260, 9721, 9628, 12267, 2922, + 12, 12274, 12279, 12283, 12287, 12293, 12301, 12311, 12316, 12321, 12328, + 12335, 12339, 12350, 12360, 12369, 12378, 12390, 12395, 12399, 12407, + 12421, 12425, 12428, 12436, 12443, 12451, 12455, 12466, 12470, 12477, + 12482, 12486, 12492, 12497, 12503, 12508, 12513, 12517, 12523, 12528, + 12539, 12543, 12546, 12552, 12557, 12563, 12569, 12576, 12587, 12597, + 12607, 12616, 12623, 12632, 12636, 9731, 9738, 9744, 9749, 12642, 12648, + 12654, 12659, 12665, 9753, 12671, 12674, 12681, 12686, 12701, 12717, + 12732, 12740, 12746, 12751, 950, 374, 12756, 12764, 12771, 12777, 12782, + 12787, 9758, 12789, 12793, 12798, 12802, 12812, 12817, 12821, 12830, + 12834, 12837, 12844, 9767, 12849, 12852, 12860, 12867, 12875, 12879, + 12883, 12890, 12899, 12906, 12902, 12913, 12917, 12923, 12927, 12931, + 12935, 12941, 12951, 12959, 12966, 12970, 12978, 12982, 12989, 12993, + 12998, 13002, 13009, 13015, 13023, 13029, 13034, 13044, 13049, 13054, + 13058, 13062, 13070, 4124, 13078, 13083, 9772, 13087, 13091, 13094, + 13102, 13109, 13113, 6298, 13117, 13122, 13127, 13131, 13142, 13152, + 13157, 13163, 13168, 13172, 13175, 13183, 13188, 13193, 13200, 13205, + 9777, 13210, 13214, 13221, 1737, 6456, 13226, 13231, 13236, 13241, 13247, + 13252, 13258, 13263, 13268, 13273, 13278, 13283, 13288, 13293, 13298, + 13303, 13308, 13313, 13318, 13323, 13328, 13333, 13338, 13344, 13349, + 13354, 13359, 13364, 13369, 13375, 13380, 13385, 13391, 13396, 13402, + 13407, 13413, 13418, 13423, 13428, 13433, 13439, 13444, 13449, 13454, + 909, 112, 13462, 13466, 13471, 13476, 13480, 13484, 13488, 13493, 13497, + 13502, 13506, 13509, 13513, 13517, 13523, 13528, 13538, 13544, 13552, + 13558, 13562, 13566, 13573, 13581, 13590, 13601, 13611, 13618, 13625, + 13629, 13638, 13647, 13655, 13664, 13673, 13682, 13691, 13701, 13711, + 13721, 13731, 13741, 13750, 13760, 13770, 13780, 13790, 13800, 13810, + 13820, 13829, 13839, 13849, 13859, 13869, 13879, 13889, 13898, 13908, + 13918, 13928, 13938, 13948, 13958, 13968, 13978, 13988, 13997, 14007, + 14017, 14027, 14037, 14047, 14057, 14067, 14077, 14087, 14097, 14106, + 1237, 14112, 14115, 14119, 14124, 14131, 14137, 14142, 14146, 14151, + 14160, 14168, 14173, 14177, 14181, 14187, 14192, 14198, 9786, 14203, + 14208, 14217, 9796, 14222, 14225, 14231, 14239, 9801, 14246, 14250, + 14254, 14259, 14263, 14273, 14279, 14285, 14290, 14299, 14307, 14314, + 14321, 14326, 14333, 14338, 14342, 14345, 14356, 14366, 14375, 14383, + 14394, 14406, 14416, 14421, 14425, 14430, 14435, 14439, 14445, 14453, + 14460, 14471, 14476, 14486, 14495, 14499, 14502, 14509, 14519, 14528, + 14535, 14539, 14546, 14552, 14557, 14562, 14566, 14575, 14580, 14584, + 14590, 14594, 14599, 14603, 14610, 14617, 14621, 14630, 14638, 14646, + 14653, 14661, 14673, 14684, 14694, 14701, 14707, 14716, 14727, 14736, + 14748, 14760, 14772, 14782, 14791, 14800, 14808, 14815, 14824, 14832, + 14836, 14841, 14847, 14853, 14858, 14863, 8093, 14867, 14869, 14873, + 14878, 14884, 14890, 14899, 14903, 14909, 14917, 14924, 14933, 14942, + 14951, 14960, 14969, 14978, 14987, 14996, 15006, 15016, 15025, 15031, + 15038, 15045, 15051, 15065, 15071, 15078, 15086, 15095, 15103, 15109, + 15118, 15127, 15138, 15148, 15156, 15163, 15171, 15180, 15193, 15202, + 15210, 15217, 15230, 15236, 15242, 15252, 15261, 15270, 15275, 15279, + 15285, 15291, 15296, 15303, 15310, 9445, 15315, 15320, 15327, 15335, + 15340, 15347, 15352, 15364, 13519, 15369, 15377, 15383, 15388, 15396, + 15404, 15411, 15419, 15425, 15433, 15441, 15447, 15452, 15458, 15465, + 15471, 15476, 15480, 15491, 15499, 15505, 15510, 15517, 15526, 15532, + 15537, 15545, 15554, 15568, 4068, 15572, 15577, 15582, 15588, 15593, + 15598, 15602, 15607, 15612, 15617, 8092, 15622, 15627, 15632, 15637, + 15642, 15646, 15651, 15656, 15661, 15666, 15672, 15678, 15683, 15687, + 15693, 15698, 15703, 15708, 9805, 15713, 15718, 15723, 15728, 15733, + 15750, 15768, 15780, 15793, 15810, 15826, 15843, 15853, 15872, 15883, + 15894, 15905, 15916, 15928, 15939, 15950, 15967, 15978, 15989, 15994, + 9810, 15999, 16003, 2420, 16007, 16010, 16016, 16024, 16032, 16041, + 16048, 16053, 16061, 16069, 16076, 16080, 16085, 16091, 16098, 16106, + 16113, 16125, 16132, 16138, 16146, 16151, 16157, 12695, 16163, 16172, + 16178, 16183, 16191, 16200, 16208, 16215, 16221, 16229, 16236, 16242, + 16248, 16255, 16262, 16268, 16274, 16283, 16291, 16301, 16308, 16314, + 16322, 16328, 16336, 16344, 16351, 16364, 16371, 16380, 16389, 16398, + 16406, 16416, 16423, 16428, 3727, 16435, 16440, 1353, 16444, 15623, + 16448, 16454, 16458, 16466, 16478, 16483, 16490, 16496, 16501, 16508, + 15628, 16512, 16516, 16520, 15633, 16524, 15638, 16528, 16535, 16540, + 16544, 16551, 16555, 16563, 16570, 16575, 16579, 16586, 16603, 16612, + 16616, 16619, 16627, 16633, 16638, 3805, 16642, 16644, 16652, 16659, + 16669, 16681, 16686, 16690, 16696, 16701, 16705, 16711, 16716, 16722, + 16725, 16732, 16740, 16747, 16753, 16758, 16764, 16769, 16776, 16782, + 16787, 16794, 16799, 16803, 16809, 16813, 16820, 16826, 16831, 16837, + 16845, 16853, 16860, 16866, 16871, 16877, 16883, 16891, 16899, 16905, + 16911, 16916, 16923, 16928, 16932, 16938, 16943, 16950, 16955, 16961, + 16964, 16970, 16976, 16979, 16983, 16987, 16999, 17005, 17010, 17017, + 17023, 17029, 17040, 17050, 17059, 17067, 17074, 17085, 17095, 17105, + 17113, 17116, 15652, 17121, 17126, 15657, 15798, 17134, 17147, 17162, + 17173, 15815, 17191, 17204, 17217, 17228, 11417, 17239, 17252, 17271, + 17282, 17293, 17304, 2688, 17317, 17321, 17329, 17340, 17348, 17363, + 17378, 17389, 17396, 17402, 17410, 17414, 17420, 17423, 17436, 17448, + 17458, 17466, 17473, 17481, 17491, 17496, 17503, 17508, 17515, 17526, + 17536, 17542, 17547, 17552, 15662, 17556, 17562, 17568, 17573, 17578, + 17583, 17587, 15667, 15673, 17591, 15679, 17596, 17604, 17609, 17613, + 17621, 17630, 17637, 17641, 9649, 17645, 17647, 17652, 17657, 17663, + 17668, 17673, 17678, 17683, 17687, 17693, 17699, 17704, 17710, 17715, + 17720, 17724, 17730, 17735, 17740, 17745, 17757, 17762, 17768, 17773, + 17778, 17784, 17790, 17795, 17800, 17805, 17812, 17818, 17829, 17836, + 17841, 17845, 17849, 17852, 17860, 17865, 17872, 17879, 17885, 17890, + 17895, 17900, 17907, 17917, 17925, 17930, 17937, 17943, 17952, 17962, + 17972, 17986, 18000, 18014, 18028, 18043, 18058, 18075, 18093, 18106, + 18112, 18117, 18122, 18126, 18134, 18139, 18147, 18153, 18159, 18164, + 18169, 18173, 18178, 18182, 18187, 18191, 18202, 18208, 18213, 18218, + 18225, 18230, 18234, 3690, 18239, 18245, 18252, 15688, 18258, 18262, + 18268, 18273, 18278, 18282, 18288, 18293, 18298, 18305, 18310, 14275, + 18314, 18319, 18323, 18328, 18334, 18340, 18347, 18357, 18365, 18372, + 18377, 18381, 18390, 18398, 18405, 18412, 18418, 18423, 18429, 18434, + 18439, 18445, 18450, 18456, 18461, 18467, 18473, 18480, 18486, 18491, + 18496, 9875, 18505, 18508, 18516, 18522, 18527, 18532, 18542, 18549, + 18555, 18560, 18565, 18571, 18576, 18582, 18587, 18593, 18599, 18604, + 18612, 18619, 18624, 18629, 18635, 18640, 18644, 18653, 18664, 18671, + 18679, 18686, 18691, 18696, 18702, 18707, 18715, 18721, 18727, 18734, + 18740, 18745, 18749, 18755, 18760, 18765, 18769, 18774, 1426, 8117, 2936, + 18778, 18782, 18786, 18790, 18794, 18798, 18801, 18806, 18813, 18821, + 15699, 18828, 18838, 18846, 18853, 18861, 18871, 18880, 9220, 18893, + 18898, 18903, 18911, 18918, 14371, 14380, 18925, 18935, 18950, 18956, + 18963, 18970, 18976, 18982, 18993, 19001, 19009, 19019, 19029, 15704, + 19038, 19044, 19050, 19058, 19066, 19071, 19080, 19088, 19100, 19110, + 19120, 19130, 19139, 19151, 19161, 19171, 19182, 19187, 19199, 19211, + 19223, 19235, 19247, 19259, 19271, 19283, 19295, 19307, 19318, 19330, + 19342, 19354, 19366, 19378, 19390, 19402, 19414, 19426, 19438, 19449, + 19461, 19473, 19485, 19497, 19509, 19521, 19533, 19545, 19557, 19569, + 19580, 19592, 19604, 19616, 19628, 19640, 19652, 19664, 19676, 19688, + 19700, 19711, 19723, 19735, 19747, 19759, 19771, 19783, 19795, 19807, + 19819, 19831, 19842, 19854, 19866, 19878, 19890, 19902, 19914, 19926, + 19938, 19950, 19962, 19973, 19985, 19997, 20009, 20021, 20033, 20045, + 20057, 20069, 20081, 20093, 20104, 20116, 20128, 20140, 20152, 20165, + 20178, 20191, 20204, 20217, 20230, 20243, 20255, 20268, 20281, 20294, + 20307, 20320, 20333, 20346, 20359, 20372, 20385, 20397, 20410, 20423, + 20436, 20449, 20462, 20475, 20488, 20501, 20514, 20527, 20539, 20552, + 20565, 20578, 20591, 20604, 20617, 20630, 20643, 20656, 20669, 20681, + 20694, 20707, 20720, 20733, 20746, 20759, 20772, 20785, 20798, 20811, + 20823, 20836, 20849, 20862, 20875, 20888, 20901, 20914, 20927, 20940, + 20953, 20965, 20976, 20989, 21002, 21015, 21028, 21041, 21054, 21067, + 21080, 21093, 21106, 21118, 21131, 21144, 21157, 21170, 21183, 21196, + 21209, 21222, 21235, 21248, 21260, 21273, 21286, 21299, 21312, 21325, + 21338, 21351, 21364, 21377, 21390, 21402, 21415, 21428, 21441, 21454, + 21467, 21480, 21493, 21506, 21519, 21532, 21544, 21557, 21570, 21583, + 21596, 21609, 21622, 21635, 21648, 21661, 21674, 21686, 21699, 21712, + 21725, 21738, 21751, 21764, 21777, 21790, 21803, 21816, 21828, 21841, + 21854, 21867, 21880, 21893, 21906, 21919, 21932, 21945, 21958, 21970, + 21983, 21996, 22009, 22022, 22035, 22048, 22061, 22074, 22087, 22100, + 22112, 22125, 22138, 22151, 22164, 22177, 22190, 22203, 22216, 22229, + 22242, 22254, 22267, 22280, 22293, 22306, 22319, 22332, 22345, 22358, + 22371, 22384, 22396, 22407, 22416, 22424, 22432, 22439, 22445, 22449, + 22455, 22461, 22469, 22474, 22480, 22485, 22489, 22498, 9654, 22509, + 22516, 22524, 22531, 22538, 11936, 22545, 22552, 22561, 22566, 22571, + 8145, 22578, 22583, 22586, 22591, 22599, 22606, 22613, 22620, 22626, + 22635, 22644, 22653, 22659, 22668, 22672, 22678, 22683, 22693, 22700, + 22706, 22714, 22720, 22727, 22737, 22746, 22750, 22757, 22761, 22766, + 22772, 22780, 22784, 22794, 15714, 22803, 22809, 22813, 22822, 22832, + 15719, 22838, 22845, 22856, 22864, 22874, 22883, 22891, 9410, 22899, + 22904, 22910, 22915, 22919, 22923, 22927, 10379, 22932, 22940, 22947, + 22956, 22963, 22970, 22976, 11856, 22983, 22989, 22993, 22999, 23006, + 23012, 23020, 23026, 23033, 23039, 23045, 23054, 23058, 23066, 23075, + 23082, 23087, 23091, 23102, 23107, 23112, 23117, 23130, 8349, 23134, + 23140, 23145, 23153, 23157, 23164, 23173, 23178, 15990, 23186, 23190, + 23202, 23207, 23211, 23214, 23220, 23226, 23232, 23237, 23241, 23244, + 23255, 23260, 9926, 23267, 23272, 1243, 9931, 23277, 23282, 23287, 23292, + 23297, 23302, 23307, 23312, 23317, 23322, 23327, 23332, 23338, 23343, + 23348, 23353, 23358, 23363, 23368, 23373, 23378, 23383, 23389, 23395, + 23400, 23405, 23410, 23415, 23420, 23425, 23430, 23435, 23440, 23446, + 23451, 23456, 23461, 23467, 23473, 23478, 23483, 23488, 23493, 23498, + 23503, 23508, 23513, 23519, 23524, 23529, 23534, 23539, 23545, 23550, + 23555, 23559, 134, 23567, 23571, 23575, 23579, 23584, 23588, 14281, 2346, + 23592, 23597, 23601, 23606, 23610, 23615, 23619, 23625, 23630, 23634, + 23638, 23646, 23650, 23654, 23659, 23664, 23668, 23674, 23679, 23683, + 23688, 23693, 23697, 23704, 23711, 23718, 23722, 23726, 23731, 23735, + 23738, 23744, 23757, 23762, 23768, 23777, 23782, 10151, 23787, 23796, + 23801, 23804, 2751, 2756, 23808, 23814, 23820, 7538, 23825, 23830, 23835, + 23841, 23846, 15134, 23851, 23856, 23861, 23866, 23872, 23877, 23882, + 23888, 23893, 23897, 23902, 23907, 23912, 23917, 23922, 23926, 23931, + 23935, 23940, 23945, 23950, 23955, 23959, 23964, 23968, 23973, 23978, + 23983, 23898, 2945, 23903, 23988, 23996, 24003, 10473, 24015, 24023, + 24033, 24051, 24070, 24079, 24087, 23908, 24094, 24099, 24107, 23913, + 24112, 24117, 24125, 24130, 23918, 24135, 24143, 24148, 24152, 24159, + 24165, 24174, 24182, 24186, 24189, 24196, 24200, 24204, 24209, 24215, + 24222, 24227, 9437, 1742, 1747, 24231, 24237, 24243, 24248, 24252, 24256, + 24260, 24264, 24268, 24272, 24276, 24280, 24283, 24289, 24296, 24304, + 24310, 24316, 24321, 24326, 24332, 24336, 24341, 15040, 15047, 24348, + 24360, 24363, 24370, 24374, 17881, 24381, 24389, 24400, 24409, 24422, + 24432, 24446, 24458, 24472, 24485, 24497, 24507, 24519, 24525, 24540, + 24564, 24582, 24601, 24614, 24628, 24646, 24662, 24679, 24697, 24708, + 24727, 24744, 24764, 24782, 24794, 24808, 24822, 24834, 24851, 24870, + 24888, 24900, 24918, 24937, 15858, 24950, 24970, 24982, 11448, 24994, + 24999, 25004, 25009, 25015, 25020, 25024, 25031, 25037, 2437, 25041, + 25047, 25051, 25054, 25058, 25061, 25069, 25075, 23936, 25079, 25088, + 25099, 25105, 25111, 25126, 25135, 25143, 25150, 25155, 25159, 25166, + 25172, 25181, 25189, 25196, 25206, 25215, 25225, 25230, 25239, 25248, + 25259, 25270, 4192, 25280, 25284, 25294, 25302, 25312, 25323, 25328, + 25338, 25346, 25353, 25359, 25366, 25371, 23946, 25375, 25384, 25388, + 25391, 25396, 25404, 25411, 25420, 25428, 25436, 25444, 25454, 25463, + 25469, 25475, 25479, 23951, 23956, 25483, 25493, 25503, 25513, 25521, + 25528, 25538, 25546, 25554, 25560, 25568, 865, 25577, 16065, 615, 25591, + 25600, 25608, 25619, 25630, 25640, 25649, 25661, 25670, 25679, 25686, + 25692, 25702, 25711, 25720, 25728, 25738, 25746, 25754, 9892, 25760, + 25763, 25767, 25772, 25777, 25781, 10588, 23969, 23974, 25789, 25795, + 25801, 25806, 25811, 25815, 25823, 25829, 25835, 25839, 3675, 25847, + 25852, 25857, 25861, 25865, 10701, 25872, 25880, 25894, 25901, 25907, + 10710, 10716, 25915, 25923, 25930, 25935, 25940, 23979, 25946, 25957, + 25961, 25966, 2640, 25971, 25982, 25988, 25993, 25997, 26001, 26004, + 26011, 26018, 26024, 26031, 26037, 26041, 23984, 26046, 26050, 26054, + 1431, 8544, 26059, 26064, 26069, 26074, 26079, 26084, 26089, 26094, + 26099, 26104, 26109, 26114, 26119, 26124, 26130, 26135, 26140, 26145, + 26150, 26155, 26160, 26166, 26171, 26176, 26181, 26186, 26191, 26196, + 26201, 26207, 26213, 26218, 26224, 26229, 26234, 5, 26240, 26244, 26248, + 26252, 26257, 26261, 26265, 26269, 26273, 26278, 26282, 26287, 26291, + 26294, 26298, 26303, 26307, 26312, 26316, 26320, 26324, 26329, 26333, + 26337, 26347, 26352, 26356, 26360, 26365, 26370, 26379, 26384, 26389, + 26393, 26397, 26410, 26422, 26431, 26440, 26445, 26451, 26456, 26460, + 26464, 26474, 26483, 26491, 26497, 26502, 26506, 26513, 26523, 26532, + 26540, 11770, 26548, 26556, 26565, 26574, 26582, 26592, 26597, 26601, + 26605, 26608, 26610, 26614, 26618, 26623, 26628, 26632, 26636, 26639, + 26643, 26646, 26650, 26653, 26656, 26660, 26666, 26670, 26674, 26678, + 26683, 26688, 26693, 26697, 26700, 26705, 26711, 26716, 26722, 26727, + 26731, 26737, 26741, 26745, 26750, 26754, 26759, 26764, 26768, 26772, + 26779, 26783, 26786, 26790, 26794, 26800, 26806, 26810, 26814, 26819, + 26826, 26832, 26836, 26845, 26849, 26853, 26856, 26862, 26867, 26873, + 1475, 1806, 26878, 26883, 26888, 26893, 26898, 26903, 26908, 2174, 2220, + 26913, 26916, 26920, 26924, 26929, 26933, 16077, 26937, 26942, 26947, + 26951, 26954, 26959, 26963, 26968, 26972, 16081, 26977, 26980, 26983, + 26987, 26992, 26996, 27009, 27013, 27016, 27024, 27033, 27040, 27045, + 27051, 27057, 27065, 27072, 27079, 27083, 27087, 27091, 27096, 27101, + 27105, 27113, 27118, 27130, 27141, 27146, 27150, 27157, 27161, 27166, + 27172, 27175, 27180, 27185, 27189, 27193, 27196, 27202, 8248, 2350, + 27206, 27211, 27227, 10198, 27247, 27256, 27272, 27276, 27283, 27286, + 27292, 27302, 27308, 27317, 27332, 27344, 27355, 27363, 27372, 27378, + 27387, 27397, 27407, 27418, 27429, 27439, 27448, 27455, 27464, 27472, + 27479, 27487, 27494, 27501, 27514, 27521, 27529, 27536, 27542, 27547, + 27556, 27562, 27567, 27575, 27582, 27589, 25304, 27601, 27613, 27627, + 27635, 27642, 27654, 27663, 27672, 27680, 27688, 27696, 27703, 27709, + 27718, 27726, 27736, 27745, 27755, 27764, 27773, 27781, 27786, 27790, + 27793, 27797, 27801, 27805, 27809, 27813, 27819, 27825, 27833, 16139, + 27840, 27845, 27852, 27858, 27865, 16147, 27872, 27875, 27887, 27895, + 27901, 27906, 27910, 27921, 10651, 27931, 27939, 27949, 27958, 27965, + 27972, 27980, 27984, 16158, 27987, 27994, 27998, 28004, 28007, 28014, + 28020, 28027, 28033, 28037, 28042, 28046, 28055, 28062, 28068, 8306, + 28075, 28083, 28090, 28096, 28101, 28107, 28113, 28121, 28127, 28131, + 28134, 28136, 27798, 28145, 28151, 28157, 28167, 28172, 28179, 28185, + 28190, 28195, 28200, 28204, 28209, 28216, 28222, 28231, 28235, 28242, + 28248, 28257, 4378, 28263, 28269, 28274, 28281, 28292, 28297, 28301, + 28311, 28317, 28321, 28326, 28336, 28345, 28349, 28356, 28364, 28371, + 28377, 28382, 28390, 28397, 28402, 28409, 28421, 28430, 28434, 14212, + 28442, 28452, 28456, 27020, 28467, 28472, 28476, 28483, 28490, 23670, + 27723, 28495, 28499, 28502, 24714, 28507, 28521, 28537, 28555, 28574, + 28591, 28609, 24733, 28626, 28646, 24750, 28658, 28670, 17178, 28682, + 24770, 28696, 28708, 11461, 28722, 28727, 28732, 28737, 28743, 28749, + 28755, 28759, 28767, 28774, 28779, 28789, 28795, 11059, 28801, 28803, + 28808, 28816, 28820, 28212, 28826, 28833, 12601, 12611, 28840, 28850, + 28855, 28859, 28862, 28868, 28876, 28888, 28898, 28914, 28927, 28941, + 17196, 28955, 28962, 28966, 28969, 28974, 28978, 28985, 28992, 28999, + 29009, 29014, 29019, 29024, 29032, 29040, 29045, 29054, 29059, 3353, + 29063, 29066, 29069, 29074, 29081, 29086, 29102, 29110, 29118, 9966, + 29126, 29131, 29135, 29141, 29146, 29152, 29155, 29161, 29173, 29181, + 29188, 29194, 29201, 29212, 29226, 29239, 29245, 29254, 29260, 29269, + 29281, 29292, 29302, 29311, 29320, 29328, 29339, 8288, 29346, 29353, + 29359, 29364, 29370, 29377, 29387, 29397, 29406, 29412, 29419, 29424, + 29432, 29439, 29447, 29455, 29467, 6563, 995, 29474, 29483, 29491, 29497, + 29503, 29508, 29512, 29515, 29521, 29528, 29533, 29538, 29543, 29547, + 29559, 29570, 29579, 29587, 16323, 29592, 29597, 29603, 29609, 12594, + 9058, 29614, 29618, 29622, 29625, 29628, 29634, 29642, 29650, 29654, + 29658, 29663, 29666, 29675, 29679, 29682, 29690, 29701, 29705, 29711, + 29717, 29721, 29727, 29735, 29757, 29781, 29790, 29797, 29804, 29810, + 29818, 29824, 29829, 29840, 29858, 29865, 29873, 29877, 29882, 29891, + 29904, 29912, 29924, 29935, 29946, 29956, 29970, 29979, 29987, 29999, + 10215, 30010, 30021, 30033, 30043, 30052, 30057, 30061, 30069, 30080, + 30090, 30095, 30099, 30102, 30105, 30113, 30121, 30130, 30140, 30149, + 30155, 30169, 2702, 30191, 30202, 30211, 30221, 30233, 30242, 30251, + 30261, 30269, 30277, 30286, 30291, 30302, 30307, 30318, 30322, 30332, + 30341, 30349, 30359, 30369, 30377, 30386, 30393, 30401, 30408, 30417, + 30426, 30430, 30438, 30445, 30453, 30460, 30471, 30486, 30493, 30499, + 30509, 30518, 30524, 30535, 30539, 30546, 30550, 30556, 15265, 30562, + 30566, 30571, 30577, 30584, 30588, 30592, 30600, 30608, 30614, 30623, + 30630, 30635, 30640, 30650, 25373, 30654, 30657, 30662, 30667, 30672, + 30677, 30682, 30687, 30692, 30697, 30703, 30708, 30713, 30719, 1199, 660, + 30724, 30733, 2398, 30740, 30745, 30749, 30755, 1248, 578, 290, 30760, + 30769, 30777, 30786, 30794, 30805, 30813, 30822, 30830, 30835, 10797, + 30839, 30847, 30855, 30860, 16094, 3824, 30866, 30872, 30878, 6148, + 30883, 30887, 30893, 30897, 30903, 30908, 30915, 1441, 30921, 30928, + 1348, 6156, 30932, 30942, 30950, 30956, 30966, 30975, 30983, 30989, + 30997, 31004, 12136, 31010, 31017, 31022, 31029, 1494, 219, 2173, 31035, + 31041, 31048, 31059, 31070, 31078, 31085, 31095, 31104, 31112, 31121, + 31128, 31135, 31148, 31155, 31161, 31172, 31191, 1253, 31196, 31201, + 31209, 3742, 31213, 31218, 31222, 31226, 1445, 26637, 31236, 31240, + 31245, 31249, 3619, 31255, 31263, 31270, 31281, 31289, 31297, 3743, 346, + 31302, 31310, 31318, 31325, 31331, 31336, 2242, 11628, 31343, 31349, + 28038, 28287, 31355, 574, 106, 31359, 31363, 31369, 663, 9841, 31374, + 31381, 31387, 31391, 1639, 31394, 31398, 16576, 31401, 31406, 31413, + 31419, 31424, 31432, 31439, 31445, 24132, 31449, 31453, 31457, 3813, + 18180, 31461, 31466, 31470, 31473, 31481, 31489, 31494, 31502, 31505, + 31512, 31522, 31534, 31539, 31543, 31551, 31558, 31564, 31571, 31578, + 31581, 31585, 31589, 1449, 31599, 31601, 31606, 31612, 31618, 31623, + 31628, 31633, 31638, 31643, 31648, 31653, 31658, 31663, 31668, 31673, + 31678, 31683, 31688, 31694, 31700, 31706, 31712, 31717, 31722, 31727, + 31733, 31738, 31743, 31748, 31754, 31759, 31765, 31770, 31775, 31780, + 31785, 31791, 31796, 31802, 31807, 31812, 31817, 31822, 31828, 31833, + 31839, 31844, 31849, 31854, 31859, 31864, 31869, 31874, 31879, 31884, + 31890, 31896, 31902, 31907, 31912, 31917, 31922, 31928, 31934, 31940, + 31946, 31952, 31958, 31963, 31969, 31974, 31979, 31984, 31989, 31995, + 2482, 32000, 2489, 2496, 2793, 32005, 2502, 2512, 32011, 32015, 32020, + 32025, 32031, 32036, 32041, 32045, 32050, 32056, 32061, 32066, 32071, + 32077, 32082, 32086, 32090, 32095, 32100, 32105, 32110, 32115, 32121, + 32127, 32132, 32136, 32141, 32147, 32151, 32156, 32161, 32166, 32171, + 32175, 32178, 32183, 32188, 32193, 32198, 32203, 32209, 32215, 32220, + 32225, 32230, 32234, 32239, 32244, 32249, 32254, 32259, 32264, 32268, + 32273, 32278, 32283, 32287, 32291, 32295, 32300, 32308, 32313, 32318, + 32324, 32330, 32336, 32341, 32345, 32348, 32353, 32358, 32362, 32367, + 32372, 32376, 32381, 32385, 32388, 32393, 3914, 18906, 32398, 32403, + 32408, 32416, 22959, 30925, 9518, 32421, 32426, 32430, 32435, 32439, + 32443, 32448, 32452, 32455, 32458, 32462, 32467, 32471, 32479, 32483, + 32486, 32491, 32495, 32499, 32504, 32509, 32513, 32519, 32524, 32529, + 32536, 32543, 32547, 32550, 32556, 32565, 32572, 32580, 32587, 32591, + 32596, 32600, 32604, 32610, 32616, 32620, 32626, 32631, 32636, 32640, + 32647, 32653, 32659, 32665, 32671, 32678, 32684, 32690, 32696, 32702, + 32708, 32714, 32720, 32727, 32733, 32740, 32746, 32752, 32758, 32764, + 32770, 32776, 32782, 32788, 32794, 12479, 32800, 32806, 32811, 32816, + 32821, 32824, 32830, 32838, 32843, 32847, 32852, 32858, 32867, 32873, + 32878, 32883, 32888, 32892, 32897, 32902, 32907, 32912, 32917, 32924, + 32931, 32937, 32943, 32948, 17822, 32955, 32961, 32968, 32974, 32980, + 32985, 32993, 32998, 10372, 33002, 33007, 33012, 33018, 33023, 33028, + 33032, 33037, 33042, 33048, 33053, 33058, 33063, 33067, 33072, 33077, + 33081, 33086, 33091, 33095, 33100, 33104, 33109, 33114, 33119, 33123, + 33128, 33132, 33136, 16682, 33141, 33150, 33156, 33162, 33171, 33179, + 33188, 33196, 33201, 33205, 33212, 33218, 33226, 33230, 33233, 33238, + 33242, 33251, 33259, 33277, 33283, 1493, 33289, 33292, 33296, 24238, + 24244, 33302, 33306, 33317, 33328, 33339, 33351, 33355, 33362, 33369, + 33374, 33378, 6204, 928, 22958, 33386, 33391, 33395, 33400, 33404, 33410, + 33415, 33421, 33426, 33432, 33437, 33443, 33448, 33454, 33460, 33466, + 33471, 33427, 33433, 33475, 33480, 33486, 33491, 33497, 33502, 33508, + 33513, 33438, 11314, 33517, 33449, 33455, 33461, 2885, 3533, 33523, + 33526, 33531, 33537, 33543, 33549, 33556, 33562, 33568, 33574, 33580, + 33586, 33592, 33598, 33604, 33610, 33616, 33622, 33628, 33635, 33641, + 33647, 33653, 33659, 33665, 33668, 33673, 33676, 33683, 33688, 33696, + 33701, 33706, 33712, 33717, 33722, 33726, 33731, 33737, 33742, 33748, + 33753, 33759, 33764, 33770, 33776, 33780, 33785, 33790, 33795, 33800, + 33804, 33809, 33814, 33819, 33825, 33831, 33837, 33843, 33848, 33852, + 33855, 33861, 33867, 33876, 33884, 33891, 33896, 33900, 33904, 33909, + 16530, 33914, 33922, 33928, 3866, 1358, 33933, 33937, 8359, 33943, 33949, + 33956, 8368, 33960, 33966, 33973, 33979, 33988, 33996, 9244, 34008, + 34012, 34019, 34025, 34030, 34034, 34038, 34041, 34051, 34060, 34068, + 33428, 34073, 34083, 34093, 34103, 34109, 34114, 34124, 34129, 34142, + 34156, 34167, 34179, 34191, 34205, 34218, 34230, 34242, 15899, 34256, + 34261, 34266, 34270, 34274, 34278, 1795, 29290, 34282, 34287, 33476, + 34292, 34295, 34300, 34305, 34310, 34316, 34322, 10974, 34327, 34333, + 34340, 17130, 34346, 34351, 34356, 34360, 34365, 34370, 33481, 34375, + 34380, 34385, 34391, 33487, 34396, 34399, 34406, 34414, 34420, 34426, + 34432, 34443, 34448, 34455, 34462, 34469, 34477, 34486, 34495, 34501, + 34507, 34515, 33492, 34520, 34526, 34532, 33498, 34537, 34542, 34550, + 34558, 34564, 34571, 34577, 34584, 34591, 34597, 34605, 34615, 34622, + 34628, 34633, 34639, 34644, 34649, 34656, 34665, 34673, 34678, 34684, + 34691, 34699, 34705, 34710, 34716, 34725, 34732, 30135, 34738, 34742, + 34747, 34756, 34761, 34766, 34771, 13548, 34779, 34784, 34789, 34794, + 34798, 34803, 34808, 34815, 34820, 34825, 34830, 33503, 22895, 34836, + 2558, 144, 34839, 34842, 34846, 34850, 34860, 34868, 34875, 34879, 34882, + 34890, 34897, 34904, 34913, 34917, 34920, 34926, 34930, 34938, 34946, + 34950, 34954, 34957, 34963, 34970, 34974, 34978, 34985, 34993, 33439, + 35000, 35008, 35013, 11034, 623, 369, 35025, 35030, 35035, 35041, 35046, + 35051, 3887, 35056, 35059, 35064, 35069, 35074, 35079, 35084, 35091, + 24356, 35096, 35101, 35106, 35111, 35116, 35122, 35127, 35133, 33679, + 35139, 35144, 35150, 35156, 35166, 35171, 35176, 35180, 35185, 35190, + 35195, 35200, 35213, 35218, 24019, 18255, 3900, 35222, 35228, 35233, + 35238, 35244, 35249, 35254, 35258, 35263, 35268, 35274, 35279, 35284, + 1363, 35288, 35293, 35298, 35303, 35307, 35312, 35317, 35322, 35328, + 35334, 35339, 35343, 35347, 35352, 35357, 35362, 35366, 35374, 35378, + 35384, 35388, 35395, 18039, 33450, 35401, 35408, 35416, 35423, 35429, + 35442, 35454, 35459, 35465, 35469, 2812, 35473, 35477, 34965, 35486, + 35497, 35502, 30198, 35507, 35512, 35516, 35521, 24249, 35525, 35529, + 35534, 33456, 22985, 35538, 35543, 35549, 35554, 35558, 35562, 35565, + 35569, 35575, 35584, 35595, 35607, 33462, 35612, 35615, 35619, 35623, + 406, 35628, 35633, 35638, 35643, 35648, 35653, 35659, 35664, 35669, + 35675, 35680, 35686, 35691, 35697, 35702, 35707, 35712, 35717, 35722, + 35727, 35732, 35737, 35743, 35748, 35753, 35758, 35763, 35768, 35773, + 35778, 35784, 35790, 35795, 35800, 35805, 35810, 35815, 35820, 35825, + 35830, 35835, 35840, 35845, 35850, 35855, 35860, 35865, 35870, 35875, + 35880, 35886, 325, 9, 35891, 35895, 35899, 35907, 35911, 35915, 35918, + 35921, 35923, 35928, 35932, 35937, 35941, 35946, 35950, 35955, 35959, + 35962, 35964, 35968, 35973, 35977, 35988, 35991, 35993, 35997, 36009, + 36018, 36022, 36026, 36032, 36037, 36046, 36052, 36057, 36062, 36066, + 36070, 36075, 36082, 36087, 36093, 36098, 36102, 36109, 27731, 27741, + 36113, 36118, 36123, 36128, 36135, 36139, 36146, 36152, 8491, 36156, + 36165, 36173, 36188, 36202, 36211, 36219, 36230, 36239, 36244, 36251, + 7556, 36261, 36266, 36271, 36275, 36278, 36283, 36287, 36292, 36296, + 36303, 36308, 36313, 36318, 9391, 36328, 36330, 36333, 36336, 36340, + 36346, 36350, 36355, 36360, 36378, 36392, 36411, 36428, 36437, 36445, + 36450, 36455, 1486, 36461, 36467, 36472, 36482, 36491, 36499, 36504, + 36510, 36515, 36524, 36535, 36540, 36547, 36551, 36558, 36566, 36573, + 36586, 36594, 36598, 36608, 36613, 36617, 36625, 36633, 36638, 36642, + 36646, 36655, 36661, 36666, 36674, 36684, 36693, 36702, 36711, 36722, + 36730, 36741, 36750, 36757, 36763, 36768, 36779, 36790, 36795, 36799, + 36802, 36806, 36814, 36820, 36831, 36842, 36853, 36864, 36875, 36886, + 36897, 36908, 36920, 36932, 36944, 36956, 36968, 36980, 36992, 36996, + 37004, 37010, 37017, 37023, 37028, 37034, 2457, 37038, 37040, 37045, + 37050, 37055, 37058, 37060, 37064, 37067, 37074, 37078, 10664, 37082, + 37088, 37098, 37103, 37109, 37113, 37118, 37131, 28162, 37137, 37146, + 37155, 19104, 37162, 37171, 34089, 37179, 37184, 37188, 37197, 37205, + 37212, 37217, 37221, 37226, 37234, 37238, 37246, 37252, 37258, 37263, + 37267, 37270, 37275, 37288, 37304, 24840, 37321, 37333, 37350, 37362, + 37376, 24857, 24876, 37388, 37400, 2719, 37414, 37419, 37424, 37429, + 37433, 37440, 37452, 37459, 37468, 37471, 37482, 37493, 37498, 34512, + 852, 37502, 37506, 37510, 37513, 37518, 37523, 37529, 37534, 37539, + 37545, 37551, 37556, 37560, 37565, 37570, 37575, 37579, 37582, 37588, + 37593, 37598, 37603, 37607, 37612, 37618, 37626, 28414, 37631, 37636, + 37643, 37649, 37655, 37660, 37668, 24365, 37675, 37680, 37685, 37690, + 37694, 37697, 37702, 37706, 37710, 37717, 37723, 37729, 37735, 37742, + 37747, 37753, 36628, 37757, 37761, 37766, 37779, 37784, 37790, 37798, + 37805, 37813, 37823, 37829, 37835, 37841, 37845, 37854, 37862, 37869, + 37874, 37879, 11337, 37884, 37891, 37897, 37907, 37912, 37918, 37926, + 3775, 37933, 37940, 37946, 37953, 3781, 37957, 37962, 37973, 37980, + 37986, 37995, 37999, 4244, 38002, 38009, 38015, 38021, 38029, 38039, + 31326, 38046, 38054, 38060, 38065, 38071, 38076, 38080, 28010, 38086, + 38093, 38099, 38108, 38115, 25565, 38121, 38126, 38130, 38138, 38146, + 10330, 6179, 38153, 38157, 38159, 38163, 38168, 38170, 38175, 38181, + 38186, 38191, 38198, 35087, 38204, 38209, 38213, 38218, 38222, 38231, + 38235, 38241, 38248, 38254, 38261, 38266, 38275, 38280, 38284, 38289, + 38296, 38304, 38312, 38317, 23041, 38321, 38324, 38328, 38332, 11725, + 872, 38336, 38341, 38349, 38353, 38362, 38369, 38373, 38377, 38385, + 38392, 38402, 38406, 38410, 38418, 38426, 38432, 38437, 38446, 14530, + 38452, 38461, 38466, 38473, 38480, 38488, 38496, 38504, 38509, 38516, + 38523, 38530, 38537, 38544, 38549, 38555, 38572, 38580, 38590, 38598, + 38605, 414, 38609, 38615, 38619, 38624, 36235, 38630, 38633, 38637, + 38648, 38656, 3786, 38664, 38670, 38676, 38686, 38695, 38705, 38712, + 38718, 38723, 3792, 3798, 38732, 38739, 38747, 38752, 38756, 38763, + 38771, 38778, 38784, 38793, 38803, 38809, 38817, 38826, 38833, 38841, + 38848, 23728, 38852, 38859, 38865, 38875, 38884, 38892, 38903, 38907, + 38917, 38923, 38930, 38938, 38947, 38956, 38966, 38977, 38984, 38989, + 38996, 3088, 39004, 39010, 39015, 39021, 39027, 39032, 39045, 39058, + 39071, 39078, 39084, 39092, 39100, 39105, 39109, 1455, 39113, 39117, + 39121, 39125, 39129, 39133, 39137, 39141, 39145, 39149, 39153, 39157, + 39161, 39165, 39169, 39173, 39177, 39181, 39185, 39189, 39193, 39197, + 39201, 39205, 39209, 39213, 39217, 39221, 39225, 39229, 39233, 39237, + 39241, 39245, 39249, 39253, 39257, 39261, 39265, 39269, 39273, 39277, + 39281, 39285, 39289, 39293, 39297, 39301, 39305, 39309, 39313, 39317, + 39321, 39325, 39329, 39333, 39337, 39341, 39345, 39349, 39353, 39357, + 39361, 39365, 39369, 39373, 39377, 39381, 39385, 39389, 39393, 39397, + 39401, 39405, 39409, 39413, 39417, 39421, 39425, 39429, 39433, 39437, + 39441, 39445, 39449, 39453, 39457, 39461, 39465, 39469, 39473, 39477, + 39481, 39485, 39489, 39493, 39497, 39501, 39505, 39509, 39513, 39517, + 39521, 39525, 39529, 39533, 39537, 39541, 39545, 39549, 39553, 39557, + 39561, 39565, 39569, 39573, 39577, 39581, 39585, 39589, 39593, 39597, + 39601, 39605, 39609, 39613, 39617, 39621, 39625, 39629, 39633, 39637, + 39641, 39645, 39649, 39653, 39657, 39661, 39665, 39669, 39673, 39677, + 39681, 39685, 39689, 39693, 39697, 39701, 39705, 39709, 39713, 39717, + 39721, 39725, 39730, 39734, 39739, 39743, 39748, 39752, 39757, 39761, + 39767, 39772, 39776, 39781, 39785, 39790, 39794, 39799, 39803, 39808, + 39812, 39817, 39821, 39826, 39830, 39836, 39842, 39847, 39851, 39856, + 39860, 39866, 39871, 39875, 39880, 39884, 39889, 39893, 39899, 39904, + 39908, 39913, 39917, 39922, 39926, 39931, 39935, 39941, 39946, 39950, + 39955, 39959, 39965, 39970, 39974, 39979, 39983, 39988, 39992, 39997, + 40001, 40006, 40010, 40016, 40021, 40025, 40031, 40036, 40040, 40046, + 40051, 40055, 40060, 40064, 40069, 40073, 40079, 40085, 40091, 40097, + 40103, 40109, 40115, 40121, 40126, 40130, 40135, 40139, 40145, 40150, + 40154, 40159, 40163, 40168, 40172, 40177, 40181, 40186, 40190, 40195, + 40199, 40204, 40208, 40214, 40219, 40223, 40228, 40232, 40238, 40244, + 40249, 116, 57, 40253, 40255, 40259, 40263, 40267, 40272, 40276, 40280, + 10251, 40285, 40291, 1756, 6597, 40297, 40300, 40305, 40309, 40314, + 40318, 40322, 40327, 11121, 40331, 40335, 40339, 525, 40343, 16783, + 40348, 40352, 40357, 40362, 40367, 40371, 40378, 28186, 40384, 40387, + 40391, 40396, 40402, 40406, 40409, 40417, 40423, 40428, 40432, 40435, + 40439, 40445, 40449, 40453, 3584, 3589, 31537, 40456, 40460, 40464, + 40468, 40472, 40480, 40487, 40491, 14480, 40498, 40503, 40517, 40524, + 40535, 335, 40540, 40544, 40550, 40562, 40568, 40574, 31574, 40578, + 40584, 40593, 40597, 40601, 40606, 40612, 40617, 40621, 40626, 40630, + 40634, 40641, 40647, 40652, 40667, 40682, 40697, 40713, 40731, 11071, + 40745, 40752, 40756, 40759, 40768, 40773, 40777, 40785, 17333, 40793, + 40797, 40807, 40818, 31507, 40831, 40835, 40844, 40862, 40881, 40889, + 10525, 11234, 40893, 24261, 40896, 32475, 40901, 10524, 40906, 40912, + 40917, 40923, 40928, 40934, 40939, 40945, 40950, 40956, 40962, 40968, + 40973, 40929, 40935, 40940, 40946, 40951, 40957, 40963, 8504, 4089, + 40977, 40985, 40989, 40992, 40996, 41001, 41006, 41013, 41019, 41025, + 41030, 16174, 41034, 28022, 41038, 41042, 41046, 41052, 41056, 30075, + 41065, 9544, 41069, 9937, 41072, 41079, 41085, 41089, 13004, 41096, + 41102, 41107, 41114, 41121, 41128, 30781, 8410, 41135, 41142, 41149, + 41155, 41160, 41167, 41178, 41184, 41189, 41194, 41199, 41203, 41208, + 41215, 40930, 41219, 41229, 41238, 41249, 41255, 41263, 41270, 41275, + 41280, 41285, 41290, 41295, 41299, 41303, 41310, 41316, 41324, 2353, + 1050, 11137, 11149, 11154, 11160, 41333, 11165, 11170, 11176, 41338, + 41348, 41352, 11181, 41357, 18453, 41360, 41365, 41369, 37463, 41380, + 41385, 41392, 41399, 41403, 41406, 41414, 11084, 41421, 41424, 41430, + 41440, 6231, 41449, 41455, 41459, 41467, 41471, 41481, 41487, 41492, + 41503, 41512, 41521, 41530, 41539, 41548, 41557, 41566, 41572, 41578, + 41583, 41589, 41595, 41601, 41606, 41609, 41616, 41622, 41626, 41631, + 41638, 41645, 41649, 41652, 41662, 41675, 41684, 41693, 41704, 41717, + 41729, 41740, 41749, 41760, 41765, 41774, 41779, 11186, 41785, 41792, + 41800, 41805, 41809, 41816, 41823, 4041, 20, 41827, 41832, 18302, 41836, + 41839, 41842, 30255, 41846, 30790, 41854, 41858, 41862, 41865, 41871, + 41877, 33527, 41882, 41890, 41896, 41903, 30238, 41907, 30441, 41911, + 41920, 41924, 41932, 41938, 41944, 41949, 41953, 30809, 41959, 41962, + 41970, 41978, 4379, 41984, 41988, 41993, 42000, 42006, 42011, 42016, + 42020, 42026, 42031, 42037, 4297, 944, 42044, 42048, 42051, 16664, 42063, + 42071, 42079, 42087, 42095, 42102, 42110, 42118, 42125, 42133, 42141, + 42149, 42157, 42165, 42173, 42181, 42189, 42197, 42205, 42213, 42220, + 42228, 42236, 42244, 42252, 42260, 42268, 42276, 42284, 42292, 42300, + 42308, 42316, 42324, 42332, 42340, 42348, 42356, 42364, 42372, 42379, + 42387, 42394, 42402, 42410, 42418, 42426, 42434, 42442, 42450, 42458, + 42469, 23764, 42474, 42477, 42484, 42488, 42494, 42498, 42504, 42509, + 42515, 42520, 42525, 42529, 42533, 42538, 42543, 42553, 42559, 42572, + 42578, 42584, 42590, 42597, 42602, 42608, 42613, 18198, 1458, 831, 42618, + 42621, 42624, 42627, 33611, 33617, 42630, 33623, 33636, 33642, 33648, + 42636, 33654, 33660, 42642, 42648, 26, 42656, 42663, 42667, 42671, 42679, + 34401, 42683, 42687, 42694, 42699, 42703, 42708, 42714, 42719, 42725, + 42730, 42734, 42738, 42742, 42747, 42751, 42756, 42760, 42764, 42771, + 42776, 42780, 42784, 42789, 42793, 42798, 42802, 42806, 42811, 42817, + 16924, 16929, 42822, 42826, 42829, 42833, 42837, 22852, 42842, 42846, + 42852, 42859, 42865, 42870, 42880, 42885, 42893, 42897, 42900, 34416, + 42904, 4356, 42909, 42914, 42918, 42923, 42927, 42932, 14548, 42943, + 42947, 42950, 42954, 42959, 42963, 42968, 42973, 42977, 42981, 42985, + 42988, 42992, 8523, 14564, 42995, 42998, 43004, 43009, 43015, 43020, + 43026, 43031, 43037, 43042, 43048, 43054, 43060, 43065, 43069, 43073, + 43082, 43098, 43114, 43124, 30145, 43131, 43135, 43140, 43145, 43149, + 43153, 38951, 43159, 43164, 43168, 43175, 43180, 43185, 43189, 43193, + 43199, 29093, 43203, 23136, 43208, 43215, 43223, 43229, 43236, 43244, + 43250, 43254, 43259, 43265, 43273, 43278, 43282, 43291, 10232, 43299, + 43303, 43311, 43318, 43323, 43328, 43333, 43337, 43340, 43344, 43347, + 43351, 43358, 43363, 43367, 43373, 28492, 33674, 43377, 43386, 43394, + 43400, 43407, 43413, 43419, 43424, 43427, 43429, 43436, 43443, 43449, + 43453, 43456, 43460, 43464, 43468, 43473, 43477, 43481, 43484, 43488, + 43502, 24906, 43521, 43534, 43547, 43560, 24924, 43575, 11422, 43590, + 43596, 43600, 43604, 43608, 43612, 43619, 43624, 43628, 43635, 43641, + 43646, 43652, 43662, 43674, 43685, 43690, 43697, 43701, 43705, 43708, + 17343, 3855, 43716, 16951, 43729, 43736, 43743, 43747, 43751, 43756, + 43762, 43767, 43773, 43777, 43781, 43784, 43789, 43793, 43798, 8082, + 16962, 43803, 43807, 43813, 43822, 43827, 43836, 43843, 38799, 43849, + 43854, 43858, 43863, 43870, 43876, 43880, 43883, 43887, 43892, 15864, + 43899, 43906, 43910, 43913, 43918, 43923, 43929, 43934, 43939, 43943, + 43948, 43958, 43963, 43969, 43974, 43980, 43985, 43991, 44001, 44006, + 44011, 44015, 44020, 7558, 7570, 44025, 44028, 44035, 44041, 44050, 9477, + 36760, 44058, 44062, 44066, 34464, 44074, 44085, 44093, 38999, 44100, + 44105, 44110, 44121, 44128, 44139, 34488, 23147, 44147, 907, 44152, + 14913, 44158, 30229, 44164, 44169, 44179, 44188, 44195, 44201, 44205, + 44208, 44215, 44221, 44228, 44234, 44244, 44252, 44258, 44264, 44269, + 44273, 44280, 44285, 44291, 44298, 44304, 43469, 44309, 44313, 558, + 15029, 44319, 44324, 44327, 44333, 44341, 1380, 44346, 44350, 44355, + 44360, 44365, 44372, 44376, 44381, 44387, 44391, 33684, 44396, 44401, + 44410, 44417, 44427, 44433, 30273, 44450, 44459, 44467, 44473, 44478, + 44485, 44491, 44499, 44508, 44516, 44520, 44525, 44533, 31251, 34497, + 44539, 44558, 17257, 44572, 44588, 44602, 44608, 44613, 44618, 44623, + 44629, 34503, 44634, 44637, 44644, 44649, 44653, 404, 2995, 44660, 44665, + 44670, 29451, 44488, 44674, 44679, 44687, 44691, 44694, 44699, 44705, + 44711, 44716, 44720, 30328, 44723, 44728, 44732, 44735, 44740, 44744, + 44749, 44754, 44758, 44763, 44767, 44771, 44775, 22848, 22859, 44780, + 44785, 44791, 44796, 44802, 29050, 44807, 44811, 22945, 17549, 44814, + 44819, 44824, 44829, 44834, 44839, 44844, 44849, 474, 68, 33697, 33702, + 33707, 33713, 33718, 33723, 44854, 33727, 44858, 44862, 44866, 33732, + 33738, 44880, 33749, 33754, 44888, 44893, 33760, 44898, 44903, 44908, + 44913, 44919, 44925, 44931, 33777, 44944, 44953, 44959, 33781, 44963, + 33786, 44968, 33791, 33796, 44971, 44976, 44980, 44986, 33332, 44993, + 14794, 45000, 45005, 33801, 45009, 45014, 45019, 45024, 45028, 45033, + 45038, 45044, 45049, 45054, 45060, 45066, 45071, 45075, 45080, 45085, + 45090, 45094, 45099, 45104, 45109, 45115, 45121, 45127, 45132, 45136, + 45141, 45145, 33805, 33810, 33815, 45149, 45153, 45157, 33820, 33826, + 33832, 33844, 45169, 28059, 45173, 45178, 45182, 45187, 45194, 45199, + 45204, 45209, 45213, 45217, 45227, 45232, 45237, 45241, 45245, 45248, + 45256, 33892, 45261, 1465, 45267, 45272, 45278, 45286, 45290, 45299, + 45303, 45307, 45315, 45321, 45329, 45345, 45349, 45353, 45357, 45362, + 45368, 45383, 33929, 1764, 13198, 45387, 1359, 1374, 45399, 45407, 45414, + 45419, 45426, 45431, 9922, 1139, 2544, 11213, 45438, 9820, 45443, 45446, + 45455, 1267, 45460, 43625, 45467, 45476, 45481, 45485, 45493, 24317, + 2596, 45500, 11678, 45510, 45516, 2371, 2381, 45525, 45534, 45544, 45555, + 3376, 37099, 45560, 11277, 4019, 18236, 1272, 45564, 45572, 45579, 45584, + 45588, 45592, 25792, 43894, 11304, 45600, 45609, 45618, 45626, 45633, + 45644, 45649, 45662, 45675, 45687, 45699, 45711, 45722, 45735, 45746, + 45757, 45767, 45775, 45783, 45795, 45807, 45818, 45827, 45835, 45842, + 45854, 45861, 45867, 45876, 45883, 45896, 45901, 45911, 45916, 45922, + 45927, 41086, 45931, 45938, 45942, 45949, 45957, 45964, 2557, 45971, + 45982, 45992, 46001, 46009, 46019, 46027, 46037, 46046, 46051, 46057, + 46063, 3899, 46074, 46084, 46093, 46102, 46110, 46120, 46128, 46137, + 46142, 46147, 46152, 1694, 47, 46160, 46168, 46179, 46190, 17875, 46200, + 46204, 46211, 46217, 46222, 46226, 46237, 46247, 46256, 46267, 18275, + 18280, 46272, 46281, 46286, 46296, 46301, 46309, 46317, 46324, 46330, + 1656, 277, 46334, 46340, 46345, 46348, 2143, 43748, 46356, 46360, 46363, + 1510, 46369, 15214, 1277, 46374, 46387, 46401, 2682, 46419, 46431, 46443, + 2696, 2713, 46457, 46470, 2728, 46484, 46496, 2743, 46510, 1283, 1289, + 1295, 11584, 46515, 46520, 46525, 46529, 46544, 46559, 46574, 46589, + 46604, 46619, 46634, 46649, 46664, 46679, 46694, 46709, 46724, 46739, + 46754, 46769, 46784, 46799, 46814, 46829, 46844, 46859, 46874, 46889, + 46904, 46919, 46934, 46949, 46964, 46979, 46994, 47009, 47024, 47039, + 47054, 47069, 47084, 47099, 47114, 47129, 47144, 47159, 47174, 47189, + 47204, 47219, 47234, 47249, 47264, 47279, 47294, 47309, 47324, 47339, + 47354, 47369, 47384, 47399, 47414, 47429, 47444, 47459, 47474, 47489, + 47504, 47519, 47534, 47549, 47564, 47579, 47594, 47609, 47624, 47639, + 47654, 47669, 47684, 47699, 47714, 47729, 47744, 47759, 47774, 47789, + 47804, 47819, 47834, 47849, 47864, 47879, 47894, 47909, 47924, 47939, + 47954, 47969, 47984, 47999, 48014, 48029, 48044, 48059, 48074, 48089, + 48104, 48119, 48134, 48149, 48164, 48179, 48194, 48209, 48224, 48239, + 48254, 48269, 48284, 48299, 48314, 48329, 48344, 48359, 48374, 48389, + 48404, 48419, 48434, 48449, 48464, 48479, 48494, 48509, 48524, 48539, + 48554, 48569, 48584, 48599, 48614, 48629, 48644, 48659, 48674, 48689, + 48704, 48719, 48734, 48749, 48764, 48779, 48794, 48809, 48824, 48839, + 48854, 48869, 48884, 48899, 48914, 48929, 48944, 48959, 48974, 48989, + 49004, 49019, 49034, 49049, 49064, 49079, 49094, 49109, 49124, 49139, + 49154, 49169, 49184, 49199, 49214, 49229, 49244, 49259, 49274, 49289, + 49304, 49319, 49334, 49349, 49364, 49379, 49394, 49409, 49424, 49439, + 49454, 49469, 49484, 49499, 49514, 49529, 49544, 49559, 49574, 49589, + 49604, 49619, 49634, 49649, 49664, 49679, 49694, 49709, 49724, 49739, + 49754, 49769, 49784, 49799, 49814, 49829, 49844, 49859, 49874, 49889, + 49904, 49919, 49934, 49949, 49964, 49979, 49994, 50009, 50024, 50039, + 50054, 50069, 50084, 50099, 50114, 50129, 50144, 50159, 50174, 50189, + 50204, 50219, 50234, 50249, 50264, 50279, 50294, 50309, 50324, 50339, + 50354, 50369, 50384, 50399, 50414, 50429, 50444, 50459, 50474, 50489, + 50504, 50519, 50534, 50549, 50564, 50579, 50594, 50609, 50624, 50639, + 50654, 50669, 50684, 50699, 50714, 50729, 50744, 50759, 50774, 50789, + 50804, 50819, 50834, 50849, 50864, 50879, 50894, 50909, 50924, 50939, + 50954, 50969, 50984, 50999, 51014, 51029, 51044, 51059, 51074, 51089, + 51104, 51119, 51134, 51149, 51164, 51179, 51194, 51209, 51224, 51239, + 51254, 51269, 51284, 51299, 51314, 51329, 51344, 51359, 51374, 51389, + 51404, 51419, 51434, 51449, 51464, 51479, 51494, 51509, 51524, 51539, + 51554, 51569, 51584, 51599, 51614, 51629, 51644, 51659, 51674, 51689, + 51704, 51719, 51734, 51749, 51764, 51779, 51794, 51809, 51824, 51839, + 51854, 51869, 51884, 51899, 51914, 51929, 51944, 51959, 51974, 51989, + 52004, 52019, 52034, 52049, 52064, 52079, 52094, 52109, 52124, 52139, + 52154, 52169, 52184, 52199, 52214, 52229, 52244, 52259, 52274, 52289, + 52304, 52319, 52334, 52349, 52364, 52379, 52394, 52409, 52424, 52439, + 52454, 52469, 52484, 52499, 52514, 52529, 52544, 52559, 52574, 52589, + 52604, 52619, 52634, 52649, 52664, 52679, 52694, 52709, 52724, 52739, + 52754, 52769, 52784, 52799, 52814, 52829, 52844, 52859, 52874, 52889, + 52904, 52919, 52934, 52949, 52964, 52979, 52994, 53009, 53024, 53039, + 53054, 53069, 53084, 53099, 53114, 53129, 53144, 53159, 53174, 53189, + 53204, 53219, 53234, 53249, 53264, 53279, 53294, 53309, 53324, 53339, + 53354, 53369, 53384, 53399, 53414, 53429, 53444, 53459, 53474, 53489, + 53504, 53519, 53534, 53549, 53564, 53579, 53594, 53609, 53624, 53639, + 53654, 53669, 53684, 53699, 53714, 53729, 53744, 53759, 53774, 53789, + 53804, 53819, 53834, 53849, 53864, 53879, 53894, 53909, 53924, 53939, + 53954, 53969, 53984, 53999, 54014, 54029, 54044, 54059, 54074, 54089, + 54104, 54119, 54134, 54149, 54164, 54179, 54194, 54209, 54224, 54239, + 54254, 54269, 54284, 54299, 54314, 54329, 54345, 54361, 54377, 54393, + 54409, 54425, 54441, 54457, 54473, 54489, 54505, 54521, 54537, 54553, + 54569, 54585, 54601, 54617, 54633, 54649, 54665, 54681, 54697, 54713, + 54729, 54745, 54761, 54777, 54793, 54809, 54825, 54841, 54857, 54873, + 54889, 54905, 54921, 54937, 54953, 54969, 54985, 55001, 55017, 55033, + 55049, 55065, 55081, 55097, 55113, 55129, 55145, 55161, 55177, 55193, + 55209, 55225, 55241, 55257, 55273, 55289, 55305, 55321, 55337, 55353, + 55369, 55385, 55401, 55417, 55433, 55449, 55465, 55481, 55497, 55513, + 55529, 55545, 55561, 55577, 55593, 55609, 55625, 55641, 55657, 55673, + 55689, 55705, 55721, 55737, 55753, 55769, 55785, 55801, 55817, 55833, + 55849, 55865, 55881, 55897, 55913, 55929, 55945, 55961, 55977, 55993, + 56009, 56025, 56041, 56057, 56073, 56089, 56105, 56121, 56137, 56153, + 56169, 56185, 56201, 56217, 56233, 56249, 56265, 56281, 56297, 56313, + 56329, 56345, 56361, 56377, 56393, 56409, 56425, 56441, 56457, 56473, + 56489, 56505, 56521, 56537, 56553, 56569, 56585, 56601, 56617, 56633, + 56649, 56665, 56681, 56697, 56713, 56729, 56745, 56761, 56777, 56793, + 56809, 56825, 56841, 56857, 56873, 56889, 56905, 56921, 56937, 56953, + 56969, 56985, 57001, 57017, 57033, 57049, 57065, 57081, 57097, 57113, + 57129, 57145, 57161, 57177, 57193, 57209, 57225, 57241, 57257, 57273, + 57289, 57305, 57321, 57337, 57353, 57369, 57385, 57401, 57417, 57433, + 57449, 57465, 57481, 57497, 57513, 57529, 57545, 57561, 57577, 57593, + 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, 63016, 18307, + 63025, 63030, 63036, 63042, 63052, 63060, 16270, 16868, 10733, 63073, + 1518, 1522, 63081, 3973, 29566, 7512, 63087, 63092, 63097, 63102, 63107, + 63113, 63118, 63124, 63129, 63135, 63140, 63145, 63150, 63155, 63161, + 63166, 63171, 63176, 63181, 63186, 63191, 63196, 63202, 63207, 63213, + 63220, 2600, 63225, 63231, 8912, 63235, 63240, 63247, 63255, 65, 63259, + 63265, 63270, 63275, 63279, 63284, 63288, 63292, 11621, 63296, 63306, + 63319, 63330, 63343, 63350, 63356, 63364, 63369, 63375, 63381, 63387, + 63392, 63397, 63402, 63407, 63411, 63416, 63421, 63426, 63432, 63438, + 63444, 63449, 63453, 63458, 63463, 63467, 63472, 63477, 63482, 63486, + 11637, 11648, 11653, 1561, 63490, 63496, 1566, 63501, 63504, 17741, + 63509, 63515, 63520, 1597, 63526, 1603, 1609, 11683, 63531, 63540, 63548, + 63555, 63559, 63563, 63569, 63574, 33365, 63579, 63586, 63593, 63598, + 63602, 63606, 63615, 1614, 17850, 63620, 63624, 17861, 1162, 63628, + 63635, 63640, 63644, 17891, 1618, 41243, 63647, 63652, 63662, 63671, + 63676, 63680, 63686, 1623, 43855, 63691, 63700, 63706, 63711, 63716, + 11882, 11888, 63722, 63734, 63751, 63768, 63785, 63802, 63819, 63836, + 63853, 63870, 63887, 63904, 63921, 63938, 63955, 63972, 63989, 64006, + 64023, 64040, 64057, 64074, 64091, 64108, 64125, 64142, 64159, 64176, + 64193, 64210, 64227, 64244, 64261, 64278, 64295, 64312, 64329, 64346, + 64363, 64380, 64397, 64414, 64431, 64448, 64465, 64482, 64499, 64516, + 64533, 64550, 64567, 64578, 64588, 64593, 1628, 64597, 64602, 64608, + 64613, 64618, 64625, 9839, 1633, 64631, 64640, 29887, 64645, 64656, + 11899, 64666, 64671, 64677, 64682, 64689, 64695, 64700, 1638, 18174, + 64705, 64711, 11909, 1643, 11914, 64717, 64722, 64728, 64733, 64738, + 64743, 64748, 64753, 64758, 64763, 64768, 64774, 64780, 64786, 64791, + 64795, 64800, 64805, 64809, 64814, 64819, 64824, 64829, 64833, 64838, + 64844, 64849, 64854, 64858, 64863, 64868, 64874, 64879, 64884, 64890, + 64896, 64901, 64905, 64910, 64915, 64920, 64924, 64929, 64934, 64939, + 64945, 64951, 64956, 64960, 64964, 64969, 64974, 64979, 31395, 64983, + 64988, 64993, 64999, 65004, 65009, 65013, 65018, 65023, 65029, 65034, + 65039, 65045, 65051, 65056, 65060, 65065, 65070, 65074, 65079, 65084, + 65089, 65095, 65101, 65106, 65110, 65115, 65120, 65124, 65129, 65134, + 65139, 65144, 65148, 65151, 65154, 65159, 65164, 34056, 65171, 65179, + 3691, 29837, 65185, 65192, 65198, 3830, 12020, 65204, 65214, 65229, + 65237, 12025, 65248, 65253, 65264, 65276, 65288, 65300, 2734, 65312, + 65317, 65329, 65333, 65339, 65345, 65350, 1660, 17418, 65359, 65364, + 43914, 65368, 65372, 65377, 65381, 18315, 65386, 65389, 65394, 65402, + 65410, 1664, 12061, 12067, 1669, 65418, 65425, 65430, 65439, 65449, + 65456, 65461, 65466, 1674, 65473, 65478, 18435, 65482, 65487, 65494, + 65500, 65504, 65515, 65525, 65532, 18457, 9733, 9740, 4022, 4028, 65539, + 1679, 65544, 65550, 65558, 65565, 65571, 65578, 65590, 65596, 65601, + 65613, 65624, 65633, 65643, 3952, 65651, 33166, 33175, 18497, 1684, 1688, + 65664, 65675, 65680, 1698, 65688, 65693, 65698, 18556, 65710, 65713, + 65719, 65725, 65730, 65738, 1703, 65743, 65748, 65756, 65764, 65771, + 65780, 65788, 65797, 1708, 65801, 1713, 23016, 65806, 65813, 18630, + 65821, 65827, 65832, 65840, 65847, 65855, 65865, 65874, 65884, 65893, + 65904, 65914, 65924, 65933, 65943, 65957, 65970, 65979, 65987, 65997, + 66006, 66018, 66029, 66040, 66050, 17948, 66055, 12213, 66064, 66070, + 66075, 66082, 66089, 66095, 17617, 66105, 66111, 66116, 66127, 66132, + 66140, 12230, 12235, 66148, 66154, 66158, 66166, 4017, 18692, 44007, + 66171, 66177, 66182, 66190, 66197, 13179, 66202, 66208, 1724, 66213, + 66216, 1438, 66222, 66227, 66232, 66238, 66243, 66248, 66253, 66258, + 66263, 66268, 1733, 13, 66274, 66278, 66283, 66287, 66291, 66295, 34296, + 66300, 25070, 66305, 66310, 66314, 66317, 66321, 66325, 66330, 66334, + 66339, 66343, 66349, 37514, 37519, 37524, 66352, 66359, 66365, 66373, + 43678, 66383, 37530, 34560, 34311, 34317, 37546, 34323, 66388, 66393, + 34593, 66397, 66400, 66404, 66412, 66419, 66422, 66427, 66432, 66436, + 66440, 66443, 66453, 66465, 66472, 66478, 34328, 66485, 36078, 66488, + 8929, 1019, 66491, 66495, 66500, 3873, 66504, 66507, 14827, 66514, 66521, + 66534, 66542, 66551, 66560, 66565, 66575, 66588, 66600, 66607, 66612, + 66621, 66634, 39039, 66652, 66657, 66664, 66670, 66675, 819, 66680, + 66688, 66695, 66702, 29392, 783, 66708, 66714, 66724, 66732, 66738, + 66743, 34347, 6310, 34361, 66747, 66757, 66762, 66772, 66787, 66793, + 66799, 34371, 66804, 33482, 66808, 66813, 66820, 66825, 66829, 66834, + 18500, 66841, 66846, 66850, 6351, 34397, 66854, 66860, 324, 66870, 66877, + 66884, 66889, 66898, 63656, 66904, 66912, 66916, 66920, 66924, 66928, + 66933, 66937, 66943, 66951, 66956, 66961, 66966, 66970, 66975, 66979, + 66983, 66989, 66995, 67000, 67004, 67009, 34521, 67013, 34527, 34533, + 67018, 67024, 67031, 67036, 67040, 33499, 18167, 67043, 67047, 67052, + 67059, 67065, 67069, 67074, 43353, 67080, 67084, 67091, 67095, 67100, + 67106, 67112, 67118, 67130, 67139, 67149, 67155, 67162, 67167, 67172, + 67176, 67179, 67185, 67192, 67197, 67202, 67209, 67216, 67223, 67229, + 67234, 67239, 67247, 34538, 2462, 67252, 67257, 67263, 67268, 67274, + 67279, 67284, 67289, 67295, 34559, 67300, 67306, 67312, 67318, 34629, + 67323, 67328, 67333, 34640, 67338, 67343, 67348, 67354, 67360, 34645, + 67365, 67370, 67375, 34700, 34706, 67380, 67385, 34711, 34733, 30136, + 34739, 34743, 67390, 12909, 67394, 67402, 67408, 67416, 67423, 67429, + 67439, 67445, 67452, 11556, 34757, 67458, 67471, 67480, 67486, 67495, + 67501, 25380, 67508, 67515, 67525, 67528, 34701, 67533, 67540, 67545, + 67549, 67553, 67558, 67562, 4133, 67567, 67572, 67577, 37608, 37613, + 67581, 37627, 67586, 37632, 67591, 67597, 37644, 37650, 37656, 67602, + 67608, 24366, 67619, 67622, 67634, 67642, 34780, 67646, 67655, 67665, + 67674, 34790, 67679, 67686, 67695, 67701, 67709, 67716, 6402, 4673, + 67721, 34712, 67727, 67730, 67736, 67743, 67748, 67753, 25290, 67757, + 67763, 67769, 67774, 67779, 67783, 67789, 67795, 35984, 1048, 38689, + 40419, 40425, 34821, 34826, 67800, 67804, 67808, 67811, 67824, 67830, + 67834, 67837, 67842, 36321, 67846, 33504, 22966, 67852, 6331, 6339, 9570, + 67855, 67860, 67865, 67870, 67875, 67880, 67885, 67890, 67895, 67900, + 67906, 67911, 67916, 67922, 67927, 67932, 67937, 67942, 67947, 67952, + 67958, 67963, 67969, 67974, 67979, 67984, 67989, 67994, 67999, 68004, + 68009, 68014, 68019, 68025, 68030, 68035, 68040, 68045, 68050, 68055, + 68061, 68066, 68071, 68076, 68081, 68086, 68091, 68096, 68101, 68106, + 68112, 68117, 68122, 68127, 68132, 68138, 68144, 68149, 68155, 68160, + 68165, 68170, 68175, 68180, 1511, 145, 68185, 68189, 68193, 68197, 27076, + 68201, 68205, 68210, 68214, 68219, 68223, 68228, 68233, 68238, 68242, + 68246, 68251, 68255, 14542, 68260, 68264, 68271, 68281, 16595, 68290, + 68299, 68303, 68308, 68313, 68317, 68321, 26870, 3078, 68325, 68331, + 18967, 68335, 68344, 68352, 68358, 68363, 68375, 68387, 68392, 68396, + 68401, 68405, 68411, 68417, 68422, 68432, 68442, 68448, 68453, 68457, + 68463, 68468, 68475, 68481, 68486, 68495, 68504, 68512, 16993, 68516, + 68525, 68533, 68545, 68556, 68567, 68576, 68580, 68589, 68597, 68607, + 68615, 68622, 68628, 68633, 68639, 68644, 68655, 54, 33309, 68661, 28331, + 28341, 68667, 68675, 68682, 68688, 68692, 68702, 68713, 68721, 68730, + 68735, 68740, 68745, 68749, 68753, 18921, 68761, 68765, 68771, 68781, + 68788, 68794, 68800, 37707, 68804, 68806, 68809, 68815, 68819, 68830, + 68840, 68846, 68853, 68860, 14479, 68868, 68874, 68883, 68892, 68898, + 10615, 68904, 68910, 68915, 68920, 68927, 68932, 68939, 68945, 68950, + 68958, 68971, 68980, 65919, 65929, 68989, 68995, 69001, 69008, 69015, + 69022, 69029, 69036, 69041, 69045, 69049, 69052, 69062, 69066, 69078, + 69087, 69091, 69102, 69107, 69111, 65938, 69117, 69124, 69133, 69141, + 69149, 69154, 69158, 69163, 69168, 69178, 69186, 69191, 69195, 69199, + 69205, 69213, 69220, 69232, 69240, 69251, 69258, 69264, 69274, 69280, + 69284, 69291, 69297, 69302, 69306, 69310, 69314, 69323, 69332, 69341, + 69347, 69353, 69359, 69364, 69371, 69377, 69385, 69392, 69398, 13622, + 69403, 69409, 69413, 15529, 69417, 69422, 69432, 69441, 69447, 69453, + 69461, 69468, 69472, 69476, 69482, 69490, 69497, 69503, 69514, 69518, + 69522, 69526, 69529, 69535, 69540, 69545, 69549, 69553, 69562, 69570, + 69577, 69583, 69590, 25963, 43422, 69595, 69603, 69607, 69611, 69614, + 69622, 69629, 69635, 69644, 69652, 69658, 69663, 69667, 69672, 69677, + 69681, 69685, 69689, 69694, 69703, 69707, 69714, 40528, 69718, 69724, + 69728, 69736, 69742, 69747, 69758, 69766, 69772, 69781, 24513, 69789, + 69796, 69803, 69810, 69817, 69824, 46704, 14317, 69831, 69838, 69843, + 37743, 6529, 69849, 69854, 69859, 69865, 69871, 69877, 69882, 69887, + 69892, 69897, 69903, 69908, 69914, 69919, 69925, 69930, 69935, 69940, + 69945, 69950, 69955, 69960, 69966, 69971, 69977, 69982, 69987, 69992, + 69997, 70002, 70007, 70013, 70018, 70023, 70028, 70033, 70038, 70043, + 70048, 70053, 70058, 70063, 70069, 70074, 70079, 70084, 70089, 70094, + 70099, 70104, 70109, 70115, 70120, 70125, 70130, 70135, 70140, 70145, + 70150, 70155, 70160, 70165, 70170, 70175, 70181, 1854, 260, 70186, 41361, + 70190, 70193, 70198, 70202, 70205, 3415, 70210, 70215, 70219, 70228, + 70239, 70256, 70274, 69145, 70282, 70285, 70295, 70302, 70311, 70327, + 70336, 70346, 70351, 70361, 70370, 70378, 70392, 70400, 70404, 70407, + 70414, 70420, 70431, 70438, 70450, 70461, 70472, 70481, 70488, 1278, 710, + 70498, 2629, 70502, 70507, 70516, 9221, 18894, 22471, 70524, 70532, + 70546, 70559, 70563, 70568, 70573, 70578, 70584, 70590, 70595, 8921, + 16623, 70600, 70604, 70612, 12062, 70617, 70623, 70632, 70640, 1736, + 12074, 908, 6465, 70644, 70648, 70657, 70667, 2419, 29127, 70676, 70682, + 18407, 29142, 70688, 4193, 12452, 70694, 70701, 65670, 70705, 70709, + 70715, 70720, 70725, 3634, 154, 15437, 70730, 70742, 70746, 70752, 70757, + 29907, 70761, 12440, 2769, 4, 70766, 70776, 70787, 70793, 70804, 70811, + 70817, 70823, 70831, 70838, 70844, 70854, 70864, 70874, 70883, 25367, + 1290, 70888, 70892, 70896, 70902, 70906, 2792, 2798, 8918, 2294, 70910, + 70914, 70923, 70931, 70942, 70950, 70958, 70964, 70969, 70980, 70991, + 70999, 71005, 71010, 10434, 71020, 71028, 71032, 71036, 71041, 71045, + 71057, 30314, 16548, 71064, 71074, 71080, 71086, 10536, 71096, 71107, + 71118, 71128, 71137, 71141, 71148, 1750, 996, 71158, 71163, 71171, 65483, + 71179, 71184, 71195, 71202, 71216, 15366, 478, 71226, 71230, 71234, + 71242, 71251, 71259, 71265, 71279, 71286, 71292, 71301, 71308, 71318, + 71326, 71333, 71341, 71348, 4024, 149, 71356, 71367, 71371, 71383, 71389, + 12633, 192, 71394, 9871, 71399, 71403, 71410, 71416, 71424, 71431, 9280, + 71438, 71447, 71455, 4093, 71468, 4110, 71472, 2842, 514, 71477, 71490, + 71494, 71499, 2847, 1853, 809, 71503, 4114, 71511, 71517, 71521, 866, + 71531, 71540, 71545, 3651, 71549, 16304, 16311, 50066, 71553, 4145, 4034, + 14200, 71561, 71568, 71573, 25431, 71577, 71584, 71590, 71595, 71600, + 16324, 186, 71605, 71617, 71623, 71631, 2859, 1768, 71639, 71641, 71646, + 71651, 71656, 71662, 71667, 71672, 71677, 71682, 71687, 71692, 71698, + 71703, 71708, 71713, 71718, 71723, 71728, 71733, 71738, 71744, 71749, + 71754, 71759, 71765, 71770, 71776, 71781, 71786, 71791, 71796, 71801, + 71806, 71811, 71817, 71822, 71828, 71833, 71838, 71843, 71848, 71853, + 71858, 71863, 71868, 71874, 71880, 71885, 71890, 71896, 71901, 71905, + 71909, 71914, 71920, 71924, 71930, 71935, 71940, 71946, 71951, 71955, + 71960, 71965, 71969, 71972, 71974, 71978, 71981, 71988, 71993, 71997, + 72002, 72006, 72010, 72014, 72023, 72027, 35026, 72030, 35031, 72037, + 72042, 35036, 72051, 72060, 35042, 72065, 35047, 72074, 72079, 12676, + 72083, 72088, 72093, 35052, 72097, 44921, 72101, 72104, 72108, 8589, + 72114, 72117, 72122, 72126, 3888, 35057, 72129, 72133, 72136, 72141, + 72145, 72151, 72159, 72172, 72181, 72187, 72192, 72198, 72202, 72208, + 72214, 72222, 72227, 72231, 72238, 72244, 72252, 72261, 72269, 35060, + 72276, 72286, 72299, 72304, 72309, 72313, 72322, 72328, 72335, 72346, + 72358, 72365, 72374, 72383, 72392, 72399, 72405, 72412, 72420, 72427, + 72435, 72444, 72452, 72459, 72467, 72476, 72484, 72493, 72503, 72512, + 72520, 72527, 72535, 72544, 72552, 72561, 72571, 72580, 72588, 72597, + 72607, 72616, 72626, 72637, 72647, 72656, 72664, 72671, 72679, 72688, + 72696, 72705, 72715, 72724, 72732, 72741, 72751, 72760, 72770, 72781, + 72791, 72800, 72808, 72817, 72827, 72836, 72846, 72857, 72867, 72876, + 72886, 72897, 72907, 72918, 72930, 72941, 72951, 72960, 72968, 72975, + 72983, 72992, 73000, 73009, 73019, 73028, 73036, 73045, 73055, 73064, + 73074, 73085, 73095, 73104, 73112, 73121, 73131, 73140, 73150, 73161, + 73171, 73180, 73190, 73201, 73211, 73222, 73234, 73245, 73255, 73264, + 73272, 73281, 73291, 73300, 73310, 73321, 73331, 73340, 73350, 73361, + 73371, 73382, 73394, 73405, 73415, 73424, 73434, 73445, 73455, 73466, + 73478, 73489, 73499, 73510, 73522, 73533, 73545, 73558, 73570, 73581, + 73591, 73600, 73608, 73615, 73623, 73632, 73640, 73649, 73659, 73668, + 73676, 73685, 73695, 73704, 73714, 73725, 73735, 73744, 73752, 73761, + 73771, 73780, 73790, 73801, 73811, 73820, 73830, 73841, 73851, 73862, + 73874, 73885, 73895, 73904, 73912, 73921, 73931, 73940, 73950, 73961, + 73971, 73980, 73990, 74001, 74011, 74022, 74034, 74045, 74055, 74064, + 74074, 74085, 74095, 74106, 74118, 74129, 74139, 74150, 74162, 74173, + 74185, 74198, 74210, 74221, 74231, 74240, 74248, 74257, 74267, 74276, + 74286, 74297, 74307, 74316, 74326, 74337, 74347, 74358, 74370, 74381, + 74391, 74400, 74410, 74421, 74431, 74442, 74454, 74465, 74475, 74486, + 74498, 74509, 74521, 74534, 74546, 74557, 74567, 74576, 74586, 74597, + 74607, 74618, 74630, 74641, 74651, 74662, 74674, 74685, 74697, 74710, + 74722, 74733, 74743, 74754, 74766, 74777, 74789, 74802, 74814, 74825, + 74837, 74850, 74862, 74875, 74889, 74902, 74914, 74925, 74935, 74944, + 74952, 74959, 74964, 8419, 74971, 35070, 74976, 74981, 35075, 74987, + 22579, 35080, 74992, 74998, 75006, 75012, 75018, 75025, 75032, 75037, + 75041, 75045, 75048, 75052, 75061, 75070, 75078, 75084, 75096, 75107, + 75111, 3140, 8394, 75116, 75119, 75121, 75125, 75129, 75133, 75139, + 75144, 27990, 75149, 75153, 75156, 75161, 75165, 75172, 75178, 75182, + 6485, 75186, 35097, 75191, 75198, 75207, 75215, 75226, 75234, 75243, + 75251, 75258, 75265, 75271, 75282, 35102, 75287, 75298, 75310, 75318, + 75329, 75338, 75349, 75354, 75362, 2595, 75367, 37166, 75380, 75384, + 75396, 75404, 75409, 75417, 75428, 19114, 75437, 75443, 75450, 75458, + 75464, 35112, 75469, 4139, 63056, 75476, 75479, 75487, 75500, 75513, + 75526, 75539, 75546, 75557, 75566, 75571, 46521, 46526, 75575, 75579, + 75587, 75594, 75603, 75611, 75617, 75626, 75634, 75641, 75649, 75653, + 75662, 75671, 75681, 75694, 75707, 75717, 35117, 75723, 75730, 75736, + 75742, 35123, 75747, 75750, 75754, 75762, 75771, 46259, 75779, 75788, + 75796, 75803, 75811, 75821, 75830, 75839, 36420, 75848, 75859, 75874, + 75884, 9904, 23263, 75893, 75898, 75903, 75907, 75912, 75916, 75921, + 75927, 75932, 75937, 75943, 75948, 75953, 23228, 75958, 75965, 75973, + 75981, 75989, 75994, 76001, 76008, 76013, 2272, 76017, 76021, 76029, + 76037, 35140, 76043, 76049, 76061, 76067, 76074, 76078, 76085, 76090, + 76097, 76103, 76110, 76121, 76131, 76141, 76153, 76159, 76167, 76173, + 76183, 76193, 35167, 76202, 76211, 76217, 76229, 76240, 76247, 76252, + 76256, 76264, 76270, 76275, 76280, 76287, 76295, 76307, 76317, 76326, + 76335, 76342, 37019, 25764, 76348, 76353, 76357, 76361, 76366, 76374, + 76380, 76391, 76404, 76409, 76416, 35172, 76421, 76433, 76442, 76450, + 76460, 76471, 76484, 76491, 76500, 76509, 76517, 76522, 76528, 1500, + 76533, 76538, 76543, 76548, 76554, 76559, 76564, 76570, 76576, 76581, + 76585, 76590, 76595, 76600, 63611, 76605, 76610, 76615, 76620, 76626, + 76632, 76637, 76641, 76646, 76651, 76656, 76662, 76667, 76673, 76678, + 76683, 76688, 76693, 76697, 76703, 76708, 76717, 76722, 76727, 76732, + 76737, 76741, 76748, 76754, 4430, 18737, 3105, 76759, 76763, 76768, + 76772, 76776, 76780, 50321, 76784, 76709, 76786, 76796, 35181, 76799, + 76804, 76813, 76819, 6454, 35186, 76823, 76829, 76834, 76840, 76845, + 76849, 76856, 76861, 76871, 76880, 76884, 76890, 76896, 76902, 76906, + 76914, 76921, 76929, 76937, 35191, 76944, 76947, 76954, 76960, 76965, + 76969, 76975, 76982, 76987, 76991, 77000, 77008, 77014, 77019, 35196, + 77026, 77038, 77045, 77051, 77056, 77062, 77069, 77075, 22979, 29589, + 77081, 77086, 77092, 77096, 77108, 76742, 76749, 23160, 77118, 77123, + 77130, 77136, 77143, 77149, 77160, 77165, 77173, 9609, 77178, 77181, + 77187, 77191, 77195, 77198, 77204, 34934, 4431, 1067, 14596, 77211, + 77217, 77223, 77229, 77235, 77241, 77247, 77253, 77259, 77264, 77269, + 77274, 77279, 77284, 77289, 77294, 77299, 77304, 77309, 77314, 77319, + 77324, 77330, 77335, 77340, 77346, 77351, 77356, 77362, 77368, 77374, + 77380, 77386, 77392, 77398, 77404, 77410, 77415, 77420, 77426, 77431, + 77436, 77442, 77447, 77452, 77457, 77462, 77467, 77472, 77477, 77482, + 77487, 77492, 77497, 77502, 77508, 77513, 77518, 77523, 77529, 77534, + 77539, 77544, 77549, 77555, 77560, 77565, 77570, 77575, 77580, 77585, + 77590, 77595, 77600, 77605, 77610, 77615, 77620, 77625, 77630, 77635, + 77640, 77645, 77650, 77656, 77661, 77666, 77671, 77676, 77681, 77686, + 77691, 1890, 163, 77696, 77700, 77704, 77709, 77717, 77721, 77728, 77736, + 77740, 77753, 77761, 77766, 77771, 28394, 77775, 77780, 77784, 77789, + 77793, 77801, 77805, 22587, 77810, 77814, 66162, 77818, 77821, 77829, + 77837, 77845, 77850, 77855, 77862, 77869, 77875, 77881, 77886, 77891, + 77899, 70551, 77906, 65948, 77911, 77916, 77920, 77927, 65975, 12743, + 77933, 77938, 77943, 77947, 77950, 77956, 77960, 77970, 77979, 77983, + 77986, 77990, 77997, 78010, 78016, 78024, 78033, 78044, 78055, 78066, + 78077, 78086, 78092, 78101, 78109, 78119, 78132, 78140, 78147, 78158, + 78164, 78169, 78174, 78180, 78186, 78196, 78203, 78213, 78222, 76423, + 78230, 78236, 78244, 78250, 78257, 78265, 78270, 78273, 78277, 78281, + 78284, 78290, 78296, 78304, 78316, 78328, 78335, 78340, 78344, 78355, + 78363, 78370, 78382, 78390, 78398, 78405, 78411, 78416, 78426, 78435, + 78440, 78450, 78459, 45549, 78466, 78470, 78475, 78483, 78490, 78496, + 78500, 78510, 78521, 78529, 78536, 78548, 78560, 78569, 75370, 78576, + 78586, 78598, 78609, 78623, 78631, 78641, 78648, 78656, 78669, 78681, + 78690, 78698, 78708, 78719, 78731, 78740, 78750, 78760, 78769, 78776, + 78785, 78800, 78808, 78818, 78827, 78835, 78848, 63026, 78863, 78873, + 78882, 78894, 78904, 78916, 78927, 78938, 78949, 78959, 78970, 78978, + 78984, 78994, 79002, 79008, 31291, 79013, 79019, 79028, 79040, 79045, + 79052, 10448, 19134, 79058, 79067, 79072, 79076, 79083, 79089, 79094, + 79099, 79107, 79115, 13119, 79119, 79122, 79124, 79131, 79137, 79148, + 79153, 79157, 79164, 79170, 79175, 79183, 71120, 71130, 79189, 79196, + 79206, 11543, 79213, 79218, 31506, 79227, 79232, 79239, 79249, 79257, + 79265, 79274, 79280, 79286, 79293, 79300, 79305, 79309, 79317, 65992, + 79322, 79331, 79339, 79346, 79351, 79355, 79364, 79370, 79373, 79377, + 79386, 79396, 77748, 79405, 79409, 79417, 79421, 79427, 79438, 79448, + 19143, 79459, 79468, 79476, 79484, 79491, 66011, 9147, 79499, 79503, + 79512, 79519, 79522, 29470, 79525, 79529, 79534, 79551, 79563, 11501, + 79575, 79580, 79585, 79590, 22669, 79594, 79599, 79604, 79610, 79615, + 6122, 79620, 22673, 79625, 79630, 79636, 79643, 79648, 79653, 79659, + 79665, 79671, 79676, 79682, 79686, 79700, 79708, 79716, 79722, 79727, + 79734, 79744, 79753, 79758, 79763, 79768, 79776, 79781, 79787, 79792, + 79801, 64713, 79806, 79809, 79827, 79846, 79859, 79873, 79889, 79896, + 79903, 79912, 79919, 79925, 79932, 79937, 79943, 79949, 79957, 79963, + 79968, 79973, 79989, 11514, 80003, 80010, 80018, 80024, 80028, 80031, + 80036, 80041, 80048, 80053, 80062, 80068, 80073, 80079, 80085, 80094, + 80103, 80108, 80112, 80120, 80129, 12772, 80138, 80144, 80152, 80158, + 80164, 80170, 80175, 80182, 80188, 12783, 80193, 80196, 80201, 35223, + 80211, 80220, 80225, 80231, 80236, 80244, 80251, 80262, 80272, 80277, + 80285, 70474, 80290, 80296, 80301, 80308, 80317, 80325, 80329, 80335, + 80341, 80348, 80354, 80358, 18518, 3114, 80363, 80367, 80371, 80377, + 80386, 80392, 80399, 80403, 80424, 80446, 80462, 80479, 80498, 80507, + 80517, 80525, 80532, 80539, 80545, 29342, 80559, 80563, 80569, 80577, + 80589, 80595, 80603, 80610, 80615, 80620, 80624, 80632, 80639, 80643, + 80649, 80655, 80660, 3730, 46721, 80666, 80670, 80674, 80678, 80683, + 80688, 80693, 80699, 80705, 80711, 80718, 80724, 80731, 80737, 80743, + 80748, 80754, 80759, 80763, 80768, 80772, 80777, 46736, 80781, 80786, + 80794, 80798, 80803, 80810, 80819, 80825, 80834, 80838, 80845, 80849, + 80852, 80859, 80865, 80874, 80884, 80889, 80893, 80901, 80910, 80914, + 80922, 80928, 80933, 80938, 80944, 80950, 80955, 80959, 80965, 80970, + 80974, 80978, 80981, 80986, 80994, 81004, 81010, 81015, 81025, 44031, + 81033, 81045, 81049, 81055, 81067, 81078, 81085, 81091, 81098, 81105, + 81117, 81124, 81130, 22747, 81134, 81142, 81148, 81155, 81161, 81167, + 81173, 81178, 81183, 81188, 81197, 81205, 81216, 7350, 81221, 17967, + 81227, 81231, 81235, 81239, 81247, 81256, 81260, 81267, 81276, 81284, + 81297, 81303, 80773, 32390, 81308, 81310, 81315, 81320, 81325, 81330, + 81335, 81340, 81345, 81350, 81355, 81360, 81365, 81370, 81375, 81380, + 81386, 81391, 81396, 81401, 81406, 81411, 81416, 81421, 81426, 81432, + 81438, 81444, 81449, 81454, 81466, 81471, 1896, 63, 81476, 81481, 35229, + 81485, 35234, 35239, 35245, 35250, 81489, 35255, 23785, 81511, 81515, + 81519, 81524, 81528, 35259, 81532, 81540, 81547, 35264, 81553, 81556, + 81561, 81565, 81574, 10266, 81582, 35269, 23641, 81585, 81589, 81597, + 1412, 81602, 35280, 81605, 81610, 27750, 27760, 38182, 81615, 81620, + 81625, 81630, 81636, 81641, 81650, 81655, 81664, 81672, 81679, 81685, + 81690, 81695, 81700, 81710, 81719, 81727, 81732, 81740, 81744, 81752, + 81756, 81763, 81771, 35088, 41192, 81778, 81784, 81789, 81794, 13154, + 30529, 81799, 81804, 81811, 81817, 81822, 81830, 81840, 81850, 81856, + 81861, 81867, 19165, 81874, 39052, 81887, 81892, 81898, 33381, 81911, + 81917, 81921, 81930, 81939, 81946, 81952, 81960, 81969, 81976, 81982, + 81985, 81989, 81993, 27891, 81997, 82004, 82010, 82018, 82023, 82027, + 25911, 82033, 82036, 82044, 82051, 82059, 82072, 82086, 82093, 82099, + 82106, 82112, 35294, 82116, 82123, 82131, 82139, 82145, 35299, 82153, + 82159, 82164, 82174, 82180, 82189, 33183, 37614, 82197, 82202, 82207, + 82211, 82216, 82220, 82228, 82233, 16296, 44044, 82237, 82242, 35304, + 67547, 82246, 82251, 82255, 82262, 82271, 82275, 82283, 82289, 82294, + 82300, 82305, 82312, 82318, 82323, 82328, 82339, 82348, 82360, 82375, + 35571, 82381, 18086, 35308, 82385, 82392, 82398, 26027, 82402, 82409, + 82418, 82425, 82434, 82440, 82445, 82453, 82459, 35318, 82464, 82473, + 81073, 82482, 82489, 82495, 82501, 82510, 82520, 82528, 82535, 82539, + 35323, 82542, 35329, 35335, 82547, 82555, 82563, 82573, 82582, 82590, + 82597, 82607, 35340, 82611, 82613, 82617, 82622, 82626, 82630, 82636, + 82641, 82645, 82656, 82661, 82666, 3119, 82670, 82677, 82681, 82690, + 82698, 82705, 82710, 82715, 67598, 82719, 82722, 82728, 82736, 82742, + 82746, 82751, 82758, 82763, 82768, 82772, 82778, 82783, 37645, 82787, + 82790, 82795, 82799, 82804, 82811, 82816, 82820, 42580, 82828, 27769, + 27778, 82834, 82840, 82846, 82851, 82855, 82858, 82868, 82877, 82882, + 82888, 82895, 82901, 82905, 82913, 82918, 37651, 77952, 82922, 82930, + 82936, 82943, 82948, 82952, 82957, 63242, 82963, 82969, 37657, 82974, + 82979, 82983, 82988, 82993, 82998, 83002, 83007, 83012, 83018, 83023, + 83028, 83034, 83040, 83045, 83049, 83054, 83059, 83064, 83068, 26026, + 83073, 83078, 83084, 83090, 83096, 83101, 83105, 83110, 83115, 83120, + 83124, 83129, 83134, 83139, 83144, 46991, 83148, 35348, 83156, 83160, + 83168, 83176, 83187, 83192, 83196, 24211, 75473, 83201, 83207, 83212, + 83222, 83229, 83234, 83242, 83251, 83256, 83260, 83265, 83273, 83281, + 83288, 70736, 83294, 83302, 83309, 83320, 83326, 83332, 35358, 83335, + 83342, 83350, 83355, 44247, 83359, 83364, 83371, 83376, 9484, 83380, + 83388, 83395, 83402, 83411, 83418, 83424, 83438, 6194, 83446, 83452, + 83456, 83459, 83467, 83474, 83479, 83492, 83499, 83505, 83509, 83514, + 83521, 83526, 65851, 83531, 83534, 83543, 83550, 83556, 83560, 83563, + 83571, 83580, 83590, 83600, 83609, 83620, 83628, 83639, 83644, 83648, + 83653, 83657, 38313, 83665, 23042, 38322, 83670, 83675, 83680, 83685, + 83690, 83695, 83700, 83704, 83709, 83714, 83719, 83724, 83729, 83734, + 83738, 83743, 83748, 83752, 83756, 83760, 83764, 83769, 83774, 83778, + 83783, 83787, 83791, 83796, 83801, 83806, 83811, 83815, 83820, 83825, + 83829, 83834, 83839, 83844, 83849, 83854, 83859, 83864, 83869, 83874, + 83879, 83884, 83889, 83894, 83899, 83904, 83909, 83914, 83919, 83924, + 83929, 83933, 83938, 83943, 83948, 83953, 83958, 83963, 83968, 83973, + 83978, 83983, 83988, 83992, 83997, 84001, 84006, 84011, 84016, 84021, + 84026, 84031, 84036, 84041, 84046, 84050, 84054, 84059, 84064, 84068, + 84073, 84078, 84082, 84087, 84092, 84097, 84102, 84106, 84111, 84116, + 84120, 84125, 84129, 84133, 84137, 84141, 84146, 84150, 84154, 84158, + 84162, 84166, 84170, 84174, 84178, 84182, 84187, 84192, 84197, 84202, + 84207, 84212, 84217, 84222, 84227, 84232, 84236, 84240, 84244, 84248, + 84252, 84256, 84261, 84265, 84270, 84274, 84279, 84284, 84288, 84292, + 84297, 84301, 84305, 84309, 84313, 84317, 84321, 84325, 84329, 84333, + 84337, 84341, 84345, 84349, 84353, 84358, 84363, 84367, 84371, 84375, + 84379, 84383, 84387, 84392, 84396, 84400, 84404, 84408, 84412, 84416, + 84421, 84425, 84430, 84434, 84438, 84442, 84446, 84450, 84454, 84458, + 84462, 84466, 84470, 84474, 84479, 84483, 84487, 84491, 84495, 84499, + 84503, 84507, 84511, 84515, 84519, 84523, 84528, 84532, 84536, 84541, + 84546, 84550, 84554, 84558, 84562, 84566, 84570, 84574, 84578, 84583, + 84587, 84592, 84596, 84601, 84605, 84610, 84614, 84620, 84625, 84629, + 84634, 84638, 84643, 84647, 84652, 84656, 84661, 1519, 84665, 2873, 1774, + 1692, 27705, 84669, 2882, 84673, 1381, 84678, 1323, 84682, 84686, 2899, + 84690, 84697, 84704, 84718, 2903, 7452, 84727, 84735, 84742, 84753, + 84762, 84769, 84781, 84794, 84807, 84818, 84823, 84830, 84842, 84846, + 2907, 12850, 84856, 84861, 84870, 84880, 84885, 2911, 84893, 84897, + 84902, 84909, 84915, 84923, 84935, 1328, 14201, 84945, 84949, 84955, + 84969, 84981, 84993, 85003, 85012, 85021, 85030, 85038, 85049, 85057, + 4292, 85067, 85078, 85087, 85093, 85108, 85115, 85121, 85126, 38447, + 85131, 2935, 14205, 85135, 85142, 9409, 85151, 2940, 34796, 85157, 65573, + 85164, 85170, 85181, 85187, 85194, 85200, 85208, 85215, 85221, 85232, + 85242, 85251, 85262, 85271, 85278, 85284, 85294, 85302, 85308, 85323, + 85329, 85334, 85341, 85344, 85350, 85357, 85363, 85371, 85380, 85388, + 85394, 85403, 46261, 85417, 85422, 85428, 16072, 85433, 85446, 85458, + 85467, 85475, 85482, 85486, 85490, 85493, 85500, 85507, 85515, 85523, + 85532, 85540, 15983, 85548, 85553, 85557, 85569, 85576, 85585, 841, + 85595, 85604, 85615, 2956, 85619, 85623, 85629, 85642, 85654, 85664, + 85673, 85685, 28446, 85696, 85704, 85713, 85724, 85735, 85745, 85755, + 85764, 85772, 12364, 85779, 85783, 85786, 85791, 85796, 85800, 85806, + 1333, 85813, 85817, 12932, 85821, 85832, 85841, 85849, 85858, 85866, + 85882, 85893, 85902, 85910, 85922, 85933, 85949, 85959, 85980, 85994, + 86007, 86015, 86022, 7498, 86035, 86040, 86046, 6203, 86052, 86055, + 86062, 86072, 8554, 86079, 86084, 86089, 86094, 86102, 86111, 86119, + 86124, 86131, 10496, 10505, 86137, 86148, 86153, 86159, 2972, 2977, + 86165, 11857, 86171, 86178, 86185, 86198, 2281, 87, 86203, 86208, 86216, + 86226, 86235, 86241, 86250, 86258, 86268, 86272, 86276, 86281, 86285, + 86297, 3000, 86305, 86313, 86318, 86329, 86340, 86352, 86363, 86373, + 86382, 23083, 86387, 86393, 86398, 86408, 86418, 86423, 86429, 86433, + 86438, 86447, 23095, 86451, 4384, 24, 86456, 86465, 86472, 86479, 86485, + 86491, 1049, 86496, 86501, 66128, 86506, 86511, 86517, 86523, 86531, + 86536, 86544, 86551, 86557, 86562, 42464, 46155, 86568, 3004, 32, 86578, + 86591, 86596, 86604, 86609, 86615, 3026, 30497, 86620, 86628, 86635, + 86640, 86649, 63492, 4018, 67218, 86657, 86661, 1719, 1833, 86666, 86671, + 86678, 1837, 280, 86685, 86691, 86696, 3048, 86700, 86705, 86712, 1841, + 86717, 86723, 86728, 86740, 6430, 86750, 86757, 1848, 86763, 86768, + 86775, 86782, 86797, 86804, 86815, 86820, 86828, 2657, 86832, 86844, + 86849, 86853, 86859, 30313, 2286, 86863, 86874, 86878, 86882, 86888, + 86892, 86901, 86905, 86916, 86920, 2332, 34613, 86924, 86934, 3139, + 86942, 9909, 86951, 86956, 86960, 86969, 86976, 86982, 3109, 16136, + 86986, 86999, 87017, 87022, 87030, 87038, 87048, 10768, 14318, 87060, + 87073, 87080, 87094, 87101, 87117, 87124, 87130, 23127, 13556, 87137, + 87144, 87154, 87163, 46990, 87175, 47125, 87183, 87186, 87192, 87198, + 87204, 87210, 87216, 87223, 87230, 87236, 87242, 87248, 87254, 87260, + 87266, 87272, 87278, 87284, 87290, 87296, 87302, 87308, 87314, 87320, + 87326, 87332, 87338, 87344, 87350, 87356, 87362, 87368, 87374, 87380, + 87386, 87392, 87398, 87404, 87410, 87416, 87422, 87428, 87434, 87440, + 87446, 87452, 87458, 87464, 87470, 87476, 87482, 87488, 87494, 87500, + 87506, 87512, 87518, 87524, 87530, 87536, 87543, 87549, 87556, 87563, + 87569, 87576, 87583, 87589, 87595, 87601, 87607, 87613, 87619, 87625, + 87631, 87637, 87643, 87649, 87655, 87661, 87667, 87673, 3123, 9882, + 87679, 87685, 87693, 87697, 84905, 3127, 87701, 22860, 13189, 3968, + 87705, 3133, 87709, 87719, 87725, 87731, 87737, 87743, 87749, 87755, + 87761, 87767, 87773, 87779, 87785, 87791, 87797, 87803, 87809, 87815, + 87821, 87827, 87833, 87839, 87845, 87851, 87857, 87863, 87869, 87876, + 87883, 87889, 87895, 87901, 87907, 87913, 87919, 1338, 87925, 87930, + 87935, 87940, 87945, 87950, 87955, 87960, 87965, 87969, 87973, 87977, + 87981, 87985, 87989, 87993, 87997, 88001, 88007, 88013, 88019, 88025, + 88029, 88033, 88037, 88041, 88045, 88049, 88053, 88057, 88061, 88066, + 88071, 88076, 88081, 88086, 88091, 88096, 88101, 88106, 88111, 88116, + 88121, 88126, 88131, 88136, 88141, 88146, 88151, 88156, 88161, 88166, + 88171, 88176, 88181, 88186, 88191, 88196, 88201, 88206, 88211, 88216, + 88221, 88226, 88231, 88236, 88241, 88246, 88251, 88256, 88261, 88266, + 88271, 88276, 88281, 88286, 88291, 88296, 88301, 88306, 88311, 88316, + 88321, 88326, 88331, 88336, 88341, 88346, 88351, 88356, 88361, 88366, + 88371, 88376, 88381, 88386, 88391, 88396, 88401, 88406, 88411, 88416, + 88421, 88426, 88431, 88436, 88441, 88446, 88451, 88456, 88461, 88466, + 88471, 88476, 88481, 88486, 88491, 88496, 88501, 88506, 88511, 88516, + 88521, 88526, 88531, 88536, 88541, 88546, 88551, 88556, 88561, 88566, + 88571, 88576, 88581, 88586, 88591, 88596, 88601, 88606, 88611, 88616, + 88621, 88626, 88631, 88636, 88641, 88646, 88651, 88656, 88661, 88666, + 88671, 88676, 88681, 88686, 88691, 88696, 88701, 88706, 88711, 88716, + 88721, 88726, 88731, 88736, 88741, 88746, 88751, 88756, 88761, 88766, + 88771, 88776, 88781, 88786, 88791, 88796, 88801, 88806, 88811, 88816, + 88821, 88826, 88831, 88836, 88841, 88846, 88851, 88856, 88861, 88866, + 88871, 88876, 88881, 88886, 88891, 88896, 88901, 88906, 88911, 88916, + 88921, 88926, 88931, 88936, 88941, 88946, 88951, 88957, 88962, 88967, + 88972, 88977, 88982, 88987, 88992, 88998, 89003, 89008, 89013, 89018, + 89023, 89028, 89033, 89038, 89043, 89048, 89053, 89058, 89063, 89068, + 89073, 89078, 89083, 89088, 89093, 89098, 89103, 89108, 89113, 89118, + 89123, 89128, 89133, 89138, 89143, 89148, 89153, 89158, 89167, 89172, + 89181, 89186, 89195, 89200, 89209, 89214, 89223, 89228, 89237, 89242, + 89251, 89256, 89265, 89270, 89275, 89284, 89288, 89297, 89302, 89311, + 89316, 89325, 89330, 89339, 89344, 89353, 89358, 89367, 89372, 89381, + 89386, 89395, 89400, 89409, 89414, 89423, 89428, 89433, 89438, 89443, + 89448, 89453, 89458, 89462, 89467, 89472, 89477, 89482, 89487, 89492, + 89498, 89503, 89508, 89513, 89519, 89523, 89528, 89534, 89539, 89544, + 89549, 89554, 89559, 89564, 89569, 89574, 89579, 89584, 89590, 89595, + 89600, 89605, 89611, 89616, 89621, 89626, 89631, 89637, 89642, 89647, + 89652, 89657, 89662, 89668, 89673, 89678, 89683, 89688, 89693, 89698, + 89703, 89708, 89713, 89718, 89723, 89728, 89733, 89738, 89743, 89748, + 89753, 89758, 89763, 89768, 89773, 89778, 89783, 89789, 89795, 89801, + 89806, 89811, 89816, 89821, 89827, 89833, 89839, 89844, 89849, 89854, + 89860, 89865, 89870, 89875, 89880, 89885, 89890, 89895, 89900, 89905, + 89910, 89915, 89920, 89925, 89930, 89935, 89940, 89946, 89952, 89958, + 89963, 89968, 89973, 89978, 89984, 89990, 89996, 90001, 90006, 90011, + 90016, 90021, 90026, 90031, 90036, 90041, 17539, 90046, 90052, 90057, + 90062, 90067, 90072, 90077, 90083, 90088, 90093, 90098, 90103, 90108, + 90114, 90119, 90124, 90129, 90134, 90139, 90144, 90149, 90154, 90159, + 90164, 90169, 90174, 90179, 90184, 90189, 90194, 90199, 90204, 90209, + 90214, 90219, 90224, 90230, 90235, 90240, 90245, 90250, 90255, 90260, + 90265, 90270, 90275, 90280, 90285, 90290, 90295, 90300, 90305, 90310, + 90315, 90320, 90325, 90330, 90335, 90340, 90345, 90350, 90355, 90360, + 90365, 90370, 90375, 90380, 90385, 90390, 90395, 90400, 90405, 90410, + 90415, 90420, 90425, 90430, 90436, 90441, 90446, 90451, 90456, 90461, + 90466, 90471, 90476, 90481, 90486, 90491, 90497, 90502, 90508, 90513, + 90518, 90523, 90528, 90533, 90538, 90544, 90549, 90554, 90560, 90565, + 90570, 90575, 90580, 90585, 90591, 90597, 90602, 90607, 13211, 90612, + 90617, 90622, 90627, 90632, 90637, 90642, 90647, 90652, 90657, 90662, + 90667, 90672, 90677, 90682, 90687, 90692, 90697, 90702, 90707, 90712, + 90717, 90722, 90727, 90732, 90737, 90742, 90747, 90752, 90757, 90762, + 90767, 90772, 90777, 90782, 90787, 90792, 90797, 90802, 90807, 90812, + 90817, 90822, 90827, 90832, 90837, 90842, 90847, 90852, 90857, 90862, + 90867, 90872, 90877, 90882, 90887, 90892, 90897, 90902, 90907, 90912, + 90917, 90922, 90927, 90932, 90938, 90943, 90948, 90953, 90958, 90964, + 90969, 90974, 90979, 90984, 90989, 90994, 91000, 91005, 91010, 91015, + 91020, 91025, 91031, 91036, 91041, 91046, 91051, 91056, 91062, 91067, + 91072, 91077, 91082, 91087, 91093, 91099, 91104, 91109, 91114, 91120, + 91126, 91132, 91137, 91142, 91148, 91154, 91159, 91165, 91171, 91177, + 91182, 91187, 91193, 91198, 91204, 91209, 91215, 91224, 91229, 91234, + 91240, 91245, 91251, 91256, 91261, 91266, 91271, 91276, 91281, 91286, + 91291, 91296, 91301, 91306, 91311, 91316, 91321, 91326, 91331, 91336, + 91341, 91346, 91351, 91356, 91361, 91366, 91371, 91376, 91381, 91386, + 91391, 91396, 91401, 91406, 91412, 91418, 91424, 91429, 91434, 91439, + 91444, 91449, 91454, 91459, 91464, 91469, 91474, 91479, 91484, 91489, + 91494, 91499, 91504, 91509, 91514, 91519, 91524, 91530, 91536, 91541, + 91547, 91552, 91557, 91563, 91568, 91574, 91579, 91585, 91590, 91596, + 91601, 91607, 91612, 91617, 91622, 91627, 91632, 91637, 91642, 87720, + 87726, 87732, 87738, 91648, 87744, 87750, 91654, 87756, 87762, 87768, + 87774, 87780, 87786, 87792, 87798, 87804, 91660, 87810, 87816, 87822, + 91666, 87828, 87834, 87840, 87846, 91672, 87852, 87858, 87864, 87884, + 91678, 91684, 87890, 91690, 87896, 87902, 87908, 87914, 87920, 3150, + 3155, 91696, 91701, 91704, 91710, 91716, 91723, 91728, 91733, 2337, }; /* code->name phrasebook */ -#define phrasebook_shift 7 -#define phrasebook_short 209 +#define phrasebook_shift 8 +#define phrasebook_short 201 static unsigned char phrasebook[] = { - 0, 219, 20, 245, 39, 79, 224, 1, 79, 54, 50, 247, 140, 50, 225, 185, 50, - 254, 134, 254, 65, 43, 226, 7, 44, 226, 7, 253, 224, 96, 50, 249, 227, - 240, 174, 243, 236, 218, 131, 219, 48, 21, 210, 86, 21, 111, 21, 105, 21, - 158, 21, 161, 21, 190, 21, 195, 21, 199, 21, 196, 21, 201, 249, 234, 220, - 152, 233, 21, 50, 245, 106, 50, 242, 137, 50, 224, 16, 79, 249, 225, 253, - 214, 7, 6, 1, 61, 7, 6, 1, 253, 166, 7, 6, 1, 251, 74, 7, 6, 1, 249, 68, - 7, 6, 1, 76, 7, 6, 1, 245, 14, 7, 6, 1, 243, 209, 7, 6, 1, 242, 67, 7, 6, - 1, 74, 7, 6, 1, 235, 150, 7, 6, 1, 235, 29, 7, 6, 1, 156, 7, 6, 1, 194, - 7, 6, 1, 230, 30, 7, 6, 1, 78, 7, 6, 1, 226, 109, 7, 6, 1, 224, 99, 7, 6, - 1, 153, 7, 6, 1, 222, 93, 7, 6, 1, 217, 153, 7, 6, 1, 69, 7, 6, 1, 214, - 105, 7, 6, 1, 212, 98, 7, 6, 1, 211, 178, 7, 6, 1, 211, 117, 7, 6, 1, - 210, 159, 43, 42, 127, 223, 53, 219, 48, 44, 42, 127, 250, 39, 255, 23, - 121, 232, 219, 242, 144, 255, 23, 7, 4, 1, 61, 7, 4, 1, 253, 166, 7, 4, - 1, 251, 74, 7, 4, 1, 249, 68, 7, 4, 1, 76, 7, 4, 1, 245, 14, 7, 4, 1, - 243, 209, 7, 4, 1, 242, 67, 7, 4, 1, 74, 7, 4, 1, 235, 150, 7, 4, 1, 235, - 29, 7, 4, 1, 156, 7, 4, 1, 194, 7, 4, 1, 230, 30, 7, 4, 1, 78, 7, 4, 1, - 226, 109, 7, 4, 1, 224, 99, 7, 4, 1, 153, 7, 4, 1, 222, 93, 7, 4, 1, 217, - 153, 7, 4, 1, 69, 7, 4, 1, 214, 105, 7, 4, 1, 212, 98, 7, 4, 1, 211, 178, - 7, 4, 1, 211, 117, 7, 4, 1, 210, 159, 43, 249, 107, 127, 67, 232, 219, - 44, 249, 107, 127, 184, 228, 78, 219, 20, 235, 200, 245, 39, 79, 250, - 184, 50, 224, 231, 50, 249, 106, 50, 211, 40, 50, 251, 143, 130, 221, - 175, 50, 248, 9, 249, 171, 50, 244, 144, 226, 158, 235, 245, 233, 48, 52, - 254, 118, 224, 1, 79, 228, 57, 50, 219, 54, 240, 175, 223, 105, 50, 231, - 237, 248, 79, 50, 225, 24, 50, 218, 24, 105, 218, 24, 158, 255, 12, 255, - 23, 230, 233, 50, 225, 71, 50, 230, 229, 247, 128, 250, 191, 218, 24, - 111, 231, 153, 226, 158, 235, 245, 222, 250, 52, 254, 118, 224, 1, 79, - 212, 114, 244, 10, 123, 224, 24, 212, 114, 244, 10, 123, 242, 34, 212, - 114, 244, 10, 134, 224, 22, 235, 200, 224, 16, 79, 7, 6, 1, 116, 2, 242, - 143, 7, 6, 1, 116, 2, 142, 7, 6, 1, 116, 2, 250, 38, 7, 6, 1, 116, 2, - 184, 7, 6, 1, 116, 2, 248, 9, 7, 6, 1, 116, 2, 222, 237, 48, 7, 6, 1, - 254, 252, 7, 6, 1, 251, 75, 2, 250, 191, 7, 6, 1, 160, 2, 242, 143, 7, 6, - 1, 160, 2, 142, 7, 6, 1, 160, 2, 250, 38, 7, 6, 1, 160, 2, 248, 9, 7, 6, - 1, 240, 161, 2, 242, 143, 7, 6, 1, 240, 161, 2, 142, 7, 6, 1, 240, 161, - 2, 250, 38, 7, 6, 1, 240, 161, 2, 248, 9, 7, 6, 1, 245, 67, 7, 6, 1, 230, - 31, 2, 184, 7, 6, 1, 144, 2, 242, 143, 7, 6, 1, 144, 2, 142, 7, 6, 1, - 144, 2, 250, 38, 7, 6, 1, 144, 2, 184, 7, 6, 1, 144, 2, 248, 9, 230, 89, - 50, 7, 6, 1, 144, 2, 91, 7, 6, 1, 104, 2, 242, 143, 7, 6, 1, 104, 2, 142, - 7, 6, 1, 104, 2, 250, 38, 7, 6, 1, 104, 2, 248, 9, 7, 6, 1, 211, 118, 2, - 142, 7, 6, 1, 216, 152, 7, 4, 1, 220, 78, 222, 93, 7, 4, 1, 116, 2, 242, - 143, 7, 4, 1, 116, 2, 142, 7, 4, 1, 116, 2, 250, 38, 7, 4, 1, 116, 2, - 184, 7, 4, 1, 116, 2, 248, 9, 7, 4, 1, 116, 2, 222, 237, 48, 7, 4, 1, - 254, 252, 7, 4, 1, 251, 75, 2, 250, 191, 7, 4, 1, 160, 2, 242, 143, 7, 4, - 1, 160, 2, 142, 7, 4, 1, 160, 2, 250, 38, 7, 4, 1, 160, 2, 248, 9, 7, 4, - 1, 240, 161, 2, 242, 143, 7, 4, 1, 240, 161, 2, 142, 7, 4, 1, 240, 161, - 2, 250, 38, 7, 4, 1, 240, 161, 2, 248, 9, 7, 4, 1, 245, 67, 7, 4, 1, 230, - 31, 2, 184, 7, 4, 1, 144, 2, 242, 143, 7, 4, 1, 144, 2, 142, 7, 4, 1, - 144, 2, 250, 38, 7, 4, 1, 144, 2, 184, 7, 4, 1, 144, 2, 248, 9, 247, 177, - 50, 7, 4, 1, 144, 2, 91, 7, 4, 1, 104, 2, 242, 143, 7, 4, 1, 104, 2, 142, - 7, 4, 1, 104, 2, 250, 38, 7, 4, 1, 104, 2, 248, 9, 7, 4, 1, 211, 118, 2, - 142, 7, 4, 1, 216, 152, 7, 4, 1, 211, 118, 2, 248, 9, 7, 6, 1, 116, 2, - 231, 237, 7, 4, 1, 116, 2, 231, 237, 7, 6, 1, 116, 2, 251, 154, 7, 4, 1, - 116, 2, 251, 154, 7, 6, 1, 116, 2, 226, 228, 7, 4, 1, 116, 2, 226, 228, - 7, 6, 1, 251, 75, 2, 142, 7, 4, 1, 251, 75, 2, 142, 7, 6, 1, 251, 75, 2, - 250, 38, 7, 4, 1, 251, 75, 2, 250, 38, 7, 6, 1, 251, 75, 2, 59, 48, 7, 4, - 1, 251, 75, 2, 59, 48, 7, 6, 1, 251, 75, 2, 250, 242, 7, 4, 1, 251, 75, - 2, 250, 242, 7, 6, 1, 249, 69, 2, 250, 242, 7, 4, 1, 249, 69, 2, 250, - 242, 7, 6, 1, 249, 69, 2, 91, 7, 4, 1, 249, 69, 2, 91, 7, 6, 1, 160, 2, - 231, 237, 7, 4, 1, 160, 2, 231, 237, 7, 6, 1, 160, 2, 251, 154, 7, 4, 1, - 160, 2, 251, 154, 7, 6, 1, 160, 2, 59, 48, 7, 4, 1, 160, 2, 59, 48, 7, 6, - 1, 160, 2, 226, 228, 7, 4, 1, 160, 2, 226, 228, 7, 6, 1, 160, 2, 250, - 242, 7, 4, 1, 160, 2, 250, 242, 7, 6, 1, 243, 210, 2, 250, 38, 7, 4, 1, - 243, 210, 2, 250, 38, 7, 6, 1, 243, 210, 2, 251, 154, 7, 4, 1, 243, 210, - 2, 251, 154, 7, 6, 1, 243, 210, 2, 59, 48, 7, 4, 1, 243, 210, 2, 59, 48, - 7, 6, 1, 243, 210, 2, 250, 191, 7, 4, 1, 243, 210, 2, 250, 191, 7, 6, 1, - 242, 68, 2, 250, 38, 7, 4, 1, 242, 68, 2, 250, 38, 7, 6, 1, 242, 68, 2, - 91, 7, 4, 1, 242, 68, 2, 91, 7, 6, 1, 240, 161, 2, 184, 7, 4, 1, 240, - 161, 2, 184, 7, 6, 1, 240, 161, 2, 231, 237, 7, 4, 1, 240, 161, 2, 231, - 237, 7, 6, 1, 240, 161, 2, 251, 154, 7, 4, 1, 240, 161, 2, 251, 154, 7, - 6, 1, 240, 161, 2, 226, 228, 7, 4, 1, 240, 161, 2, 226, 228, 7, 6, 1, - 240, 161, 2, 59, 48, 7, 4, 1, 247, 127, 74, 7, 6, 27, 236, 38, 7, 4, 27, - 236, 38, 7, 6, 1, 235, 151, 2, 250, 38, 7, 4, 1, 235, 151, 2, 250, 38, 7, - 6, 1, 235, 30, 2, 250, 191, 7, 4, 1, 235, 30, 2, 250, 191, 7, 4, 1, 233, - 245, 7, 6, 1, 233, 155, 2, 142, 7, 4, 1, 233, 155, 2, 142, 7, 6, 1, 233, - 155, 2, 250, 191, 7, 4, 1, 233, 155, 2, 250, 191, 7, 6, 1, 233, 155, 2, - 250, 242, 7, 4, 1, 233, 155, 2, 250, 242, 7, 6, 1, 233, 155, 2, 230, 229, - 247, 128, 7, 4, 1, 233, 155, 2, 230, 229, 247, 128, 7, 6, 1, 233, 155, 2, - 91, 7, 4, 1, 233, 155, 2, 91, 7, 6, 1, 230, 31, 2, 142, 7, 4, 1, 230, 31, - 2, 142, 7, 6, 1, 230, 31, 2, 250, 191, 7, 4, 1, 230, 31, 2, 250, 191, 7, - 6, 1, 230, 31, 2, 250, 242, 7, 4, 1, 230, 31, 2, 250, 242, 7, 4, 1, 230, - 31, 224, 207, 251, 86, 254, 65, 7, 6, 1, 245, 146, 7, 4, 1, 245, 146, 7, - 6, 1, 144, 2, 231, 237, 7, 4, 1, 144, 2, 231, 237, 7, 6, 1, 144, 2, 251, - 154, 7, 4, 1, 144, 2, 251, 154, 7, 6, 1, 144, 2, 52, 142, 7, 4, 1, 144, - 2, 52, 142, 7, 6, 27, 226, 238, 7, 4, 27, 226, 238, 7, 6, 1, 223, 227, 2, - 142, 7, 4, 1, 223, 227, 2, 142, 7, 6, 1, 223, 227, 2, 250, 191, 7, 4, 1, - 223, 227, 2, 250, 191, 7, 6, 1, 223, 227, 2, 250, 242, 7, 4, 1, 223, 227, - 2, 250, 242, 7, 6, 1, 222, 94, 2, 142, 7, 4, 1, 222, 94, 2, 142, 7, 6, 1, - 222, 94, 2, 250, 38, 7, 4, 1, 222, 94, 2, 250, 38, 7, 6, 1, 222, 94, 2, - 250, 191, 7, 4, 1, 222, 94, 2, 250, 191, 7, 6, 1, 222, 94, 2, 250, 242, - 7, 4, 1, 222, 94, 2, 250, 242, 7, 6, 1, 217, 154, 2, 250, 191, 7, 4, 1, - 217, 154, 2, 250, 191, 7, 6, 1, 217, 154, 2, 250, 242, 7, 4, 1, 217, 154, - 2, 250, 242, 7, 6, 1, 217, 154, 2, 91, 7, 4, 1, 217, 154, 2, 91, 7, 6, 1, - 104, 2, 184, 7, 4, 1, 104, 2, 184, 7, 6, 1, 104, 2, 231, 237, 7, 4, 1, - 104, 2, 231, 237, 7, 6, 1, 104, 2, 251, 154, 7, 4, 1, 104, 2, 251, 154, - 7, 6, 1, 104, 2, 222, 237, 48, 7, 4, 1, 104, 2, 222, 237, 48, 7, 6, 1, - 104, 2, 52, 142, 7, 4, 1, 104, 2, 52, 142, 7, 6, 1, 104, 2, 226, 228, 7, - 4, 1, 104, 2, 226, 228, 7, 6, 1, 212, 99, 2, 250, 38, 7, 4, 1, 212, 99, - 2, 250, 38, 7, 6, 1, 211, 118, 2, 250, 38, 7, 4, 1, 211, 118, 2, 250, 38, - 7, 6, 1, 211, 118, 2, 248, 9, 7, 6, 1, 210, 160, 2, 142, 7, 4, 1, 210, - 160, 2, 142, 7, 6, 1, 210, 160, 2, 59, 48, 7, 4, 1, 210, 160, 2, 59, 48, - 7, 6, 1, 210, 160, 2, 250, 242, 7, 4, 1, 210, 160, 2, 250, 242, 7, 4, 1, - 200, 222, 93, 7, 4, 1, 57, 2, 91, 7, 6, 1, 57, 2, 103, 7, 6, 1, 57, 2, - 216, 12, 7, 4, 1, 57, 2, 216, 12, 7, 6, 1, 138, 195, 7, 4, 1, 138, 195, - 7, 6, 1, 204, 78, 7, 6, 1, 251, 75, 2, 103, 7, 4, 1, 251, 75, 2, 103, 7, - 6, 1, 254, 228, 249, 68, 7, 6, 1, 249, 69, 2, 103, 7, 6, 1, 249, 69, 2, - 216, 12, 7, 4, 1, 249, 69, 2, 216, 12, 7, 4, 1, 215, 94, 248, 62, 7, 6, - 1, 223, 52, 76, 7, 6, 1, 221, 197, 7, 6, 1, 204, 76, 7, 6, 1, 245, 15, 2, - 103, 7, 4, 1, 245, 15, 2, 103, 7, 6, 1, 243, 210, 2, 103, 7, 6, 1, 243, - 114, 7, 4, 1, 240, 208, 7, 6, 1, 235, 192, 7, 6, 1, 240, 161, 2, 91, 7, - 6, 1, 235, 30, 2, 103, 7, 4, 1, 235, 30, 2, 103, 7, 4, 1, 233, 155, 2, - 130, 7, 4, 1, 233, 106, 2, 91, 7, 6, 1, 215, 94, 194, 7, 6, 1, 230, 31, - 2, 43, 103, 7, 4, 1, 230, 31, 2, 200, 44, 233, 42, 7, 6, 1, 144, 2, 230, - 229, 184, 7, 6, 1, 144, 2, 240, 255, 7, 4, 1, 144, 2, 240, 255, 7, 6, 1, - 226, 223, 7, 4, 1, 226, 223, 7, 6, 1, 226, 110, 2, 103, 7, 4, 1, 226, - 110, 2, 103, 7, 1, 210, 214, 7, 6, 1, 138, 105, 7, 4, 1, 138, 105, 7, 6, - 1, 245, 83, 7, 1, 223, 52, 245, 84, 232, 129, 7, 4, 1, 217, 154, 2, 226, - 70, 103, 7, 6, 1, 217, 154, 2, 103, 7, 4, 1, 217, 154, 2, 103, 7, 6, 1, - 217, 154, 2, 223, 58, 103, 7, 6, 1, 104, 2, 240, 255, 7, 4, 1, 104, 2, - 240, 255, 7, 6, 1, 214, 157, 7, 6, 1, 214, 106, 2, 103, 7, 6, 1, 211, - 118, 2, 103, 7, 4, 1, 211, 118, 2, 103, 7, 6, 1, 210, 160, 2, 91, 7, 4, - 1, 210, 160, 2, 91, 7, 6, 1, 245, 16, 7, 6, 1, 245, 17, 223, 51, 7, 4, 1, - 245, 17, 223, 51, 7, 4, 1, 245, 17, 2, 217, 78, 7, 1, 113, 2, 91, 7, 6, - 1, 138, 190, 7, 4, 1, 138, 190, 7, 1, 235, 200, 242, 187, 218, 132, 2, - 91, 7, 1, 211, 181, 7, 1, 248, 55, 250, 19, 7, 1, 233, 83, 250, 19, 7, 1, - 254, 145, 250, 19, 7, 1, 223, 58, 250, 19, 7, 6, 1, 246, 48, 2, 250, 242, - 7, 6, 1, 249, 69, 2, 4, 1, 210, 160, 2, 250, 242, 7, 4, 1, 246, 48, 2, - 250, 242, 7, 6, 1, 232, 194, 7, 6, 1, 233, 155, 2, 4, 1, 235, 150, 7, 4, - 1, 232, 194, 7, 6, 1, 228, 191, 7, 6, 1, 230, 31, 2, 4, 1, 235, 150, 7, - 4, 1, 228, 191, 7, 6, 1, 116, 2, 250, 242, 7, 4, 1, 116, 2, 250, 242, 7, - 6, 1, 240, 161, 2, 250, 242, 7, 4, 1, 240, 161, 2, 250, 242, 7, 6, 1, - 144, 2, 250, 242, 7, 4, 1, 144, 2, 250, 242, 7, 6, 1, 104, 2, 250, 242, - 7, 4, 1, 104, 2, 250, 242, 7, 6, 1, 104, 2, 248, 10, 22, 231, 237, 7, 4, - 1, 104, 2, 248, 10, 22, 231, 237, 7, 6, 1, 104, 2, 248, 10, 22, 142, 7, - 4, 1, 104, 2, 248, 10, 22, 142, 7, 6, 1, 104, 2, 248, 10, 22, 250, 242, - 7, 4, 1, 104, 2, 248, 10, 22, 250, 242, 7, 6, 1, 104, 2, 248, 10, 22, - 242, 143, 7, 4, 1, 104, 2, 248, 10, 22, 242, 143, 7, 4, 1, 215, 94, 76, - 7, 6, 1, 116, 2, 248, 10, 22, 231, 237, 7, 4, 1, 116, 2, 248, 10, 22, - 231, 237, 7, 6, 1, 116, 2, 59, 72, 22, 231, 237, 7, 4, 1, 116, 2, 59, 72, - 22, 231, 237, 7, 6, 1, 254, 253, 2, 231, 237, 7, 4, 1, 254, 253, 2, 231, - 237, 7, 6, 1, 243, 210, 2, 91, 7, 4, 1, 243, 210, 2, 91, 7, 6, 1, 243, - 210, 2, 250, 242, 7, 4, 1, 243, 210, 2, 250, 242, 7, 6, 1, 235, 30, 2, - 250, 242, 7, 4, 1, 235, 30, 2, 250, 242, 7, 6, 1, 144, 2, 226, 228, 7, 4, - 1, 144, 2, 226, 228, 7, 6, 1, 144, 2, 226, 229, 22, 231, 237, 7, 4, 1, - 144, 2, 226, 229, 22, 231, 237, 7, 6, 1, 245, 17, 2, 250, 242, 7, 4, 1, - 245, 17, 2, 250, 242, 7, 4, 1, 235, 151, 2, 250, 242, 7, 6, 1, 246, 47, - 7, 6, 1, 249, 69, 2, 4, 1, 210, 159, 7, 4, 1, 246, 47, 7, 6, 1, 243, 210, - 2, 142, 7, 4, 1, 243, 210, 2, 142, 7, 6, 1, 240, 206, 7, 6, 1, 211, 181, - 7, 6, 1, 230, 31, 2, 242, 143, 7, 4, 1, 230, 31, 2, 242, 143, 7, 6, 1, - 116, 2, 222, 237, 72, 22, 142, 7, 4, 1, 116, 2, 222, 237, 72, 22, 142, 7, - 6, 1, 254, 253, 2, 142, 7, 4, 1, 254, 253, 2, 142, 7, 6, 1, 144, 2, 218, - 105, 22, 142, 7, 4, 1, 144, 2, 218, 105, 22, 142, 7, 6, 1, 116, 2, 52, - 242, 143, 7, 4, 1, 116, 2, 52, 242, 143, 7, 6, 1, 116, 2, 235, 200, 251, - 154, 7, 4, 1, 116, 2, 235, 200, 251, 154, 7, 6, 1, 160, 2, 52, 242, 143, - 7, 4, 1, 160, 2, 52, 242, 143, 7, 6, 1, 160, 2, 235, 200, 251, 154, 7, 4, - 1, 160, 2, 235, 200, 251, 154, 7, 6, 1, 240, 161, 2, 52, 242, 143, 7, 4, - 1, 240, 161, 2, 52, 242, 143, 7, 6, 1, 240, 161, 2, 235, 200, 251, 154, - 7, 4, 1, 240, 161, 2, 235, 200, 251, 154, 7, 6, 1, 144, 2, 52, 242, 143, - 7, 4, 1, 144, 2, 52, 242, 143, 7, 6, 1, 144, 2, 235, 200, 251, 154, 7, 4, - 1, 144, 2, 235, 200, 251, 154, 7, 6, 1, 223, 227, 2, 52, 242, 143, 7, 4, - 1, 223, 227, 2, 52, 242, 143, 7, 6, 1, 223, 227, 2, 235, 200, 251, 154, - 7, 4, 1, 223, 227, 2, 235, 200, 251, 154, 7, 6, 1, 104, 2, 52, 242, 143, - 7, 4, 1, 104, 2, 52, 242, 143, 7, 6, 1, 104, 2, 235, 200, 251, 154, 7, 4, - 1, 104, 2, 235, 200, 251, 154, 7, 6, 1, 222, 94, 2, 249, 228, 51, 7, 4, - 1, 222, 94, 2, 249, 228, 51, 7, 6, 1, 217, 154, 2, 249, 228, 51, 7, 4, 1, - 217, 154, 2, 249, 228, 51, 7, 6, 1, 210, 231, 7, 4, 1, 210, 231, 7, 6, 1, - 242, 68, 2, 250, 242, 7, 4, 1, 242, 68, 2, 250, 242, 7, 6, 1, 230, 31, 2, - 200, 44, 233, 42, 7, 4, 1, 249, 69, 2, 249, 108, 7, 6, 1, 226, 138, 7, 4, - 1, 226, 138, 7, 6, 1, 210, 160, 2, 103, 7, 4, 1, 210, 160, 2, 103, 7, 6, - 1, 116, 2, 59, 48, 7, 4, 1, 116, 2, 59, 48, 7, 6, 1, 160, 2, 250, 191, 7, - 4, 1, 160, 2, 250, 191, 7, 6, 1, 144, 2, 248, 10, 22, 231, 237, 7, 4, 1, - 144, 2, 248, 10, 22, 231, 237, 7, 6, 1, 144, 2, 216, 90, 22, 231, 237, 7, - 4, 1, 144, 2, 216, 90, 22, 231, 237, 7, 6, 1, 144, 2, 59, 48, 7, 4, 1, - 144, 2, 59, 48, 7, 6, 1, 144, 2, 59, 72, 22, 231, 237, 7, 4, 1, 144, 2, - 59, 72, 22, 231, 237, 7, 6, 1, 211, 118, 2, 231, 237, 7, 4, 1, 211, 118, - 2, 231, 237, 7, 4, 1, 233, 155, 2, 249, 108, 7, 4, 1, 230, 31, 2, 249, - 108, 7, 4, 1, 217, 154, 2, 249, 108, 7, 4, 1, 247, 127, 235, 150, 7, 4, - 1, 248, 151, 247, 228, 7, 4, 1, 224, 34, 247, 228, 7, 6, 1, 116, 2, 91, - 7, 6, 1, 251, 75, 2, 91, 7, 4, 1, 251, 75, 2, 91, 7, 6, 1, 233, 155, 2, - 130, 7, 6, 1, 217, 154, 2, 248, 7, 91, 7, 4, 1, 222, 94, 2, 217, 251, - 217, 78, 7, 4, 1, 210, 160, 2, 217, 251, 217, 78, 7, 6, 1, 242, 187, 218, - 131, 7, 4, 1, 242, 187, 218, 131, 7, 6, 1, 57, 2, 91, 7, 6, 1, 104, 130, - 7, 6, 1, 215, 94, 214, 105, 7, 6, 1, 160, 2, 91, 7, 4, 1, 160, 2, 91, 7, - 6, 1, 235, 151, 2, 91, 7, 4, 1, 235, 151, 2, 91, 7, 6, 1, 4, 224, 100, 2, - 241, 59, 217, 78, 7, 4, 1, 224, 100, 2, 241, 59, 217, 78, 7, 6, 1, 223, - 227, 2, 91, 7, 4, 1, 223, 227, 2, 91, 7, 6, 1, 211, 118, 2, 91, 7, 4, 1, - 211, 118, 2, 91, 7, 4, 1, 215, 94, 61, 7, 4, 1, 254, 151, 7, 4, 1, 215, - 94, 254, 151, 7, 4, 1, 57, 2, 103, 7, 4, 1, 204, 78, 7, 4, 1, 251, 75, 2, - 249, 108, 7, 4, 1, 249, 69, 2, 217, 78, 7, 4, 1, 249, 69, 2, 103, 7, 4, - 1, 223, 52, 76, 7, 4, 1, 221, 197, 7, 4, 1, 221, 198, 2, 103, 7, 4, 1, - 204, 76, 7, 4, 1, 223, 52, 204, 76, 7, 4, 1, 223, 52, 204, 160, 2, 103, - 7, 4, 1, 250, 8, 223, 52, 204, 76, 7, 4, 1, 247, 127, 235, 151, 2, 91, 7, - 4, 1, 243, 210, 2, 103, 7, 4, 1, 119, 243, 209, 7, 1, 4, 6, 243, 209, 7, - 4, 1, 243, 114, 7, 4, 1, 223, 154, 240, 255, 7, 4, 1, 215, 94, 242, 67, - 7, 4, 1, 242, 68, 2, 103, 7, 4, 1, 241, 215, 2, 103, 7, 4, 1, 240, 161, - 2, 91, 7, 4, 1, 235, 192, 7, 1, 4, 6, 74, 7, 4, 1, 233, 155, 2, 230, 229, - 184, 7, 4, 1, 233, 155, 2, 252, 49, 7, 4, 1, 233, 155, 2, 223, 58, 103, - 7, 4, 1, 233, 7, 7, 4, 1, 215, 94, 194, 7, 4, 1, 215, 94, 232, 55, 2, - 200, 233, 42, 7, 4, 1, 232, 55, 2, 103, 7, 4, 1, 230, 31, 2, 43, 103, 7, - 4, 1, 230, 31, 2, 223, 58, 103, 7, 1, 4, 6, 230, 30, 7, 4, 1, 252, 142, - 78, 7, 1, 4, 6, 226, 238, 7, 4, 1, 250, 8, 226, 205, 7, 4, 1, 225, 136, - 7, 4, 1, 215, 94, 153, 7, 4, 1, 215, 94, 223, 227, 2, 200, 233, 42, 7, 4, - 1, 215, 94, 223, 227, 2, 103, 7, 4, 1, 223, 227, 2, 200, 233, 42, 7, 4, - 1, 223, 227, 2, 217, 78, 7, 4, 1, 223, 227, 2, 244, 95, 7, 4, 1, 223, 52, - 223, 227, 2, 244, 95, 7, 1, 4, 6, 153, 7, 1, 4, 6, 235, 200, 153, 7, 4, - 1, 222, 94, 2, 103, 7, 4, 1, 245, 83, 7, 4, 1, 247, 127, 235, 151, 2, - 218, 105, 22, 103, 7, 4, 1, 218, 233, 223, 52, 245, 83, 7, 4, 1, 245, 84, - 2, 249, 108, 7, 4, 1, 215, 94, 217, 153, 7, 4, 1, 217, 154, 2, 223, 58, - 103, 7, 4, 1, 104, 130, 7, 4, 1, 214, 157, 7, 4, 1, 214, 106, 2, 103, 7, - 4, 1, 215, 94, 214, 105, 7, 4, 1, 215, 94, 212, 98, 7, 4, 1, 215, 94, - 211, 117, 7, 1, 4, 6, 211, 117, 7, 4, 1, 210, 160, 2, 223, 58, 103, 7, 4, - 1, 210, 160, 2, 249, 108, 7, 4, 1, 245, 16, 7, 4, 1, 245, 17, 2, 249, - 108, 7, 1, 242, 187, 218, 131, 7, 1, 225, 142, 213, 135, 244, 1, 7, 1, - 235, 200, 242, 187, 218, 131, 7, 1, 218, 112, 251, 74, 7, 1, 251, 254, - 250, 19, 7, 1, 4, 6, 253, 166, 7, 4, 1, 250, 8, 204, 76, 7, 1, 4, 6, 243, - 210, 2, 103, 7, 1, 4, 6, 242, 67, 7, 4, 1, 235, 151, 2, 249, 135, 7, 4, - 1, 215, 94, 235, 29, 7, 1, 4, 6, 156, 7, 4, 1, 224, 100, 2, 103, 7, 1, - 242, 187, 218, 132, 2, 91, 7, 1, 223, 52, 242, 187, 218, 132, 2, 91, 7, - 4, 1, 246, 48, 247, 228, 7, 4, 1, 248, 34, 247, 228, 7, 4, 1, 246, 48, - 247, 229, 2, 249, 108, 7, 4, 1, 215, 186, 247, 228, 7, 4, 1, 216, 236, - 247, 228, 7, 4, 1, 217, 30, 247, 229, 2, 249, 108, 7, 4, 1, 244, 142, - 247, 228, 7, 4, 1, 232, 105, 247, 228, 7, 4, 1, 232, 56, 247, 228, 7, 1, - 251, 254, 225, 184, 7, 1, 252, 6, 225, 184, 7, 4, 1, 215, 94, 242, 68, 2, - 244, 95, 7, 4, 1, 215, 94, 242, 68, 2, 244, 96, 22, 217, 78, 58, 1, 4, - 242, 67, 58, 1, 4, 242, 68, 2, 103, 58, 1, 4, 235, 150, 58, 1, 4, 153, - 58, 1, 4, 215, 94, 153, 58, 1, 4, 215, 94, 223, 227, 2, 103, 58, 1, 4, 6, - 235, 200, 153, 58, 1, 4, 212, 98, 58, 1, 4, 211, 117, 58, 1, 224, 193, - 58, 1, 52, 224, 193, 58, 1, 215, 94, 249, 227, 58, 1, 254, 65, 58, 1, - 223, 52, 249, 227, 58, 1, 44, 163, 222, 236, 58, 1, 43, 163, 222, 236, - 58, 1, 242, 187, 218, 131, 58, 1, 223, 52, 242, 187, 218, 131, 58, 1, 43, - 254, 1, 58, 1, 44, 254, 1, 58, 1, 120, 254, 1, 58, 1, 124, 254, 1, 58, 1, - 250, 39, 255, 23, 250, 242, 58, 1, 67, 232, 219, 58, 1, 231, 237, 58, 1, - 255, 12, 255, 23, 58, 1, 242, 144, 255, 23, 58, 1, 121, 67, 232, 219, 58, - 1, 121, 231, 237, 58, 1, 121, 242, 144, 255, 23, 58, 1, 121, 255, 12, - 255, 23, 58, 1, 215, 223, 249, 234, 58, 1, 163, 215, 223, 249, 234, 58, - 1, 250, 181, 44, 163, 222, 236, 58, 1, 250, 181, 43, 163, 222, 236, 58, - 1, 120, 217, 88, 58, 1, 124, 217, 88, 58, 1, 96, 50, 58, 1, 230, 187, 50, - 251, 154, 59, 48, 222, 237, 48, 226, 228, 4, 184, 52, 255, 12, 255, 23, - 58, 1, 223, 39, 103, 58, 1, 249, 139, 255, 23, 58, 1, 4, 243, 114, 58, 1, - 4, 156, 58, 1, 4, 222, 93, 58, 1, 4, 211, 178, 58, 1, 4, 223, 52, 242, - 187, 218, 131, 58, 1, 245, 28, 138, 130, 58, 1, 125, 138, 130, 58, 1, - 230, 230, 138, 130, 58, 1, 121, 138, 130, 58, 1, 245, 27, 138, 130, 58, - 1, 210, 254, 248, 52, 138, 79, 58, 1, 211, 70, 248, 52, 138, 79, 58, 1, - 213, 133, 58, 1, 214, 186, 58, 1, 52, 254, 65, 58, 1, 121, 124, 254, 1, - 58, 1, 121, 120, 254, 1, 58, 1, 121, 43, 254, 1, 58, 1, 121, 44, 254, 1, - 58, 1, 121, 222, 236, 58, 1, 230, 229, 242, 144, 255, 23, 58, 1, 230, - 229, 52, 242, 144, 255, 23, 58, 1, 230, 229, 52, 255, 12, 255, 23, 58, 1, - 121, 184, 58, 1, 223, 160, 249, 234, 58, 1, 252, 66, 125, 216, 31, 58, 1, - 245, 151, 125, 216, 31, 58, 1, 252, 66, 121, 216, 31, 58, 1, 245, 151, - 121, 216, 31, 58, 1, 220, 56, 58, 1, 204, 220, 56, 58, 1, 121, 43, 75, - 38, 242, 144, 255, 23, 38, 255, 12, 255, 23, 38, 250, 39, 255, 23, 38, - 184, 38, 231, 237, 38, 226, 123, 38, 251, 154, 38, 59, 48, 38, 248, 9, - 38, 241, 59, 48, 38, 222, 237, 48, 38, 52, 255, 12, 255, 23, 38, 250, - 242, 38, 67, 232, 220, 48, 38, 52, 67, 232, 220, 48, 38, 52, 242, 144, - 255, 23, 38, 251, 7, 38, 235, 200, 251, 154, 38, 215, 94, 249, 228, 48, - 38, 249, 228, 48, 38, 223, 52, 249, 228, 48, 38, 249, 228, 72, 222, 254, - 38, 242, 144, 255, 24, 51, 38, 255, 12, 255, 24, 51, 38, 43, 217, 89, 51, - 38, 44, 217, 89, 51, 38, 43, 254, 118, 48, 38, 240, 255, 38, 43, 163, - 222, 237, 51, 38, 120, 217, 89, 51, 38, 124, 217, 89, 51, 38, 96, 5, 51, - 38, 230, 187, 5, 51, 38, 226, 68, 241, 59, 51, 38, 223, 58, 241, 59, 51, - 38, 59, 51, 38, 248, 10, 51, 38, 222, 237, 51, 38, 249, 228, 51, 38, 250, - 191, 38, 226, 228, 38, 67, 232, 220, 51, 38, 251, 148, 51, 38, 235, 200, - 52, 254, 32, 51, 38, 250, 243, 51, 38, 250, 39, 255, 24, 51, 38, 251, - 155, 51, 38, 235, 200, 251, 155, 51, 38, 216, 90, 51, 38, 231, 238, 51, - 38, 121, 232, 219, 38, 52, 121, 232, 219, 38, 216, 90, 226, 124, 38, 219, - 253, 218, 105, 226, 124, 38, 200, 218, 105, 226, 124, 38, 219, 253, 219, - 49, 226, 124, 38, 200, 219, 49, 226, 124, 38, 44, 163, 222, 237, 51, 38, - 235, 200, 251, 148, 51, 38, 42, 51, 38, 221, 182, 51, 38, 211, 179, 48, - 38, 67, 184, 38, 52, 226, 123, 38, 242, 144, 138, 79, 38, 255, 12, 138, - 79, 38, 26, 225, 178, 38, 26, 234, 8, 38, 26, 248, 4, 216, 19, 38, 26, - 210, 219, 38, 251, 148, 48, 38, 245, 106, 5, 51, 38, 52, 67, 232, 220, - 51, 38, 43, 254, 118, 51, 38, 228, 57, 216, 90, 48, 38, 241, 65, 48, 38, - 254, 156, 128, 216, 43, 48, 38, 43, 44, 80, 51, 38, 214, 153, 80, 51, 38, - 242, 149, 235, 69, 38, 44, 254, 2, 48, 38, 43, 163, 222, 237, 48, 38, - 244, 139, 38, 211, 179, 51, 38, 43, 254, 2, 51, 38, 44, 254, 2, 51, 38, - 44, 254, 2, 22, 120, 254, 2, 51, 38, 44, 163, 222, 237, 48, 38, 59, 72, - 222, 254, 38, 253, 225, 51, 38, 52, 222, 237, 51, 38, 210, 35, 48, 38, - 52, 251, 155, 51, 38, 52, 251, 154, 38, 52, 231, 237, 38, 52, 231, 238, - 51, 38, 52, 184, 38, 52, 235, 200, 251, 154, 38, 52, 97, 80, 51, 38, 7, - 4, 1, 61, 38, 7, 4, 1, 76, 38, 7, 4, 1, 74, 38, 7, 4, 1, 78, 38, 7, 4, 1, - 69, 38, 7, 4, 1, 251, 74, 38, 7, 4, 1, 249, 68, 38, 7, 4, 1, 242, 67, 38, - 7, 4, 1, 194, 38, 7, 4, 1, 153, 38, 7, 4, 1, 217, 153, 38, 7, 4, 1, 214, - 105, 38, 7, 4, 1, 211, 178, 26, 6, 1, 241, 203, 26, 4, 1, 241, 203, 26, - 6, 1, 254, 31, 221, 248, 26, 4, 1, 254, 31, 221, 248, 26, 227, 202, 50, - 26, 232, 114, 227, 202, 50, 26, 6, 1, 226, 55, 247, 235, 26, 4, 1, 226, - 55, 247, 235, 26, 210, 219, 26, 4, 223, 52, 232, 88, 219, 180, 87, 26, 4, - 246, 126, 232, 88, 219, 180, 87, 26, 4, 223, 52, 246, 126, 232, 88, 219, - 180, 87, 26, 224, 16, 79, 26, 216, 19, 26, 248, 4, 216, 19, 26, 6, 1, - 254, 152, 2, 216, 19, 26, 254, 105, 217, 3, 26, 6, 1, 245, 109, 2, 216, - 19, 26, 6, 1, 245, 72, 2, 216, 19, 26, 6, 1, 235, 193, 2, 216, 19, 26, 6, - 1, 226, 204, 2, 216, 19, 26, 6, 1, 214, 158, 2, 216, 19, 26, 6, 1, 226, - 206, 2, 216, 19, 26, 4, 1, 235, 193, 2, 248, 4, 22, 216, 19, 26, 6, 1, - 254, 151, 26, 6, 1, 252, 34, 26, 6, 1, 243, 114, 26, 6, 1, 248, 62, 26, - 6, 1, 245, 108, 26, 6, 1, 210, 85, 26, 6, 1, 245, 71, 26, 6, 1, 216, 180, - 26, 6, 1, 235, 192, 26, 6, 1, 234, 228, 26, 6, 1, 233, 104, 26, 6, 1, - 230, 107, 26, 6, 1, 227, 242, 26, 6, 1, 211, 157, 26, 6, 1, 226, 203, 26, - 6, 1, 225, 111, 26, 6, 1, 223, 40, 26, 6, 1, 219, 179, 26, 6, 1, 217, 42, - 26, 6, 1, 214, 157, 26, 6, 1, 225, 136, 26, 6, 1, 250, 118, 26, 6, 1, - 224, 164, 26, 6, 1, 226, 205, 26, 6, 1, 235, 193, 2, 248, 3, 26, 6, 1, - 214, 158, 2, 248, 3, 26, 4, 1, 254, 152, 2, 216, 19, 26, 4, 1, 245, 109, - 2, 216, 19, 26, 4, 1, 245, 72, 2, 216, 19, 26, 4, 1, 235, 193, 2, 216, - 19, 26, 4, 1, 214, 158, 2, 248, 4, 22, 216, 19, 26, 4, 1, 254, 151, 26, - 4, 1, 252, 34, 26, 4, 1, 243, 114, 26, 4, 1, 248, 62, 26, 4, 1, 245, 108, - 26, 4, 1, 210, 85, 26, 4, 1, 245, 71, 26, 4, 1, 216, 180, 26, 4, 1, 235, - 192, 26, 4, 1, 234, 228, 26, 4, 1, 233, 104, 26, 4, 1, 230, 107, 26, 4, - 1, 227, 242, 26, 4, 1, 211, 157, 26, 4, 1, 226, 203, 26, 4, 1, 225, 111, - 26, 4, 1, 223, 40, 26, 4, 1, 40, 219, 179, 26, 4, 1, 219, 179, 26, 4, 1, - 217, 42, 26, 4, 1, 214, 157, 26, 4, 1, 225, 136, 26, 4, 1, 250, 118, 26, - 4, 1, 224, 164, 26, 4, 1, 226, 205, 26, 4, 1, 235, 193, 2, 248, 3, 26, 4, - 1, 214, 158, 2, 248, 3, 26, 4, 1, 226, 204, 2, 216, 19, 26, 4, 1, 214, - 158, 2, 216, 19, 26, 4, 1, 226, 206, 2, 216, 19, 26, 6, 234, 253, 87, 26, - 252, 35, 87, 26, 216, 181, 87, 26, 214, 158, 2, 241, 59, 87, 26, 214, - 158, 2, 255, 12, 22, 241, 59, 87, 26, 214, 158, 2, 248, 10, 22, 241, 59, - 87, 26, 225, 137, 87, 26, 225, 112, 87, 26, 234, 253, 87, 26, 1, 254, 31, - 234, 12, 26, 4, 1, 254, 31, 234, 12, 26, 1, 218, 139, 26, 4, 1, 218, 139, - 26, 1, 247, 235, 26, 4, 1, 247, 235, 26, 1, 234, 12, 26, 4, 1, 234, 12, - 26, 1, 221, 248, 26, 4, 1, 221, 248, 81, 6, 1, 220, 57, 81, 4, 1, 220, - 57, 81, 6, 1, 244, 148, 81, 4, 1, 244, 148, 81, 6, 1, 234, 123, 81, 4, 1, - 234, 123, 81, 6, 1, 241, 52, 81, 4, 1, 241, 52, 81, 6, 1, 243, 109, 81, - 4, 1, 243, 109, 81, 6, 1, 220, 24, 81, 4, 1, 220, 24, 81, 6, 1, 248, 77, - 81, 4, 1, 248, 77, 26, 234, 229, 87, 26, 223, 41, 87, 26, 232, 88, 219, - 180, 87, 26, 1, 210, 224, 26, 6, 216, 181, 87, 26, 232, 88, 245, 109, 87, - 26, 223, 52, 232, 88, 245, 109, 87, 26, 6, 1, 220, 9, 26, 4, 1, 220, 9, - 26, 6, 232, 88, 219, 180, 87, 26, 6, 1, 221, 245, 26, 4, 1, 221, 245, 26, - 223, 41, 2, 218, 105, 87, 26, 6, 223, 52, 232, 88, 219, 180, 87, 26, 6, - 246, 126, 232, 88, 219, 180, 87, 26, 6, 223, 52, 246, 126, 232, 88, 219, - 180, 87, 33, 6, 1, 236, 68, 2, 242, 143, 33, 6, 1, 235, 196, 33, 6, 1, - 247, 170, 33, 6, 1, 242, 194, 33, 6, 1, 214, 202, 236, 67, 33, 6, 1, 246, - 44, 33, 6, 1, 251, 84, 74, 33, 6, 1, 211, 8, 33, 6, 1, 235, 132, 33, 6, - 1, 232, 193, 33, 6, 1, 228, 183, 33, 6, 1, 215, 175, 33, 6, 1, 234, 54, - 33, 6, 1, 240, 161, 2, 242, 143, 33, 6, 1, 219, 253, 69, 33, 6, 1, 246, - 40, 33, 6, 1, 61, 33, 6, 1, 252, 83, 33, 6, 1, 213, 255, 33, 6, 1, 242, - 243, 33, 6, 1, 248, 98, 33, 6, 1, 236, 67, 33, 6, 1, 210, 74, 33, 6, 1, - 210, 94, 33, 6, 1, 74, 33, 6, 1, 219, 253, 74, 33, 6, 1, 176, 33, 6, 1, - 245, 182, 33, 6, 1, 245, 167, 33, 6, 1, 245, 158, 33, 6, 1, 78, 33, 6, 1, - 225, 224, 33, 6, 1, 245, 100, 33, 6, 1, 245, 90, 33, 6, 1, 217, 23, 33, - 6, 1, 69, 33, 6, 1, 245, 210, 33, 6, 1, 162, 33, 6, 1, 215, 179, 33, 6, - 1, 250, 139, 33, 6, 1, 220, 104, 33, 6, 1, 220, 67, 33, 6, 1, 242, 10, - 50, 33, 6, 1, 211, 27, 33, 6, 1, 219, 54, 50, 33, 6, 1, 76, 33, 6, 1, - 210, 212, 33, 6, 1, 192, 33, 4, 1, 61, 33, 4, 1, 252, 83, 33, 4, 1, 213, - 255, 33, 4, 1, 242, 243, 33, 4, 1, 248, 98, 33, 4, 1, 236, 67, 33, 4, 1, - 210, 74, 33, 4, 1, 210, 94, 33, 4, 1, 74, 33, 4, 1, 219, 253, 74, 33, 4, - 1, 176, 33, 4, 1, 245, 182, 33, 4, 1, 245, 167, 33, 4, 1, 245, 158, 33, - 4, 1, 78, 33, 4, 1, 225, 224, 33, 4, 1, 245, 100, 33, 4, 1, 245, 90, 33, - 4, 1, 217, 23, 33, 4, 1, 69, 33, 4, 1, 245, 210, 33, 4, 1, 162, 33, 4, 1, - 215, 179, 33, 4, 1, 250, 139, 33, 4, 1, 220, 104, 33, 4, 1, 220, 67, 33, - 4, 1, 242, 10, 50, 33, 4, 1, 211, 27, 33, 4, 1, 219, 54, 50, 33, 4, 1, - 76, 33, 4, 1, 210, 212, 33, 4, 1, 192, 33, 4, 1, 236, 68, 2, 242, 143, - 33, 4, 1, 235, 196, 33, 4, 1, 247, 170, 33, 4, 1, 242, 194, 33, 4, 1, - 214, 202, 236, 67, 33, 4, 1, 246, 44, 33, 4, 1, 251, 84, 74, 33, 4, 1, - 211, 8, 33, 4, 1, 235, 132, 33, 4, 1, 232, 193, 33, 4, 1, 228, 183, 33, - 4, 1, 215, 175, 33, 4, 1, 234, 54, 33, 4, 1, 240, 161, 2, 242, 143, 33, - 4, 1, 219, 253, 69, 33, 4, 1, 246, 40, 33, 6, 1, 226, 205, 33, 4, 1, 226, - 205, 33, 6, 1, 211, 59, 33, 4, 1, 211, 59, 33, 6, 1, 235, 190, 76, 33, 4, - 1, 235, 190, 76, 33, 6, 1, 232, 198, 210, 183, 33, 4, 1, 232, 198, 210, - 183, 33, 6, 1, 235, 190, 232, 198, 210, 183, 33, 4, 1, 235, 190, 232, - 198, 210, 183, 33, 6, 1, 252, 1, 210, 183, 33, 4, 1, 252, 1, 210, 183, - 33, 6, 1, 235, 190, 252, 1, 210, 183, 33, 4, 1, 235, 190, 252, 1, 210, - 183, 33, 6, 1, 233, 239, 33, 4, 1, 233, 239, 33, 6, 1, 224, 164, 33, 4, - 1, 224, 164, 33, 6, 1, 244, 90, 33, 4, 1, 244, 90, 33, 6, 1, 235, 152, - 33, 4, 1, 235, 152, 33, 6, 1, 235, 153, 2, 52, 242, 144, 255, 23, 33, 4, - 1, 235, 153, 2, 52, 242, 144, 255, 23, 33, 6, 1, 214, 205, 33, 4, 1, 214, - 205, 33, 6, 1, 222, 187, 226, 205, 33, 4, 1, 222, 187, 226, 205, 33, 6, - 1, 226, 206, 2, 216, 66, 33, 4, 1, 226, 206, 2, 216, 66, 33, 6, 1, 226, - 144, 33, 4, 1, 226, 144, 33, 6, 1, 234, 12, 33, 4, 1, 234, 12, 33, 216, - 147, 50, 38, 33, 216, 66, 38, 33, 226, 69, 38, 33, 248, 162, 225, 21, 38, - 33, 224, 158, 225, 21, 38, 33, 225, 6, 38, 33, 240, 218, 216, 147, 50, - 38, 33, 230, 196, 50, 33, 6, 1, 219, 253, 240, 161, 2, 217, 78, 33, 4, 1, - 219, 253, 240, 161, 2, 217, 78, 33, 6, 1, 220, 148, 50, 33, 4, 1, 220, - 148, 50, 33, 6, 1, 245, 101, 2, 216, 115, 33, 4, 1, 245, 101, 2, 216, - 115, 33, 6, 1, 242, 244, 2, 214, 156, 33, 4, 1, 242, 244, 2, 214, 156, - 33, 6, 1, 242, 244, 2, 91, 33, 4, 1, 242, 244, 2, 91, 33, 6, 1, 242, 244, - 2, 230, 229, 103, 33, 4, 1, 242, 244, 2, 230, 229, 103, 33, 6, 1, 210, - 75, 2, 248, 47, 33, 4, 1, 210, 75, 2, 248, 47, 33, 6, 1, 210, 95, 2, 248, - 47, 33, 4, 1, 210, 95, 2, 248, 47, 33, 6, 1, 235, 19, 2, 248, 47, 33, 4, - 1, 235, 19, 2, 248, 47, 33, 6, 1, 235, 19, 2, 67, 91, 33, 4, 1, 235, 19, - 2, 67, 91, 33, 6, 1, 235, 19, 2, 91, 33, 4, 1, 235, 19, 2, 91, 33, 6, 1, - 252, 132, 176, 33, 4, 1, 252, 132, 176, 33, 6, 1, 245, 159, 2, 248, 47, - 33, 4, 1, 245, 159, 2, 248, 47, 33, 6, 27, 245, 159, 242, 243, 33, 4, 27, - 245, 159, 242, 243, 33, 6, 1, 225, 225, 2, 230, 229, 103, 33, 4, 1, 225, - 225, 2, 230, 229, 103, 33, 6, 1, 255, 29, 162, 33, 4, 1, 255, 29, 162, - 33, 6, 1, 245, 91, 2, 248, 47, 33, 4, 1, 245, 91, 2, 248, 47, 33, 6, 1, - 217, 24, 2, 248, 47, 33, 4, 1, 217, 24, 2, 248, 47, 33, 6, 1, 218, 123, - 69, 33, 4, 1, 218, 123, 69, 33, 6, 1, 218, 123, 104, 2, 91, 33, 4, 1, - 218, 123, 104, 2, 91, 33, 6, 1, 242, 56, 2, 248, 47, 33, 4, 1, 242, 56, - 2, 248, 47, 33, 6, 27, 217, 24, 215, 179, 33, 4, 27, 217, 24, 215, 179, - 33, 6, 1, 250, 140, 2, 248, 47, 33, 4, 1, 250, 140, 2, 248, 47, 33, 6, 1, - 250, 140, 2, 67, 91, 33, 4, 1, 250, 140, 2, 67, 91, 33, 6, 1, 220, 35, - 33, 4, 1, 220, 35, 33, 6, 1, 255, 29, 250, 139, 33, 4, 1, 255, 29, 250, - 139, 33, 6, 1, 255, 29, 250, 140, 2, 248, 47, 33, 4, 1, 255, 29, 250, - 140, 2, 248, 47, 33, 1, 226, 62, 33, 6, 1, 210, 75, 2, 251, 154, 33, 4, - 1, 210, 75, 2, 251, 154, 33, 6, 1, 235, 19, 2, 103, 33, 4, 1, 235, 19, 2, - 103, 33, 6, 1, 245, 183, 2, 217, 78, 33, 4, 1, 245, 183, 2, 217, 78, 33, - 6, 1, 245, 159, 2, 103, 33, 4, 1, 245, 159, 2, 103, 33, 6, 1, 245, 159, - 2, 217, 78, 33, 4, 1, 245, 159, 2, 217, 78, 33, 6, 1, 234, 133, 250, 139, - 33, 4, 1, 234, 133, 250, 139, 33, 6, 1, 245, 168, 2, 217, 78, 33, 4, 1, - 245, 168, 2, 217, 78, 33, 4, 1, 226, 62, 33, 6, 1, 116, 2, 251, 154, 33, - 4, 1, 116, 2, 251, 154, 33, 6, 1, 116, 2, 248, 9, 33, 4, 1, 116, 2, 248, - 9, 33, 6, 27, 116, 236, 67, 33, 4, 27, 116, 236, 67, 33, 6, 1, 236, 68, - 2, 251, 154, 33, 4, 1, 236, 68, 2, 251, 154, 33, 6, 1, 221, 197, 33, 4, - 1, 221, 197, 33, 6, 1, 221, 198, 2, 248, 9, 33, 4, 1, 221, 198, 2, 248, - 9, 33, 6, 1, 210, 75, 2, 248, 9, 33, 4, 1, 210, 75, 2, 248, 9, 33, 6, 1, - 210, 95, 2, 248, 9, 33, 4, 1, 210, 95, 2, 248, 9, 33, 6, 1, 255, 29, 246, - 44, 33, 4, 1, 255, 29, 246, 44, 33, 6, 1, 240, 161, 2, 231, 237, 33, 4, - 1, 240, 161, 2, 231, 237, 33, 6, 1, 240, 161, 2, 248, 9, 33, 4, 1, 240, - 161, 2, 248, 9, 33, 6, 1, 144, 2, 248, 9, 33, 4, 1, 144, 2, 248, 9, 33, - 6, 1, 252, 142, 78, 33, 4, 1, 252, 142, 78, 33, 6, 1, 252, 142, 144, 2, - 248, 9, 33, 4, 1, 252, 142, 144, 2, 248, 9, 33, 6, 1, 160, 2, 248, 9, 33, - 4, 1, 160, 2, 248, 9, 33, 6, 1, 104, 2, 231, 237, 33, 4, 1, 104, 2, 231, - 237, 33, 6, 1, 104, 2, 248, 9, 33, 4, 1, 104, 2, 248, 9, 33, 6, 1, 104, - 2, 52, 142, 33, 4, 1, 104, 2, 52, 142, 33, 6, 1, 250, 140, 2, 248, 9, 33, - 4, 1, 250, 140, 2, 248, 9, 33, 6, 1, 242, 244, 2, 248, 47, 33, 4, 1, 242, - 244, 2, 248, 47, 33, 6, 1, 211, 28, 2, 248, 9, 33, 4, 1, 211, 28, 2, 248, - 9, 33, 6, 1, 242, 244, 2, 218, 105, 22, 103, 33, 4, 1, 242, 244, 2, 218, - 105, 22, 103, 33, 6, 1, 242, 56, 2, 103, 33, 4, 1, 242, 56, 2, 103, 33, - 6, 1, 242, 56, 2, 91, 33, 4, 1, 242, 56, 2, 91, 33, 6, 1, 234, 20, 248, - 98, 33, 4, 1, 234, 20, 248, 98, 33, 6, 1, 234, 20, 247, 170, 33, 4, 1, - 234, 20, 247, 170, 33, 6, 1, 234, 20, 210, 27, 33, 4, 1, 234, 20, 210, - 27, 33, 6, 1, 234, 20, 246, 38, 33, 4, 1, 234, 20, 246, 38, 33, 6, 1, - 234, 20, 232, 193, 33, 4, 1, 234, 20, 232, 193, 33, 6, 1, 234, 20, 228, - 183, 33, 4, 1, 234, 20, 228, 183, 33, 6, 1, 234, 20, 219, 111, 33, 4, 1, - 234, 20, 219, 111, 33, 6, 1, 234, 20, 216, 61, 33, 4, 1, 234, 20, 216, - 61, 33, 6, 1, 223, 52, 210, 94, 33, 4, 1, 223, 52, 210, 94, 33, 6, 1, - 245, 183, 2, 103, 33, 4, 1, 245, 183, 2, 103, 33, 6, 1, 233, 4, 33, 4, 1, - 233, 4, 33, 6, 1, 223, 42, 33, 4, 1, 223, 42, 33, 6, 1, 211, 92, 33, 4, - 1, 211, 92, 33, 6, 1, 224, 91, 33, 4, 1, 224, 91, 33, 6, 1, 212, 22, 33, - 4, 1, 212, 22, 33, 6, 1, 254, 175, 176, 33, 4, 1, 254, 175, 176, 33, 6, - 1, 245, 183, 2, 230, 229, 103, 33, 4, 1, 245, 183, 2, 230, 229, 103, 33, - 6, 1, 245, 159, 2, 230, 229, 103, 33, 4, 1, 245, 159, 2, 230, 229, 103, - 33, 6, 1, 225, 225, 2, 248, 47, 33, 4, 1, 225, 225, 2, 248, 47, 33, 6, 1, - 220, 36, 2, 248, 47, 33, 4, 1, 220, 36, 2, 248, 47, 150, 6, 1, 253, 172, - 150, 6, 1, 252, 47, 150, 6, 1, 242, 210, 150, 6, 1, 248, 229, 150, 6, 1, - 245, 221, 150, 6, 1, 210, 116, 150, 6, 1, 245, 205, 150, 6, 1, 245, 73, - 150, 6, 1, 112, 150, 6, 1, 210, 74, 150, 6, 1, 235, 234, 150, 6, 1, 232, - 196, 150, 6, 1, 211, 160, 150, 6, 1, 251, 41, 150, 6, 1, 234, 171, 150, - 6, 1, 241, 75, 150, 6, 1, 235, 147, 150, 6, 1, 242, 253, 150, 6, 1, 250, - 134, 150, 6, 1, 231, 63, 150, 6, 1, 211, 8, 150, 6, 1, 228, 44, 150, 6, - 1, 220, 104, 150, 6, 1, 213, 138, 150, 6, 1, 250, 165, 150, 6, 1, 225, - 208, 150, 6, 1, 235, 116, 150, 6, 1, 205, 150, 6, 1, 221, 163, 150, 6, 1, - 213, 179, 150, 6, 1, 216, 63, 150, 6, 1, 223, 98, 150, 6, 1, 249, 246, - 150, 6, 1, 210, 249, 150, 6, 1, 225, 49, 150, 6, 1, 234, 182, 150, 6, 1, - 226, 226, 150, 6, 1, 244, 150, 150, 58, 1, 43, 163, 222, 236, 150, 254, - 65, 150, 245, 162, 79, 150, 245, 39, 79, 150, 249, 227, 150, 224, 16, 79, - 150, 255, 30, 79, 150, 4, 1, 253, 172, 150, 4, 1, 252, 47, 150, 4, 1, - 242, 210, 150, 4, 1, 248, 229, 150, 4, 1, 245, 221, 150, 4, 1, 210, 116, - 150, 4, 1, 245, 205, 150, 4, 1, 245, 73, 150, 4, 1, 112, 150, 4, 1, 210, - 74, 150, 4, 1, 235, 234, 150, 4, 1, 232, 196, 150, 4, 1, 211, 160, 150, - 4, 1, 251, 41, 150, 4, 1, 234, 171, 150, 4, 1, 241, 75, 150, 4, 1, 235, - 147, 150, 4, 1, 242, 253, 150, 4, 1, 250, 134, 150, 4, 1, 231, 63, 150, - 4, 1, 211, 8, 150, 4, 1, 228, 44, 150, 4, 1, 220, 104, 150, 4, 1, 213, - 138, 150, 4, 1, 250, 165, 150, 4, 1, 225, 208, 150, 4, 1, 235, 116, 150, - 4, 1, 205, 150, 4, 1, 221, 163, 150, 4, 1, 213, 179, 150, 4, 1, 216, 63, - 150, 4, 1, 223, 98, 150, 4, 1, 249, 246, 150, 4, 1, 210, 249, 150, 4, 1, - 225, 49, 150, 4, 1, 234, 182, 150, 4, 1, 226, 226, 150, 4, 1, 244, 150, - 150, 4, 27, 245, 222, 210, 249, 150, 243, 236, 218, 131, 150, 240, 175, - 150, 246, 103, 50, 94, 255, 24, 245, 65, 94, 255, 24, 221, 164, 94, 255, - 24, 220, 90, 94, 255, 24, 210, 104, 224, 74, 94, 255, 24, 210, 104, 243, - 132, 94, 255, 24, 216, 76, 94, 255, 24, 223, 50, 94, 255, 24, 210, 103, - 94, 255, 24, 225, 249, 94, 255, 24, 211, 20, 94, 255, 24, 216, 215, 94, - 255, 24, 243, 48, 94, 255, 24, 243, 49, 230, 74, 94, 255, 24, 243, 46, - 94, 255, 24, 224, 75, 226, 20, 94, 255, 24, 216, 254, 243, 63, 94, 255, - 24, 225, 230, 94, 255, 24, 253, 208, 242, 48, 94, 255, 24, 230, 84, 94, - 255, 24, 231, 213, 94, 255, 24, 231, 54, 94, 255, 24, 231, 55, 234, 183, - 94, 255, 24, 248, 171, 94, 255, 24, 224, 86, 94, 255, 24, 216, 254, 224, - 70, 94, 255, 24, 211, 30, 252, 48, 210, 230, 94, 255, 24, 226, 211, 94, - 255, 24, 236, 26, 94, 255, 24, 248, 78, 94, 255, 24, 210, 33, 94, 164, - 231, 148, 250, 43, 94, 225, 14, 220, 38, 94, 225, 14, 242, 1, 221, 164, - 94, 225, 14, 242, 1, 225, 243, 94, 225, 14, 242, 1, 224, 79, 94, 225, 14, - 241, 165, 94, 225, 14, 215, 177, 94, 225, 14, 221, 164, 94, 225, 14, 225, - 243, 94, 225, 14, 224, 79, 94, 225, 14, 241, 68, 94, 225, 14, 241, 69, - 242, 3, 31, 214, 3, 94, 225, 14, 224, 20, 94, 225, 14, 248, 216, 177, - 231, 176, 94, 225, 14, 231, 43, 94, 224, 144, 231, 173, 94, 225, 14, 223, - 172, 94, 224, 144, 225, 251, 94, 225, 14, 220, 23, 247, 128, 94, 225, 14, - 219, 161, 247, 128, 94, 224, 144, 219, 55, 225, 245, 94, 164, 214, 160, - 247, 128, 94, 164, 232, 114, 247, 128, 94, 224, 144, 227, 199, 242, 47, - 94, 225, 14, 224, 80, 224, 74, 94, 1, 254, 179, 94, 1, 252, 36, 94, 1, - 242, 208, 94, 1, 248, 197, 94, 1, 241, 245, 94, 1, 214, 3, 94, 1, 210, - 97, 94, 1, 241, 204, 94, 1, 216, 231, 94, 1, 210, 233, 94, 1, 40, 235, 0, - 94, 1, 235, 0, 94, 1, 233, 100, 94, 1, 40, 231, 70, 94, 1, 231, 70, 94, - 1, 40, 227, 198, 94, 1, 227, 198, 94, 1, 221, 251, 94, 1, 253, 170, 94, - 1, 40, 225, 224, 94, 1, 225, 224, 94, 1, 40, 215, 180, 94, 1, 215, 180, - 94, 1, 224, 42, 94, 1, 223, 70, 94, 1, 220, 22, 94, 1, 217, 39, 94, 27, - 211, 6, 52, 214, 3, 94, 27, 211, 6, 214, 4, 210, 233, 94, 27, 211, 6, 52, - 210, 233, 94, 224, 144, 243, 48, 94, 224, 144, 243, 46, 9, 54, 50, 9, 5, - 221, 244, 9, 244, 38, 231, 159, 9, 5, 222, 25, 9, 5, 221, 247, 254, 45, - 249, 117, 222, 195, 254, 45, 244, 12, 222, 195, 9, 223, 137, 254, 45, - 225, 186, 230, 198, 50, 254, 45, 225, 186, 216, 249, 216, 149, 50, 254, - 230, 50, 9, 249, 227, 9, 248, 158, 220, 139, 9, 225, 16, 213, 241, 50, 9, - 5, 230, 179, 9, 5, 222, 5, 254, 181, 212, 45, 9, 5, 254, 181, 253, 229, - 9, 5, 223, 170, 254, 180, 9, 5, 223, 178, 254, 161, 254, 112, 9, 5, 217, - 71, 9, 4, 125, 217, 81, 9, 4, 125, 27, 109, 2, 233, 109, 2, 211, 43, 9, - 4, 125, 210, 108, 9, 4, 244, 173, 9, 4, 248, 192, 9, 4, 234, 211, 9, 220, - 152, 9, 1, 79, 9, 215, 212, 59, 224, 144, 79, 9, 224, 16, 79, 9, 1, 234, - 215, 211, 43, 9, 1, 242, 26, 9, 1, 109, 2, 231, 233, 48, 9, 1, 109, 2, - 182, 48, 9, 1, 212, 31, 2, 182, 48, 9, 1, 109, 2, 182, 51, 9, 1, 77, 2, - 182, 48, 9, 1, 254, 179, 9, 1, 252, 62, 9, 1, 217, 9, 231, 169, 9, 1, - 217, 8, 9, 1, 216, 193, 9, 1, 235, 129, 9, 1, 242, 44, 9, 1, 234, 135, 9, - 1, 248, 203, 9, 1, 216, 203, 9, 1, 223, 98, 9, 1, 210, 108, 9, 1, 221, - 168, 9, 1, 220, 61, 9, 1, 222, 28, 9, 1, 248, 224, 9, 1, 217, 81, 9, 1, - 210, 111, 9, 1, 254, 205, 9, 1, 242, 251, 9, 1, 234, 181, 2, 113, 170, - 48, 9, 1, 234, 181, 2, 134, 170, 51, 9, 1, 244, 176, 77, 2, 235, 200, - 214, 105, 9, 1, 244, 176, 77, 2, 113, 170, 48, 9, 1, 244, 176, 77, 2, - 134, 170, 48, 9, 217, 44, 9, 1, 244, 150, 9, 1, 224, 84, 9, 1, 235, 0, 9, - 1, 233, 108, 9, 1, 231, 83, 9, 1, 228, 67, 9, 1, 241, 225, 9, 1, 212, 30, - 9, 1, 109, 231, 197, 9, 1, 211, 43, 9, 244, 171, 9, 248, 190, 9, 234, - 209, 9, 244, 173, 9, 248, 192, 9, 234, 211, 9, 220, 95, 9, 218, 46, 9, - 231, 231, 48, 9, 182, 48, 9, 182, 51, 9, 218, 66, 254, 179, 9, 235, 200, - 248, 192, 9, 164, 228, 68, 242, 225, 9, 209, 255, 9, 25, 5, 4, 214, 106, - 48, 9, 25, 5, 235, 200, 4, 214, 106, 48, 9, 25, 5, 59, 51, 9, 223, 52, - 248, 192, 9, 244, 174, 2, 113, 247, 126, 9, 212, 32, 182, 51, 254, 45, - 21, 210, 86, 254, 45, 21, 111, 254, 45, 21, 105, 254, 45, 21, 158, 254, - 45, 21, 161, 254, 45, 21, 190, 254, 45, 21, 195, 254, 45, 21, 199, 254, - 45, 21, 196, 254, 45, 21, 201, 9, 225, 185, 50, 9, 248, 91, 220, 139, 9, - 216, 147, 220, 139, 9, 244, 89, 225, 12, 218, 158, 9, 1, 247, 127, 252, - 62, 9, 1, 247, 127, 224, 84, 9, 1, 218, 24, 254, 179, 9, 1, 109, 212, 46, - 9, 1, 109, 2, 212, 32, 182, 48, 9, 1, 109, 2, 212, 32, 182, 51, 9, 1, - 125, 242, 26, 9, 1, 125, 182, 254, 179, 9, 1, 125, 182, 212, 30, 9, 1, - 104, 2, 182, 48, 9, 1, 125, 182, 211, 43, 9, 1, 215, 149, 9, 1, 215, 147, - 9, 1, 252, 72, 9, 1, 217, 9, 2, 222, 236, 9, 1, 217, 9, 2, 134, 170, 72, - 246, 111, 9, 1, 225, 208, 9, 1, 217, 6, 9, 1, 252, 60, 9, 1, 122, 2, 182, - 48, 9, 1, 122, 2, 113, 170, 67, 48, 9, 1, 227, 157, 9, 1, 246, 51, 9, 1, - 122, 2, 134, 170, 48, 9, 1, 217, 27, 9, 1, 217, 25, 9, 1, 248, 138, 9, 1, - 248, 204, 2, 222, 236, 9, 1, 248, 204, 2, 59, 51, 9, 1, 248, 204, 2, 59, - 252, 51, 22, 4, 217, 81, 9, 1, 248, 209, 9, 1, 248, 140, 9, 1, 246, 78, - 9, 1, 248, 204, 2, 134, 170, 72, 246, 111, 9, 1, 248, 204, 2, 244, 19, - 170, 48, 9, 1, 222, 173, 9, 1, 223, 99, 2, 4, 214, 105, 9, 1, 223, 99, 2, - 222, 236, 9, 1, 223, 99, 2, 59, 51, 9, 1, 223, 99, 2, 4, 214, 106, 51, 9, - 1, 223, 99, 2, 59, 252, 51, 22, 59, 48, 9, 1, 223, 99, 2, 113, 170, 48, - 9, 1, 235, 126, 9, 1, 223, 99, 2, 244, 19, 170, 48, 9, 1, 221, 169, 2, - 59, 252, 51, 22, 59, 48, 9, 1, 221, 169, 2, 134, 170, 51, 9, 1, 221, 169, - 2, 134, 170, 252, 51, 22, 134, 170, 48, 9, 1, 222, 29, 2, 113, 170, 51, - 9, 1, 222, 29, 2, 134, 170, 48, 9, 1, 217, 82, 2, 134, 170, 48, 9, 1, - 254, 206, 2, 134, 170, 48, 9, 1, 247, 127, 244, 150, 9, 1, 244, 151, 2, - 59, 230, 114, 51, 9, 1, 244, 151, 2, 59, 51, 9, 1, 213, 248, 9, 1, 244, - 151, 2, 134, 170, 51, 9, 1, 225, 206, 9, 1, 224, 85, 2, 59, 48, 9, 1, - 224, 85, 2, 134, 170, 48, 9, 1, 234, 180, 9, 1, 217, 251, 235, 0, 9, 1, - 235, 1, 2, 222, 236, 9, 1, 235, 1, 2, 59, 48, 9, 1, 229, 84, 9, 1, 235, - 1, 2, 134, 170, 51, 9, 1, 243, 129, 9, 1, 243, 130, 2, 222, 236, 9, 1, - 229, 7, 9, 1, 243, 130, 2, 113, 170, 51, 9, 1, 242, 108, 9, 1, 243, 130, - 2, 134, 170, 48, 9, 1, 233, 109, 2, 4, 214, 105, 9, 1, 233, 109, 2, 59, - 48, 9, 1, 233, 109, 2, 134, 170, 48, 9, 1, 233, 109, 2, 134, 170, 51, 9, - 1, 228, 68, 2, 59, 51, 9, 1, 228, 68, 242, 225, 9, 1, 222, 216, 9, 1, - 228, 68, 2, 222, 236, 9, 1, 228, 68, 2, 134, 170, 48, 9, 1, 241, 226, - 247, 149, 9, 1, 217, 28, 2, 59, 48, 9, 1, 241, 226, 2, 77, 48, 9, 1, 241, - 226, 242, 178, 9, 1, 241, 226, 242, 179, 2, 182, 48, 9, 1, 217, 9, 231, - 170, 242, 178, 9, 1, 212, 31, 2, 222, 236, 9, 1, 234, 79, 226, 238, 9, 1, - 226, 238, 9, 1, 69, 9, 1, 210, 212, 9, 1, 234, 79, 210, 212, 9, 1, 212, - 31, 2, 113, 170, 48, 9, 1, 213, 255, 9, 1, 244, 176, 211, 43, 9, 1, 77, - 2, 217, 78, 9, 1, 77, 2, 4, 214, 105, 9, 1, 212, 31, 2, 59, 48, 9, 1, 76, - 9, 1, 77, 2, 134, 170, 51, 9, 1, 77, 252, 140, 9, 1, 77, 252, 141, 2, - 182, 48, 9, 243, 236, 218, 131, 9, 1, 254, 252, 9, 4, 125, 27, 222, 29, - 2, 233, 109, 2, 109, 231, 197, 9, 4, 125, 27, 224, 85, 2, 233, 109, 2, - 109, 231, 197, 9, 4, 125, 66, 65, 17, 9, 4, 125, 233, 109, 254, 179, 9, - 4, 125, 235, 129, 9, 4, 125, 134, 247, 126, 9, 4, 125, 221, 168, 9, 245, - 151, 64, 253, 174, 9, 218, 154, 64, 222, 140, 245, 183, 241, 162, 9, 4, - 125, 222, 185, 210, 86, 9, 4, 125, 214, 159, 223, 118, 210, 86, 9, 4, - 125, 247, 127, 241, 243, 64, 234, 135, 9, 4, 125, 66, 53, 17, 9, 4, 121, - 221, 168, 9, 4, 125, 231, 232, 9, 4, 212, 30, 9, 4, 211, 43, 9, 4, 125, - 211, 43, 9, 4, 125, 228, 67, 9, 225, 44, 64, 222, 15, 9, 245, 160, 250, - 183, 121, 218, 131, 9, 245, 160, 250, 183, 125, 218, 131, 9, 222, 185, - 125, 218, 132, 2, 244, 112, 250, 182, 9, 4, 121, 231, 83, 9, 1, 248, 204, - 2, 235, 200, 214, 105, 9, 1, 223, 99, 2, 235, 200, 214, 105, 245, 30, - 254, 45, 21, 210, 86, 245, 30, 254, 45, 21, 111, 245, 30, 254, 45, 21, - 105, 245, 30, 254, 45, 21, 158, 245, 30, 254, 45, 21, 161, 245, 30, 254, - 45, 21, 190, 245, 30, 254, 45, 21, 195, 245, 30, 254, 45, 21, 199, 245, - 30, 254, 45, 21, 196, 245, 30, 254, 45, 21, 201, 9, 1, 220, 62, 2, 59, - 51, 9, 1, 248, 225, 2, 59, 51, 9, 1, 242, 252, 2, 59, 51, 9, 5, 219, 160, - 254, 134, 9, 5, 219, 160, 224, 238, 231, 63, 9, 1, 241, 226, 2, 235, 200, - 214, 105, 183, 245, 151, 64, 226, 18, 183, 218, 20, 243, 236, 218, 131, - 183, 218, 68, 243, 236, 218, 131, 183, 218, 20, 249, 234, 183, 218, 68, - 249, 234, 183, 203, 249, 234, 183, 249, 235, 219, 108, 233, 52, 183, 249, - 235, 219, 108, 222, 254, 183, 218, 20, 249, 235, 219, 108, 233, 52, 183, - 218, 68, 249, 235, 219, 108, 222, 254, 183, 249, 188, 183, 242, 8, 226, - 254, 183, 242, 8, 231, 41, 183, 242, 8, 253, 226, 183, 255, 30, 79, 183, - 1, 254, 183, 183, 1, 218, 24, 254, 183, 183, 1, 252, 33, 183, 1, 243, - 120, 183, 1, 243, 121, 243, 98, 183, 1, 248, 200, 183, 1, 247, 127, 248, - 201, 222, 232, 183, 1, 241, 245, 183, 1, 212, 30, 183, 1, 210, 108, 183, - 1, 241, 202, 183, 1, 216, 227, 183, 1, 216, 228, 243, 98, 183, 1, 210, - 199, 183, 1, 210, 200, 241, 245, 183, 1, 234, 231, 183, 1, 233, 107, 183, - 1, 230, 195, 183, 1, 227, 198, 183, 1, 220, 145, 183, 1, 40, 220, 145, - 183, 1, 76, 183, 1, 225, 224, 183, 1, 223, 52, 225, 224, 183, 1, 222, 26, - 183, 1, 224, 78, 183, 1, 222, 232, 183, 1, 220, 22, 183, 1, 217, 37, 183, - 1, 225, 172, 252, 20, 183, 1, 225, 172, 242, 249, 183, 1, 225, 172, 248, - 28, 183, 224, 154, 48, 183, 224, 154, 51, 183, 224, 154, 246, 125, 183, - 210, 17, 48, 183, 210, 17, 51, 183, 210, 17, 246, 125, 183, 223, 134, 48, - 183, 223, 134, 51, 183, 246, 126, 210, 24, 241, 51, 183, 246, 126, 210, - 24, 254, 113, 183, 241, 248, 48, 183, 241, 248, 51, 183, 241, 247, 246, - 125, 183, 245, 87, 48, 183, 245, 87, 51, 183, 222, 109, 183, 244, 144, - 247, 128, 183, 223, 251, 183, 222, 136, 183, 113, 67, 170, 48, 183, 113, - 67, 170, 51, 183, 134, 170, 48, 183, 134, 170, 51, 183, 226, 252, 232, - 220, 48, 183, 226, 252, 232, 220, 51, 183, 230, 61, 183, 252, 139, 183, - 1, 219, 51, 210, 80, 183, 1, 219, 51, 234, 128, 183, 1, 219, 51, 244, - 162, 9, 1, 252, 63, 2, 134, 170, 241, 1, 51, 9, 1, 252, 63, 2, 59, 252, - 51, 22, 134, 170, 48, 9, 1, 252, 63, 2, 134, 170, 225, 10, 214, 153, 51, - 9, 1, 252, 63, 2, 134, 170, 225, 10, 214, 153, 252, 51, 22, 113, 170, 48, - 9, 1, 252, 63, 2, 113, 170, 252, 51, 22, 59, 48, 9, 1, 252, 63, 2, 235, - 200, 4, 214, 106, 51, 9, 1, 252, 63, 2, 4, 214, 105, 9, 1, 122, 2, 113, - 170, 48, 9, 1, 122, 2, 134, 170, 225, 10, 214, 153, 51, 9, 1, 248, 204, - 2, 113, 170, 213, 189, 252, 51, 22, 4, 217, 81, 9, 1, 248, 204, 2, 235, - 200, 4, 214, 106, 51, 9, 1, 223, 99, 2, 91, 9, 1, 221, 169, 2, 244, 19, - 170, 48, 9, 1, 254, 206, 2, 113, 170, 48, 9, 1, 254, 206, 2, 134, 170, - 225, 10, 246, 112, 48, 9, 1, 254, 206, 2, 113, 170, 213, 189, 48, 9, 1, - 244, 151, 2, 113, 170, 51, 9, 1, 244, 151, 2, 134, 170, 225, 10, 214, - 153, 51, 9, 1, 234, 181, 2, 59, 48, 9, 1, 234, 181, 2, 134, 170, 48, 9, - 1, 234, 181, 2, 134, 170, 225, 10, 214, 153, 51, 9, 1, 66, 2, 59, 48, 9, - 1, 66, 2, 59, 51, 9, 1, 228, 68, 2, 113, 170, 51, 9, 1, 228, 68, 2, 4, - 217, 81, 9, 1, 228, 68, 2, 4, 214, 105, 9, 1, 233, 109, 2, 130, 9, 1, - 223, 99, 2, 113, 170, 213, 189, 48, 9, 1, 223, 99, 2, 182, 48, 9, 1, 221, - 169, 2, 113, 170, 213, 189, 48, 9, 1, 122, 2, 4, 9, 1, 217, 82, 51, 9, 1, - 122, 2, 4, 9, 1, 217, 82, 22, 113, 247, 126, 9, 1, 221, 169, 2, 4, 9, 1, - 217, 82, 22, 113, 247, 126, 9, 1, 223, 99, 2, 4, 9, 1, 217, 82, 22, 113, - 247, 126, 9, 1, 122, 2, 4, 9, 1, 217, 82, 48, 9, 1, 109, 2, 245, 30, 254, - 45, 21, 113, 48, 9, 1, 109, 2, 245, 30, 254, 45, 21, 134, 48, 9, 1, 244, - 176, 77, 2, 245, 30, 254, 45, 21, 113, 48, 9, 1, 244, 176, 77, 2, 245, - 30, 254, 45, 21, 134, 48, 9, 1, 244, 176, 77, 2, 245, 30, 254, 45, 21, - 244, 19, 51, 9, 1, 212, 31, 2, 245, 30, 254, 45, 21, 113, 48, 9, 1, 212, - 31, 2, 245, 30, 254, 45, 21, 134, 48, 9, 1, 77, 252, 141, 2, 245, 30, - 254, 45, 21, 113, 48, 9, 1, 77, 252, 141, 2, 245, 30, 254, 45, 21, 134, - 48, 9, 1, 122, 2, 245, 30, 254, 45, 21, 244, 19, 51, 9, 1, 221, 169, 2, - 245, 30, 254, 45, 21, 244, 19, 48, 9, 1, 221, 169, 2, 235, 200, 214, 105, - 9, 1, 235, 1, 2, 113, 170, 48, 216, 206, 1, 242, 53, 216, 206, 1, 220, - 70, 216, 206, 1, 228, 66, 216, 206, 1, 223, 187, 216, 206, 1, 252, 197, - 216, 206, 1, 233, 1, 216, 206, 1, 235, 14, 216, 206, 1, 254, 168, 216, - 206, 1, 214, 25, 216, 206, 1, 231, 82, 216, 206, 1, 244, 202, 216, 206, - 1, 248, 31, 216, 206, 1, 216, 208, 216, 206, 1, 233, 137, 216, 206, 1, - 243, 138, 216, 206, 1, 242, 184, 216, 206, 1, 221, 167, 216, 206, 1, 248, - 156, 216, 206, 1, 210, 100, 216, 206, 1, 217, 38, 216, 206, 1, 211, 103, - 216, 206, 1, 225, 237, 216, 206, 1, 235, 134, 216, 206, 1, 250, 142, 216, - 206, 1, 215, 156, 216, 206, 1, 241, 195, 216, 206, 1, 234, 137, 216, 206, - 1, 216, 207, 216, 206, 1, 210, 115, 216, 206, 1, 220, 60, 216, 206, 1, - 222, 32, 216, 206, 1, 248, 227, 216, 206, 1, 112, 216, 206, 1, 210, 23, - 216, 206, 1, 254, 202, 216, 206, 1, 242, 250, 216, 206, 1, 224, 88, 216, - 206, 1, 212, 63, 216, 206, 255, 31, 216, 206, 255, 47, 216, 206, 240, - 121, 216, 206, 245, 216, 216, 206, 214, 222, 216, 206, 226, 186, 216, - 206, 245, 224, 216, 206, 245, 24, 216, 206, 226, 251, 216, 206, 227, 3, - 216, 206, 218, 46, 216, 206, 1, 229, 230, 228, 142, 21, 210, 86, 228, - 142, 21, 111, 228, 142, 21, 105, 228, 142, 21, 158, 228, 142, 21, 161, - 228, 142, 21, 190, 228, 142, 21, 195, 228, 142, 21, 199, 228, 142, 21, - 196, 228, 142, 21, 201, 228, 142, 1, 61, 228, 142, 1, 245, 217, 228, 142, - 1, 74, 228, 142, 1, 76, 228, 142, 1, 69, 228, 142, 1, 226, 187, 228, 142, - 1, 78, 228, 142, 1, 248, 217, 228, 142, 1, 230, 30, 228, 142, 1, 252, - 199, 228, 142, 1, 191, 228, 142, 1, 217, 106, 228, 142, 1, 235, 147, 228, - 142, 1, 250, 165, 228, 142, 1, 248, 229, 228, 142, 1, 205, 228, 142, 1, - 222, 181, 228, 142, 1, 206, 228, 142, 1, 243, 86, 228, 142, 1, 244, 204, - 228, 142, 1, 176, 228, 142, 1, 233, 141, 228, 142, 1, 229, 234, 211, 223, - 228, 142, 1, 186, 228, 142, 1, 227, 169, 228, 142, 1, 198, 228, 142, 1, - 162, 228, 142, 1, 212, 65, 228, 142, 1, 192, 228, 142, 1, 227, 170, 211, - 223, 228, 142, 1, 235, 67, 235, 147, 228, 142, 1, 235, 67, 250, 165, 228, - 142, 1, 235, 67, 205, 228, 142, 38, 219, 253, 125, 216, 31, 228, 142, 38, - 219, 253, 121, 216, 31, 228, 142, 38, 219, 253, 222, 231, 216, 31, 228, - 142, 38, 200, 248, 46, 216, 31, 228, 142, 38, 200, 125, 216, 31, 228, - 142, 38, 200, 121, 216, 31, 228, 142, 38, 200, 222, 231, 216, 31, 228, - 142, 38, 229, 198, 79, 228, 142, 38, 52, 59, 48, 228, 142, 125, 138, 254, - 65, 228, 142, 121, 138, 254, 65, 228, 142, 16, 226, 188, 248, 58, 228, - 142, 16, 243, 85, 228, 142, 249, 227, 228, 142, 245, 39, 79, 228, 142, - 233, 114, 221, 254, 1, 254, 185, 221, 254, 1, 251, 236, 221, 254, 1, 243, - 119, 221, 254, 1, 248, 202, 221, 254, 1, 235, 158, 221, 254, 1, 252, 197, - 221, 254, 1, 210, 89, 221, 254, 1, 235, 166, 221, 254, 1, 216, 68, 221, - 254, 1, 210, 182, 221, 254, 1, 235, 15, 221, 254, 1, 233, 134, 221, 254, - 1, 230, 195, 221, 254, 1, 227, 198, 221, 254, 1, 219, 158, 221, 254, 1, - 236, 6, 221, 254, 1, 244, 129, 221, 254, 1, 215, 182, 221, 254, 1, 224, - 13, 221, 254, 1, 222, 232, 221, 254, 1, 220, 87, 221, 254, 1, 217, 101, - 221, 254, 164, 236, 6, 221, 254, 164, 236, 5, 221, 254, 164, 226, 247, - 221, 254, 164, 248, 215, 221, 254, 58, 1, 245, 113, 210, 182, 221, 254, - 164, 245, 113, 210, 182, 221, 254, 25, 5, 200, 76, 221, 254, 25, 5, 76, - 221, 254, 25, 5, 226, 122, 255, 82, 221, 254, 25, 5, 200, 255, 82, 221, - 254, 25, 5, 255, 82, 221, 254, 25, 5, 226, 122, 61, 221, 254, 25, 5, 200, - 61, 221, 254, 25, 5, 61, 221, 254, 58, 1, 219, 253, 61, 221, 254, 25, 5, - 219, 253, 61, 221, 254, 25, 5, 200, 69, 221, 254, 25, 5, 69, 221, 254, - 58, 1, 74, 221, 254, 25, 5, 200, 74, 221, 254, 25, 5, 74, 221, 254, 25, - 5, 78, 221, 254, 25, 5, 218, 46, 221, 254, 164, 229, 97, 221, 254, 224, - 144, 229, 97, 221, 254, 224, 144, 254, 227, 221, 254, 224, 144, 254, 122, - 221, 254, 224, 144, 252, 122, 221, 254, 224, 144, 253, 209, 221, 254, - 224, 144, 220, 10, 221, 254, 255, 30, 79, 221, 254, 224, 144, 231, 73, - 224, 48, 221, 254, 224, 144, 210, 31, 221, 254, 224, 144, 224, 48, 221, - 254, 224, 144, 210, 114, 221, 254, 224, 144, 215, 90, 221, 254, 224, 144, - 254, 17, 221, 254, 224, 144, 219, 55, 231, 150, 221, 254, 224, 144, 254, - 108, 231, 187, 1, 242, 31, 231, 187, 1, 255, 34, 231, 187, 1, 254, 225, - 231, 187, 1, 255, 8, 231, 187, 1, 254, 218, 231, 187, 1, 214, 124, 231, - 187, 1, 253, 168, 231, 187, 1, 235, 166, 231, 187, 1, 253, 206, 231, 187, - 1, 254, 190, 231, 187, 1, 254, 195, 231, 187, 1, 254, 187, 231, 187, 1, - 254, 144, 231, 187, 1, 254, 131, 231, 187, 1, 253, 245, 231, 187, 1, 236, - 6, 231, 187, 1, 254, 80, 231, 187, 1, 253, 216, 231, 187, 1, 254, 53, - 231, 187, 1, 254, 49, 231, 187, 1, 253, 239, 231, 187, 1, 253, 214, 231, - 187, 1, 246, 63, 231, 187, 1, 235, 8, 231, 187, 1, 254, 205, 231, 187, - 254, 231, 79, 231, 187, 213, 136, 79, 231, 187, 243, 60, 79, 231, 187, - 224, 143, 9, 1, 252, 63, 2, 4, 214, 106, 51, 9, 1, 151, 2, 113, 170, 48, - 9, 1, 217, 82, 2, 113, 170, 48, 9, 1, 244, 151, 2, 59, 252, 51, 22, 134, - 170, 48, 9, 1, 224, 85, 2, 59, 51, 9, 1, 233, 109, 2, 52, 130, 9, 1, 66, - 2, 134, 170, 48, 9, 1, 77, 2, 113, 170, 252, 51, 22, 182, 48, 9, 1, 77, - 2, 113, 170, 252, 51, 22, 59, 48, 9, 1, 223, 99, 2, 232, 129, 9, 1, 212, - 31, 2, 59, 211, 231, 9, 1, 222, 203, 211, 43, 9, 249, 107, 244, 173, 9, - 249, 107, 248, 192, 9, 249, 107, 234, 211, 9, 249, 107, 244, 171, 9, 249, - 107, 248, 190, 9, 249, 107, 234, 209, 9, 138, 123, 59, 48, 9, 138, 113, - 170, 48, 9, 138, 232, 130, 48, 9, 138, 123, 59, 51, 9, 138, 113, 170, 51, - 9, 138, 232, 130, 51, 9, 204, 244, 171, 9, 204, 248, 190, 9, 204, 234, - 209, 9, 4, 125, 212, 30, 9, 244, 174, 2, 222, 236, 9, 244, 174, 2, 59, - 48, 9, 234, 212, 2, 59, 51, 9, 43, 254, 2, 48, 9, 44, 254, 2, 48, 9, 43, - 254, 2, 51, 9, 44, 254, 2, 51, 9, 52, 44, 254, 2, 48, 9, 52, 44, 254, 2, - 72, 2, 247, 128, 9, 44, 254, 2, 72, 2, 247, 128, 9, 248, 193, 2, 247, - 128, 84, 5, 235, 200, 251, 7, 84, 5, 251, 7, 84, 5, 254, 83, 84, 5, 213, - 147, 84, 1, 219, 253, 61, 84, 1, 61, 84, 1, 255, 82, 84, 1, 74, 84, 1, - 236, 40, 84, 1, 69, 84, 1, 214, 118, 84, 1, 149, 153, 84, 1, 149, 156, - 84, 1, 251, 10, 76, 84, 1, 219, 253, 76, 84, 1, 76, 84, 1, 254, 210, 84, - 1, 251, 10, 78, 84, 1, 219, 253, 78, 84, 1, 78, 84, 1, 253, 200, 84, 1, - 176, 84, 1, 234, 138, 84, 1, 243, 142, 84, 1, 243, 0, 84, 1, 229, 82, 84, - 1, 251, 41, 84, 1, 250, 165, 84, 1, 235, 147, 84, 1, 235, 120, 84, 1, - 227, 169, 84, 1, 215, 157, 84, 1, 215, 145, 84, 1, 248, 143, 84, 1, 248, - 127, 84, 1, 228, 115, 84, 1, 217, 106, 84, 1, 216, 209, 84, 1, 248, 229, - 84, 1, 248, 33, 84, 1, 198, 84, 1, 228, 97, 84, 1, 191, 84, 1, 225, 150, - 84, 1, 252, 199, 84, 1, 252, 26, 84, 1, 186, 84, 1, 192, 84, 1, 205, 84, - 1, 222, 181, 84, 1, 233, 141, 84, 1, 232, 190, 84, 1, 232, 181, 84, 1, - 214, 27, 84, 1, 220, 104, 84, 1, 218, 225, 84, 1, 206, 84, 1, 162, 84, - 25, 5, 226, 238, 84, 25, 5, 226, 185, 84, 5, 227, 209, 84, 5, 253, 183, - 84, 25, 5, 255, 82, 84, 25, 5, 74, 84, 25, 5, 236, 40, 84, 25, 5, 69, 84, - 25, 5, 214, 118, 84, 25, 5, 149, 153, 84, 25, 5, 149, 222, 182, 84, 25, - 5, 251, 10, 76, 84, 25, 5, 219, 253, 76, 84, 25, 5, 76, 84, 25, 5, 254, - 210, 84, 25, 5, 251, 10, 78, 84, 25, 5, 219, 253, 78, 84, 25, 5, 78, 84, - 25, 5, 253, 200, 84, 5, 213, 152, 84, 25, 5, 224, 188, 76, 84, 25, 5, - 253, 179, 84, 226, 208, 84, 218, 113, 5, 214, 216, 84, 218, 113, 5, 254, - 85, 84, 242, 144, 255, 23, 84, 255, 12, 255, 23, 84, 25, 5, 251, 10, 200, - 76, 84, 25, 5, 214, 214, 84, 25, 5, 214, 117, 84, 1, 224, 91, 84, 1, 234, - 121, 84, 1, 242, 233, 84, 1, 210, 116, 84, 1, 248, 132, 84, 1, 223, 42, - 84, 1, 244, 204, 84, 1, 210, 168, 84, 1, 149, 222, 182, 84, 1, 149, 232, - 191, 84, 25, 5, 149, 156, 84, 25, 5, 149, 232, 191, 84, 248, 186, 84, 52, - 248, 186, 84, 21, 210, 86, 84, 21, 111, 84, 21, 105, 84, 21, 158, 84, 21, - 161, 84, 21, 190, 84, 21, 195, 84, 21, 199, 84, 21, 196, 84, 21, 201, 84, - 255, 30, 50, 84, 5, 125, 219, 19, 247, 128, 84, 1, 251, 10, 61, 84, 1, - 226, 238, 84, 1, 226, 185, 84, 1, 253, 179, 84, 1, 214, 214, 84, 1, 214, - 117, 84, 1, 210, 82, 84, 1, 114, 192, 84, 1, 243, 36, 84, 1, 235, 102, - 84, 1, 242, 187, 218, 131, 84, 1, 248, 133, 84, 1, 252, 119, 146, 5, 251, - 7, 146, 5, 254, 83, 146, 5, 213, 147, 146, 1, 61, 146, 1, 255, 82, 146, - 1, 74, 146, 1, 236, 40, 146, 1, 69, 146, 1, 214, 118, 146, 1, 149, 153, - 146, 1, 149, 156, 146, 1, 76, 146, 1, 254, 210, 146, 1, 78, 146, 1, 253, - 200, 146, 1, 176, 146, 1, 234, 138, 146, 1, 243, 142, 146, 1, 243, 0, - 146, 1, 229, 82, 146, 1, 251, 41, 146, 1, 250, 165, 146, 1, 235, 147, - 146, 1, 235, 120, 146, 1, 227, 169, 146, 1, 215, 157, 146, 1, 215, 145, - 146, 1, 248, 143, 146, 1, 248, 127, 146, 1, 228, 115, 146, 1, 217, 106, - 146, 1, 216, 209, 146, 1, 248, 229, 146, 1, 248, 33, 146, 1, 198, 146, 1, - 191, 146, 1, 225, 150, 146, 1, 252, 199, 146, 1, 252, 26, 146, 1, 186, - 146, 1, 192, 146, 1, 205, 146, 1, 233, 141, 146, 1, 220, 104, 146, 1, - 218, 225, 146, 1, 206, 146, 1, 162, 146, 5, 227, 209, 146, 5, 253, 183, - 146, 25, 5, 255, 82, 146, 25, 5, 74, 146, 25, 5, 236, 40, 146, 25, 5, 69, - 146, 25, 5, 214, 118, 146, 25, 5, 149, 153, 146, 25, 5, 149, 222, 182, - 146, 25, 5, 76, 146, 25, 5, 254, 210, 146, 25, 5, 78, 146, 25, 5, 253, - 200, 146, 5, 213, 152, 146, 1, 234, 130, 217, 106, 146, 253, 201, 233, - 29, 79, 146, 1, 222, 181, 146, 1, 223, 42, 146, 1, 210, 168, 146, 1, 149, - 222, 182, 146, 1, 149, 232, 191, 146, 25, 5, 149, 156, 146, 25, 5, 149, - 232, 191, 146, 21, 210, 86, 146, 21, 111, 146, 21, 105, 146, 21, 158, - 146, 21, 161, 146, 21, 190, 146, 21, 195, 146, 21, 199, 146, 21, 196, - 146, 21, 201, 146, 1, 223, 191, 2, 230, 229, 248, 6, 146, 1, 223, 191, 2, - 232, 114, 248, 6, 146, 222, 120, 79, 146, 222, 120, 50, 146, 249, 106, - 227, 201, 111, 146, 249, 106, 227, 201, 105, 146, 249, 106, 227, 201, - 158, 146, 249, 106, 227, 201, 161, 146, 249, 106, 227, 201, 123, 233, 22, - 216, 202, 216, 197, 248, 56, 146, 249, 106, 248, 57, 219, 121, 146, 235, - 167, 146, 243, 110, 79, 185, 5, 255, 7, 251, 251, 185, 5, 251, 251, 185, - 5, 213, 147, 185, 1, 61, 185, 1, 255, 82, 185, 1, 74, 185, 1, 236, 40, - 185, 1, 69, 185, 1, 214, 118, 185, 1, 245, 217, 185, 1, 254, 210, 185, 1, - 226, 187, 185, 1, 253, 200, 185, 1, 176, 185, 1, 234, 138, 185, 1, 243, - 142, 185, 1, 243, 0, 185, 1, 229, 82, 185, 1, 251, 41, 185, 1, 250, 165, - 185, 1, 235, 147, 185, 1, 235, 120, 185, 1, 227, 169, 185, 1, 215, 157, - 185, 1, 215, 145, 185, 1, 248, 143, 185, 1, 248, 127, 185, 1, 228, 115, - 185, 1, 217, 106, 185, 1, 216, 209, 185, 1, 248, 229, 185, 1, 248, 33, - 185, 1, 198, 185, 1, 191, 185, 1, 225, 150, 185, 1, 252, 199, 185, 1, - 252, 26, 185, 1, 186, 185, 1, 192, 185, 1, 205, 185, 1, 233, 141, 185, 1, - 232, 190, 185, 1, 214, 27, 185, 1, 220, 104, 185, 1, 206, 185, 1, 162, - 185, 5, 227, 209, 185, 25, 5, 255, 82, 185, 25, 5, 74, 185, 25, 5, 236, - 40, 185, 25, 5, 69, 185, 25, 5, 214, 118, 185, 25, 5, 245, 217, 185, 25, - 5, 254, 210, 185, 25, 5, 226, 187, 185, 25, 5, 253, 200, 185, 5, 213, - 152, 185, 5, 214, 218, 185, 1, 234, 121, 185, 1, 242, 233, 185, 1, 210, - 116, 185, 1, 222, 181, 185, 1, 244, 204, 185, 21, 210, 86, 185, 21, 111, - 185, 21, 105, 185, 21, 158, 185, 21, 161, 185, 21, 190, 185, 21, 195, - 185, 21, 199, 185, 21, 196, 185, 21, 201, 185, 216, 75, 185, 255, 6, 185, - 235, 185, 185, 214, 146, 185, 245, 189, 226, 192, 185, 5, 211, 78, 171, - 5, 251, 7, 171, 5, 254, 83, 171, 5, 213, 147, 171, 1, 61, 171, 1, 255, - 82, 171, 1, 74, 171, 1, 236, 40, 171, 1, 69, 171, 1, 214, 118, 171, 1, - 149, 153, 171, 1, 149, 156, 171, 25, 251, 10, 76, 171, 1, 76, 171, 1, - 254, 210, 171, 25, 251, 10, 78, 171, 1, 78, 171, 1, 253, 200, 171, 1, - 176, 171, 1, 234, 138, 171, 1, 243, 142, 171, 1, 243, 0, 171, 1, 229, 82, - 171, 1, 251, 41, 171, 1, 250, 165, 171, 1, 235, 147, 171, 1, 235, 120, - 171, 1, 227, 169, 171, 1, 215, 157, 171, 1, 215, 145, 171, 1, 248, 143, - 171, 1, 248, 127, 171, 1, 228, 115, 171, 1, 217, 106, 171, 1, 216, 209, - 171, 1, 248, 229, 171, 1, 248, 33, 171, 1, 198, 171, 1, 191, 171, 1, 225, - 150, 171, 1, 252, 199, 171, 1, 252, 26, 171, 1, 186, 171, 1, 192, 171, 1, - 205, 171, 1, 233, 141, 171, 1, 232, 190, 171, 1, 214, 27, 171, 1, 220, - 104, 171, 1, 218, 225, 171, 1, 206, 171, 1, 162, 171, 5, 227, 209, 171, - 5, 253, 183, 171, 25, 5, 255, 82, 171, 25, 5, 74, 171, 25, 5, 236, 40, - 171, 25, 5, 69, 171, 25, 5, 214, 118, 171, 25, 5, 149, 153, 171, 25, 5, - 149, 222, 182, 171, 25, 5, 251, 10, 76, 171, 25, 5, 76, 171, 25, 5, 254, - 210, 171, 25, 5, 251, 10, 78, 171, 25, 5, 78, 171, 25, 5, 253, 200, 171, - 5, 213, 152, 171, 226, 208, 171, 1, 149, 222, 182, 171, 1, 149, 232, 191, - 171, 25, 5, 149, 156, 171, 25, 5, 149, 232, 191, 171, 21, 210, 86, 171, - 21, 111, 171, 21, 105, 171, 21, 158, 171, 21, 161, 171, 21, 190, 171, 21, - 195, 171, 21, 199, 171, 21, 196, 171, 21, 201, 171, 255, 30, 50, 171, - 222, 120, 50, 157, 5, 251, 7, 157, 5, 254, 83, 157, 5, 213, 147, 157, 1, - 61, 157, 1, 255, 82, 157, 1, 74, 157, 1, 236, 40, 157, 1, 69, 157, 1, - 214, 118, 157, 1, 149, 153, 157, 1, 149, 156, 157, 1, 76, 157, 1, 254, - 210, 157, 1, 78, 157, 1, 253, 200, 157, 1, 176, 157, 1, 234, 138, 157, 1, - 243, 142, 157, 1, 243, 0, 157, 1, 229, 82, 157, 1, 251, 41, 157, 1, 250, - 165, 157, 1, 235, 147, 157, 1, 235, 120, 157, 1, 227, 169, 157, 1, 215, - 157, 157, 1, 215, 145, 157, 1, 248, 143, 157, 1, 248, 127, 157, 1, 228, - 115, 157, 1, 217, 106, 157, 1, 216, 209, 157, 1, 248, 229, 157, 1, 248, - 33, 157, 1, 198, 157, 1, 191, 157, 1, 225, 150, 157, 1, 252, 199, 157, 1, - 252, 26, 157, 1, 186, 157, 1, 192, 157, 1, 205, 157, 1, 233, 141, 157, 1, - 232, 190, 157, 1, 214, 27, 157, 1, 220, 104, 157, 1, 218, 225, 157, 1, - 206, 157, 1, 162, 157, 5, 227, 209, 157, 5, 253, 183, 157, 25, 5, 255, - 82, 157, 25, 5, 74, 157, 25, 5, 236, 40, 157, 25, 5, 69, 157, 25, 5, 214, - 118, 157, 25, 5, 149, 153, 157, 25, 5, 149, 222, 182, 157, 25, 5, 76, - 157, 25, 5, 254, 210, 157, 25, 5, 78, 157, 25, 5, 253, 200, 157, 5, 213, - 152, 157, 254, 211, 233, 29, 79, 157, 253, 201, 233, 29, 79, 157, 1, 222, - 181, 157, 1, 223, 42, 157, 1, 210, 168, 157, 1, 149, 222, 182, 157, 1, - 149, 232, 191, 157, 25, 5, 149, 156, 157, 25, 5, 149, 232, 191, 157, 21, - 210, 86, 157, 21, 111, 157, 21, 105, 157, 21, 158, 157, 21, 161, 157, 21, - 190, 157, 21, 195, 157, 21, 199, 157, 21, 196, 157, 21, 201, 157, 235, - 167, 157, 1, 212, 65, 157, 244, 10, 123, 224, 24, 157, 244, 10, 123, 242, - 34, 157, 244, 10, 134, 224, 22, 157, 244, 10, 123, 219, 119, 157, 244, - 10, 123, 245, 196, 157, 244, 10, 134, 219, 118, 36, 5, 254, 83, 36, 5, - 213, 147, 36, 1, 61, 36, 1, 255, 82, 36, 1, 74, 36, 1, 236, 40, 36, 1, - 69, 36, 1, 214, 118, 36, 1, 76, 36, 1, 245, 217, 36, 1, 254, 210, 36, 1, - 78, 36, 1, 226, 187, 36, 1, 253, 200, 36, 1, 176, 36, 1, 229, 82, 36, 1, - 251, 41, 36, 1, 235, 147, 36, 1, 227, 169, 36, 1, 215, 157, 36, 1, 228, - 115, 36, 1, 217, 106, 36, 1, 198, 36, 1, 228, 97, 36, 1, 191, 36, 1, 186, - 36, 1, 192, 36, 1, 205, 36, 1, 222, 181, 36, 1, 233, 141, 36, 1, 232, - 190, 36, 1, 232, 181, 36, 1, 214, 27, 36, 1, 220, 104, 36, 1, 218, 225, - 36, 1, 206, 36, 1, 162, 36, 25, 5, 255, 82, 36, 25, 5, 74, 36, 25, 5, - 236, 40, 36, 25, 5, 69, 36, 25, 5, 214, 118, 36, 25, 5, 76, 36, 25, 5, - 245, 217, 36, 25, 5, 254, 210, 36, 25, 5, 78, 36, 25, 5, 226, 187, 36, - 25, 5, 253, 200, 36, 5, 213, 152, 36, 226, 208, 36, 253, 201, 233, 29, - 79, 36, 21, 210, 86, 36, 21, 111, 36, 21, 105, 36, 21, 158, 36, 21, 161, - 36, 21, 190, 36, 21, 195, 36, 21, 199, 36, 21, 196, 36, 21, 201, 36, 54, - 216, 248, 36, 54, 123, 240, 217, 36, 54, 123, 216, 148, 36, 248, 154, 50, - 36, 230, 140, 50, 36, 211, 45, 50, 36, 248, 95, 50, 36, 249, 147, 50, 36, - 253, 246, 72, 50, 36, 222, 120, 50, 36, 54, 50, 148, 5, 251, 7, 148, 5, - 254, 83, 148, 5, 213, 147, 148, 1, 61, 148, 1, 255, 82, 148, 1, 74, 148, - 1, 236, 40, 148, 1, 69, 148, 1, 214, 118, 148, 1, 149, 153, 148, 1, 149, - 156, 148, 1, 76, 148, 1, 245, 217, 148, 1, 254, 210, 148, 1, 78, 148, 1, - 226, 187, 148, 1, 253, 200, 148, 1, 176, 148, 1, 234, 138, 148, 1, 243, - 142, 148, 1, 243, 0, 148, 1, 229, 82, 148, 1, 251, 41, 148, 1, 250, 165, - 148, 1, 235, 147, 148, 1, 235, 120, 148, 1, 227, 169, 148, 1, 215, 157, - 148, 1, 215, 145, 148, 1, 248, 143, 148, 1, 248, 127, 148, 1, 228, 115, - 148, 1, 217, 106, 148, 1, 216, 209, 148, 1, 248, 229, 148, 1, 248, 33, - 148, 1, 198, 148, 1, 191, 148, 1, 225, 150, 148, 1, 252, 199, 148, 1, - 252, 26, 148, 1, 186, 148, 1, 192, 148, 1, 205, 148, 1, 222, 181, 148, 1, - 233, 141, 148, 1, 232, 190, 148, 1, 214, 27, 148, 1, 220, 104, 148, 1, - 218, 225, 148, 1, 206, 148, 1, 162, 148, 5, 253, 183, 148, 25, 5, 255, - 82, 148, 25, 5, 74, 148, 25, 5, 236, 40, 148, 25, 5, 69, 148, 25, 5, 214, - 118, 148, 25, 5, 149, 153, 148, 25, 5, 149, 222, 182, 148, 25, 5, 76, - 148, 25, 5, 245, 217, 148, 25, 5, 254, 210, 148, 25, 5, 78, 148, 25, 5, - 226, 187, 148, 25, 5, 253, 200, 148, 5, 213, 152, 148, 233, 29, 79, 148, - 254, 211, 233, 29, 79, 148, 1, 215, 184, 148, 1, 246, 46, 148, 1, 149, - 222, 182, 148, 1, 149, 232, 191, 148, 25, 5, 149, 156, 148, 25, 5, 149, - 232, 191, 148, 21, 210, 86, 148, 21, 111, 148, 21, 105, 148, 21, 158, - 148, 21, 161, 148, 21, 190, 148, 21, 195, 148, 21, 199, 148, 21, 196, - 148, 21, 201, 148, 244, 10, 21, 210, 87, 31, 226, 241, 224, 226, 64, 161, - 148, 244, 10, 21, 123, 31, 226, 241, 224, 226, 64, 161, 148, 244, 10, 21, - 113, 31, 226, 241, 224, 226, 64, 161, 148, 244, 10, 21, 134, 31, 226, - 241, 224, 226, 64, 161, 148, 244, 10, 21, 123, 31, 245, 50, 224, 226, 64, - 161, 148, 244, 10, 21, 113, 31, 245, 50, 224, 226, 64, 161, 148, 244, 10, - 21, 134, 31, 245, 50, 224, 226, 64, 161, 148, 5, 215, 84, 165, 5, 254, - 83, 165, 5, 213, 147, 165, 1, 61, 165, 1, 255, 82, 165, 1, 74, 165, 1, - 236, 40, 165, 1, 69, 165, 1, 214, 118, 165, 1, 149, 153, 165, 1, 149, - 156, 165, 1, 76, 165, 1, 245, 217, 165, 1, 254, 210, 165, 1, 78, 165, 1, - 226, 187, 165, 1, 253, 200, 165, 1, 176, 165, 1, 234, 138, 165, 1, 243, - 142, 165, 1, 243, 0, 165, 1, 229, 82, 165, 1, 251, 41, 165, 1, 250, 165, - 165, 1, 235, 147, 165, 1, 235, 120, 165, 1, 227, 169, 165, 1, 215, 157, - 165, 1, 215, 145, 165, 1, 248, 143, 165, 1, 248, 127, 165, 1, 228, 115, - 165, 1, 217, 106, 165, 1, 216, 209, 165, 1, 248, 229, 165, 1, 248, 33, - 165, 1, 198, 165, 1, 191, 165, 1, 225, 150, 165, 1, 252, 199, 165, 1, - 252, 26, 165, 1, 186, 165, 1, 192, 165, 1, 205, 165, 1, 222, 181, 165, 1, - 233, 141, 165, 1, 232, 190, 165, 1, 214, 27, 165, 1, 220, 104, 165, 1, - 218, 225, 165, 1, 206, 165, 1, 162, 165, 5, 227, 209, 165, 5, 253, 183, - 165, 25, 5, 255, 82, 165, 25, 5, 74, 165, 25, 5, 236, 40, 165, 25, 5, 69, - 165, 25, 5, 214, 118, 165, 25, 5, 149, 153, 165, 25, 5, 149, 222, 182, - 165, 25, 5, 76, 165, 25, 5, 245, 217, 165, 25, 5, 254, 210, 165, 25, 5, - 78, 165, 25, 5, 226, 187, 165, 25, 5, 253, 200, 165, 5, 213, 152, 165, - 233, 29, 79, 165, 254, 211, 233, 29, 79, 165, 1, 244, 204, 165, 1, 149, - 222, 182, 165, 1, 149, 232, 191, 165, 25, 5, 149, 156, 165, 25, 5, 149, - 232, 191, 165, 21, 210, 86, 165, 21, 111, 165, 21, 105, 165, 21, 158, - 165, 21, 161, 165, 21, 190, 165, 21, 195, 165, 21, 199, 165, 21, 196, - 165, 21, 201, 165, 5, 235, 108, 165, 5, 214, 161, 136, 5, 254, 83, 136, - 5, 213, 147, 136, 1, 61, 136, 1, 255, 82, 136, 1, 74, 136, 1, 236, 40, - 136, 1, 69, 136, 1, 214, 118, 136, 1, 149, 153, 136, 1, 149, 156, 136, 1, - 76, 136, 1, 245, 217, 136, 1, 254, 210, 136, 1, 78, 136, 1, 226, 187, - 136, 1, 253, 200, 136, 1, 176, 136, 1, 234, 138, 136, 1, 243, 142, 136, - 1, 243, 0, 136, 1, 229, 82, 136, 1, 251, 41, 136, 1, 250, 165, 136, 1, - 235, 147, 136, 1, 235, 120, 136, 1, 227, 169, 136, 1, 215, 157, 136, 1, - 215, 145, 136, 1, 248, 143, 136, 1, 248, 127, 136, 1, 228, 115, 136, 1, - 217, 106, 136, 1, 216, 209, 136, 1, 248, 229, 136, 1, 248, 33, 136, 1, - 198, 136, 1, 228, 97, 136, 1, 191, 136, 1, 225, 150, 136, 1, 252, 199, - 136, 1, 252, 26, 136, 1, 186, 136, 1, 192, 136, 1, 205, 136, 1, 222, 181, - 136, 1, 233, 141, 136, 1, 232, 190, 136, 1, 232, 181, 136, 1, 214, 27, - 136, 1, 220, 104, 136, 1, 218, 225, 136, 1, 206, 136, 1, 162, 136, 1, - 215, 126, 136, 5, 253, 183, 136, 25, 5, 255, 82, 136, 25, 5, 74, 136, 25, - 5, 236, 40, 136, 25, 5, 69, 136, 25, 5, 214, 118, 136, 25, 5, 149, 153, - 136, 25, 5, 149, 222, 182, 136, 25, 5, 76, 136, 25, 5, 245, 217, 136, 25, - 5, 254, 210, 136, 25, 5, 78, 136, 25, 5, 226, 187, 136, 25, 5, 253, 200, - 136, 5, 213, 152, 136, 1, 59, 223, 76, 136, 253, 201, 233, 29, 79, 136, - 1, 149, 222, 182, 136, 1, 149, 232, 191, 136, 25, 5, 149, 156, 136, 25, - 5, 149, 232, 191, 136, 21, 210, 86, 136, 21, 111, 136, 21, 105, 136, 21, - 158, 136, 21, 161, 136, 21, 190, 136, 21, 195, 136, 21, 199, 136, 21, - 196, 136, 21, 201, 136, 54, 216, 248, 136, 54, 123, 240, 217, 136, 54, - 123, 216, 148, 136, 244, 10, 123, 224, 24, 136, 244, 10, 123, 242, 34, - 136, 244, 10, 134, 224, 22, 136, 248, 158, 79, 136, 1, 250, 107, 228, - 116, 136, 1, 250, 107, 230, 30, 136, 1, 250, 107, 222, 182, 136, 1, 250, - 107, 156, 136, 1, 250, 107, 232, 191, 136, 1, 250, 107, 235, 29, 175, 5, - 254, 82, 175, 5, 213, 146, 175, 1, 253, 173, 175, 1, 255, 36, 175, 1, - 254, 232, 175, 1, 254, 247, 175, 1, 235, 157, 175, 1, 236, 39, 175, 1, - 214, 110, 175, 1, 214, 112, 175, 1, 235, 180, 175, 1, 235, 181, 175, 1, - 236, 25, 175, 1, 236, 27, 175, 1, 245, 25, 175, 1, 245, 212, 175, 1, 254, - 197, 175, 1, 226, 112, 175, 1, 226, 181, 175, 1, 253, 186, 175, 1, 254, - 154, 234, 193, 175, 1, 231, 214, 234, 193, 175, 1, 254, 154, 243, 89, - 175, 1, 231, 214, 243, 89, 175, 1, 234, 235, 229, 227, 175, 1, 221, 238, - 243, 89, 175, 1, 254, 154, 250, 224, 175, 1, 231, 214, 250, 224, 175, 1, - 254, 154, 235, 133, 175, 1, 231, 214, 235, 133, 175, 1, 217, 99, 229, - 227, 175, 1, 217, 99, 221, 237, 229, 228, 175, 1, 221, 238, 235, 133, - 175, 1, 254, 154, 215, 153, 175, 1, 231, 214, 215, 153, 175, 1, 254, 154, - 248, 134, 175, 1, 231, 214, 248, 134, 175, 1, 230, 58, 229, 185, 175, 1, - 221, 238, 248, 134, 175, 1, 254, 154, 217, 31, 175, 1, 231, 214, 217, 31, - 175, 1, 254, 154, 248, 152, 175, 1, 231, 214, 248, 152, 175, 1, 248, 182, - 229, 185, 175, 1, 221, 238, 248, 152, 175, 1, 254, 154, 225, 232, 175, 1, - 231, 214, 225, 232, 175, 1, 254, 154, 252, 120, 175, 1, 231, 214, 252, - 120, 175, 1, 231, 136, 175, 1, 254, 139, 252, 120, 175, 1, 211, 51, 175, - 1, 223, 136, 175, 1, 248, 182, 233, 73, 175, 1, 214, 1, 175, 1, 217, 99, - 221, 212, 175, 1, 230, 58, 221, 212, 175, 1, 248, 182, 221, 212, 175, 1, - 241, 249, 175, 1, 230, 58, 233, 73, 175, 1, 244, 164, 175, 5, 254, 186, - 175, 25, 5, 254, 242, 175, 25, 5, 234, 161, 254, 249, 175, 25, 5, 247, - 236, 254, 249, 175, 25, 5, 234, 161, 235, 177, 175, 25, 5, 247, 236, 235, - 177, 175, 25, 5, 234, 161, 226, 92, 175, 25, 5, 247, 236, 226, 92, 175, - 25, 5, 243, 131, 175, 25, 5, 234, 21, 175, 25, 5, 247, 236, 234, 21, 175, - 25, 5, 234, 23, 248, 75, 175, 25, 5, 234, 22, 242, 54, 254, 242, 175, 25, - 5, 234, 22, 242, 54, 247, 236, 254, 242, 175, 25, 5, 234, 22, 242, 54, - 243, 88, 175, 25, 5, 243, 88, 175, 25, 5, 247, 236, 243, 131, 175, 25, 5, - 247, 236, 243, 88, 175, 224, 144, 233, 213, 168, 135, 234, 35, 234, 252, - 168, 135, 234, 112, 234, 134, 168, 135, 234, 112, 234, 105, 168, 135, - 234, 112, 234, 101, 168, 135, 234, 112, 234, 109, 168, 135, 234, 112, - 223, 157, 168, 135, 229, 10, 228, 253, 168, 135, 250, 95, 250, 155, 168, - 135, 250, 95, 250, 103, 168, 135, 250, 95, 250, 154, 168, 135, 219, 61, - 219, 60, 168, 135, 250, 95, 250, 91, 168, 135, 210, 245, 210, 252, 168, - 135, 247, 154, 250, 162, 168, 135, 216, 43, 225, 242, 168, 135, 216, 158, - 216, 201, 168, 135, 216, 158, 229, 206, 168, 135, 216, 158, 225, 114, - 168, 135, 228, 80, 229, 103, 168, 135, 247, 154, 248, 76, 168, 135, 216, - 43, 217, 56, 168, 135, 216, 158, 216, 132, 168, 135, 216, 158, 216, 205, - 168, 135, 216, 158, 216, 155, 168, 135, 228, 80, 227, 242, 168, 135, 251, - 214, 252, 172, 168, 135, 225, 20, 225, 45, 168, 135, 225, 125, 225, 116, - 168, 135, 244, 52, 244, 204, 168, 135, 225, 125, 225, 144, 168, 135, 244, - 52, 244, 181, 168, 135, 225, 125, 221, 249, 168, 135, 230, 167, 186, 168, - 135, 210, 245, 211, 79, 168, 135, 222, 214, 222, 141, 168, 135, 222, 142, - 168, 135, 232, 163, 232, 212, 168, 135, 232, 103, 168, 135, 211, 228, - 212, 61, 168, 135, 219, 61, 222, 8, 168, 135, 219, 61, 222, 116, 168, - 135, 219, 61, 218, 83, 168, 135, 241, 76, 241, 166, 168, 135, 232, 163, - 250, 76, 168, 135, 144, 254, 123, 168, 135, 241, 76, 228, 75, 168, 135, - 226, 72, 168, 135, 221, 232, 61, 168, 135, 231, 209, 242, 24, 168, 135, - 221, 232, 255, 82, 168, 135, 221, 232, 254, 144, 168, 135, 221, 232, 74, - 168, 135, 221, 232, 236, 40, 168, 135, 221, 232, 214, 214, 168, 135, 221, - 232, 214, 212, 168, 135, 221, 232, 69, 168, 135, 221, 232, 214, 118, 168, - 135, 225, 127, 168, 249, 106, 16, 252, 173, 168, 135, 221, 232, 76, 168, - 135, 221, 232, 254, 252, 168, 135, 221, 232, 78, 168, 135, 221, 232, 254, - 211, 231, 203, 168, 135, 221, 232, 254, 211, 231, 204, 168, 135, 233, - 112, 168, 135, 231, 200, 168, 135, 231, 201, 168, 135, 231, 209, 245, - 188, 168, 135, 231, 209, 216, 157, 168, 135, 231, 209, 215, 229, 168, - 135, 231, 209, 250, 143, 168, 135, 216, 199, 168, 135, 228, 210, 168, - 135, 211, 73, 168, 135, 244, 43, 168, 21, 210, 86, 168, 21, 111, 168, 21, - 105, 168, 21, 158, 168, 21, 161, 168, 21, 190, 168, 21, 195, 168, 21, - 199, 168, 21, 196, 168, 21, 201, 168, 135, 254, 119, 168, 135, 234, 110, - 209, 209, 1, 234, 34, 209, 209, 1, 234, 112, 218, 36, 209, 209, 1, 234, - 112, 217, 63, 209, 209, 1, 229, 9, 209, 209, 1, 249, 246, 209, 209, 1, - 219, 61, 217, 63, 209, 209, 1, 227, 138, 209, 209, 1, 247, 153, 209, 209, - 1, 112, 209, 209, 1, 216, 158, 218, 36, 209, 209, 1, 216, 158, 217, 63, - 209, 209, 1, 228, 79, 209, 209, 1, 251, 213, 209, 209, 1, 225, 19, 209, - 209, 1, 225, 125, 218, 36, 209, 209, 1, 244, 52, 217, 63, 209, 209, 1, - 225, 125, 217, 63, 209, 209, 1, 244, 52, 218, 36, 209, 209, 1, 230, 166, - 209, 209, 1, 210, 244, 209, 209, 1, 232, 163, 232, 212, 209, 209, 1, 232, - 163, 232, 127, 209, 209, 1, 211, 227, 209, 209, 1, 219, 61, 218, 36, 209, - 209, 1, 241, 76, 218, 36, 209, 209, 1, 78, 209, 209, 1, 241, 76, 217, 63, - 209, 209, 245, 171, 209, 209, 25, 5, 61, 209, 209, 25, 5, 231, 209, 234, - 240, 209, 209, 25, 5, 255, 82, 209, 209, 25, 5, 254, 144, 209, 209, 25, - 5, 74, 209, 209, 25, 5, 236, 40, 209, 209, 25, 5, 211, 117, 209, 209, 25, - 5, 210, 169, 209, 209, 25, 5, 69, 209, 209, 25, 5, 214, 118, 209, 209, - 25, 5, 231, 209, 234, 19, 209, 209, 220, 147, 5, 232, 162, 209, 209, 220, - 147, 5, 227, 138, 209, 209, 25, 5, 76, 209, 209, 25, 5, 245, 203, 209, - 209, 25, 5, 78, 209, 209, 25, 5, 253, 175, 209, 209, 25, 5, 254, 210, - 209, 209, 234, 35, 233, 141, 209, 209, 138, 231, 209, 245, 188, 209, 209, - 138, 231, 209, 216, 157, 209, 209, 138, 231, 209, 216, 118, 209, 209, - 138, 231, 209, 250, 231, 209, 209, 251, 12, 79, 209, 209, 228, 219, 209, - 209, 21, 210, 86, 209, 209, 21, 111, 209, 209, 21, 105, 209, 209, 21, - 158, 209, 209, 21, 161, 209, 209, 21, 190, 209, 209, 21, 195, 209, 209, - 21, 199, 209, 209, 21, 196, 209, 209, 21, 201, 209, 209, 241, 76, 228, - 79, 209, 209, 241, 76, 230, 166, 209, 209, 1, 234, 113, 242, 181, 209, - 209, 1, 234, 113, 227, 138, 63, 3, 226, 208, 63, 164, 242, 122, 211, 0, - 230, 253, 215, 190, 61, 63, 164, 242, 122, 211, 0, 230, 253, 255, 168, - 222, 218, 252, 85, 186, 63, 164, 242, 122, 211, 0, 230, 253, 255, 168, - 242, 122, 215, 174, 186, 63, 164, 65, 211, 0, 230, 253, 231, 98, 186, 63, - 164, 250, 4, 211, 0, 230, 253, 220, 111, 186, 63, 164, 250, 247, 211, 0, - 230, 253, 225, 115, 220, 98, 186, 63, 164, 211, 0, 230, 253, 215, 174, - 220, 98, 186, 63, 164, 221, 210, 220, 97, 63, 164, 251, 136, 211, 0, 230, - 252, 63, 164, 251, 231, 220, 5, 211, 0, 230, 252, 63, 164, 235, 204, 215, - 173, 63, 164, 248, 69, 215, 174, 251, 135, 63, 164, 220, 97, 63, 164, - 227, 143, 220, 97, 63, 164, 215, 174, 220, 97, 63, 164, 227, 143, 215, - 174, 220, 97, 63, 164, 222, 239, 250, 130, 218, 238, 220, 97, 63, 164, - 223, 45, 242, 153, 220, 97, 63, 164, 250, 247, 255, 172, 222, 146, 231, - 97, 200, 251, 15, 63, 164, 242, 122, 215, 173, 63, 232, 150, 5, 250, 163, - 222, 145, 63, 232, 150, 5, 233, 2, 222, 145, 63, 253, 220, 5, 220, 107, - 243, 72, 255, 173, 222, 145, 63, 253, 220, 5, 255, 170, 191, 63, 253, - 220, 5, 221, 184, 215, 169, 63, 5, 223, 133, 247, 167, 243, 71, 63, 5, - 223, 133, 247, 167, 242, 183, 63, 5, 223, 133, 247, 167, 242, 123, 63, 5, - 223, 133, 229, 224, 243, 71, 63, 5, 223, 133, 229, 224, 242, 183, 63, 5, - 223, 133, 247, 167, 223, 133, 229, 223, 63, 21, 210, 86, 63, 21, 111, 63, - 21, 105, 63, 21, 158, 63, 21, 161, 63, 21, 190, 63, 21, 195, 63, 21, 199, - 63, 21, 196, 63, 21, 201, 63, 21, 163, 111, 63, 21, 163, 105, 63, 21, - 163, 158, 63, 21, 163, 161, 63, 21, 163, 190, 63, 21, 163, 195, 63, 21, - 163, 199, 63, 21, 163, 196, 63, 21, 163, 201, 63, 21, 163, 210, 86, 63, - 164, 251, 138, 222, 145, 63, 164, 229, 73, 251, 76, 227, 153, 210, 25, - 63, 164, 250, 247, 255, 172, 222, 146, 251, 77, 230, 207, 251, 15, 63, - 164, 229, 73, 251, 76, 220, 108, 222, 145, 63, 164, 250, 140, 230, 252, - 63, 164, 215, 185, 255, 169, 63, 164, 242, 107, 222, 146, 242, 70, 63, - 164, 242, 107, 222, 146, 242, 76, 63, 164, 254, 124, 234, 129, 242, 70, - 63, 164, 254, 124, 234, 129, 242, 76, 63, 5, 211, 65, 215, 172, 63, 5, - 231, 172, 215, 172, 63, 1, 176, 63, 1, 234, 138, 63, 1, 243, 142, 63, 1, - 243, 0, 63, 1, 229, 82, 63, 1, 251, 41, 63, 1, 250, 165, 63, 1, 235, 147, - 63, 1, 227, 169, 63, 1, 215, 157, 63, 1, 215, 145, 63, 1, 248, 143, 63, - 1, 248, 127, 63, 1, 228, 115, 63, 1, 217, 106, 63, 1, 216, 209, 63, 1, - 248, 229, 63, 1, 248, 33, 63, 1, 198, 63, 1, 191, 63, 1, 225, 150, 63, 1, - 252, 199, 63, 1, 252, 26, 63, 1, 186, 63, 1, 215, 184, 63, 1, 215, 176, - 63, 1, 246, 46, 63, 1, 246, 41, 63, 1, 212, 65, 63, 1, 210, 82, 63, 1, - 210, 116, 63, 1, 255, 175, 63, 1, 192, 63, 1, 205, 63, 1, 233, 141, 63, - 1, 220, 104, 63, 1, 218, 225, 63, 1, 206, 63, 1, 162, 63, 1, 61, 63, 1, - 233, 237, 63, 1, 244, 85, 205, 63, 1, 234, 52, 63, 1, 222, 181, 63, 25, - 5, 255, 82, 63, 25, 5, 74, 63, 25, 5, 236, 40, 63, 25, 5, 69, 63, 25, 5, - 214, 118, 63, 25, 5, 149, 153, 63, 25, 5, 149, 222, 182, 63, 25, 5, 149, - 156, 63, 25, 5, 149, 232, 191, 63, 25, 5, 76, 63, 25, 5, 245, 217, 63, - 25, 5, 78, 63, 25, 5, 226, 187, 63, 5, 222, 224, 218, 85, 229, 83, 222, - 213, 63, 5, 222, 218, 252, 84, 63, 25, 5, 223, 52, 74, 63, 25, 5, 223, - 52, 236, 40, 63, 5, 227, 153, 210, 26, 229, 231, 248, 229, 63, 5, 219, - 73, 233, 66, 63, 164, 242, 36, 63, 164, 226, 61, 63, 5, 233, 69, 222, - 145, 63, 5, 211, 70, 222, 145, 63, 5, 233, 70, 215, 185, 251, 15, 63, 5, - 231, 100, 251, 15, 63, 5, 242, 126, 251, 16, 223, 43, 63, 5, 242, 126, - 231, 90, 223, 43, 63, 5, 235, 200, 231, 100, 251, 15, 63, 218, 74, 5, - 233, 70, 215, 185, 251, 15, 63, 218, 74, 5, 231, 100, 251, 15, 63, 218, - 74, 5, 235, 200, 231, 100, 251, 15, 63, 218, 74, 1, 176, 63, 218, 74, 1, - 234, 138, 63, 218, 74, 1, 243, 142, 63, 218, 74, 1, 243, 0, 63, 218, 74, - 1, 229, 82, 63, 218, 74, 1, 251, 41, 63, 218, 74, 1, 250, 165, 63, 218, - 74, 1, 235, 147, 63, 218, 74, 1, 227, 169, 63, 218, 74, 1, 215, 157, 63, - 218, 74, 1, 215, 145, 63, 218, 74, 1, 248, 143, 63, 218, 74, 1, 248, 127, - 63, 218, 74, 1, 228, 115, 63, 218, 74, 1, 217, 106, 63, 218, 74, 1, 216, - 209, 63, 218, 74, 1, 248, 229, 63, 218, 74, 1, 248, 33, 63, 218, 74, 1, - 198, 63, 218, 74, 1, 191, 63, 218, 74, 1, 225, 150, 63, 218, 74, 1, 252, - 199, 63, 218, 74, 1, 252, 26, 63, 218, 74, 1, 186, 63, 218, 74, 1, 215, - 184, 63, 218, 74, 1, 215, 176, 63, 218, 74, 1, 246, 46, 63, 218, 74, 1, - 246, 41, 63, 218, 74, 1, 212, 65, 63, 218, 74, 1, 210, 82, 63, 218, 74, - 1, 210, 116, 63, 218, 74, 1, 255, 175, 63, 218, 74, 1, 192, 63, 218, 74, - 1, 205, 63, 218, 74, 1, 233, 141, 63, 218, 74, 1, 220, 104, 63, 218, 74, - 1, 218, 225, 63, 218, 74, 1, 206, 63, 218, 74, 1, 162, 63, 218, 74, 1, - 61, 63, 218, 74, 1, 233, 237, 63, 218, 74, 1, 244, 85, 212, 65, 63, 218, - 74, 1, 244, 85, 192, 63, 218, 74, 1, 244, 85, 205, 63, 233, 224, 222, - 143, 234, 138, 63, 233, 224, 222, 143, 234, 139, 251, 77, 230, 207, 251, - 15, 63, 251, 4, 5, 114, 252, 78, 63, 251, 4, 5, 193, 252, 78, 63, 251, 4, - 5, 251, 5, 217, 21, 63, 251, 4, 5, 221, 209, 255, 174, 63, 16, 246, 99, - 251, 133, 63, 16, 223, 132, 222, 225, 63, 16, 226, 81, 243, 70, 63, 16, - 223, 132, 222, 226, 223, 45, 242, 152, 63, 16, 225, 115, 191, 63, 16, - 228, 64, 251, 133, 63, 16, 228, 64, 251, 134, 227, 143, 255, 171, 63, 16, - 228, 64, 251, 134, 242, 124, 255, 171, 63, 16, 228, 64, 251, 134, 251, - 77, 255, 171, 63, 5, 223, 133, 229, 224, 223, 133, 247, 166, 63, 5, 223, - 133, 229, 224, 242, 123, 63, 164, 251, 137, 220, 5, 242, 222, 230, 253, - 223, 44, 63, 164, 230, 168, 211, 0, 242, 222, 230, 253, 223, 44, 63, 164, - 227, 143, 215, 173, 63, 164, 65, 251, 160, 222, 215, 211, 0, 230, 253, - 231, 98, 186, 63, 164, 250, 4, 251, 160, 222, 215, 211, 0, 230, 253, 220, - 111, 186, 222, 253, 218, 0, 50, 233, 51, 218, 0, 50, 222, 253, 218, 0, 5, - 2, 247, 126, 233, 51, 218, 0, 5, 2, 247, 126, 63, 164, 233, 61, 231, 101, - 222, 145, 63, 164, 215, 251, 231, 101, 222, 145, 68, 1, 176, 68, 1, 234, - 138, 68, 1, 243, 142, 68, 1, 243, 0, 68, 1, 229, 82, 68, 1, 251, 41, 68, - 1, 250, 165, 68, 1, 235, 147, 68, 1, 235, 120, 68, 1, 227, 169, 68, 1, - 228, 81, 68, 1, 215, 157, 68, 1, 215, 145, 68, 1, 248, 143, 68, 1, 248, - 127, 68, 1, 228, 115, 68, 1, 217, 106, 68, 1, 216, 209, 68, 1, 248, 229, - 68, 1, 248, 33, 68, 1, 198, 68, 1, 191, 68, 1, 225, 150, 68, 1, 252, 199, - 68, 1, 252, 26, 68, 1, 186, 68, 1, 192, 68, 1, 205, 68, 1, 233, 141, 68, - 1, 212, 65, 68, 1, 206, 68, 1, 162, 68, 1, 232, 190, 68, 1, 61, 68, 1, - 220, 88, 61, 68, 1, 74, 68, 1, 236, 40, 68, 1, 69, 68, 1, 214, 118, 68, - 1, 76, 68, 1, 230, 156, 76, 68, 1, 78, 68, 1, 253, 200, 68, 25, 5, 217, - 65, 255, 82, 68, 25, 5, 255, 82, 68, 25, 5, 74, 68, 25, 5, 236, 40, 68, - 25, 5, 69, 68, 25, 5, 214, 118, 68, 25, 5, 76, 68, 25, 5, 254, 210, 68, - 25, 5, 230, 156, 236, 40, 68, 25, 5, 230, 156, 78, 68, 25, 5, 160, 48, - 68, 5, 254, 83, 68, 5, 59, 51, 68, 5, 213, 147, 68, 5, 213, 152, 68, 5, - 253, 243, 68, 117, 5, 147, 192, 68, 117, 5, 147, 205, 68, 117, 5, 147, - 212, 65, 68, 117, 5, 147, 162, 68, 1, 242, 139, 206, 68, 21, 210, 86, 68, - 21, 111, 68, 21, 105, 68, 21, 158, 68, 21, 161, 68, 21, 190, 68, 21, 195, - 68, 21, 199, 68, 21, 196, 68, 21, 201, 68, 5, 232, 198, 221, 174, 68, 5, - 221, 174, 68, 16, 232, 159, 68, 16, 249, 221, 68, 16, 254, 229, 68, 16, - 243, 55, 68, 1, 220, 104, 68, 1, 218, 225, 68, 1, 149, 153, 68, 1, 149, - 222, 182, 68, 1, 149, 156, 68, 1, 149, 232, 191, 68, 25, 5, 149, 153, 68, - 25, 5, 149, 222, 182, 68, 25, 5, 149, 156, 68, 25, 5, 149, 232, 191, 68, - 1, 230, 156, 229, 82, 68, 1, 230, 156, 235, 120, 68, 1, 230, 156, 252, - 119, 68, 1, 230, 156, 252, 114, 68, 117, 5, 230, 156, 147, 198, 68, 117, - 5, 230, 156, 147, 186, 68, 117, 5, 230, 156, 147, 233, 141, 68, 1, 220, - 110, 234, 219, 220, 104, 68, 25, 5, 220, 110, 234, 219, 245, 63, 68, 138, - 164, 220, 110, 234, 219, 241, 254, 68, 138, 164, 220, 110, 234, 219, 234, - 189, 225, 124, 68, 1, 212, 7, 224, 111, 234, 219, 216, 209, 68, 1, 212, - 7, 224, 111, 234, 219, 224, 117, 68, 25, 5, 212, 7, 224, 111, 234, 219, - 245, 63, 68, 25, 5, 212, 7, 224, 111, 234, 219, 214, 214, 68, 5, 212, 7, - 224, 111, 234, 219, 216, 30, 68, 5, 212, 7, 224, 111, 234, 219, 216, 29, - 68, 5, 212, 7, 224, 111, 234, 219, 216, 28, 68, 5, 212, 7, 224, 111, 234, - 219, 216, 27, 68, 5, 212, 7, 224, 111, 234, 219, 216, 26, 68, 1, 245, - 227, 224, 111, 234, 219, 228, 115, 68, 1, 245, 227, 224, 111, 234, 219, - 210, 176, 68, 1, 245, 227, 224, 111, 234, 219, 242, 224, 68, 25, 5, 243, - 66, 234, 219, 74, 68, 25, 5, 234, 194, 226, 238, 68, 25, 5, 234, 194, 69, - 68, 25, 5, 234, 194, 245, 217, 68, 1, 220, 88, 176, 68, 1, 220, 88, 234, - 138, 68, 1, 220, 88, 243, 142, 68, 1, 220, 88, 251, 41, 68, 1, 220, 88, - 210, 116, 68, 1, 220, 88, 227, 169, 68, 1, 220, 88, 248, 229, 68, 1, 220, - 88, 198, 68, 1, 220, 88, 225, 150, 68, 1, 220, 88, 244, 204, 68, 1, 220, - 88, 252, 199, 68, 1, 220, 88, 216, 209, 68, 1, 220, 88, 162, 68, 117, 5, - 220, 88, 147, 212, 65, 68, 25, 5, 220, 88, 255, 82, 68, 25, 5, 220, 88, - 76, 68, 25, 5, 220, 88, 160, 48, 68, 25, 5, 220, 88, 40, 211, 117, 68, 5, - 220, 88, 216, 29, 68, 5, 220, 88, 216, 28, 68, 5, 220, 88, 216, 26, 68, - 5, 220, 88, 216, 25, 68, 5, 220, 88, 249, 160, 216, 29, 68, 5, 220, 88, - 249, 160, 216, 28, 68, 5, 220, 88, 249, 160, 245, 161, 216, 31, 68, 1, - 222, 130, 226, 67, 244, 204, 68, 5, 222, 130, 226, 67, 216, 26, 68, 220, - 88, 21, 210, 86, 68, 220, 88, 21, 111, 68, 220, 88, 21, 105, 68, 220, 88, - 21, 158, 68, 220, 88, 21, 161, 68, 220, 88, 21, 190, 68, 220, 88, 21, - 195, 68, 220, 88, 21, 199, 68, 220, 88, 21, 196, 68, 220, 88, 21, 201, - 68, 5, 234, 132, 216, 30, 68, 5, 234, 132, 216, 28, 68, 25, 5, 254, 199, - 61, 68, 25, 5, 254, 199, 254, 210, 68, 16, 220, 88, 111, 68, 16, 220, 88, - 245, 38, 98, 6, 1, 254, 131, 98, 6, 1, 252, 160, 98, 6, 1, 243, 113, 98, - 6, 1, 247, 136, 98, 6, 1, 245, 158, 98, 6, 1, 213, 160, 98, 6, 1, 210, - 89, 98, 6, 1, 217, 61, 98, 6, 1, 236, 6, 98, 6, 1, 234, 240, 98, 6, 1, - 233, 87, 98, 6, 1, 231, 190, 98, 6, 1, 229, 200, 98, 6, 1, 226, 200, 98, - 6, 1, 226, 21, 98, 6, 1, 210, 78, 98, 6, 1, 223, 174, 98, 6, 1, 221, 245, - 98, 6, 1, 217, 51, 98, 6, 1, 214, 190, 98, 6, 1, 225, 143, 98, 6, 1, 234, - 127, 98, 6, 1, 242, 248, 98, 6, 1, 224, 76, 98, 6, 1, 220, 22, 98, 6, 1, - 250, 105, 98, 6, 1, 251, 15, 98, 6, 1, 235, 106, 98, 6, 1, 250, 48, 98, - 6, 1, 250, 151, 98, 6, 1, 211, 163, 98, 6, 1, 235, 117, 98, 6, 1, 242, - 50, 98, 6, 1, 241, 245, 98, 6, 1, 241, 182, 98, 6, 1, 212, 22, 98, 6, 1, - 242, 11, 98, 6, 1, 241, 72, 98, 6, 1, 210, 246, 98, 6, 1, 254, 241, 98, - 1, 254, 131, 98, 1, 252, 160, 98, 1, 243, 113, 98, 1, 247, 136, 98, 1, - 245, 158, 98, 1, 213, 160, 98, 1, 210, 89, 98, 1, 217, 61, 98, 1, 236, 6, - 98, 1, 234, 240, 98, 1, 233, 87, 98, 1, 231, 190, 98, 1, 229, 200, 98, 1, - 226, 200, 98, 1, 226, 21, 98, 1, 210, 78, 98, 1, 223, 174, 98, 1, 221, - 245, 98, 1, 217, 51, 98, 1, 214, 190, 98, 1, 225, 143, 98, 1, 234, 127, - 98, 1, 242, 248, 98, 1, 224, 76, 98, 1, 220, 22, 98, 1, 250, 105, 98, 1, - 251, 15, 98, 1, 235, 106, 98, 1, 250, 48, 98, 1, 250, 151, 98, 1, 211, - 163, 98, 1, 235, 117, 98, 1, 242, 50, 98, 1, 241, 245, 98, 1, 241, 182, - 98, 1, 212, 22, 98, 1, 242, 11, 98, 1, 241, 72, 98, 1, 244, 129, 98, 1, - 210, 246, 98, 1, 245, 173, 98, 1, 215, 94, 243, 113, 98, 1, 254, 205, 98, - 226, 19, 220, 139, 58, 1, 98, 229, 200, 98, 1, 254, 241, 98, 1, 242, 10, - 50, 98, 1, 233, 133, 50, 24, 100, 234, 64, 24, 100, 218, 217, 24, 100, - 228, 231, 24, 100, 216, 102, 24, 100, 218, 206, 24, 100, 223, 29, 24, - 100, 230, 222, 24, 100, 225, 98, 24, 100, 218, 214, 24, 100, 219, 150, - 24, 100, 218, 211, 24, 100, 236, 63, 24, 100, 250, 54, 24, 100, 218, 221, - 24, 100, 250, 114, 24, 100, 234, 116, 24, 100, 216, 174, 24, 100, 225, - 134, 24, 100, 241, 179, 24, 100, 228, 227, 24, 100, 218, 215, 24, 100, - 228, 221, 24, 100, 228, 225, 24, 100, 216, 99, 24, 100, 223, 17, 24, 100, - 218, 213, 24, 100, 223, 27, 24, 100, 234, 224, 24, 100, 230, 215, 24, - 100, 234, 227, 24, 100, 225, 93, 24, 100, 225, 91, 24, 100, 225, 79, 24, - 100, 225, 87, 24, 100, 225, 85, 24, 100, 225, 82, 24, 100, 225, 84, 24, - 100, 225, 81, 24, 100, 225, 86, 24, 100, 225, 96, 24, 100, 225, 97, 24, - 100, 225, 80, 24, 100, 225, 90, 24, 100, 234, 225, 24, 100, 234, 223, 24, - 100, 219, 143, 24, 100, 219, 141, 24, 100, 219, 133, 24, 100, 219, 136, - 24, 100, 219, 142, 24, 100, 219, 138, 24, 100, 219, 137, 24, 100, 219, - 135, 24, 100, 219, 146, 24, 100, 219, 148, 24, 100, 219, 149, 24, 100, - 219, 144, 24, 100, 219, 134, 24, 100, 219, 139, 24, 100, 219, 147, 24, - 100, 250, 98, 24, 100, 250, 96, 24, 100, 250, 176, 24, 100, 250, 174, 24, - 100, 226, 36, 24, 100, 236, 58, 24, 100, 236, 49, 24, 100, 236, 57, 24, - 100, 236, 54, 24, 100, 236, 52, 24, 100, 236, 56, 24, 100, 218, 218, 24, - 100, 236, 61, 24, 100, 236, 62, 24, 100, 236, 50, 24, 100, 236, 55, 24, - 100, 211, 26, 24, 100, 250, 53, 24, 100, 250, 99, 24, 100, 250, 97, 24, - 100, 250, 177, 24, 100, 250, 175, 24, 100, 250, 112, 24, 100, 250, 113, - 24, 100, 250, 100, 24, 100, 250, 178, 24, 100, 225, 132, 24, 100, 234, - 226, 24, 100, 218, 219, 24, 100, 211, 32, 24, 100, 234, 55, 24, 100, 228, - 223, 24, 100, 228, 229, 24, 100, 228, 228, 24, 100, 216, 96, 24, 100, - 244, 111, 24, 143, 244, 111, 24, 143, 61, 24, 143, 254, 252, 24, 143, - 192, 24, 143, 211, 92, 24, 143, 245, 125, 24, 143, 76, 24, 143, 211, 36, - 24, 143, 211, 47, 24, 143, 78, 24, 143, 212, 65, 24, 143, 212, 62, 24, - 143, 226, 238, 24, 143, 210, 244, 24, 143, 69, 24, 143, 212, 11, 24, 143, - 212, 22, 24, 143, 211, 250, 24, 143, 210, 212, 24, 143, 245, 63, 24, 143, - 211, 8, 24, 143, 74, 24, 143, 255, 166, 24, 143, 255, 165, 24, 143, 211, - 106, 24, 143, 211, 104, 24, 143, 245, 123, 24, 143, 245, 122, 24, 143, - 245, 124, 24, 143, 211, 35, 24, 143, 211, 34, 24, 143, 227, 88, 24, 143, - 227, 89, 24, 143, 227, 82, 24, 143, 227, 87, 24, 143, 227, 85, 24, 143, - 210, 238, 24, 143, 210, 237, 24, 143, 210, 236, 24, 143, 210, 239, 24, - 143, 210, 240, 24, 143, 215, 30, 24, 143, 215, 29, 24, 143, 215, 27, 24, - 143, 215, 24, 24, 143, 215, 25, 24, 143, 210, 211, 24, 143, 210, 208, 24, - 143, 210, 209, 24, 143, 210, 203, 24, 143, 210, 204, 24, 143, 210, 205, - 24, 143, 210, 207, 24, 143, 245, 57, 24, 143, 245, 59, 24, 143, 211, 7, - 24, 143, 240, 160, 24, 143, 240, 152, 24, 143, 240, 155, 24, 143, 240, - 153, 24, 143, 240, 157, 24, 143, 240, 159, 24, 143, 254, 42, 24, 143, - 254, 39, 24, 143, 254, 37, 24, 143, 254, 38, 24, 143, 218, 222, 24, 143, - 255, 167, 24, 143, 211, 105, 24, 143, 211, 33, 24, 143, 227, 84, 24, 143, - 227, 83, 24, 90, 234, 64, 24, 90, 218, 217, 24, 90, 234, 57, 24, 90, 228, - 231, 24, 90, 228, 229, 24, 90, 228, 228, 24, 90, 216, 102, 24, 90, 223, - 29, 24, 90, 223, 24, 24, 90, 223, 21, 24, 90, 223, 14, 24, 90, 223, 9, - 24, 90, 223, 4, 24, 90, 223, 15, 24, 90, 223, 27, 24, 90, 230, 222, 24, - 90, 225, 98, 24, 90, 225, 87, 24, 90, 219, 150, 24, 90, 218, 211, 24, 90, - 236, 63, 24, 90, 250, 54, 24, 90, 250, 114, 24, 90, 234, 116, 24, 90, - 216, 174, 24, 90, 225, 134, 24, 90, 241, 179, 24, 90, 234, 58, 24, 90, - 234, 56, 24, 90, 228, 227, 24, 90, 228, 221, 24, 90, 228, 223, 24, 90, - 228, 226, 24, 90, 228, 222, 24, 90, 216, 99, 24, 90, 216, 96, 24, 90, - 223, 22, 24, 90, 223, 17, 24, 90, 223, 3, 24, 90, 223, 2, 24, 90, 218, - 213, 24, 90, 223, 19, 24, 90, 223, 18, 24, 90, 223, 11, 24, 90, 223, 13, - 24, 90, 223, 26, 24, 90, 223, 6, 24, 90, 223, 16, 24, 90, 223, 25, 24, - 90, 223, 1, 24, 90, 230, 218, 24, 90, 230, 213, 24, 90, 230, 215, 24, 90, - 230, 212, 24, 90, 230, 210, 24, 90, 230, 216, 24, 90, 230, 221, 24, 90, - 230, 219, 24, 90, 234, 227, 24, 90, 225, 89, 24, 90, 225, 90, 24, 90, - 225, 95, 24, 90, 234, 225, 24, 90, 219, 143, 24, 90, 219, 133, 24, 90, - 219, 136, 24, 90, 219, 138, 24, 90, 226, 36, 24, 90, 236, 58, 24, 90, - 236, 51, 24, 90, 218, 218, 24, 90, 236, 59, 24, 90, 211, 26, 24, 90, 211, - 22, 24, 90, 211, 23, 24, 90, 225, 132, 24, 90, 234, 226, 24, 90, 241, - 177, 24, 90, 241, 175, 24, 90, 241, 178, 24, 90, 241, 176, 24, 90, 211, - 32, 24, 90, 234, 60, 24, 90, 234, 59, 24, 90, 234, 63, 24, 90, 234, 61, - 24, 90, 234, 62, 24, 90, 218, 215, 29, 3, 162, 29, 3, 240, 229, 29, 3, - 241, 187, 29, 3, 242, 53, 29, 3, 241, 227, 29, 3, 241, 245, 29, 3, 241, - 75, 29, 3, 241, 74, 29, 3, 233, 141, 29, 3, 232, 103, 29, 3, 232, 247, - 29, 3, 233, 140, 29, 3, 233, 56, 29, 3, 233, 64, 29, 3, 232, 162, 29, 3, - 232, 75, 29, 3, 241, 196, 29, 3, 241, 190, 29, 3, 241, 192, 29, 3, 241, - 195, 29, 3, 241, 193, 29, 3, 241, 194, 29, 3, 241, 191, 29, 3, 241, 189, - 29, 3, 186, 29, 3, 230, 107, 29, 3, 230, 235, 29, 3, 231, 242, 29, 3, - 231, 85, 29, 3, 231, 96, 29, 3, 230, 166, 29, 3, 230, 47, 29, 3, 217, - 164, 29, 3, 217, 158, 29, 3, 217, 160, 29, 3, 217, 163, 29, 3, 217, 161, - 29, 3, 217, 162, 29, 3, 217, 159, 29, 3, 217, 157, 29, 3, 205, 29, 3, - 222, 142, 29, 3, 223, 38, 29, 3, 223, 187, 29, 3, 223, 111, 29, 3, 223, - 131, 29, 3, 222, 213, 29, 3, 222, 111, 29, 3, 206, 29, 3, 218, 84, 29, 3, - 219, 193, 29, 3, 222, 33, 29, 3, 221, 172, 29, 3, 221, 183, 29, 3, 219, - 60, 29, 3, 217, 254, 29, 3, 220, 104, 29, 3, 219, 227, 29, 3, 220, 34, - 29, 3, 220, 100, 29, 3, 220, 63, 29, 3, 220, 65, 29, 3, 220, 9, 29, 3, - 219, 210, 29, 3, 224, 91, 29, 3, 224, 33, 29, 3, 224, 56, 29, 3, 224, 90, - 29, 3, 224, 71, 29, 3, 224, 72, 29, 3, 224, 45, 29, 3, 224, 44, 29, 3, - 223, 245, 29, 3, 223, 241, 29, 3, 223, 244, 29, 3, 223, 242, 29, 3, 223, - 243, 29, 3, 224, 68, 29, 3, 224, 62, 29, 3, 224, 64, 29, 3, 224, 67, 29, - 3, 224, 65, 29, 3, 224, 66, 29, 3, 224, 63, 29, 3, 224, 61, 29, 3, 224, - 57, 29, 3, 224, 60, 29, 3, 224, 58, 29, 3, 224, 59, 29, 3, 252, 199, 29, - 3, 251, 133, 29, 3, 252, 14, 29, 3, 252, 197, 29, 3, 252, 74, 29, 3, 252, - 83, 29, 3, 251, 213, 29, 3, 251, 91, 29, 3, 214, 27, 29, 3, 212, 116, 29, - 3, 213, 176, 29, 3, 214, 26, 29, 3, 213, 250, 29, 3, 213, 255, 29, 3, - 213, 138, 29, 3, 212, 107, 29, 3, 217, 106, 29, 3, 215, 119, 29, 3, 216, - 118, 29, 3, 217, 102, 29, 3, 217, 12, 29, 3, 217, 23, 29, 3, 112, 29, 3, - 215, 80, 29, 3, 251, 41, 29, 3, 249, 120, 29, 3, 250, 59, 29, 3, 251, 40, - 29, 3, 250, 190, 29, 3, 250, 198, 29, 3, 249, 246, 29, 3, 249, 89, 29, 3, - 211, 165, 29, 3, 211, 141, 29, 3, 211, 157, 29, 3, 211, 164, 29, 3, 211, - 161, 29, 3, 211, 162, 29, 3, 211, 148, 29, 3, 211, 147, 29, 3, 211, 136, - 29, 3, 211, 132, 29, 3, 211, 135, 29, 3, 211, 133, 29, 3, 211, 134, 29, - 3, 198, 29, 3, 227, 242, 29, 3, 228, 238, 29, 3, 229, 230, 29, 3, 229, - 108, 29, 3, 229, 112, 29, 3, 228, 79, 29, 3, 227, 178, 29, 3, 227, 169, - 29, 3, 227, 132, 29, 3, 227, 152, 29, 3, 227, 168, 29, 3, 227, 159, 29, - 3, 227, 160, 29, 3, 227, 138, 29, 3, 227, 123, 29, 3, 242, 187, 61, 29, - 3, 242, 187, 69, 29, 3, 242, 187, 74, 29, 3, 242, 187, 255, 82, 29, 3, - 242, 187, 245, 217, 29, 3, 242, 187, 76, 29, 3, 242, 187, 78, 29, 3, 242, - 187, 212, 65, 29, 3, 176, 29, 3, 233, 223, 29, 3, 234, 98, 29, 3, 235, - 16, 29, 3, 234, 187, 29, 3, 234, 188, 29, 3, 234, 34, 29, 3, 234, 33, 29, - 3, 233, 188, 29, 3, 233, 182, 29, 3, 233, 187, 29, 3, 233, 183, 29, 3, - 233, 184, 29, 3, 233, 177, 29, 3, 233, 171, 29, 3, 233, 173, 29, 3, 233, - 176, 29, 3, 233, 174, 29, 3, 233, 175, 29, 3, 233, 172, 29, 3, 233, 170, - 29, 3, 233, 166, 29, 3, 233, 169, 29, 3, 233, 167, 29, 3, 233, 168, 29, - 3, 212, 65, 29, 3, 211, 195, 29, 3, 211, 250, 29, 3, 212, 64, 29, 3, 212, - 17, 29, 3, 212, 22, 29, 3, 211, 227, 29, 3, 211, 226, 29, 3, 225, 142, - 61, 29, 3, 225, 142, 69, 29, 3, 225, 142, 74, 29, 3, 225, 142, 255, 82, - 29, 3, 225, 142, 245, 217, 29, 3, 225, 142, 76, 29, 3, 225, 142, 78, 29, - 3, 210, 116, 29, 3, 210, 13, 29, 3, 210, 44, 29, 3, 210, 115, 29, 3, 210, - 92, 29, 3, 210, 94, 29, 3, 210, 23, 29, 3, 210, 0, 29, 3, 210, 82, 29, 3, - 210, 62, 29, 3, 210, 69, 29, 3, 210, 81, 29, 3, 210, 73, 29, 3, 210, 74, - 29, 3, 210, 67, 29, 3, 210, 53, 29, 3, 192, 29, 3, 210, 212, 29, 3, 211, - 8, 29, 3, 211, 103, 29, 3, 211, 44, 29, 3, 211, 47, 29, 3, 210, 244, 29, - 3, 210, 235, 29, 3, 248, 229, 29, 3, 246, 86, 29, 3, 248, 11, 29, 3, 248, - 228, 29, 3, 248, 85, 29, 3, 248, 98, 29, 3, 247, 153, 29, 3, 246, 55, 29, - 3, 248, 143, 29, 3, 248, 108, 29, 3, 248, 120, 29, 3, 248, 142, 29, 3, - 248, 130, 29, 3, 248, 131, 29, 3, 248, 113, 29, 3, 248, 99, 29, 3, 235, - 147, 29, 3, 235, 57, 29, 3, 235, 114, 29, 3, 235, 146, 29, 3, 235, 130, - 29, 3, 235, 132, 29, 3, 235, 74, 29, 3, 235, 37, 29, 3, 243, 142, 29, 3, - 242, 120, 29, 3, 242, 221, 29, 3, 243, 139, 29, 3, 243, 62, 29, 3, 243, - 69, 29, 3, 242, 181, 29, 3, 242, 180, 29, 3, 242, 85, 29, 3, 242, 81, 29, - 3, 242, 84, 29, 3, 242, 82, 29, 3, 242, 83, 29, 3, 243, 36, 29, 3, 243, - 16, 29, 3, 243, 26, 29, 3, 243, 35, 29, 3, 243, 30, 29, 3, 243, 31, 29, - 3, 243, 20, 29, 3, 243, 5, 29, 3, 216, 209, 29, 3, 216, 137, 29, 3, 216, - 176, 29, 3, 216, 208, 29, 3, 216, 195, 29, 3, 216, 196, 29, 3, 216, 157, - 29, 3, 216, 129, 29, 3, 250, 165, 29, 3, 250, 77, 29, 3, 250, 118, 29, 3, - 250, 164, 29, 3, 250, 136, 29, 3, 250, 139, 29, 3, 250, 94, 29, 3, 250, - 66, 29, 3, 225, 150, 29, 3, 225, 117, 29, 3, 225, 136, 29, 3, 225, 149, - 29, 3, 225, 138, 29, 3, 225, 139, 29, 3, 225, 124, 29, 3, 225, 113, 29, - 3, 215, 184, 29, 3, 215, 164, 29, 3, 215, 168, 29, 3, 215, 183, 29, 3, - 215, 178, 29, 3, 215, 179, 29, 3, 215, 167, 29, 3, 215, 162, 29, 3, 215, - 39, 29, 3, 215, 31, 29, 3, 215, 35, 29, 3, 215, 38, 29, 3, 215, 36, 29, - 3, 215, 37, 29, 3, 215, 33, 29, 3, 215, 32, 29, 3, 244, 204, 29, 3, 243, - 241, 29, 3, 244, 129, 29, 3, 244, 203, 29, 3, 244, 155, 29, 3, 244, 162, - 29, 3, 244, 51, 29, 3, 243, 220, 29, 3, 191, 29, 3, 224, 153, 29, 3, 225, - 111, 29, 3, 226, 93, 29, 3, 225, 214, 29, 3, 225, 224, 29, 3, 225, 19, - 29, 3, 224, 117, 29, 3, 222, 101, 29, 3, 230, 36, 29, 3, 243, 214, 29, - 38, 243, 60, 22, 25, 233, 29, 79, 29, 38, 25, 233, 29, 79, 29, 38, 243, - 60, 79, 29, 221, 175, 79, 29, 211, 208, 29, 243, 236, 218, 131, 29, 249, - 227, 29, 220, 152, 29, 249, 234, 29, 224, 202, 249, 234, 29, 224, 16, 79, - 29, 226, 19, 220, 139, 29, 21, 111, 29, 21, 105, 29, 21, 158, 29, 21, - 161, 29, 21, 190, 29, 21, 195, 29, 21, 199, 29, 21, 196, 29, 21, 201, 29, - 54, 216, 248, 29, 54, 215, 73, 29, 54, 216, 163, 29, 54, 244, 23, 29, 54, - 244, 122, 29, 54, 219, 113, 29, 54, 220, 118, 29, 54, 245, 192, 29, 54, - 228, 200, 29, 54, 240, 217, 29, 54, 216, 249, 216, 148, 29, 3, 221, 179, - 230, 47, 29, 3, 230, 43, 29, 3, 230, 44, 29, 3, 230, 45, 29, 3, 221, 179, - 251, 91, 29, 3, 251, 88, 29, 3, 251, 89, 29, 3, 251, 90, 29, 3, 221, 179, - 243, 220, 29, 3, 243, 216, 29, 3, 243, 217, 29, 3, 243, 218, 29, 3, 221, - 179, 224, 117, 29, 3, 224, 113, 29, 3, 224, 114, 29, 3, 224, 115, 29, - 216, 32, 164, 210, 247, 29, 216, 32, 164, 248, 49, 29, 216, 32, 164, 222, - 241, 29, 216, 32, 164, 219, 253, 222, 241, 29, 216, 32, 164, 247, 243, - 29, 216, 32, 164, 234, 170, 29, 216, 32, 164, 250, 102, 29, 216, 32, 164, - 241, 184, 29, 216, 32, 164, 248, 48, 29, 216, 32, 164, 233, 200, 169, 1, - 61, 169, 1, 76, 169, 1, 74, 169, 1, 78, 169, 1, 69, 169, 1, 214, 105, - 169, 1, 243, 142, 169, 1, 176, 169, 1, 243, 69, 169, 1, 242, 221, 169, 1, - 242, 181, 169, 1, 242, 120, 169, 1, 242, 86, 169, 1, 162, 169, 1, 241, - 245, 169, 1, 241, 187, 169, 1, 241, 75, 169, 1, 240, 229, 169, 1, 240, - 208, 169, 1, 233, 141, 169, 1, 233, 64, 169, 1, 232, 247, 169, 1, 232, - 162, 169, 1, 232, 103, 169, 1, 232, 76, 169, 1, 186, 169, 1, 231, 96, - 169, 1, 230, 235, 169, 1, 230, 166, 169, 1, 230, 107, 169, 1, 198, 169, - 1, 241, 97, 169, 1, 229, 218, 169, 1, 229, 112, 169, 1, 228, 238, 169, 1, - 228, 79, 169, 1, 227, 242, 169, 1, 227, 180, 169, 1, 224, 32, 169, 1, - 224, 19, 169, 1, 224, 12, 169, 1, 224, 4, 169, 1, 223, 249, 169, 1, 223, - 247, 169, 1, 206, 169, 1, 222, 93, 169, 1, 221, 183, 169, 1, 219, 193, - 169, 1, 219, 60, 169, 1, 218, 84, 169, 1, 218, 3, 169, 1, 248, 229, 169, - 1, 217, 106, 169, 1, 248, 98, 169, 1, 217, 23, 169, 1, 248, 11, 169, 1, - 216, 118, 169, 1, 247, 153, 169, 1, 246, 86, 169, 1, 246, 58, 169, 1, - 247, 164, 169, 1, 216, 60, 169, 1, 216, 59, 169, 1, 216, 48, 169, 1, 216, - 47, 169, 1, 216, 46, 169, 1, 216, 45, 169, 1, 215, 184, 169, 1, 215, 179, - 169, 1, 215, 168, 169, 1, 215, 167, 169, 1, 215, 164, 169, 1, 215, 163, - 169, 1, 212, 65, 169, 1, 212, 22, 169, 1, 211, 250, 169, 1, 211, 227, - 169, 1, 211, 195, 169, 1, 211, 183, 169, 1, 192, 169, 1, 211, 47, 169, 1, - 211, 8, 169, 1, 210, 244, 169, 1, 210, 212, 169, 1, 210, 177, 18, 19, - 240, 175, 18, 19, 76, 18, 19, 255, 46, 18, 19, 74, 18, 19, 236, 40, 18, - 19, 78, 18, 19, 226, 187, 18, 19, 211, 116, 226, 187, 18, 19, 73, 245, - 217, 18, 19, 73, 74, 18, 19, 61, 18, 19, 255, 82, 18, 19, 212, 22, 18, - 19, 159, 212, 22, 18, 19, 211, 250, 18, 19, 159, 211, 250, 18, 19, 211, - 242, 18, 19, 159, 211, 242, 18, 19, 211, 227, 18, 19, 159, 211, 227, 18, - 19, 211, 215, 18, 19, 159, 211, 215, 18, 19, 229, 195, 211, 215, 18, 19, - 212, 65, 18, 19, 159, 212, 65, 18, 19, 212, 64, 18, 19, 159, 212, 64, 18, - 19, 229, 195, 212, 64, 18, 19, 254, 210, 18, 19, 211, 116, 212, 98, 18, - 19, 242, 187, 218, 131, 18, 19, 40, 142, 18, 19, 40, 242, 143, 18, 19, - 40, 251, 183, 163, 222, 236, 18, 19, 40, 216, 15, 163, 222, 236, 18, 19, - 40, 44, 163, 222, 236, 18, 19, 40, 222, 236, 18, 19, 40, 52, 142, 18, 19, - 40, 52, 219, 253, 67, 218, 92, 18, 19, 40, 230, 229, 247, 128, 18, 19, - 40, 219, 253, 203, 91, 18, 19, 40, 225, 25, 18, 19, 40, 124, 217, 88, 18, - 19, 245, 158, 18, 19, 236, 6, 18, 19, 226, 200, 18, 19, 254, 131, 18, 19, - 225, 224, 18, 19, 226, 91, 18, 19, 225, 111, 18, 19, 225, 74, 18, 19, - 225, 19, 18, 19, 224, 252, 18, 19, 211, 116, 224, 252, 18, 19, 73, 241, - 227, 18, 19, 73, 241, 187, 18, 19, 191, 18, 19, 226, 93, 18, 19, 224, - 115, 18, 19, 159, 224, 115, 18, 19, 224, 113, 18, 19, 159, 224, 113, 18, - 19, 224, 112, 18, 19, 159, 224, 112, 18, 19, 224, 110, 18, 19, 159, 224, - 110, 18, 19, 224, 109, 18, 19, 159, 224, 109, 18, 19, 224, 117, 18, 19, - 159, 224, 117, 18, 19, 224, 116, 18, 19, 159, 224, 116, 18, 19, 211, 116, - 224, 116, 18, 19, 226, 109, 18, 19, 159, 226, 109, 18, 19, 73, 242, 67, - 18, 19, 217, 23, 18, 19, 217, 100, 18, 19, 216, 118, 18, 19, 216, 104, - 18, 19, 112, 18, 19, 216, 18, 18, 19, 211, 116, 216, 18, 18, 19, 73, 248, - 85, 18, 19, 73, 248, 11, 18, 19, 217, 106, 18, 19, 217, 102, 18, 19, 215, - 78, 18, 19, 159, 215, 78, 18, 19, 215, 62, 18, 19, 159, 215, 62, 18, 19, - 215, 61, 18, 19, 159, 215, 61, 18, 19, 105, 18, 19, 159, 105, 18, 19, - 215, 54, 18, 19, 159, 215, 54, 18, 19, 215, 80, 18, 19, 159, 215, 80, 18, - 19, 215, 79, 18, 19, 159, 215, 79, 18, 19, 229, 195, 215, 79, 18, 19, - 217, 153, 18, 19, 215, 152, 18, 19, 215, 136, 18, 19, 215, 134, 18, 19, - 215, 157, 18, 19, 234, 188, 18, 19, 235, 13, 18, 19, 234, 98, 18, 19, - 234, 89, 18, 19, 234, 34, 18, 19, 234, 16, 18, 19, 211, 116, 234, 16, 18, - 19, 176, 18, 19, 235, 16, 18, 19, 233, 184, 18, 19, 159, 233, 184, 18, - 19, 233, 182, 18, 19, 159, 233, 182, 18, 19, 233, 181, 18, 19, 159, 233, - 181, 18, 19, 233, 180, 18, 19, 159, 233, 180, 18, 19, 233, 179, 18, 19, - 159, 233, 179, 18, 19, 233, 188, 18, 19, 159, 233, 188, 18, 19, 233, 187, - 18, 19, 159, 233, 187, 18, 19, 229, 195, 233, 187, 18, 19, 235, 29, 18, - 19, 233, 189, 18, 19, 219, 29, 234, 182, 18, 19, 219, 29, 234, 90, 18, - 19, 219, 29, 234, 29, 18, 19, 219, 29, 234, 254, 18, 19, 250, 198, 18, - 19, 251, 39, 18, 19, 250, 59, 18, 19, 250, 49, 18, 19, 249, 246, 18, 19, - 249, 182, 18, 19, 211, 116, 249, 182, 18, 19, 251, 41, 18, 19, 251, 40, - 18, 19, 249, 87, 18, 19, 159, 249, 87, 18, 19, 249, 85, 18, 19, 159, 249, - 85, 18, 19, 249, 84, 18, 19, 159, 249, 84, 18, 19, 249, 83, 18, 19, 159, - 249, 83, 18, 19, 249, 82, 18, 19, 159, 249, 82, 18, 19, 249, 89, 18, 19, - 159, 249, 89, 18, 19, 249, 88, 18, 19, 159, 249, 88, 18, 19, 229, 195, - 249, 88, 18, 19, 251, 74, 18, 19, 221, 211, 216, 211, 18, 19, 231, 96, - 18, 19, 231, 241, 18, 19, 230, 235, 18, 19, 230, 206, 18, 19, 230, 166, - 18, 19, 230, 137, 18, 19, 211, 116, 230, 137, 18, 19, 186, 18, 19, 231, - 242, 18, 19, 230, 45, 18, 19, 159, 230, 45, 18, 19, 230, 43, 18, 19, 159, - 230, 43, 18, 19, 230, 42, 18, 19, 159, 230, 42, 18, 19, 230, 41, 18, 19, - 159, 230, 41, 18, 19, 230, 40, 18, 19, 159, 230, 40, 18, 19, 230, 47, 18, - 19, 159, 230, 47, 18, 19, 230, 46, 18, 19, 159, 230, 46, 18, 19, 229, - 195, 230, 46, 18, 19, 194, 18, 19, 159, 194, 18, 19, 230, 239, 18, 19, - 253, 213, 194, 18, 19, 221, 211, 194, 18, 19, 229, 112, 18, 19, 229, 229, - 18, 19, 228, 238, 18, 19, 228, 213, 18, 19, 228, 79, 18, 19, 228, 69, 18, - 19, 211, 116, 228, 69, 18, 19, 198, 18, 19, 229, 230, 18, 19, 227, 176, - 18, 19, 159, 227, 176, 18, 19, 227, 178, 18, 19, 159, 227, 178, 18, 19, - 227, 177, 18, 19, 159, 227, 177, 18, 19, 229, 195, 227, 177, 18, 19, 230, - 30, 18, 19, 73, 229, 84, 18, 19, 228, 243, 18, 19, 233, 64, 18, 19, 233, - 139, 18, 19, 232, 247, 18, 19, 232, 233, 18, 19, 232, 162, 18, 19, 232, - 133, 18, 19, 211, 116, 232, 133, 18, 19, 233, 141, 18, 19, 233, 140, 18, - 19, 232, 73, 18, 19, 159, 232, 73, 18, 19, 232, 72, 18, 19, 159, 232, 72, - 18, 19, 232, 71, 18, 19, 159, 232, 71, 18, 19, 232, 70, 18, 19, 159, 232, - 70, 18, 19, 232, 69, 18, 19, 159, 232, 69, 18, 19, 232, 75, 18, 19, 159, - 232, 75, 18, 19, 232, 74, 18, 19, 159, 232, 74, 18, 19, 156, 18, 19, 159, - 156, 18, 19, 147, 156, 18, 19, 221, 183, 18, 19, 222, 31, 18, 19, 219, - 193, 18, 19, 219, 177, 18, 19, 219, 60, 18, 19, 219, 42, 18, 19, 211, - 116, 219, 42, 18, 19, 206, 18, 19, 222, 33, 18, 19, 217, 250, 18, 19, - 159, 217, 250, 18, 19, 217, 244, 18, 19, 159, 217, 244, 18, 19, 217, 243, - 18, 19, 159, 217, 243, 18, 19, 217, 239, 18, 19, 159, 217, 239, 18, 19, - 217, 238, 18, 19, 159, 217, 238, 18, 19, 217, 254, 18, 19, 159, 217, 254, - 18, 19, 217, 253, 18, 19, 159, 217, 253, 18, 19, 229, 195, 217, 253, 18, - 19, 222, 93, 18, 19, 253, 213, 222, 93, 18, 19, 217, 255, 18, 19, 251, - 226, 222, 93, 18, 19, 230, 132, 219, 110, 18, 19, 229, 195, 219, 101, 18, - 19, 229, 195, 222, 91, 18, 19, 229, 195, 218, 237, 18, 19, 229, 195, 218, - 87, 18, 19, 229, 195, 219, 100, 18, 19, 229, 195, 221, 186, 18, 19, 220, - 65, 18, 19, 220, 34, 18, 19, 220, 29, 18, 19, 220, 9, 18, 19, 220, 3, 18, - 19, 220, 104, 18, 19, 220, 100, 18, 19, 219, 208, 18, 19, 159, 219, 208, - 18, 19, 219, 207, 18, 19, 159, 219, 207, 18, 19, 219, 206, 18, 19, 159, - 219, 206, 18, 19, 219, 205, 18, 19, 159, 219, 205, 18, 19, 219, 204, 18, - 19, 159, 219, 204, 18, 19, 219, 210, 18, 19, 159, 219, 210, 18, 19, 219, - 209, 18, 19, 159, 219, 209, 18, 19, 220, 106, 18, 19, 211, 47, 18, 19, - 211, 101, 18, 19, 211, 8, 18, 19, 210, 255, 18, 19, 210, 244, 18, 19, - 210, 229, 18, 19, 211, 116, 210, 229, 18, 19, 192, 18, 19, 211, 103, 18, - 19, 210, 174, 18, 19, 159, 210, 174, 18, 19, 210, 173, 18, 19, 159, 210, - 173, 18, 19, 210, 172, 18, 19, 159, 210, 172, 18, 19, 210, 171, 18, 19, - 159, 210, 171, 18, 19, 210, 170, 18, 19, 159, 210, 170, 18, 19, 210, 176, - 18, 19, 159, 210, 176, 18, 19, 210, 175, 18, 19, 159, 210, 175, 18, 19, - 229, 195, 210, 175, 18, 19, 211, 117, 18, 19, 252, 12, 211, 117, 18, 19, - 159, 211, 117, 18, 19, 221, 211, 211, 8, 18, 19, 223, 131, 18, 19, 223, - 226, 223, 131, 18, 19, 159, 233, 64, 18, 19, 223, 186, 18, 19, 223, 38, - 18, 19, 222, 242, 18, 19, 222, 213, 18, 19, 222, 199, 18, 19, 159, 232, - 162, 18, 19, 205, 18, 19, 223, 187, 18, 19, 159, 233, 141, 18, 19, 222, - 110, 18, 19, 159, 222, 110, 18, 19, 153, 18, 19, 159, 153, 18, 19, 147, - 153, 18, 19, 244, 162, 18, 19, 244, 201, 18, 19, 244, 129, 18, 19, 244, - 116, 18, 19, 244, 51, 18, 19, 244, 42, 18, 19, 244, 204, 18, 19, 244, - 203, 18, 19, 243, 219, 18, 19, 159, 243, 219, 18, 19, 245, 14, 18, 19, - 216, 196, 18, 19, 230, 28, 216, 196, 18, 19, 216, 176, 18, 19, 230, 28, - 216, 176, 18, 19, 216, 172, 18, 19, 230, 28, 216, 172, 18, 19, 216, 157, - 18, 19, 216, 154, 18, 19, 216, 209, 18, 19, 216, 208, 18, 19, 216, 128, - 18, 19, 159, 216, 128, 18, 19, 216, 211, 18, 19, 215, 143, 18, 19, 215, - 141, 18, 19, 215, 140, 18, 19, 215, 145, 18, 19, 215, 146, 18, 19, 215, - 52, 18, 19, 215, 51, 18, 19, 215, 50, 18, 19, 215, 53, 18, 19, 227, 197, - 241, 245, 18, 19, 227, 197, 241, 187, 18, 19, 227, 197, 241, 168, 18, 19, - 227, 197, 241, 75, 18, 19, 227, 197, 241, 60, 18, 19, 227, 197, 162, 18, - 19, 227, 197, 242, 53, 18, 19, 227, 197, 242, 67, 18, 19, 227, 196, 242, - 67, 18, 19, 241, 161, 18, 19, 224, 87, 18, 19, 224, 56, 18, 19, 224, 51, - 18, 19, 224, 45, 18, 19, 224, 40, 18, 19, 224, 91, 18, 19, 224, 90, 18, - 19, 224, 99, 18, 19, 216, 56, 18, 19, 216, 54, 18, 19, 216, 53, 18, 19, - 216, 57, 18, 19, 159, 223, 131, 18, 19, 159, 223, 38, 18, 19, 159, 222, - 213, 18, 19, 159, 205, 18, 19, 229, 80, 18, 19, 229, 32, 18, 19, 229, 28, - 18, 19, 229, 9, 18, 19, 229, 4, 18, 19, 229, 82, 18, 19, 229, 81, 18, 19, - 229, 84, 18, 19, 228, 108, 18, 19, 221, 211, 220, 65, 18, 19, 221, 211, - 220, 34, 18, 19, 221, 211, 220, 9, 18, 19, 221, 211, 220, 104, 18, 19, - 211, 213, 216, 196, 18, 19, 211, 213, 216, 176, 18, 19, 211, 213, 216, - 157, 18, 19, 211, 213, 216, 209, 18, 19, 211, 213, 216, 211, 18, 19, 232, - 254, 18, 19, 232, 253, 18, 19, 232, 252, 18, 19, 232, 251, 18, 19, 233, - 4, 18, 19, 233, 3, 18, 19, 233, 5, 18, 19, 216, 210, 216, 196, 18, 19, - 216, 210, 216, 176, 18, 19, 216, 210, 216, 172, 18, 19, 216, 210, 216, - 157, 18, 19, 216, 210, 216, 154, 18, 19, 216, 210, 216, 209, 18, 19, 216, - 210, 216, 208, 18, 19, 216, 210, 216, 211, 18, 19, 254, 198, 253, 166, - 18, 19, 251, 226, 76, 18, 19, 251, 226, 74, 18, 19, 251, 226, 78, 18, 19, - 251, 226, 61, 18, 19, 251, 226, 212, 22, 18, 19, 251, 226, 211, 250, 18, - 19, 251, 226, 211, 227, 18, 19, 251, 226, 212, 65, 18, 19, 251, 226, 229, - 112, 18, 19, 251, 226, 228, 238, 18, 19, 251, 226, 228, 79, 18, 19, 251, - 226, 198, 18, 19, 251, 226, 234, 188, 18, 19, 251, 226, 234, 98, 18, 19, - 251, 226, 234, 34, 18, 19, 251, 226, 176, 18, 19, 221, 211, 241, 245, 18, - 19, 221, 211, 241, 187, 18, 19, 221, 211, 241, 75, 18, 19, 221, 211, 162, - 18, 19, 73, 242, 227, 18, 19, 73, 242, 231, 18, 19, 73, 242, 243, 18, 19, - 73, 242, 242, 18, 19, 73, 242, 232, 18, 19, 73, 243, 0, 18, 19, 73, 222, - 142, 18, 19, 73, 222, 213, 18, 19, 73, 223, 131, 18, 19, 73, 223, 111, - 18, 19, 73, 223, 38, 18, 19, 73, 205, 18, 19, 73, 211, 195, 18, 19, 73, - 211, 227, 18, 19, 73, 212, 22, 18, 19, 73, 212, 17, 18, 19, 73, 211, 250, - 18, 19, 73, 212, 65, 18, 19, 73, 240, 201, 18, 19, 73, 240, 202, 18, 19, - 73, 240, 205, 18, 19, 73, 240, 204, 18, 19, 73, 240, 203, 18, 19, 73, - 240, 207, 18, 19, 73, 216, 137, 18, 19, 73, 216, 157, 18, 19, 73, 216, - 196, 18, 19, 73, 216, 195, 18, 19, 73, 216, 176, 18, 19, 73, 216, 209, - 18, 19, 73, 215, 124, 18, 19, 73, 215, 134, 18, 19, 73, 215, 152, 18, 19, - 73, 215, 151, 18, 19, 73, 215, 136, 18, 19, 73, 215, 157, 18, 19, 73, - 224, 153, 18, 19, 73, 225, 19, 18, 19, 73, 225, 224, 18, 19, 73, 225, - 214, 18, 19, 73, 225, 111, 18, 19, 73, 191, 18, 19, 73, 226, 109, 18, 19, - 73, 242, 120, 18, 19, 73, 242, 181, 18, 19, 73, 243, 69, 18, 19, 73, 243, - 62, 18, 19, 73, 242, 221, 18, 19, 73, 243, 142, 18, 19, 73, 234, 106, 18, - 19, 73, 234, 111, 18, 19, 73, 234, 125, 18, 19, 73, 234, 124, 18, 19, 73, - 234, 118, 18, 19, 73, 234, 138, 18, 19, 73, 234, 47, 18, 19, 73, 234, 48, - 18, 19, 73, 234, 51, 18, 19, 73, 234, 50, 18, 19, 73, 234, 49, 18, 19, - 73, 234, 52, 18, 19, 73, 234, 53, 18, 19, 73, 227, 242, 18, 19, 73, 228, - 79, 18, 19, 73, 229, 112, 18, 19, 73, 229, 108, 18, 19, 73, 228, 238, 18, - 19, 73, 198, 18, 19, 73, 230, 107, 18, 19, 73, 230, 166, 18, 19, 73, 231, - 96, 18, 19, 73, 231, 85, 18, 19, 73, 230, 235, 18, 19, 73, 186, 18, 19, - 73, 210, 212, 18, 19, 73, 210, 244, 18, 19, 73, 211, 47, 18, 19, 73, 211, - 44, 18, 19, 73, 211, 8, 18, 19, 73, 192, 18, 19, 73, 235, 57, 18, 19, - 221, 211, 235, 57, 18, 19, 73, 235, 74, 18, 19, 73, 235, 132, 18, 19, 73, - 235, 130, 18, 19, 73, 235, 114, 18, 19, 221, 211, 235, 114, 18, 19, 73, - 235, 147, 18, 19, 73, 235, 87, 18, 19, 73, 235, 91, 18, 19, 73, 235, 101, - 18, 19, 73, 235, 100, 18, 19, 73, 235, 99, 18, 19, 73, 235, 102, 18, 19, - 73, 232, 103, 18, 19, 73, 232, 162, 18, 19, 73, 233, 64, 18, 19, 73, 233, - 56, 18, 19, 73, 232, 247, 18, 19, 73, 233, 141, 18, 19, 73, 247, 157, 18, - 19, 73, 247, 158, 18, 19, 73, 247, 163, 18, 19, 73, 247, 162, 18, 19, 73, - 247, 159, 18, 19, 73, 247, 164, 18, 19, 73, 232, 250, 18, 19, 73, 232, - 252, 18, 19, 73, 233, 0, 18, 19, 73, 232, 255, 18, 19, 73, 232, 254, 18, - 19, 73, 233, 4, 18, 19, 73, 216, 51, 18, 19, 73, 216, 53, 18, 19, 73, - 216, 56, 18, 19, 73, 216, 55, 18, 19, 73, 216, 54, 18, 19, 73, 216, 57, - 18, 19, 73, 216, 46, 18, 19, 73, 216, 47, 18, 19, 73, 216, 59, 18, 19, - 73, 216, 58, 18, 19, 73, 216, 48, 18, 19, 73, 216, 60, 18, 19, 73, 210, - 13, 18, 19, 73, 210, 23, 18, 19, 73, 210, 94, 18, 19, 73, 210, 92, 18, - 19, 73, 210, 44, 18, 19, 73, 210, 116, 18, 19, 73, 210, 159, 18, 19, 73, - 65, 210, 159, 18, 19, 73, 246, 36, 18, 19, 73, 246, 37, 18, 19, 73, 246, - 44, 18, 19, 73, 246, 43, 18, 19, 73, 246, 39, 18, 19, 73, 246, 46, 18, - 19, 73, 218, 84, 18, 19, 73, 219, 60, 18, 19, 73, 221, 183, 18, 19, 73, - 221, 172, 18, 19, 73, 219, 193, 18, 19, 73, 206, 18, 19, 73, 219, 227, - 18, 19, 73, 220, 9, 18, 19, 73, 220, 65, 18, 19, 73, 220, 63, 18, 19, 73, - 220, 34, 18, 19, 73, 220, 104, 18, 19, 73, 220, 106, 18, 19, 73, 215, - 164, 18, 19, 73, 215, 167, 18, 19, 73, 215, 179, 18, 19, 73, 215, 178, - 18, 19, 73, 215, 168, 18, 19, 73, 215, 184, 18, 19, 73, 250, 77, 18, 19, - 73, 250, 94, 18, 19, 73, 250, 139, 18, 19, 73, 250, 136, 18, 19, 73, 250, - 118, 18, 19, 73, 250, 165, 18, 19, 73, 215, 127, 18, 19, 73, 215, 128, - 18, 19, 73, 215, 131, 18, 19, 73, 215, 130, 18, 19, 73, 215, 129, 18, 19, - 73, 215, 132, 18, 19, 250, 119, 50, 18, 19, 243, 236, 218, 131, 18, 19, - 224, 83, 18, 19, 229, 78, 18, 19, 228, 105, 18, 19, 228, 104, 18, 19, - 228, 103, 18, 19, 228, 102, 18, 19, 228, 107, 18, 19, 228, 106, 18, 19, - 211, 213, 216, 126, 18, 19, 211, 213, 216, 125, 18, 19, 211, 213, 216, - 124, 18, 19, 211, 213, 216, 123, 18, 19, 211, 213, 216, 122, 18, 19, 211, - 213, 216, 129, 18, 19, 211, 213, 216, 128, 18, 19, 211, 213, 40, 216, - 211, 18, 19, 251, 226, 212, 98, 226, 230, 219, 21, 79, 226, 230, 1, 252, - 56, 226, 230, 1, 232, 92, 226, 230, 1, 244, 159, 226, 230, 1, 222, 17, - 226, 230, 1, 228, 198, 226, 230, 1, 214, 226, 226, 230, 1, 248, 205, 226, - 230, 1, 216, 81, 226, 230, 1, 249, 237, 226, 230, 1, 250, 188, 226, 230, - 1, 230, 96, 226, 230, 1, 242, 163, 226, 230, 1, 229, 68, 226, 230, 1, - 218, 124, 226, 230, 1, 222, 137, 226, 230, 1, 254, 207, 226, 230, 1, 226, - 191, 226, 230, 1, 214, 150, 226, 230, 1, 245, 239, 226, 230, 1, 235, 195, - 226, 230, 1, 245, 240, 226, 230, 1, 226, 162, 226, 230, 1, 214, 206, 226, - 230, 1, 236, 46, 226, 230, 1, 245, 237, 226, 230, 1, 225, 205, 226, 230, - 244, 158, 79, 226, 230, 223, 52, 244, 158, 79, 178, 1, 244, 149, 244, - 141, 244, 163, 245, 14, 178, 1, 214, 105, 178, 1, 214, 135, 214, 151, 69, - 178, 1, 210, 214, 178, 1, 211, 117, 178, 1, 212, 98, 178, 1, 216, 131, - 216, 130, 216, 152, 178, 1, 245, 67, 178, 1, 254, 101, 61, 178, 1, 226, - 147, 78, 178, 1, 255, 26, 61, 178, 1, 254, 236, 178, 1, 232, 139, 78, - 178, 1, 219, 246, 78, 178, 1, 78, 178, 1, 226, 238, 178, 1, 226, 200, - 178, 1, 223, 167, 223, 180, 223, 97, 153, 178, 1, 234, 199, 178, 1, 250, - 185, 178, 1, 234, 200, 235, 29, 178, 1, 243, 209, 178, 1, 245, 146, 178, - 1, 243, 65, 242, 73, 243, 209, 178, 1, 243, 103, 178, 1, 211, 188, 211, - 182, 212, 98, 178, 1, 242, 45, 242, 67, 178, 1, 242, 49, 242, 67, 178, 1, - 232, 141, 242, 67, 178, 1, 219, 249, 242, 67, 178, 1, 229, 190, 227, 161, - 229, 191, 230, 30, 178, 1, 219, 247, 230, 30, 178, 1, 246, 123, 178, 1, - 235, 175, 235, 179, 235, 168, 74, 178, 1, 76, 178, 1, 235, 123, 235, 150, - 178, 1, 243, 50, 178, 1, 232, 142, 254, 252, 178, 1, 219, 251, 61, 178, - 1, 235, 160, 245, 121, 178, 1, 225, 167, 225, 189, 226, 109, 178, 1, 254, - 172, 245, 119, 178, 1, 219, 26, 222, 93, 178, 1, 219, 181, 232, 138, 222, - 93, 178, 1, 219, 245, 222, 93, 178, 1, 251, 74, 178, 1, 210, 159, 178, 1, - 216, 64, 216, 74, 215, 41, 217, 153, 178, 1, 219, 244, 217, 153, 178, 1, - 249, 68, 178, 1, 252, 39, 252, 42, 251, 232, 253, 166, 178, 1, 219, 250, - 253, 166, 178, 1, 246, 122, 178, 1, 226, 175, 178, 1, 245, 204, 245, 206, - 76, 178, 1, 231, 183, 231, 191, 194, 178, 1, 232, 140, 194, 178, 1, 219, - 248, 194, 178, 1, 233, 79, 233, 120, 232, 149, 156, 178, 1, 246, 124, - 178, 1, 235, 237, 178, 1, 235, 238, 178, 1, 248, 218, 248, 223, 249, 68, - 178, 1, 226, 142, 245, 66, 78, 178, 1, 245, 235, 178, 1, 235, 194, 178, - 1, 249, 86, 178, 1, 251, 25, 178, 1, 250, 197, 178, 1, 218, 163, 178, 1, - 232, 137, 178, 1, 219, 243, 178, 1, 240, 117, 178, 1, 224, 99, 178, 1, - 211, 178, 178, 219, 157, 224, 143, 178, 230, 90, 224, 143, 178, 249, 139, - 224, 143, 178, 254, 14, 87, 178, 215, 82, 87, 178, 252, 54, 87, 217, 84, - 1, 61, 217, 84, 1, 74, 217, 84, 1, 69, 217, 84, 1, 176, 217, 84, 1, 243, - 142, 217, 84, 1, 229, 82, 217, 84, 1, 217, 106, 217, 84, 1, 248, 229, - 217, 84, 1, 198, 217, 84, 1, 191, 217, 84, 1, 252, 199, 217, 84, 1, 186, - 217, 84, 1, 192, 217, 84, 1, 233, 141, 217, 84, 1, 212, 65, 217, 84, 1, - 206, 217, 84, 1, 162, 217, 84, 25, 5, 74, 217, 84, 25, 5, 69, 217, 84, 5, - 213, 152, 242, 14, 1, 61, 242, 14, 1, 74, 242, 14, 1, 69, 242, 14, 1, - 176, 242, 14, 1, 243, 142, 242, 14, 1, 229, 82, 242, 14, 1, 217, 106, - 242, 14, 1, 248, 229, 242, 14, 1, 198, 242, 14, 1, 191, 242, 14, 1, 252, - 199, 242, 14, 1, 186, 242, 14, 1, 192, 242, 14, 1, 205, 242, 14, 1, 233, - 141, 242, 14, 1, 212, 65, 242, 14, 1, 206, 242, 14, 1, 162, 242, 14, 25, - 5, 74, 242, 14, 25, 5, 69, 242, 14, 5, 226, 53, 225, 129, 219, 157, 224, - 143, 225, 129, 52, 224, 143, 251, 128, 1, 61, 251, 128, 1, 74, 251, 128, - 1, 69, 251, 128, 1, 176, 251, 128, 1, 243, 142, 251, 128, 1, 229, 82, - 251, 128, 1, 217, 106, 251, 128, 1, 248, 229, 251, 128, 1, 198, 251, 128, - 1, 191, 251, 128, 1, 252, 199, 251, 128, 1, 186, 251, 128, 1, 192, 251, - 128, 1, 205, 251, 128, 1, 233, 141, 251, 128, 1, 212, 65, 251, 128, 1, - 206, 251, 128, 1, 162, 251, 128, 25, 5, 74, 251, 128, 25, 5, 69, 217, 83, - 1, 61, 217, 83, 1, 74, 217, 83, 1, 69, 217, 83, 1, 176, 217, 83, 1, 243, - 142, 217, 83, 1, 229, 82, 217, 83, 1, 217, 106, 217, 83, 1, 248, 229, - 217, 83, 1, 198, 217, 83, 1, 191, 217, 83, 1, 252, 199, 217, 83, 1, 186, - 217, 83, 1, 192, 217, 83, 1, 233, 141, 217, 83, 1, 212, 65, 217, 83, 1, - 206, 217, 83, 25, 5, 74, 217, 83, 25, 5, 69, 70, 1, 176, 70, 1, 234, 138, - 70, 1, 234, 34, 70, 1, 234, 111, 70, 1, 229, 9, 70, 1, 251, 41, 70, 1, - 250, 165, 70, 1, 249, 246, 70, 1, 250, 94, 70, 1, 227, 138, 70, 1, 248, - 229, 70, 1, 215, 145, 70, 1, 247, 153, 70, 1, 215, 140, 70, 1, 228, 85, - 70, 1, 217, 106, 70, 1, 216, 209, 70, 1, 112, 70, 1, 216, 157, 70, 1, - 228, 79, 70, 1, 252, 199, 70, 1, 225, 150, 70, 1, 225, 19, 70, 1, 225, - 124, 70, 1, 230, 166, 70, 1, 210, 244, 70, 1, 222, 213, 70, 1, 232, 162, - 70, 1, 213, 138, 70, 1, 220, 104, 70, 1, 218, 186, 70, 1, 206, 70, 1, - 162, 70, 1, 233, 141, 70, 1, 224, 91, 70, 235, 250, 25, 224, 77, 70, 235, - 250, 25, 224, 90, 70, 235, 250, 25, 224, 56, 70, 235, 250, 25, 224, 51, - 70, 235, 250, 25, 224, 33, 70, 235, 250, 25, 224, 5, 70, 235, 250, 25, - 223, 249, 70, 235, 250, 25, 223, 248, 70, 235, 250, 25, 222, 102, 70, - 235, 250, 25, 222, 95, 70, 235, 250, 25, 232, 67, 70, 235, 250, 25, 232, - 57, 70, 235, 250, 25, 224, 72, 70, 235, 250, 25, 224, 83, 70, 235, 250, - 25, 224, 41, 215, 49, 111, 70, 235, 250, 25, 224, 41, 215, 49, 105, 70, - 235, 250, 25, 224, 73, 70, 25, 235, 236, 254, 53, 70, 25, 235, 236, 255, - 82, 70, 25, 5, 255, 82, 70, 25, 5, 74, 70, 25, 5, 236, 40, 70, 25, 5, - 211, 117, 70, 25, 5, 210, 169, 70, 25, 5, 69, 70, 25, 5, 214, 118, 70, - 25, 5, 214, 229, 70, 25, 5, 226, 238, 70, 25, 5, 192, 70, 25, 5, 236, 67, - 70, 25, 5, 76, 70, 25, 5, 254, 252, 70, 25, 5, 254, 210, 70, 25, 5, 226, - 187, 70, 25, 5, 253, 200, 70, 5, 228, 211, 70, 5, 223, 129, 70, 5, 210, - 180, 70, 5, 230, 57, 70, 5, 215, 214, 70, 5, 252, 151, 70, 5, 222, 208, - 70, 5, 216, 41, 70, 5, 234, 247, 70, 5, 254, 212, 70, 5, 221, 246, 221, - 240, 70, 5, 213, 149, 70, 5, 249, 240, 70, 5, 252, 125, 70, 5, 234, 131, - 70, 5, 252, 145, 70, 5, 251, 17, 225, 75, 233, 193, 70, 5, 233, 36, 216, - 18, 70, 5, 252, 28, 70, 5, 225, 126, 230, 104, 70, 5, 234, 15, 70, 249, - 106, 16, 223, 31, 70, 5, 253, 182, 70, 5, 253, 203, 70, 21, 210, 86, 70, - 21, 111, 70, 21, 105, 70, 21, 158, 70, 21, 161, 70, 21, 190, 70, 21, 195, - 70, 21, 199, 70, 21, 196, 70, 21, 201, 70, 16, 233, 36, 253, 205, 219, - 45, 70, 16, 233, 36, 253, 205, 230, 76, 70, 16, 233, 36, 253, 205, 225, - 74, 70, 16, 233, 36, 253, 205, 252, 57, 70, 16, 233, 36, 253, 205, 251, - 111, 70, 16, 233, 36, 253, 205, 224, 218, 70, 16, 233, 36, 253, 205, 224, - 212, 70, 16, 233, 36, 253, 205, 224, 210, 70, 16, 233, 36, 253, 205, 224, - 216, 70, 16, 233, 36, 253, 205, 224, 214, 83, 251, 244, 83, 245, 171, 83, - 249, 227, 83, 243, 236, 218, 131, 83, 249, 234, 83, 244, 19, 247, 126, - 83, 216, 40, 219, 54, 240, 175, 83, 219, 192, 3, 251, 180, 231, 159, 83, - 231, 188, 249, 227, 83, 231, 188, 243, 236, 218, 131, 83, 228, 196, 83, - 244, 5, 45, 221, 159, 111, 83, 244, 5, 45, 221, 159, 105, 83, 244, 5, 45, - 221, 159, 158, 83, 25, 220, 139, 83, 21, 210, 86, 83, 21, 111, 83, 21, - 105, 83, 21, 158, 83, 21, 161, 83, 21, 190, 83, 21, 195, 83, 21, 199, 83, - 21, 196, 83, 21, 201, 83, 1, 61, 83, 1, 76, 83, 1, 74, 83, 1, 78, 83, 1, - 69, 83, 1, 226, 238, 83, 1, 214, 214, 83, 1, 245, 217, 83, 1, 198, 83, 1, - 254, 123, 83, 1, 252, 199, 83, 1, 191, 83, 1, 224, 91, 83, 1, 243, 142, - 83, 1, 186, 83, 1, 233, 141, 83, 1, 206, 83, 1, 220, 104, 83, 1, 217, - 106, 83, 1, 248, 229, 83, 1, 250, 165, 83, 1, 235, 147, 83, 1, 192, 83, - 1, 205, 83, 1, 212, 65, 83, 1, 244, 204, 83, 1, 176, 83, 1, 234, 138, 83, - 1, 215, 184, 83, 1, 210, 116, 83, 1, 242, 53, 83, 1, 210, 16, 83, 1, 233, - 4, 83, 1, 210, 69, 83, 1, 250, 118, 83, 1, 216, 40, 200, 25, 50, 83, 1, - 216, 40, 76, 83, 1, 216, 40, 74, 83, 1, 216, 40, 78, 83, 1, 216, 40, 69, - 83, 1, 216, 40, 226, 238, 83, 1, 216, 40, 214, 214, 83, 1, 216, 40, 254, - 123, 83, 1, 216, 40, 252, 199, 83, 1, 216, 40, 191, 83, 1, 216, 40, 224, - 91, 83, 1, 216, 40, 243, 142, 83, 1, 216, 40, 186, 83, 1, 216, 40, 217, - 106, 83, 1, 216, 40, 248, 229, 83, 1, 216, 40, 250, 165, 83, 1, 216, 40, - 235, 147, 83, 1, 216, 40, 215, 184, 83, 1, 216, 40, 192, 83, 1, 216, 40, - 212, 65, 83, 1, 216, 40, 176, 83, 1, 216, 40, 243, 139, 83, 1, 216, 40, - 242, 53, 83, 1, 216, 40, 235, 113, 83, 1, 216, 40, 228, 236, 83, 1, 216, - 40, 246, 46, 83, 1, 219, 192, 76, 83, 1, 219, 192, 74, 83, 1, 219, 192, - 235, 158, 83, 1, 219, 192, 214, 214, 83, 1, 219, 192, 69, 83, 1, 219, - 192, 254, 123, 83, 1, 219, 192, 176, 83, 1, 219, 192, 243, 142, 83, 1, - 219, 192, 162, 83, 1, 219, 192, 191, 83, 1, 219, 192, 220, 104, 83, 1, - 219, 192, 217, 106, 83, 1, 219, 192, 248, 229, 83, 1, 219, 192, 235, 147, - 83, 1, 219, 192, 244, 204, 83, 1, 219, 192, 243, 139, 83, 1, 219, 192, - 242, 53, 83, 1, 219, 192, 215, 184, 83, 1, 219, 192, 210, 116, 83, 1, - 219, 192, 223, 187, 83, 1, 219, 192, 250, 165, 83, 1, 219, 192, 210, 82, - 83, 1, 231, 188, 74, 83, 1, 231, 188, 176, 83, 1, 231, 188, 205, 83, 1, - 231, 188, 244, 204, 83, 1, 231, 188, 210, 82, 83, 1, 254, 171, 243, 123, - 254, 84, 111, 83, 1, 254, 171, 243, 123, 213, 148, 111, 83, 1, 254, 171, - 243, 123, 248, 194, 83, 1, 254, 171, 243, 123, 214, 224, 83, 1, 254, 171, - 243, 123, 235, 200, 214, 224, 83, 1, 254, 171, 243, 123, 252, 163, 83, 1, - 254, 171, 243, 123, 134, 252, 163, 83, 1, 254, 171, 243, 123, 61, 83, 1, - 254, 171, 243, 123, 74, 83, 1, 254, 171, 243, 123, 176, 83, 1, 254, 171, - 243, 123, 229, 82, 83, 1, 254, 171, 243, 123, 251, 41, 83, 1, 254, 171, - 243, 123, 215, 157, 83, 1, 254, 171, 243, 123, 215, 145, 83, 1, 254, 171, - 243, 123, 248, 143, 83, 1, 254, 171, 243, 123, 228, 115, 83, 1, 254, 171, - 243, 123, 217, 106, 83, 1, 254, 171, 243, 123, 248, 229, 83, 1, 254, 171, - 243, 123, 191, 83, 1, 254, 171, 243, 123, 225, 150, 83, 1, 254, 171, 243, - 123, 218, 225, 83, 1, 254, 171, 243, 123, 210, 82, 83, 1, 254, 171, 243, - 123, 210, 116, 83, 1, 254, 171, 243, 123, 254, 218, 83, 1, 216, 40, 254, - 171, 243, 123, 217, 106, 83, 1, 216, 40, 254, 171, 243, 123, 210, 82, 83, - 1, 231, 188, 254, 171, 243, 123, 243, 0, 83, 1, 231, 188, 254, 171, 243, - 123, 229, 82, 83, 1, 231, 188, 254, 171, 243, 123, 251, 41, 83, 1, 231, - 188, 254, 171, 243, 123, 235, 120, 83, 1, 231, 188, 254, 171, 243, 123, - 215, 157, 83, 1, 231, 188, 254, 171, 243, 123, 248, 127, 83, 1, 231, 188, - 254, 171, 243, 123, 217, 106, 83, 1, 231, 188, 254, 171, 243, 123, 248, - 33, 83, 1, 231, 188, 254, 171, 243, 123, 218, 225, 83, 1, 231, 188, 254, - 171, 243, 123, 249, 80, 83, 1, 231, 188, 254, 171, 243, 123, 210, 82, 83, - 1, 231, 188, 254, 171, 243, 123, 210, 116, 83, 1, 254, 171, 243, 123, - 163, 69, 83, 1, 254, 171, 243, 123, 163, 192, 83, 1, 231, 188, 254, 171, - 243, 123, 252, 26, 83, 1, 254, 171, 243, 123, 248, 219, 83, 1, 231, 188, - 254, 171, 243, 123, 233, 4, 18, 19, 226, 113, 18, 19, 253, 175, 18, 19, - 255, 37, 18, 19, 212, 25, 18, 19, 224, 224, 18, 19, 225, 233, 18, 19, - 224, 108, 18, 19, 217, 32, 18, 19, 234, 195, 18, 19, 233, 185, 18, 19, - 231, 137, 18, 19, 228, 42, 18, 19, 229, 186, 18, 19, 233, 74, 18, 19, - 219, 24, 18, 19, 221, 213, 18, 19, 219, 234, 18, 19, 220, 68, 18, 19, - 219, 203, 18, 19, 210, 220, 18, 19, 211, 52, 18, 19, 223, 137, 18, 19, - 227, 175, 18, 19, 226, 220, 227, 175, 18, 19, 227, 174, 18, 19, 226, 220, - 227, 174, 18, 19, 227, 173, 18, 19, 226, 220, 227, 173, 18, 19, 227, 172, - 18, 19, 226, 220, 227, 172, 18, 19, 222, 107, 18, 19, 222, 106, 18, 19, - 222, 105, 18, 19, 222, 104, 18, 19, 222, 103, 18, 19, 222, 111, 18, 19, - 226, 220, 226, 109, 18, 19, 226, 220, 217, 153, 18, 19, 226, 220, 235, - 29, 18, 19, 226, 220, 251, 74, 18, 19, 226, 220, 194, 18, 19, 226, 220, - 230, 30, 18, 19, 226, 220, 222, 93, 18, 19, 226, 220, 220, 106, 18, 19, - 245, 227, 212, 98, 18, 19, 212, 7, 212, 98, 18, 19, 40, 4, 222, 236, 18, - 19, 40, 223, 160, 247, 128, 18, 19, 223, 226, 222, 108, 18, 19, 159, 232, - 133, 18, 19, 159, 233, 140, 18, 19, 216, 127, 18, 19, 216, 129, 18, 19, - 215, 137, 18, 19, 215, 139, 18, 19, 215, 144, 18, 19, 216, 50, 18, 19, - 216, 52, 18, 19, 221, 211, 219, 208, 18, 19, 221, 211, 220, 3, 18, 19, - 221, 211, 241, 60, 18, 19, 73, 242, 80, 18, 19, 73, 248, 60, 243, 62, 18, - 19, 73, 243, 139, 18, 19, 73, 242, 85, 18, 19, 221, 211, 235, 39, 18, 19, - 73, 235, 37, 18, 19, 252, 76, 248, 60, 156, 18, 19, 252, 76, 248, 60, - 153, 18, 19, 73, 248, 55, 222, 93, 232, 229, 213, 122, 233, 16, 232, 229, - 1, 176, 232, 229, 1, 234, 138, 232, 229, 1, 243, 142, 232, 229, 1, 243, - 0, 232, 229, 1, 229, 82, 232, 229, 1, 251, 41, 232, 229, 1, 250, 165, - 232, 229, 1, 235, 147, 232, 229, 1, 235, 120, 232, 229, 1, 211, 71, 232, - 229, 1, 217, 106, 232, 229, 1, 216, 209, 232, 229, 1, 248, 229, 232, 229, - 1, 248, 33, 232, 229, 1, 198, 232, 229, 1, 191, 232, 229, 1, 225, 150, - 232, 229, 1, 252, 199, 232, 229, 1, 252, 26, 232, 229, 1, 186, 232, 229, - 1, 192, 232, 229, 1, 205, 232, 229, 1, 233, 141, 232, 229, 1, 212, 65, - 232, 229, 1, 220, 104, 232, 229, 1, 218, 225, 232, 229, 1, 206, 232, 229, - 1, 162, 232, 229, 25, 5, 61, 232, 229, 25, 5, 74, 232, 229, 25, 5, 69, - 232, 229, 25, 5, 245, 217, 232, 229, 25, 5, 254, 210, 232, 229, 25, 5, - 226, 187, 232, 229, 25, 5, 253, 200, 232, 229, 25, 5, 76, 232, 229, 25, - 5, 78, 232, 229, 218, 74, 1, 192, 232, 229, 218, 74, 1, 205, 232, 229, - 218, 74, 1, 212, 65, 232, 229, 4, 1, 176, 232, 229, 4, 1, 229, 82, 232, - 229, 4, 1, 254, 83, 232, 229, 4, 1, 217, 106, 232, 229, 4, 1, 198, 232, - 229, 4, 1, 191, 232, 229, 4, 1, 186, 232, 229, 4, 1, 205, 232, 229, 4, 1, - 233, 141, 232, 229, 5, 230, 94, 232, 229, 5, 234, 177, 232, 229, 5, 222, - 34, 232, 229, 5, 232, 133, 232, 229, 245, 39, 79, 232, 229, 224, 16, 79, - 232, 229, 21, 210, 86, 232, 229, 21, 111, 232, 229, 21, 105, 232, 229, - 21, 158, 232, 229, 21, 161, 232, 229, 21, 190, 232, 229, 21, 195, 232, - 229, 21, 199, 232, 229, 21, 196, 232, 229, 21, 201, 39, 233, 65, 1, 176, - 39, 233, 65, 1, 211, 165, 39, 233, 65, 1, 229, 82, 39, 233, 65, 1, 215, - 184, 39, 233, 65, 1, 206, 39, 233, 65, 1, 192, 39, 233, 65, 1, 217, 106, - 39, 233, 65, 1, 216, 209, 39, 233, 65, 1, 233, 141, 39, 233, 65, 1, 191, - 39, 233, 65, 1, 225, 150, 39, 233, 65, 1, 186, 39, 233, 65, 1, 244, 204, - 39, 233, 65, 1, 214, 27, 39, 233, 65, 1, 162, 39, 233, 65, 1, 224, 91, - 39, 233, 65, 1, 234, 138, 39, 233, 65, 1, 215, 176, 39, 233, 65, 1, 198, - 39, 233, 65, 1, 61, 39, 233, 65, 1, 74, 39, 233, 65, 1, 245, 217, 39, - 233, 65, 1, 245, 205, 39, 233, 65, 1, 69, 39, 233, 65, 1, 226, 187, 39, - 233, 65, 1, 78, 39, 233, 65, 1, 214, 214, 39, 233, 65, 1, 76, 39, 233, - 65, 1, 253, 198, 39, 233, 65, 1, 254, 210, 39, 233, 65, 1, 216, 29, 39, - 233, 65, 1, 216, 28, 39, 233, 65, 1, 216, 27, 39, 233, 65, 1, 216, 26, - 39, 233, 65, 1, 216, 25, 166, 39, 173, 1, 125, 224, 91, 166, 39, 173, 1, - 121, 224, 91, 166, 39, 173, 1, 125, 176, 166, 39, 173, 1, 125, 211, 165, - 166, 39, 173, 1, 125, 229, 82, 166, 39, 173, 1, 121, 176, 166, 39, 173, - 1, 121, 211, 165, 166, 39, 173, 1, 121, 229, 82, 166, 39, 173, 1, 125, - 215, 184, 166, 39, 173, 1, 125, 206, 166, 39, 173, 1, 125, 192, 166, 39, - 173, 1, 121, 215, 184, 166, 39, 173, 1, 121, 206, 166, 39, 173, 1, 121, - 192, 166, 39, 173, 1, 125, 217, 106, 166, 39, 173, 1, 125, 216, 209, 166, - 39, 173, 1, 125, 198, 166, 39, 173, 1, 121, 217, 106, 166, 39, 173, 1, - 121, 216, 209, 166, 39, 173, 1, 121, 198, 166, 39, 173, 1, 125, 191, 166, - 39, 173, 1, 125, 225, 150, 166, 39, 173, 1, 125, 186, 166, 39, 173, 1, - 121, 191, 166, 39, 173, 1, 121, 225, 150, 166, 39, 173, 1, 121, 186, 166, - 39, 173, 1, 125, 244, 204, 166, 39, 173, 1, 125, 214, 27, 166, 39, 173, - 1, 125, 233, 141, 166, 39, 173, 1, 121, 244, 204, 166, 39, 173, 1, 121, - 214, 27, 166, 39, 173, 1, 121, 233, 141, 166, 39, 173, 1, 125, 162, 166, - 39, 173, 1, 125, 248, 229, 166, 39, 173, 1, 125, 252, 199, 166, 39, 173, - 1, 121, 162, 166, 39, 173, 1, 121, 248, 229, 166, 39, 173, 1, 121, 252, - 199, 166, 39, 173, 1, 125, 233, 190, 166, 39, 173, 1, 125, 211, 138, 166, - 39, 173, 1, 121, 233, 190, 166, 39, 173, 1, 121, 211, 138, 166, 39, 173, - 1, 125, 218, 83, 166, 39, 173, 1, 121, 218, 83, 166, 39, 173, 25, 5, 25, - 219, 241, 166, 39, 173, 25, 5, 255, 82, 166, 39, 173, 25, 5, 236, 40, - 166, 39, 173, 25, 5, 69, 166, 39, 173, 25, 5, 214, 118, 166, 39, 173, 25, - 5, 76, 166, 39, 173, 25, 5, 254, 252, 166, 39, 173, 25, 5, 78, 166, 39, - 173, 25, 5, 227, 4, 166, 39, 173, 25, 5, 214, 214, 166, 39, 173, 25, 5, - 253, 175, 166, 39, 173, 25, 5, 255, 37, 166, 39, 173, 25, 5, 214, 111, - 166, 39, 173, 25, 5, 226, 113, 166, 39, 173, 25, 5, 227, 1, 166, 39, 173, - 25, 5, 214, 210, 166, 39, 173, 25, 5, 235, 158, 166, 39, 173, 1, 40, 214, - 105, 166, 39, 173, 1, 40, 229, 84, 166, 39, 173, 1, 40, 230, 30, 166, 39, - 173, 1, 40, 194, 166, 39, 173, 1, 40, 235, 29, 166, 39, 173, 1, 40, 249, - 68, 166, 39, 173, 1, 40, 253, 166, 166, 39, 173, 138, 231, 163, 166, 39, - 173, 138, 231, 162, 166, 39, 173, 21, 210, 86, 166, 39, 173, 21, 111, - 166, 39, 173, 21, 105, 166, 39, 173, 21, 158, 166, 39, 173, 21, 161, 166, - 39, 173, 21, 190, 166, 39, 173, 21, 195, 166, 39, 173, 21, 199, 166, 39, - 173, 21, 196, 166, 39, 173, 21, 201, 166, 39, 173, 89, 21, 111, 166, 39, - 173, 5, 233, 126, 166, 39, 173, 5, 233, 125, 70, 16, 225, 240, 70, 16, - 230, 77, 234, 31, 70, 16, 225, 75, 234, 31, 70, 16, 252, 58, 234, 31, 70, - 16, 251, 112, 234, 31, 70, 16, 224, 219, 234, 31, 70, 16, 224, 213, 234, - 31, 70, 16, 224, 211, 234, 31, 70, 16, 224, 217, 234, 31, 70, 16, 224, - 215, 234, 31, 70, 16, 248, 181, 234, 31, 70, 16, 248, 177, 234, 31, 70, - 16, 248, 176, 234, 31, 70, 16, 248, 179, 234, 31, 70, 16, 248, 178, 234, - 31, 70, 16, 248, 175, 234, 31, 70, 16, 215, 87, 70, 16, 230, 77, 222, - 207, 70, 16, 225, 75, 222, 207, 70, 16, 252, 58, 222, 207, 70, 16, 251, - 112, 222, 207, 70, 16, 224, 219, 222, 207, 70, 16, 224, 213, 222, 207, - 70, 16, 224, 211, 222, 207, 70, 16, 224, 217, 222, 207, 70, 16, 224, 215, - 222, 207, 70, 16, 248, 181, 222, 207, 70, 16, 248, 177, 222, 207, 70, 16, - 248, 176, 222, 207, 70, 16, 248, 179, 222, 207, 70, 16, 248, 178, 222, - 207, 70, 16, 248, 175, 222, 207, 251, 129, 1, 176, 251, 129, 1, 243, 142, - 251, 129, 1, 229, 82, 251, 129, 1, 229, 27, 251, 129, 1, 191, 251, 129, - 1, 252, 199, 251, 129, 1, 186, 251, 129, 1, 230, 110, 251, 129, 1, 217, - 106, 251, 129, 1, 248, 229, 251, 129, 1, 198, 251, 129, 1, 228, 41, 251, - 129, 1, 251, 41, 251, 129, 1, 235, 147, 251, 129, 1, 227, 169, 251, 129, - 1, 227, 162, 251, 129, 1, 192, 251, 129, 1, 205, 251, 129, 1, 233, 141, - 251, 129, 1, 214, 27, 251, 129, 1, 206, 251, 129, 1, 61, 251, 129, 1, - 162, 251, 129, 25, 5, 74, 251, 129, 25, 5, 69, 251, 129, 25, 5, 76, 251, - 129, 25, 5, 78, 251, 129, 25, 5, 254, 252, 251, 129, 226, 64, 251, 129, - 245, 151, 64, 221, 174, 39, 89, 1, 125, 176, 39, 89, 1, 125, 234, 138, - 39, 89, 1, 125, 233, 177, 39, 89, 1, 121, 176, 39, 89, 1, 121, 233, 177, - 39, 89, 1, 121, 234, 138, 39, 89, 1, 229, 82, 39, 89, 1, 125, 251, 41, - 39, 89, 1, 125, 250, 165, 39, 89, 1, 121, 251, 41, 39, 89, 1, 121, 206, - 39, 89, 1, 121, 250, 165, 39, 89, 1, 227, 169, 39, 89, 1, 223, 143, 39, - 89, 1, 125, 223, 141, 39, 89, 1, 248, 229, 39, 89, 1, 121, 223, 141, 39, - 89, 1, 223, 152, 39, 89, 1, 125, 217, 106, 39, 89, 1, 125, 216, 209, 39, - 89, 1, 121, 217, 106, 39, 89, 1, 121, 216, 209, 39, 89, 1, 198, 39, 89, - 1, 252, 199, 39, 89, 1, 125, 191, 39, 89, 1, 125, 225, 150, 39, 89, 1, - 125, 244, 204, 39, 89, 1, 121, 191, 39, 89, 1, 121, 244, 204, 39, 89, 1, - 121, 225, 150, 39, 89, 1, 186, 39, 89, 1, 121, 192, 39, 89, 1, 125, 192, - 39, 89, 1, 205, 39, 89, 1, 222, 139, 39, 89, 1, 233, 141, 39, 89, 1, 232, - 98, 39, 89, 1, 212, 65, 39, 89, 1, 125, 220, 104, 39, 89, 1, 125, 218, - 225, 39, 89, 1, 125, 206, 39, 89, 1, 125, 162, 39, 89, 1, 232, 190, 39, - 89, 1, 61, 39, 89, 1, 121, 162, 39, 89, 1, 74, 39, 89, 1, 236, 40, 39, - 89, 1, 69, 39, 89, 1, 214, 118, 39, 89, 1, 245, 217, 39, 89, 1, 226, 187, - 39, 89, 1, 233, 126, 39, 89, 1, 242, 139, 206, 39, 89, 117, 5, 147, 205, - 39, 89, 117, 5, 147, 233, 141, 39, 89, 117, 5, 233, 142, 217, 59, 233, - 115, 39, 89, 5, 231, 209, 234, 237, 233, 115, 39, 89, 117, 5, 40, 229, - 82, 39, 89, 117, 5, 121, 191, 39, 89, 117, 5, 125, 223, 142, 177, 121, - 191, 39, 89, 117, 5, 186, 39, 89, 117, 5, 252, 199, 39, 89, 117, 5, 206, - 39, 89, 5, 222, 12, 39, 89, 25, 5, 61, 39, 89, 25, 5, 231, 209, 221, 228, - 39, 89, 25, 5, 255, 82, 39, 89, 25, 5, 217, 65, 255, 82, 39, 89, 25, 5, - 74, 39, 89, 25, 5, 236, 40, 39, 89, 25, 5, 214, 214, 39, 89, 25, 5, 214, - 117, 39, 89, 25, 5, 69, 39, 89, 25, 5, 214, 118, 39, 89, 25, 5, 78, 39, - 89, 25, 5, 227, 5, 51, 39, 89, 25, 5, 226, 113, 39, 89, 25, 5, 76, 39, - 89, 25, 5, 254, 252, 39, 89, 25, 5, 226, 187, 39, 89, 25, 5, 254, 210, - 39, 89, 25, 5, 89, 254, 210, 39, 89, 25, 5, 227, 5, 48, 39, 89, 5, 231, - 209, 234, 236, 39, 89, 5, 216, 30, 39, 89, 5, 216, 29, 39, 89, 5, 234, - 103, 216, 28, 39, 89, 5, 234, 103, 216, 27, 39, 89, 5, 234, 103, 216, 26, - 39, 89, 5, 223, 191, 242, 52, 39, 89, 5, 231, 209, 221, 255, 39, 89, 5, - 234, 102, 234, 221, 39, 89, 38, 249, 123, 247, 128, 39, 89, 241, 53, 21, - 210, 86, 39, 89, 241, 53, 21, 111, 39, 89, 241, 53, 21, 105, 39, 89, 241, - 53, 21, 158, 39, 89, 241, 53, 21, 161, 39, 89, 241, 53, 21, 190, 39, 89, - 241, 53, 21, 195, 39, 89, 241, 53, 21, 199, 39, 89, 241, 53, 21, 196, 39, - 89, 241, 53, 21, 201, 39, 89, 89, 21, 210, 86, 39, 89, 89, 21, 111, 39, - 89, 89, 21, 105, 39, 89, 89, 21, 158, 39, 89, 89, 21, 161, 39, 89, 89, - 21, 190, 39, 89, 89, 21, 195, 39, 89, 89, 21, 199, 39, 89, 89, 21, 196, - 39, 89, 89, 21, 201, 39, 89, 5, 211, 249, 39, 89, 5, 211, 248, 39, 89, 5, - 221, 217, 39, 89, 5, 234, 166, 39, 89, 5, 240, 239, 39, 89, 5, 247, 142, - 39, 89, 5, 223, 52, 222, 189, 223, 152, 39, 89, 5, 231, 209, 211, 72, 39, - 89, 5, 235, 12, 39, 89, 5, 235, 11, 39, 89, 5, 221, 224, 39, 89, 5, 221, - 223, 39, 89, 5, 242, 16, 39, 89, 5, 251, 38, 102, 5, 214, 200, 223, 33, - 102, 5, 214, 200, 251, 9, 102, 5, 250, 194, 102, 5, 218, 16, 102, 5, 251, - 241, 102, 1, 254, 193, 102, 1, 254, 194, 217, 14, 102, 1, 236, 36, 102, - 1, 236, 37, 217, 14, 102, 1, 214, 203, 102, 1, 214, 204, 217, 14, 102, 1, - 223, 191, 223, 82, 102, 1, 223, 191, 223, 83, 217, 14, 102, 1, 233, 142, - 233, 30, 102, 1, 233, 142, 233, 31, 217, 14, 102, 1, 245, 187, 102, 1, - 254, 208, 102, 1, 226, 216, 102, 1, 226, 217, 217, 14, 102, 1, 176, 102, - 1, 235, 19, 231, 212, 102, 1, 243, 142, 102, 1, 243, 143, 242, 168, 102, - 1, 229, 82, 102, 1, 251, 41, 102, 1, 251, 42, 233, 129, 102, 1, 235, 147, - 102, 1, 235, 148, 235, 124, 102, 1, 227, 169, 102, 1, 217, 107, 233, 82, - 102, 1, 217, 107, 230, 72, 231, 212, 102, 1, 248, 230, 230, 72, 254, 153, - 102, 1, 248, 230, 230, 72, 231, 212, 102, 1, 229, 234, 223, 155, 102, 1, - 217, 106, 102, 1, 217, 107, 217, 36, 102, 1, 248, 229, 102, 1, 248, 230, - 231, 230, 102, 1, 198, 102, 1, 191, 102, 1, 226, 94, 234, 232, 102, 1, - 252, 199, 102, 1, 252, 200, 234, 178, 102, 1, 186, 102, 1, 192, 102, 1, - 205, 102, 1, 233, 141, 102, 1, 212, 65, 102, 1, 222, 36, 222, 22, 102, 1, - 222, 36, 221, 235, 102, 1, 206, 102, 1, 162, 102, 5, 223, 73, 102, 25, 5, - 217, 14, 102, 25, 5, 214, 199, 102, 25, 5, 214, 200, 221, 231, 102, 25, - 5, 218, 48, 102, 25, 5, 218, 49, 236, 28, 102, 25, 5, 223, 191, 223, 82, - 102, 25, 5, 223, 191, 223, 83, 217, 14, 102, 25, 5, 233, 142, 233, 30, - 102, 25, 5, 233, 142, 233, 31, 217, 14, 102, 25, 5, 217, 66, 102, 25, 5, - 217, 67, 223, 82, 102, 25, 5, 217, 67, 217, 14, 102, 25, 5, 217, 67, 223, - 83, 217, 14, 102, 25, 5, 225, 187, 102, 25, 5, 225, 188, 217, 14, 102, - 255, 3, 255, 2, 102, 1, 235, 1, 221, 230, 102, 1, 234, 108, 221, 230, - 102, 1, 215, 34, 221, 230, 102, 1, 245, 211, 221, 230, 102, 1, 214, 0, - 221, 230, 102, 1, 210, 107, 221, 230, 102, 1, 253, 217, 221, 230, 102, - 21, 210, 86, 102, 21, 111, 102, 21, 105, 102, 21, 158, 102, 21, 161, 102, - 21, 190, 102, 21, 195, 102, 21, 199, 102, 21, 196, 102, 21, 201, 102, - 226, 33, 102, 226, 59, 102, 211, 238, 102, 250, 244, 226, 52, 102, 250, - 244, 219, 174, 102, 250, 244, 226, 6, 102, 226, 58, 102, 28, 16, 247, - 134, 102, 28, 16, 248, 59, 102, 28, 16, 246, 72, 102, 28, 16, 248, 184, - 102, 28, 16, 248, 185, 218, 16, 102, 28, 16, 247, 213, 102, 28, 16, 248, - 222, 102, 28, 16, 248, 41, 102, 28, 16, 248, 206, 102, 28, 16, 248, 185, - 243, 64, 102, 28, 16, 38, 217, 10, 102, 28, 16, 38, 245, 149, 102, 28, - 16, 38, 234, 173, 102, 28, 16, 38, 234, 175, 102, 28, 16, 38, 235, 128, - 102, 28, 16, 38, 234, 174, 2, 235, 128, 102, 28, 16, 38, 234, 176, 2, - 235, 128, 102, 28, 16, 38, 252, 45, 102, 28, 16, 38, 242, 172, 102, 28, - 16, 222, 252, 204, 246, 82, 102, 28, 16, 222, 252, 204, 248, 220, 102, - 28, 16, 222, 252, 250, 8, 215, 112, 102, 28, 16, 222, 252, 250, 8, 217, - 74, 102, 28, 16, 233, 50, 204, 226, 47, 102, 28, 16, 233, 50, 204, 224, - 142, 102, 28, 16, 233, 50, 250, 8, 225, 41, 102, 28, 16, 233, 50, 250, 8, - 225, 29, 102, 28, 16, 233, 50, 204, 225, 64, 207, 5, 226, 30, 207, 5, - 226, 43, 207, 5, 226, 39, 207, 1, 61, 207, 1, 74, 207, 1, 69, 207, 1, - 254, 252, 207, 1, 78, 207, 1, 76, 207, 1, 245, 63, 207, 1, 176, 207, 1, - 224, 91, 207, 1, 243, 142, 207, 1, 229, 82, 207, 1, 251, 41, 207, 1, 235, - 147, 207, 1, 210, 116, 207, 1, 227, 169, 207, 1, 217, 106, 207, 1, 248, - 229, 207, 1, 198, 207, 1, 191, 207, 1, 244, 204, 207, 1, 214, 27, 207, 1, - 252, 199, 207, 1, 186, 207, 1, 192, 207, 1, 205, 207, 1, 233, 141, 207, - 1, 212, 65, 207, 1, 206, 207, 1, 211, 165, 207, 1, 162, 207, 117, 5, 226, - 56, 207, 117, 5, 226, 32, 207, 117, 5, 226, 29, 207, 25, 5, 226, 46, 207, - 25, 5, 226, 28, 207, 25, 5, 226, 50, 207, 25, 5, 226, 38, 207, 25, 5, - 226, 57, 207, 25, 5, 226, 48, 207, 5, 226, 60, 207, 5, 213, 152, 207, - 117, 5, 225, 252, 186, 207, 117, 5, 225, 252, 212, 65, 207, 1, 234, 138, - 207, 1, 217, 232, 207, 21, 210, 86, 207, 21, 111, 207, 21, 105, 207, 21, - 158, 207, 21, 161, 207, 21, 190, 207, 21, 195, 207, 21, 199, 207, 21, - 196, 207, 21, 201, 207, 253, 183, 207, 1, 223, 55, 207, 1, 233, 13, 207, - 1, 252, 26, 207, 1, 40, 235, 29, 207, 1, 40, 194, 252, 128, 1, 61, 252, - 128, 1, 219, 166, 61, 252, 128, 1, 162, 252, 128, 1, 219, 166, 162, 252, - 128, 1, 231, 186, 162, 252, 128, 1, 252, 199, 252, 128, 1, 234, 218, 252, - 199, 252, 128, 1, 191, 252, 128, 1, 219, 166, 191, 252, 128, 1, 198, 252, - 128, 1, 231, 186, 198, 252, 128, 1, 212, 65, 252, 128, 1, 219, 166, 212, - 65, 252, 128, 1, 226, 71, 212, 65, 252, 128, 1, 243, 142, 252, 128, 1, - 219, 166, 243, 142, 252, 128, 1, 235, 147, 252, 128, 1, 248, 229, 252, - 128, 1, 205, 252, 128, 1, 219, 166, 205, 252, 128, 1, 186, 252, 128, 1, - 219, 166, 186, 252, 128, 1, 219, 28, 217, 106, 252, 128, 1, 228, 60, 217, - 106, 252, 128, 1, 206, 252, 128, 1, 219, 166, 206, 252, 128, 1, 231, 186, - 206, 252, 128, 1, 192, 252, 128, 1, 219, 166, 192, 252, 128, 1, 229, 82, - 252, 128, 1, 233, 141, 252, 128, 1, 219, 166, 233, 141, 252, 128, 1, 227, - 169, 252, 128, 1, 251, 41, 252, 128, 1, 229, 153, 252, 128, 1, 231, 129, - 252, 128, 1, 74, 252, 128, 1, 69, 252, 128, 5, 216, 34, 252, 128, 25, 5, - 76, 252, 128, 25, 5, 226, 71, 76, 252, 128, 25, 5, 245, 217, 252, 128, - 25, 5, 74, 252, 128, 25, 5, 234, 218, 74, 252, 128, 25, 5, 78, 252, 128, - 25, 5, 234, 218, 78, 252, 128, 25, 5, 69, 252, 128, 25, 5, 104, 31, 219, - 166, 206, 252, 128, 117, 5, 229, 84, 252, 128, 117, 5, 242, 67, 252, 128, - 226, 41, 252, 128, 226, 37, 252, 128, 16, 251, 249, 229, 234, 231, 42, - 252, 128, 16, 251, 249, 225, 67, 252, 128, 16, 251, 249, 235, 54, 252, - 128, 16, 251, 249, 226, 41, 197, 1, 176, 197, 1, 234, 45, 197, 1, 234, - 138, 197, 1, 243, 142, 197, 1, 242, 193, 197, 1, 229, 82, 197, 1, 251, - 41, 197, 1, 250, 165, 197, 1, 235, 147, 197, 1, 227, 169, 197, 1, 217, - 106, 197, 1, 216, 209, 197, 1, 248, 229, 197, 1, 198, 197, 1, 191, 197, - 1, 225, 45, 197, 1, 225, 150, 197, 1, 244, 204, 197, 1, 244, 83, 197, 1, - 252, 199, 197, 1, 251, 230, 197, 1, 186, 197, 1, 230, 173, 197, 1, 215, - 184, 197, 1, 215, 176, 197, 1, 246, 46, 197, 1, 192, 197, 1, 205, 197, 1, - 233, 141, 197, 1, 162, 197, 1, 241, 160, 197, 1, 214, 27, 197, 1, 206, - 197, 1, 220, 104, 197, 1, 212, 65, 197, 1, 61, 197, 218, 74, 1, 192, 197, - 218, 74, 1, 205, 197, 25, 5, 255, 82, 197, 25, 5, 74, 197, 25, 5, 78, - 197, 25, 5, 226, 187, 197, 25, 5, 69, 197, 25, 5, 214, 118, 197, 25, 5, - 76, 197, 117, 5, 235, 29, 197, 117, 5, 194, 197, 117, 5, 156, 197, 117, - 5, 230, 30, 197, 117, 5, 226, 109, 197, 117, 5, 153, 197, 117, 5, 217, - 153, 197, 117, 5, 227, 146, 197, 117, 5, 234, 236, 197, 5, 223, 153, 197, - 5, 227, 209, 197, 224, 144, 217, 104, 197, 224, 144, 227, 156, 216, 121, - 217, 104, 197, 224, 144, 250, 172, 197, 224, 144, 215, 171, 250, 172, - 197, 224, 144, 215, 170, 197, 21, 210, 86, 197, 21, 111, 197, 21, 105, - 197, 21, 158, 197, 21, 161, 197, 21, 190, 197, 21, 195, 197, 21, 199, - 197, 21, 196, 197, 21, 201, 197, 1, 215, 157, 197, 1, 215, 145, 197, 1, - 248, 143, 226, 214, 250, 111, 21, 210, 86, 226, 214, 250, 111, 21, 111, - 226, 214, 250, 111, 21, 105, 226, 214, 250, 111, 21, 158, 226, 214, 250, - 111, 21, 161, 226, 214, 250, 111, 21, 190, 226, 214, 250, 111, 21, 195, - 226, 214, 250, 111, 21, 199, 226, 214, 250, 111, 21, 196, 226, 214, 250, - 111, 21, 201, 226, 214, 250, 111, 1, 233, 141, 226, 214, 250, 111, 1, - 253, 214, 226, 214, 250, 111, 1, 254, 225, 226, 214, 250, 111, 1, 254, - 123, 226, 214, 250, 111, 1, 254, 187, 226, 214, 250, 111, 1, 233, 140, - 226, 214, 250, 111, 1, 255, 44, 226, 214, 250, 111, 1, 255, 45, 226, 214, - 250, 111, 1, 255, 43, 226, 214, 250, 111, 1, 255, 38, 226, 214, 250, 111, - 1, 232, 247, 226, 214, 250, 111, 1, 235, 178, 226, 214, 250, 111, 1, 236, - 41, 226, 214, 250, 111, 1, 235, 197, 226, 214, 250, 111, 1, 235, 186, - 226, 214, 250, 111, 1, 232, 103, 226, 214, 250, 111, 1, 214, 221, 226, - 214, 250, 111, 1, 214, 219, 226, 214, 250, 111, 1, 214, 168, 226, 214, - 250, 111, 1, 214, 111, 226, 214, 250, 111, 1, 233, 64, 226, 214, 250, - 111, 1, 245, 116, 226, 214, 250, 111, 1, 245, 220, 226, 214, 250, 111, 1, - 245, 158, 226, 214, 250, 111, 1, 245, 94, 226, 214, 250, 111, 1, 232, - 162, 226, 214, 250, 111, 1, 226, 141, 226, 214, 250, 111, 1, 227, 0, 226, - 214, 250, 111, 1, 226, 129, 226, 214, 250, 111, 1, 226, 226, 226, 214, - 250, 111, 230, 108, 215, 122, 226, 214, 250, 111, 243, 137, 215, 123, - 226, 214, 250, 111, 230, 106, 215, 123, 226, 214, 250, 111, 223, 95, 226, - 214, 250, 111, 225, 148, 226, 214, 250, 111, 254, 217, 226, 214, 250, - 111, 224, 144, 230, 103, 226, 214, 250, 111, 224, 144, 52, 230, 103, 207, - 224, 144, 251, 249, 218, 9, 207, 224, 144, 251, 249, 226, 42, 207, 224, - 144, 251, 249, 224, 132, 207, 224, 144, 251, 249, 251, 27, 207, 224, 144, - 251, 249, 233, 14, 221, 227, 207, 224, 144, 251, 249, 235, 19, 221, 227, - 207, 224, 144, 251, 249, 248, 230, 221, 227, 207, 224, 144, 251, 249, - 252, 200, 221, 227, 213, 252, 138, 234, 216, 213, 252, 138, 220, 79, 213, - 252, 138, 224, 201, 213, 252, 5, 228, 214, 213, 252, 5, 211, 80, 230, - 227, 218, 1, 213, 252, 138, 211, 80, 254, 222, 235, 250, 218, 1, 213, - 252, 138, 211, 80, 235, 250, 218, 1, 213, 252, 138, 211, 80, 234, 204, - 235, 250, 218, 1, 213, 252, 138, 251, 10, 51, 213, 252, 138, 211, 80, - 234, 204, 235, 250, 218, 2, 221, 199, 213, 252, 138, 52, 218, 1, 213, - 252, 138, 215, 212, 218, 1, 213, 252, 138, 234, 204, 254, 85, 213, 252, - 138, 59, 51, 213, 252, 138, 113, 170, 51, 213, 252, 138, 134, 170, 51, - 213, 252, 138, 222, 243, 234, 215, 235, 250, 218, 1, 213, 252, 138, 253, - 212, 235, 250, 218, 1, 213, 252, 5, 213, 148, 218, 1, 213, 252, 5, 213, - 148, 214, 216, 213, 252, 5, 223, 52, 213, 148, 214, 216, 213, 252, 5, - 213, 148, 254, 85, 213, 252, 5, 223, 52, 213, 148, 254, 85, 213, 252, 5, - 213, 148, 214, 217, 2, 217, 78, 213, 252, 5, 213, 148, 254, 86, 2, 217, - 78, 213, 252, 5, 254, 84, 254, 99, 213, 252, 5, 254, 84, 252, 174, 213, - 252, 5, 254, 84, 214, 20, 213, 252, 5, 254, 84, 214, 21, 2, 217, 78, 213, - 252, 5, 216, 69, 213, 252, 5, 241, 198, 200, 254, 83, 213, 252, 5, 200, - 254, 83, 213, 252, 5, 222, 144, 200, 254, 83, 213, 252, 5, 254, 84, 214, - 223, 230, 95, 213, 252, 5, 254, 28, 213, 252, 5, 222, 189, 254, 28, 213, - 252, 138, 251, 10, 48, 213, 252, 5, 235, 108, 213, 252, 5, 214, 161, 7, - 1, 4, 6, 61, 7, 1, 4, 6, 254, 252, 7, 4, 1, 215, 94, 254, 252, 7, 1, 4, - 6, 252, 142, 253, 166, 7, 1, 4, 6, 251, 74, 7, 1, 4, 6, 249, 68, 7, 1, 4, - 6, 245, 67, 7, 1, 4, 6, 76, 7, 4, 1, 215, 94, 204, 76, 7, 4, 1, 215, 94, - 74, 7, 1, 4, 6, 235, 150, 7, 1, 4, 6, 235, 29, 7, 1, 4, 6, 233, 155, 2, - 91, 7, 1, 4, 6, 194, 7, 1, 4, 6, 223, 52, 230, 30, 7, 1, 4, 6, 78, 7, 1, - 4, 6, 204, 78, 7, 4, 1, 219, 189, 78, 7, 4, 1, 219, 189, 204, 78, 7, 4, - 1, 219, 189, 144, 2, 91, 7, 4, 1, 215, 94, 226, 238, 7, 1, 4, 6, 226, - 138, 7, 4, 1, 216, 15, 163, 78, 7, 4, 1, 251, 183, 163, 78, 7, 1, 4, 6, - 226, 109, 7, 1, 4, 6, 223, 52, 153, 7, 1, 4, 6, 215, 94, 153, 7, 1, 4, 6, - 217, 153, 7, 1, 4, 6, 69, 7, 4, 1, 219, 189, 69, 7, 4, 1, 219, 189, 248, - 8, 69, 7, 4, 1, 219, 189, 215, 94, 194, 7, 1, 4, 6, 214, 105, 7, 1, 4, 6, - 212, 98, 7, 1, 4, 6, 210, 159, 7, 1, 4, 6, 245, 16, 7, 1, 213, 135, 233, - 88, 218, 252, 7, 1, 254, 205, 26, 1, 4, 6, 243, 114, 26, 1, 4, 6, 233, - 104, 26, 1, 4, 6, 225, 111, 26, 1, 4, 6, 223, 40, 26, 1, 4, 6, 224, 164, - 33, 1, 4, 6, 245, 182, 58, 1, 6, 61, 58, 1, 6, 254, 252, 58, 1, 6, 253, - 166, 58, 1, 6, 252, 142, 253, 166, 58, 1, 6, 249, 68, 58, 1, 6, 76, 58, - 1, 6, 223, 52, 76, 58, 1, 6, 243, 209, 58, 1, 6, 242, 67, 58, 1, 6, 74, - 58, 1, 6, 235, 150, 58, 1, 6, 235, 29, 58, 1, 6, 156, 58, 1, 6, 194, 58, - 1, 6, 230, 30, 58, 1, 6, 223, 52, 230, 30, 58, 1, 6, 78, 58, 1, 6, 226, - 138, 58, 1, 6, 226, 109, 58, 1, 6, 153, 58, 1, 6, 217, 153, 58, 1, 6, 69, - 58, 1, 6, 212, 98, 58, 1, 4, 61, 58, 1, 4, 215, 94, 61, 58, 1, 4, 254, - 151, 58, 1, 4, 215, 94, 254, 252, 58, 1, 4, 253, 166, 58, 1, 4, 249, 68, - 58, 1, 4, 76, 58, 1, 4, 221, 197, 58, 1, 4, 204, 76, 58, 1, 4, 215, 94, - 204, 76, 58, 1, 4, 243, 209, 58, 1, 4, 215, 94, 74, 58, 1, 4, 235, 29, - 58, 1, 4, 194, 58, 1, 4, 245, 146, 58, 1, 4, 78, 58, 1, 4, 204, 78, 58, - 1, 4, 216, 15, 163, 78, 58, 1, 4, 251, 183, 163, 78, 58, 1, 4, 226, 109, - 58, 1, 4, 217, 153, 58, 1, 4, 69, 58, 1, 4, 219, 189, 69, 58, 1, 4, 215, - 94, 194, 58, 1, 4, 214, 105, 58, 1, 4, 254, 205, 58, 1, 4, 252, 34, 58, - 1, 4, 26, 243, 114, 58, 1, 4, 248, 62, 58, 1, 4, 26, 225, 136, 58, 1, 4, - 250, 118, 7, 218, 66, 4, 1, 74, 7, 218, 66, 4, 1, 153, 7, 218, 66, 4, 1, - 69, 7, 218, 66, 4, 1, 214, 105, 26, 218, 66, 4, 1, 252, 34, 26, 218, 66, - 4, 1, 243, 114, 26, 218, 66, 4, 1, 223, 40, 26, 218, 66, 4, 1, 225, 136, - 26, 218, 66, 4, 1, 250, 118, 7, 4, 1, 214, 214, 7, 4, 1, 57, 2, 230, 229, - 184, 7, 4, 1, 249, 69, 2, 230, 229, 184, 7, 4, 1, 245, 15, 2, 230, 229, - 184, 7, 4, 1, 232, 55, 2, 230, 229, 184, 7, 4, 1, 230, 31, 2, 230, 229, - 184, 7, 4, 1, 226, 110, 2, 230, 229, 184, 7, 4, 1, 223, 227, 2, 230, 229, - 184, 7, 4, 1, 223, 227, 2, 244, 96, 22, 230, 229, 184, 7, 4, 1, 222, 94, - 2, 230, 229, 184, 7, 4, 1, 217, 154, 2, 230, 229, 184, 7, 4, 1, 210, 160, - 2, 230, 229, 184, 7, 4, 1, 215, 94, 243, 209, 58, 1, 33, 245, 158, 7, 4, - 1, 235, 220, 243, 209, 7, 4, 1, 216, 212, 2, 218, 109, 7, 4, 6, 1, 240, - 161, 2, 91, 7, 4, 1, 235, 193, 2, 91, 7, 4, 1, 226, 110, 2, 91, 7, 4, 6, - 1, 104, 2, 91, 7, 4, 1, 214, 158, 2, 91, 7, 4, 1, 57, 2, 226, 70, 103, 7, - 4, 1, 249, 69, 2, 226, 70, 103, 7, 4, 1, 245, 15, 2, 226, 70, 103, 7, 4, - 1, 243, 210, 2, 226, 70, 103, 7, 4, 1, 235, 30, 2, 226, 70, 103, 7, 4, 1, - 233, 155, 2, 226, 70, 103, 7, 4, 1, 232, 55, 2, 226, 70, 103, 7, 4, 1, - 230, 31, 2, 226, 70, 103, 7, 4, 1, 226, 110, 2, 226, 70, 103, 7, 4, 1, - 223, 227, 2, 226, 70, 103, 7, 4, 1, 222, 94, 2, 226, 70, 103, 7, 4, 1, - 245, 84, 2, 226, 70, 103, 7, 4, 1, 214, 106, 2, 226, 70, 103, 7, 4, 1, - 211, 179, 2, 226, 70, 103, 7, 4, 1, 210, 160, 2, 226, 70, 103, 7, 4, 1, - 116, 2, 223, 58, 103, 7, 4, 1, 254, 152, 2, 223, 58, 103, 7, 4, 1, 249, - 69, 2, 241, 59, 22, 217, 78, 7, 4, 1, 160, 2, 223, 58, 103, 7, 4, 1, 204, - 160, 2, 223, 58, 103, 7, 4, 1, 223, 52, 204, 160, 2, 223, 58, 103, 7, 4, - 1, 221, 198, 2, 223, 58, 103, 7, 4, 1, 240, 161, 2, 223, 58, 103, 7, 4, - 1, 204, 144, 2, 223, 58, 103, 7, 4, 1, 245, 84, 2, 223, 58, 103, 7, 4, 1, - 104, 2, 223, 58, 103, 7, 4, 1, 245, 17, 2, 223, 58, 103, 58, 1, 4, 215, - 94, 254, 151, 58, 1, 4, 251, 74, 58, 1, 4, 251, 75, 2, 249, 108, 58, 1, - 4, 245, 67, 58, 1, 4, 223, 52, 204, 76, 58, 1, 4, 245, 14, 58, 1, 4, 247, - 127, 235, 151, 2, 91, 58, 1, 4, 119, 243, 209, 58, 1, 4, 215, 94, 242, - 67, 58, 1, 4, 240, 161, 2, 91, 58, 1, 4, 235, 192, 58, 1, 4, 6, 74, 58, - 1, 4, 6, 240, 161, 2, 91, 58, 1, 4, 235, 151, 2, 249, 135, 58, 1, 4, 233, - 155, 2, 223, 58, 103, 58, 1, 4, 233, 155, 2, 226, 70, 103, 58, 1, 4, 6, - 156, 58, 1, 4, 232, 55, 2, 103, 58, 1, 4, 215, 94, 232, 55, 2, 200, 233, - 42, 58, 1, 4, 230, 31, 2, 43, 103, 58, 1, 4, 230, 31, 2, 223, 58, 103, - 58, 1, 4, 6, 230, 30, 58, 1, 4, 252, 142, 78, 58, 1, 4, 225, 136, 58, 1, - 4, 222, 94, 2, 103, 58, 1, 4, 245, 83, 58, 1, 4, 217, 154, 2, 226, 70, - 103, 58, 1, 4, 104, 130, 58, 1, 4, 214, 157, 58, 1, 4, 6, 69, 58, 1, 4, - 214, 106, 2, 103, 58, 1, 4, 215, 94, 214, 105, 58, 1, 4, 210, 159, 58, 1, - 4, 210, 160, 2, 223, 58, 103, 58, 1, 4, 210, 160, 2, 249, 108, 58, 1, 4, - 245, 16, 58, 1, 4, 216, 180, 38, 246, 126, 242, 144, 255, 23, 38, 246, - 126, 255, 12, 255, 23, 38, 219, 71, 51, 38, 218, 7, 79, 38, 231, 236, 38, - 242, 141, 38, 231, 234, 38, 255, 10, 38, 242, 142, 38, 255, 11, 38, 7, 4, - 1, 223, 227, 51, 38, 251, 153, 38, 231, 235, 38, 52, 250, 39, 48, 38, - 226, 229, 48, 38, 210, 35, 51, 38, 235, 179, 51, 38, 214, 151, 48, 38, - 214, 134, 48, 38, 7, 4, 1, 244, 71, 204, 116, 48, 38, 7, 4, 1, 254, 252, - 38, 7, 4, 1, 254, 81, 38, 7, 4, 1, 253, 184, 38, 7, 4, 1, 251, 75, 250, - 191, 38, 7, 4, 1, 235, 220, 249, 68, 38, 7, 4, 1, 245, 67, 38, 7, 4, 1, - 243, 209, 38, 7, 1, 4, 6, 243, 209, 38, 7, 4, 1, 235, 29, 38, 7, 4, 1, - 156, 38, 7, 1, 4, 6, 156, 38, 7, 1, 4, 6, 194, 38, 7, 4, 1, 230, 30, 38, - 7, 1, 4, 6, 230, 30, 38, 7, 1, 4, 6, 153, 38, 7, 4, 1, 223, 227, 222, - 188, 38, 7, 4, 1, 222, 93, 38, 7, 4, 1, 200, 222, 93, 38, 7, 4, 1, 210, - 159, 38, 52, 235, 200, 251, 155, 51, 38, 254, 156, 128, 216, 43, 51, 38, - 43, 254, 2, 48, 38, 44, 254, 2, 22, 124, 254, 2, 51, 7, 6, 1, 116, 2, - 222, 237, 51, 7, 4, 1, 116, 2, 222, 237, 51, 7, 6, 1, 57, 2, 59, 48, 7, - 4, 1, 57, 2, 59, 48, 7, 6, 1, 57, 2, 59, 51, 7, 4, 1, 57, 2, 59, 51, 7, - 6, 1, 57, 2, 232, 220, 51, 7, 4, 1, 57, 2, 232, 220, 51, 7, 6, 1, 251, - 75, 2, 250, 192, 22, 142, 7, 4, 1, 251, 75, 2, 250, 192, 22, 142, 7, 6, - 1, 249, 69, 2, 59, 48, 7, 4, 1, 249, 69, 2, 59, 48, 7, 6, 1, 249, 69, 2, - 59, 51, 7, 4, 1, 249, 69, 2, 59, 51, 7, 6, 1, 249, 69, 2, 232, 220, 51, - 7, 4, 1, 249, 69, 2, 232, 220, 51, 7, 6, 1, 249, 69, 2, 250, 191, 7, 4, - 1, 249, 69, 2, 250, 191, 7, 6, 1, 249, 69, 2, 250, 39, 51, 7, 4, 1, 249, - 69, 2, 250, 39, 51, 7, 6, 1, 160, 2, 231, 238, 22, 242, 143, 7, 4, 1, - 160, 2, 231, 238, 22, 242, 143, 7, 6, 1, 160, 2, 231, 238, 22, 142, 7, 4, - 1, 160, 2, 231, 238, 22, 142, 7, 6, 1, 160, 2, 250, 39, 51, 7, 4, 1, 160, - 2, 250, 39, 51, 7, 6, 1, 160, 2, 216, 90, 51, 7, 4, 1, 160, 2, 216, 90, - 51, 7, 6, 1, 160, 2, 250, 192, 22, 251, 154, 7, 4, 1, 160, 2, 250, 192, - 22, 251, 154, 7, 6, 1, 245, 15, 2, 59, 48, 7, 4, 1, 245, 15, 2, 59, 48, - 7, 6, 1, 243, 210, 2, 231, 237, 7, 4, 1, 243, 210, 2, 231, 237, 7, 6, 1, - 242, 68, 2, 59, 48, 7, 4, 1, 242, 68, 2, 59, 48, 7, 6, 1, 242, 68, 2, 59, - 51, 7, 4, 1, 242, 68, 2, 59, 51, 7, 6, 1, 242, 68, 2, 248, 9, 7, 4, 1, - 242, 68, 2, 248, 9, 7, 6, 1, 242, 68, 2, 250, 191, 7, 4, 1, 242, 68, 2, - 250, 191, 7, 6, 1, 242, 68, 2, 251, 155, 51, 7, 4, 1, 242, 68, 2, 251, - 155, 51, 7, 6, 1, 240, 161, 2, 216, 90, 51, 7, 4, 1, 240, 161, 2, 216, - 90, 51, 7, 6, 1, 240, 161, 2, 248, 10, 22, 142, 7, 4, 1, 240, 161, 2, - 248, 10, 22, 142, 7, 6, 1, 235, 30, 2, 142, 7, 4, 1, 235, 30, 2, 142, 7, - 6, 1, 235, 30, 2, 59, 51, 7, 4, 1, 235, 30, 2, 59, 51, 7, 6, 1, 235, 30, - 2, 232, 220, 51, 7, 4, 1, 235, 30, 2, 232, 220, 51, 7, 6, 1, 233, 155, 2, - 59, 51, 7, 4, 1, 233, 155, 2, 59, 51, 7, 6, 1, 233, 155, 2, 59, 252, 51, - 22, 231, 237, 7, 4, 1, 233, 155, 2, 59, 252, 51, 22, 231, 237, 7, 6, 1, - 233, 155, 2, 232, 220, 51, 7, 4, 1, 233, 155, 2, 232, 220, 51, 7, 6, 1, - 233, 155, 2, 250, 39, 51, 7, 4, 1, 233, 155, 2, 250, 39, 51, 7, 6, 1, - 232, 55, 2, 142, 7, 4, 1, 232, 55, 2, 142, 7, 6, 1, 232, 55, 2, 59, 48, - 7, 4, 1, 232, 55, 2, 59, 48, 7, 6, 1, 232, 55, 2, 59, 51, 7, 4, 1, 232, - 55, 2, 59, 51, 7, 6, 1, 230, 31, 2, 59, 48, 7, 4, 1, 230, 31, 2, 59, 48, - 7, 6, 1, 230, 31, 2, 59, 51, 7, 4, 1, 230, 31, 2, 59, 51, 7, 6, 1, 230, - 31, 2, 232, 220, 51, 7, 4, 1, 230, 31, 2, 232, 220, 51, 7, 6, 1, 230, 31, - 2, 250, 39, 51, 7, 4, 1, 230, 31, 2, 250, 39, 51, 7, 6, 1, 144, 2, 216, - 90, 22, 142, 7, 4, 1, 144, 2, 216, 90, 22, 142, 7, 6, 1, 144, 2, 216, 90, - 22, 248, 9, 7, 4, 1, 144, 2, 216, 90, 22, 248, 9, 7, 6, 1, 144, 2, 231, - 238, 22, 242, 143, 7, 4, 1, 144, 2, 231, 238, 22, 242, 143, 7, 6, 1, 144, - 2, 231, 238, 22, 142, 7, 4, 1, 144, 2, 231, 238, 22, 142, 7, 6, 1, 226, - 110, 2, 142, 7, 4, 1, 226, 110, 2, 142, 7, 6, 1, 226, 110, 2, 59, 48, 7, - 4, 1, 226, 110, 2, 59, 48, 7, 6, 1, 223, 227, 2, 59, 48, 7, 4, 1, 223, - 227, 2, 59, 48, 7, 6, 1, 223, 227, 2, 59, 51, 7, 4, 1, 223, 227, 2, 59, - 51, 7, 6, 1, 223, 227, 2, 59, 252, 51, 22, 231, 237, 7, 4, 1, 223, 227, - 2, 59, 252, 51, 22, 231, 237, 7, 6, 1, 223, 227, 2, 232, 220, 51, 7, 4, - 1, 223, 227, 2, 232, 220, 51, 7, 6, 1, 222, 94, 2, 59, 48, 7, 4, 1, 222, - 94, 2, 59, 48, 7, 6, 1, 222, 94, 2, 59, 51, 7, 4, 1, 222, 94, 2, 59, 51, - 7, 6, 1, 222, 94, 2, 255, 12, 22, 59, 48, 7, 4, 1, 222, 94, 2, 255, 12, - 22, 59, 48, 7, 6, 1, 222, 94, 2, 250, 243, 22, 59, 48, 7, 4, 1, 222, 94, - 2, 250, 243, 22, 59, 48, 7, 6, 1, 222, 94, 2, 59, 252, 51, 22, 59, 48, 7, - 4, 1, 222, 94, 2, 59, 252, 51, 22, 59, 48, 7, 6, 1, 217, 154, 2, 59, 48, - 7, 4, 1, 217, 154, 2, 59, 48, 7, 6, 1, 217, 154, 2, 59, 51, 7, 4, 1, 217, - 154, 2, 59, 51, 7, 6, 1, 217, 154, 2, 232, 220, 51, 7, 4, 1, 217, 154, 2, - 232, 220, 51, 7, 6, 1, 217, 154, 2, 250, 39, 51, 7, 4, 1, 217, 154, 2, - 250, 39, 51, 7, 6, 1, 104, 2, 248, 10, 51, 7, 4, 1, 104, 2, 248, 10, 51, - 7, 6, 1, 104, 2, 216, 90, 51, 7, 4, 1, 104, 2, 216, 90, 51, 7, 6, 1, 104, - 2, 250, 39, 51, 7, 4, 1, 104, 2, 250, 39, 51, 7, 6, 1, 104, 2, 216, 90, - 22, 142, 7, 4, 1, 104, 2, 216, 90, 22, 142, 7, 6, 1, 104, 2, 231, 238, - 22, 248, 9, 7, 4, 1, 104, 2, 231, 238, 22, 248, 9, 7, 6, 1, 214, 106, 2, - 184, 7, 4, 1, 214, 106, 2, 184, 7, 6, 1, 214, 106, 2, 59, 51, 7, 4, 1, - 214, 106, 2, 59, 51, 7, 6, 1, 212, 99, 2, 242, 143, 7, 4, 1, 212, 99, 2, - 242, 143, 7, 6, 1, 212, 99, 2, 142, 7, 4, 1, 212, 99, 2, 142, 7, 6, 1, - 212, 99, 2, 248, 9, 7, 4, 1, 212, 99, 2, 248, 9, 7, 6, 1, 212, 99, 2, 59, - 48, 7, 4, 1, 212, 99, 2, 59, 48, 7, 6, 1, 212, 99, 2, 59, 51, 7, 4, 1, - 212, 99, 2, 59, 51, 7, 6, 1, 211, 179, 2, 59, 48, 7, 4, 1, 211, 179, 2, - 59, 48, 7, 6, 1, 211, 179, 2, 248, 9, 7, 4, 1, 211, 179, 2, 248, 9, 7, 6, - 1, 211, 118, 2, 59, 48, 7, 4, 1, 211, 118, 2, 59, 48, 7, 6, 1, 210, 160, - 2, 250, 38, 7, 4, 1, 210, 160, 2, 250, 38, 7, 6, 1, 210, 160, 2, 59, 51, - 7, 4, 1, 210, 160, 2, 59, 51, 7, 6, 1, 210, 160, 2, 232, 220, 51, 7, 4, - 1, 210, 160, 2, 232, 220, 51, 7, 4, 1, 242, 68, 2, 232, 220, 51, 7, 4, 1, - 217, 154, 2, 248, 9, 7, 4, 1, 212, 99, 2, 222, 237, 48, 7, 4, 1, 211, - 118, 2, 222, 237, 48, 7, 4, 1, 116, 2, 44, 163, 222, 236, 7, 4, 1, 200, - 222, 94, 2, 59, 48, 7, 4, 1, 200, 222, 94, 2, 248, 7, 91, 7, 4, 1, 200, - 222, 94, 2, 125, 91, 7, 6, 1, 220, 78, 222, 93, 7, 4, 1, 248, 62, 7, 6, - 1, 116, 2, 59, 51, 7, 4, 1, 116, 2, 59, 51, 7, 6, 1, 116, 2, 241, 59, 48, - 7, 4, 1, 116, 2, 241, 59, 48, 7, 6, 1, 116, 2, 250, 39, 22, 142, 7, 4, 1, - 116, 2, 250, 39, 22, 142, 7, 6, 1, 116, 2, 250, 39, 22, 242, 143, 7, 4, - 1, 116, 2, 250, 39, 22, 242, 143, 7, 6, 1, 116, 2, 250, 39, 22, 241, 59, - 48, 7, 4, 1, 116, 2, 250, 39, 22, 241, 59, 48, 7, 6, 1, 116, 2, 250, 39, - 22, 184, 7, 4, 1, 116, 2, 250, 39, 22, 184, 7, 6, 1, 116, 2, 250, 39, 22, - 59, 51, 7, 4, 1, 116, 2, 250, 39, 22, 59, 51, 7, 6, 1, 116, 2, 251, 155, - 22, 142, 7, 4, 1, 116, 2, 251, 155, 22, 142, 7, 6, 1, 116, 2, 251, 155, - 22, 242, 143, 7, 4, 1, 116, 2, 251, 155, 22, 242, 143, 7, 6, 1, 116, 2, - 251, 155, 22, 241, 59, 48, 7, 4, 1, 116, 2, 251, 155, 22, 241, 59, 48, 7, - 6, 1, 116, 2, 251, 155, 22, 184, 7, 4, 1, 116, 2, 251, 155, 22, 184, 7, - 6, 1, 116, 2, 251, 155, 22, 59, 51, 7, 4, 1, 116, 2, 251, 155, 22, 59, - 51, 7, 6, 1, 160, 2, 59, 51, 7, 4, 1, 160, 2, 59, 51, 7, 6, 1, 160, 2, - 241, 59, 48, 7, 4, 1, 160, 2, 241, 59, 48, 7, 6, 1, 160, 2, 184, 7, 4, 1, - 160, 2, 184, 7, 6, 1, 160, 2, 250, 39, 22, 142, 7, 4, 1, 160, 2, 250, 39, - 22, 142, 7, 6, 1, 160, 2, 250, 39, 22, 242, 143, 7, 4, 1, 160, 2, 250, - 39, 22, 242, 143, 7, 6, 1, 160, 2, 250, 39, 22, 241, 59, 48, 7, 4, 1, - 160, 2, 250, 39, 22, 241, 59, 48, 7, 6, 1, 160, 2, 250, 39, 22, 184, 7, - 4, 1, 160, 2, 250, 39, 22, 184, 7, 6, 1, 160, 2, 250, 39, 22, 59, 51, 7, - 4, 1, 160, 2, 250, 39, 22, 59, 51, 7, 6, 1, 240, 161, 2, 241, 59, 48, 7, - 4, 1, 240, 161, 2, 241, 59, 48, 7, 6, 1, 240, 161, 2, 59, 51, 7, 4, 1, - 240, 161, 2, 59, 51, 7, 6, 1, 144, 2, 59, 51, 7, 4, 1, 144, 2, 59, 51, 7, - 6, 1, 144, 2, 241, 59, 48, 7, 4, 1, 144, 2, 241, 59, 48, 7, 6, 1, 144, 2, - 250, 39, 22, 142, 7, 4, 1, 144, 2, 250, 39, 22, 142, 7, 6, 1, 144, 2, - 250, 39, 22, 242, 143, 7, 4, 1, 144, 2, 250, 39, 22, 242, 143, 7, 6, 1, - 144, 2, 250, 39, 22, 241, 59, 48, 7, 4, 1, 144, 2, 250, 39, 22, 241, 59, - 48, 7, 6, 1, 144, 2, 250, 39, 22, 184, 7, 4, 1, 144, 2, 250, 39, 22, 184, - 7, 6, 1, 144, 2, 250, 39, 22, 59, 51, 7, 4, 1, 144, 2, 250, 39, 22, 59, - 51, 7, 6, 1, 144, 2, 241, 0, 22, 142, 7, 4, 1, 144, 2, 241, 0, 22, 142, - 7, 6, 1, 144, 2, 241, 0, 22, 242, 143, 7, 4, 1, 144, 2, 241, 0, 22, 242, - 143, 7, 6, 1, 144, 2, 241, 0, 22, 241, 59, 48, 7, 4, 1, 144, 2, 241, 0, - 22, 241, 59, 48, 7, 6, 1, 144, 2, 241, 0, 22, 184, 7, 4, 1, 144, 2, 241, - 0, 22, 184, 7, 6, 1, 144, 2, 241, 0, 22, 59, 51, 7, 4, 1, 144, 2, 241, 0, - 22, 59, 51, 7, 6, 1, 104, 2, 59, 51, 7, 4, 1, 104, 2, 59, 51, 7, 6, 1, - 104, 2, 241, 59, 48, 7, 4, 1, 104, 2, 241, 59, 48, 7, 6, 1, 104, 2, 241, - 0, 22, 142, 7, 4, 1, 104, 2, 241, 0, 22, 142, 7, 6, 1, 104, 2, 241, 0, - 22, 242, 143, 7, 4, 1, 104, 2, 241, 0, 22, 242, 143, 7, 6, 1, 104, 2, - 241, 0, 22, 241, 59, 48, 7, 4, 1, 104, 2, 241, 0, 22, 241, 59, 48, 7, 6, - 1, 104, 2, 241, 0, 22, 184, 7, 4, 1, 104, 2, 241, 0, 22, 184, 7, 6, 1, - 104, 2, 241, 0, 22, 59, 51, 7, 4, 1, 104, 2, 241, 0, 22, 59, 51, 7, 6, 1, - 211, 118, 2, 242, 143, 7, 4, 1, 211, 118, 2, 242, 143, 7, 6, 1, 211, 118, - 2, 59, 51, 7, 4, 1, 211, 118, 2, 59, 51, 7, 6, 1, 211, 118, 2, 241, 59, - 48, 7, 4, 1, 211, 118, 2, 241, 59, 48, 7, 6, 1, 211, 118, 2, 184, 7, 4, - 1, 211, 118, 2, 184, 7, 6, 1, 230, 228, 232, 191, 7, 4, 1, 230, 228, 232, - 191, 7, 6, 1, 230, 228, 214, 105, 7, 4, 1, 230, 228, 214, 105, 7, 6, 1, - 211, 118, 2, 232, 129, 7, 4, 1, 211, 118, 2, 232, 129, 26, 4, 1, 254, - 152, 2, 224, 157, 26, 4, 1, 254, 152, 2, 248, 161, 26, 4, 1, 254, 152, 2, - 224, 158, 22, 214, 13, 26, 4, 1, 254, 152, 2, 248, 162, 22, 214, 13, 26, - 4, 1, 254, 152, 2, 224, 158, 22, 226, 114, 26, 4, 1, 254, 152, 2, 248, - 162, 22, 226, 114, 26, 4, 1, 254, 152, 2, 224, 158, 22, 225, 178, 26, 4, - 1, 254, 152, 2, 248, 162, 22, 225, 178, 26, 6, 1, 254, 152, 2, 224, 157, - 26, 6, 1, 254, 152, 2, 248, 161, 26, 6, 1, 254, 152, 2, 224, 158, 22, - 214, 13, 26, 6, 1, 254, 152, 2, 248, 162, 22, 214, 13, 26, 6, 1, 254, - 152, 2, 224, 158, 22, 226, 114, 26, 6, 1, 254, 152, 2, 248, 162, 22, 226, - 114, 26, 6, 1, 254, 152, 2, 224, 158, 22, 225, 178, 26, 6, 1, 254, 152, - 2, 248, 162, 22, 225, 178, 26, 4, 1, 245, 109, 2, 224, 157, 26, 4, 1, - 245, 109, 2, 248, 161, 26, 4, 1, 245, 109, 2, 224, 158, 22, 214, 13, 26, - 4, 1, 245, 109, 2, 248, 162, 22, 214, 13, 26, 4, 1, 245, 109, 2, 224, - 158, 22, 226, 114, 26, 4, 1, 245, 109, 2, 248, 162, 22, 226, 114, 26, 6, - 1, 245, 109, 2, 224, 157, 26, 6, 1, 245, 109, 2, 248, 161, 26, 6, 1, 245, - 109, 2, 224, 158, 22, 214, 13, 26, 6, 1, 245, 109, 2, 248, 162, 22, 214, - 13, 26, 6, 1, 245, 109, 2, 224, 158, 22, 226, 114, 26, 6, 1, 245, 109, 2, - 248, 162, 22, 226, 114, 26, 4, 1, 245, 72, 2, 224, 157, 26, 4, 1, 245, - 72, 2, 248, 161, 26, 4, 1, 245, 72, 2, 224, 158, 22, 214, 13, 26, 4, 1, - 245, 72, 2, 248, 162, 22, 214, 13, 26, 4, 1, 245, 72, 2, 224, 158, 22, - 226, 114, 26, 4, 1, 245, 72, 2, 248, 162, 22, 226, 114, 26, 4, 1, 245, - 72, 2, 224, 158, 22, 225, 178, 26, 4, 1, 245, 72, 2, 248, 162, 22, 225, - 178, 26, 6, 1, 245, 72, 2, 224, 157, 26, 6, 1, 245, 72, 2, 248, 161, 26, - 6, 1, 245, 72, 2, 224, 158, 22, 214, 13, 26, 6, 1, 245, 72, 2, 248, 162, - 22, 214, 13, 26, 6, 1, 245, 72, 2, 224, 158, 22, 226, 114, 26, 6, 1, 245, - 72, 2, 248, 162, 22, 226, 114, 26, 6, 1, 245, 72, 2, 224, 158, 22, 225, - 178, 26, 6, 1, 245, 72, 2, 248, 162, 22, 225, 178, 26, 4, 1, 235, 193, 2, - 224, 157, 26, 4, 1, 235, 193, 2, 248, 161, 26, 4, 1, 235, 193, 2, 224, - 158, 22, 214, 13, 26, 4, 1, 235, 193, 2, 248, 162, 22, 214, 13, 26, 4, 1, - 235, 193, 2, 224, 158, 22, 226, 114, 26, 4, 1, 235, 193, 2, 248, 162, 22, - 226, 114, 26, 4, 1, 235, 193, 2, 224, 158, 22, 225, 178, 26, 4, 1, 235, - 193, 2, 248, 162, 22, 225, 178, 26, 6, 1, 235, 193, 2, 224, 157, 26, 6, - 1, 235, 193, 2, 248, 161, 26, 6, 1, 235, 193, 2, 224, 158, 22, 214, 13, - 26, 6, 1, 235, 193, 2, 248, 162, 22, 214, 13, 26, 6, 1, 235, 193, 2, 224, - 158, 22, 226, 114, 26, 6, 1, 235, 193, 2, 248, 162, 22, 226, 114, 26, 6, - 1, 235, 193, 2, 224, 158, 22, 225, 178, 26, 6, 1, 235, 193, 2, 248, 162, - 22, 225, 178, 26, 4, 1, 226, 204, 2, 224, 157, 26, 4, 1, 226, 204, 2, - 248, 161, 26, 4, 1, 226, 204, 2, 224, 158, 22, 214, 13, 26, 4, 1, 226, - 204, 2, 248, 162, 22, 214, 13, 26, 4, 1, 226, 204, 2, 224, 158, 22, 226, - 114, 26, 4, 1, 226, 204, 2, 248, 162, 22, 226, 114, 26, 6, 1, 226, 204, - 2, 224, 157, 26, 6, 1, 226, 204, 2, 248, 161, 26, 6, 1, 226, 204, 2, 224, - 158, 22, 214, 13, 26, 6, 1, 226, 204, 2, 248, 162, 22, 214, 13, 26, 6, 1, - 226, 204, 2, 224, 158, 22, 226, 114, 26, 6, 1, 226, 204, 2, 248, 162, 22, - 226, 114, 26, 4, 1, 214, 158, 2, 224, 157, 26, 4, 1, 214, 158, 2, 248, - 161, 26, 4, 1, 214, 158, 2, 224, 158, 22, 214, 13, 26, 4, 1, 214, 158, 2, - 248, 162, 22, 214, 13, 26, 4, 1, 214, 158, 2, 224, 158, 22, 226, 114, 26, - 4, 1, 214, 158, 2, 248, 162, 22, 226, 114, 26, 4, 1, 214, 158, 2, 224, - 158, 22, 225, 178, 26, 4, 1, 214, 158, 2, 248, 162, 22, 225, 178, 26, 6, - 1, 214, 158, 2, 248, 161, 26, 6, 1, 214, 158, 2, 248, 162, 22, 214, 13, - 26, 6, 1, 214, 158, 2, 248, 162, 22, 226, 114, 26, 6, 1, 214, 158, 2, - 248, 162, 22, 225, 178, 26, 4, 1, 226, 206, 2, 224, 157, 26, 4, 1, 226, - 206, 2, 248, 161, 26, 4, 1, 226, 206, 2, 224, 158, 22, 214, 13, 26, 4, 1, - 226, 206, 2, 248, 162, 22, 214, 13, 26, 4, 1, 226, 206, 2, 224, 158, 22, - 226, 114, 26, 4, 1, 226, 206, 2, 248, 162, 22, 226, 114, 26, 4, 1, 226, - 206, 2, 224, 158, 22, 225, 178, 26, 4, 1, 226, 206, 2, 248, 162, 22, 225, - 178, 26, 6, 1, 226, 206, 2, 224, 157, 26, 6, 1, 226, 206, 2, 248, 161, - 26, 6, 1, 226, 206, 2, 224, 158, 22, 214, 13, 26, 6, 1, 226, 206, 2, 248, - 162, 22, 214, 13, 26, 6, 1, 226, 206, 2, 224, 158, 22, 226, 114, 26, 6, - 1, 226, 206, 2, 248, 162, 22, 226, 114, 26, 6, 1, 226, 206, 2, 224, 158, - 22, 225, 178, 26, 6, 1, 226, 206, 2, 248, 162, 22, 225, 178, 26, 4, 1, - 254, 152, 2, 214, 13, 26, 4, 1, 254, 152, 2, 226, 114, 26, 4, 1, 245, - 109, 2, 214, 13, 26, 4, 1, 245, 109, 2, 226, 114, 26, 4, 1, 245, 72, 2, - 214, 13, 26, 4, 1, 245, 72, 2, 226, 114, 26, 4, 1, 235, 193, 2, 214, 13, - 26, 4, 1, 235, 193, 2, 226, 114, 26, 4, 1, 226, 204, 2, 214, 13, 26, 4, - 1, 226, 204, 2, 226, 114, 26, 4, 1, 214, 158, 2, 214, 13, 26, 4, 1, 214, - 158, 2, 226, 114, 26, 4, 1, 226, 206, 2, 214, 13, 26, 4, 1, 226, 206, 2, - 226, 114, 26, 4, 1, 254, 152, 2, 224, 158, 22, 210, 219, 26, 4, 1, 254, - 152, 2, 248, 162, 22, 210, 219, 26, 4, 1, 254, 152, 2, 224, 158, 22, 214, - 14, 22, 210, 219, 26, 4, 1, 254, 152, 2, 248, 162, 22, 214, 14, 22, 210, - 219, 26, 4, 1, 254, 152, 2, 224, 158, 22, 226, 115, 22, 210, 219, 26, 4, - 1, 254, 152, 2, 248, 162, 22, 226, 115, 22, 210, 219, 26, 4, 1, 254, 152, - 2, 224, 158, 22, 225, 179, 22, 210, 219, 26, 4, 1, 254, 152, 2, 248, 162, - 22, 225, 179, 22, 210, 219, 26, 6, 1, 254, 152, 2, 224, 158, 22, 224, - 170, 26, 6, 1, 254, 152, 2, 248, 162, 22, 224, 170, 26, 6, 1, 254, 152, - 2, 224, 158, 22, 214, 14, 22, 224, 170, 26, 6, 1, 254, 152, 2, 248, 162, - 22, 214, 14, 22, 224, 170, 26, 6, 1, 254, 152, 2, 224, 158, 22, 226, 115, - 22, 224, 170, 26, 6, 1, 254, 152, 2, 248, 162, 22, 226, 115, 22, 224, - 170, 26, 6, 1, 254, 152, 2, 224, 158, 22, 225, 179, 22, 224, 170, 26, 6, - 1, 254, 152, 2, 248, 162, 22, 225, 179, 22, 224, 170, 26, 4, 1, 245, 72, - 2, 224, 158, 22, 210, 219, 26, 4, 1, 245, 72, 2, 248, 162, 22, 210, 219, - 26, 4, 1, 245, 72, 2, 224, 158, 22, 214, 14, 22, 210, 219, 26, 4, 1, 245, - 72, 2, 248, 162, 22, 214, 14, 22, 210, 219, 26, 4, 1, 245, 72, 2, 224, - 158, 22, 226, 115, 22, 210, 219, 26, 4, 1, 245, 72, 2, 248, 162, 22, 226, - 115, 22, 210, 219, 26, 4, 1, 245, 72, 2, 224, 158, 22, 225, 179, 22, 210, - 219, 26, 4, 1, 245, 72, 2, 248, 162, 22, 225, 179, 22, 210, 219, 26, 6, - 1, 245, 72, 2, 224, 158, 22, 224, 170, 26, 6, 1, 245, 72, 2, 248, 162, - 22, 224, 170, 26, 6, 1, 245, 72, 2, 224, 158, 22, 214, 14, 22, 224, 170, - 26, 6, 1, 245, 72, 2, 248, 162, 22, 214, 14, 22, 224, 170, 26, 6, 1, 245, - 72, 2, 224, 158, 22, 226, 115, 22, 224, 170, 26, 6, 1, 245, 72, 2, 248, - 162, 22, 226, 115, 22, 224, 170, 26, 6, 1, 245, 72, 2, 224, 158, 22, 225, - 179, 22, 224, 170, 26, 6, 1, 245, 72, 2, 248, 162, 22, 225, 179, 22, 224, - 170, 26, 4, 1, 226, 206, 2, 224, 158, 22, 210, 219, 26, 4, 1, 226, 206, - 2, 248, 162, 22, 210, 219, 26, 4, 1, 226, 206, 2, 224, 158, 22, 214, 14, - 22, 210, 219, 26, 4, 1, 226, 206, 2, 248, 162, 22, 214, 14, 22, 210, 219, - 26, 4, 1, 226, 206, 2, 224, 158, 22, 226, 115, 22, 210, 219, 26, 4, 1, - 226, 206, 2, 248, 162, 22, 226, 115, 22, 210, 219, 26, 4, 1, 226, 206, 2, - 224, 158, 22, 225, 179, 22, 210, 219, 26, 4, 1, 226, 206, 2, 248, 162, - 22, 225, 179, 22, 210, 219, 26, 6, 1, 226, 206, 2, 224, 158, 22, 224, - 170, 26, 6, 1, 226, 206, 2, 248, 162, 22, 224, 170, 26, 6, 1, 226, 206, - 2, 224, 158, 22, 214, 14, 22, 224, 170, 26, 6, 1, 226, 206, 2, 248, 162, - 22, 214, 14, 22, 224, 170, 26, 6, 1, 226, 206, 2, 224, 158, 22, 226, 115, - 22, 224, 170, 26, 6, 1, 226, 206, 2, 248, 162, 22, 226, 115, 22, 224, - 170, 26, 6, 1, 226, 206, 2, 224, 158, 22, 225, 179, 22, 224, 170, 26, 6, - 1, 226, 206, 2, 248, 162, 22, 225, 179, 22, 224, 170, 26, 4, 1, 254, 152, - 2, 213, 120, 26, 4, 1, 254, 152, 2, 231, 237, 26, 4, 1, 254, 152, 2, 214, - 14, 22, 210, 219, 26, 4, 1, 254, 152, 2, 210, 219, 26, 4, 1, 254, 152, 2, - 226, 115, 22, 210, 219, 26, 4, 1, 254, 152, 2, 225, 178, 26, 4, 1, 254, - 152, 2, 225, 179, 22, 210, 219, 26, 6, 1, 254, 152, 2, 213, 120, 26, 6, - 1, 254, 152, 2, 231, 237, 26, 6, 1, 254, 152, 2, 214, 13, 26, 6, 1, 254, - 152, 2, 226, 114, 26, 6, 1, 254, 152, 2, 224, 170, 26, 234, 8, 26, 224, - 170, 26, 224, 157, 26, 225, 178, 26, 248, 4, 22, 225, 178, 26, 4, 1, 245, - 72, 2, 214, 14, 22, 210, 219, 26, 4, 1, 245, 72, 2, 210, 219, 26, 4, 1, - 245, 72, 2, 226, 115, 22, 210, 219, 26, 4, 1, 245, 72, 2, 225, 178, 26, - 4, 1, 245, 72, 2, 225, 179, 22, 210, 219, 26, 6, 1, 245, 109, 2, 214, 13, - 26, 6, 1, 245, 109, 2, 226, 114, 26, 6, 1, 245, 72, 2, 214, 13, 26, 6, 1, - 245, 72, 2, 226, 114, 26, 6, 1, 245, 72, 2, 224, 170, 26, 224, 158, 22, - 214, 13, 26, 224, 158, 22, 226, 114, 26, 224, 158, 22, 225, 178, 26, 4, - 1, 235, 193, 2, 213, 120, 26, 4, 1, 235, 193, 2, 231, 237, 26, 4, 1, 235, - 193, 2, 248, 4, 22, 214, 13, 26, 4, 1, 235, 193, 2, 248, 4, 22, 226, 114, - 26, 4, 1, 235, 193, 2, 225, 178, 26, 4, 1, 235, 193, 2, 248, 4, 22, 225, - 178, 26, 6, 1, 235, 193, 2, 213, 120, 26, 6, 1, 235, 193, 2, 231, 237, - 26, 6, 1, 235, 193, 2, 214, 13, 26, 6, 1, 235, 193, 2, 226, 114, 26, 248, - 162, 22, 214, 13, 26, 248, 162, 22, 226, 114, 26, 248, 162, 22, 225, 178, - 26, 4, 1, 214, 158, 2, 213, 120, 26, 4, 1, 214, 158, 2, 231, 237, 26, 4, - 1, 214, 158, 2, 248, 4, 22, 214, 13, 26, 4, 1, 214, 158, 2, 248, 4, 22, - 226, 114, 26, 4, 1, 223, 41, 2, 224, 157, 26, 4, 1, 223, 41, 2, 248, 161, - 26, 4, 1, 214, 158, 2, 225, 178, 26, 4, 1, 214, 158, 2, 248, 4, 22, 225, - 178, 26, 6, 1, 214, 158, 2, 213, 120, 26, 6, 1, 214, 158, 2, 231, 237, - 26, 6, 1, 214, 158, 2, 214, 13, 26, 6, 1, 214, 158, 2, 226, 114, 26, 6, - 1, 223, 41, 2, 248, 161, 26, 248, 4, 22, 214, 13, 26, 248, 4, 22, 226, - 114, 26, 214, 13, 26, 4, 1, 226, 206, 2, 214, 14, 22, 210, 219, 26, 4, 1, - 226, 206, 2, 210, 219, 26, 4, 1, 226, 206, 2, 226, 115, 22, 210, 219, 26, - 4, 1, 226, 206, 2, 225, 178, 26, 4, 1, 226, 206, 2, 225, 179, 22, 210, - 219, 26, 6, 1, 226, 204, 2, 214, 13, 26, 6, 1, 226, 204, 2, 226, 114, 26, - 6, 1, 226, 206, 2, 214, 13, 26, 6, 1, 226, 206, 2, 226, 114, 26, 6, 1, - 226, 206, 2, 224, 170, 26, 226, 114, 26, 248, 161, 245, 159, 224, 30, - 245, 168, 224, 30, 245, 159, 219, 20, 245, 168, 219, 20, 216, 142, 219, - 20, 244, 17, 219, 20, 219, 125, 219, 20, 244, 120, 219, 20, 224, 144, - 219, 20, 216, 171, 219, 20, 242, 42, 219, 20, 210, 87, 211, 245, 219, 20, - 210, 87, 211, 245, 228, 72, 210, 87, 211, 245, 235, 69, 233, 44, 79, 222, - 246, 79, 240, 175, 228, 73, 240, 175, 244, 120, 248, 164, 245, 159, 248, - 164, 245, 168, 248, 164, 203, 130, 52, 67, 232, 219, 52, 121, 232, 219, - 43, 219, 157, 224, 1, 79, 44, 219, 157, 224, 1, 79, 219, 157, 232, 115, - 224, 1, 79, 219, 157, 241, 170, 224, 1, 79, 43, 52, 224, 1, 79, 44, 52, - 224, 1, 79, 52, 232, 115, 224, 1, 79, 52, 241, 170, 224, 1, 79, 248, 213, - 52, 248, 213, 251, 121, 215, 223, 251, 121, 123, 59, 233, 62, 113, 59, - 233, 62, 203, 245, 171, 240, 173, 225, 13, 232, 220, 220, 139, 226, 19, - 220, 139, 233, 44, 245, 166, 222, 246, 245, 166, 224, 249, 247, 204, 244, - 27, 233, 44, 226, 121, 222, 246, 226, 121, 229, 199, 228, 78, 219, 20, - 225, 186, 230, 198, 50, 225, 186, 216, 249, 216, 149, 50, 224, 193, 52, - 224, 193, 215, 212, 224, 193, 223, 52, 224, 193, 223, 52, 52, 224, 193, - 223, 52, 215, 212, 224, 193, 250, 246, 219, 157, 233, 48, 254, 118, 224, - 1, 79, 219, 157, 222, 250, 254, 118, 224, 1, 79, 223, 110, 79, 52, 245, - 39, 79, 235, 208, 226, 123, 214, 180, 135, 216, 112, 250, 247, 235, 223, - 225, 13, 253, 222, 240, 176, 251, 121, 244, 10, 219, 97, 43, 42, 251, - 166, 2, 224, 10, 44, 42, 251, 166, 2, 224, 10, 52, 224, 16, 79, 224, 16, - 245, 39, 79, 245, 39, 224, 16, 79, 216, 71, 5, 245, 73, 223, 52, 225, 71, - 50, 85, 140, 251, 121, 85, 97, 251, 121, 121, 253, 224, 223, 52, 220, - 152, 250, 9, 214, 163, 113, 253, 223, 254, 167, 213, 188, 249, 225, 230, - 187, 50, 217, 235, 248, 164, 235, 200, 214, 180, 244, 60, 224, 144, 79, - 134, 59, 224, 143, 224, 27, 224, 193, 244, 19, 59, 224, 143, 244, 89, 59, - 224, 143, 113, 59, 224, 143, 244, 19, 59, 79, 246, 126, 249, 138, 215, - 222, 67, 244, 19, 247, 126, 231, 87, 11, 219, 20, 211, 209, 235, 69, 243, - 234, 254, 60, 235, 198, 216, 86, 235, 198, 220, 139, 235, 198, 225, 25, - 233, 44, 235, 171, 222, 246, 235, 171, 244, 100, 218, 91, 235, 171, 224, - 249, 247, 204, 235, 171, 235, 235, 217, 183, 217, 252, 255, 14, 217, 183, - 217, 252, 235, 235, 9, 244, 28, 220, 82, 255, 14, 9, 244, 28, 220, 82, - 229, 194, 21, 220, 83, 228, 74, 21, 220, 83, 218, 24, 210, 86, 218, 24, - 7, 4, 1, 74, 218, 24, 161, 218, 24, 190, 218, 24, 195, 218, 24, 199, 218, - 24, 196, 218, 24, 201, 218, 24, 96, 50, 218, 24, 230, 186, 218, 24, 245, - 106, 50, 218, 24, 43, 226, 7, 218, 24, 44, 226, 7, 218, 24, 7, 4, 1, 230, - 30, 218, 66, 210, 86, 218, 66, 111, 218, 66, 105, 218, 66, 158, 218, 66, - 161, 218, 66, 190, 218, 66, 195, 218, 66, 199, 218, 66, 196, 218, 66, - 201, 218, 66, 96, 50, 218, 66, 230, 186, 218, 66, 245, 106, 50, 218, 66, - 43, 226, 7, 218, 66, 44, 226, 7, 7, 218, 66, 4, 1, 61, 7, 218, 66, 4, 1, - 76, 7, 218, 66, 4, 1, 78, 7, 218, 66, 4, 1, 211, 178, 7, 218, 66, 4, 1, - 221, 197, 7, 218, 66, 4, 1, 242, 67, 7, 218, 66, 4, 1, 235, 29, 7, 218, - 66, 4, 1, 156, 7, 218, 66, 4, 1, 194, 7, 218, 66, 4, 1, 230, 30, 7, 218, - 66, 4, 1, 226, 109, 7, 218, 66, 4, 1, 222, 93, 7, 218, 66, 4, 1, 217, - 153, 245, 54, 50, 249, 235, 50, 249, 125, 50, 244, 3, 244, 6, 50, 232, - 204, 50, 230, 199, 50, 229, 215, 50, 225, 165, 50, 222, 120, 50, 211, - 217, 50, 166, 220, 51, 50, 247, 135, 50, 245, 55, 50, 234, 82, 50, 215, - 113, 50, 246, 109, 50, 243, 47, 225, 196, 50, 225, 163, 50, 242, 116, 50, - 253, 190, 50, 240, 235, 50, 250, 193, 50, 232, 197, 216, 4, 50, 219, 2, - 50, 216, 246, 50, 235, 248, 222, 120, 50, 215, 97, 232, 204, 50, 38, 43, - 242, 6, 48, 38, 44, 242, 6, 48, 38, 200, 67, 232, 220, 226, 124, 38, 219, - 253, 67, 232, 220, 226, 124, 38, 254, 96, 80, 48, 38, 250, 10, 80, 48, - 38, 43, 80, 48, 38, 44, 80, 48, 38, 222, 237, 226, 124, 38, 250, 10, 222, - 237, 226, 124, 38, 254, 96, 222, 237, 226, 124, 38, 134, 170, 48, 38, - 244, 19, 170, 48, 38, 245, 154, 250, 43, 38, 245, 154, 218, 236, 38, 245, - 154, 248, 0, 38, 245, 154, 250, 44, 252, 188, 38, 43, 44, 80, 48, 38, - 245, 154, 221, 190, 38, 245, 154, 234, 141, 38, 245, 154, 214, 155, 225, - 10, 215, 226, 38, 223, 53, 219, 49, 226, 124, 38, 52, 67, 218, 105, 226, - 124, 38, 254, 106, 87, 38, 215, 212, 214, 182, 38, 211, 247, 251, 148, - 48, 38, 140, 80, 226, 124, 38, 200, 52, 219, 49, 226, 124, 38, 97, 242, - 6, 2, 252, 147, 246, 111, 38, 140, 242, 6, 2, 252, 147, 246, 111, 38, 43, - 80, 51, 38, 44, 80, 51, 38, 253, 225, 48, 255, 20, 226, 235, 255, 4, 216, - 43, 216, 197, 218, 75, 139, 6, 251, 74, 248, 79, 250, 186, 250, 183, 232, - 220, 87, 250, 248, 226, 235, 251, 34, 214, 189, 245, 56, 249, 199, 221, - 187, 248, 79, 244, 187, 119, 4, 243, 209, 119, 6, 242, 67, 251, 227, 6, - 242, 67, 139, 6, 242, 67, 225, 40, 249, 199, 225, 40, 249, 200, 115, 113, - 225, 111, 119, 6, 74, 251, 227, 6, 74, 119, 6, 156, 119, 4, 156, 233, - 155, 57, 252, 149, 87, 139, 6, 230, 30, 227, 200, 50, 219, 33, 223, 122, - 249, 170, 119, 6, 226, 109, 139, 6, 226, 109, 139, 6, 224, 99, 119, 6, - 153, 251, 227, 6, 153, 139, 6, 153, 224, 199, 217, 72, 223, 65, 220, 134, - 79, 217, 2, 50, 215, 254, 164, 50, 213, 240, 139, 6, 210, 159, 226, 137, - 50, 226, 225, 50, 235, 200, 226, 225, 50, 251, 227, 6, 210, 159, 215, 94, - 26, 4, 1, 235, 192, 234, 179, 50, 254, 115, 50, 119, 6, 253, 166, 251, - 227, 6, 251, 74, 245, 76, 87, 119, 4, 76, 119, 6, 76, 119, 6, 245, 14, - 215, 94, 6, 245, 14, 119, 6, 194, 119, 4, 78, 109, 87, 252, 37, 87, 242, - 209, 87, 248, 198, 87, 235, 239, 219, 31, 222, 189, 6, 224, 99, 244, 190, - 50, 139, 4, 225, 111, 139, 4, 243, 114, 139, 6, 243, 114, 139, 6, 225, - 111, 139, 230, 29, 218, 41, 215, 94, 35, 6, 243, 209, 215, 94, 35, 6, - 156, 223, 52, 35, 6, 156, 215, 94, 35, 6, 211, 117, 139, 32, 6, 249, 68, - 139, 32, 4, 249, 68, 139, 32, 4, 76, 139, 32, 4, 74, 139, 32, 4, 235, - 150, 224, 173, 232, 219, 215, 94, 254, 134, 225, 186, 50, 254, 189, 215, - 94, 4, 245, 14, 16, 31, 221, 254, 219, 31, 212, 114, 244, 10, 123, 220, - 120, 212, 114, 244, 10, 123, 228, 199, 212, 114, 244, 10, 123, 216, 242, - 212, 114, 244, 10, 123, 216, 169, 212, 114, 244, 10, 113, 216, 167, 212, - 114, 244, 10, 123, 244, 125, 212, 114, 244, 10, 113, 244, 124, 212, 114, - 244, 10, 134, 244, 124, 212, 114, 244, 10, 244, 19, 244, 124, 212, 114, - 244, 10, 123, 219, 117, 212, 114, 244, 10, 244, 89, 219, 115, 212, 114, - 244, 10, 123, 245, 196, 212, 114, 244, 10, 134, 245, 194, 212, 114, 244, - 10, 244, 89, 245, 194, 212, 114, 244, 10, 220, 124, 245, 194, 244, 10, - 227, 201, 111, 222, 200, 227, 202, 111, 222, 200, 227, 202, 105, 222, - 200, 227, 202, 158, 222, 200, 227, 202, 161, 222, 200, 227, 202, 190, - 222, 200, 227, 202, 195, 222, 200, 227, 202, 199, 222, 200, 227, 202, - 196, 222, 200, 227, 202, 201, 222, 200, 227, 202, 216, 248, 222, 200, - 227, 202, 245, 175, 222, 200, 227, 202, 215, 76, 222, 200, 227, 202, 244, - 122, 222, 200, 227, 202, 123, 240, 217, 222, 200, 227, 202, 244, 89, 240, - 217, 222, 200, 227, 202, 123, 216, 148, 4, 222, 200, 227, 202, 111, 4, - 222, 200, 227, 202, 105, 4, 222, 200, 227, 202, 158, 4, 222, 200, 227, - 202, 161, 4, 222, 200, 227, 202, 190, 4, 222, 200, 227, 202, 195, 4, 222, - 200, 227, 202, 199, 4, 222, 200, 227, 202, 196, 4, 222, 200, 227, 202, - 201, 4, 222, 200, 227, 202, 216, 248, 4, 222, 200, 227, 202, 245, 175, 4, - 222, 200, 227, 202, 215, 76, 4, 222, 200, 227, 202, 244, 122, 4, 222, - 200, 227, 202, 123, 240, 217, 4, 222, 200, 227, 202, 244, 89, 240, 217, - 4, 222, 200, 227, 202, 123, 216, 148, 222, 200, 227, 202, 123, 216, 149, - 251, 75, 249, 68, 222, 200, 227, 202, 244, 89, 216, 148, 222, 200, 227, - 202, 216, 249, 216, 148, 222, 200, 227, 202, 223, 52, 123, 240, 217, 7, - 4, 1, 223, 52, 251, 74, 222, 200, 227, 202, 219, 127, 233, 84, 17, 222, - 200, 227, 202, 244, 123, 245, 234, 17, 222, 200, 227, 202, 244, 123, 216, - 148, 222, 200, 227, 202, 123, 240, 218, 216, 148, 212, 114, 244, 10, 210, - 87, 216, 167, 140, 75, 214, 153, 75, 97, 75, 246, 112, 75, 43, 44, 75, - 120, 124, 75, 228, 61, 212, 9, 75, 228, 61, 245, 228, 75, 219, 30, 245, - 228, 75, 219, 30, 212, 9, 75, 140, 80, 2, 91, 97, 80, 2, 91, 140, 212, - 36, 75, 97, 212, 36, 75, 140, 113, 241, 241, 75, 214, 153, 113, 241, 241, - 75, 97, 113, 241, 241, 75, 246, 112, 113, 241, 241, 75, 140, 80, 2, 217, - 78, 97, 80, 2, 217, 78, 140, 80, 243, 251, 130, 214, 153, 80, 243, 251, - 130, 97, 80, 243, 251, 130, 246, 112, 80, 243, 251, 130, 120, 124, 80, 2, - 252, 135, 140, 80, 2, 103, 97, 80, 2, 103, 140, 80, 2, 232, 129, 97, 80, - 2, 232, 129, 43, 44, 212, 36, 75, 43, 44, 80, 2, 91, 246, 112, 210, 35, - 75, 214, 153, 80, 2, 216, 78, 233, 43, 214, 153, 80, 2, 216, 78, 222, - 244, 246, 112, 80, 2, 216, 78, 233, 43, 246, 112, 80, 2, 216, 78, 222, - 244, 97, 80, 2, 249, 169, 246, 111, 246, 112, 80, 2, 249, 169, 233, 43, - 254, 96, 216, 15, 220, 155, 75, 250, 10, 216, 15, 220, 155, 75, 228, 61, - 212, 9, 80, 216, 43, 200, 130, 140, 80, 216, 43, 252, 149, 115, 97, 80, - 216, 43, 130, 254, 96, 204, 250, 44, 75, 250, 10, 204, 250, 44, 75, 140, - 242, 6, 2, 252, 147, 214, 152, 140, 242, 6, 2, 252, 147, 246, 111, 214, - 153, 242, 6, 2, 252, 147, 222, 244, 214, 153, 242, 6, 2, 252, 147, 233, - 43, 97, 242, 6, 2, 252, 147, 214, 152, 97, 242, 6, 2, 252, 147, 246, 111, - 246, 112, 242, 6, 2, 252, 147, 222, 244, 246, 112, 242, 6, 2, 252, 147, - 233, 43, 97, 80, 115, 140, 75, 214, 153, 80, 140, 64, 246, 112, 75, 140, - 80, 115, 97, 75, 140, 226, 74, 253, 255, 214, 153, 226, 74, 253, 255, 97, - 226, 74, 253, 255, 246, 112, 226, 74, 253, 255, 140, 242, 6, 115, 97, - 242, 5, 97, 242, 6, 115, 140, 242, 5, 140, 52, 80, 2, 91, 43, 44, 52, 80, - 2, 91, 97, 52, 80, 2, 91, 140, 52, 75, 214, 153, 52, 75, 97, 52, 75, 246, - 112, 52, 75, 43, 44, 52, 75, 120, 124, 52, 75, 228, 61, 212, 9, 52, 75, - 228, 61, 245, 228, 52, 75, 219, 30, 245, 228, 52, 75, 219, 30, 212, 9, - 52, 75, 140, 215, 212, 75, 97, 215, 212, 75, 140, 218, 232, 75, 97, 218, - 232, 75, 214, 153, 80, 2, 52, 91, 246, 112, 80, 2, 52, 91, 140, 248, 163, - 75, 214, 153, 248, 163, 75, 97, 248, 163, 75, 246, 112, 248, 163, 75, - 140, 80, 216, 43, 130, 97, 80, 216, 43, 130, 140, 71, 75, 214, 153, 71, - 75, 97, 71, 75, 246, 112, 71, 75, 214, 153, 71, 80, 243, 251, 130, 214, - 153, 71, 80, 226, 201, 225, 217, 214, 153, 71, 80, 226, 201, 225, 218, 2, - 203, 130, 214, 153, 71, 80, 226, 201, 225, 218, 2, 67, 130, 214, 153, 71, - 52, 75, 214, 153, 71, 52, 80, 226, 201, 225, 217, 97, 71, 80, 243, 251, - 212, 56, 228, 61, 212, 9, 80, 216, 43, 249, 168, 219, 30, 245, 228, 80, - 216, 43, 249, 168, 120, 124, 71, 75, 44, 80, 2, 4, 250, 43, 246, 112, 80, - 140, 64, 214, 153, 75, 134, 97, 253, 255, 140, 80, 2, 67, 91, 97, 80, 2, - 67, 91, 43, 44, 80, 2, 67, 91, 140, 80, 2, 52, 67, 91, 97, 80, 2, 52, 67, - 91, 43, 44, 80, 2, 52, 67, 91, 140, 226, 177, 75, 97, 226, 177, 75, 43, - 44, 226, 177, 75, 31, 254, 163, 249, 222, 226, 1, 247, 241, 216, 188, - 245, 35, 216, 188, 247, 146, 228, 57, 245, 36, 245, 160, 220, 129, 235, - 252, 229, 226, 245, 178, 226, 235, 228, 57, 254, 132, 245, 178, 226, 235, - 4, 245, 178, 226, 235, 249, 194, 253, 246, 231, 67, 247, 146, 228, 57, - 249, 196, 253, 246, 231, 67, 4, 249, 194, 253, 246, 231, 67, 245, 151, - 64, 224, 175, 230, 29, 224, 183, 230, 29, 249, 173, 230, 29, 218, 41, - 230, 187, 50, 230, 185, 50, 59, 225, 25, 247, 177, 219, 97, 220, 130, - 230, 186, 253, 225, 226, 171, 222, 237, 226, 171, 251, 122, 226, 171, 42, - 222, 195, 249, 117, 222, 195, 244, 12, 222, 195, 224, 171, 112, 235, 241, - 44, 254, 117, 254, 117, 231, 93, 254, 117, 219, 1, 254, 117, 247, 179, - 247, 146, 228, 57, 247, 182, 226, 12, 112, 228, 57, 226, 12, 112, 232, - 152, 254, 126, 232, 152, 226, 162, 235, 205, 214, 175, 235, 218, 52, 235, - 218, 215, 212, 235, 218, 249, 190, 235, 218, 218, 14, 235, 218, 213, 129, - 235, 218, 250, 10, 235, 218, 250, 10, 249, 190, 235, 218, 254, 96, 249, - 190, 235, 218, 216, 187, 252, 75, 223, 140, 224, 172, 59, 230, 186, 245, - 41, 243, 53, 224, 172, 241, 64, 216, 90, 226, 171, 223, 52, 184, 235, - 200, 233, 71, 222, 93, 219, 159, 212, 35, 211, 200, 224, 183, 228, 57, - 184, 230, 187, 184, 253, 218, 128, 112, 228, 57, 253, 218, 128, 112, 254, - 56, 128, 112, 254, 56, 251, 96, 228, 57, 255, 13, 128, 112, 229, 105, - 254, 56, 228, 64, 255, 13, 128, 112, 254, 156, 128, 112, 228, 57, 254, - 156, 128, 112, 254, 156, 128, 177, 128, 112, 215, 212, 184, 254, 164, - 128, 112, 245, 102, 112, 243, 52, 245, 102, 112, 247, 242, 252, 31, 254, - 58, 216, 197, 232, 227, 243, 52, 128, 112, 254, 56, 128, 216, 43, 177, - 216, 197, 236, 22, 226, 235, 236, 22, 64, 177, 254, 56, 128, 112, 249, - 235, 245, 105, 245, 106, 249, 234, 222, 237, 236, 7, 128, 112, 222, 237, - 128, 112, 249, 162, 112, 245, 75, 245, 104, 112, 218, 159, 245, 105, 248, - 63, 128, 112, 128, 216, 43, 251, 86, 248, 80, 231, 93, 251, 85, 224, 14, - 128, 112, 228, 57, 128, 112, 240, 111, 112, 228, 57, 240, 111, 112, 218, - 111, 245, 102, 112, 233, 21, 177, 128, 112, 242, 137, 177, 128, 112, 233, - 21, 115, 128, 112, 242, 137, 115, 128, 112, 233, 21, 251, 96, 228, 57, - 128, 112, 242, 137, 251, 96, 228, 57, 128, 112, 230, 102, 233, 20, 230, - 102, 242, 136, 252, 31, 228, 57, 245, 102, 112, 228, 57, 233, 20, 228, - 57, 242, 136, 229, 105, 233, 21, 228, 64, 128, 112, 229, 105, 242, 137, - 228, 64, 128, 112, 233, 21, 177, 245, 102, 112, 242, 137, 177, 245, 102, - 112, 229, 105, 233, 21, 228, 64, 245, 102, 112, 229, 105, 242, 137, 228, - 64, 245, 102, 112, 233, 21, 177, 242, 136, 242, 137, 177, 233, 20, 229, - 105, 233, 21, 228, 64, 242, 136, 229, 105, 242, 137, 228, 64, 233, 20, - 224, 205, 218, 56, 224, 206, 177, 128, 112, 218, 57, 177, 128, 112, 224, - 206, 177, 245, 102, 112, 218, 57, 177, 245, 102, 112, 247, 146, 228, 57, - 224, 208, 247, 146, 228, 57, 218, 58, 218, 65, 226, 235, 218, 23, 226, - 235, 228, 57, 116, 218, 65, 226, 235, 228, 57, 116, 218, 23, 226, 235, - 218, 65, 64, 177, 128, 112, 218, 23, 64, 177, 128, 112, 229, 105, 116, - 218, 65, 64, 228, 64, 128, 112, 229, 105, 116, 218, 23, 64, 228, 64, 128, - 112, 218, 65, 64, 2, 228, 57, 128, 112, 218, 23, 64, 2, 228, 57, 128, - 112, 230, 86, 230, 87, 230, 88, 230, 87, 214, 175, 42, 236, 22, 226, 235, - 42, 226, 154, 226, 235, 42, 236, 22, 64, 177, 128, 112, 42, 226, 154, 64, - 177, 128, 112, 42, 251, 3, 42, 249, 110, 37, 225, 25, 37, 230, 186, 37, - 216, 86, 37, 247, 177, 219, 97, 37, 59, 226, 171, 37, 222, 237, 226, 171, - 37, 253, 225, 226, 171, 37, 245, 105, 37, 248, 164, 92, 225, 25, 92, 230, - 186, 92, 216, 86, 92, 59, 226, 171, 44, 217, 88, 43, 217, 88, 124, 217, - 88, 120, 217, 88, 253, 228, 230, 161, 215, 192, 244, 33, 215, 212, 67, - 252, 149, 44, 215, 93, 52, 67, 252, 149, 52, 44, 215, 93, 247, 146, 228, - 57, 224, 166, 228, 57, 215, 192, 247, 146, 228, 57, 244, 34, 229, 107, - 52, 67, 252, 149, 52, 44, 215, 93, 224, 206, 214, 184, 223, 94, 218, 57, - 214, 184, 223, 94, 228, 62, 218, 78, 226, 235, 249, 194, 253, 246, 228, - 62, 218, 77, 228, 62, 218, 78, 64, 177, 128, 112, 249, 194, 253, 246, - 228, 62, 218, 78, 177, 128, 112, 226, 154, 226, 235, 236, 22, 226, 235, - 230, 92, 241, 207, 249, 204, 231, 142, 235, 215, 211, 145, 229, 207, 228, - 63, 44, 254, 118, 2, 254, 33, 44, 215, 226, 230, 29, 232, 152, 254, 126, - 230, 29, 232, 152, 226, 162, 230, 29, 235, 205, 230, 29, 214, 175, 248, - 1, 226, 171, 59, 226, 171, 218, 159, 226, 171, 247, 177, 216, 86, 251, - 172, 43, 228, 62, 244, 189, 220, 151, 224, 183, 44, 228, 62, 244, 189, - 220, 151, 224, 183, 43, 220, 151, 224, 183, 44, 220, 151, 224, 183, 223, - 52, 216, 90, 245, 105, 249, 107, 232, 152, 226, 162, 249, 107, 232, 152, - 254, 126, 52, 218, 64, 52, 218, 22, 52, 235, 205, 52, 214, 175, 225, 50, - 128, 22, 226, 12, 112, 233, 21, 2, 247, 128, 242, 137, 2, 247, 128, 213, - 187, 230, 102, 233, 20, 213, 187, 230, 102, 242, 136, 233, 21, 128, 216, - 43, 177, 242, 136, 242, 137, 128, 216, 43, 177, 233, 20, 128, 216, 43, - 177, 233, 20, 128, 216, 43, 177, 242, 136, 128, 216, 43, 177, 224, 205, - 128, 216, 43, 177, 218, 56, 247, 146, 228, 57, 224, 209, 177, 245, 107, - 247, 146, 228, 57, 218, 59, 177, 245, 107, 228, 57, 42, 236, 22, 64, 177, - 128, 112, 228, 57, 42, 226, 154, 64, 177, 128, 112, 42, 236, 22, 64, 177, - 228, 57, 128, 112, 42, 226, 154, 64, 177, 228, 57, 128, 112, 233, 21, - 251, 96, 228, 57, 245, 102, 112, 242, 137, 251, 96, 228, 57, 245, 102, - 112, 224, 206, 251, 96, 228, 57, 245, 102, 112, 218, 57, 251, 96, 228, - 57, 245, 102, 112, 228, 57, 228, 62, 218, 78, 226, 235, 247, 146, 228, - 57, 249, 196, 253, 246, 228, 62, 218, 77, 228, 57, 228, 62, 218, 78, 64, - 177, 128, 112, 247, 146, 228, 57, 249, 196, 253, 246, 228, 62, 218, 78, - 177, 245, 107, 67, 245, 171, 230, 227, 203, 245, 171, 120, 44, 248, 7, - 245, 171, 124, 44, 248, 7, 245, 171, 245, 178, 64, 2, 200, 203, 91, 245, - 178, 64, 2, 67, 252, 149, 253, 215, 245, 151, 64, 203, 91, 4, 245, 178, - 64, 2, 67, 252, 149, 253, 215, 245, 151, 64, 203, 91, 245, 178, 64, 2, - 59, 48, 245, 178, 64, 2, 226, 127, 4, 245, 178, 64, 2, 226, 127, 245, - 178, 64, 2, 214, 183, 245, 178, 64, 2, 113, 203, 218, 92, 249, 194, 2, - 200, 203, 91, 249, 194, 2, 67, 252, 149, 253, 215, 245, 151, 64, 203, 91, - 4, 249, 194, 2, 67, 252, 149, 253, 215, 245, 151, 64, 203, 91, 249, 194, - 2, 226, 127, 4, 249, 194, 2, 226, 127, 210, 160, 189, 252, 181, 231, 66, - 248, 2, 50, 245, 180, 75, 240, 241, 120, 254, 1, 124, 254, 1, 224, 178, - 225, 168, 212, 32, 232, 219, 43, 250, 189, 44, 250, 189, 43, 244, 65, 44, - 244, 65, 251, 183, 44, 249, 140, 251, 183, 43, 249, 140, 216, 15, 44, - 249, 140, 216, 15, 43, 249, 140, 223, 52, 228, 57, 50, 42, 232, 110, 254, - 33, 221, 166, 221, 173, 217, 2, 223, 123, 224, 244, 235, 245, 213, 165, - 218, 236, 225, 44, 64, 235, 214, 50, 215, 94, 228, 57, 50, 212, 42, 240, - 243, 216, 15, 43, 249, 168, 216, 15, 44, 249, 168, 251, 183, 43, 249, - 168, 251, 183, 44, 249, 168, 216, 15, 163, 235, 218, 251, 183, 163, 235, - 218, 243, 248, 219, 77, 120, 254, 2, 252, 32, 113, 203, 252, 137, 226, - 164, 234, 144, 245, 98, 216, 43, 216, 197, 222, 254, 211, 179, 236, 7, - 116, 223, 120, 251, 171, 234, 143, 233, 48, 254, 118, 127, 222, 250, 254, - 118, 127, 245, 98, 216, 43, 216, 197, 233, 52, 252, 43, 222, 236, 249, - 78, 254, 164, 254, 9, 217, 182, 216, 5, 222, 125, 247, 223, 226, 155, - 249, 206, 217, 53, 219, 88, 249, 159, 249, 158, 254, 74, 243, 232, 16, - 240, 158, 254, 74, 243, 232, 16, 218, 230, 224, 30, 254, 74, 243, 232, - 16, 224, 31, 245, 107, 254, 74, 243, 232, 16, 224, 31, 247, 182, 254, 74, - 243, 232, 16, 224, 31, 248, 0, 254, 74, 243, 232, 16, 224, 31, 235, 62, - 254, 74, 243, 232, 16, 224, 31, 250, 43, 254, 74, 243, 232, 16, 250, 44, - 218, 137, 254, 74, 243, 232, 16, 250, 44, 235, 62, 254, 74, 243, 232, 16, - 219, 98, 130, 254, 74, 243, 232, 16, 252, 189, 130, 254, 74, 243, 232, - 16, 224, 31, 219, 97, 254, 74, 243, 232, 16, 224, 31, 252, 188, 254, 74, - 243, 232, 16, 224, 31, 233, 20, 254, 74, 243, 232, 16, 224, 31, 242, 136, - 254, 74, 243, 232, 16, 140, 214, 19, 254, 74, 243, 232, 16, 97, 214, 19, - 254, 74, 243, 232, 16, 224, 31, 140, 75, 254, 74, 243, 232, 16, 224, 31, - 97, 75, 254, 74, 243, 232, 16, 250, 44, 252, 188, 254, 74, 243, 232, 16, - 124, 217, 89, 214, 183, 254, 74, 243, 232, 16, 248, 63, 218, 137, 254, - 74, 243, 232, 16, 224, 31, 124, 250, 246, 254, 74, 243, 232, 16, 224, 31, - 248, 62, 254, 74, 243, 232, 16, 124, 217, 89, 235, 62, 254, 74, 243, 232, - 16, 214, 153, 214, 19, 254, 74, 243, 232, 16, 224, 31, 214, 153, 75, 254, - 74, 243, 232, 16, 120, 217, 89, 226, 127, 254, 74, 243, 232, 16, 248, 74, - 218, 137, 254, 74, 243, 232, 16, 224, 31, 120, 250, 246, 254, 74, 243, - 232, 16, 224, 31, 248, 73, 254, 74, 243, 232, 16, 120, 217, 89, 235, 62, - 254, 74, 243, 232, 16, 246, 112, 214, 19, 254, 74, 243, 232, 16, 224, 31, - 246, 112, 75, 254, 74, 243, 232, 16, 224, 0, 214, 183, 254, 74, 243, 232, - 16, 248, 63, 214, 183, 254, 74, 243, 232, 16, 248, 1, 214, 183, 254, 74, - 243, 232, 16, 235, 63, 214, 183, 254, 74, 243, 232, 16, 250, 44, 214, - 183, 254, 74, 243, 232, 16, 120, 220, 7, 235, 62, 254, 74, 243, 232, 16, - 224, 0, 224, 30, 254, 74, 243, 232, 16, 250, 44, 218, 158, 254, 74, 243, - 232, 16, 224, 31, 249, 234, 254, 74, 243, 232, 16, 120, 217, 89, 248, 9, - 254, 74, 243, 232, 16, 248, 74, 248, 9, 254, 74, 243, 232, 16, 218, 159, - 248, 9, 254, 74, 243, 232, 16, 235, 63, 248, 9, 254, 74, 243, 232, 16, - 250, 44, 248, 9, 254, 74, 243, 232, 16, 124, 220, 7, 218, 137, 254, 74, - 243, 232, 16, 43, 220, 7, 218, 137, 254, 74, 243, 232, 16, 216, 90, 248, - 9, 254, 74, 243, 232, 16, 242, 137, 248, 9, 254, 74, 243, 232, 16, 249, - 228, 130, 254, 74, 243, 232, 16, 248, 74, 184, 254, 74, 243, 232, 16, - 210, 34, 254, 74, 243, 232, 16, 218, 138, 184, 254, 74, 243, 232, 16, - 220, 153, 214, 183, 254, 74, 243, 232, 16, 224, 31, 228, 57, 245, 107, - 254, 74, 243, 232, 16, 224, 31, 224, 15, 254, 74, 243, 232, 16, 124, 250, - 247, 184, 254, 74, 243, 232, 16, 120, 250, 247, 184, 254, 74, 243, 232, - 16, 235, 192, 254, 74, 243, 232, 16, 223, 40, 254, 74, 243, 232, 16, 226, - 205, 254, 74, 243, 232, 16, 254, 152, 214, 183, 254, 74, 243, 232, 16, - 245, 109, 214, 183, 254, 74, 243, 232, 16, 235, 193, 214, 183, 254, 74, - 243, 232, 16, 226, 206, 214, 183, 254, 74, 243, 232, 16, 254, 151, 228, - 57, 250, 138, 79, 44, 254, 118, 2, 246, 112, 210, 35, 75, 219, 237, 204, - 251, 171, 252, 53, 87, 67, 232, 220, 2, 230, 229, 247, 128, 235, 223, 87, - 249, 191, 214, 181, 87, 247, 197, 214, 181, 87, 245, 162, 87, 249, 218, - 87, 71, 42, 2, 250, 183, 67, 232, 219, 245, 138, 87, 254, 147, 234, 145, - 87, 241, 220, 87, 37, 203, 252, 149, 2, 228, 55, 37, 215, 227, 246, 114, - 251, 143, 250, 44, 2, 228, 59, 75, 214, 179, 87, 230, 142, 87, 240, 171, - 87, 226, 178, 242, 66, 87, 226, 178, 233, 153, 87, 225, 248, 87, 225, - 247, 87, 247, 205, 249, 105, 16, 244, 28, 105, 219, 52, 87, 254, 74, 243, - 232, 16, 224, 30, 248, 91, 220, 140, 234, 145, 87, 224, 195, 226, 79, - 229, 87, 226, 79, 224, 191, 221, 191, 87, 250, 25, 221, 191, 87, 43, 226, - 8, 214, 160, 103, 43, 226, 8, 245, 29, 43, 226, 8, 232, 114, 103, 44, - 226, 8, 214, 160, 103, 44, 226, 8, 245, 29, 44, 226, 8, 232, 114, 103, - 43, 42, 251, 166, 214, 160, 249, 168, 43, 42, 251, 166, 245, 29, 43, 42, - 251, 166, 232, 114, 249, 168, 44, 42, 251, 166, 214, 160, 249, 168, 44, - 42, 251, 166, 245, 29, 44, 42, 251, 166, 232, 114, 249, 168, 43, 249, - 107, 251, 166, 214, 160, 103, 43, 249, 107, 251, 166, 230, 229, 225, 104, - 43, 249, 107, 251, 166, 232, 114, 103, 249, 107, 251, 166, 245, 29, 44, - 249, 107, 251, 166, 214, 160, 103, 44, 249, 107, 251, 166, 230, 229, 225, - 104, 44, 249, 107, 251, 166, 232, 114, 103, 235, 219, 245, 29, 203, 232, - 220, 245, 29, 214, 160, 43, 177, 232, 114, 44, 249, 107, 251, 166, 221, - 174, 214, 160, 44, 177, 232, 114, 43, 249, 107, 251, 166, 221, 174, 218, - 42, 216, 14, 218, 42, 251, 182, 216, 15, 42, 127, 251, 183, 42, 127, 251, - 183, 42, 251, 166, 115, 216, 15, 42, 127, 34, 16, 251, 182, 43, 67, 93, - 232, 219, 44, 67, 93, 232, 219, 203, 221, 207, 232, 218, 203, 221, 207, - 232, 217, 203, 221, 207, 232, 216, 203, 221, 207, 232, 215, 248, 54, 16, - 193, 67, 22, 216, 15, 222, 254, 248, 54, 16, 193, 67, 22, 251, 183, 222, - 254, 248, 54, 16, 193, 67, 2, 250, 43, 248, 54, 16, 193, 124, 22, 203, 2, - 250, 43, 248, 54, 16, 193, 120, 22, 203, 2, 250, 43, 248, 54, 16, 193, - 67, 2, 215, 226, 248, 54, 16, 193, 124, 22, 203, 2, 215, 226, 248, 54, - 16, 193, 120, 22, 203, 2, 215, 226, 248, 54, 16, 193, 67, 22, 212, 35, - 248, 54, 16, 193, 124, 22, 203, 2, 212, 35, 248, 54, 16, 193, 120, 22, - 203, 2, 212, 35, 248, 54, 16, 193, 124, 22, 241, 51, 248, 54, 16, 193, - 120, 22, 241, 51, 248, 54, 16, 193, 67, 22, 216, 15, 233, 52, 248, 54, - 16, 193, 67, 22, 251, 183, 233, 52, 42, 244, 40, 223, 57, 87, 245, 190, - 87, 67, 232, 220, 245, 29, 231, 38, 251, 154, 231, 38, 200, 115, 219, - 252, 231, 38, 219, 253, 115, 232, 143, 231, 38, 200, 115, 113, 219, 239, - 231, 38, 113, 219, 240, 115, 232, 143, 231, 38, 113, 219, 240, 235, 70, - 231, 38, 215, 209, 231, 38, 216, 224, 231, 38, 225, 191, 245, 232, 242, - 129, 243, 226, 216, 15, 226, 7, 251, 183, 226, 7, 216, 15, 249, 107, 127, - 251, 183, 249, 107, 127, 216, 15, 216, 7, 220, 55, 127, 251, 183, 216, 7, - 220, 55, 127, 71, 215, 240, 252, 43, 222, 237, 2, 250, 43, 218, 122, 244, - 72, 255, 26, 249, 104, 245, 179, 235, 205, 248, 91, 245, 32, 87, 85, 222, - 250, 52, 215, 226, 85, 233, 48, 52, 215, 226, 85, 214, 162, 52, 215, 226, - 85, 246, 113, 52, 215, 226, 85, 222, 250, 52, 215, 227, 2, 67, 130, 85, - 233, 48, 52, 215, 227, 2, 67, 130, 85, 222, 250, 215, 227, 2, 52, 67, - 130, 254, 182, 250, 11, 218, 128, 216, 87, 250, 11, 240, 244, 2, 244, 58, - 221, 243, 16, 31, 227, 206, 16, 31, 218, 154, 64, 241, 240, 16, 31, 218, - 154, 64, 216, 213, 16, 31, 245, 151, 64, 216, 213, 16, 31, 245, 151, 64, - 215, 244, 16, 31, 245, 140, 16, 31, 255, 16, 16, 31, 252, 52, 16, 31, - 252, 187, 16, 31, 203, 217, 90, 16, 31, 232, 220, 244, 153, 16, 31, 67, - 217, 90, 16, 31, 244, 28, 244, 153, 16, 31, 250, 238, 223, 56, 16, 31, - 220, 30, 226, 134, 16, 31, 220, 30, 236, 6, 16, 31, 248, 159, 232, 210, - 245, 85, 16, 31, 248, 39, 249, 186, 111, 16, 31, 248, 39, 249, 186, 105, - 16, 31, 248, 39, 249, 186, 158, 16, 31, 248, 39, 249, 186, 161, 16, 31, - 152, 255, 16, 16, 31, 217, 178, 236, 69, 16, 31, 245, 151, 64, 215, 245, - 251, 221, 16, 31, 251, 13, 16, 31, 245, 151, 64, 231, 86, 16, 31, 218, - 62, 16, 31, 245, 85, 16, 31, 244, 115, 220, 139, 16, 31, 242, 128, 220, - 139, 16, 31, 223, 124, 220, 139, 16, 31, 214, 174, 220, 139, 16, 31, 219, - 20, 16, 31, 248, 71, 251, 224, 87, 204, 251, 171, 16, 31, 229, 90, 16, - 31, 248, 72, 244, 28, 105, 16, 31, 218, 63, 244, 28, 105, 226, 245, 103, - 226, 245, 250, 160, 226, 245, 244, 31, 226, 245, 235, 200, 244, 31, 226, - 245, 252, 50, 251, 132, 226, 245, 251, 178, 216, 112, 226, 245, 251, 163, - 252, 154, 240, 110, 226, 245, 254, 135, 64, 250, 137, 226, 245, 248, 164, - 226, 245, 249, 95, 255, 20, 227, 204, 226, 245, 52, 252, 188, 37, 21, - 111, 37, 21, 105, 37, 21, 158, 37, 21, 161, 37, 21, 190, 37, 21, 195, 37, - 21, 199, 37, 21, 196, 37, 21, 201, 37, 54, 216, 248, 37, 54, 245, 175, - 37, 54, 215, 76, 37, 54, 216, 165, 37, 54, 244, 13, 37, 54, 244, 126, 37, - 54, 219, 121, 37, 54, 220, 121, 37, 54, 245, 198, 37, 54, 228, 202, 37, - 54, 215, 73, 88, 21, 111, 88, 21, 105, 88, 21, 158, 88, 21, 161, 88, 21, - 190, 88, 21, 195, 88, 21, 199, 88, 21, 196, 88, 21, 201, 88, 54, 216, - 248, 88, 54, 245, 175, 88, 54, 215, 76, 88, 54, 216, 165, 88, 54, 244, - 13, 88, 54, 244, 126, 88, 54, 219, 121, 88, 54, 220, 121, 88, 54, 245, - 198, 88, 54, 228, 202, 88, 54, 215, 73, 21, 123, 243, 236, 218, 131, 21, - 113, 243, 236, 218, 131, 21, 134, 243, 236, 218, 131, 21, 244, 19, 243, - 236, 218, 131, 21, 244, 89, 243, 236, 218, 131, 21, 219, 127, 243, 236, - 218, 131, 21, 220, 124, 243, 236, 218, 131, 21, 245, 201, 243, 236, 218, - 131, 21, 228, 205, 243, 236, 218, 131, 54, 216, 249, 243, 236, 218, 131, - 54, 245, 176, 243, 236, 218, 131, 54, 215, 77, 243, 236, 218, 131, 54, - 216, 166, 243, 236, 218, 131, 54, 244, 14, 243, 236, 218, 131, 54, 244, - 127, 243, 236, 218, 131, 54, 219, 122, 243, 236, 218, 131, 54, 220, 122, - 243, 236, 218, 131, 54, 245, 199, 243, 236, 218, 131, 54, 228, 203, 243, - 236, 218, 131, 54, 215, 74, 243, 236, 218, 131, 88, 7, 4, 1, 61, 88, 7, - 4, 1, 253, 166, 88, 7, 4, 1, 251, 74, 88, 7, 4, 1, 249, 68, 88, 7, 4, 1, - 76, 88, 7, 4, 1, 245, 14, 88, 7, 4, 1, 243, 209, 88, 7, 4, 1, 242, 67, - 88, 7, 4, 1, 74, 88, 7, 4, 1, 235, 150, 88, 7, 4, 1, 235, 29, 88, 7, 4, - 1, 156, 88, 7, 4, 1, 194, 88, 7, 4, 1, 230, 30, 88, 7, 4, 1, 78, 88, 7, - 4, 1, 226, 109, 88, 7, 4, 1, 224, 99, 88, 7, 4, 1, 153, 88, 7, 4, 1, 222, - 93, 88, 7, 4, 1, 217, 153, 88, 7, 4, 1, 69, 88, 7, 4, 1, 214, 105, 88, 7, - 4, 1, 212, 98, 88, 7, 4, 1, 211, 178, 88, 7, 4, 1, 211, 117, 88, 7, 4, 1, - 210, 159, 37, 7, 6, 1, 61, 37, 7, 6, 1, 253, 166, 37, 7, 6, 1, 251, 74, - 37, 7, 6, 1, 249, 68, 37, 7, 6, 1, 76, 37, 7, 6, 1, 245, 14, 37, 7, 6, 1, - 243, 209, 37, 7, 6, 1, 242, 67, 37, 7, 6, 1, 74, 37, 7, 6, 1, 235, 150, - 37, 7, 6, 1, 235, 29, 37, 7, 6, 1, 156, 37, 7, 6, 1, 194, 37, 7, 6, 1, - 230, 30, 37, 7, 6, 1, 78, 37, 7, 6, 1, 226, 109, 37, 7, 6, 1, 224, 99, - 37, 7, 6, 1, 153, 37, 7, 6, 1, 222, 93, 37, 7, 6, 1, 217, 153, 37, 7, 6, - 1, 69, 37, 7, 6, 1, 214, 105, 37, 7, 6, 1, 212, 98, 37, 7, 6, 1, 211, - 178, 37, 7, 6, 1, 211, 117, 37, 7, 6, 1, 210, 159, 37, 7, 4, 1, 61, 37, - 7, 4, 1, 253, 166, 37, 7, 4, 1, 251, 74, 37, 7, 4, 1, 249, 68, 37, 7, 4, - 1, 76, 37, 7, 4, 1, 245, 14, 37, 7, 4, 1, 243, 209, 37, 7, 4, 1, 242, 67, - 37, 7, 4, 1, 74, 37, 7, 4, 1, 235, 150, 37, 7, 4, 1, 235, 29, 37, 7, 4, - 1, 156, 37, 7, 4, 1, 194, 37, 7, 4, 1, 230, 30, 37, 7, 4, 1, 78, 37, 7, - 4, 1, 226, 109, 37, 7, 4, 1, 224, 99, 37, 7, 4, 1, 153, 37, 7, 4, 1, 222, - 93, 37, 7, 4, 1, 217, 153, 37, 7, 4, 1, 69, 37, 7, 4, 1, 214, 105, 37, 7, - 4, 1, 212, 98, 37, 7, 4, 1, 211, 178, 37, 7, 4, 1, 211, 117, 37, 7, 4, 1, - 210, 159, 37, 21, 210, 86, 152, 37, 54, 245, 175, 152, 37, 54, 215, 76, - 152, 37, 54, 216, 165, 152, 37, 54, 244, 13, 152, 37, 54, 244, 126, 152, - 37, 54, 219, 121, 152, 37, 54, 220, 121, 152, 37, 54, 245, 198, 152, 37, - 54, 228, 202, 152, 37, 54, 215, 73, 52, 37, 21, 111, 52, 37, 21, 105, 52, - 37, 21, 158, 52, 37, 21, 161, 52, 37, 21, 190, 52, 37, 21, 195, 52, 37, - 21, 199, 52, 37, 21, 196, 52, 37, 21, 201, 52, 37, 54, 216, 248, 152, 37, - 21, 210, 86, 93, 99, 193, 241, 51, 93, 99, 114, 241, 51, 93, 99, 193, - 213, 239, 93, 99, 114, 213, 239, 93, 99, 193, 215, 212, 248, 165, 241, - 51, 93, 99, 114, 215, 212, 248, 165, 241, 51, 93, 99, 193, 215, 212, 248, - 165, 213, 239, 93, 99, 114, 215, 212, 248, 165, 213, 239, 93, 99, 193, - 224, 27, 248, 165, 241, 51, 93, 99, 114, 224, 27, 248, 165, 241, 51, 93, - 99, 193, 224, 27, 248, 165, 213, 239, 93, 99, 114, 224, 27, 248, 165, - 213, 239, 93, 99, 193, 124, 22, 222, 254, 93, 99, 124, 193, 22, 44, 241, - 228, 93, 99, 124, 114, 22, 44, 232, 236, 93, 99, 114, 124, 22, 222, 254, - 93, 99, 193, 124, 22, 233, 52, 93, 99, 124, 193, 22, 43, 241, 228, 93, - 99, 124, 114, 22, 43, 232, 236, 93, 99, 114, 124, 22, 233, 52, 93, 99, - 193, 120, 22, 222, 254, 93, 99, 120, 193, 22, 44, 241, 228, 93, 99, 120, - 114, 22, 44, 232, 236, 93, 99, 114, 120, 22, 222, 254, 93, 99, 193, 120, - 22, 233, 52, 93, 99, 120, 193, 22, 43, 241, 228, 93, 99, 120, 114, 22, - 43, 232, 236, 93, 99, 114, 120, 22, 233, 52, 93, 99, 193, 67, 22, 222, - 254, 93, 99, 67, 193, 22, 44, 241, 228, 93, 99, 120, 114, 22, 44, 124, - 232, 236, 93, 99, 124, 114, 22, 44, 120, 232, 236, 93, 99, 67, 114, 22, - 44, 232, 236, 93, 99, 124, 193, 22, 44, 120, 241, 228, 93, 99, 120, 193, - 22, 44, 124, 241, 228, 93, 99, 114, 67, 22, 222, 254, 93, 99, 193, 67, - 22, 233, 52, 93, 99, 67, 193, 22, 43, 241, 228, 93, 99, 120, 114, 22, 43, - 124, 232, 236, 93, 99, 124, 114, 22, 43, 120, 232, 236, 93, 99, 67, 114, - 22, 43, 232, 236, 93, 99, 124, 193, 22, 43, 120, 241, 228, 93, 99, 120, - 193, 22, 43, 124, 241, 228, 93, 99, 114, 67, 22, 233, 52, 93, 99, 193, - 124, 22, 241, 51, 93, 99, 43, 114, 22, 44, 124, 232, 236, 93, 99, 44, - 114, 22, 43, 124, 232, 236, 93, 99, 124, 193, 22, 203, 241, 228, 93, 99, - 124, 114, 22, 203, 232, 236, 93, 99, 44, 193, 22, 43, 124, 241, 228, 93, - 99, 43, 193, 22, 44, 124, 241, 228, 93, 99, 114, 124, 22, 241, 51, 93, - 99, 193, 120, 22, 241, 51, 93, 99, 43, 114, 22, 44, 120, 232, 236, 93, - 99, 44, 114, 22, 43, 120, 232, 236, 93, 99, 120, 193, 22, 203, 241, 228, - 93, 99, 120, 114, 22, 203, 232, 236, 93, 99, 44, 193, 22, 43, 120, 241, - 228, 93, 99, 43, 193, 22, 44, 120, 241, 228, 93, 99, 114, 120, 22, 241, - 51, 93, 99, 193, 67, 22, 241, 51, 93, 99, 43, 114, 22, 44, 67, 232, 236, - 93, 99, 44, 114, 22, 43, 67, 232, 236, 93, 99, 67, 193, 22, 203, 241, - 228, 93, 99, 120, 114, 22, 124, 203, 232, 236, 93, 99, 124, 114, 22, 120, - 203, 232, 236, 93, 99, 67, 114, 22, 203, 232, 236, 93, 99, 43, 120, 114, - 22, 44, 124, 232, 236, 93, 99, 44, 120, 114, 22, 43, 124, 232, 236, 93, - 99, 43, 124, 114, 22, 44, 120, 232, 236, 93, 99, 44, 124, 114, 22, 43, - 120, 232, 236, 93, 99, 124, 193, 22, 120, 203, 241, 228, 93, 99, 120, - 193, 22, 124, 203, 241, 228, 93, 99, 44, 193, 22, 43, 67, 241, 228, 93, - 99, 43, 193, 22, 44, 67, 241, 228, 93, 99, 114, 67, 22, 241, 51, 93, 99, - 193, 52, 248, 165, 241, 51, 93, 99, 114, 52, 248, 165, 241, 51, 93, 99, - 193, 52, 248, 165, 213, 239, 93, 99, 114, 52, 248, 165, 213, 239, 93, 99, - 52, 241, 51, 93, 99, 52, 213, 239, 93, 99, 124, 219, 157, 22, 44, 246, - 121, 93, 99, 124, 52, 22, 44, 219, 156, 93, 99, 52, 124, 22, 222, 254, - 93, 99, 124, 219, 157, 22, 43, 246, 121, 93, 99, 124, 52, 22, 43, 219, - 156, 93, 99, 52, 124, 22, 233, 52, 93, 99, 120, 219, 157, 22, 44, 246, - 121, 93, 99, 120, 52, 22, 44, 219, 156, 93, 99, 52, 120, 22, 222, 254, - 93, 99, 120, 219, 157, 22, 43, 246, 121, 93, 99, 120, 52, 22, 43, 219, - 156, 93, 99, 52, 120, 22, 233, 52, 93, 99, 67, 219, 157, 22, 44, 246, - 121, 93, 99, 67, 52, 22, 44, 219, 156, 93, 99, 52, 67, 22, 222, 254, 93, - 99, 67, 219, 157, 22, 43, 246, 121, 93, 99, 67, 52, 22, 43, 219, 156, 93, - 99, 52, 67, 22, 233, 52, 93, 99, 124, 219, 157, 22, 203, 246, 121, 93, - 99, 124, 52, 22, 203, 219, 156, 93, 99, 52, 124, 22, 241, 51, 93, 99, - 120, 219, 157, 22, 203, 246, 121, 93, 99, 120, 52, 22, 203, 219, 156, 93, - 99, 52, 120, 22, 241, 51, 93, 99, 67, 219, 157, 22, 203, 246, 121, 93, - 99, 67, 52, 22, 203, 219, 156, 93, 99, 52, 67, 22, 241, 51, 93, 99, 193, - 254, 34, 124, 22, 222, 254, 93, 99, 193, 254, 34, 124, 22, 233, 52, 93, - 99, 193, 254, 34, 120, 22, 233, 52, 93, 99, 193, 254, 34, 120, 22, 222, - 254, 93, 99, 193, 248, 7, 214, 160, 44, 216, 43, 232, 114, 233, 52, 93, - 99, 193, 248, 7, 214, 160, 43, 216, 43, 232, 114, 222, 254, 93, 99, 193, - 248, 7, 249, 138, 93, 99, 193, 233, 52, 93, 99, 193, 214, 163, 93, 99, - 193, 222, 254, 93, 99, 193, 246, 114, 93, 99, 114, 233, 52, 93, 99, 114, - 214, 163, 93, 99, 114, 222, 254, 93, 99, 114, 246, 114, 93, 99, 193, 43, - 22, 114, 222, 254, 93, 99, 193, 120, 22, 114, 246, 114, 93, 99, 114, 43, - 22, 193, 222, 254, 93, 99, 114, 120, 22, 193, 246, 114, 214, 160, 163, - 251, 221, 232, 114, 123, 245, 197, 251, 221, 232, 114, 123, 224, 25, 251, - 221, 232, 114, 134, 245, 195, 251, 221, 232, 114, 163, 251, 221, 232, - 114, 244, 89, 245, 195, 251, 221, 232, 114, 134, 224, 23, 251, 221, 232, - 114, 220, 124, 245, 195, 251, 221, 243, 236, 251, 221, 43, 220, 124, 245, - 195, 251, 221, 43, 134, 224, 23, 251, 221, 43, 244, 89, 245, 195, 251, - 221, 43, 163, 251, 221, 43, 134, 245, 195, 251, 221, 43, 123, 224, 25, - 251, 221, 43, 123, 245, 197, 251, 221, 44, 163, 251, 221, 193, 220, 94, - 231, 87, 220, 94, 248, 170, 220, 94, 214, 160, 123, 245, 197, 251, 221, - 44, 123, 245, 197, 251, 221, 224, 29, 232, 114, 233, 52, 224, 29, 232, - 114, 222, 254, 224, 29, 214, 160, 233, 52, 224, 29, 214, 160, 43, 22, - 232, 114, 43, 22, 232, 114, 222, 254, 224, 29, 214, 160, 43, 22, 232, - 114, 222, 254, 224, 29, 214, 160, 43, 22, 214, 160, 44, 22, 232, 114, - 233, 52, 224, 29, 214, 160, 43, 22, 214, 160, 44, 22, 232, 114, 222, 254, - 224, 29, 214, 160, 222, 254, 224, 29, 214, 160, 44, 22, 232, 114, 233, - 52, 224, 29, 214, 160, 44, 22, 232, 114, 43, 22, 232, 114, 222, 254, 85, - 218, 236, 71, 218, 236, 71, 42, 2, 222, 185, 249, 167, 71, 42, 249, 195, - 85, 4, 218, 236, 42, 2, 203, 244, 113, 42, 2, 67, 244, 113, 42, 2, 226, - 148, 249, 134, 244, 113, 42, 2, 214, 160, 43, 216, 43, 232, 114, 44, 244, - 113, 42, 2, 214, 160, 44, 216, 43, 232, 114, 43, 244, 113, 42, 2, 248, 7, - 249, 134, 244, 113, 85, 4, 218, 236, 71, 4, 218, 236, 85, 223, 119, 71, - 223, 119, 85, 67, 223, 119, 71, 67, 223, 119, 85, 226, 10, 71, 226, 10, - 85, 214, 162, 215, 226, 71, 214, 162, 215, 226, 85, 214, 162, 4, 215, - 226, 71, 214, 162, 4, 215, 226, 85, 222, 250, 215, 226, 71, 222, 250, - 215, 226, 85, 222, 250, 4, 215, 226, 71, 222, 250, 4, 215, 226, 85, 222, - 250, 225, 11, 71, 222, 250, 225, 11, 85, 246, 113, 215, 226, 71, 246, - 113, 215, 226, 85, 246, 113, 4, 215, 226, 71, 246, 113, 4, 215, 226, 85, - 233, 48, 215, 226, 71, 233, 48, 215, 226, 85, 233, 48, 4, 215, 226, 71, - 233, 48, 4, 215, 226, 85, 233, 48, 225, 11, 71, 233, 48, 225, 11, 85, - 248, 0, 71, 248, 0, 71, 248, 1, 249, 195, 85, 4, 248, 0, 244, 97, 232, - 110, 71, 250, 43, 246, 126, 250, 43, 250, 44, 2, 67, 244, 113, 251, 119, - 85, 250, 43, 250, 44, 2, 43, 163, 251, 229, 250, 44, 2, 44, 163, 251, - 229, 250, 44, 2, 232, 114, 163, 251, 229, 250, 44, 2, 214, 160, 163, 251, - 229, 250, 44, 2, 214, 160, 44, 224, 29, 251, 229, 250, 44, 2, 254, 164, - 251, 96, 214, 160, 43, 224, 29, 251, 229, 43, 163, 85, 250, 43, 44, 163, - 85, 250, 43, 235, 201, 251, 121, 235, 201, 71, 250, 43, 214, 160, 163, - 235, 201, 71, 250, 43, 232, 114, 163, 235, 201, 71, 250, 43, 214, 160, - 43, 224, 29, 250, 41, 254, 33, 214, 160, 44, 224, 29, 250, 41, 254, 33, - 232, 114, 44, 224, 29, 250, 41, 254, 33, 232, 114, 43, 224, 29, 250, 41, - 254, 33, 214, 160, 163, 250, 43, 232, 114, 163, 250, 43, 85, 232, 114, - 44, 215, 226, 85, 232, 114, 43, 215, 226, 85, 214, 160, 43, 215, 226, 85, - 214, 160, 44, 215, 226, 71, 251, 121, 42, 2, 43, 163, 251, 229, 42, 2, - 44, 163, 251, 229, 42, 2, 214, 160, 43, 248, 7, 163, 251, 229, 42, 2, - 232, 114, 44, 248, 7, 163, 251, 229, 71, 42, 2, 67, 251, 240, 232, 219, - 71, 214, 162, 215, 227, 2, 247, 128, 214, 162, 215, 227, 2, 43, 163, 251, - 229, 214, 162, 215, 227, 2, 44, 163, 251, 229, 233, 91, 250, 43, 71, 42, - 2, 214, 160, 43, 224, 28, 71, 42, 2, 232, 114, 43, 224, 28, 71, 42, 2, - 232, 114, 44, 224, 28, 71, 42, 2, 214, 160, 44, 224, 28, 71, 250, 44, 2, - 214, 160, 43, 224, 28, 71, 250, 44, 2, 232, 114, 43, 224, 28, 71, 250, - 44, 2, 232, 114, 44, 224, 28, 71, 250, 44, 2, 214, 160, 44, 224, 28, 214, - 160, 43, 215, 226, 214, 160, 44, 215, 226, 232, 114, 43, 215, 226, 71, - 231, 87, 218, 236, 85, 231, 87, 218, 236, 71, 231, 87, 4, 218, 236, 85, - 231, 87, 4, 218, 236, 232, 114, 44, 215, 226, 85, 218, 39, 2, 223, 135, - 249, 255, 214, 194, 219, 62, 249, 230, 85, 218, 158, 71, 218, 158, 232, - 234, 216, 133, 218, 38, 253, 242, 228, 76, 248, 46, 228, 76, 249, 203, - 226, 167, 85, 217, 1, 71, 217, 1, 252, 164, 251, 171, 252, 164, 93, 2, - 250, 137, 252, 164, 93, 2, 211, 178, 222, 0, 214, 195, 2, 223, 163, 246, - 92, 240, 250, 252, 30, 71, 220, 4, 225, 104, 85, 220, 4, 225, 104, 220, - 89, 223, 52, 222, 189, 244, 63, 241, 235, 251, 121, 85, 43, 225, 10, 235, - 249, 85, 44, 225, 10, 235, 249, 71, 43, 225, 10, 235, 249, 71, 120, 225, - 10, 235, 249, 71, 44, 225, 10, 235, 249, 71, 124, 225, 10, 235, 249, 219, - 103, 22, 249, 137, 250, 227, 50, 223, 175, 50, 251, 247, 50, 251, 33, - 254, 110, 226, 149, 249, 138, 250, 119, 223, 40, 249, 139, 64, 232, 124, - 249, 139, 64, 235, 122, 218, 159, 22, 249, 144, 244, 176, 87, 255, 1, - 220, 91, 242, 29, 22, 219, 191, 225, 223, 87, 210, 254, 211, 69, 215, - 216, 31, 241, 230, 215, 216, 31, 233, 113, 215, 216, 31, 244, 104, 215, - 216, 31, 216, 134, 215, 216, 31, 211, 239, 215, 216, 31, 212, 40, 215, - 216, 31, 230, 120, 215, 216, 31, 245, 231, 212, 1, 64, 248, 26, 71, 243, - 247, 244, 198, 71, 219, 76, 244, 198, 85, 219, 76, 244, 198, 71, 218, 39, - 2, 223, 135, 244, 100, 224, 25, 230, 133, 233, 86, 224, 25, 230, 133, - 231, 59, 244, 146, 50, 245, 231, 231, 195, 50, 235, 44, 221, 222, 214, - 145, 229, 98, 225, 23, 254, 20, 217, 41, 243, 59, 251, 11, 233, 25, 213, - 150, 232, 244, 221, 193, 222, 21, 251, 0, 254, 50, 225, 55, 71, 250, 125, - 234, 84, 71, 250, 125, 224, 17, 71, 250, 125, 222, 197, 71, 250, 125, - 251, 239, 71, 250, 125, 234, 36, 71, 250, 125, 225, 235, 85, 250, 125, - 234, 84, 85, 250, 125, 224, 17, 85, 250, 125, 222, 197, 85, 250, 125, - 251, 239, 85, 250, 125, 234, 36, 85, 250, 125, 225, 235, 85, 219, 18, - 218, 51, 71, 241, 235, 218, 51, 71, 248, 1, 218, 51, 85, 249, 253, 218, - 51, 71, 219, 18, 218, 51, 85, 241, 235, 218, 51, 85, 248, 1, 218, 51, 71, - 249, 253, 218, 51, 240, 250, 218, 240, 224, 25, 228, 52, 245, 197, 228, - 52, 252, 81, 245, 197, 228, 47, 252, 81, 219, 120, 228, 47, 230, 62, 244, - 74, 50, 230, 62, 229, 193, 50, 230, 62, 220, 78, 50, 212, 9, 183, 249, - 138, 245, 228, 183, 249, 138, 214, 171, 223, 115, 87, 223, 115, 16, 31, - 215, 48, 225, 37, 223, 115, 16, 31, 215, 47, 225, 37, 223, 115, 16, 31, - 215, 46, 225, 37, 223, 115, 16, 31, 215, 45, 225, 37, 223, 115, 16, 31, - 215, 44, 225, 37, 223, 115, 16, 31, 215, 43, 225, 37, 223, 115, 16, 31, - 215, 42, 225, 37, 223, 115, 16, 31, 243, 57, 231, 143, 85, 214, 171, 223, - 115, 87, 223, 116, 226, 24, 87, 226, 0, 226, 24, 87, 225, 177, 226, 24, - 50, 211, 255, 87, 247, 249, 244, 197, 247, 249, 244, 196, 247, 249, 244, - 195, 247, 249, 244, 194, 247, 249, 244, 193, 247, 249, 244, 192, 71, 250, - 44, 2, 59, 222, 254, 71, 250, 44, 2, 113, 247, 126, 85, 250, 44, 2, 71, - 59, 222, 254, 85, 250, 44, 2, 113, 71, 247, 126, 230, 147, 31, 211, 69, - 230, 147, 31, 210, 253, 247, 232, 31, 242, 138, 211, 69, 247, 232, 31, - 233, 19, 210, 253, 247, 232, 31, 233, 19, 211, 69, 247, 232, 31, 242, - 138, 210, 253, 71, 244, 81, 85, 244, 81, 242, 29, 22, 225, 107, 254, 128, - 249, 136, 217, 236, 218, 166, 64, 254, 235, 221, 208, 254, 178, 244, 59, - 243, 67, 218, 166, 64, 241, 209, 253, 207, 87, 244, 70, 226, 130, 71, - 218, 158, 134, 232, 214, 249, 183, 222, 254, 134, 232, 214, 249, 183, - 233, 52, 212, 50, 50, 125, 213, 130, 50, 246, 118, 244, 146, 50, 246, - 118, 231, 195, 50, 235, 210, 244, 146, 22, 231, 195, 50, 231, 195, 22, - 244, 146, 50, 231, 195, 2, 218, 105, 50, 231, 195, 2, 218, 105, 22, 231, - 195, 22, 244, 146, 50, 67, 231, 195, 2, 218, 105, 50, 203, 231, 195, 2, - 218, 105, 50, 231, 87, 71, 250, 43, 231, 87, 85, 250, 43, 231, 87, 4, 71, - 250, 43, 231, 158, 87, 247, 175, 87, 214, 169, 225, 255, 87, 249, 239, - 243, 231, 214, 141, 229, 93, 250, 169, 226, 65, 235, 50, 213, 185, 250, - 101, 85, 230, 134, 232, 231, 220, 114, 220, 149, 224, 8, 220, 132, 219, - 57, 252, 167, 252, 134, 92, 234, 144, 71, 246, 101, 231, 190, 71, 246, - 101, 234, 84, 85, 246, 101, 231, 190, 85, 246, 101, 234, 84, 219, 63, - 211, 230, 219, 66, 218, 39, 252, 59, 249, 255, 223, 162, 85, 219, 62, - 216, 135, 250, 0, 22, 223, 162, 215, 94, 71, 220, 4, 225, 104, 215, 94, - 85, 220, 4, 225, 104, 71, 248, 1, 236, 7, 218, 236, 249, 133, 233, 97, - 247, 201, 250, 252, 226, 170, 225, 107, 250, 253, 219, 90, 241, 219, 2, - 71, 249, 138, 37, 249, 133, 233, 97, 250, 161, 228, 80, 245, 132, 254, - 149, 226, 195, 43, 212, 26, 215, 252, 85, 215, 55, 43, 212, 26, 215, 252, - 71, 215, 55, 43, 212, 26, 215, 252, 85, 43, 233, 98, 231, 58, 71, 43, - 233, 98, 231, 58, 246, 97, 219, 84, 50, 114, 71, 246, 113, 215, 226, 43, - 250, 8, 245, 132, 92, 222, 0, 244, 183, 248, 7, 236, 7, 71, 250, 44, 236, - 7, 85, 218, 236, 85, 215, 193, 223, 63, 43, 245, 131, 223, 63, 43, 245, - 130, 253, 219, 16, 31, 214, 145, 114, 250, 44, 2, 218, 105, 22, 113, 170, - 48, 225, 192, 222, 251, 235, 212, 225, 192, 233, 49, 235, 212, 225, 192, - 235, 200, 225, 192, 85, 249, 139, 226, 201, 220, 31, 220, 19, 219, 231, - 250, 69, 250, 234, 241, 164, 219, 128, 243, 68, 211, 230, 240, 227, 243, - 68, 2, 242, 19, 231, 178, 16, 31, 232, 235, 230, 120, 214, 195, 226, 201, - 242, 129, 244, 20, 244, 82, 236, 7, 241, 66, 244, 137, 222, 16, 42, 244, - 19, 249, 167, 219, 106, 240, 119, 219, 109, 225, 171, 2, 252, 167, 216, - 243, 235, 137, 252, 154, 87, 241, 238, 242, 140, 87, 243, 239, 224, 145, - 249, 111, 226, 201, 85, 218, 236, 71, 244, 82, 2, 203, 230, 229, 85, 218, - 106, 214, 160, 251, 225, 221, 195, 85, 221, 195, 232, 114, 251, 225, 221, - 195, 71, 221, 195, 71, 114, 250, 138, 79, 217, 2, 232, 160, 50, 217, 54, - 246, 96, 254, 200, 245, 127, 223, 160, 244, 93, 223, 160, 242, 22, 213, - 174, 242, 22, 211, 198, 242, 22, 232, 114, 44, 225, 201, 225, 201, 214, - 160, 44, 225, 201, 71, 228, 235, 85, 228, 235, 250, 138, 79, 114, 250, - 138, 79, 230, 89, 211, 178, 114, 230, 89, 211, 178, 252, 164, 211, 178, - 114, 252, 164, 211, 178, 226, 130, 26, 249, 138, 114, 26, 249, 138, 204, - 250, 183, 249, 138, 114, 204, 250, 183, 249, 138, 7, 249, 138, 220, 93, - 71, 7, 249, 138, 226, 130, 7, 249, 138, 231, 192, 249, 138, 218, 159, 64, - 248, 157, 244, 19, 217, 16, 253, 224, 244, 19, 252, 165, 253, 224, 114, - 244, 19, 252, 165, 253, 224, 244, 19, 249, 251, 253, 224, 85, 244, 19, - 225, 12, 218, 158, 71, 244, 19, 225, 12, 218, 158, 219, 13, 218, 113, - 226, 130, 71, 218, 158, 37, 71, 218, 158, 204, 250, 183, 85, 218, 158, - 85, 250, 183, 71, 218, 158, 226, 130, 85, 218, 158, 114, 226, 130, 85, - 218, 158, 225, 63, 218, 158, 220, 93, 71, 218, 158, 114, 253, 224, 204, - 250, 183, 253, 224, 245, 201, 218, 246, 253, 224, 245, 201, 225, 12, 85, - 218, 158, 245, 201, 225, 12, 225, 63, 218, 158, 219, 127, 225, 12, 85, - 218, 158, 245, 201, 225, 12, 223, 117, 85, 218, 158, 114, 245, 201, 225, - 12, 223, 117, 85, 218, 158, 215, 77, 225, 12, 85, 218, 158, 219, 122, - 225, 12, 253, 224, 217, 16, 253, 224, 204, 250, 183, 217, 16, 253, 224, - 114, 217, 16, 253, 224, 219, 127, 225, 160, 85, 22, 71, 244, 62, 85, 244, - 62, 71, 244, 62, 245, 201, 225, 160, 226, 130, 85, 244, 62, 37, 204, 250, - 183, 245, 201, 225, 12, 218, 158, 114, 217, 16, 225, 63, 253, 224, 219, - 64, 216, 106, 215, 219, 219, 64, 114, 250, 122, 219, 64, 219, 15, 114, - 219, 15, 252, 165, 253, 224, 245, 201, 217, 16, 224, 174, 253, 224, 114, - 245, 201, 217, 16, 224, 174, 253, 224, 249, 139, 79, 220, 93, 71, 250, - 43, 152, 92, 249, 139, 79, 232, 114, 44, 246, 94, 71, 218, 236, 214, 160, - 44, 246, 94, 71, 218, 236, 232, 114, 44, 220, 93, 71, 218, 236, 214, 160, - 44, 220, 93, 71, 218, 236, 85, 224, 16, 164, 226, 151, 71, 224, 16, 164, - 226, 151, 71, 245, 39, 164, 226, 151, 85, 248, 1, 230, 187, 71, 211, 178, - 114, 245, 39, 164, 87, 193, 67, 130, 231, 87, 67, 130, 114, 67, 130, 114, - 219, 157, 215, 94, 249, 228, 224, 1, 164, 226, 151, 114, 219, 157, 249, - 228, 224, 1, 164, 226, 151, 114, 52, 215, 94, 249, 228, 224, 1, 164, 226, - 151, 114, 52, 249, 228, 224, 1, 164, 226, 151, 114, 121, 219, 157, 249, - 228, 224, 1, 164, 226, 151, 114, 121, 52, 249, 228, 224, 1, 164, 226, - 151, 249, 99, 218, 142, 226, 19, 5, 226, 151, 114, 245, 39, 164, 226, - 151, 114, 241, 235, 245, 39, 164, 226, 151, 114, 85, 241, 234, 222, 189, - 114, 85, 241, 235, 251, 121, 244, 63, 241, 234, 222, 189, 244, 63, 241, - 235, 251, 121, 231, 87, 43, 226, 8, 226, 151, 231, 87, 44, 226, 8, 226, - 151, 231, 87, 244, 71, 43, 226, 8, 226, 151, 231, 87, 244, 71, 44, 226, - 8, 226, 151, 231, 87, 233, 48, 254, 118, 251, 166, 226, 151, 231, 87, - 222, 250, 254, 118, 251, 166, 226, 151, 114, 233, 48, 254, 118, 224, 1, - 164, 226, 151, 114, 222, 250, 254, 118, 224, 1, 164, 226, 151, 114, 233, - 48, 254, 118, 251, 166, 226, 151, 114, 222, 250, 254, 118, 251, 166, 226, - 151, 193, 43, 216, 7, 220, 55, 251, 166, 226, 151, 193, 44, 216, 7, 220, - 55, 251, 166, 226, 151, 231, 87, 43, 249, 107, 251, 166, 226, 151, 231, - 87, 44, 249, 107, 251, 166, 226, 151, 247, 212, 152, 37, 21, 111, 247, - 212, 152, 37, 21, 105, 247, 212, 152, 37, 21, 158, 247, 212, 152, 37, 21, - 161, 247, 212, 152, 37, 21, 190, 247, 212, 152, 37, 21, 195, 247, 212, - 152, 37, 21, 199, 247, 212, 152, 37, 21, 196, 247, 212, 152, 37, 21, 201, - 247, 212, 152, 37, 54, 216, 248, 247, 212, 37, 35, 21, 111, 247, 212, 37, - 35, 21, 105, 247, 212, 37, 35, 21, 158, 247, 212, 37, 35, 21, 161, 247, - 212, 37, 35, 21, 190, 247, 212, 37, 35, 21, 195, 247, 212, 37, 35, 21, - 199, 247, 212, 37, 35, 21, 196, 247, 212, 37, 35, 21, 201, 247, 212, 37, - 35, 54, 216, 248, 247, 212, 152, 37, 35, 21, 111, 247, 212, 152, 37, 35, - 21, 105, 247, 212, 152, 37, 35, 21, 158, 247, 212, 152, 37, 35, 21, 161, - 247, 212, 152, 37, 35, 21, 190, 247, 212, 152, 37, 35, 21, 195, 247, 212, - 152, 37, 35, 21, 199, 247, 212, 152, 37, 35, 21, 196, 247, 212, 152, 37, - 35, 21, 201, 247, 212, 152, 37, 35, 54, 216, 248, 114, 211, 246, 97, 75, - 114, 96, 50, 114, 230, 187, 50, 114, 247, 177, 50, 114, 219, 30, 245, - 228, 75, 114, 97, 75, 114, 228, 61, 245, 228, 75, 246, 106, 225, 14, 97, - 75, 114, 222, 186, 97, 75, 215, 225, 97, 75, 114, 215, 225, 97, 75, 248, - 163, 215, 225, 97, 75, 114, 248, 163, 215, 225, 97, 75, 85, 97, 75, 216, - 145, 216, 13, 97, 254, 1, 216, 145, 251, 181, 97, 254, 1, 85, 97, 254, 1, - 114, 85, 249, 99, 246, 112, 22, 97, 75, 114, 85, 249, 99, 214, 153, 22, - 97, 75, 218, 233, 85, 97, 75, 114, 249, 214, 85, 97, 75, 222, 249, 71, - 97, 75, 233, 47, 71, 97, 75, 252, 191, 220, 93, 71, 97, 75, 243, 249, - 220, 93, 71, 97, 75, 114, 232, 114, 222, 248, 71, 97, 75, 114, 214, 160, - 222, 248, 71, 97, 75, 228, 54, 232, 114, 222, 248, 71, 97, 75, 249, 107, - 232, 129, 228, 54, 214, 160, 222, 248, 71, 97, 75, 37, 114, 71, 97, 75, - 211, 252, 97, 75, 251, 228, 219, 30, 245, 228, 75, 251, 228, 97, 75, 251, - 228, 228, 61, 245, 228, 75, 114, 251, 228, 219, 30, 245, 228, 75, 114, - 251, 228, 97, 75, 114, 251, 228, 228, 61, 245, 228, 75, 217, 18, 97, 75, - 114, 217, 17, 97, 75, 212, 18, 97, 75, 114, 212, 18, 97, 75, 226, 176, - 97, 75, 52, 249, 107, 232, 129, 134, 247, 222, 254, 117, 71, 215, 227, - 249, 195, 4, 71, 215, 226, 225, 174, 204, 218, 64, 204, 218, 22, 43, 222, - 92, 252, 181, 248, 68, 44, 222, 92, 252, 181, 248, 68, 177, 2, 59, 235, - 222, 223, 53, 219, 49, 224, 204, 218, 64, 218, 23, 224, 204, 219, 48, 67, - 252, 149, 2, 203, 91, 11, 222, 231, 248, 6, 200, 247, 176, 11, 244, 183, - 248, 6, 92, 232, 152, 254, 126, 92, 232, 152, 226, 162, 71, 248, 1, 2, - 250, 181, 247, 128, 22, 2, 247, 128, 245, 178, 64, 226, 174, 214, 152, - 232, 114, 44, 249, 169, 2, 247, 128, 214, 160, 43, 249, 169, 2, 247, 128, - 43, 226, 132, 235, 72, 44, 226, 132, 235, 72, 243, 236, 226, 132, 235, - 72, 233, 91, 120, 217, 88, 233, 91, 124, 217, 88, 43, 22, 44, 52, 215, - 93, 43, 22, 44, 217, 88, 43, 230, 92, 200, 44, 217, 88, 200, 43, 217, 88, - 120, 217, 89, 2, 250, 44, 48, 232, 111, 247, 181, 251, 86, 203, 222, 135, - 71, 249, 213, 248, 0, 71, 249, 213, 248, 1, 2, 140, 216, 115, 71, 249, - 213, 248, 1, 2, 97, 216, 115, 71, 42, 2, 140, 216, 115, 71, 42, 2, 97, - 216, 115, 11, 43, 71, 42, 127, 11, 44, 71, 42, 127, 11, 43, 254, 118, - 127, 11, 44, 254, 118, 127, 11, 43, 52, 254, 118, 127, 11, 44, 52, 254, - 118, 127, 11, 43, 71, 216, 7, 220, 55, 127, 11, 44, 71, 216, 7, 220, 55, - 127, 11, 43, 244, 71, 226, 7, 11, 44, 244, 71, 226, 7, 214, 153, 224, 27, - 75, 246, 112, 224, 27, 75, 254, 96, 243, 105, 250, 44, 75, 250, 10, 243, - 105, 250, 44, 75, 44, 80, 2, 37, 225, 25, 200, 140, 75, 200, 97, 75, 200, - 43, 44, 75, 200, 140, 52, 75, 200, 97, 52, 75, 200, 43, 44, 52, 75, 200, - 140, 80, 243, 251, 130, 200, 97, 80, 243, 251, 130, 200, 140, 52, 80, - 243, 251, 130, 200, 97, 52, 80, 243, 251, 130, 200, 97, 218, 232, 75, 46, - 47, 251, 223, 46, 47, 247, 125, 46, 47, 246, 253, 46, 47, 247, 124, 46, - 47, 246, 189, 46, 47, 247, 60, 46, 47, 246, 252, 46, 47, 247, 123, 46, - 47, 246, 157, 46, 47, 247, 28, 46, 47, 246, 220, 46, 47, 247, 91, 46, 47, - 246, 188, 46, 47, 247, 59, 46, 47, 246, 251, 46, 47, 247, 122, 46, 47, - 246, 141, 46, 47, 247, 12, 46, 47, 246, 204, 46, 47, 247, 75, 46, 47, - 246, 172, 46, 47, 247, 43, 46, 47, 246, 235, 46, 47, 247, 106, 46, 47, - 246, 156, 46, 47, 247, 27, 46, 47, 246, 219, 46, 47, 247, 90, 46, 47, - 246, 187, 46, 47, 247, 58, 46, 47, 246, 250, 46, 47, 247, 121, 46, 47, - 246, 133, 46, 47, 247, 4, 46, 47, 246, 196, 46, 47, 247, 67, 46, 47, 246, - 164, 46, 47, 247, 35, 46, 47, 246, 227, 46, 47, 247, 98, 46, 47, 246, - 148, 46, 47, 247, 19, 46, 47, 246, 211, 46, 47, 247, 82, 46, 47, 246, - 179, 46, 47, 247, 50, 46, 47, 246, 242, 46, 47, 247, 113, 46, 47, 246, - 140, 46, 47, 247, 11, 46, 47, 246, 203, 46, 47, 247, 74, 46, 47, 246, - 171, 46, 47, 247, 42, 46, 47, 246, 234, 46, 47, 247, 105, 46, 47, 246, - 155, 46, 47, 247, 26, 46, 47, 246, 218, 46, 47, 247, 89, 46, 47, 246, - 186, 46, 47, 247, 57, 46, 47, 246, 249, 46, 47, 247, 120, 46, 47, 246, - 129, 46, 47, 247, 0, 46, 47, 246, 192, 46, 47, 247, 63, 46, 47, 246, 160, - 46, 47, 247, 31, 46, 47, 246, 223, 46, 47, 247, 94, 46, 47, 246, 144, 46, - 47, 247, 15, 46, 47, 246, 207, 46, 47, 247, 78, 46, 47, 246, 175, 46, 47, - 247, 46, 46, 47, 246, 238, 46, 47, 247, 109, 46, 47, 246, 136, 46, 47, - 247, 7, 46, 47, 246, 199, 46, 47, 247, 70, 46, 47, 246, 167, 46, 47, 247, - 38, 46, 47, 246, 230, 46, 47, 247, 101, 46, 47, 246, 151, 46, 47, 247, - 22, 46, 47, 246, 214, 46, 47, 247, 85, 46, 47, 246, 182, 46, 47, 247, 53, - 46, 47, 246, 245, 46, 47, 247, 116, 46, 47, 246, 132, 46, 47, 247, 3, 46, - 47, 246, 195, 46, 47, 247, 66, 46, 47, 246, 163, 46, 47, 247, 34, 46, 47, - 246, 226, 46, 47, 247, 97, 46, 47, 246, 147, 46, 47, 247, 18, 46, 47, - 246, 210, 46, 47, 247, 81, 46, 47, 246, 178, 46, 47, 247, 49, 46, 47, - 246, 241, 46, 47, 247, 112, 46, 47, 246, 139, 46, 47, 247, 10, 46, 47, - 246, 202, 46, 47, 247, 73, 46, 47, 246, 170, 46, 47, 247, 41, 46, 47, - 246, 233, 46, 47, 247, 104, 46, 47, 246, 154, 46, 47, 247, 25, 46, 47, - 246, 217, 46, 47, 247, 88, 46, 47, 246, 185, 46, 47, 247, 56, 46, 47, - 246, 248, 46, 47, 247, 119, 46, 47, 246, 127, 46, 47, 246, 254, 46, 47, - 246, 190, 46, 47, 247, 61, 46, 47, 246, 158, 46, 47, 247, 29, 46, 47, - 246, 221, 46, 47, 247, 92, 46, 47, 246, 142, 46, 47, 247, 13, 46, 47, - 246, 205, 46, 47, 247, 76, 46, 47, 246, 173, 46, 47, 247, 44, 46, 47, - 246, 236, 46, 47, 247, 107, 46, 47, 246, 134, 46, 47, 247, 5, 46, 47, - 246, 197, 46, 47, 247, 68, 46, 47, 246, 165, 46, 47, 247, 36, 46, 47, - 246, 228, 46, 47, 247, 99, 46, 47, 246, 149, 46, 47, 247, 20, 46, 47, - 246, 212, 46, 47, 247, 83, 46, 47, 246, 180, 46, 47, 247, 51, 46, 47, - 246, 243, 46, 47, 247, 114, 46, 47, 246, 130, 46, 47, 247, 1, 46, 47, - 246, 193, 46, 47, 247, 64, 46, 47, 246, 161, 46, 47, 247, 32, 46, 47, - 246, 224, 46, 47, 247, 95, 46, 47, 246, 145, 46, 47, 247, 16, 46, 47, - 246, 208, 46, 47, 247, 79, 46, 47, 246, 176, 46, 47, 247, 47, 46, 47, - 246, 239, 46, 47, 247, 110, 46, 47, 246, 137, 46, 47, 247, 8, 46, 47, - 246, 200, 46, 47, 247, 71, 46, 47, 246, 168, 46, 47, 247, 39, 46, 47, - 246, 231, 46, 47, 247, 102, 46, 47, 246, 152, 46, 47, 247, 23, 46, 47, - 246, 215, 46, 47, 247, 86, 46, 47, 246, 183, 46, 47, 247, 54, 46, 47, - 246, 246, 46, 47, 247, 117, 46, 47, 246, 128, 46, 47, 246, 255, 46, 47, - 246, 191, 46, 47, 247, 62, 46, 47, 246, 159, 46, 47, 247, 30, 46, 47, - 246, 222, 46, 47, 247, 93, 46, 47, 246, 143, 46, 47, 247, 14, 46, 47, - 246, 206, 46, 47, 247, 77, 46, 47, 246, 174, 46, 47, 247, 45, 46, 47, - 246, 237, 46, 47, 247, 108, 46, 47, 246, 135, 46, 47, 247, 6, 46, 47, - 246, 198, 46, 47, 247, 69, 46, 47, 246, 166, 46, 47, 247, 37, 46, 47, - 246, 229, 46, 47, 247, 100, 46, 47, 246, 150, 46, 47, 247, 21, 46, 47, - 246, 213, 46, 47, 247, 84, 46, 47, 246, 181, 46, 47, 247, 52, 46, 47, - 246, 244, 46, 47, 247, 115, 46, 47, 246, 131, 46, 47, 247, 2, 46, 47, - 246, 194, 46, 47, 247, 65, 46, 47, 246, 162, 46, 47, 247, 33, 46, 47, - 246, 225, 46, 47, 247, 96, 46, 47, 246, 146, 46, 47, 247, 17, 46, 47, - 246, 209, 46, 47, 247, 80, 46, 47, 246, 177, 46, 47, 247, 48, 46, 47, - 246, 240, 46, 47, 247, 111, 46, 47, 246, 138, 46, 47, 247, 9, 46, 47, - 246, 201, 46, 47, 247, 72, 46, 47, 246, 169, 46, 47, 247, 40, 46, 47, - 246, 232, 46, 47, 247, 103, 46, 47, 246, 153, 46, 47, 247, 24, 46, 47, - 246, 216, 46, 47, 247, 87, 46, 47, 246, 184, 46, 47, 247, 55, 46, 47, - 246, 247, 46, 47, 247, 118, 97, 215, 58, 80, 2, 67, 91, 97, 215, 58, 80, - 2, 52, 67, 91, 140, 52, 80, 2, 67, 91, 97, 52, 80, 2, 67, 91, 43, 44, 52, - 80, 2, 67, 91, 97, 215, 58, 80, 243, 251, 130, 140, 52, 80, 243, 251, - 130, 97, 52, 80, 243, 251, 130, 246, 112, 80, 2, 203, 91, 214, 153, 80, - 2, 203, 91, 214, 153, 215, 212, 75, 246, 112, 215, 212, 75, 140, 52, 248, - 165, 75, 97, 52, 248, 165, 75, 140, 215, 212, 248, 165, 75, 97, 215, 212, - 248, 165, 75, 97, 215, 58, 215, 212, 248, 165, 75, 97, 80, 2, 246, 126, - 218, 141, 214, 153, 80, 216, 43, 130, 246, 112, 80, 216, 43, 130, 97, 80, - 2, 217, 79, 2, 67, 91, 97, 80, 2, 217, 79, 2, 52, 67, 91, 97, 215, 58, - 80, 2, 217, 78, 97, 215, 58, 80, 2, 217, 79, 2, 67, 91, 97, 215, 58, 80, - 2, 217, 79, 2, 52, 67, 91, 140, 254, 3, 97, 254, 3, 140, 52, 254, 3, 97, - 52, 254, 3, 140, 80, 216, 43, 85, 248, 0, 97, 80, 216, 43, 85, 248, 0, - 140, 80, 243, 251, 252, 149, 216, 43, 85, 248, 0, 97, 80, 243, 251, 252, - 149, 216, 43, 85, 248, 0, 228, 61, 212, 9, 22, 219, 30, 245, 228, 75, - 228, 61, 245, 228, 22, 219, 30, 212, 9, 75, 228, 61, 212, 9, 80, 2, 103, - 228, 61, 245, 228, 80, 2, 103, 219, 30, 245, 228, 80, 2, 103, 219, 30, - 212, 9, 80, 2, 103, 228, 61, 212, 9, 80, 22, 228, 61, 245, 228, 75, 228, - 61, 245, 228, 80, 22, 219, 30, 245, 228, 75, 219, 30, 245, 228, 80, 22, - 219, 30, 212, 9, 75, 219, 30, 212, 9, 80, 22, 228, 61, 212, 9, 75, 222, - 231, 248, 7, 249, 133, 244, 183, 248, 6, 244, 183, 248, 7, 249, 133, 222, - 231, 248, 6, 219, 30, 245, 228, 80, 249, 133, 228, 61, 245, 228, 75, 228, - 61, 245, 228, 80, 249, 133, 219, 30, 245, 228, 75, 244, 183, 248, 7, 249, - 133, 228, 61, 245, 228, 75, 222, 231, 248, 7, 249, 133, 219, 30, 245, - 228, 75, 228, 61, 245, 228, 80, 249, 133, 228, 61, 212, 9, 75, 228, 61, - 212, 9, 80, 249, 133, 228, 61, 245, 228, 75, 212, 36, 80, 225, 10, 247, - 203, 222, 254, 80, 225, 10, 97, 216, 189, 249, 98, 214, 152, 80, 225, 10, - 97, 216, 189, 249, 98, 246, 111, 80, 225, 10, 246, 112, 216, 189, 249, - 98, 233, 43, 80, 225, 10, 246, 112, 216, 189, 249, 98, 222, 244, 222, - 247, 254, 34, 250, 10, 75, 233, 46, 254, 34, 254, 96, 75, 216, 15, 254, - 34, 254, 96, 75, 251, 183, 254, 34, 254, 96, 75, 216, 15, 254, 34, 250, - 10, 80, 2, 230, 186, 216, 15, 254, 34, 254, 96, 80, 2, 225, 25, 232, 114, - 44, 220, 154, 250, 10, 75, 232, 114, 43, 220, 154, 254, 96, 75, 254, 96, - 250, 8, 250, 44, 75, 250, 10, 250, 8, 250, 44, 75, 97, 80, 72, 219, 253, - 140, 75, 140, 80, 72, 219, 253, 97, 75, 219, 253, 97, 80, 72, 140, 75, - 97, 80, 2, 96, 51, 140, 80, 2, 96, 51, 97, 80, 216, 140, 211, 178, 43, - 44, 80, 216, 140, 4, 250, 43, 214, 153, 215, 58, 80, 243, 251, 4, 250, - 43, 43, 252, 147, 120, 44, 252, 147, 124, 242, 5, 43, 252, 147, 124, 44, - 252, 147, 120, 242, 5, 120, 252, 147, 44, 124, 252, 147, 43, 242, 5, 120, - 252, 147, 43, 124, 252, 147, 44, 242, 5, 43, 252, 147, 120, 44, 252, 147, - 120, 242, 5, 120, 252, 147, 44, 124, 252, 147, 44, 242, 5, 43, 252, 147, - 124, 44, 252, 147, 124, 242, 5, 120, 252, 147, 43, 124, 252, 147, 43, - 242, 5, 140, 242, 6, 2, 252, 147, 120, 216, 43, 130, 97, 242, 6, 2, 252, - 147, 120, 216, 43, 130, 214, 153, 242, 6, 2, 252, 147, 44, 216, 43, 130, - 246, 112, 242, 6, 2, 252, 147, 44, 216, 43, 130, 140, 242, 6, 2, 252, - 147, 124, 216, 43, 130, 97, 242, 6, 2, 252, 147, 124, 216, 43, 130, 214, - 153, 242, 6, 2, 252, 147, 43, 216, 43, 130, 246, 112, 242, 6, 2, 252, - 147, 43, 216, 43, 130, 140, 242, 6, 2, 252, 147, 120, 243, 251, 130, 97, - 242, 6, 2, 252, 147, 120, 243, 251, 130, 214, 153, 242, 6, 2, 252, 147, - 44, 243, 251, 130, 246, 112, 242, 6, 2, 252, 147, 44, 243, 251, 130, 140, - 242, 6, 2, 252, 147, 124, 243, 251, 130, 97, 242, 6, 2, 252, 147, 124, - 243, 251, 130, 214, 153, 242, 6, 2, 252, 147, 43, 243, 251, 130, 246, - 112, 242, 6, 2, 252, 147, 43, 243, 251, 130, 140, 242, 6, 2, 252, 147, - 120, 72, 140, 242, 6, 2, 252, 147, 246, 114, 214, 153, 242, 6, 2, 252, - 147, 43, 252, 38, 214, 153, 242, 6, 2, 252, 147, 222, 254, 97, 242, 6, 2, - 252, 147, 120, 72, 97, 242, 6, 2, 252, 147, 246, 114, 246, 112, 242, 6, - 2, 252, 147, 43, 252, 38, 246, 112, 242, 6, 2, 252, 147, 222, 254, 140, - 242, 6, 2, 252, 147, 120, 72, 97, 242, 6, 2, 252, 147, 214, 163, 140, - 242, 6, 2, 252, 147, 124, 72, 97, 242, 6, 2, 252, 147, 246, 114, 97, 242, - 6, 2, 252, 147, 120, 72, 140, 242, 6, 2, 252, 147, 214, 163, 97, 242, 6, - 2, 252, 147, 124, 72, 140, 242, 6, 2, 252, 147, 246, 114, 140, 242, 6, 2, - 252, 147, 120, 72, 200, 248, 164, 140, 242, 6, 2, 252, 147, 124, 252, 51, - 200, 248, 164, 97, 242, 6, 2, 252, 147, 120, 72, 200, 248, 164, 97, 242, - 6, 2, 252, 147, 124, 252, 51, 200, 248, 164, 214, 153, 242, 6, 2, 252, - 147, 43, 252, 38, 246, 112, 242, 6, 2, 252, 147, 222, 254, 246, 112, 242, - 6, 2, 252, 147, 43, 252, 38, 214, 153, 242, 6, 2, 252, 147, 222, 254, 44, - 52, 80, 2, 222, 185, 241, 242, 245, 106, 5, 72, 97, 75, 216, 90, 226, - 172, 72, 97, 75, 140, 80, 72, 216, 90, 226, 171, 97, 80, 72, 216, 90, - 226, 171, 97, 80, 72, 254, 156, 128, 112, 233, 21, 72, 140, 75, 140, 80, - 216, 140, 233, 20, 242, 137, 72, 97, 75, 218, 65, 72, 97, 75, 140, 80, - 216, 140, 218, 64, 218, 23, 72, 140, 75, 43, 244, 99, 217, 78, 44, 244, - 99, 217, 78, 120, 244, 99, 217, 78, 124, 244, 99, 217, 78, 215, 212, 67, - 252, 149, 248, 68, 210, 160, 189, 218, 244, 210, 160, 189, 215, 49, 249, - 234, 43, 71, 249, 107, 127, 44, 71, 249, 107, 127, 43, 71, 226, 7, 44, - 71, 226, 7, 210, 160, 189, 43, 236, 22, 127, 210, 160, 189, 44, 236, 22, - 127, 210, 160, 189, 43, 251, 250, 127, 210, 160, 189, 44, 251, 250, 127, - 43, 42, 251, 166, 2, 214, 183, 44, 42, 251, 166, 2, 214, 183, 43, 42, - 251, 166, 2, 216, 116, 236, 7, 216, 15, 249, 168, 44, 42, 251, 166, 2, - 216, 116, 236, 7, 251, 183, 249, 168, 43, 42, 251, 166, 2, 216, 116, 236, - 7, 251, 183, 249, 168, 44, 42, 251, 166, 2, 216, 116, 236, 7, 216, 15, - 249, 168, 43, 254, 118, 251, 166, 2, 247, 128, 44, 254, 118, 251, 166, 2, - 247, 128, 43, 254, 34, 233, 21, 127, 44, 254, 34, 242, 137, 127, 52, 43, - 254, 34, 242, 137, 127, 52, 44, 254, 34, 233, 21, 127, 43, 85, 216, 7, - 220, 55, 127, 44, 85, 216, 7, 220, 55, 127, 246, 126, 244, 143, 67, 210, - 35, 232, 219, 231, 93, 254, 118, 226, 174, 233, 52, 44, 254, 118, 214, - 12, 2, 218, 236, 231, 93, 44, 254, 118, 2, 247, 128, 254, 118, 2, 222, - 94, 235, 222, 255, 12, 254, 117, 219, 1, 254, 118, 226, 174, 233, 52, - 219, 1, 254, 118, 226, 174, 214, 163, 215, 94, 254, 117, 223, 52, 254, - 117, 254, 118, 2, 214, 183, 223, 52, 254, 118, 2, 214, 183, 226, 252, - 254, 118, 226, 174, 214, 163, 226, 252, 254, 118, 226, 174, 246, 114, - 231, 93, 254, 118, 2, 204, 254, 13, 245, 148, 236, 7, 80, 225, 10, 120, - 22, 222, 254, 231, 93, 254, 118, 2, 204, 254, 13, 245, 148, 236, 7, 80, - 225, 10, 120, 22, 233, 52, 231, 93, 254, 118, 2, 204, 254, 13, 245, 148, - 236, 7, 80, 225, 10, 124, 22, 222, 254, 231, 93, 254, 118, 2, 204, 254, - 13, 245, 148, 236, 7, 80, 225, 10, 124, 22, 233, 52, 231, 93, 254, 118, - 2, 204, 254, 13, 245, 148, 236, 7, 80, 225, 10, 44, 22, 214, 163, 231, - 93, 254, 118, 2, 204, 254, 13, 245, 148, 236, 7, 80, 225, 10, 43, 22, - 214, 163, 231, 93, 254, 118, 2, 204, 254, 13, 245, 148, 236, 7, 80, 225, - 10, 44, 22, 246, 114, 231, 93, 254, 118, 2, 204, 254, 13, 245, 148, 236, - 7, 80, 225, 10, 43, 22, 246, 114, 223, 52, 245, 160, 220, 129, 245, 160, - 220, 130, 2, 226, 127, 245, 160, 220, 130, 2, 4, 250, 44, 48, 245, 160, - 220, 130, 2, 44, 80, 48, 245, 160, 220, 130, 2, 43, 80, 48, 250, 44, 2, - 203, 130, 37, 67, 130, 37, 226, 11, 37, 223, 53, 219, 48, 37, 225, 174, - 250, 44, 247, 181, 251, 86, 203, 252, 149, 22, 216, 15, 163, 247, 181, - 251, 86, 67, 130, 250, 44, 2, 218, 25, 211, 178, 37, 254, 95, 247, 177, - 50, 120, 80, 216, 140, 250, 43, 37, 71, 251, 121, 37, 251, 121, 37, 233, - 20, 37, 242, 136, 250, 44, 2, 4, 250, 44, 216, 43, 216, 197, 222, 254, - 250, 44, 2, 113, 203, 218, 93, 216, 43, 216, 197, 222, 254, 92, 222, 231, - 248, 7, 219, 97, 92, 244, 183, 248, 7, 219, 97, 92, 253, 224, 92, 4, 250, - 43, 92, 218, 236, 113, 235, 71, 218, 234, 215, 227, 2, 59, 48, 215, 227, - 2, 214, 183, 222, 94, 236, 7, 215, 226, 215, 227, 2, 220, 136, 253, 215, - 251, 182, 44, 215, 227, 72, 43, 215, 226, 43, 215, 227, 252, 38, 67, 130, - 67, 252, 149, 252, 38, 44, 215, 226, 251, 173, 2, 43, 163, 251, 229, 251, - 173, 2, 44, 163, 251, 229, 85, 251, 172, 30, 2, 43, 163, 251, 229, 30, 2, - 44, 163, 251, 229, 71, 240, 243, 85, 240, 243, 43, 211, 244, 244, 143, - 44, 211, 244, 244, 143, 43, 52, 211, 244, 244, 143, 44, 52, 211, 244, - 244, 143, 235, 255, 235, 241, 216, 113, 115, 235, 241, 235, 242, 229, - 107, 2, 67, 130, 246, 120, 230, 92, 42, 2, 249, 189, 226, 131, 235, 253, - 253, 245, 219, 221, 224, 183, 245, 106, 5, 22, 219, 99, 226, 11, 245, - 106, 5, 22, 219, 99, 226, 12, 2, 216, 90, 48, 240, 111, 216, 43, 22, 219, - 99, 226, 11, 242, 190, 218, 157, 216, 186, 246, 113, 215, 227, 2, 43, - 163, 251, 229, 246, 113, 215, 227, 2, 44, 163, 251, 229, 85, 248, 1, 2, - 124, 75, 85, 232, 110, 71, 250, 44, 2, 124, 75, 85, 250, 44, 2, 124, 75, - 245, 93, 71, 218, 236, 245, 93, 85, 218, 236, 245, 93, 71, 248, 0, 245, - 93, 85, 248, 0, 245, 93, 71, 250, 43, 245, 93, 85, 250, 43, 222, 134, - 223, 53, 219, 49, 226, 171, 219, 49, 2, 226, 127, 223, 53, 219, 49, 2, - 203, 91, 252, 1, 219, 48, 252, 1, 223, 53, 219, 48, 52, 225, 25, 215, - 212, 225, 25, 233, 48, 249, 99, 254, 118, 127, 222, 250, 249, 99, 254, - 118, 127, 216, 79, 230, 184, 230, 29, 37, 59, 226, 171, 230, 29, 37, 96, - 226, 171, 230, 29, 37, 30, 226, 171, 230, 29, 214, 176, 226, 172, 2, 247, - 128, 230, 29, 214, 176, 226, 172, 2, 225, 25, 230, 29, 42, 235, 206, 226, - 171, 230, 29, 42, 214, 176, 226, 171, 113, 232, 152, 22, 226, 171, 113, - 232, 152, 177, 226, 171, 230, 29, 30, 226, 171, 230, 159, 113, 218, 44, - 218, 42, 2, 235, 218, 224, 27, 235, 219, 226, 171, 244, 107, 226, 3, 235, - 218, 235, 219, 2, 52, 91, 235, 219, 253, 181, 2, 219, 97, 250, 40, 243, - 233, 254, 96, 235, 216, 232, 220, 235, 217, 2, 223, 118, 225, 241, 254, - 10, 225, 4, 232, 220, 235, 217, 2, 220, 154, 225, 241, 254, 10, 225, 4, - 232, 220, 235, 217, 228, 57, 236, 1, 216, 197, 225, 4, 235, 219, 254, 10, - 116, 225, 14, 226, 171, 224, 21, 235, 219, 226, 171, 235, 219, 2, 140, - 80, 2, 103, 235, 219, 2, 30, 50, 235, 219, 2, 235, 205, 235, 219, 2, 214, - 175, 235, 219, 2, 226, 127, 235, 219, 2, 214, 183, 235, 72, 233, 91, 43, - 215, 227, 226, 171, 210, 160, 189, 221, 203, 249, 217, 210, 160, 189, - 221, 203, 225, 59, 210, 160, 189, 221, 203, 224, 179, 96, 5, 2, 4, 250, - 44, 48, 96, 5, 2, 250, 39, 255, 24, 48, 96, 5, 2, 216, 90, 48, 96, 5, 2, - 59, 51, 96, 5, 2, 216, 90, 51, 96, 5, 2, 218, 66, 105, 96, 5, 2, 85, 215, - 226, 230, 187, 5, 2, 249, 228, 48, 230, 187, 5, 2, 59, 51, 230, 187, 5, - 2, 244, 183, 247, 126, 230, 187, 5, 2, 222, 231, 247, 126, 96, 5, 236, 7, - 43, 163, 250, 43, 96, 5, 236, 7, 44, 163, 250, 43, 213, 254, 177, 249, - 139, 224, 183, 230, 89, 5, 2, 59, 48, 230, 89, 5, 2, 214, 183, 220, 151, - 224, 184, 2, 251, 183, 250, 7, 219, 79, 224, 183, 230, 89, 5, 236, 7, 43, - 163, 250, 43, 230, 89, 5, 236, 7, 44, 163, 250, 43, 37, 230, 89, 5, 2, - 250, 39, 255, 23, 230, 89, 5, 236, 7, 52, 250, 43, 37, 247, 177, 50, 96, - 5, 236, 7, 215, 226, 230, 187, 5, 236, 7, 215, 226, 230, 89, 5, 236, 7, - 215, 226, 235, 213, 224, 183, 222, 245, 235, 213, 224, 183, 210, 160, - 189, 223, 93, 249, 217, 254, 142, 177, 249, 173, 235, 206, 2, 247, 128, - 214, 176, 2, 230, 187, 50, 214, 176, 2, 226, 127, 235, 206, 2, 226, 127, - 235, 206, 2, 232, 152, 254, 126, 214, 176, 2, 232, 152, 226, 162, 214, - 176, 72, 235, 205, 235, 206, 72, 214, 175, 214, 176, 72, 252, 149, 72, - 235, 205, 235, 206, 72, 252, 149, 72, 214, 175, 214, 176, 252, 38, 22, - 235, 71, 2, 214, 175, 235, 206, 252, 38, 22, 235, 71, 2, 235, 205, 250, - 8, 214, 176, 2, 220, 135, 250, 8, 235, 206, 2, 220, 135, 52, 42, 235, - 205, 52, 42, 214, 175, 250, 8, 214, 176, 2, 220, 136, 22, 219, 79, 224, - 183, 232, 152, 22, 2, 59, 48, 232, 152, 177, 2, 59, 48, 52, 232, 152, - 254, 126, 52, 232, 152, 226, 162, 113, 235, 207, 232, 152, 254, 126, 113, - 235, 207, 232, 152, 226, 162, 219, 87, 233, 91, 226, 162, 219, 87, 233, - 91, 254, 126, 232, 152, 177, 226, 125, 232, 152, 254, 126, 232, 152, 22, - 2, 230, 229, 218, 141, 232, 152, 177, 2, 230, 229, 218, 141, 232, 152, - 22, 2, 203, 248, 164, 232, 152, 177, 2, 203, 248, 164, 232, 152, 22, 2, - 52, 226, 127, 232, 152, 22, 2, 214, 183, 232, 152, 22, 2, 52, 214, 183, - 4, 213, 251, 2, 214, 183, 232, 152, 177, 2, 52, 226, 127, 232, 152, 177, - 2, 52, 214, 183, 210, 160, 189, 247, 137, 254, 87, 210, 160, 189, 223, - 151, 254, 87, 245, 106, 5, 2, 59, 51, 240, 111, 2, 59, 48, 215, 212, 203, - 252, 149, 2, 52, 67, 91, 215, 212, 203, 252, 149, 2, 215, 212, 67, 91, - 216, 90, 226, 172, 2, 59, 48, 216, 90, 226, 172, 2, 222, 231, 247, 126, - 219, 164, 230, 187, 219, 163, 249, 207, 2, 59, 48, 245, 106, 2, 253, 224, - 254, 156, 128, 216, 43, 2, 250, 39, 255, 23, 254, 56, 128, 177, 128, 112, - 245, 106, 5, 72, 96, 50, 96, 5, 72, 245, 106, 50, 245, 106, 5, 72, 216, - 90, 226, 171, 52, 249, 235, 245, 107, 113, 249, 202, 245, 106, 219, 178, - 134, 249, 202, 245, 106, 219, 178, 245, 106, 5, 2, 113, 170, 72, 22, 113, - 170, 51, 245, 102, 2, 244, 19, 170, 48, 233, 21, 2, 250, 44, 235, 222, - 242, 137, 2, 250, 44, 235, 222, 233, 21, 2, 224, 16, 164, 48, 242, 137, - 2, 224, 16, 164, 48, 233, 21, 177, 219, 99, 128, 112, 242, 137, 177, 219, - 99, 128, 112, 233, 21, 177, 219, 99, 128, 216, 43, 2, 59, 235, 222, 242, - 137, 177, 219, 99, 128, 216, 43, 2, 59, 235, 222, 233, 21, 177, 219, 99, - 128, 216, 43, 2, 59, 48, 242, 137, 177, 219, 99, 128, 216, 43, 2, 59, 48, - 233, 21, 177, 219, 99, 128, 216, 43, 2, 59, 72, 222, 254, 242, 137, 177, - 219, 99, 128, 216, 43, 2, 59, 72, 233, 52, 233, 21, 177, 254, 57, 242, - 137, 177, 254, 57, 233, 21, 22, 219, 155, 228, 57, 128, 112, 242, 137, - 22, 219, 155, 228, 57, 128, 112, 233, 21, 22, 228, 57, 254, 57, 242, 137, - 22, 228, 57, 254, 57, 233, 21, 72, 246, 119, 128, 72, 242, 136, 242, 137, - 72, 246, 119, 128, 72, 233, 20, 233, 21, 72, 219, 164, 177, 245, 107, - 242, 137, 72, 219, 164, 177, 245, 107, 233, 21, 72, 219, 164, 72, 242, - 136, 242, 137, 72, 219, 164, 72, 233, 20, 233, 21, 72, 242, 137, 72, 246, - 119, 245, 107, 242, 137, 72, 233, 21, 72, 246, 119, 245, 107, 233, 21, - 72, 219, 99, 128, 72, 242, 137, 72, 219, 99, 245, 107, 242, 137, 72, 219, - 99, 128, 72, 233, 21, 72, 219, 99, 245, 107, 219, 99, 128, 216, 43, 177, - 233, 20, 219, 99, 128, 216, 43, 177, 242, 136, 219, 99, 128, 216, 43, - 177, 233, 21, 2, 59, 235, 222, 219, 99, 128, 216, 43, 177, 242, 137, 2, - 59, 235, 222, 246, 119, 128, 216, 43, 177, 233, 20, 246, 119, 128, 216, - 43, 177, 242, 136, 246, 119, 219, 99, 128, 216, 43, 177, 233, 20, 246, - 119, 219, 99, 128, 216, 43, 177, 242, 136, 219, 164, 177, 233, 20, 219, - 164, 177, 242, 136, 219, 164, 72, 233, 21, 72, 245, 106, 50, 219, 164, - 72, 242, 137, 72, 245, 106, 50, 52, 229, 96, 233, 20, 52, 229, 96, 242, - 136, 52, 229, 96, 233, 21, 2, 214, 183, 242, 137, 226, 125, 233, 20, 242, - 137, 252, 38, 233, 20, 233, 21, 250, 8, 251, 86, 249, 100, 242, 137, 250, - 8, 251, 86, 249, 100, 233, 21, 250, 8, 251, 86, 249, 101, 72, 219, 99, - 245, 107, 242, 137, 250, 8, 251, 86, 249, 101, 72, 219, 99, 245, 107, - 219, 80, 216, 201, 233, 89, 216, 201, 219, 80, 216, 202, 177, 128, 112, - 233, 89, 216, 202, 177, 128, 112, 245, 106, 5, 2, 251, 116, 48, 224, 206, - 72, 219, 155, 245, 106, 50, 218, 57, 72, 219, 155, 245, 106, 50, 224, - 206, 72, 219, 155, 228, 57, 128, 112, 218, 57, 72, 219, 155, 228, 57, - 128, 112, 224, 206, 72, 245, 106, 50, 218, 57, 72, 245, 106, 50, 224, - 206, 72, 228, 57, 128, 112, 218, 57, 72, 228, 57, 128, 112, 224, 206, 72, - 254, 156, 128, 112, 218, 57, 72, 254, 156, 128, 112, 224, 206, 72, 228, - 57, 254, 156, 128, 112, 218, 57, 72, 228, 57, 254, 156, 128, 112, 52, - 224, 205, 52, 218, 56, 218, 65, 2, 247, 128, 218, 23, 2, 247, 128, 218, - 65, 2, 96, 5, 51, 218, 23, 2, 96, 5, 51, 218, 65, 2, 230, 89, 5, 51, 218, - 23, 2, 230, 89, 5, 51, 218, 65, 64, 177, 128, 216, 43, 2, 59, 48, 218, - 23, 64, 177, 128, 216, 43, 2, 59, 48, 218, 65, 64, 72, 245, 106, 50, 218, - 23, 64, 72, 245, 106, 50, 218, 65, 64, 72, 216, 90, 226, 171, 218, 23, - 64, 72, 216, 90, 226, 171, 218, 65, 64, 72, 254, 156, 128, 112, 218, 23, - 64, 72, 254, 156, 128, 112, 218, 65, 64, 72, 228, 57, 128, 112, 218, 23, - 64, 72, 228, 57, 128, 112, 42, 43, 204, 93, 226, 171, 42, 44, 204, 93, - 226, 171, 250, 8, 218, 64, 250, 8, 218, 22, 250, 8, 218, 65, 177, 128, - 112, 250, 8, 218, 23, 177, 128, 112, 218, 65, 72, 218, 22, 218, 23, 72, - 218, 64, 218, 65, 72, 218, 64, 218, 23, 72, 218, 22, 218, 23, 252, 38, - 218, 64, 218, 23, 252, 38, 22, 235, 71, 251, 86, 248, 165, 2, 218, 64, - 245, 178, 64, 226, 174, 246, 111, 225, 51, 2, 217, 13, 216, 14, 215, 241, - 235, 205, 244, 29, 228, 70, 219, 253, 43, 217, 88, 219, 253, 124, 217, - 88, 219, 253, 120, 217, 88, 225, 175, 2, 222, 93, 67, 252, 149, 215, 212, - 44, 215, 93, 52, 67, 252, 149, 43, 215, 93, 67, 252, 149, 52, 43, 215, - 93, 52, 67, 252, 149, 52, 43, 215, 93, 200, 248, 165, 243, 251, 43, 231, - 68, 64, 52, 213, 239, 219, 253, 124, 217, 89, 2, 226, 127, 219, 253, 120, - 217, 89, 2, 214, 183, 219, 253, 120, 217, 89, 72, 219, 253, 124, 217, 88, - 52, 124, 217, 88, 52, 120, 217, 88, 52, 218, 105, 228, 57, 50, 223, 52, - 52, 218, 105, 228, 57, 50, 247, 146, 228, 57, 247, 183, 2, 223, 52, 229, - 106, 219, 97, 67, 232, 220, 2, 250, 44, 48, 67, 232, 220, 2, 250, 44, 51, - 124, 217, 89, 2, 250, 44, 51, 226, 12, 2, 203, 91, 226, 12, 2, 216, 90, - 226, 171, 215, 212, 67, 252, 149, 251, 252, 223, 94, 215, 212, 67, 252, - 149, 2, 203, 91, 215, 212, 249, 235, 226, 171, 215, 212, 229, 96, 233, - 20, 215, 212, 229, 96, 242, 136, 246, 119, 219, 99, 233, 21, 177, 128, - 112, 246, 119, 219, 99, 242, 137, 177, 128, 112, 215, 212, 219, 49, 251, - 252, 223, 94, 233, 91, 215, 212, 67, 252, 149, 226, 171, 52, 219, 49, - 226, 171, 71, 67, 130, 230, 29, 71, 67, 130, 228, 61, 245, 228, 71, 75, - 228, 61, 212, 9, 71, 75, 219, 30, 245, 228, 71, 75, 219, 30, 212, 9, 71, - 75, 43, 44, 71, 75, 140, 85, 75, 214, 153, 85, 75, 246, 112, 85, 75, 228, - 61, 245, 228, 85, 75, 228, 61, 212, 9, 85, 75, 219, 30, 245, 228, 85, 75, - 219, 30, 212, 9, 85, 75, 43, 44, 85, 75, 120, 124, 85, 75, 97, 80, 2, - 216, 78, 246, 111, 97, 80, 2, 216, 78, 214, 152, 140, 80, 2, 216, 78, - 246, 111, 140, 80, 2, 216, 78, 214, 152, 42, 2, 216, 15, 163, 251, 229, - 42, 2, 251, 183, 163, 251, 229, 42, 2, 214, 160, 44, 248, 7, 163, 251, - 229, 42, 2, 232, 114, 43, 248, 7, 163, 251, 229, 248, 1, 2, 43, 163, 251, - 229, 248, 1, 2, 44, 163, 251, 229, 248, 1, 2, 216, 15, 163, 251, 229, - 248, 1, 2, 251, 183, 163, 251, 229, 246, 126, 218, 236, 85, 233, 91, 218, - 236, 71, 233, 91, 218, 236, 85, 213, 187, 4, 218, 236, 71, 213, 187, 4, - 218, 236, 85, 225, 193, 71, 225, 193, 71, 241, 200, 85, 241, 200, 203, - 85, 241, 200, 85, 233, 91, 250, 43, 85, 231, 87, 248, 0, 71, 231, 87, - 248, 0, 85, 231, 87, 232, 110, 71, 231, 87, 232, 110, 85, 4, 248, 0, 85, - 4, 232, 110, 71, 4, 232, 110, 85, 203, 245, 172, 71, 203, 245, 172, 85, - 67, 245, 172, 71, 67, 245, 172, 43, 80, 2, 4, 250, 43, 134, 140, 253, - 255, 43, 80, 2, 37, 225, 25, 200, 140, 218, 232, 75, 140, 215, 58, 80, 2, - 67, 91, 140, 215, 58, 80, 2, 52, 67, 91, 140, 215, 58, 80, 243, 251, 130, - 140, 215, 58, 215, 212, 248, 165, 75, 140, 80, 2, 246, 126, 218, 141, - 140, 80, 2, 217, 79, 2, 67, 91, 140, 80, 2, 217, 79, 2, 52, 67, 91, 140, - 215, 58, 80, 2, 217, 78, 140, 215, 58, 80, 2, 217, 79, 2, 67, 91, 140, - 215, 58, 80, 2, 217, 79, 2, 52, 67, 91, 140, 80, 216, 140, 211, 178, 212, - 36, 80, 225, 10, 247, 203, 233, 52, 245, 106, 5, 72, 140, 75, 223, 53, - 216, 90, 226, 172, 72, 140, 75, 140, 80, 72, 223, 53, 254, 156, 128, 112, - 97, 80, 216, 140, 242, 136, 97, 80, 216, 140, 218, 22, 140, 224, 27, 75, - 97, 224, 27, 75, 223, 53, 216, 90, 226, 172, 72, 97, 75, 97, 80, 72, 223, - 53, 254, 156, 128, 112, 216, 90, 226, 172, 72, 140, 75, 140, 80, 72, 254, - 156, 128, 112, 140, 80, 72, 223, 53, 216, 90, 226, 171, 97, 80, 72, 223, - 53, 216, 90, 226, 171, 71, 231, 87, 218, 158, 85, 4, 218, 158, 71, 4, - 218, 158, 85, 222, 250, 225, 193, 71, 222, 250, 225, 193, 114, 233, 91, - 250, 43, 114, 226, 128, 2, 226, 128, 235, 222, 114, 250, 44, 2, 250, 44, - 235, 222, 114, 250, 43, 114, 37, 222, 0, 145, 6, 1, 253, 167, 145, 6, 1, - 251, 125, 145, 6, 1, 213, 253, 145, 6, 1, 242, 192, 145, 6, 1, 247, 148, - 145, 6, 1, 211, 21, 145, 6, 1, 210, 68, 145, 6, 1, 246, 42, 145, 6, 1, - 210, 91, 145, 6, 1, 235, 154, 145, 6, 1, 65, 235, 154, 145, 6, 1, 74, - 145, 6, 1, 247, 168, 145, 6, 1, 234, 246, 145, 6, 1, 232, 192, 145, 6, 1, - 230, 34, 145, 6, 1, 229, 196, 145, 6, 1, 226, 189, 145, 6, 1, 225, 7, - 145, 6, 1, 222, 230, 145, 6, 1, 219, 85, 145, 6, 1, 215, 81, 145, 6, 1, - 214, 201, 145, 6, 1, 243, 254, 145, 6, 1, 241, 206, 145, 6, 1, 226, 139, - 145, 6, 1, 225, 224, 145, 6, 1, 219, 230, 145, 6, 1, 215, 168, 145, 6, 1, - 250, 83, 145, 6, 1, 220, 104, 145, 6, 1, 211, 27, 145, 6, 1, 211, 29, - 145, 6, 1, 211, 57, 145, 6, 1, 218, 255, 162, 145, 6, 1, 210, 212, 145, - 6, 1, 4, 210, 183, 145, 6, 1, 4, 210, 184, 2, 217, 78, 145, 6, 1, 210, - 244, 145, 6, 1, 235, 191, 4, 210, 183, 145, 6, 1, 252, 1, 210, 183, 145, - 6, 1, 235, 191, 252, 1, 210, 183, 145, 6, 1, 244, 90, 145, 6, 1, 235, - 152, 145, 6, 1, 219, 229, 145, 6, 1, 215, 203, 61, 145, 6, 1, 233, 81, - 230, 34, 145, 4, 1, 253, 167, 145, 4, 1, 251, 125, 145, 4, 1, 213, 253, - 145, 4, 1, 242, 192, 145, 4, 1, 247, 148, 145, 4, 1, 211, 21, 145, 4, 1, - 210, 68, 145, 4, 1, 246, 42, 145, 4, 1, 210, 91, 145, 4, 1, 235, 154, - 145, 4, 1, 65, 235, 154, 145, 4, 1, 74, 145, 4, 1, 247, 168, 145, 4, 1, - 234, 246, 145, 4, 1, 232, 192, 145, 4, 1, 230, 34, 145, 4, 1, 229, 196, - 145, 4, 1, 226, 189, 145, 4, 1, 225, 7, 145, 4, 1, 222, 230, 145, 4, 1, - 219, 85, 145, 4, 1, 215, 81, 145, 4, 1, 214, 201, 145, 4, 1, 243, 254, - 145, 4, 1, 241, 206, 145, 4, 1, 226, 139, 145, 4, 1, 225, 224, 145, 4, 1, - 219, 230, 145, 4, 1, 215, 168, 145, 4, 1, 250, 83, 145, 4, 1, 220, 104, - 145, 4, 1, 211, 27, 145, 4, 1, 211, 29, 145, 4, 1, 211, 57, 145, 4, 1, - 218, 255, 162, 145, 4, 1, 210, 212, 145, 4, 1, 4, 210, 183, 145, 4, 1, 4, - 210, 184, 2, 217, 78, 145, 4, 1, 210, 244, 145, 4, 1, 235, 191, 4, 210, - 183, 145, 4, 1, 252, 1, 210, 183, 145, 4, 1, 235, 191, 252, 1, 210, 183, - 145, 4, 1, 244, 90, 145, 4, 1, 235, 152, 145, 4, 1, 219, 229, 145, 4, 1, - 215, 203, 61, 145, 4, 1, 233, 81, 230, 34, 7, 6, 1, 233, 155, 2, 52, 130, - 7, 4, 1, 233, 155, 2, 52, 130, 7, 6, 1, 233, 155, 2, 230, 229, 184, 7, 6, - 1, 226, 110, 2, 91, 7, 6, 1, 223, 227, 2, 217, 78, 7, 4, 1, 116, 2, 91, - 7, 4, 1, 217, 154, 2, 248, 7, 91, 7, 6, 1, 242, 68, 2, 248, 47, 7, 4, 1, - 242, 68, 2, 248, 47, 7, 6, 1, 235, 30, 2, 248, 47, 7, 4, 1, 235, 30, 2, - 248, 47, 7, 6, 1, 210, 160, 2, 248, 47, 7, 4, 1, 210, 160, 2, 248, 47, 7, - 6, 1, 254, 151, 7, 6, 1, 232, 55, 2, 103, 7, 6, 1, 215, 94, 61, 7, 6, 1, - 215, 94, 254, 151, 7, 4, 1, 214, 106, 2, 44, 103, 7, 6, 1, 212, 99, 2, - 103, 7, 4, 1, 212, 99, 2, 103, 7, 4, 1, 214, 106, 2, 249, 108, 7, 6, 1, - 163, 242, 67, 7, 4, 1, 163, 242, 67, 7, 4, 1, 217, 76, 225, 136, 7, 4, 1, - 160, 2, 228, 55, 7, 4, 1, 215, 94, 223, 227, 2, 217, 78, 7, 4, 1, 144, 2, - 121, 222, 237, 235, 222, 7, 1, 4, 6, 215, 94, 76, 7, 218, 66, 4, 1, 235, - 150, 58, 1, 6, 214, 105, 7, 6, 1, 222, 94, 2, 217, 251, 217, 78, 7, 6, 1, - 210, 160, 2, 217, 251, 217, 78, 81, 6, 1, 254, 173, 81, 4, 1, 254, 173, - 81, 6, 1, 213, 173, 81, 4, 1, 213, 173, 81, 6, 1, 243, 114, 81, 4, 1, - 243, 114, 81, 6, 1, 248, 199, 81, 4, 1, 248, 199, 81, 6, 1, 245, 202, 81, - 4, 1, 245, 202, 81, 6, 1, 219, 35, 81, 4, 1, 219, 35, 81, 6, 1, 210, 101, - 81, 4, 1, 210, 101, 81, 6, 1, 241, 255, 81, 4, 1, 241, 255, 81, 6, 1, - 216, 178, 81, 4, 1, 216, 178, 81, 6, 1, 240, 123, 81, 4, 1, 240, 123, 81, - 6, 1, 234, 233, 81, 4, 1, 234, 233, 81, 6, 1, 233, 78, 81, 4, 1, 233, 78, - 81, 6, 1, 230, 235, 81, 4, 1, 230, 235, 81, 6, 1, 228, 238, 81, 4, 1, - 228, 238, 81, 6, 1, 233, 239, 81, 4, 1, 233, 239, 81, 6, 1, 78, 81, 4, 1, - 78, 81, 6, 1, 225, 111, 81, 4, 1, 225, 111, 81, 6, 1, 222, 213, 81, 4, 1, - 222, 213, 81, 6, 1, 219, 167, 81, 4, 1, 219, 167, 81, 6, 1, 217, 42, 81, - 4, 1, 217, 42, 81, 6, 1, 214, 229, 81, 4, 1, 214, 229, 81, 6, 1, 244, - 129, 81, 4, 1, 244, 129, 81, 6, 1, 234, 118, 81, 4, 1, 234, 118, 81, 6, - 1, 224, 164, 81, 4, 1, 224, 164, 81, 6, 1, 226, 182, 81, 4, 1, 226, 182, - 81, 6, 1, 248, 5, 254, 179, 81, 4, 1, 248, 5, 254, 179, 81, 6, 1, 55, 81, - 254, 205, 81, 4, 1, 55, 81, 254, 205, 81, 6, 1, 249, 123, 245, 202, 81, - 4, 1, 249, 123, 245, 202, 81, 6, 1, 248, 5, 234, 233, 81, 4, 1, 248, 5, - 234, 233, 81, 6, 1, 248, 5, 228, 238, 81, 4, 1, 248, 5, 228, 238, 81, 6, - 1, 249, 123, 228, 238, 81, 4, 1, 249, 123, 228, 238, 81, 6, 1, 55, 81, - 226, 182, 81, 4, 1, 55, 81, 226, 182, 81, 6, 1, 221, 248, 81, 4, 1, 221, - 248, 81, 6, 1, 249, 136, 220, 57, 81, 4, 1, 249, 136, 220, 57, 81, 6, 1, - 55, 81, 220, 57, 81, 4, 1, 55, 81, 220, 57, 81, 6, 1, 55, 81, 245, 83, - 81, 4, 1, 55, 81, 245, 83, 81, 6, 1, 254, 191, 234, 123, 81, 4, 1, 254, - 191, 234, 123, 81, 6, 1, 248, 5, 241, 52, 81, 4, 1, 248, 5, 241, 52, 81, - 6, 1, 55, 81, 241, 52, 81, 4, 1, 55, 81, 241, 52, 81, 6, 1, 55, 81, 162, - 81, 4, 1, 55, 81, 162, 81, 6, 1, 233, 154, 162, 81, 4, 1, 233, 154, 162, - 81, 6, 1, 55, 81, 241, 224, 81, 4, 1, 55, 81, 241, 224, 81, 6, 1, 55, 81, - 242, 2, 81, 4, 1, 55, 81, 242, 2, 81, 6, 1, 55, 81, 243, 109, 81, 4, 1, - 55, 81, 243, 109, 81, 6, 1, 55, 81, 247, 171, 81, 4, 1, 55, 81, 247, 171, - 81, 6, 1, 55, 81, 220, 24, 81, 4, 1, 55, 81, 220, 24, 81, 6, 1, 55, 227, - 212, 220, 24, 81, 4, 1, 55, 227, 212, 220, 24, 81, 6, 1, 55, 227, 212, - 229, 32, 81, 4, 1, 55, 227, 212, 229, 32, 81, 6, 1, 55, 227, 212, 227, - 152, 81, 4, 1, 55, 227, 212, 227, 152, 81, 6, 1, 55, 227, 212, 212, 37, - 81, 4, 1, 55, 227, 212, 212, 37, 81, 16, 234, 252, 81, 16, 230, 236, 222, - 213, 81, 16, 225, 112, 222, 213, 81, 16, 218, 149, 81, 16, 217, 43, 222, - 213, 81, 16, 234, 119, 222, 213, 81, 16, 220, 25, 219, 167, 81, 6, 1, - 249, 123, 220, 57, 81, 4, 1, 249, 123, 220, 57, 81, 6, 1, 249, 123, 243, - 109, 81, 4, 1, 249, 123, 243, 109, 81, 38, 228, 239, 48, 81, 38, 218, - 249, 253, 232, 81, 38, 218, 249, 233, 27, 81, 6, 1, 251, 207, 234, 123, - 81, 4, 1, 251, 207, 234, 123, 81, 55, 227, 212, 243, 236, 218, 131, 81, - 55, 227, 212, 247, 205, 224, 16, 79, 81, 55, 227, 212, 235, 244, 224, 16, - 79, 81, 55, 227, 212, 213, 241, 247, 180, 81, 244, 10, 123, 242, 34, 81, - 243, 236, 218, 131, 81, 230, 129, 247, 180, 98, 4, 1, 254, 131, 98, 4, 1, - 252, 160, 98, 4, 1, 243, 113, 98, 4, 1, 247, 136, 98, 4, 1, 245, 158, 98, - 4, 1, 213, 160, 98, 4, 1, 210, 89, 98, 4, 1, 217, 61, 98, 4, 1, 236, 6, - 98, 4, 1, 234, 240, 98, 4, 1, 233, 87, 98, 4, 1, 231, 190, 98, 4, 1, 229, - 200, 98, 4, 1, 226, 200, 98, 4, 1, 226, 21, 98, 4, 1, 210, 78, 98, 4, 1, - 223, 174, 98, 4, 1, 221, 245, 98, 4, 1, 217, 51, 98, 4, 1, 214, 190, 98, - 4, 1, 225, 143, 98, 4, 1, 234, 127, 98, 4, 1, 242, 248, 98, 4, 1, 224, - 76, 98, 4, 1, 220, 22, 98, 4, 1, 250, 105, 98, 4, 1, 251, 15, 98, 4, 1, - 235, 106, 98, 4, 1, 250, 48, 98, 4, 1, 250, 151, 98, 4, 1, 211, 163, 98, - 4, 1, 235, 117, 98, 4, 1, 242, 50, 98, 4, 1, 241, 245, 98, 4, 1, 241, - 182, 98, 4, 1, 212, 22, 98, 4, 1, 242, 11, 98, 4, 1, 241, 72, 98, 4, 1, - 210, 246, 98, 4, 1, 254, 241, 216, 109, 1, 192, 216, 109, 1, 211, 99, - 216, 109, 1, 211, 98, 216, 109, 1, 211, 88, 216, 109, 1, 211, 86, 216, - 109, 1, 252, 40, 255, 25, 211, 81, 216, 109, 1, 211, 81, 216, 109, 1, - 211, 96, 216, 109, 1, 211, 93, 216, 109, 1, 211, 95, 216, 109, 1, 211, - 94, 216, 109, 1, 211, 12, 216, 109, 1, 211, 90, 216, 109, 1, 211, 79, - 216, 109, 1, 215, 116, 211, 79, 216, 109, 1, 211, 76, 216, 109, 1, 211, - 84, 216, 109, 1, 252, 40, 255, 25, 211, 84, 216, 109, 1, 215, 116, 211, - 84, 216, 109, 1, 211, 83, 216, 109, 1, 211, 103, 216, 109, 1, 211, 77, - 216, 109, 1, 215, 116, 211, 77, 216, 109, 1, 211, 66, 216, 109, 1, 215, - 116, 211, 66, 216, 109, 1, 211, 8, 216, 109, 1, 211, 49, 216, 109, 1, - 254, 216, 211, 49, 216, 109, 1, 215, 116, 211, 49, 216, 109, 1, 211, 75, - 216, 109, 1, 211, 74, 216, 109, 1, 211, 71, 216, 109, 1, 215, 116, 211, - 85, 216, 109, 1, 215, 116, 211, 69, 216, 109, 1, 211, 67, 216, 109, 1, - 210, 212, 216, 109, 1, 211, 64, 216, 109, 1, 211, 63, 216, 109, 1, 211, - 87, 216, 109, 1, 215, 116, 211, 87, 216, 109, 1, 253, 171, 211, 87, 216, - 109, 1, 211, 62, 216, 109, 1, 211, 60, 216, 109, 1, 211, 61, 216, 109, 1, - 211, 59, 216, 109, 1, 211, 58, 216, 109, 1, 211, 97, 216, 109, 1, 211, - 56, 216, 109, 1, 211, 54, 216, 109, 1, 211, 53, 216, 109, 1, 211, 52, - 216, 109, 1, 211, 50, 216, 109, 1, 217, 35, 211, 50, 216, 109, 1, 211, - 48, 216, 109, 1, 211, 47, 216, 109, 1, 210, 244, 216, 109, 58, 1, 233, - 132, 79, 216, 109, 220, 140, 79, 216, 109, 117, 235, 69, 29, 3, 232, 161, - 29, 3, 230, 165, 29, 3, 222, 211, 29, 3, 219, 59, 29, 3, 220, 8, 29, 3, - 251, 212, 29, 3, 216, 42, 29, 3, 249, 245, 29, 3, 228, 77, 29, 3, 227, - 137, 29, 3, 242, 187, 227, 4, 29, 3, 210, 22, 29, 3, 247, 151, 29, 3, - 248, 112, 29, 3, 235, 73, 29, 3, 216, 156, 29, 3, 250, 93, 29, 3, 225, - 123, 29, 3, 225, 18, 29, 3, 243, 6, 29, 3, 243, 2, 29, 3, 243, 3, 29, 3, - 243, 4, 29, 3, 218, 225, 29, 3, 218, 181, 29, 3, 218, 194, 29, 3, 218, - 224, 29, 3, 218, 198, 29, 3, 218, 199, 29, 3, 218, 186, 29, 3, 250, 221, - 29, 3, 250, 200, 29, 3, 250, 202, 29, 3, 250, 220, 29, 3, 250, 218, 29, - 3, 250, 219, 29, 3, 250, 201, 29, 3, 209, 243, 29, 3, 209, 221, 29, 3, - 209, 234, 29, 3, 209, 242, 29, 3, 209, 237, 29, 3, 209, 238, 29, 3, 209, - 226, 29, 3, 250, 216, 29, 3, 250, 203, 29, 3, 250, 205, 29, 3, 250, 215, - 29, 3, 250, 213, 29, 3, 250, 214, 29, 3, 250, 204, 29, 3, 223, 239, 29, - 3, 223, 229, 29, 3, 223, 235, 29, 3, 223, 238, 29, 3, 223, 236, 29, 3, - 223, 237, 29, 3, 223, 234, 29, 3, 233, 165, 29, 3, 233, 157, 29, 3, 233, - 160, 29, 3, 233, 164, 29, 3, 233, 161, 29, 3, 233, 162, 29, 3, 233, 158, - 29, 3, 211, 130, 29, 3, 211, 120, 29, 3, 211, 126, 29, 3, 211, 129, 29, - 3, 211, 127, 29, 3, 211, 128, 29, 3, 211, 125, 29, 3, 242, 78, 29, 3, - 242, 69, 29, 3, 242, 72, 29, 3, 242, 77, 29, 3, 242, 74, 29, 3, 242, 75, - 29, 3, 242, 71, 38, 33, 1, 252, 83, 38, 33, 1, 213, 255, 38, 33, 1, 242, - 243, 38, 33, 1, 248, 98, 38, 33, 1, 210, 74, 38, 33, 1, 210, 94, 38, 33, - 1, 176, 38, 33, 1, 245, 182, 38, 33, 1, 245, 167, 38, 33, 1, 245, 158, - 38, 33, 1, 78, 38, 33, 1, 225, 224, 38, 33, 1, 245, 100, 38, 33, 1, 245, - 90, 38, 33, 1, 217, 23, 38, 33, 1, 162, 38, 33, 1, 215, 179, 38, 33, 1, - 250, 139, 38, 33, 1, 220, 104, 38, 33, 1, 220, 67, 38, 33, 1, 244, 90, - 38, 33, 1, 245, 89, 38, 33, 1, 61, 38, 33, 1, 236, 67, 38, 33, 1, 247, - 169, 38, 33, 1, 230, 145, 214, 205, 38, 33, 1, 211, 59, 38, 33, 1, 210, - 212, 38, 33, 1, 235, 190, 61, 38, 33, 1, 232, 198, 210, 183, 38, 33, 1, - 252, 1, 210, 183, 38, 33, 1, 235, 190, 252, 1, 210, 183, 44, 254, 118, - 218, 61, 231, 159, 44, 254, 118, 246, 126, 218, 61, 231, 159, 43, 218, - 61, 127, 44, 218, 61, 127, 43, 246, 126, 218, 61, 127, 44, 246, 126, 218, - 61, 127, 223, 160, 235, 209, 231, 159, 223, 160, 246, 126, 235, 209, 231, - 159, 246, 126, 215, 242, 231, 159, 43, 215, 242, 127, 44, 215, 242, 127, - 223, 160, 218, 236, 43, 223, 160, 226, 202, 127, 44, 223, 160, 226, 202, - 127, 245, 218, 249, 166, 226, 17, 244, 30, 226, 17, 223, 52, 244, 30, - 226, 17, 240, 172, 246, 126, 226, 255, 246, 112, 254, 127, 214, 153, 254, - 127, 246, 126, 222, 250, 254, 117, 52, 226, 252, 240, 175, 235, 200, 235, - 208, 226, 63, 251, 162, 240, 176, 2, 248, 9, 216, 90, 2, 222, 237, 48, - 43, 121, 226, 9, 127, 44, 121, 226, 9, 127, 216, 90, 2, 59, 48, 216, 90, - 2, 59, 51, 43, 67, 252, 149, 2, 224, 10, 44, 67, 252, 149, 2, 224, 10, - 216, 15, 43, 163, 127, 216, 15, 44, 163, 127, 251, 183, 43, 163, 127, - 251, 183, 44, 163, 127, 43, 219, 189, 104, 127, 44, 219, 189, 104, 127, - 43, 52, 226, 7, 44, 52, 226, 7, 113, 170, 115, 123, 59, 224, 143, 123, - 59, 115, 113, 170, 224, 143, 92, 244, 19, 59, 224, 143, 244, 89, 59, 79, - 223, 52, 224, 16, 79, 67, 184, 222, 237, 225, 13, 211, 209, 220, 140, - 230, 229, 247, 128, 215, 94, 249, 227, 223, 160, 247, 128, 223, 160, 249, - 227, 215, 94, 220, 152, 248, 214, 2, 43, 242, 115, 248, 214, 2, 44, 242, - 115, 215, 94, 248, 213, 216, 15, 163, 221, 175, 50, 215, 59, 248, 164, - 216, 144, 248, 164, 10, 34, 223, 79, 10, 34, 250, 18, 10, 34, 221, 178, - 111, 10, 34, 221, 178, 105, 10, 34, 221, 178, 158, 10, 34, 225, 170, 10, - 34, 251, 171, 10, 34, 217, 93, 10, 34, 234, 39, 111, 10, 34, 234, 39, - 105, 10, 34, 247, 178, 10, 34, 221, 181, 10, 34, 4, 111, 10, 34, 4, 105, - 10, 34, 233, 103, 111, 10, 34, 233, 103, 105, 10, 34, 233, 103, 158, 10, - 34, 233, 103, 161, 10, 34, 219, 70, 10, 34, 216, 146, 10, 34, 219, 68, - 111, 10, 34, 219, 68, 105, 10, 34, 241, 235, 111, 10, 34, 241, 235, 105, - 10, 34, 242, 22, 10, 34, 223, 150, 10, 34, 250, 90, 10, 34, 218, 38, 10, - 34, 230, 133, 10, 34, 248, 96, 10, 34, 230, 125, 10, 34, 250, 33, 10, 34, - 212, 41, 111, 10, 34, 212, 41, 105, 10, 34, 244, 104, 10, 34, 225, 236, - 111, 10, 34, 225, 236, 105, 10, 34, 219, 162, 163, 215, 237, 215, 189, - 10, 34, 249, 153, 10, 34, 247, 144, 10, 34, 235, 143, 10, 34, 251, 206, - 64, 250, 2, 10, 34, 245, 23, 10, 34, 218, 251, 111, 10, 34, 218, 251, - 105, 10, 34, 252, 162, 10, 34, 219, 169, 10, 34, 251, 71, 219, 169, 10, - 34, 229, 95, 111, 10, 34, 229, 95, 105, 10, 34, 229, 95, 158, 10, 34, - 229, 95, 161, 10, 34, 231, 51, 10, 34, 220, 59, 10, 34, 223, 156, 10, 34, - 245, 45, 10, 34, 226, 213, 10, 34, 251, 141, 111, 10, 34, 251, 141, 105, - 10, 34, 231, 91, 10, 34, 230, 128, 10, 34, 242, 147, 111, 10, 34, 242, - 147, 105, 10, 34, 242, 147, 158, 10, 34, 216, 107, 10, 34, 250, 1, 10, - 34, 212, 9, 111, 10, 34, 212, 9, 105, 10, 34, 251, 71, 221, 172, 10, 34, - 219, 162, 240, 255, 10, 34, 240, 255, 10, 34, 251, 71, 219, 4, 10, 34, - 251, 71, 220, 54, 10, 34, 244, 40, 10, 34, 251, 71, 250, 236, 10, 34, - 219, 162, 212, 57, 10, 34, 212, 58, 111, 10, 34, 212, 58, 105, 10, 34, - 250, 35, 10, 34, 251, 71, 242, 173, 10, 34, 200, 111, 10, 34, 200, 105, - 10, 34, 251, 71, 232, 143, 10, 34, 251, 71, 243, 95, 10, 34, 230, 124, - 111, 10, 34, 230, 124, 105, 10, 34, 223, 162, 10, 34, 251, 215, 10, 34, - 251, 71, 217, 57, 233, 58, 10, 34, 251, 71, 233, 59, 10, 34, 251, 71, - 211, 239, 10, 34, 251, 71, 244, 54, 10, 34, 245, 226, 111, 10, 34, 245, - 226, 105, 10, 34, 245, 226, 158, 10, 34, 251, 71, 245, 225, 10, 34, 241, - 242, 10, 34, 251, 71, 240, 252, 10, 34, 251, 202, 10, 34, 242, 229, 10, - 34, 251, 71, 244, 98, 10, 34, 251, 71, 251, 245, 10, 34, 251, 71, 222, 3, - 10, 34, 219, 162, 212, 2, 10, 34, 219, 162, 211, 41, 10, 34, 251, 71, - 243, 252, 10, 34, 235, 149, 245, 49, 10, 34, 251, 71, 245, 49, 10, 34, - 235, 149, 216, 16, 10, 34, 251, 71, 216, 16, 10, 34, 235, 149, 246, 104, - 10, 34, 251, 71, 246, 104, 10, 34, 215, 91, 10, 34, 235, 149, 215, 91, - 10, 34, 251, 71, 215, 91, 60, 34, 111, 60, 34, 232, 219, 60, 34, 247, - 128, 60, 34, 219, 97, 60, 34, 221, 177, 60, 34, 103, 60, 34, 105, 60, 34, - 232, 243, 60, 34, 231, 190, 60, 34, 233, 39, 60, 34, 245, 137, 60, 34, - 196, 60, 34, 124, 251, 171, 60, 34, 249, 155, 60, 34, 240, 118, 60, 34, - 217, 93, 60, 34, 204, 251, 171, 60, 34, 234, 38, 60, 34, 224, 227, 60, - 34, 211, 202, 60, 34, 218, 245, 60, 34, 44, 204, 251, 171, 60, 34, 241, - 183, 245, 153, 60, 34, 216, 248, 60, 34, 247, 178, 60, 34, 221, 181, 60, - 34, 250, 18, 60, 34, 224, 185, 60, 34, 254, 224, 60, 34, 230, 115, 60, - 34, 245, 153, 60, 34, 245, 231, 60, 34, 221, 202, 60, 34, 242, 181, 60, - 34, 242, 182, 219, 83, 60, 34, 245, 48, 60, 34, 252, 0, 60, 34, 211, 221, - 60, 34, 250, 109, 60, 34, 222, 198, 60, 34, 236, 2, 60, 34, 219, 81, 60, - 34, 233, 102, 60, 34, 249, 164, 60, 34, 218, 239, 60, 34, 230, 120, 60, - 34, 222, 227, 60, 34, 211, 206, 60, 34, 226, 194, 60, 34, 215, 98, 60, - 34, 246, 88, 60, 34, 219, 253, 216, 146, 60, 34, 246, 126, 250, 18, 60, - 34, 200, 218, 110, 60, 34, 113, 242, 17, 60, 34, 220, 2, 60, 34, 251, - 177, 60, 34, 219, 67, 60, 34, 251, 145, 60, 34, 218, 140, 60, 34, 241, - 234, 60, 34, 242, 35, 60, 34, 247, 131, 60, 34, 242, 22, 60, 34, 251, - 162, 60, 34, 223, 150, 60, 34, 221, 189, 60, 34, 247, 207, 60, 34, 253, - 176, 60, 34, 218, 236, 60, 34, 228, 56, 60, 34, 218, 38, 60, 34, 221, - 213, 60, 34, 230, 133, 60, 34, 215, 236, 60, 34, 233, 128, 60, 34, 218, - 131, 60, 34, 248, 96, 60, 34, 212, 21, 60, 34, 247, 154, 228, 56, 60, 34, - 249, 223, 60, 34, 243, 229, 60, 34, 250, 29, 60, 34, 218, 144, 60, 34, - 212, 40, 60, 34, 244, 104, 60, 34, 250, 26, 60, 34, 244, 169, 60, 34, 52, - 211, 178, 60, 34, 163, 215, 237, 215, 189, 60, 34, 219, 91, 60, 34, 244, - 179, 60, 34, 249, 153, 60, 34, 247, 144, 60, 34, 224, 182, 60, 34, 235, - 143, 60, 34, 231, 72, 60, 34, 216, 89, 60, 34, 217, 246, 60, 34, 232, - 237, 60, 34, 214, 131, 60, 34, 244, 128, 60, 34, 251, 206, 64, 250, 2, - 60, 34, 219, 190, 60, 34, 246, 126, 216, 243, 60, 34, 211, 253, 60, 34, - 219, 105, 60, 34, 247, 195, 60, 34, 245, 23, 60, 34, 219, 7, 60, 34, 75, - 60, 34, 218, 133, 60, 34, 218, 250, 60, 34, 216, 0, 60, 34, 242, 154, 60, - 34, 250, 226, 60, 34, 218, 162, 60, 34, 252, 162, 60, 34, 223, 34, 60, - 34, 219, 169, 60, 34, 235, 136, 60, 34, 229, 94, 60, 34, 220, 59, 60, 34, - 244, 157, 60, 34, 226, 213, 60, 34, 254, 126, 60, 34, 225, 32, 60, 34, - 245, 235, 60, 34, 251, 140, 60, 34, 231, 91, 60, 34, 230, 188, 60, 34, - 220, 158, 60, 34, 254, 4, 60, 34, 230, 128, 60, 34, 216, 20, 60, 34, 226, - 169, 60, 34, 251, 209, 60, 34, 218, 129, 60, 34, 249, 233, 60, 34, 242, - 146, 60, 34, 216, 107, 60, 34, 235, 224, 60, 34, 251, 219, 60, 34, 212, - 58, 245, 153, 60, 34, 250, 1, 60, 34, 212, 8, 60, 34, 221, 172, 60, 34, - 240, 255, 60, 34, 219, 4, 60, 34, 214, 22, 60, 34, 252, 80, 60, 34, 225, - 76, 60, 34, 252, 182, 60, 34, 220, 54, 60, 34, 223, 113, 60, 34, 222, - 128, 60, 34, 244, 40, 60, 34, 251, 208, 60, 34, 250, 236, 60, 34, 251, - 234, 60, 34, 230, 130, 60, 34, 212, 57, 60, 34, 250, 35, 60, 34, 211, - 236, 60, 34, 247, 188, 60, 34, 213, 161, 60, 34, 242, 173, 60, 34, 232, - 143, 60, 34, 243, 95, 60, 34, 230, 123, 60, 34, 219, 96, 60, 34, 219, - 253, 217, 77, 251, 245, 60, 34, 223, 162, 60, 34, 251, 215, 60, 34, 211, - 197, 60, 34, 244, 198, 60, 34, 233, 58, 60, 34, 217, 57, 233, 58, 60, 34, - 233, 54, 60, 34, 219, 32, 60, 34, 233, 59, 60, 34, 211, 239, 60, 34, 244, - 54, 60, 34, 245, 225, 60, 34, 241, 242, 60, 34, 244, 8, 60, 34, 240, 252, - 60, 34, 251, 202, 60, 34, 217, 64, 60, 34, 242, 41, 60, 34, 244, 121, 60, - 34, 222, 30, 211, 236, 60, 34, 250, 228, 60, 34, 242, 229, 60, 34, 244, - 98, 60, 34, 251, 245, 60, 34, 222, 3, 60, 34, 248, 82, 60, 34, 212, 2, - 60, 34, 241, 217, 60, 34, 211, 41, 60, 34, 230, 197, 60, 34, 251, 229, - 60, 34, 245, 163, 60, 34, 243, 252, 60, 34, 215, 210, 60, 34, 246, 90, - 60, 34, 223, 144, 60, 34, 228, 58, 60, 34, 245, 49, 60, 34, 216, 16, 60, - 34, 246, 104, 60, 34, 215, 91, 60, 34, 244, 56, 110, 248, 45, 135, 43, - 216, 43, 222, 254, 110, 248, 45, 135, 72, 216, 43, 51, 110, 248, 45, 135, - 43, 216, 43, 230, 229, 22, 222, 254, 110, 248, 45, 135, 72, 216, 43, 230, - 229, 22, 51, 110, 248, 45, 135, 243, 236, 218, 11, 110, 248, 45, 135, - 218, 12, 243, 251, 48, 110, 248, 45, 135, 218, 12, 243, 251, 51, 110, - 248, 45, 135, 218, 12, 243, 251, 233, 52, 110, 248, 45, 135, 218, 12, - 243, 251, 214, 160, 233, 52, 110, 248, 45, 135, 218, 12, 243, 251, 214, - 160, 222, 254, 110, 248, 45, 135, 218, 12, 243, 251, 232, 114, 233, 52, - 110, 248, 45, 135, 226, 126, 110, 219, 20, 110, 249, 227, 110, 243, 236, - 218, 131, 247, 185, 79, 235, 137, 235, 243, 218, 161, 87, 110, 235, 164, - 79, 110, 250, 4, 79, 110, 54, 210, 86, 43, 254, 118, 127, 44, 254, 118, - 127, 43, 52, 254, 118, 127, 44, 52, 254, 118, 127, 43, 249, 169, 127, 44, - 249, 169, 127, 43, 71, 249, 169, 127, 44, 71, 249, 169, 127, 43, 85, 233, - 26, 127, 44, 85, 233, 26, 127, 224, 240, 79, 243, 39, 79, 43, 216, 7, - 220, 55, 127, 44, 216, 7, 220, 55, 127, 43, 71, 233, 26, 127, 44, 71, - 233, 26, 127, 43, 71, 216, 7, 220, 55, 127, 44, 71, 216, 7, 220, 55, 127, - 43, 71, 42, 127, 44, 71, 42, 127, 212, 36, 248, 164, 223, 52, 52, 224, - 194, 224, 1, 79, 52, 224, 194, 224, 1, 79, 121, 52, 224, 194, 224, 1, 79, - 224, 240, 164, 244, 198, 242, 15, 227, 202, 111, 242, 15, 227, 202, 105, - 242, 15, 227, 202, 158, 242, 15, 227, 202, 161, 242, 15, 227, 202, 190, - 242, 15, 227, 202, 195, 242, 15, 227, 202, 199, 242, 15, 227, 202, 196, - 242, 15, 227, 202, 201, 110, 233, 9, 138, 79, 110, 222, 231, 138, 79, - 110, 248, 52, 138, 79, 110, 245, 136, 138, 79, 24, 219, 157, 59, 138, 79, - 24, 52, 59, 138, 79, 212, 32, 248, 164, 67, 234, 239, 223, 80, 79, 67, - 234, 239, 223, 80, 2, 213, 135, 219, 33, 79, 67, 234, 239, 223, 80, 164, - 214, 160, 242, 34, 67, 234, 239, 223, 80, 2, 213, 135, 219, 33, 164, 214, - 160, 242, 34, 67, 234, 239, 223, 80, 164, 232, 114, 242, 34, 37, 224, - 240, 79, 110, 217, 4, 232, 220, 244, 154, 220, 140, 87, 242, 15, 227, - 202, 216, 248, 242, 15, 227, 202, 215, 73, 242, 15, 227, 202, 216, 163, - 67, 110, 235, 164, 79, 231, 145, 79, 226, 3, 254, 148, 79, 110, 45, 235, - 245, 110, 163, 244, 114, 219, 20, 141, 1, 4, 61, 141, 1, 61, 141, 1, 4, - 74, 141, 1, 74, 141, 1, 4, 69, 141, 1, 69, 141, 1, 4, 76, 141, 1, 76, - 141, 1, 4, 78, 141, 1, 78, 141, 1, 176, 141, 1, 243, 142, 141, 1, 234, - 98, 141, 1, 242, 221, 141, 1, 233, 223, 141, 1, 242, 120, 141, 1, 234, - 188, 141, 1, 243, 69, 141, 1, 234, 34, 141, 1, 242, 181, 141, 1, 206, - 141, 1, 210, 116, 141, 1, 219, 193, 141, 1, 210, 44, 141, 1, 218, 84, - 141, 1, 210, 13, 141, 1, 221, 183, 141, 1, 210, 94, 141, 1, 219, 60, 141, - 1, 210, 23, 141, 1, 217, 106, 141, 1, 248, 229, 141, 1, 216, 118, 141, 1, - 248, 11, 141, 1, 4, 215, 119, 141, 1, 215, 119, 141, 1, 246, 86, 141, 1, - 217, 23, 141, 1, 248, 98, 141, 1, 112, 141, 1, 247, 153, 141, 1, 198, - 141, 1, 228, 238, 141, 1, 227, 242, 141, 1, 229, 112, 141, 1, 228, 79, - 141, 1, 162, 141, 1, 252, 199, 141, 1, 191, 141, 1, 241, 187, 141, 1, - 252, 14, 141, 1, 225, 111, 141, 1, 240, 229, 141, 1, 251, 133, 141, 1, - 224, 153, 141, 1, 241, 245, 141, 1, 252, 83, 141, 1, 225, 224, 141, 1, - 241, 75, 141, 1, 251, 213, 141, 1, 225, 19, 141, 1, 186, 141, 1, 230, - 235, 141, 1, 230, 107, 141, 1, 231, 96, 141, 1, 230, 166, 141, 1, 4, 192, - 141, 1, 192, 141, 1, 4, 210, 212, 141, 1, 210, 212, 141, 1, 4, 210, 244, - 141, 1, 210, 244, 141, 1, 205, 141, 1, 223, 38, 141, 1, 222, 142, 141, 1, - 223, 131, 141, 1, 222, 213, 141, 1, 4, 212, 65, 141, 1, 212, 65, 141, 1, - 211, 250, 141, 1, 212, 22, 141, 1, 211, 227, 141, 1, 230, 30, 141, 1, - 212, 116, 141, 1, 4, 176, 141, 1, 4, 234, 188, 38, 234, 207, 213, 135, - 219, 33, 79, 38, 234, 207, 220, 157, 219, 33, 79, 234, 207, 213, 135, - 219, 33, 79, 234, 207, 220, 157, 219, 33, 79, 141, 235, 164, 79, 141, - 213, 135, 235, 164, 79, 141, 247, 229, 210, 225, 234, 207, 52, 240, 175, - 56, 1, 4, 61, 56, 1, 61, 56, 1, 4, 74, 56, 1, 74, 56, 1, 4, 69, 56, 1, - 69, 56, 1, 4, 76, 56, 1, 76, 56, 1, 4, 78, 56, 1, 78, 56, 1, 176, 56, 1, - 243, 142, 56, 1, 234, 98, 56, 1, 242, 221, 56, 1, 233, 223, 56, 1, 242, - 120, 56, 1, 234, 188, 56, 1, 243, 69, 56, 1, 234, 34, 56, 1, 242, 181, - 56, 1, 206, 56, 1, 210, 116, 56, 1, 219, 193, 56, 1, 210, 44, 56, 1, 218, - 84, 56, 1, 210, 13, 56, 1, 221, 183, 56, 1, 210, 94, 56, 1, 219, 60, 56, - 1, 210, 23, 56, 1, 217, 106, 56, 1, 248, 229, 56, 1, 216, 118, 56, 1, - 248, 11, 56, 1, 4, 215, 119, 56, 1, 215, 119, 56, 1, 246, 86, 56, 1, 217, - 23, 56, 1, 248, 98, 56, 1, 112, 56, 1, 247, 153, 56, 1, 198, 56, 1, 228, - 238, 56, 1, 227, 242, 56, 1, 229, 112, 56, 1, 228, 79, 56, 1, 162, 56, 1, - 252, 199, 56, 1, 191, 56, 1, 241, 187, 56, 1, 252, 14, 56, 1, 225, 111, - 56, 1, 240, 229, 56, 1, 251, 133, 56, 1, 224, 153, 56, 1, 241, 245, 56, - 1, 252, 83, 56, 1, 225, 224, 56, 1, 241, 75, 56, 1, 251, 213, 56, 1, 225, - 19, 56, 1, 186, 56, 1, 230, 235, 56, 1, 230, 107, 56, 1, 231, 96, 56, 1, - 230, 166, 56, 1, 4, 192, 56, 1, 192, 56, 1, 4, 210, 212, 56, 1, 210, 212, - 56, 1, 4, 210, 244, 56, 1, 210, 244, 56, 1, 205, 56, 1, 223, 38, 56, 1, - 222, 142, 56, 1, 223, 131, 56, 1, 222, 213, 56, 1, 4, 212, 65, 56, 1, - 212, 65, 56, 1, 211, 250, 56, 1, 212, 22, 56, 1, 211, 227, 56, 1, 230, - 30, 56, 1, 212, 116, 56, 1, 4, 176, 56, 1, 4, 234, 188, 56, 1, 214, 27, - 56, 1, 213, 176, 56, 1, 213, 255, 56, 1, 213, 138, 56, 230, 229, 247, - 128, 234, 207, 224, 176, 219, 33, 79, 56, 235, 164, 79, 56, 213, 135, - 235, 164, 79, 56, 247, 229, 234, 5, 251, 192, 1, 253, 166, 251, 192, 1, - 226, 109, 251, 192, 1, 194, 251, 192, 1, 245, 14, 251, 192, 1, 249, 68, - 251, 192, 1, 217, 153, 251, 192, 1, 230, 30, 251, 192, 1, 156, 251, 192, - 1, 243, 209, 251, 192, 1, 235, 29, 251, 192, 1, 242, 67, 251, 192, 1, - 235, 150, 251, 192, 1, 224, 99, 251, 192, 1, 211, 178, 251, 192, 1, 210, - 83, 251, 192, 1, 250, 166, 251, 192, 1, 220, 106, 251, 192, 1, 153, 251, - 192, 1, 210, 159, 251, 192, 1, 251, 74, 251, 192, 1, 222, 93, 251, 192, - 1, 61, 251, 192, 1, 78, 251, 192, 1, 76, 251, 192, 1, 245, 205, 251, 192, - 1, 254, 210, 251, 192, 1, 245, 203, 251, 192, 1, 253, 200, 251, 192, 1, - 226, 138, 251, 192, 1, 254, 131, 251, 192, 1, 245, 158, 251, 192, 1, 254, - 123, 251, 192, 1, 245, 146, 251, 192, 1, 245, 100, 251, 192, 1, 74, 251, - 192, 1, 69, 251, 192, 1, 235, 162, 251, 192, 1, 214, 105, 251, 192, 1, - 229, 84, 251, 192, 1, 242, 185, 251, 192, 1, 236, 41, 24, 1, 234, 64, 24, - 1, 218, 217, 24, 1, 234, 57, 24, 1, 228, 231, 24, 1, 228, 229, 24, 1, - 228, 228, 24, 1, 216, 102, 24, 1, 218, 206, 24, 1, 223, 29, 24, 1, 223, - 24, 24, 1, 223, 21, 24, 1, 223, 14, 24, 1, 223, 9, 24, 1, 223, 4, 24, 1, - 223, 15, 24, 1, 223, 27, 24, 1, 230, 222, 24, 1, 225, 98, 24, 1, 218, - 214, 24, 1, 225, 87, 24, 1, 219, 150, 24, 1, 218, 211, 24, 1, 236, 63, - 24, 1, 250, 54, 24, 1, 218, 221, 24, 1, 250, 114, 24, 1, 234, 116, 24, 1, - 216, 174, 24, 1, 225, 134, 24, 1, 241, 179, 24, 1, 61, 24, 1, 254, 252, - 24, 1, 192, 24, 1, 211, 92, 24, 1, 245, 125, 24, 1, 76, 24, 1, 211, 36, - 24, 1, 211, 47, 24, 1, 78, 24, 1, 212, 65, 24, 1, 212, 62, 24, 1, 226, - 238, 24, 1, 210, 244, 24, 1, 69, 24, 1, 212, 11, 24, 1, 212, 22, 24, 1, - 211, 250, 24, 1, 210, 212, 24, 1, 245, 63, 24, 1, 211, 8, 24, 1, 74, 24, - 244, 111, 24, 1, 218, 215, 24, 1, 228, 221, 24, 1, 228, 223, 24, 1, 228, - 226, 24, 1, 223, 22, 24, 1, 223, 3, 24, 1, 223, 11, 24, 1, 223, 16, 24, - 1, 223, 1, 24, 1, 230, 215, 24, 1, 230, 212, 24, 1, 230, 216, 24, 1, 234, - 227, 24, 1, 225, 93, 24, 1, 225, 79, 24, 1, 225, 85, 24, 1, 225, 82, 24, - 1, 225, 96, 24, 1, 225, 80, 24, 1, 234, 225, 24, 1, 234, 223, 24, 1, 219, - 143, 24, 1, 219, 141, 24, 1, 219, 133, 24, 1, 219, 138, 24, 1, 219, 148, - 24, 1, 226, 36, 24, 1, 218, 218, 24, 1, 211, 26, 24, 1, 211, 22, 24, 1, - 211, 23, 24, 1, 234, 226, 24, 1, 218, 219, 24, 1, 211, 32, 24, 1, 210, - 238, 24, 1, 210, 237, 24, 1, 210, 240, 24, 1, 210, 203, 24, 1, 210, 204, - 24, 1, 210, 207, 24, 1, 254, 42, 24, 1, 254, 36, 110, 254, 107, 232, 209, - 79, 110, 254, 107, 223, 53, 79, 110, 254, 107, 123, 79, 110, 254, 107, - 113, 79, 110, 254, 107, 134, 79, 110, 254, 107, 244, 19, 79, 110, 254, - 107, 216, 15, 79, 110, 254, 107, 230, 229, 79, 110, 254, 107, 251, 183, - 79, 110, 254, 107, 244, 100, 79, 110, 254, 107, 221, 178, 79, 110, 254, - 107, 216, 170, 79, 110, 254, 107, 244, 12, 79, 110, 254, 107, 241, 231, - 79, 110, 254, 107, 245, 232, 79, 110, 254, 107, 231, 191, 79, 251, 192, - 1, 251, 133, 251, 192, 1, 210, 44, 251, 192, 1, 235, 114, 251, 192, 1, - 242, 120, 251, 192, 1, 245, 217, 251, 192, 1, 245, 143, 251, 192, 1, 226, - 187, 251, 192, 1, 226, 191, 251, 192, 1, 235, 186, 251, 192, 1, 254, 109, - 251, 192, 1, 235, 231, 251, 192, 1, 214, 168, 251, 192, 1, 236, 23, 251, - 192, 1, 229, 62, 251, 192, 1, 254, 204, 251, 192, 1, 253, 195, 251, 192, - 1, 254, 144, 251, 192, 1, 226, 208, 251, 192, 1, 226, 193, 251, 192, 1, - 235, 228, 251, 192, 40, 1, 226, 109, 251, 192, 40, 1, 217, 153, 251, 192, - 40, 1, 235, 29, 251, 192, 40, 1, 242, 67, 251, 192, 1, 243, 1, 251, 192, - 1, 233, 5, 251, 192, 1, 209, 250, 10, 218, 105, 217, 153, 10, 218, 105, - 212, 4, 10, 218, 105, 211, 158, 10, 218, 105, 251, 87, 10, 218, 105, 217, - 255, 10, 218, 105, 240, 165, 10, 218, 105, 240, 169, 10, 218, 105, 240, - 238, 10, 218, 105, 240, 166, 10, 218, 105, 217, 156, 10, 218, 105, 240, - 168, 10, 218, 105, 240, 164, 10, 218, 105, 240, 236, 10, 218, 105, 240, - 167, 10, 218, 105, 240, 163, 10, 218, 105, 230, 30, 10, 218, 105, 242, - 67, 10, 218, 105, 222, 93, 10, 218, 105, 226, 109, 10, 218, 105, 219, 23, - 10, 218, 105, 249, 68, 10, 218, 105, 240, 170, 10, 218, 105, 241, 197, - 10, 218, 105, 217, 165, 10, 218, 105, 217, 234, 10, 218, 105, 218, 170, - 10, 218, 105, 220, 112, 10, 218, 105, 225, 228, 10, 218, 105, 224, 101, - 10, 218, 105, 216, 44, 10, 218, 105, 217, 155, 10, 218, 105, 217, 245, - 10, 218, 105, 240, 177, 10, 218, 105, 240, 162, 10, 218, 105, 225, 152, - 10, 218, 105, 224, 99, 56, 1, 4, 233, 223, 56, 1, 4, 219, 193, 56, 1, 4, - 218, 84, 56, 1, 4, 112, 56, 1, 4, 227, 242, 56, 1, 4, 162, 56, 1, 4, 241, - 187, 56, 1, 4, 240, 229, 56, 1, 4, 241, 245, 56, 1, 4, 241, 75, 56, 1, 4, - 230, 107, 56, 1, 4, 205, 56, 1, 4, 223, 38, 56, 1, 4, 222, 142, 56, 1, 4, - 223, 131, 56, 1, 4, 222, 213, 88, 24, 234, 64, 88, 24, 228, 231, 88, 24, - 216, 102, 88, 24, 223, 29, 88, 24, 230, 222, 88, 24, 225, 98, 88, 24, - 219, 150, 88, 24, 236, 63, 88, 24, 250, 54, 88, 24, 250, 114, 88, 24, - 234, 116, 88, 24, 216, 174, 88, 24, 225, 134, 88, 24, 241, 179, 88, 24, - 234, 65, 61, 88, 24, 228, 232, 61, 88, 24, 216, 103, 61, 88, 24, 223, 30, - 61, 88, 24, 230, 223, 61, 88, 24, 225, 99, 61, 88, 24, 219, 151, 61, 88, - 24, 236, 64, 61, 88, 24, 250, 55, 61, 88, 24, 250, 115, 61, 88, 24, 234, - 117, 61, 88, 24, 216, 175, 61, 88, 24, 225, 135, 61, 88, 24, 241, 180, - 61, 88, 24, 250, 55, 69, 88, 234, 9, 135, 226, 221, 88, 234, 9, 135, 144, - 240, 229, 88, 154, 111, 88, 154, 105, 88, 154, 158, 88, 154, 161, 88, - 154, 190, 88, 154, 195, 88, 154, 199, 88, 154, 196, 88, 154, 201, 88, - 154, 216, 248, 88, 154, 230, 133, 88, 154, 244, 104, 88, 154, 212, 40, - 88, 154, 211, 214, 88, 154, 231, 44, 88, 154, 245, 231, 88, 154, 218, 38, - 88, 154, 218, 134, 88, 154, 241, 251, 88, 154, 219, 56, 88, 154, 229, - 209, 88, 154, 219, 6, 88, 154, 244, 110, 88, 154, 249, 208, 88, 154, 233, - 131, 88, 154, 223, 74, 88, 154, 251, 23, 88, 154, 218, 88, 88, 154, 218, - 21, 88, 154, 245, 135, 88, 154, 223, 66, 88, 154, 254, 159, 88, 154, 244, - 136, 88, 154, 223, 64, 88, 154, 220, 158, 88, 154, 223, 130, 37, 154, - 224, 15, 37, 154, 234, 86, 37, 154, 221, 200, 37, 154, 234, 5, 37, 54, - 216, 249, 226, 201, 85, 218, 236, 37, 54, 215, 74, 226, 201, 85, 218, - 236, 37, 54, 216, 164, 226, 201, 85, 218, 236, 37, 54, 244, 24, 226, 201, - 85, 218, 236, 37, 54, 244, 123, 226, 201, 85, 218, 236, 37, 54, 219, 114, - 226, 201, 85, 218, 236, 37, 54, 220, 119, 226, 201, 85, 218, 236, 37, 54, - 245, 193, 226, 201, 85, 218, 236, 225, 255, 50, 37, 54, 215, 74, 111, 37, - 54, 215, 74, 105, 37, 54, 215, 74, 158, 37, 54, 215, 74, 161, 37, 54, - 215, 74, 190, 37, 54, 215, 74, 195, 37, 54, 215, 74, 199, 37, 54, 215, - 74, 196, 37, 54, 215, 74, 201, 37, 54, 216, 163, 37, 54, 216, 164, 111, - 37, 54, 216, 164, 105, 37, 54, 216, 164, 158, 37, 54, 216, 164, 161, 37, - 54, 216, 164, 190, 37, 24, 234, 64, 37, 24, 228, 231, 37, 24, 216, 102, - 37, 24, 223, 29, 37, 24, 230, 222, 37, 24, 225, 98, 37, 24, 219, 150, 37, - 24, 236, 63, 37, 24, 250, 54, 37, 24, 250, 114, 37, 24, 234, 116, 37, 24, - 216, 174, 37, 24, 225, 134, 37, 24, 241, 179, 37, 24, 234, 65, 61, 37, - 24, 228, 232, 61, 37, 24, 216, 103, 61, 37, 24, 223, 30, 61, 37, 24, 230, - 223, 61, 37, 24, 225, 99, 61, 37, 24, 219, 151, 61, 37, 24, 236, 64, 61, - 37, 24, 250, 55, 61, 37, 24, 250, 115, 61, 37, 24, 234, 117, 61, 37, 24, - 216, 175, 61, 37, 24, 225, 135, 61, 37, 24, 241, 180, 61, 37, 234, 9, - 135, 250, 156, 37, 234, 9, 135, 235, 53, 37, 24, 236, 64, 69, 234, 9, - 218, 161, 87, 37, 154, 111, 37, 154, 105, 37, 154, 158, 37, 154, 161, 37, - 154, 190, 37, 154, 195, 37, 154, 199, 37, 154, 196, 37, 154, 201, 37, - 154, 216, 248, 37, 154, 230, 133, 37, 154, 244, 104, 37, 154, 212, 40, - 37, 154, 211, 214, 37, 154, 231, 44, 37, 154, 245, 231, 37, 154, 218, 38, - 37, 154, 218, 134, 37, 154, 241, 251, 37, 154, 219, 56, 37, 154, 229, - 209, 37, 154, 219, 6, 37, 154, 244, 110, 37, 154, 249, 208, 37, 154, 233, - 131, 37, 154, 221, 176, 37, 154, 231, 194, 37, 154, 244, 145, 37, 154, - 218, 50, 37, 154, 245, 42, 37, 154, 224, 190, 37, 154, 253, 204, 37, 154, - 235, 165, 37, 154, 223, 64, 37, 154, 249, 172, 37, 154, 249, 163, 37, - 154, 241, 172, 37, 154, 250, 182, 37, 154, 232, 116, 37, 154, 233, 52, - 37, 154, 222, 254, 37, 154, 231, 88, 37, 154, 223, 90, 37, 154, 218, 88, - 37, 154, 218, 21, 37, 154, 245, 135, 37, 154, 223, 66, 37, 154, 254, 159, - 37, 154, 228, 217, 37, 54, 216, 164, 195, 37, 54, 216, 164, 199, 37, 54, - 216, 164, 196, 37, 54, 216, 164, 201, 37, 54, 244, 23, 37, 54, 244, 24, - 111, 37, 54, 244, 24, 105, 37, 54, 244, 24, 158, 37, 54, 244, 24, 161, - 37, 54, 244, 24, 190, 37, 54, 244, 24, 195, 37, 54, 244, 24, 199, 37, 54, - 244, 24, 196, 37, 54, 244, 24, 201, 37, 54, 244, 122, 110, 217, 4, 16, - 31, 235, 139, 110, 217, 4, 16, 31, 244, 156, 110, 217, 4, 16, 31, 231, - 165, 110, 217, 4, 16, 31, 254, 55, 110, 217, 4, 16, 31, 231, 137, 110, - 217, 4, 16, 31, 235, 51, 110, 217, 4, 16, 31, 235, 52, 110, 217, 4, 16, - 31, 253, 196, 110, 217, 4, 16, 31, 220, 138, 110, 217, 4, 16, 31, 226, - 243, 110, 217, 4, 16, 31, 228, 45, 110, 217, 4, 16, 31, 248, 93, 42, 241, - 197, 42, 245, 96, 42, 245, 51, 232, 225, 232, 246, 50, 37, 56, 61, 37, - 56, 74, 37, 56, 69, 37, 56, 76, 37, 56, 78, 37, 56, 176, 37, 56, 234, 98, - 37, 56, 233, 223, 37, 56, 234, 188, 37, 56, 234, 34, 37, 56, 206, 37, 56, - 219, 193, 37, 56, 218, 84, 37, 56, 221, 183, 37, 56, 219, 60, 37, 56, - 217, 106, 37, 56, 216, 118, 37, 56, 215, 119, 37, 56, 217, 23, 37, 56, - 112, 37, 56, 198, 37, 56, 228, 238, 37, 56, 227, 242, 37, 56, 229, 112, - 37, 56, 228, 79, 37, 56, 162, 37, 56, 241, 187, 37, 56, 240, 229, 37, 56, - 241, 245, 37, 56, 241, 75, 37, 56, 186, 37, 56, 230, 235, 37, 56, 230, - 107, 37, 56, 231, 96, 37, 56, 230, 166, 37, 56, 192, 37, 56, 210, 212, - 37, 56, 210, 244, 37, 56, 205, 37, 56, 223, 38, 37, 56, 222, 142, 37, 56, - 223, 131, 37, 56, 222, 213, 37, 56, 212, 65, 37, 56, 211, 250, 37, 56, - 212, 22, 37, 56, 211, 227, 42, 254, 79, 42, 253, 247, 42, 254, 103, 42, - 255, 40, 42, 235, 233, 42, 235, 203, 42, 214, 166, 42, 245, 74, 42, 245, - 214, 42, 226, 190, 42, 226, 184, 42, 234, 251, 42, 234, 220, 42, 234, - 217, 42, 243, 99, 42, 243, 108, 42, 242, 211, 42, 242, 207, 42, 233, 156, - 42, 242, 200, 42, 234, 78, 42, 234, 77, 42, 234, 76, 42, 234, 75, 42, - 242, 93, 42, 242, 92, 42, 233, 199, 42, 233, 201, 42, 234, 184, 42, 234, - 7, 42, 234, 14, 42, 222, 18, 42, 221, 239, 42, 219, 131, 42, 220, 143, - 42, 220, 142, 42, 248, 226, 42, 248, 44, 42, 247, 129, 42, 216, 33, 42, - 229, 205, 42, 228, 46, 42, 242, 39, 42, 226, 88, 42, 226, 87, 42, 252, - 196, 42, 225, 108, 42, 225, 72, 42, 225, 73, 42, 251, 242, 42, 240, 228, - 42, 240, 224, 42, 251, 99, 42, 240, 211, 42, 241, 222, 42, 225, 162, 42, - 225, 197, 42, 241, 205, 42, 225, 194, 42, 225, 210, 42, 252, 69, 42, 225, - 9, 42, 251, 188, 42, 241, 63, 42, 224, 253, 42, 241, 55, 42, 241, 57, 42, - 231, 206, 42, 231, 202, 42, 231, 211, 42, 231, 155, 42, 231, 180, 42, - 230, 202, 42, 230, 181, 42, 230, 180, 42, 231, 79, 42, 231, 76, 42, 231, - 80, 42, 211, 102, 42, 211, 100, 42, 210, 201, 42, 222, 229, 42, 222, 233, - 42, 222, 119, 42, 222, 113, 42, 223, 88, 42, 223, 85, 42, 212, 38, 110, - 217, 4, 16, 31, 240, 246, 210, 86, 110, 217, 4, 16, 31, 240, 246, 111, - 110, 217, 4, 16, 31, 240, 246, 105, 110, 217, 4, 16, 31, 240, 246, 158, - 110, 217, 4, 16, 31, 240, 246, 161, 110, 217, 4, 16, 31, 240, 246, 190, - 110, 217, 4, 16, 31, 240, 246, 195, 110, 217, 4, 16, 31, 240, 246, 199, - 110, 217, 4, 16, 31, 240, 246, 196, 110, 217, 4, 16, 31, 240, 246, 201, - 110, 217, 4, 16, 31, 240, 246, 216, 248, 110, 217, 4, 16, 31, 240, 246, - 245, 175, 110, 217, 4, 16, 31, 240, 246, 215, 76, 110, 217, 4, 16, 31, - 240, 246, 216, 165, 110, 217, 4, 16, 31, 240, 246, 244, 13, 110, 217, 4, - 16, 31, 240, 246, 244, 126, 110, 217, 4, 16, 31, 240, 246, 219, 121, 110, - 217, 4, 16, 31, 240, 246, 220, 121, 110, 217, 4, 16, 31, 240, 246, 245, - 198, 110, 217, 4, 16, 31, 240, 246, 228, 202, 110, 217, 4, 16, 31, 240, - 246, 215, 73, 110, 217, 4, 16, 31, 240, 246, 215, 67, 110, 217, 4, 16, - 31, 240, 246, 215, 63, 110, 217, 4, 16, 31, 240, 246, 215, 64, 110, 217, - 4, 16, 31, 240, 246, 215, 69, 42, 240, 237, 42, 248, 229, 42, 253, 200, - 42, 130, 42, 226, 129, 42, 225, 229, 42, 247, 155, 42, 247, 156, 218, - 235, 42, 247, 156, 249, 116, 42, 235, 162, 42, 245, 99, 229, 210, 241, - 223, 42, 245, 99, 229, 210, 217, 175, 42, 245, 99, 229, 210, 217, 75, 42, - 245, 99, 229, 210, 231, 75, 42, 249, 165, 42, 226, 94, 254, 133, 42, 198, - 42, 230, 108, 61, 42, 186, 42, 176, 42, 234, 191, 42, 231, 134, 42, 243, - 87, 42, 251, 26, 42, 234, 190, 42, 225, 153, 42, 229, 86, 42, 230, 108, - 245, 14, 42, 230, 108, 243, 209, 42, 231, 20, 42, 234, 140, 42, 240, 170, - 42, 234, 100, 42, 230, 237, 42, 242, 223, 42, 216, 120, 42, 230, 108, - 156, 42, 230, 174, 42, 247, 165, 42, 234, 46, 42, 244, 53, 42, 228, 117, - 42, 230, 108, 194, 42, 230, 171, 42, 249, 247, 42, 234, 40, 42, 230, 172, - 218, 235, 42, 249, 248, 218, 235, 42, 232, 55, 218, 235, 42, 234, 41, - 218, 235, 42, 230, 172, 249, 116, 42, 249, 248, 249, 116, 42, 232, 55, - 249, 116, 42, 234, 41, 249, 116, 42, 232, 55, 115, 222, 93, 42, 232, 55, - 115, 222, 94, 218, 235, 42, 191, 42, 234, 1, 42, 230, 110, 42, 242, 158, - 42, 223, 179, 42, 223, 180, 115, 222, 93, 42, 223, 180, 115, 222, 94, - 218, 235, 42, 224, 165, 42, 228, 18, 42, 230, 108, 222, 93, 42, 230, 109, - 42, 224, 119, 42, 227, 180, 42, 230, 108, 214, 105, 42, 230, 54, 42, 233, - 191, 42, 230, 55, 231, 79, 42, 224, 118, 42, 227, 179, 42, 230, 108, 212, - 98, 42, 230, 48, 42, 233, 189, 42, 230, 49, 231, 79, 42, 235, 30, 226, - 224, 42, 232, 55, 226, 224, 42, 254, 144, 42, 251, 168, 42, 250, 222, 42, - 250, 199, 42, 251, 75, 115, 234, 140, 42, 249, 246, 42, 248, 150, 42, - 242, 79, 42, 162, 42, 240, 238, 42, 236, 6, 42, 234, 53, 42, 234, 41, - 251, 2, 42, 233, 225, 42, 232, 165, 42, 232, 164, 42, 232, 153, 42, 232, - 68, 42, 231, 135, 219, 81, 42, 230, 201, 42, 230, 157, 42, 225, 151, 42, - 225, 22, 42, 224, 222, 42, 224, 220, 42, 218, 229, 42, 218, 3, 42, 212, - 24, 42, 214, 106, 115, 194, 42, 116, 115, 194, 110, 217, 4, 16, 31, 248, - 154, 111, 110, 217, 4, 16, 31, 248, 154, 105, 110, 217, 4, 16, 31, 248, - 154, 158, 110, 217, 4, 16, 31, 248, 154, 161, 110, 217, 4, 16, 31, 248, - 154, 190, 110, 217, 4, 16, 31, 248, 154, 195, 110, 217, 4, 16, 31, 248, - 154, 199, 110, 217, 4, 16, 31, 248, 154, 196, 110, 217, 4, 16, 31, 248, - 154, 201, 110, 217, 4, 16, 31, 248, 154, 216, 248, 110, 217, 4, 16, 31, - 248, 154, 245, 175, 110, 217, 4, 16, 31, 248, 154, 215, 76, 110, 217, 4, - 16, 31, 248, 154, 216, 165, 110, 217, 4, 16, 31, 248, 154, 244, 13, 110, - 217, 4, 16, 31, 248, 154, 244, 126, 110, 217, 4, 16, 31, 248, 154, 219, - 121, 110, 217, 4, 16, 31, 248, 154, 220, 121, 110, 217, 4, 16, 31, 248, - 154, 245, 198, 110, 217, 4, 16, 31, 248, 154, 228, 202, 110, 217, 4, 16, - 31, 248, 154, 215, 73, 110, 217, 4, 16, 31, 248, 154, 215, 67, 110, 217, - 4, 16, 31, 248, 154, 215, 63, 110, 217, 4, 16, 31, 248, 154, 215, 64, - 110, 217, 4, 16, 31, 248, 154, 215, 69, 110, 217, 4, 16, 31, 248, 154, - 215, 70, 110, 217, 4, 16, 31, 248, 154, 215, 65, 110, 217, 4, 16, 31, - 248, 154, 215, 66, 110, 217, 4, 16, 31, 248, 154, 215, 72, 110, 217, 4, - 16, 31, 248, 154, 215, 68, 110, 217, 4, 16, 31, 248, 154, 216, 163, 110, - 217, 4, 16, 31, 248, 154, 216, 162, 42, 243, 125, 241, 199, 31, 216, 197, - 249, 148, 241, 230, 241, 199, 31, 216, 197, 223, 125, 245, 231, 241, 199, - 31, 247, 239, 253, 215, 216, 197, 252, 64, 241, 199, 31, 210, 223, 244, - 46, 241, 199, 31, 212, 59, 241, 199, 31, 249, 211, 241, 199, 31, 216, - 197, 254, 11, 241, 199, 31, 241, 67, 216, 39, 241, 199, 31, 4, 217, 62, - 241, 199, 31, 215, 238, 241, 199, 31, 225, 222, 241, 199, 31, 218, 160, - 241, 199, 31, 244, 147, 241, 199, 31, 242, 139, 224, 243, 241, 199, 31, - 230, 160, 241, 199, 31, 245, 134, 241, 199, 31, 244, 47, 241, 199, 31, - 211, 207, 226, 201, 216, 197, 248, 94, 241, 199, 31, 254, 59, 241, 199, - 31, 249, 193, 241, 199, 31, 251, 235, 216, 139, 241, 199, 31, 242, 156, - 241, 199, 31, 218, 247, 254, 78, 241, 199, 31, 223, 56, 241, 199, 31, - 235, 227, 241, 199, 31, 242, 139, 217, 62, 241, 199, 31, 230, 116, 249, - 167, 241, 199, 31, 242, 139, 224, 200, 241, 199, 31, 216, 197, 255, 27, - 212, 40, 241, 199, 31, 216, 197, 250, 16, 244, 104, 241, 199, 31, 235, - 240, 241, 199, 31, 246, 65, 241, 199, 31, 223, 59, 241, 199, 31, 242, - 139, 224, 227, 241, 199, 31, 224, 180, 241, 199, 31, 248, 169, 64, 216, - 197, 232, 236, 241, 199, 31, 216, 197, 244, 182, 241, 199, 31, 226, 167, - 241, 199, 31, 226, 248, 241, 199, 31, 248, 67, 241, 199, 31, 248, 87, - 241, 199, 31, 235, 254, 241, 199, 31, 251, 157, 241, 199, 31, 249, 229, - 216, 43, 231, 81, 241, 199, 31, 243, 94, 216, 39, 241, 199, 31, 224, 128, - 214, 154, 241, 199, 31, 226, 166, 241, 199, 31, 216, 197, 212, 13, 241, - 199, 31, 223, 48, 241, 199, 31, 216, 197, 250, 228, 241, 199, 31, 216, - 197, 254, 7, 216, 134, 241, 199, 31, 216, 197, 234, 185, 218, 136, 230, - 120, 241, 199, 31, 248, 40, 241, 199, 31, 216, 197, 231, 157, 231, 207, - 241, 199, 31, 255, 28, 241, 199, 31, 216, 197, 212, 54, 241, 199, 31, - 216, 197, 243, 54, 211, 239, 241, 199, 31, 216, 197, 235, 58, 233, 113, - 241, 199, 31, 247, 192, 241, 199, 31, 232, 226, 241, 199, 31, 235, 230, - 215, 188, 241, 199, 31, 4, 224, 200, 241, 199, 31, 254, 226, 249, 220, - 241, 199, 31, 252, 67, 249, 220, 8, 3, 235, 166, 8, 3, 235, 159, 8, 3, - 74, 8, 3, 235, 189, 8, 3, 236, 65, 8, 3, 236, 48, 8, 3, 236, 67, 8, 3, - 236, 66, 8, 3, 253, 214, 8, 3, 253, 177, 8, 3, 61, 8, 3, 254, 80, 8, 3, - 214, 164, 8, 3, 214, 167, 8, 3, 214, 165, 8, 3, 226, 144, 8, 3, 226, 118, - 8, 3, 78, 8, 3, 226, 179, 8, 3, 245, 43, 8, 3, 76, 8, 3, 211, 195, 8, 3, - 251, 236, 8, 3, 251, 233, 8, 3, 252, 14, 8, 3, 251, 246, 8, 3, 252, 3, 8, - 3, 252, 2, 8, 3, 252, 5, 8, 3, 252, 4, 8, 3, 252, 129, 8, 3, 252, 121, 8, - 3, 252, 199, 8, 3, 252, 150, 8, 3, 251, 109, 8, 3, 251, 113, 8, 3, 251, - 110, 8, 3, 251, 187, 8, 3, 251, 171, 8, 3, 251, 213, 8, 3, 251, 193, 8, - 3, 252, 29, 8, 3, 252, 83, 8, 3, 252, 41, 8, 3, 251, 95, 8, 3, 251, 92, - 8, 3, 251, 133, 8, 3, 251, 108, 8, 3, 251, 102, 8, 3, 251, 106, 8, 3, - 251, 80, 8, 3, 251, 78, 8, 3, 251, 85, 8, 3, 251, 83, 8, 3, 251, 81, 8, - 3, 251, 82, 8, 3, 225, 52, 8, 3, 225, 48, 8, 3, 225, 111, 8, 3, 225, 62, - 8, 3, 225, 78, 8, 3, 225, 105, 8, 3, 225, 101, 8, 3, 225, 244, 8, 3, 225, - 234, 8, 3, 191, 8, 3, 226, 25, 8, 3, 224, 138, 8, 3, 224, 140, 8, 3, 224, - 139, 8, 3, 224, 236, 8, 3, 224, 225, 8, 3, 225, 19, 8, 3, 224, 248, 8, 3, - 224, 124, 8, 3, 224, 120, 8, 3, 224, 153, 8, 3, 224, 137, 8, 3, 224, 129, - 8, 3, 224, 135, 8, 3, 224, 103, 8, 3, 224, 102, 8, 3, 224, 107, 8, 3, - 224, 106, 8, 3, 224, 104, 8, 3, 224, 105, 8, 3, 252, 104, 8, 3, 252, 103, - 8, 3, 252, 110, 8, 3, 252, 105, 8, 3, 252, 107, 8, 3, 252, 106, 8, 3, - 252, 109, 8, 3, 252, 108, 8, 3, 252, 116, 8, 3, 252, 115, 8, 3, 252, 119, - 8, 3, 252, 117, 8, 3, 252, 95, 8, 3, 252, 97, 8, 3, 252, 96, 8, 3, 252, - 100, 8, 3, 252, 99, 8, 3, 252, 102, 8, 3, 252, 101, 8, 3, 252, 111, 8, 3, - 252, 114, 8, 3, 252, 112, 8, 3, 252, 91, 8, 3, 252, 90, 8, 3, 252, 98, 8, - 3, 252, 94, 8, 3, 252, 92, 8, 3, 252, 93, 8, 3, 252, 87, 8, 3, 252, 86, - 8, 3, 252, 89, 8, 3, 252, 88, 8, 3, 229, 174, 8, 3, 229, 173, 8, 3, 229, - 179, 8, 3, 229, 175, 8, 3, 229, 176, 8, 3, 229, 178, 8, 3, 229, 177, 8, - 3, 229, 182, 8, 3, 229, 181, 8, 3, 229, 184, 8, 3, 229, 183, 8, 3, 229, - 170, 8, 3, 229, 169, 8, 3, 229, 172, 8, 3, 229, 171, 8, 3, 229, 163, 8, - 3, 229, 162, 8, 3, 229, 167, 8, 3, 229, 166, 8, 3, 229, 164, 8, 3, 229, - 165, 8, 3, 229, 157, 8, 3, 229, 156, 8, 3, 229, 161, 8, 3, 229, 160, 8, - 3, 229, 158, 8, 3, 229, 159, 8, 3, 241, 117, 8, 3, 241, 116, 8, 3, 241, - 122, 8, 3, 241, 118, 8, 3, 241, 119, 8, 3, 241, 121, 8, 3, 241, 120, 8, - 3, 241, 125, 8, 3, 241, 124, 8, 3, 241, 127, 8, 3, 241, 126, 8, 3, 241, - 108, 8, 3, 241, 110, 8, 3, 241, 109, 8, 3, 241, 113, 8, 3, 241, 112, 8, - 3, 241, 115, 8, 3, 241, 114, 8, 3, 241, 104, 8, 3, 241, 103, 8, 3, 241, - 111, 8, 3, 241, 107, 8, 3, 241, 105, 8, 3, 241, 106, 8, 3, 241, 98, 8, 3, - 241, 102, 8, 3, 241, 101, 8, 3, 241, 99, 8, 3, 241, 100, 8, 3, 230, 177, - 8, 3, 230, 176, 8, 3, 230, 235, 8, 3, 230, 183, 8, 3, 230, 208, 8, 3, - 230, 226, 8, 3, 230, 224, 8, 3, 231, 144, 8, 3, 231, 139, 8, 3, 186, 8, - 3, 231, 177, 8, 3, 230, 79, 8, 3, 230, 78, 8, 3, 230, 82, 8, 3, 230, 80, - 8, 3, 230, 126, 8, 3, 230, 112, 8, 3, 230, 166, 8, 3, 230, 131, 8, 3, - 231, 31, 8, 3, 231, 96, 8, 3, 230, 60, 8, 3, 230, 56, 8, 3, 230, 107, 8, - 3, 230, 75, 8, 3, 230, 68, 8, 3, 230, 73, 8, 3, 230, 33, 8, 3, 230, 32, - 8, 3, 230, 38, 8, 3, 230, 35, 8, 3, 244, 91, 8, 3, 244, 86, 8, 3, 244, - 129, 8, 3, 244, 106, 8, 3, 244, 175, 8, 3, 244, 166, 8, 3, 244, 204, 8, - 3, 244, 178, 8, 3, 244, 11, 8, 3, 244, 51, 8, 3, 244, 35, 8, 3, 243, 225, - 8, 3, 243, 224, 8, 3, 243, 241, 8, 3, 243, 230, 8, 3, 243, 228, 8, 3, - 243, 229, 8, 3, 243, 212, 8, 3, 243, 211, 8, 3, 243, 215, 8, 3, 243, 213, - 8, 3, 213, 144, 8, 3, 213, 139, 8, 3, 213, 176, 8, 3, 213, 153, 8, 3, - 213, 166, 8, 3, 213, 163, 8, 3, 213, 168, 8, 3, 213, 167, 8, 3, 214, 7, - 8, 3, 214, 2, 8, 3, 214, 27, 8, 3, 214, 18, 8, 3, 213, 125, 8, 3, 213, - 121, 8, 3, 213, 138, 8, 3, 213, 126, 8, 3, 213, 178, 8, 3, 213, 244, 8, - 3, 212, 110, 8, 3, 212, 108, 8, 3, 212, 116, 8, 3, 212, 113, 8, 3, 212, - 111, 8, 3, 212, 112, 8, 3, 212, 102, 8, 3, 212, 101, 8, 3, 212, 106, 8, - 3, 212, 105, 8, 3, 212, 103, 8, 3, 212, 104, 8, 3, 247, 186, 8, 3, 247, - 174, 8, 3, 248, 11, 8, 3, 247, 211, 8, 3, 247, 244, 8, 3, 247, 248, 8, 3, - 247, 247, 8, 3, 248, 160, 8, 3, 248, 155, 8, 3, 248, 229, 8, 3, 248, 180, - 8, 3, 246, 70, 8, 3, 246, 71, 8, 3, 247, 128, 8, 3, 246, 110, 8, 3, 247, - 153, 8, 3, 247, 130, 8, 3, 248, 38, 8, 3, 248, 98, 8, 3, 248, 53, 8, 3, - 246, 61, 8, 3, 246, 59, 8, 3, 246, 86, 8, 3, 246, 69, 8, 3, 246, 64, 8, - 3, 246, 67, 8, 3, 216, 68, 8, 3, 216, 62, 8, 3, 216, 118, 8, 3, 216, 77, - 8, 3, 216, 110, 8, 3, 216, 112, 8, 3, 216, 111, 8, 3, 217, 47, 8, 3, 217, - 34, 8, 3, 217, 106, 8, 3, 217, 55, 8, 3, 215, 103, 8, 3, 215, 102, 8, 3, - 215, 105, 8, 3, 215, 104, 8, 3, 216, 6, 8, 3, 216, 2, 8, 3, 112, 8, 3, - 216, 14, 8, 3, 216, 214, 8, 3, 217, 23, 8, 3, 216, 238, 8, 3, 215, 88, 8, - 3, 215, 83, 8, 3, 215, 119, 8, 3, 215, 101, 8, 3, 215, 89, 8, 3, 215, 99, - 8, 3, 248, 115, 8, 3, 248, 114, 8, 3, 248, 120, 8, 3, 248, 116, 8, 3, - 248, 117, 8, 3, 248, 119, 8, 3, 248, 118, 8, 3, 248, 136, 8, 3, 248, 135, - 8, 3, 248, 143, 8, 3, 248, 137, 8, 3, 248, 105, 8, 3, 248, 107, 8, 3, - 248, 106, 8, 3, 248, 110, 8, 3, 248, 109, 8, 3, 248, 113, 8, 3, 248, 111, - 8, 3, 248, 128, 8, 3, 248, 131, 8, 3, 248, 129, 8, 3, 248, 101, 8, 3, - 248, 100, 8, 3, 248, 108, 8, 3, 248, 104, 8, 3, 248, 102, 8, 3, 248, 103, - 8, 3, 229, 131, 8, 3, 229, 130, 8, 3, 229, 138, 8, 3, 229, 133, 8, 3, - 229, 134, 8, 3, 229, 135, 8, 3, 229, 147, 8, 3, 229, 146, 8, 3, 229, 153, - 8, 3, 229, 148, 8, 3, 229, 123, 8, 3, 229, 122, 8, 3, 229, 129, 8, 3, - 229, 124, 8, 3, 229, 139, 8, 3, 229, 145, 8, 3, 229, 143, 8, 3, 229, 115, - 8, 3, 229, 114, 8, 3, 229, 120, 8, 3, 229, 118, 8, 3, 229, 116, 8, 3, - 229, 117, 8, 3, 241, 84, 8, 3, 241, 83, 8, 3, 241, 90, 8, 3, 241, 85, 8, - 3, 241, 87, 8, 3, 241, 86, 8, 3, 241, 89, 8, 3, 241, 88, 8, 3, 241, 95, - 8, 3, 241, 94, 8, 3, 241, 97, 8, 3, 241, 96, 8, 3, 241, 78, 8, 3, 241, - 79, 8, 3, 241, 81, 8, 3, 241, 80, 8, 3, 241, 82, 8, 3, 241, 91, 8, 3, - 241, 93, 8, 3, 241, 92, 8, 3, 241, 77, 8, 3, 228, 194, 8, 3, 228, 192, 8, - 3, 228, 238, 8, 3, 228, 197, 8, 3, 228, 220, 8, 3, 228, 234, 8, 3, 228, - 233, 8, 3, 229, 188, 8, 3, 198, 8, 3, 229, 202, 8, 3, 227, 190, 8, 3, - 227, 192, 8, 3, 227, 191, 8, 3, 228, 56, 8, 3, 228, 43, 8, 3, 228, 79, 8, - 3, 228, 65, 8, 3, 229, 88, 8, 3, 229, 112, 8, 3, 229, 99, 8, 3, 227, 185, - 8, 3, 227, 181, 8, 3, 227, 242, 8, 3, 227, 189, 8, 3, 227, 187, 8, 3, - 227, 188, 8, 3, 241, 148, 8, 3, 241, 147, 8, 3, 241, 153, 8, 3, 241, 149, - 8, 3, 241, 150, 8, 3, 241, 152, 8, 3, 241, 151, 8, 3, 241, 158, 8, 3, - 241, 157, 8, 3, 241, 160, 8, 3, 241, 159, 8, 3, 241, 140, 8, 3, 241, 142, - 8, 3, 241, 141, 8, 3, 241, 144, 8, 3, 241, 146, 8, 3, 241, 145, 8, 3, - 241, 154, 8, 3, 241, 156, 8, 3, 241, 155, 8, 3, 241, 136, 8, 3, 241, 135, - 8, 3, 241, 143, 8, 3, 241, 139, 8, 3, 241, 137, 8, 3, 241, 138, 8, 3, - 241, 130, 8, 3, 241, 129, 8, 3, 241, 134, 8, 3, 241, 133, 8, 3, 241, 131, - 8, 3, 241, 132, 8, 3, 232, 201, 8, 3, 232, 195, 8, 3, 232, 247, 8, 3, - 232, 208, 8, 3, 232, 239, 8, 3, 232, 238, 8, 3, 232, 242, 8, 3, 232, 240, - 8, 3, 233, 85, 8, 3, 233, 75, 8, 3, 233, 141, 8, 3, 233, 94, 8, 3, 232, - 84, 8, 3, 232, 83, 8, 3, 232, 86, 8, 3, 232, 85, 8, 3, 232, 122, 8, 3, - 232, 112, 8, 3, 232, 162, 8, 3, 232, 126, 8, 3, 233, 8, 8, 3, 233, 64, 8, - 3, 233, 23, 8, 3, 232, 79, 8, 3, 232, 77, 8, 3, 232, 103, 8, 3, 232, 82, - 8, 3, 232, 80, 8, 3, 232, 81, 8, 3, 232, 59, 8, 3, 232, 58, 8, 3, 232, - 67, 8, 3, 232, 62, 8, 3, 232, 60, 8, 3, 232, 61, 8, 3, 242, 196, 8, 3, - 242, 195, 8, 3, 242, 221, 8, 3, 242, 206, 8, 3, 242, 213, 8, 3, 242, 212, - 8, 3, 242, 215, 8, 3, 242, 214, 8, 3, 243, 96, 8, 3, 243, 91, 8, 3, 243, - 142, 8, 3, 243, 106, 8, 3, 242, 98, 8, 3, 242, 97, 8, 3, 242, 100, 8, 3, - 242, 99, 8, 3, 242, 161, 8, 3, 242, 159, 8, 3, 242, 181, 8, 3, 242, 169, - 8, 3, 243, 40, 8, 3, 243, 38, 8, 3, 243, 69, 8, 3, 243, 51, 8, 3, 242, - 88, 8, 3, 242, 87, 8, 3, 242, 120, 8, 3, 242, 96, 8, 3, 242, 89, 8, 3, - 242, 95, 8, 3, 234, 67, 8, 3, 234, 66, 8, 3, 234, 98, 8, 3, 234, 81, 8, - 3, 234, 91, 8, 3, 234, 94, 8, 3, 234, 92, 8, 3, 234, 208, 8, 3, 234, 196, - 8, 3, 176, 8, 3, 234, 234, 8, 3, 233, 206, 8, 3, 233, 211, 8, 3, 233, - 208, 8, 3, 234, 6, 8, 3, 234, 2, 8, 3, 234, 34, 8, 3, 234, 13, 8, 3, 234, - 162, 8, 3, 234, 146, 8, 3, 234, 188, 8, 3, 234, 165, 8, 3, 233, 195, 8, - 3, 233, 192, 8, 3, 233, 223, 8, 3, 233, 205, 8, 3, 233, 198, 8, 3, 233, - 202, 8, 3, 243, 22, 8, 3, 243, 21, 8, 3, 243, 26, 8, 3, 243, 23, 8, 3, - 243, 25, 8, 3, 243, 24, 8, 3, 243, 33, 8, 3, 243, 32, 8, 3, 243, 36, 8, - 3, 243, 34, 8, 3, 243, 13, 8, 3, 243, 12, 8, 3, 243, 15, 8, 3, 243, 14, - 8, 3, 243, 18, 8, 3, 243, 17, 8, 3, 243, 20, 8, 3, 243, 19, 8, 3, 243, - 28, 8, 3, 243, 27, 8, 3, 243, 31, 8, 3, 243, 29, 8, 3, 243, 8, 8, 3, 243, - 7, 8, 3, 243, 16, 8, 3, 243, 11, 8, 3, 243, 9, 8, 3, 243, 10, 8, 3, 230, - 254, 8, 3, 230, 255, 8, 3, 231, 17, 8, 3, 231, 16, 8, 3, 231, 19, 8, 3, - 231, 18, 8, 3, 230, 245, 8, 3, 230, 247, 8, 3, 230, 246, 8, 3, 230, 250, - 8, 3, 230, 249, 8, 3, 230, 252, 8, 3, 230, 251, 8, 3, 231, 0, 8, 3, 231, - 2, 8, 3, 231, 1, 8, 3, 230, 241, 8, 3, 230, 240, 8, 3, 230, 248, 8, 3, - 230, 244, 8, 3, 230, 242, 8, 3, 230, 243, 8, 3, 240, 187, 8, 3, 240, 186, - 8, 3, 240, 193, 8, 3, 240, 188, 8, 3, 240, 190, 8, 3, 240, 189, 8, 3, - 240, 192, 8, 3, 240, 191, 8, 3, 240, 198, 8, 3, 240, 197, 8, 3, 240, 200, - 8, 3, 240, 199, 8, 3, 240, 179, 8, 3, 240, 178, 8, 3, 240, 181, 8, 3, - 240, 180, 8, 3, 240, 183, 8, 3, 240, 182, 8, 3, 240, 185, 8, 3, 240, 184, - 8, 3, 240, 194, 8, 3, 240, 196, 8, 3, 240, 195, 8, 3, 229, 29, 8, 3, 229, - 31, 8, 3, 229, 30, 8, 3, 229, 72, 8, 3, 229, 70, 8, 3, 229, 82, 8, 3, - 229, 75, 8, 3, 228, 248, 8, 3, 228, 247, 8, 3, 228, 249, 8, 3, 229, 1, 8, - 3, 228, 254, 8, 3, 229, 9, 8, 3, 229, 3, 8, 3, 229, 63, 8, 3, 229, 69, 8, - 3, 229, 65, 8, 3, 241, 163, 8, 3, 241, 173, 8, 3, 241, 182, 8, 3, 242, 2, - 8, 3, 241, 250, 8, 3, 162, 8, 3, 242, 13, 8, 3, 240, 213, 8, 3, 240, 212, - 8, 3, 240, 215, 8, 3, 240, 214, 8, 3, 240, 249, 8, 3, 240, 240, 8, 3, - 241, 75, 8, 3, 241, 54, 8, 3, 241, 201, 8, 3, 241, 245, 8, 3, 241, 213, - 8, 3, 212, 43, 8, 3, 212, 28, 8, 3, 212, 65, 8, 3, 212, 51, 8, 3, 211, - 185, 8, 3, 211, 187, 8, 3, 211, 186, 8, 3, 211, 203, 8, 3, 211, 227, 8, - 3, 211, 210, 8, 3, 212, 5, 8, 3, 212, 22, 8, 3, 212, 10, 8, 3, 210, 30, - 8, 3, 210, 29, 8, 3, 210, 44, 8, 3, 210, 32, 8, 3, 210, 37, 8, 3, 210, - 39, 8, 3, 210, 38, 8, 3, 210, 102, 8, 3, 210, 99, 8, 3, 210, 116, 8, 3, - 210, 105, 8, 3, 210, 6, 8, 3, 210, 8, 8, 3, 210, 7, 8, 3, 210, 19, 8, 3, - 210, 18, 8, 3, 210, 23, 8, 3, 210, 20, 8, 3, 210, 84, 8, 3, 210, 94, 8, - 3, 210, 88, 8, 3, 210, 2, 8, 3, 210, 1, 8, 3, 210, 13, 8, 3, 210, 5, 8, - 3, 210, 3, 8, 3, 210, 4, 8, 3, 209, 245, 8, 3, 209, 244, 8, 3, 209, 250, - 8, 3, 209, 248, 8, 3, 209, 246, 8, 3, 209, 247, 8, 3, 250, 36, 8, 3, 250, - 32, 8, 3, 250, 59, 8, 3, 250, 45, 8, 3, 250, 56, 8, 3, 250, 50, 8, 3, - 250, 58, 8, 3, 250, 57, 8, 3, 250, 232, 8, 3, 250, 225, 8, 3, 251, 41, 8, - 3, 251, 3, 8, 3, 249, 112, 8, 3, 249, 114, 8, 3, 249, 113, 8, 3, 249, - 161, 8, 3, 249, 152, 8, 3, 249, 246, 8, 3, 249, 177, 8, 3, 250, 168, 8, - 3, 250, 198, 8, 3, 250, 173, 8, 3, 249, 92, 8, 3, 249, 90, 8, 3, 249, - 120, 8, 3, 249, 110, 8, 3, 249, 97, 8, 3, 249, 109, 8, 3, 249, 71, 8, 3, - 249, 70, 8, 3, 249, 81, 8, 3, 249, 77, 8, 3, 249, 72, 8, 3, 249, 74, 8, - 3, 209, 228, 8, 3, 209, 227, 8, 3, 209, 234, 8, 3, 209, 229, 8, 3, 209, - 231, 8, 3, 209, 230, 8, 3, 209, 233, 8, 3, 209, 232, 8, 3, 209, 240, 8, - 3, 209, 239, 8, 3, 209, 243, 8, 3, 209, 241, 8, 3, 209, 224, 8, 3, 209, - 226, 8, 3, 209, 225, 8, 3, 209, 235, 8, 3, 209, 238, 8, 3, 209, 236, 8, - 3, 209, 217, 8, 3, 209, 221, 8, 3, 209, 220, 8, 3, 209, 218, 8, 3, 209, - 219, 8, 3, 209, 211, 8, 3, 209, 210, 8, 3, 209, 216, 8, 3, 209, 214, 8, - 3, 209, 212, 8, 3, 209, 213, 8, 3, 227, 108, 8, 3, 227, 107, 8, 3, 227, - 113, 8, 3, 227, 109, 8, 3, 227, 110, 8, 3, 227, 112, 8, 3, 227, 111, 8, - 3, 227, 118, 8, 3, 227, 117, 8, 3, 227, 121, 8, 3, 227, 120, 8, 3, 227, - 101, 8, 3, 227, 102, 8, 3, 227, 105, 8, 3, 227, 106, 8, 3, 227, 114, 8, - 3, 227, 116, 8, 3, 227, 96, 8, 3, 227, 104, 8, 3, 227, 100, 8, 3, 227, - 97, 8, 3, 227, 98, 8, 3, 227, 91, 8, 3, 227, 90, 8, 3, 227, 95, 8, 3, - 227, 94, 8, 3, 227, 92, 8, 3, 227, 93, 8, 3, 219, 129, 8, 3, 195, 8, 3, - 219, 193, 8, 3, 219, 132, 8, 3, 219, 185, 8, 3, 219, 188, 8, 3, 219, 186, - 8, 3, 221, 228, 8, 3, 221, 216, 8, 3, 206, 8, 3, 221, 236, 8, 3, 218, 29, - 8, 3, 218, 31, 8, 3, 218, 30, 8, 3, 219, 36, 8, 3, 219, 25, 8, 3, 219, - 60, 8, 3, 219, 40, 8, 3, 220, 116, 8, 3, 221, 183, 8, 3, 220, 141, 8, 3, - 218, 6, 8, 3, 218, 4, 8, 3, 218, 84, 8, 3, 218, 28, 8, 3, 218, 10, 8, 3, - 218, 18, 8, 3, 217, 167, 8, 3, 217, 166, 8, 3, 217, 233, 8, 3, 217, 174, - 8, 3, 217, 169, 8, 3, 217, 173, 8, 3, 218, 188, 8, 3, 218, 187, 8, 3, - 218, 194, 8, 3, 218, 189, 8, 3, 218, 191, 8, 3, 218, 193, 8, 3, 218, 192, - 8, 3, 218, 202, 8, 3, 218, 200, 8, 3, 218, 225, 8, 3, 218, 203, 8, 3, - 218, 183, 8, 3, 218, 182, 8, 3, 218, 186, 8, 3, 218, 184, 8, 3, 218, 196, - 8, 3, 218, 199, 8, 3, 218, 197, 8, 3, 218, 179, 8, 3, 218, 177, 8, 3, - 218, 181, 8, 3, 218, 180, 8, 3, 218, 172, 8, 3, 218, 171, 8, 3, 218, 176, - 8, 3, 218, 175, 8, 3, 218, 173, 8, 3, 218, 174, 8, 3, 210, 77, 8, 3, 210, - 76, 8, 3, 210, 82, 8, 3, 210, 79, 8, 3, 210, 59, 8, 3, 210, 61, 8, 3, - 210, 60, 8, 3, 210, 64, 8, 3, 210, 63, 8, 3, 210, 67, 8, 3, 210, 65, 8, - 3, 210, 71, 8, 3, 210, 70, 8, 3, 210, 74, 8, 3, 210, 72, 8, 3, 210, 55, - 8, 3, 210, 54, 8, 3, 210, 62, 8, 3, 210, 58, 8, 3, 210, 56, 8, 3, 210, - 57, 8, 3, 210, 47, 8, 3, 210, 46, 8, 3, 210, 51, 8, 3, 210, 50, 8, 3, - 210, 48, 8, 3, 210, 49, 8, 3, 250, 144, 8, 3, 250, 141, 8, 3, 250, 165, - 8, 3, 250, 152, 8, 3, 250, 73, 8, 3, 250, 72, 8, 3, 250, 75, 8, 3, 250, - 74, 8, 3, 250, 87, 8, 3, 250, 86, 8, 3, 250, 94, 8, 3, 250, 89, 8, 3, - 250, 123, 8, 3, 250, 121, 8, 3, 250, 139, 8, 3, 250, 129, 8, 3, 250, 67, - 8, 3, 250, 77, 8, 3, 250, 71, 8, 3, 250, 68, 8, 3, 250, 70, 8, 3, 250, - 61, 8, 3, 250, 60, 8, 3, 250, 65, 8, 3, 250, 64, 8, 3, 250, 62, 8, 3, - 250, 63, 8, 3, 222, 177, 8, 3, 222, 181, 8, 3, 222, 160, 8, 3, 222, 161, - 8, 3, 222, 164, 8, 3, 222, 163, 8, 3, 222, 167, 8, 3, 222, 165, 8, 3, - 222, 171, 8, 3, 222, 170, 8, 3, 222, 176, 8, 3, 222, 172, 8, 3, 222, 156, - 8, 3, 222, 154, 8, 3, 222, 162, 8, 3, 222, 159, 8, 3, 222, 157, 8, 3, - 222, 158, 8, 3, 222, 149, 8, 3, 222, 148, 8, 3, 222, 153, 8, 3, 222, 152, - 8, 3, 222, 150, 8, 3, 222, 151, 8, 3, 228, 39, 8, 3, 228, 38, 8, 3, 228, - 41, 8, 3, 228, 40, 8, 3, 228, 31, 8, 3, 228, 33, 8, 3, 228, 32, 8, 3, - 228, 35, 8, 3, 228, 34, 8, 3, 228, 37, 8, 3, 228, 36, 8, 3, 228, 26, 8, - 3, 228, 25, 8, 3, 228, 30, 8, 3, 228, 29, 8, 3, 228, 27, 8, 3, 228, 28, - 8, 3, 228, 20, 8, 3, 228, 19, 8, 3, 228, 24, 8, 3, 228, 23, 8, 3, 228, - 21, 8, 3, 228, 22, 8, 3, 220, 74, 8, 3, 220, 69, 8, 3, 220, 104, 8, 3, - 220, 85, 8, 3, 219, 217, 8, 3, 219, 219, 8, 3, 219, 218, 8, 3, 219, 238, - 8, 3, 219, 235, 8, 3, 220, 9, 8, 3, 220, 0, 8, 3, 220, 44, 8, 3, 220, 37, - 8, 3, 220, 65, 8, 3, 220, 52, 8, 3, 219, 213, 8, 3, 219, 211, 8, 3, 219, - 227, 8, 3, 219, 216, 8, 3, 219, 214, 8, 3, 219, 215, 8, 3, 219, 196, 8, - 3, 219, 195, 8, 3, 219, 202, 8, 3, 219, 199, 8, 3, 219, 197, 8, 3, 219, - 198, 8, 3, 223, 144, 8, 3, 223, 138, 8, 3, 205, 8, 3, 223, 150, 8, 3, - 222, 122, 8, 3, 222, 124, 8, 3, 222, 123, 8, 3, 222, 190, 8, 3, 222, 183, - 8, 3, 222, 213, 8, 3, 222, 194, 8, 3, 223, 46, 8, 3, 223, 131, 8, 3, 223, - 84, 8, 3, 222, 115, 8, 3, 222, 112, 8, 3, 222, 142, 8, 3, 222, 121, 8, 3, - 222, 117, 8, 3, 222, 118, 8, 3, 222, 97, 8, 3, 222, 96, 8, 3, 222, 102, - 8, 3, 222, 100, 8, 3, 222, 98, 8, 3, 222, 99, 8, 3, 235, 104, 8, 3, 235, - 103, 8, 3, 235, 114, 8, 3, 235, 105, 8, 3, 235, 110, 8, 3, 235, 109, 8, - 3, 235, 112, 8, 3, 235, 111, 8, 3, 235, 47, 8, 3, 235, 46, 8, 3, 235, 49, - 8, 3, 235, 48, 8, 3, 235, 62, 8, 3, 235, 60, 8, 3, 235, 74, 8, 3, 235, - 64, 8, 3, 235, 40, 8, 3, 235, 38, 8, 3, 235, 57, 8, 3, 235, 45, 8, 3, - 235, 42, 8, 3, 235, 43, 8, 3, 235, 32, 8, 3, 235, 31, 8, 3, 235, 36, 8, - 3, 235, 35, 8, 3, 235, 33, 8, 3, 235, 34, 8, 3, 224, 49, 8, 3, 224, 47, - 8, 3, 224, 56, 8, 3, 224, 50, 8, 3, 224, 53, 8, 3, 224, 52, 8, 3, 224, - 55, 8, 3, 224, 54, 8, 3, 224, 2, 8, 3, 223, 255, 8, 3, 224, 4, 8, 3, 224, - 3, 8, 3, 224, 36, 8, 3, 224, 35, 8, 3, 224, 45, 8, 3, 224, 39, 8, 3, 223, - 250, 8, 3, 223, 246, 8, 3, 224, 33, 8, 3, 223, 254, 8, 3, 223, 252, 8, 3, - 223, 253, 8, 3, 223, 230, 8, 3, 223, 228, 8, 3, 223, 240, 8, 3, 223, 233, - 8, 3, 223, 231, 8, 3, 223, 232, 8, 3, 235, 93, 8, 3, 235, 92, 8, 3, 235, - 99, 8, 3, 235, 94, 8, 3, 235, 96, 8, 3, 235, 95, 8, 3, 235, 98, 8, 3, - 235, 97, 8, 3, 235, 84, 8, 3, 235, 86, 8, 3, 235, 85, 8, 3, 235, 89, 8, - 3, 235, 88, 8, 3, 235, 91, 8, 3, 235, 90, 8, 3, 235, 80, 8, 3, 235, 79, - 8, 3, 235, 87, 8, 3, 235, 83, 8, 3, 235, 81, 8, 3, 235, 82, 8, 3, 235, - 76, 8, 3, 235, 75, 8, 3, 235, 78, 8, 3, 235, 77, 8, 3, 228, 167, 8, 3, - 228, 166, 8, 3, 228, 174, 8, 3, 228, 168, 8, 3, 228, 170, 8, 3, 228, 169, - 8, 3, 228, 173, 8, 3, 228, 171, 8, 3, 228, 156, 8, 3, 228, 157, 8, 3, - 228, 162, 8, 3, 228, 161, 8, 3, 228, 165, 8, 3, 228, 163, 8, 3, 228, 151, - 8, 3, 228, 160, 8, 3, 228, 155, 8, 3, 228, 152, 8, 3, 228, 153, 8, 3, - 228, 146, 8, 3, 228, 145, 8, 3, 228, 150, 8, 3, 228, 149, 8, 3, 228, 147, - 8, 3, 228, 148, 8, 3, 227, 141, 8, 3, 227, 140, 8, 3, 227, 152, 8, 3, - 227, 145, 8, 3, 227, 149, 8, 3, 227, 148, 8, 3, 227, 151, 8, 3, 227, 150, - 8, 3, 227, 128, 8, 3, 227, 130, 8, 3, 227, 129, 8, 3, 227, 134, 8, 3, - 227, 133, 8, 3, 227, 138, 8, 3, 227, 135, 8, 3, 227, 126, 8, 3, 227, 124, - 8, 3, 227, 132, 8, 3, 227, 127, 8, 3, 211, 150, 8, 3, 211, 149, 8, 3, - 211, 157, 8, 3, 211, 152, 8, 3, 211, 154, 8, 3, 211, 153, 8, 3, 211, 156, - 8, 3, 211, 155, 8, 3, 211, 139, 8, 3, 211, 140, 8, 3, 211, 144, 8, 3, - 211, 143, 8, 3, 211, 148, 8, 3, 211, 146, 8, 3, 211, 121, 8, 3, 211, 119, - 8, 3, 211, 131, 8, 3, 211, 124, 8, 3, 211, 122, 8, 3, 211, 123, 8, 3, - 210, 250, 8, 3, 210, 248, 8, 3, 211, 8, 8, 3, 210, 251, 8, 3, 211, 2, 8, - 3, 211, 1, 8, 3, 211, 5, 8, 3, 211, 3, 8, 3, 210, 191, 8, 3, 210, 190, 8, - 3, 210, 194, 8, 3, 210, 192, 8, 3, 210, 224, 8, 3, 210, 221, 8, 3, 210, - 244, 8, 3, 210, 228, 8, 3, 210, 182, 8, 3, 210, 178, 8, 3, 210, 212, 8, - 3, 210, 189, 8, 3, 210, 185, 8, 3, 210, 186, 8, 3, 210, 162, 8, 3, 210, - 161, 8, 3, 210, 169, 8, 3, 210, 165, 8, 3, 210, 163, 8, 3, 210, 164, 8, - 34, 224, 36, 8, 34, 232, 247, 8, 34, 234, 67, 8, 34, 227, 145, 8, 34, - 249, 77, 8, 34, 218, 194, 8, 34, 243, 19, 8, 34, 243, 51, 8, 34, 230, - 235, 8, 34, 240, 187, 8, 34, 232, 61, 8, 34, 252, 91, 8, 34, 230, 131, 8, - 34, 210, 244, 8, 34, 224, 124, 8, 34, 240, 181, 8, 34, 217, 47, 8, 34, - 243, 142, 8, 34, 210, 5, 8, 34, 249, 71, 8, 34, 248, 103, 8, 34, 251, - 106, 8, 34, 243, 15, 8, 34, 227, 135, 8, 34, 215, 119, 8, 34, 226, 179, - 8, 34, 235, 80, 8, 34, 210, 19, 8, 34, 224, 103, 8, 34, 241, 115, 8, 34, - 210, 250, 8, 34, 212, 112, 8, 34, 219, 202, 8, 34, 213, 244, 8, 34, 210, - 116, 8, 34, 235, 74, 8, 34, 227, 100, 8, 34, 235, 78, 8, 34, 242, 161, 8, - 34, 235, 98, 8, 34, 211, 227, 8, 34, 246, 86, 8, 34, 219, 215, 8, 34, - 232, 242, 8, 34, 249, 81, 8, 34, 249, 113, 8, 34, 250, 45, 8, 34, 240, - 184, 8, 34, 220, 74, 8, 34, 210, 4, 8, 34, 220, 0, 8, 34, 250, 139, 8, - 34, 209, 231, 8, 34, 229, 178, 8, 34, 234, 188, 232, 202, 1, 252, 199, - 232, 202, 1, 191, 232, 202, 1, 225, 150, 232, 202, 1, 248, 229, 232, 202, - 1, 217, 106, 232, 202, 1, 216, 209, 232, 202, 1, 243, 142, 232, 202, 1, - 176, 232, 202, 1, 234, 138, 232, 202, 1, 235, 147, 232, 202, 1, 251, 41, - 232, 202, 1, 250, 165, 232, 202, 1, 246, 46, 232, 202, 1, 215, 184, 232, - 202, 1, 215, 176, 232, 202, 1, 186, 232, 202, 1, 198, 232, 202, 1, 233, - 141, 232, 202, 1, 206, 232, 202, 1, 210, 82, 232, 202, 1, 210, 116, 232, - 202, 1, 229, 82, 232, 202, 1, 162, 232, 202, 1, 211, 165, 232, 202, 1, - 241, 196, 232, 202, 1, 244, 204, 232, 202, 1, 212, 65, 232, 202, 1, 220, - 104, 232, 202, 1, 192, 232, 202, 1, 243, 0, 232, 202, 1, 61, 232, 202, 1, - 254, 252, 232, 202, 1, 76, 232, 202, 1, 245, 63, 232, 202, 1, 74, 232, - 202, 1, 78, 232, 202, 1, 69, 232, 202, 1, 214, 214, 232, 202, 1, 214, - 208, 232, 202, 1, 226, 238, 232, 202, 1, 138, 230, 37, 216, 118, 232, - 202, 1, 138, 229, 234, 225, 19, 232, 202, 1, 138, 230, 37, 249, 80, 232, - 202, 1, 138, 230, 37, 251, 213, 232, 202, 1, 138, 230, 37, 198, 232, 202, - 1, 138, 230, 37, 235, 121, 232, 202, 224, 144, 249, 227, 232, 202, 224, - 144, 243, 236, 218, 131, 41, 3, 245, 217, 41, 3, 245, 213, 41, 3, 241, - 227, 41, 3, 212, 17, 41, 3, 212, 16, 41, 3, 225, 214, 41, 3, 252, 21, 41, - 3, 252, 74, 41, 3, 231, 121, 41, 3, 233, 253, 41, 3, 231, 11, 41, 3, 243, - 82, 41, 3, 244, 155, 41, 3, 213, 250, 41, 3, 217, 12, 41, 3, 216, 195, - 41, 3, 248, 24, 41, 3, 248, 21, 41, 3, 233, 56, 41, 3, 223, 111, 41, 3, - 248, 85, 41, 3, 229, 144, 41, 3, 221, 172, 41, 3, 220, 63, 41, 3, 210, - 92, 41, 3, 210, 73, 41, 3, 250, 190, 41, 3, 235, 130, 41, 3, 228, 181, - 41, 3, 211, 44, 41, 3, 234, 187, 41, 3, 229, 56, 41, 3, 243, 62, 41, 3, - 231, 85, 41, 3, 229, 108, 41, 3, 227, 159, 41, 3, 74, 41, 3, 236, 6, 41, - 3, 241, 187, 41, 3, 241, 167, 41, 3, 211, 250, 41, 3, 211, 241, 41, 3, - 225, 111, 41, 3, 252, 19, 41, 3, 252, 14, 41, 3, 231, 114, 41, 3, 233, - 250, 41, 3, 231, 8, 41, 3, 243, 78, 41, 3, 244, 129, 41, 3, 213, 176, 41, - 3, 216, 118, 41, 3, 216, 176, 41, 3, 248, 16, 41, 3, 248, 20, 41, 3, 232, - 247, 41, 3, 223, 38, 41, 3, 248, 11, 41, 3, 229, 138, 41, 3, 219, 193, - 41, 3, 220, 34, 41, 3, 210, 44, 41, 3, 210, 69, 41, 3, 250, 59, 41, 3, - 235, 114, 41, 3, 228, 174, 41, 3, 211, 8, 41, 3, 234, 98, 41, 3, 229, 48, - 41, 3, 242, 221, 41, 3, 230, 235, 41, 3, 228, 238, 41, 3, 227, 152, 41, - 3, 61, 41, 3, 254, 131, 41, 3, 229, 77, 41, 3, 162, 41, 3, 242, 25, 41, - 3, 212, 65, 41, 3, 212, 55, 41, 3, 191, 41, 3, 252, 26, 41, 3, 252, 199, - 41, 3, 231, 129, 41, 3, 234, 1, 41, 3, 234, 0, 41, 3, 231, 15, 41, 3, - 243, 86, 41, 3, 244, 204, 41, 3, 214, 27, 41, 3, 217, 106, 41, 3, 216, - 209, 41, 3, 248, 33, 41, 3, 248, 23, 41, 3, 233, 141, 41, 3, 205, 41, 3, - 248, 229, 41, 3, 229, 153, 41, 3, 206, 41, 3, 220, 104, 41, 3, 210, 116, - 41, 3, 210, 82, 41, 3, 251, 41, 41, 3, 235, 147, 41, 3, 228, 190, 41, 3, - 192, 41, 3, 176, 41, 3, 234, 240, 41, 3, 229, 61, 41, 3, 243, 142, 41, 3, - 186, 41, 3, 198, 41, 3, 227, 169, 41, 3, 226, 187, 41, 3, 226, 183, 41, - 3, 241, 60, 41, 3, 211, 215, 41, 3, 211, 211, 41, 3, 224, 252, 41, 3, - 252, 17, 41, 3, 251, 201, 41, 3, 231, 109, 41, 3, 233, 248, 41, 3, 231, - 4, 41, 3, 243, 74, 41, 3, 244, 42, 41, 3, 213, 127, 41, 3, 216, 18, 41, - 3, 216, 154, 41, 3, 248, 14, 41, 3, 248, 18, 41, 3, 232, 133, 41, 3, 222, - 199, 41, 3, 247, 133, 41, 3, 229, 125, 41, 3, 219, 42, 41, 3, 220, 3, 41, - 3, 210, 21, 41, 3, 210, 66, 41, 3, 249, 182, 41, 3, 235, 65, 41, 3, 228, - 164, 41, 3, 210, 229, 41, 3, 234, 16, 41, 3, 229, 46, 41, 3, 242, 171, - 41, 3, 230, 137, 41, 3, 228, 69, 41, 3, 227, 136, 41, 3, 69, 41, 3, 214, - 190, 41, 3, 240, 229, 41, 3, 240, 219, 41, 3, 211, 195, 41, 3, 211, 189, - 41, 3, 224, 153, 41, 3, 252, 16, 41, 3, 251, 133, 41, 3, 231, 108, 41, 3, - 233, 246, 41, 3, 231, 3, 41, 3, 243, 73, 41, 3, 243, 241, 41, 3, 212, - 116, 41, 3, 215, 119, 41, 3, 216, 137, 41, 3, 248, 12, 41, 3, 248, 17, - 41, 3, 232, 103, 41, 3, 222, 142, 41, 3, 246, 86, 41, 3, 229, 120, 41, 3, - 218, 84, 41, 3, 219, 227, 41, 3, 210, 13, 41, 3, 210, 62, 41, 3, 249, - 120, 41, 3, 235, 57, 41, 3, 228, 160, 41, 3, 210, 212, 41, 3, 233, 223, - 41, 3, 229, 45, 41, 3, 242, 120, 41, 3, 230, 107, 41, 3, 227, 242, 41, 3, - 227, 132, 41, 3, 78, 41, 3, 226, 200, 41, 3, 229, 5, 41, 3, 241, 75, 41, - 3, 241, 63, 41, 3, 211, 227, 41, 3, 211, 216, 41, 3, 225, 19, 41, 3, 252, - 18, 41, 3, 251, 213, 41, 3, 231, 110, 41, 3, 233, 249, 41, 3, 231, 6, 41, - 3, 243, 76, 41, 3, 243, 75, 41, 3, 244, 51, 41, 3, 213, 138, 41, 3, 112, - 41, 3, 216, 157, 41, 3, 248, 15, 41, 3, 248, 19, 41, 3, 232, 162, 41, 3, - 222, 213, 41, 3, 247, 153, 41, 3, 229, 129, 41, 3, 219, 60, 41, 3, 220, - 9, 41, 3, 210, 23, 41, 3, 210, 67, 41, 3, 249, 246, 41, 3, 235, 74, 41, - 3, 228, 165, 41, 3, 210, 244, 41, 3, 234, 34, 41, 3, 229, 47, 41, 3, 242, - 181, 41, 3, 230, 166, 41, 3, 228, 79, 41, 3, 227, 138, 41, 3, 76, 41, 3, - 245, 158, 41, 3, 229, 66, 41, 3, 241, 245, 41, 3, 241, 216, 41, 3, 212, - 22, 41, 3, 212, 12, 41, 3, 225, 224, 41, 3, 252, 22, 41, 3, 252, 83, 41, - 3, 231, 122, 41, 3, 233, 254, 41, 3, 233, 252, 41, 3, 231, 12, 41, 3, - 243, 83, 41, 3, 243, 81, 41, 3, 244, 162, 41, 3, 213, 255, 41, 3, 217, - 23, 41, 3, 216, 196, 41, 3, 248, 25, 41, 3, 248, 22, 41, 3, 233, 64, 41, - 3, 223, 131, 41, 3, 248, 98, 41, 3, 229, 145, 41, 3, 221, 183, 41, 3, - 220, 65, 41, 3, 210, 94, 41, 3, 210, 74, 41, 3, 250, 198, 41, 3, 235, - 132, 41, 3, 228, 183, 41, 3, 211, 47, 41, 3, 234, 188, 41, 3, 229, 57, - 41, 3, 229, 53, 41, 3, 243, 69, 41, 3, 243, 58, 41, 3, 231, 96, 41, 3, - 229, 112, 41, 3, 227, 160, 41, 3, 229, 84, 41, 3, 233, 28, 41, 249, 227, - 41, 243, 236, 218, 131, 41, 224, 16, 79, 41, 3, 229, 128, 244, 204, 41, - 3, 229, 128, 176, 41, 3, 229, 128, 219, 42, 41, 16, 244, 152, 41, 16, - 234, 186, 41, 16, 216, 82, 41, 16, 228, 213, 41, 16, 252, 155, 41, 16, - 244, 203, 41, 16, 217, 102, 41, 16, 248, 184, 41, 16, 247, 132, 41, 16, - 233, 212, 41, 16, 216, 22, 41, 16, 247, 152, 41, 16, 235, 66, 41, 21, - 210, 86, 41, 21, 111, 41, 21, 105, 41, 21, 158, 41, 21, 161, 41, 21, 190, - 41, 21, 195, 41, 21, 199, 41, 21, 196, 41, 21, 201, 41, 3, 229, 128, 186, - 41, 3, 229, 128, 247, 153, 33, 6, 1, 210, 90, 33, 4, 1, 210, 90, 33, 6, - 1, 246, 42, 33, 4, 1, 246, 42, 33, 6, 1, 223, 52, 246, 44, 33, 4, 1, 223, - 52, 246, 44, 33, 6, 1, 235, 192, 33, 4, 1, 235, 192, 33, 6, 1, 247, 169, - 33, 4, 1, 247, 169, 33, 6, 1, 230, 145, 214, 205, 33, 4, 1, 230, 145, - 214, 205, 33, 6, 1, 251, 144, 226, 205, 33, 4, 1, 251, 144, 226, 205, 33, - 6, 1, 229, 92, 211, 31, 33, 4, 1, 229, 92, 211, 31, 33, 6, 1, 211, 28, 2, - 252, 193, 211, 31, 33, 4, 1, 211, 28, 2, 252, 193, 211, 31, 33, 6, 1, - 235, 190, 211, 59, 33, 4, 1, 235, 190, 211, 59, 33, 6, 1, 223, 52, 210, - 212, 33, 4, 1, 223, 52, 210, 212, 33, 6, 1, 235, 190, 61, 33, 4, 1, 235, - 190, 61, 33, 6, 1, 250, 8, 232, 198, 210, 183, 33, 4, 1, 250, 8, 232, - 198, 210, 183, 33, 6, 1, 251, 222, 210, 183, 33, 4, 1, 251, 222, 210, - 183, 33, 6, 1, 235, 190, 250, 8, 232, 198, 210, 183, 33, 4, 1, 235, 190, - 250, 8, 232, 198, 210, 183, 33, 6, 1, 210, 246, 33, 4, 1, 210, 246, 33, - 6, 1, 223, 52, 215, 179, 33, 4, 1, 223, 52, 215, 179, 33, 6, 1, 219, 54, - 248, 98, 33, 4, 1, 219, 54, 248, 98, 33, 6, 1, 219, 54, 245, 182, 33, 4, - 1, 219, 54, 245, 182, 33, 6, 1, 219, 54, 245, 167, 33, 4, 1, 219, 54, - 245, 167, 33, 6, 1, 230, 149, 78, 33, 4, 1, 230, 149, 78, 33, 6, 1, 251, - 248, 78, 33, 4, 1, 251, 248, 78, 33, 6, 1, 52, 230, 149, 78, 33, 4, 1, - 52, 230, 149, 78, 33, 1, 230, 91, 78, 38, 33, 212, 100, 38, 33, 216, 249, - 230, 196, 50, 38, 33, 240, 218, 230, 196, 50, 38, 33, 216, 149, 230, 196, - 50, 219, 95, 253, 224, 38, 33, 1, 214, 202, 236, 67, 38, 33, 1, 74, 38, - 33, 1, 211, 8, 38, 33, 1, 69, 38, 33, 1, 242, 10, 50, 38, 33, 1, 211, 27, - 38, 33, 1, 219, 54, 50, 38, 33, 1, 226, 205, 38, 33, 234, 198, 38, 33, - 225, 231, 33, 234, 198, 33, 225, 231, 33, 6, 1, 246, 54, 33, 4, 1, 246, - 54, 33, 6, 1, 246, 35, 33, 4, 1, 246, 35, 33, 6, 1, 210, 52, 33, 4, 1, - 210, 52, 33, 6, 1, 250, 214, 33, 4, 1, 250, 214, 33, 6, 1, 246, 33, 33, - 4, 1, 246, 33, 33, 6, 1, 217, 24, 2, 230, 229, 103, 33, 4, 1, 217, 24, 2, - 230, 229, 103, 33, 6, 1, 215, 78, 33, 4, 1, 215, 78, 33, 6, 1, 215, 161, - 33, 4, 1, 215, 161, 33, 6, 1, 215, 165, 33, 4, 1, 215, 165, 33, 6, 1, - 217, 29, 33, 4, 1, 217, 29, 33, 6, 1, 240, 205, 33, 4, 1, 240, 205, 33, - 6, 1, 219, 208, 33, 4, 1, 219, 208, 38, 33, 1, 235, 190, 76, 20, 1, 61, - 20, 1, 176, 20, 1, 69, 20, 1, 233, 223, 20, 1, 245, 217, 20, 1, 223, 111, - 20, 1, 217, 87, 20, 1, 78, 20, 1, 227, 152, 20, 1, 74, 20, 1, 233, 141, - 20, 1, 191, 20, 1, 222, 242, 20, 1, 223, 32, 20, 1, 233, 55, 20, 1, 231, - 84, 20, 1, 217, 102, 20, 1, 229, 151, 20, 1, 228, 188, 20, 1, 194, 20, 1, - 218, 5, 20, 1, 230, 107, 20, 1, 220, 29, 20, 1, 219, 193, 20, 1, 220, 39, - 20, 1, 220, 125, 20, 1, 233, 161, 20, 1, 234, 162, 20, 1, 227, 213, 20, - 1, 227, 242, 20, 1, 228, 159, 20, 1, 210, 226, 20, 1, 219, 227, 20, 1, - 210, 187, 20, 1, 192, 20, 1, 228, 14, 20, 1, 234, 148, 20, 1, 225, 154, - 20, 1, 228, 181, 20, 1, 227, 251, 20, 1, 224, 147, 20, 1, 211, 192, 20, - 1, 225, 214, 20, 1, 244, 155, 20, 1, 222, 142, 20, 1, 232, 103, 20, 1, - 230, 235, 20, 1, 228, 238, 20, 1, 223, 54, 20, 1, 223, 174, 20, 1, 234, - 171, 20, 1, 229, 12, 20, 1, 229, 61, 20, 1, 229, 82, 20, 1, 220, 9, 20, - 1, 224, 150, 20, 1, 243, 241, 20, 1, 244, 45, 20, 1, 212, 65, 20, 1, 198, - 20, 1, 232, 247, 20, 1, 225, 111, 20, 1, 232, 125, 20, 1, 234, 34, 20, 1, - 231, 119, 20, 1, 223, 86, 20, 1, 231, 63, 20, 1, 186, 20, 1, 216, 118, - 20, 1, 234, 98, 20, 1, 230, 166, 20, 1, 231, 127, 20, 1, 216, 231, 20, 1, - 234, 1, 20, 1, 216, 248, 20, 1, 227, 243, 20, 1, 221, 253, 20, 1, 244, - 200, 20, 1, 234, 3, 20, 1, 234, 30, 20, 38, 164, 234, 11, 20, 38, 164, - 215, 111, 20, 228, 187, 20, 243, 236, 218, 131, 20, 249, 234, 20, 249, - 227, 20, 220, 152, 20, 224, 16, 79, 58, 1, 250, 104, 138, 210, 254, 225, - 64, 58, 1, 250, 104, 138, 211, 70, 225, 64, 58, 1, 250, 104, 138, 210, - 254, 220, 86, 58, 1, 250, 104, 138, 211, 70, 220, 86, 58, 1, 250, 104, - 138, 210, 254, 224, 33, 58, 1, 250, 104, 138, 211, 70, 224, 33, 58, 1, - 250, 104, 138, 210, 254, 222, 142, 58, 1, 250, 104, 138, 211, 70, 222, - 142, 58, 1, 245, 28, 246, 126, 138, 130, 58, 1, 125, 246, 126, 138, 130, - 58, 1, 230, 230, 246, 126, 138, 130, 58, 1, 121, 246, 126, 138, 130, 58, - 1, 245, 27, 246, 126, 138, 130, 58, 1, 245, 28, 246, 126, 233, 45, 138, - 130, 58, 1, 125, 246, 126, 233, 45, 138, 130, 58, 1, 230, 230, 246, 126, - 233, 45, 138, 130, 58, 1, 121, 246, 126, 233, 45, 138, 130, 58, 1, 245, - 27, 246, 126, 233, 45, 138, 130, 58, 1, 245, 28, 233, 45, 138, 130, 58, - 1, 125, 233, 45, 138, 130, 58, 1, 230, 230, 233, 45, 138, 130, 58, 1, - 121, 233, 45, 138, 130, 58, 1, 245, 27, 233, 45, 138, 130, 58, 1, 59, 67, - 130, 58, 1, 59, 219, 97, 58, 1, 59, 203, 130, 58, 1, 232, 114, 44, 249, - 169, 254, 117, 58, 1, 223, 160, 120, 75, 58, 1, 223, 160, 124, 75, 58, 1, - 223, 160, 245, 39, 79, 58, 1, 223, 160, 235, 200, 245, 39, 79, 58, 1, - 121, 235, 200, 245, 39, 79, 58, 1, 218, 113, 22, 125, 216, 31, 58, 1, - 218, 113, 22, 121, 216, 31, 7, 6, 1, 245, 207, 254, 179, 7, 4, 1, 245, - 207, 254, 179, 7, 6, 1, 245, 207, 254, 205, 7, 4, 1, 245, 207, 254, 205, - 7, 6, 1, 241, 214, 7, 4, 1, 241, 214, 7, 6, 1, 215, 40, 7, 4, 1, 215, 40, - 7, 6, 1, 215, 230, 7, 4, 1, 215, 230, 7, 6, 1, 249, 118, 7, 4, 1, 249, - 118, 7, 6, 1, 249, 119, 2, 249, 227, 7, 4, 1, 249, 119, 2, 249, 227, 7, - 1, 4, 6, 245, 14, 7, 1, 4, 6, 222, 93, 7, 6, 1, 255, 82, 7, 4, 1, 255, - 82, 7, 6, 1, 254, 81, 7, 4, 1, 254, 81, 7, 6, 1, 253, 200, 7, 4, 1, 253, - 200, 7, 6, 1, 253, 184, 7, 4, 1, 253, 184, 7, 6, 1, 253, 185, 2, 203, - 130, 7, 4, 1, 253, 185, 2, 203, 130, 7, 6, 1, 253, 175, 7, 4, 1, 253, - 175, 7, 6, 1, 223, 52, 251, 75, 2, 247, 128, 7, 4, 1, 223, 52, 251, 75, - 2, 247, 128, 7, 6, 1, 235, 30, 2, 91, 7, 4, 1, 235, 30, 2, 91, 7, 6, 1, - 235, 30, 2, 248, 7, 91, 7, 4, 1, 235, 30, 2, 248, 7, 91, 7, 6, 1, 235, - 30, 2, 218, 105, 22, 248, 7, 91, 7, 4, 1, 235, 30, 2, 218, 105, 22, 248, - 7, 91, 7, 6, 1, 251, 143, 156, 7, 4, 1, 251, 143, 156, 7, 6, 1, 233, 155, - 2, 125, 91, 7, 4, 1, 233, 155, 2, 125, 91, 7, 6, 1, 144, 2, 200, 218, - 105, 226, 124, 7, 4, 1, 144, 2, 200, 218, 105, 226, 124, 7, 6, 1, 144, 2, - 232, 129, 7, 4, 1, 144, 2, 232, 129, 7, 6, 1, 226, 187, 7, 4, 1, 226, - 187, 7, 6, 1, 226, 110, 2, 218, 105, 216, 140, 248, 47, 7, 4, 1, 226, - 110, 2, 218, 105, 216, 140, 248, 47, 7, 6, 1, 226, 110, 2, 244, 61, 7, 4, - 1, 226, 110, 2, 244, 61, 7, 6, 1, 226, 110, 2, 218, 231, 217, 78, 7, 4, - 1, 226, 110, 2, 218, 231, 217, 78, 7, 6, 1, 224, 100, 2, 218, 105, 216, - 140, 248, 47, 7, 4, 1, 224, 100, 2, 218, 105, 216, 140, 248, 47, 7, 6, 1, - 224, 100, 2, 248, 7, 91, 7, 4, 1, 224, 100, 2, 248, 7, 91, 7, 6, 1, 223, - 227, 222, 188, 7, 4, 1, 223, 227, 222, 188, 7, 6, 1, 222, 132, 222, 188, - 7, 4, 1, 222, 132, 222, 188, 7, 6, 1, 214, 106, 2, 248, 7, 91, 7, 4, 1, - 214, 106, 2, 248, 7, 91, 7, 6, 1, 212, 106, 7, 4, 1, 212, 106, 7, 6, 1, - 213, 145, 210, 159, 7, 4, 1, 213, 145, 210, 159, 7, 6, 1, 216, 153, 2, - 91, 7, 4, 1, 216, 153, 2, 91, 7, 6, 1, 216, 153, 2, 218, 105, 216, 140, - 248, 47, 7, 4, 1, 216, 153, 2, 218, 105, 216, 140, 248, 47, 7, 6, 1, 213, - 245, 7, 4, 1, 213, 245, 7, 6, 1, 245, 73, 7, 4, 1, 245, 73, 7, 6, 1, 235, - 178, 7, 4, 1, 235, 178, 7, 6, 1, 249, 215, 7, 4, 1, 249, 215, 58, 1, 214, - 133, 7, 4, 1, 246, 77, 7, 4, 1, 232, 89, 7, 4, 1, 230, 85, 7, 4, 1, 227, - 205, 7, 4, 1, 222, 131, 7, 1, 4, 6, 222, 131, 7, 4, 1, 215, 109, 7, 4, 1, - 214, 197, 7, 6, 1, 235, 220, 249, 68, 7, 4, 1, 235, 220, 249, 68, 7, 6, - 1, 235, 220, 245, 14, 7, 4, 1, 235, 220, 245, 14, 7, 6, 1, 235, 220, 243, - 209, 7, 6, 1, 215, 94, 235, 220, 243, 209, 7, 4, 1, 215, 94, 235, 220, - 243, 209, 7, 6, 1, 215, 94, 156, 7, 4, 1, 215, 94, 156, 7, 6, 1, 235, - 220, 153, 7, 4, 1, 235, 220, 153, 7, 6, 1, 235, 220, 222, 93, 7, 4, 1, - 235, 220, 222, 93, 7, 6, 1, 235, 220, 217, 153, 7, 4, 1, 235, 220, 217, - 153, 58, 1, 121, 250, 39, 255, 23, 58, 1, 249, 234, 58, 1, 219, 253, 245, - 106, 50, 7, 6, 1, 222, 1, 7, 4, 1, 222, 1, 7, 6, 1, 215, 94, 242, 67, 7, - 4, 1, 233, 155, 2, 223, 58, 241, 59, 22, 252, 49, 7, 6, 1, 230, 31, 2, - 248, 47, 7, 4, 1, 230, 31, 2, 248, 47, 7, 6, 1, 251, 75, 2, 130, 7, 4, 1, - 251, 75, 2, 130, 7, 6, 1, 243, 210, 2, 226, 252, 91, 7, 4, 1, 243, 210, - 2, 226, 252, 91, 7, 6, 1, 235, 30, 2, 226, 252, 91, 7, 4, 1, 235, 30, 2, - 226, 252, 91, 7, 6, 1, 230, 31, 2, 226, 252, 91, 7, 4, 1, 230, 31, 2, - 226, 252, 91, 7, 6, 1, 223, 227, 2, 226, 252, 91, 7, 4, 1, 223, 227, 2, - 226, 252, 91, 7, 6, 1, 222, 94, 2, 226, 252, 91, 7, 4, 1, 222, 94, 2, - 226, 252, 91, 7, 6, 1, 242, 68, 2, 103, 58, 1, 6, 242, 68, 2, 91, 58, 1, - 4, 27, 226, 238, 7, 1, 4, 6, 215, 94, 194, 7, 245, 111, 1, 223, 52, 245, - 14, 7, 245, 111, 1, 223, 52, 226, 109, 7, 245, 111, 1, 235, 200, 194, 7, - 245, 111, 1, 240, 161, 232, 135, 7, 245, 111, 1, 254, 31, 194, 217, 231, - 229, 219, 1, 61, 217, 231, 229, 219, 1, 74, 217, 231, 229, 219, 5, 246, - 56, 217, 231, 229, 219, 1, 69, 217, 231, 229, 219, 1, 76, 217, 231, 229, - 219, 1, 78, 217, 231, 229, 219, 5, 242, 4, 217, 231, 229, 219, 1, 234, - 34, 217, 231, 229, 219, 1, 234, 111, 217, 231, 229, 219, 1, 242, 181, - 217, 231, 229, 219, 1, 242, 231, 217, 231, 229, 219, 5, 254, 83, 217, - 231, 229, 219, 1, 249, 246, 217, 231, 229, 219, 1, 250, 94, 217, 231, - 229, 219, 1, 235, 74, 217, 231, 229, 219, 1, 235, 115, 217, 231, 229, - 219, 1, 215, 134, 217, 231, 229, 219, 1, 215, 140, 217, 231, 229, 219, 1, - 248, 113, 217, 231, 229, 219, 1, 248, 122, 217, 231, 229, 219, 1, 112, - 217, 231, 229, 219, 1, 216, 157, 217, 231, 229, 219, 1, 247, 153, 217, - 231, 229, 219, 1, 248, 15, 217, 231, 229, 219, 1, 228, 79, 217, 231, 229, - 219, 1, 225, 19, 217, 231, 229, 219, 1, 225, 124, 217, 231, 229, 219, 1, - 251, 213, 217, 231, 229, 219, 1, 252, 18, 217, 231, 229, 219, 1, 230, - 166, 217, 231, 229, 219, 1, 222, 213, 217, 231, 229, 219, 1, 232, 162, - 217, 231, 229, 219, 1, 222, 167, 217, 231, 229, 219, 1, 219, 60, 217, - 231, 229, 219, 1, 241, 75, 217, 231, 229, 219, 25, 5, 61, 217, 231, 229, - 219, 25, 5, 74, 217, 231, 229, 219, 25, 5, 69, 217, 231, 229, 219, 25, 5, - 76, 217, 231, 229, 219, 25, 5, 226, 187, 217, 231, 229, 219, 225, 15, - 231, 163, 217, 231, 229, 219, 225, 15, 231, 162, 217, 231, 229, 219, 225, - 15, 231, 161, 217, 231, 229, 219, 225, 15, 231, 160, 228, 61, 235, 247, - 244, 10, 123, 224, 24, 228, 61, 235, 247, 244, 10, 123, 242, 34, 228, 61, - 235, 247, 244, 10, 134, 224, 22, 228, 61, 235, 247, 244, 10, 123, 219, - 119, 228, 61, 235, 247, 244, 10, 123, 245, 196, 228, 61, 235, 247, 244, - 10, 134, 219, 118, 228, 61, 235, 247, 224, 25, 79, 228, 61, 235, 247, - 225, 43, 79, 228, 61, 235, 247, 222, 120, 79, 228, 61, 235, 247, 224, 26, - 79, 225, 147, 1, 176, 225, 147, 1, 234, 138, 225, 147, 1, 243, 142, 225, - 147, 1, 229, 82, 225, 147, 1, 251, 41, 225, 147, 1, 250, 165, 225, 147, - 1, 235, 147, 225, 147, 1, 227, 169, 225, 147, 1, 217, 106, 225, 147, 1, - 216, 209, 225, 147, 1, 248, 229, 225, 147, 1, 198, 225, 147, 1, 191, 225, - 147, 1, 225, 150, 225, 147, 1, 252, 199, 225, 147, 1, 186, 225, 147, 1, - 215, 184, 225, 147, 1, 215, 176, 225, 147, 1, 246, 46, 225, 147, 1, 212, - 65, 225, 147, 1, 210, 82, 225, 147, 1, 210, 116, 225, 147, 1, 4, 61, 225, - 147, 1, 192, 225, 147, 1, 205, 225, 147, 1, 233, 141, 225, 147, 1, 220, - 104, 225, 147, 1, 206, 225, 147, 1, 162, 225, 147, 1, 61, 225, 147, 1, - 74, 225, 147, 1, 69, 225, 147, 1, 76, 225, 147, 1, 78, 225, 147, 1, 224, - 91, 225, 147, 1, 211, 165, 225, 147, 1, 244, 204, 225, 147, 1, 243, 36, - 225, 147, 1, 245, 217, 225, 147, 218, 74, 1, 212, 65, 225, 147, 218, 74, - 1, 192, 225, 147, 1, 215, 157, 225, 147, 1, 215, 145, 225, 147, 1, 248, - 143, 225, 147, 1, 228, 115, 225, 147, 1, 254, 149, 192, 225, 147, 1, 213, - 134, 220, 104, 225, 147, 1, 213, 135, 162, 225, 147, 1, 253, 231, 244, - 204, 225, 147, 218, 74, 1, 205, 225, 147, 218, 26, 1, 205, 225, 147, 1, - 251, 7, 225, 147, 219, 157, 241, 243, 79, 225, 147, 52, 241, 243, 79, - 225, 147, 164, 220, 97, 225, 147, 164, 52, 220, 97, 179, 5, 254, 83, 179, - 5, 213, 147, 179, 1, 61, 179, 1, 255, 82, 179, 1, 74, 179, 1, 236, 40, - 179, 1, 69, 179, 1, 214, 118, 179, 1, 149, 153, 179, 1, 149, 222, 182, - 179, 1, 149, 156, 179, 1, 149, 232, 191, 179, 1, 76, 179, 1, 245, 217, - 179, 1, 254, 210, 179, 1, 78, 179, 1, 226, 187, 179, 1, 253, 200, 179, 1, - 176, 179, 1, 234, 138, 179, 1, 243, 142, 179, 1, 243, 0, 179, 1, 229, 82, - 179, 1, 251, 41, 179, 1, 250, 165, 179, 1, 235, 147, 179, 1, 235, 120, - 179, 1, 227, 169, 179, 1, 215, 157, 179, 1, 215, 145, 179, 1, 248, 143, - 179, 1, 248, 127, 179, 1, 228, 115, 179, 1, 217, 106, 179, 1, 216, 209, - 179, 1, 248, 229, 179, 1, 248, 33, 179, 1, 198, 179, 1, 191, 179, 1, 225, - 150, 179, 1, 252, 199, 179, 1, 252, 26, 179, 1, 186, 179, 1, 192, 179, 1, - 205, 179, 1, 233, 141, 179, 1, 214, 27, 179, 1, 220, 104, 179, 1, 218, - 225, 179, 1, 206, 179, 1, 162, 179, 1, 232, 190, 179, 117, 5, 242, 51, - 179, 25, 5, 255, 82, 179, 25, 5, 74, 179, 25, 5, 236, 40, 179, 25, 5, 69, - 179, 25, 5, 214, 118, 179, 25, 5, 149, 153, 179, 25, 5, 149, 222, 182, - 179, 25, 5, 149, 156, 179, 25, 5, 149, 232, 191, 179, 25, 5, 76, 179, 25, - 5, 245, 217, 179, 25, 5, 254, 210, 179, 25, 5, 78, 179, 25, 5, 226, 187, - 179, 25, 5, 253, 200, 179, 5, 213, 152, 179, 248, 186, 179, 52, 248, 186, - 179, 21, 210, 86, 179, 21, 111, 179, 21, 105, 179, 21, 158, 179, 21, 161, - 179, 21, 190, 179, 21, 195, 179, 21, 199, 179, 21, 196, 179, 21, 201, 38, - 84, 21, 210, 86, 38, 84, 21, 111, 38, 84, 21, 105, 38, 84, 21, 158, 38, - 84, 21, 161, 38, 84, 21, 190, 38, 84, 21, 195, 38, 84, 21, 199, 38, 84, - 21, 196, 38, 84, 21, 201, 38, 84, 1, 61, 38, 84, 1, 69, 38, 84, 1, 176, - 38, 84, 1, 198, 38, 84, 1, 191, 38, 84, 1, 205, 38, 84, 1, 213, 176, 38, - 84, 5, 253, 183, 84, 5, 219, 19, 251, 7, 84, 5, 251, 8, 213, 152, 84, 5, - 52, 251, 8, 213, 152, 84, 5, 251, 8, 105, 84, 5, 251, 8, 158, 84, 5, 251, - 8, 253, 183, 84, 5, 224, 127, 84, 243, 107, 244, 111, 84, 250, 246, 84, - 241, 237, 234, 194, 232, 248, 21, 210, 86, 234, 194, 232, 248, 21, 111, - 234, 194, 232, 248, 21, 105, 234, 194, 232, 248, 21, 158, 234, 194, 232, - 248, 21, 161, 234, 194, 232, 248, 21, 190, 234, 194, 232, 248, 21, 195, - 234, 194, 232, 248, 21, 199, 234, 194, 232, 248, 21, 196, 234, 194, 232, - 248, 21, 201, 234, 194, 232, 248, 1, 176, 234, 194, 232, 248, 1, 234, - 138, 234, 194, 232, 248, 1, 243, 142, 234, 194, 232, 248, 1, 229, 82, - 234, 194, 232, 248, 1, 206, 234, 194, 232, 248, 1, 220, 104, 234, 194, - 232, 248, 1, 210, 116, 234, 194, 232, 248, 1, 227, 169, 234, 194, 232, - 248, 1, 217, 106, 234, 194, 232, 248, 1, 240, 233, 234, 194, 232, 248, 1, - 198, 234, 194, 232, 248, 1, 191, 234, 194, 232, 248, 1, 225, 150, 234, - 194, 232, 248, 1, 186, 234, 194, 232, 248, 1, 248, 229, 234, 194, 232, - 248, 1, 252, 199, 234, 194, 232, 248, 1, 205, 234, 194, 232, 248, 1, 192, - 234, 194, 232, 248, 1, 233, 141, 234, 194, 232, 248, 1, 212, 65, 234, - 194, 232, 248, 1, 216, 209, 234, 194, 232, 248, 1, 162, 234, 194, 232, - 248, 1, 214, 27, 234, 194, 232, 248, 1, 251, 41, 234, 194, 232, 248, 1, - 61, 234, 194, 232, 248, 1, 226, 238, 234, 194, 232, 248, 1, 74, 234, 194, - 232, 248, 1, 226, 187, 234, 194, 232, 248, 25, 214, 214, 234, 194, 232, - 248, 25, 76, 234, 194, 232, 248, 25, 69, 234, 194, 232, 248, 25, 245, - 217, 234, 194, 232, 248, 25, 78, 234, 194, 232, 248, 138, 225, 33, 234, - 194, 232, 248, 138, 251, 20, 234, 194, 232, 248, 138, 251, 21, 225, 33, - 234, 194, 232, 248, 5, 249, 85, 234, 194, 232, 248, 5, 219, 201, 223, 96, - 1, 176, 223, 96, 1, 243, 142, 223, 96, 1, 229, 82, 223, 96, 1, 217, 106, - 223, 96, 1, 248, 229, 223, 96, 1, 198, 223, 96, 1, 191, 223, 96, 1, 252, - 199, 223, 96, 1, 186, 223, 96, 1, 251, 41, 223, 96, 1, 235, 147, 223, 96, - 1, 227, 169, 223, 96, 1, 206, 223, 96, 1, 205, 223, 96, 1, 233, 141, 223, - 96, 1, 192, 223, 96, 1, 212, 65, 223, 96, 1, 162, 223, 96, 1, 231, 129, - 223, 96, 1, 229, 61, 223, 96, 1, 229, 153, 223, 96, 1, 227, 139, 223, 96, - 1, 61, 223, 96, 25, 5, 74, 223, 96, 25, 5, 69, 223, 96, 25, 5, 76, 223, - 96, 25, 5, 254, 210, 223, 96, 25, 5, 78, 223, 96, 25, 5, 253, 200, 223, - 96, 25, 5, 245, 63, 223, 96, 25, 5, 245, 241, 223, 96, 117, 5, 229, 84, - 223, 96, 117, 5, 230, 30, 223, 96, 117, 5, 153, 223, 96, 117, 5, 242, 67, - 223, 96, 213, 152, 223, 96, 221, 175, 79, 24, 100, 216, 98, 24, 100, 216, - 97, 24, 100, 216, 95, 24, 100, 216, 100, 24, 100, 223, 24, 24, 100, 223, - 8, 24, 100, 223, 3, 24, 100, 223, 5, 24, 100, 223, 21, 24, 100, 223, 14, - 24, 100, 223, 7, 24, 100, 223, 26, 24, 100, 223, 9, 24, 100, 223, 28, 24, - 100, 223, 25, 24, 100, 230, 218, 24, 100, 230, 209, 24, 100, 230, 212, - 24, 100, 225, 83, 24, 100, 225, 94, 24, 100, 225, 95, 24, 100, 218, 209, - 24, 100, 236, 53, 24, 100, 236, 60, 24, 100, 218, 220, 24, 100, 218, 207, - 24, 100, 225, 133, 24, 100, 241, 174, 24, 100, 218, 204, 155, 5, 226, 31, - 155, 5, 250, 195, 155, 5, 233, 72, 155, 5, 211, 243, 155, 1, 61, 155, 1, - 240, 161, 234, 197, 155, 1, 74, 155, 1, 236, 40, 155, 1, 69, 155, 1, 226, - 94, 250, 171, 155, 1, 229, 83, 233, 34, 155, 1, 229, 83, 233, 35, 223, - 145, 155, 1, 76, 155, 1, 254, 210, 155, 1, 78, 155, 1, 176, 155, 1, 235, - 19, 221, 230, 155, 1, 235, 19, 230, 71, 155, 1, 243, 142, 155, 1, 243, - 143, 230, 71, 155, 1, 229, 82, 155, 1, 251, 41, 155, 1, 251, 42, 230, 71, - 155, 1, 235, 147, 155, 1, 227, 170, 230, 71, 155, 1, 235, 148, 231, 212, - 155, 1, 227, 169, 155, 1, 215, 157, 155, 1, 215, 158, 231, 212, 155, 1, - 248, 143, 155, 1, 248, 144, 231, 212, 155, 1, 229, 234, 230, 71, 155, 1, - 217, 106, 155, 1, 217, 107, 230, 71, 155, 1, 248, 229, 155, 1, 248, 230, - 231, 212, 155, 1, 198, 155, 1, 191, 155, 1, 226, 94, 230, 71, 155, 1, - 252, 199, 155, 1, 252, 200, 230, 71, 155, 1, 186, 155, 1, 192, 155, 1, - 205, 155, 1, 223, 191, 254, 219, 155, 1, 233, 141, 155, 1, 212, 65, 155, - 1, 222, 36, 230, 71, 155, 1, 222, 36, 231, 212, 155, 1, 206, 155, 1, 162, - 155, 5, 250, 196, 216, 251, 155, 25, 5, 217, 48, 155, 25, 5, 216, 36, - 155, 25, 5, 211, 190, 155, 25, 5, 211, 191, 231, 74, 155, 25, 5, 218, 48, - 155, 25, 5, 218, 49, 231, 62, 155, 25, 5, 217, 66, 155, 25, 5, 247, 202, - 230, 70, 155, 25, 5, 225, 187, 155, 117, 5, 234, 164, 155, 117, 5, 225, - 199, 155, 117, 5, 251, 27, 155, 226, 44, 155, 43, 223, 72, 155, 44, 223, - 72, 155, 226, 83, 254, 125, 155, 226, 83, 231, 229, 155, 226, 83, 232, - 93, 155, 226, 83, 211, 238, 155, 226, 83, 226, 45, 155, 226, 83, 232, - 211, 155, 226, 83, 232, 87, 155, 226, 83, 255, 2, 155, 226, 83, 255, 3, - 255, 2, 155, 226, 83, 225, 54, 155, 215, 94, 226, 83, 225, 54, 155, 226, - 40, 155, 21, 210, 86, 155, 21, 111, 155, 21, 105, 155, 21, 158, 155, 21, - 161, 155, 21, 190, 155, 21, 195, 155, 21, 199, 155, 21, 196, 155, 21, - 201, 155, 226, 83, 216, 70, 215, 107, 155, 226, 83, 235, 174, 172, 1, 61, - 172, 1, 74, 172, 1, 69, 172, 1, 76, 172, 1, 254, 210, 172, 1, 78, 172, 1, - 176, 172, 1, 234, 138, 172, 1, 243, 142, 172, 1, 243, 0, 172, 1, 228, - 250, 172, 1, 229, 82, 172, 1, 250, 165, 172, 1, 250, 120, 172, 1, 235, - 147, 172, 1, 235, 120, 172, 1, 228, 240, 172, 1, 228, 242, 172, 1, 228, - 241, 172, 1, 217, 106, 172, 1, 216, 209, 172, 1, 248, 229, 172, 1, 248, - 33, 172, 1, 227, 211, 172, 1, 198, 172, 1, 248, 143, 172, 1, 191, 172, 1, - 224, 223, 172, 1, 225, 150, 172, 1, 252, 199, 172, 1, 252, 26, 172, 1, - 230, 100, 172, 1, 186, 172, 1, 252, 119, 172, 1, 192, 172, 1, 205, 172, - 1, 233, 141, 172, 1, 214, 27, 172, 1, 218, 225, 172, 1, 206, 172, 1, 162, - 172, 25, 5, 255, 82, 172, 25, 5, 74, 172, 25, 5, 236, 40, 172, 25, 5, - 245, 203, 172, 25, 5, 69, 172, 25, 5, 226, 238, 172, 25, 5, 78, 172, 25, - 5, 254, 210, 172, 25, 5, 253, 200, 172, 25, 5, 214, 214, 172, 117, 5, - 192, 172, 117, 5, 205, 172, 117, 5, 233, 141, 172, 117, 5, 212, 65, 172, - 1, 40, 235, 29, 172, 1, 40, 243, 209, 172, 1, 40, 229, 84, 172, 117, 5, - 40, 229, 84, 172, 1, 40, 250, 166, 172, 1, 40, 217, 153, 172, 1, 40, 230, - 30, 172, 1, 40, 226, 109, 172, 1, 40, 211, 117, 172, 1, 40, 153, 172, 1, - 40, 156, 172, 1, 40, 218, 228, 172, 117, 5, 40, 194, 172, 117, 5, 40, - 242, 67, 172, 21, 210, 86, 172, 21, 111, 172, 21, 105, 172, 21, 158, 172, - 21, 161, 172, 21, 190, 172, 21, 195, 172, 21, 199, 172, 21, 196, 172, 21, - 201, 172, 224, 144, 218, 253, 172, 224, 144, 248, 186, 172, 224, 144, 52, - 248, 186, 172, 224, 144, 215, 212, 248, 186, 68, 1, 234, 132, 243, 142, - 68, 1, 234, 132, 251, 41, 68, 1, 234, 132, 250, 165, 68, 1, 234, 132, - 235, 147, 68, 1, 234, 132, 235, 120, 68, 1, 234, 132, 227, 169, 68, 1, - 234, 132, 215, 157, 68, 1, 234, 132, 215, 145, 68, 1, 234, 132, 248, 143, - 68, 1, 234, 132, 248, 127, 68, 1, 234, 132, 248, 33, 68, 1, 234, 132, - 198, 68, 1, 234, 132, 206, 68, 1, 234, 132, 162, 68, 1, 234, 132, 241, - 196, 68, 1, 234, 132, 244, 204, 68, 58, 1, 234, 132, 223, 112, 68, 1, - 234, 132, 211, 165, 68, 1, 234, 132, 210, 116, 68, 1, 234, 132, 205, 68, - 232, 151, 234, 132, 227, 1, 68, 232, 151, 234, 132, 224, 46, 68, 232, - 151, 234, 132, 241, 128, 68, 16, 254, 199, 245, 38, 68, 16, 254, 199, - 111, 68, 16, 254, 199, 105, 68, 1, 254, 199, 205, 68, 5, 226, 27, 234, - 219, 216, 31, 39, 208, 1, 121, 234, 34, 39, 208, 1, 125, 234, 34, 39, - 208, 1, 121, 234, 111, 39, 208, 1, 125, 234, 111, 39, 208, 1, 121, 234, - 120, 39, 208, 1, 125, 234, 120, 39, 208, 1, 121, 242, 181, 39, 208, 1, - 125, 242, 181, 39, 208, 1, 121, 229, 9, 39, 208, 1, 125, 229, 9, 39, 208, - 1, 121, 249, 246, 39, 208, 1, 125, 249, 246, 39, 208, 1, 121, 250, 94, - 39, 208, 1, 125, 250, 94, 39, 208, 1, 121, 219, 60, 39, 208, 1, 125, 219, - 60, 39, 208, 1, 121, 227, 138, 39, 208, 1, 125, 227, 138, 39, 208, 1, - 121, 247, 153, 39, 208, 1, 125, 247, 153, 39, 208, 1, 121, 112, 39, 208, - 1, 125, 112, 39, 208, 1, 121, 216, 157, 39, 208, 1, 125, 216, 157, 39, - 208, 1, 121, 228, 79, 39, 208, 1, 125, 228, 79, 39, 208, 1, 121, 251, - 213, 39, 208, 1, 125, 251, 213, 39, 208, 1, 121, 225, 19, 39, 208, 1, - 125, 225, 19, 39, 208, 1, 121, 225, 124, 39, 208, 1, 125, 225, 124, 39, - 208, 1, 121, 244, 51, 39, 208, 1, 125, 244, 51, 39, 208, 1, 121, 230, - 166, 39, 208, 1, 125, 230, 166, 39, 208, 1, 121, 210, 244, 39, 208, 1, - 125, 210, 244, 39, 208, 1, 121, 222, 213, 39, 208, 1, 125, 222, 213, 39, - 208, 1, 121, 232, 162, 39, 208, 1, 125, 232, 162, 39, 208, 1, 121, 213, - 138, 39, 208, 1, 125, 213, 138, 39, 208, 1, 121, 241, 75, 39, 208, 1, - 125, 241, 75, 39, 208, 1, 121, 78, 39, 208, 1, 125, 78, 39, 208, 231, - 209, 234, 236, 39, 208, 25, 255, 82, 39, 208, 25, 74, 39, 208, 25, 214, - 214, 39, 208, 25, 69, 39, 208, 25, 76, 39, 208, 25, 78, 39, 208, 231, - 209, 234, 114, 39, 208, 25, 240, 126, 39, 208, 25, 214, 213, 39, 208, 25, - 214, 229, 39, 208, 25, 253, 198, 39, 208, 25, 253, 175, 39, 208, 25, 254, - 131, 39, 208, 25, 254, 144, 39, 208, 138, 231, 209, 245, 188, 39, 208, - 138, 231, 209, 227, 210, 39, 208, 138, 231, 209, 216, 157, 39, 208, 138, - 231, 209, 219, 44, 39, 208, 16, 234, 19, 39, 208, 16, 227, 210, 39, 208, - 16, 221, 255, 39, 208, 16, 241, 76, 241, 71, 39, 208, 16, 234, 28, 234, - 27, 188, 187, 1, 76, 188, 187, 1, 78, 188, 187, 1, 250, 165, 188, 187, 1, - 227, 169, 188, 187, 1, 215, 157, 188, 187, 1, 215, 145, 188, 187, 1, 248, - 143, 188, 187, 1, 248, 127, 188, 187, 1, 228, 115, 188, 187, 1, 220, 104, - 188, 187, 1, 218, 225, 188, 187, 25, 5, 236, 40, 188, 187, 25, 5, 214, - 118, 188, 187, 25, 5, 255, 46, 188, 187, 25, 5, 253, 200, 188, 187, 25, - 5, 255, 39, 188, 187, 250, 133, 188, 187, 254, 215, 234, 104, 188, 187, - 254, 111, 188, 187, 3, 223, 77, 79, 188, 187, 211, 209, 223, 77, 79, 188, - 187, 25, 5, 213, 147, 188, 187, 213, 152, 29, 3, 215, 138, 29, 3, 215, - 141, 29, 3, 215, 144, 29, 3, 215, 142, 29, 3, 215, 143, 29, 3, 215, 140, - 29, 3, 248, 121, 29, 3, 248, 123, 29, 3, 248, 126, 29, 3, 248, 124, 29, - 3, 248, 125, 29, 3, 248, 122, 29, 3, 246, 36, 29, 3, 246, 39, 29, 3, 246, - 45, 29, 3, 246, 43, 29, 3, 246, 44, 29, 3, 246, 37, 29, 3, 250, 212, 29, - 3, 250, 206, 29, 3, 250, 208, 29, 3, 250, 211, 29, 3, 250, 209, 29, 3, - 250, 210, 29, 3, 250, 207, 29, 3, 252, 119, 29, 3, 252, 98, 29, 3, 252, - 110, 29, 3, 252, 118, 29, 3, 252, 113, 29, 3, 252, 114, 29, 3, 252, 102, - 188, 187, 1, 234, 25, 188, 187, 1, 221, 255, 188, 187, 1, 233, 115, 188, - 187, 1, 230, 177, 188, 187, 1, 191, 188, 187, 1, 198, 188, 187, 1, 250, - 110, 188, 187, 1, 216, 91, 188, 187, 1, 234, 107, 188, 187, 1, 228, 255, - 188, 187, 1, 216, 151, 188, 187, 1, 212, 60, 188, 187, 1, 211, 69, 188, - 187, 1, 240, 223, 188, 187, 1, 214, 190, 188, 187, 1, 74, 188, 187, 1, - 225, 145, 188, 187, 1, 253, 210, 188, 187, 1, 242, 174, 188, 187, 1, 235, - 118, 188, 187, 1, 223, 169, 188, 187, 1, 252, 199, 188, 187, 1, 235, 106, - 188, 187, 1, 247, 227, 188, 187, 1, 242, 228, 188, 187, 1, 248, 13, 188, - 187, 1, 252, 24, 188, 187, 1, 234, 26, 232, 134, 188, 187, 1, 233, 116, - 232, 134, 188, 187, 1, 230, 178, 232, 134, 188, 187, 1, 226, 94, 232, - 134, 188, 187, 1, 229, 234, 232, 134, 188, 187, 1, 216, 92, 232, 134, - 188, 187, 1, 229, 0, 232, 134, 188, 187, 1, 240, 161, 232, 134, 188, 187, - 25, 5, 226, 199, 188, 187, 25, 5, 236, 4, 188, 187, 25, 5, 254, 130, 188, - 187, 25, 5, 211, 38, 188, 187, 25, 5, 219, 34, 188, 187, 25, 5, 214, 187, - 188, 187, 25, 5, 250, 131, 188, 187, 25, 5, 227, 195, 188, 187, 250, 132, - 188, 187, 232, 90, 235, 156, 188, 187, 254, 54, 235, 156, 188, 187, 21, - 210, 86, 188, 187, 21, 111, 188, 187, 21, 105, 188, 187, 21, 158, 188, - 187, 21, 161, 188, 187, 21, 190, 188, 187, 21, 195, 188, 187, 21, 199, - 188, 187, 21, 196, 188, 187, 21, 201, 24, 143, 227, 81, 24, 143, 227, 86, - 24, 143, 210, 243, 24, 143, 210, 242, 24, 143, 210, 241, 24, 143, 215, - 23, 24, 143, 215, 26, 24, 143, 210, 210, 24, 143, 210, 206, 24, 143, 245, - 62, 24, 143, 245, 60, 24, 143, 245, 61, 24, 143, 245, 58, 24, 143, 240, - 151, 24, 143, 240, 150, 24, 143, 240, 148, 24, 143, 240, 149, 24, 143, - 240, 154, 24, 143, 240, 147, 24, 143, 240, 146, 24, 143, 240, 156, 24, - 143, 254, 41, 24, 143, 254, 40, 24, 90, 228, 224, 24, 90, 228, 230, 24, - 90, 218, 206, 24, 90, 218, 205, 24, 90, 216, 97, 24, 90, 216, 95, 24, 90, - 216, 94, 24, 90, 216, 100, 24, 90, 216, 101, 24, 90, 216, 93, 24, 90, - 223, 8, 24, 90, 223, 23, 24, 90, 218, 212, 24, 90, 223, 20, 24, 90, 223, - 10, 24, 90, 223, 12, 24, 90, 222, 255, 24, 90, 223, 0, 24, 90, 234, 224, - 24, 90, 230, 217, 24, 90, 230, 211, 24, 90, 218, 216, 24, 90, 230, 214, - 24, 90, 230, 220, 24, 90, 225, 79, 24, 90, 225, 88, 24, 90, 225, 92, 24, - 90, 218, 214, 24, 90, 225, 82, 24, 90, 225, 96, 24, 90, 225, 97, 24, 90, - 219, 142, 24, 90, 219, 145, 24, 90, 218, 210, 24, 90, 218, 208, 24, 90, - 219, 140, 24, 90, 219, 148, 24, 90, 219, 149, 24, 90, 219, 134, 24, 90, - 219, 147, 24, 90, 226, 34, 24, 90, 226, 35, 24, 90, 211, 24, 24, 90, 211, - 25, 24, 90, 250, 52, 24, 90, 250, 51, 24, 90, 218, 221, 24, 90, 225, 131, - 24, 90, 225, 130, 10, 14, 238, 31, 10, 14, 238, 30, 10, 14, 238, 29, 10, - 14, 238, 28, 10, 14, 238, 27, 10, 14, 238, 26, 10, 14, 238, 25, 10, 14, - 238, 24, 10, 14, 238, 23, 10, 14, 238, 22, 10, 14, 238, 21, 10, 14, 238, - 20, 10, 14, 238, 19, 10, 14, 238, 18, 10, 14, 238, 17, 10, 14, 238, 16, - 10, 14, 238, 15, 10, 14, 238, 14, 10, 14, 238, 13, 10, 14, 238, 12, 10, - 14, 238, 11, 10, 14, 238, 10, 10, 14, 238, 9, 10, 14, 238, 8, 10, 14, - 238, 7, 10, 14, 238, 6, 10, 14, 238, 5, 10, 14, 238, 4, 10, 14, 238, 3, - 10, 14, 238, 2, 10, 14, 238, 1, 10, 14, 238, 0, 10, 14, 237, 255, 10, 14, - 237, 254, 10, 14, 237, 253, 10, 14, 237, 252, 10, 14, 237, 251, 10, 14, - 237, 250, 10, 14, 237, 249, 10, 14, 237, 248, 10, 14, 237, 247, 10, 14, - 237, 246, 10, 14, 237, 245, 10, 14, 237, 244, 10, 14, 237, 243, 10, 14, - 237, 242, 10, 14, 237, 241, 10, 14, 237, 240, 10, 14, 237, 239, 10, 14, - 237, 238, 10, 14, 237, 237, 10, 14, 237, 236, 10, 14, 237, 235, 10, 14, - 237, 234, 10, 14, 237, 233, 10, 14, 237, 232, 10, 14, 237, 231, 10, 14, - 237, 230, 10, 14, 237, 229, 10, 14, 237, 228, 10, 14, 237, 227, 10, 14, - 237, 226, 10, 14, 237, 225, 10, 14, 237, 224, 10, 14, 237, 223, 10, 14, - 237, 222, 10, 14, 237, 221, 10, 14, 237, 220, 10, 14, 237, 219, 10, 14, - 237, 218, 10, 14, 237, 217, 10, 14, 237, 216, 10, 14, 237, 215, 10, 14, - 237, 214, 10, 14, 237, 213, 10, 14, 237, 212, 10, 14, 237, 211, 10, 14, - 237, 210, 10, 14, 237, 209, 10, 14, 237, 208, 10, 14, 237, 207, 10, 14, - 237, 206, 10, 14, 237, 205, 10, 14, 237, 204, 10, 14, 237, 203, 10, 14, - 237, 202, 10, 14, 237, 201, 10, 14, 237, 200, 10, 14, 237, 199, 10, 14, - 237, 198, 10, 14, 237, 197, 10, 14, 237, 196, 10, 14, 237, 195, 10, 14, - 237, 194, 10, 14, 237, 193, 10, 14, 237, 192, 10, 14, 237, 191, 10, 14, - 237, 190, 10, 14, 237, 189, 10, 14, 237, 188, 10, 14, 237, 187, 10, 14, - 237, 186, 10, 14, 237, 185, 10, 14, 237, 184, 10, 14, 237, 183, 10, 14, - 237, 182, 10, 14, 237, 181, 10, 14, 237, 180, 10, 14, 237, 179, 10, 14, - 237, 178, 10, 14, 237, 177, 10, 14, 237, 176, 10, 14, 237, 175, 10, 14, - 237, 174, 10, 14, 237, 173, 10, 14, 237, 172, 10, 14, 237, 171, 10, 14, - 237, 170, 10, 14, 237, 169, 10, 14, 237, 168, 10, 14, 237, 167, 10, 14, - 237, 166, 10, 14, 237, 165, 10, 14, 237, 164, 10, 14, 237, 163, 10, 14, - 237, 162, 10, 14, 237, 161, 10, 14, 237, 160, 10, 14, 237, 159, 10, 14, - 237, 158, 10, 14, 237, 157, 10, 14, 237, 156, 10, 14, 237, 155, 10, 14, - 237, 154, 10, 14, 237, 153, 10, 14, 237, 152, 10, 14, 237, 151, 10, 14, - 237, 150, 10, 14, 237, 149, 10, 14, 237, 148, 10, 14, 237, 147, 10, 14, - 237, 146, 10, 14, 237, 145, 10, 14, 237, 144, 10, 14, 237, 143, 10, 14, - 237, 142, 10, 14, 237, 141, 10, 14, 237, 140, 10, 14, 237, 139, 10, 14, - 237, 138, 10, 14, 237, 137, 10, 14, 237, 136, 10, 14, 237, 135, 10, 14, - 237, 134, 10, 14, 237, 133, 10, 14, 237, 132, 10, 14, 237, 131, 10, 14, - 237, 130, 10, 14, 237, 129, 10, 14, 237, 128, 10, 14, 237, 127, 10, 14, - 237, 126, 10, 14, 237, 125, 10, 14, 237, 124, 10, 14, 237, 123, 10, 14, - 237, 122, 10, 14, 237, 121, 10, 14, 237, 120, 10, 14, 237, 119, 10, 14, - 237, 118, 10, 14, 237, 117, 10, 14, 237, 116, 10, 14, 237, 115, 10, 14, - 237, 114, 10, 14, 237, 113, 10, 14, 237, 112, 10, 14, 237, 111, 10, 14, - 237, 110, 10, 14, 237, 109, 10, 14, 237, 108, 10, 14, 237, 107, 10, 14, - 237, 106, 10, 14, 237, 105, 10, 14, 237, 104, 10, 14, 237, 103, 10, 14, - 237, 102, 10, 14, 237, 101, 10, 14, 237, 100, 10, 14, 237, 99, 10, 14, - 237, 98, 10, 14, 237, 97, 10, 14, 237, 96, 10, 14, 237, 95, 10, 14, 237, - 94, 10, 14, 237, 93, 10, 14, 237, 92, 10, 14, 237, 91, 10, 14, 237, 90, - 10, 14, 237, 89, 10, 14, 237, 88, 10, 14, 237, 87, 10, 14, 237, 86, 10, - 14, 237, 85, 10, 14, 237, 84, 10, 14, 237, 83, 10, 14, 237, 82, 10, 14, - 237, 81, 10, 14, 237, 80, 10, 14, 237, 79, 10, 14, 237, 78, 10, 14, 237, - 77, 10, 14, 237, 76, 10, 14, 237, 75, 10, 14, 237, 74, 10, 14, 237, 73, - 10, 14, 237, 72, 10, 14, 237, 71, 10, 14, 237, 70, 10, 14, 237, 69, 10, - 14, 237, 68, 10, 14, 237, 67, 10, 14, 237, 66, 10, 14, 237, 65, 10, 14, - 237, 64, 10, 14, 237, 63, 10, 14, 237, 62, 10, 14, 237, 61, 10, 14, 237, - 60, 10, 14, 237, 59, 10, 14, 237, 58, 10, 14, 237, 57, 10, 14, 237, 56, - 10, 14, 237, 55, 10, 14, 237, 54, 10, 14, 237, 53, 10, 14, 237, 52, 10, - 14, 237, 51, 10, 14, 237, 50, 10, 14, 237, 49, 10, 14, 237, 48, 10, 14, - 237, 47, 10, 14, 237, 46, 10, 14, 237, 45, 10, 14, 237, 44, 10, 14, 237, - 43, 10, 14, 237, 42, 10, 14, 237, 41, 10, 14, 237, 40, 10, 14, 237, 39, - 10, 14, 237, 38, 10, 14, 237, 37, 10, 14, 237, 36, 10, 14, 237, 35, 10, - 14, 237, 34, 10, 14, 237, 33, 10, 14, 237, 32, 10, 14, 237, 31, 10, 14, - 237, 30, 10, 14, 237, 29, 10, 14, 237, 28, 10, 14, 237, 27, 10, 14, 237, - 26, 10, 14, 237, 25, 10, 14, 237, 24, 10, 14, 237, 23, 10, 14, 237, 22, - 10, 14, 237, 21, 10, 14, 237, 20, 10, 14, 237, 19, 10, 14, 237, 18, 10, - 14, 237, 17, 10, 14, 237, 16, 10, 14, 237, 15, 10, 14, 237, 14, 10, 14, - 237, 13, 10, 14, 237, 12, 10, 14, 237, 11, 10, 14, 237, 10, 10, 14, 237, - 9, 10, 14, 237, 8, 10, 14, 237, 7, 10, 14, 237, 6, 10, 14, 237, 5, 10, - 14, 237, 4, 10, 14, 237, 3, 10, 14, 237, 2, 10, 14, 237, 1, 10, 14, 237, - 0, 10, 14, 236, 255, 10, 14, 236, 254, 10, 14, 236, 253, 10, 14, 236, - 252, 10, 14, 236, 251, 10, 14, 236, 250, 10, 14, 236, 249, 10, 14, 236, - 248, 10, 14, 236, 247, 10, 14, 236, 246, 10, 14, 236, 245, 10, 14, 236, - 244, 10, 14, 236, 243, 10, 14, 236, 242, 10, 14, 236, 241, 10, 14, 236, - 240, 10, 14, 236, 239, 10, 14, 236, 238, 10, 14, 236, 237, 10, 14, 236, - 236, 10, 14, 236, 235, 10, 14, 236, 234, 10, 14, 236, 233, 10, 14, 236, - 232, 10, 14, 236, 231, 10, 14, 236, 230, 10, 14, 236, 229, 10, 14, 236, - 228, 10, 14, 236, 227, 10, 14, 236, 226, 10, 14, 236, 225, 10, 14, 236, - 224, 10, 14, 236, 223, 10, 14, 236, 222, 10, 14, 236, 221, 10, 14, 236, - 220, 10, 14, 236, 219, 10, 14, 236, 218, 10, 14, 236, 217, 10, 14, 236, - 216, 10, 14, 236, 215, 10, 14, 236, 214, 10, 14, 236, 213, 10, 14, 236, - 212, 10, 14, 236, 211, 10, 14, 236, 210, 10, 14, 236, 209, 10, 14, 236, - 208, 10, 14, 236, 207, 10, 14, 236, 206, 10, 14, 236, 205, 10, 14, 236, - 204, 10, 14, 236, 203, 10, 14, 236, 202, 10, 14, 236, 201, 10, 14, 236, - 200, 10, 14, 236, 199, 10, 14, 236, 198, 10, 14, 236, 197, 10, 14, 236, - 196, 10, 14, 236, 195, 10, 14, 236, 194, 10, 14, 236, 193, 10, 14, 236, - 192, 10, 14, 236, 191, 10, 14, 236, 190, 10, 14, 236, 189, 10, 14, 236, - 188, 10, 14, 236, 187, 10, 14, 236, 186, 10, 14, 236, 185, 10, 14, 236, - 184, 10, 14, 236, 183, 10, 14, 236, 182, 10, 14, 236, 181, 10, 14, 236, - 180, 10, 14, 236, 179, 10, 14, 236, 178, 10, 14, 236, 177, 10, 14, 236, - 176, 10, 14, 236, 175, 10, 14, 236, 174, 10, 14, 236, 173, 10, 14, 236, - 172, 10, 14, 236, 171, 10, 14, 236, 170, 10, 14, 236, 169, 10, 14, 236, - 168, 10, 14, 236, 167, 10, 14, 236, 166, 10, 14, 236, 165, 10, 14, 236, - 164, 10, 14, 236, 163, 10, 14, 236, 162, 10, 14, 236, 161, 10, 14, 236, - 160, 10, 14, 236, 159, 10, 14, 236, 158, 10, 14, 236, 157, 10, 14, 236, - 156, 10, 14, 236, 155, 10, 14, 236, 154, 10, 14, 236, 153, 10, 14, 236, - 152, 10, 14, 236, 151, 10, 14, 236, 150, 10, 14, 236, 149, 10, 14, 236, - 148, 10, 14, 236, 147, 10, 14, 236, 146, 10, 14, 236, 145, 10, 14, 236, - 144, 10, 14, 236, 143, 10, 14, 236, 142, 10, 14, 236, 141, 10, 14, 236, - 140, 10, 14, 236, 139, 10, 14, 236, 138, 10, 14, 236, 137, 10, 14, 236, - 136, 10, 14, 236, 135, 10, 14, 236, 134, 10, 14, 236, 133, 10, 14, 236, - 132, 10, 14, 236, 131, 10, 14, 236, 130, 10, 14, 236, 129, 10, 14, 236, - 128, 10, 14, 236, 127, 10, 14, 236, 126, 10, 14, 236, 125, 10, 14, 236, - 124, 10, 14, 236, 123, 10, 14, 236, 122, 10, 14, 236, 121, 10, 14, 236, - 120, 10, 14, 236, 119, 10, 14, 236, 118, 10, 14, 236, 117, 10, 14, 236, - 116, 10, 14, 236, 115, 10, 14, 236, 114, 10, 14, 236, 113, 10, 14, 236, - 112, 10, 14, 236, 111, 10, 14, 236, 110, 10, 14, 236, 109, 10, 14, 236, - 108, 10, 14, 236, 107, 10, 14, 236, 106, 10, 14, 236, 105, 10, 14, 236, - 104, 10, 14, 236, 103, 10, 14, 236, 102, 10, 14, 236, 101, 10, 14, 236, - 100, 10, 14, 236, 99, 10, 14, 236, 98, 10, 14, 236, 97, 10, 14, 236, 96, - 10, 14, 236, 95, 10, 14, 236, 94, 10, 14, 236, 93, 10, 14, 236, 92, 10, - 14, 236, 91, 10, 14, 236, 90, 10, 14, 236, 89, 10, 14, 236, 88, 10, 14, - 236, 87, 10, 14, 236, 86, 10, 14, 236, 85, 10, 14, 236, 84, 10, 14, 236, - 83, 10, 14, 236, 82, 10, 14, 236, 81, 10, 14, 236, 80, 10, 14, 236, 79, - 10, 14, 236, 78, 10, 14, 236, 77, 10, 14, 236, 76, 10, 14, 236, 75, 10, - 14, 236, 74, 10, 14, 236, 73, 10, 14, 236, 72, 7, 4, 27, 244, 133, 7, 4, - 27, 244, 129, 7, 4, 27, 244, 84, 7, 4, 27, 244, 132, 7, 4, 27, 244, 131, - 7, 4, 27, 200, 222, 94, 217, 153, 7, 4, 27, 218, 170, 150, 4, 27, 231, - 64, 228, 44, 150, 4, 27, 231, 64, 245, 221, 150, 4, 27, 231, 64, 235, - 234, 150, 4, 27, 213, 180, 228, 44, 150, 4, 27, 231, 64, 211, 160, 94, 1, - 210, 234, 2, 241, 165, 94, 225, 14, 235, 56, 214, 11, 94, 27, 211, 6, - 210, 234, 210, 234, 225, 243, 94, 1, 254, 147, 253, 170, 94, 1, 211, 247, - 254, 179, 94, 1, 211, 247, 248, 197, 94, 1, 211, 247, 241, 245, 94, 1, - 211, 247, 235, 0, 94, 1, 211, 247, 233, 100, 94, 1, 211, 247, 40, 231, - 70, 94, 1, 211, 247, 223, 70, 94, 1, 211, 247, 217, 39, 94, 1, 254, 147, - 96, 50, 94, 1, 220, 23, 2, 220, 23, 247, 128, 94, 1, 220, 23, 2, 219, - 161, 247, 128, 94, 1, 220, 23, 2, 248, 216, 22, 220, 23, 247, 128, 94, 1, - 220, 23, 2, 248, 216, 22, 219, 161, 247, 128, 94, 1, 109, 2, 225, 243, - 94, 1, 109, 2, 224, 79, 94, 1, 109, 2, 231, 176, 94, 1, 252, 37, 2, 248, - 215, 94, 1, 242, 209, 2, 248, 215, 94, 1, 248, 198, 2, 248, 215, 94, 1, - 241, 246, 2, 231, 176, 94, 1, 214, 4, 2, 248, 215, 94, 1, 210, 98, 2, - 248, 215, 94, 1, 216, 232, 2, 248, 215, 94, 1, 210, 234, 2, 248, 215, 94, - 1, 40, 235, 1, 2, 248, 215, 94, 1, 235, 1, 2, 248, 215, 94, 1, 233, 101, - 2, 248, 215, 94, 1, 231, 71, 2, 248, 215, 94, 1, 227, 199, 2, 248, 215, - 94, 1, 221, 252, 2, 248, 215, 94, 1, 40, 225, 225, 2, 248, 215, 94, 1, - 225, 225, 2, 248, 215, 94, 1, 215, 181, 2, 248, 215, 94, 1, 224, 43, 2, - 248, 215, 94, 1, 223, 71, 2, 248, 215, 94, 1, 220, 23, 2, 248, 215, 94, - 1, 217, 40, 2, 248, 215, 94, 1, 214, 4, 2, 241, 68, 94, 1, 252, 37, 2, - 223, 172, 94, 1, 235, 1, 2, 223, 172, 94, 1, 225, 225, 2, 223, 172, 94, - 27, 109, 233, 100, 9, 1, 109, 212, 47, 53, 17, 9, 1, 109, 212, 47, 40, - 17, 9, 1, 252, 73, 53, 17, 9, 1, 252, 73, 40, 17, 9, 1, 252, 73, 65, 17, - 9, 1, 252, 73, 147, 17, 9, 1, 225, 209, 53, 17, 9, 1, 225, 209, 40, 17, - 9, 1, 225, 209, 65, 17, 9, 1, 225, 209, 147, 17, 9, 1, 252, 61, 53, 17, - 9, 1, 252, 61, 40, 17, 9, 1, 252, 61, 65, 17, 9, 1, 252, 61, 147, 17, 9, - 1, 215, 148, 53, 17, 9, 1, 215, 148, 40, 17, 9, 1, 215, 148, 65, 17, 9, - 1, 215, 148, 147, 17, 9, 1, 217, 7, 53, 17, 9, 1, 217, 7, 40, 17, 9, 1, - 217, 7, 65, 17, 9, 1, 217, 7, 147, 17, 9, 1, 215, 150, 53, 17, 9, 1, 215, - 150, 40, 17, 9, 1, 215, 150, 65, 17, 9, 1, 215, 150, 147, 17, 9, 1, 213, - 249, 53, 17, 9, 1, 213, 249, 40, 17, 9, 1, 213, 249, 65, 17, 9, 1, 213, - 249, 147, 17, 9, 1, 225, 207, 53, 17, 9, 1, 225, 207, 40, 17, 9, 1, 225, - 207, 65, 17, 9, 1, 225, 207, 147, 17, 9, 1, 246, 52, 53, 17, 9, 1, 246, - 52, 40, 17, 9, 1, 246, 52, 65, 17, 9, 1, 246, 52, 147, 17, 9, 1, 227, - 158, 53, 17, 9, 1, 227, 158, 40, 17, 9, 1, 227, 158, 65, 17, 9, 1, 227, - 158, 147, 17, 9, 1, 217, 28, 53, 17, 9, 1, 217, 28, 40, 17, 9, 1, 217, - 28, 65, 17, 9, 1, 217, 28, 147, 17, 9, 1, 217, 26, 53, 17, 9, 1, 217, 26, - 40, 17, 9, 1, 217, 26, 65, 17, 9, 1, 217, 26, 147, 17, 9, 1, 248, 141, - 53, 17, 9, 1, 248, 141, 40, 17, 9, 1, 248, 210, 53, 17, 9, 1, 248, 210, - 40, 17, 9, 1, 246, 79, 53, 17, 9, 1, 246, 79, 40, 17, 9, 1, 248, 139, 53, - 17, 9, 1, 248, 139, 40, 17, 9, 1, 235, 127, 53, 17, 9, 1, 235, 127, 40, - 17, 9, 1, 222, 174, 53, 17, 9, 1, 222, 174, 40, 17, 9, 1, 234, 181, 53, - 17, 9, 1, 234, 181, 40, 17, 9, 1, 234, 181, 65, 17, 9, 1, 234, 181, 147, - 17, 9, 1, 243, 130, 53, 17, 9, 1, 243, 130, 40, 17, 9, 1, 243, 130, 65, - 17, 9, 1, 243, 130, 147, 17, 9, 1, 242, 109, 53, 17, 9, 1, 242, 109, 40, - 17, 9, 1, 242, 109, 65, 17, 9, 1, 242, 109, 147, 17, 9, 1, 229, 8, 53, - 17, 9, 1, 229, 8, 40, 17, 9, 1, 229, 8, 65, 17, 9, 1, 229, 8, 147, 17, 9, - 1, 228, 68, 242, 226, 53, 17, 9, 1, 228, 68, 242, 226, 40, 17, 9, 1, 222, - 217, 53, 17, 9, 1, 222, 217, 40, 17, 9, 1, 222, 217, 65, 17, 9, 1, 222, - 217, 147, 17, 9, 1, 241, 226, 2, 77, 72, 53, 17, 9, 1, 241, 226, 2, 77, - 72, 40, 17, 9, 1, 241, 226, 242, 179, 53, 17, 9, 1, 241, 226, 242, 179, - 40, 17, 9, 1, 241, 226, 242, 179, 65, 17, 9, 1, 241, 226, 242, 179, 147, - 17, 9, 1, 241, 226, 247, 150, 53, 17, 9, 1, 241, 226, 247, 150, 40, 17, - 9, 1, 241, 226, 247, 150, 65, 17, 9, 1, 241, 226, 247, 150, 147, 17, 9, - 1, 77, 252, 141, 53, 17, 9, 1, 77, 252, 141, 40, 17, 9, 1, 77, 252, 141, - 2, 182, 72, 53, 17, 9, 1, 77, 252, 141, 2, 182, 72, 40, 17, 9, 16, 59, - 48, 9, 16, 59, 51, 9, 16, 113, 170, 48, 9, 16, 113, 170, 51, 9, 16, 134, - 170, 48, 9, 16, 134, 170, 51, 9, 16, 134, 170, 225, 10, 246, 112, 48, 9, - 16, 134, 170, 225, 10, 246, 112, 51, 9, 16, 244, 19, 170, 48, 9, 16, 244, - 19, 170, 51, 9, 16, 52, 67, 252, 149, 51, 9, 16, 113, 170, 213, 189, 48, - 9, 16, 113, 170, 213, 189, 51, 9, 16, 222, 236, 9, 16, 4, 217, 82, 48, 9, - 16, 4, 217, 82, 51, 9, 1, 229, 85, 53, 17, 9, 1, 229, 85, 40, 17, 9, 1, - 229, 85, 65, 17, 9, 1, 229, 85, 147, 17, 9, 1, 104, 53, 17, 9, 1, 104, - 40, 17, 9, 1, 226, 239, 53, 17, 9, 1, 226, 239, 40, 17, 9, 1, 210, 213, - 53, 17, 9, 1, 210, 213, 40, 17, 9, 1, 104, 2, 182, 72, 53, 17, 9, 1, 214, - 0, 53, 17, 9, 1, 214, 0, 40, 17, 9, 1, 234, 79, 226, 239, 53, 17, 9, 1, - 234, 79, 226, 239, 40, 17, 9, 1, 234, 79, 210, 213, 53, 17, 9, 1, 234, - 79, 210, 213, 40, 17, 9, 1, 160, 53, 17, 9, 1, 160, 40, 17, 9, 1, 160, - 65, 17, 9, 1, 160, 147, 17, 9, 1, 214, 207, 234, 192, 234, 79, 109, 231, - 198, 65, 17, 9, 1, 214, 207, 234, 192, 234, 79, 109, 231, 198, 147, 17, - 9, 27, 77, 2, 182, 72, 2, 109, 53, 17, 9, 27, 77, 2, 182, 72, 2, 109, 40, - 17, 9, 27, 77, 2, 182, 72, 2, 254, 253, 53, 17, 9, 27, 77, 2, 182, 72, 2, - 254, 253, 40, 17, 9, 27, 77, 2, 182, 72, 2, 212, 31, 53, 17, 9, 27, 77, - 2, 182, 72, 2, 212, 31, 40, 17, 9, 27, 77, 2, 182, 72, 2, 104, 53, 17, 9, - 27, 77, 2, 182, 72, 2, 104, 40, 17, 9, 27, 77, 2, 182, 72, 2, 226, 239, - 53, 17, 9, 27, 77, 2, 182, 72, 2, 226, 239, 40, 17, 9, 27, 77, 2, 182, - 72, 2, 210, 213, 53, 17, 9, 27, 77, 2, 182, 72, 2, 210, 213, 40, 17, 9, - 27, 77, 2, 182, 72, 2, 160, 53, 17, 9, 27, 77, 2, 182, 72, 2, 160, 40, - 17, 9, 27, 77, 2, 182, 72, 2, 160, 65, 17, 9, 27, 214, 207, 234, 79, 77, - 2, 182, 72, 2, 109, 231, 198, 53, 17, 9, 27, 214, 207, 234, 79, 77, 2, - 182, 72, 2, 109, 231, 198, 40, 17, 9, 27, 214, 207, 234, 79, 77, 2, 182, - 72, 2, 109, 231, 198, 65, 17, 9, 1, 244, 176, 77, 53, 17, 9, 1, 244, 176, - 77, 40, 17, 9, 1, 244, 176, 77, 65, 17, 9, 1, 244, 176, 77, 147, 17, 9, - 27, 77, 2, 182, 72, 2, 151, 53, 17, 9, 27, 77, 2, 182, 72, 2, 122, 53, - 17, 9, 27, 77, 2, 182, 72, 2, 66, 53, 17, 9, 27, 77, 2, 182, 72, 2, 109, - 231, 198, 53, 17, 9, 27, 77, 2, 182, 72, 2, 77, 53, 17, 9, 27, 252, 63, - 2, 151, 53, 17, 9, 27, 252, 63, 2, 122, 53, 17, 9, 27, 252, 63, 2, 234, - 136, 53, 17, 9, 27, 252, 63, 2, 66, 53, 17, 9, 27, 252, 63, 2, 109, 231, - 198, 53, 17, 9, 27, 252, 63, 2, 77, 53, 17, 9, 27, 217, 9, 2, 151, 53, - 17, 9, 27, 217, 9, 2, 122, 53, 17, 9, 27, 217, 9, 2, 234, 136, 53, 17, 9, - 27, 217, 9, 2, 66, 53, 17, 9, 27, 217, 9, 2, 109, 231, 198, 53, 17, 9, - 27, 217, 9, 2, 77, 53, 17, 9, 27, 216, 194, 2, 151, 53, 17, 9, 27, 216, - 194, 2, 66, 53, 17, 9, 27, 216, 194, 2, 109, 231, 198, 53, 17, 9, 27, - 216, 194, 2, 77, 53, 17, 9, 27, 151, 2, 122, 53, 17, 9, 27, 151, 2, 66, - 53, 17, 9, 27, 122, 2, 151, 53, 17, 9, 27, 122, 2, 66, 53, 17, 9, 27, - 234, 136, 2, 151, 53, 17, 9, 27, 234, 136, 2, 122, 53, 17, 9, 27, 234, - 136, 2, 66, 53, 17, 9, 27, 221, 169, 2, 151, 53, 17, 9, 27, 221, 169, 2, - 122, 53, 17, 9, 27, 221, 169, 2, 234, 136, 53, 17, 9, 27, 221, 169, 2, - 66, 53, 17, 9, 27, 222, 29, 2, 122, 53, 17, 9, 27, 222, 29, 2, 66, 53, - 17, 9, 27, 248, 225, 2, 151, 53, 17, 9, 27, 248, 225, 2, 122, 53, 17, 9, - 27, 248, 225, 2, 234, 136, 53, 17, 9, 27, 248, 225, 2, 66, 53, 17, 9, 27, - 217, 82, 2, 122, 53, 17, 9, 27, 217, 82, 2, 66, 53, 17, 9, 27, 210, 112, - 2, 66, 53, 17, 9, 27, 254, 206, 2, 151, 53, 17, 9, 27, 254, 206, 2, 66, - 53, 17, 9, 27, 242, 252, 2, 151, 53, 17, 9, 27, 242, 252, 2, 66, 53, 17, - 9, 27, 244, 151, 2, 151, 53, 17, 9, 27, 244, 151, 2, 122, 53, 17, 9, 27, - 244, 151, 2, 234, 136, 53, 17, 9, 27, 244, 151, 2, 66, 53, 17, 9, 27, - 244, 151, 2, 109, 231, 198, 53, 17, 9, 27, 244, 151, 2, 77, 53, 17, 9, - 27, 224, 85, 2, 122, 53, 17, 9, 27, 224, 85, 2, 66, 53, 17, 9, 27, 224, - 85, 2, 109, 231, 198, 53, 17, 9, 27, 224, 85, 2, 77, 53, 17, 9, 27, 235, - 1, 2, 109, 53, 17, 9, 27, 235, 1, 2, 151, 53, 17, 9, 27, 235, 1, 2, 122, - 53, 17, 9, 27, 235, 1, 2, 234, 136, 53, 17, 9, 27, 235, 1, 2, 233, 109, - 53, 17, 9, 27, 235, 1, 2, 66, 53, 17, 9, 27, 235, 1, 2, 109, 231, 198, - 53, 17, 9, 27, 235, 1, 2, 77, 53, 17, 9, 27, 233, 109, 2, 151, 53, 17, 9, - 27, 233, 109, 2, 122, 53, 17, 9, 27, 233, 109, 2, 234, 136, 53, 17, 9, - 27, 233, 109, 2, 66, 53, 17, 9, 27, 233, 109, 2, 109, 231, 198, 53, 17, - 9, 27, 233, 109, 2, 77, 53, 17, 9, 27, 66, 2, 151, 53, 17, 9, 27, 66, 2, - 122, 53, 17, 9, 27, 66, 2, 234, 136, 53, 17, 9, 27, 66, 2, 66, 53, 17, 9, - 27, 66, 2, 109, 231, 198, 53, 17, 9, 27, 66, 2, 77, 53, 17, 9, 27, 228, - 68, 2, 151, 53, 17, 9, 27, 228, 68, 2, 122, 53, 17, 9, 27, 228, 68, 2, - 234, 136, 53, 17, 9, 27, 228, 68, 2, 66, 53, 17, 9, 27, 228, 68, 2, 109, - 231, 198, 53, 17, 9, 27, 228, 68, 2, 77, 53, 17, 9, 27, 241, 226, 2, 151, - 53, 17, 9, 27, 241, 226, 2, 66, 53, 17, 9, 27, 241, 226, 2, 109, 231, - 198, 53, 17, 9, 27, 241, 226, 2, 77, 53, 17, 9, 27, 77, 2, 151, 53, 17, - 9, 27, 77, 2, 122, 53, 17, 9, 27, 77, 2, 234, 136, 53, 17, 9, 27, 77, 2, - 66, 53, 17, 9, 27, 77, 2, 109, 231, 198, 53, 17, 9, 27, 77, 2, 77, 53, - 17, 9, 27, 216, 204, 2, 218, 24, 109, 53, 17, 9, 27, 223, 99, 2, 218, 24, - 109, 53, 17, 9, 27, 109, 231, 198, 2, 218, 24, 109, 53, 17, 9, 27, 220, - 96, 2, 248, 191, 53, 17, 9, 27, 220, 96, 2, 234, 210, 53, 17, 9, 27, 220, - 96, 2, 244, 174, 53, 17, 9, 27, 220, 96, 2, 248, 193, 53, 17, 9, 27, 220, - 96, 2, 234, 212, 53, 17, 9, 27, 220, 96, 2, 218, 24, 109, 53, 17, 9, 27, - 77, 2, 182, 72, 2, 223, 99, 40, 17, 9, 27, 77, 2, 182, 72, 2, 210, 109, - 40, 17, 9, 27, 77, 2, 182, 72, 2, 66, 40, 17, 9, 27, 77, 2, 182, 72, 2, - 228, 68, 40, 17, 9, 27, 77, 2, 182, 72, 2, 109, 231, 198, 40, 17, 9, 27, - 77, 2, 182, 72, 2, 77, 40, 17, 9, 27, 252, 63, 2, 223, 99, 40, 17, 9, 27, - 252, 63, 2, 210, 109, 40, 17, 9, 27, 252, 63, 2, 66, 40, 17, 9, 27, 252, - 63, 2, 228, 68, 40, 17, 9, 27, 252, 63, 2, 109, 231, 198, 40, 17, 9, 27, - 252, 63, 2, 77, 40, 17, 9, 27, 217, 9, 2, 223, 99, 40, 17, 9, 27, 217, 9, - 2, 210, 109, 40, 17, 9, 27, 217, 9, 2, 66, 40, 17, 9, 27, 217, 9, 2, 228, - 68, 40, 17, 9, 27, 217, 9, 2, 109, 231, 198, 40, 17, 9, 27, 217, 9, 2, - 77, 40, 17, 9, 27, 216, 194, 2, 223, 99, 40, 17, 9, 27, 216, 194, 2, 210, - 109, 40, 17, 9, 27, 216, 194, 2, 66, 40, 17, 9, 27, 216, 194, 2, 228, 68, - 40, 17, 9, 27, 216, 194, 2, 109, 231, 198, 40, 17, 9, 27, 216, 194, 2, - 77, 40, 17, 9, 27, 244, 151, 2, 109, 231, 198, 40, 17, 9, 27, 244, 151, - 2, 77, 40, 17, 9, 27, 224, 85, 2, 109, 231, 198, 40, 17, 9, 27, 224, 85, - 2, 77, 40, 17, 9, 27, 235, 1, 2, 109, 40, 17, 9, 27, 235, 1, 2, 233, 109, - 40, 17, 9, 27, 235, 1, 2, 66, 40, 17, 9, 27, 235, 1, 2, 109, 231, 198, - 40, 17, 9, 27, 235, 1, 2, 77, 40, 17, 9, 27, 233, 109, 2, 66, 40, 17, 9, - 27, 233, 109, 2, 109, 231, 198, 40, 17, 9, 27, 233, 109, 2, 77, 40, 17, - 9, 27, 66, 2, 109, 40, 17, 9, 27, 66, 2, 66, 40, 17, 9, 27, 228, 68, 2, - 223, 99, 40, 17, 9, 27, 228, 68, 2, 210, 109, 40, 17, 9, 27, 228, 68, 2, - 66, 40, 17, 9, 27, 228, 68, 2, 228, 68, 40, 17, 9, 27, 228, 68, 2, 109, - 231, 198, 40, 17, 9, 27, 228, 68, 2, 77, 40, 17, 9, 27, 109, 231, 198, 2, - 218, 24, 109, 40, 17, 9, 27, 77, 2, 223, 99, 40, 17, 9, 27, 77, 2, 210, - 109, 40, 17, 9, 27, 77, 2, 66, 40, 17, 9, 27, 77, 2, 228, 68, 40, 17, 9, - 27, 77, 2, 109, 231, 198, 40, 17, 9, 27, 77, 2, 77, 40, 17, 9, 27, 77, 2, - 182, 72, 2, 151, 65, 17, 9, 27, 77, 2, 182, 72, 2, 122, 65, 17, 9, 27, - 77, 2, 182, 72, 2, 234, 136, 65, 17, 9, 27, 77, 2, 182, 72, 2, 66, 65, - 17, 9, 27, 77, 2, 182, 72, 2, 241, 226, 65, 17, 9, 27, 252, 63, 2, 151, - 65, 17, 9, 27, 252, 63, 2, 122, 65, 17, 9, 27, 252, 63, 2, 234, 136, 65, - 17, 9, 27, 252, 63, 2, 66, 65, 17, 9, 27, 252, 63, 2, 241, 226, 65, 17, - 9, 27, 217, 9, 2, 151, 65, 17, 9, 27, 217, 9, 2, 122, 65, 17, 9, 27, 217, - 9, 2, 234, 136, 65, 17, 9, 27, 217, 9, 2, 66, 65, 17, 9, 27, 217, 9, 2, - 241, 226, 65, 17, 9, 27, 216, 194, 2, 66, 65, 17, 9, 27, 151, 2, 122, 65, - 17, 9, 27, 151, 2, 66, 65, 17, 9, 27, 122, 2, 151, 65, 17, 9, 27, 122, 2, - 66, 65, 17, 9, 27, 234, 136, 2, 151, 65, 17, 9, 27, 234, 136, 2, 66, 65, - 17, 9, 27, 221, 169, 2, 151, 65, 17, 9, 27, 221, 169, 2, 122, 65, 17, 9, - 27, 221, 169, 2, 234, 136, 65, 17, 9, 27, 221, 169, 2, 66, 65, 17, 9, 27, - 222, 29, 2, 122, 65, 17, 9, 27, 222, 29, 2, 234, 136, 65, 17, 9, 27, 222, - 29, 2, 66, 65, 17, 9, 27, 248, 225, 2, 151, 65, 17, 9, 27, 248, 225, 2, - 122, 65, 17, 9, 27, 248, 225, 2, 234, 136, 65, 17, 9, 27, 248, 225, 2, - 66, 65, 17, 9, 27, 217, 82, 2, 122, 65, 17, 9, 27, 210, 112, 2, 66, 65, - 17, 9, 27, 254, 206, 2, 151, 65, 17, 9, 27, 254, 206, 2, 66, 65, 17, 9, - 27, 242, 252, 2, 151, 65, 17, 9, 27, 242, 252, 2, 66, 65, 17, 9, 27, 244, - 151, 2, 151, 65, 17, 9, 27, 244, 151, 2, 122, 65, 17, 9, 27, 244, 151, 2, - 234, 136, 65, 17, 9, 27, 244, 151, 2, 66, 65, 17, 9, 27, 224, 85, 2, 122, - 65, 17, 9, 27, 224, 85, 2, 66, 65, 17, 9, 27, 235, 1, 2, 151, 65, 17, 9, - 27, 235, 1, 2, 122, 65, 17, 9, 27, 235, 1, 2, 234, 136, 65, 17, 9, 27, - 235, 1, 2, 233, 109, 65, 17, 9, 27, 235, 1, 2, 66, 65, 17, 9, 27, 233, - 109, 2, 151, 65, 17, 9, 27, 233, 109, 2, 122, 65, 17, 9, 27, 233, 109, 2, - 234, 136, 65, 17, 9, 27, 233, 109, 2, 66, 65, 17, 9, 27, 233, 109, 2, - 241, 226, 65, 17, 9, 27, 66, 2, 151, 65, 17, 9, 27, 66, 2, 122, 65, 17, - 9, 27, 66, 2, 234, 136, 65, 17, 9, 27, 66, 2, 66, 65, 17, 9, 27, 228, 68, - 2, 151, 65, 17, 9, 27, 228, 68, 2, 122, 65, 17, 9, 27, 228, 68, 2, 234, - 136, 65, 17, 9, 27, 228, 68, 2, 66, 65, 17, 9, 27, 228, 68, 2, 241, 226, - 65, 17, 9, 27, 241, 226, 2, 151, 65, 17, 9, 27, 241, 226, 2, 66, 65, 17, - 9, 27, 241, 226, 2, 218, 24, 109, 65, 17, 9, 27, 77, 2, 151, 65, 17, 9, - 27, 77, 2, 122, 65, 17, 9, 27, 77, 2, 234, 136, 65, 17, 9, 27, 77, 2, 66, - 65, 17, 9, 27, 77, 2, 241, 226, 65, 17, 9, 27, 77, 2, 182, 72, 2, 66, - 147, 17, 9, 27, 77, 2, 182, 72, 2, 241, 226, 147, 17, 9, 27, 252, 63, 2, - 66, 147, 17, 9, 27, 252, 63, 2, 241, 226, 147, 17, 9, 27, 217, 9, 2, 66, - 147, 17, 9, 27, 217, 9, 2, 241, 226, 147, 17, 9, 27, 216, 194, 2, 66, - 147, 17, 9, 27, 216, 194, 2, 241, 226, 147, 17, 9, 27, 221, 169, 2, 66, - 147, 17, 9, 27, 221, 169, 2, 241, 226, 147, 17, 9, 27, 220, 62, 2, 66, - 147, 17, 9, 27, 220, 62, 2, 241, 226, 147, 17, 9, 27, 235, 1, 2, 233, - 109, 147, 17, 9, 27, 235, 1, 2, 66, 147, 17, 9, 27, 233, 109, 2, 66, 147, - 17, 9, 27, 228, 68, 2, 66, 147, 17, 9, 27, 228, 68, 2, 241, 226, 147, 17, - 9, 27, 77, 2, 66, 147, 17, 9, 27, 77, 2, 241, 226, 147, 17, 9, 27, 220, - 96, 2, 244, 174, 147, 17, 9, 27, 220, 96, 2, 248, 193, 147, 17, 9, 27, - 220, 96, 2, 234, 212, 147, 17, 9, 27, 217, 82, 2, 109, 231, 198, 53, 17, - 9, 27, 217, 82, 2, 77, 53, 17, 9, 27, 254, 206, 2, 109, 231, 198, 53, 17, - 9, 27, 254, 206, 2, 77, 53, 17, 9, 27, 242, 252, 2, 109, 231, 198, 53, - 17, 9, 27, 242, 252, 2, 77, 53, 17, 9, 27, 221, 169, 2, 109, 231, 198, - 53, 17, 9, 27, 221, 169, 2, 77, 53, 17, 9, 27, 220, 62, 2, 109, 231, 198, - 53, 17, 9, 27, 220, 62, 2, 77, 53, 17, 9, 27, 122, 2, 109, 231, 198, 53, - 17, 9, 27, 122, 2, 77, 53, 17, 9, 27, 151, 2, 109, 231, 198, 53, 17, 9, - 27, 151, 2, 77, 53, 17, 9, 27, 234, 136, 2, 109, 231, 198, 53, 17, 9, 27, - 234, 136, 2, 77, 53, 17, 9, 27, 222, 29, 2, 109, 231, 198, 53, 17, 9, 27, - 222, 29, 2, 77, 53, 17, 9, 27, 248, 225, 2, 109, 231, 198, 53, 17, 9, 27, - 248, 225, 2, 77, 53, 17, 9, 27, 220, 62, 2, 151, 53, 17, 9, 27, 220, 62, - 2, 122, 53, 17, 9, 27, 220, 62, 2, 234, 136, 53, 17, 9, 27, 220, 62, 2, - 66, 53, 17, 9, 27, 220, 62, 2, 223, 99, 53, 17, 9, 27, 221, 169, 2, 223, - 99, 53, 17, 9, 27, 222, 29, 2, 223, 99, 53, 17, 9, 27, 248, 225, 2, 223, - 99, 53, 17, 9, 27, 217, 82, 2, 109, 231, 198, 40, 17, 9, 27, 217, 82, 2, - 77, 40, 17, 9, 27, 254, 206, 2, 109, 231, 198, 40, 17, 9, 27, 254, 206, - 2, 77, 40, 17, 9, 27, 242, 252, 2, 109, 231, 198, 40, 17, 9, 27, 242, - 252, 2, 77, 40, 17, 9, 27, 221, 169, 2, 109, 231, 198, 40, 17, 9, 27, - 221, 169, 2, 77, 40, 17, 9, 27, 220, 62, 2, 109, 231, 198, 40, 17, 9, 27, - 220, 62, 2, 77, 40, 17, 9, 27, 122, 2, 109, 231, 198, 40, 17, 9, 27, 122, - 2, 77, 40, 17, 9, 27, 151, 2, 109, 231, 198, 40, 17, 9, 27, 151, 2, 77, - 40, 17, 9, 27, 234, 136, 2, 109, 231, 198, 40, 17, 9, 27, 234, 136, 2, - 77, 40, 17, 9, 27, 222, 29, 2, 109, 231, 198, 40, 17, 9, 27, 222, 29, 2, - 77, 40, 17, 9, 27, 248, 225, 2, 109, 231, 198, 40, 17, 9, 27, 248, 225, - 2, 77, 40, 17, 9, 27, 220, 62, 2, 151, 40, 17, 9, 27, 220, 62, 2, 122, - 40, 17, 9, 27, 220, 62, 2, 234, 136, 40, 17, 9, 27, 220, 62, 2, 66, 40, - 17, 9, 27, 220, 62, 2, 223, 99, 40, 17, 9, 27, 221, 169, 2, 223, 99, 40, - 17, 9, 27, 222, 29, 2, 223, 99, 40, 17, 9, 27, 248, 225, 2, 223, 99, 40, - 17, 9, 27, 220, 62, 2, 151, 65, 17, 9, 27, 220, 62, 2, 122, 65, 17, 9, - 27, 220, 62, 2, 234, 136, 65, 17, 9, 27, 220, 62, 2, 66, 65, 17, 9, 27, - 221, 169, 2, 241, 226, 65, 17, 9, 27, 220, 62, 2, 241, 226, 65, 17, 9, - 27, 217, 82, 2, 66, 65, 17, 9, 27, 221, 169, 2, 151, 147, 17, 9, 27, 221, - 169, 2, 122, 147, 17, 9, 27, 221, 169, 2, 234, 136, 147, 17, 9, 27, 220, - 62, 2, 151, 147, 17, 9, 27, 220, 62, 2, 122, 147, 17, 9, 27, 220, 62, 2, - 234, 136, 147, 17, 9, 27, 217, 82, 2, 66, 147, 17, 9, 27, 210, 112, 2, - 66, 147, 17, 9, 27, 109, 2, 244, 172, 40, 17, 9, 27, 109, 2, 244, 172, - 53, 17, 226, 150, 43, 226, 7, 226, 150, 44, 226, 7, 9, 27, 217, 9, 2, - 151, 2, 66, 65, 17, 9, 27, 217, 9, 2, 122, 2, 151, 40, 17, 9, 27, 217, 9, - 2, 122, 2, 151, 65, 17, 9, 27, 217, 9, 2, 122, 2, 66, 65, 17, 9, 27, 217, - 9, 2, 234, 136, 2, 66, 65, 17, 9, 27, 217, 9, 2, 66, 2, 151, 65, 17, 9, - 27, 217, 9, 2, 66, 2, 122, 65, 17, 9, 27, 217, 9, 2, 66, 2, 234, 136, 65, - 17, 9, 27, 151, 2, 66, 2, 122, 40, 17, 9, 27, 151, 2, 66, 2, 122, 65, 17, - 9, 27, 122, 2, 66, 2, 77, 40, 17, 9, 27, 122, 2, 66, 2, 109, 231, 198, - 40, 17, 9, 27, 221, 169, 2, 122, 2, 151, 65, 17, 9, 27, 221, 169, 2, 151, - 2, 122, 65, 17, 9, 27, 221, 169, 2, 151, 2, 109, 231, 198, 40, 17, 9, 27, - 221, 169, 2, 66, 2, 122, 40, 17, 9, 27, 221, 169, 2, 66, 2, 122, 65, 17, - 9, 27, 221, 169, 2, 66, 2, 151, 65, 17, 9, 27, 221, 169, 2, 66, 2, 66, - 40, 17, 9, 27, 221, 169, 2, 66, 2, 66, 65, 17, 9, 27, 222, 29, 2, 122, 2, - 122, 40, 17, 9, 27, 222, 29, 2, 122, 2, 122, 65, 17, 9, 27, 222, 29, 2, - 66, 2, 66, 40, 17, 9, 27, 220, 62, 2, 122, 2, 66, 40, 17, 9, 27, 220, 62, - 2, 122, 2, 66, 65, 17, 9, 27, 220, 62, 2, 151, 2, 77, 40, 17, 9, 27, 220, - 62, 2, 66, 2, 234, 136, 40, 17, 9, 27, 220, 62, 2, 66, 2, 234, 136, 65, - 17, 9, 27, 220, 62, 2, 66, 2, 66, 40, 17, 9, 27, 220, 62, 2, 66, 2, 66, - 65, 17, 9, 27, 248, 225, 2, 122, 2, 109, 231, 198, 40, 17, 9, 27, 248, - 225, 2, 234, 136, 2, 66, 40, 17, 9, 27, 248, 225, 2, 234, 136, 2, 66, 65, - 17, 9, 27, 217, 82, 2, 66, 2, 122, 40, 17, 9, 27, 217, 82, 2, 66, 2, 122, - 65, 17, 9, 27, 217, 82, 2, 66, 2, 66, 65, 17, 9, 27, 217, 82, 2, 66, 2, - 77, 40, 17, 9, 27, 254, 206, 2, 151, 2, 66, 40, 17, 9, 27, 254, 206, 2, - 66, 2, 66, 40, 17, 9, 27, 254, 206, 2, 66, 2, 66, 65, 17, 9, 27, 254, - 206, 2, 66, 2, 109, 231, 198, 40, 17, 9, 27, 242, 252, 2, 66, 2, 66, 40, - 17, 9, 27, 242, 252, 2, 66, 2, 77, 40, 17, 9, 27, 242, 252, 2, 66, 2, - 109, 231, 198, 40, 17, 9, 27, 244, 151, 2, 234, 136, 2, 66, 40, 17, 9, - 27, 244, 151, 2, 234, 136, 2, 66, 65, 17, 9, 27, 224, 85, 2, 66, 2, 122, - 40, 17, 9, 27, 224, 85, 2, 66, 2, 66, 40, 17, 9, 27, 233, 109, 2, 122, 2, - 66, 40, 17, 9, 27, 233, 109, 2, 122, 2, 77, 40, 17, 9, 27, 233, 109, 2, - 122, 2, 109, 231, 198, 40, 17, 9, 27, 233, 109, 2, 151, 2, 151, 65, 17, - 9, 27, 233, 109, 2, 151, 2, 151, 40, 17, 9, 27, 233, 109, 2, 234, 136, 2, - 66, 40, 17, 9, 27, 233, 109, 2, 234, 136, 2, 66, 65, 17, 9, 27, 233, 109, - 2, 66, 2, 122, 40, 17, 9, 27, 233, 109, 2, 66, 2, 122, 65, 17, 9, 27, 66, - 2, 122, 2, 151, 65, 17, 9, 27, 66, 2, 122, 2, 66, 65, 17, 9, 27, 66, 2, - 122, 2, 77, 40, 17, 9, 27, 66, 2, 151, 2, 122, 65, 17, 9, 27, 66, 2, 151, - 2, 66, 65, 17, 9, 27, 66, 2, 234, 136, 2, 151, 65, 17, 9, 27, 66, 2, 234, - 136, 2, 66, 65, 17, 9, 27, 66, 2, 151, 2, 234, 136, 65, 17, 9, 27, 241, - 226, 2, 66, 2, 151, 65, 17, 9, 27, 241, 226, 2, 66, 2, 66, 65, 17, 9, 27, - 228, 68, 2, 122, 2, 66, 65, 17, 9, 27, 228, 68, 2, 122, 2, 109, 231, 198, - 40, 17, 9, 27, 228, 68, 2, 151, 2, 66, 40, 17, 9, 27, 228, 68, 2, 151, 2, - 66, 65, 17, 9, 27, 228, 68, 2, 151, 2, 109, 231, 198, 40, 17, 9, 27, 228, - 68, 2, 66, 2, 77, 40, 17, 9, 27, 228, 68, 2, 66, 2, 109, 231, 198, 40, - 17, 9, 27, 77, 2, 66, 2, 66, 40, 17, 9, 27, 77, 2, 66, 2, 66, 65, 17, 9, - 27, 252, 63, 2, 234, 136, 2, 77, 40, 17, 9, 27, 217, 9, 2, 151, 2, 77, - 40, 17, 9, 27, 217, 9, 2, 151, 2, 109, 231, 198, 40, 17, 9, 27, 217, 9, - 2, 234, 136, 2, 77, 40, 17, 9, 27, 217, 9, 2, 234, 136, 2, 109, 231, 198, - 40, 17, 9, 27, 217, 9, 2, 66, 2, 77, 40, 17, 9, 27, 217, 9, 2, 66, 2, - 109, 231, 198, 40, 17, 9, 27, 151, 2, 66, 2, 77, 40, 17, 9, 27, 151, 2, - 122, 2, 109, 231, 198, 40, 17, 9, 27, 151, 2, 66, 2, 109, 231, 198, 40, - 17, 9, 27, 221, 169, 2, 234, 136, 2, 109, 231, 198, 40, 17, 9, 27, 222, - 29, 2, 122, 2, 77, 40, 17, 9, 27, 220, 62, 2, 122, 2, 77, 40, 17, 9, 27, - 248, 225, 2, 122, 2, 77, 40, 17, 9, 27, 233, 109, 2, 151, 2, 77, 40, 17, - 9, 27, 233, 109, 2, 66, 2, 77, 40, 17, 9, 27, 77, 2, 122, 2, 77, 40, 17, - 9, 27, 77, 2, 151, 2, 77, 40, 17, 9, 27, 77, 2, 66, 2, 77, 40, 17, 9, 27, - 66, 2, 66, 2, 77, 40, 17, 9, 27, 224, 85, 2, 66, 2, 77, 40, 17, 9, 27, - 228, 68, 2, 122, 2, 77, 40, 17, 9, 27, 224, 85, 2, 66, 2, 122, 65, 17, 9, - 27, 233, 109, 2, 122, 2, 66, 65, 17, 9, 27, 254, 206, 2, 66, 2, 77, 40, - 17, 9, 27, 235, 1, 2, 66, 2, 77, 40, 17, 9, 27, 228, 68, 2, 151, 2, 122, - 65, 17, 9, 27, 66, 2, 234, 136, 2, 77, 40, 17, 9, 27, 233, 109, 2, 151, - 2, 66, 65, 17, 9, 27, 235, 1, 2, 66, 2, 66, 40, 17, 9, 27, 233, 109, 2, - 151, 2, 66, 40, 17, 9, 27, 228, 68, 2, 151, 2, 122, 40, 17, 9, 27, 151, - 2, 122, 2, 77, 40, 17, 9, 27, 122, 2, 151, 2, 77, 40, 17, 9, 27, 66, 2, - 151, 2, 77, 40, 17, 9, 27, 244, 151, 2, 66, 2, 77, 40, 17, 9, 27, 252, - 63, 2, 122, 2, 77, 40, 17, 9, 27, 235, 1, 2, 66, 2, 66, 65, 17, 9, 27, - 254, 206, 2, 151, 2, 66, 65, 17, 9, 27, 222, 29, 2, 66, 2, 66, 65, 17, 9, - 27, 221, 169, 2, 234, 136, 2, 77, 40, 17, 9, 27, 228, 68, 2, 151, 2, 77, - 40, 17, 9, 27, 222, 6, 214, 128, 253, 246, 234, 10, 218, 132, 5, 53, 17, - 9, 27, 224, 81, 214, 128, 253, 246, 234, 10, 218, 132, 5, 53, 17, 9, 27, - 254, 162, 53, 17, 9, 27, 254, 192, 53, 17, 9, 27, 230, 158, 53, 17, 9, - 27, 222, 7, 53, 17, 9, 27, 223, 146, 53, 17, 9, 27, 254, 181, 53, 17, 9, - 27, 212, 49, 53, 17, 9, 27, 222, 6, 53, 17, 9, 27, 222, 5, 254, 181, 212, - 48, 9, 27, 235, 140, 223, 37, 50, 9, 27, 251, 238, 254, 47, 254, 48, 45, - 221, 158, 45, 221, 47, 45, 220, 235, 45, 220, 224, 45, 220, 213, 45, 220, - 202, 45, 220, 191, 45, 220, 180, 45, 220, 169, 45, 221, 157, 45, 221, - 146, 45, 221, 135, 45, 221, 124, 45, 221, 113, 45, 221, 102, 45, 221, 91, - 224, 197, 244, 28, 31, 67, 249, 227, 224, 197, 244, 28, 31, 67, 110, 249, - 227, 224, 197, 244, 28, 31, 67, 110, 243, 236, 218, 131, 224, 197, 244, - 28, 31, 67, 249, 234, 224, 197, 244, 28, 31, 67, 220, 152, 224, 197, 244, - 28, 31, 67, 245, 39, 79, 224, 197, 244, 28, 31, 67, 224, 16, 79, 224, - 197, 244, 28, 31, 67, 43, 71, 233, 26, 127, 224, 197, 244, 28, 31, 67, - 44, 71, 233, 26, 251, 164, 224, 197, 244, 28, 31, 67, 203, 245, 171, 38, - 27, 43, 242, 34, 38, 27, 44, 242, 34, 38, 52, 216, 90, 43, 242, 34, 38, - 52, 216, 90, 44, 242, 34, 38, 231, 238, 43, 242, 34, 38, 231, 238, 44, - 242, 34, 38, 249, 205, 231, 237, 224, 197, 244, 28, 31, 67, 113, 59, 233, - 62, 224, 197, 244, 28, 31, 67, 245, 168, 248, 164, 224, 197, 244, 28, 31, - 67, 245, 159, 248, 164, 224, 197, 244, 28, 31, 67, 121, 232, 219, 224, - 197, 244, 28, 31, 67, 212, 32, 121, 232, 219, 224, 197, 244, 28, 31, 67, - 43, 226, 7, 224, 197, 244, 28, 31, 67, 44, 226, 7, 224, 197, 244, 28, 31, - 67, 43, 249, 107, 127, 224, 197, 244, 28, 31, 67, 44, 249, 107, 127, 224, - 197, 244, 28, 31, 67, 43, 216, 7, 220, 55, 127, 224, 197, 244, 28, 31, - 67, 44, 216, 7, 220, 55, 127, 224, 197, 244, 28, 31, 67, 43, 85, 233, 26, - 127, 224, 197, 244, 28, 31, 67, 44, 85, 233, 26, 127, 224, 197, 244, 28, - 31, 67, 43, 52, 254, 118, 127, 224, 197, 244, 28, 31, 67, 44, 52, 254, - 118, 127, 224, 197, 244, 28, 31, 67, 43, 254, 118, 127, 224, 197, 244, - 28, 31, 67, 44, 254, 118, 127, 224, 197, 244, 28, 31, 67, 43, 249, 169, - 127, 224, 197, 244, 28, 31, 67, 44, 249, 169, 127, 224, 197, 244, 28, 31, - 67, 43, 71, 249, 169, 127, 224, 197, 244, 28, 31, 67, 44, 71, 249, 169, - 127, 220, 133, 247, 128, 71, 220, 133, 247, 128, 224, 197, 244, 28, 31, - 67, 43, 42, 127, 224, 197, 244, 28, 31, 67, 44, 42, 127, 248, 163, 226, - 123, 250, 180, 226, 123, 212, 32, 226, 123, 52, 212, 32, 226, 123, 248, - 163, 121, 232, 219, 250, 180, 121, 232, 219, 212, 32, 121, 232, 219, 4, - 249, 227, 4, 110, 249, 227, 4, 243, 236, 218, 131, 4, 220, 152, 4, 249, - 234, 4, 224, 16, 79, 4, 245, 39, 79, 4, 245, 168, 248, 164, 4, 43, 226, - 7, 4, 44, 226, 7, 4, 43, 249, 107, 127, 4, 44, 249, 107, 127, 4, 43, 216, - 7, 220, 55, 127, 4, 44, 216, 7, 220, 55, 127, 4, 54, 50, 4, 254, 134, 4, - 253, 224, 4, 96, 50, 4, 240, 174, 4, 233, 21, 50, 4, 242, 137, 50, 4, - 245, 106, 50, 4, 223, 53, 219, 48, 4, 247, 140, 50, 4, 225, 185, 50, 4, - 249, 225, 253, 214, 9, 244, 172, 53, 17, 9, 217, 45, 2, 244, 172, 48, 9, - 248, 191, 53, 17, 9, 217, 79, 244, 9, 9, 234, 210, 53, 17, 9, 244, 174, - 53, 17, 9, 244, 174, 147, 17, 9, 248, 193, 53, 17, 9, 248, 193, 147, 17, - 9, 234, 212, 53, 17, 9, 234, 212, 147, 17, 9, 220, 96, 53, 17, 9, 220, - 96, 147, 17, 9, 218, 47, 53, 17, 9, 218, 47, 147, 17, 9, 1, 182, 53, 17, - 9, 1, 109, 2, 231, 233, 72, 53, 17, 9, 1, 109, 2, 231, 233, 72, 40, 17, - 9, 1, 109, 2, 182, 72, 53, 17, 9, 1, 109, 2, 182, 72, 40, 17, 9, 1, 212, - 31, 2, 182, 72, 53, 17, 9, 1, 212, 31, 2, 182, 72, 40, 17, 9, 1, 109, 2, - 182, 252, 51, 53, 17, 9, 1, 109, 2, 182, 252, 51, 40, 17, 9, 1, 77, 2, - 182, 72, 53, 17, 9, 1, 77, 2, 182, 72, 40, 17, 9, 1, 77, 2, 182, 72, 65, - 17, 9, 1, 77, 2, 182, 72, 147, 17, 9, 1, 109, 53, 17, 9, 1, 109, 40, 17, - 9, 1, 252, 63, 53, 17, 9, 1, 252, 63, 40, 17, 9, 1, 252, 63, 65, 17, 9, - 1, 252, 63, 147, 17, 9, 1, 217, 9, 231, 170, 53, 17, 9, 1, 217, 9, 231, - 170, 40, 17, 9, 1, 217, 9, 53, 17, 9, 1, 217, 9, 40, 17, 9, 1, 217, 9, - 65, 17, 9, 1, 217, 9, 147, 17, 9, 1, 216, 194, 53, 17, 9, 1, 216, 194, - 40, 17, 9, 1, 216, 194, 65, 17, 9, 1, 216, 194, 147, 17, 9, 1, 151, 53, - 17, 9, 1, 151, 40, 17, 9, 1, 151, 65, 17, 9, 1, 151, 147, 17, 9, 1, 122, - 53, 17, 9, 1, 122, 40, 17, 9, 1, 122, 65, 17, 9, 1, 122, 147, 17, 9, 1, - 234, 136, 53, 17, 9, 1, 234, 136, 40, 17, 9, 1, 234, 136, 65, 17, 9, 1, - 234, 136, 147, 17, 9, 1, 248, 204, 53, 17, 9, 1, 248, 204, 40, 17, 9, 1, - 216, 204, 53, 17, 9, 1, 216, 204, 40, 17, 9, 1, 223, 99, 53, 17, 9, 1, - 223, 99, 40, 17, 9, 1, 210, 109, 53, 17, 9, 1, 210, 109, 40, 17, 9, 1, - 221, 169, 53, 17, 9, 1, 221, 169, 40, 17, 9, 1, 221, 169, 65, 17, 9, 1, - 221, 169, 147, 17, 9, 1, 220, 62, 53, 17, 9, 1, 220, 62, 40, 17, 9, 1, - 220, 62, 65, 17, 9, 1, 220, 62, 147, 17, 9, 1, 222, 29, 53, 17, 9, 1, - 222, 29, 40, 17, 9, 1, 222, 29, 65, 17, 9, 1, 222, 29, 147, 17, 9, 1, - 248, 225, 53, 17, 9, 1, 248, 225, 40, 17, 9, 1, 248, 225, 65, 17, 9, 1, - 248, 225, 147, 17, 9, 1, 217, 82, 53, 17, 9, 1, 217, 82, 40, 17, 9, 1, - 217, 82, 65, 17, 9, 1, 217, 82, 147, 17, 9, 1, 210, 112, 53, 17, 9, 1, - 210, 112, 40, 17, 9, 1, 210, 112, 65, 17, 9, 1, 210, 112, 147, 17, 9, 1, - 254, 206, 53, 17, 9, 1, 254, 206, 40, 17, 9, 1, 254, 206, 65, 17, 9, 1, - 254, 206, 147, 17, 9, 1, 242, 252, 53, 17, 9, 1, 242, 252, 40, 17, 9, 1, - 242, 252, 65, 17, 9, 1, 242, 252, 147, 17, 9, 1, 244, 151, 53, 17, 9, 1, - 244, 151, 40, 17, 9, 1, 244, 151, 65, 17, 9, 1, 244, 151, 147, 17, 9, 1, - 224, 85, 53, 17, 9, 1, 224, 85, 40, 17, 9, 1, 224, 85, 65, 17, 9, 1, 224, - 85, 147, 17, 9, 1, 235, 1, 53, 17, 9, 1, 235, 1, 40, 17, 9, 1, 235, 1, - 65, 17, 9, 1, 235, 1, 147, 17, 9, 1, 233, 109, 53, 17, 9, 1, 233, 109, - 40, 17, 9, 1, 233, 109, 65, 17, 9, 1, 233, 109, 147, 17, 9, 1, 66, 53, - 17, 9, 1, 66, 40, 17, 9, 1, 66, 65, 17, 9, 1, 66, 147, 17, 9, 1, 228, 68, - 53, 17, 9, 1, 228, 68, 40, 17, 9, 1, 228, 68, 65, 17, 9, 1, 228, 68, 147, - 17, 9, 1, 241, 226, 53, 17, 9, 1, 241, 226, 40, 17, 9, 1, 241, 226, 65, - 17, 9, 1, 241, 226, 147, 17, 9, 1, 212, 31, 53, 17, 9, 1, 212, 31, 40, - 17, 9, 1, 109, 231, 198, 53, 17, 9, 1, 109, 231, 198, 40, 17, 9, 1, 77, - 53, 17, 9, 1, 77, 40, 17, 9, 1, 77, 65, 17, 9, 1, 77, 147, 17, 9, 27, - 233, 109, 2, 109, 2, 231, 233, 72, 53, 17, 9, 27, 233, 109, 2, 109, 2, - 231, 233, 72, 40, 17, 9, 27, 233, 109, 2, 109, 2, 182, 72, 53, 17, 9, 27, - 233, 109, 2, 109, 2, 182, 72, 40, 17, 9, 27, 233, 109, 2, 109, 2, 182, - 252, 51, 53, 17, 9, 27, 233, 109, 2, 109, 2, 182, 252, 51, 40, 17, 9, 27, - 233, 109, 2, 109, 53, 17, 9, 27, 233, 109, 2, 109, 40, 17, 210, 87, 211, - 245, 228, 78, 219, 20, 126, 245, 39, 79, 126, 224, 1, 79, 126, 54, 50, - 126, 247, 140, 50, 126, 225, 185, 50, 126, 254, 134, 126, 254, 65, 126, - 43, 226, 7, 126, 44, 226, 7, 126, 253, 224, 126, 96, 50, 126, 249, 227, - 126, 240, 174, 126, 243, 236, 218, 131, 126, 219, 48, 126, 21, 210, 86, - 126, 21, 111, 126, 21, 105, 126, 21, 158, 126, 21, 161, 126, 21, 190, - 126, 21, 195, 126, 21, 199, 126, 21, 196, 126, 21, 201, 126, 249, 234, - 126, 220, 152, 126, 233, 21, 50, 126, 245, 106, 50, 126, 242, 137, 50, - 126, 224, 16, 79, 126, 249, 225, 253, 214, 126, 7, 6, 1, 61, 126, 7, 6, - 1, 253, 166, 126, 7, 6, 1, 251, 74, 126, 7, 6, 1, 249, 68, 126, 7, 6, 1, - 76, 126, 7, 6, 1, 245, 14, 126, 7, 6, 1, 243, 209, 126, 7, 6, 1, 242, 67, - 126, 7, 6, 1, 74, 126, 7, 6, 1, 235, 150, 126, 7, 6, 1, 235, 29, 126, 7, - 6, 1, 156, 126, 7, 6, 1, 194, 126, 7, 6, 1, 230, 30, 126, 7, 6, 1, 78, - 126, 7, 6, 1, 226, 109, 126, 7, 6, 1, 224, 99, 126, 7, 6, 1, 153, 126, 7, - 6, 1, 222, 93, 126, 7, 6, 1, 217, 153, 126, 7, 6, 1, 69, 126, 7, 6, 1, - 214, 105, 126, 7, 6, 1, 212, 98, 126, 7, 6, 1, 211, 178, 126, 7, 6, 1, - 211, 117, 126, 7, 6, 1, 210, 159, 126, 43, 42, 127, 126, 223, 53, 219, - 48, 126, 44, 42, 127, 126, 250, 39, 255, 23, 126, 121, 232, 219, 126, - 242, 144, 255, 23, 126, 7, 4, 1, 61, 126, 7, 4, 1, 253, 166, 126, 7, 4, - 1, 251, 74, 126, 7, 4, 1, 249, 68, 126, 7, 4, 1, 76, 126, 7, 4, 1, 245, - 14, 126, 7, 4, 1, 243, 209, 126, 7, 4, 1, 242, 67, 126, 7, 4, 1, 74, 126, - 7, 4, 1, 235, 150, 126, 7, 4, 1, 235, 29, 126, 7, 4, 1, 156, 126, 7, 4, - 1, 194, 126, 7, 4, 1, 230, 30, 126, 7, 4, 1, 78, 126, 7, 4, 1, 226, 109, - 126, 7, 4, 1, 224, 99, 126, 7, 4, 1, 153, 126, 7, 4, 1, 222, 93, 126, 7, - 4, 1, 217, 153, 126, 7, 4, 1, 69, 126, 7, 4, 1, 214, 105, 126, 7, 4, 1, - 212, 98, 126, 7, 4, 1, 211, 178, 126, 7, 4, 1, 211, 117, 126, 7, 4, 1, - 210, 159, 126, 43, 249, 107, 127, 126, 67, 232, 219, 126, 44, 249, 107, - 127, 126, 184, 126, 43, 71, 226, 7, 126, 44, 71, 226, 7, 101, 110, 243, - 236, 218, 131, 101, 43, 249, 169, 127, 101, 44, 249, 169, 127, 101, 110, - 249, 227, 101, 56, 230, 229, 247, 128, 101, 56, 1, 211, 227, 101, 56, 1, - 4, 61, 101, 56, 1, 4, 74, 101, 56, 1, 4, 69, 101, 56, 1, 4, 76, 101, 56, - 1, 4, 78, 101, 56, 1, 4, 192, 101, 56, 1, 4, 210, 212, 101, 56, 1, 4, - 210, 244, 101, 56, 1, 4, 215, 119, 101, 234, 207, 224, 176, 219, 33, 79, - 101, 56, 1, 61, 101, 56, 1, 74, 101, 56, 1, 69, 101, 56, 1, 76, 101, 56, - 1, 78, 101, 56, 1, 176, 101, 56, 1, 234, 98, 101, 56, 1, 233, 223, 101, - 56, 1, 234, 188, 101, 56, 1, 234, 34, 101, 56, 1, 206, 101, 56, 1, 219, - 193, 101, 56, 1, 218, 84, 101, 56, 1, 221, 183, 101, 56, 1, 219, 60, 101, - 56, 1, 217, 106, 101, 56, 1, 216, 118, 101, 56, 1, 215, 119, 101, 56, 1, - 217, 23, 101, 56, 1, 112, 101, 56, 1, 198, 101, 56, 1, 228, 238, 101, 56, - 1, 227, 242, 101, 56, 1, 229, 112, 101, 56, 1, 228, 79, 101, 56, 1, 162, - 101, 56, 1, 241, 187, 101, 56, 1, 240, 229, 101, 56, 1, 241, 245, 101, - 56, 1, 241, 75, 101, 56, 1, 186, 101, 56, 1, 230, 235, 101, 56, 1, 230, - 107, 101, 56, 1, 231, 96, 101, 56, 1, 230, 166, 101, 56, 1, 192, 101, 56, - 1, 210, 212, 101, 56, 1, 210, 244, 101, 56, 1, 205, 101, 56, 1, 223, 38, - 101, 56, 1, 222, 142, 101, 56, 1, 223, 131, 101, 56, 1, 222, 213, 101, - 56, 1, 212, 65, 101, 56, 1, 230, 30, 101, 56, 213, 135, 219, 33, 79, 101, - 56, 220, 157, 219, 33, 79, 101, 24, 244, 111, 101, 24, 1, 234, 64, 101, - 24, 1, 218, 217, 101, 24, 1, 234, 57, 101, 24, 1, 228, 231, 101, 24, 1, - 228, 229, 101, 24, 1, 228, 228, 101, 24, 1, 216, 102, 101, 24, 1, 218, - 206, 101, 24, 1, 223, 29, 101, 24, 1, 223, 24, 101, 24, 1, 223, 21, 101, - 24, 1, 223, 14, 101, 24, 1, 223, 9, 101, 24, 1, 223, 4, 101, 24, 1, 223, - 15, 101, 24, 1, 223, 27, 101, 24, 1, 230, 222, 101, 24, 1, 225, 98, 101, - 24, 1, 218, 214, 101, 24, 1, 225, 87, 101, 24, 1, 219, 150, 101, 24, 1, - 218, 211, 101, 24, 1, 236, 63, 101, 24, 1, 250, 54, 101, 24, 1, 218, 221, - 101, 24, 1, 250, 114, 101, 24, 1, 234, 116, 101, 24, 1, 216, 174, 101, - 24, 1, 225, 134, 101, 24, 1, 241, 179, 101, 24, 1, 61, 101, 24, 1, 254, - 252, 101, 24, 1, 192, 101, 24, 1, 211, 92, 101, 24, 1, 245, 125, 101, 24, - 1, 76, 101, 24, 1, 211, 36, 101, 24, 1, 211, 47, 101, 24, 1, 78, 101, 24, - 1, 212, 65, 101, 24, 1, 212, 62, 101, 24, 1, 226, 238, 101, 24, 1, 210, - 244, 101, 24, 1, 69, 101, 24, 1, 212, 11, 101, 24, 1, 212, 22, 101, 24, - 1, 211, 250, 101, 24, 1, 210, 212, 101, 24, 1, 245, 63, 101, 24, 1, 211, - 8, 101, 24, 1, 74, 126, 250, 184, 50, 126, 224, 231, 50, 126, 228, 57, - 50, 126, 231, 237, 126, 251, 143, 130, 126, 211, 40, 50, 126, 211, 217, - 50, 101, 244, 26, 193, 213, 239, 101, 140, 75, 101, 214, 153, 75, 101, - 97, 75, 101, 246, 112, 75, 101, 85, 218, 236, 101, 71, 250, 43, 235, 211, - 254, 107, 254, 128, 235, 211, 254, 107, 220, 139, 235, 211, 254, 107, - 216, 237, 226, 253, 223, 75, 250, 150, 223, 75, 250, 150, 62, 57, 3, 253, - 150, 61, 62, 57, 3, 253, 119, 76, 62, 57, 3, 253, 128, 74, 62, 57, 3, - 253, 96, 78, 62, 57, 3, 253, 146, 69, 62, 57, 3, 253, 165, 248, 229, 62, - 57, 3, 253, 112, 248, 98, 62, 57, 3, 253, 152, 248, 11, 62, 57, 3, 253, - 142, 247, 153, 62, 57, 3, 253, 106, 246, 86, 62, 57, 3, 253, 100, 235, - 147, 62, 57, 3, 253, 111, 235, 132, 62, 57, 3, 253, 121, 235, 74, 62, 57, - 3, 253, 92, 235, 57, 62, 57, 3, 253, 80, 176, 62, 57, 3, 253, 113, 234, - 188, 62, 57, 3, 253, 90, 234, 98, 62, 57, 3, 253, 87, 234, 34, 62, 57, 3, - 253, 76, 233, 223, 62, 57, 3, 253, 77, 186, 62, 57, 3, 253, 143, 231, 96, - 62, 57, 3, 253, 84, 230, 235, 62, 57, 3, 253, 141, 230, 166, 62, 57, 3, - 253, 133, 230, 107, 62, 57, 3, 253, 154, 198, 62, 57, 3, 253, 132, 229, - 112, 62, 57, 3, 253, 126, 228, 238, 62, 57, 3, 253, 105, 228, 79, 62, 57, - 3, 253, 102, 227, 242, 62, 57, 3, 253, 161, 191, 62, 57, 3, 253, 85, 225, - 224, 62, 57, 3, 253, 118, 225, 111, 62, 57, 3, 253, 145, 225, 19, 62, 57, - 3, 253, 107, 224, 153, 62, 57, 3, 253, 140, 224, 91, 62, 57, 3, 253, 79, - 224, 72, 62, 57, 3, 253, 135, 224, 56, 62, 57, 3, 253, 124, 224, 45, 62, - 57, 3, 253, 97, 205, 62, 57, 3, 253, 129, 223, 131, 62, 57, 3, 253, 104, - 223, 38, 62, 57, 3, 253, 163, 222, 213, 62, 57, 3, 253, 130, 222, 142, - 62, 57, 3, 253, 125, 206, 62, 57, 3, 253, 148, 221, 183, 62, 57, 3, 253, - 116, 219, 193, 62, 57, 3, 253, 144, 219, 60, 62, 57, 3, 253, 99, 218, 84, - 62, 57, 3, 253, 98, 217, 106, 62, 57, 3, 253, 159, 217, 23, 62, 57, 3, - 253, 120, 216, 118, 62, 57, 3, 253, 157, 112, 62, 57, 3, 253, 88, 215, - 119, 62, 57, 3, 253, 103, 212, 65, 62, 57, 3, 253, 82, 212, 22, 62, 57, - 3, 253, 117, 211, 250, 62, 57, 3, 253, 115, 211, 227, 62, 57, 3, 253, - 139, 210, 116, 62, 57, 3, 253, 83, 210, 94, 62, 57, 3, 253, 136, 210, 23, - 62, 57, 3, 253, 131, 255, 84, 62, 57, 3, 253, 114, 255, 83, 62, 57, 3, - 253, 73, 253, 200, 62, 57, 3, 253, 86, 246, 54, 62, 57, 3, 253, 69, 246, - 53, 62, 57, 3, 253, 109, 227, 178, 62, 57, 3, 253, 127, 224, 151, 62, 57, - 3, 253, 95, 224, 155, 62, 57, 3, 253, 81, 223, 189, 62, 57, 3, 253, 123, - 223, 188, 62, 57, 3, 253, 89, 222, 212, 62, 57, 3, 253, 91, 217, 103, 62, - 57, 3, 253, 71, 215, 78, 62, 57, 3, 253, 68, 105, 62, 57, 16, 253, 138, - 62, 57, 16, 253, 137, 62, 57, 16, 253, 134, 62, 57, 16, 253, 122, 62, 57, - 16, 253, 110, 62, 57, 16, 253, 108, 62, 57, 16, 253, 101, 62, 57, 16, - 253, 94, 62, 57, 16, 253, 93, 62, 57, 16, 253, 78, 62, 57, 16, 253, 75, - 62, 57, 16, 253, 74, 62, 57, 16, 253, 72, 62, 57, 16, 253, 70, 62, 57, - 106, 253, 67, 231, 190, 62, 57, 106, 253, 66, 211, 221, 62, 57, 106, 253, - 65, 248, 82, 62, 57, 106, 253, 64, 245, 103, 62, 57, 106, 253, 63, 231, - 164, 62, 57, 106, 253, 62, 218, 164, 62, 57, 106, 253, 61, 245, 45, 62, - 57, 106, 253, 60, 223, 156, 62, 57, 106, 253, 59, 220, 64, 62, 57, 106, - 253, 58, 241, 244, 62, 57, 106, 253, 57, 219, 27, 62, 57, 106, 253, 56, - 251, 211, 62, 57, 106, 253, 55, 249, 153, 62, 57, 106, 253, 54, 251, 123, - 62, 57, 106, 253, 53, 212, 2, 62, 57, 106, 253, 52, 252, 144, 62, 57, - 106, 253, 51, 226, 209, 62, 57, 106, 253, 50, 219, 0, 62, 57, 106, 253, - 49, 249, 76, 62, 57, 230, 147, 253, 48, 234, 230, 62, 57, 230, 147, 253, - 47, 234, 238, 62, 57, 106, 253, 46, 226, 222, 62, 57, 106, 253, 45, 211, - 236, 62, 57, 106, 253, 44, 62, 57, 230, 147, 253, 43, 254, 25, 62, 57, - 230, 147, 253, 42, 231, 57, 62, 57, 106, 253, 41, 251, 142, 62, 57, 106, - 253, 40, 242, 173, 62, 57, 106, 253, 39, 62, 57, 106, 253, 38, 211, 212, - 62, 57, 106, 253, 37, 62, 57, 106, 253, 36, 62, 57, 106, 253, 35, 240, - 255, 62, 57, 106, 253, 34, 62, 57, 106, 253, 33, 62, 57, 106, 253, 32, - 62, 57, 230, 147, 253, 30, 215, 92, 62, 57, 106, 253, 29, 62, 57, 106, - 253, 28, 62, 57, 106, 253, 27, 250, 2, 62, 57, 106, 253, 26, 62, 57, 106, - 253, 25, 62, 57, 106, 253, 24, 243, 100, 62, 57, 106, 253, 23, 254, 12, - 62, 57, 106, 253, 22, 62, 57, 106, 253, 21, 62, 57, 106, 253, 20, 62, 57, - 106, 253, 19, 62, 57, 106, 253, 18, 62, 57, 106, 253, 17, 62, 57, 106, - 253, 16, 62, 57, 106, 253, 15, 62, 57, 106, 253, 14, 62, 57, 106, 253, - 13, 230, 139, 62, 57, 106, 253, 12, 62, 57, 106, 253, 11, 215, 236, 62, - 57, 106, 253, 10, 62, 57, 106, 253, 9, 62, 57, 106, 253, 8, 62, 57, 106, - 253, 7, 62, 57, 106, 253, 6, 62, 57, 106, 253, 5, 62, 57, 106, 253, 4, - 62, 57, 106, 253, 3, 62, 57, 106, 253, 2, 62, 57, 106, 253, 1, 62, 57, - 106, 253, 0, 62, 57, 106, 252, 255, 241, 218, 62, 57, 106, 252, 234, 244, - 36, 62, 57, 106, 252, 231, 252, 124, 62, 57, 106, 252, 226, 219, 7, 62, - 57, 106, 252, 225, 75, 62, 57, 106, 252, 224, 62, 57, 106, 252, 223, 217, - 237, 62, 57, 106, 252, 222, 62, 57, 106, 252, 221, 62, 57, 106, 252, 220, - 211, 254, 250, 147, 62, 57, 106, 252, 219, 250, 147, 62, 57, 106, 252, - 218, 250, 148, 244, 7, 62, 57, 106, 252, 217, 212, 0, 62, 57, 106, 252, - 216, 62, 57, 106, 252, 215, 62, 57, 230, 147, 252, 214, 247, 206, 62, 57, - 106, 252, 213, 62, 57, 106, 252, 212, 62, 57, 106, 252, 210, 62, 57, 106, - 252, 209, 62, 57, 106, 252, 208, 62, 57, 106, 252, 207, 248, 167, 62, 57, - 106, 252, 206, 62, 57, 106, 252, 205, 62, 57, 106, 252, 204, 62, 57, 106, - 252, 203, 62, 57, 106, 252, 202, 62, 57, 106, 213, 186, 253, 31, 62, 57, - 106, 213, 186, 252, 254, 62, 57, 106, 213, 186, 252, 253, 62, 57, 106, - 213, 186, 252, 252, 62, 57, 106, 213, 186, 252, 251, 62, 57, 106, 213, - 186, 252, 250, 62, 57, 106, 213, 186, 252, 249, 62, 57, 106, 213, 186, - 252, 248, 62, 57, 106, 213, 186, 252, 247, 62, 57, 106, 213, 186, 252, - 246, 62, 57, 106, 213, 186, 252, 245, 62, 57, 106, 213, 186, 252, 244, - 62, 57, 106, 213, 186, 252, 243, 62, 57, 106, 213, 186, 252, 242, 62, 57, - 106, 213, 186, 252, 241, 62, 57, 106, 213, 186, 252, 240, 62, 57, 106, - 213, 186, 252, 239, 62, 57, 106, 213, 186, 252, 238, 62, 57, 106, 213, - 186, 252, 237, 62, 57, 106, 213, 186, 252, 236, 62, 57, 106, 213, 186, - 252, 235, 62, 57, 106, 213, 186, 252, 233, 62, 57, 106, 213, 186, 252, - 232, 62, 57, 106, 213, 186, 252, 230, 62, 57, 106, 213, 186, 252, 229, - 62, 57, 106, 213, 186, 252, 228, 62, 57, 106, 213, 186, 252, 227, 62, 57, - 106, 213, 186, 252, 211, 62, 57, 106, 213, 186, 252, 201, 254, 245, 211, - 209, 220, 140, 232, 219, 254, 245, 211, 209, 220, 140, 247, 128, 254, - 245, 250, 138, 79, 254, 245, 54, 111, 254, 245, 54, 105, 254, 245, 54, - 158, 254, 245, 54, 161, 254, 245, 54, 190, 254, 245, 54, 195, 254, 245, - 54, 199, 254, 245, 54, 196, 254, 245, 54, 201, 254, 245, 54, 216, 248, - 254, 245, 54, 215, 73, 254, 245, 54, 216, 163, 254, 245, 54, 244, 23, - 254, 245, 54, 244, 122, 254, 245, 54, 219, 113, 254, 245, 54, 220, 118, - 254, 245, 54, 245, 192, 254, 245, 54, 228, 200, 254, 245, 54, 123, 240, - 217, 254, 245, 54, 113, 240, 217, 254, 245, 54, 134, 240, 217, 254, 245, - 54, 244, 19, 240, 217, 254, 245, 54, 244, 89, 240, 217, 254, 245, 54, - 219, 127, 240, 217, 254, 245, 54, 220, 124, 240, 217, 254, 245, 54, 245, - 201, 240, 217, 254, 245, 54, 228, 205, 240, 217, 254, 245, 54, 123, 216, - 148, 254, 245, 54, 113, 216, 148, 254, 245, 54, 134, 216, 148, 254, 245, - 54, 244, 19, 216, 148, 254, 245, 54, 244, 89, 216, 148, 254, 245, 54, - 219, 127, 216, 148, 254, 245, 54, 220, 124, 216, 148, 254, 245, 54, 245, - 201, 216, 148, 254, 245, 54, 228, 205, 216, 148, 254, 245, 54, 216, 249, - 216, 148, 254, 245, 54, 215, 74, 216, 148, 254, 245, 54, 216, 164, 216, - 148, 254, 245, 54, 244, 24, 216, 148, 254, 245, 54, 244, 123, 216, 148, - 254, 245, 54, 219, 114, 216, 148, 254, 245, 54, 220, 119, 216, 148, 254, - 245, 54, 245, 193, 216, 148, 254, 245, 54, 228, 201, 216, 148, 254, 245, - 212, 14, 252, 136, 214, 173, 254, 245, 212, 14, 244, 100, 218, 60, 254, - 245, 212, 14, 221, 178, 218, 60, 254, 245, 212, 14, 216, 170, 218, 60, - 254, 245, 212, 14, 244, 12, 218, 60, 254, 245, 246, 89, 231, 95, 244, - 100, 218, 60, 254, 245, 232, 205, 231, 95, 244, 100, 218, 60, 254, 245, - 231, 95, 221, 178, 218, 60, 254, 245, 231, 95, 216, 170, 218, 60, 26, - 255, 15, 253, 202, 123, 224, 24, 26, 255, 15, 253, 202, 123, 242, 34, 26, - 255, 15, 253, 202, 123, 246, 108, 26, 255, 15, 253, 202, 190, 26, 255, - 15, 253, 202, 244, 122, 26, 255, 15, 253, 202, 244, 89, 240, 217, 26, - 255, 15, 253, 202, 244, 89, 216, 148, 26, 255, 15, 253, 202, 244, 123, - 216, 148, 26, 255, 15, 253, 202, 244, 89, 217, 68, 26, 255, 15, 253, 202, - 216, 249, 217, 68, 26, 255, 15, 253, 202, 244, 123, 217, 68, 26, 255, 15, - 253, 202, 123, 240, 218, 217, 68, 26, 255, 15, 253, 202, 244, 89, 240, - 218, 217, 68, 26, 255, 15, 253, 202, 123, 216, 149, 217, 68, 26, 255, 15, - 253, 202, 244, 89, 216, 149, 217, 68, 26, 255, 15, 253, 202, 244, 89, - 218, 152, 26, 255, 15, 253, 202, 216, 249, 218, 152, 26, 255, 15, 253, - 202, 244, 123, 218, 152, 26, 255, 15, 253, 202, 123, 240, 218, 218, 152, - 26, 255, 15, 253, 202, 244, 89, 240, 218, 218, 152, 26, 255, 15, 253, - 202, 123, 216, 149, 218, 152, 26, 255, 15, 253, 202, 216, 249, 216, 149, - 218, 152, 26, 255, 15, 253, 202, 244, 123, 216, 149, 218, 152, 26, 255, - 15, 253, 202, 216, 249, 230, 169, 26, 255, 15, 241, 212, 123, 225, 34, - 26, 255, 15, 216, 182, 111, 26, 255, 15, 241, 208, 111, 26, 255, 15, 245, - 112, 105, 26, 255, 15, 216, 182, 105, 26, 255, 15, 249, 73, 113, 246, - 107, 26, 255, 15, 245, 112, 113, 246, 107, 26, 255, 15, 215, 204, 190, - 26, 255, 15, 215, 204, 216, 248, 26, 255, 15, 215, 204, 216, 249, 254, - 149, 17, 26, 255, 15, 241, 208, 216, 248, 26, 255, 15, 231, 46, 216, 248, - 26, 255, 15, 216, 182, 216, 248, 26, 255, 15, 216, 182, 216, 163, 26, - 255, 15, 215, 204, 244, 122, 26, 255, 15, 215, 204, 244, 123, 254, 149, - 17, 26, 255, 15, 241, 208, 244, 122, 26, 255, 15, 216, 182, 244, 122, 26, - 255, 15, 216, 182, 123, 240, 217, 26, 255, 15, 216, 182, 134, 240, 217, - 26, 255, 15, 245, 112, 244, 89, 240, 217, 26, 255, 15, 215, 204, 244, 89, - 240, 217, 26, 255, 15, 216, 182, 244, 89, 240, 217, 26, 255, 15, 250, - 235, 244, 89, 240, 217, 26, 255, 15, 229, 187, 244, 89, 240, 217, 26, - 255, 15, 216, 182, 123, 216, 148, 26, 255, 15, 216, 182, 244, 89, 216, - 148, 26, 255, 15, 248, 65, 244, 89, 230, 169, 26, 255, 15, 218, 120, 244, - 123, 230, 169, 26, 123, 163, 50, 26, 123, 163, 5, 254, 149, 17, 26, 113, - 216, 168, 50, 26, 134, 224, 23, 50, 26, 211, 45, 50, 26, 217, 69, 50, 26, - 246, 109, 50, 26, 226, 250, 50, 26, 113, 226, 249, 50, 26, 134, 226, 249, - 50, 26, 244, 19, 226, 249, 50, 26, 244, 89, 226, 249, 50, 26, 231, 40, - 50, 26, 233, 163, 252, 136, 50, 26, 232, 200, 50, 26, 226, 135, 50, 26, - 211, 159, 50, 26, 253, 251, 50, 26, 254, 8, 50, 26, 242, 151, 50, 26, - 215, 187, 252, 136, 50, 26, 210, 87, 50, 222, 200, 220, 115, 50, 222, - 200, 214, 185, 50, 222, 200, 220, 144, 50, 222, 200, 220, 113, 50, 222, - 200, 247, 221, 220, 113, 50, 222, 200, 219, 170, 50, 222, 200, 248, 61, - 50, 222, 200, 224, 9, 50, 222, 200, 220, 131, 50, 222, 200, 246, 68, 50, - 222, 200, 253, 246, 50, 222, 200, 250, 179, 50, 225, 146, 247, 199, 5, - 225, 216, 225, 146, 247, 199, 5, 225, 27, 241, 242, 225, 146, 247, 199, - 5, 217, 46, 241, 242, 225, 146, 247, 199, 5, 250, 255, 225, 146, 247, - 199, 5, 250, 109, 225, 146, 247, 199, 5, 211, 221, 225, 146, 247, 199, 5, - 241, 218, 225, 146, 247, 199, 5, 243, 92, 225, 146, 247, 199, 5, 216, - 117, 225, 146, 247, 199, 5, 75, 225, 146, 247, 199, 5, 251, 177, 225, - 146, 247, 199, 5, 220, 31, 225, 146, 247, 199, 5, 249, 252, 225, 146, - 247, 199, 5, 231, 189, 225, 146, 247, 199, 5, 231, 141, 225, 146, 247, - 199, 5, 221, 218, 225, 146, 247, 199, 5, 232, 243, 225, 146, 247, 199, 5, - 251, 196, 225, 146, 247, 199, 5, 250, 239, 225, 38, 225, 146, 247, 199, - 5, 247, 141, 225, 146, 247, 199, 5, 249, 231, 225, 146, 247, 199, 5, 219, - 89, 225, 146, 247, 199, 5, 249, 232, 225, 146, 247, 199, 5, 252, 71, 225, - 146, 247, 199, 5, 220, 18, 225, 146, 247, 199, 5, 240, 255, 225, 146, - 247, 199, 5, 241, 185, 225, 146, 247, 199, 5, 251, 120, 233, 42, 225, - 146, 247, 199, 5, 250, 232, 225, 146, 247, 199, 5, 223, 156, 225, 146, - 247, 199, 5, 245, 238, 225, 146, 247, 199, 5, 246, 115, 225, 146, 247, - 199, 5, 215, 106, 225, 146, 247, 199, 5, 252, 74, 225, 146, 247, 199, 5, - 225, 39, 215, 236, 225, 146, 247, 199, 5, 213, 159, 225, 146, 247, 199, - 5, 226, 22, 225, 146, 247, 199, 5, 222, 192, 225, 146, 247, 199, 5, 232, - 230, 225, 146, 247, 199, 5, 226, 119, 252, 192, 225, 146, 247, 199, 5, - 244, 56, 225, 146, 247, 199, 5, 242, 145, 225, 146, 247, 199, 5, 218, - 121, 225, 146, 247, 199, 5, 4, 253, 176, 225, 146, 247, 199, 5, 212, 32, - 252, 156, 225, 146, 247, 199, 5, 38, 226, 252, 91, 232, 65, 1, 61, 232, - 65, 1, 76, 232, 65, 1, 253, 166, 232, 65, 1, 252, 27, 232, 65, 1, 243, - 209, 232, 65, 1, 249, 68, 232, 65, 1, 74, 232, 65, 1, 212, 98, 232, 65, - 1, 210, 159, 232, 65, 1, 216, 211, 232, 65, 1, 235, 150, 232, 65, 1, 235, - 29, 232, 65, 1, 224, 99, 232, 65, 1, 156, 232, 65, 1, 194, 232, 65, 1, - 230, 30, 232, 65, 1, 230, 171, 232, 65, 1, 228, 116, 232, 65, 1, 69, 232, - 65, 1, 226, 109, 232, 65, 1, 234, 53, 232, 65, 1, 153, 232, 65, 1, 222, - 93, 232, 65, 1, 217, 153, 232, 65, 1, 215, 160, 232, 65, 1, 254, 131, - 232, 65, 1, 245, 158, 232, 65, 1, 242, 67, 232, 65, 1, 211, 178, 250, - 245, 1, 61, 250, 245, 1, 226, 95, 250, 245, 1, 249, 68, 250, 245, 1, 156, - 250, 245, 1, 214, 116, 250, 245, 1, 153, 250, 245, 1, 233, 68, 250, 245, - 1, 255, 84, 250, 245, 1, 224, 99, 250, 245, 1, 253, 166, 250, 245, 1, - 194, 250, 245, 1, 78, 250, 245, 1, 248, 231, 250, 245, 1, 217, 153, 250, - 245, 1, 220, 106, 250, 245, 1, 220, 105, 250, 245, 1, 222, 93, 250, 245, - 1, 251, 73, 250, 245, 1, 69, 250, 245, 1, 228, 116, 250, 245, 1, 211, - 178, 250, 245, 1, 230, 30, 250, 245, 1, 215, 159, 250, 245, 1, 226, 109, - 250, 245, 1, 218, 228, 250, 245, 1, 74, 250, 245, 1, 76, 250, 245, 1, - 214, 113, 250, 245, 1, 235, 29, 250, 245, 1, 235, 20, 250, 245, 1, 229, - 155, 250, 245, 1, 214, 118, 250, 245, 1, 243, 209, 250, 245, 1, 243, 144, - 250, 245, 1, 218, 170, 250, 245, 1, 218, 169, 250, 245, 1, 229, 84, 250, - 245, 1, 236, 40, 250, 245, 1, 251, 72, 250, 245, 1, 215, 160, 250, 245, - 1, 214, 115, 250, 245, 1, 222, 182, 250, 245, 1, 231, 134, 250, 245, 1, - 231, 133, 250, 245, 1, 231, 132, 250, 245, 1, 231, 131, 250, 245, 1, 233, - 67, 250, 245, 1, 245, 242, 250, 245, 1, 214, 114, 55, 32, 1, 61, 55, 32, - 1, 252, 83, 55, 32, 1, 234, 188, 55, 32, 1, 248, 98, 55, 32, 1, 76, 55, - 32, 1, 213, 255, 55, 32, 1, 210, 94, 55, 32, 1, 241, 245, 55, 32, 1, 216, - 196, 55, 32, 1, 74, 55, 32, 1, 176, 55, 32, 1, 245, 182, 55, 32, 1, 245, - 167, 55, 32, 1, 245, 158, 55, 32, 1, 245, 83, 55, 32, 1, 78, 55, 32, 1, - 225, 224, 55, 32, 1, 220, 65, 55, 32, 1, 233, 223, 55, 32, 1, 245, 100, - 55, 32, 1, 245, 90, 55, 32, 1, 217, 23, 55, 32, 1, 69, 55, 32, 1, 245, - 185, 55, 32, 1, 225, 139, 55, 32, 1, 234, 125, 55, 32, 1, 245, 210, 55, - 32, 1, 245, 92, 55, 32, 1, 250, 139, 55, 32, 1, 236, 40, 55, 32, 1, 214, - 118, 55, 32, 227, 202, 111, 55, 32, 227, 202, 190, 55, 32, 227, 202, 216, - 248, 55, 32, 227, 202, 244, 122, 242, 160, 1, 254, 213, 242, 160, 1, 252, - 171, 242, 160, 1, 242, 218, 242, 160, 1, 248, 212, 242, 160, 1, 254, 209, - 242, 160, 1, 224, 82, 242, 160, 1, 235, 161, 242, 160, 1, 242, 46, 242, - 160, 1, 216, 159, 242, 160, 1, 245, 191, 242, 160, 1, 233, 196, 242, 160, - 1, 233, 119, 242, 160, 1, 231, 184, 242, 160, 1, 229, 189, 242, 160, 1, - 235, 125, 242, 160, 1, 214, 136, 242, 160, 1, 226, 73, 242, 160, 1, 228, - 200, 242, 160, 1, 223, 168, 242, 160, 1, 221, 220, 242, 160, 1, 217, 5, - 242, 160, 1, 211, 234, 242, 160, 1, 244, 186, 242, 160, 1, 236, 44, 242, - 160, 1, 240, 206, 242, 160, 1, 226, 143, 242, 160, 1, 228, 205, 240, 217, - 214, 209, 1, 254, 155, 214, 209, 1, 252, 34, 214, 209, 1, 243, 115, 214, - 209, 1, 234, 138, 214, 209, 1, 248, 62, 214, 209, 1, 241, 75, 214, 209, - 1, 211, 227, 214, 209, 1, 210, 85, 214, 209, 1, 240, 248, 214, 209, 1, - 216, 231, 214, 209, 1, 210, 233, 214, 209, 1, 235, 0, 214, 209, 1, 220, - 22, 214, 209, 1, 233, 104, 214, 209, 1, 231, 70, 214, 209, 1, 248, 29, - 214, 209, 1, 227, 198, 214, 209, 1, 210, 13, 214, 209, 1, 221, 250, 214, - 209, 1, 254, 205, 214, 209, 1, 224, 153, 214, 209, 1, 222, 27, 214, 209, - 1, 224, 38, 214, 209, 1, 223, 147, 214, 209, 1, 216, 200, 214, 209, 1, - 242, 251, 214, 209, 1, 112, 214, 209, 1, 74, 214, 209, 1, 69, 214, 209, - 1, 218, 181, 214, 209, 211, 209, 247, 180, 55, 225, 172, 5, 61, 55, 225, - 172, 5, 74, 55, 225, 172, 5, 69, 55, 225, 172, 5, 176, 55, 225, 172, 5, - 233, 223, 55, 225, 172, 5, 243, 142, 55, 225, 172, 5, 242, 120, 55, 225, - 172, 5, 211, 165, 55, 225, 172, 5, 251, 41, 55, 225, 172, 5, 235, 147, - 55, 225, 172, 5, 235, 114, 55, 225, 172, 5, 217, 106, 55, 225, 172, 5, - 215, 119, 55, 225, 172, 5, 248, 229, 55, 225, 172, 5, 248, 11, 55, 225, - 172, 5, 246, 86, 55, 225, 172, 5, 216, 209, 55, 225, 172, 5, 191, 55, - 225, 172, 5, 252, 199, 55, 225, 172, 5, 244, 204, 55, 225, 172, 5, 198, - 55, 225, 172, 5, 227, 242, 55, 225, 172, 5, 186, 55, 225, 172, 5, 230, - 235, 55, 225, 172, 5, 230, 107, 55, 225, 172, 5, 192, 55, 225, 172, 5, - 214, 27, 55, 225, 172, 5, 213, 176, 55, 225, 172, 5, 205, 55, 225, 172, - 5, 222, 142, 55, 225, 172, 5, 233, 141, 55, 225, 172, 5, 206, 55, 225, - 172, 5, 210, 116, 55, 225, 172, 5, 220, 104, 55, 225, 172, 5, 218, 225, - 55, 225, 172, 5, 162, 55, 225, 172, 5, 253, 194, 55, 225, 172, 5, 253, - 193, 55, 225, 172, 5, 253, 192, 55, 225, 172, 5, 211, 142, 55, 225, 172, - 5, 248, 208, 55, 225, 172, 5, 248, 207, 55, 225, 172, 5, 252, 178, 55, - 225, 172, 5, 251, 93, 55, 225, 172, 211, 209, 247, 180, 55, 225, 172, 54, - 111, 55, 225, 172, 54, 105, 55, 225, 172, 54, 216, 248, 55, 225, 172, 54, - 215, 73, 55, 225, 172, 54, 240, 217, 181, 6, 1, 200, 74, 181, 6, 1, 200, - 76, 181, 6, 1, 200, 61, 181, 6, 1, 200, 254, 218, 181, 6, 1, 200, 78, - 181, 6, 1, 200, 226, 187, 181, 6, 1, 219, 253, 74, 181, 6, 1, 219, 253, - 76, 181, 6, 1, 219, 253, 61, 181, 6, 1, 219, 253, 254, 218, 181, 6, 1, - 219, 253, 78, 181, 6, 1, 219, 253, 226, 187, 181, 6, 1, 253, 175, 181, 6, - 1, 226, 120, 181, 6, 1, 211, 195, 181, 6, 1, 211, 44, 181, 6, 1, 242, 67, - 181, 6, 1, 225, 214, 181, 6, 1, 252, 74, 181, 6, 1, 217, 12, 181, 6, 1, - 248, 85, 181, 6, 1, 250, 136, 181, 6, 1, 235, 130, 181, 6, 1, 234, 195, - 181, 6, 1, 243, 90, 181, 6, 1, 245, 210, 181, 6, 1, 213, 250, 181, 6, 1, - 245, 67, 181, 6, 1, 216, 195, 181, 6, 1, 245, 90, 181, 6, 1, 210, 92, - 181, 6, 1, 245, 83, 181, 6, 1, 210, 73, 181, 6, 1, 245, 100, 181, 6, 1, - 245, 182, 181, 6, 1, 245, 167, 181, 6, 1, 245, 158, 181, 6, 1, 245, 146, - 181, 6, 1, 226, 223, 181, 6, 1, 245, 46, 181, 4, 1, 200, 74, 181, 4, 1, - 200, 76, 181, 4, 1, 200, 61, 181, 4, 1, 200, 254, 218, 181, 4, 1, 200, - 78, 181, 4, 1, 200, 226, 187, 181, 4, 1, 219, 253, 74, 181, 4, 1, 219, - 253, 76, 181, 4, 1, 219, 253, 61, 181, 4, 1, 219, 253, 254, 218, 181, 4, - 1, 219, 253, 78, 181, 4, 1, 219, 253, 226, 187, 181, 4, 1, 253, 175, 181, - 4, 1, 226, 120, 181, 4, 1, 211, 195, 181, 4, 1, 211, 44, 181, 4, 1, 242, - 67, 181, 4, 1, 225, 214, 181, 4, 1, 252, 74, 181, 4, 1, 217, 12, 181, 4, - 1, 248, 85, 181, 4, 1, 250, 136, 181, 4, 1, 235, 130, 181, 4, 1, 234, - 195, 181, 4, 1, 243, 90, 181, 4, 1, 245, 210, 181, 4, 1, 213, 250, 181, - 4, 1, 245, 67, 181, 4, 1, 216, 195, 181, 4, 1, 245, 90, 181, 4, 1, 210, - 92, 181, 4, 1, 245, 83, 181, 4, 1, 210, 73, 181, 4, 1, 245, 100, 181, 4, - 1, 245, 182, 181, 4, 1, 245, 167, 181, 4, 1, 245, 158, 181, 4, 1, 245, - 146, 181, 4, 1, 226, 223, 181, 4, 1, 245, 46, 220, 71, 1, 225, 212, 220, - 71, 1, 216, 6, 220, 71, 1, 234, 97, 220, 71, 1, 244, 155, 220, 71, 1, - 216, 173, 220, 71, 1, 219, 60, 220, 71, 1, 218, 15, 220, 71, 1, 250, 69, - 220, 71, 1, 211, 46, 220, 71, 1, 240, 216, 220, 71, 1, 252, 13, 220, 71, - 1, 248, 97, 220, 71, 1, 243, 128, 220, 71, 1, 213, 123, 220, 71, 1, 216, - 177, 220, 71, 1, 210, 21, 220, 71, 1, 231, 94, 220, 71, 1, 235, 55, 220, - 71, 1, 211, 225, 220, 71, 1, 242, 55, 220, 71, 1, 232, 148, 220, 71, 1, - 230, 194, 220, 71, 1, 236, 47, 220, 71, 1, 245, 209, 220, 71, 1, 253, - 239, 220, 71, 1, 255, 0, 220, 71, 1, 226, 200, 220, 71, 1, 211, 212, 220, - 71, 1, 226, 134, 220, 71, 1, 254, 218, 220, 71, 1, 222, 210, 220, 71, 1, - 227, 198, 220, 71, 1, 245, 225, 220, 71, 1, 254, 223, 220, 71, 1, 240, - 118, 220, 71, 1, 214, 163, 220, 71, 1, 227, 2, 220, 71, 1, 226, 180, 220, - 71, 1, 226, 222, 220, 71, 1, 253, 178, 220, 71, 1, 254, 27, 220, 71, 1, - 226, 162, 220, 71, 1, 254, 201, 220, 71, 1, 245, 94, 220, 71, 1, 254, 5, - 220, 71, 1, 245, 235, 220, 71, 1, 240, 125, 220, 71, 1, 211, 13, 226, - 145, 1, 254, 179, 226, 145, 1, 252, 199, 226, 145, 1, 217, 106, 226, 145, - 1, 235, 147, 226, 145, 1, 211, 165, 226, 145, 1, 234, 138, 226, 145, 1, - 248, 84, 226, 145, 1, 205, 226, 145, 1, 206, 226, 145, 1, 220, 28, 226, - 145, 1, 248, 33, 226, 145, 1, 250, 223, 226, 145, 1, 243, 142, 226, 145, - 1, 244, 204, 226, 145, 1, 224, 89, 226, 145, 1, 235, 15, 226, 145, 1, - 233, 136, 226, 145, 1, 230, 205, 226, 145, 1, 227, 182, 226, 145, 1, 212, - 30, 226, 145, 1, 162, 226, 145, 1, 192, 226, 145, 1, 61, 226, 145, 1, 76, - 226, 145, 1, 74, 226, 145, 1, 78, 226, 145, 1, 69, 226, 145, 1, 255, 82, - 226, 145, 1, 245, 217, 226, 145, 1, 226, 187, 226, 145, 21, 210, 86, 226, - 145, 21, 111, 226, 145, 21, 105, 226, 145, 21, 158, 226, 145, 21, 161, - 226, 145, 21, 190, 226, 145, 21, 195, 226, 145, 21, 199, 226, 145, 21, - 196, 226, 145, 21, 201, 249, 75, 3, 61, 249, 75, 3, 76, 249, 75, 3, 74, - 249, 75, 3, 78, 249, 75, 3, 69, 249, 75, 3, 235, 147, 249, 75, 3, 235, - 74, 249, 75, 3, 176, 249, 75, 3, 234, 188, 249, 75, 3, 234, 98, 249, 75, - 3, 234, 34, 249, 75, 3, 233, 223, 249, 75, 3, 233, 141, 249, 75, 3, 233, - 64, 249, 75, 3, 232, 247, 249, 75, 3, 232, 162, 249, 75, 3, 232, 103, - 249, 75, 3, 186, 249, 75, 3, 231, 96, 249, 75, 3, 230, 235, 249, 75, 3, - 230, 166, 249, 75, 3, 230, 107, 249, 75, 3, 198, 249, 75, 3, 229, 112, - 249, 75, 3, 228, 238, 249, 75, 3, 228, 79, 249, 75, 3, 227, 242, 249, 75, - 3, 191, 249, 75, 3, 225, 224, 249, 75, 3, 225, 111, 249, 75, 3, 225, 19, - 249, 75, 3, 224, 153, 249, 75, 3, 205, 249, 75, 3, 223, 131, 249, 75, 3, - 223, 38, 249, 75, 3, 222, 213, 249, 75, 3, 222, 142, 249, 75, 3, 206, - 249, 75, 3, 221, 183, 249, 75, 3, 219, 193, 249, 75, 3, 219, 60, 249, 75, - 3, 218, 84, 249, 75, 3, 217, 106, 249, 75, 3, 217, 23, 249, 75, 3, 216, - 118, 249, 75, 3, 112, 249, 75, 3, 215, 119, 249, 75, 3, 212, 65, 249, 75, - 3, 212, 22, 249, 75, 3, 211, 250, 249, 75, 3, 211, 227, 249, 75, 3, 211, - 165, 249, 75, 3, 211, 162, 249, 75, 3, 210, 116, 249, 75, 3, 210, 23, - 236, 8, 254, 35, 1, 254, 177, 236, 8, 254, 35, 1, 252, 33, 236, 8, 254, - 35, 1, 242, 208, 236, 8, 254, 35, 1, 248, 196, 236, 8, 254, 35, 1, 241, - 245, 236, 8, 254, 35, 1, 212, 30, 236, 8, 254, 35, 1, 210, 97, 236, 8, - 254, 35, 1, 241, 202, 236, 8, 254, 35, 1, 216, 227, 236, 8, 254, 35, 1, - 210, 232, 236, 8, 254, 35, 1, 234, 231, 236, 8, 254, 35, 1, 233, 99, 236, - 8, 254, 35, 1, 231, 70, 236, 8, 254, 35, 1, 227, 198, 236, 8, 254, 35, 1, - 221, 251, 236, 8, 254, 35, 1, 253, 170, 236, 8, 254, 35, 1, 225, 224, - 236, 8, 254, 35, 1, 222, 26, 236, 8, 254, 35, 1, 224, 37, 236, 8, 254, - 35, 1, 223, 70, 236, 8, 254, 35, 1, 220, 22, 236, 8, 254, 35, 1, 217, 37, - 236, 8, 254, 35, 221, 175, 50, 236, 8, 254, 35, 54, 111, 236, 8, 254, 35, - 54, 105, 236, 8, 254, 35, 54, 158, 236, 8, 254, 35, 54, 216, 248, 236, 8, - 254, 35, 54, 215, 73, 236, 8, 254, 35, 54, 123, 240, 217, 236, 8, 254, - 35, 54, 123, 216, 148, 236, 8, 254, 35, 54, 216, 249, 216, 148, 225, 122, - 1, 254, 174, 225, 122, 1, 252, 36, 225, 122, 1, 243, 116, 225, 122, 1, - 248, 64, 225, 122, 1, 241, 245, 225, 122, 1, 212, 37, 225, 122, 1, 210, - 110, 225, 122, 1, 241, 204, 225, 122, 1, 216, 231, 225, 122, 1, 210, 233, - 225, 122, 1, 235, 0, 225, 122, 1, 233, 105, 225, 122, 1, 231, 70, 225, - 122, 1, 227, 198, 225, 122, 1, 220, 146, 225, 122, 1, 254, 205, 225, 122, - 1, 225, 224, 225, 122, 1, 222, 27, 225, 122, 1, 224, 42, 225, 122, 1, - 222, 191, 225, 122, 1, 220, 22, 225, 122, 1, 217, 42, 225, 122, 54, 111, - 225, 122, 54, 216, 248, 225, 122, 54, 215, 73, 225, 122, 54, 123, 240, - 217, 225, 122, 54, 105, 225, 122, 54, 158, 225, 122, 211, 209, 220, 139, - 232, 64, 1, 61, 232, 64, 1, 253, 166, 232, 64, 1, 243, 209, 232, 64, 1, - 249, 68, 232, 64, 1, 76, 232, 64, 1, 214, 105, 232, 64, 1, 74, 232, 64, - 1, 211, 117, 232, 64, 1, 235, 29, 232, 64, 1, 156, 232, 64, 1, 194, 232, - 64, 1, 230, 30, 232, 64, 1, 78, 232, 64, 1, 153, 232, 64, 1, 218, 228, - 232, 64, 1, 217, 153, 232, 64, 1, 69, 232, 64, 1, 245, 14, 232, 64, 1, - 224, 99, 232, 64, 1, 222, 93, 232, 64, 1, 215, 160, 232, 64, 1, 254, 131, - 232, 64, 1, 245, 158, 232, 64, 1, 232, 67, 232, 64, 1, 228, 116, 232, 64, - 1, 251, 74, 232, 64, 215, 223, 79, 231, 53, 241, 181, 1, 61, 231, 53, - 241, 181, 1, 76, 231, 53, 241, 181, 1, 74, 231, 53, 241, 181, 1, 78, 231, - 53, 241, 181, 1, 192, 231, 53, 241, 181, 1, 212, 65, 231, 53, 241, 181, - 1, 252, 199, 231, 53, 241, 181, 1, 252, 198, 231, 53, 241, 181, 1, 191, - 231, 53, 241, 181, 1, 186, 231, 53, 241, 181, 1, 198, 231, 53, 241, 181, - 1, 229, 233, 231, 53, 241, 181, 1, 229, 112, 231, 53, 241, 181, 1, 229, - 111, 231, 53, 241, 181, 1, 205, 231, 53, 241, 181, 1, 223, 190, 231, 53, - 241, 181, 1, 233, 141, 231, 53, 241, 181, 1, 234, 138, 231, 53, 241, 181, - 1, 241, 196, 231, 53, 241, 181, 1, 206, 231, 53, 241, 181, 1, 222, 35, - 231, 53, 241, 181, 1, 221, 183, 231, 53, 241, 181, 1, 176, 231, 53, 241, - 181, 1, 224, 91, 231, 53, 241, 181, 1, 217, 106, 231, 53, 241, 181, 1, - 217, 105, 231, 53, 241, 181, 1, 217, 23, 231, 53, 241, 181, 1, 217, 22, - 231, 53, 241, 181, 1, 112, 231, 53, 241, 181, 1, 248, 229, 231, 53, 241, - 181, 16, 213, 170, 231, 53, 241, 181, 16, 213, 169, 231, 53, 249, 102, 1, - 61, 231, 53, 249, 102, 1, 76, 231, 53, 249, 102, 1, 74, 231, 53, 249, - 102, 1, 78, 231, 53, 249, 102, 1, 192, 231, 53, 249, 102, 1, 212, 65, - 231, 53, 249, 102, 1, 252, 199, 231, 53, 249, 102, 1, 191, 231, 53, 249, - 102, 1, 186, 231, 53, 249, 102, 1, 198, 231, 53, 249, 102, 1, 229, 112, - 231, 53, 249, 102, 1, 205, 231, 53, 249, 102, 1, 233, 141, 231, 53, 249, - 102, 1, 234, 138, 231, 53, 249, 102, 1, 241, 196, 231, 53, 249, 102, 1, - 206, 231, 53, 249, 102, 1, 254, 31, 206, 231, 53, 249, 102, 1, 221, 183, - 231, 53, 249, 102, 1, 176, 231, 53, 249, 102, 1, 224, 91, 231, 53, 249, - 102, 1, 217, 106, 231, 53, 249, 102, 1, 217, 23, 231, 53, 249, 102, 1, - 112, 231, 53, 249, 102, 1, 248, 229, 231, 53, 249, 102, 232, 151, 222, - 219, 231, 53, 249, 102, 232, 151, 236, 13, 234, 126, 1, 61, 234, 126, 25, - 5, 74, 234, 126, 25, 5, 69, 234, 126, 25, 5, 149, 153, 234, 126, 25, 5, - 76, 234, 126, 25, 5, 78, 234, 126, 25, 233, 29, 79, 234, 126, 5, 52, 222, - 237, 51, 234, 126, 5, 254, 83, 234, 126, 5, 213, 147, 234, 126, 1, 176, - 234, 126, 1, 234, 138, 234, 126, 1, 243, 142, 234, 126, 1, 243, 0, 234, - 126, 1, 251, 41, 234, 126, 1, 250, 165, 234, 126, 1, 235, 147, 234, 126, - 1, 227, 169, 234, 126, 1, 215, 157, 234, 126, 1, 215, 145, 234, 126, 1, - 248, 143, 234, 126, 1, 248, 127, 234, 126, 1, 228, 115, 234, 126, 1, 217, - 106, 234, 126, 1, 216, 209, 234, 126, 1, 248, 229, 234, 126, 1, 248, 33, - 234, 126, 1, 198, 234, 126, 1, 191, 234, 126, 1, 225, 150, 234, 126, 1, - 252, 199, 234, 126, 1, 252, 26, 234, 126, 1, 186, 234, 126, 1, 192, 234, - 126, 1, 205, 234, 126, 1, 233, 141, 234, 126, 1, 214, 27, 234, 126, 1, - 220, 104, 234, 126, 1, 218, 225, 234, 126, 1, 206, 234, 126, 1, 210, 116, - 234, 126, 1, 162, 234, 126, 1, 234, 52, 234, 126, 1, 215, 125, 234, 126, - 5, 252, 149, 48, 234, 126, 5, 250, 229, 234, 126, 5, 59, 51, 234, 126, - 213, 152, 234, 126, 21, 111, 234, 126, 21, 105, 234, 126, 21, 158, 234, - 126, 21, 161, 234, 126, 54, 216, 248, 234, 126, 54, 215, 73, 234, 126, - 54, 123, 240, 217, 234, 126, 54, 123, 216, 148, 234, 126, 224, 144, 247, - 128, 234, 126, 224, 144, 4, 250, 43, 234, 126, 224, 144, 250, 43, 234, - 126, 224, 144, 249, 145, 130, 234, 126, 224, 144, 231, 185, 234, 126, - 224, 144, 232, 121, 234, 126, 224, 144, 248, 186, 234, 126, 224, 144, 52, - 248, 186, 234, 126, 224, 144, 232, 213, 55, 219, 30, 254, 46, 1, 241, - 245, 55, 219, 30, 254, 46, 1, 233, 99, 55, 219, 30, 254, 46, 1, 241, 202, - 55, 219, 30, 254, 46, 1, 231, 70, 55, 219, 30, 254, 46, 1, 224, 37, 55, - 219, 30, 254, 46, 1, 212, 30, 55, 219, 30, 254, 46, 1, 220, 22, 55, 219, - 30, 254, 46, 1, 223, 70, 55, 219, 30, 254, 46, 1, 252, 33, 55, 219, 30, - 254, 46, 1, 217, 37, 55, 219, 30, 254, 46, 1, 221, 228, 55, 219, 30, 254, - 46, 1, 234, 231, 55, 219, 30, 254, 46, 1, 227, 198, 55, 219, 30, 254, 46, - 1, 234, 122, 55, 219, 30, 254, 46, 1, 222, 26, 55, 219, 30, 254, 46, 1, - 221, 251, 55, 219, 30, 254, 46, 1, 244, 162, 55, 219, 30, 254, 46, 1, - 254, 179, 55, 219, 30, 254, 46, 1, 253, 169, 55, 219, 30, 254, 46, 1, - 248, 30, 55, 219, 30, 254, 46, 1, 242, 208, 55, 219, 30, 254, 46, 1, 248, - 196, 55, 219, 30, 254, 46, 1, 242, 245, 55, 219, 30, 254, 46, 1, 216, - 227, 55, 219, 30, 254, 46, 1, 210, 96, 55, 219, 30, 254, 46, 1, 248, 27, - 55, 219, 30, 254, 46, 1, 210, 232, 55, 219, 30, 254, 46, 1, 216, 198, 55, - 219, 30, 254, 46, 1, 216, 179, 55, 219, 30, 254, 46, 54, 111, 55, 219, - 30, 254, 46, 54, 244, 122, 55, 219, 30, 254, 46, 132, 235, 245, 253, 180, - 1, 61, 253, 180, 1, 255, 82, 253, 180, 1, 254, 81, 253, 180, 1, 255, 41, - 253, 180, 1, 254, 131, 253, 180, 1, 255, 42, 253, 180, 1, 254, 252, 253, - 180, 1, 254, 248, 253, 180, 1, 76, 253, 180, 1, 245, 217, 253, 180, 1, - 78, 253, 180, 1, 226, 187, 253, 180, 1, 74, 253, 180, 1, 236, 40, 253, - 180, 1, 69, 253, 180, 1, 214, 118, 253, 180, 1, 234, 188, 253, 180, 1, - 211, 162, 253, 180, 1, 211, 128, 253, 180, 1, 211, 137, 253, 180, 1, 243, - 69, 253, 180, 1, 243, 31, 253, 180, 1, 242, 243, 253, 180, 1, 250, 198, - 253, 180, 1, 235, 132, 253, 180, 1, 217, 23, 253, 180, 1, 216, 196, 253, - 180, 1, 248, 98, 253, 180, 1, 248, 25, 253, 180, 1, 215, 152, 253, 180, - 1, 225, 224, 253, 180, 1, 244, 162, 253, 180, 1, 252, 83, 253, 180, 1, - 252, 22, 253, 180, 1, 229, 69, 253, 180, 1, 228, 244, 253, 180, 1, 228, - 245, 253, 180, 1, 229, 112, 253, 180, 1, 227, 160, 253, 180, 1, 228, 110, - 253, 180, 1, 231, 96, 253, 180, 1, 241, 123, 253, 180, 1, 210, 166, 253, - 180, 1, 211, 47, 253, 180, 1, 213, 255, 253, 180, 1, 223, 131, 253, 180, - 1, 233, 64, 253, 180, 1, 221, 183, 253, 180, 1, 210, 94, 253, 180, 1, - 220, 65, 253, 180, 1, 210, 74, 253, 180, 1, 219, 200, 253, 180, 1, 218, - 195, 253, 180, 1, 241, 245, 253, 180, 255, 30, 79, 216, 80, 113, 170, - 115, 123, 59, 224, 143, 4, 113, 170, 115, 123, 59, 224, 143, 233, 91, - 113, 170, 115, 123, 59, 224, 143, 233, 91, 123, 59, 115, 113, 170, 224, - 143, 233, 91, 113, 222, 235, 115, 123, 222, 237, 224, 143, 233, 91, 123, - 222, 237, 115, 113, 222, 235, 224, 143, 235, 225, 226, 2, 1, 254, 177, - 235, 225, 226, 2, 1, 252, 33, 235, 225, 226, 2, 1, 242, 208, 235, 225, - 226, 2, 1, 248, 196, 235, 225, 226, 2, 1, 241, 245, 235, 225, 226, 2, 1, - 212, 30, 235, 225, 226, 2, 1, 210, 97, 235, 225, 226, 2, 1, 241, 202, - 235, 225, 226, 2, 1, 216, 227, 235, 225, 226, 2, 1, 210, 232, 235, 225, - 226, 2, 1, 234, 231, 235, 225, 226, 2, 1, 233, 99, 235, 225, 226, 2, 1, - 231, 70, 235, 225, 226, 2, 1, 227, 198, 235, 225, 226, 2, 1, 221, 251, - 235, 225, 226, 2, 1, 253, 170, 235, 225, 226, 2, 1, 225, 224, 235, 225, - 226, 2, 1, 222, 26, 235, 225, 226, 2, 1, 224, 37, 235, 225, 226, 2, 1, - 223, 70, 235, 225, 226, 2, 1, 220, 22, 235, 225, 226, 2, 1, 217, 37, 235, - 225, 226, 2, 54, 111, 235, 225, 226, 2, 54, 105, 235, 225, 226, 2, 54, - 158, 235, 225, 226, 2, 54, 161, 235, 225, 226, 2, 54, 216, 248, 235, 225, - 226, 2, 54, 215, 73, 235, 225, 226, 2, 54, 123, 240, 217, 235, 225, 226, - 2, 54, 123, 216, 148, 235, 225, 226, 76, 1, 254, 177, 235, 225, 226, 76, - 1, 252, 33, 235, 225, 226, 76, 1, 242, 208, 235, 225, 226, 76, 1, 248, - 196, 235, 225, 226, 76, 1, 241, 245, 235, 225, 226, 76, 1, 212, 29, 235, - 225, 226, 76, 1, 210, 97, 235, 225, 226, 76, 1, 241, 202, 235, 225, 226, - 76, 1, 216, 227, 235, 225, 226, 76, 1, 210, 232, 235, 225, 226, 76, 1, - 234, 231, 235, 225, 226, 76, 1, 233, 99, 235, 225, 226, 76, 1, 231, 69, - 235, 225, 226, 76, 1, 227, 198, 235, 225, 226, 76, 1, 221, 251, 235, 225, - 226, 76, 1, 225, 224, 235, 225, 226, 76, 1, 222, 26, 235, 225, 226, 76, - 1, 220, 22, 235, 225, 226, 76, 1, 217, 37, 235, 225, 226, 76, 54, 111, - 235, 225, 226, 76, 54, 105, 235, 225, 226, 76, 54, 158, 235, 225, 226, - 76, 54, 161, 235, 225, 226, 76, 54, 216, 248, 235, 225, 226, 76, 54, 215, - 73, 235, 225, 226, 76, 54, 123, 240, 217, 235, 225, 226, 76, 54, 123, - 216, 148, 55, 202, 1, 226, 153, 61, 55, 202, 1, 211, 37, 61, 55, 202, 1, - 211, 37, 254, 252, 55, 202, 1, 226, 153, 74, 55, 202, 1, 211, 37, 74, 55, - 202, 1, 211, 37, 76, 55, 202, 1, 226, 153, 78, 55, 202, 1, 226, 153, 226, - 238, 55, 202, 1, 211, 37, 226, 238, 55, 202, 1, 226, 153, 255, 34, 55, - 202, 1, 211, 37, 255, 34, 55, 202, 1, 226, 153, 254, 251, 55, 202, 1, - 211, 37, 254, 251, 55, 202, 1, 226, 153, 254, 225, 55, 202, 1, 211, 37, - 254, 225, 55, 202, 1, 226, 153, 254, 246, 55, 202, 1, 211, 37, 254, 246, - 55, 202, 1, 226, 153, 255, 8, 55, 202, 1, 211, 37, 255, 8, 55, 202, 1, - 226, 153, 254, 250, 55, 202, 1, 226, 153, 245, 20, 55, 202, 1, 211, 37, - 245, 20, 55, 202, 1, 226, 153, 253, 175, 55, 202, 1, 211, 37, 253, 175, - 55, 202, 1, 226, 153, 254, 233, 55, 202, 1, 211, 37, 254, 233, 55, 202, - 1, 226, 153, 254, 244, 55, 202, 1, 211, 37, 254, 244, 55, 202, 1, 226, - 153, 226, 237, 55, 202, 1, 211, 37, 226, 237, 55, 202, 1, 226, 153, 254, - 187, 55, 202, 1, 211, 37, 254, 187, 55, 202, 1, 226, 153, 254, 243, 55, - 202, 1, 226, 153, 245, 169, 55, 202, 1, 226, 153, 245, 167, 55, 202, 1, - 226, 153, 254, 131, 55, 202, 1, 226, 153, 254, 241, 55, 202, 1, 211, 37, - 254, 241, 55, 202, 1, 226, 153, 245, 139, 55, 202, 1, 211, 37, 245, 139, - 55, 202, 1, 226, 153, 245, 155, 55, 202, 1, 211, 37, 245, 155, 55, 202, - 1, 226, 153, 245, 126, 55, 202, 1, 211, 37, 245, 126, 55, 202, 1, 211, - 37, 254, 123, 55, 202, 1, 226, 153, 245, 146, 55, 202, 1, 211, 37, 254, - 240, 55, 202, 1, 226, 153, 245, 116, 55, 202, 1, 226, 153, 226, 179, 55, - 202, 1, 226, 153, 240, 120, 55, 202, 1, 226, 153, 245, 223, 55, 202, 1, - 211, 37, 245, 223, 55, 202, 1, 226, 153, 254, 53, 55, 202, 1, 211, 37, - 254, 53, 55, 202, 1, 226, 153, 235, 188, 55, 202, 1, 211, 37, 235, 188, - 55, 202, 1, 226, 153, 226, 163, 55, 202, 1, 211, 37, 226, 163, 55, 202, - 1, 226, 153, 254, 49, 55, 202, 1, 211, 37, 254, 49, 55, 202, 1, 226, 153, - 254, 239, 55, 202, 1, 226, 153, 253, 245, 55, 202, 1, 226, 153, 254, 237, - 55, 202, 1, 226, 153, 253, 239, 55, 202, 1, 211, 37, 253, 239, 55, 202, - 1, 226, 153, 245, 83, 55, 202, 1, 211, 37, 245, 83, 55, 202, 1, 226, 153, - 253, 214, 55, 202, 1, 211, 37, 253, 214, 55, 202, 1, 226, 153, 254, 234, - 55, 202, 1, 211, 37, 254, 234, 55, 202, 1, 226, 153, 226, 144, 55, 202, - 1, 226, 153, 252, 133, 222, 129, 21, 111, 222, 129, 21, 105, 222, 129, - 21, 158, 222, 129, 21, 161, 222, 129, 21, 190, 222, 129, 21, 195, 222, - 129, 21, 199, 222, 129, 21, 196, 222, 129, 21, 201, 222, 129, 54, 216, - 248, 222, 129, 54, 215, 73, 222, 129, 54, 216, 163, 222, 129, 54, 244, - 23, 222, 129, 54, 244, 122, 222, 129, 54, 219, 113, 222, 129, 54, 220, - 118, 222, 129, 54, 245, 192, 222, 129, 54, 228, 200, 222, 129, 54, 123, - 240, 217, 222, 129, 54, 113, 240, 217, 222, 129, 54, 134, 240, 217, 222, - 129, 54, 244, 19, 240, 217, 222, 129, 54, 244, 89, 240, 217, 222, 129, - 54, 219, 127, 240, 217, 222, 129, 54, 220, 124, 240, 217, 222, 129, 54, - 245, 201, 240, 217, 222, 129, 54, 228, 205, 240, 217, 222, 129, 244, 10, - 123, 242, 34, 222, 129, 244, 10, 123, 224, 24, 222, 129, 244, 10, 123, - 216, 169, 222, 129, 244, 10, 113, 216, 167, 118, 5, 251, 7, 118, 5, 254, - 83, 118, 5, 213, 147, 118, 5, 235, 108, 118, 5, 214, 161, 118, 1, 61, - 118, 1, 255, 82, 118, 1, 74, 118, 1, 236, 40, 118, 1, 69, 118, 1, 214, - 118, 118, 1, 149, 153, 118, 1, 149, 222, 182, 118, 1, 149, 156, 118, 1, - 149, 232, 191, 118, 1, 76, 118, 1, 254, 210, 118, 1, 78, 118, 1, 253, - 200, 118, 1, 176, 118, 1, 234, 138, 118, 1, 243, 142, 118, 1, 243, 0, - 118, 1, 229, 82, 118, 1, 251, 41, 118, 1, 250, 165, 118, 1, 235, 147, - 118, 1, 235, 120, 118, 1, 227, 169, 118, 1, 215, 157, 118, 1, 215, 145, - 118, 1, 248, 143, 118, 1, 248, 127, 118, 1, 228, 115, 118, 1, 217, 106, - 118, 1, 216, 209, 118, 1, 248, 229, 118, 1, 248, 33, 118, 1, 198, 118, 1, - 191, 118, 1, 225, 150, 118, 1, 252, 199, 118, 1, 252, 26, 118, 1, 186, - 118, 1, 192, 118, 1, 205, 118, 1, 233, 141, 118, 1, 214, 27, 118, 1, 220, - 104, 118, 1, 218, 225, 118, 1, 206, 118, 1, 162, 118, 1, 232, 190, 118, - 1, 55, 36, 232, 181, 118, 1, 55, 36, 222, 181, 118, 1, 55, 36, 228, 97, - 118, 25, 5, 255, 82, 118, 25, 5, 252, 23, 255, 82, 118, 25, 5, 74, 118, - 25, 5, 236, 40, 118, 25, 5, 69, 118, 25, 5, 214, 118, 118, 25, 5, 149, - 153, 118, 25, 5, 149, 222, 182, 118, 25, 5, 149, 156, 118, 25, 5, 149, - 232, 191, 118, 25, 5, 76, 118, 25, 5, 254, 210, 118, 25, 5, 78, 118, 25, - 5, 253, 200, 118, 213, 152, 118, 248, 186, 118, 52, 248, 186, 118, 224, - 144, 247, 128, 118, 224, 144, 52, 247, 128, 118, 224, 144, 232, 219, 118, - 224, 144, 249, 145, 130, 118, 224, 144, 232, 121, 118, 54, 111, 118, 54, - 105, 118, 54, 158, 118, 54, 161, 118, 54, 190, 118, 54, 195, 118, 54, - 199, 118, 54, 196, 118, 54, 201, 118, 54, 216, 248, 118, 54, 215, 73, - 118, 54, 216, 163, 118, 54, 244, 23, 118, 54, 244, 122, 118, 54, 219, - 113, 118, 54, 220, 118, 118, 54, 245, 192, 118, 54, 228, 200, 118, 54, - 123, 240, 217, 118, 54, 123, 216, 148, 118, 21, 210, 86, 118, 21, 111, - 118, 21, 105, 118, 21, 158, 118, 21, 161, 118, 21, 190, 118, 21, 195, - 118, 21, 199, 118, 21, 196, 118, 21, 201, 234, 250, 5, 251, 7, 234, 250, - 5, 254, 83, 234, 250, 5, 213, 147, 234, 250, 1, 61, 234, 250, 1, 255, 82, - 234, 250, 1, 74, 234, 250, 1, 236, 40, 234, 250, 1, 69, 234, 250, 1, 214, - 118, 234, 250, 1, 76, 234, 250, 1, 254, 210, 234, 250, 1, 78, 234, 250, - 1, 253, 200, 234, 250, 1, 176, 234, 250, 1, 234, 138, 234, 250, 1, 243, - 142, 234, 250, 1, 243, 0, 234, 250, 1, 229, 82, 234, 250, 1, 251, 41, - 234, 250, 1, 250, 165, 234, 250, 1, 235, 147, 234, 250, 1, 235, 120, 234, - 250, 1, 227, 169, 234, 250, 1, 215, 157, 234, 250, 1, 215, 145, 234, 250, - 1, 248, 143, 234, 250, 1, 248, 132, 234, 250, 1, 248, 127, 234, 250, 1, - 223, 42, 234, 250, 1, 228, 115, 234, 250, 1, 217, 106, 234, 250, 1, 216, - 209, 234, 250, 1, 248, 229, 234, 250, 1, 248, 33, 234, 250, 1, 198, 234, - 250, 1, 191, 234, 250, 1, 225, 150, 234, 250, 1, 252, 199, 234, 250, 1, - 252, 26, 234, 250, 1, 186, 234, 250, 1, 192, 234, 250, 1, 205, 234, 250, - 1, 233, 141, 234, 250, 1, 214, 27, 234, 250, 1, 220, 104, 234, 250, 1, - 218, 225, 234, 250, 1, 206, 234, 250, 1, 162, 234, 250, 25, 5, 255, 82, - 234, 250, 25, 5, 74, 234, 250, 25, 5, 236, 40, 234, 250, 25, 5, 69, 234, - 250, 25, 5, 214, 118, 234, 250, 25, 5, 76, 234, 250, 25, 5, 254, 210, - 234, 250, 25, 5, 78, 234, 250, 25, 5, 253, 200, 234, 250, 5, 213, 152, - 234, 250, 5, 227, 209, 234, 250, 255, 30, 50, 234, 250, 245, 129, 50, - 234, 250, 54, 50, 234, 250, 221, 175, 79, 234, 250, 52, 221, 175, 79, - 234, 250, 248, 186, 234, 250, 52, 248, 186, 219, 38, 219, 46, 1, 222, 20, - 219, 38, 219, 46, 1, 217, 81, 219, 38, 219, 46, 1, 252, 176, 219, 38, - 219, 46, 1, 251, 31, 219, 38, 219, 46, 1, 248, 211, 219, 38, 219, 46, 1, - 243, 127, 219, 38, 219, 46, 1, 231, 215, 219, 38, 219, 46, 1, 229, 79, - 219, 38, 219, 46, 1, 233, 118, 219, 38, 219, 46, 1, 229, 218, 219, 38, - 219, 46, 1, 214, 24, 219, 38, 219, 46, 1, 226, 77, 219, 38, 219, 46, 1, - 211, 84, 219, 38, 219, 46, 1, 223, 171, 219, 38, 219, 46, 1, 242, 44, - 219, 38, 219, 46, 1, 234, 254, 219, 38, 219, 46, 1, 235, 142, 219, 38, - 219, 46, 1, 227, 166, 219, 38, 219, 46, 1, 254, 218, 219, 38, 219, 46, 1, - 245, 215, 219, 38, 219, 46, 1, 236, 41, 219, 38, 219, 46, 1, 214, 208, - 219, 38, 219, 46, 1, 226, 226, 219, 38, 219, 46, 1, 245, 205, 219, 38, - 219, 46, 1, 231, 228, 219, 38, 219, 46, 21, 210, 86, 219, 38, 219, 46, - 21, 111, 219, 38, 219, 46, 21, 105, 219, 38, 219, 46, 21, 158, 219, 38, - 219, 46, 21, 161, 219, 38, 219, 46, 21, 190, 219, 38, 219, 46, 21, 195, - 219, 38, 219, 46, 21, 199, 219, 38, 219, 46, 21, 196, 219, 38, 219, 46, - 21, 201, 250, 159, 5, 251, 7, 250, 159, 5, 254, 83, 250, 159, 5, 213, - 147, 250, 159, 1, 255, 82, 250, 159, 1, 74, 250, 159, 1, 69, 250, 159, 1, - 76, 250, 159, 1, 235, 16, 250, 159, 1, 234, 137, 250, 159, 1, 243, 139, - 250, 159, 1, 242, 255, 250, 159, 1, 229, 81, 250, 159, 1, 251, 40, 250, - 159, 1, 250, 164, 250, 159, 1, 235, 146, 250, 159, 1, 235, 119, 250, 159, - 1, 227, 168, 250, 159, 1, 215, 156, 250, 159, 1, 215, 144, 250, 159, 1, - 248, 142, 250, 159, 1, 248, 126, 250, 159, 1, 228, 114, 250, 159, 1, 217, - 102, 250, 159, 1, 216, 208, 250, 159, 1, 248, 228, 250, 159, 1, 248, 32, - 250, 159, 1, 229, 230, 250, 159, 1, 226, 93, 250, 159, 1, 225, 149, 250, - 159, 1, 252, 197, 250, 159, 1, 252, 25, 250, 159, 1, 231, 242, 250, 159, - 1, 210, 167, 250, 159, 1, 211, 103, 250, 159, 1, 223, 187, 250, 159, 1, - 233, 140, 250, 159, 1, 212, 64, 250, 159, 1, 222, 33, 250, 159, 1, 242, - 53, 250, 159, 25, 5, 61, 250, 159, 25, 5, 74, 250, 159, 25, 5, 236, 40, - 250, 159, 25, 5, 69, 250, 159, 25, 5, 214, 118, 250, 159, 25, 5, 76, 250, - 159, 25, 5, 254, 210, 250, 159, 25, 5, 78, 250, 159, 25, 5, 253, 200, - 250, 159, 25, 5, 226, 223, 250, 159, 144, 79, 250, 159, 253, 201, 79, - 250, 159, 213, 152, 250, 159, 231, 240, 250, 159, 21, 210, 86, 250, 159, - 21, 111, 250, 159, 21, 105, 250, 159, 21, 158, 250, 159, 21, 161, 250, - 159, 21, 190, 250, 159, 21, 195, 250, 159, 21, 199, 250, 159, 21, 196, - 250, 159, 21, 201, 250, 159, 221, 175, 79, 250, 159, 248, 186, 250, 159, - 52, 248, 186, 250, 159, 224, 16, 79, 174, 5, 251, 7, 174, 5, 254, 83, - 174, 5, 213, 147, 174, 1, 61, 174, 1, 255, 82, 174, 1, 74, 174, 1, 236, - 40, 174, 1, 69, 174, 1, 214, 118, 174, 1, 149, 153, 174, 1, 149, 222, - 182, 174, 1, 149, 156, 174, 1, 149, 232, 191, 174, 1, 76, 174, 1, 254, - 210, 174, 1, 78, 174, 1, 253, 200, 174, 1, 176, 174, 1, 234, 138, 174, 1, - 243, 142, 174, 1, 243, 0, 174, 1, 229, 82, 174, 1, 251, 41, 174, 1, 250, - 165, 174, 1, 235, 147, 174, 1, 235, 120, 174, 1, 227, 169, 174, 1, 215, - 157, 174, 1, 215, 145, 174, 1, 248, 143, 174, 1, 248, 127, 174, 1, 228, - 115, 174, 1, 217, 106, 174, 1, 216, 209, 174, 1, 248, 229, 174, 1, 248, - 33, 174, 1, 198, 174, 1, 191, 174, 1, 225, 150, 174, 1, 252, 199, 174, 1, - 252, 26, 174, 1, 186, 174, 1, 192, 174, 1, 205, 174, 1, 233, 141, 174, 1, - 232, 190, 174, 1, 214, 27, 174, 1, 220, 104, 174, 1, 218, 225, 174, 1, - 206, 174, 1, 162, 174, 25, 5, 255, 82, 174, 25, 5, 74, 174, 25, 5, 236, - 40, 174, 25, 5, 69, 174, 25, 5, 214, 118, 174, 25, 5, 149, 153, 174, 25, - 5, 149, 222, 182, 174, 25, 5, 149, 156, 174, 25, 5, 149, 232, 191, 174, - 25, 5, 76, 174, 25, 5, 254, 210, 174, 25, 5, 78, 174, 25, 5, 253, 200, - 174, 5, 213, 152, 174, 5, 253, 183, 174, 5, 235, 108, 174, 5, 214, 161, - 174, 226, 208, 174, 248, 186, 174, 52, 248, 186, 174, 255, 30, 50, 174, - 220, 139, 174, 21, 210, 86, 174, 21, 111, 174, 21, 105, 174, 21, 158, - 174, 21, 161, 174, 21, 190, 174, 21, 195, 174, 21, 199, 174, 21, 196, - 174, 21, 201, 217, 70, 1, 61, 217, 70, 1, 255, 82, 217, 70, 1, 74, 217, - 70, 1, 236, 40, 217, 70, 1, 69, 217, 70, 1, 214, 118, 217, 70, 1, 76, - 217, 70, 1, 254, 210, 217, 70, 1, 78, 217, 70, 1, 253, 200, 217, 70, 1, - 176, 217, 70, 1, 234, 138, 217, 70, 1, 243, 142, 217, 70, 1, 243, 0, 217, - 70, 1, 229, 82, 217, 70, 1, 251, 41, 217, 70, 1, 250, 165, 217, 70, 1, - 235, 147, 217, 70, 1, 235, 120, 217, 70, 1, 227, 169, 217, 70, 1, 215, - 157, 217, 70, 1, 215, 145, 217, 70, 1, 248, 143, 217, 70, 1, 248, 127, - 217, 70, 1, 228, 115, 217, 70, 1, 217, 106, 217, 70, 1, 216, 209, 217, - 70, 1, 248, 229, 217, 70, 1, 248, 33, 217, 70, 1, 198, 217, 70, 1, 191, - 217, 70, 1, 225, 150, 217, 70, 1, 252, 199, 217, 70, 1, 252, 26, 217, 70, - 1, 186, 217, 70, 1, 192, 217, 70, 1, 205, 217, 70, 1, 233, 141, 217, 70, - 1, 214, 27, 217, 70, 1, 220, 104, 217, 70, 1, 206, 217, 70, 1, 162, 217, - 70, 1, 222, 181, 217, 70, 5, 254, 83, 217, 70, 5, 213, 147, 217, 70, 25, - 5, 255, 82, 217, 70, 25, 5, 74, 217, 70, 25, 5, 236, 40, 217, 70, 25, 5, - 69, 217, 70, 25, 5, 214, 118, 217, 70, 25, 5, 76, 217, 70, 25, 5, 254, - 210, 217, 70, 25, 5, 78, 217, 70, 25, 5, 253, 200, 217, 70, 5, 213, 152, - 217, 70, 5, 227, 209, 217, 70, 21, 210, 86, 217, 70, 21, 111, 217, 70, - 21, 105, 217, 70, 21, 158, 217, 70, 21, 161, 217, 70, 21, 190, 217, 70, - 21, 195, 217, 70, 21, 199, 217, 70, 21, 196, 217, 70, 21, 201, 15, 5, 61, - 15, 5, 116, 30, 61, 15, 5, 116, 30, 252, 184, 15, 5, 116, 30, 243, 112, - 216, 240, 15, 5, 116, 30, 162, 15, 5, 116, 30, 236, 42, 15, 5, 116, 30, - 233, 122, 242, 101, 15, 5, 116, 30, 230, 66, 15, 5, 116, 30, 222, 23, 15, - 5, 255, 84, 15, 5, 255, 34, 15, 5, 255, 35, 30, 253, 237, 15, 5, 255, 35, - 30, 246, 75, 242, 101, 15, 5, 255, 35, 30, 243, 125, 15, 5, 255, 35, 30, - 243, 112, 216, 240, 15, 5, 255, 35, 30, 162, 15, 5, 255, 35, 30, 236, 43, - 242, 101, 15, 5, 255, 35, 30, 236, 16, 15, 5, 255, 35, 30, 233, 123, 15, - 5, 255, 35, 30, 220, 50, 15, 5, 255, 35, 30, 104, 96, 104, 96, 69, 15, 5, - 255, 35, 242, 101, 15, 5, 255, 32, 15, 5, 255, 33, 30, 252, 168, 15, 5, - 255, 33, 30, 243, 112, 216, 240, 15, 5, 255, 33, 30, 231, 97, 96, 245, - 158, 15, 5, 255, 33, 30, 220, 102, 15, 5, 255, 33, 30, 217, 73, 15, 5, - 255, 8, 15, 5, 254, 195, 15, 5, 254, 196, 30, 245, 95, 15, 5, 254, 196, - 30, 220, 12, 96, 242, 197, 15, 5, 254, 187, 15, 5, 254, 188, 30, 254, - 187, 15, 5, 254, 188, 30, 247, 224, 15, 5, 254, 188, 30, 242, 197, 15, 5, - 254, 188, 30, 162, 15, 5, 254, 188, 30, 235, 5, 15, 5, 254, 188, 30, 234, - 98, 15, 5, 254, 188, 30, 220, 65, 15, 5, 254, 188, 30, 214, 126, 15, 5, - 254, 184, 15, 5, 254, 177, 15, 5, 254, 140, 15, 5, 254, 141, 30, 220, 65, - 15, 5, 254, 131, 15, 5, 254, 132, 115, 254, 131, 15, 5, 254, 132, 134, - 216, 86, 15, 5, 254, 132, 96, 229, 222, 226, 168, 254, 132, 96, 229, 221, - 15, 5, 254, 132, 96, 229, 222, 218, 235, 15, 5, 254, 102, 15, 5, 254, 75, - 15, 5, 254, 43, 15, 5, 254, 44, 30, 233, 202, 15, 5, 254, 16, 15, 5, 253, - 244, 15, 5, 253, 239, 15, 5, 253, 240, 210, 40, 216, 240, 15, 5, 253, - 240, 235, 9, 216, 240, 15, 5, 253, 240, 115, 253, 240, 215, 115, 115, - 215, 115, 215, 115, 115, 215, 115, 226, 25, 15, 5, 253, 240, 115, 253, - 240, 115, 253, 239, 15, 5, 253, 240, 115, 253, 240, 115, 253, 240, 249, - 133, 253, 240, 115, 253, 240, 115, 253, 239, 15, 5, 253, 237, 15, 5, 253, - 234, 15, 5, 252, 199, 15, 5, 252, 184, 15, 5, 252, 179, 15, 5, 252, 175, - 15, 5, 252, 169, 15, 5, 252, 170, 115, 252, 169, 15, 5, 252, 168, 15, 5, - 130, 15, 5, 252, 148, 15, 5, 252, 14, 15, 5, 252, 15, 30, 61, 15, 5, 252, - 15, 30, 243, 103, 15, 5, 252, 15, 30, 236, 43, 242, 101, 15, 5, 251, 133, - 15, 5, 251, 134, 115, 251, 134, 255, 34, 15, 5, 251, 134, 115, 251, 134, - 214, 190, 15, 5, 251, 134, 249, 133, 251, 133, 15, 5, 251, 117, 15, 5, - 251, 118, 115, 251, 117, 15, 5, 251, 106, 15, 5, 251, 105, 15, 5, 248, - 229, 15, 5, 248, 220, 15, 5, 248, 221, 234, 72, 30, 116, 96, 231, 152, - 15, 5, 248, 221, 234, 72, 30, 254, 140, 15, 5, 248, 221, 234, 72, 30, - 252, 168, 15, 5, 248, 221, 234, 72, 30, 252, 14, 15, 5, 248, 221, 234, - 72, 30, 243, 142, 15, 5, 248, 221, 234, 72, 30, 243, 143, 96, 231, 152, - 15, 5, 248, 221, 234, 72, 30, 242, 221, 15, 5, 248, 221, 234, 72, 30, - 242, 204, 15, 5, 248, 221, 234, 72, 30, 242, 110, 15, 5, 248, 221, 234, - 72, 30, 162, 15, 5, 248, 221, 234, 72, 30, 235, 186, 15, 5, 248, 221, - 234, 72, 30, 235, 187, 96, 232, 103, 15, 5, 248, 221, 234, 72, 30, 234, - 248, 15, 5, 248, 221, 234, 72, 30, 233, 141, 15, 5, 248, 221, 234, 72, - 30, 232, 103, 15, 5, 248, 221, 234, 72, 30, 232, 104, 96, 231, 151, 15, - 5, 248, 221, 234, 72, 30, 232, 89, 15, 5, 248, 221, 234, 72, 30, 229, - 112, 15, 5, 248, 221, 234, 72, 30, 226, 26, 96, 226, 25, 15, 5, 248, 221, - 234, 72, 30, 219, 193, 15, 5, 248, 221, 234, 72, 30, 217, 73, 15, 5, 248, - 221, 234, 72, 30, 214, 231, 96, 242, 204, 15, 5, 248, 221, 234, 72, 30, - 214, 126, 15, 5, 248, 195, 15, 5, 248, 174, 15, 5, 248, 173, 15, 5, 248, - 172, 15, 5, 248, 11, 15, 5, 247, 250, 15, 5, 247, 225, 15, 5, 247, 226, - 30, 220, 65, 15, 5, 247, 224, 15, 5, 247, 214, 15, 5, 247, 215, 234, 214, - 104, 242, 102, 247, 195, 15, 5, 247, 195, 15, 5, 246, 86, 15, 5, 246, 87, - 115, 246, 86, 15, 5, 246, 87, 242, 101, 15, 5, 246, 87, 220, 47, 15, 5, - 246, 84, 15, 5, 246, 85, 30, 245, 80, 15, 5, 246, 83, 15, 5, 246, 82, 15, - 5, 246, 81, 15, 5, 246, 80, 15, 5, 246, 76, 15, 5, 246, 74, 15, 5, 246, - 75, 242, 101, 15, 5, 246, 75, 242, 102, 242, 101, 15, 5, 246, 73, 15, 5, - 246, 66, 15, 5, 76, 15, 5, 160, 30, 226, 25, 15, 5, 160, 115, 160, 227, - 199, 115, 227, 198, 15, 5, 245, 242, 15, 5, 245, 243, 30, 116, 96, 242, - 56, 96, 248, 229, 15, 5, 245, 243, 30, 243, 103, 15, 5, 245, 243, 30, - 230, 235, 15, 5, 245, 243, 30, 222, 10, 15, 5, 245, 243, 30, 220, 65, 15, - 5, 245, 243, 30, 69, 15, 5, 245, 219, 15, 5, 245, 208, 15, 5, 245, 182, - 15, 5, 245, 158, 15, 5, 245, 159, 30, 243, 111, 15, 5, 245, 159, 30, 243, - 112, 216, 240, 15, 5, 245, 159, 30, 231, 96, 15, 5, 245, 159, 249, 133, - 245, 158, 15, 5, 245, 159, 226, 168, 245, 158, 15, 5, 245, 159, 218, 235, - 15, 5, 245, 97, 15, 5, 245, 95, 15, 5, 245, 80, 15, 5, 245, 18, 15, 5, - 245, 19, 30, 61, 15, 5, 245, 19, 30, 116, 96, 233, 110, 15, 5, 245, 19, - 30, 116, 96, 233, 111, 30, 233, 110, 15, 5, 245, 19, 30, 254, 131, 15, 5, - 245, 19, 30, 252, 184, 15, 5, 245, 19, 30, 246, 75, 242, 101, 15, 5, 245, - 19, 30, 246, 75, 242, 102, 242, 101, 15, 5, 245, 19, 30, 162, 15, 5, 245, - 19, 30, 242, 56, 242, 101, 15, 5, 245, 19, 30, 236, 43, 242, 101, 15, 5, - 245, 19, 30, 234, 213, 15, 5, 245, 19, 30, 234, 214, 218, 235, 15, 5, - 245, 19, 30, 233, 221, 15, 5, 245, 19, 30, 233, 141, 15, 5, 245, 19, 30, - 233, 111, 30, 233, 110, 15, 5, 245, 19, 30, 232, 247, 15, 5, 245, 19, 30, - 232, 103, 15, 5, 245, 19, 30, 214, 230, 15, 5, 245, 19, 30, 214, 219, 15, - 5, 243, 142, 15, 5, 243, 143, 242, 101, 15, 5, 243, 140, 15, 5, 243, 141, - 30, 116, 96, 248, 230, 96, 162, 15, 5, 243, 141, 30, 116, 96, 162, 15, 5, - 243, 141, 30, 116, 96, 236, 42, 15, 5, 243, 141, 30, 255, 33, 216, 241, - 96, 217, 94, 15, 5, 243, 141, 30, 254, 131, 15, 5, 243, 141, 30, 253, - 239, 15, 5, 243, 141, 30, 253, 238, 96, 243, 125, 15, 5, 243, 141, 30, - 252, 184, 15, 5, 243, 141, 30, 252, 149, 96, 205, 15, 5, 243, 141, 30, - 251, 106, 15, 5, 243, 141, 30, 251, 107, 96, 205, 15, 5, 243, 141, 30, - 248, 229, 15, 5, 243, 141, 30, 248, 11, 15, 5, 243, 141, 30, 247, 226, - 30, 220, 65, 15, 5, 243, 141, 30, 246, 84, 15, 5, 243, 141, 30, 245, 182, - 15, 5, 243, 141, 30, 245, 183, 96, 233, 141, 15, 5, 243, 141, 30, 245, - 158, 15, 5, 243, 141, 30, 245, 159, 30, 243, 112, 216, 240, 15, 5, 243, - 141, 30, 243, 112, 216, 240, 15, 5, 243, 141, 30, 243, 103, 15, 5, 243, - 141, 30, 242, 221, 15, 5, 243, 141, 30, 242, 219, 15, 5, 243, 141, 30, - 242, 220, 96, 61, 15, 5, 243, 141, 30, 242, 205, 96, 218, 84, 15, 5, 243, - 141, 30, 242, 56, 96, 232, 104, 96, 245, 80, 15, 5, 243, 141, 30, 242, - 37, 15, 5, 243, 141, 30, 242, 38, 96, 233, 141, 15, 5, 243, 141, 30, 241, - 188, 96, 232, 247, 15, 5, 243, 141, 30, 240, 225, 15, 5, 243, 141, 30, - 236, 43, 242, 101, 15, 5, 243, 141, 30, 235, 173, 96, 240, 230, 96, 253, - 239, 15, 5, 243, 141, 30, 234, 248, 15, 5, 243, 141, 30, 234, 213, 15, 5, - 243, 141, 30, 234, 95, 15, 5, 243, 141, 30, 234, 96, 96, 233, 110, 15, 5, - 243, 141, 30, 233, 222, 96, 254, 131, 15, 5, 243, 141, 30, 233, 141, 15, - 5, 243, 141, 30, 231, 97, 96, 245, 158, 15, 5, 243, 141, 30, 230, 235, - 15, 5, 243, 141, 30, 227, 198, 15, 5, 243, 141, 30, 227, 199, 115, 227, - 198, 15, 5, 243, 141, 30, 191, 15, 5, 243, 141, 30, 222, 10, 15, 5, 243, - 141, 30, 221, 233, 15, 5, 243, 141, 30, 220, 65, 15, 5, 243, 141, 30, - 220, 66, 96, 215, 99, 15, 5, 243, 141, 30, 220, 32, 15, 5, 243, 141, 30, - 218, 44, 15, 5, 243, 141, 30, 217, 73, 15, 5, 243, 141, 30, 69, 15, 5, - 243, 141, 30, 214, 219, 15, 5, 243, 141, 30, 214, 220, 96, 246, 86, 15, - 5, 243, 141, 115, 243, 140, 15, 5, 243, 135, 15, 5, 243, 136, 249, 133, - 243, 135, 15, 5, 243, 133, 15, 5, 243, 134, 115, 243, 134, 243, 104, 115, - 243, 103, 15, 5, 243, 125, 15, 5, 243, 126, 243, 134, 115, 243, 134, 243, - 104, 115, 243, 103, 15, 5, 243, 124, 15, 5, 243, 122, 15, 5, 243, 113, - 15, 5, 243, 111, 15, 5, 243, 112, 216, 240, 15, 5, 243, 112, 115, 243, - 111, 15, 5, 243, 112, 249, 133, 243, 111, 15, 5, 243, 103, 15, 5, 243, - 102, 15, 5, 243, 97, 15, 5, 243, 43, 15, 5, 243, 44, 30, 233, 202, 15, 5, - 242, 221, 15, 5, 242, 222, 30, 76, 15, 5, 242, 222, 30, 69, 15, 5, 242, - 222, 249, 133, 242, 221, 15, 5, 242, 219, 15, 5, 242, 220, 115, 242, 219, - 15, 5, 242, 220, 249, 133, 242, 219, 15, 5, 242, 216, 15, 5, 242, 204, - 15, 5, 242, 205, 242, 101, 15, 5, 242, 202, 15, 5, 242, 203, 30, 116, 96, - 236, 42, 15, 5, 242, 203, 30, 243, 112, 216, 240, 15, 5, 242, 203, 30, - 236, 42, 15, 5, 242, 203, 30, 232, 104, 96, 236, 42, 15, 5, 242, 203, 30, - 191, 15, 5, 242, 199, 15, 5, 242, 197, 15, 5, 242, 198, 249, 133, 242, - 197, 15, 5, 242, 198, 30, 252, 184, 15, 5, 242, 198, 30, 217, 73, 15, 5, - 242, 198, 216, 240, 15, 5, 242, 120, 15, 5, 242, 121, 249, 133, 242, 120, - 15, 5, 242, 118, 15, 5, 242, 119, 30, 234, 248, 15, 5, 242, 119, 30, 234, - 249, 30, 236, 43, 242, 101, 15, 5, 242, 119, 30, 227, 198, 15, 5, 242, - 119, 30, 222, 11, 96, 215, 114, 15, 5, 242, 119, 242, 101, 15, 5, 242, - 110, 15, 5, 242, 111, 30, 116, 96, 233, 202, 15, 5, 242, 111, 30, 233, - 202, 15, 5, 242, 111, 115, 242, 111, 232, 96, 15, 5, 242, 105, 15, 5, - 242, 103, 15, 5, 242, 104, 30, 220, 65, 15, 5, 242, 95, 15, 5, 242, 94, - 15, 5, 242, 91, 15, 5, 242, 90, 15, 5, 162, 15, 5, 242, 56, 216, 240, 15, - 5, 242, 56, 242, 101, 15, 5, 242, 37, 15, 5, 241, 187, 15, 5, 241, 188, - 30, 253, 239, 15, 5, 241, 188, 30, 253, 237, 15, 5, 241, 188, 30, 252, - 184, 15, 5, 241, 188, 30, 247, 195, 15, 5, 241, 188, 30, 243, 133, 15, 5, - 241, 188, 30, 234, 87, 15, 5, 241, 188, 30, 227, 198, 15, 5, 241, 188, - 30, 220, 65, 15, 5, 241, 188, 30, 69, 15, 5, 240, 229, 15, 5, 240, 225, - 15, 5, 240, 226, 30, 254, 131, 15, 5, 240, 226, 30, 242, 37, 15, 5, 240, - 226, 30, 234, 213, 15, 5, 240, 226, 30, 232, 203, 15, 5, 240, 226, 30, - 214, 219, 15, 5, 240, 222, 15, 5, 74, 15, 5, 240, 161, 61, 15, 5, 240, - 122, 15, 5, 236, 70, 15, 5, 236, 71, 115, 236, 71, 251, 106, 15, 5, 236, - 71, 115, 236, 71, 218, 235, 15, 5, 236, 45, 15, 5, 236, 42, 15, 5, 236, - 43, 247, 250, 15, 5, 236, 43, 223, 38, 15, 5, 236, 43, 115, 236, 43, 220, - 16, 115, 220, 16, 214, 220, 115, 214, 219, 15, 5, 236, 43, 242, 101, 15, - 5, 236, 34, 15, 5, 236, 35, 30, 243, 112, 216, 240, 15, 5, 236, 33, 15, - 5, 236, 23, 15, 5, 236, 24, 30, 217, 73, 15, 5, 236, 24, 249, 133, 236, - 23, 15, 5, 236, 24, 226, 168, 236, 23, 15, 5, 236, 24, 218, 235, 15, 5, - 236, 16, 15, 5, 236, 6, 15, 5, 235, 186, 15, 5, 235, 172, 15, 5, 176, 15, - 5, 235, 19, 30, 61, 15, 5, 235, 19, 30, 255, 8, 15, 5, 235, 19, 30, 255, - 9, 96, 233, 221, 15, 5, 235, 19, 30, 253, 237, 15, 5, 235, 19, 30, 252, - 184, 15, 5, 235, 19, 30, 252, 168, 15, 5, 235, 19, 30, 130, 15, 5, 235, - 19, 30, 252, 14, 15, 5, 235, 19, 30, 245, 95, 15, 5, 235, 19, 30, 245, - 80, 15, 5, 235, 19, 30, 243, 142, 15, 5, 235, 19, 30, 243, 125, 15, 5, - 235, 19, 30, 243, 112, 216, 240, 15, 5, 235, 19, 30, 243, 103, 15, 5, - 235, 19, 30, 243, 104, 96, 220, 103, 96, 61, 15, 5, 235, 19, 30, 242, - 221, 15, 5, 235, 19, 30, 242, 204, 15, 5, 235, 19, 30, 242, 198, 96, 221, - 233, 15, 5, 235, 19, 30, 242, 198, 249, 133, 242, 197, 15, 5, 235, 19, - 30, 242, 120, 15, 5, 235, 19, 30, 242, 94, 15, 5, 235, 19, 30, 236, 42, - 15, 5, 235, 19, 30, 236, 23, 15, 5, 235, 19, 30, 234, 248, 15, 5, 235, - 19, 30, 234, 98, 15, 5, 235, 19, 30, 234, 95, 15, 5, 235, 19, 30, 232, - 247, 15, 5, 235, 19, 30, 232, 103, 15, 5, 235, 19, 30, 231, 96, 15, 5, - 235, 19, 30, 231, 97, 96, 246, 86, 15, 5, 235, 19, 30, 231, 97, 96, 242, - 221, 15, 5, 235, 19, 30, 231, 97, 96, 217, 23, 15, 5, 235, 19, 30, 230, - 235, 15, 5, 235, 19, 30, 230, 236, 96, 227, 193, 15, 5, 235, 19, 30, 229, - 112, 15, 5, 235, 19, 30, 227, 198, 15, 5, 235, 19, 30, 225, 111, 15, 5, - 235, 19, 30, 222, 142, 15, 5, 235, 19, 30, 206, 15, 5, 235, 19, 30, 221, - 233, 15, 5, 235, 19, 30, 220, 104, 15, 5, 235, 19, 30, 220, 65, 15, 5, - 235, 19, 30, 220, 32, 15, 5, 235, 19, 30, 219, 227, 15, 5, 235, 19, 30, - 219, 184, 15, 5, 235, 19, 30, 218, 52, 15, 5, 235, 19, 30, 217, 51, 15, - 5, 235, 19, 30, 69, 15, 5, 235, 19, 30, 214, 230, 15, 5, 235, 19, 30, - 214, 219, 15, 5, 235, 19, 30, 214, 193, 30, 191, 15, 5, 235, 19, 30, 214, - 126, 15, 5, 235, 19, 30, 210, 44, 15, 5, 235, 17, 15, 5, 235, 18, 249, - 133, 235, 17, 15, 5, 235, 10, 15, 5, 235, 7, 15, 5, 235, 5, 15, 5, 235, - 4, 15, 5, 235, 2, 15, 5, 235, 3, 115, 235, 2, 15, 5, 234, 248, 15, 5, - 234, 249, 30, 236, 43, 242, 101, 15, 5, 234, 244, 15, 5, 234, 245, 30, - 252, 184, 15, 5, 234, 245, 249, 133, 234, 244, 15, 5, 234, 242, 15, 5, - 234, 241, 15, 5, 234, 213, 15, 5, 234, 214, 233, 124, 30, 104, 115, 233, - 124, 30, 69, 15, 5, 234, 214, 115, 234, 214, 233, 124, 30, 104, 115, 233, - 124, 30, 69, 15, 5, 234, 163, 15, 5, 234, 98, 15, 5, 234, 99, 30, 252, - 184, 15, 5, 234, 99, 30, 69, 15, 5, 234, 99, 30, 214, 219, 15, 5, 234, - 95, 15, 5, 234, 87, 15, 5, 234, 74, 15, 5, 234, 73, 15, 5, 234, 71, 15, - 5, 234, 72, 115, 234, 71, 15, 5, 233, 223, 15, 5, 233, 224, 115, 241, - 188, 30, 253, 238, 233, 224, 115, 241, 188, 30, 253, 237, 15, 5, 233, - 221, 15, 5, 233, 219, 15, 5, 233, 220, 214, 12, 17, 15, 5, 233, 218, 15, - 5, 233, 215, 15, 5, 233, 216, 242, 101, 15, 5, 233, 214, 15, 5, 233, 202, - 15, 5, 233, 203, 226, 168, 233, 202, 15, 5, 233, 197, 15, 5, 233, 178, - 15, 5, 233, 141, 15, 5, 233, 123, 15, 5, 233, 124, 30, 61, 15, 5, 233, - 124, 30, 116, 96, 248, 230, 96, 162, 15, 5, 233, 124, 30, 116, 96, 243, - 103, 15, 5, 233, 124, 30, 116, 96, 233, 110, 15, 5, 233, 124, 30, 254, - 187, 15, 5, 233, 124, 30, 254, 131, 15, 5, 233, 124, 30, 253, 240, 210, - 40, 216, 240, 15, 5, 233, 124, 30, 252, 184, 15, 5, 233, 124, 30, 252, - 14, 15, 5, 233, 124, 30, 248, 174, 15, 5, 233, 124, 30, 245, 158, 15, 5, - 233, 124, 30, 243, 142, 15, 5, 233, 124, 30, 243, 103, 15, 5, 233, 124, - 30, 242, 110, 15, 5, 233, 124, 30, 242, 111, 96, 242, 110, 15, 5, 233, - 124, 30, 162, 15, 5, 233, 124, 30, 242, 37, 15, 5, 233, 124, 30, 241, - 188, 30, 227, 198, 15, 5, 233, 124, 30, 236, 43, 242, 101, 15, 5, 233, - 124, 30, 236, 23, 15, 5, 233, 124, 30, 236, 24, 96, 162, 15, 5, 233, 124, - 30, 236, 24, 96, 232, 103, 15, 5, 233, 124, 30, 234, 98, 15, 5, 233, 124, - 30, 234, 87, 15, 5, 233, 124, 30, 233, 221, 15, 5, 233, 124, 30, 233, - 215, 15, 5, 233, 124, 30, 233, 216, 96, 241, 188, 96, 61, 15, 5, 233, - 124, 30, 233, 123, 15, 5, 233, 124, 30, 232, 203, 15, 5, 233, 124, 30, - 232, 103, 15, 5, 233, 124, 30, 232, 91, 15, 5, 233, 124, 30, 231, 96, 15, - 5, 233, 124, 30, 231, 97, 96, 245, 158, 15, 5, 233, 124, 30, 230, 66, 15, - 5, 233, 124, 30, 229, 112, 15, 5, 233, 124, 30, 220, 66, 96, 218, 44, 15, - 5, 233, 124, 30, 220, 12, 96, 242, 198, 96, 245, 95, 15, 5, 233, 124, 30, - 220, 12, 96, 242, 198, 216, 240, 15, 5, 233, 124, 30, 219, 225, 15, 5, - 233, 124, 30, 219, 226, 96, 219, 225, 15, 5, 233, 124, 30, 218, 44, 15, - 5, 233, 124, 30, 217, 85, 15, 5, 233, 124, 30, 217, 73, 15, 5, 233, 124, - 30, 217, 24, 96, 116, 96, 218, 85, 96, 198, 15, 5, 233, 124, 30, 69, 15, - 5, 233, 124, 30, 104, 96, 61, 15, 5, 233, 124, 30, 104, 96, 104, 96, 69, - 15, 5, 233, 124, 30, 214, 231, 96, 253, 239, 15, 5, 233, 124, 30, 214, - 219, 15, 5, 233, 124, 30, 214, 126, 15, 5, 233, 124, 218, 235, 15, 5, - 233, 121, 15, 5, 233, 122, 30, 220, 65, 15, 5, 233, 122, 30, 220, 66, 96, - 218, 44, 15, 5, 233, 122, 242, 101, 15, 5, 233, 122, 242, 102, 115, 233, - 122, 242, 102, 220, 65, 15, 5, 233, 117, 15, 5, 233, 110, 15, 5, 233, - 111, 30, 233, 110, 15, 5, 233, 108, 15, 5, 233, 109, 30, 233, 202, 15, 5, - 233, 109, 30, 233, 203, 96, 222, 142, 15, 5, 232, 247, 15, 5, 232, 232, - 15, 5, 232, 222, 15, 5, 232, 203, 15, 5, 232, 103, 15, 5, 232, 104, 30, - 252, 184, 15, 5, 232, 101, 15, 5, 232, 102, 30, 254, 187, 15, 5, 232, - 102, 30, 252, 184, 15, 5, 232, 102, 30, 245, 80, 15, 5, 232, 102, 30, - 245, 81, 216, 240, 15, 5, 232, 102, 30, 243, 112, 216, 240, 15, 5, 232, - 102, 30, 241, 188, 30, 252, 184, 15, 5, 232, 102, 30, 236, 23, 15, 5, - 232, 102, 30, 235, 7, 15, 5, 232, 102, 30, 235, 5, 15, 5, 232, 102, 30, - 235, 6, 96, 253, 239, 15, 5, 232, 102, 30, 234, 98, 15, 5, 232, 102, 30, - 233, 142, 96, 253, 239, 15, 5, 232, 102, 30, 233, 123, 15, 5, 232, 102, - 30, 231, 97, 96, 245, 158, 15, 5, 232, 102, 30, 229, 112, 15, 5, 232, - 102, 30, 227, 242, 15, 5, 232, 102, 30, 219, 194, 96, 253, 239, 15, 5, - 232, 102, 30, 219, 176, 96, 251, 133, 15, 5, 232, 102, 30, 215, 114, 15, - 5, 232, 102, 216, 240, 15, 5, 232, 102, 249, 133, 232, 101, 15, 5, 232, - 102, 226, 168, 232, 101, 15, 5, 232, 102, 218, 235, 15, 5, 232, 102, 220, - 47, 15, 5, 232, 100, 15, 5, 232, 96, 15, 5, 232, 97, 115, 232, 96, 15, 5, - 232, 97, 226, 168, 232, 96, 15, 5, 232, 97, 220, 47, 15, 5, 232, 94, 15, - 5, 232, 91, 15, 5, 232, 89, 15, 5, 232, 90, 115, 232, 89, 15, 5, 232, 90, - 115, 232, 90, 243, 104, 115, 243, 103, 15, 5, 186, 15, 5, 231, 244, 30, - 217, 73, 15, 5, 231, 244, 242, 101, 15, 5, 231, 243, 15, 5, 231, 215, 15, - 5, 231, 171, 15, 5, 231, 152, 15, 5, 231, 151, 15, 5, 231, 96, 15, 5, - 231, 52, 15, 5, 230, 235, 15, 5, 230, 193, 15, 5, 230, 107, 15, 5, 230, - 108, 115, 230, 107, 15, 5, 230, 98, 15, 5, 230, 99, 242, 101, 15, 5, 230, - 83, 15, 5, 230, 69, 15, 5, 230, 66, 15, 5, 230, 67, 30, 61, 15, 5, 230, - 67, 30, 233, 202, 15, 5, 230, 67, 30, 210, 116, 15, 5, 230, 67, 115, 230, - 66, 15, 5, 230, 67, 115, 230, 67, 30, 116, 96, 198, 15, 5, 230, 67, 249, - 133, 230, 66, 15, 5, 230, 64, 15, 5, 230, 65, 30, 61, 15, 5, 230, 65, 30, - 116, 96, 248, 11, 15, 5, 230, 65, 30, 248, 11, 15, 5, 230, 65, 242, 101, - 15, 5, 198, 15, 5, 229, 232, 15, 5, 229, 221, 15, 5, 229, 222, 235, 199, - 15, 5, 229, 222, 30, 219, 228, 216, 240, 15, 5, 229, 222, 226, 168, 229, - 221, 15, 5, 229, 220, 15, 5, 229, 213, 227, 184, 15, 5, 229, 212, 15, 5, - 229, 211, 15, 5, 229, 112, 15, 5, 229, 113, 30, 61, 15, 5, 229, 113, 30, - 214, 219, 15, 5, 229, 113, 220, 47, 15, 5, 228, 238, 15, 5, 228, 239, 30, - 76, 15, 5, 228, 237, 15, 5, 228, 208, 15, 5, 228, 209, 30, 243, 112, 216, - 240, 15, 5, 228, 209, 30, 243, 104, 96, 243, 112, 216, 240, 15, 5, 228, - 206, 15, 5, 228, 207, 30, 254, 131, 15, 5, 228, 207, 30, 253, 239, 15, 5, - 228, 207, 30, 253, 240, 96, 253, 239, 15, 5, 228, 207, 30, 242, 110, 15, - 5, 228, 207, 30, 231, 97, 96, 243, 112, 216, 240, 15, 5, 228, 207, 30, - 229, 112, 15, 5, 228, 207, 30, 227, 198, 15, 5, 228, 207, 30, 220, 65, - 15, 5, 228, 207, 30, 220, 66, 96, 116, 254, 131, 15, 5, 228, 207, 30, - 220, 66, 96, 253, 239, 15, 5, 228, 207, 30, 220, 66, 96, 253, 240, 96, - 253, 239, 15, 5, 228, 207, 30, 214, 231, 96, 253, 239, 15, 5, 228, 207, - 30, 214, 126, 15, 5, 228, 195, 15, 5, 227, 242, 15, 5, 227, 214, 15, 5, - 227, 198, 15, 5, 227, 199, 233, 122, 30, 243, 103, 15, 5, 227, 199, 233, - 122, 30, 231, 152, 15, 5, 227, 199, 233, 122, 30, 222, 10, 15, 5, 227, - 199, 233, 122, 30, 222, 11, 115, 227, 199, 233, 122, 30, 222, 10, 15, 5, - 227, 199, 233, 122, 30, 214, 126, 15, 5, 227, 199, 216, 240, 15, 5, 227, - 199, 115, 227, 198, 15, 5, 227, 199, 249, 133, 227, 198, 15, 5, 227, 199, - 249, 133, 227, 199, 233, 122, 115, 233, 121, 15, 5, 227, 193, 15, 5, 227, - 194, 255, 33, 30, 253, 234, 15, 5, 227, 194, 255, 33, 30, 252, 14, 15, 5, - 227, 194, 255, 33, 30, 246, 82, 15, 5, 227, 194, 255, 33, 30, 242, 110, - 15, 5, 227, 194, 255, 33, 30, 236, 43, 242, 101, 15, 5, 227, 194, 255, - 33, 30, 235, 5, 15, 5, 227, 194, 255, 33, 30, 233, 141, 15, 5, 227, 194, - 255, 33, 30, 229, 112, 15, 5, 227, 194, 255, 33, 30, 219, 173, 15, 5, - 227, 194, 255, 33, 30, 214, 230, 15, 5, 227, 194, 234, 72, 30, 252, 14, - 15, 5, 227, 194, 234, 72, 30, 252, 15, 69, 15, 5, 191, 15, 5, 226, 84, - 15, 5, 226, 51, 15, 5, 226, 25, 15, 5, 225, 164, 15, 5, 225, 111, 15, 5, - 225, 112, 30, 61, 15, 5, 225, 112, 30, 255, 34, 15, 5, 225, 112, 30, 252, - 14, 15, 5, 225, 112, 30, 251, 133, 15, 5, 225, 112, 30, 76, 15, 5, 225, - 112, 30, 74, 15, 5, 225, 112, 30, 240, 122, 15, 5, 225, 112, 30, 69, 15, - 5, 225, 112, 30, 214, 230, 15, 5, 225, 112, 249, 133, 225, 111, 15, 5, - 225, 56, 15, 5, 225, 57, 30, 234, 244, 15, 5, 225, 57, 30, 214, 219, 15, - 5, 225, 57, 30, 210, 116, 15, 5, 225, 57, 226, 168, 225, 56, 15, 5, 205, - 15, 5, 223, 185, 15, 5, 223, 38, 15, 5, 222, 142, 15, 5, 206, 15, 5, 222, - 24, 227, 184, 15, 5, 222, 23, 15, 5, 222, 24, 30, 61, 15, 5, 222, 24, 30, - 246, 86, 15, 5, 222, 24, 30, 246, 84, 15, 5, 222, 24, 30, 162, 15, 5, - 222, 24, 30, 234, 248, 15, 5, 222, 24, 30, 233, 202, 15, 5, 222, 24, 30, - 232, 89, 15, 5, 222, 24, 30, 230, 235, 15, 5, 222, 24, 30, 227, 198, 15, - 5, 222, 24, 30, 222, 10, 15, 5, 222, 24, 30, 220, 32, 15, 5, 222, 24, 30, - 217, 94, 15, 5, 222, 24, 30, 214, 230, 15, 5, 222, 24, 30, 214, 225, 15, - 5, 222, 24, 30, 214, 197, 15, 5, 222, 24, 30, 214, 150, 15, 5, 222, 24, - 30, 214, 126, 15, 5, 222, 24, 115, 222, 23, 15, 5, 222, 24, 242, 101, 15, - 5, 222, 10, 15, 5, 222, 11, 233, 124, 30, 253, 237, 15, 5, 221, 241, 15, - 5, 221, 233, 15, 5, 220, 104, 15, 5, 220, 102, 15, 5, 220, 103, 30, 61, - 15, 5, 220, 103, 30, 252, 184, 15, 5, 220, 103, 30, 242, 197, 15, 5, 220, - 103, 30, 229, 112, 15, 5, 220, 103, 30, 219, 225, 15, 5, 220, 103, 30, - 215, 99, 15, 5, 220, 103, 30, 69, 15, 5, 220, 103, 30, 104, 96, 61, 15, - 5, 220, 101, 15, 5, 220, 99, 15, 5, 220, 80, 15, 5, 220, 65, 15, 5, 220, - 66, 240, 229, 15, 5, 220, 66, 115, 220, 66, 243, 134, 115, 243, 134, 243, - 104, 115, 243, 103, 15, 5, 220, 66, 115, 220, 66, 217, 95, 115, 217, 95, - 243, 104, 115, 243, 103, 15, 5, 220, 58, 15, 5, 220, 53, 15, 5, 220, 50, - 15, 5, 220, 49, 15, 5, 220, 46, 15, 5, 220, 32, 15, 5, 220, 33, 30, 61, - 15, 5, 220, 33, 30, 236, 23, 15, 5, 220, 26, 15, 5, 220, 27, 30, 61, 15, - 5, 220, 27, 30, 252, 169, 15, 5, 220, 27, 30, 251, 117, 15, 5, 220, 27, - 30, 247, 214, 15, 5, 220, 27, 30, 243, 103, 15, 5, 220, 27, 30, 236, 42, - 15, 5, 220, 27, 30, 236, 43, 242, 101, 15, 5, 220, 27, 30, 233, 197, 15, - 5, 220, 27, 30, 232, 91, 15, 5, 220, 27, 30, 230, 98, 15, 5, 220, 27, 30, - 222, 10, 15, 5, 220, 20, 15, 5, 220, 15, 15, 5, 220, 16, 216, 240, 15, 5, - 220, 16, 115, 220, 16, 251, 107, 115, 251, 106, 15, 5, 220, 11, 15, 5, - 219, 227, 15, 5, 219, 228, 115, 235, 200, 219, 227, 15, 5, 219, 225, 15, - 5, 219, 224, 15, 5, 219, 193, 15, 5, 219, 194, 242, 101, 15, 5, 219, 184, - 15, 5, 219, 182, 15, 5, 219, 183, 115, 219, 183, 219, 225, 15, 5, 219, - 175, 15, 5, 219, 173, 15, 5, 218, 84, 15, 5, 218, 85, 115, 218, 84, 15, - 5, 218, 55, 15, 5, 218, 54, 15, 5, 218, 52, 15, 5, 218, 44, 15, 5, 218, - 43, 15, 5, 218, 18, 15, 5, 218, 17, 15, 5, 217, 106, 15, 5, 217, 107, - 253, 224, 15, 5, 217, 107, 30, 241, 187, 15, 5, 217, 107, 30, 230, 235, - 15, 5, 217, 107, 242, 101, 15, 5, 217, 94, 15, 5, 217, 95, 115, 217, 95, - 228, 239, 115, 228, 239, 247, 196, 115, 247, 195, 15, 5, 217, 95, 218, - 235, 15, 5, 217, 85, 15, 5, 129, 30, 252, 14, 15, 5, 129, 30, 242, 110, - 15, 5, 129, 30, 220, 65, 15, 5, 129, 30, 219, 227, 15, 5, 129, 30, 215, - 114, 15, 5, 129, 30, 214, 219, 15, 5, 217, 73, 15, 5, 217, 51, 15, 5, - 217, 23, 15, 5, 217, 24, 242, 101, 15, 5, 216, 118, 15, 5, 216, 119, 216, - 240, 15, 5, 216, 91, 15, 5, 216, 73, 15, 5, 216, 74, 30, 217, 73, 15, 5, - 216, 74, 115, 216, 73, 15, 5, 216, 74, 115, 216, 74, 243, 134, 115, 243, - 134, 243, 104, 115, 243, 103, 15, 5, 215, 119, 15, 5, 215, 114, 15, 5, - 215, 112, 15, 5, 215, 109, 15, 5, 215, 99, 15, 5, 215, 100, 115, 215, - 100, 210, 117, 115, 210, 116, 15, 5, 69, 15, 5, 104, 242, 110, 15, 5, - 104, 104, 69, 15, 5, 104, 115, 104, 226, 94, 115, 226, 94, 243, 104, 115, - 243, 103, 15, 5, 104, 115, 104, 218, 19, 115, 218, 18, 15, 5, 104, 115, - 104, 104, 223, 52, 115, 104, 223, 51, 15, 5, 214, 230, 15, 5, 214, 225, - 15, 5, 214, 219, 15, 5, 214, 220, 233, 197, 15, 5, 214, 220, 30, 252, - 184, 15, 5, 214, 220, 30, 230, 235, 15, 5, 214, 220, 30, 104, 96, 104, - 96, 69, 15, 5, 214, 220, 30, 104, 96, 104, 96, 104, 242, 101, 15, 5, 214, - 220, 242, 101, 15, 5, 214, 220, 220, 47, 15, 5, 214, 220, 220, 48, 30, - 252, 184, 15, 5, 214, 215, 15, 5, 214, 197, 15, 5, 214, 198, 30, 233, - 123, 15, 5, 214, 198, 30, 231, 97, 96, 248, 229, 15, 5, 214, 198, 30, - 220, 102, 15, 5, 214, 198, 30, 69, 15, 5, 214, 196, 15, 5, 214, 192, 15, - 5, 214, 193, 30, 234, 213, 15, 5, 214, 193, 30, 191, 15, 5, 214, 190, 15, - 5, 214, 191, 242, 101, 15, 5, 214, 150, 15, 5, 214, 151, 249, 133, 214, - 150, 15, 5, 214, 151, 220, 47, 15, 5, 214, 148, 15, 5, 214, 149, 30, 116, - 96, 162, 15, 5, 214, 149, 30, 116, 96, 198, 15, 5, 214, 149, 30, 254, - 187, 15, 5, 214, 149, 30, 162, 15, 5, 214, 149, 30, 227, 198, 15, 5, 214, - 149, 30, 214, 230, 15, 5, 214, 149, 30, 214, 231, 96, 253, 239, 15, 5, - 214, 149, 30, 214, 231, 96, 252, 14, 15, 5, 214, 147, 15, 5, 214, 144, - 15, 5, 214, 143, 15, 5, 214, 139, 15, 5, 214, 140, 30, 61, 15, 5, 214, - 140, 30, 253, 234, 15, 5, 214, 140, 30, 130, 15, 5, 214, 140, 30, 246, - 76, 15, 5, 214, 140, 30, 243, 142, 15, 5, 214, 140, 30, 243, 125, 15, 5, - 214, 140, 30, 243, 112, 216, 240, 15, 5, 214, 140, 30, 243, 103, 15, 5, - 214, 140, 30, 242, 120, 15, 5, 214, 140, 30, 162, 15, 5, 214, 140, 30, - 236, 42, 15, 5, 214, 140, 30, 236, 23, 15, 5, 214, 140, 30, 235, 172, 15, - 5, 214, 140, 30, 234, 98, 15, 5, 214, 140, 30, 232, 89, 15, 5, 214, 140, - 30, 230, 193, 15, 5, 214, 140, 30, 191, 15, 5, 214, 140, 30, 220, 65, 15, - 5, 214, 140, 30, 219, 182, 15, 5, 214, 140, 30, 215, 119, 15, 5, 214, - 140, 30, 104, 96, 242, 110, 15, 5, 214, 140, 30, 214, 219, 15, 5, 214, - 140, 30, 214, 137, 15, 5, 214, 137, 15, 5, 214, 138, 30, 69, 15, 5, 214, - 126, 15, 5, 214, 127, 30, 61, 15, 5, 214, 127, 30, 233, 223, 15, 5, 214, - 127, 30, 233, 202, 15, 5, 214, 127, 30, 217, 73, 15, 5, 214, 122, 15, 5, - 214, 125, 15, 5, 214, 123, 15, 5, 214, 119, 15, 5, 214, 108, 15, 5, 214, - 109, 30, 234, 213, 15, 5, 214, 107, 15, 5, 210, 116, 15, 5, 210, 117, - 216, 240, 15, 5, 210, 117, 92, 30, 233, 202, 15, 5, 210, 113, 15, 5, 210, - 106, 15, 5, 210, 93, 15, 5, 210, 44, 15, 5, 210, 45, 115, 210, 44, 15, 5, - 210, 43, 15, 5, 210, 41, 15, 5, 210, 42, 235, 9, 216, 240, 15, 5, 210, - 36, 15, 5, 210, 28, 15, 5, 210, 13, 15, 5, 210, 11, 15, 5, 210, 12, 30, - 61, 15, 5, 210, 10, 15, 5, 210, 9, 15, 132, 5, 113, 253, 239, 15, 132, 5, - 134, 253, 239, 15, 132, 5, 244, 19, 253, 239, 15, 132, 5, 244, 89, 253, - 239, 15, 132, 5, 219, 127, 253, 239, 15, 132, 5, 220, 124, 253, 239, 15, - 132, 5, 245, 201, 253, 239, 15, 132, 5, 228, 205, 253, 239, 15, 132, 5, - 134, 247, 195, 15, 132, 5, 244, 19, 247, 195, 15, 132, 5, 244, 89, 247, - 195, 15, 132, 5, 219, 127, 247, 195, 15, 132, 5, 220, 124, 247, 195, 15, - 132, 5, 245, 201, 247, 195, 15, 132, 5, 228, 205, 247, 195, 15, 132, 5, - 244, 19, 69, 15, 132, 5, 244, 89, 69, 15, 132, 5, 219, 127, 69, 15, 132, - 5, 220, 124, 69, 15, 132, 5, 245, 201, 69, 15, 132, 5, 228, 205, 69, 15, - 132, 5, 123, 243, 45, 15, 132, 5, 113, 243, 45, 15, 132, 5, 134, 243, 45, - 15, 132, 5, 244, 19, 243, 45, 15, 132, 5, 244, 89, 243, 45, 15, 132, 5, - 219, 127, 243, 45, 15, 132, 5, 220, 124, 243, 45, 15, 132, 5, 245, 201, - 243, 45, 15, 132, 5, 228, 205, 243, 45, 15, 132, 5, 123, 243, 42, 15, - 132, 5, 113, 243, 42, 15, 132, 5, 134, 243, 42, 15, 132, 5, 244, 19, 243, - 42, 15, 132, 5, 244, 89, 243, 42, 15, 132, 5, 113, 220, 80, 15, 132, 5, - 134, 220, 80, 15, 132, 5, 134, 220, 81, 214, 12, 17, 15, 132, 5, 244, 19, - 220, 80, 15, 132, 5, 244, 89, 220, 80, 15, 132, 5, 219, 127, 220, 80, 15, - 132, 5, 220, 124, 220, 80, 15, 132, 5, 245, 201, 220, 80, 15, 132, 5, - 228, 205, 220, 80, 15, 132, 5, 123, 220, 75, 15, 132, 5, 113, 220, 75, - 15, 132, 5, 134, 220, 75, 15, 132, 5, 134, 220, 76, 214, 12, 17, 15, 132, - 5, 244, 19, 220, 75, 15, 132, 5, 244, 89, 220, 75, 15, 132, 5, 220, 81, - 30, 243, 126, 96, 247, 195, 15, 132, 5, 220, 81, 30, 243, 126, 96, 230, - 193, 15, 132, 5, 123, 251, 103, 15, 132, 5, 113, 251, 103, 15, 132, 5, - 134, 251, 103, 15, 132, 5, 134, 251, 104, 214, 12, 17, 15, 132, 5, 244, - 19, 251, 103, 15, 132, 5, 244, 89, 251, 103, 15, 132, 5, 134, 214, 12, - 244, 28, 245, 82, 15, 132, 5, 134, 214, 12, 244, 28, 245, 79, 15, 132, 5, - 244, 19, 214, 12, 244, 28, 232, 223, 15, 132, 5, 244, 19, 214, 12, 244, - 28, 232, 221, 15, 132, 5, 244, 19, 214, 12, 244, 28, 232, 224, 61, 15, - 132, 5, 244, 19, 214, 12, 244, 28, 232, 224, 253, 166, 15, 132, 5, 219, - 127, 214, 12, 244, 28, 253, 236, 15, 132, 5, 220, 124, 214, 12, 244, 28, - 236, 15, 15, 132, 5, 220, 124, 214, 12, 244, 28, 236, 17, 61, 15, 132, 5, - 220, 124, 214, 12, 244, 28, 236, 17, 253, 166, 15, 132, 5, 245, 201, 214, - 12, 244, 28, 214, 121, 15, 132, 5, 245, 201, 214, 12, 244, 28, 214, 120, - 15, 132, 5, 228, 205, 214, 12, 244, 28, 236, 31, 15, 132, 5, 228, 205, - 214, 12, 244, 28, 236, 30, 15, 132, 5, 228, 205, 214, 12, 244, 28, 236, - 29, 15, 132, 5, 228, 205, 214, 12, 244, 28, 236, 32, 61, 15, 132, 5, 113, - 253, 240, 216, 240, 15, 132, 5, 134, 253, 240, 216, 240, 15, 132, 5, 244, - 19, 253, 240, 216, 240, 15, 132, 5, 244, 89, 253, 240, 216, 240, 15, 132, - 5, 219, 127, 253, 240, 216, 240, 15, 132, 5, 123, 252, 158, 15, 132, 5, - 113, 252, 158, 15, 132, 5, 134, 252, 158, 15, 132, 5, 244, 19, 252, 158, - 15, 132, 5, 244, 19, 252, 159, 214, 12, 17, 15, 132, 5, 244, 89, 252, - 158, 15, 132, 5, 244, 89, 252, 159, 214, 12, 17, 15, 132, 5, 228, 215, - 15, 132, 5, 228, 216, 15, 132, 5, 123, 245, 78, 15, 132, 5, 113, 245, 78, - 15, 132, 5, 123, 216, 170, 247, 195, 15, 132, 5, 113, 216, 168, 247, 195, - 15, 132, 5, 244, 89, 219, 116, 247, 195, 15, 132, 5, 123, 216, 170, 214, - 12, 244, 28, 61, 15, 132, 5, 113, 216, 168, 214, 12, 244, 28, 61, 15, - 132, 5, 123, 245, 197, 253, 239, 15, 132, 5, 123, 224, 25, 253, 239, 15, - 132, 5, 55, 253, 227, 123, 219, 117, 15, 132, 5, 55, 253, 227, 123, 224, - 24, 15, 224, 144, 5, 55, 253, 227, 211, 209, 247, 180, 15, 224, 144, 5, - 67, 249, 234, 15, 224, 144, 5, 248, 7, 249, 234, 15, 224, 144, 5, 248, 7, - 215, 222, 12, 13, 255, 164, 12, 13, 255, 163, 12, 13, 255, 162, 12, 13, - 255, 161, 12, 13, 255, 160, 12, 13, 255, 159, 12, 13, 255, 158, 12, 13, - 255, 157, 12, 13, 255, 156, 12, 13, 255, 155, 12, 13, 255, 154, 12, 13, - 255, 153, 12, 13, 255, 152, 12, 13, 255, 151, 12, 13, 255, 150, 12, 13, - 255, 149, 12, 13, 255, 148, 12, 13, 255, 147, 12, 13, 255, 146, 12, 13, - 255, 145, 12, 13, 255, 144, 12, 13, 255, 143, 12, 13, 255, 142, 12, 13, - 255, 141, 12, 13, 255, 140, 12, 13, 255, 139, 12, 13, 255, 138, 12, 13, - 255, 137, 12, 13, 255, 136, 12, 13, 255, 135, 12, 13, 255, 134, 12, 13, - 255, 133, 12, 13, 255, 132, 12, 13, 255, 131, 12, 13, 255, 130, 12, 13, - 255, 129, 12, 13, 255, 128, 12, 13, 255, 127, 12, 13, 255, 126, 12, 13, - 255, 125, 12, 13, 255, 124, 12, 13, 255, 123, 12, 13, 255, 122, 12, 13, - 255, 121, 12, 13, 255, 120, 12, 13, 255, 119, 12, 13, 255, 118, 12, 13, - 255, 117, 12, 13, 255, 116, 12, 13, 255, 115, 12, 13, 255, 114, 12, 13, - 255, 113, 12, 13, 255, 112, 12, 13, 255, 111, 12, 13, 255, 110, 12, 13, - 255, 109, 12, 13, 255, 108, 12, 13, 255, 107, 12, 13, 255, 106, 12, 13, - 255, 105, 12, 13, 255, 104, 12, 13, 255, 103, 12, 13, 255, 102, 12, 13, - 255, 101, 12, 13, 255, 100, 12, 13, 255, 99, 12, 13, 255, 98, 12, 13, - 255, 97, 12, 13, 255, 96, 12, 13, 255, 95, 12, 13, 255, 94, 12, 13, 255, - 93, 12, 13, 255, 92, 12, 13, 255, 91, 12, 13, 255, 90, 12, 13, 255, 89, - 12, 13, 255, 88, 12, 13, 255, 87, 12, 13, 255, 86, 12, 13, 255, 85, 12, - 13, 253, 164, 12, 13, 253, 162, 12, 13, 253, 160, 12, 13, 253, 158, 12, - 13, 253, 156, 12, 13, 253, 155, 12, 13, 253, 153, 12, 13, 253, 151, 12, - 13, 253, 149, 12, 13, 253, 147, 12, 13, 251, 70, 12, 13, 251, 69, 12, 13, - 251, 68, 12, 13, 251, 67, 12, 13, 251, 66, 12, 13, 251, 65, 12, 13, 251, - 64, 12, 13, 251, 63, 12, 13, 251, 62, 12, 13, 251, 61, 12, 13, 251, 60, - 12, 13, 251, 59, 12, 13, 251, 58, 12, 13, 251, 57, 12, 13, 251, 56, 12, - 13, 251, 55, 12, 13, 251, 54, 12, 13, 251, 53, 12, 13, 251, 52, 12, 13, - 251, 51, 12, 13, 251, 50, 12, 13, 251, 49, 12, 13, 251, 48, 12, 13, 251, - 47, 12, 13, 251, 46, 12, 13, 251, 45, 12, 13, 251, 44, 12, 13, 251, 43, - 12, 13, 249, 67, 12, 13, 249, 66, 12, 13, 249, 65, 12, 13, 249, 64, 12, - 13, 249, 63, 12, 13, 249, 62, 12, 13, 249, 61, 12, 13, 249, 60, 12, 13, - 249, 59, 12, 13, 249, 58, 12, 13, 249, 57, 12, 13, 249, 56, 12, 13, 249, - 55, 12, 13, 249, 54, 12, 13, 249, 53, 12, 13, 249, 52, 12, 13, 249, 51, - 12, 13, 249, 50, 12, 13, 249, 49, 12, 13, 249, 48, 12, 13, 249, 47, 12, - 13, 249, 46, 12, 13, 249, 45, 12, 13, 249, 44, 12, 13, 249, 43, 12, 13, - 249, 42, 12, 13, 249, 41, 12, 13, 249, 40, 12, 13, 249, 39, 12, 13, 249, - 38, 12, 13, 249, 37, 12, 13, 249, 36, 12, 13, 249, 35, 12, 13, 249, 34, - 12, 13, 249, 33, 12, 13, 249, 32, 12, 13, 249, 31, 12, 13, 249, 30, 12, - 13, 249, 29, 12, 13, 249, 28, 12, 13, 249, 27, 12, 13, 249, 26, 12, 13, - 249, 25, 12, 13, 249, 24, 12, 13, 249, 23, 12, 13, 249, 22, 12, 13, 249, - 21, 12, 13, 249, 20, 12, 13, 249, 19, 12, 13, 249, 18, 12, 13, 249, 17, - 12, 13, 249, 16, 12, 13, 249, 15, 12, 13, 249, 14, 12, 13, 249, 13, 12, - 13, 249, 12, 12, 13, 249, 11, 12, 13, 249, 10, 12, 13, 249, 9, 12, 13, - 249, 8, 12, 13, 249, 7, 12, 13, 249, 6, 12, 13, 249, 5, 12, 13, 249, 4, - 12, 13, 249, 3, 12, 13, 249, 2, 12, 13, 249, 1, 12, 13, 249, 0, 12, 13, - 248, 255, 12, 13, 248, 254, 12, 13, 248, 253, 12, 13, 248, 252, 12, 13, - 248, 251, 12, 13, 248, 250, 12, 13, 248, 249, 12, 13, 248, 248, 12, 13, - 248, 247, 12, 13, 248, 246, 12, 13, 248, 245, 12, 13, 248, 244, 12, 13, - 248, 243, 12, 13, 248, 242, 12, 13, 248, 241, 12, 13, 248, 240, 12, 13, - 248, 239, 12, 13, 248, 238, 12, 13, 248, 237, 12, 13, 248, 236, 12, 13, - 248, 235, 12, 13, 248, 234, 12, 13, 248, 233, 12, 13, 248, 232, 12, 13, - 246, 31, 12, 13, 246, 30, 12, 13, 246, 29, 12, 13, 246, 28, 12, 13, 246, - 27, 12, 13, 246, 26, 12, 13, 246, 25, 12, 13, 246, 24, 12, 13, 246, 23, - 12, 13, 246, 22, 12, 13, 246, 21, 12, 13, 246, 20, 12, 13, 246, 19, 12, - 13, 246, 18, 12, 13, 246, 17, 12, 13, 246, 16, 12, 13, 246, 15, 12, 13, - 246, 14, 12, 13, 246, 13, 12, 13, 246, 12, 12, 13, 246, 11, 12, 13, 246, - 10, 12, 13, 246, 9, 12, 13, 246, 8, 12, 13, 246, 7, 12, 13, 246, 6, 12, - 13, 246, 5, 12, 13, 246, 4, 12, 13, 246, 3, 12, 13, 246, 2, 12, 13, 246, - 1, 12, 13, 246, 0, 12, 13, 245, 255, 12, 13, 245, 254, 12, 13, 245, 253, - 12, 13, 245, 252, 12, 13, 245, 251, 12, 13, 245, 250, 12, 13, 245, 249, - 12, 13, 245, 248, 12, 13, 245, 247, 12, 13, 245, 246, 12, 13, 245, 245, - 12, 13, 245, 244, 12, 13, 245, 13, 12, 13, 245, 12, 12, 13, 245, 11, 12, - 13, 245, 10, 12, 13, 245, 9, 12, 13, 245, 8, 12, 13, 245, 7, 12, 13, 245, - 6, 12, 13, 245, 5, 12, 13, 245, 4, 12, 13, 245, 3, 12, 13, 245, 2, 12, - 13, 245, 1, 12, 13, 245, 0, 12, 13, 244, 255, 12, 13, 244, 254, 12, 13, - 244, 253, 12, 13, 244, 252, 12, 13, 244, 251, 12, 13, 244, 250, 12, 13, - 244, 249, 12, 13, 244, 248, 12, 13, 244, 247, 12, 13, 244, 246, 12, 13, - 244, 245, 12, 13, 244, 244, 12, 13, 244, 243, 12, 13, 244, 242, 12, 13, - 244, 241, 12, 13, 244, 240, 12, 13, 244, 239, 12, 13, 244, 238, 12, 13, - 244, 237, 12, 13, 244, 236, 12, 13, 244, 235, 12, 13, 244, 234, 12, 13, - 244, 233, 12, 13, 244, 232, 12, 13, 244, 231, 12, 13, 244, 230, 12, 13, - 244, 229, 12, 13, 244, 228, 12, 13, 244, 227, 12, 13, 244, 226, 12, 13, - 244, 225, 12, 13, 244, 224, 12, 13, 244, 223, 12, 13, 244, 222, 12, 13, - 244, 221, 12, 13, 244, 220, 12, 13, 244, 219, 12, 13, 244, 218, 12, 13, - 244, 217, 12, 13, 244, 216, 12, 13, 244, 215, 12, 13, 244, 214, 12, 13, - 244, 213, 12, 13, 244, 212, 12, 13, 244, 211, 12, 13, 244, 210, 12, 13, - 244, 209, 12, 13, 244, 208, 12, 13, 244, 207, 12, 13, 244, 206, 12, 13, - 244, 205, 12, 13, 243, 208, 12, 13, 243, 207, 12, 13, 243, 206, 12, 13, - 243, 205, 12, 13, 243, 204, 12, 13, 243, 203, 12, 13, 243, 202, 12, 13, - 243, 201, 12, 13, 243, 200, 12, 13, 243, 199, 12, 13, 243, 198, 12, 13, - 243, 197, 12, 13, 243, 196, 12, 13, 243, 195, 12, 13, 243, 194, 12, 13, - 243, 193, 12, 13, 243, 192, 12, 13, 243, 191, 12, 13, 243, 190, 12, 13, - 243, 189, 12, 13, 243, 188, 12, 13, 243, 187, 12, 13, 243, 186, 12, 13, - 243, 185, 12, 13, 243, 184, 12, 13, 243, 183, 12, 13, 243, 182, 12, 13, - 243, 181, 12, 13, 243, 180, 12, 13, 243, 179, 12, 13, 243, 178, 12, 13, - 243, 177, 12, 13, 243, 176, 12, 13, 243, 175, 12, 13, 243, 174, 12, 13, - 243, 173, 12, 13, 243, 172, 12, 13, 243, 171, 12, 13, 243, 170, 12, 13, - 243, 169, 12, 13, 243, 168, 12, 13, 243, 167, 12, 13, 243, 166, 12, 13, - 243, 165, 12, 13, 243, 164, 12, 13, 243, 163, 12, 13, 243, 162, 12, 13, - 243, 161, 12, 13, 243, 160, 12, 13, 243, 159, 12, 13, 243, 158, 12, 13, - 243, 157, 12, 13, 243, 156, 12, 13, 243, 155, 12, 13, 243, 154, 12, 13, - 243, 153, 12, 13, 243, 152, 12, 13, 243, 151, 12, 13, 243, 150, 12, 13, - 243, 149, 12, 13, 243, 148, 12, 13, 243, 147, 12, 13, 243, 146, 12, 13, - 243, 145, 12, 13, 242, 65, 12, 13, 242, 64, 12, 13, 242, 63, 12, 13, 242, - 62, 12, 13, 242, 61, 12, 13, 242, 60, 12, 13, 242, 59, 12, 13, 242, 58, - 12, 13, 242, 57, 12, 13, 240, 145, 12, 13, 240, 144, 12, 13, 240, 143, - 12, 13, 240, 142, 12, 13, 240, 141, 12, 13, 240, 140, 12, 13, 240, 139, - 12, 13, 240, 138, 12, 13, 240, 137, 12, 13, 240, 136, 12, 13, 240, 135, - 12, 13, 240, 134, 12, 13, 240, 133, 12, 13, 240, 132, 12, 13, 240, 131, - 12, 13, 240, 130, 12, 13, 240, 129, 12, 13, 240, 128, 12, 13, 240, 127, - 12, 13, 235, 28, 12, 13, 235, 27, 12, 13, 235, 26, 12, 13, 235, 25, 12, - 13, 235, 24, 12, 13, 235, 23, 12, 13, 235, 22, 12, 13, 235, 21, 12, 13, - 233, 152, 12, 13, 233, 151, 12, 13, 233, 150, 12, 13, 233, 149, 12, 13, - 233, 148, 12, 13, 233, 147, 12, 13, 233, 146, 12, 13, 233, 145, 12, 13, - 233, 144, 12, 13, 233, 143, 12, 13, 232, 54, 12, 13, 232, 53, 12, 13, - 232, 52, 12, 13, 232, 51, 12, 13, 232, 50, 12, 13, 232, 49, 12, 13, 232, - 48, 12, 13, 232, 47, 12, 13, 232, 46, 12, 13, 232, 45, 12, 13, 232, 44, - 12, 13, 232, 43, 12, 13, 232, 42, 12, 13, 232, 41, 12, 13, 232, 40, 12, - 13, 232, 39, 12, 13, 232, 38, 12, 13, 232, 37, 12, 13, 232, 36, 12, 13, - 232, 35, 12, 13, 232, 34, 12, 13, 232, 33, 12, 13, 232, 32, 12, 13, 232, - 31, 12, 13, 232, 30, 12, 13, 232, 29, 12, 13, 232, 28, 12, 13, 232, 27, - 12, 13, 232, 26, 12, 13, 232, 25, 12, 13, 232, 24, 12, 13, 232, 23, 12, - 13, 232, 22, 12, 13, 232, 21, 12, 13, 232, 20, 12, 13, 232, 19, 12, 13, - 232, 18, 12, 13, 232, 17, 12, 13, 232, 16, 12, 13, 232, 15, 12, 13, 232, - 14, 12, 13, 232, 13, 12, 13, 232, 12, 12, 13, 232, 11, 12, 13, 232, 10, - 12, 13, 232, 9, 12, 13, 232, 8, 12, 13, 232, 7, 12, 13, 232, 6, 12, 13, - 232, 5, 12, 13, 232, 4, 12, 13, 232, 3, 12, 13, 232, 2, 12, 13, 232, 1, - 12, 13, 232, 0, 12, 13, 231, 255, 12, 13, 231, 254, 12, 13, 231, 253, 12, - 13, 231, 252, 12, 13, 231, 251, 12, 13, 231, 250, 12, 13, 231, 249, 12, - 13, 231, 248, 12, 13, 231, 247, 12, 13, 231, 246, 12, 13, 231, 245, 12, - 13, 230, 27, 12, 13, 230, 26, 12, 13, 230, 25, 12, 13, 230, 24, 12, 13, - 230, 23, 12, 13, 230, 22, 12, 13, 230, 21, 12, 13, 230, 20, 12, 13, 230, - 19, 12, 13, 230, 18, 12, 13, 230, 17, 12, 13, 230, 16, 12, 13, 230, 15, - 12, 13, 230, 14, 12, 13, 230, 13, 12, 13, 230, 12, 12, 13, 230, 11, 12, - 13, 230, 10, 12, 13, 230, 9, 12, 13, 230, 8, 12, 13, 230, 7, 12, 13, 230, - 6, 12, 13, 230, 5, 12, 13, 230, 4, 12, 13, 230, 3, 12, 13, 230, 2, 12, - 13, 230, 1, 12, 13, 230, 0, 12, 13, 229, 255, 12, 13, 229, 254, 12, 13, - 229, 253, 12, 13, 229, 252, 12, 13, 229, 251, 12, 13, 229, 250, 12, 13, - 229, 249, 12, 13, 229, 248, 12, 13, 229, 247, 12, 13, 229, 246, 12, 13, - 229, 245, 12, 13, 229, 244, 12, 13, 229, 243, 12, 13, 229, 242, 12, 13, - 229, 241, 12, 13, 229, 240, 12, 13, 229, 239, 12, 13, 229, 238, 12, 13, - 229, 237, 12, 13, 229, 236, 12, 13, 229, 235, 12, 13, 228, 139, 12, 13, - 228, 138, 12, 13, 228, 137, 12, 13, 228, 136, 12, 13, 228, 135, 12, 13, - 228, 134, 12, 13, 228, 133, 12, 13, 228, 132, 12, 13, 228, 131, 12, 13, - 228, 130, 12, 13, 228, 129, 12, 13, 228, 128, 12, 13, 228, 127, 12, 13, - 228, 126, 12, 13, 228, 125, 12, 13, 228, 124, 12, 13, 228, 123, 12, 13, - 228, 122, 12, 13, 228, 121, 12, 13, 228, 120, 12, 13, 228, 119, 12, 13, - 228, 118, 12, 13, 227, 241, 12, 13, 227, 240, 12, 13, 227, 239, 12, 13, - 227, 238, 12, 13, 227, 237, 12, 13, 227, 236, 12, 13, 227, 235, 12, 13, - 227, 234, 12, 13, 227, 233, 12, 13, 227, 232, 12, 13, 227, 231, 12, 13, - 227, 230, 12, 13, 227, 229, 12, 13, 227, 228, 12, 13, 227, 227, 12, 13, - 227, 226, 12, 13, 227, 225, 12, 13, 227, 224, 12, 13, 227, 223, 12, 13, - 227, 222, 12, 13, 227, 221, 12, 13, 227, 220, 12, 13, 227, 219, 12, 13, - 227, 218, 12, 13, 227, 217, 12, 13, 227, 216, 12, 13, 227, 80, 12, 13, - 227, 79, 12, 13, 227, 78, 12, 13, 227, 77, 12, 13, 227, 76, 12, 13, 227, - 75, 12, 13, 227, 74, 12, 13, 227, 73, 12, 13, 227, 72, 12, 13, 227, 71, - 12, 13, 227, 70, 12, 13, 227, 69, 12, 13, 227, 68, 12, 13, 227, 67, 12, - 13, 227, 66, 12, 13, 227, 65, 12, 13, 227, 64, 12, 13, 227, 63, 12, 13, - 227, 62, 12, 13, 227, 61, 12, 13, 227, 60, 12, 13, 227, 59, 12, 13, 227, - 58, 12, 13, 227, 57, 12, 13, 227, 56, 12, 13, 227, 55, 12, 13, 227, 54, - 12, 13, 227, 53, 12, 13, 227, 52, 12, 13, 227, 51, 12, 13, 227, 50, 12, - 13, 227, 49, 12, 13, 227, 48, 12, 13, 227, 47, 12, 13, 227, 46, 12, 13, - 227, 45, 12, 13, 227, 44, 12, 13, 227, 43, 12, 13, 227, 42, 12, 13, 227, - 41, 12, 13, 227, 40, 12, 13, 227, 39, 12, 13, 227, 38, 12, 13, 227, 37, - 12, 13, 227, 36, 12, 13, 227, 35, 12, 13, 227, 34, 12, 13, 227, 33, 12, - 13, 227, 32, 12, 13, 227, 31, 12, 13, 227, 30, 12, 13, 227, 29, 12, 13, - 227, 28, 12, 13, 227, 27, 12, 13, 227, 26, 12, 13, 227, 25, 12, 13, 227, - 24, 12, 13, 227, 23, 12, 13, 227, 22, 12, 13, 227, 21, 12, 13, 227, 20, - 12, 13, 227, 19, 12, 13, 227, 18, 12, 13, 227, 17, 12, 13, 227, 16, 12, - 13, 227, 15, 12, 13, 227, 14, 12, 13, 227, 13, 12, 13, 227, 12, 12, 13, - 227, 11, 12, 13, 227, 10, 12, 13, 227, 9, 12, 13, 227, 8, 12, 13, 227, 7, - 12, 13, 227, 6, 12, 13, 226, 108, 12, 13, 226, 107, 12, 13, 226, 106, 12, - 13, 226, 105, 12, 13, 226, 104, 12, 13, 226, 103, 12, 13, 226, 102, 12, - 13, 226, 101, 12, 13, 226, 100, 12, 13, 226, 99, 12, 13, 226, 98, 12, 13, - 226, 97, 12, 13, 226, 96, 12, 13, 224, 98, 12, 13, 224, 97, 12, 13, 224, - 96, 12, 13, 224, 95, 12, 13, 224, 94, 12, 13, 224, 93, 12, 13, 224, 92, - 12, 13, 223, 225, 12, 13, 223, 224, 12, 13, 223, 223, 12, 13, 223, 222, - 12, 13, 223, 221, 12, 13, 223, 220, 12, 13, 223, 219, 12, 13, 223, 218, - 12, 13, 223, 217, 12, 13, 223, 216, 12, 13, 223, 215, 12, 13, 223, 214, - 12, 13, 223, 213, 12, 13, 223, 212, 12, 13, 223, 211, 12, 13, 223, 210, - 12, 13, 223, 209, 12, 13, 223, 208, 12, 13, 223, 207, 12, 13, 223, 206, - 12, 13, 223, 205, 12, 13, 223, 204, 12, 13, 223, 203, 12, 13, 223, 202, - 12, 13, 223, 201, 12, 13, 223, 200, 12, 13, 223, 199, 12, 13, 223, 198, - 12, 13, 223, 197, 12, 13, 223, 196, 12, 13, 223, 195, 12, 13, 223, 194, - 12, 13, 223, 193, 12, 13, 223, 192, 12, 13, 222, 90, 12, 13, 222, 89, 12, - 13, 222, 88, 12, 13, 222, 87, 12, 13, 222, 86, 12, 13, 222, 85, 12, 13, - 222, 84, 12, 13, 222, 83, 12, 13, 222, 82, 12, 13, 222, 81, 12, 13, 222, - 80, 12, 13, 222, 79, 12, 13, 222, 78, 12, 13, 222, 77, 12, 13, 222, 76, - 12, 13, 222, 75, 12, 13, 222, 74, 12, 13, 222, 73, 12, 13, 222, 72, 12, - 13, 222, 71, 12, 13, 222, 70, 12, 13, 222, 69, 12, 13, 222, 68, 12, 13, - 222, 67, 12, 13, 222, 66, 12, 13, 222, 65, 12, 13, 222, 64, 12, 13, 222, - 63, 12, 13, 222, 62, 12, 13, 222, 61, 12, 13, 222, 60, 12, 13, 222, 59, - 12, 13, 222, 58, 12, 13, 222, 57, 12, 13, 222, 56, 12, 13, 222, 55, 12, - 13, 222, 54, 12, 13, 222, 53, 12, 13, 222, 52, 12, 13, 222, 51, 12, 13, - 222, 50, 12, 13, 222, 49, 12, 13, 222, 48, 12, 13, 222, 47, 12, 13, 222, - 46, 12, 13, 222, 45, 12, 13, 222, 44, 12, 13, 222, 43, 12, 13, 222, 42, - 12, 13, 222, 41, 12, 13, 222, 40, 12, 13, 222, 39, 12, 13, 222, 38, 12, - 13, 222, 37, 12, 13, 217, 151, 12, 13, 217, 150, 12, 13, 217, 149, 12, - 13, 217, 148, 12, 13, 217, 147, 12, 13, 217, 146, 12, 13, 217, 145, 12, - 13, 217, 144, 12, 13, 217, 143, 12, 13, 217, 142, 12, 13, 217, 141, 12, - 13, 217, 140, 12, 13, 217, 139, 12, 13, 217, 138, 12, 13, 217, 137, 12, - 13, 217, 136, 12, 13, 217, 135, 12, 13, 217, 134, 12, 13, 217, 133, 12, - 13, 217, 132, 12, 13, 217, 131, 12, 13, 217, 130, 12, 13, 217, 129, 12, - 13, 217, 128, 12, 13, 217, 127, 12, 13, 217, 126, 12, 13, 217, 125, 12, - 13, 217, 124, 12, 13, 217, 123, 12, 13, 217, 122, 12, 13, 217, 121, 12, - 13, 217, 120, 12, 13, 217, 119, 12, 13, 217, 118, 12, 13, 217, 117, 12, - 13, 217, 116, 12, 13, 217, 115, 12, 13, 217, 114, 12, 13, 217, 113, 12, - 13, 217, 112, 12, 13, 217, 111, 12, 13, 217, 110, 12, 13, 217, 109, 12, - 13, 217, 108, 12, 13, 215, 22, 12, 13, 215, 21, 12, 13, 215, 20, 12, 13, - 215, 19, 12, 13, 215, 18, 12, 13, 215, 17, 12, 13, 215, 16, 12, 13, 215, - 15, 12, 13, 215, 14, 12, 13, 215, 13, 12, 13, 215, 12, 12, 13, 215, 11, - 12, 13, 215, 10, 12, 13, 215, 9, 12, 13, 215, 8, 12, 13, 215, 7, 12, 13, - 215, 6, 12, 13, 215, 5, 12, 13, 215, 4, 12, 13, 215, 3, 12, 13, 215, 2, - 12, 13, 215, 1, 12, 13, 215, 0, 12, 13, 214, 255, 12, 13, 214, 254, 12, - 13, 214, 253, 12, 13, 214, 252, 12, 13, 214, 251, 12, 13, 214, 250, 12, - 13, 214, 249, 12, 13, 214, 248, 12, 13, 214, 247, 12, 13, 214, 246, 12, - 13, 214, 245, 12, 13, 214, 244, 12, 13, 214, 243, 12, 13, 214, 242, 12, - 13, 214, 241, 12, 13, 214, 240, 12, 13, 214, 239, 12, 13, 214, 238, 12, - 13, 214, 237, 12, 13, 214, 236, 12, 13, 214, 235, 12, 13, 214, 234, 12, - 13, 214, 233, 12, 13, 214, 232, 12, 13, 214, 104, 12, 13, 214, 103, 12, - 13, 214, 102, 12, 13, 214, 101, 12, 13, 214, 100, 12, 13, 214, 99, 12, - 13, 214, 98, 12, 13, 214, 97, 12, 13, 214, 96, 12, 13, 214, 95, 12, 13, - 214, 94, 12, 13, 214, 93, 12, 13, 214, 92, 12, 13, 214, 91, 12, 13, 214, - 90, 12, 13, 214, 89, 12, 13, 214, 88, 12, 13, 214, 87, 12, 13, 214, 86, - 12, 13, 214, 85, 12, 13, 214, 84, 12, 13, 214, 83, 12, 13, 214, 82, 12, - 13, 214, 81, 12, 13, 214, 80, 12, 13, 214, 79, 12, 13, 214, 78, 12, 13, - 214, 77, 12, 13, 214, 76, 12, 13, 214, 75, 12, 13, 214, 74, 12, 13, 214, - 73, 12, 13, 214, 72, 12, 13, 214, 71, 12, 13, 214, 70, 12, 13, 214, 69, - 12, 13, 214, 68, 12, 13, 214, 67, 12, 13, 214, 66, 12, 13, 214, 65, 12, - 13, 214, 64, 12, 13, 214, 63, 12, 13, 214, 62, 12, 13, 214, 61, 12, 13, - 214, 60, 12, 13, 214, 59, 12, 13, 214, 58, 12, 13, 214, 57, 12, 13, 214, - 56, 12, 13, 214, 55, 12, 13, 214, 54, 12, 13, 214, 53, 12, 13, 214, 52, - 12, 13, 214, 51, 12, 13, 214, 50, 12, 13, 214, 49, 12, 13, 214, 48, 12, - 13, 214, 47, 12, 13, 214, 46, 12, 13, 214, 45, 12, 13, 214, 44, 12, 13, - 214, 43, 12, 13, 214, 42, 12, 13, 214, 41, 12, 13, 214, 40, 12, 13, 214, - 39, 12, 13, 214, 38, 12, 13, 214, 37, 12, 13, 214, 36, 12, 13, 214, 35, - 12, 13, 214, 34, 12, 13, 214, 33, 12, 13, 214, 32, 12, 13, 214, 31, 12, - 13, 214, 30, 12, 13, 214, 29, 12, 13, 214, 28, 12, 13, 212, 97, 12, 13, - 212, 96, 12, 13, 212, 95, 12, 13, 212, 94, 12, 13, 212, 93, 12, 13, 212, - 92, 12, 13, 212, 91, 12, 13, 212, 90, 12, 13, 212, 89, 12, 13, 212, 88, - 12, 13, 212, 87, 12, 13, 212, 86, 12, 13, 212, 85, 12, 13, 212, 84, 12, - 13, 212, 83, 12, 13, 212, 82, 12, 13, 212, 81, 12, 13, 212, 80, 12, 13, - 212, 79, 12, 13, 212, 78, 12, 13, 212, 77, 12, 13, 212, 76, 12, 13, 212, - 75, 12, 13, 212, 74, 12, 13, 212, 73, 12, 13, 212, 72, 12, 13, 212, 71, - 12, 13, 212, 70, 12, 13, 212, 69, 12, 13, 212, 68, 12, 13, 212, 67, 12, - 13, 212, 66, 12, 13, 211, 177, 12, 13, 211, 176, 12, 13, 211, 175, 12, - 13, 211, 174, 12, 13, 211, 173, 12, 13, 211, 172, 12, 13, 211, 171, 12, - 13, 211, 170, 12, 13, 211, 169, 12, 13, 211, 168, 12, 13, 211, 167, 12, - 13, 211, 166, 12, 13, 211, 115, 12, 13, 211, 114, 12, 13, 211, 113, 12, - 13, 211, 112, 12, 13, 211, 111, 12, 13, 211, 110, 12, 13, 211, 109, 12, - 13, 211, 108, 12, 13, 211, 107, 12, 13, 210, 158, 12, 13, 210, 157, 12, - 13, 210, 156, 12, 13, 210, 155, 12, 13, 210, 154, 12, 13, 210, 153, 12, - 13, 210, 152, 12, 13, 210, 151, 12, 13, 210, 150, 12, 13, 210, 149, 12, - 13, 210, 148, 12, 13, 210, 147, 12, 13, 210, 146, 12, 13, 210, 145, 12, - 13, 210, 144, 12, 13, 210, 143, 12, 13, 210, 142, 12, 13, 210, 141, 12, - 13, 210, 140, 12, 13, 210, 139, 12, 13, 210, 138, 12, 13, 210, 137, 12, - 13, 210, 136, 12, 13, 210, 135, 12, 13, 210, 134, 12, 13, 210, 133, 12, - 13, 210, 132, 12, 13, 210, 131, 12, 13, 210, 130, 12, 13, 210, 129, 12, - 13, 210, 128, 12, 13, 210, 127, 12, 13, 210, 126, 12, 13, 210, 125, 12, - 13, 210, 124, 12, 13, 210, 123, 12, 13, 210, 122, 12, 13, 210, 121, 12, - 13, 210, 120, 12, 13, 210, 119, 12, 13, 210, 118, 12, 13, 255, 81, 12, - 13, 255, 80, 12, 13, 255, 79, 12, 13, 255, 78, 12, 13, 255, 77, 12, 13, - 255, 76, 12, 13, 255, 75, 12, 13, 255, 74, 12, 13, 255, 73, 12, 13, 255, - 72, 12, 13, 255, 71, 12, 13, 255, 70, 12, 13, 255, 69, 12, 13, 255, 68, - 12, 13, 255, 67, 12, 13, 255, 66, 12, 13, 255, 65, 12, 13, 255, 64, 12, - 13, 255, 63, 12, 13, 255, 62, 12, 13, 255, 61, 12, 13, 255, 60, 12, 13, - 255, 59, 12, 13, 255, 58, 12, 13, 255, 57, 12, 13, 255, 56, 12, 13, 255, - 55, 12, 13, 255, 54, 12, 13, 255, 53, 12, 13, 255, 52, 12, 13, 255, 51, - 12, 13, 255, 50, 12, 13, 255, 49, 12, 13, 255, 48, 20, 1, 167, 229, 17, - 231, 21, 20, 1, 167, 243, 77, 244, 44, 20, 1, 167, 224, 254, 231, 22, - 225, 60, 20, 1, 167, 224, 254, 231, 22, 225, 61, 20, 1, 167, 229, 231, - 231, 21, 20, 1, 167, 219, 223, 20, 1, 167, 216, 67, 231, 21, 20, 1, 167, - 227, 122, 231, 21, 20, 1, 167, 220, 21, 226, 94, 228, 174, 20, 1, 167, - 224, 254, 226, 94, 228, 175, 225, 60, 20, 1, 167, 224, 254, 226, 94, 228, - 175, 225, 61, 20, 1, 167, 231, 223, 20, 1, 167, 215, 120, 231, 224, 20, - 1, 167, 229, 76, 20, 1, 167, 231, 220, 20, 1, 167, 231, 181, 20, 1, 167, - 230, 53, 20, 1, 167, 220, 126, 20, 1, 167, 227, 246, 20, 1, 167, 234, - 155, 20, 1, 167, 228, 143, 20, 1, 167, 218, 5, 20, 1, 167, 229, 16, 20, - 1, 167, 233, 93, 20, 1, 167, 233, 18, 233, 195, 20, 1, 167, 227, 253, - 231, 29, 20, 1, 167, 231, 227, 20, 1, 167, 225, 250, 20, 1, 167, 242, - 238, 20, 1, 167, 226, 54, 20, 1, 167, 230, 156, 229, 50, 20, 1, 167, 227, - 103, 231, 32, 20, 1, 167, 104, 210, 188, 229, 225, 20, 1, 167, 242, 239, - 20, 1, 167, 227, 253, 227, 254, 20, 1, 167, 219, 130, 20, 1, 167, 231, - 14, 20, 1, 167, 231, 35, 20, 1, 167, 230, 135, 20, 1, 167, 234, 255, 20, - 1, 167, 226, 94, 233, 53, 20, 1, 167, 229, 154, 233, 53, 20, 1, 167, 225, - 161, 20, 1, 167, 231, 221, 20, 1, 167, 228, 212, 20, 1, 167, 224, 137, - 20, 1, 167, 215, 117, 20, 1, 167, 232, 99, 20, 1, 167, 219, 43, 20, 1, - 167, 216, 217, 20, 1, 167, 231, 218, 20, 1, 167, 234, 162, 20, 1, 167, - 229, 150, 20, 1, 167, 233, 207, 20, 1, 167, 230, 136, 20, 1, 167, 219, - 220, 20, 1, 167, 232, 144, 20, 1, 167, 244, 101, 20, 1, 167, 222, 201, - 20, 1, 167, 233, 247, 20, 1, 167, 219, 39, 20, 1, 167, 231, 178, 225, - 102, 20, 1, 167, 220, 14, 20, 1, 167, 227, 252, 20, 1, 167, 219, 255, - 228, 7, 210, 196, 20, 1, 167, 227, 142, 230, 153, 20, 1, 167, 226, 89, - 20, 1, 167, 228, 144, 20, 1, 167, 214, 170, 20, 1, 167, 229, 53, 20, 1, - 167, 231, 217, 20, 1, 167, 228, 186, 20, 1, 167, 231, 124, 20, 1, 167, - 227, 155, 20, 1, 167, 216, 221, 20, 1, 167, 219, 36, 20, 1, 167, 226, 90, - 20, 1, 167, 228, 11, 20, 1, 167, 231, 225, 20, 1, 167, 227, 152, 20, 1, - 167, 234, 222, 20, 1, 167, 228, 14, 20, 1, 167, 213, 250, 20, 1, 167, - 232, 103, 20, 1, 167, 229, 103, 20, 1, 167, 229, 201, 20, 1, 167, 231, - 123, 20, 1, 225, 141, 228, 9, 20, 1, 225, 141, 215, 120, 231, 222, 20, 1, - 225, 141, 219, 187, 20, 1, 225, 141, 220, 130, 215, 119, 20, 1, 225, 141, - 232, 146, 227, 249, 20, 1, 225, 141, 231, 130, 231, 226, 20, 1, 225, 141, - 234, 93, 20, 1, 225, 141, 211, 15, 20, 1, 225, 141, 231, 125, 20, 1, 225, - 141, 234, 243, 20, 1, 225, 141, 225, 211, 20, 1, 225, 141, 211, 89, 233, - 53, 20, 1, 225, 141, 233, 109, 228, 7, 227, 164, 20, 1, 225, 141, 227, - 247, 220, 40, 20, 1, 225, 141, 229, 121, 228, 189, 20, 1, 225, 141, 242, - 236, 20, 1, 225, 141, 225, 52, 20, 1, 225, 141, 215, 120, 228, 5, 20, 1, - 225, 141, 220, 45, 228, 184, 20, 1, 225, 141, 220, 41, 20, 1, 225, 141, - 231, 22, 216, 220, 20, 1, 225, 141, 231, 112, 231, 126, 20, 1, 225, 141, - 227, 153, 227, 249, 20, 1, 225, 141, 234, 151, 20, 1, 225, 141, 242, 237, - 20, 1, 225, 141, 234, 147, 20, 1, 225, 141, 233, 135, 20, 1, 225, 141, - 225, 253, 20, 1, 225, 141, 213, 182, 20, 1, 225, 141, 229, 18, 230, 51, - 20, 1, 225, 141, 229, 52, 231, 108, 20, 1, 225, 141, 211, 193, 20, 1, - 225, 141, 222, 13, 20, 1, 225, 141, 217, 98, 20, 1, 225, 141, 231, 34, - 20, 1, 225, 141, 229, 37, 20, 1, 225, 141, 229, 38, 233, 90, 20, 1, 225, - 141, 231, 24, 20, 1, 225, 141, 218, 53, 20, 1, 225, 141, 231, 116, 20, 1, - 225, 141, 230, 138, 20, 1, 225, 141, 227, 167, 20, 1, 225, 141, 224, 141, - 20, 1, 225, 141, 231, 33, 229, 54, 20, 1, 225, 141, 244, 134, 20, 1, 225, - 141, 231, 103, 20, 1, 225, 141, 244, 155, 20, 1, 225, 141, 234, 159, 20, - 1, 225, 141, 231, 244, 228, 178, 20, 1, 225, 141, 231, 244, 228, 154, 20, - 1, 225, 141, 233, 17, 20, 1, 225, 141, 229, 60, 20, 1, 225, 141, 228, 16, - 20, 1, 225, 141, 186, 20, 1, 225, 141, 234, 80, 20, 1, 225, 141, 229, 6, - 20, 1, 137, 229, 17, 231, 224, 20, 1, 137, 227, 121, 20, 1, 137, 210, - 196, 20, 1, 137, 212, 53, 20, 1, 137, 229, 53, 20, 1, 137, 229, 142, 20, - 1, 137, 229, 24, 20, 1, 137, 242, 246, 20, 1, 137, 231, 120, 20, 1, 137, - 243, 84, 20, 1, 137, 227, 144, 230, 175, 231, 36, 20, 1, 137, 227, 245, - 231, 111, 20, 1, 137, 231, 117, 20, 1, 137, 225, 58, 20, 1, 137, 229, - 127, 20, 1, 137, 231, 128, 251, 37, 20, 1, 137, 234, 149, 20, 1, 137, - 242, 247, 20, 1, 137, 234, 156, 20, 1, 137, 210, 213, 230, 81, 20, 1, - 137, 227, 115, 20, 1, 137, 231, 105, 20, 1, 137, 228, 15, 20, 1, 137, - 231, 111, 20, 1, 137, 211, 16, 20, 1, 137, 233, 255, 20, 1, 137, 235, 16, - 20, 1, 137, 220, 125, 20, 1, 137, 229, 136, 20, 1, 137, 217, 96, 20, 1, - 137, 228, 158, 20, 1, 137, 216, 67, 210, 198, 20, 1, 137, 218, 80, 20, 1, - 137, 229, 44, 227, 164, 20, 1, 137, 213, 181, 20, 1, 137, 229, 204, 20, - 1, 137, 231, 244, 234, 158, 20, 1, 137, 227, 254, 20, 1, 137, 229, 39, - 20, 1, 137, 233, 94, 20, 1, 137, 231, 113, 20, 1, 137, 231, 13, 20, 1, - 137, 227, 248, 20, 1, 137, 216, 216, 20, 1, 137, 229, 41, 20, 1, 137, - 243, 240, 20, 1, 137, 229, 141, 20, 1, 137, 228, 17, 20, 1, 137, 228, 13, - 20, 1, 137, 251, 115, 20, 1, 137, 213, 183, 20, 1, 137, 231, 118, 20, 1, - 137, 222, 142, 20, 1, 137, 228, 188, 20, 1, 137, 233, 108, 20, 1, 137, - 216, 65, 20, 1, 137, 227, 255, 229, 6, 20, 1, 137, 228, 180, 20, 1, 137, - 234, 162, 20, 1, 137, 229, 45, 20, 1, 137, 231, 217, 20, 1, 137, 231, - 106, 20, 1, 137, 232, 103, 20, 1, 137, 233, 195, 20, 1, 137, 228, 186, - 20, 1, 137, 229, 6, 20, 1, 137, 211, 184, 20, 1, 137, 229, 42, 20, 1, - 137, 228, 2, 20, 1, 137, 227, 250, 20, 1, 137, 233, 209, 228, 144, 20, 1, - 137, 228, 0, 20, 1, 137, 229, 149, 20, 1, 137, 231, 244, 228, 5, 20, 1, - 137, 211, 103, 20, 1, 137, 229, 148, 20, 1, 137, 219, 222, 20, 1, 137, - 220, 128, 20, 1, 137, 231, 114, 20, 1, 137, 231, 224, 20, 1, 137, 231, - 124, 20, 1, 137, 234, 150, 20, 1, 137, 231, 115, 20, 1, 137, 234, 154, - 20, 1, 137, 231, 128, 225, 106, 20, 1, 137, 210, 179, 20, 1, 137, 228, - 176, 20, 1, 137, 230, 225, 20, 1, 137, 230, 105, 20, 1, 137, 220, 17, 20, - 1, 137, 234, 172, 233, 76, 20, 1, 137, 234, 172, 244, 168, 20, 1, 137, - 229, 74, 20, 1, 137, 229, 201, 20, 1, 137, 232, 206, 20, 1, 137, 225, 68, - 20, 1, 137, 225, 202, 20, 1, 137, 216, 231, 20, 1, 107, 231, 104, 20, 1, - 107, 212, 51, 20, 1, 107, 228, 174, 20, 1, 107, 231, 21, 20, 1, 107, 228, - 172, 20, 1, 107, 232, 241, 20, 1, 107, 228, 177, 20, 1, 107, 228, 12, 20, - 1, 107, 229, 59, 20, 1, 107, 227, 164, 20, 1, 107, 211, 194, 20, 1, 107, - 229, 14, 20, 1, 107, 220, 63, 20, 1, 107, 229, 25, 20, 1, 107, 234, 157, - 20, 1, 107, 216, 218, 20, 1, 107, 220, 43, 20, 1, 107, 228, 185, 20, 1, - 107, 218, 53, 20, 1, 107, 234, 162, 20, 1, 107, 211, 91, 20, 1, 107, 233, - 210, 20, 1, 107, 221, 236, 20, 1, 107, 231, 26, 20, 1, 107, 229, 140, 20, - 1, 107, 231, 193, 20, 1, 107, 231, 32, 20, 1, 107, 220, 127, 20, 1, 107, - 211, 39, 20, 1, 107, 228, 179, 20, 1, 107, 234, 153, 231, 107, 20, 1, - 107, 229, 21, 20, 1, 107, 215, 119, 20, 1, 107, 242, 255, 20, 1, 107, - 229, 11, 20, 1, 107, 244, 135, 20, 1, 107, 229, 144, 20, 1, 107, 231, 5, - 20, 1, 107, 233, 11, 20, 1, 107, 229, 126, 20, 1, 107, 230, 152, 20, 1, - 107, 231, 9, 20, 1, 107, 224, 121, 20, 1, 107, 231, 7, 20, 1, 107, 231, - 23, 20, 1, 107, 232, 89, 20, 1, 107, 228, 4, 20, 1, 107, 231, 127, 20, 1, - 107, 233, 186, 20, 1, 107, 227, 155, 20, 1, 107, 216, 221, 20, 1, 107, - 219, 36, 20, 1, 107, 210, 179, 20, 1, 107, 234, 154, 20, 1, 107, 223, - 173, 20, 1, 107, 217, 11, 20, 1, 107, 229, 22, 20, 1, 107, 231, 28, 20, - 1, 107, 228, 3, 20, 1, 107, 234, 152, 20, 1, 107, 225, 62, 20, 1, 107, - 225, 155, 20, 1, 107, 227, 131, 20, 1, 107, 233, 17, 20, 1, 107, 229, 60, - 20, 1, 107, 231, 25, 20, 1, 107, 229, 34, 20, 1, 107, 210, 193, 20, 1, - 107, 226, 25, 20, 1, 107, 210, 192, 20, 1, 107, 229, 149, 20, 1, 107, - 227, 249, 20, 1, 107, 218, 82, 20, 1, 107, 233, 214, 20, 1, 107, 229, 49, - 20, 1, 107, 229, 19, 20, 1, 107, 215, 103, 20, 1, 107, 231, 36, 20, 1, - 107, 233, 204, 20, 1, 107, 228, 1, 20, 1, 107, 216, 219, 20, 1, 107, 231, - 219, 20, 1, 107, 229, 58, 20, 1, 107, 233, 10, 20, 1, 107, 229, 40, 20, - 1, 107, 228, 6, 20, 1, 107, 228, 158, 20, 1, 107, 242, 240, 20, 1, 107, - 233, 223, 20, 1, 107, 223, 87, 226, 213, 20, 1, 107, 217, 87, 20, 1, 107, - 216, 11, 20, 1, 107, 227, 152, 20, 1, 107, 222, 242, 20, 1, 107, 233, 55, - 20, 1, 107, 231, 84, 20, 1, 107, 194, 20, 1, 107, 218, 5, 20, 1, 107, - 230, 107, 20, 1, 107, 220, 29, 20, 1, 107, 220, 39, 20, 1, 107, 233, 161, - 20, 1, 107, 227, 242, 20, 1, 107, 219, 227, 20, 1, 107, 227, 251, 20, 1, - 107, 225, 214, 20, 1, 107, 228, 238, 20, 1, 107, 219, 254, 20, 1, 107, - 224, 136, 20, 1, 107, 230, 51, 20, 1, 107, 232, 125, 20, 1, 107, 223, 87, - 230, 101, 20, 1, 107, 216, 118, 20, 1, 107, 227, 243, 20, 1, 107, 231, - 128, 199, 20, 1, 107, 221, 234, 20, 1, 107, 244, 203, 20, 1, 82, 229, - 148, 20, 1, 82, 216, 17, 20, 1, 82, 231, 117, 20, 1, 82, 233, 94, 20, 1, - 82, 213, 128, 20, 1, 82, 232, 131, 20, 1, 82, 226, 93, 20, 1, 82, 219, - 47, 20, 1, 82, 223, 148, 20, 1, 82, 228, 8, 20, 1, 82, 229, 119, 20, 1, - 82, 224, 150, 20, 1, 82, 217, 63, 20, 1, 82, 229, 27, 20, 1, 82, 233, - 251, 20, 1, 82, 211, 187, 20, 1, 82, 221, 172, 20, 1, 82, 229, 50, 20, 1, - 82, 226, 90, 20, 1, 82, 216, 18, 20, 1, 82, 233, 208, 20, 1, 82, 232, - 145, 20, 1, 82, 228, 11, 20, 1, 82, 229, 3, 20, 1, 82, 231, 225, 20, 1, - 82, 229, 20, 20, 1, 82, 229, 2, 20, 1, 82, 228, 10, 20, 1, 82, 222, 240, - 20, 1, 82, 228, 176, 20, 1, 82, 225, 213, 20, 1, 82, 222, 33, 20, 1, 82, - 229, 35, 20, 1, 82, 231, 15, 20, 1, 82, 242, 234, 20, 1, 82, 229, 23, 20, - 1, 82, 228, 187, 20, 1, 82, 231, 177, 20, 1, 82, 232, 127, 20, 1, 82, - 229, 55, 20, 1, 82, 229, 132, 20, 1, 82, 217, 86, 227, 249, 20, 1, 82, - 220, 129, 20, 1, 82, 224, 146, 20, 1, 82, 229, 152, 219, 53, 20, 1, 82, - 229, 43, 227, 164, 20, 1, 82, 211, 4, 20, 1, 82, 242, 235, 20, 1, 82, - 215, 118, 20, 1, 82, 211, 19, 20, 1, 82, 225, 19, 20, 1, 82, 215, 108, - 20, 1, 82, 234, 160, 20, 1, 82, 218, 81, 20, 1, 82, 216, 220, 20, 1, 82, - 213, 184, 20, 1, 82, 212, 6, 20, 1, 82, 233, 138, 20, 1, 82, 224, 153, - 20, 1, 82, 217, 97, 20, 1, 82, 242, 254, 20, 1, 82, 229, 64, 20, 1, 82, - 220, 42, 20, 1, 82, 231, 10, 20, 1, 82, 231, 121, 20, 1, 82, 227, 119, - 20, 1, 82, 228, 141, 20, 1, 82, 243, 80, 20, 1, 82, 215, 109, 20, 1, 82, - 233, 217, 20, 1, 82, 211, 67, 20, 1, 82, 227, 153, 250, 24, 20, 1, 82, - 210, 250, 20, 1, 82, 231, 27, 20, 1, 82, 229, 137, 20, 1, 82, 225, 103, - 20, 1, 82, 210, 197, 20, 1, 82, 233, 12, 20, 1, 82, 243, 240, 20, 1, 82, - 243, 79, 20, 1, 82, 229, 13, 20, 1, 82, 234, 162, 20, 1, 82, 231, 228, - 20, 1, 82, 229, 26, 20, 1, 82, 242, 241, 20, 1, 82, 244, 204, 20, 1, 82, - 227, 244, 20, 1, 82, 225, 156, 20, 1, 82, 211, 17, 20, 1, 82, 229, 51, - 20, 1, 82, 227, 153, 252, 31, 20, 1, 82, 227, 99, 20, 1, 82, 224, 250, - 20, 1, 82, 230, 225, 20, 1, 82, 243, 238, 20, 1, 82, 229, 225, 20, 1, 82, - 230, 105, 20, 1, 82, 242, 240, 20, 1, 82, 243, 242, 74, 20, 1, 82, 230, - 52, 20, 1, 82, 224, 149, 20, 1, 82, 229, 15, 20, 1, 82, 233, 195, 20, 1, - 82, 225, 100, 20, 1, 82, 227, 252, 20, 1, 82, 211, 18, 20, 1, 82, 229, - 36, 20, 1, 82, 226, 94, 225, 190, 20, 1, 82, 243, 242, 251, 23, 20, 1, - 82, 244, 45, 20, 1, 82, 228, 181, 20, 1, 82, 61, 20, 1, 82, 216, 11, 20, - 1, 82, 78, 20, 1, 82, 74, 20, 1, 82, 233, 92, 20, 1, 82, 226, 94, 225, - 26, 20, 1, 82, 217, 102, 20, 1, 82, 217, 52, 20, 1, 82, 229, 152, 230, - 39, 240, 241, 20, 1, 82, 220, 17, 20, 1, 82, 211, 14, 20, 1, 82, 228, - 252, 20, 1, 82, 210, 202, 20, 1, 82, 210, 227, 217, 241, 20, 1, 82, 210, - 227, 249, 155, 20, 1, 82, 210, 187, 20, 1, 82, 210, 195, 20, 1, 82, 234, - 148, 20, 1, 82, 225, 154, 20, 1, 82, 228, 182, 245, 110, 20, 1, 82, 224, - 147, 20, 1, 82, 211, 192, 20, 1, 82, 244, 155, 20, 1, 82, 213, 250, 20, - 1, 82, 232, 103, 20, 1, 82, 230, 235, 20, 1, 82, 223, 54, 20, 1, 82, 223, - 174, 20, 1, 82, 228, 251, 20, 1, 82, 229, 82, 20, 1, 82, 220, 9, 20, 1, - 82, 219, 254, 20, 1, 82, 243, 242, 223, 89, 20, 1, 82, 198, 20, 1, 82, - 225, 111, 20, 1, 82, 232, 125, 20, 1, 82, 234, 34, 20, 1, 82, 231, 63, - 20, 1, 82, 186, 20, 1, 82, 231, 174, 20, 1, 82, 216, 222, 20, 1, 82, 234, - 98, 20, 1, 82, 230, 155, 20, 1, 82, 216, 248, 20, 1, 82, 244, 177, 20, 1, - 82, 242, 230, 20, 1, 225, 140, 176, 20, 1, 225, 140, 69, 20, 1, 225, 140, - 233, 223, 20, 1, 225, 140, 245, 217, 20, 1, 225, 140, 223, 111, 20, 1, - 225, 140, 217, 87, 20, 1, 225, 140, 227, 152, 20, 1, 225, 140, 233, 141, - 20, 1, 225, 140, 222, 242, 20, 1, 225, 140, 223, 32, 20, 1, 225, 140, - 231, 84, 20, 1, 225, 140, 217, 102, 20, 1, 225, 140, 229, 151, 20, 1, - 225, 140, 228, 188, 20, 1, 225, 140, 194, 20, 1, 225, 140, 218, 5, 20, 1, - 225, 140, 220, 29, 20, 1, 225, 140, 219, 193, 20, 1, 225, 140, 220, 125, - 20, 1, 225, 140, 233, 161, 20, 1, 225, 140, 234, 162, 20, 1, 225, 140, - 227, 213, 20, 1, 225, 140, 227, 242, 20, 1, 225, 140, 228, 159, 20, 1, - 225, 140, 210, 226, 20, 1, 225, 140, 219, 227, 20, 1, 225, 140, 192, 20, - 1, 225, 140, 228, 14, 20, 1, 225, 140, 225, 154, 20, 1, 225, 140, 227, - 251, 20, 1, 225, 140, 211, 192, 20, 1, 225, 140, 225, 214, 20, 1, 225, - 140, 222, 142, 20, 1, 225, 140, 228, 238, 20, 1, 225, 140, 223, 54, 20, - 1, 225, 140, 234, 171, 20, 1, 225, 140, 229, 12, 20, 1, 225, 140, 229, - 61, 20, 1, 225, 140, 220, 9, 20, 1, 225, 140, 224, 150, 20, 1, 225, 140, - 244, 45, 20, 1, 225, 140, 212, 65, 20, 1, 225, 140, 232, 247, 20, 1, 225, - 140, 232, 125, 20, 1, 225, 140, 234, 34, 20, 1, 225, 140, 231, 119, 20, - 1, 225, 140, 223, 86, 20, 1, 225, 140, 186, 20, 1, 225, 140, 230, 166, - 20, 1, 225, 140, 231, 127, 20, 1, 225, 140, 216, 231, 20, 1, 225, 140, - 234, 1, 20, 1, 225, 140, 221, 253, 20, 1, 225, 140, 212, 115, 95, 1, 191, - 95, 1, 252, 199, 95, 1, 8, 191, 95, 1, 225, 45, 95, 1, 186, 95, 1, 230, - 238, 95, 1, 254, 31, 186, 95, 1, 244, 204, 95, 1, 214, 27, 95, 1, 213, - 177, 95, 1, 217, 106, 95, 1, 248, 229, 95, 1, 8, 215, 157, 95, 1, 8, 217, - 106, 95, 1, 215, 157, 95, 1, 248, 143, 95, 1, 198, 95, 1, 228, 242, 95, - 1, 8, 228, 115, 95, 1, 254, 31, 198, 95, 1, 228, 115, 95, 1, 228, 101, - 95, 1, 233, 141, 95, 1, 232, 66, 95, 1, 233, 4, 95, 1, 232, 249, 95, 1, - 216, 57, 95, 1, 247, 161, 95, 1, 216, 49, 95, 1, 247, 160, 95, 1, 176, - 95, 1, 243, 142, 95, 1, 8, 176, 95, 1, 224, 91, 95, 1, 224, 69, 95, 1, - 229, 82, 95, 1, 229, 33, 95, 1, 254, 31, 229, 82, 95, 1, 162, 95, 1, 211, - 165, 95, 1, 243, 0, 95, 1, 242, 233, 95, 1, 215, 166, 95, 1, 246, 34, 95, - 1, 227, 169, 95, 1, 227, 154, 95, 1, 215, 176, 95, 1, 246, 41, 95, 1, 8, - 215, 176, 95, 1, 8, 246, 41, 95, 1, 223, 109, 215, 176, 95, 1, 220, 104, - 95, 1, 218, 225, 95, 1, 210, 82, 95, 1, 210, 14, 95, 1, 215, 184, 95, 1, - 246, 46, 95, 1, 8, 215, 184, 95, 1, 206, 95, 1, 210, 116, 95, 1, 210, 15, - 95, 1, 209, 243, 95, 1, 209, 223, 95, 1, 254, 31, 209, 243, 95, 1, 209, - 215, 95, 1, 209, 222, 95, 1, 212, 65, 95, 1, 254, 218, 95, 1, 241, 196, - 95, 1, 229, 197, 95, 5, 253, 230, 95, 5, 223, 109, 213, 133, 95, 5, 223, - 109, 253, 230, 95, 25, 5, 61, 95, 25, 5, 255, 82, 95, 25, 5, 254, 214, - 95, 25, 5, 254, 131, 95, 25, 5, 254, 123, 95, 25, 5, 78, 95, 25, 5, 226, - 187, 95, 25, 5, 211, 227, 95, 25, 5, 212, 98, 95, 25, 5, 76, 95, 25, 5, - 245, 158, 95, 25, 5, 245, 146, 95, 25, 5, 226, 236, 95, 25, 5, 74, 95, - 25, 5, 240, 126, 95, 25, 5, 240, 125, 95, 25, 5, 240, 124, 95, 25, 5, - 235, 196, 95, 25, 5, 236, 67, 95, 25, 5, 236, 40, 95, 25, 5, 235, 162, - 95, 25, 5, 235, 238, 95, 25, 5, 69, 95, 25, 5, 214, 229, 95, 25, 5, 214, - 228, 95, 25, 5, 214, 227, 95, 25, 5, 214, 118, 95, 25, 5, 214, 211, 95, - 25, 5, 214, 178, 95, 25, 5, 211, 117, 95, 25, 5, 211, 8, 95, 25, 5, 254, - 252, 95, 25, 5, 254, 248, 95, 25, 5, 245, 94, 95, 25, 5, 222, 185, 245, - 94, 95, 25, 5, 245, 100, 95, 25, 5, 222, 185, 245, 100, 95, 25, 5, 254, - 210, 95, 25, 5, 245, 203, 95, 25, 5, 253, 200, 95, 25, 5, 226, 138, 95, - 25, 5, 230, 30, 95, 25, 5, 229, 84, 95, 138, 222, 254, 95, 138, 216, 15, - 222, 254, 95, 138, 48, 95, 138, 51, 95, 1, 216, 29, 95, 1, 216, 28, 95, - 1, 216, 27, 95, 1, 216, 26, 95, 1, 216, 25, 95, 1, 216, 24, 95, 1, 216, - 23, 95, 1, 223, 109, 216, 30, 95, 1, 223, 109, 216, 29, 95, 1, 223, 109, - 216, 27, 95, 1, 223, 109, 216, 26, 95, 1, 223, 109, 216, 25, 95, 1, 223, - 109, 216, 23, 56, 1, 254, 31, 76, 141, 1, 254, 31, 211, 47, 49, 28, 16, - 224, 157, 49, 28, 16, 248, 166, 49, 28, 16, 225, 178, 49, 28, 16, 226, - 117, 245, 186, 49, 28, 16, 226, 117, 247, 209, 49, 28, 16, 214, 16, 245, - 186, 49, 28, 16, 214, 16, 247, 209, 49, 28, 16, 234, 203, 49, 28, 16, - 217, 170, 49, 28, 16, 226, 13, 49, 28, 16, 210, 217, 49, 28, 16, 210, - 218, 247, 209, 49, 28, 16, 233, 240, 49, 28, 16, 254, 76, 245, 186, 49, - 28, 16, 245, 34, 245, 186, 49, 28, 16, 217, 3, 49, 28, 16, 234, 167, 49, - 28, 16, 254, 66, 49, 28, 16, 254, 67, 247, 209, 49, 28, 16, 217, 176, 49, - 28, 16, 216, 160, 49, 28, 16, 226, 210, 254, 29, 49, 28, 16, 242, 166, - 254, 29, 49, 28, 16, 224, 156, 49, 28, 16, 250, 157, 49, 28, 16, 214, 6, - 49, 28, 16, 235, 170, 254, 29, 49, 28, 16, 234, 169, 254, 29, 49, 28, 16, - 234, 168, 254, 29, 49, 28, 16, 221, 215, 49, 28, 16, 226, 4, 49, 28, 16, - 218, 148, 254, 69, 49, 28, 16, 226, 116, 254, 29, 49, 28, 16, 214, 15, - 254, 29, 49, 28, 16, 254, 70, 254, 29, 49, 28, 16, 254, 64, 49, 28, 16, - 234, 43, 49, 28, 16, 223, 49, 49, 28, 16, 225, 109, 254, 29, 49, 28, 16, - 216, 84, 49, 28, 16, 254, 129, 49, 28, 16, 221, 161, 49, 28, 16, 217, - 179, 254, 29, 49, 28, 16, 217, 179, 231, 45, 218, 146, 49, 28, 16, 226, - 111, 254, 29, 49, 28, 16, 216, 191, 49, 28, 16, 233, 33, 49, 28, 16, 246, - 49, 49, 28, 16, 215, 228, 49, 28, 16, 216, 233, 49, 28, 16, 233, 243, 49, - 28, 16, 254, 76, 245, 34, 229, 100, 49, 28, 16, 243, 243, 254, 29, 49, - 28, 16, 236, 19, 49, 28, 16, 215, 200, 254, 29, 49, 28, 16, 234, 206, - 215, 199, 49, 28, 16, 225, 203, 49, 28, 16, 224, 161, 49, 28, 16, 234, - 17, 49, 28, 16, 250, 88, 254, 29, 49, 28, 16, 223, 149, 49, 28, 16, 226, - 16, 254, 29, 49, 28, 16, 226, 14, 254, 29, 49, 28, 16, 240, 116, 49, 28, - 16, 229, 208, 49, 28, 16, 225, 159, 49, 28, 16, 234, 18, 254, 158, 49, - 28, 16, 215, 200, 254, 158, 49, 28, 16, 218, 125, 49, 28, 16, 242, 130, - 49, 28, 16, 235, 170, 229, 100, 49, 28, 16, 226, 210, 229, 100, 49, 28, - 16, 226, 117, 229, 100, 49, 28, 16, 225, 158, 49, 28, 16, 234, 4, 49, 28, - 16, 225, 157, 49, 28, 16, 233, 242, 49, 28, 16, 225, 204, 229, 100, 49, - 28, 16, 234, 168, 229, 101, 254, 104, 49, 28, 16, 234, 169, 229, 101, - 254, 104, 49, 28, 16, 210, 215, 49, 28, 16, 254, 67, 229, 100, 49, 28, - 16, 254, 68, 217, 177, 229, 100, 49, 28, 16, 210, 216, 49, 28, 16, 233, - 241, 49, 28, 16, 245, 181, 49, 28, 16, 250, 158, 49, 28, 16, 230, 203, - 235, 169, 49, 28, 16, 214, 16, 229, 100, 49, 28, 16, 225, 109, 229, 100, - 49, 28, 16, 224, 162, 229, 100, 49, 28, 16, 226, 207, 49, 28, 16, 254, - 92, 49, 28, 16, 232, 63, 49, 28, 16, 226, 14, 229, 100, 49, 28, 16, 226, - 16, 229, 100, 49, 28, 16, 245, 68, 226, 15, 49, 28, 16, 233, 159, 49, 28, - 16, 254, 93, 49, 28, 16, 215, 200, 229, 100, 49, 28, 16, 245, 184, 49, - 28, 16, 217, 179, 229, 100, 49, 28, 16, 217, 171, 49, 28, 16, 250, 88, - 229, 100, 49, 28, 16, 245, 114, 49, 28, 16, 221, 162, 229, 100, 49, 28, - 16, 211, 151, 234, 43, 49, 28, 16, 215, 197, 49, 28, 16, 224, 163, 49, - 28, 16, 215, 201, 49, 28, 16, 215, 198, 49, 28, 16, 224, 160, 49, 28, 16, - 215, 196, 49, 28, 16, 224, 159, 49, 28, 16, 242, 165, 49, 28, 16, 254, - 22, 49, 28, 16, 245, 68, 254, 22, 49, 28, 16, 226, 111, 229, 100, 49, 28, - 16, 216, 190, 245, 77, 49, 28, 16, 216, 190, 245, 33, 49, 28, 16, 216, - 192, 254, 71, 49, 28, 16, 216, 185, 234, 253, 254, 63, 49, 28, 16, 234, - 205, 49, 28, 16, 245, 147, 49, 28, 16, 211, 11, 234, 202, 49, 28, 16, - 211, 11, 254, 104, 49, 28, 16, 218, 147, 49, 28, 16, 234, 44, 254, 104, - 49, 28, 16, 247, 210, 254, 29, 49, 28, 16, 233, 244, 254, 29, 49, 28, 16, - 233, 244, 254, 158, 49, 28, 16, 233, 244, 229, 100, 49, 28, 16, 254, 70, - 229, 100, 49, 28, 16, 254, 72, 49, 28, 16, 247, 209, 49, 28, 16, 215, - 211, 49, 28, 16, 216, 225, 49, 28, 16, 234, 8, 49, 28, 16, 233, 38, 245, - 142, 250, 79, 49, 28, 16, 233, 38, 246, 50, 250, 80, 49, 28, 16, 233, 38, - 215, 213, 250, 80, 49, 28, 16, 233, 38, 216, 235, 250, 80, 49, 28, 16, - 233, 38, 236, 14, 250, 79, 49, 28, 16, 242, 166, 229, 101, 254, 104, 49, - 28, 16, 242, 166, 226, 5, 254, 18, 49, 28, 16, 242, 166, 226, 5, 248, 37, - 49, 28, 16, 247, 233, 49, 28, 16, 247, 234, 226, 5, 254, 19, 234, 202, - 49, 28, 16, 247, 234, 226, 5, 254, 19, 254, 104, 49, 28, 16, 247, 234, - 226, 5, 248, 37, 49, 28, 16, 215, 217, 49, 28, 16, 254, 23, 49, 28, 16, - 236, 21, 49, 28, 16, 247, 254, 49, 28, 16, 254, 220, 225, 3, 254, 24, 49, - 28, 16, 254, 220, 254, 21, 49, 28, 16, 254, 220, 254, 24, 49, 28, 16, - 254, 220, 231, 39, 49, 28, 16, 254, 220, 231, 50, 49, 28, 16, 254, 220, - 242, 167, 49, 28, 16, 254, 220, 242, 164, 49, 28, 16, 254, 220, 225, 3, - 242, 167, 49, 28, 16, 231, 156, 224, 168, 240, 114, 49, 28, 16, 231, 156, - 254, 160, 224, 168, 240, 114, 49, 28, 16, 231, 156, 248, 36, 240, 114, - 49, 28, 16, 231, 156, 254, 160, 248, 36, 240, 114, 49, 28, 16, 231, 156, - 215, 206, 240, 114, 49, 28, 16, 231, 156, 215, 218, 49, 28, 16, 231, 156, - 216, 229, 240, 114, 49, 28, 16, 231, 156, 216, 229, 233, 41, 240, 114, - 49, 28, 16, 231, 156, 233, 41, 240, 114, 49, 28, 16, 231, 156, 225, 42, - 240, 114, 49, 28, 16, 235, 176, 216, 252, 240, 115, 49, 28, 16, 254, 68, - 216, 252, 240, 115, 49, 28, 16, 244, 180, 216, 226, 49, 28, 16, 244, 180, - 230, 148, 49, 28, 16, 244, 180, 247, 238, 49, 28, 16, 231, 156, 214, 10, - 240, 114, 49, 28, 16, 231, 156, 224, 167, 240, 114, 49, 28, 16, 231, 156, - 225, 42, 216, 229, 240, 114, 49, 28, 16, 242, 162, 230, 31, 254, 71, 49, - 28, 16, 242, 162, 230, 31, 247, 208, 49, 28, 16, 245, 156, 234, 253, 243, - 243, 213, 124, 49, 28, 16, 236, 20, 49, 28, 16, 236, 18, 49, 28, 16, 243, - 243, 254, 30, 248, 35, 240, 113, 49, 28, 16, 243, 243, 247, 252, 191, 49, - 28, 16, 243, 243, 247, 252, 229, 208, 49, 28, 16, 243, 243, 229, 203, - 240, 114, 49, 28, 16, 243, 243, 247, 252, 248, 11, 49, 28, 16, 243, 243, - 219, 104, 247, 251, 248, 11, 49, 28, 16, 243, 243, 247, 252, 234, 188, - 49, 28, 16, 243, 243, 247, 252, 210, 23, 49, 28, 16, 243, 243, 247, 252, - 228, 239, 234, 202, 49, 28, 16, 243, 243, 247, 252, 228, 239, 254, 104, - 49, 28, 16, 243, 243, 231, 196, 250, 81, 247, 238, 49, 28, 16, 243, 243, - 231, 196, 250, 81, 230, 148, 49, 28, 16, 244, 130, 219, 104, 250, 81, - 214, 9, 49, 28, 16, 243, 243, 219, 104, 250, 81, 217, 180, 49, 28, 16, - 243, 243, 229, 102, 49, 28, 16, 250, 82, 209, 249, 49, 28, 16, 250, 82, - 234, 42, 49, 28, 16, 250, 82, 219, 11, 49, 28, 16, 243, 243, 240, 161, - 211, 10, 216, 230, 49, 28, 16, 243, 243, 245, 157, 254, 94, 49, 28, 16, - 211, 10, 215, 207, 49, 28, 16, 247, 246, 215, 207, 49, 28, 16, 247, 246, - 216, 230, 49, 28, 16, 247, 246, 254, 73, 246, 50, 247, 147, 49, 28, 16, - 247, 246, 230, 146, 216, 234, 247, 147, 49, 28, 16, 247, 246, 247, 230, - 245, 44, 247, 147, 49, 28, 16, 247, 246, 215, 215, 226, 215, 247, 147, - 49, 28, 16, 211, 10, 254, 73, 246, 50, 247, 147, 49, 28, 16, 211, 10, - 230, 146, 216, 234, 247, 147, 49, 28, 16, 211, 10, 247, 230, 245, 44, - 247, 147, 49, 28, 16, 211, 10, 215, 215, 226, 215, 247, 147, 49, 28, 16, - 243, 56, 247, 245, 49, 28, 16, 243, 56, 211, 9, 49, 28, 16, 247, 253, - 254, 73, 230, 204, 49, 28, 16, 247, 253, 254, 73, 231, 78, 49, 28, 16, - 247, 253, 247, 209, 49, 28, 16, 247, 253, 216, 183, 49, 28, 16, 219, 165, - 216, 183, 49, 28, 16, 219, 165, 216, 184, 247, 194, 49, 28, 16, 219, 165, - 216, 184, 215, 208, 49, 28, 16, 219, 165, 216, 184, 216, 223, 49, 28, 16, - 219, 165, 253, 252, 49, 28, 16, 219, 165, 253, 253, 247, 194, 49, 28, 16, - 219, 165, 253, 253, 215, 208, 49, 28, 16, 219, 165, 253, 253, 216, 223, - 49, 28, 16, 247, 231, 243, 37, 49, 28, 16, 247, 237, 226, 138, 49, 28, - 16, 218, 139, 49, 28, 16, 254, 15, 191, 49, 28, 16, 254, 15, 213, 124, - 49, 28, 16, 254, 15, 243, 142, 49, 28, 16, 254, 15, 248, 11, 49, 28, 16, - 254, 15, 234, 188, 49, 28, 16, 254, 15, 210, 23, 49, 28, 16, 254, 15, - 228, 238, 49, 28, 16, 234, 168, 229, 101, 231, 49, 49, 28, 16, 234, 169, - 229, 101, 231, 49, 49, 28, 16, 234, 168, 229, 101, 234, 202, 49, 28, 16, - 234, 169, 229, 101, 234, 202, 49, 28, 16, 234, 44, 234, 202, 49, 28, 16, - 242, 166, 229, 101, 234, 202, 28, 16, 219, 157, 252, 143, 28, 16, 52, - 252, 143, 28, 16, 40, 252, 143, 28, 16, 223, 53, 40, 252, 143, 28, 16, - 248, 163, 252, 143, 28, 16, 219, 253, 252, 143, 28, 16, 43, 223, 80, 50, - 28, 16, 44, 223, 80, 50, 28, 16, 223, 80, 247, 126, 28, 16, 248, 204, - 221, 165, 28, 16, 248, 230, 251, 1, 28, 16, 221, 165, 28, 16, 249, 242, - 28, 16, 223, 78, 244, 119, 28, 16, 223, 78, 244, 118, 28, 16, 223, 78, - 244, 117, 28, 16, 244, 139, 28, 16, 244, 140, 51, 28, 16, 251, 156, 79, - 28, 16, 251, 32, 28, 16, 251, 167, 28, 16, 127, 28, 16, 226, 197, 218, - 165, 28, 16, 215, 57, 218, 165, 28, 16, 216, 143, 218, 165, 28, 16, 244, - 18, 218, 165, 28, 16, 244, 88, 218, 165, 28, 16, 219, 126, 218, 165, 28, - 16, 219, 124, 244, 2, 28, 16, 244, 16, 244, 2, 28, 16, 243, 210, 250, 22, - 28, 16, 243, 210, 250, 23, 226, 140, 254, 150, 28, 16, 243, 210, 250, 23, - 226, 140, 252, 130, 28, 16, 251, 75, 250, 22, 28, 16, 245, 15, 250, 22, - 28, 16, 245, 15, 250, 23, 226, 140, 254, 150, 28, 16, 245, 15, 250, 23, - 226, 140, 252, 130, 28, 16, 246, 91, 250, 21, 28, 16, 246, 91, 250, 20, - 28, 16, 230, 90, 231, 95, 223, 64, 28, 16, 52, 220, 77, 28, 16, 52, 244, - 73, 28, 16, 244, 74, 214, 163, 28, 16, 244, 74, 246, 114, 28, 16, 229, - 193, 214, 163, 28, 16, 229, 193, 246, 114, 28, 16, 220, 78, 214, 163, 28, - 16, 220, 78, 246, 114, 28, 16, 224, 25, 138, 220, 77, 28, 16, 224, 25, - 138, 244, 73, 28, 16, 249, 224, 216, 88, 28, 16, 249, 93, 216, 88, 28, - 16, 226, 140, 254, 150, 28, 16, 226, 140, 252, 130, 28, 16, 224, 7, 254, - 150, 28, 16, 224, 7, 252, 130, 28, 16, 230, 93, 223, 64, 28, 16, 211, - 251, 223, 64, 28, 16, 163, 223, 64, 28, 16, 224, 25, 223, 64, 28, 16, - 245, 197, 223, 64, 28, 16, 219, 120, 223, 64, 28, 16, 216, 161, 223, 64, - 28, 16, 219, 112, 223, 64, 28, 16, 123, 240, 218, 215, 71, 223, 64, 28, - 16, 211, 179, 228, 48, 28, 16, 96, 228, 48, 28, 16, 250, 44, 211, 179, - 228, 48, 28, 16, 42, 228, 49, 211, 253, 28, 16, 42, 228, 49, 251, 229, - 28, 16, 215, 227, 228, 49, 120, 211, 253, 28, 16, 215, 227, 228, 49, 120, - 251, 229, 28, 16, 215, 227, 228, 49, 43, 211, 253, 28, 16, 215, 227, 228, - 49, 43, 251, 229, 28, 16, 215, 227, 228, 49, 44, 211, 253, 28, 16, 215, - 227, 228, 49, 44, 251, 229, 28, 16, 215, 227, 228, 49, 124, 211, 253, 28, - 16, 215, 227, 228, 49, 124, 251, 229, 28, 16, 215, 227, 228, 49, 120, 44, - 211, 253, 28, 16, 215, 227, 228, 49, 120, 44, 251, 229, 28, 16, 230, 134, - 228, 49, 211, 253, 28, 16, 230, 134, 228, 49, 251, 229, 28, 16, 215, 224, - 228, 49, 124, 211, 253, 28, 16, 215, 224, 228, 49, 124, 251, 229, 28, 16, - 226, 8, 228, 48, 28, 16, 213, 132, 228, 48, 28, 16, 228, 49, 251, 229, - 28, 16, 227, 207, 228, 48, 28, 16, 249, 249, 228, 49, 211, 253, 28, 16, - 249, 249, 228, 49, 251, 229, 28, 16, 251, 154, 28, 16, 211, 251, 228, 52, - 28, 16, 163, 228, 52, 28, 16, 224, 25, 228, 52, 28, 16, 245, 197, 228, - 52, 28, 16, 219, 120, 228, 52, 28, 16, 216, 161, 228, 52, 28, 16, 219, - 112, 228, 52, 28, 16, 123, 240, 218, 215, 71, 228, 52, 28, 16, 38, 218, - 141, 28, 16, 38, 218, 242, 218, 141, 28, 16, 38, 215, 235, 28, 16, 38, - 215, 234, 28, 16, 38, 215, 233, 28, 16, 244, 109, 215, 235, 28, 16, 244, - 109, 215, 234, 28, 16, 244, 109, 215, 233, 28, 16, 38, 253, 197, 247, - 128, 28, 16, 38, 244, 80, 28, 16, 38, 244, 79, 28, 16, 38, 244, 78, 28, - 16, 38, 244, 77, 28, 16, 38, 244, 76, 28, 16, 252, 66, 252, 82, 28, 16, - 245, 151, 252, 82, 28, 16, 252, 66, 216, 112, 28, 16, 245, 151, 216, 112, - 28, 16, 252, 66, 219, 82, 28, 16, 245, 151, 219, 82, 28, 16, 252, 66, - 225, 118, 28, 16, 245, 151, 225, 118, 28, 16, 38, 255, 23, 28, 16, 38, - 218, 167, 28, 16, 38, 216, 239, 28, 16, 38, 218, 168, 28, 16, 38, 231, - 167, 28, 16, 38, 231, 166, 28, 16, 38, 255, 22, 28, 16, 38, 232, 118, 28, - 16, 254, 6, 214, 163, 28, 16, 254, 6, 246, 114, 28, 16, 38, 247, 143, 28, - 16, 38, 222, 234, 28, 16, 38, 244, 66, 28, 16, 38, 219, 78, 28, 16, 38, - 252, 46, 28, 16, 38, 52, 216, 20, 28, 16, 38, 215, 212, 216, 20, 28, 16, - 222, 238, 28, 16, 218, 76, 28, 16, 210, 159, 28, 16, 225, 110, 28, 16, - 231, 30, 28, 16, 244, 25, 28, 16, 249, 146, 28, 16, 248, 86, 28, 16, 242, - 157, 228, 53, 219, 97, 28, 16, 242, 157, 228, 53, 228, 80, 219, 97, 28, - 16, 216, 1, 28, 16, 215, 95, 28, 16, 235, 200, 215, 95, 28, 16, 215, 96, - 219, 97, 28, 16, 215, 96, 214, 163, 28, 16, 226, 152, 218, 104, 28, 16, - 226, 152, 218, 101, 28, 16, 226, 152, 218, 100, 28, 16, 226, 152, 218, - 99, 28, 16, 226, 152, 218, 98, 28, 16, 226, 152, 218, 97, 28, 16, 226, - 152, 218, 96, 28, 16, 226, 152, 218, 95, 28, 16, 226, 152, 218, 94, 28, - 16, 226, 152, 218, 103, 28, 16, 226, 152, 218, 102, 28, 16, 241, 252, 28, - 16, 229, 110, 28, 16, 245, 151, 64, 218, 135, 28, 16, 248, 79, 219, 97, - 28, 16, 38, 124, 251, 177, 28, 16, 38, 120, 251, 177, 28, 16, 38, 242, 7, - 28, 16, 38, 219, 69, 225, 46, 28, 16, 225, 219, 79, 28, 16, 225, 219, - 120, 79, 28, 16, 163, 225, 219, 79, 28, 16, 242, 189, 214, 163, 28, 16, - 242, 189, 246, 114, 28, 16, 2, 244, 108, 28, 16, 248, 188, 28, 16, 248, - 189, 254, 163, 28, 16, 231, 138, 28, 16, 232, 135, 28, 16, 251, 151, 28, - 16, 220, 156, 211, 253, 28, 16, 220, 156, 251, 229, 28, 16, 230, 189, 28, - 16, 230, 190, 251, 229, 28, 16, 220, 150, 211, 253, 28, 16, 220, 150, - 251, 229, 28, 16, 243, 227, 211, 253, 28, 16, 243, 227, 251, 229, 28, 16, - 232, 136, 225, 183, 223, 64, 28, 16, 232, 136, 236, 11, 223, 64, 28, 16, - 251, 152, 223, 64, 28, 16, 220, 156, 223, 64, 28, 16, 230, 190, 223, 64, - 28, 16, 220, 150, 223, 64, 28, 16, 216, 250, 225, 181, 249, 115, 224, - 177, 225, 182, 28, 16, 216, 250, 225, 181, 249, 115, 224, 177, 236, 10, - 28, 16, 216, 250, 225, 181, 249, 115, 224, 177, 225, 183, 247, 219, 28, - 16, 216, 250, 236, 9, 249, 115, 224, 177, 225, 182, 28, 16, 216, 250, - 236, 9, 249, 115, 224, 177, 236, 10, 28, 16, 216, 250, 236, 9, 249, 115, - 224, 177, 236, 11, 247, 219, 28, 16, 216, 250, 236, 9, 249, 115, 224, - 177, 236, 11, 247, 218, 28, 16, 216, 250, 236, 9, 249, 115, 224, 177, - 236, 11, 247, 217, 28, 16, 249, 141, 28, 16, 242, 133, 251, 75, 250, 22, - 28, 16, 242, 133, 245, 15, 250, 22, 28, 16, 42, 253, 166, 28, 16, 213, - 151, 28, 16, 225, 17, 28, 16, 250, 13, 28, 16, 221, 205, 28, 16, 250, 17, - 28, 16, 216, 8, 28, 16, 224, 245, 28, 16, 224, 246, 244, 68, 28, 16, 221, - 206, 244, 68, 28, 16, 216, 9, 223, 61, 28, 16, 225, 166, 218, 67, 26, - 213, 137, 189, 217, 230, 26, 213, 137, 189, 217, 219, 26, 213, 137, 189, - 217, 209, 26, 213, 137, 189, 217, 202, 26, 213, 137, 189, 217, 194, 26, - 213, 137, 189, 217, 188, 26, 213, 137, 189, 217, 187, 26, 213, 137, 189, - 217, 186, 26, 213, 137, 189, 217, 185, 26, 213, 137, 189, 217, 229, 26, - 213, 137, 189, 217, 228, 26, 213, 137, 189, 217, 227, 26, 213, 137, 189, - 217, 226, 26, 213, 137, 189, 217, 225, 26, 213, 137, 189, 217, 224, 26, - 213, 137, 189, 217, 223, 26, 213, 137, 189, 217, 222, 26, 213, 137, 189, - 217, 221, 26, 213, 137, 189, 217, 220, 26, 213, 137, 189, 217, 218, 26, - 213, 137, 189, 217, 217, 26, 213, 137, 189, 217, 216, 26, 213, 137, 189, - 217, 215, 26, 213, 137, 189, 217, 214, 26, 213, 137, 189, 217, 193, 26, - 213, 137, 189, 217, 192, 26, 213, 137, 189, 217, 191, 26, 213, 137, 189, - 217, 190, 26, 213, 137, 189, 217, 189, 26, 235, 221, 189, 217, 230, 26, - 235, 221, 189, 217, 219, 26, 235, 221, 189, 217, 202, 26, 235, 221, 189, - 217, 194, 26, 235, 221, 189, 217, 187, 26, 235, 221, 189, 217, 186, 26, - 235, 221, 189, 217, 228, 26, 235, 221, 189, 217, 227, 26, 235, 221, 189, - 217, 226, 26, 235, 221, 189, 217, 225, 26, 235, 221, 189, 217, 222, 26, - 235, 221, 189, 217, 221, 26, 235, 221, 189, 217, 220, 26, 235, 221, 189, - 217, 215, 26, 235, 221, 189, 217, 214, 26, 235, 221, 189, 217, 213, 26, - 235, 221, 189, 217, 212, 26, 235, 221, 189, 217, 211, 26, 235, 221, 189, - 217, 210, 26, 235, 221, 189, 217, 208, 26, 235, 221, 189, 217, 207, 26, - 235, 221, 189, 217, 206, 26, 235, 221, 189, 217, 205, 26, 235, 221, 189, - 217, 204, 26, 235, 221, 189, 217, 203, 26, 235, 221, 189, 217, 201, 26, - 235, 221, 189, 217, 200, 26, 235, 221, 189, 217, 199, 26, 235, 221, 189, - 217, 198, 26, 235, 221, 189, 217, 197, 26, 235, 221, 189, 217, 196, 26, - 235, 221, 189, 217, 195, 26, 235, 221, 189, 217, 193, 26, 235, 221, 189, - 217, 192, 26, 235, 221, 189, 217, 191, 26, 235, 221, 189, 217, 190, 26, - 235, 221, 189, 217, 189, 38, 26, 28, 215, 209, 38, 26, 28, 216, 224, 38, - 26, 28, 225, 191, 26, 28, 233, 37, 230, 147, 31, 245, 231, 247, 232, 31, - 241, 229, 245, 231, 247, 232, 31, 240, 221, 245, 231, 247, 232, 31, 245, - 230, 241, 230, 247, 232, 31, 245, 230, 240, 220, 247, 232, 31, 245, 231, - 180, 31, 250, 182, 180, 31, 243, 236, 250, 43, 180, 31, 230, 182, 180, - 31, 252, 138, 180, 31, 234, 185, 219, 81, 180, 31, 249, 187, 180, 31, - 253, 241, 180, 31, 226, 167, 180, 31, 251, 161, 226, 134, 180, 31, 248, - 81, 177, 247, 187, 180, 31, 247, 184, 180, 31, 210, 222, 180, 31, 235, - 254, 180, 31, 225, 200, 180, 31, 223, 130, 180, 31, 249, 197, 180, 31, - 241, 67, 252, 192, 180, 31, 212, 59, 180, 31, 244, 47, 180, 31, 254, 255, - 180, 31, 223, 92, 180, 31, 223, 68, 180, 31, 245, 229, 180, 31, 235, 59, - 180, 31, 249, 192, 180, 31, 245, 150, 180, 31, 246, 60, 180, 31, 250, - 153, 180, 31, 248, 90, 180, 31, 23, 223, 67, 180, 31, 226, 85, 180, 31, - 233, 40, 180, 31, 250, 6, 180, 31, 234, 83, 180, 31, 243, 93, 180, 31, - 218, 114, 180, 31, 224, 133, 180, 31, 243, 235, 180, 31, 223, 69, 180, - 31, 233, 77, 177, 230, 162, 180, 31, 223, 65, 180, 31, 242, 175, 216, 43, - 231, 81, 180, 31, 245, 152, 180, 31, 218, 126, 180, 31, 242, 135, 180, - 31, 245, 144, 180, 31, 225, 239, 180, 31, 222, 228, 180, 31, 244, 67, - 180, 31, 214, 8, 177, 212, 44, 180, 31, 249, 201, 180, 31, 231, 94, 180, - 31, 245, 69, 180, 31, 214, 172, 180, 31, 247, 220, 180, 31, 250, 8, 230, - 115, 180, 31, 242, 113, 180, 31, 243, 94, 236, 6, 180, 31, 231, 146, 180, - 31, 255, 19, 180, 31, 245, 165, 180, 31, 246, 117, 180, 31, 212, 42, 180, - 31, 219, 152, 180, 31, 235, 229, 180, 31, 248, 50, 180, 31, 248, 168, - 180, 31, 247, 216, 180, 31, 245, 37, 180, 31, 220, 117, 180, 31, 218, - 130, 180, 31, 242, 9, 180, 31, 249, 220, 180, 31, 250, 3, 180, 31, 244, - 185, 180, 31, 254, 221, 180, 31, 249, 219, 180, 31, 226, 201, 216, 197, - 213, 242, 180, 31, 247, 240, 180, 31, 233, 130, 180, 31, 244, 21, 249, - 157, 222, 204, 214, 174, 21, 111, 249, 157, 222, 204, 214, 174, 21, 105, - 249, 157, 222, 204, 214, 174, 21, 158, 249, 157, 222, 204, 214, 174, 21, - 161, 249, 157, 222, 204, 214, 174, 21, 190, 249, 157, 222, 204, 214, 174, - 21, 195, 249, 157, 222, 204, 214, 174, 21, 199, 249, 157, 222, 204, 214, - 174, 21, 196, 249, 157, 222, 204, 214, 174, 21, 201, 249, 157, 222, 204, - 216, 244, 21, 111, 249, 157, 222, 204, 216, 244, 21, 105, 249, 157, 222, - 204, 216, 244, 21, 158, 249, 157, 222, 204, 216, 244, 21, 161, 249, 157, - 222, 204, 216, 244, 21, 190, 249, 157, 222, 204, 216, 244, 21, 195, 249, - 157, 222, 204, 216, 244, 21, 199, 249, 157, 222, 204, 216, 244, 21, 196, - 249, 157, 222, 204, 216, 244, 21, 201, 11, 23, 6, 61, 11, 23, 6, 253, - 166, 11, 23, 6, 251, 74, 11, 23, 6, 249, 68, 11, 23, 6, 76, 11, 23, 6, - 245, 14, 11, 23, 6, 243, 209, 11, 23, 6, 242, 67, 11, 23, 6, 74, 11, 23, - 6, 235, 150, 11, 23, 6, 235, 29, 11, 23, 6, 156, 11, 23, 6, 194, 11, 23, - 6, 230, 30, 11, 23, 6, 78, 11, 23, 6, 226, 109, 11, 23, 6, 224, 99, 11, - 23, 6, 153, 11, 23, 6, 222, 93, 11, 23, 6, 217, 153, 11, 23, 6, 69, 11, - 23, 6, 214, 105, 11, 23, 6, 212, 98, 11, 23, 6, 211, 178, 11, 23, 6, 211, - 117, 11, 23, 6, 210, 159, 11, 23, 4, 61, 11, 23, 4, 253, 166, 11, 23, 4, - 251, 74, 11, 23, 4, 249, 68, 11, 23, 4, 76, 11, 23, 4, 245, 14, 11, 23, - 4, 243, 209, 11, 23, 4, 242, 67, 11, 23, 4, 74, 11, 23, 4, 235, 150, 11, - 23, 4, 235, 29, 11, 23, 4, 156, 11, 23, 4, 194, 11, 23, 4, 230, 30, 11, - 23, 4, 78, 11, 23, 4, 226, 109, 11, 23, 4, 224, 99, 11, 23, 4, 153, 11, - 23, 4, 222, 93, 11, 23, 4, 217, 153, 11, 23, 4, 69, 11, 23, 4, 214, 105, - 11, 23, 4, 212, 98, 11, 23, 4, 211, 178, 11, 23, 4, 211, 117, 11, 23, 4, - 210, 159, 11, 32, 6, 61, 11, 32, 6, 253, 166, 11, 32, 6, 251, 74, 11, 32, - 6, 249, 68, 11, 32, 6, 76, 11, 32, 6, 245, 14, 11, 32, 6, 243, 209, 11, - 32, 6, 242, 67, 11, 32, 6, 74, 11, 32, 6, 235, 150, 11, 32, 6, 235, 29, - 11, 32, 6, 156, 11, 32, 6, 194, 11, 32, 6, 230, 30, 11, 32, 6, 78, 11, - 32, 6, 226, 109, 11, 32, 6, 224, 99, 11, 32, 6, 153, 11, 32, 6, 222, 93, - 11, 32, 6, 217, 153, 11, 32, 6, 69, 11, 32, 6, 214, 105, 11, 32, 6, 212, - 98, 11, 32, 6, 211, 178, 11, 32, 6, 211, 117, 11, 32, 6, 210, 159, 11, - 32, 4, 61, 11, 32, 4, 253, 166, 11, 32, 4, 251, 74, 11, 32, 4, 249, 68, - 11, 32, 4, 76, 11, 32, 4, 245, 14, 11, 32, 4, 243, 209, 11, 32, 4, 74, - 11, 32, 4, 235, 150, 11, 32, 4, 235, 29, 11, 32, 4, 156, 11, 32, 4, 194, - 11, 32, 4, 230, 30, 11, 32, 4, 78, 11, 32, 4, 226, 109, 11, 32, 4, 224, - 99, 11, 32, 4, 153, 11, 32, 4, 222, 93, 11, 32, 4, 217, 153, 11, 32, 4, - 69, 11, 32, 4, 214, 105, 11, 32, 4, 212, 98, 11, 32, 4, 211, 178, 11, 32, - 4, 211, 117, 11, 32, 4, 210, 159, 11, 23, 32, 6, 61, 11, 23, 32, 6, 253, - 166, 11, 23, 32, 6, 251, 74, 11, 23, 32, 6, 249, 68, 11, 23, 32, 6, 76, - 11, 23, 32, 6, 245, 14, 11, 23, 32, 6, 243, 209, 11, 23, 32, 6, 242, 67, - 11, 23, 32, 6, 74, 11, 23, 32, 6, 235, 150, 11, 23, 32, 6, 235, 29, 11, - 23, 32, 6, 156, 11, 23, 32, 6, 194, 11, 23, 32, 6, 230, 30, 11, 23, 32, - 6, 78, 11, 23, 32, 6, 226, 109, 11, 23, 32, 6, 224, 99, 11, 23, 32, 6, - 153, 11, 23, 32, 6, 222, 93, 11, 23, 32, 6, 217, 153, 11, 23, 32, 6, 69, - 11, 23, 32, 6, 214, 105, 11, 23, 32, 6, 212, 98, 11, 23, 32, 6, 211, 178, - 11, 23, 32, 6, 211, 117, 11, 23, 32, 6, 210, 159, 11, 23, 32, 4, 61, 11, - 23, 32, 4, 253, 166, 11, 23, 32, 4, 251, 74, 11, 23, 32, 4, 249, 68, 11, - 23, 32, 4, 76, 11, 23, 32, 4, 245, 14, 11, 23, 32, 4, 243, 209, 11, 23, - 32, 4, 242, 67, 11, 23, 32, 4, 74, 11, 23, 32, 4, 235, 150, 11, 23, 32, - 4, 235, 29, 11, 23, 32, 4, 156, 11, 23, 32, 4, 194, 11, 23, 32, 4, 230, - 30, 11, 23, 32, 4, 78, 11, 23, 32, 4, 226, 109, 11, 23, 32, 4, 224, 99, - 11, 23, 32, 4, 153, 11, 23, 32, 4, 222, 93, 11, 23, 32, 4, 217, 153, 11, - 23, 32, 4, 69, 11, 23, 32, 4, 214, 105, 11, 23, 32, 4, 212, 98, 11, 23, - 32, 4, 211, 178, 11, 23, 32, 4, 211, 117, 11, 23, 32, 4, 210, 159, 11, - 119, 6, 61, 11, 119, 6, 251, 74, 11, 119, 6, 249, 68, 11, 119, 6, 243, - 209, 11, 119, 6, 235, 150, 11, 119, 6, 235, 29, 11, 119, 6, 230, 30, 11, - 119, 6, 78, 11, 119, 6, 226, 109, 11, 119, 6, 224, 99, 11, 119, 6, 222, - 93, 11, 119, 6, 217, 153, 11, 119, 6, 69, 11, 119, 6, 214, 105, 11, 119, - 6, 212, 98, 11, 119, 6, 211, 178, 11, 119, 6, 211, 117, 11, 119, 6, 210, - 159, 11, 119, 4, 61, 11, 119, 4, 253, 166, 11, 119, 4, 251, 74, 11, 119, - 4, 249, 68, 11, 119, 4, 245, 14, 11, 119, 4, 242, 67, 11, 119, 4, 74, 11, - 119, 4, 235, 150, 11, 119, 4, 235, 29, 11, 119, 4, 156, 11, 119, 4, 194, - 11, 119, 4, 230, 30, 11, 119, 4, 226, 109, 11, 119, 4, 224, 99, 11, 119, - 4, 153, 11, 119, 4, 222, 93, 11, 119, 4, 217, 153, 11, 119, 4, 69, 11, - 119, 4, 214, 105, 11, 119, 4, 212, 98, 11, 119, 4, 211, 178, 11, 119, 4, - 211, 117, 11, 119, 4, 210, 159, 11, 23, 119, 6, 61, 11, 23, 119, 6, 253, - 166, 11, 23, 119, 6, 251, 74, 11, 23, 119, 6, 249, 68, 11, 23, 119, 6, - 76, 11, 23, 119, 6, 245, 14, 11, 23, 119, 6, 243, 209, 11, 23, 119, 6, - 242, 67, 11, 23, 119, 6, 74, 11, 23, 119, 6, 235, 150, 11, 23, 119, 6, - 235, 29, 11, 23, 119, 6, 156, 11, 23, 119, 6, 194, 11, 23, 119, 6, 230, - 30, 11, 23, 119, 6, 78, 11, 23, 119, 6, 226, 109, 11, 23, 119, 6, 224, - 99, 11, 23, 119, 6, 153, 11, 23, 119, 6, 222, 93, 11, 23, 119, 6, 217, - 153, 11, 23, 119, 6, 69, 11, 23, 119, 6, 214, 105, 11, 23, 119, 6, 212, - 98, 11, 23, 119, 6, 211, 178, 11, 23, 119, 6, 211, 117, 11, 23, 119, 6, - 210, 159, 11, 23, 119, 4, 61, 11, 23, 119, 4, 253, 166, 11, 23, 119, 4, - 251, 74, 11, 23, 119, 4, 249, 68, 11, 23, 119, 4, 76, 11, 23, 119, 4, - 245, 14, 11, 23, 119, 4, 243, 209, 11, 23, 119, 4, 242, 67, 11, 23, 119, - 4, 74, 11, 23, 119, 4, 235, 150, 11, 23, 119, 4, 235, 29, 11, 23, 119, 4, - 156, 11, 23, 119, 4, 194, 11, 23, 119, 4, 230, 30, 11, 23, 119, 4, 78, - 11, 23, 119, 4, 226, 109, 11, 23, 119, 4, 224, 99, 11, 23, 119, 4, 153, - 11, 23, 119, 4, 222, 93, 11, 23, 119, 4, 217, 153, 11, 23, 119, 4, 69, - 11, 23, 119, 4, 214, 105, 11, 23, 119, 4, 212, 98, 11, 23, 119, 4, 211, - 178, 11, 23, 119, 4, 211, 117, 11, 23, 119, 4, 210, 159, 11, 133, 6, 61, - 11, 133, 6, 253, 166, 11, 133, 6, 249, 68, 11, 133, 6, 76, 11, 133, 6, - 245, 14, 11, 133, 6, 243, 209, 11, 133, 6, 235, 150, 11, 133, 6, 235, 29, - 11, 133, 6, 156, 11, 133, 6, 194, 11, 133, 6, 230, 30, 11, 133, 6, 78, - 11, 133, 6, 226, 109, 11, 133, 6, 224, 99, 11, 133, 6, 222, 93, 11, 133, - 6, 217, 153, 11, 133, 6, 69, 11, 133, 6, 214, 105, 11, 133, 6, 212, 98, - 11, 133, 6, 211, 178, 11, 133, 6, 211, 117, 11, 133, 4, 61, 11, 133, 4, - 253, 166, 11, 133, 4, 251, 74, 11, 133, 4, 249, 68, 11, 133, 4, 76, 11, - 133, 4, 245, 14, 11, 133, 4, 243, 209, 11, 133, 4, 242, 67, 11, 133, 4, - 74, 11, 133, 4, 235, 150, 11, 133, 4, 235, 29, 11, 133, 4, 156, 11, 133, - 4, 194, 11, 133, 4, 230, 30, 11, 133, 4, 78, 11, 133, 4, 226, 109, 11, - 133, 4, 224, 99, 11, 133, 4, 153, 11, 133, 4, 222, 93, 11, 133, 4, 217, - 153, 11, 133, 4, 69, 11, 133, 4, 214, 105, 11, 133, 4, 212, 98, 11, 133, - 4, 211, 178, 11, 133, 4, 211, 117, 11, 133, 4, 210, 159, 11, 139, 6, 61, - 11, 139, 6, 253, 166, 11, 139, 6, 249, 68, 11, 139, 6, 76, 11, 139, 6, - 245, 14, 11, 139, 6, 243, 209, 11, 139, 6, 74, 11, 139, 6, 235, 150, 11, - 139, 6, 235, 29, 11, 139, 6, 156, 11, 139, 6, 194, 11, 139, 6, 78, 11, - 139, 6, 222, 93, 11, 139, 6, 217, 153, 11, 139, 6, 69, 11, 139, 6, 214, - 105, 11, 139, 6, 212, 98, 11, 139, 6, 211, 178, 11, 139, 6, 211, 117, 11, - 139, 4, 61, 11, 139, 4, 253, 166, 11, 139, 4, 251, 74, 11, 139, 4, 249, - 68, 11, 139, 4, 76, 11, 139, 4, 245, 14, 11, 139, 4, 243, 209, 11, 139, - 4, 242, 67, 11, 139, 4, 74, 11, 139, 4, 235, 150, 11, 139, 4, 235, 29, - 11, 139, 4, 156, 11, 139, 4, 194, 11, 139, 4, 230, 30, 11, 139, 4, 78, - 11, 139, 4, 226, 109, 11, 139, 4, 224, 99, 11, 139, 4, 153, 11, 139, 4, - 222, 93, 11, 139, 4, 217, 153, 11, 139, 4, 69, 11, 139, 4, 214, 105, 11, - 139, 4, 212, 98, 11, 139, 4, 211, 178, 11, 139, 4, 211, 117, 11, 139, 4, - 210, 159, 11, 23, 133, 6, 61, 11, 23, 133, 6, 253, 166, 11, 23, 133, 6, - 251, 74, 11, 23, 133, 6, 249, 68, 11, 23, 133, 6, 76, 11, 23, 133, 6, - 245, 14, 11, 23, 133, 6, 243, 209, 11, 23, 133, 6, 242, 67, 11, 23, 133, - 6, 74, 11, 23, 133, 6, 235, 150, 11, 23, 133, 6, 235, 29, 11, 23, 133, 6, - 156, 11, 23, 133, 6, 194, 11, 23, 133, 6, 230, 30, 11, 23, 133, 6, 78, - 11, 23, 133, 6, 226, 109, 11, 23, 133, 6, 224, 99, 11, 23, 133, 6, 153, - 11, 23, 133, 6, 222, 93, 11, 23, 133, 6, 217, 153, 11, 23, 133, 6, 69, - 11, 23, 133, 6, 214, 105, 11, 23, 133, 6, 212, 98, 11, 23, 133, 6, 211, - 178, 11, 23, 133, 6, 211, 117, 11, 23, 133, 6, 210, 159, 11, 23, 133, 4, - 61, 11, 23, 133, 4, 253, 166, 11, 23, 133, 4, 251, 74, 11, 23, 133, 4, - 249, 68, 11, 23, 133, 4, 76, 11, 23, 133, 4, 245, 14, 11, 23, 133, 4, - 243, 209, 11, 23, 133, 4, 242, 67, 11, 23, 133, 4, 74, 11, 23, 133, 4, - 235, 150, 11, 23, 133, 4, 235, 29, 11, 23, 133, 4, 156, 11, 23, 133, 4, - 194, 11, 23, 133, 4, 230, 30, 11, 23, 133, 4, 78, 11, 23, 133, 4, 226, - 109, 11, 23, 133, 4, 224, 99, 11, 23, 133, 4, 153, 11, 23, 133, 4, 222, - 93, 11, 23, 133, 4, 217, 153, 11, 23, 133, 4, 69, 11, 23, 133, 4, 214, - 105, 11, 23, 133, 4, 212, 98, 11, 23, 133, 4, 211, 178, 11, 23, 133, 4, - 211, 117, 11, 23, 133, 4, 210, 159, 11, 35, 6, 61, 11, 35, 6, 253, 166, - 11, 35, 6, 251, 74, 11, 35, 6, 249, 68, 11, 35, 6, 76, 11, 35, 6, 245, - 14, 11, 35, 6, 243, 209, 11, 35, 6, 242, 67, 11, 35, 6, 74, 11, 35, 6, - 235, 150, 11, 35, 6, 235, 29, 11, 35, 6, 156, 11, 35, 6, 194, 11, 35, 6, - 230, 30, 11, 35, 6, 78, 11, 35, 6, 226, 109, 11, 35, 6, 224, 99, 11, 35, - 6, 153, 11, 35, 6, 222, 93, 11, 35, 6, 217, 153, 11, 35, 6, 69, 11, 35, - 6, 214, 105, 11, 35, 6, 212, 98, 11, 35, 6, 211, 178, 11, 35, 6, 211, - 117, 11, 35, 6, 210, 159, 11, 35, 4, 61, 11, 35, 4, 253, 166, 11, 35, 4, - 251, 74, 11, 35, 4, 249, 68, 11, 35, 4, 76, 11, 35, 4, 245, 14, 11, 35, - 4, 243, 209, 11, 35, 4, 242, 67, 11, 35, 4, 74, 11, 35, 4, 235, 150, 11, - 35, 4, 235, 29, 11, 35, 4, 156, 11, 35, 4, 194, 11, 35, 4, 230, 30, 11, - 35, 4, 78, 11, 35, 4, 226, 109, 11, 35, 4, 224, 99, 11, 35, 4, 153, 11, - 35, 4, 222, 93, 11, 35, 4, 217, 153, 11, 35, 4, 69, 11, 35, 4, 214, 105, - 11, 35, 4, 212, 98, 11, 35, 4, 211, 178, 11, 35, 4, 211, 117, 11, 35, 4, - 210, 159, 11, 35, 23, 6, 61, 11, 35, 23, 6, 253, 166, 11, 35, 23, 6, 251, - 74, 11, 35, 23, 6, 249, 68, 11, 35, 23, 6, 76, 11, 35, 23, 6, 245, 14, - 11, 35, 23, 6, 243, 209, 11, 35, 23, 6, 242, 67, 11, 35, 23, 6, 74, 11, - 35, 23, 6, 235, 150, 11, 35, 23, 6, 235, 29, 11, 35, 23, 6, 156, 11, 35, - 23, 6, 194, 11, 35, 23, 6, 230, 30, 11, 35, 23, 6, 78, 11, 35, 23, 6, - 226, 109, 11, 35, 23, 6, 224, 99, 11, 35, 23, 6, 153, 11, 35, 23, 6, 222, - 93, 11, 35, 23, 6, 217, 153, 11, 35, 23, 6, 69, 11, 35, 23, 6, 214, 105, - 11, 35, 23, 6, 212, 98, 11, 35, 23, 6, 211, 178, 11, 35, 23, 6, 211, 117, - 11, 35, 23, 6, 210, 159, 11, 35, 23, 4, 61, 11, 35, 23, 4, 253, 166, 11, - 35, 23, 4, 251, 74, 11, 35, 23, 4, 249, 68, 11, 35, 23, 4, 76, 11, 35, - 23, 4, 245, 14, 11, 35, 23, 4, 243, 209, 11, 35, 23, 4, 242, 67, 11, 35, - 23, 4, 74, 11, 35, 23, 4, 235, 150, 11, 35, 23, 4, 235, 29, 11, 35, 23, - 4, 156, 11, 35, 23, 4, 194, 11, 35, 23, 4, 230, 30, 11, 35, 23, 4, 78, - 11, 35, 23, 4, 226, 109, 11, 35, 23, 4, 224, 99, 11, 35, 23, 4, 153, 11, - 35, 23, 4, 222, 93, 11, 35, 23, 4, 217, 153, 11, 35, 23, 4, 69, 11, 35, - 23, 4, 214, 105, 11, 35, 23, 4, 212, 98, 11, 35, 23, 4, 211, 178, 11, 35, - 23, 4, 211, 117, 11, 35, 23, 4, 210, 159, 11, 35, 32, 6, 61, 11, 35, 32, - 6, 253, 166, 11, 35, 32, 6, 251, 74, 11, 35, 32, 6, 249, 68, 11, 35, 32, - 6, 76, 11, 35, 32, 6, 245, 14, 11, 35, 32, 6, 243, 209, 11, 35, 32, 6, - 242, 67, 11, 35, 32, 6, 74, 11, 35, 32, 6, 235, 150, 11, 35, 32, 6, 235, - 29, 11, 35, 32, 6, 156, 11, 35, 32, 6, 194, 11, 35, 32, 6, 230, 30, 11, - 35, 32, 6, 78, 11, 35, 32, 6, 226, 109, 11, 35, 32, 6, 224, 99, 11, 35, - 32, 6, 153, 11, 35, 32, 6, 222, 93, 11, 35, 32, 6, 217, 153, 11, 35, 32, - 6, 69, 11, 35, 32, 6, 214, 105, 11, 35, 32, 6, 212, 98, 11, 35, 32, 6, - 211, 178, 11, 35, 32, 6, 211, 117, 11, 35, 32, 6, 210, 159, 11, 35, 32, - 4, 61, 11, 35, 32, 4, 253, 166, 11, 35, 32, 4, 251, 74, 11, 35, 32, 4, - 249, 68, 11, 35, 32, 4, 76, 11, 35, 32, 4, 245, 14, 11, 35, 32, 4, 243, - 209, 11, 35, 32, 4, 242, 67, 11, 35, 32, 4, 74, 11, 35, 32, 4, 235, 150, - 11, 35, 32, 4, 235, 29, 11, 35, 32, 4, 156, 11, 35, 32, 4, 194, 11, 35, - 32, 4, 230, 30, 11, 35, 32, 4, 78, 11, 35, 32, 4, 226, 109, 11, 35, 32, - 4, 224, 99, 11, 35, 32, 4, 153, 11, 35, 32, 4, 222, 93, 11, 35, 32, 4, - 217, 153, 11, 35, 32, 4, 69, 11, 35, 32, 4, 214, 105, 11, 35, 32, 4, 212, - 98, 11, 35, 32, 4, 211, 178, 11, 35, 32, 4, 211, 117, 11, 35, 32, 4, 210, - 159, 11, 35, 23, 32, 6, 61, 11, 35, 23, 32, 6, 253, 166, 11, 35, 23, 32, - 6, 251, 74, 11, 35, 23, 32, 6, 249, 68, 11, 35, 23, 32, 6, 76, 11, 35, - 23, 32, 6, 245, 14, 11, 35, 23, 32, 6, 243, 209, 11, 35, 23, 32, 6, 242, - 67, 11, 35, 23, 32, 6, 74, 11, 35, 23, 32, 6, 235, 150, 11, 35, 23, 32, - 6, 235, 29, 11, 35, 23, 32, 6, 156, 11, 35, 23, 32, 6, 194, 11, 35, 23, - 32, 6, 230, 30, 11, 35, 23, 32, 6, 78, 11, 35, 23, 32, 6, 226, 109, 11, - 35, 23, 32, 6, 224, 99, 11, 35, 23, 32, 6, 153, 11, 35, 23, 32, 6, 222, - 93, 11, 35, 23, 32, 6, 217, 153, 11, 35, 23, 32, 6, 69, 11, 35, 23, 32, - 6, 214, 105, 11, 35, 23, 32, 6, 212, 98, 11, 35, 23, 32, 6, 211, 178, 11, - 35, 23, 32, 6, 211, 117, 11, 35, 23, 32, 6, 210, 159, 11, 35, 23, 32, 4, - 61, 11, 35, 23, 32, 4, 253, 166, 11, 35, 23, 32, 4, 251, 74, 11, 35, 23, - 32, 4, 249, 68, 11, 35, 23, 32, 4, 76, 11, 35, 23, 32, 4, 245, 14, 11, - 35, 23, 32, 4, 243, 209, 11, 35, 23, 32, 4, 242, 67, 11, 35, 23, 32, 4, - 74, 11, 35, 23, 32, 4, 235, 150, 11, 35, 23, 32, 4, 235, 29, 11, 35, 23, - 32, 4, 156, 11, 35, 23, 32, 4, 194, 11, 35, 23, 32, 4, 230, 30, 11, 35, - 23, 32, 4, 78, 11, 35, 23, 32, 4, 226, 109, 11, 35, 23, 32, 4, 224, 99, - 11, 35, 23, 32, 4, 153, 11, 35, 23, 32, 4, 222, 93, 11, 35, 23, 32, 4, - 217, 153, 11, 35, 23, 32, 4, 69, 11, 35, 23, 32, 4, 214, 105, 11, 35, 23, - 32, 4, 212, 98, 11, 35, 23, 32, 4, 211, 178, 11, 35, 23, 32, 4, 211, 117, - 11, 35, 23, 32, 4, 210, 159, 11, 230, 143, 6, 61, 11, 230, 143, 6, 253, - 166, 11, 230, 143, 6, 251, 74, 11, 230, 143, 6, 249, 68, 11, 230, 143, 6, - 76, 11, 230, 143, 6, 245, 14, 11, 230, 143, 6, 243, 209, 11, 230, 143, 6, - 242, 67, 11, 230, 143, 6, 74, 11, 230, 143, 6, 235, 150, 11, 230, 143, 6, - 235, 29, 11, 230, 143, 6, 156, 11, 230, 143, 6, 194, 11, 230, 143, 6, - 230, 30, 11, 230, 143, 6, 78, 11, 230, 143, 6, 226, 109, 11, 230, 143, 6, - 224, 99, 11, 230, 143, 6, 153, 11, 230, 143, 6, 222, 93, 11, 230, 143, 6, - 217, 153, 11, 230, 143, 6, 69, 11, 230, 143, 6, 214, 105, 11, 230, 143, - 6, 212, 98, 11, 230, 143, 6, 211, 178, 11, 230, 143, 6, 211, 117, 11, - 230, 143, 6, 210, 159, 11, 230, 143, 4, 61, 11, 230, 143, 4, 253, 166, - 11, 230, 143, 4, 251, 74, 11, 230, 143, 4, 249, 68, 11, 230, 143, 4, 76, - 11, 230, 143, 4, 245, 14, 11, 230, 143, 4, 243, 209, 11, 230, 143, 4, - 242, 67, 11, 230, 143, 4, 74, 11, 230, 143, 4, 235, 150, 11, 230, 143, 4, - 235, 29, 11, 230, 143, 4, 156, 11, 230, 143, 4, 194, 11, 230, 143, 4, - 230, 30, 11, 230, 143, 4, 78, 11, 230, 143, 4, 226, 109, 11, 230, 143, 4, - 224, 99, 11, 230, 143, 4, 153, 11, 230, 143, 4, 222, 93, 11, 230, 143, 4, - 217, 153, 11, 230, 143, 4, 69, 11, 230, 143, 4, 214, 105, 11, 230, 143, - 4, 212, 98, 11, 230, 143, 4, 211, 178, 11, 230, 143, 4, 211, 117, 11, - 230, 143, 4, 210, 159, 11, 32, 4, 247, 127, 74, 11, 32, 4, 247, 127, 235, - 150, 11, 23, 6, 254, 151, 11, 23, 6, 252, 34, 11, 23, 6, 243, 114, 11, - 23, 6, 248, 62, 11, 23, 6, 245, 108, 11, 23, 6, 210, 85, 11, 23, 6, 245, - 71, 11, 23, 6, 216, 180, 11, 23, 6, 235, 192, 11, 23, 6, 234, 228, 11, - 23, 6, 233, 104, 11, 23, 6, 230, 107, 11, 23, 6, 227, 242, 11, 23, 6, - 211, 157, 11, 23, 6, 226, 203, 11, 23, 6, 225, 111, 11, 23, 6, 223, 40, - 11, 23, 6, 216, 181, 87, 11, 23, 6, 219, 179, 11, 23, 6, 217, 42, 11, 23, - 6, 214, 157, 11, 23, 6, 225, 136, 11, 23, 6, 250, 118, 11, 23, 6, 224, - 164, 11, 23, 6, 226, 205, 11, 23, 229, 226, 11, 23, 4, 254, 151, 11, 23, - 4, 252, 34, 11, 23, 4, 243, 114, 11, 23, 4, 248, 62, 11, 23, 4, 245, 108, - 11, 23, 4, 210, 85, 11, 23, 4, 245, 71, 11, 23, 4, 216, 180, 11, 23, 4, - 235, 192, 11, 23, 4, 234, 228, 11, 23, 4, 233, 104, 11, 23, 4, 230, 107, - 11, 23, 4, 227, 242, 11, 23, 4, 211, 157, 11, 23, 4, 226, 203, 11, 23, 4, - 225, 111, 11, 23, 4, 223, 40, 11, 23, 4, 40, 219, 179, 11, 23, 4, 219, - 179, 11, 23, 4, 217, 42, 11, 23, 4, 214, 157, 11, 23, 4, 225, 136, 11, - 23, 4, 250, 118, 11, 23, 4, 224, 164, 11, 23, 4, 226, 205, 11, 23, 226, - 1, 247, 241, 11, 23, 245, 109, 87, 11, 23, 216, 181, 87, 11, 23, 234, - 229, 87, 11, 23, 225, 137, 87, 11, 23, 223, 41, 87, 11, 23, 225, 112, 87, - 11, 32, 6, 254, 151, 11, 32, 6, 252, 34, 11, 32, 6, 243, 114, 11, 32, 6, - 248, 62, 11, 32, 6, 245, 108, 11, 32, 6, 210, 85, 11, 32, 6, 245, 71, 11, - 32, 6, 216, 180, 11, 32, 6, 235, 192, 11, 32, 6, 234, 228, 11, 32, 6, - 233, 104, 11, 32, 6, 230, 107, 11, 32, 6, 227, 242, 11, 32, 6, 211, 157, - 11, 32, 6, 226, 203, 11, 32, 6, 225, 111, 11, 32, 6, 223, 40, 11, 32, 6, - 216, 181, 87, 11, 32, 6, 219, 179, 11, 32, 6, 217, 42, 11, 32, 6, 214, - 157, 11, 32, 6, 225, 136, 11, 32, 6, 250, 118, 11, 32, 6, 224, 164, 11, - 32, 6, 226, 205, 11, 32, 229, 226, 11, 32, 4, 254, 151, 11, 32, 4, 252, - 34, 11, 32, 4, 243, 114, 11, 32, 4, 248, 62, 11, 32, 4, 245, 108, 11, 32, - 4, 210, 85, 11, 32, 4, 245, 71, 11, 32, 4, 216, 180, 11, 32, 4, 235, 192, - 11, 32, 4, 234, 228, 11, 32, 4, 233, 104, 11, 32, 4, 230, 107, 11, 32, 4, - 227, 242, 11, 32, 4, 211, 157, 11, 32, 4, 226, 203, 11, 32, 4, 225, 111, - 11, 32, 4, 223, 40, 11, 32, 4, 40, 219, 179, 11, 32, 4, 219, 179, 11, 32, - 4, 217, 42, 11, 32, 4, 214, 157, 11, 32, 4, 225, 136, 11, 32, 4, 250, - 118, 11, 32, 4, 224, 164, 11, 32, 4, 226, 205, 11, 32, 226, 1, 247, 241, - 11, 32, 245, 109, 87, 11, 32, 216, 181, 87, 11, 32, 234, 229, 87, 11, 32, - 225, 137, 87, 11, 32, 223, 41, 87, 11, 32, 225, 112, 87, 11, 23, 32, 6, - 254, 151, 11, 23, 32, 6, 252, 34, 11, 23, 32, 6, 243, 114, 11, 23, 32, 6, - 248, 62, 11, 23, 32, 6, 245, 108, 11, 23, 32, 6, 210, 85, 11, 23, 32, 6, - 245, 71, 11, 23, 32, 6, 216, 180, 11, 23, 32, 6, 235, 192, 11, 23, 32, 6, - 234, 228, 11, 23, 32, 6, 233, 104, 11, 23, 32, 6, 230, 107, 11, 23, 32, - 6, 227, 242, 11, 23, 32, 6, 211, 157, 11, 23, 32, 6, 226, 203, 11, 23, - 32, 6, 225, 111, 11, 23, 32, 6, 223, 40, 11, 23, 32, 6, 216, 181, 87, 11, - 23, 32, 6, 219, 179, 11, 23, 32, 6, 217, 42, 11, 23, 32, 6, 214, 157, 11, - 23, 32, 6, 225, 136, 11, 23, 32, 6, 250, 118, 11, 23, 32, 6, 224, 164, - 11, 23, 32, 6, 226, 205, 11, 23, 32, 229, 226, 11, 23, 32, 4, 254, 151, - 11, 23, 32, 4, 252, 34, 11, 23, 32, 4, 243, 114, 11, 23, 32, 4, 248, 62, - 11, 23, 32, 4, 245, 108, 11, 23, 32, 4, 210, 85, 11, 23, 32, 4, 245, 71, - 11, 23, 32, 4, 216, 180, 11, 23, 32, 4, 235, 192, 11, 23, 32, 4, 234, - 228, 11, 23, 32, 4, 233, 104, 11, 23, 32, 4, 230, 107, 11, 23, 32, 4, - 227, 242, 11, 23, 32, 4, 211, 157, 11, 23, 32, 4, 226, 203, 11, 23, 32, - 4, 225, 111, 11, 23, 32, 4, 223, 40, 11, 23, 32, 4, 40, 219, 179, 11, 23, - 32, 4, 219, 179, 11, 23, 32, 4, 217, 42, 11, 23, 32, 4, 214, 157, 11, 23, - 32, 4, 225, 136, 11, 23, 32, 4, 250, 118, 11, 23, 32, 4, 224, 164, 11, - 23, 32, 4, 226, 205, 11, 23, 32, 226, 1, 247, 241, 11, 23, 32, 245, 109, - 87, 11, 23, 32, 216, 181, 87, 11, 23, 32, 234, 229, 87, 11, 23, 32, 225, - 137, 87, 11, 23, 32, 223, 41, 87, 11, 23, 32, 225, 112, 87, 11, 35, 23, - 6, 254, 151, 11, 35, 23, 6, 252, 34, 11, 35, 23, 6, 243, 114, 11, 35, 23, - 6, 248, 62, 11, 35, 23, 6, 245, 108, 11, 35, 23, 6, 210, 85, 11, 35, 23, - 6, 245, 71, 11, 35, 23, 6, 216, 180, 11, 35, 23, 6, 235, 192, 11, 35, 23, - 6, 234, 228, 11, 35, 23, 6, 233, 104, 11, 35, 23, 6, 230, 107, 11, 35, - 23, 6, 227, 242, 11, 35, 23, 6, 211, 157, 11, 35, 23, 6, 226, 203, 11, - 35, 23, 6, 225, 111, 11, 35, 23, 6, 223, 40, 11, 35, 23, 6, 216, 181, 87, - 11, 35, 23, 6, 219, 179, 11, 35, 23, 6, 217, 42, 11, 35, 23, 6, 214, 157, - 11, 35, 23, 6, 225, 136, 11, 35, 23, 6, 250, 118, 11, 35, 23, 6, 224, - 164, 11, 35, 23, 6, 226, 205, 11, 35, 23, 229, 226, 11, 35, 23, 4, 254, - 151, 11, 35, 23, 4, 252, 34, 11, 35, 23, 4, 243, 114, 11, 35, 23, 4, 248, - 62, 11, 35, 23, 4, 245, 108, 11, 35, 23, 4, 210, 85, 11, 35, 23, 4, 245, - 71, 11, 35, 23, 4, 216, 180, 11, 35, 23, 4, 235, 192, 11, 35, 23, 4, 234, - 228, 11, 35, 23, 4, 233, 104, 11, 35, 23, 4, 230, 107, 11, 35, 23, 4, - 227, 242, 11, 35, 23, 4, 211, 157, 11, 35, 23, 4, 226, 203, 11, 35, 23, - 4, 225, 111, 11, 35, 23, 4, 223, 40, 11, 35, 23, 4, 40, 219, 179, 11, 35, - 23, 4, 219, 179, 11, 35, 23, 4, 217, 42, 11, 35, 23, 4, 214, 157, 11, 35, - 23, 4, 225, 136, 11, 35, 23, 4, 250, 118, 11, 35, 23, 4, 224, 164, 11, - 35, 23, 4, 226, 205, 11, 35, 23, 226, 1, 247, 241, 11, 35, 23, 245, 109, - 87, 11, 35, 23, 216, 181, 87, 11, 35, 23, 234, 229, 87, 11, 35, 23, 225, - 137, 87, 11, 35, 23, 223, 41, 87, 11, 35, 23, 225, 112, 87, 11, 35, 23, - 32, 6, 254, 151, 11, 35, 23, 32, 6, 252, 34, 11, 35, 23, 32, 6, 243, 114, - 11, 35, 23, 32, 6, 248, 62, 11, 35, 23, 32, 6, 245, 108, 11, 35, 23, 32, - 6, 210, 85, 11, 35, 23, 32, 6, 245, 71, 11, 35, 23, 32, 6, 216, 180, 11, - 35, 23, 32, 6, 235, 192, 11, 35, 23, 32, 6, 234, 228, 11, 35, 23, 32, 6, - 233, 104, 11, 35, 23, 32, 6, 230, 107, 11, 35, 23, 32, 6, 227, 242, 11, - 35, 23, 32, 6, 211, 157, 11, 35, 23, 32, 6, 226, 203, 11, 35, 23, 32, 6, - 225, 111, 11, 35, 23, 32, 6, 223, 40, 11, 35, 23, 32, 6, 216, 181, 87, - 11, 35, 23, 32, 6, 219, 179, 11, 35, 23, 32, 6, 217, 42, 11, 35, 23, 32, - 6, 214, 157, 11, 35, 23, 32, 6, 225, 136, 11, 35, 23, 32, 6, 250, 118, - 11, 35, 23, 32, 6, 224, 164, 11, 35, 23, 32, 6, 226, 205, 11, 35, 23, 32, - 229, 226, 11, 35, 23, 32, 4, 254, 151, 11, 35, 23, 32, 4, 252, 34, 11, - 35, 23, 32, 4, 243, 114, 11, 35, 23, 32, 4, 248, 62, 11, 35, 23, 32, 4, - 245, 108, 11, 35, 23, 32, 4, 210, 85, 11, 35, 23, 32, 4, 245, 71, 11, 35, - 23, 32, 4, 216, 180, 11, 35, 23, 32, 4, 235, 192, 11, 35, 23, 32, 4, 234, - 228, 11, 35, 23, 32, 4, 233, 104, 11, 35, 23, 32, 4, 230, 107, 11, 35, - 23, 32, 4, 227, 242, 11, 35, 23, 32, 4, 211, 157, 11, 35, 23, 32, 4, 226, - 203, 11, 35, 23, 32, 4, 225, 111, 11, 35, 23, 32, 4, 223, 40, 11, 35, 23, - 32, 4, 40, 219, 179, 11, 35, 23, 32, 4, 219, 179, 11, 35, 23, 32, 4, 217, - 42, 11, 35, 23, 32, 4, 214, 157, 11, 35, 23, 32, 4, 225, 136, 11, 35, 23, - 32, 4, 250, 118, 11, 35, 23, 32, 4, 224, 164, 11, 35, 23, 32, 4, 226, - 205, 11, 35, 23, 32, 226, 1, 247, 241, 11, 35, 23, 32, 245, 109, 87, 11, - 35, 23, 32, 216, 181, 87, 11, 35, 23, 32, 234, 229, 87, 11, 35, 23, 32, - 225, 137, 87, 11, 35, 23, 32, 223, 41, 87, 11, 35, 23, 32, 225, 112, 87, - 11, 23, 6, 247, 235, 11, 23, 4, 247, 235, 11, 23, 21, 210, 86, 11, 23, - 21, 111, 11, 23, 21, 105, 11, 23, 21, 158, 11, 23, 21, 161, 11, 23, 21, - 190, 11, 23, 21, 195, 11, 23, 21, 199, 11, 23, 21, 196, 11, 23, 21, 201, - 11, 139, 21, 210, 86, 11, 139, 21, 111, 11, 139, 21, 105, 11, 139, 21, - 158, 11, 139, 21, 161, 11, 139, 21, 190, 11, 139, 21, 195, 11, 139, 21, - 199, 11, 139, 21, 196, 11, 139, 21, 201, 11, 35, 21, 210, 86, 11, 35, 21, - 111, 11, 35, 21, 105, 11, 35, 21, 158, 11, 35, 21, 161, 11, 35, 21, 190, - 11, 35, 21, 195, 11, 35, 21, 199, 11, 35, 21, 196, 11, 35, 21, 201, 11, - 35, 23, 21, 210, 86, 11, 35, 23, 21, 111, 11, 35, 23, 21, 105, 11, 35, - 23, 21, 158, 11, 35, 23, 21, 161, 11, 35, 23, 21, 190, 11, 35, 23, 21, - 195, 11, 35, 23, 21, 199, 11, 35, 23, 21, 196, 11, 35, 23, 21, 201, 11, - 230, 143, 21, 210, 86, 11, 230, 143, 21, 111, 11, 230, 143, 21, 105, 11, - 230, 143, 21, 158, 11, 230, 143, 21, 161, 11, 230, 143, 21, 190, 11, 230, - 143, 21, 195, 11, 230, 143, 21, 199, 11, 230, 143, 21, 196, 11, 230, 143, - 21, 201, 9, 11, 254, 179, 9, 11, 252, 62, 9, 11, 235, 129, 9, 11, 248, - 203, 9, 11, 212, 30, 9, 11, 210, 108, 9, 11, 242, 44, 9, 11, 217, 81, 9, - 11, 211, 43, 9, 11, 235, 0, 9, 11, 233, 108, 9, 11, 231, 83, 9, 11, 228, - 67, 9, 11, 221, 168, 9, 11, 254, 205, 9, 11, 244, 150, 9, 11, 222, 28, 9, - 11, 224, 84, 9, 11, 223, 98, 9, 11, 220, 61, 9, 11, 217, 8, 9, 11, 216, - 193, 9, 11, 234, 135, 9, 11, 216, 203, 9, 11, 248, 224, 9, 11, 210, 111, - 9, 11, 242, 251, 9, 11, 247, 127, 252, 62, 9, 11, 247, 127, 228, 67, 9, - 11, 247, 127, 244, 150, 9, 11, 247, 127, 224, 84, 9, 11, 65, 252, 62, 9, - 11, 65, 235, 129, 9, 11, 65, 241, 225, 9, 11, 65, 242, 44, 9, 11, 65, - 211, 43, 9, 11, 65, 235, 0, 9, 11, 65, 233, 108, 9, 11, 65, 231, 83, 9, - 11, 65, 228, 67, 9, 11, 65, 221, 168, 9, 11, 65, 254, 205, 9, 11, 65, - 244, 150, 9, 11, 65, 222, 28, 9, 11, 65, 224, 84, 9, 11, 65, 220, 61, 9, - 11, 65, 217, 8, 9, 11, 65, 216, 193, 9, 11, 65, 234, 135, 9, 11, 65, 248, - 224, 9, 11, 65, 242, 251, 9, 11, 217, 77, 235, 129, 9, 11, 217, 77, 242, - 44, 9, 11, 217, 77, 211, 43, 9, 11, 217, 77, 233, 108, 9, 11, 217, 77, - 228, 67, 9, 11, 217, 77, 221, 168, 9, 11, 217, 77, 254, 205, 9, 11, 217, - 77, 222, 28, 9, 11, 217, 77, 224, 84, 9, 11, 217, 77, 220, 61, 9, 11, - 217, 77, 234, 135, 9, 11, 217, 77, 248, 224, 9, 11, 217, 77, 242, 251, 9, - 11, 217, 77, 247, 127, 228, 67, 9, 11, 217, 77, 247, 127, 224, 84, 9, 11, - 218, 112, 252, 62, 9, 11, 218, 112, 235, 129, 9, 11, 218, 112, 241, 225, - 9, 11, 218, 112, 242, 44, 9, 11, 218, 112, 217, 81, 9, 11, 218, 112, 211, - 43, 9, 11, 218, 112, 235, 0, 9, 11, 218, 112, 231, 83, 9, 11, 218, 112, - 228, 67, 9, 11, 218, 112, 221, 168, 9, 11, 218, 112, 254, 205, 9, 11, - 218, 112, 244, 150, 9, 11, 218, 112, 222, 28, 9, 11, 218, 112, 224, 84, - 9, 11, 218, 112, 220, 61, 9, 11, 218, 112, 217, 8, 9, 11, 218, 112, 216, - 193, 9, 11, 218, 112, 234, 135, 9, 11, 218, 112, 248, 224, 9, 11, 218, - 112, 210, 111, 9, 11, 218, 112, 242, 251, 9, 11, 218, 112, 247, 127, 252, - 62, 9, 11, 218, 112, 247, 127, 244, 150, 9, 11, 232, 128, 254, 179, 9, - 11, 232, 128, 252, 62, 9, 11, 232, 128, 235, 129, 9, 11, 232, 128, 248, - 203, 9, 11, 232, 128, 241, 225, 9, 11, 232, 128, 212, 30, 9, 11, 232, - 128, 210, 108, 9, 11, 232, 128, 242, 44, 9, 11, 232, 128, 217, 81, 9, 11, - 232, 128, 211, 43, 9, 11, 232, 128, 233, 108, 9, 11, 232, 128, 231, 83, - 9, 11, 232, 128, 228, 67, 9, 11, 232, 128, 221, 168, 9, 11, 232, 128, - 254, 205, 9, 11, 232, 128, 244, 150, 9, 11, 232, 128, 222, 28, 9, 11, - 232, 128, 224, 84, 9, 11, 232, 128, 223, 98, 9, 11, 232, 128, 220, 61, 9, - 11, 232, 128, 217, 8, 9, 11, 232, 128, 216, 193, 9, 11, 232, 128, 234, - 135, 9, 11, 232, 128, 216, 203, 9, 11, 232, 128, 248, 224, 9, 11, 232, - 128, 210, 111, 9, 11, 232, 128, 242, 251, 9, 11, 139, 252, 62, 9, 11, - 139, 235, 129, 9, 11, 139, 248, 203, 9, 11, 139, 212, 30, 9, 11, 139, - 210, 108, 9, 11, 139, 242, 44, 9, 11, 139, 217, 81, 9, 11, 139, 211, 43, - 9, 11, 139, 233, 108, 9, 11, 139, 231, 83, 9, 11, 139, 228, 67, 9, 11, - 139, 221, 168, 9, 11, 139, 254, 205, 9, 11, 139, 244, 150, 9, 11, 139, - 222, 28, 9, 11, 139, 224, 84, 9, 11, 139, 223, 98, 9, 11, 139, 220, 61, - 9, 11, 139, 217, 8, 9, 11, 139, 216, 193, 9, 11, 139, 234, 135, 9, 11, - 139, 216, 203, 9, 11, 139, 248, 224, 9, 11, 139, 210, 111, 9, 11, 139, - 242, 251, 9, 11, 226, 172, 66, 2, 122, 2, 217, 44, 9, 11, 226, 172, 122, - 2, 248, 203, 231, 210, 86, 245, 228, 211, 239, 231, 210, 86, 219, 30, - 211, 239, 231, 210, 86, 212, 9, 211, 239, 231, 210, 86, 228, 61, 211, - 239, 231, 210, 86, 223, 114, 246, 104, 231, 210, 86, 242, 134, 246, 104, - 231, 210, 86, 71, 246, 104, 231, 210, 86, 123, 64, 250, 149, 231, 210, - 86, 113, 64, 250, 149, 231, 210, 86, 134, 64, 250, 149, 231, 210, 86, - 244, 19, 64, 250, 149, 231, 210, 86, 244, 89, 64, 250, 149, 231, 210, 86, - 219, 127, 64, 250, 149, 231, 210, 86, 220, 124, 64, 250, 149, 231, 210, - 86, 245, 201, 64, 250, 149, 231, 210, 86, 228, 205, 64, 250, 149, 231, - 210, 86, 123, 64, 252, 161, 231, 210, 86, 113, 64, 252, 161, 231, 210, - 86, 134, 64, 252, 161, 231, 210, 86, 244, 19, 64, 252, 161, 231, 210, 86, - 244, 89, 64, 252, 161, 231, 210, 86, 219, 127, 64, 252, 161, 231, 210, - 86, 220, 124, 64, 252, 161, 231, 210, 86, 245, 201, 64, 252, 161, 231, - 210, 86, 228, 205, 64, 252, 161, 231, 210, 86, 123, 64, 250, 42, 231, - 210, 86, 113, 64, 250, 42, 231, 210, 86, 134, 64, 250, 42, 231, 210, 86, - 244, 19, 64, 250, 42, 231, 210, 86, 244, 89, 64, 250, 42, 231, 210, 86, - 219, 127, 64, 250, 42, 231, 210, 86, 220, 124, 64, 250, 42, 231, 210, 86, - 245, 201, 64, 250, 42, 231, 210, 86, 228, 205, 64, 250, 42, 231, 210, 86, - 225, 28, 231, 210, 86, 226, 160, 231, 210, 86, 252, 162, 231, 210, 86, - 250, 78, 231, 210, 86, 218, 241, 231, 210, 86, 218, 40, 231, 210, 86, - 253, 187, 231, 210, 86, 211, 232, 231, 210, 86, 235, 68, 231, 210, 86, - 252, 192, 131, 86, 203, 252, 192, 131, 86, 241, 50, 131, 86, 241, 49, - 131, 86, 241, 48, 131, 86, 241, 47, 131, 86, 241, 46, 131, 86, 241, 45, - 131, 86, 241, 44, 131, 86, 241, 43, 131, 86, 241, 42, 131, 86, 241, 41, - 131, 86, 241, 40, 131, 86, 241, 39, 131, 86, 241, 38, 131, 86, 241, 37, - 131, 86, 241, 36, 131, 86, 241, 35, 131, 86, 241, 34, 131, 86, 241, 33, - 131, 86, 241, 32, 131, 86, 241, 31, 131, 86, 241, 30, 131, 86, 241, 29, - 131, 86, 241, 28, 131, 86, 241, 27, 131, 86, 241, 26, 131, 86, 241, 25, - 131, 86, 241, 24, 131, 86, 241, 23, 131, 86, 241, 22, 131, 86, 241, 21, - 131, 86, 241, 20, 131, 86, 241, 19, 131, 86, 241, 18, 131, 86, 241, 17, - 131, 86, 241, 16, 131, 86, 241, 15, 131, 86, 241, 14, 131, 86, 241, 13, - 131, 86, 241, 12, 131, 86, 241, 11, 131, 86, 241, 10, 131, 86, 241, 9, - 131, 86, 241, 8, 131, 86, 241, 7, 131, 86, 241, 6, 131, 86, 241, 5, 131, - 86, 241, 4, 131, 86, 241, 3, 131, 86, 241, 2, 131, 86, 67, 252, 192, 131, - 86, 213, 238, 131, 86, 213, 237, 131, 86, 213, 236, 131, 86, 213, 235, - 131, 86, 213, 234, 131, 86, 213, 233, 131, 86, 213, 232, 131, 86, 213, - 231, 131, 86, 213, 230, 131, 86, 213, 229, 131, 86, 213, 228, 131, 86, - 213, 227, 131, 86, 213, 226, 131, 86, 213, 225, 131, 86, 213, 224, 131, - 86, 213, 223, 131, 86, 213, 222, 131, 86, 213, 221, 131, 86, 213, 220, - 131, 86, 213, 219, 131, 86, 213, 218, 131, 86, 213, 217, 131, 86, 213, - 216, 131, 86, 213, 215, 131, 86, 213, 214, 131, 86, 213, 213, 131, 86, - 213, 212, 131, 86, 213, 211, 131, 86, 213, 210, 131, 86, 213, 209, 131, - 86, 213, 208, 131, 86, 213, 207, 131, 86, 213, 206, 131, 86, 213, 205, - 131, 86, 213, 204, 131, 86, 213, 203, 131, 86, 213, 202, 131, 86, 213, - 201, 131, 86, 213, 200, 131, 86, 213, 199, 131, 86, 213, 198, 131, 86, - 213, 197, 131, 86, 213, 196, 131, 86, 213, 195, 131, 86, 213, 194, 131, - 86, 213, 193, 131, 86, 213, 192, 131, 86, 213, 191, 131, 86, 213, 190, - 225, 36, 250, 251, 252, 192, 225, 36, 250, 251, 255, 18, 64, 219, 17, - 225, 36, 250, 251, 113, 64, 219, 17, 225, 36, 250, 251, 134, 64, 219, 17, - 225, 36, 250, 251, 244, 19, 64, 219, 17, 225, 36, 250, 251, 244, 89, 64, - 219, 17, 225, 36, 250, 251, 219, 127, 64, 219, 17, 225, 36, 250, 251, - 220, 124, 64, 219, 17, 225, 36, 250, 251, 245, 201, 64, 219, 17, 225, 36, - 250, 251, 228, 205, 64, 219, 17, 225, 36, 250, 251, 216, 249, 64, 219, - 17, 225, 36, 250, 251, 235, 145, 64, 219, 17, 225, 36, 250, 251, 234, 37, - 64, 219, 17, 225, 36, 250, 251, 224, 18, 64, 219, 17, 225, 36, 250, 251, - 234, 85, 64, 219, 17, 225, 36, 250, 251, 255, 18, 64, 241, 232, 225, 36, - 250, 251, 113, 64, 241, 232, 225, 36, 250, 251, 134, 64, 241, 232, 225, - 36, 250, 251, 244, 19, 64, 241, 232, 225, 36, 250, 251, 244, 89, 64, 241, - 232, 225, 36, 250, 251, 219, 127, 64, 241, 232, 225, 36, 250, 251, 220, - 124, 64, 241, 232, 225, 36, 250, 251, 245, 201, 64, 241, 232, 225, 36, - 250, 251, 228, 205, 64, 241, 232, 225, 36, 250, 251, 216, 249, 64, 241, - 232, 225, 36, 250, 251, 235, 145, 64, 241, 232, 225, 36, 250, 251, 234, - 37, 64, 241, 232, 225, 36, 250, 251, 224, 18, 64, 241, 232, 225, 36, 250, - 251, 234, 85, 64, 241, 232, 225, 36, 250, 251, 255, 18, 64, 247, 255, - 225, 36, 250, 251, 113, 64, 247, 255, 225, 36, 250, 251, 134, 64, 247, - 255, 225, 36, 250, 251, 244, 19, 64, 247, 255, 225, 36, 250, 251, 244, - 89, 64, 247, 255, 225, 36, 250, 251, 219, 127, 64, 247, 255, 225, 36, - 250, 251, 220, 124, 64, 247, 255, 225, 36, 250, 251, 245, 201, 64, 247, - 255, 225, 36, 250, 251, 228, 205, 64, 247, 255, 225, 36, 250, 251, 216, - 249, 64, 247, 255, 225, 36, 250, 251, 235, 145, 64, 247, 255, 225, 36, - 250, 251, 234, 37, 64, 247, 255, 225, 36, 250, 251, 224, 18, 64, 247, - 255, 225, 36, 250, 251, 234, 85, 64, 247, 255, 225, 36, 250, 251, 85, - 235, 68, 225, 36, 250, 251, 255, 18, 64, 249, 250, 225, 36, 250, 251, - 113, 64, 249, 250, 225, 36, 250, 251, 134, 64, 249, 250, 225, 36, 250, - 251, 244, 19, 64, 249, 250, 225, 36, 250, 251, 244, 89, 64, 249, 250, - 225, 36, 250, 251, 219, 127, 64, 249, 250, 225, 36, 250, 251, 220, 124, - 64, 249, 250, 225, 36, 250, 251, 245, 201, 64, 249, 250, 225, 36, 250, - 251, 228, 205, 64, 249, 250, 225, 36, 250, 251, 216, 249, 64, 249, 250, - 225, 36, 250, 251, 235, 145, 64, 249, 250, 225, 36, 250, 251, 234, 37, - 64, 249, 250, 225, 36, 250, 251, 224, 18, 64, 249, 250, 225, 36, 250, - 251, 234, 85, 64, 249, 250, 225, 36, 250, 251, 71, 235, 68, 21, 210, 87, - 243, 236, 218, 131, 21, 210, 87, 249, 227, 21, 123, 249, 227, 21, 113, - 249, 227, 21, 134, 249, 227, 21, 244, 19, 249, 227, 21, 244, 89, 249, - 227, 21, 219, 127, 249, 227, 21, 220, 124, 249, 227, 21, 245, 201, 249, - 227, 21, 228, 205, 249, 227, 88, 7, 6, 1, 61, 88, 7, 6, 1, 253, 166, 88, - 7, 6, 1, 251, 74, 88, 7, 6, 1, 249, 68, 88, 7, 6, 1, 76, 88, 7, 6, 1, - 245, 14, 88, 7, 6, 1, 243, 209, 88, 7, 6, 1, 242, 67, 88, 7, 6, 1, 74, - 88, 7, 6, 1, 235, 150, 88, 7, 6, 1, 235, 29, 88, 7, 6, 1, 156, 88, 7, 6, - 1, 194, 88, 7, 6, 1, 230, 30, 88, 7, 6, 1, 78, 88, 7, 6, 1, 226, 109, 88, - 7, 6, 1, 224, 99, 88, 7, 6, 1, 153, 88, 7, 6, 1, 222, 93, 88, 7, 6, 1, - 217, 153, 88, 7, 6, 1, 69, 88, 7, 6, 1, 214, 105, 88, 7, 6, 1, 212, 98, - 88, 7, 6, 1, 211, 178, 88, 7, 6, 1, 211, 117, 88, 7, 6, 1, 210, 159, 216, - 7, 220, 55, 251, 165, 7, 6, 1, 222, 93, 37, 32, 7, 6, 1, 251, 74, 37, 32, - 7, 6, 1, 153, 37, 250, 199, 37, 211, 180, 92, 7, 6, 1, 61, 92, 7, 6, 1, - 253, 166, 92, 7, 6, 1, 251, 74, 92, 7, 6, 1, 249, 68, 92, 7, 6, 1, 76, - 92, 7, 6, 1, 245, 14, 92, 7, 6, 1, 243, 209, 92, 7, 6, 1, 242, 67, 92, 7, - 6, 1, 74, 92, 7, 6, 1, 235, 150, 92, 7, 6, 1, 235, 29, 92, 7, 6, 1, 156, - 92, 7, 6, 1, 194, 92, 7, 6, 1, 230, 30, 92, 7, 6, 1, 78, 92, 7, 6, 1, - 226, 109, 92, 7, 6, 1, 224, 99, 92, 7, 6, 1, 153, 92, 7, 6, 1, 222, 93, - 92, 7, 6, 1, 217, 153, 92, 7, 6, 1, 69, 92, 7, 6, 1, 214, 105, 92, 7, 6, - 1, 212, 98, 92, 7, 6, 1, 211, 178, 92, 7, 6, 1, 211, 117, 92, 7, 6, 1, - 210, 159, 92, 240, 208, 92, 230, 54, 92, 221, 185, 92, 218, 228, 92, 224, - 221, 92, 212, 23, 152, 37, 7, 6, 1, 61, 152, 37, 7, 6, 1, 253, 166, 152, - 37, 7, 6, 1, 251, 74, 152, 37, 7, 6, 1, 249, 68, 152, 37, 7, 6, 1, 76, - 152, 37, 7, 6, 1, 245, 14, 152, 37, 7, 6, 1, 243, 209, 152, 37, 7, 6, 1, - 242, 67, 152, 37, 7, 6, 1, 74, 152, 37, 7, 6, 1, 235, 150, 152, 37, 7, 6, - 1, 235, 29, 152, 37, 7, 6, 1, 156, 152, 37, 7, 6, 1, 194, 152, 37, 7, 6, - 1, 230, 30, 152, 37, 7, 6, 1, 78, 152, 37, 7, 6, 1, 226, 109, 152, 37, 7, - 6, 1, 224, 99, 152, 37, 7, 6, 1, 153, 152, 37, 7, 6, 1, 222, 93, 152, 37, - 7, 6, 1, 217, 153, 152, 37, 7, 6, 1, 69, 152, 37, 7, 6, 1, 214, 105, 152, - 37, 7, 6, 1, 212, 98, 152, 37, 7, 6, 1, 211, 178, 152, 37, 7, 6, 1, 211, - 117, 152, 37, 7, 6, 1, 210, 159, 223, 160, 231, 102, 50, 223, 160, 231, - 99, 50, 152, 92, 7, 6, 1, 61, 152, 92, 7, 6, 1, 253, 166, 152, 92, 7, 6, - 1, 251, 74, 152, 92, 7, 6, 1, 249, 68, 152, 92, 7, 6, 1, 76, 152, 92, 7, - 6, 1, 245, 14, 152, 92, 7, 6, 1, 243, 209, 152, 92, 7, 6, 1, 242, 67, - 152, 92, 7, 6, 1, 74, 152, 92, 7, 6, 1, 235, 150, 152, 92, 7, 6, 1, 235, - 29, 152, 92, 7, 6, 1, 156, 152, 92, 7, 6, 1, 194, 152, 92, 7, 6, 1, 230, - 30, 152, 92, 7, 6, 1, 78, 152, 92, 7, 6, 1, 226, 109, 152, 92, 7, 6, 1, - 224, 99, 152, 92, 7, 6, 1, 153, 152, 92, 7, 6, 1, 222, 93, 152, 92, 7, 6, - 1, 217, 153, 152, 92, 7, 6, 1, 69, 152, 92, 7, 6, 1, 214, 105, 152, 92, - 7, 6, 1, 212, 98, 152, 92, 7, 6, 1, 211, 178, 152, 92, 7, 6, 1, 211, 117, - 152, 92, 7, 6, 1, 210, 159, 249, 136, 152, 92, 7, 6, 1, 226, 109, 152, - 92, 240, 120, 152, 92, 191, 152, 92, 206, 152, 92, 255, 34, 152, 92, 212, - 23, 42, 247, 172, 92, 250, 31, 92, 249, 178, 92, 244, 4, 92, 240, 112, - 92, 229, 91, 92, 229, 84, 92, 226, 218, 92, 219, 37, 92, 120, 2, 245, 39, - 79, 92, 213, 119, 223, 106, 235, 246, 16, 1, 61, 223, 106, 235, 246, 16, - 1, 253, 166, 223, 106, 235, 246, 16, 1, 251, 74, 223, 106, 235, 246, 16, - 1, 249, 68, 223, 106, 235, 246, 16, 1, 76, 223, 106, 235, 246, 16, 1, - 245, 14, 223, 106, 235, 246, 16, 1, 243, 209, 223, 106, 235, 246, 16, 1, - 242, 67, 223, 106, 235, 246, 16, 1, 74, 223, 106, 235, 246, 16, 1, 235, - 150, 223, 106, 235, 246, 16, 1, 235, 29, 223, 106, 235, 246, 16, 1, 156, - 223, 106, 235, 246, 16, 1, 194, 223, 106, 235, 246, 16, 1, 230, 30, 223, - 106, 235, 246, 16, 1, 78, 223, 106, 235, 246, 16, 1, 226, 109, 223, 106, - 235, 246, 16, 1, 224, 99, 223, 106, 235, 246, 16, 1, 153, 223, 106, 235, - 246, 16, 1, 222, 93, 223, 106, 235, 246, 16, 1, 217, 153, 223, 106, 235, - 246, 16, 1, 69, 223, 106, 235, 246, 16, 1, 214, 105, 223, 106, 235, 246, - 16, 1, 212, 98, 223, 106, 235, 246, 16, 1, 211, 178, 223, 106, 235, 246, - 16, 1, 211, 117, 223, 106, 235, 246, 16, 1, 210, 159, 42, 141, 241, 70, - 92, 56, 234, 24, 92, 56, 206, 92, 10, 214, 177, 238, 57, 92, 10, 214, - 177, 238, 61, 92, 10, 214, 177, 238, 69, 92, 56, 248, 98, 92, 10, 214, - 177, 238, 76, 92, 10, 214, 177, 238, 63, 92, 10, 214, 177, 238, 35, 92, - 10, 214, 177, 238, 62, 92, 10, 214, 177, 238, 75, 92, 10, 214, 177, 238, - 49, 92, 10, 214, 177, 238, 42, 92, 10, 214, 177, 238, 51, 92, 10, 214, - 177, 238, 72, 92, 10, 214, 177, 238, 58, 92, 10, 214, 177, 238, 74, 92, - 10, 214, 177, 238, 50, 92, 10, 214, 177, 238, 73, 92, 10, 214, 177, 238, - 36, 92, 10, 214, 177, 238, 41, 92, 10, 214, 177, 238, 34, 92, 10, 214, - 177, 238, 64, 92, 10, 214, 177, 238, 66, 92, 10, 214, 177, 238, 44, 92, - 10, 214, 177, 238, 55, 92, 10, 214, 177, 238, 53, 92, 10, 214, 177, 238, - 79, 92, 10, 214, 177, 238, 78, 92, 10, 214, 177, 238, 32, 92, 10, 214, - 177, 238, 59, 92, 10, 214, 177, 238, 77, 92, 10, 214, 177, 238, 68, 92, - 10, 214, 177, 238, 54, 92, 10, 214, 177, 238, 33, 92, 10, 214, 177, 238, - 56, 92, 10, 214, 177, 238, 38, 92, 10, 214, 177, 238, 37, 92, 10, 214, - 177, 238, 67, 92, 10, 214, 177, 238, 45, 92, 10, 214, 177, 238, 47, 92, - 10, 214, 177, 238, 48, 92, 10, 214, 177, 238, 40, 92, 10, 214, 177, 238, - 71, 92, 10, 214, 177, 238, 65, 216, 7, 220, 55, 251, 165, 10, 214, 177, - 238, 46, 216, 7, 220, 55, 251, 165, 10, 214, 177, 238, 78, 216, 7, 220, - 55, 251, 165, 10, 214, 177, 238, 76, 216, 7, 220, 55, 251, 165, 10, 214, - 177, 238, 60, 216, 7, 220, 55, 251, 165, 10, 214, 177, 238, 43, 216, 7, - 220, 55, 251, 165, 10, 214, 177, 238, 56, 216, 7, 220, 55, 251, 165, 10, - 214, 177, 238, 39, 216, 7, 220, 55, 251, 165, 10, 214, 177, 238, 70, 216, - 7, 220, 55, 251, 165, 10, 214, 177, 238, 52, 37, 154, 254, 254, 37, 154, - 255, 21, 249, 79, 244, 50, 250, 8, 214, 194, 228, 218, 2, 218, 155, 218, - 34, 115, 230, 119, 218, 33, 250, 34, 253, 215, 246, 62, 218, 32, 115, - 251, 126, 223, 161, 251, 148, 253, 215, 228, 217, 212, 41, 212, 35, 213, - 131, 230, 200, 212, 25, 245, 232, 242, 188, 245, 53, 245, 232, 242, 188, - 254, 136, 245, 232, 242, 188, 253, 233, 242, 188, 2, 231, 56, 166, 230, - 134, 87, 212, 27, 249, 145, 230, 134, 87, 244, 100, 224, 25, 230, 134, - 87, 212, 27, 242, 217, 230, 134, 87, 243, 236, 230, 134, 87, 212, 52, - 242, 217, 230, 134, 87, 233, 86, 224, 25, 230, 134, 87, 212, 52, 249, - 145, 230, 134, 87, 249, 145, 230, 133, 166, 230, 134, 2, 244, 198, 244, - 100, 224, 25, 230, 134, 2, 244, 198, 233, 86, 224, 25, 230, 134, 2, 244, - 198, 243, 236, 230, 134, 2, 244, 198, 218, 39, 2, 244, 198, 242, 186, - 218, 158, 220, 1, 218, 158, 250, 124, 221, 170, 245, 47, 215, 236, 248, - 92, 215, 236, 226, 63, 215, 236, 251, 35, 215, 110, 250, 126, 251, 218, - 222, 193, 241, 186, 218, 37, 251, 218, 245, 236, 64, 231, 199, 245, 236, - 64, 223, 34, 241, 211, 244, 19, 233, 60, 249, 254, 231, 175, 233, 59, - 244, 184, 233, 59, 233, 60, 244, 55, 236, 7, 211, 239, 230, 63, 216, 35, - 253, 199, 242, 150, 231, 72, 212, 39, 217, 58, 233, 32, 252, 157, 225, - 65, 223, 114, 254, 62, 242, 134, 254, 62, 225, 220, 225, 221, 250, 127, - 218, 116, 242, 30, 219, 92, 64, 225, 47, 231, 92, 226, 201, 251, 202, - 224, 232, 233, 42, 223, 35, 249, 150, 223, 35, 252, 167, 249, 181, 223, - 34, 249, 103, 22, 223, 34, 218, 143, 251, 175, 219, 16, 251, 159, 244, 3, - 243, 255, 222, 209, 217, 247, 224, 234, 248, 183, 226, 240, 218, 8, 244, - 0, 219, 232, 244, 99, 251, 29, 2, 217, 240, 248, 43, 219, 54, 240, 119, - 249, 149, 220, 72, 240, 118, 240, 119, 249, 149, 246, 116, 249, 180, 250, - 92, 130, 251, 6, 232, 147, 249, 96, 241, 62, 224, 236, 219, 242, 252, 44, - 251, 171, 224, 237, 64, 244, 41, 249, 179, 244, 32, 22, 234, 38, 217, 20, - 211, 230, 242, 20, 222, 14, 251, 185, 22, 249, 110, 211, 237, 242, 191, - 249, 243, 242, 191, 215, 194, 246, 98, 252, 70, 230, 98, 250, 15, 252, - 70, 230, 97, 252, 195, 251, 184, 223, 36, 211, 201, 224, 198, 251, 243, - 251, 28, 235, 144, 250, 85, 215, 236, 244, 170, 250, 84, 244, 102, 244, - 103, 219, 14, 252, 166, 225, 254, 224, 247, 249, 212, 252, 167, 217, 60, - 215, 236, 249, 136, 244, 75, 225, 66, 248, 89, 235, 137, 247, 139, 250, - 240, 218, 115, 211, 240, 250, 106, 230, 134, 213, 164, 250, 170, 221, - 201, 221, 226, 242, 155, 251, 3, 250, 241, 240, 252, 244, 138, 212, 0, - 222, 202, 249, 244, 244, 94, 225, 5, 22, 244, 98, 230, 232, 230, 113, - 251, 18, 250, 47, 241, 239, 253, 249, 226, 66, 216, 15, 242, 2, 250, 37, - 216, 243, 216, 114, 250, 28, 251, 210, 225, 180, 253, 248, 213, 172, 243, - 117, 247, 205, 241, 163, 219, 86, 231, 239, 251, 253, 243, 118, 247, 248, - 251, 174, 244, 60, 225, 36, 250, 249, 28, 228, 52, 230, 90, 28, 228, 47, - 221, 214, 242, 106, 28, 234, 143, 215, 191, 213, 154, 28, 221, 194, 222, - 126, 220, 13, 2, 221, 229, 216, 245, 223, 181, 22, 252, 167, 219, 107, - 22, 219, 107, 251, 195, 252, 131, 22, 241, 56, 250, 128, 244, 81, 219, - 65, 222, 127, 218, 13, 215, 195, 240, 253, 223, 182, 254, 137, 244, 39, - 222, 138, 244, 39, 217, 242, 240, 242, 251, 127, 240, 242, 2, 243, 101, - 226, 233, 251, 127, 235, 137, 224, 242, 226, 232, 245, 52, 224, 242, 226, - 232, 240, 251, 252, 153, 253, 189, 216, 253, 231, 239, 240, 247, 232, - 117, 240, 247, 249, 184, 218, 127, 221, 200, 248, 51, 218, 127, 244, 188, - 235, 155, 233, 95, 235, 137, 250, 234, 245, 52, 250, 234, 223, 144, 230, - 117, 226, 118, 212, 41, 251, 131, 249, 153, 216, 107, 233, 24, 223, 183, - 250, 232, 246, 104, 249, 143, 212, 3, 219, 72, 219, 70, 240, 252, 223, - 156, 242, 177, 220, 59, 230, 150, 222, 196, 250, 116, 247, 144, 225, 76, - 251, 211, 245, 177, 226, 242, 218, 254, 220, 54, 251, 130, 254, 100, 241, - 61, 233, 127, 252, 68, 244, 98, 215, 194, 244, 98, 251, 217, 215, 91, - 242, 0, 250, 117, 252, 195, 250, 117, 243, 250, 252, 195, 250, 117, 251, - 245, 225, 198, 234, 32, 224, 251, 246, 95, 251, 19, 252, 185, 251, 19, - 247, 138, 230, 118, 244, 198, 249, 154, 244, 198, 216, 108, 244, 198, - 223, 184, 244, 198, 250, 233, 244, 198, 246, 105, 244, 198, 218, 243, - 212, 3, 240, 253, 244, 198, 230, 151, 244, 198, 247, 145, 244, 198, 225, - 77, 244, 198, 243, 253, 244, 198, 242, 27, 244, 198, 211, 224, 244, 198, - 252, 79, 244, 198, 226, 49, 244, 198, 225, 77, 228, 58, 225, 236, 224, - 189, 245, 21, 245, 235, 228, 58, 230, 115, 216, 20, 71, 120, 225, 10, - 252, 190, 235, 249, 71, 124, 225, 10, 252, 190, 235, 249, 71, 43, 225, - 10, 252, 190, 235, 249, 71, 44, 225, 10, 252, 190, 235, 249, 244, 92, - 242, 23, 50, 212, 33, 242, 23, 50, 226, 219, 242, 23, 50, 216, 136, 120, - 50, 216, 136, 124, 50, 250, 27, 242, 18, 50, 204, 242, 18, 50, 249, 131, - 211, 220, 242, 2, 245, 22, 229, 109, 217, 152, 235, 131, 246, 100, 234, - 88, 251, 255, 211, 220, 250, 1, 224, 130, 242, 21, 224, 233, 231, 182, - 220, 6, 253, 211, 220, 6, 241, 171, 220, 6, 211, 220, 221, 242, 211, 220, - 251, 194, 244, 37, 251, 98, 236, 7, 219, 171, 251, 97, 236, 7, 219, 171, - 251, 170, 242, 201, 231, 190, 211, 221, 244, 182, 231, 191, 22, 211, 222, - 241, 67, 242, 17, 113, 231, 64, 241, 67, 242, 17, 113, 211, 219, 241, 67, - 242, 17, 225, 2, 226, 231, 211, 222, 2, 251, 114, 245, 233, 251, 149, 2, - 213, 246, 225, 171, 2, 251, 220, 242, 41, 231, 191, 2, 242, 117, 225, - 112, 231, 179, 231, 191, 2, 215, 98, 226, 212, 231, 190, 226, 212, 211, - 221, 252, 194, 249, 198, 211, 205, 224, 192, 235, 137, 226, 227, 235, - 137, 242, 176, 242, 229, 252, 195, 254, 121, 245, 26, 254, 169, 254, 170, - 230, 141, 236, 12, 219, 102, 235, 239, 248, 42, 225, 170, 242, 112, 248, - 187, 232, 207, 229, 216, 225, 1, 244, 199, 231, 147, 242, 40, 252, 146, - 225, 4, 217, 172, 225, 69, 234, 70, 79, 232, 117, 233, 16, 222, 236, 243, - 61, 218, 133, 234, 69, 251, 179, 249, 156, 2, 241, 234, 212, 19, 252, 77, - 241, 234, 251, 143, 241, 234, 113, 241, 232, 219, 12, 241, 234, 242, 127, - 241, 234, 241, 235, 2, 75, 251, 216, 241, 234, 242, 134, 241, 234, 211, - 42, 241, 234, 224, 131, 241, 234, 241, 235, 2, 223, 36, 223, 47, 241, - 232, 241, 235, 248, 89, 248, 1, 220, 84, 2, 116, 59, 235, 222, 245, 180, - 193, 251, 124, 254, 120, 87, 251, 203, 219, 94, 87, 249, 236, 87, 218, - 248, 217, 249, 87, 246, 93, 248, 165, 87, 225, 70, 64, 224, 252, 244, 69, - 252, 11, 247, 173, 87, 219, 5, 252, 166, 216, 150, 252, 166, 71, 244, 59, - 240, 218, 225, 8, 87, 230, 154, 252, 180, 249, 106, 245, 40, 114, 247, - 140, 50, 249, 147, 250, 250, 252, 152, 2, 211, 40, 50, 252, 152, 2, 247, - 140, 50, 252, 152, 2, 245, 55, 50, 252, 152, 2, 224, 231, 50, 230, 154, - 2, 211, 235, 250, 146, 2, 214, 153, 215, 232, 22, 211, 40, 50, 221, 180, - 225, 169, 249, 216, 251, 147, 230, 191, 244, 64, 247, 193, 226, 165, 247, - 198, 246, 57, 244, 115, 244, 48, 204, 244, 115, 244, 48, 226, 80, 2, 249, - 108, 226, 80, 244, 191, 214, 163, 251, 24, 217, 19, 251, 24, 250, 251, - 235, 249, 250, 146, 2, 214, 153, 215, 231, 250, 146, 2, 246, 112, 215, - 231, 252, 149, 250, 145, 250, 14, 224, 126, 222, 187, 224, 126, 226, 23, - 218, 123, 222, 133, 215, 223, 222, 133, 251, 199, 217, 92, 233, 57, 228, - 50, 228, 51, 2, 248, 88, 249, 155, 250, 8, 251, 200, 204, 251, 200, 242, - 134, 251, 200, 251, 216, 251, 200, 226, 161, 251, 200, 251, 197, 229, - 210, 252, 183, 221, 188, 231, 65, 217, 2, 223, 126, 226, 78, 244, 167, - 231, 239, 221, 225, 254, 97, 224, 148, 255, 5, 232, 119, 250, 135, 231, - 77, 226, 133, 215, 239, 236, 3, 215, 239, 226, 86, 246, 32, 87, 236, 0, - 245, 127, 245, 128, 2, 246, 112, 80, 48, 250, 8, 231, 205, 2, 232, 113, - 244, 81, 250, 8, 231, 205, 2, 223, 160, 244, 81, 204, 231, 205, 2, 223, - 160, 244, 81, 204, 231, 205, 2, 232, 113, 244, 81, 224, 239, 224, 240, - 240, 255, 229, 89, 230, 164, 225, 120, 230, 164, 225, 121, 2, 97, 80, - 253, 215, 233, 52, 213, 175, 230, 163, 230, 164, 225, 121, 226, 234, 228, - 80, 230, 164, 225, 119, 254, 98, 2, 252, 137, 251, 18, 213, 172, 251, 18, - 216, 255, 223, 176, 213, 171, 215, 60, 97, 253, 255, 250, 10, 97, 22, - 140, 204, 250, 44, 253, 255, 250, 10, 97, 22, 140, 204, 250, 44, 254, 0, - 2, 37, 123, 226, 124, 250, 10, 246, 112, 22, 214, 153, 204, 250, 44, 253, - 255, 254, 96, 246, 112, 22, 214, 153, 204, 250, 44, 253, 255, 121, 251, - 146, 87, 125, 251, 146, 87, 219, 9, 2, 251, 12, 91, 219, 8, 219, 9, 2, - 123, 219, 33, 212, 35, 219, 9, 2, 134, 219, 33, 212, 34, 252, 123, 245, - 180, 225, 30, 233, 48, 231, 216, 242, 191, 222, 250, 231, 216, 242, 191, - 232, 158, 2, 235, 232, 225, 202, 250, 8, 232, 158, 2, 234, 144, 234, 144, - 232, 157, 204, 232, 157, 252, 52, 252, 53, 2, 251, 12, 91, 251, 198, 232, - 210, 87, 223, 177, 251, 94, 252, 193, 2, 140, 80, 48, 245, 151, 2, 140, - 80, 48, 226, 201, 2, 245, 39, 164, 2, 43, 44, 80, 48, 219, 41, 2, 97, 80, - 48, 216, 15, 2, 214, 153, 80, 48, 228, 80, 123, 214, 184, 245, 199, 87, - 234, 142, 216, 248, 235, 226, 16, 31, 7, 6, 233, 15, 235, 226, 16, 31, 7, - 4, 233, 15, 235, 226, 16, 31, 227, 203, 235, 226, 16, 31, 217, 184, 235, - 226, 16, 31, 7, 233, 15, 244, 104, 245, 180, 216, 10, 211, 199, 242, 28, - 227, 186, 22, 251, 205, 241, 73, 225, 53, 230, 231, 217, 0, 249, 122, - 252, 167, 219, 127, 225, 12, 218, 159, 2, 230, 229, 247, 128, 235, 137, - 16, 31, 252, 65, 215, 221, 245, 164, 85, 42, 251, 94, 71, 42, 251, 94, - 233, 91, 223, 114, 250, 43, 233, 91, 251, 216, 250, 43, 233, 91, 226, - 161, 248, 0, 233, 91, 251, 216, 248, 0, 4, 226, 161, 248, 0, 4, 251, 216, - 248, 0, 214, 162, 223, 114, 215, 226, 246, 113, 223, 114, 215, 226, 214, - 162, 4, 223, 114, 215, 226, 246, 113, 4, 223, 114, 215, 226, 37, 249, - 139, 224, 255, 249, 139, 225, 0, 2, 242, 33, 51, 249, 139, 224, 255, 228, - 54, 43, 220, 155, 2, 134, 247, 126, 250, 12, 244, 199, 123, 226, 246, - 250, 12, 244, 199, 113, 226, 246, 250, 12, 244, 199, 134, 226, 246, 250, - 12, 244, 199, 244, 19, 226, 246, 250, 12, 244, 199, 244, 89, 226, 246, - 250, 12, 244, 199, 219, 127, 226, 246, 250, 12, 244, 199, 220, 124, 226, - 246, 250, 12, 244, 199, 245, 201, 226, 246, 250, 12, 244, 199, 228, 205, - 226, 246, 250, 12, 244, 199, 216, 249, 226, 246, 250, 12, 244, 199, 245, - 176, 226, 246, 250, 12, 244, 199, 215, 77, 226, 246, 250, 12, 244, 199, - 226, 196, 250, 12, 244, 199, 215, 56, 250, 12, 244, 199, 216, 141, 250, - 12, 244, 199, 244, 15, 250, 12, 244, 199, 244, 87, 250, 12, 244, 199, - 219, 123, 250, 12, 244, 199, 220, 123, 250, 12, 244, 199, 245, 200, 250, - 12, 244, 199, 228, 204, 250, 12, 244, 199, 216, 247, 250, 12, 244, 199, - 245, 174, 250, 12, 244, 199, 215, 75, 230, 122, 243, 237, 216, 37, 216, - 3, 218, 150, 64, 232, 245, 219, 172, 64, 235, 138, 230, 111, 242, 131, - 244, 198, 242, 131, 244, 199, 2, 219, 76, 245, 21, 244, 199, 2, 217, 15, - 64, 235, 59, 219, 76, 244, 199, 2, 204, 230, 115, 219, 76, 244, 199, 2, - 204, 230, 116, 22, 219, 76, 245, 21, 219, 76, 244, 199, 2, 204, 230, 116, - 22, 249, 238, 217, 248, 219, 76, 244, 199, 2, 204, 230, 116, 22, 216, - 105, 245, 21, 219, 76, 244, 199, 2, 242, 32, 219, 76, 244, 199, 2, 240, - 254, 211, 233, 244, 198, 219, 76, 244, 199, 2, 219, 76, 245, 21, 244, - 199, 221, 219, 248, 70, 244, 41, 223, 91, 244, 198, 219, 76, 244, 199, 2, - 241, 233, 245, 21, 219, 76, 244, 199, 2, 218, 35, 219, 75, 244, 198, 229, - 92, 244, 198, 245, 31, 244, 198, 214, 188, 244, 198, 244, 199, 2, 249, - 238, 217, 248, 225, 195, 244, 198, 249, 209, 244, 198, 249, 210, 244, - 198, 234, 68, 244, 198, 244, 199, 216, 138, 116, 234, 69, 234, 68, 244, - 199, 2, 219, 76, 245, 21, 234, 68, 244, 199, 2, 250, 8, 245, 21, 244, - 199, 2, 218, 89, 216, 20, 244, 199, 2, 218, 89, 216, 21, 22, 211, 233, - 245, 23, 244, 199, 2, 218, 89, 216, 21, 22, 216, 105, 245, 21, 247, 200, - 244, 198, 211, 204, 244, 198, 254, 116, 244, 198, 224, 230, 244, 198, - 249, 124, 244, 198, 225, 173, 244, 198, 244, 199, 2, 232, 132, 64, 215, - 205, 247, 200, 251, 96, 223, 91, 244, 198, 243, 247, 244, 199, 2, 204, - 230, 115, 254, 114, 244, 198, 244, 160, 244, 198, 212, 20, 244, 198, 219, - 93, 244, 198, 216, 72, 244, 198, 242, 132, 244, 198, 232, 120, 249, 124, - 244, 198, 244, 199, 2, 204, 230, 115, 240, 210, 244, 198, 244, 199, 2, - 204, 230, 116, 22, 249, 238, 217, 248, 244, 199, 221, 192, 236, 7, 244, - 161, 253, 221, 244, 198, 244, 57, 244, 198, 219, 94, 244, 198, 247, 173, - 244, 198, 244, 199, 211, 230, 230, 115, 244, 199, 2, 231, 89, 231, 149, - 242, 131, 250, 233, 244, 199, 2, 219, 76, 245, 21, 250, 233, 244, 199, 2, - 217, 15, 64, 235, 59, 219, 76, 250, 233, 244, 199, 2, 204, 230, 115, 219, - 76, 250, 233, 244, 199, 2, 241, 233, 245, 21, 250, 233, 244, 199, 2, 211, - 196, 219, 77, 234, 68, 250, 233, 244, 199, 2, 250, 8, 245, 21, 224, 230, - 250, 233, 244, 198, 249, 124, 250, 233, 244, 198, 212, 20, 250, 233, 244, - 198, 244, 199, 2, 228, 80, 242, 170, 243, 41, 244, 199, 2, 226, 219, 243, - 41, 225, 171, 251, 176, 248, 83, 221, 171, 230, 150, 241, 236, 230, 150, - 219, 10, 230, 150, 242, 12, 225, 171, 223, 159, 123, 242, 22, 225, 171, - 223, 159, 251, 186, 242, 18, 236, 7, 250, 187, 225, 171, 243, 246, 225, - 171, 2, 224, 230, 244, 198, 225, 171, 2, 244, 49, 242, 17, 222, 205, 241, - 221, 218, 145, 232, 155, 223, 165, 250, 252, 241, 169, 215, 249, 241, - 169, 215, 250, 2, 251, 122, 228, 58, 215, 249, 231, 37, 193, 223, 166, - 218, 151, 215, 247, 215, 248, 250, 252, 251, 100, 226, 198, 251, 100, - 215, 202, 251, 101, 218, 131, 230, 192, 254, 138, 244, 105, 245, 145, - 225, 2, 250, 252, 226, 198, 225, 2, 250, 252, 217, 33, 226, 198, 217, 33, - 253, 188, 226, 198, 253, 188, 223, 121, 213, 247, 248, 66, 215, 193, 253, - 250, 232, 123, 215, 255, 230, 144, 230, 121, 223, 164, 218, 7, 223, 164, - 230, 121, 251, 36, 254, 238, 215, 246, 220, 18, 222, 184, 219, 3, 203, - 215, 253, 232, 236, 67, 215, 253, 232, 236, 249, 198, 50, 225, 2, 250, - 237, 223, 47, 232, 236, 215, 223, 244, 82, 226, 201, 224, 241, 247, 131, - 228, 80, 245, 133, 50, 219, 74, 87, 228, 80, 219, 74, 87, 224, 125, 232, - 199, 236, 7, 235, 163, 225, 44, 87, 247, 154, 228, 57, 232, 199, 87, 224, - 235, 212, 41, 87, 228, 71, 212, 41, 87, 252, 10, 228, 80, 252, 9, 252, 8, - 230, 121, 252, 8, 225, 216, 228, 80, 225, 215, 250, 108, 249, 132, 231, - 61, 87, 211, 218, 87, 223, 62, 252, 195, 87, 216, 38, 212, 41, 250, 5, - 219, 236, 252, 126, 252, 124, 225, 246, 249, 185, 249, 94, 252, 177, 250, - 30, 43, 232, 95, 108, 16, 31, 224, 6, 108, 16, 31, 254, 201, 108, 16, 31, - 244, 104, 108, 16, 31, 245, 231, 108, 16, 31, 212, 40, 108, 16, 31, 254, - 51, 108, 16, 31, 254, 52, 223, 108, 108, 16, 31, 254, 52, 223, 107, 108, - 16, 31, 254, 52, 213, 143, 108, 16, 31, 254, 52, 213, 142, 108, 16, 31, - 213, 157, 108, 16, 31, 213, 156, 108, 16, 31, 213, 155, 108, 16, 31, 218, - 45, 108, 16, 31, 225, 128, 218, 45, 108, 16, 31, 85, 218, 45, 108, 16, - 31, 231, 60, 218, 72, 108, 16, 31, 231, 60, 218, 71, 108, 16, 31, 231, - 60, 218, 70, 108, 16, 31, 250, 46, 108, 16, 31, 222, 3, 108, 16, 31, 228, - 193, 108, 16, 31, 213, 141, 108, 16, 31, 213, 140, 108, 16, 31, 222, 206, - 222, 3, 108, 16, 31, 222, 206, 222, 2, 108, 16, 31, 242, 173, 108, 16, - 31, 219, 168, 108, 16, 31, 235, 184, 226, 157, 108, 16, 31, 235, 184, - 226, 156, 108, 16, 31, 249, 142, 64, 235, 183, 108, 16, 31, 223, 104, 64, - 235, 183, 108, 16, 31, 249, 176, 226, 157, 108, 16, 31, 235, 182, 226, - 157, 108, 16, 31, 218, 73, 64, 249, 175, 108, 16, 31, 249, 142, 64, 249, - 175, 108, 16, 31, 249, 142, 64, 249, 174, 108, 16, 31, 249, 176, 254, 91, - 108, 16, 31, 222, 4, 64, 249, 176, 254, 91, 108, 16, 31, 218, 73, 64, - 222, 4, 64, 249, 175, 108, 16, 31, 213, 243, 108, 16, 31, 216, 85, 226, - 157, 108, 16, 31, 233, 63, 226, 157, 108, 16, 31, 254, 90, 226, 157, 108, - 16, 31, 218, 73, 64, 254, 89, 108, 16, 31, 222, 4, 64, 254, 89, 108, 16, - 31, 218, 73, 64, 222, 4, 64, 254, 89, 108, 16, 31, 213, 158, 64, 254, 89, - 108, 16, 31, 223, 104, 64, 254, 89, 108, 16, 31, 223, 104, 64, 254, 88, - 108, 16, 31, 223, 103, 108, 16, 31, 223, 102, 108, 16, 31, 223, 101, 108, - 16, 31, 223, 100, 108, 16, 31, 254, 166, 108, 16, 31, 254, 165, 108, 16, - 31, 231, 168, 108, 16, 31, 222, 9, 108, 16, 31, 253, 254, 108, 16, 31, - 223, 128, 108, 16, 31, 223, 127, 108, 16, 31, 253, 191, 108, 16, 31, 251, - 237, 226, 157, 108, 16, 31, 217, 50, 108, 16, 31, 217, 49, 108, 16, 31, - 224, 11, 232, 228, 108, 16, 31, 251, 191, 108, 16, 31, 251, 190, 108, 16, - 31, 251, 189, 108, 16, 31, 254, 146, 108, 16, 31, 226, 222, 108, 16, 31, - 218, 250, 108, 16, 31, 216, 83, 108, 16, 31, 242, 103, 108, 16, 31, 212, - 28, 108, 16, 31, 224, 229, 108, 16, 31, 251, 22, 108, 16, 31, 215, 86, - 108, 16, 31, 250, 254, 230, 127, 108, 16, 31, 221, 204, 64, 235, 61, 108, - 16, 31, 251, 33, 108, 16, 31, 215, 220, 108, 16, 31, 218, 156, 215, 220, - 108, 16, 31, 232, 154, 108, 16, 31, 219, 58, 108, 16, 31, 214, 142, 108, - 16, 31, 240, 253, 246, 72, 108, 16, 31, 253, 235, 108, 16, 31, 224, 237, - 253, 235, 108, 16, 31, 251, 150, 108, 16, 31, 224, 228, 251, 150, 108, - 16, 31, 254, 143, 108, 16, 31, 218, 119, 218, 27, 218, 118, 108, 16, 31, - 218, 119, 218, 27, 218, 117, 108, 16, 31, 218, 69, 108, 16, 31, 224, 203, - 108, 16, 31, 247, 189, 108, 16, 31, 247, 191, 108, 16, 31, 247, 190, 108, - 16, 31, 224, 134, 108, 16, 31, 224, 123, 108, 16, 31, 249, 130, 108, 16, - 31, 249, 129, 108, 16, 31, 249, 128, 108, 16, 31, 249, 127, 108, 16, 31, - 249, 126, 108, 16, 31, 254, 178, 108, 16, 31, 252, 127, 64, 231, 154, - 108, 16, 31, 252, 127, 64, 214, 17, 108, 16, 31, 223, 60, 108, 16, 31, - 240, 245, 108, 16, 31, 228, 217, 108, 16, 31, 248, 153, 108, 16, 31, 230, - 139, 108, 16, 31, 163, 246, 102, 108, 16, 31, 163, 226, 136, 10, 14, 240, - 109, 10, 14, 240, 108, 10, 14, 240, 107, 10, 14, 240, 106, 10, 14, 240, - 105, 10, 14, 240, 104, 10, 14, 240, 103, 10, 14, 240, 102, 10, 14, 240, - 101, 10, 14, 240, 100, 10, 14, 240, 99, 10, 14, 240, 98, 10, 14, 240, 97, - 10, 14, 240, 96, 10, 14, 240, 95, 10, 14, 240, 94, 10, 14, 240, 93, 10, - 14, 240, 92, 10, 14, 240, 91, 10, 14, 240, 90, 10, 14, 240, 89, 10, 14, - 240, 88, 10, 14, 240, 87, 10, 14, 240, 86, 10, 14, 240, 85, 10, 14, 240, - 84, 10, 14, 240, 83, 10, 14, 240, 82, 10, 14, 240, 81, 10, 14, 240, 80, - 10, 14, 240, 79, 10, 14, 240, 78, 10, 14, 240, 77, 10, 14, 240, 76, 10, - 14, 240, 75, 10, 14, 240, 74, 10, 14, 240, 73, 10, 14, 240, 72, 10, 14, - 240, 71, 10, 14, 240, 70, 10, 14, 240, 69, 10, 14, 240, 68, 10, 14, 240, - 67, 10, 14, 240, 66, 10, 14, 240, 65, 10, 14, 240, 64, 10, 14, 240, 63, - 10, 14, 240, 62, 10, 14, 240, 61, 10, 14, 240, 60, 10, 14, 240, 59, 10, - 14, 240, 58, 10, 14, 240, 57, 10, 14, 240, 56, 10, 14, 240, 55, 10, 14, - 240, 54, 10, 14, 240, 53, 10, 14, 240, 52, 10, 14, 240, 51, 10, 14, 240, - 50, 10, 14, 240, 49, 10, 14, 240, 48, 10, 14, 240, 47, 10, 14, 240, 46, - 10, 14, 240, 45, 10, 14, 240, 44, 10, 14, 240, 43, 10, 14, 240, 42, 10, - 14, 240, 41, 10, 14, 240, 40, 10, 14, 240, 39, 10, 14, 240, 38, 10, 14, - 240, 37, 10, 14, 240, 36, 10, 14, 240, 35, 10, 14, 240, 34, 10, 14, 240, - 33, 10, 14, 240, 32, 10, 14, 240, 31, 10, 14, 240, 30, 10, 14, 240, 29, - 10, 14, 240, 28, 10, 14, 240, 27, 10, 14, 240, 26, 10, 14, 240, 25, 10, - 14, 240, 24, 10, 14, 240, 23, 10, 14, 240, 22, 10, 14, 240, 21, 10, 14, - 240, 20, 10, 14, 240, 19, 10, 14, 240, 18, 10, 14, 240, 17, 10, 14, 240, - 16, 10, 14, 240, 15, 10, 14, 240, 14, 10, 14, 240, 13, 10, 14, 240, 12, - 10, 14, 240, 11, 10, 14, 240, 10, 10, 14, 240, 9, 10, 14, 240, 8, 10, 14, - 240, 7, 10, 14, 240, 6, 10, 14, 240, 5, 10, 14, 240, 4, 10, 14, 240, 3, - 10, 14, 240, 2, 10, 14, 240, 1, 10, 14, 240, 0, 10, 14, 239, 255, 10, 14, - 239, 254, 10, 14, 239, 253, 10, 14, 239, 252, 10, 14, 239, 251, 10, 14, - 239, 250, 10, 14, 239, 249, 10, 14, 239, 248, 10, 14, 239, 247, 10, 14, - 239, 246, 10, 14, 239, 245, 10, 14, 239, 244, 10, 14, 239, 243, 10, 14, - 239, 242, 10, 14, 239, 241, 10, 14, 239, 240, 10, 14, 239, 239, 10, 14, - 239, 238, 10, 14, 239, 237, 10, 14, 239, 236, 10, 14, 239, 235, 10, 14, - 239, 234, 10, 14, 239, 233, 10, 14, 239, 232, 10, 14, 239, 231, 10, 14, - 239, 230, 10, 14, 239, 229, 10, 14, 239, 228, 10, 14, 239, 227, 10, 14, - 239, 226, 10, 14, 239, 225, 10, 14, 239, 224, 10, 14, 239, 223, 10, 14, - 239, 222, 10, 14, 239, 221, 10, 14, 239, 220, 10, 14, 239, 219, 10, 14, - 239, 218, 10, 14, 239, 217, 10, 14, 239, 216, 10, 14, 239, 215, 10, 14, - 239, 214, 10, 14, 239, 213, 10, 14, 239, 212, 10, 14, 239, 211, 10, 14, - 239, 210, 10, 14, 239, 209, 10, 14, 239, 208, 10, 14, 239, 207, 10, 14, - 239, 206, 10, 14, 239, 205, 10, 14, 239, 204, 10, 14, 239, 203, 10, 14, - 239, 202, 10, 14, 239, 201, 10, 14, 239, 200, 10, 14, 239, 199, 10, 14, - 239, 198, 10, 14, 239, 197, 10, 14, 239, 196, 10, 14, 239, 195, 10, 14, - 239, 194, 10, 14, 239, 193, 10, 14, 239, 192, 10, 14, 239, 191, 10, 14, - 239, 190, 10, 14, 239, 189, 10, 14, 239, 188, 10, 14, 239, 187, 10, 14, - 239, 186, 10, 14, 239, 185, 10, 14, 239, 184, 10, 14, 239, 183, 10, 14, - 239, 182, 10, 14, 239, 181, 10, 14, 239, 180, 10, 14, 239, 179, 10, 14, - 239, 178, 10, 14, 239, 177, 10, 14, 239, 176, 10, 14, 239, 175, 10, 14, - 239, 174, 10, 14, 239, 173, 10, 14, 239, 172, 10, 14, 239, 171, 10, 14, - 239, 170, 10, 14, 239, 169, 10, 14, 239, 168, 10, 14, 239, 167, 10, 14, - 239, 166, 10, 14, 239, 165, 10, 14, 239, 164, 10, 14, 239, 163, 10, 14, - 239, 162, 10, 14, 239, 161, 10, 14, 239, 160, 10, 14, 239, 159, 10, 14, - 239, 158, 10, 14, 239, 157, 10, 14, 239, 156, 10, 14, 239, 155, 10, 14, - 239, 154, 10, 14, 239, 153, 10, 14, 239, 152, 10, 14, 239, 151, 10, 14, - 239, 150, 10, 14, 239, 149, 10, 14, 239, 148, 10, 14, 239, 147, 10, 14, - 239, 146, 10, 14, 239, 145, 10, 14, 239, 144, 10, 14, 239, 143, 10, 14, - 239, 142, 10, 14, 239, 141, 10, 14, 239, 140, 10, 14, 239, 139, 10, 14, - 239, 138, 10, 14, 239, 137, 10, 14, 239, 136, 10, 14, 239, 135, 10, 14, - 239, 134, 10, 14, 239, 133, 10, 14, 239, 132, 10, 14, 239, 131, 10, 14, - 239, 130, 10, 14, 239, 129, 10, 14, 239, 128, 10, 14, 239, 127, 10, 14, - 239, 126, 10, 14, 239, 125, 10, 14, 239, 124, 10, 14, 239, 123, 10, 14, - 239, 122, 10, 14, 239, 121, 10, 14, 239, 120, 10, 14, 239, 119, 10, 14, - 239, 118, 10, 14, 239, 117, 10, 14, 239, 116, 10, 14, 239, 115, 10, 14, - 239, 114, 10, 14, 239, 113, 10, 14, 239, 112, 10, 14, 239, 111, 10, 14, - 239, 110, 10, 14, 239, 109, 10, 14, 239, 108, 10, 14, 239, 107, 10, 14, - 239, 106, 10, 14, 239, 105, 10, 14, 239, 104, 10, 14, 239, 103, 10, 14, - 239, 102, 10, 14, 239, 101, 10, 14, 239, 100, 10, 14, 239, 99, 10, 14, - 239, 98, 10, 14, 239, 97, 10, 14, 239, 96, 10, 14, 239, 95, 10, 14, 239, - 94, 10, 14, 239, 93, 10, 14, 239, 92, 10, 14, 239, 91, 10, 14, 239, 90, - 10, 14, 239, 89, 10, 14, 239, 88, 10, 14, 239, 87, 10, 14, 239, 86, 10, - 14, 239, 85, 10, 14, 239, 84, 10, 14, 239, 83, 10, 14, 239, 82, 10, 14, - 239, 81, 10, 14, 239, 80, 10, 14, 239, 79, 10, 14, 239, 78, 10, 14, 239, - 77, 10, 14, 239, 76, 10, 14, 239, 75, 10, 14, 239, 74, 10, 14, 239, 73, - 10, 14, 239, 72, 10, 14, 239, 71, 10, 14, 239, 70, 10, 14, 239, 69, 10, - 14, 239, 68, 10, 14, 239, 67, 10, 14, 239, 66, 10, 14, 239, 65, 10, 14, - 239, 64, 10, 14, 239, 63, 10, 14, 239, 62, 10, 14, 239, 61, 10, 14, 239, - 60, 10, 14, 239, 59, 10, 14, 239, 58, 10, 14, 239, 57, 10, 14, 239, 56, - 10, 14, 239, 55, 10, 14, 239, 54, 10, 14, 239, 53, 10, 14, 239, 52, 10, - 14, 239, 51, 10, 14, 239, 50, 10, 14, 239, 49, 10, 14, 239, 48, 10, 14, - 239, 47, 10, 14, 239, 46, 10, 14, 239, 45, 10, 14, 239, 44, 10, 14, 239, - 43, 10, 14, 239, 42, 10, 14, 239, 41, 10, 14, 239, 40, 10, 14, 239, 39, - 10, 14, 239, 38, 10, 14, 239, 37, 10, 14, 239, 36, 10, 14, 239, 35, 10, - 14, 239, 34, 10, 14, 239, 33, 10, 14, 239, 32, 10, 14, 239, 31, 10, 14, - 239, 30, 10, 14, 239, 29, 10, 14, 239, 28, 10, 14, 239, 27, 10, 14, 239, - 26, 10, 14, 239, 25, 10, 14, 239, 24, 10, 14, 239, 23, 10, 14, 239, 22, - 10, 14, 239, 21, 10, 14, 239, 20, 10, 14, 239, 19, 10, 14, 239, 18, 10, - 14, 239, 17, 10, 14, 239, 16, 10, 14, 239, 15, 10, 14, 239, 14, 10, 14, - 239, 13, 10, 14, 239, 12, 10, 14, 239, 11, 10, 14, 239, 10, 10, 14, 239, - 9, 10, 14, 239, 8, 10, 14, 239, 7, 10, 14, 239, 6, 10, 14, 239, 5, 10, - 14, 239, 4, 10, 14, 239, 3, 10, 14, 239, 2, 10, 14, 239, 1, 10, 14, 239, - 0, 10, 14, 238, 255, 10, 14, 238, 254, 10, 14, 238, 253, 10, 14, 238, - 252, 10, 14, 238, 251, 10, 14, 238, 250, 10, 14, 238, 249, 10, 14, 238, - 248, 10, 14, 238, 247, 10, 14, 238, 246, 10, 14, 238, 245, 10, 14, 238, - 244, 10, 14, 238, 243, 10, 14, 238, 242, 10, 14, 238, 241, 10, 14, 238, - 240, 10, 14, 238, 239, 10, 14, 238, 238, 10, 14, 238, 237, 10, 14, 238, - 236, 10, 14, 238, 235, 10, 14, 238, 234, 10, 14, 238, 233, 10, 14, 238, - 232, 10, 14, 238, 231, 10, 14, 238, 230, 10, 14, 238, 229, 10, 14, 238, - 228, 10, 14, 238, 227, 10, 14, 238, 226, 10, 14, 238, 225, 10, 14, 238, - 224, 10, 14, 238, 223, 10, 14, 238, 222, 10, 14, 238, 221, 10, 14, 238, - 220, 10, 14, 238, 219, 10, 14, 238, 218, 10, 14, 238, 217, 10, 14, 238, - 216, 10, 14, 238, 215, 10, 14, 238, 214, 10, 14, 238, 213, 10, 14, 238, - 212, 10, 14, 238, 211, 10, 14, 238, 210, 10, 14, 238, 209, 10, 14, 238, - 208, 10, 14, 238, 207, 10, 14, 238, 206, 10, 14, 238, 205, 10, 14, 238, - 204, 10, 14, 238, 203, 10, 14, 238, 202, 10, 14, 238, 201, 10, 14, 238, - 200, 10, 14, 238, 199, 10, 14, 238, 198, 10, 14, 238, 197, 10, 14, 238, - 196, 10, 14, 238, 195, 10, 14, 238, 194, 10, 14, 238, 193, 10, 14, 238, - 192, 10, 14, 238, 191, 10, 14, 238, 190, 10, 14, 238, 189, 10, 14, 238, - 188, 10, 14, 238, 187, 10, 14, 238, 186, 10, 14, 238, 185, 10, 14, 238, - 184, 10, 14, 238, 183, 10, 14, 238, 182, 10, 14, 238, 181, 10, 14, 238, - 180, 10, 14, 238, 179, 10, 14, 238, 178, 10, 14, 238, 177, 10, 14, 238, - 176, 10, 14, 238, 175, 10, 14, 238, 174, 10, 14, 238, 173, 10, 14, 238, - 172, 10, 14, 238, 171, 10, 14, 238, 170, 10, 14, 238, 169, 10, 14, 238, - 168, 10, 14, 238, 167, 10, 14, 238, 166, 10, 14, 238, 165, 10, 14, 238, - 164, 10, 14, 238, 163, 10, 14, 238, 162, 10, 14, 238, 161, 10, 14, 238, - 160, 10, 14, 238, 159, 10, 14, 238, 158, 10, 14, 238, 157, 10, 14, 238, - 156, 10, 14, 238, 155, 10, 14, 238, 154, 10, 14, 238, 153, 10, 14, 238, - 152, 10, 14, 238, 151, 10, 14, 238, 150, 10, 14, 238, 149, 10, 14, 238, - 148, 10, 14, 238, 147, 10, 14, 238, 146, 10, 14, 238, 145, 10, 14, 238, - 144, 10, 14, 238, 143, 10, 14, 238, 142, 10, 14, 238, 141, 10, 14, 238, - 140, 10, 14, 238, 139, 10, 14, 238, 138, 10, 14, 238, 137, 10, 14, 238, - 136, 10, 14, 238, 135, 10, 14, 238, 134, 10, 14, 238, 133, 10, 14, 238, - 132, 10, 14, 238, 131, 10, 14, 238, 130, 10, 14, 238, 129, 10, 14, 238, - 128, 10, 14, 238, 127, 10, 14, 238, 126, 10, 14, 238, 125, 10, 14, 238, - 124, 10, 14, 238, 123, 10, 14, 238, 122, 10, 14, 238, 121, 10, 14, 238, - 120, 10, 14, 238, 119, 10, 14, 238, 118, 10, 14, 238, 117, 10, 14, 238, - 116, 10, 14, 238, 115, 10, 14, 238, 114, 10, 14, 238, 113, 10, 14, 238, - 112, 10, 14, 238, 111, 10, 14, 238, 110, 10, 14, 238, 109, 10, 14, 238, - 108, 10, 14, 238, 107, 10, 14, 238, 106, 10, 14, 238, 105, 10, 14, 238, - 104, 10, 14, 238, 103, 10, 14, 238, 102, 10, 14, 238, 101, 10, 14, 238, - 100, 10, 14, 238, 99, 10, 14, 238, 98, 10, 14, 238, 97, 10, 14, 238, 96, - 10, 14, 238, 95, 10, 14, 238, 94, 10, 14, 238, 93, 10, 14, 238, 92, 10, - 14, 238, 91, 10, 14, 238, 90, 10, 14, 238, 89, 10, 14, 238, 88, 10, 14, - 238, 87, 10, 14, 238, 86, 10, 14, 238, 85, 10, 14, 238, 84, 10, 14, 238, - 83, 10, 14, 238, 82, 10, 14, 238, 81, 10, 14, 238, 80, 233, 96, 217, 85, - 129, 219, 20, 129, 245, 39, 79, 129, 224, 1, 79, 129, 54, 50, 129, 247, - 140, 50, 129, 225, 185, 50, 129, 254, 134, 129, 254, 65, 129, 43, 226, 7, - 129, 44, 226, 7, 129, 253, 224, 129, 96, 50, 129, 249, 227, 129, 240, - 174, 129, 243, 236, 218, 131, 129, 219, 48, 129, 21, 210, 86, 129, 21, - 111, 129, 21, 105, 129, 21, 158, 129, 21, 161, 129, 21, 190, 129, 21, - 195, 129, 21, 199, 129, 21, 196, 129, 21, 201, 129, 249, 234, 129, 220, - 152, 129, 233, 21, 50, 129, 245, 106, 50, 129, 242, 137, 50, 129, 224, - 16, 79, 129, 249, 225, 253, 214, 129, 7, 6, 1, 61, 129, 7, 6, 1, 253, - 166, 129, 7, 6, 1, 251, 74, 129, 7, 6, 1, 249, 68, 129, 7, 6, 1, 76, 129, - 7, 6, 1, 245, 14, 129, 7, 6, 1, 243, 209, 129, 7, 6, 1, 242, 67, 129, 7, - 6, 1, 74, 129, 7, 6, 1, 235, 150, 129, 7, 6, 1, 235, 29, 129, 7, 6, 1, - 156, 129, 7, 6, 1, 194, 129, 7, 6, 1, 230, 30, 129, 7, 6, 1, 78, 129, 7, - 6, 1, 226, 109, 129, 7, 6, 1, 224, 99, 129, 7, 6, 1, 153, 129, 7, 6, 1, - 222, 93, 129, 7, 6, 1, 217, 153, 129, 7, 6, 1, 69, 129, 7, 6, 1, 214, - 105, 129, 7, 6, 1, 212, 98, 129, 7, 6, 1, 211, 178, 129, 7, 6, 1, 211, - 117, 129, 7, 6, 1, 210, 159, 129, 43, 42, 127, 129, 223, 53, 219, 48, - 129, 44, 42, 127, 129, 250, 39, 255, 23, 129, 121, 232, 219, 129, 242, - 144, 255, 23, 129, 7, 4, 1, 61, 129, 7, 4, 1, 253, 166, 129, 7, 4, 1, - 251, 74, 129, 7, 4, 1, 249, 68, 129, 7, 4, 1, 76, 129, 7, 4, 1, 245, 14, - 129, 7, 4, 1, 243, 209, 129, 7, 4, 1, 242, 67, 129, 7, 4, 1, 74, 129, 7, - 4, 1, 235, 150, 129, 7, 4, 1, 235, 29, 129, 7, 4, 1, 156, 129, 7, 4, 1, - 194, 129, 7, 4, 1, 230, 30, 129, 7, 4, 1, 78, 129, 7, 4, 1, 226, 109, - 129, 7, 4, 1, 224, 99, 129, 7, 4, 1, 153, 129, 7, 4, 1, 222, 93, 129, 7, - 4, 1, 217, 153, 129, 7, 4, 1, 69, 129, 7, 4, 1, 214, 105, 129, 7, 4, 1, - 212, 98, 129, 7, 4, 1, 211, 178, 129, 7, 4, 1, 211, 117, 129, 7, 4, 1, - 210, 159, 129, 43, 249, 107, 127, 129, 67, 232, 219, 129, 44, 249, 107, - 127, 129, 184, 251, 14, 217, 85, 45, 221, 80, 45, 221, 69, 45, 221, 58, - 45, 221, 46, 45, 221, 35, 45, 221, 24, 45, 221, 13, 45, 221, 2, 45, 220, - 247, 45, 220, 239, 45, 220, 238, 45, 220, 237, 45, 220, 236, 45, 220, - 234, 45, 220, 233, 45, 220, 232, 45, 220, 231, 45, 220, 230, 45, 220, - 229, 45, 220, 228, 45, 220, 227, 45, 220, 226, 45, 220, 225, 45, 220, - 223, 45, 220, 222, 45, 220, 221, 45, 220, 220, 45, 220, 219, 45, 220, - 218, 45, 220, 217, 45, 220, 216, 45, 220, 215, 45, 220, 214, 45, 220, - 212, 45, 220, 211, 45, 220, 210, 45, 220, 209, 45, 220, 208, 45, 220, - 207, 45, 220, 206, 45, 220, 205, 45, 220, 204, 45, 220, 203, 45, 220, - 201, 45, 220, 200, 45, 220, 199, 45, 220, 198, 45, 220, 197, 45, 220, - 196, 45, 220, 195, 45, 220, 194, 45, 220, 193, 45, 220, 192, 45, 220, - 190, 45, 220, 189, 45, 220, 188, 45, 220, 187, 45, 220, 186, 45, 220, - 185, 45, 220, 184, 45, 220, 183, 45, 220, 182, 45, 220, 181, 45, 220, - 179, 45, 220, 178, 45, 220, 177, 45, 220, 176, 45, 220, 175, 45, 220, - 174, 45, 220, 173, 45, 220, 172, 45, 220, 171, 45, 220, 170, 45, 220, - 168, 45, 220, 167, 45, 220, 166, 45, 220, 165, 45, 220, 164, 45, 220, - 163, 45, 220, 162, 45, 220, 161, 45, 220, 160, 45, 220, 159, 45, 221, - 156, 45, 221, 155, 45, 221, 154, 45, 221, 153, 45, 221, 152, 45, 221, - 151, 45, 221, 150, 45, 221, 149, 45, 221, 148, 45, 221, 147, 45, 221, - 145, 45, 221, 144, 45, 221, 143, 45, 221, 142, 45, 221, 141, 45, 221, - 140, 45, 221, 139, 45, 221, 138, 45, 221, 137, 45, 221, 136, 45, 221, - 134, 45, 221, 133, 45, 221, 132, 45, 221, 131, 45, 221, 130, 45, 221, - 129, 45, 221, 128, 45, 221, 127, 45, 221, 126, 45, 221, 125, 45, 221, - 123, 45, 221, 122, 45, 221, 121, 45, 221, 120, 45, 221, 119, 45, 221, - 118, 45, 221, 117, 45, 221, 116, 45, 221, 115, 45, 221, 114, 45, 221, - 112, 45, 221, 111, 45, 221, 110, 45, 221, 109, 45, 221, 108, 45, 221, - 107, 45, 221, 106, 45, 221, 105, 45, 221, 104, 45, 221, 103, 45, 221, - 101, 45, 221, 100, 45, 221, 99, 45, 221, 98, 45, 221, 97, 45, 221, 96, - 45, 221, 95, 45, 221, 94, 45, 221, 93, 45, 221, 92, 45, 221, 90, 45, 221, - 89, 45, 221, 88, 45, 221, 87, 45, 221, 86, 45, 221, 85, 45, 221, 84, 45, - 221, 83, 45, 221, 82, 45, 221, 81, 45, 221, 79, 45, 221, 78, 45, 221, 77, - 45, 221, 76, 45, 221, 75, 45, 221, 74, 45, 221, 73, 45, 221, 72, 45, 221, - 71, 45, 221, 70, 45, 221, 68, 45, 221, 67, 45, 221, 66, 45, 221, 65, 45, - 221, 64, 45, 221, 63, 45, 221, 62, 45, 221, 61, 45, 221, 60, 45, 221, 59, - 45, 221, 57, 45, 221, 56, 45, 221, 55, 45, 221, 54, 45, 221, 53, 45, 221, - 52, 45, 221, 51, 45, 221, 50, 45, 221, 49, 45, 221, 48, 45, 221, 45, 45, - 221, 44, 45, 221, 43, 45, 221, 42, 45, 221, 41, 45, 221, 40, 45, 221, 39, - 45, 221, 38, 45, 221, 37, 45, 221, 36, 45, 221, 34, 45, 221, 33, 45, 221, - 32, 45, 221, 31, 45, 221, 30, 45, 221, 29, 45, 221, 28, 45, 221, 27, 45, - 221, 26, 45, 221, 25, 45, 221, 23, 45, 221, 22, 45, 221, 21, 45, 221, 20, - 45, 221, 19, 45, 221, 18, 45, 221, 17, 45, 221, 16, 45, 221, 15, 45, 221, - 14, 45, 221, 12, 45, 221, 11, 45, 221, 10, 45, 221, 9, 45, 221, 8, 45, - 221, 7, 45, 221, 6, 45, 221, 5, 45, 221, 4, 45, 221, 3, 45, 221, 1, 45, - 221, 0, 45, 220, 255, 45, 220, 254, 45, 220, 253, 45, 220, 252, 45, 220, - 251, 45, 220, 250, 45, 220, 249, 45, 220, 248, 45, 220, 246, 45, 220, - 245, 45, 220, 244, 45, 220, 243, 45, 220, 242, 45, 220, 241, 45, 220, - 240, 227, 206, 227, 208, 218, 154, 64, 241, 240, 219, 50, 218, 154, 64, - 216, 213, 218, 86, 245, 151, 64, 216, 213, 245, 64, 245, 151, 64, 215, - 244, 245, 117, 245, 140, 245, 141, 255, 16, 255, 17, 254, 176, 252, 55, - 252, 187, 251, 139, 135, 217, 90, 203, 217, 90, 240, 234, 217, 94, 232, - 220, 244, 153, 166, 232, 219, 245, 151, 64, 232, 219, 233, 6, 228, 140, - 245, 120, 232, 220, 217, 90, 67, 217, 90, 212, 118, 244, 28, 244, 153, - 244, 133, 250, 238, 223, 56, 249, 151, 220, 30, 226, 134, 232, 156, 111, - 219, 60, 220, 30, 236, 6, 232, 156, 210, 86, 219, 193, 248, 159, 232, - 210, 245, 85, 247, 163, 248, 39, 249, 186, 111, 248, 149, 248, 39, 249, - 186, 105, 248, 148, 248, 39, 249, 186, 158, 248, 147, 248, 39, 249, 186, - 161, 248, 146, 152, 255, 16, 229, 214, 217, 178, 236, 69, 217, 181, 245, - 151, 64, 215, 245, 251, 221, 245, 70, 251, 13, 251, 15, 245, 151, 64, - 231, 86, 245, 118, 218, 62, 218, 79, 245, 85, 245, 86, 235, 239, 220, - 140, 161, 244, 115, 220, 139, 243, 245, 235, 239, 220, 140, 158, 242, - 128, 220, 139, 242, 125, 235, 239, 220, 140, 105, 223, 124, 220, 139, - 222, 147, 235, 239, 220, 140, 111, 214, 174, 220, 139, 214, 133, 219, 23, - 248, 71, 248, 73, 226, 82, 250, 150, 226, 84, 125, 226, 244, 224, 196, - 241, 54, 251, 158, 225, 176, 241, 210, 251, 169, 228, 80, 251, 158, 241, - 210, 229, 180, 235, 249, 235, 251, 229, 87, 232, 219, 229, 104, 218, 154, - 64, 221, 160, 254, 26, 218, 225, 245, 151, 64, 221, 160, 254, 26, 245, - 88, 135, 217, 91, 220, 129, 203, 217, 91, 220, 129, 240, 231, 135, 217, - 91, 2, 235, 41, 203, 217, 91, 2, 235, 41, 240, 232, 232, 220, 217, 91, - 220, 129, 67, 217, 91, 220, 129, 212, 117, 226, 1, 232, 220, 244, 22, - 226, 1, 232, 220, 246, 114, 225, 35, 226, 1, 232, 220, 252, 186, 226, 1, - 232, 220, 214, 163, 225, 31, 223, 53, 232, 220, 244, 153, 223, 53, 235, - 249, 223, 38, 219, 157, 220, 30, 105, 219, 154, 218, 227, 219, 157, 220, - 30, 158, 219, 153, 218, 226, 248, 39, 249, 186, 218, 107, 248, 145, 224, - 186, 214, 132, 111, 224, 186, 214, 130, 224, 152, 224, 186, 214, 132, - 105, 224, 186, 214, 129, 224, 151, 220, 130, 215, 243, 218, 153, 218, 90, - 251, 14, 250, 150, 250, 217, 231, 48, 212, 59, 230, 48, 218, 154, 64, - 242, 114, 254, 26, 218, 154, 64, 224, 169, 254, 26, 219, 22, 245, 151, - 64, 242, 114, 254, 26, 245, 151, 64, 224, 169, 254, 26, 245, 115, 218, - 154, 64, 218, 107, 219, 37, 219, 157, 242, 148, 135, 235, 202, 220, 109, - 219, 157, 135, 235, 202, 221, 196, 249, 186, 220, 137, 235, 202, 249, - 121, 218, 108, 216, 237, 218, 170, 226, 173, 217, 168, 249, 226, 226, - 146, 224, 187, 231, 47, 225, 22, 254, 61, 224, 181, 249, 226, 254, 77, - 229, 168, 219, 202, 7, 6, 1, 243, 0, 7, 4, 1, 243, 0, 250, 167, 254, 157, - 183, 218, 68, 249, 235, 219, 108, 233, 52, 165, 1, 232, 181, 209, 209, 1, - 244, 52, 244, 44, 209, 209, 1, 244, 52, 244, 165, 209, 209, 1, 222, 213, - 209, 209, 1, 232, 162, 63, 164, 251, 231, 220, 5, 242, 222, 230, 253, - 223, 44, 243, 223, 243, 222, 243, 221, 230, 50, 209, 251, 209, 252, 209, - 254, 232, 107, 222, 221, 232, 109, 222, 223, 225, 227, 232, 106, 222, - 220, 228, 111, 230, 170, 211, 229, 232, 108, 222, 222, 243, 244, 225, - 226, 212, 15, 245, 170, 243, 233, 230, 234, 226, 201, 214, 134, 87, 230, - 234, 248, 165, 87, 8, 3, 235, 164, 79, 224, 197, 244, 28, 31, 67, 44, 71, - 233, 26, 127, 213, 118, 213, 7, 212, 195, 212, 184, 212, 173, 212, 162, - 212, 151, 212, 140, 212, 129, 213, 117, 213, 106, 213, 95, 213, 84, 213, - 73, 213, 62, 213, 51, 251, 79, 226, 159, 79, 251, 204, 209, 253, 15, 5, - 227, 215, 216, 240, 15, 5, 227, 215, 115, 227, 215, 251, 107, 115, 251, - 106, 49, 28, 16, 243, 243, 219, 104, 250, 81, 214, 9, 213, 40, 213, 29, - 213, 18, 213, 6, 212, 251, 212, 240, 212, 229, 212, 218, 212, 207, 212, - 199, 212, 198, 212, 197, 212, 196, 212, 194, 212, 193, 212, 192, 212, - 191, 212, 190, 212, 189, 212, 188, 212, 187, 212, 186, 212, 185, 212, - 183, 212, 182, 212, 181, 212, 180, 212, 179, 212, 178, 212, 177, 212, - 176, 212, 175, 212, 174, 212, 172, 212, 171, 212, 170, 212, 169, 212, - 168, 212, 167, 212, 166, 212, 165, 212, 164, 212, 163, 212, 161, 212, - 160, 212, 159, 212, 158, 212, 157, 212, 156, 212, 155, 212, 154, 212, - 153, 212, 152, 212, 150, 212, 149, 212, 148, 212, 147, 212, 146, 212, - 145, 212, 144, 212, 143, 212, 142, 212, 141, 212, 139, 212, 138, 212, - 137, 212, 136, 212, 135, 212, 134, 212, 133, 212, 132, 212, 131, 212, - 130, 212, 128, 212, 127, 212, 126, 212, 125, 212, 124, 212, 123, 212, - 122, 212, 121, 212, 120, 212, 119, 213, 116, 213, 115, 213, 114, 213, - 113, 213, 112, 213, 111, 213, 110, 213, 109, 213, 108, 213, 107, 213, - 105, 213, 104, 213, 103, 213, 102, 213, 101, 213, 100, 213, 99, 213, 98, - 213, 97, 213, 96, 213, 94, 213, 93, 213, 92, 213, 91, 213, 90, 213, 89, - 213, 88, 213, 87, 213, 86, 213, 85, 213, 83, 213, 82, 213, 81, 213, 80, - 213, 79, 213, 78, 213, 77, 213, 76, 213, 75, 213, 74, 213, 72, 213, 71, - 213, 70, 213, 69, 213, 68, 213, 67, 213, 66, 213, 65, 213, 64, 213, 63, - 213, 61, 213, 60, 213, 59, 213, 58, 213, 57, 213, 56, 213, 55, 213, 54, - 213, 53, 213, 52, 213, 50, 213, 49, 213, 48, 213, 47, 213, 46, 213, 45, - 213, 44, 213, 43, 213, 42, 213, 41, 213, 39, 213, 38, 213, 37, 213, 36, - 213, 35, 213, 34, 213, 33, 213, 32, 213, 31, 213, 30, 213, 28, 213, 27, - 213, 26, 213, 25, 213, 24, 213, 23, 213, 22, 213, 21, 213, 20, 213, 19, - 213, 17, 213, 16, 213, 15, 213, 14, 213, 13, 213, 12, 213, 11, 213, 10, - 213, 9, 213, 8, 213, 5, 213, 4, 213, 3, 213, 2, 213, 1, 213, 0, 212, 255, - 212, 254, 212, 253, 212, 252, 212, 250, 212, 249, 212, 248, 212, 247, - 212, 246, 212, 245, 212, 244, 212, 243, 212, 242, 212, 241, 212, 239, - 212, 238, 212, 237, 212, 236, 212, 235, 212, 234, 212, 233, 212, 232, - 212, 231, 212, 230, 212, 228, 212, 227, 212, 226, 212, 225, 212, 224, - 212, 223, 212, 222, 212, 221, 212, 220, 212, 219, 212, 217, 212, 216, - 212, 215, 212, 214, 212, 213, 212, 212, 212, 211, 212, 210, 212, 209, - 212, 208, 212, 206, 212, 205, 212, 204, 212, 203, 212, 202, 212, 201, - 212, 200, 7, 6, 1, 116, 2, 231, 238, 22, 242, 143, 7, 4, 1, 116, 2, 231, - 238, 22, 242, 143, 7, 6, 1, 160, 2, 67, 232, 220, 51, 7, 4, 1, 160, 2, - 67, 232, 220, 51, 7, 6, 1, 160, 2, 67, 232, 220, 252, 51, 22, 242, 143, - 7, 4, 1, 160, 2, 67, 232, 220, 252, 51, 22, 242, 143, 7, 6, 1, 160, 2, - 67, 232, 220, 252, 51, 22, 142, 7, 4, 1, 160, 2, 67, 232, 220, 252, 51, - 22, 142, 7, 6, 1, 160, 2, 250, 39, 22, 231, 237, 7, 4, 1, 160, 2, 250, - 39, 22, 231, 237, 7, 6, 1, 160, 2, 250, 39, 22, 250, 242, 7, 4, 1, 160, - 2, 250, 39, 22, 250, 242, 7, 6, 1, 240, 161, 2, 231, 238, 22, 242, 143, - 7, 4, 1, 240, 161, 2, 231, 238, 22, 242, 143, 7, 4, 1, 240, 161, 2, 59, - 72, 22, 142, 7, 4, 1, 229, 85, 2, 216, 90, 48, 7, 6, 1, 144, 2, 67, 232, - 220, 51, 7, 4, 1, 144, 2, 67, 232, 220, 51, 7, 6, 1, 144, 2, 67, 232, - 220, 252, 51, 22, 242, 143, 7, 4, 1, 144, 2, 67, 232, 220, 252, 51, 22, - 242, 143, 7, 6, 1, 144, 2, 67, 232, 220, 252, 51, 22, 142, 7, 4, 1, 144, - 2, 67, 232, 220, 252, 51, 22, 142, 7, 6, 1, 222, 94, 2, 67, 232, 220, 51, - 7, 4, 1, 222, 94, 2, 67, 232, 220, 51, 7, 6, 1, 104, 2, 231, 238, 22, - 242, 143, 7, 4, 1, 104, 2, 231, 238, 22, 242, 143, 7, 6, 1, 116, 2, 226, - 229, 22, 142, 7, 4, 1, 116, 2, 226, 229, 22, 142, 7, 6, 1, 116, 2, 226, - 229, 22, 184, 7, 4, 1, 116, 2, 226, 229, 22, 184, 7, 6, 1, 160, 2, 226, - 229, 22, 142, 7, 4, 1, 160, 2, 226, 229, 22, 142, 7, 6, 1, 160, 2, 226, - 229, 22, 184, 7, 4, 1, 160, 2, 226, 229, 22, 184, 7, 6, 1, 160, 2, 59, - 72, 22, 142, 7, 4, 1, 160, 2, 59, 72, 22, 142, 7, 6, 1, 160, 2, 59, 72, - 22, 184, 7, 4, 1, 160, 2, 59, 72, 22, 184, 7, 4, 1, 240, 161, 2, 59, 72, - 22, 242, 143, 7, 4, 1, 240, 161, 2, 59, 72, 22, 184, 7, 6, 1, 240, 161, - 2, 226, 229, 22, 142, 7, 4, 1, 240, 161, 2, 226, 229, 22, 59, 72, 22, - 142, 7, 6, 1, 240, 161, 2, 226, 229, 22, 184, 7, 4, 1, 240, 161, 2, 226, - 229, 22, 59, 72, 22, 184, 7, 6, 1, 235, 151, 2, 184, 7, 4, 1, 235, 151, - 2, 59, 72, 22, 184, 7, 6, 1, 233, 155, 2, 184, 7, 4, 1, 233, 155, 2, 184, - 7, 6, 1, 232, 55, 2, 184, 7, 4, 1, 232, 55, 2, 184, 7, 6, 1, 223, 227, 2, - 184, 7, 4, 1, 223, 227, 2, 184, 7, 6, 1, 104, 2, 226, 229, 22, 142, 7, 4, - 1, 104, 2, 226, 229, 22, 142, 7, 6, 1, 104, 2, 226, 229, 22, 184, 7, 4, - 1, 104, 2, 226, 229, 22, 184, 7, 6, 1, 104, 2, 231, 238, 22, 142, 7, 4, - 1, 104, 2, 231, 238, 22, 142, 7, 6, 1, 104, 2, 231, 238, 22, 184, 7, 4, - 1, 104, 2, 231, 238, 22, 184, 7, 4, 1, 254, 253, 2, 242, 143, 7, 4, 1, - 204, 144, 2, 242, 143, 7, 4, 1, 204, 144, 2, 142, 7, 4, 1, 215, 94, 214, - 106, 2, 242, 143, 7, 4, 1, 215, 94, 214, 106, 2, 142, 7, 4, 1, 221, 198, - 2, 242, 143, 7, 4, 1, 221, 198, 2, 142, 7, 4, 1, 241, 58, 221, 198, 2, - 242, 143, 7, 4, 1, 241, 58, 221, 198, 2, 142, 9, 220, 137, 77, 2, 182, - 72, 2, 254, 179, 9, 220, 137, 77, 2, 182, 72, 2, 212, 30, 9, 220, 137, - 77, 2, 182, 72, 2, 109, 231, 197, 9, 220, 137, 77, 2, 182, 72, 2, 226, - 238, 9, 220, 137, 77, 2, 182, 72, 2, 69, 9, 220, 137, 77, 2, 182, 72, 2, - 210, 212, 9, 220, 137, 77, 2, 182, 72, 2, 76, 9, 220, 137, 77, 2, 182, - 72, 2, 254, 252, 9, 220, 137, 228, 68, 2, 234, 180, 146, 1, 234, 115, 36, - 117, 235, 29, 36, 117, 229, 84, 36, 117, 251, 74, 36, 117, 227, 171, 36, - 117, 215, 160, 36, 117, 228, 116, 36, 117, 217, 153, 36, 117, 230, 30, - 36, 117, 226, 109, 36, 117, 194, 36, 117, 211, 117, 36, 117, 153, 36, - 117, 156, 36, 117, 214, 105, 36, 117, 232, 182, 36, 117, 232, 191, 36, - 117, 222, 182, 36, 117, 228, 98, 36, 117, 235, 150, 36, 117, 220, 106, - 36, 117, 218, 228, 36, 117, 222, 93, 36, 117, 242, 67, 36, 117, 233, 238, - 36, 3, 235, 16, 36, 3, 234, 98, 36, 3, 234, 89, 36, 3, 233, 223, 36, 3, - 233, 194, 36, 3, 234, 188, 36, 3, 234, 187, 36, 3, 234, 252, 36, 3, 234, - 34, 36, 3, 234, 16, 36, 3, 234, 201, 36, 3, 229, 81, 36, 3, 229, 32, 36, - 3, 229, 28, 36, 3, 228, 253, 36, 3, 228, 246, 36, 3, 229, 69, 36, 3, 229, - 67, 36, 3, 229, 78, 36, 3, 229, 9, 36, 3, 229, 4, 36, 3, 229, 71, 36, 3, - 251, 40, 36, 3, 250, 59, 36, 3, 250, 49, 36, 3, 249, 120, 36, 3, 249, 91, - 36, 3, 250, 198, 36, 3, 250, 190, 36, 3, 251, 30, 36, 3, 249, 246, 36, 3, - 249, 182, 36, 3, 250, 230, 36, 3, 227, 168, 36, 3, 227, 152, 36, 3, 227, - 147, 36, 3, 227, 132, 36, 3, 227, 125, 36, 3, 227, 160, 36, 3, 227, 159, - 36, 3, 227, 165, 36, 3, 227, 138, 36, 3, 227, 136, 36, 3, 227, 163, 36, - 3, 215, 156, 36, 3, 215, 136, 36, 3, 215, 135, 36, 3, 215, 124, 36, 3, - 215, 121, 36, 3, 215, 152, 36, 3, 215, 151, 36, 3, 215, 155, 36, 3, 215, - 134, 36, 3, 215, 133, 36, 3, 215, 154, 36, 3, 228, 114, 36, 3, 228, 100, - 36, 3, 228, 99, 36, 3, 228, 83, 36, 3, 228, 82, 36, 3, 228, 110, 36, 3, - 228, 109, 36, 3, 228, 113, 36, 3, 228, 85, 36, 3, 228, 84, 36, 3, 228, - 112, 36, 3, 217, 102, 36, 3, 216, 118, 36, 3, 216, 104, 36, 3, 215, 119, - 36, 3, 215, 85, 36, 3, 217, 23, 36, 3, 217, 12, 36, 3, 217, 80, 36, 3, - 112, 36, 3, 216, 18, 36, 3, 217, 42, 36, 3, 229, 230, 36, 3, 228, 238, - 36, 3, 228, 213, 36, 3, 227, 242, 36, 3, 227, 183, 36, 3, 229, 112, 36, - 3, 229, 108, 36, 3, 229, 217, 36, 3, 228, 79, 36, 3, 228, 69, 36, 3, 229, - 192, 36, 3, 226, 93, 36, 3, 225, 111, 36, 3, 225, 74, 36, 3, 224, 153, - 36, 3, 224, 122, 36, 3, 225, 224, 36, 3, 225, 214, 36, 3, 226, 75, 36, 3, - 225, 19, 36, 3, 224, 252, 36, 3, 225, 238, 36, 3, 231, 242, 36, 3, 230, - 235, 36, 3, 230, 206, 36, 3, 230, 107, 36, 3, 230, 59, 36, 3, 231, 96, - 36, 3, 231, 85, 36, 3, 231, 208, 36, 3, 230, 166, 36, 3, 230, 137, 36, 3, - 231, 140, 36, 3, 211, 103, 36, 3, 211, 8, 36, 3, 210, 255, 36, 3, 210, - 212, 36, 3, 210, 181, 36, 3, 211, 47, 36, 3, 211, 44, 36, 3, 211, 82, 36, - 3, 210, 244, 36, 3, 210, 229, 36, 3, 211, 55, 36, 3, 223, 187, 36, 3, - 223, 38, 36, 3, 222, 242, 36, 3, 222, 142, 36, 3, 222, 114, 36, 3, 223, - 131, 36, 3, 223, 111, 36, 3, 223, 169, 36, 3, 222, 213, 36, 3, 222, 199, - 36, 3, 223, 139, 36, 3, 233, 140, 36, 3, 232, 247, 36, 3, 232, 233, 36, - 3, 232, 103, 36, 3, 232, 78, 36, 3, 233, 64, 36, 3, 233, 56, 36, 3, 233, - 115, 36, 3, 232, 162, 36, 3, 232, 133, 36, 3, 233, 80, 36, 3, 214, 26, - 36, 3, 213, 176, 36, 3, 213, 162, 36, 3, 212, 116, 36, 3, 212, 109, 36, - 3, 213, 255, 36, 3, 213, 250, 36, 3, 214, 23, 36, 3, 213, 138, 36, 3, - 213, 127, 36, 3, 214, 5, 36, 3, 232, 180, 36, 3, 232, 175, 36, 3, 232, - 174, 36, 3, 232, 171, 36, 3, 232, 170, 36, 3, 232, 177, 36, 3, 232, 176, - 36, 3, 232, 179, 36, 3, 232, 173, 36, 3, 232, 172, 36, 3, 232, 178, 36, - 3, 232, 189, 36, 3, 232, 184, 36, 3, 232, 183, 36, 3, 232, 167, 36, 3, - 232, 166, 36, 3, 232, 186, 36, 3, 232, 185, 36, 3, 232, 188, 36, 3, 232, - 169, 36, 3, 232, 168, 36, 3, 232, 187, 36, 3, 222, 180, 36, 3, 222, 169, - 36, 3, 222, 168, 36, 3, 222, 162, 36, 3, 222, 155, 36, 3, 222, 176, 36, - 3, 222, 175, 36, 3, 222, 179, 36, 3, 222, 167, 36, 3, 222, 166, 36, 3, - 222, 178, 36, 3, 228, 96, 36, 3, 228, 91, 36, 3, 228, 90, 36, 3, 228, 87, - 36, 3, 228, 86, 36, 3, 228, 93, 36, 3, 228, 92, 36, 3, 228, 95, 36, 3, - 228, 89, 36, 3, 228, 88, 36, 3, 228, 94, 36, 3, 235, 146, 36, 3, 235, - 114, 36, 3, 235, 107, 36, 3, 235, 57, 36, 3, 235, 39, 36, 3, 235, 132, - 36, 3, 235, 130, 36, 3, 235, 141, 36, 3, 235, 74, 36, 3, 235, 65, 36, 3, - 235, 135, 36, 3, 220, 100, 36, 3, 220, 34, 36, 3, 220, 29, 36, 3, 219, - 227, 36, 3, 219, 212, 36, 3, 220, 65, 36, 3, 220, 63, 36, 3, 220, 92, 36, - 3, 220, 9, 36, 3, 220, 3, 36, 3, 220, 73, 36, 3, 218, 224, 36, 3, 218, - 194, 36, 3, 218, 190, 36, 3, 218, 181, 36, 3, 218, 178, 36, 3, 218, 199, - 36, 3, 218, 198, 36, 3, 218, 223, 36, 3, 218, 186, 36, 3, 218, 185, 36, - 3, 218, 201, 36, 3, 222, 33, 36, 3, 219, 193, 36, 3, 219, 177, 36, 3, - 218, 84, 36, 3, 218, 5, 36, 3, 221, 183, 36, 3, 221, 172, 36, 3, 222, 19, - 36, 3, 219, 60, 36, 3, 219, 42, 36, 3, 221, 221, 36, 3, 242, 53, 36, 3, - 241, 187, 36, 3, 241, 168, 36, 3, 240, 229, 36, 3, 240, 209, 36, 3, 241, - 245, 36, 3, 241, 227, 36, 3, 242, 43, 36, 3, 241, 75, 36, 3, 241, 60, 36, - 3, 241, 253, 36, 3, 233, 237, 36, 3, 233, 236, 36, 3, 233, 231, 36, 3, - 233, 230, 36, 3, 233, 227, 36, 3, 233, 226, 36, 3, 233, 233, 36, 3, 233, - 232, 36, 3, 233, 235, 36, 3, 233, 229, 36, 3, 233, 228, 36, 3, 233, 234, - 36, 3, 219, 233, 175, 117, 5, 211, 68, 175, 117, 5, 223, 158, 175, 117, - 5, 223, 81, 98, 1, 215, 28, 70, 117, 5, 249, 241, 176, 70, 117, 5, 249, - 241, 234, 138, 70, 117, 5, 249, 241, 234, 34, 70, 117, 5, 249, 241, 234, - 111, 70, 117, 5, 249, 241, 229, 9, 70, 117, 5, 249, 241, 251, 41, 70, - 117, 5, 249, 241, 250, 165, 70, 117, 5, 249, 241, 249, 246, 70, 117, 5, - 249, 241, 250, 94, 70, 117, 5, 249, 241, 227, 138, 70, 117, 5, 249, 241, - 248, 229, 70, 117, 5, 249, 241, 215, 145, 70, 117, 5, 249, 241, 247, 153, - 70, 117, 5, 249, 241, 215, 140, 70, 117, 5, 249, 241, 198, 70, 117, 5, - 249, 241, 217, 106, 70, 117, 5, 249, 241, 216, 209, 70, 117, 5, 249, 241, - 112, 70, 117, 5, 249, 241, 216, 157, 70, 117, 5, 249, 241, 228, 79, 70, - 117, 5, 249, 241, 252, 199, 70, 117, 5, 249, 241, 225, 150, 70, 117, 5, - 249, 241, 225, 19, 70, 117, 5, 249, 241, 225, 124, 70, 117, 5, 249, 241, - 230, 166, 70, 117, 5, 249, 241, 210, 244, 70, 117, 5, 249, 241, 222, 213, - 70, 117, 5, 249, 241, 232, 162, 70, 117, 5, 249, 241, 213, 138, 70, 117, - 5, 249, 241, 220, 104, 70, 117, 5, 249, 241, 218, 225, 70, 117, 5, 249, - 241, 206, 70, 117, 5, 249, 241, 162, 70, 117, 5, 249, 241, 233, 141, 70, - 25, 5, 249, 241, 224, 91, 70, 235, 250, 25, 5, 249, 241, 224, 33, 70, - 235, 250, 25, 5, 249, 241, 222, 102, 70, 235, 250, 25, 5, 249, 241, 222, - 95, 70, 235, 250, 25, 5, 249, 241, 224, 72, 70, 25, 5, 226, 208, 70, 25, - 5, 255, 43, 141, 1, 252, 7, 229, 82, 141, 1, 252, 7, 229, 32, 141, 1, - 252, 7, 228, 253, 141, 1, 252, 7, 229, 69, 141, 1, 252, 7, 229, 9, 56, 1, - 252, 7, 229, 82, 56, 1, 252, 7, 229, 32, 56, 1, 252, 7, 228, 253, 56, 1, - 252, 7, 229, 69, 56, 1, 252, 7, 229, 9, 56, 1, 254, 203, 250, 198, 56, 1, - 254, 203, 215, 119, 56, 1, 254, 203, 112, 56, 1, 254, 203, 226, 109, 58, - 1, 245, 28, 245, 27, 249, 190, 138, 130, 58, 1, 245, 27, 245, 28, 249, - 190, 138, 130, + 0, 211, 228, 240, 212, 82, 217, 31, 82, 42, 54, 243, 97, 54, 218, 246, + 54, 250, 235, 250, 160, 49, 219, 76, 50, 219, 76, 250, 59, 91, 54, 245, + 233, 235, 219, 239, 102, 211, 61, 212, 0, 17, 202, 84, 17, 105, 17, 108, + 17, 147, 17, 149, 17, 170, 17, 195, 17, 213, 111, 17, 199, 17, 222, 63, + 245, 242, 213, 143, 227, 179, 54, 241, 35, 54, 237, 247, 54, 217, 47, 82, + 245, 231, 250, 49, 8, 6, 1, 63, 8, 6, 1, 249, 255, 8, 6, 1, 247, 125, 8, + 6, 1, 245, 51, 8, 6, 1, 74, 8, 6, 1, 240, 174, 8, 6, 1, 239, 75, 8, 6, 1, + 237, 171, 8, 6, 1, 75, 8, 6, 1, 230, 184, 8, 6, 1, 230, 54, 8, 6, 1, 159, + 8, 6, 1, 226, 185, 8, 6, 1, 223, 163, 8, 6, 1, 78, 8, 6, 1, 219, 184, 8, + 6, 1, 217, 134, 8, 6, 1, 146, 8, 6, 1, 194, 8, 6, 1, 210, 69, 8, 6, 1, + 68, 8, 6, 1, 206, 164, 8, 6, 1, 204, 144, 8, 6, 1, 203, 196, 8, 6, 1, + 203, 124, 8, 6, 1, 202, 159, 49, 51, 155, 216, 74, 212, 0, 50, 51, 155, + 246, 53, 251, 138, 124, 227, 114, 237, 254, 251, 138, 8, 5, 1, 63, 8, 5, + 1, 249, 255, 8, 5, 1, 247, 125, 8, 5, 1, 245, 51, 8, 5, 1, 74, 8, 5, 1, + 240, 174, 8, 5, 1, 239, 75, 8, 5, 1, 237, 171, 8, 5, 1, 75, 8, 5, 1, 230, + 184, 8, 5, 1, 230, 54, 8, 5, 1, 159, 8, 5, 1, 226, 185, 8, 5, 1, 223, + 163, 8, 5, 1, 78, 8, 5, 1, 219, 184, 8, 5, 1, 217, 134, 8, 5, 1, 146, 8, + 5, 1, 194, 8, 5, 1, 210, 69, 8, 5, 1, 68, 8, 5, 1, 206, 164, 8, 5, 1, + 204, 144, 8, 5, 1, 203, 196, 8, 5, 1, 203, 124, 8, 5, 1, 202, 159, 49, + 245, 93, 155, 80, 227, 114, 50, 245, 93, 155, 208, 227, 221, 190, 211, + 228, 230, 239, 240, 212, 82, 246, 220, 54, 218, 20, 54, 245, 92, 54, 203, + 43, 54, 247, 203, 142, 214, 168, 54, 243, 231, 245, 169, 54, 240, 41, + 219, 240, 231, 31, 227, 217, 52, 250, 218, 217, 31, 82, 221, 166, 54, + 212, 7, 235, 220, 216, 129, 54, 225, 170, 244, 55, 54, 218, 75, 54, 210, + 199, 108, 210, 199, 147, 251, 126, 251, 138, 224, 153, 54, 218, 126, 54, + 101, 243, 85, 246, 231, 210, 199, 105, 225, 80, 219, 240, 231, 31, 216, + 11, 52, 250, 218, 217, 31, 82, 204, 161, 239, 138, 118, 217, 55, 204, + 161, 239, 138, 118, 237, 137, 204, 161, 239, 138, 126, 217, 53, 230, 239, + 217, 47, 82, 8, 6, 1, 34, 3, 237, 253, 8, 6, 1, 34, 3, 165, 8, 6, 1, 34, + 3, 246, 52, 8, 6, 1, 34, 3, 208, 227, 8, 6, 1, 34, 3, 243, 231, 8, 6, 1, + 34, 3, 215, 253, 55, 8, 6, 1, 251, 109, 8, 6, 1, 247, 126, 3, 246, 231, + 8, 6, 1, 188, 3, 237, 253, 8, 6, 1, 188, 3, 165, 8, 6, 1, 188, 3, 246, + 52, 8, 6, 1, 188, 3, 243, 231, 8, 6, 1, 235, 206, 3, 237, 253, 8, 6, 1, + 235, 206, 3, 165, 8, 6, 1, 235, 206, 3, 246, 52, 8, 6, 1, 235, 206, 3, + 243, 231, 8, 6, 1, 240, 243, 8, 6, 1, 223, 164, 3, 208, 227, 8, 6, 1, + 158, 3, 237, 253, 8, 6, 1, 158, 3, 165, 8, 6, 1, 158, 3, 246, 52, 8, 6, + 1, 158, 3, 208, 227, 8, 6, 1, 158, 3, 243, 231, 223, 224, 54, 8, 6, 1, + 158, 3, 95, 8, 6, 1, 106, 3, 237, 253, 8, 6, 1, 106, 3, 165, 8, 6, 1, + 106, 3, 246, 52, 8, 6, 1, 106, 3, 243, 231, 8, 6, 1, 203, 125, 3, 165, 8, + 6, 1, 209, 40, 8, 5, 1, 213, 57, 194, 8, 5, 1, 34, 3, 237, 253, 8, 5, 1, + 34, 3, 165, 8, 5, 1, 34, 3, 246, 52, 8, 5, 1, 34, 3, 208, 227, 8, 5, 1, + 34, 3, 243, 231, 8, 5, 1, 34, 3, 215, 253, 55, 8, 5, 1, 251, 109, 8, 5, + 1, 247, 126, 3, 246, 231, 8, 5, 1, 188, 3, 237, 253, 8, 5, 1, 188, 3, + 165, 8, 5, 1, 188, 3, 246, 52, 8, 5, 1, 188, 3, 243, 231, 8, 5, 1, 235, + 206, 3, 237, 253, 8, 5, 1, 235, 206, 3, 165, 8, 5, 1, 235, 206, 3, 246, + 52, 8, 5, 1, 235, 206, 3, 243, 231, 8, 5, 1, 240, 243, 8, 5, 1, 223, 164, + 3, 208, 227, 8, 5, 1, 158, 3, 237, 253, 8, 5, 1, 158, 3, 165, 8, 5, 1, + 158, 3, 246, 52, 8, 5, 1, 158, 3, 208, 227, 8, 5, 1, 158, 3, 243, 231, + 243, 137, 54, 8, 5, 1, 158, 3, 95, 8, 5, 1, 106, 3, 237, 253, 8, 5, 1, + 106, 3, 165, 8, 5, 1, 106, 3, 246, 52, 8, 5, 1, 106, 3, 243, 231, 8, 5, + 1, 203, 125, 3, 165, 8, 5, 1, 209, 40, 8, 5, 1, 203, 125, 3, 243, 231, 8, + 6, 1, 34, 3, 225, 170, 8, 5, 1, 34, 3, 225, 170, 8, 6, 1, 34, 3, 247, + 214, 8, 5, 1, 34, 3, 247, 214, 8, 6, 1, 34, 3, 220, 62, 8, 5, 1, 34, 3, + 220, 62, 8, 6, 1, 247, 126, 3, 165, 8, 5, 1, 247, 126, 3, 165, 8, 6, 1, + 247, 126, 3, 246, 52, 8, 5, 1, 247, 126, 3, 246, 52, 8, 6, 1, 247, 126, + 3, 70, 55, 8, 5, 1, 247, 126, 3, 70, 55, 8, 6, 1, 247, 126, 3, 247, 29, + 8, 5, 1, 247, 126, 3, 247, 29, 8, 6, 1, 245, 52, 3, 247, 29, 8, 5, 1, + 245, 52, 3, 247, 29, 8, 6, 1, 245, 52, 3, 95, 8, 5, 1, 245, 52, 3, 95, 8, + 6, 1, 188, 3, 225, 170, 8, 5, 1, 188, 3, 225, 170, 8, 6, 1, 188, 3, 247, + 214, 8, 5, 1, 188, 3, 247, 214, 8, 6, 1, 188, 3, 70, 55, 8, 5, 1, 188, 3, + 70, 55, 8, 6, 1, 188, 3, 220, 62, 8, 5, 1, 188, 3, 220, 62, 8, 6, 1, 188, + 3, 247, 29, 8, 5, 1, 188, 3, 247, 29, 8, 6, 1, 239, 76, 3, 246, 52, 8, 5, + 1, 239, 76, 3, 246, 52, 8, 6, 1, 239, 76, 3, 247, 214, 8, 5, 1, 239, 76, + 3, 247, 214, 8, 6, 1, 239, 76, 3, 70, 55, 8, 5, 1, 239, 76, 3, 70, 55, 8, + 6, 1, 239, 76, 3, 246, 231, 8, 5, 1, 239, 76, 3, 246, 231, 8, 6, 1, 237, + 172, 3, 246, 52, 8, 5, 1, 237, 172, 3, 246, 52, 8, 6, 1, 237, 172, 3, 95, + 8, 5, 1, 237, 172, 3, 95, 8, 6, 1, 235, 206, 3, 208, 227, 8, 5, 1, 235, + 206, 3, 208, 227, 8, 6, 1, 235, 206, 3, 225, 170, 8, 5, 1, 235, 206, 3, + 225, 170, 8, 6, 1, 235, 206, 3, 247, 214, 8, 5, 1, 235, 206, 3, 247, 214, + 8, 6, 1, 235, 206, 3, 220, 62, 8, 5, 1, 235, 206, 3, 220, 62, 8, 6, 1, + 235, 206, 3, 70, 55, 8, 5, 1, 243, 84, 75, 8, 6, 32, 231, 81, 8, 5, 32, + 231, 81, 8, 6, 1, 230, 185, 3, 246, 52, 8, 5, 1, 230, 185, 3, 246, 52, 8, + 6, 1, 230, 55, 3, 246, 231, 8, 5, 1, 230, 55, 3, 246, 231, 8, 5, 1, 228, + 231, 8, 6, 1, 228, 131, 3, 165, 8, 5, 1, 228, 131, 3, 165, 8, 6, 1, 228, + 131, 3, 246, 231, 8, 5, 1, 228, 131, 3, 246, 231, 8, 6, 1, 228, 131, 3, + 247, 29, 8, 5, 1, 228, 131, 3, 247, 29, 8, 6, 1, 228, 131, 3, 101, 243, + 85, 8, 5, 1, 228, 131, 3, 101, 243, 85, 8, 6, 1, 228, 131, 3, 95, 8, 5, + 1, 228, 131, 3, 95, 8, 6, 1, 223, 164, 3, 165, 8, 5, 1, 223, 164, 3, 165, + 8, 6, 1, 223, 164, 3, 246, 231, 8, 5, 1, 223, 164, 3, 246, 231, 8, 6, 1, + 223, 164, 3, 247, 29, 8, 5, 1, 223, 164, 3, 247, 29, 8, 5, 1, 223, 164, + 217, 251, 247, 137, 250, 160, 8, 6, 1, 241, 78, 8, 5, 1, 241, 78, 8, 6, + 1, 158, 3, 225, 170, 8, 5, 1, 158, 3, 225, 170, 8, 6, 1, 158, 3, 247, + 214, 8, 5, 1, 158, 3, 247, 214, 8, 6, 1, 158, 3, 52, 165, 8, 5, 1, 158, + 3, 52, 165, 8, 6, 32, 220, 73, 8, 5, 32, 220, 73, 8, 6, 1, 217, 1, 3, + 165, 8, 5, 1, 217, 1, 3, 165, 8, 6, 1, 217, 1, 3, 246, 231, 8, 5, 1, 217, + 1, 3, 246, 231, 8, 6, 1, 217, 1, 3, 247, 29, 8, 5, 1, 217, 1, 3, 247, 29, + 8, 6, 1, 215, 94, 3, 165, 8, 5, 1, 215, 94, 3, 165, 8, 6, 1, 215, 94, 3, + 246, 52, 8, 5, 1, 215, 94, 3, 246, 52, 8, 6, 1, 215, 94, 3, 246, 231, 8, + 5, 1, 215, 94, 3, 246, 231, 8, 6, 1, 215, 94, 3, 247, 29, 8, 5, 1, 215, + 94, 3, 247, 29, 8, 6, 1, 210, 70, 3, 246, 231, 8, 5, 1, 210, 70, 3, 246, + 231, 8, 6, 1, 210, 70, 3, 247, 29, 8, 5, 1, 210, 70, 3, 247, 29, 8, 6, 1, + 210, 70, 3, 95, 8, 5, 1, 210, 70, 3, 95, 8, 6, 1, 106, 3, 208, 227, 8, 5, + 1, 106, 3, 208, 227, 8, 6, 1, 106, 3, 225, 170, 8, 5, 1, 106, 3, 225, + 170, 8, 6, 1, 106, 3, 247, 214, 8, 5, 1, 106, 3, 247, 214, 8, 6, 1, 106, + 3, 215, 253, 55, 8, 5, 1, 106, 3, 215, 253, 55, 8, 6, 1, 106, 3, 52, 165, + 8, 5, 1, 106, 3, 52, 165, 8, 6, 1, 106, 3, 220, 62, 8, 5, 1, 106, 3, 220, + 62, 8, 6, 1, 204, 145, 3, 246, 52, 8, 5, 1, 204, 145, 3, 246, 52, 8, 6, + 1, 203, 125, 3, 246, 52, 8, 5, 1, 203, 125, 3, 246, 52, 8, 6, 1, 203, + 125, 3, 243, 231, 8, 6, 1, 202, 160, 3, 165, 8, 5, 1, 202, 160, 3, 165, + 8, 6, 1, 202, 160, 3, 70, 55, 8, 5, 1, 202, 160, 3, 70, 55, 8, 6, 1, 202, + 160, 3, 247, 29, 8, 5, 1, 202, 160, 3, 247, 29, 8, 5, 1, 163, 194, 8, 5, + 1, 66, 3, 95, 8, 6, 1, 66, 3, 113, 8, 6, 1, 66, 3, 208, 142, 8, 5, 1, 66, + 3, 208, 142, 8, 6, 1, 143, 195, 8, 5, 1, 143, 195, 8, 6, 1, 171, 78, 8, + 6, 1, 247, 126, 3, 113, 8, 5, 1, 247, 126, 3, 113, 8, 6, 1, 251, 84, 245, + 51, 8, 6, 1, 245, 52, 3, 113, 8, 6, 1, 245, 52, 3, 208, 142, 8, 5, 1, + 245, 52, 3, 208, 142, 8, 5, 1, 207, 174, 244, 37, 8, 6, 1, 216, 73, 74, + 8, 6, 1, 214, 192, 8, 6, 1, 171, 74, 8, 6, 1, 240, 175, 3, 113, 8, 5, 1, + 240, 175, 3, 113, 8, 6, 1, 239, 76, 3, 113, 8, 6, 1, 238, 235, 8, 5, 1, + 235, 255, 8, 6, 1, 230, 230, 8, 6, 1, 235, 206, 3, 95, 8, 6, 1, 230, 55, + 3, 113, 8, 5, 1, 230, 55, 3, 113, 8, 5, 1, 228, 131, 3, 142, 8, 5, 1, + 228, 26, 3, 95, 8, 6, 1, 207, 174, 226, 185, 8, 6, 1, 223, 164, 3, 49, + 113, 8, 5, 1, 223, 164, 3, 163, 50, 227, 210, 8, 6, 1, 158, 3, 101, 208, + 227, 8, 6, 1, 158, 3, 236, 53, 8, 5, 1, 158, 3, 236, 53, 8, 6, 1, 220, + 57, 8, 5, 1, 220, 57, 8, 6, 1, 219, 185, 3, 113, 8, 5, 1, 219, 185, 3, + 113, 8, 1, 202, 216, 8, 6, 1, 143, 108, 8, 5, 1, 143, 108, 8, 6, 1, 241, + 7, 8, 1, 216, 73, 241, 8, 227, 14, 8, 5, 1, 210, 70, 3, 219, 142, 113, 8, + 6, 1, 210, 70, 3, 113, 8, 5, 1, 210, 70, 3, 113, 8, 6, 1, 210, 70, 3, + 216, 79, 113, 8, 6, 1, 106, 3, 236, 53, 8, 5, 1, 106, 3, 236, 53, 8, 6, + 1, 206, 216, 8, 6, 1, 206, 165, 3, 113, 8, 6, 1, 203, 125, 3, 113, 8, 5, + 1, 203, 125, 3, 113, 8, 6, 1, 202, 160, 3, 95, 8, 5, 1, 202, 160, 3, 95, + 8, 6, 1, 240, 177, 8, 6, 1, 240, 178, 216, 72, 8, 5, 1, 240, 178, 216, + 72, 8, 5, 1, 240, 178, 3, 209, 248, 8, 1, 120, 3, 95, 8, 6, 1, 143, 170, + 8, 5, 1, 143, 170, 8, 1, 230, 239, 238, 45, 211, 62, 3, 95, 8, 1, 203, + 199, 8, 1, 244, 30, 246, 27, 8, 1, 227, 254, 246, 27, 8, 1, 250, 248, + 246, 27, 8, 1, 216, 79, 246, 27, 8, 6, 1, 242, 1, 3, 247, 29, 8, 6, 1, + 245, 52, 3, 5, 1, 202, 160, 3, 247, 29, 8, 5, 1, 242, 1, 3, 247, 29, 8, + 6, 1, 227, 81, 8, 6, 1, 228, 131, 3, 5, 1, 230, 184, 8, 5, 1, 227, 81, 8, + 6, 1, 222, 49, 8, 6, 1, 223, 164, 3, 5, 1, 230, 184, 8, 5, 1, 222, 49, 8, + 6, 1, 34, 3, 247, 29, 8, 5, 1, 34, 3, 247, 29, 8, 6, 1, 235, 206, 3, 247, + 29, 8, 5, 1, 235, 206, 3, 247, 29, 8, 6, 1, 158, 3, 247, 29, 8, 5, 1, + 158, 3, 247, 29, 8, 6, 1, 106, 3, 247, 29, 8, 5, 1, 106, 3, 247, 29, 8, + 6, 1, 106, 3, 243, 232, 25, 225, 170, 8, 5, 1, 106, 3, 243, 232, 25, 225, + 170, 8, 6, 1, 106, 3, 243, 232, 25, 165, 8, 5, 1, 106, 3, 243, 232, 25, + 165, 8, 6, 1, 106, 3, 243, 232, 25, 247, 29, 8, 5, 1, 106, 3, 243, 232, + 25, 247, 29, 8, 6, 1, 106, 3, 243, 232, 25, 237, 253, 8, 5, 1, 106, 3, + 243, 232, 25, 237, 253, 8, 5, 1, 207, 174, 74, 8, 6, 1, 34, 3, 243, 232, + 25, 225, 170, 8, 5, 1, 34, 3, 243, 232, 25, 225, 170, 8, 6, 1, 34, 3, 70, + 87, 25, 225, 170, 8, 5, 1, 34, 3, 70, 87, 25, 225, 170, 8, 6, 1, 251, + 110, 3, 225, 170, 8, 5, 1, 251, 110, 3, 225, 170, 8, 6, 1, 239, 76, 3, + 95, 8, 5, 1, 239, 76, 3, 95, 8, 6, 1, 239, 76, 3, 247, 29, 8, 5, 1, 239, + 76, 3, 247, 29, 8, 6, 1, 230, 55, 3, 247, 29, 8, 5, 1, 230, 55, 3, 247, + 29, 8, 6, 1, 158, 3, 220, 62, 8, 5, 1, 158, 3, 220, 62, 8, 6, 1, 158, 3, + 220, 63, 25, 225, 170, 8, 5, 1, 158, 3, 220, 63, 25, 225, 170, 8, 6, 1, + 240, 178, 3, 247, 29, 8, 5, 1, 240, 178, 3, 247, 29, 8, 5, 1, 230, 185, + 3, 247, 29, 8, 6, 1, 242, 0, 8, 6, 1, 245, 52, 3, 5, 1, 202, 159, 8, 5, + 1, 242, 0, 8, 6, 1, 239, 76, 3, 165, 8, 5, 1, 239, 76, 3, 165, 8, 6, 1, + 235, 252, 8, 6, 1, 203, 199, 8, 6, 1, 223, 164, 3, 237, 253, 8, 5, 1, + 223, 164, 3, 237, 253, 8, 6, 1, 34, 3, 215, 253, 87, 25, 165, 8, 5, 1, + 34, 3, 215, 253, 87, 25, 165, 8, 6, 1, 251, 110, 3, 165, 8, 5, 1, 251, + 110, 3, 165, 8, 6, 1, 158, 3, 211, 32, 25, 165, 8, 5, 1, 158, 3, 211, 32, + 25, 165, 8, 6, 1, 34, 3, 52, 237, 253, 8, 5, 1, 34, 3, 52, 237, 253, 8, + 6, 1, 34, 3, 230, 239, 247, 214, 8, 5, 1, 34, 3, 230, 239, 247, 214, 8, + 6, 1, 188, 3, 52, 237, 253, 8, 5, 1, 188, 3, 52, 237, 253, 8, 6, 1, 188, + 3, 230, 239, 247, 214, 8, 5, 1, 188, 3, 230, 239, 247, 214, 8, 6, 1, 235, + 206, 3, 52, 237, 253, 8, 5, 1, 235, 206, 3, 52, 237, 253, 8, 6, 1, 235, + 206, 3, 230, 239, 247, 214, 8, 5, 1, 235, 206, 3, 230, 239, 247, 214, 8, + 6, 1, 158, 3, 52, 237, 253, 8, 5, 1, 158, 3, 52, 237, 253, 8, 6, 1, 158, + 3, 230, 239, 247, 214, 8, 5, 1, 158, 3, 230, 239, 247, 214, 8, 6, 1, 217, + 1, 3, 52, 237, 253, 8, 5, 1, 217, 1, 3, 52, 237, 253, 8, 6, 1, 217, 1, 3, + 230, 239, 247, 214, 8, 5, 1, 217, 1, 3, 230, 239, 247, 214, 8, 6, 1, 106, + 3, 52, 237, 253, 8, 5, 1, 106, 3, 52, 237, 253, 8, 6, 1, 106, 3, 230, + 239, 247, 214, 8, 5, 1, 106, 3, 230, 239, 247, 214, 8, 6, 1, 215, 94, 3, + 245, 234, 56, 8, 5, 1, 215, 94, 3, 245, 234, 56, 8, 6, 1, 210, 70, 3, + 245, 234, 56, 8, 5, 1, 210, 70, 3, 245, 234, 56, 8, 6, 1, 202, 234, 8, 5, + 1, 202, 234, 8, 6, 1, 237, 172, 3, 247, 29, 8, 5, 1, 237, 172, 3, 247, + 29, 8, 6, 1, 223, 164, 3, 163, 50, 227, 210, 8, 5, 1, 245, 52, 3, 245, + 95, 8, 6, 1, 219, 216, 8, 5, 1, 219, 216, 8, 6, 1, 202, 160, 3, 113, 8, + 5, 1, 202, 160, 3, 113, 8, 6, 1, 34, 3, 70, 55, 8, 5, 1, 34, 3, 70, 55, + 8, 6, 1, 188, 3, 246, 231, 8, 5, 1, 188, 3, 246, 231, 8, 6, 1, 158, 3, + 243, 232, 25, 225, 170, 8, 5, 1, 158, 3, 243, 232, 25, 225, 170, 8, 6, 1, + 158, 3, 208, 228, 25, 225, 170, 8, 5, 1, 158, 3, 208, 228, 25, 225, 170, + 8, 6, 1, 158, 3, 70, 55, 8, 5, 1, 158, 3, 70, 55, 8, 6, 1, 158, 3, 70, + 87, 25, 225, 170, 8, 5, 1, 158, 3, 70, 87, 25, 225, 170, 8, 6, 1, 203, + 125, 3, 225, 170, 8, 5, 1, 203, 125, 3, 225, 170, 8, 5, 1, 228, 131, 3, + 245, 95, 8, 5, 1, 223, 164, 3, 245, 95, 8, 5, 1, 210, 70, 3, 245, 95, 8, + 5, 1, 243, 84, 230, 184, 8, 5, 1, 244, 130, 243, 191, 8, 5, 1, 217, 66, + 243, 191, 8, 6, 1, 34, 3, 95, 8, 6, 1, 247, 126, 3, 95, 8, 5, 1, 247, + 126, 3, 95, 8, 6, 1, 228, 131, 3, 142, 8, 6, 1, 210, 70, 3, 243, 228, 95, + 8, 5, 1, 215, 94, 3, 210, 169, 209, 248, 8, 5, 1, 202, 160, 3, 210, 169, + 209, 248, 8, 6, 1, 238, 45, 211, 61, 8, 5, 1, 238, 45, 211, 61, 8, 6, 1, + 66, 3, 95, 8, 6, 1, 106, 142, 8, 6, 1, 207, 174, 206, 164, 8, 6, 1, 188, + 3, 95, 8, 5, 1, 188, 3, 95, 8, 6, 1, 230, 185, 3, 95, 8, 5, 1, 230, 185, + 3, 95, 8, 6, 1, 5, 217, 135, 3, 236, 116, 209, 248, 8, 5, 1, 217, 135, 3, + 236, 116, 209, 248, 8, 6, 1, 217, 1, 3, 95, 8, 5, 1, 217, 1, 3, 95, 8, 6, + 1, 203, 125, 3, 95, 8, 5, 1, 203, 125, 3, 95, 8, 5, 1, 207, 174, 63, 8, + 5, 1, 251, 2, 8, 5, 1, 207, 174, 251, 2, 8, 5, 1, 66, 3, 113, 8, 5, 1, + 171, 78, 8, 5, 1, 247, 126, 3, 245, 95, 8, 5, 1, 245, 52, 3, 209, 248, 8, + 5, 1, 245, 52, 3, 113, 8, 5, 1, 216, 73, 74, 8, 5, 1, 214, 192, 8, 5, 1, + 214, 193, 3, 113, 8, 5, 1, 171, 74, 8, 5, 1, 216, 73, 171, 74, 8, 5, 1, + 216, 73, 171, 188, 3, 113, 8, 5, 1, 246, 16, 216, 73, 171, 74, 8, 5, 1, + 243, 84, 230, 185, 3, 95, 8, 5, 1, 239, 76, 3, 113, 8, 5, 1, 132, 239, + 75, 8, 1, 5, 6, 239, 75, 8, 5, 1, 238, 235, 8, 5, 1, 216, 182, 236, 53, + 8, 5, 1, 207, 174, 237, 171, 8, 5, 1, 237, 172, 3, 113, 8, 5, 1, 237, 32, + 3, 113, 8, 5, 1, 235, 206, 3, 95, 8, 5, 1, 230, 230, 8, 1, 5, 6, 75, 8, + 5, 1, 228, 131, 3, 101, 208, 227, 8, 5, 1, 228, 131, 3, 248, 124, 8, 5, + 1, 228, 131, 3, 216, 79, 113, 8, 5, 1, 227, 164, 8, 5, 1, 207, 174, 226, + 185, 8, 5, 1, 207, 174, 226, 186, 3, 163, 227, 210, 8, 5, 1, 226, 186, 3, + 113, 8, 5, 1, 223, 164, 3, 49, 113, 8, 5, 1, 223, 164, 3, 216, 79, 113, + 8, 1, 5, 6, 223, 163, 8, 5, 1, 248, 225, 78, 8, 1, 5, 6, 220, 73, 8, 5, + 1, 246, 16, 220, 36, 8, 5, 1, 218, 192, 8, 5, 1, 207, 174, 146, 8, 5, 1, + 207, 174, 217, 1, 3, 163, 227, 210, 8, 5, 1, 207, 174, 217, 1, 3, 113, 8, + 5, 1, 217, 1, 3, 163, 227, 210, 8, 5, 1, 217, 1, 3, 209, 248, 8, 5, 1, + 217, 1, 3, 239, 240, 8, 5, 1, 216, 73, 217, 1, 3, 239, 240, 8, 1, 5, 6, + 146, 8, 1, 5, 6, 230, 239, 146, 8, 5, 1, 215, 94, 3, 113, 8, 5, 1, 241, + 7, 8, 5, 1, 243, 84, 230, 185, 3, 211, 32, 25, 113, 8, 5, 1, 211, 174, + 216, 73, 241, 7, 8, 5, 1, 241, 8, 3, 245, 95, 8, 5, 1, 207, 174, 210, 69, + 8, 5, 1, 210, 70, 3, 216, 79, 113, 8, 5, 1, 106, 142, 8, 5, 1, 206, 216, + 8, 5, 1, 206, 165, 3, 113, 8, 5, 1, 207, 174, 206, 164, 8, 5, 1, 207, + 174, 204, 144, 8, 5, 1, 207, 174, 203, 124, 8, 1, 5, 6, 203, 124, 8, 5, + 1, 202, 160, 3, 216, 79, 113, 8, 5, 1, 202, 160, 3, 245, 95, 8, 5, 1, + 240, 177, 8, 5, 1, 240, 178, 3, 245, 95, 8, 1, 238, 45, 211, 61, 8, 1, + 218, 199, 205, 186, 239, 126, 8, 1, 230, 239, 238, 45, 211, 61, 8, 1, + 211, 40, 247, 125, 8, 1, 248, 70, 246, 27, 8, 1, 5, 6, 249, 255, 8, 5, 1, + 246, 16, 171, 74, 8, 1, 5, 6, 239, 76, 3, 113, 8, 1, 5, 6, 237, 171, 8, + 5, 1, 230, 185, 3, 245, 126, 8, 5, 1, 207, 174, 230, 54, 8, 1, 5, 6, 159, + 8, 5, 1, 217, 135, 3, 113, 8, 1, 238, 45, 211, 62, 3, 95, 8, 1, 216, 73, + 238, 45, 211, 62, 3, 95, 8, 5, 1, 242, 1, 243, 191, 8, 5, 1, 244, 3, 243, + 191, 8, 5, 1, 242, 1, 243, 192, 3, 245, 95, 8, 5, 1, 208, 22, 243, 191, + 8, 5, 1, 209, 137, 243, 191, 8, 5, 1, 209, 194, 243, 192, 3, 245, 95, 8, + 5, 1, 240, 39, 243, 191, 8, 5, 1, 226, 241, 243, 191, 8, 5, 1, 226, 187, + 243, 191, 8, 1, 248, 70, 218, 245, 8, 1, 248, 78, 218, 245, 8, 5, 1, 207, + 174, 237, 172, 3, 239, 240, 8, 5, 1, 207, 174, 237, 172, 3, 239, 241, 25, + 209, 248, 65, 1, 5, 237, 171, 65, 1, 5, 237, 172, 3, 113, 65, 1, 5, 230, + 184, 65, 1, 5, 146, 65, 1, 5, 207, 174, 146, 65, 1, 5, 207, 174, 217, 1, + 3, 113, 65, 1, 5, 6, 230, 239, 146, 65, 1, 5, 204, 144, 65, 1, 5, 203, + 124, 65, 1, 217, 236, 65, 1, 52, 217, 236, 65, 1, 207, 174, 245, 233, 65, + 1, 250, 160, 65, 1, 216, 73, 245, 233, 65, 1, 50, 162, 215, 252, 65, 1, + 49, 162, 215, 252, 65, 1, 238, 45, 211, 61, 65, 1, 216, 73, 238, 45, 211, + 61, 65, 1, 49, 250, 94, 65, 1, 50, 250, 94, 65, 1, 112, 250, 94, 65, 1, + 121, 250, 94, 65, 1, 246, 53, 251, 138, 247, 29, 65, 1, 80, 227, 114, 65, + 1, 225, 170, 65, 1, 251, 126, 251, 138, 65, 1, 237, 254, 251, 138, 65, 1, + 124, 80, 227, 114, 65, 1, 124, 225, 170, 65, 1, 124, 237, 254, 251, 138, + 65, 1, 124, 251, 126, 251, 138, 65, 1, 208, 82, 245, 242, 65, 1, 162, + 208, 82, 245, 242, 65, 1, 246, 216, 50, 162, 215, 252, 65, 1, 246, 216, + 49, 162, 215, 252, 65, 1, 112, 210, 3, 65, 1, 121, 210, 3, 65, 1, 91, 54, + 65, 1, 224, 103, 54, 247, 214, 70, 55, 215, 253, 55, 220, 62, 5, 208, + 227, 52, 251, 126, 251, 138, 65, 1, 216, 58, 113, 65, 1, 245, 131, 251, + 138, 65, 1, 5, 238, 235, 65, 1, 5, 159, 65, 1, 5, 194, 65, 1, 5, 203, + 196, 65, 1, 5, 216, 73, 238, 45, 211, 61, 65, 1, 240, 198, 143, 142, 65, + 1, 138, 143, 142, 65, 1, 224, 150, 143, 142, 65, 1, 124, 143, 142, 65, 1, + 240, 197, 143, 142, 65, 1, 203, 1, 244, 27, 143, 82, 65, 1, 203, 77, 244, + 27, 143, 82, 65, 1, 205, 184, 65, 1, 206, 251, 65, 1, 52, 250, 160, 65, + 1, 124, 121, 250, 94, 65, 1, 124, 112, 250, 94, 65, 1, 124, 49, 250, 94, + 65, 1, 124, 50, 250, 94, 65, 1, 124, 215, 252, 65, 1, 101, 237, 254, 251, + 138, 65, 1, 101, 52, 237, 254, 251, 138, 65, 1, 101, 52, 251, 126, 251, + 138, 65, 1, 124, 208, 227, 65, 1, 216, 188, 245, 242, 65, 1, 248, 142, + 138, 208, 161, 65, 1, 241, 84, 138, 208, 161, 65, 1, 248, 142, 124, 208, + 161, 65, 1, 241, 84, 124, 208, 161, 65, 1, 213, 34, 65, 1, 171, 213, 34, + 65, 1, 124, 49, 47, 39, 237, 254, 251, 138, 39, 251, 126, 251, 138, 39, + 246, 53, 251, 138, 39, 208, 227, 39, 225, 170, 39, 219, 198, 39, 247, + 214, 39, 70, 55, 39, 243, 231, 39, 236, 116, 55, 39, 215, 253, 55, 39, + 52, 251, 126, 251, 138, 39, 247, 29, 39, 80, 227, 115, 55, 39, 52, 80, + 227, 115, 55, 39, 52, 237, 254, 251, 138, 39, 247, 52, 39, 230, 239, 247, + 214, 39, 207, 174, 245, 234, 55, 39, 245, 234, 55, 39, 216, 73, 245, 234, + 55, 39, 245, 234, 87, 216, 16, 39, 237, 254, 251, 139, 56, 39, 251, 126, + 251, 139, 56, 39, 49, 210, 4, 56, 39, 50, 210, 4, 56, 39, 49, 250, 218, + 55, 39, 236, 53, 39, 49, 162, 215, 253, 56, 39, 112, 210, 4, 56, 39, 121, + 210, 4, 56, 39, 91, 2, 56, 39, 224, 103, 2, 56, 39, 219, 140, 236, 116, + 56, 39, 216, 79, 236, 116, 56, 39, 70, 56, 39, 243, 232, 56, 39, 215, + 253, 56, 39, 245, 234, 56, 39, 246, 231, 39, 220, 62, 39, 80, 227, 115, + 56, 39, 247, 208, 56, 39, 230, 239, 52, 250, 127, 56, 39, 247, 30, 56, + 39, 246, 53, 251, 139, 56, 39, 247, 215, 56, 39, 230, 239, 247, 215, 56, + 39, 208, 228, 56, 39, 225, 171, 56, 39, 124, 227, 114, 39, 52, 124, 227, + 114, 39, 208, 228, 219, 199, 39, 212, 228, 211, 32, 219, 199, 39, 163, + 211, 32, 219, 199, 39, 212, 228, 212, 1, 219, 199, 39, 163, 212, 1, 219, + 199, 39, 50, 162, 215, 253, 56, 39, 230, 239, 247, 208, 56, 39, 51, 56, + 39, 214, 176, 56, 39, 203, 197, 55, 39, 80, 208, 227, 39, 52, 219, 198, + 39, 237, 254, 143, 82, 39, 251, 126, 143, 82, 39, 30, 218, 239, 39, 30, + 228, 252, 39, 30, 243, 225, 208, 149, 39, 30, 202, 221, 39, 247, 208, 55, + 39, 241, 35, 2, 56, 39, 52, 80, 227, 115, 56, 39, 49, 250, 218, 56, 39, + 221, 166, 208, 228, 55, 39, 236, 122, 55, 39, 251, 7, 156, 208, 173, 55, + 39, 49, 50, 53, 56, 39, 177, 53, 56, 39, 238, 4, 230, 96, 39, 50, 250, + 95, 55, 39, 49, 162, 215, 253, 55, 39, 240, 36, 39, 203, 197, 56, 39, 49, + 250, 95, 56, 39, 50, 250, 95, 56, 39, 50, 250, 95, 25, 112, 250, 95, 56, + 39, 50, 162, 215, 253, 55, 39, 70, 87, 216, 16, 39, 250, 60, 56, 39, 52, + 215, 253, 56, 39, 202, 30, 55, 39, 52, 247, 215, 56, 39, 52, 247, 214, + 39, 52, 225, 170, 39, 52, 225, 171, 56, 39, 52, 208, 227, 39, 52, 230, + 239, 247, 214, 39, 52, 86, 53, 56, 39, 8, 5, 1, 63, 39, 8, 5, 1, 74, 39, + 8, 5, 1, 75, 39, 8, 5, 1, 78, 39, 8, 5, 1, 68, 39, 8, 5, 1, 247, 125, 39, + 8, 5, 1, 245, 51, 39, 8, 5, 1, 237, 171, 39, 8, 5, 1, 226, 185, 39, 8, 5, + 1, 146, 39, 8, 5, 1, 210, 69, 39, 8, 5, 1, 206, 164, 39, 8, 5, 1, 203, + 196, 30, 6, 1, 237, 20, 30, 5, 1, 237, 20, 30, 6, 1, 250, 126, 214, 246, + 30, 5, 1, 250, 126, 214, 246, 30, 221, 44, 54, 30, 226, 251, 221, 44, 54, + 30, 6, 1, 219, 126, 243, 199, 30, 5, 1, 219, 126, 243, 199, 30, 202, 221, + 30, 5, 216, 73, 226, 221, 212, 145, 97, 30, 5, 242, 83, 226, 221, 212, + 145, 97, 30, 5, 216, 73, 242, 83, 226, 221, 212, 145, 97, 30, 217, 47, + 82, 30, 6, 1, 202, 227, 30, 208, 149, 30, 243, 225, 208, 149, 30, 6, 1, + 251, 3, 3, 208, 149, 30, 250, 203, 209, 163, 30, 6, 1, 241, 38, 3, 208, + 149, 30, 6, 1, 240, 249, 3, 208, 149, 30, 6, 1, 230, 231, 3, 208, 149, + 30, 6, 1, 220, 35, 3, 208, 149, 30, 6, 1, 206, 217, 3, 208, 149, 30, 6, + 1, 220, 37, 3, 208, 149, 30, 5, 1, 230, 231, 3, 243, 225, 25, 208, 149, + 30, 6, 1, 251, 2, 30, 6, 1, 248, 106, 30, 6, 1, 238, 235, 30, 6, 1, 244, + 37, 30, 6, 1, 241, 37, 30, 6, 1, 202, 83, 30, 6, 1, 240, 248, 30, 6, 1, + 209, 74, 30, 6, 1, 230, 230, 30, 6, 1, 229, 247, 30, 6, 1, 228, 24, 30, + 6, 1, 223, 246, 30, 6, 1, 221, 84, 30, 6, 1, 203, 170, 30, 6, 1, 220, 34, + 30, 6, 1, 218, 167, 30, 6, 1, 216, 59, 30, 6, 1, 212, 144, 30, 6, 1, 209, + 207, 30, 6, 1, 206, 216, 30, 6, 1, 218, 192, 30, 6, 1, 246, 142, 30, 6, + 1, 217, 202, 30, 6, 1, 220, 36, 30, 6, 1, 230, 231, 3, 243, 224, 30, 6, + 1, 206, 217, 3, 243, 224, 30, 5, 1, 251, 3, 3, 208, 149, 30, 5, 1, 241, + 38, 3, 208, 149, 30, 5, 1, 240, 249, 3, 208, 149, 30, 5, 1, 230, 231, 3, + 208, 149, 30, 5, 1, 206, 217, 3, 243, 225, 25, 208, 149, 30, 5, 1, 251, + 2, 30, 5, 1, 248, 106, 30, 5, 1, 238, 235, 30, 5, 1, 244, 37, 30, 5, 1, + 241, 37, 30, 5, 1, 202, 83, 30, 5, 1, 240, 248, 30, 5, 1, 209, 74, 30, 5, + 1, 230, 230, 30, 5, 1, 229, 247, 30, 5, 1, 228, 24, 30, 5, 1, 223, 246, + 30, 5, 1, 221, 84, 30, 5, 1, 203, 170, 30, 5, 1, 220, 34, 30, 5, 1, 218, + 167, 30, 5, 1, 216, 59, 30, 5, 1, 46, 212, 144, 30, 5, 1, 212, 144, 30, + 5, 1, 209, 207, 30, 5, 1, 206, 216, 30, 5, 1, 218, 192, 30, 5, 1, 246, + 142, 30, 5, 1, 217, 202, 30, 5, 1, 220, 36, 30, 5, 1, 230, 231, 3, 243, + 224, 30, 5, 1, 206, 217, 3, 243, 224, 30, 5, 1, 220, 35, 3, 208, 149, 30, + 5, 1, 206, 217, 3, 208, 149, 30, 5, 1, 220, 37, 3, 208, 149, 30, 6, 230, + 19, 97, 30, 248, 107, 97, 30, 209, 75, 97, 30, 206, 217, 3, 236, 116, 97, + 30, 206, 217, 3, 251, 126, 25, 236, 116, 97, 30, 206, 217, 3, 243, 232, + 25, 236, 116, 97, 30, 218, 193, 97, 30, 218, 168, 97, 30, 230, 19, 97, + 30, 1, 250, 126, 229, 0, 30, 5, 1, 250, 126, 229, 0, 30, 1, 211, 71, 30, + 5, 1, 211, 71, 30, 1, 243, 199, 30, 5, 1, 243, 199, 30, 1, 229, 0, 30, 5, + 1, 229, 0, 30, 1, 214, 246, 30, 5, 1, 214, 246, 84, 6, 1, 213, 35, 84, 5, + 1, 213, 35, 84, 6, 1, 240, 45, 84, 5, 1, 240, 45, 84, 6, 1, 229, 127, 84, + 5, 1, 229, 127, 84, 6, 1, 236, 107, 84, 5, 1, 236, 107, 84, 6, 1, 238, + 230, 84, 5, 1, 238, 230, 84, 6, 1, 213, 1, 84, 5, 1, 213, 1, 84, 6, 1, + 244, 52, 84, 5, 1, 244, 52, 30, 229, 248, 97, 30, 216, 60, 97, 30, 226, + 221, 212, 145, 97, 30, 1, 202, 227, 30, 6, 209, 75, 97, 30, 226, 221, + 241, 38, 97, 30, 216, 73, 226, 221, 241, 38, 97, 30, 6, 1, 212, 242, 30, + 5, 1, 212, 242, 30, 6, 226, 221, 212, 145, 97, 30, 6, 1, 214, 243, 30, 5, + 1, 214, 243, 30, 216, 60, 3, 211, 32, 97, 30, 6, 216, 73, 226, 221, 212, + 145, 97, 30, 6, 242, 83, 226, 221, 212, 145, 97, 30, 6, 216, 73, 242, 83, + 226, 221, 212, 145, 97, 36, 6, 1, 231, 111, 3, 237, 253, 36, 6, 1, 230, + 234, 36, 6, 1, 243, 130, 36, 6, 1, 238, 52, 36, 6, 1, 207, 11, 231, 110, + 36, 6, 1, 241, 252, 36, 6, 1, 247, 135, 75, 36, 6, 1, 203, 11, 36, 6, 1, + 230, 161, 36, 6, 1, 227, 80, 36, 6, 1, 222, 41, 36, 6, 1, 208, 8, 36, 6, + 1, 229, 49, 36, 6, 1, 235, 206, 3, 237, 253, 36, 6, 1, 212, 228, 68, 36, + 6, 1, 241, 248, 36, 6, 1, 63, 36, 6, 1, 248, 162, 36, 6, 1, 206, 55, 36, + 6, 1, 238, 105, 36, 6, 1, 244, 75, 36, 6, 1, 231, 110, 36, 6, 1, 202, 71, + 36, 6, 1, 202, 92, 36, 6, 1, 75, 36, 6, 1, 212, 228, 75, 36, 6, 1, 173, + 36, 6, 1, 241, 122, 36, 6, 1, 241, 103, 36, 6, 1, 241, 92, 36, 6, 1, 78, + 36, 6, 1, 219, 34, 36, 6, 1, 241, 28, 36, 6, 1, 241, 17, 36, 6, 1, 209, + 187, 36, 6, 1, 68, 36, 6, 1, 241, 154, 36, 6, 1, 152, 36, 6, 1, 208, 14, + 36, 6, 1, 246, 170, 36, 6, 1, 213, 90, 36, 6, 1, 213, 46, 36, 6, 1, 237, + 91, 54, 36, 6, 1, 203, 30, 36, 6, 1, 212, 7, 54, 36, 6, 1, 74, 36, 6, 1, + 202, 213, 36, 6, 1, 198, 36, 5, 1, 63, 36, 5, 1, 248, 162, 36, 5, 1, 206, + 55, 36, 5, 1, 238, 105, 36, 5, 1, 244, 75, 36, 5, 1, 231, 110, 36, 5, 1, + 202, 71, 36, 5, 1, 202, 92, 36, 5, 1, 75, 36, 5, 1, 212, 228, 75, 36, 5, + 1, 173, 36, 5, 1, 241, 122, 36, 5, 1, 241, 103, 36, 5, 1, 241, 92, 36, 5, + 1, 78, 36, 5, 1, 219, 34, 36, 5, 1, 241, 28, 36, 5, 1, 241, 17, 36, 5, 1, + 209, 187, 36, 5, 1, 68, 36, 5, 1, 241, 154, 36, 5, 1, 152, 36, 5, 1, 208, + 14, 36, 5, 1, 246, 170, 36, 5, 1, 213, 90, 36, 5, 1, 213, 46, 36, 5, 1, + 237, 91, 54, 36, 5, 1, 203, 30, 36, 5, 1, 212, 7, 54, 36, 5, 1, 74, 36, + 5, 1, 202, 213, 36, 5, 1, 198, 36, 5, 1, 231, 111, 3, 237, 253, 36, 5, 1, + 230, 234, 36, 5, 1, 243, 130, 36, 5, 1, 238, 52, 36, 5, 1, 207, 11, 231, + 110, 36, 5, 1, 241, 252, 36, 5, 1, 247, 135, 75, 36, 5, 1, 203, 11, 36, + 5, 1, 230, 161, 36, 5, 1, 227, 80, 36, 5, 1, 222, 41, 36, 5, 1, 208, 8, + 36, 5, 1, 229, 49, 36, 5, 1, 235, 206, 3, 237, 253, 36, 5, 1, 212, 228, + 68, 36, 5, 1, 241, 248, 36, 6, 1, 220, 36, 36, 5, 1, 220, 36, 36, 6, 1, + 203, 66, 36, 5, 1, 203, 66, 36, 6, 1, 230, 228, 74, 36, 5, 1, 230, 228, + 74, 36, 6, 1, 227, 86, 202, 183, 36, 5, 1, 227, 86, 202, 183, 36, 6, 1, + 230, 228, 227, 86, 202, 183, 36, 5, 1, 230, 228, 227, 86, 202, 183, 36, + 6, 1, 248, 73, 202, 183, 36, 5, 1, 248, 73, 202, 183, 36, 6, 1, 230, 228, + 248, 73, 202, 183, 36, 5, 1, 230, 228, 248, 73, 202, 183, 36, 6, 1, 228, + 225, 36, 5, 1, 228, 225, 36, 6, 1, 217, 202, 36, 5, 1, 217, 202, 36, 6, + 1, 239, 235, 36, 5, 1, 239, 235, 36, 6, 1, 230, 186, 36, 5, 1, 230, 186, + 36, 6, 1, 230, 187, 3, 52, 237, 254, 251, 138, 36, 5, 1, 230, 187, 3, 52, + 237, 254, 251, 138, 36, 6, 1, 207, 14, 36, 5, 1, 207, 14, 36, 6, 1, 215, + 191, 220, 36, 36, 5, 1, 215, 191, 220, 36, 36, 6, 1, 220, 37, 3, 208, + 197, 36, 5, 1, 220, 37, 3, 208, 197, 36, 6, 1, 219, 224, 36, 5, 1, 219, + 224, 36, 6, 1, 229, 0, 36, 5, 1, 229, 0, 36, 209, 35, 54, 39, 36, 208, + 197, 39, 36, 219, 141, 39, 36, 244, 142, 218, 71, 39, 36, 217, 196, 218, + 71, 39, 36, 218, 55, 39, 36, 236, 12, 209, 35, 54, 39, 36, 224, 114, 54, + 36, 6, 1, 212, 228, 235, 206, 3, 209, 248, 36, 5, 1, 212, 228, 235, 206, + 3, 209, 248, 36, 6, 1, 213, 139, 54, 36, 5, 1, 213, 139, 54, 36, 6, 1, + 241, 29, 3, 208, 254, 36, 5, 1, 241, 29, 3, 208, 254, 36, 6, 1, 238, 106, + 3, 206, 215, 36, 5, 1, 238, 106, 3, 206, 215, 36, 6, 1, 238, 106, 3, 95, + 36, 5, 1, 238, 106, 3, 95, 36, 6, 1, 238, 106, 3, 101, 113, 36, 5, 1, + 238, 106, 3, 101, 113, 36, 6, 1, 202, 72, 3, 244, 20, 36, 5, 1, 202, 72, + 3, 244, 20, 36, 6, 1, 202, 93, 3, 244, 20, 36, 5, 1, 202, 93, 3, 244, 20, + 36, 6, 1, 230, 44, 3, 244, 20, 36, 5, 1, 230, 44, 3, 244, 20, 36, 6, 1, + 230, 44, 3, 80, 95, 36, 5, 1, 230, 44, 3, 80, 95, 36, 6, 1, 230, 44, 3, + 95, 36, 5, 1, 230, 44, 3, 95, 36, 6, 1, 248, 214, 173, 36, 5, 1, 248, + 214, 173, 36, 6, 1, 241, 93, 3, 244, 20, 36, 5, 1, 241, 93, 3, 244, 20, + 36, 6, 32, 241, 93, 238, 105, 36, 5, 32, 241, 93, 238, 105, 36, 6, 1, + 219, 35, 3, 101, 113, 36, 5, 1, 219, 35, 3, 101, 113, 36, 6, 1, 251, 145, + 152, 36, 5, 1, 251, 145, 152, 36, 6, 1, 241, 18, 3, 244, 20, 36, 5, 1, + 241, 18, 3, 244, 20, 36, 6, 1, 209, 188, 3, 244, 20, 36, 5, 1, 209, 188, + 3, 244, 20, 36, 6, 1, 211, 53, 68, 36, 5, 1, 211, 53, 68, 36, 6, 1, 211, + 53, 106, 3, 95, 36, 5, 1, 211, 53, 106, 3, 95, 36, 6, 1, 237, 160, 3, + 244, 20, 36, 5, 1, 237, 160, 3, 244, 20, 36, 6, 32, 209, 188, 208, 14, + 36, 5, 32, 209, 188, 208, 14, 36, 6, 1, 246, 171, 3, 244, 20, 36, 5, 1, + 246, 171, 3, 244, 20, 36, 6, 1, 246, 171, 3, 80, 95, 36, 5, 1, 246, 171, + 3, 80, 95, 36, 6, 1, 213, 12, 36, 5, 1, 213, 12, 36, 6, 1, 251, 145, 246, + 170, 36, 5, 1, 251, 145, 246, 170, 36, 6, 1, 251, 145, 246, 171, 3, 244, + 20, 36, 5, 1, 251, 145, 246, 171, 3, 244, 20, 36, 1, 219, 133, 36, 6, 1, + 202, 72, 3, 247, 214, 36, 5, 1, 202, 72, 3, 247, 214, 36, 6, 1, 230, 44, + 3, 113, 36, 5, 1, 230, 44, 3, 113, 36, 6, 1, 241, 123, 3, 209, 248, 36, + 5, 1, 241, 123, 3, 209, 248, 36, 6, 1, 241, 93, 3, 113, 36, 5, 1, 241, + 93, 3, 113, 36, 6, 1, 241, 93, 3, 209, 248, 36, 5, 1, 241, 93, 3, 209, + 248, 36, 6, 1, 229, 138, 246, 170, 36, 5, 1, 229, 138, 246, 170, 36, 6, + 1, 241, 104, 3, 209, 248, 36, 5, 1, 241, 104, 3, 209, 248, 36, 5, 1, 219, + 133, 36, 6, 1, 34, 3, 247, 214, 36, 5, 1, 34, 3, 247, 214, 36, 6, 1, 34, + 3, 243, 231, 36, 5, 1, 34, 3, 243, 231, 36, 6, 32, 34, 231, 110, 36, 5, + 32, 34, 231, 110, 36, 6, 1, 231, 111, 3, 247, 214, 36, 5, 1, 231, 111, 3, + 247, 214, 36, 6, 1, 214, 192, 36, 5, 1, 214, 192, 36, 6, 1, 214, 193, 3, + 243, 231, 36, 5, 1, 214, 193, 3, 243, 231, 36, 6, 1, 202, 72, 3, 243, + 231, 36, 5, 1, 202, 72, 3, 243, 231, 36, 6, 1, 202, 93, 3, 243, 231, 36, + 5, 1, 202, 93, 3, 243, 231, 36, 6, 1, 251, 145, 241, 252, 36, 5, 1, 251, + 145, 241, 252, 36, 6, 1, 235, 206, 3, 225, 170, 36, 5, 1, 235, 206, 3, + 225, 170, 36, 6, 1, 235, 206, 3, 243, 231, 36, 5, 1, 235, 206, 3, 243, + 231, 36, 6, 1, 158, 3, 243, 231, 36, 5, 1, 158, 3, 243, 231, 36, 6, 1, + 248, 225, 78, 36, 5, 1, 248, 225, 78, 36, 6, 1, 248, 225, 158, 3, 243, + 231, 36, 5, 1, 248, 225, 158, 3, 243, 231, 36, 6, 1, 188, 3, 243, 231, + 36, 5, 1, 188, 3, 243, 231, 36, 6, 1, 106, 3, 225, 170, 36, 5, 1, 106, 3, + 225, 170, 36, 6, 1, 106, 3, 243, 231, 36, 5, 1, 106, 3, 243, 231, 36, 6, + 1, 106, 3, 52, 165, 36, 5, 1, 106, 3, 52, 165, 36, 6, 1, 246, 171, 3, + 243, 231, 36, 5, 1, 246, 171, 3, 243, 231, 36, 6, 1, 238, 106, 3, 244, + 20, 36, 5, 1, 238, 106, 3, 244, 20, 36, 6, 1, 203, 31, 3, 243, 231, 36, + 5, 1, 203, 31, 3, 243, 231, 36, 6, 1, 238, 106, 3, 211, 32, 25, 113, 36, + 5, 1, 238, 106, 3, 211, 32, 25, 113, 36, 6, 1, 237, 160, 3, 113, 36, 5, + 1, 237, 160, 3, 113, 36, 6, 1, 237, 160, 3, 95, 36, 5, 1, 237, 160, 3, + 95, 36, 6, 1, 229, 10, 244, 75, 36, 5, 1, 229, 10, 244, 75, 36, 6, 1, + 229, 10, 243, 130, 36, 5, 1, 229, 10, 243, 130, 36, 6, 1, 229, 10, 202, + 21, 36, 5, 1, 229, 10, 202, 21, 36, 6, 1, 229, 10, 241, 244, 36, 5, 1, + 229, 10, 241, 244, 36, 6, 1, 229, 10, 227, 80, 36, 5, 1, 229, 10, 227, + 80, 36, 6, 1, 229, 10, 222, 41, 36, 5, 1, 229, 10, 222, 41, 36, 6, 1, + 229, 10, 212, 71, 36, 5, 1, 229, 10, 212, 71, 36, 6, 1, 229, 10, 208, + 191, 36, 5, 1, 229, 10, 208, 191, 36, 6, 1, 216, 73, 202, 92, 36, 5, 1, + 216, 73, 202, 92, 36, 6, 1, 241, 123, 3, 113, 36, 5, 1, 241, 123, 3, 113, + 36, 6, 1, 227, 161, 36, 5, 1, 227, 161, 36, 6, 1, 216, 61, 36, 5, 1, 216, + 61, 36, 6, 1, 203, 99, 36, 5, 1, 203, 99, 36, 6, 1, 217, 126, 36, 5, 1, + 217, 126, 36, 6, 1, 204, 62, 36, 5, 1, 204, 62, 36, 6, 1, 251, 26, 173, + 36, 5, 1, 251, 26, 173, 36, 6, 1, 241, 123, 3, 101, 113, 36, 5, 1, 241, + 123, 3, 101, 113, 36, 6, 1, 241, 93, 3, 101, 113, 36, 5, 1, 241, 93, 3, + 101, 113, 36, 6, 1, 219, 35, 3, 244, 20, 36, 5, 1, 219, 35, 3, 244, 20, + 36, 6, 1, 213, 13, 3, 244, 20, 36, 5, 1, 213, 13, 3, 244, 20, 36, 6, 1, + 241, 93, 3, 49, 113, 36, 5, 1, 241, 93, 3, 49, 113, 36, 6, 1, 241, 237, + 36, 5, 1, 241, 237, 36, 6, 1, 244, 124, 36, 5, 1, 244, 124, 36, 6, 1, + 241, 123, 3, 244, 20, 36, 5, 1, 241, 123, 3, 244, 20, 178, 6, 1, 250, 5, + 178, 6, 1, 248, 122, 178, 6, 1, 238, 69, 178, 6, 1, 244, 212, 178, 6, 1, + 241, 167, 178, 6, 1, 202, 116, 178, 6, 1, 241, 147, 178, 6, 1, 240, 250, + 178, 6, 1, 135, 178, 6, 1, 202, 71, 178, 6, 1, 231, 19, 178, 6, 1, 227, + 83, 178, 6, 1, 203, 174, 178, 6, 1, 247, 92, 178, 6, 1, 229, 180, 178, 6, + 1, 236, 136, 178, 6, 1, 230, 181, 178, 6, 1, 238, 116, 178, 6, 1, 246, + 160, 178, 6, 1, 224, 240, 178, 6, 1, 203, 11, 178, 6, 1, 221, 152, 178, + 6, 1, 213, 90, 178, 6, 1, 205, 189, 178, 6, 1, 246, 199, 178, 6, 1, 219, + 16, 178, 6, 1, 230, 144, 178, 6, 1, 216, 220, 178, 6, 1, 214, 155, 178, + 6, 1, 205, 234, 178, 6, 1, 208, 194, 178, 6, 1, 216, 122, 178, 6, 1, 245, + 254, 178, 6, 1, 202, 252, 178, 6, 1, 218, 102, 178, 6, 1, 229, 191, 178, + 6, 1, 220, 60, 178, 6, 1, 240, 47, 178, 65, 1, 49, 162, 215, 252, 178, + 250, 160, 178, 241, 96, 82, 178, 240, 212, 82, 178, 245, 233, 178, 217, + 47, 82, 178, 251, 146, 82, 178, 5, 1, 250, 5, 178, 5, 1, 248, 122, 178, + 5, 1, 238, 69, 178, 5, 1, 244, 212, 178, 5, 1, 241, 167, 178, 5, 1, 202, + 116, 178, 5, 1, 241, 147, 178, 5, 1, 240, 250, 178, 5, 1, 135, 178, 5, 1, + 202, 71, 178, 5, 1, 231, 19, 178, 5, 1, 227, 83, 178, 5, 1, 203, 174, + 178, 5, 1, 247, 92, 178, 5, 1, 229, 180, 178, 5, 1, 236, 136, 178, 5, 1, + 230, 181, 178, 5, 1, 238, 116, 178, 5, 1, 246, 160, 178, 5, 1, 224, 240, + 178, 5, 1, 203, 11, 178, 5, 1, 221, 152, 178, 5, 1, 213, 90, 178, 5, 1, + 205, 189, 178, 5, 1, 246, 199, 178, 5, 1, 219, 16, 178, 5, 1, 230, 144, + 178, 5, 1, 216, 220, 178, 5, 1, 214, 155, 178, 5, 1, 205, 234, 178, 5, 1, + 208, 194, 178, 5, 1, 216, 122, 178, 5, 1, 245, 254, 178, 5, 1, 202, 252, + 178, 5, 1, 218, 102, 178, 5, 1, 229, 191, 178, 5, 1, 220, 60, 178, 5, 1, + 240, 47, 178, 5, 32, 241, 168, 202, 252, 178, 239, 102, 211, 61, 178, + 235, 220, 216, 15, 178, 240, 246, 54, 227, 221, 178, 240, 246, 54, 178, + 242, 60, 54, 110, 251, 139, 240, 241, 110, 251, 139, 214, 156, 110, 251, + 139, 213, 69, 110, 251, 139, 202, 103, 217, 109, 110, 251, 139, 202, 103, + 238, 254, 110, 251, 139, 208, 209, 110, 251, 139, 216, 70, 110, 251, 139, + 202, 101, 110, 251, 139, 219, 61, 110, 251, 139, 203, 23, 110, 251, 139, + 209, 115, 110, 251, 139, 238, 167, 110, 251, 139, 238, 168, 223, 208, + 110, 251, 139, 238, 165, 110, 251, 139, 217, 110, 219, 90, 110, 251, 139, + 209, 158, 238, 183, 110, 251, 139, 219, 40, 110, 251, 139, 250, 43, 237, + 152, 110, 251, 139, 223, 218, 110, 251, 139, 225, 145, 110, 251, 139, + 224, 229, 110, 251, 139, 224, 230, 229, 192, 110, 251, 139, 244, 151, + 110, 251, 139, 217, 121, 110, 251, 139, 209, 158, 217, 104, 110, 251, + 139, 203, 33, 248, 123, 202, 233, 110, 251, 139, 220, 43, 110, 251, 139, + 231, 69, 110, 251, 139, 244, 53, 110, 251, 139, 202, 28, 110, 131, 225, + 75, 246, 61, 110, 218, 63, 213, 15, 110, 218, 63, 237, 82, 214, 156, 110, + 218, 63, 237, 82, 219, 54, 110, 218, 63, 237, 82, 217, 114, 110, 218, 63, + 236, 232, 110, 218, 63, 208, 11, 110, 218, 63, 214, 156, 110, 218, 63, + 219, 54, 110, 218, 63, 217, 114, 110, 218, 63, 236, 128, 110, 218, 63, + 236, 129, 237, 84, 35, 206, 59, 110, 218, 63, 217, 51, 110, 218, 63, 244, + 198, 219, 245, 225, 105, 110, 218, 63, 224, 219, 110, 217, 179, 225, 102, + 110, 218, 63, 216, 200, 110, 217, 179, 219, 63, 110, 218, 63, 213, 0, + 243, 85, 110, 218, 63, 212, 124, 243, 85, 110, 217, 179, 212, 8, 219, 56, + 110, 131, 206, 221, 243, 85, 110, 131, 226, 251, 243, 85, 110, 217, 179, + 221, 41, 237, 151, 110, 218, 63, 217, 115, 217, 109, 110, 1, 251, 30, + 110, 1, 248, 108, 110, 1, 238, 67, 110, 1, 244, 178, 110, 1, 237, 67, + 110, 1, 206, 59, 110, 1, 202, 95, 110, 1, 237, 21, 110, 1, 209, 132, 110, + 1, 202, 236, 110, 1, 46, 230, 22, 110, 1, 230, 22, 110, 1, 228, 20, 110, + 1, 46, 224, 247, 110, 1, 224, 247, 110, 1, 46, 221, 40, 110, 1, 221, 40, + 110, 1, 214, 249, 110, 1, 250, 3, 110, 1, 46, 219, 34, 110, 1, 219, 34, + 110, 1, 46, 208, 15, 110, 1, 208, 15, 110, 1, 217, 74, 110, 1, 216, 91, + 110, 1, 212, 255, 110, 1, 209, 203, 110, 32, 203, 9, 52, 206, 59, 110, + 32, 203, 9, 206, 60, 202, 236, 110, 32, 203, 9, 52, 202, 236, 110, 217, + 179, 238, 167, 110, 217, 179, 238, 165, 10, 42, 54, 10, 2, 214, 242, 10, + 239, 170, 225, 88, 10, 2, 215, 24, 10, 2, 214, 245, 10, 42, 131, 55, 250, + 140, 245, 106, 215, 204, 250, 140, 239, 140, 215, 204, 10, 216, 165, 250, + 140, 218, 247, 224, 116, 54, 250, 140, 218, 247, 209, 153, 209, 37, 54, + 251, 86, 54, 10, 245, 233, 10, 244, 138, 213, 130, 10, 218, 65, 206, 40, + 54, 10, 2, 224, 95, 10, 2, 215, 3, 251, 33, 204, 86, 10, 2, 251, 33, 250, + 64, 10, 2, 216, 198, 251, 32, 10, 2, 216, 206, 251, 12, 250, 210, 10, 2, + 209, 240, 10, 5, 138, 209, 251, 10, 5, 138, 32, 137, 3, 228, 29, 3, 203, + 47, 10, 5, 138, 202, 107, 10, 5, 240, 71, 10, 5, 244, 172, 10, 5, 229, + 229, 10, 213, 143, 10, 1, 82, 10, 208, 70, 70, 217, 179, 82, 10, 217, 47, + 82, 10, 1, 229, 233, 203, 47, 10, 1, 237, 127, 10, 1, 137, 3, 225, 166, + 55, 10, 1, 137, 3, 237, 128, 55, 10, 1, 204, 71, 3, 237, 128, 55, 10, 1, + 137, 3, 237, 128, 56, 10, 1, 89, 3, 237, 128, 55, 10, 1, 251, 30, 10, 1, + 248, 138, 10, 1, 209, 170, 225, 98, 10, 1, 209, 169, 10, 1, 209, 88, 10, + 1, 230, 158, 10, 1, 237, 148, 10, 1, 229, 140, 10, 1, 244, 184, 10, 1, + 209, 100, 10, 1, 216, 122, 10, 1, 202, 107, 10, 1, 214, 161, 10, 1, 213, + 39, 10, 1, 215, 28, 10, 1, 244, 207, 10, 1, 209, 251, 10, 1, 202, 110, + 10, 1, 251, 59, 10, 1, 238, 114, 10, 1, 229, 190, 3, 120, 187, 55, 10, 1, + 229, 190, 3, 126, 187, 56, 10, 1, 240, 75, 89, 3, 230, 239, 206, 164, 10, + 1, 240, 75, 89, 3, 120, 187, 55, 10, 1, 240, 75, 89, 3, 126, 187, 55, 10, + 209, 209, 10, 1, 240, 47, 10, 1, 217, 119, 10, 1, 230, 22, 10, 1, 228, + 28, 10, 1, 225, 5, 10, 1, 221, 178, 10, 1, 237, 43, 10, 1, 204, 70, 10, + 1, 137, 225, 129, 10, 1, 203, 47, 10, 240, 69, 10, 244, 170, 10, 229, + 227, 10, 240, 71, 10, 244, 172, 10, 229, 229, 10, 213, 80, 10, 210, 222, + 10, 225, 164, 55, 10, 237, 128, 55, 10, 237, 128, 56, 10, 210, 246, 251, + 30, 10, 230, 239, 244, 172, 10, 131, 221, 179, 238, 85, 10, 201, 248, 10, + 22, 2, 5, 206, 165, 55, 10, 22, 2, 230, 239, 5, 206, 165, 55, 10, 22, 2, + 70, 56, 10, 216, 73, 244, 172, 10, 240, 72, 3, 120, 243, 83, 10, 204, 72, + 237, 128, 56, 250, 140, 17, 202, 84, 250, 140, 17, 105, 250, 140, 17, + 108, 250, 140, 17, 147, 250, 140, 17, 149, 250, 140, 17, 170, 250, 140, + 17, 195, 250, 140, 17, 213, 111, 250, 140, 17, 199, 250, 140, 17, 222, + 63, 10, 218, 246, 54, 10, 244, 68, 213, 130, 10, 209, 35, 213, 130, 10, + 239, 233, 218, 61, 211, 94, 10, 1, 243, 84, 248, 138, 10, 1, 243, 84, + 217, 119, 10, 1, 210, 199, 251, 30, 10, 1, 137, 204, 87, 10, 1, 137, 3, + 204, 72, 237, 128, 55, 10, 1, 137, 3, 204, 72, 237, 128, 56, 10, 1, 138, + 237, 127, 10, 1, 138, 237, 128, 251, 30, 10, 1, 138, 237, 128, 204, 70, + 10, 1, 106, 3, 237, 128, 55, 10, 1, 138, 237, 128, 203, 47, 10, 1, 207, + 233, 10, 1, 207, 231, 10, 1, 248, 148, 10, 1, 209, 170, 3, 215, 252, 10, + 1, 209, 170, 3, 126, 187, 87, 242, 68, 10, 1, 219, 16, 10, 1, 209, 167, + 10, 1, 248, 136, 10, 1, 151, 3, 237, 128, 55, 10, 1, 151, 3, 120, 187, + 80, 55, 10, 1, 220, 254, 10, 1, 242, 5, 10, 1, 151, 3, 126, 187, 55, 10, + 1, 209, 191, 10, 1, 209, 189, 10, 1, 244, 115, 10, 1, 244, 185, 3, 215, + 252, 10, 1, 244, 185, 3, 70, 56, 10, 1, 244, 185, 3, 70, 248, 126, 25, 5, + 209, 251, 10, 1, 244, 191, 10, 1, 244, 117, 10, 1, 242, 33, 10, 1, 244, + 185, 3, 126, 187, 87, 242, 68, 10, 1, 244, 185, 3, 239, 147, 187, 55, 10, + 1, 215, 177, 10, 1, 216, 123, 3, 5, 206, 164, 10, 1, 216, 123, 3, 215, + 252, 10, 1, 216, 123, 3, 70, 56, 10, 1, 216, 123, 3, 5, 206, 165, 56, 10, + 1, 216, 123, 3, 70, 248, 126, 25, 70, 55, 10, 1, 216, 123, 3, 120, 187, + 55, 10, 1, 230, 155, 10, 1, 216, 123, 3, 239, 147, 187, 55, 10, 1, 214, + 162, 3, 70, 248, 126, 25, 70, 55, 10, 1, 214, 162, 3, 126, 187, 56, 10, + 1, 214, 162, 3, 126, 187, 248, 126, 25, 126, 187, 55, 10, 1, 215, 29, 3, + 120, 187, 56, 10, 1, 215, 29, 3, 126, 187, 55, 10, 1, 209, 252, 3, 126, + 187, 55, 10, 1, 251, 60, 3, 126, 187, 55, 10, 1, 243, 84, 240, 47, 10, 1, + 240, 48, 3, 70, 224, 5, 56, 10, 1, 240, 48, 3, 70, 56, 10, 1, 206, 48, + 10, 1, 240, 48, 3, 126, 187, 56, 10, 1, 219, 14, 10, 1, 217, 120, 3, 70, + 55, 10, 1, 217, 120, 3, 126, 187, 55, 10, 1, 229, 189, 10, 1, 210, 169, + 230, 22, 10, 1, 230, 23, 3, 215, 252, 10, 1, 230, 23, 3, 70, 55, 10, 1, + 222, 205, 10, 1, 230, 23, 3, 126, 187, 56, 10, 1, 238, 251, 10, 1, 238, + 252, 3, 215, 252, 10, 1, 222, 126, 10, 1, 238, 252, 3, 120, 187, 56, 10, + 1, 237, 217, 10, 1, 238, 252, 3, 126, 187, 55, 10, 1, 228, 29, 3, 5, 206, + 164, 10, 1, 228, 29, 3, 70, 55, 10, 1, 228, 29, 3, 126, 187, 55, 10, 1, + 228, 29, 3, 126, 187, 56, 10, 1, 221, 179, 3, 70, 56, 10, 1, 221, 179, + 238, 85, 10, 1, 215, 230, 10, 1, 221, 179, 3, 215, 252, 10, 1, 221, 179, + 3, 126, 187, 55, 10, 1, 237, 44, 243, 109, 10, 1, 209, 192, 3, 70, 55, + 10, 1, 237, 44, 3, 89, 55, 10, 1, 237, 44, 238, 36, 10, 1, 237, 44, 238, + 37, 3, 237, 128, 55, 10, 1, 209, 170, 225, 99, 238, 36, 10, 1, 204, 71, + 3, 215, 252, 10, 1, 229, 76, 220, 73, 10, 1, 220, 73, 10, 1, 68, 10, 1, + 202, 213, 10, 1, 229, 76, 202, 213, 10, 1, 204, 71, 3, 120, 187, 55, 10, + 1, 206, 55, 10, 1, 240, 75, 203, 47, 10, 1, 89, 3, 209, 248, 10, 1, 89, + 3, 5, 206, 164, 10, 1, 204, 71, 3, 70, 55, 10, 1, 74, 10, 1, 89, 3, 126, + 187, 56, 10, 1, 89, 248, 223, 10, 1, 89, 248, 224, 3, 237, 128, 55, 10, + 239, 102, 211, 61, 10, 1, 251, 109, 10, 5, 138, 32, 215, 29, 3, 228, 29, + 3, 137, 225, 129, 10, 5, 138, 32, 217, 120, 3, 228, 29, 3, 137, 225, 129, + 10, 5, 138, 83, 81, 18, 10, 5, 138, 228, 29, 251, 30, 10, 5, 138, 230, + 158, 10, 5, 138, 126, 243, 83, 10, 5, 138, 214, 161, 10, 241, 84, 76, + 250, 7, 10, 211, 90, 76, 215, 143, 241, 123, 236, 227, 10, 5, 138, 215, + 189, 202, 84, 10, 5, 138, 206, 219, 216, 142, 202, 84, 10, 5, 138, 243, + 84, 237, 65, 76, 229, 140, 10, 5, 138, 83, 64, 18, 10, 5, 124, 214, 161, + 10, 5, 138, 225, 165, 10, 5, 204, 70, 10, 5, 203, 47, 10, 5, 138, 203, + 47, 10, 5, 138, 221, 178, 10, 218, 97, 76, 215, 14, 10, 241, 94, 246, + 218, 124, 211, 61, 10, 241, 94, 246, 218, 138, 211, 61, 10, 215, 189, + 138, 211, 62, 3, 240, 8, 246, 217, 10, 5, 124, 225, 5, 10, 1, 244, 185, + 3, 230, 239, 206, 164, 10, 1, 216, 123, 3, 230, 239, 206, 164, 240, 202, + 250, 140, 17, 202, 84, 240, 202, 250, 140, 17, 105, 240, 202, 250, 140, + 17, 108, 240, 202, 250, 140, 17, 147, 240, 202, 250, 140, 17, 149, 240, + 202, 250, 140, 17, 170, 240, 202, 250, 140, 17, 195, 240, 202, 250, 140, + 17, 213, 111, 240, 202, 250, 140, 17, 199, 240, 202, 250, 140, 17, 222, + 63, 10, 1, 213, 40, 3, 70, 56, 10, 1, 244, 208, 3, 70, 56, 10, 1, 238, + 115, 3, 70, 56, 10, 2, 212, 123, 250, 235, 10, 2, 212, 123, 218, 27, 224, + 240, 10, 1, 237, 44, 3, 230, 239, 206, 164, 210, 89, 241, 84, 76, 219, + 88, 210, 89, 210, 195, 239, 102, 211, 61, 210, 89, 210, 248, 239, 102, + 211, 61, 210, 89, 210, 195, 245, 242, 210, 89, 210, 248, 245, 242, 210, + 89, 236, 106, 245, 242, 210, 89, 245, 243, 212, 68, 227, 222, 210, 89, + 245, 243, 212, 68, 216, 16, 210, 89, 210, 195, 245, 243, 212, 68, 227, + 222, 210, 89, 210, 248, 245, 243, 212, 68, 216, 16, 210, 89, 245, 186, + 210, 89, 237, 89, 220, 91, 210, 89, 237, 89, 224, 217, 210, 89, 237, 89, + 250, 61, 210, 89, 251, 146, 82, 210, 89, 1, 251, 35, 210, 89, 1, 210, + 199, 251, 35, 210, 89, 1, 248, 105, 210, 89, 1, 238, 241, 210, 89, 1, + 238, 242, 238, 219, 210, 89, 1, 244, 181, 210, 89, 1, 243, 84, 244, 182, + 215, 246, 210, 89, 1, 237, 67, 210, 89, 1, 204, 70, 210, 89, 1, 202, 107, + 210, 89, 1, 237, 19, 210, 89, 1, 209, 128, 210, 89, 1, 209, 129, 238, + 219, 210, 89, 1, 202, 200, 210, 89, 1, 202, 201, 237, 67, 210, 89, 1, + 229, 250, 210, 89, 1, 228, 27, 210, 89, 1, 224, 112, 210, 89, 1, 221, 40, + 210, 89, 1, 213, 136, 210, 89, 1, 46, 213, 136, 210, 89, 1, 74, 210, 89, + 1, 219, 34, 210, 89, 1, 216, 73, 219, 34, 210, 89, 1, 215, 26, 210, 89, + 1, 217, 113, 210, 89, 1, 215, 246, 210, 89, 1, 212, 255, 210, 89, 1, 209, + 201, 210, 89, 1, 218, 231, 248, 92, 210, 89, 1, 218, 231, 238, 112, 210, + 89, 1, 218, 231, 243, 252, 210, 89, 217, 192, 55, 210, 89, 217, 192, 56, + 210, 89, 217, 192, 242, 82, 210, 89, 202, 11, 55, 210, 89, 202, 11, 56, + 210, 89, 202, 11, 242, 82, 210, 89, 216, 161, 55, 210, 89, 216, 161, 56, + 210, 89, 242, 83, 202, 18, 236, 105, 210, 89, 242, 83, 202, 18, 250, 211, + 210, 89, 237, 70, 55, 210, 89, 237, 70, 56, 210, 89, 237, 69, 242, 82, + 210, 89, 241, 11, 55, 210, 89, 241, 11, 56, 210, 89, 215, 109, 210, 89, + 240, 41, 243, 85, 210, 89, 217, 25, 210, 89, 215, 137, 210, 89, 120, 80, + 187, 55, 210, 89, 120, 80, 187, 56, 210, 89, 126, 187, 55, 210, 89, 126, + 187, 56, 210, 89, 220, 89, 227, 115, 55, 210, 89, 220, 89, 227, 115, 56, + 210, 89, 223, 194, 210, 89, 248, 222, 210, 89, 1, 212, 4, 202, 78, 210, + 89, 1, 212, 4, 229, 133, 210, 89, 1, 212, 4, 240, 60, 10, 1, 248, 139, 3, + 126, 187, 236, 55, 56, 10, 1, 248, 139, 3, 70, 248, 126, 25, 126, 187, + 55, 10, 1, 248, 139, 3, 126, 187, 218, 59, 177, 56, 10, 1, 248, 139, 3, + 126, 187, 218, 59, 177, 248, 126, 25, 120, 187, 55, 10, 1, 248, 139, 3, + 120, 187, 248, 126, 25, 70, 55, 10, 1, 248, 139, 3, 230, 239, 5, 206, + 165, 56, 10, 1, 248, 139, 3, 5, 206, 164, 10, 1, 151, 3, 120, 187, 55, + 10, 1, 151, 3, 126, 187, 218, 59, 177, 56, 10, 1, 244, 185, 3, 120, 187, + 205, 244, 248, 126, 25, 5, 209, 251, 10, 1, 244, 185, 3, 230, 239, 5, + 206, 165, 56, 10, 1, 216, 123, 3, 95, 10, 1, 214, 162, 3, 239, 147, 187, + 55, 10, 1, 251, 60, 3, 120, 187, 55, 10, 1, 251, 60, 3, 126, 187, 218, + 59, 183, 55, 10, 1, 251, 60, 3, 120, 187, 205, 244, 55, 10, 1, 240, 48, + 3, 120, 187, 56, 10, 1, 240, 48, 3, 126, 187, 218, 59, 177, 56, 10, 1, + 229, 190, 3, 70, 55, 10, 1, 229, 190, 3, 126, 187, 55, 10, 1, 229, 190, + 3, 126, 187, 218, 59, 177, 56, 10, 1, 83, 3, 70, 55, 10, 1, 83, 3, 70, + 56, 10, 1, 221, 179, 3, 120, 187, 56, 10, 1, 221, 179, 3, 5, 209, 251, + 10, 1, 221, 179, 3, 5, 206, 164, 10, 1, 228, 29, 3, 142, 10, 1, 216, 123, + 3, 120, 187, 205, 244, 55, 10, 1, 216, 123, 3, 237, 128, 55, 10, 1, 214, + 162, 3, 120, 187, 205, 244, 55, 10, 1, 151, 3, 5, 10, 1, 209, 252, 56, + 10, 1, 151, 3, 5, 10, 1, 209, 252, 25, 120, 243, 83, 10, 1, 214, 162, 3, + 5, 10, 1, 209, 252, 25, 120, 243, 83, 10, 1, 216, 123, 3, 5, 10, 1, 209, + 252, 25, 120, 243, 83, 10, 1, 151, 3, 5, 10, 1, 209, 252, 55, 10, 1, 137, + 3, 240, 202, 250, 140, 17, 120, 55, 10, 1, 137, 3, 240, 202, 250, 140, + 17, 126, 55, 10, 1, 240, 75, 89, 3, 240, 202, 250, 140, 17, 120, 55, 10, + 1, 240, 75, 89, 3, 240, 202, 250, 140, 17, 126, 55, 10, 1, 240, 75, 89, + 3, 240, 202, 250, 140, 17, 239, 147, 56, 10, 1, 204, 71, 3, 240, 202, + 250, 140, 17, 120, 55, 10, 1, 204, 71, 3, 240, 202, 250, 140, 17, 126, + 55, 10, 1, 89, 248, 224, 3, 240, 202, 250, 140, 17, 120, 55, 10, 1, 89, + 248, 224, 3, 240, 202, 250, 140, 17, 126, 55, 10, 1, 151, 3, 240, 202, + 250, 140, 17, 239, 147, 56, 10, 1, 214, 162, 3, 240, 202, 250, 140, 17, + 239, 147, 55, 10, 1, 214, 162, 3, 230, 239, 206, 164, 10, 1, 230, 23, 3, + 120, 187, 55, 209, 105, 1, 237, 157, 209, 105, 1, 213, 49, 209, 105, 1, + 221, 177, 209, 105, 1, 216, 216, 209, 105, 1, 249, 30, 209, 105, 1, 227, + 158, 209, 105, 1, 230, 37, 209, 105, 1, 251, 19, 209, 105, 1, 206, 84, + 209, 105, 1, 225, 4, 209, 105, 1, 240, 106, 209, 105, 1, 243, 255, 209, + 105, 1, 209, 107, 209, 105, 1, 228, 109, 209, 105, 1, 239, 4, 209, 105, + 1, 238, 42, 209, 105, 1, 214, 160, 209, 105, 1, 244, 136, 209, 105, 1, + 202, 98, 209, 105, 1, 209, 202, 209, 105, 1, 203, 110, 209, 105, 1, 219, + 47, 209, 105, 1, 230, 166, 209, 105, 1, 246, 173, 209, 105, 1, 207, 240, + 209, 105, 1, 237, 11, 209, 105, 1, 229, 143, 209, 105, 1, 209, 106, 209, + 105, 1, 202, 114, 209, 105, 1, 213, 38, 209, 105, 1, 215, 32, 209, 105, + 1, 244, 210, 209, 105, 1, 135, 209, 105, 1, 202, 17, 209, 105, 1, 251, + 56, 209, 105, 1, 238, 113, 209, 105, 1, 217, 123, 209, 105, 1, 204, 109, + 209, 105, 251, 148, 209, 105, 251, 246, 209, 105, 235, 165, 209, 105, + 241, 160, 209, 105, 207, 32, 209, 105, 220, 17, 209, 105, 241, 170, 209, + 105, 240, 193, 209, 105, 220, 88, 209, 105, 220, 96, 209, 105, 210, 222, + 209, 105, 1, 223, 106, 221, 255, 17, 202, 84, 221, 255, 17, 105, 221, + 255, 17, 108, 221, 255, 17, 147, 221, 255, 17, 149, 221, 255, 17, 170, + 221, 255, 17, 195, 221, 255, 17, 213, 111, 221, 255, 17, 199, 221, 255, + 17, 222, 63, 221, 255, 1, 63, 221, 255, 1, 241, 161, 221, 255, 1, 75, + 221, 255, 1, 74, 221, 255, 1, 68, 221, 255, 1, 220, 18, 221, 255, 1, 78, + 221, 255, 1, 244, 199, 221, 255, 1, 223, 163, 221, 255, 1, 249, 32, 221, + 255, 1, 185, 221, 255, 1, 210, 22, 221, 255, 1, 230, 181, 221, 255, 1, + 246, 199, 221, 255, 1, 244, 212, 221, 255, 1, 216, 220, 221, 255, 1, 215, + 185, 221, 255, 1, 215, 36, 221, 255, 1, 238, 207, 221, 255, 1, 240, 108, + 221, 255, 1, 173, 221, 255, 1, 228, 113, 221, 255, 1, 223, 111, 203, 252, + 221, 255, 1, 192, 221, 255, 1, 221, 11, 221, 255, 1, 201, 201, 221, 255, + 1, 152, 221, 255, 1, 204, 111, 221, 255, 1, 198, 221, 255, 1, 221, 12, + 203, 252, 221, 255, 1, 230, 93, 230, 181, 221, 255, 1, 230, 93, 246, 199, + 221, 255, 1, 230, 93, 216, 220, 221, 255, 39, 212, 228, 138, 208, 161, + 221, 255, 39, 212, 228, 124, 208, 161, 221, 255, 39, 212, 228, 215, 245, + 208, 161, 221, 255, 39, 163, 244, 19, 208, 161, 221, 255, 39, 163, 138, + 208, 161, 221, 255, 39, 163, 124, 208, 161, 221, 255, 39, 163, 215, 245, + 208, 161, 221, 255, 39, 223, 71, 82, 221, 255, 39, 52, 70, 55, 221, 255, + 138, 143, 250, 160, 221, 255, 124, 143, 250, 160, 221, 255, 16, 220, 19, + 244, 33, 221, 255, 16, 238, 206, 221, 255, 245, 233, 221, 255, 240, 212, + 82, 221, 255, 228, 84, 214, 252, 1, 251, 37, 214, 252, 1, 248, 51, 214, + 252, 1, 238, 240, 214, 252, 1, 244, 183, 214, 252, 1, 230, 192, 214, 252, + 1, 249, 30, 214, 252, 1, 202, 87, 214, 252, 1, 230, 201, 214, 252, 1, + 208, 200, 214, 252, 1, 202, 182, 214, 252, 1, 230, 38, 214, 252, 1, 228, + 106, 214, 252, 1, 224, 112, 214, 252, 1, 221, 40, 214, 252, 1, 212, 121, + 214, 252, 1, 231, 49, 214, 252, 1, 240, 26, 214, 252, 1, 208, 18, 214, + 252, 1, 217, 44, 214, 252, 1, 215, 246, 214, 252, 1, 213, 66, 214, 252, + 1, 210, 17, 214, 252, 131, 231, 49, 214, 252, 131, 231, 48, 214, 252, + 131, 220, 84, 214, 252, 131, 244, 197, 214, 252, 65, 1, 241, 42, 202, + 182, 214, 252, 131, 241, 42, 202, 182, 214, 252, 22, 2, 163, 74, 214, + 252, 22, 2, 74, 214, 252, 22, 2, 219, 197, 252, 25, 214, 252, 22, 2, 163, + 252, 25, 214, 252, 22, 2, 252, 25, 214, 252, 22, 2, 219, 197, 63, 214, + 252, 22, 2, 163, 63, 214, 252, 22, 2, 63, 214, 252, 65, 1, 212, 228, 63, + 214, 252, 22, 2, 212, 228, 63, 214, 252, 22, 2, 163, 68, 214, 252, 22, 2, + 68, 214, 252, 65, 1, 75, 214, 252, 22, 2, 163, 75, 214, 252, 22, 2, 75, + 214, 252, 22, 2, 78, 214, 252, 22, 2, 210, 222, 214, 252, 131, 222, 223, + 214, 252, 217, 179, 222, 223, 214, 252, 217, 179, 251, 83, 214, 252, 217, + 179, 250, 222, 214, 252, 217, 179, 248, 202, 214, 252, 217, 179, 250, 44, + 214, 252, 217, 179, 212, 243, 214, 252, 251, 146, 82, 214, 252, 217, 179, + 224, 250, 217, 80, 214, 252, 217, 179, 202, 25, 214, 252, 217, 179, 217, + 80, 214, 252, 217, 179, 202, 113, 214, 252, 217, 179, 207, 170, 214, 252, + 217, 179, 250, 111, 214, 252, 217, 179, 212, 8, 225, 77, 214, 252, 217, + 179, 250, 206, 225, 118, 1, 237, 134, 225, 118, 1, 251, 232, 225, 118, 1, + 251, 81, 225, 118, 1, 251, 122, 225, 118, 1, 251, 73, 225, 118, 1, 206, + 184, 225, 118, 1, 250, 1, 225, 118, 1, 230, 201, 225, 118, 1, 250, 41, + 225, 118, 1, 251, 42, 225, 118, 1, 251, 47, 225, 118, 1, 251, 39, 225, + 118, 1, 250, 247, 225, 118, 1, 250, 231, 225, 118, 1, 250, 81, 225, 118, + 1, 231, 49, 225, 118, 1, 250, 175, 225, 118, 1, 250, 51, 225, 118, 1, + 250, 148, 225, 118, 1, 250, 144, 225, 118, 1, 250, 75, 225, 118, 1, 250, + 49, 225, 118, 1, 242, 18, 225, 118, 1, 230, 30, 225, 118, 1, 251, 59, + 225, 118, 251, 87, 82, 225, 118, 205, 187, 82, 225, 118, 238, 179, 82, + 225, 118, 217, 178, 10, 1, 248, 139, 3, 5, 206, 165, 56, 10, 1, 248, 139, + 3, 237, 128, 55, 10, 1, 184, 3, 120, 187, 55, 10, 1, 209, 252, 3, 120, + 187, 55, 10, 1, 240, 48, 3, 70, 248, 126, 25, 126, 187, 55, 10, 1, 217, + 120, 3, 70, 56, 10, 1, 228, 29, 3, 52, 142, 10, 1, 83, 3, 126, 187, 55, + 10, 1, 89, 3, 120, 187, 248, 126, 25, 237, 128, 55, 10, 1, 89, 3, 120, + 187, 248, 126, 25, 70, 55, 10, 1, 216, 123, 3, 227, 14, 10, 1, 204, 71, + 3, 70, 204, 4, 10, 1, 215, 215, 203, 47, 10, 1, 124, 251, 30, 10, 1, 244, + 185, 3, 126, 187, 56, 10, 1, 215, 29, 3, 126, 187, 56, 10, 1, 238, 252, + 3, 230, 239, 95, 10, 1, 211, 53, 204, 70, 10, 1, 202, 108, 3, 230, 239, + 206, 165, 55, 10, 1, 251, 60, 3, 126, 187, 56, 10, 1, 230, 23, 3, 70, 56, + 10, 207, 174, 244, 173, 56, 10, 245, 93, 240, 71, 10, 245, 93, 244, 172, + 10, 245, 93, 229, 229, 10, 245, 93, 240, 69, 10, 245, 93, 244, 170, 10, + 245, 93, 229, 227, 10, 143, 118, 70, 55, 10, 143, 120, 187, 55, 10, 143, + 227, 15, 55, 10, 143, 118, 70, 56, 10, 143, 120, 187, 56, 10, 143, 227, + 15, 56, 10, 171, 240, 69, 10, 171, 244, 170, 10, 171, 229, 227, 10, 5, + 138, 204, 70, 10, 240, 72, 3, 215, 252, 10, 240, 72, 3, 70, 55, 10, 229, + 230, 3, 70, 56, 10, 49, 250, 95, 55, 10, 50, 250, 95, 55, 10, 49, 250, + 95, 56, 10, 50, 250, 95, 56, 10, 52, 50, 250, 95, 55, 10, 52, 50, 250, + 95, 87, 3, 243, 85, 10, 50, 250, 95, 87, 3, 243, 85, 10, 244, 173, 3, + 243, 85, 10, 131, 212, 154, 221, 179, 238, 85, 92, 2, 230, 239, 247, 52, + 92, 2, 247, 52, 92, 2, 250, 180, 92, 2, 205, 199, 92, 1, 212, 228, 63, + 92, 1, 63, 92, 1, 252, 25, 92, 1, 75, 92, 1, 231, 83, 92, 1, 68, 92, 1, + 206, 178, 92, 1, 125, 146, 92, 1, 125, 159, 92, 1, 247, 55, 74, 92, 1, + 212, 228, 74, 92, 1, 74, 92, 1, 251, 64, 92, 1, 247, 55, 78, 92, 1, 212, + 228, 78, 92, 1, 78, 92, 1, 250, 34, 92, 1, 173, 92, 1, 229, 144, 92, 1, + 239, 8, 92, 1, 238, 119, 92, 1, 222, 203, 92, 1, 247, 92, 92, 1, 246, + 199, 92, 1, 230, 181, 92, 1, 230, 149, 92, 1, 221, 11, 92, 1, 207, 241, + 92, 1, 207, 229, 92, 1, 244, 120, 92, 1, 244, 104, 92, 1, 221, 227, 92, + 1, 210, 22, 92, 1, 209, 108, 92, 1, 244, 212, 92, 1, 244, 1, 92, 1, 201, + 201, 92, 1, 221, 209, 92, 1, 185, 92, 1, 218, 208, 92, 1, 249, 32, 92, 1, + 248, 98, 92, 1, 192, 92, 1, 198, 92, 1, 216, 220, 92, 1, 215, 185, 92, 1, + 228, 113, 92, 1, 227, 77, 92, 1, 227, 68, 92, 1, 206, 86, 92, 1, 213, 90, + 92, 1, 211, 164, 92, 1, 215, 36, 92, 1, 152, 92, 22, 2, 220, 73, 92, 22, + 2, 220, 16, 92, 2, 221, 51, 92, 2, 250, 17, 92, 22, 2, 252, 25, 92, 22, + 2, 75, 92, 22, 2, 231, 83, 92, 22, 2, 68, 92, 22, 2, 206, 178, 92, 22, 2, + 125, 146, 92, 22, 2, 125, 215, 186, 92, 22, 2, 247, 55, 74, 92, 22, 2, + 212, 228, 74, 92, 22, 2, 74, 92, 22, 2, 251, 64, 92, 22, 2, 247, 55, 78, + 92, 22, 2, 212, 228, 78, 92, 22, 2, 78, 92, 22, 2, 250, 34, 92, 2, 205, + 204, 92, 22, 2, 217, 229, 74, 92, 22, 2, 250, 13, 92, 220, 39, 92, 211, + 42, 2, 207, 26, 92, 211, 42, 2, 250, 182, 92, 237, 254, 251, 138, 92, + 251, 126, 251, 138, 92, 22, 2, 247, 55, 163, 74, 92, 22, 2, 207, 24, 92, + 22, 2, 206, 177, 92, 1, 217, 126, 92, 1, 229, 125, 92, 1, 238, 94, 92, 1, + 202, 116, 92, 1, 244, 109, 92, 1, 216, 61, 92, 1, 240, 108, 92, 1, 202, + 168, 92, 1, 125, 215, 186, 92, 1, 125, 227, 78, 92, 22, 2, 125, 159, 92, + 22, 2, 125, 227, 78, 92, 244, 166, 92, 52, 244, 166, 92, 17, 202, 84, 92, + 17, 105, 92, 17, 108, 92, 17, 147, 92, 17, 149, 92, 17, 170, 92, 17, 195, + 92, 17, 213, 111, 92, 17, 199, 92, 17, 222, 63, 92, 251, 146, 54, 92, 2, + 138, 211, 227, 243, 85, 92, 1, 247, 55, 63, 92, 1, 220, 73, 92, 1, 220, + 16, 92, 1, 250, 13, 92, 1, 207, 24, 92, 1, 206, 177, 92, 1, 225, 82, 244, + 120, 92, 1, 202, 80, 92, 1, 79, 198, 92, 1, 238, 155, 92, 1, 230, 129, + 92, 1, 238, 45, 211, 61, 92, 1, 244, 110, 92, 1, 248, 198, 179, 250, 209, + 179, 2, 247, 52, 179, 2, 250, 180, 179, 2, 205, 199, 179, 1, 63, 179, 1, + 252, 25, 179, 1, 75, 179, 1, 231, 83, 179, 1, 68, 179, 1, 206, 178, 179, + 1, 125, 146, 179, 1, 125, 159, 179, 1, 74, 179, 1, 251, 64, 179, 1, 78, + 179, 1, 250, 34, 179, 1, 173, 179, 1, 229, 144, 179, 1, 239, 8, 179, 1, + 238, 119, 179, 1, 222, 203, 179, 1, 247, 92, 179, 1, 246, 199, 179, 1, + 230, 181, 179, 1, 230, 149, 179, 1, 221, 11, 179, 1, 207, 241, 179, 1, + 207, 229, 179, 1, 244, 120, 179, 1, 244, 104, 179, 1, 221, 227, 179, 1, + 210, 22, 179, 1, 209, 108, 179, 1, 244, 212, 179, 1, 244, 1, 179, 1, 201, + 201, 179, 1, 185, 179, 1, 218, 208, 179, 1, 249, 32, 179, 1, 248, 98, + 179, 1, 192, 179, 1, 198, 179, 1, 216, 220, 179, 1, 228, 113, 179, 1, + 213, 90, 179, 1, 211, 164, 179, 1, 215, 36, 179, 1, 152, 179, 2, 221, 51, + 179, 2, 250, 17, 179, 22, 2, 252, 25, 179, 22, 2, 75, 179, 22, 2, 231, + 83, 179, 22, 2, 68, 179, 22, 2, 206, 178, 179, 22, 2, 125, 146, 179, 22, + 2, 125, 215, 186, 179, 22, 2, 74, 179, 22, 2, 251, 64, 179, 22, 2, 78, + 179, 22, 2, 250, 34, 179, 2, 205, 204, 179, 1, 229, 135, 210, 22, 179, + 250, 35, 227, 196, 82, 179, 1, 215, 185, 179, 1, 216, 61, 179, 1, 202, + 168, 179, 1, 125, 215, 186, 179, 1, 125, 227, 78, 179, 22, 2, 125, 159, + 179, 22, 2, 125, 227, 78, 179, 17, 202, 84, 179, 17, 105, 179, 17, 108, + 179, 17, 147, 179, 17, 149, 179, 17, 170, 179, 17, 195, 179, 17, 213, + 111, 179, 17, 199, 179, 17, 222, 63, 179, 1, 216, 221, 3, 101, 243, 227, + 179, 1, 216, 221, 3, 226, 251, 243, 227, 179, 215, 120, 82, 179, 215, + 120, 54, 179, 245, 92, 221, 43, 105, 179, 245, 92, 221, 43, 108, 179, + 245, 92, 221, 43, 147, 179, 245, 92, 221, 43, 149, 179, 245, 92, 221, 43, + 118, 227, 180, 209, 98, 209, 93, 244, 31, 179, 245, 92, 244, 32, 212, 82, + 179, 230, 202, 179, 238, 231, 82, 237, 198, 2, 251, 121, 248, 66, 237, + 198, 2, 248, 66, 237, 198, 2, 205, 199, 237, 198, 1, 63, 237, 198, 1, + 252, 25, 237, 198, 1, 75, 237, 198, 1, 231, 83, 237, 198, 1, 68, 237, + 198, 1, 206, 178, 237, 198, 1, 241, 161, 237, 198, 1, 251, 64, 237, 198, + 1, 220, 18, 237, 198, 1, 250, 34, 237, 198, 1, 173, 237, 198, 1, 229, + 144, 237, 198, 1, 239, 8, 237, 198, 1, 238, 119, 237, 198, 1, 222, 203, + 237, 198, 1, 247, 92, 237, 198, 1, 246, 199, 237, 198, 1, 230, 181, 237, + 198, 1, 230, 149, 237, 198, 1, 221, 11, 237, 198, 1, 207, 241, 237, 198, + 1, 207, 229, 237, 198, 1, 244, 120, 237, 198, 1, 244, 104, 237, 198, 1, + 221, 227, 237, 198, 1, 210, 22, 237, 198, 1, 209, 108, 237, 198, 1, 244, + 212, 237, 198, 1, 244, 1, 237, 198, 1, 201, 201, 237, 198, 1, 185, 237, + 198, 1, 218, 208, 237, 198, 1, 249, 32, 237, 198, 1, 248, 98, 237, 198, + 1, 192, 237, 198, 1, 198, 237, 198, 1, 216, 220, 237, 198, 1, 228, 113, + 237, 198, 1, 227, 77, 237, 198, 1, 206, 86, 237, 198, 1, 213, 90, 237, + 198, 1, 215, 36, 237, 198, 1, 152, 237, 198, 2, 221, 51, 237, 198, 22, 2, + 252, 25, 237, 198, 22, 2, 75, 237, 198, 22, 2, 231, 83, 237, 198, 22, 2, + 68, 237, 198, 22, 2, 206, 178, 237, 198, 22, 2, 241, 161, 237, 198, 22, + 2, 251, 64, 237, 198, 22, 2, 220, 18, 237, 198, 22, 2, 250, 34, 237, 198, + 2, 205, 204, 237, 198, 2, 207, 28, 237, 198, 1, 229, 125, 237, 198, 1, + 238, 94, 237, 198, 1, 202, 116, 237, 198, 1, 215, 185, 237, 198, 1, 240, + 108, 237, 198, 17, 202, 84, 237, 198, 17, 105, 237, 198, 17, 108, 237, + 198, 17, 147, 237, 198, 17, 149, 237, 198, 17, 170, 237, 198, 17, 195, + 237, 198, 17, 213, 111, 237, 198, 17, 199, 237, 198, 17, 222, 63, 237, + 198, 208, 208, 237, 198, 251, 120, 237, 198, 230, 222, 237, 198, 206, + 206, 237, 198, 241, 130, 220, 23, 237, 198, 2, 203, 85, 237, 213, 2, 247, + 52, 237, 213, 2, 250, 180, 237, 213, 2, 205, 199, 237, 213, 1, 63, 237, + 213, 1, 252, 25, 237, 213, 1, 75, 237, 213, 1, 231, 83, 237, 213, 1, 68, + 237, 213, 1, 206, 178, 237, 213, 1, 125, 146, 237, 213, 1, 125, 159, 237, + 213, 22, 247, 55, 74, 237, 213, 1, 74, 237, 213, 1, 251, 64, 237, 213, + 22, 247, 55, 78, 237, 213, 1, 78, 237, 213, 1, 250, 34, 237, 213, 1, 173, + 237, 213, 1, 229, 144, 237, 213, 1, 239, 8, 237, 213, 1, 238, 119, 237, + 213, 1, 222, 203, 237, 213, 1, 247, 92, 237, 213, 1, 246, 199, 237, 213, + 1, 230, 181, 237, 213, 1, 230, 149, 237, 213, 1, 221, 11, 237, 213, 1, + 207, 241, 237, 213, 1, 207, 229, 237, 213, 1, 244, 120, 237, 213, 1, 244, + 104, 237, 213, 1, 221, 227, 237, 213, 1, 210, 22, 237, 213, 1, 209, 108, + 237, 213, 1, 244, 212, 237, 213, 1, 244, 1, 237, 213, 1, 201, 201, 237, + 213, 1, 185, 237, 213, 1, 218, 208, 237, 213, 1, 249, 32, 237, 213, 1, + 248, 98, 237, 213, 1, 192, 237, 213, 1, 198, 237, 213, 1, 216, 220, 237, + 213, 1, 228, 113, 237, 213, 1, 227, 77, 237, 213, 1, 206, 86, 237, 213, + 1, 213, 90, 237, 213, 1, 211, 164, 237, 213, 1, 215, 36, 237, 213, 1, + 152, 237, 213, 2, 221, 51, 237, 213, 2, 250, 17, 237, 213, 22, 2, 252, + 25, 237, 213, 22, 2, 75, 237, 213, 22, 2, 231, 83, 237, 213, 22, 2, 68, + 237, 213, 22, 2, 206, 178, 237, 213, 22, 2, 125, 146, 237, 213, 22, 2, + 125, 215, 186, 237, 213, 22, 2, 247, 55, 74, 237, 213, 22, 2, 74, 237, + 213, 22, 2, 251, 64, 237, 213, 22, 2, 247, 55, 78, 237, 213, 22, 2, 78, + 237, 213, 22, 2, 250, 34, 237, 213, 2, 205, 204, 237, 213, 220, 39, 237, + 213, 1, 125, 215, 186, 237, 213, 1, 125, 227, 78, 237, 213, 22, 2, 125, + 159, 237, 213, 22, 2, 125, 227, 78, 237, 213, 17, 202, 84, 237, 213, 17, + 105, 237, 213, 17, 108, 237, 213, 17, 147, 237, 213, 17, 149, 237, 213, + 17, 170, 237, 213, 17, 195, 237, 213, 17, 213, 111, 237, 213, 17, 199, + 237, 213, 17, 222, 63, 237, 213, 251, 146, 54, 237, 213, 215, 120, 54, + 237, 213, 1, 202, 80, 193, 2, 247, 52, 193, 2, 250, 180, 193, 2, 205, + 199, 193, 1, 63, 193, 1, 252, 25, 193, 1, 75, 193, 1, 231, 83, 193, 1, + 68, 193, 1, 206, 178, 193, 1, 125, 146, 193, 1, 125, 159, 193, 1, 74, + 193, 1, 251, 64, 193, 1, 78, 193, 1, 250, 34, 193, 1, 173, 193, 1, 229, + 144, 193, 1, 239, 8, 193, 1, 238, 119, 193, 1, 222, 203, 193, 1, 247, 92, + 193, 1, 246, 199, 193, 1, 230, 181, 193, 1, 230, 149, 193, 1, 221, 11, + 193, 1, 207, 241, 193, 1, 207, 229, 193, 1, 244, 120, 193, 1, 244, 104, + 193, 1, 221, 227, 193, 1, 210, 22, 193, 1, 209, 108, 193, 1, 244, 212, + 193, 1, 244, 1, 193, 1, 201, 201, 193, 1, 185, 193, 1, 218, 208, 193, 1, + 249, 32, 193, 1, 248, 98, 193, 1, 192, 193, 1, 198, 193, 1, 216, 220, + 193, 1, 228, 113, 193, 1, 227, 77, 193, 1, 206, 86, 193, 1, 213, 90, 193, + 1, 211, 164, 193, 1, 215, 36, 193, 1, 152, 193, 2, 221, 51, 193, 2, 250, + 17, 193, 22, 2, 252, 25, 193, 22, 2, 75, 193, 22, 2, 231, 83, 193, 22, 2, + 68, 193, 22, 2, 206, 178, 193, 22, 2, 125, 146, 193, 22, 2, 125, 215, + 186, 193, 22, 2, 74, 193, 22, 2, 251, 64, 193, 22, 2, 78, 193, 22, 2, + 250, 34, 193, 2, 205, 204, 193, 251, 65, 227, 196, 82, 193, 250, 35, 227, + 196, 82, 193, 1, 215, 185, 193, 1, 216, 61, 193, 1, 202, 168, 193, 1, + 125, 215, 186, 193, 1, 125, 227, 78, 193, 22, 2, 125, 159, 193, 22, 2, + 125, 227, 78, 193, 17, 202, 84, 193, 17, 105, 193, 17, 108, 193, 17, 147, + 193, 17, 149, 193, 17, 170, 193, 17, 195, 193, 17, 213, 111, 193, 17, + 199, 193, 17, 222, 63, 193, 230, 202, 193, 1, 204, 111, 193, 239, 138, + 118, 217, 55, 193, 239, 138, 118, 237, 137, 193, 239, 138, 126, 217, 53, + 193, 239, 138, 118, 212, 80, 193, 239, 138, 118, 241, 138, 193, 239, 138, + 126, 212, 79, 44, 2, 250, 180, 44, 2, 205, 199, 44, 1, 63, 44, 1, 252, + 25, 44, 1, 75, 44, 1, 231, 83, 44, 1, 68, 44, 1, 206, 178, 44, 1, 74, 44, + 1, 241, 161, 44, 1, 251, 64, 44, 1, 78, 44, 1, 220, 18, 44, 1, 250, 34, + 44, 1, 173, 44, 1, 222, 203, 44, 1, 247, 92, 44, 1, 230, 181, 44, 1, 221, + 11, 44, 1, 207, 241, 44, 1, 221, 227, 44, 1, 210, 22, 44, 1, 201, 201, + 44, 1, 221, 209, 44, 1, 185, 44, 1, 192, 44, 1, 198, 44, 1, 216, 220, 44, + 1, 215, 185, 44, 1, 228, 113, 44, 1, 227, 77, 44, 1, 227, 68, 44, 1, 206, + 86, 44, 1, 213, 90, 44, 1, 211, 164, 44, 1, 215, 36, 44, 1, 152, 44, 22, + 2, 252, 25, 44, 22, 2, 75, 44, 22, 2, 231, 83, 44, 22, 2, 68, 44, 22, 2, + 206, 178, 44, 22, 2, 74, 44, 22, 2, 241, 161, 44, 22, 2, 251, 64, 44, 22, + 2, 78, 44, 22, 2, 220, 18, 44, 22, 2, 250, 34, 44, 2, 205, 204, 44, 220, + 39, 44, 250, 35, 227, 196, 82, 44, 17, 202, 84, 44, 17, 105, 44, 17, 108, + 44, 17, 147, 44, 17, 149, 44, 17, 170, 44, 17, 195, 44, 17, 213, 111, 44, + 17, 199, 44, 17, 222, 63, 44, 42, 209, 152, 44, 42, 118, 236, 11, 44, 42, + 118, 209, 36, 44, 244, 133, 54, 44, 224, 38, 54, 44, 203, 50, 54, 44, + 244, 72, 54, 44, 245, 141, 54, 44, 250, 82, 87, 54, 44, 215, 120, 54, 44, + 42, 54, 175, 2, 39, 247, 53, 55, 175, 2, 247, 52, 175, 2, 250, 180, 175, + 2, 205, 199, 175, 1, 63, 175, 1, 252, 25, 175, 1, 75, 175, 1, 231, 83, + 175, 1, 68, 175, 1, 206, 178, 175, 1, 125, 146, 175, 1, 125, 159, 175, 1, + 74, 175, 1, 241, 161, 175, 1, 251, 64, 175, 1, 78, 175, 1, 220, 18, 175, + 1, 250, 34, 175, 1, 173, 175, 1, 229, 144, 175, 1, 239, 8, 175, 1, 238, + 119, 175, 1, 222, 203, 175, 1, 247, 92, 175, 1, 246, 199, 175, 1, 230, + 181, 175, 1, 230, 149, 175, 1, 221, 11, 175, 1, 207, 241, 175, 1, 207, + 229, 175, 1, 244, 120, 175, 1, 244, 104, 175, 1, 221, 227, 175, 1, 210, + 22, 175, 1, 209, 108, 175, 1, 244, 212, 175, 1, 244, 1, 175, 1, 201, 201, + 175, 1, 185, 175, 1, 218, 208, 175, 1, 249, 32, 175, 1, 248, 98, 175, 1, + 192, 175, 1, 198, 175, 1, 216, 220, 175, 1, 215, 185, 175, 1, 228, 113, + 175, 1, 227, 77, 175, 1, 227, 68, 175, 1, 206, 86, 175, 1, 213, 90, 175, + 1, 211, 164, 175, 1, 215, 36, 175, 1, 152, 175, 2, 250, 17, 175, 22, 2, + 252, 25, 175, 22, 2, 75, 175, 22, 2, 231, 83, 175, 22, 2, 68, 175, 22, 2, + 206, 178, 175, 22, 2, 125, 146, 175, 22, 2, 125, 215, 186, 175, 22, 2, + 74, 175, 22, 2, 241, 161, 175, 22, 2, 251, 64, 175, 22, 2, 78, 175, 22, + 2, 220, 18, 175, 22, 2, 250, 34, 175, 2, 205, 204, 175, 227, 196, 82, + 175, 251, 65, 227, 196, 82, 175, 1, 208, 20, 175, 1, 241, 255, 175, 1, + 215, 166, 175, 1, 125, 215, 186, 175, 1, 125, 227, 78, 175, 22, 2, 125, + 159, 175, 22, 2, 125, 227, 78, 175, 17, 202, 84, 175, 17, 105, 175, 17, + 108, 175, 17, 147, 175, 17, 149, 175, 17, 170, 175, 17, 195, 175, 17, + 213, 111, 175, 17, 199, 175, 17, 222, 63, 175, 239, 138, 17, 202, 85, 35, + 220, 77, 218, 15, 76, 149, 175, 239, 138, 17, 118, 35, 220, 77, 218, 15, + 76, 149, 175, 239, 138, 17, 120, 35, 220, 77, 218, 15, 76, 149, 175, 239, + 138, 17, 126, 35, 220, 77, 218, 15, 76, 149, 175, 239, 138, 17, 118, 35, + 240, 225, 218, 15, 76, 149, 175, 239, 138, 17, 120, 35, 240, 225, 218, + 15, 76, 149, 175, 239, 138, 17, 126, 35, 240, 225, 218, 15, 76, 149, 175, + 2, 207, 164, 200, 2, 247, 52, 200, 2, 250, 180, 200, 2, 205, 199, 200, 1, + 63, 200, 1, 252, 25, 200, 1, 75, 200, 1, 231, 83, 200, 1, 68, 200, 1, + 206, 178, 200, 1, 125, 146, 200, 1, 125, 159, 200, 1, 74, 200, 1, 241, + 161, 200, 1, 251, 64, 200, 1, 78, 200, 1, 220, 18, 200, 1, 250, 34, 200, + 1, 173, 200, 1, 229, 144, 200, 1, 239, 8, 200, 1, 238, 119, 200, 1, 222, + 203, 200, 1, 247, 92, 200, 1, 246, 199, 200, 1, 230, 181, 200, 1, 230, + 149, 200, 1, 221, 11, 200, 1, 207, 241, 200, 1, 207, 229, 200, 1, 244, + 120, 200, 1, 244, 104, 200, 1, 221, 227, 200, 1, 210, 22, 200, 1, 209, + 108, 200, 1, 244, 212, 200, 1, 244, 1, 200, 1, 201, 201, 200, 1, 185, + 200, 1, 218, 208, 200, 1, 249, 32, 200, 1, 248, 98, 200, 1, 192, 200, 1, + 198, 200, 1, 216, 220, 200, 1, 215, 185, 200, 1, 228, 113, 200, 1, 227, + 77, 200, 1, 206, 86, 200, 1, 213, 90, 200, 1, 211, 164, 200, 1, 215, 36, + 200, 1, 152, 200, 2, 221, 51, 200, 2, 250, 17, 200, 22, 2, 252, 25, 200, + 22, 2, 75, 200, 22, 2, 231, 83, 200, 22, 2, 68, 200, 22, 2, 206, 178, + 200, 22, 2, 125, 146, 200, 22, 2, 125, 215, 186, 200, 22, 2, 74, 200, 22, + 2, 241, 161, 200, 22, 2, 251, 64, 200, 22, 2, 78, 200, 22, 2, 220, 18, + 200, 22, 2, 250, 34, 200, 2, 205, 204, 200, 227, 196, 82, 200, 251, 65, + 227, 196, 82, 200, 1, 240, 108, 200, 1, 125, 215, 186, 200, 1, 125, 227, + 78, 200, 22, 2, 125, 159, 200, 22, 2, 125, 227, 78, 200, 17, 202, 84, + 200, 17, 105, 200, 17, 108, 200, 17, 147, 200, 17, 149, 200, 17, 170, + 200, 17, 195, 200, 17, 213, 111, 200, 17, 199, 200, 17, 222, 63, 200, 2, + 230, 135, 200, 2, 206, 222, 164, 2, 247, 52, 164, 2, 250, 180, 164, 2, + 205, 199, 164, 1, 63, 164, 1, 252, 25, 164, 1, 75, 164, 1, 231, 83, 164, + 1, 68, 164, 1, 206, 178, 164, 1, 125, 146, 164, 1, 125, 159, 164, 1, 74, + 164, 1, 241, 161, 164, 1, 251, 64, 164, 1, 78, 164, 1, 220, 18, 164, 1, + 250, 34, 164, 1, 173, 164, 1, 229, 144, 164, 1, 239, 8, 164, 1, 238, 119, + 164, 1, 222, 203, 164, 1, 247, 92, 164, 1, 246, 199, 164, 1, 230, 181, + 164, 1, 230, 149, 164, 1, 221, 11, 164, 1, 207, 241, 164, 1, 207, 229, + 164, 1, 244, 120, 164, 1, 244, 104, 164, 1, 221, 227, 164, 1, 210, 22, + 164, 1, 209, 108, 164, 1, 244, 212, 164, 1, 244, 1, 164, 1, 201, 201, + 164, 1, 221, 209, 164, 1, 185, 164, 1, 218, 208, 164, 1, 249, 32, 164, 1, + 248, 98, 164, 1, 192, 164, 1, 198, 164, 1, 216, 220, 164, 1, 215, 185, + 164, 1, 228, 113, 164, 1, 227, 77, 164, 1, 227, 68, 164, 1, 206, 86, 164, + 1, 213, 90, 164, 1, 211, 164, 164, 1, 215, 36, 164, 1, 152, 164, 1, 207, + 210, 164, 2, 250, 17, 164, 22, 2, 252, 25, 164, 22, 2, 75, 164, 22, 2, + 231, 83, 164, 22, 2, 68, 164, 22, 2, 206, 178, 164, 22, 2, 125, 146, 164, + 22, 2, 125, 215, 186, 164, 22, 2, 74, 164, 22, 2, 241, 161, 164, 22, 2, + 251, 64, 164, 22, 2, 78, 164, 22, 2, 220, 18, 164, 22, 2, 250, 34, 164, + 2, 205, 204, 164, 1, 70, 216, 97, 164, 250, 35, 227, 196, 82, 164, 1, + 250, 126, 231, 83, 164, 1, 125, 215, 186, 164, 1, 125, 227, 78, 164, 22, + 2, 125, 159, 164, 22, 2, 125, 227, 78, 164, 17, 202, 84, 164, 17, 105, + 164, 17, 108, 164, 17, 147, 164, 17, 149, 164, 17, 170, 164, 17, 195, + 164, 17, 213, 111, 164, 17, 199, 164, 17, 222, 63, 164, 42, 209, 152, + 164, 42, 118, 236, 11, 164, 42, 118, 209, 36, 164, 239, 138, 118, 217, + 55, 164, 239, 138, 118, 237, 137, 164, 239, 138, 126, 217, 53, 164, 244, + 138, 82, 164, 1, 246, 131, 221, 228, 164, 1, 246, 131, 223, 163, 164, 1, + 246, 131, 215, 186, 164, 1, 246, 131, 159, 164, 1, 246, 131, 227, 78, + 164, 1, 246, 131, 230, 54, 140, 2, 250, 179, 140, 2, 205, 198, 140, 1, + 250, 6, 140, 1, 251, 235, 140, 1, 251, 89, 140, 1, 251, 104, 140, 1, 230, + 191, 140, 1, 231, 82, 140, 1, 206, 169, 140, 1, 206, 172, 140, 1, 230, + 217, 140, 1, 230, 218, 140, 1, 231, 68, 140, 1, 231, 70, 140, 1, 240, + 194, 140, 1, 241, 156, 140, 1, 251, 49, 140, 1, 219, 187, 140, 1, 220, + 11, 140, 1, 250, 20, 140, 1, 251, 5, 229, 206, 140, 1, 225, 147, 229, + 206, 140, 1, 251, 5, 238, 210, 140, 1, 225, 147, 238, 210, 140, 1, 229, + 255, 223, 103, 140, 1, 214, 235, 238, 210, 140, 1, 251, 5, 247, 8, 140, + 1, 225, 147, 247, 8, 140, 1, 251, 5, 230, 164, 140, 1, 225, 147, 230, + 164, 140, 1, 210, 15, 223, 103, 140, 1, 210, 15, 214, 234, 223, 104, 140, + 1, 214, 235, 230, 164, 140, 1, 251, 5, 207, 237, 140, 1, 225, 147, 207, + 237, 140, 1, 251, 5, 244, 111, 140, 1, 225, 147, 244, 111, 140, 1, 223, + 191, 223, 58, 140, 1, 214, 235, 244, 111, 140, 1, 251, 5, 209, 195, 140, + 1, 225, 147, 209, 195, 140, 1, 251, 5, 244, 131, 140, 1, 225, 147, 244, + 131, 140, 1, 244, 162, 223, 58, 140, 1, 214, 235, 244, 131, 140, 1, 251, + 5, 219, 42, 140, 1, 225, 147, 219, 42, 140, 1, 251, 5, 248, 200, 140, 1, + 225, 147, 248, 200, 140, 1, 225, 62, 140, 1, 250, 241, 248, 200, 140, 1, + 203, 57, 140, 1, 216, 164, 140, 1, 244, 162, 227, 243, 140, 1, 206, 57, + 140, 1, 210, 15, 214, 207, 140, 1, 223, 191, 214, 207, 140, 1, 244, 162, + 214, 207, 140, 1, 237, 71, 140, 1, 223, 191, 227, 243, 140, 1, 240, 62, + 140, 2, 251, 38, 140, 22, 2, 251, 99, 140, 22, 2, 229, 169, 251, 106, + 140, 22, 2, 243, 200, 251, 106, 140, 22, 2, 229, 169, 230, 214, 140, 22, + 2, 243, 200, 230, 214, 140, 22, 2, 229, 169, 219, 167, 140, 22, 2, 243, + 200, 219, 167, 140, 22, 2, 238, 253, 140, 22, 2, 229, 11, 140, 22, 2, + 243, 200, 229, 11, 140, 22, 2, 229, 13, 244, 50, 140, 22, 2, 229, 12, + 237, 158, 251, 99, 140, 22, 2, 229, 12, 237, 158, 243, 200, 251, 99, 140, + 22, 2, 229, 12, 237, 158, 238, 209, 140, 22, 2, 238, 209, 140, 227, 89, + 17, 202, 84, 140, 227, 89, 17, 105, 140, 227, 89, 17, 108, 140, 227, 89, + 17, 147, 140, 227, 89, 17, 149, 140, 227, 89, 17, 170, 140, 227, 89, 17, + 195, 140, 227, 89, 17, 213, 111, 140, 227, 89, 17, 199, 140, 227, 89, 17, + 222, 63, 140, 22, 2, 243, 200, 238, 253, 140, 22, 2, 243, 200, 238, 209, + 140, 217, 179, 228, 194, 209, 103, 167, 229, 27, 230, 18, 209, 103, 167, + 229, 116, 229, 139, 209, 103, 167, 229, 116, 229, 108, 209, 103, 167, + 229, 116, 229, 103, 209, 103, 167, 229, 116, 229, 112, 209, 103, 167, + 229, 116, 216, 185, 209, 103, 167, 222, 129, 222, 116, 209, 103, 167, + 246, 117, 246, 188, 209, 103, 167, 246, 117, 246, 127, 209, 103, 167, + 246, 117, 246, 187, 209, 103, 167, 212, 14, 212, 13, 209, 103, 167, 246, + 117, 246, 113, 209, 103, 167, 202, 248, 202, 255, 209, 103, 167, 243, + 114, 246, 196, 209, 103, 167, 208, 173, 219, 53, 209, 103, 167, 209, 48, + 209, 97, 209, 103, 167, 209, 48, 223, 80, 209, 103, 167, 209, 48, 218, + 170, 209, 103, 167, 221, 192, 222, 230, 209, 103, 167, 243, 114, 244, 51, + 209, 103, 167, 208, 173, 209, 223, 209, 103, 167, 209, 48, 209, 16, 209, + 103, 167, 209, 48, 209, 104, 209, 103, 167, 209, 48, 209, 43, 209, 103, + 167, 221, 192, 221, 84, 209, 103, 167, 248, 24, 249, 0, 209, 103, 167, + 218, 70, 218, 98, 209, 103, 167, 218, 181, 218, 172, 209, 103, 167, 239, + 187, 240, 108, 209, 103, 167, 218, 181, 218, 201, 209, 103, 167, 239, + 187, 240, 81, 209, 103, 167, 218, 181, 214, 247, 209, 103, 167, 224, 83, + 192, 209, 103, 167, 202, 248, 203, 86, 209, 103, 167, 215, 228, 215, 144, + 209, 103, 167, 215, 145, 209, 103, 167, 227, 50, 227, 107, 209, 103, 167, + 226, 239, 209, 103, 167, 204, 1, 204, 106, 209, 103, 167, 212, 14, 215, + 6, 209, 103, 167, 212, 14, 215, 116, 209, 103, 167, 212, 14, 211, 9, 209, + 103, 167, 236, 137, 236, 233, 209, 103, 167, 227, 50, 246, 97, 209, 103, + 167, 158, 250, 223, 209, 103, 167, 236, 137, 221, 187, 209, 103, 167, + 219, 144, 209, 103, 167, 214, 229, 63, 209, 103, 167, 225, 141, 237, 125, + 209, 103, 167, 214, 229, 252, 25, 209, 103, 167, 214, 229, 250, 247, 209, + 103, 167, 214, 229, 75, 209, 103, 167, 214, 229, 231, 83, 209, 103, 167, + 214, 229, 207, 24, 209, 103, 167, 214, 229, 207, 22, 209, 103, 167, 214, + 229, 68, 209, 103, 167, 214, 229, 206, 178, 209, 103, 167, 218, 183, 209, + 103, 245, 92, 16, 249, 1, 209, 103, 167, 214, 229, 74, 209, 103, 167, + 214, 229, 251, 109, 209, 103, 167, 214, 229, 78, 209, 103, 167, 214, 229, + 251, 65, 225, 135, 209, 103, 167, 214, 229, 251, 65, 225, 136, 209, 103, + 167, 228, 32, 209, 103, 167, 225, 132, 209, 103, 167, 225, 133, 209, 103, + 167, 225, 141, 241, 129, 209, 103, 167, 225, 141, 209, 47, 209, 103, 167, + 225, 141, 208, 88, 209, 103, 167, 225, 141, 246, 175, 209, 103, 167, 209, + 95, 209, 103, 167, 222, 72, 209, 103, 167, 203, 80, 209, 103, 167, 239, + 177, 209, 103, 17, 202, 84, 209, 103, 17, 105, 209, 103, 17, 108, 209, + 103, 17, 147, 209, 103, 17, 149, 209, 103, 17, 170, 209, 103, 17, 195, + 209, 103, 17, 213, 111, 209, 103, 17, 199, 209, 103, 17, 222, 63, 209, + 103, 167, 250, 219, 209, 103, 167, 229, 113, 228, 12, 1, 229, 26, 228, + 12, 1, 229, 116, 210, 211, 228, 12, 1, 229, 116, 209, 232, 228, 12, 1, + 222, 128, 228, 12, 1, 245, 254, 228, 12, 1, 212, 14, 209, 232, 228, 12, + 1, 220, 233, 228, 12, 1, 243, 113, 228, 12, 1, 135, 228, 12, 1, 209, 48, + 210, 211, 228, 12, 1, 209, 48, 209, 232, 228, 12, 1, 221, 191, 228, 12, + 1, 248, 23, 228, 12, 1, 218, 69, 228, 12, 1, 218, 181, 210, 211, 228, 12, + 1, 239, 187, 209, 232, 228, 12, 1, 218, 181, 209, 232, 228, 12, 1, 239, + 187, 210, 211, 228, 12, 1, 224, 82, 228, 12, 1, 202, 247, 228, 12, 1, + 227, 50, 227, 107, 228, 12, 1, 227, 50, 227, 12, 228, 12, 1, 204, 0, 228, + 12, 1, 212, 14, 210, 211, 228, 12, 1, 236, 137, 210, 211, 228, 12, 1, 78, + 228, 12, 1, 236, 137, 209, 232, 228, 12, 241, 108, 228, 12, 22, 2, 63, + 228, 12, 22, 2, 225, 141, 230, 4, 228, 12, 22, 2, 252, 25, 228, 12, 22, + 2, 250, 247, 228, 12, 22, 2, 75, 228, 12, 22, 2, 231, 83, 228, 12, 22, 2, + 203, 124, 228, 12, 22, 2, 202, 169, 228, 12, 22, 2, 68, 228, 12, 22, 2, + 206, 178, 228, 12, 22, 2, 225, 141, 229, 9, 228, 12, 213, 138, 2, 227, + 49, 228, 12, 213, 138, 2, 220, 233, 228, 12, 22, 2, 74, 228, 12, 22, 2, + 241, 145, 228, 12, 22, 2, 78, 228, 12, 22, 2, 250, 8, 228, 12, 22, 2, + 251, 64, 228, 12, 229, 27, 228, 113, 228, 12, 143, 225, 141, 241, 129, + 228, 12, 143, 225, 141, 209, 47, 228, 12, 143, 225, 141, 209, 2, 228, 12, + 143, 225, 141, 247, 16, 228, 12, 247, 58, 82, 228, 12, 222, 81, 228, 12, + 17, 202, 84, 228, 12, 17, 105, 228, 12, 17, 108, 228, 12, 17, 147, 228, + 12, 17, 149, 228, 12, 17, 170, 228, 12, 17, 195, 228, 12, 17, 213, 111, + 228, 12, 17, 199, 228, 12, 17, 222, 63, 228, 12, 236, 137, 221, 191, 228, + 12, 236, 137, 224, 82, 228, 12, 1, 229, 117, 238, 39, 228, 12, 1, 229, + 117, 220, 233, 77, 4, 220, 39, 77, 131, 237, 232, 203, 3, 224, 173, 208, + 26, 63, 77, 131, 237, 232, 203, 3, 224, 173, 255, 22, 215, 232, 248, 164, + 192, 77, 131, 237, 232, 203, 3, 224, 173, 255, 22, 237, 232, 208, 6, 192, + 77, 131, 81, 203, 3, 224, 173, 225, 22, 192, 77, 131, 246, 12, 203, 3, + 224, 173, 213, 97, 192, 77, 131, 247, 34, 203, 3, 224, 173, 218, 171, + 213, 83, 192, 77, 131, 203, 3, 224, 173, 208, 6, 213, 83, 192, 77, 131, + 214, 205, 213, 82, 77, 131, 247, 196, 203, 3, 224, 172, 77, 131, 248, 45, + 212, 238, 203, 3, 224, 172, 77, 131, 230, 243, 208, 5, 77, 131, 244, 44, + 208, 6, 247, 195, 77, 131, 213, 82, 77, 131, 220, 238, 213, 82, 77, 131, + 208, 6, 213, 82, 77, 131, 220, 238, 208, 6, 213, 82, 77, 131, 215, 255, + 246, 156, 211, 180, 213, 82, 77, 131, 216, 65, 238, 9, 213, 82, 77, 131, + 247, 34, 255, 26, 215, 149, 225, 21, 163, 247, 61, 77, 131, 237, 232, + 208, 5, 77, 227, 35, 2, 246, 197, 215, 148, 77, 227, 35, 2, 227, 159, + 215, 148, 77, 250, 55, 2, 213, 93, 238, 193, 255, 27, 215, 148, 77, 250, + 55, 2, 255, 24, 185, 77, 250, 55, 2, 214, 178, 208, 0, 77, 2, 216, 160, + 243, 127, 238, 192, 77, 2, 216, 160, 243, 127, 238, 41, 77, 2, 216, 160, + 243, 127, 237, 233, 77, 2, 216, 160, 223, 99, 238, 192, 77, 2, 216, 160, + 223, 99, 238, 41, 77, 2, 216, 160, 243, 127, 216, 160, 223, 98, 77, 17, + 202, 84, 77, 17, 105, 77, 17, 108, 77, 17, 147, 77, 17, 149, 77, 17, 170, + 77, 17, 195, 77, 17, 213, 111, 77, 17, 199, 77, 17, 222, 63, 77, 17, 162, + 105, 77, 17, 162, 108, 77, 17, 162, 147, 77, 17, 162, 149, 77, 17, 162, + 170, 77, 17, 162, 195, 77, 17, 162, 213, 111, 77, 17, 162, 199, 77, 17, + 162, 222, 63, 77, 17, 162, 202, 84, 77, 131, 247, 198, 215, 148, 77, 131, + 222, 194, 247, 127, 220, 249, 202, 19, 77, 131, 247, 34, 255, 26, 215, + 149, 247, 128, 224, 126, 247, 61, 77, 131, 222, 194, 247, 127, 213, 94, + 215, 148, 77, 131, 246, 171, 224, 172, 77, 131, 208, 21, 255, 23, 77, + 131, 237, 215, 215, 149, 237, 174, 77, 131, 237, 215, 215, 149, 237, 180, + 77, 131, 250, 224, 229, 134, 237, 174, 77, 131, 250, 224, 229, 134, 237, + 180, 77, 2, 203, 72, 208, 4, 77, 2, 225, 101, 208, 4, 77, 1, 173, 77, 1, + 229, 144, 77, 1, 239, 8, 77, 1, 238, 119, 77, 1, 222, 203, 77, 1, 247, + 92, 77, 1, 246, 199, 77, 1, 230, 181, 77, 1, 221, 11, 77, 1, 207, 241, + 77, 1, 207, 229, 77, 1, 244, 120, 77, 1, 244, 104, 77, 1, 221, 227, 77, + 1, 210, 22, 77, 1, 209, 108, 77, 1, 244, 212, 77, 1, 244, 1, 77, 1, 201, + 201, 77, 1, 185, 77, 1, 218, 208, 77, 1, 249, 32, 77, 1, 248, 98, 77, 1, + 192, 77, 1, 208, 20, 77, 1, 208, 10, 77, 1, 241, 255, 77, 1, 241, 249, + 77, 1, 204, 111, 77, 1, 202, 80, 77, 1, 202, 116, 77, 1, 255, 29, 77, 1, + 198, 77, 1, 216, 220, 77, 1, 228, 113, 77, 1, 213, 90, 77, 1, 211, 164, + 77, 1, 215, 36, 77, 1, 152, 77, 1, 63, 77, 1, 228, 223, 77, 1, 239, 229, + 216, 220, 77, 1, 229, 47, 77, 1, 215, 185, 77, 22, 2, 252, 25, 77, 22, 2, + 75, 77, 22, 2, 231, 83, 77, 22, 2, 68, 77, 22, 2, 206, 178, 77, 22, 2, + 125, 146, 77, 22, 2, 125, 215, 186, 77, 22, 2, 125, 159, 77, 22, 2, 125, + 227, 78, 77, 22, 2, 74, 77, 22, 2, 241, 161, 77, 22, 2, 78, 77, 22, 2, + 220, 18, 77, 2, 215, 238, 211, 11, 222, 204, 215, 227, 77, 2, 215, 232, + 248, 163, 77, 22, 2, 216, 73, 75, 77, 22, 2, 216, 73, 231, 83, 77, 2, + 220, 249, 202, 20, 223, 107, 244, 212, 77, 2, 212, 27, 227, 236, 77, 131, + 237, 139, 77, 131, 219, 132, 77, 2, 227, 239, 215, 148, 77, 2, 203, 77, + 215, 148, 77, 2, 227, 240, 208, 21, 247, 61, 77, 2, 225, 24, 247, 61, 77, + 2, 237, 236, 247, 62, 216, 63, 77, 2, 237, 236, 225, 14, 216, 63, 77, 2, + 230, 239, 225, 24, 247, 61, 77, 210, 254, 2, 227, 240, 208, 21, 247, 61, + 77, 210, 254, 2, 225, 24, 247, 61, 77, 210, 254, 2, 230, 239, 225, 24, + 247, 61, 77, 210, 254, 1, 173, 77, 210, 254, 1, 229, 144, 77, 210, 254, + 1, 239, 8, 77, 210, 254, 1, 238, 119, 77, 210, 254, 1, 222, 203, 77, 210, + 254, 1, 247, 92, 77, 210, 254, 1, 246, 199, 77, 210, 254, 1, 230, 181, + 77, 210, 254, 1, 221, 11, 77, 210, 254, 1, 207, 241, 77, 210, 254, 1, + 207, 229, 77, 210, 254, 1, 244, 120, 77, 210, 254, 1, 244, 104, 77, 210, + 254, 1, 221, 227, 77, 210, 254, 1, 210, 22, 77, 210, 254, 1, 209, 108, + 77, 210, 254, 1, 244, 212, 77, 210, 254, 1, 244, 1, 77, 210, 254, 1, 201, + 201, 77, 210, 254, 1, 185, 77, 210, 254, 1, 218, 208, 77, 210, 254, 1, + 249, 32, 77, 210, 254, 1, 248, 98, 77, 210, 254, 1, 192, 77, 210, 254, 1, + 208, 20, 77, 210, 254, 1, 208, 10, 77, 210, 254, 1, 241, 255, 77, 210, + 254, 1, 241, 249, 77, 210, 254, 1, 204, 111, 77, 210, 254, 1, 202, 80, + 77, 210, 254, 1, 202, 116, 77, 210, 254, 1, 255, 29, 77, 210, 254, 1, + 198, 77, 210, 254, 1, 216, 220, 77, 210, 254, 1, 228, 113, 77, 210, 254, + 1, 213, 90, 77, 210, 254, 1, 211, 164, 77, 210, 254, 1, 215, 36, 77, 210, + 254, 1, 152, 77, 210, 254, 1, 63, 77, 210, 254, 1, 228, 223, 77, 210, + 254, 1, 239, 229, 204, 111, 77, 210, 254, 1, 239, 229, 198, 77, 210, 254, + 1, 239, 229, 216, 220, 77, 228, 210, 215, 146, 229, 144, 77, 228, 210, + 215, 146, 229, 145, 247, 128, 224, 126, 247, 61, 77, 247, 49, 2, 79, 248, + 155, 77, 247, 49, 2, 157, 248, 155, 77, 247, 49, 2, 247, 50, 209, 185, + 77, 247, 49, 2, 214, 204, 255, 28, 77, 16, 242, 55, 247, 193, 77, 16, + 216, 159, 215, 239, 77, 16, 219, 155, 238, 191, 77, 16, 216, 159, 215, + 240, 216, 65, 238, 8, 77, 16, 218, 171, 185, 77, 16, 221, 175, 247, 193, + 77, 16, 221, 175, 247, 194, 220, 238, 255, 25, 77, 16, 221, 175, 247, + 194, 237, 234, 255, 25, 77, 16, 221, 175, 247, 194, 247, 128, 255, 25, + 77, 2, 216, 160, 223, 99, 216, 160, 243, 126, 77, 2, 216, 160, 223, 99, + 237, 233, 77, 131, 247, 197, 212, 238, 238, 82, 224, 173, 216, 64, 77, + 131, 224, 84, 203, 3, 238, 82, 224, 173, 216, 64, 77, 131, 220, 238, 208, + 5, 77, 131, 81, 247, 220, 215, 229, 203, 3, 224, 173, 225, 22, 192, 77, + 131, 246, 12, 247, 220, 215, 229, 203, 3, 224, 173, 213, 97, 192, 216, + 15, 210, 174, 54, 227, 221, 210, 174, 54, 216, 15, 210, 174, 2, 3, 243, + 83, 227, 221, 210, 174, 2, 3, 243, 83, 77, 131, 227, 231, 225, 25, 215, + 148, 77, 131, 208, 112, 225, 25, 215, 148, 69, 1, 173, 69, 1, 229, 144, + 69, 1, 239, 8, 69, 1, 238, 119, 69, 1, 222, 203, 69, 1, 247, 92, 69, 1, + 246, 199, 69, 1, 230, 181, 69, 1, 230, 149, 69, 1, 221, 11, 69, 1, 221, + 193, 69, 1, 207, 241, 69, 1, 207, 229, 69, 1, 244, 120, 69, 1, 244, 104, + 69, 1, 221, 227, 69, 1, 210, 22, 69, 1, 209, 108, 69, 1, 244, 212, 69, 1, + 244, 1, 69, 1, 201, 201, 69, 1, 185, 69, 1, 218, 208, 69, 1, 249, 32, 69, + 1, 248, 98, 69, 1, 192, 69, 1, 198, 69, 1, 216, 220, 69, 1, 228, 113, 69, + 1, 204, 111, 69, 1, 215, 36, 69, 1, 152, 69, 1, 227, 77, 69, 1, 63, 69, + 1, 213, 67, 63, 69, 1, 75, 69, 1, 231, 83, 69, 1, 68, 69, 1, 206, 178, + 69, 1, 74, 69, 1, 224, 55, 74, 69, 1, 78, 69, 1, 250, 34, 69, 22, 2, 209, + 234, 252, 25, 69, 22, 2, 252, 25, 69, 22, 2, 75, 69, 22, 2, 231, 83, 69, + 22, 2, 68, 69, 22, 2, 206, 178, 69, 22, 2, 74, 69, 22, 2, 251, 64, 69, + 22, 2, 224, 55, 231, 83, 69, 22, 2, 224, 55, 78, 69, 22, 2, 188, 55, 69, + 2, 250, 180, 69, 2, 70, 56, 69, 2, 205, 199, 69, 2, 205, 204, 69, 2, 250, + 79, 69, 109, 2, 174, 198, 69, 109, 2, 174, 216, 220, 69, 109, 2, 174, + 204, 111, 69, 109, 2, 174, 152, 69, 1, 237, 249, 215, 36, 69, 17, 202, + 84, 69, 17, 105, 69, 17, 108, 69, 17, 147, 69, 17, 149, 69, 17, 170, 69, + 17, 195, 69, 17, 213, 111, 69, 17, 199, 69, 17, 222, 63, 69, 2, 227, 86, + 214, 167, 69, 2, 214, 167, 69, 16, 227, 44, 69, 16, 245, 227, 69, 16, + 251, 85, 69, 16, 238, 174, 69, 1, 213, 90, 69, 1, 211, 164, 69, 1, 125, + 146, 69, 1, 125, 215, 186, 69, 1, 125, 159, 69, 1, 125, 227, 78, 69, 22, + 2, 125, 146, 69, 22, 2, 125, 215, 186, 69, 22, 2, 125, 159, 69, 22, 2, + 125, 227, 78, 69, 1, 224, 55, 222, 203, 69, 1, 224, 55, 230, 149, 69, 1, + 224, 55, 248, 198, 69, 1, 224, 55, 248, 193, 69, 109, 2, 224, 55, 174, + 201, 201, 69, 109, 2, 224, 55, 174, 192, 69, 109, 2, 224, 55, 174, 228, + 113, 69, 1, 213, 96, 229, 237, 213, 90, 69, 22, 2, 213, 96, 229, 237, + 240, 238, 69, 143, 131, 213, 96, 229, 237, 237, 79, 69, 143, 131, 213, + 96, 229, 237, 229, 202, 218, 180, 69, 1, 204, 44, 217, 146, 229, 237, + 209, 108, 69, 1, 204, 44, 217, 146, 229, 237, 217, 152, 69, 22, 2, 204, + 44, 217, 146, 229, 237, 240, 238, 69, 22, 2, 204, 44, 217, 146, 229, 237, + 207, 24, 69, 2, 204, 44, 217, 146, 229, 237, 208, 160, 69, 2, 204, 44, + 217, 146, 229, 237, 208, 159, 69, 2, 204, 44, 217, 146, 229, 237, 208, + 158, 69, 2, 204, 44, 217, 146, 229, 237, 208, 157, 69, 2, 204, 44, 217, + 146, 229, 237, 208, 156, 69, 1, 241, 174, 217, 146, 229, 237, 221, 227, + 69, 1, 241, 174, 217, 146, 229, 237, 202, 176, 69, 1, 241, 174, 217, 146, + 229, 237, 238, 84, 69, 22, 2, 238, 186, 229, 237, 75, 69, 22, 2, 229, + 207, 220, 73, 69, 22, 2, 229, 207, 68, 69, 22, 2, 229, 207, 241, 161, 69, + 1, 213, 67, 173, 69, 1, 213, 67, 229, 144, 69, 1, 213, 67, 239, 8, 69, 1, + 213, 67, 247, 92, 69, 1, 213, 67, 202, 116, 69, 1, 213, 67, 221, 11, 69, + 1, 213, 67, 244, 212, 69, 1, 213, 67, 201, 201, 69, 1, 213, 67, 218, 208, + 69, 1, 213, 67, 240, 108, 69, 1, 213, 67, 249, 32, 69, 1, 213, 67, 209, + 108, 69, 1, 213, 67, 152, 69, 109, 2, 213, 67, 174, 204, 111, 69, 22, 2, + 213, 67, 252, 25, 69, 22, 2, 213, 67, 74, 69, 22, 2, 213, 67, 188, 55, + 69, 22, 2, 213, 67, 46, 203, 124, 69, 2, 213, 67, 208, 159, 69, 2, 213, + 67, 208, 158, 69, 2, 213, 67, 208, 156, 69, 2, 213, 67, 208, 155, 69, 2, + 213, 67, 245, 156, 208, 159, 69, 2, 213, 67, 245, 156, 208, 158, 69, 2, + 213, 67, 245, 156, 241, 95, 208, 161, 69, 1, 215, 130, 219, 139, 240, + 108, 69, 2, 215, 130, 219, 139, 208, 156, 69, 213, 67, 17, 202, 84, 69, + 213, 67, 17, 105, 69, 213, 67, 17, 108, 69, 213, 67, 17, 147, 69, 213, + 67, 17, 149, 69, 213, 67, 17, 170, 69, 213, 67, 17, 195, 69, 213, 67, 17, + 213, 111, 69, 213, 67, 17, 199, 69, 213, 67, 17, 222, 63, 69, 2, 229, + 137, 208, 160, 69, 2, 229, 137, 208, 158, 69, 22, 2, 251, 51, 63, 69, 22, + 2, 251, 51, 251, 64, 69, 16, 213, 67, 105, 69, 16, 213, 67, 240, 211, + 114, 6, 1, 250, 231, 114, 6, 1, 248, 242, 114, 6, 1, 238, 234, 114, 6, 1, + 243, 93, 114, 6, 1, 241, 92, 114, 6, 1, 205, 213, 114, 6, 1, 202, 87, + 114, 6, 1, 209, 230, 114, 6, 1, 231, 49, 114, 6, 1, 230, 4, 114, 6, 1, + 228, 2, 114, 6, 1, 225, 122, 114, 6, 1, 223, 74, 114, 6, 1, 220, 31, 114, + 6, 1, 219, 91, 114, 6, 1, 202, 76, 114, 6, 1, 216, 202, 114, 6, 1, 214, + 243, 114, 6, 1, 209, 218, 114, 6, 1, 206, 255, 114, 6, 1, 218, 200, 114, + 6, 1, 229, 132, 114, 6, 1, 238, 110, 114, 6, 1, 217, 111, 114, 6, 1, 212, + 255, 114, 6, 1, 246, 129, 114, 6, 1, 247, 61, 114, 6, 1, 230, 133, 114, + 6, 1, 246, 68, 114, 6, 1, 246, 183, 114, 6, 1, 203, 180, 114, 6, 1, 230, + 146, 114, 6, 1, 237, 154, 114, 6, 1, 237, 67, 114, 6, 1, 236, 254, 114, + 6, 1, 204, 62, 114, 6, 1, 237, 92, 114, 6, 1, 236, 132, 114, 6, 1, 202, + 249, 114, 6, 1, 251, 98, 114, 1, 250, 231, 114, 1, 248, 242, 114, 1, 238, + 234, 114, 1, 243, 93, 114, 1, 241, 92, 114, 1, 205, 213, 114, 1, 202, 87, + 114, 1, 209, 230, 114, 1, 231, 49, 114, 1, 230, 4, 114, 1, 228, 2, 114, + 1, 225, 122, 114, 1, 223, 74, 114, 1, 220, 31, 114, 1, 219, 91, 114, 1, + 202, 76, 114, 1, 216, 202, 114, 1, 214, 243, 114, 1, 209, 218, 114, 1, + 206, 255, 114, 1, 218, 200, 114, 1, 229, 132, 114, 1, 238, 110, 114, 1, + 217, 111, 114, 1, 212, 255, 114, 1, 246, 129, 114, 1, 247, 61, 114, 1, + 230, 133, 114, 1, 246, 68, 114, 1, 246, 183, 114, 1, 203, 180, 114, 1, + 230, 146, 114, 1, 237, 154, 114, 1, 237, 67, 114, 1, 236, 254, 114, 1, + 204, 62, 114, 1, 237, 92, 114, 1, 236, 132, 114, 1, 240, 26, 114, 1, 202, + 249, 114, 1, 241, 110, 114, 1, 207, 174, 238, 234, 114, 1, 251, 59, 114, + 219, 89, 213, 130, 65, 1, 114, 223, 74, 114, 1, 251, 98, 114, 1, 237, 91, + 54, 114, 1, 228, 104, 54, 28, 123, 229, 59, 28, 123, 211, 156, 28, 123, + 222, 93, 28, 123, 208, 240, 28, 123, 211, 145, 28, 123, 216, 47, 28, 123, + 224, 141, 28, 123, 218, 153, 28, 123, 211, 153, 28, 123, 212, 111, 28, + 123, 211, 150, 28, 123, 231, 106, 28, 123, 246, 74, 28, 123, 211, 160, + 28, 123, 246, 138, 28, 123, 229, 120, 28, 123, 209, 66, 28, 123, 218, + 190, 28, 123, 236, 251, 28, 123, 222, 89, 28, 123, 211, 154, 28, 123, + 222, 83, 28, 123, 222, 87, 28, 123, 208, 237, 28, 123, 216, 35, 28, 123, + 211, 152, 28, 123, 216, 45, 28, 123, 229, 243, 28, 123, 224, 134, 28, + 123, 229, 246, 28, 123, 218, 148, 28, 123, 218, 146, 28, 123, 218, 134, + 28, 123, 218, 142, 28, 123, 218, 140, 28, 123, 218, 137, 28, 123, 218, + 139, 28, 123, 218, 136, 28, 123, 218, 141, 28, 123, 218, 151, 28, 123, + 218, 152, 28, 123, 218, 135, 28, 123, 218, 145, 28, 123, 229, 244, 28, + 123, 229, 242, 28, 123, 212, 104, 28, 123, 212, 102, 28, 123, 212, 94, + 28, 123, 212, 97, 28, 123, 212, 103, 28, 123, 212, 99, 28, 123, 212, 98, + 28, 123, 212, 96, 28, 123, 212, 107, 28, 123, 212, 109, 28, 123, 212, + 110, 28, 123, 212, 105, 28, 123, 212, 95, 28, 123, 212, 100, 28, 123, + 212, 108, 28, 123, 246, 120, 28, 123, 246, 118, 28, 123, 246, 210, 28, + 123, 246, 208, 28, 123, 219, 107, 28, 123, 231, 101, 28, 123, 231, 92, + 28, 123, 231, 100, 28, 123, 231, 97, 28, 123, 231, 95, 28, 123, 231, 99, + 28, 123, 211, 157, 28, 123, 231, 104, 28, 123, 231, 105, 28, 123, 231, + 93, 28, 123, 231, 98, 28, 123, 203, 29, 28, 123, 246, 73, 28, 123, 246, + 121, 28, 123, 246, 119, 28, 123, 246, 211, 28, 123, 246, 209, 28, 123, + 246, 136, 28, 123, 246, 137, 28, 123, 246, 122, 28, 123, 246, 212, 28, + 123, 218, 188, 28, 123, 229, 245, 28, 123, 211, 158, 28, 123, 203, 35, + 28, 123, 229, 50, 28, 123, 222, 85, 28, 123, 222, 91, 28, 123, 222, 90, + 28, 123, 208, 234, 28, 123, 240, 7, 28, 176, 240, 7, 28, 176, 63, 28, + 176, 251, 109, 28, 176, 198, 28, 176, 203, 99, 28, 176, 241, 55, 28, 176, + 74, 28, 176, 203, 39, 28, 176, 203, 52, 28, 176, 78, 28, 176, 204, 111, + 28, 176, 204, 107, 28, 176, 220, 73, 28, 176, 202, 247, 28, 176, 68, 28, + 176, 204, 48, 28, 176, 204, 62, 28, 176, 204, 30, 28, 176, 202, 213, 28, + 176, 240, 238, 28, 176, 203, 11, 28, 176, 75, 28, 176, 255, 20, 28, 176, + 255, 19, 28, 176, 203, 113, 28, 176, 203, 111, 28, 176, 241, 53, 28, 176, + 241, 52, 28, 176, 241, 54, 28, 176, 203, 38, 28, 176, 203, 37, 28, 176, + 220, 181, 28, 176, 220, 182, 28, 176, 220, 175, 28, 176, 220, 180, 28, + 176, 220, 178, 28, 176, 202, 241, 28, 176, 202, 240, 28, 176, 202, 239, + 28, 176, 202, 242, 28, 176, 202, 243, 28, 176, 207, 97, 28, 176, 207, 96, + 28, 176, 207, 94, 28, 176, 207, 90, 28, 176, 207, 91, 28, 176, 202, 212, + 28, 176, 202, 209, 28, 176, 202, 210, 28, 176, 202, 204, 28, 176, 202, + 205, 28, 176, 202, 206, 28, 176, 202, 208, 28, 176, 240, 232, 28, 176, + 240, 234, 28, 176, 203, 10, 28, 176, 235, 205, 28, 176, 235, 197, 28, + 176, 235, 200, 28, 176, 235, 198, 28, 176, 235, 202, 28, 176, 235, 204, + 28, 176, 250, 137, 28, 176, 250, 134, 28, 176, 250, 132, 28, 176, 250, + 133, 28, 176, 211, 161, 28, 176, 255, 21, 28, 176, 203, 112, 28, 176, + 203, 36, 28, 176, 220, 177, 28, 176, 220, 176, 28, 107, 229, 59, 28, 107, + 211, 156, 28, 107, 229, 52, 28, 107, 222, 93, 28, 107, 222, 91, 28, 107, + 222, 90, 28, 107, 208, 240, 28, 107, 216, 47, 28, 107, 216, 42, 28, 107, + 216, 39, 28, 107, 216, 32, 28, 107, 216, 27, 28, 107, 216, 22, 28, 107, + 216, 33, 28, 107, 216, 45, 28, 107, 224, 141, 28, 107, 218, 153, 28, 107, + 218, 142, 28, 107, 212, 111, 28, 107, 211, 150, 28, 107, 231, 106, 28, + 107, 246, 74, 28, 107, 246, 138, 28, 107, 229, 120, 28, 107, 209, 66, 28, + 107, 218, 190, 28, 107, 236, 251, 28, 107, 229, 53, 28, 107, 229, 51, 28, + 107, 222, 89, 28, 107, 222, 83, 28, 107, 222, 85, 28, 107, 222, 88, 28, + 107, 222, 84, 28, 107, 208, 237, 28, 107, 208, 234, 28, 107, 216, 40, 28, + 107, 216, 35, 28, 107, 216, 21, 28, 107, 216, 20, 28, 107, 211, 152, 28, + 107, 216, 37, 28, 107, 216, 36, 28, 107, 216, 29, 28, 107, 216, 31, 28, + 107, 216, 44, 28, 107, 216, 24, 28, 107, 216, 34, 28, 107, 216, 43, 28, + 107, 216, 19, 28, 107, 224, 137, 28, 107, 224, 132, 28, 107, 224, 134, + 28, 107, 224, 131, 28, 107, 224, 129, 28, 107, 224, 135, 28, 107, 224, + 140, 28, 107, 224, 138, 28, 107, 229, 246, 28, 107, 218, 144, 28, 107, + 218, 145, 28, 107, 218, 150, 28, 107, 229, 244, 28, 107, 212, 104, 28, + 107, 212, 94, 28, 107, 212, 97, 28, 107, 212, 99, 28, 107, 219, 107, 28, + 107, 231, 101, 28, 107, 231, 94, 28, 107, 211, 157, 28, 107, 231, 102, + 28, 107, 203, 29, 28, 107, 203, 25, 28, 107, 203, 26, 28, 107, 218, 188, + 28, 107, 229, 245, 28, 107, 236, 249, 28, 107, 236, 247, 28, 107, 236, + 250, 28, 107, 236, 248, 28, 107, 203, 35, 28, 107, 229, 55, 28, 107, 229, + 54, 28, 107, 229, 58, 28, 107, 229, 56, 28, 107, 229, 57, 28, 107, 211, + 154, 33, 4, 152, 33, 4, 236, 26, 33, 4, 237, 3, 33, 4, 237, 157, 33, 4, + 237, 48, 33, 4, 237, 67, 33, 4, 236, 136, 33, 4, 236, 135, 33, 4, 228, + 113, 33, 4, 226, 239, 33, 4, 227, 148, 33, 4, 228, 112, 33, 4, 227, 226, + 33, 4, 227, 234, 33, 4, 227, 49, 33, 4, 226, 207, 33, 4, 237, 12, 33, 4, + 237, 6, 33, 4, 237, 8, 33, 4, 237, 11, 33, 4, 237, 9, 33, 4, 237, 10, 33, + 4, 237, 7, 33, 4, 237, 5, 33, 4, 192, 33, 4, 223, 246, 33, 4, 224, 155, + 33, 4, 225, 175, 33, 4, 225, 8, 33, 4, 225, 20, 33, 4, 224, 82, 33, 4, + 223, 180, 33, 4, 210, 80, 33, 4, 210, 74, 33, 4, 210, 76, 33, 4, 210, 79, + 33, 4, 210, 77, 33, 4, 210, 78, 33, 4, 210, 75, 33, 4, 210, 73, 33, 4, + 216, 220, 33, 4, 215, 145, 33, 4, 216, 57, 33, 4, 216, 216, 33, 4, 216, + 135, 33, 4, 216, 158, 33, 4, 215, 227, 33, 4, 215, 111, 33, 4, 215, 36, + 33, 4, 211, 10, 33, 4, 212, 162, 33, 4, 215, 33, 33, 4, 214, 165, 33, 4, + 214, 177, 33, 4, 212, 13, 33, 4, 210, 172, 33, 4, 213, 90, 33, 4, 212, + 199, 33, 4, 213, 11, 33, 4, 213, 85, 33, 4, 213, 41, 33, 4, 213, 43, 33, + 4, 212, 242, 33, 4, 212, 180, 33, 4, 217, 126, 33, 4, 217, 65, 33, 4, + 217, 88, 33, 4, 217, 125, 33, 4, 217, 105, 33, 4, 217, 106, 33, 4, 217, + 77, 33, 4, 217, 76, 33, 4, 217, 19, 33, 4, 217, 15, 33, 4, 217, 18, 33, + 4, 217, 16, 33, 4, 217, 17, 33, 4, 217, 102, 33, 4, 217, 94, 33, 4, 217, + 97, 33, 4, 217, 101, 33, 4, 217, 98, 33, 4, 217, 99, 33, 4, 217, 96, 33, + 4, 217, 93, 33, 4, 217, 89, 33, 4, 217, 92, 33, 4, 217, 90, 33, 4, 217, + 91, 33, 4, 249, 32, 33, 4, 247, 193, 33, 4, 248, 86, 33, 4, 249, 30, 33, + 4, 248, 150, 33, 4, 248, 162, 33, 4, 248, 23, 33, 4, 247, 142, 33, 4, + 206, 86, 33, 4, 204, 163, 33, 4, 205, 230, 33, 4, 206, 85, 33, 4, 206, + 50, 33, 4, 206, 55, 33, 4, 205, 189, 33, 4, 204, 154, 33, 4, 210, 22, 33, + 4, 207, 203, 33, 4, 209, 2, 33, 4, 210, 18, 33, 4, 209, 176, 33, 4, 209, + 187, 33, 4, 135, 33, 4, 207, 160, 33, 4, 247, 92, 33, 4, 245, 110, 33, 4, + 246, 79, 33, 4, 247, 91, 33, 4, 246, 230, 33, 4, 246, 238, 33, 4, 245, + 254, 33, 4, 245, 74, 33, 4, 203, 182, 33, 4, 203, 152, 33, 4, 203, 170, + 33, 4, 203, 181, 33, 4, 203, 175, 33, 4, 203, 176, 33, 4, 203, 160, 33, + 4, 203, 159, 33, 4, 203, 146, 33, 4, 203, 142, 33, 4, 203, 145, 33, 4, + 203, 143, 33, 4, 203, 144, 33, 4, 201, 201, 33, 4, 221, 84, 33, 4, 222, + 100, 33, 4, 223, 106, 33, 4, 222, 235, 33, 4, 222, 240, 33, 4, 221, 191, + 33, 4, 221, 20, 33, 4, 221, 11, 33, 4, 220, 226, 33, 4, 220, 248, 33, 4, + 221, 10, 33, 4, 221, 0, 33, 4, 221, 1, 33, 4, 220, 233, 33, 4, 220, 216, + 33, 4, 238, 45, 63, 33, 4, 238, 45, 68, 33, 4, 238, 45, 75, 33, 4, 238, + 45, 252, 25, 33, 4, 238, 45, 241, 161, 33, 4, 238, 45, 74, 33, 4, 238, + 45, 78, 33, 4, 238, 45, 204, 111, 33, 4, 173, 33, 4, 228, 209, 33, 4, + 229, 100, 33, 4, 230, 41, 33, 4, 229, 198, 33, 4, 229, 201, 33, 4, 229, + 26, 33, 4, 229, 25, 33, 4, 228, 167, 33, 4, 228, 160, 33, 4, 228, 166, + 33, 4, 228, 161, 33, 4, 228, 162, 33, 4, 228, 153, 33, 4, 228, 147, 33, + 4, 228, 149, 33, 4, 228, 152, 33, 4, 228, 150, 33, 4, 228, 151, 33, 4, + 228, 148, 33, 4, 228, 146, 33, 4, 228, 142, 33, 4, 228, 145, 33, 4, 228, + 143, 33, 4, 228, 144, 33, 4, 204, 111, 33, 4, 203, 217, 33, 4, 204, 30, + 33, 4, 204, 110, 33, 4, 204, 55, 33, 4, 204, 62, 33, 4, 204, 0, 33, 4, + 203, 255, 33, 4, 218, 199, 63, 33, 4, 218, 199, 68, 33, 4, 218, 199, 75, + 33, 4, 218, 199, 252, 25, 33, 4, 218, 199, 241, 161, 33, 4, 218, 199, 74, + 33, 4, 218, 199, 78, 33, 4, 202, 116, 33, 4, 202, 6, 33, 4, 202, 39, 33, + 4, 202, 114, 33, 4, 202, 90, 33, 4, 202, 92, 33, 4, 202, 17, 33, 4, 201, + 249, 33, 4, 202, 80, 33, 4, 202, 57, 33, 4, 202, 66, 33, 4, 202, 79, 33, + 4, 202, 70, 33, 4, 202, 71, 33, 4, 202, 63, 33, 4, 202, 48, 33, 4, 198, + 33, 4, 202, 213, 33, 4, 203, 11, 33, 4, 203, 110, 33, 4, 203, 49, 33, 4, + 203, 52, 33, 4, 202, 247, 33, 4, 202, 238, 33, 4, 244, 212, 33, 4, 242, + 42, 33, 4, 243, 233, 33, 4, 244, 211, 33, 4, 244, 61, 33, 4, 244, 75, 33, + 4, 243, 113, 33, 4, 242, 10, 33, 4, 244, 120, 33, 4, 244, 85, 33, 4, 244, + 97, 33, 4, 244, 119, 33, 4, 244, 107, 33, 4, 244, 108, 33, 4, 244, 90, + 33, 4, 244, 76, 33, 4, 230, 181, 33, 4, 230, 82, 33, 4, 230, 141, 33, 4, + 230, 180, 33, 4, 230, 159, 33, 4, 230, 161, 33, 4, 230, 101, 33, 4, 230, + 62, 33, 4, 239, 8, 33, 4, 237, 230, 33, 4, 238, 81, 33, 4, 239, 5, 33, 4, + 238, 182, 33, 4, 238, 190, 33, 4, 238, 39, 33, 4, 238, 38, 33, 4, 237, + 190, 33, 4, 237, 186, 33, 4, 237, 189, 33, 4, 237, 187, 33, 4, 237, 188, + 33, 4, 238, 155, 33, 4, 238, 135, 33, 4, 238, 145, 33, 4, 238, 154, 33, + 4, 238, 149, 33, 4, 238, 150, 33, 4, 238, 139, 33, 4, 238, 124, 33, 4, + 209, 108, 33, 4, 209, 22, 33, 4, 209, 70, 33, 4, 209, 107, 33, 4, 209, + 90, 33, 4, 209, 92, 33, 4, 209, 47, 33, 4, 209, 13, 33, 4, 246, 199, 33, + 4, 246, 98, 33, 4, 246, 142, 33, 4, 246, 198, 33, 4, 246, 166, 33, 4, + 246, 170, 33, 4, 246, 116, 33, 4, 246, 87, 33, 4, 218, 208, 33, 4, 218, + 173, 33, 4, 218, 192, 33, 4, 218, 207, 33, 4, 218, 194, 33, 4, 218, 195, + 33, 4, 218, 180, 33, 4, 218, 169, 33, 4, 208, 20, 33, 4, 207, 249, 33, 4, + 207, 255, 33, 4, 208, 19, 33, 4, 208, 13, 33, 4, 208, 14, 33, 4, 207, + 253, 33, 4, 207, 247, 33, 4, 207, 106, 33, 4, 207, 98, 33, 4, 207, 102, + 33, 4, 207, 105, 33, 4, 207, 103, 33, 4, 207, 104, 33, 4, 207, 100, 33, + 4, 207, 99, 33, 4, 240, 108, 33, 4, 239, 108, 33, 4, 240, 26, 33, 4, 240, + 107, 33, 4, 240, 53, 33, 4, 240, 60, 33, 4, 239, 186, 33, 4, 239, 86, 33, + 4, 185, 33, 4, 217, 191, 33, 4, 218, 167, 33, 4, 219, 168, 33, 4, 219, + 23, 33, 4, 219, 34, 33, 4, 218, 69, 33, 4, 217, 152, 33, 4, 215, 101, 33, + 4, 223, 169, 33, 4, 239, 80, 33, 39, 238, 179, 25, 22, 227, 196, 82, 33, + 39, 22, 227, 196, 82, 33, 39, 238, 179, 82, 33, 214, 168, 82, 33, 203, + 237, 33, 239, 102, 211, 61, 33, 245, 233, 33, 213, 143, 33, 245, 242, 33, + 217, 246, 245, 242, 33, 217, 47, 82, 33, 219, 89, 213, 130, 33, 17, 105, + 33, 17, 108, 33, 17, 147, 33, 17, 149, 33, 17, 170, 33, 17, 195, 33, 17, + 213, 111, 33, 17, 199, 33, 17, 222, 63, 33, 42, 209, 152, 33, 42, 207, + 151, 33, 42, 209, 53, 33, 42, 239, 153, 33, 42, 240, 18, 33, 42, 212, 74, + 33, 42, 213, 105, 33, 42, 241, 134, 33, 42, 222, 58, 33, 42, 236, 11, 33, + 42, 209, 153, 209, 36, 33, 4, 214, 173, 223, 180, 33, 4, 223, 176, 33, 4, + 223, 177, 33, 4, 223, 178, 33, 4, 214, 173, 247, 142, 33, 4, 247, 139, + 33, 4, 247, 140, 33, 4, 247, 141, 33, 4, 214, 173, 239, 86, 33, 4, 239, + 82, 33, 4, 239, 83, 33, 4, 239, 84, 33, 4, 214, 173, 217, 152, 33, 4, + 217, 148, 33, 4, 217, 149, 33, 4, 217, 150, 33, 208, 162, 131, 202, 250, + 33, 208, 162, 131, 244, 22, 33, 208, 162, 131, 216, 2, 33, 208, 162, 131, + 212, 228, 216, 2, 33, 208, 162, 131, 243, 207, 33, 208, 162, 131, 229, + 179, 33, 208, 162, 131, 246, 124, 33, 208, 162, 131, 237, 0, 33, 208, + 162, 131, 244, 21, 33, 208, 162, 131, 228, 181, 90, 1, 63, 90, 1, 74, 90, + 1, 75, 90, 1, 78, 90, 1, 68, 90, 1, 206, 164, 90, 1, 239, 8, 90, 1, 173, + 90, 1, 238, 190, 90, 1, 238, 81, 90, 1, 238, 39, 90, 1, 237, 230, 90, 1, + 237, 192, 90, 1, 152, 90, 1, 237, 67, 90, 1, 237, 3, 90, 1, 236, 136, 90, + 1, 236, 26, 90, 1, 235, 255, 90, 1, 228, 113, 90, 1, 227, 234, 90, 1, + 227, 148, 90, 1, 227, 49, 90, 1, 226, 239, 90, 1, 226, 208, 90, 1, 192, + 90, 1, 225, 20, 90, 1, 224, 155, 90, 1, 224, 82, 90, 1, 223, 246, 90, 1, + 201, 201, 90, 1, 236, 160, 90, 1, 223, 93, 90, 1, 222, 240, 90, 1, 222, + 100, 90, 1, 221, 191, 90, 1, 221, 84, 90, 1, 221, 22, 90, 1, 217, 64, 90, + 1, 217, 50, 90, 1, 217, 43, 90, 1, 217, 34, 90, 1, 217, 23, 90, 1, 217, + 21, 90, 1, 215, 36, 90, 1, 194, 90, 1, 214, 177, 90, 1, 212, 162, 90, 1, + 212, 13, 90, 1, 211, 10, 90, 1, 210, 177, 90, 1, 244, 212, 90, 1, 210, + 22, 90, 1, 244, 75, 90, 1, 209, 187, 90, 1, 243, 233, 90, 1, 209, 2, 90, + 1, 243, 113, 90, 1, 242, 42, 90, 1, 242, 13, 90, 1, 243, 124, 90, 1, 208, + 190, 90, 1, 208, 189, 90, 1, 208, 178, 90, 1, 208, 177, 90, 1, 208, 176, + 90, 1, 208, 175, 90, 1, 208, 20, 90, 1, 208, 14, 90, 1, 207, 255, 90, 1, + 207, 253, 90, 1, 207, 249, 90, 1, 207, 248, 90, 1, 204, 111, 90, 1, 204, + 62, 90, 1, 204, 30, 90, 1, 204, 0, 90, 1, 203, 217, 90, 1, 203, 204, 90, + 1, 198, 90, 1, 203, 52, 90, 1, 203, 11, 90, 1, 202, 247, 90, 1, 202, 213, + 90, 1, 202, 177, 90, 1, 223, 187, 90, 5, 1, 203, 52, 90, 5, 1, 203, 11, + 90, 5, 1, 202, 247, 90, 5, 1, 202, 213, 90, 5, 1, 202, 177, 90, 5, 1, + 223, 187, 19, 20, 235, 220, 19, 20, 74, 19, 20, 251, 245, 19, 20, 75, 19, + 20, 231, 83, 19, 20, 78, 19, 20, 220, 18, 19, 20, 203, 123, 220, 18, 19, + 20, 88, 241, 161, 19, 20, 88, 75, 19, 20, 63, 19, 20, 252, 25, 19, 20, + 204, 62, 19, 20, 196, 204, 62, 19, 20, 204, 30, 19, 20, 196, 204, 30, 19, + 20, 204, 19, 19, 20, 196, 204, 19, 19, 20, 204, 0, 19, 20, 196, 204, 0, + 19, 20, 203, 244, 19, 20, 196, 203, 244, 19, 20, 223, 68, 203, 244, 19, + 20, 204, 111, 19, 20, 196, 204, 111, 19, 20, 204, 110, 19, 20, 196, 204, + 110, 19, 20, 223, 68, 204, 110, 19, 20, 251, 64, 19, 20, 203, 123, 204, + 144, 19, 20, 238, 45, 211, 61, 19, 20, 46, 165, 19, 20, 46, 237, 253, 19, + 20, 46, 247, 248, 162, 215, 252, 19, 20, 46, 208, 145, 162, 215, 252, 19, + 20, 46, 50, 162, 215, 252, 19, 20, 46, 215, 252, 19, 20, 46, 52, 165, 19, + 20, 46, 52, 212, 228, 80, 211, 19, 19, 20, 46, 101, 243, 85, 19, 20, 46, + 212, 228, 236, 106, 95, 19, 20, 46, 218, 76, 19, 20, 46, 121, 210, 3, 19, + 20, 241, 92, 19, 20, 231, 49, 19, 20, 220, 31, 19, 20, 250, 231, 19, 20, + 219, 34, 19, 20, 219, 166, 19, 20, 218, 167, 19, 20, 218, 129, 19, 20, + 218, 69, 19, 20, 218, 45, 19, 20, 203, 123, 218, 45, 19, 20, 88, 237, 48, + 19, 20, 88, 237, 3, 19, 20, 185, 19, 20, 219, 168, 19, 20, 217, 150, 19, + 20, 196, 217, 150, 19, 20, 217, 148, 19, 20, 196, 217, 148, 19, 20, 217, + 147, 19, 20, 196, 217, 147, 19, 20, 217, 145, 19, 20, 196, 217, 145, 19, + 20, 217, 144, 19, 20, 196, 217, 144, 19, 20, 217, 152, 19, 20, 196, 217, + 152, 19, 20, 217, 151, 19, 20, 196, 217, 151, 19, 20, 203, 123, 217, 151, + 19, 20, 219, 184, 19, 20, 196, 219, 184, 19, 20, 88, 237, 171, 19, 20, + 209, 187, 19, 20, 210, 16, 19, 20, 209, 2, 19, 20, 208, 242, 19, 20, 135, + 19, 20, 208, 148, 19, 20, 203, 123, 208, 148, 19, 20, 88, 244, 61, 19, + 20, 88, 243, 233, 19, 20, 210, 22, 19, 20, 210, 18, 19, 20, 207, 158, 19, + 20, 196, 207, 158, 19, 20, 207, 140, 19, 20, 196, 207, 140, 19, 20, 207, + 139, 19, 20, 196, 207, 139, 19, 20, 108, 19, 20, 196, 108, 19, 20, 207, + 130, 19, 20, 196, 207, 130, 19, 20, 207, 160, 19, 20, 196, 207, 160, 19, + 20, 207, 159, 19, 20, 196, 207, 159, 19, 20, 223, 68, 207, 159, 19, 20, + 210, 69, 19, 20, 207, 236, 19, 20, 207, 220, 19, 20, 207, 218, 19, 20, + 207, 241, 19, 20, 229, 201, 19, 20, 230, 36, 19, 20, 229, 100, 19, 20, + 229, 87, 19, 20, 229, 26, 19, 20, 229, 6, 19, 20, 203, 123, 229, 6, 19, + 20, 173, 19, 20, 230, 41, 19, 20, 228, 162, 19, 20, 196, 228, 162, 19, + 20, 228, 160, 19, 20, 196, 228, 160, 19, 20, 228, 159, 19, 20, 196, 228, + 159, 19, 20, 228, 157, 19, 20, 196, 228, 157, 19, 20, 228, 156, 19, 20, + 196, 228, 156, 19, 20, 228, 167, 19, 20, 196, 228, 167, 19, 20, 228, 166, + 19, 20, 196, 228, 166, 19, 20, 223, 68, 228, 166, 19, 20, 230, 54, 19, + 20, 228, 168, 19, 20, 211, 237, 229, 191, 19, 20, 211, 237, 229, 88, 19, + 20, 211, 237, 229, 20, 19, 20, 211, 237, 230, 20, 19, 20, 246, 238, 19, + 20, 247, 90, 19, 20, 246, 79, 19, 20, 246, 69, 19, 20, 245, 254, 19, 20, + 245, 180, 19, 20, 203, 123, 245, 180, 19, 20, 247, 92, 19, 20, 247, 91, + 19, 20, 245, 72, 19, 20, 196, 245, 72, 19, 20, 245, 70, 19, 20, 196, 245, + 70, 19, 20, 245, 69, 19, 20, 196, 245, 69, 19, 20, 245, 68, 19, 20, 196, + 245, 68, 19, 20, 245, 67, 19, 20, 196, 245, 67, 19, 20, 245, 74, 19, 20, + 196, 245, 74, 19, 20, 245, 73, 19, 20, 196, 245, 73, 19, 20, 223, 68, + 245, 73, 19, 20, 247, 125, 19, 20, 214, 206, 209, 110, 19, 20, 225, 20, + 19, 20, 225, 174, 19, 20, 224, 155, 19, 20, 224, 125, 19, 20, 224, 82, + 19, 20, 224, 35, 19, 20, 203, 123, 224, 35, 19, 20, 192, 19, 20, 225, + 175, 19, 20, 223, 178, 19, 20, 196, 223, 178, 19, 20, 223, 176, 19, 20, + 196, 223, 176, 19, 20, 223, 175, 19, 20, 196, 223, 175, 19, 20, 223, 174, + 19, 20, 196, 223, 174, 19, 20, 223, 173, 19, 20, 196, 223, 173, 19, 20, + 223, 180, 19, 20, 196, 223, 180, 19, 20, 223, 179, 19, 20, 196, 223, 179, + 19, 20, 223, 68, 223, 179, 19, 20, 226, 185, 19, 20, 196, 226, 185, 19, + 20, 224, 159, 19, 20, 250, 48, 226, 185, 19, 20, 214, 206, 226, 185, 19, + 20, 222, 240, 19, 20, 223, 105, 19, 20, 222, 100, 19, 20, 222, 75, 19, + 20, 221, 191, 19, 20, 221, 180, 19, 20, 203, 123, 221, 180, 19, 20, 201, + 201, 19, 20, 223, 106, 19, 20, 221, 18, 19, 20, 196, 221, 18, 19, 20, + 221, 20, 19, 20, 196, 221, 20, 19, 20, 221, 19, 19, 20, 196, 221, 19, 19, + 20, 223, 68, 221, 19, 19, 20, 223, 163, 19, 20, 88, 222, 205, 19, 20, + 222, 105, 19, 20, 227, 234, 19, 20, 228, 111, 19, 20, 227, 148, 19, 20, + 227, 130, 19, 20, 227, 49, 19, 20, 227, 18, 19, 20, 203, 123, 227, 18, + 19, 20, 228, 113, 19, 20, 228, 112, 19, 20, 226, 205, 19, 20, 196, 226, + 205, 19, 20, 226, 204, 19, 20, 196, 226, 204, 19, 20, 226, 203, 19, 20, + 196, 226, 203, 19, 20, 226, 202, 19, 20, 196, 226, 202, 19, 20, 226, 201, + 19, 20, 196, 226, 201, 19, 20, 226, 207, 19, 20, 196, 226, 207, 19, 20, + 226, 206, 19, 20, 196, 226, 206, 19, 20, 159, 19, 20, 196, 159, 19, 20, + 174, 159, 19, 20, 214, 177, 19, 20, 215, 31, 19, 20, 212, 162, 19, 20, + 212, 142, 19, 20, 212, 13, 19, 20, 211, 250, 19, 20, 203, 123, 211, 250, + 19, 20, 215, 36, 19, 20, 215, 33, 19, 20, 210, 168, 19, 20, 196, 210, + 168, 19, 20, 210, 162, 19, 20, 196, 210, 162, 19, 20, 210, 161, 19, 20, + 196, 210, 161, 19, 20, 210, 157, 19, 20, 196, 210, 157, 19, 20, 210, 156, + 19, 20, 196, 210, 156, 19, 20, 210, 172, 19, 20, 196, 210, 172, 19, 20, + 210, 171, 19, 20, 196, 210, 171, 19, 20, 223, 68, 210, 171, 19, 20, 194, + 19, 20, 250, 48, 194, 19, 20, 210, 173, 19, 20, 248, 40, 194, 19, 20, + 224, 28, 212, 70, 19, 20, 223, 68, 212, 61, 19, 20, 223, 68, 215, 92, 19, + 20, 223, 68, 211, 179, 19, 20, 223, 68, 211, 13, 19, 20, 223, 68, 212, + 60, 19, 20, 223, 68, 214, 180, 19, 20, 213, 43, 19, 20, 213, 11, 19, 20, + 213, 6, 19, 20, 212, 242, 19, 20, 212, 236, 19, 20, 213, 90, 19, 20, 213, + 85, 19, 20, 212, 177, 19, 20, 196, 212, 177, 19, 20, 212, 176, 19, 20, + 196, 212, 176, 19, 20, 212, 175, 19, 20, 196, 212, 175, 19, 20, 212, 174, + 19, 20, 196, 212, 174, 19, 20, 212, 173, 19, 20, 196, 212, 173, 19, 20, + 212, 180, 19, 20, 196, 212, 180, 19, 20, 212, 179, 19, 20, 196, 212, 179, + 19, 20, 213, 92, 19, 20, 203, 52, 19, 20, 203, 108, 19, 20, 203, 11, 19, + 20, 203, 2, 19, 20, 202, 247, 19, 20, 202, 232, 19, 20, 203, 123, 202, + 232, 19, 20, 198, 19, 20, 203, 110, 19, 20, 202, 174, 19, 20, 196, 202, + 174, 19, 20, 202, 173, 19, 20, 196, 202, 173, 19, 20, 202, 172, 19, 20, + 196, 202, 172, 19, 20, 202, 171, 19, 20, 196, 202, 171, 19, 20, 202, 170, + 19, 20, 196, 202, 170, 19, 20, 202, 176, 19, 20, 196, 202, 176, 19, 20, + 202, 175, 19, 20, 196, 202, 175, 19, 20, 223, 68, 202, 175, 19, 20, 203, + 124, 19, 20, 248, 84, 203, 124, 19, 20, 196, 203, 124, 19, 20, 214, 206, + 203, 11, 19, 20, 216, 158, 19, 20, 217, 0, 216, 158, 19, 20, 196, 227, + 234, 19, 20, 216, 215, 19, 20, 216, 57, 19, 20, 216, 3, 19, 20, 215, 227, + 19, 20, 215, 208, 19, 20, 196, 227, 49, 19, 20, 216, 220, 19, 20, 216, + 216, 19, 20, 196, 228, 113, 19, 20, 215, 110, 19, 20, 196, 215, 110, 19, + 20, 146, 19, 20, 196, 146, 19, 20, 174, 146, 19, 20, 240, 60, 19, 20, + 240, 105, 19, 20, 240, 26, 19, 20, 240, 12, 19, 20, 239, 186, 19, 20, + 239, 175, 19, 20, 240, 108, 19, 20, 240, 107, 19, 20, 239, 85, 19, 20, + 196, 239, 85, 19, 20, 240, 174, 19, 20, 209, 92, 19, 20, 223, 161, 209, + 92, 19, 20, 209, 70, 19, 20, 223, 161, 209, 70, 19, 20, 209, 64, 19, 20, + 223, 161, 209, 64, 19, 20, 209, 47, 19, 20, 209, 42, 19, 20, 209, 108, + 19, 20, 209, 107, 19, 20, 209, 12, 19, 20, 196, 209, 12, 19, 20, 209, + 110, 19, 20, 207, 227, 19, 20, 207, 225, 19, 20, 207, 224, 19, 20, 207, + 229, 19, 20, 207, 230, 19, 20, 207, 124, 19, 20, 207, 123, 19, 20, 207, + 122, 19, 20, 207, 126, 19, 20, 221, 39, 237, 67, 19, 20, 221, 39, 237, 3, + 19, 20, 221, 39, 236, 239, 19, 20, 221, 39, 236, 136, 19, 20, 221, 39, + 236, 117, 19, 20, 221, 39, 152, 19, 20, 221, 39, 237, 157, 19, 20, 221, + 39, 237, 171, 19, 20, 221, 38, 237, 171, 19, 20, 236, 226, 19, 20, 217, + 122, 19, 20, 217, 88, 19, 20, 217, 83, 19, 20, 217, 77, 19, 20, 217, 72, + 19, 20, 217, 126, 19, 20, 217, 125, 19, 20, 217, 134, 19, 20, 208, 186, + 19, 20, 208, 184, 19, 20, 208, 183, 19, 20, 208, 187, 19, 20, 196, 216, + 158, 19, 20, 196, 216, 57, 19, 20, 196, 215, 227, 19, 20, 196, 216, 220, + 19, 20, 222, 201, 19, 20, 222, 151, 19, 20, 222, 147, 19, 20, 222, 128, + 19, 20, 222, 123, 19, 20, 222, 203, 19, 20, 222, 202, 19, 20, 222, 205, + 19, 20, 221, 220, 19, 20, 214, 206, 213, 43, 19, 20, 214, 206, 213, 11, + 19, 20, 214, 206, 212, 242, 19, 20, 214, 206, 213, 90, 19, 20, 203, 242, + 209, 92, 19, 20, 203, 242, 209, 70, 19, 20, 203, 242, 209, 47, 19, 20, + 203, 242, 209, 108, 19, 20, 203, 242, 209, 110, 19, 20, 227, 155, 19, 20, + 227, 154, 19, 20, 227, 153, 19, 20, 227, 152, 19, 20, 227, 161, 19, 20, + 227, 160, 19, 20, 227, 162, 19, 20, 209, 109, 209, 92, 19, 20, 209, 109, + 209, 70, 19, 20, 209, 109, 209, 64, 19, 20, 209, 109, 209, 47, 19, 20, + 209, 109, 209, 42, 19, 20, 209, 109, 209, 108, 19, 20, 209, 109, 209, + 107, 19, 20, 209, 109, 209, 110, 19, 20, 251, 50, 249, 255, 19, 20, 248, + 40, 74, 19, 20, 248, 40, 75, 19, 20, 248, 40, 78, 19, 20, 248, 40, 63, + 19, 20, 248, 40, 204, 62, 19, 20, 248, 40, 204, 30, 19, 20, 248, 40, 204, + 0, 19, 20, 248, 40, 204, 111, 19, 20, 248, 40, 222, 240, 19, 20, 248, 40, + 222, 100, 19, 20, 248, 40, 221, 191, 19, 20, 248, 40, 201, 201, 19, 20, + 248, 40, 229, 201, 19, 20, 248, 40, 229, 100, 19, 20, 248, 40, 229, 26, + 19, 20, 248, 40, 173, 19, 20, 214, 206, 237, 67, 19, 20, 214, 206, 237, + 3, 19, 20, 214, 206, 236, 136, 19, 20, 214, 206, 152, 19, 20, 88, 238, + 87, 19, 20, 88, 238, 91, 19, 20, 88, 238, 105, 19, 20, 88, 238, 104, 19, + 20, 88, 238, 93, 19, 20, 88, 238, 119, 19, 20, 88, 215, 145, 19, 20, 88, + 215, 227, 19, 20, 88, 216, 158, 19, 20, 88, 216, 135, 19, 20, 88, 216, + 57, 19, 20, 88, 216, 220, 19, 20, 88, 203, 217, 19, 20, 88, 204, 0, 19, + 20, 88, 204, 62, 19, 20, 88, 204, 55, 19, 20, 88, 204, 30, 19, 20, 88, + 204, 111, 19, 20, 88, 235, 247, 19, 20, 88, 235, 248, 19, 20, 88, 235, + 251, 19, 20, 88, 235, 250, 19, 20, 88, 235, 249, 19, 20, 88, 235, 254, + 19, 20, 88, 209, 22, 19, 20, 88, 209, 47, 19, 20, 88, 209, 92, 19, 20, + 88, 209, 90, 19, 20, 88, 209, 70, 19, 20, 88, 209, 108, 19, 20, 88, 207, + 208, 19, 20, 88, 207, 218, 19, 20, 88, 207, 236, 19, 20, 88, 207, 235, + 19, 20, 88, 207, 220, 19, 20, 88, 207, 241, 19, 20, 88, 217, 191, 19, 20, + 88, 218, 69, 19, 20, 88, 219, 34, 19, 20, 88, 219, 23, 19, 20, 88, 218, + 167, 19, 20, 88, 185, 19, 20, 88, 219, 184, 19, 20, 88, 237, 230, 19, 20, + 88, 238, 39, 19, 20, 88, 238, 190, 19, 20, 88, 238, 182, 19, 20, 88, 238, + 81, 19, 20, 88, 239, 8, 19, 20, 88, 229, 109, 19, 20, 88, 229, 115, 19, + 20, 88, 229, 129, 19, 20, 88, 229, 128, 19, 20, 88, 229, 122, 19, 20, 88, + 229, 144, 19, 20, 88, 229, 42, 19, 20, 88, 229, 43, 19, 20, 88, 229, 46, + 19, 20, 88, 229, 45, 19, 20, 88, 229, 44, 19, 20, 88, 229, 47, 19, 20, + 88, 229, 48, 19, 20, 88, 221, 84, 19, 20, 88, 221, 191, 19, 20, 88, 222, + 240, 19, 20, 88, 222, 235, 19, 20, 88, 222, 100, 19, 20, 88, 201, 201, + 19, 20, 88, 223, 246, 19, 20, 88, 224, 82, 19, 20, 88, 225, 20, 19, 20, + 88, 225, 8, 19, 20, 88, 224, 155, 19, 20, 88, 192, 19, 20, 88, 202, 213, + 19, 20, 88, 202, 247, 19, 20, 88, 203, 52, 19, 20, 88, 203, 49, 19, 20, + 88, 203, 11, 19, 20, 88, 198, 19, 20, 88, 230, 82, 19, 20, 214, 206, 230, + 82, 19, 20, 88, 230, 101, 19, 20, 88, 230, 161, 19, 20, 88, 230, 159, 19, + 20, 88, 230, 141, 19, 20, 214, 206, 230, 141, 19, 20, 88, 230, 181, 19, + 20, 88, 230, 114, 19, 20, 88, 230, 118, 19, 20, 88, 230, 128, 19, 20, 88, + 230, 127, 19, 20, 88, 230, 126, 19, 20, 88, 230, 129, 19, 20, 88, 226, + 239, 19, 20, 88, 227, 49, 19, 20, 88, 227, 234, 19, 20, 88, 227, 226, 19, + 20, 88, 227, 148, 19, 20, 88, 228, 113, 19, 20, 88, 243, 117, 19, 20, 88, + 243, 118, 19, 20, 88, 243, 123, 19, 20, 88, 243, 122, 19, 20, 88, 243, + 119, 19, 20, 88, 243, 124, 19, 20, 88, 227, 151, 19, 20, 88, 227, 153, + 19, 20, 88, 227, 157, 19, 20, 88, 227, 156, 19, 20, 88, 227, 155, 19, 20, + 88, 227, 161, 19, 20, 88, 208, 181, 19, 20, 88, 208, 183, 19, 20, 88, + 208, 186, 19, 20, 88, 208, 185, 19, 20, 88, 208, 184, 19, 20, 88, 208, + 187, 19, 20, 88, 208, 176, 19, 20, 88, 208, 177, 19, 20, 88, 208, 189, + 19, 20, 88, 208, 188, 19, 20, 88, 208, 178, 19, 20, 88, 208, 190, 19, 20, + 88, 202, 6, 19, 20, 88, 202, 17, 19, 20, 88, 202, 92, 19, 20, 88, 202, + 90, 19, 20, 88, 202, 39, 19, 20, 88, 202, 116, 19, 20, 88, 202, 159, 19, + 20, 88, 81, 202, 159, 19, 20, 88, 241, 242, 19, 20, 88, 241, 243, 19, 20, + 88, 241, 252, 19, 20, 88, 241, 251, 19, 20, 88, 241, 246, 19, 20, 88, + 241, 255, 19, 20, 88, 211, 10, 19, 20, 88, 212, 13, 19, 20, 88, 214, 177, + 19, 20, 88, 214, 165, 19, 20, 88, 212, 162, 19, 20, 88, 215, 36, 19, 20, + 88, 212, 199, 19, 20, 88, 212, 242, 19, 20, 88, 213, 43, 19, 20, 88, 213, + 41, 19, 20, 88, 213, 11, 19, 20, 88, 213, 90, 19, 20, 88, 213, 92, 19, + 20, 88, 207, 249, 19, 20, 88, 207, 253, 19, 20, 88, 208, 14, 19, 20, 88, + 208, 13, 19, 20, 88, 207, 255, 19, 20, 88, 208, 20, 19, 20, 88, 246, 98, + 19, 20, 88, 246, 116, 19, 20, 88, 246, 170, 19, 20, 88, 246, 166, 19, 20, + 88, 246, 142, 19, 20, 88, 246, 199, 19, 20, 88, 207, 211, 19, 20, 88, + 207, 212, 19, 20, 88, 207, 215, 19, 20, 88, 207, 214, 19, 20, 88, 207, + 213, 19, 20, 88, 207, 216, 19, 20, 246, 143, 54, 19, 20, 239, 102, 211, + 61, 19, 20, 217, 118, 19, 20, 222, 199, 19, 20, 221, 217, 19, 20, 221, + 216, 19, 20, 221, 215, 19, 20, 221, 214, 19, 20, 221, 219, 19, 20, 221, + 218, 19, 20, 203, 242, 209, 10, 19, 20, 203, 242, 209, 9, 19, 20, 203, + 242, 209, 8, 19, 20, 203, 242, 209, 7, 19, 20, 203, 242, 209, 6, 19, 20, + 203, 242, 209, 13, 19, 20, 203, 242, 209, 12, 19, 20, 203, 242, 46, 209, + 110, 19, 20, 248, 40, 204, 144, 220, 64, 211, 229, 82, 220, 64, 1, 248, + 132, 220, 64, 1, 226, 225, 220, 64, 1, 240, 57, 220, 64, 1, 215, 16, 220, + 64, 1, 222, 56, 220, 64, 1, 207, 36, 220, 64, 1, 244, 186, 220, 64, 1, + 208, 214, 220, 64, 1, 245, 245, 220, 64, 1, 246, 225, 220, 64, 1, 223, + 233, 220, 64, 1, 238, 20, 220, 64, 1, 222, 189, 220, 64, 1, 211, 54, 220, + 64, 1, 215, 138, 220, 64, 1, 251, 61, 220, 64, 1, 220, 22, 220, 64, 1, + 206, 210, 220, 64, 1, 241, 187, 220, 64, 1, 230, 233, 220, 64, 1, 241, + 188, 220, 64, 1, 219, 244, 220, 64, 1, 207, 15, 220, 64, 1, 231, 89, 220, + 64, 1, 241, 185, 220, 64, 1, 219, 13, 220, 64, 240, 56, 82, 220, 64, 216, + 73, 240, 56, 82, 197, 1, 240, 46, 240, 38, 240, 61, 240, 174, 197, 1, + 206, 164, 197, 1, 206, 195, 206, 211, 68, 197, 1, 202, 216, 197, 1, 203, + 124, 197, 1, 204, 144, 197, 1, 209, 15, 209, 14, 209, 40, 197, 1, 240, + 243, 197, 1, 250, 199, 63, 197, 1, 219, 228, 78, 197, 1, 251, 142, 63, + 197, 1, 251, 93, 197, 1, 227, 24, 78, 197, 1, 212, 221, 78, 197, 1, 78, + 197, 1, 220, 73, 197, 1, 220, 31, 197, 1, 216, 195, 216, 208, 216, 120, + 146, 197, 1, 229, 216, 197, 1, 246, 221, 197, 1, 229, 217, 230, 54, 197, + 1, 239, 75, 197, 1, 241, 78, 197, 1, 238, 185, 237, 177, 239, 75, 197, 1, + 238, 224, 197, 1, 203, 209, 203, 200, 204, 144, 197, 1, 237, 149, 237, + 171, 197, 1, 237, 153, 237, 171, 197, 1, 227, 26, 237, 171, 197, 1, 212, + 224, 237, 171, 197, 1, 223, 63, 221, 2, 223, 64, 223, 163, 197, 1, 212, + 222, 223, 163, 197, 1, 242, 80, 197, 1, 230, 212, 230, 216, 230, 203, 75, + 197, 1, 74, 197, 1, 230, 152, 230, 184, 197, 1, 238, 169, 197, 1, 227, + 27, 251, 109, 197, 1, 212, 226, 63, 197, 1, 230, 195, 241, 51, 197, 1, + 218, 226, 218, 251, 219, 184, 197, 1, 251, 23, 241, 49, 197, 1, 211, 234, + 194, 197, 1, 212, 146, 227, 23, 194, 197, 1, 212, 220, 194, 197, 1, 247, + 125, 197, 1, 202, 159, 197, 1, 208, 195, 208, 207, 207, 108, 210, 69, + 197, 1, 212, 219, 210, 69, 197, 1, 245, 51, 197, 1, 248, 111, 248, 114, + 248, 46, 249, 255, 197, 1, 212, 225, 249, 255, 197, 1, 242, 79, 197, 1, + 220, 2, 197, 1, 241, 146, 241, 148, 74, 197, 1, 225, 113, 225, 123, 226, + 185, 197, 1, 227, 25, 226, 185, 197, 1, 212, 223, 226, 185, 197, 1, 227, + 249, 228, 91, 227, 34, 159, 197, 1, 242, 81, 197, 1, 231, 23, 197, 1, + 231, 24, 197, 1, 244, 200, 244, 206, 245, 51, 197, 1, 219, 222, 240, 242, + 78, 197, 1, 241, 183, 197, 1, 230, 232, 197, 1, 245, 71, 197, 1, 247, 75, + 197, 1, 246, 237, 197, 1, 211, 99, 197, 1, 227, 22, 197, 1, 212, 218, + 197, 1, 235, 161, 197, 1, 217, 134, 197, 1, 203, 196, 197, 212, 120, 217, + 178, 197, 223, 226, 217, 178, 197, 245, 131, 217, 178, 197, 250, 108, 97, + 197, 207, 162, 97, 197, 248, 130, 97, 197, 1, 230, 54, 197, 1, 213, 92, + 197, 1, 220, 18, 197, 1, 239, 131, 247, 20, 219, 227, 197, 1, 239, 131, + 247, 20, 230, 215, 197, 1, 239, 131, 247, 20, 241, 147, 197, 1, 239, 131, + 247, 20, 251, 141, 197, 1, 239, 131, 247, 20, 251, 93, 209, 254, 1, 63, + 209, 254, 1, 75, 209, 254, 1, 68, 209, 254, 1, 173, 209, 254, 1, 239, 8, + 209, 254, 1, 222, 203, 209, 254, 1, 210, 22, 209, 254, 1, 244, 212, 209, + 254, 1, 201, 201, 209, 254, 1, 185, 209, 254, 1, 249, 32, 209, 254, 1, + 192, 209, 254, 1, 198, 209, 254, 1, 228, 113, 209, 254, 1, 204, 111, 209, + 254, 1, 215, 36, 209, 254, 1, 152, 209, 254, 22, 2, 75, 209, 254, 22, 2, + 68, 209, 254, 2, 205, 204, 237, 96, 1, 63, 237, 96, 1, 75, 237, 96, 1, + 68, 237, 96, 1, 173, 237, 96, 1, 239, 8, 237, 96, 1, 222, 203, 237, 96, + 1, 210, 22, 237, 96, 1, 244, 212, 237, 96, 1, 201, 201, 237, 96, 1, 185, + 237, 96, 1, 249, 32, 237, 96, 1, 192, 237, 96, 1, 198, 237, 96, 1, 216, + 220, 237, 96, 1, 228, 113, 237, 96, 1, 204, 111, 237, 96, 1, 215, 36, + 237, 96, 1, 152, 237, 96, 22, 2, 75, 237, 96, 22, 2, 68, 237, 96, 2, 219, + 124, 218, 185, 212, 120, 217, 178, 218, 185, 52, 217, 178, 247, 185, 1, + 63, 247, 185, 1, 75, 247, 185, 1, 68, 247, 185, 1, 173, 247, 185, 1, 239, + 8, 247, 185, 1, 222, 203, 247, 185, 1, 210, 22, 247, 185, 1, 244, 212, + 247, 185, 1, 201, 201, 247, 185, 1, 185, 247, 185, 1, 249, 32, 247, 185, + 1, 192, 247, 185, 1, 198, 247, 185, 1, 216, 220, 247, 185, 1, 228, 113, + 247, 185, 1, 204, 111, 247, 185, 1, 215, 36, 247, 185, 1, 152, 247, 185, + 22, 2, 75, 247, 185, 22, 2, 68, 209, 253, 1, 63, 209, 253, 1, 75, 209, + 253, 1, 68, 209, 253, 1, 173, 209, 253, 1, 239, 8, 209, 253, 1, 222, 203, + 209, 253, 1, 210, 22, 209, 253, 1, 244, 212, 209, 253, 1, 201, 201, 209, + 253, 1, 185, 209, 253, 1, 249, 32, 209, 253, 1, 192, 209, 253, 1, 198, + 209, 253, 1, 228, 113, 209, 253, 1, 204, 111, 209, 253, 1, 215, 36, 209, + 253, 22, 2, 75, 209, 253, 22, 2, 68, 85, 1, 173, 85, 1, 229, 144, 85, 1, + 229, 26, 85, 1, 229, 115, 85, 1, 222, 128, 85, 1, 247, 92, 85, 1, 246, + 199, 85, 1, 245, 254, 85, 1, 246, 116, 85, 1, 220, 233, 85, 1, 244, 212, + 85, 1, 207, 229, 85, 1, 243, 113, 85, 1, 207, 224, 85, 1, 221, 197, 85, + 1, 210, 22, 85, 1, 209, 108, 85, 1, 135, 85, 1, 209, 47, 85, 1, 221, 191, + 85, 1, 249, 32, 85, 1, 218, 208, 85, 1, 218, 69, 85, 1, 218, 180, 85, 1, + 224, 82, 85, 1, 202, 247, 85, 1, 215, 227, 85, 1, 227, 49, 85, 1, 205, + 189, 85, 1, 213, 90, 85, 1, 211, 124, 85, 1, 215, 36, 85, 1, 152, 85, 1, + 228, 113, 85, 1, 217, 126, 85, 231, 36, 22, 217, 112, 85, 231, 36, 22, + 217, 125, 85, 231, 36, 22, 217, 88, 85, 231, 36, 22, 217, 83, 85, 231, + 36, 22, 217, 65, 85, 231, 36, 22, 217, 35, 85, 231, 36, 22, 217, 23, 85, + 231, 36, 22, 217, 22, 85, 231, 36, 22, 215, 102, 85, 231, 36, 22, 215, + 95, 85, 231, 36, 22, 226, 199, 85, 231, 36, 22, 226, 188, 85, 231, 36, + 22, 217, 106, 85, 231, 36, 22, 217, 118, 85, 231, 36, 22, 217, 73, 207, + 121, 105, 85, 231, 36, 22, 217, 73, 207, 121, 108, 85, 231, 36, 22, 217, + 108, 85, 22, 231, 21, 250, 148, 85, 22, 231, 21, 252, 25, 85, 22, 2, 252, + 25, 85, 22, 2, 75, 85, 22, 2, 231, 83, 85, 22, 2, 203, 124, 85, 22, 2, + 202, 169, 85, 22, 2, 68, 85, 22, 2, 206, 178, 85, 22, 2, 207, 39, 85, 22, + 2, 220, 73, 85, 22, 2, 198, 85, 22, 2, 231, 110, 85, 22, 2, 74, 85, 22, + 2, 251, 109, 85, 22, 2, 251, 64, 85, 22, 2, 220, 18, 85, 22, 2, 250, 34, + 85, 2, 222, 73, 85, 2, 216, 156, 85, 2, 202, 180, 85, 2, 223, 190, 85, 2, + 208, 73, 85, 2, 248, 233, 85, 2, 215, 222, 85, 2, 208, 171, 85, 2, 230, + 11, 85, 2, 251, 66, 85, 2, 214, 244, 214, 237, 85, 2, 205, 201, 85, 2, + 245, 248, 85, 2, 248, 205, 85, 2, 229, 136, 85, 2, 248, 228, 85, 2, 247, + 64, 218, 130, 228, 173, 85, 2, 227, 203, 208, 148, 85, 2, 248, 100, 85, + 2, 218, 182, 223, 243, 85, 2, 229, 4, 85, 245, 92, 16, 216, 49, 85, 2, + 250, 16, 85, 2, 250, 37, 85, 17, 202, 84, 85, 17, 105, 85, 17, 108, 85, + 17, 147, 85, 17, 149, 85, 17, 170, 85, 17, 195, 85, 17, 213, 111, 85, 17, + 199, 85, 17, 222, 63, 85, 16, 227, 203, 250, 39, 211, 253, 85, 16, 227, + 203, 250, 39, 223, 210, 85, 16, 227, 203, 250, 39, 218, 129, 85, 16, 227, + 203, 250, 39, 248, 133, 85, 16, 227, 203, 250, 39, 247, 165, 85, 16, 227, + 203, 250, 39, 218, 7, 85, 16, 227, 203, 250, 39, 218, 1, 85, 16, 227, + 203, 250, 39, 217, 255, 85, 16, 227, 203, 250, 39, 218, 5, 85, 16, 227, + 203, 250, 39, 218, 3, 94, 248, 59, 94, 241, 108, 94, 245, 233, 94, 239, + 102, 211, 61, 94, 245, 242, 94, 239, 147, 243, 83, 94, 208, 170, 212, 7, + 235, 220, 94, 212, 160, 4, 247, 244, 225, 88, 94, 225, 119, 245, 233, 94, + 225, 119, 239, 102, 211, 61, 94, 222, 54, 94, 239, 130, 57, 214, 151, + 105, 94, 239, 130, 57, 214, 151, 108, 94, 239, 130, 57, 214, 151, 147, + 94, 22, 213, 130, 94, 17, 202, 84, 94, 17, 105, 94, 17, 108, 94, 17, 147, + 94, 17, 149, 94, 17, 170, 94, 17, 195, 94, 17, 213, 111, 94, 17, 199, 94, + 17, 222, 63, 94, 1, 63, 94, 1, 74, 94, 1, 75, 94, 1, 78, 94, 1, 68, 94, + 1, 220, 73, 94, 1, 207, 24, 94, 1, 241, 161, 94, 1, 201, 201, 94, 1, 250, + 223, 94, 1, 249, 32, 94, 1, 185, 94, 1, 217, 126, 94, 1, 239, 8, 94, 1, + 192, 94, 1, 228, 113, 94, 1, 215, 36, 94, 1, 213, 90, 94, 1, 210, 22, 94, + 1, 244, 212, 94, 1, 246, 199, 94, 1, 230, 181, 94, 1, 198, 94, 1, 216, + 220, 94, 1, 204, 111, 94, 1, 240, 108, 94, 1, 173, 94, 1, 229, 144, 94, + 1, 208, 20, 94, 1, 202, 116, 94, 1, 237, 157, 94, 1, 202, 10, 94, 1, 227, + 161, 94, 1, 202, 66, 94, 1, 246, 142, 94, 1, 208, 170, 163, 22, 54, 94, + 1, 208, 170, 74, 94, 1, 208, 170, 75, 94, 1, 208, 170, 78, 94, 1, 208, + 170, 68, 94, 1, 208, 170, 220, 73, 94, 1, 208, 170, 207, 24, 94, 1, 208, + 170, 250, 223, 94, 1, 208, 170, 249, 32, 94, 1, 208, 170, 185, 94, 1, + 208, 170, 217, 126, 94, 1, 208, 170, 239, 8, 94, 1, 208, 170, 192, 94, 1, + 208, 170, 210, 22, 94, 1, 208, 170, 244, 212, 94, 1, 208, 170, 246, 199, + 94, 1, 208, 170, 230, 181, 94, 1, 208, 170, 208, 20, 94, 1, 208, 170, + 198, 94, 1, 208, 170, 204, 111, 94, 1, 208, 170, 173, 94, 1, 208, 170, + 239, 5, 94, 1, 208, 170, 237, 157, 94, 1, 208, 170, 230, 140, 94, 1, 208, + 170, 222, 98, 94, 1, 208, 170, 241, 255, 94, 1, 212, 160, 74, 94, 1, 212, + 160, 75, 94, 1, 212, 160, 230, 192, 94, 1, 212, 160, 207, 24, 94, 1, 212, + 160, 68, 94, 1, 212, 160, 250, 223, 94, 1, 212, 160, 173, 94, 1, 212, + 160, 239, 8, 94, 1, 212, 160, 152, 94, 1, 212, 160, 185, 94, 1, 212, 160, + 213, 90, 94, 1, 212, 160, 210, 22, 94, 1, 212, 160, 244, 212, 94, 1, 212, + 160, 230, 181, 94, 1, 212, 160, 240, 108, 94, 1, 212, 160, 239, 5, 94, 1, + 212, 160, 237, 157, 94, 1, 212, 160, 208, 20, 94, 1, 212, 160, 202, 116, + 94, 1, 212, 160, 216, 216, 94, 1, 212, 160, 246, 199, 94, 1, 212, 160, + 202, 80, 94, 1, 225, 119, 75, 94, 1, 225, 119, 173, 94, 1, 225, 119, 216, + 220, 94, 1, 225, 119, 240, 108, 94, 1, 225, 119, 202, 80, 94, 1, 251, 22, + 238, 244, 250, 181, 105, 94, 1, 251, 22, 238, 244, 205, 200, 105, 94, 1, + 251, 22, 238, 244, 244, 174, 94, 1, 251, 22, 238, 244, 207, 34, 94, 1, + 251, 22, 238, 244, 230, 239, 207, 34, 94, 1, 251, 22, 238, 244, 248, 245, + 94, 1, 251, 22, 238, 244, 126, 248, 245, 94, 1, 251, 22, 238, 244, 63, + 94, 1, 251, 22, 238, 244, 75, 94, 1, 251, 22, 238, 244, 173, 94, 1, 251, + 22, 238, 244, 222, 203, 94, 1, 251, 22, 238, 244, 247, 92, 94, 1, 251, + 22, 238, 244, 207, 241, 94, 1, 251, 22, 238, 244, 207, 229, 94, 1, 251, + 22, 238, 244, 244, 120, 94, 1, 251, 22, 238, 244, 221, 227, 94, 1, 251, + 22, 238, 244, 210, 22, 94, 1, 251, 22, 238, 244, 244, 212, 94, 1, 251, + 22, 238, 244, 185, 94, 1, 251, 22, 238, 244, 218, 208, 94, 1, 251, 22, + 238, 244, 211, 164, 94, 1, 251, 22, 238, 244, 202, 80, 94, 1, 251, 22, + 238, 244, 202, 116, 94, 1, 251, 22, 238, 244, 251, 73, 94, 1, 208, 170, + 251, 22, 238, 244, 210, 22, 94, 1, 208, 170, 251, 22, 238, 244, 202, 80, + 94, 1, 225, 119, 251, 22, 238, 244, 238, 119, 94, 1, 225, 119, 251, 22, + 238, 244, 222, 203, 94, 1, 225, 119, 251, 22, 238, 244, 247, 92, 94, 1, + 225, 119, 251, 22, 238, 244, 230, 149, 94, 1, 225, 119, 251, 22, 238, + 244, 207, 241, 94, 1, 225, 119, 251, 22, 238, 244, 244, 104, 94, 1, 225, + 119, 251, 22, 238, 244, 210, 22, 94, 1, 225, 119, 251, 22, 238, 244, 244, + 1, 94, 1, 225, 119, 251, 22, 238, 244, 211, 164, 94, 1, 225, 119, 251, + 22, 238, 244, 245, 65, 94, 1, 225, 119, 251, 22, 238, 244, 202, 80, 94, + 1, 225, 119, 251, 22, 238, 244, 202, 116, 94, 1, 251, 22, 238, 244, 162, + 68, 94, 1, 251, 22, 238, 244, 162, 198, 94, 1, 225, 119, 251, 22, 238, + 244, 248, 98, 94, 1, 251, 22, 238, 244, 244, 201, 94, 1, 225, 119, 251, + 22, 238, 244, 227, 161, 19, 20, 219, 188, 19, 20, 250, 8, 19, 20, 251, + 236, 19, 20, 204, 65, 19, 20, 218, 13, 19, 20, 219, 43, 19, 20, 217, 143, + 19, 20, 209, 196, 19, 20, 229, 208, 19, 20, 228, 164, 19, 20, 225, 63, + 19, 20, 221, 149, 19, 20, 223, 59, 19, 20, 227, 244, 19, 20, 211, 232, + 19, 20, 214, 208, 19, 20, 212, 207, 19, 20, 213, 47, 19, 20, 212, 172, + 19, 20, 202, 222, 19, 20, 203, 58, 19, 20, 216, 165, 19, 20, 221, 17, 19, + 20, 220, 53, 221, 17, 19, 20, 221, 16, 19, 20, 220, 53, 221, 16, 19, 20, + 221, 15, 19, 20, 220, 53, 221, 15, 19, 20, 221, 14, 19, 20, 220, 53, 221, + 14, 19, 20, 215, 107, 19, 20, 215, 106, 19, 20, 215, 105, 19, 20, 215, + 104, 19, 20, 215, 103, 19, 20, 215, 111, 19, 20, 220, 53, 219, 184, 19, + 20, 220, 53, 210, 69, 19, 20, 220, 53, 230, 54, 19, 20, 220, 53, 247, + 125, 19, 20, 220, 53, 226, 185, 19, 20, 220, 53, 223, 163, 19, 20, 220, + 53, 194, 19, 20, 220, 53, 213, 92, 19, 20, 241, 174, 204, 144, 19, 20, + 204, 44, 204, 144, 19, 20, 46, 5, 215, 252, 19, 20, 46, 216, 188, 243, + 85, 19, 20, 217, 0, 215, 108, 19, 20, 196, 227, 18, 19, 20, 196, 228, + 112, 19, 20, 209, 11, 19, 20, 209, 13, 19, 20, 207, 221, 19, 20, 207, + 223, 19, 20, 207, 228, 19, 20, 208, 180, 19, 20, 208, 182, 19, 20, 214, + 206, 212, 177, 19, 20, 214, 206, 212, 236, 19, 20, 214, 206, 236, 117, + 19, 20, 88, 237, 185, 19, 20, 88, 244, 35, 238, 182, 19, 20, 88, 239, 5, + 19, 20, 88, 237, 190, 19, 20, 214, 206, 230, 64, 19, 20, 88, 230, 62, 19, + 20, 248, 153, 244, 35, 159, 19, 20, 248, 153, 244, 35, 146, 19, 20, 88, + 244, 30, 194, 227, 124, 205, 169, 227, 174, 227, 124, 1, 173, 227, 124, + 1, 229, 144, 227, 124, 1, 239, 8, 227, 124, 1, 238, 119, 227, 124, 1, + 222, 203, 227, 124, 1, 247, 92, 227, 124, 1, 246, 199, 227, 124, 1, 230, + 181, 227, 124, 1, 230, 149, 227, 124, 1, 203, 78, 227, 124, 1, 210, 22, + 227, 124, 1, 209, 108, 227, 124, 1, 244, 212, 227, 124, 1, 244, 1, 227, + 124, 1, 201, 201, 227, 124, 1, 185, 227, 124, 1, 218, 208, 227, 124, 1, + 249, 32, 227, 124, 1, 248, 98, 227, 124, 1, 192, 227, 124, 1, 198, 227, + 124, 1, 216, 220, 227, 124, 1, 228, 113, 227, 124, 1, 204, 111, 227, 124, + 1, 213, 90, 227, 124, 1, 211, 164, 227, 124, 1, 215, 36, 227, 124, 1, + 152, 227, 124, 1, 237, 181, 227, 124, 1, 208, 119, 227, 124, 22, 2, 63, + 227, 124, 22, 2, 75, 227, 124, 22, 2, 68, 227, 124, 22, 2, 241, 161, 227, + 124, 22, 2, 251, 64, 227, 124, 22, 2, 220, 18, 227, 124, 22, 2, 250, 34, + 227, 124, 22, 2, 74, 227, 124, 22, 2, 78, 227, 124, 210, 254, 1, 198, + 227, 124, 210, 254, 1, 216, 220, 227, 124, 210, 254, 1, 204, 111, 227, + 124, 5, 1, 173, 227, 124, 5, 1, 222, 203, 227, 124, 5, 1, 250, 180, 227, + 124, 5, 1, 210, 22, 227, 124, 5, 1, 201, 201, 227, 124, 5, 1, 185, 227, + 124, 5, 1, 192, 227, 124, 5, 1, 216, 220, 227, 124, 5, 1, 228, 113, 227, + 124, 2, 223, 231, 227, 124, 2, 229, 186, 227, 124, 2, 215, 34, 227, 124, + 2, 227, 18, 227, 124, 240, 212, 82, 227, 124, 217, 47, 82, 227, 124, 17, + 202, 84, 227, 124, 17, 105, 227, 124, 17, 108, 227, 124, 17, 147, 227, + 124, 17, 149, 227, 124, 17, 170, 227, 124, 17, 195, 227, 124, 17, 213, + 111, 227, 124, 17, 199, 227, 124, 17, 222, 63, 45, 227, 235, 1, 173, 45, + 227, 235, 1, 203, 182, 45, 227, 235, 1, 222, 203, 45, 227, 235, 1, 208, + 20, 45, 227, 235, 1, 215, 36, 45, 227, 235, 1, 198, 45, 227, 235, 1, 210, + 22, 45, 227, 235, 1, 209, 108, 45, 227, 235, 1, 228, 113, 45, 227, 235, + 1, 185, 45, 227, 235, 1, 218, 208, 45, 227, 235, 1, 192, 45, 227, 235, 1, + 240, 108, 45, 227, 235, 1, 206, 86, 45, 227, 235, 1, 152, 45, 227, 235, + 1, 217, 126, 45, 227, 235, 1, 229, 144, 45, 227, 235, 1, 208, 10, 45, + 227, 235, 1, 201, 201, 45, 227, 235, 1, 63, 45, 227, 235, 1, 75, 45, 227, + 235, 1, 241, 161, 45, 227, 235, 1, 241, 147, 45, 227, 235, 1, 68, 45, + 227, 235, 1, 220, 18, 45, 227, 235, 1, 78, 45, 227, 235, 1, 207, 24, 45, + 227, 235, 1, 74, 45, 227, 235, 1, 250, 32, 45, 227, 235, 1, 251, 64, 45, + 227, 235, 1, 208, 159, 45, 227, 235, 1, 208, 158, 45, 227, 235, 1, 208, + 157, 45, 227, 235, 1, 208, 156, 45, 227, 235, 1, 208, 155, 222, 214, 45, + 226, 233, 1, 138, 217, 126, 222, 214, 45, 226, 233, 1, 124, 217, 126, + 222, 214, 45, 226, 233, 1, 138, 173, 222, 214, 45, 226, 233, 1, 138, 203, + 182, 222, 214, 45, 226, 233, 1, 138, 222, 203, 222, 214, 45, 226, 233, 1, + 124, 173, 222, 214, 45, 226, 233, 1, 124, 203, 182, 222, 214, 45, 226, + 233, 1, 124, 222, 203, 222, 214, 45, 226, 233, 1, 138, 208, 20, 222, 214, + 45, 226, 233, 1, 138, 215, 36, 222, 214, 45, 226, 233, 1, 138, 198, 222, + 214, 45, 226, 233, 1, 124, 208, 20, 222, 214, 45, 226, 233, 1, 124, 215, + 36, 222, 214, 45, 226, 233, 1, 124, 198, 222, 214, 45, 226, 233, 1, 138, + 210, 22, 222, 214, 45, 226, 233, 1, 138, 209, 108, 222, 214, 45, 226, + 233, 1, 138, 201, 201, 222, 214, 45, 226, 233, 1, 124, 210, 22, 222, 214, + 45, 226, 233, 1, 124, 209, 108, 222, 214, 45, 226, 233, 1, 124, 201, 201, + 222, 214, 45, 226, 233, 1, 138, 185, 222, 214, 45, 226, 233, 1, 138, 218, + 208, 222, 214, 45, 226, 233, 1, 138, 192, 222, 214, 45, 226, 233, 1, 124, + 185, 222, 214, 45, 226, 233, 1, 124, 218, 208, 222, 214, 45, 226, 233, 1, + 124, 192, 222, 214, 45, 226, 233, 1, 138, 240, 108, 222, 214, 45, 226, + 233, 1, 138, 206, 86, 222, 214, 45, 226, 233, 1, 138, 228, 113, 222, 214, + 45, 226, 233, 1, 124, 240, 108, 222, 214, 45, 226, 233, 1, 124, 206, 86, + 222, 214, 45, 226, 233, 1, 124, 228, 113, 222, 214, 45, 226, 233, 1, 138, + 152, 222, 214, 45, 226, 233, 1, 138, 244, 212, 222, 214, 45, 226, 233, 1, + 138, 249, 32, 222, 214, 45, 226, 233, 1, 124, 152, 222, 214, 45, 226, + 233, 1, 124, 244, 212, 222, 214, 45, 226, 233, 1, 124, 249, 32, 222, 214, + 45, 226, 233, 1, 138, 228, 169, 222, 214, 45, 226, 233, 1, 138, 203, 149, + 222, 214, 45, 226, 233, 1, 124, 228, 169, 222, 214, 45, 226, 233, 1, 124, + 203, 149, 222, 214, 45, 226, 233, 1, 138, 211, 9, 222, 214, 45, 226, 233, + 1, 124, 211, 9, 222, 214, 45, 226, 233, 22, 2, 22, 212, 216, 222, 214, + 45, 226, 233, 22, 2, 252, 25, 222, 214, 45, 226, 233, 22, 2, 231, 83, + 222, 214, 45, 226, 233, 22, 2, 68, 222, 214, 45, 226, 233, 22, 2, 206, + 178, 222, 214, 45, 226, 233, 22, 2, 74, 222, 214, 45, 226, 233, 22, 2, + 251, 109, 222, 214, 45, 226, 233, 22, 2, 78, 222, 214, 45, 226, 233, 22, + 2, 220, 97, 222, 214, 45, 226, 233, 22, 2, 207, 24, 222, 214, 45, 226, + 233, 22, 2, 250, 8, 222, 214, 45, 226, 233, 22, 2, 251, 236, 222, 214, + 45, 226, 233, 22, 2, 206, 170, 222, 214, 45, 226, 233, 22, 2, 219, 188, + 222, 214, 45, 226, 233, 22, 2, 220, 94, 222, 214, 45, 226, 233, 22, 2, + 207, 20, 222, 214, 45, 226, 233, 22, 2, 230, 192, 222, 214, 45, 226, 233, + 1, 46, 206, 164, 222, 214, 45, 226, 233, 1, 46, 222, 205, 222, 214, 45, + 226, 233, 1, 46, 223, 163, 222, 214, 45, 226, 233, 1, 46, 226, 185, 222, + 214, 45, 226, 233, 1, 46, 230, 54, 222, 214, 45, 226, 233, 1, 46, 245, + 51, 222, 214, 45, 226, 233, 1, 46, 249, 255, 222, 214, 45, 226, 233, 143, + 225, 92, 222, 214, 45, 226, 233, 143, 225, 91, 222, 214, 45, 226, 233, + 17, 202, 84, 222, 214, 45, 226, 233, 17, 105, 222, 214, 45, 226, 233, 17, + 108, 222, 214, 45, 226, 233, 17, 147, 222, 214, 45, 226, 233, 17, 149, + 222, 214, 45, 226, 233, 17, 170, 222, 214, 45, 226, 233, 17, 195, 222, + 214, 45, 226, 233, 17, 213, 111, 222, 214, 45, 226, 233, 17, 199, 222, + 214, 45, 226, 233, 17, 222, 63, 222, 214, 45, 226, 233, 104, 17, 105, + 222, 214, 45, 226, 233, 2, 228, 97, 222, 214, 45, 226, 233, 2, 228, 96, + 85, 16, 219, 51, 85, 16, 223, 211, 229, 22, 85, 16, 218, 130, 229, 22, + 85, 16, 248, 134, 229, 22, 85, 16, 247, 166, 229, 22, 85, 16, 218, 8, + 229, 22, 85, 16, 218, 2, 229, 22, 85, 16, 218, 0, 229, 22, 85, 16, 218, + 6, 229, 22, 85, 16, 218, 4, 229, 22, 85, 16, 244, 161, 229, 22, 85, 16, + 244, 157, 229, 22, 85, 16, 244, 156, 229, 22, 85, 16, 244, 159, 229, 22, + 85, 16, 244, 158, 229, 22, 85, 16, 244, 155, 229, 22, 85, 16, 207, 167, + 85, 16, 223, 211, 215, 220, 85, 16, 218, 130, 215, 220, 85, 16, 248, 134, + 215, 220, 85, 16, 247, 166, 215, 220, 85, 16, 218, 8, 215, 220, 85, 16, + 218, 2, 215, 220, 85, 16, 218, 0, 215, 220, 85, 16, 218, 6, 215, 220, 85, + 16, 218, 4, 215, 220, 85, 16, 244, 161, 215, 220, 85, 16, 244, 157, 215, + 220, 85, 16, 244, 156, 215, 220, 85, 16, 244, 159, 215, 220, 85, 16, 244, + 158, 215, 220, 85, 16, 244, 155, 215, 220, 247, 186, 1, 173, 247, 186, 1, + 239, 8, 247, 186, 1, 222, 203, 247, 186, 1, 222, 146, 247, 186, 1, 185, + 247, 186, 1, 249, 32, 247, 186, 1, 192, 247, 186, 1, 223, 250, 247, 186, + 1, 210, 22, 247, 186, 1, 244, 212, 247, 186, 1, 201, 201, 247, 186, 1, + 221, 147, 247, 186, 1, 247, 92, 247, 186, 1, 230, 181, 247, 186, 1, 221, + 11, 247, 186, 1, 221, 3, 247, 186, 1, 198, 247, 186, 1, 216, 220, 247, + 186, 1, 228, 113, 247, 186, 1, 206, 86, 247, 186, 1, 215, 36, 247, 186, + 1, 63, 247, 186, 1, 152, 247, 186, 22, 2, 75, 247, 186, 22, 2, 68, 247, + 186, 22, 2, 74, 247, 186, 22, 2, 78, 247, 186, 22, 2, 251, 109, 247, 186, + 219, 136, 247, 186, 241, 84, 76, 214, 167, 45, 104, 1, 138, 173, 45, 104, + 1, 138, 229, 144, 45, 104, 1, 138, 228, 153, 45, 104, 1, 124, 173, 45, + 104, 1, 124, 228, 153, 45, 104, 1, 124, 229, 144, 45, 104, 1, 222, 203, + 45, 104, 1, 138, 247, 92, 45, 104, 1, 138, 246, 199, 45, 104, 1, 124, + 247, 92, 45, 104, 1, 124, 215, 36, 45, 104, 1, 124, 246, 199, 45, 104, 1, + 221, 11, 45, 104, 1, 216, 171, 45, 104, 1, 138, 216, 169, 45, 104, 1, + 244, 212, 45, 104, 1, 124, 216, 169, 45, 104, 1, 216, 180, 45, 104, 1, + 138, 210, 22, 45, 104, 1, 138, 209, 108, 45, 104, 1, 124, 210, 22, 45, + 104, 1, 124, 209, 108, 45, 104, 1, 201, 201, 45, 104, 1, 249, 32, 45, + 104, 1, 138, 185, 45, 104, 1, 138, 218, 208, 45, 104, 1, 138, 240, 108, + 45, 104, 1, 124, 185, 45, 104, 1, 124, 240, 108, 45, 104, 1, 124, 218, + 208, 45, 104, 1, 192, 45, 104, 1, 124, 198, 45, 104, 1, 138, 198, 45, + 104, 1, 216, 220, 45, 104, 1, 215, 140, 45, 104, 1, 228, 113, 45, 104, 1, + 226, 232, 45, 104, 1, 204, 111, 45, 104, 1, 138, 213, 90, 45, 104, 1, + 138, 211, 164, 45, 104, 1, 138, 215, 36, 45, 104, 1, 138, 152, 45, 104, + 1, 227, 77, 45, 104, 1, 63, 45, 104, 1, 124, 152, 45, 104, 1, 75, 45, + 104, 1, 231, 83, 45, 104, 1, 68, 45, 104, 1, 206, 178, 45, 104, 1, 241, + 161, 45, 104, 1, 220, 18, 45, 104, 1, 228, 97, 45, 104, 1, 237, 249, 215, + 36, 45, 104, 109, 2, 174, 216, 220, 45, 104, 109, 2, 174, 228, 113, 45, + 104, 109, 2, 228, 114, 209, 228, 228, 86, 45, 104, 2, 225, 141, 230, 1, + 228, 86, 45, 104, 109, 2, 46, 222, 203, 45, 104, 109, 2, 124, 185, 45, + 104, 109, 2, 138, 216, 170, 219, 245, 124, 185, 45, 104, 109, 2, 192, 45, + 104, 109, 2, 249, 32, 45, 104, 109, 2, 215, 36, 45, 104, 2, 215, 10, 45, + 104, 22, 2, 63, 45, 104, 22, 2, 225, 141, 214, 225, 45, 104, 22, 2, 252, + 25, 45, 104, 22, 2, 209, 234, 252, 25, 45, 104, 22, 2, 75, 45, 104, 22, + 2, 231, 83, 45, 104, 22, 2, 207, 24, 45, 104, 22, 2, 206, 177, 45, 104, + 22, 2, 68, 45, 104, 22, 2, 206, 178, 45, 104, 22, 2, 78, 45, 104, 22, 2, + 220, 98, 56, 45, 104, 22, 2, 219, 188, 45, 104, 22, 2, 74, 45, 104, 22, + 2, 251, 109, 45, 104, 22, 2, 220, 18, 45, 104, 22, 2, 251, 64, 45, 104, + 22, 2, 104, 251, 64, 45, 104, 22, 2, 220, 98, 55, 45, 104, 2, 225, 141, + 230, 0, 45, 104, 2, 208, 160, 45, 104, 2, 208, 159, 45, 104, 2, 229, 105, + 208, 158, 45, 104, 2, 229, 105, 208, 157, 45, 104, 2, 229, 105, 208, 156, + 45, 104, 2, 216, 221, 237, 156, 45, 104, 2, 225, 141, 214, 253, 45, 104, + 2, 229, 104, 229, 239, 45, 104, 39, 245, 113, 243, 85, 45, 104, 236, 108, + 17, 202, 84, 45, 104, 236, 108, 17, 105, 45, 104, 236, 108, 17, 108, 45, + 104, 236, 108, 17, 147, 45, 104, 236, 108, 17, 149, 45, 104, 236, 108, + 17, 170, 45, 104, 236, 108, 17, 195, 45, 104, 236, 108, 17, 213, 111, 45, + 104, 236, 108, 17, 199, 45, 104, 236, 108, 17, 222, 63, 45, 104, 104, 17, + 202, 84, 45, 104, 104, 17, 105, 45, 104, 104, 17, 108, 45, 104, 104, 17, + 147, 45, 104, 104, 17, 149, 45, 104, 104, 17, 170, 45, 104, 104, 17, 195, + 45, 104, 104, 17, 213, 111, 45, 104, 104, 17, 199, 45, 104, 104, 17, 222, + 63, 45, 104, 2, 204, 29, 45, 104, 2, 204, 28, 45, 104, 2, 214, 212, 45, + 104, 2, 229, 175, 45, 104, 2, 236, 36, 45, 104, 2, 243, 99, 45, 104, 2, + 216, 73, 215, 198, 216, 180, 45, 104, 2, 225, 141, 203, 79, 45, 104, 2, + 230, 35, 45, 104, 2, 230, 34, 45, 104, 2, 214, 220, 45, 104, 2, 214, 219, + 45, 104, 2, 237, 98, 45, 104, 2, 247, 89, 39, 242, 75, 246, 53, 251, 138, + 39, 243, 230, 39, 231, 27, 39, 183, 47, 39, 208, 70, 243, 85, 39, 203, + 195, 56, 39, 204, 21, 227, 115, 56, 39, 171, 131, 56, 39, 52, 171, 131, + 56, 39, 157, 246, 219, 211, 32, 56, 39, 211, 18, 246, 219, 211, 32, 56, + 39, 219, 78, 55, 39, 52, 219, 78, 55, 39, 219, 78, 56, 39, 219, 78, 219, + 199, 130, 2, 207, 9, 216, 51, 130, 2, 207, 9, 247, 54, 130, 2, 246, 234, + 130, 2, 210, 191, 130, 2, 248, 56, 130, 1, 251, 45, 130, 1, 251, 46, 209, + 178, 130, 1, 231, 79, 130, 1, 231, 80, 209, 178, 130, 1, 207, 12, 130, 1, + 207, 13, 209, 178, 130, 1, 216, 221, 216, 103, 130, 1, 216, 221, 216, + 104, 209, 178, 130, 1, 228, 114, 227, 197, 130, 1, 228, 114, 227, 198, + 209, 178, 130, 1, 241, 127, 130, 1, 251, 62, 130, 1, 220, 49, 130, 1, + 220, 50, 209, 178, 130, 1, 173, 130, 1, 230, 44, 225, 144, 130, 1, 239, + 8, 130, 1, 239, 9, 238, 25, 130, 1, 222, 203, 130, 1, 247, 92, 130, 1, + 247, 93, 228, 100, 130, 1, 230, 181, 130, 1, 230, 182, 230, 153, 130, 1, + 221, 11, 130, 1, 210, 23, 227, 253, 130, 1, 210, 23, 223, 206, 225, 144, + 130, 1, 244, 213, 223, 206, 251, 4, 130, 1, 244, 213, 223, 206, 225, 144, + 130, 1, 223, 111, 216, 183, 130, 1, 210, 22, 130, 1, 210, 23, 209, 200, + 130, 1, 244, 212, 130, 1, 244, 213, 225, 163, 130, 1, 201, 201, 130, 1, + 185, 130, 1, 219, 169, 229, 251, 130, 1, 249, 32, 130, 1, 249, 33, 229, + 187, 130, 1, 192, 130, 1, 198, 130, 1, 216, 220, 130, 1, 228, 113, 130, + 1, 204, 111, 130, 1, 215, 37, 215, 21, 130, 1, 215, 37, 214, 232, 130, 1, + 215, 36, 130, 1, 152, 130, 2, 216, 94, 130, 22, 2, 209, 178, 130, 22, 2, + 207, 8, 130, 22, 2, 207, 9, 214, 228, 130, 22, 2, 210, 224, 130, 22, 2, + 210, 225, 231, 71, 130, 22, 2, 216, 221, 216, 103, 130, 22, 2, 216, 221, + 216, 104, 209, 178, 130, 22, 2, 228, 114, 227, 197, 130, 22, 2, 228, 114, + 227, 198, 209, 178, 130, 22, 2, 209, 235, 130, 22, 2, 209, 236, 216, 103, + 130, 22, 2, 209, 236, 209, 178, 130, 22, 2, 209, 236, 216, 104, 209, 178, + 130, 22, 2, 218, 249, 130, 22, 2, 218, 250, 209, 178, 130, 251, 117, 251, + 116, 130, 1, 230, 23, 214, 227, 130, 1, 229, 111, 214, 227, 130, 1, 207, + 101, 214, 227, 130, 1, 241, 155, 214, 227, 130, 1, 206, 56, 214, 227, + 130, 1, 202, 106, 214, 227, 130, 1, 250, 52, 214, 227, 130, 17, 202, 84, + 130, 17, 105, 130, 17, 108, 130, 17, 147, 130, 17, 149, 130, 17, 170, + 130, 17, 195, 130, 17, 213, 111, 130, 17, 199, 130, 17, 222, 63, 130, + 219, 104, 130, 219, 130, 130, 204, 14, 130, 247, 31, 219, 123, 130, 247, + 31, 212, 139, 130, 247, 31, 219, 75, 130, 219, 129, 130, 31, 16, 243, 91, + 130, 31, 16, 244, 34, 130, 31, 16, 242, 27, 130, 31, 16, 244, 164, 130, + 31, 16, 244, 165, 210, 191, 130, 31, 16, 243, 175, 130, 31, 16, 244, 205, + 130, 31, 16, 244, 10, 130, 31, 16, 244, 187, 130, 31, 16, 244, 165, 238, + 184, 130, 31, 16, 39, 209, 171, 130, 31, 16, 39, 241, 82, 130, 31, 16, + 39, 229, 182, 130, 31, 16, 39, 229, 184, 130, 31, 16, 39, 230, 157, 130, + 31, 16, 39, 229, 183, 3, 230, 157, 130, 31, 16, 39, 229, 185, 3, 230, + 157, 130, 31, 16, 39, 248, 119, 130, 31, 16, 39, 238, 29, 130, 31, 16, + 216, 14, 171, 242, 37, 130, 31, 16, 216, 14, 171, 244, 203, 130, 31, 16, + 216, 14, 246, 16, 207, 195, 130, 31, 16, 216, 14, 246, 16, 209, 244, 130, + 31, 16, 227, 220, 171, 219, 118, 130, 31, 16, 227, 220, 171, 217, 177, + 130, 31, 16, 227, 220, 246, 16, 218, 94, 130, 31, 16, 227, 220, 246, 16, + 218, 80, 130, 31, 16, 227, 220, 171, 218, 119, 210, 213, 2, 219, 101, + 210, 213, 2, 219, 114, 210, 213, 2, 219, 110, 210, 213, 1, 63, 210, 213, + 1, 75, 210, 213, 1, 68, 210, 213, 1, 251, 109, 210, 213, 1, 78, 210, 213, + 1, 74, 210, 213, 1, 240, 238, 210, 213, 1, 173, 210, 213, 1, 217, 126, + 210, 213, 1, 239, 8, 210, 213, 1, 222, 203, 210, 213, 1, 247, 92, 210, + 213, 1, 230, 181, 210, 213, 1, 202, 116, 210, 213, 1, 221, 11, 210, 213, + 1, 210, 22, 210, 213, 1, 244, 212, 210, 213, 1, 201, 201, 210, 213, 1, + 185, 210, 213, 1, 240, 108, 210, 213, 1, 206, 86, 210, 213, 1, 249, 32, + 210, 213, 1, 192, 210, 213, 1, 198, 210, 213, 1, 216, 220, 210, 213, 1, + 228, 113, 210, 213, 1, 204, 111, 210, 213, 1, 215, 36, 210, 213, 1, 203, + 182, 210, 213, 1, 152, 210, 213, 109, 2, 219, 127, 210, 213, 109, 2, 219, + 103, 210, 213, 109, 2, 219, 100, 210, 213, 22, 2, 219, 117, 210, 213, 22, + 2, 219, 99, 210, 213, 22, 2, 219, 121, 210, 213, 22, 2, 219, 109, 210, + 213, 22, 2, 219, 128, 210, 213, 22, 2, 219, 119, 210, 213, 2, 219, 131, + 210, 213, 2, 205, 204, 210, 213, 109, 2, 219, 64, 192, 210, 213, 109, 2, + 219, 64, 204, 111, 210, 213, 1, 229, 144, 210, 213, 1, 210, 150, 210, + 213, 17, 202, 84, 210, 213, 17, 105, 210, 213, 17, 108, 210, 213, 17, + 147, 210, 213, 17, 149, 210, 213, 17, 170, 210, 213, 17, 195, 210, 213, + 17, 213, 111, 210, 213, 17, 199, 210, 213, 17, 222, 63, 210, 213, 250, + 17, 210, 213, 1, 216, 76, 210, 213, 1, 227, 171, 210, 213, 1, 248, 98, + 210, 213, 1, 46, 230, 54, 210, 213, 1, 46, 226, 185, 248, 208, 1, 63, + 248, 208, 1, 212, 131, 63, 248, 208, 1, 152, 248, 208, 1, 212, 131, 152, + 248, 208, 1, 225, 117, 152, 248, 208, 1, 249, 32, 248, 208, 1, 229, 236, + 249, 32, 248, 208, 1, 185, 248, 208, 1, 212, 131, 185, 248, 208, 1, 201, + 201, 248, 208, 1, 225, 117, 201, 201, 248, 208, 1, 204, 111, 248, 208, 1, + 212, 131, 204, 111, 248, 208, 1, 219, 143, 204, 111, 248, 208, 1, 239, 8, + 248, 208, 1, 212, 131, 239, 8, 248, 208, 1, 230, 181, 248, 208, 1, 244, + 212, 248, 208, 1, 216, 220, 248, 208, 1, 212, 131, 216, 220, 248, 208, 1, + 192, 248, 208, 1, 212, 131, 192, 248, 208, 1, 211, 236, 210, 22, 248, + 208, 1, 221, 170, 210, 22, 248, 208, 1, 215, 36, 248, 208, 1, 212, 131, + 215, 36, 248, 208, 1, 225, 117, 215, 36, 248, 208, 1, 198, 248, 208, 1, + 212, 131, 198, 248, 208, 1, 222, 203, 248, 208, 1, 228, 113, 248, 208, 1, + 212, 131, 228, 113, 248, 208, 1, 221, 11, 248, 208, 1, 247, 92, 248, 208, + 1, 223, 25, 248, 208, 1, 225, 54, 248, 208, 1, 75, 248, 208, 1, 68, 248, + 208, 2, 208, 164, 248, 208, 22, 2, 74, 248, 208, 22, 2, 219, 143, 74, + 248, 208, 22, 2, 241, 161, 248, 208, 22, 2, 75, 248, 208, 22, 2, 229, + 236, 75, 248, 208, 22, 2, 78, 248, 208, 22, 2, 229, 236, 78, 248, 208, + 22, 2, 68, 248, 208, 22, 2, 106, 35, 212, 131, 215, 36, 248, 208, 109, 2, + 222, 205, 248, 208, 109, 2, 237, 171, 248, 208, 219, 112, 248, 208, 219, + 108, 248, 208, 16, 248, 64, 223, 111, 224, 218, 248, 208, 16, 248, 64, + 218, 122, 248, 208, 16, 248, 64, 230, 79, 248, 208, 16, 248, 64, 219, + 112, 227, 181, 1, 173, 227, 181, 1, 229, 40, 227, 181, 1, 229, 144, 227, + 181, 1, 239, 8, 227, 181, 1, 238, 51, 227, 181, 1, 222, 203, 227, 181, 1, + 247, 92, 227, 181, 1, 246, 199, 227, 181, 1, 230, 181, 227, 181, 1, 221, + 11, 227, 181, 1, 210, 22, 227, 181, 1, 209, 108, 227, 181, 1, 244, 212, + 227, 181, 1, 201, 201, 227, 181, 1, 185, 227, 181, 1, 218, 98, 227, 181, + 1, 218, 208, 227, 181, 1, 240, 108, 227, 181, 1, 239, 227, 227, 181, 1, + 249, 32, 227, 181, 1, 248, 44, 227, 181, 1, 192, 227, 181, 1, 224, 89, + 227, 181, 1, 208, 20, 227, 181, 1, 208, 10, 227, 181, 1, 241, 255, 227, + 181, 1, 198, 227, 181, 1, 216, 220, 227, 181, 1, 228, 113, 227, 181, 1, + 152, 227, 181, 1, 236, 224, 227, 181, 1, 206, 86, 227, 181, 1, 215, 36, + 227, 181, 1, 213, 90, 227, 181, 1, 204, 111, 227, 181, 1, 63, 227, 181, + 210, 254, 1, 198, 227, 181, 210, 254, 1, 216, 220, 227, 181, 22, 2, 252, + 25, 227, 181, 22, 2, 75, 227, 181, 22, 2, 78, 227, 181, 22, 2, 220, 18, + 227, 181, 22, 2, 68, 227, 181, 22, 2, 206, 178, 227, 181, 22, 2, 74, 227, + 181, 109, 2, 230, 54, 227, 181, 109, 2, 226, 185, 227, 181, 109, 2, 159, + 227, 181, 109, 2, 223, 163, 227, 181, 109, 2, 219, 184, 227, 181, 109, 2, + 146, 227, 181, 109, 2, 210, 69, 227, 181, 109, 2, 220, 241, 227, 181, + 109, 2, 230, 0, 227, 181, 2, 216, 181, 227, 181, 2, 221, 51, 227, 181, + 217, 179, 210, 20, 227, 181, 217, 179, 220, 252, 209, 5, 210, 20, 227, + 181, 217, 179, 246, 206, 227, 181, 217, 179, 208, 2, 246, 206, 227, 181, + 217, 179, 208, 1, 227, 181, 17, 202, 84, 227, 181, 17, 105, 227, 181, 17, + 108, 227, 181, 17, 147, 227, 181, 17, 149, 227, 181, 17, 170, 227, 181, + 17, 195, 227, 181, 17, 213, 111, 227, 181, 17, 199, 227, 181, 17, 222, + 63, 227, 181, 1, 207, 241, 227, 181, 1, 207, 229, 227, 181, 1, 244, 120, + 220, 47, 246, 135, 17, 202, 84, 220, 47, 246, 135, 17, 105, 220, 47, 246, + 135, 17, 108, 220, 47, 246, 135, 17, 147, 220, 47, 246, 135, 17, 149, + 220, 47, 246, 135, 17, 170, 220, 47, 246, 135, 17, 195, 220, 47, 246, + 135, 17, 213, 111, 220, 47, 246, 135, 17, 199, 220, 47, 246, 135, 17, + 222, 63, 220, 47, 246, 135, 1, 228, 113, 220, 47, 246, 135, 1, 250, 49, + 220, 47, 246, 135, 1, 251, 81, 220, 47, 246, 135, 1, 250, 223, 220, 47, + 246, 135, 1, 251, 39, 220, 47, 246, 135, 1, 228, 112, 220, 47, 246, 135, + 1, 251, 243, 220, 47, 246, 135, 1, 251, 244, 220, 47, 246, 135, 1, 251, + 242, 220, 47, 246, 135, 1, 251, 237, 220, 47, 246, 135, 1, 227, 148, 220, + 47, 246, 135, 1, 230, 215, 220, 47, 246, 135, 1, 231, 84, 220, 47, 246, + 135, 1, 230, 236, 220, 47, 246, 135, 1, 230, 224, 220, 47, 246, 135, 1, + 226, 239, 220, 47, 246, 135, 1, 207, 31, 220, 47, 246, 135, 1, 207, 29, + 220, 47, 246, 135, 1, 206, 229, 220, 47, 246, 135, 1, 206, 170, 220, 47, + 246, 135, 1, 227, 234, 220, 47, 246, 135, 1, 241, 46, 220, 47, 246, 135, + 1, 241, 164, 220, 47, 246, 135, 1, 241, 92, 220, 47, 246, 135, 1, 241, + 21, 220, 47, 246, 135, 1, 227, 49, 220, 47, 246, 135, 1, 219, 219, 220, + 47, 246, 135, 1, 220, 93, 220, 47, 246, 135, 1, 219, 206, 220, 47, 246, + 135, 1, 220, 60, 220, 47, 246, 135, 223, 247, 207, 206, 220, 47, 246, + 135, 239, 3, 207, 207, 220, 47, 246, 135, 223, 245, 207, 207, 220, 47, + 246, 135, 216, 118, 220, 47, 246, 135, 218, 206, 220, 47, 246, 135, 251, + 72, 220, 47, 246, 135, 217, 179, 223, 241, 220, 47, 246, 135, 217, 179, + 52, 223, 241, 210, 213, 217, 179, 248, 64, 210, 184, 210, 213, 217, 179, + 248, 64, 219, 113, 210, 213, 217, 179, 248, 64, 217, 167, 210, 213, 217, + 179, 248, 64, 247, 77, 210, 213, 217, 179, 248, 64, 227, 172, 214, 224, + 210, 213, 217, 179, 248, 64, 230, 44, 214, 224, 210, 213, 217, 179, 248, + 64, 244, 213, 214, 224, 210, 213, 217, 179, 248, 64, 249, 33, 214, 224, + 206, 52, 143, 229, 234, 206, 52, 143, 213, 58, 206, 52, 143, 217, 245, + 206, 52, 2, 222, 76, 206, 52, 2, 203, 87, 224, 146, 210, 175, 206, 52, + 143, 203, 87, 251, 77, 231, 36, 210, 175, 206, 52, 143, 203, 87, 231, 36, + 210, 175, 206, 52, 143, 203, 87, 229, 222, 231, 36, 210, 175, 206, 52, + 143, 247, 55, 56, 206, 52, 143, 203, 87, 229, 222, 231, 36, 210, 176, + 214, 194, 206, 52, 143, 52, 210, 175, 206, 52, 143, 208, 70, 210, 175, + 206, 52, 143, 229, 222, 250, 182, 206, 52, 143, 70, 56, 206, 52, 143, + 120, 187, 56, 206, 52, 143, 126, 187, 56, 206, 52, 143, 216, 4, 229, 233, + 231, 36, 210, 175, 206, 52, 143, 250, 47, 231, 36, 210, 175, 206, 52, 2, + 205, 200, 210, 175, 206, 52, 2, 205, 200, 207, 26, 206, 52, 2, 216, 73, + 205, 200, 207, 26, 206, 52, 2, 205, 200, 250, 182, 206, 52, 2, 216, 73, + 205, 200, 250, 182, 206, 52, 2, 205, 200, 207, 27, 3, 209, 248, 206, 52, + 2, 205, 200, 250, 183, 3, 209, 248, 206, 52, 2, 250, 181, 250, 197, 206, + 52, 2, 250, 181, 249, 2, 206, 52, 2, 250, 181, 206, 77, 206, 52, 2, 250, + 181, 206, 78, 3, 209, 248, 206, 52, 2, 208, 201, 206, 52, 2, 237, 15, + 163, 250, 180, 206, 52, 2, 163, 250, 180, 206, 52, 2, 215, 147, 163, 250, + 180, 206, 52, 2, 250, 181, 207, 33, 223, 232, 206, 52, 2, 250, 122, 206, + 52, 2, 215, 198, 250, 122, 206, 52, 143, 247, 55, 55, 206, 52, 2, 230, + 135, 206, 52, 2, 206, 222, 206, 52, 143, 215, 253, 55, 206, 52, 143, 52, + 215, 253, 55, 8, 1, 5, 6, 63, 8, 1, 5, 6, 251, 109, 8, 5, 1, 207, 174, + 251, 109, 8, 1, 5, 6, 248, 225, 249, 255, 8, 1, 5, 6, 247, 125, 8, 1, 5, + 6, 245, 51, 8, 1, 5, 6, 240, 243, 8, 1, 5, 6, 74, 8, 5, 1, 207, 174, 171, + 74, 8, 5, 1, 207, 174, 75, 8, 1, 5, 6, 230, 184, 8, 1, 5, 6, 230, 54, 8, + 1, 5, 6, 228, 131, 3, 95, 8, 1, 5, 6, 226, 185, 8, 1, 5, 6, 216, 73, 223, + 163, 8, 1, 5, 6, 78, 8, 1, 5, 6, 171, 78, 8, 5, 1, 212, 154, 78, 8, 5, 1, + 212, 154, 171, 78, 8, 5, 1, 212, 154, 158, 3, 95, 8, 5, 1, 207, 174, 220, + 73, 8, 1, 5, 6, 219, 216, 8, 5, 1, 208, 145, 162, 78, 8, 5, 1, 247, 248, + 162, 78, 8, 1, 5, 6, 219, 184, 8, 1, 5, 6, 216, 73, 146, 8, 1, 5, 6, 207, + 174, 146, 8, 1, 5, 6, 210, 69, 8, 1, 5, 6, 68, 8, 5, 1, 212, 154, 68, 8, + 5, 1, 212, 154, 243, 229, 68, 8, 5, 1, 212, 154, 207, 174, 226, 185, 8, + 1, 5, 6, 206, 164, 8, 1, 5, 6, 204, 144, 8, 1, 5, 6, 202, 159, 8, 1, 5, + 6, 240, 177, 8, 1, 205, 186, 228, 3, 211, 200, 8, 1, 251, 59, 30, 1, 5, + 6, 238, 235, 30, 1, 5, 6, 228, 24, 30, 1, 5, 6, 218, 167, 30, 1, 5, 6, + 216, 59, 30, 1, 5, 6, 217, 202, 36, 1, 5, 6, 241, 122, 65, 1, 6, 63, 65, + 1, 6, 251, 109, 65, 1, 6, 249, 255, 65, 1, 6, 248, 225, 249, 255, 65, 1, + 6, 245, 51, 65, 1, 6, 74, 65, 1, 6, 216, 73, 74, 65, 1, 6, 239, 75, 65, + 1, 6, 237, 171, 65, 1, 6, 75, 65, 1, 6, 230, 184, 65, 1, 6, 230, 54, 65, + 1, 6, 159, 65, 1, 6, 226, 185, 65, 1, 6, 223, 163, 65, 1, 6, 216, 73, + 223, 163, 65, 1, 6, 78, 65, 1, 6, 219, 216, 65, 1, 6, 219, 184, 65, 1, 6, + 146, 65, 1, 6, 210, 69, 65, 1, 6, 68, 65, 1, 6, 204, 144, 65, 1, 5, 63, + 65, 1, 5, 207, 174, 63, 65, 1, 5, 251, 2, 65, 1, 5, 207, 174, 251, 109, + 65, 1, 5, 249, 255, 65, 1, 5, 245, 51, 65, 1, 5, 74, 65, 1, 5, 214, 192, + 65, 1, 5, 171, 74, 65, 1, 5, 207, 174, 171, 74, 65, 1, 5, 239, 75, 65, 1, + 5, 207, 174, 75, 65, 1, 5, 230, 54, 65, 1, 5, 226, 185, 65, 1, 5, 241, + 78, 65, 1, 5, 78, 65, 1, 5, 171, 78, 65, 1, 5, 208, 145, 162, 78, 65, 1, + 5, 247, 248, 162, 78, 65, 1, 5, 219, 184, 65, 1, 5, 210, 69, 65, 1, 5, + 68, 65, 1, 5, 212, 154, 68, 65, 1, 5, 207, 174, 226, 185, 65, 1, 5, 206, + 164, 65, 1, 5, 251, 59, 65, 1, 5, 248, 106, 65, 1, 5, 30, 238, 235, 65, + 1, 5, 244, 37, 65, 1, 5, 30, 218, 192, 65, 1, 5, 246, 142, 8, 210, 246, + 5, 1, 75, 8, 210, 246, 5, 1, 146, 8, 210, 246, 5, 1, 68, 8, 210, 246, 5, + 1, 206, 164, 30, 210, 246, 5, 1, 248, 106, 30, 210, 246, 5, 1, 238, 235, + 30, 210, 246, 5, 1, 216, 59, 30, 210, 246, 5, 1, 218, 192, 30, 210, 246, + 5, 1, 246, 142, 8, 5, 1, 207, 24, 8, 5, 1, 66, 3, 101, 208, 227, 8, 5, 1, + 245, 52, 3, 101, 208, 227, 8, 5, 1, 240, 175, 3, 101, 208, 227, 8, 5, 1, + 226, 186, 3, 101, 208, 227, 8, 5, 1, 223, 164, 3, 101, 208, 227, 8, 5, 1, + 219, 185, 3, 101, 208, 227, 8, 5, 1, 217, 1, 3, 101, 208, 227, 8, 5, 1, + 217, 1, 3, 239, 241, 25, 101, 208, 227, 8, 5, 1, 215, 94, 3, 101, 208, + 227, 8, 5, 1, 210, 70, 3, 101, 208, 227, 8, 5, 1, 202, 160, 3, 101, 208, + 227, 8, 5, 1, 207, 174, 239, 75, 65, 1, 36, 241, 92, 8, 5, 1, 231, 4, + 239, 75, 8, 5, 1, 209, 111, 3, 211, 36, 8, 5, 6, 1, 235, 206, 3, 95, 8, + 5, 1, 230, 231, 3, 95, 8, 5, 1, 219, 185, 3, 95, 8, 5, 6, 1, 106, 3, 95, + 8, 5, 1, 206, 217, 3, 95, 8, 5, 1, 66, 3, 219, 142, 113, 8, 5, 1, 245, + 52, 3, 219, 142, 113, 8, 5, 1, 240, 175, 3, 219, 142, 113, 8, 5, 1, 239, + 76, 3, 219, 142, 113, 8, 5, 1, 230, 55, 3, 219, 142, 113, 8, 5, 1, 228, + 131, 3, 219, 142, 113, 8, 5, 1, 226, 186, 3, 219, 142, 113, 8, 5, 1, 223, + 164, 3, 219, 142, 113, 8, 5, 1, 219, 185, 3, 219, 142, 113, 8, 5, 1, 217, + 1, 3, 219, 142, 113, 8, 5, 1, 215, 94, 3, 219, 142, 113, 8, 5, 1, 241, 8, + 3, 219, 142, 113, 8, 5, 1, 206, 165, 3, 219, 142, 113, 8, 5, 1, 203, 197, + 3, 219, 142, 113, 8, 5, 1, 202, 160, 3, 219, 142, 113, 8, 5, 1, 34, 3, + 216, 79, 113, 8, 5, 1, 251, 3, 3, 216, 79, 113, 8, 5, 1, 245, 52, 3, 236, + 116, 25, 209, 248, 8, 5, 1, 188, 3, 216, 79, 113, 8, 5, 1, 171, 188, 3, + 216, 79, 113, 8, 5, 1, 216, 73, 171, 188, 3, 216, 79, 113, 8, 5, 1, 214, + 193, 3, 216, 79, 113, 8, 5, 1, 235, 206, 3, 216, 79, 113, 8, 5, 1, 171, + 158, 3, 216, 79, 113, 8, 5, 1, 241, 8, 3, 216, 79, 113, 8, 5, 1, 106, 3, + 216, 79, 113, 8, 5, 1, 240, 178, 3, 216, 79, 113, 65, 1, 5, 207, 174, + 251, 2, 65, 1, 5, 247, 125, 65, 1, 5, 247, 126, 3, 245, 95, 65, 1, 5, + 240, 243, 65, 1, 5, 216, 73, 171, 74, 65, 1, 5, 240, 174, 65, 1, 5, 243, + 84, 230, 185, 3, 95, 65, 1, 5, 132, 239, 75, 65, 1, 5, 207, 174, 237, + 171, 65, 1, 5, 235, 206, 3, 95, 65, 1, 5, 230, 230, 65, 1, 5, 6, 75, 65, + 1, 5, 6, 235, 206, 3, 95, 65, 1, 5, 230, 185, 3, 245, 126, 65, 1, 5, 228, + 131, 3, 216, 79, 113, 65, 1, 5, 228, 131, 3, 219, 142, 113, 65, 1, 5, 6, + 159, 65, 1, 5, 226, 186, 3, 113, 65, 1, 5, 207, 174, 226, 186, 3, 163, + 227, 210, 65, 1, 5, 223, 164, 3, 49, 113, 65, 1, 5, 223, 164, 3, 216, 79, + 113, 65, 1, 5, 6, 223, 163, 65, 1, 5, 248, 225, 78, 65, 1, 5, 218, 192, + 65, 1, 5, 215, 94, 3, 113, 65, 1, 5, 241, 7, 65, 1, 5, 210, 70, 3, 219, + 142, 113, 65, 1, 5, 106, 142, 65, 1, 5, 206, 216, 65, 1, 5, 6, 68, 65, 1, + 5, 206, 165, 3, 113, 65, 1, 5, 207, 174, 206, 164, 65, 1, 5, 202, 159, + 65, 1, 5, 202, 160, 3, 216, 79, 113, 65, 1, 5, 202, 160, 3, 245, 95, 65, + 1, 5, 240, 177, 65, 1, 5, 209, 74, 39, 242, 83, 237, 254, 251, 138, 39, + 242, 83, 251, 126, 251, 138, 39, 212, 25, 56, 39, 210, 182, 82, 39, 225, + 169, 39, 237, 251, 39, 225, 167, 39, 251, 124, 39, 237, 252, 39, 251, + 125, 39, 8, 5, 1, 217, 1, 56, 39, 247, 213, 39, 225, 168, 39, 52, 246, + 53, 55, 39, 220, 63, 55, 39, 202, 30, 56, 39, 230, 216, 56, 39, 206, 211, + 55, 39, 206, 194, 55, 39, 8, 5, 1, 239, 214, 171, 34, 55, 39, 8, 5, 1, + 251, 109, 39, 8, 5, 1, 250, 178, 39, 8, 5, 1, 250, 18, 39, 8, 5, 1, 247, + 126, 246, 231, 39, 8, 5, 1, 231, 4, 245, 51, 39, 8, 5, 1, 240, 243, 39, + 8, 5, 1, 239, 75, 39, 8, 1, 5, 6, 239, 75, 39, 8, 5, 1, 230, 54, 39, 8, + 5, 1, 159, 39, 8, 1, 5, 6, 159, 39, 8, 1, 5, 6, 226, 185, 39, 8, 5, 1, + 223, 163, 39, 8, 1, 5, 6, 223, 163, 39, 8, 1, 5, 6, 146, 39, 8, 5, 1, + 217, 1, 215, 192, 39, 8, 5, 1, 194, 39, 8, 5, 1, 163, 194, 39, 8, 5, 1, + 202, 159, 39, 8, 5, 1, 251, 2, 39, 8, 5, 1, 249, 255, 39, 8, 5, 1, 248, + 106, 39, 8, 5, 1, 214, 192, 39, 8, 5, 1, 240, 174, 39, 8, 5, 1, 228, 131, + 3, 52, 101, 208, 227, 39, 8, 5, 1, 158, 3, 157, 246, 219, 95, 39, 8, 5, + 1, 219, 184, 39, 8, 5, 1, 241, 7, 39, 8, 5, 1, 106, 3, 157, 246, 219, 95, + 39, 8, 5, 1, 204, 144, 39, 8, 5, 1, 34, 3, 243, 231, 39, 8, 5, 1, 158, 3, + 243, 231, 39, 8, 5, 1, 106, 3, 243, 231, 39, 112, 210, 4, 55, 39, 52, + 230, 239, 247, 215, 56, 39, 251, 7, 156, 208, 173, 56, 39, 49, 250, 95, + 55, 39, 50, 250, 95, 25, 121, 250, 95, 56, 8, 6, 1, 34, 3, 215, 253, 56, + 8, 5, 1, 34, 3, 215, 253, 56, 8, 6, 1, 66, 3, 70, 55, 8, 5, 1, 66, 3, 70, + 55, 8, 6, 1, 66, 3, 70, 56, 8, 5, 1, 66, 3, 70, 56, 8, 6, 1, 66, 3, 227, + 115, 56, 8, 5, 1, 66, 3, 227, 115, 56, 8, 6, 1, 247, 126, 3, 246, 232, + 25, 165, 8, 5, 1, 247, 126, 3, 246, 232, 25, 165, 8, 6, 1, 245, 52, 3, + 70, 55, 8, 5, 1, 245, 52, 3, 70, 55, 8, 6, 1, 245, 52, 3, 70, 56, 8, 5, + 1, 245, 52, 3, 70, 56, 8, 6, 1, 245, 52, 3, 227, 115, 56, 8, 5, 1, 245, + 52, 3, 227, 115, 56, 8, 6, 1, 245, 52, 3, 246, 231, 8, 5, 1, 245, 52, 3, + 246, 231, 8, 6, 1, 245, 52, 3, 246, 53, 56, 8, 5, 1, 245, 52, 3, 246, 53, + 56, 8, 6, 1, 188, 3, 225, 171, 25, 237, 253, 8, 5, 1, 188, 3, 225, 171, + 25, 237, 253, 8, 6, 1, 188, 3, 225, 171, 25, 165, 8, 5, 1, 188, 3, 225, + 171, 25, 165, 8, 6, 1, 188, 3, 246, 53, 56, 8, 5, 1, 188, 3, 246, 53, 56, + 8, 6, 1, 188, 3, 208, 228, 56, 8, 5, 1, 188, 3, 208, 228, 56, 8, 6, 1, + 188, 3, 246, 232, 25, 247, 214, 8, 5, 1, 188, 3, 246, 232, 25, 247, 214, + 8, 6, 1, 240, 175, 3, 70, 55, 8, 5, 1, 240, 175, 3, 70, 55, 8, 6, 1, 239, + 76, 3, 225, 170, 8, 5, 1, 239, 76, 3, 225, 170, 8, 6, 1, 237, 172, 3, 70, + 55, 8, 5, 1, 237, 172, 3, 70, 55, 8, 6, 1, 237, 172, 3, 70, 56, 8, 5, 1, + 237, 172, 3, 70, 56, 8, 6, 1, 237, 172, 3, 243, 231, 8, 5, 1, 237, 172, + 3, 243, 231, 8, 6, 1, 237, 172, 3, 246, 231, 8, 5, 1, 237, 172, 3, 246, + 231, 8, 6, 1, 237, 172, 3, 247, 215, 56, 8, 5, 1, 237, 172, 3, 247, 215, + 56, 8, 6, 1, 235, 206, 3, 208, 228, 56, 8, 5, 1, 235, 206, 3, 208, 228, + 56, 8, 6, 1, 235, 206, 3, 243, 232, 25, 165, 8, 5, 1, 235, 206, 3, 243, + 232, 25, 165, 8, 6, 1, 230, 55, 3, 165, 8, 5, 1, 230, 55, 3, 165, 8, 6, + 1, 230, 55, 3, 70, 56, 8, 5, 1, 230, 55, 3, 70, 56, 8, 6, 1, 230, 55, 3, + 227, 115, 56, 8, 5, 1, 230, 55, 3, 227, 115, 56, 8, 6, 1, 228, 131, 3, + 70, 56, 8, 5, 1, 228, 131, 3, 70, 56, 8, 6, 1, 228, 131, 3, 70, 248, 126, + 25, 225, 170, 8, 5, 1, 228, 131, 3, 70, 248, 126, 25, 225, 170, 8, 6, 1, + 228, 131, 3, 227, 115, 56, 8, 5, 1, 228, 131, 3, 227, 115, 56, 8, 6, 1, + 228, 131, 3, 246, 53, 56, 8, 5, 1, 228, 131, 3, 246, 53, 56, 8, 6, 1, + 226, 186, 3, 165, 8, 5, 1, 226, 186, 3, 165, 8, 6, 1, 226, 186, 3, 70, + 55, 8, 5, 1, 226, 186, 3, 70, 55, 8, 6, 1, 226, 186, 3, 70, 56, 8, 5, 1, + 226, 186, 3, 70, 56, 8, 6, 1, 223, 164, 3, 70, 55, 8, 5, 1, 223, 164, 3, + 70, 55, 8, 6, 1, 223, 164, 3, 70, 56, 8, 5, 1, 223, 164, 3, 70, 56, 8, 6, + 1, 223, 164, 3, 227, 115, 56, 8, 5, 1, 223, 164, 3, 227, 115, 56, 8, 6, + 1, 223, 164, 3, 246, 53, 56, 8, 5, 1, 223, 164, 3, 246, 53, 56, 8, 6, 1, + 158, 3, 208, 228, 25, 165, 8, 5, 1, 158, 3, 208, 228, 25, 165, 8, 6, 1, + 158, 3, 208, 228, 25, 243, 231, 8, 5, 1, 158, 3, 208, 228, 25, 243, 231, + 8, 6, 1, 158, 3, 225, 171, 25, 237, 253, 8, 5, 1, 158, 3, 225, 171, 25, + 237, 253, 8, 6, 1, 158, 3, 225, 171, 25, 165, 8, 5, 1, 158, 3, 225, 171, + 25, 165, 8, 6, 1, 219, 185, 3, 165, 8, 5, 1, 219, 185, 3, 165, 8, 6, 1, + 219, 185, 3, 70, 55, 8, 5, 1, 219, 185, 3, 70, 55, 8, 6, 1, 217, 1, 3, + 70, 55, 8, 5, 1, 217, 1, 3, 70, 55, 8, 6, 1, 217, 1, 3, 70, 56, 8, 5, 1, + 217, 1, 3, 70, 56, 8, 6, 1, 217, 1, 3, 70, 248, 126, 25, 225, 170, 8, 5, + 1, 217, 1, 3, 70, 248, 126, 25, 225, 170, 8, 6, 1, 217, 1, 3, 227, 115, + 56, 8, 5, 1, 217, 1, 3, 227, 115, 56, 8, 6, 1, 215, 94, 3, 70, 55, 8, 5, + 1, 215, 94, 3, 70, 55, 8, 6, 1, 215, 94, 3, 70, 56, 8, 5, 1, 215, 94, 3, + 70, 56, 8, 6, 1, 215, 94, 3, 251, 126, 25, 70, 55, 8, 5, 1, 215, 94, 3, + 251, 126, 25, 70, 55, 8, 6, 1, 215, 94, 3, 247, 30, 25, 70, 55, 8, 5, 1, + 215, 94, 3, 247, 30, 25, 70, 55, 8, 6, 1, 215, 94, 3, 70, 248, 126, 25, + 70, 55, 8, 5, 1, 215, 94, 3, 70, 248, 126, 25, 70, 55, 8, 6, 1, 210, 70, + 3, 70, 55, 8, 5, 1, 210, 70, 3, 70, 55, 8, 6, 1, 210, 70, 3, 70, 56, 8, + 5, 1, 210, 70, 3, 70, 56, 8, 6, 1, 210, 70, 3, 227, 115, 56, 8, 5, 1, + 210, 70, 3, 227, 115, 56, 8, 6, 1, 210, 70, 3, 246, 53, 56, 8, 5, 1, 210, + 70, 3, 246, 53, 56, 8, 6, 1, 106, 3, 243, 232, 56, 8, 5, 1, 106, 3, 243, + 232, 56, 8, 6, 1, 106, 3, 208, 228, 56, 8, 5, 1, 106, 3, 208, 228, 56, 8, + 6, 1, 106, 3, 246, 53, 56, 8, 5, 1, 106, 3, 246, 53, 56, 8, 6, 1, 106, 3, + 208, 228, 25, 165, 8, 5, 1, 106, 3, 208, 228, 25, 165, 8, 6, 1, 106, 3, + 225, 171, 25, 243, 231, 8, 5, 1, 106, 3, 225, 171, 25, 243, 231, 8, 6, 1, + 206, 165, 3, 208, 227, 8, 5, 1, 206, 165, 3, 208, 227, 8, 6, 1, 206, 165, + 3, 70, 56, 8, 5, 1, 206, 165, 3, 70, 56, 8, 6, 1, 204, 145, 3, 237, 253, + 8, 5, 1, 204, 145, 3, 237, 253, 8, 6, 1, 204, 145, 3, 165, 8, 5, 1, 204, + 145, 3, 165, 8, 6, 1, 204, 145, 3, 243, 231, 8, 5, 1, 204, 145, 3, 243, + 231, 8, 6, 1, 204, 145, 3, 70, 55, 8, 5, 1, 204, 145, 3, 70, 55, 8, 6, 1, + 204, 145, 3, 70, 56, 8, 5, 1, 204, 145, 3, 70, 56, 8, 6, 1, 203, 197, 3, + 70, 55, 8, 5, 1, 203, 197, 3, 70, 55, 8, 6, 1, 203, 197, 3, 243, 231, 8, + 5, 1, 203, 197, 3, 243, 231, 8, 6, 1, 203, 125, 3, 70, 55, 8, 5, 1, 203, + 125, 3, 70, 55, 8, 6, 1, 202, 160, 3, 246, 52, 8, 5, 1, 202, 160, 3, 246, + 52, 8, 6, 1, 202, 160, 3, 70, 56, 8, 5, 1, 202, 160, 3, 70, 56, 8, 6, 1, + 202, 160, 3, 227, 115, 56, 8, 5, 1, 202, 160, 3, 227, 115, 56, 8, 5, 1, + 237, 172, 3, 227, 115, 56, 8, 5, 1, 210, 70, 3, 243, 231, 8, 5, 1, 204, + 145, 3, 215, 253, 55, 8, 5, 1, 203, 125, 3, 215, 253, 55, 8, 5, 1, 34, 3, + 50, 162, 215, 252, 8, 5, 1, 163, 215, 94, 3, 70, 55, 8, 5, 1, 163, 215, + 94, 3, 243, 228, 95, 8, 5, 1, 163, 215, 94, 3, 138, 95, 8, 6, 1, 213, 57, + 194, 8, 5, 1, 244, 37, 8, 6, 1, 34, 3, 70, 56, 8, 5, 1, 34, 3, 70, 56, 8, + 6, 1, 34, 3, 236, 116, 55, 8, 5, 1, 34, 3, 236, 116, 55, 8, 6, 1, 34, 3, + 246, 53, 25, 165, 8, 5, 1, 34, 3, 246, 53, 25, 165, 8, 6, 1, 34, 3, 246, + 53, 25, 237, 253, 8, 5, 1, 34, 3, 246, 53, 25, 237, 253, 8, 6, 1, 34, 3, + 246, 53, 25, 236, 116, 55, 8, 5, 1, 34, 3, 246, 53, 25, 236, 116, 55, 8, + 6, 1, 34, 3, 246, 53, 25, 208, 227, 8, 5, 1, 34, 3, 246, 53, 25, 208, + 227, 8, 6, 1, 34, 3, 246, 53, 25, 70, 56, 8, 5, 1, 34, 3, 246, 53, 25, + 70, 56, 8, 6, 1, 34, 3, 247, 215, 25, 165, 8, 5, 1, 34, 3, 247, 215, 25, + 165, 8, 6, 1, 34, 3, 247, 215, 25, 237, 253, 8, 5, 1, 34, 3, 247, 215, + 25, 237, 253, 8, 6, 1, 34, 3, 247, 215, 25, 236, 116, 55, 8, 5, 1, 34, 3, + 247, 215, 25, 236, 116, 55, 8, 6, 1, 34, 3, 247, 215, 25, 208, 227, 8, 5, + 1, 34, 3, 247, 215, 25, 208, 227, 8, 6, 1, 34, 3, 247, 215, 25, 70, 56, + 8, 5, 1, 34, 3, 247, 215, 25, 70, 56, 8, 6, 1, 188, 3, 70, 56, 8, 5, 1, + 188, 3, 70, 56, 8, 6, 1, 188, 3, 236, 116, 55, 8, 5, 1, 188, 3, 236, 116, + 55, 8, 6, 1, 188, 3, 208, 227, 8, 5, 1, 188, 3, 208, 227, 8, 6, 1, 188, + 3, 246, 53, 25, 165, 8, 5, 1, 188, 3, 246, 53, 25, 165, 8, 6, 1, 188, 3, + 246, 53, 25, 237, 253, 8, 5, 1, 188, 3, 246, 53, 25, 237, 253, 8, 6, 1, + 188, 3, 246, 53, 25, 236, 116, 55, 8, 5, 1, 188, 3, 246, 53, 25, 236, + 116, 55, 8, 6, 1, 188, 3, 246, 53, 25, 208, 227, 8, 5, 1, 188, 3, 246, + 53, 25, 208, 227, 8, 6, 1, 188, 3, 246, 53, 25, 70, 56, 8, 5, 1, 188, 3, + 246, 53, 25, 70, 56, 8, 6, 1, 235, 206, 3, 236, 116, 55, 8, 5, 1, 235, + 206, 3, 236, 116, 55, 8, 6, 1, 235, 206, 3, 70, 56, 8, 5, 1, 235, 206, 3, + 70, 56, 8, 6, 1, 158, 3, 70, 56, 8, 5, 1, 158, 3, 70, 56, 8, 6, 1, 158, + 3, 236, 116, 55, 8, 5, 1, 158, 3, 236, 116, 55, 8, 6, 1, 158, 3, 246, 53, + 25, 165, 8, 5, 1, 158, 3, 246, 53, 25, 165, 8, 6, 1, 158, 3, 246, 53, 25, + 237, 253, 8, 5, 1, 158, 3, 246, 53, 25, 237, 253, 8, 6, 1, 158, 3, 246, + 53, 25, 236, 116, 55, 8, 5, 1, 158, 3, 246, 53, 25, 236, 116, 55, 8, 6, + 1, 158, 3, 246, 53, 25, 208, 227, 8, 5, 1, 158, 3, 246, 53, 25, 208, 227, + 8, 6, 1, 158, 3, 246, 53, 25, 70, 56, 8, 5, 1, 158, 3, 246, 53, 25, 70, + 56, 8, 6, 1, 158, 3, 236, 54, 25, 165, 8, 5, 1, 158, 3, 236, 54, 25, 165, + 8, 6, 1, 158, 3, 236, 54, 25, 237, 253, 8, 5, 1, 158, 3, 236, 54, 25, + 237, 253, 8, 6, 1, 158, 3, 236, 54, 25, 236, 116, 55, 8, 5, 1, 158, 3, + 236, 54, 25, 236, 116, 55, 8, 6, 1, 158, 3, 236, 54, 25, 208, 227, 8, 5, + 1, 158, 3, 236, 54, 25, 208, 227, 8, 6, 1, 158, 3, 236, 54, 25, 70, 56, + 8, 5, 1, 158, 3, 236, 54, 25, 70, 56, 8, 6, 1, 106, 3, 70, 56, 8, 5, 1, + 106, 3, 70, 56, 8, 6, 1, 106, 3, 236, 116, 55, 8, 5, 1, 106, 3, 236, 116, + 55, 8, 6, 1, 106, 3, 236, 54, 25, 165, 8, 5, 1, 106, 3, 236, 54, 25, 165, + 8, 6, 1, 106, 3, 236, 54, 25, 237, 253, 8, 5, 1, 106, 3, 236, 54, 25, + 237, 253, 8, 6, 1, 106, 3, 236, 54, 25, 236, 116, 55, 8, 5, 1, 106, 3, + 236, 54, 25, 236, 116, 55, 8, 6, 1, 106, 3, 236, 54, 25, 208, 227, 8, 5, + 1, 106, 3, 236, 54, 25, 208, 227, 8, 6, 1, 106, 3, 236, 54, 25, 70, 56, + 8, 5, 1, 106, 3, 236, 54, 25, 70, 56, 8, 6, 1, 203, 125, 3, 237, 253, 8, + 5, 1, 203, 125, 3, 237, 253, 8, 6, 1, 203, 125, 3, 70, 56, 8, 5, 1, 203, + 125, 3, 70, 56, 8, 6, 1, 203, 125, 3, 236, 116, 55, 8, 5, 1, 203, 125, 3, + 236, 116, 55, 8, 6, 1, 203, 125, 3, 208, 227, 8, 5, 1, 203, 125, 3, 208, + 227, 8, 6, 1, 224, 147, 227, 78, 8, 5, 1, 224, 147, 227, 78, 8, 6, 1, + 224, 147, 206, 164, 8, 5, 1, 224, 147, 206, 164, 8, 6, 1, 203, 125, 3, + 227, 14, 8, 5, 1, 203, 125, 3, 227, 14, 30, 5, 1, 251, 3, 3, 217, 195, + 30, 5, 1, 251, 3, 3, 244, 141, 30, 5, 1, 251, 3, 3, 217, 196, 25, 206, + 70, 30, 5, 1, 251, 3, 3, 244, 142, 25, 206, 70, 30, 5, 1, 251, 3, 3, 217, + 196, 25, 219, 189, 30, 5, 1, 251, 3, 3, 244, 142, 25, 219, 189, 30, 5, 1, + 251, 3, 3, 217, 196, 25, 218, 239, 30, 5, 1, 251, 3, 3, 244, 142, 25, + 218, 239, 30, 6, 1, 251, 3, 3, 217, 195, 30, 6, 1, 251, 3, 3, 244, 141, + 30, 6, 1, 251, 3, 3, 217, 196, 25, 206, 70, 30, 6, 1, 251, 3, 3, 244, + 142, 25, 206, 70, 30, 6, 1, 251, 3, 3, 217, 196, 25, 219, 189, 30, 6, 1, + 251, 3, 3, 244, 142, 25, 219, 189, 30, 6, 1, 251, 3, 3, 217, 196, 25, + 218, 239, 30, 6, 1, 251, 3, 3, 244, 142, 25, 218, 239, 30, 5, 1, 241, 38, + 3, 217, 195, 30, 5, 1, 241, 38, 3, 244, 141, 30, 5, 1, 241, 38, 3, 217, + 196, 25, 206, 70, 30, 5, 1, 241, 38, 3, 244, 142, 25, 206, 70, 30, 5, 1, + 241, 38, 3, 217, 196, 25, 219, 189, 30, 5, 1, 241, 38, 3, 244, 142, 25, + 219, 189, 30, 6, 1, 241, 38, 3, 217, 195, 30, 6, 1, 241, 38, 3, 244, 141, + 30, 6, 1, 241, 38, 3, 217, 196, 25, 206, 70, 30, 6, 1, 241, 38, 3, 244, + 142, 25, 206, 70, 30, 6, 1, 241, 38, 3, 217, 196, 25, 219, 189, 30, 6, 1, + 241, 38, 3, 244, 142, 25, 219, 189, 30, 5, 1, 240, 249, 3, 217, 195, 30, + 5, 1, 240, 249, 3, 244, 141, 30, 5, 1, 240, 249, 3, 217, 196, 25, 206, + 70, 30, 5, 1, 240, 249, 3, 244, 142, 25, 206, 70, 30, 5, 1, 240, 249, 3, + 217, 196, 25, 219, 189, 30, 5, 1, 240, 249, 3, 244, 142, 25, 219, 189, + 30, 5, 1, 240, 249, 3, 217, 196, 25, 218, 239, 30, 5, 1, 240, 249, 3, + 244, 142, 25, 218, 239, 30, 6, 1, 240, 249, 3, 217, 195, 30, 6, 1, 240, + 249, 3, 244, 141, 30, 6, 1, 240, 249, 3, 217, 196, 25, 206, 70, 30, 6, 1, + 240, 249, 3, 244, 142, 25, 206, 70, 30, 6, 1, 240, 249, 3, 217, 196, 25, + 219, 189, 30, 6, 1, 240, 249, 3, 244, 142, 25, 219, 189, 30, 6, 1, 240, + 249, 3, 217, 196, 25, 218, 239, 30, 6, 1, 240, 249, 3, 244, 142, 25, 218, + 239, 30, 5, 1, 230, 231, 3, 217, 195, 30, 5, 1, 230, 231, 3, 244, 141, + 30, 5, 1, 230, 231, 3, 217, 196, 25, 206, 70, 30, 5, 1, 230, 231, 3, 244, + 142, 25, 206, 70, 30, 5, 1, 230, 231, 3, 217, 196, 25, 219, 189, 30, 5, + 1, 230, 231, 3, 244, 142, 25, 219, 189, 30, 5, 1, 230, 231, 3, 217, 196, + 25, 218, 239, 30, 5, 1, 230, 231, 3, 244, 142, 25, 218, 239, 30, 6, 1, + 230, 231, 3, 217, 195, 30, 6, 1, 230, 231, 3, 244, 141, 30, 6, 1, 230, + 231, 3, 217, 196, 25, 206, 70, 30, 6, 1, 230, 231, 3, 244, 142, 25, 206, + 70, 30, 6, 1, 230, 231, 3, 217, 196, 25, 219, 189, 30, 6, 1, 230, 231, 3, + 244, 142, 25, 219, 189, 30, 6, 1, 230, 231, 3, 217, 196, 25, 218, 239, + 30, 6, 1, 230, 231, 3, 244, 142, 25, 218, 239, 30, 5, 1, 220, 35, 3, 217, + 195, 30, 5, 1, 220, 35, 3, 244, 141, 30, 5, 1, 220, 35, 3, 217, 196, 25, + 206, 70, 30, 5, 1, 220, 35, 3, 244, 142, 25, 206, 70, 30, 5, 1, 220, 35, + 3, 217, 196, 25, 219, 189, 30, 5, 1, 220, 35, 3, 244, 142, 25, 219, 189, + 30, 6, 1, 220, 35, 3, 217, 195, 30, 6, 1, 220, 35, 3, 244, 141, 30, 6, 1, + 220, 35, 3, 217, 196, 25, 206, 70, 30, 6, 1, 220, 35, 3, 244, 142, 25, + 206, 70, 30, 6, 1, 220, 35, 3, 217, 196, 25, 219, 189, 30, 6, 1, 220, 35, + 3, 244, 142, 25, 219, 189, 30, 5, 1, 206, 217, 3, 217, 195, 30, 5, 1, + 206, 217, 3, 244, 141, 30, 5, 1, 206, 217, 3, 217, 196, 25, 206, 70, 30, + 5, 1, 206, 217, 3, 244, 142, 25, 206, 70, 30, 5, 1, 206, 217, 3, 217, + 196, 25, 219, 189, 30, 5, 1, 206, 217, 3, 244, 142, 25, 219, 189, 30, 5, + 1, 206, 217, 3, 217, 196, 25, 218, 239, 30, 5, 1, 206, 217, 3, 244, 142, + 25, 218, 239, 30, 6, 1, 206, 217, 3, 244, 141, 30, 6, 1, 206, 217, 3, + 244, 142, 25, 206, 70, 30, 6, 1, 206, 217, 3, 244, 142, 25, 219, 189, 30, + 6, 1, 206, 217, 3, 244, 142, 25, 218, 239, 30, 5, 1, 220, 37, 3, 217, + 195, 30, 5, 1, 220, 37, 3, 244, 141, 30, 5, 1, 220, 37, 3, 217, 196, 25, + 206, 70, 30, 5, 1, 220, 37, 3, 244, 142, 25, 206, 70, 30, 5, 1, 220, 37, + 3, 217, 196, 25, 219, 189, 30, 5, 1, 220, 37, 3, 244, 142, 25, 219, 189, + 30, 5, 1, 220, 37, 3, 217, 196, 25, 218, 239, 30, 5, 1, 220, 37, 3, 244, + 142, 25, 218, 239, 30, 6, 1, 220, 37, 3, 217, 195, 30, 6, 1, 220, 37, 3, + 244, 141, 30, 6, 1, 220, 37, 3, 217, 196, 25, 206, 70, 30, 6, 1, 220, 37, + 3, 244, 142, 25, 206, 70, 30, 6, 1, 220, 37, 3, 217, 196, 25, 219, 189, + 30, 6, 1, 220, 37, 3, 244, 142, 25, 219, 189, 30, 6, 1, 220, 37, 3, 217, + 196, 25, 218, 239, 30, 6, 1, 220, 37, 3, 244, 142, 25, 218, 239, 30, 5, + 1, 251, 3, 3, 206, 70, 30, 5, 1, 251, 3, 3, 219, 189, 30, 5, 1, 241, 38, + 3, 206, 70, 30, 5, 1, 241, 38, 3, 219, 189, 30, 5, 1, 240, 249, 3, 206, + 70, 30, 5, 1, 240, 249, 3, 219, 189, 30, 5, 1, 230, 231, 3, 206, 70, 30, + 5, 1, 230, 231, 3, 219, 189, 30, 5, 1, 220, 35, 3, 206, 70, 30, 5, 1, + 220, 35, 3, 219, 189, 30, 5, 1, 206, 217, 3, 206, 70, 30, 5, 1, 206, 217, + 3, 219, 189, 30, 5, 1, 220, 37, 3, 206, 70, 30, 5, 1, 220, 37, 3, 219, + 189, 30, 5, 1, 251, 3, 3, 217, 196, 25, 202, 221, 30, 5, 1, 251, 3, 3, + 244, 142, 25, 202, 221, 30, 5, 1, 251, 3, 3, 217, 196, 25, 206, 71, 25, + 202, 221, 30, 5, 1, 251, 3, 3, 244, 142, 25, 206, 71, 25, 202, 221, 30, + 5, 1, 251, 3, 3, 217, 196, 25, 219, 190, 25, 202, 221, 30, 5, 1, 251, 3, + 3, 244, 142, 25, 219, 190, 25, 202, 221, 30, 5, 1, 251, 3, 3, 217, 196, + 25, 218, 240, 25, 202, 221, 30, 5, 1, 251, 3, 3, 244, 142, 25, 218, 240, + 25, 202, 221, 30, 6, 1, 251, 3, 3, 217, 196, 25, 217, 209, 30, 6, 1, 251, + 3, 3, 244, 142, 25, 217, 209, 30, 6, 1, 251, 3, 3, 217, 196, 25, 206, 71, + 25, 217, 209, 30, 6, 1, 251, 3, 3, 244, 142, 25, 206, 71, 25, 217, 209, + 30, 6, 1, 251, 3, 3, 217, 196, 25, 219, 190, 25, 217, 209, 30, 6, 1, 251, + 3, 3, 244, 142, 25, 219, 190, 25, 217, 209, 30, 6, 1, 251, 3, 3, 217, + 196, 25, 218, 240, 25, 217, 209, 30, 6, 1, 251, 3, 3, 244, 142, 25, 218, + 240, 25, 217, 209, 30, 5, 1, 240, 249, 3, 217, 196, 25, 202, 221, 30, 5, + 1, 240, 249, 3, 244, 142, 25, 202, 221, 30, 5, 1, 240, 249, 3, 217, 196, + 25, 206, 71, 25, 202, 221, 30, 5, 1, 240, 249, 3, 244, 142, 25, 206, 71, + 25, 202, 221, 30, 5, 1, 240, 249, 3, 217, 196, 25, 219, 190, 25, 202, + 221, 30, 5, 1, 240, 249, 3, 244, 142, 25, 219, 190, 25, 202, 221, 30, 5, + 1, 240, 249, 3, 217, 196, 25, 218, 240, 25, 202, 221, 30, 5, 1, 240, 249, + 3, 244, 142, 25, 218, 240, 25, 202, 221, 30, 6, 1, 240, 249, 3, 217, 196, + 25, 217, 209, 30, 6, 1, 240, 249, 3, 244, 142, 25, 217, 209, 30, 6, 1, + 240, 249, 3, 217, 196, 25, 206, 71, 25, 217, 209, 30, 6, 1, 240, 249, 3, + 244, 142, 25, 206, 71, 25, 217, 209, 30, 6, 1, 240, 249, 3, 217, 196, 25, + 219, 190, 25, 217, 209, 30, 6, 1, 240, 249, 3, 244, 142, 25, 219, 190, + 25, 217, 209, 30, 6, 1, 240, 249, 3, 217, 196, 25, 218, 240, 25, 217, + 209, 30, 6, 1, 240, 249, 3, 244, 142, 25, 218, 240, 25, 217, 209, 30, 5, + 1, 220, 37, 3, 217, 196, 25, 202, 221, 30, 5, 1, 220, 37, 3, 244, 142, + 25, 202, 221, 30, 5, 1, 220, 37, 3, 217, 196, 25, 206, 71, 25, 202, 221, + 30, 5, 1, 220, 37, 3, 244, 142, 25, 206, 71, 25, 202, 221, 30, 5, 1, 220, + 37, 3, 217, 196, 25, 219, 190, 25, 202, 221, 30, 5, 1, 220, 37, 3, 244, + 142, 25, 219, 190, 25, 202, 221, 30, 5, 1, 220, 37, 3, 217, 196, 25, 218, + 240, 25, 202, 221, 30, 5, 1, 220, 37, 3, 244, 142, 25, 218, 240, 25, 202, + 221, 30, 6, 1, 220, 37, 3, 217, 196, 25, 217, 209, 30, 6, 1, 220, 37, 3, + 244, 142, 25, 217, 209, 30, 6, 1, 220, 37, 3, 217, 196, 25, 206, 71, 25, + 217, 209, 30, 6, 1, 220, 37, 3, 244, 142, 25, 206, 71, 25, 217, 209, 30, + 6, 1, 220, 37, 3, 217, 196, 25, 219, 190, 25, 217, 209, 30, 6, 1, 220, + 37, 3, 244, 142, 25, 219, 190, 25, 217, 209, 30, 6, 1, 220, 37, 3, 217, + 196, 25, 218, 240, 25, 217, 209, 30, 6, 1, 220, 37, 3, 244, 142, 25, 218, + 240, 25, 217, 209, 30, 5, 1, 251, 3, 3, 205, 167, 30, 5, 1, 251, 3, 3, + 225, 170, 30, 5, 1, 251, 3, 3, 206, 71, 25, 202, 221, 30, 5, 1, 251, 3, + 3, 202, 221, 30, 5, 1, 251, 3, 3, 219, 190, 25, 202, 221, 30, 5, 1, 251, + 3, 3, 218, 239, 30, 5, 1, 251, 3, 3, 218, 240, 25, 202, 221, 30, 6, 1, + 251, 3, 3, 205, 167, 30, 6, 1, 251, 3, 3, 225, 170, 30, 6, 1, 251, 3, 3, + 206, 70, 30, 6, 1, 251, 3, 3, 219, 189, 30, 6, 1, 251, 3, 3, 217, 209, + 30, 228, 252, 30, 217, 209, 30, 217, 195, 30, 218, 239, 30, 243, 225, 25, + 218, 239, 30, 5, 1, 240, 249, 3, 206, 71, 25, 202, 221, 30, 5, 1, 240, + 249, 3, 202, 221, 30, 5, 1, 240, 249, 3, 219, 190, 25, 202, 221, 30, 5, + 1, 240, 249, 3, 218, 239, 30, 5, 1, 240, 249, 3, 218, 240, 25, 202, 221, + 30, 6, 1, 241, 38, 3, 206, 70, 30, 6, 1, 241, 38, 3, 219, 189, 30, 6, 1, + 240, 249, 3, 206, 70, 30, 6, 1, 240, 249, 3, 219, 189, 30, 6, 1, 240, + 249, 3, 217, 209, 30, 217, 196, 25, 206, 70, 30, 217, 196, 25, 219, 189, + 30, 217, 196, 25, 218, 239, 30, 5, 1, 230, 231, 3, 205, 167, 30, 5, 1, + 230, 231, 3, 225, 170, 30, 5, 1, 230, 231, 3, 243, 225, 25, 206, 70, 30, + 5, 1, 230, 231, 3, 243, 225, 25, 219, 189, 30, 5, 1, 230, 231, 3, 218, + 239, 30, 5, 1, 230, 231, 3, 243, 225, 25, 218, 239, 30, 6, 1, 230, 231, + 3, 205, 167, 30, 6, 1, 230, 231, 3, 225, 170, 30, 6, 1, 230, 231, 3, 206, + 70, 30, 6, 1, 230, 231, 3, 219, 189, 30, 244, 142, 25, 206, 70, 30, 244, + 142, 25, 219, 189, 30, 244, 142, 25, 218, 239, 30, 5, 1, 206, 217, 3, + 205, 167, 30, 5, 1, 206, 217, 3, 225, 170, 30, 5, 1, 206, 217, 3, 243, + 225, 25, 206, 70, 30, 5, 1, 206, 217, 3, 243, 225, 25, 219, 189, 30, 5, + 1, 216, 60, 3, 217, 195, 30, 5, 1, 216, 60, 3, 244, 141, 30, 5, 1, 206, + 217, 3, 218, 239, 30, 5, 1, 206, 217, 3, 243, 225, 25, 218, 239, 30, 6, + 1, 206, 217, 3, 205, 167, 30, 6, 1, 206, 217, 3, 225, 170, 30, 6, 1, 206, + 217, 3, 206, 70, 30, 6, 1, 206, 217, 3, 219, 189, 30, 6, 1, 216, 60, 3, + 244, 141, 30, 243, 225, 25, 206, 70, 30, 243, 225, 25, 219, 189, 30, 206, + 70, 30, 5, 1, 220, 37, 3, 206, 71, 25, 202, 221, 30, 5, 1, 220, 37, 3, + 202, 221, 30, 5, 1, 220, 37, 3, 219, 190, 25, 202, 221, 30, 5, 1, 220, + 37, 3, 218, 239, 30, 5, 1, 220, 37, 3, 218, 240, 25, 202, 221, 30, 6, 1, + 220, 35, 3, 206, 70, 30, 6, 1, 220, 35, 3, 219, 189, 30, 6, 1, 220, 37, + 3, 206, 70, 30, 6, 1, 220, 37, 3, 219, 189, 30, 6, 1, 220, 37, 3, 217, + 209, 30, 219, 189, 30, 244, 141, 241, 93, 217, 62, 241, 104, 217, 62, + 241, 93, 211, 228, 241, 104, 211, 228, 209, 28, 211, 228, 239, 145, 211, + 228, 212, 86, 211, 228, 240, 16, 211, 228, 217, 179, 211, 228, 209, 63, + 211, 228, 237, 146, 211, 228, 202, 85, 204, 24, 211, 228, 202, 85, 204, + 24, 221, 183, 202, 85, 204, 24, 230, 96, 227, 213, 82, 216, 7, 82, 235, + 220, 221, 184, 235, 220, 240, 16, 244, 144, 241, 93, 244, 144, 241, 104, + 244, 144, 236, 106, 142, 52, 80, 227, 114, 52, 124, 227, 114, 49, 212, + 120, 217, 31, 82, 50, 212, 120, 217, 31, 82, 212, 120, 226, 255, 217, 31, + 82, 212, 120, 236, 241, 217, 31, 82, 49, 52, 217, 31, 82, 50, 52, 217, + 31, 82, 52, 226, 255, 217, 31, 82, 52, 236, 241, 217, 31, 82, 244, 195, + 52, 244, 195, 247, 177, 208, 82, 247, 177, 118, 70, 227, 232, 120, 70, + 227, 232, 236, 106, 241, 108, 235, 218, 218, 62, 227, 115, 213, 130, 219, + 89, 213, 130, 227, 213, 241, 102, 216, 7, 241, 102, 218, 42, 243, 165, + 239, 157, 227, 213, 219, 196, 216, 7, 219, 196, 223, 73, 221, 190, 211, + 228, 218, 247, 224, 116, 54, 218, 247, 209, 153, 209, 37, 54, 217, 236, + 52, 217, 236, 208, 70, 217, 236, 216, 73, 217, 236, 216, 73, 52, 217, + 236, 216, 73, 208, 70, 217, 236, 247, 33, 212, 120, 227, 217, 250, 218, + 217, 31, 82, 212, 120, 216, 11, 250, 218, 217, 31, 82, 216, 134, 82, 52, + 240, 212, 82, 230, 247, 219, 198, 206, 243, 167, 208, 250, 247, 34, 231, + 8, 218, 62, 250, 57, 235, 221, 247, 177, 239, 138, 212, 57, 49, 51, 247, + 227, 3, 217, 41, 50, 51, 247, 227, 3, 217, 41, 52, 217, 47, 82, 217, 47, + 240, 212, 82, 240, 212, 217, 47, 82, 208, 203, 2, 240, 250, 216, 73, 218, + 126, 54, 62, 96, 247, 177, 62, 86, 247, 177, 124, 250, 59, 216, 73, 213, + 143, 246, 17, 206, 224, 120, 250, 58, 251, 18, 205, 243, 245, 231, 224, + 103, 54, 210, 153, 244, 144, 230, 239, 206, 243, 239, 198, 217, 179, 82, + 126, 70, 217, 178, 217, 58, 217, 236, 239, 147, 70, 217, 178, 239, 233, + 70, 217, 178, 120, 70, 217, 178, 239, 147, 70, 82, 242, 83, 245, 130, + 208, 81, 80, 239, 147, 243, 83, 225, 10, 13, 211, 228, 203, 238, 230, 96, + 239, 100, 250, 155, 230, 237, 208, 219, 230, 237, 213, 130, 230, 237, + 218, 76, 227, 213, 230, 207, 216, 7, 230, 207, 239, 245, 211, 18, 230, + 207, 218, 42, 243, 165, 230, 207, 231, 20, 210, 101, 210, 170, 251, 128, + 210, 101, 210, 170, 231, 20, 10, 239, 159, 213, 61, 251, 128, 10, 239, + 159, 213, 61, 223, 67, 17, 213, 62, 221, 186, 17, 213, 62, 210, 199, 202, + 84, 210, 199, 8, 5, 1, 75, 210, 199, 149, 210, 199, 170, 210, 199, 195, + 210, 199, 213, 111, 210, 199, 199, 210, 199, 222, 63, 210, 199, 91, 54, + 210, 199, 224, 102, 210, 199, 241, 35, 54, 210, 199, 49, 219, 76, 210, + 199, 50, 219, 76, 210, 199, 8, 5, 1, 223, 163, 210, 246, 202, 84, 210, + 246, 105, 210, 246, 108, 210, 246, 147, 210, 246, 149, 210, 246, 170, + 210, 246, 195, 210, 246, 213, 111, 210, 246, 199, 210, 246, 222, 63, 210, + 246, 91, 54, 210, 246, 224, 102, 210, 246, 241, 35, 54, 210, 246, 49, + 219, 76, 210, 246, 50, 219, 76, 8, 210, 246, 5, 1, 63, 8, 210, 246, 5, 1, + 74, 8, 210, 246, 5, 1, 78, 8, 210, 246, 5, 1, 203, 196, 8, 210, 246, 5, + 1, 214, 192, 8, 210, 246, 5, 1, 237, 171, 8, 210, 246, 5, 1, 230, 54, 8, + 210, 246, 5, 1, 159, 8, 210, 246, 5, 1, 226, 185, 8, 210, 246, 5, 1, 223, + 163, 8, 210, 246, 5, 1, 219, 184, 8, 210, 246, 5, 1, 194, 8, 210, 246, 5, + 1, 210, 69, 240, 229, 54, 245, 243, 54, 245, 115, 54, 239, 128, 239, 132, + 54, 227, 94, 54, 224, 117, 54, 223, 90, 54, 218, 224, 54, 215, 120, 54, + 203, 246, 54, 222, 214, 213, 29, 54, 243, 92, 54, 240, 230, 54, 229, 79, + 54, 207, 196, 54, 242, 66, 54, 238, 166, 219, 2, 54, 218, 221, 54, 237, + 225, 54, 250, 24, 54, 236, 32, 54, 246, 233, 54, 227, 84, 208, 125, 54, + 211, 209, 54, 209, 150, 54, 231, 34, 215, 120, 54, 207, 177, 227, 94, 54, + 221, 173, 131, 54, 225, 120, 54, 215, 142, 54, 228, 4, 54, 39, 49, 237, + 87, 55, 39, 50, 237, 87, 55, 39, 163, 80, 227, 115, 219, 199, 39, 212, + 228, 80, 227, 115, 219, 199, 39, 250, 194, 53, 55, 39, 246, 18, 53, 55, + 39, 49, 53, 55, 39, 50, 53, 55, 39, 215, 253, 219, 199, 39, 246, 18, 215, + 253, 219, 199, 39, 250, 194, 215, 253, 219, 199, 39, 126, 187, 55, 39, + 239, 147, 187, 55, 39, 241, 88, 246, 61, 39, 241, 88, 211, 177, 39, 241, + 88, 243, 221, 39, 241, 88, 246, 62, 249, 20, 39, 49, 50, 53, 55, 39, 241, + 88, 214, 184, 39, 241, 88, 229, 147, 39, 241, 88, 206, 214, 218, 59, 208, + 85, 39, 216, 74, 212, 1, 219, 199, 39, 52, 80, 211, 32, 219, 199, 39, + 250, 204, 97, 39, 208, 70, 206, 245, 39, 204, 27, 247, 208, 55, 39, 96, + 53, 219, 199, 39, 163, 52, 212, 1, 219, 199, 39, 86, 237, 87, 3, 150, + 242, 68, 39, 96, 237, 87, 3, 150, 242, 68, 39, 49, 53, 56, 39, 50, 53, + 56, 39, 250, 60, 55, 251, 134, 220, 69, 251, 118, 208, 173, 209, 93, 210, + 255, 169, 6, 247, 125, 244, 55, 246, 223, 246, 218, 227, 115, 97, 247, + 35, 220, 69, 247, 84, 206, 254, 240, 231, 245, 200, 214, 181, 244, 55, + 240, 90, 132, 5, 239, 75, 132, 6, 237, 171, 248, 41, 6, 237, 171, 169, 6, + 237, 171, 218, 93, 245, 200, 218, 93, 245, 201, 115, 120, 218, 167, 132, + 6, 75, 248, 41, 6, 75, 132, 6, 159, 132, 5, 159, 228, 131, 66, 248, 231, + 97, 169, 6, 223, 163, 221, 42, 54, 211, 241, 216, 146, 245, 168, 132, 6, + 219, 184, 169, 6, 219, 184, 169, 6, 217, 134, 132, 6, 146, 248, 41, 6, + 146, 169, 6, 146, 217, 243, 209, 241, 216, 86, 213, 122, 82, 209, 162, + 54, 208, 115, 131, 54, 206, 39, 169, 6, 202, 159, 219, 215, 54, 220, 59, + 54, 230, 239, 220, 59, 54, 248, 41, 6, 202, 159, 207, 174, 30, 5, 1, 230, + 230, 229, 188, 54, 250, 213, 54, 132, 6, 249, 255, 248, 41, 6, 247, 125, + 240, 255, 97, 132, 5, 74, 132, 6, 74, 132, 6, 240, 174, 207, 174, 6, 240, + 174, 132, 6, 226, 185, 132, 5, 78, 137, 97, 248, 109, 97, 238, 68, 97, + 244, 179, 97, 231, 25, 211, 239, 215, 198, 6, 217, 134, 240, 93, 54, 169, + 5, 218, 167, 169, 5, 238, 235, 169, 6, 238, 235, 169, 6, 218, 167, 169, + 223, 162, 210, 217, 207, 174, 41, 6, 239, 75, 207, 174, 41, 6, 159, 216, + 73, 41, 6, 159, 207, 174, 41, 6, 203, 124, 169, 37, 6, 245, 51, 169, 37, + 5, 245, 51, 169, 37, 5, 74, 169, 37, 5, 75, 169, 37, 5, 230, 184, 217, + 212, 227, 114, 207, 174, 250, 235, 218, 247, 54, 251, 41, 207, 174, 5, + 240, 174, 16, 35, 214, 252, 211, 239, 204, 161, 239, 138, 118, 213, 107, + 204, 161, 239, 138, 118, 222, 57, 204, 161, 239, 138, 118, 209, 143, 204, + 161, 239, 138, 118, 209, 60, 204, 161, 239, 138, 120, 209, 57, 204, 161, + 239, 138, 118, 240, 21, 204, 161, 239, 138, 120, 240, 20, 204, 161, 239, + 138, 126, 240, 20, 204, 161, 239, 138, 239, 147, 240, 20, 204, 161, 239, + 138, 118, 212, 78, 204, 161, 239, 138, 239, 233, 212, 76, 204, 161, 239, + 138, 118, 241, 138, 204, 161, 239, 138, 126, 241, 136, 204, 161, 239, + 138, 239, 233, 241, 136, 204, 161, 239, 138, 213, 112, 241, 136, 239, + 138, 221, 43, 105, 215, 210, 221, 44, 105, 215, 210, 221, 44, 108, 215, + 210, 221, 44, 147, 215, 210, 221, 44, 149, 215, 210, 221, 44, 170, 215, + 210, 221, 44, 195, 215, 210, 221, 44, 213, 111, 215, 210, 221, 44, 199, + 215, 210, 221, 44, 222, 63, 215, 210, 221, 44, 209, 152, 215, 210, 221, + 44, 241, 112, 215, 210, 221, 44, 207, 154, 215, 210, 221, 44, 240, 18, + 215, 210, 221, 44, 118, 236, 11, 215, 210, 221, 44, 239, 233, 236, 11, + 215, 210, 221, 44, 118, 209, 36, 5, 215, 210, 221, 44, 105, 5, 215, 210, + 221, 44, 108, 5, 215, 210, 221, 44, 147, 5, 215, 210, 221, 44, 149, 5, + 215, 210, 221, 44, 170, 5, 215, 210, 221, 44, 195, 5, 215, 210, 221, 44, + 213, 111, 5, 215, 210, 221, 44, 199, 5, 215, 210, 221, 44, 222, 63, 5, + 215, 210, 221, 44, 209, 152, 5, 215, 210, 221, 44, 241, 112, 5, 215, 210, + 221, 44, 207, 154, 5, 215, 210, 221, 44, 240, 18, 5, 215, 210, 221, 44, + 118, 236, 11, 5, 215, 210, 221, 44, 239, 233, 236, 11, 5, 215, 210, 221, + 44, 118, 209, 36, 215, 210, 221, 44, 118, 209, 37, 247, 126, 245, 51, + 215, 210, 221, 44, 239, 233, 209, 36, 215, 210, 221, 44, 209, 153, 209, + 36, 215, 210, 221, 44, 216, 73, 118, 236, 11, 8, 5, 1, 216, 73, 247, 125, + 215, 210, 221, 44, 212, 88, 227, 255, 18, 215, 210, 221, 44, 240, 19, + 241, 182, 18, 215, 210, 221, 44, 240, 19, 209, 36, 215, 210, 221, 44, + 118, 236, 12, 209, 36, 204, 161, 239, 138, 202, 85, 209, 57, 207, 174, + 17, 108, 207, 174, 17, 147, 96, 47, 177, 47, 86, 47, 183, 47, 49, 50, 47, + 112, 121, 47, 153, 204, 46, 47, 153, 241, 176, 47, 211, 238, 241, 176, + 47, 211, 238, 204, 46, 47, 96, 53, 3, 95, 86, 53, 3, 95, 96, 204, 76, 47, + 86, 204, 76, 47, 96, 120, 237, 62, 47, 177, 120, 237, 62, 47, 86, 120, + 237, 62, 47, 183, 120, 237, 62, 47, 96, 53, 3, 209, 248, 86, 53, 3, 209, + 248, 96, 53, 239, 120, 142, 177, 53, 239, 120, 142, 86, 53, 239, 120, + 142, 183, 53, 239, 120, 142, 112, 121, 53, 3, 248, 218, 96, 53, 3, 113, + 86, 53, 3, 113, 96, 53, 3, 227, 14, 86, 53, 3, 227, 14, 49, 50, 204, 76, + 47, 49, 50, 53, 3, 95, 183, 202, 30, 47, 177, 53, 3, 208, 211, 227, 212, + 177, 53, 3, 208, 211, 216, 5, 183, 53, 3, 208, 211, 227, 212, 183, 53, 3, + 208, 211, 216, 5, 86, 53, 3, 245, 166, 242, 68, 183, 53, 3, 245, 166, + 227, 212, 250, 194, 208, 145, 213, 146, 47, 246, 18, 208, 145, 213, 146, + 47, 153, 204, 46, 53, 208, 173, 163, 142, 96, 53, 208, 173, 248, 231, + 115, 86, 53, 208, 173, 142, 250, 194, 171, 246, 62, 47, 246, 18, 171, + 246, 62, 47, 96, 237, 87, 3, 150, 206, 212, 96, 237, 87, 3, 150, 242, 68, + 177, 237, 87, 3, 150, 216, 5, 177, 237, 87, 3, 150, 227, 212, 86, 237, + 87, 3, 150, 206, 212, 86, 237, 87, 3, 150, 242, 68, 183, 237, 87, 3, 150, + 216, 5, 183, 237, 87, 3, 150, 227, 212, 86, 53, 115, 96, 47, 177, 53, 96, + 76, 183, 47, 96, 53, 115, 86, 47, 96, 219, 146, 250, 91, 177, 219, 146, + 250, 91, 86, 219, 146, 250, 91, 183, 219, 146, 250, 91, 96, 237, 87, 115, + 86, 237, 86, 86, 237, 87, 115, 96, 237, 86, 96, 52, 53, 3, 95, 49, 50, + 52, 53, 3, 95, 86, 52, 53, 3, 95, 96, 52, 47, 177, 52, 47, 86, 52, 47, + 183, 52, 47, 49, 50, 52, 47, 112, 121, 52, 47, 153, 204, 46, 52, 47, 153, + 241, 176, 52, 47, 211, 238, 241, 176, 52, 47, 211, 238, 204, 46, 52, 47, + 96, 208, 70, 47, 86, 208, 70, 47, 96, 211, 171, 47, 86, 211, 171, 47, + 177, 53, 3, 52, 95, 183, 53, 3, 52, 95, 96, 244, 143, 47, 177, 244, 143, + 47, 86, 244, 143, 47, 183, 244, 143, 47, 96, 53, 208, 173, 142, 86, 53, + 208, 173, 142, 96, 61, 47, 177, 61, 47, 86, 61, 47, 183, 61, 47, 177, 61, + 53, 239, 120, 142, 177, 61, 53, 220, 32, 219, 26, 177, 61, 53, 220, 32, + 219, 27, 3, 236, 106, 142, 177, 61, 53, 220, 32, 219, 27, 3, 80, 142, + 177, 61, 52, 47, 177, 61, 52, 53, 220, 32, 219, 26, 86, 61, 53, 239, 120, + 204, 99, 153, 204, 46, 53, 208, 173, 245, 165, 211, 238, 241, 176, 53, + 208, 173, 245, 165, 112, 121, 61, 47, 50, 53, 3, 5, 246, 61, 183, 53, 96, + 76, 177, 47, 126, 86, 250, 91, 96, 53, 3, 80, 95, 86, 53, 3, 80, 95, 49, + 50, 53, 3, 80, 95, 96, 53, 3, 52, 80, 95, 86, 53, 3, 52, 80, 95, 49, 50, + 53, 3, 52, 80, 95, 96, 220, 6, 47, 86, 220, 6, 47, 49, 50, 220, 6, 47, + 35, 251, 14, 245, 228, 219, 69, 243, 205, 209, 83, 240, 207, 209, 83, + 243, 104, 221, 166, 240, 208, 241, 94, 213, 117, 231, 38, 223, 101, 241, + 115, 220, 69, 221, 166, 250, 232, 241, 115, 220, 69, 5, 241, 115, 220, + 69, 245, 194, 250, 82, 224, 244, 243, 104, 221, 166, 245, 196, 250, 82, + 224, 244, 5, 245, 194, 250, 82, 224, 244, 241, 84, 76, 217, 214, 223, + 162, 217, 224, 223, 162, 245, 171, 223, 162, 210, 217, 224, 103, 54, 224, + 101, 54, 70, 218, 76, 243, 137, 212, 57, 213, 118, 224, 102, 250, 60, + 219, 254, 215, 253, 219, 254, 247, 178, 219, 254, 51, 215, 204, 245, 106, + 215, 204, 239, 140, 215, 204, 217, 210, 135, 231, 27, 50, 250, 217, 250, + 217, 225, 17, 250, 217, 211, 208, 250, 217, 243, 139, 243, 104, 221, 166, + 243, 143, 219, 82, 135, 221, 166, 219, 82, 135, 227, 37, 250, 226, 227, + 37, 219, 244, 230, 244, 206, 237, 231, 2, 52, 231, 2, 208, 70, 231, 2, + 245, 188, 231, 2, 210, 189, 231, 2, 205, 178, 231, 2, 246, 18, 231, 2, + 246, 18, 245, 188, 231, 2, 250, 194, 245, 188, 231, 2, 209, 82, 248, 152, + 216, 168, 217, 211, 70, 224, 102, 240, 215, 238, 172, 217, 211, 236, 121, + 208, 228, 219, 254, 216, 73, 208, 227, 230, 239, 227, 241, 194, 212, 122, + 204, 75, 203, 226, 217, 224, 221, 166, 208, 227, 224, 103, 208, 227, 250, + 53, 156, 135, 221, 166, 250, 53, 156, 135, 250, 151, 156, 135, 250, 151, + 247, 148, 221, 166, 251, 127, 156, 135, 222, 232, 250, 151, 221, 175, + 251, 127, 156, 135, 251, 7, 156, 135, 221, 166, 251, 7, 156, 135, 251, 7, + 156, 219, 245, 156, 135, 208, 70, 208, 227, 251, 15, 156, 135, 241, 30, + 135, 238, 171, 241, 30, 135, 243, 206, 248, 103, 250, 153, 209, 93, 227, + 122, 238, 171, 156, 135, 250, 151, 156, 208, 173, 219, 245, 209, 93, 231, + 65, 220, 69, 231, 65, 76, 219, 245, 250, 151, 156, 135, 245, 243, 241, + 34, 241, 35, 245, 242, 215, 253, 231, 50, 156, 135, 215, 253, 156, 135, + 245, 159, 135, 240, 254, 241, 33, 135, 211, 95, 241, 34, 244, 38, 156, + 135, 156, 208, 173, 247, 137, 244, 56, 225, 17, 247, 136, 217, 45, 156, + 135, 221, 166, 156, 135, 235, 154, 135, 221, 166, 235, 154, 135, 211, 39, + 241, 30, 135, 227, 179, 219, 245, 156, 135, 237, 247, 219, 245, 156, 135, + 227, 179, 115, 156, 135, 237, 247, 115, 156, 135, 227, 179, 247, 148, + 221, 166, 156, 135, 237, 247, 247, 148, 221, 166, 156, 135, 223, 240, + 227, 178, 223, 240, 237, 246, 248, 103, 221, 166, 241, 30, 135, 221, 166, + 227, 178, 221, 166, 237, 246, 222, 232, 227, 179, 221, 175, 156, 135, + 222, 232, 237, 247, 221, 175, 156, 135, 227, 179, 219, 245, 241, 30, 135, + 237, 247, 219, 245, 241, 30, 135, 222, 232, 227, 179, 221, 175, 241, 30, + 135, 222, 232, 237, 247, 221, 175, 241, 30, 135, 227, 179, 219, 245, 237, + 246, 237, 247, 219, 245, 227, 178, 222, 232, 227, 179, 221, 175, 237, + 246, 222, 232, 237, 247, 221, 175, 227, 178, 217, 249, 210, 236, 217, + 250, 219, 245, 156, 135, 210, 237, 219, 245, 156, 135, 217, 250, 219, + 245, 241, 30, 135, 210, 237, 219, 245, 241, 30, 135, 243, 104, 221, 166, + 217, 252, 243, 104, 221, 166, 210, 238, 210, 245, 220, 69, 210, 198, 220, + 69, 221, 166, 34, 210, 245, 220, 69, 221, 166, 34, 210, 198, 220, 69, + 210, 245, 76, 219, 245, 156, 135, 210, 198, 76, 219, 245, 156, 135, 222, + 232, 34, 210, 245, 76, 221, 175, 156, 135, 222, 232, 34, 210, 198, 76, + 221, 175, 156, 135, 210, 245, 76, 3, 221, 166, 156, 135, 210, 198, 76, 3, + 221, 166, 156, 135, 223, 221, 223, 222, 223, 223, 223, 222, 206, 237, 51, + 231, 65, 220, 69, 51, 219, 236, 220, 69, 51, 231, 65, 76, 219, 245, 156, + 135, 51, 219, 236, 76, 219, 245, 156, 135, 51, 247, 48, 51, 245, 99, 43, + 218, 76, 43, 224, 102, 43, 208, 219, 43, 243, 137, 212, 57, 43, 70, 219, + 254, 43, 215, 253, 219, 254, 43, 250, 60, 219, 254, 43, 241, 34, 43, 244, + 144, 103, 218, 76, 103, 224, 102, 103, 208, 219, 103, 70, 219, 254, 50, + 210, 3, 49, 210, 3, 121, 210, 3, 112, 210, 3, 250, 63, 224, 77, 208, 49, + 239, 165, 208, 70, 80, 248, 231, 50, 207, 173, 52, 80, 248, 231, 52, 50, + 207, 173, 243, 104, 221, 166, 217, 205, 221, 166, 208, 49, 243, 104, 221, + 166, 239, 166, 222, 234, 52, 80, 248, 231, 52, 50, 207, 173, 217, 250, + 206, 248, 216, 117, 210, 237, 206, 248, 216, 117, 221, 172, 211, 2, 220, + 69, 245, 194, 250, 82, 221, 172, 211, 1, 221, 172, 211, 2, 76, 219, 245, + 156, 135, 245, 194, 250, 82, 221, 172, 211, 2, 219, 245, 156, 135, 219, + 236, 220, 69, 231, 65, 220, 69, 223, 228, 237, 24, 245, 205, 225, 69, + 230, 255, 203, 156, 223, 81, 221, 174, 50, 250, 218, 3, 250, 128, 50, + 208, 85, 223, 162, 227, 37, 250, 226, 223, 162, 227, 37, 219, 244, 223, + 162, 230, 244, 223, 162, 206, 237, 243, 222, 219, 254, 70, 219, 254, 211, + 95, 219, 254, 243, 137, 208, 219, 247, 234, 49, 221, 172, 240, 92, 213, + 142, 217, 224, 50, 221, 172, 240, 92, 213, 142, 217, 224, 49, 213, 142, + 217, 224, 50, 213, 142, 217, 224, 216, 73, 208, 228, 241, 34, 245, 93, + 227, 37, 219, 244, 245, 93, 227, 37, 250, 226, 52, 210, 244, 52, 210, + 197, 52, 230, 244, 52, 206, 237, 218, 103, 156, 25, 219, 82, 135, 227, + 179, 3, 243, 85, 237, 247, 3, 243, 85, 205, 242, 223, 240, 227, 178, 205, + 242, 223, 240, 237, 246, 227, 179, 156, 208, 173, 219, 245, 237, 246, + 237, 247, 156, 208, 173, 219, 245, 227, 178, 156, 208, 173, 219, 245, + 227, 178, 156, 208, 173, 219, 245, 237, 246, 156, 208, 173, 219, 245, + 217, 249, 156, 208, 173, 219, 245, 210, 236, 243, 104, 221, 166, 217, + 253, 219, 245, 241, 36, 243, 104, 221, 166, 210, 239, 219, 245, 241, 36, + 221, 166, 51, 231, 65, 76, 219, 245, 156, 135, 221, 166, 51, 219, 236, + 76, 219, 245, 156, 135, 51, 231, 65, 76, 219, 245, 221, 166, 156, 135, + 51, 219, 236, 76, 219, 245, 221, 166, 156, 135, 227, 179, 247, 148, 221, + 166, 241, 30, 135, 237, 247, 247, 148, 221, 166, 241, 30, 135, 217, 250, + 247, 148, 221, 166, 241, 30, 135, 210, 237, 247, 148, 221, 166, 241, 30, + 135, 221, 166, 221, 172, 211, 2, 220, 69, 243, 104, 221, 166, 245, 196, + 250, 82, 221, 172, 211, 1, 221, 166, 221, 172, 211, 2, 76, 219, 245, 156, + 135, 243, 104, 221, 166, 245, 196, 250, 82, 221, 172, 211, 2, 219, 245, + 241, 36, 80, 241, 108, 224, 146, 236, 106, 241, 108, 112, 50, 243, 228, + 241, 108, 121, 50, 243, 228, 241, 108, 241, 115, 76, 3, 163, 236, 106, + 95, 241, 115, 76, 3, 80, 248, 231, 250, 50, 241, 84, 76, 236, 106, 95, 5, + 241, 115, 76, 3, 80, 248, 231, 250, 50, 241, 84, 76, 236, 106, 95, 241, + 115, 76, 3, 70, 55, 241, 115, 76, 3, 219, 203, 5, 241, 115, 76, 3, 219, + 203, 241, 115, 76, 3, 206, 246, 241, 115, 76, 3, 120, 236, 106, 211, 19, + 245, 194, 3, 163, 236, 106, 95, 245, 194, 3, 80, 248, 231, 250, 50, 241, + 84, 76, 236, 106, 95, 5, 245, 194, 3, 80, 248, 231, 250, 50, 241, 84, 76, + 236, 106, 95, 245, 194, 3, 219, 203, 5, 245, 194, 3, 219, 203, 202, 160, + 221, 164, 249, 11, 224, 243, 243, 223, 54, 241, 117, 47, 236, 38, 112, + 250, 94, 121, 250, 94, 217, 218, 218, 227, 204, 72, 227, 114, 49, 246, + 226, 50, 246, 226, 49, 239, 204, 50, 239, 204, 247, 248, 50, 245, 132, + 247, 248, 49, 245, 132, 208, 145, 50, 245, 132, 208, 145, 49, 245, 132, + 216, 73, 221, 166, 54, 51, 226, 246, 250, 128, 214, 158, 214, 166, 209, + 162, 216, 147, 218, 34, 231, 31, 205, 218, 211, 177, 218, 97, 76, 230, + 254, 54, 207, 174, 221, 166, 54, 204, 82, 236, 40, 208, 145, 49, 245, + 165, 208, 145, 50, 245, 165, 247, 248, 49, 245, 165, 247, 248, 50, 245, + 165, 208, 145, 162, 231, 2, 247, 248, 162, 231, 2, 239, 115, 212, 31, + 112, 250, 95, 248, 104, 120, 236, 106, 248, 220, 219, 247, 229, 151, 241, + 26, 208, 173, 209, 93, 216, 16, 203, 197, 231, 50, 34, 216, 144, 247, + 233, 229, 149, 227, 217, 250, 218, 155, 216, 11, 250, 218, 155, 241, 26, + 208, 173, 209, 93, 227, 222, 248, 115, 215, 252, 245, 61, 251, 15, 250, + 103, 210, 100, 208, 130, 215, 125, 243, 185, 219, 237, 245, 209, 209, + 220, 212, 44, 245, 155, 245, 154, 250, 169, 239, 98, 16, 235, 203, 250, + 169, 239, 98, 16, 211, 169, 217, 62, 250, 169, 239, 98, 16, 217, 63, 241, + 36, 250, 169, 239, 98, 16, 217, 63, 243, 143, 250, 169, 239, 98, 16, 217, + 63, 243, 221, 250, 169, 239, 98, 16, 217, 63, 230, 88, 250, 169, 239, 98, + 16, 217, 63, 246, 61, 250, 169, 239, 98, 16, 246, 62, 211, 69, 250, 169, + 239, 98, 16, 246, 62, 230, 88, 250, 169, 239, 98, 16, 212, 58, 142, 250, + 169, 239, 98, 16, 249, 21, 142, 250, 169, 239, 98, 16, 217, 63, 212, 57, + 250, 169, 239, 98, 16, 217, 63, 249, 20, 250, 169, 239, 98, 16, 217, 63, + 227, 178, 250, 169, 239, 98, 16, 217, 63, 237, 246, 250, 169, 239, 98, + 16, 96, 206, 76, 250, 169, 239, 98, 16, 86, 206, 76, 250, 169, 239, 98, + 16, 217, 63, 96, 47, 250, 169, 239, 98, 16, 217, 63, 86, 47, 250, 169, + 239, 98, 16, 246, 62, 249, 20, 250, 169, 239, 98, 16, 121, 210, 4, 206, + 246, 250, 169, 239, 98, 16, 244, 38, 211, 69, 250, 169, 239, 98, 16, 217, + 63, 121, 247, 33, 250, 169, 239, 98, 16, 217, 63, 244, 37, 250, 169, 239, + 98, 16, 121, 210, 4, 230, 88, 250, 169, 239, 98, 16, 177, 206, 76, 250, + 169, 239, 98, 16, 217, 63, 177, 47, 250, 169, 239, 98, 16, 112, 210, 4, + 219, 203, 250, 169, 239, 98, 16, 244, 49, 211, 69, 250, 169, 239, 98, 16, + 217, 63, 112, 247, 33, 250, 169, 239, 98, 16, 217, 63, 244, 48, 250, 169, + 239, 98, 16, 112, 210, 4, 230, 88, 250, 169, 239, 98, 16, 183, 206, 76, + 250, 169, 239, 98, 16, 217, 63, 183, 47, 250, 169, 239, 98, 16, 217, 30, + 206, 246, 250, 169, 239, 98, 16, 244, 38, 206, 246, 250, 169, 239, 98, + 16, 243, 222, 206, 246, 250, 169, 239, 98, 16, 230, 89, 206, 246, 250, + 169, 239, 98, 16, 246, 62, 206, 246, 250, 169, 239, 98, 16, 112, 212, + 240, 230, 88, 250, 169, 239, 98, 16, 217, 30, 217, 62, 250, 169, 239, 98, + 16, 246, 62, 211, 94, 250, 169, 239, 98, 16, 217, 63, 245, 242, 250, 169, + 239, 98, 16, 112, 210, 4, 243, 231, 250, 169, 239, 98, 16, 244, 49, 243, + 231, 250, 169, 239, 98, 16, 211, 95, 243, 231, 250, 169, 239, 98, 16, + 230, 89, 243, 231, 250, 169, 239, 98, 16, 246, 62, 243, 231, 250, 169, + 239, 98, 16, 121, 212, 240, 211, 69, 250, 169, 239, 98, 16, 49, 212, 240, + 211, 69, 250, 169, 239, 98, 16, 208, 228, 243, 231, 250, 169, 239, 98, + 16, 237, 247, 243, 231, 250, 169, 239, 98, 16, 245, 234, 142, 250, 169, + 239, 98, 16, 244, 49, 208, 227, 250, 169, 239, 98, 16, 202, 29, 250, 169, + 239, 98, 16, 211, 70, 208, 227, 250, 169, 239, 98, 16, 213, 144, 206, + 246, 250, 169, 239, 98, 16, 217, 63, 221, 166, 241, 36, 250, 169, 239, + 98, 16, 217, 63, 217, 46, 250, 169, 239, 98, 16, 121, 247, 34, 208, 227, + 250, 169, 239, 98, 16, 112, 247, 34, 208, 227, 250, 169, 239, 98, 16, + 230, 230, 250, 169, 239, 98, 16, 216, 59, 250, 169, 239, 98, 16, 220, 36, + 250, 169, 239, 98, 16, 251, 3, 206, 246, 250, 169, 239, 98, 16, 241, 38, + 206, 246, 250, 169, 239, 98, 16, 230, 231, 206, 246, 250, 169, 239, 98, + 16, 220, 37, 206, 246, 250, 169, 239, 98, 16, 251, 2, 221, 166, 246, 169, + 82, 50, 250, 218, 3, 183, 202, 30, 47, 212, 210, 171, 247, 233, 248, 129, + 97, 80, 227, 115, 3, 101, 243, 85, 231, 8, 97, 245, 189, 206, 244, 97, + 243, 158, 206, 244, 97, 241, 96, 97, 245, 224, 97, 61, 51, 3, 246, 218, + 80, 227, 114, 241, 68, 97, 250, 250, 229, 152, 97, 237, 37, 97, 43, 236, + 106, 248, 231, 3, 221, 163, 43, 208, 86, 242, 70, 247, 203, 246, 62, 3, + 221, 169, 47, 206, 242, 97, 224, 40, 97, 235, 216, 97, 220, 7, 237, 170, + 97, 220, 7, 228, 129, 97, 219, 59, 97, 219, 58, 97, 243, 167, 245, 91, + 16, 239, 159, 108, 212, 5, 97, 250, 169, 239, 98, 16, 217, 62, 244, 68, + 213, 131, 229, 152, 97, 217, 238, 219, 153, 222, 208, 219, 153, 217, 234, + 214, 185, 97, 246, 33, 214, 185, 97, 49, 219, 77, 206, 221, 113, 49, 219, + 77, 240, 200, 49, 219, 77, 226, 251, 113, 50, 219, 77, 206, 221, 113, 50, + 219, 77, 240, 200, 50, 219, 77, 226, 251, 113, 49, 51, 247, 227, 206, + 221, 245, 165, 49, 51, 247, 227, 240, 200, 49, 51, 247, 227, 226, 251, + 245, 165, 50, 51, 247, 227, 206, 221, 245, 165, 50, 51, 247, 227, 240, + 200, 50, 51, 247, 227, 226, 251, 245, 165, 49, 245, 93, 247, 227, 206, + 221, 113, 49, 245, 93, 247, 227, 101, 218, 159, 49, 245, 93, 247, 227, + 226, 251, 113, 245, 93, 247, 227, 240, 200, 50, 245, 93, 247, 227, 206, + 221, 113, 50, 245, 93, 247, 227, 101, 218, 159, 50, 245, 93, 247, 227, + 226, 251, 113, 231, 3, 240, 200, 236, 106, 227, 115, 240, 200, 206, 221, + 49, 219, 245, 226, 251, 50, 245, 93, 247, 227, 214, 167, 206, 221, 50, + 219, 245, 226, 251, 49, 245, 93, 247, 227, 214, 167, 210, 218, 208, 144, + 210, 218, 247, 247, 208, 145, 51, 155, 247, 248, 51, 155, 247, 248, 51, + 247, 227, 115, 208, 145, 51, 155, 40, 16, 247, 247, 49, 80, 98, 227, 114, + 50, 80, 98, 227, 114, 236, 106, 214, 202, 227, 113, 236, 106, 214, 202, + 227, 112, 236, 106, 214, 202, 227, 111, 236, 106, 214, 202, 227, 110, + 244, 29, 16, 157, 80, 25, 208, 145, 216, 16, 244, 29, 16, 157, 80, 25, + 247, 248, 216, 16, 244, 29, 16, 157, 80, 3, 246, 61, 244, 29, 16, 157, + 121, 25, 236, 106, 3, 246, 61, 244, 29, 16, 157, 112, 25, 236, 106, 3, + 246, 61, 244, 29, 16, 157, 80, 3, 208, 85, 244, 29, 16, 157, 121, 25, + 236, 106, 3, 208, 85, 244, 29, 16, 157, 112, 25, 236, 106, 3, 208, 85, + 244, 29, 16, 157, 80, 25, 204, 75, 244, 29, 16, 157, 121, 25, 236, 106, + 3, 204, 75, 244, 29, 16, 157, 112, 25, 236, 106, 3, 204, 75, 244, 29, 16, + 157, 121, 25, 236, 105, 244, 29, 16, 157, 112, 25, 236, 105, 244, 29, 16, + 157, 80, 25, 208, 145, 227, 222, 244, 29, 16, 157, 80, 25, 247, 248, 227, + 222, 51, 239, 172, 216, 78, 97, 241, 131, 97, 80, 227, 115, 240, 200, + 224, 214, 247, 214, 224, 214, 163, 115, 212, 227, 224, 214, 212, 228, + 115, 227, 28, 224, 214, 163, 115, 120, 212, 213, 224, 214, 120, 212, 214, + 115, 227, 28, 224, 214, 120, 212, 214, 230, 97, 224, 214, 208, 66, 224, + 214, 209, 124, 224, 214, 218, 253, 241, 180, 237, 239, 239, 92, 208, 145, + 219, 76, 247, 248, 219, 76, 208, 145, 245, 93, 155, 247, 248, 245, 93, + 155, 208, 145, 208, 133, 213, 33, 155, 247, 248, 208, 133, 213, 33, 155, + 61, 208, 101, 248, 115, 215, 253, 3, 246, 61, 211, 51, 239, 215, 251, + 142, 245, 90, 241, 116, 230, 244, 244, 68, 240, 204, 97, 62, 216, 11, 52, + 208, 85, 62, 227, 217, 52, 208, 85, 62, 206, 223, 52, 208, 85, 62, 242, + 69, 52, 208, 85, 62, 216, 11, 52, 208, 86, 3, 80, 142, 62, 227, 217, 52, + 208, 86, 3, 80, 142, 62, 216, 11, 208, 86, 3, 52, 80, 142, 251, 34, 246, + 19, 211, 58, 208, 220, 246, 19, 236, 41, 3, 239, 195, 214, 241, 62, 225, + 10, 227, 217, 208, 85, 62, 225, 10, 216, 11, 208, 85, 62, 225, 10, 206, + 223, 208, 85, 62, 225, 10, 242, 69, 208, 85, 52, 80, 142, 62, 51, 35, + 211, 61, 62, 246, 62, 35, 216, 148, 16, 35, 221, 48, 16, 35, 211, 90, 76, + 237, 61, 16, 35, 211, 90, 76, 209, 112, 16, 35, 241, 84, 76, 209, 112, + 16, 35, 241, 84, 76, 208, 105, 16, 35, 241, 71, 16, 35, 251, 130, 16, 35, + 248, 128, 16, 35, 249, 19, 16, 35, 236, 106, 210, 5, 16, 35, 227, 115, + 240, 51, 16, 35, 80, 210, 5, 16, 35, 239, 159, 240, 51, 16, 35, 247, 25, + 216, 77, 16, 35, 213, 7, 219, 211, 16, 35, 213, 7, 231, 49, 16, 35, 244, + 139, 227, 105, 241, 9, 16, 35, 244, 8, 245, 184, 105, 16, 35, 244, 8, + 245, 184, 108, 16, 35, 244, 8, 245, 184, 147, 16, 35, 244, 8, 245, 184, + 149, 16, 35, 182, 251, 130, 16, 35, 210, 95, 231, 112, 16, 35, 241, 84, + 76, 208, 106, 248, 33, 16, 35, 247, 59, 16, 35, 241, 84, 76, 225, 9, 16, + 35, 210, 242, 16, 35, 241, 9, 16, 35, 240, 11, 213, 130, 16, 35, 237, + 238, 213, 130, 16, 35, 216, 149, 213, 130, 16, 35, 206, 236, 213, 130, + 16, 35, 211, 228, 16, 35, 244, 46, 248, 37, 97, 171, 247, 233, 16, 35, + 222, 211, 16, 35, 244, 47, 239, 159, 108, 16, 35, 210, 243, 239, 159, + 108, 220, 82, 113, 220, 82, 246, 194, 220, 82, 239, 162, 220, 82, 230, + 239, 239, 162, 220, 82, 248, 125, 247, 190, 220, 82, 247, 241, 208, 250, + 220, 82, 247, 224, 248, 236, 235, 153, 220, 82, 250, 237, 76, 246, 168, + 220, 82, 244, 144, 220, 82, 245, 80, 251, 134, 221, 46, 220, 82, 52, 249, + 20, 43, 17, 105, 43, 17, 108, 43, 17, 147, 43, 17, 149, 43, 17, 170, 43, + 17, 195, 43, 17, 213, 111, 43, 17, 199, 43, 17, 222, 63, 43, 42, 209, + 152, 43, 42, 241, 112, 43, 42, 207, 154, 43, 42, 209, 55, 43, 42, 239, + 141, 43, 42, 240, 22, 43, 42, 212, 82, 43, 42, 213, 108, 43, 42, 241, + 140, 43, 42, 222, 60, 43, 42, 207, 151, 102, 17, 105, 102, 17, 108, 102, + 17, 147, 102, 17, 149, 102, 17, 170, 102, 17, 195, 102, 17, 213, 111, + 102, 17, 199, 102, 17, 222, 63, 102, 42, 209, 152, 102, 42, 241, 112, + 102, 42, 207, 154, 102, 42, 209, 55, 102, 42, 239, 141, 102, 42, 240, 22, + 102, 42, 212, 82, 102, 42, 213, 108, 102, 42, 241, 140, 102, 42, 222, 60, + 102, 42, 207, 151, 17, 118, 239, 102, 211, 61, 17, 120, 239, 102, 211, + 61, 17, 126, 239, 102, 211, 61, 17, 239, 147, 239, 102, 211, 61, 17, 239, + 233, 239, 102, 211, 61, 17, 212, 88, 239, 102, 211, 61, 17, 213, 112, + 239, 102, 211, 61, 17, 241, 143, 239, 102, 211, 61, 17, 222, 64, 239, + 102, 211, 61, 42, 209, 153, 239, 102, 211, 61, 42, 241, 113, 239, 102, + 211, 61, 42, 207, 155, 239, 102, 211, 61, 42, 209, 56, 239, 102, 211, 61, + 42, 239, 142, 239, 102, 211, 61, 42, 240, 23, 239, 102, 211, 61, 42, 212, + 83, 239, 102, 211, 61, 42, 213, 109, 239, 102, 211, 61, 42, 241, 141, + 239, 102, 211, 61, 42, 222, 61, 239, 102, 211, 61, 42, 207, 152, 239, + 102, 211, 61, 102, 8, 5, 1, 63, 102, 8, 5, 1, 249, 255, 102, 8, 5, 1, + 247, 125, 102, 8, 5, 1, 245, 51, 102, 8, 5, 1, 74, 102, 8, 5, 1, 240, + 174, 102, 8, 5, 1, 239, 75, 102, 8, 5, 1, 237, 171, 102, 8, 5, 1, 75, + 102, 8, 5, 1, 230, 184, 102, 8, 5, 1, 230, 54, 102, 8, 5, 1, 159, 102, 8, + 5, 1, 226, 185, 102, 8, 5, 1, 223, 163, 102, 8, 5, 1, 78, 102, 8, 5, 1, + 219, 184, 102, 8, 5, 1, 217, 134, 102, 8, 5, 1, 146, 102, 8, 5, 1, 194, + 102, 8, 5, 1, 210, 69, 102, 8, 5, 1, 68, 102, 8, 5, 1, 206, 164, 102, 8, + 5, 1, 204, 144, 102, 8, 5, 1, 203, 196, 102, 8, 5, 1, 203, 124, 102, 8, + 5, 1, 202, 159, 43, 8, 6, 1, 63, 43, 8, 6, 1, 249, 255, 43, 8, 6, 1, 247, + 125, 43, 8, 6, 1, 245, 51, 43, 8, 6, 1, 74, 43, 8, 6, 1, 240, 174, 43, 8, + 6, 1, 239, 75, 43, 8, 6, 1, 237, 171, 43, 8, 6, 1, 75, 43, 8, 6, 1, 230, + 184, 43, 8, 6, 1, 230, 54, 43, 8, 6, 1, 159, 43, 8, 6, 1, 226, 185, 43, + 8, 6, 1, 223, 163, 43, 8, 6, 1, 78, 43, 8, 6, 1, 219, 184, 43, 8, 6, 1, + 217, 134, 43, 8, 6, 1, 146, 43, 8, 6, 1, 194, 43, 8, 6, 1, 210, 69, 43, + 8, 6, 1, 68, 43, 8, 6, 1, 206, 164, 43, 8, 6, 1, 204, 144, 43, 8, 6, 1, + 203, 196, 43, 8, 6, 1, 203, 124, 43, 8, 6, 1, 202, 159, 43, 8, 5, 1, 63, + 43, 8, 5, 1, 249, 255, 43, 8, 5, 1, 247, 125, 43, 8, 5, 1, 245, 51, 43, + 8, 5, 1, 74, 43, 8, 5, 1, 240, 174, 43, 8, 5, 1, 239, 75, 43, 8, 5, 1, + 237, 171, 43, 8, 5, 1, 75, 43, 8, 5, 1, 230, 184, 43, 8, 5, 1, 230, 54, + 43, 8, 5, 1, 159, 43, 8, 5, 1, 226, 185, 43, 8, 5, 1, 223, 163, 43, 8, 5, + 1, 78, 43, 8, 5, 1, 219, 184, 43, 8, 5, 1, 217, 134, 43, 8, 5, 1, 146, + 43, 8, 5, 1, 194, 43, 8, 5, 1, 210, 69, 43, 8, 5, 1, 68, 43, 8, 5, 1, + 206, 164, 43, 8, 5, 1, 204, 144, 43, 8, 5, 1, 203, 196, 43, 8, 5, 1, 203, + 124, 43, 8, 5, 1, 202, 159, 43, 17, 202, 84, 182, 43, 42, 241, 112, 182, + 43, 42, 207, 154, 182, 43, 42, 209, 55, 182, 43, 42, 239, 141, 182, 43, + 42, 240, 22, 182, 43, 42, 212, 82, 182, 43, 42, 213, 108, 182, 43, 42, + 241, 140, 182, 43, 42, 222, 60, 182, 43, 42, 207, 151, 52, 43, 17, 105, + 52, 43, 17, 108, 52, 43, 17, 147, 52, 43, 17, 149, 52, 43, 17, 170, 52, + 43, 17, 195, 52, 43, 17, 213, 111, 52, 43, 17, 199, 52, 43, 17, 222, 63, + 52, 43, 42, 209, 152, 182, 43, 17, 202, 84, 98, 116, 157, 236, 105, 98, + 116, 79, 236, 105, 98, 116, 157, 206, 38, 98, 116, 79, 206, 38, 98, 116, + 157, 208, 70, 244, 145, 236, 105, 98, 116, 79, 208, 70, 244, 145, 236, + 105, 98, 116, 157, 208, 70, 244, 145, 206, 38, 98, 116, 79, 208, 70, 244, + 145, 206, 38, 98, 116, 157, 217, 58, 244, 145, 236, 105, 98, 116, 79, + 217, 58, 244, 145, 236, 105, 98, 116, 157, 217, 58, 244, 145, 206, 38, + 98, 116, 79, 217, 58, 244, 145, 206, 38, 98, 116, 157, 121, 25, 216, 16, + 98, 116, 121, 157, 25, 50, 237, 49, 98, 116, 121, 79, 25, 50, 227, 134, + 98, 116, 79, 121, 25, 216, 16, 98, 116, 157, 121, 25, 227, 222, 98, 116, + 121, 157, 25, 49, 237, 49, 98, 116, 121, 79, 25, 49, 227, 134, 98, 116, + 79, 121, 25, 227, 222, 98, 116, 157, 112, 25, 216, 16, 98, 116, 112, 157, + 25, 50, 237, 49, 98, 116, 112, 79, 25, 50, 227, 134, 98, 116, 79, 112, + 25, 216, 16, 98, 116, 157, 112, 25, 227, 222, 98, 116, 112, 157, 25, 49, + 237, 49, 98, 116, 112, 79, 25, 49, 227, 134, 98, 116, 79, 112, 25, 227, + 222, 98, 116, 157, 80, 25, 216, 16, 98, 116, 80, 157, 25, 50, 237, 49, + 98, 116, 112, 79, 25, 50, 121, 227, 134, 98, 116, 121, 79, 25, 50, 112, + 227, 134, 98, 116, 80, 79, 25, 50, 227, 134, 98, 116, 121, 157, 25, 50, + 112, 237, 49, 98, 116, 112, 157, 25, 50, 121, 237, 49, 98, 116, 79, 80, + 25, 216, 16, 98, 116, 157, 80, 25, 227, 222, 98, 116, 80, 157, 25, 49, + 237, 49, 98, 116, 112, 79, 25, 49, 121, 227, 134, 98, 116, 121, 79, 25, + 49, 112, 227, 134, 98, 116, 80, 79, 25, 49, 227, 134, 98, 116, 121, 157, + 25, 49, 112, 237, 49, 98, 116, 112, 157, 25, 49, 121, 237, 49, 98, 116, + 79, 80, 25, 227, 222, 98, 116, 157, 121, 25, 236, 105, 98, 116, 49, 79, + 25, 50, 121, 227, 134, 98, 116, 50, 79, 25, 49, 121, 227, 134, 98, 116, + 121, 157, 25, 236, 106, 237, 49, 98, 116, 121, 79, 25, 236, 106, 227, + 134, 98, 116, 50, 157, 25, 49, 121, 237, 49, 98, 116, 49, 157, 25, 50, + 121, 237, 49, 98, 116, 79, 121, 25, 236, 105, 98, 116, 157, 112, 25, 236, + 105, 98, 116, 49, 79, 25, 50, 112, 227, 134, 98, 116, 50, 79, 25, 49, + 112, 227, 134, 98, 116, 112, 157, 25, 236, 106, 237, 49, 98, 116, 112, + 79, 25, 236, 106, 227, 134, 98, 116, 50, 157, 25, 49, 112, 237, 49, 98, + 116, 49, 157, 25, 50, 112, 237, 49, 98, 116, 79, 112, 25, 236, 105, 98, + 116, 157, 80, 25, 236, 105, 98, 116, 49, 79, 25, 50, 80, 227, 134, 98, + 116, 50, 79, 25, 49, 80, 227, 134, 98, 116, 80, 157, 25, 236, 106, 237, + 49, 98, 116, 112, 79, 25, 121, 236, 106, 227, 134, 98, 116, 121, 79, 25, + 112, 236, 106, 227, 134, 98, 116, 80, 79, 25, 236, 106, 227, 134, 98, + 116, 49, 112, 79, 25, 50, 121, 227, 134, 98, 116, 50, 112, 79, 25, 49, + 121, 227, 134, 98, 116, 49, 121, 79, 25, 50, 112, 227, 134, 98, 116, 50, + 121, 79, 25, 49, 112, 227, 134, 98, 116, 121, 157, 25, 112, 236, 106, + 237, 49, 98, 116, 112, 157, 25, 121, 236, 106, 237, 49, 98, 116, 50, 157, + 25, 49, 80, 237, 49, 98, 116, 49, 157, 25, 50, 80, 237, 49, 98, 116, 79, + 80, 25, 236, 105, 98, 116, 157, 52, 244, 145, 236, 105, 98, 116, 79, 52, + 244, 145, 236, 105, 98, 116, 157, 52, 244, 145, 206, 38, 98, 116, 79, 52, + 244, 145, 206, 38, 98, 116, 52, 236, 105, 98, 116, 52, 206, 38, 98, 116, + 121, 212, 120, 25, 50, 242, 78, 98, 116, 121, 52, 25, 50, 212, 119, 98, + 116, 52, 121, 25, 216, 16, 98, 116, 121, 212, 120, 25, 49, 242, 78, 98, + 116, 121, 52, 25, 49, 212, 119, 98, 116, 52, 121, 25, 227, 222, 98, 116, + 112, 212, 120, 25, 50, 242, 78, 98, 116, 112, 52, 25, 50, 212, 119, 98, + 116, 52, 112, 25, 216, 16, 98, 116, 112, 212, 120, 25, 49, 242, 78, 98, + 116, 112, 52, 25, 49, 212, 119, 98, 116, 52, 112, 25, 227, 222, 98, 116, + 80, 212, 120, 25, 50, 242, 78, 98, 116, 80, 52, 25, 50, 212, 119, 98, + 116, 52, 80, 25, 216, 16, 98, 116, 80, 212, 120, 25, 49, 242, 78, 98, + 116, 80, 52, 25, 49, 212, 119, 98, 116, 52, 80, 25, 227, 222, 98, 116, + 121, 212, 120, 25, 236, 106, 242, 78, 98, 116, 121, 52, 25, 236, 106, + 212, 119, 98, 116, 52, 121, 25, 236, 105, 98, 116, 112, 212, 120, 25, + 236, 106, 242, 78, 98, 116, 112, 52, 25, 236, 106, 212, 119, 98, 116, 52, + 112, 25, 236, 105, 98, 116, 80, 212, 120, 25, 236, 106, 242, 78, 98, 116, + 80, 52, 25, 236, 106, 212, 119, 98, 116, 52, 80, 25, 236, 105, 98, 116, + 157, 250, 129, 121, 25, 216, 16, 98, 116, 157, 250, 129, 121, 25, 227, + 222, 98, 116, 157, 250, 129, 112, 25, 227, 222, 98, 116, 157, 250, 129, + 112, 25, 216, 16, 98, 116, 157, 243, 228, 206, 221, 50, 208, 173, 226, + 251, 227, 222, 98, 116, 157, 243, 228, 206, 221, 49, 208, 173, 226, 251, + 216, 16, 98, 116, 157, 243, 228, 245, 130, 98, 116, 157, 227, 222, 98, + 116, 157, 206, 224, 98, 116, 157, 216, 16, 98, 116, 157, 242, 70, 98, + 116, 79, 227, 222, 98, 116, 79, 206, 224, 98, 116, 79, 216, 16, 98, 116, + 79, 242, 70, 98, 116, 157, 49, 25, 79, 216, 16, 98, 116, 157, 112, 25, + 79, 242, 70, 98, 116, 79, 49, 25, 157, 216, 16, 98, 116, 79, 112, 25, + 157, 242, 70, 206, 221, 162, 248, 33, 226, 251, 118, 241, 139, 248, 33, + 226, 251, 118, 217, 56, 248, 33, 226, 251, 126, 241, 137, 248, 33, 226, + 251, 162, 248, 33, 226, 251, 239, 233, 241, 137, 248, 33, 226, 251, 126, + 217, 54, 248, 33, 226, 251, 213, 112, 241, 137, 248, 33, 239, 102, 248, + 33, 49, 213, 112, 241, 137, 248, 33, 49, 126, 217, 54, 248, 33, 49, 239, + 233, 241, 137, 248, 33, 49, 162, 248, 33, 49, 126, 241, 137, 248, 33, 49, + 118, 217, 56, 248, 33, 49, 118, 241, 139, 248, 33, 50, 162, 248, 33, 157, + 213, 79, 225, 10, 213, 79, 244, 150, 213, 79, 206, 221, 118, 241, 139, + 248, 33, 50, 118, 241, 139, 248, 33, 217, 60, 226, 251, 227, 222, 217, + 60, 226, 251, 216, 16, 217, 60, 206, 221, 227, 222, 217, 60, 206, 221, + 49, 25, 226, 251, 49, 25, 226, 251, 216, 16, 217, 60, 206, 221, 49, 25, + 226, 251, 216, 16, 217, 60, 206, 221, 49, 25, 206, 221, 50, 25, 226, 251, + 227, 222, 217, 60, 206, 221, 49, 25, 206, 221, 50, 25, 226, 251, 216, 16, + 217, 60, 206, 221, 216, 16, 217, 60, 206, 221, 50, 25, 226, 251, 227, + 222, 217, 60, 206, 221, 50, 25, 226, 251, 49, 25, 226, 251, 216, 16, 62, + 211, 177, 61, 211, 177, 61, 51, 3, 215, 189, 245, 164, 61, 51, 245, 195, + 62, 5, 211, 177, 51, 3, 236, 106, 240, 9, 51, 3, 80, 240, 9, 51, 3, 219, + 229, 245, 125, 240, 9, 51, 3, 206, 221, 49, 208, 173, 226, 251, 50, 240, + 9, 51, 3, 206, 221, 50, 208, 173, 226, 251, 49, 240, 9, 51, 3, 243, 228, + 245, 125, 240, 9, 62, 5, 211, 177, 61, 5, 211, 177, 62, 216, 143, 61, + 216, 143, 62, 80, 216, 143, 61, 80, 216, 143, 62, 219, 80, 61, 219, 80, + 62, 206, 223, 208, 85, 61, 206, 223, 208, 85, 62, 206, 223, 5, 208, 85, + 61, 206, 223, 5, 208, 85, 62, 216, 11, 208, 85, 61, 216, 11, 208, 85, 62, + 216, 11, 5, 208, 85, 61, 216, 11, 5, 208, 85, 62, 216, 11, 218, 60, 61, + 216, 11, 218, 60, 62, 242, 69, 208, 85, 61, 242, 69, 208, 85, 62, 242, + 69, 5, 208, 85, 61, 242, 69, 5, 208, 85, 62, 227, 217, 208, 85, 61, 227, + 217, 208, 85, 62, 227, 217, 5, 208, 85, 61, 227, 217, 5, 208, 85, 62, + 227, 217, 218, 60, 61, 227, 217, 218, 60, 62, 243, 221, 61, 243, 221, 61, + 243, 222, 245, 195, 62, 5, 243, 221, 239, 242, 226, 246, 61, 246, 61, + 242, 83, 246, 61, 246, 62, 3, 80, 240, 9, 247, 173, 62, 246, 61, 246, 62, + 3, 49, 162, 248, 43, 246, 62, 3, 50, 162, 248, 43, 246, 62, 3, 226, 251, + 162, 248, 43, 246, 62, 3, 206, 221, 162, 248, 43, 246, 62, 3, 206, 221, + 50, 217, 60, 248, 43, 246, 62, 3, 251, 15, 247, 148, 206, 221, 49, 217, + 60, 248, 43, 49, 162, 62, 246, 61, 50, 162, 62, 246, 61, 230, 240, 247, + 177, 230, 240, 61, 246, 61, 206, 221, 162, 230, 240, 61, 246, 61, 226, + 251, 162, 230, 240, 61, 246, 61, 206, 221, 49, 217, 60, 246, 55, 250, + 128, 206, 221, 50, 217, 60, 246, 55, 250, 128, 226, 251, 50, 217, 60, + 246, 55, 250, 128, 226, 251, 49, 217, 60, 246, 55, 250, 128, 206, 221, + 162, 246, 61, 226, 251, 162, 246, 61, 62, 226, 251, 50, 208, 85, 62, 226, + 251, 49, 208, 85, 62, 206, 221, 49, 208, 85, 62, 206, 221, 50, 208, 85, + 61, 247, 177, 51, 3, 49, 162, 248, 43, 51, 3, 50, 162, 248, 43, 51, 3, + 206, 221, 49, 243, 228, 162, 248, 43, 51, 3, 226, 251, 50, 243, 228, 162, + 248, 43, 61, 51, 3, 80, 248, 55, 227, 114, 61, 206, 223, 208, 86, 3, 243, + 85, 206, 223, 208, 86, 3, 49, 162, 248, 43, 206, 223, 208, 86, 3, 50, + 162, 248, 43, 228, 8, 246, 61, 61, 51, 3, 206, 221, 49, 217, 59, 61, 51, + 3, 226, 251, 49, 217, 59, 61, 51, 3, 226, 251, 50, 217, 59, 61, 51, 3, + 206, 221, 50, 217, 59, 61, 246, 62, 3, 206, 221, 49, 217, 59, 61, 246, + 62, 3, 226, 251, 49, 217, 59, 61, 246, 62, 3, 226, 251, 50, 217, 59, 61, + 246, 62, 3, 206, 221, 50, 217, 59, 206, 221, 49, 208, 85, 206, 221, 50, + 208, 85, 226, 251, 49, 208, 85, 61, 225, 10, 211, 177, 62, 225, 10, 211, + 177, 61, 225, 10, 5, 211, 177, 62, 225, 10, 5, 211, 177, 226, 251, 50, + 208, 85, 62, 210, 215, 3, 216, 162, 246, 7, 207, 3, 212, 15, 245, 236, + 62, 211, 94, 61, 211, 94, 227, 131, 209, 17, 210, 214, 250, 78, 221, 188, + 244, 19, 221, 188, 245, 204, 219, 250, 62, 209, 161, 61, 209, 161, 248, + 248, 247, 233, 248, 248, 98, 3, 246, 168, 248, 248, 98, 3, 203, 196, 214, + 254, 207, 4, 3, 216, 191, 242, 48, 236, 47, 248, 102, 61, 212, 237, 218, + 159, 62, 212, 237, 218, 159, 213, 68, 216, 73, 215, 198, 239, 201, 237, + 56, 247, 177, 62, 49, 218, 59, 231, 35, 62, 50, 218, 59, 231, 35, 61, 49, + 218, 59, 231, 35, 61, 112, 218, 59, 231, 35, 61, 50, 218, 59, 231, 35, + 61, 121, 218, 59, 231, 35, 212, 63, 25, 245, 129, 247, 11, 54, 216, 203, + 54, 248, 62, 54, 247, 83, 250, 208, 219, 230, 245, 130, 246, 143, 216, + 59, 245, 131, 76, 227, 9, 245, 131, 76, 230, 151, 211, 95, 25, 245, 138, + 240, 75, 97, 251, 115, 213, 70, 237, 131, 25, 212, 159, 219, 33, 97, 203, + 1, 203, 76, 208, 75, 35, 237, 51, 208, 75, 35, 228, 33, 208, 75, 35, 239, + 249, 208, 75, 35, 209, 18, 208, 75, 35, 204, 16, 208, 75, 35, 204, 80, + 208, 75, 35, 224, 12, 208, 75, 35, 241, 179, 204, 37, 76, 243, 249, 61, + 239, 114, 240, 102, 61, 212, 30, 240, 102, 62, 212, 30, 240, 102, 61, + 210, 215, 3, 216, 162, 239, 245, 217, 56, 224, 29, 228, 1, 217, 56, 224, + 29, 224, 234, 240, 43, 54, 241, 179, 225, 127, 54, 230, 69, 214, 218, + 206, 205, 222, 224, 218, 73, 250, 114, 209, 205, 238, 178, 247, 57, 227, + 184, 205, 202, 227, 145, 214, 187, 215, 20, 247, 43, 250, 145, 218, 108, + 61, 246, 150, 229, 81, 61, 246, 150, 217, 48, 61, 246, 150, 215, 206, 61, + 246, 150, 248, 54, 61, 246, 150, 229, 31, 61, 246, 150, 219, 45, 62, 246, + 150, 229, 81, 62, 246, 150, 217, 48, 62, 246, 150, 215, 206, 62, 246, + 150, 248, 54, 62, 246, 150, 229, 31, 62, 246, 150, 219, 45, 62, 211, 226, + 210, 227, 61, 237, 56, 210, 227, 61, 243, 222, 210, 227, 62, 246, 5, 210, + 227, 61, 211, 226, 210, 227, 62, 237, 56, 210, 227, 62, 243, 222, 210, + 227, 61, 246, 5, 210, 227, 236, 47, 211, 182, 217, 56, 221, 160, 241, + 139, 221, 160, 248, 158, 241, 139, 221, 155, 248, 158, 212, 81, 221, 155, + 223, 195, 239, 217, 54, 223, 195, 223, 66, 54, 223, 195, 213, 57, 54, + 204, 46, 210, 89, 245, 130, 241, 176, 210, 89, 245, 130, 206, 233, 216, + 139, 97, 216, 139, 16, 35, 207, 120, 218, 90, 216, 139, 16, 35, 207, 118, + 218, 90, 216, 139, 16, 35, 207, 117, 218, 90, 216, 139, 16, 35, 207, 115, + 218, 90, 216, 139, 16, 35, 207, 113, 218, 90, 216, 139, 16, 35, 207, 111, + 218, 90, 216, 139, 16, 35, 207, 109, 218, 90, 216, 139, 16, 35, 238, 176, + 225, 70, 62, 206, 233, 216, 139, 97, 216, 140, 219, 95, 97, 219, 68, 219, + 95, 97, 218, 238, 219, 95, 54, 204, 35, 97, 243, 214, 240, 101, 243, 214, + 240, 100, 243, 214, 240, 99, 243, 214, 240, 98, 243, 214, 240, 97, 243, + 214, 240, 96, 61, 246, 62, 3, 70, 216, 16, 61, 246, 62, 3, 120, 243, 83, + 62, 246, 62, 3, 61, 70, 216, 16, 62, 246, 62, 3, 120, 61, 243, 83, 224, + 45, 35, 203, 76, 224, 45, 35, 203, 0, 243, 195, 35, 237, 248, 203, 76, + 243, 195, 35, 227, 177, 203, 0, 243, 195, 35, 227, 177, 203, 76, 243, + 195, 35, 237, 248, 203, 0, 61, 239, 225, 62, 239, 225, 237, 131, 25, 218, + 163, 250, 228, 245, 128, 210, 154, 211, 103, 76, 251, 92, 214, 203, 251, + 29, 239, 197, 238, 187, 211, 103, 76, 237, 26, 250, 42, 97, 239, 213, + 219, 207, 61, 211, 94, 126, 227, 109, 245, 181, 216, 16, 126, 227, 109, + 245, 181, 227, 222, 204, 91, 54, 138, 205, 179, 54, 242, 75, 240, 43, 54, + 242, 75, 225, 127, 54, 230, 250, 240, 43, 25, 225, 127, 54, 225, 127, 25, + 240, 43, 54, 225, 127, 3, 211, 32, 54, 225, 127, 3, 211, 32, 25, 225, + 127, 25, 240, 43, 54, 80, 225, 127, 3, 211, 32, 54, 236, 106, 225, 127, + 3, 211, 32, 54, 225, 10, 61, 246, 61, 225, 10, 62, 246, 61, 225, 10, 5, + 61, 246, 61, 225, 86, 97, 243, 135, 97, 206, 230, 219, 67, 97, 245, 247, + 239, 97, 206, 201, 222, 217, 246, 203, 219, 137, 230, 75, 205, 240, 246, + 123, 62, 224, 30, 227, 128, 213, 101, 213, 140, 217, 38, 213, 120, 212, + 10, 248, 251, 248, 217, 103, 229, 151, 61, 242, 58, 225, 122, 61, 242, + 58, 229, 81, 62, 242, 58, 225, 122, 62, 242, 58, 229, 81, 212, 16, 204, + 3, 212, 19, 210, 215, 248, 135, 246, 7, 216, 190, 62, 212, 15, 209, 19, + 246, 8, 25, 216, 190, 207, 174, 61, 212, 237, 218, 159, 207, 174, 62, + 212, 237, 218, 159, 61, 243, 222, 231, 50, 211, 177, 245, 124, 228, 15, + 243, 162, 247, 39, 219, 253, 218, 163, 247, 40, 212, 48, 237, 36, 3, 61, + 245, 130, 43, 245, 124, 228, 15, 246, 195, 221, 192, 241, 62, 250, 255, + 220, 26, 49, 204, 66, 208, 113, 62, 207, 131, 49, 204, 66, 208, 113, 61, + 207, 131, 49, 204, 66, 208, 113, 62, 49, 228, 16, 224, 233, 61, 49, 228, + 16, 224, 233, 242, 53, 212, 40, 54, 79, 61, 242, 69, 208, 85, 49, 246, + 16, 241, 62, 103, 214, 254, 240, 84, 243, 228, 231, 50, 61, 246, 62, 231, + 50, 62, 211, 177, 62, 208, 50, 216, 84, 49, 241, 61, 216, 84, 49, 241, + 60, 250, 54, 16, 35, 206, 205, 79, 246, 62, 3, 211, 32, 25, 120, 187, 55, + 218, 254, 216, 13, 230, 252, 218, 254, 227, 219, 230, 252, 218, 254, 230, + 239, 218, 254, 62, 245, 131, 220, 32, 213, 8, 212, 252, 212, 203, 246, + 90, 247, 19, 236, 231, 212, 89, 238, 188, 204, 3, 236, 23, 238, 188, 3, + 237, 101, 225, 107, 16, 35, 227, 133, 224, 12, 207, 4, 220, 32, 237, 239, + 239, 148, 239, 226, 231, 50, 236, 126, 240, 34, 215, 15, 51, 239, 147, + 245, 164, 212, 66, 235, 163, 212, 69, 218, 230, 3, 248, 251, 209, 144, + 230, 169, 248, 236, 97, 237, 59, 237, 250, 97, 239, 105, 217, 180, 245, + 100, 220, 32, 62, 211, 177, 61, 239, 226, 3, 236, 106, 101, 62, 211, 33, + 62, 215, 25, 214, 190, 206, 221, 248, 38, 214, 190, 62, 214, 190, 226, + 251, 248, 38, 214, 190, 61, 214, 190, 61, 79, 246, 169, 82, 209, 162, + 227, 47, 54, 209, 221, 242, 52, 251, 52, 241, 57, 216, 188, 239, 238, + 216, 188, 237, 123, 205, 228, 237, 123, 203, 220, 237, 123, 226, 251, 50, + 219, 8, 219, 8, 206, 221, 50, 219, 8, 61, 222, 97, 62, 222, 97, 246, 169, + 82, 79, 246, 169, 82, 223, 224, 203, 196, 79, 223, 224, 203, 196, 248, + 248, 203, 196, 79, 248, 248, 203, 196, 219, 207, 30, 245, 130, 79, 30, + 245, 130, 171, 246, 218, 245, 130, 79, 171, 246, 218, 245, 130, 8, 245, + 130, 213, 77, 61, 8, 245, 130, 219, 207, 8, 245, 130, 225, 124, 245, 130, + 211, 95, 76, 244, 137, 239, 147, 209, 180, 250, 59, 239, 147, 248, 249, + 250, 59, 79, 239, 147, 248, 249, 250, 59, 239, 147, 246, 3, 250, 59, 62, + 239, 147, 218, 61, 211, 94, 61, 239, 147, 218, 61, 211, 94, 211, 221, + 211, 42, 219, 207, 61, 211, 94, 43, 61, 211, 94, 171, 246, 218, 62, 211, + 94, 62, 246, 218, 61, 211, 94, 219, 207, 62, 211, 94, 79, 219, 207, 62, + 211, 94, 218, 118, 211, 94, 213, 77, 61, 211, 94, 79, 250, 59, 171, 246, + 218, 250, 59, 241, 143, 211, 191, 250, 59, 241, 143, 218, 61, 62, 211, + 94, 241, 143, 218, 61, 218, 118, 211, 94, 212, 88, 218, 61, 62, 211, 94, + 241, 143, 218, 61, 216, 141, 62, 211, 94, 79, 241, 143, 218, 61, 216, + 141, 62, 211, 94, 207, 155, 218, 61, 62, 211, 94, 212, 83, 218, 61, 250, + 59, 209, 180, 250, 59, 171, 246, 218, 209, 180, 250, 59, 79, 209, 180, + 250, 59, 212, 88, 218, 218, 62, 25, 61, 239, 200, 62, 239, 200, 61, 239, + 200, 241, 143, 218, 218, 219, 207, 62, 239, 200, 43, 171, 246, 218, 241, + 143, 218, 61, 211, 94, 79, 209, 180, 218, 118, 250, 59, 212, 17, 208, + 244, 208, 78, 212, 17, 79, 246, 146, 212, 17, 211, 223, 79, 211, 223, + 248, 249, 250, 59, 241, 143, 209, 180, 217, 213, 250, 59, 79, 241, 143, + 209, 180, 217, 213, 250, 59, 245, 131, 82, 213, 77, 61, 246, 61, 182, + 103, 245, 131, 82, 226, 251, 50, 242, 50, 61, 211, 177, 206, 221, 50, + 242, 50, 61, 211, 177, 226, 251, 50, 213, 77, 61, 211, 177, 206, 221, 50, + 213, 77, 61, 211, 177, 62, 217, 47, 131, 219, 233, 61, 217, 47, 131, 219, + 233, 61, 240, 212, 131, 219, 233, 62, 243, 222, 224, 103, 61, 203, 196, + 79, 240, 212, 131, 97, 157, 80, 142, 225, 10, 80, 142, 79, 80, 142, 79, + 212, 120, 207, 174, 245, 234, 217, 31, 131, 219, 233, 79, 212, 120, 245, + 234, 217, 31, 131, 219, 233, 79, 52, 207, 174, 245, 234, 217, 31, 131, + 219, 233, 79, 52, 245, 234, 217, 31, 131, 219, 233, 79, 124, 212, 120, + 245, 234, 217, 31, 131, 219, 233, 79, 124, 52, 245, 234, 217, 31, 131, + 219, 233, 245, 86, 211, 78, 219, 89, 2, 219, 233, 79, 240, 212, 131, 219, + 233, 79, 237, 56, 240, 212, 131, 219, 233, 79, 62, 237, 55, 215, 198, 79, + 62, 237, 56, 247, 177, 239, 201, 237, 55, 215, 198, 239, 201, 237, 56, + 247, 177, 225, 10, 49, 219, 77, 219, 233, 225, 10, 50, 219, 77, 219, 233, + 225, 10, 239, 214, 49, 219, 77, 219, 233, 225, 10, 239, 214, 50, 219, 77, + 219, 233, 225, 10, 227, 217, 250, 218, 247, 227, 219, 233, 225, 10, 216, + 11, 250, 218, 247, 227, 219, 233, 79, 227, 217, 250, 218, 217, 31, 131, + 219, 233, 79, 216, 11, 250, 218, 217, 31, 131, 219, 233, 79, 227, 217, + 250, 218, 247, 227, 219, 233, 79, 216, 11, 250, 218, 247, 227, 219, 233, + 157, 49, 208, 133, 213, 33, 247, 227, 219, 233, 157, 50, 208, 133, 213, + 33, 247, 227, 219, 233, 225, 10, 49, 245, 93, 247, 227, 219, 233, 225, + 10, 50, 245, 93, 247, 227, 219, 233, 243, 174, 182, 43, 17, 105, 243, + 174, 182, 43, 17, 108, 243, 174, 182, 43, 17, 147, 243, 174, 182, 43, 17, + 149, 243, 174, 182, 43, 17, 170, 243, 174, 182, 43, 17, 195, 243, 174, + 182, 43, 17, 213, 111, 243, 174, 182, 43, 17, 199, 243, 174, 182, 43, 17, + 222, 63, 243, 174, 182, 43, 42, 209, 152, 243, 174, 43, 41, 17, 105, 243, + 174, 43, 41, 17, 108, 243, 174, 43, 41, 17, 147, 243, 174, 43, 41, 17, + 149, 243, 174, 43, 41, 17, 170, 243, 174, 43, 41, 17, 195, 243, 174, 43, + 41, 17, 213, 111, 243, 174, 43, 41, 17, 199, 243, 174, 43, 41, 17, 222, + 63, 243, 174, 43, 41, 42, 209, 152, 243, 174, 182, 43, 41, 17, 105, 243, + 174, 182, 43, 41, 17, 108, 243, 174, 182, 43, 41, 17, 147, 243, 174, 182, + 43, 41, 17, 149, 243, 174, 182, 43, 41, 17, 170, 243, 174, 182, 43, 41, + 17, 195, 243, 174, 182, 43, 41, 17, 213, 111, 243, 174, 182, 43, 41, 17, + 199, 243, 174, 182, 43, 41, 17, 222, 63, 243, 174, 182, 43, 41, 42, 209, + 152, 79, 204, 26, 86, 47, 79, 91, 54, 79, 224, 103, 54, 79, 243, 137, 54, + 79, 211, 238, 241, 176, 47, 79, 86, 47, 79, 153, 241, 176, 47, 242, 63, + 218, 63, 86, 47, 79, 215, 190, 86, 47, 208, 84, 86, 47, 79, 208, 84, 86, + 47, 244, 143, 208, 84, 86, 47, 79, 244, 143, 208, 84, 86, 47, 62, 86, 47, + 209, 31, 208, 143, 86, 250, 94, 209, 31, 247, 246, 86, 250, 94, 62, 86, + 250, 94, 79, 62, 245, 86, 183, 25, 86, 47, 79, 62, 245, 86, 177, 25, 86, + 47, 211, 174, 62, 86, 47, 79, 245, 217, 62, 86, 47, 216, 10, 61, 86, 47, + 227, 216, 61, 86, 47, 249, 24, 213, 77, 61, 86, 47, 239, 117, 213, 77, + 61, 86, 47, 79, 226, 251, 216, 9, 61, 86, 47, 79, 206, 221, 216, 9, 61, + 86, 47, 221, 162, 226, 251, 216, 9, 61, 86, 47, 245, 93, 227, 14, 221, + 162, 206, 221, 216, 9, 61, 86, 47, 43, 79, 61, 86, 47, 204, 32, 86, 47, + 248, 42, 211, 238, 241, 176, 47, 248, 42, 86, 47, 248, 42, 153, 241, 176, + 47, 79, 248, 42, 211, 238, 241, 176, 47, 79, 248, 42, 86, 47, 79, 248, + 42, 153, 241, 176, 47, 209, 182, 86, 47, 79, 209, 181, 86, 47, 204, 56, + 86, 47, 79, 204, 56, 86, 47, 220, 3, 86, 47, 52, 245, 93, 227, 14, 126, + 243, 184, 250, 217, 61, 208, 86, 245, 195, 5, 61, 208, 85, 218, 233, 171, + 210, 244, 171, 210, 197, 49, 215, 93, 249, 11, 244, 43, 50, 215, 93, 249, + 11, 244, 43, 219, 245, 3, 70, 231, 6, 216, 74, 212, 1, 217, 248, 210, + 244, 210, 198, 217, 248, 212, 0, 80, 248, 231, 3, 236, 106, 95, 13, 215, + 245, 243, 227, 163, 243, 136, 13, 240, 84, 243, 227, 103, 227, 37, 250, + 226, 103, 227, 37, 219, 244, 61, 243, 222, 3, 246, 216, 243, 85, 25, 3, + 243, 85, 241, 115, 76, 220, 1, 206, 212, 226, 251, 50, 245, 166, 3, 243, + 85, 206, 221, 49, 245, 166, 3, 243, 85, 49, 219, 209, 230, 99, 50, 219, + 209, 230, 99, 239, 102, 219, 209, 230, 99, 228, 8, 112, 210, 3, 228, 8, + 121, 210, 3, 49, 25, 50, 52, 207, 173, 49, 25, 50, 210, 3, 49, 223, 228, + 163, 50, 210, 3, 163, 49, 210, 3, 112, 210, 4, 3, 246, 62, 55, 226, 247, + 243, 142, 247, 137, 236, 106, 215, 135, 61, 245, 216, 243, 221, 61, 245, + 216, 243, 222, 3, 96, 208, 254, 61, 245, 216, 243, 222, 3, 86, 208, 254, + 61, 51, 3, 96, 208, 254, 61, 51, 3, 86, 208, 254, 13, 49, 61, 51, 155, + 13, 50, 61, 51, 155, 13, 49, 250, 218, 155, 13, 50, 250, 218, 155, 13, + 49, 52, 250, 218, 155, 13, 50, 52, 250, 218, 155, 13, 49, 61, 208, 133, + 213, 33, 155, 13, 50, 61, 208, 133, 213, 33, 155, 13, 49, 239, 214, 219, + 76, 13, 50, 239, 214, 219, 76, 177, 217, 58, 47, 183, 217, 58, 47, 250, + 194, 238, 226, 246, 62, 47, 246, 18, 238, 226, 246, 62, 47, 50, 53, 3, + 43, 218, 76, 163, 96, 47, 163, 86, 47, 163, 49, 50, 47, 163, 96, 52, 47, + 163, 86, 52, 47, 163, 49, 50, 52, 47, 163, 96, 53, 239, 120, 142, 163, + 86, 53, 239, 120, 142, 163, 96, 52, 53, 239, 120, 142, 163, 86, 52, 53, + 239, 120, 142, 163, 86, 211, 171, 47, 58, 59, 248, 36, 58, 59, 243, 82, + 58, 59, 242, 210, 58, 59, 243, 81, 58, 59, 242, 146, 58, 59, 243, 17, 58, + 59, 242, 209, 58, 59, 243, 80, 58, 59, 242, 114, 58, 59, 242, 241, 58, + 59, 242, 177, 58, 59, 243, 48, 58, 59, 242, 145, 58, 59, 243, 16, 58, 59, + 242, 208, 58, 59, 243, 79, 58, 59, 242, 98, 58, 59, 242, 225, 58, 59, + 242, 161, 58, 59, 243, 32, 58, 59, 242, 129, 58, 59, 243, 0, 58, 59, 242, + 192, 58, 59, 243, 63, 58, 59, 242, 113, 58, 59, 242, 240, 58, 59, 242, + 176, 58, 59, 243, 47, 58, 59, 242, 144, 58, 59, 243, 15, 58, 59, 242, + 207, 58, 59, 243, 78, 58, 59, 242, 90, 58, 59, 242, 217, 58, 59, 242, + 153, 58, 59, 243, 24, 58, 59, 242, 121, 58, 59, 242, 248, 58, 59, 242, + 184, 58, 59, 243, 55, 58, 59, 242, 105, 58, 59, 242, 232, 58, 59, 242, + 168, 58, 59, 243, 39, 58, 59, 242, 136, 58, 59, 243, 7, 58, 59, 242, 199, + 58, 59, 243, 70, 58, 59, 242, 97, 58, 59, 242, 224, 58, 59, 242, 160, 58, + 59, 243, 31, 58, 59, 242, 128, 58, 59, 242, 255, 58, 59, 242, 191, 58, + 59, 243, 62, 58, 59, 242, 112, 58, 59, 242, 239, 58, 59, 242, 175, 58, + 59, 243, 46, 58, 59, 242, 143, 58, 59, 243, 14, 58, 59, 242, 206, 58, 59, + 243, 77, 58, 59, 242, 86, 58, 59, 242, 213, 58, 59, 242, 149, 58, 59, + 243, 20, 58, 59, 242, 117, 58, 59, 242, 244, 58, 59, 242, 180, 58, 59, + 243, 51, 58, 59, 242, 101, 58, 59, 242, 228, 58, 59, 242, 164, 58, 59, + 243, 35, 58, 59, 242, 132, 58, 59, 243, 3, 58, 59, 242, 195, 58, 59, 243, + 66, 58, 59, 242, 93, 58, 59, 242, 220, 58, 59, 242, 156, 58, 59, 243, 27, + 58, 59, 242, 124, 58, 59, 242, 251, 58, 59, 242, 187, 58, 59, 243, 58, + 58, 59, 242, 108, 58, 59, 242, 235, 58, 59, 242, 171, 58, 59, 243, 42, + 58, 59, 242, 139, 58, 59, 243, 10, 58, 59, 242, 202, 58, 59, 243, 73, 58, + 59, 242, 89, 58, 59, 242, 216, 58, 59, 242, 152, 58, 59, 243, 23, 58, 59, + 242, 120, 58, 59, 242, 247, 58, 59, 242, 183, 58, 59, 243, 54, 58, 59, + 242, 104, 58, 59, 242, 231, 58, 59, 242, 167, 58, 59, 243, 38, 58, 59, + 242, 135, 58, 59, 243, 6, 58, 59, 242, 198, 58, 59, 243, 69, 58, 59, 242, + 96, 58, 59, 242, 223, 58, 59, 242, 159, 58, 59, 243, 30, 58, 59, 242, + 127, 58, 59, 242, 254, 58, 59, 242, 190, 58, 59, 243, 61, 58, 59, 242, + 111, 58, 59, 242, 238, 58, 59, 242, 174, 58, 59, 243, 45, 58, 59, 242, + 142, 58, 59, 243, 13, 58, 59, 242, 205, 58, 59, 243, 76, 58, 59, 242, 84, + 58, 59, 242, 211, 58, 59, 242, 147, 58, 59, 243, 18, 58, 59, 242, 115, + 58, 59, 242, 242, 58, 59, 242, 178, 58, 59, 243, 49, 58, 59, 242, 99, 58, + 59, 242, 226, 58, 59, 242, 162, 58, 59, 243, 33, 58, 59, 242, 130, 58, + 59, 243, 1, 58, 59, 242, 193, 58, 59, 243, 64, 58, 59, 242, 91, 58, 59, + 242, 218, 58, 59, 242, 154, 58, 59, 243, 25, 58, 59, 242, 122, 58, 59, + 242, 249, 58, 59, 242, 185, 58, 59, 243, 56, 58, 59, 242, 106, 58, 59, + 242, 233, 58, 59, 242, 169, 58, 59, 243, 40, 58, 59, 242, 137, 58, 59, + 243, 8, 58, 59, 242, 200, 58, 59, 243, 71, 58, 59, 242, 87, 58, 59, 242, + 214, 58, 59, 242, 150, 58, 59, 243, 21, 58, 59, 242, 118, 58, 59, 242, + 245, 58, 59, 242, 181, 58, 59, 243, 52, 58, 59, 242, 102, 58, 59, 242, + 229, 58, 59, 242, 165, 58, 59, 243, 36, 58, 59, 242, 133, 58, 59, 243, 4, + 58, 59, 242, 196, 58, 59, 243, 67, 58, 59, 242, 94, 58, 59, 242, 221, 58, + 59, 242, 157, 58, 59, 243, 28, 58, 59, 242, 125, 58, 59, 242, 252, 58, + 59, 242, 188, 58, 59, 243, 59, 58, 59, 242, 109, 58, 59, 242, 236, 58, + 59, 242, 172, 58, 59, 243, 43, 58, 59, 242, 140, 58, 59, 243, 11, 58, 59, + 242, 203, 58, 59, 243, 74, 58, 59, 242, 85, 58, 59, 242, 212, 58, 59, + 242, 148, 58, 59, 243, 19, 58, 59, 242, 116, 58, 59, 242, 243, 58, 59, + 242, 179, 58, 59, 243, 50, 58, 59, 242, 100, 58, 59, 242, 227, 58, 59, + 242, 163, 58, 59, 243, 34, 58, 59, 242, 131, 58, 59, 243, 2, 58, 59, 242, + 194, 58, 59, 243, 65, 58, 59, 242, 92, 58, 59, 242, 219, 58, 59, 242, + 155, 58, 59, 243, 26, 58, 59, 242, 123, 58, 59, 242, 250, 58, 59, 242, + 186, 58, 59, 243, 57, 58, 59, 242, 107, 58, 59, 242, 234, 58, 59, 242, + 170, 58, 59, 243, 41, 58, 59, 242, 138, 58, 59, 243, 9, 58, 59, 242, 201, + 58, 59, 243, 72, 58, 59, 242, 88, 58, 59, 242, 215, 58, 59, 242, 151, 58, + 59, 243, 22, 58, 59, 242, 119, 58, 59, 242, 246, 58, 59, 242, 182, 58, + 59, 243, 53, 58, 59, 242, 103, 58, 59, 242, 230, 58, 59, 242, 166, 58, + 59, 243, 37, 58, 59, 242, 134, 58, 59, 243, 5, 58, 59, 242, 197, 58, 59, + 243, 68, 58, 59, 242, 95, 58, 59, 242, 222, 58, 59, 242, 158, 58, 59, + 243, 29, 58, 59, 242, 126, 58, 59, 242, 253, 58, 59, 242, 189, 58, 59, + 243, 60, 58, 59, 242, 110, 58, 59, 242, 237, 58, 59, 242, 173, 58, 59, + 243, 44, 58, 59, 242, 141, 58, 59, 243, 12, 58, 59, 242, 204, 58, 59, + 243, 75, 86, 207, 134, 53, 3, 80, 95, 86, 207, 134, 53, 3, 52, 80, 95, + 96, 52, 53, 3, 80, 95, 86, 52, 53, 3, 80, 95, 49, 50, 52, 53, 3, 80, 95, + 86, 207, 134, 53, 239, 120, 142, 96, 52, 53, 239, 120, 142, 86, 52, 53, + 239, 120, 142, 183, 53, 3, 236, 106, 95, 177, 53, 3, 236, 106, 95, 177, + 208, 70, 47, 183, 208, 70, 47, 96, 52, 244, 145, 47, 86, 52, 244, 145, + 47, 96, 208, 70, 244, 145, 47, 86, 208, 70, 244, 145, 47, 86, 207, 134, + 208, 70, 244, 145, 47, 86, 53, 3, 242, 83, 211, 77, 177, 53, 208, 173, + 142, 183, 53, 208, 173, 142, 86, 53, 3, 209, 249, 3, 80, 95, 86, 53, 3, + 209, 249, 3, 52, 80, 95, 86, 207, 134, 53, 3, 209, 248, 86, 207, 134, 53, + 3, 209, 249, 3, 80, 95, 86, 207, 134, 53, 3, 209, 249, 3, 52, 80, 95, 96, + 250, 96, 86, 250, 96, 96, 52, 250, 96, 86, 52, 250, 96, 96, 53, 208, 173, + 62, 243, 221, 86, 53, 208, 173, 62, 243, 221, 96, 53, 239, 120, 248, 231, + 208, 173, 62, 243, 221, 86, 53, 239, 120, 248, 231, 208, 173, 62, 243, + 221, 153, 204, 46, 25, 211, 238, 241, 176, 47, 153, 241, 176, 25, 211, + 238, 204, 46, 47, 153, 204, 46, 53, 3, 113, 153, 241, 176, 53, 3, 113, + 211, 238, 241, 176, 53, 3, 113, 211, 238, 204, 46, 53, 3, 113, 153, 204, + 46, 53, 25, 153, 241, 176, 47, 153, 241, 176, 53, 25, 211, 238, 241, 176, + 47, 211, 238, 241, 176, 53, 25, 211, 238, 204, 46, 47, 211, 238, 204, 46, + 53, 25, 153, 204, 46, 47, 215, 245, 243, 228, 245, 124, 240, 84, 243, + 227, 240, 84, 243, 228, 245, 124, 215, 245, 243, 227, 211, 238, 241, 176, + 53, 245, 124, 153, 241, 176, 47, 153, 241, 176, 53, 245, 124, 211, 238, + 241, 176, 47, 240, 84, 243, 228, 245, 124, 153, 241, 176, 47, 215, 245, + 243, 228, 245, 124, 211, 238, 241, 176, 47, 153, 241, 176, 53, 245, 124, + 153, 204, 46, 47, 153, 204, 46, 53, 245, 124, 153, 241, 176, 47, 204, 76, + 53, 218, 59, 243, 164, 216, 16, 53, 218, 59, 86, 209, 84, 245, 84, 206, + 212, 53, 218, 59, 86, 209, 84, 245, 84, 242, 68, 53, 218, 59, 183, 209, + 84, 245, 84, 227, 212, 53, 218, 59, 183, 209, 84, 245, 84, 216, 5, 216, + 8, 250, 129, 246, 18, 47, 227, 215, 250, 129, 250, 194, 47, 208, 145, + 250, 129, 250, 194, 47, 247, 248, 250, 129, 250, 194, 47, 208, 145, 250, + 129, 246, 18, 53, 3, 224, 102, 208, 145, 250, 129, 250, 194, 53, 3, 218, + 76, 226, 251, 50, 213, 145, 246, 18, 47, 226, 251, 49, 213, 145, 250, + 194, 47, 250, 194, 246, 16, 246, 62, 47, 246, 18, 246, 16, 246, 62, 47, + 86, 53, 87, 212, 228, 96, 47, 96, 53, 87, 212, 228, 86, 47, 212, 228, 86, + 53, 87, 96, 47, 86, 53, 3, 91, 56, 96, 53, 3, 91, 56, 86, 53, 209, 25, + 203, 196, 49, 50, 53, 209, 25, 5, 246, 61, 177, 207, 134, 53, 239, 120, + 5, 246, 61, 49, 150, 112, 50, 150, 121, 237, 86, 49, 150, 121, 50, 150, + 112, 237, 86, 112, 150, 50, 121, 150, 49, 237, 86, 112, 150, 49, 121, + 150, 50, 237, 86, 49, 150, 112, 50, 150, 112, 237, 86, 112, 150, 50, 121, + 150, 50, 237, 86, 49, 150, 121, 50, 150, 121, 237, 86, 112, 150, 49, 121, + 150, 49, 237, 86, 96, 237, 87, 3, 150, 112, 208, 173, 142, 86, 237, 87, + 3, 150, 112, 208, 173, 142, 177, 237, 87, 3, 150, 50, 208, 173, 142, 183, + 237, 87, 3, 150, 50, 208, 173, 142, 96, 237, 87, 3, 150, 121, 208, 173, + 142, 86, 237, 87, 3, 150, 121, 208, 173, 142, 177, 237, 87, 3, 150, 49, + 208, 173, 142, 183, 237, 87, 3, 150, 49, 208, 173, 142, 96, 237, 87, 3, + 150, 112, 239, 120, 142, 86, 237, 87, 3, 150, 112, 239, 120, 142, 177, + 237, 87, 3, 150, 50, 239, 120, 142, 183, 237, 87, 3, 150, 50, 239, 120, + 142, 96, 237, 87, 3, 150, 121, 239, 120, 142, 86, 237, 87, 3, 150, 121, + 239, 120, 142, 177, 237, 87, 3, 150, 49, 239, 120, 142, 183, 237, 87, 3, + 150, 49, 239, 120, 142, 96, 237, 87, 3, 150, 112, 87, 96, 237, 87, 3, + 150, 242, 70, 177, 237, 87, 3, 150, 49, 248, 110, 177, 237, 87, 3, 150, + 216, 16, 86, 237, 87, 3, 150, 112, 87, 86, 237, 87, 3, 150, 242, 70, 183, + 237, 87, 3, 150, 49, 248, 110, 183, 237, 87, 3, 150, 216, 16, 96, 237, + 87, 3, 150, 112, 87, 86, 237, 87, 3, 150, 206, 224, 96, 237, 87, 3, 150, + 121, 87, 86, 237, 87, 3, 150, 242, 70, 86, 237, 87, 3, 150, 112, 87, 96, + 237, 87, 3, 150, 206, 224, 86, 237, 87, 3, 150, 121, 87, 96, 237, 87, 3, + 150, 242, 70, 96, 237, 87, 3, 150, 112, 87, 163, 244, 144, 96, 237, 87, + 3, 150, 121, 248, 126, 163, 244, 144, 86, 237, 87, 3, 150, 112, 87, 163, + 244, 144, 86, 237, 87, 3, 150, 121, 248, 126, 163, 244, 144, 177, 237, + 87, 3, 150, 49, 248, 110, 183, 237, 87, 3, 150, 216, 16, 183, 237, 87, 3, + 150, 49, 248, 110, 177, 237, 87, 3, 150, 216, 16, 50, 52, 53, 3, 215, + 189, 237, 64, 241, 35, 2, 87, 86, 47, 208, 228, 219, 255, 87, 86, 47, 96, + 53, 87, 208, 228, 219, 254, 86, 53, 87, 208, 228, 219, 254, 86, 53, 87, + 251, 7, 156, 135, 227, 179, 87, 96, 47, 96, 53, 209, 25, 227, 178, 237, + 247, 87, 86, 47, 210, 245, 87, 86, 47, 96, 53, 209, 25, 210, 244, 210, + 198, 87, 96, 47, 49, 239, 244, 209, 248, 50, 239, 244, 209, 248, 112, + 239, 244, 209, 248, 121, 239, 244, 209, 248, 208, 70, 80, 248, 231, 244, + 43, 202, 160, 221, 164, 211, 188, 202, 160, 221, 164, 207, 121, 245, 242, + 49, 61, 245, 93, 155, 50, 61, 245, 93, 155, 49, 61, 219, 76, 50, 61, 219, + 76, 202, 160, 221, 164, 49, 231, 65, 155, 202, 160, 221, 164, 50, 231, + 65, 155, 202, 160, 221, 164, 49, 248, 65, 155, 202, 160, 221, 164, 50, + 248, 65, 155, 49, 51, 247, 227, 3, 206, 246, 50, 51, 247, 227, 3, 206, + 246, 49, 51, 247, 227, 3, 208, 255, 231, 50, 208, 145, 245, 165, 50, 51, + 247, 227, 3, 208, 255, 231, 50, 247, 248, 245, 165, 49, 51, 247, 227, 3, + 208, 255, 231, 50, 247, 248, 245, 165, 50, 51, 247, 227, 3, 208, 255, + 231, 50, 208, 145, 245, 165, 49, 250, 218, 247, 227, 3, 243, 85, 50, 250, + 218, 247, 227, 3, 243, 85, 49, 250, 129, 227, 179, 155, 50, 250, 129, + 237, 247, 155, 52, 49, 250, 129, 237, 247, 155, 52, 50, 250, 129, 227, + 179, 155, 49, 62, 208, 133, 213, 33, 155, 50, 62, 208, 133, 213, 33, 155, + 242, 83, 240, 40, 80, 202, 30, 227, 114, 225, 17, 250, 218, 220, 1, 227, + 222, 50, 250, 218, 206, 69, 3, 211, 177, 225, 17, 50, 250, 218, 3, 243, + 85, 250, 218, 3, 215, 94, 231, 6, 251, 126, 250, 217, 211, 208, 250, 218, + 220, 1, 227, 222, 211, 208, 250, 218, 220, 1, 206, 224, 207, 174, 250, + 217, 216, 73, 250, 217, 250, 218, 3, 206, 246, 216, 73, 250, 218, 3, 206, + 246, 220, 89, 250, 218, 220, 1, 206, 224, 220, 89, 250, 218, 220, 1, 242, + 70, 225, 17, 250, 218, 3, 171, 250, 107, 241, 81, 231, 50, 53, 218, 59, + 112, 25, 216, 16, 225, 17, 250, 218, 3, 171, 250, 107, 241, 81, 231, 50, + 53, 218, 59, 112, 25, 227, 222, 225, 17, 250, 218, 3, 171, 250, 107, 241, + 81, 231, 50, 53, 218, 59, 121, 25, 216, 16, 225, 17, 250, 218, 3, 171, + 250, 107, 241, 81, 231, 50, 53, 218, 59, 121, 25, 227, 222, 225, 17, 250, + 218, 3, 171, 250, 107, 241, 81, 231, 50, 53, 218, 59, 50, 25, 206, 224, + 225, 17, 250, 218, 3, 171, 250, 107, 241, 81, 231, 50, 53, 218, 59, 49, + 25, 206, 224, 225, 17, 250, 218, 3, 171, 250, 107, 241, 81, 231, 50, 53, + 218, 59, 50, 25, 242, 70, 225, 17, 250, 218, 3, 171, 250, 107, 241, 81, + 231, 50, 53, 218, 59, 49, 25, 242, 70, 216, 73, 241, 94, 213, 117, 241, + 94, 213, 118, 3, 219, 203, 241, 94, 213, 118, 3, 5, 246, 62, 55, 241, 94, + 213, 118, 3, 50, 53, 55, 241, 94, 213, 118, 3, 49, 53, 55, 246, 62, 3, + 236, 106, 142, 43, 80, 142, 43, 219, 81, 43, 216, 74, 212, 0, 43, 218, + 233, 246, 62, 243, 142, 247, 137, 236, 106, 248, 231, 25, 208, 145, 162, + 243, 142, 247, 137, 80, 142, 246, 62, 3, 210, 200, 203, 196, 43, 250, + 192, 243, 137, 54, 112, 53, 209, 25, 246, 61, 43, 61, 247, 177, 43, 247, + 177, 43, 227, 178, 43, 237, 246, 246, 62, 3, 5, 246, 62, 208, 173, 209, + 93, 216, 16, 246, 62, 3, 120, 236, 106, 211, 20, 208, 173, 209, 93, 216, + 16, 103, 215, 245, 243, 228, 212, 57, 103, 240, 84, 243, 228, 212, 57, + 103, 250, 59, 103, 5, 246, 61, 103, 211, 177, 120, 230, 98, 211, 175, + 208, 86, 3, 70, 55, 208, 86, 3, 206, 246, 215, 94, 231, 50, 208, 85, 208, + 86, 3, 213, 124, 250, 50, 247, 247, 50, 208, 86, 87, 49, 208, 85, 49, + 208, 86, 248, 110, 80, 142, 80, 248, 231, 248, 110, 50, 208, 85, 247, + 235, 3, 49, 162, 248, 43, 247, 235, 3, 50, 162, 248, 43, 62, 247, 234, + 23, 3, 49, 162, 248, 43, 23, 3, 50, 162, 248, 43, 61, 236, 40, 62, 236, + 40, 49, 204, 21, 240, 40, 50, 204, 21, 240, 40, 49, 52, 204, 21, 240, 40, + 50, 52, 204, 21, 240, 40, 231, 42, 231, 27, 208, 251, 115, 231, 27, 231, + 28, 222, 234, 3, 80, 142, 242, 77, 223, 228, 51, 3, 245, 187, 219, 208, + 231, 39, 250, 81, 212, 193, 217, 224, 241, 35, 2, 25, 212, 59, 219, 81, + 241, 35, 2, 25, 212, 59, 219, 82, 3, 208, 228, 55, 235, 154, 208, 173, + 25, 212, 59, 219, 81, 238, 48, 211, 93, 209, 81, 242, 69, 208, 86, 3, 49, + 162, 248, 43, 242, 69, 208, 86, 3, 50, 162, 248, 43, 62, 243, 222, 3, + 121, 47, 62, 226, 246, 61, 246, 62, 3, 121, 47, 62, 246, 62, 3, 121, 47, + 241, 20, 61, 211, 177, 241, 20, 62, 211, 177, 241, 20, 61, 243, 221, 241, + 20, 62, 243, 221, 241, 20, 61, 246, 61, 241, 20, 62, 246, 61, 215, 134, + 216, 74, 212, 1, 219, 254, 212, 1, 3, 219, 203, 216, 74, 212, 1, 3, 236, + 106, 95, 248, 73, 212, 0, 248, 73, 216, 74, 212, 0, 52, 218, 76, 208, 70, + 218, 76, 227, 217, 245, 86, 250, 218, 155, 216, 11, 245, 86, 250, 218, + 155, 208, 212, 224, 100, 223, 162, 43, 70, 219, 254, 223, 162, 43, 91, + 219, 254, 223, 162, 43, 23, 219, 254, 223, 162, 206, 238, 219, 255, 3, + 243, 85, 223, 162, 206, 238, 219, 255, 3, 218, 76, 223, 162, 51, 230, + 245, 219, 254, 223, 162, 51, 206, 238, 219, 254, 120, 227, 37, 25, 219, + 254, 120, 227, 37, 219, 245, 219, 254, 223, 162, 23, 219, 254, 224, 58, + 120, 210, 220, 210, 218, 3, 231, 2, 217, 58, 231, 3, 219, 254, 239, 252, + 219, 71, 231, 2, 231, 3, 3, 52, 95, 231, 3, 250, 15, 3, 212, 57, 246, 54, + 239, 99, 250, 194, 231, 0, 227, 115, 231, 1, 3, 216, 142, 219, 52, 250, + 104, 218, 53, 227, 115, 231, 1, 3, 213, 145, 219, 52, 250, 104, 218, 53, + 227, 115, 231, 1, 221, 166, 231, 44, 209, 93, 218, 53, 231, 3, 250, 104, + 34, 218, 63, 219, 254, 217, 52, 231, 3, 219, 254, 231, 3, 3, 96, 53, 3, + 113, 231, 3, 3, 23, 54, 231, 3, 3, 230, 244, 231, 3, 3, 206, 237, 231, 3, + 3, 219, 203, 231, 3, 3, 206, 246, 230, 99, 228, 8, 49, 208, 86, 219, 254, + 202, 160, 221, 164, 214, 198, 245, 223, 202, 160, 221, 164, 214, 198, + 218, 114, 202, 160, 221, 164, 214, 198, 217, 219, 91, 2, 3, 5, 246, 62, + 55, 91, 2, 3, 246, 53, 251, 139, 55, 91, 2, 3, 208, 228, 55, 91, 2, 3, + 70, 56, 91, 2, 3, 208, 228, 56, 91, 2, 3, 210, 246, 108, 91, 2, 3, 62, + 208, 85, 224, 103, 2, 3, 245, 234, 55, 224, 103, 2, 3, 70, 56, 224, 103, + 2, 3, 240, 84, 243, 83, 224, 103, 2, 3, 215, 245, 243, 83, 91, 2, 231, + 50, 49, 162, 246, 61, 91, 2, 231, 50, 50, 162, 246, 61, 206, 54, 219, + 245, 245, 131, 217, 224, 223, 224, 2, 3, 70, 55, 223, 224, 2, 3, 206, + 246, 213, 142, 217, 225, 3, 247, 248, 246, 15, 212, 34, 217, 224, 223, + 224, 2, 231, 50, 49, 162, 246, 61, 223, 224, 2, 231, 50, 50, 162, 246, + 61, 43, 223, 224, 2, 3, 246, 53, 251, 138, 223, 224, 2, 231, 50, 52, 246, + 61, 43, 243, 137, 54, 91, 2, 231, 50, 208, 85, 224, 103, 2, 231, 50, 208, + 85, 223, 224, 2, 231, 50, 208, 85, 230, 253, 217, 224, 216, 6, 230, 253, + 217, 224, 202, 160, 221, 164, 216, 116, 245, 223, 250, 245, 219, 245, + 245, 171, 230, 245, 3, 243, 85, 206, 238, 3, 224, 103, 54, 206, 238, 3, + 219, 203, 230, 245, 3, 219, 203, 230, 245, 3, 227, 37, 250, 226, 206, + 238, 3, 227, 37, 219, 244, 206, 238, 87, 230, 244, 230, 245, 87, 206, + 237, 206, 238, 87, 248, 231, 87, 230, 244, 230, 245, 87, 248, 231, 87, + 206, 237, 206, 238, 248, 110, 25, 230, 98, 3, 206, 237, 230, 245, 248, + 110, 25, 230, 98, 3, 230, 244, 246, 16, 206, 238, 3, 213, 123, 246, 16, + 230, 245, 3, 213, 123, 52, 51, 230, 244, 52, 51, 206, 237, 246, 16, 206, + 238, 3, 213, 124, 25, 212, 34, 217, 224, 227, 37, 25, 3, 70, 55, 227, 37, + 219, 245, 3, 70, 55, 52, 227, 37, 250, 226, 52, 227, 37, 219, 244, 120, + 230, 246, 227, 37, 250, 226, 120, 230, 246, 227, 37, 219, 244, 212, 43, + 228, 8, 219, 244, 212, 43, 228, 8, 250, 226, 227, 37, 219, 245, 219, 200, + 227, 37, 250, 226, 227, 37, 25, 3, 101, 211, 77, 227, 37, 219, 245, 3, + 101, 211, 77, 227, 37, 25, 3, 236, 106, 244, 144, 227, 37, 219, 245, 3, + 236, 106, 244, 144, 227, 37, 25, 3, 52, 219, 203, 227, 37, 25, 3, 206, + 246, 227, 37, 25, 3, 52, 206, 246, 5, 206, 51, 3, 206, 246, 227, 37, 219, + 245, 3, 52, 219, 203, 227, 37, 219, 245, 3, 52, 206, 246, 202, 160, 221, + 164, 243, 94, 250, 184, 202, 160, 221, 164, 216, 179, 250, 184, 241, 35, + 2, 3, 70, 56, 235, 154, 3, 70, 55, 208, 70, 236, 106, 248, 231, 3, 52, + 80, 95, 208, 70, 236, 106, 248, 231, 3, 208, 70, 80, 95, 208, 228, 219, + 255, 3, 70, 55, 208, 228, 219, 255, 3, 215, 245, 243, 83, 212, 129, 224, + 103, 212, 128, 245, 210, 3, 70, 55, 241, 35, 3, 250, 59, 251, 7, 156, + 208, 173, 3, 246, 53, 251, 138, 250, 151, 156, 219, 245, 156, 135, 241, + 35, 2, 87, 91, 54, 91, 2, 87, 241, 35, 54, 241, 35, 2, 87, 208, 228, 219, + 254, 52, 245, 243, 241, 36, 120, 245, 203, 241, 35, 212, 143, 126, 245, + 203, 241, 35, 212, 143, 241, 35, 2, 3, 120, 187, 87, 25, 120, 187, 56, + 241, 30, 3, 239, 147, 187, 55, 227, 179, 3, 246, 62, 231, 6, 237, 247, 3, + 246, 62, 231, 6, 227, 179, 3, 217, 47, 131, 55, 237, 247, 3, 217, 47, + 131, 55, 227, 179, 219, 245, 212, 59, 156, 135, 237, 247, 219, 245, 212, + 59, 156, 135, 227, 179, 219, 245, 212, 59, 156, 208, 173, 3, 70, 231, 6, + 237, 247, 219, 245, 212, 59, 156, 208, 173, 3, 70, 231, 6, 227, 179, 219, + 245, 212, 59, 156, 208, 173, 3, 70, 55, 237, 247, 219, 245, 212, 59, 156, + 208, 173, 3, 70, 55, 227, 179, 219, 245, 212, 59, 156, 208, 173, 3, 70, + 87, 216, 16, 237, 247, 219, 245, 212, 59, 156, 208, 173, 3, 70, 87, 227, + 222, 227, 179, 219, 245, 250, 152, 237, 247, 219, 245, 250, 152, 227, + 179, 25, 212, 118, 221, 166, 156, 135, 237, 247, 25, 212, 118, 221, 166, + 156, 135, 227, 179, 25, 221, 166, 250, 152, 237, 247, 25, 221, 166, 250, + 152, 227, 179, 87, 242, 76, 156, 87, 237, 246, 237, 247, 87, 242, 76, + 156, 87, 227, 178, 227, 179, 87, 212, 129, 219, 245, 241, 36, 237, 247, + 87, 212, 129, 219, 245, 241, 36, 227, 179, 87, 212, 129, 87, 237, 246, + 237, 247, 87, 212, 129, 87, 227, 178, 227, 179, 87, 237, 247, 87, 242, + 76, 241, 36, 237, 247, 87, 227, 179, 87, 242, 76, 241, 36, 227, 179, 87, + 212, 59, 156, 87, 237, 247, 87, 212, 59, 241, 36, 237, 247, 87, 212, 59, + 156, 87, 227, 179, 87, 212, 59, 241, 36, 212, 59, 156, 208, 173, 219, + 245, 227, 178, 212, 59, 156, 208, 173, 219, 245, 237, 246, 212, 59, 156, + 208, 173, 219, 245, 227, 179, 3, 70, 231, 6, 212, 59, 156, 208, 173, 219, + 245, 237, 247, 3, 70, 231, 6, 242, 76, 156, 208, 173, 219, 245, 227, 178, + 242, 76, 156, 208, 173, 219, 245, 237, 246, 242, 76, 212, 59, 156, 208, + 173, 219, 245, 227, 178, 242, 76, 212, 59, 156, 208, 173, 219, 245, 237, + 246, 212, 129, 219, 245, 227, 178, 212, 129, 219, 245, 237, 246, 212, + 129, 87, 227, 179, 87, 241, 35, 54, 212, 129, 87, 237, 247, 87, 241, 35, + 54, 52, 222, 221, 227, 178, 52, 222, 221, 237, 246, 52, 222, 221, 227, + 179, 3, 206, 246, 237, 247, 219, 200, 227, 178, 237, 247, 248, 110, 227, + 178, 227, 179, 246, 16, 247, 137, 245, 87, 237, 247, 246, 16, 247, 137, + 245, 87, 227, 179, 246, 16, 247, 137, 245, 88, 87, 212, 59, 241, 36, 237, + 247, 246, 16, 247, 137, 245, 88, 87, 212, 59, 241, 36, 212, 35, 209, 97, + 228, 6, 209, 97, 212, 35, 209, 98, 219, 245, 156, 135, 228, 6, 209, 98, + 219, 245, 156, 135, 241, 35, 2, 3, 247, 170, 55, 217, 250, 87, 212, 118, + 241, 35, 54, 210, 237, 87, 212, 118, 241, 35, 54, 217, 250, 87, 212, 118, + 221, 166, 156, 135, 210, 237, 87, 212, 118, 221, 166, 156, 135, 217, 250, + 87, 241, 35, 54, 210, 237, 87, 241, 35, 54, 217, 250, 87, 221, 166, 156, + 135, 210, 237, 87, 221, 166, 156, 135, 217, 250, 87, 251, 7, 156, 135, + 210, 237, 87, 251, 7, 156, 135, 217, 250, 87, 221, 166, 251, 7, 156, 135, + 210, 237, 87, 221, 166, 251, 7, 156, 135, 52, 217, 249, 52, 210, 236, + 210, 245, 3, 243, 85, 210, 198, 3, 243, 85, 210, 245, 3, 91, 2, 56, 210, + 198, 3, 91, 2, 56, 210, 245, 3, 223, 224, 2, 56, 210, 198, 3, 223, 224, + 2, 56, 210, 245, 76, 219, 245, 156, 208, 173, 3, 70, 55, 210, 198, 76, + 219, 245, 156, 208, 173, 3, 70, 55, 210, 245, 76, 87, 241, 35, 54, 210, + 198, 76, 87, 241, 35, 54, 210, 245, 76, 87, 208, 228, 219, 254, 210, 198, + 76, 87, 208, 228, 219, 254, 210, 245, 76, 87, 251, 7, 156, 135, 210, 198, + 76, 87, 251, 7, 156, 135, 210, 245, 76, 87, 221, 166, 156, 135, 210, 198, + 76, 87, 221, 166, 156, 135, 51, 49, 171, 98, 219, 254, 51, 50, 171, 98, + 219, 254, 246, 16, 210, 244, 246, 16, 210, 197, 246, 16, 210, 245, 219, + 245, 156, 135, 246, 16, 210, 198, 219, 245, 156, 135, 210, 245, 87, 210, + 197, 210, 198, 87, 210, 244, 210, 245, 87, 210, 244, 210, 198, 87, 210, + 197, 210, 198, 248, 110, 210, 244, 210, 198, 248, 110, 25, 230, 98, 247, + 137, 244, 145, 3, 210, 244, 241, 115, 76, 220, 1, 242, 68, 218, 104, 3, + 209, 177, 208, 144, 208, 102, 230, 244, 239, 160, 221, 181, 212, 228, 49, + 210, 3, 212, 228, 121, 210, 3, 212, 228, 112, 210, 3, 218, 234, 3, 194, + 80, 248, 231, 208, 70, 50, 207, 173, 52, 80, 248, 231, 49, 207, 173, 80, + 248, 231, 52, 49, 207, 173, 52, 80, 248, 231, 52, 49, 207, 173, 163, 244, + 145, 239, 120, 49, 224, 245, 76, 52, 206, 38, 212, 228, 121, 210, 4, 3, + 219, 203, 212, 228, 112, 210, 4, 3, 206, 246, 212, 228, 112, 210, 4, 87, + 212, 228, 121, 210, 3, 52, 121, 210, 3, 52, 112, 210, 3, 52, 211, 32, + 221, 166, 54, 216, 73, 52, 211, 32, 221, 166, 54, 243, 104, 221, 166, + 243, 144, 3, 216, 73, 222, 233, 212, 57, 80, 227, 115, 3, 246, 62, 55, + 80, 227, 115, 3, 246, 62, 56, 121, 210, 4, 3, 246, 62, 56, 219, 82, 3, + 236, 106, 95, 219, 82, 3, 208, 228, 219, 254, 208, 70, 80, 248, 231, 248, + 67, 216, 117, 208, 70, 80, 248, 231, 3, 236, 106, 95, 208, 70, 245, 243, + 219, 254, 208, 70, 222, 221, 227, 178, 208, 70, 222, 221, 237, 246, 242, + 76, 212, 59, 227, 179, 219, 245, 156, 135, 242, 76, 212, 59, 237, 247, + 219, 245, 156, 135, 208, 70, 212, 1, 248, 67, 216, 117, 228, 8, 208, 70, + 80, 248, 231, 219, 254, 52, 212, 1, 219, 254, 61, 80, 142, 223, 162, 61, + 80, 142, 153, 241, 176, 61, 47, 153, 204, 46, 61, 47, 211, 238, 241, 176, + 61, 47, 211, 238, 204, 46, 61, 47, 49, 50, 61, 47, 96, 62, 47, 177, 62, + 47, 183, 62, 47, 153, 241, 176, 62, 47, 153, 204, 46, 62, 47, 211, 238, + 241, 176, 62, 47, 211, 238, 204, 46, 62, 47, 49, 50, 62, 47, 112, 121, + 62, 47, 86, 53, 3, 208, 211, 242, 68, 86, 53, 3, 208, 211, 206, 212, 96, + 53, 3, 208, 211, 242, 68, 96, 53, 3, 208, 211, 206, 212, 51, 3, 208, 145, + 162, 248, 43, 51, 3, 247, 248, 162, 248, 43, 51, 3, 206, 221, 50, 243, + 228, 162, 248, 43, 51, 3, 226, 251, 49, 243, 228, 162, 248, 43, 243, 222, + 3, 49, 162, 248, 43, 243, 222, 3, 50, 162, 248, 43, 243, 222, 3, 208, + 145, 162, 248, 43, 243, 222, 3, 247, 248, 162, 248, 43, 242, 83, 211, + 177, 62, 228, 8, 211, 177, 61, 228, 8, 211, 177, 62, 205, 242, 5, 211, + 177, 61, 205, 242, 5, 211, 177, 62, 218, 255, 61, 218, 255, 61, 237, 17, + 62, 237, 17, 236, 106, 62, 237, 17, 62, 228, 8, 246, 61, 62, 225, 10, + 243, 221, 61, 225, 10, 243, 221, 62, 225, 10, 226, 246, 61, 225, 10, 226, + 246, 62, 5, 243, 221, 62, 5, 226, 246, 61, 5, 226, 246, 62, 236, 106, + 241, 109, 61, 236, 106, 241, 109, 62, 80, 241, 109, 61, 80, 241, 109, 49, + 53, 3, 5, 246, 61, 126, 96, 250, 91, 49, 53, 3, 43, 218, 76, 163, 96, + 211, 171, 47, 96, 207, 134, 53, 3, 80, 95, 96, 207, 134, 53, 3, 52, 80, + 95, 96, 207, 134, 53, 239, 120, 142, 96, 207, 134, 208, 70, 244, 145, 47, + 96, 53, 3, 242, 83, 211, 77, 96, 53, 3, 209, 249, 3, 80, 95, 96, 53, 3, + 209, 249, 3, 52, 80, 95, 96, 207, 134, 53, 3, 209, 248, 96, 207, 134, 53, + 3, 209, 249, 3, 80, 95, 96, 207, 134, 53, 3, 209, 249, 3, 52, 80, 95, 96, + 53, 209, 25, 203, 196, 204, 76, 53, 218, 59, 243, 164, 227, 222, 241, 35, + 2, 87, 96, 47, 216, 74, 208, 228, 219, 255, 87, 96, 47, 96, 53, 87, 216, + 74, 251, 7, 156, 135, 86, 53, 209, 25, 237, 246, 86, 53, 209, 25, 210, + 197, 96, 217, 58, 47, 86, 217, 58, 47, 216, 74, 208, 228, 219, 255, 87, + 86, 47, 86, 53, 87, 216, 74, 251, 7, 156, 135, 208, 228, 219, 255, 87, + 96, 47, 96, 53, 87, 251, 7, 156, 135, 96, 53, 87, 216, 74, 208, 228, 219, + 254, 86, 53, 87, 216, 74, 208, 228, 219, 254, 183, 208, 84, 202, 30, 47, + 212, 228, 212, 59, 153, 47, 212, 228, 249, 22, 211, 238, 47, 61, 225, 10, + 211, 94, 62, 5, 211, 94, 61, 5, 211, 94, 62, 216, 11, 218, 255, 61, 216, + 11, 218, 255, 79, 228, 8, 246, 61, 79, 219, 205, 3, 219, 205, 231, 6, 79, + 246, 62, 3, 246, 62, 231, 6, 79, 246, 61, 79, 43, 214, 254, 212, 59, 153, + 53, 3, 236, 115, 237, 64, 249, 22, 211, 238, 53, 3, 236, 115, 209, 248, + 212, 59, 153, 53, 3, 236, 106, 209, 248, 249, 22, 211, 238, 53, 3, 236, + 106, 209, 248, 248, 118, 53, 218, 59, 183, 209, 84, 153, 241, 175, 212, + 228, 248, 118, 53, 218, 59, 183, 209, 84, 153, 241, 175, 96, 208, 84, 47, + 177, 208, 84, 47, 86, 208, 84, 47, 183, 208, 84, 47, 49, 50, 208, 84, 47, + 112, 121, 208, 84, 47, 153, 204, 46, 208, 84, 47, 153, 241, 176, 208, 84, + 47, 211, 238, 241, 176, 208, 84, 47, 211, 238, 204, 46, 208, 84, 47, 96, + 208, 84, 244, 143, 47, 177, 208, 84, 244, 143, 47, 86, 208, 84, 244, 143, + 47, 183, 208, 84, 244, 143, 47, 246, 18, 208, 84, 171, 246, 62, 47, 250, + 194, 208, 84, 171, 246, 62, 47, 96, 208, 84, 53, 208, 173, 142, 177, 208, + 84, 53, 208, 173, 142, 86, 208, 84, 53, 208, 173, 142, 183, 208, 84, 53, + 208, 173, 142, 153, 204, 46, 208, 84, 53, 208, 173, 142, 153, 241, 176, + 208, 84, 53, 208, 173, 142, 211, 238, 241, 176, 208, 84, 53, 208, 173, + 142, 211, 238, 204, 46, 208, 84, 53, 208, 173, 142, 96, 208, 84, 53, 3, + 52, 236, 106, 95, 177, 208, 84, 53, 3, 52, 236, 106, 95, 86, 208, 84, 53, + 3, 52, 236, 106, 95, 183, 208, 84, 53, 3, 52, 236, 106, 95, 236, 106, + 210, 11, 229, 151, 80, 210, 11, 229, 151, 96, 208, 84, 53, 115, 86, 208, + 84, 47, 177, 208, 84, 53, 96, 76, 183, 208, 84, 47, 86, 208, 84, 53, 115, + 96, 208, 84, 47, 183, 208, 84, 53, 96, 76, 177, 208, 84, 47, 96, 208, 84, + 219, 146, 250, 91, 177, 208, 84, 219, 146, 250, 91, 86, 208, 84, 219, + 146, 250, 91, 183, 208, 84, 219, 146, 250, 91, 96, 62, 43, 61, 47, 177, + 62, 43, 61, 47, 86, 62, 43, 61, 47, 183, 62, 43, 61, 47, 250, 194, 208, + 84, 50, 207, 92, 47, 250, 194, 208, 84, 247, 248, 207, 92, 47, 250, 194, + 208, 84, 49, 207, 92, 47, 250, 194, 208, 84, 208, 145, 207, 92, 47, 216, + 78, 227, 222, 216, 78, 216, 16, 222, 212, 227, 222, 222, 212, 216, 16, + 239, 147, 245, 166, 250, 92, 246, 57, 250, 193, 86, 62, 47, 209, 31, 208, + 143, 96, 241, 31, 250, 94, 209, 31, 216, 12, 177, 241, 31, 250, 94, 209, + 31, 208, 143, 86, 241, 31, 250, 94, 209, 31, 227, 218, 183, 241, 31, 250, + 94, 62, 96, 241, 31, 250, 94, 62, 177, 241, 31, 250, 94, 62, 86, 241, 31, + 250, 94, 62, 183, 241, 31, 250, 94, 183, 208, 84, 53, 3, 163, 208, 211, + 227, 212, 183, 208, 84, 53, 3, 163, 208, 211, 216, 5, 177, 208, 84, 53, + 3, 163, 208, 211, 227, 212, 177, 208, 84, 53, 3, 163, 208, 211, 216, 5, + 96, 208, 84, 53, 3, 163, 208, 211, 206, 212, 86, 208, 84, 53, 3, 163, + 208, 211, 206, 212, 96, 208, 84, 53, 3, 163, 208, 211, 242, 68, 86, 208, + 84, 53, 3, 163, 208, 211, 242, 68, 62, 245, 86, 183, 25, 96, 47, 62, 245, + 86, 183, 25, 86, 47, 62, 245, 86, 177, 25, 96, 47, 62, 245, 86, 177, 25, + 86, 47, 62, 245, 86, 96, 25, 177, 47, 62, 245, 86, 86, 25, 177, 47, 62, + 245, 86, 96, 25, 183, 47, 62, 245, 86, 86, 25, 183, 47, 216, 55, 53, 121, + 227, 222, 216, 55, 53, 121, 216, 16, 216, 55, 53, 112, 227, 222, 216, 55, + 53, 112, 216, 16, 216, 55, 53, 49, 206, 224, 216, 55, 53, 50, 206, 224, + 216, 55, 53, 49, 242, 70, 216, 55, 53, 50, 242, 70, 177, 61, 53, 239, + 120, 248, 231, 3, 236, 106, 142, 112, 250, 95, 231, 50, 34, 216, 144, + 247, 233, 248, 248, 98, 3, 157, 203, 196, 43, 203, 196, 43, 26, 203, 196, + 62, 51, 246, 215, 62, 243, 222, 246, 215, 207, 174, 62, 218, 255, 236, + 106, 62, 220, 81, 62, 220, 81, 62, 225, 10, 206, 223, 208, 86, 246, 215, + 62, 225, 10, 242, 69, 208, 86, 246, 215, 62, 225, 10, 227, 217, 208, 86, + 246, 215, 62, 225, 10, 216, 11, 208, 86, 246, 215, 208, 145, 162, 62, + 246, 61, 247, 248, 162, 62, 246, 61, 157, 239, 147, 218, 61, 62, 245, 82, + 215, 198, 157, 239, 147, 218, 61, 62, 245, 82, 61, 239, 147, 218, 61, + 245, 82, 215, 198, 61, 239, 147, 218, 61, 245, 82, 51, 218, 34, 231, 31, + 206, 250, 54, 96, 207, 134, 53, 3, 208, 86, 250, 93, 177, 207, 134, 53, + 3, 208, 86, 250, 93, 86, 207, 134, 53, 3, 208, 86, 250, 93, 183, 207, + 134, 53, 3, 208, 86, 250, 93, 180, 6, 1, 250, 0, 180, 6, 1, 247, 181, + 180, 6, 1, 206, 53, 180, 6, 1, 238, 50, 180, 6, 1, 243, 108, 180, 6, 1, + 203, 24, 180, 6, 1, 202, 64, 180, 6, 1, 241, 250, 180, 6, 1, 202, 89, + 180, 6, 1, 230, 188, 180, 6, 1, 81, 230, 188, 180, 6, 1, 75, 180, 6, 1, + 243, 128, 180, 6, 1, 230, 10, 180, 6, 1, 227, 79, 180, 6, 1, 223, 167, + 180, 6, 1, 223, 69, 180, 6, 1, 220, 20, 180, 6, 1, 218, 56, 180, 6, 1, + 215, 244, 180, 6, 1, 212, 41, 180, 6, 1, 207, 161, 180, 6, 1, 207, 10, + 180, 6, 1, 239, 123, 180, 6, 1, 237, 23, 180, 6, 1, 219, 217, 180, 6, 1, + 219, 34, 180, 6, 1, 212, 202, 180, 6, 1, 207, 255, 180, 6, 1, 246, 104, + 180, 6, 1, 213, 90, 180, 6, 1, 203, 30, 180, 6, 1, 203, 32, 180, 6, 1, + 203, 64, 180, 6, 1, 211, 204, 152, 180, 6, 1, 202, 213, 180, 6, 1, 5, + 202, 183, 180, 6, 1, 5, 202, 184, 3, 209, 248, 180, 6, 1, 202, 247, 180, + 6, 1, 230, 229, 5, 202, 183, 180, 6, 1, 248, 73, 202, 183, 180, 6, 1, + 230, 229, 248, 73, 202, 183, 180, 6, 1, 239, 235, 180, 6, 1, 230, 186, + 180, 6, 1, 212, 201, 180, 6, 1, 208, 60, 63, 180, 6, 1, 227, 252, 223, + 167, 180, 5, 1, 250, 0, 180, 5, 1, 247, 181, 180, 5, 1, 206, 53, 180, 5, + 1, 238, 50, 180, 5, 1, 243, 108, 180, 5, 1, 203, 24, 180, 5, 1, 202, 64, + 180, 5, 1, 241, 250, 180, 5, 1, 202, 89, 180, 5, 1, 230, 188, 180, 5, 1, + 81, 230, 188, 180, 5, 1, 75, 180, 5, 1, 243, 128, 180, 5, 1, 230, 10, + 180, 5, 1, 227, 79, 180, 5, 1, 223, 167, 180, 5, 1, 223, 69, 180, 5, 1, + 220, 20, 180, 5, 1, 218, 56, 180, 5, 1, 215, 244, 180, 5, 1, 212, 41, + 180, 5, 1, 207, 161, 180, 5, 1, 207, 10, 180, 5, 1, 239, 123, 180, 5, 1, + 237, 23, 180, 5, 1, 219, 217, 180, 5, 1, 219, 34, 180, 5, 1, 212, 202, + 180, 5, 1, 207, 255, 180, 5, 1, 246, 104, 180, 5, 1, 213, 90, 180, 5, 1, + 203, 30, 180, 5, 1, 203, 32, 180, 5, 1, 203, 64, 180, 5, 1, 211, 204, + 152, 180, 5, 1, 202, 213, 180, 5, 1, 5, 202, 183, 180, 5, 1, 5, 202, 184, + 3, 209, 248, 180, 5, 1, 202, 247, 180, 5, 1, 230, 229, 5, 202, 183, 180, + 5, 1, 248, 73, 202, 183, 180, 5, 1, 230, 229, 248, 73, 202, 183, 180, 5, + 1, 239, 235, 180, 5, 1, 230, 186, 180, 5, 1, 212, 201, 180, 5, 1, 208, + 60, 63, 180, 5, 1, 227, 252, 223, 167, 8, 6, 1, 228, 131, 3, 52, 142, 8, + 5, 1, 228, 131, 3, 52, 142, 8, 6, 1, 228, 131, 3, 101, 208, 227, 8, 6, 1, + 219, 185, 3, 95, 8, 6, 1, 217, 1, 3, 209, 248, 8, 5, 1, 34, 3, 95, 8, 5, + 1, 210, 70, 3, 243, 228, 95, 8, 6, 1, 237, 172, 3, 244, 20, 8, 5, 1, 237, + 172, 3, 244, 20, 8, 6, 1, 230, 55, 3, 244, 20, 8, 5, 1, 230, 55, 3, 244, + 20, 8, 6, 1, 202, 160, 3, 244, 20, 8, 5, 1, 202, 160, 3, 244, 20, 8, 6, + 1, 251, 2, 8, 6, 1, 226, 186, 3, 113, 8, 6, 1, 207, 174, 63, 8, 6, 1, + 207, 174, 251, 2, 8, 5, 1, 206, 165, 3, 50, 113, 8, 6, 1, 204, 145, 3, + 113, 8, 5, 1, 204, 145, 3, 113, 8, 5, 1, 206, 165, 3, 245, 95, 8, 6, 1, + 162, 237, 171, 8, 5, 1, 162, 237, 171, 8, 5, 1, 209, 246, 218, 192, 8, 5, + 1, 188, 3, 221, 163, 8, 5, 1, 207, 174, 217, 1, 3, 209, 248, 8, 5, 1, + 158, 3, 124, 215, 253, 231, 6, 8, 1, 5, 6, 207, 174, 74, 8, 210, 246, 5, + 1, 230, 184, 65, 1, 6, 206, 164, 8, 6, 1, 215, 94, 3, 210, 169, 209, 248, + 8, 6, 1, 202, 160, 3, 210, 169, 209, 248, 84, 6, 1, 251, 24, 84, 5, 1, + 251, 24, 84, 6, 1, 205, 227, 84, 5, 1, 205, 227, 84, 6, 1, 238, 235, 84, + 5, 1, 238, 235, 84, 6, 1, 244, 180, 84, 5, 1, 244, 180, 84, 6, 1, 241, + 144, 84, 5, 1, 241, 144, 84, 6, 1, 211, 243, 84, 5, 1, 211, 243, 84, 6, + 1, 202, 99, 84, 5, 1, 202, 99, 84, 6, 1, 237, 80, 84, 5, 1, 237, 80, 84, + 6, 1, 209, 72, 84, 5, 1, 209, 72, 84, 6, 1, 235, 168, 84, 5, 1, 235, 168, + 84, 6, 1, 229, 252, 84, 5, 1, 229, 252, 84, 6, 1, 227, 248, 84, 5, 1, + 227, 248, 84, 6, 1, 224, 155, 84, 5, 1, 224, 155, 84, 6, 1, 222, 100, 84, + 5, 1, 222, 100, 84, 6, 1, 228, 225, 84, 5, 1, 228, 225, 84, 6, 1, 78, 84, + 5, 1, 78, 84, 6, 1, 218, 167, 84, 5, 1, 218, 167, 84, 6, 1, 215, 227, 84, + 5, 1, 215, 227, 84, 6, 1, 212, 132, 84, 5, 1, 212, 132, 84, 6, 1, 209, + 207, 84, 5, 1, 209, 207, 84, 6, 1, 207, 39, 84, 5, 1, 207, 39, 84, 6, 1, + 240, 26, 84, 5, 1, 240, 26, 84, 6, 1, 229, 122, 84, 5, 1, 229, 122, 84, + 6, 1, 217, 202, 84, 5, 1, 217, 202, 84, 6, 1, 220, 12, 84, 5, 1, 220, 12, + 84, 6, 1, 243, 226, 251, 30, 84, 5, 1, 243, 226, 251, 30, 84, 6, 1, 38, + 84, 251, 59, 84, 5, 1, 38, 84, 251, 59, 84, 6, 1, 245, 113, 241, 144, 84, + 5, 1, 245, 113, 241, 144, 84, 6, 1, 243, 226, 229, 252, 84, 5, 1, 243, + 226, 229, 252, 84, 6, 1, 243, 226, 222, 100, 84, 5, 1, 243, 226, 222, + 100, 84, 6, 1, 245, 113, 222, 100, 84, 5, 1, 245, 113, 222, 100, 84, 6, + 1, 38, 84, 220, 12, 84, 5, 1, 38, 84, 220, 12, 84, 6, 1, 214, 246, 84, 5, + 1, 214, 246, 84, 6, 1, 245, 128, 213, 35, 84, 5, 1, 245, 128, 213, 35, + 84, 6, 1, 38, 84, 213, 35, 84, 5, 1, 38, 84, 213, 35, 84, 6, 1, 38, 84, + 241, 7, 84, 5, 1, 38, 84, 241, 7, 84, 6, 1, 251, 43, 229, 127, 84, 5, 1, + 251, 43, 229, 127, 84, 6, 1, 243, 226, 236, 107, 84, 5, 1, 243, 226, 236, + 107, 84, 6, 1, 38, 84, 236, 107, 84, 5, 1, 38, 84, 236, 107, 84, 6, 1, + 38, 84, 152, 84, 5, 1, 38, 84, 152, 84, 6, 1, 228, 130, 152, 84, 5, 1, + 228, 130, 152, 84, 6, 1, 38, 84, 237, 42, 84, 5, 1, 38, 84, 237, 42, 84, + 6, 1, 38, 84, 237, 83, 84, 5, 1, 38, 84, 237, 83, 84, 6, 1, 38, 84, 238, + 230, 84, 5, 1, 38, 84, 238, 230, 84, 6, 1, 38, 84, 243, 131, 84, 5, 1, + 38, 84, 243, 131, 84, 6, 1, 38, 84, 213, 1, 84, 5, 1, 38, 84, 213, 1, 84, + 6, 1, 38, 221, 54, 213, 1, 84, 5, 1, 38, 221, 54, 213, 1, 84, 6, 1, 38, + 221, 54, 222, 151, 84, 5, 1, 38, 221, 54, 222, 151, 84, 6, 1, 38, 221, + 54, 220, 248, 84, 5, 1, 38, 221, 54, 220, 248, 84, 6, 1, 38, 221, 54, + 204, 77, 84, 5, 1, 38, 221, 54, 204, 77, 84, 16, 230, 18, 84, 16, 224, + 156, 215, 227, 84, 16, 218, 168, 215, 227, 84, 16, 211, 85, 84, 16, 209, + 208, 215, 227, 84, 16, 229, 123, 215, 227, 84, 16, 213, 2, 212, 132, 84, + 6, 1, 245, 113, 213, 35, 84, 5, 1, 245, 113, 213, 35, 84, 6, 1, 245, 113, + 238, 230, 84, 5, 1, 245, 113, 238, 230, 84, 39, 222, 101, 55, 84, 39, + 211, 197, 250, 67, 84, 39, 211, 197, 227, 186, 84, 6, 1, 248, 16, 229, + 127, 84, 5, 1, 248, 16, 229, 127, 84, 38, 221, 54, 239, 102, 211, 61, 84, + 38, 221, 54, 243, 167, 217, 47, 82, 84, 38, 221, 54, 231, 30, 217, 47, + 82, 84, 38, 221, 54, 206, 40, 243, 141, 84, 239, 138, 118, 237, 137, 84, + 239, 102, 211, 61, 84, 224, 25, 243, 141, 114, 5, 1, 250, 231, 114, 5, 1, + 248, 242, 114, 5, 1, 238, 234, 114, 5, 1, 243, 93, 114, 5, 1, 241, 92, + 114, 5, 1, 205, 213, 114, 5, 1, 202, 87, 114, 5, 1, 209, 230, 114, 5, 1, + 231, 49, 114, 5, 1, 230, 4, 114, 5, 1, 228, 2, 114, 5, 1, 225, 122, 114, + 5, 1, 223, 74, 114, 5, 1, 220, 31, 114, 5, 1, 219, 91, 114, 5, 1, 202, + 76, 114, 5, 1, 216, 202, 114, 5, 1, 214, 243, 114, 5, 1, 209, 218, 114, + 5, 1, 206, 255, 114, 5, 1, 218, 200, 114, 5, 1, 229, 132, 114, 5, 1, 238, + 110, 114, 5, 1, 217, 111, 114, 5, 1, 212, 255, 114, 5, 1, 246, 129, 114, + 5, 1, 247, 61, 114, 5, 1, 230, 133, 114, 5, 1, 246, 68, 114, 5, 1, 246, + 183, 114, 5, 1, 203, 180, 114, 5, 1, 230, 146, 114, 5, 1, 237, 154, 114, + 5, 1, 237, 67, 114, 5, 1, 236, 254, 114, 5, 1, 204, 62, 114, 5, 1, 237, + 92, 114, 5, 1, 236, 132, 114, 5, 1, 202, 249, 114, 5, 1, 251, 98, 208, + 247, 1, 198, 208, 247, 1, 203, 106, 208, 247, 1, 203, 105, 208, 247, 1, + 203, 95, 208, 247, 1, 203, 93, 208, 247, 1, 248, 112, 251, 140, 203, 88, + 208, 247, 1, 203, 88, 208, 247, 1, 203, 103, 208, 247, 1, 203, 100, 208, + 247, 1, 203, 102, 208, 247, 1, 203, 101, 208, 247, 1, 203, 15, 208, 247, + 1, 203, 97, 208, 247, 1, 203, 86, 208, 247, 1, 207, 200, 203, 86, 208, + 247, 1, 203, 83, 208, 247, 1, 203, 91, 208, 247, 1, 248, 112, 251, 140, + 203, 91, 208, 247, 1, 207, 200, 203, 91, 208, 247, 1, 203, 90, 208, 247, + 1, 203, 110, 208, 247, 1, 203, 84, 208, 247, 1, 207, 200, 203, 84, 208, + 247, 1, 203, 73, 208, 247, 1, 207, 200, 203, 73, 208, 247, 1, 203, 11, + 208, 247, 1, 203, 54, 208, 247, 1, 251, 71, 203, 54, 208, 247, 1, 207, + 200, 203, 54, 208, 247, 1, 203, 82, 208, 247, 1, 203, 81, 208, 247, 1, + 203, 78, 208, 247, 1, 207, 200, 203, 92, 208, 247, 1, 207, 200, 203, 76, + 208, 247, 1, 203, 74, 208, 247, 1, 202, 213, 208, 247, 1, 203, 71, 208, + 247, 1, 203, 70, 208, 247, 1, 203, 94, 208, 247, 1, 207, 200, 203, 94, + 208, 247, 1, 250, 4, 203, 94, 208, 247, 1, 203, 69, 208, 247, 1, 203, 67, + 208, 247, 1, 203, 68, 208, 247, 1, 203, 66, 208, 247, 1, 203, 65, 208, + 247, 1, 203, 104, 208, 247, 1, 203, 63, 208, 247, 1, 203, 61, 208, 247, + 1, 203, 60, 208, 247, 1, 203, 58, 208, 247, 1, 203, 55, 208, 247, 1, 209, + 199, 203, 55, 208, 247, 1, 203, 53, 208, 247, 1, 203, 52, 208, 247, 1, + 202, 247, 208, 247, 65, 1, 228, 103, 82, 208, 247, 213, 131, 82, 208, + 247, 109, 230, 96, 33, 4, 227, 48, 33, 4, 224, 81, 33, 4, 215, 225, 33, + 4, 212, 12, 33, 4, 212, 241, 33, 4, 248, 22, 33, 4, 208, 172, 33, 4, 245, + 253, 33, 4, 221, 189, 33, 4, 220, 232, 33, 4, 238, 45, 220, 97, 33, 4, + 202, 16, 33, 4, 243, 111, 33, 4, 244, 89, 33, 4, 230, 100, 33, 4, 209, + 46, 33, 4, 246, 115, 33, 4, 218, 179, 33, 4, 218, 68, 33, 4, 238, 125, + 33, 4, 238, 121, 33, 4, 238, 122, 33, 4, 238, 123, 33, 4, 211, 164, 33, + 4, 211, 119, 33, 4, 211, 132, 33, 4, 211, 163, 33, 4, 211, 137, 33, 4, + 211, 138, 33, 4, 211, 124, 33, 4, 247, 5, 33, 4, 246, 240, 33, 4, 246, + 242, 33, 4, 247, 4, 33, 4, 247, 2, 33, 4, 247, 3, 33, 4, 246, 241, 33, 4, + 201, 235, 33, 4, 201, 213, 33, 4, 201, 226, 33, 4, 201, 234, 33, 4, 201, + 229, 33, 4, 201, 230, 33, 4, 201, 218, 33, 4, 247, 0, 33, 4, 246, 243, + 33, 4, 246, 245, 33, 4, 246, 255, 33, 4, 246, 253, 33, 4, 246, 254, 33, + 4, 246, 244, 33, 4, 217, 13, 33, 4, 217, 3, 33, 4, 217, 9, 33, 4, 217, + 12, 33, 4, 217, 10, 33, 4, 217, 11, 33, 4, 217, 8, 33, 4, 228, 141, 33, + 4, 228, 133, 33, 4, 228, 136, 33, 4, 228, 140, 33, 4, 228, 137, 33, 4, + 228, 138, 33, 4, 228, 134, 33, 4, 203, 140, 33, 4, 203, 127, 33, 4, 203, + 135, 33, 4, 203, 139, 33, 4, 203, 137, 33, 4, 203, 138, 33, 4, 203, 134, + 33, 4, 237, 183, 33, 4, 237, 173, 33, 4, 237, 176, 33, 4, 237, 182, 33, + 4, 237, 178, 33, 4, 237, 179, 33, 4, 237, 175, 39, 36, 1, 248, 162, 39, + 36, 1, 206, 55, 39, 36, 1, 238, 105, 39, 36, 1, 244, 75, 39, 36, 1, 202, + 71, 39, 36, 1, 202, 92, 39, 36, 1, 173, 39, 36, 1, 241, 122, 39, 36, 1, + 241, 103, 39, 36, 1, 241, 92, 39, 36, 1, 78, 39, 36, 1, 219, 34, 39, 36, + 1, 241, 28, 39, 36, 1, 241, 17, 39, 36, 1, 209, 187, 39, 36, 1, 152, 39, + 36, 1, 208, 14, 39, 36, 1, 246, 170, 39, 36, 1, 213, 90, 39, 36, 1, 213, + 46, 39, 36, 1, 239, 235, 39, 36, 1, 241, 13, 39, 36, 1, 63, 39, 36, 1, + 231, 110, 39, 36, 1, 243, 129, 39, 36, 1, 224, 43, 207, 14, 39, 36, 1, + 203, 66, 39, 36, 1, 202, 213, 39, 36, 1, 230, 228, 63, 39, 36, 1, 227, + 86, 202, 183, 39, 36, 1, 248, 73, 202, 183, 39, 36, 1, 230, 228, 248, 73, + 202, 183, 50, 250, 218, 210, 241, 225, 88, 50, 250, 218, 242, 83, 210, + 241, 225, 88, 49, 210, 241, 155, 50, 210, 241, 155, 49, 242, 83, 210, + 241, 155, 50, 242, 83, 210, 241, 155, 216, 188, 230, 249, 225, 88, 216, + 188, 242, 83, 230, 249, 225, 88, 242, 83, 208, 103, 225, 88, 49, 208, + 103, 155, 50, 208, 103, 155, 216, 188, 211, 177, 49, 216, 188, 220, 33, + 155, 50, 216, 188, 220, 33, 155, 241, 162, 245, 163, 219, 87, 239, 161, + 219, 87, 216, 73, 239, 161, 219, 87, 235, 217, 242, 83, 220, 92, 183, + 250, 227, 177, 250, 227, 242, 83, 216, 11, 250, 217, 52, 220, 89, 235, + 220, 230, 239, 230, 247, 219, 135, 247, 223, 235, 221, 3, 243, 231, 208, + 228, 3, 215, 253, 55, 49, 124, 219, 79, 155, 50, 124, 219, 79, 155, 208, + 228, 3, 70, 55, 208, 228, 3, 70, 56, 49, 80, 248, 231, 3, 217, 41, 50, + 80, 248, 231, 3, 217, 41, 208, 145, 49, 162, 155, 208, 145, 50, 162, 155, + 247, 248, 49, 162, 155, 247, 248, 50, 162, 155, 49, 212, 154, 106, 155, + 50, 212, 154, 106, 155, 49, 52, 219, 76, 50, 52, 219, 76, 120, 187, 115, + 118, 70, 217, 178, 118, 70, 115, 120, 187, 217, 178, 103, 239, 147, 70, + 217, 178, 239, 233, 70, 82, 216, 73, 217, 47, 82, 80, 208, 227, 215, 253, + 218, 62, 203, 238, 213, 131, 101, 243, 85, 207, 174, 245, 233, 216, 188, + 243, 85, 216, 188, 245, 233, 207, 174, 213, 143, 244, 196, 3, 49, 237, + 224, 244, 196, 3, 50, 237, 224, 207, 174, 244, 195, 208, 145, 162, 214, + 168, 54, 207, 135, 244, 144, 209, 30, 244, 144, 211, 76, 239, 102, 211, + 61, 80, 212, 88, 243, 83, 204, 21, 80, 227, 114, 247, 46, 52, 235, 220, + 216, 73, 245, 233, 52, 226, 252, 217, 31, 82, 12, 40, 216, 100, 12, 40, + 246, 26, 12, 40, 214, 171, 105, 12, 40, 214, 171, 108, 12, 40, 214, 171, + 147, 12, 40, 218, 229, 12, 40, 247, 233, 12, 40, 210, 8, 12, 40, 229, 34, + 105, 12, 40, 229, 34, 108, 12, 40, 243, 138, 12, 40, 214, 175, 12, 40, 5, + 105, 12, 40, 5, 108, 12, 40, 228, 23, 105, 12, 40, 228, 23, 108, 12, 40, + 228, 23, 147, 12, 40, 228, 23, 149, 12, 40, 212, 24, 12, 40, 209, 33, 12, + 40, 212, 22, 105, 12, 40, 212, 22, 108, 12, 40, 237, 56, 105, 12, 40, + 237, 56, 108, 12, 40, 237, 123, 12, 40, 216, 178, 12, 40, 246, 112, 12, + 40, 210, 214, 12, 40, 224, 29, 12, 40, 244, 73, 12, 40, 224, 20, 12, 40, + 246, 44, 12, 40, 204, 81, 105, 12, 40, 204, 81, 108, 12, 40, 239, 249, + 12, 40, 219, 46, 105, 12, 40, 219, 46, 108, 12, 40, 212, 127, 162, 208, + 96, 208, 25, 12, 40, 245, 149, 12, 40, 243, 102, 12, 40, 230, 176, 12, + 40, 248, 15, 76, 246, 10, 12, 40, 240, 191, 12, 40, 211, 199, 105, 12, + 40, 211, 199, 108, 12, 40, 248, 244, 12, 40, 212, 134, 12, 40, 247, 122, + 212, 134, 12, 40, 222, 220, 105, 12, 40, 222, 220, 108, 12, 40, 222, 220, + 147, 12, 40, 222, 220, 149, 12, 40, 224, 227, 12, 40, 213, 37, 12, 40, + 216, 184, 12, 40, 240, 219, 12, 40, 220, 45, 12, 40, 247, 201, 105, 12, + 40, 247, 201, 108, 12, 40, 225, 15, 12, 40, 224, 24, 12, 40, 238, 1, 105, + 12, 40, 238, 1, 108, 12, 40, 238, 1, 147, 12, 40, 208, 245, 12, 40, 246, + 9, 12, 40, 204, 46, 105, 12, 40, 204, 46, 108, 12, 40, 247, 122, 214, + 165, 12, 40, 212, 127, 236, 53, 12, 40, 236, 53, 12, 40, 247, 122, 211, + 211, 12, 40, 247, 122, 213, 32, 12, 40, 239, 172, 12, 40, 247, 122, 247, + 23, 12, 40, 212, 127, 204, 101, 12, 40, 204, 102, 105, 12, 40, 204, 102, + 108, 12, 40, 246, 47, 12, 40, 247, 122, 238, 31, 12, 40, 163, 105, 12, + 40, 163, 108, 12, 40, 247, 122, 227, 28, 12, 40, 247, 122, 238, 216, 12, + 40, 224, 16, 105, 12, 40, 224, 16, 108, 12, 40, 216, 190, 12, 40, 248, + 25, 12, 40, 247, 122, 209, 224, 227, 228, 12, 40, 247, 122, 227, 229, 12, + 40, 247, 122, 204, 16, 12, 40, 247, 122, 239, 190, 12, 40, 241, 173, 105, + 12, 40, 241, 173, 108, 12, 40, 241, 173, 147, 12, 40, 247, 122, 241, 172, + 12, 40, 237, 64, 12, 40, 247, 122, 236, 49, 12, 40, 248, 11, 12, 40, 238, + 89, 12, 40, 247, 122, 239, 243, 12, 40, 247, 122, 248, 60, 12, 40, 247, + 122, 215, 1, 12, 40, 212, 127, 204, 38, 12, 40, 212, 127, 203, 44, 12, + 40, 247, 122, 239, 121, 12, 40, 230, 183, 240, 224, 12, 40, 247, 122, + 240, 224, 12, 40, 230, 183, 208, 146, 12, 40, 247, 122, 208, 146, 12, 40, + 230, 183, 242, 61, 12, 40, 247, 122, 242, 61, 12, 40, 207, 171, 12, 40, + 230, 183, 207, 171, 12, 40, 247, 122, 207, 171, 71, 40, 105, 71, 40, 227, + 114, 71, 40, 243, 85, 71, 40, 212, 57, 71, 40, 214, 170, 71, 40, 113, 71, + 40, 108, 71, 40, 227, 143, 71, 40, 225, 122, 71, 40, 227, 207, 71, 40, + 241, 67, 71, 40, 199, 71, 40, 121, 247, 233, 71, 40, 245, 151, 71, 40, + 235, 162, 71, 40, 210, 8, 71, 40, 171, 247, 233, 71, 40, 229, 33, 71, 40, + 218, 16, 71, 40, 203, 228, 71, 40, 211, 190, 71, 40, 50, 171, 247, 233, + 71, 40, 236, 255, 241, 87, 71, 40, 209, 152, 71, 40, 243, 138, 71, 40, + 214, 175, 71, 40, 246, 26, 71, 40, 217, 226, 71, 40, 251, 80, 71, 40, + 224, 7, 71, 40, 241, 87, 71, 40, 241, 179, 71, 40, 214, 197, 71, 40, 238, + 39, 71, 40, 238, 40, 212, 38, 71, 40, 240, 223, 71, 40, 248, 72, 71, 40, + 203, 250, 71, 40, 246, 133, 71, 40, 215, 207, 71, 40, 231, 45, 71, 40, + 212, 36, 71, 40, 228, 22, 71, 40, 245, 161, 71, 40, 211, 181, 71, 40, + 224, 12, 71, 40, 215, 241, 71, 40, 203, 235, 71, 40, 220, 25, 71, 40, + 207, 180, 71, 40, 242, 44, 71, 40, 212, 228, 209, 33, 71, 40, 242, 83, + 246, 26, 71, 40, 163, 211, 38, 71, 40, 120, 237, 99, 71, 40, 212, 234, + 71, 40, 247, 240, 71, 40, 212, 21, 71, 40, 247, 205, 71, 40, 211, 75, 71, + 40, 237, 55, 71, 40, 237, 138, 71, 40, 243, 88, 71, 40, 237, 123, 71, 40, + 247, 223, 71, 40, 216, 178, 71, 40, 214, 183, 71, 40, 243, 169, 71, 40, + 250, 9, 71, 40, 211, 177, 71, 40, 221, 165, 71, 40, 210, 214, 71, 40, + 214, 208, 71, 40, 224, 29, 71, 40, 208, 95, 71, 40, 228, 99, 71, 40, 211, + 61, 71, 40, 244, 73, 71, 40, 204, 61, 71, 40, 243, 114, 221, 165, 71, 40, + 245, 229, 71, 40, 239, 95, 71, 40, 246, 38, 71, 40, 211, 80, 71, 40, 204, + 80, 71, 40, 239, 249, 71, 40, 246, 34, 71, 40, 240, 67, 71, 40, 52, 203, + 196, 71, 40, 162, 208, 96, 208, 25, 71, 40, 212, 50, 71, 40, 240, 79, 71, + 40, 245, 149, 71, 40, 243, 102, 71, 40, 217, 223, 71, 40, 230, 176, 71, + 40, 224, 249, 71, 40, 208, 226, 71, 40, 210, 164, 71, 40, 227, 137, 71, + 40, 206, 191, 71, 40, 240, 24, 71, 40, 248, 15, 76, 246, 10, 71, 40, 212, + 158, 71, 40, 242, 83, 209, 144, 71, 40, 204, 33, 71, 40, 212, 65, 71, 40, + 243, 156, 71, 40, 240, 191, 71, 40, 211, 214, 71, 40, 47, 71, 40, 211, + 63, 71, 40, 211, 198, 71, 40, 208, 118, 71, 40, 238, 10, 71, 40, 247, 10, + 71, 40, 211, 98, 71, 40, 248, 244, 71, 40, 216, 52, 71, 40, 212, 134, 71, + 40, 230, 168, 71, 40, 222, 219, 71, 40, 213, 37, 71, 40, 240, 55, 71, 40, + 220, 45, 71, 40, 250, 226, 71, 40, 218, 83, 71, 40, 241, 183, 71, 40, + 247, 200, 71, 40, 225, 15, 71, 40, 224, 104, 71, 40, 213, 149, 71, 40, + 250, 98, 71, 40, 224, 24, 71, 40, 208, 150, 71, 40, 219, 252, 71, 40, + 248, 19, 71, 40, 211, 59, 71, 40, 245, 241, 71, 40, 238, 0, 71, 40, 208, + 245, 71, 40, 231, 9, 71, 40, 248, 31, 71, 40, 204, 102, 241, 87, 71, 40, + 246, 9, 71, 40, 204, 45, 71, 40, 214, 165, 71, 40, 236, 53, 71, 40, 211, + 211, 71, 40, 206, 79, 71, 40, 248, 157, 71, 40, 218, 131, 71, 40, 249, + 13, 71, 40, 213, 32, 71, 40, 216, 137, 71, 40, 215, 128, 71, 40, 239, + 172, 71, 40, 248, 17, 71, 40, 247, 23, 71, 40, 248, 48, 71, 40, 224, 26, + 71, 40, 204, 101, 71, 40, 246, 47, 71, 40, 204, 12, 71, 40, 243, 149, 71, + 40, 205, 214, 71, 40, 238, 31, 71, 40, 227, 28, 71, 40, 238, 216, 71, 40, + 224, 15, 71, 40, 212, 56, 71, 40, 212, 228, 209, 247, 248, 60, 71, 40, + 216, 190, 71, 40, 248, 25, 71, 40, 203, 219, 71, 40, 240, 102, 71, 40, + 227, 228, 71, 40, 209, 224, 227, 228, 71, 40, 227, 224, 71, 40, 211, 240, + 71, 40, 227, 229, 71, 40, 204, 16, 71, 40, 239, 190, 71, 40, 241, 172, + 71, 40, 237, 64, 71, 40, 239, 136, 71, 40, 236, 49, 71, 40, 248, 11, 71, + 40, 209, 233, 71, 40, 237, 145, 71, 40, 240, 17, 71, 40, 215, 30, 204, + 12, 71, 40, 247, 12, 71, 40, 238, 89, 71, 40, 239, 243, 71, 40, 248, 60, + 71, 40, 215, 1, 71, 40, 244, 58, 71, 40, 204, 38, 71, 40, 237, 34, 71, + 40, 203, 44, 71, 40, 224, 115, 71, 40, 248, 43, 71, 40, 241, 99, 71, 40, + 239, 121, 71, 40, 208, 67, 71, 40, 242, 46, 71, 40, 216, 172, 71, 40, + 221, 167, 71, 40, 240, 224, 71, 40, 208, 146, 71, 40, 242, 61, 71, 40, + 207, 171, 71, 40, 239, 193, 139, 244, 18, 167, 49, 208, 173, 216, 16, + 139, 244, 18, 167, 87, 208, 173, 56, 139, 244, 18, 167, 49, 208, 173, + 101, 25, 216, 16, 139, 244, 18, 167, 87, 208, 173, 101, 25, 56, 139, 244, + 18, 167, 239, 102, 210, 186, 139, 244, 18, 167, 210, 187, 239, 120, 55, + 139, 244, 18, 167, 210, 187, 239, 120, 56, 139, 244, 18, 167, 210, 187, + 239, 120, 227, 222, 139, 244, 18, 167, 210, 187, 239, 120, 206, 221, 227, + 222, 139, 244, 18, 167, 210, 187, 239, 120, 206, 221, 216, 16, 139, 244, + 18, 167, 210, 187, 239, 120, 226, 251, 227, 222, 139, 244, 18, 167, 219, + 202, 139, 211, 228, 139, 245, 233, 139, 239, 102, 211, 61, 243, 146, 82, + 230, 169, 231, 29, 211, 97, 97, 139, 230, 199, 82, 139, 246, 12, 82, 139, + 42, 202, 84, 49, 250, 218, 155, 50, 250, 218, 155, 49, 52, 250, 218, 155, + 50, 52, 250, 218, 155, 49, 245, 166, 155, 50, 245, 166, 155, 49, 61, 245, + 166, 155, 50, 61, 245, 166, 155, 49, 62, 227, 185, 155, 50, 62, 227, 185, + 155, 218, 29, 82, 238, 158, 82, 49, 208, 133, 213, 33, 155, 50, 208, 133, + 213, 33, 155, 49, 61, 227, 185, 155, 50, 61, 227, 185, 155, 49, 61, 208, + 133, 213, 33, 155, 50, 61, 208, 133, 213, 33, 155, 49, 61, 51, 155, 50, + 61, 51, 155, 204, 76, 244, 144, 216, 73, 52, 217, 237, 217, 31, 82, 52, + 217, 237, 217, 31, 82, 124, 52, 217, 237, 217, 31, 82, 218, 29, 131, 240, + 102, 237, 97, 221, 44, 105, 237, 97, 221, 44, 108, 237, 97, 221, 44, 147, + 237, 97, 221, 44, 149, 237, 97, 221, 44, 170, 237, 97, 221, 44, 195, 237, + 97, 221, 44, 213, 111, 237, 97, 221, 44, 199, 237, 97, 221, 44, 222, 63, + 139, 227, 167, 143, 82, 139, 215, 245, 143, 82, 139, 244, 27, 143, 82, + 139, 241, 66, 143, 82, 28, 212, 120, 70, 143, 82, 28, 52, 70, 143, 82, + 204, 72, 244, 144, 80, 230, 3, 216, 101, 82, 80, 230, 3, 216, 101, 3, + 205, 186, 211, 241, 82, 80, 230, 3, 216, 101, 131, 206, 221, 237, 137, + 80, 230, 3, 216, 101, 3, 205, 186, 211, 241, 131, 206, 221, 237, 137, 80, + 230, 3, 216, 101, 131, 226, 251, 237, 137, 43, 218, 29, 82, 139, 209, + 164, 227, 115, 240, 52, 213, 131, 97, 237, 97, 221, 44, 209, 152, 237, + 97, 221, 44, 207, 151, 237, 97, 221, 44, 209, 53, 80, 139, 230, 199, 82, + 225, 72, 82, 219, 71, 250, 251, 82, 139, 57, 231, 31, 139, 162, 240, 10, + 211, 228, 172, 1, 5, 63, 172, 1, 63, 172, 1, 5, 75, 172, 1, 75, 172, 1, + 5, 68, 172, 1, 68, 172, 1, 5, 74, 172, 1, 74, 172, 1, 5, 78, 172, 1, 78, + 172, 1, 173, 172, 1, 239, 8, 172, 1, 229, 100, 172, 1, 238, 81, 172, 1, + 228, 209, 172, 1, 237, 230, 172, 1, 229, 201, 172, 1, 238, 190, 172, 1, + 229, 26, 172, 1, 238, 39, 172, 1, 215, 36, 172, 1, 202, 116, 172, 1, 212, + 162, 172, 1, 202, 39, 172, 1, 211, 10, 172, 1, 202, 6, 172, 1, 214, 177, + 172, 1, 202, 92, 172, 1, 212, 13, 172, 1, 202, 17, 172, 1, 210, 22, 172, + 1, 244, 212, 172, 1, 209, 2, 172, 1, 243, 233, 172, 1, 5, 207, 203, 172, + 1, 207, 203, 172, 1, 242, 42, 172, 1, 209, 187, 172, 1, 244, 75, 172, 1, + 135, 172, 1, 243, 113, 172, 1, 201, 201, 172, 1, 222, 100, 172, 1, 221, + 84, 172, 1, 222, 240, 172, 1, 221, 191, 172, 1, 152, 172, 1, 249, 32, + 172, 1, 185, 172, 1, 237, 3, 172, 1, 248, 86, 172, 1, 218, 167, 172, 1, + 236, 26, 172, 1, 247, 193, 172, 1, 217, 191, 172, 1, 237, 67, 172, 1, + 248, 162, 172, 1, 219, 34, 172, 1, 236, 136, 172, 1, 248, 23, 172, 1, + 218, 69, 172, 1, 192, 172, 1, 224, 155, 172, 1, 223, 246, 172, 1, 225, + 20, 172, 1, 224, 82, 172, 1, 5, 198, 172, 1, 198, 172, 1, 5, 202, 213, + 172, 1, 202, 213, 172, 1, 5, 202, 247, 172, 1, 202, 247, 172, 1, 216, + 220, 172, 1, 216, 57, 172, 1, 215, 145, 172, 1, 216, 158, 172, 1, 215, + 227, 172, 1, 5, 204, 111, 172, 1, 204, 111, 172, 1, 204, 30, 172, 1, 204, + 62, 172, 1, 204, 0, 172, 1, 223, 163, 172, 1, 204, 163, 172, 1, 5, 173, + 172, 1, 5, 229, 201, 39, 229, 225, 205, 186, 211, 241, 82, 39, 229, 225, + 213, 148, 211, 241, 82, 229, 225, 205, 186, 211, 241, 82, 229, 225, 213, + 148, 211, 241, 82, 172, 230, 199, 82, 172, 205, 186, 230, 199, 82, 172, + 243, 192, 202, 228, 229, 225, 52, 235, 220, 67, 1, 5, 63, 67, 1, 63, 67, + 1, 5, 75, 67, 1, 75, 67, 1, 5, 68, 67, 1, 68, 67, 1, 5, 74, 67, 1, 74, + 67, 1, 5, 78, 67, 1, 78, 67, 1, 173, 67, 1, 239, 8, 67, 1, 229, 100, 67, + 1, 238, 81, 67, 1, 228, 209, 67, 1, 237, 230, 67, 1, 229, 201, 67, 1, + 238, 190, 67, 1, 229, 26, 67, 1, 238, 39, 67, 1, 215, 36, 67, 1, 202, + 116, 67, 1, 212, 162, 67, 1, 202, 39, 67, 1, 211, 10, 67, 1, 202, 6, 67, + 1, 214, 177, 67, 1, 202, 92, 67, 1, 212, 13, 67, 1, 202, 17, 67, 1, 210, + 22, 67, 1, 244, 212, 67, 1, 209, 2, 67, 1, 243, 233, 67, 1, 5, 207, 203, + 67, 1, 207, 203, 67, 1, 242, 42, 67, 1, 209, 187, 67, 1, 244, 75, 67, 1, + 135, 67, 1, 243, 113, 67, 1, 201, 201, 67, 1, 222, 100, 67, 1, 221, 84, + 67, 1, 222, 240, 67, 1, 221, 191, 67, 1, 152, 67, 1, 249, 32, 67, 1, 185, + 67, 1, 237, 3, 67, 1, 248, 86, 67, 1, 218, 167, 67, 1, 236, 26, 67, 1, + 247, 193, 67, 1, 217, 191, 67, 1, 237, 67, 67, 1, 248, 162, 67, 1, 219, + 34, 67, 1, 236, 136, 67, 1, 248, 23, 67, 1, 218, 69, 67, 1, 192, 67, 1, + 224, 155, 67, 1, 223, 246, 67, 1, 225, 20, 67, 1, 224, 82, 67, 1, 5, 198, + 67, 1, 198, 67, 1, 5, 202, 213, 67, 1, 202, 213, 67, 1, 5, 202, 247, 67, + 1, 202, 247, 67, 1, 216, 220, 67, 1, 216, 57, 67, 1, 215, 145, 67, 1, + 216, 158, 67, 1, 215, 227, 67, 1, 5, 204, 111, 67, 1, 204, 111, 67, 1, + 204, 30, 67, 1, 204, 62, 67, 1, 204, 0, 67, 1, 223, 163, 67, 1, 204, 163, + 67, 1, 5, 173, 67, 1, 5, 229, 201, 67, 1, 206, 86, 67, 1, 205, 230, 67, + 1, 206, 55, 67, 1, 205, 189, 67, 101, 243, 85, 229, 225, 217, 215, 211, + 241, 82, 67, 230, 199, 82, 67, 205, 186, 230, 199, 82, 67, 243, 192, 228, + 249, 248, 1, 1, 249, 255, 248, 1, 1, 219, 184, 248, 1, 1, 226, 185, 248, + 1, 1, 240, 174, 248, 1, 1, 245, 51, 248, 1, 1, 210, 69, 248, 1, 1, 223, + 163, 248, 1, 1, 159, 248, 1, 1, 239, 75, 248, 1, 1, 230, 54, 248, 1, 1, + 237, 171, 248, 1, 1, 230, 184, 248, 1, 1, 217, 134, 248, 1, 1, 203, 196, + 248, 1, 1, 202, 81, 248, 1, 1, 246, 200, 248, 1, 1, 213, 92, 248, 1, 1, + 146, 248, 1, 1, 202, 159, 248, 1, 1, 247, 125, 248, 1, 1, 194, 248, 1, 1, + 63, 248, 1, 1, 78, 248, 1, 1, 74, 248, 1, 1, 241, 147, 248, 1, 1, 251, + 64, 248, 1, 1, 241, 145, 248, 1, 1, 250, 34, 248, 1, 1, 219, 216, 248, 1, + 1, 250, 231, 248, 1, 1, 241, 92, 248, 1, 1, 250, 223, 248, 1, 1, 241, 78, + 248, 1, 1, 241, 28, 248, 1, 1, 75, 248, 1, 1, 68, 248, 1, 1, 230, 197, + 248, 1, 1, 206, 164, 248, 1, 1, 222, 205, 248, 1, 1, 238, 43, 248, 1, 1, + 231, 84, 28, 1, 229, 59, 28, 1, 211, 156, 28, 1, 229, 52, 28, 1, 222, 93, + 28, 1, 222, 91, 28, 1, 222, 90, 28, 1, 208, 240, 28, 1, 211, 145, 28, 1, + 216, 47, 28, 1, 216, 42, 28, 1, 216, 39, 28, 1, 216, 32, 28, 1, 216, 27, + 28, 1, 216, 22, 28, 1, 216, 33, 28, 1, 216, 45, 28, 1, 224, 141, 28, 1, + 218, 153, 28, 1, 211, 153, 28, 1, 218, 142, 28, 1, 212, 111, 28, 1, 211, + 150, 28, 1, 231, 106, 28, 1, 246, 74, 28, 1, 211, 160, 28, 1, 246, 138, + 28, 1, 229, 120, 28, 1, 209, 66, 28, 1, 218, 190, 28, 1, 236, 251, 28, 1, + 63, 28, 1, 251, 109, 28, 1, 198, 28, 1, 203, 99, 28, 1, 241, 55, 28, 1, + 74, 28, 1, 203, 39, 28, 1, 203, 52, 28, 1, 78, 28, 1, 204, 111, 28, 1, + 204, 107, 28, 1, 220, 73, 28, 1, 202, 247, 28, 1, 68, 28, 1, 204, 48, 28, + 1, 204, 62, 28, 1, 204, 30, 28, 1, 202, 213, 28, 1, 240, 238, 28, 1, 203, + 11, 28, 1, 75, 28, 240, 7, 28, 1, 211, 154, 28, 1, 222, 83, 28, 1, 222, + 85, 28, 1, 222, 88, 28, 1, 216, 40, 28, 1, 216, 21, 28, 1, 216, 29, 28, + 1, 216, 34, 28, 1, 216, 19, 28, 1, 224, 134, 28, 1, 224, 131, 28, 1, 224, + 135, 28, 1, 229, 246, 28, 1, 218, 148, 28, 1, 218, 134, 28, 1, 218, 140, + 28, 1, 218, 137, 28, 1, 218, 151, 28, 1, 218, 135, 28, 1, 229, 244, 28, + 1, 229, 242, 28, 1, 212, 104, 28, 1, 212, 102, 28, 1, 212, 94, 28, 1, + 212, 99, 28, 1, 212, 109, 28, 1, 219, 107, 28, 1, 211, 157, 28, 1, 203, + 29, 28, 1, 203, 25, 28, 1, 203, 26, 28, 1, 229, 245, 28, 1, 211, 158, 28, + 1, 203, 35, 28, 1, 202, 241, 28, 1, 202, 240, 28, 1, 202, 243, 28, 1, + 202, 204, 28, 1, 202, 205, 28, 1, 202, 208, 28, 1, 250, 137, 28, 1, 250, + 131, 139, 250, 205, 227, 103, 82, 139, 250, 205, 216, 74, 82, 139, 250, + 205, 118, 82, 139, 250, 205, 120, 82, 139, 250, 205, 126, 82, 139, 250, + 205, 239, 147, 82, 139, 250, 205, 208, 145, 82, 139, 250, 205, 101, 82, + 139, 250, 205, 247, 248, 82, 139, 250, 205, 239, 245, 82, 139, 250, 205, + 214, 171, 82, 139, 250, 205, 209, 61, 82, 139, 250, 205, 239, 140, 82, + 139, 250, 205, 237, 52, 82, 139, 250, 205, 241, 180, 82, 139, 250, 205, + 225, 123, 82, 248, 1, 1, 247, 193, 248, 1, 1, 202, 39, 248, 1, 1, 230, + 141, 248, 1, 1, 237, 230, 248, 1, 1, 241, 161, 248, 1, 1, 241, 75, 248, + 1, 1, 220, 18, 248, 1, 1, 220, 22, 248, 1, 1, 230, 224, 248, 1, 1, 250, + 207, 248, 1, 1, 231, 16, 248, 1, 1, 206, 229, 248, 1, 1, 231, 66, 248, 1, + 1, 222, 183, 248, 1, 1, 251, 58, 248, 1, 1, 250, 29, 248, 1, 1, 250, 247, + 248, 1, 1, 220, 39, 248, 1, 1, 220, 24, 248, 1, 1, 231, 13, 248, 1, 46, + 1, 219, 184, 248, 1, 46, 1, 210, 69, 248, 1, 46, 1, 230, 54, 248, 1, 46, + 1, 237, 171, 248, 1, 1, 238, 120, 248, 1, 1, 227, 162, 248, 1, 1, 201, + 242, 12, 211, 32, 210, 69, 12, 211, 32, 204, 41, 12, 211, 32, 203, 171, + 12, 211, 32, 247, 138, 12, 211, 32, 210, 173, 12, 211, 32, 235, 210, 12, + 211, 32, 235, 214, 12, 211, 32, 236, 35, 12, 211, 32, 235, 211, 12, 211, + 32, 210, 72, 12, 211, 32, 235, 213, 12, 211, 32, 235, 209, 12, 211, 32, + 236, 33, 12, 211, 32, 235, 212, 12, 211, 32, 235, 208, 12, 211, 32, 223, + 163, 12, 211, 32, 237, 171, 12, 211, 32, 194, 12, 211, 32, 219, 184, 12, + 211, 32, 211, 231, 12, 211, 32, 245, 51, 12, 211, 32, 235, 215, 12, 211, + 32, 237, 13, 12, 211, 32, 210, 81, 12, 211, 32, 210, 152, 12, 211, 32, + 211, 108, 12, 211, 32, 213, 98, 12, 211, 32, 219, 38, 12, 211, 32, 217, + 136, 12, 211, 32, 208, 174, 12, 211, 32, 210, 71, 12, 211, 32, 210, 163, + 12, 211, 32, 235, 223, 12, 211, 32, 235, 207, 12, 211, 32, 218, 210, 12, + 211, 32, 217, 134, 67, 1, 5, 228, 209, 67, 1, 5, 212, 162, 67, 1, 5, 211, + 10, 67, 1, 5, 135, 67, 1, 5, 221, 84, 67, 1, 5, 152, 67, 1, 5, 237, 3, + 67, 1, 5, 236, 26, 67, 1, 5, 237, 67, 67, 1, 5, 236, 136, 67, 1, 5, 223, + 246, 67, 1, 5, 216, 220, 67, 1, 5, 216, 57, 67, 1, 5, 215, 145, 67, 1, 5, + 216, 158, 67, 1, 5, 215, 227, 102, 28, 229, 59, 102, 28, 222, 93, 102, + 28, 208, 240, 102, 28, 216, 47, 102, 28, 224, 141, 102, 28, 218, 153, + 102, 28, 212, 111, 102, 28, 231, 106, 102, 28, 246, 74, 102, 28, 246, + 138, 102, 28, 229, 120, 102, 28, 209, 66, 102, 28, 218, 190, 102, 28, + 236, 251, 102, 28, 229, 60, 63, 102, 28, 222, 94, 63, 102, 28, 208, 241, + 63, 102, 28, 216, 48, 63, 102, 28, 224, 142, 63, 102, 28, 218, 154, 63, + 102, 28, 212, 112, 63, 102, 28, 231, 107, 63, 102, 28, 246, 75, 63, 102, + 28, 246, 139, 63, 102, 28, 229, 121, 63, 102, 28, 209, 67, 63, 102, 28, + 218, 191, 63, 102, 28, 236, 252, 63, 102, 28, 246, 75, 68, 102, 228, 253, + 167, 220, 54, 102, 228, 253, 167, 158, 236, 26, 102, 189, 105, 102, 189, + 108, 102, 189, 147, 102, 189, 149, 102, 189, 170, 102, 189, 195, 102, + 189, 213, 111, 102, 189, 199, 102, 189, 222, 63, 102, 189, 209, 152, 102, + 189, 224, 29, 102, 189, 239, 249, 102, 189, 204, 80, 102, 189, 203, 243, + 102, 189, 224, 220, 102, 189, 241, 179, 102, 189, 210, 214, 102, 189, + 211, 64, 102, 189, 237, 74, 102, 189, 212, 9, 102, 189, 223, 84, 102, + 189, 211, 213, 102, 189, 240, 4, 102, 189, 245, 211, 102, 189, 228, 102, + 102, 189, 216, 95, 102, 189, 247, 71, 102, 189, 211, 14, 102, 189, 210, + 196, 102, 189, 241, 65, 102, 189, 216, 87, 102, 189, 251, 10, 102, 189, + 240, 33, 102, 189, 216, 85, 102, 189, 213, 149, 102, 189, 216, 157, 43, + 189, 217, 46, 43, 189, 229, 83, 43, 189, 214, 195, 43, 189, 228, 249, 43, + 42, 209, 153, 220, 32, 62, 211, 177, 43, 42, 207, 152, 220, 32, 62, 211, + 177, 43, 42, 209, 54, 220, 32, 62, 211, 177, 43, 42, 239, 154, 220, 32, + 62, 211, 177, 43, 42, 240, 19, 220, 32, 62, 211, 177, 43, 42, 212, 75, + 220, 32, 62, 211, 177, 43, 42, 213, 106, 220, 32, 62, 211, 177, 43, 42, + 241, 135, 220, 32, 62, 211, 177, 219, 67, 54, 43, 42, 207, 152, 105, 43, + 42, 207, 152, 108, 43, 42, 207, 152, 147, 43, 42, 207, 152, 149, 43, 42, + 207, 152, 170, 43, 42, 207, 152, 195, 43, 42, 207, 152, 213, 111, 43, 42, + 207, 152, 199, 43, 42, 207, 152, 222, 63, 43, 42, 209, 53, 43, 42, 209, + 54, 105, 43, 42, 209, 54, 108, 43, 42, 209, 54, 147, 43, 42, 209, 54, + 149, 43, 42, 209, 54, 170, 43, 28, 229, 59, 43, 28, 222, 93, 43, 28, 208, + 240, 43, 28, 216, 47, 43, 28, 224, 141, 43, 28, 218, 153, 43, 28, 212, + 111, 43, 28, 231, 106, 43, 28, 246, 74, 43, 28, 246, 138, 43, 28, 229, + 120, 43, 28, 209, 66, 43, 28, 218, 190, 43, 28, 236, 251, 43, 28, 229, + 60, 63, 43, 28, 222, 94, 63, 43, 28, 208, 241, 63, 43, 28, 216, 48, 63, + 43, 28, 224, 142, 63, 43, 28, 218, 154, 63, 43, 28, 212, 112, 63, 43, 28, + 231, 107, 63, 43, 28, 246, 75, 63, 43, 28, 246, 139, 63, 43, 28, 229, + 121, 63, 43, 28, 209, 67, 63, 43, 28, 218, 191, 63, 43, 28, 236, 252, 63, + 43, 228, 253, 167, 246, 189, 43, 228, 253, 167, 230, 78, 43, 28, 231, + 107, 68, 228, 253, 211, 97, 97, 43, 189, 105, 43, 189, 108, 43, 189, 147, + 43, 189, 149, 43, 189, 170, 43, 189, 195, 43, 189, 213, 111, 43, 189, + 199, 43, 189, 222, 63, 43, 189, 209, 152, 43, 189, 224, 29, 43, 189, 239, + 249, 43, 189, 204, 80, 43, 189, 203, 243, 43, 189, 224, 220, 43, 189, + 241, 179, 43, 189, 210, 214, 43, 189, 211, 64, 43, 189, 237, 74, 43, 189, + 212, 9, 43, 189, 223, 84, 43, 189, 211, 213, 43, 189, 240, 4, 43, 189, + 245, 211, 43, 189, 228, 102, 43, 189, 214, 169, 43, 189, 225, 126, 43, + 189, 240, 42, 43, 189, 210, 226, 43, 189, 240, 216, 43, 189, 217, 233, + 43, 189, 250, 38, 43, 189, 230, 200, 43, 189, 216, 85, 43, 189, 245, 170, + 43, 189, 245, 160, 43, 189, 236, 244, 43, 189, 246, 217, 43, 189, 227, 0, + 43, 189, 227, 222, 43, 189, 216, 16, 43, 189, 225, 11, 43, 189, 216, 112, + 43, 189, 211, 14, 43, 189, 210, 196, 43, 189, 241, 65, 43, 189, 216, 87, + 43, 189, 251, 10, 43, 189, 222, 79, 43, 42, 209, 54, 195, 43, 42, 209, + 54, 213, 111, 43, 42, 209, 54, 199, 43, 42, 209, 54, 222, 63, 43, 42, + 239, 153, 43, 42, 239, 154, 105, 43, 42, 239, 154, 108, 43, 42, 239, 154, + 147, 43, 42, 239, 154, 149, 43, 42, 239, 154, 170, 43, 42, 239, 154, 195, + 43, 42, 239, 154, 213, 111, 43, 42, 239, 154, 199, 43, 42, 239, 154, 222, + 63, 43, 42, 240, 18, 139, 209, 164, 16, 35, 230, 171, 139, 209, 164, 16, + 35, 240, 54, 139, 209, 164, 16, 35, 225, 94, 139, 209, 164, 16, 35, 250, + 150, 139, 209, 164, 16, 35, 225, 63, 139, 209, 164, 16, 35, 230, 76, 139, + 209, 164, 16, 35, 230, 77, 139, 209, 164, 16, 35, 250, 30, 139, 209, 164, + 16, 35, 213, 129, 139, 209, 164, 16, 35, 220, 79, 139, 209, 164, 16, 35, + 221, 153, 139, 209, 164, 16, 35, 244, 70, 51, 237, 13, 51, 241, 24, 51, + 240, 226, 227, 120, 227, 147, 54, 43, 67, 63, 43, 67, 75, 43, 67, 68, 43, + 67, 74, 43, 67, 78, 43, 67, 173, 43, 67, 229, 100, 43, 67, 228, 209, 43, + 67, 229, 201, 43, 67, 229, 26, 43, 67, 215, 36, 43, 67, 212, 162, 43, 67, + 211, 10, 43, 67, 214, 177, 43, 67, 212, 13, 43, 67, 210, 22, 43, 67, 209, + 2, 43, 67, 207, 203, 43, 67, 209, 187, 43, 67, 135, 43, 67, 201, 201, 43, + 67, 222, 100, 43, 67, 221, 84, 43, 67, 222, 240, 43, 67, 221, 191, 43, + 67, 152, 43, 67, 237, 3, 43, 67, 236, 26, 43, 67, 237, 67, 43, 67, 236, + 136, 43, 67, 192, 43, 67, 224, 155, 43, 67, 223, 246, 43, 67, 225, 20, + 43, 67, 224, 82, 43, 67, 198, 43, 67, 202, 213, 43, 67, 202, 247, 43, 67, + 216, 220, 43, 67, 216, 57, 43, 67, 215, 145, 43, 67, 216, 158, 43, 67, + 215, 227, 43, 67, 204, 111, 43, 67, 204, 30, 43, 67, 204, 62, 43, 67, + 204, 0, 51, 250, 174, 51, 250, 83, 51, 250, 201, 51, 251, 239, 51, 231, + 18, 51, 230, 242, 51, 206, 227, 51, 240, 253, 51, 241, 158, 51, 220, 21, + 51, 220, 14, 51, 230, 16, 51, 229, 238, 51, 229, 235, 51, 238, 220, 51, + 238, 229, 51, 238, 70, 51, 238, 66, 51, 228, 132, 51, 238, 58, 51, 229, + 75, 51, 229, 74, 51, 229, 73, 51, 229, 72, 51, 237, 200, 51, 237, 199, + 51, 228, 180, 51, 228, 182, 51, 229, 194, 51, 228, 251, 51, 229, 3, 51, + 215, 17, 51, 214, 236, 51, 212, 92, 51, 213, 134, 51, 213, 133, 51, 244, + 209, 51, 244, 14, 51, 243, 86, 51, 208, 163, 51, 223, 79, 51, 221, 154, + 51, 237, 142, 51, 219, 163, 51, 219, 162, 51, 249, 29, 51, 218, 164, 51, + 218, 127, 51, 218, 128, 51, 248, 57, 51, 236, 24, 51, 236, 19, 51, 247, + 151, 51, 236, 4, 51, 237, 39, 51, 218, 220, 51, 219, 4, 51, 237, 22, 51, + 219, 0, 51, 219, 18, 51, 248, 145, 51, 218, 58, 51, 247, 253, 51, 236, + 120, 51, 218, 46, 51, 236, 111, 51, 236, 113, 51, 225, 138, 51, 225, 134, + 51, 225, 143, 51, 225, 83, 51, 225, 110, 51, 224, 121, 51, 224, 97, 51, + 224, 96, 51, 225, 0, 51, 224, 253, 51, 225, 1, 51, 203, 109, 51, 203, + 107, 51, 202, 202, 51, 215, 243, 51, 215, 247, 51, 215, 119, 51, 215, + 113, 51, 216, 109, 51, 216, 106, 51, 204, 78, 139, 209, 164, 16, 35, 236, + 43, 202, 84, 139, 209, 164, 16, 35, 236, 43, 105, 139, 209, 164, 16, 35, + 236, 43, 108, 139, 209, 164, 16, 35, 236, 43, 147, 139, 209, 164, 16, 35, + 236, 43, 149, 139, 209, 164, 16, 35, 236, 43, 170, 139, 209, 164, 16, 35, + 236, 43, 195, 139, 209, 164, 16, 35, 236, 43, 213, 111, 139, 209, 164, + 16, 35, 236, 43, 199, 139, 209, 164, 16, 35, 236, 43, 222, 63, 139, 209, + 164, 16, 35, 236, 43, 209, 152, 139, 209, 164, 16, 35, 236, 43, 241, 112, + 139, 209, 164, 16, 35, 236, 43, 207, 154, 139, 209, 164, 16, 35, 236, 43, + 209, 55, 139, 209, 164, 16, 35, 236, 43, 239, 141, 139, 209, 164, 16, 35, + 236, 43, 240, 22, 139, 209, 164, 16, 35, 236, 43, 212, 82, 139, 209, 164, + 16, 35, 236, 43, 213, 108, 139, 209, 164, 16, 35, 236, 43, 241, 140, 139, + 209, 164, 16, 35, 236, 43, 222, 60, 139, 209, 164, 16, 35, 236, 43, 207, + 151, 139, 209, 164, 16, 35, 236, 43, 207, 145, 139, 209, 164, 16, 35, + 236, 43, 207, 141, 139, 209, 164, 16, 35, 236, 43, 207, 142, 139, 209, + 164, 16, 35, 236, 43, 207, 147, 51, 236, 34, 51, 244, 212, 51, 250, 34, + 51, 142, 51, 219, 206, 51, 219, 39, 51, 243, 115, 51, 243, 116, 211, 176, + 51, 243, 116, 245, 105, 51, 230, 197, 51, 241, 27, 223, 85, 237, 40, 51, + 241, 27, 223, 85, 210, 92, 51, 241, 27, 223, 85, 209, 245, 51, 241, 27, + 223, 85, 224, 252, 51, 245, 162, 51, 219, 169, 250, 233, 51, 201, 201, + 51, 223, 247, 63, 51, 192, 51, 173, 51, 229, 204, 51, 225, 59, 51, 238, + 208, 51, 247, 76, 51, 229, 203, 51, 218, 211, 51, 222, 207, 51, 223, 247, + 240, 174, 51, 223, 247, 239, 75, 51, 224, 196, 51, 229, 146, 51, 235, + 215, 51, 229, 102, 51, 224, 157, 51, 238, 83, 51, 209, 4, 51, 223, 247, + 159, 51, 224, 90, 51, 243, 125, 51, 229, 41, 51, 239, 188, 51, 221, 229, + 51, 223, 247, 226, 185, 51, 224, 87, 51, 245, 255, 51, 229, 35, 51, 224, + 88, 211, 176, 51, 246, 0, 211, 176, 51, 226, 186, 211, 176, 51, 229, 36, + 211, 176, 51, 224, 88, 245, 105, 51, 246, 0, 245, 105, 51, 226, 186, 245, + 105, 51, 229, 36, 245, 105, 51, 226, 186, 115, 194, 51, 226, 186, 115, + 215, 94, 211, 176, 51, 185, 51, 228, 244, 51, 223, 250, 51, 238, 15, 51, + 216, 207, 51, 216, 208, 115, 194, 51, 216, 208, 115, 215, 94, 211, 176, + 51, 217, 204, 51, 221, 122, 51, 223, 247, 194, 51, 223, 248, 51, 217, + 154, 51, 221, 22, 51, 223, 247, 206, 164, 51, 223, 187, 51, 228, 170, 51, + 223, 188, 225, 0, 51, 217, 153, 51, 221, 21, 51, 223, 247, 204, 144, 51, + 223, 181, 51, 228, 168, 51, 223, 182, 225, 0, 51, 230, 55, 220, 58, 51, + 226, 186, 220, 58, 51, 250, 247, 51, 247, 229, 51, 247, 6, 51, 246, 239, + 51, 247, 126, 115, 229, 146, 51, 245, 254, 51, 244, 129, 51, 237, 184, + 51, 152, 51, 236, 35, 51, 231, 49, 51, 229, 48, 51, 229, 36, 247, 47, 51, + 228, 211, 51, 227, 52, 51, 227, 51, 51, 227, 38, 51, 226, 200, 51, 225, + 60, 212, 36, 51, 224, 120, 51, 224, 56, 51, 218, 209, 51, 218, 72, 51, + 218, 11, 51, 218, 9, 51, 211, 168, 51, 210, 177, 51, 204, 64, 51, 206, + 165, 115, 226, 185, 51, 34, 115, 226, 185, 139, 209, 164, 16, 35, 244, + 133, 105, 139, 209, 164, 16, 35, 244, 133, 108, 139, 209, 164, 16, 35, + 244, 133, 147, 139, 209, 164, 16, 35, 244, 133, 149, 139, 209, 164, 16, + 35, 244, 133, 170, 139, 209, 164, 16, 35, 244, 133, 195, 139, 209, 164, + 16, 35, 244, 133, 213, 111, 139, 209, 164, 16, 35, 244, 133, 199, 139, + 209, 164, 16, 35, 244, 133, 222, 63, 139, 209, 164, 16, 35, 244, 133, + 209, 152, 139, 209, 164, 16, 35, 244, 133, 241, 112, 139, 209, 164, 16, + 35, 244, 133, 207, 154, 139, 209, 164, 16, 35, 244, 133, 209, 55, 139, + 209, 164, 16, 35, 244, 133, 239, 141, 139, 209, 164, 16, 35, 244, 133, + 240, 22, 139, 209, 164, 16, 35, 244, 133, 212, 82, 139, 209, 164, 16, 35, + 244, 133, 213, 108, 139, 209, 164, 16, 35, 244, 133, 241, 140, 139, 209, + 164, 16, 35, 244, 133, 222, 60, 139, 209, 164, 16, 35, 244, 133, 207, + 151, 139, 209, 164, 16, 35, 244, 133, 207, 145, 139, 209, 164, 16, 35, + 244, 133, 207, 141, 139, 209, 164, 16, 35, 244, 133, 207, 142, 139, 209, + 164, 16, 35, 244, 133, 207, 147, 139, 209, 164, 16, 35, 244, 133, 207, + 148, 139, 209, 164, 16, 35, 244, 133, 207, 143, 139, 209, 164, 16, 35, + 244, 133, 207, 144, 139, 209, 164, 16, 35, 244, 133, 207, 150, 139, 209, + 164, 16, 35, 244, 133, 207, 146, 139, 209, 164, 16, 35, 244, 133, 209, + 53, 139, 209, 164, 16, 35, 244, 133, 209, 52, 51, 238, 246, 237, 16, 35, + 209, 93, 245, 142, 237, 51, 237, 16, 35, 209, 93, 216, 151, 241, 179, + 237, 16, 35, 243, 203, 250, 50, 209, 93, 248, 140, 237, 16, 35, 202, 226, + 239, 180, 237, 16, 35, 204, 103, 237, 16, 35, 245, 214, 237, 16, 35, 209, + 93, 250, 105, 237, 16, 35, 236, 127, 208, 169, 237, 16, 35, 5, 209, 231, + 237, 16, 35, 208, 97, 237, 16, 35, 219, 32, 237, 16, 35, 211, 96, 237, + 16, 35, 240, 44, 237, 16, 35, 237, 249, 218, 32, 237, 16, 35, 224, 75, + 237, 16, 35, 241, 64, 237, 16, 35, 239, 181, 237, 16, 35, 203, 236, 220, + 32, 209, 93, 244, 71, 237, 16, 35, 250, 154, 237, 16, 35, 245, 193, 237, + 16, 35, 248, 49, 209, 24, 237, 16, 35, 238, 13, 237, 16, 35, 211, 192, + 250, 173, 237, 16, 35, 216, 77, 237, 16, 35, 231, 12, 237, 16, 35, 237, + 249, 209, 231, 237, 16, 35, 224, 8, 245, 164, 237, 16, 35, 237, 249, 217, + 244, 237, 16, 35, 209, 93, 251, 143, 204, 80, 237, 16, 35, 209, 93, 246, + 24, 239, 249, 237, 16, 35, 231, 26, 237, 16, 35, 242, 20, 237, 16, 35, + 216, 80, 237, 16, 35, 237, 249, 218, 16, 237, 16, 35, 217, 221, 237, 16, + 35, 244, 149, 76, 209, 93, 227, 134, 237, 16, 35, 209, 93, 240, 82, 237, + 16, 35, 219, 250, 237, 16, 35, 220, 85, 237, 16, 35, 244, 42, 237, 16, + 35, 244, 63, 237, 16, 35, 231, 40, 237, 16, 35, 247, 217, 237, 16, 35, + 245, 235, 208, 173, 225, 3, 237, 16, 35, 238, 215, 208, 169, 237, 16, 35, + 217, 163, 206, 213, 237, 16, 35, 219, 249, 237, 16, 35, 209, 93, 204, 50, + 237, 16, 35, 216, 68, 237, 16, 35, 209, 93, 247, 12, 237, 16, 35, 209, + 93, 250, 101, 209, 18, 237, 16, 35, 209, 93, 229, 195, 211, 68, 224, 12, + 237, 16, 35, 244, 9, 237, 16, 35, 209, 93, 225, 85, 225, 139, 237, 16, + 35, 251, 144, 237, 16, 35, 209, 93, 204, 96, 237, 16, 35, 209, 93, 238, + 173, 204, 16, 237, 16, 35, 209, 93, 230, 84, 228, 33, 237, 16, 35, 243, + 153, 237, 16, 35, 227, 121, 237, 16, 35, 231, 15, 208, 24, 237, 16, 35, + 5, 217, 244, 237, 16, 35, 251, 82, 245, 226, 237, 16, 35, 248, 143, 245, + 226, 11, 4, 230, 201, 11, 4, 230, 193, 11, 4, 75, 11, 4, 230, 227, 11, 4, + 231, 108, 11, 4, 231, 91, 11, 4, 231, 110, 11, 4, 231, 109, 11, 4, 250, + 49, 11, 4, 250, 10, 11, 4, 63, 11, 4, 250, 175, 11, 4, 206, 225, 11, 4, + 206, 228, 11, 4, 206, 226, 11, 4, 219, 224, 11, 4, 219, 193, 11, 4, 78, + 11, 4, 220, 9, 11, 4, 240, 217, 11, 4, 74, 11, 4, 203, 217, 11, 4, 248, + 51, 11, 4, 248, 47, 11, 4, 248, 86, 11, 4, 248, 61, 11, 4, 248, 75, 11, + 4, 248, 74, 11, 4, 248, 77, 11, 4, 248, 76, 11, 4, 248, 209, 11, 4, 248, + 201, 11, 4, 249, 32, 11, 4, 248, 232, 11, 4, 247, 163, 11, 4, 247, 167, + 11, 4, 247, 164, 11, 4, 247, 252, 11, 4, 247, 233, 11, 4, 248, 23, 11, 4, + 248, 2, 11, 4, 248, 101, 11, 4, 248, 162, 11, 4, 248, 113, 11, 4, 247, + 147, 11, 4, 247, 143, 11, 4, 247, 193, 11, 4, 247, 162, 11, 4, 247, 155, + 11, 4, 247, 160, 11, 4, 247, 131, 11, 4, 247, 129, 11, 4, 247, 136, 11, + 4, 247, 134, 11, 4, 247, 132, 11, 4, 247, 133, 11, 4, 218, 105, 11, 4, + 218, 101, 11, 4, 218, 167, 11, 4, 218, 117, 11, 4, 218, 133, 11, 4, 218, + 160, 11, 4, 218, 156, 11, 4, 219, 55, 11, 4, 219, 44, 11, 4, 185, 11, 4, + 219, 96, 11, 4, 217, 173, 11, 4, 217, 175, 11, 4, 217, 174, 11, 4, 218, + 25, 11, 4, 218, 14, 11, 4, 218, 69, 11, 4, 218, 41, 11, 4, 217, 159, 11, + 4, 217, 155, 11, 4, 217, 191, 11, 4, 217, 172, 11, 4, 217, 164, 11, 4, + 217, 170, 11, 4, 217, 138, 11, 4, 217, 137, 11, 4, 217, 142, 11, 4, 217, + 141, 11, 4, 217, 139, 11, 4, 217, 140, 11, 4, 248, 183, 11, 4, 248, 182, + 11, 4, 248, 189, 11, 4, 248, 184, 11, 4, 248, 186, 11, 4, 248, 185, 11, + 4, 248, 188, 11, 4, 248, 187, 11, 4, 248, 195, 11, 4, 248, 194, 11, 4, + 248, 198, 11, 4, 248, 196, 11, 4, 248, 174, 11, 4, 248, 176, 11, 4, 248, + 175, 11, 4, 248, 179, 11, 4, 248, 178, 11, 4, 248, 181, 11, 4, 248, 180, + 11, 4, 248, 190, 11, 4, 248, 193, 11, 4, 248, 191, 11, 4, 248, 170, 11, + 4, 248, 169, 11, 4, 248, 177, 11, 4, 248, 173, 11, 4, 248, 171, 11, 4, + 248, 172, 11, 4, 248, 166, 11, 4, 248, 165, 11, 4, 248, 168, 11, 4, 248, + 167, 11, 4, 223, 47, 11, 4, 223, 46, 11, 4, 223, 52, 11, 4, 223, 48, 11, + 4, 223, 49, 11, 4, 223, 51, 11, 4, 223, 50, 11, 4, 223, 55, 11, 4, 223, + 54, 11, 4, 223, 57, 11, 4, 223, 56, 11, 4, 223, 43, 11, 4, 223, 42, 11, + 4, 223, 45, 11, 4, 223, 44, 11, 4, 223, 36, 11, 4, 223, 35, 11, 4, 223, + 40, 11, 4, 223, 39, 11, 4, 223, 37, 11, 4, 223, 38, 11, 4, 223, 30, 11, + 4, 223, 29, 11, 4, 223, 34, 11, 4, 223, 33, 11, 4, 223, 31, 11, 4, 223, + 32, 11, 4, 236, 180, 11, 4, 236, 179, 11, 4, 236, 185, 11, 4, 236, 181, + 11, 4, 236, 182, 11, 4, 236, 184, 11, 4, 236, 183, 11, 4, 236, 188, 11, + 4, 236, 187, 11, 4, 236, 190, 11, 4, 236, 189, 11, 4, 236, 171, 11, 4, + 236, 173, 11, 4, 236, 172, 11, 4, 236, 176, 11, 4, 236, 175, 11, 4, 236, + 178, 11, 4, 236, 177, 11, 4, 236, 167, 11, 4, 236, 166, 11, 4, 236, 174, + 11, 4, 236, 170, 11, 4, 236, 168, 11, 4, 236, 169, 11, 4, 236, 161, 11, + 4, 236, 165, 11, 4, 236, 164, 11, 4, 236, 162, 11, 4, 236, 163, 11, 4, + 224, 93, 11, 4, 224, 92, 11, 4, 224, 155, 11, 4, 224, 99, 11, 4, 224, + 127, 11, 4, 224, 145, 11, 4, 224, 143, 11, 4, 225, 71, 11, 4, 225, 66, + 11, 4, 192, 11, 4, 225, 106, 11, 4, 223, 213, 11, 4, 223, 212, 11, 4, + 223, 216, 11, 4, 223, 214, 11, 4, 224, 21, 11, 4, 223, 252, 11, 4, 224, + 82, 11, 4, 224, 27, 11, 4, 224, 207, 11, 4, 225, 20, 11, 4, 223, 193, 11, + 4, 223, 189, 11, 4, 223, 246, 11, 4, 223, 209, 11, 4, 223, 202, 11, 4, + 223, 207, 11, 4, 223, 166, 11, 4, 223, 165, 11, 4, 223, 171, 11, 4, 223, + 168, 11, 4, 239, 236, 11, 4, 239, 230, 11, 4, 240, 26, 11, 4, 239, 251, + 11, 4, 240, 73, 11, 4, 240, 64, 11, 4, 240, 108, 11, 4, 240, 78, 11, 4, + 239, 139, 11, 4, 239, 186, 11, 4, 239, 167, 11, 4, 239, 91, 11, 4, 239, + 90, 11, 4, 239, 108, 11, 4, 239, 96, 11, 4, 239, 94, 11, 4, 239, 95, 11, + 4, 239, 78, 11, 4, 239, 77, 11, 4, 239, 81, 11, 4, 239, 79, 11, 4, 205, + 196, 11, 4, 205, 191, 11, 4, 205, 230, 11, 4, 205, 205, 11, 4, 205, 219, + 11, 4, 205, 216, 11, 4, 205, 222, 11, 4, 205, 221, 11, 4, 206, 63, 11, 4, + 206, 58, 11, 4, 206, 86, 11, 4, 206, 75, 11, 4, 205, 172, 11, 4, 205, + 168, 11, 4, 205, 189, 11, 4, 205, 174, 11, 4, 205, 233, 11, 4, 206, 44, + 11, 4, 204, 157, 11, 4, 204, 155, 11, 4, 204, 163, 11, 4, 204, 160, 11, + 4, 204, 158, 11, 4, 204, 159, 11, 4, 204, 148, 11, 4, 204, 147, 11, 4, + 204, 152, 11, 4, 204, 151, 11, 4, 204, 149, 11, 4, 204, 150, 11, 4, 243, + 147, 11, 4, 243, 134, 11, 4, 243, 233, 11, 4, 243, 173, 11, 4, 243, 208, + 11, 4, 243, 213, 11, 4, 243, 212, 11, 4, 244, 140, 11, 4, 244, 134, 11, + 4, 244, 212, 11, 4, 244, 160, 11, 4, 242, 25, 11, 4, 242, 26, 11, 4, 243, + 85, 11, 4, 242, 67, 11, 4, 243, 113, 11, 4, 243, 87, 11, 4, 244, 7, 11, + 4, 244, 75, 11, 4, 244, 28, 11, 4, 242, 16, 11, 4, 242, 14, 11, 4, 242, + 42, 11, 4, 242, 24, 11, 4, 242, 19, 11, 4, 242, 22, 11, 4, 208, 200, 11, + 4, 208, 192, 11, 4, 209, 2, 11, 4, 208, 210, 11, 4, 208, 248, 11, 4, 208, + 250, 11, 4, 208, 249, 11, 4, 209, 212, 11, 4, 209, 198, 11, 4, 210, 22, + 11, 4, 209, 222, 11, 4, 207, 185, 11, 4, 207, 184, 11, 4, 207, 187, 11, + 4, 207, 186, 11, 4, 208, 131, 11, 4, 208, 121, 11, 4, 135, 11, 4, 208, + 144, 11, 4, 209, 114, 11, 4, 209, 187, 11, 4, 209, 139, 11, 4, 207, 168, + 11, 4, 207, 163, 11, 4, 207, 203, 11, 4, 207, 183, 11, 4, 207, 169, 11, + 4, 207, 181, 11, 4, 244, 92, 11, 4, 244, 91, 11, 4, 244, 97, 11, 4, 244, + 93, 11, 4, 244, 94, 11, 4, 244, 96, 11, 4, 244, 95, 11, 4, 244, 113, 11, + 4, 244, 112, 11, 4, 244, 120, 11, 4, 244, 114, 11, 4, 244, 82, 11, 4, + 244, 84, 11, 4, 244, 83, 11, 4, 244, 87, 11, 4, 244, 86, 11, 4, 244, 90, + 11, 4, 244, 88, 11, 4, 244, 105, 11, 4, 244, 108, 11, 4, 244, 106, 11, 4, + 244, 78, 11, 4, 244, 77, 11, 4, 244, 85, 11, 4, 244, 81, 11, 4, 244, 79, + 11, 4, 244, 80, 11, 4, 223, 3, 11, 4, 223, 2, 11, 4, 223, 10, 11, 4, 223, + 5, 11, 4, 223, 6, 11, 4, 223, 7, 11, 4, 223, 19, 11, 4, 223, 18, 11, 4, + 223, 25, 11, 4, 223, 20, 11, 4, 222, 251, 11, 4, 222, 250, 11, 4, 223, 1, + 11, 4, 222, 252, 11, 4, 223, 11, 11, 4, 223, 17, 11, 4, 223, 15, 11, 4, + 222, 243, 11, 4, 222, 242, 11, 4, 222, 248, 11, 4, 222, 246, 11, 4, 222, + 244, 11, 4, 222, 245, 11, 4, 236, 146, 11, 4, 236, 145, 11, 4, 236, 152, + 11, 4, 236, 147, 11, 4, 236, 149, 11, 4, 236, 148, 11, 4, 236, 151, 11, + 4, 236, 150, 11, 4, 236, 158, 11, 4, 236, 156, 11, 4, 236, 160, 11, 4, + 236, 159, 11, 4, 236, 139, 11, 4, 236, 140, 11, 4, 236, 143, 11, 4, 236, + 142, 11, 4, 236, 144, 11, 4, 236, 153, 11, 4, 236, 155, 11, 4, 236, 154, + 11, 4, 236, 138, 11, 4, 222, 52, 11, 4, 222, 50, 11, 4, 222, 100, 11, 4, + 222, 55, 11, 4, 222, 82, 11, 4, 222, 96, 11, 4, 222, 95, 11, 4, 223, 61, + 11, 4, 201, 201, 11, 4, 223, 76, 11, 4, 221, 32, 11, 4, 221, 34, 11, 4, + 221, 33, 11, 4, 221, 165, 11, 4, 221, 150, 11, 4, 221, 191, 11, 4, 221, + 176, 11, 4, 222, 209, 11, 4, 222, 240, 11, 4, 222, 225, 11, 4, 221, 27, + 11, 4, 221, 23, 11, 4, 221, 84, 11, 4, 221, 31, 11, 4, 221, 29, 11, 4, + 221, 30, 11, 4, 236, 211, 11, 4, 236, 210, 11, 4, 236, 216, 11, 4, 236, + 212, 11, 4, 236, 213, 11, 4, 236, 215, 11, 4, 236, 214, 11, 4, 236, 222, + 11, 4, 236, 220, 11, 4, 236, 224, 11, 4, 236, 223, 11, 4, 236, 203, 11, + 4, 236, 205, 11, 4, 236, 204, 11, 4, 236, 207, 11, 4, 236, 209, 11, 4, + 236, 208, 11, 4, 236, 217, 11, 4, 236, 219, 11, 4, 236, 218, 11, 4, 236, + 199, 11, 4, 236, 198, 11, 4, 236, 206, 11, 4, 236, 202, 11, 4, 236, 200, + 11, 4, 236, 201, 11, 4, 236, 193, 11, 4, 236, 192, 11, 4, 236, 197, 11, + 4, 236, 196, 11, 4, 236, 194, 11, 4, 236, 195, 11, 4, 227, 90, 11, 4, + 227, 82, 11, 4, 227, 148, 11, 4, 227, 100, 11, 4, 227, 139, 11, 4, 227, + 138, 11, 4, 227, 142, 11, 4, 227, 140, 11, 4, 228, 0, 11, 4, 227, 245, + 11, 4, 228, 113, 11, 4, 228, 11, 11, 4, 226, 217, 11, 4, 226, 216, 11, 4, + 226, 219, 11, 4, 226, 218, 11, 4, 227, 6, 11, 4, 226, 248, 11, 4, 227, + 49, 11, 4, 227, 11, 11, 4, 227, 165, 11, 4, 227, 234, 11, 4, 227, 182, + 11, 4, 226, 211, 11, 4, 226, 209, 11, 4, 226, 239, 11, 4, 226, 215, 11, + 4, 226, 213, 11, 4, 226, 214, 11, 4, 226, 190, 11, 4, 226, 189, 11, 4, + 226, 199, 11, 4, 226, 193, 11, 4, 226, 191, 11, 4, 226, 192, 11, 4, 238, + 54, 11, 4, 238, 53, 11, 4, 238, 81, 11, 4, 238, 65, 11, 4, 238, 73, 11, + 4, 238, 72, 11, 4, 238, 75, 11, 4, 238, 74, 11, 4, 238, 217, 11, 4, 238, + 212, 11, 4, 239, 8, 11, 4, 238, 227, 11, 4, 237, 205, 11, 4, 237, 204, + 11, 4, 237, 207, 11, 4, 237, 206, 11, 4, 238, 18, 11, 4, 238, 16, 11, 4, + 238, 39, 11, 4, 238, 26, 11, 4, 238, 159, 11, 4, 238, 157, 11, 4, 238, + 190, 11, 4, 238, 170, 11, 4, 237, 194, 11, 4, 237, 193, 11, 4, 237, 230, + 11, 4, 237, 203, 11, 4, 237, 195, 11, 4, 237, 202, 11, 4, 229, 64, 11, 4, + 229, 61, 11, 4, 229, 100, 11, 4, 229, 78, 11, 4, 229, 89, 11, 4, 229, 93, + 11, 4, 229, 91, 11, 4, 229, 226, 11, 4, 229, 209, 11, 4, 173, 11, 4, 229, + 253, 11, 4, 228, 187, 11, 4, 228, 192, 11, 4, 228, 189, 11, 4, 228, 250, + 11, 4, 228, 245, 11, 4, 229, 26, 11, 4, 229, 1, 11, 4, 229, 170, 11, 4, + 229, 153, 11, 4, 229, 201, 11, 4, 229, 174, 11, 4, 228, 175, 11, 4, 228, + 171, 11, 4, 228, 209, 11, 4, 228, 186, 11, 4, 228, 179, 11, 4, 228, 183, + 11, 4, 238, 141, 11, 4, 238, 140, 11, 4, 238, 145, 11, 4, 238, 142, 11, + 4, 238, 144, 11, 4, 238, 143, 11, 4, 238, 152, 11, 4, 238, 151, 11, 4, + 238, 155, 11, 4, 238, 153, 11, 4, 238, 132, 11, 4, 238, 131, 11, 4, 238, + 134, 11, 4, 238, 133, 11, 4, 238, 137, 11, 4, 238, 136, 11, 4, 238, 139, + 11, 4, 238, 138, 11, 4, 238, 147, 11, 4, 238, 146, 11, 4, 238, 150, 11, + 4, 238, 148, 11, 4, 238, 127, 11, 4, 238, 126, 11, 4, 238, 135, 11, 4, + 238, 130, 11, 4, 238, 128, 11, 4, 238, 129, 11, 4, 224, 174, 11, 4, 224, + 175, 11, 4, 224, 193, 11, 4, 224, 192, 11, 4, 224, 195, 11, 4, 224, 194, + 11, 4, 224, 165, 11, 4, 224, 167, 11, 4, 224, 166, 11, 4, 224, 170, 11, + 4, 224, 169, 11, 4, 224, 172, 11, 4, 224, 171, 11, 4, 224, 176, 11, 4, + 224, 178, 11, 4, 224, 177, 11, 4, 224, 161, 11, 4, 224, 160, 11, 4, 224, + 168, 11, 4, 224, 164, 11, 4, 224, 162, 11, 4, 224, 163, 11, 4, 235, 233, + 11, 4, 235, 232, 11, 4, 235, 239, 11, 4, 235, 234, 11, 4, 235, 236, 11, + 4, 235, 235, 11, 4, 235, 238, 11, 4, 235, 237, 11, 4, 235, 244, 11, 4, + 235, 243, 11, 4, 235, 246, 11, 4, 235, 245, 11, 4, 235, 225, 11, 4, 235, + 224, 11, 4, 235, 227, 11, 4, 235, 226, 11, 4, 235, 229, 11, 4, 235, 228, + 11, 4, 235, 231, 11, 4, 235, 230, 11, 4, 235, 240, 11, 4, 235, 242, 11, + 4, 235, 241, 11, 4, 222, 148, 11, 4, 222, 150, 11, 4, 222, 149, 11, 4, + 222, 193, 11, 4, 222, 191, 11, 4, 222, 203, 11, 4, 222, 196, 11, 4, 222, + 110, 11, 4, 222, 109, 11, 4, 222, 111, 11, 4, 222, 120, 11, 4, 222, 117, + 11, 4, 222, 128, 11, 4, 222, 122, 11, 4, 222, 184, 11, 4, 222, 190, 11, + 4, 222, 186, 11, 4, 236, 230, 11, 4, 236, 245, 11, 4, 236, 254, 11, 4, + 237, 83, 11, 4, 237, 72, 11, 4, 152, 11, 4, 237, 94, 11, 4, 236, 6, 11, + 4, 236, 5, 11, 4, 236, 8, 11, 4, 236, 7, 11, 4, 236, 46, 11, 4, 236, 37, + 11, 4, 236, 136, 11, 4, 236, 109, 11, 4, 237, 18, 11, 4, 237, 67, 11, 4, + 237, 30, 11, 4, 204, 83, 11, 4, 204, 68, 11, 4, 204, 111, 11, 4, 204, 93, + 11, 4, 203, 206, 11, 4, 203, 208, 11, 4, 203, 207, 11, 4, 203, 229, 11, + 4, 204, 0, 11, 4, 203, 239, 11, 4, 204, 42, 11, 4, 204, 62, 11, 4, 204, + 47, 11, 4, 202, 24, 11, 4, 202, 23, 11, 4, 202, 39, 11, 4, 202, 27, 11, + 4, 202, 32, 11, 4, 202, 34, 11, 4, 202, 33, 11, 4, 202, 100, 11, 4, 202, + 97, 11, 4, 202, 116, 11, 4, 202, 104, 11, 4, 201, 255, 11, 4, 202, 1, 11, + 4, 202, 0, 11, 4, 202, 13, 11, 4, 202, 12, 11, 4, 202, 17, 11, 4, 202, + 14, 11, 4, 202, 82, 11, 4, 202, 92, 11, 4, 202, 86, 11, 4, 201, 251, 11, + 4, 201, 250, 11, 4, 202, 6, 11, 4, 201, 254, 11, 4, 201, 252, 11, 4, 201, + 253, 11, 4, 201, 237, 11, 4, 201, 236, 11, 4, 201, 242, 11, 4, 201, 240, + 11, 4, 201, 238, 11, 4, 201, 239, 11, 4, 246, 50, 11, 4, 246, 43, 11, 4, + 246, 79, 11, 4, 246, 63, 11, 4, 246, 76, 11, 4, 246, 70, 11, 4, 246, 78, + 11, 4, 246, 77, 11, 4, 247, 17, 11, 4, 247, 9, 11, 4, 247, 92, 11, 4, + 247, 48, 11, 4, 245, 101, 11, 4, 245, 103, 11, 4, 245, 102, 11, 4, 245, + 158, 11, 4, 245, 148, 11, 4, 245, 254, 11, 4, 245, 175, 11, 4, 246, 202, + 11, 4, 246, 238, 11, 4, 246, 207, 11, 4, 245, 77, 11, 4, 245, 75, 11, 4, + 245, 110, 11, 4, 245, 99, 11, 4, 245, 83, 11, 4, 245, 96, 11, 4, 245, 54, + 11, 4, 245, 53, 11, 4, 245, 66, 11, 4, 245, 60, 11, 4, 245, 55, 11, 4, + 245, 57, 11, 4, 201, 220, 11, 4, 201, 219, 11, 4, 201, 226, 11, 4, 201, + 221, 11, 4, 201, 223, 11, 4, 201, 222, 11, 4, 201, 225, 11, 4, 201, 224, + 11, 4, 201, 232, 11, 4, 201, 231, 11, 4, 201, 235, 11, 4, 201, 233, 11, + 4, 201, 216, 11, 4, 201, 218, 11, 4, 201, 217, 11, 4, 201, 227, 11, 4, + 201, 230, 11, 4, 201, 228, 11, 4, 201, 209, 11, 4, 201, 213, 11, 4, 201, + 212, 11, 4, 201, 210, 11, 4, 201, 211, 11, 4, 201, 203, 11, 4, 201, 202, + 11, 4, 201, 208, 11, 4, 201, 206, 11, 4, 201, 204, 11, 4, 201, 205, 11, + 4, 220, 201, 11, 4, 220, 200, 11, 4, 220, 206, 11, 4, 220, 202, 11, 4, + 220, 203, 11, 4, 220, 205, 11, 4, 220, 204, 11, 4, 220, 211, 11, 4, 220, + 210, 11, 4, 220, 214, 11, 4, 220, 213, 11, 4, 220, 194, 11, 4, 220, 195, + 11, 4, 220, 198, 11, 4, 220, 199, 11, 4, 220, 207, 11, 4, 220, 209, 11, + 4, 220, 189, 11, 4, 220, 197, 11, 4, 220, 193, 11, 4, 220, 190, 11, 4, + 220, 191, 11, 4, 220, 184, 11, 4, 220, 183, 11, 4, 220, 188, 11, 4, 220, + 187, 11, 4, 220, 185, 11, 4, 220, 186, 11, 4, 212, 90, 11, 4, 195, 11, 4, + 212, 162, 11, 4, 212, 93, 11, 4, 212, 150, 11, 4, 212, 153, 11, 4, 212, + 151, 11, 4, 214, 225, 11, 4, 214, 211, 11, 4, 215, 36, 11, 4, 214, 233, + 11, 4, 210, 204, 11, 4, 210, 206, 11, 4, 210, 205, 11, 4, 211, 244, 11, + 4, 211, 233, 11, 4, 212, 13, 11, 4, 211, 248, 11, 4, 213, 103, 11, 4, + 214, 177, 11, 4, 213, 132, 11, 4, 210, 181, 11, 4, 210, 178, 11, 4, 211, + 10, 11, 4, 210, 203, 11, 4, 210, 185, 11, 4, 210, 193, 11, 4, 210, 83, + 11, 4, 210, 82, 11, 4, 210, 151, 11, 4, 210, 91, 11, 4, 210, 85, 11, 4, + 210, 90, 11, 4, 211, 126, 11, 4, 211, 125, 11, 4, 211, 132, 11, 4, 211, + 127, 11, 4, 211, 129, 11, 4, 211, 131, 11, 4, 211, 130, 11, 4, 211, 141, + 11, 4, 211, 139, 11, 4, 211, 164, 11, 4, 211, 142, 11, 4, 211, 121, 11, + 4, 211, 120, 11, 4, 211, 124, 11, 4, 211, 122, 11, 4, 211, 135, 11, 4, + 211, 138, 11, 4, 211, 136, 11, 4, 211, 117, 11, 4, 211, 115, 11, 4, 211, + 119, 11, 4, 211, 118, 11, 4, 211, 110, 11, 4, 211, 109, 11, 4, 211, 114, + 11, 4, 211, 113, 11, 4, 211, 111, 11, 4, 211, 112, 11, 4, 202, 75, 11, 4, + 202, 74, 11, 4, 202, 80, 11, 4, 202, 77, 11, 4, 202, 54, 11, 4, 202, 56, + 11, 4, 202, 55, 11, 4, 202, 59, 11, 4, 202, 58, 11, 4, 202, 63, 11, 4, + 202, 60, 11, 4, 202, 68, 11, 4, 202, 67, 11, 4, 202, 71, 11, 4, 202, 69, + 11, 4, 202, 50, 11, 4, 202, 49, 11, 4, 202, 57, 11, 4, 202, 53, 11, 4, + 202, 51, 11, 4, 202, 52, 11, 4, 202, 42, 11, 4, 202, 41, 11, 4, 202, 46, + 11, 4, 202, 45, 11, 4, 202, 43, 11, 4, 202, 44, 11, 4, 246, 176, 11, 4, + 246, 172, 11, 4, 246, 199, 11, 4, 246, 185, 11, 4, 246, 94, 11, 4, 246, + 93, 11, 4, 246, 96, 11, 4, 246, 95, 11, 4, 246, 109, 11, 4, 246, 108, 11, + 4, 246, 116, 11, 4, 246, 111, 11, 4, 246, 147, 11, 4, 246, 145, 11, 4, + 246, 170, 11, 4, 246, 155, 11, 4, 246, 88, 11, 4, 246, 98, 11, 4, 246, + 92, 11, 4, 246, 89, 11, 4, 246, 91, 11, 4, 246, 81, 11, 4, 246, 80, 11, + 4, 246, 85, 11, 4, 246, 84, 11, 4, 246, 82, 11, 4, 246, 83, 11, 4, 215, + 181, 11, 4, 215, 185, 11, 4, 215, 163, 11, 4, 215, 164, 11, 4, 215, 168, + 11, 4, 215, 167, 11, 4, 215, 171, 11, 4, 215, 169, 11, 4, 215, 175, 11, + 4, 215, 174, 11, 4, 215, 180, 11, 4, 215, 176, 11, 4, 215, 159, 11, 4, + 215, 157, 11, 4, 215, 165, 11, 4, 215, 162, 11, 4, 215, 160, 11, 4, 215, + 161, 11, 4, 215, 152, 11, 4, 215, 151, 11, 4, 215, 156, 11, 4, 215, 155, + 11, 4, 215, 153, 11, 4, 215, 154, 11, 4, 221, 145, 11, 4, 221, 144, 11, + 4, 221, 147, 11, 4, 221, 146, 11, 4, 221, 136, 11, 4, 221, 138, 11, 4, + 221, 137, 11, 4, 221, 140, 11, 4, 221, 139, 11, 4, 221, 143, 11, 4, 221, + 142, 11, 4, 221, 130, 11, 4, 221, 129, 11, 4, 221, 135, 11, 4, 221, 133, + 11, 4, 221, 131, 11, 4, 221, 132, 11, 4, 221, 124, 11, 4, 221, 123, 11, + 4, 221, 128, 11, 4, 221, 127, 11, 4, 221, 125, 11, 4, 221, 126, 11, 4, + 213, 53, 11, 4, 213, 48, 11, 4, 213, 90, 11, 4, 213, 64, 11, 4, 212, 188, + 11, 4, 212, 190, 11, 4, 212, 189, 11, 4, 212, 212, 11, 4, 212, 208, 11, + 4, 212, 242, 11, 4, 212, 232, 11, 4, 213, 21, 11, 4, 213, 14, 11, 4, 213, + 43, 11, 4, 213, 30, 11, 4, 212, 184, 11, 4, 212, 181, 11, 4, 212, 199, + 11, 4, 212, 187, 11, 4, 212, 185, 11, 4, 212, 186, 11, 4, 212, 165, 11, + 4, 212, 164, 11, 4, 212, 171, 11, 4, 212, 168, 11, 4, 212, 166, 11, 4, + 212, 167, 11, 4, 216, 172, 11, 4, 216, 166, 11, 4, 216, 220, 11, 4, 216, + 178, 11, 4, 215, 122, 11, 4, 215, 124, 11, 4, 215, 123, 11, 4, 215, 199, + 11, 4, 215, 187, 11, 4, 215, 227, 11, 4, 215, 203, 11, 4, 216, 66, 11, 4, + 216, 158, 11, 4, 216, 105, 11, 4, 215, 115, 11, 4, 215, 112, 11, 4, 215, + 145, 11, 4, 215, 121, 11, 4, 215, 117, 11, 4, 215, 118, 11, 4, 215, 97, + 11, 4, 215, 96, 11, 4, 215, 102, 11, 4, 215, 100, 11, 4, 215, 98, 11, 4, + 215, 99, 11, 4, 230, 131, 11, 4, 230, 130, 11, 4, 230, 141, 11, 4, 230, + 132, 11, 4, 230, 137, 11, 4, 230, 136, 11, 4, 230, 139, 11, 4, 230, 138, + 11, 4, 230, 72, 11, 4, 230, 71, 11, 4, 230, 74, 11, 4, 230, 73, 11, 4, + 230, 88, 11, 4, 230, 86, 11, 4, 230, 101, 11, 4, 230, 90, 11, 4, 230, 65, + 11, 4, 230, 63, 11, 4, 230, 82, 11, 4, 230, 70, 11, 4, 230, 67, 11, 4, + 230, 68, 11, 4, 230, 57, 11, 4, 230, 56, 11, 4, 230, 61, 11, 4, 230, 60, + 11, 4, 230, 58, 11, 4, 230, 59, 11, 4, 217, 81, 11, 4, 217, 79, 11, 4, + 217, 88, 11, 4, 217, 82, 11, 4, 217, 85, 11, 4, 217, 84, 11, 4, 217, 87, + 11, 4, 217, 86, 11, 4, 217, 32, 11, 4, 217, 29, 11, 4, 217, 34, 11, 4, + 217, 33, 11, 4, 217, 68, 11, 4, 217, 67, 11, 4, 217, 77, 11, 4, 217, 71, + 11, 4, 217, 24, 11, 4, 217, 20, 11, 4, 217, 65, 11, 4, 217, 28, 11, 4, + 217, 26, 11, 4, 217, 27, 11, 4, 217, 4, 11, 4, 217, 2, 11, 4, 217, 14, + 11, 4, 217, 7, 11, 4, 217, 5, 11, 4, 217, 6, 11, 4, 230, 120, 11, 4, 230, + 119, 11, 4, 230, 126, 11, 4, 230, 121, 11, 4, 230, 123, 11, 4, 230, 122, + 11, 4, 230, 125, 11, 4, 230, 124, 11, 4, 230, 111, 11, 4, 230, 113, 11, + 4, 230, 112, 11, 4, 230, 116, 11, 4, 230, 115, 11, 4, 230, 118, 11, 4, + 230, 117, 11, 4, 230, 107, 11, 4, 230, 106, 11, 4, 230, 114, 11, 4, 230, + 110, 11, 4, 230, 108, 11, 4, 230, 109, 11, 4, 230, 103, 11, 4, 230, 102, + 11, 4, 230, 105, 11, 4, 230, 104, 11, 4, 222, 25, 11, 4, 222, 24, 11, 4, + 222, 32, 11, 4, 222, 26, 11, 4, 222, 28, 11, 4, 222, 27, 11, 4, 222, 31, + 11, 4, 222, 29, 11, 4, 222, 14, 11, 4, 222, 15, 11, 4, 222, 20, 11, 4, + 222, 19, 11, 4, 222, 23, 11, 4, 222, 21, 11, 4, 222, 9, 11, 4, 222, 18, + 11, 4, 222, 13, 11, 4, 222, 10, 11, 4, 222, 11, 11, 4, 222, 4, 11, 4, + 222, 3, 11, 4, 222, 8, 11, 4, 222, 7, 11, 4, 222, 5, 11, 4, 222, 6, 11, + 4, 220, 236, 11, 4, 220, 235, 11, 4, 220, 248, 11, 4, 220, 240, 11, 4, + 220, 245, 11, 4, 220, 244, 11, 4, 220, 247, 11, 4, 220, 246, 11, 4, 220, + 221, 11, 4, 220, 223, 11, 4, 220, 222, 11, 4, 220, 228, 11, 4, 220, 227, + 11, 4, 220, 233, 11, 4, 220, 229, 11, 4, 220, 219, 11, 4, 220, 217, 11, + 4, 220, 226, 11, 4, 220, 220, 11, 4, 203, 162, 11, 4, 203, 161, 11, 4, + 203, 170, 11, 4, 203, 164, 11, 4, 203, 166, 11, 4, 203, 165, 11, 4, 203, + 168, 11, 4, 203, 167, 11, 4, 203, 150, 11, 4, 203, 151, 11, 4, 203, 155, + 11, 4, 203, 154, 11, 4, 203, 160, 11, 4, 203, 158, 11, 4, 203, 128, 11, + 4, 203, 126, 11, 4, 203, 141, 11, 4, 203, 131, 11, 4, 203, 129, 11, 4, + 203, 130, 11, 4, 202, 253, 11, 4, 202, 251, 11, 4, 203, 11, 11, 4, 202, + 254, 11, 4, 203, 5, 11, 4, 203, 4, 11, 4, 203, 8, 11, 4, 203, 6, 11, 4, + 202, 191, 11, 4, 202, 190, 11, 4, 202, 194, 11, 4, 202, 192, 11, 4, 202, + 227, 11, 4, 202, 223, 11, 4, 202, 247, 11, 4, 202, 231, 11, 4, 202, 182, + 11, 4, 202, 178, 11, 4, 202, 213, 11, 4, 202, 189, 11, 4, 202, 185, 11, + 4, 202, 186, 11, 4, 202, 162, 11, 4, 202, 161, 11, 4, 202, 169, 11, 4, + 202, 165, 11, 4, 202, 163, 11, 4, 202, 164, 11, 40, 217, 68, 11, 40, 227, + 148, 11, 40, 229, 64, 11, 40, 220, 240, 11, 40, 245, 60, 11, 40, 211, + 132, 11, 40, 238, 138, 11, 40, 238, 170, 11, 40, 224, 155, 11, 40, 235, + 233, 11, 40, 226, 192, 11, 40, 248, 170, 11, 40, 224, 27, 11, 40, 202, + 247, 11, 40, 217, 159, 11, 40, 235, 227, 11, 40, 209, 212, 11, 40, 239, + 8, 11, 40, 201, 254, 11, 40, 245, 54, 11, 40, 244, 80, 11, 40, 247, 160, + 11, 40, 238, 134, 11, 40, 220, 229, 11, 40, 207, 203, 11, 40, 220, 9, 11, + 40, 230, 107, 11, 40, 202, 13, 11, 40, 217, 138, 11, 40, 236, 178, 11, + 40, 202, 253, 11, 40, 204, 159, 11, 40, 212, 171, 11, 40, 206, 44, 11, + 40, 202, 116, 11, 40, 230, 101, 11, 40, 220, 193, 11, 40, 230, 105, 11, + 40, 238, 18, 11, 40, 230, 125, 11, 40, 204, 0, 11, 40, 242, 42, 11, 40, + 212, 186, 11, 40, 227, 142, 11, 40, 245, 66, 11, 40, 245, 102, 11, 40, + 246, 63, 11, 40, 235, 230, 11, 40, 213, 53, 11, 40, 201, 253, 11, 40, + 212, 232, 11, 40, 246, 170, 11, 40, 201, 223, 11, 40, 223, 51, 11, 40, + 229, 201, 227, 91, 1, 249, 32, 227, 91, 1, 185, 227, 91, 1, 218, 208, + 227, 91, 1, 244, 212, 227, 91, 1, 210, 22, 227, 91, 1, 209, 108, 227, 91, + 1, 239, 8, 227, 91, 1, 173, 227, 91, 1, 229, 144, 227, 91, 1, 230, 181, + 227, 91, 1, 247, 92, 227, 91, 1, 246, 199, 227, 91, 1, 241, 255, 227, 91, + 1, 208, 20, 227, 91, 1, 208, 10, 227, 91, 1, 192, 227, 91, 1, 201, 201, + 227, 91, 1, 228, 113, 227, 91, 1, 215, 36, 227, 91, 1, 202, 80, 227, 91, + 1, 202, 116, 227, 91, 1, 222, 203, 227, 91, 1, 152, 227, 91, 1, 203, 182, + 227, 91, 1, 237, 12, 227, 91, 1, 240, 108, 227, 91, 1, 204, 111, 227, 91, + 1, 213, 90, 227, 91, 1, 198, 227, 91, 1, 238, 119, 227, 91, 1, 63, 227, + 91, 1, 251, 109, 227, 91, 1, 74, 227, 91, 1, 240, 238, 227, 91, 1, 75, + 227, 91, 1, 78, 227, 91, 1, 68, 227, 91, 1, 207, 24, 227, 91, 1, 207, 18, + 227, 91, 1, 220, 73, 227, 91, 1, 143, 223, 170, 209, 2, 227, 91, 1, 143, + 223, 111, 218, 69, 227, 91, 1, 143, 223, 170, 245, 65, 227, 91, 1, 143, + 223, 170, 248, 23, 227, 91, 1, 143, 223, 170, 201, 201, 227, 91, 1, 143, + 223, 170, 230, 150, 227, 91, 217, 179, 245, 233, 227, 91, 217, 179, 239, + 102, 211, 61, 48, 4, 241, 161, 48, 4, 241, 157, 48, 4, 237, 48, 48, 4, + 204, 55, 48, 4, 204, 54, 48, 4, 219, 23, 48, 4, 248, 93, 48, 4, 248, 150, + 48, 4, 225, 46, 48, 4, 228, 239, 48, 4, 224, 187, 48, 4, 238, 203, 48, 4, + 240, 53, 48, 4, 206, 50, 48, 4, 209, 176, 48, 4, 209, 90, 48, 4, 243, + 247, 48, 4, 243, 244, 48, 4, 227, 226, 48, 4, 216, 135, 48, 4, 244, 61, + 48, 4, 223, 16, 48, 4, 214, 165, 48, 4, 213, 41, 48, 4, 202, 90, 48, 4, + 202, 70, 48, 4, 246, 230, 48, 4, 230, 159, 48, 4, 222, 39, 48, 4, 203, + 49, 48, 4, 229, 198, 48, 4, 222, 176, 48, 4, 238, 182, 48, 4, 225, 8, 48, + 4, 222, 235, 48, 4, 221, 0, 48, 4, 75, 48, 4, 231, 49, 48, 4, 237, 3, 48, + 4, 236, 238, 48, 4, 204, 30, 48, 4, 204, 18, 48, 4, 218, 167, 48, 4, 248, + 91, 48, 4, 248, 86, 48, 4, 225, 39, 48, 4, 228, 236, 48, 4, 224, 184, 48, + 4, 238, 199, 48, 4, 240, 26, 48, 4, 205, 230, 48, 4, 209, 2, 48, 4, 209, + 70, 48, 4, 243, 239, 48, 4, 243, 243, 48, 4, 227, 148, 48, 4, 216, 57, + 48, 4, 243, 233, 48, 4, 223, 10, 48, 4, 212, 162, 48, 4, 213, 11, 48, 4, + 202, 39, 48, 4, 202, 66, 48, 4, 246, 79, 48, 4, 230, 141, 48, 4, 222, 32, + 48, 4, 203, 11, 48, 4, 229, 100, 48, 4, 222, 168, 48, 4, 238, 81, 48, 4, + 224, 155, 48, 4, 222, 100, 48, 4, 220, 248, 48, 4, 63, 48, 4, 250, 231, + 48, 4, 222, 198, 48, 4, 152, 48, 4, 237, 126, 48, 4, 204, 111, 48, 4, + 204, 97, 48, 4, 185, 48, 4, 248, 98, 48, 4, 249, 32, 48, 4, 225, 54, 48, + 4, 228, 244, 48, 4, 228, 242, 48, 4, 224, 191, 48, 4, 238, 207, 48, 4, + 240, 108, 48, 4, 206, 86, 48, 4, 210, 22, 48, 4, 209, 108, 48, 4, 244, 1, + 48, 4, 243, 246, 48, 4, 228, 113, 48, 4, 216, 220, 48, 4, 244, 212, 48, + 4, 223, 25, 48, 4, 215, 36, 48, 4, 213, 90, 48, 4, 202, 116, 48, 4, 202, + 80, 48, 4, 247, 92, 48, 4, 230, 181, 48, 4, 222, 48, 48, 4, 198, 48, 4, + 173, 48, 4, 230, 4, 48, 4, 222, 182, 48, 4, 239, 8, 48, 4, 192, 48, 4, + 201, 201, 48, 4, 221, 11, 48, 4, 220, 18, 48, 4, 220, 13, 48, 4, 236, + 117, 48, 4, 203, 244, 48, 4, 203, 240, 48, 4, 218, 45, 48, 4, 248, 89, + 48, 4, 248, 10, 48, 4, 225, 34, 48, 4, 228, 234, 48, 4, 224, 180, 48, 4, + 238, 195, 48, 4, 239, 175, 48, 4, 205, 176, 48, 4, 208, 148, 48, 4, 209, + 42, 48, 4, 243, 236, 48, 4, 243, 241, 48, 4, 227, 18, 48, 4, 215, 208, + 48, 4, 243, 90, 48, 4, 222, 253, 48, 4, 211, 250, 48, 4, 212, 236, 48, 4, + 202, 15, 48, 4, 202, 61, 48, 4, 245, 180, 48, 4, 230, 91, 48, 4, 222, 22, + 48, 4, 202, 232, 48, 4, 229, 6, 48, 4, 222, 166, 48, 4, 238, 28, 48, 4, + 224, 35, 48, 4, 221, 180, 48, 4, 220, 230, 48, 4, 68, 48, 4, 206, 255, + 48, 4, 236, 26, 48, 4, 236, 13, 48, 4, 203, 217, 48, 4, 203, 210, 48, 4, + 217, 191, 48, 4, 248, 88, 48, 4, 247, 193, 48, 4, 225, 33, 48, 4, 228, + 232, 48, 4, 224, 179, 48, 4, 238, 194, 48, 4, 239, 108, 48, 4, 204, 163, + 48, 4, 207, 203, 48, 4, 209, 22, 48, 4, 243, 234, 48, 4, 243, 240, 48, 4, + 226, 239, 48, 4, 215, 145, 48, 4, 242, 42, 48, 4, 222, 248, 48, 4, 211, + 10, 48, 4, 212, 199, 48, 4, 202, 6, 48, 4, 202, 57, 48, 4, 245, 110, 48, + 4, 230, 82, 48, 4, 222, 18, 48, 4, 202, 213, 48, 4, 228, 209, 48, 4, 222, + 165, 48, 4, 237, 230, 48, 4, 223, 246, 48, 4, 221, 84, 48, 4, 220, 226, + 48, 4, 78, 48, 4, 220, 31, 48, 4, 222, 124, 48, 4, 236, 136, 48, 4, 236, + 120, 48, 4, 204, 0, 48, 4, 203, 245, 48, 4, 218, 69, 48, 4, 248, 90, 48, + 4, 248, 23, 48, 4, 225, 35, 48, 4, 228, 235, 48, 4, 224, 182, 48, 4, 238, + 197, 48, 4, 238, 196, 48, 4, 239, 186, 48, 4, 205, 189, 48, 4, 135, 48, + 4, 209, 47, 48, 4, 243, 237, 48, 4, 243, 242, 48, 4, 227, 49, 48, 4, 215, + 227, 48, 4, 243, 113, 48, 4, 223, 1, 48, 4, 212, 13, 48, 4, 212, 242, 48, + 4, 202, 17, 48, 4, 202, 63, 48, 4, 245, 254, 48, 4, 230, 101, 48, 4, 222, + 23, 48, 4, 202, 247, 48, 4, 229, 26, 48, 4, 222, 167, 48, 4, 238, 39, 48, + 4, 224, 82, 48, 4, 221, 191, 48, 4, 220, 233, 48, 4, 74, 48, 4, 241, 92, + 48, 4, 222, 187, 48, 4, 237, 67, 48, 4, 237, 33, 48, 4, 204, 62, 48, 4, + 204, 49, 48, 4, 219, 34, 48, 4, 248, 94, 48, 4, 248, 162, 48, 4, 225, 47, + 48, 4, 228, 240, 48, 4, 228, 238, 48, 4, 224, 188, 48, 4, 238, 204, 48, + 4, 238, 202, 48, 4, 240, 60, 48, 4, 206, 55, 48, 4, 209, 187, 48, 4, 209, + 92, 48, 4, 243, 248, 48, 4, 243, 245, 48, 4, 227, 234, 48, 4, 216, 158, + 48, 4, 244, 75, 48, 4, 223, 17, 48, 4, 214, 177, 48, 4, 213, 43, 48, 4, + 202, 92, 48, 4, 202, 71, 48, 4, 246, 238, 48, 4, 230, 161, 48, 4, 222, + 41, 48, 4, 203, 52, 48, 4, 229, 201, 48, 4, 222, 177, 48, 4, 222, 173, + 48, 4, 238, 190, 48, 4, 238, 177, 48, 4, 225, 20, 48, 4, 222, 240, 48, 4, + 221, 1, 48, 4, 222, 205, 48, 4, 227, 188, 48, 245, 233, 48, 239, 102, + 211, 61, 48, 217, 47, 82, 48, 4, 223, 0, 240, 108, 48, 4, 223, 0, 173, + 48, 4, 223, 0, 211, 250, 48, 16, 240, 49, 48, 16, 229, 196, 48, 16, 208, + 215, 48, 16, 222, 75, 48, 16, 248, 237, 48, 16, 240, 107, 48, 16, 210, + 18, 48, 16, 244, 164, 48, 16, 243, 89, 48, 16, 228, 193, 48, 16, 208, + 152, 48, 16, 243, 112, 48, 16, 230, 92, 48, 17, 202, 84, 48, 17, 105, 48, + 17, 108, 48, 17, 147, 48, 17, 149, 48, 17, 170, 48, 17, 195, 48, 17, 213, + 111, 48, 17, 199, 48, 17, 222, 63, 48, 4, 223, 0, 192, 48, 4, 223, 0, + 243, 113, 36, 6, 1, 202, 88, 36, 5, 1, 202, 88, 36, 6, 1, 241, 250, 36, + 5, 1, 241, 250, 36, 6, 1, 216, 73, 241, 252, 36, 5, 1, 216, 73, 241, 252, + 36, 6, 1, 230, 230, 36, 5, 1, 230, 230, 36, 6, 1, 243, 129, 36, 5, 1, + 243, 129, 36, 6, 1, 224, 43, 207, 14, 36, 5, 1, 224, 43, 207, 14, 36, 6, + 1, 247, 204, 220, 36, 36, 5, 1, 247, 204, 220, 36, 36, 6, 1, 222, 216, + 203, 34, 36, 5, 1, 222, 216, 203, 34, 36, 6, 1, 203, 31, 3, 249, 26, 203, + 34, 36, 5, 1, 203, 31, 3, 249, 26, 203, 34, 36, 6, 1, 230, 228, 203, 66, + 36, 5, 1, 230, 228, 203, 66, 36, 6, 1, 216, 73, 202, 213, 36, 5, 1, 216, + 73, 202, 213, 36, 6, 1, 230, 228, 63, 36, 5, 1, 230, 228, 63, 36, 6, 1, + 246, 16, 227, 86, 202, 183, 36, 5, 1, 246, 16, 227, 86, 202, 183, 36, 6, + 1, 248, 35, 202, 183, 36, 5, 1, 248, 35, 202, 183, 36, 6, 1, 230, 228, + 246, 16, 227, 86, 202, 183, 36, 5, 1, 230, 228, 246, 16, 227, 86, 202, + 183, 36, 6, 1, 202, 249, 36, 5, 1, 202, 249, 36, 6, 1, 216, 73, 208, 14, + 36, 5, 1, 216, 73, 208, 14, 36, 6, 1, 212, 7, 244, 75, 36, 5, 1, 212, 7, + 244, 75, 36, 6, 1, 212, 7, 241, 122, 36, 5, 1, 212, 7, 241, 122, 36, 6, + 1, 212, 7, 241, 103, 36, 5, 1, 212, 7, 241, 103, 36, 6, 1, 224, 47, 78, + 36, 5, 1, 224, 47, 78, 36, 6, 1, 248, 63, 78, 36, 5, 1, 248, 63, 78, 36, + 6, 1, 52, 224, 47, 78, 36, 5, 1, 52, 224, 47, 78, 36, 1, 223, 227, 78, + 39, 36, 204, 146, 39, 36, 209, 153, 224, 114, 54, 39, 36, 236, 12, 224, + 114, 54, 39, 36, 209, 37, 224, 114, 54, 212, 55, 250, 59, 39, 36, 1, 207, + 11, 231, 110, 39, 36, 1, 75, 39, 36, 1, 203, 11, 39, 36, 1, 68, 39, 36, + 1, 237, 91, 54, 39, 36, 1, 203, 30, 39, 36, 1, 212, 7, 54, 39, 36, 1, + 220, 36, 39, 36, 229, 213, 39, 36, 219, 41, 36, 229, 213, 36, 219, 41, + 36, 6, 1, 242, 9, 36, 5, 1, 242, 9, 36, 6, 1, 241, 241, 36, 5, 1, 241, + 241, 36, 6, 1, 202, 47, 36, 5, 1, 202, 47, 36, 6, 1, 246, 254, 36, 5, 1, + 246, 254, 36, 6, 1, 241, 238, 36, 5, 1, 241, 238, 36, 6, 1, 209, 188, 3, + 101, 113, 36, 5, 1, 209, 188, 3, 101, 113, 36, 6, 1, 207, 158, 36, 5, 1, + 207, 158, 36, 6, 1, 207, 245, 36, 5, 1, 207, 245, 36, 6, 1, 207, 250, 36, + 5, 1, 207, 250, 36, 6, 1, 209, 193, 36, 5, 1, 209, 193, 36, 6, 1, 235, + 251, 36, 5, 1, 235, 251, 36, 6, 1, 212, 177, 36, 5, 1, 212, 177, 36, 6, + 1, 52, 78, 36, 5, 1, 52, 78, 36, 6, 1, 245, 128, 78, 36, 5, 1, 245, 128, + 78, 65, 1, 36, 237, 91, 54, 65, 1, 36, 212, 7, 54, 39, 36, 1, 241, 154, + 39, 36, 1, 230, 228, 74, 24, 1, 63, 24, 1, 173, 24, 1, 68, 24, 1, 228, + 209, 24, 1, 241, 161, 24, 1, 216, 135, 24, 1, 210, 1, 24, 1, 78, 24, 1, + 220, 248, 24, 1, 75, 24, 1, 228, 113, 24, 1, 185, 24, 1, 216, 3, 24, 1, + 216, 50, 24, 1, 227, 225, 24, 1, 225, 7, 24, 1, 210, 18, 24, 1, 223, 23, + 24, 1, 222, 46, 24, 1, 226, 185, 24, 1, 210, 179, 24, 1, 223, 246, 24, 1, + 213, 6, 24, 1, 212, 162, 24, 1, 213, 16, 24, 1, 213, 113, 24, 1, 228, + 137, 24, 1, 229, 170, 24, 1, 221, 55, 24, 1, 221, 84, 24, 1, 222, 17, 24, + 1, 202, 229, 24, 1, 212, 199, 24, 1, 202, 187, 24, 1, 198, 24, 1, 221, + 118, 24, 1, 229, 156, 24, 1, 218, 212, 24, 1, 222, 39, 24, 1, 221, 99, + 24, 1, 217, 183, 24, 1, 203, 214, 24, 1, 219, 23, 24, 1, 240, 53, 24, 1, + 215, 145, 24, 1, 226, 239, 24, 1, 224, 155, 24, 1, 222, 100, 24, 1, 216, + 75, 24, 1, 216, 202, 24, 1, 229, 180, 24, 1, 222, 131, 24, 1, 222, 182, + 24, 1, 222, 203, 24, 1, 212, 242, 24, 1, 217, 188, 24, 1, 239, 108, 24, + 1, 239, 179, 24, 1, 204, 111, 24, 1, 201, 201, 24, 1, 227, 148, 24, 1, + 218, 167, 24, 1, 227, 10, 24, 1, 229, 26, 24, 1, 225, 44, 24, 1, 216, + 107, 24, 1, 224, 240, 24, 1, 192, 24, 1, 209, 2, 24, 1, 229, 100, 24, 1, + 224, 82, 24, 1, 225, 52, 24, 1, 209, 132, 24, 1, 228, 244, 24, 1, 209, + 152, 24, 1, 221, 86, 24, 1, 214, 251, 24, 1, 240, 104, 24, 1, 228, 246, + 24, 1, 229, 21, 24, 39, 131, 228, 255, 24, 39, 131, 207, 194, 24, 222, + 45, 24, 239, 102, 211, 61, 24, 245, 242, 24, 245, 233, 24, 213, 143, 24, + 217, 47, 82, 65, 1, 246, 128, 143, 203, 1, 218, 119, 65, 1, 246, 128, + 143, 203, 77, 218, 119, 65, 1, 246, 128, 143, 203, 1, 213, 65, 65, 1, + 246, 128, 143, 203, 77, 213, 65, 65, 1, 246, 128, 143, 203, 1, 217, 65, + 65, 1, 246, 128, 143, 203, 77, 217, 65, 65, 1, 246, 128, 143, 203, 1, + 215, 145, 65, 1, 246, 128, 143, 203, 77, 215, 145, 65, 1, 240, 198, 242, + 83, 143, 142, 65, 1, 138, 242, 83, 143, 142, 65, 1, 224, 150, 242, 83, + 143, 142, 65, 1, 124, 242, 83, 143, 142, 65, 1, 240, 197, 242, 83, 143, + 142, 65, 1, 240, 198, 242, 83, 227, 214, 143, 142, 65, 1, 138, 242, 83, + 227, 214, 143, 142, 65, 1, 224, 150, 242, 83, 227, 214, 143, 142, 65, 1, + 124, 242, 83, 227, 214, 143, 142, 65, 1, 240, 197, 242, 83, 227, 214, + 143, 142, 65, 1, 240, 198, 227, 214, 143, 142, 65, 1, 138, 227, 214, 143, + 142, 65, 1, 224, 150, 227, 214, 143, 142, 65, 1, 124, 227, 214, 143, 142, + 65, 1, 240, 197, 227, 214, 143, 142, 65, 1, 70, 80, 142, 65, 1, 70, 212, + 57, 65, 1, 70, 236, 106, 142, 65, 1, 226, 251, 50, 245, 166, 250, 217, + 65, 1, 216, 188, 112, 47, 65, 1, 216, 188, 121, 47, 65, 1, 216, 188, 240, + 212, 82, 65, 1, 216, 188, 230, 239, 240, 212, 82, 65, 1, 124, 230, 239, + 240, 212, 82, 65, 1, 211, 42, 25, 138, 208, 161, 65, 1, 211, 42, 25, 124, + 208, 161, 8, 6, 1, 241, 149, 251, 30, 8, 5, 1, 241, 149, 251, 30, 8, 6, + 1, 241, 149, 251, 59, 8, 5, 1, 241, 149, 251, 59, 8, 6, 1, 237, 31, 8, 5, + 1, 237, 31, 8, 6, 1, 207, 107, 8, 5, 1, 207, 107, 8, 6, 1, 208, 89, 8, 5, + 1, 208, 89, 8, 6, 1, 245, 107, 8, 5, 1, 245, 107, 8, 6, 1, 245, 108, 3, + 245, 233, 8, 5, 1, 245, 108, 3, 245, 233, 8, 1, 5, 6, 240, 174, 8, 1, 5, + 6, 194, 8, 6, 1, 252, 25, 8, 5, 1, 252, 25, 8, 6, 1, 250, 178, 8, 5, 1, + 250, 178, 8, 6, 1, 250, 34, 8, 5, 1, 250, 34, 8, 6, 1, 250, 18, 8, 5, 1, + 250, 18, 8, 6, 1, 250, 19, 3, 236, 106, 142, 8, 5, 1, 250, 19, 3, 236, + 106, 142, 8, 6, 1, 250, 8, 8, 5, 1, 250, 8, 8, 6, 1, 216, 73, 247, 126, + 3, 243, 85, 8, 5, 1, 216, 73, 247, 126, 3, 243, 85, 8, 6, 1, 230, 55, 3, + 95, 8, 5, 1, 230, 55, 3, 95, 8, 6, 1, 230, 55, 3, 243, 228, 95, 8, 5, 1, + 230, 55, 3, 243, 228, 95, 8, 6, 1, 230, 55, 3, 211, 32, 25, 243, 228, 95, + 8, 5, 1, 230, 55, 3, 211, 32, 25, 243, 228, 95, 8, 6, 1, 247, 203, 159, + 8, 5, 1, 247, 203, 159, 8, 6, 1, 228, 131, 3, 138, 95, 8, 5, 1, 228, 131, + 3, 138, 95, 8, 6, 1, 158, 3, 163, 211, 32, 219, 199, 8, 5, 1, 158, 3, + 163, 211, 32, 219, 199, 8, 6, 1, 158, 3, 227, 14, 8, 5, 1, 158, 3, 227, + 14, 8, 6, 1, 220, 18, 8, 5, 1, 220, 18, 8, 6, 1, 219, 185, 3, 211, 32, + 209, 25, 244, 20, 8, 5, 1, 219, 185, 3, 211, 32, 209, 25, 244, 20, 8, 6, + 1, 219, 185, 3, 239, 199, 8, 5, 1, 219, 185, 3, 239, 199, 8, 6, 1, 219, + 185, 3, 211, 170, 209, 248, 8, 5, 1, 219, 185, 3, 211, 170, 209, 248, 8, + 6, 1, 217, 135, 3, 211, 32, 209, 25, 244, 20, 8, 5, 1, 217, 135, 3, 211, + 32, 209, 25, 244, 20, 8, 6, 1, 217, 135, 3, 243, 228, 95, 8, 5, 1, 217, + 135, 3, 243, 228, 95, 8, 6, 1, 217, 1, 215, 192, 8, 5, 1, 217, 1, 215, + 192, 8, 6, 1, 215, 132, 215, 192, 8, 5, 1, 215, 132, 215, 192, 8, 6, 1, + 206, 165, 3, 243, 228, 95, 8, 5, 1, 206, 165, 3, 243, 228, 95, 8, 6, 1, + 204, 152, 8, 5, 1, 204, 152, 8, 6, 1, 205, 197, 202, 159, 8, 5, 1, 205, + 197, 202, 159, 8, 6, 1, 209, 41, 3, 95, 8, 5, 1, 209, 41, 3, 95, 8, 6, 1, + 209, 41, 3, 211, 32, 209, 25, 244, 20, 8, 5, 1, 209, 41, 3, 211, 32, 209, + 25, 244, 20, 8, 6, 1, 206, 45, 8, 5, 1, 206, 45, 8, 6, 1, 240, 250, 8, 5, + 1, 240, 250, 8, 6, 1, 230, 215, 8, 5, 1, 230, 215, 8, 6, 1, 245, 218, 8, + 5, 1, 245, 218, 65, 1, 206, 193, 8, 5, 1, 242, 32, 8, 5, 1, 226, 222, 8, + 5, 1, 223, 220, 8, 5, 1, 221, 47, 8, 5, 1, 215, 131, 8, 1, 5, 6, 215, + 131, 8, 5, 1, 207, 191, 8, 5, 1, 207, 6, 8, 6, 1, 231, 4, 245, 51, 8, 5, + 1, 231, 4, 245, 51, 8, 6, 1, 231, 4, 240, 174, 8, 5, 1, 231, 4, 240, 174, + 8, 6, 1, 231, 4, 239, 75, 8, 6, 1, 207, 174, 231, 4, 239, 75, 8, 5, 1, + 207, 174, 231, 4, 239, 75, 8, 6, 1, 207, 174, 159, 8, 5, 1, 207, 174, + 159, 8, 6, 1, 231, 4, 146, 8, 5, 1, 231, 4, 146, 8, 6, 1, 231, 4, 194, 8, + 5, 1, 231, 4, 194, 8, 6, 1, 231, 4, 210, 69, 8, 5, 1, 231, 4, 210, 69, + 65, 1, 124, 246, 53, 251, 138, 65, 1, 245, 242, 65, 1, 212, 228, 241, 35, + 54, 8, 6, 1, 214, 255, 8, 5, 1, 214, 255, 8, 6, 1, 207, 174, 237, 171, 8, + 5, 1, 228, 131, 3, 216, 79, 236, 116, 25, 248, 124, 8, 1, 212, 114, 243, + 85, 8, 6, 1, 223, 164, 3, 244, 20, 8, 5, 1, 223, 164, 3, 244, 20, 8, 6, + 1, 247, 126, 3, 142, 8, 5, 1, 247, 126, 3, 142, 8, 5, 1, 247, 126, 3, + 219, 142, 113, 8, 5, 1, 237, 172, 3, 219, 142, 113, 8, 6, 1, 66, 3, 239, + 199, 8, 5, 1, 66, 3, 239, 199, 8, 6, 1, 240, 175, 3, 95, 8, 5, 1, 240, + 175, 3, 95, 8, 6, 1, 205, 182, 251, 109, 8, 5, 1, 205, 182, 251, 109, 8, + 6, 1, 205, 182, 220, 73, 8, 5, 1, 205, 182, 220, 73, 8, 6, 1, 205, 182, + 207, 24, 8, 5, 1, 205, 182, 207, 24, 8, 6, 1, 239, 76, 3, 220, 89, 95, 8, + 5, 1, 239, 76, 3, 220, 89, 95, 8, 6, 1, 230, 55, 3, 220, 89, 95, 8, 5, 1, + 230, 55, 3, 220, 89, 95, 8, 6, 1, 223, 164, 3, 220, 89, 95, 8, 5, 1, 223, + 164, 3, 220, 89, 95, 8, 6, 1, 217, 1, 3, 220, 89, 95, 8, 5, 1, 217, 1, 3, + 220, 89, 95, 8, 6, 1, 215, 94, 3, 220, 89, 95, 8, 5, 1, 215, 94, 3, 220, + 89, 95, 8, 6, 1, 237, 172, 3, 113, 8, 6, 1, 216, 73, 171, 74, 8, 6, 1, + 132, 239, 75, 8, 6, 1, 228, 131, 3, 248, 124, 8, 6, 1, 207, 174, 230, 54, + 8, 6, 1, 207, 174, 210, 69, 8, 6, 1, 230, 185, 3, 245, 126, 8, 6, 1, 246, + 142, 8, 6, 1, 248, 106, 8, 5, 1, 248, 106, 8, 6, 1, 220, 36, 8, 5, 1, + 220, 36, 8, 241, 40, 1, 212, 154, 75, 65, 1, 6, 237, 172, 3, 95, 65, 1, + 5, 32, 220, 73, 8, 1, 5, 6, 207, 174, 226, 185, 8, 241, 40, 1, 216, 73, + 240, 174, 8, 241, 40, 1, 216, 73, 219, 184, 8, 241, 40, 1, 230, 239, 226, + 185, 8, 241, 40, 1, 235, 206, 227, 20, 8, 241, 40, 1, 250, 126, 226, 185, + 210, 149, 223, 94, 1, 63, 210, 149, 223, 94, 1, 75, 210, 149, 223, 94, 2, + 242, 11, 210, 149, 223, 94, 1, 68, 210, 149, 223, 94, 1, 74, 210, 149, + 223, 94, 1, 78, 210, 149, 223, 94, 2, 237, 85, 210, 149, 223, 94, 1, 229, + 26, 210, 149, 223, 94, 1, 229, 115, 210, 149, 223, 94, 1, 238, 39, 210, + 149, 223, 94, 1, 238, 91, 210, 149, 223, 94, 2, 250, 180, 210, 149, 223, + 94, 1, 245, 254, 210, 149, 223, 94, 1, 246, 116, 210, 149, 223, 94, 1, + 230, 101, 210, 149, 223, 94, 1, 230, 143, 210, 149, 223, 94, 1, 207, 218, + 210, 149, 223, 94, 1, 207, 224, 210, 149, 223, 94, 1, 244, 90, 210, 149, + 223, 94, 1, 244, 99, 210, 149, 223, 94, 1, 135, 210, 149, 223, 94, 1, + 209, 47, 210, 149, 223, 94, 1, 243, 113, 210, 149, 223, 94, 1, 243, 237, + 210, 149, 223, 94, 1, 221, 191, 210, 149, 223, 94, 1, 218, 69, 210, 149, + 223, 94, 1, 218, 180, 210, 149, 223, 94, 1, 248, 23, 210, 149, 223, 94, + 1, 248, 90, 210, 149, 223, 94, 1, 224, 82, 210, 149, 223, 94, 1, 215, + 227, 210, 149, 223, 94, 1, 227, 49, 210, 149, 223, 94, 1, 215, 171, 210, + 149, 223, 94, 1, 212, 13, 210, 149, 223, 94, 1, 236, 136, 210, 149, 223, + 94, 22, 2, 63, 210, 149, 223, 94, 22, 2, 75, 210, 149, 223, 94, 22, 2, + 68, 210, 149, 223, 94, 22, 2, 74, 210, 149, 223, 94, 22, 2, 220, 18, 210, + 149, 223, 94, 218, 64, 225, 92, 210, 149, 223, 94, 218, 64, 225, 91, 210, + 149, 223, 94, 218, 64, 225, 90, 210, 149, 223, 94, 218, 64, 225, 89, 153, + 231, 33, 239, 138, 118, 217, 55, 153, 231, 33, 239, 138, 118, 237, 137, + 153, 231, 33, 239, 138, 126, 217, 53, 153, 231, 33, 239, 138, 118, 212, + 80, 153, 231, 33, 239, 138, 118, 241, 138, 153, 231, 33, 239, 138, 126, + 212, 79, 153, 231, 33, 217, 56, 82, 153, 231, 33, 218, 96, 82, 153, 231, + 33, 215, 120, 82, 153, 231, 33, 217, 57, 82, 218, 204, 1, 173, 218, 204, + 1, 229, 144, 218, 204, 1, 239, 8, 218, 204, 1, 222, 203, 218, 204, 1, + 247, 92, 218, 204, 1, 246, 199, 218, 204, 1, 230, 181, 218, 204, 1, 221, + 11, 218, 204, 1, 210, 22, 218, 204, 1, 209, 108, 218, 204, 1, 244, 212, + 218, 204, 1, 201, 201, 218, 204, 1, 185, 218, 204, 1, 218, 208, 218, 204, + 1, 249, 32, 218, 204, 1, 192, 218, 204, 1, 208, 20, 218, 204, 1, 208, 10, + 218, 204, 1, 241, 255, 218, 204, 1, 204, 111, 218, 204, 1, 202, 80, 218, + 204, 1, 202, 116, 218, 204, 1, 5, 63, 218, 204, 1, 198, 218, 204, 1, 216, + 220, 218, 204, 1, 228, 113, 218, 204, 1, 213, 90, 218, 204, 1, 215, 36, + 218, 204, 1, 152, 218, 204, 1, 63, 218, 204, 1, 75, 218, 204, 1, 68, 218, + 204, 1, 74, 218, 204, 1, 78, 218, 204, 1, 217, 126, 218, 204, 1, 203, + 182, 218, 204, 1, 240, 108, 218, 204, 1, 238, 155, 218, 204, 1, 241, 161, + 218, 204, 210, 254, 1, 204, 111, 218, 204, 210, 254, 1, 198, 218, 204, 1, + 207, 241, 218, 204, 1, 207, 229, 218, 204, 1, 244, 120, 218, 204, 1, 221, + 227, 218, 204, 1, 250, 255, 198, 218, 204, 1, 205, 185, 213, 90, 218, + 204, 1, 205, 186, 152, 218, 204, 1, 250, 66, 240, 108, 218, 204, 210, + 254, 1, 216, 220, 218, 204, 210, 201, 1, 216, 220, 218, 204, 1, 247, 52, + 218, 204, 212, 120, 237, 65, 82, 218, 204, 52, 237, 65, 82, 218, 204, + 131, 213, 82, 218, 204, 131, 52, 213, 82, 214, 215, 2, 250, 180, 214, + 215, 2, 205, 199, 214, 215, 1, 63, 214, 215, 1, 252, 25, 214, 215, 1, 75, + 214, 215, 1, 231, 83, 214, 215, 1, 68, 214, 215, 1, 206, 178, 214, 215, + 1, 125, 146, 214, 215, 1, 125, 215, 186, 214, 215, 1, 125, 159, 214, 215, + 1, 125, 227, 78, 214, 215, 1, 74, 214, 215, 1, 241, 161, 214, 215, 1, + 251, 64, 214, 215, 1, 78, 214, 215, 1, 220, 18, 214, 215, 1, 250, 34, + 214, 215, 1, 173, 214, 215, 1, 229, 144, 214, 215, 1, 239, 8, 214, 215, + 1, 238, 119, 214, 215, 1, 222, 203, 214, 215, 1, 247, 92, 214, 215, 1, + 246, 199, 214, 215, 1, 230, 181, 214, 215, 1, 230, 149, 214, 215, 1, 221, + 11, 214, 215, 1, 207, 241, 214, 215, 1, 207, 229, 214, 215, 1, 244, 120, + 214, 215, 1, 244, 104, 214, 215, 1, 221, 227, 214, 215, 1, 210, 22, 214, + 215, 1, 209, 108, 214, 215, 1, 244, 212, 214, 215, 1, 244, 1, 214, 215, + 1, 201, 201, 214, 215, 1, 185, 214, 215, 1, 218, 208, 214, 215, 1, 249, + 32, 214, 215, 1, 248, 98, 214, 215, 1, 192, 214, 215, 1, 198, 214, 215, + 1, 216, 220, 214, 215, 1, 228, 113, 214, 215, 1, 206, 86, 214, 215, 1, + 213, 90, 214, 215, 1, 211, 164, 214, 215, 1, 215, 36, 214, 215, 1, 152, + 214, 215, 1, 227, 77, 214, 215, 109, 2, 237, 155, 214, 215, 22, 2, 252, + 25, 214, 215, 22, 2, 75, 214, 215, 22, 2, 231, 83, 214, 215, 22, 2, 68, + 214, 215, 22, 2, 206, 178, 214, 215, 22, 2, 125, 146, 214, 215, 22, 2, + 125, 215, 186, 214, 215, 22, 2, 125, 159, 214, 215, 22, 2, 125, 227, 78, + 214, 215, 22, 2, 74, 214, 215, 22, 2, 241, 161, 214, 215, 22, 2, 251, 64, + 214, 215, 22, 2, 78, 214, 215, 22, 2, 220, 18, 214, 215, 22, 2, 250, 34, + 214, 215, 2, 205, 204, 214, 215, 244, 166, 214, 215, 52, 244, 166, 214, + 215, 17, 202, 84, 214, 215, 17, 105, 214, 215, 17, 108, 214, 215, 17, + 147, 214, 215, 17, 149, 214, 215, 17, 170, 214, 215, 17, 195, 214, 215, + 17, 213, 111, 214, 215, 17, 199, 214, 215, 17, 222, 63, 39, 92, 17, 202, + 84, 39, 92, 17, 105, 39, 92, 17, 108, 39, 92, 17, 147, 39, 92, 17, 149, + 39, 92, 17, 170, 39, 92, 17, 195, 39, 92, 17, 213, 111, 39, 92, 17, 199, + 39, 92, 17, 222, 63, 39, 92, 1, 63, 39, 92, 1, 68, 39, 92, 1, 173, 39, + 92, 1, 201, 201, 39, 92, 1, 185, 39, 92, 1, 216, 220, 39, 92, 1, 205, + 230, 39, 92, 2, 250, 17, 92, 2, 211, 227, 247, 52, 92, 2, 247, 53, 205, + 204, 92, 2, 52, 247, 53, 205, 204, 92, 2, 247, 53, 108, 92, 2, 247, 53, + 147, 92, 2, 247, 53, 250, 17, 92, 2, 217, 162, 92, 238, 228, 240, 7, 92, + 247, 33, 92, 237, 58, 92, 2, 212, 157, 92, 230, 173, 220, 39, 229, 207, + 227, 149, 17, 202, 84, 229, 207, 227, 149, 17, 105, 229, 207, 227, 149, + 17, 108, 229, 207, 227, 149, 17, 147, 229, 207, 227, 149, 17, 149, 229, + 207, 227, 149, 17, 170, 229, 207, 227, 149, 17, 195, 229, 207, 227, 149, + 17, 213, 111, 229, 207, 227, 149, 17, 199, 229, 207, 227, 149, 17, 222, + 63, 229, 207, 227, 149, 1, 173, 229, 207, 227, 149, 1, 229, 144, 229, + 207, 227, 149, 1, 239, 8, 229, 207, 227, 149, 1, 222, 203, 229, 207, 227, + 149, 1, 215, 36, 229, 207, 227, 149, 1, 213, 90, 229, 207, 227, 149, 1, + 202, 116, 229, 207, 227, 149, 1, 221, 11, 229, 207, 227, 149, 1, 210, 22, + 229, 207, 227, 149, 1, 236, 30, 229, 207, 227, 149, 1, 201, 201, 229, + 207, 227, 149, 1, 185, 229, 207, 227, 149, 1, 218, 208, 229, 207, 227, + 149, 1, 192, 229, 207, 227, 149, 1, 244, 212, 229, 207, 227, 149, 1, 249, + 32, 229, 207, 227, 149, 1, 216, 220, 229, 207, 227, 149, 1, 198, 229, + 207, 227, 149, 1, 228, 113, 229, 207, 227, 149, 1, 204, 111, 229, 207, + 227, 149, 1, 209, 108, 229, 207, 227, 149, 1, 152, 229, 207, 227, 149, 1, + 206, 86, 229, 207, 227, 149, 1, 247, 92, 229, 207, 227, 149, 1, 63, 229, + 207, 227, 149, 1, 220, 73, 229, 207, 227, 149, 1, 75, 229, 207, 227, 149, + 1, 220, 18, 229, 207, 227, 149, 22, 207, 24, 229, 207, 227, 149, 22, 74, + 229, 207, 227, 149, 22, 68, 229, 207, 227, 149, 22, 241, 161, 229, 207, + 227, 149, 22, 78, 229, 207, 227, 149, 143, 218, 84, 229, 207, 227, 149, + 143, 247, 68, 229, 207, 227, 149, 143, 247, 69, 218, 84, 229, 207, 227, + 149, 2, 245, 70, 229, 207, 227, 149, 2, 212, 170, 216, 119, 1, 173, 216, + 119, 1, 239, 8, 216, 119, 1, 222, 203, 216, 119, 1, 210, 22, 216, 119, 1, + 244, 212, 216, 119, 1, 201, 201, 216, 119, 1, 185, 216, 119, 1, 249, 32, + 216, 119, 1, 192, 216, 119, 1, 247, 92, 216, 119, 1, 230, 181, 216, 119, + 1, 221, 11, 216, 119, 1, 215, 36, 216, 119, 1, 216, 220, 216, 119, 1, + 228, 113, 216, 119, 1, 198, 216, 119, 1, 204, 111, 216, 119, 1, 152, 216, + 119, 1, 225, 54, 216, 119, 1, 222, 182, 216, 119, 1, 223, 25, 216, 119, + 1, 220, 234, 216, 119, 1, 63, 216, 119, 22, 2, 75, 216, 119, 22, 2, 68, + 216, 119, 22, 2, 74, 216, 119, 22, 2, 251, 64, 216, 119, 22, 2, 78, 216, + 119, 22, 2, 250, 34, 216, 119, 22, 2, 240, 238, 216, 119, 22, 2, 241, + 189, 216, 119, 109, 2, 222, 205, 216, 119, 109, 2, 223, 163, 216, 119, + 109, 2, 146, 216, 119, 109, 2, 237, 171, 216, 119, 205, 204, 216, 119, + 214, 168, 82, 28, 123, 208, 236, 28, 123, 208, 235, 28, 123, 208, 233, + 28, 123, 208, 238, 28, 123, 216, 42, 28, 123, 216, 26, 28, 123, 216, 21, + 28, 123, 216, 23, 28, 123, 216, 39, 28, 123, 216, 32, 28, 123, 216, 25, + 28, 123, 216, 44, 28, 123, 216, 27, 28, 123, 216, 46, 28, 123, 216, 43, + 28, 123, 224, 137, 28, 123, 224, 128, 28, 123, 224, 131, 28, 123, 218, + 138, 28, 123, 218, 149, 28, 123, 218, 150, 28, 123, 211, 148, 28, 123, + 231, 96, 28, 123, 231, 103, 28, 123, 211, 159, 28, 123, 211, 146, 28, + 123, 218, 189, 28, 123, 236, 246, 28, 123, 211, 143, 190, 2, 219, 102, + 190, 2, 246, 235, 190, 2, 227, 242, 190, 2, 204, 20, 190, 1, 63, 190, 1, + 235, 206, 229, 211, 190, 1, 75, 190, 1, 231, 83, 190, 1, 68, 190, 1, 219, + 169, 246, 205, 190, 1, 222, 204, 227, 201, 190, 1, 222, 204, 227, 202, + 216, 173, 190, 1, 74, 190, 1, 251, 64, 190, 1, 78, 190, 1, 173, 190, 1, + 230, 44, 214, 227, 190, 1, 230, 44, 223, 205, 190, 1, 239, 8, 190, 1, + 239, 9, 223, 205, 190, 1, 222, 203, 190, 1, 247, 92, 190, 1, 247, 93, + 223, 205, 190, 1, 230, 181, 190, 1, 221, 12, 223, 205, 190, 1, 230, 182, + 225, 144, 190, 1, 221, 11, 190, 1, 207, 241, 190, 1, 207, 242, 225, 144, + 190, 1, 244, 120, 190, 1, 244, 121, 225, 144, 190, 1, 223, 111, 223, 205, + 190, 1, 210, 22, 190, 1, 210, 23, 223, 205, 190, 1, 244, 212, 190, 1, + 244, 213, 225, 144, 190, 1, 201, 201, 190, 1, 185, 190, 1, 219, 169, 223, + 205, 190, 1, 249, 32, 190, 1, 249, 33, 223, 205, 190, 1, 192, 190, 1, + 198, 190, 1, 216, 220, 190, 1, 216, 221, 251, 74, 190, 1, 228, 113, 190, + 1, 204, 111, 190, 1, 215, 37, 223, 205, 190, 1, 215, 37, 225, 144, 190, + 1, 215, 36, 190, 1, 152, 190, 2, 246, 236, 209, 155, 190, 22, 2, 209, + 214, 190, 22, 2, 208, 166, 190, 22, 2, 203, 211, 190, 22, 2, 203, 212, + 224, 251, 190, 22, 2, 210, 224, 190, 22, 2, 210, 225, 224, 239, 190, 22, + 2, 209, 235, 190, 22, 2, 243, 163, 223, 204, 190, 22, 2, 218, 249, 190, + 109, 2, 229, 173, 190, 109, 2, 219, 6, 190, 109, 2, 247, 77, 190, 219, + 115, 190, 49, 216, 93, 190, 50, 216, 93, 190, 219, 158, 250, 225, 190, + 219, 158, 225, 162, 190, 219, 158, 226, 226, 190, 219, 158, 204, 14, 190, + 219, 158, 219, 116, 190, 219, 158, 227, 106, 190, 219, 158, 226, 220, + 190, 219, 158, 251, 116, 190, 219, 158, 251, 117, 251, 116, 190, 219, + 158, 218, 107, 190, 207, 174, 219, 158, 218, 107, 190, 219, 111, 190, 17, + 202, 84, 190, 17, 105, 190, 17, 108, 190, 17, 147, 190, 17, 149, 190, 17, + 170, 190, 17, 195, 190, 17, 213, 111, 190, 17, 199, 190, 17, 222, 63, + 190, 219, 158, 208, 202, 207, 189, 190, 219, 158, 230, 211, 69, 1, 213, + 67, 238, 119, 69, 1, 213, 67, 246, 199, 69, 1, 213, 67, 230, 149, 69, 1, + 213, 67, 221, 227, 69, 1, 213, 67, 248, 98, 69, 2, 213, 67, 214, 213, 69, + 65, 1, 213, 67, 216, 136, 69, 1, 45, 228, 85, 221, 11, 69, 1, 45, 228, + 85, 240, 108, 69, 1, 45, 228, 85, 239, 8, 69, 1, 45, 228, 85, 238, 119, + 69, 1, 45, 228, 85, 230, 181, 69, 1, 45, 228, 85, 230, 149, 69, 1, 45, + 228, 85, 244, 120, 69, 1, 45, 228, 85, 244, 104, 69, 1, 45, 228, 85, 221, + 227, 69, 45, 228, 85, 17, 202, 84, 69, 45, 228, 85, 17, 105, 69, 45, 228, + 85, 17, 108, 69, 45, 228, 85, 17, 147, 69, 45, 228, 85, 17, 149, 69, 45, + 228, 85, 17, 170, 69, 45, 228, 85, 17, 195, 69, 45, 228, 85, 17, 213, + 111, 69, 45, 228, 85, 17, 199, 69, 45, 228, 85, 17, 222, 63, 69, 1, 45, + 228, 85, 227, 77, 69, 1, 45, 228, 85, 244, 212, 69, 1, 45, 228, 85, 244, + 1, 69, 1, 45, 228, 85, 249, 32, 69, 1, 45, 228, 85, 248, 98, 246, 192, 1, + 63, 246, 192, 1, 75, 246, 192, 1, 68, 246, 192, 1, 74, 246, 192, 1, 251, + 64, 246, 192, 1, 78, 246, 192, 1, 173, 246, 192, 1, 229, 144, 246, 192, + 1, 239, 8, 246, 192, 1, 238, 119, 246, 192, 1, 222, 112, 246, 192, 1, + 222, 203, 246, 192, 1, 246, 199, 246, 192, 1, 246, 144, 246, 192, 1, 230, + 181, 246, 192, 1, 230, 149, 246, 192, 1, 222, 102, 246, 192, 1, 222, 104, + 246, 192, 1, 222, 103, 246, 192, 1, 210, 22, 246, 192, 1, 209, 108, 246, + 192, 1, 244, 212, 246, 192, 1, 244, 1, 246, 192, 1, 221, 53, 246, 192, 1, + 201, 201, 246, 192, 1, 244, 120, 246, 192, 1, 185, 246, 192, 1, 218, 12, + 246, 192, 1, 218, 208, 246, 192, 1, 249, 32, 246, 192, 1, 248, 98, 246, + 192, 1, 223, 238, 246, 192, 1, 192, 246, 192, 1, 248, 198, 246, 192, 1, + 198, 246, 192, 1, 216, 220, 246, 192, 1, 228, 113, 246, 192, 1, 206, 86, + 246, 192, 1, 211, 164, 246, 192, 1, 215, 36, 246, 192, 1, 152, 246, 192, + 22, 2, 252, 25, 246, 192, 22, 2, 75, 246, 192, 22, 2, 231, 83, 246, 192, + 22, 2, 241, 145, 246, 192, 22, 2, 68, 246, 192, 22, 2, 220, 73, 246, 192, + 22, 2, 78, 246, 192, 22, 2, 251, 64, 246, 192, 22, 2, 250, 34, 246, 192, + 22, 2, 207, 24, 246, 192, 109, 2, 198, 246, 192, 109, 2, 216, 220, 246, + 192, 109, 2, 228, 113, 246, 192, 109, 2, 204, 111, 246, 192, 1, 46, 230, + 54, 246, 192, 1, 46, 239, 75, 246, 192, 1, 46, 222, 205, 246, 192, 109, + 2, 46, 222, 205, 246, 192, 1, 46, 246, 200, 246, 192, 1, 46, 210, 69, + 246, 192, 1, 46, 223, 163, 246, 192, 1, 46, 219, 184, 246, 192, 1, 46, + 203, 124, 246, 192, 1, 46, 146, 246, 192, 1, 46, 159, 246, 192, 1, 46, + 211, 167, 246, 192, 109, 2, 46, 226, 185, 246, 192, 109, 2, 46, 237, 171, + 246, 192, 17, 202, 84, 246, 192, 17, 105, 246, 192, 17, 108, 246, 192, + 17, 147, 246, 192, 17, 149, 246, 192, 17, 170, 246, 192, 17, 195, 246, + 192, 17, 213, 111, 246, 192, 17, 199, 246, 192, 17, 222, 63, 246, 192, + 217, 179, 211, 201, 246, 192, 217, 179, 244, 166, 246, 192, 217, 179, 52, + 244, 166, 246, 192, 217, 179, 208, 70, 244, 166, 69, 1, 229, 137, 239, 8, + 69, 1, 229, 137, 247, 92, 69, 1, 229, 137, 246, 199, 69, 1, 229, 137, + 230, 181, 69, 1, 229, 137, 230, 149, 69, 1, 229, 137, 221, 11, 69, 1, + 229, 137, 207, 241, 69, 1, 229, 137, 207, 229, 69, 1, 229, 137, 244, 120, + 69, 1, 229, 137, 244, 104, 69, 1, 229, 137, 244, 1, 69, 1, 229, 137, 201, + 201, 69, 1, 229, 137, 215, 36, 69, 1, 229, 137, 152, 69, 1, 229, 137, + 237, 12, 69, 1, 229, 137, 240, 108, 69, 65, 1, 229, 137, 216, 136, 69, 1, + 229, 137, 203, 182, 69, 1, 229, 137, 202, 116, 69, 1, 229, 137, 216, 220, + 69, 227, 36, 229, 137, 220, 94, 69, 227, 36, 229, 137, 217, 78, 69, 227, + 36, 229, 137, 236, 191, 69, 16, 251, 51, 240, 211, 69, 16, 251, 51, 105, + 69, 16, 251, 51, 108, 69, 1, 251, 51, 216, 220, 69, 2, 219, 98, 229, 237, + 208, 161, 69, 2, 45, 228, 85, 208, 159, 69, 2, 45, 228, 85, 208, 156, 69, + 1, 212, 178, 219, 139, 246, 199, 69, 1, 212, 178, 219, 139, 213, 90, 45, + 205, 220, 1, 124, 229, 26, 45, 205, 220, 1, 138, 229, 26, 45, 205, 220, + 1, 124, 229, 115, 45, 205, 220, 1, 138, 229, 115, 45, 205, 220, 1, 124, + 229, 124, 45, 205, 220, 1, 138, 229, 124, 45, 205, 220, 1, 124, 238, 39, + 45, 205, 220, 1, 138, 238, 39, 45, 205, 220, 1, 124, 222, 128, 45, 205, + 220, 1, 138, 222, 128, 45, 205, 220, 1, 124, 245, 254, 45, 205, 220, 1, + 138, 245, 254, 45, 205, 220, 1, 124, 246, 116, 45, 205, 220, 1, 138, 246, + 116, 45, 205, 220, 1, 124, 212, 13, 45, 205, 220, 1, 138, 212, 13, 45, + 205, 220, 1, 124, 220, 233, 45, 205, 220, 1, 138, 220, 233, 45, 205, 220, + 1, 124, 243, 113, 45, 205, 220, 1, 138, 243, 113, 45, 205, 220, 1, 124, + 135, 45, 205, 220, 1, 138, 135, 45, 205, 220, 1, 124, 209, 47, 45, 205, + 220, 1, 138, 209, 47, 45, 205, 220, 1, 124, 221, 191, 45, 205, 220, 1, + 138, 221, 191, 45, 205, 220, 1, 124, 248, 23, 45, 205, 220, 1, 138, 248, + 23, 45, 205, 220, 1, 124, 218, 69, 45, 205, 220, 1, 138, 218, 69, 45, + 205, 220, 1, 124, 218, 180, 45, 205, 220, 1, 138, 218, 180, 45, 205, 220, + 1, 124, 239, 186, 45, 205, 220, 1, 138, 239, 186, 45, 205, 220, 1, 124, + 224, 82, 45, 205, 220, 1, 138, 224, 82, 45, 205, 220, 1, 124, 202, 247, + 45, 205, 220, 1, 138, 202, 247, 45, 205, 220, 1, 124, 215, 227, 45, 205, + 220, 1, 138, 215, 227, 45, 205, 220, 1, 124, 227, 49, 45, 205, 220, 1, + 138, 227, 49, 45, 205, 220, 1, 124, 205, 189, 45, 205, 220, 1, 138, 205, + 189, 45, 205, 220, 1, 124, 236, 136, 45, 205, 220, 1, 138, 236, 136, 45, + 205, 220, 1, 124, 78, 45, 205, 220, 1, 138, 78, 45, 205, 220, 225, 141, + 230, 0, 45, 205, 220, 22, 252, 25, 45, 205, 220, 22, 75, 45, 205, 220, + 22, 207, 24, 45, 205, 220, 22, 68, 45, 205, 220, 22, 74, 45, 205, 220, + 22, 78, 45, 205, 220, 225, 141, 229, 118, 45, 205, 220, 22, 235, 171, 45, + 205, 220, 22, 207, 23, 45, 205, 220, 22, 207, 39, 45, 205, 220, 22, 250, + 32, 45, 205, 220, 22, 250, 8, 45, 205, 220, 22, 250, 231, 45, 205, 220, + 22, 250, 247, 45, 205, 220, 143, 225, 141, 241, 129, 45, 205, 220, 143, + 225, 141, 221, 52, 45, 205, 220, 143, 225, 141, 209, 47, 45, 205, 220, + 143, 225, 141, 211, 252, 45, 205, 220, 16, 229, 9, 45, 205, 220, 16, 221, + 52, 45, 205, 220, 16, 214, 253, 45, 205, 220, 16, 236, 137, 236, 131, 45, + 205, 220, 16, 229, 19, 229, 18, 225, 2, 225, 61, 1, 74, 225, 2, 225, 61, + 1, 78, 225, 2, 225, 61, 1, 246, 199, 225, 2, 225, 61, 1, 221, 11, 225, 2, + 225, 61, 1, 207, 241, 225, 2, 225, 61, 1, 207, 229, 225, 2, 225, 61, 1, + 244, 120, 225, 2, 225, 61, 1, 244, 104, 225, 2, 225, 61, 1, 221, 227, + 225, 2, 225, 61, 1, 213, 90, 225, 2, 225, 61, 1, 211, 164, 225, 2, 225, + 61, 22, 2, 231, 83, 225, 2, 225, 61, 22, 2, 206, 178, 225, 2, 225, 61, + 22, 2, 251, 245, 225, 2, 225, 61, 22, 2, 250, 34, 225, 2, 225, 61, 22, 2, + 251, 238, 225, 2, 225, 61, 246, 159, 225, 2, 225, 61, 251, 70, 229, 107, + 225, 2, 225, 61, 250, 209, 225, 2, 225, 61, 4, 216, 98, 82, 225, 2, 225, + 61, 203, 238, 216, 98, 82, 225, 2, 225, 61, 22, 2, 205, 199, 225, 2, 225, + 61, 205, 204, 33, 4, 207, 222, 33, 4, 207, 225, 33, 4, 207, 228, 33, 4, + 207, 226, 33, 4, 207, 227, 33, 4, 207, 224, 33, 4, 244, 98, 33, 4, 244, + 100, 33, 4, 244, 103, 33, 4, 244, 101, 33, 4, 244, 102, 33, 4, 244, 99, + 33, 4, 241, 242, 33, 4, 241, 246, 33, 4, 241, 254, 33, 4, 241, 251, 33, + 4, 241, 252, 33, 4, 241, 243, 33, 4, 246, 252, 33, 4, 246, 246, 33, 4, + 246, 248, 33, 4, 246, 251, 33, 4, 246, 249, 33, 4, 246, 250, 33, 4, 246, + 247, 33, 4, 248, 198, 33, 4, 248, 177, 33, 4, 248, 189, 33, 4, 248, 197, + 33, 4, 248, 192, 33, 4, 248, 193, 33, 4, 248, 181, 8, 5, 1, 248, 225, + 251, 2, 8, 5, 1, 34, 216, 71, 8, 5, 1, 248, 39, 74, 8, 5, 1, 248, 225, + 74, 8, 5, 1, 188, 3, 239, 199, 8, 5, 1, 227, 187, 240, 174, 8, 5, 1, 132, + 239, 76, 3, 245, 126, 8, 5, 1, 228, 131, 3, 230, 239, 227, 241, 194, 8, + 5, 1, 228, 131, 3, 52, 101, 208, 227, 8, 5, 1, 228, 131, 3, 101, 215, + 252, 8, 5, 1, 226, 186, 3, 245, 126, 8, 5, 1, 223, 164, 3, 245, 126, 8, + 5, 1, 241, 79, 3, 245, 126, 8, 5, 1, 248, 39, 78, 8, 5, 1, 248, 39, 158, + 3, 95, 8, 5, 1, 171, 158, 3, 95, 8, 5, 1, 230, 239, 220, 73, 8, 5, 1, + 207, 174, 220, 74, 3, 95, 8, 5, 1, 207, 174, 220, 74, 3, 236, 106, 95, 8, + 5, 1, 207, 174, 158, 220, 4, 8, 5, 1, 207, 174, 158, 220, 5, 3, 95, 8, 5, + 1, 211, 66, 146, 8, 1, 5, 6, 217, 1, 3, 50, 227, 210, 8, 5, 1, 217, 1, + 204, 3, 237, 102, 8, 5, 1, 52, 146, 8, 5, 1, 217, 1, 3, 245, 126, 8, 5, + 1, 52, 217, 1, 3, 245, 126, 8, 5, 1, 132, 146, 8, 5, 1, 132, 217, 1, 3, + 215, 252, 8, 5, 1, 248, 216, 241, 7, 8, 5, 1, 106, 3, 212, 228, 50, 227, + 210, 8, 5, 1, 106, 248, 231, 3, 212, 228, 50, 227, 210, 8, 5, 1, 207, 17, + 8, 5, 1, 207, 174, 207, 17, 8, 5, 1, 106, 3, 49, 113, 8, 5, 1, 246, 142, + 8, 5, 1, 246, 143, 3, 124, 50, 215, 252, 8, 5, 1, 246, 143, 3, 124, 49, + 213, 125, 8, 5, 1, 203, 197, 3, 124, 50, 215, 252, 8, 5, 1, 203, 197, 3, + 163, 49, 227, 210, 8, 5, 1, 203, 197, 3, 163, 49, 227, 211, 25, 124, 50, + 215, 252, 8, 5, 1, 203, 197, 3, 163, 49, 227, 211, 3, 213, 125, 8, 5, 1, + 203, 125, 3, 212, 228, 50, 227, 210, 65, 247, 215, 3, 230, 239, 247, 214, + 65, 1, 5, 237, 31, 65, 1, 5, 228, 131, 3, 230, 239, 227, 241, 194, 65, 1, + 5, 228, 131, 3, 101, 208, 227, 65, 1, 5, 106, 3, 49, 113, 8, 5, 1, 215, + 11, 203, 66, 8, 5, 1, 230, 228, 74, 8, 5, 1, 171, 220, 73, 8, 5, 1, 206, + 228, 8, 5, 1, 230, 239, 251, 2, 30, 1, 5, 6, 220, 36, 90, 5, 1, 63, 90, + 5, 1, 74, 90, 5, 1, 75, 90, 5, 1, 78, 90, 5, 1, 68, 90, 5, 1, 206, 164, + 90, 5, 1, 239, 8, 90, 5, 1, 173, 90, 5, 1, 238, 190, 90, 5, 1, 238, 81, + 90, 5, 1, 238, 39, 90, 5, 1, 237, 230, 90, 5, 1, 237, 192, 90, 5, 1, 152, + 90, 5, 1, 237, 67, 90, 5, 1, 237, 3, 90, 5, 1, 236, 136, 90, 5, 1, 236, + 26, 90, 5, 1, 235, 255, 90, 5, 1, 228, 113, 90, 5, 1, 227, 234, 90, 5, 1, + 227, 148, 90, 5, 1, 227, 49, 90, 5, 1, 226, 239, 90, 5, 1, 226, 208, 90, + 5, 1, 192, 90, 5, 1, 225, 20, 90, 5, 1, 224, 155, 90, 5, 1, 224, 82, 90, + 5, 1, 223, 246, 90, 5, 1, 201, 201, 90, 5, 1, 236, 160, 90, 5, 1, 223, + 93, 90, 5, 1, 222, 240, 90, 5, 1, 222, 100, 90, 5, 1, 221, 191, 90, 5, 1, + 221, 84, 90, 5, 1, 221, 22, 90, 5, 1, 217, 64, 90, 5, 1, 217, 50, 90, 5, + 1, 217, 43, 90, 5, 1, 217, 34, 90, 5, 1, 217, 23, 90, 5, 1, 217, 21, 90, + 5, 1, 215, 36, 90, 5, 1, 194, 90, 5, 1, 214, 177, 90, 5, 1, 212, 162, 90, + 5, 1, 212, 13, 90, 5, 1, 211, 10, 90, 5, 1, 210, 177, 90, 5, 1, 244, 212, + 90, 5, 1, 210, 22, 90, 5, 1, 244, 75, 90, 5, 1, 209, 187, 90, 5, 1, 243, + 233, 90, 5, 1, 209, 2, 90, 5, 1, 243, 113, 90, 5, 1, 242, 42, 90, 5, 1, + 242, 13, 90, 5, 1, 243, 124, 90, 5, 1, 208, 190, 90, 5, 1, 208, 189, 90, + 5, 1, 208, 178, 90, 5, 1, 208, 177, 90, 5, 1, 208, 176, 90, 5, 1, 208, + 175, 90, 5, 1, 208, 20, 90, 5, 1, 208, 14, 90, 5, 1, 207, 255, 90, 5, 1, + 207, 253, 90, 5, 1, 207, 249, 90, 5, 1, 207, 248, 90, 5, 1, 204, 111, 90, + 5, 1, 204, 62, 90, 5, 1, 204, 30, 90, 5, 1, 204, 0, 90, 5, 1, 203, 217, + 90, 5, 1, 203, 204, 90, 5, 1, 198, 225, 2, 225, 61, 1, 229, 16, 225, 2, + 225, 61, 1, 214, 253, 225, 2, 225, 61, 1, 228, 86, 225, 2, 225, 61, 1, + 224, 93, 225, 2, 225, 61, 1, 185, 225, 2, 225, 61, 1, 201, 201, 225, 2, + 225, 61, 1, 246, 134, 225, 2, 225, 61, 1, 208, 229, 225, 2, 225, 61, 1, + 229, 110, 225, 2, 225, 61, 1, 222, 118, 225, 2, 225, 61, 1, 209, 39, 225, + 2, 225, 61, 1, 204, 105, 225, 2, 225, 61, 1, 203, 76, 225, 2, 225, 61, 1, + 236, 18, 225, 2, 225, 61, 1, 206, 255, 225, 2, 225, 61, 1, 75, 225, 2, + 225, 61, 1, 218, 202, 225, 2, 225, 61, 1, 250, 45, 225, 2, 225, 61, 1, + 238, 32, 225, 2, 225, 61, 1, 230, 147, 225, 2, 225, 61, 1, 216, 197, 225, + 2, 225, 61, 1, 249, 32, 225, 2, 225, 61, 1, 230, 133, 225, 2, 225, 61, 1, + 243, 190, 225, 2, 225, 61, 1, 238, 88, 225, 2, 225, 61, 1, 243, 235, 225, + 2, 225, 61, 1, 248, 96, 225, 2, 225, 61, 1, 229, 17, 227, 19, 225, 2, + 225, 61, 1, 228, 87, 227, 19, 225, 2, 225, 61, 1, 224, 94, 227, 19, 225, + 2, 225, 61, 1, 219, 169, 227, 19, 225, 2, 225, 61, 1, 223, 111, 227, 19, + 225, 2, 225, 61, 1, 208, 230, 227, 19, 225, 2, 225, 61, 1, 222, 119, 227, + 19, 225, 2, 225, 61, 1, 235, 206, 227, 19, 225, 2, 225, 61, 22, 2, 220, + 30, 225, 2, 225, 61, 22, 2, 231, 47, 225, 2, 225, 61, 22, 2, 250, 230, + 225, 2, 225, 61, 22, 2, 203, 41, 225, 2, 225, 61, 22, 2, 211, 242, 225, + 2, 225, 61, 22, 2, 206, 252, 225, 2, 225, 61, 22, 2, 246, 157, 225, 2, + 225, 61, 22, 2, 221, 37, 225, 2, 225, 61, 246, 158, 225, 2, 225, 61, 226, + 223, 230, 190, 225, 2, 225, 61, 250, 149, 230, 190, 225, 2, 225, 61, 17, + 202, 84, 225, 2, 225, 61, 17, 105, 225, 2, 225, 61, 17, 108, 225, 2, 225, + 61, 17, 147, 225, 2, 225, 61, 17, 149, 225, 2, 225, 61, 17, 170, 225, 2, + 225, 61, 17, 195, 225, 2, 225, 61, 17, 213, 111, 225, 2, 225, 61, 17, + 199, 225, 2, 225, 61, 17, 222, 63, 28, 176, 220, 174, 28, 176, 220, 179, + 28, 176, 202, 246, 28, 176, 202, 245, 28, 176, 202, 244, 28, 176, 207, + 89, 28, 176, 207, 93, 28, 176, 202, 211, 28, 176, 202, 207, 28, 176, 240, + 237, 28, 176, 240, 235, 28, 176, 240, 236, 28, 176, 240, 233, 28, 176, + 235, 196, 28, 176, 235, 195, 28, 176, 235, 193, 28, 176, 235, 194, 28, + 176, 235, 199, 28, 176, 235, 192, 28, 176, 235, 191, 28, 176, 235, 201, + 28, 176, 250, 136, 28, 176, 250, 135, 28, 107, 222, 86, 28, 107, 222, 92, + 28, 107, 211, 145, 28, 107, 211, 144, 28, 107, 208, 235, 28, 107, 208, + 233, 28, 107, 208, 232, 28, 107, 208, 238, 28, 107, 208, 239, 28, 107, + 208, 231, 28, 107, 216, 26, 28, 107, 216, 41, 28, 107, 211, 151, 28, 107, + 216, 38, 28, 107, 216, 28, 28, 107, 216, 30, 28, 107, 216, 17, 28, 107, + 216, 18, 28, 107, 229, 243, 28, 107, 224, 136, 28, 107, 224, 130, 28, + 107, 211, 155, 28, 107, 224, 133, 28, 107, 224, 139, 28, 107, 218, 134, + 28, 107, 218, 143, 28, 107, 218, 147, 28, 107, 211, 153, 28, 107, 218, + 137, 28, 107, 218, 151, 28, 107, 218, 152, 28, 107, 212, 103, 28, 107, + 212, 106, 28, 107, 211, 149, 28, 107, 211, 147, 28, 107, 212, 101, 28, + 107, 212, 109, 28, 107, 212, 110, 28, 107, 212, 95, 28, 107, 212, 108, + 28, 107, 219, 105, 28, 107, 219, 106, 28, 107, 203, 27, 28, 107, 203, 28, + 28, 107, 246, 72, 28, 107, 246, 71, 28, 107, 211, 160, 28, 107, 218, 187, + 28, 107, 218, 186, 12, 15, 233, 74, 12, 15, 233, 73, 12, 15, 233, 72, 12, + 15, 233, 71, 12, 15, 233, 70, 12, 15, 233, 69, 12, 15, 233, 68, 12, 15, + 233, 67, 12, 15, 233, 66, 12, 15, 233, 65, 12, 15, 233, 64, 12, 15, 233, + 63, 12, 15, 233, 62, 12, 15, 233, 61, 12, 15, 233, 60, 12, 15, 233, 59, + 12, 15, 233, 58, 12, 15, 233, 57, 12, 15, 233, 56, 12, 15, 233, 55, 12, + 15, 233, 54, 12, 15, 233, 53, 12, 15, 233, 52, 12, 15, 233, 51, 12, 15, + 233, 50, 12, 15, 233, 49, 12, 15, 233, 48, 12, 15, 233, 47, 12, 15, 233, + 46, 12, 15, 233, 45, 12, 15, 233, 44, 12, 15, 233, 43, 12, 15, 233, 42, + 12, 15, 233, 41, 12, 15, 233, 40, 12, 15, 233, 39, 12, 15, 233, 38, 12, + 15, 233, 37, 12, 15, 233, 36, 12, 15, 233, 35, 12, 15, 233, 34, 12, 15, + 233, 33, 12, 15, 233, 32, 12, 15, 233, 31, 12, 15, 233, 30, 12, 15, 233, + 29, 12, 15, 233, 28, 12, 15, 233, 27, 12, 15, 233, 26, 12, 15, 233, 25, + 12, 15, 233, 24, 12, 15, 233, 23, 12, 15, 233, 22, 12, 15, 233, 21, 12, + 15, 233, 20, 12, 15, 233, 19, 12, 15, 233, 18, 12, 15, 233, 17, 12, 15, + 233, 16, 12, 15, 233, 15, 12, 15, 233, 14, 12, 15, 233, 13, 12, 15, 233, + 12, 12, 15, 233, 11, 12, 15, 233, 10, 12, 15, 233, 9, 12, 15, 233, 8, 12, + 15, 233, 7, 12, 15, 233, 6, 12, 15, 233, 5, 12, 15, 233, 4, 12, 15, 233, + 3, 12, 15, 233, 2, 12, 15, 233, 1, 12, 15, 233, 0, 12, 15, 232, 255, 12, + 15, 232, 254, 12, 15, 232, 253, 12, 15, 232, 252, 12, 15, 232, 251, 12, + 15, 232, 250, 12, 15, 232, 249, 12, 15, 232, 248, 12, 15, 232, 247, 12, + 15, 232, 246, 12, 15, 232, 245, 12, 15, 232, 244, 12, 15, 232, 243, 12, + 15, 232, 242, 12, 15, 232, 241, 12, 15, 232, 240, 12, 15, 232, 239, 12, + 15, 232, 238, 12, 15, 232, 237, 12, 15, 232, 236, 12, 15, 232, 235, 12, + 15, 232, 234, 12, 15, 232, 233, 12, 15, 232, 232, 12, 15, 232, 231, 12, + 15, 232, 230, 12, 15, 232, 229, 12, 15, 232, 228, 12, 15, 232, 227, 12, + 15, 232, 226, 12, 15, 232, 225, 12, 15, 232, 224, 12, 15, 232, 223, 12, + 15, 232, 222, 12, 15, 232, 221, 12, 15, 232, 220, 12, 15, 232, 219, 12, + 15, 232, 218, 12, 15, 232, 217, 12, 15, 232, 216, 12, 15, 232, 215, 12, + 15, 232, 214, 12, 15, 232, 213, 12, 15, 232, 212, 12, 15, 232, 211, 12, + 15, 232, 210, 12, 15, 232, 209, 12, 15, 232, 208, 12, 15, 232, 207, 12, + 15, 232, 206, 12, 15, 232, 205, 12, 15, 232, 204, 12, 15, 232, 203, 12, + 15, 232, 202, 12, 15, 232, 201, 12, 15, 232, 200, 12, 15, 232, 199, 12, + 15, 232, 198, 12, 15, 232, 197, 12, 15, 232, 196, 12, 15, 232, 195, 12, + 15, 232, 194, 12, 15, 232, 193, 12, 15, 232, 192, 12, 15, 232, 191, 12, + 15, 232, 190, 12, 15, 232, 189, 12, 15, 232, 188, 12, 15, 232, 187, 12, + 15, 232, 186, 12, 15, 232, 185, 12, 15, 232, 184, 12, 15, 232, 183, 12, + 15, 232, 182, 12, 15, 232, 181, 12, 15, 232, 180, 12, 15, 232, 179, 12, + 15, 232, 178, 12, 15, 232, 177, 12, 15, 232, 176, 12, 15, 232, 175, 12, + 15, 232, 174, 12, 15, 232, 173, 12, 15, 232, 172, 12, 15, 232, 171, 12, + 15, 232, 170, 12, 15, 232, 169, 12, 15, 232, 168, 12, 15, 232, 167, 12, + 15, 232, 166, 12, 15, 232, 165, 12, 15, 232, 164, 12, 15, 232, 163, 12, + 15, 232, 162, 12, 15, 232, 161, 12, 15, 232, 160, 12, 15, 232, 159, 12, + 15, 232, 158, 12, 15, 232, 157, 12, 15, 232, 156, 12, 15, 232, 155, 12, + 15, 232, 154, 12, 15, 232, 153, 12, 15, 232, 152, 12, 15, 232, 151, 12, + 15, 232, 150, 12, 15, 232, 149, 12, 15, 232, 148, 12, 15, 232, 147, 12, + 15, 232, 146, 12, 15, 232, 145, 12, 15, 232, 144, 12, 15, 232, 143, 12, + 15, 232, 142, 12, 15, 232, 141, 12, 15, 232, 140, 12, 15, 232, 139, 12, + 15, 232, 138, 12, 15, 232, 137, 12, 15, 232, 136, 12, 15, 232, 135, 12, + 15, 232, 134, 12, 15, 232, 133, 12, 15, 232, 132, 12, 15, 232, 131, 12, + 15, 232, 130, 12, 15, 232, 129, 12, 15, 232, 128, 12, 15, 232, 127, 12, + 15, 232, 126, 12, 15, 232, 125, 12, 15, 232, 124, 12, 15, 232, 123, 12, + 15, 232, 122, 12, 15, 232, 121, 12, 15, 232, 120, 12, 15, 232, 119, 12, + 15, 232, 118, 12, 15, 232, 117, 12, 15, 232, 116, 12, 15, 232, 115, 12, + 15, 232, 114, 12, 15, 232, 113, 12, 15, 232, 112, 12, 15, 232, 111, 12, + 15, 232, 110, 12, 15, 232, 109, 12, 15, 232, 108, 12, 15, 232, 107, 12, + 15, 232, 106, 12, 15, 232, 105, 12, 15, 232, 104, 12, 15, 232, 103, 12, + 15, 232, 102, 12, 15, 232, 101, 12, 15, 232, 100, 12, 15, 232, 99, 12, + 15, 232, 98, 12, 15, 232, 97, 12, 15, 232, 96, 12, 15, 232, 95, 12, 15, + 232, 94, 12, 15, 232, 93, 12, 15, 232, 92, 12, 15, 232, 91, 12, 15, 232, + 90, 12, 15, 232, 89, 12, 15, 232, 88, 12, 15, 232, 87, 12, 15, 232, 86, + 12, 15, 232, 85, 12, 15, 232, 84, 12, 15, 232, 83, 12, 15, 232, 82, 12, + 15, 232, 81, 12, 15, 232, 80, 12, 15, 232, 79, 12, 15, 232, 78, 12, 15, + 232, 77, 12, 15, 232, 76, 12, 15, 232, 75, 12, 15, 232, 74, 12, 15, 232, + 73, 12, 15, 232, 72, 12, 15, 232, 71, 12, 15, 232, 70, 12, 15, 232, 69, + 12, 15, 232, 68, 12, 15, 232, 67, 12, 15, 232, 66, 12, 15, 232, 65, 12, + 15, 232, 64, 12, 15, 232, 63, 12, 15, 232, 62, 12, 15, 232, 61, 12, 15, + 232, 60, 12, 15, 232, 59, 12, 15, 232, 58, 12, 15, 232, 57, 12, 15, 232, + 56, 12, 15, 232, 55, 12, 15, 232, 54, 12, 15, 232, 53, 12, 15, 232, 52, + 12, 15, 232, 51, 12, 15, 232, 50, 12, 15, 232, 49, 12, 15, 232, 48, 12, + 15, 232, 47, 12, 15, 232, 46, 12, 15, 232, 45, 12, 15, 232, 44, 12, 15, + 232, 43, 12, 15, 232, 42, 12, 15, 232, 41, 12, 15, 232, 40, 12, 15, 232, + 39, 12, 15, 232, 38, 12, 15, 232, 37, 12, 15, 232, 36, 12, 15, 232, 35, + 12, 15, 232, 34, 12, 15, 232, 33, 12, 15, 232, 32, 12, 15, 232, 31, 12, + 15, 232, 30, 12, 15, 232, 29, 12, 15, 232, 28, 12, 15, 232, 27, 12, 15, + 232, 26, 12, 15, 232, 25, 12, 15, 232, 24, 12, 15, 232, 23, 12, 15, 232, + 22, 12, 15, 232, 21, 12, 15, 232, 20, 12, 15, 232, 19, 12, 15, 232, 18, + 12, 15, 232, 17, 12, 15, 232, 16, 12, 15, 232, 15, 12, 15, 232, 14, 12, + 15, 232, 13, 12, 15, 232, 12, 12, 15, 232, 11, 12, 15, 232, 10, 12, 15, + 232, 9, 12, 15, 232, 8, 12, 15, 232, 7, 12, 15, 232, 6, 12, 15, 232, 5, + 12, 15, 232, 4, 12, 15, 232, 3, 12, 15, 232, 2, 12, 15, 232, 1, 12, 15, + 232, 0, 12, 15, 231, 255, 12, 15, 231, 254, 12, 15, 231, 253, 12, 15, + 231, 252, 12, 15, 231, 251, 12, 15, 231, 250, 12, 15, 231, 249, 12, 15, + 231, 248, 12, 15, 231, 247, 12, 15, 231, 246, 12, 15, 231, 245, 12, 15, + 231, 244, 12, 15, 231, 243, 12, 15, 231, 242, 12, 15, 231, 241, 12, 15, + 231, 240, 12, 15, 231, 239, 12, 15, 231, 238, 12, 15, 231, 237, 12, 15, + 231, 236, 12, 15, 231, 235, 12, 15, 231, 234, 12, 15, 231, 233, 12, 15, + 231, 232, 12, 15, 231, 231, 12, 15, 231, 230, 12, 15, 231, 229, 12, 15, + 231, 228, 12, 15, 231, 227, 12, 15, 231, 226, 12, 15, 231, 225, 12, 15, + 231, 224, 12, 15, 231, 223, 12, 15, 231, 222, 12, 15, 231, 221, 12, 15, + 231, 220, 12, 15, 231, 219, 12, 15, 231, 218, 12, 15, 231, 217, 12, 15, + 231, 216, 12, 15, 231, 215, 12, 15, 231, 214, 12, 15, 231, 213, 12, 15, + 231, 212, 12, 15, 231, 211, 12, 15, 231, 210, 12, 15, 231, 209, 12, 15, + 231, 208, 12, 15, 231, 207, 12, 15, 231, 206, 12, 15, 231, 205, 12, 15, + 231, 204, 12, 15, 231, 203, 12, 15, 231, 202, 12, 15, 231, 201, 12, 15, + 231, 200, 12, 15, 231, 199, 12, 15, 231, 198, 12, 15, 231, 197, 12, 15, + 231, 196, 12, 15, 231, 195, 12, 15, 231, 194, 12, 15, 231, 193, 12, 15, + 231, 192, 12, 15, 231, 191, 12, 15, 231, 190, 12, 15, 231, 189, 12, 15, + 231, 188, 12, 15, 231, 187, 12, 15, 231, 186, 12, 15, 231, 185, 12, 15, + 231, 184, 12, 15, 231, 183, 12, 15, 231, 182, 12, 15, 231, 181, 12, 15, + 231, 180, 12, 15, 231, 179, 12, 15, 231, 178, 12, 15, 231, 177, 12, 15, + 231, 176, 12, 15, 231, 175, 12, 15, 231, 174, 12, 15, 231, 173, 12, 15, + 231, 172, 12, 15, 231, 171, 12, 15, 231, 170, 12, 15, 231, 169, 12, 15, + 231, 168, 12, 15, 231, 167, 12, 15, 231, 166, 12, 15, 231, 165, 12, 15, + 231, 164, 12, 15, 231, 163, 12, 15, 231, 162, 12, 15, 231, 161, 12, 15, + 231, 160, 12, 15, 231, 159, 12, 15, 231, 158, 12, 15, 231, 157, 12, 15, + 231, 156, 12, 15, 231, 155, 12, 15, 231, 154, 12, 15, 231, 153, 12, 15, + 231, 152, 12, 15, 231, 151, 12, 15, 231, 150, 12, 15, 231, 149, 12, 15, + 231, 148, 12, 15, 231, 147, 12, 15, 231, 146, 12, 15, 231, 145, 12, 15, + 231, 144, 12, 15, 231, 143, 12, 15, 231, 142, 12, 15, 231, 141, 12, 15, + 231, 140, 12, 15, 231, 139, 12, 15, 231, 138, 12, 15, 231, 137, 12, 15, + 231, 136, 12, 15, 231, 135, 12, 15, 231, 134, 12, 15, 231, 133, 12, 15, + 231, 132, 12, 15, 231, 131, 12, 15, 231, 130, 12, 15, 231, 129, 12, 15, + 231, 128, 12, 15, 231, 127, 12, 15, 231, 126, 12, 15, 231, 125, 12, 15, + 231, 124, 12, 15, 231, 123, 12, 15, 231, 122, 12, 15, 231, 121, 12, 15, + 231, 120, 12, 15, 231, 119, 12, 15, 231, 118, 12, 15, 231, 117, 12, 15, + 231, 116, 12, 15, 231, 115, 8, 5, 32, 240, 30, 8, 5, 32, 240, 26, 8, 5, + 32, 239, 228, 8, 5, 32, 240, 29, 8, 5, 32, 240, 28, 8, 5, 32, 163, 215, + 94, 210, 69, 8, 5, 32, 211, 108, 178, 5, 32, 224, 241, 221, 152, 178, 5, + 32, 224, 241, 241, 167, 178, 5, 32, 224, 241, 231, 19, 178, 5, 32, 205, + 235, 221, 152, 178, 5, 32, 224, 241, 203, 174, 110, 1, 202, 237, 3, 236, + 232, 110, 218, 63, 230, 81, 206, 67, 110, 32, 203, 9, 202, 237, 202, 237, + 219, 54, 110, 1, 250, 250, 250, 3, 110, 1, 204, 27, 251, 30, 110, 1, 204, + 27, 244, 178, 110, 1, 204, 27, 237, 67, 110, 1, 204, 27, 230, 22, 110, 1, + 204, 27, 228, 20, 110, 1, 204, 27, 46, 224, 247, 110, 1, 204, 27, 216, + 91, 110, 1, 204, 27, 209, 203, 110, 1, 250, 250, 91, 54, 110, 1, 213, 0, + 3, 213, 0, 243, 85, 110, 1, 213, 0, 3, 212, 124, 243, 85, 110, 1, 213, 0, + 3, 244, 198, 25, 213, 0, 243, 85, 110, 1, 213, 0, 3, 244, 198, 25, 212, + 124, 243, 85, 110, 1, 137, 3, 219, 54, 110, 1, 137, 3, 217, 114, 110, 1, + 137, 3, 225, 105, 110, 1, 248, 109, 3, 244, 197, 110, 1, 238, 68, 3, 244, + 197, 110, 1, 244, 179, 3, 244, 197, 110, 1, 237, 68, 3, 225, 105, 110, 1, + 206, 60, 3, 244, 197, 110, 1, 202, 96, 3, 244, 197, 110, 1, 209, 133, 3, + 244, 197, 110, 1, 202, 237, 3, 244, 197, 110, 1, 46, 230, 23, 3, 244, + 197, 110, 1, 230, 23, 3, 244, 197, 110, 1, 228, 21, 3, 244, 197, 110, 1, + 224, 248, 3, 244, 197, 110, 1, 221, 41, 3, 244, 197, 110, 1, 214, 250, 3, + 244, 197, 110, 1, 46, 219, 35, 3, 244, 197, 110, 1, 219, 35, 3, 244, 197, + 110, 1, 208, 16, 3, 244, 197, 110, 1, 217, 75, 3, 244, 197, 110, 1, 216, + 92, 3, 244, 197, 110, 1, 213, 0, 3, 244, 197, 110, 1, 209, 204, 3, 244, + 197, 110, 1, 206, 60, 3, 236, 128, 110, 1, 248, 109, 3, 216, 200, 110, 1, + 230, 23, 3, 216, 200, 110, 1, 219, 35, 3, 216, 200, 110, 32, 137, 228, + 20, 10, 1, 137, 204, 88, 64, 18, 10, 1, 137, 204, 88, 46, 18, 10, 1, 248, + 149, 64, 18, 10, 1, 248, 149, 46, 18, 10, 1, 248, 149, 81, 18, 10, 1, + 248, 149, 174, 18, 10, 1, 219, 17, 64, 18, 10, 1, 219, 17, 46, 18, 10, 1, + 219, 17, 81, 18, 10, 1, 219, 17, 174, 18, 10, 1, 248, 137, 64, 18, 10, 1, + 248, 137, 46, 18, 10, 1, 248, 137, 81, 18, 10, 1, 248, 137, 174, 18, 10, + 1, 207, 232, 64, 18, 10, 1, 207, 232, 46, 18, 10, 1, 207, 232, 81, 18, + 10, 1, 207, 232, 174, 18, 10, 1, 209, 168, 64, 18, 10, 1, 209, 168, 46, + 18, 10, 1, 209, 168, 81, 18, 10, 1, 209, 168, 174, 18, 10, 1, 207, 234, + 64, 18, 10, 1, 207, 234, 46, 18, 10, 1, 207, 234, 81, 18, 10, 1, 207, + 234, 174, 18, 10, 1, 206, 49, 64, 18, 10, 1, 206, 49, 46, 18, 10, 1, 206, + 49, 81, 18, 10, 1, 206, 49, 174, 18, 10, 1, 219, 15, 64, 18, 10, 1, 219, + 15, 46, 18, 10, 1, 219, 15, 81, 18, 10, 1, 219, 15, 174, 18, 10, 1, 242, + 6, 64, 18, 10, 1, 242, 6, 46, 18, 10, 1, 242, 6, 81, 18, 10, 1, 242, 6, + 174, 18, 10, 1, 220, 255, 64, 18, 10, 1, 220, 255, 46, 18, 10, 1, 220, + 255, 81, 18, 10, 1, 220, 255, 174, 18, 10, 1, 209, 192, 64, 18, 10, 1, + 209, 192, 46, 18, 10, 1, 209, 192, 81, 18, 10, 1, 209, 192, 174, 18, 10, + 1, 209, 190, 64, 18, 10, 1, 209, 190, 46, 18, 10, 1, 209, 190, 81, 18, + 10, 1, 209, 190, 174, 18, 10, 1, 244, 118, 64, 18, 10, 1, 244, 118, 46, + 18, 10, 1, 244, 192, 64, 18, 10, 1, 244, 192, 46, 18, 10, 1, 242, 34, 64, + 18, 10, 1, 242, 34, 46, 18, 10, 1, 244, 116, 64, 18, 10, 1, 244, 116, 46, + 18, 10, 1, 230, 156, 64, 18, 10, 1, 230, 156, 46, 18, 10, 1, 215, 178, + 64, 18, 10, 1, 215, 178, 46, 18, 10, 1, 229, 190, 64, 18, 10, 1, 229, + 190, 46, 18, 10, 1, 229, 190, 81, 18, 10, 1, 229, 190, 174, 18, 10, 1, + 238, 252, 64, 18, 10, 1, 238, 252, 46, 18, 10, 1, 238, 252, 81, 18, 10, + 1, 238, 252, 174, 18, 10, 1, 237, 218, 64, 18, 10, 1, 237, 218, 46, 18, + 10, 1, 237, 218, 81, 18, 10, 1, 237, 218, 174, 18, 10, 1, 222, 127, 64, + 18, 10, 1, 222, 127, 46, 18, 10, 1, 222, 127, 81, 18, 10, 1, 222, 127, + 174, 18, 10, 1, 221, 179, 238, 86, 64, 18, 10, 1, 221, 179, 238, 86, 46, + 18, 10, 1, 215, 231, 64, 18, 10, 1, 215, 231, 46, 18, 10, 1, 215, 231, + 81, 18, 10, 1, 215, 231, 174, 18, 10, 1, 237, 44, 3, 89, 87, 64, 18, 10, + 1, 237, 44, 3, 89, 87, 46, 18, 10, 1, 237, 44, 238, 37, 64, 18, 10, 1, + 237, 44, 238, 37, 46, 18, 10, 1, 237, 44, 238, 37, 81, 18, 10, 1, 237, + 44, 238, 37, 174, 18, 10, 1, 237, 44, 243, 110, 64, 18, 10, 1, 237, 44, + 243, 110, 46, 18, 10, 1, 237, 44, 243, 110, 81, 18, 10, 1, 237, 44, 243, + 110, 174, 18, 10, 1, 89, 248, 224, 64, 18, 10, 1, 89, 248, 224, 46, 18, + 10, 1, 89, 248, 224, 3, 237, 128, 87, 64, 18, 10, 1, 89, 248, 224, 3, + 237, 128, 87, 46, 18, 10, 16, 70, 55, 10, 16, 70, 56, 10, 16, 120, 187, + 55, 10, 16, 120, 187, 56, 10, 16, 126, 187, 55, 10, 16, 126, 187, 56, 10, + 16, 126, 187, 218, 59, 183, 55, 10, 16, 126, 187, 218, 59, 183, 56, 10, + 16, 239, 147, 187, 55, 10, 16, 239, 147, 187, 56, 10, 16, 52, 80, 248, + 231, 56, 10, 16, 120, 187, 205, 244, 55, 10, 16, 120, 187, 205, 244, 56, + 10, 16, 215, 252, 10, 16, 5, 209, 252, 55, 10, 16, 5, 209, 252, 56, 10, + 1, 222, 206, 64, 18, 10, 1, 222, 206, 46, 18, 10, 1, 222, 206, 81, 18, + 10, 1, 222, 206, 174, 18, 10, 1, 106, 64, 18, 10, 1, 106, 46, 18, 10, 1, + 220, 74, 64, 18, 10, 1, 220, 74, 46, 18, 10, 1, 202, 214, 64, 18, 10, 1, + 202, 214, 46, 18, 10, 1, 106, 3, 237, 128, 87, 64, 18, 10, 1, 206, 56, + 64, 18, 10, 1, 206, 56, 46, 18, 10, 1, 229, 76, 220, 74, 64, 18, 10, 1, + 229, 76, 220, 74, 46, 18, 10, 1, 229, 76, 202, 214, 64, 18, 10, 1, 229, + 76, 202, 214, 46, 18, 10, 1, 188, 64, 18, 10, 1, 188, 46, 18, 10, 1, 188, + 81, 18, 10, 1, 188, 174, 18, 10, 1, 207, 16, 229, 205, 229, 76, 137, 225, + 130, 81, 18, 10, 1, 207, 16, 229, 205, 229, 76, 137, 225, 130, 174, 18, + 10, 32, 89, 3, 237, 128, 87, 3, 137, 64, 18, 10, 32, 89, 3, 237, 128, 87, + 3, 137, 46, 18, 10, 32, 89, 3, 237, 128, 87, 3, 251, 110, 64, 18, 10, 32, + 89, 3, 237, 128, 87, 3, 251, 110, 46, 18, 10, 32, 89, 3, 237, 128, 87, 3, + 204, 71, 64, 18, 10, 32, 89, 3, 237, 128, 87, 3, 204, 71, 46, 18, 10, 32, + 89, 3, 237, 128, 87, 3, 106, 64, 18, 10, 32, 89, 3, 237, 128, 87, 3, 106, + 46, 18, 10, 32, 89, 3, 237, 128, 87, 3, 220, 74, 64, 18, 10, 32, 89, 3, + 237, 128, 87, 3, 220, 74, 46, 18, 10, 32, 89, 3, 237, 128, 87, 3, 202, + 214, 64, 18, 10, 32, 89, 3, 237, 128, 87, 3, 202, 214, 46, 18, 10, 32, + 89, 3, 237, 128, 87, 3, 188, 64, 18, 10, 32, 89, 3, 237, 128, 87, 3, 188, + 46, 18, 10, 32, 89, 3, 237, 128, 87, 3, 188, 81, 18, 10, 32, 207, 16, + 229, 76, 89, 3, 237, 128, 87, 3, 137, 225, 130, 64, 18, 10, 32, 207, 16, + 229, 76, 89, 3, 237, 128, 87, 3, 137, 225, 130, 46, 18, 10, 32, 207, 16, + 229, 76, 89, 3, 237, 128, 87, 3, 137, 225, 130, 81, 18, 10, 1, 240, 75, + 89, 64, 18, 10, 1, 240, 75, 89, 46, 18, 10, 1, 240, 75, 89, 81, 18, 10, + 1, 240, 75, 89, 174, 18, 10, 32, 89, 3, 237, 128, 87, 3, 184, 64, 18, 10, + 32, 89, 3, 237, 128, 87, 3, 151, 64, 18, 10, 32, 89, 3, 237, 128, 87, 3, + 83, 64, 18, 10, 32, 89, 3, 237, 128, 87, 3, 137, 225, 130, 64, 18, 10, + 32, 89, 3, 237, 128, 87, 3, 89, 64, 18, 10, 32, 248, 139, 3, 184, 64, 18, + 10, 32, 248, 139, 3, 151, 64, 18, 10, 32, 248, 139, 3, 229, 141, 64, 18, + 10, 32, 248, 139, 3, 83, 64, 18, 10, 32, 248, 139, 3, 137, 225, 130, 64, + 18, 10, 32, 248, 139, 3, 89, 64, 18, 10, 32, 209, 170, 3, 184, 64, 18, + 10, 32, 209, 170, 3, 151, 64, 18, 10, 32, 209, 170, 3, 229, 141, 64, 18, + 10, 32, 209, 170, 3, 83, 64, 18, 10, 32, 209, 170, 3, 137, 225, 130, 64, + 18, 10, 32, 209, 170, 3, 89, 64, 18, 10, 32, 209, 89, 3, 184, 64, 18, 10, + 32, 209, 89, 3, 83, 64, 18, 10, 32, 209, 89, 3, 137, 225, 130, 64, 18, + 10, 32, 209, 89, 3, 89, 64, 18, 10, 32, 184, 3, 151, 64, 18, 10, 32, 184, + 3, 83, 64, 18, 10, 32, 151, 3, 184, 64, 18, 10, 32, 151, 3, 83, 64, 18, + 10, 32, 229, 141, 3, 184, 64, 18, 10, 32, 229, 141, 3, 151, 64, 18, 10, + 32, 229, 141, 3, 83, 64, 18, 10, 32, 214, 162, 3, 184, 64, 18, 10, 32, + 214, 162, 3, 151, 64, 18, 10, 32, 214, 162, 3, 229, 141, 64, 18, 10, 32, + 214, 162, 3, 83, 64, 18, 10, 32, 215, 29, 3, 151, 64, 18, 10, 32, 215, + 29, 3, 83, 64, 18, 10, 32, 244, 208, 3, 184, 64, 18, 10, 32, 244, 208, 3, + 151, 64, 18, 10, 32, 244, 208, 3, 229, 141, 64, 18, 10, 32, 244, 208, 3, + 83, 64, 18, 10, 32, 209, 252, 3, 151, 64, 18, 10, 32, 209, 252, 3, 83, + 64, 18, 10, 32, 202, 111, 3, 83, 64, 18, 10, 32, 251, 60, 3, 184, 64, 18, + 10, 32, 251, 60, 3, 83, 64, 18, 10, 32, 238, 115, 3, 184, 64, 18, 10, 32, + 238, 115, 3, 83, 64, 18, 10, 32, 240, 48, 3, 184, 64, 18, 10, 32, 240, + 48, 3, 151, 64, 18, 10, 32, 240, 48, 3, 229, 141, 64, 18, 10, 32, 240, + 48, 3, 83, 64, 18, 10, 32, 240, 48, 3, 137, 225, 130, 64, 18, 10, 32, + 240, 48, 3, 89, 64, 18, 10, 32, 217, 120, 3, 151, 64, 18, 10, 32, 217, + 120, 3, 83, 64, 18, 10, 32, 217, 120, 3, 137, 225, 130, 64, 18, 10, 32, + 217, 120, 3, 89, 64, 18, 10, 32, 230, 23, 3, 137, 64, 18, 10, 32, 230, + 23, 3, 184, 64, 18, 10, 32, 230, 23, 3, 151, 64, 18, 10, 32, 230, 23, 3, + 229, 141, 64, 18, 10, 32, 230, 23, 3, 228, 29, 64, 18, 10, 32, 230, 23, + 3, 83, 64, 18, 10, 32, 230, 23, 3, 137, 225, 130, 64, 18, 10, 32, 230, + 23, 3, 89, 64, 18, 10, 32, 228, 29, 3, 184, 64, 18, 10, 32, 228, 29, 3, + 151, 64, 18, 10, 32, 228, 29, 3, 229, 141, 64, 18, 10, 32, 228, 29, 3, + 83, 64, 18, 10, 32, 228, 29, 3, 137, 225, 130, 64, 18, 10, 32, 228, 29, + 3, 89, 64, 18, 10, 32, 83, 3, 184, 64, 18, 10, 32, 83, 3, 151, 64, 18, + 10, 32, 83, 3, 229, 141, 64, 18, 10, 32, 83, 3, 83, 64, 18, 10, 32, 83, + 3, 137, 225, 130, 64, 18, 10, 32, 83, 3, 89, 64, 18, 10, 32, 221, 179, 3, + 184, 64, 18, 10, 32, 221, 179, 3, 151, 64, 18, 10, 32, 221, 179, 3, 229, + 141, 64, 18, 10, 32, 221, 179, 3, 83, 64, 18, 10, 32, 221, 179, 3, 137, + 225, 130, 64, 18, 10, 32, 221, 179, 3, 89, 64, 18, 10, 32, 237, 44, 3, + 184, 64, 18, 10, 32, 237, 44, 3, 83, 64, 18, 10, 32, 237, 44, 3, 137, + 225, 130, 64, 18, 10, 32, 237, 44, 3, 89, 64, 18, 10, 32, 89, 3, 184, 64, + 18, 10, 32, 89, 3, 151, 64, 18, 10, 32, 89, 3, 229, 141, 64, 18, 10, 32, + 89, 3, 83, 64, 18, 10, 32, 89, 3, 137, 225, 130, 64, 18, 10, 32, 89, 3, + 89, 64, 18, 10, 32, 209, 101, 3, 210, 199, 137, 64, 18, 10, 32, 216, 123, + 3, 210, 199, 137, 64, 18, 10, 32, 137, 225, 130, 3, 210, 199, 137, 64, + 18, 10, 32, 213, 81, 3, 244, 171, 64, 18, 10, 32, 213, 81, 3, 229, 228, + 64, 18, 10, 32, 213, 81, 3, 240, 72, 64, 18, 10, 32, 213, 81, 3, 244, + 173, 64, 18, 10, 32, 213, 81, 3, 229, 230, 64, 18, 10, 32, 213, 81, 3, + 210, 199, 137, 64, 18, 10, 32, 89, 3, 237, 128, 87, 3, 216, 123, 46, 18, + 10, 32, 89, 3, 237, 128, 87, 3, 202, 108, 46, 18, 10, 32, 89, 3, 237, + 128, 87, 3, 83, 46, 18, 10, 32, 89, 3, 237, 128, 87, 3, 221, 179, 46, 18, + 10, 32, 89, 3, 237, 128, 87, 3, 137, 225, 130, 46, 18, 10, 32, 89, 3, + 237, 128, 87, 3, 89, 46, 18, 10, 32, 248, 139, 3, 216, 123, 46, 18, 10, + 32, 248, 139, 3, 202, 108, 46, 18, 10, 32, 248, 139, 3, 83, 46, 18, 10, + 32, 248, 139, 3, 221, 179, 46, 18, 10, 32, 248, 139, 3, 137, 225, 130, + 46, 18, 10, 32, 248, 139, 3, 89, 46, 18, 10, 32, 209, 170, 3, 216, 123, + 46, 18, 10, 32, 209, 170, 3, 202, 108, 46, 18, 10, 32, 209, 170, 3, 83, + 46, 18, 10, 32, 209, 170, 3, 221, 179, 46, 18, 10, 32, 209, 170, 3, 137, + 225, 130, 46, 18, 10, 32, 209, 170, 3, 89, 46, 18, 10, 32, 209, 89, 3, + 216, 123, 46, 18, 10, 32, 209, 89, 3, 202, 108, 46, 18, 10, 32, 209, 89, + 3, 83, 46, 18, 10, 32, 209, 89, 3, 221, 179, 46, 18, 10, 32, 209, 89, 3, + 137, 225, 130, 46, 18, 10, 32, 209, 89, 3, 89, 46, 18, 10, 32, 240, 48, + 3, 137, 225, 130, 46, 18, 10, 32, 240, 48, 3, 89, 46, 18, 10, 32, 217, + 120, 3, 137, 225, 130, 46, 18, 10, 32, 217, 120, 3, 89, 46, 18, 10, 32, + 230, 23, 3, 137, 46, 18, 10, 32, 230, 23, 3, 228, 29, 46, 18, 10, 32, + 230, 23, 3, 83, 46, 18, 10, 32, 230, 23, 3, 137, 225, 130, 46, 18, 10, + 32, 230, 23, 3, 89, 46, 18, 10, 32, 228, 29, 3, 83, 46, 18, 10, 32, 228, + 29, 3, 137, 225, 130, 46, 18, 10, 32, 228, 29, 3, 89, 46, 18, 10, 32, 83, + 3, 137, 46, 18, 10, 32, 83, 3, 83, 46, 18, 10, 32, 221, 179, 3, 216, 123, + 46, 18, 10, 32, 221, 179, 3, 202, 108, 46, 18, 10, 32, 221, 179, 3, 83, + 46, 18, 10, 32, 221, 179, 3, 221, 179, 46, 18, 10, 32, 221, 179, 3, 137, + 225, 130, 46, 18, 10, 32, 221, 179, 3, 89, 46, 18, 10, 32, 137, 225, 130, + 3, 210, 199, 137, 46, 18, 10, 32, 89, 3, 216, 123, 46, 18, 10, 32, 89, 3, + 202, 108, 46, 18, 10, 32, 89, 3, 83, 46, 18, 10, 32, 89, 3, 221, 179, 46, + 18, 10, 32, 89, 3, 137, 225, 130, 46, 18, 10, 32, 89, 3, 89, 46, 18, 10, + 32, 89, 3, 237, 128, 87, 3, 184, 81, 18, 10, 32, 89, 3, 237, 128, 87, 3, + 151, 81, 18, 10, 32, 89, 3, 237, 128, 87, 3, 229, 141, 81, 18, 10, 32, + 89, 3, 237, 128, 87, 3, 83, 81, 18, 10, 32, 89, 3, 237, 128, 87, 3, 237, + 44, 81, 18, 10, 32, 248, 139, 3, 184, 81, 18, 10, 32, 248, 139, 3, 151, + 81, 18, 10, 32, 248, 139, 3, 229, 141, 81, 18, 10, 32, 248, 139, 3, 83, + 81, 18, 10, 32, 248, 139, 3, 237, 44, 81, 18, 10, 32, 209, 170, 3, 184, + 81, 18, 10, 32, 209, 170, 3, 151, 81, 18, 10, 32, 209, 170, 3, 229, 141, + 81, 18, 10, 32, 209, 170, 3, 83, 81, 18, 10, 32, 209, 170, 3, 237, 44, + 81, 18, 10, 32, 209, 89, 3, 83, 81, 18, 10, 32, 184, 3, 151, 81, 18, 10, + 32, 184, 3, 83, 81, 18, 10, 32, 151, 3, 184, 81, 18, 10, 32, 151, 3, 83, + 81, 18, 10, 32, 229, 141, 3, 184, 81, 18, 10, 32, 229, 141, 3, 83, 81, + 18, 10, 32, 214, 162, 3, 184, 81, 18, 10, 32, 214, 162, 3, 151, 81, 18, + 10, 32, 214, 162, 3, 229, 141, 81, 18, 10, 32, 214, 162, 3, 83, 81, 18, + 10, 32, 215, 29, 3, 151, 81, 18, 10, 32, 215, 29, 3, 229, 141, 81, 18, + 10, 32, 215, 29, 3, 83, 81, 18, 10, 32, 244, 208, 3, 184, 81, 18, 10, 32, + 244, 208, 3, 151, 81, 18, 10, 32, 244, 208, 3, 229, 141, 81, 18, 10, 32, + 244, 208, 3, 83, 81, 18, 10, 32, 209, 252, 3, 151, 81, 18, 10, 32, 202, + 111, 3, 83, 81, 18, 10, 32, 251, 60, 3, 184, 81, 18, 10, 32, 251, 60, 3, + 83, 81, 18, 10, 32, 238, 115, 3, 184, 81, 18, 10, 32, 238, 115, 3, 83, + 81, 18, 10, 32, 240, 48, 3, 184, 81, 18, 10, 32, 240, 48, 3, 151, 81, 18, + 10, 32, 240, 48, 3, 229, 141, 81, 18, 10, 32, 240, 48, 3, 83, 81, 18, 10, + 32, 217, 120, 3, 151, 81, 18, 10, 32, 217, 120, 3, 83, 81, 18, 10, 32, + 230, 23, 3, 184, 81, 18, 10, 32, 230, 23, 3, 151, 81, 18, 10, 32, 230, + 23, 3, 229, 141, 81, 18, 10, 32, 230, 23, 3, 228, 29, 81, 18, 10, 32, + 230, 23, 3, 83, 81, 18, 10, 32, 228, 29, 3, 184, 81, 18, 10, 32, 228, 29, + 3, 151, 81, 18, 10, 32, 228, 29, 3, 229, 141, 81, 18, 10, 32, 228, 29, 3, + 83, 81, 18, 10, 32, 228, 29, 3, 237, 44, 81, 18, 10, 32, 83, 3, 184, 81, + 18, 10, 32, 83, 3, 151, 81, 18, 10, 32, 83, 3, 229, 141, 81, 18, 10, 32, + 83, 3, 83, 81, 18, 10, 32, 221, 179, 3, 184, 81, 18, 10, 32, 221, 179, 3, + 151, 81, 18, 10, 32, 221, 179, 3, 229, 141, 81, 18, 10, 32, 221, 179, 3, + 83, 81, 18, 10, 32, 221, 179, 3, 237, 44, 81, 18, 10, 32, 237, 44, 3, + 184, 81, 18, 10, 32, 237, 44, 3, 83, 81, 18, 10, 32, 237, 44, 3, 210, + 199, 137, 81, 18, 10, 32, 89, 3, 184, 81, 18, 10, 32, 89, 3, 151, 81, 18, + 10, 32, 89, 3, 229, 141, 81, 18, 10, 32, 89, 3, 83, 81, 18, 10, 32, 89, + 3, 237, 44, 81, 18, 10, 32, 89, 3, 237, 128, 87, 3, 83, 174, 18, 10, 32, + 89, 3, 237, 128, 87, 3, 237, 44, 174, 18, 10, 32, 248, 139, 3, 83, 174, + 18, 10, 32, 248, 139, 3, 237, 44, 174, 18, 10, 32, 209, 170, 3, 83, 174, + 18, 10, 32, 209, 170, 3, 237, 44, 174, 18, 10, 32, 209, 89, 3, 83, 174, + 18, 10, 32, 209, 89, 3, 237, 44, 174, 18, 10, 32, 214, 162, 3, 83, 174, + 18, 10, 32, 214, 162, 3, 237, 44, 174, 18, 10, 32, 213, 40, 3, 83, 174, + 18, 10, 32, 213, 40, 3, 237, 44, 174, 18, 10, 32, 230, 23, 3, 228, 29, + 174, 18, 10, 32, 230, 23, 3, 83, 174, 18, 10, 32, 228, 29, 3, 83, 174, + 18, 10, 32, 221, 179, 3, 83, 174, 18, 10, 32, 221, 179, 3, 237, 44, 174, + 18, 10, 32, 89, 3, 83, 174, 18, 10, 32, 89, 3, 237, 44, 174, 18, 10, 32, + 213, 81, 3, 240, 72, 174, 18, 10, 32, 213, 81, 3, 244, 173, 174, 18, 10, + 32, 213, 81, 3, 229, 230, 174, 18, 10, 32, 209, 252, 3, 137, 225, 130, + 64, 18, 10, 32, 209, 252, 3, 89, 64, 18, 10, 32, 251, 60, 3, 137, 225, + 130, 64, 18, 10, 32, 251, 60, 3, 89, 64, 18, 10, 32, 238, 115, 3, 137, + 225, 130, 64, 18, 10, 32, 238, 115, 3, 89, 64, 18, 10, 32, 214, 162, 3, + 137, 225, 130, 64, 18, 10, 32, 214, 162, 3, 89, 64, 18, 10, 32, 213, 40, + 3, 137, 225, 130, 64, 18, 10, 32, 213, 40, 3, 89, 64, 18, 10, 32, 151, 3, + 137, 225, 130, 64, 18, 10, 32, 151, 3, 89, 64, 18, 10, 32, 184, 3, 137, + 225, 130, 64, 18, 10, 32, 184, 3, 89, 64, 18, 10, 32, 229, 141, 3, 137, + 225, 130, 64, 18, 10, 32, 229, 141, 3, 89, 64, 18, 10, 32, 215, 29, 3, + 137, 225, 130, 64, 18, 10, 32, 215, 29, 3, 89, 64, 18, 10, 32, 244, 208, + 3, 137, 225, 130, 64, 18, 10, 32, 244, 208, 3, 89, 64, 18, 10, 32, 213, + 40, 3, 184, 64, 18, 10, 32, 213, 40, 3, 151, 64, 18, 10, 32, 213, 40, 3, + 229, 141, 64, 18, 10, 32, 213, 40, 3, 83, 64, 18, 10, 32, 213, 40, 3, + 216, 123, 64, 18, 10, 32, 214, 162, 3, 216, 123, 64, 18, 10, 32, 215, 29, + 3, 216, 123, 64, 18, 10, 32, 244, 208, 3, 216, 123, 64, 18, 10, 32, 209, + 252, 3, 137, 225, 130, 46, 18, 10, 32, 209, 252, 3, 89, 46, 18, 10, 32, + 251, 60, 3, 137, 225, 130, 46, 18, 10, 32, 251, 60, 3, 89, 46, 18, 10, + 32, 238, 115, 3, 137, 225, 130, 46, 18, 10, 32, 238, 115, 3, 89, 46, 18, + 10, 32, 214, 162, 3, 137, 225, 130, 46, 18, 10, 32, 214, 162, 3, 89, 46, + 18, 10, 32, 213, 40, 3, 137, 225, 130, 46, 18, 10, 32, 213, 40, 3, 89, + 46, 18, 10, 32, 151, 3, 137, 225, 130, 46, 18, 10, 32, 151, 3, 89, 46, + 18, 10, 32, 184, 3, 137, 225, 130, 46, 18, 10, 32, 184, 3, 89, 46, 18, + 10, 32, 229, 141, 3, 137, 225, 130, 46, 18, 10, 32, 229, 141, 3, 89, 46, + 18, 10, 32, 215, 29, 3, 137, 225, 130, 46, 18, 10, 32, 215, 29, 3, 89, + 46, 18, 10, 32, 244, 208, 3, 137, 225, 130, 46, 18, 10, 32, 244, 208, 3, + 89, 46, 18, 10, 32, 213, 40, 3, 184, 46, 18, 10, 32, 213, 40, 3, 151, 46, + 18, 10, 32, 213, 40, 3, 229, 141, 46, 18, 10, 32, 213, 40, 3, 83, 46, 18, + 10, 32, 213, 40, 3, 216, 123, 46, 18, 10, 32, 214, 162, 3, 216, 123, 46, + 18, 10, 32, 215, 29, 3, 216, 123, 46, 18, 10, 32, 244, 208, 3, 216, 123, + 46, 18, 10, 32, 213, 40, 3, 184, 81, 18, 10, 32, 213, 40, 3, 151, 81, 18, + 10, 32, 213, 40, 3, 229, 141, 81, 18, 10, 32, 213, 40, 3, 83, 81, 18, 10, + 32, 214, 162, 3, 237, 44, 81, 18, 10, 32, 213, 40, 3, 237, 44, 81, 18, + 10, 32, 209, 252, 3, 83, 81, 18, 10, 32, 214, 162, 3, 184, 174, 18, 10, + 32, 214, 162, 3, 151, 174, 18, 10, 32, 214, 162, 3, 229, 141, 174, 18, + 10, 32, 213, 40, 3, 184, 174, 18, 10, 32, 213, 40, 3, 151, 174, 18, 10, + 32, 213, 40, 3, 229, 141, 174, 18, 10, 32, 209, 252, 3, 83, 174, 18, 10, + 32, 202, 111, 3, 83, 174, 18, 10, 32, 137, 3, 240, 70, 46, 18, 10, 32, + 137, 3, 240, 70, 64, 18, 219, 231, 49, 219, 76, 219, 231, 50, 219, 76, + 10, 32, 209, 170, 3, 184, 3, 83, 81, 18, 10, 32, 209, 170, 3, 151, 3, + 184, 46, 18, 10, 32, 209, 170, 3, 151, 3, 184, 81, 18, 10, 32, 209, 170, + 3, 151, 3, 83, 81, 18, 10, 32, 209, 170, 3, 229, 141, 3, 83, 81, 18, 10, + 32, 209, 170, 3, 83, 3, 184, 81, 18, 10, 32, 209, 170, 3, 83, 3, 151, 81, + 18, 10, 32, 209, 170, 3, 83, 3, 229, 141, 81, 18, 10, 32, 184, 3, 83, 3, + 151, 46, 18, 10, 32, 184, 3, 83, 3, 151, 81, 18, 10, 32, 151, 3, 83, 3, + 89, 46, 18, 10, 32, 151, 3, 83, 3, 137, 225, 130, 46, 18, 10, 32, 214, + 162, 3, 151, 3, 184, 81, 18, 10, 32, 214, 162, 3, 184, 3, 151, 81, 18, + 10, 32, 214, 162, 3, 184, 3, 137, 225, 130, 46, 18, 10, 32, 214, 162, 3, + 83, 3, 151, 46, 18, 10, 32, 214, 162, 3, 83, 3, 151, 81, 18, 10, 32, 214, + 162, 3, 83, 3, 184, 81, 18, 10, 32, 214, 162, 3, 83, 3, 83, 46, 18, 10, + 32, 214, 162, 3, 83, 3, 83, 81, 18, 10, 32, 215, 29, 3, 151, 3, 151, 46, + 18, 10, 32, 215, 29, 3, 151, 3, 151, 81, 18, 10, 32, 215, 29, 3, 83, 3, + 83, 46, 18, 10, 32, 213, 40, 3, 151, 3, 83, 46, 18, 10, 32, 213, 40, 3, + 151, 3, 83, 81, 18, 10, 32, 213, 40, 3, 184, 3, 89, 46, 18, 10, 32, 213, + 40, 3, 83, 3, 229, 141, 46, 18, 10, 32, 213, 40, 3, 83, 3, 229, 141, 81, + 18, 10, 32, 213, 40, 3, 83, 3, 83, 46, 18, 10, 32, 213, 40, 3, 83, 3, 83, + 81, 18, 10, 32, 244, 208, 3, 151, 3, 137, 225, 130, 46, 18, 10, 32, 244, + 208, 3, 229, 141, 3, 83, 46, 18, 10, 32, 244, 208, 3, 229, 141, 3, 83, + 81, 18, 10, 32, 209, 252, 3, 83, 3, 151, 46, 18, 10, 32, 209, 252, 3, 83, + 3, 151, 81, 18, 10, 32, 209, 252, 3, 83, 3, 83, 81, 18, 10, 32, 209, 252, + 3, 83, 3, 89, 46, 18, 10, 32, 251, 60, 3, 184, 3, 83, 46, 18, 10, 32, + 251, 60, 3, 83, 3, 83, 46, 18, 10, 32, 251, 60, 3, 83, 3, 83, 81, 18, 10, + 32, 251, 60, 3, 83, 3, 137, 225, 130, 46, 18, 10, 32, 238, 115, 3, 83, 3, + 83, 46, 18, 10, 32, 238, 115, 3, 83, 3, 89, 46, 18, 10, 32, 238, 115, 3, + 83, 3, 137, 225, 130, 46, 18, 10, 32, 240, 48, 3, 229, 141, 3, 83, 46, + 18, 10, 32, 240, 48, 3, 229, 141, 3, 83, 81, 18, 10, 32, 217, 120, 3, 83, + 3, 151, 46, 18, 10, 32, 217, 120, 3, 83, 3, 83, 46, 18, 10, 32, 228, 29, + 3, 151, 3, 83, 46, 18, 10, 32, 228, 29, 3, 151, 3, 89, 46, 18, 10, 32, + 228, 29, 3, 151, 3, 137, 225, 130, 46, 18, 10, 32, 228, 29, 3, 184, 3, + 184, 81, 18, 10, 32, 228, 29, 3, 184, 3, 184, 46, 18, 10, 32, 228, 29, 3, + 229, 141, 3, 83, 46, 18, 10, 32, 228, 29, 3, 229, 141, 3, 83, 81, 18, 10, + 32, 228, 29, 3, 83, 3, 151, 46, 18, 10, 32, 228, 29, 3, 83, 3, 151, 81, + 18, 10, 32, 83, 3, 151, 3, 184, 81, 18, 10, 32, 83, 3, 151, 3, 83, 81, + 18, 10, 32, 83, 3, 151, 3, 89, 46, 18, 10, 32, 83, 3, 184, 3, 151, 81, + 18, 10, 32, 83, 3, 184, 3, 83, 81, 18, 10, 32, 83, 3, 229, 141, 3, 184, + 81, 18, 10, 32, 83, 3, 229, 141, 3, 83, 81, 18, 10, 32, 83, 3, 184, 3, + 229, 141, 81, 18, 10, 32, 237, 44, 3, 83, 3, 184, 81, 18, 10, 32, 237, + 44, 3, 83, 3, 83, 81, 18, 10, 32, 221, 179, 3, 151, 3, 83, 81, 18, 10, + 32, 221, 179, 3, 151, 3, 137, 225, 130, 46, 18, 10, 32, 221, 179, 3, 184, + 3, 83, 46, 18, 10, 32, 221, 179, 3, 184, 3, 83, 81, 18, 10, 32, 221, 179, + 3, 184, 3, 137, 225, 130, 46, 18, 10, 32, 221, 179, 3, 83, 3, 89, 46, 18, + 10, 32, 221, 179, 3, 83, 3, 137, 225, 130, 46, 18, 10, 32, 89, 3, 83, 3, + 83, 46, 18, 10, 32, 89, 3, 83, 3, 83, 81, 18, 10, 32, 248, 139, 3, 229, + 141, 3, 89, 46, 18, 10, 32, 209, 170, 3, 184, 3, 89, 46, 18, 10, 32, 209, + 170, 3, 184, 3, 137, 225, 130, 46, 18, 10, 32, 209, 170, 3, 229, 141, 3, + 89, 46, 18, 10, 32, 209, 170, 3, 229, 141, 3, 137, 225, 130, 46, 18, 10, + 32, 209, 170, 3, 83, 3, 89, 46, 18, 10, 32, 209, 170, 3, 83, 3, 137, 225, + 130, 46, 18, 10, 32, 184, 3, 83, 3, 89, 46, 18, 10, 32, 184, 3, 151, 3, + 137, 225, 130, 46, 18, 10, 32, 184, 3, 83, 3, 137, 225, 130, 46, 18, 10, + 32, 214, 162, 3, 229, 141, 3, 137, 225, 130, 46, 18, 10, 32, 215, 29, 3, + 151, 3, 89, 46, 18, 10, 32, 213, 40, 3, 151, 3, 89, 46, 18, 10, 32, 244, + 208, 3, 151, 3, 89, 46, 18, 10, 32, 228, 29, 3, 184, 3, 89, 46, 18, 10, + 32, 228, 29, 3, 83, 3, 89, 46, 18, 10, 32, 89, 3, 151, 3, 89, 46, 18, 10, + 32, 89, 3, 184, 3, 89, 46, 18, 10, 32, 89, 3, 83, 3, 89, 46, 18, 10, 32, + 83, 3, 83, 3, 89, 46, 18, 10, 32, 217, 120, 3, 83, 3, 89, 46, 18, 10, 32, + 221, 179, 3, 151, 3, 89, 46, 18, 10, 32, 217, 120, 3, 83, 3, 151, 81, 18, + 10, 32, 228, 29, 3, 151, 3, 83, 81, 18, 10, 32, 251, 60, 3, 83, 3, 89, + 46, 18, 10, 32, 230, 23, 3, 83, 3, 89, 46, 18, 10, 32, 221, 179, 3, 184, + 3, 151, 81, 18, 10, 32, 83, 3, 229, 141, 3, 89, 46, 18, 10, 32, 228, 29, + 3, 184, 3, 83, 81, 18, 10, 32, 230, 23, 3, 83, 3, 83, 46, 18, 10, 32, + 228, 29, 3, 184, 3, 83, 46, 18, 10, 32, 221, 179, 3, 184, 3, 151, 46, 18, + 10, 32, 184, 3, 151, 3, 89, 46, 18, 10, 32, 151, 3, 184, 3, 89, 46, 18, + 10, 32, 83, 3, 184, 3, 89, 46, 18, 10, 32, 240, 48, 3, 83, 3, 89, 46, 18, + 10, 32, 248, 139, 3, 151, 3, 89, 46, 18, 10, 32, 230, 23, 3, 83, 3, 83, + 81, 18, 10, 32, 251, 60, 3, 184, 3, 83, 81, 18, 10, 32, 215, 29, 3, 83, + 3, 83, 81, 18, 10, 32, 214, 162, 3, 229, 141, 3, 89, 46, 18, 10, 32, 221, + 179, 3, 184, 3, 89, 46, 18, 10, 32, 215, 4, 206, 188, 250, 82, 228, 254, + 211, 62, 2, 64, 18, 10, 32, 217, 116, 206, 188, 250, 82, 228, 254, 211, + 62, 2, 64, 18, 10, 32, 251, 13, 64, 18, 10, 32, 251, 44, 64, 18, 10, 32, + 224, 57, 64, 18, 10, 32, 215, 5, 64, 18, 10, 32, 216, 174, 64, 18, 10, + 32, 251, 33, 64, 18, 10, 32, 204, 90, 64, 18, 10, 32, 215, 4, 64, 18, 10, + 32, 215, 3, 251, 33, 204, 89, 10, 32, 230, 172, 216, 56, 54, 10, 32, 248, + 53, 250, 142, 250, 143, 57, 214, 149, 57, 214, 38, 57, 213, 226, 57, 213, + 215, 57, 213, 204, 57, 213, 193, 57, 213, 182, 57, 213, 171, 57, 213, + 160, 57, 214, 148, 57, 214, 137, 57, 214, 126, 57, 214, 115, 57, 214, + 104, 57, 214, 93, 57, 214, 82, 217, 241, 239, 159, 35, 80, 245, 233, 217, + 241, 239, 159, 35, 80, 139, 245, 233, 217, 241, 239, 159, 35, 80, 139, + 239, 102, 211, 61, 217, 241, 239, 159, 35, 80, 245, 242, 217, 241, 239, + 159, 35, 80, 213, 143, 217, 241, 239, 159, 35, 80, 240, 212, 82, 217, + 241, 239, 159, 35, 80, 217, 47, 82, 217, 241, 239, 159, 35, 80, 49, 61, + 227, 185, 155, 217, 241, 239, 159, 35, 80, 50, 61, 227, 185, 247, 225, + 217, 241, 239, 159, 35, 80, 236, 106, 241, 108, 39, 32, 49, 237, 137, 39, + 32, 50, 237, 137, 39, 52, 208, 228, 49, 237, 137, 39, 52, 208, 228, 50, + 237, 137, 39, 225, 171, 49, 237, 137, 39, 225, 171, 50, 237, 137, 39, + 245, 206, 225, 170, 39, 32, 49, 162, 56, 39, 32, 50, 162, 56, 39, 208, + 228, 49, 162, 56, 39, 208, 228, 50, 162, 56, 39, 225, 171, 49, 162, 56, + 39, 225, 171, 50, 162, 56, 39, 245, 206, 225, 171, 56, 39, 36, 208, 198, + 49, 237, 137, 39, 36, 208, 198, 50, 237, 137, 217, 241, 239, 159, 35, 80, + 120, 70, 227, 232, 217, 241, 239, 159, 35, 80, 241, 104, 244, 144, 217, + 241, 239, 159, 35, 80, 241, 93, 244, 144, 217, 241, 239, 159, 35, 80, + 124, 227, 114, 217, 241, 239, 159, 35, 80, 204, 72, 124, 227, 114, 217, + 241, 239, 159, 35, 80, 49, 219, 76, 217, 241, 239, 159, 35, 80, 50, 219, + 76, 217, 241, 239, 159, 35, 80, 49, 245, 93, 155, 217, 241, 239, 159, 35, + 80, 50, 245, 93, 155, 217, 241, 239, 159, 35, 80, 49, 208, 133, 213, 33, + 155, 217, 241, 239, 159, 35, 80, 50, 208, 133, 213, 33, 155, 217, 241, + 239, 159, 35, 80, 49, 62, 227, 185, 155, 217, 241, 239, 159, 35, 80, 50, + 62, 227, 185, 155, 217, 241, 239, 159, 35, 80, 49, 52, 250, 218, 155, + 217, 241, 239, 159, 35, 80, 50, 52, 250, 218, 155, 217, 241, 239, 159, + 35, 80, 49, 250, 218, 155, 217, 241, 239, 159, 35, 80, 50, 250, 218, 155, + 217, 241, 239, 159, 35, 80, 49, 245, 166, 155, 217, 241, 239, 159, 35, + 80, 50, 245, 166, 155, 217, 241, 239, 159, 35, 80, 49, 61, 245, 166, 155, + 217, 241, 239, 159, 35, 80, 50, 61, 245, 166, 155, 213, 121, 243, 85, 61, + 213, 121, 243, 85, 217, 241, 239, 159, 35, 80, 49, 51, 155, 217, 241, + 239, 159, 35, 80, 50, 51, 155, 244, 143, 219, 198, 246, 214, 219, 198, + 204, 72, 219, 198, 52, 204, 72, 219, 198, 244, 143, 124, 227, 114, 246, + 214, 124, 227, 114, 204, 72, 124, 227, 114, 5, 245, 233, 5, 139, 245, + 233, 5, 239, 102, 211, 61, 5, 213, 143, 5, 245, 242, 5, 217, 47, 82, 5, + 240, 212, 82, 5, 241, 104, 244, 144, 5, 49, 219, 76, 5, 50, 219, 76, 5, + 49, 245, 93, 155, 5, 50, 245, 93, 155, 5, 49, 208, 133, 213, 33, 155, 5, + 50, 208, 133, 213, 33, 155, 5, 42, 54, 5, 250, 235, 5, 250, 59, 5, 91, + 54, 5, 235, 219, 5, 227, 179, 54, 5, 237, 247, 54, 5, 241, 35, 54, 5, + 216, 74, 212, 0, 5, 243, 97, 54, 5, 218, 246, 54, 5, 245, 231, 250, 49, + 10, 240, 70, 64, 18, 10, 209, 210, 3, 240, 70, 55, 10, 244, 171, 64, 18, + 10, 209, 249, 239, 137, 10, 229, 228, 64, 18, 10, 240, 72, 64, 18, 10, + 240, 72, 174, 18, 10, 244, 173, 64, 18, 10, 244, 173, 174, 18, 10, 229, + 230, 64, 18, 10, 229, 230, 174, 18, 10, 213, 81, 64, 18, 10, 213, 81, + 174, 18, 10, 210, 223, 64, 18, 10, 210, 223, 174, 18, 10, 1, 237, 128, + 64, 18, 10, 1, 137, 3, 225, 166, 87, 64, 18, 10, 1, 137, 3, 225, 166, 87, + 46, 18, 10, 1, 137, 3, 237, 128, 87, 64, 18, 10, 1, 137, 3, 237, 128, 87, + 46, 18, 10, 1, 204, 71, 3, 237, 128, 87, 64, 18, 10, 1, 204, 71, 3, 237, + 128, 87, 46, 18, 10, 1, 137, 3, 237, 128, 248, 126, 64, 18, 10, 1, 137, + 3, 237, 128, 248, 126, 46, 18, 10, 1, 89, 3, 237, 128, 87, 64, 18, 10, 1, + 89, 3, 237, 128, 87, 46, 18, 10, 1, 89, 3, 237, 128, 87, 81, 18, 10, 1, + 89, 3, 237, 128, 87, 174, 18, 10, 1, 137, 64, 18, 10, 1, 137, 46, 18, 10, + 1, 248, 139, 64, 18, 10, 1, 248, 139, 46, 18, 10, 1, 248, 139, 81, 18, + 10, 1, 248, 139, 174, 18, 10, 1, 209, 170, 225, 99, 64, 18, 10, 1, 209, + 170, 225, 99, 46, 18, 10, 1, 209, 170, 64, 18, 10, 1, 209, 170, 46, 18, + 10, 1, 209, 170, 81, 18, 10, 1, 209, 170, 174, 18, 10, 1, 209, 89, 64, + 18, 10, 1, 209, 89, 46, 18, 10, 1, 209, 89, 81, 18, 10, 1, 209, 89, 174, + 18, 10, 1, 184, 64, 18, 10, 1, 184, 46, 18, 10, 1, 184, 81, 18, 10, 1, + 184, 174, 18, 10, 1, 151, 64, 18, 10, 1, 151, 46, 18, 10, 1, 151, 81, 18, + 10, 1, 151, 174, 18, 10, 1, 229, 141, 64, 18, 10, 1, 229, 141, 46, 18, + 10, 1, 229, 141, 81, 18, 10, 1, 229, 141, 174, 18, 10, 1, 244, 185, 64, + 18, 10, 1, 244, 185, 46, 18, 10, 1, 209, 101, 64, 18, 10, 1, 209, 101, + 46, 18, 10, 1, 216, 123, 64, 18, 10, 1, 216, 123, 46, 18, 10, 1, 202, + 108, 64, 18, 10, 1, 202, 108, 46, 18, 10, 1, 214, 162, 64, 18, 10, 1, + 214, 162, 46, 18, 10, 1, 214, 162, 81, 18, 10, 1, 214, 162, 174, 18, 10, + 1, 213, 40, 64, 18, 10, 1, 213, 40, 46, 18, 10, 1, 213, 40, 81, 18, 10, + 1, 213, 40, 174, 18, 10, 1, 215, 29, 64, 18, 10, 1, 215, 29, 46, 18, 10, + 1, 215, 29, 81, 18, 10, 1, 215, 29, 174, 18, 10, 1, 244, 208, 64, 18, 10, + 1, 244, 208, 46, 18, 10, 1, 244, 208, 81, 18, 10, 1, 244, 208, 174, 18, + 10, 1, 209, 252, 64, 18, 10, 1, 209, 252, 46, 18, 10, 1, 209, 252, 81, + 18, 10, 1, 209, 252, 174, 18, 10, 1, 202, 111, 64, 18, 10, 1, 202, 111, + 46, 18, 10, 1, 202, 111, 81, 18, 10, 1, 202, 111, 174, 18, 10, 1, 251, + 60, 64, 18, 10, 1, 251, 60, 46, 18, 10, 1, 251, 60, 81, 18, 10, 1, 251, + 60, 174, 18, 10, 1, 238, 115, 64, 18, 10, 1, 238, 115, 46, 18, 10, 1, + 238, 115, 81, 18, 10, 1, 238, 115, 174, 18, 10, 1, 240, 48, 64, 18, 10, + 1, 240, 48, 46, 18, 10, 1, 240, 48, 81, 18, 10, 1, 240, 48, 174, 18, 10, + 1, 217, 120, 64, 18, 10, 1, 217, 120, 46, 18, 10, 1, 217, 120, 81, 18, + 10, 1, 217, 120, 174, 18, 10, 1, 230, 23, 64, 18, 10, 1, 230, 23, 46, 18, + 10, 1, 230, 23, 81, 18, 10, 1, 230, 23, 174, 18, 10, 1, 228, 29, 64, 18, + 10, 1, 228, 29, 46, 18, 10, 1, 228, 29, 81, 18, 10, 1, 228, 29, 174, 18, + 10, 1, 83, 64, 18, 10, 1, 83, 46, 18, 10, 1, 83, 81, 18, 10, 1, 83, 174, + 18, 10, 1, 221, 179, 64, 18, 10, 1, 221, 179, 46, 18, 10, 1, 221, 179, + 81, 18, 10, 1, 221, 179, 174, 18, 10, 1, 237, 44, 64, 18, 10, 1, 237, 44, + 46, 18, 10, 1, 237, 44, 81, 18, 10, 1, 237, 44, 174, 18, 10, 1, 204, 71, + 64, 18, 10, 1, 204, 71, 46, 18, 10, 1, 137, 225, 130, 64, 18, 10, 1, 137, + 225, 130, 46, 18, 10, 1, 89, 64, 18, 10, 1, 89, 46, 18, 10, 1, 89, 81, + 18, 10, 1, 89, 174, 18, 10, 32, 228, 29, 3, 137, 3, 225, 166, 87, 64, 18, + 10, 32, 228, 29, 3, 137, 3, 225, 166, 87, 46, 18, 10, 32, 228, 29, 3, + 137, 3, 237, 128, 87, 64, 18, 10, 32, 228, 29, 3, 137, 3, 237, 128, 87, + 46, 18, 10, 32, 228, 29, 3, 137, 3, 237, 128, 248, 126, 64, 18, 10, 32, + 228, 29, 3, 137, 3, 237, 128, 248, 126, 46, 18, 10, 32, 228, 29, 3, 137, + 64, 18, 10, 32, 228, 29, 3, 137, 46, 18, 202, 85, 204, 24, 221, 190, 211, + 228, 154, 240, 212, 82, 154, 217, 31, 82, 154, 42, 54, 154, 243, 97, 54, + 154, 218, 246, 54, 154, 250, 235, 154, 250, 160, 154, 49, 219, 76, 154, + 50, 219, 76, 154, 250, 59, 154, 91, 54, 154, 245, 233, 154, 235, 219, + 154, 239, 102, 211, 61, 154, 212, 0, 154, 17, 202, 84, 154, 17, 105, 154, + 17, 108, 154, 17, 147, 154, 17, 149, 154, 17, 170, 154, 17, 195, 154, 17, + 213, 111, 154, 17, 199, 154, 17, 222, 63, 154, 245, 242, 154, 213, 143, + 154, 227, 179, 54, 154, 241, 35, 54, 154, 237, 247, 54, 154, 217, 47, 82, + 154, 245, 231, 250, 49, 154, 8, 6, 1, 63, 154, 8, 6, 1, 249, 255, 154, 8, + 6, 1, 247, 125, 154, 8, 6, 1, 245, 51, 154, 8, 6, 1, 74, 154, 8, 6, 1, + 240, 174, 154, 8, 6, 1, 239, 75, 154, 8, 6, 1, 237, 171, 154, 8, 6, 1, + 75, 154, 8, 6, 1, 230, 184, 154, 8, 6, 1, 230, 54, 154, 8, 6, 1, 159, + 154, 8, 6, 1, 226, 185, 154, 8, 6, 1, 223, 163, 154, 8, 6, 1, 78, 154, 8, + 6, 1, 219, 184, 154, 8, 6, 1, 217, 134, 154, 8, 6, 1, 146, 154, 8, 6, 1, + 194, 154, 8, 6, 1, 210, 69, 154, 8, 6, 1, 68, 154, 8, 6, 1, 206, 164, + 154, 8, 6, 1, 204, 144, 154, 8, 6, 1, 203, 196, 154, 8, 6, 1, 203, 124, + 154, 8, 6, 1, 202, 159, 154, 49, 51, 155, 154, 216, 74, 212, 0, 154, 50, + 51, 155, 154, 246, 53, 251, 138, 154, 124, 227, 114, 154, 237, 254, 251, + 138, 154, 8, 5, 1, 63, 154, 8, 5, 1, 249, 255, 154, 8, 5, 1, 247, 125, + 154, 8, 5, 1, 245, 51, 154, 8, 5, 1, 74, 154, 8, 5, 1, 240, 174, 154, 8, + 5, 1, 239, 75, 154, 8, 5, 1, 237, 171, 154, 8, 5, 1, 75, 154, 8, 5, 1, + 230, 184, 154, 8, 5, 1, 230, 54, 154, 8, 5, 1, 159, 154, 8, 5, 1, 226, + 185, 154, 8, 5, 1, 223, 163, 154, 8, 5, 1, 78, 154, 8, 5, 1, 219, 184, + 154, 8, 5, 1, 217, 134, 154, 8, 5, 1, 146, 154, 8, 5, 1, 194, 154, 8, 5, + 1, 210, 69, 154, 8, 5, 1, 68, 154, 8, 5, 1, 206, 164, 154, 8, 5, 1, 204, + 144, 154, 8, 5, 1, 203, 196, 154, 8, 5, 1, 203, 124, 154, 8, 5, 1, 202, + 159, 154, 49, 245, 93, 155, 154, 80, 227, 114, 154, 50, 245, 93, 155, + 154, 208, 227, 154, 49, 61, 219, 76, 154, 50, 61, 219, 76, 127, 139, 239, + 102, 211, 61, 127, 49, 245, 166, 155, 127, 50, 245, 166, 155, 127, 139, + 245, 233, 127, 67, 101, 243, 85, 127, 67, 1, 204, 0, 127, 67, 1, 5, 63, + 127, 67, 1, 5, 75, 127, 67, 1, 5, 68, 127, 67, 1, 5, 74, 127, 67, 1, 5, + 78, 127, 67, 1, 5, 198, 127, 67, 1, 5, 202, 213, 127, 67, 1, 5, 202, 247, + 127, 67, 1, 5, 207, 203, 127, 229, 225, 217, 215, 211, 241, 82, 127, 67, + 1, 63, 127, 67, 1, 75, 127, 67, 1, 68, 127, 67, 1, 74, 127, 67, 1, 78, + 127, 67, 1, 173, 127, 67, 1, 229, 100, 127, 67, 1, 228, 209, 127, 67, 1, + 229, 201, 127, 67, 1, 229, 26, 127, 67, 1, 215, 36, 127, 67, 1, 212, 162, + 127, 67, 1, 211, 10, 127, 67, 1, 214, 177, 127, 67, 1, 212, 13, 127, 67, + 1, 210, 22, 127, 67, 1, 209, 2, 127, 67, 1, 207, 203, 127, 67, 1, 209, + 187, 127, 67, 1, 135, 127, 67, 1, 201, 201, 127, 67, 1, 222, 100, 127, + 67, 1, 221, 84, 127, 67, 1, 222, 240, 127, 67, 1, 221, 191, 127, 67, 1, + 152, 127, 67, 1, 237, 3, 127, 67, 1, 236, 26, 127, 67, 1, 237, 67, 127, + 67, 1, 236, 136, 127, 67, 1, 192, 127, 67, 1, 224, 155, 127, 67, 1, 223, + 246, 127, 67, 1, 225, 20, 127, 67, 1, 224, 82, 127, 67, 1, 198, 127, 67, + 1, 202, 213, 127, 67, 1, 202, 247, 127, 67, 1, 216, 220, 127, 67, 1, 216, + 57, 127, 67, 1, 215, 145, 127, 67, 1, 216, 158, 127, 67, 1, 215, 227, + 127, 67, 1, 204, 111, 127, 67, 1, 223, 163, 127, 67, 205, 186, 211, 241, + 82, 127, 67, 213, 148, 211, 241, 82, 127, 28, 240, 7, 127, 28, 1, 229, + 59, 127, 28, 1, 211, 156, 127, 28, 1, 229, 52, 127, 28, 1, 222, 93, 127, + 28, 1, 222, 91, 127, 28, 1, 222, 90, 127, 28, 1, 208, 240, 127, 28, 1, + 211, 145, 127, 28, 1, 216, 47, 127, 28, 1, 216, 42, 127, 28, 1, 216, 39, + 127, 28, 1, 216, 32, 127, 28, 1, 216, 27, 127, 28, 1, 216, 22, 127, 28, + 1, 216, 33, 127, 28, 1, 216, 45, 127, 28, 1, 224, 141, 127, 28, 1, 218, + 153, 127, 28, 1, 211, 153, 127, 28, 1, 218, 142, 127, 28, 1, 212, 111, + 127, 28, 1, 211, 150, 127, 28, 1, 231, 106, 127, 28, 1, 246, 74, 127, 28, + 1, 211, 160, 127, 28, 1, 246, 138, 127, 28, 1, 229, 120, 127, 28, 1, 209, + 66, 127, 28, 1, 218, 190, 127, 28, 1, 236, 251, 127, 28, 1, 63, 127, 28, + 1, 251, 109, 127, 28, 1, 198, 127, 28, 1, 203, 99, 127, 28, 1, 241, 55, + 127, 28, 1, 74, 127, 28, 1, 203, 39, 127, 28, 1, 203, 52, 127, 28, 1, 78, + 127, 28, 1, 204, 111, 127, 28, 1, 204, 107, 127, 28, 1, 220, 73, 127, 28, + 1, 202, 247, 127, 28, 1, 68, 127, 28, 1, 204, 48, 127, 28, 1, 204, 62, + 127, 28, 1, 204, 30, 127, 28, 1, 202, 213, 127, 28, 1, 240, 238, 127, 28, + 1, 203, 11, 127, 28, 1, 75, 154, 246, 220, 54, 154, 218, 20, 54, 154, + 221, 166, 54, 154, 225, 170, 154, 247, 203, 142, 154, 203, 43, 54, 154, + 203, 246, 54, 127, 239, 156, 157, 206, 38, 127, 96, 47, 127, 177, 47, + 127, 86, 47, 127, 183, 47, 127, 62, 211, 177, 127, 61, 246, 61, 230, 251, + 250, 205, 250, 228, 230, 251, 250, 205, 213, 130, 230, 251, 250, 205, + 209, 138, 220, 90, 216, 96, 246, 182, 216, 96, 246, 182, 29, 66, 4, 249, + 239, 63, 29, 66, 4, 249, 208, 74, 29, 66, 4, 249, 217, 75, 29, 66, 4, + 249, 185, 78, 29, 66, 4, 249, 235, 68, 29, 66, 4, 249, 254, 244, 212, 29, + 66, 4, 249, 201, 244, 75, 29, 66, 4, 249, 241, 243, 233, 29, 66, 4, 249, + 231, 243, 113, 29, 66, 4, 249, 195, 242, 42, 29, 66, 4, 249, 189, 230, + 181, 29, 66, 4, 249, 200, 230, 161, 29, 66, 4, 249, 210, 230, 101, 29, + 66, 4, 249, 181, 230, 82, 29, 66, 4, 249, 169, 173, 29, 66, 4, 249, 202, + 229, 201, 29, 66, 4, 249, 179, 229, 100, 29, 66, 4, 249, 176, 229, 26, + 29, 66, 4, 249, 165, 228, 209, 29, 66, 4, 249, 166, 192, 29, 66, 4, 249, + 232, 225, 20, 29, 66, 4, 249, 173, 224, 155, 29, 66, 4, 249, 230, 224, + 82, 29, 66, 4, 249, 222, 223, 246, 29, 66, 4, 249, 243, 201, 201, 29, 66, + 4, 249, 221, 222, 240, 29, 66, 4, 249, 215, 222, 100, 29, 66, 4, 249, + 194, 221, 191, 29, 66, 4, 249, 191, 221, 84, 29, 66, 4, 249, 250, 185, + 29, 66, 4, 249, 174, 219, 34, 29, 66, 4, 249, 207, 218, 167, 29, 66, 4, + 249, 234, 218, 69, 29, 66, 4, 249, 196, 217, 191, 29, 66, 4, 249, 229, + 217, 126, 29, 66, 4, 249, 168, 217, 106, 29, 66, 4, 249, 224, 217, 88, + 29, 66, 4, 249, 213, 217, 77, 29, 66, 4, 249, 186, 216, 220, 29, 66, 4, + 249, 218, 216, 158, 29, 66, 4, 249, 193, 216, 57, 29, 66, 4, 249, 252, + 215, 227, 29, 66, 4, 249, 219, 215, 145, 29, 66, 4, 249, 214, 215, 36, + 29, 66, 4, 249, 237, 214, 177, 29, 66, 4, 249, 205, 212, 162, 29, 66, 4, + 249, 233, 212, 13, 29, 66, 4, 249, 188, 211, 10, 29, 66, 4, 249, 187, + 210, 22, 29, 66, 4, 249, 248, 209, 187, 29, 66, 4, 249, 209, 209, 2, 29, + 66, 4, 249, 246, 135, 29, 66, 4, 249, 177, 207, 203, 29, 66, 4, 249, 192, + 204, 111, 29, 66, 4, 249, 171, 204, 62, 29, 66, 4, 249, 206, 204, 30, 29, + 66, 4, 249, 204, 204, 0, 29, 66, 4, 249, 228, 202, 116, 29, 66, 4, 249, + 172, 202, 92, 29, 66, 4, 249, 225, 202, 17, 29, 66, 4, 249, 220, 254, 34, + 29, 66, 4, 249, 203, 253, 178, 29, 66, 4, 249, 162, 250, 34, 29, 66, 4, + 249, 175, 242, 9, 29, 66, 4, 249, 158, 242, 8, 29, 66, 4, 249, 198, 221, + 20, 29, 66, 4, 249, 216, 217, 189, 29, 66, 4, 249, 184, 217, 193, 29, 66, + 4, 249, 170, 216, 218, 29, 66, 4, 249, 212, 216, 217, 29, 66, 4, 249, + 178, 215, 226, 29, 66, 4, 249, 180, 210, 19, 29, 66, 4, 249, 160, 207, + 158, 29, 66, 4, 249, 157, 108, 29, 66, 16, 249, 227, 29, 66, 16, 249, + 226, 29, 66, 16, 249, 223, 29, 66, 16, 249, 211, 29, 66, 16, 249, 199, + 29, 66, 16, 249, 197, 29, 66, 16, 249, 190, 29, 66, 16, 249, 183, 29, 66, + 16, 249, 182, 29, 66, 16, 249, 167, 29, 66, 16, 249, 164, 29, 66, 16, + 249, 163, 29, 66, 16, 249, 161, 29, 66, 16, 249, 159, 29, 66, 133, 249, + 156, 225, 122, 29, 66, 133, 249, 155, 203, 250, 29, 66, 133, 249, 154, + 244, 58, 29, 66, 133, 249, 153, 241, 32, 29, 66, 133, 249, 152, 225, 93, + 29, 66, 133, 249, 151, 211, 101, 29, 66, 133, 249, 150, 240, 219, 29, 66, + 133, 249, 149, 216, 184, 29, 66, 133, 249, 148, 213, 42, 29, 66, 133, + 249, 147, 237, 66, 29, 66, 133, 249, 146, 211, 235, 29, 66, 133, 249, + 145, 248, 21, 29, 66, 133, 249, 144, 245, 149, 29, 66, 133, 249, 143, + 247, 179, 29, 66, 133, 249, 142, 204, 38, 29, 66, 133, 249, 141, 248, + 227, 29, 66, 133, 249, 140, 220, 41, 29, 66, 133, 249, 139, 211, 207, 29, + 66, 133, 249, 138, 245, 59, 29, 66, 224, 45, 249, 137, 229, 249, 29, 66, + 224, 45, 249, 136, 230, 2, 29, 66, 133, 249, 135, 220, 55, 29, 66, 133, + 249, 134, 204, 12, 29, 66, 133, 249, 133, 29, 66, 224, 45, 249, 132, 250, + 119, 29, 66, 224, 45, 249, 131, 224, 232, 29, 66, 133, 249, 130, 247, + 202, 29, 66, 133, 249, 129, 238, 31, 29, 66, 133, 249, 128, 29, 66, 133, + 249, 127, 203, 241, 29, 66, 133, 249, 126, 29, 66, 133, 249, 125, 29, 66, + 133, 249, 124, 236, 53, 29, 66, 133, 249, 123, 29, 66, 133, 249, 122, 29, + 66, 133, 249, 121, 29, 66, 224, 45, 249, 119, 207, 172, 29, 66, 133, 249, + 118, 29, 66, 133, 249, 117, 29, 66, 133, 249, 116, 246, 10, 29, 66, 133, + 249, 115, 29, 66, 133, 249, 114, 29, 66, 133, 249, 113, 238, 221, 29, 66, + 133, 249, 112, 250, 106, 29, 66, 133, 249, 111, 29, 66, 133, 249, 110, + 29, 66, 133, 249, 109, 29, 66, 133, 249, 108, 29, 66, 133, 249, 107, 29, + 66, 133, 249, 106, 29, 66, 133, 249, 105, 29, 66, 133, 249, 104, 29, 66, + 133, 249, 103, 29, 66, 133, 249, 102, 224, 37, 29, 66, 133, 249, 101, 29, + 66, 133, 249, 100, 208, 95, 29, 66, 133, 249, 99, 29, 66, 133, 249, 98, + 29, 66, 133, 249, 97, 29, 66, 133, 249, 96, 29, 66, 133, 249, 95, 29, 66, + 133, 249, 94, 29, 66, 133, 249, 93, 29, 66, 133, 249, 92, 29, 66, 133, + 249, 91, 29, 66, 133, 249, 90, 29, 66, 133, 249, 89, 29, 66, 133, 249, + 88, 237, 35, 29, 66, 133, 249, 67, 239, 168, 29, 66, 133, 249, 64, 248, + 204, 29, 66, 133, 249, 59, 211, 214, 29, 66, 133, 249, 58, 47, 29, 66, + 133, 249, 57, 29, 66, 133, 249, 56, 210, 155, 29, 66, 133, 249, 55, 29, + 66, 133, 249, 54, 29, 66, 133, 249, 53, 204, 34, 246, 179, 29, 66, 133, + 249, 52, 246, 179, 29, 66, 133, 249, 51, 246, 180, 239, 134, 29, 66, 133, + 249, 50, 204, 36, 29, 66, 133, 249, 49, 29, 66, 133, 249, 48, 29, 66, + 224, 45, 249, 47, 243, 168, 29, 66, 133, 249, 46, 29, 66, 133, 249, 45, + 29, 66, 133, 249, 43, 29, 66, 133, 249, 42, 29, 66, 133, 249, 41, 29, 66, + 133, 249, 40, 244, 147, 29, 66, 133, 249, 39, 29, 66, 133, 249, 38, 29, + 66, 133, 249, 37, 29, 66, 133, 249, 36, 29, 66, 133, 249, 35, 29, 66, + 133, 205, 241, 249, 120, 29, 66, 133, 205, 241, 249, 87, 29, 66, 133, + 205, 241, 249, 86, 29, 66, 133, 205, 241, 249, 85, 29, 66, 133, 205, 241, + 249, 84, 29, 66, 133, 205, 241, 249, 83, 29, 66, 133, 205, 241, 249, 82, + 29, 66, 133, 205, 241, 249, 81, 29, 66, 133, 205, 241, 249, 80, 29, 66, + 133, 205, 241, 249, 79, 29, 66, 133, 205, 241, 249, 78, 29, 66, 133, 205, + 241, 249, 77, 29, 66, 133, 205, 241, 249, 76, 29, 66, 133, 205, 241, 249, + 75, 29, 66, 133, 205, 241, 249, 74, 29, 66, 133, 205, 241, 249, 73, 29, + 66, 133, 205, 241, 249, 72, 29, 66, 133, 205, 241, 249, 71, 29, 66, 133, + 205, 241, 249, 70, 29, 66, 133, 205, 241, 249, 69, 29, 66, 133, 205, 241, + 249, 68, 29, 66, 133, 205, 241, 249, 66, 29, 66, 133, 205, 241, 249, 65, + 29, 66, 133, 205, 241, 249, 63, 29, 66, 133, 205, 241, 249, 62, 29, 66, + 133, 205, 241, 249, 61, 29, 66, 133, 205, 241, 249, 60, 29, 66, 133, 205, + 241, 249, 44, 29, 66, 133, 205, 241, 249, 34, 251, 102, 203, 238, 213, + 131, 227, 114, 251, 102, 203, 238, 213, 131, 243, 85, 251, 102, 246, 169, + 82, 251, 102, 42, 105, 251, 102, 42, 108, 251, 102, 42, 147, 251, 102, + 42, 149, 251, 102, 42, 170, 251, 102, 42, 195, 251, 102, 42, 213, 111, + 251, 102, 42, 199, 251, 102, 42, 222, 63, 251, 102, 42, 209, 152, 251, + 102, 42, 207, 151, 251, 102, 42, 209, 53, 251, 102, 42, 239, 153, 251, + 102, 42, 240, 18, 251, 102, 42, 212, 74, 251, 102, 42, 213, 105, 251, + 102, 42, 241, 134, 251, 102, 42, 222, 58, 251, 102, 42, 118, 236, 11, + 251, 102, 42, 120, 236, 11, 251, 102, 42, 126, 236, 11, 251, 102, 42, + 239, 147, 236, 11, 251, 102, 42, 239, 233, 236, 11, 251, 102, 42, 212, + 88, 236, 11, 251, 102, 42, 213, 112, 236, 11, 251, 102, 42, 241, 143, + 236, 11, 251, 102, 42, 222, 64, 236, 11, 251, 102, 42, 118, 209, 36, 251, + 102, 42, 120, 209, 36, 251, 102, 42, 126, 209, 36, 251, 102, 42, 239, + 147, 209, 36, 251, 102, 42, 239, 233, 209, 36, 251, 102, 42, 212, 88, + 209, 36, 251, 102, 42, 213, 112, 209, 36, 251, 102, 42, 241, 143, 209, + 36, 251, 102, 42, 222, 64, 209, 36, 251, 102, 42, 209, 153, 209, 36, 251, + 102, 42, 207, 152, 209, 36, 251, 102, 42, 209, 54, 209, 36, 251, 102, 42, + 239, 154, 209, 36, 251, 102, 42, 240, 19, 209, 36, 251, 102, 42, 212, 75, + 209, 36, 251, 102, 42, 213, 106, 209, 36, 251, 102, 42, 241, 135, 209, + 36, 251, 102, 42, 222, 59, 209, 36, 251, 102, 204, 51, 248, 219, 206, + 235, 251, 102, 204, 51, 239, 245, 210, 240, 251, 102, 204, 51, 214, 171, + 210, 240, 251, 102, 204, 51, 209, 61, 210, 240, 251, 102, 204, 51, 239, + 140, 210, 240, 251, 102, 242, 45, 225, 19, 239, 245, 210, 240, 251, 102, + 227, 95, 225, 19, 239, 245, 210, 240, 251, 102, 225, 19, 214, 171, 210, + 240, 251, 102, 225, 19, 209, 61, 210, 240, 30, 251, 129, 250, 36, 118, + 217, 55, 30, 251, 129, 250, 36, 118, 237, 137, 30, 251, 129, 250, 36, + 118, 242, 65, 30, 251, 129, 250, 36, 170, 30, 251, 129, 250, 36, 240, 18, + 30, 251, 129, 250, 36, 239, 233, 236, 11, 30, 251, 129, 250, 36, 239, + 233, 209, 36, 30, 251, 129, 250, 36, 240, 19, 209, 36, 30, 251, 129, 250, + 36, 239, 233, 209, 237, 30, 251, 129, 250, 36, 209, 153, 209, 237, 30, + 251, 129, 250, 36, 240, 19, 209, 237, 30, 251, 129, 250, 36, 118, 236, + 12, 209, 237, 30, 251, 129, 250, 36, 239, 233, 236, 12, 209, 237, 30, + 251, 129, 250, 36, 118, 209, 37, 209, 237, 30, 251, 129, 250, 36, 239, + 233, 209, 37, 209, 237, 30, 251, 129, 250, 36, 239, 233, 211, 88, 30, + 251, 129, 250, 36, 209, 153, 211, 88, 30, 251, 129, 250, 36, 240, 19, + 211, 88, 30, 251, 129, 250, 36, 118, 236, 12, 211, 88, 30, 251, 129, 250, + 36, 239, 233, 236, 12, 211, 88, 30, 251, 129, 250, 36, 118, 209, 37, 211, + 88, 30, 251, 129, 250, 36, 209, 153, 209, 37, 211, 88, 30, 251, 129, 250, + 36, 240, 19, 209, 37, 211, 88, 30, 251, 129, 250, 36, 209, 153, 224, 85, + 30, 251, 129, 237, 29, 118, 218, 86, 30, 251, 129, 209, 76, 105, 30, 251, + 129, 237, 25, 105, 30, 251, 129, 241, 41, 108, 30, 251, 129, 209, 76, + 108, 30, 251, 129, 245, 56, 120, 242, 64, 30, 251, 129, 241, 41, 120, + 242, 64, 30, 251, 129, 208, 61, 170, 30, 251, 129, 208, 61, 209, 152, 30, + 251, 129, 208, 61, 209, 153, 250, 255, 18, 30, 251, 129, 237, 25, 209, + 152, 30, 251, 129, 224, 222, 209, 152, 30, 251, 129, 209, 76, 209, 152, + 30, 251, 129, 209, 76, 209, 53, 30, 251, 129, 208, 61, 240, 18, 30, 251, + 129, 208, 61, 240, 19, 250, 255, 18, 30, 251, 129, 237, 25, 240, 18, 30, + 251, 129, 209, 76, 240, 18, 30, 251, 129, 209, 76, 118, 236, 11, 30, 251, + 129, 209, 76, 126, 236, 11, 30, 251, 129, 241, 41, 239, 233, 236, 11, 30, + 251, 129, 208, 61, 239, 233, 236, 11, 30, 251, 129, 209, 76, 239, 233, + 236, 11, 30, 251, 129, 247, 21, 239, 233, 236, 11, 30, 251, 129, 223, 60, + 239, 233, 236, 11, 30, 251, 129, 209, 76, 118, 209, 36, 30, 251, 129, + 209, 76, 239, 233, 209, 36, 30, 251, 129, 244, 40, 239, 233, 224, 85, 30, + 251, 129, 211, 49, 240, 19, 224, 85, 30, 118, 162, 54, 30, 118, 162, 2, + 250, 255, 18, 30, 120, 209, 58, 54, 30, 126, 217, 54, 54, 30, 203, 50, + 54, 30, 209, 238, 54, 30, 242, 66, 54, 30, 220, 87, 54, 30, 120, 220, 86, + 54, 30, 126, 220, 86, 54, 30, 239, 147, 220, 86, 54, 30, 239, 233, 220, + 86, 54, 30, 224, 216, 54, 30, 228, 139, 248, 219, 54, 30, 227, 88, 54, + 30, 219, 213, 54, 30, 203, 173, 54, 30, 250, 87, 54, 30, 250, 102, 54, + 30, 238, 7, 54, 30, 208, 23, 248, 219, 54, 30, 202, 85, 54, 30, 118, 217, + 56, 54, 30, 212, 113, 54, 215, 210, 213, 102, 54, 215, 210, 206, 249, 54, + 215, 210, 213, 135, 54, 215, 210, 213, 100, 54, 215, 210, 243, 183, 213, + 100, 54, 215, 210, 212, 135, 54, 215, 210, 244, 36, 54, 215, 210, 217, + 39, 54, 215, 210, 213, 119, 54, 215, 210, 242, 23, 54, 215, 210, 250, 82, + 54, 215, 210, 246, 213, 54, 30, 16, 209, 208, 216, 59, 218, 203, 243, + 160, 2, 219, 25, 218, 203, 243, 160, 2, 218, 78, 237, 64, 218, 203, 243, + 160, 2, 209, 211, 237, 64, 218, 203, 243, 160, 2, 247, 42, 218, 203, 243, + 160, 2, 246, 133, 218, 203, 243, 160, 2, 203, 250, 218, 203, 243, 160, 2, + 237, 35, 218, 203, 243, 160, 2, 238, 213, 218, 203, 243, 160, 2, 209, 0, + 218, 203, 243, 160, 2, 47, 218, 203, 243, 160, 2, 247, 240, 218, 203, + 243, 160, 2, 213, 8, 218, 203, 243, 160, 2, 246, 4, 218, 203, 243, 160, + 2, 225, 121, 218, 203, 243, 160, 2, 225, 68, 218, 203, 243, 160, 2, 214, + 213, 218, 203, 243, 160, 2, 227, 143, 218, 203, 243, 160, 2, 248, 5, 218, + 203, 243, 160, 2, 247, 26, 218, 91, 218, 203, 243, 160, 2, 243, 98, 218, + 203, 243, 160, 2, 245, 239, 218, 203, 243, 160, 2, 212, 46, 218, 203, + 243, 160, 2, 245, 240, 218, 203, 243, 160, 2, 248, 147, 218, 203, 243, + 160, 2, 212, 251, 218, 203, 243, 160, 2, 236, 53, 218, 203, 243, 160, 2, + 237, 1, 218, 203, 243, 160, 2, 247, 174, 227, 210, 218, 203, 243, 160, 2, + 247, 17, 218, 203, 243, 160, 2, 216, 184, 218, 203, 243, 160, 2, 241, + 186, 218, 203, 243, 160, 2, 242, 71, 218, 203, 243, 160, 2, 207, 188, + 218, 203, 243, 160, 2, 248, 150, 218, 203, 243, 160, 2, 218, 92, 208, 95, + 218, 203, 243, 160, 2, 205, 211, 218, 203, 243, 160, 2, 219, 92, 218, + 203, 243, 160, 2, 215, 201, 218, 203, 243, 160, 2, 227, 127, 218, 203, + 243, 160, 2, 219, 194, 249, 25, 218, 203, 243, 160, 2, 239, 193, 218, + 203, 243, 160, 2, 237, 255, 218, 203, 243, 160, 2, 211, 50, 218, 203, + 243, 160, 2, 5, 250, 9, 218, 203, 243, 160, 2, 204, 72, 248, 238, 218, + 203, 243, 160, 2, 39, 220, 89, 95, 226, 197, 1, 63, 226, 197, 1, 74, 226, + 197, 1, 249, 255, 226, 197, 1, 248, 99, 226, 197, 1, 239, 75, 226, 197, + 1, 245, 51, 226, 197, 1, 75, 226, 197, 1, 204, 144, 226, 197, 1, 202, + 159, 226, 197, 1, 209, 110, 226, 197, 1, 230, 184, 226, 197, 1, 230, 54, + 226, 197, 1, 217, 134, 226, 197, 1, 159, 226, 197, 1, 226, 185, 226, 197, + 1, 223, 163, 226, 197, 1, 224, 87, 226, 197, 1, 221, 228, 226, 197, 1, + 68, 226, 197, 1, 219, 184, 226, 197, 1, 229, 48, 226, 197, 1, 146, 226, + 197, 1, 194, 226, 197, 1, 210, 69, 226, 197, 1, 207, 244, 226, 197, 1, + 250, 231, 226, 197, 1, 241, 92, 226, 197, 1, 237, 171, 226, 197, 1, 203, + 196, 247, 32, 1, 63, 247, 32, 1, 219, 170, 247, 32, 1, 245, 51, 247, 32, + 1, 159, 247, 32, 1, 206, 176, 247, 32, 1, 146, 247, 32, 1, 227, 238, 247, + 32, 1, 254, 34, 247, 32, 1, 217, 134, 247, 32, 1, 249, 255, 247, 32, 1, + 226, 185, 247, 32, 1, 78, 247, 32, 1, 244, 214, 247, 32, 1, 210, 69, 247, + 32, 1, 213, 92, 247, 32, 1, 213, 91, 247, 32, 1, 194, 247, 32, 1, 247, + 124, 247, 32, 1, 68, 247, 32, 1, 221, 228, 247, 32, 1, 203, 196, 247, 32, + 1, 223, 163, 247, 32, 1, 207, 243, 247, 32, 1, 219, 184, 247, 32, 1, 211, + 167, 247, 32, 1, 75, 247, 32, 1, 74, 247, 32, 1, 206, 173, 247, 32, 1, + 230, 54, 247, 32, 1, 230, 45, 247, 32, 1, 223, 27, 247, 32, 1, 206, 178, + 247, 32, 1, 239, 75, 247, 32, 1, 239, 10, 247, 32, 1, 211, 108, 247, 32, + 1, 211, 107, 247, 32, 1, 222, 205, 247, 32, 1, 231, 83, 247, 32, 1, 247, + 123, 247, 32, 1, 207, 244, 247, 32, 1, 206, 175, 247, 32, 1, 215, 186, + 247, 32, 1, 225, 59, 247, 32, 1, 225, 58, 247, 32, 1, 225, 57, 247, 32, + 1, 225, 56, 247, 32, 1, 227, 237, 247, 32, 1, 241, 190, 247, 32, 1, 206, + 174, 84, 241, 44, 209, 35, 82, 84, 241, 44, 17, 105, 84, 241, 44, 17, + 108, 84, 241, 44, 17, 147, 84, 241, 44, 17, 149, 84, 241, 44, 17, 170, + 84, 241, 44, 17, 195, 84, 241, 44, 17, 213, 111, 84, 241, 44, 17, 199, + 84, 241, 44, 17, 222, 63, 84, 241, 44, 42, 209, 152, 84, 241, 44, 42, + 207, 151, 84, 241, 44, 42, 209, 53, 84, 241, 44, 42, 239, 153, 84, 241, + 44, 42, 240, 18, 84, 241, 44, 42, 212, 74, 84, 241, 44, 42, 213, 105, 84, + 241, 44, 42, 241, 134, 84, 241, 44, 42, 222, 58, 84, 241, 44, 42, 118, + 236, 11, 84, 241, 44, 42, 120, 236, 11, 84, 241, 44, 42, 126, 236, 11, + 84, 241, 44, 42, 239, 147, 236, 11, 84, 241, 44, 42, 239, 233, 236, 11, + 84, 241, 44, 42, 212, 88, 236, 11, 84, 241, 44, 42, 213, 112, 236, 11, + 84, 241, 44, 42, 241, 143, 236, 11, 84, 241, 44, 42, 222, 64, 236, 11, + 38, 37, 1, 63, 38, 37, 1, 248, 162, 38, 37, 1, 229, 201, 38, 37, 1, 244, + 75, 38, 37, 1, 74, 38, 37, 1, 206, 55, 38, 37, 1, 202, 92, 38, 37, 1, + 237, 67, 38, 37, 1, 209, 92, 38, 37, 1, 75, 38, 37, 1, 173, 38, 37, 1, + 241, 122, 38, 37, 1, 241, 103, 38, 37, 1, 241, 92, 38, 37, 1, 241, 7, 38, + 37, 1, 78, 38, 37, 1, 219, 34, 38, 37, 1, 213, 43, 38, 37, 1, 228, 209, + 38, 37, 1, 241, 28, 38, 37, 1, 241, 17, 38, 37, 1, 209, 187, 38, 37, 1, + 68, 38, 37, 1, 241, 125, 38, 37, 1, 218, 195, 38, 37, 1, 229, 129, 38, + 37, 1, 241, 154, 38, 37, 1, 241, 19, 38, 37, 1, 246, 170, 38, 37, 1, 231, + 83, 38, 37, 1, 206, 178, 38, 37, 1, 241, 0, 38, 37, 221, 44, 105, 38, 37, + 221, 44, 170, 38, 37, 221, 44, 209, 152, 38, 37, 221, 44, 240, 18, 238, + 17, 1, 251, 67, 238, 17, 1, 248, 255, 238, 17, 1, 238, 78, 238, 17, 1, + 244, 194, 238, 17, 1, 251, 63, 238, 17, 1, 217, 117, 238, 17, 1, 230, + 196, 238, 17, 1, 237, 150, 238, 17, 1, 209, 49, 238, 17, 1, 241, 133, + 238, 17, 1, 228, 176, 238, 17, 1, 228, 90, 238, 17, 1, 225, 114, 238, 17, + 1, 223, 62, 238, 17, 1, 230, 154, 238, 17, 1, 206, 196, 238, 17, 1, 219, + 145, 238, 17, 1, 222, 58, 238, 17, 1, 216, 196, 238, 17, 1, 214, 216, + 238, 17, 1, 209, 166, 238, 17, 1, 204, 10, 238, 17, 1, 240, 88, 238, 17, + 1, 231, 87, 238, 17, 1, 235, 252, 238, 17, 1, 219, 223, 238, 17, 1, 222, + 64, 236, 11, 38, 218, 237, 1, 250, 231, 38, 218, 237, 1, 247, 160, 38, + 218, 237, 1, 238, 248, 38, 218, 237, 1, 243, 101, 38, 218, 237, 1, 74, + 38, 218, 237, 1, 202, 62, 38, 218, 237, 1, 241, 247, 38, 218, 237, 1, + 202, 99, 38, 218, 237, 1, 241, 245, 38, 218, 237, 1, 75, 38, 218, 237, 1, + 229, 15, 38, 218, 237, 1, 227, 206, 38, 218, 237, 1, 224, 238, 38, 218, + 237, 1, 222, 228, 38, 218, 237, 1, 205, 175, 38, 218, 237, 1, 219, 22, + 38, 218, 237, 1, 216, 121, 38, 218, 237, 1, 212, 142, 38, 218, 237, 1, + 209, 250, 38, 218, 237, 1, 68, 38, 218, 237, 1, 246, 151, 38, 218, 237, + 1, 212, 235, 38, 218, 237, 1, 213, 45, 38, 218, 237, 1, 202, 215, 38, + 218, 237, 1, 203, 30, 38, 218, 237, 1, 78, 38, 218, 237, 1, 220, 18, 38, + 218, 237, 1, 241, 154, 38, 218, 237, 1, 152, 38, 218, 237, 1, 207, 254, + 38, 218, 237, 1, 206, 43, 38, 218, 237, 1, 203, 34, 38, 218, 237, 1, 203, + 32, 38, 218, 237, 1, 203, 66, 38, 218, 237, 1, 231, 110, 38, 218, 237, 1, + 202, 213, 38, 218, 237, 1, 198, 38, 218, 237, 1, 235, 171, 39, 38, 218, + 237, 1, 250, 231, 39, 38, 218, 237, 1, 243, 101, 39, 38, 218, 237, 1, + 202, 99, 39, 38, 218, 237, 1, 222, 228, 39, 38, 218, 237, 1, 212, 142, + 207, 19, 1, 251, 6, 207, 19, 1, 248, 106, 207, 19, 1, 238, 236, 207, 19, + 1, 229, 144, 207, 19, 1, 244, 37, 207, 19, 1, 236, 136, 207, 19, 1, 204, + 0, 207, 19, 1, 202, 83, 207, 19, 1, 236, 45, 207, 19, 1, 209, 132, 207, + 19, 1, 202, 236, 207, 19, 1, 230, 22, 207, 19, 1, 212, 255, 207, 19, 1, + 228, 24, 207, 19, 1, 224, 247, 207, 19, 1, 243, 253, 207, 19, 1, 221, 40, + 207, 19, 1, 202, 6, 207, 19, 1, 214, 248, 207, 19, 1, 251, 59, 207, 19, + 1, 217, 191, 207, 19, 1, 215, 27, 207, 19, 1, 217, 70, 207, 19, 1, 216, + 175, 207, 19, 1, 209, 96, 207, 19, 1, 238, 114, 207, 19, 1, 135, 207, 19, + 1, 75, 207, 19, 1, 68, 207, 19, 1, 211, 119, 207, 19, 203, 238, 243, 141, + 38, 218, 231, 2, 63, 38, 218, 231, 2, 75, 38, 218, 231, 2, 68, 38, 218, + 231, 2, 173, 38, 218, 231, 2, 228, 209, 38, 218, 231, 2, 239, 8, 38, 218, + 231, 2, 237, 230, 38, 218, 231, 2, 203, 182, 38, 218, 231, 2, 247, 92, + 38, 218, 231, 2, 230, 181, 38, 218, 231, 2, 230, 141, 38, 218, 231, 2, + 210, 22, 38, 218, 231, 2, 207, 203, 38, 218, 231, 2, 244, 212, 38, 218, + 231, 2, 243, 233, 38, 218, 231, 2, 242, 42, 38, 218, 231, 2, 209, 108, + 38, 218, 231, 2, 185, 38, 218, 231, 2, 249, 32, 38, 218, 231, 2, 240, + 108, 38, 218, 231, 2, 201, 201, 38, 218, 231, 2, 221, 84, 38, 218, 231, + 2, 192, 38, 218, 231, 2, 224, 155, 38, 218, 231, 2, 223, 246, 38, 218, + 231, 2, 198, 38, 218, 231, 2, 206, 86, 38, 218, 231, 2, 205, 230, 38, + 218, 231, 2, 216, 220, 38, 218, 231, 2, 215, 145, 38, 218, 231, 2, 228, + 113, 38, 218, 231, 2, 215, 36, 38, 218, 231, 2, 202, 116, 38, 218, 231, + 2, 213, 90, 38, 218, 231, 2, 211, 164, 38, 218, 231, 2, 152, 38, 218, + 231, 2, 250, 28, 38, 218, 231, 2, 250, 27, 38, 218, 231, 2, 250, 26, 38, + 218, 231, 2, 203, 153, 38, 218, 231, 2, 244, 190, 38, 218, 231, 2, 244, + 189, 38, 218, 231, 2, 249, 8, 38, 218, 231, 2, 247, 144, 38, 218, 231, + 203, 238, 243, 141, 38, 218, 231, 42, 105, 38, 218, 231, 42, 108, 38, + 218, 231, 42, 209, 152, 38, 218, 231, 42, 207, 151, 38, 218, 231, 42, + 236, 11, 244, 17, 6, 1, 163, 75, 244, 17, 6, 1, 163, 74, 244, 17, 6, 1, + 163, 63, 244, 17, 6, 1, 163, 251, 73, 244, 17, 6, 1, 163, 78, 244, 17, 6, + 1, 163, 220, 18, 244, 17, 6, 1, 212, 228, 75, 244, 17, 6, 1, 212, 228, + 74, 244, 17, 6, 1, 212, 228, 63, 244, 17, 6, 1, 212, 228, 251, 73, 244, + 17, 6, 1, 212, 228, 78, 244, 17, 6, 1, 212, 228, 220, 18, 244, 17, 6, 1, + 250, 8, 244, 17, 6, 1, 219, 195, 244, 17, 6, 1, 203, 217, 244, 17, 6, 1, + 203, 49, 244, 17, 6, 1, 237, 171, 244, 17, 6, 1, 219, 23, 244, 17, 6, 1, + 248, 150, 244, 17, 6, 1, 209, 176, 244, 17, 6, 1, 244, 61, 244, 17, 6, 1, + 246, 166, 244, 17, 6, 1, 230, 159, 244, 17, 6, 1, 229, 208, 244, 17, 6, + 1, 238, 211, 244, 17, 6, 1, 241, 154, 244, 17, 6, 1, 206, 50, 244, 17, 6, + 1, 240, 243, 244, 17, 6, 1, 209, 90, 244, 17, 6, 1, 241, 17, 244, 17, 6, + 1, 202, 90, 244, 17, 6, 1, 241, 7, 244, 17, 6, 1, 202, 70, 244, 17, 6, 1, + 241, 28, 244, 17, 6, 1, 241, 122, 244, 17, 6, 1, 241, 103, 244, 17, 6, 1, + 241, 92, 244, 17, 6, 1, 241, 78, 244, 17, 6, 1, 220, 57, 244, 17, 6, 1, + 240, 220, 244, 17, 5, 1, 163, 75, 244, 17, 5, 1, 163, 74, 244, 17, 5, 1, + 163, 63, 244, 17, 5, 1, 163, 251, 73, 244, 17, 5, 1, 163, 78, 244, 17, 5, + 1, 163, 220, 18, 244, 17, 5, 1, 212, 228, 75, 244, 17, 5, 1, 212, 228, + 74, 244, 17, 5, 1, 212, 228, 63, 244, 17, 5, 1, 212, 228, 251, 73, 244, + 17, 5, 1, 212, 228, 78, 244, 17, 5, 1, 212, 228, 220, 18, 244, 17, 5, 1, + 250, 8, 244, 17, 5, 1, 219, 195, 244, 17, 5, 1, 203, 217, 244, 17, 5, 1, + 203, 49, 244, 17, 5, 1, 237, 171, 244, 17, 5, 1, 219, 23, 244, 17, 5, 1, + 248, 150, 244, 17, 5, 1, 209, 176, 244, 17, 5, 1, 244, 61, 244, 17, 5, 1, + 246, 166, 244, 17, 5, 1, 230, 159, 244, 17, 5, 1, 229, 208, 244, 17, 5, + 1, 238, 211, 244, 17, 5, 1, 241, 154, 244, 17, 5, 1, 206, 50, 244, 17, 5, + 1, 240, 243, 244, 17, 5, 1, 209, 90, 244, 17, 5, 1, 241, 17, 244, 17, 5, + 1, 202, 90, 244, 17, 5, 1, 241, 7, 244, 17, 5, 1, 202, 70, 244, 17, 5, 1, + 241, 28, 244, 17, 5, 1, 241, 122, 244, 17, 5, 1, 241, 103, 244, 17, 5, 1, + 241, 92, 244, 17, 5, 1, 241, 78, 244, 17, 5, 1, 220, 57, 244, 17, 5, 1, + 240, 220, 213, 50, 1, 219, 20, 213, 50, 1, 208, 131, 213, 50, 1, 229, 96, + 213, 50, 1, 240, 53, 213, 50, 1, 209, 65, 213, 50, 1, 212, 13, 213, 50, + 1, 210, 190, 213, 50, 1, 246, 90, 213, 50, 1, 203, 51, 213, 50, 1, 236, + 9, 213, 50, 1, 248, 85, 213, 50, 1, 244, 74, 213, 50, 1, 238, 250, 213, + 50, 1, 205, 170, 213, 50, 1, 209, 71, 213, 50, 1, 202, 15, 213, 50, 1, + 225, 18, 213, 50, 1, 230, 80, 213, 50, 1, 203, 254, 213, 50, 1, 237, 159, + 213, 50, 1, 227, 33, 213, 50, 1, 224, 111, 213, 50, 1, 231, 90, 213, 50, + 1, 241, 152, 213, 50, 1, 250, 75, 213, 50, 1, 251, 113, 213, 50, 1, 220, + 31, 213, 50, 1, 203, 241, 213, 50, 1, 219, 211, 213, 50, 1, 251, 73, 213, + 50, 1, 215, 224, 213, 50, 1, 221, 40, 213, 50, 1, 241, 172, 213, 50, 1, + 251, 78, 213, 50, 1, 235, 162, 213, 50, 1, 206, 224, 213, 50, 1, 220, 95, + 213, 50, 1, 220, 10, 213, 50, 1, 220, 55, 213, 50, 1, 250, 11, 213, 50, + 1, 250, 121, 213, 50, 1, 219, 244, 213, 50, 1, 251, 54, 213, 50, 1, 241, + 21, 213, 50, 1, 250, 99, 213, 50, 1, 241, 183, 213, 50, 1, 235, 170, 213, + 50, 1, 203, 16, 219, 225, 1, 251, 30, 219, 225, 1, 249, 32, 219, 225, 1, + 210, 22, 219, 225, 1, 230, 181, 219, 225, 1, 203, 182, 219, 225, 1, 229, + 144, 219, 225, 1, 244, 60, 219, 225, 1, 216, 220, 219, 225, 1, 215, 36, + 219, 225, 1, 213, 5, 219, 225, 1, 244, 1, 219, 225, 1, 247, 7, 219, 225, + 1, 239, 8, 219, 225, 1, 240, 108, 219, 225, 1, 217, 124, 219, 225, 1, + 230, 38, 219, 225, 1, 228, 108, 219, 225, 1, 224, 124, 219, 225, 1, 221, + 24, 219, 225, 1, 204, 70, 219, 225, 1, 152, 219, 225, 1, 198, 219, 225, + 1, 63, 219, 225, 1, 74, 219, 225, 1, 75, 219, 225, 1, 78, 219, 225, 1, + 68, 219, 225, 1, 252, 25, 219, 225, 1, 241, 161, 219, 225, 1, 220, 18, + 219, 225, 17, 202, 84, 219, 225, 17, 105, 219, 225, 17, 108, 219, 225, + 17, 147, 219, 225, 17, 149, 219, 225, 17, 170, 219, 225, 17, 195, 219, + 225, 17, 213, 111, 219, 225, 17, 199, 219, 225, 17, 222, 63, 241, 118, 1, + 63, 241, 118, 1, 248, 162, 241, 118, 1, 246, 238, 241, 118, 1, 246, 170, + 241, 118, 1, 244, 75, 241, 118, 1, 223, 17, 241, 118, 1, 243, 248, 241, + 118, 1, 241, 145, 241, 118, 1, 74, 241, 118, 1, 240, 60, 241, 118, 1, + 238, 190, 241, 118, 1, 238, 52, 241, 118, 1, 237, 67, 241, 118, 1, 75, + 241, 118, 1, 230, 161, 241, 118, 1, 229, 201, 241, 118, 1, 227, 234, 241, + 118, 1, 227, 73, 241, 118, 1, 225, 20, 241, 118, 1, 222, 240, 241, 118, + 1, 201, 201, 241, 118, 1, 222, 41, 241, 118, 1, 78, 241, 118, 1, 219, 34, + 241, 118, 1, 217, 106, 241, 118, 1, 216, 158, 241, 118, 1, 215, 180, 241, + 118, 1, 214, 177, 241, 118, 1, 213, 43, 241, 118, 1, 209, 187, 241, 118, + 1, 209, 92, 241, 118, 1, 68, 241, 118, 1, 206, 55, 241, 118, 1, 203, 176, + 241, 118, 1, 203, 124, 241, 118, 1, 202, 92, 241, 118, 1, 202, 71, 241, + 118, 1, 238, 105, 241, 118, 1, 238, 111, 241, 118, 1, 229, 129, 247, 14, + 251, 31, 1, 251, 1, 247, 14, 251, 31, 1, 248, 108, 247, 14, 251, 31, 1, + 238, 69, 247, 14, 251, 31, 1, 244, 140, 247, 14, 251, 31, 1, 241, 171, + 247, 14, 251, 31, 1, 202, 102, 247, 14, 251, 31, 1, 240, 183, 247, 14, + 251, 31, 1, 202, 65, 247, 14, 251, 31, 1, 209, 213, 247, 14, 251, 31, 1, + 246, 199, 247, 14, 251, 31, 1, 202, 224, 247, 14, 251, 31, 1, 202, 80, + 247, 14, 251, 31, 1, 230, 223, 247, 14, 251, 31, 1, 213, 90, 247, 14, + 251, 31, 1, 228, 17, 247, 14, 251, 31, 1, 230, 235, 247, 14, 251, 31, 1, + 203, 172, 247, 14, 251, 31, 1, 242, 7, 247, 14, 251, 31, 1, 247, 39, 247, + 14, 251, 31, 1, 230, 142, 247, 14, 251, 31, 1, 229, 240, 247, 14, 251, + 31, 1, 226, 194, 247, 14, 251, 31, 1, 237, 14, 247, 14, 251, 31, 1, 217, + 107, 247, 14, 251, 31, 1, 250, 177, 247, 14, 251, 31, 1, 246, 107, 247, + 14, 251, 31, 1, 246, 142, 247, 14, 251, 31, 1, 245, 63, 247, 14, 251, 31, + 1, 225, 103, 247, 14, 251, 31, 1, 217, 111, 247, 14, 251, 31, 1, 221, + 151, 247, 14, 251, 31, 1, 241, 240, 247, 14, 251, 31, 1, 213, 73, 247, + 14, 251, 31, 1, 230, 162, 247, 14, 251, 31, 1, 220, 31, 247, 14, 251, 31, + 1, 207, 125, 247, 14, 251, 31, 1, 240, 83, 247, 14, 251, 31, 1, 241, 253, + 247, 14, 251, 31, 1, 246, 176, 247, 14, 251, 31, 1, 219, 9, 247, 14, 251, + 31, 1, 238, 95, 247, 14, 251, 31, 1, 216, 172, 247, 14, 251, 31, 1, 213, + 99, 247, 14, 251, 31, 1, 205, 232, 247, 14, 251, 31, 1, 208, 193, 247, + 14, 251, 31, 1, 212, 207, 247, 14, 251, 31, 1, 230, 194, 247, 14, 251, + 31, 1, 245, 64, 247, 14, 251, 31, 1, 247, 7, 247, 14, 251, 31, 1, 203, + 56, 247, 14, 251, 31, 1, 218, 102, 247, 14, 251, 31, 1, 229, 62, 247, 14, + 251, 31, 246, 49, 82, 29, 34, 2, 251, 231, 29, 34, 2, 251, 230, 29, 34, + 2, 251, 229, 29, 34, 2, 251, 228, 29, 34, 2, 251, 227, 29, 34, 2, 251, + 226, 29, 34, 2, 251, 225, 29, 34, 2, 251, 224, 29, 34, 2, 251, 223, 29, + 34, 2, 251, 222, 29, 34, 2, 251, 221, 29, 34, 2, 251, 220, 29, 34, 2, + 251, 219, 29, 34, 2, 251, 218, 29, 34, 2, 251, 217, 29, 34, 2, 251, 216, + 29, 34, 2, 251, 215, 29, 34, 2, 251, 214, 29, 34, 2, 251, 213, 29, 34, 2, + 251, 212, 29, 34, 2, 251, 211, 29, 34, 2, 251, 210, 29, 34, 2, 251, 209, + 29, 34, 2, 251, 208, 29, 34, 2, 251, 207, 29, 34, 2, 251, 206, 29, 34, 2, + 251, 205, 29, 34, 2, 254, 239, 29, 34, 2, 251, 204, 29, 34, 2, 251, 203, + 29, 34, 2, 251, 202, 29, 34, 2, 251, 201, 29, 34, 2, 251, 200, 29, 34, 2, + 251, 199, 29, 34, 2, 251, 198, 29, 34, 2, 251, 197, 29, 34, 2, 251, 196, + 29, 34, 2, 251, 195, 29, 34, 2, 251, 194, 29, 34, 2, 251, 193, 29, 34, 2, + 251, 192, 29, 34, 2, 251, 191, 29, 34, 2, 251, 190, 29, 34, 2, 251, 189, + 29, 34, 2, 251, 188, 29, 34, 2, 251, 187, 29, 34, 2, 251, 186, 29, 34, 2, + 251, 185, 29, 34, 2, 251, 184, 29, 34, 2, 251, 183, 29, 34, 2, 251, 182, + 29, 34, 2, 251, 181, 29, 34, 2, 251, 180, 29, 34, 2, 251, 179, 29, 34, 2, + 251, 178, 29, 34, 2, 251, 177, 29, 34, 2, 251, 176, 29, 34, 2, 251, 175, + 29, 34, 2, 251, 174, 29, 34, 2, 251, 173, 29, 34, 2, 251, 172, 29, 34, 2, + 251, 171, 29, 34, 2, 251, 170, 29, 34, 2, 251, 169, 29, 34, 2, 251, 168, + 29, 34, 2, 251, 167, 29, 34, 2, 251, 166, 29, 34, 2, 251, 165, 29, 34, 2, + 251, 164, 29, 34, 2, 251, 163, 29, 34, 2, 251, 162, 29, 34, 2, 254, 152, + 29, 34, 2, 251, 161, 29, 34, 2, 251, 160, 29, 34, 2, 254, 117, 29, 34, 2, + 251, 159, 29, 34, 2, 251, 158, 29, 34, 2, 251, 157, 29, 34, 2, 251, 156, + 29, 34, 2, 254, 104, 29, 34, 2, 251, 155, 29, 34, 2, 251, 154, 29, 34, 2, + 251, 153, 29, 34, 2, 251, 152, 29, 34, 2, 251, 151, 29, 34, 2, 253, 176, + 29, 34, 2, 253, 175, 29, 34, 2, 253, 174, 29, 34, 2, 253, 173, 29, 34, 2, + 253, 172, 29, 34, 2, 253, 171, 29, 34, 2, 253, 170, 29, 34, 2, 253, 169, + 29, 34, 2, 253, 167, 29, 34, 2, 253, 166, 29, 34, 2, 253, 165, 29, 34, 2, + 253, 164, 29, 34, 2, 253, 163, 29, 34, 2, 253, 162, 29, 34, 2, 253, 160, + 29, 34, 2, 253, 159, 29, 34, 2, 253, 158, 29, 34, 2, 253, 157, 29, 34, 2, + 253, 156, 29, 34, 2, 253, 155, 29, 34, 2, 253, 154, 29, 34, 2, 253, 153, + 29, 34, 2, 253, 152, 29, 34, 2, 253, 151, 29, 34, 2, 253, 150, 29, 34, 2, + 253, 149, 29, 34, 2, 253, 148, 29, 34, 2, 253, 147, 29, 34, 2, 253, 146, + 29, 34, 2, 253, 145, 29, 34, 2, 253, 144, 29, 34, 2, 253, 143, 29, 34, 2, + 253, 142, 29, 34, 2, 253, 140, 29, 34, 2, 253, 139, 29, 34, 2, 253, 138, + 29, 34, 2, 253, 134, 29, 34, 2, 253, 133, 29, 34, 2, 253, 132, 29, 34, 2, + 253, 131, 29, 34, 2, 253, 127, 29, 34, 2, 253, 126, 29, 34, 2, 253, 125, + 29, 34, 2, 253, 124, 29, 34, 2, 253, 123, 29, 34, 2, 253, 122, 29, 34, 2, + 253, 121, 29, 34, 2, 253, 120, 29, 34, 2, 253, 119, 29, 34, 2, 253, 118, + 29, 34, 2, 253, 117, 29, 34, 2, 253, 116, 29, 34, 2, 253, 115, 29, 34, 2, + 253, 114, 29, 34, 2, 253, 113, 29, 34, 2, 253, 112, 29, 34, 2, 253, 111, + 29, 34, 2, 253, 110, 29, 34, 2, 253, 109, 29, 34, 2, 253, 108, 29, 34, 2, + 253, 107, 29, 34, 2, 253, 106, 29, 34, 2, 253, 105, 29, 34, 2, 253, 103, + 29, 34, 2, 253, 102, 29, 34, 2, 253, 101, 29, 34, 2, 253, 100, 29, 34, 2, + 253, 99, 29, 34, 2, 253, 97, 29, 34, 2, 253, 96, 29, 34, 2, 253, 95, 29, + 34, 2, 253, 94, 29, 34, 2, 253, 92, 29, 34, 2, 253, 91, 29, 34, 2, 253, + 90, 29, 34, 2, 253, 56, 29, 34, 2, 253, 54, 29, 34, 2, 253, 52, 29, 34, + 2, 253, 50, 29, 34, 2, 253, 48, 29, 34, 2, 253, 46, 29, 34, 2, 253, 44, + 29, 34, 2, 253, 42, 29, 34, 2, 253, 40, 29, 34, 2, 253, 38, 29, 34, 2, + 253, 36, 29, 34, 2, 253, 33, 29, 34, 2, 253, 31, 29, 34, 2, 253, 29, 29, + 34, 2, 253, 27, 29, 34, 2, 253, 25, 29, 34, 2, 253, 23, 29, 34, 2, 253, + 21, 29, 34, 2, 253, 19, 29, 34, 2, 252, 193, 29, 34, 2, 252, 192, 29, 34, + 2, 252, 191, 29, 34, 2, 252, 190, 29, 34, 2, 252, 189, 29, 34, 2, 252, + 188, 29, 34, 2, 252, 186, 29, 34, 2, 252, 185, 29, 34, 2, 252, 184, 29, + 34, 2, 252, 183, 29, 34, 2, 252, 182, 29, 34, 2, 252, 181, 29, 34, 2, + 252, 179, 29, 34, 2, 252, 178, 29, 34, 2, 252, 174, 29, 34, 2, 252, 173, + 29, 34, 2, 252, 171, 29, 34, 2, 252, 170, 29, 34, 2, 252, 169, 29, 34, 2, + 252, 168, 29, 34, 2, 252, 167, 29, 34, 2, 252, 166, 29, 34, 2, 252, 165, + 29, 34, 2, 252, 164, 29, 34, 2, 252, 163, 29, 34, 2, 252, 162, 29, 34, 2, + 252, 161, 29, 34, 2, 252, 160, 29, 34, 2, 252, 159, 29, 34, 2, 252, 158, + 29, 34, 2, 252, 157, 29, 34, 2, 252, 156, 29, 34, 2, 252, 155, 29, 34, 2, + 252, 154, 29, 34, 2, 252, 153, 29, 34, 2, 252, 152, 29, 34, 2, 252, 151, + 29, 34, 2, 252, 150, 29, 34, 2, 252, 149, 29, 34, 2, 252, 148, 29, 34, 2, + 252, 147, 29, 34, 2, 252, 146, 29, 34, 2, 252, 145, 29, 34, 2, 252, 144, + 29, 34, 2, 252, 143, 29, 34, 2, 252, 142, 29, 34, 2, 252, 141, 29, 34, 2, + 252, 140, 29, 34, 2, 252, 139, 29, 34, 2, 252, 138, 29, 34, 2, 252, 137, + 29, 34, 2, 252, 136, 29, 34, 2, 252, 135, 29, 34, 2, 252, 134, 29, 34, 2, + 252, 133, 29, 34, 2, 252, 132, 29, 34, 2, 252, 131, 29, 34, 2, 252, 130, + 29, 34, 2, 252, 129, 29, 34, 2, 252, 128, 29, 34, 2, 252, 127, 29, 34, 2, + 252, 126, 29, 34, 2, 252, 125, 29, 34, 2, 252, 124, 29, 34, 2, 252, 123, + 29, 34, 2, 252, 122, 29, 34, 2, 252, 121, 29, 34, 2, 252, 120, 29, 34, 2, + 252, 119, 29, 34, 2, 252, 118, 29, 34, 2, 252, 117, 29, 34, 2, 252, 116, + 29, 34, 2, 252, 115, 29, 34, 2, 252, 114, 29, 34, 2, 252, 113, 29, 34, 2, + 252, 112, 29, 34, 2, 252, 111, 29, 34, 2, 252, 110, 29, 34, 2, 252, 109, + 29, 34, 2, 252, 108, 29, 34, 2, 252, 107, 29, 34, 2, 252, 106, 29, 34, 2, + 252, 105, 29, 34, 2, 252, 104, 29, 34, 2, 252, 103, 29, 34, 2, 252, 102, + 29, 34, 2, 252, 101, 29, 34, 2, 252, 100, 29, 34, 2, 252, 99, 29, 34, 2, + 252, 98, 29, 34, 2, 252, 97, 29, 34, 2, 252, 96, 29, 34, 2, 252, 95, 29, + 34, 2, 252, 94, 29, 34, 2, 252, 93, 29, 34, 2, 252, 92, 29, 34, 2, 252, + 91, 29, 34, 2, 252, 90, 29, 34, 2, 252, 89, 29, 34, 2, 252, 88, 29, 34, + 2, 252, 87, 29, 34, 2, 252, 86, 29, 34, 2, 252, 85, 29, 34, 2, 252, 84, + 29, 34, 2, 252, 83, 29, 34, 2, 252, 82, 29, 34, 2, 252, 81, 29, 34, 2, + 252, 80, 29, 34, 2, 252, 79, 29, 34, 2, 252, 78, 29, 34, 2, 252, 77, 29, + 34, 2, 252, 76, 29, 34, 2, 252, 75, 29, 34, 2, 252, 74, 29, 34, 2, 252, + 73, 29, 34, 2, 252, 72, 29, 34, 2, 252, 71, 29, 34, 2, 252, 70, 29, 34, + 2, 252, 69, 29, 34, 2, 252, 68, 29, 34, 2, 252, 67, 29, 34, 2, 252, 66, + 29, 34, 2, 252, 65, 29, 34, 2, 252, 64, 29, 34, 2, 252, 63, 29, 34, 2, + 252, 62, 29, 34, 2, 252, 61, 29, 34, 2, 252, 60, 29, 34, 2, 252, 59, 29, + 34, 2, 252, 58, 29, 34, 2, 252, 57, 29, 34, 2, 252, 56, 29, 34, 2, 252, + 55, 63, 29, 34, 2, 252, 54, 249, 255, 29, 34, 2, 252, 53, 245, 51, 29, + 34, 2, 252, 52, 74, 29, 34, 2, 252, 51, 240, 174, 29, 34, 2, 252, 50, + 237, 171, 29, 34, 2, 252, 49, 230, 184, 29, 34, 2, 252, 48, 230, 54, 29, + 34, 2, 252, 47, 159, 29, 34, 2, 252, 46, 228, 118, 29, 34, 2, 252, 45, + 228, 117, 29, 34, 2, 252, 44, 228, 116, 29, 34, 2, 252, 43, 228, 115, 29, + 34, 2, 252, 42, 204, 144, 29, 34, 2, 252, 41, 203, 196, 29, 34, 2, 252, + 40, 203, 124, 29, 34, 2, 252, 39, 220, 36, 29, 34, 2, 252, 38, 251, 147, + 29, 34, 2, 252, 37, 248, 199, 29, 34, 2, 252, 36, 244, 122, 29, 34, 2, + 252, 35, 240, 182, 29, 34, 2, 252, 34, 230, 161, 29, 34, 2, 252, 33, 29, + 34, 2, 252, 32, 29, 34, 2, 252, 31, 29, 34, 2, 252, 30, 29, 34, 2, 252, + 29, 29, 34, 2, 252, 28, 29, 34, 2, 252, 27, 29, 34, 2, 252, 26, 245, 58, + 4, 63, 245, 58, 4, 74, 245, 58, 4, 75, 245, 58, 4, 78, 245, 58, 4, 68, + 245, 58, 4, 230, 181, 245, 58, 4, 230, 101, 245, 58, 4, 173, 245, 58, 4, + 229, 201, 245, 58, 4, 229, 100, 245, 58, 4, 229, 26, 245, 58, 4, 228, + 209, 245, 58, 4, 228, 113, 245, 58, 4, 227, 234, 245, 58, 4, 227, 148, + 245, 58, 4, 227, 49, 245, 58, 4, 226, 239, 245, 58, 4, 192, 245, 58, 4, + 225, 20, 245, 58, 4, 224, 155, 245, 58, 4, 224, 82, 245, 58, 4, 223, 246, + 245, 58, 4, 201, 201, 245, 58, 4, 222, 240, 245, 58, 4, 222, 100, 245, + 58, 4, 221, 191, 245, 58, 4, 221, 84, 245, 58, 4, 185, 245, 58, 4, 219, + 34, 245, 58, 4, 218, 167, 245, 58, 4, 218, 69, 245, 58, 4, 217, 191, 245, + 58, 4, 216, 220, 245, 58, 4, 216, 158, 245, 58, 4, 216, 57, 245, 58, 4, + 215, 227, 245, 58, 4, 215, 145, 245, 58, 4, 215, 36, 245, 58, 4, 214, + 177, 245, 58, 4, 212, 162, 245, 58, 4, 212, 13, 245, 58, 4, 211, 10, 245, + 58, 4, 210, 22, 245, 58, 4, 209, 187, 245, 58, 4, 209, 2, 245, 58, 4, + 135, 245, 58, 4, 207, 203, 245, 58, 4, 204, 111, 245, 58, 4, 204, 62, + 245, 58, 4, 204, 30, 245, 58, 4, 204, 0, 245, 58, 4, 203, 182, 245, 58, + 4, 203, 176, 245, 58, 4, 202, 116, 245, 58, 4, 202, 17, 231, 51, 250, + 130, 1, 251, 28, 231, 51, 250, 130, 1, 248, 105, 231, 51, 250, 130, 1, + 238, 67, 231, 51, 250, 130, 1, 244, 177, 231, 51, 250, 130, 1, 237, 67, + 231, 51, 250, 130, 1, 204, 70, 231, 51, 250, 130, 1, 202, 95, 231, 51, + 250, 130, 1, 237, 19, 231, 51, 250, 130, 1, 209, 128, 231, 51, 250, 130, + 1, 202, 235, 231, 51, 250, 130, 1, 229, 250, 231, 51, 250, 130, 1, 228, + 19, 231, 51, 250, 130, 1, 224, 247, 231, 51, 250, 130, 1, 221, 40, 231, + 51, 250, 130, 1, 214, 249, 231, 51, 250, 130, 1, 250, 3, 231, 51, 250, + 130, 1, 219, 34, 231, 51, 250, 130, 1, 215, 26, 231, 51, 250, 130, 1, + 217, 69, 231, 51, 250, 130, 1, 216, 91, 231, 51, 250, 130, 1, 212, 255, + 231, 51, 250, 130, 1, 209, 201, 231, 51, 250, 130, 214, 168, 54, 231, 51, + 250, 130, 42, 105, 231, 51, 250, 130, 42, 108, 231, 51, 250, 130, 42, + 147, 231, 51, 250, 130, 42, 209, 152, 231, 51, 250, 130, 42, 207, 151, + 231, 51, 250, 130, 42, 118, 236, 11, 231, 51, 250, 130, 42, 118, 209, 36, + 231, 51, 250, 130, 42, 209, 153, 209, 36, 219, 134, 1, 251, 28, 219, 134, + 1, 248, 105, 219, 134, 1, 238, 67, 219, 134, 1, 244, 177, 219, 134, 1, + 237, 67, 219, 134, 1, 204, 70, 219, 134, 1, 202, 95, 219, 134, 1, 237, + 19, 219, 134, 1, 209, 128, 219, 134, 1, 202, 235, 219, 134, 1, 229, 250, + 219, 134, 1, 228, 19, 219, 134, 1, 224, 247, 219, 134, 1, 46, 221, 40, + 219, 134, 1, 221, 40, 219, 134, 1, 214, 249, 219, 134, 1, 250, 3, 219, + 134, 1, 219, 34, 219, 134, 1, 215, 26, 219, 134, 1, 217, 69, 219, 134, 1, + 216, 91, 219, 134, 1, 212, 255, 219, 134, 1, 209, 201, 219, 134, 227, + 217, 239, 212, 219, 134, 216, 11, 239, 212, 219, 134, 42, 105, 219, 134, + 42, 108, 219, 134, 42, 147, 219, 134, 42, 149, 219, 134, 42, 170, 219, + 134, 42, 209, 152, 219, 134, 42, 207, 151, 223, 102, 1, 46, 251, 28, 223, + 102, 1, 251, 28, 223, 102, 1, 46, 248, 105, 223, 102, 1, 248, 105, 223, + 102, 1, 238, 67, 223, 102, 1, 244, 177, 223, 102, 1, 46, 237, 67, 223, + 102, 1, 237, 67, 223, 102, 1, 204, 70, 223, 102, 1, 202, 95, 223, 102, 1, + 237, 19, 223, 102, 1, 209, 128, 223, 102, 1, 46, 202, 235, 223, 102, 1, + 202, 235, 223, 102, 1, 46, 229, 250, 223, 102, 1, 229, 250, 223, 102, 1, + 46, 228, 19, 223, 102, 1, 228, 19, 223, 102, 1, 46, 224, 247, 223, 102, + 1, 224, 247, 223, 102, 1, 46, 221, 40, 223, 102, 1, 221, 40, 223, 102, 1, + 214, 249, 223, 102, 1, 250, 3, 223, 102, 1, 219, 34, 223, 102, 1, 215, + 26, 223, 102, 1, 217, 69, 223, 102, 1, 216, 91, 223, 102, 1, 46, 212, + 255, 223, 102, 1, 212, 255, 223, 102, 1, 209, 201, 223, 102, 42, 105, + 223, 102, 42, 108, 223, 102, 42, 147, 223, 102, 42, 149, 223, 102, 245, + 116, 42, 149, 223, 102, 42, 170, 223, 102, 42, 209, 152, 223, 102, 42, + 207, 151, 223, 102, 42, 118, 236, 11, 237, 78, 1, 251, 28, 237, 78, 1, + 248, 105, 237, 78, 1, 238, 67, 237, 78, 1, 244, 176, 237, 78, 1, 237, 67, + 237, 78, 1, 204, 70, 237, 78, 1, 202, 94, 237, 78, 1, 237, 19, 237, 78, + 1, 209, 128, 237, 78, 1, 202, 235, 237, 78, 1, 229, 250, 237, 78, 1, 228, + 19, 237, 78, 1, 224, 247, 237, 78, 1, 221, 40, 237, 78, 1, 214, 249, 237, + 78, 1, 250, 2, 237, 78, 1, 219, 34, 237, 78, 1, 215, 26, 237, 78, 1, 217, + 69, 237, 78, 1, 212, 255, 237, 78, 1, 209, 201, 237, 78, 42, 105, 237, + 78, 42, 170, 237, 78, 42, 209, 152, 237, 78, 42, 207, 151, 237, 78, 42, + 118, 236, 11, 218, 178, 1, 251, 25, 218, 178, 1, 248, 108, 218, 178, 1, + 238, 237, 218, 178, 1, 244, 39, 218, 178, 1, 237, 67, 218, 178, 1, 204, + 77, 218, 178, 1, 202, 109, 218, 178, 1, 237, 21, 218, 178, 1, 209, 132, + 218, 178, 1, 202, 236, 218, 178, 1, 230, 22, 218, 178, 1, 228, 25, 218, + 178, 1, 224, 247, 218, 178, 1, 221, 40, 218, 178, 1, 213, 137, 218, 178, + 1, 251, 59, 218, 178, 1, 219, 34, 218, 178, 1, 215, 27, 218, 178, 1, 217, + 74, 218, 178, 1, 215, 200, 218, 178, 1, 212, 255, 218, 178, 1, 209, 207, + 218, 178, 42, 105, 218, 178, 42, 209, 152, 218, 178, 42, 207, 151, 218, + 178, 42, 118, 236, 11, 218, 178, 42, 108, 218, 178, 42, 147, 218, 178, + 203, 238, 213, 130, 226, 196, 1, 63, 226, 196, 1, 249, 255, 226, 196, 1, + 239, 75, 226, 196, 1, 245, 51, 226, 196, 1, 74, 226, 196, 1, 206, 164, + 226, 196, 1, 75, 226, 196, 1, 203, 124, 226, 196, 1, 230, 54, 226, 196, + 1, 159, 226, 196, 1, 226, 185, 226, 196, 1, 223, 163, 226, 196, 1, 78, + 226, 196, 1, 146, 226, 196, 1, 211, 167, 226, 196, 1, 210, 69, 226, 196, + 1, 68, 226, 196, 1, 240, 174, 226, 196, 1, 217, 134, 226, 196, 1, 194, + 226, 196, 1, 207, 244, 226, 196, 1, 250, 231, 226, 196, 1, 241, 92, 226, + 196, 1, 226, 199, 226, 196, 1, 221, 228, 226, 196, 1, 247, 125, 226, 196, + 208, 82, 82, 129, 236, 253, 1, 63, 129, 236, 253, 1, 74, 129, 236, 253, + 1, 75, 129, 236, 253, 1, 78, 129, 236, 253, 1, 198, 129, 236, 253, 1, + 204, 111, 129, 236, 253, 1, 249, 32, 129, 236, 253, 1, 249, 31, 129, 236, + 253, 1, 185, 129, 236, 253, 1, 192, 129, 236, 253, 1, 201, 201, 129, 236, + 253, 1, 223, 110, 129, 236, 253, 1, 222, 240, 129, 236, 253, 1, 222, 239, + 129, 236, 253, 1, 216, 220, 129, 236, 253, 1, 216, 219, 129, 236, 253, 1, + 228, 113, 129, 236, 253, 1, 229, 144, 129, 236, 253, 1, 237, 12, 129, + 236, 253, 1, 215, 36, 129, 236, 253, 1, 215, 35, 129, 236, 253, 1, 214, + 177, 129, 236, 253, 1, 173, 129, 236, 253, 1, 217, 126, 129, 236, 253, 1, + 210, 22, 129, 236, 253, 1, 210, 21, 129, 236, 253, 1, 209, 187, 129, 236, + 253, 1, 209, 186, 129, 236, 253, 1, 135, 129, 236, 253, 1, 244, 212, 129, + 236, 253, 16, 205, 224, 129, 236, 253, 16, 205, 223, 129, 191, 1, 63, + 129, 191, 1, 74, 129, 191, 1, 75, 129, 191, 1, 78, 129, 191, 1, 198, 129, + 191, 1, 204, 111, 129, 191, 1, 249, 32, 129, 191, 1, 185, 129, 191, 1, + 192, 129, 191, 1, 201, 201, 129, 191, 1, 222, 240, 129, 191, 1, 216, 220, + 129, 191, 1, 228, 113, 129, 191, 1, 229, 144, 129, 191, 1, 237, 12, 129, + 191, 1, 215, 36, 129, 191, 1, 250, 126, 215, 36, 129, 191, 1, 214, 177, + 129, 191, 1, 173, 129, 191, 1, 217, 126, 129, 191, 1, 210, 22, 129, 191, + 1, 209, 187, 129, 191, 1, 135, 129, 191, 1, 244, 212, 129, 191, 239, 138, + 241, 113, 207, 156, 129, 191, 239, 138, 118, 237, 137, 129, 191, 227, 36, + 215, 233, 129, 191, 227, 36, 231, 56, 129, 191, 42, 105, 129, 191, 42, + 108, 129, 191, 42, 147, 129, 191, 42, 149, 129, 191, 42, 170, 129, 191, + 42, 195, 129, 191, 42, 213, 111, 129, 191, 42, 199, 129, 191, 42, 222, + 63, 129, 191, 42, 209, 152, 129, 191, 42, 207, 151, 129, 191, 42, 209, + 53, 129, 191, 42, 239, 153, 129, 191, 42, 240, 18, 129, 191, 42, 212, 74, + 129, 191, 42, 213, 105, 129, 191, 42, 118, 236, 11, 129, 191, 42, 120, + 236, 11, 129, 191, 42, 126, 236, 11, 129, 191, 42, 239, 147, 236, 11, + 129, 191, 42, 239, 233, 236, 11, 129, 191, 42, 212, 88, 236, 11, 129, + 191, 42, 213, 112, 236, 11, 129, 191, 42, 241, 143, 236, 11, 129, 191, + 42, 222, 64, 236, 11, 129, 191, 42, 118, 209, 36, 129, 191, 42, 120, 209, + 36, 129, 191, 42, 126, 209, 36, 129, 191, 42, 239, 147, 209, 36, 129, + 191, 42, 239, 233, 209, 36, 129, 191, 42, 212, 88, 209, 36, 129, 191, 42, + 213, 112, 209, 36, 129, 191, 42, 241, 143, 209, 36, 129, 191, 42, 222, + 64, 209, 36, 129, 191, 42, 209, 153, 209, 36, 129, 191, 42, 207, 152, + 209, 36, 129, 191, 42, 209, 54, 209, 36, 129, 191, 42, 239, 154, 209, 36, + 129, 191, 42, 240, 19, 209, 36, 129, 191, 42, 212, 75, 209, 36, 129, 191, + 42, 213, 106, 209, 36, 129, 191, 42, 241, 135, 209, 36, 129, 191, 42, + 222, 59, 209, 36, 129, 191, 42, 118, 236, 12, 209, 36, 129, 191, 42, 120, + 236, 12, 209, 36, 129, 191, 42, 126, 236, 12, 209, 36, 129, 191, 42, 239, + 147, 236, 12, 209, 36, 129, 191, 42, 239, 233, 236, 12, 209, 36, 129, + 191, 42, 212, 88, 236, 12, 209, 36, 129, 191, 42, 213, 112, 236, 12, 209, + 36, 129, 191, 42, 241, 143, 236, 12, 209, 36, 129, 191, 42, 222, 64, 236, + 12, 209, 36, 129, 191, 239, 138, 118, 207, 157, 129, 191, 239, 138, 120, + 207, 156, 129, 191, 239, 138, 126, 207, 156, 129, 191, 239, 138, 239, + 147, 207, 156, 129, 191, 239, 138, 239, 233, 207, 156, 129, 191, 239, + 138, 212, 88, 207, 156, 129, 191, 239, 138, 213, 112, 207, 156, 129, 191, + 239, 138, 241, 143, 207, 156, 129, 191, 239, 138, 222, 64, 207, 156, 129, + 191, 239, 138, 209, 153, 207, 156, 229, 131, 1, 63, 229, 131, 22, 2, 75, + 229, 131, 22, 2, 68, 229, 131, 22, 2, 125, 146, 229, 131, 22, 2, 74, 229, + 131, 22, 2, 78, 229, 131, 22, 227, 196, 82, 229, 131, 2, 52, 215, 253, + 56, 229, 131, 2, 250, 180, 229, 131, 2, 205, 199, 229, 131, 1, 173, 229, + 131, 1, 229, 144, 229, 131, 1, 239, 8, 229, 131, 1, 238, 119, 229, 131, + 1, 247, 92, 229, 131, 1, 246, 199, 229, 131, 1, 230, 181, 229, 131, 1, + 221, 11, 229, 131, 1, 207, 241, 229, 131, 1, 207, 229, 229, 131, 1, 244, + 120, 229, 131, 1, 244, 104, 229, 131, 1, 221, 227, 229, 131, 1, 210, 22, + 229, 131, 1, 209, 108, 229, 131, 1, 244, 212, 229, 131, 1, 244, 1, 229, + 131, 1, 201, 201, 229, 131, 1, 185, 229, 131, 1, 218, 208, 229, 131, 1, + 249, 32, 229, 131, 1, 248, 98, 229, 131, 1, 192, 229, 131, 1, 198, 229, + 131, 1, 216, 220, 229, 131, 1, 228, 113, 229, 131, 1, 206, 86, 229, 131, + 1, 213, 90, 229, 131, 1, 211, 164, 229, 131, 1, 215, 36, 229, 131, 1, + 202, 116, 229, 131, 1, 152, 229, 131, 1, 229, 47, 229, 131, 1, 207, 209, + 229, 131, 2, 248, 231, 55, 229, 131, 2, 247, 13, 229, 131, 2, 70, 56, + 229, 131, 205, 204, 229, 131, 17, 105, 229, 131, 17, 108, 229, 131, 17, + 147, 229, 131, 17, 149, 229, 131, 42, 209, 152, 229, 131, 42, 207, 151, + 229, 131, 42, 118, 236, 11, 229, 131, 42, 118, 209, 36, 229, 131, 217, + 179, 243, 85, 229, 131, 217, 179, 5, 246, 61, 229, 131, 217, 179, 246, + 61, 229, 131, 217, 179, 245, 139, 142, 229, 131, 217, 179, 225, 116, 229, + 131, 217, 179, 227, 5, 229, 131, 217, 179, 244, 166, 229, 131, 217, 179, + 52, 244, 166, 229, 131, 217, 179, 227, 108, 38, 211, 238, 250, 141, 1, + 237, 67, 38, 211, 238, 250, 141, 1, 228, 19, 38, 211, 238, 250, 141, 1, + 237, 19, 38, 211, 238, 250, 141, 1, 224, 247, 38, 211, 238, 250, 141, 1, + 217, 69, 38, 211, 238, 250, 141, 1, 204, 70, 38, 211, 238, 250, 141, 1, + 212, 255, 38, 211, 238, 250, 141, 1, 216, 91, 38, 211, 238, 250, 141, 1, + 248, 105, 38, 211, 238, 250, 141, 1, 209, 201, 38, 211, 238, 250, 141, 1, + 214, 225, 38, 211, 238, 250, 141, 1, 229, 250, 38, 211, 238, 250, 141, 1, + 221, 40, 38, 211, 238, 250, 141, 1, 229, 126, 38, 211, 238, 250, 141, 1, + 215, 26, 38, 211, 238, 250, 141, 1, 214, 249, 38, 211, 238, 250, 141, 1, + 240, 60, 38, 211, 238, 250, 141, 1, 251, 30, 38, 211, 238, 250, 141, 1, + 250, 2, 38, 211, 238, 250, 141, 1, 243, 254, 38, 211, 238, 250, 141, 1, + 238, 67, 38, 211, 238, 250, 141, 1, 244, 177, 38, 211, 238, 250, 141, 1, + 238, 107, 38, 211, 238, 250, 141, 1, 209, 128, 38, 211, 238, 250, 141, 1, + 202, 94, 38, 211, 238, 250, 141, 1, 243, 251, 38, 211, 238, 250, 141, 1, + 202, 235, 38, 211, 238, 250, 141, 1, 209, 94, 38, 211, 238, 250, 141, 1, + 209, 73, 38, 211, 238, 250, 141, 42, 105, 38, 211, 238, 250, 141, 42, + 240, 18, 38, 211, 238, 250, 141, 141, 231, 31, 38, 153, 250, 141, 1, 237, + 43, 38, 153, 250, 141, 1, 228, 28, 38, 153, 250, 141, 1, 237, 148, 38, + 153, 250, 141, 1, 225, 5, 38, 153, 250, 141, 1, 217, 119, 38, 153, 250, + 141, 1, 204, 70, 38, 153, 250, 141, 1, 241, 15, 38, 153, 250, 141, 1, + 216, 122, 38, 153, 250, 141, 1, 248, 138, 38, 153, 250, 141, 1, 209, 169, + 38, 153, 250, 141, 1, 241, 16, 38, 153, 250, 141, 1, 230, 22, 38, 153, + 250, 141, 1, 221, 178, 38, 153, 250, 141, 1, 229, 140, 38, 153, 250, 141, + 1, 215, 28, 38, 153, 250, 141, 1, 241, 14, 38, 153, 250, 141, 1, 240, 47, + 38, 153, 250, 141, 1, 251, 30, 38, 153, 250, 141, 1, 251, 59, 38, 153, + 250, 141, 1, 244, 207, 38, 153, 250, 141, 1, 238, 181, 38, 153, 250, 141, + 1, 244, 184, 38, 153, 250, 141, 1, 238, 114, 38, 153, 250, 141, 1, 209, + 251, 38, 153, 250, 141, 1, 202, 107, 38, 153, 250, 141, 1, 209, 100, 38, + 153, 250, 141, 1, 203, 47, 38, 153, 250, 141, 1, 209, 88, 38, 153, 250, + 141, 1, 202, 110, 38, 153, 250, 141, 42, 105, 38, 153, 250, 141, 42, 209, + 152, 38, 153, 250, 141, 42, 207, 151, 225, 115, 1, 251, 28, 225, 115, 1, + 248, 105, 225, 115, 1, 248, 92, 225, 115, 1, 238, 67, 225, 115, 1, 238, + 92, 225, 115, 1, 244, 177, 225, 115, 1, 237, 67, 225, 115, 1, 204, 70, + 225, 115, 2, 207, 29, 225, 115, 1, 202, 95, 225, 115, 1, 202, 73, 225, + 115, 1, 230, 163, 225, 115, 1, 230, 145, 225, 115, 1, 237, 19, 225, 115, + 1, 209, 128, 225, 115, 1, 202, 235, 225, 115, 1, 229, 250, 225, 115, 1, + 203, 179, 225, 115, 1, 229, 133, 225, 115, 1, 228, 19, 225, 115, 1, 243, + 250, 225, 115, 1, 209, 99, 225, 115, 1, 224, 247, 225, 115, 1, 221, 40, + 225, 115, 1, 214, 249, 225, 115, 1, 250, 3, 225, 115, 1, 251, 234, 225, + 115, 1, 219, 34, 225, 115, 1, 240, 60, 225, 115, 1, 215, 26, 225, 115, 1, + 217, 69, 225, 115, 1, 203, 157, 225, 115, 1, 217, 95, 225, 115, 1, 216, + 91, 225, 115, 1, 212, 255, 225, 115, 1, 211, 133, 225, 115, 1, 209, 201, + 225, 115, 251, 146, 131, 55, 225, 115, 251, 146, 131, 56, 225, 115, 42, + 105, 225, 115, 42, 170, 225, 115, 42, 209, 152, 225, 115, 42, 207, 151, + 225, 115, 42, 118, 236, 11, 225, 115, 217, 179, 211, 94, 225, 115, 217, + 179, 239, 212, 225, 115, 217, 179, 52, 70, 204, 5, 243, 85, 225, 115, + 217, 179, 70, 204, 5, 243, 85, 225, 115, 217, 179, 243, 85, 225, 115, + 217, 179, 120, 243, 83, 225, 115, 217, 179, 227, 115, 240, 7, 250, 14, 1, + 63, 250, 14, 1, 252, 25, 250, 14, 1, 250, 178, 250, 14, 1, 251, 240, 250, + 14, 1, 250, 231, 250, 14, 1, 251, 241, 250, 14, 1, 251, 109, 250, 14, 1, + 251, 105, 250, 14, 1, 74, 250, 14, 1, 241, 161, 250, 14, 1, 78, 250, 14, + 1, 220, 18, 250, 14, 1, 75, 250, 14, 1, 231, 83, 250, 14, 1, 68, 250, 14, + 1, 206, 178, 250, 14, 1, 229, 201, 250, 14, 1, 203, 176, 250, 14, 1, 203, + 138, 250, 14, 1, 203, 148, 250, 14, 1, 238, 190, 250, 14, 1, 238, 150, + 250, 14, 1, 238, 105, 250, 14, 1, 246, 238, 250, 14, 1, 230, 161, 250, + 14, 1, 209, 187, 250, 14, 1, 209, 92, 250, 14, 1, 244, 75, 250, 14, 1, + 243, 248, 250, 14, 1, 207, 236, 250, 14, 1, 219, 34, 250, 14, 1, 240, 60, + 250, 14, 1, 248, 162, 250, 14, 1, 248, 94, 250, 14, 1, 222, 190, 250, 14, + 1, 222, 106, 250, 14, 1, 222, 107, 250, 14, 1, 222, 240, 250, 14, 1, 221, + 1, 250, 14, 1, 221, 222, 250, 14, 1, 225, 20, 250, 14, 1, 236, 186, 250, + 14, 1, 202, 166, 250, 14, 1, 203, 52, 250, 14, 1, 206, 55, 250, 14, 1, + 216, 158, 250, 14, 1, 227, 234, 250, 14, 1, 214, 177, 250, 14, 1, 202, + 92, 250, 14, 1, 213, 43, 250, 14, 1, 202, 71, 250, 14, 1, 212, 169, 250, + 14, 1, 211, 134, 250, 14, 1, 237, 67, 250, 14, 251, 146, 82, 208, 213, + 120, 187, 115, 118, 70, 217, 178, 5, 120, 187, 115, 118, 70, 217, 178, + 228, 8, 120, 187, 115, 118, 70, 217, 178, 228, 8, 118, 70, 115, 120, 187, + 217, 178, 228, 8, 120, 215, 250, 115, 118, 215, 253, 217, 178, 228, 8, + 118, 215, 253, 115, 120, 215, 250, 217, 178, 231, 10, 219, 70, 1, 251, + 28, 231, 10, 219, 70, 1, 248, 105, 231, 10, 219, 70, 1, 238, 67, 231, 10, + 219, 70, 1, 244, 177, 231, 10, 219, 70, 1, 237, 67, 231, 10, 219, 70, 1, + 204, 70, 231, 10, 219, 70, 1, 202, 95, 231, 10, 219, 70, 1, 237, 19, 231, + 10, 219, 70, 1, 209, 128, 231, 10, 219, 70, 1, 202, 235, 231, 10, 219, + 70, 1, 229, 250, 231, 10, 219, 70, 1, 228, 19, 231, 10, 219, 70, 1, 224, + 247, 231, 10, 219, 70, 1, 221, 40, 231, 10, 219, 70, 1, 214, 249, 231, + 10, 219, 70, 1, 250, 3, 231, 10, 219, 70, 1, 219, 34, 231, 10, 219, 70, + 1, 215, 26, 231, 10, 219, 70, 1, 217, 69, 231, 10, 219, 70, 1, 216, 91, + 231, 10, 219, 70, 1, 212, 255, 231, 10, 219, 70, 1, 209, 201, 231, 10, + 219, 70, 42, 105, 231, 10, 219, 70, 42, 108, 231, 10, 219, 70, 42, 147, + 231, 10, 219, 70, 42, 149, 231, 10, 219, 70, 42, 209, 152, 231, 10, 219, + 70, 42, 207, 151, 231, 10, 219, 70, 42, 118, 236, 11, 231, 10, 219, 70, + 42, 118, 209, 36, 231, 10, 219, 149, 1, 251, 28, 231, 10, 219, 149, 1, + 248, 105, 231, 10, 219, 149, 1, 238, 67, 231, 10, 219, 149, 1, 244, 177, + 231, 10, 219, 149, 1, 237, 67, 231, 10, 219, 149, 1, 204, 69, 231, 10, + 219, 149, 1, 202, 95, 231, 10, 219, 149, 1, 237, 19, 231, 10, 219, 149, + 1, 209, 128, 231, 10, 219, 149, 1, 202, 235, 231, 10, 219, 149, 1, 229, + 250, 231, 10, 219, 149, 1, 228, 19, 231, 10, 219, 149, 1, 224, 246, 231, + 10, 219, 149, 1, 221, 40, 231, 10, 219, 149, 1, 214, 249, 231, 10, 219, + 149, 1, 219, 34, 231, 10, 219, 149, 1, 215, 26, 231, 10, 219, 149, 1, + 212, 255, 231, 10, 219, 149, 1, 209, 201, 231, 10, 219, 149, 42, 105, + 231, 10, 219, 149, 42, 108, 231, 10, 219, 149, 42, 147, 231, 10, 219, + 149, 42, 149, 231, 10, 219, 149, 42, 209, 152, 231, 10, 219, 149, 42, + 207, 151, 231, 10, 219, 149, 42, 118, 236, 11, 231, 10, 219, 149, 42, + 118, 209, 36, 217, 203, 219, 149, 1, 251, 28, 217, 203, 219, 149, 1, 248, + 105, 217, 203, 219, 149, 1, 238, 67, 217, 203, 219, 149, 1, 244, 177, + 217, 203, 219, 149, 1, 237, 67, 217, 203, 219, 149, 1, 204, 69, 217, 203, + 219, 149, 1, 202, 95, 217, 203, 219, 149, 1, 237, 19, 217, 203, 219, 149, + 1, 202, 235, 217, 203, 219, 149, 1, 229, 250, 217, 203, 219, 149, 1, 228, + 19, 217, 203, 219, 149, 1, 224, 246, 217, 203, 219, 149, 1, 221, 40, 217, + 203, 219, 149, 1, 214, 249, 217, 203, 219, 149, 1, 219, 34, 217, 203, + 219, 149, 1, 215, 26, 217, 203, 219, 149, 1, 212, 255, 217, 203, 219, + 149, 1, 209, 201, 217, 203, 219, 149, 214, 168, 82, 217, 203, 219, 149, + 207, 174, 214, 168, 82, 217, 203, 219, 149, 239, 147, 187, 3, 245, 130, + 217, 203, 219, 149, 239, 147, 187, 3, 243, 85, 217, 203, 219, 149, 42, + 105, 217, 203, 219, 149, 42, 108, 217, 203, 219, 149, 42, 147, 217, 203, + 219, 149, 42, 149, 217, 203, 219, 149, 42, 209, 152, 217, 203, 219, 149, + 42, 207, 151, 217, 203, 219, 149, 42, 118, 236, 11, 38, 207, 178, 1, 219, + 235, 63, 38, 207, 178, 1, 203, 40, 63, 38, 207, 178, 1, 203, 40, 251, + 109, 38, 207, 178, 1, 219, 235, 75, 38, 207, 178, 1, 203, 40, 75, 38, + 207, 178, 1, 203, 40, 74, 38, 207, 178, 1, 219, 235, 78, 38, 207, 178, 1, + 219, 235, 220, 73, 38, 207, 178, 1, 203, 40, 220, 73, 38, 207, 178, 1, + 219, 235, 251, 232, 38, 207, 178, 1, 203, 40, 251, 232, 38, 207, 178, 1, + 219, 235, 251, 108, 38, 207, 178, 1, 203, 40, 251, 108, 38, 207, 178, 1, + 219, 235, 251, 81, 38, 207, 178, 1, 203, 40, 251, 81, 38, 207, 178, 1, + 219, 235, 251, 103, 38, 207, 178, 1, 203, 40, 251, 103, 38, 207, 178, 1, + 219, 235, 251, 122, 38, 207, 178, 1, 203, 40, 251, 122, 38, 207, 178, 1, + 219, 235, 251, 107, 38, 207, 178, 1, 219, 235, 240, 181, 38, 207, 178, 1, + 203, 40, 240, 181, 38, 207, 178, 1, 219, 235, 250, 8, 38, 207, 178, 1, + 203, 40, 250, 8, 38, 207, 178, 1, 219, 235, 251, 90, 38, 207, 178, 1, + 203, 40, 251, 90, 38, 207, 178, 1, 219, 235, 251, 101, 38, 207, 178, 1, + 203, 40, 251, 101, 38, 207, 178, 1, 219, 235, 220, 71, 38, 207, 178, 1, + 203, 40, 220, 71, 38, 207, 178, 1, 219, 235, 251, 39, 38, 207, 178, 1, + 203, 40, 251, 39, 38, 207, 178, 1, 219, 235, 251, 100, 38, 207, 178, 1, + 219, 235, 241, 106, 38, 207, 178, 1, 219, 235, 241, 103, 38, 207, 178, 1, + 219, 235, 250, 231, 38, 207, 178, 1, 219, 235, 251, 98, 38, 207, 178, 1, + 203, 40, 251, 98, 38, 207, 178, 1, 219, 235, 241, 70, 38, 207, 178, 1, + 203, 40, 241, 70, 38, 207, 178, 1, 219, 235, 241, 89, 38, 207, 178, 1, + 203, 40, 241, 89, 38, 207, 178, 1, 219, 235, 241, 56, 38, 207, 178, 1, + 203, 40, 241, 56, 38, 207, 178, 1, 203, 40, 250, 223, 38, 207, 178, 1, + 219, 235, 241, 78, 38, 207, 178, 1, 203, 40, 251, 97, 38, 207, 178, 1, + 219, 235, 241, 46, 38, 207, 178, 1, 219, 235, 220, 9, 38, 207, 178, 1, + 219, 235, 235, 164, 38, 207, 178, 1, 219, 235, 241, 169, 38, 207, 178, 1, + 203, 40, 241, 169, 38, 207, 178, 1, 219, 235, 250, 148, 38, 207, 178, 1, + 203, 40, 250, 148, 38, 207, 178, 1, 219, 235, 230, 226, 38, 207, 178, 1, + 203, 40, 230, 226, 38, 207, 178, 1, 219, 235, 219, 246, 38, 207, 178, 1, + 203, 40, 219, 246, 38, 207, 178, 1, 219, 235, 250, 144, 38, 207, 178, 1, + 203, 40, 250, 144, 38, 207, 178, 1, 219, 235, 251, 96, 38, 207, 178, 1, + 219, 235, 250, 81, 38, 207, 178, 1, 219, 235, 251, 94, 38, 207, 178, 1, + 219, 235, 250, 75, 38, 207, 178, 1, 203, 40, 250, 75, 38, 207, 178, 1, + 219, 235, 241, 7, 38, 207, 178, 1, 203, 40, 241, 7, 38, 207, 178, 1, 219, + 235, 250, 49, 38, 207, 178, 1, 203, 40, 250, 49, 38, 207, 178, 1, 219, + 235, 251, 91, 38, 207, 178, 1, 203, 40, 251, 91, 38, 207, 178, 1, 219, + 235, 219, 224, 38, 207, 178, 1, 219, 235, 248, 215, 38, 145, 6, 1, 63, + 38, 145, 6, 1, 252, 25, 38, 145, 6, 1, 241, 171, 38, 145, 6, 1, 250, 242, + 38, 145, 6, 1, 241, 169, 38, 145, 6, 1, 241, 89, 38, 145, 6, 1, 241, 166, + 38, 145, 6, 1, 241, 165, 38, 145, 6, 1, 250, 226, 38, 145, 6, 1, 74, 38, + 145, 6, 1, 246, 17, 74, 38, 145, 6, 1, 241, 161, 38, 145, 6, 1, 241, 154, + 38, 145, 6, 1, 241, 153, 38, 145, 6, 1, 241, 150, 38, 145, 6, 1, 241, + 147, 38, 145, 6, 1, 75, 38, 145, 6, 1, 231, 83, 38, 145, 6, 1, 241, 132, + 38, 145, 6, 1, 241, 129, 38, 145, 6, 1, 251, 47, 38, 145, 6, 1, 206, 232, + 38, 145, 6, 1, 241, 122, 38, 145, 6, 1, 241, 105, 38, 145, 6, 1, 241, + 103, 38, 145, 6, 1, 241, 92, 38, 145, 6, 1, 241, 56, 38, 145, 6, 1, 78, + 38, 145, 6, 1, 220, 18, 38, 145, 6, 1, 222, 71, 220, 73, 38, 145, 6, 1, + 215, 141, 220, 73, 38, 145, 6, 1, 220, 72, 38, 145, 6, 1, 241, 46, 38, + 145, 6, 1, 241, 97, 38, 145, 6, 1, 241, 28, 38, 145, 6, 1, 212, 228, 241, + 28, 38, 145, 6, 1, 241, 17, 38, 145, 6, 1, 240, 252, 38, 145, 6, 1, 240, + 250, 38, 145, 6, 1, 241, 70, 38, 145, 6, 1, 240, 239, 38, 145, 6, 1, 241, + 167, 38, 145, 6, 1, 68, 38, 145, 6, 1, 206, 178, 38, 145, 6, 1, 222, 71, + 207, 24, 38, 145, 6, 1, 215, 141, 207, 24, 38, 145, 6, 1, 240, 226, 38, + 145, 6, 1, 240, 181, 38, 145, 6, 1, 240, 176, 38, 145, 6, 1, 241, 69, 54, + 38, 145, 6, 1, 206, 193, 38, 145, 5, 1, 63, 38, 145, 5, 1, 252, 25, 38, + 145, 5, 1, 241, 171, 38, 145, 5, 1, 250, 242, 38, 145, 5, 1, 241, 169, + 38, 145, 5, 1, 241, 89, 38, 145, 5, 1, 241, 166, 38, 145, 5, 1, 241, 165, + 38, 145, 5, 1, 250, 226, 38, 145, 5, 1, 74, 38, 145, 5, 1, 246, 17, 74, + 38, 145, 5, 1, 241, 161, 38, 145, 5, 1, 241, 154, 38, 145, 5, 1, 241, + 153, 38, 145, 5, 1, 241, 150, 38, 145, 5, 1, 241, 147, 38, 145, 5, 1, 75, + 38, 145, 5, 1, 231, 83, 38, 145, 5, 1, 241, 132, 38, 145, 5, 1, 241, 129, + 38, 145, 5, 1, 251, 47, 38, 145, 5, 1, 206, 232, 38, 145, 5, 1, 241, 122, + 38, 145, 5, 1, 241, 105, 38, 145, 5, 1, 241, 103, 38, 145, 5, 1, 241, 92, + 38, 145, 5, 1, 241, 56, 38, 145, 5, 1, 78, 38, 145, 5, 1, 220, 18, 38, + 145, 5, 1, 222, 71, 220, 73, 38, 145, 5, 1, 215, 141, 220, 73, 38, 145, + 5, 1, 220, 72, 38, 145, 5, 1, 241, 46, 38, 145, 5, 1, 241, 97, 38, 145, + 5, 1, 241, 28, 38, 145, 5, 1, 212, 228, 241, 28, 38, 145, 5, 1, 241, 17, + 38, 145, 5, 1, 240, 252, 38, 145, 5, 1, 240, 250, 38, 145, 5, 1, 241, 70, + 38, 145, 5, 1, 240, 239, 38, 145, 5, 1, 241, 167, 38, 145, 5, 1, 68, 38, + 145, 5, 1, 206, 178, 38, 145, 5, 1, 222, 71, 207, 24, 38, 145, 5, 1, 215, + 141, 207, 24, 38, 145, 5, 1, 240, 226, 38, 145, 5, 1, 240, 181, 38, 145, + 5, 1, 240, 176, 38, 145, 5, 1, 241, 69, 54, 38, 145, 5, 1, 206, 193, 38, + 145, 42, 105, 38, 145, 42, 170, 38, 145, 42, 209, 152, 38, 145, 42, 240, + 18, 38, 145, 42, 118, 236, 11, 38, 145, 42, 118, 209, 36, 215, 129, 17, + 105, 215, 129, 17, 108, 215, 129, 17, 147, 215, 129, 17, 149, 215, 129, + 17, 170, 215, 129, 17, 195, 215, 129, 17, 213, 111, 215, 129, 17, 199, + 215, 129, 17, 222, 63, 215, 129, 42, 209, 152, 215, 129, 42, 207, 151, + 215, 129, 42, 209, 53, 215, 129, 42, 239, 153, 215, 129, 42, 240, 18, + 215, 129, 42, 212, 74, 215, 129, 42, 213, 105, 215, 129, 42, 241, 134, + 215, 129, 42, 222, 58, 215, 129, 42, 118, 236, 11, 215, 129, 42, 120, + 236, 11, 215, 129, 42, 126, 236, 11, 215, 129, 42, 239, 147, 236, 11, + 215, 129, 42, 239, 233, 236, 11, 215, 129, 42, 212, 88, 236, 11, 215, + 129, 42, 213, 112, 236, 11, 215, 129, 42, 241, 143, 236, 11, 215, 129, + 42, 222, 64, 236, 11, 215, 129, 239, 138, 118, 237, 137, 215, 129, 239, + 138, 118, 217, 55, 215, 129, 239, 138, 118, 209, 60, 215, 129, 239, 138, + 120, 209, 57, 144, 2, 247, 52, 144, 2, 250, 180, 144, 2, 205, 199, 144, + 2, 230, 135, 144, 2, 206, 222, 144, 1, 63, 144, 1, 252, 25, 144, 1, 75, + 144, 1, 231, 83, 144, 1, 68, 144, 1, 206, 178, 144, 1, 125, 146, 144, 1, + 125, 215, 186, 144, 1, 125, 159, 144, 1, 125, 227, 78, 144, 1, 74, 144, + 1, 251, 64, 144, 1, 78, 144, 1, 250, 34, 144, 1, 173, 144, 1, 229, 144, + 144, 1, 239, 8, 144, 1, 238, 119, 144, 1, 222, 203, 144, 1, 247, 92, 144, + 1, 246, 199, 144, 1, 230, 181, 144, 1, 230, 149, 144, 1, 221, 11, 144, 1, + 207, 241, 144, 1, 207, 229, 144, 1, 244, 120, 144, 1, 244, 104, 144, 1, + 221, 227, 144, 1, 210, 22, 144, 1, 209, 108, 144, 1, 244, 212, 144, 1, + 244, 1, 144, 1, 201, 201, 144, 1, 185, 144, 1, 218, 208, 144, 1, 249, 32, + 144, 1, 248, 98, 144, 1, 192, 144, 1, 198, 144, 1, 216, 220, 144, 1, 228, + 113, 144, 1, 206, 86, 144, 1, 213, 90, 144, 1, 211, 164, 144, 1, 215, 36, + 144, 1, 152, 144, 1, 227, 77, 144, 1, 38, 44, 227, 68, 144, 1, 38, 44, + 215, 185, 144, 1, 38, 44, 221, 209, 144, 22, 2, 252, 25, 144, 22, 2, 248, + 95, 252, 25, 144, 22, 2, 75, 144, 22, 2, 231, 83, 144, 22, 2, 68, 144, + 22, 2, 206, 178, 144, 22, 2, 125, 146, 144, 22, 2, 125, 215, 186, 144, + 22, 2, 125, 159, 144, 22, 2, 125, 227, 78, 144, 22, 2, 74, 144, 22, 2, + 251, 64, 144, 22, 2, 78, 144, 22, 2, 250, 34, 144, 205, 204, 144, 244, + 166, 144, 52, 244, 166, 144, 217, 179, 243, 85, 144, 217, 179, 52, 243, + 85, 144, 217, 179, 227, 114, 144, 217, 179, 245, 139, 142, 144, 217, 179, + 227, 5, 144, 42, 105, 144, 42, 108, 144, 42, 147, 144, 42, 149, 144, 42, + 170, 144, 42, 195, 144, 42, 213, 111, 144, 42, 199, 144, 42, 222, 63, + 144, 42, 209, 152, 144, 42, 207, 151, 144, 42, 209, 53, 144, 42, 239, + 153, 144, 42, 240, 18, 144, 42, 212, 74, 144, 42, 213, 105, 144, 42, 241, + 134, 144, 42, 222, 58, 144, 42, 118, 236, 11, 144, 42, 118, 209, 36, 144, + 17, 202, 84, 144, 17, 105, 144, 17, 108, 144, 17, 147, 144, 17, 149, 144, + 17, 170, 144, 17, 195, 144, 17, 213, 111, 144, 17, 199, 144, 17, 222, 63, + 144, 42, 230, 96, 230, 15, 2, 247, 52, 230, 15, 2, 250, 180, 230, 15, 2, + 205, 199, 230, 15, 1, 63, 230, 15, 1, 252, 25, 230, 15, 1, 75, 230, 15, + 1, 231, 83, 230, 15, 1, 68, 230, 15, 1, 206, 178, 230, 15, 1, 74, 230, + 15, 1, 251, 64, 230, 15, 1, 78, 230, 15, 1, 250, 34, 230, 15, 1, 173, + 230, 15, 1, 229, 144, 230, 15, 1, 239, 8, 230, 15, 1, 238, 119, 230, 15, + 1, 222, 203, 230, 15, 1, 247, 92, 230, 15, 1, 246, 199, 230, 15, 1, 230, + 181, 230, 15, 1, 230, 149, 230, 15, 1, 221, 11, 230, 15, 1, 207, 241, + 230, 15, 1, 207, 229, 230, 15, 1, 244, 120, 230, 15, 1, 244, 109, 230, + 15, 1, 244, 104, 230, 15, 1, 216, 61, 230, 15, 1, 221, 227, 230, 15, 1, + 210, 22, 230, 15, 1, 209, 108, 230, 15, 1, 244, 212, 230, 15, 1, 244, 1, + 230, 15, 1, 201, 201, 230, 15, 1, 185, 230, 15, 1, 218, 208, 230, 15, 1, + 249, 32, 230, 15, 1, 248, 98, 230, 15, 1, 192, 230, 15, 1, 198, 230, 15, + 1, 216, 220, 230, 15, 1, 228, 113, 230, 15, 1, 206, 86, 230, 15, 1, 213, + 90, 230, 15, 1, 211, 164, 230, 15, 1, 215, 36, 230, 15, 1, 152, 230, 15, + 22, 2, 252, 25, 230, 15, 22, 2, 75, 230, 15, 22, 2, 231, 83, 230, 15, 22, + 2, 68, 230, 15, 22, 2, 206, 178, 230, 15, 22, 2, 74, 230, 15, 22, 2, 251, + 64, 230, 15, 22, 2, 78, 230, 15, 22, 2, 250, 34, 230, 15, 2, 205, 204, + 230, 15, 2, 221, 51, 230, 15, 251, 146, 54, 230, 15, 241, 59, 54, 230, + 15, 42, 54, 230, 15, 214, 168, 82, 230, 15, 52, 214, 168, 82, 230, 15, + 244, 166, 230, 15, 52, 244, 166, 211, 246, 211, 254, 1, 215, 19, 211, + 246, 211, 254, 1, 209, 251, 211, 246, 211, 254, 1, 249, 5, 211, 246, 211, + 254, 1, 247, 81, 211, 246, 211, 254, 1, 244, 193, 211, 246, 211, 254, 1, + 238, 249, 211, 246, 211, 254, 1, 225, 148, 211, 246, 211, 254, 1, 222, + 200, 211, 246, 211, 254, 1, 228, 89, 211, 246, 211, 254, 1, 223, 93, 211, + 246, 211, 254, 1, 206, 82, 211, 246, 211, 254, 1, 219, 150, 211, 246, + 211, 254, 1, 203, 91, 211, 246, 211, 254, 1, 216, 199, 211, 246, 211, + 254, 1, 237, 148, 211, 246, 211, 254, 1, 230, 20, 211, 246, 211, 254, 1, + 230, 175, 211, 246, 211, 254, 1, 221, 8, 211, 246, 211, 254, 1, 251, 73, + 211, 246, 211, 254, 1, 241, 159, 211, 246, 211, 254, 1, 231, 84, 211, + 246, 211, 254, 1, 207, 18, 211, 246, 211, 254, 1, 220, 60, 211, 246, 211, + 254, 1, 241, 147, 211, 246, 211, 254, 1, 225, 161, 211, 246, 211, 254, + 17, 202, 84, 211, 246, 211, 254, 17, 105, 211, 246, 211, 254, 17, 108, + 211, 246, 211, 254, 17, 147, 211, 246, 211, 254, 17, 149, 211, 246, 211, + 254, 17, 170, 211, 246, 211, 254, 17, 195, 211, 246, 211, 254, 17, 213, + 111, 211, 246, 211, 254, 17, 199, 211, 246, 211, 254, 17, 222, 63, 246, + 193, 2, 247, 52, 246, 193, 2, 250, 180, 246, 193, 2, 205, 199, 246, 193, + 1, 252, 25, 246, 193, 1, 75, 246, 193, 1, 68, 246, 193, 1, 74, 246, 193, + 1, 230, 41, 246, 193, 1, 229, 143, 246, 193, 1, 239, 5, 246, 193, 1, 238, + 118, 246, 193, 1, 222, 202, 246, 193, 1, 247, 91, 246, 193, 1, 246, 198, + 246, 193, 1, 230, 180, 246, 193, 1, 230, 148, 246, 193, 1, 221, 10, 246, + 193, 1, 207, 240, 246, 193, 1, 207, 228, 246, 193, 1, 244, 119, 246, 193, + 1, 244, 103, 246, 193, 1, 221, 226, 246, 193, 1, 210, 18, 246, 193, 1, + 209, 107, 246, 193, 1, 244, 211, 246, 193, 1, 244, 0, 246, 193, 1, 223, + 106, 246, 193, 1, 219, 168, 246, 193, 1, 218, 207, 246, 193, 1, 249, 30, + 246, 193, 1, 248, 97, 246, 193, 1, 225, 175, 246, 193, 1, 202, 167, 246, + 193, 1, 203, 110, 246, 193, 1, 216, 216, 246, 193, 1, 228, 112, 246, 193, + 1, 204, 110, 246, 193, 1, 215, 33, 246, 193, 1, 237, 157, 246, 193, 22, + 2, 63, 246, 193, 22, 2, 75, 246, 193, 22, 2, 231, 83, 246, 193, 22, 2, + 68, 246, 193, 22, 2, 206, 178, 246, 193, 22, 2, 74, 246, 193, 22, 2, 251, + 64, 246, 193, 22, 2, 78, 246, 193, 22, 2, 250, 34, 246, 193, 22, 2, 220, + 57, 246, 193, 158, 82, 246, 193, 250, 35, 82, 246, 193, 205, 204, 246, + 193, 225, 173, 246, 193, 17, 202, 84, 246, 193, 17, 105, 246, 193, 17, + 108, 246, 193, 17, 147, 246, 193, 17, 149, 246, 193, 17, 170, 246, 193, + 17, 195, 246, 193, 17, 213, 111, 246, 193, 17, 199, 246, 193, 17, 222, + 63, 246, 193, 214, 168, 82, 246, 193, 244, 166, 246, 193, 52, 244, 166, + 246, 193, 217, 47, 82, 225, 146, 1, 63, 225, 146, 1, 75, 225, 146, 1, 68, + 225, 146, 1, 74, 225, 146, 1, 78, 225, 146, 1, 173, 225, 146, 1, 229, + 144, 225, 146, 1, 239, 8, 225, 146, 1, 238, 119, 225, 146, 1, 247, 92, + 225, 146, 1, 246, 199, 225, 146, 1, 230, 181, 225, 146, 1, 230, 149, 225, + 146, 1, 221, 11, 225, 146, 1, 207, 241, 225, 146, 1, 207, 229, 225, 146, + 1, 244, 120, 225, 146, 1, 244, 104, 225, 146, 1, 221, 227, 225, 146, 1, + 210, 22, 225, 146, 1, 209, 108, 225, 146, 1, 244, 212, 225, 146, 1, 244, + 1, 225, 146, 1, 201, 201, 225, 146, 1, 185, 225, 146, 1, 218, 208, 225, + 146, 1, 249, 32, 225, 146, 1, 248, 98, 225, 146, 1, 192, 225, 146, 1, + 216, 220, 225, 146, 1, 228, 113, 225, 146, 1, 206, 86, 225, 146, 1, 215, + 36, 225, 146, 1, 152, 225, 146, 1, 215, 185, 225, 146, 2, 221, 51, 225, + 146, 251, 146, 54, 225, 146, 214, 168, 82, 225, 146, 32, 212, 206, 181, + 2, 247, 52, 181, 2, 250, 180, 181, 2, 205, 199, 181, 1, 63, 181, 1, 252, + 25, 181, 1, 75, 181, 1, 231, 83, 181, 1, 68, 181, 1, 206, 178, 181, 1, + 125, 146, 181, 1, 125, 215, 186, 181, 1, 125, 159, 181, 1, 125, 227, 78, + 181, 1, 74, 181, 1, 251, 64, 181, 1, 78, 181, 1, 250, 34, 181, 1, 173, + 181, 1, 229, 144, 181, 1, 239, 8, 181, 1, 238, 119, 181, 1, 222, 203, + 181, 1, 247, 92, 181, 1, 246, 199, 181, 1, 230, 181, 181, 1, 230, 149, + 181, 1, 221, 11, 181, 1, 207, 241, 181, 1, 207, 229, 181, 1, 244, 120, + 181, 1, 244, 104, 181, 1, 221, 227, 181, 1, 210, 22, 181, 1, 209, 108, + 181, 1, 244, 212, 181, 1, 244, 1, 181, 1, 201, 201, 181, 1, 185, 181, 1, + 218, 208, 181, 1, 249, 32, 181, 1, 248, 98, 181, 1, 192, 181, 1, 198, + 181, 1, 216, 220, 181, 1, 228, 113, 181, 1, 227, 77, 181, 1, 206, 86, + 181, 1, 213, 90, 181, 1, 211, 164, 181, 1, 215, 36, 181, 1, 152, 181, 22, + 2, 252, 25, 181, 22, 2, 75, 181, 22, 2, 231, 83, 181, 22, 2, 68, 181, 22, + 2, 206, 178, 181, 22, 2, 125, 146, 181, 22, 2, 125, 215, 186, 181, 22, 2, + 125, 159, 181, 22, 2, 125, 227, 78, 181, 22, 2, 74, 181, 22, 2, 251, 64, + 181, 22, 2, 78, 181, 22, 2, 250, 34, 181, 2, 205, 204, 181, 2, 250, 17, + 181, 2, 230, 135, 181, 2, 206, 222, 181, 220, 39, 181, 244, 166, 181, 52, + 244, 166, 181, 251, 146, 54, 181, 213, 130, 181, 214, 239, 82, 181, 2, + 221, 51, 181, 22, 65, 82, 181, 240, 199, 212, 228, 22, 82, 181, 210, 180, + 82, 181, 17, 202, 84, 181, 17, 105, 181, 17, 108, 181, 17, 147, 181, 17, + 149, 181, 17, 170, 181, 17, 195, 181, 17, 213, 111, 181, 17, 199, 181, + 17, 222, 63, 181, 241, 128, 181, 2, 212, 157, 181, 237, 58, 181, 245, + 191, 54, 181, 214, 168, 225, 92, 181, 214, 168, 225, 91, 140, 250, 126, + 17, 105, 140, 250, 126, 17, 108, 140, 250, 126, 17, 147, 140, 250, 126, + 17, 149, 140, 250, 126, 17, 170, 140, 250, 126, 17, 195, 140, 250, 126, + 17, 213, 111, 140, 250, 126, 17, 199, 140, 250, 126, 17, 222, 63, 140, + 250, 126, 42, 209, 152, 140, 250, 126, 42, 207, 151, 140, 250, 126, 42, + 209, 53, 140, 250, 126, 42, 239, 153, 140, 250, 126, 42, 240, 18, 140, + 250, 126, 42, 212, 74, 140, 250, 126, 42, 213, 105, 140, 250, 126, 42, + 241, 134, 140, 250, 126, 42, 222, 58, 140, 250, 126, 42, 118, 236, 11, + 140, 250, 126, 42, 118, 209, 36, 229, 114, 1, 63, 229, 114, 1, 252, 25, + 229, 114, 1, 75, 229, 114, 1, 68, 229, 114, 1, 74, 229, 114, 1, 251, 64, + 229, 114, 1, 78, 229, 114, 1, 250, 34, 229, 114, 1, 173, 229, 114, 1, + 229, 144, 229, 114, 1, 239, 8, 229, 114, 1, 238, 155, 229, 114, 1, 238, + 119, 229, 114, 1, 222, 203, 229, 114, 1, 247, 92, 229, 114, 1, 246, 199, + 229, 114, 1, 230, 181, 229, 114, 1, 230, 129, 229, 114, 1, 221, 11, 229, + 114, 1, 207, 241, 229, 114, 1, 207, 229, 229, 114, 1, 244, 120, 229, 114, + 1, 244, 104, 229, 114, 1, 221, 227, 229, 114, 1, 210, 22, 229, 114, 1, + 209, 108, 229, 114, 1, 244, 212, 229, 114, 1, 244, 110, 229, 114, 1, 244, + 1, 229, 114, 1, 201, 201, 229, 114, 1, 185, 229, 114, 1, 218, 208, 229, + 114, 1, 249, 32, 229, 114, 1, 248, 198, 229, 114, 1, 248, 98, 229, 114, + 1, 192, 229, 114, 1, 198, 229, 114, 1, 216, 220, 229, 114, 1, 228, 113, + 229, 114, 1, 206, 86, 229, 114, 1, 215, 36, 229, 114, 1, 152, 229, 114, + 1, 227, 77, 229, 114, 22, 2, 252, 25, 229, 114, 22, 2, 75, 229, 114, 22, + 2, 231, 83, 229, 114, 22, 2, 68, 229, 114, 22, 2, 74, 229, 114, 22, 2, + 251, 64, 229, 114, 22, 2, 78, 229, 114, 22, 2, 250, 34, 229, 114, 2, 250, + 180, 229, 114, 2, 205, 204, 229, 114, 2, 221, 51, 229, 114, 2, 213, 80, + 229, 114, 244, 166, 229, 114, 52, 244, 166, 229, 114, 203, 238, 213, 130, + 229, 114, 214, 168, 82, 229, 114, 52, 214, 168, 82, 229, 114, 251, 146, + 54, 223, 230, 1, 63, 223, 230, 1, 75, 223, 230, 1, 68, 223, 230, 1, 74, + 223, 230, 1, 173, 223, 230, 1, 229, 144, 223, 230, 1, 239, 8, 223, 230, + 1, 238, 119, 223, 230, 1, 247, 92, 223, 230, 1, 246, 199, 223, 230, 1, + 230, 181, 223, 230, 1, 230, 129, 223, 230, 1, 221, 11, 223, 230, 1, 207, + 241, 223, 230, 1, 207, 229, 223, 230, 1, 244, 120, 223, 230, 1, 244, 110, + 223, 230, 1, 244, 104, 223, 230, 1, 221, 227, 223, 230, 1, 210, 22, 223, + 230, 1, 209, 108, 223, 230, 1, 244, 212, 223, 230, 1, 244, 1, 223, 230, + 1, 201, 201, 223, 230, 1, 185, 223, 230, 1, 218, 208, 223, 230, 1, 249, + 32, 223, 230, 1, 248, 98, 223, 230, 1, 192, 223, 230, 1, 198, 223, 230, + 1, 216, 220, 223, 230, 1, 228, 113, 223, 230, 1, 206, 86, 223, 230, 1, + 215, 36, 223, 230, 1, 152, 223, 230, 1, 215, 185, 223, 230, 1, 216, 61, + 223, 230, 214, 168, 82, 229, 106, 1, 63, 229, 106, 1, 252, 25, 229, 106, + 1, 75, 229, 106, 1, 231, 83, 229, 106, 1, 68, 229, 106, 1, 206, 178, 229, + 106, 1, 74, 229, 106, 1, 251, 64, 229, 106, 1, 78, 229, 106, 1, 250, 34, + 229, 106, 1, 173, 229, 106, 1, 229, 144, 229, 106, 1, 239, 8, 229, 106, + 1, 238, 155, 229, 106, 1, 238, 119, 229, 106, 1, 222, 203, 229, 106, 1, + 247, 92, 229, 106, 1, 246, 199, 229, 106, 1, 230, 181, 229, 106, 1, 230, + 129, 229, 106, 1, 230, 149, 229, 106, 1, 221, 11, 229, 106, 1, 207, 241, + 229, 106, 1, 207, 229, 229, 106, 1, 244, 120, 229, 106, 1, 244, 110, 229, + 106, 1, 215, 185, 229, 106, 1, 244, 104, 229, 106, 1, 221, 227, 229, 106, + 1, 210, 22, 229, 106, 1, 209, 108, 229, 106, 1, 244, 212, 229, 106, 1, + 244, 1, 229, 106, 1, 201, 201, 229, 106, 1, 185, 229, 106, 1, 218, 208, + 229, 106, 1, 249, 32, 229, 106, 1, 248, 198, 229, 106, 1, 248, 98, 229, + 106, 1, 192, 229, 106, 1, 198, 229, 106, 1, 216, 220, 229, 106, 1, 228, + 113, 229, 106, 1, 206, 86, 229, 106, 1, 213, 90, 229, 106, 1, 215, 36, + 229, 106, 1, 152, 229, 106, 2, 250, 180, 229, 106, 22, 2, 252, 25, 229, + 106, 22, 2, 75, 229, 106, 22, 2, 231, 83, 229, 106, 22, 2, 68, 229, 106, + 22, 2, 206, 178, 229, 106, 22, 2, 74, 229, 106, 22, 2, 251, 64, 229, 106, + 22, 2, 78, 229, 106, 22, 2, 250, 34, 229, 106, 2, 221, 51, 229, 106, 2, + 205, 204, 229, 106, 17, 202, 84, 229, 106, 17, 105, 229, 106, 17, 108, + 229, 106, 17, 147, 229, 106, 17, 149, 229, 106, 17, 170, 229, 106, 17, + 195, 229, 106, 17, 213, 111, 229, 106, 17, 199, 229, 106, 17, 222, 63, + 238, 6, 2, 39, 250, 181, 55, 238, 6, 2, 247, 52, 238, 6, 2, 250, 180, + 238, 6, 2, 205, 199, 238, 6, 1, 63, 238, 6, 1, 252, 25, 238, 6, 1, 75, + 238, 6, 1, 231, 83, 238, 6, 1, 68, 238, 6, 1, 206, 178, 238, 6, 1, 125, + 146, 238, 6, 1, 125, 159, 238, 6, 1, 241, 161, 238, 6, 1, 251, 64, 238, + 6, 1, 220, 18, 238, 6, 1, 250, 34, 238, 6, 1, 173, 238, 6, 1, 229, 144, + 238, 6, 1, 239, 8, 238, 6, 1, 238, 119, 238, 6, 1, 222, 203, 238, 6, 1, + 247, 92, 238, 6, 1, 246, 199, 238, 6, 1, 230, 181, 238, 6, 1, 230, 149, + 238, 6, 1, 221, 11, 238, 6, 1, 207, 241, 238, 6, 1, 207, 229, 238, 6, 1, + 244, 120, 238, 6, 1, 244, 104, 238, 6, 1, 221, 227, 238, 6, 1, 210, 22, + 238, 6, 1, 209, 108, 238, 6, 1, 244, 212, 238, 6, 1, 244, 1, 238, 6, 1, + 201, 201, 238, 6, 1, 185, 238, 6, 1, 218, 208, 238, 6, 1, 249, 32, 238, + 6, 1, 248, 98, 238, 6, 1, 192, 238, 6, 1, 198, 238, 6, 1, 216, 220, 238, + 6, 1, 228, 113, 238, 6, 1, 227, 77, 238, 6, 1, 206, 86, 238, 6, 1, 213, + 90, 238, 6, 1, 211, 164, 238, 6, 1, 215, 36, 238, 6, 1, 152, 238, 6, 2, + 221, 51, 238, 6, 2, 250, 17, 238, 6, 22, 2, 252, 25, 238, 6, 22, 2, 75, + 238, 6, 22, 2, 231, 83, 238, 6, 22, 2, 68, 238, 6, 22, 2, 206, 178, 238, + 6, 22, 2, 125, 146, 238, 6, 22, 2, 125, 215, 186, 238, 6, 22, 2, 241, + 161, 238, 6, 22, 2, 251, 64, 238, 6, 22, 2, 220, 18, 238, 6, 22, 2, 250, + 34, 238, 6, 2, 205, 204, 238, 6, 220, 39, 238, 6, 250, 35, 227, 196, 82, + 238, 6, 2, 218, 74, 238, 6, 1, 206, 52, 250, 180, 238, 6, 1, 206, 52, 52, + 250, 180, 238, 6, 1, 125, 215, 186, 238, 6, 1, 125, 227, 78, 238, 6, 22, + 2, 125, 159, 238, 6, 22, 2, 125, 227, 78, 39, 238, 6, 17, 202, 84, 39, + 238, 6, 17, 105, 39, 238, 6, 17, 108, 39, 238, 6, 17, 147, 39, 238, 6, + 17, 149, 39, 238, 6, 17, 170, 39, 238, 6, 17, 195, 39, 238, 6, 1, 63, 39, + 238, 6, 1, 173, 39, 238, 6, 1, 201, 201, 39, 238, 6, 1, 205, 230, 39, + 238, 6, 1, 185, 208, 204, 250, 209, 208, 204, 1, 63, 208, 204, 1, 252, + 25, 208, 204, 1, 75, 208, 204, 1, 231, 83, 208, 204, 1, 68, 208, 204, 1, + 206, 178, 208, 204, 1, 125, 146, 208, 204, 1, 125, 215, 186, 208, 204, 1, + 125, 159, 208, 204, 1, 125, 227, 78, 208, 204, 1, 74, 208, 204, 1, 251, + 64, 208, 204, 1, 78, 208, 204, 1, 250, 34, 208, 204, 1, 173, 208, 204, 1, + 229, 144, 208, 204, 1, 239, 8, 208, 204, 1, 238, 119, 208, 204, 1, 222, + 203, 208, 204, 1, 247, 92, 208, 204, 1, 246, 199, 208, 204, 1, 230, 181, + 208, 204, 1, 230, 149, 208, 204, 1, 221, 11, 208, 204, 1, 207, 241, 208, + 204, 1, 207, 229, 208, 204, 1, 244, 120, 208, 204, 1, 244, 104, 208, 204, + 1, 221, 227, 208, 204, 1, 210, 22, 208, 204, 1, 209, 108, 208, 204, 1, + 244, 212, 208, 204, 1, 244, 1, 208, 204, 1, 201, 201, 208, 204, 1, 185, + 208, 204, 1, 218, 208, 208, 204, 1, 249, 32, 208, 204, 1, 248, 98, 208, + 204, 1, 192, 208, 204, 1, 198, 208, 204, 1, 216, 220, 208, 204, 1, 228, + 113, 208, 204, 1, 206, 86, 208, 204, 1, 213, 90, 208, 204, 1, 211, 164, + 208, 204, 1, 215, 36, 208, 204, 1, 152, 208, 204, 22, 2, 252, 25, 208, + 204, 22, 2, 75, 208, 204, 22, 2, 231, 83, 208, 204, 22, 2, 68, 208, 204, + 22, 2, 206, 178, 208, 204, 22, 2, 125, 146, 208, 204, 22, 2, 125, 215, + 186, 208, 204, 22, 2, 125, 159, 208, 204, 22, 2, 125, 227, 78, 208, 204, + 22, 2, 74, 208, 204, 22, 2, 212, 228, 74, 208, 204, 22, 2, 251, 64, 208, + 204, 22, 2, 78, 208, 204, 22, 2, 212, 228, 78, 208, 204, 22, 2, 250, 34, + 208, 204, 2, 247, 52, 208, 204, 2, 250, 180, 208, 204, 2, 205, 199, 208, + 204, 2, 205, 204, 208, 204, 2, 221, 51, 208, 204, 2, 250, 17, 208, 204, + 237, 191, 208, 204, 251, 146, 54, 208, 204, 220, 39, 208, 204, 17, 202, + 84, 208, 204, 17, 105, 208, 204, 17, 108, 208, 204, 17, 147, 208, 204, + 17, 149, 208, 204, 17, 170, 208, 204, 17, 195, 208, 204, 17, 213, 111, + 208, 204, 17, 199, 208, 204, 17, 222, 63, 186, 1, 63, 186, 1, 252, 25, + 186, 1, 75, 186, 1, 231, 83, 186, 1, 68, 186, 1, 206, 178, 186, 1, 125, + 146, 186, 1, 125, 215, 186, 186, 1, 125, 159, 186, 1, 125, 227, 78, 186, + 1, 74, 186, 1, 251, 64, 186, 1, 78, 186, 1, 250, 34, 186, 1, 173, 186, 1, + 229, 144, 186, 1, 239, 8, 186, 1, 238, 119, 186, 1, 222, 203, 186, 1, + 247, 92, 186, 1, 246, 199, 186, 1, 230, 181, 186, 1, 230, 149, 186, 1, + 221, 11, 186, 1, 207, 241, 186, 1, 207, 229, 186, 1, 244, 120, 186, 1, + 244, 104, 186, 1, 221, 227, 186, 1, 210, 22, 186, 1, 209, 108, 186, 1, + 244, 212, 186, 1, 244, 1, 186, 1, 201, 201, 186, 1, 185, 186, 1, 218, + 208, 186, 1, 249, 32, 186, 1, 248, 98, 186, 1, 192, 186, 1, 198, 186, 1, + 216, 220, 186, 1, 228, 113, 186, 1, 206, 86, 186, 1, 213, 90, 186, 1, + 211, 164, 186, 1, 215, 36, 186, 1, 152, 186, 22, 2, 252, 25, 186, 22, 2, + 75, 186, 22, 2, 231, 83, 186, 22, 2, 68, 186, 22, 2, 206, 178, 186, 22, + 2, 125, 146, 186, 22, 2, 125, 215, 186, 186, 22, 2, 74, 186, 22, 2, 251, + 64, 186, 22, 2, 78, 186, 22, 2, 250, 34, 186, 2, 247, 52, 186, 2, 250, + 180, 186, 2, 205, 199, 186, 2, 205, 204, 186, 2, 221, 51, 186, 2, 212, + 157, 186, 244, 166, 186, 52, 244, 166, 186, 213, 131, 243, 85, 186, 213, + 131, 142, 186, 216, 98, 225, 92, 186, 216, 98, 225, 91, 186, 216, 98, + 225, 90, 186, 241, 84, 76, 209, 113, 82, 186, 214, 168, 131, 3, 208, 80, + 25, 207, 92, 219, 232, 186, 214, 168, 131, 3, 208, 80, 25, 242, 83, 245, + 137, 186, 214, 168, 131, 3, 216, 163, 25, 242, 83, 245, 137, 186, 214, + 168, 131, 3, 216, 163, 25, 242, 83, 52, 245, 137, 186, 214, 168, 131, 3, + 216, 163, 25, 242, 83, 208, 70, 245, 137, 186, 214, 168, 131, 52, 215, + 252, 186, 214, 168, 131, 52, 215, 253, 3, 216, 162, 186, 214, 168, 131, + 3, 52, 245, 137, 186, 214, 168, 131, 3, 208, 70, 245, 137, 186, 214, 168, + 131, 3, 217, 58, 245, 137, 186, 214, 168, 131, 3, 213, 128, 245, 137, + 186, 214, 168, 131, 3, 246, 59, 25, 216, 162, 186, 214, 168, 131, 3, 246, + 59, 25, 120, 241, 86, 186, 214, 168, 131, 3, 246, 59, 25, 239, 147, 241, + 86, 186, 1, 209, 32, 250, 255, 75, 186, 1, 207, 136, 250, 255, 75, 186, + 1, 207, 136, 250, 255, 231, 83, 186, 1, 250, 255, 68, 186, 22, 2, 250, + 255, 68, 186, 22, 2, 250, 255, 206, 178, 224, 74, 1, 63, 224, 74, 1, 252, + 25, 224, 74, 1, 75, 224, 74, 1, 231, 83, 224, 74, 1, 68, 224, 74, 1, 206, + 178, 224, 74, 1, 125, 146, 224, 74, 1, 125, 215, 186, 224, 74, 1, 125, + 159, 224, 74, 1, 125, 227, 78, 224, 74, 1, 74, 224, 74, 1, 251, 64, 224, + 74, 1, 78, 224, 74, 1, 250, 34, 224, 74, 1, 173, 224, 74, 1, 229, 144, + 224, 74, 1, 239, 8, 224, 74, 1, 238, 119, 224, 74, 1, 222, 203, 224, 74, + 1, 247, 92, 224, 74, 1, 246, 199, 224, 74, 1, 230, 181, 224, 74, 1, 230, + 149, 224, 74, 1, 221, 11, 224, 74, 1, 207, 241, 224, 74, 1, 207, 229, + 224, 74, 1, 244, 120, 224, 74, 1, 244, 104, 224, 74, 1, 221, 227, 224, + 74, 1, 210, 22, 224, 74, 1, 209, 108, 224, 74, 1, 244, 212, 224, 74, 1, + 244, 1, 224, 74, 1, 201, 201, 224, 74, 1, 185, 224, 74, 1, 218, 208, 224, + 74, 1, 249, 32, 224, 74, 1, 248, 98, 224, 74, 1, 192, 224, 74, 1, 198, + 224, 74, 1, 216, 220, 224, 74, 1, 228, 113, 224, 74, 1, 206, 86, 224, 74, + 1, 213, 90, 224, 74, 1, 211, 164, 224, 74, 1, 215, 36, 224, 74, 1, 152, + 224, 74, 1, 227, 77, 224, 74, 22, 2, 252, 25, 224, 74, 22, 2, 75, 224, + 74, 22, 2, 231, 83, 224, 74, 22, 2, 68, 224, 74, 22, 2, 206, 178, 224, + 74, 22, 2, 125, 146, 224, 74, 22, 2, 125, 215, 186, 224, 74, 22, 2, 125, + 159, 224, 74, 22, 2, 125, 227, 78, 224, 74, 22, 2, 74, 224, 74, 22, 2, + 251, 64, 224, 74, 22, 2, 78, 224, 74, 22, 2, 250, 34, 224, 74, 2, 250, + 180, 224, 74, 2, 205, 199, 224, 74, 2, 205, 204, 224, 74, 2, 250, 123, + 224, 74, 244, 166, 224, 74, 52, 244, 166, 224, 74, 251, 146, 54, 224, 74, + 2, 236, 0, 224, 74, 17, 202, 84, 224, 74, 17, 105, 224, 74, 17, 108, 224, + 74, 17, 147, 224, 74, 17, 149, 224, 74, 17, 170, 224, 74, 17, 195, 224, + 74, 17, 213, 111, 224, 74, 17, 199, 224, 74, 17, 222, 63, 209, 239, 1, + 63, 209, 239, 1, 252, 25, 209, 239, 1, 75, 209, 239, 1, 231, 83, 209, + 239, 1, 68, 209, 239, 1, 206, 178, 209, 239, 1, 74, 209, 239, 1, 251, 64, + 209, 239, 1, 78, 209, 239, 1, 250, 34, 209, 239, 1, 173, 209, 239, 1, + 229, 144, 209, 239, 1, 239, 8, 209, 239, 1, 238, 119, 209, 239, 1, 222, + 203, 209, 239, 1, 247, 92, 209, 239, 1, 246, 199, 209, 239, 1, 230, 181, + 209, 239, 1, 230, 149, 209, 239, 1, 221, 11, 209, 239, 1, 207, 241, 209, + 239, 1, 207, 229, 209, 239, 1, 244, 120, 209, 239, 1, 244, 104, 209, 239, + 1, 221, 227, 209, 239, 1, 210, 22, 209, 239, 1, 209, 108, 209, 239, 1, + 244, 212, 209, 239, 1, 244, 1, 209, 239, 1, 201, 201, 209, 239, 1, 185, + 209, 239, 1, 218, 208, 209, 239, 1, 249, 32, 209, 239, 1, 248, 98, 209, + 239, 1, 192, 209, 239, 1, 198, 209, 239, 1, 216, 220, 209, 239, 1, 228, + 113, 209, 239, 1, 206, 86, 209, 239, 1, 213, 90, 209, 239, 1, 215, 36, + 209, 239, 1, 152, 209, 239, 1, 215, 185, 209, 239, 2, 250, 180, 209, 239, + 2, 205, 199, 209, 239, 22, 2, 252, 25, 209, 239, 22, 2, 75, 209, 239, 22, + 2, 231, 83, 209, 239, 22, 2, 68, 209, 239, 22, 2, 206, 178, 209, 239, 22, + 2, 74, 209, 239, 22, 2, 251, 64, 209, 239, 22, 2, 78, 209, 239, 22, 2, + 250, 34, 209, 239, 2, 205, 204, 209, 239, 2, 221, 51, 209, 239, 17, 202, + 84, 209, 239, 17, 105, 209, 239, 17, 108, 209, 239, 17, 147, 209, 239, + 17, 149, 209, 239, 17, 170, 209, 239, 17, 195, 209, 239, 17, 213, 111, + 209, 239, 17, 199, 209, 239, 17, 222, 63, 251, 68, 1, 173, 251, 68, 1, + 229, 144, 251, 68, 1, 222, 203, 251, 68, 1, 201, 201, 251, 68, 1, 210, + 22, 251, 68, 1, 250, 255, 210, 22, 251, 68, 1, 185, 251, 68, 1, 218, 208, + 251, 68, 1, 249, 32, 251, 68, 1, 192, 251, 68, 1, 230, 181, 251, 68, 1, + 246, 199, 251, 68, 1, 209, 108, 251, 68, 1, 216, 220, 251, 68, 1, 228, + 113, 251, 68, 1, 215, 36, 251, 68, 1, 221, 11, 251, 68, 1, 152, 251, 68, + 1, 63, 251, 68, 1, 244, 212, 251, 68, 1, 244, 1, 251, 68, 1, 239, 8, 251, + 68, 1, 250, 255, 239, 8, 251, 68, 1, 238, 119, 251, 68, 1, 248, 98, 251, + 68, 1, 230, 149, 251, 68, 109, 2, 174, 228, 113, 251, 68, 109, 2, 174, + 216, 220, 251, 68, 109, 2, 174, 227, 135, 216, 220, 251, 68, 22, 2, 63, + 251, 68, 22, 2, 252, 25, 251, 68, 22, 2, 75, 251, 68, 22, 2, 231, 83, + 251, 68, 22, 2, 68, 251, 68, 22, 2, 206, 178, 251, 68, 22, 2, 74, 251, + 68, 22, 2, 250, 13, 251, 68, 22, 2, 78, 251, 68, 22, 2, 251, 64, 251, 68, + 22, 2, 250, 247, 251, 68, 2, 229, 86, 251, 68, 17, 202, 84, 251, 68, 17, + 105, 251, 68, 17, 108, 251, 68, 17, 147, 251, 68, 17, 149, 251, 68, 17, + 170, 251, 68, 17, 195, 251, 68, 17, 213, 111, 251, 68, 17, 199, 251, 68, + 17, 222, 63, 251, 68, 42, 209, 152, 251, 68, 42, 207, 151, 251, 68, 2, 5, + 214, 167, 251, 68, 2, 214, 167, 251, 68, 2, 215, 136, 251, 68, 16, 205, + 230, 204, 92, 246, 48, 6, 1, 222, 202, 204, 92, 246, 48, 6, 1, 63, 204, + 92, 246, 48, 6, 1, 204, 30, 204, 92, 246, 48, 6, 1, 202, 213, 204, 92, + 246, 48, 6, 1, 198, 204, 92, 246, 48, 6, 1, 202, 247, 204, 92, 246, 48, + 6, 1, 231, 83, 204, 92, 246, 48, 6, 1, 206, 178, 204, 92, 246, 48, 6, 1, + 74, 204, 92, 246, 48, 6, 1, 78, 204, 92, 246, 48, 6, 1, 250, 223, 204, + 92, 246, 48, 6, 1, 239, 8, 204, 92, 246, 48, 6, 1, 229, 26, 204, 92, 246, + 48, 6, 1, 241, 56, 204, 92, 246, 48, 6, 1, 202, 197, 204, 92, 246, 48, 6, + 1, 207, 31, 204, 92, 246, 48, 6, 1, 241, 75, 204, 92, 246, 48, 6, 1, 220, + 76, 204, 92, 246, 48, 6, 1, 207, 236, 204, 92, 246, 48, 6, 1, 221, 37, + 204, 92, 246, 48, 6, 1, 244, 212, 204, 92, 246, 48, 6, 1, 250, 49, 204, + 92, 246, 48, 6, 1, 250, 247, 204, 92, 246, 48, 6, 1, 247, 193, 204, 92, + 246, 48, 6, 1, 217, 191, 204, 92, 246, 48, 6, 1, 236, 228, 204, 92, 246, + 48, 6, 1, 236, 124, 204, 92, 246, 48, 6, 1, 236, 51, 204, 92, 246, 48, 6, + 1, 237, 92, 204, 92, 246, 48, 6, 1, 211, 116, 204, 92, 246, 48, 6, 1, + 212, 142, 204, 92, 246, 48, 6, 1, 205, 190, 204, 92, 246, 48, 5, 1, 222, + 202, 204, 92, 246, 48, 5, 1, 63, 204, 92, 246, 48, 5, 1, 204, 30, 204, + 92, 246, 48, 5, 1, 202, 213, 204, 92, 246, 48, 5, 1, 198, 204, 92, 246, + 48, 5, 1, 202, 247, 204, 92, 246, 48, 5, 1, 231, 83, 204, 92, 246, 48, 5, + 1, 206, 178, 204, 92, 246, 48, 5, 1, 74, 204, 92, 246, 48, 5, 1, 78, 204, + 92, 246, 48, 5, 1, 250, 223, 204, 92, 246, 48, 5, 1, 239, 8, 204, 92, + 246, 48, 5, 1, 229, 26, 204, 92, 246, 48, 5, 1, 241, 56, 204, 92, 246, + 48, 5, 1, 202, 197, 204, 92, 246, 48, 5, 1, 207, 31, 204, 92, 246, 48, 5, + 1, 241, 75, 204, 92, 246, 48, 5, 1, 220, 76, 204, 92, 246, 48, 5, 1, 207, + 236, 204, 92, 246, 48, 5, 1, 221, 37, 204, 92, 246, 48, 5, 1, 244, 212, + 204, 92, 246, 48, 5, 1, 250, 49, 204, 92, 246, 48, 5, 1, 250, 247, 204, + 92, 246, 48, 5, 1, 247, 193, 204, 92, 246, 48, 5, 1, 217, 191, 204, 92, + 246, 48, 5, 1, 236, 228, 204, 92, 246, 48, 5, 1, 236, 124, 204, 92, 246, + 48, 5, 1, 236, 51, 204, 92, 246, 48, 5, 1, 237, 92, 204, 92, 246, 48, 5, + 1, 211, 116, 204, 92, 246, 48, 5, 1, 212, 142, 204, 92, 246, 48, 5, 1, + 205, 190, 204, 92, 246, 48, 17, 202, 84, 204, 92, 246, 48, 17, 105, 204, + 92, 246, 48, 17, 108, 204, 92, 246, 48, 17, 147, 204, 92, 246, 48, 17, + 149, 204, 92, 246, 48, 17, 170, 204, 92, 246, 48, 17, 195, 204, 92, 246, + 48, 17, 213, 111, 204, 92, 246, 48, 17, 199, 204, 92, 246, 48, 17, 222, + 63, 204, 92, 246, 48, 42, 209, 152, 204, 92, 246, 48, 42, 207, 151, 204, + 92, 246, 48, 42, 209, 53, 204, 92, 246, 48, 42, 239, 153, 204, 92, 246, + 48, 42, 240, 18, 204, 92, 246, 48, 42, 212, 74, 204, 92, 246, 48, 42, + 213, 105, 204, 92, 246, 48, 42, 241, 134, 204, 92, 246, 48, 42, 222, 58, + 204, 92, 246, 48, 220, 39, 219, 49, 246, 66, 237, 77, 1, 185, 219, 49, + 246, 66, 237, 77, 1, 173, 219, 49, 246, 66, 237, 77, 1, 228, 113, 219, + 49, 246, 66, 237, 77, 1, 192, 219, 49, 246, 66, 237, 77, 1, 244, 212, + 219, 49, 246, 66, 237, 77, 1, 202, 116, 219, 49, 246, 66, 237, 77, 1, + 206, 86, 219, 49, 246, 66, 237, 77, 1, 222, 203, 219, 49, 246, 66, 237, + 77, 1, 152, 219, 49, 246, 66, 237, 77, 1, 239, 8, 219, 49, 246, 66, 237, + 77, 1, 229, 144, 219, 49, 246, 66, 237, 77, 1, 215, 36, 219, 49, 246, 66, + 237, 77, 1, 249, 32, 219, 49, 246, 66, 237, 77, 1, 247, 92, 219, 49, 246, + 66, 237, 77, 1, 210, 22, 219, 49, 246, 66, 237, 77, 1, 209, 108, 219, 49, + 246, 66, 237, 77, 1, 201, 201, 219, 49, 246, 66, 237, 77, 1, 218, 208, + 219, 49, 246, 66, 237, 77, 1, 216, 220, 219, 49, 246, 66, 237, 77, 1, + 240, 108, 219, 49, 246, 66, 237, 77, 1, 246, 199, 219, 49, 246, 66, 237, + 77, 1, 63, 219, 49, 246, 66, 237, 77, 1, 74, 219, 49, 246, 66, 237, 77, + 1, 75, 219, 49, 246, 66, 237, 77, 1, 78, 219, 49, 246, 66, 237, 77, 1, + 68, 219, 49, 246, 66, 237, 77, 1, 207, 39, 219, 49, 246, 66, 237, 77, 1, + 235, 171, 219, 49, 246, 66, 237, 77, 1, 46, 219, 184, 219, 49, 246, 66, + 237, 77, 1, 46, 230, 54, 219, 49, 246, 66, 237, 77, 1, 46, 210, 69, 219, + 49, 246, 66, 237, 77, 1, 46, 226, 185, 219, 49, 246, 66, 237, 77, 1, 46, + 223, 163, 219, 49, 246, 66, 237, 77, 1, 46, 159, 219, 49, 246, 66, 237, + 77, 1, 46, 204, 144, 219, 49, 246, 66, 237, 77, 1, 46, 222, 205, 219, 49, + 246, 66, 237, 77, 1, 46, 203, 124, 219, 49, 246, 66, 237, 77, 215, 245, + 143, 227, 28, 219, 49, 246, 66, 237, 77, 215, 245, 208, 161, 219, 49, + 246, 66, 237, 77, 214, 239, 238, 45, 211, 61, 219, 49, 246, 66, 237, 77, + 215, 245, 143, 163, 240, 5, 219, 49, 246, 66, 237, 77, 215, 245, 143, + 240, 5, 219, 49, 246, 66, 237, 77, 214, 239, 238, 45, 211, 62, 240, 5, + 219, 49, 246, 66, 237, 77, 214, 239, 143, 227, 28, 219, 49, 246, 66, 237, + 77, 214, 239, 208, 161, 219, 49, 246, 66, 237, 77, 214, 239, 143, 163, + 240, 5, 219, 49, 246, 66, 237, 77, 214, 239, 143, 240, 5, 219, 49, 246, + 66, 237, 77, 224, 149, 208, 161, 219, 49, 246, 66, 237, 77, 238, 45, 211, + 62, 206, 68, 219, 49, 246, 66, 237, 77, 224, 149, 143, 163, 240, 5, 219, + 49, 246, 66, 237, 77, 224, 149, 143, 240, 5, 219, 49, 246, 66, 237, 77, + 226, 254, 143, 227, 28, 219, 49, 246, 66, 237, 77, 226, 254, 208, 161, + 219, 49, 246, 66, 237, 77, 238, 45, 211, 61, 219, 49, 246, 66, 237, 77, + 226, 254, 143, 163, 240, 5, 219, 49, 246, 66, 237, 77, 226, 254, 143, + 240, 5, 219, 49, 246, 66, 237, 77, 238, 45, 211, 62, 240, 5, 9, 2, 63, 9, + 2, 34, 23, 63, 9, 2, 34, 23, 249, 15, 9, 2, 34, 23, 238, 233, 209, 141, + 9, 2, 34, 23, 152, 9, 2, 34, 23, 231, 85, 9, 2, 34, 23, 228, 93, 237, + 208, 9, 2, 34, 23, 223, 199, 9, 2, 34, 23, 215, 22, 9, 2, 254, 34, 9, 2, + 251, 232, 9, 2, 251, 233, 23, 250, 73, 9, 2, 251, 233, 23, 242, 30, 237, + 208, 9, 2, 251, 233, 23, 238, 246, 9, 2, 251, 233, 23, 238, 233, 209, + 141, 9, 2, 251, 233, 23, 152, 9, 2, 251, 233, 23, 231, 86, 237, 208, 9, + 2, 251, 233, 23, 231, 59, 9, 2, 251, 233, 23, 228, 94, 9, 2, 251, 233, + 23, 213, 27, 9, 2, 251, 233, 23, 106, 91, 106, 91, 68, 9, 2, 251, 233, + 237, 208, 9, 2, 251, 149, 9, 2, 251, 150, 23, 248, 252, 9, 2, 251, 150, + 23, 238, 233, 209, 141, 9, 2, 251, 150, 23, 225, 21, 91, 241, 92, 9, 2, + 251, 150, 23, 213, 88, 9, 2, 251, 150, 23, 209, 242, 9, 2, 251, 122, 9, + 2, 251, 47, 9, 2, 251, 48, 23, 241, 22, 9, 2, 251, 48, 23, 212, 245, 91, + 238, 55, 9, 2, 251, 39, 9, 2, 251, 40, 23, 251, 39, 9, 2, 251, 40, 23, + 243, 186, 9, 2, 251, 40, 23, 238, 55, 9, 2, 251, 40, 23, 152, 9, 2, 251, + 40, 23, 230, 27, 9, 2, 251, 40, 23, 229, 100, 9, 2, 251, 40, 23, 213, 43, + 9, 2, 251, 40, 23, 206, 186, 9, 2, 251, 36, 9, 2, 251, 28, 9, 2, 250, + 243, 9, 2, 250, 244, 23, 213, 43, 9, 2, 250, 231, 9, 2, 250, 232, 115, + 250, 231, 9, 2, 250, 232, 126, 208, 219, 9, 2, 250, 232, 91, 223, 97, + 219, 251, 250, 232, 91, 223, 96, 9, 2, 250, 232, 91, 223, 97, 211, 176, + 9, 2, 250, 200, 9, 2, 250, 170, 9, 2, 250, 138, 9, 2, 250, 139, 23, 228, + 183, 9, 2, 250, 110, 9, 2, 250, 80, 9, 2, 250, 75, 9, 2, 250, 76, 202, + 35, 209, 141, 9, 2, 250, 76, 230, 31, 209, 141, 9, 2, 250, 76, 115, 250, + 76, 207, 198, 115, 207, 198, 207, 198, 115, 207, 198, 219, 96, 9, 2, 250, + 76, 115, 250, 76, 115, 250, 75, 9, 2, 250, 76, 115, 250, 76, 115, 250, + 76, 245, 124, 250, 76, 115, 250, 76, 115, 250, 75, 9, 2, 250, 73, 9, 2, + 250, 69, 9, 2, 249, 32, 9, 2, 249, 15, 9, 2, 249, 9, 9, 2, 249, 3, 9, 2, + 248, 253, 9, 2, 248, 254, 115, 248, 253, 9, 2, 248, 252, 9, 2, 142, 9, 2, + 248, 230, 9, 2, 248, 86, 9, 2, 248, 87, 23, 63, 9, 2, 248, 87, 23, 238, + 224, 9, 2, 248, 87, 23, 231, 86, 237, 208, 9, 2, 247, 193, 9, 2, 247, + 194, 115, 247, 194, 251, 232, 9, 2, 247, 194, 115, 247, 194, 206, 255, 9, + 2, 247, 194, 245, 124, 247, 193, 9, 2, 247, 171, 9, 2, 247, 172, 115, + 247, 171, 9, 2, 247, 160, 9, 2, 247, 159, 9, 2, 244, 212, 9, 2, 244, 203, + 9, 2, 244, 204, 229, 69, 23, 34, 91, 225, 79, 9, 2, 244, 204, 229, 69, + 23, 250, 243, 9, 2, 244, 204, 229, 69, 23, 248, 252, 9, 2, 244, 204, 229, + 69, 23, 248, 86, 9, 2, 244, 204, 229, 69, 23, 239, 8, 9, 2, 244, 204, + 229, 69, 23, 239, 9, 91, 225, 79, 9, 2, 244, 204, 229, 69, 23, 238, 81, + 9, 2, 244, 204, 229, 69, 23, 238, 63, 9, 2, 244, 204, 229, 69, 23, 237, + 219, 9, 2, 244, 204, 229, 69, 23, 152, 9, 2, 244, 204, 229, 69, 23, 230, + 224, 9, 2, 244, 204, 229, 69, 23, 230, 225, 91, 226, 239, 9, 2, 244, 204, + 229, 69, 23, 230, 12, 9, 2, 244, 204, 229, 69, 23, 228, 113, 9, 2, 244, + 204, 229, 69, 23, 226, 239, 9, 2, 244, 204, 229, 69, 23, 226, 240, 91, + 225, 78, 9, 2, 244, 204, 229, 69, 23, 226, 222, 9, 2, 244, 204, 229, 69, + 23, 222, 240, 9, 2, 244, 204, 229, 69, 23, 219, 97, 91, 219, 96, 9, 2, + 244, 204, 229, 69, 23, 212, 162, 9, 2, 244, 204, 229, 69, 23, 209, 242, + 9, 2, 244, 204, 229, 69, 23, 207, 41, 91, 238, 63, 9, 2, 244, 204, 229, + 69, 23, 206, 186, 9, 2, 244, 175, 9, 2, 244, 154, 9, 2, 244, 153, 9, 2, + 244, 152, 9, 2, 243, 233, 9, 2, 243, 215, 9, 2, 243, 188, 9, 2, 243, 189, + 23, 213, 43, 9, 2, 243, 186, 9, 2, 243, 176, 9, 2, 243, 177, 229, 232, + 106, 237, 209, 243, 156, 9, 2, 243, 156, 9, 2, 242, 42, 9, 2, 242, 43, + 115, 242, 42, 9, 2, 242, 43, 237, 208, 9, 2, 242, 43, 213, 24, 9, 2, 242, + 40, 9, 2, 242, 41, 23, 241, 4, 9, 2, 242, 39, 9, 2, 242, 37, 9, 2, 242, + 36, 9, 2, 242, 35, 9, 2, 242, 31, 9, 2, 242, 29, 9, 2, 242, 30, 237, 208, + 9, 2, 242, 30, 237, 209, 237, 208, 9, 2, 242, 28, 9, 2, 242, 21, 9, 2, + 74, 9, 2, 188, 23, 219, 96, 9, 2, 188, 115, 188, 221, 41, 115, 221, 40, + 9, 2, 241, 190, 9, 2, 241, 191, 23, 34, 91, 237, 160, 91, 244, 212, 9, 2, + 241, 191, 23, 238, 224, 9, 2, 241, 191, 23, 224, 155, 9, 2, 241, 191, 23, + 215, 8, 9, 2, 241, 191, 23, 213, 43, 9, 2, 241, 191, 23, 68, 9, 2, 241, + 163, 9, 2, 241, 151, 9, 2, 241, 122, 9, 2, 241, 92, 9, 2, 241, 93, 23, + 238, 232, 9, 2, 241, 93, 23, 238, 233, 209, 141, 9, 2, 241, 93, 23, 225, + 20, 9, 2, 241, 93, 245, 124, 241, 92, 9, 2, 241, 93, 219, 251, 241, 92, + 9, 2, 241, 93, 211, 176, 9, 2, 241, 25, 9, 2, 241, 22, 9, 2, 241, 4, 9, + 2, 240, 179, 9, 2, 240, 180, 23, 63, 9, 2, 240, 180, 23, 34, 91, 228, 30, + 9, 2, 240, 180, 23, 34, 91, 228, 31, 23, 228, 30, 9, 2, 240, 180, 23, + 250, 231, 9, 2, 240, 180, 23, 249, 15, 9, 2, 240, 180, 23, 242, 30, 237, + 208, 9, 2, 240, 180, 23, 242, 30, 237, 209, 237, 208, 9, 2, 240, 180, 23, + 152, 9, 2, 240, 180, 23, 237, 160, 237, 208, 9, 2, 240, 180, 23, 231, 86, + 237, 208, 9, 2, 240, 180, 23, 229, 231, 9, 2, 240, 180, 23, 229, 232, + 211, 176, 9, 2, 240, 180, 23, 228, 207, 9, 2, 240, 180, 23, 228, 113, 9, + 2, 240, 180, 23, 228, 31, 23, 228, 30, 9, 2, 240, 180, 23, 227, 148, 9, + 2, 240, 180, 23, 226, 239, 9, 2, 240, 180, 23, 207, 40, 9, 2, 240, 180, + 23, 207, 29, 9, 2, 239, 8, 9, 2, 239, 9, 237, 208, 9, 2, 239, 6, 9, 2, + 239, 7, 23, 34, 91, 244, 213, 91, 152, 9, 2, 239, 7, 23, 34, 91, 152, 9, + 2, 239, 7, 23, 34, 91, 231, 85, 9, 2, 239, 7, 23, 251, 150, 209, 142, 91, + 210, 10, 9, 2, 239, 7, 23, 250, 231, 9, 2, 239, 7, 23, 250, 75, 9, 2, + 239, 7, 23, 250, 74, 91, 238, 246, 9, 2, 239, 7, 23, 249, 15, 9, 2, 239, + 7, 23, 248, 231, 91, 216, 220, 9, 2, 239, 7, 23, 247, 160, 9, 2, 239, 7, + 23, 247, 161, 91, 216, 220, 9, 2, 239, 7, 23, 244, 212, 9, 2, 239, 7, 23, + 243, 233, 9, 2, 239, 7, 23, 243, 189, 23, 213, 43, 9, 2, 239, 7, 23, 242, + 40, 9, 2, 239, 7, 23, 241, 122, 9, 2, 239, 7, 23, 241, 123, 91, 228, 113, + 9, 2, 239, 7, 23, 241, 92, 9, 2, 239, 7, 23, 241, 93, 23, 238, 233, 209, + 141, 9, 2, 239, 7, 23, 238, 233, 209, 141, 9, 2, 239, 7, 23, 238, 224, 9, + 2, 239, 7, 23, 238, 81, 9, 2, 239, 7, 23, 238, 79, 9, 2, 239, 7, 23, 238, + 80, 91, 63, 9, 2, 239, 7, 23, 238, 64, 91, 211, 10, 9, 2, 239, 7, 23, + 237, 160, 91, 226, 240, 91, 241, 4, 9, 2, 239, 7, 23, 237, 140, 9, 2, + 239, 7, 23, 237, 141, 91, 228, 113, 9, 2, 239, 7, 23, 237, 4, 91, 227, + 148, 9, 2, 239, 7, 23, 236, 21, 9, 2, 239, 7, 23, 231, 86, 237, 208, 9, + 2, 239, 7, 23, 230, 210, 91, 236, 27, 91, 250, 75, 9, 2, 239, 7, 23, 230, + 12, 9, 2, 239, 7, 23, 229, 231, 9, 2, 239, 7, 23, 229, 94, 9, 2, 239, 7, + 23, 229, 95, 91, 228, 30, 9, 2, 239, 7, 23, 228, 208, 91, 250, 231, 9, 2, + 239, 7, 23, 228, 113, 9, 2, 239, 7, 23, 225, 21, 91, 241, 92, 9, 2, 239, + 7, 23, 224, 155, 9, 2, 239, 7, 23, 221, 40, 9, 2, 239, 7, 23, 221, 41, + 115, 221, 40, 9, 2, 239, 7, 23, 185, 9, 2, 239, 7, 23, 215, 8, 9, 2, 239, + 7, 23, 214, 230, 9, 2, 239, 7, 23, 213, 43, 9, 2, 239, 7, 23, 213, 44, + 91, 207, 181, 9, 2, 239, 7, 23, 213, 9, 9, 2, 239, 7, 23, 210, 220, 9, 2, + 239, 7, 23, 209, 242, 9, 2, 239, 7, 23, 68, 9, 2, 239, 7, 23, 207, 29, 9, + 2, 239, 7, 23, 207, 30, 91, 242, 42, 9, 2, 239, 7, 115, 239, 6, 9, 2, + 239, 1, 9, 2, 239, 2, 245, 124, 239, 1, 9, 2, 238, 255, 9, 2, 239, 0, + 115, 239, 0, 238, 225, 115, 238, 224, 9, 2, 238, 246, 9, 2, 238, 247, + 239, 0, 115, 239, 0, 238, 225, 115, 238, 224, 9, 2, 238, 245, 9, 2, 238, + 243, 9, 2, 238, 234, 9, 2, 238, 232, 9, 2, 238, 233, 209, 141, 9, 2, 238, + 233, 115, 238, 232, 9, 2, 238, 233, 245, 124, 238, 232, 9, 2, 238, 224, + 9, 2, 238, 223, 9, 2, 238, 218, 9, 2, 238, 162, 9, 2, 238, 163, 23, 228, + 183, 9, 2, 238, 81, 9, 2, 238, 82, 23, 74, 9, 2, 238, 82, 23, 68, 9, 2, + 238, 82, 245, 124, 238, 81, 9, 2, 238, 79, 9, 2, 238, 80, 115, 238, 79, + 9, 2, 238, 80, 245, 124, 238, 79, 9, 2, 238, 76, 9, 2, 238, 63, 9, 2, + 238, 64, 237, 208, 9, 2, 238, 61, 9, 2, 238, 62, 23, 34, 91, 231, 85, 9, + 2, 238, 62, 23, 238, 233, 209, 141, 9, 2, 238, 62, 23, 231, 85, 9, 2, + 238, 62, 23, 226, 240, 91, 231, 85, 9, 2, 238, 62, 23, 185, 9, 2, 238, + 57, 9, 2, 238, 55, 9, 2, 238, 56, 245, 124, 238, 55, 9, 2, 238, 56, 23, + 249, 15, 9, 2, 238, 56, 23, 209, 242, 9, 2, 238, 56, 209, 141, 9, 2, 237, + 230, 9, 2, 237, 231, 245, 124, 237, 230, 9, 2, 237, 228, 9, 2, 237, 229, + 23, 230, 12, 9, 2, 237, 229, 23, 230, 13, 23, 231, 86, 237, 208, 9, 2, + 237, 229, 23, 221, 40, 9, 2, 237, 229, 23, 215, 9, 91, 207, 197, 9, 2, + 237, 229, 237, 208, 9, 2, 237, 219, 9, 2, 237, 220, 23, 34, 91, 228, 183, + 9, 2, 237, 220, 23, 228, 183, 9, 2, 237, 220, 115, 237, 220, 226, 230, 9, + 2, 237, 212, 9, 2, 237, 210, 9, 2, 237, 211, 23, 213, 43, 9, 2, 237, 202, + 9, 2, 237, 201, 9, 2, 237, 197, 9, 2, 237, 196, 9, 2, 152, 9, 2, 237, + 160, 209, 141, 9, 2, 237, 160, 237, 208, 9, 2, 237, 140, 9, 2, 237, 3, 9, + 2, 237, 4, 23, 250, 75, 9, 2, 237, 4, 23, 250, 73, 9, 2, 237, 4, 23, 249, + 15, 9, 2, 237, 4, 23, 243, 156, 9, 2, 237, 4, 23, 238, 255, 9, 2, 237, 4, + 23, 229, 84, 9, 2, 237, 4, 23, 221, 40, 9, 2, 237, 4, 23, 213, 43, 9, 2, + 237, 4, 23, 68, 9, 2, 236, 26, 9, 2, 236, 21, 9, 2, 236, 22, 23, 250, + 231, 9, 2, 236, 22, 23, 237, 140, 9, 2, 236, 22, 23, 229, 231, 9, 2, 236, + 22, 23, 227, 92, 9, 2, 236, 22, 23, 207, 29, 9, 2, 236, 17, 9, 2, 75, 9, + 2, 235, 206, 63, 9, 2, 235, 166, 9, 2, 231, 113, 9, 2, 231, 114, 115, + 231, 114, 247, 160, 9, 2, 231, 114, 115, 231, 114, 211, 176, 9, 2, 231, + 88, 9, 2, 231, 85, 9, 2, 231, 86, 243, 215, 9, 2, 231, 86, 216, 57, 9, 2, + 231, 86, 115, 231, 86, 212, 249, 115, 212, 249, 207, 30, 115, 207, 29, 9, + 2, 231, 86, 237, 208, 9, 2, 231, 77, 9, 2, 231, 78, 23, 238, 233, 209, + 141, 9, 2, 231, 76, 9, 2, 231, 66, 9, 2, 231, 67, 23, 209, 242, 9, 2, + 231, 67, 245, 124, 231, 66, 9, 2, 231, 67, 219, 251, 231, 66, 9, 2, 231, + 67, 211, 176, 9, 2, 231, 59, 9, 2, 231, 49, 9, 2, 230, 224, 9, 2, 230, + 209, 9, 2, 173, 9, 2, 230, 44, 23, 63, 9, 2, 230, 44, 23, 251, 122, 9, 2, + 230, 44, 23, 251, 123, 91, 228, 207, 9, 2, 230, 44, 23, 250, 73, 9, 2, + 230, 44, 23, 249, 15, 9, 2, 230, 44, 23, 248, 252, 9, 2, 230, 44, 23, + 142, 9, 2, 230, 44, 23, 248, 86, 9, 2, 230, 44, 23, 241, 22, 9, 2, 230, + 44, 23, 241, 4, 9, 2, 230, 44, 23, 239, 8, 9, 2, 230, 44, 23, 238, 246, + 9, 2, 230, 44, 23, 238, 233, 209, 141, 9, 2, 230, 44, 23, 238, 224, 9, 2, + 230, 44, 23, 238, 225, 91, 213, 89, 91, 63, 9, 2, 230, 44, 23, 238, 81, + 9, 2, 230, 44, 23, 238, 63, 9, 2, 230, 44, 23, 238, 56, 91, 214, 230, 9, + 2, 230, 44, 23, 238, 56, 245, 124, 238, 55, 9, 2, 230, 44, 23, 237, 230, + 9, 2, 230, 44, 23, 237, 201, 9, 2, 230, 44, 23, 231, 85, 9, 2, 230, 44, + 23, 231, 66, 9, 2, 230, 44, 23, 230, 12, 9, 2, 230, 44, 23, 229, 100, 9, + 2, 230, 44, 23, 229, 94, 9, 2, 230, 44, 23, 227, 148, 9, 2, 230, 44, 23, + 226, 239, 9, 2, 230, 44, 23, 225, 20, 9, 2, 230, 44, 23, 225, 21, 91, + 242, 42, 9, 2, 230, 44, 23, 225, 21, 91, 238, 81, 9, 2, 230, 44, 23, 225, + 21, 91, 209, 187, 9, 2, 230, 44, 23, 224, 155, 9, 2, 230, 44, 23, 224, + 156, 91, 221, 35, 9, 2, 230, 44, 23, 222, 240, 9, 2, 230, 44, 23, 221, + 40, 9, 2, 230, 44, 23, 218, 167, 9, 2, 230, 44, 23, 215, 145, 9, 2, 230, + 44, 23, 215, 36, 9, 2, 230, 44, 23, 214, 230, 9, 2, 230, 44, 23, 213, 90, + 9, 2, 230, 44, 23, 213, 43, 9, 2, 230, 44, 23, 213, 9, 9, 2, 230, 44, 23, + 212, 199, 9, 2, 230, 44, 23, 212, 149, 9, 2, 230, 44, 23, 210, 229, 9, 2, + 230, 44, 23, 209, 218, 9, 2, 230, 44, 23, 68, 9, 2, 230, 44, 23, 207, 40, + 9, 2, 230, 44, 23, 207, 29, 9, 2, 230, 44, 23, 207, 2, 23, 185, 9, 2, + 230, 44, 23, 206, 186, 9, 2, 230, 44, 23, 202, 39, 9, 2, 230, 42, 9, 2, + 230, 43, 245, 124, 230, 42, 9, 2, 230, 32, 9, 2, 230, 29, 9, 2, 230, 27, + 9, 2, 230, 26, 9, 2, 230, 24, 9, 2, 230, 25, 115, 230, 24, 9, 2, 230, 12, + 9, 2, 230, 13, 23, 231, 86, 237, 208, 9, 2, 230, 8, 9, 2, 230, 9, 23, + 249, 15, 9, 2, 230, 9, 245, 124, 230, 8, 9, 2, 230, 6, 9, 2, 230, 5, 9, + 2, 229, 231, 9, 2, 229, 232, 228, 95, 23, 106, 115, 228, 95, 23, 68, 9, + 2, 229, 232, 115, 229, 232, 228, 95, 23, 106, 115, 228, 95, 23, 68, 9, 2, + 229, 171, 9, 2, 229, 100, 9, 2, 229, 101, 23, 249, 15, 9, 2, 229, 101, + 23, 68, 9, 2, 229, 101, 23, 207, 29, 9, 2, 229, 94, 9, 2, 229, 84, 9, 2, + 229, 71, 9, 2, 229, 70, 9, 2, 229, 68, 9, 2, 229, 69, 115, 229, 68, 9, 2, + 228, 209, 9, 2, 228, 210, 115, 237, 4, 23, 250, 74, 228, 210, 115, 237, + 4, 23, 250, 73, 9, 2, 228, 207, 9, 2, 228, 205, 9, 2, 228, 206, 206, 69, + 18, 9, 2, 228, 204, 9, 2, 228, 196, 9, 2, 228, 197, 237, 208, 9, 2, 228, + 195, 9, 2, 228, 183, 9, 2, 228, 184, 219, 251, 228, 183, 9, 2, 228, 177, + 9, 2, 228, 155, 9, 2, 228, 113, 9, 2, 228, 94, 9, 2, 228, 95, 23, 63, 9, + 2, 228, 95, 23, 34, 91, 244, 213, 91, 152, 9, 2, 228, 95, 23, 34, 91, + 238, 224, 9, 2, 228, 95, 23, 34, 91, 228, 30, 9, 2, 228, 95, 23, 251, 39, + 9, 2, 228, 95, 23, 250, 231, 9, 2, 228, 95, 23, 250, 76, 202, 35, 209, + 141, 9, 2, 228, 95, 23, 249, 15, 9, 2, 228, 95, 23, 248, 86, 9, 2, 228, + 95, 23, 244, 154, 9, 2, 228, 95, 23, 241, 92, 9, 2, 228, 95, 23, 239, 8, + 9, 2, 228, 95, 23, 238, 224, 9, 2, 228, 95, 23, 237, 219, 9, 2, 228, 95, + 23, 237, 220, 91, 237, 219, 9, 2, 228, 95, 23, 152, 9, 2, 228, 95, 23, + 237, 140, 9, 2, 228, 95, 23, 237, 4, 23, 221, 40, 9, 2, 228, 95, 23, 231, + 86, 237, 208, 9, 2, 228, 95, 23, 231, 66, 9, 2, 228, 95, 23, 231, 67, 91, + 152, 9, 2, 228, 95, 23, 231, 67, 91, 226, 239, 9, 2, 228, 95, 23, 229, + 100, 9, 2, 228, 95, 23, 229, 84, 9, 2, 228, 95, 23, 228, 207, 9, 2, 228, + 95, 23, 228, 196, 9, 2, 228, 95, 23, 228, 197, 91, 237, 4, 91, 63, 9, 2, + 228, 95, 23, 228, 94, 9, 2, 228, 95, 23, 227, 92, 9, 2, 228, 95, 23, 226, + 239, 9, 2, 228, 95, 23, 226, 224, 9, 2, 228, 95, 23, 225, 20, 9, 2, 228, + 95, 23, 225, 21, 91, 241, 92, 9, 2, 228, 95, 23, 223, 199, 9, 2, 228, 95, + 23, 222, 240, 9, 2, 228, 95, 23, 213, 44, 91, 210, 220, 9, 2, 228, 95, + 23, 212, 245, 91, 238, 56, 91, 241, 22, 9, 2, 228, 95, 23, 212, 245, 91, + 238, 56, 209, 141, 9, 2, 228, 95, 23, 212, 197, 9, 2, 228, 95, 23, 212, + 198, 91, 212, 197, 9, 2, 228, 95, 23, 210, 220, 9, 2, 228, 95, 23, 209, + 255, 9, 2, 228, 95, 23, 209, 242, 9, 2, 228, 95, 23, 209, 188, 91, 34, + 91, 211, 11, 91, 201, 201, 9, 2, 228, 95, 23, 68, 9, 2, 228, 95, 23, 106, + 91, 63, 9, 2, 228, 95, 23, 106, 91, 106, 91, 68, 9, 2, 228, 95, 23, 207, + 41, 91, 250, 75, 9, 2, 228, 95, 23, 207, 29, 9, 2, 228, 95, 23, 206, 186, + 9, 2, 228, 95, 211, 176, 9, 2, 228, 92, 9, 2, 228, 93, 23, 213, 43, 9, 2, + 228, 93, 23, 213, 44, 91, 210, 220, 9, 2, 228, 93, 237, 208, 9, 2, 228, + 93, 237, 209, 115, 228, 93, 237, 209, 213, 43, 9, 2, 228, 88, 9, 2, 228, + 30, 9, 2, 228, 31, 23, 228, 30, 9, 2, 228, 28, 9, 2, 228, 29, 23, 228, + 183, 9, 2, 228, 29, 23, 228, 184, 91, 215, 145, 9, 2, 227, 148, 9, 2, + 227, 129, 9, 2, 227, 117, 9, 2, 227, 92, 9, 2, 226, 239, 9, 2, 226, 240, + 23, 249, 15, 9, 2, 226, 237, 9, 2, 226, 238, 23, 251, 39, 9, 2, 226, 238, + 23, 249, 15, 9, 2, 226, 238, 23, 241, 4, 9, 2, 226, 238, 23, 241, 5, 209, + 141, 9, 2, 226, 238, 23, 238, 233, 209, 141, 9, 2, 226, 238, 23, 237, 4, + 23, 249, 15, 9, 2, 226, 238, 23, 231, 66, 9, 2, 226, 238, 23, 230, 29, 9, + 2, 226, 238, 23, 230, 27, 9, 2, 226, 238, 23, 230, 28, 91, 250, 75, 9, 2, + 226, 238, 23, 229, 100, 9, 2, 226, 238, 23, 228, 114, 91, 250, 75, 9, 2, + 226, 238, 23, 228, 94, 9, 2, 226, 238, 23, 225, 21, 91, 241, 92, 9, 2, + 226, 238, 23, 222, 240, 9, 2, 226, 238, 23, 221, 84, 9, 2, 226, 238, 23, + 212, 163, 91, 250, 75, 9, 2, 226, 238, 23, 212, 141, 91, 247, 193, 9, 2, + 226, 238, 23, 207, 197, 9, 2, 226, 238, 209, 141, 9, 2, 226, 238, 245, + 124, 226, 237, 9, 2, 226, 238, 219, 251, 226, 237, 9, 2, 226, 238, 211, + 176, 9, 2, 226, 238, 213, 24, 9, 2, 226, 236, 9, 2, 226, 230, 9, 2, 226, + 231, 115, 226, 230, 9, 2, 226, 231, 219, 251, 226, 230, 9, 2, 226, 231, + 213, 24, 9, 2, 226, 227, 9, 2, 226, 224, 9, 2, 226, 222, 9, 2, 226, 223, + 115, 226, 222, 9, 2, 226, 223, 115, 226, 223, 238, 225, 115, 238, 224, 9, + 2, 192, 9, 2, 225, 177, 23, 209, 242, 9, 2, 225, 177, 237, 208, 9, 2, + 225, 176, 9, 2, 225, 148, 9, 2, 225, 100, 9, 2, 225, 79, 9, 2, 225, 78, + 9, 2, 225, 20, 9, 2, 224, 228, 9, 2, 224, 155, 9, 2, 224, 110, 9, 2, 223, + 246, 9, 2, 223, 247, 115, 223, 246, 9, 2, 223, 235, 9, 2, 223, 236, 237, + 208, 9, 2, 223, 217, 9, 2, 223, 203, 9, 2, 223, 199, 9, 2, 223, 200, 23, + 63, 9, 2, 223, 200, 23, 228, 183, 9, 2, 223, 200, 23, 202, 116, 9, 2, + 223, 200, 115, 223, 199, 9, 2, 223, 200, 115, 223, 200, 23, 34, 91, 201, + 201, 9, 2, 223, 200, 245, 124, 223, 199, 9, 2, 223, 197, 9, 2, 223, 198, + 23, 63, 9, 2, 223, 198, 23, 34, 91, 243, 233, 9, 2, 223, 198, 23, 243, + 233, 9, 2, 223, 198, 237, 208, 9, 2, 201, 201, 9, 2, 223, 109, 9, 2, 223, + 96, 9, 2, 223, 97, 230, 238, 9, 2, 223, 97, 23, 212, 200, 209, 141, 9, 2, + 223, 97, 219, 251, 223, 96, 9, 2, 223, 95, 9, 2, 223, 88, 221, 26, 9, 2, + 223, 87, 9, 2, 223, 86, 9, 2, 222, 240, 9, 2, 222, 241, 23, 63, 9, 2, + 222, 241, 23, 207, 29, 9, 2, 222, 241, 213, 24, 9, 2, 222, 100, 9, 2, + 222, 101, 23, 74, 9, 2, 222, 99, 9, 2, 222, 69, 9, 2, 222, 70, 23, 238, + 233, 209, 141, 9, 2, 222, 70, 23, 238, 225, 91, 238, 233, 209, 141, 9, 2, + 222, 65, 9, 2, 222, 66, 23, 250, 231, 9, 2, 222, 66, 23, 250, 75, 9, 2, + 222, 66, 23, 250, 76, 91, 250, 75, 9, 2, 222, 66, 23, 237, 219, 9, 2, + 222, 66, 23, 225, 21, 91, 238, 233, 209, 141, 9, 2, 222, 66, 23, 222, + 240, 9, 2, 222, 66, 23, 221, 40, 9, 2, 222, 66, 23, 213, 43, 9, 2, 222, + 66, 23, 213, 44, 91, 34, 250, 231, 9, 2, 222, 66, 23, 213, 44, 91, 250, + 75, 9, 2, 222, 66, 23, 213, 44, 91, 250, 76, 91, 250, 75, 9, 2, 222, 66, + 23, 207, 41, 91, 250, 75, 9, 2, 222, 66, 23, 206, 186, 9, 2, 222, 53, 9, + 2, 221, 84, 9, 2, 221, 56, 9, 2, 221, 40, 9, 2, 221, 41, 228, 93, 23, + 238, 224, 9, 2, 221, 41, 228, 93, 23, 225, 79, 9, 2, 221, 41, 228, 93, + 23, 215, 8, 9, 2, 221, 41, 228, 93, 23, 215, 9, 115, 221, 41, 228, 93, + 23, 215, 8, 9, 2, 221, 41, 228, 93, 23, 206, 186, 9, 2, 221, 41, 209, + 141, 9, 2, 221, 41, 115, 221, 40, 9, 2, 221, 41, 245, 124, 221, 40, 9, 2, + 221, 41, 245, 124, 221, 41, 228, 93, 115, 228, 92, 9, 2, 221, 35, 9, 2, + 221, 36, 251, 150, 23, 250, 69, 9, 2, 221, 36, 251, 150, 23, 248, 86, 9, + 2, 221, 36, 251, 150, 23, 242, 37, 9, 2, 221, 36, 251, 150, 23, 237, 219, + 9, 2, 221, 36, 251, 150, 23, 231, 86, 237, 208, 9, 2, 221, 36, 251, 150, + 23, 230, 27, 9, 2, 221, 36, 251, 150, 23, 228, 113, 9, 2, 221, 36, 251, + 150, 23, 222, 240, 9, 2, 221, 36, 251, 150, 23, 212, 138, 9, 2, 221, 36, + 251, 150, 23, 207, 40, 9, 2, 221, 36, 229, 69, 23, 248, 86, 9, 2, 221, + 36, 229, 69, 23, 248, 87, 68, 9, 2, 185, 9, 2, 219, 159, 9, 2, 219, 122, + 9, 2, 219, 96, 9, 2, 218, 222, 9, 2, 218, 167, 9, 2, 218, 168, 23, 63, 9, + 2, 218, 168, 23, 251, 232, 9, 2, 218, 168, 23, 248, 86, 9, 2, 218, 168, + 23, 247, 193, 9, 2, 218, 168, 23, 74, 9, 2, 218, 168, 23, 75, 9, 2, 218, + 168, 23, 235, 166, 9, 2, 218, 168, 23, 68, 9, 2, 218, 168, 23, 207, 40, + 9, 2, 218, 168, 245, 124, 218, 167, 9, 2, 218, 109, 9, 2, 218, 110, 23, + 230, 8, 9, 2, 218, 110, 23, 207, 29, 9, 2, 218, 110, 23, 202, 116, 9, 2, + 218, 110, 219, 251, 218, 109, 9, 2, 216, 220, 9, 2, 216, 214, 9, 2, 216, + 57, 9, 2, 215, 145, 9, 2, 215, 36, 9, 2, 215, 23, 221, 26, 9, 2, 215, 22, + 9, 2, 215, 23, 23, 63, 9, 2, 215, 23, 23, 242, 42, 9, 2, 215, 23, 23, + 242, 40, 9, 2, 215, 23, 23, 152, 9, 2, 215, 23, 23, 230, 12, 9, 2, 215, + 23, 23, 228, 183, 9, 2, 215, 23, 23, 226, 222, 9, 2, 215, 23, 23, 224, + 155, 9, 2, 215, 23, 23, 221, 40, 9, 2, 215, 23, 23, 215, 8, 9, 2, 215, + 23, 23, 213, 9, 9, 2, 215, 23, 23, 210, 10, 9, 2, 215, 23, 23, 207, 40, + 9, 2, 215, 23, 23, 207, 35, 9, 2, 215, 23, 23, 207, 6, 9, 2, 215, 23, 23, + 206, 210, 9, 2, 215, 23, 23, 206, 186, 9, 2, 215, 23, 115, 215, 22, 9, 2, + 215, 23, 237, 208, 9, 2, 215, 8, 9, 2, 215, 9, 228, 95, 23, 250, 73, 9, + 2, 214, 238, 9, 2, 214, 230, 9, 2, 213, 90, 9, 2, 213, 88, 9, 2, 213, 89, + 23, 63, 9, 2, 213, 89, 23, 249, 15, 9, 2, 213, 89, 23, 238, 55, 9, 2, + 213, 89, 23, 222, 240, 9, 2, 213, 89, 23, 212, 197, 9, 2, 213, 89, 23, + 207, 181, 9, 2, 213, 89, 23, 68, 9, 2, 213, 89, 23, 106, 91, 63, 9, 2, + 213, 86, 9, 2, 213, 84, 9, 2, 213, 59, 9, 2, 213, 43, 9, 2, 213, 44, 236, + 26, 9, 2, 213, 44, 115, 213, 44, 239, 0, 115, 239, 0, 238, 225, 115, 238, + 224, 9, 2, 213, 44, 115, 213, 44, 210, 11, 115, 210, 11, 238, 225, 115, + 238, 224, 9, 2, 213, 36, 9, 2, 213, 31, 9, 2, 213, 27, 9, 2, 213, 26, 9, + 2, 213, 23, 9, 2, 213, 9, 9, 2, 213, 10, 23, 63, 9, 2, 213, 10, 23, 231, + 66, 9, 2, 213, 3, 9, 2, 213, 4, 23, 63, 9, 2, 213, 4, 23, 248, 253, 9, 2, + 213, 4, 23, 247, 171, 9, 2, 213, 4, 23, 243, 176, 9, 2, 213, 4, 23, 238, + 224, 9, 2, 213, 4, 23, 231, 85, 9, 2, 213, 4, 23, 231, 86, 237, 208, 9, + 2, 213, 4, 23, 228, 177, 9, 2, 213, 4, 23, 226, 224, 9, 2, 213, 4, 23, + 223, 235, 9, 2, 213, 4, 23, 215, 8, 9, 2, 212, 253, 9, 2, 212, 248, 9, 2, + 212, 249, 209, 141, 9, 2, 212, 249, 115, 212, 249, 247, 161, 115, 247, + 160, 9, 2, 212, 244, 9, 2, 212, 199, 9, 2, 212, 200, 115, 230, 239, 212, + 199, 9, 2, 212, 197, 9, 2, 212, 196, 9, 2, 212, 162, 9, 2, 212, 163, 237, + 208, 9, 2, 212, 149, 9, 2, 212, 147, 9, 2, 212, 148, 115, 212, 148, 212, + 197, 9, 2, 212, 140, 9, 2, 212, 138, 9, 2, 211, 10, 9, 2, 211, 11, 115, + 211, 10, 9, 2, 210, 232, 9, 2, 210, 231, 9, 2, 210, 229, 9, 2, 210, 220, + 9, 2, 210, 219, 9, 2, 210, 193, 9, 2, 210, 192, 9, 2, 210, 22, 9, 2, 210, + 23, 250, 59, 9, 2, 210, 23, 23, 237, 3, 9, 2, 210, 23, 23, 224, 155, 9, + 2, 210, 23, 237, 208, 9, 2, 210, 10, 9, 2, 210, 11, 115, 210, 11, 222, + 101, 115, 222, 101, 243, 157, 115, 243, 156, 9, 2, 210, 11, 211, 176, 9, + 2, 209, 255, 9, 2, 160, 23, 248, 86, 9, 2, 160, 23, 237, 219, 9, 2, 160, + 23, 213, 43, 9, 2, 160, 23, 212, 199, 9, 2, 160, 23, 207, 197, 9, 2, 160, + 23, 207, 29, 9, 2, 209, 242, 9, 2, 209, 218, 9, 2, 209, 187, 9, 2, 209, + 188, 237, 208, 9, 2, 209, 2, 9, 2, 209, 3, 209, 141, 9, 2, 208, 229, 9, + 2, 208, 206, 9, 2, 208, 207, 23, 209, 242, 9, 2, 208, 207, 115, 208, 206, + 9, 2, 208, 207, 115, 208, 207, 239, 0, 115, 239, 0, 238, 225, 115, 238, + 224, 9, 2, 207, 203, 9, 2, 207, 197, 9, 2, 207, 195, 9, 2, 207, 191, 9, + 2, 207, 181, 9, 2, 207, 182, 115, 207, 182, 202, 117, 115, 202, 116, 9, + 2, 68, 9, 2, 106, 237, 219, 9, 2, 106, 106, 68, 9, 2, 106, 115, 106, 219, + 169, 115, 219, 169, 238, 225, 115, 238, 224, 9, 2, 106, 115, 106, 210, + 194, 115, 210, 193, 9, 2, 106, 115, 106, 106, 216, 73, 115, 106, 216, 72, + 9, 2, 207, 40, 9, 2, 207, 35, 9, 2, 207, 29, 9, 2, 207, 30, 228, 177, 9, + 2, 207, 30, 23, 249, 15, 9, 2, 207, 30, 23, 224, 155, 9, 2, 207, 30, 23, + 106, 91, 106, 91, 68, 9, 2, 207, 30, 23, 106, 91, 106, 91, 106, 237, 208, + 9, 2, 207, 30, 237, 208, 9, 2, 207, 30, 213, 24, 9, 2, 207, 30, 213, 25, + 23, 249, 15, 9, 2, 207, 25, 9, 2, 207, 6, 9, 2, 207, 7, 23, 228, 94, 9, + 2, 207, 7, 23, 225, 21, 91, 244, 212, 9, 2, 207, 7, 23, 213, 88, 9, 2, + 207, 7, 23, 68, 9, 2, 207, 5, 9, 2, 207, 1, 9, 2, 207, 2, 23, 229, 231, + 9, 2, 207, 2, 23, 185, 9, 2, 206, 255, 9, 2, 207, 0, 237, 208, 9, 2, 206, + 210, 9, 2, 206, 211, 245, 124, 206, 210, 9, 2, 206, 211, 213, 24, 9, 2, + 206, 208, 9, 2, 206, 209, 23, 34, 91, 152, 9, 2, 206, 209, 23, 34, 91, + 201, 201, 9, 2, 206, 209, 23, 251, 39, 9, 2, 206, 209, 23, 152, 9, 2, + 206, 209, 23, 221, 40, 9, 2, 206, 209, 23, 207, 40, 9, 2, 206, 209, 23, + 207, 41, 91, 250, 75, 9, 2, 206, 209, 23, 207, 41, 91, 248, 86, 9, 2, + 206, 207, 9, 2, 206, 204, 9, 2, 206, 203, 9, 2, 206, 199, 9, 2, 206, 200, + 23, 63, 9, 2, 206, 200, 23, 250, 69, 9, 2, 206, 200, 23, 142, 9, 2, 206, + 200, 23, 242, 31, 9, 2, 206, 200, 23, 239, 8, 9, 2, 206, 200, 23, 238, + 246, 9, 2, 206, 200, 23, 238, 233, 209, 141, 9, 2, 206, 200, 23, 238, + 224, 9, 2, 206, 200, 23, 237, 230, 9, 2, 206, 200, 23, 152, 9, 2, 206, + 200, 23, 231, 85, 9, 2, 206, 200, 23, 231, 66, 9, 2, 206, 200, 23, 230, + 209, 9, 2, 206, 200, 23, 229, 100, 9, 2, 206, 200, 23, 226, 222, 9, 2, + 206, 200, 23, 224, 110, 9, 2, 206, 200, 23, 185, 9, 2, 206, 200, 23, 213, + 43, 9, 2, 206, 200, 23, 212, 147, 9, 2, 206, 200, 23, 207, 203, 9, 2, + 206, 200, 23, 106, 91, 237, 219, 9, 2, 206, 200, 23, 207, 29, 9, 2, 206, + 200, 23, 206, 197, 9, 2, 206, 197, 9, 2, 206, 198, 23, 68, 9, 2, 206, + 186, 9, 2, 206, 187, 23, 63, 9, 2, 206, 187, 23, 228, 209, 9, 2, 206, + 187, 23, 228, 183, 9, 2, 206, 187, 23, 209, 242, 9, 2, 206, 182, 9, 2, + 206, 185, 9, 2, 206, 183, 9, 2, 206, 179, 9, 2, 206, 167, 9, 2, 206, 168, + 23, 229, 231, 9, 2, 206, 166, 9, 2, 202, 116, 9, 2, 202, 117, 209, 141, + 9, 2, 202, 117, 103, 23, 228, 183, 9, 2, 202, 112, 9, 2, 202, 105, 9, 2, + 202, 91, 9, 2, 202, 39, 9, 2, 202, 40, 115, 202, 39, 9, 2, 202, 38, 9, 2, + 202, 36, 9, 2, 202, 37, 230, 31, 209, 141, 9, 2, 202, 31, 9, 2, 202, 22, + 9, 2, 202, 6, 9, 2, 202, 4, 9, 2, 202, 5, 23, 63, 9, 2, 202, 3, 9, 2, + 202, 2, 9, 2, 229, 254, 241, 119, 9, 2, 251, 233, 23, 221, 40, 9, 2, 251, + 150, 23, 63, 9, 2, 250, 244, 23, 228, 198, 9, 2, 244, 204, 229, 69, 23, + 207, 41, 91, 225, 79, 9, 2, 244, 202, 9, 2, 243, 157, 91, 212, 199, 9, 2, + 242, 41, 23, 213, 43, 9, 2, 240, 180, 23, 237, 219, 9, 2, 240, 180, 23, + 213, 43, 9, 2, 239, 7, 23, 250, 232, 91, 230, 13, 91, 63, 9, 2, 239, 7, + 23, 250, 73, 9, 2, 238, 189, 9, 2, 238, 71, 9, 2, 236, 3, 9, 2, 230, 44, + 23, 250, 200, 9, 2, 230, 44, 23, 250, 72, 9, 2, 230, 44, 23, 238, 55, 9, + 2, 230, 44, 23, 237, 219, 9, 2, 230, 44, 23, 237, 4, 23, 250, 73, 9, 2, + 230, 44, 23, 226, 222, 9, 2, 230, 44, 23, 185, 9, 2, 230, 44, 23, 212, + 192, 9, 2, 230, 44, 23, 207, 203, 9, 2, 230, 44, 23, 206, 208, 9, 2, 228, + 95, 23, 238, 81, 9, 2, 226, 238, 213, 25, 23, 249, 15, 9, 2, 226, 238, + 23, 241, 5, 91, 228, 30, 9, 2, 226, 238, 23, 212, 199, 9, 2, 224, 227, 9, + 2, 223, 198, 23, 202, 116, 9, 2, 223, 108, 9, 2, 222, 68, 9, 2, 222, 67, + 9, 2, 222, 66, 23, 248, 253, 9, 2, 222, 66, 23, 238, 81, 9, 2, 221, 57, + 215, 198, 222, 59, 244, 54, 9, 2, 218, 223, 250, 59, 9, 2, 218, 113, 9, + 2, 215, 23, 23, 231, 86, 237, 208, 9, 2, 209, 1, 9, 2, 207, 7, 23, 225, + 20, 9, 2, 106, 68, 9, 141, 2, 120, 250, 75, 9, 141, 2, 126, 250, 75, 9, + 141, 2, 239, 147, 250, 75, 9, 141, 2, 239, 233, 250, 75, 9, 141, 2, 212, + 88, 250, 75, 9, 141, 2, 213, 112, 250, 75, 9, 141, 2, 241, 143, 250, 75, + 9, 141, 2, 222, 64, 250, 75, 9, 141, 2, 126, 243, 156, 9, 141, 2, 239, + 147, 243, 156, 9, 141, 2, 239, 233, 243, 156, 9, 141, 2, 212, 88, 243, + 156, 9, 141, 2, 213, 112, 243, 156, 9, 141, 2, 241, 143, 243, 156, 9, + 141, 2, 222, 64, 243, 156, 9, 141, 2, 239, 147, 68, 9, 141, 2, 239, 233, + 68, 9, 141, 2, 212, 88, 68, 9, 141, 2, 213, 112, 68, 9, 141, 2, 241, 143, + 68, 9, 141, 2, 222, 64, 68, 9, 141, 2, 118, 238, 164, 9, 141, 2, 120, + 238, 164, 9, 141, 2, 126, 238, 164, 9, 141, 2, 239, 147, 238, 164, 9, + 141, 2, 239, 233, 238, 164, 9, 141, 2, 212, 88, 238, 164, 9, 141, 2, 213, + 112, 238, 164, 9, 141, 2, 241, 143, 238, 164, 9, 141, 2, 222, 64, 238, + 164, 9, 141, 2, 118, 238, 161, 9, 141, 2, 120, 238, 161, 9, 141, 2, 126, + 238, 161, 9, 141, 2, 239, 147, 238, 161, 9, 141, 2, 239, 233, 238, 161, + 9, 141, 2, 120, 213, 59, 9, 141, 2, 126, 213, 59, 9, 141, 2, 126, 213, + 60, 206, 69, 18, 9, 141, 2, 239, 147, 213, 59, 9, 141, 2, 239, 233, 213, + 59, 9, 141, 2, 212, 88, 213, 59, 9, 141, 2, 213, 112, 213, 59, 9, 141, 2, + 241, 143, 213, 59, 9, 141, 2, 222, 64, 213, 59, 9, 141, 2, 118, 213, 54, + 9, 141, 2, 120, 213, 54, 9, 141, 2, 126, 213, 54, 9, 141, 2, 126, 213, + 55, 206, 69, 18, 9, 141, 2, 239, 147, 213, 54, 9, 141, 2, 239, 233, 213, + 54, 9, 141, 2, 213, 60, 23, 238, 247, 91, 243, 156, 9, 141, 2, 213, 60, + 23, 238, 247, 91, 224, 110, 9, 141, 2, 118, 247, 156, 9, 141, 2, 120, + 247, 156, 9, 141, 2, 126, 247, 156, 9, 141, 2, 126, 247, 157, 206, 69, + 18, 9, 141, 2, 239, 147, 247, 156, 9, 141, 2, 239, 233, 247, 156, 9, 141, + 2, 126, 206, 69, 239, 159, 241, 6, 9, 141, 2, 126, 206, 69, 239, 159, + 241, 3, 9, 141, 2, 239, 147, 206, 69, 239, 159, 227, 118, 9, 141, 2, 239, + 147, 206, 69, 239, 159, 227, 116, 9, 141, 2, 239, 147, 206, 69, 239, 159, + 227, 119, 63, 9, 141, 2, 239, 147, 206, 69, 239, 159, 227, 119, 249, 255, + 9, 141, 2, 212, 88, 206, 69, 239, 159, 250, 71, 9, 141, 2, 213, 112, 206, + 69, 239, 159, 231, 58, 9, 141, 2, 213, 112, 206, 69, 239, 159, 231, 60, + 63, 9, 141, 2, 213, 112, 206, 69, 239, 159, 231, 60, 249, 255, 9, 141, 2, + 241, 143, 206, 69, 239, 159, 206, 181, 9, 141, 2, 241, 143, 206, 69, 239, + 159, 206, 180, 9, 141, 2, 222, 64, 206, 69, 239, 159, 231, 74, 9, 141, 2, + 222, 64, 206, 69, 239, 159, 231, 73, 9, 141, 2, 222, 64, 206, 69, 239, + 159, 231, 72, 9, 141, 2, 222, 64, 206, 69, 239, 159, 231, 75, 63, 9, 141, + 2, 120, 250, 76, 209, 141, 9, 141, 2, 126, 250, 76, 209, 141, 9, 141, 2, + 239, 147, 250, 76, 209, 141, 9, 141, 2, 239, 233, 250, 76, 209, 141, 9, + 141, 2, 212, 88, 250, 76, 209, 141, 9, 141, 2, 118, 248, 240, 9, 141, 2, + 120, 248, 240, 9, 141, 2, 126, 248, 240, 9, 141, 2, 239, 147, 248, 240, + 9, 141, 2, 239, 147, 248, 241, 206, 69, 18, 9, 141, 2, 239, 233, 248, + 240, 9, 141, 2, 239, 233, 248, 241, 206, 69, 18, 9, 141, 2, 222, 77, 9, + 141, 2, 222, 78, 9, 141, 2, 118, 241, 2, 9, 141, 2, 120, 241, 2, 9, 141, + 2, 118, 209, 61, 243, 156, 9, 141, 2, 120, 209, 58, 243, 156, 9, 141, 2, + 239, 233, 212, 77, 243, 156, 9, 141, 2, 118, 209, 61, 206, 69, 239, 159, + 63, 9, 141, 2, 120, 209, 58, 206, 69, 239, 159, 63, 9, 141, 2, 118, 241, + 139, 250, 75, 9, 141, 2, 118, 217, 56, 250, 75, 9, 141, 2, 38, 250, 62, + 118, 212, 78, 9, 141, 2, 38, 250, 62, 118, 217, 55, 9, 141, 2, 118, 217, + 56, 237, 202, 9, 141, 2, 118, 162, 237, 202, 9, 141, 2, 241, 120, 118, + 209, 60, 9, 141, 2, 241, 120, 120, 209, 57, 9, 141, 2, 241, 120, 239, + 153, 9, 141, 2, 241, 120, 240, 18, 9, 141, 2, 239, 147, 106, 206, 69, 18, + 9, 141, 2, 239, 233, 106, 206, 69, 18, 9, 141, 2, 212, 88, 106, 206, 69, + 18, 9, 141, 2, 213, 112, 106, 206, 69, 18, 9, 141, 2, 241, 143, 106, 206, + 69, 18, 9, 141, 2, 222, 64, 106, 206, 69, 18, 9, 217, 179, 2, 38, 250, + 62, 203, 238, 243, 141, 9, 217, 179, 2, 80, 245, 242, 9, 217, 179, 2, + 243, 228, 245, 242, 9, 217, 179, 2, 243, 228, 208, 81, 9, 217, 179, 2, + 243, 228, 217, 61, 9, 2, 251, 233, 23, 221, 41, 209, 141, 9, 2, 251, 233, + 23, 212, 197, 9, 2, 251, 123, 23, 241, 4, 9, 2, 249, 16, 23, 243, 157, + 209, 141, 9, 2, 249, 4, 23, 251, 149, 9, 2, 249, 4, 23, 222, 100, 9, 2, + 249, 4, 23, 202, 116, 9, 2, 247, 194, 115, 247, 194, 23, 223, 109, 9, 2, + 244, 213, 23, 209, 242, 9, 2, 244, 204, 23, 228, 183, 9, 2, 243, 189, 23, + 231, 85, 9, 2, 243, 189, 23, 106, 106, 68, 9, 2, 243, 187, 23, 207, 29, + 9, 2, 242, 38, 23, 250, 200, 9, 2, 242, 38, 23, 250, 75, 9, 2, 242, 38, + 23, 250, 76, 250, 50, 227, 222, 9, 2, 242, 38, 23, 243, 176, 9, 2, 242, + 38, 23, 242, 31, 9, 2, 242, 38, 23, 241, 22, 9, 2, 242, 38, 23, 239, 8, + 9, 2, 242, 38, 23, 238, 81, 9, 2, 242, 38, 23, 238, 64, 237, 208, 9, 2, + 242, 38, 23, 238, 55, 9, 2, 242, 38, 23, 152, 9, 2, 242, 38, 23, 237, 3, + 9, 2, 242, 38, 23, 231, 86, 237, 208, 9, 2, 242, 38, 23, 229, 231, 9, 2, + 242, 38, 23, 228, 183, 9, 2, 242, 38, 23, 228, 177, 9, 2, 242, 38, 23, + 228, 178, 91, 229, 231, 9, 2, 242, 38, 23, 228, 82, 9, 2, 242, 38, 23, + 228, 28, 9, 2, 242, 38, 23, 228, 29, 23, 228, 183, 9, 2, 242, 38, 23, + 226, 228, 91, 238, 55, 9, 2, 242, 38, 23, 225, 79, 9, 2, 242, 38, 23, + 224, 228, 9, 2, 242, 38, 23, 224, 155, 9, 2, 242, 38, 23, 222, 100, 9, 2, + 242, 38, 23, 218, 167, 9, 2, 242, 38, 23, 213, 43, 9, 2, 242, 38, 23, + 212, 163, 237, 208, 9, 2, 241, 191, 23, 228, 183, 9, 2, 241, 191, 23, + 219, 96, 9, 2, 241, 23, 203, 196, 9, 2, 241, 5, 245, 124, 241, 4, 9, 2, + 240, 180, 213, 25, 23, 250, 75, 9, 2, 240, 180, 213, 25, 23, 237, 3, 9, + 2, 240, 180, 213, 25, 23, 231, 86, 237, 208, 9, 2, 240, 180, 213, 25, 23, + 228, 113, 9, 2, 240, 180, 213, 25, 23, 228, 30, 9, 2, 240, 180, 213, 25, + 23, 225, 20, 9, 2, 240, 180, 213, 25, 23, 224, 228, 9, 2, 240, 180, 213, + 25, 23, 211, 10, 9, 2, 240, 180, 23, 211, 10, 9, 2, 239, 7, 23, 249, 3, + 9, 2, 239, 7, 23, 243, 189, 237, 208, 9, 2, 239, 7, 23, 242, 38, 23, 231, + 86, 237, 208, 9, 2, 239, 7, 23, 242, 38, 23, 229, 231, 9, 2, 239, 7, 23, + 241, 25, 9, 2, 239, 7, 23, 239, 8, 9, 2, 239, 7, 23, 238, 225, 91, 243, + 233, 9, 2, 239, 7, 23, 238, 225, 91, 222, 240, 9, 2, 239, 7, 23, 237, + 160, 91, 63, 9, 2, 239, 7, 23, 228, 178, 91, 229, 231, 9, 2, 239, 7, 23, + 228, 28, 9, 2, 239, 7, 23, 228, 29, 23, 228, 183, 9, 2, 239, 7, 23, 226, + 227, 9, 2, 239, 7, 23, 223, 199, 9, 2, 239, 7, 23, 222, 240, 9, 2, 239, + 7, 23, 222, 241, 91, 241, 190, 9, 2, 239, 7, 23, 222, 241, 91, 238, 81, + 9, 2, 239, 7, 23, 213, 3, 9, 2, 239, 7, 23, 202, 22, 9, 2, 239, 2, 215, + 198, 222, 59, 244, 54, 9, 2, 238, 163, 23, 68, 9, 2, 238, 56, 23, 238, + 56, 245, 124, 238, 55, 9, 2, 237, 229, 23, 231, 86, 237, 208, 9, 2, 237, + 220, 91, 238, 56, 23, 209, 242, 9, 2, 237, 160, 209, 142, 237, 208, 9, 2, + 237, 4, 23, 250, 76, 115, 237, 4, 23, 250, 75, 9, 2, 230, 44, 23, 247, + 193, 9, 2, 230, 44, 23, 173, 9, 2, 230, 44, 23, 106, 106, 68, 9, 2, 230, + 44, 23, 206, 210, 9, 2, 228, 95, 23, 202, 7, 115, 202, 6, 9, 2, 228, 83, + 9, 2, 228, 81, 9, 2, 228, 80, 9, 2, 228, 79, 9, 2, 228, 78, 9, 2, 228, + 77, 9, 2, 228, 76, 9, 2, 228, 75, 115, 228, 75, 237, 208, 9, 2, 228, 74, + 9, 2, 228, 73, 115, 228, 72, 9, 2, 228, 71, 9, 2, 228, 70, 9, 2, 228, 69, + 9, 2, 228, 68, 9, 2, 228, 67, 9, 2, 228, 66, 9, 2, 228, 65, 9, 2, 228, + 64, 9, 2, 228, 63, 9, 2, 228, 62, 9, 2, 228, 61, 9, 2, 228, 60, 9, 2, + 228, 59, 9, 2, 228, 58, 9, 2, 228, 57, 9, 2, 228, 56, 9, 2, 228, 55, 9, + 2, 228, 54, 9, 2, 228, 52, 9, 2, 228, 53, 23, 237, 230, 9, 2, 228, 53, + 23, 231, 85, 9, 2, 228, 53, 23, 219, 97, 91, 226, 236, 9, 2, 228, 53, 23, + 219, 97, 91, 219, 97, 91, 226, 236, 9, 2, 228, 53, 23, 207, 41, 91, 249, + 32, 9, 2, 228, 51, 9, 2, 228, 50, 9, 2, 228, 49, 9, 2, 228, 48, 9, 2, + 228, 47, 9, 2, 228, 46, 9, 2, 228, 45, 9, 2, 228, 44, 9, 2, 228, 43, 9, + 2, 228, 42, 9, 2, 228, 40, 9, 2, 228, 41, 23, 250, 75, 9, 2, 228, 41, 23, + 249, 15, 9, 2, 228, 41, 23, 242, 30, 237, 209, 237, 208, 9, 2, 228, 41, + 23, 228, 207, 9, 2, 228, 41, 23, 228, 113, 9, 2, 228, 41, 23, 209, 218, + 9, 2, 228, 41, 23, 209, 187, 9, 2, 228, 41, 23, 207, 40, 9, 2, 228, 41, + 23, 207, 29, 9, 2, 228, 41, 23, 206, 197, 9, 2, 228, 39, 9, 2, 228, 37, + 9, 2, 228, 38, 23, 242, 40, 9, 2, 228, 38, 23, 239, 8, 9, 2, 228, 38, 23, + 231, 85, 9, 2, 228, 38, 23, 231, 86, 237, 208, 9, 2, 228, 38, 23, 222, + 100, 9, 2, 228, 38, 23, 219, 97, 91, 219, 97, 91, 226, 236, 9, 2, 228, + 38, 23, 213, 28, 91, 229, 100, 9, 2, 228, 38, 23, 207, 29, 9, 2, 228, 38, + 23, 206, 197, 9, 2, 228, 35, 9, 2, 228, 34, 9, 2, 226, 238, 237, 209, 23, + 250, 75, 9, 2, 226, 238, 23, 243, 156, 9, 2, 226, 238, 23, 237, 140, 9, + 2, 226, 238, 23, 219, 96, 9, 2, 226, 238, 23, 219, 97, 91, 219, 97, 91, + 226, 236, 9, 2, 226, 238, 23, 209, 242, 9, 2, 224, 156, 91, 202, 115, 9, + 2, 223, 200, 115, 223, 200, 23, 239, 8, 9, 2, 223, 200, 115, 223, 200, + 23, 230, 12, 9, 2, 222, 66, 23, 243, 189, 237, 208, 9, 2, 222, 66, 23, + 238, 55, 9, 2, 222, 66, 23, 237, 212, 9, 2, 222, 66, 23, 237, 3, 9, 2, + 222, 66, 23, 229, 171, 9, 2, 222, 66, 23, 228, 78, 9, 2, 222, 66, 23, + 225, 79, 9, 2, 222, 66, 23, 219, 97, 91, 219, 96, 9, 2, 222, 66, 23, 68, + 9, 2, 222, 66, 23, 106, 91, 68, 9, 2, 222, 66, 23, 206, 197, 9, 2, 215, + 23, 237, 209, 23, 152, 9, 2, 215, 23, 23, 241, 92, 9, 2, 215, 23, 23, + 213, 44, 250, 50, 227, 222, 9, 2, 215, 23, 23, 209, 242, 9, 2, 213, 87, + 209, 141, 9, 2, 213, 44, 115, 213, 43, 9, 2, 213, 44, 91, 236, 21, 9, 2, + 213, 44, 91, 223, 86, 9, 2, 213, 44, 91, 214, 230, 9, 2, 212, 198, 91, + 242, 38, 23, 222, 100, 9, 2, 212, 198, 91, 241, 191, 23, 250, 231, 9, 2, + 212, 163, 23, 209, 242, 9, 2, 209, 243, 91, 215, 22, 9, 2, 207, 192, 23, + 238, 233, 209, 141, 9, 2, 207, 192, 23, 126, 243, 156, 9, 2, 206, 209, + 230, 238, 9, 2, 206, 209, 23, 207, 29, 9, 2, 206, 200, 23, 244, 153, 9, + 2, 206, 200, 23, 228, 36, 9, 2, 206, 200, 23, 226, 236, 9, 2, 202, 115, + 9, 2, 202, 7, 115, 202, 7, 91, 214, 230, 9, 2, 202, 5, 23, 126, 243, 157, + 209, 141, 14, 7, 255, 18, 14, 7, 255, 17, 14, 7, 255, 16, 14, 7, 255, 15, + 14, 7, 255, 14, 14, 7, 255, 13, 14, 7, 255, 12, 14, 7, 255, 11, 14, 7, + 255, 10, 14, 7, 255, 9, 14, 7, 255, 8, 14, 7, 255, 7, 14, 7, 255, 6, 14, + 7, 255, 4, 14, 7, 255, 3, 14, 7, 255, 2, 14, 7, 255, 1, 14, 7, 255, 0, + 14, 7, 254, 255, 14, 7, 254, 254, 14, 7, 254, 253, 14, 7, 254, 252, 14, + 7, 254, 251, 14, 7, 254, 250, 14, 7, 254, 249, 14, 7, 254, 248, 14, 7, + 254, 247, 14, 7, 254, 246, 14, 7, 254, 245, 14, 7, 254, 244, 14, 7, 254, + 243, 14, 7, 254, 241, 14, 7, 254, 240, 14, 7, 254, 238, 14, 7, 254, 237, + 14, 7, 254, 236, 14, 7, 254, 235, 14, 7, 254, 234, 14, 7, 254, 233, 14, + 7, 254, 232, 14, 7, 254, 231, 14, 7, 254, 230, 14, 7, 254, 229, 14, 7, + 254, 228, 14, 7, 254, 227, 14, 7, 254, 225, 14, 7, 254, 224, 14, 7, 254, + 223, 14, 7, 254, 221, 14, 7, 254, 220, 14, 7, 254, 219, 14, 7, 254, 218, + 14, 7, 254, 217, 14, 7, 254, 216, 14, 7, 254, 215, 14, 7, 254, 214, 14, + 7, 254, 211, 14, 7, 254, 210, 14, 7, 254, 209, 14, 7, 254, 208, 14, 7, + 254, 207, 14, 7, 254, 206, 14, 7, 254, 205, 14, 7, 254, 204, 14, 7, 254, + 203, 14, 7, 254, 202, 14, 7, 254, 201, 14, 7, 254, 200, 14, 7, 254, 199, + 14, 7, 254, 198, 14, 7, 254, 197, 14, 7, 254, 196, 14, 7, 254, 195, 14, + 7, 254, 194, 14, 7, 254, 193, 14, 7, 254, 192, 14, 7, 254, 188, 14, 7, + 254, 187, 14, 7, 254, 186, 14, 7, 254, 185, 14, 7, 249, 253, 14, 7, 249, + 251, 14, 7, 249, 249, 14, 7, 249, 247, 14, 7, 249, 245, 14, 7, 249, 244, + 14, 7, 249, 242, 14, 7, 249, 240, 14, 7, 249, 238, 14, 7, 249, 236, 14, + 7, 247, 121, 14, 7, 247, 120, 14, 7, 247, 119, 14, 7, 247, 118, 14, 7, + 247, 117, 14, 7, 247, 116, 14, 7, 247, 115, 14, 7, 247, 114, 14, 7, 247, + 113, 14, 7, 247, 112, 14, 7, 247, 111, 14, 7, 247, 110, 14, 7, 247, 109, + 14, 7, 247, 108, 14, 7, 247, 107, 14, 7, 247, 106, 14, 7, 247, 105, 14, + 7, 247, 104, 14, 7, 247, 103, 14, 7, 247, 102, 14, 7, 247, 101, 14, 7, + 247, 100, 14, 7, 247, 99, 14, 7, 247, 98, 14, 7, 247, 97, 14, 7, 247, 96, + 14, 7, 247, 95, 14, 7, 247, 94, 14, 7, 245, 50, 14, 7, 245, 49, 14, 7, + 245, 48, 14, 7, 245, 47, 14, 7, 245, 46, 14, 7, 245, 45, 14, 7, 245, 44, + 14, 7, 245, 43, 14, 7, 245, 42, 14, 7, 245, 41, 14, 7, 245, 40, 14, 7, + 245, 39, 14, 7, 245, 38, 14, 7, 245, 37, 14, 7, 245, 36, 14, 7, 245, 35, + 14, 7, 245, 34, 14, 7, 245, 33, 14, 7, 245, 32, 14, 7, 245, 31, 14, 7, + 245, 30, 14, 7, 245, 29, 14, 7, 245, 28, 14, 7, 245, 27, 14, 7, 245, 26, + 14, 7, 245, 25, 14, 7, 245, 24, 14, 7, 245, 23, 14, 7, 245, 22, 14, 7, + 245, 21, 14, 7, 245, 20, 14, 7, 245, 19, 14, 7, 245, 18, 14, 7, 245, 17, + 14, 7, 245, 16, 14, 7, 245, 15, 14, 7, 245, 14, 14, 7, 245, 13, 14, 7, + 245, 12, 14, 7, 245, 11, 14, 7, 245, 10, 14, 7, 245, 9, 14, 7, 245, 8, + 14, 7, 245, 7, 14, 7, 245, 6, 14, 7, 245, 5, 14, 7, 245, 4, 14, 7, 245, + 3, 14, 7, 245, 2, 14, 7, 245, 1, 14, 7, 245, 0, 14, 7, 244, 255, 14, 7, + 244, 254, 14, 7, 244, 253, 14, 7, 244, 252, 14, 7, 244, 251, 14, 7, 244, + 250, 14, 7, 244, 249, 14, 7, 244, 248, 14, 7, 244, 247, 14, 7, 244, 246, + 14, 7, 244, 245, 14, 7, 244, 244, 14, 7, 244, 243, 14, 7, 244, 242, 14, + 7, 244, 241, 14, 7, 244, 240, 14, 7, 244, 239, 14, 7, 244, 238, 14, 7, + 244, 237, 14, 7, 244, 236, 14, 7, 244, 235, 14, 7, 244, 234, 14, 7, 244, + 233, 14, 7, 244, 232, 14, 7, 244, 231, 14, 7, 244, 230, 14, 7, 244, 229, + 14, 7, 244, 228, 14, 7, 244, 227, 14, 7, 244, 226, 14, 7, 244, 225, 14, + 7, 244, 224, 14, 7, 244, 223, 14, 7, 244, 222, 14, 7, 244, 221, 14, 7, + 244, 220, 14, 7, 244, 219, 14, 7, 244, 218, 14, 7, 244, 217, 14, 7, 244, + 216, 14, 7, 244, 215, 14, 7, 241, 235, 14, 7, 241, 234, 14, 7, 241, 233, + 14, 7, 241, 232, 14, 7, 241, 231, 14, 7, 241, 230, 14, 7, 241, 229, 14, + 7, 241, 228, 14, 7, 241, 227, 14, 7, 241, 226, 14, 7, 241, 225, 14, 7, + 241, 224, 14, 7, 241, 223, 14, 7, 241, 222, 14, 7, 241, 221, 14, 7, 241, + 220, 14, 7, 241, 219, 14, 7, 241, 218, 14, 7, 241, 217, 14, 7, 241, 216, + 14, 7, 241, 215, 14, 7, 241, 214, 14, 7, 241, 213, 14, 7, 241, 212, 14, + 7, 241, 211, 14, 7, 241, 210, 14, 7, 241, 209, 14, 7, 241, 208, 14, 7, + 241, 207, 14, 7, 241, 206, 14, 7, 241, 205, 14, 7, 241, 204, 14, 7, 241, + 203, 14, 7, 241, 202, 14, 7, 241, 201, 14, 7, 241, 200, 14, 7, 241, 199, + 14, 7, 241, 198, 14, 7, 241, 197, 14, 7, 241, 196, 14, 7, 241, 195, 14, + 7, 241, 194, 14, 7, 241, 193, 14, 7, 241, 192, 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, + 240, 138, 14, 7, 240, 137, 14, 7, 240, 136, 14, 7, 240, 135, 14, 7, 240, + 134, 14, 7, 240, 133, 14, 7, 240, 132, 14, 7, 240, 131, 14, 7, 240, 130, + 14, 7, 240, 129, 14, 7, 240, 128, 14, 7, 240, 127, 14, 7, 240, 126, 14, + 7, 240, 125, 14, 7, 240, 124, 14, 7, 240, 123, 14, 7, 240, 122, 14, 7, + 240, 121, 14, 7, 240, 120, 14, 7, 240, 119, 14, 7, 240, 118, 14, 7, 240, + 117, 14, 7, 240, 116, 14, 7, 240, 115, 14, 7, 240, 114, 14, 7, 240, 113, + 14, 7, 240, 112, 14, 7, 240, 111, 14, 7, 240, 110, 14, 7, 240, 109, 14, + 7, 239, 74, 14, 7, 239, 73, 14, 7, 239, 72, 14, 7, 239, 71, 14, 7, 239, + 70, 14, 7, 239, 69, 14, 7, 239, 68, 14, 7, 239, 67, 14, 7, 239, 66, 14, + 7, 239, 65, 14, 7, 239, 64, 14, 7, 239, 63, 14, 7, 239, 62, 14, 7, 239, + 61, 14, 7, 239, 60, 14, 7, 239, 59, 14, 7, 239, 58, 14, 7, 239, 57, 14, + 7, 239, 56, 14, 7, 239, 55, 14, 7, 239, 54, 14, 7, 239, 53, 14, 7, 239, + 52, 14, 7, 239, 51, 14, 7, 239, 50, 14, 7, 239, 49, 14, 7, 239, 48, 14, + 7, 239, 47, 14, 7, 239, 46, 14, 7, 239, 45, 14, 7, 239, 44, 14, 7, 239, + 43, 14, 7, 239, 42, 14, 7, 239, 41, 14, 7, 239, 40, 14, 7, 239, 39, 14, + 7, 239, 38, 14, 7, 239, 37, 14, 7, 239, 36, 14, 7, 239, 35, 14, 7, 239, + 34, 14, 7, 239, 33, 14, 7, 239, 32, 14, 7, 239, 31, 14, 7, 239, 30, 14, + 7, 239, 29, 14, 7, 239, 28, 14, 7, 239, 27, 14, 7, 239, 26, 14, 7, 239, + 25, 14, 7, 239, 24, 14, 7, 239, 23, 14, 7, 239, 22, 14, 7, 239, 21, 14, + 7, 239, 20, 14, 7, 239, 19, 14, 7, 239, 18, 14, 7, 239, 17, 14, 7, 239, + 16, 14, 7, 239, 15, 14, 7, 239, 14, 14, 7, 239, 13, 14, 7, 239, 12, 14, + 7, 239, 11, 14, 7, 237, 169, 14, 7, 237, 168, 14, 7, 237, 167, 14, 7, + 237, 166, 14, 7, 237, 165, 14, 7, 237, 164, 14, 7, 237, 163, 14, 7, 237, + 162, 14, 7, 237, 161, 14, 7, 235, 190, 14, 7, 235, 189, 14, 7, 235, 188, + 14, 7, 235, 187, 14, 7, 235, 186, 14, 7, 235, 185, 14, 7, 235, 184, 14, + 7, 235, 183, 14, 7, 235, 182, 14, 7, 235, 181, 14, 7, 235, 180, 14, 7, + 235, 179, 14, 7, 235, 178, 14, 7, 235, 177, 14, 7, 235, 176, 14, 7, 235, + 175, 14, 7, 235, 174, 14, 7, 235, 173, 14, 7, 235, 172, 14, 7, 230, 53, + 14, 7, 230, 52, 14, 7, 230, 51, 14, 7, 230, 50, 14, 7, 230, 49, 14, 7, + 230, 48, 14, 7, 230, 47, 14, 7, 230, 46, 14, 7, 228, 128, 14, 7, 228, + 127, 14, 7, 228, 126, 14, 7, 228, 125, 14, 7, 228, 124, 14, 7, 228, 123, + 14, 7, 228, 122, 14, 7, 228, 121, 14, 7, 228, 120, 14, 7, 228, 119, 14, + 7, 226, 183, 14, 7, 226, 182, 14, 7, 226, 181, 14, 7, 226, 179, 14, 7, + 226, 177, 14, 7, 226, 176, 14, 7, 226, 174, 14, 7, 226, 172, 14, 7, 226, + 170, 14, 7, 226, 168, 14, 7, 226, 166, 14, 7, 226, 164, 14, 7, 226, 162, + 14, 7, 226, 161, 14, 7, 226, 159, 14, 7, 226, 157, 14, 7, 226, 156, 14, + 7, 226, 155, 14, 7, 226, 154, 14, 7, 226, 153, 14, 7, 226, 152, 14, 7, + 226, 151, 14, 7, 226, 150, 14, 7, 226, 149, 14, 7, 226, 147, 14, 7, 226, + 145, 14, 7, 226, 143, 14, 7, 226, 142, 14, 7, 226, 140, 14, 7, 226, 139, + 14, 7, 226, 137, 14, 7, 226, 136, 14, 7, 226, 134, 14, 7, 226, 132, 14, + 7, 226, 130, 14, 7, 226, 128, 14, 7, 226, 126, 14, 7, 226, 125, 14, 7, + 226, 123, 14, 7, 226, 121, 14, 7, 226, 120, 14, 7, 226, 118, 14, 7, 226, + 116, 14, 7, 226, 114, 14, 7, 226, 112, 14, 7, 226, 111, 14, 7, 226, 109, + 14, 7, 226, 107, 14, 7, 226, 105, 14, 7, 226, 104, 14, 7, 226, 102, 14, + 7, 226, 100, 14, 7, 226, 99, 14, 7, 226, 98, 14, 7, 226, 96, 14, 7, 226, + 94, 14, 7, 226, 92, 14, 7, 226, 90, 14, 7, 226, 88, 14, 7, 226, 86, 14, + 7, 226, 84, 14, 7, 226, 83, 14, 7, 226, 81, 14, 7, 226, 79, 14, 7, 226, + 77, 14, 7, 226, 75, 14, 7, 223, 160, 14, 7, 223, 159, 14, 7, 223, 158, + 14, 7, 223, 157, 14, 7, 223, 156, 14, 7, 223, 155, 14, 7, 223, 154, 14, + 7, 223, 153, 14, 7, 223, 152, 14, 7, 223, 151, 14, 7, 223, 150, 14, 7, + 223, 149, 14, 7, 223, 148, 14, 7, 223, 147, 14, 7, 223, 146, 14, 7, 223, + 145, 14, 7, 223, 144, 14, 7, 223, 143, 14, 7, 223, 142, 14, 7, 223, 141, + 14, 7, 223, 140, 14, 7, 223, 139, 14, 7, 223, 138, 14, 7, 223, 137, 14, + 7, 223, 136, 14, 7, 223, 135, 14, 7, 223, 134, 14, 7, 223, 133, 14, 7, + 223, 132, 14, 7, 223, 131, 14, 7, 223, 130, 14, 7, 223, 129, 14, 7, 223, + 128, 14, 7, 223, 127, 14, 7, 223, 126, 14, 7, 223, 125, 14, 7, 223, 124, + 14, 7, 223, 123, 14, 7, 223, 122, 14, 7, 223, 121, 14, 7, 223, 120, 14, + 7, 223, 119, 14, 7, 223, 118, 14, 7, 223, 117, 14, 7, 223, 116, 14, 7, + 223, 115, 14, 7, 223, 114, 14, 7, 223, 113, 14, 7, 223, 112, 14, 7, 221, + 252, 14, 7, 221, 251, 14, 7, 221, 250, 14, 7, 221, 249, 14, 7, 221, 248, + 14, 7, 221, 247, 14, 7, 221, 246, 14, 7, 221, 245, 14, 7, 221, 244, 14, + 7, 221, 243, 14, 7, 221, 242, 14, 7, 221, 241, 14, 7, 221, 240, 14, 7, + 221, 239, 14, 7, 221, 238, 14, 7, 221, 237, 14, 7, 221, 236, 14, 7, 221, + 235, 14, 7, 221, 234, 14, 7, 221, 233, 14, 7, 221, 232, 14, 7, 221, 231, + 14, 7, 221, 83, 14, 7, 221, 82, 14, 7, 221, 81, 14, 7, 221, 80, 14, 7, + 221, 79, 14, 7, 221, 78, 14, 7, 221, 77, 14, 7, 221, 76, 14, 7, 221, 75, + 14, 7, 221, 74, 14, 7, 221, 73, 14, 7, 221, 72, 14, 7, 221, 71, 14, 7, + 221, 70, 14, 7, 221, 69, 14, 7, 221, 68, 14, 7, 221, 67, 14, 7, 221, 66, + 14, 7, 221, 65, 14, 7, 221, 64, 14, 7, 221, 63, 14, 7, 221, 62, 14, 7, + 221, 61, 14, 7, 221, 60, 14, 7, 221, 59, 14, 7, 221, 58, 14, 7, 220, 173, + 14, 7, 220, 172, 14, 7, 220, 171, 14, 7, 220, 170, 14, 7, 220, 169, 14, + 7, 220, 168, 14, 7, 220, 167, 14, 7, 220, 166, 14, 7, 220, 165, 14, 7, + 220, 164, 14, 7, 220, 163, 14, 7, 220, 162, 14, 7, 220, 161, 14, 7, 220, + 160, 14, 7, 220, 159, 14, 7, 220, 158, 14, 7, 220, 157, 14, 7, 220, 156, + 14, 7, 220, 155, 14, 7, 220, 154, 14, 7, 220, 153, 14, 7, 220, 152, 14, + 7, 220, 151, 14, 7, 220, 150, 14, 7, 220, 149, 14, 7, 220, 148, 14, 7, + 220, 147, 14, 7, 220, 146, 14, 7, 220, 145, 14, 7, 220, 144, 14, 7, 220, + 143, 14, 7, 220, 142, 14, 7, 220, 141, 14, 7, 220, 140, 14, 7, 220, 139, + 14, 7, 220, 138, 14, 7, 220, 137, 14, 7, 220, 136, 14, 7, 220, 135, 14, + 7, 220, 134, 14, 7, 220, 133, 14, 7, 220, 132, 14, 7, 220, 131, 14, 7, + 220, 130, 14, 7, 220, 129, 14, 7, 220, 128, 14, 7, 220, 127, 14, 7, 220, + 126, 14, 7, 220, 125, 14, 7, 220, 124, 14, 7, 220, 123, 14, 7, 220, 122, + 14, 7, 220, 121, 14, 7, 220, 120, 14, 7, 220, 119, 14, 7, 220, 118, 14, + 7, 220, 117, 14, 7, 220, 116, 14, 7, 220, 115, 14, 7, 220, 114, 14, 7, + 220, 113, 14, 7, 220, 112, 14, 7, 220, 111, 14, 7, 220, 110, 14, 7, 220, + 109, 14, 7, 220, 108, 14, 7, 220, 107, 14, 7, 220, 106, 14, 7, 220, 105, + 14, 7, 220, 104, 14, 7, 220, 103, 14, 7, 220, 102, 14, 7, 220, 101, 14, + 7, 220, 100, 14, 7, 220, 99, 14, 7, 219, 183, 14, 7, 219, 182, 14, 7, + 219, 181, 14, 7, 219, 180, 14, 7, 219, 179, 14, 7, 219, 178, 14, 7, 219, + 177, 14, 7, 219, 176, 14, 7, 219, 175, 14, 7, 219, 174, 14, 7, 219, 173, + 14, 7, 219, 172, 14, 7, 219, 171, 14, 7, 217, 133, 14, 7, 217, 132, 14, + 7, 217, 131, 14, 7, 217, 130, 14, 7, 217, 129, 14, 7, 217, 128, 14, 7, + 217, 127, 14, 7, 216, 255, 14, 7, 216, 254, 14, 7, 216, 253, 14, 7, 216, + 252, 14, 7, 216, 251, 14, 7, 216, 250, 14, 7, 216, 249, 14, 7, 216, 248, + 14, 7, 216, 247, 14, 7, 216, 246, 14, 7, 216, 245, 14, 7, 216, 244, 14, + 7, 216, 243, 14, 7, 216, 242, 14, 7, 216, 241, 14, 7, 216, 240, 14, 7, + 216, 239, 14, 7, 216, 238, 14, 7, 216, 237, 14, 7, 216, 236, 14, 7, 216, + 235, 14, 7, 216, 234, 14, 7, 216, 233, 14, 7, 216, 232, 14, 7, 216, 231, + 14, 7, 216, 230, 14, 7, 216, 229, 14, 7, 216, 228, 14, 7, 216, 227, 14, + 7, 216, 226, 14, 7, 216, 225, 14, 7, 216, 224, 14, 7, 216, 223, 14, 7, + 216, 222, 14, 7, 215, 91, 14, 7, 215, 90, 14, 7, 215, 89, 14, 7, 215, 88, + 14, 7, 215, 87, 14, 7, 215, 86, 14, 7, 215, 85, 14, 7, 215, 84, 14, 7, + 215, 83, 14, 7, 215, 82, 14, 7, 215, 81, 14, 7, 215, 80, 14, 7, 215, 79, + 14, 7, 215, 78, 14, 7, 215, 77, 14, 7, 215, 76, 14, 7, 215, 75, 14, 7, + 215, 74, 14, 7, 215, 73, 14, 7, 215, 72, 14, 7, 215, 71, 14, 7, 215, 70, + 14, 7, 215, 69, 14, 7, 215, 68, 14, 7, 215, 67, 14, 7, 215, 66, 14, 7, + 215, 65, 14, 7, 215, 64, 14, 7, 215, 63, 14, 7, 215, 62, 14, 7, 215, 61, + 14, 7, 215, 60, 14, 7, 215, 59, 14, 7, 215, 58, 14, 7, 215, 57, 14, 7, + 215, 56, 14, 7, 215, 55, 14, 7, 215, 54, 14, 7, 215, 53, 14, 7, 215, 52, + 14, 7, 215, 51, 14, 7, 215, 50, 14, 7, 215, 49, 14, 7, 215, 48, 14, 7, + 215, 47, 14, 7, 215, 46, 14, 7, 215, 45, 14, 7, 215, 44, 14, 7, 215, 43, + 14, 7, 215, 42, 14, 7, 215, 41, 14, 7, 215, 40, 14, 7, 215, 39, 14, 7, + 215, 38, 14, 7, 210, 67, 14, 7, 210, 66, 14, 7, 210, 65, 14, 7, 210, 64, + 14, 7, 210, 63, 14, 7, 210, 62, 14, 7, 210, 61, 14, 7, 210, 60, 14, 7, + 210, 59, 14, 7, 210, 58, 14, 7, 210, 57, 14, 7, 210, 56, 14, 7, 210, 55, + 14, 7, 210, 54, 14, 7, 210, 53, 14, 7, 210, 52, 14, 7, 210, 51, 14, 7, + 210, 50, 14, 7, 210, 49, 14, 7, 210, 48, 14, 7, 210, 47, 14, 7, 210, 46, + 14, 7, 210, 45, 14, 7, 210, 44, 14, 7, 210, 43, 14, 7, 210, 42, 14, 7, + 210, 41, 14, 7, 210, 40, 14, 7, 210, 39, 14, 7, 210, 38, 14, 7, 210, 37, + 14, 7, 210, 36, 14, 7, 210, 35, 14, 7, 210, 34, 14, 7, 210, 33, 14, 7, + 210, 32, 14, 7, 210, 31, 14, 7, 210, 30, 14, 7, 210, 29, 14, 7, 210, 28, + 14, 7, 210, 27, 14, 7, 210, 26, 14, 7, 210, 25, 14, 7, 210, 24, 14, 7, + 207, 88, 14, 7, 207, 87, 14, 7, 207, 86, 14, 7, 207, 85, 14, 7, 207, 84, + 14, 7, 207, 83, 14, 7, 207, 82, 14, 7, 207, 81, 14, 7, 207, 80, 14, 7, + 207, 79, 14, 7, 207, 78, 14, 7, 207, 77, 14, 7, 207, 76, 14, 7, 207, 75, + 14, 7, 207, 74, 14, 7, 207, 73, 14, 7, 207, 72, 14, 7, 207, 71, 14, 7, + 207, 70, 14, 7, 207, 69, 14, 7, 207, 68, 14, 7, 207, 67, 14, 7, 207, 66, + 14, 7, 207, 65, 14, 7, 207, 64, 14, 7, 207, 63, 14, 7, 207, 62, 14, 7, + 207, 61, 14, 7, 207, 60, 14, 7, 207, 59, 14, 7, 207, 58, 14, 7, 207, 57, + 14, 7, 207, 56, 14, 7, 207, 55, 14, 7, 207, 54, 14, 7, 207, 53, 14, 7, + 207, 52, 14, 7, 207, 51, 14, 7, 207, 50, 14, 7, 207, 49, 14, 7, 207, 48, + 14, 7, 207, 47, 14, 7, 207, 46, 14, 7, 207, 45, 14, 7, 207, 44, 14, 7, + 207, 43, 14, 7, 207, 42, 14, 7, 206, 163, 14, 7, 206, 162, 14, 7, 206, + 161, 14, 7, 206, 160, 14, 7, 206, 159, 14, 7, 206, 158, 14, 7, 206, 157, + 14, 7, 206, 156, 14, 7, 206, 155, 14, 7, 206, 154, 14, 7, 206, 153, 14, + 7, 206, 152, 14, 7, 206, 151, 14, 7, 206, 150, 14, 7, 206, 149, 14, 7, + 206, 148, 14, 7, 206, 147, 14, 7, 206, 146, 14, 7, 206, 145, 14, 7, 206, + 144, 14, 7, 206, 143, 14, 7, 206, 142, 14, 7, 206, 141, 14, 7, 206, 140, + 14, 7, 206, 139, 14, 7, 206, 138, 14, 7, 206, 137, 14, 7, 206, 136, 14, + 7, 206, 135, 14, 7, 206, 134, 14, 7, 206, 133, 14, 7, 206, 132, 14, 7, + 206, 131, 14, 7, 206, 130, 14, 7, 206, 129, 14, 7, 206, 128, 14, 7, 206, + 127, 14, 7, 206, 126, 14, 7, 206, 125, 14, 7, 206, 124, 14, 7, 206, 123, + 14, 7, 206, 122, 14, 7, 206, 121, 14, 7, 206, 120, 14, 7, 206, 119, 14, + 7, 206, 118, 14, 7, 206, 117, 14, 7, 206, 116, 14, 7, 206, 115, 14, 7, + 206, 114, 14, 7, 206, 113, 14, 7, 206, 112, 14, 7, 206, 111, 14, 7, 206, + 110, 14, 7, 206, 109, 14, 7, 206, 108, 14, 7, 206, 107, 14, 7, 206, 106, + 14, 7, 206, 105, 14, 7, 206, 104, 14, 7, 206, 103, 14, 7, 206, 102, 14, + 7, 206, 101, 14, 7, 206, 100, 14, 7, 206, 99, 14, 7, 206, 98, 14, 7, 206, + 97, 14, 7, 206, 96, 14, 7, 206, 95, 14, 7, 206, 94, 14, 7, 206, 93, 14, + 7, 206, 92, 14, 7, 206, 91, 14, 7, 206, 90, 14, 7, 206, 89, 14, 7, 206, + 88, 14, 7, 206, 87, 14, 7, 204, 143, 14, 7, 204, 142, 14, 7, 204, 141, + 14, 7, 204, 140, 14, 7, 204, 139, 14, 7, 204, 138, 14, 7, 204, 137, 14, + 7, 204, 136, 14, 7, 204, 135, 14, 7, 204, 134, 14, 7, 204, 133, 14, 7, + 204, 132, 14, 7, 204, 131, 14, 7, 204, 130, 14, 7, 204, 129, 14, 7, 204, + 128, 14, 7, 204, 127, 14, 7, 204, 126, 14, 7, 204, 125, 14, 7, 204, 124, + 14, 7, 204, 123, 14, 7, 204, 122, 14, 7, 204, 121, 14, 7, 204, 120, 14, + 7, 204, 119, 14, 7, 204, 118, 14, 7, 204, 117, 14, 7, 204, 116, 14, 7, + 204, 115, 14, 7, 204, 114, 14, 7, 204, 113, 14, 7, 204, 112, 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, 122, 14, 7, + 203, 121, 14, 7, 203, 120, 14, 7, 203, 119, 14, 7, 203, 118, 14, 7, 203, + 117, 14, 7, 203, 116, 14, 7, 203, 115, 14, 7, 203, 114, 14, 7, 202, 158, + 14, 7, 202, 157, 14, 7, 202, 156, 14, 7, 202, 155, 14, 7, 202, 154, 14, + 7, 202, 153, 14, 7, 202, 152, 14, 7, 202, 151, 14, 7, 202, 150, 14, 7, + 202, 149, 14, 7, 202, 148, 14, 7, 202, 147, 14, 7, 202, 146, 14, 7, 202, + 145, 14, 7, 202, 144, 14, 7, 202, 143, 14, 7, 202, 142, 14, 7, 202, 141, + 14, 7, 202, 140, 14, 7, 202, 139, 14, 7, 202, 138, 14, 7, 202, 137, 14, + 7, 202, 136, 14, 7, 202, 135, 14, 7, 202, 134, 14, 7, 202, 133, 14, 7, + 202, 132, 14, 7, 202, 131, 14, 7, 202, 130, 14, 7, 202, 129, 14, 7, 202, + 128, 14, 7, 202, 127, 14, 7, 202, 126, 14, 7, 202, 125, 14, 7, 202, 124, + 14, 7, 202, 123, 14, 7, 202, 122, 14, 7, 202, 121, 14, 7, 202, 120, 14, + 7, 202, 119, 14, 7, 202, 118, 14, 7, 252, 24, 14, 7, 252, 23, 14, 7, 252, + 22, 14, 7, 252, 21, 14, 7, 252, 20, 14, 7, 252, 19, 14, 7, 252, 18, 14, + 7, 252, 17, 14, 7, 252, 16, 14, 7, 252, 15, 14, 7, 252, 14, 14, 7, 252, + 13, 14, 7, 252, 12, 14, 7, 252, 11, 14, 7, 252, 10, 14, 7, 252, 9, 14, 7, + 252, 8, 14, 7, 252, 7, 14, 7, 252, 6, 14, 7, 252, 5, 14, 7, 252, 4, 14, + 7, 252, 3, 14, 7, 252, 2, 14, 7, 252, 1, 14, 7, 252, 0, 14, 7, 251, 255, + 14, 7, 251, 254, 14, 7, 251, 253, 14, 7, 251, 252, 14, 7, 251, 251, 14, + 7, 251, 250, 14, 7, 251, 249, 14, 7, 251, 248, 14, 7, 251, 247, 27, 7, + 255, 18, 27, 7, 255, 17, 27, 7, 255, 16, 27, 7, 255, 15, 27, 7, 255, 14, + 27, 7, 255, 12, 27, 7, 255, 9, 27, 7, 255, 8, 27, 7, 255, 7, 27, 7, 255, + 6, 27, 7, 255, 5, 27, 7, 255, 4, 27, 7, 255, 3, 27, 7, 255, 2, 27, 7, + 255, 1, 27, 7, 254, 255, 27, 7, 254, 254, 27, 7, 254, 253, 27, 7, 254, + 251, 27, 7, 254, 250, 27, 7, 254, 249, 27, 7, 254, 248, 27, 7, 254, 247, + 27, 7, 254, 246, 27, 7, 254, 245, 27, 7, 254, 244, 27, 7, 254, 243, 27, + 7, 254, 242, 27, 7, 254, 241, 27, 7, 254, 240, 27, 7, 254, 238, 27, 7, + 254, 237, 27, 7, 254, 236, 27, 7, 254, 235, 27, 7, 254, 233, 27, 7, 254, + 232, 27, 7, 254, 231, 27, 7, 254, 230, 27, 7, 254, 229, 27, 7, 254, 228, + 27, 7, 254, 227, 27, 7, 254, 226, 27, 7, 254, 225, 27, 7, 254, 223, 27, + 7, 254, 222, 27, 7, 254, 221, 27, 7, 254, 219, 27, 7, 254, 217, 27, 7, + 254, 216, 27, 7, 254, 215, 27, 7, 254, 214, 27, 7, 254, 213, 27, 7, 254, + 212, 27, 7, 254, 211, 27, 7, 254, 210, 27, 7, 254, 209, 27, 7, 254, 208, + 27, 7, 254, 207, 27, 7, 254, 206, 27, 7, 254, 205, 27, 7, 254, 204, 27, + 7, 254, 203, 27, 7, 254, 202, 27, 7, 254, 201, 27, 7, 254, 200, 27, 7, + 254, 199, 27, 7, 254, 198, 27, 7, 254, 197, 27, 7, 254, 196, 27, 7, 254, + 195, 27, 7, 254, 194, 27, 7, 254, 193, 27, 7, 254, 192, 27, 7, 254, 191, + 27, 7, 254, 190, 27, 7, 254, 189, 27, 7, 254, 188, 27, 7, 254, 187, 27, + 7, 254, 186, 27, 7, 254, 185, 27, 7, 254, 184, 27, 7, 254, 183, 27, 7, + 254, 182, 27, 7, 254, 181, 27, 7, 254, 180, 27, 7, 254, 179, 27, 7, 254, + 178, 27, 7, 254, 177, 27, 7, 254, 176, 27, 7, 254, 175, 27, 7, 254, 174, + 27, 7, 254, 173, 27, 7, 254, 172, 27, 7, 254, 171, 27, 7, 254, 170, 27, + 7, 254, 169, 27, 7, 254, 168, 27, 7, 254, 167, 27, 7, 254, 166, 27, 7, + 254, 165, 27, 7, 254, 164, 27, 7, 254, 163, 27, 7, 254, 162, 27, 7, 254, + 161, 27, 7, 254, 160, 27, 7, 254, 159, 27, 7, 254, 158, 27, 7, 254, 157, + 27, 7, 254, 156, 27, 7, 254, 155, 27, 7, 254, 154, 27, 7, 254, 153, 27, + 7, 254, 151, 27, 7, 254, 150, 27, 7, 254, 149, 27, 7, 254, 148, 27, 7, + 254, 147, 27, 7, 254, 146, 27, 7, 254, 145, 27, 7, 254, 144, 27, 7, 254, + 143, 27, 7, 254, 142, 27, 7, 254, 141, 27, 7, 254, 140, 27, 7, 254, 139, + 27, 7, 254, 138, 27, 7, 254, 137, 27, 7, 254, 136, 27, 7, 254, 135, 27, + 7, 254, 134, 27, 7, 254, 133, 27, 7, 254, 132, 27, 7, 254, 131, 27, 7, + 254, 130, 27, 7, 254, 129, 27, 7, 254, 128, 27, 7, 254, 127, 27, 7, 254, + 126, 27, 7, 254, 125, 27, 7, 254, 124, 27, 7, 254, 123, 27, 7, 254, 122, + 27, 7, 254, 121, 27, 7, 254, 120, 27, 7, 254, 119, 27, 7, 254, 118, 27, + 7, 254, 116, 27, 7, 254, 115, 27, 7, 254, 114, 27, 7, 254, 113, 27, 7, + 254, 112, 27, 7, 254, 111, 27, 7, 254, 110, 27, 7, 254, 109, 27, 7, 254, + 108, 27, 7, 254, 107, 27, 7, 254, 106, 27, 7, 254, 105, 27, 7, 254, 103, + 27, 7, 254, 102, 27, 7, 254, 101, 27, 7, 254, 100, 27, 7, 254, 99, 27, 7, + 254, 98, 27, 7, 254, 97, 27, 7, 254, 96, 27, 7, 254, 95, 27, 7, 254, 94, + 27, 7, 254, 93, 27, 7, 254, 92, 27, 7, 254, 91, 27, 7, 254, 90, 27, 7, + 254, 89, 27, 7, 254, 88, 27, 7, 254, 87, 27, 7, 254, 86, 27, 7, 254, 85, + 27, 7, 254, 84, 27, 7, 254, 83, 27, 7, 254, 82, 27, 7, 254, 81, 27, 7, + 254, 80, 27, 7, 254, 79, 27, 7, 254, 78, 27, 7, 254, 77, 27, 7, 254, 76, + 27, 7, 254, 75, 27, 7, 254, 74, 27, 7, 254, 73, 27, 7, 254, 72, 27, 7, + 254, 71, 27, 7, 254, 70, 27, 7, 254, 69, 27, 7, 254, 68, 27, 7, 254, 67, + 27, 7, 254, 66, 27, 7, 254, 65, 27, 7, 254, 64, 27, 7, 254, 63, 27, 7, + 254, 62, 27, 7, 254, 61, 27, 7, 254, 60, 27, 7, 254, 59, 27, 7, 254, 58, + 27, 7, 254, 57, 27, 7, 254, 56, 27, 7, 254, 55, 27, 7, 254, 54, 27, 7, + 254, 53, 27, 7, 254, 52, 27, 7, 254, 51, 27, 7, 254, 50, 27, 7, 254, 49, + 27, 7, 254, 48, 27, 7, 254, 47, 27, 7, 254, 46, 27, 7, 254, 45, 27, 7, + 254, 44, 27, 7, 254, 43, 27, 7, 254, 42, 27, 7, 254, 41, 27, 7, 254, 40, + 27, 7, 254, 39, 27, 7, 254, 38, 27, 7, 254, 37, 27, 7, 254, 36, 27, 7, + 254, 35, 27, 7, 254, 33, 27, 7, 254, 32, 27, 7, 254, 31, 27, 7, 254, 30, + 27, 7, 254, 29, 27, 7, 254, 28, 27, 7, 254, 27, 27, 7, 254, 26, 27, 7, + 254, 25, 27, 7, 254, 24, 27, 7, 254, 23, 27, 7, 254, 22, 27, 7, 254, 21, + 27, 7, 254, 20, 27, 7, 254, 19, 27, 7, 254, 18, 27, 7, 254, 17, 27, 7, + 254, 16, 27, 7, 254, 15, 27, 7, 254, 14, 27, 7, 254, 13, 27, 7, 254, 12, + 27, 7, 254, 11, 27, 7, 254, 10, 27, 7, 254, 9, 27, 7, 254, 8, 27, 7, 254, + 7, 27, 7, 254, 6, 27, 7, 254, 5, 27, 7, 254, 4, 27, 7, 254, 3, 27, 7, + 254, 2, 27, 7, 254, 1, 27, 7, 254, 0, 27, 7, 253, 255, 27, 7, 253, 254, + 27, 7, 253, 253, 27, 7, 253, 252, 27, 7, 253, 251, 27, 7, 253, 250, 27, + 7, 253, 249, 27, 7, 253, 248, 27, 7, 253, 247, 27, 7, 253, 246, 27, 7, + 253, 245, 27, 7, 253, 244, 27, 7, 253, 243, 27, 7, 253, 242, 27, 7, 253, + 241, 27, 7, 253, 240, 27, 7, 253, 239, 27, 7, 253, 238, 27, 7, 253, 237, + 27, 7, 253, 236, 27, 7, 253, 235, 27, 7, 253, 234, 27, 7, 253, 233, 27, + 7, 253, 232, 27, 7, 253, 231, 27, 7, 253, 230, 27, 7, 253, 229, 27, 7, + 253, 228, 27, 7, 253, 227, 27, 7, 253, 226, 27, 7, 253, 225, 27, 7, 253, + 224, 27, 7, 253, 223, 27, 7, 253, 222, 27, 7, 253, 221, 27, 7, 253, 220, + 27, 7, 253, 219, 27, 7, 253, 218, 27, 7, 253, 217, 27, 7, 253, 216, 27, + 7, 253, 215, 27, 7, 253, 214, 27, 7, 253, 213, 27, 7, 253, 212, 27, 7, + 253, 211, 27, 7, 253, 210, 27, 7, 253, 209, 27, 7, 253, 208, 27, 7, 253, + 207, 27, 7, 253, 206, 27, 7, 253, 205, 27, 7, 253, 204, 27, 7, 253, 203, + 27, 7, 253, 202, 27, 7, 253, 201, 27, 7, 253, 200, 27, 7, 253, 199, 27, + 7, 253, 198, 27, 7, 253, 197, 27, 7, 253, 196, 27, 7, 253, 195, 27, 7, + 253, 194, 27, 7, 253, 193, 27, 7, 253, 192, 27, 7, 253, 191, 27, 7, 253, + 190, 27, 7, 253, 189, 27, 7, 253, 188, 27, 7, 253, 187, 27, 7, 253, 186, + 27, 7, 253, 185, 27, 7, 253, 184, 27, 7, 253, 183, 27, 7, 253, 182, 27, + 7, 253, 181, 27, 7, 253, 180, 27, 7, 253, 179, 27, 7, 253, 177, 27, 7, + 253, 176, 27, 7, 253, 175, 27, 7, 253, 174, 27, 7, 253, 173, 27, 7, 253, + 172, 27, 7, 253, 171, 27, 7, 253, 170, 27, 7, 253, 169, 27, 7, 253, 168, + 27, 7, 253, 167, 27, 7, 253, 164, 27, 7, 253, 163, 27, 7, 253, 162, 27, + 7, 253, 161, 27, 7, 253, 157, 27, 7, 253, 156, 27, 7, 253, 155, 27, 7, + 253, 154, 27, 7, 253, 153, 27, 7, 253, 152, 27, 7, 253, 151, 27, 7, 253, + 150, 27, 7, 253, 149, 27, 7, 253, 148, 27, 7, 253, 147, 27, 7, 253, 146, + 27, 7, 253, 145, 27, 7, 253, 144, 27, 7, 253, 143, 27, 7, 253, 142, 27, + 7, 253, 141, 27, 7, 253, 140, 27, 7, 253, 139, 27, 7, 253, 137, 27, 7, + 253, 136, 27, 7, 253, 135, 27, 7, 253, 134, 27, 7, 253, 133, 27, 7, 253, + 132, 27, 7, 253, 131, 27, 7, 253, 130, 27, 7, 253, 129, 27, 7, 253, 128, + 27, 7, 253, 127, 27, 7, 253, 126, 27, 7, 253, 125, 27, 7, 253, 124, 27, + 7, 253, 123, 27, 7, 253, 122, 27, 7, 253, 121, 27, 7, 253, 120, 27, 7, + 253, 119, 27, 7, 253, 118, 27, 7, 253, 117, 27, 7, 253, 116, 27, 7, 253, + 115, 27, 7, 253, 114, 27, 7, 253, 113, 27, 7, 253, 112, 27, 7, 253, 111, + 27, 7, 253, 110, 27, 7, 253, 109, 27, 7, 253, 108, 27, 7, 253, 107, 27, + 7, 253, 106, 27, 7, 253, 105, 27, 7, 253, 104, 27, 7, 253, 103, 27, 7, + 253, 102, 27, 7, 253, 101, 27, 7, 253, 100, 27, 7, 253, 99, 27, 7, 253, + 98, 27, 7, 253, 97, 27, 7, 253, 96, 27, 7, 253, 95, 27, 7, 253, 94, 27, + 7, 253, 93, 27, 7, 253, 92, 27, 7, 253, 91, 27, 7, 253, 90, 27, 7, 253, + 89, 27, 7, 253, 88, 27, 7, 253, 87, 27, 7, 253, 86, 27, 7, 253, 85, 27, + 7, 253, 84, 27, 7, 253, 83, 27, 7, 253, 82, 27, 7, 253, 81, 27, 7, 253, + 80, 27, 7, 253, 79, 27, 7, 253, 78, 27, 7, 253, 77, 27, 7, 253, 76, 216, + 221, 219, 245, 216, 57, 27, 7, 253, 75, 27, 7, 253, 74, 27, 7, 253, 73, + 27, 7, 253, 72, 27, 7, 253, 71, 27, 7, 253, 70, 27, 7, 253, 69, 27, 7, + 253, 68, 27, 7, 253, 67, 27, 7, 253, 66, 27, 7, 253, 65, 27, 7, 253, 64, + 199, 27, 7, 253, 63, 27, 7, 253, 62, 27, 7, 253, 61, 27, 7, 253, 60, 27, + 7, 253, 59, 27, 7, 253, 58, 27, 7, 253, 57, 27, 7, 253, 55, 27, 7, 253, + 53, 27, 7, 253, 51, 27, 7, 253, 49, 27, 7, 253, 47, 27, 7, 253, 45, 27, + 7, 253, 43, 27, 7, 253, 41, 27, 7, 253, 39, 27, 7, 253, 37, 248, 142, + 227, 36, 82, 27, 7, 253, 35, 241, 84, 227, 36, 82, 27, 7, 253, 34, 27, 7, + 253, 32, 27, 7, 253, 30, 27, 7, 253, 28, 27, 7, 253, 26, 27, 7, 253, 24, + 27, 7, 253, 22, 27, 7, 253, 20, 27, 7, 253, 18, 27, 7, 253, 17, 27, 7, + 253, 16, 27, 7, 253, 15, 27, 7, 253, 14, 27, 7, 253, 13, 27, 7, 253, 12, + 27, 7, 253, 11, 27, 7, 253, 10, 27, 7, 253, 9, 27, 7, 253, 8, 27, 7, 253, + 7, 27, 7, 253, 6, 27, 7, 253, 5, 27, 7, 253, 4, 27, 7, 253, 3, 27, 7, + 253, 2, 27, 7, 253, 1, 27, 7, 253, 0, 27, 7, 252, 255, 27, 7, 252, 254, + 27, 7, 252, 253, 27, 7, 252, 252, 27, 7, 252, 251, 27, 7, 252, 250, 27, + 7, 252, 249, 27, 7, 252, 248, 27, 7, 252, 247, 27, 7, 252, 246, 27, 7, + 252, 245, 27, 7, 252, 244, 27, 7, 252, 243, 27, 7, 252, 242, 27, 7, 252, + 241, 27, 7, 252, 240, 27, 7, 252, 239, 27, 7, 252, 238, 27, 7, 252, 237, + 27, 7, 252, 236, 27, 7, 252, 235, 27, 7, 252, 234, 27, 7, 252, 233, 27, + 7, 252, 232, 27, 7, 252, 231, 27, 7, 252, 230, 27, 7, 252, 229, 27, 7, + 252, 228, 27, 7, 252, 227, 27, 7, 252, 226, 27, 7, 252, 225, 27, 7, 252, + 224, 27, 7, 252, 223, 27, 7, 252, 222, 27, 7, 252, 221, 27, 7, 252, 220, + 27, 7, 252, 219, 27, 7, 252, 218, 27, 7, 252, 217, 27, 7, 252, 216, 27, + 7, 252, 215, 27, 7, 252, 214, 27, 7, 252, 213, 27, 7, 252, 212, 27, 7, + 252, 211, 27, 7, 252, 210, 27, 7, 252, 209, 27, 7, 252, 208, 27, 7, 252, + 207, 27, 7, 252, 206, 27, 7, 252, 205, 27, 7, 252, 204, 27, 7, 252, 203, + 27, 7, 252, 202, 27, 7, 252, 201, 27, 7, 252, 200, 27, 7, 252, 199, 27, + 7, 252, 198, 27, 7, 252, 197, 27, 7, 252, 196, 27, 7, 252, 195, 27, 7, + 252, 194, 27, 7, 252, 193, 27, 7, 252, 192, 27, 7, 252, 191, 27, 7, 252, + 190, 27, 7, 252, 189, 27, 7, 252, 188, 27, 7, 252, 187, 27, 7, 252, 186, + 27, 7, 252, 185, 27, 7, 252, 184, 27, 7, 252, 183, 27, 7, 252, 182, 27, + 7, 252, 181, 27, 7, 252, 180, 27, 7, 252, 179, 27, 7, 252, 178, 27, 7, + 252, 177, 27, 7, 252, 176, 27, 7, 252, 175, 27, 7, 252, 174, 27, 7, 252, + 173, 27, 7, 252, 172, 27, 7, 252, 171, 27, 7, 252, 170, 27, 7, 252, 169, + 27, 7, 252, 168, 27, 7, 252, 167, 27, 7, 252, 166, 27, 7, 252, 165, 27, + 7, 252, 164, 24, 1, 218, 198, 222, 136, 224, 197, 24, 1, 218, 198, 238, + 198, 239, 178, 24, 1, 218, 198, 218, 47, 224, 198, 218, 115, 24, 1, 218, + 198, 218, 47, 224, 198, 218, 116, 24, 1, 218, 198, 223, 107, 224, 197, + 24, 1, 218, 198, 212, 195, 24, 1, 218, 198, 208, 199, 224, 197, 24, 1, + 218, 198, 220, 215, 224, 197, 24, 1, 218, 198, 212, 254, 219, 169, 222, + 32, 24, 1, 218, 198, 218, 47, 219, 169, 222, 33, 218, 115, 24, 1, 218, + 198, 218, 47, 219, 169, 222, 33, 218, 116, 24, 1, 218, 198, 225, 156, 24, + 1, 218, 198, 207, 204, 225, 157, 24, 1, 218, 198, 222, 197, 24, 1, 218, + 198, 225, 153, 24, 1, 218, 198, 225, 111, 24, 1, 218, 198, 223, 186, 24, + 1, 218, 198, 213, 114, 24, 1, 218, 198, 221, 91, 24, 1, 218, 198, 229, + 163, 24, 1, 218, 198, 222, 0, 24, 1, 218, 198, 210, 179, 24, 1, 218, 198, + 222, 135, 24, 1, 218, 198, 228, 10, 24, 1, 218, 198, 227, 176, 228, 175, + 24, 1, 218, 198, 221, 101, 224, 205, 24, 1, 218, 198, 225, 160, 24, 1, + 218, 198, 219, 62, 24, 1, 218, 198, 238, 100, 24, 1, 218, 198, 219, 125, + 24, 1, 218, 198, 224, 55, 222, 170, 24, 1, 218, 198, 220, 196, 224, 208, + 24, 1, 218, 198, 106, 202, 188, 223, 100, 24, 1, 218, 198, 238, 101, 24, + 1, 218, 198, 221, 101, 221, 102, 24, 1, 218, 198, 212, 91, 24, 1, 218, + 198, 224, 190, 24, 1, 218, 198, 224, 211, 24, 1, 218, 198, 224, 31, 24, + 1, 218, 198, 230, 21, 24, 1, 218, 198, 219, 169, 227, 223, 24, 1, 218, + 198, 223, 26, 227, 223, 24, 1, 218, 198, 218, 219, 24, 1, 218, 198, 225, + 154, 24, 1, 218, 198, 222, 74, 24, 1, 218, 198, 217, 172, 24, 1, 218, + 198, 207, 201, 24, 1, 218, 198, 226, 235, 24, 1, 218, 198, 211, 251, 24, + 1, 218, 198, 209, 117, 24, 1, 218, 198, 225, 151, 24, 1, 218, 198, 229, + 170, 24, 1, 218, 198, 223, 22, 24, 1, 218, 198, 228, 188, 24, 1, 218, + 198, 224, 32, 24, 1, 218, 198, 212, 191, 24, 1, 218, 198, 227, 29, 24, 1, + 218, 198, 239, 246, 24, 1, 218, 198, 215, 211, 24, 1, 218, 198, 228, 233, + 24, 1, 218, 198, 211, 247, 24, 1, 218, 198, 225, 107, 218, 157, 24, 1, + 218, 198, 212, 247, 24, 1, 218, 198, 221, 100, 24, 1, 218, 198, 212, 230, + 221, 111, 202, 196, 24, 1, 218, 198, 220, 237, 224, 51, 24, 1, 218, 198, + 219, 164, 24, 1, 218, 198, 222, 2, 24, 1, 218, 198, 206, 231, 24, 1, 218, + 198, 222, 173, 24, 1, 218, 198, 225, 150, 24, 1, 218, 198, 222, 44, 24, + 1, 218, 198, 225, 49, 24, 1, 218, 198, 220, 251, 24, 1, 218, 198, 209, + 121, 24, 1, 218, 198, 211, 244, 24, 1, 218, 198, 219, 165, 24, 1, 218, + 198, 221, 115, 24, 1, 218, 198, 225, 158, 24, 1, 218, 198, 220, 248, 24, + 1, 218, 198, 229, 241, 24, 1, 218, 198, 221, 118, 24, 1, 218, 198, 206, + 50, 24, 1, 218, 198, 226, 239, 24, 1, 218, 198, 222, 230, 24, 1, 218, + 198, 223, 75, 24, 1, 218, 198, 225, 48, 24, 1, 218, 197, 221, 113, 24, 1, + 218, 197, 207, 204, 225, 155, 24, 1, 218, 197, 212, 152, 24, 1, 218, 197, + 213, 118, 207, 203, 24, 1, 218, 197, 227, 31, 221, 97, 24, 1, 218, 197, + 225, 55, 225, 159, 24, 1, 218, 197, 229, 92, 24, 1, 218, 197, 203, 18, + 24, 1, 218, 197, 225, 50, 24, 1, 218, 197, 230, 7, 24, 1, 218, 197, 219, + 19, 24, 1, 218, 197, 203, 96, 227, 223, 24, 1, 218, 197, 228, 29, 221, + 111, 221, 6, 24, 1, 218, 197, 221, 94, 213, 17, 24, 1, 218, 197, 222, + 249, 222, 47, 24, 1, 218, 197, 238, 98, 24, 1, 218, 197, 218, 105, 24, 1, + 218, 197, 207, 204, 221, 109, 24, 1, 218, 197, 213, 22, 222, 42, 24, 1, + 218, 197, 213, 18, 24, 1, 218, 197, 224, 198, 209, 120, 24, 1, 218, 197, + 225, 37, 225, 51, 24, 1, 218, 197, 220, 249, 221, 97, 24, 1, 218, 197, + 229, 159, 24, 1, 218, 197, 238, 99, 24, 1, 218, 197, 229, 155, 24, 1, + 218, 197, 228, 107, 24, 1, 218, 197, 219, 65, 24, 1, 218, 197, 205, 237, + 24, 1, 218, 197, 222, 137, 223, 184, 24, 1, 218, 197, 222, 172, 225, 33, + 24, 1, 218, 197, 203, 215, 24, 1, 218, 197, 215, 12, 24, 1, 218, 197, + 210, 14, 24, 1, 218, 197, 224, 210, 24, 1, 218, 197, 222, 156, 24, 1, + 218, 197, 222, 157, 228, 7, 24, 1, 218, 197, 224, 200, 24, 1, 218, 197, + 210, 230, 24, 1, 218, 197, 225, 41, 24, 1, 218, 197, 224, 36, 24, 1, 218, + 197, 221, 9, 24, 1, 218, 197, 217, 176, 24, 1, 218, 197, 224, 209, 222, + 174, 24, 1, 218, 197, 240, 31, 24, 1, 218, 197, 225, 28, 24, 1, 218, 197, + 240, 53, 24, 1, 218, 197, 229, 167, 24, 1, 218, 197, 225, 177, 222, 36, + 24, 1, 218, 197, 225, 177, 222, 12, 24, 1, 218, 197, 227, 175, 24, 1, + 218, 197, 222, 180, 24, 1, 218, 197, 221, 120, 24, 1, 218, 197, 192, 24, + 1, 218, 197, 229, 77, 24, 1, 218, 197, 222, 125, 24, 1, 168, 222, 136, + 225, 157, 24, 1, 168, 220, 214, 24, 1, 168, 202, 196, 24, 1, 168, 204, + 95, 24, 1, 168, 222, 173, 24, 1, 168, 223, 14, 24, 1, 168, 222, 143, 24, + 1, 168, 238, 108, 24, 1, 168, 225, 45, 24, 1, 168, 238, 205, 24, 1, 168, + 220, 239, 224, 91, 224, 212, 24, 1, 168, 221, 89, 225, 36, 24, 1, 168, + 225, 42, 24, 1, 168, 218, 111, 24, 1, 168, 222, 255, 24, 1, 168, 225, 53, + 247, 88, 24, 1, 168, 229, 157, 24, 1, 168, 238, 109, 24, 1, 168, 229, + 164, 24, 1, 168, 202, 214, 223, 215, 24, 1, 168, 220, 208, 24, 1, 168, + 225, 30, 24, 1, 168, 221, 119, 24, 1, 168, 225, 36, 24, 1, 168, 203, 19, + 24, 1, 168, 228, 241, 24, 1, 168, 230, 41, 24, 1, 168, 213, 113, 24, 1, + 168, 223, 8, 24, 1, 168, 210, 12, 24, 1, 168, 222, 16, 24, 1, 168, 208, + 199, 202, 199, 24, 1, 168, 211, 5, 24, 1, 168, 222, 163, 221, 6, 24, 1, + 168, 205, 236, 24, 1, 168, 223, 78, 24, 1, 168, 225, 177, 229, 166, 24, + 1, 168, 221, 102, 24, 1, 168, 222, 158, 24, 1, 168, 228, 11, 24, 1, 168, + 225, 38, 24, 1, 168, 224, 189, 24, 1, 168, 221, 96, 24, 1, 168, 209, 116, + 24, 1, 168, 222, 160, 24, 1, 168, 239, 106, 24, 1, 168, 223, 13, 24, 1, + 168, 221, 121, 24, 1, 168, 221, 117, 24, 1, 168, 247, 169, 24, 1, 168, + 205, 238, 24, 1, 168, 225, 43, 24, 1, 168, 215, 145, 24, 1, 168, 222, 46, + 24, 1, 168, 228, 28, 24, 1, 168, 208, 196, 24, 1, 168, 221, 103, 222, + 125, 24, 1, 168, 222, 38, 24, 1, 168, 229, 170, 24, 1, 168, 222, 165, 24, + 1, 168, 225, 150, 24, 1, 168, 225, 31, 24, 1, 168, 226, 239, 24, 1, 168, + 228, 175, 24, 1, 168, 222, 44, 24, 1, 168, 222, 125, 24, 1, 168, 203, + 205, 24, 1, 168, 222, 161, 24, 1, 168, 221, 106, 24, 1, 168, 221, 98, 24, + 1, 168, 228, 190, 222, 2, 24, 1, 168, 221, 104, 24, 1, 168, 223, 21, 24, + 1, 168, 225, 177, 221, 109, 24, 1, 168, 203, 110, 24, 1, 168, 223, 20, + 24, 1, 168, 212, 194, 24, 1, 168, 213, 116, 24, 1, 168, 225, 39, 24, 1, + 168, 225, 157, 24, 1, 168, 225, 49, 24, 1, 168, 229, 158, 24, 1, 168, + 225, 40, 24, 1, 168, 229, 162, 24, 1, 168, 225, 53, 218, 162, 24, 1, 168, + 202, 179, 24, 1, 168, 222, 34, 24, 1, 168, 224, 144, 24, 1, 168, 223, + 244, 24, 1, 168, 212, 250, 24, 1, 168, 229, 181, 227, 246, 24, 1, 168, + 229, 181, 240, 66, 24, 1, 168, 222, 195, 24, 1, 168, 223, 75, 24, 1, 168, + 227, 96, 24, 1, 168, 218, 123, 24, 1, 168, 219, 9, 24, 1, 168, 209, 132, + 24, 1, 134, 225, 29, 24, 1, 134, 204, 93, 24, 1, 134, 222, 32, 24, 1, + 134, 224, 197, 24, 1, 134, 222, 30, 24, 1, 134, 227, 141, 24, 1, 134, + 222, 35, 24, 1, 134, 221, 116, 24, 1, 134, 222, 179, 24, 1, 134, 221, 6, + 24, 1, 134, 203, 216, 24, 1, 134, 222, 133, 24, 1, 134, 213, 41, 24, 1, + 134, 222, 144, 24, 1, 134, 229, 165, 24, 1, 134, 209, 118, 24, 1, 134, + 213, 20, 24, 1, 134, 222, 43, 24, 1, 134, 210, 230, 24, 1, 134, 229, 170, + 24, 1, 134, 203, 98, 24, 1, 134, 228, 191, 24, 1, 134, 214, 233, 24, 1, + 134, 224, 202, 24, 1, 134, 223, 12, 24, 1, 134, 225, 125, 24, 1, 134, + 224, 208, 24, 1, 134, 213, 115, 24, 1, 134, 203, 42, 24, 1, 134, 222, 37, + 24, 1, 134, 229, 161, 225, 32, 24, 1, 134, 222, 140, 24, 1, 134, 207, + 203, 24, 1, 134, 238, 118, 24, 1, 134, 222, 130, 24, 1, 134, 240, 32, 24, + 1, 134, 223, 16, 24, 1, 134, 224, 181, 24, 1, 134, 227, 169, 24, 1, 134, + 222, 254, 24, 1, 134, 224, 50, 24, 1, 134, 224, 185, 24, 1, 134, 217, + 156, 24, 1, 134, 224, 183, 24, 1, 134, 224, 199, 24, 1, 134, 226, 222, + 24, 1, 134, 221, 108, 24, 1, 134, 225, 52, 24, 1, 134, 228, 165, 24, 1, + 134, 220, 251, 24, 1, 134, 209, 121, 24, 1, 134, 211, 244, 24, 1, 134, + 202, 179, 24, 1, 134, 229, 162, 24, 1, 134, 216, 201, 24, 1, 134, 209, + 175, 24, 1, 134, 222, 141, 24, 1, 134, 224, 204, 24, 1, 134, 221, 107, + 24, 1, 134, 229, 160, 24, 1, 134, 218, 117, 24, 1, 134, 218, 213, 24, 1, + 134, 220, 225, 24, 1, 134, 227, 175, 24, 1, 134, 222, 180, 24, 1, 134, + 224, 201, 24, 1, 134, 222, 153, 24, 1, 134, 202, 193, 24, 1, 134, 219, + 96, 24, 1, 134, 202, 192, 24, 1, 134, 223, 21, 24, 1, 134, 221, 97, 24, + 1, 134, 211, 7, 24, 1, 134, 228, 195, 24, 1, 134, 222, 169, 24, 1, 134, + 222, 138, 24, 1, 134, 207, 185, 24, 1, 134, 224, 212, 24, 1, 134, 228, + 185, 24, 1, 134, 221, 105, 24, 1, 134, 209, 119, 24, 1, 134, 225, 152, + 24, 1, 134, 222, 178, 24, 1, 134, 227, 168, 24, 1, 134, 222, 159, 24, 1, + 134, 221, 110, 24, 1, 134, 222, 16, 24, 1, 134, 238, 102, 24, 1, 134, + 228, 209, 24, 1, 134, 216, 108, 220, 45, 24, 1, 134, 210, 1, 24, 1, 134, + 208, 141, 24, 1, 134, 220, 248, 24, 1, 134, 216, 3, 24, 1, 134, 227, 225, + 24, 1, 134, 225, 7, 24, 1, 134, 226, 185, 24, 1, 134, 210, 179, 24, 1, + 134, 223, 246, 24, 1, 134, 213, 6, 24, 1, 134, 213, 16, 24, 1, 134, 228, + 137, 24, 1, 134, 221, 84, 24, 1, 134, 212, 199, 24, 1, 134, 221, 99, 24, + 1, 134, 219, 23, 24, 1, 134, 222, 100, 24, 1, 134, 212, 229, 24, 1, 134, + 217, 171, 24, 1, 134, 223, 184, 24, 1, 134, 227, 10, 24, 1, 134, 216, + 108, 223, 239, 24, 1, 134, 209, 2, 24, 1, 134, 221, 86, 24, 1, 134, 225, + 53, 213, 111, 24, 1, 134, 214, 231, 24, 1, 134, 240, 107, 24, 1, 93, 223, + 20, 24, 1, 93, 208, 147, 24, 1, 93, 225, 42, 24, 1, 93, 228, 11, 24, 1, + 93, 205, 177, 24, 1, 93, 227, 16, 24, 1, 93, 219, 168, 24, 1, 93, 211, + 255, 24, 1, 93, 216, 176, 24, 1, 93, 221, 112, 24, 1, 93, 222, 247, 24, + 1, 93, 217, 188, 24, 1, 93, 209, 232, 24, 1, 93, 222, 146, 24, 1, 93, + 228, 237, 24, 1, 93, 203, 208, 24, 1, 93, 214, 165, 24, 1, 93, 222, 170, + 24, 1, 93, 219, 165, 24, 1, 93, 208, 148, 24, 1, 93, 228, 189, 24, 1, 93, + 227, 30, 24, 1, 93, 221, 115, 24, 1, 93, 222, 122, 24, 1, 93, 225, 158, + 24, 1, 93, 222, 139, 24, 1, 93, 222, 121, 24, 1, 93, 221, 114, 24, 1, 93, + 216, 0, 24, 1, 93, 222, 34, 24, 1, 93, 219, 21, 24, 1, 93, 215, 33, 24, + 1, 93, 222, 154, 24, 1, 93, 224, 191, 24, 1, 93, 238, 96, 24, 1, 93, 222, + 142, 24, 1, 93, 222, 45, 24, 1, 93, 225, 106, 24, 1, 93, 227, 12, 24, 1, + 93, 222, 175, 24, 1, 93, 223, 4, 24, 1, 93, 210, 0, 221, 97, 24, 1, 93, + 213, 117, 24, 1, 93, 217, 181, 24, 1, 93, 223, 24, 212, 6, 24, 1, 93, + 222, 162, 221, 6, 24, 1, 93, 203, 7, 24, 1, 93, 238, 97, 24, 1, 93, 207, + 202, 24, 1, 93, 203, 22, 24, 1, 93, 218, 69, 24, 1, 93, 207, 190, 24, 1, + 93, 229, 168, 24, 1, 93, 211, 6, 24, 1, 93, 209, 120, 24, 1, 93, 205, + 239, 24, 1, 93, 204, 43, 24, 1, 93, 228, 110, 24, 1, 93, 217, 191, 24, 1, + 93, 210, 13, 24, 1, 93, 238, 117, 24, 1, 93, 222, 185, 24, 1, 93, 213, + 19, 24, 1, 93, 224, 186, 24, 1, 93, 225, 46, 24, 1, 93, 220, 212, 24, 1, + 93, 221, 254, 24, 1, 93, 238, 201, 24, 1, 93, 207, 191, 24, 1, 93, 228, + 199, 24, 1, 93, 203, 74, 24, 1, 93, 220, 249, 246, 32, 24, 1, 93, 202, + 253, 24, 1, 93, 224, 203, 24, 1, 93, 223, 9, 24, 1, 93, 218, 158, 24, 1, + 93, 202, 198, 24, 1, 93, 227, 170, 24, 1, 93, 239, 106, 24, 1, 93, 238, + 200, 24, 1, 93, 222, 132, 24, 1, 93, 229, 170, 24, 1, 93, 225, 161, 24, + 1, 93, 222, 145, 24, 1, 93, 238, 103, 24, 1, 93, 240, 108, 24, 1, 93, + 221, 87, 24, 1, 93, 218, 214, 24, 1, 93, 203, 20, 24, 1, 93, 222, 171, + 24, 1, 93, 220, 249, 248, 103, 24, 1, 93, 220, 192, 24, 1, 93, 218, 43, + 24, 1, 93, 224, 144, 24, 1, 93, 239, 104, 24, 1, 93, 223, 100, 24, 1, 93, + 223, 244, 24, 1, 93, 238, 102, 24, 1, 93, 239, 109, 75, 24, 1, 93, 223, + 185, 24, 1, 93, 217, 187, 24, 1, 93, 222, 134, 24, 1, 93, 228, 175, 24, + 1, 93, 218, 155, 24, 1, 93, 221, 100, 24, 1, 93, 203, 21, 24, 1, 93, 222, + 155, 24, 1, 93, 219, 169, 218, 252, 24, 1, 93, 239, 109, 247, 71, 24, 1, + 93, 239, 179, 24, 1, 93, 222, 39, 24, 1, 93, 63, 24, 1, 93, 208, 141, 24, + 1, 93, 78, 24, 1, 93, 75, 24, 1, 93, 228, 9, 24, 1, 93, 219, 169, 218, + 77, 24, 1, 93, 210, 18, 24, 1, 93, 209, 219, 24, 1, 93, 223, 24, 223, + 172, 236, 38, 24, 1, 93, 212, 250, 24, 1, 93, 203, 17, 24, 1, 93, 222, + 115, 24, 1, 93, 202, 203, 24, 1, 93, 202, 230, 210, 159, 24, 1, 93, 202, + 230, 245, 151, 24, 1, 93, 202, 187, 24, 1, 93, 202, 195, 24, 1, 93, 229, + 156, 24, 1, 93, 218, 212, 24, 1, 93, 222, 40, 241, 39, 24, 1, 93, 217, + 183, 24, 1, 93, 203, 214, 24, 1, 93, 240, 53, 24, 1, 93, 206, 50, 24, 1, + 93, 226, 239, 24, 1, 93, 224, 155, 24, 1, 93, 216, 75, 24, 1, 93, 216, + 202, 24, 1, 93, 222, 114, 24, 1, 93, 222, 203, 24, 1, 93, 212, 242, 24, + 1, 93, 212, 229, 24, 1, 93, 239, 109, 216, 111, 24, 1, 93, 201, 201, 24, + 1, 93, 218, 167, 24, 1, 93, 227, 10, 24, 1, 93, 229, 26, 24, 1, 93, 224, + 240, 24, 1, 93, 192, 24, 1, 93, 225, 103, 24, 1, 93, 209, 122, 24, 1, 93, + 229, 100, 24, 1, 93, 224, 54, 24, 1, 93, 209, 152, 24, 1, 93, 240, 77, + 24, 1, 93, 238, 90, 24, 1, 218, 196, 173, 24, 1, 218, 196, 68, 24, 1, + 218, 196, 228, 209, 24, 1, 218, 196, 241, 161, 24, 1, 218, 196, 216, 135, + 24, 1, 218, 196, 210, 1, 24, 1, 218, 196, 220, 248, 24, 1, 218, 196, 228, + 113, 24, 1, 218, 196, 216, 3, 24, 1, 218, 196, 216, 50, 24, 1, 218, 196, + 225, 7, 24, 1, 218, 196, 210, 18, 24, 1, 218, 196, 223, 23, 24, 1, 218, + 196, 222, 46, 24, 1, 218, 196, 226, 185, 24, 1, 218, 196, 210, 179, 24, + 1, 218, 196, 213, 6, 24, 1, 218, 196, 212, 162, 24, 1, 218, 196, 213, + 113, 24, 1, 218, 196, 228, 137, 24, 1, 218, 196, 229, 170, 24, 1, 218, + 196, 221, 55, 24, 1, 218, 196, 221, 84, 24, 1, 218, 196, 222, 17, 24, 1, + 218, 196, 202, 229, 24, 1, 218, 196, 212, 199, 24, 1, 218, 196, 198, 24, + 1, 218, 196, 221, 118, 24, 1, 218, 196, 218, 212, 24, 1, 218, 196, 221, + 99, 24, 1, 218, 196, 203, 214, 24, 1, 218, 196, 219, 23, 24, 1, 218, 196, + 215, 145, 24, 1, 218, 196, 222, 100, 24, 1, 218, 196, 216, 75, 24, 1, + 218, 196, 229, 180, 24, 1, 218, 196, 222, 131, 24, 1, 218, 196, 222, 182, + 24, 1, 218, 196, 212, 242, 24, 1, 218, 196, 217, 188, 24, 1, 218, 196, + 239, 179, 24, 1, 218, 196, 204, 111, 24, 1, 218, 196, 227, 148, 24, 1, + 218, 196, 227, 10, 24, 1, 218, 196, 229, 26, 24, 1, 218, 196, 225, 44, + 24, 1, 218, 196, 216, 107, 24, 1, 218, 196, 192, 24, 1, 218, 196, 224, + 82, 24, 1, 218, 196, 225, 52, 24, 1, 218, 196, 209, 132, 24, 1, 218, 196, + 228, 244, 24, 1, 218, 196, 214, 251, 24, 1, 218, 196, 204, 162, 223, 249, + 1, 210, 22, 223, 249, 1, 222, 151, 223, 249, 1, 202, 247, 223, 249, 1, + 224, 112, 223, 249, 1, 249, 32, 223, 249, 1, 244, 212, 223, 249, 1, 63, + 223, 249, 1, 218, 192, 223, 249, 1, 229, 139, 223, 249, 1, 237, 95, 223, + 249, 1, 244, 188, 223, 249, 1, 246, 98, 223, 249, 1, 229, 200, 223, 249, + 1, 220, 46, 223, 249, 1, 225, 158, 223, 249, 1, 222, 68, 223, 249, 1, + 185, 223, 249, 1, 220, 18, 223, 249, 1, 78, 223, 249, 1, 215, 227, 223, + 249, 1, 213, 11, 223, 249, 1, 209, 91, 223, 249, 1, 241, 189, 223, 249, + 1, 204, 111, 223, 249, 1, 74, 223, 249, 1, 229, 26, 223, 249, 1, 228, 17, + 223, 249, 1, 228, 113, 223, 249, 1, 237, 147, 223, 249, 1, 216, 57, 223, + 249, 1, 209, 165, 223, 249, 17, 202, 84, 223, 249, 17, 105, 223, 249, 17, + 108, 223, 249, 17, 147, 223, 249, 17, 149, 223, 249, 17, 170, 223, 249, + 17, 195, 223, 249, 17, 213, 111, 223, 249, 17, 199, 223, 249, 17, 222, + 63, 223, 249, 244, 166, 223, 249, 52, 244, 166, 248, 212, 206, 83, 1, + 241, 74, 248, 212, 206, 83, 1, 173, 248, 212, 206, 83, 1, 214, 177, 248, + 212, 206, 83, 1, 240, 108, 248, 212, 206, 83, 1, 225, 47, 248, 212, 206, + 83, 1, 203, 8, 248, 212, 206, 83, 1, 238, 249, 248, 212, 206, 83, 1, 243, + 238, 248, 212, 206, 83, 1, 228, 243, 248, 212, 206, 83, 1, 230, 101, 248, + 212, 206, 83, 1, 235, 253, 248, 212, 206, 83, 1, 204, 111, 248, 212, 206, + 83, 1, 202, 17, 248, 212, 206, 83, 1, 238, 194, 248, 212, 206, 83, 1, + 243, 113, 248, 212, 206, 83, 1, 246, 238, 248, 212, 206, 83, 1, 206, 171, + 248, 212, 206, 83, 1, 135, 248, 212, 206, 83, 1, 249, 32, 248, 212, 206, + 83, 1, 204, 163, 248, 212, 206, 83, 1, 203, 46, 248, 212, 206, 83, 1, + 185, 248, 212, 206, 83, 1, 204, 108, 248, 212, 206, 83, 1, 63, 248, 212, + 206, 83, 1, 78, 248, 212, 206, 83, 1, 220, 18, 248, 212, 206, 83, 1, 68, + 248, 212, 206, 83, 1, 241, 161, 248, 212, 206, 83, 1, 74, 248, 212, 206, + 83, 1, 75, 248, 212, 206, 83, 39, 138, 208, 161, 248, 212, 206, 83, 39, + 124, 208, 161, 248, 212, 206, 83, 39, 224, 150, 208, 161, 248, 212, 206, + 83, 39, 226, 253, 208, 161, 248, 212, 206, 83, 39, 236, 242, 208, 161, + 248, 212, 206, 83, 239, 102, 211, 61, 119, 117, 22, 229, 197, 119, 117, + 22, 229, 193, 119, 117, 22, 229, 97, 119, 117, 22, 229, 63, 119, 117, 22, + 229, 218, 119, 117, 22, 229, 215, 119, 117, 22, 228, 200, 119, 117, 22, + 228, 172, 119, 117, 22, 229, 199, 119, 117, 22, 229, 154, 119, 117, 22, + 230, 17, 119, 117, 22, 230, 14, 119, 117, 22, 229, 5, 119, 117, 22, 229, + 2, 119, 117, 22, 229, 212, 119, 117, 22, 229, 210, 119, 117, 22, 228, + 202, 119, 117, 22, 228, 201, 119, 117, 22, 229, 23, 119, 117, 22, 228, + 247, 119, 117, 22, 229, 99, 119, 117, 22, 229, 98, 119, 117, 22, 230, 32, + 119, 117, 22, 229, 214, 119, 117, 22, 228, 163, 119, 117, 22, 228, 154, + 119, 117, 22, 230, 40, 119, 117, 22, 230, 33, 119, 117, 109, 206, 61, + 119, 117, 109, 221, 90, 119, 117, 109, 227, 251, 119, 117, 109, 237, 76, + 119, 117, 109, 221, 230, 119, 117, 109, 216, 167, 119, 117, 109, 222, 1, + 119, 117, 109, 217, 100, 119, 117, 109, 203, 62, 119, 117, 109, 236, 221, + 119, 117, 109, 225, 67, 119, 117, 109, 246, 174, 119, 117, 109, 223, 28, + 119, 117, 109, 236, 157, 119, 117, 109, 218, 85, 119, 117, 109, 221, 95, + 119, 117, 109, 223, 65, 119, 117, 109, 250, 34, 119, 117, 109, 203, 178, + 119, 117, 109, 247, 15, 119, 117, 131, 246, 67, 207, 199, 119, 117, 131, + 246, 67, 212, 13, 119, 117, 131, 246, 67, 229, 172, 119, 117, 131, 246, + 67, 229, 130, 119, 117, 131, 246, 67, 211, 4, 119, 117, 131, 246, 67, + 236, 123, 119, 117, 131, 246, 67, 209, 206, 119, 117, 2, 205, 173, 209, + 44, 119, 117, 2, 205, 173, 208, 9, 246, 229, 119, 117, 2, 246, 67, 246, + 163, 119, 117, 2, 205, 173, 209, 69, 119, 117, 2, 205, 173, 240, 50, 119, + 117, 2, 203, 136, 221, 85, 119, 117, 2, 203, 136, 216, 59, 119, 117, 2, + 203, 136, 208, 124, 119, 117, 2, 203, 136, 240, 89, 119, 117, 2, 205, + 173, 214, 159, 119, 117, 2, 225, 6, 211, 8, 119, 117, 2, 205, 173, 221, + 134, 119, 117, 2, 235, 167, 203, 81, 119, 117, 2, 203, 177, 119, 117, 2, + 246, 67, 207, 252, 215, 216, 119, 117, 17, 202, 84, 119, 117, 17, 105, + 119, 117, 17, 108, 119, 117, 17, 147, 119, 117, 17, 149, 119, 117, 17, + 170, 119, 117, 17, 195, 119, 117, 17, 213, 111, 119, 117, 17, 199, 119, + 117, 17, 222, 63, 119, 117, 42, 209, 147, 119, 117, 42, 236, 10, 119, + 117, 42, 209, 153, 209, 34, 119, 117, 42, 224, 113, 119, 117, 42, 236, + 12, 224, 113, 119, 117, 42, 209, 153, 248, 68, 119, 117, 42, 208, 72, + 119, 117, 2, 205, 173, 226, 234, 119, 117, 2, 203, 133, 119, 117, 2, 236, + 216, 119, 117, 2, 209, 59, 236, 216, 119, 117, 2, 201, 247, 209, 102, + 119, 117, 2, 236, 141, 119, 117, 2, 221, 148, 119, 117, 2, 203, 169, 119, + 117, 2, 221, 88, 119, 117, 2, 250, 18, 119, 117, 2, 207, 129, 246, 228, + 119, 117, 2, 225, 6, 208, 12, 119, 117, 2, 209, 207, 119, 117, 2, 227, 7, + 119, 117, 2, 223, 201, 119, 117, 2, 246, 67, 237, 143, 226, 212, 221, 93, + 221, 92, 119, 117, 2, 246, 67, 245, 109, 208, 3, 119, 117, 2, 246, 67, + 207, 127, 119, 117, 2, 246, 67, 207, 128, 246, 86, 119, 117, 2, 246, 67, + 217, 186, 244, 135, 119, 117, 2, 246, 67, 221, 141, 208, 132, 119, 117, + 246, 39, 2, 208, 7, 119, 117, 246, 39, 2, 203, 48, 119, 117, 246, 39, 2, + 227, 93, 119, 117, 246, 39, 2, 227, 250, 119, 117, 246, 39, 2, 203, 132, + 119, 117, 246, 39, 2, 229, 6, 119, 117, 246, 39, 2, 237, 73, 119, 117, + 246, 39, 2, 223, 242, 119, 117, 246, 39, 2, 209, 45, 119, 117, 246, 39, + 2, 208, 17, 119, 117, 246, 39, 2, 218, 205, 119, 117, 246, 39, 2, 229, + 142, 119, 117, 246, 39, 2, 237, 133, 119, 117, 246, 39, 2, 206, 80, 119, + 117, 246, 39, 2, 240, 86, 119, 117, 246, 39, 2, 203, 88, 119, 117, 246, + 39, 2, 207, 246, 119, 117, 246, 39, 2, 228, 158, 119, 117, 246, 39, 2, + 204, 153, 111, 1, 185, 111, 1, 249, 32, 111, 1, 11, 185, 111, 1, 218, 98, + 111, 1, 192, 111, 1, 224, 158, 111, 1, 250, 126, 192, 111, 1, 240, 108, + 111, 1, 206, 86, 111, 1, 205, 231, 111, 1, 210, 22, 111, 1, 244, 212, + 111, 1, 11, 207, 241, 111, 1, 11, 210, 22, 111, 1, 207, 241, 111, 1, 244, + 120, 111, 1, 201, 201, 111, 1, 222, 104, 111, 1, 11, 221, 227, 111, 1, + 250, 126, 201, 201, 111, 1, 221, 227, 111, 1, 221, 213, 111, 1, 228, 113, + 111, 1, 226, 198, 111, 1, 227, 161, 111, 1, 227, 150, 111, 1, 208, 187, + 111, 1, 243, 121, 111, 1, 208, 179, 111, 1, 243, 120, 111, 1, 173, 111, + 1, 239, 8, 111, 1, 11, 173, 111, 1, 217, 126, 111, 1, 217, 103, 111, 1, + 222, 203, 111, 1, 222, 152, 111, 1, 250, 126, 222, 203, 111, 1, 152, 111, + 1, 203, 182, 111, 1, 238, 119, 111, 1, 238, 94, 111, 1, 207, 251, 111, 1, + 241, 239, 111, 1, 221, 11, 111, 1, 220, 250, 111, 1, 208, 10, 111, 1, + 241, 249, 111, 1, 11, 208, 10, 111, 1, 11, 241, 249, 111, 1, 216, 133, + 208, 10, 111, 1, 213, 90, 111, 1, 211, 164, 111, 1, 202, 80, 111, 1, 202, + 8, 111, 1, 208, 20, 111, 1, 241, 255, 111, 1, 11, 208, 20, 111, 1, 215, + 36, 111, 1, 202, 116, 111, 1, 202, 9, 111, 1, 201, 235, 111, 1, 201, 215, + 111, 1, 250, 126, 201, 235, 111, 1, 201, 207, 111, 1, 201, 214, 111, 1, + 204, 111, 111, 1, 251, 73, 111, 1, 237, 12, 111, 1, 223, 70, 111, 2, 250, + 65, 111, 2, 216, 133, 205, 184, 111, 2, 216, 133, 250, 65, 111, 22, 2, + 63, 111, 22, 2, 252, 25, 111, 22, 2, 251, 69, 111, 22, 2, 250, 231, 111, + 22, 2, 250, 223, 111, 22, 2, 78, 111, 22, 2, 220, 18, 111, 22, 2, 204, 0, + 111, 22, 2, 204, 144, 111, 22, 2, 74, 111, 22, 2, 241, 92, 111, 22, 2, + 241, 78, 111, 22, 2, 220, 70, 111, 22, 2, 75, 111, 22, 2, 235, 171, 111, + 22, 2, 235, 170, 111, 22, 2, 235, 169, 111, 22, 2, 230, 234, 111, 22, 2, + 231, 110, 111, 22, 2, 231, 83, 111, 22, 2, 230, 197, 111, 22, 2, 231, 24, + 111, 22, 2, 68, 111, 22, 2, 207, 39, 111, 22, 2, 207, 38, 111, 22, 2, + 207, 37, 111, 22, 2, 206, 178, 111, 22, 2, 207, 21, 111, 22, 2, 206, 241, + 111, 22, 2, 203, 124, 111, 22, 2, 203, 11, 111, 22, 2, 251, 109, 111, 22, + 2, 251, 105, 111, 22, 2, 241, 21, 111, 22, 2, 215, 189, 241, 21, 111, 22, + 2, 241, 28, 111, 22, 2, 215, 189, 241, 28, 111, 22, 2, 251, 64, 111, 22, + 2, 241, 145, 111, 22, 2, 250, 34, 111, 22, 2, 219, 216, 111, 22, 2, 223, + 163, 111, 22, 2, 222, 205, 111, 143, 216, 16, 111, 143, 208, 145, 216, + 16, 111, 143, 55, 111, 143, 56, 111, 1, 208, 159, 111, 1, 208, 158, 111, + 1, 208, 157, 111, 1, 208, 156, 111, 1, 208, 155, 111, 1, 208, 154, 111, + 1, 208, 153, 111, 1, 216, 133, 208, 160, 111, 1, 216, 133, 208, 159, 111, + 1, 216, 133, 208, 157, 111, 1, 216, 133, 208, 156, 111, 1, 216, 133, 208, + 155, 111, 1, 216, 133, 208, 153, 67, 1, 250, 126, 74, 172, 1, 250, 126, + 203, 52, 100, 1, 237, 171, 100, 1, 203, 196, 100, 1, 219, 184, 100, 1, + 210, 69, 100, 1, 240, 174, 100, 1, 230, 54, 100, 1, 159, 100, 1, 249, + 255, 100, 1, 245, 51, 100, 1, 206, 164, 100, 1, 239, 75, 100, 1, 146, + 100, 1, 219, 185, 223, 163, 100, 1, 245, 52, 194, 100, 1, 240, 175, 223, + 163, 100, 1, 230, 55, 226, 185, 100, 1, 217, 1, 194, 100, 1, 209, 110, + 100, 1, 212, 45, 244, 2, 100, 1, 244, 2, 100, 1, 229, 48, 100, 1, 212, + 45, 230, 184, 100, 1, 236, 225, 100, 1, 227, 162, 100, 1, 216, 62, 100, + 1, 226, 185, 100, 1, 223, 163, 100, 1, 230, 184, 100, 1, 194, 100, 1, + 226, 186, 223, 163, 100, 1, 223, 164, 226, 185, 100, 1, 230, 185, 226, + 185, 100, 1, 215, 94, 230, 184, 100, 1, 226, 186, 3, 243, 85, 100, 1, + 223, 164, 3, 243, 85, 100, 1, 230, 185, 3, 243, 85, 100, 1, 230, 185, 3, + 187, 231, 7, 25, 55, 100, 1, 215, 94, 3, 243, 85, 100, 1, 215, 94, 3, 70, + 56, 100, 1, 226, 186, 194, 100, 1, 223, 164, 194, 100, 1, 230, 185, 194, + 100, 1, 215, 94, 194, 100, 1, 226, 186, 223, 164, 194, 100, 1, 223, 164, + 226, 186, 194, 100, 1, 230, 185, 226, 186, 194, 100, 1, 215, 94, 230, + 185, 194, 100, 1, 230, 185, 215, 94, 3, 243, 85, 100, 1, 230, 185, 223, + 163, 100, 1, 230, 185, 223, 164, 194, 100, 1, 215, 94, 210, 69, 100, 1, + 215, 94, 210, 70, 146, 100, 1, 215, 94, 219, 184, 100, 1, 215, 94, 219, + 185, 146, 100, 1, 210, 70, 194, 100, 1, 210, 70, 217, 1, 194, 100, 1, + 204, 144, 100, 1, 204, 40, 100, 1, 204, 145, 146, 100, 1, 215, 94, 223, + 163, 100, 1, 215, 94, 226, 185, 100, 1, 230, 55, 217, 1, 194, 100, 1, + 239, 76, 217, 1, 194, 100, 1, 215, 94, 230, 54, 100, 1, 215, 94, 230, 55, + 146, 100, 1, 63, 100, 1, 212, 45, 219, 195, 100, 1, 220, 97, 100, 1, 78, + 100, 1, 250, 176, 100, 1, 75, 100, 1, 74, 100, 1, 231, 110, 100, 1, 212, + 228, 75, 100, 1, 207, 17, 100, 1, 241, 161, 100, 1, 212, 45, 241, 147, + 100, 1, 215, 209, 75, 100, 1, 212, 45, 241, 161, 100, 1, 163, 75, 100, 1, + 203, 52, 100, 1, 68, 100, 1, 240, 238, 100, 1, 203, 147, 100, 1, 106, + 223, 163, 100, 1, 163, 68, 100, 1, 215, 209, 68, 100, 1, 207, 18, 100, 1, + 212, 45, 68, 100, 1, 220, 15, 100, 1, 219, 195, 100, 1, 219, 216, 100, 1, + 204, 111, 100, 1, 204, 0, 100, 1, 204, 30, 100, 1, 204, 53, 100, 1, 203, + 230, 100, 1, 223, 72, 68, 100, 1, 223, 72, 78, 100, 1, 223, 72, 75, 100, + 1, 223, 72, 63, 100, 1, 218, 235, 250, 231, 100, 1, 218, 235, 250, 247, + 100, 1, 212, 45, 241, 92, 100, 1, 212, 45, 250, 231, 100, 1, 212, 45, + 220, 31, 100, 1, 125, 226, 185, 100, 251, 88, 49, 236, 106, 214, 172, + 100, 251, 88, 224, 150, 236, 106, 214, 172, 100, 251, 88, 50, 236, 106, + 214, 172, 100, 251, 88, 124, 80, 214, 172, 100, 251, 88, 224, 150, 80, + 214, 172, 100, 251, 88, 138, 80, 214, 172, 100, 251, 88, 250, 40, 214, + 172, 100, 251, 88, 250, 40, 227, 213, 214, 172, 100, 251, 88, 250, 40, + 209, 226, 100, 251, 88, 250, 40, 209, 248, 100, 251, 88, 250, 40, 188, + 113, 100, 251, 88, 250, 40, 235, 206, 113, 100, 251, 88, 250, 40, 209, + 227, 113, 100, 251, 88, 138, 165, 100, 251, 88, 138, 208, 244, 165, 100, + 251, 88, 138, 237, 253, 100, 251, 88, 138, 163, 237, 253, 100, 251, 88, + 138, 243, 85, 100, 251, 88, 138, 246, 61, 100, 251, 88, 138, 227, 114, + 100, 251, 88, 138, 204, 75, 100, 251, 88, 138, 206, 38, 100, 251, 88, + 124, 165, 100, 251, 88, 124, 208, 244, 165, 100, 251, 88, 124, 237, 253, + 100, 251, 88, 124, 163, 237, 253, 100, 251, 88, 124, 243, 85, 100, 251, + 88, 124, 246, 61, 100, 251, 88, 124, 227, 114, 100, 251, 88, 124, 204, + 75, 100, 251, 88, 124, 206, 38, 100, 251, 88, 124, 47, 100, 2, 158, 3, + 245, 130, 100, 209, 68, 1, 214, 150, 100, 52, 82, 100, 217, 179, 246, + 126, 239, 102, 211, 61, 212, 215, 239, 158, 1, 219, 201, 212, 215, 239, + 158, 245, 190, 219, 201, 212, 215, 239, 158, 121, 211, 75, 212, 215, 239, + 158, 112, 211, 75, 60, 31, 16, 217, 195, 60, 31, 16, 244, 146, 60, 31, + 16, 218, 239, 60, 31, 16, 219, 192, 241, 126, 60, 31, 16, 219, 192, 243, + 171, 60, 31, 16, 206, 73, 241, 126, 60, 31, 16, 206, 73, 243, 171, 60, + 31, 16, 229, 221, 60, 31, 16, 210, 86, 60, 31, 16, 219, 83, 60, 31, 16, + 202, 219, 60, 31, 16, 202, 220, 243, 171, 60, 31, 16, 228, 226, 60, 31, + 16, 250, 171, 241, 126, 60, 31, 16, 240, 206, 241, 126, 60, 31, 16, 209, + 163, 60, 31, 16, 229, 176, 60, 31, 16, 250, 161, 60, 31, 16, 250, 162, + 243, 171, 60, 31, 16, 210, 93, 60, 31, 16, 209, 50, 60, 31, 16, 220, 42, + 250, 124, 60, 31, 16, 238, 23, 250, 124, 60, 31, 16, 217, 194, 60, 31, + 16, 246, 190, 60, 31, 16, 206, 62, 60, 31, 16, 230, 206, 250, 124, 60, + 31, 16, 229, 178, 250, 124, 60, 31, 16, 229, 177, 250, 124, 60, 31, 16, + 214, 210, 60, 31, 16, 219, 73, 60, 31, 16, 211, 84, 250, 164, 60, 31, 16, + 219, 191, 250, 124, 60, 31, 16, 206, 72, 250, 124, 60, 31, 16, 250, 165, + 250, 124, 60, 31, 16, 250, 159, 60, 31, 16, 229, 38, 60, 31, 16, 216, 69, + 60, 31, 16, 218, 165, 250, 124, 60, 31, 16, 208, 217, 60, 31, 16, 250, + 229, 60, 31, 16, 214, 153, 60, 31, 16, 210, 97, 250, 124, 60, 31, 16, + 210, 97, 224, 221, 211, 82, 60, 31, 16, 219, 186, 250, 124, 60, 31, 16, + 209, 86, 60, 31, 16, 227, 200, 60, 31, 16, 242, 2, 60, 31, 16, 208, 87, + 60, 31, 16, 209, 134, 60, 31, 16, 228, 229, 60, 31, 16, 250, 171, 240, + 206, 222, 226, 60, 31, 16, 239, 110, 250, 124, 60, 31, 16, 231, 62, 60, + 31, 16, 208, 57, 250, 124, 60, 31, 16, 229, 224, 208, 56, 60, 31, 16, + 219, 11, 60, 31, 16, 217, 199, 60, 31, 16, 229, 7, 60, 31, 16, 246, 110, + 250, 124, 60, 31, 16, 216, 177, 60, 31, 16, 219, 86, 250, 124, 60, 31, + 16, 219, 84, 250, 124, 60, 31, 16, 235, 160, 60, 31, 16, 223, 82, 60, 31, + 16, 218, 217, 60, 31, 16, 229, 8, 251, 9, 60, 31, 16, 208, 57, 251, 9, + 60, 31, 16, 211, 55, 60, 31, 16, 237, 240, 60, 31, 16, 230, 206, 222, + 226, 60, 31, 16, 220, 42, 222, 226, 60, 31, 16, 219, 192, 222, 226, 60, + 31, 16, 218, 216, 60, 31, 16, 228, 248, 60, 31, 16, 218, 215, 60, 31, 16, + 228, 228, 60, 31, 16, 219, 12, 222, 226, 60, 31, 16, 229, 177, 222, 227, + 250, 202, 60, 31, 16, 229, 178, 222, 227, 250, 202, 60, 31, 16, 202, 217, + 60, 31, 16, 250, 162, 222, 226, 60, 31, 16, 250, 163, 210, 94, 222, 226, + 60, 31, 16, 202, 218, 60, 31, 16, 228, 227, 60, 31, 16, 241, 121, 60, 31, + 16, 246, 191, 60, 31, 16, 224, 122, 230, 205, 60, 31, 16, 206, 73, 222, + 226, 60, 31, 16, 218, 165, 222, 226, 60, 31, 16, 217, 200, 222, 226, 60, + 31, 16, 220, 38, 60, 31, 16, 250, 189, 60, 31, 16, 226, 195, 60, 31, 16, + 219, 84, 222, 226, 60, 31, 16, 219, 86, 222, 226, 60, 31, 16, 240, 244, + 219, 85, 60, 31, 16, 228, 135, 60, 31, 16, 250, 190, 60, 31, 16, 208, 57, + 222, 226, 60, 31, 16, 241, 124, 60, 31, 16, 210, 97, 222, 226, 60, 31, + 16, 210, 87, 60, 31, 16, 246, 110, 222, 226, 60, 31, 16, 241, 43, 60, 31, + 16, 214, 154, 222, 226, 60, 31, 16, 203, 163, 229, 38, 60, 31, 16, 208, + 54, 60, 31, 16, 217, 201, 60, 31, 16, 208, 58, 60, 31, 16, 208, 55, 60, + 31, 16, 217, 198, 60, 31, 16, 208, 53, 60, 31, 16, 217, 197, 60, 31, 16, + 238, 22, 60, 31, 16, 250, 116, 60, 31, 16, 240, 244, 250, 116, 60, 31, + 16, 219, 186, 222, 226, 60, 31, 16, 209, 85, 241, 1, 60, 31, 16, 209, 85, + 240, 205, 60, 31, 16, 209, 87, 250, 166, 60, 31, 16, 209, 79, 230, 19, + 250, 158, 60, 31, 16, 229, 223, 60, 31, 16, 241, 80, 60, 31, 16, 203, 14, + 229, 220, 60, 31, 16, 203, 14, 250, 202, 60, 31, 16, 211, 83, 60, 31, 16, + 229, 39, 250, 202, 60, 31, 16, 243, 172, 250, 124, 60, 31, 16, 228, 230, + 250, 124, 60, 31, 16, 228, 230, 251, 9, 60, 31, 16, 228, 230, 222, 226, + 60, 31, 16, 250, 165, 222, 226, 60, 31, 16, 250, 167, 60, 31, 16, 243, + 171, 60, 31, 16, 208, 68, 60, 31, 16, 209, 125, 60, 31, 16, 228, 252, 60, + 31, 16, 227, 205, 241, 73, 246, 100, 60, 31, 16, 227, 205, 242, 3, 246, + 101, 60, 31, 16, 227, 205, 208, 71, 246, 101, 60, 31, 16, 227, 205, 209, + 136, 246, 101, 60, 31, 16, 227, 205, 231, 57, 246, 100, 60, 31, 16, 238, + 23, 222, 227, 250, 202, 60, 31, 16, 238, 23, 219, 74, 250, 112, 60, 31, + 16, 238, 23, 219, 74, 244, 6, 60, 31, 16, 243, 196, 60, 31, 16, 243, 197, + 219, 74, 250, 113, 229, 220, 60, 31, 16, 243, 197, 219, 74, 250, 113, + 250, 202, 60, 31, 16, 243, 197, 219, 74, 244, 6, 60, 31, 16, 208, 76, 60, + 31, 16, 250, 117, 60, 31, 16, 231, 64, 60, 31, 16, 243, 219, 60, 31, 16, + 251, 75, 218, 52, 250, 118, 60, 31, 16, 251, 75, 250, 115, 60, 31, 16, + 251, 75, 250, 118, 60, 31, 16, 251, 75, 224, 215, 60, 31, 16, 251, 75, + 224, 226, 60, 31, 16, 251, 75, 238, 24, 60, 31, 16, 251, 75, 238, 21, 60, + 31, 16, 251, 75, 218, 52, 238, 24, 60, 31, 16, 225, 84, 217, 207, 235, + 158, 60, 31, 16, 225, 84, 251, 11, 217, 207, 235, 158, 60, 31, 16, 225, + 84, 244, 5, 235, 158, 60, 31, 16, 225, 84, 251, 11, 244, 5, 235, 158, 60, + 31, 16, 225, 84, 208, 63, 235, 158, 60, 31, 16, 225, 84, 208, 77, 60, 31, + 16, 225, 84, 209, 130, 235, 158, 60, 31, 16, 225, 84, 209, 130, 227, 209, + 235, 158, 60, 31, 16, 225, 84, 227, 209, 235, 158, 60, 31, 16, 225, 84, + 218, 95, 235, 158, 60, 31, 16, 230, 213, 209, 156, 235, 159, 60, 31, 16, + 250, 163, 209, 156, 235, 159, 60, 31, 16, 240, 80, 209, 127, 60, 31, 16, + 240, 80, 224, 46, 60, 31, 16, 240, 80, 243, 202, 60, 31, 16, 225, 84, + 206, 66, 235, 158, 60, 31, 16, 225, 84, 217, 206, 235, 158, 60, 31, 16, + 225, 84, 218, 95, 209, 130, 235, 158, 60, 31, 16, 238, 19, 223, 164, 250, + 166, 60, 31, 16, 238, 19, 223, 164, 243, 170, 60, 31, 16, 241, 90, 230, + 19, 239, 110, 205, 171, 60, 31, 16, 231, 63, 60, 31, 16, 231, 61, 60, 31, + 16, 239, 110, 250, 125, 244, 4, 235, 157, 60, 31, 16, 239, 110, 243, 217, + 185, 60, 31, 16, 239, 110, 243, 217, 223, 82, 60, 31, 16, 239, 110, 223, + 77, 235, 158, 60, 31, 16, 239, 110, 243, 217, 243, 233, 60, 31, 16, 239, + 110, 212, 64, 243, 216, 243, 233, 60, 31, 16, 239, 110, 243, 217, 229, + 201, 60, 31, 16, 239, 110, 243, 217, 202, 17, 60, 31, 16, 239, 110, 243, + 217, 222, 101, 229, 220, 60, 31, 16, 239, 110, 243, 217, 222, 101, 250, + 202, 60, 31, 16, 239, 110, 225, 128, 246, 102, 243, 202, 60, 31, 16, 239, + 110, 225, 128, 246, 102, 224, 46, 60, 31, 16, 240, 27, 212, 64, 246, 102, + 206, 65, 60, 31, 16, 239, 110, 212, 64, 246, 102, 210, 98, 60, 31, 16, + 239, 110, 222, 229, 60, 31, 16, 246, 103, 201, 241, 60, 31, 16, 246, 103, + 229, 37, 60, 31, 16, 246, 103, 211, 219, 60, 31, 16, 239, 110, 235, 206, + 203, 13, 209, 131, 60, 31, 16, 239, 110, 241, 91, 250, 191, 60, 31, 16, + 203, 13, 208, 64, 60, 31, 16, 243, 210, 208, 64, 60, 31, 16, 243, 210, + 209, 131, 60, 31, 16, 243, 210, 250, 168, 242, 3, 243, 105, 60, 31, 16, + 243, 210, 224, 44, 209, 135, 243, 105, 60, 31, 16, 243, 210, 243, 193, + 240, 218, 243, 105, 60, 31, 16, 243, 210, 208, 74, 220, 48, 243, 105, 60, + 31, 16, 203, 13, 250, 168, 242, 3, 243, 105, 60, 31, 16, 203, 13, 224, + 44, 209, 135, 243, 105, 60, 31, 16, 203, 13, 243, 193, 240, 218, 243, + 105, 60, 31, 16, 203, 13, 208, 74, 220, 48, 243, 105, 60, 31, 16, 238, + 175, 243, 209, 60, 31, 16, 238, 175, 203, 12, 60, 31, 16, 243, 218, 250, + 168, 224, 123, 60, 31, 16, 243, 218, 250, 168, 224, 255, 60, 31, 16, 243, + 218, 243, 171, 60, 31, 16, 243, 218, 209, 77, 60, 31, 16, 212, 130, 209, + 77, 60, 31, 16, 212, 130, 209, 78, 243, 155, 60, 31, 16, 212, 130, 209, + 78, 208, 65, 60, 31, 16, 212, 130, 209, 78, 209, 123, 60, 31, 16, 212, + 130, 250, 88, 60, 31, 16, 212, 130, 250, 89, 243, 155, 60, 31, 16, 212, + 130, 250, 89, 208, 65, 60, 31, 16, 212, 130, 250, 89, 209, 123, 60, 31, + 16, 243, 194, 238, 156, 60, 31, 16, 243, 201, 219, 216, 60, 31, 16, 211, + 71, 60, 31, 16, 250, 109, 185, 60, 31, 16, 250, 109, 205, 171, 60, 31, + 16, 250, 109, 239, 8, 60, 31, 16, 250, 109, 243, 233, 60, 31, 16, 250, + 109, 229, 201, 60, 31, 16, 250, 109, 202, 17, 60, 31, 16, 250, 109, 222, + 100, 60, 31, 16, 229, 177, 222, 227, 224, 225, 60, 31, 16, 229, 178, 222, + 227, 224, 225, 60, 31, 16, 229, 177, 222, 227, 229, 220, 60, 31, 16, 229, + 178, 222, 227, 229, 220, 60, 31, 16, 229, 39, 229, 220, 60, 31, 16, 238, + 23, 222, 227, 229, 220, 31, 16, 212, 120, 248, 226, 31, 16, 52, 248, 226, + 31, 16, 46, 248, 226, 31, 16, 216, 74, 46, 248, 226, 31, 16, 244, 143, + 248, 226, 31, 16, 212, 228, 248, 226, 31, 16, 49, 216, 101, 54, 31, 16, + 50, 216, 101, 54, 31, 16, 216, 101, 243, 83, 31, 16, 244, 185, 214, 157, + 31, 16, 244, 213, 247, 45, 31, 16, 214, 157, 31, 16, 245, 250, 31, 16, + 216, 99, 240, 15, 31, 16, 216, 99, 240, 14, 31, 16, 216, 99, 240, 13, 31, + 16, 240, 36, 31, 16, 240, 37, 56, 31, 16, 247, 216, 82, 31, 16, 247, 82, + 31, 16, 247, 228, 31, 16, 155, 31, 16, 220, 28, 211, 102, 31, 16, 207, + 133, 211, 102, 31, 16, 209, 29, 211, 102, 31, 16, 239, 146, 211, 102, 31, + 16, 239, 232, 211, 102, 31, 16, 212, 87, 211, 102, 31, 16, 212, 85, 239, + 127, 31, 16, 239, 144, 239, 127, 31, 16, 239, 76, 246, 30, 31, 16, 239, + 76, 246, 31, 219, 218, 251, 0, 31, 16, 239, 76, 246, 31, 219, 218, 248, + 211, 31, 16, 247, 126, 246, 30, 31, 16, 240, 175, 246, 30, 31, 16, 240, + 175, 246, 31, 219, 218, 251, 0, 31, 16, 240, 175, 246, 31, 219, 218, 248, + 211, 31, 16, 242, 47, 246, 29, 31, 16, 242, 47, 246, 28, 31, 16, 223, + 226, 225, 19, 216, 85, 31, 16, 52, 213, 56, 31, 16, 52, 239, 216, 31, 16, + 239, 217, 206, 224, 31, 16, 239, 217, 242, 70, 31, 16, 223, 66, 206, 224, + 31, 16, 223, 66, 242, 70, 31, 16, 213, 57, 206, 224, 31, 16, 213, 57, + 242, 70, 31, 16, 217, 56, 143, 213, 56, 31, 16, 217, 56, 143, 239, 216, + 31, 16, 245, 230, 208, 221, 31, 16, 245, 78, 208, 221, 31, 16, 219, 218, + 251, 0, 31, 16, 219, 218, 248, 211, 31, 16, 217, 37, 251, 0, 31, 16, 217, + 37, 248, 211, 31, 16, 223, 229, 216, 85, 31, 16, 204, 31, 216, 85, 31, + 16, 162, 216, 85, 31, 16, 217, 56, 216, 85, 31, 16, 241, 139, 216, 85, + 31, 16, 212, 81, 216, 85, 31, 16, 209, 51, 216, 85, 31, 16, 212, 73, 216, + 85, 31, 16, 118, 236, 12, 207, 149, 216, 85, 31, 16, 203, 197, 221, 156, + 31, 16, 91, 221, 156, 31, 16, 246, 62, 203, 197, 221, 156, 31, 16, 51, + 221, 157, 204, 33, 31, 16, 51, 221, 157, 248, 43, 31, 16, 208, 86, 221, + 157, 112, 204, 33, 31, 16, 208, 86, 221, 157, 112, 248, 43, 31, 16, 208, + 86, 221, 157, 49, 204, 33, 31, 16, 208, 86, 221, 157, 49, 248, 43, 31, + 16, 208, 86, 221, 157, 50, 204, 33, 31, 16, 208, 86, 221, 157, 50, 248, + 43, 31, 16, 208, 86, 221, 157, 121, 204, 33, 31, 16, 208, 86, 221, 157, + 121, 248, 43, 31, 16, 208, 86, 221, 157, 112, 50, 204, 33, 31, 16, 208, + 86, 221, 157, 112, 50, 248, 43, 31, 16, 224, 30, 221, 157, 204, 33, 31, + 16, 224, 30, 221, 157, 248, 43, 31, 16, 208, 83, 221, 157, 121, 204, 33, + 31, 16, 208, 83, 221, 157, 121, 248, 43, 31, 16, 219, 77, 221, 156, 31, + 16, 205, 183, 221, 156, 31, 16, 221, 157, 248, 43, 31, 16, 221, 49, 221, + 156, 31, 16, 246, 1, 221, 157, 204, 33, 31, 16, 246, 1, 221, 157, 248, + 43, 31, 16, 247, 214, 31, 16, 204, 31, 221, 160, 31, 16, 162, 221, 160, + 31, 16, 217, 56, 221, 160, 31, 16, 241, 139, 221, 160, 31, 16, 212, 81, + 221, 160, 31, 16, 209, 51, 221, 160, 31, 16, 212, 73, 221, 160, 31, 16, + 118, 236, 12, 207, 149, 221, 160, 31, 16, 39, 211, 77, 31, 16, 39, 211, + 184, 211, 77, 31, 16, 39, 208, 94, 31, 16, 39, 208, 93, 31, 16, 39, 208, + 92, 31, 16, 240, 0, 208, 94, 31, 16, 240, 0, 208, 93, 31, 16, 240, 0, + 208, 92, 31, 16, 39, 250, 31, 243, 85, 31, 16, 39, 239, 224, 31, 16, 39, + 239, 223, 31, 16, 39, 239, 222, 31, 16, 39, 239, 221, 31, 16, 39, 239, + 220, 31, 16, 248, 142, 248, 159, 31, 16, 241, 84, 248, 159, 31, 16, 248, + 142, 208, 250, 31, 16, 241, 84, 208, 250, 31, 16, 248, 142, 212, 37, 31, + 16, 241, 84, 212, 37, 31, 16, 248, 142, 218, 174, 31, 16, 241, 84, 218, + 174, 31, 16, 39, 251, 138, 31, 16, 39, 211, 105, 31, 16, 39, 209, 140, + 31, 16, 39, 211, 106, 31, 16, 39, 225, 96, 31, 16, 39, 225, 95, 31, 16, + 39, 251, 137, 31, 16, 39, 227, 2, 31, 16, 250, 100, 206, 224, 31, 16, + 250, 100, 242, 70, 31, 16, 39, 243, 100, 31, 16, 39, 215, 249, 31, 16, + 39, 239, 206, 31, 16, 39, 212, 33, 31, 16, 39, 248, 120, 31, 16, 39, 52, + 208, 150, 31, 16, 39, 208, 70, 208, 150, 31, 16, 215, 254, 31, 16, 211, + 0, 31, 16, 202, 159, 31, 16, 218, 166, 31, 16, 224, 206, 31, 16, 239, + 155, 31, 16, 245, 140, 31, 16, 244, 62, 31, 16, 238, 14, 221, 161, 212, + 57, 31, 16, 238, 14, 221, 161, 221, 192, 212, 57, 31, 16, 208, 120, 31, + 16, 207, 175, 31, 16, 230, 239, 207, 175, 31, 16, 207, 176, 212, 57, 31, + 16, 207, 176, 206, 224, 31, 16, 219, 234, 211, 31, 31, 16, 219, 234, 211, + 28, 31, 16, 219, 234, 211, 27, 31, 16, 219, 234, 211, 26, 31, 16, 219, + 234, 211, 25, 31, 16, 219, 234, 211, 24, 31, 16, 219, 234, 211, 23, 31, + 16, 219, 234, 211, 22, 31, 16, 219, 234, 211, 21, 31, 16, 219, 234, 211, + 30, 31, 16, 219, 234, 211, 29, 31, 16, 237, 75, 31, 16, 222, 238, 31, 16, + 241, 84, 76, 211, 67, 31, 16, 244, 55, 212, 57, 31, 16, 39, 121, 247, + 240, 31, 16, 39, 112, 247, 240, 31, 16, 39, 237, 88, 31, 16, 39, 212, 23, + 218, 99, 31, 16, 219, 28, 82, 31, 16, 219, 28, 112, 82, 31, 16, 162, 219, + 28, 82, 31, 16, 238, 47, 206, 224, 31, 16, 238, 47, 242, 70, 31, 16, 3, + 239, 255, 31, 16, 244, 168, 31, 16, 244, 169, 251, 14, 31, 16, 225, 65, + 31, 16, 227, 20, 31, 16, 247, 211, 31, 16, 213, 147, 204, 33, 31, 16, + 213, 147, 248, 43, 31, 16, 224, 106, 31, 16, 224, 107, 248, 43, 31, 16, + 213, 141, 204, 33, 31, 16, 213, 141, 248, 43, 31, 16, 239, 93, 204, 33, + 31, 16, 239, 93, 248, 43, 31, 16, 227, 21, 218, 244, 216, 85, 31, 16, + 227, 21, 231, 54, 216, 85, 31, 16, 247, 212, 216, 85, 31, 16, 213, 147, + 216, 85, 31, 16, 224, 107, 216, 85, 31, 16, 213, 141, 216, 85, 31, 16, + 209, 154, 218, 242, 245, 104, 217, 216, 218, 243, 31, 16, 209, 154, 218, + 242, 245, 104, 217, 216, 231, 53, 31, 16, 209, 154, 218, 242, 245, 104, + 217, 216, 218, 244, 243, 181, 31, 16, 209, 154, 231, 52, 245, 104, 217, + 216, 218, 243, 31, 16, 209, 154, 231, 52, 245, 104, 217, 216, 231, 53, + 31, 16, 209, 154, 231, 52, 245, 104, 217, 216, 231, 54, 243, 181, 31, 16, + 209, 154, 231, 52, 245, 104, 217, 216, 231, 54, 243, 180, 31, 16, 209, + 154, 231, 52, 245, 104, 217, 216, 231, 54, 243, 179, 31, 16, 245, 133, + 31, 16, 237, 243, 247, 126, 246, 30, 31, 16, 237, 243, 240, 175, 246, 30, + 31, 16, 51, 249, 255, 31, 16, 205, 203, 31, 16, 218, 66, 31, 16, 246, 21, + 31, 16, 214, 200, 31, 16, 246, 25, 31, 16, 208, 138, 31, 16, 218, 36, 31, + 16, 218, 37, 239, 209, 31, 16, 214, 201, 239, 209, 31, 16, 208, 139, 216, + 82, 31, 16, 218, 225, 210, 247, 31, 16, 229, 90, 247, 126, 246, 30, 31, + 16, 229, 90, 241, 84, 76, 218, 159, 31, 16, 229, 90, 46, 221, 160, 31, + 16, 229, 90, 216, 150, 82, 31, 16, 229, 90, 204, 31, 221, 160, 31, 16, + 229, 90, 162, 221, 160, 31, 16, 229, 90, 217, 56, 221, 161, 211, 78, 242, + 70, 31, 16, 229, 90, 217, 56, 221, 161, 211, 78, 206, 224, 31, 16, 229, + 90, 241, 139, 221, 161, 211, 78, 242, 70, 31, 16, 229, 90, 241, 139, 221, + 161, 211, 78, 206, 224, 31, 16, 229, 90, 239, 217, 54, 30, 205, 188, 221, + 164, 210, 148, 30, 205, 188, 221, 164, 210, 137, 30, 205, 188, 221, 164, + 210, 127, 30, 205, 188, 221, 164, 210, 120, 30, 205, 188, 221, 164, 210, + 112, 30, 205, 188, 221, 164, 210, 106, 30, 205, 188, 221, 164, 210, 105, + 30, 205, 188, 221, 164, 210, 104, 30, 205, 188, 221, 164, 210, 103, 30, + 205, 188, 221, 164, 210, 147, 30, 205, 188, 221, 164, 210, 146, 30, 205, + 188, 221, 164, 210, 145, 30, 205, 188, 221, 164, 210, 144, 30, 205, 188, + 221, 164, 210, 143, 30, 205, 188, 221, 164, 210, 142, 30, 205, 188, 221, + 164, 210, 141, 30, 205, 188, 221, 164, 210, 140, 30, 205, 188, 221, 164, + 210, 139, 30, 205, 188, 221, 164, 210, 138, 30, 205, 188, 221, 164, 210, + 136, 30, 205, 188, 221, 164, 210, 135, 30, 205, 188, 221, 164, 210, 134, + 30, 205, 188, 221, 164, 210, 133, 30, 205, 188, 221, 164, 210, 132, 30, + 205, 188, 221, 164, 210, 111, 30, 205, 188, 221, 164, 210, 110, 30, 205, + 188, 221, 164, 210, 109, 30, 205, 188, 221, 164, 210, 108, 30, 205, 188, + 221, 164, 210, 107, 30, 231, 5, 221, 164, 210, 148, 30, 231, 5, 221, 164, + 210, 137, 30, 231, 5, 221, 164, 210, 120, 30, 231, 5, 221, 164, 210, 112, + 30, 231, 5, 221, 164, 210, 105, 30, 231, 5, 221, 164, 210, 104, 30, 231, + 5, 221, 164, 210, 146, 30, 231, 5, 221, 164, 210, 145, 30, 231, 5, 221, + 164, 210, 144, 30, 231, 5, 221, 164, 210, 143, 30, 231, 5, 221, 164, 210, + 140, 30, 231, 5, 221, 164, 210, 139, 30, 231, 5, 221, 164, 210, 138, 30, + 231, 5, 221, 164, 210, 133, 30, 231, 5, 221, 164, 210, 132, 30, 231, 5, + 221, 164, 210, 131, 30, 231, 5, 221, 164, 210, 130, 30, 231, 5, 221, 164, + 210, 129, 30, 231, 5, 221, 164, 210, 128, 30, 231, 5, 221, 164, 210, 126, + 30, 231, 5, 221, 164, 210, 125, 30, 231, 5, 221, 164, 210, 124, 30, 231, + 5, 221, 164, 210, 123, 30, 231, 5, 221, 164, 210, 122, 30, 231, 5, 221, + 164, 210, 121, 30, 231, 5, 221, 164, 210, 119, 30, 231, 5, 221, 164, 210, + 118, 30, 231, 5, 221, 164, 210, 117, 30, 231, 5, 221, 164, 210, 116, 30, + 231, 5, 221, 164, 210, 115, 30, 231, 5, 221, 164, 210, 114, 30, 231, 5, + 221, 164, 210, 113, 30, 231, 5, 221, 164, 210, 111, 30, 231, 5, 221, 164, + 210, 110, 30, 231, 5, 221, 164, 210, 109, 30, 231, 5, 221, 164, 210, 108, + 30, 231, 5, 221, 164, 210, 107, 39, 30, 31, 208, 66, 39, 30, 31, 209, + 124, 39, 30, 31, 218, 253, 30, 31, 227, 204, 224, 45, 35, 241, 179, 243, + 195, 35, 237, 50, 241, 179, 243, 195, 35, 236, 16, 241, 179, 243, 195, + 35, 241, 178, 237, 51, 243, 195, 35, 241, 178, 236, 15, 243, 195, 35, + 241, 179, 209, 126, 35, 246, 217, 209, 126, 35, 239, 102, 246, 61, 209, + 126, 35, 224, 98, 209, 126, 35, 248, 221, 209, 126, 35, 229, 195, 212, + 36, 209, 126, 35, 245, 185, 209, 126, 35, 250, 77, 209, 126, 35, 219, + 250, 209, 126, 35, 247, 221, 219, 211, 209, 126, 35, 244, 57, 219, 245, + 243, 148, 209, 126, 35, 243, 145, 209, 126, 35, 202, 225, 209, 126, 35, + 231, 40, 209, 126, 35, 219, 7, 209, 126, 35, 216, 157, 209, 126, 35, 245, + 197, 209, 126, 35, 236, 127, 249, 25, 209, 126, 35, 204, 103, 209, 126, + 35, 239, 181, 209, 126, 35, 251, 112, 209, 126, 35, 216, 114, 209, 126, + 35, 216, 89, 209, 126, 35, 241, 177, 209, 126, 35, 230, 85, 209, 126, 35, + 245, 192, 209, 126, 35, 241, 83, 209, 126, 35, 242, 15, 209, 126, 35, + 246, 186, 209, 126, 35, 244, 67, 209, 126, 35, 26, 216, 88, 209, 126, 35, + 219, 160, 209, 126, 35, 227, 208, 209, 126, 35, 246, 14, 209, 126, 35, + 229, 80, 209, 126, 35, 238, 214, 209, 126, 35, 211, 43, 209, 126, 35, + 217, 168, 209, 126, 35, 239, 101, 209, 126, 35, 216, 90, 209, 126, 35, + 227, 247, 219, 245, 224, 78, 209, 126, 35, 216, 86, 209, 126, 35, 238, + 33, 208, 173, 225, 3, 209, 126, 35, 241, 85, 209, 126, 35, 211, 56, 209, + 126, 35, 237, 245, 209, 126, 35, 241, 76, 209, 126, 35, 219, 50, 209, + 126, 35, 215, 242, 209, 126, 35, 239, 207, 209, 126, 35, 206, 64, 219, + 245, 204, 84, 209, 126, 35, 245, 202, 209, 126, 35, 225, 18, 209, 126, + 35, 240, 245, 209, 126, 35, 206, 234, 209, 126, 35, 243, 182, 209, 126, + 35, 246, 16, 224, 7, 209, 126, 35, 237, 222, 209, 126, 35, 238, 215, 231, + 49, 209, 126, 35, 225, 73, 209, 126, 35, 251, 133, 209, 126, 35, 241, + 101, 209, 126, 35, 242, 74, 209, 126, 35, 204, 82, 209, 126, 35, 212, + 115, 209, 126, 35, 231, 14, 209, 126, 35, 244, 25, 209, 126, 35, 244, + 148, 209, 126, 35, 243, 178, 209, 126, 35, 240, 209, 209, 126, 35, 213, + 104, 209, 126, 35, 211, 60, 209, 126, 35, 237, 90, 209, 126, 35, 245, + 226, 209, 126, 35, 246, 11, 209, 126, 35, 240, 87, 209, 126, 35, 251, 76, + 209, 126, 35, 245, 225, 209, 126, 35, 220, 32, 209, 93, 206, 41, 209, + 126, 35, 243, 204, 209, 126, 35, 228, 101, 209, 126, 35, 239, 150, 245, + 153, 215, 217, 206, 236, 17, 105, 245, 153, 215, 217, 206, 236, 17, 108, + 245, 153, 215, 217, 206, 236, 17, 147, 245, 153, 215, 217, 206, 236, 17, + 149, 245, 153, 215, 217, 206, 236, 17, 170, 245, 153, 215, 217, 206, 236, + 17, 195, 245, 153, 215, 217, 206, 236, 17, 213, 111, 245, 153, 215, 217, + 206, 236, 17, 199, 245, 153, 215, 217, 206, 236, 17, 222, 63, 245, 153, + 215, 217, 209, 148, 17, 105, 245, 153, 215, 217, 209, 148, 17, 108, 245, + 153, 215, 217, 209, 148, 17, 147, 245, 153, 215, 217, 209, 148, 17, 149, + 245, 153, 215, 217, 209, 148, 17, 170, 245, 153, 215, 217, 209, 148, 17, + 195, 245, 153, 215, 217, 209, 148, 17, 213, 111, 245, 153, 215, 217, 209, + 148, 17, 199, 245, 153, 215, 217, 209, 148, 17, 222, 63, 13, 26, 6, 63, + 13, 26, 6, 249, 255, 13, 26, 6, 247, 125, 13, 26, 6, 245, 51, 13, 26, 6, + 74, 13, 26, 6, 240, 174, 13, 26, 6, 239, 75, 13, 26, 6, 237, 171, 13, 26, + 6, 75, 13, 26, 6, 230, 184, 13, 26, 6, 230, 54, 13, 26, 6, 159, 13, 26, + 6, 226, 185, 13, 26, 6, 223, 163, 13, 26, 6, 78, 13, 26, 6, 219, 184, 13, + 26, 6, 217, 134, 13, 26, 6, 146, 13, 26, 6, 194, 13, 26, 6, 210, 69, 13, + 26, 6, 68, 13, 26, 6, 206, 164, 13, 26, 6, 204, 144, 13, 26, 6, 203, 196, + 13, 26, 6, 203, 124, 13, 26, 6, 202, 159, 13, 26, 5, 63, 13, 26, 5, 249, + 255, 13, 26, 5, 247, 125, 13, 26, 5, 245, 51, 13, 26, 5, 74, 13, 26, 5, + 240, 174, 13, 26, 5, 239, 75, 13, 26, 5, 237, 171, 13, 26, 5, 75, 13, 26, + 5, 230, 184, 13, 26, 5, 230, 54, 13, 26, 5, 159, 13, 26, 5, 226, 185, 13, + 26, 5, 223, 163, 13, 26, 5, 78, 13, 26, 5, 219, 184, 13, 26, 5, 217, 134, + 13, 26, 5, 146, 13, 26, 5, 194, 13, 26, 5, 210, 69, 13, 26, 5, 68, 13, + 26, 5, 206, 164, 13, 26, 5, 204, 144, 13, 26, 5, 203, 196, 13, 26, 5, + 203, 124, 13, 26, 5, 202, 159, 13, 37, 6, 63, 13, 37, 6, 249, 255, 13, + 37, 6, 247, 125, 13, 37, 6, 245, 51, 13, 37, 6, 74, 13, 37, 6, 240, 174, + 13, 37, 6, 239, 75, 13, 37, 6, 237, 171, 13, 37, 6, 75, 13, 37, 6, 230, + 184, 13, 37, 6, 230, 54, 13, 37, 6, 159, 13, 37, 6, 226, 185, 13, 37, 6, + 223, 163, 13, 37, 6, 78, 13, 37, 6, 219, 184, 13, 37, 6, 217, 134, 13, + 37, 6, 146, 13, 37, 6, 194, 13, 37, 6, 210, 69, 13, 37, 6, 68, 13, 37, 6, + 206, 164, 13, 37, 6, 204, 144, 13, 37, 6, 203, 196, 13, 37, 6, 203, 124, + 13, 37, 6, 202, 159, 13, 37, 5, 63, 13, 37, 5, 249, 255, 13, 37, 5, 247, + 125, 13, 37, 5, 245, 51, 13, 37, 5, 74, 13, 37, 5, 240, 174, 13, 37, 5, + 239, 75, 13, 37, 5, 75, 13, 37, 5, 230, 184, 13, 37, 5, 230, 54, 13, 37, + 5, 159, 13, 37, 5, 226, 185, 13, 37, 5, 223, 163, 13, 37, 5, 78, 13, 37, + 5, 219, 184, 13, 37, 5, 217, 134, 13, 37, 5, 146, 13, 37, 5, 194, 13, 37, + 5, 210, 69, 13, 37, 5, 68, 13, 37, 5, 206, 164, 13, 37, 5, 204, 144, 13, + 37, 5, 203, 196, 13, 37, 5, 203, 124, 13, 37, 5, 202, 159, 13, 26, 37, 6, + 63, 13, 26, 37, 6, 249, 255, 13, 26, 37, 6, 247, 125, 13, 26, 37, 6, 245, + 51, 13, 26, 37, 6, 74, 13, 26, 37, 6, 240, 174, 13, 26, 37, 6, 239, 75, + 13, 26, 37, 6, 237, 171, 13, 26, 37, 6, 75, 13, 26, 37, 6, 230, 184, 13, + 26, 37, 6, 230, 54, 13, 26, 37, 6, 159, 13, 26, 37, 6, 226, 185, 13, 26, + 37, 6, 223, 163, 13, 26, 37, 6, 78, 13, 26, 37, 6, 219, 184, 13, 26, 37, + 6, 217, 134, 13, 26, 37, 6, 146, 13, 26, 37, 6, 194, 13, 26, 37, 6, 210, + 69, 13, 26, 37, 6, 68, 13, 26, 37, 6, 206, 164, 13, 26, 37, 6, 204, 144, + 13, 26, 37, 6, 203, 196, 13, 26, 37, 6, 203, 124, 13, 26, 37, 6, 202, + 159, 13, 26, 37, 5, 63, 13, 26, 37, 5, 249, 255, 13, 26, 37, 5, 247, 125, + 13, 26, 37, 5, 245, 51, 13, 26, 37, 5, 74, 13, 26, 37, 5, 240, 174, 13, + 26, 37, 5, 239, 75, 13, 26, 37, 5, 237, 171, 13, 26, 37, 5, 75, 13, 26, + 37, 5, 230, 184, 13, 26, 37, 5, 230, 54, 13, 26, 37, 5, 159, 13, 26, 37, + 5, 226, 185, 13, 26, 37, 5, 223, 163, 13, 26, 37, 5, 78, 13, 26, 37, 5, + 219, 184, 13, 26, 37, 5, 217, 134, 13, 26, 37, 5, 146, 13, 26, 37, 5, + 194, 13, 26, 37, 5, 210, 69, 13, 26, 37, 5, 68, 13, 26, 37, 5, 206, 164, + 13, 26, 37, 5, 204, 144, 13, 26, 37, 5, 203, 196, 13, 26, 37, 5, 203, + 124, 13, 26, 37, 5, 202, 159, 13, 132, 6, 63, 13, 132, 6, 247, 125, 13, + 132, 6, 245, 51, 13, 132, 6, 239, 75, 13, 132, 6, 230, 184, 13, 132, 6, + 230, 54, 13, 132, 6, 223, 163, 13, 132, 6, 78, 13, 132, 6, 219, 184, 13, + 132, 6, 217, 134, 13, 132, 6, 194, 13, 132, 6, 210, 69, 13, 132, 6, 68, + 13, 132, 6, 206, 164, 13, 132, 6, 204, 144, 13, 132, 6, 203, 196, 13, + 132, 6, 203, 124, 13, 132, 6, 202, 159, 13, 132, 5, 63, 13, 132, 5, 249, + 255, 13, 132, 5, 247, 125, 13, 132, 5, 245, 51, 13, 132, 5, 240, 174, 13, + 132, 5, 237, 171, 13, 132, 5, 75, 13, 132, 5, 230, 184, 13, 132, 5, 230, + 54, 13, 132, 5, 159, 13, 132, 5, 226, 185, 13, 132, 5, 223, 163, 13, 132, + 5, 219, 184, 13, 132, 5, 217, 134, 13, 132, 5, 146, 13, 132, 5, 194, 13, + 132, 5, 210, 69, 13, 132, 5, 68, 13, 132, 5, 206, 164, 13, 132, 5, 204, + 144, 13, 132, 5, 203, 196, 13, 132, 5, 203, 124, 13, 132, 5, 202, 159, + 13, 26, 132, 6, 63, 13, 26, 132, 6, 249, 255, 13, 26, 132, 6, 247, 125, + 13, 26, 132, 6, 245, 51, 13, 26, 132, 6, 74, 13, 26, 132, 6, 240, 174, + 13, 26, 132, 6, 239, 75, 13, 26, 132, 6, 237, 171, 13, 26, 132, 6, 75, + 13, 26, 132, 6, 230, 184, 13, 26, 132, 6, 230, 54, 13, 26, 132, 6, 159, + 13, 26, 132, 6, 226, 185, 13, 26, 132, 6, 223, 163, 13, 26, 132, 6, 78, + 13, 26, 132, 6, 219, 184, 13, 26, 132, 6, 217, 134, 13, 26, 132, 6, 146, + 13, 26, 132, 6, 194, 13, 26, 132, 6, 210, 69, 13, 26, 132, 6, 68, 13, 26, + 132, 6, 206, 164, 13, 26, 132, 6, 204, 144, 13, 26, 132, 6, 203, 196, 13, + 26, 132, 6, 203, 124, 13, 26, 132, 6, 202, 159, 13, 26, 132, 5, 63, 13, + 26, 132, 5, 249, 255, 13, 26, 132, 5, 247, 125, 13, 26, 132, 5, 245, 51, + 13, 26, 132, 5, 74, 13, 26, 132, 5, 240, 174, 13, 26, 132, 5, 239, 75, + 13, 26, 132, 5, 237, 171, 13, 26, 132, 5, 75, 13, 26, 132, 5, 230, 184, + 13, 26, 132, 5, 230, 54, 13, 26, 132, 5, 159, 13, 26, 132, 5, 226, 185, + 13, 26, 132, 5, 223, 163, 13, 26, 132, 5, 78, 13, 26, 132, 5, 219, 184, + 13, 26, 132, 5, 217, 134, 13, 26, 132, 5, 146, 13, 26, 132, 5, 194, 13, + 26, 132, 5, 210, 69, 13, 26, 132, 5, 68, 13, 26, 132, 5, 206, 164, 13, + 26, 132, 5, 204, 144, 13, 26, 132, 5, 203, 196, 13, 26, 132, 5, 203, 124, + 13, 26, 132, 5, 202, 159, 13, 166, 6, 63, 13, 166, 6, 249, 255, 13, 166, + 6, 245, 51, 13, 166, 6, 74, 13, 166, 6, 240, 174, 13, 166, 6, 239, 75, + 13, 166, 6, 230, 184, 13, 166, 6, 230, 54, 13, 166, 6, 159, 13, 166, 6, + 226, 185, 13, 166, 6, 223, 163, 13, 166, 6, 78, 13, 166, 6, 219, 184, 13, + 166, 6, 217, 134, 13, 166, 6, 194, 13, 166, 6, 210, 69, 13, 166, 6, 68, + 13, 166, 6, 206, 164, 13, 166, 6, 204, 144, 13, 166, 6, 203, 196, 13, + 166, 6, 203, 124, 13, 166, 5, 63, 13, 166, 5, 249, 255, 13, 166, 5, 247, + 125, 13, 166, 5, 245, 51, 13, 166, 5, 74, 13, 166, 5, 240, 174, 13, 166, + 5, 239, 75, 13, 166, 5, 237, 171, 13, 166, 5, 75, 13, 166, 5, 230, 184, + 13, 166, 5, 230, 54, 13, 166, 5, 159, 13, 166, 5, 226, 185, 13, 166, 5, + 223, 163, 13, 166, 5, 78, 13, 166, 5, 219, 184, 13, 166, 5, 217, 134, 13, + 166, 5, 146, 13, 166, 5, 194, 13, 166, 5, 210, 69, 13, 166, 5, 68, 13, + 166, 5, 206, 164, 13, 166, 5, 204, 144, 13, 166, 5, 203, 196, 13, 166, 5, + 203, 124, 13, 166, 5, 202, 159, 13, 169, 6, 63, 13, 169, 6, 249, 255, 13, + 169, 6, 245, 51, 13, 169, 6, 74, 13, 169, 6, 240, 174, 13, 169, 6, 239, + 75, 13, 169, 6, 75, 13, 169, 6, 230, 184, 13, 169, 6, 230, 54, 13, 169, + 6, 159, 13, 169, 6, 226, 185, 13, 169, 6, 78, 13, 169, 6, 194, 13, 169, + 6, 210, 69, 13, 169, 6, 68, 13, 169, 6, 206, 164, 13, 169, 6, 204, 144, + 13, 169, 6, 203, 196, 13, 169, 6, 203, 124, 13, 169, 5, 63, 13, 169, 5, + 249, 255, 13, 169, 5, 247, 125, 13, 169, 5, 245, 51, 13, 169, 5, 74, 13, + 169, 5, 240, 174, 13, 169, 5, 239, 75, 13, 169, 5, 237, 171, 13, 169, 5, + 75, 13, 169, 5, 230, 184, 13, 169, 5, 230, 54, 13, 169, 5, 159, 13, 169, + 5, 226, 185, 13, 169, 5, 223, 163, 13, 169, 5, 78, 13, 169, 5, 219, 184, + 13, 169, 5, 217, 134, 13, 169, 5, 146, 13, 169, 5, 194, 13, 169, 5, 210, + 69, 13, 169, 5, 68, 13, 169, 5, 206, 164, 13, 169, 5, 204, 144, 13, 169, + 5, 203, 196, 13, 169, 5, 203, 124, 13, 169, 5, 202, 159, 13, 26, 166, 6, + 63, 13, 26, 166, 6, 249, 255, 13, 26, 166, 6, 247, 125, 13, 26, 166, 6, + 245, 51, 13, 26, 166, 6, 74, 13, 26, 166, 6, 240, 174, 13, 26, 166, 6, + 239, 75, 13, 26, 166, 6, 237, 171, 13, 26, 166, 6, 75, 13, 26, 166, 6, + 230, 184, 13, 26, 166, 6, 230, 54, 13, 26, 166, 6, 159, 13, 26, 166, 6, + 226, 185, 13, 26, 166, 6, 223, 163, 13, 26, 166, 6, 78, 13, 26, 166, 6, + 219, 184, 13, 26, 166, 6, 217, 134, 13, 26, 166, 6, 146, 13, 26, 166, 6, + 194, 13, 26, 166, 6, 210, 69, 13, 26, 166, 6, 68, 13, 26, 166, 6, 206, + 164, 13, 26, 166, 6, 204, 144, 13, 26, 166, 6, 203, 196, 13, 26, 166, 6, + 203, 124, 13, 26, 166, 6, 202, 159, 13, 26, 166, 5, 63, 13, 26, 166, 5, + 249, 255, 13, 26, 166, 5, 247, 125, 13, 26, 166, 5, 245, 51, 13, 26, 166, + 5, 74, 13, 26, 166, 5, 240, 174, 13, 26, 166, 5, 239, 75, 13, 26, 166, 5, + 237, 171, 13, 26, 166, 5, 75, 13, 26, 166, 5, 230, 184, 13, 26, 166, 5, + 230, 54, 13, 26, 166, 5, 159, 13, 26, 166, 5, 226, 185, 13, 26, 166, 5, + 223, 163, 13, 26, 166, 5, 78, 13, 26, 166, 5, 219, 184, 13, 26, 166, 5, + 217, 134, 13, 26, 166, 5, 146, 13, 26, 166, 5, 194, 13, 26, 166, 5, 210, + 69, 13, 26, 166, 5, 68, 13, 26, 166, 5, 206, 164, 13, 26, 166, 5, 204, + 144, 13, 26, 166, 5, 203, 196, 13, 26, 166, 5, 203, 124, 13, 26, 166, 5, + 202, 159, 13, 41, 6, 63, 13, 41, 6, 249, 255, 13, 41, 6, 247, 125, 13, + 41, 6, 245, 51, 13, 41, 6, 74, 13, 41, 6, 240, 174, 13, 41, 6, 239, 75, + 13, 41, 6, 237, 171, 13, 41, 6, 75, 13, 41, 6, 230, 184, 13, 41, 6, 230, + 54, 13, 41, 6, 159, 13, 41, 6, 226, 185, 13, 41, 6, 223, 163, 13, 41, 6, + 78, 13, 41, 6, 219, 184, 13, 41, 6, 217, 134, 13, 41, 6, 146, 13, 41, 6, + 194, 13, 41, 6, 210, 69, 13, 41, 6, 68, 13, 41, 6, 206, 164, 13, 41, 6, + 204, 144, 13, 41, 6, 203, 196, 13, 41, 6, 203, 124, 13, 41, 6, 202, 159, + 13, 41, 5, 63, 13, 41, 5, 249, 255, 13, 41, 5, 247, 125, 13, 41, 5, 245, + 51, 13, 41, 5, 74, 13, 41, 5, 240, 174, 13, 41, 5, 239, 75, 13, 41, 5, + 237, 171, 13, 41, 5, 75, 13, 41, 5, 230, 184, 13, 41, 5, 230, 54, 13, 41, + 5, 159, 13, 41, 5, 226, 185, 13, 41, 5, 223, 163, 13, 41, 5, 78, 13, 41, + 5, 219, 184, 13, 41, 5, 217, 134, 13, 41, 5, 146, 13, 41, 5, 194, 13, 41, + 5, 210, 69, 13, 41, 5, 68, 13, 41, 5, 206, 164, 13, 41, 5, 204, 144, 13, + 41, 5, 203, 196, 13, 41, 5, 203, 124, 13, 41, 5, 202, 159, 13, 41, 26, 6, + 63, 13, 41, 26, 6, 249, 255, 13, 41, 26, 6, 247, 125, 13, 41, 26, 6, 245, + 51, 13, 41, 26, 6, 74, 13, 41, 26, 6, 240, 174, 13, 41, 26, 6, 239, 75, + 13, 41, 26, 6, 237, 171, 13, 41, 26, 6, 75, 13, 41, 26, 6, 230, 184, 13, + 41, 26, 6, 230, 54, 13, 41, 26, 6, 159, 13, 41, 26, 6, 226, 185, 13, 41, + 26, 6, 223, 163, 13, 41, 26, 6, 78, 13, 41, 26, 6, 219, 184, 13, 41, 26, + 6, 217, 134, 13, 41, 26, 6, 146, 13, 41, 26, 6, 194, 13, 41, 26, 6, 210, + 69, 13, 41, 26, 6, 68, 13, 41, 26, 6, 206, 164, 13, 41, 26, 6, 204, 144, + 13, 41, 26, 6, 203, 196, 13, 41, 26, 6, 203, 124, 13, 41, 26, 6, 202, + 159, 13, 41, 26, 5, 63, 13, 41, 26, 5, 249, 255, 13, 41, 26, 5, 247, 125, + 13, 41, 26, 5, 245, 51, 13, 41, 26, 5, 74, 13, 41, 26, 5, 240, 174, 13, + 41, 26, 5, 239, 75, 13, 41, 26, 5, 237, 171, 13, 41, 26, 5, 75, 13, 41, + 26, 5, 230, 184, 13, 41, 26, 5, 230, 54, 13, 41, 26, 5, 159, 13, 41, 26, + 5, 226, 185, 13, 41, 26, 5, 223, 163, 13, 41, 26, 5, 78, 13, 41, 26, 5, + 219, 184, 13, 41, 26, 5, 217, 134, 13, 41, 26, 5, 146, 13, 41, 26, 5, + 194, 13, 41, 26, 5, 210, 69, 13, 41, 26, 5, 68, 13, 41, 26, 5, 206, 164, + 13, 41, 26, 5, 204, 144, 13, 41, 26, 5, 203, 196, 13, 41, 26, 5, 203, + 124, 13, 41, 26, 5, 202, 159, 13, 41, 37, 6, 63, 13, 41, 37, 6, 249, 255, + 13, 41, 37, 6, 247, 125, 13, 41, 37, 6, 245, 51, 13, 41, 37, 6, 74, 13, + 41, 37, 6, 240, 174, 13, 41, 37, 6, 239, 75, 13, 41, 37, 6, 237, 171, 13, + 41, 37, 6, 75, 13, 41, 37, 6, 230, 184, 13, 41, 37, 6, 230, 54, 13, 41, + 37, 6, 159, 13, 41, 37, 6, 226, 185, 13, 41, 37, 6, 223, 163, 13, 41, 37, + 6, 78, 13, 41, 37, 6, 219, 184, 13, 41, 37, 6, 217, 134, 13, 41, 37, 6, + 146, 13, 41, 37, 6, 194, 13, 41, 37, 6, 210, 69, 13, 41, 37, 6, 68, 13, + 41, 37, 6, 206, 164, 13, 41, 37, 6, 204, 144, 13, 41, 37, 6, 203, 196, + 13, 41, 37, 6, 203, 124, 13, 41, 37, 6, 202, 159, 13, 41, 37, 5, 63, 13, + 41, 37, 5, 249, 255, 13, 41, 37, 5, 247, 125, 13, 41, 37, 5, 245, 51, 13, + 41, 37, 5, 74, 13, 41, 37, 5, 240, 174, 13, 41, 37, 5, 239, 75, 13, 41, + 37, 5, 237, 171, 13, 41, 37, 5, 75, 13, 41, 37, 5, 230, 184, 13, 41, 37, + 5, 230, 54, 13, 41, 37, 5, 159, 13, 41, 37, 5, 226, 185, 13, 41, 37, 5, + 223, 163, 13, 41, 37, 5, 78, 13, 41, 37, 5, 219, 184, 13, 41, 37, 5, 217, + 134, 13, 41, 37, 5, 146, 13, 41, 37, 5, 194, 13, 41, 37, 5, 210, 69, 13, + 41, 37, 5, 68, 13, 41, 37, 5, 206, 164, 13, 41, 37, 5, 204, 144, 13, 41, + 37, 5, 203, 196, 13, 41, 37, 5, 203, 124, 13, 41, 37, 5, 202, 159, 13, + 41, 26, 37, 6, 63, 13, 41, 26, 37, 6, 249, 255, 13, 41, 26, 37, 6, 247, + 125, 13, 41, 26, 37, 6, 245, 51, 13, 41, 26, 37, 6, 74, 13, 41, 26, 37, + 6, 240, 174, 13, 41, 26, 37, 6, 239, 75, 13, 41, 26, 37, 6, 237, 171, 13, + 41, 26, 37, 6, 75, 13, 41, 26, 37, 6, 230, 184, 13, 41, 26, 37, 6, 230, + 54, 13, 41, 26, 37, 6, 159, 13, 41, 26, 37, 6, 226, 185, 13, 41, 26, 37, + 6, 223, 163, 13, 41, 26, 37, 6, 78, 13, 41, 26, 37, 6, 219, 184, 13, 41, + 26, 37, 6, 217, 134, 13, 41, 26, 37, 6, 146, 13, 41, 26, 37, 6, 194, 13, + 41, 26, 37, 6, 210, 69, 13, 41, 26, 37, 6, 68, 13, 41, 26, 37, 6, 206, + 164, 13, 41, 26, 37, 6, 204, 144, 13, 41, 26, 37, 6, 203, 196, 13, 41, + 26, 37, 6, 203, 124, 13, 41, 26, 37, 6, 202, 159, 13, 41, 26, 37, 5, 63, + 13, 41, 26, 37, 5, 249, 255, 13, 41, 26, 37, 5, 247, 125, 13, 41, 26, 37, + 5, 245, 51, 13, 41, 26, 37, 5, 74, 13, 41, 26, 37, 5, 240, 174, 13, 41, + 26, 37, 5, 239, 75, 13, 41, 26, 37, 5, 237, 171, 13, 41, 26, 37, 5, 75, + 13, 41, 26, 37, 5, 230, 184, 13, 41, 26, 37, 5, 230, 54, 13, 41, 26, 37, + 5, 159, 13, 41, 26, 37, 5, 226, 185, 13, 41, 26, 37, 5, 223, 163, 13, 41, + 26, 37, 5, 78, 13, 41, 26, 37, 5, 219, 184, 13, 41, 26, 37, 5, 217, 134, + 13, 41, 26, 37, 5, 146, 13, 41, 26, 37, 5, 194, 13, 41, 26, 37, 5, 210, + 69, 13, 41, 26, 37, 5, 68, 13, 41, 26, 37, 5, 206, 164, 13, 41, 26, 37, + 5, 204, 144, 13, 41, 26, 37, 5, 203, 196, 13, 41, 26, 37, 5, 203, 124, + 13, 41, 26, 37, 5, 202, 159, 13, 224, 41, 6, 63, 13, 224, 41, 6, 249, + 255, 13, 224, 41, 6, 247, 125, 13, 224, 41, 6, 245, 51, 13, 224, 41, 6, + 74, 13, 224, 41, 6, 240, 174, 13, 224, 41, 6, 239, 75, 13, 224, 41, 6, + 237, 171, 13, 224, 41, 6, 75, 13, 224, 41, 6, 230, 184, 13, 224, 41, 6, + 230, 54, 13, 224, 41, 6, 159, 13, 224, 41, 6, 226, 185, 13, 224, 41, 6, + 223, 163, 13, 224, 41, 6, 78, 13, 224, 41, 6, 219, 184, 13, 224, 41, 6, + 217, 134, 13, 224, 41, 6, 146, 13, 224, 41, 6, 194, 13, 224, 41, 6, 210, + 69, 13, 224, 41, 6, 68, 13, 224, 41, 6, 206, 164, 13, 224, 41, 6, 204, + 144, 13, 224, 41, 6, 203, 196, 13, 224, 41, 6, 203, 124, 13, 224, 41, 6, + 202, 159, 13, 224, 41, 5, 63, 13, 224, 41, 5, 249, 255, 13, 224, 41, 5, + 247, 125, 13, 224, 41, 5, 245, 51, 13, 224, 41, 5, 74, 13, 224, 41, 5, + 240, 174, 13, 224, 41, 5, 239, 75, 13, 224, 41, 5, 237, 171, 13, 224, 41, + 5, 75, 13, 224, 41, 5, 230, 184, 13, 224, 41, 5, 230, 54, 13, 224, 41, 5, + 159, 13, 224, 41, 5, 226, 185, 13, 224, 41, 5, 223, 163, 13, 224, 41, 5, + 78, 13, 224, 41, 5, 219, 184, 13, 224, 41, 5, 217, 134, 13, 224, 41, 5, + 146, 13, 224, 41, 5, 194, 13, 224, 41, 5, 210, 69, 13, 224, 41, 5, 68, + 13, 224, 41, 5, 206, 164, 13, 224, 41, 5, 204, 144, 13, 224, 41, 5, 203, + 196, 13, 224, 41, 5, 203, 124, 13, 224, 41, 5, 202, 159, 13, 37, 5, 243, + 84, 75, 13, 37, 5, 243, 84, 230, 184, 13, 26, 6, 251, 2, 13, 26, 6, 248, + 106, 13, 26, 6, 238, 235, 13, 26, 6, 244, 37, 13, 26, 6, 241, 37, 13, 26, + 6, 202, 83, 13, 26, 6, 240, 248, 13, 26, 6, 209, 74, 13, 26, 6, 230, 230, + 13, 26, 6, 229, 247, 13, 26, 6, 228, 24, 13, 26, 6, 223, 246, 13, 26, 6, + 221, 84, 13, 26, 6, 203, 170, 13, 26, 6, 220, 34, 13, 26, 6, 218, 167, + 13, 26, 6, 216, 59, 13, 26, 6, 209, 75, 97, 13, 26, 6, 212, 144, 13, 26, + 6, 209, 207, 13, 26, 6, 206, 216, 13, 26, 6, 218, 192, 13, 26, 6, 246, + 142, 13, 26, 6, 217, 202, 13, 26, 6, 220, 36, 13, 26, 223, 101, 13, 26, + 5, 251, 2, 13, 26, 5, 248, 106, 13, 26, 5, 238, 235, 13, 26, 5, 244, 37, + 13, 26, 5, 241, 37, 13, 26, 5, 202, 83, 13, 26, 5, 240, 248, 13, 26, 5, + 209, 74, 13, 26, 5, 230, 230, 13, 26, 5, 229, 247, 13, 26, 5, 228, 24, + 13, 26, 5, 223, 246, 13, 26, 5, 221, 84, 13, 26, 5, 203, 170, 13, 26, 5, + 220, 34, 13, 26, 5, 218, 167, 13, 26, 5, 216, 59, 13, 26, 5, 46, 212, + 144, 13, 26, 5, 212, 144, 13, 26, 5, 209, 207, 13, 26, 5, 206, 216, 13, + 26, 5, 218, 192, 13, 26, 5, 246, 142, 13, 26, 5, 217, 202, 13, 26, 5, + 220, 36, 13, 26, 219, 69, 243, 205, 13, 26, 241, 38, 97, 13, 26, 209, 75, + 97, 13, 26, 229, 248, 97, 13, 26, 218, 193, 97, 13, 26, 216, 60, 97, 13, + 26, 218, 168, 97, 13, 37, 6, 251, 2, 13, 37, 6, 248, 106, 13, 37, 6, 238, + 235, 13, 37, 6, 244, 37, 13, 37, 6, 241, 37, 13, 37, 6, 202, 83, 13, 37, + 6, 240, 248, 13, 37, 6, 209, 74, 13, 37, 6, 230, 230, 13, 37, 6, 229, + 247, 13, 37, 6, 228, 24, 13, 37, 6, 223, 246, 13, 37, 6, 221, 84, 13, 37, + 6, 203, 170, 13, 37, 6, 220, 34, 13, 37, 6, 218, 167, 13, 37, 6, 216, 59, + 13, 37, 6, 209, 75, 97, 13, 37, 6, 212, 144, 13, 37, 6, 209, 207, 13, 37, + 6, 206, 216, 13, 37, 6, 218, 192, 13, 37, 6, 246, 142, 13, 37, 6, 217, + 202, 13, 37, 6, 220, 36, 13, 37, 223, 101, 13, 37, 5, 251, 2, 13, 37, 5, + 248, 106, 13, 37, 5, 238, 235, 13, 37, 5, 244, 37, 13, 37, 5, 241, 37, + 13, 37, 5, 202, 83, 13, 37, 5, 240, 248, 13, 37, 5, 209, 74, 13, 37, 5, + 230, 230, 13, 37, 5, 229, 247, 13, 37, 5, 228, 24, 13, 37, 5, 223, 246, + 13, 37, 5, 221, 84, 13, 37, 5, 203, 170, 13, 37, 5, 220, 34, 13, 37, 5, + 218, 167, 13, 37, 5, 216, 59, 13, 37, 5, 46, 212, 144, 13, 37, 5, 212, + 144, 13, 37, 5, 209, 207, 13, 37, 5, 206, 216, 13, 37, 5, 218, 192, 13, + 37, 5, 246, 142, 13, 37, 5, 217, 202, 13, 37, 5, 220, 36, 13, 37, 219, + 69, 243, 205, 13, 37, 241, 38, 97, 13, 37, 209, 75, 97, 13, 37, 229, 248, + 97, 13, 37, 218, 193, 97, 13, 37, 216, 60, 97, 13, 37, 218, 168, 97, 13, + 26, 37, 6, 251, 2, 13, 26, 37, 6, 248, 106, 13, 26, 37, 6, 238, 235, 13, + 26, 37, 6, 244, 37, 13, 26, 37, 6, 241, 37, 13, 26, 37, 6, 202, 83, 13, + 26, 37, 6, 240, 248, 13, 26, 37, 6, 209, 74, 13, 26, 37, 6, 230, 230, 13, + 26, 37, 6, 229, 247, 13, 26, 37, 6, 228, 24, 13, 26, 37, 6, 223, 246, 13, + 26, 37, 6, 221, 84, 13, 26, 37, 6, 203, 170, 13, 26, 37, 6, 220, 34, 13, + 26, 37, 6, 218, 167, 13, 26, 37, 6, 216, 59, 13, 26, 37, 6, 209, 75, 97, + 13, 26, 37, 6, 212, 144, 13, 26, 37, 6, 209, 207, 13, 26, 37, 6, 206, + 216, 13, 26, 37, 6, 218, 192, 13, 26, 37, 6, 246, 142, 13, 26, 37, 6, + 217, 202, 13, 26, 37, 6, 220, 36, 13, 26, 37, 223, 101, 13, 26, 37, 5, + 251, 2, 13, 26, 37, 5, 248, 106, 13, 26, 37, 5, 238, 235, 13, 26, 37, 5, + 244, 37, 13, 26, 37, 5, 241, 37, 13, 26, 37, 5, 202, 83, 13, 26, 37, 5, + 240, 248, 13, 26, 37, 5, 209, 74, 13, 26, 37, 5, 230, 230, 13, 26, 37, 5, + 229, 247, 13, 26, 37, 5, 228, 24, 13, 26, 37, 5, 223, 246, 13, 26, 37, 5, + 221, 84, 13, 26, 37, 5, 203, 170, 13, 26, 37, 5, 220, 34, 13, 26, 37, 5, + 218, 167, 13, 26, 37, 5, 216, 59, 13, 26, 37, 5, 46, 212, 144, 13, 26, + 37, 5, 212, 144, 13, 26, 37, 5, 209, 207, 13, 26, 37, 5, 206, 216, 13, + 26, 37, 5, 218, 192, 13, 26, 37, 5, 246, 142, 13, 26, 37, 5, 217, 202, + 13, 26, 37, 5, 220, 36, 13, 26, 37, 219, 69, 243, 205, 13, 26, 37, 241, + 38, 97, 13, 26, 37, 209, 75, 97, 13, 26, 37, 229, 248, 97, 13, 26, 37, + 218, 193, 97, 13, 26, 37, 216, 60, 97, 13, 26, 37, 218, 168, 97, 13, 41, + 26, 6, 251, 2, 13, 41, 26, 6, 248, 106, 13, 41, 26, 6, 238, 235, 13, 41, + 26, 6, 244, 37, 13, 41, 26, 6, 241, 37, 13, 41, 26, 6, 202, 83, 13, 41, + 26, 6, 240, 248, 13, 41, 26, 6, 209, 74, 13, 41, 26, 6, 230, 230, 13, 41, + 26, 6, 229, 247, 13, 41, 26, 6, 228, 24, 13, 41, 26, 6, 223, 246, 13, 41, + 26, 6, 221, 84, 13, 41, 26, 6, 203, 170, 13, 41, 26, 6, 220, 34, 13, 41, + 26, 6, 218, 167, 13, 41, 26, 6, 216, 59, 13, 41, 26, 6, 209, 75, 97, 13, + 41, 26, 6, 212, 144, 13, 41, 26, 6, 209, 207, 13, 41, 26, 6, 206, 216, + 13, 41, 26, 6, 218, 192, 13, 41, 26, 6, 246, 142, 13, 41, 26, 6, 217, + 202, 13, 41, 26, 6, 220, 36, 13, 41, 26, 223, 101, 13, 41, 26, 5, 251, 2, + 13, 41, 26, 5, 248, 106, 13, 41, 26, 5, 238, 235, 13, 41, 26, 5, 244, 37, + 13, 41, 26, 5, 241, 37, 13, 41, 26, 5, 202, 83, 13, 41, 26, 5, 240, 248, + 13, 41, 26, 5, 209, 74, 13, 41, 26, 5, 230, 230, 13, 41, 26, 5, 229, 247, + 13, 41, 26, 5, 228, 24, 13, 41, 26, 5, 223, 246, 13, 41, 26, 5, 221, 84, + 13, 41, 26, 5, 203, 170, 13, 41, 26, 5, 220, 34, 13, 41, 26, 5, 218, 167, + 13, 41, 26, 5, 216, 59, 13, 41, 26, 5, 46, 212, 144, 13, 41, 26, 5, 212, + 144, 13, 41, 26, 5, 209, 207, 13, 41, 26, 5, 206, 216, 13, 41, 26, 5, + 218, 192, 13, 41, 26, 5, 246, 142, 13, 41, 26, 5, 217, 202, 13, 41, 26, + 5, 220, 36, 13, 41, 26, 219, 69, 243, 205, 13, 41, 26, 241, 38, 97, 13, + 41, 26, 209, 75, 97, 13, 41, 26, 229, 248, 97, 13, 41, 26, 218, 193, 97, + 13, 41, 26, 216, 60, 97, 13, 41, 26, 218, 168, 97, 13, 41, 26, 37, 6, + 251, 2, 13, 41, 26, 37, 6, 248, 106, 13, 41, 26, 37, 6, 238, 235, 13, 41, + 26, 37, 6, 244, 37, 13, 41, 26, 37, 6, 241, 37, 13, 41, 26, 37, 6, 202, + 83, 13, 41, 26, 37, 6, 240, 248, 13, 41, 26, 37, 6, 209, 74, 13, 41, 26, + 37, 6, 230, 230, 13, 41, 26, 37, 6, 229, 247, 13, 41, 26, 37, 6, 228, 24, + 13, 41, 26, 37, 6, 223, 246, 13, 41, 26, 37, 6, 221, 84, 13, 41, 26, 37, + 6, 203, 170, 13, 41, 26, 37, 6, 220, 34, 13, 41, 26, 37, 6, 218, 167, 13, + 41, 26, 37, 6, 216, 59, 13, 41, 26, 37, 6, 209, 75, 97, 13, 41, 26, 37, + 6, 212, 144, 13, 41, 26, 37, 6, 209, 207, 13, 41, 26, 37, 6, 206, 216, + 13, 41, 26, 37, 6, 218, 192, 13, 41, 26, 37, 6, 246, 142, 13, 41, 26, 37, + 6, 217, 202, 13, 41, 26, 37, 6, 220, 36, 13, 41, 26, 37, 223, 101, 13, + 41, 26, 37, 5, 251, 2, 13, 41, 26, 37, 5, 248, 106, 13, 41, 26, 37, 5, + 238, 235, 13, 41, 26, 37, 5, 244, 37, 13, 41, 26, 37, 5, 241, 37, 13, 41, + 26, 37, 5, 202, 83, 13, 41, 26, 37, 5, 240, 248, 13, 41, 26, 37, 5, 209, + 74, 13, 41, 26, 37, 5, 230, 230, 13, 41, 26, 37, 5, 229, 247, 13, 41, 26, + 37, 5, 228, 24, 13, 41, 26, 37, 5, 223, 246, 13, 41, 26, 37, 5, 221, 84, + 13, 41, 26, 37, 5, 203, 170, 13, 41, 26, 37, 5, 220, 34, 13, 41, 26, 37, + 5, 218, 167, 13, 41, 26, 37, 5, 216, 59, 13, 41, 26, 37, 5, 46, 212, 144, + 13, 41, 26, 37, 5, 212, 144, 13, 41, 26, 37, 5, 209, 207, 13, 41, 26, 37, + 5, 206, 216, 13, 41, 26, 37, 5, 218, 192, 13, 41, 26, 37, 5, 246, 142, + 13, 41, 26, 37, 5, 217, 202, 13, 41, 26, 37, 5, 220, 36, 13, 41, 26, 37, + 219, 69, 243, 205, 13, 41, 26, 37, 241, 38, 97, 13, 41, 26, 37, 209, 75, + 97, 13, 41, 26, 37, 229, 248, 97, 13, 41, 26, 37, 218, 193, 97, 13, 41, + 26, 37, 216, 60, 97, 13, 41, 26, 37, 218, 168, 97, 13, 26, 6, 243, 199, + 13, 26, 5, 243, 199, 13, 26, 17, 202, 84, 13, 26, 17, 105, 13, 26, 17, + 108, 13, 26, 17, 147, 13, 26, 17, 149, 13, 26, 17, 170, 13, 26, 17, 195, + 13, 26, 17, 213, 111, 13, 26, 17, 199, 13, 26, 17, 222, 63, 13, 169, 17, + 202, 84, 13, 169, 17, 105, 13, 169, 17, 108, 13, 169, 17, 147, 13, 169, + 17, 149, 13, 169, 17, 170, 13, 169, 17, 195, 13, 169, 17, 213, 111, 13, + 169, 17, 199, 13, 169, 17, 222, 63, 13, 41, 17, 202, 84, 13, 41, 17, 105, + 13, 41, 17, 108, 13, 41, 17, 147, 13, 41, 17, 149, 13, 41, 17, 170, 13, + 41, 17, 195, 13, 41, 17, 213, 111, 13, 41, 17, 199, 13, 41, 17, 222, 63, + 13, 41, 26, 17, 202, 84, 13, 41, 26, 17, 105, 13, 41, 26, 17, 108, 13, + 41, 26, 17, 147, 13, 41, 26, 17, 149, 13, 41, 26, 17, 170, 13, 41, 26, + 17, 195, 13, 41, 26, 17, 213, 111, 13, 41, 26, 17, 199, 13, 41, 26, 17, + 222, 63, 13, 224, 41, 17, 202, 84, 13, 224, 41, 17, 105, 13, 224, 41, 17, + 108, 13, 224, 41, 17, 147, 13, 224, 41, 17, 149, 13, 224, 41, 17, 170, + 13, 224, 41, 17, 195, 13, 224, 41, 17, 213, 111, 13, 224, 41, 17, 199, + 13, 224, 41, 17, 222, 63, 21, 128, 231, 35, 21, 237, 120, 231, 35, 21, + 237, 116, 231, 35, 21, 237, 105, 231, 35, 21, 237, 109, 231, 35, 21, 237, + 122, 231, 35, 21, 128, 122, 248, 117, 21, 237, 120, 122, 248, 117, 21, + 128, 148, 206, 248, 122, 248, 117, 21, 128, 122, 216, 188, 229, 29, 21, + 128, 122, 245, 97, 21, 128, 122, 236, 235, 21, 128, 122, 236, 236, 227, + 0, 21, 237, 120, 122, 236, 237, 21, 128, 122, 224, 148, 21, 237, 120, + 122, 224, 148, 21, 128, 122, 101, 248, 117, 21, 128, 122, 101, 216, 188, + 229, 28, 21, 128, 122, 101, 236, 235, 21, 128, 122, 112, 101, 236, 235, + 21, 128, 122, 236, 236, 101, 206, 224, 21, 128, 122, 101, 245, 207, 21, + 128, 122, 101, 245, 208, 122, 248, 117, 21, 128, 122, 101, 245, 208, 101, + 248, 117, 21, 128, 122, 101, 245, 208, 245, 97, 21, 128, 122, 101, 245, + 208, 236, 235, 21, 128, 122, 101, 245, 127, 21, 237, 120, 122, 101, 245, + 127, 21, 128, 101, 248, 118, 115, 231, 35, 21, 128, 122, 248, 118, 115, + 224, 148, 21, 128, 122, 101, 209, 21, 21, 237, 120, 122, 101, 209, 21, + 21, 128, 122, 101, 211, 53, 148, 248, 117, 21, 128, 122, 101, 248, 118, + 148, 211, 52, 21, 128, 122, 101, 148, 248, 117, 21, 128, 122, 101, 236, + 236, 211, 186, 148, 212, 155, 21, 128, 122, 112, 101, 236, 236, 148, 212, + 155, 21, 128, 122, 112, 101, 236, 236, 148, 245, 207, 21, 128, 122, 236, + 236, 101, 112, 148, 212, 155, 21, 128, 122, 101, 112, 211, 186, 148, 239, + 151, 21, 128, 122, 101, 148, 245, 97, 21, 128, 122, 101, 148, 246, 60, + 21, 128, 122, 101, 148, 236, 114, 21, 128, 122, 101, 148, 236, 235, 21, + 128, 148, 248, 104, 122, 101, 211, 52, 21, 128, 122, 101, 245, 208, 148, + 212, 155, 21, 128, 122, 101, 245, 208, 148, 212, 156, 245, 207, 21, 128, + 122, 101, 245, 208, 148, 212, 156, 248, 117, 21, 128, 101, 148, 236, 115, + 122, 206, 224, 21, 128, 122, 148, 236, 115, 101, 206, 224, 21, 128, 122, + 101, 245, 208, 236, 236, 148, 212, 155, 21, 128, 122, 101, 245, 128, 148, + 212, 155, 21, 128, 122, 101, 245, 208, 148, 239, 151, 21, 128, 122, 101, + 245, 208, 245, 98, 148, 239, 151, 21, 128, 101, 148, 245, 98, 122, 206, + 224, 21, 128, 122, 148, 245, 98, 101, 206, 224, 21, 128, 101, 148, 43, + 122, 206, 224, 21, 128, 101, 148, 43, 122, 236, 235, 21, 128, 122, 148, + 250, 216, 219, 212, 101, 206, 224, 21, 128, 122, 148, 250, 216, 231, 50, + 101, 206, 224, 21, 128, 122, 148, 43, 101, 206, 224, 21, 128, 122, 101, + 148, 245, 208, 236, 235, 21, 128, 122, 101, 148, 250, 216, 219, 211, 21, + 128, 122, 101, 148, 250, 215, 21, 128, 101, 148, 250, 216, 219, 212, 122, + 206, 224, 21, 128, 101, 148, 250, 216, 219, 212, 122, 245, 127, 21, 128, + 101, 148, 250, 216, 122, 206, 224, 21, 128, 122, 148, 236, 115, 101, 236, + 235, 21, 237, 111, 239, 147, 239, 253, 21, 237, 111, 239, 147, 239, 254, + 248, 117, 21, 237, 111, 239, 147, 239, 254, 236, 235, 21, 237, 111, 239, + 147, 239, 254, 245, 207, 21, 237, 111, 239, 147, 239, 254, 245, 208, 211, + 193, 21, 237, 118, 239, 147, 239, 254, 245, 207, 21, 128, 239, 147, 239, + 254, 245, 208, 248, 117, 21, 237, 109, 239, 147, 239, 254, 245, 207, 21, + 237, 111, 239, 233, 239, 254, 211, 185, 21, 237, 111, 237, 46, 239, 233, + 239, 254, 211, 185, 21, 237, 111, 239, 233, 239, 254, 211, 186, 239, 147, + 248, 117, 21, 237, 111, 237, 46, 239, 233, 239, 254, 211, 186, 239, 147, + 248, 117, 21, 237, 111, 239, 233, 239, 254, 211, 186, 248, 117, 21, 237, + 111, 237, 46, 239, 233, 239, 254, 211, 186, 248, 117, 21, 237, 111, 239, + 233, 239, 254, 211, 186, 148, 239, 151, 21, 237, 116, 239, 233, 239, 254, + 211, 185, 21, 237, 116, 239, 233, 239, 254, 211, 186, 220, 8, 21, 237, + 109, 239, 233, 239, 254, 211, 186, 220, 8, 21, 237, 105, 239, 233, 239, + 254, 211, 185, 21, 237, 111, 239, 233, 239, 254, 211, 186, 236, 235, 21, + 237, 111, 239, 233, 239, 254, 211, 186, 236, 236, 148, 212, 155, 21, 237, + 111, 239, 233, 239, 254, 211, 186, 236, 236, 221, 192, 209, 21, 21, 237, + 110, 21, 237, 111, 248, 104, 219, 135, 240, 94, 21, 237, 111, 237, 45, + 21, 237, 111, 148, 212, 155, 21, 237, 111, 237, 46, 148, 212, 155, 21, + 237, 111, 148, 248, 117, 21, 237, 111, 148, 239, 151, 21, 237, 111, 211, + 194, 122, 148, 212, 155, 21, 237, 111, 211, 194, 246, 217, 21, 237, 111, + 211, 194, 246, 218, 148, 212, 155, 21, 237, 111, 211, 194, 246, 218, 148, + 212, 156, 248, 117, 21, 237, 111, 211, 194, 227, 85, 21, 237, 117, 21, + 237, 118, 148, 212, 155, 21, 237, 118, 221, 192, 209, 21, 21, 237, 118, + 148, 239, 151, 21, 237, 107, 245, 94, 21, 237, 106, 21, 237, 116, 220, 8, + 21, 237, 115, 21, 237, 116, 171, 148, 212, 155, 21, 237, 116, 148, 212, + 155, 21, 237, 116, 171, 221, 192, 209, 21, 21, 237, 116, 221, 192, 209, + 21, 21, 237, 116, 171, 148, 239, 151, 21, 237, 116, 148, 239, 151, 21, + 237, 114, 220, 8, 21, 237, 113, 21, 237, 119, 21, 237, 104, 21, 237, 105, + 148, 212, 155, 21, 237, 105, 221, 192, 209, 21, 21, 237, 105, 148, 239, + 151, 21, 237, 109, 220, 8, 21, 237, 109, 171, 148, 239, 151, 21, 237, + 108, 21, 237, 109, 212, 36, 21, 237, 109, 171, 148, 212, 155, 21, 237, + 109, 148, 212, 155, 21, 237, 109, 171, 221, 192, 209, 21, 21, 237, 109, + 221, 192, 209, 21, 21, 237, 109, 148, 212, 156, 208, 127, 231, 35, 21, + 237, 109, 148, 248, 104, 101, 215, 252, 21, 237, 121, 21, 128, 122, 101, + 215, 252, 21, 237, 120, 122, 101, 215, 252, 21, 237, 109, 122, 101, 215, + 252, 21, 237, 122, 122, 101, 215, 252, 21, 237, 109, 227, 85, 21, 128, + 122, 101, 215, 253, 248, 117, 21, 128, 122, 101, 215, 253, 245, 207, 21, + 237, 109, 122, 101, 215, 253, 245, 207, 21, 128, 227, 86, 242, 70, 21, + 128, 227, 86, 121, 215, 248, 211, 52, 21, 128, 227, 86, 121, 215, 248, + 245, 85, 21, 128, 227, 86, 121, 219, 220, 246, 60, 21, 128, 227, 86, 206, + 224, 21, 128, 148, 206, 248, 227, 86, 206, 224, 21, 237, 120, 227, 86, + 206, 224, 21, 237, 105, 227, 86, 206, 224, 21, 237, 122, 227, 86, 206, + 224, 21, 128, 227, 86, 216, 188, 229, 29, 21, 128, 227, 86, 248, 117, 21, + 128, 227, 86, 208, 128, 209, 21, 21, 128, 227, 86, 209, 21, 21, 237, 109, + 227, 86, 209, 21, 21, 128, 227, 86, 122, 209, 21, 21, 237, 109, 227, 86, + 122, 209, 21, 21, 237, 122, 227, 86, 122, 148, 122, 148, 219, 211, 21, + 237, 122, 227, 86, 122, 148, 122, 209, 21, 21, 128, 227, 86, 231, 35, 21, + 237, 120, 227, 86, 231, 35, 21, 237, 109, 227, 86, 231, 35, 21, 237, 122, + 227, 86, 231, 35, 21, 128, 122, 101, 227, 85, 21, 237, 120, 122, 101, + 227, 85, 21, 237, 109, 122, 101, 227, 85, 21, 237, 109, 215, 252, 21, + 237, 122, 122, 101, 227, 85, 21, 128, 122, 101, 245, 131, 227, 85, 21, + 237, 120, 122, 101, 245, 131, 227, 85, 21, 128, 215, 253, 242, 70, 21, + 237, 109, 215, 253, 121, 122, 148, 236, 116, 224, 148, 21, 237, 122, 215, + 253, 121, 101, 148, 122, 245, 130, 21, 128, 215, 253, 206, 224, 21, 128, + 215, 253, 216, 188, 229, 29, 21, 128, 215, 253, 227, 85, 21, 237, 120, + 215, 253, 227, 85, 21, 237, 105, 215, 253, 227, 85, 21, 237, 122, 215, + 253, 227, 85, 21, 128, 215, 253, 224, 148, 21, 128, 215, 253, 101, 245, + 207, 21, 128, 215, 253, 101, 216, 188, 229, 28, 21, 128, 215, 253, 231, + 35, 21, 128, 215, 253, 209, 21, 21, 237, 107, 215, 253, 209, 21, 21, 128, + 122, 215, 253, 227, 85, 21, 237, 120, 122, 215, 253, 227, 85, 21, 237, + 114, 122, 215, 253, 227, 86, 220, 31, 21, 237, 107, 122, 215, 253, 227, + 86, 219, 211, 21, 237, 107, 122, 215, 253, 227, 86, 231, 49, 21, 237, + 107, 122, 215, 253, 227, 86, 206, 247, 21, 237, 116, 122, 215, 253, 227, + 85, 21, 237, 109, 122, 215, 253, 227, 85, 21, 237, 122, 122, 215, 253, + 227, 86, 219, 211, 21, 237, 122, 122, 215, 253, 227, 85, 21, 128, 101, + 242, 70, 21, 237, 109, 224, 148, 21, 128, 101, 206, 224, 21, 237, 120, + 101, 206, 224, 21, 128, 101, 216, 188, 229, 29, 21, 128, 101, 112, 148, + 212, 155, 21, 237, 107, 101, 209, 21, 21, 128, 101, 148, 227, 85, 21, + 128, 101, 227, 85, 21, 128, 101, 215, 253, 227, 85, 21, 237, 120, 101, + 215, 253, 227, 85, 21, 237, 114, 101, 215, 253, 227, 86, 220, 31, 21, + 237, 116, 101, 215, 253, 227, 85, 21, 237, 109, 101, 215, 253, 227, 85, + 21, 237, 122, 101, 215, 253, 227, 86, 219, 211, 21, 237, 122, 101, 215, + 253, 227, 86, 231, 49, 21, 237, 122, 101, 215, 253, 227, 85, 21, 237, + 120, 101, 215, 253, 227, 86, 248, 117, 21, 237, 118, 101, 215, 253, 227, + 86, 245, 207, 21, 237, 118, 101, 215, 253, 227, 86, 245, 208, 212, 155, + 21, 237, 107, 101, 215, 253, 227, 86, 245, 208, 219, 211, 21, 237, 107, + 101, 215, 253, 227, 86, 245, 208, 231, 49, 21, 237, 107, 101, 215, 253, + 227, 86, 245, 207, 21, 237, 109, 122, 236, 235, 21, 128, 122, 148, 212, + 155, 21, 237, 109, 122, 148, 212, 155, 21, 128, 122, 148, 212, 156, 148, + 243, 227, 21, 128, 122, 148, 212, 156, 148, 245, 207, 21, 128, 122, 148, + 212, 156, 148, 248, 117, 21, 128, 122, 148, 212, 156, 122, 248, 117, 21, + 128, 122, 148, 212, 156, 247, 251, 248, 117, 21, 128, 122, 148, 212, 156, + 122, 236, 237, 21, 128, 122, 148, 239, 152, 122, 211, 52, 21, 128, 122, + 148, 239, 152, 122, 248, 117, 21, 128, 122, 148, 113, 21, 128, 122, 148, + 245, 94, 21, 128, 122, 148, 245, 88, 148, 231, 6, 21, 237, 118, 122, 148, + 245, 88, 148, 231, 6, 21, 128, 122, 148, 245, 88, 148, 206, 247, 21, 128, + 122, 148, 246, 61, 21, 237, 116, 122, 209, 21, 21, 237, 116, 122, 148, + 220, 8, 21, 237, 109, 122, 148, 220, 8, 21, 237, 109, 122, 148, 228, 7, + 21, 237, 109, 122, 209, 21, 21, 237, 109, 122, 148, 212, 36, 21, 237, + 122, 122, 148, 219, 211, 21, 237, 122, 122, 148, 231, 49, 21, 237, 122, + 122, 209, 21, 21, 128, 209, 21, 21, 128, 148, 237, 45, 21, 128, 148, 212, + 156, 243, 227, 21, 128, 148, 212, 156, 245, 207, 21, 128, 148, 212, 156, + 248, 117, 21, 128, 148, 239, 151, 21, 128, 148, 248, 104, 122, 224, 148, + 21, 128, 148, 248, 104, 101, 215, 252, 21, 128, 148, 248, 104, 215, 253, + 227, 85, 21, 128, 148, 206, 248, 120, 239, 253, 21, 128, 148, 115, 120, + 239, 253, 21, 128, 148, 206, 248, 126, 239, 253, 21, 128, 148, 206, 248, + 239, 147, 239, 253, 21, 128, 148, 115, 239, 147, 216, 188, 229, 28, 21, + 237, 112, 21, 128, 237, 45, 21, 208, 129, 212, 119, 21, 208, 129, 223, + 225, 21, 208, 129, 248, 103, 21, 238, 2, 212, 119, 21, 238, 2, 223, 225, + 21, 238, 2, 248, 103, 21, 211, 37, 212, 119, 21, 211, 37, 223, 225, 21, + 211, 37, 248, 103, 21, 247, 201, 212, 119, 21, 247, 201, 223, 225, 21, + 247, 201, 248, 103, 21, 215, 143, 212, 119, 21, 215, 143, 223, 225, 21, + 215, 143, 248, 103, 21, 210, 189, 210, 102, 21, 210, 189, 248, 103, 21, + 211, 173, 228, 8, 212, 119, 21, 211, 173, 5, 212, 119, 21, 211, 173, 228, + 8, 223, 225, 21, 211, 173, 5, 223, 225, 21, 211, 173, 213, 126, 21, 239, + 208, 228, 8, 212, 119, 21, 239, 208, 5, 212, 119, 21, 239, 208, 228, 8, + 223, 225, 21, 239, 208, 5, 223, 225, 21, 239, 208, 213, 126, 21, 211, + 173, 239, 208, 250, 252, 21, 224, 0, 112, 121, 228, 7, 21, 224, 0, 112, + 121, 212, 36, 21, 224, 0, 112, 213, 126, 21, 224, 0, 121, 213, 126, 21, + 224, 0, 112, 121, 250, 253, 228, 7, 21, 224, 0, 112, 121, 250, 253, 212, + 36, 21, 224, 0, 212, 156, 208, 173, 212, 156, 214, 190, 21, 223, 255, + 240, 3, 245, 197, 21, 224, 1, 240, 3, 245, 197, 21, 223, 255, 212, 120, + 211, 53, 212, 36, 21, 223, 255, 212, 120, 211, 53, 225, 9, 21, 223, 255, + 212, 120, 211, 53, 228, 7, 21, 223, 255, 212, 120, 211, 53, 228, 5, 21, + 223, 255, 212, 120, 203, 221, 239, 211, 21, 223, 255, 52, 211, 52, 21, + 223, 255, 52, 203, 221, 239, 211, 21, 223, 255, 52, 250, 252, 21, 223, + 255, 52, 250, 253, 203, 221, 239, 211, 21, 223, 255, 245, 130, 21, 223, + 255, 208, 70, 211, 53, 224, 3, 21, 223, 255, 208, 70, 203, 221, 239, 211, + 21, 223, 255, 208, 70, 250, 252, 21, 223, 255, 208, 70, 250, 253, 203, + 221, 239, 211, 21, 223, 255, 248, 121, 212, 36, 21, 223, 255, 248, 121, + 225, 9, 21, 223, 255, 248, 121, 228, 7, 21, 223, 255, 245, 166, 212, 36, + 21, 223, 255, 245, 166, 225, 9, 21, 223, 255, 245, 166, 228, 7, 21, 223, + 255, 245, 166, 215, 196, 21, 223, 255, 246, 169, 212, 36, 21, 223, 255, + 246, 169, 225, 9, 21, 223, 255, 246, 169, 228, 7, 21, 223, 255, 98, 212, + 36, 21, 223, 255, 98, 225, 9, 21, 223, 255, 98, 228, 7, 21, 223, 255, + 202, 30, 212, 36, 21, 223, 255, 202, 30, 225, 9, 21, 223, 255, 202, 30, + 228, 7, 21, 223, 255, 219, 30, 212, 36, 21, 223, 255, 219, 30, 225, 9, + 21, 223, 255, 219, 30, 228, 7, 21, 208, 99, 215, 194, 212, 119, 21, 208, + 99, 215, 194, 242, 78, 21, 208, 99, 215, 194, 250, 252, 21, 208, 99, 215, + 195, 212, 119, 21, 208, 99, 215, 195, 242, 78, 21, 208, 99, 215, 195, + 250, 252, 21, 208, 99, 213, 71, 21, 208, 99, 250, 107, 211, 202, 212, + 119, 21, 208, 99, 250, 107, 211, 202, 242, 78, 21, 208, 99, 250, 107, + 211, 202, 208, 69, 21, 224, 2, 250, 12, 212, 36, 21, 224, 2, 250, 12, + 225, 9, 21, 224, 2, 250, 12, 228, 7, 21, 224, 2, 250, 12, 228, 5, 21, + 224, 2, 208, 123, 212, 36, 21, 224, 2, 208, 123, 225, 9, 21, 224, 2, 208, + 123, 228, 7, 21, 224, 2, 208, 123, 228, 5, 21, 224, 2, 248, 104, 250, 12, + 212, 36, 21, 224, 2, 248, 104, 250, 12, 225, 9, 21, 224, 2, 248, 104, + 250, 12, 228, 7, 21, 224, 2, 248, 104, 250, 12, 228, 5, 21, 224, 2, 248, + 104, 208, 123, 212, 36, 21, 224, 2, 248, 104, 208, 123, 225, 9, 21, 224, + 2, 248, 104, 208, 123, 228, 7, 21, 224, 2, 248, 104, 208, 123, 228, 5, + 21, 224, 1, 212, 120, 211, 53, 212, 36, 21, 224, 1, 212, 120, 211, 53, + 225, 9, 21, 224, 1, 212, 120, 211, 53, 228, 7, 21, 224, 1, 212, 120, 211, + 53, 228, 5, 21, 224, 1, 212, 120, 203, 221, 239, 211, 21, 224, 1, 52, + 211, 52, 21, 224, 1, 52, 203, 221, 239, 211, 21, 224, 1, 52, 250, 252, + 21, 224, 1, 52, 250, 253, 203, 221, 239, 211, 21, 224, 1, 245, 130, 21, + 224, 1, 208, 70, 211, 53, 224, 3, 21, 224, 1, 208, 70, 203, 221, 239, + 211, 21, 224, 1, 208, 70, 250, 253, 224, 3, 21, 224, 1, 208, 70, 250, + 253, 203, 221, 239, 211, 21, 224, 1, 248, 120, 21, 224, 1, 245, 166, 212, + 36, 21, 224, 1, 245, 166, 225, 9, 21, 224, 1, 245, 166, 228, 7, 21, 224, + 1, 246, 168, 21, 224, 1, 98, 212, 36, 21, 224, 1, 98, 225, 9, 21, 224, 1, + 98, 228, 7, 21, 224, 1, 202, 30, 212, 36, 21, 224, 1, 202, 30, 225, 9, + 21, 224, 1, 202, 30, 228, 7, 21, 224, 1, 219, 30, 212, 36, 21, 224, 1, + 219, 30, 225, 9, 21, 224, 1, 219, 30, 228, 7, 21, 208, 100, 215, 195, + 212, 119, 21, 208, 100, 215, 195, 242, 78, 21, 208, 100, 215, 195, 250, + 252, 21, 208, 100, 215, 194, 212, 119, 21, 208, 100, 215, 194, 242, 78, + 21, 208, 100, 215, 194, 250, 252, 21, 208, 100, 213, 71, 21, 223, 255, + 245, 88, 217, 56, 212, 36, 21, 223, 255, 245, 88, 217, 56, 225, 9, 21, + 223, 255, 245, 88, 217, 56, 228, 7, 21, 223, 255, 245, 88, 217, 56, 228, + 5, 21, 223, 255, 245, 88, 237, 136, 212, 36, 21, 223, 255, 245, 88, 237, + 136, 225, 9, 21, 223, 255, 245, 88, 237, 136, 228, 7, 21, 223, 255, 245, + 88, 237, 136, 228, 5, 21, 223, 255, 245, 88, 209, 27, 246, 62, 212, 36, + 21, 223, 255, 245, 88, 209, 27, 246, 62, 225, 9, 21, 223, 255, 236, 14, + 212, 36, 21, 223, 255, 236, 14, 225, 9, 21, 223, 255, 236, 14, 228, 7, + 21, 223, 255, 227, 15, 212, 36, 21, 223, 255, 227, 15, 225, 9, 21, 223, + 255, 227, 15, 228, 7, 21, 223, 255, 227, 15, 5, 242, 78, 21, 223, 255, + 204, 76, 245, 88, 52, 212, 36, 21, 223, 255, 204, 76, 245, 88, 52, 225, + 9, 21, 223, 255, 204, 76, 245, 88, 52, 228, 7, 21, 223, 255, 204, 76, + 245, 88, 208, 70, 212, 36, 21, 223, 255, 204, 76, 245, 88, 208, 70, 225, + 9, 21, 223, 255, 204, 76, 245, 88, 208, 70, 228, 7, 21, 223, 255, 245, + 88, 209, 84, 211, 52, 21, 223, 255, 245, 86, 245, 131, 212, 36, 21, 223, + 255, 245, 86, 245, 131, 225, 9, 21, 215, 194, 212, 119, 21, 215, 194, + 242, 78, 21, 215, 194, 250, 254, 21, 223, 255, 213, 71, 21, 223, 255, + 245, 88, 236, 229, 239, 119, 204, 99, 21, 223, 255, 236, 14, 236, 229, + 239, 119, 204, 99, 21, 223, 255, 227, 15, 236, 229, 239, 119, 204, 99, + 21, 223, 255, 204, 76, 236, 229, 239, 119, 204, 99, 21, 215, 194, 212, + 120, 236, 229, 239, 119, 204, 99, 21, 215, 194, 52, 236, 229, 239, 119, + 204, 99, 21, 215, 194, 250, 253, 236, 229, 239, 119, 204, 99, 21, 223, + 255, 245, 88, 236, 229, 246, 149, 21, 223, 255, 236, 14, 236, 229, 246, + 149, 21, 223, 255, 227, 15, 236, 229, 246, 149, 21, 223, 255, 204, 76, + 236, 229, 246, 149, 21, 215, 194, 212, 120, 236, 229, 246, 149, 21, 215, + 194, 52, 236, 229, 246, 149, 21, 215, 194, 250, 253, 236, 229, 246, 149, + 21, 223, 255, 204, 76, 243, 228, 219, 52, 212, 36, 21, 223, 255, 204, 76, + 243, 228, 219, 52, 225, 9, 21, 223, 255, 204, 76, 243, 228, 219, 52, 228, + 7, 21, 224, 1, 245, 88, 236, 229, 246, 227, 212, 36, 21, 224, 1, 245, 88, + 236, 229, 246, 227, 228, 7, 21, 224, 1, 236, 14, 236, 229, 246, 227, 5, + 242, 78, 21, 224, 1, 236, 14, 236, 229, 246, 227, 228, 8, 242, 78, 21, + 224, 1, 236, 14, 236, 229, 246, 227, 5, 208, 69, 21, 224, 1, 236, 14, + 236, 229, 246, 227, 228, 8, 208, 69, 21, 224, 1, 227, 15, 236, 229, 246, + 227, 5, 212, 119, 21, 224, 1, 227, 15, 236, 229, 246, 227, 228, 8, 212, + 119, 21, 224, 1, 227, 15, 236, 229, 246, 227, 5, 242, 78, 21, 224, 1, + 227, 15, 236, 229, 246, 227, 228, 8, 242, 78, 21, 224, 1, 204, 76, 236, + 229, 246, 227, 212, 36, 21, 224, 1, 204, 76, 236, 229, 246, 227, 228, 7, + 21, 215, 195, 212, 120, 236, 229, 246, 226, 21, 215, 195, 52, 236, 229, + 246, 226, 21, 215, 195, 250, 253, 236, 229, 246, 226, 21, 224, 1, 245, + 88, 236, 229, 239, 205, 212, 36, 21, 224, 1, 245, 88, 236, 229, 239, 205, + 228, 7, 21, 224, 1, 236, 14, 236, 229, 239, 205, 5, 242, 78, 21, 224, 1, + 236, 14, 236, 229, 239, 205, 228, 8, 242, 78, 21, 224, 1, 236, 14, 236, + 229, 239, 205, 208, 70, 5, 208, 69, 21, 224, 1, 236, 14, 236, 229, 239, + 205, 208, 70, 228, 8, 208, 69, 21, 224, 1, 227, 15, 236, 229, 239, 205, + 5, 212, 119, 21, 224, 1, 227, 15, 236, 229, 239, 205, 228, 8, 212, 119, + 21, 224, 1, 227, 15, 236, 229, 239, 205, 5, 242, 78, 21, 224, 1, 227, 15, + 236, 229, 239, 205, 228, 8, 242, 78, 21, 224, 1, 204, 76, 236, 229, 239, + 205, 212, 36, 21, 224, 1, 204, 76, 236, 229, 239, 205, 228, 7, 21, 215, + 195, 212, 120, 236, 229, 239, 204, 21, 215, 195, 52, 236, 229, 239, 204, + 21, 215, 195, 250, 253, 236, 229, 239, 204, 21, 224, 1, 245, 88, 212, 36, + 21, 224, 1, 245, 88, 225, 9, 21, 224, 1, 245, 88, 228, 7, 21, 224, 1, + 245, 88, 228, 5, 21, 224, 1, 245, 88, 245, 237, 21, 224, 1, 236, 14, 212, + 36, 21, 224, 1, 227, 15, 212, 36, 21, 224, 1, 204, 76, 212, 24, 21, 224, + 1, 204, 76, 212, 36, 21, 224, 1, 204, 76, 228, 7, 21, 215, 195, 212, 119, + 21, 215, 195, 242, 78, 21, 215, 195, 250, 252, 21, 224, 1, 213, 72, 219, + 81, 21, 223, 255, 250, 107, 246, 62, 5, 212, 119, 21, 223, 255, 250, 107, + 246, 62, 225, 10, 212, 119, 21, 223, 255, 250, 107, 246, 62, 5, 242, 78, + 21, 223, 255, 250, 107, 246, 62, 225, 10, 242, 78, 21, 224, 1, 250, 107, + 246, 62, 236, 229, 204, 100, 5, 212, 119, 21, 224, 1, 250, 107, 246, 62, + 236, 229, 204, 100, 225, 10, 212, 119, 21, 224, 1, 250, 107, 246, 62, + 236, 229, 204, 100, 228, 8, 212, 119, 21, 224, 1, 250, 107, 246, 62, 236, + 229, 204, 100, 5, 242, 78, 21, 224, 1, 250, 107, 246, 62, 236, 229, 204, + 100, 225, 10, 242, 78, 21, 224, 1, 250, 107, 246, 62, 236, 229, 204, 100, + 228, 8, 242, 78, 21, 223, 255, 203, 221, 246, 62, 239, 119, 212, 119, 21, + 223, 255, 203, 221, 246, 62, 239, 119, 242, 78, 21, 224, 1, 203, 221, + 246, 62, 236, 229, 204, 100, 212, 119, 21, 224, 1, 203, 221, 246, 62, + 236, 229, 204, 100, 242, 78, 21, 223, 255, 240, 3, 246, 59, 212, 119, 21, + 223, 255, 240, 3, 246, 59, 242, 78, 21, 224, 1, 240, 3, 246, 59, 236, + 229, 204, 100, 212, 119, 21, 224, 1, 240, 3, 246, 59, 236, 229, 204, 100, + 242, 78, 21, 242, 4, 250, 95, 212, 36, 21, 242, 4, 250, 95, 228, 7, 21, + 242, 4, 240, 74, 21, 242, 4, 212, 39, 21, 242, 4, 209, 145, 21, 242, 4, + 216, 115, 21, 242, 4, 212, 125, 21, 242, 4, 212, 126, 250, 252, 21, 242, + 4, 240, 221, 219, 221, 208, 221, 21, 242, 4, 238, 12, 21, 237, 64, 21, + 237, 65, 216, 1, 21, 237, 65, 223, 255, 211, 52, 21, 237, 65, 223, 255, + 208, 224, 21, 237, 65, 224, 1, 211, 52, 21, 237, 65, 223, 255, 245, 87, + 21, 237, 65, 224, 1, 245, 87, 21, 237, 65, 224, 4, 246, 61, 21, 240, 103, + 243, 166, 218, 34, 221, 168, 239, 152, 208, 222, 21, 240, 103, 243, 166, + 218, 34, 221, 168, 112, 219, 245, 242, 70, 21, 240, 103, 243, 166, 218, + 34, 221, 168, 112, 219, 245, 121, 208, 222, 21, 240, 190, 211, 53, 206, + 224, 21, 240, 190, 211, 53, 222, 215, 21, 240, 190, 211, 53, 242, 70, 21, + 242, 57, 240, 190, 222, 216, 242, 70, 21, 242, 57, 240, 190, 121, 222, + 215, 21, 242, 57, 240, 190, 112, 222, 215, 21, 242, 57, 240, 190, 222, + 216, 206, 224, 21, 239, 164, 222, 215, 21, 239, 164, 245, 197, 21, 239, + 164, 203, 224, 21, 240, 185, 220, 8, 21, 240, 185, 211, 172, 21, 240, + 185, 246, 15, 21, 240, 192, 248, 34, 212, 119, 21, 240, 192, 248, 34, + 223, 225, 21, 240, 185, 162, 220, 8, 21, 240, 185, 204, 27, 220, 8, 21, + 240, 185, 162, 246, 15, 21, 240, 185, 204, 25, 224, 3, 21, 240, 192, 204, + 9, 21, 240, 186, 206, 224, 21, 240, 186, 242, 70, 21, 240, 186, 239, 191, + 21, 240, 188, 211, 52, 21, 240, 188, 211, 53, 242, 78, 21, 240, 188, 211, + 53, 250, 252, 21, 240, 189, 211, 52, 21, 240, 189, 211, 53, 242, 78, 21, + 240, 189, 211, 53, 250, 252, 21, 240, 188, 245, 85, 21, 240, 189, 245, + 85, 21, 240, 188, 246, 56, 21, 246, 164, 217, 182, 21, 246, 164, 222, + 215, 21, 246, 164, 210, 234, 21, 209, 146, 246, 164, 236, 244, 21, 209, + 146, 246, 164, 224, 148, 21, 209, 146, 246, 164, 227, 0, 21, 241, 181, + 21, 221, 168, 222, 215, 21, 221, 168, 245, 197, 21, 221, 168, 203, 222, + 21, 221, 168, 204, 22, 21, 251, 55, 248, 27, 219, 211, 21, 251, 55, 210, + 233, 231, 49, 21, 251, 55, 248, 29, 5, 215, 193, 21, 251, 55, 210, 235, + 5, 215, 193, 21, 247, 216, 231, 22, 21, 247, 216, 240, 210, 21, 224, 8, + 246, 16, 222, 215, 21, 224, 8, 246, 16, 239, 151, 21, 224, 8, 246, 16, + 245, 197, 21, 224, 8, 212, 31, 21, 224, 8, 212, 32, 203, 224, 21, 224, 8, + 212, 32, 220, 8, 21, 224, 8, 239, 115, 21, 224, 8, 239, 116, 203, 224, + 21, 224, 8, 239, 116, 220, 8, 21, 224, 8, 171, 246, 61, 21, 224, 8, 171, + 239, 151, 21, 224, 8, 171, 203, 224, 21, 224, 8, 171, 219, 204, 21, 224, + 8, 171, 219, 205, 203, 224, 21, 224, 8, 171, 219, 205, 203, 59, 21, 224, + 8, 171, 216, 143, 21, 224, 8, 171, 216, 144, 203, 224, 21, 224, 8, 171, + 216, 144, 203, 59, 21, 224, 8, 229, 66, 21, 224, 8, 229, 67, 239, 151, + 21, 224, 8, 229, 67, 203, 224, 21, 224, 8, 209, 145, 21, 224, 8, 209, + 146, 239, 151, 21, 224, 8, 209, 146, 210, 234, 21, 227, 99, 217, 239, + 208, 169, 21, 227, 101, 226, 251, 115, 206, 220, 21, 227, 101, 206, 221, + 115, 226, 250, 21, 224, 8, 245, 164, 21, 224, 8, 203, 223, 212, 119, 21, + 224, 8, 203, 223, 242, 78, 21, 208, 151, 211, 72, 219, 212, 240, 76, 21, + 208, 151, 227, 144, 227, 98, 21, 208, 151, 208, 211, 248, 104, 227, 98, + 21, 208, 151, 208, 211, 208, 127, 231, 7, 224, 7, 21, 208, 151, 231, 7, + 224, 8, 216, 115, 21, 208, 151, 223, 254, 251, 79, 246, 165, 21, 208, + 151, 246, 218, 211, 72, 219, 211, 21, 208, 151, 246, 218, 231, 7, 224, 7, + 21, 209, 172, 21, 209, 173, 224, 3, 21, 209, 173, 220, 32, 208, 150, 21, + 209, 173, 220, 32, 208, 151, 224, 3, 21, 209, 173, 220, 32, 227, 98, 21, + 209, 173, 220, 32, 227, 99, 224, 3, 21, 209, 173, 248, 50, 227, 98, 21, + 223, 255, 230, 165, 21, 224, 1, 230, 165, 21, 222, 237, 21, 237, 145, 21, + 240, 213, 21, 212, 211, 236, 234, 211, 203, 21, 212, 211, 236, 234, 218, + 33, 21, 204, 98, 212, 211, 236, 234, 224, 6, 21, 239, 203, 212, 211, 236, + 234, 224, 6, 21, 212, 211, 208, 223, 239, 120, 204, 104, 21, 208, 134, + 211, 53, 211, 41, 21, 208, 134, 245, 86, 248, 120, 21, 208, 135, 207, + 137, 21, 206, 221, 248, 18, 208, 223, 239, 120, 236, 234, 230, 95, 21, + 227, 126, 245, 238, 21, 227, 126, 227, 195, 21, 227, 126, 227, 194, 21, + 227, 126, 227, 193, 21, 227, 126, 227, 192, 21, 227, 126, 227, 191, 21, + 227, 126, 227, 190, 21, 227, 126, 227, 189, 21, 240, 2, 21, 227, 45, 211, + 228, 21, 227, 46, 211, 228, 21, 227, 47, 237, 41, 21, 227, 47, 204, 23, + 21, 227, 47, 244, 24, 21, 227, 47, 237, 65, 222, 237, 21, 227, 47, 208, + 136, 21, 227, 47, 227, 125, 243, 198, 21, 245, 233, 21, 239, 102, 211, + 61, 21, 213, 143, 21, 245, 242, 21, 219, 76, 21, 240, 10, 224, 66, 21, + 240, 10, 224, 65, 21, 240, 10, 224, 64, 21, 240, 10, 224, 63, 21, 240, + 10, 224, 62, 21, 215, 197, 224, 66, 21, 215, 197, 224, 65, 21, 215, 197, + 224, 64, 21, 215, 197, 224, 63, 21, 215, 197, 224, 62, 21, 215, 197, 224, + 61, 21, 215, 197, 224, 60, 21, 215, 197, 224, 59, 21, 215, 197, 224, 73, + 21, 215, 197, 224, 72, 21, 215, 197, 224, 71, 21, 215, 197, 224, 70, 21, + 215, 197, 224, 69, 21, 215, 197, 224, 68, 21, 215, 197, 224, 67, 73, 72, + 4, 226, 184, 229, 100, 73, 72, 4, 226, 180, 173, 73, 72, 4, 226, 178, + 228, 209, 73, 72, 4, 226, 54, 229, 198, 73, 72, 4, 226, 24, 229, 201, 73, + 72, 4, 226, 43, 229, 6, 73, 72, 4, 226, 71, 229, 26, 73, 72, 4, 225, 196, + 228, 203, 73, 72, 4, 226, 175, 204, 30, 73, 72, 4, 226, 173, 204, 111, + 73, 72, 4, 226, 171, 203, 217, 73, 72, 4, 225, 249, 204, 55, 73, 72, 4, + 226, 1, 204, 62, 73, 72, 4, 226, 5, 203, 244, 73, 72, 4, 226, 74, 204, 0, + 73, 72, 4, 225, 181, 203, 213, 73, 72, 4, 225, 232, 204, 53, 73, 72, 4, + 226, 58, 203, 201, 73, 72, 4, 226, 70, 203, 203, 73, 72, 4, 225, 236, + 203, 202, 73, 72, 4, 226, 169, 224, 110, 73, 72, 4, 226, 167, 225, 122, + 73, 72, 4, 226, 165, 223, 219, 73, 72, 4, 226, 60, 224, 240, 73, 72, 4, + 226, 25, 224, 54, 73, 72, 4, 225, 221, 223, 243, 73, 72, 4, 225, 186, + 223, 237, 73, 72, 4, 226, 163, 248, 86, 73, 72, 4, 226, 160, 249, 32, 73, + 72, 4, 226, 158, 247, 193, 73, 72, 4, 225, 225, 248, 150, 73, 72, 4, 226, + 22, 248, 162, 73, 72, 4, 226, 16, 248, 10, 73, 72, 4, 225, 237, 248, 23, + 73, 72, 4, 226, 148, 75, 73, 72, 4, 226, 146, 63, 73, 72, 4, 226, 144, + 68, 73, 72, 4, 225, 212, 241, 161, 73, 72, 4, 226, 19, 74, 73, 72, 4, + 225, 210, 220, 18, 73, 72, 4, 225, 228, 78, 73, 72, 4, 225, 238, 241, + 145, 73, 72, 4, 225, 244, 231, 49, 73, 72, 4, 225, 240, 231, 49, 73, 72, + 4, 225, 180, 250, 231, 73, 72, 4, 225, 197, 241, 92, 73, 72, 4, 226, 133, + 212, 162, 73, 72, 4, 226, 131, 215, 36, 73, 72, 4, 226, 129, 211, 10, 73, + 72, 4, 225, 213, 214, 165, 73, 72, 4, 226, 3, 214, 177, 73, 72, 4, 225, + 239, 211, 250, 73, 72, 4, 226, 40, 212, 13, 73, 72, 4, 225, 179, 212, + 161, 73, 72, 4, 226, 119, 227, 148, 73, 72, 4, 226, 117, 228, 113, 73, + 72, 4, 226, 115, 226, 239, 73, 72, 4, 226, 35, 227, 226, 73, 72, 4, 226, + 46, 227, 234, 73, 72, 4, 226, 65, 227, 18, 73, 72, 4, 225, 222, 227, 49, + 73, 72, 4, 226, 9, 163, 227, 234, 73, 72, 4, 226, 141, 243, 233, 73, 72, + 4, 226, 138, 244, 212, 73, 72, 4, 226, 135, 242, 42, 73, 72, 4, 226, 30, + 244, 61, 73, 72, 4, 225, 195, 243, 90, 73, 72, 4, 225, 194, 243, 113, 73, + 72, 4, 226, 127, 209, 2, 73, 72, 4, 226, 124, 210, 22, 73, 72, 4, 226, + 122, 207, 203, 73, 72, 4, 226, 28, 209, 176, 73, 72, 4, 226, 64, 209, + 187, 73, 72, 4, 226, 15, 208, 148, 73, 72, 4, 226, 50, 135, 73, 72, 4, + 226, 113, 230, 141, 73, 72, 4, 226, 110, 230, 181, 73, 72, 4, 226, 108, + 230, 82, 73, 72, 4, 225, 218, 230, 159, 73, 72, 4, 226, 6, 230, 161, 73, + 72, 4, 225, 215, 230, 91, 73, 72, 4, 226, 56, 230, 101, 73, 72, 4, 225, + 200, 163, 230, 101, 73, 72, 4, 226, 106, 203, 11, 73, 72, 4, 226, 103, + 198, 73, 72, 4, 226, 101, 202, 213, 73, 72, 4, 226, 10, 203, 49, 73, 72, + 4, 226, 39, 203, 52, 73, 72, 4, 225, 234, 202, 232, 73, 72, 4, 225, 254, + 202, 247, 73, 72, 4, 226, 97, 240, 26, 73, 72, 4, 226, 95, 240, 108, 73, + 72, 4, 226, 93, 239, 108, 73, 72, 4, 226, 41, 240, 53, 73, 72, 4, 226, + 44, 240, 60, 73, 72, 4, 225, 242, 239, 175, 73, 72, 4, 226, 31, 239, 186, + 73, 72, 4, 225, 178, 239, 107, 73, 72, 4, 226, 18, 240, 81, 73, 72, 4, + 226, 91, 222, 68, 73, 72, 4, 226, 89, 223, 83, 73, 72, 4, 226, 87, 221, + 40, 73, 72, 4, 226, 2, 222, 230, 73, 72, 4, 225, 206, 221, 185, 73, 72, + 4, 225, 199, 237, 3, 73, 72, 4, 226, 82, 152, 73, 72, 4, 225, 189, 236, + 26, 73, 72, 4, 226, 85, 237, 48, 73, 72, 4, 226, 23, 237, 67, 73, 72, 4, + 226, 80, 236, 117, 73, 72, 4, 225, 235, 236, 136, 73, 72, 4, 226, 36, + 237, 47, 73, 72, 4, 225, 247, 236, 110, 73, 72, 4, 226, 66, 236, 238, 73, + 72, 4, 225, 245, 237, 126, 73, 72, 4, 226, 32, 236, 13, 73, 72, 4, 226, + 67, 237, 33, 73, 72, 4, 225, 182, 236, 120, 73, 72, 4, 226, 73, 236, 25, + 73, 72, 4, 226, 29, 222, 168, 73, 72, 4, 226, 78, 222, 182, 73, 72, 4, + 226, 37, 222, 165, 73, 72, 4, 226, 4, 222, 176, 73, 72, 4, 225, 229, 222, + 177, 73, 72, 4, 225, 219, 222, 166, 73, 72, 4, 225, 255, 222, 167, 73, + 72, 4, 225, 216, 222, 181, 73, 72, 4, 225, 248, 222, 164, 73, 72, 4, 226, + 33, 163, 222, 177, 73, 72, 4, 226, 13, 163, 222, 166, 73, 72, 4, 225, + 192, 163, 222, 167, 73, 72, 4, 225, 220, 238, 81, 73, 72, 4, 226, 8, 239, + 8, 73, 72, 4, 225, 207, 237, 230, 73, 72, 4, 225, 185, 238, 182, 73, 72, + 4, 225, 209, 237, 216, 73, 72, 4, 225, 208, 237, 226, 73, 72, 4, 225, + 191, 222, 187, 73, 72, 4, 226, 62, 222, 124, 73, 72, 4, 225, 198, 222, + 113, 73, 72, 4, 226, 51, 218, 167, 73, 72, 4, 226, 20, 185, 73, 72, 4, + 226, 69, 217, 191, 73, 72, 4, 226, 38, 219, 23, 73, 72, 4, 226, 68, 219, + 34, 73, 72, 4, 226, 17, 218, 45, 73, 72, 4, 226, 53, 218, 69, 73, 72, 4, + 225, 230, 225, 39, 73, 72, 4, 226, 57, 225, 54, 73, 72, 4, 225, 253, 225, + 33, 73, 72, 4, 226, 72, 225, 46, 73, 72, 4, 225, 187, 225, 46, 73, 72, 4, + 226, 47, 225, 47, 73, 72, 4, 225, 203, 225, 34, 73, 72, 4, 225, 201, 225, + 35, 73, 72, 4, 225, 188, 225, 27, 73, 72, 4, 225, 214, 163, 225, 47, 73, + 72, 4, 226, 14, 163, 225, 34, 73, 72, 4, 225, 233, 163, 225, 35, 73, 72, + 4, 225, 243, 228, 236, 73, 72, 4, 226, 27, 228, 244, 73, 72, 4, 226, 45, + 228, 232, 73, 72, 4, 226, 76, 228, 239, 73, 72, 4, 226, 11, 228, 240, 73, + 72, 4, 226, 7, 228, 234, 73, 72, 4, 225, 217, 228, 235, 73, 72, 4, 225, + 251, 238, 199, 73, 72, 4, 226, 63, 238, 207, 73, 72, 4, 225, 227, 238, + 194, 73, 72, 4, 226, 26, 238, 203, 73, 72, 4, 226, 12, 238, 204, 73, 72, + 4, 226, 48, 238, 195, 73, 72, 4, 226, 49, 238, 197, 73, 72, 4, 225, 204, + 216, 220, 73, 72, 4, 225, 252, 223, 10, 73, 72, 4, 225, 246, 223, 25, 73, + 72, 4, 225, 250, 222, 248, 73, 72, 4, 225, 184, 223, 16, 73, 72, 4, 226, + 0, 223, 17, 73, 72, 4, 226, 52, 222, 253, 73, 72, 4, 226, 55, 223, 1, 73, + 72, 4, 225, 223, 222, 48, 73, 72, 4, 225, 183, 222, 18, 73, 72, 4, 225, + 226, 222, 39, 73, 72, 4, 225, 241, 222, 22, 73, 72, 4, 225, 193, 205, + 230, 73, 72, 4, 225, 190, 206, 86, 73, 72, 4, 225, 224, 204, 163, 73, 72, + 4, 225, 202, 206, 50, 73, 72, 4, 226, 34, 206, 55, 73, 72, 4, 225, 231, + 205, 176, 73, 72, 4, 226, 42, 205, 189, 73, 72, 4, 225, 211, 220, 242, + 73, 72, 4, 226, 61, 221, 5, 73, 72, 4, 225, 205, 220, 224, 73, 72, 4, + 226, 21, 220, 253, 73, 72, 4, 226, 59, 220, 231, 73, 72, 17, 105, 73, 72, + 17, 108, 73, 72, 17, 147, 73, 72, 17, 149, 73, 72, 17, 170, 73, 72, 17, + 195, 73, 72, 17, 213, 111, 73, 72, 17, 199, 73, 72, 17, 222, 63, 73, 72, + 39, 42, 209, 174, 73, 72, 39, 42, 209, 147, 73, 72, 39, 42, 236, 10, 73, + 72, 39, 42, 209, 34, 73, 72, 39, 42, 209, 153, 209, 34, 73, 72, 39, 42, + 236, 12, 209, 34, 73, 72, 39, 42, 224, 113, 10, 13, 251, 30, 10, 13, 248, + 138, 10, 13, 230, 158, 10, 13, 244, 184, 10, 13, 204, 70, 10, 13, 202, + 107, 10, 13, 237, 148, 10, 13, 209, 251, 10, 13, 203, 47, 10, 13, 230, + 22, 10, 13, 228, 28, 10, 13, 225, 5, 10, 13, 221, 178, 10, 13, 214, 161, + 10, 13, 251, 59, 10, 13, 240, 47, 10, 13, 215, 28, 10, 13, 217, 119, 10, + 13, 216, 122, 10, 13, 213, 39, 10, 13, 209, 169, 10, 13, 209, 88, 10, 13, + 229, 140, 10, 13, 209, 100, 10, 13, 244, 207, 10, 13, 202, 110, 10, 13, + 238, 114, 10, 13, 243, 84, 248, 138, 10, 13, 243, 84, 221, 178, 10, 13, + 243, 84, 240, 47, 10, 13, 243, 84, 217, 119, 10, 13, 81, 248, 138, 10, + 13, 81, 230, 158, 10, 13, 81, 237, 43, 10, 13, 81, 237, 148, 10, 13, 81, + 203, 47, 10, 13, 81, 230, 22, 10, 13, 81, 228, 28, 10, 13, 81, 225, 5, + 10, 13, 81, 221, 178, 10, 13, 81, 214, 161, 10, 13, 81, 251, 59, 10, 13, + 81, 240, 47, 10, 13, 81, 215, 28, 10, 13, 81, 217, 119, 10, 13, 81, 213, + 39, 10, 13, 81, 209, 169, 10, 13, 81, 209, 88, 10, 13, 81, 229, 140, 10, + 13, 81, 244, 207, 10, 13, 81, 238, 114, 10, 13, 209, 247, 230, 158, 10, + 13, 209, 247, 237, 148, 10, 13, 209, 247, 203, 47, 10, 13, 209, 247, 228, + 28, 10, 13, 209, 247, 221, 178, 10, 13, 209, 247, 214, 161, 10, 13, 209, + 247, 251, 59, 10, 13, 209, 247, 215, 28, 10, 13, 209, 247, 217, 119, 10, + 13, 209, 247, 213, 39, 10, 13, 209, 247, 229, 140, 10, 13, 209, 247, 244, + 207, 10, 13, 209, 247, 238, 114, 10, 13, 209, 247, 243, 84, 221, 178, 10, + 13, 209, 247, 243, 84, 217, 119, 10, 13, 211, 40, 248, 138, 10, 13, 211, + 40, 230, 158, 10, 13, 211, 40, 237, 43, 10, 13, 211, 40, 237, 148, 10, + 13, 211, 40, 209, 251, 10, 13, 211, 40, 203, 47, 10, 13, 211, 40, 230, + 22, 10, 13, 211, 40, 225, 5, 10, 13, 211, 40, 221, 178, 10, 13, 211, 40, + 214, 161, 10, 13, 211, 40, 251, 59, 10, 13, 211, 40, 240, 47, 10, 13, + 211, 40, 215, 28, 10, 13, 211, 40, 217, 119, 10, 13, 211, 40, 213, 39, + 10, 13, 211, 40, 209, 169, 10, 13, 211, 40, 209, 88, 10, 13, 211, 40, + 229, 140, 10, 13, 211, 40, 244, 207, 10, 13, 211, 40, 202, 110, 10, 13, + 211, 40, 238, 114, 10, 13, 211, 40, 243, 84, 248, 138, 10, 13, 211, 40, + 243, 84, 240, 47, 10, 13, 227, 13, 251, 30, 10, 13, 227, 13, 248, 138, + 10, 13, 227, 13, 230, 158, 10, 13, 227, 13, 244, 184, 10, 13, 227, 13, + 237, 43, 10, 13, 227, 13, 204, 70, 10, 13, 227, 13, 202, 107, 10, 13, + 227, 13, 237, 148, 10, 13, 227, 13, 209, 251, 10, 13, 227, 13, 203, 47, + 10, 13, 227, 13, 228, 28, 10, 13, 227, 13, 225, 5, 10, 13, 227, 13, 221, + 178, 10, 13, 227, 13, 214, 161, 10, 13, 227, 13, 251, 59, 10, 13, 227, + 13, 240, 47, 10, 13, 227, 13, 215, 28, 10, 13, 227, 13, 217, 119, 10, 13, + 227, 13, 216, 122, 10, 13, 227, 13, 213, 39, 10, 13, 227, 13, 209, 169, + 10, 13, 227, 13, 209, 88, 10, 13, 227, 13, 229, 140, 10, 13, 227, 13, + 209, 100, 10, 13, 227, 13, 244, 207, 10, 13, 227, 13, 202, 110, 10, 13, + 227, 13, 238, 114, 10, 13, 169, 248, 138, 10, 13, 169, 230, 158, 10, 13, + 169, 244, 184, 10, 13, 169, 204, 70, 10, 13, 169, 202, 107, 10, 13, 169, + 237, 148, 10, 13, 169, 209, 251, 10, 13, 169, 203, 47, 10, 13, 169, 228, + 28, 10, 13, 169, 225, 5, 10, 13, 169, 221, 178, 10, 13, 169, 214, 161, + 10, 13, 169, 251, 59, 10, 13, 169, 240, 47, 10, 13, 169, 215, 28, 10, 13, + 169, 217, 119, 10, 13, 169, 216, 122, 10, 13, 169, 213, 39, 10, 13, 169, + 209, 169, 10, 13, 169, 209, 88, 10, 13, 169, 229, 140, 10, 13, 169, 209, + 100, 10, 13, 169, 244, 207, 10, 13, 169, 202, 110, 10, 13, 169, 238, 114, + 10, 13, 219, 255, 83, 3, 151, 3, 209, 209, 10, 13, 219, 255, 151, 3, 244, + 184, 225, 142, 99, 241, 176, 204, 16, 225, 142, 99, 211, 238, 204, 16, + 225, 142, 99, 204, 46, 204, 16, 225, 142, 99, 153, 204, 16, 225, 142, 99, + 216, 138, 242, 61, 225, 142, 99, 237, 244, 242, 61, 225, 142, 99, 61, + 242, 61, 225, 142, 99, 118, 76, 246, 181, 225, 142, 99, 120, 76, 246, + 181, 225, 142, 99, 126, 76, 246, 181, 225, 142, 99, 239, 147, 76, 246, + 181, 225, 142, 99, 239, 233, 76, 246, 181, 225, 142, 99, 212, 88, 76, + 246, 181, 225, 142, 99, 213, 112, 76, 246, 181, 225, 142, 99, 241, 143, + 76, 246, 181, 225, 142, 99, 222, 64, 76, 246, 181, 225, 142, 99, 118, 76, + 248, 243, 225, 142, 99, 120, 76, 248, 243, 225, 142, 99, 126, 76, 248, + 243, 225, 142, 99, 239, 147, 76, 248, 243, 225, 142, 99, 239, 233, 76, + 248, 243, 225, 142, 99, 212, 88, 76, 248, 243, 225, 142, 99, 213, 112, + 76, 248, 243, 225, 142, 99, 241, 143, 76, 248, 243, 225, 142, 99, 222, + 64, 76, 248, 243, 225, 142, 99, 118, 76, 246, 58, 225, 142, 99, 120, 76, + 246, 58, 225, 142, 99, 126, 76, 246, 58, 225, 142, 99, 239, 147, 76, 246, + 58, 225, 142, 99, 239, 233, 76, 246, 58, 225, 142, 99, 212, 88, 76, 246, + 58, 225, 142, 99, 213, 112, 76, 246, 58, 225, 142, 99, 241, 143, 76, 246, + 58, 225, 142, 99, 222, 64, 76, 246, 58, 225, 142, 99, 218, 79, 225, 142, + 99, 219, 242, 225, 142, 99, 248, 244, 225, 142, 99, 246, 99, 225, 142, + 99, 211, 183, 225, 142, 99, 210, 216, 225, 142, 99, 250, 21, 225, 142, + 99, 204, 7, 225, 142, 99, 230, 94, 225, 142, 99, 249, 25, 161, 99, 236, + 106, 249, 25, 161, 99, 236, 104, 161, 99, 236, 103, 161, 99, 236, 102, + 161, 99, 236, 101, 161, 99, 236, 100, 161, 99, 236, 99, 161, 99, 236, 98, + 161, 99, 236, 97, 161, 99, 236, 96, 161, 99, 236, 95, 161, 99, 236, 94, + 161, 99, 236, 93, 161, 99, 236, 92, 161, 99, 236, 91, 161, 99, 236, 90, + 161, 99, 236, 89, 161, 99, 236, 88, 161, 99, 236, 87, 161, 99, 236, 86, + 161, 99, 236, 85, 161, 99, 236, 84, 161, 99, 236, 83, 161, 99, 236, 82, + 161, 99, 236, 81, 161, 99, 236, 80, 161, 99, 236, 79, 161, 99, 236, 78, + 161, 99, 236, 77, 161, 99, 236, 76, 161, 99, 236, 75, 161, 99, 236, 74, + 161, 99, 236, 73, 161, 99, 236, 72, 161, 99, 236, 71, 161, 99, 236, 70, + 161, 99, 236, 69, 161, 99, 236, 68, 161, 99, 236, 67, 161, 99, 236, 66, + 161, 99, 236, 65, 161, 99, 236, 64, 161, 99, 236, 63, 161, 99, 236, 62, + 161, 99, 236, 61, 161, 99, 236, 60, 161, 99, 236, 59, 161, 99, 236, 58, + 161, 99, 236, 57, 161, 99, 236, 56, 161, 99, 80, 249, 25, 161, 99, 206, + 37, 161, 99, 206, 36, 161, 99, 206, 35, 161, 99, 206, 34, 161, 99, 206, + 33, 161, 99, 206, 32, 161, 99, 206, 31, 161, 99, 206, 30, 161, 99, 206, + 29, 161, 99, 206, 28, 161, 99, 206, 27, 161, 99, 206, 26, 161, 99, 206, + 25, 161, 99, 206, 24, 161, 99, 206, 23, 161, 99, 206, 22, 161, 99, 206, + 21, 161, 99, 206, 20, 161, 99, 206, 19, 161, 99, 206, 18, 161, 99, 206, + 17, 161, 99, 206, 16, 161, 99, 206, 15, 161, 99, 206, 14, 161, 99, 206, + 13, 161, 99, 206, 12, 161, 99, 206, 11, 161, 99, 206, 10, 161, 99, 206, + 9, 161, 99, 206, 8, 161, 99, 206, 7, 161, 99, 206, 6, 161, 99, 206, 5, + 161, 99, 206, 4, 161, 99, 206, 3, 161, 99, 206, 2, 161, 99, 206, 1, 161, + 99, 206, 0, 161, 99, 205, 255, 161, 99, 205, 254, 161, 99, 205, 253, 161, + 99, 205, 252, 161, 99, 205, 251, 161, 99, 205, 250, 161, 99, 205, 249, + 161, 99, 205, 248, 161, 99, 205, 247, 161, 99, 205, 246, 161, 99, 205, + 245, 218, 88, 247, 38, 249, 25, 218, 88, 247, 38, 251, 132, 76, 211, 225, + 218, 88, 247, 38, 120, 76, 211, 225, 218, 88, 247, 38, 126, 76, 211, 225, + 218, 88, 247, 38, 239, 147, 76, 211, 225, 218, 88, 247, 38, 239, 233, 76, + 211, 225, 218, 88, 247, 38, 212, 88, 76, 211, 225, 218, 88, 247, 38, 213, + 112, 76, 211, 225, 218, 88, 247, 38, 241, 143, 76, 211, 225, 218, 88, + 247, 38, 222, 64, 76, 211, 225, 218, 88, 247, 38, 209, 153, 76, 211, 225, + 218, 88, 247, 38, 230, 179, 76, 211, 225, 218, 88, 247, 38, 229, 32, 76, + 211, 225, 218, 88, 247, 38, 217, 49, 76, 211, 225, 218, 88, 247, 38, 229, + 82, 76, 211, 225, 218, 88, 247, 38, 251, 132, 76, 237, 53, 218, 88, 247, + 38, 120, 76, 237, 53, 218, 88, 247, 38, 126, 76, 237, 53, 218, 88, 247, + 38, 239, 147, 76, 237, 53, 218, 88, 247, 38, 239, 233, 76, 237, 53, 218, + 88, 247, 38, 212, 88, 76, 237, 53, 218, 88, 247, 38, 213, 112, 76, 237, + 53, 218, 88, 247, 38, 241, 143, 76, 237, 53, 218, 88, 247, 38, 222, 64, + 76, 237, 53, 218, 88, 247, 38, 209, 153, 76, 237, 53, 218, 88, 247, 38, + 230, 179, 76, 237, 53, 218, 88, 247, 38, 229, 32, 76, 237, 53, 218, 88, + 247, 38, 217, 49, 76, 237, 53, 218, 88, 247, 38, 229, 82, 76, 237, 53, + 218, 88, 247, 38, 216, 138, 230, 94, 218, 88, 247, 38, 251, 132, 76, 243, + 220, 218, 88, 247, 38, 120, 76, 243, 220, 218, 88, 247, 38, 126, 76, 243, + 220, 218, 88, 247, 38, 239, 147, 76, 243, 220, 218, 88, 247, 38, 239, + 233, 76, 243, 220, 218, 88, 247, 38, 212, 88, 76, 243, 220, 218, 88, 247, + 38, 213, 112, 76, 243, 220, 218, 88, 247, 38, 241, 143, 76, 243, 220, + 218, 88, 247, 38, 222, 64, 76, 243, 220, 218, 88, 247, 38, 209, 153, 76, + 243, 220, 218, 88, 247, 38, 230, 179, 76, 243, 220, 218, 88, 247, 38, + 229, 32, 76, 243, 220, 218, 88, 247, 38, 217, 49, 76, 243, 220, 218, 88, + 247, 38, 229, 82, 76, 243, 220, 218, 88, 247, 38, 62, 230, 94, 218, 88, + 247, 38, 251, 132, 76, 246, 2, 218, 88, 247, 38, 120, 76, 246, 2, 218, + 88, 247, 38, 126, 76, 246, 2, 218, 88, 247, 38, 239, 147, 76, 246, 2, + 218, 88, 247, 38, 239, 233, 76, 246, 2, 218, 88, 247, 38, 212, 88, 76, + 246, 2, 218, 88, 247, 38, 213, 112, 76, 246, 2, 218, 88, 247, 38, 241, + 143, 76, 246, 2, 218, 88, 247, 38, 222, 64, 76, 246, 2, 218, 88, 247, 38, + 209, 153, 76, 246, 2, 218, 88, 247, 38, 230, 179, 76, 246, 2, 218, 88, + 247, 38, 229, 32, 76, 246, 2, 218, 88, 247, 38, 217, 49, 76, 246, 2, 218, + 88, 247, 38, 229, 82, 76, 246, 2, 218, 88, 247, 38, 61, 230, 94, 218, 88, + 247, 38, 239, 173, 218, 88, 247, 38, 208, 48, 218, 88, 247, 38, 208, 37, + 218, 88, 247, 38, 208, 34, 218, 88, 247, 38, 208, 33, 218, 88, 247, 38, + 208, 32, 218, 88, 247, 38, 208, 31, 218, 88, 247, 38, 208, 30, 218, 88, + 247, 38, 208, 29, 218, 88, 247, 38, 208, 28, 218, 88, 247, 38, 208, 47, + 218, 88, 247, 38, 208, 46, 218, 88, 247, 38, 208, 45, 218, 88, 247, 38, + 208, 44, 218, 88, 247, 38, 208, 43, 218, 88, 247, 38, 208, 42, 218, 88, + 247, 38, 208, 41, 218, 88, 247, 38, 208, 40, 218, 88, 247, 38, 208, 39, + 218, 88, 247, 38, 208, 38, 218, 88, 247, 38, 208, 36, 218, 88, 247, 38, + 208, 35, 17, 202, 85, 239, 102, 211, 61, 17, 202, 85, 245, 233, 17, 118, + 245, 233, 17, 120, 245, 233, 17, 126, 245, 233, 17, 239, 147, 245, 233, + 17, 239, 233, 245, 233, 17, 212, 88, 245, 233, 17, 213, 112, 245, 233, + 17, 241, 143, 245, 233, 17, 222, 64, 245, 233, 243, 174, 43, 41, 17, 202, + 84, 243, 174, 182, 43, 41, 17, 202, 84, 102, 8, 6, 1, 63, 102, 8, 6, 1, + 249, 255, 102, 8, 6, 1, 247, 125, 102, 8, 6, 1, 245, 51, 102, 8, 6, 1, + 74, 102, 8, 6, 1, 240, 174, 102, 8, 6, 1, 239, 75, 102, 8, 6, 1, 237, + 171, 102, 8, 6, 1, 75, 102, 8, 6, 1, 230, 184, 102, 8, 6, 1, 230, 54, + 102, 8, 6, 1, 159, 102, 8, 6, 1, 226, 185, 102, 8, 6, 1, 223, 163, 102, + 8, 6, 1, 78, 102, 8, 6, 1, 219, 184, 102, 8, 6, 1, 217, 134, 102, 8, 6, + 1, 146, 102, 8, 6, 1, 194, 102, 8, 6, 1, 210, 69, 102, 8, 6, 1, 68, 102, + 8, 6, 1, 206, 164, 102, 8, 6, 1, 204, 144, 102, 8, 6, 1, 203, 196, 102, + 8, 6, 1, 203, 124, 102, 8, 6, 1, 202, 159, 208, 133, 213, 33, 247, 226, + 8, 6, 1, 194, 43, 37, 8, 6, 1, 247, 125, 43, 37, 8, 6, 1, 146, 43, 246, + 239, 43, 203, 198, 103, 8, 6, 1, 63, 103, 8, 6, 1, 249, 255, 103, 8, 6, + 1, 247, 125, 103, 8, 6, 1, 245, 51, 103, 8, 6, 1, 74, 103, 8, 6, 1, 240, + 174, 103, 8, 6, 1, 239, 75, 103, 8, 6, 1, 237, 171, 103, 8, 6, 1, 75, + 103, 8, 6, 1, 230, 184, 103, 8, 6, 1, 230, 54, 103, 8, 6, 1, 159, 103, 8, + 6, 1, 226, 185, 103, 8, 6, 1, 223, 163, 103, 8, 6, 1, 78, 103, 8, 6, 1, + 219, 184, 103, 8, 6, 1, 217, 134, 103, 8, 6, 1, 146, 103, 8, 6, 1, 194, + 103, 8, 6, 1, 210, 69, 103, 8, 6, 1, 68, 103, 8, 6, 1, 206, 164, 103, 8, + 6, 1, 204, 144, 103, 8, 6, 1, 203, 196, 103, 8, 6, 1, 203, 124, 103, 8, + 6, 1, 202, 159, 103, 235, 255, 103, 223, 187, 103, 214, 179, 103, 211, + 167, 103, 218, 10, 103, 204, 63, 182, 43, 8, 6, 1, 63, 182, 43, 8, 6, 1, + 249, 255, 182, 43, 8, 6, 1, 247, 125, 182, 43, 8, 6, 1, 245, 51, 182, 43, + 8, 6, 1, 74, 182, 43, 8, 6, 1, 240, 174, 182, 43, 8, 6, 1, 239, 75, 182, + 43, 8, 6, 1, 237, 171, 182, 43, 8, 6, 1, 75, 182, 43, 8, 6, 1, 230, 184, + 182, 43, 8, 6, 1, 230, 54, 182, 43, 8, 6, 1, 159, 182, 43, 8, 6, 1, 226, + 185, 182, 43, 8, 6, 1, 223, 163, 182, 43, 8, 6, 1, 78, 182, 43, 8, 6, 1, + 219, 184, 182, 43, 8, 6, 1, 217, 134, 182, 43, 8, 6, 1, 146, 182, 43, 8, + 6, 1, 194, 182, 43, 8, 6, 1, 210, 69, 182, 43, 8, 6, 1, 68, 182, 43, 8, + 6, 1, 206, 164, 182, 43, 8, 6, 1, 204, 144, 182, 43, 8, 6, 1, 203, 196, + 182, 43, 8, 6, 1, 203, 124, 182, 43, 8, 6, 1, 202, 159, 216, 188, 225, + 26, 54, 216, 188, 225, 23, 54, 182, 103, 8, 6, 1, 63, 182, 103, 8, 6, 1, + 249, 255, 182, 103, 8, 6, 1, 247, 125, 182, 103, 8, 6, 1, 245, 51, 182, + 103, 8, 6, 1, 74, 182, 103, 8, 6, 1, 240, 174, 182, 103, 8, 6, 1, 239, + 75, 182, 103, 8, 6, 1, 237, 171, 182, 103, 8, 6, 1, 75, 182, 103, 8, 6, + 1, 230, 184, 182, 103, 8, 6, 1, 230, 54, 182, 103, 8, 6, 1, 159, 182, + 103, 8, 6, 1, 226, 185, 182, 103, 8, 6, 1, 223, 163, 182, 103, 8, 6, 1, + 78, 182, 103, 8, 6, 1, 219, 184, 182, 103, 8, 6, 1, 217, 134, 182, 103, + 8, 6, 1, 146, 182, 103, 8, 6, 1, 194, 182, 103, 8, 6, 1, 210, 69, 182, + 103, 8, 6, 1, 68, 182, 103, 8, 6, 1, 206, 164, 182, 103, 8, 6, 1, 204, + 144, 182, 103, 8, 6, 1, 203, 196, 182, 103, 8, 6, 1, 203, 124, 182, 103, + 8, 6, 1, 202, 159, 245, 128, 182, 103, 8, 6, 1, 219, 184, 182, 103, 235, + 164, 182, 103, 185, 182, 103, 215, 36, 182, 103, 251, 232, 182, 103, 204, + 63, 51, 243, 132, 103, 246, 42, 103, 245, 176, 103, 239, 129, 103, 235, + 155, 103, 222, 213, 103, 222, 205, 103, 220, 51, 103, 211, 245, 103, 112, + 3, 240, 212, 82, 103, 205, 166, 216, 130, 231, 32, 16, 1, 63, 216, 130, + 231, 32, 16, 1, 249, 255, 216, 130, 231, 32, 16, 1, 247, 125, 216, 130, + 231, 32, 16, 1, 245, 51, 216, 130, 231, 32, 16, 1, 74, 216, 130, 231, 32, + 16, 1, 240, 174, 216, 130, 231, 32, 16, 1, 239, 75, 216, 130, 231, 32, + 16, 1, 237, 171, 216, 130, 231, 32, 16, 1, 75, 216, 130, 231, 32, 16, 1, + 230, 184, 216, 130, 231, 32, 16, 1, 230, 54, 216, 130, 231, 32, 16, 1, + 159, 216, 130, 231, 32, 16, 1, 226, 185, 216, 130, 231, 32, 16, 1, 223, + 163, 216, 130, 231, 32, 16, 1, 78, 216, 130, 231, 32, 16, 1, 219, 184, + 216, 130, 231, 32, 16, 1, 217, 134, 216, 130, 231, 32, 16, 1, 146, 216, + 130, 231, 32, 16, 1, 194, 216, 130, 231, 32, 16, 1, 210, 69, 216, 130, + 231, 32, 16, 1, 68, 216, 130, 231, 32, 16, 1, 206, 164, 216, 130, 231, + 32, 16, 1, 204, 144, 216, 130, 231, 32, 16, 1, 203, 196, 216, 130, 231, + 32, 16, 1, 203, 124, 216, 130, 231, 32, 16, 1, 202, 159, 51, 172, 236, + 130, 103, 67, 229, 14, 103, 67, 215, 36, 103, 12, 206, 239, 233, 100, + 103, 12, 206, 239, 233, 104, 103, 12, 206, 239, 233, 112, 103, 67, 244, + 75, 103, 12, 206, 239, 233, 119, 103, 12, 206, 239, 233, 106, 103, 12, + 206, 239, 233, 78, 103, 12, 206, 239, 233, 105, 103, 12, 206, 239, 233, + 118, 103, 12, 206, 239, 233, 92, 103, 12, 206, 239, 233, 85, 103, 12, + 206, 239, 233, 94, 103, 12, 206, 239, 233, 115, 103, 12, 206, 239, 233, + 101, 103, 12, 206, 239, 233, 117, 103, 12, 206, 239, 233, 93, 103, 12, + 206, 239, 233, 116, 103, 12, 206, 239, 233, 79, 103, 12, 206, 239, 233, + 84, 103, 12, 206, 239, 233, 77, 103, 12, 206, 239, 233, 107, 103, 12, + 206, 239, 233, 109, 103, 12, 206, 239, 233, 87, 103, 12, 206, 239, 233, + 98, 103, 12, 206, 239, 233, 96, 103, 12, 206, 239, 233, 122, 103, 12, + 206, 239, 233, 121, 103, 12, 206, 239, 233, 75, 103, 12, 206, 239, 233, + 102, 103, 12, 206, 239, 233, 120, 103, 12, 206, 239, 233, 111, 103, 12, + 206, 239, 233, 97, 103, 12, 206, 239, 233, 76, 103, 12, 206, 239, 233, + 99, 103, 12, 206, 239, 233, 81, 103, 12, 206, 239, 233, 80, 103, 12, 206, + 239, 233, 110, 103, 12, 206, 239, 233, 88, 103, 12, 206, 239, 233, 90, + 103, 12, 206, 239, 233, 91, 103, 12, 206, 239, 233, 83, 103, 12, 206, + 239, 233, 114, 103, 12, 206, 239, 233, 108, 208, 133, 213, 33, 247, 226, + 12, 206, 239, 233, 89, 208, 133, 213, 33, 247, 226, 12, 206, 239, 233, + 121, 208, 133, 213, 33, 247, 226, 12, 206, 239, 233, 119, 208, 133, 213, + 33, 247, 226, 12, 206, 239, 233, 103, 208, 133, 213, 33, 247, 226, 12, + 206, 239, 233, 86, 208, 133, 213, 33, 247, 226, 12, 206, 239, 233, 99, + 208, 133, 213, 33, 247, 226, 12, 206, 239, 233, 82, 208, 133, 213, 33, + 247, 226, 12, 206, 239, 233, 113, 208, 133, 213, 33, 247, 226, 12, 206, + 239, 233, 95, 43, 189, 251, 111, 43, 189, 251, 136, 245, 62, 239, 184, + 246, 16, 207, 3, 222, 80, 3, 211, 91, 210, 209, 115, 224, 11, 210, 208, + 246, 46, 250, 50, 242, 17, 210, 207, 115, 247, 182, 216, 189, 247, 208, + 250, 50, 222, 79, 204, 81, 204, 75, 205, 181, 224, 118, 204, 65, 241, + 180, 238, 46, 240, 228, 241, 180, 238, 46, 250, 238, 241, 180, 238, 46, + 250, 68, 238, 46, 3, 224, 231, 222, 214, 224, 30, 97, 204, 67, 245, 139, + 224, 30, 97, 239, 245, 217, 56, 224, 30, 97, 204, 67, 238, 77, 224, 30, + 97, 239, 102, 224, 30, 97, 204, 94, 238, 77, 224, 30, 97, 228, 1, 217, + 56, 224, 30, 97, 204, 94, 245, 139, 224, 30, 97, 245, 139, 224, 29, 222, + 214, 224, 30, 3, 240, 102, 239, 245, 217, 56, 224, 30, 3, 240, 102, 228, + 1, 217, 56, 224, 30, 3, 240, 102, 239, 102, 224, 30, 3, 240, 102, 210, + 215, 3, 240, 102, 238, 44, 211, 94, 212, 233, 211, 94, 209, 80, 62, 242, + 49, 61, 210, 214, 61, 210, 215, 3, 5, 246, 7, 61, 210, 215, 248, 135, + 246, 7, 61, 210, 215, 248, 135, 246, 8, 3, 216, 190, 246, 8, 3, 216, 190, + 246, 8, 3, 212, 19, 246, 8, 3, 227, 131, 246, 8, 3, 208, 137, 239, 185, + 204, 17, 248, 27, 240, 102, 236, 47, 243, 102, 210, 2, 247, 158, 246, + 148, 214, 163, 240, 222, 208, 95, 244, 69, 208, 95, 219, 135, 208, 95, + 247, 85, 236, 47, 218, 248, 207, 193, 246, 152, 248, 30, 215, 202, 237, + 2, 210, 212, 248, 30, 241, 184, 76, 225, 131, 241, 184, 76, 216, 52, 237, + 28, 239, 147, 227, 230, 246, 6, 225, 104, 227, 229, 240, 85, 227, 229, + 227, 230, 239, 192, 231, 50, 204, 16, 223, 196, 208, 165, 250, 33, 238, + 5, 224, 249, 204, 79, 209, 225, 227, 199, 248, 239, 218, 120, 216, 138, + 250, 157, 237, 244, 250, 157, 219, 29, 219, 31, 246, 153, 211, 45, 237, + 132, 212, 51, 76, 218, 100, 225, 16, 220, 32, 248, 11, 218, 21, 227, 210, + 216, 53, 245, 145, 216, 53, 248, 251, 245, 179, 216, 52, 245, 89, 25, + 216, 52, 211, 79, 247, 237, 211, 224, 247, 219, 239, 128, 239, 124, 215, + 223, 210, 165, 218, 23, 244, 163, 220, 75, 210, 183, 239, 125, 212, 204, + 239, 244, 247, 79, 3, 210, 158, 244, 13, 212, 7, 235, 163, 245, 143, 213, + 51, 235, 162, 235, 163, 245, 143, 242, 73, 245, 178, 246, 114, 142, 247, + 51, 227, 32, 245, 81, 236, 119, 218, 25, 212, 217, 248, 116, 247, 233, + 218, 26, 76, 239, 174, 245, 177, 239, 163, 25, 229, 33, 209, 184, 204, 3, + 237, 102, 215, 13, 247, 250, 25, 245, 99, 204, 13, 238, 49, 245, 251, + 238, 49, 208, 51, 242, 54, 248, 146, 223, 235, 246, 23, 248, 146, 223, + 234, 249, 28, 247, 249, 239, 163, 25, 229, 34, 3, 218, 89, 247, 250, 3, + 218, 38, 245, 167, 218, 40, 216, 54, 203, 227, 217, 242, 248, 58, 247, + 78, 230, 178, 246, 106, 208, 95, 240, 68, 246, 105, 239, 247, 239, 248, + 211, 222, 248, 250, 219, 66, 218, 39, 245, 215, 248, 251, 209, 229, 208, + 95, 245, 128, 239, 219, 218, 121, 244, 66, 230, 169, 243, 96, 247, 27, + 211, 44, 204, 17, 246, 130, 224, 30, 205, 217, 246, 204, 214, 196, 214, + 223, 238, 11, 247, 48, 237, 56, 3, 208, 211, 220, 32, 209, 93, 227, 222, + 247, 243, 76, 239, 196, 224, 119, 225, 13, 216, 110, 216, 54, 31, 229, + 150, 3, 230, 177, 211, 15, 224, 152, 227, 167, 212, 49, 245, 184, 229, + 30, 248, 158, 250, 78, 31, 221, 155, 248, 158, 244, 19, 31, 221, 155, + 240, 6, 239, 133, 251, 114, 208, 252, 247, 28, 236, 49, 240, 35, 204, 36, + 215, 213, 245, 252, 239, 239, 218, 54, 25, 239, 243, 224, 152, 223, 253, + 247, 65, 246, 65, 237, 60, 250, 85, 219, 138, 208, 145, 237, 83, 246, 51, + 209, 144, 208, 253, 246, 37, 248, 20, 218, 241, 250, 84, 205, 226, 238, + 238, 243, 167, 236, 230, 212, 42, 225, 172, 248, 69, 238, 239, 243, 213, + 247, 236, 239, 198, 218, 88, 247, 36, 31, 221, 160, 223, 226, 31, 221, + 155, 214, 209, 237, 214, 31, 229, 149, 208, 27, 205, 206, 31, 214, 189, + 215, 126, 212, 246, 3, 214, 226, 209, 149, 216, 209, 25, 248, 251, 212, + 67, 25, 212, 67, 248, 4, 248, 213, 25, 236, 112, 246, 154, 239, 225, 212, + 18, 215, 127, 210, 188, 211, 189, 225, 13, 208, 52, 236, 50, 216, 210, + 250, 239, 239, 171, 215, 139, 239, 171, 210, 160, 204, 51, 227, 136, 238, + 30, 216, 211, 224, 18, 216, 211, 247, 39, 245, 136, 248, 210, 25, 248, + 251, 205, 180, 240, 25, 236, 133, 211, 73, 25, 248, 251, 235, 163, 236, + 133, 211, 73, 25, 217, 184, 210, 9, 209, 149, 219, 156, 25, 248, 251, + 212, 20, 247, 44, 224, 12, 247, 63, 248, 161, 3, 207, 3, 247, 184, 245, + 198, 236, 39, 247, 182, 246, 45, 244, 23, 236, 39, 247, 183, 246, 35, + 247, 183, 244, 15, 244, 16, 230, 208, 223, 67, 219, 72, 211, 104, 236, + 39, 247, 183, 236, 39, 3, 238, 222, 220, 67, 247, 183, 230, 169, 218, 31, + 220, 66, 240, 227, 218, 31, 220, 66, 236, 48, 248, 235, 250, 23, 209, + 157, 225, 172, 236, 44, 227, 1, 236, 44, 245, 182, 211, 57, 214, 195, + 244, 26, 211, 57, 240, 91, 230, 189, 228, 13, 230, 169, 247, 19, 240, + 227, 247, 19, 61, 219, 3, 62, 219, 3, 204, 73, 61, 239, 225, 204, 73, 62, + 239, 225, 215, 201, 62, 215, 201, 228, 105, 249, 12, 216, 209, 25, 212, + 183, 247, 241, 25, 47, 250, 234, 241, 98, 65, 239, 234, 207, 119, 241, + 98, 65, 239, 234, 207, 116, 241, 98, 65, 239, 234, 207, 114, 241, 98, 65, + 239, 234, 207, 112, 241, 98, 65, 239, 234, 207, 110, 216, 172, 224, 9, + 219, 193, 204, 81, 247, 188, 245, 149, 208, 245, 227, 183, 216, 212, 247, + 17, 242, 61, 245, 135, 204, 39, 212, 26, 212, 24, 236, 49, 216, 184, 238, + 35, 213, 37, 224, 48, 215, 205, 246, 140, 243, 102, 218, 131, 248, 21, + 241, 114, 220, 78, 211, 202, 213, 32, 247, 187, 250, 198, 236, 118, 228, + 98, 248, 144, 239, 243, 208, 51, 239, 243, 248, 28, 207, 171, 237, 81, + 246, 141, 249, 28, 246, 141, 239, 118, 249, 28, 246, 141, 248, 60, 219, + 5, 229, 24, 218, 44, 242, 51, 247, 67, 249, 17, 247, 67, 243, 95, 224, + 10, 240, 102, 245, 150, 240, 102, 208, 246, 240, 102, 216, 213, 240, 102, + 247, 18, 240, 102, 242, 62, 240, 102, 211, 187, 204, 39, 236, 50, 240, + 102, 224, 49, 240, 102, 243, 103, 240, 102, 218, 132, 240, 102, 239, 122, + 240, 102, 237, 129, 240, 102, 203, 253, 240, 102, 248, 156, 240, 102, + 219, 120, 240, 102, 218, 132, 221, 167, 219, 46, 217, 230, 246, 125, 240, + 184, 240, 191, 241, 183, 221, 167, 224, 7, 208, 150, 61, 112, 218, 59, + 249, 23, 231, 35, 61, 121, 218, 59, 249, 23, 231, 35, 61, 49, 218, 59, + 249, 23, 231, 35, 61, 50, 218, 59, 249, 23, 231, 35, 239, 237, 237, 124, + 54, 204, 73, 237, 124, 54, 220, 52, 237, 124, 54, 209, 20, 112, 54, 209, + 20, 121, 54, 246, 36, 237, 100, 54, 171, 237, 100, 54, 245, 122, 203, + 249, 237, 83, 240, 187, 222, 236, 210, 68, 230, 160, 242, 56, 229, 85, + 248, 71, 203, 249, 246, 9, 217, 165, 237, 103, 218, 22, 225, 112, 212, + 239, 250, 46, 212, 239, 236, 243, 212, 239, 203, 249, 214, 240, 203, 249, + 248, 3, 239, 169, 247, 150, 231, 50, 212, 136, 247, 149, 231, 50, 212, + 136, 247, 232, 238, 60, 225, 122, 203, 250, 240, 82, 225, 123, 25, 203, + 251, 236, 127, 237, 99, 120, 224, 241, 236, 127, 237, 99, 120, 203, 248, + 236, 127, 237, 99, 218, 51, 220, 65, 203, 251, 3, 247, 168, 241, 181, + 247, 209, 3, 206, 46, 218, 230, 3, 248, 32, 237, 145, 225, 123, 3, 237, + 227, 218, 168, 225, 108, 225, 123, 3, 207, 180, 220, 44, 225, 122, 220, + 44, 203, 250, 249, 27, 245, 199, 203, 234, 217, 235, 230, 169, 220, 61, + 230, 169, 238, 34, 238, 89, 249, 28, 250, 221, 240, 196, 251, 20, 251, + 21, 224, 39, 231, 55, 212, 62, 231, 25, 244, 12, 218, 229, 237, 221, 244, + 167, 227, 97, 223, 91, 218, 50, 240, 103, 225, 74, 237, 144, 248, 229, + 218, 53, 210, 88, 218, 124, 229, 67, 82, 227, 1, 227, 174, 215, 252, 238, + 180, 211, 63, 229, 66, 247, 242, 245, 152, 3, 237, 55, 204, 58, 248, 154, + 237, 55, 247, 203, 237, 55, 120, 237, 53, 211, 220, 237, 55, 237, 237, + 237, 55, 237, 56, 3, 47, 248, 26, 237, 55, 237, 244, 237, 55, 203, 45, + 237, 55, 217, 166, 237, 55, 237, 56, 3, 216, 54, 216, 67, 237, 53, 237, + 56, 244, 66, 243, 222, 213, 63, 3, 34, 70, 231, 6, 241, 117, 157, 247, + 180, 250, 220, 97, 248, 12, 212, 54, 97, 245, 244, 97, 211, 196, 210, + 167, 97, 242, 49, 244, 145, 97, 218, 125, 76, 218, 45, 239, 210, 248, 83, + 243, 133, 97, 211, 212, 248, 250, 209, 38, 248, 250, 61, 239, 197, 236, + 12, 218, 57, 97, 224, 53, 249, 10, 245, 92, 240, 214, 79, 243, 97, 54, + 245, 141, 247, 37, 248, 234, 3, 203, 43, 54, 248, 234, 3, 243, 97, 54, + 248, 234, 3, 240, 230, 54, 248, 234, 3, 218, 20, 54, 224, 53, 3, 204, 11, + 246, 178, 3, 177, 208, 91, 25, 203, 43, 54, 214, 174, 218, 228, 245, 220, + 247, 207, 224, 108, 239, 202, 243, 154, 219, 248, 243, 159, 242, 12, 240, + 11, 239, 182, 171, 240, 11, 239, 182, 219, 154, 3, 245, 95, 219, 154, + 240, 95, 206, 224, 247, 72, 209, 183, 247, 72, 247, 38, 231, 35, 246, + 178, 3, 177, 208, 90, 246, 178, 3, 183, 208, 90, 248, 231, 246, 177, 246, + 22, 217, 161, 215, 191, 217, 161, 219, 94, 211, 53, 215, 133, 208, 82, + 215, 133, 248, 8, 210, 7, 227, 227, 221, 158, 221, 159, 3, 244, 65, 245, + 151, 246, 16, 248, 9, 171, 248, 9, 237, 244, 248, 9, 248, 26, 248, 9, + 219, 243, 248, 9, 248, 6, 223, 85, 249, 14, 214, 182, 224, 242, 209, 162, + 216, 152, 219, 152, 240, 65, 225, 172, 214, 222, 250, 195, 217, 185, 251, + 119, 227, 3, 246, 162, 224, 254, 219, 210, 208, 98, 231, 46, 208, 98, + 219, 161, 241, 236, 97, 231, 43, 241, 57, 241, 58, 3, 183, 53, 55, 246, + 16, 225, 137, 3, 226, 249, 239, 225, 246, 16, 225, 137, 3, 216, 188, 239, + 225, 171, 225, 137, 3, 216, 188, 239, 225, 171, 225, 137, 3, 226, 249, + 239, 225, 218, 28, 218, 29, 236, 53, 222, 210, 224, 80, 218, 176, 224, + 80, 218, 177, 3, 86, 53, 250, 50, 227, 222, 205, 229, 224, 79, 224, 80, + 218, 177, 220, 68, 221, 192, 224, 80, 218, 175, 250, 196, 3, 248, 220, + 247, 65, 247, 66, 3, 239, 218, 205, 226, 247, 65, 209, 159, 216, 204, + 205, 225, 240, 6, 217, 217, 218, 35, 211, 74, 217, 254, 248, 160, 207, + 138, 86, 250, 91, 246, 18, 86, 25, 96, 171, 246, 62, 250, 91, 246, 18, + 86, 25, 96, 171, 246, 62, 250, 92, 3, 43, 118, 219, 199, 246, 18, 183, + 25, 177, 171, 246, 62, 250, 91, 250, 194, 183, 25, 177, 171, 246, 62, + 250, 91, 124, 247, 206, 97, 138, 247, 206, 97, 211, 217, 3, 247, 58, 95, + 211, 216, 211, 217, 3, 118, 211, 241, 204, 75, 211, 217, 3, 126, 211, + 241, 204, 74, 248, 203, 241, 117, 218, 81, 227, 217, 225, 149, 238, 49, + 216, 11, 225, 149, 238, 49, 227, 43, 3, 231, 17, 219, 9, 246, 16, 227, + 43, 3, 229, 151, 229, 151, 227, 42, 171, 227, 42, 248, 128, 248, 129, 3, + 247, 58, 95, 248, 7, 227, 105, 97, 216, 205, 247, 145, 249, 26, 3, 96, + 53, 55, 241, 84, 3, 96, 53, 55, 220, 32, 3, 240, 212, 131, 3, 49, 50, 53, + 55, 211, 249, 3, 86, 53, 55, 208, 145, 3, 177, 53, 55, 221, 192, 118, + 206, 248, 241, 141, 97, 229, 148, 209, 152, 231, 11, 16, 35, 8, 6, 227, + 173, 231, 11, 16, 35, 8, 5, 227, 173, 231, 11, 16, 35, 221, 45, 231, 11, + 16, 35, 210, 102, 231, 11, 16, 35, 8, 227, 173, 239, 249, 241, 117, 208, + 140, 203, 225, 237, 130, 221, 28, 25, 248, 14, 236, 134, 218, 106, 224, + 151, 209, 160, 245, 112, 248, 251, 212, 88, 218, 61, 211, 95, 3, 101, + 243, 85, 230, 169, 16, 35, 248, 141, 208, 80, 241, 100, 62, 51, 247, 145, + 61, 51, 247, 145, 228, 8, 216, 138, 246, 61, 228, 8, 248, 26, 246, 61, + 228, 8, 219, 243, 243, 221, 228, 8, 248, 26, 243, 221, 5, 219, 243, 243, + 221, 5, 248, 26, 243, 221, 206, 223, 216, 138, 208, 85, 242, 69, 216, + 138, 208, 85, 206, 223, 5, 216, 138, 208, 85, 242, 69, 5, 216, 138, 208, + 85, 226, 251, 50, 213, 77, 61, 246, 61, 206, 221, 50, 213, 77, 61, 246, + 61, 43, 245, 131, 218, 48, 245, 131, 218, 49, 3, 237, 136, 56, 245, 131, + 218, 48, 221, 162, 49, 213, 146, 3, 126, 243, 83, 221, 162, 50, 213, 146, + 3, 126, 243, 83, 16, 35, 225, 87, 246, 184, 61, 8, 245, 130, 79, 8, 245, + 130, 246, 222, 245, 130, 220, 40, 97, 242, 72, 76, 219, 32, 230, 39, 224, + 22, 210, 96, 224, 237, 3, 222, 64, 247, 222, 247, 238, 76, 235, 222, 246, + 20, 240, 103, 118, 220, 83, 246, 20, 240, 103, 120, 220, 83, 246, 20, + 240, 103, 126, 220, 83, 246, 20, 240, 103, 239, 147, 220, 83, 246, 20, + 240, 103, 239, 233, 220, 83, 246, 20, 240, 103, 212, 88, 220, 83, 246, + 20, 240, 103, 213, 112, 220, 83, 246, 20, 240, 103, 241, 143, 220, 83, + 246, 20, 240, 103, 222, 64, 220, 83, 246, 20, 240, 103, 209, 153, 220, + 83, 246, 20, 240, 103, 241, 113, 220, 83, 246, 20, 240, 103, 207, 155, + 220, 83, 246, 20, 240, 103, 220, 27, 246, 20, 240, 103, 207, 132, 246, + 20, 240, 103, 209, 26, 246, 20, 240, 103, 239, 143, 246, 20, 240, 103, + 239, 231, 246, 20, 240, 103, 212, 84, 246, 20, 240, 103, 213, 110, 246, + 20, 240, 103, 241, 142, 246, 20, 240, 103, 222, 62, 246, 20, 240, 103, + 209, 151, 246, 20, 240, 103, 241, 111, 246, 20, 240, 103, 207, 153, 50, + 211, 216, 50, 211, 217, 3, 118, 211, 241, 204, 75, 50, 211, 217, 3, 126, + 211, 241, 204, 74, 247, 175, 247, 176, 3, 211, 241, 204, 74, 215, 251, + 248, 128, 248, 9, 247, 56, 225, 109, 246, 19, 62, 212, 63, 25, 245, 129, + 221, 192, 218, 112, 236, 126, 225, 123, 231, 50, 247, 152, 210, 228, 227, + 166, 212, 52, 219, 245, 211, 178, 244, 150, 210, 210, 211, 205, 211, 206, + 204, 59, 230, 83, 49, 237, 124, 209, 162, 216, 152, 209, 162, 216, 153, + 3, 219, 153, 50, 237, 124, 209, 162, 216, 152, 61, 208, 126, 209, 161, + 62, 208, 126, 209, 161, 209, 162, 220, 32, 208, 145, 76, 224, 76, 246, + 40, 224, 80, 218, 176, 249, 26, 76, 241, 57, 211, 100, 241, 57, 241, 58, + 3, 227, 131, 239, 189, 241, 57, 219, 10, 115, 211, 100, 241, 57, 227, + 104, 219, 93, 62, 217, 161, 226, 251, 49, 219, 8, 226, 251, 49, 248, 246, + 219, 9, 226, 251, 49, 239, 149, 219, 9, 226, 251, 49, 219, 147, 226, 251, + 49, 245, 144, 49, 203, 220, 237, 123, 207, 174, 220, 52, 237, 124, 54, + 216, 188, 237, 124, 3, 239, 254, 211, 195, 216, 73, 216, 188, 237, 124, + 3, 239, 254, 211, 195, 216, 73, 209, 20, 112, 54, 216, 73, 209, 20, 121, + 54, 216, 73, 205, 228, 237, 123, 216, 73, 237, 124, 3, 101, 240, 3, 240, + 201, 216, 188, 237, 124, 3, 219, 71, 248, 104, 101, 25, 215, 253, 239, + 253, 61, 121, 218, 59, 49, 237, 124, 231, 35, 212, 154, 61, 49, 218, 59, + 231, 35, 212, 154, 61, 50, 218, 59, 231, 35, 212, 154, 62, 49, 218, 59, + 231, 35, 212, 154, 62, 50, 218, 59, 231, 35, 62, 49, 218, 59, 249, 23, + 231, 35, 62, 50, 218, 59, 249, 23, 231, 35, 212, 154, 61, 112, 218, 59, + 231, 35, 212, 154, 61, 121, 218, 59, 231, 35, 212, 154, 62, 112, 218, 59, + 231, 35, 212, 154, 62, 121, 218, 59, 231, 35, 62, 112, 218, 59, 249, 23, + 231, 35, 62, 121, 218, 59, 249, 23, 231, 35, 244, 11, 245, 220, 229, 150, + 25, 224, 9, 126, 222, 218, 245, 219, 217, 231, 218, 67, 247, 74, 62, 237, + 91, 213, 33, 239, 202, 243, 154, 61, 237, 91, 213, 33, 239, 202, 243, + 154, 212, 7, 213, 33, 239, 202, 243, 154, 209, 221, 247, 22, 204, 6, 229, + 149, 118, 247, 146, 224, 9, 120, 247, 146, 224, 9, 126, 247, 146, 224, 9, + 208, 117, 38, 218, 228, 245, 220, 237, 91, 243, 154, 214, 184, 217, 232, + 235, 156, 240, 65, 235, 156, 219, 248, 243, 160, 235, 156, 243, 107, 3, + 209, 112, 243, 107, 3, 209, 113, 25, 218, 161, 243, 107, 3, 218, 161, + 239, 135, 3, 218, 161, 239, 135, 3, 208, 225, 239, 135, 3, 250, 232, 203, + 196, 62, 239, 182, 239, 182, 171, 239, 182, 247, 38, 122, 243, 140, 247, + 38, 240, 11, 247, 233, 240, 11, 247, 87, 241, 94, 221, 160, 241, 94, 221, + 161, 219, 153, 241, 94, 221, 161, 219, 159, 221, 160, 221, 161, 219, 153, + 221, 161, 219, 159, 241, 94, 243, 106, 241, 94, 219, 153, 241, 94, 219, + 151, 243, 106, 219, 153, 219, 151, 204, 85, 211, 202, 221, 161, 219, 159, + 211, 202, 247, 73, 219, 159, 244, 11, 204, 15, 224, 105, 225, 64, 219, + 201, 246, 18, 50, 25, 49, 213, 146, 250, 91, 247, 58, 203, 196, 231, 41, + 239, 176, 212, 72, 97, 244, 64, 239, 176, 212, 72, 97, 245, 221, 38, 229, + 151, 215, 214, 222, 210, 219, 154, 3, 43, 209, 112, 211, 65, 246, 177, + 244, 196, 229, 33, 227, 98, 211, 215, 237, 65, 231, 50, 212, 136, 126, + 216, 163, 55, 126, 216, 163, 56, 126, 216, 163, 227, 222, 126, 216, 163, + 216, 16, 49, 211, 212, 247, 192, 50, 211, 212, 247, 192, 120, 211, 212, + 247, 191, 126, 211, 212, 247, 191, 49, 209, 38, 247, 192, 50, 209, 38, + 247, 192, 49, 250, 220, 247, 192, 50, 250, 220, 247, 192, 224, 34, 247, + 192, 227, 132, 224, 34, 247, 192, 227, 132, 224, 33, 248, 248, 98, 3, + 248, 247, 248, 248, 132, 203, 196, 248, 248, 98, 3, 132, 203, 196, 248, + 248, 26, 132, 203, 196, 248, 248, 98, 3, 26, 132, 203, 196, 157, 246, + 169, 82, 248, 248, 98, 3, 26, 246, 168, 203, 233, 225, 106, 224, 14, 239, + 103, 208, 167, 208, 122, 211, 86, 76, 227, 146, 212, 137, 76, 230, 170, + 223, 251, 237, 241, 240, 102, 237, 241, 240, 103, 3, 212, 30, 240, 184, + 240, 103, 3, 209, 179, 76, 230, 85, 212, 30, 240, 103, 3, 171, 224, 7, + 212, 30, 240, 103, 3, 171, 224, 8, 25, 212, 30, 240, 184, 212, 30, 240, + 103, 3, 171, 224, 8, 25, 245, 246, 210, 166, 212, 30, 240, 103, 3, 171, + 224, 8, 25, 208, 243, 240, 184, 212, 30, 240, 103, 3, 237, 135, 212, 30, + 240, 103, 3, 236, 52, 204, 8, 240, 102, 212, 30, 240, 103, 3, 212, 30, + 240, 184, 240, 103, 214, 214, 244, 45, 239, 174, 216, 113, 240, 102, 212, + 30, 240, 103, 3, 237, 54, 240, 184, 212, 30, 240, 103, 3, 210, 210, 212, + 29, 240, 102, 222, 216, 240, 102, 240, 203, 240, 102, 206, 253, 240, 102, + 240, 103, 3, 245, 246, 210, 166, 219, 1, 240, 102, 245, 212, 240, 102, + 245, 213, 240, 102, 229, 65, 240, 102, 240, 103, 209, 23, 34, 229, 66, + 229, 65, 240, 103, 3, 212, 30, 240, 184, 229, 65, 240, 103, 3, 246, 16, + 240, 184, 240, 103, 3, 211, 16, 208, 150, 240, 103, 3, 211, 16, 208, 151, + 25, 204, 8, 240, 191, 240, 103, 3, 211, 16, 208, 151, 25, 208, 243, 240, + 184, 243, 161, 240, 102, 203, 232, 240, 102, 250, 214, 240, 102, 218, 19, + 240, 102, 245, 114, 240, 102, 218, 232, 240, 102, 240, 103, 3, 227, 17, + 76, 208, 62, 243, 161, 247, 148, 216, 113, 240, 102, 239, 114, 240, 103, + 3, 171, 224, 7, 250, 212, 240, 102, 240, 58, 240, 102, 204, 60, 240, 102, + 212, 53, 240, 102, 208, 205, 240, 102, 237, 242, 240, 102, 227, 4, 245, + 114, 240, 102, 240, 103, 3, 171, 224, 7, 236, 2, 240, 102, 240, 103, 3, + 171, 224, 8, 25, 245, 246, 210, 166, 240, 103, 214, 186, 231, 50, 240, + 59, 250, 56, 240, 102, 239, 194, 240, 102, 212, 54, 240, 102, 243, 133, + 240, 102, 240, 103, 204, 3, 224, 7, 240, 103, 3, 225, 12, 225, 76, 237, + 241, 247, 18, 240, 103, 3, 212, 30, 240, 184, 247, 18, 240, 103, 3, 209, + 179, 76, 230, 85, 212, 30, 247, 18, 240, 103, 3, 171, 224, 7, 212, 30, + 247, 18, 240, 103, 3, 237, 54, 240, 184, 247, 18, 240, 103, 3, 203, 218, + 212, 31, 229, 65, 247, 18, 240, 103, 3, 246, 16, 240, 184, 218, 19, 247, + 18, 240, 102, 245, 114, 247, 18, 240, 102, 204, 60, 247, 18, 240, 102, + 212, 47, 239, 114, 240, 102, 212, 47, 212, 30, 240, 102, 206, 218, 240, + 102, 240, 103, 3, 215, 212, 240, 184, 240, 103, 3, 221, 192, 238, 27, + 238, 160, 240, 103, 3, 220, 52, 238, 160, 218, 230, 247, 239, 244, 59, + 214, 164, 224, 48, 237, 57, 224, 48, 211, 218, 224, 48, 237, 93, 218, + 230, 216, 187, 118, 237, 123, 218, 230, 216, 187, 247, 251, 237, 100, + 231, 50, 246, 224, 218, 230, 239, 113, 218, 230, 3, 218, 19, 240, 102, + 218, 230, 3, 239, 183, 237, 99, 153, 204, 46, 218, 59, 227, 229, 211, + 238, 204, 46, 218, 59, 227, 229, 153, 241, 176, 218, 59, 227, 229, 211, + 238, 241, 176, 218, 59, 227, 229, 207, 174, 153, 204, 46, 218, 59, 227, + 229, 207, 174, 211, 238, 204, 46, 218, 59, 227, 229, 207, 174, 153, 241, + 176, 218, 59, 227, 229, 207, 174, 211, 238, 241, 176, 218, 59, 227, 229, + 153, 204, 46, 218, 59, 205, 212, 227, 229, 211, 238, 204, 46, 218, 59, + 205, 212, 227, 229, 153, 241, 176, 218, 59, 205, 212, 227, 229, 211, 238, + 241, 176, 218, 59, 205, 212, 227, 229, 79, 153, 204, 46, 218, 59, 205, + 212, 227, 229, 79, 211, 238, 204, 46, 218, 59, 205, 212, 227, 229, 79, + 153, 241, 176, 218, 59, 205, 212, 227, 229, 79, 211, 238, 241, 176, 218, + 59, 205, 212, 227, 229, 153, 204, 46, 218, 59, 247, 189, 211, 238, 204, + 46, 218, 59, 247, 189, 153, 241, 176, 218, 59, 247, 189, 211, 238, 241, + 176, 218, 59, 247, 189, 79, 153, 204, 46, 218, 59, 247, 189, 79, 211, + 238, 204, 46, 218, 59, 247, 189, 79, 153, 241, 176, 218, 59, 247, 189, + 79, 211, 238, 241, 176, 218, 59, 247, 189, 236, 125, 217, 40, 51, 219, + 233, 236, 125, 217, 40, 51, 219, 234, 231, 50, 62, 211, 177, 212, 2, 217, + 40, 51, 219, 233, 212, 2, 217, 40, 51, 219, 234, 231, 50, 62, 211, 177, + 96, 215, 218, 177, 215, 218, 86, 215, 218, 183, 215, 218, 132, 32, 240, + 251, 219, 233, 79, 132, 32, 240, 251, 219, 233, 32, 171, 240, 251, 219, + 233, 79, 32, 171, 240, 251, 219, 233, 79, 250, 236, 219, 233, 210, 169, + 250, 236, 219, 233, 41, 79, 52, 207, 174, 245, 234, 217, 31, 131, 219, + 233, 41, 79, 52, 245, 234, 217, 31, 131, 219, 233, 41, 79, 124, 52, 245, + 234, 217, 31, 131, 219, 233, 79, 230, 248, 219, 233, 41, 230, 248, 219, + 233, 79, 41, 230, 248, 219, 233, 205, 242, 79, 212, 0, 205, 242, 79, 216, + 74, 212, 0, 246, 167, 248, 20, 216, 74, 246, 167, 248, 20, 215, 218, 237, + 38, 211, 81, 227, 40, 216, 193, 247, 39, 236, 240, 208, 110, 236, 240, + 208, 111, 3, 247, 178, 221, 167, 208, 110, 224, 213, 157, 216, 194, 211, + 87, 208, 108, 208, 109, 247, 39, 247, 153, 220, 29, 247, 153, 208, 59, + 247, 154, 211, 61, 224, 109, 250, 240, 239, 250, 241, 77, 218, 51, 247, + 39, 220, 29, 218, 51, 247, 39, 209, 197, 220, 29, 209, 197, 250, 22, 220, + 29, 250, 22, 216, 145, 206, 47, 244, 41, 208, 50, 250, 86, 227, 8, 208, + 116, 224, 42, 224, 13, 216, 192, 210, 182, 216, 192, 224, 13, 247, 86, + 251, 95, 208, 107, 212, 251, 215, 188, 211, 210, 236, 106, 208, 114, 227, + 134, 80, 208, 114, 227, 134, 245, 199, 54, 218, 51, 247, 24, 216, 67, + 227, 134, 208, 82, 239, 226, 220, 32, 218, 30, 243, 88, 221, 192, 241, + 63, 54, 212, 28, 97, 221, 192, 212, 28, 97, 217, 160, 227, 87, 231, 50, + 230, 198, 218, 97, 97, 243, 114, 221, 166, 227, 87, 97, 218, 24, 204, 81, + 97, 221, 182, 204, 81, 97, 248, 82, 221, 192, 248, 81, 248, 80, 224, 13, + 248, 80, 219, 25, 221, 192, 219, 24, 246, 132, 245, 123, 224, 236, 97, + 203, 247, 97, 216, 83, 249, 28, 97, 208, 168, 204, 81, 246, 13, 212, 209, + 248, 206, 248, 204, 219, 57, 245, 183, 245, 79, 249, 7, 246, 41, 49, 226, + 229, 208, 86, 3, 215, 189, 245, 164, 217, 220, 54, 43, 231, 25, 211, 239, + 247, 231, 97, 238, 59, 97, 245, 157, 25, 228, 18, 212, 54, 251, 135, 212, + 231, 249, 6, 248, 127, 248, 128, 248, 151, 218, 97, 76, 203, 231, 237, + 131, 25, 203, 225, 213, 8, 220, 56, 242, 46, 224, 17, 216, 193, 208, 118, + 224, 19, 248, 19, 206, 223, 224, 119, 251, 52, 206, 223, 251, 52, 206, + 223, 5, 251, 52, 5, 251, 52, 221, 171, 251, 52, 251, 53, 244, 25, 251, + 53, 250, 97, 214, 221, 220, 29, 239, 250, 241, 77, 243, 211, 227, 40, + 219, 60, 212, 251, 136, 16, 35, 217, 36, 136, 16, 35, 251, 54, 136, 16, + 35, 239, 249, 136, 16, 35, 241, 179, 136, 16, 35, 204, 80, 136, 16, 35, + 250, 146, 136, 16, 35, 250, 147, 216, 132, 136, 16, 35, 250, 147, 216, + 131, 136, 16, 35, 250, 147, 205, 195, 136, 16, 35, 250, 147, 205, 194, + 136, 16, 35, 205, 209, 136, 16, 35, 205, 208, 136, 16, 35, 205, 207, 136, + 16, 35, 210, 221, 136, 16, 35, 218, 184, 210, 221, 136, 16, 35, 62, 210, + 221, 136, 16, 35, 224, 235, 210, 252, 136, 16, 35, 224, 235, 210, 251, + 136, 16, 35, 224, 235, 210, 250, 136, 16, 35, 246, 64, 136, 16, 35, 215, + 1, 136, 16, 35, 222, 51, 136, 16, 35, 205, 193, 136, 16, 35, 205, 192, + 136, 16, 35, 215, 219, 215, 1, 136, 16, 35, 215, 219, 215, 0, 136, 16, + 35, 238, 31, 136, 16, 35, 212, 133, 136, 16, 35, 230, 221, 219, 239, 136, + 16, 35, 230, 221, 219, 238, 136, 16, 35, 245, 134, 76, 230, 220, 136, 16, + 35, 216, 128, 76, 230, 220, 136, 16, 35, 245, 174, 219, 239, 136, 16, 35, + 230, 219, 219, 239, 136, 16, 35, 210, 253, 76, 245, 173, 136, 16, 35, + 245, 134, 76, 245, 173, 136, 16, 35, 245, 134, 76, 245, 172, 136, 16, 35, + 245, 174, 250, 188, 136, 16, 35, 215, 2, 76, 245, 174, 250, 188, 136, 16, + 35, 210, 253, 76, 215, 2, 76, 245, 173, 136, 16, 35, 206, 42, 136, 16, + 35, 208, 218, 219, 239, 136, 16, 35, 227, 233, 219, 239, 136, 16, 35, + 250, 187, 219, 239, 136, 16, 35, 210, 253, 76, 250, 186, 136, 16, 35, + 215, 2, 76, 250, 186, 136, 16, 35, 210, 253, 76, 215, 2, 76, 250, 186, + 136, 16, 35, 205, 210, 76, 250, 186, 136, 16, 35, 216, 128, 76, 250, 186, + 136, 16, 35, 216, 128, 76, 250, 185, 136, 16, 35, 216, 127, 136, 16, 35, + 216, 126, 136, 16, 35, 216, 125, 136, 16, 35, 216, 124, 136, 16, 35, 251, + 17, 136, 16, 35, 251, 16, 136, 16, 35, 225, 97, 136, 16, 35, 215, 7, 136, + 16, 35, 250, 90, 136, 16, 35, 216, 155, 136, 16, 35, 216, 154, 136, 16, + 35, 250, 25, 136, 16, 35, 248, 52, 219, 239, 136, 16, 35, 209, 216, 136, + 16, 35, 209, 215, 136, 16, 35, 217, 42, 227, 123, 136, 16, 35, 248, 0, + 136, 16, 35, 247, 255, 136, 16, 35, 247, 254, 136, 16, 35, 250, 249, 136, + 16, 35, 220, 55, 136, 16, 35, 211, 198, 136, 16, 35, 208, 216, 136, 16, + 35, 237, 210, 136, 16, 35, 204, 68, 136, 16, 35, 218, 18, 136, 16, 35, + 247, 70, 136, 16, 35, 207, 166, 136, 16, 35, 247, 41, 224, 23, 136, 16, + 35, 214, 199, 76, 230, 87, 136, 16, 35, 247, 83, 136, 16, 35, 208, 79, + 136, 16, 35, 211, 92, 208, 79, 136, 16, 35, 227, 39, 136, 16, 35, 212, + 11, 136, 16, 35, 206, 202, 136, 16, 35, 236, 50, 242, 27, 136, 16, 35, + 250, 70, 136, 16, 35, 218, 26, 250, 70, 136, 16, 35, 247, 210, 136, 16, + 35, 218, 17, 247, 210, 136, 16, 35, 250, 246, 136, 16, 35, 211, 48, 210, + 202, 211, 47, 136, 16, 35, 211, 48, 210, 202, 211, 46, 136, 16, 35, 210, + 249, 136, 16, 35, 217, 247, 136, 16, 35, 243, 150, 136, 16, 35, 243, 152, + 136, 16, 35, 243, 151, 136, 16, 35, 217, 169, 136, 16, 35, 217, 158, 136, + 16, 35, 245, 121, 136, 16, 35, 245, 120, 136, 16, 35, 245, 119, 136, 16, + 35, 245, 118, 136, 16, 35, 245, 117, 136, 16, 35, 251, 29, 136, 16, 35, + 248, 207, 76, 225, 81, 136, 16, 35, 248, 207, 76, 206, 74, 136, 16, 35, + 216, 81, 136, 16, 35, 236, 42, 136, 16, 35, 222, 79, 136, 16, 35, 244, + 132, 136, 16, 35, 224, 37, 136, 16, 35, 162, 242, 59, 136, 16, 35, 162, + 219, 214, 62, 227, 217, 230, 204, 50, 208, 85, 62, 206, 223, 230, 204, + 50, 208, 85, 62, 216, 11, 230, 204, 50, 208, 85, 62, 242, 69, 230, 204, + 50, 208, 85, 62, 212, 47, 5, 246, 61, 225, 10, 26, 61, 246, 61, 26, 61, + 246, 61, 79, 61, 246, 61, 205, 242, 79, 61, 246, 61, 240, 195, 79, 61, + 246, 61, 61, 246, 62, 245, 195, 62, 5, 246, 61, 215, 191, 209, 217, 62, + 208, 213, 211, 177, 62, 212, 47, 5, 211, 177, 157, 61, 211, 177, 225, 10, + 61, 211, 177, 26, 61, 211, 177, 79, 61, 211, 177, 205, 242, 79, 61, 211, + 177, 240, 195, 79, 61, 211, 177, 61, 51, 245, 195, 62, 205, 242, 5, 211, + 177, 61, 51, 245, 195, 62, 225, 10, 211, 177, 51, 209, 217, 62, 208, 213, + 243, 221, 62, 205, 242, 5, 243, 221, 62, 225, 10, 5, 243, 221, 61, 243, + 222, 245, 195, 62, 205, 242, 5, 243, 221, 61, 243, 222, 245, 195, 62, + 225, 10, 243, 221, 243, 222, 209, 217, 62, 208, 213, 226, 246, 62, 205, + 242, 5, 226, 246, 62, 225, 10, 5, 226, 246, 61, 226, 247, 245, 195, 62, + 5, 226, 246, 209, 63, 30, 245, 130, 157, 30, 245, 130, 225, 10, 30, 245, + 130, 26, 30, 245, 130, 205, 242, 26, 30, 245, 130, 205, 242, 79, 30, 245, + 130, 240, 195, 79, 30, 245, 130, 209, 63, 214, 254, 157, 214, 254, 225, + 10, 214, 254, 26, 214, 254, 79, 214, 254, 205, 242, 79, 214, 254, 240, + 195, 79, 214, 254, 157, 239, 233, 211, 191, 250, 59, 225, 10, 239, 233, + 211, 191, 250, 59, 26, 239, 233, 211, 191, 250, 59, 79, 239, 233, 211, + 191, 250, 59, 205, 242, 79, 239, 233, 211, 191, 250, 59, 240, 195, 79, + 239, 233, 211, 191, 250, 59, 157, 212, 88, 211, 191, 250, 59, 225, 10, + 212, 88, 211, 191, 250, 59, 26, 212, 88, 211, 191, 250, 59, 79, 212, 88, + 211, 191, 250, 59, 205, 242, 79, 212, 88, 211, 191, 250, 59, 240, 195, + 79, 212, 88, 211, 191, 250, 59, 157, 241, 143, 211, 191, 250, 59, 225, + 10, 241, 143, 211, 191, 250, 59, 26, 241, 143, 211, 191, 250, 59, 79, + 241, 143, 211, 191, 250, 59, 205, 242, 79, 241, 143, 211, 191, 250, 59, + 157, 126, 218, 61, 62, 211, 94, 225, 10, 126, 218, 61, 62, 211, 94, 126, + 218, 61, 62, 211, 94, 225, 10, 126, 218, 61, 218, 118, 211, 94, 157, 239, + 147, 218, 61, 62, 211, 94, 225, 10, 239, 147, 218, 61, 62, 211, 94, 239, + 147, 218, 61, 62, 211, 94, 225, 10, 239, 147, 218, 61, 218, 118, 211, 94, + 216, 74, 157, 239, 147, 218, 61, 218, 118, 211, 94, 157, 239, 233, 218, + 61, 62, 211, 94, 79, 239, 233, 218, 61, 62, 211, 94, 225, 10, 212, 88, + 218, 61, 62, 211, 94, 79, 212, 88, 218, 61, 62, 211, 94, 212, 88, 218, + 61, 218, 118, 211, 94, 225, 10, 241, 143, 218, 61, 62, 211, 94, 79, 241, + 143, 218, 61, 62, 211, 94, 205, 242, 79, 241, 143, 218, 61, 62, 211, 94, + 79, 241, 143, 218, 61, 218, 118, 211, 94, 157, 207, 155, 218, 61, 62, + 211, 94, 79, 207, 155, 218, 61, 62, 211, 94, 79, 207, 155, 218, 61, 218, + 118, 211, 94, 96, 53, 3, 5, 208, 86, 250, 94, 177, 53, 3, 5, 208, 86, + 250, 94, 86, 53, 3, 5, 208, 86, 250, 94, 183, 53, 3, 5, 208, 86, 250, 94, + 96, 53, 3, 225, 10, 208, 86, 250, 94, 177, 53, 3, 225, 10, 208, 86, 250, + 94, 86, 53, 3, 225, 10, 208, 86, 250, 94, 183, 53, 3, 225, 10, 208, 86, + 250, 94, 96, 53, 3, 228, 8, 208, 86, 250, 94, 177, 53, 3, 228, 8, 208, + 86, 250, 94, 86, 53, 3, 228, 8, 208, 86, 250, 94, 183, 53, 3, 228, 8, + 208, 86, 250, 94, 96, 53, 3, 5, 241, 31, 250, 94, 177, 53, 3, 5, 241, 31, + 250, 94, 86, 53, 3, 5, 241, 31, 250, 94, 183, 53, 3, 5, 241, 31, 250, 94, + 96, 53, 3, 241, 31, 250, 94, 177, 53, 3, 241, 31, 250, 94, 86, 53, 3, + 241, 31, 250, 94, 183, 53, 3, 241, 31, 250, 94, 79, 96, 53, 3, 241, 31, + 250, 94, 79, 177, 53, 3, 241, 31, 250, 94, 79, 86, 53, 3, 241, 31, 250, + 94, 79, 183, 53, 3, 241, 31, 250, 94, 79, 96, 53, 3, 228, 8, 241, 31, + 250, 94, 79, 177, 53, 3, 228, 8, 241, 31, 250, 94, 79, 86, 53, 3, 228, 8, + 241, 31, 250, 94, 79, 183, 53, 3, 228, 8, 241, 31, 250, 94, 96, 208, 84, + 53, 3, 223, 73, 213, 75, 177, 208, 84, 53, 3, 223, 73, 213, 75, 86, 208, + 84, 53, 3, 223, 73, 213, 75, 183, 208, 84, 53, 3, 223, 73, 213, 75, 96, + 208, 84, 53, 3, 225, 10, 213, 75, 177, 208, 84, 53, 3, 225, 10, 213, 75, + 86, 208, 84, 53, 3, 225, 10, 213, 75, 183, 208, 84, 53, 3, 225, 10, 213, + 75, 96, 208, 84, 53, 3, 26, 213, 75, 177, 208, 84, 53, 3, 26, 213, 75, + 86, 208, 84, 53, 3, 26, 213, 75, 183, 208, 84, 53, 3, 26, 213, 75, 96, + 208, 84, 53, 3, 79, 213, 75, 177, 208, 84, 53, 3, 79, 213, 75, 86, 208, + 84, 53, 3, 79, 213, 75, 183, 208, 84, 53, 3, 79, 213, 75, 96, 208, 84, + 53, 3, 205, 242, 79, 213, 75, 177, 208, 84, 53, 3, 205, 242, 79, 213, 75, + 86, 208, 84, 53, 3, 205, 242, 79, 213, 75, 183, 208, 84, 53, 3, 205, 242, + 79, 213, 75, 96, 240, 1, 47, 177, 240, 1, 47, 86, 240, 1, 47, 183, 240, + 1, 47, 96, 103, 47, 177, 103, 47, 86, 103, 47, 183, 103, 47, 96, 245, + 222, 47, 177, 245, 222, 47, 86, 245, 222, 47, 183, 245, 222, 47, 96, 79, + 245, 222, 47, 177, 79, 245, 222, 47, 86, 79, 245, 222, 47, 183, 79, 245, + 222, 47, 96, 79, 47, 177, 79, 47, 86, 79, 47, 183, 79, 47, 96, 41, 47, + 177, 41, 47, 86, 41, 47, 183, 41, 47, 153, 204, 46, 41, 47, 153, 241, + 176, 41, 47, 211, 238, 241, 176, 41, 47, 211, 238, 204, 46, 41, 47, 49, + 50, 41, 47, 112, 121, 41, 47, 204, 26, 96, 157, 150, 47, 204, 26, 177, + 157, 150, 47, 204, 26, 86, 157, 150, 47, 204, 26, 183, 157, 150, 47, 204, + 26, 153, 204, 46, 157, 150, 47, 204, 26, 153, 241, 176, 157, 150, 47, + 204, 26, 211, 238, 241, 176, 157, 150, 47, 204, 26, 211, 238, 204, 46, + 157, 150, 47, 204, 26, 96, 150, 47, 204, 26, 177, 150, 47, 204, 26, 86, + 150, 47, 204, 26, 183, 150, 47, 204, 26, 153, 204, 46, 150, 47, 204, 26, + 153, 241, 176, 150, 47, 204, 26, 211, 238, 241, 176, 150, 47, 204, 26, + 211, 238, 204, 46, 150, 47, 204, 26, 96, 225, 10, 150, 47, 204, 26, 177, + 225, 10, 150, 47, 204, 26, 86, 225, 10, 150, 47, 204, 26, 183, 225, 10, + 150, 47, 204, 26, 153, 204, 46, 225, 10, 150, 47, 204, 26, 153, 241, 176, + 225, 10, 150, 47, 204, 26, 211, 238, 241, 176, 225, 10, 150, 47, 204, 26, + 211, 238, 204, 46, 225, 10, 150, 47, 204, 26, 96, 79, 150, 47, 204, 26, + 177, 79, 150, 47, 204, 26, 86, 79, 150, 47, 204, 26, 183, 79, 150, 47, + 204, 26, 153, 204, 46, 79, 150, 47, 204, 26, 153, 241, 176, 79, 150, 47, + 204, 26, 211, 238, 241, 176, 79, 150, 47, 204, 26, 211, 238, 204, 46, 79, + 150, 47, 204, 26, 96, 205, 242, 79, 150, 47, 204, 26, 177, 205, 242, 79, + 150, 47, 204, 26, 86, 205, 242, 79, 150, 47, 204, 26, 183, 205, 242, 79, + 150, 47, 204, 26, 153, 204, 46, 205, 242, 79, 150, 47, 204, 26, 153, 241, + 176, 205, 242, 79, 150, 47, 204, 26, 211, 238, 241, 176, 205, 242, 79, + 150, 47, 204, 26, 211, 238, 204, 46, 205, 242, 79, 150, 47, 96, 208, 86, + 250, 94, 177, 208, 86, 250, 94, 86, 208, 86, 250, 94, 183, 208, 86, 250, + 94, 96, 61, 53, 204, 5, 208, 86, 250, 94, 177, 61, 53, 204, 5, 208, 86, + 250, 94, 86, 61, 53, 204, 5, 208, 86, 250, 94, 183, 61, 53, 204, 5, 208, + 86, 250, 94, 96, 53, 3, 221, 162, 209, 248, 177, 53, 3, 221, 162, 209, + 248, 86, 53, 3, 221, 162, 209, 248, 183, 53, 3, 221, 162, 209, 248, 79, + 53, 213, 76, 204, 24, 105, 79, 53, 213, 76, 204, 24, 120, 209, 57, 79, + 53, 213, 76, 204, 24, 118, 237, 137, 79, 53, 213, 76, 204, 24, 118, 209, + 60, 96, 247, 245, 61, 47, 86, 247, 248, 213, 78, 61, 47, 96, 208, 145, + 213, 78, 61, 47, 86, 208, 145, 213, 78, 61, 47, 96, 227, 216, 61, 47, 86, + 216, 10, 61, 47, 96, 216, 10, 61, 47, 86, 227, 216, 61, 47, 96, 249, 24, + 213, 77, 61, 47, 86, 249, 24, 213, 77, 61, 47, 96, 239, 117, 213, 77, 61, + 47, 86, 239, 117, 213, 77, 61, 47, 61, 53, 213, 76, 204, 24, 105, 61, 53, + 213, 76, 204, 24, 120, 209, 57, 202, 26, 240, 102, 224, 52, 240, 102, + 240, 103, 3, 209, 80, 222, 222, 240, 102, 209, 62, 240, 102, 240, 103, 3, + 237, 63, 215, 221, 240, 102, 236, 20, 240, 102, 2, 76, 209, 93, 236, 52, + 245, 146, 227, 102, 240, 102, 214, 188, 207, 179, 206, 240, 240, 102, + 246, 161, 204, 57, 12, 15, 235, 152, 12, 15, 235, 151, 12, 15, 235, 150, + 12, 15, 235, 149, 12, 15, 235, 148, 12, 15, 235, 147, 12, 15, 235, 146, + 12, 15, 235, 145, 12, 15, 235, 144, 12, 15, 235, 143, 12, 15, 235, 142, + 12, 15, 235, 141, 12, 15, 235, 140, 12, 15, 235, 139, 12, 15, 235, 138, + 12, 15, 235, 137, 12, 15, 235, 136, 12, 15, 235, 135, 12, 15, 235, 134, + 12, 15, 235, 133, 12, 15, 235, 132, 12, 15, 235, 131, 12, 15, 235, 130, + 12, 15, 235, 129, 12, 15, 235, 128, 12, 15, 235, 127, 12, 15, 235, 126, + 12, 15, 235, 125, 12, 15, 235, 124, 12, 15, 235, 123, 12, 15, 235, 122, + 12, 15, 235, 121, 12, 15, 235, 120, 12, 15, 235, 119, 12, 15, 235, 118, + 12, 15, 235, 117, 12, 15, 235, 116, 12, 15, 235, 115, 12, 15, 235, 114, + 12, 15, 235, 113, 12, 15, 235, 112, 12, 15, 235, 111, 12, 15, 235, 110, + 12, 15, 235, 109, 12, 15, 235, 108, 12, 15, 235, 107, 12, 15, 235, 106, + 12, 15, 235, 105, 12, 15, 235, 104, 12, 15, 235, 103, 12, 15, 235, 102, + 12, 15, 235, 101, 12, 15, 235, 100, 12, 15, 235, 99, 12, 15, 235, 98, 12, + 15, 235, 97, 12, 15, 235, 96, 12, 15, 235, 95, 12, 15, 235, 94, 12, 15, + 235, 93, 12, 15, 235, 92, 12, 15, 235, 91, 12, 15, 235, 90, 12, 15, 235, + 89, 12, 15, 235, 88, 12, 15, 235, 87, 12, 15, 235, 86, 12, 15, 235, 85, + 12, 15, 235, 84, 12, 15, 235, 83, 12, 15, 235, 82, 12, 15, 235, 81, 12, + 15, 235, 80, 12, 15, 235, 79, 12, 15, 235, 78, 12, 15, 235, 77, 12, 15, + 235, 76, 12, 15, 235, 75, 12, 15, 235, 74, 12, 15, 235, 73, 12, 15, 235, + 72, 12, 15, 235, 71, 12, 15, 235, 70, 12, 15, 235, 69, 12, 15, 235, 68, + 12, 15, 235, 67, 12, 15, 235, 66, 12, 15, 235, 65, 12, 15, 235, 64, 12, + 15, 235, 63, 12, 15, 235, 62, 12, 15, 235, 61, 12, 15, 235, 60, 12, 15, + 235, 59, 12, 15, 235, 58, 12, 15, 235, 57, 12, 15, 235, 56, 12, 15, 235, + 55, 12, 15, 235, 54, 12, 15, 235, 53, 12, 15, 235, 52, 12, 15, 235, 51, + 12, 15, 235, 50, 12, 15, 235, 49, 12, 15, 235, 48, 12, 15, 235, 47, 12, + 15, 235, 46, 12, 15, 235, 45, 12, 15, 235, 44, 12, 15, 235, 43, 12, 15, + 235, 42, 12, 15, 235, 41, 12, 15, 235, 40, 12, 15, 235, 39, 12, 15, 235, + 38, 12, 15, 235, 37, 12, 15, 235, 36, 12, 15, 235, 35, 12, 15, 235, 34, + 12, 15, 235, 33, 12, 15, 235, 32, 12, 15, 235, 31, 12, 15, 235, 30, 12, + 15, 235, 29, 12, 15, 235, 28, 12, 15, 235, 27, 12, 15, 235, 26, 12, 15, + 235, 25, 12, 15, 235, 24, 12, 15, 235, 23, 12, 15, 235, 22, 12, 15, 235, + 21, 12, 15, 235, 20, 12, 15, 235, 19, 12, 15, 235, 18, 12, 15, 235, 17, + 12, 15, 235, 16, 12, 15, 235, 15, 12, 15, 235, 14, 12, 15, 235, 13, 12, + 15, 235, 12, 12, 15, 235, 11, 12, 15, 235, 10, 12, 15, 235, 9, 12, 15, + 235, 8, 12, 15, 235, 7, 12, 15, 235, 6, 12, 15, 235, 5, 12, 15, 235, 4, + 12, 15, 235, 3, 12, 15, 235, 2, 12, 15, 235, 1, 12, 15, 235, 0, 12, 15, + 234, 255, 12, 15, 234, 254, 12, 15, 234, 253, 12, 15, 234, 252, 12, 15, + 234, 251, 12, 15, 234, 250, 12, 15, 234, 249, 12, 15, 234, 248, 12, 15, + 234, 247, 12, 15, 234, 246, 12, 15, 234, 245, 12, 15, 234, 244, 12, 15, + 234, 243, 12, 15, 234, 242, 12, 15, 234, 241, 12, 15, 234, 240, 12, 15, + 234, 239, 12, 15, 234, 238, 12, 15, 234, 237, 12, 15, 234, 236, 12, 15, + 234, 235, 12, 15, 234, 234, 12, 15, 234, 233, 12, 15, 234, 232, 12, 15, + 234, 231, 12, 15, 234, 230, 12, 15, 234, 229, 12, 15, 234, 228, 12, 15, + 234, 227, 12, 15, 234, 226, 12, 15, 234, 225, 12, 15, 234, 224, 12, 15, + 234, 223, 12, 15, 234, 222, 12, 15, 234, 221, 12, 15, 234, 220, 12, 15, + 234, 219, 12, 15, 234, 218, 12, 15, 234, 217, 12, 15, 234, 216, 12, 15, + 234, 215, 12, 15, 234, 214, 12, 15, 234, 213, 12, 15, 234, 212, 12, 15, + 234, 211, 12, 15, 234, 210, 12, 15, 234, 209, 12, 15, 234, 208, 12, 15, + 234, 207, 12, 15, 234, 206, 12, 15, 234, 205, 12, 15, 234, 204, 12, 15, + 234, 203, 12, 15, 234, 202, 12, 15, 234, 201, 12, 15, 234, 200, 12, 15, + 234, 199, 12, 15, 234, 198, 12, 15, 234, 197, 12, 15, 234, 196, 12, 15, + 234, 195, 12, 15, 234, 194, 12, 15, 234, 193, 12, 15, 234, 192, 12, 15, + 234, 191, 12, 15, 234, 190, 12, 15, 234, 189, 12, 15, 234, 188, 12, 15, + 234, 187, 12, 15, 234, 186, 12, 15, 234, 185, 12, 15, 234, 184, 12, 15, + 234, 183, 12, 15, 234, 182, 12, 15, 234, 181, 12, 15, 234, 180, 12, 15, + 234, 179, 12, 15, 234, 178, 12, 15, 234, 177, 12, 15, 234, 176, 12, 15, + 234, 175, 12, 15, 234, 174, 12, 15, 234, 173, 12, 15, 234, 172, 12, 15, + 234, 171, 12, 15, 234, 170, 12, 15, 234, 169, 12, 15, 234, 168, 12, 15, + 234, 167, 12, 15, 234, 166, 12, 15, 234, 165, 12, 15, 234, 164, 12, 15, + 234, 163, 12, 15, 234, 162, 12, 15, 234, 161, 12, 15, 234, 160, 12, 15, + 234, 159, 12, 15, 234, 158, 12, 15, 234, 157, 12, 15, 234, 156, 12, 15, + 234, 155, 12, 15, 234, 154, 12, 15, 234, 153, 12, 15, 234, 152, 12, 15, + 234, 151, 12, 15, 234, 150, 12, 15, 234, 149, 12, 15, 234, 148, 12, 15, + 234, 147, 12, 15, 234, 146, 12, 15, 234, 145, 12, 15, 234, 144, 12, 15, + 234, 143, 12, 15, 234, 142, 12, 15, 234, 141, 12, 15, 234, 140, 12, 15, + 234, 139, 12, 15, 234, 138, 12, 15, 234, 137, 12, 15, 234, 136, 12, 15, + 234, 135, 12, 15, 234, 134, 12, 15, 234, 133, 12, 15, 234, 132, 12, 15, + 234, 131, 12, 15, 234, 130, 12, 15, 234, 129, 12, 15, 234, 128, 12, 15, + 234, 127, 12, 15, 234, 126, 12, 15, 234, 125, 12, 15, 234, 124, 12, 15, + 234, 123, 12, 15, 234, 122, 12, 15, 234, 121, 12, 15, 234, 120, 12, 15, + 234, 119, 12, 15, 234, 118, 12, 15, 234, 117, 12, 15, 234, 116, 12, 15, + 234, 115, 12, 15, 234, 114, 12, 15, 234, 113, 12, 15, 234, 112, 12, 15, + 234, 111, 12, 15, 234, 110, 12, 15, 234, 109, 12, 15, 234, 108, 12, 15, + 234, 107, 12, 15, 234, 106, 12, 15, 234, 105, 12, 15, 234, 104, 12, 15, + 234, 103, 12, 15, 234, 102, 12, 15, 234, 101, 12, 15, 234, 100, 12, 15, + 234, 99, 12, 15, 234, 98, 12, 15, 234, 97, 12, 15, 234, 96, 12, 15, 234, + 95, 12, 15, 234, 94, 12, 15, 234, 93, 12, 15, 234, 92, 12, 15, 234, 91, + 12, 15, 234, 90, 12, 15, 234, 89, 12, 15, 234, 88, 12, 15, 234, 87, 12, + 15, 234, 86, 12, 15, 234, 85, 12, 15, 234, 84, 12, 15, 234, 83, 12, 15, + 234, 82, 12, 15, 234, 81, 12, 15, 234, 80, 12, 15, 234, 79, 12, 15, 234, + 78, 12, 15, 234, 77, 12, 15, 234, 76, 12, 15, 234, 75, 12, 15, 234, 74, + 12, 15, 234, 73, 12, 15, 234, 72, 12, 15, 234, 71, 12, 15, 234, 70, 12, + 15, 234, 69, 12, 15, 234, 68, 12, 15, 234, 67, 12, 15, 234, 66, 12, 15, + 234, 65, 12, 15, 234, 64, 12, 15, 234, 63, 12, 15, 234, 62, 12, 15, 234, + 61, 12, 15, 234, 60, 12, 15, 234, 59, 12, 15, 234, 58, 12, 15, 234, 57, + 12, 15, 234, 56, 12, 15, 234, 55, 12, 15, 234, 54, 12, 15, 234, 53, 12, + 15, 234, 52, 12, 15, 234, 51, 12, 15, 234, 50, 12, 15, 234, 49, 12, 15, + 234, 48, 12, 15, 234, 47, 12, 15, 234, 46, 12, 15, 234, 45, 12, 15, 234, + 44, 12, 15, 234, 43, 12, 15, 234, 42, 12, 15, 234, 41, 12, 15, 234, 40, + 12, 15, 234, 39, 12, 15, 234, 38, 12, 15, 234, 37, 12, 15, 234, 36, 12, + 15, 234, 35, 12, 15, 234, 34, 12, 15, 234, 33, 12, 15, 234, 32, 12, 15, + 234, 31, 12, 15, 234, 30, 12, 15, 234, 29, 12, 15, 234, 28, 12, 15, 234, + 27, 12, 15, 234, 26, 12, 15, 234, 25, 12, 15, 234, 24, 12, 15, 234, 23, + 12, 15, 234, 22, 12, 15, 234, 21, 12, 15, 234, 20, 12, 15, 234, 19, 12, + 15, 234, 18, 12, 15, 234, 17, 12, 15, 234, 16, 12, 15, 234, 15, 12, 15, + 234, 14, 12, 15, 234, 13, 12, 15, 234, 12, 12, 15, 234, 11, 12, 15, 234, + 10, 12, 15, 234, 9, 12, 15, 234, 8, 12, 15, 234, 7, 12, 15, 234, 6, 12, + 15, 234, 5, 12, 15, 234, 4, 12, 15, 234, 3, 12, 15, 234, 2, 12, 15, 234, + 1, 12, 15, 234, 0, 12, 15, 233, 255, 12, 15, 233, 254, 12, 15, 233, 253, + 12, 15, 233, 252, 12, 15, 233, 251, 12, 15, 233, 250, 12, 15, 233, 249, + 12, 15, 233, 248, 12, 15, 233, 247, 12, 15, 233, 246, 12, 15, 233, 245, + 12, 15, 233, 244, 12, 15, 233, 243, 12, 15, 233, 242, 12, 15, 233, 241, + 12, 15, 233, 240, 12, 15, 233, 239, 12, 15, 233, 238, 12, 15, 233, 237, + 12, 15, 233, 236, 12, 15, 233, 235, 12, 15, 233, 234, 12, 15, 233, 233, + 12, 15, 233, 232, 12, 15, 233, 231, 12, 15, 233, 230, 12, 15, 233, 229, + 12, 15, 233, 228, 12, 15, 233, 227, 12, 15, 233, 226, 12, 15, 233, 225, + 12, 15, 233, 224, 12, 15, 233, 223, 12, 15, 233, 222, 12, 15, 233, 221, + 12, 15, 233, 220, 12, 15, 233, 219, 12, 15, 233, 218, 12, 15, 233, 217, + 12, 15, 233, 216, 12, 15, 233, 215, 12, 15, 233, 214, 12, 15, 233, 213, + 12, 15, 233, 212, 12, 15, 233, 211, 12, 15, 233, 210, 12, 15, 233, 209, + 12, 15, 233, 208, 12, 15, 233, 207, 12, 15, 233, 206, 12, 15, 233, 205, + 12, 15, 233, 204, 12, 15, 233, 203, 12, 15, 233, 202, 12, 15, 233, 201, + 12, 15, 233, 200, 12, 15, 233, 199, 12, 15, 233, 198, 12, 15, 233, 197, + 12, 15, 233, 196, 12, 15, 233, 195, 12, 15, 233, 194, 12, 15, 233, 193, + 12, 15, 233, 192, 12, 15, 233, 191, 12, 15, 233, 190, 12, 15, 233, 189, + 12, 15, 233, 188, 12, 15, 233, 187, 12, 15, 233, 186, 12, 15, 233, 185, + 12, 15, 233, 184, 12, 15, 233, 183, 12, 15, 233, 182, 12, 15, 233, 181, + 12, 15, 233, 180, 12, 15, 233, 179, 12, 15, 233, 178, 12, 15, 233, 177, + 12, 15, 233, 176, 12, 15, 233, 175, 12, 15, 233, 174, 12, 15, 233, 173, + 12, 15, 233, 172, 12, 15, 233, 171, 12, 15, 233, 170, 12, 15, 233, 169, + 12, 15, 233, 168, 12, 15, 233, 167, 12, 15, 233, 166, 12, 15, 233, 165, + 12, 15, 233, 164, 12, 15, 233, 163, 12, 15, 233, 162, 12, 15, 233, 161, + 12, 15, 233, 160, 12, 15, 233, 159, 12, 15, 233, 158, 12, 15, 233, 157, + 12, 15, 233, 156, 12, 15, 233, 155, 12, 15, 233, 154, 12, 15, 233, 153, + 12, 15, 233, 152, 12, 15, 233, 151, 12, 15, 233, 150, 12, 15, 233, 149, + 12, 15, 233, 148, 12, 15, 233, 147, 12, 15, 233, 146, 12, 15, 233, 145, + 12, 15, 233, 144, 12, 15, 233, 143, 12, 15, 233, 142, 12, 15, 233, 141, + 12, 15, 233, 140, 12, 15, 233, 139, 12, 15, 233, 138, 12, 15, 233, 137, + 12, 15, 233, 136, 12, 15, 233, 135, 12, 15, 233, 134, 12, 15, 233, 133, + 12, 15, 233, 132, 12, 15, 233, 131, 12, 15, 233, 130, 12, 15, 233, 129, + 12, 15, 233, 128, 12, 15, 233, 127, 12, 15, 233, 126, 12, 15, 233, 125, + 12, 15, 233, 124, 12, 15, 233, 123, 228, 14, 209, 255, 160, 211, 228, + 160, 240, 212, 82, 160, 217, 31, 82, 160, 42, 54, 160, 243, 97, 54, 160, + 218, 246, 54, 160, 250, 235, 160, 250, 160, 160, 49, 219, 76, 160, 50, + 219, 76, 160, 250, 59, 160, 91, 54, 160, 245, 233, 160, 235, 219, 160, + 239, 102, 211, 61, 160, 212, 0, 160, 17, 202, 84, 160, 17, 105, 160, 17, + 108, 160, 17, 147, 160, 17, 149, 160, 17, 170, 160, 17, 195, 160, 17, + 213, 111, 160, 17, 199, 160, 17, 222, 63, 160, 245, 242, 160, 213, 143, + 160, 227, 179, 54, 160, 241, 35, 54, 160, 237, 247, 54, 160, 217, 47, 82, + 160, 245, 231, 250, 49, 160, 8, 6, 1, 63, 160, 8, 6, 1, 249, 255, 160, 8, + 6, 1, 247, 125, 160, 8, 6, 1, 245, 51, 160, 8, 6, 1, 74, 160, 8, 6, 1, + 240, 174, 160, 8, 6, 1, 239, 75, 160, 8, 6, 1, 237, 171, 160, 8, 6, 1, + 75, 160, 8, 6, 1, 230, 184, 160, 8, 6, 1, 230, 54, 160, 8, 6, 1, 159, + 160, 8, 6, 1, 226, 185, 160, 8, 6, 1, 223, 163, 160, 8, 6, 1, 78, 160, 8, + 6, 1, 219, 184, 160, 8, 6, 1, 217, 134, 160, 8, 6, 1, 146, 160, 8, 6, 1, + 194, 160, 8, 6, 1, 210, 69, 160, 8, 6, 1, 68, 160, 8, 6, 1, 206, 164, + 160, 8, 6, 1, 204, 144, 160, 8, 6, 1, 203, 196, 160, 8, 6, 1, 203, 124, + 160, 8, 6, 1, 202, 159, 160, 49, 51, 155, 160, 216, 74, 212, 0, 160, 50, + 51, 155, 160, 246, 53, 251, 138, 160, 124, 227, 114, 160, 237, 254, 251, + 138, 160, 8, 5, 1, 63, 160, 8, 5, 1, 249, 255, 160, 8, 5, 1, 247, 125, + 160, 8, 5, 1, 245, 51, 160, 8, 5, 1, 74, 160, 8, 5, 1, 240, 174, 160, 8, + 5, 1, 239, 75, 160, 8, 5, 1, 237, 171, 160, 8, 5, 1, 75, 160, 8, 5, 1, + 230, 184, 160, 8, 5, 1, 230, 54, 160, 8, 5, 1, 159, 160, 8, 5, 1, 226, + 185, 160, 8, 5, 1, 223, 163, 160, 8, 5, 1, 78, 160, 8, 5, 1, 219, 184, + 160, 8, 5, 1, 217, 134, 160, 8, 5, 1, 146, 160, 8, 5, 1, 194, 160, 8, 5, + 1, 210, 69, 160, 8, 5, 1, 68, 160, 8, 5, 1, 206, 164, 160, 8, 5, 1, 204, + 144, 160, 8, 5, 1, 203, 196, 160, 8, 5, 1, 203, 124, 160, 8, 5, 1, 202, + 159, 160, 49, 245, 93, 155, 160, 80, 227, 114, 160, 50, 245, 93, 155, + 160, 208, 227, 247, 60, 209, 255, 57, 214, 71, 57, 214, 60, 57, 214, 49, + 57, 214, 37, 57, 214, 26, 57, 214, 15, 57, 214, 4, 57, 213, 249, 57, 213, + 238, 57, 213, 230, 57, 213, 229, 57, 213, 228, 57, 213, 227, 57, 213, + 225, 57, 213, 224, 57, 213, 223, 57, 213, 222, 57, 213, 221, 57, 213, + 220, 57, 213, 219, 57, 213, 218, 57, 213, 217, 57, 213, 216, 57, 213, + 214, 57, 213, 213, 57, 213, 212, 57, 213, 211, 57, 213, 210, 57, 213, + 209, 57, 213, 208, 57, 213, 207, 57, 213, 206, 57, 213, 205, 57, 213, + 203, 57, 213, 202, 57, 213, 201, 57, 213, 200, 57, 213, 199, 57, 213, + 198, 57, 213, 197, 57, 213, 196, 57, 213, 195, 57, 213, 194, 57, 213, + 192, 57, 213, 191, 57, 213, 190, 57, 213, 189, 57, 213, 188, 57, 213, + 187, 57, 213, 186, 57, 213, 185, 57, 213, 184, 57, 213, 183, 57, 213, + 181, 57, 213, 180, 57, 213, 179, 57, 213, 178, 57, 213, 177, 57, 213, + 176, 57, 213, 175, 57, 213, 174, 57, 213, 173, 57, 213, 172, 57, 213, + 170, 57, 213, 169, 57, 213, 168, 57, 213, 167, 57, 213, 166, 57, 213, + 165, 57, 213, 164, 57, 213, 163, 57, 213, 162, 57, 213, 161, 57, 213, + 159, 57, 213, 158, 57, 213, 157, 57, 213, 156, 57, 213, 155, 57, 213, + 154, 57, 213, 153, 57, 213, 152, 57, 213, 151, 57, 213, 150, 57, 214, + 147, 57, 214, 146, 57, 214, 145, 57, 214, 144, 57, 214, 143, 57, 214, + 142, 57, 214, 141, 57, 214, 140, 57, 214, 139, 57, 214, 138, 57, 214, + 136, 57, 214, 135, 57, 214, 134, 57, 214, 133, 57, 214, 132, 57, 214, + 131, 57, 214, 130, 57, 214, 129, 57, 214, 128, 57, 214, 127, 57, 214, + 125, 57, 214, 124, 57, 214, 123, 57, 214, 122, 57, 214, 121, 57, 214, + 120, 57, 214, 119, 57, 214, 118, 57, 214, 117, 57, 214, 116, 57, 214, + 114, 57, 214, 113, 57, 214, 112, 57, 214, 111, 57, 214, 110, 57, 214, + 109, 57, 214, 108, 57, 214, 107, 57, 214, 106, 57, 214, 105, 57, 214, + 103, 57, 214, 102, 57, 214, 101, 57, 214, 100, 57, 214, 99, 57, 214, 98, + 57, 214, 97, 57, 214, 96, 57, 214, 95, 57, 214, 94, 57, 214, 92, 57, 214, + 91, 57, 214, 90, 57, 214, 89, 57, 214, 88, 57, 214, 87, 57, 214, 86, 57, + 214, 85, 57, 214, 84, 57, 214, 83, 57, 214, 81, 57, 214, 80, 57, 214, 79, + 57, 214, 78, 57, 214, 77, 57, 214, 76, 57, 214, 75, 57, 214, 74, 57, 214, + 73, 57, 214, 72, 57, 214, 70, 57, 214, 69, 57, 214, 68, 57, 214, 67, 57, + 214, 66, 57, 214, 65, 57, 214, 64, 57, 214, 63, 57, 214, 62, 57, 214, 61, + 57, 214, 59, 57, 214, 58, 57, 214, 57, 57, 214, 56, 57, 214, 55, 57, 214, + 54, 57, 214, 53, 57, 214, 52, 57, 214, 51, 57, 214, 50, 57, 214, 48, 57, + 214, 47, 57, 214, 46, 57, 214, 45, 57, 214, 44, 57, 214, 43, 57, 214, 42, + 57, 214, 41, 57, 214, 40, 57, 214, 39, 57, 214, 36, 57, 214, 35, 57, 214, + 34, 57, 214, 33, 57, 214, 32, 57, 214, 31, 57, 214, 30, 57, 214, 29, 57, + 214, 28, 57, 214, 27, 57, 214, 25, 57, 214, 24, 57, 214, 23, 57, 214, 22, + 57, 214, 21, 57, 214, 20, 57, 214, 19, 57, 214, 18, 57, 214, 17, 57, 214, + 16, 57, 214, 14, 57, 214, 13, 57, 214, 12, 57, 214, 11, 57, 214, 10, 57, + 214, 9, 57, 214, 8, 57, 214, 7, 57, 214, 6, 57, 214, 5, 57, 214, 3, 57, + 214, 2, 57, 214, 1, 57, 214, 0, 57, 213, 255, 57, 213, 254, 57, 213, 253, + 57, 213, 252, 57, 213, 251, 57, 213, 250, 57, 213, 248, 57, 213, 247, 57, + 213, 246, 57, 213, 245, 57, 213, 244, 57, 213, 243, 57, 213, 242, 57, + 213, 241, 57, 213, 240, 57, 213, 239, 57, 213, 237, 57, 213, 236, 57, + 213, 235, 57, 213, 234, 57, 213, 233, 57, 213, 232, 57, 213, 231, 221, + 48, 221, 50, 211, 90, 76, 237, 61, 212, 3, 211, 90, 76, 209, 112, 211, + 12, 241, 84, 76, 209, 112, 240, 240, 241, 84, 76, 208, 105, 241, 47, 241, + 71, 241, 72, 251, 130, 251, 131, 251, 27, 248, 131, 249, 19, 247, 199, + 167, 210, 5, 236, 106, 210, 5, 236, 31, 210, 10, 227, 115, 240, 51, 222, + 214, 227, 114, 241, 84, 76, 227, 114, 227, 163, 221, 253, 241, 50, 227, + 115, 210, 5, 80, 210, 5, 204, 165, 239, 159, 240, 51, 240, 30, 247, 25, + 216, 77, 245, 147, 213, 7, 219, 211, 227, 41, 105, 212, 13, 213, 7, 231, + 49, 227, 41, 202, 84, 212, 162, 244, 139, 227, 105, 241, 9, 243, 123, + 244, 8, 245, 184, 105, 244, 128, 244, 8, 245, 184, 108, 244, 127, 244, 8, + 245, 184, 147, 244, 126, 244, 8, 245, 184, 149, 244, 125, 182, 251, 130, + 223, 89, 210, 95, 231, 112, 210, 99, 241, 84, 76, 208, 106, 248, 33, 240, + 247, 247, 59, 247, 61, 241, 84, 76, 225, 9, 241, 48, 210, 242, 211, 3, + 241, 9, 241, 10, 231, 25, 213, 131, 149, 240, 11, 213, 130, 239, 112, + 231, 25, 213, 131, 147, 237, 238, 213, 130, 237, 235, 231, 25, 213, 131, + 108, 216, 149, 213, 130, 215, 150, 231, 25, 213, 131, 105, 206, 236, 213, + 130, 206, 193, 211, 231, 244, 46, 244, 48, 219, 157, 246, 182, 219, 159, + 138, 220, 80, 217, 240, 236, 109, 247, 218, 218, 236, 237, 27, 247, 230, + 221, 192, 247, 218, 237, 27, 223, 53, 231, 35, 231, 37, 222, 208, 227, + 114, 222, 231, 211, 90, 76, 214, 152, 250, 120, 211, 164, 241, 84, 76, + 214, 152, 250, 120, 241, 12, 167, 210, 6, 213, 117, 236, 106, 210, 6, + 213, 117, 236, 28, 167, 210, 6, 3, 230, 66, 236, 106, 210, 6, 3, 230, 66, + 236, 29, 227, 115, 210, 6, 213, 117, 80, 210, 6, 213, 117, 204, 164, 219, + 69, 227, 115, 239, 151, 219, 69, 227, 115, 242, 70, 218, 87, 219, 69, + 227, 115, 249, 18, 219, 69, 227, 115, 206, 224, 218, 82, 216, 74, 227, + 115, 240, 51, 216, 74, 231, 35, 216, 57, 212, 120, 213, 7, 108, 212, 117, + 211, 166, 212, 120, 213, 7, 147, 212, 116, 211, 165, 244, 8, 245, 184, + 211, 34, 244, 123, 217, 227, 206, 192, 105, 217, 227, 206, 190, 217, 190, + 217, 227, 206, 192, 108, 217, 227, 206, 189, 217, 189, 213, 118, 208, + 104, 211, 89, 211, 17, 247, 60, 246, 182, 247, 1, 224, 224, 204, 103, + 223, 181, 211, 90, 76, 237, 223, 250, 120, 211, 90, 76, 217, 208, 250, + 120, 211, 230, 241, 84, 76, 237, 223, 250, 120, 241, 84, 76, 217, 208, + 250, 120, 241, 45, 211, 90, 76, 211, 34, 211, 245, 212, 120, 238, 3, 167, + 230, 241, 213, 95, 212, 120, 167, 230, 241, 214, 191, 245, 184, 213, 127, + 230, 241, 245, 111, 211, 35, 209, 138, 211, 108, 220, 0, 210, 84, 245, + 232, 219, 226, 217, 228, 224, 223, 218, 72, 250, 156, 217, 222, 245, 232, + 250, 172, 223, 41, 212, 171, 8, 6, 1, 238, 119, 8, 5, 1, 238, 119, 246, + 201, 251, 8, 210, 89, 210, 248, 245, 243, 212, 68, 227, 222, 200, 1, 227, + 68, 228, 12, 1, 239, 187, 239, 178, 228, 12, 1, 239, 187, 240, 63, 228, + 12, 1, 215, 227, 228, 12, 1, 227, 49, 77, 131, 248, 45, 212, 238, 238, + 82, 224, 173, 216, 64, 239, 89, 239, 88, 239, 87, 223, 183, 201, 243, + 201, 244, 201, 246, 226, 243, 215, 235, 226, 245, 215, 237, 219, 37, 226, + 242, 215, 234, 221, 223, 224, 86, 204, 2, 226, 244, 215, 236, 239, 111, + 219, 36, 204, 52, 241, 107, 239, 99, 224, 154, 220, 32, 206, 194, 97, + 224, 154, 244, 145, 97, 96, 208, 84, 53, 3, 52, 80, 95, 86, 208, 84, 53, + 3, 52, 80, 95, 11, 4, 230, 199, 82, 217, 241, 239, 159, 35, 80, 50, 61, + 227, 185, 155, 205, 165, 205, 54, 204, 242, 204, 231, 204, 220, 204, 209, + 204, 198, 204, 187, 204, 176, 205, 164, 205, 153, 205, 142, 205, 131, + 205, 120, 205, 109, 205, 98, 247, 130, 219, 241, 82, 248, 13, 201, 245, + 9, 2, 221, 57, 209, 141, 9, 2, 221, 57, 115, 221, 57, 247, 161, 115, 247, + 160, 60, 31, 16, 239, 110, 212, 64, 246, 102, 206, 65, 205, 87, 205, 76, + 205, 65, 205, 53, 205, 42, 205, 31, 205, 20, 205, 9, 204, 254, 204, 246, + 204, 245, 204, 244, 204, 243, 204, 241, 204, 240, 204, 239, 204, 238, + 204, 237, 204, 236, 204, 235, 204, 234, 204, 233, 204, 232, 204, 230, + 204, 229, 204, 228, 204, 227, 204, 226, 204, 225, 204, 224, 204, 223, + 204, 222, 204, 221, 204, 219, 204, 218, 204, 217, 204, 216, 204, 215, + 204, 214, 204, 213, 204, 212, 204, 211, 204, 210, 204, 208, 204, 207, + 204, 206, 204, 205, 204, 204, 204, 203, 204, 202, 204, 201, 204, 200, + 204, 199, 204, 197, 204, 196, 204, 195, 204, 194, 204, 193, 204, 192, + 204, 191, 204, 190, 204, 189, 204, 188, 204, 186, 204, 185, 204, 184, + 204, 183, 204, 182, 204, 181, 204, 180, 204, 179, 204, 178, 204, 177, + 204, 175, 204, 174, 204, 173, 204, 172, 204, 171, 204, 170, 204, 169, + 204, 168, 204, 167, 204, 166, 205, 163, 205, 162, 205, 161, 205, 160, + 205, 159, 205, 158, 205, 157, 205, 156, 205, 155, 205, 154, 205, 152, + 205, 151, 205, 150, 205, 149, 205, 148, 205, 147, 205, 146, 205, 145, + 205, 144, 205, 143, 205, 141, 205, 140, 205, 139, 205, 138, 205, 137, + 205, 136, 205, 135, 205, 134, 205, 133, 205, 132, 205, 130, 205, 129, + 205, 128, 205, 127, 205, 126, 205, 125, 205, 124, 205, 123, 205, 122, + 205, 121, 205, 119, 205, 118, 205, 117, 205, 116, 205, 115, 205, 114, + 205, 113, 205, 112, 205, 111, 205, 110, 205, 108, 205, 107, 205, 106, + 205, 105, 205, 104, 205, 103, 205, 102, 205, 101, 205, 100, 205, 99, 205, + 97, 205, 96, 205, 95, 205, 94, 205, 93, 205, 92, 205, 91, 205, 90, 205, + 89, 205, 88, 205, 86, 205, 85, 205, 84, 205, 83, 205, 82, 205, 81, 205, + 80, 205, 79, 205, 78, 205, 77, 205, 75, 205, 74, 205, 73, 205, 72, 205, + 71, 205, 70, 205, 69, 205, 68, 205, 67, 205, 66, 205, 64, 205, 63, 205, + 62, 205, 61, 205, 60, 205, 59, 205, 58, 205, 57, 205, 56, 205, 55, 205, + 52, 205, 51, 205, 50, 205, 49, 205, 48, 205, 47, 205, 46, 205, 45, 205, + 44, 205, 43, 205, 41, 205, 40, 205, 39, 205, 38, 205, 37, 205, 36, 205, + 35, 205, 34, 205, 33, 205, 32, 205, 30, 205, 29, 205, 28, 205, 27, 205, + 26, 205, 25, 205, 24, 205, 23, 205, 22, 205, 21, 205, 19, 205, 18, 205, + 17, 205, 16, 205, 15, 205, 14, 205, 13, 205, 12, 205, 11, 205, 10, 205, + 8, 205, 7, 205, 6, 205, 5, 205, 4, 205, 3, 205, 2, 205, 1, 205, 0, 204, + 255, 204, 253, 204, 252, 204, 251, 204, 250, 204, 249, 204, 248, 204, + 247, 8, 6, 1, 34, 3, 225, 171, 25, 237, 253, 8, 5, 1, 34, 3, 225, 171, + 25, 237, 253, 8, 6, 1, 188, 3, 80, 227, 115, 56, 8, 5, 1, 188, 3, 80, + 227, 115, 56, 8, 6, 1, 188, 3, 80, 227, 115, 248, 126, 25, 237, 253, 8, + 5, 1, 188, 3, 80, 227, 115, 248, 126, 25, 237, 253, 8, 6, 1, 188, 3, 80, + 227, 115, 248, 126, 25, 165, 8, 5, 1, 188, 3, 80, 227, 115, 248, 126, 25, + 165, 8, 6, 1, 188, 3, 246, 53, 25, 225, 170, 8, 5, 1, 188, 3, 246, 53, + 25, 225, 170, 8, 6, 1, 188, 3, 246, 53, 25, 247, 29, 8, 5, 1, 188, 3, + 246, 53, 25, 247, 29, 8, 6, 1, 235, 206, 3, 225, 171, 25, 237, 253, 8, 5, + 1, 235, 206, 3, 225, 171, 25, 237, 253, 8, 5, 1, 235, 206, 3, 70, 87, 25, + 165, 8, 5, 1, 222, 206, 3, 208, 228, 55, 8, 6, 1, 158, 3, 80, 227, 115, + 56, 8, 5, 1, 158, 3, 80, 227, 115, 56, 8, 6, 1, 158, 3, 80, 227, 115, + 248, 126, 25, 237, 253, 8, 5, 1, 158, 3, 80, 227, 115, 248, 126, 25, 237, + 253, 8, 6, 1, 158, 3, 80, 227, 115, 248, 126, 25, 165, 8, 5, 1, 158, 3, + 80, 227, 115, 248, 126, 25, 165, 8, 6, 1, 215, 94, 3, 80, 227, 115, 56, + 8, 5, 1, 215, 94, 3, 80, 227, 115, 56, 8, 6, 1, 106, 3, 225, 171, 25, + 237, 253, 8, 5, 1, 106, 3, 225, 171, 25, 237, 253, 8, 6, 1, 34, 3, 220, + 63, 25, 165, 8, 5, 1, 34, 3, 220, 63, 25, 165, 8, 6, 1, 34, 3, 220, 63, + 25, 208, 227, 8, 5, 1, 34, 3, 220, 63, 25, 208, 227, 8, 6, 1, 188, 3, + 220, 63, 25, 165, 8, 5, 1, 188, 3, 220, 63, 25, 165, 8, 6, 1, 188, 3, + 220, 63, 25, 208, 227, 8, 5, 1, 188, 3, 220, 63, 25, 208, 227, 8, 6, 1, + 188, 3, 70, 87, 25, 165, 8, 5, 1, 188, 3, 70, 87, 25, 165, 8, 6, 1, 188, + 3, 70, 87, 25, 208, 227, 8, 5, 1, 188, 3, 70, 87, 25, 208, 227, 8, 5, 1, + 235, 206, 3, 70, 87, 25, 237, 253, 8, 5, 1, 235, 206, 3, 70, 87, 25, 208, + 227, 8, 6, 1, 235, 206, 3, 220, 63, 25, 165, 8, 5, 1, 235, 206, 3, 220, + 63, 25, 70, 87, 25, 165, 8, 6, 1, 235, 206, 3, 220, 63, 25, 208, 227, 8, + 5, 1, 235, 206, 3, 220, 63, 25, 70, 87, 25, 208, 227, 8, 6, 1, 230, 185, + 3, 208, 227, 8, 5, 1, 230, 185, 3, 70, 87, 25, 208, 227, 8, 6, 1, 228, + 131, 3, 208, 227, 8, 5, 1, 228, 131, 3, 208, 227, 8, 6, 1, 226, 186, 3, + 208, 227, 8, 5, 1, 226, 186, 3, 208, 227, 8, 6, 1, 217, 1, 3, 208, 227, + 8, 5, 1, 217, 1, 3, 208, 227, 8, 6, 1, 106, 3, 220, 63, 25, 165, 8, 5, 1, + 106, 3, 220, 63, 25, 165, 8, 6, 1, 106, 3, 220, 63, 25, 208, 227, 8, 5, + 1, 106, 3, 220, 63, 25, 208, 227, 8, 6, 1, 106, 3, 225, 171, 25, 165, 8, + 5, 1, 106, 3, 225, 171, 25, 165, 8, 6, 1, 106, 3, 225, 171, 25, 208, 227, + 8, 5, 1, 106, 3, 225, 171, 25, 208, 227, 8, 5, 1, 251, 110, 3, 237, 253, + 8, 5, 1, 171, 158, 3, 237, 253, 8, 5, 1, 171, 158, 3, 165, 8, 5, 1, 207, + 174, 206, 165, 3, 237, 253, 8, 5, 1, 207, 174, 206, 165, 3, 165, 8, 5, 1, + 214, 193, 3, 237, 253, 8, 5, 1, 214, 193, 3, 165, 8, 5, 1, 236, 115, 214, + 193, 3, 237, 253, 8, 5, 1, 236, 115, 214, 193, 3, 165, 10, 213, 127, 89, + 3, 237, 128, 87, 3, 251, 30, 10, 213, 127, 89, 3, 237, 128, 87, 3, 204, + 70, 10, 213, 127, 89, 3, 237, 128, 87, 3, 137, 225, 129, 10, 213, 127, + 89, 3, 237, 128, 87, 3, 220, 73, 10, 213, 127, 89, 3, 237, 128, 87, 3, + 68, 10, 213, 127, 89, 3, 237, 128, 87, 3, 202, 213, 10, 213, 127, 89, 3, + 237, 128, 87, 3, 74, 10, 213, 127, 89, 3, 237, 128, 87, 3, 251, 109, 10, + 213, 127, 221, 179, 3, 229, 189, 179, 1, 229, 119, 44, 109, 230, 54, 44, + 109, 222, 205, 44, 109, 247, 125, 44, 109, 221, 13, 44, 109, 207, 244, + 44, 109, 221, 228, 44, 109, 210, 69, 44, 109, 223, 163, 44, 109, 219, + 184, 44, 109, 226, 185, 44, 109, 203, 124, 44, 109, 146, 44, 109, 159, + 44, 109, 206, 164, 44, 109, 227, 69, 44, 109, 227, 78, 44, 109, 215, 186, + 44, 109, 221, 210, 44, 109, 230, 184, 44, 109, 213, 92, 44, 109, 211, + 167, 44, 109, 194, 44, 109, 237, 171, 44, 109, 228, 224, 44, 4, 230, 41, + 44, 4, 229, 100, 44, 4, 229, 87, 44, 4, 228, 209, 44, 4, 228, 174, 44, 4, + 229, 201, 44, 4, 229, 198, 44, 4, 230, 18, 44, 4, 229, 26, 44, 4, 229, 6, + 44, 4, 229, 219, 44, 4, 222, 202, 44, 4, 222, 151, 44, 4, 222, 147, 44, + 4, 222, 116, 44, 4, 222, 108, 44, 4, 222, 190, 44, 4, 222, 188, 44, 4, + 222, 199, 44, 4, 222, 128, 44, 4, 222, 123, 44, 4, 222, 192, 44, 4, 247, + 91, 44, 4, 246, 79, 44, 4, 246, 69, 44, 4, 245, 110, 44, 4, 245, 76, 44, + 4, 246, 238, 44, 4, 246, 230, 44, 4, 247, 80, 44, 4, 245, 254, 44, 4, + 245, 180, 44, 4, 247, 15, 44, 4, 221, 10, 44, 4, 220, 248, 44, 4, 220, + 243, 44, 4, 220, 226, 44, 4, 220, 218, 44, 4, 221, 1, 44, 4, 221, 0, 44, + 4, 221, 7, 44, 4, 220, 233, 44, 4, 220, 230, 44, 4, 221, 4, 44, 4, 207, + 240, 44, 4, 207, 220, 44, 4, 207, 219, 44, 4, 207, 208, 44, 4, 207, 205, + 44, 4, 207, 236, 44, 4, 207, 235, 44, 4, 207, 239, 44, 4, 207, 218, 44, + 4, 207, 217, 44, 4, 207, 238, 44, 4, 221, 226, 44, 4, 221, 212, 44, 4, + 221, 211, 44, 4, 221, 195, 44, 4, 221, 194, 44, 4, 221, 222, 44, 4, 221, + 221, 44, 4, 221, 225, 44, 4, 221, 197, 44, 4, 221, 196, 44, 4, 221, 224, + 44, 4, 210, 18, 44, 4, 209, 2, 44, 4, 208, 242, 44, 4, 207, 203, 44, 4, + 207, 165, 44, 4, 209, 187, 44, 4, 209, 176, 44, 4, 209, 250, 44, 4, 135, + 44, 4, 208, 148, 44, 4, 209, 207, 44, 4, 223, 106, 44, 4, 222, 100, 44, + 4, 222, 75, 44, 4, 221, 84, 44, 4, 221, 25, 44, 4, 222, 240, 44, 4, 222, + 235, 44, 4, 223, 92, 44, 4, 221, 191, 44, 4, 221, 180, 44, 4, 223, 65, + 44, 4, 219, 168, 44, 4, 218, 167, 44, 4, 218, 129, 44, 4, 217, 191, 44, + 4, 217, 157, 44, 4, 219, 34, 44, 4, 219, 23, 44, 4, 219, 148, 44, 4, 218, + 69, 44, 4, 218, 45, 44, 4, 219, 48, 44, 4, 225, 175, 44, 4, 224, 155, 44, + 4, 224, 125, 44, 4, 223, 246, 44, 4, 223, 192, 44, 4, 225, 20, 44, 4, + 225, 8, 44, 4, 225, 140, 44, 4, 224, 82, 44, 4, 224, 35, 44, 4, 225, 67, + 44, 4, 203, 110, 44, 4, 203, 11, 44, 4, 203, 2, 44, 4, 202, 213, 44, 4, + 202, 181, 44, 4, 203, 52, 44, 4, 203, 49, 44, 4, 203, 89, 44, 4, 202, + 247, 44, 4, 202, 232, 44, 4, 203, 62, 44, 4, 216, 216, 44, 4, 216, 57, + 44, 4, 216, 3, 44, 4, 215, 145, 44, 4, 215, 114, 44, 4, 216, 158, 44, 4, + 216, 135, 44, 4, 216, 197, 44, 4, 215, 227, 44, 4, 215, 208, 44, 4, 216, + 167, 44, 4, 228, 112, 44, 4, 227, 148, 44, 4, 227, 130, 44, 4, 226, 239, + 44, 4, 226, 210, 44, 4, 227, 234, 44, 4, 227, 226, 44, 4, 228, 86, 44, 4, + 227, 49, 44, 4, 227, 18, 44, 4, 227, 251, 44, 4, 206, 85, 44, 4, 205, + 230, 44, 4, 205, 215, 44, 4, 204, 163, 44, 4, 204, 156, 44, 4, 206, 55, + 44, 4, 206, 50, 44, 4, 206, 81, 44, 4, 205, 189, 44, 4, 205, 176, 44, 4, + 206, 61, 44, 4, 227, 67, 44, 4, 227, 62, 44, 4, 227, 61, 44, 4, 227, 58, + 44, 4, 227, 57, 44, 4, 227, 64, 44, 4, 227, 63, 44, 4, 227, 66, 44, 4, + 227, 60, 44, 4, 227, 59, 44, 4, 227, 65, 44, 4, 227, 76, 44, 4, 227, 71, + 44, 4, 227, 70, 44, 4, 227, 54, 44, 4, 227, 53, 44, 4, 227, 73, 44, 4, + 227, 72, 44, 4, 227, 75, 44, 4, 227, 56, 44, 4, 227, 55, 44, 4, 227, 74, + 44, 4, 215, 184, 44, 4, 215, 173, 44, 4, 215, 172, 44, 4, 215, 165, 44, + 4, 215, 158, 44, 4, 215, 180, 44, 4, 215, 179, 44, 4, 215, 183, 44, 4, + 215, 171, 44, 4, 215, 170, 44, 4, 215, 182, 44, 4, 221, 208, 44, 4, 221, + 203, 44, 4, 221, 202, 44, 4, 221, 199, 44, 4, 221, 198, 44, 4, 221, 205, + 44, 4, 221, 204, 44, 4, 221, 207, 44, 4, 221, 201, 44, 4, 221, 200, 44, + 4, 221, 206, 44, 4, 230, 180, 44, 4, 230, 141, 44, 4, 230, 134, 44, 4, + 230, 82, 44, 4, 230, 64, 44, 4, 230, 161, 44, 4, 230, 159, 44, 4, 230, + 174, 44, 4, 230, 101, 44, 4, 230, 91, 44, 4, 230, 167, 44, 4, 213, 85, + 44, 4, 213, 11, 44, 4, 213, 6, 44, 4, 212, 199, 44, 4, 212, 182, 44, 4, + 213, 43, 44, 4, 213, 41, 44, 4, 213, 74, 44, 4, 212, 242, 44, 4, 212, + 236, 44, 4, 213, 52, 44, 4, 211, 163, 44, 4, 211, 132, 44, 4, 211, 128, + 44, 4, 211, 119, 44, 4, 211, 116, 44, 4, 211, 138, 44, 4, 211, 137, 44, + 4, 211, 162, 44, 4, 211, 124, 44, 4, 211, 123, 44, 4, 211, 140, 44, 4, + 215, 33, 44, 4, 212, 162, 44, 4, 212, 142, 44, 4, 211, 10, 44, 4, 210, + 179, 44, 4, 214, 177, 44, 4, 214, 165, 44, 4, 215, 18, 44, 4, 212, 13, + 44, 4, 211, 250, 44, 4, 214, 217, 44, 4, 237, 157, 44, 4, 237, 3, 44, 4, + 236, 239, 44, 4, 236, 26, 44, 4, 236, 1, 44, 4, 237, 67, 44, 4, 237, 48, + 44, 4, 237, 147, 44, 4, 236, 136, 44, 4, 236, 117, 44, 4, 237, 76, 44, 4, + 228, 223, 44, 4, 228, 222, 44, 4, 228, 217, 44, 4, 228, 216, 44, 4, 228, + 213, 44, 4, 228, 212, 44, 4, 228, 219, 44, 4, 228, 218, 44, 4, 228, 221, + 44, 4, 228, 215, 44, 4, 228, 214, 44, 4, 228, 220, 44, 4, 212, 205, 140, + 109, 2, 203, 75, 140, 109, 2, 216, 186, 140, 109, 2, 216, 102, 114, 1, + 207, 95, 85, 109, 2, 245, 249, 173, 85, 109, 2, 245, 249, 229, 144, 85, + 109, 2, 245, 249, 229, 26, 85, 109, 2, 245, 249, 229, 115, 85, 109, 2, + 245, 249, 222, 128, 85, 109, 2, 245, 249, 247, 92, 85, 109, 2, 245, 249, + 246, 199, 85, 109, 2, 245, 249, 245, 254, 85, 109, 2, 245, 249, 246, 116, + 85, 109, 2, 245, 249, 220, 233, 85, 109, 2, 245, 249, 244, 212, 85, 109, + 2, 245, 249, 207, 229, 85, 109, 2, 245, 249, 243, 113, 85, 109, 2, 245, + 249, 207, 224, 85, 109, 2, 245, 249, 201, 201, 85, 109, 2, 245, 249, 210, + 22, 85, 109, 2, 245, 249, 209, 108, 85, 109, 2, 245, 249, 135, 85, 109, + 2, 245, 249, 209, 47, 85, 109, 2, 245, 249, 221, 191, 85, 109, 2, 245, + 249, 249, 32, 85, 109, 2, 245, 249, 218, 208, 85, 109, 2, 245, 249, 218, + 69, 85, 109, 2, 245, 249, 218, 180, 85, 109, 2, 245, 249, 224, 82, 85, + 109, 2, 245, 249, 202, 247, 85, 109, 2, 245, 249, 215, 227, 85, 109, 2, + 245, 249, 227, 49, 85, 109, 2, 245, 249, 205, 189, 85, 109, 2, 245, 249, + 213, 90, 85, 109, 2, 245, 249, 211, 164, 85, 109, 2, 245, 249, 215, 36, + 85, 109, 2, 245, 249, 152, 85, 109, 2, 245, 249, 228, 113, 85, 22, 2, + 245, 249, 217, 126, 85, 231, 36, 22, 2, 245, 249, 217, 65, 85, 231, 36, + 22, 2, 245, 249, 215, 102, 85, 231, 36, 22, 2, 245, 249, 215, 95, 85, + 231, 36, 22, 2, 245, 249, 217, 106, 85, 22, 2, 220, 39, 85, 22, 2, 251, + 242, 172, 1, 248, 79, 222, 203, 172, 1, 248, 79, 222, 151, 172, 1, 248, + 79, 222, 116, 172, 1, 248, 79, 222, 190, 172, 1, 248, 79, 222, 128, 67, + 1, 248, 79, 222, 203, 67, 1, 248, 79, 222, 151, 67, 1, 248, 79, 222, 116, + 67, 1, 248, 79, 222, 190, 67, 1, 248, 79, 222, 128, 67, 1, 251, 57, 246, + 238, 67, 1, 251, 57, 207, 203, 67, 1, 251, 57, 135, 67, 1, 251, 57, 219, + 184, 65, 1, 240, 198, 240, 197, 245, 188, 143, 142, 65, 1, 240, 197, 240, + 198, 245, 188, 143, 142, }; static unsigned char phrasebook_offset1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 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, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 104, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 129, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 130, 131, - 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 87, 148, 149, 150, 151, 152, 87, 87, 87, 87, 87, 87, 153, 87, - 154, 155, 156, 87, 157, 87, 158, 87, 87, 87, 159, 87, 87, 87, 160, 161, - 162, 163, 87, 87, 87, 87, 87, 87, 87, 87, 87, 164, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 165, 166, 167, 168, - 169, 170, 171, 87, 172, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 182, - 183, 184, 185, 186, 87, 87, 87, 87, 87, 87, 87, 87, 87, 187, 188, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 189, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 190, 191, 192, 193, 194, 87, 195, - 87, 196, 197, 198, 199, 200, 201, 202, 203, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 204, 205, 87, 87, 206, 207, 208, 209, 210, 87, 211, 212, 213, 214, - 215, 216, 217, 218, 219, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 220, 221, - 222, 223, 224, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 225, 87, 226, 227, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 228, 229, 230, 231, 232, 233, 234, 235, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 53, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 66, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 52, 87, 52, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 52, 97, 52, 52, 52, 52, 52, 98, 99, 100, + 101, 102, 103, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 104, 105, 106, + 107, 108, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 109, 110, 111, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 112, 113, 114, 115, 52, 52, 52, 116, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 117, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 118, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 130, 52, 52, 52, 52, 52, 131, 52, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 142, 143, 144, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 145, 146, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 147, 148, 149, + 150, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, }; static 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, 142, - 147, 151, 156, 161, 165, 170, 175, 179, 184, 189, 194, 199, 204, 207, - 211, 214, 218, 221, 225, 229, 234, 239, 244, 248, 253, 258, 263, 267, - 272, 277, 281, 285, 290, 294, 299, 304, 308, 313, 318, 322, 327, 332, - 337, 342, 347, 351, 354, 358, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 359, 363, 368, - 371, 374, 377, 380, 383, 386, 388, 391, 397, 405, 408, 412, 415, 417, - 420, 423, 426, 429, 433, 436, 439, 443, 445, 448, 454, 462, 469, 476, - 483, 488, 495, 501, 508, 514, 521, 529, 534, 542, 549, 555, 562, 569, - 577, 584, 592, 600, 605, 612, 619, 625, 632, 638, 645, 648, 654, 661, - 667, 674, 681, 688, 693, 700, 707, 713, 720, 726, 733, 741, 746, 754, - 761, 767, 774, 781, 789, 796, 804, 812, 817, 824, 831, 837, 844, 850, - 857, 860, 866, 873, 879, 886, 893, 900, 905, 913, 920, 927, 934, 941, - 948, 955, 962, 969, 977, 985, 993, 1001, 1009, 1017, 1025, 1033, 1040, - 1047, 1054, 1061, 1068, 1075, 1082, 1089, 1096, 1103, 1110, 1117, 1125, - 1133, 1141, 1149, 1157, 1165, 1173, 1181, 1189, 1197, 1204, 1211, 1218, - 1225, 1233, 1241, 1249, 1257, 1265, 1273, 1281, 1287, 1292, 1297, 1305, - 1313, 1321, 1329, 1334, 1341, 1348, 1356, 1364, 1372, 1380, 1390, 1400, - 1407, 1414, 1421, 1428, 1436, 1444, 1452, 1460, 1471, 1476, 1481, 1488, - 1495, 1502, 1509, 1516, 1523, 1528, 1533, 1540, 1547, 1555, 1563, 1571, - 1579, 1586, 1593, 1601, 1609, 1617, 1625, 1633, 1641, 1649, 1657, 1665, - 1673, 1680, 1687, 1693, 1699, 1706, 1713, 1720, 1727, 1735, 1743, 1750, - 1757, 1764, 1771, 1779, 1787, 1795, 1803, 1811, 1818, 1825, 1833, 1841, - 1849, 1857, 1863, 1869, 1875, 1882, 1889, 1894, 1899, 1904, 1911, 1918, - 1925, 1932, 1940, 1948, 1955, 1961, 1966, 1971, 1978, 1985, 1992, 1997, - 2002, 2007, 2014, 2021, 2028, 2035, 2042, 2048, 2056, 2066, 2074, 2081, - 2088, 2093, 2098, 2105, 2112, 2116, 2121, 2126, 2131, 2139, 2148, 2155, - 2162, 2171, 2178, 2185, 2190, 2197, 2204, 2211, 2218, 2225, 2230, 2237, - 2244, 2252, 2257, 2262, 2267, 2277, 2281, 2287, 2293, 2299, 2305, 2313, - 2326, 2334, 2339, 2349, 2354, 2359, 2369, 2374, 2381, 2388, 2396, 2404, - 2411, 2418, 2425, 2432, 2442, 2452, 2461, 2470, 2480, 2490, 2500, 2510, - 2516, 2526, 2536, 2546, 2556, 2564, 2572, 2579, 2586, 2594, 2602, 2610, - 2618, 2625, 2632, 2642, 2652, 2660, 2668, 2676, 2681, 2691, 2696, 2703, - 2710, 2715, 2720, 2728, 2736, 2746, 2756, 2763, 2770, 2779, 2788, 2796, - 2804, 2813, 2822, 2830, 2838, 2847, 2856, 2865, 2874, 2884, 2894, 2902, - 2910, 2919, 2928, 2937, 2946, 2956, 2966, 2974, 2982, 2991, 3000, 3009, - 3018, 3027, 3036, 3041, 3046, 3054, 3062, 3072, 3080, 3085, 3090, 3097, - 3104, 3111, 3118, 3125, 3132, 3142, 3152, 3162, 3172, 3179, 3186, 3196, - 3206, 3214, 3222, 3230, 3238, 3246, 3253, 3260, 3267, 3273, 3280, 3287, - 3294, 3303, 3313, 3323, 3330, 3337, 3343, 3348, 3355, 3361, 3367, 3374, - 3381, 3392, 3402, 3409, 3416, 3423, 3430, 3436, 3441, 3448, 3454, 3459, - 3467, 3475, 3482, 3488, 3493, 3500, 3505, 3512, 3521, 3530, 3539, 3546, - 3552, 3558, 3563, 3570, 3577, 3584, 3591, 3598, 3603, 3608, 3617, 3625, - 3634, 3639, 3645, 3656, 3663, 3671, 3680, 3686, 3692, 3698, 3705, 3710, - 3716, 3727, 3736, 3745, 3753, 3761, 3771, 3776, 3783, 3790, 3795, 3807, - 3816, 3824, 3831, 3840, 3845, 3850, 3857, 3864, 3871, 3878, 3884, 3893, - 3901, 3906, 3914, 3920, 3928, 3936, 3942, 3948, 3954, 3961, 3969, 3975, - 3983, 3990, 3995, 4002, 4010, 4020, 4027, 4034, 4044, 4051, 4058, 4068, - 4075, 4082, 4089, 4095, 4101, 4111, 4124, 4129, 4136, 4141, 4145, 4151, - 4160, 4167, 4172, 4177, 4181, 4186, 4192, 4196, 4202, 4208, 4214, 4220, - 4228, 4233, 4238, 4243, 4248, 4254, 4256, 4261, 4265, 4271, 4277, 4283, - 4288, 4295, 4302, 4308, 4315, 4323, 4331, 4336, 4341, 4345, 4350, 4352, - 4354, 4357, 4359, 4361, 4366, 4371, 4377, 4382, 4386, 4391, 4396, 4405, - 4411, 4416, 4422, 4427, 4433, 4441, 4449, 4453, 4457, 4462, 4468, 4474, - 4480, 4486, 4491, 4499, 4508, 4517, 4521, 4527, 4534, 4541, 4548, 4555, - 4559, 4564, 4569, 4574, 4579, 4584, 4586, 4589, 4592, 4595, 4598, 4601, - 4605, 4609, 4615, 4618, 4623, 4629, 4635, 4638, 4643, 4649, 4653, 4659, - 4665, 4671, 4677, 4682, 4687, 4692, 4695, 4701, 4706, 4711, 4715, 4720, - 4726, 4732, 4735, 4739, 4743, 4747, 4750, 4753, 4758, 4762, 4769, 4773, - 4779, 4783, 4789, 4793, 4797, 4801, 4806, 4811, 4818, 4824, 4831, 4837, - 4843, 4849, 4852, 4856, 4860, 4863, 4867, 4872, 4877, 4881, 4885, 4891, - 4895, 4899, 4904, 4910, 4915, 4921, 4925, 4932, 4937, 4942, 4947, 4952, - 4958, 4961, 4965, 4970, 4975, 4984, 4990, 4995, 4999, 5004, 5008, 5013, - 5017, 5021, 5026, 5029, 5035, 5040, 5045, 5050, 5055, 5060, 5065, 5071, - 5077, 5083, 5088, 5093, 5099, 5105, 5111, 5116, 5121, 5128, 5135, 5139, - 5145, 5152, 0, 0, 5159, 5162, 5171, 5180, 5191, 0, 0, 0, 0, 0, 5195, - 5198, 5203, 5211, 5216, 5224, 5232, 0, 5240, 0, 5248, 5256, 5264, 5275, - 5280, 5285, 5290, 5295, 5300, 5305, 5310, 5315, 5320, 5325, 5330, 5335, - 5340, 5345, 5350, 5355, 0, 5360, 5365, 5370, 5375, 5380, 5385, 5390, - 5395, 5403, 5411, 5419, 5427, 5435, 5443, 5454, 5459, 5464, 5469, 5474, - 5479, 5484, 5489, 5494, 5499, 5504, 5509, 5514, 5519, 5524, 5529, 5534, - 5539, 5545, 5550, 5555, 5560, 5565, 5570, 5575, 5580, 5588, 5596, 5604, - 5612, 5620, 5625, 5629, 5633, 5640, 5650, 5660, 5664, 5668, 5672, 5678, - 5685, 5689, 5694, 5698, 5703, 5707, 5712, 5716, 5721, 5726, 5731, 5736, - 5741, 5746, 5751, 5756, 5761, 5766, 5771, 5776, 5781, 5786, 5791, 5795, - 5799, 5805, 5809, 5814, 5820, 5828, 5833, 5838, 5845, 5850, 5855, 5862, - 5871, 5880, 5891, 5899, 5904, 5909, 5914, 5921, 5926, 5932, 5937, 5942, - 5947, 5952, 5957, 5962, 5970, 5976, 5981, 5985, 5990, 5995, 6000, 6005, - 6010, 6015, 6020, 6024, 6030, 6034, 6039, 6044, 6049, 6053, 6058, 6063, - 6068, 6073, 6077, 6082, 6086, 6091, 6096, 6101, 6106, 6112, 6117, 6123, - 6127, 6132, 6136, 6140, 6145, 6150, 6155, 6160, 6165, 6170, 6175, 6179, - 6185, 6189, 6194, 6199, 6204, 6208, 6213, 6218, 6223, 6228, 6232, 6237, - 6241, 6246, 6251, 6256, 6261, 6267, 6272, 6278, 6282, 6287, 6291, 6299, - 6304, 6309, 6314, 6321, 6326, 6332, 6337, 6342, 6347, 6352, 6357, 6362, - 6370, 6376, 6381, 6386, 6391, 6396, 6401, 6407, 6413, 6420, 6427, 6436, - 6445, 6452, 6459, 6468, 6477, 6482, 6487, 6492, 6497, 6502, 6507, 6512, - 6517, 6528, 6539, 6544, 6549, 6556, 6563, 6571, 6579, 6584, 6589, 6594, - 6599, 6603, 6607, 6611, 6617, 6623, 6627, 6634, 6639, 6649, 6659, 6665, - 6671, 6679, 6687, 6695, 6703, 6710, 6717, 6726, 6735, 6743, 6751, 6759, - 6767, 6775, 6783, 6791, 6799, 6806, 6813, 6819, 6825, 6833, 6841, 6848, - 6855, 6864, 6873, 6879, 6885, 6893, 6901, 6909, 6917, 6923, 6929, 6937, - 6945, 6953, 6961, 6968, 6975, 6983, 6991, 6999, 7007, 7012, 7017, 7024, - 7031, 7041, 7051, 7055, 7063, 7071, 7078, 7085, 7093, 7101, 7108, 7115, - 7123, 7131, 7138, 7145, 7153, 7161, 7166, 7173, 7180, 7187, 7194, 7200, - 7206, 7214, 7222, 7227, 7232, 7240, 7248, 7256, 7264, 7272, 7280, 7287, - 7294, 7302, 7310, 7318, 7326, 7333, 7340, 7346, 7352, 7361, 7370, 7377, - 7384, 7391, 7398, 7405, 7412, 7419, 7426, 7434, 7442, 7450, 7458, 7466, - 7474, 7484, 7494, 7501, 7508, 7515, 7522, 7529, 7536, 7543, 7550, 7557, - 7564, 7571, 7578, 7585, 7592, 7599, 7606, 7613, 7620, 7627, 7634, 7641, - 7648, 7655, 7662, 7667, 7672, 7677, 7682, 7687, 7692, 7697, 7702, 7707, - 7712, 7718, 7724, 7733, 7742, 7751, 7760, 7768, 7776, 7784, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 7792, 7797, 7802, 7807, 7812, 7817, 7822, 7827, 7832, - 7836, 7841, 7846, 7851, 7856, 7861, 7866, 7871, 7876, 7881, 7886, 7891, - 7896, 7901, 7906, 7911, 7916, 7921, 7926, 7930, 7935, 7940, 7945, 7950, - 7955, 7960, 7965, 7970, 7975, 0, 0, 7980, 7987, 7990, 7994, 7998, 8001, - 8005, 0, 8009, 8014, 8019, 8024, 8029, 8034, 8039, 8044, 8049, 8053, - 8058, 8063, 8068, 8073, 8078, 8083, 8088, 8093, 8098, 8103, 8108, 8113, - 8118, 8123, 8128, 8133, 8138, 8143, 8147, 8152, 8157, 8162, 8167, 8172, - 8177, 8182, 8187, 8192, 8197, 0, 8204, 8209, 0, 0, 0, 0, 8212, 0, 8216, - 8221, 8226, 8231, 8238, 8245, 8250, 8255, 8260, 8265, 8270, 8275, 8280, - 8287, 8292, 8299, 8306, 8311, 8318, 8323, 8328, 8333, 8340, 8345, 8350, - 8357, 8366, 8371, 8376, 8381, 8386, 8392, 8397, 8404, 8411, 8418, 8423, - 8428, 8433, 8438, 8443, 8448, 8458, 8463, 8471, 8476, 8481, 8486, 8491, - 8498, 8505, 8512, 8518, 8524, 8531, 0, 0, 0, 0, 0, 0, 0, 0, 8538, 8542, - 8546, 8550, 8554, 8558, 8562, 8566, 8570, 8574, 8578, 8583, 8587, 8591, - 8596, 8600, 8605, 8609, 8613, 8617, 8622, 8626, 8631, 8635, 8639, 8643, - 8647, 0, 0, 0, 0, 0, 8651, 8658, 8666, 8673, 8678, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 8683, 8686, 8690, 8695, 8699, 0, 8703, 8709, 8715, 8718, - 8725, 8734, 8737, 8740, 8745, 8751, 8755, 8763, 8769, 8775, 8783, 8787, - 8792, 8803, 8808, 8812, 8816, 8820, 8823, 0, 8826, 8833, 8837, 8843, - 8847, 8854, 8860, 8867, 8873, 8879, 8883, 8887, 8893, 8897, 8901, 8905, - 8909, 8913, 8917, 8921, 8925, 8929, 8933, 8937, 8941, 8945, 8949, 8953, - 8957, 8961, 8969, 8977, 8987, 8996, 9005, 9008, 9012, 9016, 9020, 9024, - 9028, 9032, 9036, 9040, 9045, 9049, 9052, 9055, 9058, 9061, 9064, 9067, - 9070, 9073, 9077, 9080, 9083, 9088, 9093, 9099, 9102, 9109, 9118, 9123, - 9128, 9135, 9140, 9145, 9149, 9153, 9157, 9161, 9165, 9169, 9173, 9177, - 9181, 9185, 9190, 9195, 9202, 9208, 9214, 9220, 9225, 9233, 9241, 9246, - 9252, 9258, 9264, 9270, 9274, 9278, 9282, 9289, 9299, 9303, 9307, 9311, - 9317, 9325, 9329, 9333, 9340, 9344, 9348, 9352, 9359, 9366, 9378, 9382, - 9386, 9390, 9400, 9409, 9413, 9421, 9428, 9435, 9444, 9455, 9463, 9467, - 9476, 9487, 9495, 9508, 9516, 9524, 9532, 9540, 9546, 9555, 9562, 9566, - 9574, 9578, 9585, 9593, 9597, 9603, 9610, 9617, 9621, 9629, 9633, 9640, - 9644, 9652, 9656, 9664, 9672, 9679, 9687, 9695, 9702, 9708, 9712, 9719, - 9727, 9733, 9740, 9747, 9753, 9762, 9770, 9777, 9783, 9787, 9790, 9794, - 9800, 9808, 9812, 9818, 9824, 9831, 9838, 9841, 9848, 9853, 9861, 9866, - 9870, 9883, 9896, 9902, 9909, 9914, 9920, 9925, 9931, 9941, 9948, 9957, - 9967, 9973, 9978, 9983, 9987, 9991, 9996, 10001, 10007, 10015, 10023, - 10034, 10039, 10048, 10057, 10064, 10070, 10076, 10082, 10088, 10094, - 10100, 10106, 10112, 10118, 10125, 10132, 10139, 10145, 10153, 10162, - 10168, 10175, 10182, 10187, 10192, 10196, 10203, 10210, 10219, 10228, - 10231, 10236, 10241, 0, 10246, 10250, 10254, 10260, 10264, 10268, 10274, - 10278, 10286, 10290, 10294, 10298, 10302, 10306, 10312, 10316, 10322, - 10326, 10330, 10334, 10338, 10342, 10347, 10350, 10354, 10360, 10364, - 10368, 10372, 10376, 10380, 10386, 10392, 10398, 10402, 10406, 10411, - 10415, 10419, 10424, 10428, 10432, 10439, 10446, 10450, 10454, 10459, - 10463, 10467, 10470, 10475, 10478, 10481, 10486, 10491, 10495, 10499, - 10505, 10511, 10514, 0, 0, 10517, 10523, 10529, 10535, 10545, 10557, - 10569, 10586, 10598, 10609, 10617, 10624, 10635, 10650, 10661, 10667, - 10676, 10684, 10696, 10706, 10714, 10726, 10733, 10741, 10753, 10759, - 10765, 10773, 10781, 10789, 10795, 10805, 10812, 10822, 10832, 10845, - 10859, 10873, 10883, 10894, 10905, 10918, 10931, 10945, 10957, 10969, - 10982, 10995, 11007, 11020, 11029, 11037, 11042, 11047, 11052, 11057, - 11062, 11067, 11072, 11077, 11082, 11087, 11092, 11097, 11102, 11107, - 11112, 11117, 11122, 11127, 11132, 11137, 11142, 11147, 11152, 11157, - 11162, 11167, 11172, 11177, 11182, 11187, 11192, 11197, 11201, 11206, - 11211, 11216, 11221, 11226, 11230, 11234, 11238, 11242, 11246, 11250, - 11254, 11258, 11262, 11266, 11270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 11275, 11280, 11284, 11288, 11292, 11296, 11300, 11304, 11308, 11312, - 11316, 11320, 11325, 11329, 11333, 11337, 11342, 11346, 11351, 11356, - 11361, 11365, 11370, 11375, 11380, 11385, 11389, 11394, 11398, 11403, - 11408, 11412, 11417, 11424, 11428, 11433, 11437, 11441, 11446, 11450, - 11457, 11464, 11471, 11477, 11485, 11493, 11502, 11510, 11517, 11524, - 11532, 11538, 11544, 11550, 11556, 11563, 11568, 11572, 11577, 0, 0, 0, - 0, 0, 11581, 11586, 11591, 11596, 11601, 11606, 11611, 11616, 11621, - 11626, 11631, 11636, 11641, 11646, 11651, 11656, 11661, 11666, 11671, - 11676, 11681, 11686, 11691, 11696, 11701, 11706, 11711, 11719, 11726, - 11732, 11737, 11745, 11752, 11758, 11765, 11771, 11776, 11783, 11790, - 11796, 11801, 11806, 11812, 11817, 11822, 11828, 0, 0, 11833, 11839, - 11845, 11851, 11857, 11863, 11869, 11874, 11882, 11888, 11894, 11900, - 11906, 11912, 11920, 0, 11926, 11931, 11936, 11941, 11946, 11951, 11956, - 11961, 11966, 11971, 11976, 11981, 11986, 11991, 11996, 12001, 12006, - 12011, 12016, 12021, 12026, 12031, 12036, 12041, 12046, 12051, 12056, - 12061, 0, 0, 12066, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 33, 35, 39, 41, 44, 46, 48, 50, 52, 54, 56, 59, 61, 64, 66, 68, 71, 74, + 77, 80, 84, 88, 93, 98, 103, 107, 112, 117, 122, 126, 131, 136, 140, 145, + 150, 154, 159, 164, 168, 172, 177, 181, 186, 191, 196, 201, 206, 209, + 213, 216, 220, 223, 227, 231, 236, 241, 246, 250, 255, 260, 265, 269, + 274, 279, 283, 288, 293, 297, 302, 307, 311, 315, 320, 324, 329, 334, + 339, 344, 349, 353, 356, 360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 362, 366, 371, + 374, 377, 380, 383, 386, 389, 391, 394, 400, 408, 411, 415, 418, 420, + 423, 426, 429, 432, 436, 439, 442, 445, 447, 450, 456, 464, 471, 478, + 485, 490, 497, 503, 510, 517, 524, 532, 537, 545, 552, 558, 565, 572, + 580, 587, 595, 603, 608, 616, 623, 629, 636, 643, 650, 653, 659, 666, + 672, 679, 686, 693, 698, 704, 711, 717, 724, 731, 738, 746, 751, 759, + 766, 772, 779, 786, 794, 801, 809, 817, 822, 830, 837, 843, 850, 857, + 864, 867, 873, 880, 886, 893, 900, 907, 912, 920, 927, 934, 941, 948, + 955, 962, 969, 976, 984, 992, 1000, 1008, 1016, 1024, 1032, 1040, 1047, + 1054, 1061, 1068, 1075, 1082, 1089, 1096, 1103, 1110, 1117, 1124, 1132, + 1140, 1148, 1156, 1164, 1172, 1180, 1188, 1196, 1204, 1211, 1218, 1226, + 1234, 1242, 1250, 1258, 1266, 1274, 1282, 1290, 1296, 1301, 1306, 1314, + 1322, 1330, 1338, 1343, 1350, 1357, 1365, 1373, 1381, 1389, 1398, 1407, + 1414, 1421, 1428, 1435, 1443, 1451, 1459, 1467, 1478, 1483, 1488, 1495, + 1502, 1509, 1516, 1523, 1530, 1535, 1540, 1547, 1554, 1562, 1570, 1578, + 1586, 1593, 1600, 1608, 1616, 1624, 1632, 1640, 1648, 1656, 1664, 1672, + 1680, 1687, 1694, 1701, 1708, 1715, 1722, 1729, 1736, 1744, 1752, 1759, + 1766, 1773, 1780, 1788, 1796, 1804, 1812, 1820, 1827, 1834, 1842, 1850, + 1858, 1866, 1871, 1877, 1883, 1890, 1897, 1902, 1907, 1912, 1919, 1926, + 1933, 1940, 1948, 1956, 1963, 1969, 1974, 1979, 1986, 1993, 2000, 2005, + 2010, 2015, 2022, 2029, 2036, 2043, 2050, 2057, 2065, 2075, 2083, 2090, + 2097, 2102, 2107, 2114, 2121, 2125, 2130, 2135, 2140, 2148, 2157, 2164, + 2171, 2180, 2187, 2194, 2199, 2206, 2213, 2220, 2227, 2234, 2239, 2246, + 2253, 2261, 2266, 2271, 2276, 2286, 2290, 2296, 2302, 2308, 2314, 2322, + 2335, 2343, 2348, 2358, 2363, 2368, 2378, 2383, 2390, 2397, 2405, 2413, + 2420, 2427, 2434, 2441, 2451, 2461, 2470, 2479, 2489, 2499, 2509, 2519, + 2525, 2535, 2545, 2555, 2565, 2573, 2581, 2588, 2595, 2603, 2611, 2619, + 2627, 2634, 2641, 2651, 2661, 2669, 2677, 2685, 2690, 2700, 2705, 2712, + 2719, 2724, 2729, 2737, 2745, 2755, 2765, 2772, 2779, 2788, 2797, 2805, + 2813, 2822, 2831, 2839, 2847, 2856, 2865, 2874, 2883, 2893, 2903, 2911, + 2919, 2928, 2937, 2946, 2955, 2965, 2975, 2983, 2991, 3000, 3009, 3018, + 3027, 3036, 3045, 3050, 3055, 3063, 3071, 3081, 3089, 3094, 3099, 3106, + 3113, 3120, 3127, 3134, 3141, 3151, 3161, 3171, 3181, 3188, 3195, 3205, + 3215, 3223, 3231, 3239, 3247, 3255, 3262, 3269, 3276, 3282, 3289, 3296, + 3303, 3312, 3322, 3332, 3339, 3346, 3352, 3357, 3364, 3370, 3376, 3383, + 3390, 3401, 3411, 3418, 3425, 3432, 3439, 3445, 3450, 3457, 3463, 3468, + 3476, 3484, 3491, 3497, 3502, 3509, 3514, 3521, 3530, 3539, 3548, 3555, + 3561, 3567, 3572, 3579, 3586, 3593, 3600, 3607, 3612, 3617, 3626, 3634, + 3643, 3648, 3655, 3666, 3673, 3681, 3690, 3696, 3702, 3708, 3715, 3720, + 3726, 3737, 3746, 3755, 3763, 3771, 3781, 3786, 3793, 3800, 3805, 3817, + 3826, 3834, 3841, 3850, 3855, 3860, 3867, 3874, 3881, 3888, 3894, 3903, + 3911, 3916, 3924, 3930, 3938, 3946, 3952, 3958, 3964, 3971, 3979, 3985, + 3993, 4000, 4005, 4012, 4020, 4030, 4037, 4044, 4054, 4061, 4068, 4078, + 4085, 4092, 4099, 4105, 4111, 4121, 4134, 4139, 4146, 4151, 4155, 4161, + 4170, 4177, 4182, 4187, 4191, 4196, 4202, 4206, 4212, 4218, 4224, 4230, + 4238, 4243, 4248, 4253, 4258, 4264, 4266, 4271, 4275, 4281, 4287, 4293, + 4298, 4305, 4312, 4318, 4325, 4333, 4341, 4346, 4351, 4355, 4360, 4362, + 4364, 4367, 4369, 4372, 4377, 4382, 4388, 4393, 4397, 4401, 4406, 4415, + 4421, 4426, 4432, 4437, 4443, 4451, 4459, 4463, 4467, 4472, 4478, 4484, + 4490, 4496, 4501, 4508, 4516, 4524, 4529, 4535, 4542, 4549, 4556, 4563, + 4567, 4572, 4577, 4582, 4587, 4592, 4595, 4598, 4601, 4604, 4607, 4610, + 4614, 4618, 4624, 4627, 4632, 4638, 4644, 4647, 4652, 4658, 4662, 4668, + 4674, 4680, 4686, 4691, 4696, 4701, 4704, 4710, 4715, 4720, 4724, 4729, + 4735, 4741, 4744, 4748, 4752, 4756, 4759, 4762, 4767, 4771, 4778, 4782, + 4788, 4792, 4798, 4802, 4806, 4810, 4815, 4820, 4827, 4833, 4840, 4846, + 4852, 4858, 4861, 4865, 4869, 4873, 4877, 4882, 4887, 4891, 4895, 4901, + 4905, 4909, 4914, 4920, 4925, 4931, 4935, 4942, 4947, 4951, 4956, 4961, + 4967, 4970, 4974, 4979, 4984, 4993, 4999, 5004, 5008, 5013, 5017, 5022, + 5026, 5030, 5035, 5039, 5045, 5050, 5055, 5060, 5065, 5070, 5075, 5081, + 5087, 5093, 5099, 5104, 5110, 5116, 5122, 5127, 5132, 5139, 5146, 5150, + 5156, 5163, 0, 0, 5170, 5173, 5182, 5191, 5202, 5206, 0, 0, 0, 0, 5211, + 5214, 5219, 5227, 5232, 5240, 5248, 0, 5256, 0, 5264, 5272, 5280, 5291, + 5296, 5301, 5306, 5311, 5316, 5321, 5326, 5331, 5336, 5341, 5346, 5351, + 5356, 5361, 5366, 5371, 0, 5376, 5381, 5386, 5391, 5396, 5401, 5406, + 5411, 5419, 5427, 5435, 5443, 5451, 5459, 5470, 5475, 5480, 5485, 5490, + 5495, 5500, 5505, 5510, 5515, 5520, 5525, 5530, 5535, 5540, 5545, 5550, + 5555, 5561, 5566, 5571, 5576, 5581, 5586, 5591, 5596, 5604, 5612, 5620, + 5628, 5636, 5641, 5645, 5649, 5656, 5666, 5676, 5680, 5684, 5688, 5694, + 5701, 5705, 5710, 5714, 5719, 5723, 5728, 5732, 5737, 5742, 5747, 5752, + 5757, 5762, 5767, 5772, 5777, 5782, 5787, 5792, 5797, 5802, 5807, 5811, + 5815, 5821, 5825, 5830, 5836, 5844, 5849, 5854, 5861, 5866, 5871, 5878, + 5887, 5896, 5907, 5915, 5920, 5925, 5930, 5937, 5942, 5948, 5953, 5958, + 5963, 5968, 5973, 5978, 5986, 5992, 5997, 6001, 6006, 6011, 6016, 6021, + 6026, 6031, 6036, 6040, 6046, 6050, 6055, 6060, 6065, 6069, 6074, 6079, + 6084, 6089, 6093, 6098, 6102, 6107, 6112, 6117, 6122, 6128, 6133, 6139, + 6143, 6148, 6152, 6156, 6161, 6166, 6171, 6176, 6181, 6186, 6191, 6195, + 6201, 6205, 6210, 6215, 6220, 6224, 6229, 6234, 6239, 6244, 6248, 6253, + 6257, 6262, 6267, 6272, 6277, 6283, 6288, 6294, 6298, 6303, 6307, 6315, + 6320, 6325, 6330, 6337, 6342, 6348, 6353, 6358, 6363, 6368, 6373, 6378, + 6386, 6392, 6397, 6402, 6407, 6412, 6417, 6423, 6429, 6436, 6443, 6452, + 6461, 6468, 6475, 6484, 6493, 6498, 6503, 6508, 6513, 6518, 6523, 6528, + 6533, 6544, 6555, 6560, 6565, 6572, 6579, 6587, 6595, 6600, 6605, 6610, + 6615, 6619, 6623, 6627, 6633, 6639, 6643, 6650, 6655, 6665, 6675, 6681, + 6687, 6695, 6703, 6711, 6719, 6726, 6733, 6741, 6749, 6757, 6765, 6773, + 6781, 6789, 6797, 6805, 6813, 6820, 6827, 6833, 6839, 6847, 6855, 6862, + 6869, 6877, 6885, 6891, 6897, 6905, 6913, 6921, 6929, 6935, 6941, 6949, + 6957, 6965, 6973, 6980, 6987, 6995, 7003, 7011, 7019, 7024, 7029, 7036, + 7043, 7053, 7063, 7067, 7075, 7083, 7090, 7097, 7105, 7113, 7120, 7127, + 7135, 7143, 7150, 7157, 7165, 7173, 7178, 7185, 7192, 7199, 7206, 7212, + 7218, 7226, 7234, 7239, 7244, 7252, 7260, 7268, 7276, 7284, 7292, 7299, + 7306, 7314, 7322, 7330, 7338, 7345, 7352, 7358, 7364, 7373, 7382, 7389, + 7396, 7403, 7410, 7417, 7424, 7431, 7438, 7446, 7454, 7462, 7470, 7478, + 7486, 7496, 7506, 7513, 7520, 7527, 7534, 7541, 7548, 7555, 7562, 7569, + 7576, 7583, 7590, 7597, 7604, 7611, 7618, 7625, 7632, 7639, 7646, 7653, + 7660, 7667, 7674, 7679, 7684, 7689, 7694, 7699, 7704, 7709, 7714, 7719, + 7724, 7730, 7736, 7744, 7752, 7760, 7768, 7776, 7784, 7792, 7800, 7808, + 7816, 7821, 7826, 7831, 7836, 7844, 0, 7852, 7857, 7862, 7867, 7872, + 7877, 7882, 7887, 7892, 7896, 7901, 7906, 7911, 7916, 7921, 7926, 7931, + 7936, 7941, 7946, 7951, 7956, 7961, 7966, 7971, 7976, 7981, 7986, 7991, + 7996, 8001, 8006, 8011, 8016, 8021, 8026, 8031, 8036, 0, 0, 8041, 8048, + 8051, 8055, 8059, 8062, 8066, 0, 8070, 8075, 8080, 8085, 8090, 8095, + 8100, 8105, 8110, 8114, 8119, 8124, 8129, 8134, 8139, 8144, 8149, 8154, + 8159, 8164, 8169, 8174, 8179, 8184, 8189, 8194, 8199, 8204, 8209, 8214, + 8219, 8224, 8229, 8234, 8239, 8244, 8249, 8254, 8259, 0, 8266, 8271, 0, + 0, 8274, 8280, 8286, 0, 8290, 8295, 8300, 8305, 8312, 8319, 8324, 8329, + 8334, 8339, 8344, 8349, 8354, 8361, 8366, 8373, 8380, 8385, 8392, 8397, + 8402, 8407, 8414, 8419, 8424, 8431, 8440, 8445, 8450, 8455, 8460, 8466, + 8471, 8478, 8485, 8492, 8497, 8502, 8507, 8512, 8517, 8522, 8532, 8537, + 8546, 8551, 8556, 8561, 8566, 8573, 8580, 8587, 8593, 8599, 8606, 0, 0, + 0, 0, 0, 0, 0, 0, 8613, 8617, 8621, 8625, 8629, 8633, 8637, 8641, 8645, + 8649, 8653, 8658, 8662, 8666, 8671, 8675, 8680, 8684, 8688, 8692, 8697, + 8701, 8706, 8710, 8714, 8718, 8722, 0, 0, 0, 0, 0, 8726, 8733, 8741, + 8748, 8753, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8758, 8761, 8765, 8770, + 8774, 8778, 8782, 8788, 8794, 8797, 8804, 8813, 8816, 8819, 8824, 8830, + 8834, 8842, 8848, 8854, 8862, 8866, 8871, 8882, 8887, 8891, 8895, 8899, + 8902, 0, 8905, 8912, 8916, 8922, 8926, 8933, 8940, 8948, 8955, 8962, + 8966, 8970, 8976, 8980, 8984, 8988, 8992, 8996, 9000, 9004, 9008, 9012, + 9016, 9020, 9024, 9028, 9032, 9036, 9040, 9044, 9052, 9060, 9070, 9079, + 9088, 9091, 9095, 9099, 9103, 9107, 9111, 9115, 9119, 9123, 9128, 9132, + 9135, 9138, 9141, 9144, 9147, 9150, 9153, 9156, 9160, 9164, 9168, 9173, + 9178, 9184, 9187, 9194, 9203, 9208, 9213, 9220, 9226, 9231, 9235, 9239, + 9243, 9247, 9251, 9255, 9260, 9264, 9269, 9273, 9278, 9283, 9290, 9296, + 9302, 9308, 9313, 9322, 9331, 9336, 9343, 9350, 9357, 9364, 9368, 9372, + 9376, 9383, 9393, 9397, 9401, 9405, 9412, 9420, 9424, 9428, 9435, 9439, + 9443, 9447, 9454, 9461, 9473, 9477, 9481, 9485, 9495, 9504, 9508, 9516, + 9523, 9530, 9539, 9550, 9558, 9562, 9571, 9582, 9590, 9603, 9611, 9619, + 9627, 9635, 9641, 9650, 9657, 9661, 9669, 9673, 9680, 9688, 9692, 9698, + 9705, 9712, 9716, 9724, 9728, 9735, 9739, 9747, 9751, 9759, 9767, 9774, + 9782, 9790, 9797, 9803, 9807, 9814, 9822, 9828, 9835, 9842, 9848, 9858, + 9866, 9873, 9879, 9883, 9886, 9890, 9896, 9904, 9908, 9914, 9920, 9927, + 9934, 9937, 9944, 9949, 9958, 9963, 9967, 9980, 9993, 9999, 10006, 10011, + 10017, 10022, 10028, 10038, 10045, 10054, 10064, 10070, 10075, 10080, + 10084, 10088, 10093, 10098, 10104, 10112, 10120, 10131, 10136, 10145, + 10154, 10161, 10167, 10173, 10179, 10185, 10191, 10197, 10204, 10210, + 10217, 10224, 10231, 10238, 10244, 10252, 10261, 10268, 10276, 10284, + 10290, 10296, 10302, 10310, 10318, 10328, 10338, 10342, 10348, 10354, 0, + 10360, 10365, 10370, 10377, 10382, 10387, 10394, 10399, 10408, 10413, + 10418, 10423, 10428, 10433, 10440, 10445, 10452, 10457, 10462, 10467, + 10472, 10477, 10483, 10487, 10492, 10499, 10504, 10509, 10514, 10519, + 10524, 10531, 10538, 10545, 10550, 10555, 10561, 10566, 10571, 10577, + 10582, 10587, 10595, 10603, 10608, 10613, 10619, 10624, 10629, 10633, + 10639, 10643, 10647, 10653, 10659, 10664, 10669, 10676, 10683, 10687, 0, + 0, 10691, 10698, 10705, 10712, 10722, 10734, 10745, 10761, 10773, 10784, + 10792, 10799, 10809, 10824, 10835, 10841, 10850, 10858, 10869, 10879, + 10887, 10898, 10905, 10913, 10924, 10930, 10936, 10944, 10952, 10960, + 10966, 10976, 10984, 10994, 11004, 11017, 11031, 11045, 11055, 11066, + 11077, 11090, 11103, 11117, 11129, 11141, 11154, 11167, 11179, 11192, + 11201, 11209, 11214, 11219, 11224, 11229, 11234, 11239, 11244, 11249, + 11254, 11259, 11264, 11269, 11274, 11279, 11284, 11289, 11294, 11299, + 11304, 11309, 11314, 11319, 11324, 11329, 11334, 11339, 11344, 11349, + 11354, 11359, 11364, 11369, 11373, 11378, 11383, 11388, 11393, 11398, + 11402, 11406, 11410, 11414, 11418, 11422, 11426, 11430, 11434, 11438, + 11442, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11447, 11452, 11456, + 11460, 11464, 11468, 11472, 11476, 11481, 11485, 11490, 11494, 11499, + 11503, 11507, 11511, 11516, 11520, 11525, 11530, 11535, 11539, 11544, + 11549, 11554, 11559, 11564, 11569, 11574, 11579, 11584, 11588, 11593, + 11600, 11604, 11609, 11614, 11618, 11623, 11627, 11634, 11641, 11648, + 11655, 11663, 11671, 11680, 11688, 11695, 11702, 11710, 11716, 11722, + 11728, 11734, 11741, 11746, 11750, 11755, 0, 0, 0, 0, 0, 11759, 11764, + 11769, 11774, 11779, 11784, 11789, 11794, 11799, 11804, 11809, 11814, + 11819, 11824, 11829, 11834, 11839, 11844, 11849, 11854, 11859, 11864, + 11869, 11874, 11879, 11884, 11889, 11897, 11904, 11910, 11915, 11923, + 11930, 11936, 11943, 11949, 11954, 11961, 11968, 11974, 11979, 11984, + 11990, 11995, 12000, 12006, 0, 0, 12011, 12017, 12023, 12029, 12035, + 12041, 12047, 12052, 12060, 12066, 12072, 12078, 12084, 12090, 12098, 0, + 12104, 12109, 12114, 12119, 12124, 12129, 12134, 12139, 12144, 12149, + 12154, 12159, 12164, 12169, 12174, 12179, 12184, 12189, 12194, 12199, + 12204, 12209, 12214, 12219, 12224, 12229, 12234, 12239, 0, 0, 12244, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12248, 12257, 12265, + 12272, 12280, 12292, 12299, 12306, 12313, 12325, 12336, 12343, 12351, + 12357, 12362, 12370, 12378, 12386, 12392, 12402, 12410, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12417, 12423, 12428, + 12433, 12438, 12443, 12448, 12453, 12458, 12463, 12468, 12473, 12478, + 12483, 12487, 12491, 12495, 12500, 12506, 12512, 12518, 12523, 12528, + 12533, 12538, 12544, 12553, 12561, 12567, 12575, 12581, 12585, 12589, + 12593, 12598, 12601, 12605, 12608, 12612, 12615, 12619, 12623, 12627, + 12632, 12637, 12640, 12644, 12649, 12654, 12657, 12661, 12664, 12668, + 12672, 12676, 12680, 12684, 12688, 12692, 12696, 12700, 12704, 12708, + 12712, 12716, 12720, 12724, 12728, 12732, 12736, 12740, 12744, 12747, + 12751, 12755, 12759, 12762, 12765, 12769, 12773, 12777, 12781, 12785, + 12789, 12793, 12797, 12801, 12804, 12809, 12814, 12818, 12822, 12827, + 12831, 12836, 12840, 12845, 12850, 12856, 12862, 12868, 12872, 12877, + 12883, 12889, 12893, 12898, 12902, 12908, 12913, 12916, 12922, 12928, + 12933, 12938, 12945, 12950, 12955, 12959, 12963, 12967, 12971, 12975, + 12979, 12983, 12987, 12992, 12997, 13002, 13008, 13011, 13015, 13019, + 13022, 13025, 13028, 13031, 13034, 13037, 13041, 13044, 13048, 13052, + 13059, 13064, 13068, 13072, 13076, 13080, 13084, 13090, 13094, 13098, + 13102, 13106, 13112, 13116, 13120, 13123, 13127, 13131, 0, 13135, 13138, + 13142, 13145, 13149, 13152, 13156, 13160, 0, 0, 13164, 13167, 0, 0, + 13171, 13174, 13178, 13181, 13185, 13189, 13193, 13197, 13201, 13205, + 13209, 13213, 13217, 13221, 13225, 13229, 13233, 13237, 13241, 13245, + 13249, 13253, 0, 13257, 13260, 13264, 13268, 13272, 13275, 13278, 0, + 13282, 0, 0, 0, 13286, 13290, 13294, 13298, 0, 0, 13301, 13305, 13309, + 13314, 13318, 13323, 13327, 13332, 13337, 0, 0, 13343, 13347, 0, 0, + 13352, 13356, 13361, 13365, 0, 0, 0, 0, 0, 0, 0, 0, 13371, 0, 0, 0, 0, + 13377, 13381, 0, 13385, 13389, 13394, 13399, 13404, 0, 0, 13410, 13414, + 13417, 13420, 13423, 13426, 13429, 13432, 13436, 13439, 13443, 13451, + 13460, 13464, 13468, 13474, 13480, 13486, 13492, 13506, 13513, 13516, 0, + 0, 0, 0, 0, 13520, 13527, 13532, 0, 13537, 13541, 13546, 13550, 13555, + 13559, 0, 0, 0, 0, 13564, 13569, 0, 0, 13574, 13579, 13584, 13588, 13593, + 13598, 13603, 13608, 13613, 13618, 13623, 13628, 13633, 13638, 13643, + 13648, 13653, 13658, 13663, 13668, 13673, 13678, 0, 13683, 13687, 13692, + 13697, 13702, 13706, 13710, 0, 13715, 13720, 0, 13725, 13730, 0, 13735, + 13740, 0, 0, 13744, 0, 13749, 13755, 13760, 13766, 13771, 0, 0, 0, 0, + 13777, 13783, 0, 0, 13789, 13795, 13801, 0, 0, 0, 13806, 0, 0, 0, 0, 0, + 0, 0, 13811, 13816, 13821, 13826, 0, 13831, 0, 0, 0, 0, 0, 0, 0, 13836, + 13841, 13845, 13849, 13853, 13857, 13861, 13865, 13870, 13874, 13879, + 13883, 13887, 13891, 13895, 13901, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 13906, 13911, 13916, 0, 13921, 13925, 13930, 13934, 13939, 13943, 13948, + 13953, 13958, 0, 13964, 13968, 13973, 0, 13979, 13983, 13988, 13992, + 13997, 14002, 14007, 14012, 14017, 14022, 14027, 14032, 14037, 14042, + 14047, 14052, 14057, 14062, 14067, 14072, 14077, 14082, 0, 14087, 14091, + 14096, 14101, 14106, 14110, 14114, 0, 14119, 14124, 0, 14129, 14134, + 14139, 14144, 14149, 0, 0, 14153, 14158, 14163, 14169, 14174, 14180, + 14185, 14191, 14197, 14204, 0, 14211, 14216, 14222, 0, 14229, 14234, + 14240, 0, 0, 14245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14249, + 14255, 14261, 14267, 0, 0, 14274, 14279, 14283, 14287, 14291, 14295, + 14299, 14303, 14308, 14312, 14317, 14322, 0, 0, 0, 0, 0, 0, 0, 14327, 0, + 0, 0, 0, 0, 0, 0, 14332, 14336, 14340, 0, 14344, 14347, 14351, 14354, + 14358, 14361, 14365, 14369, 0, 0, 14373, 14376, 0, 0, 14380, 14383, + 14387, 14390, 14394, 14398, 14402, 14406, 14410, 14414, 14418, 14422, + 14426, 14430, 14434, 14438, 14442, 14446, 14450, 14454, 14458, 14462, 0, + 14466, 14469, 14473, 14477, 14481, 14484, 14487, 0, 14491, 14495, 0, + 14499, 14503, 14507, 14511, 14515, 0, 0, 14518, 14522, 14526, 14531, + 14535, 14540, 14544, 14549, 14554, 0, 0, 14560, 14564, 0, 0, 14569, + 14573, 14578, 0, 0, 0, 0, 0, 0, 0, 0, 14582, 14588, 0, 0, 0, 0, 14594, + 14598, 0, 14602, 14606, 14611, 14616, 14621, 0, 0, 14627, 14631, 14634, + 14637, 14640, 14643, 14646, 14649, 14653, 14656, 14660, 14663, 14667, + 14673, 14679, 14685, 14691, 14697, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14703, + 14707, 0, 14711, 14714, 14718, 14721, 14725, 14728, 0, 0, 0, 14732, + 14735, 14739, 0, 14743, 14746, 14750, 14754, 0, 0, 0, 14757, 14761, 0, + 14765, 0, 14769, 14773, 0, 0, 0, 14777, 14781, 0, 0, 0, 14785, 14789, + 14793, 0, 0, 0, 14796, 14799, 14802, 14806, 14810, 14814, 14818, 14822, + 14826, 14830, 14834, 14838, 0, 0, 0, 0, 14841, 14846, 14850, 14855, + 14859, 0, 0, 0, 14864, 14868, 14873, 0, 14878, 14882, 14887, 14892, 0, 0, + 14896, 0, 0, 0, 0, 0, 0, 14899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 14905, 14909, 14912, 14915, 14918, 14921, 14924, 14927, 14931, 14934, + 14938, 14942, 14947, 14952, 14956, 14960, 14964, 14968, 14972, 14977, + 14981, 0, 0, 0, 0, 0, 14984, 14990, 14994, 14998, 0, 15002, 15005, 15009, + 15012, 15016, 15019, 15023, 15027, 0, 15031, 15034, 15038, 0, 15042, + 15045, 15049, 15053, 15056, 15060, 15064, 15068, 15072, 15076, 15080, + 15084, 15088, 15092, 15096, 15100, 15104, 15108, 15112, 15116, 15120, + 15124, 15128, 0, 15132, 15135, 15139, 15143, 15147, 15150, 15153, 15157, + 15161, 15165, 15169, 15173, 15177, 15181, 15185, 15189, 0, 0, 0, 15192, + 15196, 15201, 15205, 15210, 15214, 15219, 15224, 0, 15230, 15234, 15239, + 0, 15244, 15248, 15253, 15258, 0, 0, 0, 0, 0, 0, 0, 15262, 15266, 0, + 15272, 15276, 15280, 0, 0, 0, 0, 0, 15284, 15289, 15294, 15299, 0, 0, + 15305, 15309, 15312, 15315, 15318, 15321, 15324, 15327, 15331, 15334, 0, + 0, 0, 0, 0, 0, 0, 0, 15338, 15351, 15363, 15375, 15387, 15399, 15411, + 15423, 0, 15427, 15431, 15435, 0, 15439, 15442, 15446, 15449, 15453, + 15456, 15460, 15464, 0, 15468, 15471, 15475, 0, 15479, 15482, 15486, + 15490, 15493, 15497, 15501, 15505, 15509, 15513, 15517, 15521, 15525, + 15529, 15533, 15537, 15541, 15545, 15549, 15553, 15557, 15561, 15565, 0, + 15569, 15572, 15576, 15580, 15584, 15587, 15590, 15594, 15598, 15602, 0, + 15606, 15610, 15614, 15618, 15622, 0, 0, 15625, 15629, 15633, 15638, + 15642, 15647, 15651, 15656, 15661, 0, 15667, 15671, 15676, 0, 15681, + 15685, 15690, 15695, 0, 0, 0, 0, 0, 0, 0, 15699, 15703, 0, 0, 0, 0, 0, 0, + 0, 15709, 0, 15713, 15718, 15723, 15728, 0, 0, 15734, 15738, 15741, + 15744, 15747, 15750, 15753, 15756, 15760, 15763, 0, 15767, 15771, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15775, 15779, 15783, 0, 15787, 15790, + 15794, 15797, 15801, 15804, 15808, 15812, 0, 15816, 15819, 15823, 0, + 15827, 15830, 15834, 15838, 15841, 15845, 15849, 15853, 15857, 15861, + 15865, 15869, 15873, 15877, 15881, 15885, 15889, 15893, 15897, 15901, + 15905, 15909, 15913, 15917, 15921, 15924, 15928, 15932, 15936, 15939, + 15942, 15946, 15950, 15954, 15958, 15962, 15966, 15970, 15974, 15978, + 15981, 0, 0, 15985, 15989, 15994, 15998, 16003, 16007, 16012, 16017, 0, + 16023, 16027, 16032, 0, 16037, 16041, 16046, 16051, 16055, 0, 0, 0, 0, 0, + 0, 0, 0, 16060, 0, 0, 0, 0, 0, 0, 0, 16066, 16072, 16077, 16082, 16087, + 0, 0, 16093, 16097, 16100, 16103, 16106, 16109, 16112, 16115, 16119, + 16122, 16126, 16130, 16135, 16140, 16146, 16152, 0, 0, 0, 16158, 16162, + 16168, 16174, 16180, 16185, 16191, 0, 0, 16197, 16201, 0, 16205, 16209, + 16213, 16217, 16221, 16225, 16229, 16233, 16237, 16241, 16245, 16249, + 16253, 16257, 16261, 16265, 16269, 16273, 0, 0, 0, 16277, 16283, 16289, + 16295, 16301, 16307, 16313, 16319, 16325, 16331, 16337, 16343, 16351, + 16357, 16363, 16369, 16375, 16381, 16387, 16393, 16399, 16405, 16411, + 16417, 0, 16423, 16429, 16435, 16441, 16447, 16453, 16457, 16463, 16467, + 0, 16471, 0, 0, 16477, 16481, 16487, 16493, 16499, 16503, 16509, 0, 0, 0, + 16513, 0, 0, 0, 0, 16517, 16522, 16529, 16536, 16543, 16550, 0, 16557, 0, + 16564, 16569, 16574, 16581, 16588, 16597, 16608, 16617, 0, 0, 0, 0, 0, 0, + 16622, 16628, 16633, 16638, 16643, 16648, 16653, 16658, 16664, 16669, 0, + 0, 16675, 16682, 16689, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16694, 16701, + 16708, 16715, 16722, 16729, 16736, 16743, 16750, 16757, 16764, 16771, + 16778, 16785, 16792, 16799, 16806, 16813, 16820, 16827, 16834, 16841, + 16848, 16855, 16862, 16869, 16876, 16883, 16890, 16897, 16904, 16911, + 16918, 16924, 16931, 16938, 16943, 16950, 16955, 16962, 16969, 16976, + 16983, 16990, 16997, 17003, 17010, 17015, 17021, 17028, 17035, 17042, + 17048, 17055, 17062, 17069, 17075, 17082, 0, 0, 0, 0, 17087, 17094, + 17100, 17107, 17113, 17122, 17131, 17136, 17141, 17146, 17153, 17160, + 17167, 17174, 17179, 17184, 17189, 17194, 17199, 17203, 17207, 17211, + 17215, 17219, 17223, 17228, 17232, 17237, 17242, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 17247, 17252, 0, 17259, 0, 0, 17266, 17271, 0, 17276, 0, + 0, 17283, 0, 0, 0, 0, 0, 0, 17288, 17293, 17297, 17304, 0, 17311, 17316, + 17321, 17326, 17333, 17340, 17347, 0, 17354, 17359, 17364, 0, 17371, 0, + 17378, 0, 0, 17383, 17390, 0, 17397, 17401, 17408, 17412, 17417, 17425, + 17431, 17437, 17442, 17448, 17454, 17460, 17465, 0, 17471, 17479, 17486, + 0, 0, 17493, 17498, 17504, 17509, 17515, 0, 17521, 0, 17527, 17534, + 17541, 17548, 17555, 17560, 0, 0, 17564, 17569, 17573, 17577, 17581, + 17585, 17589, 17593, 17598, 17602, 0, 0, 17607, 17613, 17619, 17626, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 17633, 17637, 17648, 17663, 17678, 17688, 17699, + 17712, 17723, 17729, 17737, 17747, 17753, 17761, 17765, 17771, 17777, + 17785, 17795, 17803, 17816, 17822, 17830, 17838, 17850, 17857, 17865, + 17873, 17881, 17889, 17897, 17905, 17915, 17919, 17922, 17925, 17928, + 17931, 17934, 17937, 17941, 17944, 17948, 17952, 17956, 17960, 17964, + 17968, 17972, 17977, 17981, 17986, 17991, 17997, 18007, 18021, 18031, + 18037, 18043, 18051, 18059, 18067, 18075, 18081, 18087, 18090, 18094, + 18098, 18102, 18106, 18110, 18114, 0, 18118, 18122, 18126, 18130, 18134, + 18138, 18142, 18146, 18150, 18154, 18158, 18162, 18165, 18169, 18173, + 18177, 18180, 18184, 18188, 18192, 18196, 18200, 18204, 18208, 18212, + 18215, 18219, 18223, 18227, 18231, 18235, 18238, 18241, 18245, 18251, + 18255, 0, 0, 0, 0, 18259, 18264, 18268, 18273, 18277, 18282, 18287, + 18293, 18298, 18304, 18308, 18313, 18317, 18322, 18332, 18338, 18344, + 18351, 18361, 18367, 18371, 18375, 18381, 18387, 18395, 18401, 18409, + 18417, 18425, 18435, 18443, 18453, 18458, 18464, 18470, 18476, 18482, + 18488, 18494, 0, 18500, 18506, 18512, 18518, 18524, 18530, 18536, 18542, + 18548, 18554, 18560, 18566, 18571, 18577, 18583, 18589, 18594, 18600, + 18606, 18612, 18618, 18624, 18630, 18636, 18642, 18647, 18653, 18659, + 18665, 18671, 18677, 18682, 18687, 18693, 18701, 18708, 0, 18716, 18723, + 18736, 18743, 18750, 18758, 18766, 18772, 18778, 18784, 18794, 18799, + 18805, 18815, 18825, 0, 18835, 18845, 18853, 18865, 18877, 18883, 18897, + 18912, 18917, 18922, 18930, 18938, 18946, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 18954, 18957, 18961, 18965, 18969, 18973, 18977, 18981, 18985, + 18989, 18993, 18997, 19001, 19005, 19009, 19013, 19017, 19021, 19025, + 19029, 19033, 19037, 19040, 19044, 19048, 19052, 19055, 19058, 19062, + 19066, 19070, 19074, 19077, 19081, 19084, 19089, 19092, 19096, 19099, + 19103, 19106, 19111, 19114, 19118, 19125, 19130, 19134, 19139, 19143, + 19148, 19152, 19157, 19164, 19170, 19175, 19179, 19183, 19187, 19191, + 19195, 19200, 19206, 19212, 19217, 19223, 19227, 19230, 19233, 19236, + 19239, 19242, 19245, 19249, 19252, 19256, 19262, 19266, 19270, 19274, + 19278, 19282, 19286, 19290, 19294, 19299, 19303, 19308, 19313, 19319, + 19324, 19330, 19336, 19342, 19348, 19354, 19362, 19369, 19377, 19385, + 19394, 19403, 19414, 19424, 19434, 19445, 19456, 19466, 19476, 19486, + 19496, 19506, 19516, 19526, 19536, 19544, 19551, 19557, 19564, 19569, + 19575, 19581, 19587, 19593, 19599, 19605, 19611, 19617, 19623, 19629, + 19635, 19640, 19648, 19655, 19661, 19668, 19676, 19682, 19688, 19694, + 19700, 19708, 19716, 19726, 19734, 19742, 19748, 19753, 19758, 19763, + 19768, 19773, 19778, 19784, 19789, 19795, 19801, 19807, 19813, 19820, + 19825, 19831, 19836, 19841, 19846, 19851, 19856, 19861, 19866, 19871, + 19876, 19881, 19886, 19891, 19896, 19901, 19906, 19911, 19916, 19921, + 19926, 19931, 19936, 19941, 19946, 19951, 19956, 19961, 19966, 19971, + 19976, 19981, 19986, 19991, 19996, 20001, 20006, 20011, 20016, 0, 20021, + 0, 0, 0, 0, 0, 20026, 0, 0, 20031, 20035, 20039, 20043, 20047, 20051, + 20055, 20059, 20063, 20067, 20071, 20075, 20079, 20083, 20087, 20091, + 20095, 20099, 20103, 20107, 20111, 20115, 20119, 20123, 20127, 20131, + 20135, 20139, 20143, 20147, 20151, 20155, 20159, 20163, 20167, 20171, + 20175, 20179, 20183, 20187, 20191, 20195, 20201, 20205, 20210, 20215, + 20219, 20224, 20229, 20233, 20237, 20241, 20245, 20249, 20253, 20257, + 20261, 20265, 20269, 20273, 20277, 20281, 20285, 20289, 20293, 20297, + 20301, 20305, 20309, 20313, 20317, 20321, 20325, 20329, 20333, 20337, + 20341, 20345, 20349, 20353, 20357, 20361, 20365, 20369, 20373, 20377, + 20381, 20385, 20389, 20393, 20397, 20401, 20405, 20409, 20413, 20417, + 20421, 20425, 20429, 20433, 20437, 20441, 20445, 20449, 20453, 20457, + 20461, 20465, 20469, 20473, 20477, 20481, 20485, 20489, 20493, 20497, + 20501, 20505, 20509, 20513, 20517, 20521, 20525, 20529, 20533, 20537, + 20541, 20545, 20549, 20553, 20557, 20561, 20565, 20569, 20573, 20577, + 20581, 20585, 20589, 20593, 20597, 20601, 20605, 20609, 20613, 20617, + 20620, 20624, 20627, 20631, 20635, 20638, 20642, 20646, 20649, 20653, + 20657, 20661, 20665, 20668, 20672, 20676, 20680, 20684, 20688, 20692, + 20695, 20699, 20703, 20707, 20711, 20715, 20719, 20723, 20727, 20731, + 20735, 20739, 20743, 20747, 20751, 20755, 20759, 20763, 20767, 20771, + 20775, 20779, 20783, 20787, 20791, 20795, 20799, 20803, 20807, 20811, + 20815, 20819, 20823, 20827, 20831, 20835, 20839, 20843, 20847, 20851, + 20855, 20859, 20863, 20867, 20871, 20875, 20879, 20883, 20887, 20891, + 20895, 20899, 20903, 20907, 20911, 20915, 20919, 20923, 20927, 20931, + 20935, 20939, 20943, 20947, 20951, 20955, 20959, 20963, 20967, 20971, + 20975, 20979, 20983, 20987, 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, 21159, 21163, 21167, 21171, + 21175, 21179, 21183, 21187, 21191, 21195, 21199, 21203, 21207, 21211, + 21215, 21219, 21223, 21227, 21231, 21235, 21239, 21243, 21247, 21250, + 21254, 21258, 21262, 21266, 21270, 21274, 21278, 21282, 21286, 21290, + 21294, 21298, 21302, 21306, 21310, 21314, 21318, 21322, 21326, 21330, + 21334, 21338, 21342, 21345, 21349, 21353, 21357, 21361, 21365, 21369, + 21373, 21377, 21381, 21385, 21389, 21393, 21397, 21401, 21405, 21409, + 21413, 21417, 21421, 21425, 21429, 21433, 21437, 21441, 21445, 21449, + 21453, 21457, 21461, 21465, 21469, 21473, 21477, 21481, 21485, 21489, + 21493, 21497, 21501, 21505, 21509, 21513, 21517, 21521, 21525, 21529, + 21533, 0, 21537, 21541, 21545, 21549, 0, 0, 21553, 21557, 21561, 21565, + 21569, 21573, 21577, 0, 21581, 0, 21585, 21589, 21593, 21597, 0, 0, + 21601, 21605, 21609, 21613, 21617, 21621, 21625, 21629, 21633, 21637, + 21641, 21645, 21649, 21653, 21657, 21661, 21665, 21669, 21673, 21677, + 21681, 21685, 21689, 21692, 21696, 21700, 21704, 21708, 21712, 21716, + 21720, 21724, 21728, 21732, 21736, 21740, 21744, 21748, 21752, 21756, + 21760, 0, 21764, 21768, 21772, 21776, 0, 0, 21780, 21784, 21788, 21792, + 21796, 21800, 21804, 21808, 21812, 21816, 21820, 21824, 21828, 21832, + 21836, 21840, 21844, 21849, 21854, 21859, 21865, 21871, 21876, 21881, + 21887, 21890, 21894, 21898, 21902, 21906, 21910, 21914, 21918, 0, 21922, + 21926, 21930, 21934, 0, 0, 21938, 21942, 21946, 21950, 21954, 21958, + 21962, 0, 21966, 0, 21970, 21974, 21978, 21982, 0, 0, 21986, 21990, + 21994, 21998, 22002, 22006, 22010, 22014, 22018, 22023, 22028, 22033, + 22039, 22045, 22050, 0, 22055, 22059, 22063, 22067, 22071, 22075, 22079, + 22083, 22087, 22091, 22095, 22099, 22103, 22107, 22111, 22115, 22119, + 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, 0, + 22282, 22286, 22290, 22294, 0, 0, 22298, 22302, 22306, 22310, 22314, + 22318, 22322, 22326, 22330, 22334, 22338, 22342, 22346, 22350, 22354, + 22358, 22362, 22366, 22370, 22374, 22378, 22382, 22386, 22390, 22394, + 22398, 22402, 22406, 22410, 22414, 22418, 22422, 22426, 22430, 22434, + 22438, 22442, 22446, 22450, 22454, 22458, 22462, 22466, 22470, 22474, + 22478, 22482, 22486, 22490, 22494, 22498, 22502, 22506, 22510, 22514, + 22518, 22522, 22525, 22529, 22533, 22537, 22541, 22545, 22549, 22553, + 22557, 22561, 0, 0, 22565, 22574, 22580, 22585, 22589, 22592, 22597, + 22600, 22603, 22606, 22611, 22615, 22620, 22623, 22626, 22629, 22632, + 22635, 22638, 22642, 22645, 22649, 22653, 22657, 22661, 22665, 22669, + 22673, 22677, 22681, 22685, 22689, 0, 0, 0, 22695, 22701, 22705, 22709, + 22713, 22719, 22723, 22727, 22731, 22737, 22741, 22745, 22749, 22755, + 22759, 22763, 22767, 22773, 22779, 22785, 22793, 22799, 22805, 22811, + 22817, 22823, 0, 0, 0, 0, 0, 0, 22829, 22832, 22835, 22838, 22841, 22844, + 22848, 22852, 22855, 22859, 22863, 22867, 22871, 22875, 22878, 22882, + 22886, 22890, 22894, 22898, 22902, 22906, 22910, 22914, 22918, 22922, + 22925, 22929, 22933, 22937, 22941, 22945, 22949, 22953, 22957, 22961, + 22965, 22969, 22973, 22977, 22981, 22985, 22989, 22993, 22997, 23001, + 23004, 23008, 23012, 23016, 23020, 23024, 23028, 23032, 23036, 23040, + 23044, 23048, 23052, 23056, 23060, 23064, 23068, 23072, 23076, 23080, + 23084, 23088, 23092, 23096, 23100, 23104, 23108, 23112, 23116, 23120, + 23124, 23128, 23132, 23136, 23139, 23143, 23147, 23151, 23155, 23159, 0, + 0, 23163, 23168, 23173, 23178, 23183, 23188, 0, 0, 23193, 23197, 23200, + 23204, 23207, 23211, 23214, 23218, 23224, 23229, 23233, 23236, 23240, + 23244, 23249, 23253, 23258, 23262, 23267, 23271, 23276, 23280, 23285, + 23291, 23295, 23300, 23304, 23309, 23315, 23319, 23325, 23331, 23335, + 23340, 23348, 23356, 23363, 23368, 23373, 23382, 23388, 23396, 23401, + 23407, 23411, 23415, 23419, 23423, 23427, 23431, 23435, 23439, 23443, + 23447, 23453, 23458, 23463, 23466, 23470, 23474, 23479, 23483, 23488, + 23492, 23497, 23501, 23506, 23510, 23515, 23519, 23524, 23528, 23533, + 23539, 23543, 23548, 23553, 23557, 23561, 23565, 23569, 23572, 23576, + 23582, 23587, 23592, 23596, 23600, 23604, 23609, 23613, 23618, 23622, + 23627, 23630, 23634, 23638, 23643, 23647, 23652, 23656, 23661, 23667, + 23671, 23675, 23679, 23683, 23687, 23691, 23695, 23699, 23703, 23707, + 23711, 23717, 23720, 23724, 23728, 23733, 23737, 23742, 23746, 23751, + 23755, 23760, 23764, 23769, 23773, 23778, 23782, 23787, 23793, 23797, + 23801, 23807, 23813, 23819, 23825, 23829, 23833, 23837, 23841, 23845, + 23849, 23855, 23859, 23863, 23867, 23872, 23876, 23881, 23885, 23890, + 23894, 23899, 23903, 23908, 23912, 23917, 23921, 23926, 23932, 23936, + 23942, 23946, 23950, 23954, 23958, 23962, 23966, 23972, 23975, 23979, + 23983, 23988, 23992, 23997, 24001, 24006, 24010, 24015, 24019, 24024, + 24028, 24033, 24037, 24042, 24048, 24052, 24057, 24061, 24067, 24073, + 24077, 24081, 24085, 24089, 24093, 24097, 24103, 24107, 24111, 24115, + 24120, 24124, 24129, 24133, 24138, 24144, 24148, 24153, 24157, 24161, + 24165, 24169, 24173, 24177, 24181, 24187, 24191, 24195, 24199, 24204, + 24208, 24213, 24217, 24222, 24226, 24231, 24235, 24240, 24244, 24249, + 24253, 24258, 24261, 24265, 24269, 24273, 24277, 24281, 24285, 24289, + 24293, 24299, 24303, 24307, 24311, 24316, 24320, 24325, 24329, 24334, + 24338, 24343, 24347, 24352, 24356, 24361, 24365, 24370, 24376, 24379, + 24384, 24388, 24393, 24399, 24405, 24411, 24417, 24423, 24429, 24435, + 24439, 24443, 24447, 24451, 24455, 24459, 24463, 24467, 24472, 24476, + 24481, 24485, 24490, 24494, 24499, 24503, 24508, 24512, 24517, 24521, + 24526, 24530, 24534, 24538, 24542, 24546, 24550, 24554, 24560, 24563, + 24567, 24571, 24576, 24580, 24585, 24589, 24594, 24598, 24603, 24607, + 24612, 24616, 24621, 24625, 24630, 24636, 24640, 24646, 24651, 24657, + 24661, 24667, 24672, 24676, 24680, 24684, 24688, 24692, 24697, 24701, + 24705, 24710, 24714, 24719, 24722, 24726, 24730, 24734, 24738, 24742, + 24746, 24750, 24754, 24758, 24762, 24766, 24771, 24775, 24779, 24785, + 24789, 24795, 24799, 24805, 24809, 24813, 24817, 24821, 24825, 24830, + 24834, 24838, 24842, 24846, 24850, 24854, 24858, 24862, 24866, 24870, + 24876, 24882, 24888, 24894, 24900, 24905, 24911, 24917, 24923, 24927, + 24931, 24935, 24939, 24943, 24947, 24951, 24955, 24959, 24963, 24967, + 24971, 24975, 24980, 24985, 24990, 24995, 24999, 25003, 25007, 25011, + 25015, 25019, 25023, 25027, 25031, 25037, 25043, 25049, 25055, 25061, + 25067, 25073, 25079, 25085, 25089, 25093, 25097, 25101, 25105, 25109, + 25113, 25119, 25125, 25131, 25137, 25143, 25149, 25155, 25161, 25167, + 25172, 25177, 25182, 25187, 25193, 25199, 25205, 25211, 25217, 25223, + 25229, 25235, 25241, 25247, 25253, 25258, 25264, 25270, 25276, 25281, + 25286, 25291, 25296, 25301, 25306, 25311, 25316, 25321, 25326, 25331, + 25336, 25341, 25346, 25351, 25356, 25361, 25366, 25371, 25376, 25381, + 25386, 25391, 25396, 25401, 25406, 25411, 25416, 25421, 25426, 25431, + 25436, 25441, 25446, 25451, 25456, 25461, 25466, 25471, 25476, 25481, + 25486, 25490, 25495, 25500, 25505, 25510, 25515, 25520, 25525, 25530, + 25535, 25540, 25545, 25550, 25555, 25560, 25565, 25570, 25575, 25580, + 25585, 25590, 25595, 25600, 25605, 25610, 25615, 25620, 25625, 25630, + 25635, 25640, 25645, 25649, 25654, 25659, 25664, 25669, 25674, 25678, + 25683, 25689, 25694, 25699, 25704, 25709, 25715, 25720, 25725, 25730, + 25735, 25740, 25745, 25750, 25755, 25760, 25765, 25770, 25775, 25780, + 25785, 25790, 25795, 25800, 25805, 25810, 25815, 25820, 25825, 25830, + 25835, 25840, 25845, 25850, 25855, 25860, 25865, 25870, 25875, 25880, + 25885, 25890, 25895, 25900, 25905, 25910, 25915, 25920, 25925, 25930, + 25935, 25941, 25946, 25951, 25956, 25961, 25966, 25971, 25976, 25981, + 25986, 25991, 25996, 26001, 26006, 26011, 26016, 26021, 26026, 26031, + 26036, 26041, 26046, 26051, 26056, 26061, 26066, 26071, 26076, 26081, + 26086, 26091, 26096, 26101, 26106, 26111, 26116, 26121, 26126, 26131, + 26137, 26141, 26145, 26149, 26153, 26157, 26161, 26165, 26169, 26175, + 26181, 26187, 26193, 26199, 26205, 26211, 26218, 26224, 26229, 26234, + 26239, 26244, 26249, 26254, 26259, 26264, 26269, 26274, 26279, 26284, + 26289, 26294, 26299, 26304, 26309, 26314, 26319, 26324, 26329, 26334, + 26339, 26344, 26349, 26354, 26359, 26364, 0, 0, 0, 26371, 26381, 26385, + 26392, 26396, 26400, 26404, 26412, 26416, 26421, 26426, 26431, 26435, + 26440, 26445, 26448, 26452, 26456, 26465, 26469, 26473, 26479, 26483, + 26487, 26495, 26499, 26507, 26513, 26519, 26525, 26531, 26541, 26547, + 26551, 26560, 26563, 26569, 26573, 26579, 26584, 26590, 26598, 26604, + 26609, 26616, 26621, 26625, 26629, 26639, 26645, 26649, 26659, 26665, + 26669, 26673, 26680, 26688, 26694, 26700, 26709, 26713, 26717, 26721, + 26729, 26736, 26740, 26744, 26748, 26752, 26756, 26760, 26764, 26768, + 26772, 26776, 26780, 26785, 26790, 26795, 26799, 26803, 26807, 26811, + 26815, 26819, 26827, 26835, 26843, 26851, 0, 0, 0, 0, 0, 0, 0, 26859, + 26863, 26867, 26871, 26875, 26880, 26885, 26890, 26895, 26900, 26904, + 26909, 26913, 0, 26917, 26922, 26927, 26932, 26936, 26941, 26946, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 26951, 26955, 26959, 26963, 26967, 26972, + 26977, 26982, 26987, 26992, 26996, 27001, 27005, 27009, 27014, 27019, + 27024, 27029, 27033, 27038, 27043, 27048, 27054, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 27059, 27063, 27067, 27071, 27075, 27080, 27085, 27090, 27095, 27100, + 27104, 27109, 27113, 27117, 27122, 27127, 27132, 27137, 27141, 27146, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27151, 27155, 27159, 27163, 27167, + 27172, 27177, 27182, 27187, 27192, 27196, 27201, 27205, 0, 27209, 27214, + 27219, 0, 27224, 27229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27234, 27237, + 27241, 27245, 27249, 27253, 27257, 27261, 27265, 27269, 27273, 27277, + 27281, 27285, 27289, 27293, 27297, 27301, 27304, 27308, 27312, 27316, + 27320, 27324, 27328, 27332, 27336, 27340, 27344, 27348, 27352, 27356, + 27360, 27363, 27367, 27371, 27377, 27383, 27389, 27395, 27401, 27407, + 27413, 27419, 27425, 27431, 27437, 27443, 27449, 27455, 27464, 27473, + 27479, 27485, 27491, 27496, 27500, 27505, 27510, 27515, 27519, 27524, + 27529, 27534, 27538, 27543, 27547, 27552, 27557, 27562, 27567, 27571, + 27575, 27579, 27583, 27587, 27591, 27595, 27599, 27603, 27607, 27613, + 27617, 27621, 27625, 27629, 27633, 27641, 27647, 27651, 27657, 27661, + 27667, 27671, 0, 0, 27675, 27679, 27682, 27685, 27688, 27691, 27694, + 27697, 27701, 27704, 0, 0, 0, 0, 0, 0, 27708, 27716, 27724, 27732, 27740, + 27748, 27756, 27764, 27772, 27780, 0, 0, 0, 0, 0, 0, 27788, 27791, 27794, + 27797, 27802, 27805, 27810, 27817, 27825, 27830, 27837, 27840, 27847, + 27854, 27861, 0, 27865, 27869, 27872, 27875, 27878, 27881, 27884, 27887, + 27891, 27894, 0, 0, 0, 0, 0, 0, 27898, 27901, 27904, 27907, 27910, 27913, + 27917, 27921, 27925, 27929, 27933, 27937, 27940, 27944, 27948, 27951, + 27955, 27959, 27963, 27967, 27971, 27975, 27979, 27982, 27986, 27990, + 27994, 27997, 28001, 28005, 28009, 28013, 28017, 28021, 28025, 28029, + 28036, 28041, 28046, 28051, 28056, 28062, 28068, 28074, 28080, 28085, + 28091, 28097, 28102, 28108, 28114, 28120, 28126, 28132, 28137, 28143, + 28148, 28154, 28160, 28166, 28172, 28178, 28183, 28188, 28194, 28200, + 28205, 28211, 28216, 28222, 28227, 28232, 28238, 28244, 28250, 28256, + 28262, 28268, 28274, 28280, 28286, 28292, 28298, 28304, 28309, 28314, + 28320, 28326, 0, 0, 0, 0, 0, 0, 0, 0, 28332, 28341, 28350, 28358, 28366, + 28376, 28384, 28393, 28400, 28407, 28414, 28422, 28430, 28438, 28446, + 28454, 28462, 28470, 28478, 28485, 28493, 28501, 28509, 28517, 28525, + 28535, 28545, 28555, 28565, 28575, 28585, 28595, 28605, 28615, 28625, + 28635, 28645, 28655, 28665, 28673, 28681, 28691, 28699, 0, 0, 0, 0, 0, + 28709, 28713, 28717, 28721, 28725, 28729, 28733, 28737, 28741, 28745, + 28749, 28753, 28757, 28761, 28765, 28769, 28773, 28777, 28781, 28785, + 28789, 28793, 28797, 28801, 28807, 28811, 28817, 28821, 28827, 28831, + 28837, 28841, 28845, 28849, 28853, 28857, 28861, 28867, 28873, 28879, + 28885, 28891, 28897, 28902, 28908, 28914, 28920, 28926, 28933, 28939, + 28944, 28949, 28953, 28957, 28961, 28965, 28969, 28973, 28977, 28983, + 28989, 28995, 29000, 29007, 29012, 29017, 29023, 29028, 29035, 29042, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 29048, 29054, 29058, 29063, 29068, 29073, + 29078, 29083, 29088, 29093, 29098, 29103, 29108, 29113, 29118, 29123, + 29128, 29132, 29137, 29142, 29147, 29151, 29155, 29160, 29165, 29170, + 29175, 29180, 29185, 29189, 29194, 0, 29199, 29204, 29209, 29214, 29220, + 29226, 29232, 29238, 29243, 29248, 29254, 29261, 0, 0, 0, 0, 29268, + 29273, 29279, 29285, 29291, 29297, 29302, 29307, 29313, 29319, 29324, + 29329, 0, 0, 0, 0, 29334, 0, 0, 0, 29339, 29344, 29349, 29354, 29358, + 29362, 29366, 29370, 29374, 29378, 29383, 29387, 29392, 29397, 29403, + 29409, 29415, 29421, 29426, 29432, 29438, 29444, 29449, 29455, 29460, + 29466, 29472, 29477, 29483, 29489, 29495, 29501, 29506, 29511, 29517, + 29523, 29528, 29534, 29539, 29545, 29550, 29556, 0, 0, 29562, 29568, + 29574, 29580, 29586, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29592, 29601, + 29610, 29618, 29627, 29636, 29644, 29653, 29662, 29671, 29680, 29688, + 29697, 29706, 29714, 29723, 29732, 29741, 29750, 29759, 29768, 29776, + 29785, 29793, 29801, 29810, 29818, 29827, 29836, 29845, 29854, 29863, + 29872, 29880, 29889, 29898, 29906, 29915, 29924, 29933, 29942, 29951, + 29960, 29969, 0, 0, 0, 0, 29978, 29988, 29997, 30006, 30014, 30023, + 30031, 30040, 30048, 30057, 30066, 30075, 30084, 30093, 30102, 30111, + 30120, 30129, 30138, 30147, 30156, 30165, 30174, 30183, 30192, 30200, 0, + 0, 0, 0, 0, 0, 30208, 30216, 30223, 30230, 30237, 30244, 30251, 30258, + 30266, 30273, 30281, 0, 0, 0, 30289, 30297, 30305, 30309, 30315, 30321, + 30327, 30333, 30339, 30345, 30351, 30357, 30363, 30369, 30375, 30381, + 30387, 30393, 30399, 30403, 30409, 30415, 30421, 30427, 30433, 30439, + 30445, 30451, 30457, 30463, 30469, 30475, 30481, 30487, 30493, 30497, + 30502, 30507, 30512, 30516, 30521, 30525, 30530, 30535, 30540, 30545, + 30550, 30555, 30560, 30565, 30570, 30574, 30579, 30584, 30589, 30594, + 30598, 30602, 30607, 30612, 30617, 30622, 0, 0, 30628, 30632, 30639, + 30644, 30650, 30656, 30661, 30667, 30673, 30678, 30684, 30690, 30696, + 30702, 30708, 30713, 30718, 30724, 30729, 30735, 30740, 30746, 30752, + 30758, 30764, 30769, 30774, 30779, 30785, 30791, 30796, 30802, 30808, + 30812, 30817, 30822, 30827, 30832, 30837, 30842, 30847, 30853, 30859, + 30865, 30870, 30875, 30879, 30884, 30888, 30893, 30897, 30902, 30907, + 30912, 30917, 30924, 30931, 30938, 30948, 30957, 30964, 30970, 30981, + 30986, 30992, 0, 30998, 31003, 31008, 31016, 31022, 31030, 31035, 31041, + 31047, 31053, 31058, 31064, 31069, 31076, 31082, 31087, 31093, 31099, + 31105, 31112, 31119, 31126, 31131, 31136, 31143, 31150, 31157, 31164, + 31171, 0, 0, 31178, 31185, 31192, 31198, 31204, 31210, 31216, 31222, + 31228, 31235, 31241, 0, 0, 0, 0, 0, 0, 31248, 31254, 31259, 31264, 31269, + 31274, 31279, 31284, 31290, 31295, 0, 0, 0, 0, 0, 0, 31301, 31306, 31311, + 31316, 31321, 31326, 31331, 31340, 31347, 31352, 31357, 31362, 31367, + 31372, 0, 0, 31377, 31384, 31387, 31390, 31393, 31398, 31402, 31408, + 31412, 31417, 31424, 31432, 31436, 31441, 31445, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 31450, 31456, 31462, 31466, 31470, 31474, + 31478, 31484, 31488, 31494, 31498, 31504, 31510, 31518, 31524, 31532, + 31536, 31540, 31544, 31550, 31553, 31559, 31563, 31569, 31573, 31577, + 31583, 31587, 31593, 31597, 31603, 31611, 31619, 31627, 31633, 31637, + 31643, 31647, 31653, 31657, 31660, 31666, 31670, 31676, 31679, 31682, + 31686, 31690, 31694, 31700, 31706, 31710, 31713, 31717, 31722, 31727, + 31734, 31739, 31746, 31753, 31762, 31769, 31778, 31783, 31790, 31797, + 31806, 31811, 31818, 31823, 31829, 31835, 31841, 31847, 31853, 31859, 0, + 0, 0, 0, 31865, 31869, 31872, 31875, 31878, 31881, 31884, 31887, 31891, + 31894, 31898, 31901, 31904, 31907, 31912, 31917, 31922, 31925, 31930, + 31935, 31940, 31945, 31952, 31957, 31962, 31967, 31972, 31979, 31985, + 31991, 31997, 32003, 32009, 32018, 32027, 32033, 32039, 32047, 32055, + 32064, 32073, 32081, 32089, 32098, 32107, 0, 0, 0, 32115, 32120, 32125, + 32130, 32134, 32138, 32142, 32147, 32151, 32155, 32160, 32164, 32169, + 32174, 32179, 32184, 32189, 32194, 32199, 32204, 32209, 32214, 32218, + 32223, 32228, 32233, 32237, 32241, 32246, 32251, 32256, 32261, 32266, + 32270, 32276, 32282, 32288, 32294, 32300, 32306, 32312, 32318, 32324, + 32329, 32334, 32341, 32349, 32354, 32359, 32364, 32368, 32372, 32376, + 32380, 32384, 32388, 32393, 32397, 32402, 32406, 32411, 32416, 32421, + 32427, 32433, 32437, 32443, 32447, 32453, 32459, 32464, 32471, 32475, + 32481, 32486, 32493, 32498, 32505, 32512, 32517, 32524, 32529, 32534, + 32539, 32546, 32550, 32556, 32563, 32570, 32575, 32582, 32589, 32593, + 32599, 32604, 32609, 32616, 32621, 32626, 32631, 32636, 32640, 32644, + 32649, 32654, 32661, 32667, 32672, 32679, 32684, 32691, 32696, 32706, + 32712, 32718, 32722, 0, 0, 0, 0, 0, 0, 0, 0, 32726, 32735, 32742, 32749, + 32756, 32760, 32765, 32770, 32775, 32780, 32785, 32790, 32795, 32800, + 32805, 32810, 32815, 32820, 32825, 32829, 32834, 32839, 32844, 32849, + 32854, 32859, 32863, 32868, 32873, 32878, 32883, 32887, 32892, 32897, + 32901, 32906, 32911, 32916, 32921, 32926, 32930, 32936, 32943, 32949, + 32954, 32959, 32965, 32970, 32976, 32981, 32987, 32993, 32998, 33004, + 33010, 33015, 33021, 33027, 33033, 33038, 0, 0, 0, 33043, 33049, 33059, + 33065, 33073, 33079, 33084, 33088, 33092, 33096, 33100, 33104, 33108, + 33113, 33117, 0, 0, 0, 33122, 33127, 33132, 33137, 33144, 33150, 33156, + 33162, 33168, 33174, 33180, 33187, 33193, 33200, 33207, 33214, 33221, + 33228, 33235, 33242, 33249, 33256, 33263, 33270, 33277, 33284, 33291, + 33298, 33305, 33312, 33319, 33326, 33333, 33340, 33347, 33354, 33361, + 33368, 33375, 33382, 33389, 33396, 33403, 33410, 33418, 33426, 33434, + 33440, 33446, 33452, 33460, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 12070, 0, 12079, 12086, 12094, 12106, 12113, 12120, 12127, 12138, 12149, - 12156, 12164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12170, 12175, 12180, 12185, 12190, - 12195, 12200, 12205, 12210, 12215, 12220, 12225, 12230, 12234, 12238, - 12242, 12247, 12253, 12259, 12265, 12270, 12275, 12280, 12285, 12291, - 12300, 12308, 0, 12314, 12320, 12324, 12328, 12332, 12337, 12340, 12344, - 12347, 12351, 12354, 12358, 12362, 12366, 12371, 12376, 12379, 12383, - 12388, 12393, 12396, 12400, 12403, 12407, 12411, 12415, 12419, 12423, - 12427, 12431, 12435, 12439, 12443, 12447, 12451, 12455, 12459, 12463, - 12467, 12471, 12475, 12478, 12482, 12485, 12489, 12493, 12497, 12500, - 12503, 12506, 12510, 12514, 12518, 12522, 12526, 12530, 12534, 12537, - 12540, 12545, 12550, 12554, 12558, 12563, 12567, 12572, 12576, 12581, - 12586, 12592, 12598, 12604, 12608, 12613, 12619, 12625, 12629, 12634, - 12638, 12644, 12649, 12652, 12658, 12664, 12669, 12674, 12681, 12686, - 12691, 12695, 12699, 12703, 12707, 12711, 12715, 12719, 12723, 12728, - 12733, 12738, 12744, 12747, 12751, 12755, 12758, 12761, 12764, 12767, - 12770, 12773, 12776, 12779, 12782, 12786, 12793, 12798, 12802, 12806, - 12810, 12814, 0, 12818, 12822, 12826, 12830, 12834, 12840, 12844, 0, - 12848, 12852, 12856, 0, 12860, 12863, 12867, 12870, 12874, 12877, 12881, - 12885, 0, 0, 12889, 12892, 0, 0, 12896, 12899, 12903, 12906, 12910, - 12914, 12918, 12922, 12926, 12930, 12934, 12938, 12942, 12946, 12950, - 12954, 12958, 12962, 12966, 12970, 12974, 12978, 0, 12981, 12984, 12988, - 12992, 12996, 12999, 13002, 0, 13005, 0, 0, 0, 13009, 13013, 13017, - 13020, 0, 0, 13023, 13027, 13031, 13036, 13040, 13045, 13049, 13054, - 13059, 0, 0, 13065, 13069, 0, 0, 13074, 13078, 13083, 13087, 0, 0, 0, 0, - 0, 0, 0, 0, 13093, 0, 0, 0, 0, 13099, 13103, 0, 13107, 13111, 13116, - 13121, 13126, 0, 0, 13132, 13136, 13139, 13142, 13145, 13148, 13151, - 13154, 13157, 13160, 13163, 13172, 13181, 13185, 13189, 13195, 13201, - 13207, 13213, 13227, 13234, 13237, 0, 0, 0, 0, 0, 13241, 13247, 13251, 0, - 13255, 13258, 13262, 13265, 13269, 13272, 0, 0, 0, 0, 13276, 13280, 0, 0, - 13284, 13288, 13292, 13295, 13299, 13303, 13307, 13311, 13315, 13319, - 13323, 13327, 13331, 13335, 13339, 13343, 13347, 13351, 13355, 13359, - 13363, 13367, 0, 13370, 13373, 13377, 13381, 13385, 13388, 13391, 0, - 13394, 13398, 0, 13402, 13406, 0, 13410, 13413, 0, 0, 13416, 0, 13420, - 13425, 13429, 13434, 13438, 0, 0, 0, 0, 13443, 13448, 0, 0, 13453, 13458, - 13463, 0, 0, 0, 13467, 0, 0, 0, 0, 0, 0, 0, 13471, 13475, 13479, 13483, - 0, 13487, 0, 0, 0, 0, 0, 0, 0, 13491, 13495, 13498, 13501, 13504, 13507, - 13510, 13513, 13516, 13519, 13522, 13525, 13528, 13531, 13534, 13539, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13543, 13547, 13551, 0, 13555, 13558, - 13562, 13565, 13569, 13572, 13576, 13580, 13584, 0, 13589, 13592, 13596, - 0, 13601, 13604, 13608, 13611, 13615, 13619, 13623, 13627, 13631, 13635, - 13639, 13643, 13647, 13651, 13655, 13659, 13663, 13667, 13671, 13675, - 13679, 13683, 0, 13686, 13689, 13693, 13697, 13701, 13704, 13707, 0, - 13710, 13714, 0, 13718, 13722, 13726, 13730, 13733, 0, 0, 13736, 13740, - 13744, 13749, 13753, 13758, 13762, 13767, 13772, 13778, 0, 13784, 13788, - 13793, 0, 13799, 13803, 13808, 0, 0, 13812, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 13815, 13820, 13825, 13830, 0, 0, 13836, 13840, 13843, - 13846, 13849, 13852, 13855, 13858, 13861, 13864, 13867, 13871, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13875, 13879, 13883, 0, 13887, 13890, - 13894, 13897, 13901, 13904, 13908, 13912, 0, 0, 13916, 13919, 0, 0, - 13923, 13926, 13930, 13933, 13937, 13941, 13945, 13949, 13953, 13957, - 13961, 13965, 13969, 13973, 13977, 13981, 13985, 13989, 13993, 13997, - 14001, 14005, 0, 14008, 14011, 14015, 14019, 14023, 14026, 14029, 0, - 14032, 14036, 0, 14040, 14044, 14048, 14052, 14055, 0, 0, 14058, 14062, - 14066, 14071, 14075, 14080, 14084, 14089, 14094, 0, 0, 14100, 14104, 0, - 0, 14109, 14113, 14118, 0, 0, 0, 0, 0, 0, 0, 0, 14122, 14128, 0, 0, 0, 0, - 14134, 14138, 0, 14142, 14146, 14151, 14156, 14161, 0, 0, 14167, 14171, - 14174, 14177, 14180, 14183, 14186, 14189, 14192, 14195, 14198, 14201, - 14205, 14211, 14217, 14223, 14229, 14235, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 14241, 14245, 0, 14249, 14252, 14256, 14259, 14263, 14266, 0, 0, 0, - 14270, 14273, 14277, 0, 14281, 14284, 14288, 14292, 0, 0, 0, 14295, - 14299, 0, 14303, 0, 14307, 14311, 0, 0, 0, 14315, 14319, 0, 0, 0, 14323, - 14326, 14330, 0, 0, 0, 14333, 14336, 14339, 14342, 14346, 14350, 14354, - 14358, 14362, 14366, 14370, 14373, 0, 0, 0, 0, 14376, 14381, 14385, - 14390, 14394, 0, 0, 0, 14399, 14403, 14408, 0, 14413, 14417, 14422, - 14427, 0, 0, 14431, 0, 0, 0, 0, 0, 0, 14434, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 14440, 14444, 14447, 14450, 14453, 14456, 14459, 14462, - 14465, 14468, 14471, 14475, 14480, 14485, 14489, 14493, 14497, 14501, - 14505, 14510, 14514, 0, 0, 0, 0, 0, 0, 14517, 14521, 14525, 0, 14529, - 14532, 14536, 14539, 14543, 14546, 14550, 14554, 0, 14558, 14561, 14565, - 0, 14569, 14572, 14576, 14580, 14583, 14587, 14591, 14595, 14599, 14603, - 14607, 14611, 14615, 14619, 14623, 14627, 14631, 14635, 14639, 14643, - 14647, 14651, 14655, 0, 14658, 14661, 14665, 14669, 14673, 14676, 14679, - 14682, 14686, 14690, 0, 14694, 14698, 14702, 14706, 14709, 0, 0, 0, - 14712, 14716, 14721, 14725, 14730, 14734, 14739, 14744, 0, 14750, 14754, - 14759, 0, 14764, 14768, 14773, 14778, 0, 0, 0, 0, 0, 0, 0, 14782, 14786, - 0, 14792, 14796, 0, 0, 0, 0, 0, 0, 14800, 14805, 14810, 14815, 0, 0, - 14821, 14825, 14828, 14831, 14834, 14837, 14840, 14843, 14846, 14849, 0, - 0, 0, 0, 0, 0, 0, 0, 14852, 14865, 14877, 14889, 14901, 14913, 14925, - 14937, 0, 0, 14941, 14945, 0, 14949, 14952, 14956, 14959, 14963, 14966, - 14970, 14974, 0, 14978, 14981, 14985, 0, 14989, 14992, 14996, 15000, - 15003, 15007, 15011, 15015, 15019, 15023, 15027, 15031, 15035, 15039, - 15043, 15047, 15051, 15055, 15059, 15063, 15067, 15071, 15075, 0, 15078, - 15081, 15085, 15089, 15093, 15096, 15099, 15102, 15106, 15110, 0, 15114, - 15118, 15122, 15126, 15129, 0, 0, 15132, 15136, 15140, 15145, 15149, - 15154, 15158, 15163, 15168, 0, 15174, 15178, 15183, 0, 15188, 15192, - 15197, 15202, 0, 0, 0, 0, 0, 0, 0, 15206, 15210, 0, 0, 0, 0, 0, 0, 0, - 15216, 0, 15220, 15225, 15230, 15235, 0, 0, 15241, 15245, 15248, 15251, - 15254, 15257, 15260, 15263, 15266, 15269, 0, 15272, 15276, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15280, 15284, 0, 15288, 15291, 15295, - 15298, 15302, 15305, 15309, 15313, 0, 15317, 15320, 15324, 0, 15328, - 15331, 15335, 15339, 15342, 15346, 15350, 15354, 15358, 15362, 15366, - 15370, 15374, 15378, 15382, 15386, 15390, 15394, 15398, 15402, 15406, - 15410, 15414, 15417, 15421, 15424, 15428, 15432, 15436, 15439, 15442, - 15445, 15449, 15453, 15457, 15461, 15465, 15469, 15473, 15476, 15479, 0, - 0, 15483, 15487, 15492, 15496, 15501, 15505, 15510, 15515, 0, 15521, - 15525, 15530, 0, 15535, 15539, 15544, 15549, 15553, 0, 0, 0, 0, 0, 0, 0, - 0, 15558, 0, 0, 0, 0, 0, 0, 0, 0, 15564, 15569, 15574, 15579, 0, 0, - 15585, 15589, 15592, 15595, 15598, 15601, 15604, 15607, 15610, 15613, - 15616, 15620, 15625, 15630, 15636, 15642, 0, 0, 0, 15648, 15652, 15658, - 15664, 15670, 15675, 15681, 0, 0, 15687, 15691, 0, 15695, 15699, 15703, - 15707, 15711, 15715, 15719, 15723, 15727, 15731, 15735, 15739, 15743, - 15747, 15751, 15755, 15759, 15763, 0, 0, 0, 15767, 15773, 15779, 15785, - 15791, 15797, 15803, 15809, 15815, 15821, 15827, 15833, 15841, 15847, - 15853, 15859, 15865, 15871, 15877, 15883, 15889, 15895, 15901, 15907, 0, - 15913, 15919, 15925, 15931, 15937, 15943, 15947, 15953, 15957, 0, 15961, - 0, 0, 15967, 15971, 15977, 15983, 15989, 15993, 15999, 0, 0, 0, 16003, 0, - 0, 0, 0, 16007, 16012, 16019, 16026, 16033, 16040, 0, 16047, 0, 16054, - 16059, 16064, 16071, 16078, 16087, 16098, 16107, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16112, 16119, 16126, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 16131, 16137, 16143, 16149, 16155, 16161, 16167, 16173, - 16179, 16185, 16191, 16197, 16203, 16209, 16215, 16221, 16227, 16233, - 16239, 16245, 16251, 16257, 16263, 16269, 16275, 16281, 16287, 16293, - 16299, 16305, 16311, 16317, 16323, 16328, 16334, 16340, 16344, 16350, - 16354, 16360, 16366, 16372, 16378, 16384, 16390, 16395, 16401, 16405, - 16410, 16416, 16422, 16428, 16433, 16439, 16445, 16451, 16456, 16462, 0, - 0, 0, 0, 16466, 16472, 16477, 16483, 16488, 16496, 16504, 16508, 16512, - 16516, 16522, 16528, 16534, 16540, 16544, 16548, 16552, 16556, 16560, - 16563, 16566, 16569, 16572, 16575, 16578, 16581, 16584, 16587, 16591, 0, + 0, 33469, 33477, 33485, 33493, 33501, 33511, 33521, 33531, 0, 0, 0, 0, 0, + 0, 0, 0, 33541, 33546, 33551, 33556, 33561, 33570, 33581, 33590, 33601, + 33607, 33620, 33626, 33633, 33640, 33645, 33651, 33657, 33668, 33677, + 33684, 33691, 33700, 33707, 33716, 33726, 33736, 33743, 33750, 33757, + 33767, 33772, 33780, 33786, 33794, 33803, 33808, 33815, 33821, 33826, 0, + 33831, 33837, 0, 0, 0, 0, 0, 0, 33844, 33849, 33855, 33862, 33870, 33876, + 33882, 33888, 33893, 33900, 33906, 33912, 33918, 33926, 33932, 33940, + 33945, 33951, 33957, 33964, 33972, 33979, 33985, 33992, 33999, 34005, + 34012, 34019, 34025, 34030, 34036, 34044, 34053, 34059, 34065, 34071, + 34077, 34085, 34089, 34095, 34101, 34107, 34113, 34119, 34125, 34129, + 34134, 34139, 34146, 34151, 34155, 34161, 34166, 34171, 34175, 34180, + 34185, 34189, 34194, 34199, 34206, 34210, 34215, 34220, 34224, 34229, + 34233, 34238, 34242, 34248, 34253, 34260, 34265, 34270, 34274, 34279, + 34284, 34291, 34296, 34302, 34307, 34312, 34317, 34321, 34326, 34333, + 34340, 34345, 34350, 34354, 34360, 34367, 34372, 34377, 34382, 34388, + 34393, 34399, 34404, 34410, 34416, 34422, 34429, 34436, 34443, 34450, + 34457, 34464, 34469, 34477, 34486, 34495, 34504, 34513, 34522, 34531, + 34543, 34552, 34561, 34570, 34577, 34582, 34589, 34597, 34605, 34612, + 34619, 34626, 34633, 34641, 34650, 34659, 34668, 34677, 34686, 34695, + 34704, 34713, 34722, 34731, 34740, 34749, 34758, 34767, 34775, 34784, + 34795, 34803, 34812, 34823, 34832, 34841, 34850, 34859, 34867, 34876, + 34883, 34888, 34896, 34901, 34908, 34913, 34922, 34928, 34935, 34942, + 34947, 34952, 34960, 34968, 34977, 34986, 34991, 34998, 35009, 35017, + 35026, 35032, 35038, 35043, 35050, 35055, 35064, 35069, 35074, 35079, + 35086, 35093, 35098, 35107, 35115, 35120, 35125, 35132, 35139, 35143, + 35147, 35150, 35153, 35156, 35159, 35162, 35165, 35172, 35175, 35178, + 35183, 35187, 35191, 35195, 35199, 35203, 35212, 35218, 35224, 35230, + 35238, 35246, 35252, 35258, 35265, 35271, 35276, 35282, 35289, 35295, + 35302, 35308, 35316, 35321, 35327, 35333, 35339, 35345, 35351, 35357, + 35363, 35374, 35384, 35390, 35396, 35406, 35412, 35420, 35428, 35436, 0, + 0, 0, 0, 0, 0, 35441, 35448, 35455, 35460, 35469, 35477, 35485, 35492, + 35499, 35506, 35513, 35521, 35529, 35539, 35549, 35557, 35565, 35573, + 35581, 35590, 35599, 35607, 35615, 35624, 35633, 35643, 35653, 35662, + 35671, 35679, 35687, 35695, 35703, 35713, 35723, 35731, 35739, 35747, + 35755, 35763, 35771, 35779, 35787, 35795, 35803, 35811, 35819, 35828, + 35837, 35846, 35855, 35865, 35875, 35882, 35889, 35897, 35905, 35914, + 35923, 35931, 35939, 35951, 35963, 35972, 35981, 35990, 35999, 36006, + 36013, 36021, 36029, 36037, 36045, 36053, 36061, 36069, 36077, 36086, + 36095, 36104, 36113, 36122, 36131, 36141, 36151, 36161, 36171, 36180, + 36189, 36196, 36203, 36211, 36219, 36227, 36235, 36243, 36251, 36263, + 36275, 36284, 36293, 36301, 36309, 36317, 36325, 36336, 36347, 36358, + 36369, 36381, 36393, 36401, 36409, 36417, 36425, 36434, 36443, 36452, + 36461, 36469, 36477, 36485, 36493, 36501, 36509, 36518, 36527, 36537, + 36547, 36555, 36563, 36571, 36579, 36587, 36595, 36602, 36609, 36617, + 36625, 36633, 36641, 36649, 36657, 36665, 36673, 36681, 36689, 36697, + 36705, 36713, 36721, 36729, 36737, 36746, 36755, 36764, 36772, 36781, + 36790, 36799, 36808, 36818, 36827, 36833, 36838, 36845, 36852, 36860, + 36868, 36877, 36886, 36896, 36906, 36917, 36928, 36938, 36948, 36958, + 36968, 36977, 36986, 36996, 37006, 37017, 37028, 37038, 37048, 37058, + 37068, 37075, 37082, 37090, 37098, 37105, 37112, 37121, 37130, 37140, + 37150, 37161, 37172, 37182, 37192, 37202, 37212, 37221, 37230, 37238, + 37246, 37253, 37260, 37268, 37276, 37285, 37294, 37304, 37314, 37325, + 37336, 37346, 37356, 37366, 37376, 37385, 37394, 37404, 37414, 37425, + 37436, 37446, 37456, 37466, 37476, 37483, 37490, 37498, 37506, 37515, + 37524, 37534, 37544, 37555, 37566, 37576, 37586, 37596, 37606, 37614, + 37622, 37630, 37638, 37647, 37656, 37664, 37672, 37679, 37686, 37693, + 37700, 37708, 37716, 37724, 37732, 37743, 37754, 37765, 37776, 37787, + 37798, 37806, 37814, 37825, 37836, 37847, 37858, 37869, 37880, 37888, + 37896, 37907, 37918, 37929, 0, 0, 37940, 37948, 37956, 37967, 37978, + 37989, 0, 0, 38000, 38008, 38016, 38027, 38038, 38049, 38060, 38071, + 38082, 38090, 38098, 38109, 38120, 38131, 38142, 38153, 38164, 38172, + 38180, 38191, 38202, 38213, 38224, 38235, 38246, 38254, 38262, 38273, + 38284, 38295, 38306, 38317, 38328, 38336, 38344, 38355, 38366, 38377, 0, + 0, 38388, 38396, 38404, 38415, 38426, 38437, 0, 0, 38448, 38456, 38464, + 38475, 38486, 38497, 38508, 38519, 0, 38530, 0, 38538, 0, 38549, 0, + 38560, 38571, 38579, 38587, 38598, 38609, 38620, 38631, 38642, 38653, + 38661, 38669, 38680, 38691, 38702, 38713, 38724, 38735, 38743, 38751, + 38759, 38767, 38775, 38783, 38791, 38799, 38807, 38815, 38823, 38831, + 38839, 0, 0, 38847, 38858, 38869, 38883, 38897, 38911, 38925, 38939, + 38953, 38964, 38975, 38989, 39003, 39017, 39031, 39045, 39059, 39070, + 39081, 39095, 39109, 39123, 39137, 39151, 39165, 39176, 39187, 39201, + 39215, 39229, 39243, 39257, 39271, 39282, 39293, 39307, 39321, 39335, + 39349, 39363, 39377, 39388, 39399, 39413, 39427, 39441, 39455, 39469, + 39483, 39491, 39499, 39510, 39518, 0, 39529, 39537, 39548, 39556, 39564, + 39572, 39580, 39588, 39591, 39594, 39597, 39600, 39606, 39617, 39625, 0, + 39636, 39644, 39655, 39663, 39671, 39679, 39687, 39695, 39701, 39707, + 39713, 39721, 39729, 39740, 0, 0, 39751, 39759, 39770, 39778, 39786, + 39794, 0, 39802, 39808, 39814, 39820, 39828, 39836, 39847, 39858, 39866, + 39874, 39882, 39893, 39901, 39909, 39917, 39925, 39933, 39939, 39945, 0, + 0, 39948, 39959, 39967, 0, 39978, 39986, 39997, 40005, 40013, 40021, + 40029, 40037, 40040, 0, 40043, 40047, 40051, 40055, 40059, 40063, 40067, + 40071, 40075, 40079, 40083, 40087, 40093, 40099, 40105, 40108, 40111, + 40113, 40117, 40121, 40125, 40129, 40132, 40136, 40140, 40146, 40152, + 40159, 40166, 40171, 40176, 40182, 40188, 40190, 40193, 40195, 40199, + 40203, 40207, 40211, 40215, 40219, 40223, 40227, 40231, 40237, 40241, + 40245, 40251, 40256, 40263, 40265, 40268, 40272, 40276, 40281, 40287, + 40289, 40298, 40307, 40310, 40314, 40316, 40318, 40320, 40323, 40329, + 40331, 40335, 40339, 40346, 40353, 40357, 40362, 40367, 40372, 40377, + 40381, 40385, 40388, 40392, 40396, 40403, 40408, 40412, 40416, 40421, + 40425, 40429, 40434, 40439, 40443, 40447, 40451, 40453, 40458, 40463, + 40467, 40471, 40475, 40479, 0, 40483, 40487, 40491, 40497, 40503, 40509, + 40515, 40522, 40529, 40534, 40539, 40543, 0, 0, 40549, 40552, 40555, + 40558, 40562, 40565, 40569, 40573, 40577, 40582, 40587, 40592, 40599, + 40603, 40606, 40609, 40612, 40615, 40618, 40621, 40625, 40628, 40632, + 40636, 40640, 40645, 40650, 0, 40655, 40661, 40667, 40673, 40680, 40687, + 40694, 40701, 40707, 40714, 40721, 40728, 40734, 0, 0, 0, 40741, 40744, + 40747, 40750, 40755, 40758, 40761, 40764, 40767, 40770, 40773, 40778, + 40781, 40784, 40787, 40790, 40793, 40798, 40801, 40804, 40807, 40810, + 40813, 40818, 40821, 40824, 40829, 40834, 40838, 40841, 40844, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40847, 40852, 40857, 40864, + 40872, 40877, 40882, 40886, 40890, 40895, 40902, 40909, 40913, 40918, + 40923, 40928, 40933, 40940, 40945, 40950, 40955, 40964, 40971, 40978, + 40982, 40987, 40993, 40998, 41005, 41013, 41021, 41025, 41029, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41033, 41037, 41045, 41049, 41053, + 41058, 41062, 41066, 41070, 41072, 41076, 41080, 41084, 41089, 41093, + 41097, 41105, 41108, 41112, 41115, 41118, 41124, 41128, 41131, 41137, + 41141, 41145, 41149, 41152, 41156, 41159, 41163, 41165, 41168, 41171, + 41175, 41177, 41181, 41184, 41187, 41192, 41197, 41204, 41207, 41210, + 41214, 41219, 41222, 41225, 41228, 41232, 41237, 41241, 41244, 41246, + 41249, 41252, 41255, 41259, 41264, 41267, 41271, 41275, 41279, 41283, + 41288, 41294, 41299, 41304, 41310, 41315, 41320, 41324, 41328, 41333, + 41337, 41341, 41344, 41346, 41351, 41357, 41364, 41371, 41378, 41385, + 41392, 41399, 41406, 41413, 41421, 41428, 41436, 41443, 41450, 41458, + 41466, 41471, 41476, 41481, 41486, 41491, 41496, 41501, 41507, 41512, + 41518, 41524, 41530, 41536, 41542, 41549, 41557, 41564, 41570, 41576, + 41582, 41588, 41594, 41600, 41607, 41613, 41620, 41627, 41634, 41641, + 41648, 41656, 41665, 41673, 41684, 41692, 41700, 41709, 41716, 41725, + 41734, 41742, 41751, 41759, 41763, 0, 0, 0, 0, 41767, 41769, 41771, + 41773, 41775, 41778, 41781, 41785, 41789, 41794, 41799, 41803, 41807, + 41811, 41815, 41820, 41825, 41830, 41835, 41840, 41845, 41850, 41855, + 41860, 41865, 41871, 41875, 41879, 41884, 41889, 41894, 41899, 41903, + 41910, 41917, 41924, 41931, 41938, 41945, 41952, 41959, 41967, 41979, + 41985, 41991, 41998, 42005, 42012, 42019, 42026, 42033, 42040, 42047, + 42052, 42058, 42063, 42068, 42073, 42078, 42083, 42090, 42097, 42102, + 42108, 42113, 42116, 42119, 42122, 42125, 42129, 42133, 42138, 42143, + 42149, 42155, 42159, 42163, 42167, 42171, 42176, 42181, 42185, 42189, + 42193, 42197, 42202, 42207, 42210, 42213, 42216, 42219, 42225, 42232, + 42243, 42253, 42257, 42265, 42272, 42280, 42289, 42293, 42299, 42305, + 42309, 42314, 42319, 42325, 42331, 42337, 42344, 42348, 42352, 42357, + 42360, 42362, 42366, 42370, 42378, 42382, 42384, 42386, 42390, 42398, + 42403, 42409, 42419, 42426, 42431, 42435, 42439, 42443, 42446, 42449, + 42452, 42456, 42460, 42464, 42468, 42472, 42475, 42479, 42483, 42486, + 42488, 42491, 42493, 42497, 42501, 42503, 42509, 42512, 42517, 42521, + 42525, 42527, 42529, 42531, 42534, 42538, 42542, 42546, 42550, 42554, + 42560, 42566, 42568, 42570, 42572, 42574, 42577, 42579, 42583, 42585, + 42589, 42593, 42598, 42602, 42606, 42610, 42614, 42618, 42624, 42628, + 42638, 42648, 42652, 42658, 42665, 42669, 42673, 42676, 42681, 42685, + 42691, 42695, 42708, 42717, 42721, 42725, 42731, 42735, 42738, 42740, + 42743, 42747, 42751, 42758, 42762, 42766, 42770, 42773, 42778, 42783, + 42789, 42795, 42800, 42805, 42813, 42821, 42825, 42829, 42831, 42836, + 42840, 42844, 42852, 42860, 42867, 42874, 42883, 42892, 42898, 42904, + 42912, 42920, 42922, 42924, 42930, 42936, 42943, 42950, 42956, 42962, + 42966, 42970, 42977, 42984, 42991, 42998, 43008, 43018, 43026, 43034, + 43036, 43040, 43044, 43049, 43054, 43062, 43070, 43073, 43076, 43079, + 43082, 43085, 43090, 43094, 43099, 43104, 43107, 43110, 43113, 43116, + 43119, 43123, 43126, 43129, 43132, 43135, 43137, 43139, 43141, 43143, + 43151, 43159, 43165, 43169, 43175, 43185, 43191, 43197, 43203, 43211, + 43220, 43232, 43236, 43240, 43242, 43248, 43250, 43252, 43254, 43256, + 43262, 43265, 43271, 43277, 43281, 43285, 43289, 43292, 43296, 43300, + 43302, 43311, 43320, 43325, 43330, 43336, 43342, 43348, 43351, 43354, + 43357, 43360, 43362, 43367, 43372, 43377, 43383, 43389, 43398, 43407, + 43414, 43421, 43428, 43435, 43445, 43455, 43465, 43475, 43485, 43495, + 43504, 43513, 43522, 43531, 43539, 43551, 43562, 43578, 43581, 43587, + 43593, 43599, 43607, 43622, 43638, 43644, 43650, 43657, 43663, 43672, + 43679, 43693, 43708, 43713, 43719, 43727, 43730, 43733, 43735, 43738, + 43741, 43743, 43745, 43749, 43752, 43755, 43758, 43761, 43766, 43771, + 43776, 43781, 43786, 43789, 43791, 43793, 43795, 43799, 43803, 43807, + 43813, 43818, 43820, 43822, 43827, 43832, 43837, 43842, 43847, 43852, + 43854, 43856, 43866, 43870, 43878, 43887, 43889, 43894, 43899, 43907, + 43911, 43913, 43917, 43919, 43923, 43927, 43931, 43933, 43935, 43937, + 43944, 43953, 43962, 43971, 43980, 43989, 43998, 44007, 44016, 44024, + 44032, 44041, 44050, 44059, 44068, 44076, 44084, 44093, 44102, 44111, + 44121, 44130, 44140, 44149, 44159, 44167, 44176, 44186, 44195, 44205, + 44214, 44224, 44232, 44241, 44250, 44259, 44268, 44277, 44286, 44296, + 44305, 44314, 44323, 44333, 44342, 44351, 44360, 44369, 44379, 44389, + 44398, 44407, 44415, 44424, 44431, 44440, 44449, 44460, 44469, 44479, + 44489, 44496, 44503, 44510, 44519, 44528, 44537, 44546, 44553, 44558, + 44566, 44571, 44574, 44581, 44584, 44589, 44594, 44597, 44600, 44608, + 44611, 44616, 44619, 44627, 44632, 44640, 44643, 44646, 44649, 44654, + 44659, 44662, 44665, 44673, 44676, 44683, 44690, 44694, 44698, 44703, + 44708, 44714, 44719, 44725, 44731, 44736, 44742, 44750, 44756, 44764, + 44772, 44778, 44786, 44794, 44802, 44810, 44816, 44824, 44832, 44840, + 44844, 44850, 44864, 44878, 44882, 44886, 44890, 44894, 44904, 44908, + 44913, 44918, 44924, 44930, 44936, 44942, 44952, 44962, 44970, 44981, + 44992, 45000, 45011, 45022, 45030, 45041, 45052, 45060, 45068, 45078, + 45088, 45091, 45094, 45097, 45102, 45106, 45112, 45119, 45126, 45134, + 45141, 45145, 45149, 45153, 45157, 45159, 45163, 45167, 45172, 45177, + 45184, 45191, 45194, 45201, 45203, 45205, 45209, 45213, 45218, 45224, + 45230, 45236, 45242, 45251, 45260, 45269, 45273, 45275, 45279, 45286, + 45293, 45300, 45307, 45314, 45317, 45322, 0, 0, 0, 0, 0, 45328, 45332, + 45339, 45346, 45353, 45360, 45364, 45368, 45372, 45376, 45382, 45388, + 45393, 45399, 45405, 45411, 45417, 45425, 45432, 45439, 45446, 45453, + 45458, 45464, 45473, 45477, 45484, 45488, 45492, 45498, 45504, 45510, + 45516, 45520, 45524, 45527, 45530, 45534, 45541, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45548, 45551, 45555, + 45559, 45565, 45571, 45577, 45585, 45592, 45596, 45604, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45609, 45612, 45615, 45618, + 45621, 45624, 45627, 45631, 45634, 45638, 45642, 45646, 45650, 45654, + 45658, 45662, 45666, 45670, 45674, 45678, 45682, 45685, 45688, 45691, + 45694, 45697, 45700, 45704, 45707, 45711, 45715, 45719, 45723, 45727, + 45731, 45735, 45739, 45743, 45747, 45751, 45755, 45761, 45767, 45773, + 45780, 45787, 45794, 45801, 45808, 45815, 45822, 45829, 45836, 45843, + 45850, 45857, 45864, 45871, 45878, 45885, 45892, 45897, 45903, 45909, + 45915, 45920, 45926, 45932, 45938, 45943, 45949, 45955, 45960, 45966, + 45972, 45977, 45983, 45989, 45994, 45999, 46005, 46010, 46016, 46022, + 46028, 46034, 46040, 46045, 46051, 46057, 46063, 46068, 46074, 46080, + 46086, 46091, 46097, 46103, 46108, 46114, 46120, 46125, 46131, 46137, + 46142, 46147, 46153, 46158, 46164, 46170, 46176, 46182, 46188, 46193, + 46199, 46205, 46211, 46216, 46222, 46228, 46234, 46239, 46245, 46251, + 46256, 46262, 46268, 46273, 46279, 46285, 46290, 46295, 46301, 46306, + 46312, 46318, 46324, 46330, 46336, 46340, 46345, 46350, 46355, 46360, + 46365, 46370, 46375, 46380, 46385, 46390, 46394, 46398, 46402, 46406, + 46410, 46414, 46419, 46423, 46428, 46433, 46438, 46443, 46448, 46453, + 46458, 46467, 46476, 46485, 46494, 46503, 46512, 46521, 46530, 46537, + 46545, 46553, 46560, 46567, 46575, 46583, 46590, 46597, 46605, 46613, + 46620, 46627, 46635, 46643, 46650, 46657, 46665, 46674, 46683, 46691, + 46700, 46709, 46716, 46723, 46731, 46740, 46749, 46757, 46766, 46775, + 46782, 46789, 46798, 46807, 46816, 46825, 46834, 46843, 46850, 46857, + 46866, 46875, 46884, 46893, 46902, 46911, 46918, 46925, 46934, 46943, + 46952, 46962, 46972, 46981, 46991, 47001, 47011, 47021, 47031, 47041, + 47050, 47059, 47066, 47074, 47082, 47090, 47098, 47103, 47108, 47117, + 47125, 47132, 47141, 47149, 47156, 47165, 47173, 47180, 47189, 47197, + 47204, 47213, 47221, 47228, 47237, 47245, 47252, 47262, 47271, 47278, + 47288, 47297, 47304, 47314, 47323, 47330, 47339, 47348, 47357, 47366, + 47380, 47394, 47401, 47406, 47411, 47416, 47421, 47426, 47431, 47436, + 47441, 47449, 47457, 47465, 47473, 47478, 47485, 47492, 47499, 47504, + 47512, 47519, 47527, 47531, 47538, 47544, 47551, 47555, 47561, 47567, + 47573, 47577, 47580, 47584, 47588, 47595, 47601, 47607, 47613, 47619, + 47633, 47643, 47657, 47671, 47677, 47687, 47701, 47704, 47707, 47714, + 47722, 47728, 47733, 47741, 47753, 47765, 47773, 47777, 47781, 47784, + 47787, 47791, 47795, 47798, 47801, 47806, 47811, 47817, 47823, 47828, + 47833, 47839, 47845, 47850, 47855, 47860, 47865, 47871, 47877, 47882, + 47887, 47893, 47899, 47904, 47909, 47912, 47915, 47924, 47926, 47928, + 47931, 47935, 47941, 47943, 47946, 47953, 47960, 47968, 47976, 47986, + 48000, 48005, 48010, 48014, 48019, 48027, 48035, 48044, 48053, 48062, + 48071, 48076, 48081, 48087, 48093, 48099, 48105, 48108, 48114, 48120, + 48130, 48140, 48148, 48156, 48165, 48174, 48178, 48186, 48194, 48202, + 48210, 48219, 48228, 48237, 48246, 48251, 48256, 48261, 48266, 48271, + 48277, 48283, 48288, 48294, 48296, 48298, 48300, 48302, 48305, 48308, + 48310, 48312, 48314, 48318, 48322, 48324, 48326, 48329, 48332, 48336, + 48342, 48348, 48350, 48357, 48361, 48366, 48371, 48373, 48383, 48389, + 48395, 48401, 48407, 48413, 48419, 48424, 48427, 48430, 48433, 48435, + 48437, 48441, 48445, 48450, 48455, 48460, 48463, 48467, 48472, 48475, + 48479, 48484, 48489, 48494, 48499, 48504, 48509, 48514, 48519, 48524, + 48529, 48534, 48539, 48545, 48551, 48557, 48559, 48562, 48564, 48567, + 48569, 48571, 48573, 48575, 48577, 48579, 48581, 48583, 48585, 48587, + 48589, 48591, 48593, 48595, 48597, 48599, 48601, 48606, 48611, 48616, + 48621, 48626, 48631, 48636, 48641, 48646, 48651, 48656, 48661, 48666, + 48671, 48676, 48681, 48686, 48691, 48696, 48701, 48705, 48709, 48713, + 48719, 48725, 48730, 48735, 48740, 48746, 48752, 48757, 48765, 48773, + 48781, 48789, 48797, 48805, 48813, 48821, 48827, 48832, 48837, 48842, + 48845, 48849, 48853, 48857, 48861, 48865, 48869, 48876, 48883, 48891, + 48899, 48904, 48909, 48916, 48923, 48930, 48937, 48940, 48943, 48948, + 48950, 48954, 48959, 48961, 48963, 48965, 48967, 48972, 48975, 48977, + 48982, 48989, 48996, 48999, 49003, 49008, 49013, 49021, 49027, 49033, + 49045, 49052, 49060, 49065, 49070, 49076, 49079, 49082, 49087, 49089, + 49093, 49095, 49097, 49099, 49101, 49103, 49105, 49110, 49112, 49114, + 49116, 49118, 49122, 49124, 49127, 49132, 49137, 49142, 49147, 49153, + 49159, 49161, 49164, 49171, 49178, 49185, 49192, 49196, 49200, 49202, + 49204, 49208, 49214, 49219, 49221, 49225, 49234, 49242, 49250, 49256, + 49262, 49267, 49273, 49278, 49281, 49295, 49298, 49303, 49308, 49314, + 49324, 49326, 49332, 49338, 49342, 49349, 49353, 49355, 49357, 49361, + 49367, 49372, 49378, 49380, 49386, 49388, 49394, 49396, 49398, 49403, + 49405, 49409, 49414, 49416, 49421, 49426, 49430, 49437, 49447, 49452, + 49458, 49461, 49467, 49470, 49475, 49480, 49484, 49486, 49488, 49492, + 49496, 49500, 49504, 49509, 49511, 49516, 49519, 49522, 49525, 49529, + 49533, 49538, 49542, 49547, 49552, 49556, 49561, 49567, 49570, 49576, + 49581, 49585, 49590, 49596, 49602, 49609, 49615, 49622, 49629, 49631, + 49638, 49642, 49648, 49654, 49659, 49665, 49669, 49674, 49677, 49682, + 49688, 49695, 49703, 49710, 49719, 49729, 49736, 49742, 49746, 49753, + 49758, 49767, 49770, 49773, 49782, 49792, 49799, 49801, 49807, 49812, + 49814, 49817, 49821, 49829, 49838, 49841, 49846, 49851, 49859, 49867, + 49875, 49883, 49889, 49895, 49901, 49909, 49914, 49917, 49921, 49924, + 49936, 49946, 49957, 49966, 49977, 49987, 49996, 50002, 50010, 50014, + 50022, 50026, 50034, 50041, 50048, 50057, 50066, 50076, 50086, 50096, + 50106, 50115, 50124, 50134, 50144, 50153, 50162, 50168, 50174, 50180, + 50186, 50192, 50198, 50205, 50211, 50218, 50225, 50231, 50237, 50243, + 50249, 50255, 50261, 50268, 50274, 50281, 50288, 50295, 50302, 50309, + 50316, 50323, 50330, 50338, 50345, 50353, 50361, 50366, 50369, 50373, + 50377, 50383, 50386, 50391, 50397, 50402, 50406, 50411, 50417, 50424, + 50427, 50434, 50441, 50445, 50453, 50461, 50466, 50472, 50477, 50482, + 50489, 50496, 50504, 50512, 50521, 50525, 50534, 50539, 50543, 50550, + 50554, 50560, 50568, 50573, 50580, 50584, 50589, 50593, 50598, 50602, + 50607, 50612, 50621, 50623, 50626, 50629, 50636, 50643, 50649, 50657, + 50663, 50670, 50675, 50678, 50683, 50688, 50693, 50701, 50705, 50712, + 50720, 50728, 50733, 50738, 50744, 50749, 50754, 50760, 50765, 50768, + 50772, 50776, 50783, 50793, 50798, 50807, 50816, 50822, 50828, 50833, + 50838, 50843, 50848, 50854, 50860, 50868, 50876, 50882, 50888, 50892, + 50896, 50903, 50910, 50916, 50919, 50922, 50926, 50930, 50934, 50939, + 50945, 50951, 50958, 50965, 50970, 50974, 50978, 50982, 50986, 50990, + 50994, 50998, 51002, 51006, 51010, 51014, 51018, 51022, 51026, 51030, + 51034, 51038, 51042, 51046, 51050, 51054, 51058, 51062, 51066, 51070, + 51074, 51078, 51082, 51086, 51090, 51094, 51098, 51102, 51106, 51110, + 51114, 51118, 51122, 51126, 51130, 51134, 51138, 51142, 51146, 51150, + 51154, 51158, 51162, 51166, 51170, 51174, 51178, 51182, 51186, 51190, + 51194, 51198, 51202, 51206, 51210, 51214, 51218, 51222, 51226, 51230, + 51234, 51238, 51242, 51246, 51250, 51254, 51258, 51262, 51266, 51270, + 51274, 51278, 51282, 51286, 51290, 51294, 51298, 51302, 51306, 51310, + 51314, 51318, 51322, 51326, 51330, 51334, 51338, 51342, 51346, 51350, + 51354, 51358, 51362, 51366, 51370, 51374, 51378, 51382, 51386, 51390, + 51394, 51398, 51402, 51406, 51410, 51414, 51418, 51422, 51426, 51430, + 51434, 51438, 51442, 51446, 51450, 51454, 51458, 51462, 51466, 51470, + 51474, 51478, 51482, 51486, 51490, 51494, 51498, 51502, 51506, 51510, + 51514, 51518, 51522, 51526, 51530, 51534, 51538, 51542, 51546, 51550, + 51554, 51558, 51562, 51566, 51570, 51574, 51578, 51582, 51586, 51590, + 51594, 51598, 51602, 51606, 51610, 51614, 51618, 51622, 51626, 51630, + 51634, 51638, 51642, 51646, 51650, 51654, 51658, 51662, 51666, 51670, + 51674, 51678, 51682, 51686, 51690, 51694, 51698, 51702, 51706, 51710, + 51714, 51718, 51722, 51726, 51730, 51734, 51738, 51742, 51746, 51750, + 51754, 51758, 51762, 51766, 51770, 51774, 51778, 51782, 51786, 51790, + 51794, 51798, 51802, 51806, 51810, 51814, 51818, 51822, 51826, 51830, + 51834, 51838, 51842, 51846, 51850, 51854, 51858, 51862, 51866, 51870, + 51874, 51878, 51882, 51886, 51890, 51894, 51898, 51902, 51906, 51910, + 51914, 51918, 51922, 51926, 51930, 51934, 51938, 51942, 51946, 51950, + 51954, 51958, 51962, 51966, 51970, 51974, 51978, 51982, 51986, 51990, + 51994, 52001, 52009, 52015, 52021, 52028, 52035, 52041, 52047, 52053, + 52059, 52063, 52067, 52072, 52077, 52083, 52089, 52097, 52104, 52109, + 52114, 52122, 52131, 52138, 52148, 52159, 52162, 52165, 52169, 52173, + 52180, 52187, 52198, 52209, 52218, 52227, 52233, 52239, 52246, 52253, + 52262, 52272, 52283, 52293, 52303, 52313, 52324, 52335, 52345, 52356, + 52366, 52376, 52385, 52395, 52405, 52415, 52425, 52432, 52439, 52446, + 52453, 52463, 52473, 52481, 52489, 52496, 52503, 52510, 52517, 52524, + 52529, 52534, 52540, 52548, 52557, 52565, 52573, 52581, 52589, 52597, + 52605, 52613, 52621, 52630, 52639, 52648, 52657, 52666, 52675, 52684, + 52693, 52702, 52711, 52720, 52729, 52738, 52747, 52756, 52765, 52779, + 52794, 52808, 52823, 52837, 52851, 52865, 52879, 52889, 52900, 52910, + 52921, 52936, 52951, 52959, 52965, 52972, 52979, 52986, 52993, 52998, + 53004, 53009, 53014, 53020, 53025, 53030, 53035, 53040, 53045, 53052, + 53058, 53066, 53071, 53076, 53080, 53084, 53092, 53100, 53108, 53116, + 53123, 53130, 53143, 53156, 53169, 53182, 53190, 53198, 53204, 53210, + 53217, 53224, 53231, 53238, 53242, 53247, 53255, 53263, 53271, 53278, + 53282, 53290, 53298, 53302, 53306, 53311, 53318, 53326, 53334, 53353, + 53372, 53391, 53410, 53429, 53448, 53467, 53486, 53492, 53499, 53508, + 53516, 53524, 53530, 53533, 53536, 53541, 53544, 53564, 53571, 53577, + 53583, 53587, 53590, 53593, 53596, 53608, 53622, 53629, 53636, 53639, + 53643, 53646, 53651, 53656, 53661, 53667, 53676, 53683, 53690, 53698, + 53705, 53712, 53715, 53721, 53727, 53730, 53733, 53738, 53743, 53749, + 53755, 53759, 53764, 53771, 53775, 53781, 53785, 53789, 53797, 53809, + 53818, 53822, 53824, 53833, 53842, 53848, 53851, 53857, 53863, 53868, + 53873, 53878, 53883, 53888, 53893, 53895, 53901, 53906, 53914, 53918, + 53924, 53927, 53931, 53938, 53945, 53947, 53949, 53955, 53961, 53967, + 53976, 53985, 53992, 53999, 54005, 54012, 54017, 54022, 54027, 54033, + 54039, 54044, 54051, 54055, 54059, 54072, 54085, 54097, 54106, 54112, + 54119, 54124, 54129, 54134, 54139, 54144, 54146, 54153, 54161, 54169, + 54177, 54184, 54192, 54198, 54203, 54209, 54215, 54221, 54228, 54234, + 54242, 54250, 54258, 54266, 54274, 54280, 54286, 54295, 54299, 54308, + 54317, 54326, 54334, 54338, 54344, 54351, 54358, 54362, 54368, 54376, + 54382, 54387, 54393, 54398, 54403, 54410, 54417, 54422, 54427, 54435, + 54443, 54453, 54463, 54470, 54477, 54481, 54485, 54497, 54503, 54510, + 54515, 54520, 54527, 54534, 54540, 54546, 54556, 54563, 54571, 54579, + 54588, 54595, 54601, 54608, 54614, 54622, 54630, 54638, 54646, 54652, + 54657, 54667, 54678, 54685, 54694, 54700, 54705, 54710, 54720, 54727, + 54733, 54739, 54747, 54752, 54759, 54766, 54777, 54784, 54791, 54798, + 54805, 54812, 54820, 54828, 54841, 54854, 54866, 54878, 54892, 54906, + 54912, 54918, 54927, 54936, 54943, 54950, 54959, 54968, 54977, 54986, + 54994, 55002, 55012, 55022, 55036, 55050, 55059, 55068, 55081, 55094, + 55103, 55112, 55123, 55134, 55140, 55146, 55155, 55164, 55169, 55174, + 55182, 55188, 55194, 55202, 55210, 55223, 55236, 55240, 55244, 55252, + 55260, 55267, 55275, 55283, 55292, 55301, 55307, 55313, 55320, 55327, + 55334, 55341, 55350, 55359, 55362, 55365, 55370, 55375, 55381, 55387, + 55394, 55401, 55412, 55423, 55430, 55437, 55445, 55453, 55461, 55469, + 55477, 55485, 55491, 55497, 55501, 55505, 55513, 55521, 55526, 55531, + 55536, 55541, 55547, 55561, 55568, 55575, 55579, 55581, 55583, 55588, + 55593, 55598, 55602, 55610, 55617, 55624, 55632, 55644, 55652, 55660, + 55671, 55675, 55679, 55685, 55693, 55706, 55713, 55720, 55727, 55733, + 55740, 55749, 55758, 55764, 55770, 55776, 55786, 55796, 55804, 55813, + 55818, 55821, 55826, 55831, 55836, 55842, 55848, 55852, 55855, 55858, + 55861, 55866, 55871, 55877, 55883, 55887, 55891, 55898, 55905, 55912, + 55919, 55926, 55933, 55943, 55953, 55960, 55967, 55975, 55983, 55987, + 55992, 55997, 56003, 56009, 56012, 56015, 56018, 56021, 56026, 56031, + 56036, 56041, 56046, 56051, 56055, 56059, 56063, 56068, 56073, 56077, + 56081, 56087, 56091, 56097, 56102, 56109, 56117, 56124, 56132, 56139, + 56147, 56156, 56163, 56173, 56184, 56190, 56199, 56205, 56214, 56223, + 56229, 56235, 56239, 56243, 56252, 56261, 56268, 56275, 56284, 56293, + 56299, 56305, 56312, 56317, 56321, 56325, 56330, 56335, 56340, 56348, + 56356, 56359, 56363, 56372, 56382, 56391, 56401, 56412, 56425, 56429, + 56433, 56437, 56441, 56446, 56451, 56457, 56463, 56470, 56477, 56483, + 56489, 56495, 56501, 56509, 56517, 56524, 56531, 56538, 0, 0, 56545, + 56554, 56563, 56573, 56583, 56592, 56601, 56610, 56619, 56625, 56630, + 56639, 56649, 56658, 56668, 56675, 56682, 56689, 56696, 56701, 56706, + 56711, 56716, 56724, 56733, 56741, 56750, 56754, 56758, 56762, 56766, + 56776, 0, 0, 56779, 56788, 56797, 56806, 56815, 56821, 56827, 56833, + 56839, 56849, 56859, 56869, 56879, 56889, 56899, 56909, 56919, 56926, + 56933, 56940, 56947, 56954, 56961, 56968, 56975, 56981, 56987, 56993, + 56999, 57005, 57011, 57017, 57023, 57034, 0, 0, 0, 57044, 57051, 57054, + 57058, 57062, 57067, 57072, 57077, 57080, 57089, 57098, 57107, 0, 57116, + 57122, 57128, 57136, 57146, 57153, 57162, 57167, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57170, 57179, + 57188, 57197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57206, + 57211, 57216, 57221, 57226, 57231, 57236, 57241, 57246, 57251, 57256, + 57262, 57266, 57271, 57276, 57281, 57286, 57291, 57296, 57301, 57306, + 57311, 57316, 57321, 57326, 57331, 57336, 57341, 57346, 57351, 57356, + 57361, 57366, 57371, 57376, 57382, 57387, 57393, 57402, 57407, 57415, + 57422, 57431, 57436, 57441, 57446, 57452, 0, 57459, 57464, 57469, 57474, + 57479, 57484, 57489, 57494, 57499, 57504, 57509, 57515, 57519, 57524, + 57529, 57534, 57539, 57544, 57549, 57554, 57559, 57564, 57569, 57574, + 57579, 57584, 57589, 57594, 57599, 57604, 57609, 57614, 57619, 57624, + 57629, 57635, 57640, 57646, 57655, 57660, 57668, 57675, 57684, 57689, + 57694, 57699, 57705, 0, 57712, 57720, 57728, 57737, 57744, 57752, 57758, + 57767, 57775, 57783, 57791, 57799, 57807, 57815, 57820, 57827, 57833, + 57840, 57848, 57855, 57862, 57870, 57876, 57882, 57889, 57896, 57906, + 57916, 57923, 57930, 57935, 57945, 57955, 57960, 57965, 57970, 57975, + 57980, 57985, 57990, 57995, 58000, 58005, 58010, 58015, 58020, 58025, + 58030, 58035, 58040, 58045, 58050, 58055, 58060, 58065, 58070, 58075, + 58080, 58085, 58090, 58095, 58100, 58105, 58109, 58113, 58118, 58123, + 58128, 58133, 58138, 58143, 58148, 58153, 58158, 58163, 58168, 58173, + 58178, 58183, 58188, 58193, 58198, 58203, 58210, 58217, 58224, 58231, + 58238, 58245, 58252, 58259, 58266, 58273, 58280, 58287, 58294, 58301, + 58306, 58311, 58318, 58325, 58332, 58339, 58346, 58353, 58360, 58367, + 58374, 58381, 58388, 58395, 58401, 58407, 58413, 58419, 58426, 58433, + 58440, 58447, 58454, 58461, 58468, 58475, 58482, 58489, 58497, 58505, + 58513, 58521, 58529, 58537, 58545, 58553, 58557, 58563, 58569, 58573, + 58579, 58585, 58591, 58598, 58605, 58612, 58619, 58624, 58630, 58636, + 58643, 0, 0, 0, 0, 0, 58650, 58658, 58667, 58676, 58684, 58690, 58695, + 58700, 58705, 58710, 58715, 58720, 58725, 58730, 58735, 58740, 58745, + 58750, 58755, 58760, 58765, 58770, 58775, 58780, 58785, 58790, 58795, + 58800, 58805, 58810, 58815, 58820, 58825, 58830, 58835, 58840, 58845, + 58850, 58855, 58860, 58865, 58870, 58875, 58880, 58885, 0, 58890, 0, 0, + 0, 0, 0, 58895, 0, 0, 58900, 58904, 58909, 58914, 58919, 58924, 58933, + 58938, 58943, 58948, 58953, 58958, 58963, 58968, 58973, 58980, 58985, + 58990, 58999, 59006, 59011, 59016, 59021, 59028, 59033, 59040, 59045, + 59050, 59057, 59064, 59069, 59074, 59079, 59086, 59093, 59098, 59103, + 59108, 59113, 59118, 59125, 59132, 59137, 59142, 59147, 59152, 59157, + 59162, 59167, 59172, 59177, 59182, 59187, 59194, 59199, 59204, 0, 0, 0, + 0, 0, 0, 0, 59209, 59216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 59221, 59226, 59230, 59234, 59238, 59242, 59246, 59250, 59254, 59258, + 59262, 59266, 59272, 59276, 59280, 59284, 59288, 59292, 59296, 59300, + 59304, 59308, 59312, 59316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59320, 59324, + 59328, 59332, 59336, 59340, 59344, 0, 59348, 59352, 59356, 59360, 59364, + 59368, 59372, 0, 59376, 59380, 59384, 59388, 59392, 59396, 59400, 0, + 59404, 59408, 59412, 59416, 59420, 59424, 59428, 0, 59432, 59436, 59440, + 59444, 59448, 59452, 59456, 0, 59460, 59464, 59468, 59472, 59476, 59480, + 59484, 0, 59488, 59492, 59496, 59500, 59504, 59508, 59512, 0, 59516, + 59520, 59524, 59528, 59532, 59536, 59540, 0, 59544, 59549, 59554, 59559, + 59564, 59569, 59574, 59578, 59583, 59588, 59593, 59597, 59602, 59607, + 59612, 59617, 59621, 59626, 59631, 59636, 59641, 59646, 59651, 59655, + 59660, 59665, 59672, 59677, 59682, 59688, 59695, 59702, 59711, 59718, + 59727, 59731, 59735, 59741, 59747, 59753, 59761, 59767, 59771, 59775, + 59779, 59785, 59791, 59795, 59797, 59801, 59807, 59809, 59813, 59816, + 59819, 59825, 59830, 59834, 59838, 59843, 59849, 59854, 59859, 59864, + 59869, 59876, 59883, 59888, 59893, 59898, 59903, 59908, 59913, 59917, + 59921, 59928, 59935, 59941, 59945, 59950, 59953, 59957, 59964, 59968, + 59972, 59976, 59980, 59986, 59992, 59996, 60002, 60006, 60010, 60016, + 60021, 60026, 60028, 60031, 60035, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16595, 16600, 0, 16607, 0, 0, 16614, - 16619, 0, 16624, 0, 0, 16631, 0, 0, 0, 0, 0, 0, 16636, 16641, 16645, - 16652, 0, 16659, 16664, 16669, 16674, 16681, 16688, 16695, 0, 16702, - 16707, 16712, 0, 16719, 0, 16726, 0, 0, 16731, 16738, 0, 16745, 16749, - 16756, 16760, 16765, 16773, 16779, 16785, 16790, 16796, 16802, 16808, - 16813, 0, 16819, 16827, 16834, 0, 0, 16841, 16846, 16852, 16857, 16863, - 0, 16869, 0, 16875, 16882, 16889, 16896, 16903, 16908, 0, 0, 16912, - 16917, 16921, 16925, 16929, 16933, 16937, 16941, 16945, 16949, 0, 0, - 16953, 16959, 16965, 16972, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16979, 16983, 16994, - 17009, 17024, 17034, 17045, 17058, 17069, 17075, 17083, 17093, 17099, - 17107, 17111, 17117, 17123, 17131, 17141, 17149, 17162, 17168, 17176, - 17184, 17196, 17203, 17211, 17219, 17227, 17235, 17243, 17251, 17261, - 17265, 17268, 17271, 17274, 17277, 17280, 17283, 17286, 17289, 17292, - 17296, 17300, 17304, 17308, 17312, 17316, 17320, 17324, 17328, 17333, - 17339, 17349, 17363, 17373, 17379, 17385, 17393, 17401, 17409, 17417, - 17423, 17429, 17432, 17436, 17440, 17444, 17448, 17452, 17456, 0, 17460, - 17464, 17468, 17472, 17476, 17480, 17484, 17488, 17492, 17496, 17500, - 17503, 17506, 17510, 17514, 17518, 17521, 17525, 17529, 17533, 17537, - 17541, 17545, 17549, 17553, 17556, 17559, 17563, 17567, 17571, 17574, - 17577, 17580, 17584, 17589, 17593, 0, 0, 0, 0, 17597, 17602, 17606, - 17611, 17615, 17620, 17625, 17631, 17636, 17642, 17646, 17651, 17655, - 17660, 17670, 17676, 17682, 17689, 17699, 17705, 17709, 17713, 17719, - 17725, 17733, 17739, 17747, 17755, 17763, 17773, 17781, 17791, 17796, - 17802, 17808, 17814, 17820, 17826, 17832, 0, 17838, 17844, 17850, 17856, - 17862, 17868, 17874, 17880, 17886, 17892, 17898, 17903, 17908, 17914, - 17920, 17926, 17931, 17937, 17943, 17949, 17955, 17961, 17967, 17973, - 17979, 17984, 17989, 17995, 18001, 18007, 18012, 18017, 18022, 18028, - 18036, 18043, 0, 18050, 18057, 18070, 18077, 18084, 18092, 18100, 18106, - 18112, 18118, 18128, 18133, 18139, 18149, 18159, 0, 18169, 18179, 18187, - 18199, 18211, 18217, 18231, 18246, 18251, 18256, 18264, 18272, 18280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18288, 18291, 18295, 18299, 18303, - 18307, 18311, 18315, 18319, 18323, 18327, 18331, 18335, 18339, 18343, - 18347, 18351, 18355, 18359, 18363, 18367, 18370, 18373, 18377, 18381, - 18385, 18388, 18391, 18394, 18398, 18402, 18405, 18408, 18412, 18415, - 18420, 18423, 18427, 18430, 18434, 18437, 18442, 18445, 18449, 18456, - 18461, 18465, 18470, 18474, 18479, 18483, 18488, 18495, 18501, 18506, - 18510, 18514, 18518, 18522, 18526, 18531, 18536, 18542, 18547, 18552, - 18556, 18559, 18562, 18565, 18568, 18571, 18574, 18577, 18580, 18583, - 18589, 18593, 18597, 18601, 18605, 18609, 18613, 18617, 18621, 18626, - 18630, 18635, 18640, 18646, 18651, 18657, 18663, 18669, 18675, 18681, - 18688, 18695, 18703, 18711, 18720, 18729, 18740, 18750, 18760, 18771, - 18782, 18792, 18802, 18812, 18822, 18832, 18842, 18852, 18862, 18870, - 18877, 18883, 18890, 18895, 18901, 18907, 18913, 18919, 18925, 18931, - 18936, 18942, 18948, 18954, 18960, 18965, 18973, 18980, 18986, 18993, - 19001, 19007, 19013, 19019, 19025, 19033, 19041, 19051, 19059, 19067, - 19073, 19078, 19083, 19088, 19093, 19098, 19103, 19108, 19113, 19118, - 19124, 19130, 19136, 19143, 19148, 19154, 19159, 19164, 19169, 19174, - 19179, 19184, 19189, 19194, 19199, 19204, 19209, 19214, 19219, 19224, - 19229, 19234, 19239, 19244, 19249, 19254, 19259, 19264, 19269, 19274, - 19279, 19284, 19289, 19294, 19299, 19304, 19309, 19314, 19319, 19324, - 19329, 19334, 19339, 0, 19344, 0, 0, 0, 0, 0, 19349, 0, 0, 19354, 19358, - 19362, 19366, 19370, 19374, 19378, 19382, 19386, 19390, 19394, 19398, - 19402, 19406, 19410, 19414, 19418, 19422, 19426, 19430, 19434, 19438, - 19442, 19446, 19450, 19454, 19458, 19462, 19466, 19470, 19474, 19478, - 19482, 19486, 19490, 19494, 19498, 19502, 19506, 19510, 19514, 19518, - 19524, 19528, 19533, 19538, 19542, 19547, 19552, 19556, 19560, 19564, - 19568, 19572, 19576, 19580, 19584, 19588, 19592, 19596, 19600, 19604, - 19608, 19612, 19616, 19620, 19624, 19628, 19632, 19636, 19640, 19644, - 19648, 19652, 19656, 19660, 19664, 19668, 19672, 19676, 19680, 19684, - 19688, 19692, 19696, 19700, 19704, 19708, 19712, 19716, 19720, 19724, - 19728, 19732, 19736, 19740, 19744, 19748, 19752, 19756, 19760, 19764, - 19768, 19772, 19776, 19780, 19784, 19788, 19792, 19796, 19800, 19804, - 19808, 19812, 19816, 19820, 19824, 19828, 19832, 19836, 19840, 19844, - 19848, 19852, 19856, 19860, 19864, 19868, 19872, 19876, 19880, 19884, - 19888, 19892, 19896, 19900, 19904, 19908, 19912, 19916, 19920, 19924, - 19928, 19932, 19936, 19940, 19943, 19947, 19950, 19954, 19958, 19961, - 19965, 19969, 19972, 19976, 19980, 19984, 19988, 19991, 19995, 19999, - 20003, 20007, 20011, 20015, 20018, 20022, 20026, 20030, 20034, 20038, - 20042, 20046, 20050, 20054, 20058, 20062, 20066, 20070, 20074, 20078, - 20082, 20086, 20090, 20094, 20098, 20102, 20106, 20110, 20114, 20118, - 20122, 20126, 20130, 20134, 20138, 20142, 20146, 20150, 20154, 20158, - 20162, 20166, 20170, 20174, 20178, 20182, 20186, 20190, 20194, 20198, - 20202, 20206, 20210, 20214, 20218, 20222, 20226, 20230, 20234, 20238, - 20242, 20246, 20250, 20254, 20258, 20262, 20266, 20270, 20274, 20278, - 20282, 20286, 20290, 20294, 20298, 20302, 20306, 20310, 20314, 20318, - 20322, 20326, 20330, 20334, 20338, 20342, 20346, 20350, 20354, 20358, - 20362, 20366, 20370, 20374, 20378, 20382, 20386, 20390, 20394, 20398, - 20402, 20406, 20410, 20414, 20418, 20422, 20426, 20430, 20434, 20438, - 20442, 20446, 20450, 20454, 20458, 20462, 20466, 20470, 20474, 20478, - 20482, 20486, 20490, 20494, 20498, 20502, 20506, 20510, 20514, 20518, - 20522, 20526, 20530, 20534, 20538, 20542, 20546, 20550, 20554, 20558, - 20562, 20566, 20570, 20573, 20577, 20581, 20585, 20589, 20593, 20597, - 20601, 20605, 20609, 20613, 20617, 20621, 20625, 20629, 20633, 20637, - 20641, 20645, 20649, 20653, 20657, 20661, 20665, 20668, 20672, 20676, - 20680, 20684, 20688, 20692, 20696, 20700, 20704, 20708, 20712, 20716, - 20720, 20724, 20728, 20731, 20735, 20739, 20743, 20747, 20751, 20755, - 20759, 20762, 20766, 20770, 20774, 20778, 20782, 20786, 20790, 20794, - 20798, 20802, 20806, 20810, 20814, 20818, 20822, 20826, 20830, 20834, - 20838, 20842, 20846, 20850, 20854, 0, 20858, 20862, 20866, 20870, 0, 0, - 20874, 20878, 20882, 20886, 20890, 20894, 20898, 0, 20902, 0, 20906, - 20910, 20914, 20918, 0, 0, 20922, 20926, 20930, 20934, 20938, 20942, - 20946, 20950, 20954, 20958, 20962, 20966, 20970, 20974, 20978, 20982, - 20986, 20990, 20994, 20998, 21002, 21006, 21010, 21013, 21017, 21021, - 21025, 21029, 21033, 21037, 21041, 21045, 21049, 21053, 21057, 21061, - 21065, 21069, 21073, 21077, 21081, 0, 21085, 21089, 21093, 21097, 0, 0, - 21101, 21104, 21108, 21112, 21116, 21120, 21124, 21128, 21132, 21136, - 21140, 21144, 21148, 21152, 21156, 21160, 21164, 21169, 21174, 21179, - 21185, 21191, 21196, 21201, 21207, 21210, 21214, 21218, 21222, 21226, - 21230, 21234, 21238, 0, 21242, 21246, 21250, 21254, 0, 0, 21258, 21262, - 21266, 21270, 21274, 21278, 21282, 0, 21286, 0, 21290, 21294, 21298, - 21302, 0, 0, 21306, 21310, 21314, 21318, 21322, 21326, 21330, 21334, - 21338, 21343, 21348, 21353, 21359, 21365, 21370, 0, 21375, 21379, 21383, - 21387, 21391, 21395, 21399, 21403, 21407, 21411, 21415, 21419, 21423, - 21427, 21431, 21435, 21439, 21442, 21446, 21450, 21454, 21458, 21462, - 21466, 21470, 21474, 21478, 21482, 21486, 21490, 21494, 21498, 21502, - 21506, 21510, 21514, 21518, 21522, 21526, 21530, 21534, 21538, 21542, - 21546, 21550, 21554, 21558, 21562, 21566, 21570, 21574, 21578, 21582, - 21586, 21590, 21594, 21598, 0, 21602, 21606, 21610, 21614, 0, 0, 21618, - 21622, 21626, 21630, 21634, 21638, 21642, 21646, 21650, 21654, 21658, - 21662, 21666, 21670, 21674, 21678, 21682, 21686, 21690, 21694, 21698, - 21702, 21706, 21710, 21714, 21718, 21722, 21726, 21730, 21734, 21738, - 21742, 21746, 21750, 21754, 21758, 21762, 21766, 21770, 21774, 21778, - 21782, 21786, 21790, 21794, 21798, 21802, 21806, 21810, 21814, 21818, - 21822, 21826, 21830, 21834, 21838, 21842, 21845, 21849, 21853, 21857, - 21861, 21865, 21869, 21873, 21877, 21881, 0, 0, 21885, 21894, 21900, - 21905, 21909, 21912, 21917, 21920, 21923, 21926, 21931, 21935, 21940, - 21943, 21946, 21949, 21952, 21955, 21958, 21961, 21964, 21967, 21971, - 21975, 21979, 21983, 21987, 21991, 21995, 21999, 22003, 22007, 0, 0, 0, - 22013, 22019, 22023, 22027, 22031, 22037, 22041, 22045, 22049, 22055, - 22059, 22063, 22067, 22073, 22077, 22081, 22085, 22091, 22097, 22103, - 22111, 22117, 22123, 22129, 22135, 22141, 0, 0, 0, 0, 0, 0, 22147, 22150, - 22153, 22156, 22159, 22162, 22166, 22170, 22173, 22177, 22181, 22185, - 22189, 22193, 22196, 22200, 22204, 22208, 22212, 22216, 22220, 22224, - 22228, 22232, 22236, 22240, 22243, 22247, 22251, 22255, 22259, 22262, - 22266, 22270, 22274, 22278, 22282, 22286, 22290, 22294, 22298, 22302, - 22306, 22310, 22314, 22317, 22321, 22325, 22329, 22333, 22337, 22341, - 22345, 22349, 22353, 22357, 22361, 22365, 22369, 22373, 22377, 22381, - 22385, 22389, 22393, 22397, 22401, 22405, 22409, 22413, 22417, 22421, - 22425, 22429, 22433, 22437, 22441, 22445, 22449, 22453, 22456, 22460, - 22464, 22468, 22472, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22476, 22480, - 22483, 22487, 22490, 22494, 22497, 22501, 22507, 22512, 22516, 22519, - 22523, 22527, 22532, 22536, 22541, 22545, 22550, 22554, 22559, 22563, - 22568, 22574, 22578, 22583, 22587, 22592, 22598, 22602, 22608, 22614, - 22618, 22623, 22631, 22639, 22646, 22651, 22656, 22665, 22672, 22679, - 22684, 22690, 22694, 22698, 22702, 22706, 22710, 22714, 22718, 22722, - 22726, 22730, 22736, 22741, 22746, 22749, 22753, 22757, 22762, 22766, - 22771, 22775, 22780, 22784, 22789, 22793, 22798, 22802, 22807, 22811, - 22816, 22822, 22826, 22831, 22836, 22840, 22844, 22848, 22852, 22855, - 22859, 22865, 22870, 22875, 22879, 22883, 22887, 22892, 22896, 22901, - 22905, 22910, 22913, 22917, 22921, 22926, 22930, 22935, 22939, 22944, - 22950, 22954, 22958, 22962, 22966, 22970, 22974, 22978, 22982, 22986, - 22990, 22994, 23000, 23003, 23007, 23011, 23016, 23020, 23025, 23029, - 23034, 23038, 23043, 23047, 23052, 23056, 23061, 23065, 23070, 23076, - 23080, 23084, 23090, 23096, 23102, 23108, 23112, 23116, 23120, 23124, - 23128, 23132, 23138, 23142, 23146, 23150, 23155, 23159, 23164, 23168, - 23173, 23177, 23182, 23186, 23191, 23195, 23200, 23204, 23209, 23215, - 23219, 23225, 23229, 23233, 23237, 23241, 23245, 23249, 23255, 23258, - 23262, 23266, 23271, 23275, 23280, 23284, 23289, 23293, 23298, 23302, - 23307, 23311, 23316, 23320, 23325, 23331, 23334, 23338, 23342, 23347, - 23352, 23356, 23360, 23364, 23368, 23372, 23376, 23382, 23385, 23389, - 23393, 23398, 23402, 23407, 23411, 23416, 23422, 23426, 23431, 23435, - 23439, 23443, 23447, 23451, 23455, 23459, 23465, 23469, 23473, 23477, - 23482, 23486, 23491, 23495, 23500, 23504, 23509, 23513, 23518, 23522, - 23527, 23531, 23536, 23539, 23543, 23547, 23551, 23555, 23559, 23563, - 23567, 23571, 23577, 23580, 23584, 23588, 23593, 23597, 23602, 23606, - 23611, 23615, 23620, 23624, 23629, 23633, 23638, 23642, 23647, 23653, - 23657, 23663, 23667, 23673, 23679, 23685, 23691, 23697, 23703, 23709, - 23715, 23719, 23723, 23727, 23731, 23735, 23739, 23743, 23747, 23752, - 23756, 23761, 23765, 23770, 23774, 23779, 23783, 23788, 23792, 23797, - 23801, 23806, 23810, 23814, 23818, 23822, 23826, 23830, 23834, 23840, - 23843, 23847, 23851, 23856, 23860, 23865, 23869, 23874, 23878, 23883, - 23887, 23892, 23896, 23901, 23905, 23910, 23916, 23920, 23926, 23931, - 23937, 23941, 23947, 23952, 23956, 23960, 23964, 23968, 23972, 23977, - 23980, 23984, 23989, 23993, 23998, 24001, 24005, 24009, 24013, 24017, - 24021, 24025, 24029, 24033, 24037, 24041, 24045, 24050, 24054, 24058, - 24064, 24068, 24074, 24078, 24084, 24088, 24092, 24096, 24100, 24104, - 24109, 24113, 24117, 24121, 24125, 24129, 24133, 24137, 24141, 24145, - 24149, 24155, 24161, 24167, 24173, 24179, 24184, 24190, 24196, 24202, - 24206, 24210, 24214, 24218, 24222, 24226, 24230, 24234, 24238, 24242, - 24246, 24250, 24254, 24259, 24264, 24269, 24273, 24277, 24281, 24285, - 24289, 24293, 24297, 24301, 24305, 24309, 24315, 24321, 24327, 24333, - 24339, 24345, 24351, 24357, 24363, 24367, 24371, 24375, 24379, 24383, - 24387, 24391, 24397, 24403, 24409, 24415, 24421, 24427, 24433, 24439, - 24445, 24450, 24455, 24460, 24465, 24471, 24477, 24483, 24489, 24495, - 24501, 24507, 24512, 24518, 24524, 24530, 24535, 24541, 24547, 24553, - 24558, 24563, 24568, 24573, 24578, 24583, 24588, 24593, 24598, 24603, - 24608, 24613, 24617, 24622, 24627, 24632, 24637, 24642, 24647, 24652, - 24657, 24662, 24667, 24672, 24677, 24682, 24687, 24692, 24697, 24702, - 24707, 24712, 24717, 24722, 24727, 24732, 24737, 24742, 24747, 24752, - 24757, 24762, 24766, 24771, 24776, 24781, 24786, 24791, 24796, 24801, - 24806, 24811, 24816, 24821, 24826, 24831, 24836, 24841, 24846, 24851, - 24856, 24861, 24866, 24871, 24876, 24881, 24886, 24891, 24895, 24900, - 24905, 24910, 24915, 24920, 24924, 24929, 24934, 24939, 24944, 24949, - 24953, 24958, 24964, 24969, 24974, 24979, 24984, 24990, 24995, 25000, - 25005, 25010, 25015, 25020, 25025, 25030, 25035, 25040, 25045, 25050, - 25055, 25060, 25065, 25070, 25075, 25080, 25085, 25090, 25095, 25100, - 25105, 25110, 25115, 25120, 25125, 25130, 25135, 25140, 25145, 25150, - 25155, 25160, 25165, 25170, 25175, 25180, 25185, 25190, 25195, 25200, - 25205, 25210, 25216, 25221, 25226, 25231, 25236, 25241, 25246, 25251, - 25256, 25261, 25266, 25271, 25275, 25280, 25285, 25290, 25295, 25300, - 25305, 25310, 25315, 25320, 25325, 25330, 25335, 25340, 25345, 25350, - 25355, 25360, 25365, 25370, 25375, 25380, 25385, 25390, 25395, 25400, - 25405, 25411, 25415, 25419, 25423, 25427, 25431, 25435, 25439, 25443, - 25449, 25455, 25461, 25467, 25473, 25479, 25485, 25492, 25498, 25503, - 25508, 25513, 25518, 25523, 25528, 25533, 25538, 25543, 25548, 25553, - 25558, 25563, 25568, 25573, 25578, 25583, 25588, 25593, 25598, 25603, - 25608, 25613, 25618, 25623, 25628, 25633, 25638, 0, 0, 0, 25645, 25655, - 25659, 25666, 25670, 25674, 25678, 25686, 25690, 25695, 25700, 25705, - 25709, 25714, 25719, 25722, 25726, 25730, 25739, 25743, 25747, 25753, - 25757, 25761, 25769, 25773, 25781, 25787, 25793, 25799, 25805, 25815, - 25821, 25825, 25834, 25837, 25843, 25847, 25853, 25858, 25864, 25872, - 25878, 25884, 25892, 25898, 25902, 25906, 25916, 25922, 25926, 25936, - 25942, 25946, 25950, 25957, 25964, 25969, 25974, 25983, 25987, 25991, - 25995, 26003, 26010, 26014, 26018, 26022, 26026, 26030, 26034, 26038, - 26042, 26046, 26050, 26054, 26059, 26064, 26069, 26073, 26077, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26081, 26085, 26089, 26093, 26097, - 26102, 26107, 26112, 26117, 26121, 26125, 26130, 26134, 0, 26138, 26143, - 26148, 26152, 26156, 26161, 26166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 26171, 26175, 26179, 26183, 26187, 26192, 26197, 26202, 26207, 26211, - 26215, 26220, 26224, 26228, 26232, 26237, 26242, 26246, 26250, 26255, - 26260, 26265, 26271, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26276, 26280, 26284, - 26288, 26292, 26297, 26302, 26307, 26312, 26316, 26320, 26325, 26329, - 26333, 26337, 26342, 26347, 26351, 26355, 26360, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 26365, 26369, 26373, 26377, 26381, 26386, 26391, 26396, - 26401, 26405, 26409, 26414, 26418, 0, 26422, 26427, 26432, 0, 26436, - 26441, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26446, 26449, 26453, 26457, - 26461, 26465, 26469, 26473, 26477, 26481, 26485, 26489, 26493, 26497, - 26501, 26505, 26509, 26513, 26516, 26520, 26524, 26528, 26532, 26536, - 26540, 26544, 26548, 26552, 26556, 26560, 26564, 26568, 26571, 26574, - 26578, 26582, 26588, 26594, 26600, 26606, 26612, 26618, 26624, 26630, - 26636, 26642, 26648, 26654, 26660, 26666, 26675, 26684, 26690, 26696, - 26702, 26707, 26711, 26716, 26721, 26726, 26730, 26735, 26740, 26745, - 26749, 26754, 26758, 26763, 26768, 26773, 26778, 26782, 26786, 26790, - 26794, 26798, 26802, 26806, 26810, 26814, 26818, 26824, 26828, 26832, - 26836, 26840, 26844, 26852, 26858, 26862, 26868, 26872, 26878, 26882, 0, - 0, 26886, 26890, 26893, 26896, 26899, 26902, 26905, 26908, 26911, 26914, - 0, 0, 0, 0, 0, 0, 26917, 26925, 26933, 26941, 26949, 26957, 26965, 26973, - 26981, 26989, 0, 0, 0, 0, 0, 0, 26997, 27000, 27003, 27006, 27011, 27014, - 27019, 27026, 27034, 27039, 27046, 27049, 27056, 27063, 27070, 0, 27074, - 27078, 27081, 27084, 27087, 27090, 27093, 27096, 27099, 27102, 0, 0, 0, - 0, 0, 0, 27105, 27108, 27111, 27114, 27117, 27120, 27124, 27128, 27132, - 27135, 27139, 27143, 27146, 27150, 27154, 27157, 27161, 27164, 27168, - 27172, 27176, 27180, 27184, 27187, 27190, 27194, 27198, 27201, 27205, - 27209, 27213, 27217, 27221, 27225, 27229, 27233, 27240, 27245, 27250, - 27255, 27260, 27266, 27272, 27278, 27284, 27289, 27295, 27301, 27306, - 27312, 27318, 27324, 27330, 27336, 27341, 27347, 27352, 27358, 27364, - 27370, 27376, 27382, 27387, 27392, 27398, 27404, 27409, 27415, 27420, - 27426, 27431, 27436, 27442, 27448, 27454, 27460, 27466, 27472, 27478, - 27484, 27490, 27496, 27502, 27508, 27513, 27518, 27523, 27529, 0, 0, 0, - 0, 0, 0, 0, 0, 27535, 27544, 27553, 27561, 27569, 27579, 27587, 27596, - 27603, 27610, 27617, 27625, 27633, 27641, 27649, 27657, 27665, 27673, - 27681, 27688, 27696, 27704, 27712, 27720, 27728, 27738, 27748, 27758, - 27768, 27778, 27788, 27798, 27808, 27818, 27828, 27838, 27848, 27858, - 27868, 27876, 27884, 27894, 27902, 0, 0, 0, 0, 0, 27912, 27916, 27920, - 27924, 27928, 27932, 27936, 27940, 27944, 27948, 27952, 27956, 27960, - 27964, 27968, 27972, 27976, 27980, 27984, 27988, 27992, 27996, 28000, - 28004, 28010, 28014, 28020, 28024, 28030, 28034, 28040, 28044, 28048, - 28052, 28056, 28060, 28064, 28070, 28076, 28082, 28088, 28093, 28099, - 28105, 28111, 28117, 28123, 28129, 28136, 28142, 28147, 28152, 28156, - 28160, 28164, 28168, 28172, 28176, 28180, 28186, 28192, 28198, 28203, - 28210, 28215, 28220, 28226, 28231, 28238, 28245, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 28252, 28258, 28262, 28267, 28272, 28277, 28282, 28287, 28292, - 28297, 28302, 28307, 28312, 28317, 28322, 28327, 28331, 28335, 28340, - 28345, 28350, 28354, 28358, 28362, 28367, 28372, 28377, 28382, 28386, 0, - 0, 0, 28390, 28395, 28400, 28405, 28411, 28417, 28423, 28429, 28434, - 28439, 28445, 28451, 0, 0, 0, 0, 28458, 28463, 28469, 28475, 28481, - 28486, 28491, 28496, 28501, 28507, 28512, 28517, 0, 0, 0, 0, 28522, 0, 0, - 0, 28527, 28532, 28537, 28542, 28546, 28550, 28554, 28558, 28562, 28566, - 28570, 28574, 28578, 28583, 28589, 28595, 28601, 28606, 28611, 28617, - 28623, 28629, 28634, 28640, 28645, 28651, 28657, 28662, 28668, 28674, - 28680, 28685, 28690, 28695, 28701, 28707, 28712, 28718, 28723, 28729, - 28734, 28740, 0, 0, 28746, 28752, 28758, 28764, 28770, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 28776, 28783, 28790, 28796, 28803, 28810, 28816, 28823, - 28830, 28837, 28843, 28849, 28856, 28862, 28868, 28875, 28882, 28888, - 28895, 28902, 28908, 28914, 28921, 28927, 28933, 28940, 28946, 28953, - 28960, 28967, 28974, 28981, 28988, 28994, 29001, 29008, 29014, 29021, - 29028, 29035, 29042, 29049, 29056, 29063, 0, 0, 0, 0, 29070, 29078, - 29085, 29092, 29098, 29105, 29111, 29118, 29124, 29131, 29138, 29145, - 29152, 29159, 29166, 29173, 29180, 29187, 29194, 29201, 29208, 29214, - 29221, 29228, 29235, 29241, 0, 0, 0, 0, 0, 0, 29247, 29253, 29258, 29263, - 29268, 29273, 29278, 29283, 29288, 29293, 29298, 0, 0, 0, 29304, 29310, - 29316, 29320, 29326, 29332, 29338, 29344, 29350, 29356, 29362, 29368, - 29374, 29380, 29386, 29392, 29398, 29404, 29410, 29414, 29420, 29426, - 29432, 29438, 29444, 29450, 29456, 29462, 29468, 29474, 29480, 29486, - 29492, 29498, 29504, 29508, 29513, 29518, 29523, 29527, 29532, 29536, - 29541, 29546, 29551, 29555, 29560, 29565, 29570, 29575, 29580, 29584, - 29588, 29593, 29598, 29602, 29606, 29610, 29615, 29620, 29625, 29630, 0, - 0, 29636, 29640, 29647, 29652, 29658, 29664, 29669, 29675, 29681, 29686, - 29692, 29698, 29704, 29709, 29715, 29720, 29725, 29731, 29736, 29742, - 29747, 29753, 29759, 29765, 29771, 29775, 29780, 29785, 29791, 29797, - 29802, 29808, 29814, 29818, 29823, 29828, 29832, 29837, 29842, 29847, - 29852, 29858, 29864, 29869, 29874, 29879, 29883, 29888, 29892, 29897, - 29901, 29906, 29911, 29916, 29921, 29927, 29933, 29940, 29950, 29959, - 29966, 29972, 29982, 29987, 29993, 0, 29998, 30003, 30008, 30016, 30022, - 30030, 30035, 30041, 30047, 30053, 30058, 30064, 30069, 30076, 30082, - 30087, 30093, 30099, 30105, 30112, 30119, 30126, 30131, 30136, 30143, - 30150, 30157, 30164, 30171, 0, 0, 30178, 30185, 30192, 30198, 30204, - 30210, 30216, 30222, 30228, 30234, 30240, 0, 0, 0, 0, 0, 0, 30246, 30252, - 30257, 30262, 30267, 30272, 30277, 30282, 30287, 30292, 0, 0, 0, 0, 0, 0, - 30297, 30302, 30307, 30312, 30317, 30322, 30327, 30336, 30343, 30348, - 30353, 30358, 30363, 30368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 60041, 60045, 60049, 60054, 60059, 60064, 60068, 60072, 60076, 60081, + 60086, 60090, 60094, 60098, 60102, 60107, 60112, 60117, 60122, 60126, + 60130, 60135, 60140, 60145, 60150, 60154, 0, 60158, 60162, 60166, 60170, + 60174, 60178, 60182, 60187, 60192, 60196, 60201, 60206, 60215, 60219, + 60223, 60227, 60234, 60238, 60243, 60248, 60252, 60256, 60262, 60267, + 60272, 60277, 60282, 60286, 60290, 60294, 60298, 60302, 60307, 60312, + 60316, 60320, 60325, 60330, 60335, 60339, 60343, 60348, 60353, 60359, + 60365, 60369, 60375, 60381, 60385, 60391, 60397, 60402, 60407, 60411, + 60417, 60421, 60425, 60431, 60437, 60442, 60447, 60451, 60455, 60463, + 60469, 60475, 60481, 60486, 60491, 60496, 60502, 60506, 60512, 60516, + 60520, 60526, 60532, 60538, 60544, 60550, 60556, 60562, 60568, 60574, + 60580, 60586, 60592, 60596, 60602, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 60608, 60611, 60615, 60619, 60623, 60627, 60630, 60633, 60637, 60641, + 60645, 60649, 60652, 60657, 60661, 60665, 60669, 60674, 60678, 60682, + 60686, 60690, 60696, 60702, 60706, 60710, 60714, 60718, 60722, 60726, + 60730, 60734, 60738, 60742, 60746, 60752, 60756, 60760, 60764, 60768, + 60772, 60776, 60780, 60784, 60788, 60792, 60796, 60800, 60804, 60808, + 60812, 60816, 60822, 60828, 60833, 60838, 60842, 60846, 60850, 60854, + 60858, 60862, 60866, 60870, 60874, 60878, 60882, 60886, 60890, 60894, + 60898, 60902, 60906, 60910, 60914, 60918, 60922, 60926, 60930, 60934, + 60940, 60944, 60948, 60952, 60956, 60960, 60964, 60968, 60972, 60977, + 60984, 60988, 60992, 60996, 61000, 61004, 61008, 61012, 61016, 61020, + 61024, 61028, 61032, 61039, 61043, 61049, 61053, 61057, 61061, 61065, + 61069, 61072, 61076, 61080, 61084, 61088, 61092, 61096, 61100, 61104, + 61108, 61112, 61116, 61120, 61124, 61128, 61132, 61136, 61140, 61144, + 61148, 61152, 61156, 61160, 61164, 61168, 61172, 61176, 61180, 61184, + 61188, 61192, 61196, 61200, 61206, 61210, 61214, 61218, 61222, 61226, + 61230, 61234, 61238, 61242, 61246, 61250, 61254, 61258, 61262, 61266, + 61270, 61274, 61278, 61282, 61286, 61290, 61294, 61298, 61302, 61306, + 61310, 61314, 61322, 61326, 61330, 61334, 61338, 61342, 61348, 61352, + 61356, 61360, 61364, 61368, 61372, 61376, 61380, 61384, 61388, 61392, + 61396, 61400, 61406, 61410, 61414, 61418, 61422, 61426, 61430, 61434, + 61438, 61442, 61446, 61450, 61454, 61458, 61462, 61466, 61470, 61474, + 61478, 61482, 61486, 61490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61494, 61503, 61511, 61522, 61532, + 61540, 61549, 61558, 61568, 61580, 61592, 61604, 0, 0, 0, 0, 61610, + 61613, 61616, 61621, 61624, 61631, 61635, 61639, 61643, 61647, 61651, + 61656, 61661, 61665, 61669, 61674, 61679, 61684, 61689, 61692, 61695, + 61701, 61707, 61712, 61717, 61724, 61731, 61735, 61739, 61743, 61751, + 61757, 61764, 61769, 61774, 61779, 61784, 61789, 61794, 61799, 61805, + 61810, 61816, 61821, 61826, 61831, 61836, 61842, 61847, 61851, 61857, + 61868, 61878, 61893, 61903, 61907, 61917, 61923, 61929, 61935, 61940, + 61943, 61948, 61952, 0, 61958, 61962, 61965, 61969, 61972, 61976, 61979, + 61983, 61986, 61990, 61993, 61996, 62000, 62004, 62008, 62012, 62016, + 62020, 62024, 62028, 62032, 62036, 62040, 62044, 62048, 62052, 62056, + 62060, 62064, 62068, 62072, 62076, 62080, 62084, 62088, 62093, 62097, + 62101, 62105, 62109, 62112, 62116, 62120, 62124, 62128, 62132, 62136, + 62139, 62143, 62146, 62150, 62154, 62158, 62162, 62166, 62170, 62174, + 62178, 62182, 62186, 62190, 62194, 62197, 62201, 62205, 62209, 62213, + 62217, 62220, 62225, 62229, 62234, 62238, 62242, 62246, 62250, 62254, + 62258, 62263, 62267, 62271, 62275, 62279, 62283, 62287, 62291, 0, 0, + 62296, 62304, 62312, 62319, 62326, 62330, 62336, 62341, 62346, 62350, + 62353, 62357, 62360, 62364, 62367, 62371, 62374, 62378, 62381, 62384, + 62388, 62392, 62396, 62400, 62404, 62408, 62412, 62416, 62420, 62424, + 62428, 62432, 62436, 62440, 62444, 62448, 62452, 62456, 62460, 62464, + 62468, 62472, 62476, 62481, 62485, 62489, 62493, 62497, 62500, 62504, + 62508, 62512, 62516, 62520, 62524, 62527, 62531, 62534, 62538, 62542, + 62546, 62550, 62554, 62558, 62562, 62566, 62570, 62574, 62578, 62582, + 62585, 62589, 62593, 62597, 62601, 62605, 62608, 62613, 62617, 62622, + 62626, 62630, 62634, 62638, 62642, 62646, 62651, 62655, 62659, 62663, + 62667, 62671, 62675, 62679, 62684, 62688, 62692, 62696, 62700, 62704, + 62711, 62715, 62721, 0, 0, 0, 0, 0, 62726, 62731, 62736, 62741, 62746, + 62751, 62756, 62761, 62765, 62770, 62775, 62780, 62785, 62790, 62795, + 62800, 62805, 62810, 62814, 62819, 62824, 62828, 62832, 62836, 62840, + 62845, 62850, 62855, 62860, 62865, 62870, 62875, 62880, 62885, 62890, + 62894, 62898, 62903, 62908, 62913, 62918, 0, 0, 0, 62923, 62927, 62931, + 62935, 62939, 62943, 62947, 62951, 62955, 62959, 62963, 62967, 62971, + 62975, 62979, 62983, 62987, 62991, 62995, 62999, 63003, 63007, 63011, + 63015, 63019, 63023, 63027, 63031, 63035, 63039, 63043, 63046, 63050, + 63053, 63057, 63061, 63064, 63068, 63072, 63075, 63079, 63083, 63087, + 63091, 63094, 63098, 63102, 63106, 63110, 63114, 63118, 63121, 63124, + 63128, 63132, 63136, 63140, 63144, 63148, 63152, 63156, 63160, 63164, + 63168, 63172, 63176, 63180, 63184, 63188, 63192, 63196, 63200, 63204, + 63208, 63212, 63216, 63220, 63224, 63228, 63232, 63236, 63240, 63244, + 63248, 63252, 63256, 63260, 63264, 63268, 63272, 63276, 63280, 63284, + 63288, 0, 63292, 63298, 63304, 63309, 63314, 63319, 63325, 63331, 63336, + 63342, 63348, 63354, 63360, 63366, 63372, 63378, 63384, 63389, 63394, + 63399, 63404, 63409, 63414, 63419, 63424, 63429, 63434, 63439, 63444, + 63449, 63454, 63459, 63464, 63469, 63474, 63479, 63484, 63490, 63496, + 63502, 63508, 63513, 63518, 0, 0, 0, 0, 0, 63523, 63528, 63533, 63538, + 63543, 63548, 63553, 63558, 63563, 63568, 63573, 63578, 63583, 63588, + 63593, 63598, 63603, 63608, 63612, 63617, 63622, 63627, 63632, 63637, + 63642, 63647, 63652, 63657, 63662, 63667, 63672, 63677, 63682, 63687, + 63692, 63697, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63702, 63707, 63712, + 63717, 63721, 63726, 63730, 63735, 63740, 63745, 63750, 63755, 63760, + 63765, 63770, 63775, 63780, 63784, 63788, 63792, 63796, 63800, 63804, + 63808, 63812, 63816, 63820, 63824, 63828, 63832, 63836, 63841, 63846, + 63851, 63856, 63861, 63866, 63871, 63876, 63881, 63886, 63891, 63896, + 63901, 63906, 63911, 63917, 0, 63924, 63927, 63930, 63933, 63936, 63939, + 63942, 63946, 63949, 63953, 63957, 63961, 63965, 63969, 63973, 63977, + 63981, 63985, 63989, 63993, 63997, 64001, 64005, 64009, 64013, 64017, + 64021, 64025, 64029, 64033, 64037, 64041, 64045, 64049, 64053, 64057, + 64061, 64065, 64069, 64073, 64077, 64086, 64095, 64104, 64113, 64122, + 64131, 64140, 64149, 64152, 64157, 64162, 64167, 64172, 64177, 64182, + 64188, 64193, 64199, 64203, 64208, 64213, 64218, 64223, 64228, 64232, + 64236, 64240, 64244, 64248, 64252, 64256, 64260, 64264, 64268, 64272, + 64276, 64280, 64284, 64289, 64294, 64299, 64304, 64309, 64314, 64319, + 64324, 64329, 64334, 64339, 64344, 64349, 64354, 64360, 64366, 64371, + 64376, 64379, 64382, 64385, 64388, 64391, 64394, 64398, 64401, 64405, + 64409, 64413, 64417, 64421, 64425, 64429, 64433, 64437, 64441, 64445, + 64449, 64453, 64457, 64461, 64465, 64469, 64473, 64477, 64481, 64485, + 64489, 64493, 64497, 64501, 64505, 64509, 64513, 64517, 64521, 64525, + 64529, 64533, 64537, 64541, 64545, 64549, 64553, 64557, 64561, 64565, + 64570, 64576, 64581, 64587, 64591, 64596, 64601, 64606, 64611, 64616, + 64621, 64627, 64632, 64638, 64642, 64649, 64656, 64663, 64670, 64677, + 64684, 64691, 64698, 64705, 64712, 64719, 64726, 64729, 64732, 64735, + 64740, 64743, 64746, 64749, 64752, 64755, 64758, 64762, 64766, 64770, + 64774, 64778, 64782, 64786, 64790, 64794, 64798, 64802, 64806, 64810, + 64813, 64817, 64821, 64825, 64829, 64833, 64836, 64840, 64844, 64848, + 64852, 64855, 64859, 64863, 64867, 64871, 64874, 64878, 64882, 64886, + 64890, 64894, 64898, 64902, 64906, 64910, 64914, 0, 64918, 64921, 64924, + 64927, 64930, 64933, 64936, 64939, 64942, 64945, 64948, 64951, 64954, + 64957, 64960, 64963, 64966, 64969, 64972, 64975, 64978, 64981, 64984, + 64987, 64990, 64993, 64996, 64999, 65002, 65005, 65008, 65011, 65014, + 65017, 65020, 65023, 65026, 65029, 65032, 65035, 65038, 65041, 65044, + 65047, 65050, 65053, 65056, 65059, 65062, 65065, 65068, 65071, 65074, + 65077, 65080, 65083, 65086, 65089, 65092, 65095, 65098, 65101, 65104, + 65107, 65110, 65113, 65116, 65119, 65122, 65125, 65128, 65131, 65134, + 65137, 65140, 65143, 65146, 65149, 65152, 65155, 65158, 65161, 65164, + 65167, 65170, 65173, 65176, 65179, 65182, 65191, 65199, 65207, 65215, + 65223, 65231, 65239, 65248, 65256, 65265, 65274, 65283, 65292, 65301, + 65310, 65319, 65328, 65337, 65346, 65355, 65364, 65373, 65382, 65391, + 65400, 65403, 65406, 65409, 65411, 65414, 65417, 65420, 65425, 65430, + 65433, 65440, 65447, 65454, 65461, 65464, 65469, 65472, 65476, 65478, + 65480, 65483, 65486, 65489, 65492, 65495, 65498, 65501, 65506, 65511, + 65514, 65517, 65520, 65523, 65526, 65529, 65532, 65536, 65539, 65542, + 65545, 65548, 65551, 65556, 65559, 65562, 65565, 65570, 65575, 65580, + 65585, 65590, 65595, 65600, 65605, 65610, 65618, 65620, 65623, 65626, + 65629, 65632, 65637, 65645, 65648, 65651, 65655, 65658, 65661, 65664, + 65669, 65672, 65675, 65680, 65683, 65686, 65691, 65694, 65697, 65702, + 65707, 65712, 65715, 65718, 65721, 65724, 65730, 65733, 65736, 65739, + 65741, 65744, 65747, 65750, 65755, 65758, 65761, 65764, 65767, 65770, + 65775, 65778, 65781, 65784, 65787, 65790, 65793, 65796, 65799, 65802, + 65808, 65813, 65821, 65829, 65837, 65845, 65853, 65861, 65870, 65878, + 65887, 65896, 65905, 65914, 65923, 65932, 65941, 65950, 65959, 65968, + 65977, 65986, 65995, 66004, 66013, 66022, 66031, 66040, 66049, 66058, + 66067, 66076, 66085, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30373, 30379, - 30385, 30389, 30393, 30397, 30401, 30407, 30411, 30417, 30421, 30427, - 30433, 30441, 30447, 30455, 30459, 30463, 30467, 30473, 30476, 30482, - 30486, 30492, 30496, 30500, 30506, 30510, 30516, 30520, 30526, 30534, - 30542, 30550, 30556, 30560, 30566, 30570, 30576, 30579, 30582, 30588, - 30592, 30598, 30601, 30604, 30607, 30611, 30615, 30621, 30627, 30630, - 30633, 30637, 30642, 30647, 30654, 30659, 30666, 30673, 30682, 30689, - 30698, 30703, 30710, 30717, 30726, 30731, 30738, 30743, 30749, 30755, - 30761, 30767, 30773, 30779, 0, 0, 0, 0, 30785, 30789, 30792, 30795, - 30798, 30801, 30804, 30807, 30810, 30813, 30816, 30819, 30822, 30825, - 30830, 30835, 30840, 30843, 30848, 30853, 30858, 30863, 30870, 30875, - 30880, 30885, 30890, 30897, 30903, 30909, 30915, 30921, 30927, 30936, - 30945, 30951, 30957, 30965, 30973, 30982, 30991, 30999, 31007, 31016, - 31025, 0, 0, 0, 31033, 31037, 31041, 31045, 31048, 31051, 31054, 31058, - 31061, 31064, 31068, 31071, 31075, 31079, 31083, 31087, 31091, 31095, - 31099, 31103, 31107, 31110, 31113, 31117, 31121, 31125, 31128, 31131, - 31134, 31138, 31142, 31145, 31149, 31152, 31157, 31162, 31167, 31172, - 31177, 31182, 31187, 31192, 31197, 31201, 31205, 31211, 31218, 31222, - 31226, 31230, 31233, 31236, 31239, 31242, 31245, 31248, 31251, 31254, - 31257, 31260, 31264, 31268, 31272, 31277, 31281, 31285, 31291, 31295, - 31301, 31307, 31312, 31319, 31323, 31329, 31333, 31339, 31344, 31351, - 31358, 31363, 31370, 31375, 31380, 31384, 31390, 31394, 31400, 31407, - 31414, 31418, 31424, 31430, 31434, 31440, 31445, 31450, 31457, 31462, - 31467, 31472, 31477, 31481, 31485, 31490, 31495, 31502, 31508, 31513, - 31520, 31525, 31532, 31537, 31546, 31552, 31558, 31562, 0, 0, 0, 0, 0, 0, - 0, 0, 31566, 31575, 31582, 31589, 31596, 31599, 31603, 31607, 31611, - 31615, 31619, 31623, 31627, 31631, 31635, 31639, 31643, 31647, 31650, - 31653, 31657, 31661, 31665, 31669, 31673, 31677, 31680, 31684, 31688, - 31692, 31696, 31699, 31702, 31706, 31709, 31713, 31717, 31720, 31724, - 31728, 31731, 31736, 31741, 31746, 31750, 31754, 31759, 31763, 31768, - 31772, 31777, 31781, 31785, 31790, 31795, 31799, 31804, 31809, 31814, - 31818, 0, 0, 0, 31822, 31827, 31836, 31841, 31848, 31853, 31857, 31860, - 31863, 31866, 31869, 31872, 31875, 31878, 31881, 0, 0, 0, 31884, 31888, - 31892, 31896, 31903, 31909, 31915, 31921, 31927, 31933, 31939, 31945, - 31951, 31957, 31964, 31971, 31978, 31985, 31992, 31999, 32006, 32013, - 32020, 32027, 32034, 32041, 32048, 32055, 32062, 32069, 32076, 32083, - 32090, 32097, 32104, 32111, 32118, 32125, 32132, 32139, 32146, 32153, - 32160, 32167, 32175, 32183, 32191, 32197, 32203, 32209, 32217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32226, 32233, 32240, 32247, 32254, - 32263, 32272, 32281, 0, 0, 0, 0, 0, 0, 0, 0, 32290, 32295, 32300, 32305, - 32310, 32319, 32330, 32339, 32350, 32356, 32369, 32375, 32382, 32389, - 32394, 32400, 32406, 32417, 32426, 32433, 32440, 32449, 32456, 32465, - 32475, 32485, 32492, 32499, 32506, 32516, 32521, 32529, 32535, 32543, - 32552, 32557, 32564, 32570, 32575, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32580, - 32585, 32591, 32598, 32606, 32612, 32618, 32624, 32629, 32636, 32642, - 32648, 32654, 32662, 32667, 32675, 32680, 32686, 32692, 32699, 32707, - 32714, 32720, 32727, 32734, 32740, 32747, 32754, 32760, 32765, 32771, - 32779, 32787, 32793, 32799, 32805, 32811, 32819, 32823, 32829, 32835, - 32841, 32847, 32853, 32859, 32863, 32868, 32873, 32880, 32885, 32889, - 32895, 32900, 32905, 32909, 32914, 32919, 32923, 32927, 32932, 32939, - 32943, 32948, 32953, 32957, 32962, 32966, 32971, 32975, 32981, 32986, - 32993, 32998, 33003, 33007, 33012, 33017, 33024, 33029, 33035, 33040, - 33044, 33049, 33053, 33058, 33065, 33072, 33077, 33082, 33086, 33092, - 33098, 33103, 33108, 33113, 33119, 33124, 33130, 33135, 33141, 33147, - 33153, 33160, 33167, 33174, 33181, 33188, 33195, 33200, 33208, 33217, - 33226, 33235, 33244, 33253, 33262, 33274, 33283, 33292, 33301, 33308, - 33313, 33320, 33328, 33336, 33343, 33350, 33357, 33364, 33372, 33381, - 33390, 33399, 33408, 33417, 33426, 33435, 33444, 33453, 33462, 33471, - 33480, 33489, 33498, 33506, 33515, 33526, 33534, 33543, 33554, 33563, - 33572, 33581, 33590, 33598, 33607, 33614, 33619, 33627, 33632, 33639, - 33644, 33653, 33659, 33666, 33673, 33678, 33683, 33691, 33699, 33708, - 33717, 33722, 33729, 33740, 33748, 33757, 33763, 33769, 33774, 33781, - 33786, 33795, 33800, 33805, 33810, 33817, 33824, 33829, 33838, 33846, - 33851, 33856, 33863, 33870, 33874, 33878, 33881, 33884, 33887, 33890, - 33893, 33896, 33903, 33906, 33909, 33914, 33918, 33922, 33926, 33930, - 33934, 33943, 33949, 33955, 33961, 33969, 33977, 33983, 33989, 33996, - 34002, 34007, 34013, 34019, 34025, 34032, 34038, 34046, 34052, 34059, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34065, 34072, - 34079, 34084, 34093, 34101, 34109, 34116, 34123, 34130, 34137, 34145, - 34153, 34163, 34173, 34181, 34189, 34197, 34205, 34214, 34223, 34231, - 34239, 34248, 34257, 34267, 34277, 34286, 34295, 34303, 34311, 34319, - 34327, 34337, 34347, 34355, 34363, 34371, 34379, 34387, 34395, 34403, - 34411, 34419, 34427, 34435, 34443, 34452, 34461, 34470, 34479, 34489, - 34499, 34506, 34513, 34521, 34529, 34538, 34547, 34555, 34563, 34575, - 34587, 34596, 34605, 34614, 34623, 34630, 34637, 34645, 34653, 34661, - 34669, 34677, 34685, 34693, 34701, 34710, 34719, 34728, 34737, 34746, - 34755, 34765, 34775, 34785, 34795, 34804, 34813, 34820, 34827, 34835, - 34843, 34851, 34859, 34867, 34875, 34887, 34899, 34908, 34917, 34925, - 34933, 34941, 34949, 34960, 34971, 34982, 34993, 35005, 35017, 35025, - 35033, 35041, 35049, 35058, 35067, 35076, 35085, 35093, 35101, 35109, - 35117, 35125, 35133, 35142, 35151, 35161, 35171, 35178, 35185, 35193, - 35201, 35209, 35217, 35224, 35231, 35239, 35247, 35255, 35263, 35271, - 35279, 35287, 35295, 35303, 35311, 35319, 35327, 35335, 35343, 35351, - 35359, 35368, 35377, 35386, 35394, 35403, 35412, 35421, 35430, 35440, - 35449, 35456, 35461, 35468, 35475, 35483, 35491, 35500, 35509, 35519, - 35529, 35540, 35551, 35560, 35569, 35579, 35589, 35598, 35607, 35617, - 35627, 35638, 35649, 35658, 35667, 35677, 35687, 35694, 35701, 35709, - 35717, 35723, 35729, 35738, 35747, 35757, 35767, 35778, 35789, 35798, - 35807, 35817, 35827, 35836, 35845, 35853, 35861, 35868, 35875, 35883, - 35891, 35900, 35909, 35919, 35929, 35940, 35951, 35960, 35969, 35979, - 35989, 35998, 36007, 36017, 36027, 36038, 36049, 36058, 36067, 36077, - 36087, 36094, 36101, 36109, 36117, 36126, 36135, 36145, 36155, 36166, - 36177, 36186, 36195, 36205, 36215, 36223, 36231, 36239, 36247, 36256, - 36265, 36272, 36279, 36286, 36293, 36300, 36307, 36315, 36323, 36331, - 36339, 36350, 36361, 36372, 36383, 36394, 36405, 36413, 36421, 36432, - 36443, 36454, 36465, 36476, 36487, 36495, 36503, 36514, 36525, 36536, 0, - 0, 36547, 36555, 36563, 36574, 36585, 36596, 0, 0, 36607, 36615, 36623, - 36634, 36645, 36656, 36667, 36678, 36689, 36697, 36705, 36716, 36727, - 36738, 36749, 36760, 36771, 36779, 36787, 36798, 36809, 36820, 36831, - 36842, 36853, 36861, 36869, 36880, 36891, 36902, 36913, 36924, 36935, - 36943, 36951, 36962, 36973, 36984, 0, 0, 36995, 37003, 37011, 37022, - 37033, 37044, 0, 0, 37055, 37063, 37071, 37082, 37093, 37104, 37115, - 37126, 0, 37137, 0, 37145, 0, 37156, 0, 37167, 37178, 37186, 37194, - 37205, 37216, 37227, 37238, 37249, 37260, 37268, 37276, 37287, 37298, - 37309, 37320, 37331, 37342, 37350, 37358, 37366, 37374, 37382, 37390, - 37398, 37406, 37414, 37422, 37430, 37438, 37446, 0, 0, 37454, 37465, - 37476, 37490, 37504, 37518, 37532, 37546, 37560, 37571, 37582, 37596, - 37610, 37624, 37638, 37652, 37666, 37677, 37688, 37702, 37716, 37730, - 37744, 37758, 37772, 37783, 37794, 37808, 37822, 37836, 37850, 37864, - 37878, 37889, 37900, 37914, 37928, 37942, 37956, 37970, 37984, 37995, - 38006, 38020, 38034, 38048, 38062, 38076, 38090, 38098, 38106, 38117, - 38125, 0, 38136, 38144, 38155, 38163, 38171, 38179, 38187, 38195, 38198, - 38201, 38204, 38207, 38213, 38224, 38232, 0, 38243, 38251, 38262, 38270, - 38278, 38286, 38294, 38302, 38308, 38314, 38320, 38328, 38336, 38347, 0, - 0, 38358, 38366, 38377, 38385, 38393, 38401, 0, 38409, 38415, 38421, - 38427, 38435, 38443, 38454, 38465, 38473, 38481, 38489, 38500, 38508, - 38516, 38524, 38532, 38540, 38546, 38552, 0, 0, 38555, 38566, 38574, 0, - 38585, 38593, 38604, 38612, 38620, 38628, 38636, 38644, 38647, 0, 38650, - 38654, 38658, 38662, 38666, 38670, 38674, 38678, 38682, 38686, 38690, - 38694, 38700, 38706, 38712, 38715, 38718, 38720, 38724, 38728, 38732, - 38736, 38738, 38742, 38746, 38752, 38758, 38765, 38772, 38777, 38782, - 38788, 38794, 38796, 38799, 38801, 38805, 38809, 38813, 38816, 38820, - 38824, 38828, 38832, 38836, 38842, 38846, 38850, 38856, 38861, 38868, - 38870, 38873, 38877, 38881, 38886, 38892, 38894, 38903, 38912, 38915, - 38919, 38921, 38923, 38925, 38928, 38934, 38936, 38940, 38944, 38951, - 38958, 38962, 38967, 38972, 38977, 38982, 38986, 38990, 38993, 38997, - 39001, 39008, 39013, 39017, 39021, 39026, 39030, 39034, 39039, 39044, - 39048, 39052, 39056, 39058, 39063, 39068, 39072, 39076, 39080, 39084, 0, - 39088, 39092, 39096, 39102, 39108, 39114, 39120, 39127, 39134, 39139, - 39144, 39148, 0, 0, 39154, 39157, 39160, 39163, 39166, 39169, 39172, - 39176, 39180, 39185, 39190, 39195, 39202, 39206, 39209, 39212, 39215, - 39218, 39221, 39224, 39227, 39230, 39233, 39237, 39241, 39246, 39251, 0, - 39256, 39262, 39268, 39274, 39281, 39288, 39295, 39302, 39308, 39314, - 39321, 39328, 39335, 0, 0, 0, 39342, 39345, 39348, 39351, 39356, 39359, - 39362, 39365, 39368, 39371, 39374, 39378, 39381, 39384, 39387, 39390, - 39393, 39398, 39401, 39404, 39407, 39410, 39413, 39418, 39421, 39424, - 39429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 39434, 39439, 39444, 39451, 39459, 39464, 39469, 39473, 39477, 39482, - 39489, 39496, 39500, 39505, 39510, 39515, 39520, 39527, 39532, 39537, - 39542, 39551, 39558, 39565, 39569, 39574, 39580, 39585, 39592, 39601, - 39610, 39614, 39618, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39622, - 39626, 39634, 39638, 39642, 39647, 39651, 39655, 39659, 39661, 39665, - 39669, 39673, 39678, 39682, 39686, 39694, 39697, 39701, 39704, 39707, - 39713, 39717, 39720, 39726, 39730, 39734, 39738, 39741, 39745, 39748, - 39752, 39754, 39757, 39760, 39764, 39766, 39770, 39773, 39776, 39781, - 39786, 39793, 39796, 39799, 39803, 39808, 39811, 39814, 39817, 39821, - 39826, 39829, 39832, 39834, 39837, 39840, 39843, 39847, 39852, 39855, - 39859, 39863, 39867, 39871, 39876, 39882, 39887, 39892, 39898, 39903, - 39908, 39912, 39916, 39921, 39925, 39929, 39932, 39934, 39939, 39945, - 39952, 39959, 39966, 39973, 39980, 39987, 39994, 40001, 40009, 40016, - 40024, 40031, 40038, 40046, 40054, 40059, 40064, 40069, 40074, 40079, - 40084, 40089, 40094, 40099, 40104, 40110, 40116, 40122, 40128, 40135, - 40143, 40150, 40156, 40162, 40168, 40174, 40180, 40186, 40192, 40198, - 40204, 40211, 40218, 40225, 40232, 40240, 40249, 40257, 40268, 40276, - 40284, 40293, 40300, 40309, 40318, 40326, 40335, 0, 0, 0, 0, 0, 0, 40343, - 40345, 40348, 40350, 40353, 40356, 40359, 40364, 40369, 40374, 40379, - 40383, 40387, 40391, 40395, 40400, 40406, 40411, 40417, 40422, 40427, - 40432, 40438, 40443, 40449, 40455, 40459, 40463, 40468, 40473, 40478, - 40483, 40488, 40496, 40504, 40512, 40520, 40527, 40535, 40542, 40549, - 40558, 40570, 40576, 40582, 40590, 40598, 40607, 40616, 40624, 40632, - 40641, 40650, 40655, 40663, 40668, 40673, 40679, 40684, 40690, 40697, - 40704, 40709, 40715, 40720, 40723, 40727, 40730, 40734, 40738, 40742, - 40748, 40754, 40760, 40766, 40770, 40774, 40778, 40782, 40788, 40794, - 40798, 40803, 40807, 40812, 40817, 40822, 40825, 40829, 40832, 40836, - 40843, 40851, 40862, 40873, 40878, 40887, 40894, 40903, 40912, 40916, - 40922, 40930, 40934, 40939, 40944, 40950, 40956, 40962, 40969, 40973, - 40977, 40982, 40985, 40987, 40991, 40995, 41003, 41007, 41009, 41011, - 41015, 41023, 41028, 41034, 41044, 41051, 41056, 41060, 41064, 41068, - 41071, 41074, 41077, 41081, 41085, 41089, 41093, 41097, 41100, 41104, - 41108, 41111, 41113, 41116, 41118, 41122, 41126, 41128, 41134, 41137, - 41142, 41146, 41150, 41152, 41154, 41156, 41159, 41163, 41167, 41171, - 41175, 41179, 41185, 41191, 41193, 41195, 41197, 41199, 41202, 41204, - 41208, 41210, 41214, 41217, 41223, 41227, 41231, 41234, 41237, 41241, - 41247, 41251, 41261, 41271, 41275, 41281, 41287, 41290, 41294, 41297, - 41302, 41306, 41312, 41316, 41328, 41336, 41340, 41344, 41350, 41354, - 41357, 41359, 41362, 41366, 41370, 41377, 41381, 41385, 41389, 41392, - 41397, 41402, 41407, 41412, 41417, 41422, 41430, 41438, 41442, 41446, - 41448, 41453, 41457, 41461, 41469, 41477, 41483, 41489, 41498, 41507, - 41512, 41517, 41525, 41533, 41535, 41537, 41542, 41547, 41553, 41559, - 41565, 41571, 41575, 41579, 41586, 41593, 41599, 41605, 41615, 41625, - 41633, 41641, 41643, 41647, 41651, 41656, 41661, 41668, 41675, 41678, - 41681, 41684, 41687, 41690, 41695, 41699, 41704, 41709, 41712, 41715, - 41718, 41721, 41724, 41728, 41731, 41734, 41737, 41740, 41742, 41744, - 41746, 41748, 41756, 41764, 41770, 41774, 41780, 41790, 41796, 41802, - 41808, 41816, 41824, 41835, 41839, 41843, 41845, 41851, 41853, 41855, - 41857, 41859, 41865, 41868, 41874, 41880, 41884, 41888, 41892, 41895, - 41899, 41903, 41905, 41914, 41923, 41928, 41933, 41939, 41945, 41951, - 41954, 41957, 41960, 41963, 41965, 41970, 41975, 41980, 41986, 41992, - 42000, 42008, 42014, 42020, 42026, 42032, 42041, 42050, 42059, 42068, - 42077, 42086, 42095, 42104, 42113, 42122, 42130, 42142, 42152, 42167, - 42170, 42175, 42181, 42187, 42194, 42208, 42223, 42229, 42235, 42242, - 42248, 42256, 42262, 42275, 42289, 42294, 42300, 42307, 42310, 42313, - 42315, 42318, 42321, 42323, 42325, 42329, 42332, 42335, 42338, 42341, - 42346, 42351, 42356, 42361, 42366, 42369, 42371, 42373, 42375, 42379, - 42383, 42387, 42393, 42398, 42400, 42402, 42407, 42412, 42417, 42422, - 42427, 42432, 42434, 42436, 42445, 42449, 42457, 42466, 42468, 42473, - 42478, 42486, 42490, 42492, 42496, 42498, 42502, 42506, 42510, 42512, - 42514, 42516, 42523, 42532, 42541, 42550, 42559, 42568, 42577, 42586, - 42595, 42603, 42611, 42620, 42629, 42638, 42647, 42655, 42663, 42672, - 42681, 42690, 42700, 42709, 42719, 42728, 42738, 42747, 42757, 42767, - 42776, 42786, 42795, 42805, 42814, 42824, 42833, 42842, 42851, 42860, - 42869, 42879, 42888, 42897, 42906, 42916, 42925, 42934, 42943, 42952, - 42962, 42972, 42981, 42990, 42998, 43006, 43013, 43021, 43030, 43041, - 43050, 43059, 43068, 43075, 43082, 43089, 43098, 43107, 43116, 43125, - 43132, 43137, 43146, 43151, 43154, 43162, 43165, 43170, 43175, 43178, - 43181, 43189, 43192, 43197, 43200, 43207, 43212, 43220, 43223, 43226, - 43229, 43234, 43239, 43242, 43245, 43253, 43256, 43263, 43270, 43274, - 43278, 43283, 43288, 43294, 43299, 43305, 43311, 43316, 43322, 43330, - 43336, 43344, 43352, 43358, 43366, 43374, 43383, 43391, 43397, 43405, - 43414, 43422, 43426, 43431, 43444, 43457, 43461, 43465, 43469, 43473, - 43483, 43487, 43492, 43497, 43502, 43507, 43512, 43517, 43527, 43537, - 43545, 43555, 43565, 43573, 43583, 43593, 43601, 43611, 43621, 43629, - 43637, 43647, 43657, 43660, 43663, 43666, 43671, 43675, 43681, 43688, - 43695, 43703, 43710, 43714, 43718, 43722, 43726, 43728, 43732, 43736, - 43741, 43746, 43753, 43760, 43763, 43770, 43772, 43774, 43778, 43782, - 43787, 43793, 43799, 43805, 43811, 43820, 43829, 43838, 43842, 43844, - 43848, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43855, 43859, 43866, 43873, - 43880, 43887, 43891, 43895, 43899, 43903, 43908, 43914, 43919, 43925, - 43931, 43937, 43943, 43951, 43958, 43965, 43972, 43979, 43984, 43990, - 43999, 44003, 44010, 44014, 44018, 44024, 44030, 44036, 44042, 44046, - 44050, 44053, 44056, 44060, 44067, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44074, 44077, 44081, 44085, 44091, - 44097, 44103, 44111, 44118, 44122, 44130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44135, 44138, 44141, 44144, 44147, - 44150, 44153, 44156, 44159, 44162, 44166, 44170, 44174, 44178, 44182, - 44186, 44190, 44194, 44198, 44202, 44206, 44209, 44212, 44215, 44218, - 44221, 44224, 44227, 44230, 44233, 44237, 44241, 44245, 44249, 44253, - 44257, 44261, 44265, 44269, 44273, 44277, 44283, 44289, 44295, 44302, - 44309, 44316, 44323, 44330, 44337, 44344, 44351, 44358, 44365, 44372, - 44379, 44386, 44393, 44400, 44407, 44414, 44419, 44425, 44431, 44437, - 44442, 44448, 44454, 44460, 44465, 44471, 44477, 44482, 44487, 44493, - 44498, 44504, 44510, 44515, 44521, 44527, 44532, 44538, 44544, 44550, - 44556, 44562, 44567, 44573, 44579, 44585, 44590, 44596, 44602, 44608, - 44613, 44619, 44625, 44630, 44635, 44641, 44646, 44652, 44658, 44663, - 44669, 44675, 44680, 44686, 44692, 44698, 44704, 44710, 44715, 44721, - 44727, 44733, 44738, 44744, 44750, 44756, 44761, 44767, 44773, 44778, - 44783, 44789, 44794, 44800, 44806, 44811, 44817, 44823, 44828, 44834, - 44840, 44846, 44852, 44858, 44862, 44867, 44872, 44877, 44882, 44887, - 44892, 44897, 44902, 44907, 44912, 44916, 44920, 44924, 44928, 44932, - 44936, 44940, 44944, 44948, 44953, 44958, 44963, 44968, 44973, 44978, - 44987, 44996, 45005, 45014, 45023, 45032, 45041, 45050, 45057, 45065, - 45073, 45080, 45087, 45095, 45103, 45110, 45117, 45125, 45133, 45140, - 45147, 45155, 45163, 45170, 45177, 45185, 45194, 45203, 45211, 45220, - 45229, 45236, 45243, 45251, 45260, 45269, 45277, 45286, 45295, 45302, - 45309, 45318, 45327, 45335, 45343, 45352, 45361, 45368, 45375, 45384, - 45393, 45401, 45409, 45418, 45427, 45434, 45441, 45450, 45459, 45467, - 45476, 45485, 45493, 45503, 45513, 45523, 45533, 45542, 45551, 45560, - 45569, 45576, 45584, 45592, 45600, 45608, 45613, 45618, 45627, 45635, - 45642, 45651, 45659, 45666, 45675, 45683, 45690, 45699, 45707, 45714, - 45723, 45731, 45738, 45747, 45755, 45762, 45771, 45779, 45786, 45795, - 45803, 45810, 45819, 45827, 45834, 45843, 45852, 45861, 45870, 45884, - 45898, 45905, 45910, 45915, 45920, 45925, 45930, 45935, 45940, 45945, - 45953, 45961, 45969, 45977, 45982, 45989, 45996, 46003, 46008, 46016, - 46023, 46031, 46035, 46042, 46048, 46055, 46059, 46065, 46071, 46077, - 46081, 46084, 46088, 46092, 46099, 46105, 46111, 46117, 46123, 46137, - 46147, 46161, 46175, 46181, 46191, 46205, 46208, 46211, 46218, 46226, - 46231, 46236, 46244, 46256, 46268, 46276, 46280, 46284, 46287, 46290, - 46294, 46298, 46301, 46304, 46309, 46314, 46320, 46326, 46331, 46336, - 46342, 46348, 46353, 46358, 46363, 46368, 46374, 46380, 46385, 46390, - 46396, 46402, 46407, 46412, 46415, 46418, 46427, 46429, 46431, 46434, - 46438, 46444, 46446, 46449, 46456, 46463, 46471, 46479, 46489, 46503, - 46508, 46513, 46517, 46522, 46530, 46538, 46547, 46556, 46565, 46574, - 46579, 46584, 46590, 46596, 46602, 46608, 46611, 46617, 46623, 46633, - 46643, 46651, 46659, 46668, 46677, 46681, 46689, 46697, 46705, 46713, - 46722, 46731, 46740, 46749, 46754, 46759, 46764, 46769, 46774, 46780, - 46786, 46791, 46797, 46799, 46801, 46803, 46805, 46808, 46811, 46813, - 46815, 46817, 46821, 46825, 46827, 46829, 46832, 46835, 46839, 46845, - 46851, 46853, 46860, 46864, 46869, 46874, 46876, 46886, 46892, 46898, - 46904, 46910, 46916, 46922, 46927, 46930, 46933, 46936, 46938, 46940, - 46944, 46948, 46953, 46958, 46963, 46966, 46970, 46975, 46978, 46982, - 46987, 46992, 46997, 47002, 47007, 47012, 47017, 47022, 47027, 47032, - 47037, 47042, 47048, 47054, 47060, 47062, 47065, 47067, 47070, 47072, - 47074, 47076, 47078, 47080, 47082, 47084, 47086, 47088, 47090, 47092, - 47094, 47096, 47098, 47100, 47102, 47104, 47109, 47114, 47119, 47124, - 47129, 47134, 47139, 47144, 47149, 47154, 47159, 47164, 47169, 47174, - 47179, 47184, 47189, 47194, 47199, 47204, 47208, 47212, 47216, 47222, - 47228, 47233, 47238, 47243, 47248, 47253, 47258, 47266, 47274, 47282, - 47290, 47298, 47306, 47314, 47322, 47328, 47333, 47338, 47343, 47346, - 47350, 47354, 47358, 47362, 47366, 47370, 47377, 47384, 47392, 47400, - 47405, 47410, 47417, 47424, 47431, 47438, 47441, 47444, 47449, 47451, - 47455, 47460, 47462, 47464, 47466, 47468, 47473, 47476, 47478, 47483, - 47490, 47497, 47500, 47504, 47509, 47514, 47522, 47528, 47534, 47546, - 47553, 47560, 47565, 47570, 47576, 47579, 47582, 47587, 47589, 47593, - 47595, 47597, 47599, 47601, 47603, 47605, 47610, 47612, 47614, 47616, - 47618, 47622, 47624, 47627, 47632, 47637, 47642, 47647, 47653, 47659, - 47661, 47664, 47671, 47678, 47685, 47692, 47696, 47700, 47702, 47704, - 47708, 47714, 47719, 47721, 47725, 47734, 47742, 47750, 47756, 47762, - 47767, 47773, 47778, 47781, 47795, 47798, 47803, 47808, 47814, 47824, - 47826, 47832, 47838, 47842, 47849, 47853, 47855, 47857, 47861, 47867, - 47872, 47878, 47880, 47886, 47888, 47894, 47896, 47898, 47903, 47905, - 47909, 47914, 47916, 47921, 47926, 47930, 47937, 0, 47947, 47953, 47956, - 47962, 47965, 47970, 47975, 47979, 47981, 47983, 47987, 47991, 47995, - 47999, 48004, 48006, 48011, 48014, 48017, 48020, 48024, 48028, 48033, - 48037, 48042, 48047, 48051, 48056, 48062, 48065, 48071, 48076, 48080, - 48085, 48091, 48097, 48104, 48110, 48117, 48124, 48126, 48133, 48137, - 48143, 48149, 48154, 48160, 48164, 48169, 48172, 48177, 48183, 48190, - 48198, 48205, 48214, 48224, 48231, 48237, 48241, 48248, 48253, 48262, - 48265, 48268, 48277, 48287, 48294, 48296, 48302, 48307, 48309, 48312, - 48316, 48324, 48333, 48336, 48341, 48346, 48354, 48362, 48370, 48378, - 48384, 48390, 48396, 48404, 48409, 48412, 48416, 48419, 48431, 48441, - 48452, 48461, 48472, 48482, 48491, 48497, 48505, 48509, 48517, 48521, - 48529, 48536, 48543, 48552, 48561, 48571, 48581, 48591, 48601, 48610, - 48619, 48629, 48639, 48648, 48657, 48663, 48669, 48675, 48681, 48687, - 48693, 48699, 48705, 48711, 48718, 48724, 48730, 48736, 48742, 48748, - 48754, 48760, 48766, 48772, 48779, 48786, 48793, 48800, 48807, 48814, - 48821, 48828, 48835, 48842, 48850, 48855, 48858, 48862, 48866, 48872, - 48875, 48881, 48887, 48892, 48896, 48901, 48907, 48914, 48917, 48924, - 48931, 48935, 48944, 48953, 48958, 48964, 48969, 48974, 48981, 48988, - 48996, 49004, 49013, 49017, 49026, 49031, 49035, 49042, 49046, 49053, - 49061, 49066, 49074, 49078, 49083, 49087, 49092, 49096, 49101, 49106, - 49115, 49117, 49120, 49123, 49130, 49137, 49142, 49150, 49156, 49162, - 49167, 49170, 49175, 49180, 49185, 49193, 49197, 49204, 49212, 49220, - 49225, 49230, 49236, 49241, 49246, 49252, 49257, 49260, 49264, 49268, - 49275, 49284, 49289, 49298, 49307, 49313, 49319, 49324, 49329, 49334, - 49339, 49345, 49351, 49359, 49367, 49373, 49379, 49384, 49389, 49396, - 49403, 49409, 49412, 49415, 49419, 49423, 49427, 49432, 49438, 49444, - 49451, 49458, 49463, 49467, 49471, 49475, 49479, 49483, 49487, 49491, - 49495, 49499, 49503, 49507, 49511, 49515, 49519, 49523, 49527, 49531, - 49535, 49539, 49543, 49547, 49551, 49555, 49559, 49563, 49567, 49571, - 49575, 49579, 49583, 49587, 49591, 49595, 49599, 49603, 49607, 49611, - 49615, 49619, 49623, 49627, 49631, 49635, 49639, 49643, 49647, 49651, - 49655, 49659, 49663, 49667, 49671, 49675, 49679, 49683, 49687, 49691, - 49695, 49699, 49703, 49707, 49711, 49715, 49719, 49723, 49727, 49731, - 49735, 49739, 49743, 49747, 49751, 49755, 49759, 49763, 49767, 49771, - 49775, 49779, 49783, 49787, 49791, 49795, 49799, 49803, 49807, 49811, - 49815, 49819, 49823, 49827, 49831, 49835, 49839, 49843, 49847, 49851, - 49855, 49859, 49863, 49867, 49871, 49875, 49879, 49883, 49887, 49891, - 49895, 49899, 49903, 49907, 49911, 49915, 49919, 49923, 49927, 49931, - 49935, 49939, 49943, 49947, 49951, 49955, 49959, 49963, 49967, 49971, - 49975, 49979, 49983, 49987, 49991, 49995, 49999, 50003, 50007, 50011, - 50015, 50019, 50023, 50027, 50031, 50035, 50039, 50043, 50047, 50051, - 50055, 50059, 50063, 50067, 50071, 50075, 50079, 50083, 50087, 50091, - 50095, 50099, 50103, 50107, 50111, 50115, 50119, 50123, 50127, 50131, - 50135, 50139, 50143, 50147, 50151, 50155, 50159, 50163, 50167, 50171, - 50175, 50179, 50183, 50187, 50191, 50195, 50199, 50203, 50207, 50211, - 50215, 50219, 50223, 50227, 50231, 50235, 50239, 50243, 50247, 50251, - 50255, 50259, 50263, 50267, 50271, 50275, 50279, 50283, 50287, 50291, - 50295, 50299, 50303, 50307, 50311, 50315, 50319, 50323, 50327, 50331, - 50335, 50339, 50343, 50347, 50351, 50355, 50359, 50363, 50367, 50371, - 50375, 50379, 50383, 50387, 50391, 50395, 50399, 50403, 50407, 50411, - 50415, 50419, 50423, 50427, 50431, 50435, 50439, 50443, 50447, 50451, - 50455, 50459, 50463, 50467, 50471, 50475, 50479, 50483, 50487, 50494, - 50502, 50508, 50514, 50521, 50528, 50534, 50540, 50546, 50552, 50557, - 50562, 50567, 50572, 50578, 50584, 50592, 50599, 50605, 50611, 50619, - 50628, 50635, 50645, 50656, 50659, 50662, 50666, 50670, 50677, 50684, - 50695, 50706, 50716, 50726, 50733, 50740, 50747, 50754, 50765, 50776, - 50787, 50798, 50808, 50818, 50830, 50842, 50853, 50864, 50876, 50888, - 50897, 50907, 50917, 50928, 50939, 50946, 50953, 50960, 50967, 50977, - 50987, 50995, 51003, 51010, 51017, 51024, 51031, 51038, 51043, 51048, - 51054, 51062, 51072, 51082, 51092, 51102, 51112, 51122, 51132, 51142, - 51152, 51162, 51172, 51183, 51194, 51204, 51214, 51225, 51236, 51246, - 51256, 51267, 51278, 51288, 51298, 51309, 51320, 51336, 51355, 51371, - 51390, 51406, 51422, 51438, 51454, 51465, 51477, 51488, 51500, 51519, - 51538, 51546, 51552, 51559, 51566, 51573, 51580, 51585, 51591, 51596, - 51601, 51607, 51612, 51617, 51622, 51627, 51632, 51639, 51644, 51651, - 51656, 51661, 51665, 51669, 51676, 51683, 51690, 51697, 51704, 51711, - 51724, 51737, 51750, 51763, 51771, 51779, 51785, 51791, 51798, 51805, - 51812, 51819, 51823, 51828, 51836, 51844, 51852, 51859, 51863, 51871, - 51879, 51883, 51887, 51892, 51899, 51907, 51915, 51934, 51953, 51972, - 51991, 52010, 52029, 52048, 52067, 52073, 52080, 52089, 52097, 52105, - 52110, 52113, 52116, 52121, 52124, 52143, 52150, 52156, 52162, 52166, - 52169, 52172, 52175, 52187, 52200, 52207, 52214, 52217, 52221, 52224, - 52229, 52234, 52239, 52245, 52254, 52261, 52268, 52276, 52283, 52290, - 52293, 52299, 52305, 52308, 52311, 52316, 52321, 52327, 52333, 52337, - 52342, 52349, 52353, 52359, 52363, 52367, 52375, 52387, 52396, 52400, - 52402, 52411, 52420, 52426, 52429, 52435, 52441, 52446, 52451, 52456, - 52461, 52466, 52471, 52473, 52479, 52484, 52491, 52495, 52501, 52504, - 52508, 52515, 52522, 52524, 52526, 52532, 52538, 52544, 52553, 52562, - 52569, 52576, 52582, 52588, 52593, 52598, 52603, 52609, 52615, 52620, - 52627, 52631, 52635, 52648, 52661, 52673, 52682, 52688, 52695, 52700, - 52705, 52710, 52715, 52720, 52722, 52729, 52736, 52743, 52750, 52757, - 52765, 52771, 52776, 52782, 52788, 52794, 52801, 52807, 52815, 52823, - 52831, 52839, 52846, 52852, 52858, 52867, 52871, 52880, 52889, 52898, - 52906, 52910, 52916, 52923, 52930, 52934, 52940, 52947, 52952, 52957, - 52963, 52968, 52973, 52980, 52987, 52992, 52997, 53005, 53013, 53023, - 53033, 53040, 53047, 53051, 53055, 53067, 53073, 53079, 53084, 53089, - 53096, 53103, 53109, 53115, 53124, 53132, 53140, 53147, 53154, 53161, - 53167, 53174, 53180, 53187, 53194, 53201, 53208, 53214, 53219, 53228, - 53238, 53245, 53254, 53260, 53265, 53270, 53280, 53286, 53292, 53298, - 53306, 53311, 53318, 53325, 53336, 53343, 53350, 53357, 53364, 53371, - 53378, 53385, 53397, 53409, 53420, 53431, 53444, 53457, 53462, 53467, - 53476, 53485, 53492, 53499, 53508, 53517, 53525, 53533, 53541, 53549, - 53559, 53569, 53583, 53597, 53605, 53613, 53625, 53637, 53645, 53653, - 53663, 53673, 53678, 53683, 53692, 53701, 53706, 53711, 53719, 53725, - 53731, 53739, 53747, 53760, 53773, 53777, 53781, 53788, 53795, 53802, - 53810, 53818, 53827, 53836, 53842, 53848, 53855, 53862, 53869, 53876, - 53885, 53894, 53897, 53900, 53905, 53910, 53916, 53922, 53929, 53936, - 53946, 53956, 53963, 53970, 53978, 53986, 53994, 54002, 54010, 54018, - 54024, 54030, 54034, 54038, 54045, 54052, 54057, 54062, 54067, 54072, - 54078, 54092, 54099, 54106, 54110, 54112, 54114, 54119, 54124, 54129, - 54134, 54142, 54149, 54156, 54164, 54176, 54184, 54192, 54203, 54207, - 54211, 54217, 54225, 54238, 54245, 54252, 54259, 54264, 54271, 54280, - 54288, 54294, 54300, 54306, 54315, 54324, 54332, 54341, 54346, 54349, - 54354, 54360, 54366, 54372, 54378, 54382, 54385, 54389, 54393, 54399, - 54405, 54411, 54417, 54421, 54425, 54432, 54439, 54446, 54453, 54460, - 54467, 54477, 54487, 54494, 54501, 54509, 54517, 54521, 54526, 54531, - 54537, 54543, 54546, 54549, 54552, 54555, 54559, 54564, 54569, 54574, - 54579, 54584, 54588, 54592, 54596, 54600, 54604, 54608, 54612, 54618, - 54622, 54628, 54633, 54640, 54648, 54655, 54663, 54670, 54678, 54687, - 54694, 54704, 54715, 54721, 54730, 54736, 54745, 54754, 54760, 54766, - 54770, 54774, 54783, 54792, 54799, 54806, 54815, 0, 0, 0, 54824, 54829, - 54833, 54837, 54842, 54847, 54852, 54860, 54868, 54871, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54875, 54880, 54885, - 54890, 54895, 54900, 54905, 54910, 54915, 54920, 54925, 54931, 54935, - 54940, 54945, 54950, 54955, 54960, 54965, 54970, 54975, 54980, 54985, - 54990, 54995, 55000, 55005, 55010, 55015, 55020, 55025, 55030, 55035, - 55040, 55045, 55051, 55056, 55062, 55071, 55076, 55084, 55091, 55100, - 55105, 55110, 55115, 55121, 0, 55128, 55133, 55138, 55143, 55148, 55153, - 55158, 55163, 55168, 55173, 55178, 55184, 55188, 55193, 55198, 55203, - 55208, 55213, 55218, 55223, 55228, 55233, 55238, 55243, 55248, 55253, - 55258, 55263, 55268, 55273, 55278, 55283, 55288, 55293, 55298, 55304, - 55309, 55315, 55324, 55329, 55337, 55344, 55353, 55358, 55363, 55368, - 55374, 0, 55381, 55389, 55397, 55406, 55413, 55421, 55427, 55436, 55444, - 55452, 55460, 55468, 55476, 55484, 55489, 55496, 55502, 55509, 55517, - 55524, 55531, 55539, 55545, 55551, 55558, 55565, 55575, 55585, 55592, - 55599, 55604, 55614, 55624, 55629, 55634, 55639, 55644, 55649, 55654, - 55659, 55664, 55669, 55674, 55679, 55684, 55689, 55694, 55699, 55704, - 55709, 55714, 55719, 55724, 55729, 55734, 55739, 55744, 55749, 55754, - 55759, 55764, 55769, 55774, 55778, 55782, 55787, 55792, 55797, 55802, - 55807, 55812, 55817, 55822, 55827, 55832, 55837, 55842, 55847, 55852, - 55857, 55862, 55867, 55872, 55879, 55886, 55893, 55900, 55907, 55914, - 55921, 55928, 55935, 55942, 55949, 55956, 55963, 55970, 55975, 55980, - 55987, 55994, 56001, 56008, 56015, 56022, 56029, 56036, 56043, 56050, - 56057, 56064, 56070, 56076, 56082, 56088, 56095, 56102, 56109, 56116, - 56123, 56130, 56137, 56144, 56151, 56158, 56166, 56174, 56182, 56190, - 56198, 56206, 56214, 56222, 56226, 56232, 56238, 56242, 56248, 56254, - 56260, 56267, 56274, 56281, 56288, 56293, 56299, 56305, 56312, 0, 0, 0, - 0, 0, 56319, 56327, 56336, 56345, 56353, 56359, 56364, 56369, 56374, - 56379, 56384, 56389, 56394, 56399, 56404, 56409, 56414, 56419, 56424, - 56429, 56434, 56439, 56444, 56449, 56454, 56459, 56464, 56469, 56474, - 56479, 56484, 56489, 56494, 56499, 56504, 56509, 56514, 56519, 56524, - 56529, 56534, 56539, 56544, 56549, 56554, 0, 56559, 0, 0, 0, 0, 0, 56564, - 0, 0, 56569, 56573, 56578, 56583, 56588, 56593, 56602, 56607, 56612, - 56617, 56622, 56627, 56632, 56637, 56642, 56649, 56654, 56659, 56668, - 56675, 56680, 56685, 56690, 56697, 56702, 56709, 56714, 56719, 56726, - 56733, 56738, 56743, 56748, 56755, 56762, 56767, 56772, 56777, 56782, - 56787, 56794, 56801, 56806, 56811, 56816, 56821, 56826, 56831, 56836, - 56841, 56846, 56851, 56856, 56863, 56868, 56873, 0, 0, 0, 0, 0, 0, 0, - 56878, 56885, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56890, 56895, - 56899, 56903, 56907, 56911, 56915, 56919, 56923, 56927, 56931, 56935, - 56941, 56945, 56949, 56953, 56957, 56961, 56965, 56969, 56973, 56977, - 56981, 56985, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56989, 56993, 56997, 57001, - 57005, 57009, 57013, 0, 57017, 57021, 57025, 57029, 57033, 57037, 57041, - 0, 57045, 57049, 57053, 57057, 57061, 57065, 57069, 0, 57073, 57077, - 57081, 57085, 57089, 57093, 57097, 0, 57101, 57105, 57109, 57113, 57117, - 57121, 57125, 0, 57129, 57133, 57137, 57141, 57145, 57149, 57153, 0, - 57157, 57161, 57165, 57169, 57173, 57177, 57181, 0, 57185, 57189, 57193, - 57197, 57201, 57205, 57209, 0, 57213, 57218, 57223, 57228, 57233, 57238, - 57243, 57247, 57252, 57257, 57262, 57266, 57271, 57276, 57281, 57286, - 57290, 57295, 57300, 57305, 57310, 57315, 57320, 57324, 57329, 57334, - 57341, 57346, 57351, 57357, 57364, 57371, 57380, 57387, 57396, 57400, - 57404, 57410, 57416, 57422, 57430, 57436, 57440, 57444, 57448, 57454, - 57460, 57464, 57466, 57470, 57476, 57478, 57482, 57486, 57490, 57496, - 57501, 57505, 57509, 57514, 57520, 57525, 57530, 57535, 57540, 57547, - 57554, 57559, 57564, 57569, 57574, 57579, 57584, 57588, 57592, 57599, - 57606, 57612, 57616, 57621, 57623, 57627, 57635, 57639, 57643, 57647, - 57651, 57657, 57663, 57667, 57673, 57677, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57681, 57685, 57689, 57694, 57699, 57704, - 57708, 57712, 57716, 57721, 57726, 57730, 57734, 57738, 57742, 57747, - 57752, 57757, 57762, 57766, 57770, 57775, 57780, 57785, 57790, 57794, 0, - 57798, 57802, 57806, 57810, 57814, 57818, 57822, 57827, 57832, 57836, - 57841, 57846, 57855, 57859, 57863, 57867, 57874, 57878, 57883, 57888, - 57892, 57896, 57902, 57907, 57912, 57917, 57922, 57926, 57930, 57934, - 57938, 57942, 57947, 57952, 57956, 57960, 57965, 57970, 57975, 57979, - 57983, 57988, 57993, 57999, 58005, 58009, 58015, 58021, 58025, 58031, - 58037, 58042, 58047, 58051, 58057, 58061, 58065, 58071, 58077, 58082, - 58087, 58091, 58095, 58103, 58109, 58115, 58121, 58126, 58131, 58136, - 58142, 58146, 58152, 58156, 58160, 58166, 58172, 58178, 58184, 58190, - 58196, 58202, 58208, 58214, 58220, 58226, 58232, 58236, 58242, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 58248, 58251, 58255, 58259, 58263, 58267, - 58270, 58273, 58277, 58281, 58285, 58289, 58292, 58297, 58301, 58305, - 58309, 58314, 58318, 58322, 58326, 58330, 58336, 58342, 58346, 58350, - 58354, 58358, 58362, 58366, 58370, 58374, 58378, 58382, 58386, 58392, - 58396, 58400, 58404, 58408, 58412, 58416, 58420, 58424, 58428, 58432, - 58436, 58440, 58444, 58448, 58452, 58456, 58462, 58468, 58473, 58478, - 58482, 58486, 58490, 58494, 58498, 58502, 58506, 58510, 58514, 58518, - 58522, 58526, 58530, 58534, 58538, 58542, 58546, 58550, 58554, 58558, - 58562, 58566, 58570, 58574, 58580, 58584, 58588, 58592, 58596, 58600, - 58604, 58608, 58612, 58617, 58624, 58628, 58632, 58636, 58640, 58644, - 58648, 58652, 58656, 58660, 58664, 58668, 58672, 58679, 58683, 58689, - 58693, 58697, 58701, 58705, 58709, 58712, 58716, 58720, 58724, 58728, - 58732, 58736, 58740, 58744, 58748, 58752, 58756, 58760, 58764, 58768, - 58772, 58776, 58780, 58784, 58788, 58792, 58796, 58800, 58804, 58808, - 58812, 58816, 58820, 58824, 58828, 58832, 58836, 58840, 58846, 58850, - 58854, 58858, 58862, 58866, 58870, 58874, 58878, 58882, 58886, 58890, - 58894, 58898, 58902, 58906, 58910, 58914, 58918, 58922, 58926, 58930, - 58934, 58938, 58942, 58946, 58950, 58954, 58962, 58966, 58970, 58974, - 58978, 58982, 58988, 58992, 58996, 59000, 59004, 59008, 59012, 59016, - 59020, 59024, 59028, 59032, 59036, 59040, 59046, 59050, 59054, 59058, - 59062, 59066, 59070, 59074, 59078, 59082, 59086, 59090, 59094, 59098, - 59102, 59106, 59110, 59114, 59118, 59122, 59126, 59130, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59134, 59143, - 59151, 59163, 59174, 59182, 59191, 59200, 59210, 59222, 59234, 59246, 0, - 0, 0, 0, 59252, 59255, 59258, 59263, 59266, 59273, 59277, 59281, 59285, - 59289, 59293, 59298, 59303, 59307, 59311, 59316, 59321, 59326, 59331, - 59334, 59337, 59343, 59349, 59354, 59359, 59366, 59373, 59377, 59381, - 59385, 59393, 59399, 59406, 59411, 59416, 59421, 59426, 59431, 59436, - 59441, 59446, 59451, 59456, 59461, 59466, 59471, 59476, 59482, 59487, - 59491, 59497, 59508, 59518, 59533, 59543, 59547, 59557, 59563, 59569, - 59575, 59580, 59583, 59588, 59592, 0, 59598, 59602, 59605, 59609, 59612, - 59616, 59619, 59623, 59626, 59630, 59633, 59636, 59640, 59644, 59648, - 59652, 59656, 59660, 59664, 59668, 59672, 59675, 59679, 59683, 59687, - 59691, 59695, 59699, 59703, 59707, 59711, 59715, 59719, 59723, 59727, - 59732, 59736, 59740, 59744, 59748, 59751, 59755, 59758, 59762, 59766, - 59770, 59774, 59777, 59781, 59784, 59788, 59792, 59796, 59800, 59804, - 59808, 59812, 59816, 59820, 59824, 59828, 59832, 59835, 59839, 59843, - 59847, 59851, 59855, 59858, 59863, 59867, 59872, 59876, 59879, 59883, - 59887, 59891, 59895, 59900, 59904, 59908, 59912, 59916, 59920, 59924, - 59928, 0, 0, 59933, 59941, 59949, 59956, 59963, 59967, 59973, 59978, - 59983, 59987, 59990, 59994, 59997, 60001, 60004, 60008, 60011, 60015, - 60018, 60021, 60025, 60029, 60033, 60037, 60041, 60045, 60049, 60053, - 60057, 60060, 60064, 60068, 60072, 60076, 60080, 60084, 60088, 60092, - 60096, 60100, 60104, 60108, 60112, 60117, 60121, 60125, 60129, 60133, - 60136, 60140, 60143, 60147, 60151, 60155, 60159, 60162, 60166, 60169, - 60173, 60177, 60181, 60185, 60189, 60193, 60197, 60201, 60205, 60209, - 60213, 60217, 60220, 60224, 60228, 60232, 60236, 60240, 60243, 60248, - 60252, 60257, 60261, 60264, 60268, 60272, 60276, 60280, 60285, 60289, - 60293, 60297, 60301, 60305, 60309, 60313, 60318, 60322, 60326, 60330, - 60334, 60339, 60346, 60350, 60356, 0, 0, 0, 0, 0, 60361, 60366, 60371, - 60375, 60380, 60385, 60390, 60395, 60399, 60404, 60409, 60414, 60419, - 60424, 60429, 60434, 60439, 60444, 60448, 60453, 60458, 60463, 60467, - 60471, 60475, 60480, 60485, 60490, 60495, 60500, 60505, 60510, 60515, - 60520, 60525, 60529, 60533, 60538, 60543, 60548, 60553, 0, 0, 0, 60558, - 60562, 60566, 60570, 60574, 60578, 60582, 60586, 60590, 60594, 60598, - 60602, 60606, 60610, 60614, 60618, 60622, 60626, 60630, 60634, 60638, - 60642, 60646, 60650, 60654, 60658, 60662, 60666, 60670, 60674, 60678, - 60681, 60685, 60688, 60692, 60696, 60699, 60703, 60707, 60710, 60714, - 60718, 60722, 60726, 60729, 60733, 60737, 60741, 60745, 60749, 60753, - 60756, 60759, 60763, 60767, 60771, 60775, 60779, 60783, 60787, 60791, - 60795, 60799, 60803, 60807, 60811, 60815, 60819, 60823, 60827, 60831, - 60835, 60839, 60843, 60847, 60851, 60855, 60859, 60863, 60867, 60871, - 60875, 60879, 60883, 60887, 60891, 60895, 60899, 60903, 60907, 60911, - 60915, 60919, 60923, 0, 60927, 60933, 60939, 60944, 60949, 60954, 60960, - 60966, 60972, 60978, 60984, 60990, 60996, 61002, 61008, 61014, 61020, - 61025, 61030, 61035, 61040, 61045, 61050, 61055, 61060, 61065, 61070, - 61075, 61080, 61085, 61090, 61095, 61100, 61105, 61110, 61115, 61120, - 61126, 61132, 61138, 61144, 61149, 61154, 0, 0, 0, 0, 0, 61159, 61164, - 61169, 61174, 61179, 61184, 61189, 61194, 61199, 61204, 61209, 61214, - 61219, 61224, 61229, 61234, 61239, 61244, 61249, 61254, 61259, 61264, - 61269, 61274, 61279, 61284, 61289, 61294, 61299, 61304, 61309, 61314, - 61319, 61324, 61329, 61334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61339, - 61344, 61349, 61354, 61358, 61363, 61367, 61372, 61377, 61382, 61387, - 61392, 61396, 61401, 61406, 61411, 61416, 61420, 61424, 61428, 61432, - 61436, 61440, 61444, 61448, 61452, 61456, 61460, 61464, 61468, 61472, - 61477, 61482, 61487, 61492, 61497, 61502, 61507, 61512, 61517, 61522, - 61527, 61532, 61537, 61542, 61547, 61553, 0, 61560, 61563, 61566, 61569, - 61572, 61575, 61578, 61581, 61584, 61587, 61591, 61595, 61599, 61603, - 61607, 61611, 61615, 61619, 61623, 61627, 61631, 61635, 61639, 61643, - 61647, 61651, 61655, 61659, 61663, 61667, 61671, 61675, 61679, 61683, - 61687, 61691, 61695, 61699, 61703, 61707, 61711, 61720, 61729, 61738, - 61747, 61756, 61765, 61774, 61783, 61786, 61791, 61796, 61801, 61806, - 61811, 61816, 61821, 61826, 61831, 61835, 61840, 61845, 61850, 61855, - 61860, 61864, 61868, 61872, 61876, 61880, 61884, 61888, 61892, 61896, - 61900, 61904, 61908, 61912, 61916, 61921, 61926, 61931, 61936, 61941, - 61946, 61951, 61956, 61961, 61966, 61971, 61976, 61981, 61986, 61992, - 61998, 62003, 62008, 62011, 62014, 62017, 62020, 62023, 62026, 62029, - 62032, 62035, 62039, 62043, 62047, 62051, 62055, 62059, 62063, 62067, - 62071, 62075, 62079, 62083, 62087, 62091, 62095, 62099, 62103, 62107, - 62111, 62115, 62119, 62123, 62127, 62131, 62135, 62139, 62143, 62147, - 62151, 62155, 62159, 62163, 62167, 62171, 62175, 62179, 62183, 62187, - 62191, 62195, 62200, 62205, 62210, 62215, 62219, 62224, 62229, 62234, - 62239, 62244, 62249, 62254, 62259, 62264, 62268, 62275, 62282, 62289, - 62296, 62303, 62310, 62317, 62324, 62331, 62338, 62345, 62352, 62355, - 62358, 62361, 62366, 62369, 62372, 62375, 62378, 62381, 62384, 62388, - 62392, 62396, 62400, 62403, 62407, 62411, 62415, 62419, 62423, 62427, - 62431, 62435, 62438, 62441, 62445, 62449, 62453, 62457, 62460, 62464, - 62468, 62472, 62476, 62479, 62483, 62487, 62491, 62495, 62498, 62502, - 62506, 62509, 62513, 62517, 62521, 62525, 62529, 62533, 62537, 0, 62541, - 62544, 62547, 62550, 62553, 62556, 62559, 62562, 62565, 62568, 62571, - 62574, 62577, 62580, 62583, 62586, 62589, 62592, 62595, 62598, 62601, - 62604, 62607, 62610, 62613, 62616, 62619, 62622, 62625, 62628, 62631, - 62634, 62637, 62640, 62643, 62646, 62649, 62652, 62655, 62658, 62661, - 62664, 62667, 62670, 62673, 62676, 62679, 62682, 62685, 62688, 62691, - 62694, 62697, 62700, 62703, 62706, 62709, 62712, 62715, 62718, 62721, - 62724, 62727, 62730, 62733, 62736, 62739, 62742, 62745, 62748, 62751, - 62754, 62757, 62760, 62763, 62766, 62769, 62772, 62775, 62778, 62781, - 62784, 62787, 62790, 62793, 62796, 62799, 62802, 62805, 62814, 62822, - 62830, 62838, 62846, 62854, 62862, 62870, 62878, 62886, 62895, 62904, - 62913, 62922, 62931, 62940, 62949, 62958, 62967, 62976, 62985, 62994, - 63003, 63012, 63021, 63024, 63027, 63030, 63032, 63035, 63038, 63041, - 63046, 63051, 63054, 63061, 63068, 63075, 63082, 63085, 63090, 63092, - 63096, 63098, 63100, 63103, 63106, 63109, 63112, 63115, 63118, 63121, - 63126, 63131, 63134, 63137, 63140, 63143, 63146, 63149, 63152, 63156, - 63159, 63162, 63165, 63168, 63171, 63175, 63178, 63181, 63184, 63189, - 63194, 63199, 63204, 63209, 63214, 63219, 63224, 63230, 63238, 63240, - 63243, 63246, 63249, 63252, 63258, 63266, 63269, 63272, 63277, 63280, - 63283, 63286, 63291, 63294, 63297, 63302, 63305, 63308, 63313, 63316, - 63319, 63324, 63329, 63334, 63337, 63340, 63343, 63346, 63352, 63355, - 63358, 63361, 63363, 63366, 63369, 63372, 63377, 63380, 63383, 63386, - 63389, 63392, 63397, 63400, 63403, 63406, 63409, 63412, 63415, 63418, - 63421, 63424, 63429, 63433, 63441, 63449, 63457, 63465, 63473, 63481, - 63489, 63497, 63505, 63514, 63523, 63532, 63541, 63550, 63559, 63568, - 63577, 63586, 63595, 63604, 63613, 63622, 63631, 63640, 63649, 63658, - 63667, 63676, 63685, 63694, 63703, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 63706, 63715, 63724, 63735, 63742, 63747, 63752, 63759, 63766, - 63772, 63777, 63782, 63787, 63792, 63799, 63804, 63809, 63814, 63825, - 63830, 63835, 63842, 63847, 63854, 63859, 63864, 63871, 63878, 63885, - 63894, 63903, 63908, 63913, 63918, 63925, 63930, 63940, 63947, 63952, - 63957, 63962, 63967, 63972, 63977, 63986, 63993, 64000, 64005, 64012, - 64017, 64024, 64033, 64044, 64049, 64058, 64063, 64070, 64079, 64088, - 64093, 64098, 64105, 64111, 64118, 64125, 64129, 64133, 64136, 64140, - 64144, 64148, 64152, 64156, 64160, 64164, 64167, 64171, 64175, 64179, - 64183, 64187, 64191, 64194, 64198, 64202, 64205, 64209, 64213, 64217, - 64221, 64225, 64229, 64233, 64237, 64241, 64245, 64249, 64253, 64257, - 64261, 64265, 64269, 64273, 64277, 64281, 64285, 64289, 64293, 64297, - 64301, 64305, 64309, 64313, 64317, 64321, 64325, 64329, 64333, 64337, - 64341, 64345, 64349, 64353, 64357, 64361, 64365, 64369, 64373, 64377, - 64381, 64384, 64388, 64392, 64396, 64400, 64404, 64408, 64412, 64416, - 64420, 64424, 64428, 64432, 64436, 64440, 64444, 64448, 64452, 64456, - 64460, 64464, 64468, 64472, 64476, 64480, 64484, 64488, 64492, 64496, - 64500, 64504, 64508, 64512, 64516, 64520, 64524, 64528, 64532, 64536, - 64540, 64544, 64548, 64552, 64556, 64560, 64564, 64568, 64572, 64576, - 64580, 64584, 64588, 64592, 64596, 64600, 64604, 64608, 64612, 64616, - 64620, 64624, 64628, 64632, 64636, 64640, 64644, 64648, 64652, 64656, - 64660, 64664, 64668, 64672, 64676, 64680, 64684, 64688, 64692, 64696, - 64700, 64704, 64708, 64712, 64716, 64720, 64724, 64728, 64732, 64736, - 64740, 64744, 64748, 64752, 64756, 64760, 64764, 64768, 64772, 64776, - 64780, 64784, 64788, 64792, 64796, 64800, 64804, 64808, 64812, 64816, - 64820, 64824, 64828, 64832, 64836, 64840, 64844, 64848, 64852, 64855, - 64859, 64863, 64867, 64871, 64875, 64879, 64883, 64887, 64891, 64895, - 64899, 64903, 64907, 64911, 64915, 64919, 64923, 64927, 64931, 64935, - 64939, 64943, 64947, 64951, 64955, 64959, 64963, 64967, 64971, 64975, - 64979, 64983, 64987, 64991, 64995, 64999, 65003, 65007, 65011, 65015, - 65019, 65023, 65027, 65031, 65035, 65039, 65043, 65047, 65051, 65055, - 65059, 65063, 65067, 65071, 65075, 65079, 65083, 65087, 65091, 65095, - 65099, 65103, 65107, 65111, 65115, 65119, 65123, 65127, 65131, 65135, - 65139, 65143, 65147, 65151, 65155, 65159, 65163, 65167, 65171, 65175, - 65179, 65183, 65187, 65191, 65195, 65199, 65203, 65207, 65211, 65215, - 65219, 65223, 65227, 65231, 65235, 65239, 65243, 65247, 65251, 65255, - 65259, 65263, 65267, 65271, 65275, 65279, 65283, 65287, 65291, 65295, - 65299, 65303, 65307, 65311, 65315, 65318, 65322, 65326, 65330, 65334, - 65338, 65342, 65346, 65350, 65354, 65358, 65362, 65366, 65370, 65374, - 65378, 65382, 65386, 65390, 65394, 65398, 65402, 65406, 65410, 65414, - 65418, 65422, 65426, 65430, 65434, 65438, 65442, 65446, 65450, 65454, - 65458, 65462, 65466, 65470, 65474, 65478, 65482, 65486, 65490, 65494, - 65498, 65502, 65506, 65510, 65514, 65518, 65522, 65526, 65530, 65534, - 65538, 65542, 65546, 65550, 65554, 65558, 65562, 65566, 65570, 65574, - 65578, 65582, 65586, 65590, 65594, 65598, 65602, 65606, 65610, 65614, - 65618, 65622, 65626, 65630, 65634, 65638, 65642, 65646, 65650, 65654, - 65658, 65662, 65666, 65670, 65674, 65677, 65681, 65685, 65689, 65693, - 65697, 65701, 65705, 65709, 65713, 65717, 65721, 65725, 65729, 65733, - 65737, 65741, 65745, 65749, 65753, 65757, 65761, 65765, 65769, 65773, - 65777, 65781, 65785, 65789, 65793, 65797, 65801, 65805, 65809, 65813, - 65817, 65821, 65825, 65829, 65833, 65837, 65841, 65845, 65849, 65853, - 65857, 65861, 65865, 65869, 65873, 65877, 65881, 65885, 65889, 65893, - 65897, 65901, 65905, 65909, 65913, 65917, 65921, 65925, 65929, 65933, - 65937, 65941, 65945, 65949, 65953, 65957, 65961, 65965, 65969, 65973, - 65977, 65981, 65985, 65989, 65993, 65997, 66001, 66005, 66009, 66013, - 66017, 66021, 66025, 66029, 66033, 66037, 66041, 66045, 66049, 66053, - 66057, 66061, 66065, 66069, 66073, 66077, 66081, 66085, 66089, 66093, - 66097, 66101, 66105, 66109, 66113, 66117, 66121, 66125, 66129, 66133, - 66137, 66141, 66145, 66149, 66153, 66157, 66161, 66165, 66169, 66172, - 66176, 66180, 66184, 66188, 66192, 66196, 66200, 66204, 66208, 66212, - 66216, 66220, 66224, 66228, 66232, 66236, 66240, 66244, 66248, 66252, - 66256, 66260, 66264, 66268, 66272, 66276, 66280, 66284, 66288, 66292, - 66296, 66300, 66304, 66308, 66312, 66316, 66320, 66324, 66328, 66332, - 66336, 66340, 66344, 66348, 66352, 66356, 66360, 66364, 66368, 66372, - 66376, 66380, 66384, 66388, 66392, 66396, 66400, 66404, 66408, 66412, - 66416, 66420, 66424, 66428, 66432, 66436, 66440, 66444, 66448, 66452, - 66456, 66460, 66464, 66468, 66472, 66476, 66480, 66484, 66488, 66492, - 66496, 66500, 66504, 66508, 66512, 66516, 66520, 66524, 66528, 66532, - 66536, 66540, 66544, 66548, 66552, 66556, 66560, 66564, 66568, 66572, - 66576, 66580, 66584, 66588, 66592, 66596, 66600, 66604, 66608, 66612, - 66616, 66620, 66624, 66627, 66631, 66635, 66639, 66643, 66647, 66651, - 66655, 66659, 66663, 66667, 66671, 66675, 66679, 66683, 66687, 66691, - 66695, 66699, 66703, 66707, 66711, 66715, 66719, 66723, 66727, 66731, - 66735, 66739, 66743, 66747, 66751, 66755, 66759, 66763, 66767, 66771, - 66775, 66779, 66783, 66787, 66791, 66795, 66799, 66803, 66807, 66811, - 66815, 66819, 66823, 66827, 66831, 66835, 66839, 66843, 66847, 66851, - 66855, 66859, 66863, 66867, 66871, 66875, 66879, 66883, 66887, 66891, - 66895, 66899, 66903, 66907, 66911, 66915, 66919, 66923, 66927, 66931, - 66935, 66939, 66943, 66947, 66951, 66955, 66959, 66963, 66967, 66971, - 66975, 66979, 66983, 66987, 66991, 66995, 66999, 67003, 67007, 67011, - 67015, 67019, 67023, 67027, 67031, 67035, 67039, 67043, 67047, 67051, - 67055, 67059, 67063, 67067, 67071, 67075, 67079, 67083, 67087, 67091, - 67095, 67099, 67103, 67107, 67111, 67115, 67119, 67123, 67127, 67131, - 67135, 67139, 67143, 67147, 67151, 67155, 67159, 67163, 67167, 67171, - 67175, 67179, 67183, 67187, 67191, 67195, 67199, 67203, 67207, 67211, - 67215, 67219, 67223, 67227, 67230, 67234, 67238, 67242, 67246, 67250, - 67254, 67258, 67261, 67265, 67269, 67273, 67277, 67281, 67285, 67289, - 67293, 67297, 67301, 67305, 67309, 67313, 67317, 67321, 67325, 67329, - 67333, 67337, 67341, 67345, 67349, 67353, 67357, 67361, 67365, 67369, - 67373, 67377, 67381, 67385, 67389, 67393, 67397, 67401, 67405, 67409, - 67413, 67417, 67421, 67425, 67429, 67433, 67437, 67441, 67445, 67449, - 67453, 67457, 67461, 67465, 67469, 67473, 67477, 67481, 67485, 67489, - 67493, 67497, 67501, 67505, 67509, 67513, 67517, 67521, 67525, 67529, - 67533, 67537, 67541, 67545, 67549, 67553, 67557, 67561, 67565, 67569, - 67573, 67577, 67581, 67585, 67589, 67593, 67597, 67601, 67605, 67609, - 67613, 67617, 67621, 67625, 67629, 67633, 67637, 67641, 67645, 67649, - 67653, 67657, 67661, 67665, 67669, 67673, 67677, 67681, 67685, 67689, - 67693, 67697, 67701, 67705, 67709, 67713, 67717, 67721, 67725, 67729, - 67733, 67737, 67741, 67745, 67749, 67753, 67757, 67761, 67765, 67769, - 67773, 67777, 67781, 67785, 67789, 67793, 67797, 67801, 67805, 67809, - 67813, 67817, 67821, 67825, 67829, 67833, 67837, 67841, 67845, 67849, - 67853, 67857, 67861, 67865, 67869, 67873, 67877, 67881, 67885, 67889, - 67893, 67897, 67901, 67905, 67909, 67913, 67917, 67921, 67925, 67929, - 67933, 67937, 67941, 67945, 67949, 67953, 67957, 67961, 67965, 67969, - 67973, 67977, 67981, 67985, 67988, 67992, 67996, 68000, 68004, 68008, - 68012, 68016, 68020, 68024, 68028, 68032, 68036, 68040, 68044, 68048, - 68052, 68056, 68060, 68064, 68068, 68072, 68076, 68080, 68084, 68088, - 68092, 68096, 68100, 68104, 68108, 68112, 68116, 68120, 68124, 68128, - 68132, 68136, 68140, 68144, 68148, 68152, 68156, 68160, 68164, 68168, - 68172, 68176, 68180, 68184, 68188, 68192, 68196, 68200, 68204, 68208, - 68212, 68216, 68220, 68224, 68228, 68232, 68236, 68240, 68244, 68248, - 68252, 68256, 68260, 68264, 68268, 68272, 68276, 68280, 68284, 68288, - 68292, 68296, 68300, 68304, 68308, 68312, 68316, 68320, 68324, 68328, - 68332, 68336, 68340, 68344, 68348, 68352, 68356, 68360, 68364, 68368, - 68372, 68376, 68380, 68384, 68388, 68392, 68396, 68400, 68404, 68408, - 68412, 68416, 68420, 68424, 68428, 68432, 68436, 68440, 68444, 68448, - 68452, 68456, 68460, 68464, 68468, 68472, 68476, 68480, 68484, 68488, - 68492, 68496, 68500, 68504, 68508, 68512, 68516, 68520, 68524, 68528, - 68532, 68536, 68540, 68544, 68548, 68552, 68556, 68560, 68564, 68568, - 68572, 68576, 68580, 68584, 68588, 68592, 68596, 68600, 68604, 68608, - 68612, 68616, 68620, 68624, 68628, 68632, 68636, 68640, 68644, 68648, - 68652, 68656, 68660, 68664, 68668, 68672, 68676, 68680, 68684, 68688, - 68692, 68696, 68700, 68704, 68708, 68712, 68716, 68720, 68724, 68728, - 68732, 68736, 68740, 68744, 68748, 68752, 68756, 68760, 68764, 68768, 0, - 0, 0, 68772, 68776, 68780, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 68992, 68997, 69001, 69006, 69011, 69016, 69021, 69026, 69030, 69035, - 69040, 69045, 69050, 69055, 69060, 69065, 69069, 69073, 69078, 69082, - 69087, 69092, 69097, 69101, 69106, 69111, 69116, 69121, 69126, 69130, - 69135, 69139, 69144, 69148, 69153, 69157, 69161, 69165, 69170, 69175, - 69180, 69188, 69196, 69204, 69212, 69219, 69227, 69233, 69241, 69245, - 69249, 69253, 69257, 69261, 69265, 69269, 69273, 69277, 69281, 69285, - 69289, 69293, 69297, 69301, 69305, 69309, 69313, 69317, 69321, 69325, - 69329, 69333, 69337, 69341, 69345, 69349, 69353, 69357, 69361, 69365, - 69369, 69373, 69377, 69381, 69385, 69388, 69392, 69396, 69400, 69404, - 69408, 69412, 69416, 69420, 69424, 69428, 69432, 69436, 69440, 69444, - 69448, 69452, 69456, 69460, 69464, 69468, 69472, 69476, 69480, 69484, - 69488, 69492, 69496, 69500, 69504, 69508, 69512, 69516, 69520, 69524, - 69528, 69532, 69535, 69539, 69543, 69546, 69550, 69554, 69558, 69561, - 69565, 69569, 69573, 69577, 69581, 69585, 69589, 69593, 69597, 69601, - 69605, 69609, 69613, 69617, 69620, 69624, 69628, 69631, 69635, 69639, - 69643, 69647, 69651, 69655, 69658, 69661, 69665, 69669, 69673, 69676, - 69679, 69683, 69687, 69691, 69695, 69699, 69703, 69707, 69711, 69715, - 69719, 69723, 69727, 69731, 69735, 69739, 69743, 69747, 69751, 69755, - 69759, 69763, 69767, 69771, 69775, 69779, 69783, 69787, 69791, 69795, - 69799, 69803, 69807, 69811, 69815, 69819, 69823, 69827, 69830, 69834, - 69838, 69842, 69846, 69850, 69854, 69858, 69862, 69866, 69870, 69874, - 69878, 69882, 69886, 69890, 69894, 69898, 69902, 69906, 69910, 69914, - 69918, 69922, 69926, 69930, 69934, 69938, 69942, 69946, 69950, 69954, - 69958, 69962, 69966, 69970, 69974, 69977, 69981, 69985, 69989, 69993, - 69997, 70001, 70005, 70009, 70013, 70017, 70021, 70025, 70029, 70033, - 70037, 70041, 70044, 70048, 70052, 70056, 70060, 70064, 70068, 70072, - 70076, 70080, 70084, 70088, 70092, 70096, 70100, 70104, 70108, 70112, - 70116, 70120, 70124, 70128, 70131, 70135, 70139, 70143, 70147, 70151, - 70155, 70159, 70163, 70167, 70171, 70175, 70179, 70183, 70187, 70191, - 70195, 70199, 70203, 70207, 70211, 70215, 70219, 70223, 70227, 70231, - 70235, 70239, 70243, 70247, 70251, 70255, 70259, 70263, 70267, 70271, - 70275, 70279, 70283, 70287, 70291, 70295, 70299, 70303, 70306, 70311, - 70315, 70321, 70326, 70332, 70336, 70340, 70344, 70348, 70352, 70356, - 70360, 70364, 70368, 70372, 70376, 70380, 70384, 70388, 70391, 70394, - 70397, 70400, 70403, 70406, 70409, 70412, 70415, 70420, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70426, 70431, 70436, 70441, - 70446, 70453, 70460, 70465, 70470, 70475, 70480, 70487, 70494, 70501, - 70508, 70515, 70522, 70532, 70542, 70549, 70556, 70563, 70570, 70576, - 70582, 70591, 70600, 70607, 70614, 70625, 70636, 70641, 70646, 70653, - 70660, 70667, 70674, 70681, 70688, 70695, 70702, 70708, 70714, 70720, - 70726, 70733, 70740, 70745, 70749, 70756, 70763, 70770, 70774, 70781, - 70785, 70790, 70794, 70800, 70805, 70811, 70816, 70820, 70824, 70827, - 70830, 70835, 70840, 70845, 70850, 70855, 70860, 70865, 70870, 70875, - 70880, 70889, 70898, 70903, 70908, 70913, 70918, 70923, 70928, 70933, - 70938, 70943, 70948, 70953, 0, 0, 0, 0, 0, 0, 0, 70958, 70964, 70967, - 70970, 70973, 70977, 70981, 70985, 70989, 70992, 70996, 70999, 71003, - 71006, 71010, 71014, 71018, 71022, 71026, 71030, 71034, 71037, 71041, - 71045, 71049, 71053, 71057, 71061, 71065, 71069, 71073, 71077, 71081, - 71085, 71089, 71093, 71096, 71100, 71104, 71108, 71112, 71116, 71120, - 71124, 71128, 71132, 71136, 71140, 71144, 71148, 71152, 71156, 71160, - 71164, 71168, 71172, 71176, 71180, 71184, 71188, 71192, 71195, 71199, - 71203, 71207, 71211, 71215, 71219, 71223, 71226, 71230, 71234, 71238, - 71242, 71246, 71250, 71254, 71258, 71262, 71266, 71270, 71274, 71279, - 71284, 71287, 71292, 71295, 71298, 71301, 0, 0, 0, 0, 0, 0, 0, 0, 71305, - 71314, 71323, 71332, 71341, 71350, 71359, 71368, 71377, 71385, 71392, - 71400, 71407, 71415, 71425, 71434, 71444, 71453, 71463, 71471, 71478, - 71486, 71493, 71501, 71506, 71511, 71516, 71525, 71531, 71537, 71544, - 71553, 71561, 71569, 71577, 71584, 71591, 71598, 71605, 71610, 71615, - 71620, 71625, 71630, 71635, 71640, 71645, 71653, 71661, 71667, 71673, - 71678, 71683, 71688, 71693, 71698, 71703, 71708, 71713, 71721, 71729, - 71734, 71739, 71749, 71759, 71766, 71773, 71782, 71791, 71803, 71815, - 71821, 71827, 71835, 71843, 71853, 71863, 71870, 71877, 71882, 71887, - 71899, 71911, 71919, 71927, 71937, 71947, 71959, 71971, 71980, 71989, - 71996, 72003, 72010, 72017, 72026, 72035, 72040, 72045, 72052, 72059, - 72066, 72073, 72085, 72097, 72102, 72107, 72112, 72117, 72122, 72127, - 72132, 72137, 72141, 72146, 72151, 72156, 72161, 72166, 72172, 72177, - 72182, 72189, 72196, 72203, 72210, 72217, 72226, 72235, 72241, 72247, - 72253, 72259, 72266, 72273, 72280, 72287, 72294, 72298, 72305, 72310, - 72315, 72322, 0, 72335, 72343, 72351, 72358, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 72365, 72374, 72383, 72392, 72401, 72410, 72419, 72428, 72437, - 72446, 72455, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 72462, 72469, 72475, 72482, 72490, 72498, - 72505, 72513, 72520, 72526, 72532, 72539, 72545, 72551, 72557, 72564, - 72571, 72578, 72585, 72592, 72599, 72606, 72613, 72620, 72627, 72634, - 72641, 72648, 72655, 72661, 72668, 72675, 72682, 72689, 72696, 72703, - 72710, 72717, 72724, 72731, 72738, 72745, 72752, 72759, 72766, 72773, - 72780, 72787, 72795, 72803, 72811, 72819, 0, 0, 0, 0, 72827, 72836, - 72845, 72854, 72863, 72872, 72881, 72888, 72895, 72902, 0, 0, 0, 0, 0, 0, - 72909, 72913, 72918, 72923, 72928, 72933, 72938, 72943, 72948, 72953, - 72958, 72963, 72967, 72971, 72976, 72981, 72985, 72990, 72995, 73000, - 73005, 73010, 73015, 73020, 73024, 73028, 73033, 73038, 73042, 73046, - 73050, 73054, 73058, 73062, 73066, 73071, 73076, 73081, 73086, 73091, - 73098, 73104, 73109, 73114, 73119, 73124, 73130, 73137, 73143, 73150, - 73156, 73162, 73167, 73174, 73180, 73185, 0, 0, 0, 0, 0, 0, 0, 0, 73191, - 73195, 73199, 73202, 73206, 73209, 73213, 73216, 73220, 73224, 73229, - 73233, 73238, 73241, 73245, 73249, 73252, 73256, 73260, 73263, 73267, - 73271, 73275, 73279, 73283, 73287, 73291, 73295, 73299, 73303, 73307, - 73311, 73315, 73319, 73323, 73327, 73331, 73335, 73338, 73341, 73345, - 73349, 73353, 73356, 73359, 73362, 73366, 73370, 73374, 73378, 73381, - 73384, 73388, 73393, 73398, 73402, 73407, 73411, 73416, 73421, 73427, - 73432, 73438, 73442, 73447, 73452, 73456, 73461, 73466, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 73470, 73473, 73477, 73481, 73484, 73487, 73490, 73493, 73496, - 73499, 73502, 73505, 0, 0, 0, 0, 0, 0, 73508, 73513, 73517, 73521, 73525, - 73529, 73533, 73537, 73541, 73545, 73549, 73553, 73557, 73561, 73565, - 73569, 73573, 73578, 73583, 73589, 73595, 73602, 73607, 73612, 73618, - 73622, 73627, 73630, 0, 0, 0, 0, 73633, 73640, 73646, 73652, 73658, - 73664, 73670, 73676, 73682, 73688, 73694, 73700, 73707, 73714, 73721, - 73727, 73734, 73741, 73748, 73755, 73762, 73768, 73774, 73781, 73787, - 73794, 73801, 73807, 73813, 73820, 73827, 73834, 73840, 73847, 73854, - 73860, 73867, 73873, 73880, 73887, 73893, 73899, 73906, 73912, 73919, - 73926, 73935, 73942, 73949, 73953, 73958, 73963, 73968, 73973, 73977, - 73981, 73986, 73990, 73995, 74000, 74005, 74009, 74013, 74018, 74022, - 74027, 74031, 74036, 74041, 74046, 74051, 74055, 74060, 74065, 74070, - 74076, 74081, 74087, 74093, 74099, 74105, 74111, 74116, 74122, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 74126, 74131, 74135, 74139, 74143, 74147, 74151, - 74155, 74159, 74163, 74167, 74171, 74175, 74179, 74183, 74187, 74191, - 74195, 74199, 74203, 74207, 74211, 74215, 74219, 74223, 74227, 74231, - 74235, 74239, 74243, 0, 0, 0, 74247, 74251, 74255, 74259, 74263, 74266, - 74272, 74275, 74279, 74282, 74288, 74294, 74302, 74305, 74309, 74312, - 74315, 74321, 74327, 74331, 74337, 74341, 74345, 74351, 74355, 74361, - 74367, 74371, 74375, 74381, 74385, 74391, 74397, 74401, 74407, 74411, - 74417, 74420, 74423, 74429, 74433, 74439, 74442, 74445, 74448, 74454, - 74458, 74462, 74468, 74474, 74477, 74480, 74486, 74491, 74496, 74501, - 74508, 74513, 74520, 74525, 74532, 74537, 74542, 74547, 74552, 74555, - 74559, 74563, 74568, 74573, 74578, 74583, 74588, 74593, 74598, 74603, - 74610, 74615, 0, 74622, 74625, 74629, 74632, 74635, 74638, 74641, 74644, - 74647, 74650, 74653, 0, 0, 0, 0, 74656, 74663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 74668, 74671, 74674, 74677, 74680, 74684, 74687, 74690, 74694, 74698, - 74702, 74706, 74710, 74714, 74718, 74722, 74726, 74730, 74734, 74738, - 74742, 74746, 74750, 74754, 74758, 74761, 74765, 74768, 74772, 74776, - 74780, 74784, 74788, 74791, 74795, 74798, 74801, 74805, 74809, 74813, - 74816, 74819, 74824, 74828, 74833, 74838, 74842, 74847, 74851, 74856, - 74861, 74866, 74870, 74874, 74879, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74884, - 74889, 74894, 74899, 74905, 74910, 74915, 74920, 74925, 74930, 74934, - 74938, 74943, 74948, 0, 0, 74954, 74958, 74961, 74964, 74967, 74970, - 74973, 74976, 74979, 74982, 0, 0, 74985, 74990, 74995, 75001, 75008, - 75014, 75020, 75026, 75032, 75038, 75044, 75050, 75056, 75062, 75068, - 75074, 75079, 75084, 75089, 75095, 75101, 75108, 75114, 75120, 75125, - 75132, 75139, 75146, 75152, 75157, 75162, 75167, 0, 0, 0, 0, 75175, - 75181, 75187, 75193, 75199, 75205, 75211, 75217, 75223, 75229, 75235, - 75241, 75247, 75253, 75259, 75265, 75271, 75277, 75283, 75289, 75295, - 75300, 75305, 75311, 75317, 75323, 75329, 75335, 75341, 75347, 75353, - 75359, 75365, 75371, 75377, 75383, 75389, 75395, 75401, 75407, 75413, - 75419, 75425, 75431, 75437, 75443, 75449, 75454, 75459, 75465, 75470, - 75474, 75479, 75483, 75487, 75491, 75497, 75502, 75507, 75512, 75517, - 75522, 75527, 75532, 75539, 75546, 75553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75560, 75565, 75570, 75575, - 75582, 75589, 75593, 75597, 75602, 75607, 75612, 75617, 75622, 75627, - 75632, 75637, 75642, 75648, 75654, 75660, 75666, 75672, 75676, 75682, - 75686, 75692, 75699, 75705, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75709, 75713, - 75717, 75721, 75725, 75729, 0, 0, 75733, 75737, 75741, 75745, 75749, - 75753, 0, 0, 75757, 75761, 75765, 75769, 75773, 75777, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 75781, 75785, 75789, 75793, 75797, 75801, 75805, 0, 75809, - 75813, 75817, 75821, 75825, 75829, 75833, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 66088, 66097, 66106, 66117, 66124, 66129, 66134, 66141, 66148, 66154, + 66159, 66164, 66169, 66174, 66181, 66186, 66191, 66196, 66207, 66212, + 66217, 66224, 66229, 66236, 66241, 66246, 66253, 66260, 66267, 66276, + 66285, 66290, 66295, 66300, 66307, 66312, 66322, 66329, 66334, 66339, + 66344, 66349, 66354, 66359, 66368, 66375, 66382, 66387, 66394, 66399, + 66406, 66415, 66426, 66431, 66440, 66445, 66452, 66461, 66470, 66475, + 66480, 66487, 66493, 66500, 66507, 66511, 66515, 66518, 66522, 66526, + 66530, 66534, 66538, 66542, 66546, 66549, 66553, 66557, 66561, 66565, + 66569, 66573, 66576, 66580, 66584, 66587, 66591, 66595, 66599, 66603, + 66607, 66611, 66615, 66619, 66623, 66627, 66631, 66635, 66639, 66643, + 66647, 66651, 66655, 66659, 66663, 66667, 66671, 66675, 66679, 66683, + 66687, 66691, 66695, 66699, 66703, 66707, 66711, 66715, 66719, 66723, + 66727, 66731, 66735, 66739, 66743, 66747, 66751, 66755, 66759, 66763, + 66766, 66770, 66774, 66778, 66782, 66786, 66790, 66794, 66798, 66802, + 66806, 66810, 66814, 66818, 66822, 66826, 66830, 66834, 66838, 66842, + 66846, 66850, 66854, 66858, 66862, 66866, 66870, 66874, 66878, 66882, + 66886, 66890, 66894, 66898, 66902, 66906, 66910, 66914, 66918, 66922, + 66926, 66930, 66934, 66938, 66942, 66946, 66950, 66954, 66958, 66962, + 66966, 66970, 66974, 66978, 66982, 66986, 66990, 66994, 66998, 67002, + 67006, 67010, 67014, 67018, 67022, 67026, 67030, 67034, 67038, 67042, + 67046, 67050, 67054, 67058, 67062, 67066, 67070, 67074, 67078, 67082, + 67086, 67090, 67094, 67098, 67102, 67106, 67110, 67114, 67118, 67122, + 67126, 67130, 67134, 67138, 67142, 67146, 67150, 67154, 67158, 67162, + 67166, 67170, 67174, 67178, 67182, 67186, 67190, 67194, 67198, 67202, + 67206, 67210, 67214, 67218, 67222, 67226, 67230, 67234, 67237, 67241, + 67245, 67249, 67253, 67257, 67261, 67265, 67269, 67273, 67277, 67281, + 67285, 67289, 67293, 67297, 67301, 67305, 67309, 67313, 67317, 67321, + 67325, 67329, 67333, 67337, 67341, 67345, 67349, 67353, 67357, 67361, + 67365, 67369, 67373, 67377, 67381, 67385, 67389, 67393, 67397, 67401, + 67405, 67409, 67413, 67417, 67421, 67425, 67429, 67433, 67437, 67441, + 67445, 67449, 67453, 67457, 67461, 67465, 67469, 67473, 67477, 67481, + 67485, 67489, 67493, 67497, 67501, 67505, 67509, 67513, 67517, 67521, + 67525, 67529, 67533, 67537, 67541, 67545, 67549, 67553, 67557, 67561, + 67565, 67569, 67573, 67577, 67581, 67585, 67589, 67593, 67597, 67601, + 67605, 67609, 67613, 67617, 67621, 67625, 67629, 67633, 67637, 67641, + 67645, 67649, 67653, 67657, 67661, 67665, 67669, 67673, 67677, 67681, + 67685, 67689, 67693, 67697, 67700, 67704, 67708, 67712, 67716, 67720, + 67724, 67728, 67732, 67736, 67740, 67744, 67748, 67752, 67756, 67760, + 67764, 67768, 67772, 67776, 67780, 67784, 67788, 67792, 67796, 67800, + 67804, 67808, 67812, 67816, 67820, 67824, 67828, 67832, 67836, 67840, + 67844, 67848, 67852, 67856, 67860, 67864, 67868, 67872, 67876, 67880, + 67884, 67888, 67892, 67896, 67900, 67904, 67908, 67912, 67916, 67920, + 67924, 67928, 67932, 67936, 67940, 67944, 67948, 67952, 67956, 67960, + 67964, 67968, 67972, 67976, 67980, 67984, 67988, 67992, 67996, 68000, + 68004, 68008, 68012, 68016, 68020, 68024, 68028, 68032, 68036, 68040, + 68044, 68048, 68052, 68056, 68060, 68064, 68068, 68072, 68076, 68080, + 68084, 68088, 68092, 68096, 68100, 68104, 68108, 68112, 68116, 68120, + 68124, 68128, 68132, 68136, 68140, 68144, 68148, 68152, 68156, 68160, + 68164, 68168, 68172, 68176, 68180, 68184, 68188, 68192, 68196, 68200, + 68204, 68208, 68212, 68216, 68220, 68224, 68228, 68232, 68236, 68240, + 68244, 68248, 68252, 68256, 68260, 68264, 68268, 68272, 68276, 68280, + 68284, 68288, 68292, 68296, 68300, 68304, 68308, 68312, 68316, 68320, + 68324, 68328, 68332, 68336, 68340, 68344, 68348, 68352, 68356, 68360, + 68364, 68368, 68372, 68376, 68380, 68384, 68388, 68392, 68396, 68400, + 68404, 68408, 68412, 68416, 68420, 68424, 68428, 68432, 68436, 68440, + 68444, 68448, 68452, 68456, 68460, 68464, 68468, 68472, 68476, 68480, + 68484, 68488, 68492, 68496, 68500, 68504, 68508, 68512, 68516, 68520, + 68524, 68528, 68532, 68536, 68540, 68544, 68548, 68552, 68555, 68559, + 68563, 68567, 68571, 68575, 68579, 68583, 68587, 68591, 68595, 68599, + 68603, 68607, 68611, 68615, 68619, 68623, 68627, 68631, 68635, 68639, + 68643, 68647, 68651, 68655, 68659, 68663, 68667, 68671, 68675, 68679, + 68683, 68687, 68691, 68695, 68699, 68703, 68707, 68711, 68715, 68719, + 68723, 68727, 68731, 68735, 68739, 68743, 68747, 68751, 68755, 68759, + 68763, 68767, 68771, 68775, 68779, 68783, 68787, 68791, 68795, 68799, + 68803, 68807, 68811, 68815, 68819, 68823, 68827, 68831, 68835, 68839, + 68843, 68847, 68851, 68855, 68859, 68863, 68867, 68871, 68875, 68879, + 68883, 68887, 68891, 68895, 68899, 68903, 68907, 68911, 68915, 68919, + 68923, 68927, 68931, 68935, 68939, 68943, 68947, 68951, 68955, 68959, + 68963, 68967, 68971, 68975, 68979, 68983, 68987, 68991, 68995, 68999, + 69003, 69007, 69010, 69014, 69018, 69022, 69026, 69030, 69034, 69038, + 69042, 69046, 69050, 69054, 69058, 69062, 69066, 69070, 69074, 69078, + 69082, 69086, 69090, 69094, 69098, 69102, 69106, 69110, 69114, 69118, + 69122, 69126, 69130, 69134, 69138, 69142, 69146, 69150, 69154, 69158, + 69162, 69166, 69170, 69174, 69178, 69182, 69186, 69190, 69194, 69198, + 69202, 69206, 69210, 69214, 69218, 69222, 69226, 69230, 69234, 69238, + 69242, 69246, 69250, 69254, 69258, 69262, 69266, 69270, 69274, 69278, + 69282, 69286, 69290, 69294, 69298, 69302, 69306, 69310, 69314, 69318, + 69322, 69326, 69330, 69334, 69338, 69342, 69346, 69350, 69354, 69358, + 69362, 69366, 69370, 69374, 69378, 69382, 69386, 69390, 69394, 69398, + 69402, 69406, 69410, 69414, 69418, 69422, 69426, 69430, 69434, 69438, + 69442, 69446, 69450, 69454, 69458, 69462, 69466, 69470, 69474, 69478, + 69482, 69486, 69490, 69494, 69498, 69502, 69506, 69510, 69514, 69518, + 69522, 69526, 69530, 69534, 69538, 69542, 69546, 69550, 69554, 69558, + 69562, 69566, 69570, 69574, 69578, 69582, 69586, 69590, 69594, 69598, + 69602, 69606, 69610, 69613, 69617, 69621, 69625, 69629, 69633, 69637, + 69641, 69645, 69649, 69653, 69657, 69661, 69665, 69669, 69673, 69677, + 69681, 69685, 69689, 69693, 69697, 69701, 69705, 69709, 69713, 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, 70077, + 70081, 70085, 70089, 70093, 70097, 70101, 70105, 70109, 70113, 70117, + 70121, 70125, 70129, 70133, 70137, 70141, 70145, 70149, 70153, 70157, + 70161, 70165, 70169, 70173, 70177, 70181, 70185, 70189, 70193, 70197, + 70201, 70205, 70209, 70213, 70217, 70221, 70225, 70229, 70233, 70237, + 70241, 70245, 70249, 70253, 70257, 70261, 70265, 70269, 70273, 70277, + 70281, 70285, 70289, 70293, 70297, 70301, 70305, 70309, 70313, 70317, + 70321, 70325, 70329, 70333, 70337, 70341, 70345, 70349, 70353, 70357, + 70361, 70365, 70369, 70373, 70377, 70381, 70385, 70389, 70393, 70397, + 70401, 70405, 70409, 70413, 70417, 70421, 70425, 70429, 70433, 70437, + 70441, 70445, 70449, 70453, 70457, 70461, 70465, 70469, 70473, 70477, + 70481, 70485, 70489, 70493, 70497, 70501, 70505, 70509, 70513, 70517, + 70521, 70525, 70529, 70533, 70537, 70541, 70545, 70549, 70553, 70557, + 70561, 70565, 70569, 70573, 70577, 70581, 70585, 70589, 70593, 70597, + 70601, 70605, 70609, 70613, 70617, 70621, 70625, 70629, 70633, 70637, + 70641, 70645, 70649, 70653, 70657, 70661, 70665, 70669, 70673, 70677, + 70681, 70685, 70689, 70693, 70697, 70701, 70705, 70709, 70713, 70717, + 70721, 70725, 70729, 70733, 70737, 70741, 70745, 70749, 70753, 70757, + 70761, 70765, 70769, 70773, 70777, 70781, 70785, 70789, 70793, 70797, + 70801, 70805, 70809, 70813, 70817, 70821, 70825, 70829, 70833, 70837, + 70841, 70845, 70849, 70853, 70857, 70861, 70865, 70869, 70873, 70877, + 70881, 70885, 70889, 70893, 70897, 70901, 70905, 70909, 70913, 70917, + 70921, 70925, 70929, 70933, 70937, 70941, 70945, 70949, 70953, 70957, + 70961, 70965, 70969, 70973, 70977, 70981, 70985, 70989, 70993, 70997, + 71001, 71005, 71009, 71013, 71017, 71021, 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, 0, 0, 0, + 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71377, + 71382, 71386, 71391, 71396, 71401, 71406, 71411, 71415, 71420, 71425, + 71430, 71435, 71440, 71445, 71450, 71454, 71459, 71464, 71469, 71474, + 71479, 71484, 71488, 71493, 71498, 71503, 71508, 71513, 71517, 71522, + 71526, 71531, 71535, 71540, 71544, 71548, 71552, 71557, 71562, 71567, + 71575, 71583, 71591, 71599, 71607, 71615, 71621, 71629, 71633, 71637, + 71641, 71645, 71649, 71653, 71657, 71661, 71665, 71669, 71673, 71677, + 71681, 71685, 71689, 71693, 71697, 71701, 71705, 71709, 71713, 71717, + 71721, 71725, 71729, 71733, 71737, 71741, 71745, 71749, 71753, 71757, + 71761, 71765, 71769, 71773, 71776, 71780, 71784, 71788, 71792, 71796, + 71800, 71804, 71808, 71812, 71816, 71820, 71824, 71828, 71832, 71836, + 71840, 71844, 71848, 71852, 71856, 71860, 71864, 71868, 71872, 71876, + 71880, 71884, 71888, 71892, 71896, 71900, 71904, 71908, 71912, 71916, + 71920, 71923, 71927, 71931, 71934, 71938, 71942, 71946, 71949, 71953, + 71957, 71961, 71965, 71969, 71973, 71977, 71981, 71985, 71989, 71993, + 71997, 72001, 72005, 72009, 72013, 72017, 72021, 72025, 72029, 72033, + 72037, 72041, 72045, 72048, 72051, 72055, 72059, 72063, 72066, 72070, + 72074, 72078, 72082, 72086, 72090, 72094, 72098, 72102, 72106, 72110, + 72114, 72118, 72122, 72126, 72130, 72134, 72138, 72142, 72146, 72150, + 72154, 72158, 72162, 72166, 72170, 72174, 72178, 72182, 72186, 72190, + 72194, 72198, 72202, 72206, 72210, 72214, 72218, 72221, 72225, 72229, + 72233, 72237, 72241, 72245, 72249, 72253, 72257, 72261, 72265, 72269, + 72273, 72277, 72281, 72285, 72289, 72293, 72297, 72301, 72305, 72309, + 72313, 72317, 72321, 72325, 72329, 72333, 72337, 72341, 72345, 72349, + 72353, 72357, 72361, 72365, 72368, 72372, 72376, 72380, 72384, 72388, + 72392, 72396, 72400, 72404, 72408, 72412, 72416, 72420, 72424, 72428, + 72432, 72435, 72439, 72443, 72447, 72451, 72455, 72459, 72463, 72467, + 72471, 72475, 72479, 72483, 72487, 72491, 72495, 72499, 72503, 72507, + 72511, 72515, 72519, 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, 72697, 72702, 72706, + 72712, 72717, 72723, 72727, 72731, 72735, 72739, 72743, 72747, 72751, + 72755, 72759, 72763, 72767, 72771, 72775, 72779, 72782, 72785, 72788, + 72791, 72794, 72797, 72801, 72804, 72808, 72813, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 72819, 72824, 72829, 72834, 72839, + 72846, 72853, 72858, 72863, 72868, 72873, 72880, 72887, 72894, 72901, + 72908, 72915, 72925, 72935, 72942, 72949, 72956, 72963, 72969, 72975, + 72984, 72993, 73000, 73007, 73018, 73029, 73034, 73039, 73046, 73053, + 73060, 73067, 73074, 73081, 73088, 73095, 73101, 73107, 73113, 73119, + 73126, 73133, 73138, 73142, 73149, 73156, 73163, 73167, 73174, 73178, + 73183, 73187, 73193, 73198, 73204, 73209, 73213, 73217, 73220, 73223, + 73228, 73233, 73238, 73243, 73248, 73253, 73258, 73263, 73268, 73273, + 73281, 73289, 73294, 73299, 73304, 73309, 73314, 73319, 73324, 73329, + 73334, 73339, 73344, 73349, 73354, 73359, 73365, 73371, 73377, 73383, + 73388, 73394, 73397, 73400, 73403, 73407, 73411, 73415, 73419, 73422, + 73426, 73429, 73433, 73436, 73440, 73444, 73448, 73452, 73456, 73460, + 73464, 73468, 73472, 73476, 73480, 73484, 73488, 73492, 73496, 73500, + 73504, 73508, 73512, 73516, 73520, 73524, 73527, 73531, 73535, 73539, + 73543, 73547, 73551, 73555, 73559, 73563, 73567, 73571, 73575, 73579, + 73583, 73587, 73591, 73595, 73599, 73603, 73607, 73611, 73615, 73619, + 73623, 73627, 73631, 73635, 73639, 73643, 73647, 73651, 73655, 73658, + 73662, 73666, 73670, 73674, 73678, 73682, 73686, 73690, 73694, 73698, + 73702, 73706, 73711, 73716, 73719, 73724, 73727, 73730, 73733, 0, 0, 0, + 0, 0, 0, 0, 0, 73737, 73746, 73755, 73764, 73773, 73782, 73791, 73800, + 73809, 73817, 73824, 73832, 73839, 73847, 73857, 73866, 73876, 73885, + 73895, 73903, 73910, 73918, 73925, 73933, 73938, 73943, 73949, 73958, + 73964, 73970, 73977, 73986, 73994, 74002, 74010, 74017, 74024, 74031, + 74038, 74043, 74048, 74053, 74058, 74063, 74068, 74073, 74078, 74086, + 74094, 74100, 74105, 74110, 74115, 74120, 74125, 74130, 74135, 74140, + 74145, 74154, 74163, 74168, 74173, 74183, 74193, 74200, 74207, 74216, + 74225, 74237, 74249, 74255, 74261, 74269, 74277, 74287, 74297, 74304, + 74311, 74316, 74321, 74333, 74345, 74353, 74361, 74371, 74381, 74393, + 74405, 74414, 74423, 74430, 74437, 74444, 74451, 74460, 74469, 74474, + 74479, 74486, 74493, 74500, 74507, 74519, 74531, 74536, 74541, 74546, + 74551, 74556, 74561, 74566, 74571, 74575, 74580, 74585, 74590, 74595, + 74600, 74606, 74611, 74616, 74623, 74630, 74637, 74644, 74651, 74660, + 74669, 74675, 74681, 74687, 74693, 74699, 74705, 74712, 74719, 74726, + 74730, 74737, 74742, 74747, 74754, 74767, 74773, 74781, 74789, 74796, + 74803, 74812, 74821, 74828, 74835, 74842, 74849, 74856, 74863, 74870, + 74877, 74884, 74891, 74900, 74909, 74918, 74927, 74936, 74945, 74954, + 74963, 74972, 74981, 74988, 74995, 75001, 0, 0, 75009, 75016, 75023, + 75031, 75036, 75041, 75046, 75051, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 75056, 75063, 75070, 75076, 75084, 75092, 75100, 75108, 75116, + 75124, 75130, 75136, 75143, 75149, 75155, 75161, 75168, 75175, 75182, + 75189, 75196, 75203, 75210, 75217, 75224, 75231, 75238, 75245, 75252, + 75259, 75265, 75272, 75279, 75286, 75293, 75300, 75307, 75314, 75321, + 75328, 75335, 75342, 75349, 75356, 75363, 75370, 75377, 75384, 75391, + 75399, 75407, 75415, 75423, 0, 0, 0, 0, 75431, 75439, 75447, 75455, + 75463, 75471, 75479, 75485, 75491, 75497, 0, 0, 0, 0, 0, 0, 75503, 75507, + 75512, 75517, 75522, 75527, 75532, 75537, 75542, 75547, 75552, 75557, + 75562, 75566, 75571, 75576, 75580, 75585, 75590, 75595, 75600, 75605, + 75610, 75615, 75619, 75624, 75629, 75634, 75639, 75643, 75647, 75651, + 75655, 75659, 75663, 75668, 75673, 75678, 75683, 75688, 75695, 75701, + 75706, 75711, 75716, 75721, 75727, 75734, 75740, 75747, 75754, 75761, + 75766, 75773, 75779, 75784, 0, 0, 0, 0, 0, 0, 0, 0, 75790, 75795, 75800, + 75804, 75809, 75813, 75818, 75822, 75827, 75832, 75838, 75843, 75849, + 75853, 75858, 75863, 75867, 75872, 75877, 75881, 75886, 75891, 75896, + 75901, 75906, 75911, 75916, 75921, 75926, 75931, 75936, 75941, 75946, + 75951, 75956, 75961, 75966, 75971, 75976, 75980, 75985, 75990, 75995, + 75999, 76003, 76008, 76013, 76018, 76023, 76028, 76033, 76037, 76042, + 76048, 76054, 76059, 76065, 76070, 76076, 76082, 76089, 76095, 76102, + 76107, 76113, 76119, 76124, 76130, 76136, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 76141, 76145, 76150, 76155, 76159, 76163, 76167, 76171, 76175, 76179, + 76184, 76188, 0, 0, 0, 0, 0, 0, 76193, 76198, 76202, 76206, 76210, 76214, + 76218, 76222, 76227, 76231, 76236, 76240, 76244, 76248, 76253, 76257, + 76262, 76267, 76272, 76278, 76284, 76291, 76296, 76301, 76307, 76311, + 76316, 76319, 76322, 76326, 0, 0, 76331, 76338, 76344, 76350, 76356, + 76362, 76368, 76374, 76381, 76387, 76394, 76400, 76407, 76414, 76421, + 76428, 76435, 76442, 76449, 76456, 76463, 76470, 76476, 76483, 76489, + 76496, 76503, 76510, 76516, 76523, 76530, 76537, 76543, 76550, 76557, + 76563, 76570, 76576, 76583, 76590, 76596, 76602, 76609, 76615, 76622, + 76629, 76638, 76645, 76652, 76656, 76661, 76666, 76671, 76676, 76681, + 76685, 76690, 76694, 76699, 76704, 76709, 76714, 76719, 76724, 76728, + 76733, 76737, 76742, 76747, 76752, 76757, 76761, 76766, 76771, 76776, + 76782, 76787, 76793, 76799, 76805, 76811, 76817, 76822, 76828, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 76832, 76837, 76841, 76845, 76849, 76853, 76857, + 76861, 76865, 76869, 76873, 76877, 76881, 76885, 76889, 76893, 76897, + 76901, 76905, 76909, 76913, 76917, 76921, 76925, 76929, 76933, 76937, + 76941, 76945, 76949, 0, 0, 0, 76953, 76957, 76961, 76965, 76969, 76972, + 76978, 76981, 76985, 76988, 76994, 77000, 77008, 77011, 77015, 77018, + 77021, 77027, 77033, 77037, 77043, 77047, 77051, 77057, 77061, 77067, + 77073, 77077, 77081, 77087, 77091, 77097, 77103, 77107, 77113, 77117, + 77123, 77127, 77130, 77136, 77140, 77146, 77149, 77152, 77156, 77162, + 77166, 77170, 77176, 77182, 77186, 77189, 77195, 77200, 77205, 77210, + 77217, 77222, 77229, 77234, 77241, 77246, 77251, 77256, 77261, 77264, + 77268, 77272, 77277, 77282, 77287, 77292, 77297, 77302, 77307, 77312, + 77319, 77324, 0, 77331, 77334, 77338, 77341, 77344, 77347, 77350, 77353, + 77356, 77360, 77363, 0, 0, 0, 0, 77367, 77374, 77379, 77385, 77391, + 77397, 77403, 77409, 77415, 77422, 77429, 77436, 77443, 77450, 77457, + 77464, 77471, 77478, 77485, 77492, 77498, 77504, 77510, 77516, 77522, + 77528, 77535, 77541, 77548, 77555, 77562, 77569, 77576, 0, 77583, 77587, + 77591, 77595, 77599, 77604, 77608, 77612, 77617, 77622, 77627, 77632, + 77637, 77642, 77647, 77652, 77657, 77662, 77667, 77672, 77677, 77682, + 77687, 77692, 77697, 77702, 77707, 77711, 77716, 77721, 77726, 77731, + 77736, 77740, 77745, 77749, 77754, 77759, 77764, 77769, 77774, 77778, + 77784, 77789, 77795, 77801, 77806, 77812, 77817, 77823, 77829, 77835, + 77840, 77846, 77852, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77858, 77864, 77870, + 77876, 77883, 77889, 77895, 77901, 77907, 77913, 77918, 77923, 77929, + 77936, 0, 0, 77943, 77948, 77952, 77956, 77960, 77964, 77968, 77972, + 77977, 77981, 0, 0, 77986, 77992, 77998, 78005, 78013, 78019, 78025, + 78031, 78037, 78043, 78049, 78055, 78061, 78067, 78073, 78079, 78085, + 78091, 78096, 78102, 78108, 78115, 78121, 78127, 78133, 78140, 78147, + 78154, 78160, 78165, 78170, 78176, 78184, 78191, 78198, 78206, 78214, + 78221, 78228, 78235, 78242, 78249, 78256, 78263, 78270, 78277, 78284, + 78291, 78298, 78305, 78312, 78319, 78326, 78333, 78340, 78347, 78354, + 78360, 78366, 78373, 78380, 78387, 78394, 78401, 78408, 78415, 78422, + 78429, 78436, 78443, 78450, 78457, 78464, 78471, 78478, 78485, 78492, + 78499, 78506, 78513, 78520, 78527, 78534, 78540, 78546, 78553, 78559, + 78564, 78570, 78575, 78580, 78585, 78592, 78598, 78604, 78610, 78616, + 78622, 78628, 78634, 78642, 78650, 78658, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78666, 78672, 78678, 78684, + 78692, 78700, 78706, 78712, 78719, 78726, 78733, 78740, 78747, 78754, + 78761, 78768, 78775, 78783, 78791, 78799, 78807, 78815, 78821, 78829, + 78835, 78843, 78852, 78860, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78866, 78870, + 78874, 78878, 78882, 78886, 0, 0, 78890, 78894, 78898, 78902, 78906, + 78910, 0, 0, 78914, 78918, 78922, 78926, 78930, 78934, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 78938, 78942, 78946, 78950, 78954, 78958, 78962, 0, 78966, + 78970, 78974, 78978, 78982, 78986, 78990, 0, 78994, 79001, 79007, 79013, + 79019, 79026, 79033, 79042, 79053, 79063, 79072, 79080, 79088, 79096, + 79102, 79110, 79117, 79124, 79133, 79144, 79152, 79162, 79168, 79178, + 79187, 79192, 79200, 79209, 79214, 79223, 79230, 79240, 79252, 79257, + 79264, 79271, 79276, 79286, 79296, 79306, 79316, 79331, 79344, 79355, + 79363, 79368, 79379, 79388, 79395, 79402, 79408, 79414, 79419, 79426, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 79432, 79436, 79440, 79444, 79448, 79452, + 79457, 79462, 79466, 79471, 79476, 79481, 79486, 79491, 79495, 79500, + 79505, 79510, 79515, 79520, 79525, 79530, 79535, 79540, 79545, 79550, + 79554, 79559, 79564, 79569, 79574, 79579, 79584, 79589, 79594, 79599, + 79604, 79609, 79614, 79619, 79624, 79629, 79634, 79639, 79644, 79649, + 79653, 79658, 79663, 79668, 79673, 79678, 79683, 79688, 79693, 79698, + 79703, 79708, 79713, 79718, 79723, 79728, 79733, 79738, 79743, 79748, + 79753, 79758, 79763, 79768, 79773, 79778, 79783, 79788, 79793, 79798, + 79803, 79808, 79813, 79818, 79822, 79829, 79836, 79843, 79850, 79856, + 79863, 79870, 79877, 79884, 79891, 79898, 79905, 79912, 79919, 79926, + 79932, 79939, 79946, 79953, 79960, 79967, 79974, 79981, 79988, 79995, + 80002, 80009, 80018, 80027, 80036, 80045, 80054, 80063, 80072, 80081, + 80089, 80097, 80105, 80113, 80121, 80129, 80137, 80145, 80151, 80159, 0, + 0, 80167, 80174, 80180, 80186, 80192, 80198, 80204, 80210, 80217, 80223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75837, 75842, 75847, 75852, - 75857, 75861, 75865, 75870, 75875, 75880, 75885, 75890, 75895, 75900, - 75905, 75910, 75914, 75919, 75924, 75929, 75934, 75939, 75944, 75949, - 75954, 75959, 75964, 75969, 75976, 75983, 75990, 75997, 76004, 76011, - 76018, 76025, 76031, 76037, 76043, 76049, 76055, 76061, 76067, 76073, - 76077, 76083, 0, 0, 76089, 76094, 76098, 76102, 76106, 76110, 76114, - 76118, 76122, 76126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76130, 76134, 76138, 76142, 76146, - 76150, 76154, 76158, 76162, 76166, 76170, 76174, 76178, 76182, 76186, - 76190, 76194, 76198, 76202, 76206, 76210, 76214, 76218, 0, 0, 0, 0, - 76222, 76226, 76230, 76234, 76238, 76242, 76246, 76250, 76254, 76258, - 76262, 76266, 76270, 76274, 76278, 76282, 76286, 76290, 76294, 76298, - 76302, 76306, 76310, 76314, 76318, 76322, 76326, 76330, 76334, 76338, - 76342, 76346, 76350, 76354, 76358, 76362, 76366, 76370, 76374, 76378, - 76382, 76386, 76390, 76394, 76398, 76402, 76406, 76410, 76414, 0, 0, 0, - 0, 76418, 76422, 76426, 76430, 76434, 76438, 76442, 76446, 76450, 76454, - 76458, 76462, 76466, 76470, 76474, 76478, 76482, 76486, 76490, 76494, - 76498, 76502, 76506, 76510, 76514, 76518, 76522, 76526, 76530, 76534, - 76538, 76542, 76546, 76550, 76554, 76558, 76562, 76566, 76570, 76574, - 76578, 76582, 76586, 76590, 76594, 76598, 76602, 76606, 76610, 76614, - 76618, 76622, 76626, 76630, 76634, 76638, 76642, 76646, 76650, 76654, - 76658, 76662, 76666, 76670, 76674, 76678, 76682, 76686, 76690, 76694, - 76698, 76702, 76706, 76710, 76714, 76718, 76722, 76726, 76730, 76734, - 76738, 76742, 76746, 76750, 76754, 76758, 76762, 76766, 76770, 76774, - 76778, 76782, 76786, 76790, 76794, 76798, 76802, 76806, 76810, 76814, - 76818, 76822, 76826, 76830, 76834, 76838, 76842, 76846, 76850, 76854, - 76858, 76862, 76866, 76870, 76874, 76878, 76882, 76886, 76890, 76894, - 76898, 76902, 76906, 76910, 76914, 76918, 76922, 76926, 76930, 76934, - 76938, 76942, 76946, 76950, 76954, 76958, 76962, 76966, 76970, 76974, - 76978, 76982, 76986, 76990, 76994, 76998, 77002, 77006, 77010, 77014, - 77018, 77022, 77026, 77030, 77034, 77038, 77042, 77046, 77050, 77054, - 77058, 77062, 77066, 77070, 77074, 77078, 77082, 77086, 77090, 77094, - 77098, 77102, 77106, 77110, 77114, 77118, 77122, 77126, 77130, 77134, - 77138, 77142, 77146, 77150, 77154, 77158, 77162, 77166, 77170, 77174, - 77178, 77182, 77186, 77190, 77194, 77198, 77202, 77206, 77210, 77214, - 77218, 77222, 77226, 77230, 77234, 77238, 77242, 77246, 77250, 77254, - 77258, 77262, 77266, 77270, 77274, 77278, 77282, 77286, 77290, 77294, - 77298, 77302, 77306, 77310, 77314, 77318, 77322, 77326, 77330, 77334, - 77338, 77342, 77346, 77350, 77354, 77358, 77362, 77366, 77370, 77374, - 77378, 77382, 77386, 77390, 77394, 77398, 77402, 77406, 77410, 77414, - 77418, 77422, 77426, 77430, 77434, 77438, 77442, 77446, 77450, 77454, - 77458, 77462, 77466, 77470, 77474, 77478, 77482, 77486, 77490, 77494, - 77498, 77502, 77506, 77510, 77514, 77518, 77522, 77526, 77530, 77534, - 77538, 77542, 77546, 77550, 77554, 77558, 77562, 77566, 77570, 77574, - 77578, 77582, 77586, 77590, 77594, 77598, 77602, 77606, 77610, 77614, - 77618, 77622, 77626, 77630, 77634, 77638, 77642, 77646, 77650, 77654, - 77658, 77662, 77666, 77670, 77674, 77678, 77682, 77686, 77690, 77694, - 77698, 77702, 77706, 77710, 77714, 77718, 77722, 77726, 77730, 77734, - 77738, 77742, 77746, 77750, 77754, 77758, 77762, 77766, 77770, 77774, - 77778, 77782, 77786, 77790, 77794, 77798, 77802, 77806, 77810, 77814, - 77818, 77822, 77826, 77830, 77834, 77838, 77842, 77846, 77850, 77854, - 77858, 77862, 77866, 77870, 77874, 77878, 0, 0, 77882, 77886, 77890, - 77894, 77898, 77902, 77906, 77910, 77914, 77918, 77922, 77926, 77930, - 77934, 77938, 77942, 77946, 77950, 77954, 77958, 77962, 77966, 77970, - 77974, 77978, 77982, 77986, 77990, 77994, 77998, 78002, 78006, 78010, - 78014, 78018, 78022, 78026, 78030, 78034, 78038, 78042, 78046, 78050, - 78054, 78058, 78062, 78066, 78070, 78074, 78078, 78082, 78086, 78090, - 78094, 78098, 78102, 78106, 78110, 78114, 78118, 78122, 78126, 78130, - 78134, 78138, 78142, 78146, 78150, 78154, 78158, 78162, 78166, 78170, - 78174, 78178, 78182, 78186, 78190, 78194, 78198, 78202, 78206, 78210, - 78214, 78218, 78222, 78226, 78230, 78234, 78238, 78242, 78246, 78250, - 78254, 78258, 78262, 78266, 78270, 78274, 78278, 78282, 78286, 78290, - 78294, 78298, 78302, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78306, - 78311, 78316, 78321, 78326, 78331, 78339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 78344, 78351, 78358, 78365, 78372, 0, 0, 0, 0, 0, 78379, 78386, - 78393, 78403, 78409, 78415, 78421, 78427, 78433, 78439, 78446, 78452, - 78458, 78464, 78473, 78482, 78494, 78506, 78512, 78518, 78524, 78531, - 78538, 78545, 78552, 78559, 0, 78566, 78573, 78580, 78588, 78595, 0, - 78602, 0, 78609, 78616, 0, 78623, 78631, 0, 78638, 78645, 78652, 78659, - 78666, 78673, 78680, 78687, 78694, 78701, 78706, 78713, 78720, 78726, - 78732, 78738, 78744, 78750, 78756, 78762, 78768, 78774, 78780, 78786, - 78792, 78798, 78804, 78810, 78816, 78822, 78828, 78834, 78840, 78846, - 78852, 78858, 78864, 78870, 78876, 78882, 78888, 78894, 78900, 78906, - 78912, 78918, 78924, 78930, 78936, 78942, 78948, 78954, 78960, 78966, - 78972, 78978, 78984, 78990, 78996, 79002, 79008, 79014, 79020, 79026, - 79032, 79038, 79044, 79050, 79056, 79062, 79068, 79074, 79080, 79086, - 79092, 79098, 79104, 79110, 79116, 79122, 79128, 79134, 79140, 79146, - 79152, 79158, 79164, 79170, 79176, 79184, 79192, 79198, 79204, 79210, - 79216, 79225, 79234, 79242, 79250, 79258, 79266, 79274, 79282, 79290, - 79298, 79305, 79312, 79322, 79332, 79336, 79340, 79345, 79350, 79355, - 79360, 79369, 79378, 79384, 79390, 79397, 79404, 79411, 79415, 79421, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 79427, 79433, 79439, - 79445, 79451, 79456, 79461, 79467, 79473, 79479, 79485, 79493, 79499, - 79505, 79513, 79521, 79529, 79537, 79542, 79547, 79552, 79557, 79570, - 79583, 79593, 79603, 79614, 79625, 79636, 79647, 79657, 79667, 79678, - 79689, 79700, 79711, 79721, 79731, 79741, 79757, 79773, 79789, 79796, - 79803, 79810, 79817, 79827, 79837, 79847, 79859, 79869, 79877, 79885, - 79894, 79902, 79912, 79920, 79928, 79936, 79945, 79953, 79963, 79971, - 79979, 79987, 79997, 80005, 80012, 80019, 80026, 80033, 80041, 80049, - 80057, 80065, 80073, 80082, 80090, 80098, 80106, 80114, 80122, 80131, - 80139, 80147, 80155, 80163, 80171, 80179, 80187, 80195, 80203, 80211, - 80220, 80228, 80238, 80246, 80254, 80262, 80272, 80280, 80288, 80296, - 80304, 80313, 80322, 80330, 80340, 80348, 80356, 80364, 80373, 80381, - 80391, 80399, 80406, 80413, 80421, 80428, 80437, 80444, 80452, 80460, - 80469, 80477, 80487, 80495, 80503, 80511, 80521, 80529, 80536, 80543, - 80551, 80558, 80567, 80574, 80584, 80594, 80605, 80614, 80623, 80632, - 80641, 80650, 80660, 80671, 80682, 80692, 80703, 80715, 80725, 80734, - 80743, 80751, 80760, 80770, 80778, 80787, 80796, 80804, 80813, 80823, - 80831, 80840, 80849, 80857, 80866, 80876, 80884, 80894, 80902, 80912, - 80920, 80928, 80937, 80945, 80955, 80963, 80971, 80981, 80989, 80996, - 81003, 81012, 81021, 81029, 81038, 81048, 81056, 81067, 81075, 81083, - 81090, 81098, 81107, 81114, 81124, 81134, 81145, 81155, 81166, 81174, - 81182, 81191, 81199, 81208, 81216, 81224, 81233, 81241, 81250, 81258, - 81265, 81272, 81279, 81286, 81294, 81302, 81310, 81318, 81327, 81335, - 81343, 81352, 81360, 81368, 81376, 81385, 81393, 81401, 81409, 81417, - 81425, 81433, 81441, 81449, 81457, 81466, 81474, 81482, 81490, 81498, - 81506, 81515, 81524, 81532, 81540, 81548, 81557, 81565, 81574, 81581, - 81588, 81596, 81603, 81611, 81619, 81628, 81636, 81645, 81653, 81661, - 81671, 81678, 81685, 81693, 81700, 81708, 81718, 81729, 81737, 81746, - 81754, 81763, 81771, 81780, 81788, 81797, 81805, 81814, 81823, 81831, - 81839, 81847, 81856, 81863, 81871, 81880, 81889, 81898, 81908, 81916, - 81926, 81934, 81944, 81952, 81962, 81970, 81980, 81988, 81997, 82004, - 82013, 82020, 82030, 82038, 82048, 82056, 82066, 82074, 82082, 82090, - 82099, 82107, 82116, 82125, 82134, 82143, 82153, 82161, 82171, 82179, - 82189, 82197, 82207, 82215, 82225, 82233, 82242, 82249, 82258, 82265, - 82275, 82283, 82293, 82301, 82311, 82319, 82327, 82335, 82344, 82352, - 82361, 82370, 82379, 82388, 82396, 82404, 82413, 82421, 82430, 82439, - 82447, 82455, 82463, 82472, 82480, 82488, 82497, 82505, 82513, 82521, - 82529, 82534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82539, - 82549, 82559, 82569, 82579, 82590, 82600, 82610, 82621, 82630, 82639, - 82648, 82659, 82669, 82679, 82691, 82701, 82711, 82721, 82731, 82741, - 82751, 82761, 82771, 82781, 82791, 82801, 82812, 82823, 82833, 82843, - 82855, 82866, 82877, 82887, 82897, 82907, 82917, 82927, 82937, 82947, - 82959, 82969, 82979, 82991, 83002, 83013, 83023, 83033, 83043, 83053, - 83065, 83075, 83085, 83096, 83107, 83117, 83127, 83136, 83145, 83154, - 83163, 83172, 83182, 0, 0, 83192, 83202, 83212, 83222, 83232, 83244, - 83254, 83264, 83276, 83286, 83298, 83307, 83316, 83327, 83337, 83349, - 83360, 83373, 83383, 83395, 83404, 83415, 83426, 83439, 83449, 83459, - 83469, 83479, 83489, 83498, 83507, 83516, 83525, 83535, 83545, 83555, - 83565, 83575, 83585, 83595, 83605, 83615, 83625, 83635, 83645, 83654, - 83663, 83672, 83682, 83692, 83702, 83712, 83722, 83733, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83743, 83758, 83773, 83779, 83785, 83791, - 83797, 83803, 83809, 83815, 83821, 83829, 83833, 83836, 0, 0, 83844, - 83847, 83850, 83853, 83856, 83859, 83862, 83865, 83868, 83871, 83874, - 83877, 83880, 83883, 83886, 83889, 83892, 83900, 83909, 83920, 83928, - 83936, 83945, 83954, 83965, 83977, 0, 0, 0, 0, 0, 0, 83986, 83991, 83996, - 84003, 84010, 84016, 84022, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84027, 84037, - 84047, 84057, 84066, 84077, 84086, 84095, 84105, 84115, 84127, 84139, - 84150, 84161, 84172, 84183, 84193, 84203, 84213, 84223, 84234, 84245, - 84249, 84254, 84263, 84272, 84276, 84280, 84284, 84289, 84294, 84299, - 84304, 84307, 84311, 0, 84316, 84319, 84322, 84326, 84330, 84335, 84339, - 84343, 84348, 84353, 84360, 84367, 84370, 84373, 84376, 84379, 84382, - 84386, 84390, 0, 84394, 84399, 84403, 84407, 0, 0, 0, 0, 84412, 84417, - 84424, 84429, 84434, 0, 84439, 84444, 84449, 84454, 84459, 84464, 84469, - 84474, 84479, 84484, 84489, 84494, 84503, 84512, 84520, 84528, 84537, - 84546, 84555, 84564, 84572, 84580, 84588, 84596, 84601, 84606, 84612, - 84618, 84624, 84630, 84638, 84646, 84652, 84658, 84664, 84670, 84676, - 84682, 84688, 84694, 84699, 84704, 84709, 84714, 84719, 84724, 84729, - 84734, 84740, 84746, 84752, 84758, 84764, 84770, 84776, 84782, 84788, - 84794, 84800, 84806, 84812, 84818, 84824, 84830, 84836, 84842, 84848, - 84854, 84860, 84866, 84872, 84878, 84884, 84890, 84896, 84902, 84908, - 84914, 84920, 84926, 84932, 84938, 84944, 84950, 84956, 84962, 84968, - 84974, 84980, 84986, 84992, 84998, 85004, 85010, 85016, 85022, 85028, - 85034, 85040, 85046, 85052, 85058, 85064, 85070, 85076, 85082, 85088, - 85094, 85099, 85104, 85109, 85114, 85120, 85126, 85132, 85138, 85144, - 85150, 85156, 85162, 85168, 85174, 85181, 85188, 85193, 85198, 85203, - 85208, 85220, 85232, 85243, 85254, 85266, 85278, 85286, 0, 0, 85294, 0, - 85302, 85306, 85310, 85313, 85317, 85321, 85324, 85327, 85331, 85335, - 85338, 85341, 85344, 85347, 85352, 85355, 85359, 85362, 85365, 85368, - 85371, 85374, 85377, 85380, 85383, 85386, 85389, 85392, 85396, 85400, - 85404, 85408, 85413, 85418, 85424, 85430, 85436, 85441, 85447, 85453, - 85459, 85464, 85470, 85476, 85481, 85486, 85492, 85497, 85503, 85509, - 85514, 85520, 85526, 85531, 85537, 85543, 85549, 85555, 85561, 85565, - 85570, 85574, 85579, 85583, 85588, 85593, 85599, 85605, 85611, 85616, - 85622, 85628, 85634, 85639, 85645, 85651, 85656, 85661, 85667, 85672, - 85678, 85684, 85689, 85695, 85701, 85706, 85712, 85718, 85724, 85730, - 85736, 85741, 85745, 85750, 85752, 85757, 85762, 85768, 85773, 85778, - 85782, 85788, 85793, 85798, 85803, 85808, 85813, 85818, 85823, 85829, - 85835, 85841, 85849, 85853, 85857, 85861, 85865, 85869, 85873, 85878, - 85883, 85888, 85893, 85897, 85902, 85907, 85912, 85917, 85922, 85927, - 85932, 85937, 85941, 85945, 85950, 85955, 85960, 85965, 85969, 85974, - 85979, 85984, 85989, 85993, 85998, 86003, 86008, 86013, 86017, 86022, - 86027, 86031, 86036, 86041, 86046, 86051, 86056, 86061, 86068, 86075, - 86079, 86084, 86089, 86094, 86099, 86104, 86109, 86114, 86119, 86124, - 86129, 86134, 86139, 86144, 86149, 86154, 86159, 86164, 86169, 86174, - 86179, 86184, 86189, 86194, 86199, 86204, 86209, 86214, 86219, 86224, 0, - 0, 0, 86229, 86233, 86238, 86242, 86247, 86252, 0, 0, 86256, 86261, - 86266, 86270, 86275, 86280, 0, 0, 86285, 86290, 86294, 86299, 86304, - 86309, 0, 0, 86314, 86319, 86324, 0, 0, 0, 86328, 86332, 86336, 86340, - 86343, 86347, 86351, 0, 86355, 86361, 86364, 86368, 86371, 86375, 86379, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86383, 86389, 86395, 86401, 86407, 0, 0, - 86411, 86417, 86423, 86429, 86435, 86441, 86448, 86455, 86462, 86469, - 86476, 86483, 0, 86490, 86497, 86504, 86510, 86517, 86524, 86531, 86538, - 86544, 86551, 86558, 86565, 86572, 86578, 86585, 86592, 86599, 86606, - 86612, 86619, 86626, 86633, 86640, 86647, 86654, 86661, 0, 86668, 86674, - 86681, 86688, 86695, 86702, 86708, 86715, 86722, 86729, 86736, 86743, - 86750, 86757, 86763, 86770, 86777, 86784, 86791, 0, 86798, 86805, 0, - 86812, 86819, 86826, 86833, 86840, 86847, 86854, 86861, 86868, 86875, - 86882, 86889, 86896, 86903, 86910, 0, 0, 86916, 86921, 86926, 86931, - 86936, 86941, 86946, 86951, 86956, 86961, 86966, 86971, 86976, 86981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 86986, 86993, 87000, 87007, 87014, 87021, - 87028, 87035, 87042, 87049, 87056, 87063, 87070, 87077, 87084, 87091, - 87098, 87105, 87112, 87119, 87127, 87135, 87142, 87149, 87154, 87162, - 87170, 87177, 87184, 87189, 87196, 87201, 87206, 87213, 87218, 87223, - 87228, 87236, 87241, 87246, 87253, 87258, 87263, 87270, 87277, 87282, - 87287, 87292, 87297, 87302, 87307, 87312, 87317, 87322, 87329, 87334, - 87341, 87346, 87351, 87356, 87361, 87366, 87371, 87376, 87381, 87386, - 87391, 87396, 87403, 87410, 87417, 87424, 87430, 87435, 87442, 87447, - 87452, 87461, 87468, 87477, 87484, 87489, 87494, 87502, 87507, 87512, - 87517, 87522, 87527, 87534, 87539, 87544, 87549, 87554, 87559, 87566, - 87573, 87580, 87587, 87594, 87601, 87608, 87615, 87622, 87629, 87636, - 87643, 87650, 87657, 87664, 87671, 87678, 87685, 87692, 87699, 87706, - 87713, 87720, 87727, 87734, 87741, 87748, 87755, 0, 0, 0, 0, 0, 87762, - 87770, 87778, 0, 0, 0, 0, 87783, 87787, 87791, 87795, 87799, 87803, - 87807, 87811, 87815, 87819, 87824, 87829, 87834, 87839, 87844, 87849, - 87854, 87859, 87864, 87870, 87876, 87882, 87889, 87896, 87903, 87910, - 87917, 87924, 87930, 87936, 87942, 87949, 87956, 87963, 87970, 87977, - 87984, 87991, 87998, 88005, 88012, 88019, 88026, 88033, 88040, 0, 0, 0, - 88047, 88055, 88063, 88071, 88079, 88087, 88097, 88107, 88115, 88123, - 88131, 88139, 88147, 88153, 88160, 88169, 88178, 88187, 88196, 88205, - 88214, 88224, 88235, 88245, 88256, 88265, 88274, 88283, 88293, 88304, - 88314, 88325, 88336, 88345, 88353, 88359, 88365, 88371, 88377, 88385, - 88393, 88399, 88406, 88416, 88423, 88430, 88437, 88444, 88451, 88461, - 88468, 88475, 88483, 88491, 88500, 88509, 88518, 88527, 88536, 88544, - 88553, 88562, 88571, 88575, 88582, 88587, 88592, 88596, 88600, 88604, - 88608, 88613, 88618, 88624, 88630, 88634, 88640, 88644, 88648, 88652, - 88656, 88660, 88664, 88670, 0, 0, 0, 0, 0, 88674, 88679, 88684, 88689, - 88694, 88701, 88706, 88711, 88716, 88721, 88726, 88731, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88736, - 88743, 88752, 88761, 88768, 88775, 88782, 88789, 88796, 88803, 88809, - 88816, 88823, 88830, 88837, 88844, 88851, 88858, 88865, 88874, 88881, - 88888, 88895, 88902, 88909, 88916, 88923, 88930, 88939, 88946, 88953, - 88960, 88967, 88974, 88981, 88990, 88997, 89004, 89011, 89018, 89027, - 89034, 89041, 89048, 89056, 89065, 0, 0, 89074, 89078, 89082, 89087, - 89092, 89097, 89102, 89106, 89111, 89116, 89121, 89126, 89131, 89136, - 89140, 89144, 89149, 89154, 89159, 89163, 89168, 89173, 89177, 89182, - 89187, 89192, 89197, 89202, 89207, 0, 0, 0, 89212, 89216, 89221, 89226, - 89230, 89235, 89239, 89244, 89249, 89254, 89259, 89263, 89267, 89272, - 89277, 89282, 89287, 89292, 89297, 89301, 89306, 89311, 89316, 89321, - 89326, 89331, 89335, 89339, 89344, 89349, 89354, 89359, 89364, 89369, - 89374, 89379, 89384, 89389, 89394, 89399, 89404, 89409, 89414, 89419, - 89424, 89429, 89434, 89439, 89444, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80230, 80234, 80238, 80242, + 80246, 80250, 80254, 80258, 80262, 80266, 80270, 80274, 80278, 80282, + 80286, 80290, 80294, 80298, 80302, 80306, 80310, 80314, 80318, 0, 0, 0, + 0, 80322, 80326, 80330, 80334, 80338, 80342, 80346, 80350, 80354, 80358, + 80362, 80366, 80370, 80374, 80378, 80382, 80386, 80390, 80394, 80398, + 80402, 80406, 80410, 80414, 80418, 80422, 80426, 80430, 80434, 80438, + 80442, 80446, 80450, 80454, 80458, 80462, 80466, 80470, 80474, 80478, + 80482, 80486, 80490, 80494, 80498, 80502, 80506, 80510, 80514, 0, 0, 0, + 0, 80518, 80522, 80526, 80530, 80534, 80538, 80542, 80546, 80550, 80554, + 80558, 80562, 80566, 80570, 80574, 80578, 80582, 80586, 80590, 80594, + 80598, 80602, 80606, 80610, 80614, 80618, 80622, 80626, 80630, 80634, + 80638, 80642, 80646, 80650, 80654, 80658, 80662, 80666, 80670, 80674, + 80678, 80682, 80686, 80690, 80694, 80698, 80702, 80706, 80710, 80714, + 80718, 80722, 80726, 80730, 80734, 80738, 80742, 80746, 80750, 80754, + 80758, 80762, 80766, 80770, 80774, 80778, 80782, 80786, 80790, 80794, + 80798, 80802, 80806, 80810, 80814, 80818, 80822, 80826, 80830, 80834, + 80838, 80842, 80846, 80850, 80854, 80858, 80862, 80866, 80870, 80874, + 80878, 80882, 80886, 80890, 80894, 80898, 80902, 80906, 80910, 80914, + 80918, 80922, 80926, 80930, 80934, 80938, 80942, 80946, 80950, 80954, + 80958, 80962, 80966, 80970, 80974, 80978, 80982, 80986, 80990, 80994, + 80998, 81002, 81006, 81010, 81014, 81018, 81022, 81026, 81030, 81034, + 81038, 81042, 81046, 81050, 81054, 81058, 81062, 81066, 81070, 81074, + 81078, 81082, 81086, 81090, 81094, 81098, 81102, 81106, 81110, 81114, + 81118, 81122, 81126, 81130, 81134, 81138, 81142, 81146, 81150, 81154, + 81158, 81162, 81166, 81170, 81174, 81178, 81182, 81186, 81190, 81194, + 81198, 81202, 81206, 81210, 81214, 81218, 81222, 81226, 81230, 81234, + 81238, 81242, 81246, 81250, 81254, 81258, 81262, 81266, 81270, 81274, + 81278, 81282, 81286, 81290, 81294, 81298, 81302, 81306, 81310, 81314, + 81318, 81322, 81326, 81330, 81334, 81338, 81342, 81346, 81350, 81354, + 81358, 81362, 81366, 81370, 81374, 81378, 81382, 81386, 81390, 81394, + 81398, 81402, 81406, 81410, 81414, 81418, 81422, 81426, 81430, 81434, + 81438, 81442, 81446, 81450, 81454, 81458, 81462, 81466, 81470, 81474, + 81478, 81482, 81486, 81490, 81494, 81498, 81502, 81506, 81510, 81514, + 81518, 81522, 81526, 81530, 81534, 81538, 81542, 81546, 81550, 81554, + 81558, 81562, 81566, 81570, 81574, 81578, 81582, 81586, 81590, 81594, + 81598, 81602, 81606, 81610, 81614, 81618, 81622, 81626, 81630, 81634, + 81638, 81642, 81646, 81650, 81654, 81658, 81662, 81666, 81670, 81674, + 81678, 81682, 81686, 81690, 81694, 81698, 81702, 81706, 81710, 81714, + 81718, 81722, 81726, 81730, 81734, 81738, 81742, 81746, 81750, 81754, + 81758, 81762, 81766, 81770, 81774, 81778, 81782, 81786, 81790, 81794, + 81798, 81802, 81806, 81810, 81814, 81818, 81822, 81826, 81830, 81834, + 81838, 81842, 81846, 81850, 81854, 81858, 81862, 81866, 81870, 81874, + 81878, 81882, 81886, 81890, 81894, 81898, 81902, 81906, 81910, 81914, + 81918, 81922, 81926, 81930, 81934, 81938, 81942, 81946, 81950, 81954, + 81958, 81962, 81966, 81970, 81974, 81978, 0, 0, 81982, 81986, 81990, + 81994, 81998, 82002, 82006, 82010, 82014, 82018, 82022, 82026, 82030, + 82034, 82038, 82042, 82046, 82050, 82054, 82058, 82062, 82066, 82070, + 82074, 82078, 82082, 82086, 82090, 82094, 82098, 82102, 82106, 82110, + 82114, 82118, 82122, 82126, 82130, 82134, 82138, 82142, 82146, 82150, + 82154, 82158, 82162, 82166, 82170, 82174, 82178, 82182, 82186, 82190, + 82194, 82198, 82202, 82206, 82210, 82214, 82218, 82222, 82226, 82230, + 82234, 82238, 82242, 82246, 82250, 82254, 82258, 82262, 82266, 82270, + 82274, 82278, 82282, 82286, 82290, 82294, 82298, 82302, 82306, 82310, + 82314, 82318, 82322, 82326, 82330, 82334, 82338, 82342, 82346, 82350, + 82354, 82358, 82362, 82366, 82370, 82374, 82378, 82382, 82386, 82390, + 82394, 82398, 82402, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82406, + 82411, 82416, 82421, 82426, 82431, 82439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 82444, 82451, 82458, 82465, 82472, 0, 0, 0, 0, 0, 82479, 82486, + 82493, 82503, 82509, 82515, 82521, 82527, 82533, 82539, 82546, 82552, + 82558, 82564, 82573, 82582, 82594, 82606, 82612, 82618, 82624, 82631, + 82638, 82645, 82652, 82659, 0, 82666, 82673, 82680, 82688, 82695, 0, + 82702, 0, 82709, 82716, 0, 82723, 82731, 0, 82738, 82745, 82752, 82759, + 82766, 82773, 82780, 82787, 82794, 82801, 82806, 82813, 82820, 82826, + 82832, 82838, 82844, 82850, 82856, 82862, 82868, 82874, 82880, 82886, + 82892, 82898, 82904, 82910, 82916, 82922, 82928, 82934, 82940, 82946, + 82952, 82958, 82964, 82970, 82976, 82982, 82988, 82994, 83000, 83006, + 83012, 83018, 83024, 83030, 83036, 83042, 83048, 83054, 83060, 83066, + 83072, 83078, 83084, 83090, 83096, 83102, 83108, 83114, 83120, 83126, + 83132, 83138, 83144, 83150, 83156, 83162, 83168, 83174, 83180, 83186, + 83192, 83198, 83204, 83210, 83216, 83222, 83228, 83234, 83240, 83246, + 83252, 83258, 83264, 83270, 83276, 83284, 83292, 83298, 83304, 83310, + 83316, 83325, 83334, 83342, 83350, 83358, 83366, 83374, 83382, 83390, + 83398, 83405, 83412, 83423, 83434, 83438, 83442, 83447, 83452, 83457, + 83462, 83470, 83478, 83484, 83490, 83497, 83504, 83511, 83515, 83521, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83527, 83533, 83539, + 83545, 83551, 83556, 83561, 83567, 83573, 83579, 83585, 83594, 83600, + 83606, 83614, 83622, 83630, 83638, 83643, 83648, 83653, 83658, 83671, + 83684, 83695, 83706, 83718, 83730, 83742, 83754, 83765, 83776, 83788, + 83800, 83812, 83824, 83835, 83846, 83857, 83874, 83891, 83908, 83915, + 83922, 83929, 83936, 83947, 83958, 83969, 83982, 83993, 84001, 84009, + 84018, 84026, 84036, 84044, 84052, 84060, 84069, 84077, 84087, 84095, + 84103, 84111, 84121, 84129, 84136, 84143, 84150, 84157, 84165, 84173, + 84181, 84189, 84197, 84206, 84214, 84222, 84230, 84238, 84246, 84255, + 84263, 84271, 84279, 84287, 84295, 84303, 84311, 84319, 84327, 84335, + 84344, 84352, 84362, 84370, 84378, 84386, 84396, 84404, 84412, 84420, + 84428, 84437, 84446, 84454, 84464, 84472, 84480, 84488, 84497, 84505, + 84515, 84523, 84530, 84537, 84545, 84552, 84561, 84568, 84576, 84584, + 84593, 84601, 84611, 84619, 84627, 84635, 84645, 84653, 84660, 84667, + 84675, 84682, 84691, 84698, 84708, 84718, 84729, 84738, 84747, 84756, + 84765, 84774, 84784, 84796, 84808, 84819, 84831, 84844, 84855, 84864, + 84873, 84881, 84890, 84900, 84908, 84917, 84926, 84934, 84943, 84953, + 84961, 84970, 84979, 84987, 84996, 85006, 85014, 85024, 85032, 85042, + 85050, 85058, 85067, 85075, 85085, 85093, 85101, 85111, 85119, 85126, + 85133, 85142, 85151, 85159, 85168, 85178, 85186, 85197, 85205, 85213, + 85220, 85228, 85237, 85244, 85255, 85266, 85278, 85289, 85301, 85309, + 85317, 85326, 85334, 85343, 85351, 85359, 85368, 85376, 85385, 85393, + 85400, 85407, 85414, 85421, 85429, 85437, 85445, 85453, 85462, 85470, + 85478, 85487, 85495, 85503, 85511, 85520, 85528, 85536, 85544, 85552, + 85560, 85568, 85576, 85584, 85592, 85601, 85609, 85617, 85625, 85633, + 85641, 85650, 85659, 85667, 85675, 85683, 85692, 85700, 85709, 85716, + 85723, 85731, 85738, 85746, 85754, 85763, 85771, 85780, 85788, 85796, + 85806, 85813, 85820, 85828, 85835, 85843, 85854, 85866, 85874, 85883, + 85891, 85900, 85908, 85917, 85925, 85934, 85942, 85951, 85960, 85968, + 85976, 85984, 85993, 86000, 86008, 86017, 86026, 86035, 86045, 86053, + 86063, 86071, 86081, 86089, 86099, 86107, 86117, 86125, 86134, 86141, + 86150, 86157, 86167, 86175, 86185, 86193, 86203, 86211, 86219, 86227, + 86236, 86244, 86253, 86262, 86271, 86280, 86290, 86298, 86308, 86316, + 86326, 86334, 86344, 86352, 86362, 86370, 86379, 86386, 86395, 86402, + 86412, 86420, 86430, 86438, 86448, 86456, 86464, 86472, 86481, 86489, + 86498, 86507, 86516, 86525, 86533, 86541, 86550, 86558, 86567, 86576, + 86584, 86592, 86600, 86609, 86617, 86625, 86634, 86642, 86650, 86658, + 86666, 86671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86676, + 86686, 86696, 86706, 86716, 86727, 86737, 86747, 86758, 86767, 86776, + 86785, 86796, 86806, 86816, 86828, 86838, 86848, 86858, 86868, 86878, + 86888, 86898, 86908, 86918, 86928, 86938, 86949, 86960, 86970, 86980, + 86992, 87003, 87014, 87024, 87034, 87044, 87054, 87064, 87074, 87084, + 87096, 87106, 87116, 87128, 87139, 87150, 87160, 87170, 87180, 87190, + 87202, 87212, 87222, 87233, 87244, 87254, 87264, 87273, 87282, 87291, + 87300, 87309, 87319, 0, 0, 87329, 87339, 87349, 87359, 87369, 87381, + 87391, 87401, 87413, 87423, 87435, 87444, 87453, 87464, 87474, 87486, + 87497, 87510, 87520, 87532, 87541, 87552, 87563, 87576, 87586, 87596, + 87606, 87616, 87626, 87635, 87644, 87653, 87662, 87672, 87682, 87692, + 87702, 87712, 87722, 87732, 87742, 87752, 87762, 87772, 87782, 87791, + 87800, 87809, 87819, 87829, 87839, 87849, 87859, 87870, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89449, 89453, 89458, 89463, 89468, 89472, - 89477, 89482, 89487, 89492, 89496, 89500, 89505, 89510, 89515, 89520, - 89524, 89529, 89534, 89539, 89544, 89549, 89554, 89558, 89563, 89568, - 89573, 89578, 89583, 89588, 89593, 0, 89598, 89603, 89608, 89614, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89620, 89625, 89630, 89635, 89640, 89645, - 89650, 89655, 89660, 89665, 89670, 89675, 89680, 89685, 89690, 89695, - 89700, 89705, 89710, 89715, 89720, 89725, 89730, 89735, 89740, 89745, - 89750, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87880, 87895, 87910, 87916, 87922, 87928, + 87934, 87940, 87946, 87952, 87958, 87966, 87970, 87973, 0, 0, 87981, + 87984, 87987, 87990, 87993, 87996, 87999, 88002, 88005, 88008, 88011, + 88014, 88017, 88020, 88023, 88026, 88029, 88037, 88046, 88057, 88065, + 88073, 88082, 88091, 88102, 88114, 0, 0, 0, 0, 0, 0, 88124, 88129, 88134, + 88141, 88148, 88154, 88160, 88165, 88170, 88175, 88181, 88187, 88193, + 88199, 88205, 88212, 88219, 88229, 88239, 88249, 88258, 88269, 88278, + 88287, 88297, 88307, 88319, 88331, 88342, 88353, 88364, 88375, 88385, + 88395, 88405, 88415, 88426, 88437, 88441, 88446, 88455, 88464, 88468, + 88472, 88476, 88481, 88486, 88491, 88496, 88499, 88503, 0, 88508, 88511, + 88514, 88518, 88522, 88527, 88531, 88535, 88540, 88545, 88552, 88559, + 88562, 88565, 88568, 88571, 88574, 88578, 88582, 0, 88586, 88591, 88595, + 88599, 0, 0, 0, 0, 88604, 88609, 88616, 88621, 88626, 0, 88631, 88636, + 88641, 88646, 88651, 88656, 88661, 88666, 88671, 88676, 88681, 88687, + 88696, 88705, 88714, 88723, 88733, 88743, 88753, 88763, 88772, 88781, + 88790, 88799, 88804, 88809, 88815, 88821, 88827, 88833, 88841, 88849, + 88855, 88861, 88867, 88873, 88879, 88885, 88891, 88897, 88902, 88907, + 88912, 88917, 88922, 88927, 88932, 88937, 88943, 88949, 88955, 88961, + 88967, 88973, 88979, 88985, 88991, 88997, 89003, 89009, 89015, 89021, + 89027, 89033, 89039, 89045, 89051, 89057, 89063, 89069, 89075, 89081, + 89087, 89093, 89099, 89105, 89111, 89117, 89123, 89129, 89135, 89141, + 89147, 89153, 89159, 89165, 89171, 89177, 89183, 89189, 89195, 89201, + 89207, 89213, 89219, 89225, 89231, 89237, 89243, 89249, 89255, 89261, + 89267, 89273, 89279, 89285, 89291, 89297, 89302, 89307, 89312, 89317, + 89323, 89329, 89335, 89341, 89347, 89353, 89359, 89365, 89371, 89377, + 89384, 89391, 89396, 89401, 89406, 89411, 89423, 89435, 89447, 89459, + 89472, 89485, 89493, 0, 0, 89501, 0, 89509, 89513, 89517, 89520, 89524, + 89528, 89531, 89534, 89538, 89542, 89545, 89548, 89551, 89554, 89559, + 89562, 89566, 89569, 89572, 89575, 89578, 89581, 89584, 89588, 89591, + 89595, 89598, 89601, 89605, 89609, 89613, 89617, 89622, 89627, 89633, + 89639, 89645, 89650, 89656, 89662, 89668, 89673, 89679, 89685, 89690, + 89696, 89702, 89707, 89713, 89719, 89724, 89729, 89735, 89740, 89746, + 89752, 89758, 89764, 89770, 89774, 89779, 89783, 89788, 89792, 89797, + 89802, 89808, 89814, 89820, 89825, 89831, 89837, 89843, 89848, 89854, + 89860, 89865, 89871, 89877, 89882, 89888, 89894, 89899, 89904, 89910, + 89915, 89921, 89927, 89933, 89939, 89945, 89950, 89954, 89959, 89962, + 89967, 89972, 89978, 89983, 89988, 89992, 89997, 90002, 90007, 90012, + 90017, 90022, 90027, 90032, 90038, 90044, 90050, 90058, 90062, 90066, + 90070, 90074, 90078, 90082, 90087, 90092, 90097, 90102, 90107, 90112, + 90117, 90122, 90127, 90132, 90137, 90142, 90147, 90151, 90156, 90161, + 90166, 90171, 90176, 90180, 90185, 90190, 90195, 90200, 90204, 90209, + 90214, 90219, 90224, 90228, 90233, 90238, 90243, 90248, 90253, 90258, + 90263, 90268, 90273, 90280, 90287, 90291, 90296, 90301, 90306, 90311, + 90316, 90321, 90326, 90331, 90336, 90341, 90346, 90351, 90356, 90361, + 90366, 90371, 90376, 90381, 90386, 90391, 90396, 90401, 90406, 90411, + 90416, 90421, 90426, 90431, 90436, 0, 0, 0, 90441, 90445, 90450, 90454, + 90459, 90464, 0, 0, 90468, 90473, 90478, 90482, 90487, 90492, 0, 0, + 90497, 90502, 90506, 90511, 90516, 90521, 0, 0, 90526, 90531, 90536, 0, + 0, 0, 90540, 90544, 90548, 90552, 90555, 90559, 90563, 0, 90567, 90573, + 90576, 90579, 90582, 90585, 90589, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90593, + 90599, 90605, 90611, 90617, 0, 0, 90621, 90627, 90633, 90639, 90645, + 90651, 90658, 90665, 90672, 90679, 90686, 90693, 0, 90700, 90707, 90714, + 90720, 90727, 90734, 90741, 90748, 90754, 90761, 90768, 90775, 90782, + 90789, 90796, 90803, 90810, 90817, 90823, 90830, 90837, 90844, 90851, + 90858, 90865, 90872, 0, 90879, 90886, 90893, 90900, 90907, 90914, 90921, + 90928, 90935, 90942, 90949, 90956, 90963, 90970, 90976, 90983, 90990, + 90997, 91004, 0, 91011, 91018, 0, 91025, 91032, 91039, 91046, 91053, + 91060, 91067, 91074, 91081, 91088, 91095, 91102, 91109, 91116, 91123, 0, + 0, 91129, 91134, 91139, 91144, 91149, 91154, 91159, 91164, 91169, 91174, + 91179, 91184, 91189, 91194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91199, 91206, + 91213, 91220, 91227, 91234, 91241, 91248, 91255, 91262, 91269, 91276, + 91283, 91290, 91297, 91304, 91311, 91318, 91325, 91332, 91340, 91348, + 91355, 91362, 91367, 91375, 91383, 91390, 91397, 91402, 91409, 91414, + 91419, 91426, 91431, 91436, 91441, 91449, 91454, 91459, 91466, 91471, + 91476, 91483, 91490, 91495, 91500, 91505, 91510, 91515, 91520, 91525, + 91530, 91535, 91542, 91547, 91554, 91559, 91564, 91569, 91574, 91579, + 91584, 91589, 91594, 91599, 91604, 91609, 91616, 91623, 91630, 91637, + 91643, 91648, 91655, 91660, 91665, 91674, 91681, 91690, 91697, 91702, + 91707, 91715, 91720, 91725, 91730, 91735, 91740, 91747, 91752, 91757, + 91762, 91767, 91772, 91779, 91786, 91793, 91800, 91807, 91814, 91821, + 91828, 91835, 91842, 91849, 91856, 91863, 91870, 91877, 91884, 91891, + 91898, 91905, 91912, 91919, 91926, 91933, 91940, 91947, 91954, 91961, + 91968, 0, 0, 0, 0, 0, 91975, 91983, 91991, 0, 0, 0, 0, 91996, 92000, + 92004, 92008, 92012, 92016, 92020, 92025, 92029, 92034, 92039, 92044, + 92049, 92054, 92059, 92064, 92069, 92074, 92079, 92085, 92091, 92097, + 92104, 92111, 92118, 92125, 92132, 92139, 92145, 92151, 92157, 92164, + 92171, 92178, 92185, 92192, 92199, 92206, 92213, 92220, 92227, 92234, + 92241, 92248, 92255, 0, 0, 0, 92262, 92270, 92278, 92286, 92294, 92302, + 92312, 92322, 92330, 92338, 92346, 92354, 92362, 92368, 92375, 92384, + 92393, 92402, 92411, 92420, 92429, 92439, 92450, 92460, 92471, 92480, + 92489, 92498, 92508, 92519, 92529, 92540, 92551, 92560, 92568, 92574, + 92580, 92586, 92592, 92600, 92608, 92614, 92621, 92631, 92638, 92645, + 92652, 92659, 92666, 92676, 92683, 92690, 92698, 92706, 92715, 92724, + 92733, 92742, 92751, 92759, 92768, 92777, 92786, 92790, 92797, 92802, + 92807, 92811, 92815, 92819, 92823, 92828, 92833, 92839, 92845, 92849, + 92855, 92859, 92863, 92867, 92871, 92875, 92879, 92885, 92889, 92894, 0, + 0, 0, 92898, 92903, 92908, 92913, 92918, 92925, 92930, 92935, 92940, + 92945, 92950, 92955, 0, 0, 0, 0, 92960, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 89757, 89762, 89767, 89772, 89777, 89782, 89787, - 89792, 89797, 89802, 89807, 89812, 89817, 89822, 89827, 89832, 89837, - 89842, 89847, 89852, 89857, 89862, 89867, 89872, 89877, 89882, 89887, - 89891, 89895, 89899, 0, 89904, 89910, 89915, 89920, 89925, 89930, 89936, - 89942, 89948, 89954, 89960, 89966, 89972, 89978, 89984, 89990, 89996, - 90002, 90008, 90013, 90019, 90025, 90030, 90036, 90041, 90047, 90053, - 90058, 90064, 90070, 90075, 90081, 90087, 90092, 90098, 90104, 90110, 0, - 0, 0, 0, 90115, 90121, 90127, 90133, 90139, 90145, 90151, 90157, 90163, - 90170, 90175, 90180, 90186, 90192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92966, 92973, 92982, 92991, 92998, + 93005, 93012, 93019, 93026, 93033, 93039, 93046, 93053, 93060, 93067, + 93074, 93081, 93088, 93095, 93104, 93111, 93118, 93125, 93132, 93139, + 93146, 93153, 93160, 93169, 93176, 93183, 93190, 93197, 93204, 93211, + 93220, 93227, 93234, 93241, 93248, 93257, 93264, 93271, 93278, 93286, + 93295, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 90198, 90203, 90208, 90213, 90219, 90224, 90230, 90236, - 90242, 90248, 90255, 90261, 90268, 90273, 90278, 90283, 90288, 90293, - 90298, 90303, 90308, 90313, 90318, 90323, 90328, 90333, 90338, 90343, - 90348, 90353, 90358, 90363, 90368, 90373, 90378, 90383, 90388, 90393, - 90398, 90403, 90408, 90413, 90418, 90423, 90429, 90434, 90440, 90446, - 90452, 90458, 90465, 90471, 90478, 90483, 90488, 90493, 90498, 90503, - 90508, 90513, 90518, 90523, 90528, 90533, 90538, 90543, 90548, 90553, - 90558, 90563, 90568, 90573, 90578, 90583, 90588, 90593, 90598, 90603, - 90608, 90613, 90618, 90623, 90628, 90633, 90638, 90643, 90648, 90653, - 90658, 90663, 90668, 90673, 90678, 90683, 90688, 90693, 90698, 90703, - 90708, 90713, 90718, 90723, 90728, 90733, 90738, 90743, 90748, 90753, - 90758, 90763, 90768, 90773, 90778, 90783, 90788, 90793, 90798, 90803, - 90808, 90813, 90818, 90823, 90828, 90833, 90838, 90843, 90848, 90853, - 90858, 90863, 90868, 90873, 90878, 90883, 90888, 90893, 90897, 90901, - 90906, 90911, 90916, 90921, 90926, 90931, 90936, 90941, 90946, 90951, - 90956, 90960, 90964, 90968, 90972, 90976, 90980, 90984, 90989, 90994, 0, - 0, 90999, 91004, 91008, 91012, 91016, 91020, 91024, 91028, 91032, 91036, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91040, 91044, 91048, 91052, - 91056, 91060, 0, 0, 91065, 0, 91070, 91074, 91079, 91084, 91089, 91094, - 91099, 91104, 91109, 91114, 91119, 91123, 91128, 91133, 91138, 91143, - 91147, 91152, 91157, 91162, 91167, 91171, 91176, 91181, 91186, 91191, - 91195, 91200, 91205, 91210, 91215, 91219, 91224, 91229, 91234, 91239, - 91244, 91249, 91254, 91258, 91263, 91268, 91273, 91278, 0, 91283, 91288, - 0, 0, 0, 91293, 0, 0, 91298, 91303, 91310, 91317, 91324, 91331, 91338, - 91345, 91352, 91359, 91366, 91373, 91380, 91387, 91394, 91401, 91408, - 91415, 91422, 91429, 91436, 91443, 91450, 0, 91457, 91464, 91470, 91476, - 91482, 91489, 91496, 91504, 91512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91521, 91526, - 91531, 91536, 91541, 91546, 91551, 91556, 91561, 91566, 91571, 91576, - 91581, 91586, 91591, 91596, 91601, 91606, 91611, 91616, 91621, 91626, - 91631, 91635, 91640, 91645, 91651, 91655, 0, 0, 0, 91659, 91665, 91669, - 91674, 91679, 91684, 91688, 91693, 91697, 91702, 91707, 91711, 91715, - 91720, 91724, 91728, 91733, 91738, 91742, 91747, 91752, 91757, 91762, - 91767, 91772, 91777, 91782, 0, 0, 0, 0, 0, 91787, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93304, 93308, 93312, 93317, 93322, + 93327, 93332, 93336, 93341, 93346, 93351, 93356, 93361, 93366, 93370, + 93375, 93380, 93385, 93390, 93394, 93399, 93404, 93408, 93412, 93417, + 93422, 93427, 93432, 93437, 0, 0, 0, 93442, 93446, 93451, 93456, 93460, + 93465, 93469, 93474, 93479, 93484, 93489, 93494, 93498, 93503, 93508, + 93513, 93518, 93522, 93527, 93531, 93536, 93541, 93546, 93551, 93556, + 93561, 93565, 93569, 93574, 93579, 93584, 93589, 93594, 93599, 93604, + 93609, 93614, 93619, 93624, 93629, 93634, 93639, 93644, 93649, 93654, + 93659, 93664, 93669, 93674, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 93679, 93685, 93690, 93695, 93700, 93705, 93710, 93715, 93721, 93726, + 93732, 93738, 93744, 93750, 93756, 93762, 93768, 93774, 93780, 93786, + 93793, 93800, 93807, 93815, 93823, 93831, 93839, 93847, 0, 0, 0, 0, + 93855, 93859, 93864, 93869, 93874, 93878, 93883, 93888, 93893, 93898, + 93902, 93906, 93911, 93916, 93921, 93926, 93930, 93935, 93940, 93945, + 93950, 93955, 93960, 93964, 93969, 93974, 93979, 93984, 93989, 93994, + 93999, 94004, 94009, 94014, 94019, 94025, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 94031, 94036, 94041, 94046, 94051, 94056, 94061, 94066, 94071, + 94076, 94081, 94086, 94091, 94096, 94101, 94106, 94111, 94116, 94121, + 94126, 94131, 94136, 94141, 94146, 94151, 94156, 94161, 0, 0, 0, 0, 0, + 94168, 94174, 94180, 94186, 94192, 94197, 94203, 94209, 94215, 94221, + 94226, 94232, 94238, 94244, 94250, 94256, 94262, 94268, 94274, 94280, + 94285, 94291, 94297, 94303, 94309, 94315, 94320, 94326, 94332, 94337, + 94343, 94349, 94355, 94361, 94367, 94373, 94379, 94384, 94390, 94397, + 94404, 94411, 94418, 0, 0, 0, 0, 0, 94425, 94430, 94435, 94440, 94445, + 94450, 94455, 94460, 94465, 94470, 94475, 94480, 94485, 94490, 94495, + 94500, 94505, 94510, 94515, 94520, 94525, 94530, 94535, 94540, 94545, + 94550, 94555, 94559, 94563, 94567, 0, 94572, 94578, 94583, 94588, 94593, + 94598, 94604, 94610, 94616, 94622, 94628, 94634, 94640, 94646, 94652, + 94658, 94664, 94670, 94676, 94681, 94687, 94693, 94699, 94705, 94710, + 94716, 94722, 94727, 94733, 94739, 94745, 94751, 94757, 94763, 94769, + 94775, 94781, 0, 0, 0, 0, 94786, 94792, 94798, 94804, 94810, 94816, + 94822, 94828, 94834, 94841, 94846, 94851, 94857, 94863, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94869, 94875, 94881, 94887, 94894, + 94900, 94907, 94914, 94921, 94928, 94936, 94943, 94951, 94957, 94963, + 94969, 94975, 94981, 94987, 94993, 94999, 95005, 95011, 95017, 95023, + 95029, 95035, 95041, 95047, 95053, 95059, 95065, 95071, 95077, 95083, + 95089, 95095, 95101, 95107, 95113, 95119, 95125, 95131, 95137, 95144, + 95150, 95157, 95164, 95171, 95178, 95186, 95193, 95201, 95207, 95213, + 95219, 95225, 95231, 95237, 95243, 95249, 95255, 95261, 95267, 95273, + 95279, 95285, 95291, 95297, 95303, 95309, 95315, 95321, 95327, 95333, + 95339, 95345, 95351, 95357, 95363, 95369, 95374, 95379, 95384, 95389, + 95394, 95399, 95404, 95409, 95414, 95419, 95424, 95429, 95434, 95439, + 95444, 95449, 95454, 95459, 95464, 95469, 95474, 95479, 95484, 95489, + 95494, 95499, 95504, 95509, 95514, 95519, 95524, 95529, 95534, 95539, + 95544, 95549, 95554, 95559, 95564, 95569, 95574, 95579, 95584, 95589, + 95594, 95599, 95604, 95609, 95614, 95619, 95624, 95629, 95634, 95639, + 95644, 95649, 95654, 95659, 95664, 95669, 95674, 95679, 95684, 95689, + 95694, 95699, 95704, 95709, 95713, 95717, 95721, 95725, 95729, 95733, + 95737, 95742, 95747, 0, 0, 95752, 95757, 95761, 95765, 95769, 95773, + 95777, 95781, 95786, 95790, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 91792, 91798, 91804, 91810, 91816, 91822, 91829, - 91836, 91843, 91849, 91855, 91861, 91868, 91875, 91882, 91888, 91895, - 91902, 91909, 91916, 91922, 91929, 91936, 91942, 91949, 91956, 91963, - 91970, 91977, 91983, 91990, 91997, 92004, 92010, 92016, 92022, 92028, - 92034, 92041, 92048, 92054, 92060, 92066, 92073, 92079, 92086, 92093, - 92100, 92106, 92114, 92121, 92127, 92134, 92141, 92148, 92154, 0, 0, 0, - 0, 0, 0, 92161, 92169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 92177, 92181, 92186, 92191, 0, 92197, 92202, 0, 0, 0, 0, 0, 92207, 92213, - 92220, 92225, 92230, 92234, 92239, 92244, 0, 92249, 92254, 92259, 0, - 92264, 92269, 92274, 92279, 92284, 92289, 92294, 92299, 92304, 92309, - 92314, 92318, 92322, 92327, 92332, 92337, 92341, 92345, 92349, 92354, - 92359, 92364, 92369, 92373, 92378, 92382, 92387, 0, 0, 0, 0, 92392, - 92398, 92403, 0, 0, 0, 0, 92408, 92412, 92416, 92420, 92424, 92428, - 92433, 92438, 92444, 0, 0, 0, 0, 0, 0, 0, 0, 92450, 92456, 92463, 92469, - 92476, 92482, 92488, 92494, 92501, 0, 0, 0, 0, 0, 0, 0, 92507, 92515, - 92523, 92531, 92539, 92547, 92555, 92563, 92571, 92579, 92587, 92595, - 92603, 92611, 92619, 92627, 92635, 92643, 92651, 92659, 92667, 92675, - 92683, 92691, 92699, 92707, 92715, 92723, 92731, 92739, 92746, 92754, - 92762, 92766, 92771, 92776, 92781, 92786, 92791, 92796, 92801, 92805, - 92810, 92814, 92819, 92823, 92828, 92832, 92837, 92842, 92847, 92852, - 92857, 92862, 92867, 92872, 92877, 92882, 92887, 92892, 92897, 92902, - 92907, 92912, 92917, 92922, 92927, 92932, 92937, 92942, 92947, 92952, - 92957, 92962, 92967, 92972, 92977, 92982, 92987, 92992, 92997, 93002, - 93007, 93012, 93017, 93022, 0, 0, 0, 93027, 93032, 93041, 93049, 93058, - 93067, 93078, 93089, 93096, 93103, 93110, 93117, 93124, 93131, 93138, - 93145, 93152, 93159, 93166, 93173, 93180, 93187, 93194, 93201, 93208, - 93215, 93222, 93229, 93236, 0, 0, 93243, 93249, 93255, 93261, 93267, - 93274, 93281, 93289, 93297, 93304, 93311, 93318, 93325, 93332, 93339, - 93346, 93353, 93360, 93367, 93374, 93381, 93388, 93395, 93402, 93409, - 93416, 93423, 0, 0, 0, 0, 0, 93430, 93436, 93442, 93448, 93454, 93461, - 93468, 93476, 93484, 93490, 93496, 93503, 93509, 93515, 93521, 93527, - 93534, 93541, 93548, 93555, 93562, 93569, 93576, 93583, 93590, 93597, - 93604, 93611, 93618, 93625, 93632, 93639, 93646, 93653, 93660, 93667, - 93674, 93681, 93688, 93695, 93702, 93709, 93716, 93723, 93730, 93737, - 93744, 93751, 93758, 93765, 93772, 93779, 93786, 93793, 93800, 93807, - 93814, 93821, 93828, 93835, 93842, 93849, 93856, 93863, 93870, 93877, - 93884, 93891, 93898, 93905, 93912, 93919, 93926, 93933, 93940, 93947, - 93954, 93961, 93968, 93975, 93982, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 95795, 95799, 95804, 95809, 95814, 95819, 95824, 95829, 95834, 95838, + 95843, 95848, 95853, 95858, 95862, 95867, 95872, 95877, 95882, 95887, + 95892, 95897, 95902, 95906, 95911, 95916, 95921, 95926, 95931, 95936, + 95941, 95946, 95950, 95955, 95960, 95965, 95970, 95975, 95980, 95985, 0, + 0, 0, 0, 0, 0, 0, 0, 95990, 95997, 96004, 96011, 96018, 96025, 96032, + 96039, 96046, 96053, 96060, 96067, 96074, 96081, 96088, 96095, 96102, + 96109, 96116, 96123, 96130, 96137, 96144, 96151, 96158, 96165, 96172, + 96179, 96186, 96193, 96200, 96207, 96214, 96221, 96228, 96235, 96242, + 96249, 96256, 96263, 96270, 96277, 96284, 96291, 96298, 96305, 96312, + 96319, 96326, 96333, 96340, 96347, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 96354, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 96361, 96366, 96371, 96376, 96381, 96386, 96391, 96396, 96401, + 96406, 96411, 96416, 96421, 96426, 96431, 96436, 96441, 96446, 96451, + 96456, 96461, 96466, 96471, 96476, 96481, 96486, 96491, 96496, 96501, + 96506, 96511, 96516, 96521, 96526, 96531, 96536, 96541, 96546, 96551, + 96556, 96561, 96566, 96571, 96576, 96581, 96586, 96591, 96596, 96601, + 96606, 96611, 96616, 96621, 96626, 96631, 96636, 96641, 96646, 96651, + 96656, 96661, 96666, 96671, 96676, 96681, 96686, 96691, 96696, 96701, + 96706, 96711, 96716, 96721, 96726, 96731, 96736, 96741, 96746, 96751, + 96756, 96761, 96766, 96771, 96776, 96781, 96786, 96791, 96796, 96801, + 96806, 96811, 96816, 96821, 96826, 96831, 96836, 96841, 96846, 96851, + 96856, 96861, 96866, 96871, 96876, 96881, 96886, 96891, 96896, 96901, + 96906, 96911, 96916, 96921, 96926, 96931, 96936, 96941, 96946, 96951, + 96956, 96961, 96966, 96971, 96976, 96981, 96986, 96991, 96996, 97001, + 97006, 97011, 97016, 97021, 97026, 97031, 97036, 97041, 97046, 97051, + 97056, 97061, 97066, 97071, 97076, 97081, 97086, 97091, 97096, 97101, + 97106, 97111, 97116, 97121, 97126, 97131, 97136, 97141, 97146, 97151, + 97156, 97161, 97166, 97171, 97176, 97181, 97186, 97191, 97196, 97201, + 97206, 97211, 97216, 97221, 97226, 97231, 97236, 97241, 97246, 97251, + 97256, 97261, 97266, 97271, 97276, 97281, 97286, 97291, 97296, 97301, + 97306, 97311, 97316, 97321, 97326, 97331, 97336, 97341, 97346, 97351, + 97356, 97361, 97366, 97371, 97376, 97381, 97386, 97391, 97396, 97401, + 97406, 97411, 97416, 97421, 97426, 97431, 97436, 97441, 97446, 97451, + 97456, 97461, 97466, 97471, 97476, 97481, 97486, 97491, 97496, 97501, + 97506, 97511, 97516, 97521, 97526, 97531, 97536, 97541, 97546, 97551, + 97556, 97561, 97566, 97571, 97576, 97581, 97586, 97591, 97596, 97601, + 97606, 97611, 97616, 97621, 97626, 97631, 97636, 97641, 97646, 97651, + 97656, 97661, 97666, 97671, 97676, 97681, 97686, 97691, 97696, 97701, + 97706, 97711, 97716, 97721, 97726, 97731, 97736, 97741, 97746, 97751, + 97756, 97761, 97766, 97771, 97776, 97781, 97786, 97791, 97796, 97801, + 97806, 97811, 97816, 97821, 97826, 97831, 97836, 97841, 97846, 97851, + 97856, 97861, 97866, 97871, 97876, 97881, 97886, 97891, 97896, 97901, + 97906, 97911, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97916, 97922, 97929, 97936, + 97942, 97949, 97956, 97963, 97970, 97976, 97983, 97990, 97997, 98004, + 98011, 98018, 98025, 98032, 98039, 98046, 98053, 98060, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 98067, 98072, 98077, 98082, 98087, 98092, 98097, 98102, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 98107, 98111, 98115, 98119, 98123, 98127, 0, 0, 98132, + 0, 98137, 98141, 98146, 98151, 98156, 98161, 98166, 98171, 98176, 98181, + 98186, 98190, 98195, 98200, 98205, 98210, 98215, 98220, 98225, 98230, + 98235, 98239, 98244, 98249, 98254, 98259, 98264, 98269, 98274, 98279, + 98284, 98289, 98294, 98299, 98304, 98309, 98314, 98319, 98324, 98328, + 98333, 98338, 98343, 98348, 0, 98353, 98358, 0, 0, 0, 98363, 0, 0, 98368, + 98373, 98380, 98387, 98394, 98401, 98408, 98415, 98422, 98429, 98436, + 98443, 98450, 98457, 98464, 98471, 98478, 98485, 98492, 98499, 98506, + 98513, 98520, 0, 98527, 98534, 98540, 98546, 98552, 98559, 98566, 98574, + 98582, 98591, 98596, 98601, 98606, 98611, 98616, 98621, 98626, 98631, + 98636, 98641, 98646, 98651, 98656, 98662, 98667, 98672, 98677, 98682, + 98687, 98692, 98697, 98702, 98707, 98713, 98719, 98723, 98727, 98731, + 98735, 98739, 98744, 98749, 98755, 98760, 98766, 98771, 98776, 98781, + 98787, 98792, 98797, 98802, 98807, 98812, 98818, 98823, 98829, 98834, + 98840, 98845, 98851, 98856, 98862, 98867, 98872, 98877, 98882, 98887, + 98892, 98897, 98903, 98908, 0, 0, 0, 0, 0, 0, 0, 0, 98913, 98917, 98921, + 98925, 98929, 98935, 98939, 98944, 98949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98955, 98960, 98965, 98970, + 98975, 98980, 98985, 98990, 98995, 99000, 99005, 99010, 99015, 99020, + 99025, 99030, 99035, 99040, 99045, 0, 99050, 99055, 0, 0, 0, 0, 0, 99060, + 99064, 99068, 99073, 99078, 99084, 99089, 99094, 99099, 99104, 99109, + 99114, 99119, 99124, 99129, 99134, 99139, 99144, 99149, 99154, 99159, + 99164, 99169, 99174, 99179, 99184, 99189, 99194, 99198, 99203, 99208, + 99214, 99218, 0, 0, 0, 99222, 99228, 99232, 99237, 99242, 99247, 99251, + 99256, 99260, 99265, 99270, 99274, 99279, 99284, 99288, 99292, 99297, + 99302, 99306, 99311, 99316, 99320, 99325, 99330, 99335, 99340, 99345, 0, + 0, 0, 0, 0, 99350, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99355, + 99360, 99365, 99370, 99375, 99380, 99386, 99392, 99398, 99403, 99408, + 99414, 99420, 99426, 99432, 99438, 99444, 99450, 99456, 99462, 99468, + 99474, 99480, 99485, 99491, 99497, 99503, 99509, 99515, 99520, 99526, + 99532, 99538, 99542, 99546, 99550, 99554, 99558, 99563, 99568, 99572, + 99576, 99581, 99586, 99591, 99596, 99601, 99606, 99611, 99618, 99623, + 99627, 99632, 99637, 99642, 99646, 0, 0, 0, 0, 99651, 99659, 99666, + 99672, 99678, 99682, 99686, 99690, 99694, 99698, 99702, 99707, 99711, + 99716, 99721, 99726, 99731, 99736, 99741, 99746, 0, 0, 99751, 99757, + 99763, 99769, 99776, 99783, 99790, 99797, 99804, 99811, 99817, 99823, + 99829, 99836, 99843, 99850, 99857, 99864, 99871, 99878, 99885, 99892, + 99899, 99906, 99913, 99920, 99927, 99934, 99942, 99950, 99958, 99967, + 99976, 99985, 99994, 100003, 100012, 100019, 100026, 100033, 100041, + 100049, 100057, 100065, 100073, 100081, 100089, 100093, 100098, 100103, + 0, 100109, 100114, 0, 0, 0, 0, 0, 100119, 100125, 100132, 100137, 100142, + 100146, 100151, 100156, 0, 100161, 100166, 100171, 0, 100176, 100181, + 100186, 100191, 100196, 100201, 100206, 100211, 100216, 100221, 100226, + 100231, 100235, 100240, 100245, 100250, 100254, 100258, 100263, 100268, + 100273, 100278, 100283, 100288, 100293, 100297, 100302, 0, 0, 0, 0, + 100307, 100313, 100318, 0, 0, 0, 0, 100323, 100327, 100331, 100335, + 100339, 100343, 100348, 100353, 100359, 0, 0, 0, 0, 0, 0, 0, 0, 100365, + 100371, 100378, 100384, 100391, 100397, 100403, 100409, 100416, 0, 0, 0, + 0, 0, 0, 0, 100422, 100430, 100438, 100446, 100454, 100462, 100470, + 100478, 100486, 100494, 100502, 100510, 100518, 100526, 100534, 100542, + 100550, 100558, 100566, 100574, 100582, 100590, 100598, 100606, 100614, + 100622, 100630, 100638, 100646, 100654, 100661, 100669, 100677, 100684, + 100691, 100698, 100705, 100712, 100719, 100726, 100733, 100740, 100747, + 100754, 100761, 100768, 100775, 100782, 100789, 100796, 100803, 100810, + 100817, 100824, 100831, 100838, 100845, 100852, 100859, 100866, 100873, + 100880, 100886, 100893, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100900, 100905, 100910, + 100915, 100920, 100925, 100930, 100935, 100940, 100945, 100950, 100955, + 100960, 100965, 100970, 100975, 100980, 100985, 100990, 100995, 101000, + 101005, 101010, 101015, 101020, 101025, 101030, 101035, 101040, 101045, + 101050, 101055, 101060, 101065, 101070, 101075, 101080, 101085, 101091, + 0, 0, 0, 0, 101097, 101101, 101105, 101110, 101115, 101121, 101127, + 101133, 101143, 101152, 101158, 101165, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 101173, 101177, 101182, 101187, 101192, 101197, 101202, 101207, 101212, + 101216, 101221, 101225, 101230, 101234, 101239, 101243, 101248, 101253, + 101258, 101263, 101268, 101273, 101278, 101283, 101288, 101293, 101298, + 101303, 101308, 101313, 101318, 101323, 101328, 101333, 101338, 101343, + 101348, 101353, 101358, 101363, 101368, 101373, 101378, 101383, 101388, + 101393, 101398, 101403, 101408, 101413, 101418, 101423, 101428, 101433, + 0, 0, 0, 101438, 101443, 101452, 101460, 101469, 101478, 101489, 101500, + 101507, 101514, 101521, 101528, 101535, 101542, 101549, 101556, 101563, + 101570, 101577, 101584, 101591, 101598, 101605, 101612, 101619, 101626, + 101633, 101640, 101647, 0, 0, 101654, 101660, 101666, 101672, 101678, + 101685, 101692, 101700, 101708, 101715, 101722, 101729, 101736, 101743, + 101750, 101757, 101764, 101771, 101778, 101785, 101792, 101799, 101806, + 101813, 101820, 101827, 101834, 0, 0, 0, 0, 0, 101841, 101847, 101853, + 101859, 101865, 101872, 101879, 101887, 101895, 101902, 101909, 101916, + 101923, 101930, 101937, 101944, 101951, 101958, 101965, 101972, 101979, + 101986, 101993, 102000, 102007, 102014, 0, 0, 0, 0, 0, 0, 0, 102021, + 102028, 102037, 102047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102057, + 102063, 102069, 102075, 102081, 102088, 102095, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 102103, 102110, 102117, 102125, 102132, 102139, 102146, 102153, 102161, + 102169, 102177, 102185, 102193, 102201, 102209, 102217, 102225, 102233, + 102241, 102249, 102257, 102265, 102273, 102281, 102289, 102297, 102305, + 102313, 102321, 102329, 102337, 102345, 102353, 102361, 102369, 102377, + 102385, 102393, 102401, 102409, 102417, 102425, 102433, 102441, 102449, + 102457, 102465, 102473, 102481, 102489, 102497, 102505, 102513, 102521, + 102529, 102537, 102545, 102553, 102561, 102569, 102577, 102585, 102593, + 102601, 102609, 102617, 102625, 102633, 102641, 102649, 102657, 102665, + 102673, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 102681, 102686, 102692, 102698, 102704, + 102710, 102716, 102722, 102728, 102734, 102739, 102746, 102752, 102758, + 102764, 102770, 102776, 102781, 102787, 102793, 102799, 102805, 102811, + 102817, 102823, 102829, 102835, 102841, 102846, 102852, 102860, 102868, + 102874, 102880, 102886, 102892, 102900, 102906, 102912, 102918, 102924, + 102930, 102936, 102941, 102947, 102955, 102963, 102969, 102975, 102981, + 102988, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102994, 102999, 103005, + 103011, 103017, 103023, 103029, 103035, 103041, 103047, 103052, 103059, + 103065, 103071, 103077, 103083, 103089, 103094, 103100, 103106, 103112, + 103118, 103124, 103130, 103136, 103142, 103148, 103154, 103159, 103165, + 103173, 103181, 103187, 103193, 103199, 103205, 103213, 103219, 103225, + 103231, 103237, 103243, 103249, 103254, 103260, 103268, 103276, 103282, + 103288, 103294, 103301, 0, 0, 0, 0, 0, 0, 0, 103307, 103311, 103315, + 103320, 103325, 103331, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 103337, 103341, 103345, 103349, 103353, 103357, + 103361, 103366, 103370, 103375, 103380, 103385, 103390, 103395, 103400, + 103405, 103410, 103415, 103420, 103426, 103432, 103438, 103445, 103452, + 103459, 103466, 103473, 103480, 103487, 103494, 103501, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 103508, 103512, 103516, 103520, 103524, 103528, 103531, 103535, + 103538, 103542, 103545, 103549, 103553, 103558, 103562, 103567, 103570, + 103574, 103577, 103581, 103584, 103588, 103592, 103596, 103600, 103604, + 103608, 103612, 103616, 103620, 103624, 103628, 103632, 103636, 103640, + 103644, 103648, 103652, 103656, 103660, 103663, 103667, 103671, 103675, + 103678, 103681, 103685, 103689, 103693, 103697, 103701, 103705, 103708, + 103712, 103718, 103724, 103730, 103735, 103742, 103746, 103751, 103755, + 103760, 103765, 103771, 103776, 103782, 103786, 103791, 103795, 103800, + 103803, 103806, 103810, 103815, 103821, 103826, 103832, 0, 0, 0, 0, + 103837, 103840, 103843, 103846, 103849, 103852, 103855, 103859, 103862, + 103866, 103870, 103874, 103878, 103882, 103886, 103890, 103894, 103898, + 103902, 103907, 103912, 103916, 103919, 103922, 103925, 103928, 103931, + 103934, 103938, 103941, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 103945, 103949, 103954, 103959, 103964, 103968, 103973, 103977, 103982, + 103986, 103991, 103995, 104000, 104004, 104009, 104013, 104018, 104023, + 104028, 104033, 104038, 104043, 104048, 104053, 104058, 104063, 104068, + 104073, 104078, 104083, 104088, 104093, 104098, 104103, 104108, 104113, + 104118, 104122, 104127, 104132, 104137, 104141, 104145, 104150, 104155, + 104160, 104165, 104170, 104175, 104179, 104185, 104190, 104196, 104201, + 104207, 104212, 104218, 104223, 104229, 104234, 104239, 104244, 104249, + 104253, 104258, 104264, 104268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 104273, 104280, 104287, 104294, 104301, 104308, 104315, 104322, 104329, + 104336, 104343, 104350, 104357, 104364, 104371, 104378, 104385, 104392, + 104399, 104406, 104413, 104420, 104427, 104434, 104441, 0, 0, 0, 0, 0, 0, + 0, 104448, 104455, 104461, 104467, 104473, 104479, 104485, 104491, + 104498, 104504, 0, 0, 0, 0, 0, 0, 104511, 104516, 104521, 104526, 104531, + 104535, 104539, 104543, 104548, 104553, 104558, 104563, 104568, 104573, + 104578, 104583, 104588, 104593, 104598, 104603, 104608, 104613, 104618, + 104623, 104628, 104633, 104638, 104643, 104648, 104653, 104658, 104663, + 104668, 104673, 104678, 104683, 104688, 104693, 104698, 104703, 104708, + 104713, 104719, 104724, 104730, 104735, 104741, 104746, 104752, 104758, + 104762, 104767, 104771, 0, 104775, 104780, 104784, 104788, 104792, + 104796, 104800, 104804, 104809, 104813, 104818, 104823, 104827, 104832, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104837, 104841, 104845, 104849, + 104853, 104857, 104861, 104866, 104871, 104876, 104881, 104886, 104891, + 104896, 104901, 104906, 104911, 104916, 104921, 104926, 104931, 104936, + 104941, 104946, 104951, 104955, 104960, 104965, 104970, 104974, 104979, + 104984, 104989, 104994, 104998, 105003, 105008, 105013, 105018, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 105023, 105027, 105031, 105035, 105038, 105042, 105045, + 105049, 105052, 105056, 105060, 105065, 105069, 105074, 105077, 105081, + 105084, 105088, 105091, 105095, 105099, 105103, 105107, 105111, 105115, + 105119, 105123, 105127, 105131, 105135, 105139, 105143, 105147, 105151, + 105155, 105159, 105163, 105167, 105170, 105174, 105178, 105182, 105185, + 105188, 105192, 105196, 105200, 105204, 105208, 105212, 105216, 105219, + 105224, 105228, 105233, 105237, 105242, 105247, 105253, 105258, 105264, + 105268, 105273, 105277, 105282, 105286, 105290, 105294, 105298, 105301, + 105304, 105308, 105312, 105315, 105319, 105323, 105327, 105334, 0, 0, + 105338, 105342, 105345, 105348, 105351, 105354, 105357, 105360, 105364, + 105367, 105371, 105374, 105378, 105381, 105385, 105390, 0, 105395, + 105400, 105405, 105410, 105415, 105420, 105425, 105431, 105436, 105442, + 105448, 105454, 105460, 105466, 105472, 105478, 105484, 105490, 105496, + 105503, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105510, 105514, 105519, 105523, + 105527, 105531, 105536, 105540, 105545, 105549, 105554, 105559, 105564, + 105569, 105574, 105579, 105584, 105589, 0, 105594, 105599, 105604, + 105609, 105614, 105619, 105624, 105629, 105634, 105639, 105644, 105649, + 105654, 105658, 105663, 105668, 105673, 105678, 105682, 105686, 105691, + 105696, 105701, 105706, 105710, 105715, 105721, 105726, 105732, 105737, + 105742, 105748, 105753, 105759, 105764, 105769, 105774, 105779, 105783, + 105788, 105794, 105799, 105805, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 105810, 105814, 105818, 105822, 105826, 105830, 105835, 0, + 105840, 0, 105845, 105850, 105855, 105860, 0, 105865, 105870, 105875, + 105880, 105885, 105890, 105895, 105900, 105905, 105910, 105915, 105920, + 105925, 105929, 105934, 0, 105939, 105944, 105948, 105952, 105957, + 105962, 105967, 105972, 105976, 105981, 105986, 0, 0, 0, 0, 0, 0, 105991, + 105995, 106000, 106004, 106009, 106013, 106018, 106022, 106027, 106031, + 106036, 106040, 106045, 106050, 106055, 106060, 106065, 106070, 106075, + 106080, 106085, 106090, 106095, 106100, 106105, 106110, 106115, 106120, + 106125, 106130, 106135, 106140, 106145, 106150, 106155, 106159, 106164, + 106169, 106174, 106179, 106183, 106187, 106192, 106197, 106202, 106207, + 106212, 106216, 106221, 106227, 106232, 106238, 106243, 106249, 106254, + 106260, 106265, 106271, 106276, 0, 0, 0, 0, 0, 106281, 106286, 106290, + 106294, 106298, 106302, 106306, 106310, 106315, 106319, 0, 0, 0, 0, 0, 0, + 106324, 106331, 106336, 106341, 0, 106346, 106350, 106355, 106359, + 106364, 106368, 106373, 106378, 0, 0, 106383, 106388, 0, 0, 106393, + 106398, 106403, 106407, 106412, 106417, 106422, 106427, 106432, 106437, + 106442, 106447, 106452, 106457, 106462, 106467, 106472, 106477, 106482, + 106487, 106492, 106497, 0, 106502, 106506, 106511, 106516, 106521, + 106525, 106529, 0, 106534, 106539, 0, 106544, 106549, 106554, 106559, + 106564, 0, 0, 106568, 106573, 106578, 106584, 106589, 106595, 106600, + 106606, 106612, 0, 0, 106619, 106625, 0, 0, 106631, 106637, 106643, 0, 0, + 106648, 0, 0, 0, 0, 0, 0, 106652, 0, 0, 0, 0, 0, 106659, 106664, 106671, + 106679, 106685, 106691, 106697, 0, 0, 106704, 106710, 106715, 106720, + 106725, 106730, 106735, 0, 0, 0, 106740, 106745, 106750, 106756, 106762, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 106767, 106771, 106775, 106780, 106784, 106789, 106793, 106798, + 106803, 106809, 106814, 106820, 106824, 106829, 106833, 106838, 106842, + 106847, 106852, 106857, 106862, 106867, 106872, 106877, 106882, 106887, + 106892, 106897, 106902, 106907, 106912, 106917, 106922, 106927, 106932, + 106937, 106941, 106946, 106951, 106956, 106960, 106964, 106969, 106974, + 106979, 106984, 106989, 106994, 106998, 107004, 107009, 107015, 107020, + 107026, 107032, 107039, 107045, 107052, 107057, 107064, 107070, 107075, + 107082, 107088, 107093, 107098, 107103, 107108, 107113, 107118, 107122, + 107127, 0, 0, 0, 0, 0, 0, 0, 0, 107131, 107136, 107140, 107144, 107148, + 107152, 107156, 107160, 107165, 107169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107174, 107177, 107181, 107184, 107188, + 107191, 107195, 107199, 107204, 107208, 107213, 107216, 107220, 107223, + 107227, 107230, 107234, 107238, 107242, 107246, 107250, 107254, 107258, + 107262, 107266, 107270, 107274, 107278, 107282, 107286, 107290, 107294, + 107298, 107302, 107306, 107309, 107313, 107317, 107321, 107324, 107327, + 107331, 107335, 107339, 107343, 107347, 107351, 107354, 107359, 107363, + 107368, 107372, 107377, 107382, 0, 0, 107388, 107392, 107397, 107401, + 107406, 107410, 107414, 107418, 107422, 107426, 107430, 107433, 107437, + 107442, 107446, 107451, 107456, 107461, 107468, 107480, 107492, 107504, + 107517, 107531, 107538, 107548, 107556, 107565, 107574, 107583, 107593, + 107604, 107616, 107623, 107630, 107638, 107643, 107649, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 107656, 107660, 107665, 107669, 107674, 107678, 107683, + 107688, 107694, 107699, 107705, 107709, 107714, 107718, 107723, 107727, + 107732, 107737, 107742, 107747, 107752, 107757, 107762, 107767, 107772, + 107777, 107782, 107787, 107792, 107797, 107802, 107807, 107812, 107817, + 107822, 107826, 107831, 107836, 107841, 107845, 107849, 107854, 107859, + 107864, 107869, 107874, 107879, 107883, 107888, 107894, 107899, 107905, + 107910, 107916, 107922, 107929, 107935, 107942, 107947, 107953, 107958, + 107964, 107969, 107974, 107979, 107984, 107988, 107993, 107998, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 108003, 108008, 108012, 108016, 108020, 108024, + 108028, 108032, 108037, 108041, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 108046, 108050, 108055, 108059, 108064, 108068, 108073, 108077, 108082, + 108086, 108091, 108095, 108100, 108105, 108110, 108115, 108120, 108125, + 108130, 108135, 108140, 108145, 108150, 108155, 108160, 108165, 108170, + 108175, 108180, 108185, 108190, 108194, 108199, 108204, 108209, 108213, + 108217, 108222, 108227, 108232, 108237, 108242, 108246, 108251, 108256, + 108261, 108267, 108272, 108278, 108283, 108289, 108294, 108300, 108305, + 108311, 108316, 0, 0, 0, 0, 0, 0, 0, 0, 108321, 108326, 108330, 108334, + 108338, 108342, 108346, 108350, 108355, 108359, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108364, + 108368, 108373, 108378, 108383, 108388, 108395, 108399, 108404, 108409, + 108413, 108418, 108423, 108428, 108433, 108438, 108443, 108448, 108452, + 108456, 108461, 108466, 108471, 108478, 108483, 108488, 0, 0, 0, 108493, + 108500, 108507, 108516, 108521, 108527, 108532, 108538, 108543, 108549, + 108554, 108560, 108565, 108571, 108577, 0, 0, 0, 0, 108582, 108587, + 108591, 108595, 108599, 108603, 108607, 108611, 108616, 108620, 108625, + 108630, 108635, 108641, 108646, 108651, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 108656, 108664, 108671, 108679, 108687, 108694, 108702, + 108710, 108718, 108725, 108732, 108740, 108748, 108756, 108764, 108772, + 108780, 108788, 108796, 108804, 108812, 108820, 108828, 108836, 108844, + 108852, 108860, 108868, 108876, 108884, 108892, 108900, 108908, 108916, + 108923, 108931, 108939, 108946, 108954, 108962, 108970, 108977, 108984, + 108992, 109000, 109008, 109016, 109024, 109032, 109040, 109048, 109056, + 109064, 109072, 109080, 109088, 109096, 109104, 109112, 109120, 109128, + 109136, 109144, 109152, 109160, 109167, 109173, 109179, 109185, 109191, + 109197, 109203, 109210, 109216, 109223, 109230, 109237, 109244, 109251, + 109258, 109265, 109272, 109279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 109286, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 109292, 109300, 109308, 109317, 109325, 109334, 109343, 109352, + 109361, 109369, 109378, 109387, 109396, 109405, 109414, 109423, 109432, + 109441, 109450, 109459, 109468, 109477, 109485, 109493, 109501, 109509, + 109517, 109526, 109535, 109545, 109555, 109565, 109575, 109585, 109594, + 109604, 109614, 109624, 109635, 109645, 109657, 109669, 109680, 109694, + 109705, 109715, 109727, 109738, 109748, 109760, 109772, 109783, 109794, + 109804, 109814, 109826, 109837, 0, 0, 0, 0, 0, 0, 0, 109849, 109852, + 109857, 109863, 109871, 109876, 109882, 109890, 109896, 109902, 109906, + 109910, 109917, 109926, 109933, 109942, 109948, 109957, 109964, 109971, + 109978, 109988, 109994, 109998, 110005, 110014, 110024, 110031, 110038, + 110042, 110046, 110053, 110063, 110067, 110074, 110081, 110088, 110094, + 110101, 110108, 110115, 110122, 110126, 110130, 110134, 110141, 110145, + 110152, 110159, 110173, 110182, 110186, 110190, 110194, 110201, 110205, + 110209, 110213, 110221, 110229, 110248, 110258, 110278, 110282, 110286, + 110290, 110294, 110298, 110302, 110306, 110313, 110317, 110320, 110324, + 110328, 110334, 110341, 110350, 110354, 110363, 110372, 110380, 110384, + 110391, 110395, 110399, 110403, 110407, 110418, 110427, 110436, 110445, + 110454, 110466, 110475, 110484, 110493, 110501, 110510, 110522, 110531, + 110540, 110549, 110561, 110570, 110579, 110591, 110600, 110609, 110621, + 110630, 110634, 110638, 110642, 110646, 110650, 110654, 110658, 110665, + 110669, 110673, 110684, 110688, 110692, 110699, 110705, 110711, 110715, + 110722, 110726, 110730, 110734, 110738, 110742, 110746, 110752, 110760, + 110764, 110768, 110771, 110777, 110787, 110791, 110803, 110810, 110817, + 110824, 110831, 110837, 110841, 110845, 110849, 110853, 110860, 110869, + 110876, 110884, 110892, 110898, 110902, 110906, 110910, 110914, 110920, + 110929, 110941, 110948, 110955, 110964, 110975, 110981, 110990, 110999, + 111006, 111015, 111022, 111029, 111039, 111046, 111053, 111060, 111067, + 111071, 111077, 111081, 111092, 111100, 111109, 111121, 111128, 111135, + 111145, 111152, 111162, 111169, 111179, 111186, 111193, 111203, 111210, + 111217, 111227, 111234, 111246, 111255, 111262, 111269, 111276, 111285, + 111295, 111308, 111315, 111325, 111335, 111342, 111351, 111364, 111371, + 111378, 111385, 111395, 111405, 111412, 111422, 111429, 111436, 111446, + 111452, 111459, 111466, 111473, 111483, 111490, 111497, 111504, 111510, + 111517, 111527, 111534, 111538, 111546, 111550, 111562, 111566, 111580, + 111584, 111588, 111592, 111596, 111602, 111609, 111617, 111621, 111625, + 111629, 111633, 111640, 111644, 111650, 111656, 111664, 111668, 111675, + 111683, 111687, 111691, 111697, 111701, 111710, 111719, 111726, 111736, + 111742, 111746, 111750, 111758, 111765, 111772, 111778, 111782, 111790, + 111794, 111801, 111813, 111820, 111830, 111836, 111840, 111849, 111856, + 111865, 111869, 111873, 111880, 111884, 111888, 111892, 111896, 111899, + 111905, 111911, 111915, 111919, 111926, 111933, 111940, 111947, 111954, + 111961, 111968, 111975, 111981, 111985, 111989, 111996, 112003, 112010, + 112017, 112024, 112028, 112031, 112036, 112040, 112044, 112053, 112062, + 112066, 112070, 112076, 112082, 112099, 112105, 112109, 112118, 112122, + 112126, 112133, 112141, 112149, 112155, 112159, 112163, 112167, 112171, + 112174, 112180, 112187, 112197, 112204, 112211, 112218, 112224, 112231, + 112238, 112245, 112252, 112259, 112268, 112275, 112287, 112294, 112301, + 112311, 112322, 112329, 112336, 112343, 112350, 112357, 112364, 112371, + 112378, 112385, 112392, 112402, 112412, 112422, 112429, 112439, 112446, + 112453, 112460, 112467, 112474, 112481, 112488, 112495, 112502, 112509, + 112516, 112523, 112530, 112536, 112543, 112550, 112559, 112566, 112573, + 112577, 112585, 112589, 112593, 112597, 112601, 112605, 112612, 112616, + 112625, 112629, 112636, 112644, 112648, 112652, 112656, 112669, 112685, + 112689, 112693, 112700, 112706, 112713, 112717, 112721, 112725, 112729, + 112733, 112740, 112744, 112762, 112766, 112770, 112777, 112781, 112785, + 112791, 112795, 112799, 112807, 112811, 112815, 112819, 112823, 112829, + 112840, 112849, 112858, 112865, 112872, 112883, 112890, 112897, 112904, + 112911, 112918, 112925, 112932, 112942, 112948, 112955, 112965, 112974, + 112981, 112990, 113000, 113007, 113014, 113021, 113028, 113040, 113047, + 113054, 113061, 113068, 113075, 113085, 113092, 113099, 113109, 113122, + 113134, 113141, 113151, 113158, 113165, 113172, 113187, 113193, 113201, + 113211, 113221, 113228, 113235, 113241, 113245, 113252, 113262, 113268, + 113281, 113285, 113289, 113296, 113300, 113307, 113317, 113321, 113325, + 113329, 113333, 113337, 113344, 113348, 113355, 113362, 113369, 113378, + 113387, 113397, 113404, 113411, 113418, 113428, 113435, 113445, 113452, + 113462, 113469, 113476, 113486, 113496, 113503, 113509, 113517, 113525, + 113531, 113537, 113541, 113545, 113552, 113560, 113566, 113570, 113574, + 113578, 113585, 113597, 113600, 113607, 113613, 113617, 113621, 113625, + 113629, 113633, 113637, 113641, 113645, 113649, 113653, 113660, 113664, + 113670, 113674, 113678, 113682, 113688, 113695, 113702, 113709, 113721, + 113729, 113733, 113739, 113748, 113755, 113761, 113765, 113769, 113773, + 113779, 113788, 113796, 113800, 113806, 113810, 113814, 113818, 113824, + 113831, 113837, 113841, 113847, 113851, 113855, 113864, 113876, 113880, + 113887, 113894, 113904, 113911, 113923, 113930, 113937, 113944, 113955, + 113965, 113978, 113988, 113995, 113999, 114003, 114007, 114011, 114020, + 114029, 114038, 114055, 114064, 114070, 114077, 114085, 114098, 114102, + 114111, 114120, 114129, 114138, 114149, 114158, 114167, 114176, 114185, + 114194, 114203, 114213, 114216, 114220, 114224, 114228, 114232, 114236, + 114242, 114249, 114256, 114263, 114269, 114275, 114282, 114288, 114295, + 114303, 114307, 114314, 114321, 114328, 114336, 114340, 114344, 114348, + 114352, 114356, 114362, 114366, 114372, 114379, 114386, 114392, 114399, + 114406, 114413, 114420, 114427, 114434, 114441, 114448, 114455, 114462, + 114469, 114476, 114483, 114490, 114496, 114500, 114509, 114513, 114517, + 114521, 114525, 114531, 114538, 114545, 114552, 114559, 114566, 114572, + 114580, 114584, 114588, 114592, 114596, 114602, 114619, 114636, 114640, + 114644, 114648, 114652, 114656, 114660, 114666, 114673, 114677, 114683, + 114690, 114697, 114704, 114711, 114718, 114727, 114734, 114741, 114748, + 114755, 114759, 114763, 114769, 114781, 114785, 114789, 114798, 114802, + 114806, 114810, 114816, 114820, 114824, 114833, 114837, 114841, 114845, + 114852, 114856, 114860, 114864, 114868, 114872, 114876, 114880, 114884, + 114890, 114897, 114904, 114910, 114914, 114931, 114937, 114941, 114947, + 114953, 114959, 114965, 114971, 114977, 114981, 114985, 114989, 114995, + 114999, 115005, 115009, 115013, 115020, 115027, 115044, 115048, 115052, + 115056, 115060, 115064, 115076, 115079, 115084, 115089, 115104, 115114, + 115126, 115130, 115134, 115138, 115144, 115151, 115158, 115168, 115180, + 115186, 115192, 115201, 115205, 115209, 115216, 115226, 115233, 115239, + 115243, 115247, 115254, 115260, 115264, 115270, 115274, 115282, 115288, + 115292, 115300, 115309, 115316, 115322, 115329, 115336, 115346, 115356, + 115360, 115364, 115368, 115372, 115378, 115385, 115391, 115398, 115405, + 115412, 115421, 115428, 115435, 115441, 115448, 115455, 115462, 115469, + 115476, 115483, 115489, 115496, 115503, 115510, 115519, 115526, 115533, + 115537, 115543, 115547, 115553, 115560, 115567, 115574, 115578, 115582, + 115586, 115590, 115594, 115601, 115605, 115609, 115615, 115623, 115627, + 115631, 115635, 115639, 115646, 115650, 115654, 115662, 115666, 115670, + 115674, 115678, 115684, 115688, 115692, 115698, 115705, 115711, 115718, + 115730, 115734, 115741, 115748, 115755, 115762, 115774, 115781, 115785, + 115789, 115793, 115800, 115807, 115814, 115821, 115831, 115838, 115844, + 115851, 115858, 115865, 115872, 115881, 115891, 115898, 115902, 115909, + 115913, 115917, 115921, 115928, 115935, 115945, 115951, 115955, 115964, + 115968, 115975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115979, 115985, 115991, 115998, 116005, + 116012, 116019, 116026, 116033, 116039, 116046, 116053, 116060, 116067, + 116074, 116081, 116087, 116093, 116099, 116105, 116111, 116117, 116123, + 116129, 116135, 116142, 116149, 116156, 116163, 116170, 116177, 116183, + 116189, 116195, 116202, 116209, 116215, 116221, 116230, 116237, 116244, + 116251, 116258, 116265, 116272, 116278, 116284, 116290, 116299, 116306, + 116313, 116324, 116335, 116341, 116347, 116353, 116362, 116369, 116376, + 116386, 116396, 116407, 116418, 116430, 116443, 116454, 116465, 116477, + 116490, 116501, 116512, 116523, 116534, 116545, 116557, 116565, 116573, + 116582, 116591, 116600, 116606, 116612, 116618, 116625, 116635, 116642, + 116652, 116657, 116662, 116668, 116674, 116682, 116690, 116699, 116710, + 116721, 116729, 116737, 116746, 116755, 116763, 116770, 116778, 116786, + 116793, 116800, 116809, 116818, 116827, 116836, 116845, 0, 116854, + 116865, 116872, 116880, 116888, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116896, + 116905, 116912, 116919, 116928, 116935, 116942, 116949, 116959, 116966, + 116973, 116980, 116988, 116995, 117002, 117009, 117020, 117027, 117034, + 117041, 117048, 117055, 117064, 117071, 117077, 117084, 117093, 117100, + 117107, 117114, 117124, 117131, 117138, 117148, 117158, 117165, 117172, + 117179, 117186, 117193, 117200, 117209, 117216, 117223, 117229, 117237, + 117246, 117255, 117266, 117275, 117284, 117293, 117302, 117311, 117318, + 117325, 117334, 117346, 117356, 117363, 117370, 117380, 117390, 117399, + 117409, 117416, 117426, 117433, 117440, 117447, 117457, 117467, 117474, + 117481, 117491, 117497, 117508, 117517, 117527, 117535, 117548, 117555, + 117561, 117569, 117576, 117586, 117590, 117594, 117598, 117602, 117606, + 117610, 117614, 117623, 117627, 117634, 117638, 117642, 117646, 117650, + 117654, 117658, 117662, 117666, 117670, 117674, 117678, 117682, 117686, + 117690, 117694, 117698, 117702, 117706, 117710, 117717, 117724, 117734, + 117747, 117757, 117761, 117765, 117769, 117773, 117777, 117781, 117785, + 117789, 117793, 117797, 117801, 117808, 117815, 117826, 117833, 117840, + 117847, 117854, 117861, 117868, 117875, 117879, 117883, 117890, 117897, + 117904, 117913, 117920, 117933, 117943, 117950, 117957, 117961, 117965, + 117974, 117981, 117988, 117995, 118008, 118015, 118022, 118032, 118042, + 118051, 118058, 118065, 118072, 118079, 118086, 118093, 118103, 118109, + 118117, 118124, 118132, 118139, 118150, 118157, 118163, 118170, 118177, + 118184, 118191, 118201, 118211, 118218, 118225, 118234, 118242, 118248, + 118255, 118262, 118269, 118276, 118280, 118290, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 118300, 118304, 118308, 118312, + 118316, 118320, 118324, 118328, 118332, 118336, 118340, 118344, 118348, + 118352, 118356, 118360, 118364, 118368, 118372, 118376, 118380, 118384, + 118388, 118392, 118396, 118400, 118404, 118408, 118412, 118416, 118420, + 118424, 118428, 118432, 118436, 118440, 118444, 118448, 118452, 118456, + 118460, 118464, 118468, 118472, 118476, 118480, 118484, 118488, 118492, + 118496, 118500, 118504, 118508, 118512, 118516, 118520, 118524, 118528, + 118532, 118536, 118540, 118544, 118548, 118552, 118556, 118560, 118564, + 118568, 118572, 118576, 118580, 118584, 118588, 118592, 118596, 118600, + 118604, 118608, 118612, 118616, 118620, 118624, 118628, 118632, 118636, + 118640, 118644, 118648, 118652, 118656, 118660, 118664, 118668, 118672, + 118676, 118680, 118684, 118688, 118692, 118696, 118700, 118704, 118708, + 118712, 118716, 118720, 118724, 118728, 118732, 118736, 118740, 118744, + 118748, 118752, 118756, 118760, 118764, 118768, 118772, 118776, 118780, + 118784, 118788, 118792, 118796, 118800, 118804, 118808, 118812, 118816, + 118820, 118824, 118828, 118832, 118836, 118840, 118844, 118848, 118852, + 118856, 118860, 118864, 118868, 118872, 118876, 118880, 118884, 118888, + 118892, 118896, 118900, 118904, 118908, 118912, 118916, 118920, 118924, + 118928, 118932, 118936, 118940, 118944, 118948, 118952, 118956, 118960, + 118964, 118968, 118972, 118976, 118980, 118984, 118988, 118992, 118996, + 119000, 119004, 119008, 119012, 119016, 119020, 119024, 119028, 119032, + 119036, 119040, 119044, 119048, 119052, 119056, 119060, 119064, 119068, + 119072, 119076, 119080, 119084, 119088, 119092, 119096, 119100, 119104, + 119108, 119112, 119116, 119120, 119124, 119128, 119132, 119136, 119140, + 119144, 119148, 119152, 119156, 119160, 119164, 119168, 119172, 119176, + 119180, 119184, 119188, 119192, 119196, 119200, 119204, 119208, 119212, + 119216, 119220, 119224, 119228, 119232, 119236, 119240, 119244, 119248, + 119252, 119256, 119260, 119264, 119268, 119272, 119276, 119280, 119284, + 119288, 119292, 119296, 119300, 119304, 119308, 119312, 119316, 119320, + 119324, 119328, 119332, 119336, 119340, 119344, 119348, 119352, 119356, + 119360, 119364, 119368, 119372, 119376, 119380, 119384, 119388, 119392, + 119396, 119400, 119404, 119408, 119412, 119416, 119420, 119424, 119428, + 119432, 119436, 119440, 119444, 119448, 119452, 119456, 119460, 119464, + 119468, 119472, 119476, 119480, 119484, 119488, 119492, 119496, 119500, + 119504, 119508, 119512, 119516, 119520, 119524, 119528, 119532, 119536, + 119540, 119544, 119548, 119552, 119556, 119560, 119564, 119568, 119572, + 119576, 119580, 119584, 119588, 119592, 119596, 119600, 119604, 119608, + 119612, 119616, 119620, 119624, 119628, 119632, 119636, 119640, 119644, + 119648, 119652, 119656, 119660, 119664, 119668, 119672, 119676, 119680, + 119684, 119688, 119692, 119696, 119700, 119704, 119708, 119712, 119716, + 119720, 119724, 119728, 119732, 119736, 119740, 119744, 119748, 119752, + 119756, 119760, 119764, 119768, 119772, 119776, 119780, 119784, 119788, + 119792, 119796, 119800, 119804, 119808, 119812, 119816, 119820, 119824, + 119828, 119832, 119836, 119840, 119844, 119848, 119852, 119856, 119860, + 119864, 119868, 119872, 119876, 119880, 119884, 119888, 119892, 119896, + 119900, 119904, 119908, 119912, 119916, 119920, 119924, 119928, 119932, + 119936, 119940, 119944, 119948, 119952, 119956, 119960, 119964, 119968, + 119972, 119976, 119980, 119984, 119988, 119992, 119996, 120000, 120004, + 120008, 120012, 120016, 120020, 120024, 120028, 120032, 120036, 120040, + 120044, 120048, 120052, 120056, 120060, 120064, 120068, 120072, 120076, + 120080, 120084, 120088, 120092, 120096, 120100, 120104, 120108, 120112, + 120116, 120120, 120124, 120128, 120132, 120136, 120140, 120144, 120148, + 120152, 120156, 120160, 120164, 120168, 120172, 120176, 120180, 120184, + 120188, 120192, 120196, 120200, 120204, 120208, 120212, 120216, 120220, + 120224, 120228, 120232, 120236, 120240, 120244, 120248, 120252, 120256, + 120260, 120264, 120268, 120272, 120276, 120280, 120284, 120288, 120292, + 120296, 120300, 120304, 120308, 120312, 120316, 120320, 120324, 120328, + 120332, 120336, 120340, 120344, 120348, 120352, 120356, 120360, 120364, + 120368, 120372, 120376, 120380, 120384, 120388, 120392, 120396, 120400, + 120404, 120408, 120412, 120416, 120420, 120424, 120428, 120432, 120436, + 120440, 120444, 120448, 120452, 120456, 120460, 120464, 120468, 120472, + 120476, 120480, 120484, 120488, 120492, 120496, 120500, 120504, 120508, + 120512, 120516, 120520, 120524, 120528, 120532, 120536, 120540, 120544, + 120548, 120552, 120556, 120560, 120564, 120568, 120572, 120576, 120580, + 120584, 120588, 120592, 120596, 120600, 120604, 120608, 120612, 120616, + 120620, 120624, 120628, 120632, 120636, 120640, 120644, 120648, 120652, + 120656, 120660, 120664, 120668, 120672, 120676, 120680, 120684, 120688, + 120692, 120696, 120700, 120704, 120708, 120712, 120716, 120720, 120724, + 120728, 120732, 120736, 120740, 120744, 120748, 120752, 120756, 120760, + 120764, 120768, 120772, 120776, 120780, 120784, 120788, 120792, 120796, + 120800, 120804, 120808, 120812, 120816, 120820, 120824, 120828, 120832, + 120836, 120840, 120844, 120848, 120852, 120856, 120860, 120864, 120868, + 120872, 120876, 120880, 120884, 120888, 120892, 120896, 120900, 120904, + 120908, 120912, 120916, 120920, 120924, 120928, 120932, 120936, 120940, + 120944, 120948, 120952, 120956, 120960, 120964, 120968, 120972, 120976, + 120980, 120984, 120988, 120992, 120996, 121000, 121004, 121008, 121012, + 121016, 121020, 121024, 121028, 121032, 121036, 121040, 121044, 121048, + 121052, 121056, 121060, 121064, 121068, 121072, 121076, 121080, 121084, + 121088, 121092, 121096, 121100, 121104, 121108, 121112, 121116, 121120, + 121124, 121128, 121132, 121136, 121140, 121144, 121148, 121152, 121156, + 121160, 121164, 121168, 121172, 121176, 121180, 121184, 121188, 121192, + 121196, 121200, 121204, 121208, 121212, 121216, 121220, 121224, 121228, + 121232, 121236, 121240, 121244, 121248, 121252, 121256, 121260, 121264, + 121268, 121272, 121276, 121280, 121284, 121288, 121292, 121296, 121300, + 121304, 121308, 121312, 121316, 121320, 121324, 121328, 121332, 121336, + 121340, 121344, 121348, 121352, 121356, 121360, 121364, 121368, 121372, + 121376, 121380, 121384, 121388, 121392, 121396, 121400, 121404, 121408, + 121412, 121416, 121420, 121424, 121428, 121432, 121436, 121440, 121444, + 121448, 121452, 121456, 121460, 121464, 121468, 121472, 121476, 121480, + 121484, 121488, 121492, 121496, 121500, 121504, 121508, 121512, 121516, + 121520, 121524, 121528, 121532, 121536, 121540, 121544, 121548, 121552, + 121556, 121560, 121564, 121568, 121572, 121576, 121580, 121584, 121588, + 121592, 121596, 121600, 121604, 121608, 121612, 121616, 121620, 121624, + 121628, 121632, 121636, 121640, 121644, 121648, 121652, 121656, 121660, + 121664, 121668, 121672, 121676, 121680, 121684, 121688, 121692, 121696, + 121700, 121704, 121708, 121712, 121716, 121720, 121724, 121728, 121732, + 121736, 121740, 121744, 121748, 121752, 121756, 121760, 121764, 121768, + 121772, 121776, 121780, 121784, 121788, 121792, 121796, 121800, 121804, + 121808, 121812, 121816, 121820, 121824, 121828, 121832, 121836, 121840, + 121844, 121848, 121852, 121856, 121860, 121864, 121868, 121872, 121876, + 121880, 121884, 121888, 121892, 121896, 121900, 121904, 121908, 121912, + 121916, 121920, 121924, 121928, 121932, 121936, 121940, 121944, 121948, + 121952, 121956, 121960, 121964, 121968, 121972, 121976, 121980, 121984, + 121988, 121992, 121996, 122000, 122004, 122008, 122012, 122016, 122020, + 122024, 122028, 122032, 122036, 122040, 122044, 122048, 122052, 122056, + 122060, 122064, 122068, 122072, 122076, 122080, 122084, 122088, 122092, + 122096, 122100, 122104, 122108, 122112, 122116, 122120, 122124, 122128, + 122132, 122136, 122140, 122144, 122148, 122152, 122156, 122160, 122164, + 122168, 122172, 122176, 122180, 122184, 122188, 122192, 122196, 122200, + 122204, 122208, 122212, 122216, 122220, 122224, 122228, 122232, 122236, + 122240, 122244, 122248, 122252, 122256, 122260, 122264, 122268, 122272, + 122276, 122280, 122284, 122288, 122292, 122296, 122300, 122304, 122308, + 122312, 122316, 122320, 122324, 122328, 122332, 122336, 122340, 122344, + 122348, 122352, 122356, 122360, 122364, 122368, 122372, 122376, 122380, + 122384, 122388, 122392, 122396, 122400, 122404, 122408, 122412, 122416, + 122420, 122424, 122428, 122432, 122436, 122440, 122444, 122448, 122452, + 122456, 122460, 122464, 122468, 122472, 122476, 122480, 122484, 122488, + 122492, 122496, 122500, 122504, 122508, 122512, 122516, 122520, 122524, + 122528, 122532, 122536, 122540, 122544, 122548, 122552, 122556, 122560, + 122564, 122568, 122572, 122576, 122580, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 122584, 122588, 122592, 122596, 122600, 122604, 122608, + 122612, 122616, 122620, 122624, 122628, 122632, 122636, 122640, 122644, + 122648, 122652, 122656, 122660, 122664, 122668, 122672, 122676, 122680, + 122684, 122688, 122692, 122696, 122700, 122704, 122708, 122712, 122716, + 122720, 122724, 122728, 122732, 122736, 122740, 122744, 122748, 122752, + 122756, 122760, 122764, 122768, 122772, 122776, 122780, 122784, 122788, + 122792, 122796, 122800, 122804, 122808, 122812, 122816, 122820, 122824, + 122828, 122832, 122836, 122840, 122844, 122848, 122852, 122856, 122860, + 122864, 122868, 122872, 122876, 122880, 122884, 122888, 122892, 122896, + 122900, 122904, 122908, 122912, 122916, 122920, 122924, 122928, 122932, + 122936, 122940, 122944, 122948, 122952, 122956, 122960, 122964, 122968, + 122972, 122976, 122980, 122984, 122988, 122992, 122996, 123000, 123004, + 123008, 123012, 123016, 123020, 123024, 123028, 123032, 123036, 123040, + 123044, 123048, 123052, 123056, 123060, 123064, 123068, 123072, 123076, + 123080, 123084, 123088, 123092, 123096, 123100, 123104, 123108, 123112, + 123116, 123120, 123124, 123128, 123132, 123136, 123140, 123144, 123148, + 123152, 123156, 123160, 123164, 123168, 123172, 123176, 123180, 123184, + 123188, 123192, 123196, 123200, 123204, 123208, 123212, 123216, 123220, + 123224, 123228, 123232, 123236, 123240, 123244, 123248, 123252, 123256, + 123260, 123264, 123268, 123272, 123276, 123280, 123284, 123288, 123292, + 123296, 123300, 123304, 123308, 123312, 123316, 123320, 123324, 123328, + 123332, 123336, 123340, 123344, 123348, 123352, 123356, 123360, 123364, + 123368, 123372, 123376, 123380, 123384, 123388, 123392, 123396, 123400, + 123404, 123408, 123412, 123416, 123420, 123424, 123428, 123432, 123436, + 123440, 123444, 123448, 123452, 123456, 123460, 123464, 123468, 123472, + 123476, 123480, 123484, 123488, 123492, 123496, 123500, 123504, 123508, + 123512, 123516, 123520, 123524, 123528, 123532, 123536, 123540, 123544, + 123548, 123552, 123556, 123560, 123564, 123568, 123572, 123576, 123580, + 123584, 123588, 123592, 123596, 123600, 123604, 123608, 123612, 123616, + 123620, 123624, 123628, 123632, 123636, 123640, 123644, 123648, 123652, + 123656, 123660, 123664, 123668, 123672, 123676, 123680, 123684, 123688, + 123692, 123696, 123700, 123704, 123708, 123712, 123716, 123720, 123724, + 123728, 123732, 123736, 123740, 123744, 123748, 123752, 123756, 123760, + 123764, 123768, 123772, 123776, 123780, 123784, 123788, 123792, 123796, + 123800, 123804, 123808, 123812, 123816, 123820, 123824, 123828, 123832, + 123836, 123840, 123844, 123848, 123852, 123856, 123860, 123864, 123868, + 123872, 123876, 123880, 123884, 123888, 123892, 123896, 123900, 123904, + 123908, 123912, 123916, 123920, 123924, 123928, 123932, 123936, 123940, + 123944, 123948, 123952, 123956, 123960, 123964, 123968, 123972, 123976, + 123980, 123984, 123988, 123992, 123996, 124000, 124004, 124008, 124012, + 124016, 124020, 124024, 124028, 124032, 124036, 124040, 124044, 124048, + 124052, 124056, 124060, 124064, 124068, 124072, 124076, 124080, 124084, + 124088, 124092, 124096, 124100, 124104, 124108, 124112, 124116, 124120, + 124124, 124128, 124132, 124136, 124140, 124144, 124148, 124152, 124156, + 124160, 124164, 124168, 124172, 124176, 124180, 124184, 124188, 124192, + 124196, 124200, 124204, 124208, 124212, 124216, 124220, 124224, 124228, + 124232, 124236, 124240, 124244, 124248, 124252, 124256, 124260, 124264, + 124268, 124272, 124276, 124280, 124284, 124288, 124292, 124296, 124300, + 124304, 124308, 124312, 124316, 124326, 124330, 124334, 124338, 124342, + 124346, 124350, 124354, 124358, 124362, 124366, 124370, 124375, 124379, + 124383, 124387, 124391, 124395, 124399, 124403, 124407, 124411, 124415, + 124419, 124423, 124427, 124431, 124435, 124439, 124448, 124457, 124461, + 124465, 124469, 124473, 124477, 124481, 124485, 124489, 124493, 124497, + 124501, 124505, 124509, 124513, 124517, 124521, 124525, 124529, 124533, + 124537, 124541, 124545, 124549, 124553, 124557, 124561, 124565, 124569, + 124573, 124577, 124581, 124585, 124589, 124593, 124597, 124601, 124605, + 124609, 124613, 124617, 124621, 124625, 124629, 124633, 124637, 124641, + 124645, 124649, 124653, 124657, 124661, 124665, 124669, 124673, 124677, + 124681, 124685, 124689, 124693, 124697, 124701, 124705, 124709, 124713, + 124717, 124721, 124725, 124729, 124733, 124737, 124741, 124745, 124749, + 124753, 124757, 124761, 124765, 124769, 124773, 124777, 124781, 124785, + 124789, 124793, 124797, 124801, 124805, 124809, 124813, 124817, 124821, + 124825, 124829, 124833, 124837, 124841, 124845, 124849, 124853, 124857, + 124861, 124865, 124869, 124873, 124877, 124881, 124885, 124889, 124893, + 124897, 124901, 124905, 124909, 124913, 124917, 124921, 124925, 124929, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124933, 124941, + 124949, 124959, 124969, 124977, 124983, 124991, 124999, 125009, 125021, + 125033, 125039, 125047, 125053, 125059, 125065, 125071, 125077, 125083, + 125089, 125095, 125101, 125107, 125113, 125121, 125129, 125135, 125141, + 125147, 125153, 125161, 125169, 125178, 125184, 125192, 125198, 125204, + 125210, 125216, 125222, 125230, 125238, 125244, 125250, 125256, 125262, + 125268, 125274, 125280, 125286, 125292, 125298, 125304, 125310, 125316, + 125322, 125328, 125334, 125340, 125346, 125352, 125360, 125366, 125372, + 125382, 125390, 125396, 125402, 125408, 125414, 125420, 125426, 125432, + 125438, 125444, 125450, 125456, 125462, 125468, 125474, 125480, 125486, + 125492, 125498, 125504, 125510, 125516, 125522, 125530, 125536, 125544, + 125552, 125560, 125566, 125572, 125578, 125584, 125590, 125598, 125608, + 125616, 125624, 125630, 125636, 125644, 125652, 125658, 125666, 125674, + 125682, 125688, 125694, 125700, 125706, 125712, 125718, 125726, 125734, + 125740, 125746, 125752, 125758, 125764, 125772, 125778, 125784, 125790, + 125796, 125802, 125808, 125816, 125822, 125828, 125834, 125840, 125848, + 125856, 125862, 125868, 125874, 125879, 125885, 125891, 125898, 125903, + 125908, 125913, 125918, 125923, 125928, 125933, 125938, 125943, 125952, + 125959, 125964, 125969, 125974, 125981, 125986, 125991, 125996, 126003, + 126008, 126013, 126018, 126023, 126028, 126033, 126038, 126043, 126048, + 126053, 126058, 126065, 126070, 126077, 126082, 126087, 126094, 126099, + 126104, 126109, 126114, 126119, 126124, 126129, 126134, 126139, 126144, + 126149, 126154, 126159, 126164, 126169, 126174, 126179, 126184, 126189, + 126196, 126201, 126206, 126211, 126216, 126221, 126226, 126231, 126236, + 126241, 126246, 126251, 126256, 126261, 126268, 126273, 126278, 126285, + 126290, 126295, 126300, 126305, 126310, 126315, 126320, 126325, 126330, + 126335, 126342, 126347, 126352, 126357, 126362, 126367, 126374, 126381, + 126386, 126391, 126396, 126401, 126406, 126411, 126416, 126421, 126426, + 126431, 126436, 126441, 126446, 126451, 126456, 126461, 126466, 126471, + 126476, 126481, 126486, 126491, 126496, 126501, 126506, 126511, 126516, + 126521, 126526, 126531, 126536, 126541, 126546, 126551, 126556, 126561, + 126568, 126573, 126578, 126583, 126588, 126593, 126598, 126603, 126608, + 126613, 126618, 126623, 126628, 126633, 126638, 126643, 126648, 126653, + 126658, 126663, 126668, 126673, 126678, 126683, 126688, 126693, 126698, + 126703, 126708, 126713, 126718, 126723, 126728, 126733, 126738, 126743, + 126748, 126753, 126758, 126763, 126768, 126773, 126778, 126783, 126788, + 126793, 126798, 126803, 126808, 126813, 126818, 126823, 126828, 126833, + 126838, 126843, 126848, 126853, 126858, 126865, 126870, 126875, 126880, + 126885, 126890, 126895, 126900, 126905, 126910, 126915, 126920, 126925, + 126930, 126935, 126940, 126945, 126950, 126955, 126960, 126965, 126970, + 126977, 126982, 126987, 126994, 126999, 127004, 127009, 127014, 127019, + 127024, 127029, 127034, 127039, 127044, 127049, 127054, 127059, 127064, + 127069, 127074, 127079, 127084, 127089, 127094, 127099, 127104, 127109, + 127114, 127119, 127124, 127129, 127134, 127139, 127144, 127149, 127154, + 127159, 127164, 127169, 127174, 127179, 127184, 127189, 127194, 127199, + 127204, 127209, 127216, 127221, 127226, 127233, 127240, 127245, 127250, + 127255, 127260, 127265, 127270, 127275, 127280, 127285, 127290, 127295, + 127300, 127305, 127310, 127315, 127320, 127325, 127330, 127335, 127340, + 127345, 127350, 127355, 127360, 127365, 127372, 127377, 127382, 127387, + 127392, 127397, 127402, 127407, 127412, 127417, 127422, 127427, 127432, + 127437, 127442, 127447, 127452, 127457, 127462, 127469, 127474, 127479, + 127484, 127489, 127494, 127499, 127504, 127510, 127515, 127520, 127525, + 127530, 127535, 127540, 127545, 127550, 127557, 127564, 127569, 127574, + 127578, 127583, 127587, 127591, 127596, 127603, 127608, 127613, 127622, + 127627, 127632, 127637, 127642, 127649, 127656, 127661, 127666, 127671, + 127676, 127683, 127688, 127693, 127698, 127703, 127708, 127713, 127718, + 127723, 127728, 127733, 127738, 127743, 127750, 127755, 127760, 127765, + 127770, 127775, 127779, 127784, 127789, 127794, 127799, 127804, 127809, + 127814, 127819, 127824, 127830, 127836, 127842, 127848, 127854, 127860, + 127866, 127872, 127878, 127884, 127890, 127896, 127902, 127908, 127914, + 127920, 127926, 127932, 127938, 127944, 127950, 127956, 127962, 127968, + 127973, 127979, 127985, 127991, 127997, 128003, 128009, 128015, 128021, + 128027, 128033, 128039, 128045, 128051, 128057, 128063, 128069, 128075, + 128081, 128087, 128093, 128098, 128104, 128110, 128116, 128122, 128128, + 0, 0, 0, 0, 0, 0, 0, 128134, 128139, 128144, 128149, 128154, 128159, + 128164, 128168, 128173, 128178, 128183, 128188, 128193, 128198, 128203, + 128208, 128213, 128217, 128222, 128226, 128231, 128236, 128241, 128246, + 128251, 128255, 128260, 128265, 128270, 128275, 128280, 0, 128285, + 128290, 128294, 128298, 128302, 128306, 128310, 128314, 128319, 128323, + 0, 0, 0, 0, 128328, 128332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 128337, 128344, 128350, 128357, 128364, + 128371, 128378, 128385, 128392, 128399, 128406, 128413, 128420, 128427, + 128434, 128441, 128448, 128455, 128461, 128468, 128475, 128482, 128488, + 128495, 128501, 128507, 128514, 128520, 128527, 128533, 0, 0, 128539, + 128547, 128555, 128564, 128573, 128582, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 128590, 128595, 128600, 128605, 128610, 128615, 128620, 128625, 128630, + 128635, 128640, 128645, 128650, 128655, 128660, 128665, 128670, 128675, + 128680, 128685, 128690, 128695, 128700, 128705, 128710, 128715, 128720, + 128725, 128730, 128735, 128740, 128745, 128750, 128755, 128760, 128765, + 128770, 128775, 128780, 128785, 128790, 128795, 128800, 128805, 128810, + 128815, 128820, 128825, 128830, 128837, 128844, 128851, 128858, 128865, + 128872, 128879, 128886, 128895, 128902, 128909, 128916, 128923, 128930, + 128937, 128944, 128951, 128958, 128965, 128972, 128977, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 128986, 128991, 128995, 128999, 129003, 129007, 129011, + 129015, 129020, 129024, 0, 129029, 129034, 129039, 129046, 129051, + 129058, 129065, 0, 129070, 129077, 129082, 129087, 129094, 129101, + 129106, 129111, 129116, 129121, 129126, 129133, 129140, 129145, 129150, + 129155, 129168, 129177, 129184, 129193, 129202, 0, 0, 0, 0, 0, 129211, + 129218, 129225, 129232, 129239, 129246, 129253, 129260, 129267, 129274, + 129281, 129288, 129295, 129302, 129309, 129316, 129323, 129330, 129337, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129344, 129347, 129351, + 129355, 129359, 129362, 129366, 129371, 129375, 129379, 129383, 129387, + 129391, 129396, 129401, 129405, 129409, 129413, 129417, 129422, 129428, + 129432, 129436, 129440, 129444, 129448, 129452, 129456, 129460, 129464, + 129468, 129471, 129475, 129479, 129483, 129487, 129491, 129495, 129501, + 129504, 129508, 129512, 129516, 129520, 129524, 129528, 129532, 129536, + 129540, 129545, 129550, 129556, 129560, 129564, 129568, 129572, 129576, + 129580, 129585, 129589, 129593, 129597, 129601, 129605, 129611, 129615, + 129619, 129623, 129627, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129631, 129635, + 129639, 129645, 129651, 129655, 129660, 129665, 129670, 129675, 129679, + 129684, 129689, 129694, 129698, 129703, 129708, 129713, 129717, 129722, + 129727, 129732, 129737, 129742, 129747, 129752, 129757, 129761, 129766, + 129771, 129776, 129781, 129786, 129791, 129796, 129801, 129806, 129811, + 129816, 129823, 129828, 129835, 129840, 129845, 129850, 129855, 129860, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129865, 129869, 129875, + 129878, 129881, 129885, 129889, 129893, 129897, 129901, 129905, 129909, + 129915, 129921, 129927, 129933, 129939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129945, 129950, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 129956, 129960, 129964, 129968, 129972, 129976, + 129980, 129983, 129987, 129991, 129995, 129999, 130002, 130008, 130013, + 130019, 130025, 130030, 130034, 130040, 130044, 130048, 130054, 130058, + 130062, 130066, 130070, 130074, 130078, 130081, 130087, 130093, 130099, + 130105, 130112, 130119, 130126, 130136, 130143, 130150, 130155, 130160, + 130165, 130170, 130177, 130184, 130191, 130198, 130207, 130213, 130220, + 130226, 130233, 130239, 130246, 130251, 130258, 130262, 130266, 130271, + 130277, 130283, 130290, 130297, 130303, 130310, 130313, 130319, 130323, + 130326, 130330, 130333, 130336, 130340, 130345, 130349, 130353, 130359, + 130364, 130370, 130374, 130378, 130381, 130385, 130389, 130394, 130398, + 130403, 130407, 130412, 130416, 130420, 130424, 130428, 130432, 130436, + 130440, 130444, 130449, 130454, 130459, 130464, 130470, 130476, 130482, + 130488, 130494, 0, 0, 0, 0, 0, 130499, 130507, 130516, 130524, 130531, + 130539, 130546, 130553, 130562, 130569, 130576, 130583, 130591, 0, 0, 0, + 130599, 130604, 130611, 130617, 130624, 130630, 130636, 130642, 130648, + 0, 0, 0, 0, 0, 0, 0, 130654, 130659, 130666, 130672, 130679, 130685, + 130691, 130697, 130703, 130709, 0, 0, 130714, 130720, 130726, 130729, + 130738, 130745, 130753, 130760, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 130767, 130772, 130777, 130782, 130789, 130796, 130803, + 130810, 130815, 130820, 130825, 130830, 130837, 130842, 130849, 130856, + 130861, 130866, 130871, 130878, 130883, 130888, 130895, 130902, 130907, + 130912, 130917, 130924, 130931, 130938, 130943, 130948, 130955, 130962, + 130969, 130976, 130981, 130986, 130991, 130998, 131003, 131008, 131013, + 131020, 131029, 131036, 131041, 131046, 131051, 131056, 131061, 131066, + 131075, 131082, 131087, 131094, 131101, 131106, 131111, 131116, 131123, + 131128, 131135, 131142, 131147, 131152, 131157, 131164, 131171, 131176, + 131181, 131188, 131195, 131202, 131207, 131212, 131217, 131222, 131229, + 131238, 131247, 131252, 131259, 131268, 131273, 131278, 131283, 131288, + 131295, 131302, 131309, 131316, 131321, 131326, 131331, 131338, 131345, + 131352, 131357, 131362, 131369, 131374, 131381, 131386, 131393, 131398, + 131405, 131412, 131417, 131422, 131427, 131432, 131437, 131442, 131447, + 131452, 131457, 131464, 131471, 131478, 131485, 131492, 131501, 131506, + 131511, 131518, 131525, 131530, 131537, 131544, 131551, 131558, 131565, + 131572, 131577, 131582, 131587, 131592, 131597, 131606, 131615, 131624, + 131633, 131642, 131651, 131660, 131669, 131674, 131685, 131696, 131705, + 131710, 131715, 131720, 131725, 131734, 131741, 131748, 131755, 131762, + 131769, 131776, 131785, 131794, 131805, 131814, 131825, 131834, 131841, + 131850, 131861, 131870, 131879, 131888, 131897, 131904, 131911, 131918, + 131927, 131936, 131947, 131956, 131965, 131976, 131981, 131986, 131997, + 132005, 132014, 132023, 132032, 132043, 132052, 132061, 132072, 132083, + 132094, 132105, 132116, 132127, 132134, 132141, 132148, 132155, 132166, + 132175, 132182, 132189, 132196, 132207, 132218, 132229, 132240, 132251, + 132262, 132273, 132284, 132291, 132298, 132307, 132316, 132323, 132330, + 132337, 132346, 132355, 132364, 132371, 132380, 132389, 132398, 132405, + 132412, 132417, 132423, 132430, 132437, 132444, 132451, 132458, 132465, + 132474, 132483, 132492, 132501, 132508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 132517, 132523, 132528, 132533, 132540, 132546, 132552, 132558, 132564, + 132570, 132576, 132582, 132586, 132590, 132596, 132602, 132608, 132612, + 132617, 132622, 132626, 132630, 132633, 132639, 132645, 132651, 132657, + 132663, 132669, 132675, 132681, 132687, 132697, 132707, 132713, 132719, + 132729, 132739, 132745, 0, 0, 132751, 132759, 132764, 132769, 132775, + 132781, 132787, 132793, 132799, 132805, 132812, 132819, 132825, 132831, + 132837, 132843, 132849, 132855, 132861, 132867, 132872, 132878, 132884, + 132890, 132896, 132902, 132911, 132917, 132922, 132930, 132937, 132944, + 132953, 132962, 132971, 132980, 132989, 132998, 133007, 133016, 133026, + 133036, 133044, 133052, 133061, 133070, 133076, 133082, 133088, 133094, + 133102, 133110, 133114, 133120, 133125, 133131, 133137, 133143, 133149, + 133155, 133164, 133169, 133176, 133181, 133186, 133191, 133197, 133203, + 133209, 133216, 133221, 133226, 133231, 133236, 133241, 133247, 133253, + 133259, 133265, 133271, 133277, 133283, 133289, 133294, 133299, 133304, + 133309, 133314, 133319, 133324, 133329, 133335, 133341, 133346, 133351, + 133356, 133361, 133366, 133372, 133379, 133383, 133387, 133391, 133395, + 133399, 133403, 133407, 133411, 133419, 133429, 133433, 133437, 133443, + 133449, 133455, 133461, 133467, 133473, 133479, 133485, 133491, 133497, + 133503, 133509, 133515, 133521, 133525, 133529, 133536, 133542, 133548, + 133554, 133559, 133566, 133571, 133577, 133583, 133589, 133595, 133600, + 133604, 133610, 133614, 133618, 133622, 133628, 133634, 133638, 133644, + 133650, 133656, 133662, 133668, 133676, 133684, 133690, 133696, 133702, + 133708, 133720, 133732, 133746, 133758, 133770, 133784, 133798, 133812, + 133816, 133824, 133832, 133837, 133841, 133845, 133849, 133853, 133857, + 133861, 133865, 133871, 133877, 133883, 133889, 133897, 133906, 133913, + 133920, 133928, 133935, 133947, 133959, 133971, 133983, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133990, 133997, + 134004, 134011, 134018, 134025, 134032, 134039, 134046, 134053, 134060, + 134067, 134074, 134081, 134088, 134095, 134102, 134109, 134116, 134123, + 134130, 134137, 134144, 134151, 134158, 134165, 134172, 134179, 134186, + 134193, 134200, 134207, 134214, 134221, 134228, 134235, 134242, 134249, + 134256, 134263, 134270, 134277, 134284, 134291, 134298, 134305, 134312, + 134319, 134326, 134333, 134340, 134347, 134354, 134361, 134368, 134375, + 134382, 134389, 134396, 134403, 134410, 134417, 134424, 134431, 134438, + 134445, 134452, 134457, 134462, 134467, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 134471, 134476, 134483, 134490, 134497, 134504, + 134509, 134514, 134521, 134526, 134531, 134538, 134543, 134548, 134553, + 134560, 134569, 134574, 134579, 134584, 134589, 134594, 134599, 134606, + 134611, 134616, 134621, 134626, 134631, 134636, 134641, 134646, 134651, + 134656, 134661, 134666, 134672, 134677, 134682, 134687, 134692, 134697, + 134702, 134707, 134712, 134717, 134726, 134731, 134740, 134745, 134750, + 134755, 134760, 134765, 134770, 134775, 134784, 134789, 134794, 134799, + 134804, 134809, 134816, 134821, 134828, 134833, 134838, 134843, 134848, + 134853, 134858, 134863, 134868, 134873, 134878, 134883, 134888, 134893, + 134898, 134903, 134908, 134913, 134918, 134923, 134932, 134937, 134942, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 134947, 134955, 134963, 134971, 134979, + 134987, 134995, 135004, 135012, 135021, 135029, 135037, 135045, 135053, + 135061, 135069, 135078, 135086, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 135095, 135099, 135104, 135109, 135114, 135118, + 135123, 135128, 135133, 135137, 135142, 135147, 135151, 135156, 135161, + 135165, 135170, 135175, 135179, 135183, 135188, 135192, 135197, 135202, + 135207, 135212, 135217, 135221, 135226, 135231, 135236, 135240, 135245, + 135250, 135255, 135259, 135264, 135269, 135273, 135278, 135283, 135287, + 135292, 135297, 135301, 135305, 135310, 135314, 135319, 135324, 135329, + 135334, 135339, 135343, 135348, 135353, 135358, 135362, 135367, 135372, + 135377, 135381, 135386, 135391, 135395, 135400, 135405, 135409, 135414, + 135419, 135423, 135427, 135432, 135436, 135441, 135446, 135451, 135456, + 135461, 135465, 135470, 135475, 135480, 135484, 135489, 0, 135494, + 135498, 135503, 135508, 135512, 135517, 135522, 135526, 135531, 135536, + 135540, 135544, 135549, 135553, 135558, 135563, 135568, 135573, 135578, + 135583, 135589, 135595, 135601, 135606, 135612, 135618, 135624, 135629, + 135635, 135641, 135646, 135652, 135658, 135663, 135669, 135675, 135680, + 135685, 135691, 135696, 135702, 135708, 135714, 135720, 135726, 135731, + 135737, 135743, 135749, 135754, 135760, 135766, 135772, 135777, 135783, + 135789, 135794, 135800, 135806, 135811, 135817, 135823, 135828, 135833, + 135839, 135844, 135850, 135856, 135862, 135868, 135874, 0, 135878, + 135883, 0, 0, 135888, 0, 0, 135893, 135898, 0, 0, 135903, 135908, 135912, + 135917, 0, 135922, 135926, 135931, 135935, 135940, 135945, 135950, + 135955, 135960, 135964, 135969, 135974, 0, 135979, 0, 135984, 135989, + 135993, 135998, 136003, 136007, 136012, 0, 136017, 136022, 136027, + 136031, 136035, 136040, 136044, 136049, 136054, 136059, 136064, 136069, + 136074, 136080, 136086, 136092, 136097, 136103, 136109, 136115, 136120, + 136126, 136132, 136137, 136143, 136149, 136154, 136160, 136166, 136171, + 136176, 136182, 136187, 136193, 136199, 136205, 136211, 136217, 136222, + 136228, 136234, 136240, 136245, 136251, 136257, 136263, 136268, 136274, + 136280, 136285, 136291, 136297, 136302, 136308, 136314, 136319, 136324, + 136330, 136335, 136341, 136347, 136353, 136359, 136365, 136369, 0, + 136374, 136379, 136383, 136388, 0, 0, 136393, 136398, 136403, 136407, + 136412, 136417, 136421, 136426, 0, 136431, 136435, 136440, 136444, + 136449, 136454, 136459, 0, 136464, 136468, 136473, 136478, 136483, + 136487, 136492, 136497, 136502, 136506, 136511, 136516, 136520, 136525, + 136530, 136534, 136539, 136544, 136548, 136552, 136557, 136561, 136566, + 136571, 136576, 136581, 136586, 136590, 0, 136595, 136600, 136604, + 136609, 0, 136614, 136618, 136623, 136628, 136632, 0, 136637, 0, 0, 0, + 136641, 136645, 136650, 136654, 136659, 136664, 136669, 0, 136674, + 136678, 136683, 136688, 136693, 136697, 136702, 136707, 136712, 136716, + 136721, 136726, 136730, 136735, 136740, 136744, 136749, 136754, 136758, + 136762, 136767, 136771, 136776, 136781, 136786, 136791, 136796, 136801, + 136807, 136813, 136819, 136824, 136830, 136836, 136842, 136847, 136853, + 136859, 136864, 136870, 136876, 136881, 136887, 136893, 136898, 136903, + 136909, 136914, 136920, 136926, 136932, 136938, 136944, 136949, 136955, + 136961, 136967, 136972, 136978, 136984, 136990, 136995, 137001, 137007, + 137012, 137018, 137024, 137029, 137035, 137041, 137046, 137051, 137057, + 137062, 137068, 137074, 137080, 137086, 137092, 137096, 137101, 137106, + 137111, 137115, 137120, 137125, 137130, 137134, 137139, 137144, 137148, + 137153, 137158, 137162, 137167, 137172, 137176, 137180, 137185, 137189, + 137194, 137199, 137204, 137209, 137214, 137218, 137223, 137228, 137233, + 137237, 137242, 137247, 137252, 137256, 137261, 137266, 137270, 137275, + 137280, 137284, 137289, 137294, 137298, 137302, 137307, 137311, 137316, + 137321, 137326, 137331, 137336, 137341, 137347, 137353, 137359, 137364, + 137370, 137376, 137382, 137387, 137393, 137399, 137404, 137410, 137416, + 137421, 137427, 137433, 137438, 137443, 137449, 137454, 137460, 137466, + 137472, 137478, 137484, 137489, 137495, 137501, 137507, 137512, 137518, + 137524, 137530, 137535, 137541, 137547, 137552, 137558, 137564, 137569, + 137575, 137581, 137586, 137591, 137597, 137602, 137608, 137614, 137620, + 137626, 137632, 137637, 137643, 137649, 137655, 137660, 137666, 137672, + 137678, 137683, 137689, 137695, 137700, 137706, 137712, 137717, 137723, + 137729, 137734, 137739, 137745, 137750, 137756, 137762, 137768, 137774, + 137780, 137785, 137791, 137797, 137803, 137808, 137814, 137820, 137826, + 137831, 137837, 137843, 137848, 137854, 137860, 137865, 137871, 137877, + 137882, 137887, 137893, 137898, 137904, 137910, 137916, 137922, 137928, + 137934, 137941, 137948, 137955, 137961, 137968, 137975, 137982, 137988, + 137995, 138002, 138008, 138015, 138022, 138028, 138035, 138042, 138048, + 138054, 138061, 138067, 138074, 138081, 138088, 138095, 138102, 138108, + 138115, 138122, 138129, 138135, 138142, 138149, 138156, 138162, 138169, + 138176, 138182, 138189, 138196, 138202, 138209, 138216, 138222, 138228, + 138235, 138241, 138248, 138255, 138262, 138269, 138276, 138281, 138287, + 138293, 138299, 138304, 138310, 138316, 138322, 138327, 138333, 138339, + 138344, 138350, 138356, 138361, 138367, 138373, 138378, 138383, 138389, + 138394, 138400, 138406, 138412, 138418, 138424, 138429, 138435, 138441, + 138447, 138452, 138458, 138464, 138470, 138475, 138481, 138487, 138492, + 138498, 138504, 138509, 138515, 138521, 138526, 138531, 138537, 138542, + 138548, 138554, 138560, 138566, 138572, 138578, 0, 0, 138585, 138590, + 138595, 138600, 138605, 138610, 138615, 138620, 138625, 138630, 138635, + 138640, 138645, 138650, 138655, 138660, 138665, 138670, 138676, 138681, + 138686, 138691, 138696, 138701, 138706, 138711, 138715, 138720, 138725, + 138730, 138735, 138740, 138745, 138750, 138755, 138760, 138765, 138770, + 138775, 138780, 138785, 138790, 138795, 138800, 138806, 138811, 138816, + 138821, 138826, 138831, 138836, 138841, 138847, 138852, 138857, 138862, + 138867, 138872, 138877, 138882, 138887, 138892, 138897, 138902, 138907, + 138912, 138917, 138922, 138927, 138932, 138937, 138942, 138947, 138952, + 138957, 138962, 138968, 138973, 138978, 138983, 138988, 138993, 138998, + 139003, 139007, 139012, 139017, 139022, 139027, 139032, 139037, 139042, + 139047, 139052, 139057, 139062, 139067, 139072, 139077, 139082, 139087, + 139092, 139098, 139103, 139108, 139113, 139118, 139123, 139128, 139133, + 139139, 139144, 139149, 139154, 139159, 139164, 139169, 139175, 139181, + 139187, 139193, 139199, 139205, 139211, 139217, 139223, 139229, 139235, + 139241, 139247, 139253, 139259, 139265, 139271, 139278, 139284, 139290, + 139296, 139302, 139308, 139314, 139320, 139325, 139331, 139337, 139343, + 139349, 139355, 139361, 139367, 139373, 139379, 139385, 139391, 139397, + 139403, 139409, 139415, 139421, 139427, 139434, 139440, 139446, 139452, + 139458, 139464, 139470, 139476, 139483, 139489, 139495, 139501, 139507, + 139513, 139519, 139525, 139531, 139537, 139543, 139549, 139555, 139561, + 139567, 139573, 139579, 139585, 139591, 139597, 139603, 139609, 139615, + 139621, 139628, 139634, 139640, 139646, 139652, 139658, 139664, 139670, + 139675, 139681, 139687, 139693, 139699, 139705, 139711, 139717, 139723, + 139729, 139735, 139741, 139747, 139753, 139759, 139765, 139771, 139777, + 139784, 139790, 139796, 139802, 139808, 139814, 139820, 139826, 139833, + 139839, 139845, 139851, 139857, 139863, 139869, 139876, 139883, 139890, + 139897, 139904, 139911, 139918, 139925, 139932, 139939, 139946, 139953, + 139960, 139967, 139974, 139981, 139988, 139996, 140003, 140010, 140017, + 140024, 140031, 140038, 140045, 140051, 140058, 140065, 140072, 140079, + 140086, 140093, 140100, 140107, 140114, 140121, 140128, 140135, 140142, + 140149, 140156, 140163, 140170, 140178, 140185, 140192, 140199, 140206, + 140213, 140220, 140227, 140235, 140242, 140249, 140256, 140263, 140270, + 140277, 140282, 0, 0, 140287, 140292, 140296, 140300, 140304, 140308, + 140312, 140316, 140321, 140325, 140330, 140335, 140339, 140343, 140347, + 140351, 140355, 140359, 140364, 140368, 140373, 140378, 140382, 140386, + 140390, 140394, 140398, 140402, 140407, 140411, 140416, 140422, 140427, + 140432, 140437, 140442, 140447, 140452, 140458, 140463, 140469, 140475, + 140480, 140485, 140490, 140495, 140500, 140505, 140511, 140516, 140522, + 140526, 140531, 140536, 140541, 140546, 140551, 140556, 140562, 140570, + 140577, 140582, 140587, 140594, 140600, 140605, 140611, 140617, 140625, + 140631, 140638, 140646, 140652, 140661, 140670, 140678, 140686, 140692, + 140699, 140707, 140715, 140721, 140728, 140737, 140746, 140753, 140764, + 140774, 140784, 140794, 140804, 140811, 140818, 140825, 140832, 140841, + 140850, 140861, 140872, 140881, 140890, 140901, 140910, 140919, 140930, + 140939, 140948, 140956, 140964, 140975, 140986, 140994, 141003, 141012, + 141019, 141030, 141041, 141050, 141059, 141066, 141075, 141084, 141093, + 141104, 141113, 141123, 141132, 141141, 141152, 141165, 141180, 141191, + 141204, 141216, 141225, 141236, 141247, 141256, 141267, 141281, 141296, + 141299, 141308, 141313, 141319, 141327, 141333, 141339, 141348, 141355, + 141365, 141377, 141384, 141387, 141393, 141400, 141406, 141411, 141414, + 141419, 141422, 141429, 141435, 141443, 141450, 141457, 141463, 141468, + 141471, 141474, 141477, 141483, 141490, 141496, 141501, 141508, 141511, + 141516, 141523, 141529, 141537, 141544, 141554, 141563, 141566, 141572, + 141579, 141586, 141593, 141598, 141606, 141614, 141623, 141629, 141638, + 141647, 141656, 141662, 141671, 141678, 141685, 141692, 141700, 141706, + 141714, 141720, 141727, 141734, 141742, 141753, 141763, 141769, 141776, + 141783, 141790, 141796, 141803, 141810, 141815, 141822, 141830, 141839, + 141845, 141857, 141868, 141874, 141882, 141888, 141895, 141902, 141909, + 141915, 141922, 141931, 141937, 141943, 141950, 141957, 141965, 141975, + 141985, 141995, 142005, 142013, 142021, 142031, 142039, 142044, 142049, + 142054, 142060, 142067, 142074, 142080, 142086, 142091, 142098, 142106, + 142116, 142124, 142132, 142142, 142152, 142160, 142170, 142180, 142192, + 142204, 142216, 142226, 142232, 142238, 142245, 142254, 142263, 142272, + 142281, 142291, 142300, 142309, 142318, 142323, 142329, 142338, 142348, + 142357, 142363, 142369, 142376, 142383, 142390, 142396, 142403, 142410, + 142417, 142423, 142427, 142432, 142439, 142446, 142453, 142458, 142466, + 142474, 142483, 142491, 142498, 142506, 142515, 142525, 142528, 142532, + 142537, 142542, 142547, 142552, 142557, 142562, 142567, 142572, 142577, + 142582, 142587, 142592, 142597, 142602, 142607, 142612, 142617, 142624, + 142630, 142637, 142643, 142648, 142655, 142661, 142668, 142674, 142679, + 142686, 142693, 142700, 142706, 142712, 142721, 142730, 142741, 142748, + 142755, 142764, 142773, 142782, 142791, 142800, 142806, 142814, 142820, + 142830, 142835, 142844, 142853, 142860, 142871, 142878, 142885, 142892, + 142899, 142906, 142913, 142920, 142927, 142934, 142941, 142947, 142953, + 142959, 142966, 142973, 142980, 142987, 142994, 143001, 143008, 143015, + 143022, 143029, 143036, 143043, 143048, 143057, 143066, 143075, 143082, + 143089, 143096, 143103, 143110, 143117, 143124, 143131, 143140, 143149, + 143158, 143167, 143176, 143185, 143194, 143203, 143212, 143221, 143230, + 143239, 143248, 143254, 143262, 143268, 143278, 143283, 143292, 143301, + 143310, 143321, 143326, 143333, 143340, 143347, 143352, 143358, 143364, + 143370, 143377, 143384, 143391, 143398, 143405, 143412, 143419, 143426, + 143433, 143440, 143447, 143454, 143459, 143468, 143477, 143486, 143495, + 143504, 143513, 143522, 143531, 143542, 143553, 143560, 143567, 143574, + 143581, 143588, 143595, 143603, 143613, 143623, 143633, 143644, 143655, + 143666, 143675, 143684, 143693, 143698, 143703, 143708, 143713, 143724, + 143735, 143746, 143757, 143768, 143778, 143789, 143798, 143807, 143816, + 143825, 143834, 143842, 143851, 143862, 143873, 143884, 143895, 143906, + 143918, 143931, 143943, 143956, 143968, 143981, 143993, 144006, 144017, + 144028, 144037, 144045, 144054, 144065, 144076, 144088, 144101, 144115, + 144130, 144142, 144155, 144167, 144180, 144191, 144202, 144211, 144219, + 144228, 144235, 144242, 144249, 144256, 144263, 144270, 144277, 144284, + 144291, 144298, 144303, 144308, 144313, 144320, 144330, 144341, 144351, + 144362, 144376, 144391, 144406, 144420, 144435, 144450, 144461, 144472, + 144485, 144498, 144507, 144516, 144529, 144542, 144549, 144556, 144561, + 144566, 144571, 144576, 144581, 144588, 144597, 144602, 144605, 144610, + 144617, 144624, 144631, 144638, 144645, 144652, 144665, 144679, 144694, + 144701, 144708, 144715, 144724, 144732, 144740, 144749, 144754, 144759, + 144764, 144769, 144774, 144779, 144786, 144793, 144799, 144806, 144812, + 144819, 144824, 144829, 144834, 144839, 144844, 144851, 144858, 144863, + 144870, 144877, 144882, 144887, 144892, 144897, 144902, 144907, 144914, + 144921, 144928, 144931, 144936, 144941, 144946, 144951, 144958, 144965, + 144973, 144981, 144986, 144991, 144998, 145005, 145012, 145017, 145024, + 145031, 145036, 145043, 145050, 145056, 145062, 145068, 145074, 145082, + 145090, 145096, 145104, 145112, 145117, 145124, 145131, 145136, 145143, + 145150, 145157, 145165, 145173, 145178, 145185, 145192, 145201, 145208, + 145217, 145228, 145237, 145246, 145255, 145264, 145267, 145272, 145279, + 145288, 145295, 145304, 145311, 145316, 145321, 145324, 145327, 145330, + 145337, 145344, 145353, 145362, 145371, 145378, 145385, 145390, 145403, + 145408, 145413, 145418, 145423, 145428, 145433, 145438, 145443, 145446, + 145451, 145456, 145461, 145466, 145471, 145478, 145483, 145490, 145493, + 145498, 145501, 145504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 145507, 145512, 145517, 145522, 145527, 0, 145532, 145537, 145542, + 145547, 145552, 145557, 145562, 145567, 145572, 145577, 145582, 145587, + 145592, 145597, 145602, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93989, 93993, - 93997, 94001, 94005, 94009, 94013, 94017, 94021, 94025, 94030, 94035, - 94040, 94045, 94050, 94055, 94060, 94065, 94070, 94076, 94082, 94088, - 94095, 94102, 94109, 94116, 94123, 94130, 94137, 94144, 94151, 0, 94158, - 94162, 94166, 94170, 94174, 94178, 94181, 94185, 94188, 94192, 94195, - 94199, 94203, 94208, 94212, 94217, 94220, 94224, 94227, 94231, 94234, - 94238, 94242, 94246, 94250, 94254, 94258, 94262, 94266, 94270, 94274, - 94278, 94282, 94286, 94290, 94294, 94298, 94302, 94306, 94309, 94312, - 94316, 94320, 94324, 94327, 94330, 94333, 94337, 94341, 94345, 94349, - 94352, 94355, 94359, 94365, 94371, 94377, 94382, 94389, 94393, 94398, - 94402, 94407, 94412, 94418, 94423, 94429, 94433, 94438, 94442, 94447, - 94450, 94453, 94457, 94462, 94468, 94473, 94479, 0, 0, 0, 0, 94484, - 94487, 94490, 94493, 94496, 94499, 94502, 94505, 94508, 94511, 94515, - 94519, 94523, 94527, 94531, 94535, 94539, 94543, 94547, 94552, 94557, - 94561, 94564, 94567, 94570, 94573, 94576, 94579, 94582, 94585, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94588, 94593, 94598, 94603, 94607, - 94612, 94616, 94621, 94625, 94630, 94634, 94639, 94643, 94648, 94652, - 94657, 94662, 94667, 94672, 94677, 94682, 94687, 94692, 94697, 94702, - 94707, 94712, 94717, 94722, 94727, 94732, 94737, 94742, 94747, 94752, - 94756, 94760, 94765, 94770, 94775, 94779, 94783, 94787, 94792, 94797, - 94802, 94807, 94811, 94815, 94821, 94826, 94832, 94837, 94843, 94848, - 94854, 94859, 94865, 94870, 94875, 94880, 94885, 94889, 94894, 94900, - 94904, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94909, 94916, 94923, - 94930, 94937, 94944, 94951, 94958, 94965, 94972, 94979, 94986, 94993, - 95000, 95007, 95014, 95021, 95028, 95035, 95042, 95049, 95056, 95063, - 95070, 95077, 0, 0, 0, 0, 0, 0, 0, 95084, 95091, 95097, 95103, 95109, - 95115, 95121, 95127, 95133, 95139, 0, 0, 0, 0, 0, 0, 95145, 95150, 95155, - 95160, 95165, 95169, 95173, 95177, 95182, 95187, 95192, 95197, 95202, - 95207, 95212, 95217, 95222, 95227, 95232, 95237, 95242, 95247, 95252, - 95257, 95262, 95267, 95272, 95277, 95282, 95287, 95292, 95297, 95302, - 95307, 95312, 95317, 95322, 95327, 95332, 95337, 95342, 95347, 95353, - 95358, 95364, 95369, 95375, 95380, 95386, 95392, 95396, 95401, 95405, 0, - 95409, 95414, 95418, 95422, 95426, 95430, 95434, 95438, 95442, 95446, - 95450, 95455, 95459, 95464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95469, - 95473, 95477, 95481, 95484, 95488, 95491, 95495, 95498, 95502, 95506, - 95511, 95515, 95520, 95523, 95527, 95530, 95534, 95537, 95541, 95545, - 95549, 95553, 95557, 95561, 95565, 95569, 95573, 95577, 95581, 95585, - 95589, 95593, 95597, 95601, 95605, 95609, 95612, 95615, 95619, 95623, - 95627, 95630, 95633, 95636, 95640, 95644, 95648, 95652, 95656, 95659, - 95662, 95667, 95671, 95676, 95680, 95685, 95690, 95696, 95701, 95707, - 95711, 95716, 95720, 95725, 95729, 95733, 95737, 95741, 95744, 95747, - 95751, 95755, 0, 0, 0, 0, 0, 0, 0, 95758, 95762, 95765, 95768, 95771, - 95774, 95777, 95780, 95783, 95786, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145607, 145614, 145620, + 145627, 145634, 145641, 145648, 145655, 145662, 145669, 145676, 145683, + 145690, 145697, 145704, 145711, 145718, 145725, 145732, 145739, 145746, + 145753, 145760, 145767, 145774, 145781, 145788, 145795, 145802, 145809, + 145816, 145823, 145830, 145837, 145844, 145850, 145856, 145862, 145869, + 145875, 145882, 145888, 145895, 145902, 145909, 145916, 145923, 145930, + 145937, 145944, 145951, 145958, 145965, 145972, 145979, 145986, 145993, + 146000, 146007, 146014, 146021, 146028, 146036, 146043, 146050, 146057, + 146064, 146071, 146078, 146085, 146092, 146099, 146106, 146113, 146120, + 146126, 146133, 146140, 146147, 146154, 146161, 146168, 146175, 146183, + 146190, 146196, 146203, 146210, 146217, 146224, 146231, 146238, 146245, + 146252, 146259, 146266, 146273, 146280, 146287, 146294, 146301, 146308, + 146315, 146322, 146329, 146336, 146342, 146349, 146356, 146363, 146370, + 146377, 146384, 146391, 146398, 146405, 146412, 146419, 146426, 146433, + 146440, 146447, 146454, 146461, 146468, 146475, 146482, 146489, 146496, + 146504, 146512, 146520, 146527, 146534, 146541, 146548, 146555, 146562, + 146569, 146576, 146583, 146590, 146596, 146603, 146610, 146617, 146624, + 146631, 146638, 146645, 146652, 146659, 146666, 146673, 146680, 146687, + 146694, 146702, 146710, 146718, 146725, 146732, 146739, 146746, 146753, + 146760, 146767, 146774, 146781, 146788, 146795, 146802, 146809, 146816, + 146823, 146830, 146837, 146844, 146851, 146858, 146865, 146872, 146879, + 146886, 146893, 146900, 146907, 146914, 146921, 146928, 146935, 146942, + 146949, 146956, 146963, 146970, 146977, 0, 0, 146984, 146988, 146992, + 146996, 147000, 147004, 147008, 147013, 147017, 147022, 147028, 147034, + 147040, 147046, 147054, 147062, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 95789, 95793, 95798, 95802, 95807, 95811, 95816, 95820, 95825, 95829, - 95834, 95838, 95843, 95848, 95853, 95858, 95863, 95868, 95873, 95878, - 95883, 95888, 95893, 95898, 95903, 95908, 95913, 95918, 95923, 95928, - 95932, 95936, 95941, 95946, 95951, 95955, 95959, 95963, 95968, 95973, - 95978, 95982, 95986, 95991, 95996, 96001, 96007, 96012, 96018, 96023, - 96029, 96034, 96040, 96045, 96051, 96056, 0, 0, 0, 0, 0, 0, 0, 0, 96061, - 96066, 96070, 96074, 96078, 96082, 96086, 96090, 96094, 96098, 0, 0, 0, + 0, 0, 0, 147068, 147072, 147076, 147080, 0, 147084, 147088, 147092, + 147096, 147100, 147104, 147108, 147112, 147116, 147120, 147124, 147128, + 147132, 147136, 147140, 147144, 147148, 147152, 147156, 147160, 147164, + 147168, 147172, 147176, 147182, 147188, 147194, 0, 147200, 147205, 0, + 147210, 0, 0, 147215, 0, 147220, 147225, 147230, 147235, 147240, 147245, + 147250, 147255, 147260, 147265, 0, 147270, 147275, 147280, 147285, 0, + 147290, 0, 147295, 0, 0, 0, 0, 0, 0, 147300, 0, 0, 0, 0, 147306, 0, + 147312, 0, 147318, 0, 147324, 147330, 147336, 0, 147342, 147348, 0, + 147354, 0, 0, 147360, 0, 147366, 0, 147372, 0, 147378, 0, 147386, 0, + 147394, 147400, 0, 147406, 0, 0, 147412, 147418, 147424, 147430, 0, + 147436, 147442, 147448, 147454, 147460, 147466, 147472, 0, 147478, + 147484, 147490, 147496, 0, 147502, 147508, 147514, 147520, 0, 147528, 0, + 147536, 147542, 147548, 147554, 147560, 147566, 147572, 147578, 147584, + 147590, 0, 147596, 147602, 147608, 147614, 147620, 147626, 147632, + 147638, 147644, 147650, 147656, 147662, 147668, 147674, 147680, 147686, + 147692, 0, 0, 0, 0, 0, 147698, 147703, 147708, 0, 147713, 147718, 147723, + 147728, 147733, 0, 147738, 147743, 147748, 147753, 147758, 147763, + 147768, 147773, 147778, 147783, 147788, 147793, 147798, 147803, 147808, + 147813, 147818, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 147823, 147833, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 147841, 147848, 147855, 147862, 147868, 147875, 147882, + 147888, 147895, 147902, 147909, 147917, 147925, 147933, 147941, 147949, + 147957, 147964, 147971, 147978, 147986, 147994, 148002, 148010, 148018, + 148026, 148033, 148040, 148047, 148055, 148063, 148071, 148079, 148087, + 148095, 148100, 148105, 148110, 148115, 148120, 148125, 148130, 148135, + 148140, 0, 0, 0, 0, 148145, 148151, 148155, 148159, 148163, 148167, + 148171, 148175, 148179, 148183, 148187, 148191, 148195, 148199, 148203, + 148207, 148211, 148215, 148219, 148223, 148227, 148231, 148235, 148239, + 148243, 148247, 148251, 148255, 148259, 148263, 148267, 148271, 148275, + 148279, 148283, 148287, 148291, 148295, 148299, 148303, 148307, 148311, + 148315, 148319, 148323, 148327, 148331, 148335, 148339, 148343, 148347, + 148352, 148356, 148360, 148364, 148368, 148372, 148376, 148380, 148384, + 148388, 148392, 148396, 148400, 148404, 148408, 148412, 148416, 148420, + 148424, 148428, 148432, 148436, 148440, 148444, 148448, 148452, 148456, + 148460, 148464, 148468, 148472, 148476, 148480, 148484, 148488, 148492, + 148496, 148500, 148504, 148508, 148512, 148516, 148520, 148524, 148528, + 148532, 148536, 148540, 148544, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 148548, 148554, 148563, 148571, 148579, 148588, 148597, 148606, 148615, + 148624, 148633, 148642, 148651, 148660, 148669, 0, 0, 148678, 148687, + 148695, 148703, 148712, 148721, 148730, 148739, 148748, 148757, 148766, + 148775, 148784, 148793, 148802, 0, 148810, 148819, 148827, 148835, + 148844, 148853, 148862, 148871, 148880, 148889, 148898, 148907, 148916, + 148925, 148934, 0, 148941, 148950, 148958, 148966, 148975, 148984, + 148993, 149002, 149011, 149020, 149029, 149038, 149047, 149056, 149065, + 149072, 149078, 149084, 149090, 149096, 149102, 149108, 149114, 149120, + 149126, 149132, 149138, 149144, 149150, 149156, 149162, 149168, 149174, + 149180, 149186, 149192, 149198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 149204, + 149211, 149216, 149220, 149224, 149228, 149233, 149238, 149243, 149248, + 149253, 149258, 149265, 0, 0, 0, 149273, 149278, 149284, 149290, 149296, + 149301, 149307, 149313, 149319, 149324, 149330, 149336, 149341, 149347, + 149353, 149358, 149364, 149370, 149375, 149380, 149386, 149391, 149397, + 149403, 149409, 149415, 149421, 149431, 149438, 149444, 149447, 0, + 149450, 149455, 149461, 149467, 149473, 149478, 149484, 149490, 149496, + 149501, 149507, 149513, 149518, 149524, 149530, 149535, 149541, 149547, + 149552, 149557, 149563, 149568, 149574, 149580, 149586, 149592, 149598, + 149601, 149604, 149607, 149610, 149613, 149616, 149622, 149629, 149636, + 149643, 149649, 149656, 149663, 149670, 149676, 149683, 149690, 149696, + 149703, 149710, 149716, 149723, 149730, 149736, 149742, 149749, 149755, + 149762, 149769, 149776, 149783, 149790, 149795, 0, 0, 0, 0, 149800, + 149806, 149813, 149820, 149827, 149833, 149840, 149847, 149854, 149860, + 149867, 149874, 149880, 149887, 149894, 149900, 149907, 149914, 149920, + 149926, 149933, 149939, 149946, 149953, 149960, 149967, 149974, 149983, + 149987, 149990, 149994, 149998, 150002, 150005, 150008, 150011, 150014, + 150017, 150020, 150023, 150026, 150029, 150035, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 96102, 96105, 96110, 96116, 96124, 96129, 96135, 96143, 96149, - 96155, 96159, 96163, 96170, 96179, 96186, 96195, 96201, 96210, 96217, - 96224, 96231, 96241, 96247, 96251, 96258, 96267, 96277, 96284, 96291, - 96295, 96299, 96306, 96316, 96320, 96327, 96334, 96341, 96347, 96354, - 96361, 96368, 96375, 96379, 96383, 96387, 96394, 96398, 96405, 96412, - 96426, 96435, 96439, 96443, 96447, 96454, 96458, 96462, 96466, 96474, - 96482, 96501, 96511, 96531, 96535, 96539, 96543, 96547, 96551, 96555, - 96559, 96566, 96570, 96573, 96577, 96581, 96587, 96594, 96603, 96607, - 96616, 96625, 96633, 96637, 96644, 96648, 96652, 96656, 96660, 96671, - 96680, 96689, 96698, 96707, 96719, 96728, 96737, 96746, 96754, 96763, - 96775, 96784, 96793, 96802, 96814, 96823, 96832, 96844, 96853, 96862, - 96874, 96883, 96887, 96891, 96895, 96899, 96903, 96907, 96911, 96918, - 96922, 96926, 96937, 96941, 96945, 96952, 96958, 96964, 96968, 96975, - 96979, 96983, 96987, 96991, 96995, 96999, 97005, 97013, 97017, 97021, - 97024, 97030, 97040, 97044, 97056, 97063, 97070, 97077, 97084, 97090, - 97094, 97098, 97102, 97106, 97113, 97122, 97129, 97137, 97145, 97151, - 97155, 97159, 97163, 97167, 97173, 97182, 97194, 97201, 97208, 97217, - 97228, 97234, 97243, 97252, 97259, 97268, 97275, 97282, 97292, 97299, - 97306, 97313, 97320, 97324, 97330, 97334, 97345, 97353, 97362, 97374, - 97381, 97388, 97398, 97405, 97414, 97421, 97430, 97437, 97444, 97454, - 97461, 97468, 97478, 97485, 97497, 97506, 97513, 97520, 97527, 97536, - 97546, 97559, 97566, 97576, 97586, 97593, 97602, 97615, 97622, 97629, - 97636, 97646, 97656, 97663, 97673, 97680, 97687, 97697, 97703, 97710, - 97717, 97724, 97734, 97741, 97748, 97755, 97761, 97768, 97778, 97785, - 97789, 97797, 97801, 97813, 97817, 97831, 97835, 97839, 97843, 97847, - 97853, 97860, 97868, 97872, 97876, 97880, 97884, 97891, 97895, 97901, - 97907, 97915, 97919, 97926, 97934, 97938, 97942, 97948, 97952, 97961, - 97970, 97977, 97987, 97993, 97997, 98001, 98009, 98016, 98023, 98029, - 98033, 98041, 98045, 98052, 98064, 98071, 98081, 98087, 98091, 98100, - 98107, 98116, 98120, 98124, 98131, 98135, 98139, 98143, 98147, 98150, - 98156, 98162, 98166, 98170, 98177, 98184, 98191, 98198, 98205, 98212, - 98219, 98226, 98232, 98236, 98240, 98247, 98254, 98261, 98268, 98275, - 98279, 98282, 98287, 98291, 98295, 98304, 98313, 98317, 98321, 98327, - 98333, 98350, 98356, 98360, 98369, 98373, 98377, 98384, 98392, 98400, - 98406, 98410, 98414, 98418, 98422, 98425, 98431, 98438, 98448, 98455, - 98462, 98469, 98475, 98482, 98489, 98496, 98503, 98510, 98519, 98526, - 98538, 98545, 98552, 98562, 98573, 98580, 98587, 98594, 98601, 98608, - 98615, 98622, 98629, 98636, 98643, 98653, 98663, 98673, 98680, 98690, - 98697, 98704, 98711, 98718, 98724, 98731, 98738, 98745, 98752, 98759, - 98766, 98773, 98780, 98786, 98793, 98800, 98809, 98816, 98823, 98827, - 98835, 98839, 98843, 98847, 98851, 98855, 98862, 98866, 98875, 98879, - 98886, 98894, 98898, 98902, 98906, 98919, 98935, 98939, 98943, 98950, - 98956, 98963, 98967, 98971, 98975, 98979, 98983, 98990, 98994, 99012, - 99016, 99020, 99027, 99031, 99035, 99041, 99045, 99049, 99057, 99061, - 99065, 99069, 99073, 99079, 99090, 99099, 99108, 99115, 99122, 99133, - 99140, 99147, 99154, 99161, 99168, 99175, 99182, 99192, 99198, 99205, - 99215, 99224, 99231, 99240, 99250, 99257, 99264, 99271, 99278, 99290, - 99297, 99304, 99311, 99318, 99325, 99335, 99342, 99349, 99359, 99372, - 99384, 99391, 99401, 99408, 99415, 99422, 99436, 99442, 99450, 99460, - 99470, 99477, 99484, 99490, 99494, 99501, 99511, 99517, 99530, 99534, - 99538, 99545, 99549, 99556, 99566, 99570, 99574, 99578, 99582, 99586, - 99593, 99597, 99604, 99611, 99618, 99627, 99636, 99646, 99653, 99660, - 99667, 99677, 99684, 99694, 99701, 99711, 99718, 99725, 99735, 99745, - 99752, 99758, 99766, 99774, 99780, 99786, 99790, 99794, 99801, 99809, - 99815, 99819, 99823, 99827, 99834, 99846, 99849, 99856, 99862, 99866, - 99870, 99874, 99878, 99882, 99886, 99890, 99894, 99898, 99902, 99909, - 99913, 99919, 99923, 99927, 99931, 99937, 99944, 99951, 99958, 99969, - 99977, 99981, 99987, 99996, 100003, 100009, 100012, 100016, 100020, - 100026, 100035, 100043, 100047, 100053, 100057, 100061, 100065, 100071, - 100078, 100084, 100088, 100094, 100098, 100102, 100111, 100123, 100127, - 100134, 100141, 100151, 100158, 100170, 100177, 100184, 100191, 100202, - 100212, 100225, 100235, 100242, 100246, 100250, 100254, 100258, 100267, - 100276, 100285, 100302, 100311, 100317, 100324, 100332, 100345, 100349, - 100358, 100367, 100376, 100385, 100396, 100405, 100414, 100423, 100432, - 100441, 100450, 100460, 100463, 100467, 100471, 100475, 100479, 100483, - 100489, 100496, 100503, 100510, 100516, 100522, 100529, 100535, 100542, - 100550, 100554, 100561, 100568, 100575, 100583, 100586, 100590, 100594, - 100598, 100601, 100607, 100611, 100617, 100624, 100631, 100637, 100644, - 100651, 100658, 100665, 100672, 100679, 100686, 100693, 100700, 100707, - 100714, 100721, 100728, 100735, 100741, 100745, 100754, 100758, 100762, - 100766, 100770, 100776, 100783, 100790, 100797, 100804, 100811, 100817, - 100825, 100829, 100833, 100837, 100841, 100847, 100864, 100881, 100885, - 100889, 100893, 100897, 100901, 100905, 100911, 100918, 100922, 100928, - 100935, 100942, 100949, 100956, 100963, 100972, 100979, 100986, 100993, - 101000, 101004, 101008, 101014, 101026, 101030, 101034, 101043, 101047, - 101051, 101055, 101061, 101065, 101069, 101078, 101082, 101086, 101090, - 101097, 101101, 101105, 101109, 101113, 101117, 101121, 101125, 101129, - 101135, 101142, 101149, 101155, 101159, 101176, 101182, 101186, 101192, - 101198, 101204, 101210, 101216, 101222, 101226, 101230, 101234, 101240, - 101244, 101250, 101254, 101258, 101265, 101272, 101289, 101293, 101297, - 101301, 101305, 101309, 101321, 101324, 101329, 101334, 101349, 101359, - 101371, 101375, 101379, 101383, 101389, 101396, 101403, 101413, 101425, - 101431, 101437, 101446, 101450, 101454, 101461, 101471, 101478, 101484, - 101488, 101492, 101499, 101505, 101509, 101515, 101519, 101527, 101533, - 101537, 101545, 101553, 101560, 101566, 101573, 101580, 101590, 101600, - 101604, 101608, 101612, 101616, 101622, 101629, 101635, 101642, 101649, - 101656, 101665, 101672, 101679, 101685, 101692, 101699, 101706, 101713, - 101720, 101727, 101733, 101740, 101747, 101754, 101763, 101770, 101777, - 101781, 101787, 101791, 101797, 101804, 101811, 101818, 101822, 101826, - 101830, 101834, 101838, 101845, 101849, 101853, 101859, 101867, 101871, - 101875, 101879, 101883, 101890, 101894, 101898, 101906, 101910, 101914, - 101918, 101922, 101928, 101932, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 101936, 101942, 101948, 101955, 101962, 101969, 101976, 101983, - 101990, 101996, 102003, 102010, 102017, 102024, 102031, 102038, 102044, - 102050, 102056, 102062, 102068, 102074, 102080, 102086, 102092, 102099, - 102106, 102113, 102120, 102127, 102134, 102140, 102146, 102152, 102159, - 102166, 102172, 102178, 102187, 102194, 102201, 102208, 102215, 102222, - 102229, 102235, 102241, 102247, 102256, 102263, 102270, 102281, 102292, - 102298, 102304, 102310, 102319, 102326, 102333, 102343, 102353, 102364, - 102375, 102387, 102400, 102411, 102422, 102434, 102447, 102458, 102469, - 102480, 102491, 102502, 102514, 102522, 102530, 102539, 102548, 102557, - 102563, 102569, 102575, 102582, 102592, 102599, 102609, 102614, 102619, - 102625, 102631, 102639, 102647, 102656, 102667, 102678, 102686, 102694, - 102703, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102712, 102723, 102730, - 102738, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102746, 102750, 102754, - 102758, 102762, 102766, 102770, 102774, 102778, 102782, 102786, 102790, - 102794, 102798, 102802, 102806, 102810, 102814, 102818, 102822, 102826, - 102830, 102834, 102838, 102842, 102846, 102850, 102854, 102858, 102862, - 102866, 102870, 102874, 102878, 102882, 102886, 102890, 102894, 102898, - 102902, 102906, 102910, 102914, 102918, 102922, 102926, 102930, 102934, - 102938, 102942, 102946, 102950, 102954, 102958, 102962, 102966, 102970, - 102974, 102978, 102982, 102986, 102990, 102994, 102998, 103002, 103006, - 103010, 103014, 103018, 103022, 103026, 103030, 103034, 103038, 103042, - 103046, 103050, 103054, 103058, 103062, 103066, 103070, 103074, 103078, - 103082, 103086, 103090, 103094, 103098, 103102, 103106, 103110, 103114, - 103118, 103122, 103126, 103130, 103134, 103138, 103142, 103146, 103150, - 103154, 103158, 103162, 103166, 103170, 103174, 103178, 103182, 103186, - 103190, 103194, 103198, 103202, 103206, 103210, 103214, 103218, 103222, - 103226, 103230, 103234, 103238, 103242, 103246, 103250, 103254, 103258, - 103262, 103266, 103270, 103274, 103278, 103282, 103286, 103290, 103294, - 103298, 103302, 103306, 103310, 103314, 103318, 103322, 103326, 103330, - 103334, 103338, 103342, 103346, 103350, 103354, 103358, 103362, 103366, - 103370, 103374, 103378, 103382, 103386, 103390, 103394, 103398, 103402, - 103406, 103410, 103414, 103418, 103422, 103426, 103430, 103434, 103438, - 103442, 103446, 103450, 103454, 103458, 103462, 103466, 103470, 103474, - 103478, 103482, 103486, 103490, 103494, 103498, 103502, 103506, 103510, - 103514, 103518, 103522, 103526, 103530, 103534, 103538, 103542, 103546, - 103550, 103554, 103558, 103562, 103566, 103570, 103574, 103578, 103582, - 103586, 103590, 103594, 103598, 103602, 103606, 103610, 103614, 103618, - 103622, 103626, 103630, 103634, 103638, 103642, 103646, 103650, 103654, - 103658, 103662, 103666, 103670, 103674, 103678, 103682, 103686, 103690, - 103694, 103698, 103702, 103706, 103710, 103714, 103718, 103722, 103726, - 103730, 103734, 103738, 103742, 103746, 103750, 103754, 103758, 103762, - 103766, 103770, 103774, 103778, 103782, 103786, 103790, 103794, 103798, - 103802, 103806, 103810, 103814, 103818, 103822, 103826, 103830, 103834, - 103838, 103842, 103846, 103850, 103854, 103858, 103862, 103866, 103870, - 103874, 103878, 103882, 103886, 103890, 103894, 103898, 103902, 103906, - 103910, 103914, 103918, 103922, 103926, 103930, 103934, 103938, 103942, - 103946, 103950, 103954, 103958, 103962, 103966, 103970, 103974, 103978, - 103982, 103986, 103990, 103994, 103998, 104002, 104006, 104010, 104014, - 104018, 104022, 104026, 104030, 104034, 104038, 104042, 104046, 104050, - 104054, 104058, 104062, 104066, 104070, 104074, 104078, 104082, 104086, - 104090, 104094, 104098, 104102, 104106, 104110, 104114, 104118, 104122, - 104126, 104130, 104134, 104138, 104142, 104146, 104150, 104154, 104158, - 104162, 104166, 104170, 104174, 104178, 104182, 104186, 104190, 104194, - 104198, 104202, 104206, 104210, 104214, 104218, 104222, 104226, 104230, - 104234, 104238, 104242, 104246, 104250, 104254, 104258, 104262, 104266, - 104270, 104274, 104278, 104282, 104286, 104290, 104294, 104298, 104302, - 104306, 104310, 104314, 104318, 104322, 104326, 104330, 104334, 104338, - 104342, 104346, 104350, 104354, 104358, 104362, 104366, 104370, 104374, - 104378, 104382, 104386, 104390, 104394, 104398, 104402, 104406, 104410, - 104414, 104418, 104422, 104426, 104430, 104434, 104438, 104442, 104446, - 104450, 104454, 104458, 104462, 104466, 104470, 104474, 104478, 104482, - 104486, 104490, 104494, 104498, 104502, 104506, 104510, 104514, 104518, - 104522, 104526, 104530, 104534, 104538, 104542, 104546, 104550, 104554, - 104558, 104562, 104566, 104570, 104574, 104578, 104582, 104586, 104590, - 104594, 104598, 104602, 104606, 104610, 104614, 104618, 104622, 104626, - 104630, 104634, 104638, 104642, 104646, 104650, 104654, 104658, 104662, - 104666, 104670, 104674, 104678, 104682, 104686, 104690, 104694, 104698, - 104702, 104706, 104710, 104714, 104718, 104722, 104726, 104730, 104734, - 104738, 104742, 104746, 104750, 104754, 104758, 104762, 104766, 104770, - 104774, 104778, 104782, 104786, 104790, 104794, 104798, 104802, 104806, - 104810, 104814, 104818, 104822, 104826, 104830, 104834, 104838, 104842, - 104846, 104850, 104854, 104858, 104862, 104866, 104870, 104874, 104878, - 104882, 104886, 104890, 104894, 104898, 104902, 104906, 104910, 104914, - 104918, 104922, 104926, 104930, 104934, 104938, 104942, 104946, 104950, - 104954, 104958, 104962, 104966, 104970, 104974, 104978, 104982, 104986, - 104990, 104994, 104998, 105002, 105006, 105010, 105014, 105018, 105022, - 105026, 105030, 105034, 105038, 105042, 105046, 105050, 105054, 105058, - 105062, 105066, 105070, 105074, 105078, 105082, 105086, 105090, 105094, - 105098, 105102, 105106, 105110, 105114, 105118, 105122, 105126, 105130, - 105134, 105138, 105142, 105146, 105150, 105154, 105158, 105162, 105166, - 105170, 105174, 105178, 105182, 105186, 105190, 105194, 105198, 105202, - 105206, 105210, 105214, 105218, 105222, 105226, 105230, 105234, 105238, - 105242, 105246, 105250, 105254, 105258, 105262, 105266, 105270, 105274, - 105278, 105282, 105286, 105290, 105294, 105298, 105302, 105306, 105310, - 105314, 105318, 105322, 105326, 105330, 105334, 105338, 105342, 105346, - 105350, 105354, 105358, 105362, 105366, 105370, 105374, 105378, 105382, - 105386, 105390, 105394, 105398, 105402, 105406, 105410, 105414, 105418, - 105422, 105426, 105430, 105434, 105438, 105442, 105446, 105450, 105454, - 105458, 105462, 105466, 105470, 105474, 105478, 105482, 105486, 105490, - 105494, 105498, 105502, 105506, 105510, 105514, 105518, 105522, 105526, - 105530, 105534, 105538, 105542, 105546, 105550, 105554, 105558, 105562, - 105566, 105570, 105574, 105578, 105582, 105586, 105590, 105594, 105598, - 105602, 105606, 105610, 105614, 105618, 105622, 105626, 105630, 105634, - 105638, 105642, 105646, 105650, 105654, 105658, 105662, 105666, 105670, - 105674, 105678, 105682, 105686, 105690, 105694, 105698, 105702, 105706, - 105710, 105714, 105718, 105722, 105726, 105730, 105734, 105738, 105742, - 105746, 105750, 105754, 105758, 105762, 105766, 105770, 105774, 105778, - 105782, 105786, 105790, 105794, 105798, 105802, 105806, 105810, 105814, - 105818, 105822, 105826, 105830, 105834, 105838, 105842, 105846, 105850, - 105854, 105858, 105862, 105866, 105870, 105874, 105878, 105882, 105886, - 105890, 105894, 105898, 105902, 105906, 105910, 105914, 105918, 105922, - 105926, 105930, 105934, 105938, 105942, 105946, 105950, 105954, 105958, - 105962, 105966, 105970, 105974, 105978, 105982, 105986, 105990, 105994, - 105998, 106002, 106006, 106010, 106014, 106018, 106022, 106026, 106030, - 106034, 106038, 106042, 106046, 106050, 106054, 106058, 106062, 106066, - 106070, 106074, 106078, 106082, 106086, 106090, 106094, 106098, 106102, - 106106, 106110, 106114, 106118, 106122, 106126, 106130, 106134, 106138, - 106142, 106146, 106150, 106154, 106158, 106162, 106166, 106170, 106174, - 106178, 106182, 106186, 106190, 106194, 106198, 106202, 106206, 106210, - 106214, 106218, 106222, 106226, 106230, 106234, 106238, 106242, 106246, - 106250, 106254, 106258, 106262, 106266, 106270, 106274, 106278, 106282, - 106286, 106290, 106294, 106298, 106302, 106306, 106310, 106314, 106318, - 106322, 106326, 106330, 106334, 106338, 106342, 106346, 106350, 106354, - 106358, 106362, 106366, 106370, 106374, 106378, 106382, 106386, 106390, - 106394, 106398, 106402, 106406, 106410, 106414, 106418, 106422, 106426, - 106430, 106434, 106438, 106442, 106446, 106450, 106454, 106458, 106462, - 106466, 106470, 106474, 106478, 106482, 106486, 106490, 106494, 106498, - 106502, 106506, 106510, 106514, 106518, 106522, 106526, 106530, 106534, - 106538, 106542, 106546, 106550, 106554, 106558, 106562, 106566, 106570, - 106574, 106578, 106582, 106586, 106590, 106594, 106598, 106602, 106606, - 106610, 106614, 106618, 106622, 106626, 106630, 106634, 106638, 106642, - 106646, 106650, 106654, 106658, 106662, 106666, 106670, 106674, 106678, - 106682, 106686, 106690, 106694, 106698, 106702, 106706, 106710, 106714, - 106718, 106722, 106726, 106730, 106734, 106738, 106742, 106746, 106750, - 106754, 106758, 106762, 106766, 106770, 106774, 106778, 106782, 106786, - 106790, 106794, 106798, 106802, 106806, 106810, 106814, 106818, 106822, - 106826, 106830, 106834, 106838, 106842, 106846, 106850, 106854, 106858, - 106862, 106866, 106870, 106874, 106878, 106882, 106886, 106890, 106894, - 106898, 106902, 106906, 106910, 106914, 106918, 106922, 106926, 106930, - 106934, 106938, 106942, 106946, 106950, 106954, 106958, 106962, 106966, - 106970, 106974, 106978, 106982, 106986, 106990, 106994, 106998, 107002, - 107006, 107010, 107014, 107018, 107022, 107026, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150038, 150045, + 150053, 150061, 150069, 150076, 150084, 150092, 150100, 150107, 150115, + 150123, 150130, 150138, 150146, 150153, 150161, 150169, 150176, 150183, + 150191, 150198, 150206, 150214, 150222, 150230, 150238, 150242, 150246, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150250, 150256, 150262, 150268, + 150272, 150278, 150284, 150290, 150296, 150302, 150308, 150314, 150320, + 150326, 150332, 150338, 150344, 150350, 150356, 150362, 150368, 150374, + 150380, 150386, 150392, 150398, 150404, 150410, 150416, 150422, 150428, + 150434, 150440, 150446, 150452, 150458, 150464, 150470, 150476, 150482, + 150488, 150494, 150500, 0, 0, 0, 0, 0, 150506, 150517, 150528, 150539, + 150550, 150561, 150572, 150583, 150594, 0, 0, 0, 0, 0, 0, 0, 150605, + 150609, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 107030, 107037, 107044, 107053, 107062, 107069, 107074, 107081, - 107088, 107097, 107108, 107119, 107124, 107131, 107136, 107141, 107146, - 107151, 107156, 107161, 107166, 107171, 107176, 107181, 107186, 107193, - 107200, 107205, 107210, 107215, 107220, 107227, 107234, 107242, 107247, - 107254, 107259, 107264, 107269, 107274, 107279, 107286, 107293, 107298, - 107303, 107308, 107313, 107318, 107323, 107328, 107333, 107338, 107343, - 107348, 107353, 107358, 107363, 107368, 107373, 107378, 107383, 107388, - 107395, 107400, 107405, 107414, 107421, 107426, 107431, 107436, 107441, - 107446, 107451, 107456, 107461, 107466, 107471, 107476, 107481, 107486, - 107491, 107496, 107501, 107506, 107511, 107516, 107521, 107526, 107532, - 107540, 107546, 107554, 107562, 107570, 107576, 107582, 107588, 107594, - 107600, 107608, 107618, 107626, 107634, 107640, 107646, 107654, 107662, - 107668, 107676, 107684, 107692, 107698, 107704, 107710, 107716, 107722, - 107728, 107736, 107744, 107750, 107756, 107762, 107768, 107774, 107782, - 107788, 107794, 107800, 107806, 107812, 107818, 107826, 107832, 107838, - 107844, 107850, 107858, 107866, 107872, 107878, 107884, 107889, 107895, - 107901, 107908, 107913, 107918, 107923, 107928, 107933, 107938, 107943, - 107948, 107953, 107962, 107969, 107974, 107979, 107984, 107991, 107996, - 108001, 108006, 108013, 108018, 108023, 108028, 108033, 108038, 108043, - 108048, 108053, 108058, 108063, 108068, 108075, 108080, 108087, 108092, - 108097, 108104, 108109, 108114, 108119, 108124, 108129, 108134, 108139, - 108144, 108149, 108154, 108159, 108164, 108169, 108174, 108179, 108184, - 108189, 108194, 108199, 108206, 108211, 108216, 108221, 108226, 108231, - 108236, 108241, 108246, 108251, 108256, 108261, 108266, 108271, 108278, - 108283, 108288, 108295, 108300, 108305, 108310, 108315, 108320, 108325, - 108330, 108335, 108340, 108345, 108352, 108357, 108362, 108367, 108372, - 108377, 108384, 108391, 108396, 108401, 108406, 108411, 108416, 108421, - 108426, 108431, 108436, 108441, 108446, 108451, 108456, 108461, 108466, - 108471, 108476, 108481, 108486, 108491, 108496, 108501, 108506, 108511, - 108516, 108521, 108526, 108531, 108536, 108541, 108546, 108551, 108556, - 108561, 108566, 108571, 108578, 108583, 108588, 108593, 108598, 108603, - 108608, 108613, 108618, 108623, 108628, 108633, 108638, 108643, 108648, - 108653, 108658, 108663, 108668, 108673, 108678, 108683, 108688, 108693, - 108698, 108703, 108708, 108713, 108718, 108723, 108728, 108733, 108738, - 108743, 108748, 108753, 108758, 108763, 108768, 108773, 108778, 108783, - 108788, 108793, 108798, 108803, 108808, 108813, 108818, 108823, 108828, - 108833, 108838, 108843, 108848, 108853, 108858, 108863, 108868, 108875, - 108880, 108885, 108890, 108895, 108900, 108905, 108909, 108914, 108919, - 108924, 108929, 108934, 108939, 108944, 108949, 108954, 108959, 108964, - 108969, 108974, 108979, 108986, 108991, 108996, 109002, 109007, 109012, - 109017, 109022, 109027, 109032, 109037, 109042, 109047, 109052, 109057, - 109062, 109067, 109072, 109077, 109082, 109087, 109092, 109097, 109102, - 109107, 109112, 109117, 109122, 109127, 109132, 109137, 109142, 109147, - 109152, 109157, 109162, 109167, 109172, 109177, 109182, 109187, 109192, - 109197, 109202, 109207, 109212, 109217, 109224, 109229, 109234, 109241, - 109248, 109253, 109258, 109263, 109268, 109273, 109278, 109283, 109288, - 109293, 109298, 109303, 109308, 109313, 109318, 109323, 109328, 109333, - 109338, 109343, 109348, 109353, 109358, 109363, 109368, 109373, 109380, - 109385, 109390, 109395, 109400, 109405, 109410, 109415, 109420, 109425, - 109430, 109435, 109440, 109445, 109450, 109455, 109460, 109465, 109470, - 109477, 109482, 109487, 109492, 109497, 109502, 109507, 109512, 109518, - 109523, 109528, 109533, 109538, 109543, 109548, 109553, 109558, 109565, - 109572, 109577, 109582, 109586, 109591, 109595, 109599, 109604, 109611, - 109616, 109621, 109630, 109635, 109640, 109645, 109650, 109657, 109664, - 109669, 109674, 109679, 109684, 109691, 109696, 109701, 109706, 109711, - 109716, 109721, 109726, 109731, 109736, 109741, 109746, 109751, 109758, - 109762, 109767, 109772, 109777, 109782, 109786, 109791, 109796, 109801, - 109806, 109811, 109816, 109821, 109826, 109831, 109837, 109843, 109849, - 109855, 109861, 109867, 109873, 109879, 109885, 109891, 109897, 109903, - 109908, 109914, 109920, 109926, 109932, 109938, 109944, 109950, 109956, - 109962, 109968, 109974, 109979, 109985, 109991, 109997, 110003, 110009, - 110015, 110021, 110027, 110033, 110039, 110045, 110051, 110057, 110063, - 110069, 110075, 110081, 110087, 110093, 110099, 110104, 110110, 110116, - 110122, 110128, 110134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 110140, 110143, 110147, 110151, 110155, 110158, - 110162, 110167, 110171, 110175, 110179, 110183, 110187, 110192, 110197, - 110201, 110205, 110208, 110212, 110217, 110222, 110226, 110230, 110234, - 110238, 110242, 110246, 110250, 110254, 110258, 110262, 110265, 110269, - 110273, 110277, 110281, 110285, 110289, 110295, 110298, 110302, 110306, - 110310, 110314, 110318, 110322, 110326, 110330, 110334, 110339, 110344, - 110350, 110354, 110358, 110362, 110366, 110370, 110374, 110379, 110382, - 110386, 110390, 110394, 110398, 110404, 110408, 110412, 110416, 110420, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110424, 110428, 110432, 110438, 110444, - 110448, 110453, 110458, 110463, 110468, 110472, 110477, 110482, 110487, - 110491, 110496, 110501, 110506, 110510, 110515, 110520, 110525, 110530, - 110535, 110540, 110545, 110550, 110554, 110559, 110564, 110569, 110574, - 110579, 110584, 110589, 110594, 110599, 110604, 110609, 110616, 110621, - 110628, 110633, 110638, 110643, 110648, 110653, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 110658, 110662, 110668, 110671, 110674, 110678, - 110682, 110686, 110690, 110694, 110698, 110702, 110708, 110714, 110720, - 110726, 110732, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 150613, 150615, 150617, 150621, 150626, 150631, + 150633, 150639, 150644, 150646, 150652, 150656, 150658, 150662, 150668, + 150674, 150680, 150685, 150690, 150697, 150704, 150711, 150716, 150723, + 150730, 150737, 150741, 150748, 150757, 150766, 150773, 150778, 150782, + 150786, 150788, 150791, 150794, 150801, 150808, 150818, 150823, 150828, + 150833, 150838, 150840, 150846, 150850, 150852, 150854, 150856, 150858, + 150862, 150866, 150870, 150872, 150876, 150878, 150882, 150884, 150886, + 150888, 150890, 150895, 150900, 150902, 150908, 150912, 150916, 150924, + 150926, 150928, 150930, 150932, 150934, 150936, 150938, 150940, 150942, + 150944, 150948, 150952, 150954, 150956, 150958, 150960, 150962, 150967, + 150973, 150977, 150981, 150985, 150989, 150994, 150998, 151000, 151002, + 151006, 151012, 151014, 151016, 151018, 151022, 151031, 151037, 151041, + 151045, 151047, 151049, 151052, 151054, 151056, 151058, 151062, 151064, + 151068, 151073, 151075, 151080, 151086, 151093, 151097, 151101, 151105, + 151109, 151115, 151119, 151127, 151134, 151136, 151138, 151142, 151146, + 151148, 151152, 151156, 151158, 151162, 151164, 151168, 151172, 151176, + 151180, 151184, 151188, 151192, 151196, 151202, 151206, 151210, 151221, + 151226, 151230, 151234, 151240, 151244, 151248, 151252, 151259, 151266, + 151270, 151274, 151278, 151282, 151286, 151293, 151295, 151299, 151301, + 151303, 151307, 151311, 151315, 151317, 151321, 151325, 151329, 151333, + 151337, 151339, 151343, 151345, 151351, 151354, 151359, 151361, 151363, + 151366, 151368, 151370, 151373, 151380, 151387, 151394, 151399, 151403, + 151405, 151407, 151409, 151413, 151415, 151419, 151423, 151427, 151429, + 151433, 151435, 151439, 151443, 151450, 151452, 151461, 151470, 151479, + 151485, 151487, 151492, 151496, 151500, 151502, 151508, 151512, 151514, + 151518, 151522, 151524, 151528, 151533, 151537, 151543, 151549, 151551, + 151553, 151559, 151561, 151565, 151569, 151571, 151575, 151577, 151581, + 151585, 151589, 151592, 151595, 151600, 151605, 151607, 151610, 151612, + 151619, 151623, 151625, 151632, 151639, 151646, 151653, 151660, 151662, + 151664, 151666, 151670, 151672, 151674, 151676, 151678, 151680, 151682, + 151684, 151686, 151688, 151690, 151692, 151694, 151696, 151698, 151700, + 151702, 151704, 151706, 151708, 151710, 151712, 151714, 151718, 151720, + 151722, 151724, 151728, 151730, 151734, 151736, 151738, 151742, 151746, + 151752, 151754, 151756, 151758, 151760, 151764, 151768, 151770, 151774, + 151778, 151782, 151786, 151790, 151794, 151798, 151802, 151806, 151810, + 151814, 151818, 151822, 151826, 151830, 151834, 151838, 151842, 151844, + 151846, 151848, 151850, 151852, 151854, 151856, 151864, 151872, 151880, + 151888, 151893, 151898, 151903, 151907, 151911, 151916, 151920, 151922, + 151926, 151928, 151930, 151932, 151934, 151936, 151938, 151940, 151944, + 151946, 151948, 151950, 151954, 151958, 151962, 151966, 151970, 151972, + 151978, 151984, 151986, 151988, 151990, 151992, 151994, 152003, 152010, + 152017, 152021, 152028, 152033, 152040, 152049, 152054, 152058, 152062, + 152064, 152068, 152070, 152074, 152078, 152080, 152084, 152088, 152092, + 152094, 152096, 152102, 152104, 152106, 152108, 152112, 152116, 152118, + 152122, 152124, 152126, 152129, 152133, 152135, 152139, 152141, 152143, + 152148, 152150, 152154, 152158, 152161, 152165, 152169, 152173, 152177, + 152181, 152185, 152189, 152194, 152198, 152202, 152211, 152216, 152219, + 152221, 152224, 152227, 152232, 152234, 152237, 152242, 152246, 152249, + 152253, 152257, 152260, 152265, 152269, 152273, 152277, 152281, 152287, + 152293, 152299, 152305, 152310, 152320, 152322, 152326, 152328, 152330, + 152334, 152338, 152340, 152344, 152349, 152354, 152360, 152362, 152366, + 152370, 152376, 152382, 152386, 152388, 152390, 152394, 152396, 152400, + 152404, 152408, 152410, 152412, 152419, 152423, 152426, 152430, 152434, + 152438, 152440, 152444, 152446, 152448, 152452, 152454, 152458, 152462, + 152468, 152472, 152476, 152480, 152482, 152485, 152489, 152495, 152504, + 152513, 152521, 152529, 152531, 152535, 152537, 152541, 152552, 152556, + 152562, 152568, 152573, 152575, 152580, 152584, 152586, 152588, 152590, + 152594, 152598, 152602, 152607, 152617, 152632, 152642, 152652, 152656, + 152660, 152666, 152668, 152676, 152684, 152686, 152690, 152696, 152702, + 152709, 152716, 152718, 152720, 152723, 152725, 152731, 152733, 152736, + 152740, 152746, 152752, 152763, 152769, 152775, 152783, 152787, 152795, + 152803, 152809, 152815, 152822, 152824, 152828, 152830, 152832, 152837, + 152839, 152841, 152843, 152845, 152849, 152859, 152865, 152869, 152873, + 152877, 152883, 152889, 152895, 152901, 152906, 152911, 152917, 152923, + 152930, 152937, 152945, 152953, 152958, 152966, 152970, 152979, 152988, + 152994, 152998, 153002, 153006, 153009, 153014, 153016, 153018, 153020, + 153027, 153032, 153039, 153046, 153053, 153061, 153069, 153077, 153085, + 153093, 153101, 153109, 153117, 153125, 153131, 153137, 153143, 153149, + 153155, 153161, 153167, 153173, 153179, 153185, 153191, 153197, 153200, + 153209, 153218, 153220, 153227, 153231, 153233, 153235, 153239, 153245, + 153249, 153251, 153261, 153267, 153271, 153273, 153277, 0, 153279, + 153286, 153293, 153300, 153305, 153310, 153319, 153325, 153330, 153334, + 153339, 153343, 153350, 153354, 153357, 153362, 153369, 153376, 153381, + 153386, 153391, 153398, 153407, 153418, 153424, 153430, 153436, 153446, + 153461, 153470, 153478, 153486, 153494, 153502, 153510, 153518, 153526, + 153534, 153542, 153550, 153558, 0, 153566, 153570, 153575, 153580, + 153582, 153586, 153595, 153604, 153612, 153616, 153620, 153625, 153630, + 153635, 153637, 153642, 153646, 153648, 153652, 153656, 153662, 153667, + 153675, 153680, 153685, 153690, 153697, 153700, 153702, 153705, 153710, + 153716, 153720, 153724, 153730, 153736, 153738, 153742, 153746, 153750, + 153754, 153758, 153760, 153762, 153764, 153766, 153772, 153778, 153782, + 153784, 153786, 153788, 153797, 153801, 153808, 153815, 153817, 153820, + 153824, 153830, 153834, 153838, 153840, 153848, 153852, 153856, 153861, + 153866, 153871, 153876, 153881, 153886, 153891, 153896, 153901, 153906, + 153910, 153916, 153920, 153926, 153931, 153938, 153944, 153952, 153956, + 153963, 153967, 153971, 153975, 153980, 153985, 153987, 153991, 154000, + 154008, 154016, 154029, 154042, 154055, 154062, 154069, 154073, 154082, + 154090, 154094, 154103, 154110, 154114, 154118, 154122, 154126, 154133, + 154137, 154141, 154145, 154149, 154156, 154165, 154174, 154181, 154193, + 154205, 154209, 154213, 154217, 154221, 154225, 154229, 154237, 154245, + 154253, 154257, 154261, 154265, 154269, 154273, 154277, 154283, 154289, + 154293, 154304, 154312, 154316, 154320, 154324, 154328, 154334, 154341, + 154352, 154362, 154372, 154383, 154392, 154403, 154409, 154415, 154421, + 154427, 154433, 154437, 154444, 154453, 154460, 154466, 154470, 154474, + 154478, 154487, 154499, 154503, 154510, 154517, 154524, 154532, 154539, + 154547, 154556, 154566, 154575, 154585, 154594, 154604, 154613, 154623, + 154633, 154644, 154654, 154665, 154672, 154680, 154687, 154695, 154703, + 154712, 154720, 154729, 154736, 154748, 154755, 154767, 154770, 154773, + 154776, 154779, 154785, 154792, 154798, 154805, 154810, 154816, 154828, + 154838, 154849, 154854, 154859, 154865, 154870, 154877, 154881, 154887, + 154889, 154891, 154895, 154899, 154903, 154912, 154914, 154916, 154919, + 154921, 154923, 154927, 154929, 154933, 154935, 154939, 154941, 154943, + 154947, 154951, 154957, 154959, 154963, 154965, 154969, 154973, 154977, + 154981, 154983, 154985, 154989, 154993, 154997, 155001, 155003, 155005, + 155007, 155013, 155018, 155021, 155029, 155037, 155039, 155044, 155047, + 155052, 155063, 155070, 155075, 155080, 155082, 155086, 155088, 155092, + 155094, 155098, 155102, 155105, 155108, 155110, 155113, 155115, 155119, + 155121, 155123, 155125, 155129, 155131, 155135, 155138, 155145, 155148, + 155153, 155156, 155159, 155164, 155168, 155172, 155176, 155178, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155183, 155188, 155190, 155194, + 155196, 155200, 155204, 155210, 155214, 155219, 155222, 155226, 155230, + 0, 0, 0, 155234, 155236, 155242, 155246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 155250, 155255, 155260, 155265, 155270, 155275, 155280, 155287, + 155294, 155301, 155308, 155313, 155318, 155323, 155328, 155335, 155341, + 155348, 155355, 155362, 155367, 155372, 155377, 155382, 155387, 155394, + 155401, 155406, 155411, 155418, 155425, 155433, 155441, 155448, 155455, + 155463, 155471, 155479, 155486, 155496, 155507, 155512, 155519, 155526, + 155533, 155541, 155549, 155560, 155568, 155576, 155584, 155589, 155594, + 155599, 155604, 155609, 155614, 155619, 155624, 155629, 155634, 155639, + 155644, 155651, 155656, 155661, 155668, 155673, 155678, 155683, 155688, + 155693, 155698, 155703, 155708, 155713, 155718, 155723, 155728, 155735, + 155743, 155748, 155753, 155760, 155765, 155770, 155775, 155782, 155787, + 155794, 155799, 155806, 155811, 155820, 155829, 155834, 155839, 155844, + 155849, 155854, 155859, 155864, 155869, 155874, 155879, 155884, 155889, + 155894, 155902, 155910, 155915, 155920, 155925, 155930, 155935, 155941, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155947, 155955, 155963, 155971, + 155979, 155985, 155991, 155995, 155999, 156005, 156011, 156020, 156024, + 156029, 156035, 156039, 156044, 156048, 156052, 156058, 156064, 156074, + 156083, 156086, 156091, 156097, 156103, 156114, 156124, 156128, 156133, + 156139, 156145, 156154, 156159, 156163, 156168, 156172, 156178, 156184, + 156190, 156194, 156197, 156201, 156204, 156207, 156212, 156217, 156224, + 156232, 156239, 156246, 156255, 156264, 156271, 156279, 156286, 156293, + 156302, 156311, 156318, 156326, 156333, 156340, 156349, 156356, 156364, + 156370, 156379, 156387, 156396, 156403, 156413, 156424, 156432, 156440, + 156449, 156457, 156465, 156474, 156482, 156492, 156501, 156509, 156517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 110738, 110743, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156526, 156534, + 156542, 156550, 156558, 156567, 156576, 156585, 156594, 156603, 156612, + 156621, 0, 0, 0, 0, 156630, 156638, 156646, 156654, 156662, 156669, + 156676, 156683, 156690, 156698, 156706, 156714, 156722, 156732, 156742, + 156752, 156762, 156771, 156780, 156789, 156798, 156807, 156816, 156825, + 156834, 156842, 156850, 156858, 156866, 156874, 156882, 156890, 156898, + 156908, 156918, 156928, 156938, 156942, 156946, 156950, 156954, 156957, + 156960, 156963, 156966, 156970, 156974, 156978, 156982, 156987, 156992, + 156997, 157002, 157005, 157008, 157011, 0, 0, 0, 0, 0, 0, 0, 0, 157014, + 157017, 157020, 157023, 157026, 157031, 157036, 157042, 157048, 157052, + 0, 0, 0, 0, 0, 0, 157056, 157062, 157068, 157074, 157080, 157088, 157096, + 157105, 157114, 157119, 157124, 157129, 157134, 157141, 157148, 157156, + 157164, 157171, 157178, 157185, 157192, 157201, 157210, 157220, 157230, + 157236, 157242, 157248, 157254, 157262, 157270, 157279, 157288, 157296, + 157304, 157312, 157320, 157330, 157340, 157351, 0, 0, 0, 0, 0, 0, 0, 0, + 157362, 157367, 157372, 157377, 157382, 157391, 157400, 157409, 157418, + 157425, 157432, 157439, 157446, 157453, 157462, 157471, 157480, 157485, + 157492, 157499, 157506, 157511, 157516, 157521, 157526, 157533, 157540, + 157547, 157554, 157561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157570, 157574, 157578, 157583, 157587, + 157591, 157596, 157600, 157604, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110749, 110754, 110759, - 110764, 110771, 110778, 110785, 110792, 110797, 110802, 110807, 110812, - 110819, 110824, 110831, 110838, 110843, 110848, 110853, 110860, 110865, - 110870, 110877, 110884, 110889, 110894, 110899, 110906, 110913, 110920, - 110925, 110930, 110937, 110944, 110951, 110958, 110963, 110968, 110973, - 110980, 110985, 110990, 110995, 111002, 111011, 111018, 111023, 111028, - 111033, 111038, 111043, 111048, 111057, 111064, 111069, 111076, 111083, - 111088, 111093, 111098, 111105, 111110, 111117, 111124, 111129, 111134, - 111139, 111146, 111153, 111158, 111163, 111170, 111177, 111184, 111189, - 111194, 111199, 111204, 111211, 111220, 111229, 111234, 111241, 111250, - 111255, 111260, 111265, 111270, 111277, 111284, 111291, 111298, 111303, - 111308, 111313, 111320, 111327, 111334, 111339, 111344, 111351, 111356, - 111363, 111368, 111375, 111380, 111387, 111394, 111399, 111404, 111409, - 111414, 111419, 111424, 111429, 111434, 111439, 111446, 111453, 111460, - 111467, 111474, 111483, 111488, 111493, 111500, 111507, 111512, 111519, - 111526, 111533, 111540, 111547, 111554, 111559, 111564, 111569, 111574, - 111579, 111588, 111597, 111606, 111615, 111624, 111633, 111642, 111651, - 111656, 111667, 111678, 111687, 111692, 111697, 111702, 111707, 111716, - 111723, 111730, 111737, 111744, 111751, 111758, 111767, 111776, 111787, - 111796, 111807, 111816, 111823, 111832, 111843, 111852, 111861, 111870, - 111879, 111886, 111893, 111900, 111909, 111918, 111929, 111938, 111947, - 111958, 111963, 111968, 111979, 111987, 111996, 112005, 112014, 112025, - 112034, 112043, 112054, 112065, 112076, 112087, 112098, 112109, 112116, - 112123, 112130, 112137, 112148, 112157, 112164, 112171, 112178, 112189, - 112200, 112211, 112222, 112233, 112244, 112255, 112266, 112273, 112280, - 112289, 112298, 112305, 112312, 112319, 112328, 112337, 112346, 112353, - 112362, 112371, 112380, 112387, 112394, 112399, 112405, 112412, 112419, - 112426, 112433, 112440, 112447, 112456, 112465, 112474, 112483, 112490, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112499, 112505, 112510, 112515, 112522, - 112528, 112534, 112540, 112546, 112552, 112558, 112564, 112568, 112572, - 112578, 112584, 112590, 112594, 112599, 112604, 112608, 112612, 112615, - 112621, 112627, 112633, 112639, 112645, 112651, 112657, 112663, 112669, - 112679, 112689, 112695, 112701, 112711, 112721, 112727, 0, 0, 112733, - 112741, 112746, 112751, 112757, 112763, 112769, 112775, 112781, 112787, - 112794, 112801, 112807, 112813, 112819, 112825, 112831, 112837, 112843, - 112849, 112854, 112860, 112866, 112872, 112878, 112884, 112893, 112899, - 112904, 112912, 112919, 112926, 112935, 112944, 112953, 112962, 112971, - 112980, 112989, 112998, 113008, 113018, 113026, 113034, 113043, 113052, - 113058, 113064, 113070, 113076, 113084, 113092, 113096, 113102, 113107, - 113113, 113119, 113125, 113131, 113137, 113146, 113151, 113158, 113163, - 113168, 113173, 113179, 113185, 113191, 113198, 113203, 113208, 113213, - 113218, 113223, 113229, 113235, 113241, 113247, 113253, 113259, 113265, - 113271, 113276, 113281, 113286, 113291, 113296, 113301, 113306, 113311, - 113317, 113323, 113328, 113333, 113338, 113343, 113348, 113354, 113361, - 113365, 113369, 113373, 113377, 113381, 113385, 113389, 113393, 113401, - 113411, 113415, 113419, 113425, 113431, 113437, 113443, 113449, 113455, - 113461, 113467, 113473, 113479, 113485, 113491, 113497, 113503, 113507, - 113511, 113518, 113524, 113530, 113536, 113541, 113548, 113553, 113559, - 113565, 113571, 113577, 113582, 113586, 113592, 113596, 113600, 113604, - 113610, 113616, 113620, 113626, 113632, 113638, 113644, 113650, 113658, - 113666, 113672, 113678, 113684, 113690, 113702, 113714, 113728, 113740, - 113752, 113766, 113780, 113794, 113798, 113806, 113814, 113819, 113823, - 113827, 113831, 113835, 113839, 113843, 113847, 113853, 113859, 113865, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113871, 113877, 113883, 113889, 113895, - 113901, 113907, 113913, 113919, 113925, 113931, 113937, 113943, 113949, - 113955, 113961, 113967, 113973, 113979, 113985, 113991, 113997, 114003, - 114009, 114015, 114021, 114027, 114033, 114039, 114045, 114051, 114057, - 114063, 114069, 114075, 114081, 114087, 114093, 114099, 114105, 114111, - 114117, 114123, 114129, 114135, 114141, 114147, 114153, 114159, 114165, - 114171, 114177, 114183, 114189, 114195, 114201, 114207, 114213, 114219, - 114225, 114231, 114237, 114243, 114249, 114255, 114261, 114267, 114272, - 114277, 114282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114286, 114291, 114298, - 114305, 114312, 114319, 114324, 114328, 114334, 114338, 114342, 114348, - 114352, 114356, 114360, 114366, 114373, 114377, 114381, 114385, 114389, - 114393, 114397, 114403, 114407, 114411, 114415, 114419, 114423, 114427, - 114431, 114435, 114439, 114443, 114447, 114451, 114456, 114460, 114464, - 114468, 114472, 114476, 114480, 114484, 114488, 114492, 114499, 114503, - 114511, 114515, 114519, 114523, 114527, 114531, 114535, 114539, 114546, - 114550, 114554, 114558, 114562, 114566, 114572, 114576, 114582, 114586, - 114590, 114594, 114598, 114602, 114606, 114610, 114614, 114618, 114622, - 114626, 114630, 114634, 114638, 114642, 114646, 114650, 114654, 114658, - 114666, 114670, 114674, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114678, 114686, - 114694, 114702, 114710, 114718, 114726, 114734, 114742, 114750, 114758, - 114766, 114774, 114782, 114790, 114798, 114806, 114814, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 114822, 114826, 114831, 114836, 114841, 114845, - 114850, 114855, 114860, 114864, 114869, 114874, 114878, 114882, 114887, - 114891, 114896, 114901, 114905, 114910, 114915, 114919, 114924, 114929, - 114934, 114939, 114944, 114948, 114953, 114958, 114963, 114967, 114972, - 114977, 114982, 114986, 114991, 114996, 115000, 115004, 115009, 115013, - 115018, 115023, 115027, 115032, 115037, 115041, 115046, 115051, 115056, - 115061, 115066, 115070, 115075, 115080, 115085, 115089, 115094, 115099, - 115104, 115108, 115113, 115118, 115122, 115126, 115131, 115135, 115140, - 115145, 115149, 115154, 115159, 115163, 115168, 115173, 115178, 115183, - 115188, 115192, 115197, 115202, 115207, 115211, 115216, 0, 115221, - 115225, 115230, 115235, 115239, 115243, 115248, 115252, 115257, 115262, - 115266, 115271, 115276, 115280, 115285, 115290, 115295, 115300, 115305, - 115310, 115316, 115322, 115328, 115333, 115339, 115345, 115351, 115356, - 115362, 115368, 115373, 115378, 115384, 115389, 115395, 115401, 115406, - 115412, 115418, 115423, 115429, 115435, 115441, 115447, 115453, 115458, - 115464, 115470, 115476, 115481, 115487, 115493, 115499, 115504, 115510, - 115516, 115521, 115526, 115532, 115537, 115543, 115549, 115554, 115560, - 115566, 115571, 115577, 115583, 115589, 115595, 115601, 0, 115605, - 115610, 0, 0, 115615, 0, 0, 115620, 115625, 0, 0, 115630, 115635, 115639, - 115644, 0, 115649, 115654, 115659, 115663, 115668, 115673, 115678, - 115683, 115688, 115692, 115697, 115702, 0, 115707, 0, 115712, 115717, - 115721, 115726, 115731, 115735, 115739, 0, 115744, 115749, 115754, - 115758, 115763, 115768, 115772, 115777, 115782, 115787, 115792, 115797, - 115802, 115808, 115814, 115820, 115825, 115831, 115837, 115843, 115848, - 115854, 115860, 115865, 115870, 115876, 115881, 115887, 115893, 115898, - 115904, 115910, 115915, 115921, 115927, 115933, 115939, 115945, 115950, - 115956, 115962, 115968, 115973, 115979, 115985, 115991, 115996, 116002, - 116008, 116013, 116018, 116024, 116029, 116035, 116041, 116046, 116052, - 116058, 116063, 116069, 116075, 116081, 116087, 116093, 116097, 0, - 116102, 116107, 116111, 116116, 0, 0, 116121, 116126, 116131, 116135, - 116139, 116144, 116148, 116153, 0, 116158, 116163, 116168, 116172, - 116177, 116182, 116187, 0, 116192, 116196, 116201, 116206, 116211, - 116215, 116220, 116225, 116230, 116234, 116239, 116244, 116248, 116252, - 116257, 116261, 116266, 116271, 116275, 116280, 116285, 116289, 116294, - 116299, 116304, 116309, 116314, 116318, 0, 116323, 116328, 116332, - 116337, 0, 116342, 116346, 116351, 116356, 116360, 0, 116364, 0, 0, 0, - 116368, 116373, 116378, 116382, 116387, 116392, 116397, 0, 116402, - 116406, 116411, 116416, 116421, 116425, 116430, 116435, 116440, 116444, - 116449, 116454, 116458, 116462, 116467, 116471, 116476, 116481, 116485, - 116490, 116495, 116499, 116504, 116509, 116514, 116519, 116524, 116529, - 116535, 116541, 116547, 116552, 116558, 116564, 116570, 116575, 116581, - 116587, 116592, 116597, 116603, 116608, 116614, 116620, 116625, 116631, - 116637, 116642, 116648, 116654, 116660, 116666, 116672, 116677, 116683, - 116689, 116695, 116700, 116706, 116712, 116718, 116723, 116729, 116735, - 116740, 116745, 116751, 116756, 116762, 116768, 116773, 116779, 116785, - 116790, 116796, 116802, 116808, 116814, 116820, 116824, 116829, 116834, - 116839, 116843, 116848, 116853, 116858, 116862, 116867, 116872, 116876, - 116880, 116885, 116889, 116894, 116899, 116903, 116908, 116913, 116917, - 116922, 116927, 116932, 116937, 116942, 116946, 116951, 116956, 116961, - 116965, 116970, 116975, 116980, 116984, 116989, 116994, 116998, 117002, - 117007, 117011, 117016, 117021, 117025, 117030, 117035, 117039, 117044, - 117049, 117054, 117059, 117064, 117069, 117075, 117081, 117087, 117092, - 117098, 117104, 117110, 117115, 117121, 117127, 117132, 117137, 117143, - 117148, 117154, 117160, 117165, 117171, 117177, 117182, 117188, 117194, - 117200, 117206, 117212, 117217, 117223, 117229, 117235, 117240, 117246, - 117252, 117258, 117263, 117269, 117275, 117280, 117285, 117291, 117296, - 117302, 117308, 117313, 117319, 117325, 117330, 117336, 117342, 117348, - 117354, 117360, 117365, 117371, 117377, 117383, 117388, 117394, 117400, - 117406, 117411, 117417, 117423, 117428, 117433, 117439, 117444, 117450, - 117456, 117461, 117467, 117473, 117478, 117484, 117490, 117496, 117502, - 117508, 117513, 117519, 117525, 117531, 117536, 117542, 117548, 117554, - 117559, 117565, 117571, 117576, 117581, 117587, 117592, 117598, 117604, - 117609, 117615, 117621, 117626, 117632, 117638, 117644, 117650, 117656, - 117662, 117669, 117676, 117683, 117689, 117696, 117703, 117710, 117716, - 117723, 117730, 117736, 117742, 117749, 117755, 117762, 117769, 117775, - 117782, 117789, 117795, 117802, 117809, 117816, 117823, 117830, 117836, - 117843, 117850, 117857, 117863, 117870, 117877, 117884, 117890, 117897, - 117904, 117910, 117916, 117923, 117929, 117936, 117943, 117949, 117956, - 117963, 117969, 117976, 117983, 117990, 117997, 118004, 118009, 118015, - 118021, 118027, 118032, 118038, 118044, 118050, 118055, 118061, 118067, - 118072, 118077, 118083, 118088, 118094, 118100, 118105, 118111, 118117, - 118122, 118128, 118134, 118140, 118146, 118152, 118157, 118163, 118169, - 118175, 118180, 118186, 118192, 118198, 118203, 118209, 118215, 118220, - 118225, 118231, 118236, 118242, 118248, 118253, 118259, 118265, 118270, - 118276, 118282, 118288, 118294, 118300, 118306, 0, 0, 118313, 118318, - 118323, 118328, 118333, 118338, 118343, 118348, 118353, 118358, 118363, - 118368, 118373, 118378, 118383, 118388, 118393, 118398, 118404, 118409, - 118414, 118419, 118424, 118429, 118434, 118439, 118443, 118448, 118453, - 118458, 118463, 118468, 118473, 118478, 118483, 118488, 118493, 118498, - 118503, 118508, 118513, 118518, 118523, 118528, 118534, 118539, 118544, - 118549, 118554, 118559, 118564, 118569, 118575, 118580, 118585, 118590, - 118595, 118600, 118605, 118610, 118615, 118620, 118625, 118630, 118635, - 118640, 118645, 118650, 118655, 118660, 118665, 118670, 118675, 118680, - 118685, 118690, 118696, 118701, 118706, 118711, 118716, 118721, 118726, - 118731, 118735, 118740, 118745, 118750, 118755, 118760, 118765, 118770, - 118775, 118780, 118785, 118790, 118795, 118800, 118805, 118810, 118815, - 118820, 118826, 118831, 118836, 118841, 118846, 118851, 118856, 118861, - 118867, 118872, 118877, 118882, 118887, 118892, 118897, 118903, 118909, - 118915, 118921, 118927, 118933, 118939, 118945, 118951, 118957, 118963, - 118969, 118975, 118981, 118987, 118993, 118999, 119006, 119012, 119018, - 119024, 119030, 119036, 119042, 119048, 119053, 119059, 119065, 119071, - 119077, 119083, 119089, 119095, 119101, 119107, 119113, 119119, 119125, - 119131, 119137, 119143, 119149, 119155, 119162, 119168, 119174, 119180, - 119186, 119192, 119198, 119204, 119211, 119217, 119223, 119229, 119235, - 119241, 119247, 119253, 119259, 119265, 119271, 119277, 119283, 119289, - 119295, 119301, 119307, 119313, 119319, 119325, 119331, 119337, 119343, - 119349, 119356, 119362, 119368, 119374, 119380, 119386, 119392, 119398, - 119403, 119409, 119415, 119421, 119427, 119433, 119439, 119445, 119451, - 119457, 119463, 119469, 119475, 119481, 119487, 119493, 119499, 119505, - 119512, 119518, 119524, 119530, 119536, 119542, 119548, 119554, 119561, - 119567, 119573, 119579, 119585, 119591, 119597, 119604, 119611, 119618, - 119625, 119632, 119639, 119646, 119653, 119660, 119667, 119674, 119681, - 119688, 119695, 119702, 119709, 119716, 119724, 119731, 119738, 119745, - 119752, 119759, 119766, 119773, 119779, 119786, 119793, 119800, 119807, - 119814, 119821, 119828, 119835, 119842, 119849, 119856, 119863, 119870, - 119877, 119884, 119891, 119898, 119906, 119913, 119920, 119927, 119934, - 119941, 119948, 119955, 119963, 119970, 119977, 119984, 119991, 119998, - 120005, 120010, 0, 0, 120015, 120020, 120024, 120028, 120032, 120036, - 120040, 120044, 120048, 120052, 120056, 120061, 120065, 120069, 120073, - 120077, 120081, 120085, 120089, 120093, 120097, 120102, 120106, 120110, - 120114, 120118, 120122, 120126, 120130, 120134, 120138, 120144, 120149, - 120154, 120159, 120164, 120169, 120174, 120179, 120184, 120189, 120195, - 120200, 120205, 120210, 120215, 120220, 120225, 120230, 120235, 120240, - 120244, 120248, 120252, 0, 120256, 120260, 120264, 120268, 120272, - 120276, 120280, 120284, 120288, 120292, 120296, 120300, 120304, 120308, - 120312, 120316, 120320, 120324, 120328, 120332, 120336, 120340, 120344, - 120348, 120354, 120360, 120366, 0, 120372, 120377, 0, 120382, 0, 0, - 120387, 0, 120392, 120397, 120402, 120407, 120412, 120417, 120422, - 120427, 120432, 120437, 0, 120442, 120447, 120452, 120457, 0, 120462, 0, - 120467, 0, 0, 0, 0, 0, 0, 120472, 0, 0, 0, 0, 120478, 0, 120484, 0, - 120490, 0, 120496, 120502, 120508, 0, 120514, 120520, 0, 120526, 0, 0, - 120532, 0, 120538, 0, 120544, 0, 120550, 0, 120558, 0, 120566, 120572, 0, - 120578, 0, 0, 120584, 120590, 120596, 120602, 0, 120608, 120614, 120620, - 120626, 120632, 120638, 120644, 0, 120650, 120656, 120662, 120668, 0, - 120674, 120680, 120686, 120692, 0, 120700, 0, 120708, 120714, 120720, - 120726, 120732, 120738, 120744, 120750, 120756, 120762, 0, 120768, - 120774, 120780, 120786, 120792, 120798, 120804, 120810, 120816, 120822, - 120828, 120834, 120840, 120846, 120852, 120858, 120864, 0, 0, 0, 0, 0, - 120870, 120875, 120880, 0, 120885, 120890, 120895, 120900, 120905, 0, - 120910, 120915, 120920, 120925, 120930, 120935, 120940, 120945, 120950, - 120955, 120960, 120965, 120970, 120975, 120980, 120985, 120990, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157610, 157612, + 157616, 157618, 157620, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 120995, 121005, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121013, - 121020, 121027, 121034, 121041, 121048, 121055, 121061, 121068, 121075, - 121082, 121090, 121098, 121106, 121114, 121122, 121130, 121137, 121144, - 121151, 121159, 121167, 121175, 121183, 121191, 121199, 121206, 121213, - 121220, 121228, 121236, 121244, 121252, 121260, 121268, 121273, 121278, - 121283, 121288, 121293, 121298, 121303, 121308, 121313, 0, 0, 0, 0, - 121318, 121323, 121327, 121331, 121335, 121339, 121343, 121347, 121351, - 121355, 121359, 121363, 121367, 121371, 121375, 121379, 121383, 121387, - 121391, 121395, 121399, 121403, 121407, 121411, 121415, 121419, 121423, - 121427, 121431, 121435, 121439, 121443, 121447, 121451, 121455, 121459, - 121463, 121467, 121471, 121475, 121479, 121483, 121487, 121491, 121495, - 121499, 121503, 121507, 121511, 121515, 121519, 121524, 121528, 121532, - 121536, 121540, 121544, 121548, 121552, 121556, 121560, 121564, 121568, - 121572, 121576, 121580, 121584, 121588, 121592, 121596, 121600, 121604, - 121608, 121612, 121616, 121620, 121624, 121628, 121632, 121636, 121640, - 121644, 121648, 121652, 121656, 121660, 121664, 121668, 121672, 121676, - 121680, 121684, 121688, 121692, 121696, 121700, 121704, 121708, 121712, - 121716, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121720, 121726, 121735, - 121743, 121751, 121760, 121769, 121778, 121787, 121796, 121805, 121814, - 121823, 121832, 121841, 0, 0, 121850, 121859, 121867, 121875, 121884, - 121893, 121902, 121911, 121920, 121929, 121938, 121947, 121956, 121965, - 0, 0, 121974, 121983, 121991, 121999, 122008, 122017, 122026, 122035, - 122044, 122053, 122062, 122071, 122080, 122089, 122098, 0, 122105, - 122114, 122122, 122130, 122139, 122148, 122157, 122166, 122175, 122184, - 122193, 122202, 122211, 122220, 122229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122236, - 122243, 122248, 122252, 122256, 122260, 122265, 122270, 122275, 122280, - 122285, 0, 0, 0, 0, 0, 122290, 122295, 122301, 122307, 122313, 122318, - 122324, 122330, 122336, 122341, 122347, 122353, 122358, 122363, 122369, - 122374, 122380, 122386, 122391, 122397, 122403, 122408, 122414, 122420, - 122426, 122432, 122438, 122449, 122456, 122462, 122465, 0, 122468, - 122473, 122479, 122485, 122491, 122496, 122502, 122508, 122514, 122519, - 122525, 122531, 122536, 122541, 122547, 122552, 122558, 122564, 122569, - 122575, 122581, 122586, 122592, 122598, 122604, 122610, 122616, 122619, - 122622, 122625, 122628, 122631, 122634, 122640, 122647, 122654, 122661, - 122667, 122674, 122681, 122688, 122694, 122701, 122708, 122714, 122720, - 122727, 122733, 122740, 122747, 122753, 122760, 122767, 122773, 122780, - 122787, 122794, 122801, 122808, 122813, 0, 0, 0, 0, 122818, 122824, - 122831, 122838, 122845, 122851, 122858, 122865, 122872, 122878, 122885, - 122892, 122898, 122904, 122911, 122917, 122924, 122931, 122937, 122944, - 122951, 122957, 122964, 122971, 122978, 122985, 122992, 123001, 123005, - 123008, 123011, 123015, 123019, 123022, 123025, 123028, 123031, 123034, - 123037, 123040, 123043, 123046, 123052, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157628, 157632, 157636, 157640, + 157644, 157648, 157652, 157656, 157660, 157664, 157668, 157672, 157676, + 157680, 157684, 157688, 157692, 157696, 157700, 157704, 157708, 157712, + 157716, 157720, 157724, 157728, 157732, 157736, 157740, 157744, 157748, + 157752, 157756, 157760, 157764, 157768, 157772, 157776, 157780, 157784, + 157788, 157792, 157796, 157800, 157804, 157808, 157812, 157816, 157820, + 157824, 157828, 157832, 157836, 157840, 157844, 157848, 157852, 157856, + 157860, 157864, 157868, 157872, 157876, 157880, 157884, 157888, 157892, + 157896, 157900, 157904, 157908, 157912, 157916, 157920, 157924, 157928, + 157932, 157936, 157940, 157944, 157948, 157952, 157956, 157960, 157964, + 157968, 157972, 157976, 157980, 157984, 157988, 157992, 157996, 158000, + 158004, 158008, 158012, 158016, 158020, 158024, 158028, 158032, 158036, + 158040, 158044, 158048, 158052, 158056, 158060, 158064, 158068, 158072, + 158076, 158080, 158084, 158088, 158092, 158096, 158100, 158104, 158108, + 158112, 158116, 158120, 158124, 158128, 158132, 158136, 158140, 158144, + 158148, 158152, 158156, 158160, 158164, 158168, 158172, 158176, 158180, + 158184, 158188, 158192, 158196, 158200, 158204, 158208, 158212, 158216, + 158220, 158224, 158228, 158232, 158236, 158240, 158244, 158248, 158252, + 158256, 158260, 158264, 158268, 158272, 158276, 158280, 158284, 158288, + 158292, 158296, 158300, 158304, 158308, 158312, 158316, 158320, 158324, + 158328, 158332, 158336, 158340, 158344, 158348, 158352, 158356, 158360, + 158364, 158368, 158372, 158376, 158380, 158384, 158388, 158392, 158396, + 158400, 158404, 158408, 158412, 158416, 158420, 158424, 158428, 158432, + 158436, 158440, 158444, 158448, 158452, 158456, 158460, 158464, 158468, + 158472, 158476, 158480, 158484, 158488, 158492, 158496, 158500, 158504, + 158508, 158512, 158516, 158520, 158524, 158528, 158532, 158536, 158540, + 158544, 158548, 158552, 158556, 158560, 158564, 158568, 158572, 158576, + 158580, 158584, 158588, 158592, 158596, 158600, 158604, 158608, 158612, + 158616, 158620, 158624, 158628, 158632, 158636, 158640, 158644, 158648, + 158652, 158656, 158660, 158664, 158668, 158672, 158676, 158680, 158684, + 158688, 158692, 158696, 158700, 158704, 158708, 158712, 158716, 158720, + 158724, 158728, 158732, 158736, 158740, 158744, 158748, 158752, 158756, + 158760, 158764, 158768, 158772, 158776, 158780, 158784, 158788, 158792, + 158796, 158800, 158804, 158808, 158812, 158816, 158820, 158824, 158828, + 158832, 158836, 158840, 158844, 158848, 158852, 158856, 158860, 158864, + 158868, 158872, 158876, 158880, 158884, 158888, 158892, 158896, 158900, + 158904, 158908, 158912, 158916, 158920, 158924, 158928, 158932, 158936, + 158940, 158944, 158948, 158952, 158956, 158960, 158964, 158968, 158972, + 158976, 158980, 158984, 158988, 158992, 158996, 159000, 159004, 159008, + 159012, 159016, 159020, 159024, 159028, 159032, 159036, 159040, 159044, + 159048, 159052, 159056, 159060, 159064, 159068, 159072, 159076, 159080, + 159084, 159088, 159092, 159096, 159100, 159104, 159108, 159112, 159116, + 159120, 159124, 159128, 159132, 159136, 159140, 159144, 159148, 159152, + 159156, 159160, 159164, 159168, 159172, 159176, 159180, 159184, 159188, + 159192, 159196, 159200, 159204, 159208, 159212, 159216, 159220, 159224, + 159228, 159232, 159236, 159240, 159244, 159248, 159252, 159256, 159260, + 159264, 159268, 159272, 159276, 159280, 159284, 159288, 159292, 159296, + 159300, 159304, 159308, 159312, 159316, 159320, 159324, 159328, 159332, + 159336, 159340, 159344, 159348, 159352, 159356, 159360, 159364, 159368, + 159372, 159376, 159380, 159384, 159388, 159392, 159396, 159400, 159404, + 159408, 159412, 159416, 159420, 159424, 159428, 159432, 159436, 159440, + 159444, 159448, 159452, 159456, 159460, 159464, 159468, 159472, 159476, + 159480, 159484, 159488, 159492, 159496, 159500, 159504, 159508, 159512, + 159516, 159520, 159524, 159528, 159532, 159536, 159540, 159544, 159548, + 159552, 159556, 159560, 159564, 159568, 159572, 159576, 159580, 159584, + 159588, 159592, 159596, 159600, 159604, 159608, 159612, 159616, 159620, + 159624, 159628, 159632, 159636, 159640, 159644, 159648, 159652, 159656, + 159660, 159664, 159668, 159672, 159676, 159680, 159684, 159688, 159692, + 159696, 159700, 159704, 159708, 159712, 159716, 159720, 159724, 159728, + 159732, 159736, 159740, 159744, 159748, 159752, 159756, 159760, 159764, + 159768, 159772, 159776, 159780, 159784, 159788, 159792, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123055, 123062, 123070, - 123078, 123086, 123093, 123101, 123109, 123117, 123124, 123132, 123140, - 123147, 123154, 123162, 123169, 123177, 123185, 123192, 123200, 123208, - 123215, 123223, 123231, 123239, 123247, 123255, 123259, 123263, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123266, 123272, 123278, 123284, 123288, - 123294, 123300, 123306, 123312, 123318, 123324, 123330, 123336, 123342, - 123348, 123354, 123360, 123366, 123372, 123378, 123384, 123390, 123396, - 123402, 123408, 123414, 123420, 123426, 123432, 123438, 123444, 123450, - 123456, 123462, 123468, 123474, 123480, 123486, 123492, 123498, 123504, - 123510, 123516, 0, 0, 0, 0, 0, 123522, 123533, 123544, 123555, 123566, - 123577, 123588, 123599, 123610, 0, 0, 0, 0, 0, 0, 0, 123621, 123625, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123629, - 123631, 123633, 123637, 123642, 123647, 123649, 123655, 123660, 123662, - 123668, 123672, 123674, 123678, 123684, 123690, 123696, 123701, 123705, - 123712, 123719, 123726, 123731, 123738, 123745, 123752, 123756, 123762, - 123771, 123780, 123787, 123792, 123796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 123800, 123802, 123804, 123808, 123812, 123816, 0, 123818, - 123820, 123824, 123826, 123828, 123830, 123832, 123837, 123842, 123844, - 123850, 123854, 123858, 123866, 123868, 123870, 123872, 123874, 123876, - 123878, 123880, 123882, 123884, 123886, 123890, 123894, 123896, 123898, - 123900, 123902, 123904, 123909, 123915, 123919, 123923, 123927, 123931, - 123936, 123940, 123942, 123944, 123948, 123954, 123956, 123958, 123960, - 123964, 123973, 123979, 123983, 123987, 123989, 123991, 123994, 123996, - 123998, 124000, 124004, 124006, 124010, 124015, 124017, 124022, 124028, - 124035, 124039, 124043, 124047, 124051, 124057, 0, 0, 0, 124061, 124063, - 124067, 124071, 124073, 124077, 124081, 124083, 124087, 124089, 124093, - 124097, 124101, 124105, 124109, 124113, 124117, 124121, 124127, 124131, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124135, 124139, 124143, 124147, - 124154, 124156, 124160, 124162, 124164, 124168, 124172, 124176, 124178, - 124182, 124186, 124190, 124194, 124198, 124200, 124204, 124206, 124212, - 124215, 124220, 124222, 124224, 124227, 124229, 124231, 124234, 124241, - 124248, 124255, 124260, 124264, 124266, 124268, 0, 124270, 124272, - 124276, 124280, 124284, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 124286, 124290, 124295, 124299, 124305, 124311, 124313, - 124315, 124321, 124323, 124327, 124331, 124333, 124337, 124339, 124343, - 124347, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124351, 124353, - 124355, 124357, 124361, 124363, 124365, 124367, 124369, 124371, 124373, - 124375, 124377, 124379, 124381, 124383, 124385, 124387, 124389, 124391, - 124393, 124395, 124397, 124399, 124401, 124403, 124405, 124409, 124411, - 124413, 124415, 124419, 124421, 124425, 124427, 124429, 124433, 124437, - 124443, 124445, 124447, 124449, 124451, 124455, 124459, 124461, 124465, - 124469, 124473, 124477, 124481, 124485, 124489, 124493, 124497, 124501, - 124505, 124509, 124513, 124517, 124521, 124525, 124529, 0, 124533, 0, - 124535, 124537, 124539, 124541, 124543, 124551, 124559, 124567, 124575, - 124580, 124585, 124590, 124594, 124598, 124603, 124607, 124609, 124613, - 124615, 124617, 124619, 124621, 124623, 124625, 124627, 124631, 124633, - 124635, 124637, 124641, 124645, 124649, 124653, 124657, 124659, 124665, - 124671, 124673, 124675, 124677, 124679, 124681, 124690, 124697, 124704, - 124708, 124715, 124720, 124727, 124736, 124741, 124745, 124749, 124751, - 124755, 124757, 124761, 124765, 124767, 124771, 124775, 124779, 124781, - 124783, 124789, 124791, 124793, 124795, 124799, 124803, 124805, 124809, - 124811, 124813, 124816, 124820, 124822, 124826, 124828, 124830, 124835, - 124837, 124841, 124845, 124848, 124852, 124856, 124860, 124864, 124868, - 124872, 124876, 124881, 124885, 124889, 124898, 124903, 124906, 124908, - 124911, 124914, 124919, 124921, 124924, 124929, 124933, 124936, 124940, - 124944, 124947, 124952, 124956, 124960, 124964, 124968, 124974, 124980, - 124986, 124992, 124997, 125008, 125010, 125014, 125016, 125018, 125022, - 125026, 125028, 125032, 125037, 125042, 125048, 125050, 125054, 125058, - 125065, 125072, 125076, 125078, 125080, 125084, 125086, 125090, 125094, - 125098, 125100, 125102, 125109, 125113, 125116, 125120, 125124, 125128, - 125130, 125134, 125136, 125138, 125142, 125144, 125148, 125152, 125158, - 125162, 125166, 125170, 125172, 125175, 125179, 125186, 125195, 125204, - 125212, 125220, 125222, 125226, 125228, 125232, 125243, 125247, 125253, - 125259, 125264, 0, 125266, 125270, 125272, 125274, 0, 0, 0, 125276, - 125281, 125291, 125306, 125318, 125330, 125334, 125338, 125344, 125346, - 125354, 125362, 125364, 125368, 125374, 125380, 125387, 125394, 125396, - 125398, 125401, 125403, 125409, 125411, 125414, 125418, 125424, 125430, - 125441, 125447, 125454, 125462, 125466, 125474, 125482, 125488, 125494, - 125501, 125503, 125507, 125509, 125511, 125516, 125518, 125520, 125522, - 125524, 125528, 125539, 125545, 125549, 125553, 125557, 125563, 125569, - 125575, 125581, 125586, 125591, 125597, 125603, 125610, 0, 0, 125617, - 125622, 125630, 125634, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 125643, - 125650, 125657, 125664, 125672, 125680, 125688, 125696, 125704, 125712, - 125720, 125728, 125736, 125742, 125748, 125754, 125760, 125766, 125772, - 125778, 125784, 125790, 125796, 125802, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 125808, 125812, 125816, - 125821, 125826, 125828, 125832, 125841, 125849, 125857, 125870, 125883, - 125896, 125903, 125910, 125914, 125923, 125931, 125935, 125944, 125951, - 125955, 125959, 125963, 125967, 125974, 125978, 125982, 125986, 125990, - 125997, 126006, 126015, 126022, 126034, 126046, 126050, 126054, 126058, - 126062, 126066, 126070, 126078, 126086, 126094, 126098, 126102, 126106, - 126110, 126114, 126118, 126124, 126130, 126134, 126145, 126153, 126157, - 126161, 126165, 126169, 126175, 126182, 126193, 126203, 126213, 126224, - 126233, 126244, 126250, 126256, 0, 0, 0, 0, 126262, 126271, 126278, - 126284, 126288, 126292, 126296, 126305, 126317, 126321, 126328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126335, - 126337, 126339, 126343, 126347, 126351, 126360, 126362, 126364, 126367, - 126369, 126371, 126375, 126377, 126381, 126383, 126387, 126389, 126391, - 126395, 126399, 126405, 126407, 126411, 126413, 126417, 126421, 126425, - 126429, 126431, 126433, 126437, 126441, 126445, 126449, 126451, 126453, - 126455, 126460, 126465, 126468, 126476, 126484, 126486, 126491, 126494, - 126499, 126510, 126517, 126522, 126527, 126529, 126533, 126535, 126539, - 126541, 126545, 126549, 126552, 126555, 126557, 126560, 126562, 126566, - 126568, 126570, 126572, 126576, 126578, 126582, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 159796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 159800, 159803, 159807, 159811, + 159814, 159818, 159822, 159825, 159828, 159832, 159836, 159839, 159842, + 159845, 159848, 159853, 159856, 159860, 159863, 159866, 159869, 159872, + 159875, 159878, 159882, 159885, 159889, 159892, 159895, 159899, 159903, + 159907, 159911, 159916, 159921, 159927, 159933, 159939, 159944, 159950, + 159956, 159962, 159967, 159973, 159979, 159984, 159990, 159996, 160001, + 160007, 160013, 160018, 160023, 160029, 160034, 160040, 160046, 160052, + 160058, 160064, 160068, 160073, 160077, 160082, 160086, 160091, 160096, + 160102, 160108, 160114, 160119, 160125, 160131, 160137, 160142, 160148, + 160154, 160159, 160165, 160171, 160176, 160182, 160188, 160193, 160198, + 160204, 160209, 160215, 160221, 160227, 160233, 160239, 160244, 160248, + 160253, 160256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 126585, 126590, 126595, 126600, 126605, 126610, 126615, 126622, - 126629, 126636, 126643, 126648, 126653, 126658, 126663, 126670, 126676, - 126683, 126690, 126697, 126702, 126707, 126712, 126717, 126722, 126729, - 126736, 126741, 126746, 126753, 126760, 126768, 126776, 126783, 126790, - 126798, 126806, 126814, 126821, 126831, 126842, 126847, 126854, 126861, - 126868, 126876, 126884, 126895, 126903, 126911, 126919, 126924, 126929, - 126934, 126939, 126944, 126949, 126954, 126959, 126964, 126969, 126974, - 126979, 126986, 126991, 126996, 127003, 127008, 127013, 127018, 127023, - 127028, 127033, 127038, 127043, 127048, 127053, 127058, 127063, 127070, - 127078, 127083, 127088, 127095, 127100, 127105, 127110, 127117, 127122, - 127129, 127134, 127141, 127146, 127155, 127164, 127169, 127174, 127179, - 127184, 127189, 127194, 127199, 127204, 127209, 127214, 127219, 127224, - 127229, 127237, 127245, 127250, 127255, 127260, 127265, 127270, 127276, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127282, 127286, 127290, 127294, - 127298, 127302, 127306, 127310, 127314, 127318, 127322, 127326, 127330, - 127334, 127338, 127342, 127346, 127350, 127354, 127358, 127362, 127366, - 127370, 127374, 127378, 127382, 127386, 127390, 127394, 127398, 127402, - 127406, 127410, 127414, 127418, 127422, 127426, 127430, 127434, 127438, - 127442, 127446, 127450, 127454, 127458, 127462, 127466, 127470, 127474, - 127478, 127482, 127486, 127490, 127494, 127498, 127502, 127506, 127510, - 127514, 127518, 127522, 127526, 127530, 127534, 127538, 127542, 127546, - 127550, 127554, 127558, 127562, 127566, 127570, 127574, 127578, 127582, - 127586, 127590, 127594, 127598, 127602, 127606, 127610, 127614, 127618, - 127622, 127626, 127630, 127634, 127638, 127642, 127646, 127650, 127654, - 127658, 127662, 127666, 127670, 127674, 127678, 127682, 127686, 127690, - 127694, 127698, 127702, 127706, 127710, 127714, 127718, 127722, 127726, - 127730, 127734, 127738, 127742, 127746, 127750, 127754, 127758, 127762, - 127766, 127770, 127774, 127778, 127782, 127786, 127790, 127794, 127798, - 127802, 127806, 127810, 127814, 127818, 127822, 127826, 127830, 127834, - 127838, 127842, 127846, 127850, 127854, 127858, 127862, 127866, 127870, - 127874, 127878, 127882, 127886, 127890, 127894, 127898, 127902, 127906, - 127910, 127914, 127918, 127922, 127926, 127930, 127934, 127938, 127942, - 127946, 127950, 127954, 127958, 127962, 127966, 127970, 127974, 127978, - 127982, 127986, 127990, 127994, 127998, 128002, 128006, 128010, 128014, - 128018, 128022, 128026, 128030, 128034, 128038, 128042, 128046, 128050, - 128054, 128058, 128062, 128066, 128070, 128074, 128078, 128082, 128086, - 128090, 128094, 128098, 128102, 128106, 128110, 128114, 128118, 128122, - 128126, 128130, 128134, 128138, 128142, 128146, 128150, 128154, 128158, - 128162, 128166, 128170, 128174, 128178, 128182, 128186, 128190, 128194, - 128198, 128202, 128206, 128210, 128214, 128218, 128222, 128226, 128230, - 128234, 128238, 128242, 128246, 128250, 128254, 128258, 128262, 128266, - 128270, 128274, 128278, 128282, 128286, 128290, 128294, 128298, 128302, - 128306, 128310, 128314, 128318, 128322, 128326, 128330, 128334, 128338, - 128342, 128346, 128350, 128354, 128358, 128362, 128366, 128370, 128374, - 128378, 128382, 128386, 128390, 128394, 128398, 128402, 128406, 128410, - 128414, 128418, 128422, 128426, 128430, 128434, 128438, 128442, 128446, - 128450, 128454, 128458, 128462, 128466, 128470, 128474, 128478, 128482, - 128486, 128490, 128494, 128498, 128502, 128506, 128510, 128514, 128518, - 128522, 128526, 128530, 128534, 128538, 128542, 128546, 128550, 128554, - 128558, 128562, 128566, 128570, 128574, 128578, 128582, 128586, 128590, - 128594, 128598, 128602, 128606, 128610, 128614, 128618, 128622, 128626, - 128630, 128634, 128638, 128642, 128646, 128650, 128654, 128658, 128662, - 128666, 128670, 128674, 128678, 128682, 128686, 128690, 128694, 128698, - 128702, 128706, 128710, 128714, 128718, 128722, 128726, 128730, 128734, - 128738, 128742, 128746, 128750, 128754, 128758, 128762, 128766, 128770, - 128774, 128778, 128782, 128786, 128790, 128794, 128798, 128802, 128806, - 128810, 128814, 128818, 128822, 128826, 128830, 128834, 128838, 128842, - 128846, 128850, 128854, 128858, 128862, 128866, 128870, 128874, 128878, - 128882, 128886, 128890, 128894, 128898, 128902, 128906, 128910, 128914, - 128918, 128922, 128926, 128930, 128934, 128938, 128942, 128946, 128950, - 128954, 128958, 128962, 128966, 128970, 128974, 128978, 128982, 128986, - 128990, 128994, 128998, 129002, 129006, 129010, 129014, 129018, 129022, - 129026, 129030, 129034, 129038, 129042, 129046, 129050, 129054, 129058, - 129062, 129066, 129070, 129074, 129078, 129082, 129086, 129090, 129094, - 129098, 129102, 129106, 129110, 129114, 129118, 129122, 129126, 129130, - 129134, 129138, 129142, 129146, 129150, 129154, 129158, 129162, 129166, - 129170, 129174, 129178, 129182, 129186, 129190, 129194, 129198, 129202, - 129206, 129210, 129214, 129218, 129222, 129226, 129230, 129234, 129238, - 129242, 129246, 129250, 129254, 129258, 129262, 129266, 129270, 129274, - 129278, 129282, 129286, 129290, 129294, 129298, 129302, 129306, 129310, - 129314, 129318, 129322, 129326, 129330, 129334, 129338, 129342, 129346, - 129350, 129354, 129358, 129362, 129366, 129370, 129374, 129378, 129382, - 129386, 129390, 129394, 129398, 129402, 129406, 129410, 129414, 129418, - 129422, 129426, 129430, 129434, 129438, 129442, 129446, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129450, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160260, 160263, 160266, 160269, + 160272, 160275, 160278, 160281, 160284, 160287, 160290, 160293, 160296, + 160299, 160302, 160305, 160308, 160311, 160314, 160317, 160320, 160323, + 160326, 160329, 160332, 160335, 160338, 160341, 160344, 160347, 160350, + 160353, 160356, 160359, 160362, 160365, 160368, 160371, 160374, 160377, + 160380, 160383, 160386, 160389, 160392, 160395, 160398, 160401, 160404, + 160407, 160410, 160413, 160416, 160419, 160422, 160425, 160428, 160431, + 160434, 160437, 160440, 160443, 160446, 160449, 160452, 160455, 160458, + 160461, 160464, 160467, 160470, 160473, 160476, 160479, 160482, 160485, + 160488, 160491, 160494, 160497, 160500, 160503, 160506, 160509, 160512, + 160515, 160518, 160521, 160524, 160527, 160530, 160533, 160536, 160539, + 160542, 160545, 160548, 160551, 160554, 160557, 160560, 160563, 160566, + 160569, 160572, 160575, 160578, 160581, 160584, 160587, 160590, 160593, + 160596, 160599, 160602, 160605, 160608, 160611, 160614, 160617, 160620, + 160623, 160626, 160629, 160632, 160635, 160638, 160641, 160644, 160647, + 160650, 160653, 160656, 160659, 160662, 160665, 160668, 160671, 160674, + 160677, 160680, 160683, 160686, 160689, 160692, 160695, 160698, 160701, + 160704, 160707, 160710, 160713, 160716, 160719, 160722, 160725, 160728, + 160731, 160734, 160737, 160740, 160743, 160746, 160749, 160752, 160755, + 160758, 160761, 160764, 160767, 160770, 160773, 160776, 160779, 160782, + 160785, 160788, 160791, 160794, 160797, 160800, 160803, 160806, 160809, + 160812, 160815, 160818, 160821, 160824, 160827, 160830, 160833, 160836, + 160839, 160842, 160845, 160848, 160851, 160854, 160857, 160860, 160863, + 160866, 160869, 160872, 160875, 160878, 160881, 160884, 160887, 160890, + 160893, 160896, 160899, 160902, 160905, 160908, 160911, 160914, 160917, + 160920, 160923, 160926, 160929, 160932, 160935, 160938, 160941, 160944, + 160947, 160950, 160953, 160956, 160959, 160962, 160965, 160968, 160971, + 160974, 160977, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160980, + 160982, 160984, 160989, 160991, 160996, 160998, 161003, 161005, 161010, + 161012, 161014, 161016, 161018, 161020, 161022, 161024, 161026, 161028, + 161031, 161035, 161037, 161039, 161043, 161047, 161052, 161054, 161056, + 161058, 161062, 161065, 161067, 161071, 161073, 161077, 161079, 161083, + 161086, 161088, 161092, 161096, 161098, 161104, 161106, 161111, 161113, + 161118, 161120, 161125, 161127, 161132, 161134, 161137, 161139, 161143, + 161145, 161152, 161154, 161156, 161158, 161163, 161165, 161167, 161169, + 161171, 161173, 161178, 161182, 161184, 161189, 161193, 161195, 161200, + 161204, 161206, 161211, 161215, 161217, 161219, 161221, 161223, 161227, + 161229, 161234, 161236, 161242, 161244, 161250, 161252, 161254, 161256, + 161260, 161262, 161269, 161271, 161278, 161280, 161285, 161291, 161293, + 161299, 161306, 161308, 161314, 161319, 161321, 161327, 161333, 161335, + 161341, 161347, 161349, 161355, 161359, 161361, 161366, 161368, 161370, + 161375, 161377, 161379, 161385, 161387, 161392, 161396, 161398, 161403, + 161407, 161409, 161415, 161417, 161421, 161423, 161427, 161429, 161436, + 161443, 161445, 161452, 161459, 161461, 161466, 161468, 161475, 161477, + 161482, 161484, 161490, 161492, 161496, 161498, 161504, 161506, 161510, + 161512, 161518, 161520, 161522, 161524, 161529, 161534, 161536, 161538, + 161548, 161552, 161559, 161566, 161571, 161576, 161588, 161590, 161592, + 161594, 161596, 161598, 161600, 161602, 161604, 161606, 161608, 161610, + 161612, 161614, 161616, 161618, 161620, 161622, 161624, 161626, 161628, + 161630, 161636, 161643, 161648, 161656, 161664, 161669, 161680, 161682, + 161684, 161686, 161688, 161690, 161692, 161694, 161696, 161698, 161700, + 161702, 161704, 161706, 161708, 161710, 161712, 161717, 161719, 161721, + 161727, 161739, 161750, 161752, 161754, 161756, 161758, 161760, 161762, + 161764, 161766, 161768, 161770, 161772, 161774, 161776, 161778, 161780, + 161782, 161784, 161786, 161788, 161790, 161792, 161794, 161796, 161798, + 161800, 161802, 161804, 161806, 161808, 161810, 161812, 161814, 161816, + 161818, 161820, 161822, 161824, 161826, 161828, 161830, 161832, 161834, + 161836, 161838, 161840, 161842, 161844, 161846, 161848, 161850, 161852, + 161854, 161856, 161858, 161860, 161862, 161864, 161866, 161868, 161870, + 161872, 161874, 161876, 161878, 161880, 161882, 161884, 161886, 161888, + 161890, 161892, 161894, 161896, 161898, 161900, 161902, 161904, 161906, + 161908, 161910, 161912, 161914, 161916, 161918, 161920, 161922, 161924, + 161926, 161928, 161930, 161932, 161934, 161936, 161938, 161940, 161942, + 161944, 161946, 161948, 161950, 161952, 161954, 161956, 161958, 161960, + 161962, 161964, 161966, 161968, 161970, 161972, 161974, 161976, 161978, + 161980, 161982, 161984, 161986, 161988, 161990, 161992, 161994, 161996, + 161998, 162000, 162002, 162004, 162006, 162008, 162010, 162012, 162014, + 162016, 162018, 162020, 162022, 162024, 162026, 162028, 162030, 162032, + 162034, 162036, 162038, 162040, 162042, 162044, 162046, 162048, 162050, + 162052, 162054, 162056, 162058, 162060, 162062, 162064, 162066, 162068, + 162070, 162072, 162074, 162076, 162078, 162080, 162082, 162084, 162086, + 162088, 162090, 162092, 162094, 162096, 162098, 162100, 162102, 162104, + 162106, 162108, 162110, 162112, 162114, 162116, 162118, 162120, 162122, + 162124, 162126, 162128, 162130, 162132, 162134, 162136, 162138, 162140, + 162142, 162144, 162146, 162148, 162150, 162152, 162154, 162156, 162158, + 162160, 162162, 162164, 162166, 162168, 162170, 162172, 162174, 162176, + 162178, 162180, 162182, 162184, 162186, 162188, 162190, 162192, 162194, + 162196, 162198, 162200, 162202, 162204, 162206, 162208, 162210, 162212, + 162214, 162216, 162218, 162220, 162222, 162224, 162226, 162228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 129454, 129457, 129461, 129465, 129468, 129472, 129476, - 129479, 129482, 129486, 129490, 129493, 129496, 129499, 129502, 129507, - 129510, 129514, 129517, 129520, 129523, 129526, 129529, 129532, 129535, - 129538, 129541, 129544, 129547, 129551, 129555, 129559, 129563, 129568, - 129573, 129579, 129585, 129591, 129596, 129602, 129608, 129614, 129619, - 129625, 129631, 129636, 129641, 129647, 129652, 129658, 129664, 129669, - 129675, 129681, 129686, 129692, 129698, 129704, 129710, 129716, 129720, - 129725, 129729, 129734, 129738, 129743, 129748, 129754, 129760, 129766, - 129771, 129777, 129783, 129789, 129794, 129800, 129806, 129811, 129816, - 129822, 129827, 129833, 129839, 129844, 129850, 129856, 129861, 129867, - 129873, 129879, 129885, 129891, 129896, 129900, 129905, 129907, 129911, - 129914, 129917, 129920, 129923, 129926, 129929, 129932, 129935, 129938, - 129941, 129944, 129947, 129950, 129953, 129956, 129959, 129962, 129965, - 129968, 129971, 129974, 129977, 129980, 129983, 129986, 129989, 129992, - 129995, 129998, 130001, 130004, 130007, 130010, 130013, 130016, 130019, - 130022, 130025, 130028, 130031, 130034, 130037, 130040, 130043, 130046, - 130049, 130052, 130055, 130058, 130061, 130064, 130067, 130070, 130073, - 130076, 130079, 130082, 130085, 130088, 130091, 130094, 130097, 130100, - 130103, 130106, 130109, 130112, 130115, 130118, 130121, 130124, 130127, - 130130, 130133, 130136, 130139, 130142, 130145, 130148, 130151, 130154, - 130157, 130160, 130163, 130166, 130169, 130172, 130175, 130178, 130181, - 130184, 130187, 130190, 130193, 130196, 130199, 130202, 130205, 130208, - 130211, 130214, 130217, 130220, 130223, 130226, 130229, 130232, 130235, - 130238, 130241, 130244, 130247, 130250, 130253, 130256, 130259, 130262, - 130265, 130268, 130271, 130274, 130277, 130280, 130283, 130286, 130289, - 130292, 130295, 130298, 130301, 130304, 130307, 130310, 130313, 130316, - 130319, 130322, 130325, 130328, 130331, 130334, 130337, 130340, 130343, - 130346, 130349, 130352, 130355, 130358, 130361, 130364, 130367, 130370, - 130373, 130376, 130379, 130382, 130385, 130388, 130391, 130394, 130397, - 130400, 130403, 130406, 130409, 130412, 130415, 130418, 130421, 130424, - 130427, 130430, 130433, 130436, 130439, 130442, 130445, 130448, 130451, - 130454, 130457, 130460, 130463, 130466, 130469, 130472, 130475, 130478, - 130481, 130484, 130487, 130490, 130493, 130496, 130499, 130502, 130505, - 130508, 130511, 130514, 130517, 130520, 130523, 130526, 130529, 130532, - 130535, 130538, 130541, 130544, 130547, 130550, 130553, 130556, 130559, - 130562, 130565, 130568, 130571, 130574, 130577, 130580, 130583, 130586, - 130589, 130592, 130595, 130598, 130601, 130604, 130607, 130610, 130613, - 130616, 130619, 130622, 130625, 130628, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 130631, 130633, 130635, 130640, 130642, 130647, 130649, - 130654, 130656, 130661, 130663, 130665, 130667, 130669, 130671, 130673, - 130675, 130677, 130679, 130682, 130685, 130687, 130689, 130693, 130696, - 130701, 130703, 130705, 130707, 130711, 130714, 130716, 130720, 130722, - 130726, 130728, 130732, 130735, 130737, 130741, 130745, 130747, 130753, - 130755, 130760, 130762, 130767, 130769, 130774, 130776, 130781, 130783, - 130786, 130788, 130792, 130794, 130801, 130803, 130805, 130807, 130812, - 130814, 130816, 130818, 130820, 130822, 130827, 130831, 130833, 130838, - 130842, 130844, 130849, 130853, 130855, 130860, 130864, 130866, 130868, - 130870, 130872, 130876, 130878, 130883, 130885, 130891, 130893, 130899, - 130901, 130903, 130905, 130909, 130911, 130918, 130920, 130927, 130929, - 130934, 130939, 130941, 130947, 130953, 130955, 130961, 130966, 130968, - 130974, 130980, 130982, 130988, 130994, 130996, 131002, 131006, 131008, - 131013, 131015, 131017, 131022, 131024, 131026, 131032, 131034, 131039, - 131043, 131045, 131050, 131054, 131056, 131062, 131064, 131068, 131070, - 131074, 131076, 131083, 131090, 131092, 131099, 131106, 131108, 131113, - 131115, 131122, 131124, 131129, 131131, 131137, 131139, 131143, 131145, - 131151, 131153, 131157, 131159, 131165, 131167, 131169, 131171, 131176, - 131181, 131183, 131185, 131194, 131198, 131205, 131212, 131217, 131222, - 131234, 131236, 131238, 131240, 131242, 131244, 131246, 131248, 131250, - 131252, 131254, 131256, 131258, 131260, 131262, 131264, 131266, 131268, - 131270, 131272, 131274, 131276, 131282, 131289, 131294, 131299, 131310, - 131312, 131314, 131316, 131318, 131320, 131322, 131324, 131326, 131328, - 131330, 131332, 131334, 131336, 131338, 131340, 131342, 131347, 131349, - 131351, 131357, 131369, 131380, 131382, 131384, 131386, 131388, 131390, - 131392, 131394, 131396, 131398, 131400, 131402, 131404, 131406, 131408, - 131410, 131412, 131414, 131416, 131418, 131420, 131422, 131424, 131426, - 131428, 131430, 131432, 131434, 131436, 131438, 131440, 131442, 131444, - 131446, 131448, 131450, 131452, 131454, 131456, 131458, 131460, 131462, - 131464, 131466, 131468, 131470, 131472, 131474, 131476, 131478, 131480, - 131482, 131484, 131486, 131488, 131490, 131492, 131494, 131496, 131498, - 131500, 131502, 131504, 131506, 131508, 131510, 131512, 131514, 131516, - 131518, 131520, 131522, 131524, 131526, 131528, 131530, 131532, 131534, - 131536, 131538, 131540, 131542, 131544, 131546, 131548, 131550, 131552, - 131554, 131556, 131558, 131560, 131562, 131564, 131566, 131568, 131570, - 131572, 131574, 131576, 131578, 131580, 131582, 131584, 131586, 131588, - 131590, 131592, 131594, 131596, 131598, 131600, 131602, 131604, 131606, - 131608, 131610, 131612, 131614, 131616, 131618, 131620, 131622, 131624, - 131626, 131628, 131630, 131632, 131634, 131636, 131638, 131640, 131642, - 131644, 131646, 131648, 131650, 131652, 131654, 131656, 131658, 131660, - 131662, 131664, 131666, 131668, 131670, 131672, 131674, 131676, 131678, - 131680, 131682, 131684, 131686, 131688, 131690, 131692, 131694, 131696, - 131698, 131700, 131702, 131704, 131706, 131708, 131710, 131712, 131714, - 131716, 131718, 131720, 131722, 131724, 131726, 131728, 131730, 131732, - 131734, 131736, 131738, 131740, 131742, 131744, 131746, 131748, 131750, - 131752, 131754, 131756, 131758, 131760, 131762, 131764, 131766, 131768, - 131770, 131772, 131774, 131776, 131778, 131780, 131782, 131784, 131786, - 131788, 131790, 131792, 131794, 131796, 131798, 131800, 131802, 131804, - 131806, 131808, 131810, 131812, 131814, 131816, 131818, 131820, 131822, - 131824, 131826, 131828, 131830, 131832, 131834, 131836, 131838, 131840, - 131842, 131844, 131846, 131848, 131850, 131852, 131854, 131856, 131858, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 162230, 162240, 162250, 162259, 162268, 162281, 162294, 162306, + 162318, 162328, 162338, 162348, 162358, 162369, 162380, 162390, 162399, + 162408, 162417, 162430, 162443, 162455, 162467, 162477, 162487, 162497, + 162507, 162516, 162525, 162535, 162545, 162554, 162563, 162573, 162583, + 162592, 162601, 162611, 162621, 162632, 162643, 162653, 162666, 162677, + 162691, 162699, 162710, 162718, 162726, 162734, 162742, 162750, 162758, + 162767, 162776, 162786, 162796, 162805, 162814, 162824, 162834, 162842, + 162850, 162857, 162867, 162876, 162884, 162891, 162901, 162910, 162921, + 162932, 162944, 162955, 162965, 162976, 162986, 162997, 163005, 163009, + 163013, 163017, 163021, 163025, 163029, 163033, 163037, 163041, 163045, + 163049, 163053, 163056, 163059, 163063, 163067, 163071, 163075, 163079, + 163083, 163087, 163091, 163094, 163098, 163102, 163106, 163110, 163114, + 163118, 163122, 163126, 163130, 163134, 163138, 163142, 163146, 163150, + 163154, 163158, 163162, 163166, 163170, 163174, 163178, 163182, 163186, + 163190, 163194, 163198, 163202, 163206, 163210, 163214, 163218, 163222, + 163226, 163230, 163234, 163238, 163242, 163246, 163250, 163254, 163258, + 163262, 163266, 163270, 163274, 163278, 163282, 163286, 163290, 163294, + 163298, 163302, 163306, 163310, 163314, 163318, 163322, 163326, 163330, + 163334, 163338, 163342, 163346, 163350, 163354, 163358, 163362, 163366, + 163370, 163374, 163378, 163382, 163386, 163390, 163394, 163398, 163401, + 163405, 163409, 163413, 163417, 163421, 163425, 163429, 163433, 163437, + 163441, 163445, 163449, 163453, 163457, 163461, 163465, 163469, 163473, + 163477, 163481, 163485, 163489, 163493, 163497, 163501, 163505, 163509, + 163513, 163517, 163521, 163525, 163529, 163533, 163537, 163541, 163545, + 163549, 163553, 163557, 163561, 163565, 163569, 163573, 163577, 163581, + 163585, 163589, 163593, 163597, 163601, 163605, 163609, 163613, 163617, + 163621, 163625, 163629, 163633, 163637, 163641, 163645, 163649, 163653, + 163657, 163661, 163665, 163669, 163673, 163677, 163681, 163685, 163689, + 163693, 163697, 163701, 163705, 163709, 163713, 163717, 163721, 163725, + 163729, 163733, 163737, 163741, 163745, 163749, 163753, 163757, 163761, + 163765, 163769, 163773, 163777, 163781, 163785, 163789, 163793, 163797, + 163801, 163805, 163809, 163813, 163817, 163821, 163825, 163829, 163833, + 163837, 163841, 163845, 163849, 163853, 163857, 163861, 163865, 163869, + 163873, 163877, 163881, 163885, 163889, 163893, 163897, 163901, 163905, + 163909, 163913, 163917, 163921, 163925, 163929, 163933, 163937, 163941, + 163945, 163949, 163953, 163957, 163961, 163965, 163969, 163973, 163977, + 163981, 163985, 163989, 163993, 163997, 164001, 164005, 164009, 164013, + 164017, 164021, 164025, 164029, 164033, 164037, 164041, 164045, 164049, + 164053, 164057, 164061, 164065, 164069, 164073, 164077, 164081, 164085, + 164089, 164093, 164097, 164101, 164105, 164109, 164113, 164117, 164121, + 164125, 164129, 164133, 164137, 164141, 164145, 164149, 164153, 164157, + 164161, 164165, 164170, 164175, 164180, 164184, 164190, 164197, 164204, + 164211, 164218, 164225, 164232, 164239, 164246, 164253, 164260, 164267, + 164274, 164281, 164288, 164295, 164302, 164308, 164315, 164322, 164329, + 164336, 164343, 164350, 164357, 164364, 164371, 164378, 164385, 164392, + 164399, 164406, 164412, 164419, 164426, 164435, 164444, 164453, 164462, + 164467, 164472, 164478, 164484, 164490, 164496, 164502, 164508, 164514, + 164520, 164526, 164532, 164538, 164544, 164549, 164555, 164565, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 131860, 131870, 131880, 131889, 131898, 131911, - 131924, 131936, 131948, 131958, 131968, 131978, 131988, 131999, 132010, - 132020, 132029, 132038, 132047, 132060, 132073, 132085, 132097, 132107, - 132117, 132127, 132137, 132146, 132155, 132164, 132173, 132182, 132191, - 132200, 132209, 132218, 132227, 132236, 132245, 132256, 132266, 132276, - 132289, 132299, 132312, 132319, 132329, 132336, 132343, 132350, 132357, - 132364, 132371, 132380, 132389, 132398, 132407, 132416, 132425, 132434, - 132443, 132451, 132459, 132466, 132476, 132485, 132493, 132500, 132510, - 132519, 132529, 132539, 132550, 132560, 132569, 132579, 132588, 132598, - 132606, 132610, 132614, 132618, 132622, 132626, 132630, 132634, 132638, - 132642, 132646, 132649, 132653, 132656, 132659, 132663, 132667, 132671, - 132675, 132679, 132683, 132687, 132691, 132695, 132699, 132703, 132707, - 132711, 132715, 132719, 132723, 132727, 132731, 132735, 132739, 132743, - 132747, 132751, 132755, 132759, 132763, 132767, 132771, 132775, 132779, - 132783, 132787, 132791, 132795, 132799, 132803, 132807, 132811, 132815, - 132819, 132823, 132827, 132831, 132835, 132839, 132843, 132847, 132851, - 132855, 132859, 132863, 132867, 132871, 132875, 132879, 132883, 132887, - 132891, 132895, 132899, 132903, 132907, 132911, 132915, 132919, 132923, - 132927, 132931, 132935, 132939, 132943, 132947, 132951, 132955, 132959, - 132963, 132967, 132971, 132975, 132979, 132983, 132987, 132991, 132995, - 132999, 133002, 133006, 133010, 133014, 133018, 133022, 133026, 133030, - 133034, 133038, 133042, 133046, 133050, 133054, 133058, 133062, 133066, - 133070, 133074, 133078, 133082, 133086, 133090, 133094, 133098, 133102, - 133106, 133110, 133114, 133118, 133122, 133126, 133130, 133134, 133138, - 133142, 133146, 133150, 133154, 133158, 133162, 133166, 133170, 133174, - 133178, 133182, 133186, 133190, 133194, 133198, 133202, 133206, 133210, - 133214, 133218, 133222, 133226, 133230, 133234, 133238, 133242, 133246, - 133250, 133254, 133258, 133262, 133266, 133270, 133274, 133278, 133282, - 133286, 133290, 133294, 133298, 133302, 133306, 133310, 133314, 133318, - 133322, 133326, 133330, 133334, 133338, 133342, 133346, 133350, 133354, - 133358, 133362, 133366, 133370, 133374, 133378, 133382, 133386, 133390, - 133394, 133398, 133402, 133406, 133410, 133414, 133418, 133422, 133426, - 133430, 133434, 133438, 133442, 133446, 133450, 133454, 133458, 133462, - 133466, 133470, 133474, 133478, 133482, 133486, 133490, 133494, 133498, - 133502, 133506, 133510, 133514, 133518, 133522, 133526, 133530, 133534, - 133538, 133542, 133546, 133550, 133554, 133558, 133562, 133566, 133570, - 133574, 133578, 133582, 133586, 133590, 133594, 133598, 133602, 133606, - 133610, 133614, 133618, 133622, 133626, 133630, 133634, 133638, 133642, - 133646, 133650, 133654, 133658, 133662, 133666, 133670, 133674, 133678, - 133682, 133686, 133690, 133694, 133698, 133702, 133706, 133710, 133714, - 133718, 133722, 133726, 133730, 133734, 133738, 133742, 133746, 133750, - 133754, 133758, 133762, 133766, 133771, 133776, 133781, 133785, 133791, - 133798, 133805, 133812, 133819, 133826, 133833, 133840, 133847, 133854, - 133861, 133868, 133875, 133882, 133888, 133895, 133902, 133908, 133915, - 133922, 133929, 133936, 133943, 133950, 133957, 133964, 133971, 133978, - 133985, 133992, 133999, 134005, 134011, 134018, 134025, 134034, 134043, - 134052, 134061, 134066, 134071, 134077, 134083, 134089, 134095, 134101, - 134107, 134113, 134119, 134125, 134131, 134137, 134143, 134148, 134154, - 134164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 unsigned int code_hash[] = { - 74224, 4851, 0, 78156, 78499, 128685, 7929, 0, 194682, 127766, 78500, - 66480, 0, 42833, 74529, 12064, 0, 596, 983821, 69850, 13192, 8651, 0, 0, - 120218, 12995, 64865, 1373, 0, 0, 5816, 119067, 64810, 4231, 6825, 42897, - 4233, 4234, 4232, 917836, 74415, 120210, 6384, 917840, 78108, 8851, 0, - 128553, 0, 41601, 8874, 983783, 7748, 0, 0, 0, 127939, 41603, 9784, 0, - 9188, 41600, 0, 120618, 128343, 1457, 3535, 0, 0, 0, 0, 65240, 11951, 0, - 3404, 0, 0, 0, 1759, 0, 41076, 68383, 120572, 119205, 66577, 94014, - 127764, 65859, 0, 7404, 0, 0, 0, 0, 65908, 9834, 3055, 9852, 983860, - 65288, 0, 11398, 0, 92417, 119255, 0, 0, 603, 74398, 43548, 0, 0, 917824, - 3350, 120817, 64318, 917828, 127089, 3390, 74483, 43265, 120599, 917830, - 78573, 0, 1919, 3400, 120651, 127944, 11647, 917540, 66446, 64141, 8562, - 2121, 64138, 4043, 8712, 64134, 64133, 11297, 983688, 983152, 11966, - 64128, 128587, 0, 0, 64132, 10867, 64130, 64129, 983844, 43374, 9779, - 2764, 66002, 10167, 9471, 0, 66021, 0, 0, 5457, 5440, 8857, 93981, 65282, - 2843, 5355, 127928, 983965, 0, 5194, 11657, 43984, 128292, 0, 983620, 0, - 0, 127027, 10717, 64570, 5630, 5396, 64143, 10682, 0, 10602, 800, 42499, - 66186, 0, 0, 64930, 11631, 64146, 64145, 64144, 762, 13172, 118859, - 194661, 64468, 10906, 1353, 6960, 0, 0, 5828, 8724, 917806, 8933, 1601, - 42244, 858, 7080, 64109, 64108, 8090, 0, 74401, 917811, 587, 0, 128131, - 0, 0, 0, 78214, 2750, 74218, 556, 64158, 64157, 983949, 12213, 194678, - 2760, 0, 0, 0, 194794, 64156, 64155, 42496, 0, 64151, 64150, 12679, - 10053, 10421, 11093, 64153, 64152, 0, 0, 4839, 0, 0, 1874, 119016, 0, - 6577, 64125, 64124, 64123, 0, 127531, 92534, 7007, 7590, 65443, 9036, - 92550, 64122, 74422, 66609, 0, 64117, 64116, 6287, 64114, 2725, 64120, - 64119, 43981, 42128, 127842, 1177, 65601, 12322, 64106, 69640, 127306, - 64102, 7859, 1945, 64099, 0, 10453, 64104, 7188, 7997, 0, 7389, 983161, - 8705, 64097, 64096, 9571, 528, 128671, 44017, 11429, 71347, 0, 983077, - 917990, 73841, 0, 0, 9056, 64313, 6188, 120019, 6155, 64068, 1823, 64066, - 64065, 64072, 64071, 63, 7233, 92212, 0, 41904, 6639, 64064, 983775, - 128344, 0, 1176, 118959, 127930, 8162, 128667, 983831, 0, 120519, 66376, - 66242, 11415, 4333, 9855, 64112, 64642, 0, 5388, 0, 0, 0, 7714, 66222, - 69902, 7768, 0, 4199, 64708, 983421, 0, 0, 8708, 9560, 64077, 64076, - 8996, 4992, 4471, 42622, 64079, 64078, 92179, 0, 126570, 0, 64615, 41915, - 0, 12075, 70062, 0, 5174, 983217, 0, 127557, 3123, 0, 12685, 127904, - 8408, 64704, 0, 0, 9223, 0, 41616, 67999, 73797, 0, 1116, 128204, 43049, - 7136, 43050, 8548, 120485, 0, 119061, 917999, 0, 13115, 43675, 64091, - 9322, 0, 120595, 64095, 64094, 8111, 66247, 42332, 64089, 64088, 6199, 0, - 0, 11434, 64083, 64082, 11329, 7737, 64087, 64086, 64085, 64084, 194817, - 9927, 41335, 4118, 1797, 0, 41334, 0, 46, 43448, 127881, 298, 0, 128114, - 0, 42627, 0, 32, 6187, 119052, 11495, 11459, 3665, 983600, 42871, 0, - 19923, 74335, 0, 127192, 66239, 42264, 64403, 4412, 7240, 92495, 0, - 983466, 65758, 12750, 4181, 8544, 0, 120199, 917897, 120198, 69809, 6181, - 65014, 0, 0, 983196, 3639, 119588, 0, 0, 118904, 10073, 120206, 128862, - 127186, 68409, 42844, 7498, 1098, 92565, 120205, 0, 983118, 10207, 8789, - 983225, 0, 0, 983472, 9234, 0, 6182, 983474, 65058, 0, 983478, 983475, 0, - 5471, 9461, 5573, 118936, 5473, 44, 0, 66244, 94072, 0, 66238, 12844, 0, - 1622, 7767, 1900, 41339, 11458, 0, 0, 6581, 5576, 0, 64405, 41337, 0, - 41631, 8947, 68390, 127844, 41694, 0, 0, 7908, 0, 10408, 6579, 0, 64618, - 0, 120147, 2138, 6583, 7761, 127010, 120504, 194828, 0, 5058, 41010, - 9992, 128299, 5057, 0, 0, 74538, 5054, 118951, 194971, 78606, 0, 1437, - 41617, 658, 3497, 128509, 7486, 5061, 5060, 4235, 127878, 0, 128529, - 12113, 4236, 4727, 0, 0, 7693, 10749, 0, 7488, 5773, 978, 128134, 0, - 41619, 10239, 68611, 0, 66209, 0, 128700, 9748, 983956, 127524, 0, 0, 0, - 0, 195083, 0, 983843, 0, 0, 0, 0, 0, 9341, 119596, 2379, 11325, 0, 64668, - 67854, 8125, 120545, 6743, 119175, 917940, 2369, 0, 983972, 983973, - 119235, 74092, 73936, 7008, 43660, 0, 0, 0, 2367, 127827, 983857, 264, - 2375, 8060, 6194, 119858, 1844, 119084, 0, 6019, 0, 0, 6961, 0, 118839, - 0, 8800, 0, 42862, 4463, 65581, 6192, 194676, 42771, 0, 92333, 725, - 65042, 118797, 120800, 983040, 12892, 0, 0, 0, 0, 0, 0, 127261, 120707, - 983128, 0, 5074, 5073, 128790, 8983, 118981, 74493, 983561, 5072, 93977, - 6198, 11614, 0, 196, 0, 0, 0, 4929, 120342, 0, 0, 0, 0, 42847, 0, 0, 0, - 4934, 0, 41323, 9758, 0, 92289, 127917, 42584, 0, 4329, 41321, 4979, - 3048, 7752, 41320, 983042, 74418, 12819, 0, 5071, 0, 3642, 0, 5070, - 10042, 118835, 3987, 5068, 0, 8909, 78650, 78649, 69917, 10636, 73981, - 11806, 43167, 4531, 1245, 9105, 66463, 4921, 120219, 4926, 65544, 73884, - 194619, 0, 0, 64709, 0, 194620, 78880, 4922, 325, 992, 119568, 4925, 0, - 0, 9526, 4920, 0, 948, 0, 120208, 4930, 0, 92175, 120275, 4933, 120211, - 0, 118985, 4928, 0, 0, 74770, 120194, 126548, 722, 194934, 19908, 12637, - 127485, 119855, 8753, 1509, 0, 5468, 9511, 127474, 127477, 1672, 6205, - 10864, 74586, 127480, 70103, 127466, 78555, 127468, 73863, 126577, - 126503, 41607, 120115, 1679, 120116, 120180, 120113, 127462, 7005, 41609, - 9580, 0, 401, 69949, 43779, 6968, 5761, 342, 8553, 0, 8143, 127115, - 11983, 92249, 624, 74508, 4057, 43788, 5078, 74258, 12478, 0, 5076, 0, - 194609, 0, 8295, 685, 9025, 1524, 12618, 0, 5539, 0, 92523, 120102, 7138, - 120552, 0, 194611, 78752, 0, 12520, 8058, 9732, 0, 5080, 64775, 5036, - 5035, 120590, 42604, 983656, 0, 8074, 275, 13291, 1907, 78838, 4432, - 127271, 5033, 127273, 127272, 4836, 3888, 73792, 10729, 64546, 127262, - 43704, 127264, 127251, 67588, 119000, 127252, 127255, 8858, 6409, 127256, - 120252, 128100, 0, 0, 66321, 0, 12814, 127248, 3432, 10218, 0, 6094, - 7641, 42445, 0, 92487, 42406, 1676, 74320, 194607, 983177, 5030, 0, 0, 0, - 73869, 9622, 0, 69944, 6787, 0, 0, 0, 983583, 10544, 12919, 0, 92218, 0, - 0, 69906, 120789, 0, 947, 119835, 194586, 194585, 10969, 119935, 7613, + 74224, 4851, 125138, 78156, 78499, 72391, 7929, 66910, 194682, 127766, + 78500, 66480, 64038, 42833, 74529, 12064, 72385, 596, 983821, 69850, + 13192, 8651, 120217, 126542, 120218, 12995, 64865, 1373, 119856, 113752, + 5816, 119067, 64810, 4231, 6825, 42897, 4233, 4234, 4232, 120889, 74415, + 120210, 6384, 70351, 78108, 8851, 67698, 128553, 82954, 41601, 8874, + 72392, 7748, 125083, 0, 127026, 127939, 41603, 9784, 0, 9188, 41600, 0, + 120618, 128343, 1457, 3535, 128635, 6381, 0, 0, 65240, 11951, 0, 3404, + 983079, 70487, 72411, 1759, 120853, 41076, 68383, 69972, 119205, 66577, + 94014, 127764, 65859, 0, 7404, 0, 0, 69970, 128387, 65908, 9834, 3055, + 9852, 128360, 65288, 121291, 11398, 0, 92417, 93016, 128380, 127337, 603, + 74398, 43548, 0, 71865, 917824, 3350, 120817, 64318, 194698, 78121, 3390, + 74483, 43265, 92399, 917830, 78573, 118803, 1919, 3400, 120651, 83296, + 11647, 83298, 66446, 64141, 8562, 2121, 64138, 4043, 8712, 64134, 64133, + 11297, 983688, 983152, 11966, 64128, 66286, 93042, 128830, 64132, 10867, + 64130, 64129, 121255, 43374, 9779, 2764, 66002, 10167, 9471, 83458, + 66021, 74509, 0, 5457, 5440, 8857, 93981, 65282, 2843, 5355, 68858, + 983342, 69971, 5194, 11657, 43984, 128292, 113724, 128872, 0, 0, 72393, + 10717, 64570, 5630, 5396, 64143, 10682, 83300, 10602, 800, 42499, 66186, + 0, 0, 64930, 11631, 64146, 64145, 64144, 762, 13172, 75008, 77928, 43929, + 10906, 1353, 6960, 83032, 128779, 5828, 8724, 917806, 8933, 1601, 42244, + 858, 7080, 64109, 64108, 8090, 70455, 72388, 74606, 587, 917907, 82971, + 0, 0, 0, 78214, 2750, 74218, 556, 64158, 64157, 78707, 12213, 83290, + 2760, 83284, 83285, 78708, 83287, 64156, 64155, 42496, 83283, 64151, + 64150, 12679, 10053, 10421, 11093, 64153, 64152, 125016, 0, 4839, 68527, + 0, 1874, 119016, 120091, 6577, 64125, 64124, 64123, 0, 127531, 92534, + 7007, 7590, 65443, 9036, 78847, 64122, 66389, 66609, 121347, 64117, + 64116, 6287, 64114, 2725, 64120, 64119, 43981, 42128, 127842, 1177, + 65601, 12322, 64106, 69640, 92895, 64102, 7859, 1945, 64099, 0, 10453, + 64104, 7188, 7997, 0, 7389, 983161, 8705, 64097, 64096, 9571, 528, + 128545, 44017, 11429, 71347, 0, 983077, 120864, 73841, 83339, 83340, + 9056, 64313, 6188, 74360, 6155, 64068, 1823, 64066, 64065, 64072, 64071, + 63, 7233, 92212, 72414, 41904, 6639, 64064, 983775, 128344, 121388, 1176, + 118959, 127930, 8162, 127019, 128197, 92747, 120519, 42931, 66242, 11415, + 4333, 9855, 64112, 64642, 0, 5388, 0, 121271, 983649, 7714, 66222, 69902, + 7768, 72403, 4199, 64708, 65064, 70117, 0, 8708, 9560, 64077, 64076, + 8996, 4992, 4471, 42622, 64079, 64078, 92179, 71878, 126570, 121256, + 64615, 41915, 0, 12075, 42041, 194825, 5174, 983217, 0, 127557, 3123, + 125100, 12685, 119216, 8408, 64704, 83328, 0, 9223, 0, 41616, 67999, + 73797, 83327, 1116, 75067, 43049, 7136, 43050, 8548, 120485, 0, 75031, + 917622, 128168, 13115, 43675, 64091, 9322, 83338, 83331, 64095, 64094, + 8111, 66247, 42332, 64089, 64088, 6199, 67249, 66398, 11434, 64083, + 64082, 11329, 7737, 64087, 64086, 64085, 64084, 83033, 9927, 41335, 4118, + 1797, 83312, 41334, 0, 46, 43448, 83309, 298, 83303, 83304, 83305, 42627, + 125011, 32, 6187, 83037, 11495, 11459, 3665, 83036, 42871, 0, 19923, + 74335, 0, 127192, 66239, 42264, 64403, 4412, 7240, 83314, 71444, 983468, + 65758, 12750, 4181, 8544, 83461, 68053, 83407, 120198, 69809, 6181, + 65014, 983422, 128484, 983196, 3639, 119588, 118851, 83039, 118904, + 10073, 120206, 83038, 127186, 68409, 42844, 7498, 1098, 92565, 120205, 0, + 128915, 10207, 8789, 93070, 120338, 92973, 128325, 9234, 917895, 6182, + 983475, 65058, 120319, 983480, 68064, 917831, 5471, 9461, 5573, 118936, + 5473, 44, 0, 66244, 94072, 0, 66238, 12844, 66894, 1622, 7767, 1900, + 41339, 11458, 119061, 0, 6581, 5576, 128618, 43855, 41337, 0, 41631, + 8947, 68390, 69683, 41694, 983848, 72396, 7908, 0, 10408, 6579, 917872, + 64618, 0, 120147, 2138, 6583, 7761, 70005, 120504, 194828, 128961, 5058, + 41010, 9992, 128299, 5057, 917941, 0, 74538, 5054, 118951, 194971, 78606, + 0, 1437, 41617, 658, 3497, 128509, 7486, 5061, 5060, 4235, 127878, + 128322, 128529, 12113, 4236, 4727, 128487, 0, 7693, 10749, 120332, 7488, + 5773, 978, 128134, 983699, 41619, 10239, 68611, 71864, 66209, 127233, + 74135, 9748, 983956, 127524, 0, 983316, 194676, 194675, 128081, 0, + 983313, 983302, 0, 127865, 0, 92776, 9341, 78821, 2379, 11325, 917902, + 64668, 67854, 8125, 120545, 6743, 83164, 917940, 2369, 83406, 983323, + 127966, 119235, 71868, 73936, 7008, 43660, 120346, 0, 43841, 2367, + 127827, 983857, 264, 2375, 8060, 6194, 119858, 1844, 119084, 129049, + 6019, 128975, 0, 6961, 0, 70435, 67171, 8800, 127332, 42862, 4463, 65581, + 6192, 119610, 42771, 0, 92333, 725, 65042, 93014, 120800, 74942, 12892, + 0, 67149, 74899, 73931, 0, 120495, 127261, 12224, 983128, 129061, 5074, + 5073, 121164, 8983, 118981, 74493, 71231, 5072, 74547, 6198, 11614, 0, + 196, 983154, 0, 983936, 4929, 120342, 129145, 0, 127987, 121455, 42847, + 92953, 0, 67754, 4934, 983981, 41323, 9758, 0, 92289, 70181, 42584, 0, + 4329, 41321, 4979, 3048, 7752, 41320, 983042, 64667, 12819, 983870, 5071, + 127915, 3642, 67334, 5070, 10042, 113813, 3987, 5068, 983460, 8909, + 78650, 78649, 69917, 10636, 73981, 11806, 43167, 4531, 1245, 9105, 66463, + 4921, 120219, 4926, 65544, 73884, 121359, 128028, 0, 64709, 83269, + 128854, 78880, 4922, 325, 992, 119568, 4925, 127218, 0, 9526, 4920, + 128617, 948, 0, 120208, 4930, 127857, 92175, 120275, 4933, 113779, + 121049, 118985, 4928, 983149, 83514, 74770, 120194, 126548, 722, 194934, + 19908, 12637, 127485, 82999, 8753, 1509, 0, 5468, 9511, 43493, 127477, + 1672, 6205, 10864, 74586, 127480, 70103, 92694, 78555, 127468, 73863, + 126577, 68336, 41607, 120115, 1679, 120116, 120180, 92761, 127462, 7005, + 41609, 9580, 70431, 401, 69949, 43779, 6968, 5761, 342, 8553, 127900, + 8143, 127115, 11983, 92249, 624, 74508, 4057, 43788, 5078, 74258, 12478, + 0, 5076, 128702, 82991, 0, 8295, 685, 9025, 1524, 12618, 0, 5539, 129182, + 92523, 71435, 7138, 120552, 43504, 194611, 66914, 65794, 12520, 8058, + 9732, 92480, 5080, 64775, 5036, 5035, 120590, 42604, 983656, 0, 8074, + 275, 13291, 1907, 78838, 4432, 121313, 5033, 120341, 120818, 4836, 3888, + 73792, 10729, 64546, 127262, 43704, 127264, 92957, 67588, 68061, 124983, + 70360, 8858, 6409, 7663, 120252, 128100, 119007, 0, 66321, 94052, 12814, + 127248, 3432, 10218, 0, 6094, 7641, 42445, 128792, 92487, 42406, 1676, + 67362, 74862, 67365, 5030, 67364, 118810, 195008, 73869, 9622, 113763, + 69944, 6787, 67361, 983270, 0, 68319, 10544, 12919, 71484, 72397, 0, 0, + 69906, 120789, 983041, 947, 67695, 67367, 128528, 10969, 67228, 7613, 92562, 119936, 4795, 119930, 7018, 7376, 120181, 120192, 120268, 0, - 43567, 74056, 917910, 11833, 119919, 7216, 65232, 7217, 251, 7218, 7895, - 4395, 43538, 119926, 119929, 119928, 7213, 119922, 7214, 7215, 983836, - 74141, 8880, 7685, 66459, 120173, 65540, 119618, 625, 8187, 42861, 1113, - 7236, 7915, 3630, 120176, 8179, 74264, 67886, 9316, 10980, 2489, 65624, - 8150, 1359, 67652, 127329, 127330, 73756, 5042, 5041, 42769, 12084, - 127324, 127321, 92279, 127319, 127320, 127317, 127318, 127315, 12283, - 1616, 3795, 0, 8795, 66245, 0, 0, 0, 1138, 73905, 12677, 0, 0, 3239, - 127311, 0, 0, 8431, 0, 42164, 0, 11778, 12620, 6826, 73773, 119073, 5040, - 0, 0, 983443, 78420, 0, 5039, 0, 78418, 0, 5038, 0, 0, 13184, 74293, 0, - 64648, 0, 9359, 78416, 0, 128770, 65157, 6662, 0, 0, 3863, 73909, 4835, - 55266, 43432, 127822, 4309, 7127, 194569, 0, 194568, 1301, 0, 42589, 569, - 0, 73813, 711, 4389, 7133, 0, 73880, 11610, 11368, 0, 194570, 41331, - 1006, 74240, 0, 1550, 8201, 73737, 7627, 5499, 5031, 77908, 42738, 65784, - 77907, 65267, 3758, 0, 65781, 64734, 70073, 2440, 65780, 77913, 8449, 0, - 5008, 983572, 2118, 0, 12121, 8255, 5512, 73875, 2128, 2130, 2131, 2126, - 2133, 1119, 127068, 2114, 2116, 2455, 0, 2122, 2123, 2124, 2125, 127486, - 8714, 983820, 2113, 0, 2115, 128177, 127907, 43713, 5052, 66220, 5821, - 6186, 65778, 65775, 5051, 65773, 1429, 42647, 5050, 302, 388, 41115, 735, - 6637, 5907, 65088, 0, 12726, 74594, 9117, 983181, 12003, 5513, 6666, - 5053, 74230, 5510, 78451, 0, 78447, 2470, 78437, 0, 1925, 0, 92237, - 74807, 0, 5048, 5047, 0, 0, 0, 92313, 0, 74497, 92395, 8089, 6929, 639, - 983563, 68179, 64442, 0, 92348, 4599, 41402, 6674, 43397, 43294, 1476, - 648, 0, 65819, 3233, 0, 41782, 6951, 94017, 983976, 3530, 9750, 128317, - 0, 6656, 42618, 0, 5046, 8512, 65856, 74261, 8967, 0, 5045, 42026, 1916, - 7986, 5044, 120556, 9006, 13128, 5043, 0, 7853, 74068, 74004, 9669, - 12341, 12703, 8402, 0, 119070, 917600, 41750, 3586, 64508, 43148, 0, 0, - 119606, 67983, 13296, 517, 0, 128534, 194946, 41528, 123, 65454, 0, 0, - 74478, 10531, 7784, 41526, 10829, 73991, 8057, 1126, 73895, 0, 194591, 0, - 3925, 4251, 8069, 10517, 120439, 489, 0, 4250, 120441, 120452, 43151, - 983178, 194851, 66200, 0, 0, 0, 78423, 0, 0, 8711, 6183, 0, 0, 0, 120448, - 7623, 118925, 118889, 9235, 12760, 74176, 69662, 66445, 43540, 10062, - 3743, 11514, 11078, 0, 12136, 0, 126597, 120435, 0, 7726, 0, 19922, 267, - 3393, 42198, 1371, 194849, 69233, 2458, 0, 6201, 0, 41074, 4266, 10652, - 41612, 41077, 3402, 9050, 3398, 0, 983348, 0, 3391, 41075, 2476, 0, - 128017, 0, 10625, 0, 12767, 13017, 78743, 64261, 64934, 127537, 13014, - 13013, 0, 6673, 0, 0, 0, 12438, 0, 983342, 0, 983880, 126638, 9053, - 13015, 74523, 0, 704, 66215, 6195, 983828, 6660, 78758, 917760, 917793, - 42212, 12629, 11435, 0, 55256, 65538, 0, 127940, 983341, 74547, 126585, - 65448, 78100, 12948, 119001, 195002, 119238, 195004, 78099, 127085, 0, - 128320, 4287, 8276, 4902, 1131, 0, 78458, 66728, 1816, 0, 42533, 168, - 42845, 4898, 64298, 983141, 0, 4901, 1821, 0, 578, 3653, 0, 791, 9162, - 6977, 0, 78889, 74561, 0, 73731, 8354, 43590, 119303, 983449, 7557, - 119339, 119301, 8234, 7241, 0, 120671, 119167, 194996, 12811, 65925, - 3946, 78078, 10998, 78080, 673, 194867, 64397, 128276, 74599, 78449, - 8890, 194977, 194976, 2448, 78085, 10267, 8424, 2452, 78083, 128824, - 8729, 78456, 0, 7845, 917917, 71302, 4408, 4122, 6772, 11039, 8723, - 194990, 71310, 119302, 731, 119304, 92286, 2438, 64855, 119300, 119299, - 1175, 0, 42135, 373, 119172, 2119, 11457, 11521, 7723, 0, 0, 0, 41952, 0, - 5273, 2127, 5269, 6337, 5202, 2404, 5267, 42823, 11291, 19915, 5277, - 12963, 127864, 6189, 4125, 1314, 12133, 120340, 118873, 1271, 983640, 0, - 66024, 41482, 3864, 74539, 0, 3879, 0, 12978, 4166, 4574, 0, 7567, 7459, - 983160, 41390, 5384, 41882, 67647, 92548, 5759, 983912, 0, 41388, 64446, - 41392, 64288, 41387, 0, 8706, 5552, 983187, 700, 0, 5553, 0, 7088, 5356, - 7499, 68007, 66596, 74066, 0, 10263, 5554, 0, 12344, 10311, 78113, 6665, - 92626, 0, 7618, 8517, 11455, 78440, 64632, 64447, 5555, 78088, 78093, - 78091, 0, 42803, 65033, 9143, 6668, 195067, 67995, 195069, 656, 195071, - 65037, 4577, 64624, 0, 0, 0, 983649, 4269, 73885, 917775, 42846, 69644, - 950, 0, 92273, 66580, 118895, 66683, 10554, 917778, 119121, 0, 5098, - 917770, 0, 119099, 5097, 4935, 9848, 10381, 0, 128870, 983701, 3651, 0, - 120730, 127556, 5102, 5101, 10269, 12983, 8138, 4517, 1932, 5100, 1439, - 12093, 1247, 10034, 195064, 5099, 78373, 1441, 42087, 3063, 650, 0, 7838, - 0, 195041, 195040, 119142, 9031, 120790, 128582, 9078, 8545, 66356, - 128799, 0, 9154, 9118, 126543, 0, 2676, 2277, 0, 73812, 6190, 8599, - 195053, 69918, 10795, 9857, 7014, 9856, 195033, 92620, 12129, 0, 8481, 0, - 6202, 195035, 10920, 128237, 5203, 195039, 195038, 5108, 5107, 65818, - 66019, 9762, 0, 5541, 74772, 0, 12613, 5284, 6657, 207, 128806, 4275, - 74819, 854, 68147, 74381, 0, 78786, 5103, 127861, 64348, 41368, 43974, - 488, 69811, 0, 71339, 10157, 0, 43034, 11438, 64674, 0, 92694, 68431, - 41771, 5106, 6669, 8504, 65154, 69813, 41367, 5105, 127509, 69720, 6476, - 5104, 983749, 304, 3176, 119010, 0, 932, 120633, 6567, 238, 69656, - 195011, 194595, 19905, 120577, 195015, 78870, 41044, 67640, 194902, - 42055, 9912, 65939, 10670, 74093, 13273, 0, 12552, 195019, 8803, 309, - 6622, 8151, 10858, 78706, 67636, 0, 12568, 0, 12553, 10814, 43275, 6950, - 9712, 68680, 43970, 983198, 65165, 92725, 0, 66466, 0, 0, 0, 66725, 6191, - 11351, 10437, 11316, 67634, 43763, 0, 41754, 67635, 9370, 2720, 194975, - 68462, 8232, 118817, 0, 3222, 0, 0, 0, 66663, 0, 0, 10834, 0, 0, 65732, - 94095, 917547, 92682, 67679, 195020, 0, 7781, 41383, 64568, 0, 120738, - 12077, 0, 64586, 917620, 42396, 55255, 3475, 128035, 2479, 0, 3632, - 120728, 10698, 8376, 3648, 194960, 74844, 67639, 3636, 67894, 3650, 8837, - 65229, 1843, 42283, 43250, 41562, 9100, 74548, 917630, 3640, 127190, - 42321, 7284, 194974, 194973, 194950, 194949, 194952, 194951, 126649, - 194953, 42080, 2529, 0, 0, 0, 42083, 120678, 68398, 194957, 67619, 66367, - 194958, 9634, 92380, 9988, 0, 41068, 0, 4295, 65264, 68006, 0, 92545, 0, - 785, 8236, 128647, 9027, 68160, 67623, 64383, 120265, 925, 127156, 0, - 41985, 41071, 9586, 0, 41984, 9217, 0, 0, 0, 9186, 2067, 4016, 983803, 0, - 381, 12936, 0, 42077, 0, 69880, 5184, 42078, 194947, 10810, 128531, 4585, - 19943, 5860, 67633, 0, 0, 812, 3615, 0, 5178, 44000, 120548, 78807, 5188, - 74287, 67629, 3605, 10692, 1166, 64429, 42639, 924, 0, 67631, 42616, - 120670, 2442, 10703, 78789, 67632, 917924, 12771, 12736, 12753, 66708, - 73933, 67626, 42401, 0, 69872, 127373, 42288, 12751, 0, 8542, 13145, - 194963, 2468, 66706, 41294, 3626, 3883, 64388, 42479, 0, 41117, 0, 92580, - 0, 0, 67624, 0, 1290, 0, 65585, 2715, 806, 65208, 41884, 917883, 1318, - 64731, 126578, 0, 0, 66325, 3465, 2405, 9240, 0, 12756, 65259, 0, 983781, - 12752, 5833, 1432, 0, 41883, 73912, 9799, 0, 41886, 2480, 0, 2062, - 127293, 6494, 5537, 78656, 0, 194587, 0, 1211, 0, 0, 0, 118832, 12318, 0, - 0, 68005, 10622, 983779, 0, 78654, 6566, 78659, 0, 73780, 119196, 64864, - 0, 78660, 0, 8284, 13081, 0, 3589, 42051, 4035, 6492, 92236, 4265, 6642, - 3977, 74186, 41778, 836, 119216, 2488, 0, 4582, 0, 0, 41777, 12926, - 983377, 7528, 10550, 0, 92706, 0, 10961, 0, 1374, 64878, 119014, 0, - 42389, 41374, 2286, 0, 78492, 41377, 127909, 0, 400, 12597, 120586, 0, 0, - 6661, 983145, 64827, 0, 73817, 390, 0, 71301, 983862, 3473, 7718, 0, 0, - 0, 55285, 0, 0, 0, 11969, 983390, 127841, 6365, 1887, 6763, 983370, 8080, - 7006, 0, 983371, 6757, 64351, 1544, 0, 6766, 64677, 120716, 983372, 6146, - 0, 771, 983373, 0, 12812, 13168, 42272, 12200, 917927, 7904, 0, 953, - 12917, 119560, 12300, 0, 11491, 9724, 10341, 983773, 9524, 7490, 11389, - 7489, 3379, 0, 7487, 0, 471, 7484, 7482, 6753, 7480, 5764, 7478, 7477, - 6501, 7475, 6918, 7473, 7472, 2474, 7470, 7468, 10232, 10615, 10213, - 127288, 92357, 10049, 11834, 3544, 0, 6017, 65311, 127481, 120216, 13306, - 10533, 7870, 73949, 7625, 0, 120544, 0, 0, 92660, 0, 0, 0, 19961, 2472, - 42665, 92341, 0, 2139, 4256, 120776, 74380, 0, 42675, 42658, 12845, 0, 0, - 65138, 119355, 67862, 0, 65671, 7083, 120008, 8066, 7678, 74865, 0, 0, 0, - 0, 7186, 0, 120555, 0, 445, 120566, 128308, 0, 0, 8330, 0, 0, 42797, - 983150, 120215, 0, 3902, 0, 1770, 0, 128866, 1560, 120209, 194972, 4584, - 73843, 0, 11712, 10866, 118928, 1118, 71334, 0, 0, 1081, 7436, 68420, - 7252, 0, 5996, 69921, 4903, 0, 41386, 5162, 119189, 1330, 0, 7139, 0, - 12047, 41384, 0, 0, 1848, 4334, 6324, 41975, 64777, 10674, 12308, 12186, - 0, 0, 983741, 12715, 68002, 983479, 126630, 2018, 66672, 41979, 66685, - 119157, 68000, 92464, 0, 126984, 68001, 9334, 92705, 92315, 70101, 7975, - 0, 77957, 0, 66621, 4884, 66597, 69732, 0, 0, 6313, 65513, 69857, 0, 0, - 0, 2345, 43697, 463, 0, 0, 119607, 3117, 5460, 0, 0, 983387, 0, 42279, - 194577, 0, 78415, 0, 195008, 983384, 13248, 0, 0, 0, 0, 0, 0, 5663, 0, 0, - 0, 0, 2482, 1471, 0, 0, 42247, 12378, 73925, 69664, 0, 12374, 0, 0, 0, - 983694, 2460, 0, 11944, 12376, 127868, 64679, 0, 12380, 10557, 64473, - 5870, 0, 2024, 127180, 0, 0, 539, 0, 127765, 94052, 3853, 65180, 127923, - 120796, 120245, 92324, 0, 8659, 0, 12474, 92579, 9503, 194969, 2478, 0, - 4162, 0, 4260, 12953, 69633, 120089, 12470, 0, 74189, 2742, 12476, 11798, - 10946, 127310, 5000, 0, 983579, 0, 69672, 8213, 74017, 7771, 6161, 68018, - 6709, 0, 78885, 983708, 127971, 120582, 78547, 0, 10301, 10333, 10397, 0, - 0, 73791, 0, 0, 0, 0, 119123, 4014, 12842, 73952, 12015, 127290, 8275, - 3893, 983264, 0, 12210, 7221, 42147, 0, 74550, 74465, 64747, 118841, 0, - 12516, 4444, 0, 92271, 74537, 10892, 8231, 0, 6473, 41968, 78388, 41973, - 3591, 41969, 0, 2453, 128549, 92666, 64705, 0, 0, 10349, 10413, 43591, - 41962, 3202, 74353, 0, 8316, 0, 0, 94060, 687, 0, 0, 0, 1840, 0, 68671, - 119809, 4883, 285, 4723, 70099, 92692, 4459, 74577, 42921, 41720, 11089, - 240, 19906, 0, 42323, 0, 9743, 120232, 13134, 126535, 0, 0, 0, 0, 42634, - 983343, 43437, 3081, 11463, 120154, 0, 0, 10445, 0, 0, 66717, 2614, 9125, - 119023, 1729, 0, 120236, 65221, 63883, 43334, 64852, 0, 65194, 66201, 0, - 66578, 5001, 41879, 74427, 4121, 5003, 884, 66700, 63879, 4943, 5150, - 73889, 74182, 127915, 643, 3086, 0, 42448, 42299, 58, 0, 917952, 120083, - 63873, 8491, 0, 0, 983623, 4530, 42409, 7126, 194575, 2721, 120074, - 119096, 19929, 0, 194574, 0, 4242, 4264, 120077, 120530, 66179, 42412, - 65941, 13114, 64522, 10740, 3094, 0, 9754, 119102, 4437, 73948, 127074, - 983238, 55280, 42174, 194925, 42430, 0, 0, 42355, 66026, 4306, 41380, - 68432, 92586, 0, 66667, 127309, 0, 126521, 42200, 42566, 0, 0, 5088, - 6948, 0, 8524, 0, 0, 12385, 0, 0, 69646, 1386, 64580, 11480, 6116, 65039, - 65038, 12392, 65036, 8064, 0, 12101, 5822, 119004, 2080, 710, 77999, - 11663, 1666, 42091, 119657, 12383, 43671, 42092, 68418, 4289, 0, 63896, - 12061, 42096, 43621, 3362, 12377, 983832, 983834, 68449, 7461, 73901, - 1244, 331, 73786, 12683, 10662, 0, 8112, 0, 65852, 0, 12379, 194877, - 120818, 41964, 42208, 63843, 2084, 41965, 0, 65866, 4327, 0, 63840, - 78549, 41220, 13032, 0, 584, 12933, 43177, 12373, 69855, 13000, 1351, - 2935, 8698, 12665, 0, 1930, 0, 78229, 12427, 66514, 69859, 13031, 0, - 63901, 0, 3657, 128572, 65202, 6000, 119206, 12426, 127181, 0, 41740, - 12428, 41283, 41916, 119210, 0, 0, 12429, 6727, 0, 7562, 0, 5170, 0, - 41755, 676, 0, 66704, 66664, 9978, 66491, 3536, 0, 9752, 92397, 6162, 0, - 69228, 10113, 41829, 65886, 5159, 12422, 41832, 439, 43077, 0, 42207, - 74549, 11796, 40970, 41830, 0, 917799, 8308, 917797, 917796, 0, 67864, - 917801, 917800, 12336, 4135, 69805, 341, 2727, 4129, 3539, 0, 63861, 0, - 7913, 0, 63859, 4131, 63868, 0, 63867, 4133, 11371, 210, 4600, 0, 74560, - 4137, 8082, 78506, 119062, 78504, 6704, 4591, 128029, 0, 0, 9680, 0, - 120623, 561, 12159, 195, 78508, 41501, 0, 42031, 5719, 7172, 42687, 8368, - 0, 41499, 0, 0, 42242, 41498, 917794, 42025, 78565, 65805, 42463, 0, - 2924, 0, 120510, 0, 0, 119213, 73941, 0, 42330, 917784, 3969, 0, 0, 7169, - 1992, 9652, 73977, 7246, 42086, 126615, 2219, 0, 0, 128801, 194837, 0, - 327, 0, 9042, 917777, 917776, 65148, 12433, 917781, 127276, 917779, - 12431, 8668, 12434, 983835, 917782, 5999, 0, 7712, 12432, 128243, 43653, - 1726, 1015, 0, 8212, 0, 128014, 42423, 119066, 0, 128108, 66709, 0, 8811, - 927, 0, 0, 12436, 983245, 42021, 0, 0, 1299, 12240, 42350, 65143, 0, - 195016, 0, 78197, 11348, 0, 78037, 9194, 983184, 0, 19914, 12179, 983812, - 2296, 194923, 63836, 63832, 917773, 10967, 63816, 2594, 3444, 63817, - 64651, 0, 41503, 127478, 11265, 0, 120756, 194922, 0, 5664, 3972, 0, 0, - 0, 128508, 12416, 917764, 119608, 10816, 917769, 917768, 12418, 74111, - 3882, 8532, 917771, 1573, 128648, 119847, 4596, 66339, 12417, 66001, - 65343, 126491, 12414, 8287, 68219, 195017, 68108, 1143, 119169, 119846, - 12415, 6626, 42763, 0, 118884, 9021, 120783, 0, 11724, 0, 0, 127104, - 126619, 0, 0, 8027, 10997, 9171, 12741, 11400, 71305, 194799, 0, 128239, - 0, 128881, 119604, 127523, 120190, 194773, 67608, 128214, 42368, 0, 7715, - 3881, 41487, 12118, 42514, 68651, 0, 983895, 3009, 41476, 41489, 69825, - 3007, 1448, 3018, 194809, 3889, 8521, 5083, 5082, 119859, 120184, 8519, - 983241, 3014, 5081, 65853, 120715, 0, 68014, 69951, 5079, 64802, 42210, - 4597, 65532, 11828, 120185, 12371, 0, 8407, 0, 10805, 8518, 10779, - 120188, 71303, 983933, 12367, 42170, 0, 92557, 629, 1924, 0, 12037, - 74366, 5987, 8462, 8005, 12365, 63933, 69735, 120815, 12369, 10649, - 67981, 5077, 120174, 10880, 63927, 5075, 917881, 0, 65075, 0, 11007, - 983705, 66659, 92607, 0, 66684, 0, 3434, 4954, 1904, 0, 5266, 126980, - 5272, 10499, 4507, 9578, 63923, 120177, 7979, 0, 9831, 0, 194926, 461, - 9803, 0, 4504, 1505, 0, 6325, 5276, 43021, 120488, 0, 55236, 0, 66461, - 5177, 41324, 12055, 8722, 0, 41327, 0, 66695, 4114, 409, 4383, 8900, - 8948, 41325, 0, 721, 10182, 9108, 71311, 0, 119185, 42229, 194912, 0, - 5998, 0, 42353, 74825, 0, 12587, 94104, 78571, 0, 71328, 194562, 41576, - 42215, 78570, 119207, 0, 8578, 5995, 7573, 41575, 74789, 74752, 63944, - 63949, 64767, 2670, 4167, 194796, 11723, 0, 74120, 0, 65076, 938, 43414, - 73854, 11737, 9721, 0, 0, 0, 11742, 2419, 0, 11493, 12334, 194913, 4153, - 12302, 10793, 5250, 12407, 11978, 4404, 9189, 12401, 42007, 5775, 6759, - 65806, 43997, 0, 42002, 12404, 983553, 0, 4940, 12410, 7683, 1167, 73729, - 4983, 120507, 861, 0, 0, 0, 0, 43757, 43370, 0, 0, 11956, 0, 0, 0, 9616, - 6631, 0, 12816, 43759, 42218, 12710, 68674, 12721, 4101, 66185, 0, 5992, - 7616, 195044, 0, 12577, 0, 983884, 853, 42693, 195014, 0, 983647, 5016, - 43535, 63893, 42835, 9491, 917913, 0, 917914, 0, 12712, 7105, 127807, - 65060, 120797, 9900, 7750, 0, 194919, 0, 127830, 0, 64778, 12585, 10565, - 128151, 12177, 0, 0, 0, 77824, 0, 4900, 127874, 12878, 92630, 8984, 4119, - 74768, 8971, 78593, 43113, 9702, 78594, 11025, 9245, 13048, 4927, 4138, - 74185, 92481, 92710, 12397, 77827, 0, 13054, 12394, 0, 0, 0, 13053, 0, - 3948, 10781, 1546, 0, 5010, 1680, 10507, 78590, 78583, 0, 0, 0, 194915, - 7267, 0, 74833, 128181, 5993, 2819, 0, 12706, 77840, 1893, 7266, 63915, - 7264, 7265, 0, 1363, 0, 63997, 63910, 63996, 3077, 0, 0, 1512, 69929, - 12589, 41479, 128313, 0, 43339, 73776, 9836, 120727, 0, 41481, 43335, - 7832, 42343, 3090, 43337, 817, 1664, 1850, 128841, 3079, 11340, 42408, - 42447, 127140, 120020, 42307, 12386, 42304, 917555, 0, 12389, 0, 92366, - 41996, 11526, 63985, 5864, 1147, 63992, 42887, 1987, 92718, 5480, 7858, - 11653, 4116, 12391, 66193, 0, 4939, 12384, 0, 0, 41686, 63905, 119601, - 194688, 983190, 0, 12649, 0, 0, 8247, 507, 91, 2042, 120775, 43643, - 194689, 66028, 10036, 41844, 119813, 774, 119829, 0, 119815, 5994, 12539, - 0, 78375, 120597, 119833, 983105, 119600, 0, 0, 7719, 6026, 2486, 128312, - 119808, 162, 0, 65219, 41073, 9687, 41681, 6304, 119812, 66196, 194881, - 5262, 0, 55233, 12681, 42379, 0, 7534, 12219, 0, 127528, 42810, 10492, 0, - 983661, 0, 43119, 0, 120753, 12403, 2500, 195013, 0, 4899, 12729, 0, 0, - 74113, 2343, 4103, 19946, 74112, 77851, 13112, 0, 195012, 12859, 70087, - 120148, 66369, 5861, 127758, 11999, 12400, 0, 983839, 12645, 5146, 11320, - 68410, 6748, 65040, 0, 64184, 12974, 64183, 67613, 120645, 5147, 0, 0, - 74524, 0, 1928, 0, 67649, 5991, 3445, 67609, 4976, 64176, 0, 67610, 8241, - 0, 77868, 4206, 0, 0, 0, 128298, 0, 10138, 0, 0, 8897, 120234, 0, 8357, - 4124, 77862, 65836, 120641, 127926, 77859, 0, 0, 1123, 963, 41553, 10120, - 12405, 120150, 92664, 398, 13278, 9723, 6366, 120311, 7945, 0, 4402, - 9970, 12402, 983136, 42392, 1305, 12408, 0, 44007, 0, 0, 41464, 12411, - 12969, 120824, 41465, 983565, 8528, 1575, 0, 63955, 165, 3024, 41467, - 119163, 0, 9093, 0, 9147, 128787, 63958, 0, 9148, 9692, 4096, 53, 8296, - 6750, 195018, 0, 9594, 0, 0, 43527, 0, 727, 194703, 195023, 5805, 0, - 6726, 0, 42176, 12370, 11655, 119095, 10591, 2280, 0, 12372, 120642, - 120307, 0, 92343, 0, 12366, 10963, 6066, 1329, 0, 3052, 9220, 0, 64478, - 194701, 10803, 4132, 120306, 68474, 92473, 0, 983313, 74837, 120155, - 1499, 0, 8055, 42740, 63965, 0, 63962, 74042, 8924, 43123, 5988, 3660, - 63969, 11781, 42718, 8788, 1357, 64851, 65743, 0, 8774, 0, 127086, 9941, - 120172, 0, 1933, 69655, 9564, 0, 92435, 73866, 0, 0, 2487, 67614, 3121, - 1804, 3311, 67615, 70081, 78302, 12220, 67616, 120598, 127475, 0, 68200, - 6675, 128144, 0, 67592, 120685, 0, 64771, 1198, 9132, 0, 64619, 510, - 64663, 0, 0, 4561, 2101, 1398, 0, 92554, 74034, 41569, 92684, 11406, - 8167, 12127, 0, 840, 0, 126518, 7101, 6967, 0, 194898, 9796, 0, 333, - 69891, 0, 8144, 2117, 0, 983595, 12406, 0, 19931, 119089, 6678, 7769, 0, - 12621, 0, 127366, 10227, 4764, 43101, 9981, 0, 40986, 4127, 66487, 0, - 42202, 12754, 195022, 0, 0, 94097, 67594, 2048, 12944, 4050, 67595, - 917967, 43102, 10581, 12985, 4533, 195021, 74003, 6490, 0, 12038, 0, 0, - 120704, 65461, 9798, 69704, 0, 1948, 69841, 0, 952, 128235, 0, 0, 120802, - 6449, 9494, 120313, 0, 43098, 4843, 8142, 64160, 4098, 64170, 0, 0, 3436, - 119973, 0, 12817, 67597, 6676, 3930, 42615, 0, 0, 67598, 0, 0, 0, 65591, - 41581, 65916, 1453, 0, 0, 0, 8500, 42222, 120142, 73743, 120400, 4317, - 11543, 67676, 64676, 0, 0, 67606, 119083, 0, 42217, 13102, 0, 66003, - 6672, 0, 0, 0, 983747, 63841, 9613, 9001, 4526, 11274, 67601, 64520, - 64210, 6664, 78704, 42056, 10228, 64957, 11281, 0, 3807, 1469, 66640, - 65381, 42197, 4988, 42372, 0, 9598, 904, 352, 42225, 1451, 8061, 8453, - 4134, 0, 74847, 66576, 127916, 0, 10520, 8575, 9960, 1201, 127289, 12846, - 127291, 127292, 11919, 64962, 127287, 43739, 127281, 8511, 9460, 823, - 11587, 12305, 0, 64695, 127305, 12387, 1253, 13183, 65766, 500, 42783, - 65765, 64208, 64369, 65760, 65761, 119585, 11606, 64784, 11702, 66498, - 9821, 64304, 0, 5152, 11048, 7533, 68366, 64410, 92305, 0, 4323, 120062, - 92669, 71332, 127052, 42587, 42214, 41394, 0, 4763, 4112, 118935, 0, - 5260, 43143, 94038, 326, 120131, 68423, 0, 10771, 2876, 74074, 92530, - 194924, 41398, 7382, 9802, 127077, 127076, 453, 41396, 120524, 42720, - 12140, 9572, 0, 7003, 194883, 42334, 7704, 126490, 194885, 43144, 4123, - 8494, 43146, 9977, 0, 0, 65759, 10765, 64061, 4465, 9808, 64056, 65582, - 4126, 0, 9521, 9589, 64755, 0, 64020, 126604, 10464, 0, 0, 194869, 64514, - 11528, 64024, 128072, 679, 64013, 0, 5850, 758, 7536, 0, 92234, 41441, - 10693, 64006, 983567, 64005, 4058, 119019, 126487, 64660, 0, 119050, 0, - 983069, 1139, 43298, 64027, 64029, 8970, 0, 9934, 983094, 10774, 128020, - 42201, 12421, 128216, 0, 1852, 3057, 64046, 73744, 64034, 64039, 0, 0, 0, - 194899, 92322, 7645, 12854, 74338, 3496, 0, 0, 0, 9102, 627, 127795, - 6158, 8327, 74553, 66632, 12419, 13309, 11570, 127811, 19960, 11696, 0, - 1018, 118970, 194909, 194897, 1682, 194896, 194911, 42756, 6765, 194906, - 0, 0, 73814, 11412, 6768, 10728, 194830, 71316, 118863, 43311, 64966, - 11577, 0, 43040, 1833, 11576, 0, 74779, 0, 185, 65085, 74533, 64754, - 194848, 7535, 8085, 42525, 120387, 9749, 41701, 6131, 1949, 4117, 7847, - 120489, 194711, 64483, 65693, 0, 0, 0, 69695, 42240, 0, 126651, 42864, - 126498, 64667, 41868, 1184, 0, 815, 11484, 127535, 67840, 983651, 0, - 66197, 0, 10986, 64683, 983785, 0, 3455, 0, 0, 9879, 0, 0, 4158, 128050, - 68166, 0, 0, 0, 0, 69645, 332, 118808, 0, 5142, 2407, 69643, 42199, 0, - 92404, 74373, 0, 55217, 0, 63870, 43163, 0, 0, 92390, 42867, 1834, 0, - 92461, 69817, 10940, 65249, 119040, 8662, 0, 0, 2652, 120527, 7164, - 10784, 195093, 67674, 0, 92233, 92482, 194749, 74562, 917505, 1828, - 74474, 120327, 78620, 8531, 12499, 6280, 12324, 118854, 65238, 68374, - 4832, 65573, 0, 6279, 12508, 12904, 12502, 9161, 0, 1620, 64436, 3601, - 195094, 128073, 983562, 609, 11555, 983099, 12496, 127839, 74181, 4343, - 12505, 0, 127863, 0, 11377, 239, 0, 637, 0, 0, 42671, 0, 0, 0, 43565, - 71306, 126493, 12696, 128256, 0, 94062, 12929, 0, 712, 0, 4197, 983206, - 42818, 126632, 0, 120490, 0, 119137, 1506, 43562, 0, 92491, 0, 12651, 0, - 64628, 74517, 12058, 74084, 917838, 7494, 0, 4924, 65592, 118844, 0, - 127088, 355, 9719, 127087, 13066, 64796, 0, 0, 12033, 42178, 0, 69760, - 42571, 92635, 0, 0, 0, 0, 0, 127176, 3178, 0, 0, 92704, 0, 9080, 127000, - 120352, 0, 68209, 0, 11082, 0, 5699, 195100, 66000, 9488, 65166, 119112, - 0, 0, 0, 0, 71313, 0, 5265, 69235, 0, 11487, 67858, 12464, 0, 43045, 0, - 0, 43345, 0, 10770, 118994, 6807, 465, 9829, 0, 74348, 0, 43346, 8116, - 795, 0, 0, 12462, 10930, 10831, 0, 118952, 64362, 74334, 983602, 120811, - 0, 12468, 8607, 1008, 0, 10092, 195078, 917842, 67855, 55257, 73771, - 1766, 11282, 11996, 1820, 4547, 0, 0, 0, 0, 13223, 128665, 64595, 127294, - 0, 92311, 4345, 12616, 0, 0, 0, 74467, 0, 0, 0, 5382, 0, 0, 0, 119060, - 64953, 5406, 19920, 69897, 66510, 3590, 194864, 1130, 0, 0, 42016, 11823, - 43023, 0, 118896, 7742, 0, 13280, 71323, 9326, 73826, 5310, 74812, 78584, - 92229, 8959, 43589, 6747, 66723, 0, 8568, 0, 120496, 73816, 120803, - 983848, 42670, 0, 11621, 12460, 0, 120631, 0, 43063, 74519, 127182, 0, - 73917, 7843, 69783, 11689, 5410, 5783, 10468, 8403, 5400, 11594, 128247, - 0, 118990, 10491, 69842, 64412, 0, 0, 5587, 42865, 64404, 8268, 4923, - 65086, 8981, 12382, 42133, 120755, 9706, 69738, 0, 66610, 10461, 12103, - 0, 8642, 0, 42766, 983866, 2210, 9983, 0, 94009, 0, 0, 0, 7398, 41515, 0, - 11802, 8041, 1461, 910, 119133, 0, 6749, 3658, 93964, 120525, 0, 7617, - 194841, 12888, 127983, 67668, 13143, 0, 9193, 11097, 5703, 0, 41517, - 41504, 41519, 10016, 64305, 0, 65864, 623, 781, 670, 10660, 5769, 613, - 7543, 120279, 477, 41083, 92521, 0, 592, 1578, 12459, 43449, 0, 0, 8225, - 0, 654, 11345, 653, 652, 0, 647, 0, 633, 120744, 0, 126472, 12480, 43243, - 0, 39, 12487, 0, 120529, 74199, 12482, 0, 12489, 0, 3195, 5550, 983554, - 7897, 0, 1203, 74396, 1813, 64544, 41311, 12090, 0, 2877, 0, 0, 1675, - 69840, 0, 0, 0, 10070, 10595, 0, 119077, 194777, 983611, 0, 0, 0, 43244, - 0, 0, 983916, 119561, 983078, 0, 194921, 128160, 9939, 0, 983151, 77860, - 0, 0, 270, 0, 10714, 0, 0, 0, 0, 0, 65372, 0, 74038, 119558, 6273, 66679, - 364, 9595, 194908, 0, 0, 707, 0, 0, 9282, 66489, 224, 0, 68670, 9332, - 4966, 68677, 0, 68644, 0, 3841, 68634, 0, 10732, 68640, 850, 4972, 0, - 12890, 2909, 68619, 44008, 68627, 983718, 11544, 10203, 9608, 0, 0, - 11962, 194694, 12507, 1196, 128687, 128311, 777, 120187, 4375, 65271, - 67678, 0, 12198, 0, 64824, 119343, 983236, 9454, 63778, 8658, 42528, - 78000, 2705, 917975, 41520, 0, 0, 11986, 7765, 42502, 8280, 74520, 2701, - 0, 127002, 5767, 0, 0, 9809, 8353, 63747, 66701, 63772, 983814, 63745, - 1748, 63770, 0, 0, 0, 65542, 63766, 55244, 3061, 0, 63764, 63787, 9067, - 6096, 0, 7694, 0, 7257, 63768, 3485, 12987, 0, 127522, 120628, 63807, - 1591, 0, 6386, 63783, 0, 0, 92535, 0, 0, 0, 74575, 0, 65719, 13083, - 64574, 65012, 0, 1640, 12495, 66691, 7624, 3138, 10996, 92247, 1922, 0, - 12498, 10987, 69936, 69939, 3894, 65543, 0, 194842, 983588, 493, 0, - 43197, 1717, 4228, 479, 10303, 74020, 0, 917935, 10335, 3520, 917932, - 12490, 64315, 0, 127039, 12493, 6233, 42681, 1002, 12491, 0, 64911, - 92615, 2096, 65120, 0, 78219, 983081, 8378, 11632, 127041, 66213, 63864, + 43567, 74056, 120266, 11833, 119919, 7216, 65232, 7217, 251, 7218, 7895, + 4395, 43538, 119926, 119834, 119928, 7213, 68476, 7214, 7215, 5879, + 74141, 8880, 7685, 66459, 120173, 65540, 67359, 625, 8187, 42861, 1113, + 7236, 7915, 3630, 120176, 8179, 70163, 67886, 9316, 10980, 2489, 65624, + 8150, 1359, 67652, 70464, 127330, 73756, 5042, 5041, 42769, 12084, + 127324, 127321, 74410, 127319, 127320, 127317, 121284, 127315, 12283, + 1616, 3795, 67732, 8795, 66245, 0, 0, 0, 1138, 73905, 12677, 128280, + 67724, 3239, 66893, 128818, 0, 8431, 0, 42164, 71229, 11778, 12620, 6826, + 73773, 70169, 5040, 127969, 0, 67094, 78420, 0, 5039, 983241, 78418, 0, + 5038, 0, 983862, 13184, 43960, 120931, 64648, 0, 9359, 78416, 917623, + 128770, 65157, 6662, 0, 70182, 3863, 73909, 4835, 55266, 43432, 127822, + 4309, 7127, 194569, 0, 194568, 1301, 0, 42589, 569, 128804, 73813, 711, + 4389, 7133, 120643, 73880, 11610, 11368, 0, 194570, 41331, 1006, 74240, + 67224, 1550, 8201, 70453, 7627, 5499, 5031, 77908, 42738, 65784, 43957, + 65267, 3758, 0, 65781, 64734, 67222, 2440, 43955, 70787, 8449, 0, 5008, + 983572, 2118, 126508, 12121, 8255, 5512, 73875, 2128, 2130, 2131, 2126, + 2133, 1119, 121250, 2114, 2116, 2455, 113798, 2122, 2123, 2124, 2125, + 127486, 8714, 983820, 2113, 195049, 2115, 128177, 127907, 43713, 5052, + 66220, 5821, 6186, 65778, 65775, 5051, 65773, 1429, 42647, 5050, 302, + 388, 41115, 735, 6637, 5907, 65088, 0, 12726, 74594, 9117, 983181, 12003, + 5513, 5109, 5053, 74230, 5510, 78451, 0, 78447, 2470, 78437, 0, 1925, + 71251, 92237, 74807, 983062, 5048, 5047, 194837, 983380, 74201, 92313, + 194802, 74497, 82982, 8089, 6929, 639, 82981, 68179, 64442, 70180, 82984, + 4599, 41402, 6674, 43397, 43294, 1476, 648, 0, 65819, 3233, 0, 41782, + 6951, 94017, 129197, 3530, 9750, 128317, 120991, 6656, 42618, 70175, + 5046, 8512, 65856, 74261, 8967, 0, 5045, 42026, 1916, 7986, 5044, 120556, + 9006, 13128, 5043, 121335, 7853, 67808, 74004, 9669, 12341, 12703, 8402, + 128883, 119070, 70174, 41750, 3586, 64508, 43148, 0, 127971, 119606, + 67983, 13296, 517, 0, 128467, 194946, 41528, 123, 65454, 0, 121326, + 74478, 10531, 7784, 41526, 10829, 73991, 8057, 1126, 73895, 194857, + 194591, 0, 3925, 4251, 8069, 10517, 71112, 489, 71110, 4250, 92266, + 120452, 43151, 983178, 92738, 66200, 0, 0, 125026, 74298, 128879, 983476, + 8711, 6183, 83448, 983952, 72402, 120448, 7623, 118925, 66376, 9235, + 12760, 74176, 69662, 66445, 43540, 10062, 3743, 11514, 11078, 0, 12136, + 0, 126597, 120434, 194850, 7726, 195095, 19922, 267, 3393, 42198, 1371, + 194849, 69233, 2458, 0, 6201, 0, 41074, 4266, 10652, 41612, 41077, 3402, + 9050, 3398, 128424, 983350, 0, 3391, 41075, 2476, 0, 128017, 0, 10625, + 129106, 12767, 13017, 78743, 64261, 64934, 70152, 13014, 13013, 121198, + 6673, 0, 0, 121324, 12438, 0, 983344, 83106, 71128, 120062, 9053, 13015, + 74523, 0, 704, 66215, 6195, 74949, 6660, 78758, 917760, 74861, 42212, + 12629, 11435, 0, 55256, 65538, 67343, 121437, 129086, 43876, 92941, + 65448, 78100, 12948, 119001, 128595, 43949, 120048, 78099, 127085, 0, + 128320, 4287, 8276, 4902, 1131, 983606, 78458, 66728, 1816, 43952, 42533, + 168, 42845, 4898, 64298, 43950, 78105, 4901, 1821, 43951, 578, 3653, + 128946, 791, 9162, 6977, 74196, 78889, 70160, 0, 73731, 8354, 43590, + 119303, 983451, 7557, 119108, 67378, 8234, 7241, 128608, 113735, 119167, + 194996, 12811, 65925, 3946, 78078, 10998, 78080, 673, 194867, 64397, + 128276, 74599, 78449, 8890, 194977, 194976, 2448, 78085, 10267, 8424, + 2452, 78083, 67217, 8729, 78456, 0, 7845, 126564, 71302, 4408, 4122, + 6772, 11039, 8723, 65896, 71310, 119302, 731, 119304, 71904, 2438, 64855, + 119300, 119299, 1175, 0, 42135, 373, 119172, 2119, 11457, 11521, 7723, + 128639, 0, 0, 41952, 93023, 5273, 2127, 5269, 6337, 5202, 2404, 5267, + 42823, 11291, 19915, 5277, 12963, 70320, 6189, 4125, 1314, 12133, 120340, + 118873, 1271, 983640, 129112, 66024, 41482, 3864, 9204, 0, 3879, 0, + 12978, 4166, 4574, 128111, 7567, 7459, 78128, 41390, 5384, 41882, 67647, + 70154, 5759, 194869, 121413, 41388, 64446, 41392, 64288, 41387, 67201, + 8706, 5552, 68837, 700, 0, 5553, 0, 7088, 5356, 7499, 68007, 66596, + 74066, 67251, 10263, 5554, 0, 12344, 10311, 78113, 6665, 11115, 121035, + 7618, 8517, 11455, 78440, 64632, 64447, 5555, 78088, 78093, 78091, 0, + 42803, 65033, 9143, 6668, 67288, 67995, 195069, 656, 195071, 65037, 4577, + 64624, 0, 0, 71912, 194908, 4269, 73885, 917775, 42846, 69644, 950, 0, + 92273, 66580, 77992, 66683, 10554, 119008, 119121, 6832, 5098, 917768, + 194668, 70403, 5097, 4935, 9848, 10381, 0, 67296, 92896, 3651, 0, 67294, + 70848, 5102, 5101, 10269, 12983, 8138, 4517, 1932, 5100, 1439, 12093, + 1247, 10034, 121340, 5099, 78373, 1441, 42087, 3063, 650, 119953, 7838, + 0, 128655, 195040, 119142, 9031, 70829, 78427, 9078, 8545, 66356, 128799, + 194923, 9154, 9118, 126543, 119586, 2676, 2277, 128422, 68237, 6190, + 8599, 125118, 69918, 10795, 9857, 7014, 9856, 195033, 71903, 12129, + 126651, 8481, 83068, 6202, 67711, 10920, 113726, 5203, 195039, 195038, + 5108, 5107, 65818, 66019, 9762, 11205, 5541, 74772, 0, 12613, 5284, 6657, + 207, 121206, 4275, 74819, 854, 68147, 74381, 66816, 78786, 5103, 127861, + 64348, 41368, 43974, 488, 69811, 0, 71339, 10157, 194612, 43034, 11438, + 64674, 0, 70158, 68431, 41771, 5106, 6669, 8504, 65154, 69813, 41367, + 5105, 65266, 69720, 6476, 5104, 983749, 304, 3176, 78871, 70149, 932, + 113683, 6567, 238, 69656, 78432, 194595, 19905, 43850, 195015, 78870, + 41044, 67640, 67302, 42055, 9912, 65939, 10670, 74093, 13273, 0, 12552, + 93039, 8803, 309, 6622, 8151, 10858, 78706, 67636, 70171, 12568, 127917, + 12553, 10814, 43275, 6950, 9712, 68680, 43970, 126535, 65165, 92725, 0, + 66466, 124986, 127784, 0, 66725, 6191, 11351, 10437, 11316, 67634, 43763, + 0, 41754, 67635, 9370, 2720, 194600, 68462, 8232, 118817, 121056, 3222, + 121439, 121137, 0, 66663, 983047, 93067, 10834, 983127, 0, 65732, 94095, + 917547, 92682, 67679, 120734, 67309, 7781, 41383, 64568, 67311, 120738, + 12077, 74433, 64586, 917620, 42396, 55255, 3475, 67260, 2479, 67306, + 3632, 120728, 10698, 8376, 3648, 67263, 74844, 67639, 3636, 67894, 3650, + 8837, 65229, 1843, 42283, 43250, 41562, 9100, 74548, 68826, 3640, 127190, + 42321, 7284, 92880, 118987, 194950, 194949, 74115, 194951, 126649, + 194953, 42080, 2529, 0, 983784, 66010, 42083, 74952, 68398, 194957, + 67619, 66367, 194958, 9634, 92380, 9988, 0, 41068, 0, 4295, 65264, 68006, + 0, 67835, 0, 785, 8236, 128647, 9027, 68160, 67623, 64383, 120265, 925, + 127156, 0, 41985, 41071, 9586, 120988, 41984, 9217, 128372, 92510, 92218, + 9186, 2067, 4016, 983803, 0, 381, 12936, 0, 42077, 92985, 69880, 5184, + 42078, 194607, 10810, 128531, 4585, 19943, 5860, 67633, 121334, 127104, + 812, 3615, 72401, 5178, 44000, 92436, 78807, 5188, 74287, 67629, 3605, + 10692, 1166, 64429, 42639, 924, 127793, 67631, 42616, 120670, 2442, + 10703, 67317, 67632, 67316, 12771, 12736, 12753, 66708, 73933, 67626, + 42401, 194865, 69872, 127373, 42288, 12751, 74906, 8542, 13145, 194963, + 2468, 66706, 41294, 3626, 3883, 64388, 42479, 71220, 41117, 0, 92580, + 128624, 74939, 67624, 127976, 1290, 0, 65585, 2715, 806, 65208, 41884, + 917883, 1318, 64731, 78004, 0, 0, 66325, 3465, 2405, 9240, 983858, 12756, + 65259, 0, 983781, 12752, 5833, 1432, 11246, 41883, 73912, 9799, 917893, + 41886, 2480, 127906, 2062, 67326, 6494, 5537, 78656, 0, 194587, 124969, + 1211, 0, 120971, 67269, 118832, 12318, 129024, 113796, 68005, 10622, + 983779, 0, 68821, 6566, 71195, 0, 73780, 119196, 64864, 0, 78660, 0, + 8284, 13081, 119206, 3589, 42051, 4035, 6492, 83003, 4265, 6642, 3977, + 74186, 41778, 836, 92947, 2488, 125096, 4582, 0, 71426, 41777, 12926, + 983379, 7528, 10550, 113761, 92706, 983955, 10961, 93977, 1374, 64878, + 119014, 67720, 42389, 41374, 2286, 917604, 78492, 41377, 127909, 195047, + 400, 12597, 120586, 128097, 129071, 6661, 917961, 64827, 0, 73817, 390, + 0, 71301, 127292, 3473, 7718, 113755, 68814, 0, 55285, 73784, 66394, 0, + 11969, 120461, 127841, 6365, 1887, 6763, 92551, 8080, 7006, 0, 118902, + 6757, 64351, 1544, 67156, 6766, 64677, 120716, 67088, 6146, 74031, 771, + 120682, 0, 12812, 13168, 42272, 12200, 66423, 7904, 0, 953, 12917, + 119560, 12300, 67089, 11491, 9724, 10341, 983773, 9524, 7490, 11389, + 7489, 3379, 0, 7487, 194624, 471, 7484, 7482, 6753, 7480, 5764, 7478, + 7477, 6501, 7475, 6918, 7473, 7472, 2474, 7470, 7468, 10232, 10615, + 10213, 127288, 92357, 10049, 11834, 3544, 983785, 6017, 65311, 74935, + 120216, 13306, 10533, 7870, 73949, 7625, 194882, 120544, 0, 127950, + 92660, 983356, 77889, 0, 19961, 2472, 42665, 92341, 121133, 2139, 4256, + 120776, 74380, 43836, 42675, 42658, 12845, 6666, 70508, 65138, 119355, + 67862, 0, 65671, 7083, 120008, 8066, 7678, 74865, 125134, 120321, 127283, + 983396, 7186, 0, 120555, 0, 445, 120566, 66849, 125141, 0, 8330, 0, 0, + 42797, 113736, 120215, 83001, 3902, 0, 1770, 43959, 125067, 1560, 43958, + 92167, 4584, 73843, 0, 11712, 10866, 67092, 1118, 71334, 74888, 0, 1081, + 7436, 11147, 7252, 70093, 5996, 69921, 4903, 68142, 41386, 5162, 119189, + 1330, 128613, 7139, 0, 12047, 41384, 0, 0, 1848, 4334, 6324, 41975, + 64777, 10674, 12308, 12186, 0, 0, 983741, 12715, 68002, 194576, 83256, + 2018, 66672, 41979, 66685, 119157, 68000, 78490, 0, 126984, 68001, 9334, + 92705, 70800, 70101, 7975, 0, 77957, 0, 43494, 4884, 66597, 69732, 0, + 121010, 6313, 65513, 69857, 0, 0, 0, 2345, 43697, 463, 0, 127890, 68178, + 3117, 5460, 121423, 128717, 983389, 0, 42279, 127142, 126503, 78415, + 983228, 68524, 983386, 13248, 125027, 983843, 43956, 128415, 983153, + 121009, 5663, 71120, 128472, 128958, 0, 2482, 1471, 194583, 113747, + 42247, 12378, 73925, 69664, 71427, 12374, 121357, 127067, 0, 118828, + 2460, 71882, 11944, 12376, 92342, 64679, 92893, 12380, 10557, 64473, + 5870, 11122, 2024, 127180, 983391, 71879, 539, 0, 120302, 70120, 3853, + 65180, 127923, 120796, 120245, 92324, 0, 8659, 0, 12474, 67241, 9503, + 194969, 2478, 120248, 4162, 0, 4260, 12953, 69633, 82966, 12470, 92640, + 74189, 2742, 12476, 11798, 10946, 127310, 5000, 113687, 983579, 128190, + 69672, 8213, 43824, 7771, 6161, 68018, 6709, 194967, 78885, 119243, + 68235, 120582, 78547, 113709, 10301, 10333, 10397, 119044, 0, 73791, 0, + 83030, 0, 121482, 119123, 4014, 12842, 73952, 12015, 127290, 8275, 3893, + 74903, 120927, 12210, 7221, 42147, 74868, 74550, 71215, 64747, 118841, + 128086, 12516, 4444, 0, 92271, 74537, 10892, 8231, 0, 6473, 41968, 78388, + 41973, 3591, 41969, 83008, 2453, 118899, 92666, 64705, 71068, 0, 10349, + 10413, 43591, 41962, 3202, 74353, 129175, 8316, 129174, 0, 94060, 687, + 93055, 129074, 0, 1840, 127809, 68671, 11121, 4883, 285, 4723, 11175, + 92692, 4459, 74577, 42921, 41720, 11089, 240, 19906, 0, 42323, 74640, + 9743, 120232, 13134, 93065, 128956, 65931, 92579, 128329, 42634, 983345, + 43437, 3081, 11463, 120154, 0, 195013, 10445, 121322, 92969, 66717, 2614, + 9125, 71125, 1729, 129034, 72420, 65221, 63883, 43334, 64852, 124929, + 65194, 66201, 0, 66578, 5001, 41879, 74427, 4121, 5003, 884, 66700, + 63879, 4943, 5150, 73889, 73764, 4039, 643, 3086, 92533, 42448, 42299, + 58, 120084, 917952, 120083, 63873, 8491, 0, 0, 983623, 4530, 42409, 7126, + 194575, 2721, 120073, 119096, 19929, 118941, 128797, 92975, 4242, 4264, + 120077, 120530, 66179, 42412, 65941, 13114, 64522, 10740, 3094, 983199, + 9754, 119102, 4437, 73948, 127074, 983240, 55280, 42174, 127954, 42430, + 0, 983452, 42355, 66026, 4306, 41380, 68432, 92586, 68314, 66667, 119351, + 194982, 121172, 42200, 42566, 70000, 128928, 5088, 6948, 0, 8524, 125040, + 0, 12385, 0, 74926, 69646, 1386, 64580, 11480, 6116, 65039, 65038, 12392, + 65036, 8064, 127558, 12101, 5822, 119004, 2080, 710, 77999, 11663, 1666, + 42091, 119657, 12383, 43671, 42092, 68418, 4289, 127897, 63896, 12061, + 42096, 43621, 3362, 12377, 119934, 983834, 68449, 7461, 73901, 1244, 331, + 73786, 12683, 10662, 0, 8112, 0, 65852, 74629, 12379, 127107, 92930, + 41964, 42208, 63843, 2084, 41965, 70089, 65866, 4327, 0, 63840, 66413, + 41220, 13032, 92980, 584, 12933, 43177, 12373, 69855, 13000, 1351, 2935, + 8698, 12665, 0, 1930, 0, 78229, 12427, 66514, 69859, 13031, 0, 63901, 0, + 3657, 119611, 65202, 6000, 113786, 12426, 121058, 119935, 41740, 12428, + 41283, 41916, 119210, 128318, 0, 12429, 6727, 983948, 7562, 125129, 5170, + 983915, 41755, 676, 0, 66704, 66664, 9978, 66491, 3536, 0, 9752, 92397, + 6162, 78320, 69228, 10113, 41829, 65886, 5159, 12422, 41832, 439, 3072, + 917828, 42207, 74549, 11796, 40970, 41830, 125021, 70151, 8308, 917797, + 70807, 119258, 67864, 113696, 917800, 12336, 4135, 67231, 341, 2727, + 4129, 3539, 0, 63861, 0, 7913, 0, 63859, 4131, 63868, 129085, 63867, + 4133, 11371, 210, 4600, 983897, 74560, 4137, 8082, 78506, 119062, 78504, + 6704, 4591, 128029, 43873, 120753, 9680, 12937, 120623, 561, 12159, 195, + 68321, 41501, 194581, 42031, 5719, 7172, 42687, 8368, 128306, 41499, + 93068, 71047, 42242, 41498, 917794, 42025, 78565, 65805, 42463, 67182, + 2924, 67183, 120510, 0, 983972, 92766, 73941, 67186, 42330, 67187, 3969, + 121405, 0, 7169, 1992, 9652, 73977, 7246, 42086, 126615, 2219, 121349, 0, + 128801, 67180, 127569, 327, 121277, 9042, 917777, 917776, 65148, 12433, + 917781, 120222, 83129, 12431, 8668, 12434, 67194, 113812, 5999, 75013, + 7712, 12432, 128243, 43653, 1726, 1015, 74079, 8212, 128065, 113754, + 42423, 119066, 194613, 72398, 66709, 121061, 8811, 927, 92532, 0, 12436, + 120087, 42021, 0, 67644, 1299, 12240, 42350, 65143, 0, 195016, 127972, + 78197, 11348, 0, 78037, 9194, 983184, 0, 19914, 12179, 128740, 2296, + 128932, 63836, 63832, 917773, 10967, 63816, 2594, 3444, 63817, 11178, + 917584, 41503, 127478, 11265, 68295, 120756, 194922, 67285, 5664, 3972, + 120891, 128583, 129408, 67284, 12416, 917764, 119608, 10816, 917769, + 11210, 12418, 8586, 3882, 8532, 917771, 1573, 68081, 119847, 4596, 66339, + 12417, 66001, 65343, 126491, 12414, 8287, 68219, 195017, 68108, 1143, + 119169, 119846, 12415, 6626, 42763, 917594, 118884, 9021, 120783, 119931, + 11724, 127787, 0, 71122, 126619, 0, 983661, 8027, 10997, 9171, 12741, + 11400, 43943, 194799, 66833, 128239, 983707, 92557, 93976, 127523, + 120190, 1324, 67608, 128214, 42368, 983873, 7715, 3881, 41487, 12118, + 42514, 68651, 128210, 128594, 3009, 41476, 41489, 69825, 3007, 1448, + 3018, 194809, 3889, 8521, 5083, 5082, 119859, 78255, 8519, 121226, 3014, + 5081, 65853, 120715, 194992, 68014, 69951, 5079, 64802, 42210, 4597, + 65532, 11828, 120185, 12371, 11105, 8407, 67163, 10805, 8518, 10779, + 120188, 71303, 121240, 12367, 42170, 0, 67290, 629, 1924, 127098, 12037, + 67158, 5987, 8462, 8005, 12365, 63933, 69735, 120815, 12369, 10649, + 67981, 5077, 120174, 10880, 63927, 5075, 121109, 127300, 65075, 0, 11007, + 70851, 66659, 92607, 917933, 66684, 128063, 3434, 4954, 1904, 92679, + 5266, 126980, 5272, 10499, 4507, 9578, 63923, 120177, 7979, 0, 9831, 0, + 194926, 461, 9803, 42282, 4504, 1505, 127893, 6325, 5276, 43021, 120488, + 0, 55236, 92659, 66461, 5177, 41324, 12055, 8722, 120805, 41327, 983732, + 66695, 4114, 409, 4383, 8900, 8948, 41325, 74930, 721, 10182, 9108, + 71311, 0, 119185, 42229, 74963, 121014, 5998, 0, 42353, 74825, 0, 12587, + 94104, 78571, 74889, 71328, 128955, 41576, 42215, 78570, 74037, 0, 8578, + 5995, 7573, 41575, 74789, 74752, 63944, 63949, 64767, 2670, 4167, 194796, + 11723, 0, 74120, 126642, 65076, 938, 43414, 73854, 11737, 9721, 0, 67179, + 67168, 11742, 2419, 67177, 11493, 12334, 92494, 4153, 12302, 10793, 5250, + 12407, 11978, 4404, 9189, 12401, 42007, 5775, 6759, 65806, 43997, 0, + 42002, 12404, 68092, 74928, 4940, 12410, 7683, 1167, 73729, 4983, 120507, + 861, 67699, 74880, 68297, 983807, 43757, 43370, 129298, 0, 11956, 124967, + 121263, 70815, 9616, 6631, 92338, 12816, 43759, 42218, 12710, 68674, + 12721, 4101, 66185, 0, 5992, 7616, 195044, 0, 12577, 93017, 128289, 853, + 42693, 194647, 119027, 983284, 5016, 43535, 63893, 42835, 9491, 917913, + 0, 917914, 0, 12712, 7105, 127807, 65060, 66875, 9900, 7750, 917946, + 127896, 74619, 119265, 983587, 64778, 12585, 10565, 128151, 12177, + 119843, 983260, 0, 77824, 0, 4900, 127874, 12878, 92630, 8984, 4119, + 74768, 8971, 78593, 43113, 9702, 66852, 11025, 9245, 13048, 4927, 4138, + 74185, 92481, 92710, 12397, 77827, 119040, 13054, 12394, 0, 0, 194954, + 13053, 118974, 3948, 10781, 1546, 0, 5010, 1680, 10507, 78590, 78583, + 92431, 121037, 126644, 194915, 7267, 127479, 74833, 128181, 5993, 2819, + 128788, 12706, 71063, 1893, 7266, 63915, 7264, 7265, 0, 1363, 983580, + 42923, 63910, 63996, 3077, 120018, 0, 1512, 69929, 12589, 41479, 128313, + 71048, 43339, 73776, 9836, 120727, 983909, 41481, 43335, 7832, 42343, + 3090, 43337, 817, 1664, 1850, 83177, 3079, 11340, 42408, 42447, 74932, + 74044, 42307, 12386, 42304, 917555, 83428, 12389, 121079, 92366, 41996, + 11526, 63985, 5864, 1147, 43849, 42887, 1987, 92718, 5480, 7858, 11653, + 4116, 12391, 66193, 121383, 4939, 12384, 0, 127778, 41686, 63905, 119601, + 70285, 67398, 128820, 12649, 120022, 0, 8247, 507, 91, 2042, 120775, + 43643, 121445, 66028, 10036, 41844, 119813, 774, 119829, 77840, 119815, + 5994, 12539, 0, 78375, 120597, 119833, 983105, 78377, 983237, 917628, + 7719, 6026, 2486, 128312, 119808, 162, 0, 65219, 41073, 9687, 41681, + 6304, 119812, 66196, 194881, 5262, 0, 55233, 12681, 42379, 0, 7534, + 12219, 2226, 70499, 42810, 10492, 121510, 121148, 121509, 43119, 0, + 78537, 12403, 2500, 70145, 83246, 4899, 12729, 983399, 194619, 74113, + 2343, 4103, 19946, 74112, 77851, 13112, 129046, 74834, 12859, 70087, + 120148, 66369, 5861, 127758, 11999, 12400, 43641, 128183, 12645, 5146, + 11320, 68410, 6748, 65040, 194786, 64184, 12974, 64183, 67613, 120645, + 5147, 125019, 0, 74524, 128356, 1928, 0, 67649, 5991, 3445, 67609, 4976, + 64176, 0, 67610, 8241, 0, 77868, 4206, 0, 78662, 129029, 128298, 67277, + 10138, 67238, 128785, 8897, 120234, 1422, 8357, 4124, 77862, 65836, + 120641, 127926, 77859, 0, 120930, 1123, 963, 41553, 10120, 12405, 120150, + 92664, 398, 13278, 9723, 6366, 120311, 7945, 129126, 4402, 9970, 12402, + 93062, 42392, 1305, 12408, 92384, 44007, 128563, 127216, 41464, 12411, + 12969, 67268, 41465, 121092, 8528, 1575, 0, 63955, 165, 3024, 41467, + 119163, 70119, 9093, 128535, 6833, 92574, 63958, 0, 9148, 9692, 4096, 53, + 8296, 6750, 66855, 128410, 9594, 120308, 120938, 43527, 121192, 727, + 74192, 93060, 5805, 0, 6726, 0, 42176, 12370, 11655, 119095, 10591, 2280, + 983234, 12372, 120642, 120307, 71209, 92343, 983872, 12366, 10963, 6066, + 1329, 0, 3052, 9220, 121045, 64478, 194701, 10803, 4132, 120306, 68474, + 92473, 983247, 120712, 74837, 120155, 1499, 0, 8055, 42740, 63965, + 120305, 63962, 74042, 8924, 43123, 5988, 3660, 63969, 11781, 42718, 8788, + 1357, 64851, 65743, 92894, 8774, 70337, 127086, 9941, 120172, 92748, + 1933, 69655, 9564, 120016, 92435, 73866, 0, 121241, 2487, 67614, 3121, + 1804, 3311, 67615, 70081, 78302, 12220, 67616, 92769, 120020, 194594, + 68200, 6675, 128144, 0, 67592, 120685, 0, 64771, 1198, 9132, 0, 64619, + 510, 64663, 0, 121500, 4561, 2101, 1398, 917972, 92554, 74034, 41569, + 92684, 11406, 8167, 12127, 120505, 840, 983283, 69992, 7101, 6967, 0, + 194898, 9796, 127000, 333, 69891, 0, 8144, 2117, 0, 121155, 12406, + 917970, 19931, 66388, 6678, 7769, 983124, 12621, 0, 127366, 10227, 4764, + 43101, 9981, 0, 40986, 4127, 66487, 983576, 42202, 12754, 195021, 983191, + 0, 94097, 67594, 2048, 12944, 4050, 67595, 917967, 43102, 10581, 11184, + 4533, 127212, 74003, 6490, 0, 12038, 0, 0, 68225, 65461, 9798, 69704, + 128912, 1948, 69841, 0, 952, 128235, 125107, 983354, 70296, 6449, 9494, + 120313, 0, 43098, 4843, 8142, 64160, 4098, 64170, 983341, 0, 3436, + 119973, 0, 12817, 67597, 6676, 3930, 42615, 66407, 69991, 67598, 0, 0, 0, + 65591, 41581, 65916, 1453, 194993, 121458, 127859, 8500, 42222, 120142, + 73743, 120400, 4317, 11543, 67676, 64676, 0, 127833, 67606, 119083, + 121083, 42217, 13102, 0, 66003, 6672, 0, 0, 66880, 77912, 63841, 9613, + 9001, 4526, 11274, 67601, 64520, 64210, 6664, 78704, 42056, 10228, 64957, + 11281, 0, 3807, 1469, 66640, 65381, 42197, 4988, 42372, 0, 9598, 904, + 352, 42225, 1451, 8061, 8453, 4134, 83485, 67223, 66576, 127916, 127831, + 10520, 8575, 9960, 1201, 127289, 12846, 127291, 68040, 11919, 64962, + 127081, 43739, 127281, 8511, 9460, 823, 11587, 12305, 0, 64695, 127305, + 12387, 1253, 13183, 65766, 500, 42783, 65765, 64208, 64369, 65760, 65761, + 70334, 11606, 64784, 11702, 66498, 9821, 64304, 127369, 5152, 11048, + 7533, 68366, 64410, 92305, 0, 4323, 70276, 92669, 71332, 120158, 42587, + 42214, 41394, 11188, 4763, 4112, 118935, 0, 5260, 43143, 94038, 326, + 120131, 68423, 119218, 10771, 2876, 74074, 92530, 128460, 41398, 7382, + 9802, 127077, 127076, 453, 41396, 120524, 13159, 12140, 9572, 983132, + 7003, 194883, 42334, 7704, 125069, 125020, 43144, 4123, 8494, 43146, + 9977, 0, 121283, 65759, 10765, 64061, 4465, 9808, 64056, 65582, 4126, 0, + 9521, 9589, 64755, 0, 64020, 126604, 10464, 0, 92968, 194610, 64514, + 11528, 64024, 128072, 679, 64013, 983555, 5850, 758, 7536, 120538, 92234, + 41441, 10693, 64006, 75044, 64005, 4058, 119019, 126487, 64660, 128176, + 119050, 0, 983069, 1139, 43298, 64027, 64029, 8970, 0, 9934, 128685, + 10774, 67104, 42201, 12421, 128216, 127006, 1852, 3057, 64046, 73744, + 64034, 64039, 68065, 0, 983690, 92913, 92322, 7645, 12854, 74338, 3496, + 0, 121323, 113710, 9102, 627, 127795, 6158, 8327, 74553, 66632, 12419, + 13309, 11570, 127811, 19960, 11696, 0, 1018, 118970, 129075, 194897, + 1682, 43863, 194896, 42756, 6765, 194906, 67717, 74358, 73814, 11412, + 6768, 10728, 119982, 71316, 71099, 43311, 64966, 11577, 127832, 43040, + 1833, 11576, 70054, 74779, 0, 185, 65085, 74533, 64754, 119334, 7535, + 8085, 42525, 119944, 9749, 41701, 6131, 1949, 4117, 7847, 120489, 120997, + 64483, 65693, 983711, 983495, 128615, 69695, 42240, 128587, 121352, + 42864, 126498, 43168, 41868, 1184, 0, 815, 11484, 127535, 67840, 983651, + 0, 66197, 983474, 10986, 64683, 128549, 128454, 3455, 126530, 0, 9879, 0, + 0, 4158, 70307, 68166, 0, 128091, 0, 0, 69645, 332, 118808, 83368, 5142, + 2407, 69643, 42199, 0, 92404, 74373, 83372, 55217, 71457, 63870, 43163, + 0, 0, 12985, 42867, 1834, 120387, 92461, 69817, 10940, 65249, 70385, + 8662, 120324, 0, 2652, 120527, 7164, 10784, 195093, 67674, 0, 83359, + 92482, 194749, 74562, 917505, 1828, 74474, 120019, 68078, 8531, 12499, + 6280, 12324, 72434, 65238, 68374, 4832, 65573, 43851, 6279, 12508, 12904, + 12502, 9161, 128555, 1620, 11247, 3601, 121301, 83353, 67246, 609, 11555, + 83456, 12496, 11980, 74181, 4343, 12505, 82960, 127863, 0, 11377, 239, + 128114, 637, 0, 128678, 42671, 0, 93032, 83095, 43565, 71306, 126493, + 12696, 128256, 917600, 94062, 12929, 0, 712, 0, 4197, 983206, 42818, + 126632, 70306, 120490, 70333, 119137, 1506, 43562, 119913, 92491, 68076, + 12651, 120917, 64628, 74517, 12058, 74084, 194633, 7494, 0, 4924, 65592, + 118844, 194823, 127088, 355, 9719, 127087, 13066, 64796, 121077, 983297, + 12033, 42178, 194754, 69760, 42571, 92635, 11430, 0, 70299, 121508, + 124951, 68324, 3178, 126488, 128633, 92704, 917566, 9080, 120943, 67697, + 195101, 68209, 72418, 11082, 71485, 5699, 83373, 66000, 9488, 65166, + 119112, 70477, 11170, 68662, 128120, 71313, 0, 5265, 69235, 83384, 11487, + 67858, 12464, 983365, 43045, 983831, 70345, 43345, 983276, 10770, 118994, + 6807, 465, 9829, 69997, 74348, 0, 43346, 8116, 795, 120352, 72412, 12462, + 10930, 10831, 121320, 118952, 64362, 74334, 93056, 83047, 983933, 12468, + 8607, 1008, 118948, 10092, 125122, 128851, 67855, 55257, 73771, 1766, + 11282, 11996, 1820, 4547, 0, 11202, 120243, 128345, 13223, 74934, 64595, + 127294, 83374, 68489, 4345, 12616, 917784, 128947, 983155, 74467, 0, + 983819, 128291, 5382, 127779, 0, 67233, 119060, 64953, 5406, 19920, + 69897, 66510, 3590, 194835, 1130, 917766, 120977, 42016, 11823, 43023, + 121002, 118896, 7742, 127374, 13280, 71323, 9326, 73826, 5310, 43509, + 78584, 92229, 8959, 43589, 6747, 66723, 64757, 8568, 194684, 120496, + 73816, 83060, 128418, 42670, 0, 11621, 12460, 1326, 120631, 83393, 43063, + 43239, 65678, 194840, 73917, 7843, 69783, 11689, 5410, 5783, 10468, 8403, + 5400, 11594, 120405, 68333, 83390, 10491, 69842, 64412, 0, 128012, 5587, + 42865, 64404, 8268, 4923, 65086, 8981, 12382, 42133, 120755, 9706, 69738, + 70294, 66610, 10461, 12103, 0, 8642, 83388, 42766, 83387, 2210, 9983, + 128689, 94009, 0, 0, 0, 7398, 41515, 0, 11802, 8041, 1461, 910, 119133, + 0, 6749, 3658, 93964, 120525, 0, 7617, 194841, 12888, 127983, 67668, + 13143, 0, 9193, 11097, 5703, 128247, 41517, 41504, 41519, 10016, 64305, + 0, 65864, 623, 781, 670, 10660, 5769, 613, 7543, 120279, 477, 41083, + 92521, 0, 592, 1578, 12459, 43449, 0, 0, 8225, 121191, 654, 11345, 653, + 652, 0, 647, 83266, 633, 120744, 983809, 126472, 12480, 43243, 194909, + 39, 12487, 121247, 120529, 74199, 12482, 0, 12489, 119607, 3195, 5550, + 129121, 7897, 127089, 1203, 74396, 1813, 64544, 41311, 12090, 983634, + 2877, 121518, 70496, 1675, 69840, 0, 0, 119078, 10070, 10595, 0, 119077, + 194777, 121162, 67170, 120790, 118787, 43244, 92233, 917835, 983916, + 119561, 983078, 194914, 194921, 128160, 9939, 0, 983151, 77860, 128948, + 83440, 270, 0, 10714, 118983, 72437, 0, 119942, 119338, 65372, 73803, + 74038, 68251, 6273, 66679, 364, 9595, 71440, 0, 0, 707, 194839, 128409, + 9282, 11163, 224, 128588, 68670, 9332, 4966, 68677, 194586, 68644, + 983131, 3841, 67357, 67341, 10732, 68640, 850, 4972, 127181, 12890, 2909, + 68619, 44008, 68627, 120699, 11544, 10203, 9608, 0, 917943, 11962, + 121397, 12507, 1196, 67684, 67100, 777, 120187, 4375, 65271, 67678, 0, + 12198, 917887, 64824, 119343, 127243, 9454, 63778, 8658, 42528, 70073, + 2705, 128680, 41520, 195098, 120379, 11986, 7765, 42502, 8280, 74520, + 2701, 0, 120240, 5767, 0, 195018, 9809, 8353, 63747, 66701, 63772, + 121233, 63745, 1748, 63770, 121419, 121078, 0, 65542, 63766, 55244, 3061, + 78609, 63764, 63787, 9067, 6096, 0, 7694, 0, 7257, 63768, 3485, 12987, + 127781, 127522, 120628, 63807, 1591, 0, 6386, 63783, 120990, 125041, + 92535, 0, 0, 68249, 74575, 127010, 65719, 13083, 64574, 65012, 121452, + 1640, 12495, 66691, 7624, 3138, 10996, 11171, 1922, 127275, 12498, 10987, + 69936, 69939, 3894, 65543, 129183, 194842, 128112, 493, 0, 43197, 1717, + 4228, 479, 10303, 74020, 0, 917935, 10335, 3520, 917932, 12490, 64315, + 92170, 127039, 12493, 6233, 42681, 1002, 12491, 83519, 64911, 83521, + 2096, 65120, 83516, 78219, 83270, 8378, 11632, 68838, 66213, 63864, 66221, 66226, 66229, 13218, 66231, 66216, 8507, 66236, 66211, 66218, 92672, 66240, 78041, 66233, 8928, 983552, 7909, 66234, 11605, 63759, - 983654, 66208, 73999, 63799, 63803, 244, 11542, 12898, 12494, 73761, - 12492, 12669, 0, 0, 74153, 0, 128278, 120680, 4882, 13040, 0, 8612, 4885, - 74053, 0, 13042, 4880, 64662, 2429, 1360, 248, 0, 63797, 92394, 42358, 0, - 7292, 0, 63756, 42786, 66693, 0, 1870, 78040, 470, 78038, 78035, 78036, - 70028, 78034, 4579, 128090, 0, 12511, 74453, 12514, 0, 74579, 7239, 7001, - 8623, 94011, 128052, 128048, 7378, 12512, 11615, 6104, 0, 0, 659, 6098, - 0, 12234, 127307, 127067, 8311, 12510, 41803, 13039, 127072, 12513, - 10202, 12471, 0, 8747, 983920, 0, 0, 2323, 0, 2319, 77917, 12477, 77916, - 2311, 0, 4415, 237, 6281, 127280, 0, 0, 2309, 1312, 8173, 128871, 12469, - 0, 78505, 64335, 10609, 0, 128111, 9397, 11524, 9395, 9396, 9393, 9394, - 9391, 9392, 9389, 6209, 9387, 9388, 4932, 9386, 9383, 9384, 6740, 0, - 65451, 8185, 0, 917832, 43024, 43336, 67659, 2313, 128167, 7948, 9236, - 92571, 0, 0, 10570, 43473, 6289, 10484, 0, 0, 11998, 12082, 10924, 3147, - 0, 120684, 12524, 119081, 2310, 11818, 9381, 9382, 9379, 9380, 9377, - 9378, 9375, 9376, 1683, 9374, 983778, 9372, 12444, 0, 0, 13016, 8210, - 983958, 42029, 11079, 12331, 43451, 42032, 8744, 726, 0, 983837, 4155, 0, - 0, 42030, 5007, 12522, 43088, 0, 4951, 127805, 127240, 0, 9922, 43309, - 983841, 12525, 983471, 12016, 65770, 9548, 67665, 403, 78230, 12503, 0, - 0, 11030, 0, 92567, 65691, 63998, 1819, 10496, 0, 0, 119920, 0, 194668, - 0, 12506, 0, 12231, 0, 12500, 44023, 12509, 64393, 78830, 3389, 10589, - 6608, 41047, 120321, 78395, 78394, 74069, 77995, 78391, 3608, 8281, - 120320, 1107, 0, 9076, 8862, 69743, 41052, 13084, 64766, 43217, 7803, - 13222, 74165, 74782, 126514, 8546, 11553, 63995, 13177, 9043, 6303, - 983947, 498, 64471, 120324, 128567, 12529, 8042, 0, 2344, 12528, 8031, - 2414, 0, 69719, 3231, 0, 6422, 66512, 69653, 12530, 2537, 78405, 41429, - 12658, 13036, 65772, 0, 78738, 41433, 4719, 469, 0, 4363, 3313, 41428, - 78407, 2023, 1772, 78224, 78225, 65706, 10051, 64812, 78220, 0, 9920, - 12215, 0, 4931, 1951, 12497, 119363, 9607, 0, 9663, 983228, 119634, 6503, - 41110, 0, 1491, 0, 0, 127304, 41061, 0, 194838, 127187, 65026, 41993, - 41509, 11045, 65028, 78602, 66476, 41108, 9738, 41995, 1075, 1958, 12535, - 41992, 41506, 0, 41687, 0, 120717, 127776, 9940, 127299, 7692, 983833, - 8008, 41131, 330, 8566, 65083, 41133, 9816, 126517, 12532, 78550, 78546, - 3508, 127058, 43235, 0, 127298, 64139, 78231, 6411, 12910, 78554, 66644, - 13028, 6737, 12537, 0, 0, 64136, 12536, 2350, 13029, 78233, 0, 983103, - 13030, 6702, 4527, 0, 12538, 128810, 983645, 65599, 65717, 9966, 0, 4948, - 12484, 4032, 128149, 12623, 0, 6207, 0, 6117, 65930, 8412, 0, 7438, 1296, - 2325, 41511, 126625, 10149, 74118, 0, 127286, 12481, 0, 12488, 66713, 0, - 41556, 64414, 118802, 2354, 42619, 73766, 0, 6295, 901, 41510, 7953, 0, - 65032, 41513, 983166, 11927, 66584, 78559, 78560, 78557, 78558, 0, 78556, - 848, 9868, 0, 6424, 78568, 119338, 69922, 74031, 78563, 78564, 2352, - 78572, 893, 64576, 11289, 1407, 67973, 0, 13026, 6762, 78579, 78580, - 13023, 8903, 9777, 66715, 1871, 8099, 0, 0, 1343, 983823, 0, 9325, 6818, - 6283, 11738, 0, 983934, 0, 11741, 0, 0, 9216, 8263, 11279, 194752, - 983825, 194754, 13021, 64494, 3136, 194758, 194757, 194760, 13022, 42737, - 9956, 0, 0, 74552, 10014, 0, 41260, 119340, 13020, 10024, 194764, 74583, - 74340, 69681, 0, 43001, 8029, 0, 0, 983780, 3335, 0, 0, 9776, 120526, + 127308, 66208, 67339, 13002, 63803, 244, 11542, 12898, 12494, 73761, + 12492, 12669, 94070, 0, 74153, 120310, 128278, 120680, 4882, 13040, + 983362, 8612, 4885, 74053, 127830, 13042, 4880, 64662, 2429, 1360, 248, + 129066, 63797, 92394, 42358, 0, 7292, 0, 63756, 42786, 66693, 0, 1870, + 78040, 470, 78038, 78035, 78036, 70028, 78034, 4579, 69232, 0, 12511, + 74453, 12514, 0, 71130, 7239, 7001, 8623, 94011, 125137, 128048, 7378, + 12512, 11615, 6104, 0, 120900, 659, 6098, 0, 12234, 83511, 67358, 8311, + 12510, 7669, 13039, 83509, 12513, 10202, 12471, 0, 8747, 121385, 70193, + 128354, 2323, 0, 2319, 77917, 12477, 77916, 2311, 7666, 4415, 237, 6281, + 127280, 983311, 83020, 2309, 1312, 8173, 83013, 12469, 83015, 78505, + 64335, 10609, 83011, 78006, 9397, 11524, 9395, 9396, 9393, 9394, 9391, + 9392, 9389, 6209, 9387, 9388, 4932, 9386, 9383, 9384, 6740, 127990, + 65451, 8185, 128931, 194843, 43024, 43336, 67659, 2313, 128167, 7948, + 9236, 77942, 0, 0, 10570, 43473, 6289, 10484, 83006, 83007, 11998, 12082, + 10924, 3147, 83004, 66406, 12524, 119081, 2310, 11818, 9381, 9382, 9379, + 9380, 9377, 9378, 9375, 9376, 1683, 9374, 983778, 9372, 12444, 74256, 0, + 13016, 8210, 121062, 42029, 11079, 12331, 43451, 42032, 8744, 726, 0, + 120630, 4155, 121090, 120704, 42030, 5007, 12522, 43088, 0, 4951, 113826, + 127217, 983202, 9922, 43309, 11211, 12525, 983473, 12016, 65770, 9548, + 67665, 403, 78230, 12503, 194689, 127191, 11030, 43916, 92567, 65691, + 63998, 1819, 10496, 0, 0, 119920, 0, 129143, 121072, 12506, 983838, + 11146, 71477, 12500, 44023, 12509, 64393, 78830, 3389, 10589, 6608, + 11208, 120236, 78395, 78394, 74069, 71446, 78391, 3608, 8281, 113732, + 1107, 113745, 9076, 8862, 69743, 41052, 13084, 64766, 43217, 7803, 13222, + 74165, 74782, 43499, 8546, 11553, 63995, 13177, 9043, 6303, 113664, 498, + 64471, 77987, 92974, 12529, 8042, 43899, 2344, 12528, 8031, 2414, 74506, + 69719, 3231, 917836, 6422, 66512, 69653, 12530, 2537, 78405, 41429, + 12658, 13036, 65772, 0, 78738, 41433, 4719, 469, 917810, 4363, 3313, + 41428, 78407, 2023, 1772, 78224, 78225, 65706, 10051, 64812, 78220, + 74237, 9920, 12215, 82978, 4931, 1951, 12497, 119363, 9607, 70368, 9663, + 66838, 119634, 6503, 41110, 983467, 1491, 66847, 129169, 127304, 41061, + 70454, 194838, 127187, 65026, 41993, 41509, 11045, 65028, 71181, 66476, + 41108, 9738, 41995, 1075, 1958, 12535, 41992, 41506, 127002, 41687, 0, + 120717, 127776, 9940, 127299, 7692, 983833, 8008, 41131, 330, 8566, + 65083, 6839, 9816, 126517, 12532, 78550, 78546, 3508, 127058, 43235, + 120351, 127298, 64139, 78231, 6411, 12910, 67710, 66644, 13028, 6737, + 12537, 0, 43506, 64136, 12536, 2350, 13029, 78233, 120914, 43897, 13030, + 6702, 4527, 71250, 12538, 128810, 983645, 65599, 65717, 9966, 93046, + 4948, 12484, 4032, 121177, 12623, 0, 6207, 983225, 6117, 65930, 8412, + 127183, 7438, 1296, 2325, 41511, 121020, 10149, 74118, 0, 120233, 12481, + 121280, 12488, 66713, 0, 41556, 64414, 118802, 2354, 42619, 73766, + 119244, 6295, 901, 41510, 7953, 0, 65032, 41513, 120209, 11927, 66584, + 78559, 78560, 78557, 71459, 83034, 67603, 848, 9868, 67220, 6424, 78568, + 67226, 69922, 70190, 78563, 78564, 2352, 67219, 893, 64576, 11289, 1407, + 67973, 983193, 13026, 6762, 78579, 70192, 13023, 8903, 9777, 66715, 1871, + 8099, 127984, 0, 1343, 917999, 120784, 9325, 6818, 6283, 11738, 0, 72436, + 113713, 11741, 917986, 75043, 9216, 8263, 11279, 83023, 83024, 83025, + 13021, 64494, 3136, 194758, 194757, 194760, 13022, 42737, 9956, 0, 43954, + 74552, 10014, 0, 41260, 119340, 13020, 10024, 194764, 74583, 74340, + 69681, 0, 43001, 8029, 0, 0, 983780, 3335, 119341, 9209, 9776, 120526, 194748, 5215, 42644, 3333, 1632, 194751, 64849, 3342, 78582, 5363, 12957, - 78581, 4156, 0, 0, 6421, 78591, 1611, 78589, 13018, 74257, 78588, 74542, - 3337, 4537, 67895, 11736, 0, 68608, 6482, 4214, 73790, 11945, 0, 13046, - 8838, 425, 4025, 10709, 78595, 2108, 2392, 13047, 0, 0, 6819, 13049, - 6499, 92243, 12424, 68614, 73944, 13050, 9924, 194745, 6507, 127919, - 94073, 128069, 3277, 8929, 4947, 41055, 0, 194722, 194721, 194724, 13045, - 64626, 66034, 7751, 194727, 8371, 194729, 3997, 12806, 8768, 13044, 0, - 12420, 4024, 194730, 41054, 1078, 9757, 69736, 41057, 0, 0, 0, 0, 983791, - 92210, 92411, 0, 41496, 0, 9165, 1572, 11911, 0, 118842, 2346, 13270, - 8958, 0, 9646, 3773, 43183, 6401, 5831, 0, 0, 13043, 8056, 92494, 65681, - 208, 127382, 41514, 0, 0, 0, 10699, 6408, 92227, 7825, 5661, 0, 120630, - 3603, 41109, 2398, 3548, 126596, 0, 119933, 0, 3115, 9918, 0, 8294, - 42912, 0, 0, 194726, 4876, 65804, 0, 0, 43468, 983274, 41558, 41471, + 78581, 4156, 0, 127329, 6421, 78039, 1611, 78589, 13018, 74257, 78588, + 74542, 3337, 4537, 67895, 11736, 0, 68608, 6482, 4214, 73790, 11945, + 43925, 13046, 8838, 425, 4025, 10709, 78595, 2108, 2392, 13047, 92745, 0, + 6819, 13049, 6499, 92243, 12424, 68614, 65827, 13050, 9924, 194745, 6507, + 127919, 94073, 128069, 3277, 8929, 4947, 41055, 0, 194722, 194721, + 194724, 13045, 64626, 66034, 7751, 194727, 8371, 121036, 3997, 12806, + 8768, 13044, 0, 12420, 4024, 128000, 41054, 1078, 9757, 69736, 41057, + 68307, 917842, 0, 0, 983791, 92210, 92411, 129303, 41496, 0, 9165, 1572, + 11911, 124990, 118842, 2346, 13270, 8958, 0, 9646, 3773, 43183, 6401, + 5831, 0, 120865, 13043, 8056, 70108, 65681, 208, 127382, 41514, 0, + 121048, 983884, 10699, 6408, 92227, 7825, 5661, 82972, 82973, 3603, + 41109, 2398, 3548, 82969, 82970, 119933, 82964, 3115, 9918, 127823, 8294, + 42912, 0, 127287, 194726, 4876, 65804, 0, 0, 43468, 121221, 41558, 41471, 73950, 8158, 9944, 41472, 120298, 13051, 78689, 3143, 194674, 6701, - 41559, 1896, 66256, 13052, 194680, 5665, 0, 119071, 7025, 63974, 0, + 41559, 1896, 65215, 13052, 194680, 5665, 78594, 119071, 7025, 63974, 0, 74352, 74161, 4154, 9863, 43550, 12310, 5662, 42382, 1564, 73924, 1121, - 78319, 63959, 0, 9942, 13231, 0, 64752, 4732, 194666, 11596, 119931, - 65187, 1626, 63983, 10110, 64772, 42024, 6420, 42028, 0, 10509, 2795, - 4910, 194728, 69231, 64753, 6275, 93957, 118830, 63978, 11044, 3229, - 6423, 42774, 0, 0, 0, 12823, 2331, 917810, 7085, 6137, 0, 7524, 0, - 917809, 8346, 0, 8338, 128315, 65043, 0, 822, 127984, 9903, 64721, 42722, - 69877, 194659, 78655, 78661, 194660, 78662, 41265, 5311, 1795, 965, - 118791, 10587, 78055, 11278, 78632, 194640, 0, 12946, 194641, 119341, - 120349, 6294, 3144, 194648, 194647, 65019, 194649, 73990, 0, 983960, 748, - 41067, 2330, 535, 3148, 12375, 78799, 194629, 10556, 2475, 12388, 4889, - 8968, 67863, 3593, 0, 0, 2342, 0, 194634, 65206, 4894, 194635, 4890, - 194637, 917804, 581, 4893, 983616, 6571, 65545, 4888, 4157, 78048, 78049, - 78046, 78047, 0, 10119, 6415, 42893, 0, 69702, 0, 0, 11375, 64746, 2332, - 78063, 412, 78061, 64932, 42880, 43587, 0, 0, 0, 0, 65197, 78066, 12203, - 78064, 78065, 8913, 65854, 4875, 65811, 120381, 120389, 118888, 9344, - 8826, 120386, 120395, 13104, 74781, 11997, 120393, 78075, 0, 3134, 0, - 65696, 92331, 0, 66217, 0, 8334, 119344, 0, 3449, 0, 0, 78414, 78413, - 118950, 74011, 0, 0, 0, 0, 1908, 120167, 4328, 10734, 127014, 0, 127914, - 7804, 78272, 10811, 6250, 11339, 4914, 11367, 0, 78054, 4917, 74516, - 74208, 64285, 4912, 5464, 127836, 118893, 2361, 7971, 78072, 78073, - 55243, 78071, 0, 8086, 74317, 6707, 8319, 2312, 40977, 10960, 40962, - 8305, 12573, 983608, 40980, 983964, 13202, 0, 12582, 78282, 983048, - 69856, 42438, 55221, 6288, 78280, 127946, 5653, 42400, 10891, 7698, 5658, - 74045, 70039, 0, 0, 4913, 0, 983959, 71333, 42326, 128194, 12728, 92685, - 42478, 2327, 0, 12563, 42287, 12705, 0, 0, 12588, 8821, 6153, 2867, - 194708, 66312, 698, 128007, 194606, 10356, 70017, 194713, 651, 12641, 0, - 0, 0, 0, 41552, 65115, 78465, 78467, 78463, 78464, 128851, 78461, 194697, - 74356, 64945, 4716, 43277, 0, 78474, 12340, 120568, 0, 194700, 55264, - 41211, 120676, 8703, 5462, 917629, 983495, 10101, 0, 70049, 8479, 4151, - 41933, 0, 0, 66254, 120821, 0, 0, 128654, 0, 119194, 74050, 92701, 0, 0, - 0, 0, 0, 12278, 0, 0, 0, 2700, 12576, 7842, 12899, 0, 0, 2699, 0, 73845, - 2985, 92568, 126475, 917845, 12192, 119314, 0, 119312, 9827, 119310, - 119311, 119308, 119309, 119306, 11481, 41210, 119305, 0, 35, 78481, - 78482, 66694, 68479, 78477, 78478, 43596, 6090, 64257, 7812, 10534, 0, - 78485, 73848, 67975, 4272, 0, 40967, 40964, 917825, 12704, 78487, 43306, - 0, 64497, 12138, 7930, 0, 2292, 68216, 0, 917826, 5244, 4189, 94108, - 67596, 127504, 4188, 1879, 0, 968, 0, 43743, 0, 8873, 2279, 0, 917827, - 65555, 12574, 0, 0, 0, 74490, 127099, 43657, 0, 0, 0, 42682, 12578, - 12720, 0, 41227, 0, 12346, 127101, 64848, 0, 0, 7251, 0, 0, 118850, - 119141, 128546, 66015, 0, 959, 8885, 12564, 66457, 78808, 9469, 9632, - 92323, 74761, 64323, 127335, 0, 0, 0, 310, 0, 41281, 10976, 0, 71325, 0, - 74266, 10054, 6497, 8574, 0, 9012, 19958, 74420, 65089, 13215, 12730, - 65163, 74044, 374, 43195, 816, 120161, 0, 0, 41934, 7465, 0, 128168, - 983268, 4715, 6101, 94106, 41936, 0, 4879, 0, 65446, 0, 307, 127147, - 9585, 5374, 983267, 128059, 0, 0, 126618, 120390, 0, 65567, 120614, 1929, - 0, 12142, 0, 12236, 41419, 194618, 120610, 12982, 194623, 5378, 78791, - 128679, 41421, 0, 4462, 0, 126599, 128092, 821, 0, 2498, 5800, 120157, - 983115, 1760, 2421, 4469, 2324, 828, 3611, 78400, 757, 1185, 0, 78770, - 43597, 10628, 74808, 194572, 7999, 43971, 0, 0, 10634, 10942, 7713, 2348, - 0, 64374, 4380, 194608, 119044, 9982, 64324, 41240, 862, 65626, 78462, - 1810, 3673, 5137, 194617, 0, 7277, 65622, 0, 7566, 64688, 194593, 194592, - 78092, 74357, 194597, 4748, 92228, 194598, 194601, 42260, 5871, 119075, - 0, 74576, 44019, 0, 128189, 3967, 194604, 13137, 8775, 127945, 0, 2963, - 0, 8410, 4454, 723, 127882, 966, 4449, 92330, 92238, 0, 7819, 2320, - 194589, 339, 4968, 194590, 120399, 8075, 55276, 0, 8047, 0, 78827, 12634, - 41542, 78780, 7466, 6705, 12174, 42610, 0, 74452, 983763, 1584, 66645, - 6045, 6729, 120640, 65218, 11559, 0, 78062, 7537, 0, 11370, 0, 10330, 0, - 10394, 0, 74194, 0, 127929, 9780, 0, 13092, 194576, 77950, 194578, 7074, - 92648, 194579, 194582, 11414, 128868, 2531, 13034, 0, 0, 4211, 1259, - 7517, 0, 0, 194561, 40996, 13037, 7092, 641, 5219, 94034, 194566, 11064, - 41129, 0, 42850, 13035, 9075, 92387, 5466, 128153, 0, 64098, 65793, 4535, - 194573, 4271, 78417, 128357, 6769, 41410, 983452, 64262, 6767, 41407, 0, - 0, 6755, 118864, 9046, 127934, 126608, 0, 0, 0, 0, 67675, 0, 0, 0, 64338, - 2563, 13033, 247, 118915, 0, 12338, 4651, 69895, 11270, 0, 0, 11933, 0, - 0, 41903, 43447, 11001, 0, 42255, 0, 92661, 69821, 41905, 0, 0, 10775, - 9793, 5009, 0, 42269, 64587, 983063, 42535, 69812, 64529, 41408, 42853, - 3877, 120795, 42674, 8147, 43566, 119021, 983776, 10236, 65918, 43782, 0, - 0, 64506, 69652, 118921, 4747, 128058, 69844, 43200, 5832, 0, 0, 5141, - 42600, 0, 43203, 0, 983799, 43286, 0, 128211, 43778, 0, 41305, 78776, - 43781, 11303, 65547, 0, 7031, 859, 0, 0, 0, 6059, 126985, 55235, 0, 8535, - 0, 65196, 194787, 66032, 11488, 120481, 120786, 42233, 64140, 9946, - 63885, 194792, 11822, 0, 43189, 983898, 0, 1788, 1579, 120482, 71298, 0, - 0, 0, 9028, 119571, 69234, 94055, 0, 1285, 64882, 41242, 70086, 0, 12640, - 0, 7401, 0, 12625, 68198, 0, 70082, 3940, 41597, 43754, 3396, 12642, - 8665, 0, 0, 12630, 1653, 917815, 10153, 0, 6166, 120516, 118989, 0, 8815, - 66673, 65046, 9285, 913, 42259, 119317, 119318, 2142, 68454, 42485, - 94012, 7878, 8211, 42293, 64377, 0, 92643, 0, 194673, 12032, 0, 9725, 0, - 78431, 5263, 12818, 78430, 41939, 10022, 65387, 78419, 42777, 10139, 980, - 43698, 65386, 2208, 0, 43701, 43198, 7184, 120673, 194797, 917819, 10085, - 119992, 0, 119993, 6634, 92373, 0, 119323, 8072, 119321, 43700, 0, 8872, - 7783, 917992, 12398, 8237, 0, 0, 12395, 0, 126977, 120565, 9914, 2217, - 917854, 73975, 6367, 6351, 66688, 0, 78107, 0, 64735, 41243, 92199, 7808, - 1829, 0, 41937, 4358, 43272, 6353, 0, 0, 120422, 0, 1710, 0, 0, 65607, 0, - 49, 6627, 0, 6258, 10683, 78672, 9741, 78329, 5649, 78441, 43443, 64418, - 1643, 65213, 8405, 3470, 128225, 13213, 42452, 78331, 120664, 78445, 0, - 1072, 78457, 78452, 78454, 6576, 41988, 41132, 65675, 1080, 120002, 9886, - 55225, 1101, 68404, 12309, 55227, 0, 12632, 1086, 1869, 78685, 7680, 0, - 65458, 120714, 12639, 3380, 8123, 1091, 12638, 7977, 4501, 41099, 0, - 66309, 0, 0, 1494, 983146, 126613, 0, 11693, 126513, 10494, 92655, 65872, - 12363, 11386, 0, 0, 0, 0, 64582, 0, 73794, 0, 8022, 0, 120462, 74106, - 12413, 94069, 917994, 917993, 917995, 5570, 1881, 7210, 0, 1012, 43752, - 0, 120709, 7208, 66442, 5569, 983242, 42339, 0, 6063, 0, 78383, 119594, - 6053, 65602, 0, 92201, 64727, 9160, 194827, 0, 0, 92180, 10503, 118810, - 6055, 3870, 4279, 8490, 120114, 4319, 64786, 8602, 120110, 11326, 92204, - 983116, 0, 120119, 78333, 120117, 120118, 120099, 120100, 65087, 5571, - 3674, 9740, 9121, 5568, 120107, 120108, 42085, 10107, 42159, 42870, - 120101, 589, 7050, 983800, 43281, 10233, 41263, 66251, 65729, 66253, - 126497, 74099, 42645, 0, 194815, 8583, 0, 5847, 6928, 128074, 0, 0, 0, 0, - 66592, 12204, 917962, 19966, 77856, 42561, 120626, 983251, 0, 8120, - 120701, 0, 0, 128012, 41063, 0, 10664, 0, 8369, 0, 4551, 194964, 3369, 0, - 0, 9673, 66334, 65580, 10478, 118960, 12517, 557, 9457, 12034, 983671, - 6355, 12519, 41004, 0, 195025, 74094, 0, 0, 77970, 983560, 0, 128175, - 12111, 3927, 0, 12515, 1474, 67893, 5492, 6923, 92281, 10441, 73836, 0, - 43990, 5493, 0, 74319, 0, 66635, 12019, 0, 1618, 0, 120474, 9645, 10430, - 917959, 5853, 13063, 10363, 0, 12956, 128169, 120729, 11314, 917582, - 12060, 0, 78392, 12826, 6329, 0, 10514, 65517, 74395, 2707, 8309, 0, - 127054, 78398, 43570, 2697, 43420, 78396, 127057, 2695, 42171, 0, 0, 0, - 67617, 118971, 0, 2693, 12125, 12766, 0, 1164, 128817, 0, 41918, 983168, - 127542, 8687, 66009, 12178, 7053, 128001, 7469, 0, 5248, 12218, 120538, - 6427, 42884, 41123, 0, 0, 42873, 41126, 9991, 41128, 74371, 127031, 0, - 9873, 0, 42877, 7994, 64762, 2053, 42843, 6591, 9340, 0, 1589, 0, 296, - 74438, 78852, 0, 67841, 74370, 0, 8922, 128068, 74600, 12700, 74836, 0, - 12579, 0, 12575, 6416, 5656, 2891, 13262, 65590, 5299, 0, 11473, 5449, - 1252, 0, 78404, 41431, 74369, 65373, 5295, 917569, 74114, 1223, 1642, - 174, 78399, 883, 4161, 12691, 42603, 41413, 3212, 41459, 3211, 74810, - 41425, 127029, 78412, 74450, 9728, 3846, 8070, 6150, 6636, 4370, 0, 0, - 74178, 74587, 74117, 0, 0, 0, 4986, 12189, 0, 67648, 120499, 94001, 4257, - 12104, 77942, 6220, 9004, 65561, 0, 77949, 0, 68135, 917576, 77946, 0, - 69679, 69684, 9890, 78561, 12971, 78453, 92556, 73898, 11979, 70051, - 118900, 917894, 0, 9635, 12600, 8871, 0, 0, 0, 6469, 74227, 0, 65304, - 4679, 10230, 64300, 64867, 3427, 4240, 0, 0, 0, 0, 42916, 0, 0, 0, 7282, - 78728, 65733, 4445, 127138, 128082, 3494, 74606, 6555, 0, 77976, 0, 0, - 78566, 0, 983189, 65898, 983244, 65312, 5447, 0, 12895, 65593, 4010, 0, - 41106, 0, 64448, 0, 41105, 0, 65820, 6232, 0, 128280, 0, 43608, 119091, - 0, 6538, 4335, 78364, 3941, 41122, 11061, 78363, 64892, 9113, 1954, - 12155, 983674, 42878, 11500, 0, 0, 74578, 0, 65832, 0, 0, 0, 77975, - 119230, 4586, 0, 350, 10951, 0, 509, 0, 0, 92307, 0, 0, 5133, 0, 0, 9500, - 0, 4957, 64741, 2422, 2212, 983080, 0, 0, 2496, 11516, 944, 118851, 3890, - 12168, 1438, 0, 983117, 0, 41947, 1220, 120828, 128555, 0, 0, 1571, - 42630, 41949, 42805, 8270, 943, 564, 0, 312, 41980, 983944, 0, 78120, - 8877, 269, 4429, 6272, 9617, 1460, 6954, 78657, 41120, 65121, 10862, - 6060, 41119, 41416, 74355, 4173, 0, 0, 0, 1906, 917986, 11532, 74073, - 127338, 0, 1985, 6296, 9582, 917895, 64287, 0, 78115, 11428, 1730, 2457, - 917808, 19918, 10469, 0, 0, 7703, 8840, 8035, 0, 0, 92230, 0, 6129, 0, - 128528, 128268, 0, 7874, 8681, 119092, 0, 13136, 0, 0, 70102, 63886, - 118881, 9605, 71308, 13220, 128776, 120274, 5514, 0, 9228, 0, 0, 0, 5240, - 9811, 10012, 3096, 0, 0, 983351, 66676, 65873, 0, 0, 0, 9501, 0, 1272, - 64536, 65465, 64654, 7467, 0, 1467, 10158, 10040, 0, 9519, 0, 917812, 0, - 118899, 12193, 0, 0, 0, 0, 983353, 19935, 0, 92162, 69676, 0, 0, 0, 5275, - 0, 0, 8637, 0, 0, 3789, 63880, 11471, 43554, 65862, 11474, 66332, 66603, - 128138, 2426, 12042, 92194, 983911, 9537, 3961, 12115, 77953, 2605, 4500, - 64561, 55224, 4981, 0, 0, 63876, 11667, 42686, 77973, 42362, 64686, 4499, - 41649, 7589, 0, 0, 3237, 0, 68215, 917904, 8541, 78298, 70034, 41866, 0, - 0, 0, 0, 69924, 43555, 2823, 9559, 10060, 41940, 8299, 41945, 7132, - 41941, 3308, 7190, 64880, 8614, 65220, 41493, 0, 41699, 10762, 43780, - 12999, 0, 0, 8106, 4128, 0, 6274, 4494, 0, 4012, 10395, 983591, 43633, - 65447, 126511, 0, 11004, 695, 739, 696, 7611, 0, 42755, 74802, 9227, - 7506, 7510, 69937, 691, 738, 7511, 7512, 7515, 3868, 688, 41847, 690, - 2548, 737, 974, 8003, 7406, 917911, 0, 128688, 3985, 917912, 65860, - 63921, 7051, 69777, 4682, 917805, 12809, 6406, 4685, 92505, 10879, 10347, - 4680, 6341, 0, 3851, 8132, 74325, 0, 917907, 0, 41958, 119176, 917908, 0, - 0, 42657, 92468, 7643, 42373, 11714, 67587, 43568, 983175, 11717, 7650, - 10594, 64951, 7647, 7649, 128155, 7646, 0, 78082, 9651, 0, 3891, 0, 0, - 2337, 1735, 74324, 67860, 2363, 983135, 0, 43561, 0, 0, 74146, 1860, - 7495, 7580, 5812, 7497, 7584, 119140, 127853, 0, 120347, 7727, 0, 8498, - 69818, 8949, 3065, 42719, 7135, 1569, 92375, 12534, 12124, 7690, 0, - 12533, 983879, 6418, 4543, 78086, 6969, 0, 74800, 0, 67974, 11980, - 128650, 983801, 63894, 120760, 12282, 66192, 0, 74592, 8850, 74275, 9238, - 10617, 917545, 0, 92625, 0, 12791, 0, 0, 127843, 4447, 73732, 12793, - 12900, 92377, 10950, 0, 78087, 12790, 41400, 119128, 66607, 12792, 42232, - 194938, 1744, 12789, 10366, 12317, 41310, 983869, 41399, 0, 0, 55258, 0, - 12690, 0, 0, 43672, 127840, 41652, 2974, 9010, 11315, 0, 278, 0, 41405, - 119254, 0, 10077, 63853, 74557, 42586, 0, 0, 6002, 0, 43553, 0, 67903, 0, - 12787, 41308, 7934, 65306, 0, 0, 0, 8646, 983186, 77829, 71360, 0, 6413, - 6550, 0, 1940, 0, 43637, 220, 65193, 43551, 10678, 10044, 128322, 0, 0, - 68659, 6403, 5707, 10393, 127532, 0, 66614, 0, 0, 0, 10297, 0, 3742, 0, - 3959, 0, 0, 0, 2467, 0, 6003, 63844, 6663, 8040, 0, 43758, 4182, 78171, - 4676, 120501, 0, 0, 2510, 0, 10208, 78168, 92361, 11540, 43546, 6692, 0, - 41060, 0, 4668, 9083, 0, 0, 78144, 1559, 63831, 9677, 120260, 0, 65256, - 0, 74070, 0, 0, 365, 12056, 43027, 120423, 41716, 128236, 0, 120472, - 5516, 2845, 7717, 8036, 41717, 73827, 544, 12045, 6278, 0, 5515, 0, 0, - 983051, 65339, 43221, 2211, 0, 5517, 0, 0, 74841, 67884, 0, 67890, 67885, - 67880, 67881, 67882, 67883, 0, 0, 67879, 127188, 1902, 67887, 9638, - 12976, 126546, 12483, 12368, 41769, 42726, 41765, 7361, 6667, 67874, - 7556, 67878, 74351, 11264, 989, 42677, 67889, 0, 1311, 917966, 4326, - 11000, 63824, 13068, 10932, 128880, 6917, 78155, 0, 949, 78162, 0, 6148, - 8605, 42253, 78177, 0, 0, 42715, 0, 0, 0, 63871, 0, 41796, 1269, 6530, 0, - 65057, 0, 5144, 12221, 42716, 0, 4431, 4331, 983729, 128675, 41834, 5279, - 0, 10336, 8312, 0, 42701, 128825, 0, 78165, 66036, 0, 0, 6428, 42270, 0, - 983596, 43059, 42666, 5256, 1067, 255, 12131, 983722, 9493, 983968, - 41014, 11793, 194920, 0, 74394, 43460, 10653, 42723, 983854, 119632, 0, - 6560, 7016, 74274, 983615, 43556, 3929, 67977, 6614, 2768, 92504, 9746, - 5135, 11811, 12796, 11953, 0, 69761, 5139, 346, 74303, 6305, 12795, 4675, - 5168, 78552, 127753, 74315, 74361, 8253, 8817, 1136, 0, 43563, 92232, 0, - 194750, 7392, 8230, 9365, 0, 0, 983607, 0, 0, 4041, 0, 2357, 43240, - 12786, 229, 119885, 119884, 44004, 7142, 119881, 12350, 65554, 119882, - 119877, 119876, 12785, 63863, 43795, 7770, 10712, 64853, 12686, 118916, - 42375, 0, 127238, 66352, 10470, 0, 11059, 10791, 917944, 450, 119328, 0, - 10432, 12097, 5450, 64691, 1233, 0, 44009, 78284, 66338, 0, 0, 1839, - 118799, 983219, 10927, 1701, 983664, 2388, 41749, 41761, 5453, 8361, - 119865, 41758, 5444, 41763, 64889, 7143, 92493, 78677, 0, 92429, 78174, - 66432, 8801, 3053, 4340, 983044, 0, 65812, 917831, 0, 41824, 67985, - 120203, 194800, 194803, 42700, 194805, 127980, 194807, 78676, 92356, - 194808, 0, 0, 4493, 4336, 0, 2314, 43602, 78826, 119325, 194811, 42439, - 64638, 42327, 43528, 4489, 71331, 0, 194793, 1912, 42385, 10306, 10370, - 0, 0, 8867, 10250, 10258, 2712, 1635, 78821, 1410, 92671, 983250, 118878, - 0, 0, 9919, 120528, 559, 128157, 41825, 127975, 78188, 4892, 74016, - 194781, 6542, 41957, 128865, 5777, 0, 759, 65749, 2079, 65248, 12788, - 64487, 64552, 0, 10223, 42062, 0, 0, 126573, 3668, 65754, 43560, 12226, - 67991, 65149, 2340, 41959, 194786, 194785, 194788, 43618, 65747, 10937, - 2962, 0, 2321, 3587, 65745, 92436, 8921, 9952, 0, 0, 42714, 9951, 43409, - 194770, 2949, 66012, 194775, 194774, 2958, 68359, 41820, 2300, 2395, - 128563, 9976, 120043, 120050, 120058, 68220, 128143, 42809, 42807, 0, - 120046, 10198, 4150, 64371, 8318, 41790, 67976, 41898, 2360, 41794, - 917942, 71314, 127818, 0, 0, 2418, 983098, 2411, 11336, 799, 63823, - 10276, 10308, 10372, 917541, 41772, 42813, 2317, 10260, 118980, 55284, - 92203, 0, 10384, 983220, 0, 0, 7753, 2351, 6655, 64489, 69931, 0, 77872, - 4443, 42779, 230, 0, 0, 43549, 4855, 42150, 65739, 5441, 41896, 10288, - 10320, 0, 855, 7046, 6109, 65045, 63839, 78198, 2049, 10098, 0, 74145, - 127943, 10264, 10280, 9184, 10376, 7013, 4467, 0, 0, 0, 41887, 0, 4862, - 9735, 6537, 120591, 74286, 3914, 92178, 93976, 9065, 12961, 0, 0, 92253, - 0, 289, 0, 4694, 11420, 4690, 0, 120514, 917978, 4693, 73893, 42724, 0, - 4688, 120454, 0, 0, 67994, 8238, 3110, 120162, 983908, 120163, 6528, - 127553, 43035, 69898, 218, 0, 1520, 0, 4786, 0, 43225, 4602, 0, 78167, - 10088, 6548, 0, 120156, 43978, 8988, 8888, 0, 0, 0, 0, 10666, 0, 73902, - 69740, 0, 0, 9975, 128039, 119902, 4689, 8932, 0, 65560, 119209, 74441, - 78810, 0, 0, 67987, 0, 0, 0, 67989, 0, 10065, 8207, 0, 92613, 128011, 0, - 662, 0, 9244, 194863, 0, 119261, 983428, 0, 0, 0, 41929, 0, 0, 66674, - 41926, 120408, 120443, 10513, 64637, 194862, 68013, 52, 13118, 6475, 0, - 120341, 12095, 10225, 4812, 92578, 0, 67992, 74085, 0, 3978, 0, 917945, - 127823, 11582, 120761, 12281, 0, 6544, 13241, 93961, 69782, 128557, - 194860, 11765, 65258, 10369, 0, 1585, 7192, 10249, 422, 1500, 2036, 986, - 194859, 64394, 5781, 5599, 64294, 2494, 120450, 4861, 74021, 64334, - 78203, 127808, 0, 92266, 65102, 8961, 65842, 10243, 10245, 74191, 120410, - 0, 120453, 64821, 9478, 2508, 92683, 0, 202, 128246, 74131, 1242, 65514, - 0, 63940, 128706, 64533, 120129, 0, 67842, 11990, 92430, 63939, 43375, - 65440, 2504, 0, 78671, 64829, 983910, 6943, 917934, 5859, 0, 2858, - 983361, 74294, 983914, 69239, 0, 119027, 12992, 2753, 1936, 70078, 92574, - 2751, 12662, 2763, 8953, 64701, 10731, 12922, 7052, 917839, 0, 0, 0, - 63920, 74128, 2856, 119910, 47, 69908, 126986, 65858, 0, 0, 0, 7899, 0, - 8417, 43798, 7072, 0, 0, 4033, 128164, 43992, 0, 0, 212, 64600, 1903, - 12320, 0, 0, 194563, 0, 8915, 2759, 945, 6689, 0, 0, 0, 0, 1291, 74828, - 0, 0, 9531, 13155, 8505, 68379, 12062, 0, 0, 65487, 92189, 41837, 120611, - 120432, 0, 0, 0, 120433, 0, 63935, 73962, 120806, 64787, 43524, 0, 64426, - 0, 194948, 0, 0, 65664, 6693, 9843, 0, 8674, 119887, 128812, 92715, 0, - 12624, 0, 1673, 4811, 92383, 5986, 9338, 3046, 74480, 5985, 917928, - 119598, 9820, 0, 12187, 0, 0, 5984, 0, 43308, 4393, 67650, 0, 0, 0, 0, - 74826, 64733, 0, 0, 3491, 0, 0, 128219, 3514, 65485, 0, 7492, 0, 74605, - 92483, 7514, 983367, 0, 194731, 7502, 7587, 68353, 0, 0, 63925, 0, 7610, - 219, 0, 0, 692, 43588, 74433, 41635, 43241, 9688, 7147, 9535, 0, 93991, - 0, 64530, 0, 64610, 11804, 0, 7149, 7453, 0, 8013, 0, 92301, 0, 8895, - 5253, 70025, 5458, 0, 2866, 0, 127860, 65111, 68433, 6700, 120484, 0, - 120583, 0, 8962, 77960, 9641, 43694, 7059, 983677, 0, 9604, 78700, 7441, - 63826, 67970, 118941, 64392, 194735, 983687, 2844, 983941, 41974, 0, - 12139, 67971, 0, 0, 3358, 65295, 0, 3104, 194734, 0, 194765, 983233, - 5308, 0, 290, 0, 0, 2862, 2792, 195088, 983070, 0, 3268, 66591, 0, 6552, - 42367, 7035, 120558, 0, 0, 1814, 0, 10240, 92338, 74305, 0, 74528, 65903, - 0, 42646, 7606, 2591, 2837, 4341, 77956, 64482, 127337, 8163, 65270, 0, - 77932, 0, 9112, 74431, 863, 9490, 119898, 128349, 43323, 120513, 119897, - 9071, 127333, 0, 3654, 7789, 9637, 0, 2535, 65504, 7653, 40993, 119899, - 66587, 195098, 0, 92401, 983894, 11006, 12927, 7807, 8073, 0, 10629, 0, - 74088, 3056, 10823, 128797, 127327, 8762, 10508, 69689, 73770, 43969, - 43193, 10737, 3463, 983065, 0, 66633, 8695, 4815, 11322, 5811, 12345, - 7049, 119911, 5195, 195081, 0, 66639, 0, 0, 0, 128041, 0, 92385, 1262, 0, - 6561, 19939, 0, 0, 128535, 119906, 0, 0, 983097, 0, 983667, 119907, - 64612, 11991, 0, 0, 0, 1502, 917568, 0, 9107, 127316, 5702, 3655, 67661, - 8430, 0, 74132, 120758, 0, 74057, 9603, 0, 5254, 120742, 7724, 74388, - 68375, 10796, 5129, 0, 0, 590, 7579, 5614, 5893, 92280, 11720, 92496, - 11721, 0, 4798, 0, 119316, 66038, 4793, 67851, 11726, 127541, 74204, - 68610, 0, 68626, 894, 300, 917813, 12306, 66235, 8004, 0, 0, 2562, - 126555, 0, 42503, 0, 11652, 0, 0, 119241, 64699, 126569, 5096, 5095, - 2863, 3424, 92244, 10454, 42530, 5094, 119638, 0, 13156, 0, 10832, 5093, - 0, 69852, 0, 5092, 10708, 11327, 0, 5091, 176, 0, 9153, 4104, 78599, - 78601, 1215, 42712, 5744, 12272, 9832, 11777, 71299, 127371, 42881, 0, - 8980, 118988, 67861, 8844, 7209, 0, 0, 4278, 0, 0, 194789, 0, 9074, 4348, - 0, 65558, 65946, 8113, 7087, 5255, 1786, 661, 0, 0, 0, 74423, 71345, 586, - 74414, 64359, 1267, 128269, 65468, 0, 65731, 0, 127179, 3621, 120473, - 66666, 64211, 0, 6562, 12928, 0, 1228, 65490, 11383, 0, 0, 0, 1714, - 74406, 127831, 0, 983921, 0, 66225, 0, 0, 42660, 11436, 2070, 64, 120694, - 0, 10291, 10323, 2826, 0, 0, 0, 42008, 9708, 42710, 0, 42011, 41999, - 92164, 12206, 5839, 1702, 1240, 74065, 6286, 0, 983969, 65833, 77848, 0, - 1765, 0, 0, 65588, 0, 0, 0, 8401, 0, 42014, 0, 7030, 194704, 10479, - 64959, 2852, 0, 0, 0, 0, 128586, 917951, 6963, 0, 12667, 64540, 74786, - 10147, 12935, 127568, 126483, 0, 0, 0, 78757, 0, 0, 0, 0, 9994, 12467, - 2864, 64719, 1148, 10435, 11462, 41675, 7084, 2765, 0, 43382, 0, 120719, - 128188, 92516, 66662, 0, 78133, 9364, 194685, 74416, 0, 0, 77988, 263, - 10449, 41288, 0, 41839, 78387, 983742, 77986, 0, 6931, 69722, 64355, - 7177, 70105, 0, 0, 0, 4262, 10285, 10722, 42020, 126575, 6806, 6992, - 42019, 0, 41290, 983716, 750, 0, 71304, 10163, 63913, 71300, 7032, 5954, - 64931, 4314, 0, 198, 68453, 730, 120094, 63907, 77993, 78891, 13165, - 7107, 74171, 42804, 678, 8240, 78015, 128784, 41378, 11008, 6938, 70026, - 92637, 2097, 66246, 120560, 0, 0, 0, 3892, 68632, 69642, 6712, 66045, - 41470, 64805, 0, 0, 128215, 64801, 0, 497, 12100, 5953, 92667, 7796, - 69669, 43254, 73831, 0, 10293, 5952, 1281, 43747, 0, 0, 10677, 604, - 41097, 9182, 1859, 0, 92603, 3425, 127488, 0, 2836, 0, 0, 9707, 0, 43202, - 0, 0, 65199, 1738, 917818, 128158, 2832, 92702, 9670, 12937, 0, 66374, - 917956, 0, 2822, 68122, 4436, 92519, 983723, 73752, 0, 64872, 92340, - 1331, 0, 0, 0, 12708, 0, 5090, 5089, 127977, 0, 119109, 0, 128681, 319, - 118847, 43479, 9477, 0, 0, 5087, 92325, 7640, 96, 5086, 0, 92379, 0, - 5085, 64286, 92665, 0, 41422, 0, 119901, 42356, 3772, 0, 0, 5011, 0, 0, - 126587, 0, 127165, 127241, 6677, 7601, 0, 591, 64419, 118953, 92262, 0, - 118923, 70084, 0, 10939, 6106, 6933, 41271, 6760, 71343, 4534, 41270, - 128876, 0, 65574, 0, 9224, 69853, 3671, 8976, 126474, 0, 41275, 6372, - 128084, 55261, 7963, 6371, 0, 568, 0, 41273, 983730, 0, 6728, 0, 9715, 0, - 8258, 11753, 74820, 0, 9602, 118919, 42, 0, 43688, 0, 0, 7458, 0, 0, - 65385, 119900, 0, 11958, 0, 917822, 0, 6254, 42721, 66336, 8045, 11550, - 0, 0, 983597, 42858, 11789, 65868, 5557, 10133, 9737, 13109, 0, 9467, - 5558, 8878, 128136, 195036, 7451, 6706, 10146, 0, 9086, 64566, 0, 64584, - 7437, 7454, 12594, 128690, 68362, 4546, 7731, 0, 70048, 74243, 0, 3805, - 0, 194565, 44001, 41008, 0, 6307, 19949, 983790, 7544, 983045, 43469, 0, - 0, 10152, 64422, 65091, 119113, 7602, 64729, 0, 43521, 0, 42302, 43711, - 43523, 41447, 5559, 0, 8704, 2397, 5556, 0, 0, 0, 9011, 9630, 92633, 0, - 93998, 5506, 0, 1911, 66652, 0, 9961, 8845, 66698, 0, 10792, 8889, 0, - 2098, 0, 64751, 0, 66622, 0, 0, 74364, 0, 0, 983805, 74365, 7552, 0, 0, - 65384, 7223, 4559, 0, 1956, 43138, 7024, 65728, 64501, 1210, 195077, - 65175, 10184, 43140, 43654, 0, 0, 0, 38, 8533, 66669, 119124, 983293, - 983792, 0, 4357, 0, 119837, 917863, 74233, 9967, 78884, 42860, 119838, - 10941, 65721, 6962, 0, 0, 119324, 0, 11014, 127972, 8942, 12000, 69224, - 92267, 128536, 11974, 92213, 42772, 127518, 11650, 5013, 92663, 126583, - 66210, 118914, 6613, 92476, 0, 43819, 983770, 0, 64714, 0, 0, 12162, - 12120, 43476, 983766, 11024, 74811, 66228, 10563, 0, 127196, 43522, 2462, - 0, 1837, 0, 63972, 6957, 0, 120559, 4952, 65718, 65827, 5504, 65720, - 65714, 65715, 65716, 0, 127005, 127119, 3109, 63975, 74028, 0, 8107, - 119234, 1127, 455, 0, 63968, 127924, 3483, 119593, 1989, 0, 69678, 9104, - 3503, 65375, 92509, 6694, 42633, 1864, 0, 74306, 41446, 2540, 7736, 0, - 74064, 0, 10521, 0, 42173, 9705, 74124, 8604, 6955, 10916, 43684, 6149, - 3887, 19956, 1411, 2824, 0, 10106, 127862, 1403, 128839, 1347, 9631, - 74444, 0, 0, 0, 0, 8640, 0, 258, 1654, 0, 0, 0, 43314, 0, 0, 4042, 11478, - 2873, 63977, 11522, 41668, 8549, 10861, 0, 63976, 0, 68623, 0, 74585, - 41391, 0, 917903, 376, 6987, 9221, 0, 0, 8823, 128697, 12943, 65185, - 41869, 12619, 0, 10154, 983043, 74439, 2039, 0, 7446, 1684, 63979, 10974, - 458, 120620, 0, 69791, 127161, 11916, 65016, 0, 69671, 42115, 983133, - 12288, 78057, 0, 1493, 42111, 7553, 4097, 128199, 13080, 0, 65808, 6610, - 6030, 8059, 7508, 13131, 0, 983431, 0, 8794, 41278, 41629, 12154, 128192, - 41277, 64658, 0, 64380, 6625, 74354, 19904, 0, 0, 0, 65371, 7078, 0, 833, - 0, 6369, 0, 10979, 41953, 0, 41434, 6062, 0, 0, 19916, 6913, 933, 1341, - 9842, 6720, 65744, 0, 983592, 128295, 0, 7405, 10105, 65810, 0, 41632, - 7493, 55290, 0, 41622, 0, 0, 119556, 74584, 7632, 9716, 19954, 9805, - 5990, 900, 0, 63957, 0, 0, 3612, 0, 64376, 93987, 5389, 92597, 0, 65938, - 2839, 9621, 582, 0, 74368, 3749, 6949, 7569, 74061, 0, 0, 6956, 4403, - 19962, 65559, 3299, 0, 917566, 119127, 9002, 0, 74372, 74236, 8478, 7598, - 546, 42469, 65569, 1918, 9542, 472, 7716, 10319, 10383, 6996, 0, 63952, - 8425, 3602, 8328, 11764, 118894, 0, 69796, 41183, 12907, 10271, 10287, - 684, 43525, 0, 2854, 119586, 4592, 65755, 0, 92256, 11963, 43620, 0, - 78249, 0, 128551, 128809, 9881, 43115, 65757, 3415, 119131, 0, 8648, 0, - 6741, 43047, 0, 13180, 128517, 418, 917972, 64495, 10295, 10327, 10391, - 41752, 74339, 8641, 41449, 0, 74100, 0, 10911, 6942, 0, 1024, 42849, - 41751, 69776, 8941, 983556, 4554, 0, 9023, 11685, 0, 9928, 78617, 0, - 11437, 43741, 92163, 120700, 63967, 983483, 41206, 120724, 9049, 41185, - 43166, 0, 11680, 92619, 11686, 78544, 65224, 4565, 4655, 119553, 0, - 92183, 64523, 10343, 10407, 0, 66671, 11466, 0, 128003, 42890, 74013, - 12050, 68201, 2860, 0, 0, 0, 42792, 5743, 10424, 12065, 42872, 0, 92342, - 0, 8875, 0, 0, 917991, 7531, 12847, 2413, 0, 78635, 962, 0, 12855, 41196, - 42564, 0, 1582, 983715, 5508, 0, 0, 0, 10801, 69876, 92354, 0, 7173, 496, - 10439, 4313, 64607, 69638, 7860, 0, 906, 42793, 2842, 6405, 64722, 13132, - 798, 64694, 12801, 8406, 1153, 92173, 64788, 0, 8054, 9174, 128652, - 917976, 9964, 74409, 41611, 4642, 66574, 11556, 917982, 0, 78857, 42089, - 78855, 9008, 0, 126592, 195096, 42079, 917981, 77924, 42513, 77927, - 42842, 73985, 65285, 118974, 127003, 983702, 0, 0, 0, 11335, 64069, - 42093, 3920, 0, 0, 0, 0, 4580, 41967, 983732, 64384, 92167, 93984, 3021, - 42004, 0, 0, 42317, 41998, 0, 6946, 0, 0, 0, 128193, 65204, 0, 68113, - 42690, 9880, 42010, 74824, 64589, 10111, 64875, 127880, 68399, 43998, - 11360, 0, 0, 0, 118826, 42149, 0, 0, 0, 64941, 77919, 120421, 128077, 0, - 55247, 4110, 66005, 6959, 10929, 119110, 0, 66703, 77921, 8617, 41982, - 6025, 69242, 983176, 0, 0, 0, 9597, 42099, 43172, 983376, 10117, 983169, - 92297, 41636, 0, 0, 120681, 8301, 0, 0, 187, 0, 65669, 128339, 4963, 0, - 127517, 0, 8964, 65676, 7775, 0, 41948, 0, 0, 0, 41942, 65449, 3160, - 10081, 13226, 42121, 42475, 42663, 128210, 41766, 119114, 65882, 78849, - 41760, 1189, 905, 480, 10985, 41733, 67859, 9629, 6742, 1745, 43625, - 73835, 7888, 0, 3980, 0, 42656, 41507, 8806, 7023, 0, 74279, 9447, 78651, - 7867, 69218, 6236, 983134, 0, 10505, 0, 12851, 118948, 348, 5474, 128843, - 3103, 0, 41753, 128540, 0, 0, 78844, 78845, 41739, 78843, 42515, 10931, - 41756, 43347, 42560, 5391, 41746, 119147, 92591, 41259, 5561, 69930, - 2691, 0, 65553, 7933, 5562, 69800, 128265, 41262, 128146, 64421, 74846, - 41251, 0, 0, 3979, 0, 0, 74813, 983739, 0, 0, 0, 92524, 41266, 0, 66566, - 128836, 10585, 65741, 41737, 9574, 2666, 0, 41738, 831, 419, 13126, - 10716, 0, 42822, 0, 6434, 0, 6939, 7766, 6432, 128106, 69932, 916, 769, - 41742, 11968, 74805, 6433, 5563, 547, 1943, 6439, 5560, 4994, 487, - 126537, 4497, 3754, 127056, 120424, 9039, 0, 41776, 0, 8716, 1595, 41615, - 0, 0, 74260, 0, 42854, 43219, 128709, 983460, 12185, 128879, 70072, - 68355, 68357, 0, 42856, 8634, 0, 983397, 4209, 120702, 0, 65879, 41538, - 65612, 127543, 669, 5679, 0, 69786, 92540, 0, 983464, 5678, 11821, 0, - 6711, 460, 0, 0, 983461, 0, 120747, 0, 0, 78050, 119022, 0, 983462, 0, - 7782, 9044, 4974, 11760, 78494, 7577, 65711, 41912, 1216, 0, 128079, - 5792, 0, 0, 78501, 0, 2933, 12244, 0, 5683, 983392, 0, 78119, 1549, 0, 0, - 120398, 5682, 6206, 8670, 10256, 5680, 69935, 10001, 128512, 69768, 1449, - 10241, 78290, 128228, 0, 10552, 64342, 41922, 128548, 8584, 68030, 5567, - 2717, 0, 0, 5564, 42886, 41908, 42882, 5565, 983256, 128026, 0, 65708, - 65709, 5566, 69803, 65704, 65705, 11904, 42875, 43373, 42539, 5942, 8468, - 120561, 10361, 10425, 65697, 65698, 65699, 0, 66598, 0, 64664, 10647, - 78702, 78703, 78690, 457, 78502, 65701, 1934, 43006, 119903, 8802, 78710, - 65130, 11747, 78709, 6087, 78705, 78716, 41757, 78711, 8043, 8950, 65694, - 64485, 43534, 10457, 0, 11961, 78725, 78722, 78723, 78720, 78721, 0, - 65515, 9499, 10035, 13069, 71309, 0, 9889, 68184, 42806, 0, 7256, 0, 0, - 1667, 42161, 0, 42428, 0, 6934, 0, 10802, 64861, 6556, 78390, 0, 8101, - 3610, 983199, 41748, 4995, 955, 65907, 119208, 5350, 64339, 78306, 64549, - 10875, 128662, 5477, 65692, 0, 128532, 120397, 12896, 10456, 917954, 0, - 3874, 0, 0, 983619, 120331, 0, 0, 65603, 0, 65687, 0, 41038, 74009, - 119570, 42239, 8536, 78740, 78324, 78726, 74432, 724, 0, 1455, 78749, - 7183, 64583, 78747, 68443, 4175, 78741, 43614, 69801, 939, 0, 43520, - 68613, 74569, 917958, 0, 78763, 78764, 78760, 10788, 6088, 78759, 78755, - 190, 0, 12593, 0, 8188, 64408, 0, 4417, 983213, 92261, 6370, 0, 7827, - 68441, 6965, 0, 0, 13201, 128205, 69896, 0, 74382, 73781, 7918, 73988, 0, - 0, 917884, 1728, 0, 43764, 178, 12972, 92679, 0, 917887, 92563, 983381, - 0, 78327, 120405, 65690, 0, 0, 119054, 0, 9252, 917889, 4652, 68371, 0, - 0, 0, 13065, 9923, 10806, 0, 11763, 70016, 120688, 6723, 78187, 0, 6993, - 0, 0, 8333, 0, 0, 11390, 0, 74464, 0, 92320, 74080, 983315, 69911, 11910, - 92559, 8278, 8963, 4034, 128560, 0, 65344, 120517, 41747, 0, 0, 8677, 0, - 12707, 9350, 66037, 128180, 8836, 12315, 12747, 8300, 983750, 0, 7491, - 8856, 71361, 0, 43150, 127768, 120404, 65389, 120402, 120403, 10813, - 2592, 12853, 43269, 7263, 120244, 6536, 120238, 120239, 65516, 12321, - 120391, 120388, 55287, 10007, 120246, 9588, 120248, 1596, 120383, 41994, - 65801, 128808, 0, 66572, 0, 0, 10613, 6697, 12805, 41928, 40981, 78403, - 78409, 5006, 64328, 0, 9931, 0, 8825, 74555, 65940, 43259, 0, 6107, 0, - 119177, 0, 78401, 128641, 11783, 335, 120227, 64689, 438, 4510, 5765, - 8721, 120233, 119227, 6092, 12840, 43112, 8876, 120231, 8096, 10284, - 128515, 0, 0, 10380, 8733, 983072, 128240, 41602, 0, 92308, 74831, - 917901, 0, 73747, 65399, 0, 64591, 42405, 0, 120820, 843, 11541, 0, - 917898, 2065, 41935, 74496, 41902, 0, 0, 215, 41258, 77875, 43159, 1953, - 9579, 41938, 1256, 3910, 9407, 6242, 0, 983100, 41257, 41900, 8675, - 10700, 8805, 1742, 0, 9333, 8202, 127750, 0, 983197, 0, 0, 73882, 499, - 983049, 43467, 0, 43818, 0, 1712, 5932, 77845, 41762, 983104, 0, 11967, - 1775, 0, 0, 0, 0, 128009, 9458, 0, 6470, 9180, 120380, 43176, 0, 0, - 42782, 0, 0, 0, 128309, 74777, 120669, 9414, 120382, 73782, 73969, 565, - 42484, 5794, 201, 2662, 42292, 0, 8254, 0, 10975, 0, 120625, 74763, 1022, - 4108, 3880, 74247, 0, 0, 92263, 917980, 7507, 0, 43149, 0, 65031, 7961, - 1636, 0, 65029, 65024, 0, 12473, 6534, 0, 99, 98, 97, 120571, 67584, - 4049, 74163, 127065, 7090, 0, 7892, 917969, 10777, 917803, 65310, 65562, - 66599, 66722, 0, 8039, 3363, 66594, 43434, 0, 0, 12596, 66595, 42258, - 42570, 5593, 119148, 120711, 92425, 10100, 6061, 64854, 119, 118, 117, - 116, 12998, 122, 121, 120, 111, 110, 109, 108, 115, 114, 113, 112, 103, - 102, 101, 100, 107, 106, 105, 104, 6436, 73974, 534, 41212, 77931, 1536, - 64093, 73970, 77930, 127157, 0, 6020, 12716, 127112, 12744, 475, 120394, - 13266, 127813, 127111, 0, 73926, 0, 10645, 1212, 6543, 983307, 8134, - 128028, 2913, 73870, 127113, 1866, 983229, 195095, 0, 8923, 1645, 12059, - 66585, 71297, 3196, 0, 0, 5935, 1250, 127066, 8174, 9787, 6733, 9859, - 7916, 9861, 9860, 5258, 1882, 1892, 6731, 10882, 405, 11454, 73911, 0, - 128781, 41169, 8939, 41245, 0, 41170, 1454, 11369, 6477, 12157, 0, 0, 0, - 41172, 7855, 0, 0, 10480, 0, 0, 77936, 8264, 12610, 983308, 645, 126616, + 78319, 63959, 0, 9942, 13231, 983578, 64752, 4732, 194666, 11596, 78142, + 65187, 1626, 63983, 10110, 64772, 42024, 6420, 42028, 92294, 10509, 2795, + 4910, 129193, 69231, 64753, 6275, 93957, 118830, 63978, 11044, 3229, + 6423, 42774, 0, 0, 68526, 12823, 2331, 127788, 7085, 6137, 0, 7524, + 120721, 917809, 8346, 128438, 8338, 128315, 65043, 77982, 822, 70412, + 9903, 64721, 42722, 69877, 82956, 78655, 66882, 82959, 78484, 41265, + 5311, 1795, 965, 118791, 10587, 43962, 11278, 78632, 74111, 128095, + 12946, 121076, 71921, 120349, 6294, 3144, 113706, 127967, 65019, 74078, + 73990, 65111, 983960, 748, 41067, 2330, 535, 3148, 12375, 78799, 194629, + 10556, 2475, 12388, 4889, 8968, 67863, 3593, 74076, 82949, 2342, 82951, + 82944, 65206, 4894, 82947, 4890, 121059, 64433, 581, 4893, 42929, 6571, + 65545, 4888, 4157, 78048, 78049, 64651, 78047, 0, 10119, 6415, 42893, 0, + 69702, 983937, 0, 11375, 64746, 2332, 78063, 412, 78061, 42928, 42880, + 43587, 121098, 0, 0, 70461, 65197, 78066, 12203, 78064, 78065, 8913, + 65854, 4875, 65811, 75024, 120389, 71854, 9344, 8826, 92916, 120395, + 13104, 67828, 11997, 120393, 78075, 0, 3134, 83096, 65696, 72432, 121412, + 66217, 121190, 8334, 92755, 83207, 3449, 121264, 13100, 78414, 78413, + 83216, 66405, 70430, 83089, 83203, 127250, 1908, 120167, 4328, 10734, + 127014, 83198, 67825, 7804, 78272, 10811, 6250, 11339, 4914, 11367, + 83510, 78054, 4917, 74516, 74208, 64285, 4912, 5464, 127836, 83100, 2361, + 7971, 78072, 78073, 55243, 78071, 983575, 8086, 74317, 6707, 8319, 2312, + 40977, 10960, 40962, 8305, 12573, 71131, 40980, 983964, 13202, 127816, + 12582, 78282, 983048, 69856, 42438, 55221, 6288, 78280, 127946, 5653, + 42400, 10891, 7698, 5658, 70401, 70039, 0, 70460, 4913, 71060, 128562, + 71333, 42326, 121119, 12728, 92685, 42478, 2327, 0, 12563, 42287, 12705, + 120829, 83081, 12588, 8821, 6153, 2867, 83085, 66312, 698, 83076, 83087, + 10356, 70017, 128570, 651, 12641, 83138, 125098, 120710, 129064, 41552, + 65115, 78465, 78467, 78463, 74905, 127516, 78461, 92960, 66927, 64945, + 4716, 43277, 120932, 78474, 12340, 120568, 120928, 194700, 55264, 41211, + 120676, 8703, 5462, 83195, 83185, 10101, 0, 70049, 8479, 4151, 41933, + 83189, 0, 66254, 120821, 68497, 0, 128654, 113799, 83159, 74050, 42651, + 127371, 0, 0, 83225, 83218, 12278, 75011, 128405, 0, 2700, 12576, 7842, + 12899, 83155, 0, 2699, 129304, 73845, 2985, 83149, 68648, 83146, 12192, + 119314, 0, 66489, 9827, 119310, 8609, 119308, 67426, 119306, 11481, + 41210, 119305, 0, 35, 70838, 67431, 66694, 68479, 78477, 67428, 43596, + 6090, 64257, 7812, 10534, 0, 78485, 73848, 67975, 4272, 78321, 40967, + 40964, 917825, 12704, 78487, 43306, 0, 64497, 12138, 7930, 0, 2292, + 68216, 194871, 121390, 5244, 4189, 92697, 67596, 127504, 4188, 1879, + 70463, 968, 0, 43743, 0, 8873, 2279, 127100, 917827, 65555, 12574, 0, + 92749, 92753, 74490, 127099, 11838, 75001, 0, 0, 42682, 12578, 12720, 0, + 41227, 0, 12346, 127101, 64848, 69950, 917950, 7251, 0, 120382, 118850, + 119141, 128461, 66015, 67332, 959, 8885, 12564, 66457, 78808, 9469, 9632, + 92231, 74761, 64323, 127335, 128842, 0, 11132, 310, 120924, 41281, 10976, + 0, 71325, 128364, 74266, 10054, 6497, 8574, 917823, 9012, 19958, 74420, + 65089, 13215, 12730, 65163, 64260, 374, 43195, 816, 92783, 0, 83191, + 41934, 7465, 74615, 92752, 127895, 4715, 6101, 71089, 41936, 82967, 4879, + 43965, 65446, 0, 307, 127147, 9585, 5374, 127962, 128059, 0, 129189, + 126618, 120390, 74953, 65567, 120614, 1929, 120984, 12142, 194696, 12236, + 41419, 194618, 120610, 12982, 75003, 5378, 75004, 120957, 41421, 75005, + 4462, 0, 126599, 128092, 821, 0, 2498, 5800, 120157, 67758, 1760, 2421, + 4469, 2324, 828, 3611, 78400, 757, 1185, 0, 78770, 43597, 10628, 74808, + 68849, 7999, 43971, 11217, 121224, 10634, 10942, 7713, 2348, 0, 64374, + 4380, 128284, 83061, 9982, 64324, 41240, 862, 64468, 78462, 1810, 3673, + 5137, 194617, 0, 7277, 65622, 65069, 7566, 64688, 67143, 194592, 74957, + 43912, 128385, 4748, 92228, 129185, 194601, 42260, 5871, 119075, 121278, + 74576, 44019, 194720, 128189, 3967, 71098, 13137, 8775, 127945, 0, 2963, + 917785, 8410, 4454, 723, 83084, 966, 4449, 92330, 92238, 75022, 7819, + 2320, 194589, 339, 4968, 194590, 120399, 8075, 55276, 83057, 8047, 0, + 78827, 12634, 41542, 78780, 7466, 6705, 12174, 42610, 124934, 74452, + 983763, 1584, 66645, 6045, 6729, 120640, 65218, 11559, 194983, 78062, + 7537, 124991, 11370, 125093, 10330, 78798, 10394, 92236, 74194, 0, + 127929, 9780, 0, 11117, 74993, 77950, 67091, 7074, 92648, 194579, 194582, + 11414, 68781, 2531, 13034, 129159, 0, 4211, 1259, 7517, 70866, 70198, + 83122, 40996, 13037, 7092, 641, 5219, 83125, 194566, 11064, 41129, + 121253, 42850, 13035, 9075, 92387, 5466, 74293, 74530, 64098, 65793, + 4535, 121267, 4271, 78417, 127059, 6769, 41410, 127257, 64262, 6767, + 41407, 66273, 917816, 6755, 118864, 9046, 120886, 126608, 70830, 0, + 83232, 0, 67675, 983694, 83234, 121254, 64338, 2563, 13033, 247, 83229, + 0, 12338, 4651, 67355, 11270, 0, 74630, 11933, 70107, 0, 41903, 43447, + 11001, 73827, 42255, 83243, 83238, 69821, 41905, 67350, 0, 10775, 9793, + 5009, 128774, 42269, 64587, 983063, 42535, 69812, 64529, 41408, 42853, + 3877, 120795, 42674, 8147, 43566, 119021, 67342, 10236, 65918, 43782, + 78769, 78060, 64506, 69652, 118921, 4747, 83251, 69844, 43200, 5832, + 71208, 83250, 5141, 42600, 71866, 43203, 127208, 120129, 43286, 0, + 128211, 43778, 7657, 41305, 71132, 43781, 11303, 65547, 128609, 7031, + 859, 128488, 83262, 83237, 6059, 126985, 55235, 194817, 8535, 128638, + 65196, 125084, 66032, 11488, 120481, 120786, 42233, 64140, 9946, 7667, + 194792, 11822, 128591, 11135, 983600, 0, 1788, 1579, 120482, 71298, 0, + 983461, 0, 9028, 119571, 69234, 71061, 92545, 1285, 64882, 41242, 70086, + 83111, 12640, 83112, 7401, 0, 12625, 68198, 0, 70082, 3940, 41597, 43754, + 3396, 12642, 8665, 983610, 983609, 12630, 1653, 917815, 10153, 0, 6166, + 70825, 118989, 129409, 8815, 66673, 65046, 9285, 913, 42259, 11180, + 119318, 2142, 68454, 42485, 94012, 7878, 8211, 42293, 64377, 120478, + 92643, 121118, 194673, 12032, 0, 9725, 983491, 78431, 5263, 12818, 78430, + 41939, 10022, 65387, 78419, 42777, 10139, 980, 43698, 65386, 2208, 68848, + 43701, 43198, 7184, 92542, 128423, 128875, 10085, 74979, 0, 67394, 6634, + 92373, 125085, 83413, 8072, 119321, 43700, 0, 8872, 7783, 917991, 12398, + 8237, 0, 0, 12395, 0, 126977, 74891, 9914, 2217, 92323, 73975, 6367, + 6351, 66688, 92740, 68766, 0, 64735, 41243, 92199, 7808, 1829, 126541, + 41937, 4358, 43272, 6353, 0, 0, 120422, 93045, 1710, 120140, 0, 65607, + 67234, 49, 6627, 0, 6258, 10683, 78672, 9741, 78329, 5649, 78441, 43443, + 64418, 1643, 65213, 8405, 3470, 67244, 13213, 42452, 78331, 78013, 78445, + 125124, 1072, 78457, 78452, 78454, 6576, 41988, 41132, 65675, 1080, + 70824, 9886, 55225, 1101, 68404, 12309, 55227, 71082, 12632, 1086, 1869, + 78685, 7680, 0, 65458, 120714, 12639, 3380, 8123, 1091, 12638, 7977, + 4501, 41099, 0, 66309, 120141, 92758, 1494, 113716, 126613, 0, 11693, + 71255, 10494, 92655, 65872, 12363, 11386, 113727, 0, 0, 78771, 64582, 0, + 73794, 67395, 8022, 120989, 120462, 74106, 12413, 66883, 917994, 93035, + 75007, 5570, 1881, 7210, 120425, 1012, 43752, 0, 120709, 7208, 66442, + 5569, 195007, 42339, 92997, 6063, 67888, 69981, 119594, 6053, 65602, 0, + 92201, 64727, 9160, 70301, 0, 92905, 92180, 10503, 70387, 3423, 3870, + 4279, 8490, 120114, 4319, 64786, 8602, 120110, 11326, 92204, 983116, 0, + 74961, 78333, 120117, 120118, 120099, 92385, 65087, 5571, 3674, 9740, + 9121, 5568, 71464, 120108, 42085, 10107, 42159, 42870, 113700, 589, 7050, + 983800, 43281, 10233, 41263, 66251, 65729, 66253, 126497, 74099, 42645, + 92331, 121358, 8583, 121123, 5847, 6928, 128074, 0, 0, 0, 0, 66592, + 12204, 917962, 19966, 77856, 42561, 120626, 129170, 66854, 8120, 70311, + 194585, 0, 70308, 41063, 120417, 10664, 0, 8369, 0, 4551, 194964, 3369, + 74971, 121094, 9673, 66334, 65580, 10478, 118960, 12517, 557, 9457, + 12034, 68496, 6355, 12519, 41004, 0, 74937, 74094, 917888, 125060, 77970, + 92171, 127219, 128175, 12111, 3927, 0, 12515, 1474, 67893, 5492, 6923, + 92281, 10441, 73836, 0, 43990, 5493, 0, 74319, 0, 66635, 12019, 0, 1618, + 0, 120474, 9645, 10430, 126636, 5853, 13063, 10363, 983898, 12956, + 113666, 120729, 11314, 917582, 12060, 128648, 78392, 12826, 6329, 0, + 10514, 65517, 74395, 2707, 8309, 0, 127054, 78398, 43570, 2697, 43420, + 78396, 68247, 2695, 42171, 70809, 68334, 0, 67617, 118971, 0, 2693, + 12125, 12766, 120409, 1164, 113729, 70283, 41918, 77849, 67150, 8687, + 66009, 12178, 7053, 92540, 7469, 0, 5248, 12218, 69988, 6427, 42884, + 41123, 11176, 0, 42873, 41126, 9991, 41128, 74371, 127031, 983932, 9873, + 0, 42877, 7994, 64762, 2053, 42843, 6591, 9340, 128841, 1589, 128691, + 296, 67712, 78852, 121409, 67841, 74370, 128504, 8922, 128068, 43829, + 12700, 74836, 0, 12579, 0, 12575, 6416, 5656, 2891, 13262, 65590, 5299, + 78837, 11473, 5449, 1252, 127328, 78404, 41431, 74369, 65373, 5295, + 917569, 68320, 1223, 1642, 174, 78399, 883, 4161, 12691, 42603, 41413, + 3212, 41459, 3211, 74810, 41425, 74598, 78412, 74450, 9728, 3846, 8070, + 6150, 6636, 4370, 128619, 129158, 74178, 74587, 74117, 195094, 0, 113748, + 4986, 12189, 127512, 67648, 120499, 94001, 4257, 12104, 71176, 6220, + 9004, 65561, 983881, 77949, 0, 68135, 917576, 77946, 83453, 69679, 69684, + 9890, 78561, 12971, 78453, 92556, 73898, 11979, 70051, 71897, 83451, 0, + 9635, 12600, 8871, 67366, 68491, 0, 6469, 74227, 118900, 65304, 4679, + 10230, 64300, 64867, 3427, 4240, 67376, 67375, 67374, 67373, 42916, + 129155, 128279, 67377, 7282, 78728, 65733, 4445, 67372, 67371, 3494, + 67369, 6555, 129148, 77976, 0, 0, 78566, 0, 983189, 65898, 983246, 65312, + 5447, 0, 12895, 65593, 4010, 83154, 41106, 74357, 64448, 93994, 41105, + 74114, 65820, 6232, 68233, 126625, 0, 43608, 119091, 78118, 6538, 4335, + 78364, 3941, 41122, 11061, 78363, 64892, 9113, 1954, 12155, 983674, + 42878, 11500, 67405, 128152, 74578, 0, 65832, 128667, 0, 70789, 67333, + 119230, 4586, 0, 350, 10951, 0, 509, 67336, 983879, 92307, 0, 0, 5133, + 67382, 0, 9500, 0, 4957, 64741, 2422, 2212, 983080, 67381, 67380, 2496, + 11516, 944, 67817, 3890, 12168, 1438, 67813, 68335, 70003, 41947, 1220, + 120828, 74946, 70854, 74058, 1571, 42630, 41949, 42805, 8270, 943, 564, + 0, 312, 41980, 983944, 128295, 70797, 8877, 269, 4429, 6272, 9617, 1460, + 6954, 78657, 41120, 65121, 10862, 6060, 41119, 41416, 74355, 4173, 0, + 82948, 0, 1906, 121169, 11532, 74073, 127338, 0, 1985, 6296, 9582, 75071, + 64287, 128406, 78115, 11428, 1730, 2457, 917808, 19918, 10469, 0, 68088, + 7703, 8840, 8035, 120711, 0, 92230, 983357, 6129, 128437, 78586, 128268, + 0, 7874, 8681, 119092, 11206, 13136, 0, 0, 70102, 63886, 70450, 9605, + 71308, 13220, 67348, 67354, 5514, 74960, 9228, 67349, 67356, 67346, 5240, + 9811, 10012, 3096, 0, 0, 74526, 66676, 65873, 0, 128179, 0, 9501, 120832, + 1272, 64536, 65465, 64654, 7467, 0, 1467, 10158, 10040, 0, 9519, 68759, + 70312, 195085, 68820, 12193, 70400, 127240, 121373, 0, 983355, 19935, + 120733, 92162, 68801, 127955, 83133, 93057, 5275, 120195, 128632, 8637, + 43682, 0, 3789, 63880, 11471, 43554, 65862, 11474, 66332, 66603, 68784, + 2426, 12042, 92194, 983911, 9537, 3961, 12115, 77953, 2605, 4500, 64561, + 55224, 4981, 74644, 0, 41646, 11667, 42686, 74991, 42362, 64686, 4499, + 41649, 7589, 128776, 0, 3237, 0, 66895, 68296, 8541, 78298, 70034, 41866, + 0, 983814, 94056, 11174, 69924, 43555, 2823, 9559, 10060, 41940, 8299, + 41945, 7132, 41941, 3308, 7190, 64880, 8614, 65220, 41493, 128679, 41699, + 10762, 43780, 12999, 119245, 128494, 8106, 4128, 0, 6274, 4494, 983082, + 4012, 10395, 983591, 43633, 65447, 78260, 120973, 11004, 695, 739, 696, + 7611, 121073, 42755, 74802, 9227, 7506, 7510, 69937, 691, 738, 7511, + 7512, 7515, 3868, 688, 41847, 690, 2548, 737, 974, 8003, 7406, 127353, + 120166, 128688, 3985, 66425, 65860, 41851, 7051, 69777, 4682, 71873, + 12809, 6406, 4685, 92505, 10879, 10347, 4680, 6341, 0, 3851, 8132, 74325, + 119263, 120855, 127948, 41958, 119176, 917908, 194855, 0, 42657, 71075, + 7643, 42373, 11714, 67587, 43568, 983175, 11717, 7650, 10594, 64951, + 7647, 7649, 128155, 7646, 0, 78082, 9651, 126475, 3891, 127205, 0, 2337, + 1735, 74324, 11134, 2363, 121008, 92443, 43561, 67706, 128032, 74146, + 1860, 7495, 7580, 5812, 7497, 7584, 119140, 127853, 78753, 120347, 7727, + 0, 8498, 69818, 8949, 3065, 42719, 7135, 1569, 92375, 12534, 12124, 7690, + 0, 12533, 983796, 6418, 4543, 78086, 6969, 128444, 74800, 71051, 67974, + 10859, 128650, 983801, 63894, 120760, 12282, 66192, 983583, 74592, 8850, + 74275, 9238, 10617, 68063, 917909, 92625, 917801, 12791, 0, 94069, + 127843, 4447, 71065, 12793, 12900, 92377, 10950, 983449, 74639, 12790, + 41400, 119128, 66607, 12792, 42232, 119239, 1744, 12789, 10366, 12317, + 41310, 120730, 41399, 0, 0, 55258, 0, 12690, 127763, 0, 43672, 127840, + 41652, 2974, 9010, 11315, 983808, 278, 121204, 41405, 43871, 0, 10077, + 63853, 74557, 42586, 0, 0, 6002, 67335, 43553, 11189, 67338, 67337, + 12787, 41308, 7934, 65306, 120263, 120940, 94042, 8646, 128257, 77829, + 71360, 0, 6413, 6550, 113759, 1940, 2809, 43637, 220, 65193, 43551, + 10678, 10044, 68841, 128121, 983816, 68290, 6403, 5707, 10393, 127532, 0, + 66614, 0, 0, 0, 10297, 0, 3742, 67331, 3959, 0, 120466, 0, 2467, 68806, + 6003, 63844, 6663, 8040, 983220, 43758, 4182, 78171, 4676, 120501, 9210, + 0, 2510, 0, 10208, 78168, 92361, 11540, 43546, 6692, 6837, 41060, 128018, + 4668, 9083, 0, 0, 78144, 1559, 63831, 9677, 67340, 67347, 65256, 67345, + 67344, 983352, 983266, 365, 12056, 43027, 120423, 41716, 128236, 67352, + 67351, 5516, 2845, 7717, 8036, 41717, 67353, 544, 12045, 6278, 74632, + 5515, 129186, 120884, 983051, 65339, 43221, 2211, 0, 5517, 70116, 74225, + 74841, 67884, 128414, 67890, 67885, 67880, 67881, 67882, 67883, 120199, + 118883, 67879, 127188, 1902, 67887, 9638, 12976, 126546, 12483, 12368, + 41769, 42726, 41765, 7361, 6667, 67874, 7556, 67878, 74351, 11264, 989, + 42677, 67889, 93040, 1311, 128949, 4326, 11000, 63824, 13068, 10932, + 128880, 6917, 78155, 120837, 949, 77882, 917968, 6148, 8605, 42253, + 78177, 66906, 0, 42715, 71432, 70282, 983373, 63871, 0, 41796, 1269, + 6530, 121414, 65057, 70493, 5144, 12221, 42716, 68299, 4431, 4331, + 983729, 128675, 41834, 5279, 121362, 10336, 8312, 0, 42701, 92959, 0, + 78165, 66036, 70166, 120937, 6428, 42270, 983726, 983596, 43059, 42666, + 5256, 1067, 255, 12131, 128742, 9493, 74990, 41014, 11793, 194920, + 121195, 74394, 43460, 10653, 42723, 983854, 119632, 70427, 6560, 7016, + 74274, 69986, 43556, 3929, 67977, 6614, 2768, 92504, 9746, 5135, 11811, + 12796, 11953, 0, 69761, 5139, 346, 74303, 6305, 12795, 4675, 5168, 78552, + 43845, 74315, 74361, 8253, 8817, 1136, 917931, 43563, 92232, 128914, + 66410, 7392, 8230, 9365, 71194, 127109, 983607, 66915, 128402, 4041, 0, + 2357, 43240, 12786, 229, 43834, 119884, 44004, 7142, 119881, 12350, + 65554, 119882, 71305, 119876, 12785, 63863, 43795, 7770, 10712, 64853, + 12686, 43831, 42375, 65780, 124944, 66352, 10470, 71119, 11059, 10791, + 917944, 450, 119328, 127254, 10432, 12097, 5450, 64691, 1233, 0, 44009, + 78284, 66338, 66395, 917832, 1839, 118799, 983219, 10927, 1701, 983664, + 2388, 41749, 41761, 5453, 8361, 119865, 895, 5444, 41763, 64889, 7143, + 92493, 78677, 983137, 92429, 69983, 66432, 8801, 3053, 4340, 983044, + 128013, 65812, 120675, 70001, 41824, 67985, 120203, 92600, 127053, 42700, + 194805, 127980, 194807, 78676, 92356, 194808, 127844, 0, 4493, 4336, + 129171, 2314, 43602, 78826, 119325, 194811, 42439, 64638, 42327, 43528, + 4489, 68750, 125116, 194793, 1912, 42385, 10306, 10370, 0, 194761, 8867, + 10250, 10258, 2712, 1635, 71064, 1410, 78763, 983252, 118878, 983567, + 128715, 9919, 120528, 559, 128157, 41825, 121274, 74641, 4892, 74016, + 121502, 6542, 41957, 128865, 5777, 127167, 759, 65749, 2079, 65248, + 12788, 64487, 64552, 93063, 10223, 42062, 121279, 0, 74246, 3668, 65754, + 43560, 12226, 67991, 65149, 2340, 41959, 71463, 194785, 194788, 43618, + 65747, 10937, 2962, 0, 2321, 3587, 65745, 67236, 8921, 9952, 128941, 0, + 42714, 9951, 43409, 194770, 2949, 66012, 194775, 194774, 2958, 68359, + 41820, 2300, 2395, 120061, 9976, 120043, 120050, 71896, 68220, 128143, + 42809, 42807, 70798, 66290, 10198, 4150, 64371, 8318, 41790, 67976, + 41898, 2360, 41794, 917942, 70796, 92163, 93033, 0, 2418, 983098, 2411, + 11336, 799, 63823, 10276, 10308, 10372, 917541, 41772, 42813, 2317, + 10260, 118980, 55284, 78686, 127177, 10384, 194794, 121147, 129111, 7753, + 2351, 6655, 64489, 69931, 70199, 77872, 4443, 42779, 230, 0, 68067, + 43549, 4855, 42150, 65739, 5441, 41896, 10288, 10320, 0, 855, 7046, 6109, + 65045, 63839, 78198, 2049, 10098, 917779, 74145, 127943, 10264, 10280, + 9184, 10376, 7013, 4467, 78684, 917554, 92260, 41887, 0, 4862, 9735, + 6537, 120591, 74286, 3914, 92178, 68823, 9065, 12961, 0, 120456, 92253, + 128204, 289, 128714, 4694, 11420, 4690, 0, 120514, 917978, 4693, 73893, + 42724, 69977, 4688, 120454, 128507, 0, 67994, 8238, 3110, 120162, 3565, + 120163, 6528, 78387, 43035, 69898, 218, 983850, 1520, 0, 4786, 983168, + 43225, 4602, 92400, 78167, 10088, 6548, 121157, 120156, 43978, 8988, + 8888, 92724, 74812, 69709, 983967, 10666, 0, 73902, 69740, 121436, 0, + 9975, 113704, 119902, 4689, 8932, 0, 65560, 119209, 74441, 78810, 0, 0, + 67987, 0, 128828, 0, 67989, 119029, 10065, 8207, 71900, 92613, 128011, + 121028, 662, 128720, 9244, 194863, 83183, 119261, 983430, 0, 120901, + 917838, 41929, 0, 71084, 66674, 41926, 69994, 120443, 10513, 64637, + 194862, 68013, 52, 13118, 6475, 195004, 83479, 12095, 10225, 4812, 92578, + 128486, 67992, 74085, 0, 3978, 128425, 917945, 74015, 11582, 92768, + 12281, 127043, 6544, 13241, 93961, 69782, 125014, 194860, 11765, 65258, + 10369, 0, 1585, 7192, 10249, 422, 1500, 2036, 986, 194859, 64394, 5781, + 5599, 64294, 2494, 120450, 4861, 74021, 64334, 78203, 127808, 0, 83444, + 65102, 8961, 65842, 10243, 10245, 71907, 120410, 0, 120453, 64821, 9478, + 2508, 92683, 0, 202, 128246, 74131, 1242, 65514, 121170, 63940, 121363, + 64533, 71883, 120446, 67842, 11990, 92405, 63939, 43375, 65440, 2504, 0, + 78671, 64829, 93020, 6943, 917934, 5859, 0, 2858, 983363, 74294, 983914, + 69239, 0, 67871, 12992, 2753, 1936, 70078, 67701, 2751, 12662, 2763, + 8953, 64701, 10731, 12922, 7052, 917839, 66424, 63992, 0, 63920, 74128, + 2856, 119910, 47, 69908, 71053, 65858, 194806, 0, 67829, 7899, 0, 8417, + 43798, 7072, 74195, 0, 4033, 121289, 43992, 121081, 0, 212, 64600, 1903, + 12320, 83484, 120894, 194563, 0, 8915, 2759, 945, 6689, 93064, 0, 0, + 118798, 1291, 74828, 0, 120435, 9531, 13155, 8505, 68379, 12062, 128198, + 121216, 65487, 92189, 41837, 120611, 8246, 128874, 93066, 0, 120433, 0, + 63935, 73962, 120806, 64787, 43524, 0, 64426, 983092, 194948, 917866, + 917788, 65664, 6693, 9843, 0, 8674, 119887, 128812, 92715, 70788, 1320, + 121461, 1673, 4811, 92383, 5986, 9338, 3046, 74480, 5985, 917928, 119598, + 9820, 119892, 12187, 983841, 71041, 5984, 0, 43308, 4393, 67650, 983227, + 0, 74822, 0, 74826, 64733, 983214, 127898, 3491, 67146, 121142, 128219, + 3514, 65485, 72428, 7492, 128860, 74605, 92483, 7514, 983369, 126585, + 194731, 7502, 7587, 68353, 63921, 121178, 63925, 120161, 7610, 219, + 128158, 78722, 692, 43588, 68485, 41635, 43241, 9688, 7147, 9535, 0, + 93991, 0, 64530, 0, 64610, 11804, 0, 7149, 7453, 0, 8013, 66396, 92301, + 0, 8895, 5253, 70025, 5458, 917629, 2866, 129045, 127860, 11098, 68433, + 6700, 120484, 0, 120583, 194824, 8962, 77960, 9641, 43694, 7059, 983677, + 63997, 9604, 78700, 7441, 63826, 67970, 83435, 64392, 92626, 983687, + 2844, 74610, 41974, 67397, 12139, 67971, 0, 0, 3358, 65295, 983899, 3104, + 194734, 0, 121304, 983235, 5308, 83434, 290, 0, 121338, 2862, 2792, + 195088, 92963, 77984, 3268, 66591, 0, 6552, 42367, 7035, 120558, 0, 0, + 1814, 78464, 10240, 66285, 74305, 128382, 74528, 65903, 71454, 42646, + 7606, 2591, 2837, 4341, 43513, 64482, 92524, 8163, 65270, 0, 77932, 0, + 9112, 74431, 863, 9490, 75037, 128349, 43323, 120513, 119897, 9071, + 68054, 0, 3654, 7789, 9637, 121136, 2535, 65504, 7653, 40993, 92415, + 66587, 124987, 0, 92401, 43927, 11006, 12927, 7807, 8073, 120980, 10629, + 127869, 74088, 3056, 10823, 127267, 92391, 8762, 10508, 69689, 73770, + 43969, 43193, 10737, 3463, 120975, 983351, 66633, 8695, 4815, 11322, + 5811, 12345, 7049, 118811, 5195, 195081, 0, 66639, 92939, 0, 0, 128041, + 67903, 67739, 1262, 120165, 6561, 19939, 128673, 0, 127318, 119906, + 70300, 0, 983097, 0, 983667, 119907, 64612, 11991, 120654, 0, 92943, + 1502, 917568, 127988, 9107, 127316, 5702, 3655, 67661, 8430, 0, 71223, + 120758, 0, 74057, 9603, 128079, 5254, 120742, 7724, 74388, 68375, 10796, + 5129, 0, 70816, 590, 7579, 5614, 5893, 92280, 11720, 92496, 11721, 70804, + 4798, 121468, 119316, 66038, 4793, 67851, 11726, 127541, 74204, 68610, + 68824, 68626, 894, 300, 120875, 12306, 66235, 8004, 0, 119574, 2562, + 70156, 120856, 42503, 92900, 11652, 917813, 917799, 119241, 64699, + 126569, 5096, 5095, 2863, 3424, 92244, 10454, 42530, 5094, 70873, 0, + 13156, 129057, 10832, 5093, 0, 69852, 72430, 5092, 10708, 11327, 0, 5091, + 176, 0, 9153, 4104, 78599, 78601, 1215, 42712, 5744, 12272, 9832, 11777, + 71299, 66817, 42881, 0, 8980, 118988, 67861, 8844, 7209, 0, 0, 4278, + 128809, 0, 119160, 70821, 9074, 4348, 0, 65558, 65946, 8113, 7087, 5255, + 1786, 661, 128116, 0, 917925, 74423, 71345, 586, 74414, 64359, 1267, + 128269, 65468, 194966, 65731, 0, 72405, 3621, 92932, 66666, 64211, 0, + 6562, 12928, 194904, 1228, 65490, 11383, 0, 127953, 70343, 1714, 74406, + 120751, 0, 121113, 983976, 66225, 70110, 70867, 42660, 11436, 2070, 64, + 120694, 121025, 10291, 10323, 2826, 113809, 126510, 0, 42008, 9708, + 42710, 0, 42011, 41999, 92164, 12206, 5839, 1702, 1240, 74065, 6286, + 9689, 983969, 65833, 77848, 0, 1765, 0, 128622, 65588, 92350, 983281, 0, + 8401, 983924, 42014, 127307, 7030, 120969, 10479, 64959, 2852, 0, 121225, + 0, 70819, 128586, 917951, 6963, 126704, 12667, 64540, 74786, 10147, + 12935, 127568, 126483, 121281, 0, 0, 78757, 0, 113815, 121302, 0, 9994, + 12467, 2864, 64719, 1148, 10435, 11462, 41675, 7084, 2765, 78466, 43382, + 0, 120719, 128188, 92516, 66662, 0, 78133, 9364, 194685, 74416, 127797, + 0, 77988, 263, 10449, 41288, 0, 41839, 78385, 983742, 70313, 129140, + 6931, 69722, 43261, 7177, 70105, 92652, 0, 0, 4262, 10285, 10722, 42020, + 126575, 6806, 6992, 42019, 0, 41290, 983716, 750, 0, 71304, 10163, 63913, + 71300, 7032, 5954, 64931, 4314, 128600, 198, 68453, 730, 120094, 63907, + 77993, 70818, 13165, 7107, 74171, 42804, 678, 8240, 78015, 125005, 41378, + 11008, 6938, 70026, 92637, 2097, 66246, 120560, 70823, 194990, 983604, + 3892, 68632, 69642, 6712, 66045, 41470, 64805, 0, 983213, 126511, 64801, + 127818, 497, 12100, 5953, 92667, 7796, 69669, 43254, 73831, 0, 10293, + 5952, 1281, 43747, 0, 121399, 10677, 604, 41097, 9182, 1859, 0, 92603, + 3425, 127488, 126523, 2836, 983738, 0, 9707, 113718, 43202, 0, 0, 65199, + 1738, 128311, 67707, 2832, 92702, 9670, 11101, 0, 66374, 917956, 119552, + 2822, 68122, 4436, 92519, 983081, 73752, 70305, 64872, 92340, 1331, 0, 0, + 121377, 12708, 917954, 5090, 5089, 127977, 917953, 119109, 0, 70826, 319, + 118847, 43479, 9477, 0, 0, 5087, 74886, 7640, 96, 5086, 983597, 92379, 0, + 5085, 64286, 92665, 113717, 41422, 119617, 119901, 42356, 3772, 119042, + 0, 5011, 0, 983329, 126587, 0, 120698, 118874, 6677, 7601, 0, 591, 64419, + 118953, 92262, 118895, 70799, 70084, 0, 10939, 6106, 6933, 41271, 6760, + 71343, 4534, 41270, 128876, 67138, 65574, 194947, 9224, 67140, 3671, + 8976, 67139, 0, 41275, 6372, 82997, 55261, 7963, 6371, 0, 568, 92368, + 41273, 121448, 74531, 6728, 0, 9715, 129297, 8258, 11753, 74820, 0, 9602, + 118919, 42, 11191, 43688, 68243, 0, 7458, 0, 0, 65385, 67135, 67134, + 11958, 11165, 917822, 125087, 6254, 42721, 66336, 8045, 11550, 195064, + 67132, 67131, 42858, 11789, 65868, 5557, 10133, 9737, 13109, 0, 9467, + 5558, 8878, 43844, 195036, 7451, 6706, 10146, 0, 9086, 64566, 983185, + 64584, 7437, 7454, 12594, 73749, 68362, 4546, 7731, 0, 70048, 74243, + 125092, 3805, 0, 67128, 44001, 41008, 128052, 6307, 19949, 67129, 7544, + 124989, 43469, 121095, 983735, 10152, 64422, 65091, 67124, 7602, 64729, + 0, 43521, 0, 42302, 43711, 43523, 41447, 5559, 68483, 8704, 2397, 5556, + 0, 0, 0, 9011, 9630, 11166, 0, 93998, 5506, 92498, 1911, 66652, 67686, + 9961, 8845, 66698, 68325, 10792, 8889, 121402, 2098, 0, 64751, 70309, + 66622, 126626, 0, 74364, 68816, 129152, 983805, 42909, 7552, 70092, + 194567, 65384, 7223, 4559, 93015, 1956, 43138, 7024, 65728, 43490, 1210, + 195077, 65175, 10184, 43140, 43654, 0, 983233, 125045, 38, 8533, 66669, + 119124, 983295, 983792, 0, 4357, 0, 70289, 917863, 74233, 9967, 78884, + 42860, 119838, 10941, 65721, 6962, 0, 83279, 113808, 0, 11014, 120126, + 8942, 12000, 69224, 92267, 128536, 11974, 67363, 42772, 42650, 11650, + 5013, 92663, 68810, 66210, 118914, 6613, 92476, 0, 11193, 983770, 0, + 64714, 71479, 70802, 12162, 12120, 43476, 983766, 11024, 74811, 66228, + 10563, 92954, 127196, 43522, 2462, 92955, 1837, 125086, 63972, 6957, 0, + 113820, 4952, 65718, 64405, 5504, 65720, 65714, 65715, 65716, 128026, + 75016, 127119, 3109, 63975, 74028, 127213, 8107, 67154, 1127, 455, 0, + 63968, 127835, 3483, 119593, 1989, 983176, 69678, 9104, 3503, 65375, + 68300, 6694, 42633, 1864, 0, 74306, 41446, 2540, 7736, 121434, 74064, + 128601, 10521, 70786, 42173, 9705, 74124, 8604, 6955, 10916, 43684, 6149, + 3887, 19956, 1411, 2824, 0, 10106, 127862, 1403, 125053, 1347, 9631, + 74444, 983753, 127997, 92951, 74897, 8640, 0, 258, 1654, 0, 0, 983479, + 43314, 0, 0, 4042, 11478, 2873, 63977, 11522, 41668, 8549, 10861, 121053, + 63976, 70377, 68623, 67082, 67081, 41391, 67084, 83465, 376, 6987, 9221, + 0, 0, 8823, 128697, 12943, 65185, 41869, 12619, 128067, 10154, 983043, + 74439, 2039, 0, 7446, 1684, 63979, 10974, 458, 120620, 82950, 69791, + 127161, 11916, 65016, 0, 69671, 42115, 121057, 12288, 78057, 67080, 1493, + 42111, 7553, 4097, 128199, 13080, 0, 65808, 6610, 6030, 8059, 7508, + 13131, 67074, 67073, 128506, 8794, 41278, 41629, 12154, 75073, 41277, + 64658, 983456, 64380, 6625, 42911, 19904, 0, 121305, 71193, 65371, 7078, + 128699, 833, 128228, 6369, 194815, 10979, 41953, 983370, 41434, 6062, 0, + 0, 19916, 6913, 933, 1341, 9842, 6720, 65744, 71200, 983592, 121223, + 126567, 7405, 10105, 65810, 0, 41632, 7493, 55290, 92890, 41622, 0, 0, + 119556, 74584, 7632, 9716, 19954, 9805, 5990, 900, 0, 63957, 119638, 0, + 3612, 0, 64376, 93987, 5389, 92597, 0, 65938, 2839, 9621, 582, 0, 74368, + 3749, 6949, 7569, 74061, 83222, 83223, 6956, 4403, 19962, 65559, 3299, + 121005, 194939, 119127, 9002, 0, 74372, 74236, 8478, 7598, 546, 42469, + 65569, 1918, 9542, 472, 7716, 10319, 10383, 6996, 43077, 63952, 8425, + 3602, 8328, 11764, 83199, 83200, 65065, 41183, 12907, 10271, 10287, 684, + 43525, 127996, 2854, 83214, 4592, 65755, 83217, 67120, 11963, 43620, + 67117, 78249, 67123, 67122, 67121, 9881, 43115, 65757, 3415, 69677, + 67116, 8648, 128377, 6741, 43047, 119900, 13180, 78077, 418, 120653, + 64495, 10295, 10327, 10391, 41752, 66846, 8641, 41449, 83194, 74100, + 83186, 10911, 6942, 120879, 1024, 42849, 41751, 69776, 8941, 983556, + 4554, 66892, 9023, 11685, 121476, 9928, 67109, 66865, 11437, 43741, + 67113, 67112, 63967, 129056, 41206, 12624, 9049, 41185, 43166, 121275, + 8159, 92619, 11686, 71478, 65224, 4565, 4655, 119553, 129090, 92183, + 64523, 10343, 10407, 92764, 66671, 11466, 0, 128003, 42890, 74013, 12050, + 68201, 2860, 0, 127934, 70828, 42792, 5743, 10424, 12065, 42872, 121401, + 43875, 67103, 8875, 0, 67102, 67105, 7531, 12847, 2413, 118917, 67404, + 962, 0, 12855, 41196, 42564, 127975, 1582, 983715, 5508, 0, 120904, + 74588, 10801, 69876, 92354, 119207, 7173, 496, 10439, 4313, 64607, 69638, + 7860, 128049, 906, 42793, 2842, 6405, 64722, 13132, 798, 64694, 12801, + 8406, 1153, 83263, 64788, 83265, 8054, 9174, 67087, 67086, 9964, 67096, + 41611, 4642, 66574, 11556, 42512, 0, 78857, 42089, 74613, 9008, 0, + 126592, 195096, 42079, 83248, 77924, 42513, 77927, 42842, 73985, 65285, + 68338, 83239, 83240, 83241, 83242, 983590, 11335, 64069, 42093, 3920, + 917869, 0, 11110, 83255, 4580, 41967, 83258, 64384, 83252, 83253, 3021, + 42004, 983096, 83249, 42317, 41998, 0, 6946, 194755, 92967, 128455, + 128193, 65204, 0, 68113, 42690, 9880, 42010, 74824, 64589, 10111, 64875, + 127880, 68035, 43998, 11360, 83233, 74182, 83235, 83228, 42149, 83230, + 68508, 917993, 64941, 77919, 120421, 128077, 74885, 55247, 4110, 66005, + 6959, 10929, 42907, 128080, 66703, 77921, 8617, 41982, 6025, 69242, + 121068, 194854, 125139, 0, 9597, 42099, 43172, 983378, 10117, 983169, + 92297, 41636, 194889, 73738, 120681, 8301, 0, 0, 187, 128237, 65669, + 128339, 4963, 0, 68765, 0, 8964, 65676, 7775, 983849, 41948, 125003, 0, + 83236, 41942, 65449, 3160, 10081, 13226, 42121, 42475, 42663, 120616, + 41766, 74948, 65882, 78849, 41760, 1189, 905, 480, 10985, 41733, 67859, + 9629, 6742, 1745, 43625, 73835, 7888, 83405, 3980, 70373, 42656, 41507, + 8806, 7023, 0, 74279, 9447, 78651, 7867, 69218, 6236, 127162, 0, 10505, + 126638, 12851, 83489, 348, 5474, 121382, 3103, 0, 41753, 71109, 128604, + 0, 78844, 78845, 41739, 78843, 42515, 10931, 41756, 43347, 42560, 5391, + 41746, 119147, 92591, 41259, 5561, 69930, 2691, 68752, 65553, 7933, 5562, + 69800, 128265, 41262, 128146, 64421, 74846, 41251, 127242, 0, 3979, + 71248, 194899, 68331, 917912, 68847, 983697, 83382, 74633, 41266, 68836, + 66566, 128836, 10585, 65741, 41737, 2275, 2666, 121232, 41738, 831, 419, + 13126, 10716, 83400, 42822, 0, 6434, 74857, 6939, 7766, 6432, 128106, + 69932, 916, 769, 41742, 11968, 74805, 6433, 5563, 547, 1943, 6439, 5560, + 4994, 487, 126537, 4497, 3754, 83072, 83105, 9039, 0, 41776, 0, 8716, + 1595, 41615, 121001, 0, 74260, 74860, 42854, 43219, 83311, 121107, 12185, + 113810, 70072, 68355, 68357, 68421, 42856, 8634, 0, 119988, 4209, 75057, + 68832, 65879, 41538, 65612, 68822, 669, 5679, 68813, 68815, 68811, 68812, + 68804, 5678, 11821, 68802, 6711, 460, 121513, 0, 983463, 70114, 120747, + 194718, 121519, 78050, 119022, 0, 121515, 121514, 7782, 9044, 4974, + 11760, 78494, 7577, 65711, 41912, 1216, 0, 127017, 5792, 126643, 128319, + 78501, 0, 2933, 12244, 983702, 5683, 917896, 120895, 78119, 1549, 0, + 983223, 120398, 5682, 6206, 8670, 10256, 5680, 69935, 10001, 67237, + 69768, 1449, 10241, 78290, 119587, 194891, 10552, 64342, 41922, 70330, + 8584, 68030, 5567, 2717, 83179, 71448, 5564, 42886, 41908, 42882, 5565, + 917611, 120881, 0, 65708, 65709, 5566, 69803, 65704, 65705, 11904, 42875, + 43373, 42539, 5942, 8468, 120561, 10361, 10425, 65697, 65698, 65699, + 68052, 66598, 110592, 64664, 10647, 78702, 78703, 78690, 457, 78502, + 65701, 1934, 43006, 83280, 8802, 78710, 65130, 11747, 78709, 6087, 78705, + 78716, 41757, 78711, 8043, 8950, 65694, 64485, 43534, 10457, 0, 11961, + 78725, 66850, 78723, 78720, 78721, 127899, 65515, 9499, 10035, 13069, + 71309, 0, 9889, 68184, 42806, 125061, 7256, 0, 68094, 1667, 42161, + 120981, 42428, 0, 6934, 0, 10802, 64861, 6556, 78390, 0, 8101, 3610, + 68420, 41748, 4995, 955, 65907, 119208, 5350, 64339, 78306, 64549, 10875, + 125052, 5477, 65692, 0, 128532, 120397, 12896, 10456, 68298, 0, 3874, 0, + 0, 983619, 120331, 128773, 113665, 65603, 83272, 65687, 0, 41038, 74009, + 9207, 42239, 8536, 78740, 78324, 78726, 74432, 724, 83058, 1455, 78749, + 7183, 64583, 78747, 68443, 4175, 78741, 43614, 69801, 939, 75021, 43520, + 68613, 74569, 917958, 0, 70168, 78764, 78760, 10788, 6088, 78759, 78755, + 190, 119899, 12593, 0, 8188, 64408, 0, 4417, 121303, 92261, 6370, 125128, + 7827, 68441, 6965, 128581, 128868, 13201, 128205, 69896, 78868, 74382, + 11841, 7918, 73988, 0, 113668, 917884, 1728, 983705, 43764, 178, 12972, + 74620, 113671, 71103, 11168, 983383, 113672, 78327, 75042, 65690, 8382, + 71107, 119054, 194968, 9252, 917889, 4652, 68371, 0, 121327, 74070, + 13065, 9923, 10806, 194596, 11763, 70016, 120688, 6723, 78187, 0, 6993, + 71044, 121312, 8333, 121329, 0, 11390, 0, 74464, 0, 92320, 74080, 983317, + 69911, 11910, 92559, 8278, 8963, 4034, 128560, 983113, 65344, 120517, + 41747, 0, 128110, 8677, 0, 12707, 9350, 66037, 128180, 8836, 12315, + 12747, 8300, 194562, 124984, 7491, 8856, 71361, 0, 43150, 127768, 120404, + 65389, 120402, 120403, 10813, 2592, 12853, 43269, 7263, 83308, 6536, + 120238, 71891, 65516, 12321, 120391, 120388, 55287, 10007, 120246, 9588, + 68494, 1596, 120383, 41994, 65801, 128808, 6838, 3561, 119867, 0, 10613, + 6697, 12805, 41928, 40981, 10804, 78409, 5006, 64328, 0, 9931, 0, 8825, + 74555, 65940, 43259, 126586, 6107, 83455, 119177, 77941, 78401, 119270, + 11783, 335, 120227, 64689, 438, 4510, 5765, 8721, 119570, 119227, 6092, + 12840, 43112, 8876, 120231, 8096, 10284, 120935, 0, 0, 10380, 8733, + 10316, 70121, 41602, 917575, 92308, 74831, 93984, 0, 68482, 65399, + 917820, 64591, 42405, 83466, 120820, 843, 11541, 128326, 70321, 2065, + 41935, 74496, 41902, 0, 983306, 215, 41258, 77875, 43159, 1953, 9579, + 41938, 1256, 3910, 9407, 6242, 0, 83464, 41257, 41900, 8675, 10700, 8805, + 1742, 113722, 9333, 8202, 72399, 0, 983197, 127252, 0, 73882, 499, + 983049, 43467, 0, 43818, 83482, 1712, 5932, 77845, 41762, 983103, 0, + 11967, 1775, 125006, 75009, 11118, 121391, 128009, 9458, 92935, 6470, + 9180, 120380, 43176, 128307, 0, 42782, 0, 124999, 983135, 128309, 73849, + 120669, 9414, 74647, 73782, 73969, 565, 42484, 5794, 201, 2662, 42292, + 194870, 8254, 0, 10975, 43518, 120625, 74763, 1022, 4108, 3880, 74247, + 127153, 0, 92263, 917980, 7507, 983118, 43149, 71059, 65031, 7961, 1636, + 0, 65029, 65024, 119099, 12473, 6534, 120633, 99, 98, 97, 68226, 67584, + 4049, 74163, 127065, 7090, 83274, 7892, 127064, 10777, 917803, 65310, + 65562, 66599, 66722, 194955, 8039, 3363, 66594, 43434, 127062, 71191, + 12596, 66595, 42258, 42570, 5593, 119148, 120534, 92425, 10100, 6061, + 64854, 119, 118, 117, 116, 12998, 122, 121, 120, 111, 110, 109, 108, 115, + 114, 113, 112, 103, 102, 101, 100, 107, 106, 105, 104, 6436, 73974, 534, + 41212, 67713, 1536, 64093, 73970, 77930, 121093, 0, 6020, 12716, 127112, + 12744, 475, 120394, 13266, 127813, 127111, 78842, 73926, 66291, 10645, + 1212, 6543, 983309, 8134, 42935, 2913, 73870, 127113, 1866, 983229, + 71892, 120996, 8923, 1645, 12059, 66585, 71297, 3196, 72404, 194827, + 5935, 1250, 127066, 8174, 9787, 6733, 9859, 7916, 9861, 9860, 5258, 1882, + 1892, 6731, 10882, 405, 11454, 73911, 113787, 73819, 41169, 8939, 41245, + 128775, 41170, 1454, 11369, 6477, 12157, 120861, 0, 0, 41172, 7855, 0, + 71472, 10480, 43258, 126596, 77936, 8264, 12610, 983310, 645, 126616, 7609, 40973, 69943, 73833, 69948, 5824, 984, 77918, 10688, 5851, 0, 7729, - 73982, 120518, 0, 195086, 43369, 0, 128140, 68415, 983093, 4538, 120406, - 43141, 0, 983210, 74214, 73886, 0, 0, 118902, 43005, 78448, 9552, 0, 0, - 983159, 12997, 0, 0, 0, 0, 2381, 12883, 10994, 10529, 41906, 0, 0, 0, - 12425, 10661, 10856, 9614, 2428, 41478, 8582, 10064, 73930, 0, 0, 0, - 64896, 119162, 1952, 92181, 8455, 10082, 11575, 983490, 119566, 0, 12808, - 12183, 6145, 118955, 64929, 92433, 0, 983193, 43186, 42509, 0, 3922, - 9187, 983614, 0, 10191, 119057, 11752, 3353, 9358, 0, 71366, 66680, - 120090, 8248, 7931, 8558, 9795, 68380, 983297, 0, 120082, 120081, 120084, - 41027, 120086, 0, 120088, 7366, 7019, 120073, 0, 11751, 120078, 78294, - 64657, 8657, 120048, 8594, 120068, 0, 0, 120069, 120072, 120071, 0, 0, - 43154, 41029, 0, 11332, 65380, 7728, 94077, 11294, 0, 66665, 7851, 0, - 8375, 8699, 0, 42524, 0, 9085, 94041, 7504, 9327, 6160, 128095, 983864, - 0, 8088, 0, 74012, 92500, 0, 4439, 6926, 983047, 12924, 128227, 42369, - 4350, 65491, 65145, 9041, 43559, 64577, 10826, 0, 11296, 983283, 0, 0, - 65825, 9577, 68199, 0, 64670, 983121, 78056, 6793, 11295, 0, 78053, - 73872, 0, 0, 10902, 0, 0, 78070, 78068, 10472, 2995, 0, 0, 64682, 2371, - 78069, 120808, 259, 1009, 92171, 2402, 2333, 6440, 194741, 0, 65125, - 41244, 0, 13271, 9103, 2278, 0, 0, 0, 0, 10219, 0, 0, 0, 0, 43178, - 127070, 41261, 119362, 43640, 8613, 0, 94049, 6736, 195092, 41492, 12005, - 69927, 0, 1890, 120056, 0, 0, 0, 7293, 7991, 0, 10578, 0, 78076, 194738, - 78077, 69928, 0, 78800, 92653, 64445, 42668, 6635, 0, 6164, 65170, 0, 0, - 7676, 11664, 0, 983658, 69707, 0, 118812, 0, 0, 128045, 9175, 11925, - 78045, 9088, 0, 64545, 1396, 0, 7546, 3847, 127177, 127835, 4985, 13288, - 672, 8098, 43196, 194746, 983096, 128126, 42655, 74043, 65072, 1577, - 11772, 13041, 5928, 4525, 10658, 65911, 1266, 10180, 0, 128584, 12622, 0, - 0, 0, 194714, 127139, 13310, 773, 19933, 1539, 0, 126983, 42731, 67972, - 0, 0, 0, 3051, 5862, 7823, 92478, 0, 120411, 3250, 43991, 69687, 66649, - 9510, 66237, 983302, 0, 41066, 64673, 917963, 917964, 0, 3505, 8707, - 917968, 6725, 128013, 917971, 92314, 3471, 917970, 5479, 882, 6686, - 119584, 11613, 120772, 42754, 0, 983306, 92696, 0, 0, 0, 128523, 3225, - 917996, 4433, 41156, 43973, 43173, 1443, 4381, 0, 0, 10926, 11756, 11757, - 64879, 917949, 917950, 127848, 13227, 0, 10021, 5160, 1387, 0, 917953, - 41418, 0, 65914, 6721, 217, 917955, 917960, 917961, 10443, 10789, 41158, - 119257, 4274, 983300, 41483, 0, 41250, 0, 42179, 0, 5931, 11744, 69232, - 0, 41252, 66682, 0, 119637, 41249, 1366, 64635, 65047, 12466, 0, 0, 4397, - 128037, 128336, 41296, 9545, 41291, 128049, 0, 41485, 3511, 41282, 5923, - 10400, 0, 128818, 760, 0, 12088, 5786, 0, 42256, 119869, 119860, 417, - 41474, 119562, 41565, 0, 5934, 119867, 66583, 119231, 64877, 2284, 64481, - 78614, 66013, 41956, 43455, 126995, 0, 0, 0, 42273, 5819, 0, 917556, 0, - 126643, 0, 65910, 127747, 10246, 120816, 65785, 1237, 10274, 4552, - 119576, 0, 0, 1375, 66705, 43573, 65260, 42063, 0, 42811, 10312, 69845, - 120794, 7840, 0, 43630, 10252, 0, 128104, 43185, 0, 4396, 0, 119880, - 10769, 9676, 119041, 0, 9753, 0, 8944, 0, 0, 10473, 0, 0, 6072, 43025, - 10299, 0, 0, 120608, 66326, 983447, 127794, 0, 43811, 9330, 120596, 7222, - 10283, 10315, 10379, 4996, 983782, 13281, 66517, 7865, 10087, 78343, 0, - 78347, 0, 0, 7565, 66363, 12952, 64806, 43180, 77928, 7414, 77929, 43982, - 74288, 622, 74023, 885, 43405, 1602, 0, 0, 852, 0, 12160, 0, 10212, - 65435, 0, 12071, 9609, 12156, 917983, 917984, 43586, 11035, 10411, - 917988, 10255, 6710, 10279, 4194, 10375, 73900, 0, 4315, 12644, 127516, - 77937, 43639, 43343, 78777, 917998, 11501, 41177, 128689, 0, 917792, 0, - 92413, 8715, 0, 41179, 0, 43313, 0, 41176, 0, 994, 0, 8452, 127103, - 73966, 0, 0, 5921, 0, 2597, 0, 5922, 118903, 77943, 4186, 92531, 119967, - 127105, 6718, 0, 4406, 74601, 8480, 9192, 9747, 126530, 4413, 92196, - 42268, 3198, 5924, 5920, 92469, 6921, 78081, 74007, 42869, 8418, 11681, - 43169, 10176, 0, 742, 0, 2893, 10772, 65276, 5937, 1914, 2553, 11682, - 6756, 128590, 128646, 8363, 0, 2993, 7772, 3916, 4301, 120494, 1141, - 42407, 8159, 718, 7572, 973, 0, 120718, 3235, 2415, 43164, 0, 8018, - 42333, 74756, 10675, 6937, 42486, 43381, 65390, 10067, 0, 1202, 0, 0, - 65863, 0, 0, 94013, 78182, 64542, 3260, 73829, 65388, 9945, 8419, 78042, - 6738, 0, 43681, 69728, 2059, 0, 0, 55237, 1431, 0, 66565, 10821, 0, - 12804, 128076, 8229, 1235, 3307, 11472, 78089, 78184, 4544, 0, 0, 0, - 1740, 78097, 8758, 985, 12872, 64511, 78094, 12068, 78102, 0, 10141, 0, - 63761, 8785, 4476, 78109, 63763, 12655, 8907, 78105, 78106, 78103, 78104, - 0, 119572, 10665, 64616, 41572, 0, 127160, 0, 41573, 0, 3931, 120295, - 74143, 0, 0, 0, 78460, 11982, 0, 0, 0, 128016, 64484, 0, 41167, 0, 41735, - 94019, 717, 10754, 0, 0, 127979, 0, 63767, 0, 1780, 6936, 0, 92254, 819, - 10611, 9694, 126978, 0, 0, 0, 0, 8343, 8342, 8345, 8344, 6578, 7009, - 7523, 6922, 8348, 8347, 7525, 3346, 8339, 128165, 128338, 575, 268, - 78111, 8563, 5754, 120343, 41541, 65565, 8336, 5936, 7290, 78117, 8337, - 8341, 308, 11388, 7522, 120721, 78123, 65466, 11090, 6953, 0, 120346, 0, - 78132, 5926, 78128, 78130, 78126, 78127, 78124, 78125, 9038, 7887, 43456, - 7830, 11651, 13093, 64002, 0, 65742, 12874, 119597, 11590, 0, 74048, - 128350, 8595, 0, 917947, 43703, 13097, 0, 64643, 13283, 12697, 0, 12381, - 3488, 5933, 10033, 73738, 66241, 65570, 0, 12297, 119153, 1955, 0, 5349, - 42538, 0, 0, 7411, 9462, 917554, 0, 0, 0, 42736, 0, 5756, 983221, 7638, - 41642, 42764, 0, 43109, 7637, 5752, 74037, 0, 73832, 128827, 120635, - 128231, 78334, 0, 7636, 65171, 9124, 0, 78892, 120798, 291, 0, 0, 2027, - 66230, 10080, 78136, 10403, 0, 4640, 64713, 10224, 120429, 42512, 120431, - 120430, 0, 128351, 127489, 127148, 0, 92499, 0, 119094, 74213, 7824, 0, - 0, 41274, 5778, 6302, 0, 0, 12680, 119130, 1417, 77889, 194914, 9452, 0, - 74393, 11552, 0, 127855, 128217, 65391, 0, 10172, 65453, 63789, 41264, - 78658, 6426, 4641, 9179, 64819, 55278, 41255, 42036, 41469, 41269, - 120412, 41267, 4646, 120425, 865, 42034, 78274, 78273, 4645, 42033, - 78270, 127982, 983172, 64728, 0, 78673, 78674, 1659, 919, 42784, 1671, - 195089, 6069, 9219, 128558, 1661, 13120, 63784, 69819, 10140, 9713, - 119143, 0, 0, 94050, 2306, 10485, 118943, 6068, 10612, 195099, 119567, - 195101, 92561, 41462, 120470, 195079, 5422, 128234, 983629, 0, 0, 10229, - 10635, 826, 128081, 195082, 195085, 195084, 195087, 6483, 92211, 1808, - 7848, 0, 8100, 78227, 78669, 78670, 13301, 78667, 9667, 78665, 78872, 0, - 11003, 9904, 0, 0, 120690, 9144, 10921, 0, 78680, 9840, 65131, 78678, - 77841, 10313, 0, 0, 64320, 10265, 78686, 10962, 78684, 43008, 8945, - 78683, 0, 41, 195072, 1792, 120515, 195073, 8655, 195075, 92544, 77951, - 12066, 0, 385, 4152, 2585, 127804, 119068, 3126, 0, 74136, 10957, 983703, - 43258, 119116, 127873, 13157, 0, 917544, 3570, 0, 7443, 0, 44006, 6997, - 68004, 126631, 7879, 8739, 11075, 0, 65216, 0, 69795, 2593, 8463, 7810, - 917862, 7839, 119913, 78806, 119912, 9691, 4411, 78802, 0, 0, 43442, - 69851, 65254, 10066, 983889, 0, 0, 0, 13061, 8016, 78687, 19932, 64831, - 0, 119923, 12390, 119171, 1634, 68115, 0, 11056, 983574, 119925, 0, - 41165, 11328, 12450, 0, 41166, 0, 12456, 119914, 171, 5941, 12452, - 194709, 12458, 12531, 78779, 43013, 63800, 74162, 127569, 120483, 9969, - 120767, 12454, 63806, 42132, 12063, 78425, 78424, 3230, 0, 0, 0, 5209, - 297, 5810, 8522, 8415, 119937, 78429, 78428, 7077, 2497, 128651, 960, - 74156, 6981, 92374, 12938, 4292, 0, 74815, 10512, 0, 74814, 78875, - 127505, 78876, 2503, 73778, 1762, 69794, 2495, 78873, 5844, 68031, - 118838, 0, 12654, 4663, 1899, 78877, 2507, 64121, 8726, 65594, 0, 0, 0, - 8892, 0, 92339, 0, 983073, 5782, 420, 0, 0, 43796, 10797, 63794, 0, 0, - 64814, 63796, 77965, 0, 66581, 119204, 41608, 0, 0, 63792, 4659, 120788, - 0, 43676, 0, 69673, 0, 0, 0, 329, 77968, 92707, 917548, 7399, 0, 41188, - 13244, 120466, 42167, 7435, 78193, 5380, 119086, 69225, 1155, 11365, - 43126, 77972, 0, 65684, 0, 5601, 65192, 42765, 63752, 0, 7987, 128543, - 1172, 69799, 6786, 43601, 120476, 74126, 5603, 0, 4473, 0, 194823, 0, - 65347, 65346, 65345, 0, 127384, 5347, 69802, 983632, 73868, 118944, - 10588, 0, 0, 63755, 0, 5343, 78422, 120661, 4555, 5341, 0, 70071, 128670, - 5351, 78675, 43104, 65244, 917892, 64541, 42519, 74472, 0, 0, 74765, - 917888, 127510, 6638, 0, 65113, 271, 74180, 65370, 8835, 65368, 12653, - 65366, 42172, 41086, 65363, 65362, 65361, 11912, 43410, 11323, 65357, - 11800, 65355, 5345, 65353, 65352, 65351, 761, 65349, 19959, 69718, 63856, - 126635, 2423, 77958, 64647, 77959, 11957, 4699, 0, 0, 0, 0, 64605, 0, 0, - 0, 4916, 0, 380, 10958, 66563, 77955, 69773, 9773, 13167, 12918, 41096, - 73980, 69245, 78254, 917893, 10684, 0, 917896, 0, 7946, 12541, 8182, - 67586, 69780, 0, 0, 0, 0, 9005, 1225, 6630, 0, 0, 0, 68011, 8847, 0, - 65876, 5535, 8329, 74590, 983208, 92609, 0, 0, 3127, 2595, 65713, 42013, - 983858, 5607, 41089, 0, 0, 74256, 2665, 11304, 43751, 74200, 4970, 8764, - 120459, 8934, 92726, 41566, 4492, 0, 65011, 41090, 0, 0, 1188, 7254, - 1100, 0, 128301, 41081, 2912, 11749, 69792, 0, 68019, 3572, 10023, 4959, - 13079, 0, 983276, 9729, 0, 0, 0, 43361, 0, 0, 11803, 7996, 9907, 41450, - 13304, 128290, 127260, 41451, 0, 11095, 8273, 127533, 3451, 983309, 972, - 41453, 983442, 0, 73883, 68022, 73945, 983735, 2288, 19955, 9538, 0, - 69807, 0, 0, 0, 0, 11396, 983440, 11019, 0, 0, 0, 68020, 41078, 71365, - 261, 5927, 7791, 0, 7362, 0, 10696, 0, 6073, 9838, 118920, 0, 6075, - 93995, 282, 126510, 6437, 74078, 128000, 9801, 0, 74177, 0, 0, 3474, - 118787, 0, 120655, 6081, 0, 78874, 74076, 78879, 0, 0, 0, 0, 0, 8751, - 11499, 120273, 7816, 12636, 4665, 12628, 4670, 92608, 120272, 68017, - 9642, 10912, 958, 0, 11387, 78878, 4666, 0, 4915, 0, 4669, 0, 68099, - 13287, 4664, 10836, 120550, 0, 69775, 0, 43595, 7450, 0, 917875, 8664, - 9697, 3606, 917873, 0, 0, 64815, 1063, 120250, 120251, 9772, 7255, 8886, - 1389, 127932, 120257, 120258, 120259, 12941, 42661, 92381, 120255, - 120256, 12301, 120266, 69820, 41102, 64428, 120262, 120263, 120264, 1017, - 66600, 523, 505, 1447, 74436, 0, 0, 0, 8608, 42789, 120613, 128704, 0, - 73855, 11307, 66707, 917871, 127751, 11745, 7919, 0, 1641, 0, 0, 8966, 0, - 0, 5908, 0, 0, 6744, 128355, 1699, 69861, 74843, 917933, 0, 6306, 10169, - 71324, 119251, 10068, 3766, 2389, 120456, 120455, 6611, 257, 43170, - 13153, 0, 42386, 0, 9436, 2599, 0, 6496, 9449, 5930, 11476, 11033, 11447, - 10541, 5622, 120436, 8477, 3760, 1718, 9442, 66433, 3776, 0, 41435, 4352, - 983610, 2435, 120809, 5621, 120385, 4201, 3778, 4203, 4202, 4205, 4204, - 120447, 3768, 68142, 765, 41440, 3764, 8473, 6373, 8469, 120438, 12947, - 4564, 0, 0, 74271, 73753, 8374, 983156, 0, 6829, 5225, 128807, 127385, 0, - 0, 119615, 0, 74793, 5626, 73807, 11771, 74075, 127236, 128019, 42614, - 5353, 5625, 74179, 0, 0, 1010, 64572, 41780, 42623, 64277, 69942, 6952, - 983272, 120752, 78762, 2590, 5629, 65552, 7551, 10325, 5632, 10471, - 120038, 120027, 120028, 120025, 5628, 120031, 970, 120029, 4772, 2400, - 5627, 120017, 120018, 120023, 64275, 120021, 8786, 0, 203, 0, 0, 0, 0, - 78350, 0, 64378, 42054, 0, 0, 554, 119649, 11358, 0, 12182, 42048, 11065, - 126464, 73891, 0, 0, 5694, 7689, 69798, 9323, 4325, 3047, 10317, 175, 0, - 0, 69764, 0, 0, 1243, 42154, 5431, 6652, 0, 69770, 43651, 0, 68118, - 128024, 1129, 126574, 0, 65900, 1986, 7846, 78804, 8661, 917772, 65255, - 0, 3845, 4490, 118969, 6649, 74400, 1456, 7530, 11977, 7249, 8366, 0, - 7756, 12342, 128568, 51, 41516, 0, 8570, 9568, 71318, 456, 7026, 8145, - 1168, 9251, 9082, 119964, 64055, 42781, 3866, 12323, 41512, 73805, 68121, - 0, 41494, 92316, 4660, 0, 10405, 0, 78803, 0, 0, 42040, 73918, 119627, - 7944, 41454, 12605, 0, 42205, 41455, 236, 64051, 78867, 8214, 0, 0, 0, - 41457, 983970, 119589, 1969, 2384, 8097, 917864, 7413, 68012, 78029, - 8766, 0, 78079, 5854, 127974, 10583, 0, 119989, 0, 10416, 917869, 3872, - 917868, 0, 8429, 0, 118806, 2838, 128802, 0, 917866, 0, 0, 0, 983967, - 94005, 11096, 120813, 10553, 1662, 8483, 120396, 43605, 5892, 43418, 0, - 73742, 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, 119862, 10357, 7385, 8170, 1704, - 8556, 0, 9659, 0, 0, 0, 9556, 0, 4503, 11353, 9647, 0, 78185, 0, 0, - 92713, 78886, 0, 0, 74229, 66593, 6438, 917979, 9109, 78882, 1289, 64599, - 0, 68009, 0, 65507, 2447, 0, 0, 128042, 126545, 983137, 0, 6334, 0, 0, - 19937, 0, 92368, 0, 5675, 254, 0, 0, 69686, 42425, 8918, 64003, 5716, - 42312, 0, 0, 6972, 42826, 0, 42464, 120567, 0, 92645, 74796, 64400, - 64693, 0, 77861, 65429, 9515, 4435, 0, 42522, 0, 68008, 11785, 7412, - 64671, 41978, 1412, 4594, 1391, 10536, 8067, 9901, 7103, 128293, 7102, - 74588, 120748, 3140, 128854, 7960, 43271, 0, 12518, 10909, 127508, 1428, - 12472, 0, 69864, 7699, 12393, 0, 0, 0, 74518, 8223, 0, 4261, 0, 0, 0, 0, - 0, 128302, 0, 128046, 43419, 0, 64554, 10574, 3878, 0, 42352, 1752, - 73785, 0, 42506, 128541, 10199, 0, 0, 68021, 65919, 0, 6695, 720, 324, 0, - 0, 43406, 983736, 1464, 40985, 0, 7974, 0, 43474, 0, 64488, 0, 0, 64041, - 74787, 0, 78865, 92258, 65597, 0, 78863, 0, 1302, 0, 78861, 119134, 0, 0, - 5204, 74774, 43404, 11835, 0, 3995, 68360, 65608, 3714, 92190, 0, 0, - 10999, 11750, 0, 43251, 68660, 43301, 0, 120557, 8130, 8672, 10845, - 11964, 0, 983185, 0, 0, 68455, 42863, 73839, 0, 0, 0, 0, 126629, 0, 468, - 612, 0, 64401, 66448, 68376, 0, 1674, 0, 5823, 983163, 12280, 0, 540, - 74564, 119017, 0, 8432, 0, 11073, 0, 64316, 0, 0, 820, 41741, 0, 120667, - 0, 64684, 126992, 3359, 7800, 69934, 65177, 6226, 353, 12396, 0, 119612, - 64742, 128682, 120282, 0, 983450, 12412, 19941, 0, 120277, 78847, 1884, - 9481, 42418, 70059, 41157, 0, 1195, 64898, 7924, 0, 41151, 2010, 0, - 41328, 42344, 0, 12409, 0, 4360, 127009, 9739, 128550, 69933, 73921, 0, - 42521, 8539, 983725, 0, 118986, 0, 4788, 0, 68023, 65734, 983455, 43790, - 0, 13075, 74429, 94063, 64569, 43532, 10837, 2492, 127197, 118901, 68637, - 41136, 43785, 11813, 9649, 41154, 119617, 5128, 4038, 41143, 65604, - 64859, 41592, 6771, 1648, 5435, 917837, 6734, 41343, 119848, 65439, - 12709, 6986, 92364, 68015, 0, 41349, 70021, 12581, 10374, 5175, 0, 73806, - 10254, 0, 10278, 10262, 69858, 41346, 0, 607, 0, 119852, 128846, 12923, - 10314, 10282, 65477, 10378, 120297, 40976, 8265, 0, 119834, 40975, 5840, - 42838, 0, 40978, 983897, 119840, 0, 983071, 0, 66444, 10538, 0, 2550, - 119836, 6779, 0, 0, 3525, 6824, 118886, 0, 0, 5619, 65822, 126567, - 194882, 7455, 0, 5616, 11486, 9656, 0, 0, 10727, 5615, 0, 120551, 42380, - 64895, 43693, 66451, 808, 5455, 11347, 0, 1026, 5620, 194887, 0, 11350, - 5617, 0, 9225, 64639, 127073, 9145, 128060, 1338, 120581, 983158, 12739, - 4603, 3084, 983155, 92484, 9858, 6037, 0, 3974, 78213, 10290, 983704, - 3083, 10322, 0, 0, 0, 41036, 0, 0, 43321, 65606, 0, 41032, 42388, 0, - 64700, 10011, 1445, 40961, 0, 119105, 0, 40960, 0, 194891, 0, 40963, - 64952, 10402, 0, 0, 92304, 10603, 0, 0, 983113, 0, 6714, 10083, 127069, - 194895, 78367, 127377, 0, 93963, 9073, 42585, 64302, 10704, 65030, 4787, - 0, 74829, 0, 65423, 0, 128118, 9570, 55260, 9525, 2689, 917626, 65426, 0, - 917624, 43740, 0, 40966, 917622, 13286, 3998, 42598, 42596, 503, 74237, - 8735, 2690, 66488, 42836, 127150, 41954, 917617, 1652, 772, 6688, 8310, - 65428, 3487, 43416, 3585, 10194, 43320, 119159, 128183, 194874, 6468, - 41976, 9720, 917606, 11767, 41970, 194596, 5836, 12358, 0, 4355, 9048, - 12180, 65027, 64680, 13038, 43699, 0, 41488, 128087, 8527, 194917, 12362, - 12435, 12360, 41053, 3266, 0, 12356, 8616, 41466, 0, 92588, 11450, 0, - 3638, 12354, 0, 3216, 0, 2358, 92606, 8633, 0, 983745, 119182, 69244, 0, - 0, 11759, 194903, 6368, 74823, 0, 41423, 8078, 10504, 127558, 41698, - 42237, 0, 7002, 983678, 41430, 42267, 41051, 41484, 0, 0, 41050, 41473, - 10466, 13099, 0, 0, 0, 6435, 0, 11362, 0, 0, 65382, 0, 41420, 0, 3625, - 78157, 41409, 0, 69639, 2041, 9178, 9672, 41427, 43541, 43317, 0, 0, 0, - 41424, 917598, 120546, 0, 128212, 0, 41417, 1261, 0, 0, 12102, 119662, - 41401, 0, 127538, 0, 78251, 0, 42290, 3275, 92472, 42329, 74759, 0, 0, 0, - 92388, 69649, 10989, 74234, 983140, 10598, 7410, 2669, 903, 0, 2920, 0, - 127232, 74603, 64504, 19928, 0, 0, 3917, 0, 11732, 0, 983180, 41448, - 41461, 128823, 0, 127912, 0, 8819, 12663, 0, 41184, 74014, 232, 74835, - 120646, 9168, 65786, 0, 0, 0, 9094, 0, 11758, 68425, 0, 1064, 42467, - 128044, 10115, 19924, 92711, 0, 7862, 64551, 13224, 8516, 41862, 66650, - 7561, 78618, 69793, 1878, 0, 983269, 2911, 0, 41178, 5427, 64823, 0, 0, - 3787, 41174, 0, 41458, 0, 41463, 42413, 11292, 2406, 775, 0, 65584, - 69923, 6074, 9618, 128668, 983952, 43440, 0, 194901, 41436, 3656, 0, - 120600, 41456, 0, 1599, 11333, 0, 6703, 8513, 0, 1613, 0, 68456, 12598, - 983191, 120734, 78745, 74500, 41460, 10145, 10542, 9937, 78746, 70029, - 9905, 0, 65730, 0, 120374, 8427, 120375, 55246, 120376, 0, 11497, 64687, - 74008, 42592, 3871, 0, 128305, 9111, 5741, 0, 194846, 120366, 119111, - 120745, 0, 120368, 0, 11648, 0, 194873, 120364, 41587, 120365, 0, 74322, - 42113, 0, 127155, 12172, 0, 74530, 65298, 65723, 194840, 73871, 65724, - 7928, 120354, 983095, 41595, 73730, 0, 42118, 73830, 66042, 10355, - 983110, 7875, 0, 41598, 3993, 0, 1545, 40971, 536, 128521, 43029, 0, 0, - 65173, 65286, 0, 0, 0, 0, 0, 0, 41375, 5402, 0, 0, 1687, 120503, 917817, - 0, 78194, 64326, 40969, 10526, 78753, 8323, 40968, 1339, 11731, 78756, 0, - 65460, 12242, 128513, 8020, 10843, 11554, 0, 0, 8266, 41006, 65722, 0, - 10710, 0, 118942, 67667, 64567, 119155, 195091, 0, 119636, 67857, 120687, - 0, 983066, 11755, 66305, 0, 0, 10917, 93979, 0, 11272, 2040, 41247, - 41326, 195060, 1741, 42370, 1227, 0, 0, 11413, 0, 0, 5283, 1586, 4978, 0, - 1984, 11830, 0, 92293, 40984, 128306, 9373, 0, 12916, 6284, 0, 41663, 0, - 0, 0, 9237, 9385, 41648, 0, 194580, 2299, 41666, 1830, 73783, 2056, - 41287, 92610, 0, 0, 42219, 128257, 0, 41987, 41676, 983059, 120823, - 983144, 41670, 0, 92590, 2796, 55291, 11683, 9902, 74521, 67988, 11451, - 983111, 128822, 42631, 2359, 0, 67844, 74164, 41238, 548, 11405, 13133, - 64368, 983239, 128795, 0, 397, 43622, 42139, 9547, 9590, 128238, 1614, - 43661, 64356, 66307, 6651, 1358, 0, 428, 9620, 1466, 78112, 10982, - 118831, 1333, 7104, 407, 6425, 128834, 74253, 0, 0, 0, 5804, 11976, 8554, - 92721, 0, 0, 9057, 42294, 41218, 0, 0, 78137, 1883, 10952, 8048, 78142, - 41225, 92621, 42915, 983676, 128684, 0, 4407, 0, 65809, 119074, 194821, - 8448, 7141, 74183, 0, 12675, 12659, 0, 42363, 120624, 194824, 55273, - 10766, 12012, 2386, 64732, 9170, 917821, 9123, 64585, 120500, 119158, - 7140, 10977, 127378, 4164, 9081, 0, 120569, 42049, 42042, 8709, 128283, - 126477, 120637, 42419, 64799, 42047, 0, 0, 8470, 11807, 65897, 577, 0, - 983760, 74300, 0, 127308, 74840, 0, 0, 128791, 92224, 8736, 1414, 42643, - 9683, 43486, 74344, 0, 2536, 0, 66330, 0, 0, 0, 0, 0, 0, 0, 66317, 69945, - 66315, 2106, 120222, 11273, 0, 43004, 7541, 0, 0, 961, 64307, 66324, - 64906, 128591, 3106, 65917, 41284, 1696, 0, 891, 12105, 0, 42624, 12802, - 3264, 8824, 13268, 43003, 10936, 0, 0, 0, 194826, 92688, 0, 2322, 120371, - 983584, 11449, 128187, 42868, 41285, 3547, 0, 0, 128793, 983398, 43216, - 6089, 78682, 0, 120578, 4170, 1029, 127761, 127036, 119224, 42374, 0, - 744, 0, 0, 0, 65823, 127826, 0, 3551, 0, 0, 4623, 55268, 0, 4598, 983162, - 65136, 127136, 0, 0, 10851, 0, 6179, 92602, 6180, 0, 11952, 120778, - 78648, 11972, 78646, 78647, 78644, 78645, 177, 78643, 6176, 120580, 0, 0, - 6177, 9020, 78652, 78653, 6178, 120249, 120242, 128027, 67673, 2214, - 8754, 0, 120237, 2137, 43081, 0, 0, 9136, 120240, 4401, 41280, 0, 8974, - 2308, 0, 74149, 0, 2318, 983183, 66361, 8198, 0, 64360, 12601, 42536, - 65266, 120827, 74307, 92462, 6970, 5404, 43332, 3667, 7936, 12925, - 126989, 6385, 0, 0, 118949, 10874, 65505, 128083, 0, 42053, 2075, 42057, - 11083, 42052, 0, 0, 67651, 0, 9665, 92300, 983666, 13181, 0, 0, 0, 70088, - 74148, 0, 0, 120225, 120229, 120224, 74172, 41145, 0, 94096, 983946, - 41148, 8683, 7594, 127519, 0, 119090, 10869, 43458, 41146, 92407, 11441, - 0, 3512, 119633, 983709, 8103, 0, 0, 65184, 11780, 41563, 42796, 0, - 69742, 41544, 65146, 0, 0, 0, 0, 19942, 0, 118908, 7988, 10436, 74273, - 3271, 73804, 64711, 0, 94064, 0, 0, 3804, 13070, 11557, 42044, 0, 1095, - 0, 3599, 127774, 0, 128861, 8514, 0, 0, 0, 74346, 66697, 0, 11684, 0, - 92486, 917603, 0, 42043, 43232, 66677, 0, 42046, 78241, 4036, 126481, 0, - 128213, 194861, 0, 11954, 93978, 1450, 12986, 1340, 0, 65441, 92722, 0, - 0, 127772, 0, 917542, 0, 0, 6539, 0, 0, 0, 194856, 0, 120492, 41190, - 3973, 119365, 4575, 41193, 7982, 429, 0, 127194, 0, 194854, 65792, 0, - 118968, 6417, 118918, 78178, 0, 194850, 0, 0, 4919, 10590, 128556, 7755, - 0, 0, 64548, 120506, 1621, 10214, 65126, 0, 127004, 0, 12188, 983668, - 1617, 8050, 0, 5015, 0, 119174, 42590, 194871, 1756, 78181, 0, 65768, - 6352, 41892, 0, 7555, 13103, 5408, 2817, 1214, 69919, 92335, 983125, 0, - 0, 0, 127195, 7957, 8689, 64723, 1056, 42896, 74147, 194813, 0, 55286, - 7073, 65850, 12327, 983948, 119028, 0, 0, 0, 2341, 8450, 8484, 8474, - 983260, 0, 70079, 8461, 128102, 12153, 12799, 0, 43709, 43708, 9451, - 7571, 13073, 0, 0, 681, 983252, 703, 0, 3272, 8781, 12894, 70077, 11709, - 92288, 74446, 0, 92532, 0, 11338, 120768, 3276, 0, 0, 65928, 0, 0, 65021, - 64795, 74574, 0, 10047, 78814, 3262, 78811, 42711, 0, 0, 68478, 163, 576, - 9895, 1655, 78817, 74591, 78815, 78816, 983122, 0, 0, 0, 10039, 0, - 983945, 5623, 5717, 5776, 0, 0, 0, 41591, 11036, 65252, 92382, 0, 0, 0, - 67848, 0, 0, 0, 8887, 127521, 7295, 11031, 0, 43157, 0, 8946, 10348, - 10412, 8755, 0, 0, 5718, 13221, 0, 0, 78135, 0, 983711, 8810, 74499, 686, - 0, 71362, 4619, 118954, 6654, 73769, 74426, 0, 12040, 65689, 10128, - 65118, 0, 119151, 74205, 92651, 0, 2401, 68144, 8792, 983648, 0, 65455, - 0, 92246, 0, 119129, 0, 12886, 127920, 66624, 0, 43557, 10300, 10161, - 10396, 74135, 983453, 118945, 78118, 73851, 3010, 6441, 78122, 1458, - 41475, 128672, 93975, 0, 11479, 0, 120356, 6350, 12864, 69674, 78114, - 1061, 64780, 2001, 43111, 55230, 128686, 4052, 0, 7626, 0, 0, 1045, 0, - 5631, 41113, 0, 0, 43707, 74127, 0, 0, 8486, 0, 73758, 2335, 4362, - 983195, 126561, 69221, 1025, 0, 42625, 917627, 78084, 41443, 0, 128206, - 0, 1774, 1523, 0, 0, 41445, 78236, 0, 8567, 41442, 3988, 0, 78237, - 118910, 0, 65274, 8564, 78199, 78238, 127515, 0, 0, 43446, 0, 66513, - 6256, 0, 579, 55218, 10206, 983075, 6375, 2673, 0, 11814, 0, 4488, 0, - 127336, 68451, 10444, 118846, 127334, 11799, 74407, 68466, 4487, 127849, - 42832, 1032, 120267, 43450, 78257, 7203, 0, 614, 78191, 127325, 120615, - 0, 78262, 128669, 127323, 0, 43121, 0, 0, 92513, 1050, 7549, 0, 0, 9314, - 0, 0, 120616, 0, 10057, 0, 127313, 0, 66504, 983171, 0, 2307, 0, 64333, - 127312, 128547, 73873, 0, 94035, 0, 127973, 128708, 0, 10360, 6746, 0, - 92245, 440, 0, 13085, 9233, 74216, 0, 0, 9957, 128285, 66447, 8046, - 64963, 65777, 10125, 74212, 42819, 10910, 0, 1521, 9896, 93965, 10487, - 69878, 12527, 0, 7970, 0, 128660, 0, 65769, 5243, 9849, 5239, 65771, - 983235, 0, 5237, 69714, 0, 10103, 5247, 4769, 0, 118977, 12873, 2283, - 983237, 0, 3008, 4896, 0, 12087, 0, 55231, 41103, 0, 64565, 4773, 0, - 92717, 70074, 4770, 0, 917567, 8731, 65378, 127362, 120619, 9122, 128033, - 126600, 4774, 3019, 9997, 12834, 0, 9456, 10215, 120547, 0, 0, 0, 0, - 74776, 4281, 4768, 0, 41535, 4099, 9017, 0, 0, 78095, 0, 78096, 0, 0, 0, - 78098, 0, 42814, 880, 0, 0, 128021, 2134, 0, 10116, 9877, 92329, 0, 0, - 7095, 0, 74116, 6778, 0, 78090, 8243, 2427, 128141, 7093, 0, 11585, - 195003, 9962, 0, 12223, 0, 0, 1434, 120254, 5637, 11573, 0, 0, 0, 19951, - 0, 78121, 0, 0, 55283, 0, 0, 74437, 1156, 8740, 92415, 3782, 64331, 0, - 41370, 1014, 8261, 0, 0, 10835, 0, 65536, 0, 120463, 0, 7702, 118824, 0, - 43010, 65779, 65783, 1150, 10547, 5700, 0, 120603, 65383, 2339, 42594, - 5697, 118788, 0, 128576, 0, 42257, 5696, 92677, 120465, 3862, 9643, 0, 0, - 7634, 65167, 9845, 0, 0, 5701, 9722, 41490, 983153, 1426, 68217, 0, - 68447, 42204, 55270, 8571, 194991, 78067, 0, 78818, 92719, 43182, 12184, - 0, 42022, 0, 10281, 0, 5650, 43194, 64712, 10744, 0, 990, 5647, 0, 7387, - 78734, 41114, 11477, 5646, 12879, 11018, 983930, 3945, 92589, 0, 0, 0, 0, - 78212, 127746, 1020, 73763, 0, 78731, 5648, 64748, 194910, 78733, 10205, - 3545, 983585, 6984, 0, 74051, 983655, 43242, 120458, 2667, 0, 0, 0, 9911, - 0, 65020, 10097, 119166, 127145, 983662, 118836, 983748, 78427, 1140, - 78426, 0, 10159, 0, 0, 8128, 0, 0, 917965, 1815, 19910, 890, 0, 3267, - 92291, 0, 10123, 0, 4410, 1041, 10576, 6354, 92581, 580, 74232, 0, - 128347, 0, 0, 0, 19938, 65906, 127819, 0, 0, 3298, 5375, 10142, 0, 8215, - 0, 6134, 41246, 64402, 0, 69899, 0, 0, 0, 41382, 0, 128653, 5173, 65348, - 527, 0, 0, 92612, 128250, 78797, 11915, 0, 0, 10072, 0, 42695, 2329, - 42250, 0, 128864, 69667, 12245, 1568, 94033, 0, 0, 128120, 0, 74328, - 92708, 74769, 0, 119087, 9069, 6144, 0, 0, 73822, 0, 128010, 64917, - 41521, 118934, 494, 13250, 0, 65098, 6364, 956, 0, 12830, 10462, 73740, - 73734, 0, 0, 0, 66449, 13263, 74281, 69217, 13171, 127796, 0, 0, 92294, - 0, 1044, 41276, 0, 0, 0, 42068, 11795, 0, 0, 0, 0, 42450, 3907, 0, 64526, - 11829, 68197, 12295, 0, 11475, 0, 3020, 11537, 0, 66441, 983454, 7098, 0, - 0, 1057, 566, 42696, 0, 3016, 42274, 43464, 66490, 12921, 66571, 78472, - 92510, 3006, 4620, 127237, 983578, 0, 0, 64659, 0, 127749, 55253, 6357, - 6362, 8626, 71337, 2216, 9090, 65377, 41596, 0, 42920, 1698, 0, 64477, 0, - 43813, 1053, 0, 78269, 0, 126586, 1052, 1051, 459, 1060, 74349, 66479, 0, - 0, 0, 0, 42490, 689, 6508, 4163, 42298, 8639, 66641, 4246, 0, 0, 12130, - 0, 42337, 64596, 64375, 66481, 127850, 0, 0, 6359, 0, 43471, 983768, 0, - 0, 127274, 0, 6358, 6361, 1926, 6356, 92627, 7898, 8110, 10935, 0, 10069, - 5830, 0, 43685, 0, 0, 0, 0, 8693, 78611, 119565, 983808, 120413, 0, - 127257, 65894, 0, 0, 0, 983923, 0, 0, 119187, 2135, 78868, 0, 0, 78869, - 42313, 5579, 92412, 0, 983082, 94002, 0, 5578, 41774, 128115, 42023, - 6234, 5669, 92275, 0, 0, 0, 127506, 68202, 5583, 0, 0, 42426, 5580, - 42276, 2923, 892, 2220, 42465, 41330, 194987, 5795, 65512, 119006, 65702, - 0, 120801, 65251, 0, 65710, 0, 0, 67672, 0, 5370, 0, 2931, 1638, 10966, - 10188, 65878, 118848, 0, 69694, 69879, 128830, 8172, 42017, 0, 10844, 0, - 128195, 92424, 6374, 0, 0, 286, 78023, 1062, 0, 119999, 0, 7395, 0, 1070, - 64900, 7153, 6095, 41865, 0, 3015, 128023, 126465, 5211, 983083, 6400, 0, - 194983, 70054, 8189, 11276, 0, 0, 372, 128829, 0, 118874, 42102, 41585, - 128202, 0, 42101, 276, 78402, 0, 33, 74226, 127303, 9007, 118796, 41588, - 66033, 427, 10763, 118819, 0, 127884, 0, 1031, 6257, 0, 42104, 0, 983980, - 2328, 92409, 1071, 42899, 0, 74848, 0, 983580, 0, 1047, 0, 0, 64790, 0, - 69723, 10651, 0, 0, 0, 0, 92206, 119181, 5711, 41633, 12098, 65571, 9166, - 0, 5710, 0, 6790, 65168, 13216, 0, 69716, 69726, 0, 64611, 41623, 195001, - 5715, 69654, 0, 0, 5712, 2761, 41620, 68124, 3074, 5722, 0, 8643, 73768, - 0, 118906, 2757, 11067, 9718, 74498, 8910, 10689, 6479, 0, 0, 0, 78607, - 9196, 69670, 0, 0, 0, 0, 118911, 0, 0, 0, 0, 0, 120010, 0, 8701, 68130, - 119616, 120522, 0, 42477, 194994, 12123, 4495, 43569, 0, 0, 0, 64946, - 10992, 0, 120009, 0, 0, 9318, 93986, 13249, 65679, 73808, 0, 65457, - 42249, 7639, 43995, 67845, 42641, 5454, 0, 0, 194997, 120005, 0, 983966, - 5084, 0, 0, 118861, 0, 733, 917876, 78014, 78436, 78435, 41677, 0, 9218, - 1731, 0, 983746, 0, 67990, 0, 0, 0, 120001, 127018, 92492, 5155, 120000, - 5358, 983744, 0, 917767, 64424, 983231, 3840, 64314, 41432, 0, 78315, - 68430, 67980, 43253, 65943, 0, 3371, 10988, 0, 8771, 1479, 0, 0, 1109, - 11580, 0, 64601, 12205, 0, 0, 64507, 8868, 399, 67978, 74842, 983284, - 983721, 12149, 13088, 551, 0, 10156, 12119, 92572, 0, 2544, 65074, - 119211, 0, 0, 78011, 351, 119149, 0, 0, 55229, 0, 74268, 0, 0, 0, 42377, - 0, 0, 0, 983924, 0, 9013, 4054, 0, 983570, 983628, 0, 73960, 5585, 65881, - 2549, 74469, 0, 0, 5584, 8358, 0, 64215, 92219, 10919, 0, 7980, 126601, - 983784, 2218, 41800, 5589, 0, 2664, 41613, 5586, 118890, 0, 11356, 0, 0, - 43452, 78609, 0, 42573, 67856, 0, 78129, 0, 0, 74392, 8135, 6450, 10055, - 77996, 0, 0, 119225, 5657, 0, 9626, 0, 77994, 10179, 5654, 12939, 92573, - 120799, 0, 0, 5652, 10945, 0, 66486, 0, 3661, 7863, 0, 0, 0, 74509, - 983852, 5659, 0, 78692, 66729, 5655, 983626, 42168, 0, 1055, 917628, - 127792, 66310, 74030, 0, 12146, 73955, 73956, 11618, 0, 126990, 0, 10272, - 10304, 10368, 42518, 594, 10244, 10248, 7407, 983887, 64870, 0, 3467, - 983891, 0, 3331, 946, 10231, 1495, 8131, 74330, 0, 9562, 69222, 65927, 0, - 70036, 69696, 69769, 64656, 983726, 0, 94020, 70056, 5666, 65227, 5318, - 63994, 0, 9091, 10798, 0, 128166, 10186, 0, 7732, 983724, 64556, 0, 0, - 5668, 74445, 0, 128663, 5670, 126610, 127297, 11820, 2992, 7826, 5667, - 19952, 120807, 0, 12749, 74551, 0, 0, 66496, 4361, 119260, 1306, 9286, - 1497, 128286, 94004, 0, 0, 3571, 13247, 0, 7973, 66353, 68435, 78278, - 67896, 43192, 0, 78265, 553, 120653, 0, 128554, 5829, 0, 4587, 78285, - 65912, 0, 12746, 0, 0, 119924, 5633, 119927, 94101, 94102, 94099, 64905, - 94105, 9512, 94103, 12742, 6443, 983806, 0, 9135, 0, 41564, 0, 55219, - 128832, 983851, 0, 12148, 0, 78297, 0, 64256, 0, 11669, 0, 5634, 4524, 0, - 127270, 0, 118880, 2425, 65182, 128769, 43636, 5221, 78410, 328, 0, - 983809, 69815, 5636, 0, 5329, 0, 5638, 119918, 7940, 64938, 43223, 43760, - 5635, 3373, 2986, 78292, 74223, 3437, 78291, 6203, 4247, 0, 11920, 8274, - 0, 0, 1657, 41561, 78299, 78295, 5639, 2954, 5660, 5640, 78303, 983685, - 78300, 42227, 0, 0, 41637, 67872, 0, 78310, 41625, 43362, 78309, 120713, - 11705, 5642, 0, 5486, 0, 4356, 11710, 0, 12051, 69938, 0, 5641, 8259, 0, - 1058, 0, 67630, 0, 0, 1144, 78750, 0, 42228, 0, 73890, 118972, 0, 2800, - 0, 5645, 64964, 8652, 2547, 66484, 43634, 0, 5608, 65890, 43808, 0, - 67621, 119934, 9000, 0, 0, 92673, 1865, 0, 5613, 69950, 0, 0, 5610, 0, 0, - 65826, 2069, 0, 10787, 43999, 2997, 0, 5609, 78316, 65319, 78313, 12316, - 65376, 2412, 0, 8186, 9807, 74269, 92547, 13130, 65874, 0, 5807, 0, - 10030, 5306, 12364, 128064, 0, 11704, 0, 92583, 10211, 0, 0, 0, 0, 11706, - 9710, 0, 0, 0, 413, 65623, 7118, 0, 9133, 74262, 0, 1042, 0, 64779, - 12171, 119240, 6185, 64776, 4984, 0, 708, 11391, 0, 12241, 92720, 983899, - 1308, 0, 2534, 810, 0, 0, 0, 0, 0, 1917, 3000, 0, 0, 120739, 2364, 92443, - 74470, 66618, 65680, 120779, 10027, 0, 128154, 12337, 120722, 127368, - 983167, 2980, 755, 69774, 931, 13124, 68182, 6363, 2748, 0, 0, 65041, - 92276, 44011, 8730, 983067, 127854, 78312, 7274, 119250, 0, 7275, 78304, - 935, 0, 65840, 377, 42325, 11649, 127363, 65253, 64301, 128835, 78308, - 42341, 65284, 2417, 0, 12884, 19912, 7907, 10768, 0, 194998, 0, 10673, - 119217, 7248, 0, 128346, 1781, 5496, 3627, 62, 1649, 0, 964, 0, 127876, - 78226, 128775, 127512, 0, 0, 0, 0, 43689, 127911, 13142, 78812, 42415, - 66575, 4542, 69909, 43547, 0, 0, 7677, 2991, 4946, 42454, 11565, 7949, 0, - 983918, 11341, 42494, 3073, 65625, 9714, 11692, 4657, 0, 92724, 6478, - 9898, 43673, 65237, 6241, 7106, 4877, 983795, 6238, 0, 10548, 127049, - 4409, 0, 0, 64798, 0, 5346, 0, 94047, 6237, 4874, 0, 9176, 0, 126553, - 65231, 65884, 12678, 78748, 118912, 11378, 44018, 42785, 2408, 3251, 0, - 0, 5685, 0, 2461, 11052, 7091, 5342, 8317, 0, 68163, 5340, 0, 127820, - 43635, 73928, 127529, 0, 0, 0, 128510, 65482, 0, 9142, 0, 126470, 0, - 10938, 0, 118790, 1182, 2542, 4826, 0, 0, 128176, 529, 8580, 0, 0, 10586, - 10790, 10839, 66023, 41593, 41207, 0, 0, 41594, 225, 42828, 0, 0, 983938, - 11376, 74379, 10721, 67664, 3438, 42097, 127267, 11084, 3194, 41870, 266, - 78305, 120183, 41873, 120575, 11324, 120531, 0, 8420, 64918, 128844, - 41871, 41338, 3734, 7734, 43683, 8750, 66605, 66011, 92514, 40965, - 127937, 0, 5161, 10572, 0, 0, 0, 64349, 7287, 42162, 127552, 0, 126605, - 11948, 69220, 12359, 43429, 41369, 1697, 12191, 0, 68633, 7286, 0, 68635, - 10031, 0, 9870, 68645, 8620, 65824, 0, 11938, 0, 7285, 0, 119577, 42678, - 0, 43677, 41583, 0, 65799, 92623, 0, 0, 983936, 78169, 66199, 0, 3609, - 68624, 0, 832, 120693, 120770, 78473, 66007, 78471, 65703, 0, 0, 42732, - 5180, 92699, 41395, 41530, 11691, 64773, 92214, 74002, 0, 0, 128645, - 6348, 243, 13200, 983813, 6024, 92309, 9979, 10037, 41529, 10648, 8538, - 43687, 0, 0, 4285, 66195, 0, 4230, 0, 7367, 43256, 92353, 7563, 42376, 0, - 68442, 120512, 0, 0, 214, 0, 0, 78466, 65893, 12208, 9973, 0, 66311, - 65589, 128277, 2603, 0, 0, 0, 70047, 0, 6022, 0, 2884, 0, 11620, 0, 43, - 0, 66453, 1016, 41107, 0, 41121, 3885, 92, 65456, 64608, 0, 74801, 0, - 2074, 0, 78283, 0, 12453, 128128, 983826, 74241, 126568, 6791, 12457, - 78268, 0, 0, 0, 78279, 0, 0, 92358, 66637, 7995, 8759, 43421, 78277, - 12449, 128552, 0, 0, 8752, 3197, 4720, 10165, 0, 119249, 0, 11595, 64893, - 0, 43435, 0, 0, 4993, 0, 6168, 10934, 1946, 741, 0, 5494, 4639, 983147, - 1990, 66589, 4498, 78664, 119183, 0, 0, 69734, 2960, 73779, 0, 8969, - 128117, 43424, 127059, 0, 2950, 119579, 6210, 65753, 370, 0, 0, 0, 4953, - 983682, 0, 0, 0, 69230, 0, 0, 65688, 983246, 5063, 3517, 2964, 43663, - 917762, 6344, 74791, 10566, 10144, 66333, 8252, 729, 66016, 78253, 0, - 71317, 64923, 128040, 43669, 9032, 78263, 78264, 0, 41215, 0, 65883, 0, - 917774, 120602, 3761, 0, 0, 70068, 0, 12912, 119012, 3850, 128191, 0, 0, - 0, 0, 908, 0, 8611, 0, 0, 127555, 43691, 41197, 0, 8978, 120540, 119135, - 41586, 10527, 0, 917848, 3848, 78739, 194937, 127536, 65241, 5336, - 983259, 128786, 663, 0, 10780, 0, 0, 78767, 983257, 127163, 68193, 347, - 0, 0, 78775, 64675, 41582, 78774, 78744, 65579, 12980, 78769, 12143, - 69657, 78512, 0, 43441, 41804, 78523, 0, 78525, 0, 128859, 41584, 10681, - 0, 983695, 73938, 0, 128022, 4800, 66661, 0, 66306, 64715, 78534, 9518, - 6609, 10434, 0, 11319, 1097, 0, 917850, 41730, 983214, 0, 73847, 78761, - 65172, 41728, 41721, 0, 0, 0, 41203, 917612, 13110, 41726, 983855, 0, - 1000, 69651, 0, 41140, 1209, 73978, 0, 73750, 1073, 6321, 77878, 41138, - 0, 68213, 0, 12167, 1115, 41605, 9794, 127062, 67671, 55248, 12237, - 78787, 66314, 6587, 9290, 78782, 78783, 9231, 78781, 2959, 7926, 0, 0, 0, - 64398, 0, 119970, 12311, 983727, 78796, 78798, 78794, 78795, 68434, - 78793, 66670, 0, 0, 12290, 120169, 0, 119873, 42142, 9968, 8205, 0, 5131, - 0, 9627, 78536, 78542, 78535, 983212, 1944, 1248, 10148, 127755, 119990, - 119991, 12701, 78376, 11308, 119995, 0, 119997, 119998, 65305, 65100, - 4031, 42794, 120003, 7075, 8154, 119985, 120007, 41817, 73934, 42275, - 120011, 120012, 78526, 120014, 120015, 6041, 0, 41899, 0, 8002, 0, 4364, - 0, 0, 64332, 0, 7813, 9064, 119986, 10124, 7526, 8601, 7281, 78455, 7279, - 12041, 1418, 10885, 12673, 0, 0, 9660, 983280, 13012, 4571, 0, 0, 120164, - 12078, 2970, 0, 10933, 0, 77870, 0, 127015, 0, 41599, 0, 128831, 0, - 12950, 92160, 3486, 0, 78311, 4239, 0, 127799, 66511, 0, 2637, 64629, - 8460, 127053, 8476, 983975, 0, 0, 0, 65673, 1019, 78495, 4148, 0, 12289, - 0, 4316, 0, 13119, 8488, 5412, 66243, 9935, 0, 73864, 983203, 41734, - 8206, 74081, 9163, 3286, 9072, 5867, 13302, 7622, 7120, 41736, 92546, - 41731, 0, 7400, 5416, 68663, 118924, 10817, 0, 41539, 127284, 0, 73963, - 41855, 41867, 65564, 11277, 65892, 11536, 10620, 92272, 7115, 66030, - 73932, 5498, 73942, 41536, 0, 68204, 92587, 3459, 8997, 0, 0, 0, 0, - 92512, 0, 66377, 69781, 0, 983699, 78511, 3161, 295, 120207, 0, 92223, - 127856, 78742, 9016, 43454, 63903, 63902, 43641, 0, 3971, 0, 70063, 2952, - 78765, 11038, 10901, 63900, 63899, 63898, 94043, 667, 12332, 63887, 6086, - 41722, 0, 5172, 0, 983278, 4159, 0, 0, 9815, 63884, 19934, 63882, 41198, - 8555, 63878, 63877, 42460, 6050, 42708, 63881, 63872, 0, 42421, 0, 41723, - 63875, 63874, 11460, 7432, 1913, 41913, 63852, 126636, 0, 42348, 73892, - 6752, 446, 41911, 127906, 63851, 63850, 41910, 0, 63846, 2972, 12932, - 7262, 0, 63849, 63848, 63847, 128070, 6570, 8302, 7259, 63842, 4178, - 10746, 7250, 13214, 10041, 8105, 63892, 0, 118983, 1105, 4180, 0, 12094, - 9497, 0, 63891, 63890, 63889, 63888, 5538, 9987, 0, 118932, 1678, 13274, - 552, 120654, 44010, 10785, 0, 119170, 4557, 74459, 9159, 10171, 13125, - 63860, 5540, 63858, 63865, 281, 13242, 63862, 74154, 0, 5536, 65568, - 63857, 1388, 74169, 0, 1077, 983577, 65099, 11531, 5834, 0, 0, 0, 0, - 42773, 0, 0, 0, 119220, 0, 3663, 0, 1112, 119122, 8686, 0, 5334, 65081, - 43249, 74778, 127968, 11077, 0, 6509, 0, 5327, 0, 19907, 63869, 3478, - 7583, 7679, 2903, 0, 3001, 1158, 8745, 43746, 73748, 63866, 78626, 1915, - 4846, 0, 66371, 118984, 42105, 2990, 120128, 805, 69238, 64438, 12070, - 8760, 1117, 118987, 12212, 120123, 65174, 42357, 63835, 63834, 0, 78240, - 12225, 63838, 63837, 983853, 983804, 63833, 6042, 66360, 8083, 0, 0, - 63821, 63820, 63819, 63818, 983904, 5227, 9047, 63822, 127162, 6091, 0, - 10691, 560, 5643, 8226, 119578, 63812, 63811, 63810, 63809, 2289, 63815, - 63814, 63813, 6047, 1597, 120143, 780, 206, 77925, 4936, 65147, 8168, - 63930, 2076, 1093, 9882, 63934, 2082, 63932, 128150, 63929, 3546, 1605, - 77934, 9806, 43472, 77933, 8400, 11343, 2086, 0, 63926, 2984, 5968, 9287, - 0, 4618, 42209, 43431, 13169, 5290, 2089, 1695, 10743, 1088, 63825, 7268, - 1084, 1085, 63829, 1083, 10131, 7283, 0, 63970, 128358, 1092, 4754, 7273, - 5252, 44016, 43627, 127921, 0, 7408, 11809, 917618, 0, 0, 2965, 7258, - 8808, 0, 1089, 4187, 63937, 42119, 42120, 0, 940, 5787, 10099, 63938, 0, - 74494, 12463, 2994, 0, 118827, 0, 9664, 77939, 77940, 67892, 77938, - 74343, 0, 0, 660, 10127, 666, 9022, 5532, 43667, 5533, 77941, 78507, - 6118, 222, 979, 3884, 0, 74151, 92652, 6502, 0, 127118, 128695, 63951, - 12465, 0, 0, 128782, 63946, 1707, 63924, 12461, 63950, 63897, 63948, - 63947, 63945, 6038, 63943, 63942, 64685, 63895, 65838, 2276, 7776, 94076, - 0, 127773, 120444, 69730, 801, 43165, 1690, 63919, 63918, 63917, 13277, - 43659, 12951, 120638, 9906, 2054, 2334, 78515, 63916, 5483, 63914, 69737, - 63911, 5484, 63909, 63908, 2539, 0, 43980, 5485, 0, 42697, 9061, 5534, - 10672, 4502, 0, 253, 0, 68208, 0, 9203, 74231, 0, 11530, 92542, 68668, 0, - 118907, 0, 10474, 43426, 13257, 42354, 128099, 983698, 70044, 195065, 0, - 8413, 983816, 0, 5693, 7272, 0, 13209, 64470, 65831, 74350, 195063, 0, 0, - 0, 126639, 120097, 0, 94078, 128133, 127767, 66608, 3111, 41863, 8804, - 42913, 92187, 7270, 0, 66606, 6628, 1076, 7433, 1436, 73844, 55226, - 128353, 63982, 7393, 12807, 43413, 63906, 1598, 63904, 0, 0, 41729, 4423, - 1307, 0, 10515, 41589, 128698, 0, 6218, 0, 1430, 0, 0, 120606, 78754, - 5413, 7619, 3255, 3493, 74032, 11549, 10735, 41743, 73937, 6801, 983633, - 4518, 10990, 65073, 5167, 4481, 3771, 120158, 2710, 0, 69243, 41724, 0, - 43073, 41690, 12479, 983635, 0, 0, 983818, 70046, 1628, 127149, 983487, - 983731, 65262, 6333, 10783, 42315, 0, 63855, 94056, 0, 0, 5339, 74323, 0, - 13004, 0, 4457, 0, 0, 194818, 0, 5684, 8678, 10914, 0, 5689, 65807, 0, - 68464, 12633, 12870, 69705, 65183, 5688, 11926, 6033, 6310, 5686, 0, - 74251, 0, 120647, 0, 50, 10558, 9871, 42612, 43655, 0, 0, 0, 66468, 0, - 13259, 4448, 0, 983845, 0, 70043, 67853, 0, 10640, 11539, 1151, 0, - 917607, 127544, 127079, 195050, 127852, 0, 0, 0, 12501, 64604, 0, 11527, - 118870, 8812, 0, 11538, 8673, 12650, 11020, 0, 66467, 2105, 8087, 78163, - 69632, 9894, 0, 0, 0, 4636, 55262, 78513, 4515, 2382, 0, 127055, 0, - 120495, 0, 128284, 12277, 194627, 11995, 92553, 0, 12158, 0, 8741, 10197, - 0, 92426, 0, 6531, 0, 127846, 473, 43415, 0, 983650, 1873, 1087, 0, 0, 0, - 78527, 66439, 43218, 983123, 194716, 7237, 12504, 74282, 0, 983571, 0, - 9489, 0, 0, 4384, 74220, 63845, 2058, 128863, 13295, 43191, 128030, 0, - 1154, 3857, 1205, 0, 0, 13100, 12958, 120706, 74168, 0, 0, 4421, 10592, - 0, 495, 119007, 41712, 7983, 0, 93997, 0, 6347, 120165, 7654, 41710, - 4196, 0, 437, 41709, 73772, 0, 0, 9465, 13290, 119180, 4997, 64306, 0, 0, - 4999, 194642, 0, 126582, 4711, 120769, 0, 2739, 0, 8044, 74834, 194643, - 41789, 128142, 10809, 0, 0, 0, 1779, 6600, 6601, 41543, 5325, 642, 64187, - 13058, 120449, 12875, 0, 92186, 13229, 0, 10575, 43399, 0, 0, 41791, - 1104, 0, 0, 10655, 0, 0, 0, 0, 1082, 195049, 8428, 6569, 0, 0, 0, 69849, - 6783, 0, 12993, 8049, 41548, 44021, 6458, 983807, 128882, 4761, 63828, - 4766, 64623, 1273, 43407, 0, 118876, 195045, 6912, 1313, 6322, 10483, - 983603, 41545, 0, 92449, 0, 0, 0, 0, 78624, 3484, 74337, 0, 0, 8503, - 5122, 41527, 0, 66320, 983811, 0, 0, 0, 41537, 69683, 8303, 8282, 11817, - 73857, 10003, 73859, 65904, 7363, 1686, 0, 78406, 11467, 3664, 65921, - 64299, 194664, 0, 0, 4324, 126, 42246, 119152, 0, 74378, 65926, 7744, - 194636, 74277, 74302, 78052, 43817, 6966, 43822, 8136, 0, 65600, 1633, 0, - 0, 4762, 1103, 0, 0, 4765, 983492, 13078, 0, 4760, 63827, 2050, 10871, - 43199, 1102, 0, 42236, 128867, 194667, 11546, 74794, 337, 0, 42591, 8627, - 12279, 1111, 0, 92161, 4707, 68206, 10143, 7883, 127081, 7880, 4522, - 8645, 5704, 13010, 0, 8304, 917561, 0, 119575, 2293, 0, 66654, 0, 92676, - 0, 13008, 0, 4385, 0, 13011, 0, 92569, 119161, 13009, 160, 2677, 0, 0, - 41793, 65763, 74221, 120141, 41792, 42770, 94054, 65762, 118829, 43821, - 5709, 0, 94053, 43816, 0, 0, 1079, 3867, 5708, 0, 0, 43797, 5706, 64768, - 5705, 8791, 4005, 0, 10237, 10991, 128816, 43459, 9173, 917581, 917580, - 13170, 12540, 917577, 42605, 120765, 126617, 68647, 917572, 10058, 0, - 74867, 194654, 127078, 3339, 11448, 1106, 917591, 917590, 917593, 3340, - 917587, 917586, 917589, 917588, 120541, 10605, 1309, 63966, 120743, 1754, - 92226, 13246, 864, 0, 118926, 8972, 0, 7849, 120092, 92533, 13240, - 195068, 5192, 4338, 67982, 10948, 917601, 13199, 92575, 1236, 13208, - 13261, 13189, 13188, 93993, 0, 7440, 0, 120153, 9553, 1590, 63777, 63776, - 13178, 63782, 63781, 63780, 63779, 1583, 0, 13260, 4550, 0, 64205, 0, 0, - 41522, 983915, 92168, 983772, 917858, 11354, 94071, 0, 42795, 0, 119195, + 73982, 120518, 83473, 195086, 43369, 983177, 128140, 68415, 77861, 4538, + 93978, 43141, 983769, 82976, 74214, 73886, 67709, 917599, 71918, 43005, + 71114, 9552, 0, 70129, 129173, 12997, 83477, 0, 128897, 195030, 2381, + 12883, 10994, 10529, 41906, 0, 74618, 0, 12425, 10661, 10856, 9614, 2428, + 41478, 8582, 10064, 73930, 82977, 70437, 121251, 64896, 119162, 1952, + 92181, 8455, 10082, 11575, 128450, 119566, 128093, 12808, 12183, 6145, + 75020, 64929, 74985, 71916, 74984, 43186, 42509, 0, 3922, 9187, 83277, + 83278, 10191, 83271, 11752, 3353, 9358, 983462, 71366, 66680, 120090, + 8248, 7931, 8558, 9795, 68380, 120047, 983056, 83470, 120081, 119052, + 41027, 120086, 71449, 120088, 7366, 7019, 70378, 0, 11751, 120078, 78294, + 64657, 8657, 83472, 8594, 120068, 0, 983789, 120069, 120072, 120071, 0, + 113711, 43154, 41029, 119956, 11332, 65380, 7728, 94077, 11294, 0, 66665, + 7851, 0, 8375, 8699, 127949, 42524, 68419, 9085, 94041, 7504, 9327, 6160, + 73842, 983864, 194929, 8088, 128937, 74012, 66562, 0, 4439, 6926, 72423, + 12924, 128227, 42369, 4350, 65491, 65145, 9041, 43559, 64577, 10826, + 127476, 11296, 983285, 983409, 0, 65825, 9577, 68199, 983393, 64670, + 983121, 78056, 6793, 11295, 70409, 78053, 73872, 78055, 119993, 10902, 0, + 0, 78070, 11200, 10472, 2995, 121438, 120138, 64682, 2371, 78069, 118893, + 259, 1009, 70405, 2402, 2333, 6440, 194741, 113757, 65125, 41244, 70407, + 13271, 9103, 2278, 983146, 194728, 129120, 0, 10219, 74968, 194740, 0, + 67718, 43178, 127070, 41261, 119362, 43640, 8613, 0, 94049, 6736, 83439, + 41492, 12005, 69927, 127068, 1890, 120056, 0, 83443, 0, 7293, 7991, + 74052, 10578, 121141, 78076, 128620, 67368, 69928, 71850, 78800, 92653, + 64445, 42668, 6635, 128308, 6164, 65170, 74936, 121182, 7676, 11664, 0, + 93025, 69707, 93022, 118812, 0, 71096, 128045, 9175, 11925, 78045, 9088, + 119145, 64545, 1396, 120664, 7546, 3847, 71088, 93037, 4985, 13288, 672, + 8098, 43196, 194746, 120723, 128126, 42655, 74043, 65072, 1577, 11772, + 13041, 5928, 4525, 10658, 65911, 1266, 10180, 194711, 128371, 12622, + 127234, 124948, 0, 121214, 127139, 13310, 773, 19933, 1539, 0, 74969, + 42731, 67972, 74970, 71066, 983200, 3051, 5862, 7823, 92478, 92746, + 120411, 3250, 43991, 69687, 66649, 9510, 66237, 983304, 0, 41066, 64673, + 917963, 92381, 128636, 3505, 8707, 74925, 6725, 120802, 121296, 75041, + 3471, 66391, 5479, 882, 6686, 119584, 11613, 120772, 42754, 74608, + 125029, 83433, 121237, 120845, 0, 83431, 3225, 917996, 4433, 41156, + 43973, 43173, 1443, 4381, 0, 983642, 10926, 11756, 11757, 64879, 121106, + 42654, 127848, 13227, 120320, 10021, 5160, 1387, 0, 92644, 41418, 128933, + 65914, 6721, 217, 917955, 917960, 121082, 10443, 10789, 41158, 119257, + 4274, 11143, 41483, 0, 41250, 128904, 42179, 128375, 5931, 11744, 11215, + 74446, 41252, 66682, 0, 119637, 41249, 1366, 64635, 65047, 12466, 983458, + 120813, 4397, 128037, 128336, 41296, 9545, 41291, 120893, 0, 41485, 3511, + 41282, 5923, 10400, 0, 120493, 760, 0, 12088, 5786, 68252, 42256, 119869, + 67145, 417, 41474, 119562, 41565, 74965, 5934, 74572, 66583, 74904, + 64877, 2284, 64481, 78614, 66013, 41956, 43455, 67240, 194656, 0, 0, + 42273, 5819, 0, 128056, 0, 119129, 983100, 65910, 127747, 10246, 120816, + 65785, 1237, 10274, 4552, 119576, 128287, 0, 1375, 66705, 43573, 65260, + 3329, 0, 42811, 10312, 69845, 120794, 7840, 0, 43630, 10252, 119242, + 128104, 43185, 0, 4396, 195051, 119880, 10769, 9676, 119041, 0, 9753, + 92762, 8944, 983164, 0, 10473, 983823, 120472, 6072, 43025, 10299, + 128436, 68845, 120608, 66326, 67412, 92952, 0, 43811, 9330, 120596, 7222, + 10283, 10315, 10379, 4996, 127902, 13281, 66517, 7865, 10087, 78343, + 74938, 43324, 0, 0, 7565, 66363, 12952, 64806, 43180, 74967, 7414, 77929, + 43982, 74288, 622, 74023, 885, 43405, 1602, 0, 983731, 852, 0, 12160, + 83491, 10212, 65435, 129092, 12071, 9609, 12156, 917983, 917984, 43586, + 11035, 10411, 917988, 10255, 6710, 10279, 4194, 10375, 43853, 128599, + 4315, 12644, 83490, 77937, 43639, 43343, 67408, 128945, 11501, 41177, + 121180, 128866, 43431, 127097, 92413, 8715, 0, 41179, 983358, 43313, + 120230, 41176, 128780, 994, 983045, 8452, 77973, 73966, 66890, 70812, + 5921, 0, 2597, 92423, 5922, 118903, 66873, 4186, 92531, 119967, 127105, + 6718, 127029, 4406, 74601, 8480, 9192, 9747, 121040, 4413, 92196, 42268, + 3198, 5924, 5920, 92469, 6921, 78081, 74007, 42869, 8418, 11681, 43169, + 10176, 0, 742, 74881, 2893, 10772, 65276, 5937, 1914, 2553, 11682, 6756, + 125104, 121126, 8363, 0, 2993, 7772, 3916, 4301, 120494, 1141, 42407, + 7417, 718, 7572, 973, 119599, 120718, 3235, 2415, 43164, 0, 8018, 42333, + 74756, 10675, 6937, 42486, 43381, 65390, 10067, 120849, 1202, 0, 983910, + 65863, 0, 68484, 94013, 78182, 64542, 3260, 73829, 65388, 9945, 8419, + 78042, 6738, 0, 43681, 69728, 2059, 92422, 0, 55237, 1431, 119194, 66565, + 10821, 0, 12804, 128076, 8229, 1235, 3307, 11472, 78089, 78184, 4544, + 71228, 917982, 129188, 1740, 78097, 8758, 985, 12872, 64511, 78094, + 12068, 78102, 71226, 10141, 74922, 63761, 8785, 4476, 65071, 63763, + 12655, 8907, 9147, 78106, 78103, 78104, 120898, 119572, 10665, 64616, + 41572, 127979, 127160, 983554, 41573, 83160, 3931, 120295, 74143, 83156, + 83157, 83158, 78460, 11982, 0, 83067, 128381, 92712, 64484, 119266, + 41167, 0, 41735, 94019, 717, 10754, 83168, 83169, 72413, 83163, 63767, + 83165, 1780, 6936, 0, 83161, 819, 10611, 9694, 126978, 71474, 0, 127871, + 129069, 8343, 8342, 8345, 8344, 6578, 7009, 7523, 6922, 8348, 8347, 7525, + 3346, 8339, 128165, 128208, 575, 268, 78111, 8563, 5754, 120343, 41541, + 65565, 8336, 5936, 7290, 78117, 8337, 8341, 308, 11388, 7522, 83151, + 78123, 65466, 11090, 6953, 0, 83375, 74973, 78132, 5926, 68250, 78130, + 78126, 78127, 78124, 78125, 9038, 7887, 43456, 7830, 11651, 13093, 64002, + 983559, 65742, 12874, 119597, 11590, 0, 74048, 67379, 8595, 9835, 917947, + 43703, 13097, 0, 64643, 13283, 12697, 74975, 12381, 3488, 5933, 10033, + 71101, 66241, 65570, 119154, 12297, 71212, 1955, 127970, 5349, 42538, 0, + 124932, 7411, 9462, 128150, 0, 128465, 43920, 42736, 121017, 5756, + 128324, 7638, 41642, 42764, 983717, 43109, 7637, 5752, 11213, 83481, + 73832, 128827, 83486, 128231, 78334, 917957, 7636, 65171, 9124, 983210, + 78892, 120798, 291, 0, 983221, 2027, 66230, 10080, 78136, 10403, 70869, + 4640, 64713, 10224, 120429, 11183, 120431, 120430, 0, 128351, 127489, + 127138, 0, 92499, 0, 119094, 74213, 7824, 0, 194648, 41274, 5778, 6302, + 121432, 0, 12680, 119130, 1417, 67242, 93041, 9452, 128153, 74393, 11552, + 0, 127855, 128217, 65391, 128614, 10172, 65453, 63789, 41264, 78658, + 6426, 4641, 9179, 64819, 55278, 41255, 42036, 41469, 41269, 120412, + 41267, 4646, 67759, 865, 42034, 78274, 78273, 4645, 42033, 78270, 127982, + 983172, 43948, 195100, 68840, 78674, 1659, 919, 42784, 1671, 127892, + 6069, 9219, 128558, 1661, 13120, 63784, 69819, 10140, 9713, 119143, 0, + 71462, 94050, 2306, 10485, 118943, 6068, 10612, 195099, 119567, 67705, + 92561, 41462, 120470, 195079, 5422, 128234, 983629, 128611, 83474, 10229, + 10635, 826, 83475, 195082, 127003, 195084, 71455, 6483, 92211, 1808, + 7848, 113788, 8100, 78227, 71198, 78670, 13301, 78667, 9667, 78665, + 67704, 983921, 11003, 9904, 83410, 983919, 120690, 9144, 10921, 92992, + 78680, 9840, 65131, 78678, 71092, 10313, 83408, 83500, 64320, 10265, + 67252, 10962, 66904, 43008, 8945, 78683, 120995, 41, 195072, 1792, + 120515, 195073, 8655, 68254, 92544, 77951, 12066, 67258, 385, 4152, 2585, + 127804, 119068, 3126, 917852, 73983, 10957, 127037, 11160, 119116, + 127873, 13157, 0, 128024, 3570, 129187, 7443, 118804, 44006, 6997, 68004, + 126631, 7879, 8739, 11075, 917971, 65216, 70196, 69795, 2593, 8463, 7810, + 128543, 7839, 92612, 78806, 75064, 9691, 4411, 78802, 121219, 120854, + 43442, 69851, 65254, 10066, 983889, 72419, 0, 0, 13061, 8016, 78687, + 19932, 64831, 0, 113684, 12390, 119171, 1634, 68115, 65070, 11056, + 983574, 119925, 983099, 41165, 11328, 12450, 983811, 41166, 0, 12456, + 119914, 171, 5941, 12452, 194709, 12458, 12531, 78779, 43013, 63800, + 74162, 119320, 120483, 9969, 120767, 12454, 63806, 42132, 12063, 78425, + 78424, 3230, 68773, 983497, 75025, 5209, 297, 5810, 8522, 8415, 119937, + 78429, 78428, 7077, 2497, 128651, 960, 74156, 6981, 92374, 12938, 4292, + 78893, 74815, 10512, 0, 74814, 78875, 127505, 78876, 2503, 73778, 1762, + 69794, 2495, 74911, 5844, 68031, 118838, 127947, 12654, 4663, 1899, + 78877, 2507, 64121, 8726, 65594, 92972, 0, 119000, 8892, 78872, 92339, + 71232, 983073, 5782, 420, 127348, 917871, 43796, 10797, 63794, 0, 128533, + 64814, 63796, 43861, 0, 66581, 119204, 41608, 128479, 121144, 63792, + 4659, 120788, 77971, 43676, 74944, 69673, 121029, 11129, 92929, 329, + 77968, 92707, 83496, 7399, 0, 41188, 13244, 67692, 42167, 7435, 78193, + 5380, 119086, 69225, 1155, 11365, 43126, 77972, 0, 65684, 0, 5601, 65192, + 42765, 63752, 0, 7987, 69676, 1172, 69799, 6786, 43601, 120476, 74126, + 5603, 0, 4473, 121085, 72426, 124947, 65347, 65346, 65345, 128548, + 119213, 5347, 69802, 917973, 73868, 70852, 10588, 0, 0, 63755, 128271, + 5343, 78422, 120661, 4555, 5341, 83459, 70071, 74916, 5351, 78675, 43104, + 65244, 121365, 64541, 42519, 68134, 128916, 126986, 74765, 128979, + 127510, 6638, 0, 65113, 271, 74180, 65370, 8835, 65368, 12653, 65366, + 42172, 41086, 65363, 65362, 65361, 11912, 43410, 11323, 65357, 11800, + 65355, 5345, 11103, 65352, 65351, 761, 65349, 19959, 69718, 63856, + 126635, 2423, 74518, 64647, 77959, 11957, 4699, 126573, 128670, 983787, + 0, 64605, 0, 68074, 983977, 4916, 128568, 380, 10958, 66563, 77955, + 69773, 9773, 13167, 12918, 41096, 73980, 69245, 78254, 83450, 10684, 0, + 125063, 92906, 7946, 12541, 8182, 67586, 69780, 0, 128207, 0, 983654, + 9005, 1225, 6630, 0, 0, 118854, 68011, 8847, 92371, 65876, 5535, 8329, + 74590, 125036, 92609, 0, 66874, 3127, 2595, 65713, 42013, 121211, 5607, + 41089, 128626, 0, 70292, 2665, 11304, 43751, 74200, 4970, 8764, 120459, + 8934, 92726, 41566, 4492, 67271, 65011, 41090, 0, 83417, 1188, 7254, + 1100, 0, 67270, 41081, 2912, 11749, 67282, 67281, 67280, 3572, 10023, + 4959, 13079, 0, 67275, 9729, 125110, 121042, 67278, 43361, 127355, 67276, + 11803, 7996, 9907, 41450, 13304, 83392, 83369, 41451, 83370, 11095, 8273, + 74322, 3451, 70291, 972, 41453, 68164, 119327, 73883, 68022, 73945, + 83363, 2288, 19955, 9538, 83366, 69807, 0, 129095, 0, 83381, 11396, + 83385, 11019, 0, 128416, 121205, 68020, 41078, 71365, 261, 5927, 7791, + 128681, 7362, 0, 10696, 70124, 6073, 9838, 118920, 0, 6075, 93995, 282, + 119178, 6437, 68830, 121459, 9801, 66399, 74177, 0, 917959, 3474, 67287, + 0, 67286, 6081, 83469, 78874, 67289, 67283, 83471, 70002, 42930, 0, + 93013, 8751, 11499, 67297, 7816, 12636, 4665, 12628, 4670, 67298, 120272, + 68017, 9642, 10912, 958, 67293, 11387, 67291, 4666, 70792, 4915, 67715, + 4669, 0, 68099, 13287, 4664, 10836, 120550, 75053, 69775, 0, 43595, 7450, + 0, 917875, 8664, 9697, 3606, 83446, 983978, 917874, 64815, 1063, 120250, + 67312, 9772, 7255, 8886, 1389, 127932, 120257, 120258, 120259, 12941, + 42661, 83438, 120255, 120256, 12301, 67836, 69820, 41102, 64428, 120262, + 66602, 120264, 1017, 66600, 523, 505, 1447, 74436, 0, 70340, 83437, 8608, + 42789, 120613, 83436, 0, 71906, 11307, 66707, 67301, 67300, 11745, 7919, + 67304, 1641, 0, 0, 8966, 128900, 74919, 5908, 71870, 67853, 6744, 67310, + 1699, 67308, 67307, 67314, 67313, 6306, 10169, 71324, 119251, 10068, + 3766, 2389, 67305, 120455, 6611, 257, 43170, 13153, 0, 42386, 983815, + 9436, 2599, 0, 6496, 9449, 5930, 11476, 11033, 11447, 10541, 5622, + 120436, 8477, 3760, 1718, 9442, 66433, 3776, 917837, 41435, 4352, 67324, + 2435, 71211, 5621, 120385, 4201, 3778, 4203, 4202, 4205, 4204, 120447, + 3768, 41774, 765, 41440, 3764, 8473, 6373, 8469, 120438, 12947, 4564, + 119049, 74623, 74271, 73753, 8374, 127201, 0, 6829, 5225, 66901, 127385, + 0, 0, 119615, 67319, 67318, 3162, 43507, 11771, 67322, 67321, 67320, + 42614, 5353, 5625, 74179, 67315, 0, 1010, 64572, 41780, 42623, 64277, + 69942, 6952, 67329, 67328, 67327, 2590, 5629, 65552, 7551, 10325, 5632, + 10471, 120038, 120027, 120028, 120025, 5628, 120031, 970, 120029, 4772, + 2400, 5627, 120017, 67330, 120023, 64275, 120021, 8786, 113693, 203, + 74365, 0, 0, 69985, 78350, 113703, 64378, 42054, 128575, 0, 554, 119649, + 11358, 71172, 12182, 42048, 11065, 125114, 73891, 83423, 83019, 5694, + 7689, 69798, 9323, 4325, 3047, 10317, 175, 120962, 93029, 69764, 0, 0, + 1243, 42154, 5431, 6652, 917561, 67753, 43651, 129129, 68118, 68093, + 1129, 126574, 0, 65900, 1986, 7846, 78804, 8661, 75058, 65255, 93992, + 3845, 4490, 118969, 6649, 74136, 1456, 7530, 11977, 7249, 8366, 0, 7756, + 12342, 120697, 51, 41516, 0, 8570, 9568, 71318, 456, 7026, 8145, 1168, + 9251, 9082, 119964, 64055, 42781, 3866, 12323, 41512, 73805, 68121, + 917850, 41494, 92316, 4660, 67114, 10405, 127195, 78803, 0, 129176, + 42040, 73918, 119627, 7944, 41454, 12605, 0, 42205, 41455, 236, 64051, + 78867, 8214, 83421, 113784, 120037, 41457, 983970, 119589, 1969, 2384, + 8097, 128019, 7413, 68012, 78029, 8766, 43864, 78079, 5854, 125000, + 10583, 0, 119989, 127556, 10416, 68070, 3872, 83424, 983839, 8429, + 121230, 118806, 2838, 6429, 0, 83426, 0, 128478, 0, 194620, 94005, 11096, + 83422, 10553, 1662, 8483, 120396, 43605, 5892, 43418, 67819, 73742, 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, 119862, 10357, 7385, 8170, 1704, 8556, + 917975, 9659, 0, 0, 0, 9556, 0, 4503, 11353, 9647, 125015, 78185, 128959, + 0, 71437, 78886, 0, 0, 74229, 66593, 6438, 83364, 9109, 78882, 1289, + 64599, 118915, 68009, 128302, 65507, 2447, 119911, 128694, 128042, + 126545, 66589, 0, 6334, 128369, 0, 19937, 917793, 1322, 92359, 5675, 254, + 0, 0, 69686, 42425, 8918, 64003, 5716, 42312, 0, 194692, 6972, 42826, + 74409, 42464, 120567, 66899, 67155, 74796, 64400, 64693, 128805, 67687, + 65429, 9515, 4435, 0, 42522, 0, 68008, 11785, 7412, 43867, 41978, 1412, + 4594, 1391, 10536, 8067, 9901, 7103, 128293, 7102, 71428, 120748, 3140, + 127276, 7960, 43271, 121099, 12518, 10909, 127508, 1428, 12472, 67254, + 67253, 7699, 12393, 67257, 0, 67256, 67255, 8223, 0, 4261, 121460, + 120910, 74308, 983827, 113712, 67153, 983571, 128046, 43419, 983471, + 64554, 10574, 3878, 67691, 42352, 1752, 73785, 128171, 42506, 128541, + 10199, 917865, 125142, 68021, 65919, 0, 6695, 720, 324, 0, 129035, 43406, + 983736, 1464, 40985, 0, 7974, 0, 43474, 68082, 64488, 128977, 120951, + 64041, 74787, 0, 78865, 92258, 65597, 121416, 78863, 0, 1302, 66288, + 78861, 119134, 0, 67152, 5204, 74774, 43404, 11835, 120923, 3995, 68360, + 65608, 3714, 92190, 120026, 67262, 10999, 11750, 67259, 43251, 67264, + 43301, 0, 120557, 8130, 8672, 10845, 11964, 121268, 128014, 92173, 0, + 68455, 42863, 73839, 127529, 0, 67700, 917812, 113701, 43645, 468, 612, + 0, 64401, 66448, 68376, 0, 1674, 0, 5823, 128625, 12280, 70367, 540, + 74564, 119017, 66422, 8432, 78873, 11073, 0, 64316, 0, 121070, 820, + 41741, 983477, 120667, 124981, 64684, 126992, 3359, 7800, 69934, 65177, + 6226, 353, 12396, 121176, 119612, 64742, 128682, 78879, 983478, 127938, + 12412, 19941, 0, 120277, 70352, 1884, 9481, 42418, 70059, 41157, 983142, + 1195, 64898, 7924, 119870, 41151, 2010, 71430, 41328, 42344, 0, 12409, 0, + 4360, 121023, 9739, 128550, 69933, 73921, 917631, 42521, 8539, 128606, 0, + 118986, 127148, 4788, 121345, 68023, 65734, 983457, 43790, 120274, 13075, + 74429, 94063, 64569, 43532, 10837, 2492, 127197, 118901, 68637, 41136, + 43785, 11813, 9649, 41154, 113731, 5128, 4038, 41143, 65604, 64859, + 41592, 6771, 1648, 5435, 67295, 6734, 41343, 119848, 65439, 12709, 6986, + 92364, 68015, 120533, 41349, 70021, 12581, 10374, 5175, 0, 73806, 10254, + 113681, 10278, 10262, 69858, 41346, 120870, 607, 0, 68182, 128846, 12923, + 10314, 10282, 65477, 10378, 120297, 40976, 8265, 129149, 78639, 40975, + 5840, 42838, 74987, 40978, 121386, 92945, 128020, 119809, 0, 66444, + 10538, 120810, 2550, 119836, 6779, 129130, 0, 3525, 6824, 118886, 983582, + 0, 5619, 65822, 113751, 113738, 7455, 71424, 5616, 11486, 9656, 0, 0, + 10727, 5615, 120873, 120551, 42380, 64895, 43693, 66451, 808, 5455, + 11347, 0, 1026, 5620, 194887, 0, 11350, 5617, 0, 9225, 64639, 127073, + 9145, 128060, 1338, 120581, 983158, 12739, 4603, 3084, 70408, 92484, + 9858, 6037, 983465, 3974, 78213, 10290, 983704, 3083, 10322, 129048, + 129030, 75038, 41036, 66897, 0, 43321, 65606, 127071, 41032, 42388, 0, + 64700, 10011, 1445, 40961, 0, 119105, 0, 40960, 194907, 67727, 125106, + 2223, 64952, 10402, 128358, 125049, 92304, 10603, 0, 983403, 71438, 0, + 6714, 10083, 127069, 121019, 78367, 69976, 0, 43872, 9073, 42585, 64302, + 10704, 65030, 4787, 129031, 74829, 0, 65423, 121306, 128118, 9570, 55260, + 9525, 2689, 917626, 65426, 194872, 917624, 43740, 121163, 40966, 120009, + 13286, 3998, 42598, 42596, 503, 71433, 8735, 2690, 66488, 42836, 127150, + 41954, 917615, 1652, 772, 6688, 8310, 65428, 3487, 43416, 3585, 10194, + 43320, 119159, 73955, 92315, 6468, 41976, 9720, 74964, 11179, 41970, + 66255, 5836, 12358, 0, 4355, 9048, 12180, 65027, 64680, 13038, 43699, 0, + 41488, 128087, 8527, 194917, 12362, 12435, 12360, 41053, 3266, 0, 12356, + 8616, 41466, 42924, 2227, 11450, 983691, 3638, 12354, 67299, 3216, 83099, + 2358, 83092, 8633, 71201, 983745, 119182, 69244, 83090, 70375, 11759, + 194903, 6368, 74823, 67303, 41423, 8078, 10504, 83104, 41698, 42237, + 983454, 7002, 83101, 41430, 42267, 41051, 41484, 0, 71467, 41050, 41473, + 10466, 13099, 71445, 70371, 120897, 6435, 74331, 11362, 128973, 83088, + 65382, 92770, 41420, 83083, 3625, 74915, 41409, 71441, 69639, 2041, 9178, + 9672, 41427, 43541, 43317, 74924, 0, 128557, 41424, 917598, 120546, 0, + 128212, 0, 41417, 1261, 0, 0, 12102, 119662, 41401, 0, 127538, 0, 78251, + 124943, 42290, 3275, 92472, 42329, 68850, 74901, 0, 127951, 92388, 69649, + 10989, 74234, 113781, 10598, 7410, 2669, 903, 0, 2920, 0, 127232, 74603, + 64504, 19928, 0, 128411, 3917, 983119, 11732, 0, 983180, 41448, 41461, + 128823, 0, 113721, 113758, 8819, 12663, 0, 41184, 74014, 232, 74835, + 120646, 9168, 65786, 0, 83293, 121007, 9094, 983926, 11758, 68425, 71886, + 1064, 42467, 128044, 10115, 19924, 92711, 113682, 7862, 64551, 13224, + 8516, 41862, 66650, 7561, 78618, 69793, 1878, 0, 71434, 2911, 83074, + 41178, 5427, 64823, 83062, 83066, 3787, 41174, 83055, 41458, 67147, + 41463, 42413, 11292, 2406, 775, 0, 65584, 69923, 6074, 9618, 68056, + 121480, 43440, 74539, 194901, 41436, 3656, 917805, 120600, 41456, 67694, + 1599, 11333, 83139, 6703, 8513, 83134, 1613, 83136, 68456, 12598, 83131, + 83132, 78745, 74500, 41460, 10145, 10542, 9937, 78746, 67144, 9905, + 83145, 65730, 83147, 120374, 8427, 83142, 55246, 120376, 42895, 11497, + 64687, 74008, 42592, 3871, 983584, 128305, 9111, 5741, 83325, 120987, + 120366, 119111, 11150, 0, 120368, 128855, 11648, 83126, 83127, 83128, + 41587, 70391, 83123, 71108, 42113, 983588, 127155, 12172, 83121, 71443, + 65298, 65723, 68289, 73871, 65724, 7928, 120354, 983095, 41595, 73730, + 64671, 42118, 73830, 66042, 10355, 983110, 7875, 983669, 41598, 3993, + 121269, 1545, 40971, 536, 127075, 43029, 0, 121000, 65173, 65286, 0, + 70331, 195012, 0, 94065, 0, 41375, 5402, 83035, 128192, 1687, 120503, + 917817, 0, 78194, 64326, 40969, 10526, 73747, 8323, 40968, 1339, 11731, + 78756, 127108, 65460, 12242, 128513, 8020, 10843, 11554, 917867, 0, 8266, + 41006, 65722, 83041, 10710, 74045, 118942, 67667, 64567, 119155, 83313, + 128778, 71889, 67857, 120687, 0, 92958, 11755, 66305, 68332, 0, 10917, + 93979, 0, 11272, 2040, 41247, 41326, 195060, 1741, 42370, 1227, 83119, + 83120, 11413, 126583, 83115, 5283, 1586, 4978, 68050, 1984, 11830, 43819, + 92293, 40984, 42904, 9373, 0, 12916, 6284, 194888, 41663, 983093, 0, + 68313, 9237, 9385, 41648, 0, 128953, 2299, 41666, 1830, 73783, 2056, + 41287, 92610, 0, 71917, 42219, 68086, 120327, 41987, 41676, 983059, + 120823, 126553, 41670, 0, 92590, 2796, 55291, 11683, 9902, 74521, 67988, + 11451, 82995, 78855, 42631, 2359, 71890, 67844, 74164, 41238, 548, 11405, + 13133, 64368, 127270, 120925, 66272, 397, 43622, 42139, 9547, 9590, + 128238, 1614, 43661, 64356, 66307, 6651, 1358, 120871, 428, 9620, 1466, + 78112, 10982, 113785, 1333, 7104, 407, 6425, 128834, 74253, 127993, 0, 0, + 5804, 11976, 8554, 92721, 0, 70167, 9057, 42294, 41218, 125097, 121290, + 78137, 1883, 10952, 8048, 70443, 41225, 92621, 42915, 128616, 128512, + 128629, 4407, 74648, 65809, 11837, 194821, 8448, 7141, 74183, 120334, + 12675, 12659, 74634, 42363, 120624, 68077, 55273, 10766, 12012, 2386, + 64732, 9170, 917821, 9123, 64585, 10296, 119158, 7140, 10977, 127378, + 4164, 9081, 0, 120569, 42049, 42042, 8709, 128283, 126477, 120637, 42419, + 64799, 42047, 0, 194820, 8470, 11807, 65897, 577, 0, 983760, 74300, 0, + 68087, 74840, 126474, 0, 128791, 92224, 8736, 1414, 42643, 9683, 43486, + 74344, 0, 2536, 983941, 66330, 121238, 0, 0, 0, 0, 0, 194830, 66317, + 69945, 66315, 2106, 67809, 11273, 120986, 43004, 7541, 82988, 0, 961, + 64307, 66324, 64906, 125080, 3106, 65917, 41284, 1696, 983130, 891, + 12105, 0, 42624, 12802, 3264, 8824, 13268, 43003, 10936, 120878, 0, 0, + 194826, 92688, 3566, 2322, 120371, 70831, 11449, 128187, 42868, 41285, + 3547, 0, 0, 113746, 983400, 43216, 6089, 78682, 68490, 120578, 4170, + 1029, 127761, 127036, 119224, 42374, 0, 744, 92883, 113739, 0, 65823, + 127826, 11182, 3551, 92938, 983891, 4623, 55268, 128738, 4598, 983162, + 65136, 127136, 0, 128169, 10851, 120876, 6179, 92602, 6180, 0, 11952, + 74579, 78648, 11972, 78646, 78647, 78644, 78645, 177, 78643, 6176, + 120580, 983696, 125135, 6177, 9020, 78652, 78653, 6178, 120249, 120242, + 128027, 67673, 2214, 8754, 127051, 120237, 2137, 43081, 194663, 119114, + 9136, 66889, 4401, 41280, 70801, 8974, 2308, 194750, 74149, 128327, 2318, + 983183, 66361, 8198, 65626, 64360, 12601, 42536, 43931, 120827, 43930, + 92462, 6970, 5404, 43332, 3667, 7936, 12925, 126989, 6385, 128482, + 128403, 118949, 10874, 65505, 120002, 129151, 42053, 2075, 42057, 11083, + 42052, 0, 67266, 67651, 121104, 9665, 92300, 983666, 13181, 917617, 0, 0, + 70088, 74148, 0, 70419, 120225, 120229, 120224, 74172, 41145, 66404, + 94096, 74422, 41148, 8683, 7594, 113686, 75033, 119090, 10869, 43458, + 41146, 92407, 11441, 121456, 3512, 119633, 92965, 8103, 78140, 120847, + 65184, 11780, 41563, 42796, 129055, 69742, 41544, 65146, 71314, 0, 78109, + 129177, 19942, 983244, 118908, 7988, 10436, 74273, 3271, 73804, 64711, 0, + 94064, 983071, 128652, 3804, 13070, 11557, 42044, 0, 1095, 0, 3599, + 127774, 0, 128861, 8514, 0, 0, 0, 74346, 66697, 0, 11684, 0, 92486, + 917603, 0, 42043, 43232, 66677, 74927, 42046, 74157, 4036, 126481, 0, + 128213, 194861, 83355, 11954, 70348, 1450, 12986, 1340, 0, 65441, 92722, + 0, 0, 125117, 0, 917542, 73812, 83053, 6539, 92948, 126607, 120702, + 92390, 0, 120492, 41190, 3973, 119365, 4575, 41193, 7982, 429, 917979, + 78891, 0, 194848, 65792, 128408, 83282, 6417, 118918, 78178, 0, 128970, + 0, 0, 4919, 10590, 128556, 7755, 0, 92942, 64548, 120506, 1621, 10214, + 65126, 68253, 127004, 983616, 12188, 983668, 1617, 8050, 0, 5015, 0, + 119174, 42590, 70354, 1756, 78181, 0, 65768, 6352, 41892, 0, 7555, 13103, + 5408, 2817, 1214, 69919, 92335, 121208, 0, 68224, 120872, 41764, 7957, + 8689, 64723, 1056, 42896, 74147, 3559, 983918, 55286, 7073, 65850, 12327, + 70853, 119028, 0, 128122, 128442, 2341, 8450, 8484, 8474, 194884, 68322, + 70079, 8461, 67721, 12153, 12799, 0, 43709, 43708, 9451, 7571, 13073, + 43847, 0, 681, 983254, 703, 127518, 3272, 8781, 12894, 70077, 11709, + 92288, 70514, 983900, 83175, 71436, 11338, 120768, 3276, 128968, 917989, + 65928, 0, 121367, 65021, 64795, 74574, 0, 10047, 78814, 3262, 78811, + 42711, 0, 0, 68478, 163, 576, 9895, 1655, 70131, 74591, 78815, 78816, + 66888, 0, 0, 70513, 10039, 120426, 5626, 5623, 5717, 5776, 43488, 83497, + 66885, 41591, 11036, 65252, 92382, 0, 0, 120111, 67848, 128128, 983595, + 983472, 8887, 127521, 7295, 11031, 983336, 43157, 0, 8946, 10348, 10412, + 8755, 119152, 0, 5718, 13221, 0, 0, 78135, 70515, 917616, 8810, 74499, + 686, 0, 71362, 4619, 118954, 6654, 73769, 74426, 0, 12040, 65689, 10128, + 65118, 68029, 119151, 74205, 92651, 128902, 2401, 68144, 8792, 983648, + 68044, 65455, 0, 74328, 0, 74561, 120763, 12886, 120952, 66624, 126578, + 43557, 10300, 10161, 10396, 71210, 78602, 118945, 9984, 73851, 3010, + 6441, 70349, 1458, 41475, 72429, 93975, 127910, 11479, 121355, 120356, + 6350, 12864, 69674, 71473, 1061, 64780, 2001, 43111, 55230, 124946, 4052, + 113673, 7626, 0, 120907, 1045, 0, 5631, 41113, 127544, 0, 43707, 74127, + 0, 983718, 8486, 0, 73758, 2335, 4362, 983195, 126561, 69221, 1025, + 127277, 42625, 70325, 78084, 41443, 0, 128206, 0, 1774, 1523, 121330, + 68059, 41445, 78236, 11207, 8567, 41442, 3988, 74843, 78237, 118910, 0, + 65274, 8564, 78199, 78238, 127515, 121272, 0, 43446, 0, 66513, 6256, + 917807, 579, 55218, 10206, 78195, 6375, 2673, 983886, 11814, 0, 4488, + 128716, 120554, 68451, 10444, 118846, 127334, 11799, 74407, 68466, 4487, + 127849, 42832, 1032, 120267, 43450, 78257, 7203, 124998, 614, 70361, + 127215, 120615, 119622, 78262, 127271, 127323, 0, 43121, 127211, 128366, + 92513, 1050, 7549, 121260, 82994, 9314, 70365, 92898, 68039, 127061, + 10057, 70434, 127313, 128577, 66504, 120963, 82992, 2307, 128456, 64333, + 127312, 128230, 73873, 983710, 94035, 0, 127973, 128708, 70446, 10360, + 6746, 120473, 92245, 440, 0, 13085, 9233, 74216, 0, 127785, 9957, 128285, + 66447, 8046, 64963, 65777, 10125, 74212, 42819, 10910, 120424, 1521, + 9896, 93965, 10487, 69878, 12527, 68737, 7970, 125073, 128660, 0, 65769, + 5243, 9849, 5239, 65771, 121429, 0, 5237, 69714, 68756, 10103, 5247, + 4769, 129302, 118977, 12873, 2283, 92931, 0, 3008, 4896, 128102, 12087, + 0, 55231, 41103, 92256, 64565, 4773, 120846, 78549, 70074, 4770, 66891, + 917567, 8731, 65378, 66911, 120619, 9122, 128033, 126600, 4774, 3019, + 9997, 12834, 0, 9456, 10215, 120547, 0, 78556, 0, 121332, 74776, 4281, + 4768, 120572, 41535, 4099, 9017, 69993, 983692, 78095, 2225, 78096, + 118946, 121097, 0, 78098, 0, 42814, 880, 0, 113764, 66870, 2134, 0, + 10116, 9877, 92329, 128960, 0, 7095, 8379, 74116, 6778, 0, 78090, 8243, + 2427, 128141, 7093, 0, 11585, 195003, 9962, 82990, 12223, 128485, 92430, + 1434, 120254, 5637, 11573, 0, 0, 0, 19951, 83389, 74419, 0, 194686, + 55283, 0, 70363, 74437, 1156, 8740, 83295, 3782, 64331, 0, 41370, 1014, + 8261, 120956, 917596, 10835, 917966, 65536, 83294, 120463, 125051, 7702, + 118824, 128976, 43010, 65779, 65783, 1150, 10547, 5700, 0, 120603, 65383, + 2339, 42594, 5697, 118788, 75018, 128576, 74923, 42257, 5696, 92677, + 120465, 3862, 9643, 0, 70183, 7634, 65167, 9845, 0, 0, 5701, 9722, 41490, + 128719, 1426, 68217, 983614, 68447, 42204, 55270, 8571, 67403, 78067, + 43859, 78818, 92719, 43182, 12184, 0, 42022, 0, 10281, 0, 5650, 43194, + 64712, 10744, 78887, 990, 5647, 0, 7387, 78734, 41114, 11477, 5646, + 12879, 11018, 128362, 3945, 92589, 983466, 194989, 78883, 0, 78212, + 127746, 1020, 73763, 983835, 78731, 5648, 64748, 120920, 78733, 10205, + 3545, 983585, 6984, 128008, 74051, 128901, 43242, 120458, 2667, 128173, + 125037, 0, 9911, 0, 65020, 10097, 119166, 127145, 983662, 118836, 983748, + 78208, 1140, 78426, 0, 10159, 0, 0, 8128, 128644, 68326, 194911, 1815, + 19910, 890, 124935, 3267, 92291, 0, 10123, 121398, 4410, 1041, 10576, + 6354, 92581, 580, 74232, 983746, 128347, 0, 0, 128098, 19938, 65906, + 127819, 917811, 0, 3298, 5375, 10142, 0, 8215, 92633, 6134, 41246, 64402, + 983147, 69899, 194938, 0, 121426, 41382, 917927, 128653, 5173, 65348, + 527, 121174, 113782, 78469, 128250, 78797, 11915, 0, 0, 10072, 0, 42695, + 2329, 42250, 0, 11187, 69667, 12245, 1568, 94033, 83460, 0, 113705, + 917910, 11201, 92708, 74769, 126470, 67680, 9069, 6144, 0, 119840, 73822, + 0, 128010, 64917, 41521, 118934, 494, 13250, 92250, 65098, 6364, 956, + 113792, 12830, 10462, 73740, 73734, 0, 0, 983739, 66449, 13263, 74281, + 69217, 13171, 127796, 120564, 0, 63885, 127251, 1044, 41276, 128363, 0, + 0, 42068, 11795, 124985, 0, 127202, 0, 42450, 3907, 0, 64526, 11829, + 68197, 12295, 0, 11475, 70329, 3020, 11537, 0, 66441, 120761, 7098, + 125071, 0, 1057, 566, 42696, 127239, 3016, 42274, 43464, 66490, 12921, + 66571, 78472, 71207, 3006, 4620, 127237, 983330, 0, 0, 64659, 0, 127749, + 55253, 6357, 6362, 8626, 71337, 2216, 9090, 65377, 41596, 0, 42920, 1698, + 0, 64477, 917853, 43813, 1053, 0, 78269, 0, 92977, 1052, 1051, 459, 1060, + 74349, 66479, 67689, 66871, 917845, 70327, 42490, 689, 6508, 4163, 42298, + 8639, 66641, 4246, 0, 43514, 12130, 983308, 42337, 64596, 64375, 66481, + 127850, 983144, 127828, 6359, 0, 43471, 983768, 0, 83345, 75065, 0, 6358, + 6361, 1926, 6356, 92627, 7898, 8110, 10935, 0, 10069, 5830, 127773, + 43685, 74307, 0, 42910, 83301, 8693, 78611, 119565, 128621, 120413, + 92192, 121454, 65894, 194694, 0, 64296, 983681, 983644, 194959, 119187, + 2135, 11836, 0, 0, 78869, 42313, 5579, 92412, 70384, 129113, 43854, + 71913, 5578, 11840, 128115, 42023, 6234, 5669, 92275, 78620, 121171, + 68833, 92254, 68202, 5583, 0, 0, 42426, 5580, 42276, 2923, 892, 2220, + 42465, 41330, 194987, 5795, 65512, 68774, 65702, 68770, 120801, 65251, + 68228, 65710, 128399, 128429, 67672, 68783, 5370, 70465, 2931, 1638, + 10966, 10188, 65878, 118848, 0, 69694, 69879, 74585, 8172, 42017, 92756, + 10844, 121016, 128195, 92424, 6374, 119998, 121075, 286, 78023, 1062, 0, + 119999, 0, 7395, 127783, 1070, 64900, 7153, 6095, 41865, 194640, 3015, + 68743, 68740, 5211, 68805, 6400, 68749, 68748, 68760, 8189, 11276, 68754, + 70284, 372, 128829, 68761, 113783, 42102, 41585, 127751, 0, 42101, 276, + 78402, 67427, 33, 67425, 67424, 9007, 67430, 41588, 66033, 427, 10763, + 118819, 70872, 127884, 983943, 1031, 6257, 92489, 42104, 0, 983980, 2328, + 66837, 1071, 42899, 125088, 74848, 120857, 113793, 194981, 1047, 0, + 194943, 42908, 128480, 69723, 10651, 70356, 0, 125113, 72433, 66829, + 70817, 5711, 41633, 12098, 65571, 9166, 0, 5710, 128551, 6790, 65168, + 13216, 983150, 69716, 69726, 0, 64611, 41623, 195001, 5715, 69654, 71915, + 0, 5712, 2761, 41620, 68124, 3074, 5722, 0, 8643, 68525, 0, 118906, 2757, + 11067, 9718, 66419, 8910, 10689, 6479, 0, 0, 71173, 78607, 9196, 69670, + 125070, 0, 128338, 120335, 118911, 0, 94043, 129194, 0, 0, 120010, 73795, + 8701, 68130, 119616, 120522, 0, 42477, 194994, 12123, 4495, 43569, 0, + 129296, 0, 64946, 10992, 0, 74566, 70336, 113688, 9318, 93986, 13249, + 42902, 73808, 0, 65457, 42249, 7639, 43995, 67845, 42641, 5454, 0, 0, + 70366, 120005, 119585, 121212, 5084, 121189, 121134, 75062, 0, 733, + 74646, 78014, 68767, 78435, 11204, 0, 9218, 1731, 0, 92937, 71070, 67990, + 983125, 0, 0, 70323, 121371, 92492, 5155, 120000, 5358, 983744, 0, + 917767, 64424, 71236, 3840, 64314, 41432, 121316, 78315, 68430, 67980, + 43253, 65943, 0, 3371, 10988, 127960, 8771, 1479, 0, 0, 1109, 11580, + 43657, 64601, 12205, 92782, 0, 64507, 8868, 399, 67978, 74842, 983286, + 121336, 12149, 13088, 551, 0, 10156, 12119, 92572, 118916, 2544, 65074, + 119211, 983298, 0, 78011, 351, 68764, 0, 128713, 55229, 0, 74268, 78008, + 128094, 0, 42377, 0, 0, 0, 113767, 74320, 9013, 4054, 0, 194580, 113740, + 0, 73960, 5585, 65881, 2549, 74469, 74457, 11104, 5584, 8358, 126473, + 64215, 66864, 10919, 70480, 7980, 126601, 113698, 2218, 41800, 5589, + 82983, 2664, 41613, 5586, 118890, 0, 11356, 121120, 194833, 43452, 67245, + 92993, 42573, 66879, 83329, 67810, 69767, 78752, 74392, 8135, 6450, + 10055, 77996, 119948, 983173, 119225, 5657, 0, 9626, 121453, 77994, + 10179, 5654, 12939, 92573, 120799, 71860, 0, 5652, 10945, 194599, 66486, + 0, 3661, 7863, 0, 68069, 983675, 70332, 127194, 5659, 194606, 78692, + 66729, 5655, 983626, 42168, 121131, 1055, 71171, 71888, 66310, 74030, + 70516, 12146, 70362, 73956, 11618, 0, 42720, 92949, 10272, 10304, 10368, + 42518, 594, 10244, 10248, 7407, 74978, 64870, 74191, 3467, 71073, 7881, + 3331, 946, 10231, 1495, 8131, 74330, 0, 9562, 69222, 65927, 0, 70036, + 69696, 69769, 64656, 917995, 0, 92409, 70056, 5666, 65227, 5318, 63994, + 119596, 9091, 10798, 78664, 78508, 10186, 983265, 7732, 983724, 64556, 0, + 983979, 5668, 74445, 74982, 74645, 5670, 113795, 127297, 11820, 2992, + 7826, 5667, 19952, 120807, 74981, 12749, 74551, 67757, 0, 66496, 4361, + 119260, 1306, 9286, 1497, 128286, 94004, 70359, 0, 3571, 13247, 5874, + 7973, 66353, 68435, 78278, 67896, 43192, 74621, 78265, 553, 113768, + 127012, 93053, 5829, 0, 4587, 78285, 65912, 194919, 12746, 128671, 70338, + 119924, 5633, 119927, 74259, 94102, 94099, 64905, 94105, 9512, 94103, + 12742, 6443, 983806, 0, 9135, 128863, 41564, 121517, 55219, 128832, + 983851, 194877, 12148, 0, 78297, 0, 64256, 0, 11669, 0, 5634, 4524, + 128903, 124936, 128390, 83215, 2425, 65182, 128769, 43636, 5221, 78410, + 328, 121031, 68736, 69815, 5636, 119917, 5329, 121293, 5638, 83166, 7940, + 64938, 43223, 43760, 5635, 3373, 2986, 78292, 74223, 3437, 68763, 6203, + 4247, 71169, 11920, 8274, 68240, 983658, 1657, 41561, 68778, 78295, 5639, + 2954, 5660, 5640, 78303, 983685, 71179, 42227, 68301, 83322, 41637, + 67872, 121105, 78310, 41625, 43362, 78309, 120713, 11705, 5642, 0, 5486, + 0, 4356, 11710, 0, 12051, 69938, 0, 5641, 8259, 126994, 1058, 0, 67630, + 0, 128927, 1144, 78750, 127293, 42228, 983714, 73890, 118972, 127352, + 2800, 83209, 5645, 64964, 8652, 2547, 66484, 43634, 121356, 5608, 65890, + 43808, 194972, 67621, 64932, 9000, 71204, 67235, 92673, 1865, 128706, + 5613, 66401, 121145, 0, 5610, 983226, 71199, 65826, 2069, 0, 10787, + 43999, 2997, 119932, 5609, 78316, 65319, 78313, 12316, 5875, 2412, 83206, + 8186, 9807, 74269, 66294, 13130, 65874, 71855, 5807, 113678, 10030, 5306, + 12364, 118863, 92970, 11704, 83202, 92583, 10211, 0, 120579, 0, 121063, + 11706, 9710, 125022, 82985, 120655, 413, 65623, 7118, 83167, 9133, 74262, + 917964, 1042, 125068, 64779, 12171, 119240, 6185, 64776, 4984, 121266, + 708, 11391, 0, 12241, 92720, 83399, 1308, 121258, 2534, 810, 125089, + 120933, 128016, 71849, 71869, 1917, 3000, 125140, 120184, 120739, 2364, + 66387, 74470, 66618, 65680, 66411, 10027, 71841, 128154, 12337, 74283, + 127368, 983167, 2980, 755, 69774, 931, 13124, 68068, 6363, 2748, 121022, + 0, 65041, 92276, 44011, 8730, 194997, 127854, 78312, 7274, 119250, 92988, + 7275, 78304, 935, 127052, 65840, 377, 42325, 11649, 127363, 65253, 64301, + 128835, 78308, 42341, 65284, 2417, 0, 12884, 19912, 7907, 10768, 78300, + 194998, 194912, 10673, 68779, 7248, 68786, 43515, 1781, 5496, 3627, 62, + 1649, 67876, 964, 121034, 66403, 78226, 66393, 92897, 70355, 66409, 0, + 83398, 43689, 127911, 13142, 78812, 42415, 66575, 4542, 69909, 43547, + 83028, 0, 7677, 2991, 4946, 42454, 11565, 7949, 0, 69759, 11341, 42494, + 3073, 65625, 9714, 11692, 4657, 0, 70810, 6478, 9898, 43673, 65237, 6241, + 7106, 4877, 129108, 6238, 0, 10548, 127049, 4409, 0, 0, 64798, 70805, + 5346, 128240, 94047, 6237, 4874, 66851, 9176, 92882, 121153, 65231, + 65884, 12678, 78748, 118912, 11378, 44018, 42785, 2408, 3251, 11203, + 983159, 5685, 0, 2461, 11052, 7091, 5342, 8317, 121446, 68163, 5340, + 120559, 127820, 43635, 73928, 125001, 71069, 83318, 0, 83317, 65482, + 121394, 9142, 0, 68506, 0, 10938, 0, 118790, 1182, 2542, 4826, 0, 126648, + 72438, 529, 8580, 127490, 0, 10586, 10790, 10839, 66023, 41593, 41207, + 68744, 983825, 41594, 225, 42828, 0, 67821, 121200, 11376, 74379, 10721, + 67664, 3438, 42097, 68862, 11084, 3194, 41870, 266, 78305, 120183, 41873, + 120575, 11324, 120531, 0, 8420, 64918, 128839, 41871, 41338, 3734, 7734, + 43683, 8750, 66605, 66011, 92514, 40965, 127937, 983216, 5161, 10572, + 917558, 42906, 0, 64349, 7287, 42162, 120406, 983643, 126605, 11167, + 69220, 12359, 43429, 41369, 1697, 12191, 0, 68633, 7286, 0, 68635, 10031, + 113766, 9870, 67726, 8620, 65824, 917855, 11938, 121308, 7285, 983557, + 119577, 42678, 66842, 43677, 41583, 0, 65799, 92623, 0, 129168, 128267, + 78169, 66199, 0, 3609, 68624, 70280, 832, 120693, 120770, 78473, 66007, + 78471, 65703, 71256, 128517, 42732, 5180, 92699, 41395, 41530, 11691, + 64773, 92214, 74002, 127790, 120548, 128645, 6348, 243, 13200, 120160, + 6024, 92309, 9979, 10037, 41529, 10648, 8538, 43687, 0, 917844, 4285, + 66195, 121370, 4230, 92886, 7367, 43256, 92353, 7563, 42376, 983271, + 68442, 120512, 0, 0, 214, 128578, 0, 74856, 65893, 12208, 9973, 128386, + 66311, 65589, 128277, 2603, 0, 70155, 78622, 70047, 127273, 6022, 195023, + 2884, 0, 11620, 0, 43, 195020, 12682, 1016, 41107, 0, 41121, 3885, 92, + 65456, 64608, 0, 74801, 70855, 2074, 113742, 78283, 0, 12453, 70847, + 983826, 74241, 126568, 6791, 12457, 78268, 0, 66278, 0, 78279, 0, 0, + 92358, 66637, 7995, 8759, 43421, 78277, 12449, 128552, 71224, 43868, + 8752, 3197, 4720, 10165, 113765, 119249, 113715, 11595, 64893, 118905, + 43435, 124964, 125030, 4993, 0, 6168, 10934, 1946, 741, 120650, 5494, + 4639, 127559, 1990, 11107, 4498, 74169, 67736, 83273, 127272, 69734, + 2960, 73779, 0, 8969, 128117, 43424, 73959, 126464, 2950, 119579, 6210, + 65753, 370, 121360, 0, 0, 4953, 195009, 121054, 113708, 0, 69230, 0, + 195010, 65688, 74951, 5063, 3517, 2964, 43663, 917762, 6344, 74791, + 10566, 10144, 66333, 8252, 729, 66016, 78253, 0, 71317, 64923, 120571, + 43669, 9032, 78263, 78264, 0, 41215, 0, 65883, 0, 917774, 74914, 3761, 0, + 0, 70068, 120408, 12912, 119012, 3850, 128191, 983256, 128389, 0, 0, 908, + 0, 8611, 121384, 0, 74642, 43691, 41197, 0, 8978, 120540, 119135, 41586, + 10527, 70426, 917848, 3848, 78739, 74917, 127536, 65241, 5336, 74883, + 128786, 663, 0, 10780, 0, 0, 78767, 983259, 127163, 68193, 347, 0, + 917544, 78775, 64675, 41582, 78774, 78744, 65579, 12980, 68046, 12143, + 69657, 78512, 128493, 11153, 41804, 78523, 0, 78525, 0, 128859, 41584, + 10681, 0, 120979, 73938, 73781, 128022, 4800, 66661, 0, 66306, 64715, + 66384, 9518, 6609, 10434, 70845, 11319, 1097, 128964, 917564, 41730, + 129181, 121501, 73847, 74845, 65172, 41728, 41721, 194780, 194769, + 121499, 41203, 127056, 13110, 41726, 194856, 67077, 1000, 69651, 127509, + 41140, 1209, 73978, 125059, 73750, 1073, 6321, 77878, 41138, 983968, + 68213, 78000, 12167, 1115, 41605, 9794, 119904, 67671, 55248, 12237, + 78787, 66314, 6587, 9290, 78782, 78783, 9231, 78781, 2959, 7926, 0, + 917601, 128833, 64398, 71124, 119970, 12311, 119181, 78796, 68768, 78794, + 78795, 68434, 78793, 66670, 113797, 128579, 12290, 120169, 129093, + 119873, 42142, 9968, 8205, 0, 5131, 113694, 9627, 43646, 78542, 78535, + 983212, 1944, 1248, 10148, 127755, 119990, 119991, 12701, 78376, 11308, + 119995, 983493, 113702, 66836, 65305, 65100, 4031, 42794, 120003, 7075, + 8154, 119985, 120007, 41817, 73934, 42275, 120011, 120012, 78526, 120014, + 120015, 6041, 120520, 41899, 983288, 8002, 128367, 4364, 73732, 983570, + 64332, 120976, 7813, 9064, 119986, 10124, 7526, 8601, 7281, 68246, 7279, + 12041, 1418, 10885, 12673, 121152, 121381, 9660, 917929, 13012, 4571, + 917588, 0, 118940, 12078, 2970, 129122, 10933, 0, 77870, 121243, 77841, + 0, 41599, 70159, 121342, 120885, 12950, 92160, 3486, 983973, 78311, 4239, + 128073, 127799, 66511, 68066, 2637, 64629, 8460, 66834, 8476, 983975, 0, + 68312, 78489, 65673, 1019, 78495, 4148, 0, 12289, 0, 4316, 0, 13119, + 8488, 5412, 66243, 9935, 92777, 73864, 983203, 41734, 8206, 74081, 9163, + 3286, 9072, 5867, 13302, 7622, 7120, 41736, 92546, 41731, 0, 7400, 5416, + 68663, 118924, 10817, 0, 41539, 127284, 66853, 73963, 41855, 41867, + 65564, 11277, 65892, 11536, 10620, 92272, 7115, 66030, 73932, 5498, + 63876, 41536, 0, 68204, 92587, 3459, 8997, 194719, 92714, 0, 127782, + 92512, 0, 66377, 69781, 0, 124972, 78511, 3161, 295, 71257, 0, 92223, + 121328, 78742, 9016, 43454, 63903, 63902, 43501, 68210, 3971, 983959, + 70063, 2952, 78765, 11038, 10901, 63900, 63899, 63898, 68095, 667, 12332, + 63887, 6086, 41722, 0, 5172, 0, 983280, 4159, 983562, 0, 9815, 63884, + 19934, 63882, 41198, 8555, 63878, 63877, 42460, 6050, 42708, 63881, + 63872, 120941, 42421, 195035, 41723, 63875, 63874, 11460, 7432, 1913, + 41913, 63852, 66869, 128971, 42348, 73892, 6752, 446, 41911, 127901, + 63851, 63850, 41910, 128637, 63846, 2972, 12932, 7262, 69968, 63849, + 63848, 63847, 113749, 6570, 8302, 7259, 63842, 4178, 10746, 7250, 13214, + 10041, 8105, 63892, 127780, 69969, 1105, 4180, 127786, 12094, 9497, 0, + 63891, 63890, 63889, 63888, 5538, 9987, 0, 92739, 1678, 13274, 552, + 118834, 44010, 10785, 0, 11192, 4557, 74459, 9159, 10171, 13125, 63860, + 5540, 63858, 63865, 281, 13242, 63862, 74154, 0, 5536, 65568, 9574, 1388, + 71902, 0, 1077, 195000, 65099, 11531, 5834, 0, 0, 917789, 0, 42773, + 121331, 0, 0, 119220, 120912, 3663, 127027, 1112, 70335, 8686, 126611, + 5334, 65081, 43249, 74778, 127968, 11077, 125017, 6509, 0, 5327, 78776, + 19907, 63869, 3478, 7583, 7679, 2903, 0, 3001, 1158, 8745, 43746, 73748, + 63866, 78626, 1915, 4846, 67755, 66371, 118984, 42105, 2990, 120128, 805, + 69238, 64438, 12070, 8760, 1117, 113750, 12212, 120123, 65174, 42357, + 63835, 63834, 983947, 78240, 12225, 63838, 63837, 983853, 70173, 63833, + 6042, 66360, 8083, 128166, 983733, 63821, 63820, 63819, 63818, 983904, + 5227, 9047, 63822, 74797, 6091, 0, 10691, 560, 5643, 8226, 119578, 63812, + 63811, 63810, 63809, 2289, 63815, 63814, 63813, 6047, 1597, 120143, 780, + 206, 70126, 4936, 65147, 8168, 63930, 2076, 1093, 9882, 63934, 2082, + 63932, 75050, 63929, 3546, 1605, 77934, 9806, 43472, 77933, 8400, 11343, + 2086, 0, 63926, 2984, 5968, 9287, 0, 4618, 42209, 11137, 13169, 5290, + 2089, 1695, 10743, 1088, 63825, 7268, 1084, 1085, 63829, 1083, 10131, + 7283, 0, 63970, 121165, 1092, 4754, 7273, 5252, 44016, 43627, 127921, + 128920, 7408, 11809, 83220, 121181, 0, 2965, 7258, 8808, 66572, 1089, + 4187, 63937, 42119, 42120, 11106, 940, 5787, 10099, 63938, 0, 74494, + 12463, 2994, 125136, 118827, 68522, 9664, 70834, 77940, 67892, 77938, + 74343, 67370, 0, 660, 10127, 666, 9022, 5532, 43667, 5533, 12580, 78507, + 6118, 222, 979, 3884, 983394, 74151, 83227, 6502, 983855, 11085, 121261, + 63951, 12465, 917862, 0, 128782, 63946, 1707, 63924, 12461, 63950, 63897, + 63948, 63947, 63945, 6038, 63943, 63942, 64685, 63895, 65838, 2276, 7776, + 94076, 121086, 92464, 120444, 69730, 801, 43165, 1690, 63919, 63918, + 63917, 13277, 43659, 12951, 120638, 9906, 2054, 2334, 78515, 63916, 5483, + 63914, 69737, 63911, 5484, 63909, 63908, 2539, 120102, 43980, 5485, 0, + 42697, 9061, 5534, 10672, 4502, 68057, 253, 0, 68208, 120439, 9203, + 74231, 0, 11530, 68634, 68668, 121242, 11127, 0, 10474, 43426, 13257, + 42354, 128099, 983698, 70044, 195065, 0, 8413, 66841, 0, 5693, 7272, 0, + 13209, 64470, 65831, 74350, 195063, 0, 0, 0, 126639, 120097, 0, 94078, + 66840, 127165, 66608, 3111, 41863, 8804, 42913, 78347, 7270, 0, 66606, + 6628, 1076, 7433, 1436, 73844, 55226, 128353, 63982, 7393, 12807, 43413, + 63906, 1598, 63904, 71187, 70393, 41729, 4423, 1307, 113692, 10515, + 41589, 128698, 128918, 6218, 92917, 1430, 0, 126513, 120606, 78754, 5413, + 7619, 3255, 3493, 74032, 11549, 10735, 41743, 73937, 6801, 983633, 4518, + 10990, 65073, 5167, 4481, 3771, 67093, 2710, 983593, 66277, 41724, 67716, + 43073, 41690, 12479, 983635, 8380, 121071, 71852, 70046, 1628, 121229, + 128817, 129067, 65262, 6333, 10783, 11172, 121473, 63855, 70840, 113679, + 0, 5339, 74323, 120946, 13004, 66843, 4457, 0, 127756, 194818, 127116, + 5684, 8678, 10914, 43632, 5689, 65807, 70814, 68464, 12633, 12870, 69705, + 65183, 5688, 11926, 6033, 6310, 5686, 119076, 74251, 0, 120647, 128930, + 50, 10558, 9871, 42612, 43655, 74403, 983818, 74284, 66468, 66905, 13259, + 4448, 119150, 121406, 83349, 70043, 1321, 0, 10640, 11539, 1151, 121186, + 917607, 124958, 127079, 71106, 127852, 0, 0, 983075, 12501, 64604, + 128657, 11527, 118870, 8812, 983706, 11538, 8673, 12650, 11020, 0, 66467, + 2105, 8087, 78163, 69632, 9894, 127137, 127856, 69995, 4636, 55262, + 78513, 4515, 2382, 0, 127055, 983695, 113780, 0, 118968, 12277, 121239, + 11995, 92553, 121006, 12158, 70170, 8741, 10197, 68780, 92426, 121285, + 6531, 83051, 127846, 473, 43415, 92936, 983650, 1873, 1087, 124966, 0, + 74280, 78527, 66439, 43218, 983123, 194716, 7237, 12504, 71113, 126559, + 128748, 120887, 9489, 0, 70843, 4384, 74220, 63845, 2058, 69741, 13295, + 43191, 128030, 128571, 1154, 3857, 1205, 0, 0, 6055, 12958, 120706, + 74168, 128388, 70846, 4421, 10592, 0, 495, 66400, 41712, 7983, 70833, + 93997, 983332, 6347, 78715, 7654, 41710, 4196, 0, 437, 41709, 73772, + 70832, 0, 9465, 13290, 119180, 4997, 64306, 121309, 0, 4999, 194642, + 67401, 126582, 4711, 120769, 120602, 2739, 0, 8044, 74313, 194643, 41789, + 128142, 10809, 66279, 0, 0, 1779, 6600, 6601, 41543, 5325, 642, 64187, + 13058, 120449, 12875, 983804, 92186, 13229, 71845, 10575, 43399, 194577, + 0, 41791, 1104, 0, 983725, 10655, 983334, 983561, 120164, 0, 1082, + 121024, 8428, 6569, 0, 0, 78534, 69849, 6783, 194671, 12993, 8049, 41548, + 44021, 6458, 64728, 128882, 4761, 63828, 4766, 64623, 1273, 43407, + 120677, 118876, 195045, 6912, 1313, 6322, 10483, 128627, 41545, 126465, + 92449, 0, 11216, 121307, 0, 78624, 3484, 74337, 0, 0, 8503, 5122, 41527, + 71910, 66320, 70161, 74907, 0, 0, 41537, 66453, 8303, 8282, 11817, 73857, + 10003, 73859, 65904, 7363, 1686, 0, 70115, 11467, 3664, 65921, 64299, + 124939, 128462, 128001, 4324, 126, 42246, 75030, 69984, 67725, 65926, + 7744, 68859, 74277, 66283, 78052, 43817, 6966, 43822, 8136, 0, 65600, + 1633, 0, 126614, 4762, 1103, 70827, 70157, 4765, 983494, 13078, 0, 4760, + 63827, 2050, 10871, 43199, 1102, 194652, 42236, 128867, 127072, 11546, + 74794, 337, 121196, 42591, 8627, 12279, 1111, 0, 75047, 4707, 68206, + 10143, 7883, 121444, 7880, 4522, 8645, 5704, 13010, 69796, 8304, 92982, + 194688, 119575, 2293, 70195, 66654, 129077, 92676, 0, 13008, 121194, + 4385, 128736, 13011, 125004, 92569, 119161, 13009, 160, 2677, 70388, + 983282, 41793, 65763, 74221, 70790, 41792, 42770, 94054, 65762, 118829, + 43821, 5709, 128296, 71076, 43816, 983087, 983896, 1079, 3867, 5708, 0, + 0, 43797, 5706, 64768, 5705, 8791, 4005, 121091, 10237, 10991, 128816, + 43459, 9173, 917581, 917580, 13170, 12540, 129178, 42605, 120765, 126617, + 68647, 917572, 10058, 68058, 74867, 67730, 127078, 3339, 11448, 1106, + 917591, 917540, 917593, 3340, 74017, 917586, 120994, 129141, 120541, + 10605, 1309, 63966, 120743, 1754, 92226, 13246, 864, 983171, 118926, + 8972, 119918, 7849, 120092, 83130, 13240, 195068, 5192, 4338, 67982, + 10948, 66825, 13199, 92575, 1236, 13208, 13261, 13189, 13188, 93993, + 71847, 7440, 0, 120153, 9553, 1590, 63777, 63776, 13178, 63782, 63781, + 63780, 63779, 1583, 119923, 13260, 4550, 120598, 64205, 129107, 71071, + 41522, 41523, 68523, 983772, 118923, 11354, 94071, 0, 42795, 0, 119195, 11394, 194646, 13236, 13272, 13194, 1334, 69926, 4479, 1178, 65586, - 120663, 66681, 119193, 4601, 0, 0, 983765, 0, 0, 194658, 0, 6809, 63786, - 6031, 0, 63791, 63790, 1145, 63788, 7910, 63785, 43153, 754, 10192, - 13105, 8183, 120741, 2037, 0, 0, 10747, 125, 0, 64890, 0, 983131, 0, - 41719, 63758, 3523, 1074, 13258, 9536, 74077, 0, 4427, 74242, 63757, - 43145, 12217, 63754, 41532, 1349, 63750, 63749, 0, 0, 0, 63753, 63802, - 41084, 120622, 68133, 41930, 63805, 63804, 43632, 63801, 41082, 8140, - 63798, 6260, 0, 0, 94074, 63793, 11988, 3898, 128241, 10201, 12238, - 63795, 42194, 10367, 12521, 10431, 42114, 41932, 1068, 0, 12523, 12945, - 983329, 42203, 7950, 10804, 63771, 42787, 4386, 12224, 6973, 2793, 12475, - 0, 0, 63769, 9530, 983119, 12232, 13135, 8596, 5681, 63762, 4595, 63760, - 792, 0, 64803, 0, 8742, 0, 11053, 128796, 63744, 128107, 0, 7588, 63748, - 1693, 63746, 43204, 5055, 68426, 917853, 1090, 120679, 128356, 11665, - 74133, 4558, 65685, 9523, 0, 0, 78681, 11513, 0, 6157, 63775, 63774, - 63773, 13191, 12170, 3500, 3139, 0, 3170, 12485, 0, 10872, 78271, 13006, - 64433, 0, 0, 941, 0, 0, 0, 65541, 11063, 0, 8228, 0, 42065, 0, 0, 94039, - 0, 92455, 7386, 0, 64444, 0, 119863, 43603, 94075, 65397, 288, 0, 0, 0, - 10025, 69915, 2918, 0, 65300, 119871, 9883, 64726, 2790, 65395, 3793, 0, - 127829, 65393, 0, 74138, 0, 0, 0, 74139, 92712, 65394, 11548, 5270, 0, - 65396, 0, 65813, 13256, 1282, 120771, 0, 0, 10888, 983604, 65242, 0, - 3330, 0, 0, 983974, 0, 0, 74259, 3304, 42753, 0, 0, 0, 1627, 0, 0, 0, - 5371, 13116, 0, 1826, 118794, 0, 43094, 70023, 43650, 94037, 0, 9035, 0, - 0, 128005, 0, 92207, 68125, 0, 164, 0, 94067, 94000, 6958, 0, 43116, 0, - 70019, 13245, 0, 0, 127376, 0, 70031, 127756, 12666, 13175, 13207, - 120414, 66014, 120428, 7447, 5929, 0, 65509, 0, 7449, 11306, 0, 73920, - 3180, 0, 63808, 9054, 971, 13062, 0, 0, 65195, 10164, 92252, 74428, 0, - 78146, 92611, 0, 0, 0, 10045, 12882, 13275, 128161, 11057, 0, 13276, 0, - 41525, 78150, 7271, 11444, 0, 0, 0, 12229, 41523, 0, 43411, 73751, 0, - 64813, 0, 0, 10476, 3858, 0, 3932, 64958, 0, 0, 73989, 68192, 0, 69847, - 369, 0, 41784, 0, 64163, 0, 0, 0, 65474, 4796, 12292, 126595, 65479, 0, - 41781, 10486, 41480, 43002, 9899, 0, 0, 404, 12821, 3741, 0, 5788, 8092, - 68212, 41222, 1831, 66020, 3982, 0, 4388, 0, 746, 120784, 0, 0, 12018, - 65294, 0, 0, 0, 0, 4422, 4708, 3799, 74292, 119357, 0, 74430, 0, 11700, - 4374, 0, 128179, 1364, 0, 8038, 0, 917597, 12868, 69814, 0, 6735, 73979, - 13174, 73968, 13225, 0, 69808, 65835, 0, 2365, 7841, 0, 42855, 118856, - 42866, 0, 0, 0, 66438, 41785, 12617, 64172, 13173, 4372, 119354, 0, - 983568, 0, 0, 92402, 128062, 12965, 384, 64512, 10404, 10340, 119352, - 1556, 5274, 13210, 120125, 10017, 9733, 41787, 983243, 126994, 41373, - 78039, 12303, 0, 13232, 13233, 349, 4863, 41371, 11656, 0, 120703, - 119883, 12861, 4398, 8543, 65618, 128018, 1096, 0, 0, 42688, 12441, - 12355, 119348, 119347, 4318, 10452, 0, 8032, 13243, 13237, 12719, 126646, - 119101, 0, 64884, 119872, 119345, 8597, 0, 0, 9864, 0, 120785, 119874, - 94107, 13195, 41452, 64961, 7722, 0, 10459, 119878, 0, 119879, 66590, - 128123, 41533, 66337, 0, 92184, 0, 4965, 43445, 917536, 73849, 0, 43638, - 78537, 128287, 6261, 119342, 43147, 66570, 1957, 10420, 982, 2756, 13292, - 13206, 128828, 0, 2925, 73809, 13056, 127559, 13212, 43238, 0, 13190, - 13187, 92541, 13198, 118793, 0, 5242, 119179, 64476, 1694, 8216, 71369, + 68311, 66681, 119193, 4601, 0, 127885, 983765, 66828, 128972, 127839, + 74580, 6809, 63786, 6031, 67402, 63791, 63790, 1145, 63788, 7910, 63785, + 43153, 754, 10192, 13105, 8183, 120741, 2037, 0, 64710, 10747, 125, + 120803, 64890, 983064, 127376, 0, 41719, 63758, 3523, 1074, 13258, 9536, + 71056, 0, 4427, 74242, 63757, 43145, 12217, 63754, 41532, 1349, 63750, + 63749, 129025, 0, 127928, 63753, 63802, 41084, 120622, 68133, 41930, + 63805, 63804, 11140, 63801, 41082, 8140, 63798, 6260, 0, 128391, 94074, + 63793, 11988, 3898, 92246, 10201, 12238, 63795, 42194, 10367, 12521, + 10431, 42114, 41932, 1068, 0, 12523, 12945, 983331, 42203, 7950, 3124, + 63771, 42787, 4386, 11148, 6973, 2793, 12475, 129180, 75056, 63769, 9530, + 121248, 12232, 13135, 8596, 5681, 63762, 4595, 63760, 792, 113674, 64803, + 0, 8742, 195029, 11053, 128796, 63744, 128107, 128942, 7588, 63748, 1693, + 63746, 43204, 5055, 68426, 42063, 1090, 68803, 120778, 11665, 74133, + 4558, 65685, 9523, 983453, 63857, 71216, 11513, 0, 6157, 63775, 63774, + 63773, 13191, 12170, 3500, 3139, 68071, 3170, 12485, 43891, 10872, 43892, + 13006, 43933, 120074, 0, 941, 0, 129079, 120967, 65541, 11063, 0, 8228, + 0, 42065, 128368, 43889, 94039, 129299, 92455, 7386, 0, 64444, 70295, + 119863, 43603, 94075, 65397, 288, 83409, 0, 0, 10025, 69915, 2918, 66820, + 65300, 119871, 9883, 64726, 2790, 65395, 3793, 983620, 127829, 65393, + 120592, 74138, 83505, 92751, 75019, 74139, 78777, 65394, 11548, 5270, + 983238, 65396, 74998, 65813, 13256, 1282, 120771, 75012, 0, 10888, + 120934, 65242, 0, 3330, 0, 0, 68340, 0, 0, 71202, 3304, 42753, 92588, + 70298, 74643, 1627, 0, 127765, 194735, 5371, 13116, 0, 1826, 118794, 0, + 43094, 70023, 43650, 94037, 68317, 9035, 11141, 917977, 128005, 0, 92207, + 68125, 74898, 164, 68309, 94067, 94000, 6958, 0, 43116, 67719, 70019, + 13245, 0, 68808, 66818, 0, 70031, 11099, 12666, 13175, 13207, 120414, + 66014, 120428, 7447, 5929, 0, 65509, 129192, 7449, 11306, 0, 73920, 3180, + 125102, 63808, 9054, 971, 13062, 71090, 0, 65195, 10164, 92252, 74428, + 983321, 78146, 92611, 0, 70204, 0, 10045, 12882, 13275, 2303, 11057, + 917976, 13276, 125133, 41525, 78150, 7271, 11444, 126479, 127904, 121203, + 12229, 11680, 92956, 43411, 73751, 0, 64813, 195089, 0, 10476, 3858, + 64175, 3932, 64958, 120432, 983678, 73989, 68192, 0, 69847, 369, 74908, + 41784, 119175, 64163, 77997, 0, 92645, 65474, 4796, 12292, 126595, 65479, + 128631, 41781, 10486, 41480, 43002, 9899, 92608, 0, 404, 12821, 3741, 0, + 5788, 8092, 68212, 41222, 1831, 66020, 3982, 0, 4388, 194913, 746, + 118826, 74783, 0, 12018, 65294, 127545, 194925, 68835, 983488, 4422, + 4708, 3799, 74292, 119357, 121146, 74430, 0, 11700, 4374, 120377, 121151, + 1364, 0, 8038, 120883, 917597, 12868, 69814, 70425, 6735, 73979, 13174, + 73968, 13225, 194902, 69808, 65835, 0, 2365, 7841, 71476, 42855, 118856, + 42866, 0, 0, 127986, 66438, 41785, 12617, 64172, 13173, 4372, 119354, + 983920, 983568, 128871, 127821, 67685, 128062, 12965, 384, 64512, 10404, + 10340, 119352, 1556, 5274, 13210, 120125, 10017, 9733, 41787, 983245, + 121149, 41373, 68486, 12303, 128476, 13232, 13233, 349, 4863, 41371, + 11656, 0, 120703, 119883, 12861, 4398, 8543, 65618, 92737, 1096, 43852, + 121433, 42688, 12441, 12355, 119348, 119347, 4318, 10452, 92902, 8032, + 13243, 13237, 12719, 126646, 119101, 121156, 64884, 92909, 119345, 8597, + 71100, 129062, 9864, 0, 120785, 119874, 94107, 13195, 41452, 64961, 7722, + 0, 10459, 119878, 124949, 119879, 66590, 128123, 41533, 66337, 128663, + 92184, 0, 4965, 43445, 917536, 67856, 0, 43638, 78536, 121187, 6261, + 119342, 43147, 66570, 1957, 10420, 982, 2756, 13292, 13206, 125064, + 917795, 2925, 73809, 13056, 92914, 13212, 43238, 121396, 13190, 13187, + 92541, 13198, 118793, 121089, 5242, 119179, 64476, 1694, 8216, 71369, 6770, 43331, 0, 65620, 983728, 43544, 126466, 0, 41444, 65621, 69955, 9197, 5246, 119106, 13185, 9709, 120323, 120322, 12314, 65616, 5238, - 119333, 0, 119337, 5236, 40979, 0, 74201, 8286, 128537, 3936, 119331, - 11699, 41347, 127249, 13235, 8842, 41248, 0, 4379, 13239, 12692, 7969, - 127266, 7219, 127250, 128251, 120509, 0, 66224, 734, 2979, 120303, 65619, - 9872, 957, 64921, 1846, 66631, 41477, 119256, 120310, 74511, 41770, 1670, - 6442, 120317, 42446, 5379, 120318, 41163, 74832, 120315, 120314, 11506, - 0, 42841, 13267, 0, 0, 41775, 0, 7130, 41773, 0, 10663, 0, 0, 0, 6151, - 12110, 42673, 65572, 65293, 65250, 13265, 13264, 64518, 0, 6100, 0, - 92647, 5808, 65922, 0, 12967, 66041, 5612, 4583, 0, 0, 68097, 64575, - 126637, 11965, 0, 68358, 0, 69789, 0, 92260, 68102, 9698, 7814, 74476, - 119651, 128514, 0, 41921, 118858, 9756, 6985, 119258, 78490, 74219, 0, 0, - 118997, 8012, 5674, 12353, 0, 12361, 5677, 5588, 0, 41925, 128124, 41920, - 5673, 120534, 5676, 41923, 12694, 118978, 5672, 1294, 0, 78059, 0, 42511, - 1727, 120725, 42436, 0, 0, 0, 74222, 8718, 3550, 736, 10268, 4505, 10316, - 74090, 5826, 55232, 5813, 0, 120712, 5841, 5837, 55234, 0, 3105, 12829, - 5838, 5796, 0, 119592, 5793, 0, 5866, 5797, 41011, 5865, 120091, 7956, - 598, 0, 64649, 5806, 42398, 0, 9037, 5671, 120041, 983255, 0, 0, 128855, - 0, 847, 128242, 9529, 0, 66657, 6980, 78483, 120035, 78484, 983491, 0, - 120033, 78486, 0, 0, 120039, 42683, 0, 983055, 7114, 0, 0, 43190, 65463, - 1554, 0, 42611, 42563, 0, 5651, 2929, 6792, 43201, 0, 19963, 5698, 0, 0, - 0, 0, 5644, 10292, 65546, 69727, 68141, 8372, 0, 65116, 0, 120022, 10175, - 10388, 42799, 94100, 41013, 10568, 0, 983618, 2869, 0, 41015, 194692, - 2785, 4366, 0, 10954, 41802, 0, 42608, 78469, 9884, 4759, 0, 0, 10266, - 41359, 1170, 43365, 69810, 73908, 1609, 902, 0, 63936, 128875, 11661, - 8122, 5818, 0, 0, 3861, 9540, 11028, 2554, 5158, 5714, 2213, 0, 0, 807, - 43079, 0, 78475, 976, 5511, 64553, 0, 42155, 0, 41356, 74110, 118801, - 126614, 0, 8676, 983291, 0, 5582, 451, 63941, 5798, 9349, 42018, 127858, - 0, 0, 43609, 5906, 120553, 1440, 0, 128853, 120016, 74283, 11005, 0, - 66656, 66044, 0, 194698, 0, 0, 43393, 10094, 0, 11529, 10857, 120643, - 66436, 6546, 93, 8102, 0, 68405, 0, 0, 8171, 0, 119097, 127064, 917543, - 383, 7154, 41656, 92634, 94040, 0, 5187, 71296, 127277, 11286, 68620, - 64217, 0, 5232, 0, 41009, 0, 41005, 0, 0, 983827, 8292, 195074, 4980, - 8860, 73947, 10028, 65291, 7076, 13182, 194705, 0, 0, 10631, 66031, 7972, - 0, 78785, 0, 7900, 0, 11309, 3806, 4198, 42725, 0, 67656, 9995, 0, 92552, - 0, 12931, 0, 42684, 74285, 2088, 64213, 64366, 65156, 8814, 42238, 74771, - 0, 0, 12836, 0, 0, 74342, 8593, 0, 0, 68445, 13255, 0, 0, 7464, 0, 65865, - 0, 194650, 127144, 0, 9342, 120464, 0, 64516, 0, 78792, 10129, 41007, - 74375, 0, 40995, 12209, 41012, 119136, 0, 0, 69724, 40992, 92264, 127153, - 68653, 43558, 5522, 0, 61, 0, 74105, 3633, 983900, 65162, 41234, 12089, - 78281, 9771, 983905, 13251, 128701, 0, 6262, 2784, 42743, 0, 8126, 66483, - 0, 0, 441, 42621, 0, 0, 41002, 40999, 119623, 43266, 7108, 194779, 10890, - 74481, 65834, 8324, 119103, 64417, 74817, 127465, 64737, 0, 983659, 8930, - 66678, 74249, 1193, 10056, 1800, 13253, 13252, 7829, 0, 0, 7743, 0, 0, - 77904, 92640, 77905, 9034, 6039, 0, 10075, 0, 41018, 65683, 10338, 66469, - 0, 0, 0, 42815, 0, 41966, 0, 127471, 0, 11792, 43064, 41025, 911, 7539, - 0, 0, 120339, 65159, 64390, 0, 0, 5520, 11662, 0, 65330, 42812, 0, 0, - 12326, 983856, 0, 42808, 128337, 9348, 64901, 983861, 0, 0, 0, 0, 0, - 917584, 43702, 983576, 5857, 65342, 92727, 119120, 120079, 8644, 0, 0, 0, - 74296, 41909, 0, 120332, 2791, 69663, 1891, 69824, 0, 41907, 66647, - 118939, 8761, 12942, 5748, 0, 10773, 0, 0, 8796, 78149, 6412, 2061, 8520, - 13146, 127185, 63931, 0, 65902, 2882, 0, 0, 12843, 4520, 120345, 92459, - 0, 983660, 0, 73860, 0, 0, 64345, 0, 9201, 128314, 194940, 0, 0, 43679, - 917585, 65117, 92270, 0, 10427, 0, 3844, 120675, 9755, 1110, 6612, 12222, - 0, 128789, 0, 0, 783, 194935, 0, 0, 983064, 194720, 65056, 3620, 41180, - 68378, 4556, 0, 0, 194933, 74250, 0, 67657, 10510, 4382, 66482, 0, 0, - 127527, 9177, 8902, 93958, 9839, 0, 12891, 983755, 983636, 63999, 2016, - 41917, 9788, 63928, 0, 1862, 65800, 9155, 66623, 9786, 65082, 41919, - 8579, 41914, 7981, 0, 66017, 4508, 64883, 92456, 92522, 127814, 0, 64592, - 74276, 120080, 6784, 78788, 68181, 0, 0, 0, 127534, 12147, 9024, 66378, - 66472, 983929, 64289, 65289, 78151, 66658, 194929, 64509, 78152, 0, - 126505, 11051, 983296, 0, 11355, 65885, 0, 128310, 41214, 0, 12299, 0, - 7500, 4506, 7773, 0, 0, 9963, 68649, 126609, 4040, 120570, 6167, 0, - 63922, 6594, 983740, 0, 0, 3624, 43036, 0, 6387, 63990, 19947, 63988, - 41955, 0, 63993, 10440, 9611, 65605, 6803, 0, 7738, 63986, 11446, 63984, - 92641, 3435, 78164, 43814, 43810, 7029, 64258, 41292, 118898, 12748, - 42742, 9517, 11518, 0, 78790, 0, 67993, 63956, 42458, 63954, 63953, - 63960, 9591, 4516, 10217, 68370, 11469, 69697, 42306, 2723, 118947, 0, 0, - 0, 0, 0, 11397, 2880, 0, 0, 2872, 0, 0, 3498, 4378, 917539, 4270, 0, - 65551, 68205, 6633, 43387, 0, 5230, 0, 0, 0, 0, 0, 8161, 393, 12013, 0, - 0, 126479, 415, 63964, 63963, 42345, 92310, 5183, 1877, 42498, 0, 2927, - 0, 63961, 4472, 0, 0, 78159, 69699, 917936, 42340, 4756, 128078, 7081, - 10730, 7691, 10331, 63830, 119625, 42922, 42103, 8628, 9813, 0, 42453, - 1604, 9565, 10539, 69701, 65764, 41415, 65767, 0, 8457, 42301, 11372, - 64873, 11992, 0, 0, 63980, 11801, 3622, 983124, 64336, 12017, 10463, - 63981, 4967, 64189, 1966, 43628, 0, 983292, 0, 0, 63971, 4347, 4416, - 42098, 11009, 10694, 63973, 402, 0, 13147, 128692, 42100, 64646, 13228, - 0, 41875, 3515, 74252, 11805, 0, 11302, 6259, 43395, 0, 0, 194670, 0, - 92351, 0, 74425, 11299, 1561, 0, 92359, 64942, 983559, 194733, 983686, - 194732, 0, 74301, 0, 11280, 0, 69784, 74060, 0, 0, 119664, 5145, 12486, - 65018, 66516, 5409, 127379, 194669, 7402, 5399, 9685, 74089, 7952, 5401, - 0, 66616, 68421, 983919, 0, 5405, 127875, 64866, 0, 119583, 128345, - 78784, 74248, 11330, 194723, 64690, 3254, 0, 0, 128207, 42390, 43678, - 194725, 983909, 65077, 0, 6388, 3355, 9508, 9867, 5723, 11520, 5611, 0, - 3377, 0, 0, 0, 0, 78228, 0, 983762, 42691, 917886, 127198, 74767, 0, - 127075, 1379, 246, 0, 983761, 3788, 983106, 11041, 92549, 66304, 0, 0, - 8917, 42403, 301, 0, 0, 0, 0, 0, 983697, 10656, 0, 65214, 119242, 42567, - 92217, 13163, 983204, 120831, 74597, 3182, 0, 0, 0, 65034, 65889, 42169, - 4755, 74244, 194621, 11443, 0, 66319, 74598, 608, 600, 0, 1219, 3934, - 64206, 11483, 74510, 0, 74485, 42442, 65470, 983907, 64202, 13160, 7759, - 42482, 485, 128006, 0, 9828, 0, 0, 42280, 0, 9351, 7778, 64379, 7496, - 42431, 6916, 1208, 0, 119631, 11002, 42470, 0, 118946, 0, 0, 74041, 0, - 70045, 43539, 5411, 42196, 0, 0, 0, 9150, 0, 42393, 13086, 1310, 194687, - 9337, 12052, 10643, 55271, 983179, 12166, 2546, 194683, 213, 118852, - 65611, 0, 0, 194756, 74310, 6554, 0, 11914, 5452, 0, 0, 0, 0, 0, 194681, - 92560, 2713, 0, 9650, 43330, 0, 194675, 1406, 0, 0, 92659, 0, 68223, - 4143, 194677, 0, 65748, 4141, 9682, 65287, 1508, 127013, 8779, 10569, - 8725, 13299, 66638, 65750, 42263, 4145, 6380, 65751, 66613, 43994, 65738, - 55250, 9185, 9550, 0, 43403, 0, 0, 0, 65736, 41951, 64816, 65756, 983205, - 12955, 10596, 2888, 194645, 0, 0, 9657, 9019, 194766, 0, 2878, 5390, 0, - 194961, 0, 68679, 43552, 7501, 6328, 0, 10429, 10365, 0, 0, 41946, 7503, - 5235, 803, 68381, 0, 0, 8986, 126542, 10632, 11934, 11452, 1332, 0, 0, - 126647, 0, 118887, 1791, 5191, 9288, 64822, 2892, 0, 43394, 555, 0, 0, - 66646, 0, 119002, 13151, 74512, 7289, 74055, 64161, 8854, 64162, 5858, - 41927, 10582, 0, 1784, 1361, 195047, 0, 7905, 0, 64868, 128813, 13158, - 92166, 7211, 0, 9371, 73973, 917553, 6828, 1625, 92302, 0, 1342, 68440, - 64171, 126704, 10903, 983494, 0, 0, 0, 0, 4482, 41606, 0, 128569, 983112, - 0, 64381, 0, 0, 195090, 42245, 126467, 41972, 0, 444, 0, 9127, 66687, - 66619, 126489, 78025, 0, 11349, 40991, 917570, 0, 119599, 120830, 0, - 1197, 128282, 1149, 194970, 0, 0, 40990, 43765, 0, 3492, 0, 127942, 0, 0, - 0, 12838, 983978, 19948, 0, 3099, 0, 0, 41087, 0, 0, 0, 119059, 12036, - 41309, 0, 0, 8152, 0, 41550, 12227, 983613, 0, 12828, 127511, 0, 0, - 120708, 0, 0, 10386, 119574, 0, 0, 92680, 983789, 68154, 0, 1743, 0, 0, - 92239, 65186, 917571, 0, 9606, 0, 0, 64439, 0, 0, 92686, 0, 0, 194967, 0, - 0, 3395, 9362, 10878, 0, 0, 78362, 64830, 0, 126557, 41091, 3426, 1344, - 8870, 0, 0, 4735, 127017, 6119, 12822, 42699, 0, 983824, 74818, 1423, 0, - 42637, 41080, 0, 12039, 10559, 0, 118892, 0, 9472, 0, 11929, 0, 7170, - 9596, 6130, 128826, 43629, 11579, 78713, 0, 194740, 128691, 92185, 66699, - 64440, 1004, 92584, 194737, 43234, 66008, 12627, 0, 68414, 0, 43619, - 43303, 11300, 43304, 9686, 5890, 11776, 7558, 127158, 65627, 0, 10718, - 13154, 3461, 9139, 0, 0, 0, 0, 65365, 73877, 65628, 78019, 120319, 0, - 41708, 12860, 2641, 12069, 10838, 5403, 10352, 70085, 10061, 43237, 0, - 5140, 209, 128847, 41704, 41056, 43078, 128125, 118809, 0, 10899, 65469, - 92362, 0, 0, 2410, 993, 0, 120589, 120689, 78693, 0, 0, 7232, 0, 119253, - 0, 7110, 74462, 2066, 10489, 42166, 43463, 10659, 3600, 0, 4224, 1336, - 41518, 0, 0, 0, 0, 41139, 64820, 92538, 12966, 41134, 0, 0, 0, 0, 272, - 4263, 8793, 0, 0, 41502, 0, 983, 12549, 0, 0, 1190, 4109, 1335, 841, - 5888, 41358, 64863, 9544, 43481, 0, 194806, 70027, 2099, 5120, 2409, - 7799, 0, 74424, 0, 0, 4731, 0, 66629, 0, 0, 1255, 4149, 9247, 0, 9913, 0, - 0, 64914, 917787, 65101, 0, 11694, 92475, 11690, 5835, 127164, 66625, - 10842, 41354, 42123, 43097, 11688, 66634, 1094, 194, 64692, 0, 8180, 0, - 0, 9972, 73865, 4519, 6114, 10898, 43072, 0, 0, 93960, 983322, 126581, - 10695, 0, 7540, 0, 881, 7857, 6067, 65164, 0, 0, 0, 13311, 68403, 41857, - 64321, 8359, 0, 12689, 0, 194594, 0, 983312, 983881, 68183, 0, 983314, - 1287, 5436, 0, 983317, 74142, 92328, 74152, 119078, 6051, 10497, 69668, - 8985, 12109, 983323, 0, 127242, 0, 0, 3652, 10537, 0, 1276, 120440, 6549, - 279, 73745, 0, 0, 0, 1489, 0, 0, 0, 3899, 1007, 42124, 983557, 42122, - 92337, 92367, 0, 11985, 1345, 78600, 0, 0, 8956, 43083, 94057, 42138, - 78610, 0, 12151, 78608, 78604, 78605, 6285, 78603, 78612, 78613, 65942, - 492, 8685, 0, 983759, 0, 78622, 43712, 2582, 11470, 64538, 7444, 78615, - 78616, 2297, 0, 73837, 119823, 2527, 119824, 197, 2799, 92594, 41944, - 120276, 9933, 0, 66515, 767, 5524, 7028, 0, 0, 119827, 119817, 119828, - 78633, 10896, 0, 1799, 120497, 6971, 74336, 128342, 0, 65340, 118979, - 41551, 2434, 94018, 0, 120579, 0, 4631, 0, 0, 6407, 0, 6338, 43214, 0, - 7570, 0, 3192, 0, 8414, 0, 93983, 0, 0, 0, 9164, 66612, 93959, 3171, - 6623, 4961, 68396, 886, 55216, 8654, 78832, 9993, 74390, 64603, 70066, - 69241, 9599, 78629, 43084, 78627, 78628, 78625, 2399, 69693, 8994, 10944, - 41208, 983713, 41168, 8178, 0, 3367, 92334, 42510, 78641, 78636, 6804, - 78634, 1947, 0, 0, 92681, 42759, 11068, 1705, 9331, 0, 74798, 9181, - 65359, 0, 8017, 119831, 65096, 66720, 0, 43475, 0, 4909, 12126, 128673, - 120696, 4904, 983333, 69650, 1365, 9253, 42757, 43436, 7462, 0, 0, 0, 0, - 119587, 64415, 0, 0, 5398, 0, 127386, 93953, 0, 0, 119015, 0, 0, 9476, 0, - 983777, 12763, 126603, 3629, 0, 13005, 0, 3628, 0, 0, 92502, 3469, 42107, - 42116, 917578, 64809, 2928, 4905, 9853, 851, 9040, 0, 64665, 43086, 9114, - 0, 42583, 9315, 4822, 4906, 3852, 2847, 119821, 3236, 11317, 1251, 7777, - 41852, 11410, 10964, 0, 43222, 12646, 120269, 10259, 9865, 65821, 0, - 6018, 92290, 0, 12276, 0, 68372, 0, 92259, 119244, 0, 983230, 10467, 0, - 2443, 10918, 78217, 119825, 1001, 9241, 1927, 0, 0, 73987, 127885, 0, 0, - 118828, 120271, 65678, 12867, 0, 8260, 77945, 7519, 11505, 12274, 8904, - 518, 65857, 0, 128674, 13204, 4387, 857, 0, 65369, 0, 92336, 43125, - 120592, 0, 0, 0, 0, 5136, 1968, 983041, 126627, 1337, 64967, 1629, 0, - 796, 66506, 0, 74123, 12877, 120649, 42314, 43388, 0, 74403, 6120, 478, - 65151, 68128, 128147, 43082, 6016, 0, 42284, 128507, 4276, 1206, 3619, - 41638, 69691, 3843, 12011, 8853, 3361, 0, 490, 10715, 7578, 68384, 0, - 65350, 10530, 12348, 8653, 74314, 42435, 6154, 9551, 65354, 78522, 784, - 42397, 334, 0, 42416, 65356, 65273, 77987, 69666, 4442, 10364, 0, 778, - 41626, 42455, 7989, 74063, 3227, 69907, 127275, 73983, 2915, 11502, - 41022, 41702, 10309, 127035, 78320, 0, 6975, 0, 5415, 12176, 0, 74193, - 3462, 65215, 42629, 78691, 73784, 0, 0, 9759, 0, 70057, 127254, 8114, - 78698, 78697, 78696, 78695, 8710, 42495, 118956, 0, 4051, 10460, 43364, - 118917, 1356, 12161, 42713, 128857, 127268, 1619, 9703, 43152, 42489, - 42112, 127978, 1875, 10808, 42109, 120284, 41860, 64862, 13305, 64907, - 5289, 13144, 128658, 0, 5575, 9675, 0, 5940, 226, 2649, 6336, 983277, - 119830, 43236, 3382, 42449, 6498, 1658, 11936, 78232, 0, 11269, 10151, - 73759, 43100, 69888, 65508, 0, 0, 0, 8935, 917985, 0, 0, 0, 616, 74753, - 65178, 4684, 78701, 119653, 0, 126551, 0, 6048, 74460, 42110, 73965, - 10870, 8557, 11054, 68664, 119049, 9681, 4475, 0, 41142, 2100, 0, 120731, - 6035, 0, 7651, 10296, 64443, 0, 983295, 917987, 0, 118966, 74144, 40997, - 0, 10392, 10328, 40998, 43462, 74488, 0, 9800, 8979, 0, 13307, 41000, 0, - 119239, 6487, 3386, 0, 10344, 0, 65299, 5394, 43246, 78243, 10220, 66505, - 41200, 128583, 4425, 0, 0, 0, 43074, 73799, 983200, 78147, 0, 12173, - 78545, 0, 127011, 65338, 0, 0, 119582, 4474, 0, 43093, 128644, 1587, 0, - 127372, 64475, 128098, 1369, 983672, 9959, 7927, 0, 4560, 0, 0, 92277, - 983621, 64948, 4430, 74347, 42601, 4514, 66434, 93955, 8194, 65462, - 10626, 10965, 0, 8893, 983301, 12542, 0, 65341, 0, 65829, 7925, 119822, - 10475, 0, 0, 1352, 11069, 7707, 127560, 126486, 65279, 127102, 68207, - 127100, 7099, 6040, 127097, 10071, 0, 9336, 43750, 0, 8899, 7798, 64474, - 64259, 69873, 65188, 7820, 43018, 127082, 0, 7746, 1492, 78551, 10884, - 77982, 0, 5127, 11285, 42501, 5495, 4273, 43095, 41426, 10849, 5730, - 2999, 6342, 68636, 74304, 371, 64373, 6023, 169, 5497, 11708, 0, 0, 6323, - 194684, 8224, 0, 8938, 6043, 12738, 0, 983076, 5321, 0, 194798, 0, 2589, - 74332, 1689, 7802, 4683, 74318, 42704, 120296, 11905, 0, 0, 128516, - 128163, 74513, 6049, 0, 4027, 834, 118962, 1803, 0, 1503, 0, 0, 71312, - 5731, 1381, 2387, 0, 0, 8289, 64525, 65817, 2881, 43142, 0, 9601, 2879, - 9668, 9766, 0, 5729, 917833, 74410, 6036, 64881, 4026, 9361, 127091, - 2887, 0, 3526, 6298, 0, 77897, 120095, 78519, 0, 8572, 6021, 77896, - 128288, 77895, 43155, 0, 119849, 3146, 10959, 9483, 0, 77893, 10981, 166, - 917841, 8635, 983606, 10623, 408, 119058, 127507, 13298, 0, 7426, 41641, - 12717, 0, 7607, 10639, 43396, 0, 0, 41643, 74134, 983054, 8713, 41640, - 10221, 41645, 66712, 6645, 646, 66726, 66711, 42129, 93994, 77901, 3472, - 8697, 0, 0, 983815, 0, 0, 0, 5809, 1950, 119356, 92432, 74572, 0, 42136, - 0, 0, 0, 0, 3247, 119854, 65017, 983953, 68428, 66668, 0, 0, 10983, 0, 0, - 0, 41567, 0, 0, 0, 194624, 119853, 0, 0, 8285, 0, 4509, 0, 66471, 12216, - 0, 40988, 92592, 74809, 41727, 0, 42848, 2396, 917766, 0, 74018, 917538, - 64940, 7027, 3886, 0, 42457, 119008, 0, 996, 68123, 94058, 4249, 0, - 917594, 11707, 8222, 0, 7939, 92454, 92460, 127801, 917592, 128359, 8534, - 127154, 40983, 0, 983240, 0, 7201, 12561, 0, 42371, 12558, 1540, 917549, - 10052, 40982, 0, 0, 1488, 0, 0, 0, 917559, 0, 0, 1563, 128034, 9619, - 983940, 0, 0, 127872, 71363, 5803, 7797, 6070, 10006, 0, 2922, 6082, 0, - 65009, 983942, 12567, 128703, 0, 41412, 0, 0, 3607, 9200, 10046, 9612, - 42153, 8218, 9485, 0, 2032, 78354, 0, 0, 0, 0, 0, 43085, 6057, 508, - 93968, 128015, 67968, 0, 92405, 0, 0, 638, 6083, 119072, 0, 0, 2305, - 78348, 68096, 0, 6056, 6659, 67969, 0, 6085, 0, 0, 3915, 41634, 0, 41639, - 63912, 11941, 0, 4028, 1787, 42180, 43096, 43753, 3249, 1768, 93982, - 12328, 501, 93985, 10601, 0, 583, 0, 41977, 0, 66004, 119350, 6505, - 74010, 0, 13064, 55267, 120810, 6500, 5526, 65049, 0, 73764, 0, 92376, - 12745, 9678, 0, 120587, 9869, 128815, 1771, 0, 8936, 0, 0, 4208, 78341, - 78567, 78342, 0, 983456, 74101, 0, 11762, 0, 92422, 77997, 68010, 66475, - 0, 5027, 78172, 128878, 0, 5069, 73862, 5028, 9897, 0, 73739, 5026, - 983253, 68639, 6331, 10079, 8931, 0, 1415, 8866, 41901, 74790, 78138, - 119361, 983564, 43106, 5029, 65309, 1580, 3598, 68424, 41070, 77903, 0, - 3440, 78215, 1562, 128656, 127175, 119358, 1716, 983679, 10600, 917867, - 620, 41001, 6028, 0, 42892, 0, 74822, 5024, 120829, 41003, 0, 5025, - 69892, 983209, 0, 118885, 0, 65557, 0, 74541, 983587, 11599, 128209, - 11602, 6243, 11574, 11581, 11597, 11598, 6253, 6105, 11584, 74195, 11569, - 65275, 8906, 127096, 5755, 2636, 983227, 10815, 11619, 2301, 41540, 7815, - 11616, 6979, 12080, 7721, 11604, 7869, 1592, 0, 42152, 78498, 41048, - 917763, 829, 0, 92406, 19950, 0, 126482, 6616, 0, 118875, 10953, 391, 0, - 69785, 482, 42296, 11588, 0, 43606, 0, 68397, 66370, 74506, 42335, - 983188, 0, 0, 7538, 5315, 120644, 42491, 0, 42061, 128088, 4576, 0, - 68417, 43809, 4277, 0, 4039, 64472, 42338, 368, 42058, 3960, 11043, - 11337, 78209, 917820, 63989, 3958, 12132, 1849, 0, 9921, 42451, 4253, - 41147, 42064, 11959, 42404, 41160, 0, 3618, 78338, 0, 43300, 5156, 92629, - 0, 929, 6827, 42035, 42437, 1555, 0, 8691, 66435, 2215, 41662, 94010, 0, - 0, 0, 93952, 4578, 64513, 41664, 983734, 42578, 128794, 41661, 78715, - 43267, 9356, 0, 0, 0, 1286, 10166, 0, 0, 64707, 983127, 42476, 7730, - 983859, 128522, 42483, 0, 0, 42324, 42291, 10020, 43359, 0, 6641, 525, - 41627, 917923, 8763, 128304, 41628, 533, 11931, 65225, 8321, 42504, - 42581, 0, 6915, 42310, 4377, 8559, 0, 74360, 0, 13193, 64350, 11666, - 8679, 41924, 1576, 7735, 92398, 0, 73840, 983092, 11374, 78043, 10889, - 43461, 7757, 42462, 120226, 10029, 66493, 2718, 4168, 73842, 13308, - 120112, 0, 1179, 4440, 0, 77948, 363, 11015, 77947, 77944, 64296, 127090, - 66692, 120826, 0, 66492, 6593, 64625, 41963, 92177, 119329, 0, 10013, - 64434, 92520, 127095, 9492, 11782, 64382, 12833, 77830, 0, 1297, 41630, - 630, 127094, 0, 120774, 92465, 1043, 43652, 66223, 10090, 0, 128664, 313, - 917563, 41881, 0, 42311, 7445, 0, 5750, 10759, 9419, 55222, 9405, 11268, - 42919, 9398, 8526, 9399, 9422, 0, 66495, 0, 0, 127239, 41718, 10707, - 1603, 0, 119003, 0, 631, 77952, 69703, 13161, 65272, 0, 10546, 74210, - 78101, 11600, 77961, 2797, 73821, 42427, 306, 714, 3058, 42381, 77962, - 127080, 12351, 42395, 0, 11607, 0, 42282, 77971, 77967, 9157, 73765, - 66364, 42433, 77964, 7603, 12803, 180, 42141, 0, 120612, 66494, 12674, - 8244, 362, 92439, 0, 8037, 43777, 11535, 0, 74845, 5185, 7165, 5521, - 10334, 2093, 71329, 10302, 128112, 10104, 1027, 5181, 0, 0, 10523, 1446, - 42320, 41646, 991, 5189, 42472, 41647, 120105, 1722, 5581, 42898, 3405, - 0, 194644, 5523, 0, 42620, 92447, 983819, 9549, 0, 10549, 55282, 9661, - 43682, 0, 77910, 120026, 78708, 0, 77911, 0, 41991, 983893, 0, 7630, - 9846, 7684, 10350, 0, 1174, 77981, 42733, 77978, 77980, 66485, 77977, - 42277, 77974, 42456, 65667, 127037, 12330, 128272, 0, 42417, 42383, - 66630, 41344, 6293, 0, 66252, 77984, 74443, 0, 10209, 8313, 4195, 74435, - 1316, 66690, 120032, 6332, 64894, 0, 65871, 78060, 1736, 983684, 3901, - 12228, 120151, 65200, 3383, 10446, 78841, 693, 9130, 314, 64149, 42420, - 11949, 983669, 120152, 11026, 128788, 5332, 6940, 64154, 12635, 127007, - 42706, 1751, 273, 8165, 13166, 120763, 78840, 71368, 12824, 0, 4528, - 5320, 6301, 43662, 6133, 9339, 9463, 42346, 10922, 64560, 3757, 0, 0, 0, - 65869, 73760, 2569, 0, 2326, 65740, 2565, 42459, 7596, 7921, 983868, - 74095, 127981, 41848, 2567, 66006, 0, 4044, 92646, 0, 12233, 983871, - 1023, 474, 0, 119818, 0, 0, 42487, 65556, 0, 127866, 42295, 0, 0, 71322, - 92518, 9835, 66499, 0, 5417, 12275, 10895, 0, 274, 0, 1858, 0, 0, 55251, - 10118, 3133, 128008, 73795, 0, 9610, 8068, 8197, 0, 699, 0, 41665, 5868, - 0, 92695, 42182, 7581, 19940, 43668, 41667, 128057, 0, 1923, 65583, - 65802, 93970, 64597, 43444, 119184, 92197, 0, 6464, 7036, 2996, 1937, - 983751, 0, 41835, 4047, 41842, 0, 64107, 0, 0, 11017, 120601, 0, 293, - 77966, 92169, 64791, 41827, 42466, 43422, 10579, 8560, 71350, 65413, - 77963, 4803, 12964, 1739, 1941, 3900, 0, 1713, 77969, 0, 73957, 11407, - 42441, 41971, 6297, 120098, 64105, 128080, 42481, 11716, 66473, 7179, - 42289, 0, 64103, 969, 0, 9352, 0, 6165, 64100, 0, 6632, 73861, 42402, - 74327, 7806, 0, 8914, 0, 0, 3183, 1435, 64876, 2969, 6046, 64441, 6208, - 67849, 5746, 73749, 0, 64416, 42422, 0, 983046, 7082, 73775, 338, 5059, - 194719, 0, 42328, 10767, 0, 8115, 0, 74758, 0, 8227, 2073, 1218, 917790, - 0, 65848, 0, 0, 69863, 0, 126987, 4486, 0, 0, 0, 10925, 0, 0, 0, 983586, - 42309, 10257, 65191, 10273, 0, 10305, 42461, 0, 42349, 8832, 78051, - 64127, 10644, 42662, 78828, 42278, 74451, 126988, 69874, 7794, 0, 42429, - 6377, 42316, 119026, 3669, 3968, 42468, 71319, 69658, 0, 65402, 119581, - 0, 0, 64933, 0, 41960, 6699, 0, 0, 128354, 6823, 42391, 1588, 65400, - 8409, 78223, 19967, 65398, 787, 71315, 917939, 127744, 6115, 2078, 41654, - 42480, 0, 92650, 41655, 65401, 43975, 0, 0, 0, 644, 65500, 41657, 10778, - 3659, 9533, 184, 1553, 13107, 65484, 69648, 10502, 74457, 0, 0, 41554, 0, - 8220, 917943, 41557, 0, 0, 11070, 119221, 5157, 4020, 73858, 41555, 9514, - 64818, 65103, 64641, 64303, 78131, 7520, 0, 74377, 11029, 66651, 983068, - 0, 118930, 64527, 0, 7877, 73803, 983798, 127348, 120096, 74602, 9955, - 119557, 4055, 42817, 0, 65212, 11715, 12190, 12319, 78630, 0, 78631, - 9502, 65427, 0, 65424, 12607, 0, 9734, 65425, 0, 0, 127357, 78835, 92410, - 10112, 10827, 0, 9866, 74527, 66675, 0, 8625, 64346, 11290, 10477, 0, - 8636, 983927, 8315, 65444, 983793, 0, 74595, 6152, 0, 0, 6629, 127108, - 120171, 0, 74589, 43993, 0, 69790, 64435, 0, 43690, 11046, 11490, 42730, - 4485, 127107, 0, 64926, 0, 0, 0, 5869, 12437, 42728, 0, 7040, 3588, 0, - 12825, 0, 0, 12725, 0, 127106, 78642, 223, 0, 69675, 120166, 42444, 0, - 64499, 65245, 0, 1171, 0, 69717, 0, 1805, 8772, 43820, 0, 9930, 65247, - 78619, 120111, 2338, 0, 118853, 0, 42676, 0, 64800, 65236, 67644, 68126, - 1213, 0, 64075, 797, 64074, 8734, 4212, 127369, 64387, 4115, 0, 5005, - 64070, 64073, 10679, 0, 77954, 9402, 64276, 426, 0, 0, 8251, 10136, - 65436, 0, 2120, 43302, 1224, 0, 65576, 74192, 10701, 1764, 3101, 127815, - 12858, 120159, 0, 11373, 6378, 127859, 120103, 8663, 9312, 41644, 4539, - 2129, 0, 9222, 983738, 0, 4259, 9092, 74567, 41961, 0, 12724, 66357, - 42331, 64935, 0, 0, 1293, 7947, 2132, 983767, 74593, 120308, 2454, 42717, - 3613, 128837, 0, 0, 65888, 8816, 10978, 10840, 0, 10668, 0, 43087, 12595, - 120304, 983114, 8822, 0, 1157, 64903, 8638, 0, 0, 0, 0, 69848, 8235, - 120316, 4405, 10086, 120247, 0, 69216, 0, 65430, 71321, 6079, 6817, - 10764, 127910, 64291, 128051, 998, 120312, 11062, 1317, 64327, 1558, 0, - 1991, 7882, 42254, 0, 41700, 530, 0, 10428, 119335, 12002, 119336, 5742, - 43076, 4692, 64630, 41823, 4007, 5004, 119334, 7896, 751, 6595, 6596, - 120325, 66373, 0, 0, 64908, 92691, 6311, 0, 12004, 119192, 12049, 43108, - 120326, 0, 41705, 92188, 6598, 0, 6599, 120334, 0, 42148, 118825, 66027, - 0, 6597, 9412, 8340, 11824, 64745, 2281, 69904, 0, 1988, 5407, 67865, - 2430, 41678, 0, 120243, 2336, 983903, 0, 78871, 120442, 983769, 1921, - 10947, 19927, 0, 65406, 0, 19913, 4284, 13217, 0, 43789, 12841, 9229, - 10956, 42285, 41674, 19964, 41679, 65084, 3521, 0, 5774, 8325, 0, 65403, - 983089, 1854, 10794, 0, 67660, 69846, 0, 78359, 5280, 0, 4344, 12905, + 43825, 71085, 119337, 5236, 40979, 983140, 71874, 8286, 128537, 3936, + 119331, 11699, 41347, 69739, 13235, 8842, 41248, 0, 4379, 13239, 12692, + 7969, 127266, 7219, 71875, 128251, 120509, 92907, 66224, 734, 2979, + 120303, 65619, 9872, 957, 64921, 1846, 66631, 41477, 119256, 71192, + 74511, 41770, 1670, 6442, 120317, 42446, 5379, 120318, 41163, 74832, + 11136, 71876, 11506, 128395, 42841, 13267, 128421, 0, 41775, 0, 7130, + 41773, 0, 10663, 70130, 0, 983974, 6151, 12110, 42673, 65572, 65293, + 65250, 13265, 13264, 64518, 0, 6100, 127964, 92647, 5808, 65922, 67814, + 12967, 66041, 5612, 4583, 70004, 43386, 68097, 64575, 126637, 11965, + 194930, 68358, 71483, 69789, 42653, 83181, 68102, 9698, 7814, 71045, + 119651, 128514, 0, 41921, 118858, 9756, 6985, 66418, 66621, 74219, 66412, + 128822, 118997, 8012, 5674, 12353, 66421, 12361, 5677, 5588, 92348, + 41925, 128124, 41920, 5673, 83113, 5676, 41923, 12694, 118978, 5672, + 1294, 0, 78059, 983962, 42511, 1727, 120725, 42436, 121400, 121183, 0, + 74222, 8718, 3550, 736, 10268, 4505, 5873, 74090, 5826, 55232, 5813, + 129032, 92889, 5841, 5837, 55234, 194864, 3105, 12829, 5838, 5796, 0, + 119592, 5793, 0, 5866, 5797, 41011, 5865, 93009, 7956, 598, 0, 64649, + 5806, 42398, 0, 9037, 5671, 120041, 983257, 83478, 983929, 83184, 0, 847, + 128242, 9529, 83018, 66657, 6980, 78483, 43510, 78122, 92219, 0, 67411, + 78486, 83017, 127260, 120039, 42683, 71848, 983055, 7114, 126521, 0, + 43190, 65463, 1554, 0, 42611, 42563, 0, 5651, 2929, 6792, 43201, 75059, + 19963, 5698, 194768, 983272, 92933, 71887, 5644, 10292, 65546, 69727, + 68141, 8372, 0, 65116, 0, 70304, 10175, 10388, 42799, 94100, 41013, + 10568, 0, 983618, 2869, 917843, 41015, 74473, 2785, 4366, 0, 10954, + 41802, 983652, 42608, 78468, 9884, 4759, 73768, 120296, 10266, 41359, + 1170, 43365, 69810, 73908, 1609, 902, 92773, 63936, 83247, 11661, 8122, + 5818, 83245, 0, 3861, 9540, 11028, 2554, 5158, 5714, 2213, 983966, 0, + 807, 43079, 78092, 78475, 976, 5511, 64553, 120863, 42155, 983319, 41356, + 74110, 118801, 71043, 120080, 8676, 983293, 94002, 5582, 451, 63941, + 5798, 9349, 42018, 127858, 128521, 78681, 43609, 5906, 120553, 1440, 0, + 128853, 74933, 70342, 11005, 194699, 66656, 66044, 194636, 120079, + 128793, 0, 43393, 10094, 70164, 11529, 10857, 92944, 66436, 6546, 93, + 8102, 67323, 68405, 0, 194714, 8171, 118888, 119097, 82996, 917543, 383, + 7154, 41656, 43495, 94040, 67162, 5187, 71296, 71086, 11286, 68620, + 64217, 0, 5232, 0, 41009, 127377, 41005, 983810, 0, 128471, 8292, 125108, + 4980, 8860, 71054, 10028, 65291, 7076, 13182, 194705, 74912, 127974, + 10631, 11244, 7972, 68042, 78785, 0, 7900, 128590, 11309, 3806, 4198, + 42725, 0, 67656, 9995, 0, 92552, 0, 12931, 121110, 42684, 74285, 2088, + 64213, 64366, 65156, 8814, 42238, 74771, 127920, 194713, 12836, 0, + 113800, 74342, 8593, 0, 0, 68445, 13255, 121333, 128843, 7464, 0, 65865, + 0, 194650, 127144, 92395, 9342, 120464, 70376, 64516, 0, 78792, 10129, + 41007, 74375, 983701, 40995, 12209, 41012, 83501, 0, 83257, 69724, 40992, + 92264, 119136, 68653, 43558, 5522, 75026, 61, 120959, 74105, 3633, + 120082, 65162, 41234, 12089, 78281, 9771, 83281, 13251, 128701, 0, 6262, + 2784, 42743, 71078, 8126, 66483, 0, 0, 441, 42621, 0, 0, 41002, 40999, + 119623, 43266, 7108, 194779, 10890, 74481, 65834, 8324, 118944, 64417, + 74817, 127465, 64737, 74853, 983659, 8930, 66678, 67216, 1193, 10056, + 1800, 13253, 13252, 7829, 120992, 121175, 7743, 83502, 124996, 77904, + 77913, 77905, 9034, 6039, 129139, 10075, 0, 41018, 65683, 10338, 66469, + 0, 0, 194637, 42815, 92984, 41966, 0, 127471, 0, 11792, 43064, 41025, + 911, 7539, 0, 40963, 120339, 65159, 64390, 0, 983160, 5520, 11662, + 127473, 65330, 42812, 983215, 0, 12326, 71081, 194638, 42808, 128337, + 9348, 64901, 983861, 983892, 121050, 66839, 0, 0, 121004, 43702, 983148, + 5857, 65342, 92727, 119120, 83503, 8644, 121227, 83332, 11186, 74296, + 41909, 0, 66900, 2791, 69663, 1891, 69824, 66397, 41907, 66647, 118939, + 8761, 12942, 5748, 92713, 10773, 70868, 83174, 8796, 78149, 6412, 2061, + 8520, 13146, 127096, 63931, 83275, 65902, 2882, 83334, 0, 12843, 4520, + 120345, 92459, 0, 983660, 0, 73860, 83335, 0, 64345, 0, 9201, 128314, + 70871, 0, 917864, 43679, 121026, 65117, 92270, 0, 10427, 121506, 3844, + 6842, 9755, 1110, 6612, 12222, 93030, 128789, 983638, 92928, 783, 194935, + 92185, 127221, 73855, 68032, 65056, 3620, 41180, 68378, 4556, 67839, + 68480, 194933, 74250, 0, 67657, 10510, 4382, 66482, 67823, 0, 127527, + 9177, 8902, 93958, 9839, 120700, 12891, 983755, 983636, 63999, 2016, + 41917, 9788, 63928, 67696, 1862, 65800, 9155, 66623, 9786, 65082, 41919, + 8579, 41914, 7981, 0, 66017, 4508, 64883, 92456, 92522, 127814, 120834, + 64592, 74276, 67688, 6784, 78788, 68181, 0, 71218, 113821, 66366, 12147, + 9024, 66378, 66472, 124976, 64289, 65289, 78151, 66658, 71935, 64509, + 78152, 113697, 126505, 11051, 194928, 0, 11355, 65885, 121319, 127941, + 41214, 0, 12299, 0, 7500, 4506, 7773, 0, 0, 9963, 68649, 126609, 4040, + 120570, 6167, 74519, 63922, 6594, 983740, 0, 0, 3624, 43036, 129472, + 6387, 63990, 19947, 63988, 41955, 126990, 63993, 10440, 9611, 65605, + 6803, 120968, 7738, 63986, 11446, 63984, 92641, 3435, 78164, 43814, + 43810, 7029, 64258, 41292, 118898, 12748, 42742, 9517, 11518, 83292, + 78790, 983381, 67993, 63956, 42458, 63954, 63953, 63960, 9591, 4516, + 10217, 68370, 11469, 69697, 42306, 2723, 118947, 0, 92325, 0, 68079, + 121344, 11397, 2880, 70806, 917829, 2872, 0, 83321, 3498, 4378, 917539, + 4270, 0, 65551, 68205, 6633, 43387, 0, 5230, 194991, 0, 983040, 194910, + 121392, 8161, 393, 12013, 0, 983198, 119103, 415, 63964, 63963, 42345, + 92310, 5183, 1877, 42498, 0, 2927, 71058, 63961, 4472, 983299, 0, 78159, + 69699, 127301, 42340, 4756, 128078, 7081, 10730, 7691, 10331, 63830, + 119625, 42922, 42103, 8628, 9813, 78654, 42453, 1604, 9565, 10539, 69701, + 65764, 41415, 65767, 129196, 8457, 42301, 11372, 64873, 11992, 0, 0, + 63980, 11801, 3622, 195092, 64336, 12017, 10463, 63981, 4967, 64189, + 1966, 43628, 983908, 983294, 83267, 121052, 63971, 4347, 4416, 42098, + 11009, 10694, 63973, 402, 92213, 13147, 128692, 42100, 64646, 13228, 0, + 41875, 3515, 74252, 11805, 983157, 11302, 6259, 43395, 0, 83323, 194670, + 120836, 92351, 74813, 74425, 11299, 1561, 118881, 92318, 64942, 93021, + 194733, 70411, 78718, 121140, 74301, 68825, 11280, 128489, 69784, 74060, + 128392, 0, 119664, 5145, 12486, 65018, 66516, 5409, 127379, 124988, 7402, + 5399, 9685, 74089, 7952, 5401, 0, 66616, 66832, 92966, 120852, 5405, + 127875, 64866, 120965, 119583, 119122, 78784, 74248, 11330, 194723, + 64690, 3254, 983166, 128944, 92696, 42390, 43678, 194725, 129127, 65077, + 129059, 6388, 3355, 9508, 9867, 5723, 11520, 5611, 83021, 3377, 0, 0, + 74354, 194578, 78228, 983722, 983762, 42691, 127886, 120948, 68091, + 128404, 75023, 1379, 246, 74649, 983761, 3788, 92520, 11041, 67202, + 66304, 0, 121213, 8917, 42403, 301, 0, 128500, 127046, 0, 0, 113822, + 10656, 125042, 65214, 92987, 42567, 92217, 13163, 983204, 120831, 74597, + 3182, 0, 0, 0, 65034, 65889, 42169, 4755, 74244, 194574, 11443, 983603, + 66319, 6841, 608, 600, 0, 1219, 3934, 64206, 11483, 74510, 119117, 74485, + 42442, 65470, 983907, 64202, 13160, 7759, 42482, 485, 69982, 70505, 9828, + 0, 43505, 42280, 0, 9351, 7778, 64379, 7496, 42431, 6916, 1208, 0, + 119631, 11002, 42470, 0, 68315, 0, 0, 74041, 83144, 70045, 43539, 5411, + 42196, 0, 0, 0, 9150, 66831, 42393, 13086, 1310, 66848, 9337, 12052, + 10643, 55271, 128951, 12166, 2546, 194683, 213, 118852, 65611, 83316, + 194822, 194756, 74310, 6554, 94059, 11914, 5452, 0, 0, 92772, 0, 917880, + 194681, 92560, 2713, 119564, 9650, 43330, 121033, 128505, 1406, 125007, + 42925, 74638, 194593, 66256, 4143, 128136, 194762, 65748, 4141, 9682, + 65287, 1508, 127013, 8779, 10569, 8725, 13299, 66638, 65750, 42263, 4145, + 6380, 65751, 66613, 43994, 65738, 55250, 9185, 9550, 42932, 43403, 0, 0, + 194783, 65736, 41951, 64816, 65756, 983205, 12955, 10596, 2888, 83190, 0, + 121354, 9657, 9019, 121154, 0, 2878, 5390, 0, 194961, 67325, 68679, + 43552, 7501, 6328, 194960, 10429, 10365, 0, 0, 41946, 7503, 5235, 803, + 68381, 0, 0, 8986, 43838, 10632, 11934, 11452, 1332, 0, 194970, 126647, + 0, 118887, 1791, 5191, 9288, 64822, 2892, 83192, 43394, 555, 0, 0, 66646, + 128980, 119002, 13151, 74512, 7289, 74055, 64161, 8854, 64162, 5858, + 41927, 10582, 120457, 1784, 1361, 120921, 121516, 7905, 0, 64868, 128813, + 13158, 92166, 7211, 71884, 9371, 73973, 128441, 6828, 1625, 7664, 128768, + 1342, 68440, 64171, 92642, 10903, 983496, 0, 92527, 0, 70438, 4482, + 41606, 128934, 125033, 121475, 0, 64381, 983940, 194974, 195090, 42245, + 126467, 41972, 0, 444, 983439, 9127, 66687, 66619, 126489, 78025, 0, + 11349, 40991, 917570, 0, 70177, 120830, 0, 1197, 128282, 1149, 68316, 0, + 983258, 40990, 43765, 121262, 3492, 917906, 118784, 129026, 0, 983566, + 12838, 67208, 19948, 41677, 3099, 0, 0, 41087, 0, 0, 983261, 119059, + 12036, 41309, 128161, 0, 8152, 0, 41550, 12227, 983613, 0, 12828, 127511, + 75015, 120964, 120708, 0, 0, 10386, 75068, 119955, 127303, 92680, 983134, + 68154, 127876, 1743, 0, 0, 92239, 65186, 917571, 0, 9606, 0, 70052, + 64439, 128864, 68062, 92686, 983875, 0, 43866, 128881, 0, 3395, 9362, + 10878, 43260, 0, 78362, 64830, 0, 125046, 41091, 3426, 1344, 8870, + 121100, 71344, 4735, 11111, 6119, 12822, 42699, 0, 983824, 74818, 1423, + 128923, 42637, 41080, 0, 12039, 10559, 128634, 118892, 0, 9472, 67734, + 11929, 126557, 7170, 9596, 6130, 128826, 43629, 11579, 71475, 0, 92501, + 125081, 78046, 66699, 64440, 1004, 92584, 194736, 43234, 66008, 12627, 0, + 68414, 74614, 43619, 43303, 11300, 43304, 9686, 5890, 11776, 7558, 70109, + 65627, 0, 10718, 13154, 3461, 9139, 0, 983094, 0, 119023, 65365, 73877, + 65628, 78019, 119272, 83118, 41708, 12860, 2641, 12069, 10838, 5403, + 10352, 70085, 10061, 43237, 125057, 5140, 209, 128847, 41704, 41056, + 43078, 127789, 118809, 67232, 10899, 65469, 70125, 0, 0, 2410, 993, + 83117, 120589, 120689, 78693, 0, 0, 7232, 0, 119253, 124963, 7110, 74462, + 2066, 10489, 42166, 43463, 10659, 3600, 68863, 4224, 1336, 41518, 121311, + 0, 0, 0, 41139, 64820, 92538, 12966, 41134, 0, 0, 119153, 120441, 272, + 4263, 8793, 983856, 0, 41502, 128133, 983, 12549, 124940, 0, 1190, 4109, + 1335, 841, 5888, 41358, 64863, 9544, 43481, 0, 120926, 70027, 2099, 5120, + 2409, 7799, 0, 74424, 0, 121041, 4731, 92279, 66629, 128127, 92525, 1255, + 4149, 9247, 74977, 9913, 983828, 121101, 64914, 917787, 65101, 113714, + 11694, 92475, 11690, 5835, 127164, 66625, 10842, 41354, 42123, 43097, + 11688, 66634, 1094, 194, 64692, 917900, 8180, 125055, 0, 9972, 73865, + 4519, 6114, 10898, 43072, 92465, 0, 93960, 983324, 126581, 10695, 0, + 7540, 0, 881, 7857, 6067, 65164, 0, 917897, 129134, 13311, 68403, 41857, + 64321, 8359, 83286, 12689, 983312, 11245, 128105, 983314, 71859, 68183, + 983415, 194829, 1287, 5436, 0, 71097, 74142, 92328, 74152, 70205, 6051, + 10497, 69668, 8985, 12109, 82962, 128908, 93043, 121013, 0, 3652, 10537, + 120282, 1276, 120440, 6549, 279, 73745, 0, 128664, 83244, 1489, 0, 0, 0, + 3899, 1007, 42124, 43828, 42122, 92337, 92367, 0, 11985, 1345, 78600, + 119832, 917563, 8956, 43083, 94057, 42138, 78610, 129131, 6430, 78608, + 78604, 78605, 6285, 78603, 78612, 78613, 65942, 492, 8685, 128481, + 121270, 0, 75027, 43712, 2582, 11470, 64538, 7444, 78615, 78616, 2297, 0, + 73837, 119823, 2527, 119824, 197, 2799, 92594, 41944, 83152, 9933, 74011, + 66515, 767, 5524, 7028, 0, 92168, 119827, 119817, 92950, 78633, 10896, 0, + 1799, 120497, 6971, 74336, 128342, 0, 65340, 118979, 41551, 2434, 94018, + 118823, 65353, 0, 4631, 118996, 0, 6407, 113737, 6338, 43214, 0, 7570, 0, + 3192, 120330, 8414, 983392, 93983, 195043, 0, 0, 9164, 66612, 93959, + 3171, 6623, 4961, 68396, 886, 55216, 8654, 78832, 9993, 74390, 64603, + 70066, 69241, 9599, 78629, 43084, 78627, 78628, 78625, 2399, 69693, 8994, + 10944, 41208, 983713, 41168, 8178, 74859, 3367, 92334, 42510, 78641, + 78636, 6804, 70475, 1947, 917579, 0, 92681, 42759, 11068, 1705, 9331, 0, + 74798, 9181, 65359, 125065, 8017, 119831, 65096, 66720, 68223, 43475, + 917548, 4909, 12126, 127540, 120696, 4904, 92961, 43503, 1365, 9253, + 42757, 43436, 7462, 127772, 0, 0, 83173, 66845, 64415, 120500, 83172, + 5398, 125035, 127386, 93953, 127362, 983782, 119015, 83171, 127007, 9476, + 983887, 120695, 12763, 126603, 3629, 120844, 13005, 11181, 3628, 0, 0, + 92502, 3469, 42107, 42116, 917578, 64809, 2928, 4905, 9853, 851, 9040, + 120372, 64665, 43086, 9114, 43870, 42583, 9315, 4822, 4906, 3852, 2847, + 119821, 3236, 11317, 1251, 7777, 41852, 11410, 10964, 0, 43222, 12646, + 120269, 10259, 9865, 65821, 75046, 6018, 68293, 125010, 12276, 119110, + 68372, 128255, 92259, 71893, 0, 119828, 10467, 0, 2443, 10918, 78217, + 77947, 1001, 9241, 1927, 0, 124942, 73987, 127882, 71895, 93012, 7992, + 77943, 43939, 12867, 128649, 8260, 77945, 7519, 11505, 12274, 8904, 518, + 65857, 128361, 128674, 13204, 4387, 857, 121252, 65369, 0, 92336, 43125, + 11842, 0, 71072, 121462, 0, 5136, 1968, 128906, 126627, 1337, 64967, + 1629, 0, 796, 66506, 0, 74123, 12877, 120649, 42314, 43388, 43826, 43944, + 6120, 478, 65151, 68128, 128147, 43082, 6016, 0, 42284, 71894, 4276, + 1206, 3619, 41638, 69691, 3843, 12011, 8853, 3361, 0, 490, 10715, 7578, + 68384, 92754, 65350, 10530, 12348, 8653, 68245, 42435, 6154, 9551, 65354, + 78522, 784, 42397, 334, 121084, 42416, 65356, 65273, 43937, 69666, 4442, + 10364, 43935, 778, 41626, 42455, 7989, 74063, 3227, 69907, 43932, 11102, + 2915, 11502, 41022, 41702, 10309, 127035, 75032, 120273, 6975, 0, 5415, + 12176, 983709, 74193, 3462, 43940, 42629, 78691, 71175, 43942, 127256, + 9759, 127255, 70057, 121442, 8114, 78698, 78697, 78696, 78695, 8710, + 42495, 118956, 70189, 4051, 10460, 43364, 71206, 1356, 12161, 42713, + 128857, 127268, 1619, 9703, 43152, 42489, 42112, 64436, 1875, 10808, + 42109, 120284, 41860, 64862, 13305, 64907, 5289, 13144, 128658, 983224, + 5575, 9675, 71129, 5940, 226, 2649, 6336, 983279, 92979, 43236, 3382, + 42449, 6498, 1658, 11936, 78232, 113814, 11269, 10151, 73759, 43100, + 69888, 65508, 983143, 0, 121451, 8935, 78234, 0, 983757, 0, 616, 74753, + 65178, 4684, 78701, 119653, 74631, 126551, 124992, 6048, 74460, 42110, + 73965, 10870, 8557, 11054, 68664, 75051, 9681, 4475, 67429, 41142, 2100, + 125024, 120731, 6035, 73796, 7651, 6846, 64443, 983957, 983296, 917987, + 0, 118966, 74144, 40997, 68488, 10392, 10328, 40998, 43462, 74488, 71182, + 9800, 8979, 0, 13307, 41000, 0, 5114, 6487, 3386, 129094, 10344, 0, 5115, + 5394, 43246, 78243, 5113, 66505, 41200, 128582, 4425, 194669, 0, 0, + 43074, 73799, 129076, 78147, 5112, 12173, 78545, 128771, 66824, 65338, + 983676, 0, 119582, 4474, 128936, 43093, 43964, 1587, 0, 127372, 64475, + 119217, 1369, 983672, 9959, 7927, 43963, 4560, 120793, 67811, 92277, + 983621, 64948, 4430, 43961, 42601, 4514, 66434, 93955, 8194, 65462, + 10626, 10965, 120905, 8893, 983303, 12542, 0, 65341, 67703, 65829, 7925, + 119822, 10475, 113825, 127011, 1352, 11069, 7707, 127560, 126486, 65279, + 127102, 68207, 74956, 7099, 6040, 67681, 10071, 78554, 9336, 43750, + 121074, 8899, 7798, 64474, 64259, 69873, 65188, 7820, 43018, 127082, + 128898, 7746, 1492, 78551, 10884, 75075, 66866, 5127, 11285, 42501, 5495, + 4273, 43095, 41426, 10849, 5730, 2999, 6342, 68636, 74304, 371, 64373, + 6023, 169, 5497, 11708, 75028, 128603, 6323, 129065, 8224, 128417, 8938, + 6043, 12738, 120671, 983076, 5321, 68645, 194798, 120251, 2589, 74332, + 1689, 7802, 4683, 74318, 42704, 92940, 11905, 983615, 0, 128516, 128163, + 74513, 6049, 0, 4027, 834, 118962, 1803, 983822, 1503, 78336, 127173, + 71312, 5731, 1381, 2387, 126610, 70808, 8289, 64525, 65817, 2881, 43142, + 0, 9601, 2879, 9668, 9766, 0, 5729, 129110, 71230, 6036, 64881, 4026, + 9361, 127091, 2887, 70389, 3526, 6298, 119851, 77897, 120095, 78519, + 118964, 8572, 6021, 77896, 128288, 71174, 43155, 0, 71197, 3146, 10959, + 9483, 83219, 77893, 10981, 166, 917841, 8635, 917840, 10623, 408, 119058, + 127507, 13298, 127253, 7426, 41641, 12717, 983795, 7607, 10639, 43396, + 129300, 119089, 41643, 74134, 983054, 8713, 41640, 10221, 41645, 66293, + 6645, 646, 66726, 66711, 42129, 68255, 77901, 3472, 8697, 0, 120936, + 121069, 0, 118859, 0, 5809, 1950, 119356, 92432, 68339, 128943, 42136, + 121440, 0, 0, 0, 3247, 92402, 65017, 128794, 68428, 66668, 0, 121112, + 10983, 0, 128787, 0, 41567, 119852, 0, 0, 78446, 119853, 127922, 0, 8285, + 126516, 4509, 121043, 66471, 12216, 128806, 40988, 83221, 74809, 41727, + 0, 42848, 2396, 128083, 194892, 74018, 917538, 64940, 7027, 3886, 0, + 42457, 92888, 83299, 996, 68123, 94058, 4249, 92410, 69650, 11707, 8222, + 73825, 7939, 71213, 92460, 127801, 121408, 128359, 8534, 69853, 40983, 0, + 121421, 0, 7201, 12561, 120866, 42371, 12558, 1540, 917549, 10052, 40982, + 119841, 0, 1488, 71177, 0, 194831, 917559, 128401, 0, 1563, 128034, 9619, + 120840, 917905, 120954, 127872, 71363, 3560, 7797, 6070, 10006, 128922, + 2922, 6082, 70147, 65009, 983942, 12567, 66712, 0, 41412, 128131, 119591, + 3607, 9200, 10046, 9612, 42153, 8218, 9485, 0, 2032, 78354, 83462, + 119131, 0, 0, 67826, 43085, 6057, 508, 93968, 92989, 67968, 0, 92198, 0, + 128831, 638, 6083, 119072, 124950, 0, 2305, 78348, 68096, 917772, 6056, + 6659, 67969, 983290, 6085, 0, 0, 3915, 41634, 0, 41639, 63912, 11941, + 983783, 4028, 1787, 42180, 43096, 43753, 3249, 1768, 93982, 12328, 501, + 93985, 10601, 0, 583, 0, 41977, 0, 66004, 66416, 6505, 74010, 983250, + 13064, 55267, 119113, 6500, 5526, 65049, 0, 12990, 0, 92376, 12745, 9678, + 121108, 120587, 9869, 83150, 1771, 128965, 8936, 92964, 0, 4208, 78341, + 78567, 78342, 67742, 983208, 74101, 128605, 11762, 0, 70096, 6835, 68010, + 66475, 120260, 5027, 78172, 128878, 119830, 5069, 73736, 5028, 9897, + 92774, 73739, 5026, 983255, 68639, 6331, 10079, 8931, 0, 1415, 8866, + 41901, 74790, 78138, 119361, 983564, 43106, 5029, 65309, 1580, 3598, + 68424, 41070, 77903, 7658, 3440, 78215, 1562, 128656, 127175, 119358, + 1716, 983679, 10600, 78558, 620, 41001, 6028, 70445, 42892, 0, 71116, + 5024, 74945, 41003, 68137, 5025, 69892, 983209, 75039, 118885, 127956, + 65557, 0, 74541, 128924, 11599, 128209, 11602, 6243, 11574, 11581, 11597, + 11598, 6253, 6105, 11584, 70273, 11569, 65275, 8906, 43945, 5755, 2636, + 71203, 10815, 11619, 2301, 41540, 7815, 11616, 6979, 12080, 7721, 11604, + 7869, 1592, 0, 42152, 78498, 41048, 917763, 829, 0, 92406, 19950, 66886, + 64131, 6616, 0, 118875, 10953, 391, 0, 69785, 482, 42296, 11588, 0, + 43606, 71185, 68397, 66370, 74282, 42335, 69786, 72421, 82998, 7538, + 5315, 83367, 42491, 92901, 42061, 128002, 4576, 0, 68417, 43809, 4277, 0, + 3563, 64472, 42338, 368, 42058, 3960, 11043, 11337, 78209, 120244, 63989, + 3958, 12132, 1849, 0, 9921, 42451, 4253, 41147, 42064, 11959, 42404, + 41160, 121481, 3618, 78338, 194924, 43300, 5156, 92629, 70350, 929, 6827, + 42035, 42437, 1555, 0, 8691, 66435, 2215, 41662, 94010, 119262, 0, + 128824, 93952, 4578, 64513, 41664, 983734, 42578, 71049, 41661, 78351, + 43267, 9356, 0, 194880, 983401, 1286, 10166, 983117, 0, 64707, 128925, + 42476, 7730, 11156, 128522, 42483, 129083, 74940, 42324, 42291, 10020, + 43359, 0, 6641, 525, 41627, 917923, 8763, 128304, 41628, 533, 11931, + 65225, 8321, 42504, 42581, 0, 6915, 42310, 4377, 8559, 128321, 8587, + 121318, 13193, 64350, 11666, 8679, 41924, 1576, 7735, 92398, 0, 73840, + 83153, 11374, 78043, 10889, 43461, 7757, 42462, 120226, 10029, 66493, + 2718, 4168, 43904, 13308, 120112, 0, 1179, 4440, 43902, 77948, 363, + 11015, 43903, 77944, 43857, 83049, 66692, 120826, 0, 66492, 6593, 64625, + 41963, 92177, 119329, 0, 10013, 64434, 75010, 127095, 9492, 11782, 64382, + 12833, 77830, 0, 1297, 41630, 630, 120960, 983923, 120774, 70165, 1043, + 43652, 66223, 10090, 0, 124945, 313, 121483, 41881, 194658, 42311, 7445, + 43906, 5750, 10759, 9419, 55222, 9405, 11268, 42919, 9398, 8526, 9399, + 9422, 43894, 66495, 69990, 983885, 92990, 41718, 10707, 1603, 983703, + 119003, 0, 631, 77952, 69703, 13161, 65272, 71067, 10546, 74210, 78101, + 11600, 77961, 2797, 43924, 42427, 306, 714, 3058, 42381, 77962, 127080, + 12351, 42395, 0, 11607, 127528, 11198, 66821, 77967, 9157, 73765, 66364, + 42433, 77964, 7603, 12803, 180, 42141, 0, 120612, 66494, 12674, 8244, + 362, 92439, 43890, 8037, 43777, 11535, 126539, 43893, 5185, 7165, 5521, + 10334, 2093, 71329, 10302, 125131, 10104, 1027, 5181, 128435, 5117, + 10523, 1446, 42320, 6845, 991, 5189, 42472, 41647, 120105, 1722, 5581, + 42898, 3405, 0, 194644, 5523, 43915, 42620, 92447, 74943, 9549, 0, 10549, + 43923, 9661, 42933, 74884, 77910, 78068, 43921, 0, 71184, 983070, 41991, + 983893, 0, 7630, 9846, 7684, 10350, 128453, 1174, 77981, 42733, 77978, + 77980, 66485, 77977, 42277, 77974, 42456, 43909, 74438, 12330, 128272, 0, + 42417, 42383, 66630, 41344, 6293, 0, 66252, 43908, 74443, 127894, 10209, + 8313, 4195, 74435, 1316, 66690, 75072, 6332, 64894, 983156, 65871, 67250, + 1736, 983684, 3901, 12228, 120151, 65200, 3383, 10446, 78241, 693, 9130, + 314, 64149, 42420, 11949, 127200, 120152, 11026, 120516, 5332, 6940, + 64154, 12635, 124980, 42706, 1751, 273, 8165, 13166, 83307, 78840, 71368, + 12824, 43911, 4528, 5320, 6301, 43662, 6133, 9339, 9463, 42346, 10922, + 64560, 3757, 0, 0, 74302, 65869, 73760, 2569, 74976, 2326, 65740, 2565, + 42459, 7596, 7921, 983868, 73862, 127981, 41848, 2567, 66006, 92622, + 4044, 92646, 43953, 12233, 983871, 1023, 474, 194940, 119818, 0, 0, + 42487, 65556, 121168, 127866, 42295, 128203, 121474, 71322, 92518, 2222, + 66499, 0, 5417, 12275, 10895, 0, 274, 0, 1858, 983455, 0, 55251, 10118, + 3133, 127771, 71857, 121201, 9610, 8068, 8197, 917545, 699, 0, 41665, + 5868, 128710, 92695, 42182, 7581, 19940, 43668, 41667, 128057, 0, 1923, + 65583, 65802, 93970, 64597, 43444, 78129, 68751, 0, 6464, 7036, 2996, + 1937, 983751, 68481, 41835, 4047, 41842, 0, 64107, 77965, 119837, 11017, + 120601, 0, 293, 77966, 92169, 64791, 41827, 42466, 43422, 10579, 8560, + 71350, 65413, 77963, 4803, 12964, 1739, 1941, 3900, 128967, 1713, 77969, + 121292, 73957, 11407, 42441, 41971, 6297, 120098, 64105, 120565, 42481, + 11716, 66473, 7179, 42289, 125095, 64103, 969, 0, 9352, 71481, 6165, + 64100, 917819, 6632, 73861, 42402, 74327, 7806, 113762, 8914, 66908, + 124954, 3183, 1435, 64876, 2969, 6046, 64441, 6208, 67849, 5746, 66408, + 0, 64416, 42422, 83506, 983046, 7082, 73775, 338, 5059, 121369, 83524, + 42328, 10767, 128862, 8115, 83454, 74758, 0, 8227, 2073, 1218, 917790, + 983230, 65848, 92884, 83517, 69863, 128328, 126987, 4486, 128082, 917796, + 0, 10925, 0, 83515, 83507, 124952, 42309, 10257, 65191, 10273, 7668, + 10305, 42461, 74882, 42349, 8832, 78051, 64127, 10644, 42662, 78828, + 42278, 74451, 126988, 69874, 7794, 119214, 42429, 6377, 42316, 119026, + 3669, 3968, 42468, 71319, 69658, 0, 65402, 119581, 194973, 128747, 64933, + 194627, 41960, 6699, 42903, 128755, 125013, 6823, 42391, 1588, 43502, + 8409, 78223, 19967, 65398, 787, 71315, 128335, 127744, 6115, 2078, 41654, + 42480, 917949, 92650, 41655, 65401, 43975, 72427, 0, 113816, 644, 65500, + 41657, 10778, 3659, 9533, 184, 1553, 13107, 65484, 69648, 10502, 66296, + 0, 0, 41554, 0, 8220, 128432, 41557, 0, 128938, 11070, 119221, 5157, + 4020, 73858, 41555, 9514, 64818, 65103, 64641, 64303, 78131, 7520, 73888, + 74377, 11029, 66651, 983068, 128492, 118930, 64527, 121395, 7877, 12723, + 983798, 68776, 120096, 74602, 9955, 119557, 4055, 42817, 0, 65212, 11715, + 12190, 12319, 78630, 0, 78631, 9502, 65427, 125048, 65424, 12607, 120966, + 9734, 65425, 0, 121431, 127357, 74890, 78836, 10112, 10827, 194635, 9866, + 74527, 66675, 118867, 8625, 64346, 11290, 10477, 67738, 8636, 983927, + 8315, 65444, 983793, 195011, 74595, 6152, 78820, 73947, 6629, 125056, + 120171, 0, 74589, 43993, 128346, 69790, 64435, 64955, 43690, 11046, + 11490, 42730, 4485, 71126, 128194, 64926, 0, 983133, 43830, 5869, 12437, + 42728, 0, 7040, 3588, 0, 12825, 121158, 0, 12725, 74092, 127106, 78634, + 223, 78635, 69675, 120119, 42444, 128449, 64499, 65245, 129104, 1171, + 128802, 69717, 120113, 1805, 8772, 43820, 0, 9930, 65247, 78619, 74954, + 2338, 120032, 118853, 0, 42676, 0, 64800, 13092, 11185, 68126, 1213, + 128419, 64075, 797, 64074, 8734, 4212, 83005, 64387, 4115, 71331, 5005, + 64070, 64073, 10679, 83000, 77954, 9402, 64276, 426, 83358, 83010, 8251, + 10136, 65436, 0, 2120, 43302, 1224, 0, 65576, 70795, 10701, 1764, 3101, + 127815, 12858, 120159, 120101, 11373, 6378, 71093, 120103, 8663, 9312, + 41644, 4539, 2129, 70785, 9222, 121479, 118907, 4259, 9092, 74567, 41961, + 128515, 12724, 66357, 42331, 64935, 0, 0, 1293, 7947, 2132, 983767, + 71858, 72440, 2454, 42717, 3613, 128837, 71117, 0, 65888, 8816, 10978, + 10840, 0, 10668, 113723, 43087, 12595, 120304, 983114, 8822, 0, 1157, + 64903, 8638, 127265, 917886, 127905, 0, 69848, 8235, 120316, 4405, 10086, + 120247, 11128, 69216, 121065, 65430, 71321, 6079, 6817, 10764, 120314, + 64291, 120315, 998, 120312, 11062, 1317, 64327, 1558, 194572, 1991, 7882, + 42254, 128954, 41700, 530, 0, 10428, 119335, 12002, 119336, 5742, 43076, + 4692, 64630, 41823, 4007, 5004, 74033, 7896, 751, 6595, 6596, 120325, + 66373, 983249, 128746, 64908, 92691, 6311, 93019, 12004, 119192, 12049, + 43108, 120326, 71083, 41705, 92188, 6598, 121298, 6599, 66822, 93031, + 42148, 118825, 66027, 121055, 6597, 9412, 8340, 11824, 64745, 2281, + 69904, 128495, 1988, 5407, 67865, 2430, 41678, 93059, 83114, 2336, + 983903, 0, 67169, 120442, 127092, 1921, 10947, 19927, 70390, 65406, + 983464, 19913, 4284, 13217, 0, 43789, 12841, 9229, 10956, 42285, 41674, + 19964, 41679, 65084, 3521, 124957, 5774, 8325, 69864, 65403, 983089, + 1854, 10794, 93054, 67660, 69846, 194765, 78359, 5280, 0, 4344, 12905, 65433, 6076, 64793, 41610, 768, 12074, 442, 0, 68162, 64081, 12934, 41682, 65432, 41693, 0, 6071, 65434, 127467, 4804, 4053, 0, 127469, - 194653, 41696, 467, 69823, 127463, 69797, 194652, 127473, 8421, 127472, - 69682, 43705, 502, 0, 65431, 119056, 69954, 12043, 1303, 316, 7364, 2029, - 2136, 119246, 11533, 64365, 43480, 92639, 4860, 126648, 127877, 42488, 0, - 9583, 128849, 5546, 8019, 73856, 0, 0, 0, 5544, 2355, 12150, 65725, 5543, - 77989, 63751, 12137, 5548, 77985, 0, 65727, 68388, 65726, 6077, 128352, - 65452, 0, 11301, 78013, 78008, 78010, 9874, 78007, 0, 1319, 3050, 65410, - 0, 0, 78016, 78017, 42830, 43996, 66716, 128137, 4691, 92242, 9345, 621, - 92709, 128222, 0, 65411, 0, 41182, 73881, 65408, 73899, 78024, 9474, - 10545, 119118, 10887, 3786, 65409, 8894, 43179, 119611, 7923, 3716, - 92363, 9996, 8508, 0, 7012, 8195, 127834, 9566, 0, 3722, 0, 41707, 8493, - 545, 9575, 41379, 10050, 12718, 69854, 8859, 6820, 74345, 65110, 120740, - 0, 0, 9119, 2787, 7920, 118823, 4021, 2012, 7985, 0, 119663, 0, 0, 78021, - 78022, 410, 78020, 1802, 78018, 74107, 0, 41659, 41671, 1827, 0, 64396, - 10126, 12116, 41673, 120370, 11422, 78141, 120373, 3860, 120367, 68412, - 41345, 120362, 120363, 11748, 42158, 7941, 11076, 8749, 120361, 2104, - 64858, 361, 120357, 845, 0, 41560, 11970, 4562, 917920, 2926, 917919, - 4569, 74130, 0, 43487, 194630, 611, 74129, 64871, 118891, 65629, 0, - 194858, 0, 0, 127545, 120543, 0, 0, 6291, 0, 78639, 41669, 7094, 917921, - 0, 983581, 74054, 127754, 195029, 0, 839, 983319, 7695, 8769, 65246, - 4829, 194663, 4859, 64467, 0, 983963, 118998, 7206, 0, 6647, 43986, 0, - 69766, 0, 64764, 4210, 983863, 127936, 804, 0, 0, 12298, 0, 66653, 0, - 64924, 10091, 73931, 9468, 74245, 0, 0, 74246, 92503, 12839, 64669, - 92202, 0, 1279, 1425, 6224, 119229, 11049, 0, 92697, 43239, 8482, 92440, - 0, 5032, 69677, 11940, 67888, 664, 120437, 5034, 0, 0, 127525, 42702, - 73888, 983149, 13294, 67873, 64869, 6032, 0, 9115, 7430, 120377, 0, + 194653, 41696, 467, 69823, 127463, 69797, 121403, 121294, 8421, 127472, + 69682, 43705, 502, 75029, 65431, 119056, 69954, 12043, 1303, 316, 7364, + 2029, 2136, 119246, 11533, 64365, 43480, 92639, 4860, 70372, 127877, + 42488, 70339, 9583, 128849, 5546, 8019, 73856, 983840, 124960, 120839, + 5544, 2355, 12150, 65725, 5543, 75034, 63751, 12137, 5548, 77985, 0, + 65727, 68388, 65726, 6077, 128352, 65452, 0, 11301, 11214, 65952, 78010, + 9874, 78007, 983115, 1319, 3050, 65410, 67399, 92606, 78016, 78017, + 42830, 43996, 66716, 83050, 4691, 92242, 9345, 621, 83512, 128222, 0, + 65411, 0, 41182, 73881, 65408, 73899, 78024, 9474, 10545, 119118, 10887, + 3786, 65409, 8894, 43179, 71042, 7923, 3716, 92363, 9996, 8508, 127794, + 7012, 8195, 127834, 9566, 0, 3722, 983374, 41707, 8493, 545, 9575, 41379, + 10050, 12718, 69854, 8859, 6820, 74345, 65110, 120740, 128978, 55282, + 9119, 2787, 7920, 70091, 4021, 2012, 7985, 0, 119663, 917792, 0, 78021, + 78022, 410, 78020, 1802, 78018, 74107, 74895, 41659, 41671, 1827, 0, + 64396, 10126, 12116, 41673, 120370, 11422, 71846, 120373, 3860, 120367, + 68412, 41345, 120362, 120363, 11748, 42158, 7941, 11076, 8749, 120361, + 2104, 64858, 361, 120357, 845, 92174, 41560, 11970, 4562, 128473, 2926, + 68495, 4569, 74130, 128659, 43487, 194630, 611, 74129, 64871, 118891, + 65629, 0, 194858, 74854, 0, 70466, 67392, 66385, 71439, 6291, 0, 68487, + 41669, 7094, 121051, 0, 120999, 74054, 127754, 128917, 0, 839, 121315, + 7695, 8769, 65246, 4829, 67756, 4859, 64467, 0, 83525, 118998, 7206, + 119636, 6647, 43986, 83518, 69766, 194664, 64764, 4210, 128300, 127936, + 804, 83520, 0, 12298, 70344, 66653, 126983, 64924, 10091, 67200, 9468, + 67206, 67205, 67204, 67203, 92503, 12839, 64669, 92202, 71851, 1279, + 1425, 6224, 119229, 11049, 127123, 71480, 42649, 8482, 92440, 0, 5032, + 67209, 11940, 67207, 664, 120437, 5034, 92495, 70200, 127525, 42702, + 70194, 93061, 13294, 67873, 64869, 6032, 67218, 9115, 7430, 77837, 70191, 120819, 68387, 120168, 73913, 120170, 41161, 5518, 4174, 10993, 41162, - 120160, 64528, 1169, 434, 41437, 1905, 6034, 41164, 64744, 9528, 118867, - 128800, 524, 0, 74029, 788, 74027, 0, 194638, 0, 1663, 10419, 74025, - 42636, 0, 69725, 0, 120656, 0, 67876, 0, 0, 0, 67897, 74039, 0, 0, 11395, - 0, 119107, 43612, 64344, 0, 0, 10855, 5445, 9355, 0, 65198, 7391, 8989, - 221, 65686, 0, 0, 8010, 7191, 4962, 69772, 8855, 0, 0, 64469, 120426, - 10555, 0, 43333, 92299, 0, 120427, 10451, 0, 67653, 7245, 12443, 74405, - 9947, 120149, 78317, 3873, 8367, 0, 120146, 43433, 43649, 11987, 0, 0, - 11010, 12723, 74059, 74062, 6217, 5896, 0, 7682, 74049, 1462, 10235, 0, - 0, 0, 0, 0, 0, 42595, 0, 74402, 118860, 0, 120419, 92497, 74052, 0, - 92378, 120549, 119082, 64295, 120418, 0, 64765, 73923, 120417, 120662, - 69920, 194702, 6216, 0, 10755, 9455, 0, 8124, 127042, 9470, 6944, 127540, - 0, 69680, 2828, 0, 531, 42638, 0, 0, 0, 43428, 8204, 3614, 2827, 9696, 0, - 0, 8728, 4354, 10904, 78562, 19936, 7833, 120691, 0, 42599, 42597, 42709, - 120409, 127044, 0, 8537, 0, 0, 9354, 983164, 128833, 41199, 10121, 2028, - 0, 983194, 69715, 0, 3062, 0, 74447, 12608, 0, 66440, 7545, 9700, 12580, - 92205, 120777, 120502, 41155, 0, 74071, 0, 983457, 12713, 0, 0, 0, 78772, - 0, 1734, 0, 0, 127040, 64594, 2456, 231, 0, 74167, 542, 0, 118786, 0, - 983979, 1230, 0, 0, 3597, 4446, 10584, 74235, 92215, 4037, 127938, 8352, - 0, 5687, 0, 64515, 0, 194801, 55265, 67846, 78434, 9704, 0, 0, 70080, - 71338, 0, 8660, 126495, 0, 0, 78773, 74482, 4483, 1709, 69721, 9909, - 6080, 0, 120358, 1746, 1315, 8667, 0, 0, 13140, 65899, 10604, 0, 4480, - 11266, 128152, 1226, 6930, 67979, 983690, 6360, 10897, 41230, 605, 0, - 74785, 69875, 0, 0, 41500, 0, 311, 11453, 6221, 10608, 64943, 74280, - 10877, 118868, 64885, 74272, 0, 0, 128559, 120736, 74312, 345, 0, 74456, - 64606, 9917, 0, 92231, 5037, 0, 1776, 8422, 0, 118814, 41508, 41201, 323, - 43328, 0, 42698, 1295, 194853, 4625, 0, 4630, 13117, 0, 128772, 65123, - 11293, 2668, 11288, 0, 42640, 65666, 2519, 92369, 65420, 92479, 0, 4252, - 5049, 42659, 119011, 706, 7754, 10854, 8738, 0, 65419, 0, 0, 649, 65421, - 0, 66702, 0, 12670, 1013, 0, 64919, 705, 0, 65422, 127803, 1183, 126519, - 7017, 42852, 0, 8157, 9736, 64503, 65418, 0, 983878, 74035, 0, 11913, - 73874, 6696, 0, 8920, 119298, 0, 7962, 12211, 9837, 2051, 66227, 0, 4184, - 0, 0, 10177, 73777, 1857, 194657, 4626, 8464, 8472, 0, 4629, 8499, 78321, - 78322, 4624, 7818, 119173, 0, 0, 7805, 0, 94007, 6935, 92292, 78325, - 78326, 78323, 43327, 43989, 119046, 8492, 8250, 8459, 0, 8497, 8496, 0, - 0, 78336, 78339, 9543, 78335, 78332, 77832, 65849, 77831, 983961, 0, - 12451, 0, 8684, 0, 6102, 0, 5298, 0, 5294, 0, 0, 983459, 195062, 9949, - 119826, 43617, 119215, 0, 12073, 0, 0, 77863, 13108, 120617, 11439, - 41468, 983757, 0, 5292, 55272, 983883, 1939, 5302, 3970, 917879, 12455, - 1793, 0, 0, 0, 6643, 92477, 65263, 0, 78330, 41293, 78328, 65923, 0, - 13219, 9569, 0, 74383, 0, 74197, 0, 5500, 8813, 0, 0, 74566, 5322, 0, - 78340, 43631, 5324, 66443, 3784, 41614, 65269, 6230, 78349, 78345, 43324, - 3360, 78344, 11523, 0, 92488, 9926, 7197, 0, 68429, 42894, 41821, 1249, - 78360, 78361, 78356, 78358, 78353, 64899, 64763, 41149, 41807, 43162, - 41815, 41150, 0, 10571, 10096, 0, 0, 78074, 6947, 41152, 887, 9249, 6565, - 78510, 41990, 78509, 41811, 74466, 93966, 6670, 77882, 0, 0, 43092, - 43325, 0, 10168, 0, 9781, 128655, 9190, 0, 9666, 8269, 65944, 74005, - 13019, 11670, 69860, 315, 12813, 983458, 78432, 78256, 78351, 78352, 0, - 983657, 0, 0, 1378, 9509, 0, 0, 74475, 3066, 92220, 67847, 0, 92355, 0, - 78365, 8787, 120379, 194616, 41618, 194615, 78261, 194614, 0, 64652, 0, - 194612, 0, 78366, 42088, 0, 195061, 7176, 43756, 10137, 6121, 10995, - 78259, 74534, 8119, 64874, 917816, 127199, 194939, 0, 74525, 0, 0, 12930, - 1394, 74514, 0, 74515, 0, 118804, 2998, 9527, 120659, 65190, 12977, - 42090, 119165, 0, 119100, 41236, 92235, 42005, 42003, 41237, 5848, 0, 0, - 3670, 128657, 194600, 0, 0, 7890, 0, 11298, 43315, 0, 6229, 1593, 0, 0, - 619, 4635, 65080, 0, 128002, 4120, 65337, 65336, 0, 11808, 119214, 74115, - 9366, 42790, 42006, 119115, 65327, 65326, 65325, 10757, 1507, 42216, - 65321, 65320, 65335, 65334, 65333, 65332, 65331, 42059, 65329, 42689, - 92427, 9128, 94045, 42073, 6785, 64590, 983830, 4371, 7196, 65318, 2035, - 65316, 4106, 65314, 65313, 42074, 127847, 41228, 0, 65609, 41241, 7903, - 41239, 43533, 78459, 7189, 0, 0, 0, 12357, 42802, 78450, 8487, 9131, 0, - 4615, 12695, 127752, 0, 12175, 0, 64535, 0, 7809, 0, 0, 562, 12169, 6590, - 69762, 66455, 64738, 3219, 68654, 983787, 0, 1037, 0, 2025, 128263, - 13098, 78442, 10637, 4568, 549, 1570, 0, 2835, 0, 10624, 43623, 11072, - 127191, 0, 0, 12606, 78433, 2825, 0, 10825, 8079, 2821, 41046, 92327, - 7365, 983753, 120593, 13071, 0, 452, 41049, 42840, 6346, 2831, 5461, - 74596, 11465, 5212, 0, 64703, 119191, 42308, 7181, 0, 41332, 0, 12333, 0, - 1668, 0, 0, 0, 1187, 983385, 42628, 78575, 0, 128777, 0, 3240, 128518, - 12194, 0, 11591, 41065, 5323, 8166, 0, 0, 0, 74535, 1623, 65297, 128856, - 571, 0, 4918, 0, 5288, 127295, 8916, 65048, 1909, 8864, 0, 0, 10736, - 92508, 11571, 7615, 127300, 92296, 4237, 92576, 1035, 65815, 0, 7881, - 701, 65936, 3489, 0, 0, 120751, 11403, 0, 0, 127146, 3796, 6800, 0, 3994, - 11421, 0, 195076, 0, 983922, 0, 0, 64857, 128105, 2855, 127828, 66308, - 41621, 68214, 127283, 127817, 10654, 0, 119226, 12164, 3246, 7906, 43972, - 65847, 7182, 0, 13024, 194822, 74270, 128289, 0, 0, 0, 1496, 747, 0, 942, - 2378, 43136, 127905, 8466, 983575, 9320, 8001, 1232, 8139, 11617, 0, 0, - 11409, 68373, 6382, 0, 64634, 128279, 0, 11612, 0, 67600, 2374, 94066, - 8475, 11609, 66313, 0, 0, 5286, 119297, 0, 0, 64925, 120283, 194584, - 118982, 194583, 7705, 11942, 11305, 194581, 3309, 0, 0, 0, 0, 6802, 0, - 41653, 1280, 1241, 7168, 12096, 0, 66615, 42565, 41651, 0, 0, 0, 41650, - 66507, 66470, 0, 12914, 41491, 66010, 119552, 6078, 9954, 0, 1475, - 119247, 9938, 6084, 917546, 41064, 41062, 0, 0, 3256, 10189, 42076, - 43252, 78823, 917906, 8727, 0, 65875, 0, 0, 127762, 10562, 74215, 43065, - 0, 0, 3248, 74297, 3261, 9015, 71351, 0, 3635, 64337, 983281, 0, 0, 7195, - 0, 2007, 64431, 0, 0, 0, 0, 635, 0, 0, 65613, 77909, 92420, 73997, 0, 0, - 119218, 7984, 8600, 74434, 127770, 4176, 70050, 2034, 92551, 120805, - 65891, 127038, 0, 318, 2038, 128860, 78596, 0, 3649, 13149, 42145, 42798, - 3634, 120291, 118927, 67677, 120124, 7866, 0, 11402, 42146, 94032, 74238, - 42664, 2849, 127034, 0, 7938, 12960, 1761, 11812, 65379, 68386, 128185, - 1159, 0, 69729, 0, 0, 7178, 194632, 0, 41680, 0, 128203, 11534, 1514, - 11668, 67891, 9313, 7015, 0, 67877, 194567, 12989, 66474, 9368, 12848, - 1624, 43270, 0, 74278, 10818, 126644, 9953, 0, 78421, 1194, 3242, 9761, - 9555, 8598, 120299, 6169, 12871, 1551, 2798, 65176, 4958, 42752, 119025, - 0, 67875, 120301, 3495, 66648, 194768, 0, 68364, 983224, 4891, 0, 10641, - 0, 73746, 0, 68352, 0, 73787, 194829, 194633, 7199, 64955, 0, 0, 0, 0, 0, - 42685, 42679, 193, 0, 0, 0, 42667, 0, 5271, 92318, 92517, 118882, 1362, - 13297, 0, 128094, 0, 983331, 73789, 0, 6658, 4426, 0, 92628, 983842, - 92319, 7276, 42163, 5220, 0, 0, 983330, 2416, 3310, 42703, 0, 379, 0, - 43755, 0, 0, 3223, 65492, 1284, 194771, 4549, 0, 0, 983154, 127763, - 10807, 9558, 194613, 0, 8515, 8688, 12866, 65308, 3294, 983332, 8529, - 128101, 43385, 7564, 0, 43329, 0, 92458, 73757, 66456, 42359, 0, 2031, 0, - 7202, 0, 12676, 42729, 92198, 3215, 0, 7710, 1610, 73801, 0, 0, 65682, 0, - 120537, 65924, 9974, 228, 66354, 1501, 0, 64395, 5179, 7200, 6225, 0, - 65794, 1725, 65533, 8196, 7476, 74399, 0, 0, 7152, 8502, 5762, 1967, - 7483, 0, 0, 8104, 0, 7474, 77979, 0, 126507, 10414, 13001, 8141, 0, - 42537, 1557, 43594, 128642, 6330, 6805, 8631, 2545, 70052, 127166, 0, - 74190, 0, 0, 983786, 42762, 0, 42914, 1650, 262, 1637, 0, 7901, 3238, - 128173, 41861, 0, 128585, 65158, 10860, 94059, 43658, 7527, 0, 43319, - 6419, 0, 45, 0, 64588, 93989, 0, 119810, 7194, 5291, 0, 43666, 13129, 0, - 9084, 0, 8737, 0, 12881, 0, 12906, 9639, 7912, 2620, 0, 0, 0, 983875, - 179, 65896, 0, 64756, 2853, 78443, 118813, 983890, 118996, 119009, 2850, - 8084, 983085, 73850, 2801, 92284, 42069, 119839, 74754, 119841, 42072, - 119843, 119842, 10398, 983056, 0, 8377, 127116, 8245, 68401, 3158, 92396, - 3983, 43656, 923, 119857, 119856, 292, 13002, 119845, 119844, 3221, 1763, - 92463, 4612, 119851, 119850, 7253, 127110, 68391, 0, 10782, 3637, 12996, - 43542, 0, 64578, 983675, 3228, 69636, 8783, 0, 119614, 2731, 0, 0, 78585, - 4102, 7696, 73878, 0, 0, 78586, 43316, 4177, 11283, 9089, 0, 73996, - 983173, 64500, 43674, 0, 64947, 1856, 0, 0, 6379, 0, 0, 0, 3208, 12975, - 74775, 127380, 983931, 92389, 74072, 55269, 0, 0, 983683, 2033, 78577, - 78576, 195026, 55254, 7740, 0, 0, 0, 73964, 0, 93988, 67612, 65674, - 128244, 94110, 41689, 0, 74006, 64909, 6646, 11790, 74019, 0, 128066, - 128031, 8561, 4573, 0, 5326, 0, 120605, 7230, 8257, 0, 8778, 41688, 0, - 65776, 2071, 8314, 6459, 0, 7628, 65092, 73903, 66721, 11342, 128561, 0, - 0, 128226, 127001, 0, 11810, 13164, 10723, 967, 983951, 126469, 11946, 0, - 3257, 0, 12307, 1845, 983157, 43526, 0, 0, 1886, 42342, 10089, 870, 7648, - 3499, 8609, 7652, 876, 871, 877, 0, 878, 42015, 879, 43692, 4563, 0, 0, - 7591, 65887, 867, 9520, 872, 126607, 868, 873, 7642, 0, 869, 874, 7644, - 120674, 875, 790, 128303, 0, 0, 0, 66182, 983258, 5429, 195055, 66180, - 126480, 66181, 68452, 983289, 983248, 42067, 0, 5433, 10657, 7911, - 194622, 1547, 66176, 42012, 120576, 5425, 4977, 9999, 5317, 5423, 4611, - 0, 67637, 0, 9679, 74122, 0, 0, 0, 66194, 4418, 66184, 4628, 4245, - 119648, 0, 0, 1851, 0, 127189, 11908, 0, 9360, 118897, 983202, 42776, - 66187, 12837, 8829, 7711, 92714, 0, 92321, 43318, 0, 8809, 69881, 0, - 983142, 120604, 983052, 983882, 0, 983270, 0, 0, 7427, 9958, 4588, 43680, - 0, 74484, 194968, 2433, 0, 119622, 3352, 74363, 983885, 0, 793, 74404, 0, - 305, 567, 67662, 842, 128519, 8208, 0, 41695, 1647, 118877, 0, 7837, - 917625, 818, 5337, 194628, 917621, 41376, 119978, 126576, 120594, 74086, - 917615, 917614, 917613, 10973, 66359, 1372, 127172, 917608, 4969, 1254, - 917605, 917604, 93967, 917602, 65228, 78221, 126612, 0, 2840, 0, 119982, - 983939, 0, 3245, 9068, 68194, 64725, 0, 0, 12991, 0, 2651, 68016, 983265, - 917611, 127026, 128883, 0, 0, 43648, 120812, 0, 43322, 92662, 0, 0, - 64372, 92698, 3226, 655, 752, 7457, 7456, 7452, 3285, 128779, 127821, - 119988, 65610, 2391, 0, 92248, 671, 250, 7434, 618, 668, 610, 42800, - 7431, 1152, 42801, 640, 120666, 7448, 7439, 628, 3905, 73810, 0, 128266, - 64749, 67850, 2107, 0, 0, 4605, 128174, 983192, 43372, 65945, 128838, 0, - 119590, 0, 0, 0, 987, 6927, 11572, 42261, 11464, 3365, 9971, 0, 0, - 128297, 0, 0, 0, 0, 11334, 43326, 12609, 11519, 11503, 5530, 5210, 0, - 4627, 983892, 5208, 0, 128842, 10332, 5218, 7976, 9156, 0, 3244, 5529, - 69647, 73894, 128852, 5432, 64965, 5527, 74033, 10516, 7790, 5528, 0, - 42140, 120281, 0, 0, 43545, 9887, 0, 4000, 7429, 7428, 665, 7424, 3206, - 120278, 7884, 0, 128566, 917989, 128666, 211, 2509, 128858, 120573, - 68672, 3220, 42235, 0, 10690, 8951, 5214, 42474, 8118, 0, 7048, 4590, - 127258, 5852, 0, 0, 127259, 1708, 0, 983165, 2623, 11943, 0, 69226, 0, - 4698, 66509, 1066, 119921, 4701, 983876, 120285, 74225, 94111, 8267, 0, - 127265, 0, 7516, 0, 2625, 983977, 8034, 74309, 0, 3631, 10955, 7850, - 120293, 8416, 0, 0, 0, 43384, 12660, 0, 0, 0, 74850, 41069, 0, 128156, - 12099, 4310, 10032, 6252, 713, 7990, 0, 3990, 0, 983262, 66368, 5017, - 64956, 7071, 0, 119144, 1030, 118800, 983120, 9513, 41059, 9357, 0, 1773, - 0, 120350, 0, 6339, 7745, 9844, 0, 64650, 94, 1880, 74766, 983838, 8908, - 0, 128707, 65913, 78470, 10752, 13003, 0, 126572, 41307, 8732, 120338, 0, - 1757, 6964, 4696, 0, 120335, 64785, 7394, 3641, 5419, 128055, 0, 127883, - 0, 120344, 43988, 0, 8610, 43062, 7592, 856, 74299, 936, 13289, 69894, - 43171, 1459, 0, 65243, 78638, 19953, 0, 1504, 70064, 0, 12913, 74206, - 7529, 0, 128699, 983957, 120782, 4113, 0, 2372, 336, 0, 7509, 12152, 0, - 682, 66458, 41505, 0, 64743, 10593, 1703, 0, 983955, 8033, 69953, 0, - 9810, 127269, 0, 12970, 0, 42351, 10109, 917623, 0, 194693, 0, 92690, 0, - 0, 74291, 1965, 7069, 43312, 0, 73887, 0, 2087, 64370, 6314, 41714, 8501, - 0, 0, 74239, 41317, 92614, 2091, 74545, 2090, 0, 9353, 7117, 2077, 77886, - 0, 10498, 2083, 77888, 0, 0, 119236, 634, 0, 0, 0, 69779, 4165, 8746, 0, - 9654, 12856, 6924, 0, 7066, 983719, 0, 128135, 41037, 42692, 7786, 12959, - 41039, 127483, 0, 680, 2302, 128200, 1181, 7056, 3174, 126516, 0, 92668, - 65665, 127375, 126506, 6920, 0, 92295, 0, 118965, 0, 64644, 126981, - 74119, 0, 41028, 0, 6231, 2613, 65302, 40989, 0, 194696, 0, 42760, 0, - 983566, 0, 40987, 4667, 0, 983932, 8828, 0, 0, 1246, 4746, 0, 0, 11021, - 4749, 92675, 0, 921, 4744, 0, 12702, 242, 0, 1566, 8217, 0, 64653, 78386, - 128121, 74036, 74505, 43274, 5313, 951, 0, 0, 983867, 7604, 983290, 4009, - 127816, 983710, 120562, 0, 983720, 64860, 119138, 119069, 0, 127370, - 4048, 983598, 0, 70024, 1646, 77890, 64534, 73995, 120705, 0, 119890, - 2579, 119905, 3177, 11357, 9099, 4107, 3441, 119894, 2975, 74442, 9822, - 983935, 55220, 10084, 73943, 118840, 0, 917562, 194610, 3399, 9851, - 983717, 11909, 9059, 0, 7687, 0, 6789, 0, 0, 0, 71367, 0, 0, 1777, 9151, - 1137, 69767, 749, 42366, 0, 5385, 128574, 128218, 0, 0, 5989, 0, 0, - 128091, 0, 41685, 69223, 0, 9769, 41684, 983216, 519, 0, 11740, 5766, 0, - 0, 2600, 8848, 120138, 41297, 0, 3666, 74473, 41300, 74468, 65160, 0, - 69688, 69771, 74479, 0, 6558, 0, 0, 69765, 120750, 252, 0, 41302, 0, 0, - 0, 69763, 0, 11729, 8719, 9060, 0, 120139, 10761, 0, 0, 0, 118792, 11734, - 983223, 11730, 0, 9593, 5757, 2403, 64808, 55275, 0, 11728, 43572, 0, 0, - 7764, 983714, 11094, 120825, 0, 983226, 4282, 8298, 0, 0, 0, 0, 0, 64449, - 0, 126650, 63854, 8456, 0, 74783, 65670, 0, 78250, 0, 7774, 10607, 9792, - 0, 0, 0, 0, 120764, 0, 10019, 74762, 0, 3458, 4365, 70053, 983712, 3647, - 0, 2602, 128341, 0, 194707, 41135, 0, 0, 0, 64631, 172, 4971, 41219, - 41137, 1889, 7238, 6545, 126476, 92193, 7597, 10528, 0, 0, 3732, 73910, - 194588, 5344, 0, 43366, 43363, 9062, 119252, 0, 0, 0, 64479, 9232, 92596, - 0, 0, 194712, 10900, 41531, 1263, 3720, 12048, 0, 64292, 41524, 7227, - 119635, 6099, 41534, 0, 127354, 127345, 299, 917957, 8525, 127347, 3524, - 917565, 8831, 127349, 92564, 3075, 67867, 127352, 0, 66362, 0, 64353, 0, - 0, 5845, 0, 0, 0, 2581, 8200, 65114, 68460, 0, 43283, 5551, 0, 120735, - 983201, 6340, 118855, 0, 78134, 8680, 7204, 70065, 2588, 2914, 7011, - 55281, 0, 2471, 194631, 2883, 2749, 119563, 73774, 10913, 0, 0, 8666, - 675, 42493, 0, 43571, 0, 6219, 0, 9980, 41232, 10928, 0, 41153, 41229, - 118967, 0, 3738, 94016, 0, 12711, 3181, 66212, 74289, 68472, 42857, 8262, - 983379, 0, 983222, 0, 42347, 12092, 9615, 7234, 74047, 983088, 0, 43744, - 0, 0, 73846, 2934, 12722, 120762, 922, 43983, 74507, 983126, 74461, 3218, - 120471, 74290, 120469, 64562, 120475, 8569, 11404, 11932, 73728, 3214, - 120461, 120468, 12128, 3207, 65486, 78729, 1901, 78727, 127326, 120460, - 7425, 3205, 68003, 78737, 78736, 78735, 43383, 69940, 65459, 2606, 78730, - 73897, 0, 11496, 1173, 0, 41272, 119661, 0, 0, 983321, 120737, 0, 983971, - 983320, 378, 2610, 0, 65079, 983325, 65695, 126559, 37, 7068, 0, 120480, - 120479, 3209, 120477, 0, 10638, 9768, 69952, 119909, 983399, 0, 0, 0, 0, - 65510, 0, 0, 5233, 983335, 64792, 983334, 0, 126633, 0, 7060, 9847, - 120144, 1685, 595, 0, 73971, 1292, 8940, 7380, 11088, 0, 10004, 126997, - 0, 6541, 0, 0, 0, 3243, 9014, 5606, 0, 538, 64620, 5602, 8467, 74391, - 6547, 128132, 8203, 78488, 983090, 8458, 65211, 8495, 119904, 0, 917552, - 779, 78314, 64367, 2465, 69901, 8193, 55279, 9730, 9280, 0, 7065, 74155, - 4346, 0, 73798, 504, 0, 92414, 8982, 0, 0, 0, 782, 0, 10883, 0, 194852, - 732, 3737, 127253, 1548, 68650, 92507, 1832, 5604, 5735, 41141, 119020, - 4376, 0, 11787, 3745, 0, 0, 42888, 65712, 983304, 3869, 11937, 5725, - 127539, 1783, 68648, 5728, 0, 0, 0, 11918, 66567, 5724, 0, 5727, 78521, - 0, 0, 764, 0, 128116, 43531, 0, 9033, 0, 42532, 6223, 11042, 120749, - 11423, 0, 119861, 71344, 43465, 0, 128267, 6559, 64557, 71348, 92649, - 120648, 43019, 43477, 10238, 74491, 0, 43377, 92282, 71346, 1478, 9783, - 11825, 2607, 64740, 0, 7739, 74543, 0, 0, 0, 6132, 0, 63765, 0, 70058, - 41144, 0, 92438, 43537, 6761, 10093, 4369, 917791, 0, 983148, 8820, 3947, - 0, 0, 11515, 526, 128103, 41295, 194603, 917785, 194932, 0, 7688, 917786, - 7686, 8288, 11815, 0, 0, 983382, 1543, 3713, 41221, 12423, 42281, 917788, - 74024, 12293, 0, 64357, 11794, 42082, 0, 1737, 8987, 42081, 0, 7205, 0, - 9335, 12850, 119870, 6553, 7055, 0, 8277, 0, 0, 5475, 74795, 6780, 0, 0, - 12990, 1160, 42084, 119650, 41217, 119660, 10018, 360, 0, 0, 68176, 5863, - 3137, 0, 4147, 983170, 41216, 7844, 2616, 119190, 68461, 65234, 983294, - 13076, 3135, 983287, 78143, 119139, 3142, 92451, 94068, 10819, 119580, - 10183, 0, 2608, 1470, 73967, 94008, 6227, 0, 127173, 69741, 983582, 6163, - 983558, 0, 127314, 0, 0, 8603, 0, 119866, 3306, 10876, 43392, 119573, - 127931, 5751, 0, 6222, 0, 0, 12086, 7403, 1600, 64309, 64939, 0, 64783, - 92658, 11310, 0, 8882, 0, 0, 2570, 7021, 0, 0, 43110, 0, 1234, 6540, - 6974, 0, 0, 983211, 5002, 0, 41286, 69946, 127019, 0, 43585, 0, 6551, - 983962, 128229, 0, 41289, 0, 194602, 0, 8977, 602, 120814, 0, 128778, - 128661, 0, 983375, 41279, 0, 0, 0, 11081, 43615, 0, 0, 0, 983612, 12727, - 0, 0, 78397, 9475, 7112, 65105, 0, 9633, 10886, 43592, 7831, 983829, - 194571, 0, 73915, 8076, 43048, 8290, 8291, 43051, 92570, 0, 2596, 43584, - 0, 13113, 0, 127757, 2393, 7058, 9087, 74067, 68673, 41574, 78337, 0, - 74058, 6376, 0, 0, 0, 0, 9854, 127748, 64696, 0, 128220, 0, 6994, 0, - 1720, 0, 0, 0, 6529, 7063, 983182, 3751, 9120, 983485, 0, 1798, 709, 0, - 1354, 1876, 13152, 6557, 12430, 8137, 94098, 92642, 0, 0, 245, 128097, - 11456, 41233, 7070, 0, 94046, 6136, 917609, 65677, 8682, 41235, 92595, - 42045, 9804, 118963, 432, 3595, 194945, 65437, 0, 74455, 42399, 0, 0, - 128274, 0, 119658, 0, 0, 0, 77894, 8797, 0, 9052, 64888, 7167, 2356, 95, - 74784, 10580, 0, 42286, 0, 64640, 0, 94109, 0, 74137, 70035, 10063, - 12652, 12199, 92480, 0, 2566, 11971, 983737, 0, 1065, 0, 0, 43400, 2576, - 66696, 93999, 0, 43604, 0, 0, 74082, 514, 74502, 70032, 2921, 43215, - 64493, 5772, 12968, 70055, 194944, 74580, 43398, 2580, 983810, 41341, - 41223, 6564, 1463, 41342, 0, 5293, 70020, 0, 3733, 11346, 0, 12054, 0, - 74098, 42827, 0, 13091, 0, 0, 0, 917915, 0, 127025, 0, 74821, 0, 983733, - 119042, 0, 127865, 13090, 66643, 0, 1270, 1132, 42360, 0, 74096, 66655, - 42569, 127824, 0, 64761, 0, 41021, 8510, 42432, 0, 0, 194782, 0, 64496, - 74109, 70030, 9915, 0, 983218, 7061, 41336, 3854, 69700, 13141, 68413, - 43401, 42319, 13082, 0, 7067, 68221, 0, 127383, 127171, 0, 0, 127797, - 9029, 43543, 119315, 2353, 6308, 0, 74792, 2611, 119186, 0, 0, 0, 43664, - 92399, 66627, 0, 4484, 8509, 118976, 11066, 65233, 0, 41224, 41017, 0, - 3747, 10522, 0, 0, 1691, 41226, 0, 12107, 7100, 10905, 65010, 194986, - 697, 66018, 9284, 4244, 0, 0, 92644, 13121, 120036, 0, 12010, 128573, - 128221, 0, 0, 0, 127193, 65816, 68111, 0, 127933, 65668, 92257, 6618, - 118784, 66365, 0, 42234, 12648, 78110, 7123, 70038, 5785, 9198, 9764, - 41316, 65877, 7383, 13230, 41299, 0, 0, 68365, 128258, 0, 0, 0, 13122, 0, - 191, 70060, 8585, 8000, 64411, 120652, 42889, 64850, 41072, 41578, 0, - 41577, 0, 10002, 0, 6533, 73802, 41570, 0, 683, 396, 41580, 68146, 0, - 12901, 43058, 0, 343, 7129, 42680, 41360, 78154, 0, 4743, 0, 0, 74040, - 74108, 8743, 1724, 1433, 119322, 0, 3739, 6263, 71349, 0, 3964, 6592, 0, - 128693, 66040, 0, 42568, 69806, 128113, 1778, 3956, 0, 42070, 6563, - 43075, 9018, 94006, 983396, 12067, 41312, 0, 5547, 74531, 127969, 0, - 8175, 0, 284, 8108, 934, 0, 74001, 173, 66460, 7174, 92703, 118822, 1750, - 0, 4394, 68368, 1807, 983888, 92298, 0, 5889, 0, 7180, 0, 119145, 0, - 917558, 42471, 6982, 1721, 44022, 7891, 42243, 42160, 2583, 4512, 119360, - 65230, 128109, 0, 0, 3855, 0, 0, 0, 0, 74295, 0, 0, 92416, 3975, 0, - 74087, 0, 12672, 3798, 2703, 983599, 0, 2109, 9774, 1275, 0, 0, 41095, - 3962, 0, 2932, 41101, 3954, 6457, 4513, 0, 0, 73994, 73992, 1468, 0, 0, - 41851, 128230, 41846, 0, 55238, 7633, 41849, 68385, 4320, 3224, 0, - 128032, 0, 42531, 119108, 1510, 0, 8256, 0, 11393, 0, 8879, 128075, - 92474, 8770, 0, 0, 78377, 1910, 8671, 78374, 4283, 0, 127117, 68361, - 78318, 2654, 7893, 195007, 0, 0, 0, 65106, 42761, 12857, 4581, 8411, - 78372, 78371, 78370, 78369, 78368, 0, 0, 0, 1733, 4392, 2568, 10786, - 69661, 0, 8184, 41486, 0, 7396, 7116, 0, 69788, 0, 7185, 7965, 0, 0, - 92347, 983087, 41350, 9129, 0, 0, 2294, 0, 92489, 0, 10481, 0, 70022, - 7171, 0, 340, 92498, 93972, 0, 0, 92200, 0, 0, 6764, 127487, 0, 0, 0, 0, - 65203, 11392, 119098, 119359, 0, 3210, 0, 0, 118795, 0, 0, 127970, - 917619, 0, 0, 10043, 0, 1186, 41571, 6999, 617, 9464, 126642, 3675, 5207, - 65062, 5213, 194769, 2617, 41348, 41568, 128803, 3253, 120535, 0, 8630, - 128544, 0, 5596, 5545, 7288, 2586, 64887, 0, 5217, 71336, 0, 0, 0, 64293, - 68098, 2635, 0, 0, 983846, 0, 983641, 7835, 70040, 0, 194988, 92285, - 64558, 127122, 0, 127121, 0, 127913, 0, 5784, 983102, 0, 0, 70033, 4011, - 917616, 68101, 0, 7864, 4254, 65095, 983496, 5600, 3903, 127083, 10447, - 5598, 1207, 120521, 66689, 3501, 42582, 43600, 194780, 0, 1124, 5597, - 194778, 194772, 9321, 983484, 983481, 983482, 0, 1719, 68356, 68354, - 9671, 1125, 4399, 127479, 917610, 983488, 7631, 5488, 7128, 120532, 0, - 5491, 0, 8937, 43044, 2604, 74187, 5490, 43046, 5489, 7212, 11768, 43043, - 6300, 0, 7122, 0, 4390, 454, 41397, 0, 9875, 7593, 194791, 92274, 118913, - 7207, 0, 65901, 2394, 2575, 0, 3746, 11016, 65752, 120037, 0, 43423, - 128683, 11989, 0, 0, 0, 0, 0, 8249, 128172, 0, 78531, 6640, 74806, 2598, - 513, 0, 6586, 8656, 0, 120710, 65008, 0, 194784, 194989, 194795, 983473, - 92515, 68475, 93973, 0, 0, 78637, 12647, 0, 128043, 69893, 1036, 983477, - 92419, 1723, 128056, 74217, 0, 41579, 2444, 0, 10705, 73876, 983469, - 74486, 983467, 740, 119222, 194978, 194984, 0, 4238, 11071, 9459, 68437, - 78140, 78139, 194985, 8121, 10438, 74487, 42574, 13285, 55263, 11907, - 195000, 5690, 92255, 93992, 0, 43181, 13095, 0, 127857, 64498, 0, 9506, - 6978, 194993, 77992, 0, 0, 194992, 0, 127845, 1122, 317, 0, 0, 0, 0, - 1920, 0, 10173, 827, 0, 0, 78378, 120126, 5223, 1304, 0, 119564, 5226, - 12602, 94044, 0, 9329, 7758, 9239, 41173, 5224, 5487, 1222, 5692, 41725, - 69229, 9674, 5695, 41711, 64627, 19909, 0, 74604, 5691, 287, 866, 233, - 127490, 983441, 42816, 94036, 65140, 74797, 0, 8830, 6568, 42300, 10524, - 41175, 983448, 983445, 983446, 5296, 983444, 42492, 43402, 92466, 3302, - 0, 0, 6516, 6515, 6514, 6513, 6512, 0, 7856, 8690, 0, 0, 12122, 119602, - 43976, 0, 1785, 69925, 68622, 65153, 194810, 5138, 0, 0, 118869, 0, 4540, - 41181, 0, 6200, 0, 5134, 0, 322, 4643, 5132, 0, 6389, 128533, 5143, 0, - 8790, 128694, 0, 194802, 0, 8869, 69916, 0, 42060, 71326, 9648, 194804, - 127012, 10270, 10286, 10318, 10382, 43529, 66477, 0, 0, 74170, 0, 3234, - 0, 0, 74376, 43139, 118815, 127084, 120627, 8767, 0, 74489, 9695, 120746, - 5201, 0, 6215, 12714, 6214, 13101, 0, 194999, 65268, 0, 0, 0, 11027, 0, - 10059, 10511, 42075, 9767, 789, 1749, 78890, 127071, 983670, 320, 0, - 8647, 0, 3049, 0, 6471, 42071, 43156, 9925, 127356, 127355, 66478, 4960, - 5549, 127359, 127346, 8485, 4671, 5418, 127350, 3351, 127006, 127351, - 10610, 5414, 3064, 6212, 4286, 5421, 127344, 9554, 0, 94048, 127109, - 6653, 128811, 0, 64510, 6213, 12885, 0, 119045, 64720, 0, 120759, 73741, - 12603, 7131, 11430, 4566, 7518, 9317, 3801, 10342, 10406, 0, 119259, - 42576, 0, 5200, 126611, 917948, 0, 9183, 127361, 74458, 73825, 395, 5482, - 5198, 4349, 10390, 74202, 5196, 43224, 6113, 42009, 5205, 0, 43307, 0, - 118973, 0, 12134, 0, 0, 118843, 9126, 435, 983624, 12014, 10377, 8093, - 9079, 3203, 192, 65109, 3385, 0, 64430, 5383, 10294, 10326, 128178, 5738, - 983215, 3336, 78355, 5361, 3623, 41159, 0, 68112, 7872, 8581, 0, 1260, - 3149, 5359, 120134, 0, 7914, 5357, 92170, 128659, 2624, 5364, 0, 11431, - 120030, 9101, 11058, 78288, 0, 78293, 42271, 78289, 42917, 120793, 0, - 65566, 6717, 10619, 43360, 78385, 78384, 11832, 78382, 78381, 78380, - 78379, 9319, 7097, 119055, 77906, 3232, 73824, 74581, 120632, 0, 0, - 41889, 92453, 0, 1161, 41895, 74103, 9701, 8622, 0, 0, 73819, 120588, - 5012, 77912, 41362, 69862, 78296, 11921, 0, 11769, 0, 68609, 41364, 0, - 74228, 41352, 41361, 0, 41366, 0, 3356, 11611, 917, 68422, 119915, 7134, - 8199, 78389, 119917, 677, 119916, 0, 119932, 127169, 0, 0, 0, 3349, - 74125, 7022, 8927, 4739, 0, 5802, 0, 8615, 0, 0, 491, 128819, 10190, - 120698, 65837, 128820, 8426, 11092, 9891, 0, 42497, 7113, 7586, 42305, - 10852, 0, 0, 4606, 68448, 9095, 7741, 12684, 41885, 1046, 7124, 0, 0, - 5815, 5171, 65539, 68612, 6932, 74267, 42394, 41878, 74849, 120621, 0, - 5169, 11935, 0, 0, 3175, 120822, 1537, 120804, 5176, 8905, 4136, 4871, - 78287, 0, 9833, 0, 0, 1128, 65920, 0, 9711, 7057, 9408, 9409, 9410, 9411, - 3662, 9413, 3378, 9415, 9416, 9417, 9418, 6320, 9420, 9421, 5897, 9423, - 5165, 5126, 41385, 0, 41389, 917938, 8955, 3374, 9400, 9401, 7119, 9403, - 9404, 3507, 9406, 7629, 983617, 19925, 42669, 68463, 183, 43985, 2631, 0, - 10627, 41130, 78260, 3996, 0, 78771, 0, 119313, 119307, 78768, 6580, - 4332, 64825, 66329, 10726, 66686, 41125, 5899, 41365, 917918, 12085, 0, - 574, 917922, 77825, 73828, 5448, 41058, 5446, 69709, 41322, 42211, 5442, - 4190, 77834, 77835, 5451, 77833, 3616, 77828, 77837, 77838, 7708, 77836, - 10859, 65867, 10345, 10409, 4191, 0, 77844, 73800, 42181, 77843, 77839, - 2060, 0, 7111, 11788, 65587, 68129, 10415, 74102, 0, 205, 0, 10351, - 119076, 0, 9862, 6588, 43257, 64697, 73998, 41355, 5505, 119154, 5503, - 8021, 0, 7125, 9819, 41357, 8011, 42885, 5507, 12044, 92636, 0, 10026, - 5472, 7109, 1191, 13106, 5470, 10329, 5476, 8991, 66322, 69778, 78267, - 42874, 8550, 42876, 5592, 2919, 0, 2675, 5595, 78411, 43762, 4367, 0, 0, - 5478, 5904, 5594, 0, 74150, 7291, 5590, 43761, 13067, 118909, 120372, - 983108, 9731, 69731, 64633, 77857, 77854, 77855, 77852, 77853, 77850, - 10750, 43714, 77858, 7137, 0, 128296, 12887, 10551, 194564, 77866, 77867, - 77864, 77865, 9929, 5199, 9936, 1120, 42387, 0, 1444, 9486, 7554, 65839, - 55252, 73972, 1442, 0, 5894, 70069, 0, 41171, 92511, 74313, 0, 13162, 0, - 3334, 195010, 118803, 77881, 66022, 0, 0, 1651, 128771, 8861, 0, 0, 1142, - 0, 8271, 0, 983058, 126645, 12903, 0, 4002, 43626, 10442, 10676, 3344, 0, - 0, 12920, 194560, 0, 0, 66642, 1277, 0, 7871, 0, 194686, 78853, 0, 78854, - 120360, 0, 11784, 0, 78012, 4700, 66366, 78858, 120359, 11012, 0, 78856, - 92400, 77879, 4973, 8784, 77877, 74804, 77874, 77869, 77871, 42440, 0, - 43118, 0, 42364, 6774, 6773, 917560, 120369, 10346, 10410, 78859, 9243, - 2464, 74263, 6108, 3372, 0, 6247, 43117, 74526, 7121, 74166, 0, 120355, - 92537, 0, 0, 195034, 0, 0, 0, 70083, 3354, 195037, 4192, 9289, 118999, - 41191, 3876, 0, 70067, 120660, 43696, 43380, 0, 983091, 0, 0, 11603, - 983954, 0, 6589, 128588, 194679, 0, 0, 983700, 0, 0, 42572, 128264, - 10630, 74827, 1963, 11622, 127098, 11654, 0, 7550, 10686, 5903, 0, 78009, - 41329, 9662, 917937, 64698, 3366, 10399, 0, 5542, 11013, 127927, 128300, - 0, 78621, 194672, 6925, 0, 0, 917929, 0, 11568, 983673, 43367, 64579, - 917930, 7852, 0, 0, 6754, 6312, 0, 64672, 65296, 0, 118957, 0, 416, - 12296, 68457, 73834, 68177, 11050, 10984, 92208, 0, 0, 92182, 0, 983605, - 9532, 66355, 0, 983234, 917925, 64343, 195032, 128281, 195031, 0, 195030, - 195057, 11445, 0, 2112, 195056, 128814, 10185, 1021, 128130, 9507, 10210, - 74544, 8023, 1200, 12243, 78001, 5282, 78003, 9624, 11545, 0, 120493, - 3343, 4424, 11047, 1885, 43268, 3896, 78444, 66497, 2947, 392, 7894, - 4391, 68139, 983062, 13059, 74816, 77998, 3381, 7942, 0, 69219, 0, 64757, - 0, 3913, 0, 0, 78235, 7044, 1265, 0, 6309, 7045, 7175, 7047, 78239, - 11791, 0, 0, 8221, 78307, 41864, 0, 0, 0, 0, 167, 983906, 78301, 983653, - 74211, 41897, 68477, 0, 917583, 983634, 94065, 2493, 0, 118811, 0, 0, - 64354, 0, 8777, 0, 406, 8884, 2385, 0, 92450, 0, 917573, 43030, 42027, - 12114, 0, 917579, 64936, 194695, 0, 120629, 10561, 0, 8365, 120539, - 983774, 65841, 120787, 11601, 0, 74121, 0, 917575, 7834, 74159, 0, - 917574, 10298, 6624, 4908, 917596, 1639, 0, 0, 74157, 6327, 6724, 0, - 128086, 92566, 69910, 4817, 78446, 194759, 92536, 7043, 9600, 11022, 0, - 0, 0, 0, 0, 0, 7548, 64794, 42050, 12291, 55289, 194761, 12343, 657, - 195054, 42705, 4461, 1134, 1838, 78438, 2057, 0, 4468, 0, 0, 0, 4456, - 5206, 10720, 0, 42523, 127520, 0, 0, 917595, 65550, 260, 4816, 67658, - 10687, 0, 4821, 4466, 0, 195043, 4818, 195048, 41403, 119977, 0, 0, - 41406, 43273, 74160, 119983, 73939, 92638, 119984, 119979, 41404, 1165, - 119980, 4451, 13087, 0, 11284, 119987, 70097, 65155, 43014, 5439, 9363, - 70070, 3375, 128869, 5900, 93990, 7889, 2722, 42262, 0, 0, 128774, 0, - 2282, 0, 127810, 11401, 983822, 0, 68459, 0, 0, 0, 0, 65438, 0, 7280, - 127887, 0, 127381, 4868, 8297, 119966, 118798, 0, 0, 43161, 0, 92360, 0, - 5182, 0, 120542, 0, 0, 4226, 119243, 12135, 5732, 4464, 0, 71330, 977, - 4458, 0, 0, 64770, 74838, 0, 344, 0, 194790, 1395, 64279, 0, 92240, 0, - 786, 0, 43174, 64340, 0, 194767, 120723, 43026, 7612, 10132, 64413, - 65025, 0, 0, 0, 93956, 0, 68444, 0, 92437, 0, 119160, 10204, 92656, 0, - 127809, 983644, 1399, 983652, 65217, 0, 8852, 128571, 241, 128780, 4907, - 0, 983639, 7932, 9727, 128873, 74255, 8748, 0, 0, 983643, 0, 42780, 0, 0, - 0, 4217, 0, 8650, 0, 0, 0, 69900, 118872, 43099, 3965, 119119, 6719, 0, - 13300, 78439, 93971, 43057, 66588, 118991, 0, 0, 73815, 4420, 0, 6410, - 7760, 0, 0, 0, 0, 0, 7294, 0, 0, 0, 9066, 0, 11993, 43188, 2626, 7762, 0, - 0, 0, 92601, 42825, 41854, 5304, 0, 78516, 6919, 8619, 119655, 10038, - 66454, 9592, 42851, 126993, 1542, 92303, 0, 0, 0, 0, 74311, 78497, 0, - 10181, 0, 43624, 0, 7779, 0, 10195, 9479, 6029, 0, 92268, 9689, 0, 65577, - 8993, 66358, 0, 42378, 3368, 606, 127030, 7697, 69237, 69787, 2030, 0, - 6027, 8370, 4322, 0, 65207, 0, 983339, 983338, 983337, 983336, 2735, - 42831, 77935, 127120, 74866, 8881, 119047, 0, 0, 73946, 0, 0, 0, 68140, - 983928, 9576, 128872, 3347, 4160, 5154, 55288, 3794, 66564, 8530, 127063, - 7709, 41112, 983132, 66560, 42041, 4572, 12876, 66561, 983758, 6758, - 983926, 1615, 5855, 809, 0, 92283, 128316, 128004, 5799, 983328, 70100, - 983326, 7260, 983324, 43031, 64425, 65128, 78819, 64386, 65257, 0, 68616, - 120607, 9347, 128067, 6532, 0, 0, 0, 127060, 65828, 0, 283, 68665, 78813, - 532, 78663, 0, 983796, 120609, 0, 3370, 0, 11361, 5443, 78778, 8153, - 73767, 0, 10741, 0, 2298, 0, 983917, 65495, 64706, 983318, 43344, 983316, - 7144, 9466, 78866, 9824, 983311, 983310, 0, 0, 915, 43425, 0, 0, 0, 0, - 127178, 43264, 70096, 0, 0, 43038, 78864, 6730, 78862, 68161, 64550, - 5186, 7360, 127837, 0, 12108, 0, 65124, 43127, 66043, 0, 6326, 43107, - 77826, 0, 42562, 0, 128821, 0, 128520, 11485, 6103, 127123, 983305, - 11718, 983303, 12889, 92657, 127137, 0, 0, 0, 55245, 0, 1630, 128232, - 65483, 0, 12565, 0, 65476, 120013, 0, 119554, 9283, 7700, 917537, 9690, - 65499, 0, 64593, 512, 3376, 68210, 0, 128677, 77892, 632, 12940, 77891, - 42529, 78587, 0, 5957, 110593, 8926, 983299, 983298, 128273, 10745, - 10174, 7379, 64581, 5386, 120686, 11713, 10633, 69708, 5056, 0, 0, 0, - 120773, 0, 9812, 0, 4460, 0, 0, 71307, 128038, 0, 0, 127174, 64278, - 92370, 43466, 0, 0, 64389, 2953, 73879, 1801, 12835, 119029, 0, 73823, 0, - 66375, 2085, 702, 42579, 77884, 77885, 13074, 77883, 983286, 983285, - 128570, 12106, 983282, 74207, 1755, 10482, 12863, 77898, 1163, 2951, - 9522, 74079, 78266, 66604, 0, 3384, 69227, 10702, 830, 77902, 77899, - 77900, 8451, 0, 0, 0, 69739, 0, 0, 0, 0, 2908, 0, 43386, 64902, 4243, 0, - 12239, 0, 0, 4441, 0, 983279, 73940, 64352, 127513, 983275, 411, 983273, - 9199, 983271, 4056, 118992, 41890, 0, 2730, 41604, 983937, 5428, 194743, - 3364, 42265, 64437, 127935, 118816, 194742, 9684, 216, 0, 1401, 128053, - 44012, 0, 0, 92585, 9158, 77842, 69905, 5768, 0, 0, 0, 484, 194739, 0, 0, - 65895, 0, 0, 3338, 73935, 572, 7041, 2736, 67605, 983263, 93962, 2794, - 8807, 64491, 77847, 5438, 5222, 5381, 43114, 0, 5193, 5125, 5456, 5509, - 77846, 194747, 9534, 0, 0, 0, 3430, 0, 0, 78717, 0, 981, 0, 4330, 73929, - 120536, 1824, 10908, 0, 7034, 41683, 64617, 0, 73754, 3957, 64358, 64547, - 128259, 674, 63991, 983249, 2946, 5354, 5251, 5328, 5307, 3759, 11411, - 8364, 5123, 119628, 5281, 5469, 5121, 119245, 118993, 0, 5130, 0, 0, - 77990, 0, 120726, 1221, 2733, 11746, 77991, 5216, 0, 0, 0, 0, 3468, 7033, - 9230, 5939, 195052, 0, 0, 120677, 68400, 7278, 10321, 10289, 64613, - 10385, 41706, 0, 0, 983413, 0, 11739, 983426, 41981, 0, 5938, 0, 43766, - 12448, 7576, 10401, 10337, 73852, 0, 13057, 0, 126976, 0, 10009, 0, - 41703, 983638, 12165, 0, 0, 9885, 0, 8077, 0, 127908, 0, 0, 0, 92457, 0, - 4220, 10725, 10433, 0, 68395, 4987, 64519, 0, 128340, 0, 0, 0, 10970, - 11733, 0, 120792, 0, 19944, 0, 9009, 8551, 92345, 11468, 64636, 7575, 0, - 2724, 0, 0, 12313, 110592, 515, 119947, 42791, 63987, 78286, 119943, - 119940, 119941, 119938, 9775, 4046, 4589, 4521, 68629, 9141, 0, 78850, - 2741, 64399, 6197, 1370, 0, 0, 0, 0, 0, 0, 6184, 8606, 3303, 41372, - 11786, 9473, 66203, 66177, 92446, 11593, 43007, 4478, 66178, 0, 0, 2744, - 0, 4477, 118964, 814, 42066, 66183, 66204, 43786, 119961, 66198, 41880, - 66188, 11623, 78148, 11955, 66190, 66191, 41111, 66189, 73788, 7788, - 4847, 0, 127759, 0, 0, 0, 1581, 6535, 78161, 12954, 430, 78160, 55259, - 78158, 128036, 5278, 4945, 42883, 4950, 983438, 68625, 983436, 7269, 0, - 5964, 12908, 983555, 0, 74764, 74477, 119146, 194936, 4949, 983429, 443, - 983427, 4944, 5467, 119603, 983254, 65137, 6044, 65392, 0, 4213, 0, - 41303, 0, 194931, 119962, 41306, 73984, 2698, 127159, 0, 12072, 3193, 0, - 41304, 824, 128676, 12091, 78893, 78894, 119816, 4673, 64804, 4678, - 119820, 119819, 65059, 0, 6739, 0, 5481, 3490, 1199, 119811, 8356, 69947, - 119832, 4677, 12688, 3102, 0, 4672, 78173, 78175, 5531, 68367, 42575, - 78170, 78166, 4674, 4548, 44005, 119949, 68658, 119946, 8025, 68630, - 127024, 1855, 983412, 68669, 983410, 92445, 127554, 0, 127339, 119652, - 2745, 11797, 983418, 128159, 9202, 4654, 983414, 983416, 68638, 73993, - 10525, 4649, 65209, 983417, 0, 4648, 43080, 983406, 983407, 983404, 6246, - 64950, 7828, 4650, 6777, 6776, 6775, 4653, 7822, 78005, 92384, 43187, - 8669, 983415, 6821, 65093, 0, 78881, 2716, 0, 983060, 983419, 0, 68369, - 120054, 11060, 8547, 2711, 42165, 78027, 78026, 7992, 0, 0, 4662, 78033, - 78032, 9149, 9146, 599, 2081, 78031, 78030, 194962, 4656, 10130, 68450, - 7811, 40994, 194965, 6414, 5967, 4658, 3725, 5713, 5814, 4661, 42434, - 983411, 0, 0, 64904, 9026, 10833, 74864, 7547, 4867, 0, 10008, 10222, - 3054, 194956, 9744, 78860, 7605, 4622, 119656, 983395, 94070, 983393, - 983394, 983391, 9045, 78888, 4225, 19926, 78887, 12880, 65307, 4617, - 78883, 983386, 41732, 4616, 10518, 10423, 10359, 983380, 5958, 0, 983433, - 4215, 9789, 917941, 4321, 4621, 983389, 41313, 522, 5368, 0, 65803, 0, - 5366, 12201, 5372, 0, 983409, 0, 7720, 7390, 2696, 983400, 0, 4638, - 983405, 1790, 78242, 5965, 64363, 66569, 68646, 127833, 5376, 1835, 5335, - 194966, 128089, 4633, 0, 68119, 1180, 4632, 128093, 5387, 5333, 0, 0, - 42094, 5331, 4634, 11928, 983594, 5338, 4637, 128170, 5971, 42414, 0, - 1268, 65097, 42361, 0, 0, 73853, 1427, 0, 0, 5970, 3431, 0, 10358, 10422, - 4758, 983374, 1608, 2738, 0, 10455, 4753, 74026, 11344, 4222, 6240, 5231, - 74384, 983378, 68377, 6248, 983362, 983363, 983360, 42318, 92582, 5229, - 4757, 0, 0, 2728, 4752, 64563, 65235, 5234, 0, 128145, 0, 10713, 7166, 0, - 2622, 7460, 127302, 0, 0, 8954, 74760, 65189, 2632, 42617, 10108, 1011, - 5574, 1853, 2709, 65139, 5577, 0, 0, 118871, 68641, 8965, 7635, 42177, - 5316, 0, 5314, 6451, 5572, 66464, 5312, 0, 5525, 5330, 5319, 983420, - 983872, 194907, 44003, 0, 983480, 983423, 120498, 127851, 195009, 983865, - 74022, 983422, 64609, 68643, 120634, 983489, 5721, 983401, 5519, 8632, - 66465, 11267, 73961, 92278, 5720, 983352, 1692, 4219, 4610, 8696, 4305, - 0, 4609, 43478, 4614, 541, 983355, 5287, 5309, 5285, 68389, 5961, 4647, - 56, 4216, 10577, 41381, 601, 4613, 983349, 983346, 77849, 4608, 64260, - 41124, 5190, 67628, 0, 68145, 7086, 0, 67998, 67620, 0, 2734, 11074, 0, - 67627, 43593, 0, 67625, 5960, 0, 8992, 42593, 128260, 1782, 67622, 68114, - 119939, 0, 68180, 5501, 119952, 42508, 7442, 43665, 359, 41253, 68392, - 6239, 119956, 41256, 0, 68134, 0, 74209, 917550, 9346, 69660, 41254, - 128047, 43291, 3767, 5737, 0, 4865, 0, 5740, 917997, 5736, 4368, 64724, - 7193, 68137, 0, 5739, 41024, 4866, 0, 73904, 983840, 4869, 120563, 0, - 4223, 128201, 6650, 126509, 0, 983463, 127890, 4870, 120445, 68661, 6716, - 78176, 68667, 68382, 68676, 127925, 10122, 4864, 66568, 4144, 7937, 0, - 6245, 68652, 2732, 42734, 745, 0, 195097, 92195, 4777, 7821, 0, 68631, - 42775, 0, 194954, 0, 3097, 0, 5966, 983486, 4778, 0, 10863, 0, 4781, 0, - 64407, 0, 128323, 8577, 128562, 68196, 43285, 10216, 4782, 0, 0, 120757, - 68618, 12325, 43056, 8717, 0, 0, 4776, 73818, 11492, 8700, 0, 13176, - 68363, 10426, 0, 917599, 10362, 194706, 1715, 4849, 8242, 9561, 73922, - 43278, 42635, 0, 0, 5963, 917926, 0, 0, 4850, 0, 1607, 466, 4853, 118995, - 4854, 127918, 5164, 983870, 1350, 5124, 64420, 1993, 5362, 8471, 2708, - 92471, 12445, 3785, 234, 3199, 0, 41268, 4848, 2530, 917909, 2068, 1964, - 0, 73762, 10458, 0, 8576, 78543, 0, 2704, 4794, 0, 68211, 8322, 4797, - 5753, 0, 2694, 4792, 0, 2439, 65104, 69804, 983424, 303, 983101, 92622, - 983425, 2437, 0, 4221, 4844, 92216, 0, 0, 0, 70042, 0, 43292, 0, 2441, - 10739, 65090, 0, 119327, 126541, 2451, 2714, 119326, 0, 43379, 4937, - 43376, 753, 5849, 10597, 43089, 11722, 9248, 92555, 42879, 11725, 0, 0, - 2726, 3107, 73958, 4941, 64937, 119233, 9140, 1408, 5261, 4607, 0, 181, - 983430, 4942, 9539, 4938, 0, 65201, 5259, 9369, 64185, 4142, 5257, - 983601, 0, 4964, 5264, 64178, 64177, 12979, 41411, 64182, 64181, 64180, - 64179, 9482, 4873, 41231, 1822, 42526, 128581, 12758, 3865, 0, 0, 10500, - 0, 119024, 78028, 92408, 9830, 43642, 389, 10893, 7521, 127879, 4872, - 5463, 0, 3125, 9567, 0, 4878, 5459, 4604, 917931, 9557, 5465, 68617, 0, - 11494, 126492, 9563, 10865, 74570, 43279, 64186, 983439, 78714, 64191, - 64190, 8898, 64188, 0, 41030, 78836, 0, 917835, 78820, 917834, 0, 78805, - 41031, 78801, 11960, 6745, 3082, 983437, 78539, 73919, 10573, 41744, - 7079, 5856, 127043, 5163, 78809, 128162, 1817, 66724, 78538, 0, 10564, - 7763, 13077, 41813, 4400, 41745, 64207, 10275, 8925, 10371, 10307, 41814, - 4248, 0, 0, 4541, 6299, 64204, 64203, 64201, 64200, 64199, 64198, 126471, + 77836, 64528, 1169, 434, 41437, 1905, 6034, 41164, 64744, 9528, 67741, + 128800, 524, 0, 74029, 788, 74027, 194667, 71881, 0, 1663, 10419, 42901, + 42636, 67211, 67210, 129147, 120656, 67215, 67214, 67213, 67212, 0, + 67897, 74039, 0, 0, 11395, 0, 119107, 43612, 64344, 194732, 0, 10855, + 5445, 9355, 67221, 65198, 7391, 8989, 221, 65686, 983874, 119238, 8010, + 7191, 4962, 69772, 8855, 74612, 70820, 64469, 92592, 10555, 67227, 43333, + 67225, 128483, 120427, 10451, 67229, 67653, 7245, 12443, 74405, 9947, + 120149, 78317, 3873, 8367, 77842, 120146, 43433, 43649, 11987, 83343, + 983581, 11010, 11164, 74059, 74062, 6217, 5896, 43846, 7682, 74049, 1462, + 10235, 0, 0, 983325, 43441, 127924, 127777, 42595, 126641, 74402, 118860, + 78661, 120419, 92497, 66287, 120420, 92378, 120549, 119082, 64295, + 120418, 0, 64765, 73923, 83210, 120662, 69920, 194702, 6216, 67230, + 10755, 9455, 11155, 8124, 127042, 9470, 6944, 121125, 0, 69680, 2828, 0, + 531, 42638, 194804, 917856, 120961, 43428, 8204, 3614, 2827, 9696, + 120365, 0, 8728, 4354, 10904, 78562, 19936, 7833, 120691, 120850, 42599, + 42597, 42709, 68829, 125012, 0, 8537, 127306, 0, 9354, 121244, 121348, + 41199, 10121, 2028, 74950, 120253, 69715, 128525, 3062, 0, 74447, 12608, + 983657, 66440, 7545, 9700, 11948, 92205, 120777, 120502, 41155, 68306, + 74071, 0, 983459, 12713, 127519, 70402, 0, 78772, 113770, 1734, 0, 78141, + 127040, 64594, 2456, 231, 68227, 74167, 542, 917981, 118786, 983859, + 194797, 1230, 125018, 121343, 3597, 4446, 10584, 74235, 92215, 4037, + 67737, 8352, 78436, 5687, 127018, 64515, 121378, 194801, 55265, 67846, + 78434, 9704, 0, 194573, 70080, 71338, 0, 8660, 126478, 0, 128569, 78773, + 74482, 4483, 1709, 69721, 9909, 6080, 194851, 120358, 1746, 1315, 8667, + 983101, 0, 13140, 65899, 10604, 0, 4480, 11266, 121114, 1226, 6930, + 67979, 195019, 6360, 10897, 41230, 605, 68302, 74785, 69875, 0, 121478, + 41500, 0, 311, 11453, 6221, 10608, 64943, 67682, 10877, 118868, 64885, + 74272, 0, 194672, 128559, 120736, 74312, 345, 124933, 74456, 64606, 9917, + 0, 74855, 5037, 119912, 1776, 8422, 128935, 118814, 41508, 41201, 323, + 43328, 0, 42698, 1295, 194853, 4625, 77855, 4630, 13117, 83002, 128772, + 65123, 11293, 2668, 11288, 0, 42640, 65666, 2519, 92369, 65420, 92479, 0, + 4252, 5049, 42659, 119011, 706, 7754, 10854, 8738, 983949, 65419, 0, + 128496, 649, 65421, 0, 66702, 983721, 12670, 1013, 0, 64919, 705, 0, + 65422, 127803, 1183, 126519, 7017, 42852, 917826, 8157, 9736, 64503, + 65418, 129050, 983878, 74035, 194918, 11913, 73874, 6696, 120916, 8920, + 119298, 128426, 7962, 12211, 9837, 2051, 66227, 0, 4184, 119825, 128598, + 10177, 73777, 1857, 194657, 4626, 8464, 8472, 68844, 4629, 8499, 74627, + 78322, 4624, 7818, 118861, 128108, 0, 7805, 128754, 94007, 6935, 92292, + 78325, 78326, 78323, 43327, 43989, 119046, 8492, 8250, 8459, 0, 8497, + 8496, 83499, 74582, 75052, 78339, 9543, 67860, 78332, 77832, 65849, + 77831, 983961, 194649, 12451, 74376, 8684, 128301, 6102, 0, 5298, 917847, + 5294, 0, 83016, 68043, 195062, 9949, 83014, 43617, 119215, 0, 12073, 0, + 128646, 77863, 13108, 120617, 11439, 41468, 83012, 0, 5292, 55272, + 983883, 1939, 5302, 3970, 917877, 12455, 1793, 124982, 0, 75036, 6643, + 92477, 65263, 0, 78330, 41293, 78328, 65923, 78835, 13219, 9569, 129041, + 74383, 0, 74197, 129089, 5500, 8813, 0, 128612, 68860, 5322, 120944, + 78340, 43631, 5324, 66443, 3784, 41614, 65269, 6230, 78349, 78345, 13282, + 3360, 78344, 11523, 0, 92488, 9926, 7197, 128248, 68429, 42894, 41821, + 1249, 78360, 78361, 78356, 78358, 78353, 64899, 64763, 41149, 41807, + 43162, 41815, 41150, 128911, 10571, 10096, 67161, 67160, 67159, 6947, + 41152, 887, 9249, 6565, 78510, 41990, 78509, 41811, 67157, 93966, 6670, + 67175, 67174, 0, 43092, 43325, 67178, 10168, 67176, 9781, 68248, 9190, + 128497, 9666, 8269, 65944, 74005, 13019, 11670, 69860, 315, 12813, + 129132, 72409, 78256, 72408, 78352, 0, 75063, 0, 0, 1378, 9509, 194634, + 92996, 72407, 3066, 92220, 67847, 72406, 92355, 917890, 78365, 8787, + 67189, 194616, 41618, 194615, 78261, 127384, 0, 64652, 121222, 121012, 0, + 78366, 42088, 71040, 195061, 7176, 43756, 10137, 6121, 10995, 78259, + 71050, 8119, 64874, 71052, 78174, 128690, 128630, 74525, 0, 0, 12930, + 1394, 74514, 128413, 74515, 983727, 67184, 2998, 9527, 67181, 65190, + 12977, 42090, 67185, 983647, 119100, 41236, 92235, 42005, 42003, 41237, + 5848, 67193, 67192, 3670, 67190, 67197, 67196, 67195, 7890, 128070, + 11298, 43315, 983315, 6229, 1593, 0, 125120, 619, 4635, 65080, 127158, + 12194, 4120, 65337, 65336, 128407, 11808, 67199, 67198, 9366, 42790, + 42006, 119115, 65327, 65326, 65325, 10757, 1507, 42216, 65321, 65320, + 43947, 65334, 43946, 65332, 65331, 42059, 65329, 42689, 92427, 9128, + 94045, 42073, 6785, 64590, 983830, 4371, 7196, 65318, 2035, 65316, 4106, + 65314, 65313, 42074, 127847, 41228, 120862, 65609, 41241, 7903, 41239, + 43533, 78459, 7189, 0, 0, 43941, 12357, 42802, 78450, 8487, 9131, 66292, + 4615, 12695, 127752, 0, 12175, 0, 64535, 0, 7809, 0, 121351, 562, 12169, + 6590, 69762, 66455, 64738, 3219, 68654, 121096, 128281, 1037, 128677, + 2025, 128263, 13098, 78442, 10637, 4568, 549, 1570, 43839, 2835, 83052, + 10624, 43623, 11072, 83045, 128523, 83046, 12606, 78433, 2825, 83048, + 10825, 8079, 2821, 41046, 92327, 7365, 83043, 120593, 13071, 121288, 452, + 41049, 42840, 6346, 2831, 5461, 74596, 11465, 5212, 917917, 64703, + 119191, 42308, 7181, 0, 41332, 0, 12333, 41047, 1668, 119849, 121150, + 128275, 1187, 983387, 42628, 78575, 82953, 71863, 82955, 3240, 128518, + 12151, 0, 11591, 41065, 5323, 8166, 0, 118932, 0, 66827, 1623, 65297, + 128856, 571, 0, 4918, 0, 5288, 127295, 1541, 65048, 1909, 8864, 0, 66402, + 10736, 92508, 11571, 7615, 70476, 92296, 4237, 92576, 1035, 65815, 68083, + 3567, 701, 65936, 3489, 120899, 70462, 70172, 11403, 0, 0, 82986, 3796, + 6800, 70472, 3994, 11421, 74611, 195076, 195078, 68036, 0, 0, 64857, + 83508, 2855, 74418, 66308, 41621, 68214, 83513, 127817, 10654, 82945, + 119226, 12164, 3246, 7906, 43972, 65847, 7182, 0, 13024, 66276, 74270, + 83069, 125090, 121115, 0, 1496, 747, 0, 942, 2378, 43136, 83031, 8466, + 83075, 9320, 8001, 1232, 8139, 11617, 74637, 0, 11409, 68373, 6382, + 126500, 64634, 92362, 70202, 11612, 93008, 67600, 2374, 94066, 8475, + 11609, 66313, 92568, 0, 5286, 119297, 83059, 983253, 64925, 120283, + 127204, 118982, 71905, 7705, 11942, 11305, 127203, 3309, 82979, 9206, + 82980, 113824, 6802, 70353, 41653, 1280, 1241, 7168, 12096, 0, 66615, + 42565, 41651, 0, 917627, 83042, 41650, 66507, 66470, 74472, 12914, 41491, + 43901, 94106, 6078, 9954, 78822, 1475, 119247, 9938, 6084, 917546, 41064, + 41062, 0, 113680, 3256, 10189, 42076, 43252, 78823, 68089, 8727, 120922, + 65875, 0, 0, 127762, 10562, 74215, 43065, 120906, 0, 3248, 74297, 3261, + 9015, 71351, 0, 3635, 64337, 92759, 125054, 0, 7195, 83346, 2007, 64431, + 195075, 0, 92197, 127090, 635, 0, 129082, 65613, 77909, 92420, 73997, + 128510, 121457, 43905, 7984, 8600, 74434, 127770, 4176, 70050, 2034, + 78423, 11154, 65891, 127038, 0, 318, 2038, 128544, 78596, 194602, 3649, + 13149, 42145, 42798, 3634, 120291, 71885, 67677, 120124, 7866, 75045, + 11402, 42146, 94032, 74238, 42664, 2849, 127034, 0, 7938, 12960, 1761, + 11812, 65379, 68386, 128185, 1159, 71183, 69729, 0, 120797, 7178, 120851, + 983836, 41680, 128469, 83098, 11534, 1514, 11668, 67891, 9313, 7015, + 128490, 67877, 194561, 12989, 66474, 9368, 12848, 1624, 43270, 0, 74278, + 10818, 83091, 9953, 194895, 78421, 1194, 3242, 9761, 9555, 8598, 120299, + 6169, 12871, 1551, 2798, 65176, 4958, 42752, 119025, 917924, 67875, + 120301, 3495, 66648, 125079, 83354, 68364, 120779, 4891, 0, 10641, 0, + 73746, 120945, 68352, 0, 73787, 128858, 127094, 7199, 11131, 0, 0, 0, + 983852, 126979, 42685, 42679, 193, 78789, 0, 0, 42667, 0, 5271, 68323, + 92517, 83356, 1362, 13297, 0, 71880, 0, 983333, 73789, 0, 6658, 4426, 0, + 66830, 983842, 83103, 7276, 42163, 5220, 0, 78621, 67822, 2416, 3310, + 42703, 83107, 379, 0, 43755, 70504, 43647, 3223, 65492, 1284, 194771, + 4549, 194738, 0, 71253, 70784, 10807, 9558, 93027, 0, 8515, 8688, 12866, + 65308, 3294, 83143, 8529, 128101, 43385, 7564, 0, 43329, 83148, 92458, + 73757, 66456, 42359, 128439, 2031, 983890, 7202, 128232, 12676, 42729, + 74777, 3215, 120982, 7710, 1610, 73801, 128807, 0, 65682, 0, 43917, + 65924, 9974, 228, 43922, 1501, 127994, 64395, 5179, 7200, 6225, 118927, + 42999, 1725, 65533, 8196, 7476, 74399, 0, 66868, 7152, 8502, 5762, 1967, + 7483, 43898, 0, 8104, 70128, 7474, 43914, 83080, 126507, 10414, 13001, + 8141, 983239, 42537, 1557, 43594, 128642, 6330, 6805, 8631, 2545, 42934, + 127166, 0, 74190, 128477, 70410, 983786, 42762, 194708, 42914, 1650, 262, + 1637, 128502, 7901, 3238, 83026, 41861, 0, 120211, 65158, 10860, 74959, + 43658, 7527, 83086, 43319, 6419, 0, 45, 0, 64588, 93989, 127753, 119810, + 7194, 5291, 0, 43666, 13129, 128684, 9084, 121039, 8737, 983165, 12881, + 75066, 12906, 9639, 7912, 2620, 983882, 3564, 0, 69978, 179, 43644, + 75049, 64756, 2853, 78443, 118813, 129042, 70347, 119009, 2850, 8084, + 983085, 73850, 2801, 92284, 42069, 119839, 74754, 83522, 42072, 92736, + 119842, 10398, 83386, 83523, 8377, 119312, 8245, 68401, 3158, 92396, + 3983, 43656, 923, 119857, 92470, 292, 11119, 119845, 119844, 3221, 1763, + 92463, 4612, 67729, 119850, 7253, 70456, 68391, 75002, 10782, 3637, + 12996, 43542, 113676, 64578, 83449, 3228, 69636, 8783, 983632, 119614, + 2731, 0, 120833, 78585, 4102, 7696, 73878, 121417, 128132, 70813, 43316, + 4177, 11283, 9089, 120918, 73996, 121111, 64500, 43674, 0, 64947, 1856, + 0, 0, 6379, 917804, 11142, 127176, 3208, 12975, 74775, 127380, 983931, + 92389, 74072, 55269, 0, 124962, 983683, 2033, 78577, 78576, 82965, 55254, + 7740, 82974, 70448, 126555, 73964, 68505, 93988, 67612, 65674, 128244, + 94110, 41689, 0, 74006, 64909, 6646, 11790, 74019, 128520, 128066, + 128031, 8561, 4573, 121375, 5326, 92571, 120605, 7230, 8257, 121415, + 8778, 41688, 0, 65776, 2071, 8314, 6459, 43511, 7628, 65092, 73903, + 64355, 11342, 128561, 0, 983434, 128226, 127001, 0, 11810, 13164, 10723, + 967, 983335, 120985, 11946, 983602, 3257, 127209, 12307, 1845, 129072, + 43526, 0, 119573, 1886, 42342, 10089, 870, 7648, 3499, 7662, 7652, 876, + 871, 877, 7665, 878, 42015, 879, 43692, 4563, 0, 917892, 7591, 65887, + 867, 9520, 872, 7656, 868, 873, 7642, 7659, 869, 874, 7644, 120674, 875, + 790, 128303, 118938, 195053, 93038, 66182, 194623, 5429, 195055, 66180, + 126480, 66181, 68452, 983291, 127214, 42067, 0, 5433, 10657, 7911, + 125119, 1547, 66176, 42012, 120576, 5425, 4977, 9999, 5317, 5423, 4611, + 125094, 67637, 127286, 9679, 74122, 92978, 917585, 0, 66194, 4418, 66184, + 4628, 4245, 119648, 0, 127263, 1851, 124995, 83320, 11908, 0, 9360, + 118897, 120874, 42776, 66187, 12837, 8829, 7711, 11112, 0, 92321, 43318, + 92302, 8809, 69881, 0, 126518, 120604, 983052, 983277, 983433, 128412, 0, + 120577, 7427, 9958, 4588, 43680, 0, 74484, 127185, 2433, 128602, 69973, + 3352, 74363, 128668, 121341, 793, 74404, 11197, 305, 567, 67662, 842, + 69979, 8208, 68308, 41695, 1647, 118877, 70841, 7837, 917625, 818, 5337, + 194628, 917621, 41376, 119978, 68742, 120594, 74086, 68777, 70179, + 917613, 10973, 66359, 1372, 127172, 917608, 4969, 1254, 917605, 194654, + 93967, 917602, 65228, 78221, 126612, 67723, 2840, 983905, 78829, 983939, + 66887, 3245, 9068, 68194, 64725, 121161, 128051, 12991, 124971, 2651, + 68016, 983267, 127326, 125038, 70835, 0, 70844, 43648, 120812, 917833, + 43322, 92662, 0, 0, 64372, 92698, 3226, 655, 752, 7457, 7456, 7452, 3285, + 74894, 11152, 92903, 65610, 2391, 92908, 92248, 671, 250, 7434, 618, 668, + 610, 42800, 7431, 1152, 42801, 640, 120666, 7448, 7439, 628, 3905, 73810, + 128340, 128266, 64749, 67850, 2107, 128290, 74249, 4605, 128174, 983192, + 43372, 65945, 127249, 11113, 119590, 0, 0, 70495, 987, 6927, 11572, + 42261, 11464, 3365, 9971, 0, 983951, 128297, 0, 78762, 127867, 121368, + 11334, 43326, 12609, 11519, 11503, 5530, 5210, 0, 4627, 119269, 5208, 0, + 70090, 10332, 2424, 7976, 9156, 0, 3244, 5529, 69647, 73894, 128852, + 5432, 64965, 5527, 42315, 10516, 7790, 5528, 128838, 42140, 120281, 0, + 983777, 43545, 9887, 121477, 4000, 7429, 7428, 665, 7424, 3206, 120278, + 7884, 0, 128566, 74910, 128666, 211, 2509, 92904, 70822, 68672, 3220, + 42235, 78480, 10690, 8951, 5214, 42474, 8118, 0, 7048, 4590, 127258, + 5852, 0, 78482, 127259, 1708, 0, 78481, 2623, 11943, 128700, 69226, + 69974, 4698, 66509, 1066, 119921, 4701, 983876, 120285, 70447, 94111, + 8267, 0, 1421, 66426, 7516, 127552, 2625, 983641, 8034, 74309, 0, 3631, + 10955, 7850, 120293, 8416, 0, 983065, 0, 43384, 12660, 128693, 128270, 0, + 74850, 41069, 70185, 128156, 12099, 4310, 10032, 6252, 713, 7990, 983489, + 3990, 125050, 983264, 66368, 5017, 64956, 7071, 0, 70457, 1030, 118800, + 92563, 9513, 41059, 9357, 74988, 1773, 77939, 120350, 124961, 6339, 7745, + 9844, 127220, 64650, 94, 1880, 74766, 113719, 8908, 983222, 128707, + 65913, 78470, 10752, 13003, 68769, 126572, 41307, 8732, 120336, 0, 1757, + 6964, 4696, 0, 120333, 64785, 7394, 3641, 5419, 128055, 0, 127883, + 194707, 120344, 43988, 70423, 8610, 43062, 7592, 856, 74299, 936, 13289, + 69894, 43171, 1459, 128224, 65243, 78638, 19953, 129078, 1504, 70064, 0, + 12913, 74206, 7529, 128745, 127868, 70203, 120782, 4113, 120929, 2372, + 336, 0, 7509, 12152, 194885, 682, 7655, 41505, 0, 64743, 10593, 1703, + 92467, 77911, 8033, 69953, 0, 9810, 127269, 120013, 12970, 0, 42351, + 10109, 74535, 74068, 74921, 0, 92690, 0, 65068, 74291, 1965, 7069, 43312, + 0, 73887, 11130, 2087, 64370, 6314, 41714, 8501, 11145, 121117, 74239, + 41317, 92614, 2091, 74545, 2090, 69912, 9353, 7117, 2077, 77886, 11161, + 10498, 2083, 77888, 71196, 0, 119236, 634, 124970, 92290, 194886, 69779, + 4165, 8746, 195048, 9654, 12856, 6924, 7660, 7066, 194693, 70415, 128135, + 41037, 42692, 7786, 12959, 41039, 127483, 124965, 680, 2302, 128200, + 1181, 7056, 3174, 67248, 0, 92668, 65665, 127375, 113776, 6920, 0, 92295, + 126606, 118965, 68318, 64644, 126981, 74119, 68238, 41028, 74025, 6231, + 2613, 65302, 40989, 68239, 68230, 68234, 42760, 0, 43896, 0, 40987, 4667, + 0, 71843, 8828, 77995, 70506, 1246, 4746, 128501, 128508, 11021, 4749, + 92675, 917882, 921, 4744, 0, 12702, 242, 0, 1566, 8217, 127210, 64653, + 78386, 74617, 74036, 74505, 43274, 5313, 951, 74568, 92983, 983867, 7604, + 983292, 4009, 70277, 71844, 120562, 0, 983720, 64860, 119138, 119069, 0, + 127370, 4048, 983598, 83009, 70024, 1646, 77890, 64534, 73995, 120705, + 129047, 119890, 2579, 119905, 3177, 11357, 9099, 4107, 3441, 119894, + 2975, 74442, 9822, 983935, 55220, 10084, 73943, 118840, 0, 917562, 78299, + 3399, 9851, 917609, 11909, 9059, 0, 7687, 0, 6789, 127767, 0, 71842, + 70178, 92314, 0, 1777, 9151, 1137, 66867, 749, 42366, 70444, 5385, 70791, + 72435, 70127, 83377, 5989, 128905, 74636, 120848, 0, 41685, 69223, 0, + 9769, 41684, 194737, 519, 119231, 11740, 5766, 0, 0, 2600, 8848, 70416, + 41297, 0, 3666, 70420, 41300, 74468, 65160, 0, 69688, 69771, 74479, 0, + 6558, 127149, 128064, 69765, 92775, 252, 0, 41302, 119350, 83504, 118839, + 69763, 68762, 11729, 8719, 9060, 129091, 120139, 10761, 0, 0, 129410, + 118792, 11734, 93011, 11730, 113741, 9593, 5757, 2403, 64808, 55275, 0, + 11728, 43572, 983139, 0, 7764, 68741, 11094, 120825, 0, 43489, 4282, + 8298, 0, 0, 70328, 194986, 70324, 64449, 0, 126650, 63854, 8456, 65587, + 70442, 65670, 983963, 78250, 0, 7774, 10607, 9792, 983869, 70326, 0, + 71460, 120764, 70322, 10019, 74762, 0, 3458, 4365, 70053, 983712, 3647, + 120207, 2602, 128341, 121103, 125043, 41135, 83498, 0, 121325, 64631, + 172, 4971, 41219, 41137, 1889, 7238, 6545, 126476, 77926, 7597, 10528, + 75054, 0, 3732, 73910, 194588, 5344, 983971, 43366, 43363, 9062, 119252, + 121441, 92528, 0, 64479, 9232, 92596, 83330, 113707, 194712, 10900, + 41531, 1263, 3720, 12048, 74075, 64292, 41524, 7227, 119635, 6099, 41534, + 0, 127354, 127345, 299, 83022, 8525, 127347, 3524, 917565, 8831, 127349, + 92564, 3075, 67867, 94053, 0, 66362, 0, 64353, 70440, 0, 5845, 121310, 0, + 121185, 2581, 8200, 65114, 68460, 983693, 43283, 5551, 0, 120735, 983201, + 6340, 118855, 121027, 78134, 8680, 7204, 70065, 2588, 2914, 7011, 55281, + 0, 2471, 194631, 2883, 2749, 119563, 73774, 10913, 83116, 983086, 8666, + 675, 42493, 121297, 43571, 0, 6219, 128584, 9980, 41232, 10928, 0, 41153, + 41229, 118967, 0, 3738, 94016, 983243, 12711, 3181, 66212, 74289, 68472, + 42857, 8262, 93036, 0, 74476, 0, 42347, 12092, 9615, 7234, 74047, 983088, + 128137, 43744, 0, 0, 73846, 2934, 12722, 120762, 922, 43983, 74507, + 983126, 74461, 3218, 120471, 74290, 120469, 64562, 120475, 8569, 11404, + 11932, 73728, 3214, 11212, 120468, 12128, 3207, 65486, 78729, 1901, + 78727, 65667, 120460, 7425, 3205, 68003, 78737, 78736, 78735, 43383, + 69940, 65459, 2606, 78730, 73897, 129043, 11496, 1173, 0, 41272, 119661, + 0, 0, 83178, 120737, 120953, 194773, 983322, 378, 2610, 983328, 65079, + 983327, 65695, 121220, 37, 7068, 0, 120480, 68236, 3209, 120477, 120835, + 10638, 9768, 69952, 119909, 71486, 92225, 983953, 983340, 0, 43840, 0, 0, + 5233, 983337, 64792, 71233, 128223, 126633, 128919, 7060, 9847, 120144, + 1685, 595, 83197, 70428, 1292, 8940, 7380, 11088, 0, 10004, 126997, 0, + 6541, 43837, 71465, 121030, 3243, 9014, 5606, 125032, 538, 64620, 5602, + 8467, 74391, 6547, 71466, 8203, 66420, 68241, 8458, 65211, 8495, 92311, + 127481, 917552, 779, 78314, 64367, 2465, 69901, 8193, 55279, 9730, 9280, + 120913, 7065, 74155, 4346, 113690, 73798, 504, 125115, 92414, 8982, 0, + 121471, 119170, 782, 129028, 10883, 128446, 194852, 732, 3737, 121188, + 1548, 68650, 92507, 1832, 5604, 5735, 41141, 119020, 4376, 983372, 11787, + 3745, 917868, 119885, 42888, 65712, 127913, 3869, 11937, 5725, 127539, + 1783, 7416, 5728, 0, 128457, 119554, 11918, 66567, 5724, 127965, 5727, + 78521, 121121, 0, 764, 0, 121011, 43531, 113670, 9033, 127182, 42532, + 6223, 11042, 120749, 11423, 74852, 119861, 68303, 43465, 0, 74767, 6559, + 64557, 71348, 92649, 120648, 43019, 43477, 10238, 74491, 128711, 43377, + 92282, 71346, 1478, 9783, 11825, 2607, 64740, 113689, 7739, 74543, + 917765, 67393, 0, 6132, 0, 63765, 128396, 70058, 41144, 71899, 92438, + 43537, 6761, 10093, 4369, 917791, 128394, 194776, 8820, 3947, 0, 65299, + 11515, 526, 128103, 41295, 194603, 125002, 194932, 113691, 7688, 917786, + 7686, 8288, 11815, 983188, 121411, 983384, 1543, 3713, 41221, 12423, + 42281, 78544, 74024, 12293, 983680, 64357, 11794, 42082, 128125, 1737, + 8987, 42081, 0, 7205, 83264, 9335, 12850, 119173, 6553, 7055, 68041, + 8277, 0, 67751, 5475, 74795, 6780, 65067, 0, 1327, 1160, 42084, 93963, + 41217, 119660, 10018, 360, 129070, 983865, 68176, 5863, 3137, 0, 4147, + 983170, 41216, 7844, 2616, 70197, 68461, 65234, 68341, 13076, 3135, + 983289, 78143, 119139, 3142, 92451, 94068, 10819, 119580, 10183, 74635, + 2608, 1470, 73967, 94008, 6227, 121257, 83268, 65236, 917878, 6163, + 983558, 113728, 127314, 128138, 983236, 8603, 127959, 119866, 3306, + 10876, 43392, 83187, 127931, 5751, 127517, 6222, 0, 127466, 12086, 7403, + 1600, 64309, 64939, 0, 64783, 92658, 11310, 0, 8882, 119903, 0, 2570, + 7021, 74902, 194742, 43110, 0, 1234, 6540, 6974, 92750, 0, 983211, 5002, + 983563, 41286, 69946, 74465, 71074, 43585, 113720, 6551, 983375, 128229, + 983274, 41289, 125130, 71080, 127958, 8977, 602, 120814, 0, 128350, + 128661, 194890, 983377, 41279, 0, 0, 94108, 11081, 43615, 0, 0, 127888, + 983612, 12727, 43895, 0, 78397, 9475, 7112, 65105, 0, 9633, 10886, 43592, + 7831, 983829, 194571, 0, 73915, 8076, 43048, 8290, 8291, 43051, 92570, 0, + 2596, 43584, 120983, 13113, 0, 127757, 2393, 7058, 9087, 74067, 68673, + 41574, 78337, 70498, 42900, 6376, 0, 0, 0, 0, 9854, 127748, 64696, 73879, + 128220, 120752, 6994, 0, 1720, 0, 0, 0, 6529, 7063, 983179, 3751, 9120, + 983487, 68038, 1798, 709, 0, 1354, 1876, 13152, 6557, 12430, 8137, 94098, + 67752, 70850, 119057, 245, 121066, 11456, 41233, 7070, 0, 94046, 6136, + 68304, 65677, 8682, 41235, 92595, 42045, 9804, 118963, 432, 3595, 127015, + 65437, 0, 74455, 42399, 983136, 0, 128274, 0, 119658, 128184, 0, 0, + 77894, 8797, 0, 9052, 64888, 7167, 2356, 95, 74784, 10580, 0, 42286, + 71123, 64640, 69999, 94109, 120877, 74137, 70035, 10063, 12652, 12199, + 74622, 43492, 2566, 11971, 983737, 120882, 1065, 0, 127005, 43400, 2576, + 66696, 66819, 83333, 43604, 127891, 0, 3201, 514, 74502, 70032, 2921, + 43215, 64493, 5772, 12968, 70055, 194944, 70310, 43398, 2580, 195025, + 41341, 41223, 6564, 1463, 41342, 0, 5293, 70020, 127870, 3733, 11346, 0, + 12054, 0, 74098, 42827, 195074, 13091, 0, 128580, 0, 917915, 127961, + 127025, 128334, 74821, 71104, 66295, 68037, 0, 121116, 13090, 66643, 0, + 1270, 1132, 42360, 0, 74096, 66655, 42569, 127824, 66898, 64761, 0, + 41021, 8510, 42432, 119898, 119317, 194782, 194641, 64496, 74109, 70030, + 9915, 983083, 983218, 7061, 41336, 3854, 69700, 13141, 68413, 43401, + 42319, 13082, 78114, 7067, 68221, 127881, 127383, 127171, 0, 120745, + 74209, 9029, 43543, 70836, 2353, 6308, 129154, 74792, 2611, 119186, + 66881, 127241, 65063, 43664, 92319, 66627, 92912, 4484, 8509, 118976, + 11066, 65233, 127146, 41224, 41017, 128149, 3747, 10522, 0, 194876, 1691, + 41226, 74962, 12107, 7100, 10905, 65010, 121299, 697, 66018, 9284, 4244, + 983343, 93058, 74781, 13121, 120036, 0, 12010, 128573, 128221, 120949, + 121032, 0, 127193, 65816, 68111, 118950, 127933, 65668, 92257, 6618, + 3562, 66365, 0, 42234, 12648, 78110, 7123, 70038, 5785, 9198, 9764, + 41316, 65877, 7383, 13230, 41299, 0, 0, 68365, 128258, 195027, 0, 0, + 13122, 0, 191, 70060, 8585, 8000, 64411, 120652, 42889, 64850, 41072, + 41578, 983104, 41577, 0, 10002, 121364, 6533, 73802, 41570, 917919, 683, + 396, 41580, 68146, 983067, 12901, 43058, 0, 343, 7129, 42680, 41360, + 78154, 983397, 4743, 69987, 0, 74040, 74108, 8743, 1724, 1433, 119322, + 128665, 3739, 6263, 71349, 128811, 3964, 6592, 121424, 68288, 66040, + 82946, 42568, 69806, 128113, 1778, 3956, 128443, 42070, 6563, 43075, + 9018, 94006, 983398, 12067, 41312, 92763, 5547, 8916, 120869, 128950, + 8175, 94034, 284, 8108, 934, 128039, 74001, 173, 66460, 7174, 92703, + 118822, 1750, 128686, 4394, 68368, 1807, 983888, 92298, 0, 5889, 128795, + 7180, 0, 67127, 0, 67126, 42471, 6982, 1721, 44022, 7891, 42243, 42160, + 2583, 4512, 119360, 65230, 128109, 0, 917630, 3855, 194810, 11767, + 127998, 0, 74295, 194651, 0, 92416, 3975, 67125, 74087, 74989, 12672, + 3798, 2703, 194608, 0, 2109, 9774, 1275, 0, 983750, 41095, 3962, 68242, + 2932, 41101, 3954, 6457, 4513, 74536, 127189, 73994, 73992, 1468, 120033, + 983057, 41803, 127999, 41846, 127244, 55238, 7633, 41849, 68385, 4320, + 3224, 113734, 92741, 66281, 42531, 74593, 1510, 128384, 8256, 0, 11393, + 0, 8879, 128075, 92474, 8770, 72416, 120811, 72415, 1910, 8671, 78374, + 4283, 68842, 120824, 68361, 78318, 2654, 7893, 195006, 128241, 0, 72394, + 65106, 42761, 12857, 4581, 8411, 78372, 78371, 78370, 78369, 78368, + 74475, 983444, 0, 1733, 4392, 2568, 10786, 69661, 0, 8184, 41486, 0, + 7396, 7116, 0, 69788, 0, 7185, 7965, 119144, 128447, 92347, 195066, + 41350, 9129, 983448, 0, 2294, 64501, 68034, 83326, 10481, 0, 70022, 7171, + 0, 340, 71105, 93972, 67360, 0, 92200, 128249, 124979, 6764, 127487, + 128393, 0, 92509, 128962, 65203, 11392, 119098, 119359, 119073, 3210, 0, + 0, 118795, 82958, 94101, 127484, 917619, 119149, 0, 10043, 121215, 1186, + 41571, 6999, 617, 9464, 125123, 3675, 5207, 65062, 5213, 74616, 2617, + 41348, 41568, 128803, 3253, 120535, 0, 8630, 121209, 0, 5596, 5545, 7288, + 2586, 64887, 119826, 5217, 71336, 128687, 917614, 121038, 64293, 68098, + 2635, 92760, 83137, 983846, 0, 92742, 7835, 70040, 120707, 194988, 92285, + 64558, 127122, 121425, 67083, 67085, 70099, 71118, 5784, 983102, 195050, + 983812, 70033, 4011, 194565, 68101, 124978, 7864, 4254, 65095, 983498, + 5600, 3903, 127083, 10447, 5598, 1207, 120521, 66689, 3501, 42582, 43600, + 129054, 127103, 1124, 5597, 194778, 194772, 9321, 983486, 75040, 983484, + 67400, 1719, 68356, 68354, 9671, 1125, 4399, 68775, 66274, 983490, 7631, + 5488, 7128, 120532, 0, 5491, 118797, 8937, 43044, 2604, 74187, 5490, + 43046, 5489, 7212, 11768, 43043, 6300, 127121, 7122, 983090, 4390, 454, + 41397, 0, 9875, 7593, 194791, 92274, 118913, 7207, 0, 65901, 2394, 2575, + 119184, 3746, 11016, 65752, 92757, 0, 43423, 128683, 11989, 118889, + 127791, 127995, 78296, 0, 8249, 128172, 11109, 78531, 6640, 74806, 2598, + 513, 127118, 6586, 8656, 129301, 69792, 65008, 194597, 71111, 78383, + 194795, 127474, 92515, 68475, 93973, 194584, 63799, 78637, 12647, 917606, + 128043, 69893, 1036, 68090, 92419, 1723, 68215, 74217, 0, 41579, 2444, + 120722, 10705, 73876, 195054, 74486, 983469, 740, 119222, 194978, 194984, + 0, 4238, 11071, 9459, 43936, 43938, 78139, 194985, 8121, 10438, 74487, + 42574, 13285, 43967, 11907, 43928, 5690, 92255, 5116, 0, 43181, 13095, + 77925, 43926, 64498, 0, 9506, 6978, 70176, 74931, 0, 113743, 78379, + 43934, 127845, 1122, 317, 0, 71055, 120621, 0, 1920, 0, 10173, 827, 0, 0, + 78378, 119600, 5223, 1304, 0, 83526, 5226, 12602, 94044, 5880, 9329, + 7758, 9239, 41173, 5224, 5487, 1222, 5692, 41725, 69229, 9674, 5695, + 41711, 64627, 19909, 71077, 74604, 5691, 287, 866, 233, 68138, 983443, + 42816, 94036, 65140, 68028, 83093, 8830, 6568, 42300, 10524, 41175, + 83094, 983447, 68827, 5296, 983446, 42492, 43402, 92466, 3302, 0, 74858, + 6516, 6515, 6514, 6513, 6512, 0, 7856, 8690, 983686, 70870, 12122, + 119602, 43976, 194937, 1785, 69925, 68622, 65153, 68809, 5138, 983637, + 71922, 118869, 0, 4540, 41181, 917920, 6200, 0, 5134, 69980, 322, 4643, + 5132, 121184, 6389, 120998, 5143, 83205, 8790, 120911, 120121, 128695, + 71168, 8869, 69916, 93069, 42060, 71326, 9648, 83109, 71170, 10270, + 10286, 10318, 10382, 43529, 66477, 194800, 128534, 74170, 0, 3234, 43835, + 917818, 70111, 43139, 118815, 127084, 120627, 8767, 68231, 74489, 9695, + 72439, 5201, 75061, 6215, 12714, 6214, 13101, 0, 194999, 65268, 7661, 0, + 120909, 11027, 128596, 10059, 10511, 42075, 9767, 789, 1749, 78890, + 67115, 983670, 320, 0, 8647, 83054, 3049, 0, 6471, 42071, 43156, 9925, + 127356, 118894, 66478, 4960, 5549, 127359, 127346, 8485, 4671, 5418, + 127350, 3351, 120892, 127351, 10610, 5414, 3064, 6212, 4286, 5421, + 127344, 9554, 68051, 94048, 66896, 6653, 83044, 83102, 64510, 6213, + 12885, 0, 119045, 64720, 917873, 120759, 73741, 12603, 7131, 11108, 4566, + 7518, 9317, 3801, 10342, 10406, 124938, 119259, 42576, 0, 5200, 92946, + 121435, 983895, 9183, 127361, 74458, 66282, 395, 5482, 5198, 4349, 10390, + 74202, 5196, 43224, 6113, 42009, 5205, 128383, 43307, 70297, 118973, + 70467, 12134, 121167, 0, 118843, 9126, 435, 983624, 12014, 10377, 8093, + 9079, 3203, 192, 65109, 3385, 125075, 64430, 5383, 10294, 10326, 127309, + 5738, 120089, 3336, 78355, 5361, 3623, 41159, 83378, 68112, 7872, 8581, + 0, 1260, 3149, 5359, 120134, 74955, 7914, 5357, 71190, 74339, 2624, 5364, + 983608, 11431, 120030, 9101, 11058, 78288, 67107, 78293, 42271, 78289, + 42917, 67111, 129179, 65566, 6717, 10619, 43360, 78291, 78384, 11832, + 78382, 78381, 78380, 69861, 9319, 7097, 119055, 77906, 3232, 73824, + 74581, 78087, 0, 71205, 41889, 92453, 129144, 1161, 41895, 74103, 9701, + 8622, 125025, 0, 68772, 120588, 5012, 71453, 41362, 69862, 68507, 11921, + 0, 11769, 68782, 68609, 41364, 120947, 74228, 41352, 41361, 917903, + 41366, 0, 3356, 11611, 917, 68422, 119915, 7134, 8199, 78389, 119618, + 677, 119916, 917876, 71482, 127169, 68747, 0, 68738, 3349, 74125, 7022, + 8927, 4739, 92599, 5802, 194874, 8615, 0, 128058, 491, 74401, 10190, + 68755, 65837, 68800, 8426, 11092, 9891, 0, 42497, 7113, 7586, 42305, + 10852, 0, 42648, 4606, 68448, 9095, 7741, 12684, 41885, 1046, 7124, + 128610, 68753, 5815, 5171, 65539, 68612, 6932, 74267, 42394, 41878, + 74849, 74947, 72424, 5169, 11935, 0, 0, 3175, 120822, 1537, 120804, 5176, + 8905, 4136, 4871, 78287, 120663, 9833, 0, 113730, 1128, 65920, 917879, + 9711, 7057, 9408, 9409, 9410, 9411, 3662, 9413, 3378, 9415, 9416, 9417, + 9418, 6320, 9420, 9421, 5897, 9423, 5165, 5126, 41385, 983938, 41389, + 127963, 8955, 3374, 9400, 9401, 7119, 9403, 9404, 3507, 9406, 7629, + 983617, 19925, 42669, 68463, 183, 43985, 2631, 70811, 10627, 41130, + 71079, 3996, 0, 71442, 128913, 119313, 119307, 78768, 6580, 4332, 64825, + 66329, 10726, 66686, 41125, 5899, 41365, 127206, 12085, 66902, 574, + 126705, 77825, 73828, 5448, 41058, 5446, 65932, 41322, 42211, 5442, 4190, + 77834, 77835, 5451, 77833, 3616, 77828, 68817, 77838, 7708, 74759, 2228, + 65867, 10345, 10409, 4191, 120378, 77844, 73800, 42181, 77843, 77839, + 2060, 121193, 7111, 11788, 65376, 68129, 10415, 74102, 983625, 205, + 83040, 10351, 67151, 0, 9862, 6588, 43257, 64697, 73998, 41355, 5505, + 74966, 5503, 8021, 128035, 7125, 9819, 41357, 8011, 42885, 5507, 12044, + 92636, 0, 10026, 5472, 7109, 1191, 13106, 5470, 10329, 5476, 8991, 66322, + 69778, 11133, 42874, 8550, 42876, 5592, 2919, 129052, 2675, 5595, 78411, + 43762, 4367, 127912, 917782, 5478, 5904, 5594, 0, 74150, 7291, 5590, + 43761, 13067, 118909, 75069, 983108, 9731, 69731, 64633, 77857, 77854, + 71217, 77852, 71227, 77850, 10750, 43714, 77858, 7137, 0, 66909, 12887, + 10551, 194564, 77866, 77867, 77864, 77865, 9929, 5199, 9936, 1120, 42387, + 0, 1444, 9486, 7554, 65839, 55252, 73972, 1442, 129080, 5894, 70069, + 128672, 41171, 92511, 70358, 1323, 13162, 120599, 3334, 128704, 92709, + 77881, 66022, 0, 69770, 1651, 120364, 8861, 0, 0, 1142, 983112, 8271, 0, + 983058, 126645, 12903, 78406, 4002, 43626, 10442, 10676, 3344, 128910, + 194787, 12920, 194560, 70497, 194687, 66642, 1277, 66876, 7871, 67106, + 71487, 78853, 129068, 78854, 120360, 983492, 11784, 0, 78012, 4700, + 43856, 78858, 120359, 11012, 983627, 78856, 78448, 77879, 4973, 8784, + 77877, 74804, 77874, 77869, 77871, 42440, 71225, 43118, 119875, 42364, + 6774, 6773, 917560, 120369, 10346, 10410, 78859, 9243, 2464, 74263, 6108, + 3372, 0, 6247, 43117, 70364, 7121, 74166, 124973, 120355, 92537, 194846, + 119877, 195034, 70357, 119922, 0, 67119, 3354, 195037, 4192, 9289, + 118999, 41191, 3876, 0, 70067, 120660, 43696, 43380, 0, 983091, 983965, + 983758, 11603, 983954, 75074, 6589, 128564, 82975, 120993, 67812, 983700, + 0, 129087, 42572, 128264, 10630, 74827, 1963, 11622, 118882, 11654, + 121287, 7550, 10686, 5903, 67098, 78009, 41329, 9662, 917937, 64698, + 3366, 10399, 917938, 5542, 11013, 127927, 71062, 194677, 71461, 67090, + 6925, 0, 0, 92892, 71856, 11568, 983673, 43367, 64579, 917930, 7852, + 11138, 0, 6754, 6312, 77956, 64672, 65296, 0, 118957, 0, 416, 12296, + 68457, 73834, 68177, 11050, 10984, 92208, 0, 0, 92182, 129146, 983605, + 9532, 66355, 119264, 68073, 113695, 64343, 195032, 92744, 195031, 0, + 194847, 195057, 11445, 68294, 2112, 128741, 128814, 10185, 1021, 128130, + 9507, 10210, 74544, 8023, 1200, 12243, 78001, 5282, 78003, 9624, 11545, + 0, 120276, 3343, 4424, 11047, 1885, 43268, 3896, 78444, 66497, 2947, 392, + 7894, 4391, 68139, 121064, 13059, 74816, 77998, 3381, 7942, 0, 69219, + 92433, 3558, 129190, 3913, 70429, 121376, 78235, 7044, 1265, 0, 6309, + 7045, 7175, 7047, 78239, 11791, 983122, 917587, 8221, 78307, 41864, 0, 0, + 67075, 71219, 167, 983906, 78301, 983653, 74211, 41897, 67072, 0, 917583, + 127140, 67076, 2493, 0, 113778, 121245, 78107, 64354, 0, 8777, 127940, + 406, 8884, 2385, 78210, 92450, 917590, 917573, 43030, 42027, 12114, 0, + 128597, 64936, 194695, 119267, 120629, 10561, 128940, 8365, 120539, + 983774, 65841, 120787, 11601, 0, 74121, 128896, 83176, 7834, 74159, 0, + 917574, 10298, 6624, 4908, 917577, 1639, 120842, 0, 70803, 6327, 6724, + 124953, 66354, 92566, 69910, 4817, 11087, 194759, 92536, 7043, 9600, + 11022, 0, 0, 0, 983599, 0, 73954, 7548, 64794, 42050, 12291, 55289, + 128781, 12343, 657, 67110, 42705, 4461, 1134, 1838, 78438, 2057, 0, 4468, + 92891, 194945, 83056, 4456, 5206, 10720, 0, 42523, 127520, 0, 93044, + 129411, 65550, 260, 4816, 67658, 10687, 0, 4821, 4466, 0, 83182, 4818, + 129058, 41403, 119977, 72422, 128458, 41406, 43273, 74160, 69805, 73939, + 92638, 119984, 119979, 41404, 1165, 119980, 4451, 13087, 0, 11284, + 119987, 70097, 65155, 43014, 5439, 9363, 70070, 3375, 128448, 5900, + 93990, 7889, 2722, 42262, 983481, 0, 67078, 128451, 2282, 121422, 127810, + 11401, 67079, 0, 68459, 125028, 983141, 0, 70150, 65438, 0, 7280, 127887, + 68055, 70146, 4868, 8297, 119966, 70148, 125008, 128744, 43161, 70144, + 92360, 0, 5182, 0, 120542, 0, 0, 4226, 70186, 12135, 5732, 4464, 195083, + 71330, 977, 4458, 43827, 92971, 64770, 74838, 0, 344, 0, 121228, 1395, + 64279, 0, 92240, 121179, 786, 126995, 43174, 64340, 83077, 194767, 73971, + 43026, 7612, 10132, 64413, 65025, 0, 0, 0, 93956, 983917, 68444, 0, + 92437, 124928, 92549, 10204, 92656, 83078, 119271, 128431, 1399, 121463, + 65217, 121465, 8852, 120808, 241, 121469, 4907, 128427, 983639, 7932, + 9727, 128463, 74255, 8748, 0, 128428, 983631, 0, 42780, 55263, 113677, + 983560, 4217, 93034, 8650, 127991, 120673, 128215, 69900, 118872, 43099, + 3965, 119119, 6719, 128007, 13300, 78439, 93971, 43057, 66588, 118991, + 66289, 120902, 73815, 4420, 983120, 6410, 7760, 0, 70468, 128752, 120684, + 121246, 7294, 128218, 43869, 120859, 9066, 121321, 11993, 43188, 2626, + 7762, 983866, 118831, 92899, 92601, 42825, 41854, 5304, 70290, 78516, + 6919, 8619, 119655, 10038, 66454, 9592, 42851, 120537, 1542, 92303, + 128819, 0, 127327, 121199, 74311, 78497, 0, 10181, 124937, 43624, 129060, + 7779, 917551, 10195, 9479, 6029, 128374, 92268, 2224, 0, 65577, 8993, + 66358, 0, 42378, 3368, 606, 127030, 7697, 69237, 69787, 2030, 70106, + 6027, 8370, 4322, 0, 65207, 0, 70386, 127903, 983339, 983338, 2735, + 42831, 77935, 70439, 74866, 8881, 119047, 0, 70433, 73946, 0, 194703, 0, + 68140, 983928, 9576, 70288, 3347, 4160, 5154, 55288, 3794, 66564, 8530, + 127063, 7709, 41112, 119868, 66560, 8381, 4572, 12876, 66561, 128921, + 6758, 66031, 1615, 5855, 809, 127117, 92283, 128316, 128004, 5799, + 128929, 70100, 128607, 7260, 983326, 43031, 64425, 65128, 78819, 64386, + 65257, 74909, 68616, 120607, 9347, 83360, 6532, 0, 917918, 120860, + 127060, 65828, 120006, 283, 68665, 78813, 532, 78663, 78817, 128021, + 120609, 0, 3370, 917881, 11361, 5443, 71431, 8153, 73767, 0, 10741, + 121503, 2298, 0, 125039, 65495, 64706, 983320, 43344, 983318, 7144, 9466, + 78866, 9824, 67142, 128963, 67133, 67130, 915, 43425, 67292, 43865, + 68232, 983111, 120888, 43264, 67136, 67137, 0, 43038, 78864, 6730, 78862, + 68161, 64550, 5186, 7360, 127837, 70451, 12108, 120644, 65124, 43127, + 66043, 0, 6326, 43107, 77826, 0, 42562, 0, 128821, 128178, 120919, 11485, + 6103, 92468, 983307, 11718, 983305, 12889, 92657, 125034, 120635, 127157, + 121128, 55245, 128709, 1630, 83027, 65483, 120634, 12565, 0, 65476, + 70369, 983072, 83029, 9283, 7700, 917537, 9690, 65499, 0, 64593, 512, + 3376, 68080, 0, 128253, 77892, 632, 12940, 77891, 42529, 78587, 194604, + 5957, 110593, 8926, 983301, 983300, 128273, 10745, 10174, 7379, 64581, + 5386, 120686, 11713, 10633, 69708, 5056, 0, 0, 0, 120773, 94055, 9812, 0, + 4460, 78791, 124956, 71307, 128038, 0, 121135, 127174, 64278, 92370, + 43466, 0, 0, 64389, 2953, 70122, 1801, 12835, 74847, 120867, 73823, + 83110, 66375, 2085, 702, 42579, 77884, 77885, 13074, 77883, 66299, + 983287, 71447, 12106, 120972, 74207, 1755, 10482, 12863, 77898, 1163, + 2951, 9522, 67816, 78266, 66604, 983860, 3384, 69227, 10702, 830, 77902, + 77899, 77900, 8451, 83324, 0, 0, 66458, 128957, 128870, 74896, 0, 2908, + 0, 11177, 64902, 4243, 92454, 12239, 121003, 124959, 4441, 0, 82968, + 73940, 64352, 127513, 125031, 411, 983275, 9199, 983273, 4056, 118992, + 41890, 128592, 2730, 41604, 128355, 5428, 194743, 3364, 42265, 64437, + 127935, 118816, 71458, 9684, 216, 71367, 1401, 128053, 44012, 92628, + 71456, 92585, 9158, 66878, 11126, 5768, 0, 983759, 0, 484, 194739, 0, 0, + 65895, 125076, 121380, 3338, 73935, 572, 7041, 2736, 67605, 127543, + 93962, 2794, 8807, 64491, 77847, 5438, 5222, 5381, 43114, 0, 5193, 5125, + 5456, 5509, 77846, 194747, 9534, 129109, 129040, 0, 3430, 0, 42905, + 78717, 74929, 981, 129184, 4330, 73929, 120536, 1824, 10908, 126506, + 7034, 41683, 64617, 0, 73754, 3957, 64358, 64547, 128259, 674, 63991, + 983251, 2946, 5354, 5251, 5328, 5307, 3759, 11411, 8364, 5123, 119628, + 5281, 5469, 5121, 77989, 118993, 0, 5130, 83180, 128357, 77990, 0, + 120726, 1221, 2733, 11746, 77991, 5216, 119268, 0, 128475, 92187, 3468, + 7033, 9230, 5939, 128397, 0, 5803, 71867, 68400, 7278, 10321, 10289, + 64613, 10385, 41706, 0, 0, 917939, 0, 11739, 77986, 41981, 92743, 5938, + 0, 43766, 12448, 7576, 10401, 10337, 73852, 124994, 13057, 0, 126976, + 129081, 10009, 0, 41703, 120950, 12165, 129191, 0, 9885, 0, 8077, 92620, + 127908, 121044, 194995, 0, 92457, 129138, 4220, 10725, 10433, 0, 68395, + 4987, 64519, 121265, 125078, 0, 194813, 128574, 10970, 11733, 0, 120792, + 126490, 19944, 74356, 9009, 8551, 92345, 11468, 64636, 7575, 0, 2724, + 128899, 0, 12313, 11151, 515, 119947, 42791, 63987, 78286, 119943, + 119940, 119941, 119938, 9775, 4046, 4589, 4521, 68629, 9141, 917904, + 78850, 2741, 64399, 6197, 1370, 0, 120841, 0, 125062, 983441, 120843, + 6184, 8606, 3303, 41372, 11786, 9473, 66203, 66177, 92446, 11593, 43007, + 4478, 66178, 0, 0, 2744, 0, 4477, 78267, 814, 42066, 66183, 66204, 43786, + 119961, 66198, 41880, 66188, 11623, 78148, 11955, 66190, 66191, 41111, + 66189, 73788, 7788, 4847, 983428, 127759, 0, 128433, 2221, 1581, 6535, + 78161, 12954, 430, 78160, 55259, 73944, 128036, 5278, 4945, 42883, 4950, + 983440, 68625, 983438, 7269, 128499, 5964, 12908, 124997, 0, 74764, + 43512, 119146, 194936, 4949, 983431, 443, 983429, 4944, 5467, 119603, + 70865, 65137, 6044, 65392, 0, 4213, 0, 41303, 917556, 194931, 119962, + 41306, 73984, 2698, 127159, 0, 12072, 3193, 0, 41304, 824, 128676, 12091, + 67118, 78894, 119816, 4673, 64804, 4678, 119820, 119819, 65059, 43860, + 6739, 66844, 5481, 3490, 1199, 119811, 8356, 69947, 67702, 4677, 12688, + 3102, 0, 4672, 78173, 78175, 5531, 68367, 42575, 78170, 78166, 4674, + 4548, 44005, 71087, 68658, 119946, 8025, 68630, 127024, 1855, 127475, + 68669, 118990, 92445, 127554, 126630, 127339, 119652, 2745, 11797, + 983419, 128159, 9202, 4654, 6840, 983416, 68638, 73993, 10525, 4649, + 65209, 121512, 121511, 4648, 43080, 75070, 121507, 983406, 6246, 64950, + 7828, 4650, 6777, 6776, 6775, 4653, 7822, 70287, 74624, 43187, 8669, + 120659, 6821, 65093, 983565, 78881, 2716, 983412, 983060, 70503, 194952, + 68369, 120054, 11060, 8547, 2711, 42165, 78027, 78026, 6836, 983423, 0, + 4662, 78033, 78032, 9149, 9146, 599, 2081, 78031, 78030, 194962, 4656, + 10130, 68450, 7811, 40994, 194965, 6414, 5967, 4658, 3725, 5713, 5814, + 4661, 42434, 983413, 128737, 11190, 64904, 9026, 10833, 74864, 7547, + 4867, 11100, 10008, 10222, 3054, 194956, 9744, 78860, 7605, 4622, 119656, + 43888, 70303, 983395, 69905, 67188, 9045, 78888, 4225, 19926, 68831, + 12880, 65307, 4617, 68757, 983388, 41732, 4616, 10518, 10423, 10359, + 983382, 5958, 0, 983435, 4215, 9789, 119619, 4321, 4621, 195028, 41313, + 522, 5368, 11139, 65803, 128546, 5366, 12201, 5372, 121060, 119949, + 194975, 7720, 7390, 2696, 983402, 0, 4638, 983407, 1790, 78242, 5965, + 64363, 66569, 68646, 68477, 5376, 1835, 5335, 121505, 128089, 4633, 0, + 68119, 1180, 4632, 67191, 5387, 5333, 0, 125132, 42094, 5331, 4634, + 11928, 983594, 5338, 4637, 128170, 5971, 42414, 43500, 1268, 65097, + 42361, 0, 0, 73853, 1427, 128440, 0, 5970, 3431, 0, 10358, 10422, 4758, + 983376, 1608, 2738, 125066, 10455, 4753, 74026, 11344, 4222, 6240, 5231, + 74384, 66611, 68377, 6248, 983364, 67815, 78878, 42318, 92582, 5229, + 4757, 0, 126576, 2728, 4752, 64563, 65235, 5234, 0, 128145, 128926, + 10713, 7166, 0, 2622, 7460, 83124, 67101, 126495, 8954, 74760, 65189, + 2632, 42617, 10108, 1011, 5574, 1853, 2709, 65139, 5577, 128966, 0, + 118871, 68641, 8965, 7635, 42177, 5316, 0, 5314, 6451, 5572, 66464, 5312, + 0, 5525, 5330, 5319, 68292, 127311, 65066, 44003, 68437, 983482, 43843, + 120498, 127851, 43918, 74851, 74022, 983424, 64609, 68643, 67410, 128593, + 5721, 74892, 5519, 8632, 66465, 11267, 73961, 92278, 5720, 78778, 1692, + 4219, 4610, 8696, 4305, 0, 4609, 43478, 4614, 541, 983242, 5287, 5309, + 5285, 68389, 5961, 4647, 56, 4216, 10577, 41381, 601, 4613, 120479, + 983348, 9208, 4608, 43966, 41124, 5190, 67628, 66826, 68145, 7086, 0, + 67998, 67620, 93047, 2734, 11074, 0, 67627, 43593, 0, 67625, 5960, 67722, + 8992, 42593, 128260, 1782, 67622, 68114, 119939, 0, 68180, 5501, 119952, + 42508, 7442, 43665, 359, 41253, 68392, 6239, 43900, 41256, 74132, 67740, + 0, 71178, 917550, 9346, 69660, 41254, 128047, 43291, 3767, 5737, 0, 4865, + 0, 5740, 917997, 5736, 4368, 64724, 7193, 67097, 128844, 5739, 41024, + 4866, 983880, 73904, 121420, 4869, 120563, 129172, 4223, 128201, 6650, + 126509, 0, 120212, 119872, 4870, 120445, 68661, 6716, 78176, 68667, + 68382, 68676, 127925, 10122, 4864, 66568, 4144, 7937, 83193, 6245, 68652, + 2732, 42734, 745, 68045, 195097, 92195, 4777, 7821, 129136, 68631, 42775, + 194661, 128445, 120679, 3097, 120908, 5966, 121197, 4778, 126469, 10863, + 127506, 4781, 92986, 64407, 128503, 128323, 8577, 71221, 68196, 43285, + 10216, 4782, 983485, 983411, 120757, 68618, 12325, 43056, 8717, 0, 0, + 4776, 73818, 11492, 8700, 129128, 13176, 68363, 10426, 67247, 71091, + 10362, 194706, 1715, 4849, 8242, 9561, 73922, 43278, 42635, 0, 127207, + 5963, 917926, 983483, 0, 4850, 73900, 1607, 466, 4853, 118995, 4854, + 127918, 5164, 73807, 1350, 5124, 64420, 1993, 5362, 8471, 2708, 92471, + 12445, 3785, 234, 3199, 121273, 41268, 4848, 2530, 74941, 2068, 1964, 0, + 73762, 10458, 983417, 8576, 78543, 0, 2704, 4794, 121102, 68211, 8322, + 4797, 5753, 0, 2694, 4792, 0, 2439, 65104, 69804, 983426, 303, 74625, + 68229, 983427, 2437, 78659, 4221, 4844, 92216, 0, 0, 0, 70042, 74095, + 43292, 0, 2441, 10739, 65090, 194622, 70436, 118929, 2451, 2714, 119326, + 0, 43379, 4937, 43376, 753, 5849, 10597, 43089, 11722, 9248, 92555, + 42879, 11725, 917969, 0, 2726, 3107, 73958, 4941, 64937, 119233, 9140, + 1408, 5261, 4607, 194715, 181, 983432, 4942, 9539, 4938, 0, 65201, 5259, + 9369, 64185, 4142, 5257, 983601, 6844, 4964, 5264, 64178, 64177, 12979, + 41411, 64182, 64181, 64180, 64179, 9482, 4873, 41231, 1822, 42526, + 127989, 12758, 3865, 194660, 121129, 10500, 0, 119024, 78028, 92408, + 9830, 43642, 389, 10893, 7521, 127879, 4872, 5463, 128119, 3125, 9567, 0, + 4878, 5459, 4604, 119650, 9557, 5465, 68617, 0, 11494, 126492, 9563, + 10865, 74570, 43279, 64186, 68521, 78714, 64191, 64190, 8898, 64188, + 129153, 41030, 74226, 78713, 74600, 74994, 917834, 0, 78805, 41031, + 78801, 11960, 6745, 3082, 983269, 78539, 73919, 10573, 41744, 7079, 5856, + 67838, 5163, 78809, 128162, 1817, 66724, 78538, 119010, 10564, 7763, + 13077, 41813, 4400, 41745, 64207, 10275, 8925, 10371, 10307, 41814, 4248, + 77979, 0, 4541, 6299, 64204, 64203, 64201, 64200, 64199, 64198, 126471, 42156, 78688, 0, 64193, 64192, 65223, 9943, 64197, 64196, 64195, 64194, - 13282, 64175, 64174, 64173, 78189, 846, 78186, 9965, 0, 0, 0, 0, 2543, - 12163, 3108, 9745, 64167, 64166, 64165, 64164, 2110, 92176, 64169, 64168, - 64949, 10972, 10251, 10247, 42768, 715, 2295, 43299, 9453, 5348, 10943, - 120378, 0, 11352, 550, 9910, 126705, 0, 66579, 11551, 0, 195080, 9504, - 7187, 0, 10373, 0, 120791, 10261, 10253, 6404, 10277, 78183, 11984, 1552, - 65222, 6998, 78180, 0, 3128, 4789, 5067, 5066, 118849, 4784, 0, 8827, - 1146, 5065, 69890, 78192, 68136, 78190, 43412, 5064, 2431, 0, 9450, 1809, - 0, 78200, 78201, 5062, 1264, 64817, 13254, 11697, 126598, 9785, 64716, 0, - 3933, 74559, 4740, 7954, 0, 0, 42609, 0, 74175, 0, 127016, 0, 983873, - 42130, 0, 5151, 917829, 917823, 0, 93980, 0, 7620, 3800, 65122, 0, 0, - 8355, 7854, 0, 954, 64927, 4185, 41045, 127141, 41438, 41439, 68666, - 10711, 4593, 127745, 120584, 983408, 64774, 8053, 10532, 66727, 0, 0, 0, - 64759, 6381, 5166, 9888, 127800, 5148, 42834, 0, 78205, 78206, 43787, - 78204, 64131, 3119, 917814, 0, 3060, 64135, 9986, 0, 77876, 636, 11698, - 0, 983451, 9916, 11701, 7836, 42741, 64137, 8320, 78640, 8863, 92431, - 119960, 1477, 43289, 0, 74358, 8618, 983402, 9908, 983981, 0, 0, 3937, - 12312, 0, 983403, 0, 64781, 912, 6349, 4536, 93954, 74532, 126594, 6244, - 92209, 71341, 3935, 120665, 983476, 0, 11950, 5392, 42248, 65129, 68656, - 5397, 0, 12046, 12599, 0, 128261, 5395, 0, 5393, 354, 68615, 119948, - 78503, 0, 0, 42039, 0, 0, 64142, 626, 0, 5895, 0, 0, 5780, 0, 0, 128874, - 0, 0, 43297, 983079, 4311, 4644, 8818, 0, 128186, 0, 7145, 3918, 66452, - 3797, 1644, 92346, 9658, 4140, 11385, 65947, 6455, 9030, 813, 119945, - 68131, 4146, 119957, 5360, 2466, 0, 67669, 119942, 6249, 42117, 92287, - 128224, 0, 0, 74046, 43745, 4911, 988, 917807, 0, 983468, 43061, 7054, - 64147, 0, 64920, 68195, 6698, 118933, 92506, 0, 120006, 11981, 12202, 0, - 11032, 67654, 6093, 11608, 975, 68662, 65843, 170, 0, 0, 4169, 0, 41859, - 6058, 120401, 13203, 120657, 0, 0, 68657, 9818, 10178, 10324, 42106, - 5898, 74540, 4738, 41856, 7062, 917865, 4737, 11779, 4742, 120564, 92391, - 73736, 983364, 9825, 6448, 6715, 127008, 4831, 0, 92525, 0, 5300, 4741, - 42108, 983354, 64159, 4736, 64148, 0, 849, 92191, 78491, 43288, 0, 66620, - 917916, 127331, 65549, 9496, 64598, 118866, 983366, 7876, 68132, 917872, - 3928, 917870, 43378, 10706, 7198, 0, 4842, 12053, 128129, 0, 4841, 0, - 4171, 12008, 6251, 3923, 1490, 0, 119591, 126512, 40972, 5245, 0, 10114, - 42001, 41888, 4845, 8332, 40974, 64347, 4840, 9077, 78346, 1747, 917849, - 4825, 69240, 917852, 68655, 0, 983388, 0, 0, 68628, 983347, 9850, 118937, - 367, 1472, 917859, 6687, 1274, 0, 5905, 12339, 8919, 73953, 10907, 65261, - 11023, 119559, 4830, 9134, 78666, 64126, 43011, 0, 126626, 64101, 0, 0, - 4824, 10614, 119659, 0, 1888, 1960, 7861, 917856, 78524, 41836, 43012, - 6052, 6064, 54, 43009, 12214, 0, 6211, 0, 358, 41997, 41833, 11442, - 10758, 65774, 0, 120384, 64115, 92221, 70018, 0, 0, 119053, 0, 12765, - 64118, 126998, 12962, 0, 126580, 4017, 12827, 5241, 120392, 0, 41118, - 3924, 0, 11366, 917843, 0, 0, 917846, 41116, 917844, 917564, 0, 11363, - 12057, 11917, 1567, 74000, 4721, 126641, 66202, 8957, 4139, 0, 0, 0, 0, - 0, 12740, 128702, 4722, 6816, 127793, 12759, 4725, 983383, 4726, 0, - 194892, 983622, 128321, 917905, 0, 12755, 12762, 4015, 0, 8052, 476, 0, - 0, 128294, 64212, 41020, 1382, 64209, 64216, 44002, 64214, 1656, 41831, - 0, 0, 41843, 8720, 3908, 1452, 13111, 0, 64067, 127328, 8552, 64113, - 41845, 3849, 78732, 66232, 9778, 120066, 5891, 7064, 55, 9948, 119085, 0, - 0, 7935, 2420, 0, 1114, 92599, 67585, 70104, 120053, 92350, 120051, 3938, - 120057, 65417, 64717, 120060, 120061, 65415, 120059, 6292, 65303, 7955, - 6452, 4713, 128196, 66249, 917885, 917890, 917891, 65152, 719, 120044, - 78623, 120042, 6713, 4532, 65412, 69822, 10868, 4717, 2349, 5902, 66450, - 4712, 917902, 917899, 917900, 65416, 8155, 4718, 3942, 4714, 9625, 0, - 6383, 194744, 12006, 128565, 0, 0, 0, 0, 65414, 6454, 1229, 126606, - 66437, 66025, 78699, 0, 42500, 120508, 4809, 9623, 917874, 78694, 917880, - 917877, 917878, 65405, 68159, 12893, 917882, 5365, 4545, 8901, 92421, - 119555, 4813, 128262, 0, 5925, 4808, 64330, 0, 65475, 118940, 195028, - 4814, 0, 4810, 0, 0, 64928, 10543, 0, 3522, 71335, 414, 65404, 0, 195027, - 6456, 73820, 0, 6691, 42193, 92225, 128171, 0, 74495, 0, 0, 0, 118820, - 9751, 65407, 128085, 11770, 3919, 0, 0, 65061, 0, 0, 0, 12235, 0, 0, - 127233, 64092, 983470, 64080, 0, 64090, 0, 69913, 10162, 10310, 0, 8454, - 127888, 42038, 387, 41363, 12737, 0, 4780, 43368, 0, 64310, 64621, 6732, - 78116, 0, 983139, 0, 983074, 8896, 0, 375, 6976, 66582, 119005, 983874, - 0, 983434, 119202, 119203, 12526, 43120, 2315, 0, 1938, 119197, 0, 4529, - 119200, 119201, 119198, 119199, 69692, 983432, 69698, 13150, 64492, 0, 0, - 2291, 12902, 0, 42891, 66327, 74298, 917857, 10799, 69690, 2587, 66372, - 0, 4193, 92250, 4241, 983057, 7998, 0, 0, 0, 126640, 2316, 118821, 0, 0, - 0, 64297, 74799, 92442, 74140, 0, 5373, 0, 983886, 3762, 10015, 120672, - 119232, 0, 41590, 0, 70098, 3780, 7485, 5779, 0, 42037, 0, 3906, 12349, - 0, 8326, 0, 65498, 3763, 6983, 5618, 0, 3779, 0, 43613, 0, 0, 0, 0, 0, 0, - 280, 74558, 127332, 68138, 13072, 1894, 0, 0, 65478, 43310, 7231, 0, - 11773, 0, 0, 0, 0, 2551, 0, 6453, 10200, 6235, 983752, 119237, 0, 128805, - 4470, 11826, 917557, 7780, 5369, 118958, 5249, 0, 5367, 8756, 127143, 0, - 5377, 120585, 68143, 1688, 78245, 983356, 69685, 983756, 0, 0, 44020, - 6808, 41319, 1300, 10650, 41692, 64505, 2290, 0, 119624, 1465, 10850, - 3943, 0, 41205, 41315, 118961, 0, 0, 5352, 0, 0, 8839, 41314, 7384, 7785, - 41204, 127322, 41209, 69637, 92241, 43607, 0, 0, 5420, 3897, 10134, 0, - 74417, 4018, 7150, 68127, 0, 0, 0, 0, 127526, 2561, 68621, 3542, 7148, - 12076, 7951, 68152, 118857, 5303, 6276, 1706, 0, 78751, 7146, 0, 65150, - 41819, 0, 73951, 10847, 41822, 9985, 860, 0, 10506, 983435, 69641, 10753, - 10830, 0, 615, 64490, 7574, 92617, 77922, 0, 12909, 43016, 64559, 127028, - 0, 0, 67996, 2020, 0, 4022, 128783, 0, 77923, 126593, 41691, 0, 0, 74329, - 0, 64622, 9070, 0, 68411, 3911, 42829, 43122, 1033, 74440, 0, 7000, 3904, - 0, 128198, 0, 118931, 119630, 13123, 10846, 3450, 127360, 7397, 118807, - 0, 42778, 10000, 41088, 449, 0, 3777, 68458, 0, 9636, 0, 10738, 69634, - 9367, 593, 41085, 3999, 65226, 41713, 12764, 0, 64409, 3596, 0, 0, 9763, - 120280, 92192, 12347, 124, 12981, 41127, 2092, 92687, 0, 0, 0, 10820, - 43987, 0, 0, 1769, 41715, 2463, 78489, 0, 12770, 126500, 1538, 0, 43124, - 0, 195058, 7795, 120300, 0, 4828, 1258, 127802, 2006, 0, 0, 9498, 127032, + 12231, 42652, 64174, 64173, 78189, 846, 78186, 9965, 74495, 83492, 83493, + 83494, 2543, 12163, 3108, 9745, 64167, 64166, 64165, 64164, 2110, 92176, + 64169, 64168, 64949, 10972, 10251, 10247, 42768, 715, 2295, 43299, 9453, + 5348, 10943, 66390, 0, 11352, 550, 9910, 125127, 0, 66579, 11551, 128464, + 195080, 9504, 7187, 82957, 10373, 983418, 120375, 10261, 10253, 6404, + 10277, 78183, 11984, 1552, 65222, 6998, 78180, 71429, 3128, 4789, 5067, + 5066, 118849, 4784, 0, 8827, 1146, 5065, 69890, 78192, 68136, 78190, + 43412, 5064, 2431, 0, 9450, 1809, 0, 78200, 78201, 5062, 1264, 64817, + 13254, 11697, 126598, 9785, 64716, 0, 3933, 74559, 4740, 7954, 0, 125023, + 42609, 119855, 74175, 66912, 127016, 0, 121300, 42130, 121046, 5151, + 121346, 83488, 0, 93980, 917802, 7620, 3800, 65122, 83487, 83480, 8355, + 7854, 83483, 954, 64927, 4185, 41045, 127141, 41438, 41439, 68666, 10711, + 4593, 82993, 120584, 983410, 64774, 8053, 10532, 66727, 983414, 0, 78642, + 64759, 1325, 5166, 9888, 127800, 5148, 42834, 0, 78205, 78206, 43787, + 78204, 43913, 3119, 917814, 0, 3060, 64135, 9986, 74996, 77876, 636, + 11698, 83476, 82961, 9916, 11701, 7836, 42741, 64137, 8320, 78640, 8863, + 70201, 119960, 1477, 43289, 68492, 67164, 8618, 983404, 9908, 74972, 0, + 0, 3937, 12312, 0, 983405, 0, 64781, 912, 6349, 4536, 93954, 74532, + 126594, 6244, 92209, 71341, 3935, 120665, 128969, 0, 11950, 5392, 42248, + 65129, 68656, 5397, 128310, 12046, 12599, 67407, 128261, 5395, 0, 5393, + 354, 68615, 77853, 74366, 121404, 0, 42039, 113817, 0, 64142, 626, 0, + 5895, 0, 43910, 5780, 0, 10220, 121337, 43907, 71121, 43297, 70188, 4311, + 4644, 8818, 78158, 128186, 128869, 7145, 3918, 66452, 3797, 1644, 92346, + 9658, 4140, 11385, 65947, 6455, 9030, 813, 119945, 68131, 4146, 119957, + 5360, 2466, 0, 67669, 94020, 6249, 42117, 68828, 92206, 128023, 119255, + 74046, 43745, 4911, 988, 71180, 0, 983470, 43061, 7054, 64147, 983847, + 64920, 68195, 6698, 118933, 92506, 0, 70849, 11981, 12202, 195087, 11032, + 67654, 6093, 11608, 975, 66415, 65843, 170, 0, 67239, 4169, 0, 41859, + 6058, 120401, 13203, 120657, 70507, 125091, 68657, 9818, 10178, 10324, + 42106, 5898, 74540, 4738, 41856, 7062, 127120, 4737, 11779, 4742, 83425, + 68758, 68342, 83420, 9825, 6448, 6715, 127008, 4831, 83418, 83419, 67731, + 5300, 4741, 42108, 127057, 64159, 4736, 64148, 92634, 849, 92191, 78491, + 43288, 0, 66620, 127533, 127331, 65549, 9496, 64598, 118866, 983368, + 7876, 68132, 66280, 3928, 917870, 43378, 10706, 7198, 120890, 4842, + 12053, 128129, 68746, 4841, 0, 4171, 12008, 6251, 3923, 1490, 83411, + 83412, 126512, 40972, 5245, 70794, 10114, 42001, 41888, 4845, 8332, + 40974, 64347, 4840, 9077, 78346, 1747, 917849, 4825, 69240, 121443, + 68655, 0, 983390, 0, 0, 68628, 983349, 9850, 118937, 367, 1472, 917859, + 6687, 1274, 195022, 5905, 12339, 8919, 73953, 10907, 65261, 11023, + 119559, 4830, 9134, 78666, 64126, 43011, 83297, 78669, 64101, 0, 128434, + 4824, 10614, 119659, 126993, 1888, 1960, 7861, 83416, 78524, 41836, + 43012, 6052, 6064, 54, 43009, 12214, 83260, 6211, 120386, 358, 41997, + 41833, 11442, 10758, 65774, 113823, 120384, 64115, 92221, 70018, 983611, + 983708, 119053, 0, 12765, 64118, 126998, 12962, 0, 126580, 4017, 12827, + 5241, 120392, 0, 41118, 3924, 983894, 11366, 129084, 0, 0, 83401, 41116, + 83403, 83404, 83397, 11363, 12057, 11917, 1567, 74000, 4721, 83396, + 66202, 8957, 4139, 70512, 0, 983074, 0, 0, 12740, 121470, 4722, 6816, + 124974, 12759, 4725, 67099, 4726, 83467, 83468, 983622, 70029, 83463, + 74913, 12755, 12762, 4015, 67690, 8052, 476, 0, 74893, 128294, 64212, + 41020, 1382, 64209, 64216, 44002, 64214, 1656, 41831, 127553, 125121, + 41843, 8720, 3908, 1452, 13111, 983421, 64067, 92287, 8552, 64113, 41845, + 3849, 78732, 66232, 9778, 120066, 5891, 7064, 55, 9948, 119085, 83302, + 917610, 7935, 2420, 0, 1114, 78120, 67585, 70104, 70432, 83447, 74920, + 3938, 120057, 65417, 64717, 120060, 71920, 65415, 66884, 6292, 65303, + 7955, 6452, 4713, 128196, 66249, 917885, 194766, 129073, 65152, 719, + 120044, 78623, 120042, 6713, 4532, 65412, 69822, 10868, 4717, 2349, 5902, + 66450, 4712, 75055, 917899, 65400, 65416, 8155, 4718, 3942, 4714, 9625, + 0, 6383, 194744, 12006, 128565, 194789, 0, 113756, 0, 65414, 6454, 1229, + 83457, 66437, 66025, 78699, 83452, 42500, 120508, 4809, 9623, 129137, + 78694, 121173, 128777, 917858, 65405, 68159, 12893, 78617, 5365, 4545, + 8901, 92421, 119555, 4813, 128262, 194729, 5925, 4808, 64330, 128400, + 65475, 83432, 68244, 4814, 83427, 4810, 83429, 83430, 64928, 10543, + 71249, 3522, 71335, 414, 65404, 0, 83442, 6456, 73820, 83445, 6691, + 42193, 66284, 83441, 0, 68337, 0, 43858, 43832, 118820, 9751, 65407, + 128085, 11770, 3919, 120724, 0, 65061, 983945, 917894, 129142, 12235, + 128572, 92701, 121087, 64092, 68739, 64080, 129063, 64090, 983586, 69913, + 10162, 10310, 121210, 8454, 121387, 42038, 387, 41363, 12737, 0, 4780, + 43368, 0, 64310, 64621, 6732, 78116, 0, 121295, 195024, 92193, 8896, 0, + 375, 6976, 66582, 119005, 74997, 127325, 983436, 119202, 119203, 12526, + 43120, 2315, 0, 1938, 119197, 128452, 4529, 119200, 119201, 119198, + 119199, 69692, 129124, 69698, 13150, 64492, 128974, 78761, 2291, 12902, + 0, 42891, 66327, 70502, 917857, 10799, 69690, 2587, 66372, 128628, 4193, + 66823, 4241, 129195, 7998, 83276, 0, 127009, 126640, 2316, 118821, 0, + 983934, 0, 64297, 74799, 92442, 74140, 128148, 5373, 128798, 70370, 3762, + 10015, 120672, 119232, 125109, 41590, 0, 70098, 3780, 7485, 5779, 917898, + 42037, 0, 3906, 12349, 74793, 8326, 127333, 65498, 3763, 6983, 5618, 0, + 3779, 983194, 43613, 70132, 0, 83288, 78335, 83289, 0, 280, 74558, + 121353, 67396, 13072, 1894, 83291, 67735, 65478, 43310, 7231, 0, 11773, + 0, 119165, 11144, 917778, 2551, 0, 6453, 10200, 6235, 983752, 119237, + 71877, 128669, 4470, 11826, 917557, 7780, 5369, 118958, 5249, 983066, + 5367, 8756, 127143, 119183, 5377, 120585, 68143, 1688, 78245, 5218, + 69685, 983756, 0, 113794, 44020, 6808, 41319, 1300, 10650, 41692, 64505, + 2290, 71057, 119624, 1465, 10850, 3943, 0, 41205, 41315, 118961, 119333, + 67148, 5352, 113753, 0, 8839, 41314, 7384, 7785, 41204, 127322, 41209, + 69637, 92241, 43607, 71254, 0, 5420, 3897, 10134, 120381, 74417, 4018, + 7150, 68127, 71425, 0, 121427, 127864, 127526, 2561, 68621, 3542, 7148, + 12076, 7951, 68152, 118857, 5303, 6276, 1706, 120750, 78751, 7146, + 983682, 65150, 41819, 0, 73951, 10847, 41822, 9985, 860, 0, 10506, + 983437, 69641, 10753, 10830, 119339, 615, 64490, 7574, 74082, 77922, 0, + 12909, 43016, 64559, 127028, 0, 121231, 67996, 2020, 128790, 4022, + 128783, 120701, 77923, 126593, 41691, 0, 75060, 74329, 0, 64622, 9070, 0, + 68411, 3911, 42829, 43122, 1033, 74440, 983813, 7000, 3904, 983628, + 73737, 125105, 118931, 119630, 13123, 10846, 3450, 127360, 7397, 118807, + 917891, 42778, 10000, 41088, 449, 0, 3777, 68458, 113725, 9636, 0, 10738, + 69634, 9367, 593, 41085, 3999, 65226, 41713, 12764, 983723, 64409, 3596, + 129044, 128090, 9763, 120280, 74609, 12347, 124, 12981, 41127, 2092, + 92687, 0, 127555, 194632, 10820, 43987, 0, 128907, 1769, 41715, 2463, + 71214, 83070, 12770, 71222, 1538, 92617, 43124, 194614, 195058, 7795, + 120300, 129053, 4828, 1258, 127802, 2006, 0, 121130, 9498, 127032, 127033, 120289, 120288, 3939, 120290, 8846, 8943, 120287, 120286, 2650, - 4491, 1961, 42602, 11525, 120292, 1959, 120294, 55228, 11774, 41016, 0, - 68675, 128054, 1511, 9324, 78211, 10519, 66331, 3454, 19930, 0, 41019, 0, - 0, 65292, 6822, 12862, 0, 0, 42143, 41828, 78207, 65531, 78208, 118879, - 55223, 0, 128071, 41826, 8865, 6402, 0, 13279, 7917, 74755, 0, 7733, 0, - 4998, 983896, 92332, 41950, 0, 4268, 0, 0, 70061, 4013, 0, 10881, 0, 0, - 0, 74788, 2014, 0, 0, 9765, 0, 0, 0, 195059, 78357, 65281, 127825, 10949, - 0, 0, 0, 2015, 0, 0, 0, 66318, 43233, 0, 42517, 0, 0, 0, 12698, 8094, - 10135, 65909, 6474, 794, 0, 12656, 128122, 119353, 128270, 1665, 0, 4833, - 983053, 119351, 127367, 0, 189, 12611, 0, 0, 2859, 4838, 0, 4834, 65078, - 0, 0, 4837, 127061, 770, 0, 811, 0, 41042, 917551, 41318, 64427, 0, - 128208, 78848, 3895, 0, 74341, 3976, 0, 42859, 10193, 3116, 7747, 0, 0, - 0, 0, 0, 43686, 78846, 41877, 0, 2871, 64614, 128785, 999, 0, 6345, - 41876, 2663, 2017, 0, 0, 11040, 10150, 0, 64308, 1522, 597, 4775, 12555, - 12571, 12550, 12583, 12560, 2019, 12556, 12584, 3092, 0, 12562, 4783, - 12566, 12569, 12554, 0, 10812, 78851, 0, 0, 3078, 1402, 0, 128275, 0, 0, - 119248, 394, 3088, 0, 92172, 0, 3991, 64391, 0, 128524, 424, 66328, 1999, - 69659, 73914, 0, 0, 0, 0, 42231, 8246, 0, 0, 0, 41840, 983609, 2377, + 4491, 1961, 42602, 11525, 120292, 1959, 120294, 55228, 11774, 41016, + 983262, 68675, 128054, 1511, 9324, 78211, 10519, 66331, 3454, 19930, 0, + 41019, 127944, 0, 65292, 6822, 12862, 0, 0, 42143, 41828, 78207, 65531, + 70864, 118879, 55223, 0, 128071, 41826, 8865, 6402, 113827, 13279, 7917, + 74755, 917948, 7733, 983408, 4998, 68493, 92332, 41950, 0, 4268, 194790, + 195056, 70061, 4013, 128718, 10881, 0, 983163, 0, 74788, 2014, 2432, + 71901, 9765, 195052, 0, 917854, 195059, 78357, 65281, 127825, 10949, 0, + 0, 119315, 2015, 121088, 92765, 71840, 66318, 43233, 917992, 42517, + 68060, 0, 0, 12698, 8094, 10135, 65909, 6474, 794, 43497, 12656, 66335, + 119353, 67279, 1665, 71853, 4833, 917985, 71188, 127367, 121464, 189, + 12611, 0, 983420, 2859, 4838, 983930, 4834, 65078, 0, 92991, 4837, 67413, + 770, 92671, 811, 70062, 41042, 83073, 41318, 64427, 73999, 67693, 78848, + 3895, 92615, 74341, 3976, 128466, 42859, 10193, 3116, 7747, 78488, 0, + 43496, 0, 121015, 43686, 78846, 41877, 983743, 2871, 64614, 68843, 999, + 983844, 6345, 41876, 2663, 2017, 121234, 67824, 11040, 10150, 120678, + 64308, 1522, 597, 4775, 12555, 12571, 12550, 12583, 12560, 2019, 12556, + 12584, 3092, 0, 12562, 4783, 12566, 12569, 12554, 83344, 10812, 78851, 0, + 83342, 3078, 1402, 0, 83348, 0, 125072, 119248, 394, 3088, 83347, 92172, + 917965, 3991, 64391, 83341, 128524, 424, 66328, 1999, 69659, 73914, 0, + 127534, 66903, 128468, 42231, 2209, 125103, 0, 0, 41840, 66913, 2377, 1298, 64011, 12572, 11318, 12557, 12559, 12570, 7479, 1003, 2373, 9446, - 7481, 9448, 48, 0, 9480, 481, 0, 9438, 9439, 9440, 9441, 8465, 9443, - 9444, 9445, 9430, 9431, 9432, 9433, 9434, 9435, 3984, 9437, 0, 0, 9424, - 9425, 9426, 9427, 9428, 9429, 64758, 2362, 9655, 0, 2004, 9096, 9782, - 128848, 9172, 128545, 19965, 0, 5955, 67666, 1108, 0, 74773, 0, 0, 64782, - 3926, 92448, 65210, 8798, 0, 92165, 1392, 0, 0, 127364, 10606, 8065, - 118805, 10353, 10417, 0, 0, 64524, 92418, 4019, 0, 983288, 43280, 8219, - 68402, 1812, 119963, 983692, 0, 126488, 42410, 74448, 119132, 6054, - 10697, 3169, 42297, 42322, 10642, 3909, 9950, 0, 128139, 983261, 68678, - 0, 0, 1049, 0, 65707, 2304, 41806, 92326, 42336, 3921, 0, 11775, 64760, + 7481, 9448, 48, 983084, 9480, 481, 0, 9438, 9439, 9440, 9441, 8465, 9443, + 9444, 9445, 9430, 9431, 9432, 9433, 9434, 9435, 3984, 9437, 129135, + 92934, 9424, 9425, 9426, 9427, 9428, 9429, 64758, 2362, 9655, 128050, + 2004, 9096, 9782, 70842, 9172, 83071, 19965, 0, 5955, 67666, 1108, 0, + 74773, 78271, 128909, 64782, 3926, 92448, 65210, 8798, 0, 92165, 1392, + 983817, 120838, 127364, 10606, 8065, 118805, 10353, 10417, 127238, + 128739, 64524, 92418, 4019, 0, 125082, 43280, 8219, 68402, 1812, 119963, + 121067, 128430, 120939, 42410, 74448, 119132, 6054, 10697, 3169, 42297, + 42322, 10642, 3909, 9950, 128848, 128139, 983263, 68678, 74986, 983790, + 1049, 43517, 65707, 2304, 41806, 92326, 42336, 3921, 0, 11775, 64760, 11766, 1038, 42303, 9823, 127278, 69236, 4008, 64004, 8773, 10733, 36, 0, - 5153, 41805, 0, 73735, 763, 41808, 64910, 983130, 2009, 0, 0, 127142, - 9640, 119951, 0, 120695, 8621, 120523, 12852, 3031, 983050, 64361, 0, - 182, 194718, 92716, 92598, 119950, 42613, 9058, 366, 0, 9892, 5969, - 11754, 10848, 4570, 65301, 44013, 4255, 127889, 10102, 41189, 4003, - 41026, 68109, 13293, 41192, 69635, 0, 42251, 0, 42534, 65179, 11287, - 6128, 0, 11034, 10923, 64423, 0, 65506, 0, 65861, 74083, 92600, 9932, 0, - 92423, 119955, 0, 9817, 0, 120140, 0, 12117, 66586, 4183, 10540, 66250, - 9063, 127045, 0, 119954, 0, 12897, 3792, 2011, 0, 6065, 43160, 0, 194715, - 8692, 41186, 41816, 41023, 41818, 41187, 11659, 7922, 12614, 2005, 8523, - 78002, 0, 7513, 1863, 4710, 0, 5956, 7621, 78006, 92624, 4705, 716, - 78004, 0, 4704, 120040, 120270, 42241, 161, 43977, 74546, 66214, 4706, 0, - 69914, 42672, 4709, 10680, 119065, 43293, 119944, 0, 119164, 120328, - 92467, 10187, 1700, 119223, 0, 0, 128119, 4004, 0, 10968, 43296, 983642, - 8506, 0, 0, 126996, 1005, 937, 78216, 4734, 2870, 0, 78218, 983109, 7463, - 4729, 0, 235, 1384, 4728, 0, 120420, 92490, 74449, 8109, 43105, 983174, - 4730, 447, 13186, 1513, 4733, 120415, 0, 0, 42527, 12911, 43427, 1383, - 8565, 2469, 120024, 6690, 6156, 68117, 43439, 7993, 4288, 120416, 2674, - 13238, 11922, 0, 120330, 3510, 13234, 0, 120407, 5605, 42095, 11364, 0, - 1380, 65617, 120253, 120261, 13196, 13197, 120309, 120682, 9495, 119346, - 0, 5959, 67984, 73976, 120305, 43371, 6941, 119349, 13205, 13211, 5801, - 12769, 65905, 41697, 1283, 120302, 4779, 0, 3719, 4006, 983569, 19957, - 128773, 2021, 119332, 120699, 119150, 43028, 65493, 41838, 3875, 5962, - 64341, 92616, 9814, 43457, 5827, 3314, 7787, 78234, 65494, 68153, 0, 0, - 120636, 64531, 120692, 194626, 0, 0, 66316, 65467, 5771, 41298, 983794, - 9742, 521, 0, 10800, 92222, 8404, 194625, 483, 7096, 7089, 66323, 928, 0, - 0, 119018, 10599, 11586, 3989, 10971, 43748, 65782, 9841, 8843, 12145, - 92470, 10074, 78548, 0, 3769, 0, 0, 0, 983107, 9573, 0, 65290, 8849, 0, - 65855, 65112, 1796, 120505, 0, 69665, 8164, 41301, 3502, 0, 7388, 10621, - 73838, 78553, 5825, 13007, 68165, 0, 120457, 12661, 7608, 10354, 10418, - 42411, 2022, 0, 1409, 12195, 4001, 3112, 10824, 120639, 1390, 0, 0, 421, - 43536, 5846, 120120, 4130, 127775, 7595, 42588, 7600, 120121, 66035, - 983913, 0, 65851, 42607, 128190, 92403, 3168, 0, 42134, 11831, 2370, - 2846, 92605, 0, 0, 120132, 0, 1836, 0, 0, 92558, 3740, 69843, 6290, - 65374, 120451, 2390, 3944, 66628, 120434, 0, 6135, 3118, 74265, 119093, - 120446, 0, 0, 8127, 8975, 64739, 7943, 983743, 0, 10618, 2584, 0, 0, 0, - 9998, 128564, 0, 0, 0, 0, 6204, 0, 0, 8279, 8776, 64954, 4975, 70075, - 120130, 4267, 1631, 42206, 77983, 0, 195046, 65700, 66562, 0, 64645, 0, - 0, 126588, 12586, 0, 9242, 127922, 0, 4523, 5842, 10495, 3122, 983797, - 7793, 78275, 9328, 119104, 78393, 12604, 0, 6615, 2285, 92344, 3986, - 44025, 0, 8912, 64555, 7409, 0, 983358, 9541, 78276, 0, 11275, 8540, - 11498, 0, 983357, 41040, 2459, 0, 13060, 41041, 74413, 983138, 0, 0, - 68427, 10450, 12551, 41043, 7020, 120353, 3765, 983350, 0, 1606, 120348, - 120351, 3093, 68436, 0, 983061, 119613, 0, 0, 4312, 74091, 120337, - 120336, 11923, 4023, 120333, 5763, 94015, 4827, 10894, 12810, 64406, - 118785, 4455, 74321, 433, 119620, 66660, 2499, 0, 0, 118837, 11973, - 13089, 4293, 120329, 42224, 42758, 12196, 42837, 42226, 119319, 0, - 119126, 5817, 127806, 55277, 3120, 9797, 0, 0, 0, 10389, 126485, 0, 4895, - 65358, 0, 4359, 585, 2383, 3509, 70037, 486, 4290, 5758, 127546, 0, 0, - 7004, 0, 65880, 127886, 119048, 2380, 11380, 0, 93996, 2376, 0, 119320, - 0, 5197, 127046, 127047, 127048, 2366, 127050, 127051, 120554, 120045, 0, - 0, 0, 983084, 0, 0, 0, 74188, 71342, 983086, 983573, 120047, 128575, 0, - 0, 120049, 0, 1847, 0, 10339, 983365, 42384, 0, 4227, 74158, 0, 92501, - 43032, 0, 42365, 0, 12671, 11384, 0, 983465, 0, 64797, 983345, 5820, - 983344, 120052, 120065, 0, 120064, 120650, 42137, 9893, 2754, 12664, - 120063, 0, 7377, 127867, 41799, 65530, 1711, 12984, 43039, 3114, 6255, - 983340, 118938, 0, 10853, 926, 983369, 74184, 983368, 120055, 0, 43175, - 0, 43037, 41798, 41035, 11583, 127769, 41801, 119088, 119605, 520, 4200, - 12699, 8331, 0, 3091, 41034, 127353, 983681, 8360, 0, 78044, 321, 4229, - 64543, 917946, 65563, 0, 917974, 2861, 43793, 10095, 0, 9195, 92386, - 1861, 0, 73733, 0, 0, 43041, 0, 43794, 128530, 3859, 12181, 41660, 8209, - 0, 73867, 12973, 0, 74757, 127514, 41658, 0, 0, 5760, 0, 743, 4414, - 120766, 0, 42632, 917973, 65161, 73896, 128589, 0, 1405, 119063, 43220, - 43341, 0, 19919, 0, 64532, 65367, 43710, 0, 0, 3513, 0, 118883, 43342, - 119064, 65529, 65364, 128197, 0, 6485, 1397, 0, 41986, 92678, 0, 0, - 74097, 0, 7471, 12079, 67997, 12682, 43287, 92317, 0, 983143, 983707, 0, - 0, 1099, 10490, 0, 10501, 65181, 74463, 0, 464, 41624, 65283, 67663, - 78222, 1346, 0, 917631, 64573, 64897, 423, 1818, 65144, 0, 8272, 127812, - 19911, 4218, 3087, 64960, 127234, 43564, 0, 0, 9584, 10465, 983902, - 74359, 12626, 9106, 0, 42642, 120230, 64750, 9390, 0, 41797, 0, 0, 265, - 41795, 64666, 126508, 43530, 2752, 0, 0, 983493, 59, 0, 983593, 0, 92371, - 77873, 41810, 0, 7010, 0, 41809, 41495, 119364, 0, 42252, 42213, 8009, - 3305, 43033, 511, 92700, 66255, 13127, 120067, 0, 74397, 120235, 917977, - 65915, 1400, 41812, 10685, 194870, 2103, 10387, 4453, 43276, 917783, - 13159, 0, 6481, 41213, 0, 0, 0, 0, 41983, 74198, 6617, 9116, 119654, 0, - 462, 68110, 10493, 0, 8129, 0, 0, 74471, 6644, 11658, 0, 128245, 3452, - 11906, 9581, 1385, 3098, 0, 119013, 43340, 0, 41033, 6493, 42626, 0, 0, - 11426, 77887, 1681, 118789, 1204, 3755, 64661, 7235, 10170, 3966, 8911, - 0, 41841, 43338, 0, 0, 5726, 64915, 42175, 0, 0, 41497, 65044, 120109, - 2851, 43017, 983589, 0, 4373, 78058, 0, 9587, 1789, 6671, 128840, 3100, - 0, 65360, 0, 92365, 917789, 64922, 0, 8190, 12083, 0, 0, 6506, 64312, - 74374, 2368, 0, 4419, 983847, 119125, 3439, 1825, 1192, 120106, 8891, - 3080, 120228, 2347, 5430, 0, 8990, 2848, 0, 128223, 92528, 249, 0, 0, 0, - 120658, 0, 0, 8883, 917802, 728, 68178, 995, 0, 0, 64826, 0, 917798, - 128348, 0, 19945, 8091, 558, 0, 12273, 194814, 983850, 12112, 69912, 0, - 0, 74419, 12335, 120104, 917795, 3443, 3129, 0, 2102, 65445, 78258, - 64891, 0, 7725, 65108, 78255, 0, 8624, 69246, 12446, 43295, 0, 41894, 0, - 6277, 41672, 41893, 10010, 128678, 3540, 128649, 835, 71340, 69816, - 119868, 74408, 0, 73959, 5426, 4258, 0, 0, 5424, 128127, 8283, 0, 5434, - 983590, 0, 19917, 11408, 0, 11947, 0, 1404, 3095, 11432, 128307, 3464, - 6486, 4819, 128233, 0, 570, 8095, 3672, 119864, 1498, 67866, 0, 128539, - 431, 0, 0, 128182, 128096, 68167, 983663, 13096, 128643, 0, 43408, 9516, - 128538, 5268, 42230, 42220, 0, 4450, 120511, 11547, 43417, 128542, 356, - 3477, 227, 10488, 68203, 382, 11418, 0, 195066, 0, 0, 0, 0, 6484, 2541, - 66039, 0, 78718, 92723, 3549, 0, 9110, 119665, 2743, 0, 43290, 194812, - 9097, 0, 43015, 8782, 0, 776, 2524, 42707, 8573, 0, 126494, 0, 0, 42694, - 64944, 8952, 3856, 118818, 0, 5872, 6495, 0, 0, 0, 92543, 0, 120733, - 12849, 3953, 1897, 0, 65094, 11994, 4339, 74556, 92654, 67843, 0, 0, 0, - 68473, 74104, 5228, 128804, 7868, 43184, 0, 0, 73986, 43438, 0, 43022, 0, - 1162, 917847, 2671, 0, 0, 92632, 92631, 118865, 4553, 73811, 0, 195005, - 0, 0, 19921, 74331, 11424, 195006, 4567, 41891, 0, 983788, 55249, 4820, - 65239, 194662, 0, 194665, 43042, 119212, 1377, 12869, 4897, 42821, 9250, - 0, 4438, 64385, 0, 1753, 11331, 6147, 194941, 43282, 8833, 0, 0, 6504, - 78408, 126979, 10719, 0, 1898, 1413, 42443, 0, 802, 12141, 0, 194671, - 6648, 10671, 2528, 0, 64789, 9169, 838, 120087, 120697, 844, 5014, 0, - 256, 0, 9990, 0, 42739, 917851, 7542, 65464, 9726, 0, 6489, 10048, 74326, - 78719, 66573, 0, 78724, 78712, 11761, 194655, 0, 41094, 0, 0, 194893, 0, - 92689, 6196, 6945, 93969, 194890, 128184, 120491, 11816, 194943, 5733, - 2930, 0, 0, 41098, 0, 41093, 0, 66626, 588, 9760, 0, 194717, 1238, 200, - 983207, 1660, 73916, 0, 118905, 74362, 0, 92485, 194651, 0, 983706, 3394, - 194894, 120668, 0, 0, 127358, 66219, 127183, 43284, 194656, 7817, 1841, - 11055, 120533, 194979, 194982, 1669, 10776, 194981, 7701, 194980, 0, - 194995, 1732, 4030, 0, 3963, 66611, 127530, 41768, 6491, 0, 65324, 914, - 65323, 8071, 3538, 0, 2287, 65328, 92441, 74367, 7614, 0, 11819, 0, - 12009, 12399, 0, 67852, 65537, 0, 10841, 43430, 5301, 0, 92618, 5734, - 8960, 0, 92527, 65317, 77880, 0, 0, 0, 12304, 0, 0, 65315, 92670, 128511, - 0, 0, 0, 119621, 92529, 74536, 12447, 64486, 127374, 126562, 983129, 0, - 0, 983802, 42767, 10915, 0, 12007, 43695, 120520, 11975, 194878, 0, - 92604, 2555, 8629, 128640, 43168, 41872, 43706, 4496, 194879, 128148, - 120241, 0, 0, 0, 0, 64730, 70041, 66714, 68222, 0, 70076, 65596, 92306, - 11416, 4280, 67655, 8765, 12784, 7792, 1393, 126473, 67871, 74386, 0, - 8233, 12820, 0, 6683, 194876, 3442, 12144, 2841, 12543, 0, 1473, 42820, - 64329, 127832, 0, 68642, 6488, 357, 1048, 41100, 0, 41104, 94003, 3406, - 1054, 71320, 1040, 65450, 0, 4434, 1069, 0, 118862, 65737, 917765, - 128705, 0, 983693, 9693, 41943, 126564, 41931, 41759, 12757, 4353, 0, - 1059, 9790, 8995, 119974, 983696, 65937, 0, 41764, 10646, 0, 118833, - 92372, 0, 74830, 78569, 12743, 983689, 6480, 917761, 41779, 42580, 66601, - 12207, 119619, 6335, 66602, 11312, 64807, 0, 0, 41767, 119629, 983764, - 43020, 128271, 3955, 74254, 0, 983754, 917861, 0, 77926, 9770, 9246, - 12230, 0, 0, 0, 10448, 41783, 41786, 127093, 12797, 2755, 64571, 78578, - 194927, 4857, 0, 4428, 12794, 73755, 128061, 78574, 0, 74284, 0, 5747, - 78825, 0, 7978, 41092, 74571, 0, 11924, 43812, 42144, 65015, 0, 563, 0, - 983691, 12798, 11271, 57, 0, 0, 917860, 119043, 0, 94051, 43137, 694, 0, - 9876, 0, 119168, 0, 78822, 64537, 0, 277, 74385, 7229, 12761, 0, 0, - 13025, 64811, 8757, 78824, 126478, 1574, 7381, 0, 2525, 4852, 5749, - 68465, 13027, 42824, 120574, 1039, 7151, 10155, 5745, 188, 41858, 11592, - 0, 74015, 9055, 41853, 4858, 917780, 0, 436, 4771, 0, 2786, 0, 4856, - 8051, 0, 119609, 71327, 9644, 0, 0, 0, 194916, 120732, 66710, 118834, - 983359, 73906, 128680, 127114, 0, 10234, 5843, 11939, 0, 42157, 0, 3157, - 194918, 68393, 0, 3504, 119178, 0, 10822, 5149, 66029, 10226, 65142, - 128025, 3594, 42424, 194959, 40, 12657, 983665, 0, 386, 0, 8834, 0, - 12815, 43574, 0, 73907, 0, 74196, 7220, 74504, 0, 74316, 0, 65322, 4304, - 74503, 8160, 78707, 194753, 0, 0, 128526, 1348, 92349, 78597, 126539, - 13303, 0, 92392, 194755, 7599, 1278, 43616, 13269, 0, 0, 74387, 78179, - 78598, 74492, 6097, 7568, 8780, 4982, 127464, 74501, 194763, 78592, - 194762, 2672, 3735, 127470, 13138, 42266, 9484, 10724, 41202, 71364, 0, - 43742, 0, 9487, 119959, 119117, 3842, 128768, 78668, 12442, 6193, 9791, - 127976, 0, 42516, 7228, 7559, 74803, 78468, 7873, 11399, 119219, 194691, - 194855, 194690, 194857, 3604, 120683, 119188, 128877, 78540, 78541, - 42507, 1962, 43305, 78476, 42505, 11660, 0, 2072, 92312, 6995, 74173, - 5437, 74174, 10669, 8702, 7964, 92352, 0, 199, 194843, 4105, 194845, - 194699, 194847, 194710, 119875, 13148, 7560, 78479, 9226, 78480, 195070, - 6472, 65814, 73954, 0, 4724, 0, 0, 9191, 0, 64432, 983817, 983247, - 195024, 10196, 7886, 0, 6585, 0, 6680, 195042, 0, 195051, 6679, 74412, - 92251, 194866, 74421, 11382, 983631, 983637, 127891, 127484, 194833, - 194832, 6681, 127482, 12693, 194836, 42727, 78196, 128252, 78195, 65442, - 119610, 69733, 9989, 43248, 66248, 194816, 0, 11321, 128845, 194820, - 194819, 5297, 7042, 13284, 6112, 7968, 194825, 73927, 92444, 194736, - 65746, 127476, 69889, 74389, 128696, 4342, 42839, 194831, 1677, 0, 0, - 126590, 917855, 11091, 11011, 2719, 0, 0, 119595, 10160, 0, 0, 7585, - 65169, 2052, 4308, 92174, 43000, 7505, 543, 64916, 64736, 0, 0, 64655, 0, - 118922, 2064, 0, 43158, 7902, 0, 65265, 194639, 0, 127170, 0, 983625, 0, - 0, 12994, 92728, 10828, 983943, 6228, 4307, 3482, 128527, 0, 0, 0, 506, - 74573, 41194, 65735, 2055, 43255, 41195, 0, 8169, 983680, 8841, 0, 516, - 93974, 2063, 119051, 34, 128850, 120186, 11504, 1612, 74333, 120182, - 11827, 74308, 12001, 120178, 10242, 64564, 120179, 67986, 6584, 7749, - 11037, 0, 1758, 127092, 10667, 10560, 120197, 92593, 1935, 11517, 120193, - 120196, 120195, 1931, 120189, 74839, 120191, 1217, 64702, 12643, 825, - 127838, 194905, 12294, 92428, 78834, 9138, 78831, 78833, 12631, 78829, - 11080, 74554, 64000, 5591, 1239, 0, 11313, 0, 3403, 0, 0, 64364, 92269, - 0, 74582, 8998, 12988, 0, 9152, 983849, 0, 126484, 67589, 41850, 64290, - 3433, 92393, 12615, 1594, 42192, 6914, 67603, 0, 119569, 74565, 41353, - 67602, 67611, 4337, 0, 127296, 918, 65035, 41351, 7681, 194900, 42577, - 41393, 12668, 194904, 2477, 127285, 0, 127301, 0, 67604, 194880, 127235, - 573, 127282, 194884, 11417, 194886, 119814, 194888, 67599, 0, 194889, - 67607, 11482, 0, 3981, 3357, 0, 42223, 4207, 1288, 78842, 78839, 68419, - 78837, 11589, 42195, 194872, 194599, 127263, 64602, 67618, 92539, 0, - 42788, 68416, 64480, 194875, 8423, 3348, 448, 68476, 9717, 0, 0, 997, 0, - 0, 92577, 0, 11440, 11379, 42000, 13139, 42221, 65013, 126999, 127760, - 73796, 0, 119228, 12035, 0, 2818, 0, 74411, 73793, 0, 4172, 0, 0, 8373, - 10873, 12197, 0, 0, 92265, 69706, 0, 78210, 0, 128110, 194865, 126982, - 74563, 64828, 11419, 194868, 766, 1257, 0, 118845, 11381, 3265, 66617, - 3274, 127365, 126523, 94042, 983950, 74522, 41989, 0, 0, 128798, 3263, 0, - 65672, 0, 3270, 64539, 11489, 0, 0, 0, 0, 9505, 65518, 194776, 756, - 194605, 0, 0, 0, 7261, 0, 186, 0, 119156, 5770, 13179, 65830, 12612, - 12949, 64856, 12800, 983901, 74203, 64718, 11507, 0, 92434, 118929, 0, - 11578, 0, 119296, 0, 0, 0, 0, 74568, 9254, 0, 1794, 120217, 64521, 5624, - 120220, 120221, 119958, 120223, 3617, 66636, 64886, 94061, 120212, - 120213, 120214, 1872, 66508, 120467, 41079, 10748, 5502, 119330, 4452, 0, - 983771, 92526, 4511, 0, 983877, 64678, 11425, 0, 43245, 1231, 194783, - 69903, 0, 9003, 8192, 0, 5305, 9653, 10616, 8694, 9546, 0, 0, 120478, - 120200, 65205, 120202, 64063, 9878, 74780, 119626, 78202, 64058, 8799, - 42131, 0, 64062, 1028, 64060, 64059, 837, 10567, 0, 43103, 0, 120754, - 11427, 2902, 64043, 64042, 43749, 10756, 64047, 42606, 64045, 64044, - 43979, 10076, 64040, 43060, 194942, 1034, 3392, 127771, 43091, 64033, - 64032, 42735, 64038, 64037, 64036, 64035, 4291, 194928, 64015, 64014, - 64681, 194930, 0, 78145, 0, 43090, 0, 3476, 8973, 64012, 42473, 64010, - 64008, 64007, 2003, 7706, 64517, 78153, 2538, 64009, 204, 0, 4802, 4111, - 8239, 9098, 4805, 64001, 64057, 7885, 7247, 64054, 983266, 0, 4767, 9343, - 64049, 64048, 120034, 1133, 64053, 64052, 43453, 64050, 41340, 118975, - 194835, 10005, 12329, 41333, 0, 8489, 1942, 0, 194834, 42520, 128249, 0, - 0, 10760, 64023, 64022, 64021, 6582, 43670, 0, 64025, 9167, 42151, 78244, - 983232, 2026, 64019, 64018, 64017, 64016, 12768, 0, 7582, 78252, 78248, - 77914, 78246, 78247, 0, 77915, 78766, 6788, 13094, 77920, 7532, 41414, - 78520, 3179, 78518, 64769, 78514, 78517, 11461, 74454, 10751, 9051, - 120720, 6708, 10535, 983627, 68218, 55274, 2008, 64031, 64030, 294, - 41874, 0, 126991, 65929, 0, 0, 0, 0, 64028, 8146, 64026, 41788, 194844, - 0, 4351, 6343, 43247, 119888, 0, 119886, 119891, 119892, 119889, 11433, - 119895, 119896, 0, 7801, 65578, 194839, 12915, 43968, 3297, 9699, 194955, - 1135, 0, 0, 128525, 1995, 6722, 983925, 0, 2552, 41546, 60, 68394, 8649, - 41549, 78496, 983327, 0, 6682, 0, 78679, 64710, 41547, 983630, 2013, - 128291, 78530, 78532, 78528, 78529, 12832, 78493, 8081, 8362, 3537, - 119908, 9137, 7155, 8999, 0, 78533, 3466, 0, 0, 1996, 0, 3453, 6282, 0, - 2002, 2000, 120175, 537, 0, 4179, 65119, 1998, 0, 1842, 0, 92674, 9628, - 68446, 12081, 9826, 64502, 1767, 0, 0, 0, 120201, 983646, 0, 0, 3059, - 44024, 120204, 119953, 92693, 0, 0, 92452, 4100, 920, 1811, 1355, 0, 0, - 3592, 10078, 0, 0, 0, 8592, 65870, 68164, 128792, 10742, 0, 42918, 1994, - 9281, 3296, 12865, 1997, 1895, + 5153, 41805, 0, 73735, 763, 41808, 64910, 121389, 2009, 0, 127985, 74245, + 9640, 119951, 0, 69895, 8621, 120523, 12852, 3031, 983050, 64361, 129088, + 182, 66414, 92716, 92598, 119950, 42613, 9058, 366, 0, 9892, 5969, 11754, + 10848, 4570, 65301, 44013, 4255, 127889, 10102, 41189, 4003, 41026, + 68109, 13293, 41192, 69635, 124977, 42251, 0, 42534, 65179, 11287, 6128, + 113811, 11034, 10923, 64423, 125058, 65506, 983912, 65861, 74083, 66872, + 9932, 43516, 83063, 83065, 83064, 9817, 0, 71234, 0, 12117, 66586, 4183, + 10540, 66250, 9063, 127045, 128547, 119954, 113685, 12897, 3792, 2011, + 121418, 6065, 43160, 128379, 120595, 8692, 41186, 41816, 41023, 41818, + 41187, 11659, 7922, 12614, 2005, 8523, 78002, 120035, 7513, 1863, 4710, + 0, 5956, 7621, 78005, 92624, 4705, 716, 74918, 0, 4704, 120040, 93024, + 42241, 161, 43977, 74546, 66214, 4706, 74077, 69914, 42672, 4709, 10680, + 119065, 43293, 68771, 983190, 119164, 120328, 83319, 10187, 1700, 119223, + 83315, 0, 74980, 4004, 917595, 10968, 43296, 128331, 8506, 113744, + 194812, 126996, 1005, 937, 78216, 4734, 2870, 121350, 78218, 983109, + 7463, 4729, 0, 235, 1384, 4728, 74887, 70494, 92490, 74449, 8109, 43105, + 128623, 4730, 447, 13186, 1513, 4733, 120415, 92548, 0, 42527, 12911, + 43427, 1383, 8565, 2469, 120024, 6690, 6156, 68117, 43439, 7993, 4288, + 120416, 2674, 13238, 11922, 0, 92529, 3510, 13234, 983832, 120407, 5605, + 42095, 11364, 92286, 1380, 65617, 11162, 120261, 13196, 13197, 120309, + 67708, 9495, 119346, 127154, 5959, 67984, 73976, 66275, 43371, 6941, + 119349, 13205, 13211, 5801, 12769, 65905, 41697, 1283, 82952, 4779, + 983922, 3719, 4006, 983569, 19957, 71186, 2021, 119332, 43877, 83140, + 43028, 65493, 41838, 3875, 5962, 64341, 92616, 9814, 43457, 5827, 3314, + 7787, 71189, 65494, 68153, 126991, 194697, 120636, 64531, 120692, 194626, + 128753, 983958, 66316, 65467, 5771, 41298, 983794, 9742, 521, 0, 10800, + 92222, 8404, 194625, 483, 7096, 7089, 66323, 928, 0, 0, 119018, 10599, + 11586, 3989, 10971, 43748, 65782, 9841, 8843, 12145, 67261, 10074, 78548, + 93999, 3769, 0, 0, 128703, 983107, 9573, 917998, 65290, 8849, 119254, + 65855, 65112, 1796, 71046, 0, 69665, 8164, 41301, 3502, 83135, 7388, + 10621, 73838, 78553, 5825, 13007, 68165, 92203, 92915, 12661, 7608, + 10354, 10418, 42411, 2022, 0, 1409, 12195, 4001, 3112, 10824, 120639, + 1390, 70184, 194704, 421, 43536, 5846, 120120, 4130, 127775, 7595, 42588, + 7600, 74400, 66035, 195091, 0, 65851, 42607, 124955, 92403, 3168, 67733, + 42134, 11831, 2370, 2846, 92605, 128084, 0, 120132, 127745, 1836, 0, + 121207, 92558, 3740, 69843, 6290, 65374, 120451, 2390, 3944, 66628, + 119006, 0, 6135, 3118, 74265, 119093, 83310, 77975, 0, 8127, 8975, 64739, + 7943, 124968, 119234, 10618, 2584, 0, 0, 128225, 9998, 120573, 83306, 0, + 127750, 43508, 6204, 127044, 121374, 8279, 8776, 64954, 4975, 70075, + 120130, 4267, 1631, 42206, 77983, 128015, 195046, 65700, 66386, 0, 64645, + 0, 92887, 126588, 12586, 0, 9242, 120100, 0, 4523, 5842, 10495, 3122, + 983797, 7793, 78275, 9328, 119104, 78393, 12604, 92885, 6615, 2285, + 92344, 3986, 44025, 0, 8912, 64555, 7409, 92247, 983360, 9541, 78276, + 113669, 11275, 8540, 11498, 120868, 983359, 41040, 2459, 127302, 13060, + 41041, 74413, 983138, 0, 77931, 68427, 10450, 12551, 41043, 7020, 120353, + 3765, 92881, 917612, 1606, 120348, 92299, 3093, 68436, 128040, 983061, + 119613, 0, 0, 4312, 74091, 120337, 74983, 11923, 4023, 68399, 5763, + 94015, 4827, 10894, 12810, 64406, 118785, 4455, 74321, 433, 119620, + 66660, 2499, 67167, 67166, 118837, 11973, 13089, 4293, 120329, 42224, + 42758, 12196, 42837, 42226, 119319, 127992, 119126, 5817, 127806, 55277, + 3120, 9797, 0, 0, 11086, 10389, 126485, 128784, 4895, 65358, 124941, + 4359, 585, 2383, 3509, 70037, 486, 4290, 5758, 127546, 121160, 983106, + 7004, 113667, 65880, 126514, 119048, 2380, 11380, 983863, 93996, 2376, + 78841, 83402, 0, 5197, 70839, 127047, 127048, 2366, 127050, 119604, + 70837, 120045, 0, 128554, 0, 917846, 0, 0, 0, 74188, 71342, 78455, 75048, + 113675, 74900, 120046, 127542, 120049, 983366, 1847, 120978, 10339, + 983367, 42384, 121379, 4227, 74158, 0, 74498, 43032, 121124, 42365, 0, + 12671, 11384, 120059, 74264, 120058, 64797, 983347, 5820, 983346, 120052, + 120065, 128825, 120064, 120053, 42137, 9893, 2754, 12664, 120063, 121286, + 7377, 120051, 41799, 65530, 1711, 12984, 43039, 3114, 6255, 121132, + 68660, 0, 10853, 926, 983371, 74184, 120915, 120055, 119301, 43175, 0, + 43037, 41798, 41035, 11583, 127769, 41801, 119088, 119605, 520, 4200, + 12699, 8331, 70118, 3091, 41034, 66298, 70293, 8360, 983445, 78044, 321, + 4229, 64543, 128470, 65563, 194873, 917974, 2861, 43793, 10095, 121428, + 9195, 92386, 1861, 0, 73733, 917780, 68839, 43041, 0, 43794, 128530, + 3859, 12181, 41660, 8209, 70793, 73867, 12973, 75014, 74757, 127514, + 41658, 128376, 121235, 5760, 113699, 743, 4414, 120766, 0, 42632, 127236, + 65161, 73896, 128589, 0, 1405, 119063, 43220, 43341, 0, 19919, 70278, + 64532, 65367, 43710, 11199, 125077, 3513, 71115, 70341, 43342, 119064, + 65529, 65364, 83208, 83170, 6485, 1397, 194781, 41986, 92678, 83204, + 83212, 74097, 83213, 7471, 12079, 67997, 6843, 43287, 92317, 0, 67406, + 120239, 194678, 71914, 1099, 10490, 83201, 10501, 65181, 74463, 128952, + 464, 41624, 65283, 67663, 78222, 1346, 194609, 65679, 64573, 64897, 423, + 1818, 65144, 82963, 8272, 127812, 19911, 4218, 3087, 64960, 121447, + 43564, 0, 983182, 9584, 10465, 983902, 74359, 12626, 9106, 0, 42642, + 71235, 64750, 9390, 0, 41797, 194730, 128333, 265, 41795, 64666, 74628, + 43530, 2752, 127365, 128459, 126482, 59, 983671, 121410, 11149, 78074, + 77873, 41810, 83162, 7010, 0, 41809, 41495, 119364, 5877, 42252, 42213, + 8009, 3305, 43033, 511, 92700, 43848, 13127, 120067, 983946, 74397, + 120235, 128641, 65915, 1400, 41812, 10685, 75017, 2103, 10387, 4453, + 43276, 917783, 11169, 128939, 6481, 41213, 0, 0, 129133, 119929, 41983, + 74198, 6617, 9116, 119654, 92995, 462, 68110, 10493, 121449, 8129, 92994, + 128365, 74471, 6644, 11658, 0, 128245, 3452, 11906, 9581, 1385, 3098, 0, + 119013, 43340, 11123, 41033, 6493, 42626, 0, 129051, 11426, 77887, 1681, + 118789, 1204, 3755, 64661, 7235, 10170, 3966, 8911, 0, 41841, 43338, 0, + 119323, 5726, 64915, 42175, 983913, 0, 41497, 65044, 120109, 2851, 43017, + 983589, 120896, 4373, 78058, 0, 9587, 1789, 6671, 128840, 3100, 0, 65360, + 917589, 92365, 128202, 64922, 0, 8190, 12083, 0, 83141, 6506, 64312, + 74374, 2368, 983187, 4419, 121259, 119125, 3439, 1825, 1192, 120106, + 8891, 3080, 120228, 2347, 5430, 120107, 8990, 2848, 92981, 121372, 73942, + 249, 0, 0, 0, 120658, 119324, 128712, 8883, 119860, 728, 11173, 995, 0, + 121047, 64826, 124931, 917798, 128348, 0, 19945, 8091, 558, 0, 12273, + 194814, 67714, 12112, 67272, 67265, 67273, 67274, 12335, 120104, 68019, + 3443, 3129, 67267, 2102, 65445, 78258, 64891, 0, 7725, 65108, 11120, + 9205, 8624, 69246, 12446, 43295, 128519, 41894, 0, 6277, 41672, 41893, + 10010, 127381, 3540, 121450, 835, 71340, 69816, 119854, 74408, 0, 67108, + 5426, 4258, 83188, 120858, 5424, 92306, 8283, 127978, 5434, 83196, + 129027, 19917, 11408, 0, 11947, 128330, 1404, 3095, 11432, 121122, 3464, + 6486, 4819, 128233, 129123, 570, 8095, 3672, 119864, 1498, 67866, 0, + 128539, 431, 67820, 0, 128182, 128096, 68167, 983663, 13096, 128643, + 121018, 43408, 9516, 128538, 5268, 42230, 42220, 0, 4450, 120511, 11547, + 43417, 128542, 356, 3477, 227, 10488, 68203, 382, 11418, 0, 5878, 983799, + 0, 0, 0, 6484, 2541, 66039, 113777, 78157, 92723, 3549, 195067, 9110, + 119665, 2743, 0, 43290, 128585, 9097, 195026, 43015, 8782, 0, 776, 2524, + 42707, 8573, 120903, 126494, 0, 71102, 42694, 64944, 8952, 3856, 118818, + 125111, 5872, 6495, 129125, 0, 0, 92543, 67173, 67172, 12849, 3953, 1897, + 93071, 65094, 11994, 4339, 74556, 92654, 67843, 0, 0, 119087, 68473, + 74104, 5228, 119835, 7868, 43184, 0, 120955, 73986, 43438, 0, 43022, + 917553, 1162, 74995, 2671, 128567, 127198, 92632, 92631, 118865, 4553, + 73811, 983573, 195005, 118928, 68085, 19921, 73821, 11424, 195002, 4567, + 41891, 0, 983788, 55249, 4820, 65239, 194662, 0, 194665, 43042, 119212, + 1377, 12869, 4897, 42821, 9250, 70272, 4438, 64385, 0, 1753, 11331, 6147, + 194941, 43282, 8833, 69998, 0, 6504, 78408, 121166, 10719, 70275, 1898, + 1413, 42443, 0, 802, 12141, 121138, 83097, 6648, 10671, 2528, 0, 64789, + 9169, 838, 68819, 68807, 844, 5014, 66297, 256, 68818, 9990, 128398, + 42739, 917851, 7542, 65464, 9726, 83224, 6489, 10048, 74326, 78719, + 66573, 0, 78724, 78712, 11761, 121314, 83226, 41094, 0, 77958, 194893, + 78403, 92689, 6196, 6945, 93969, 120942, 67095, 120491, 11816, 68846, + 5733, 2930, 70274, 127179, 41098, 92771, 41093, 68834, 66626, 588, 9760, + 125099, 194717, 1238, 200, 983207, 1660, 73916, 0, 67141, 74362, 0, + 92485, 124930, 0, 74999, 3394, 194894, 120668, 0, 69996, 127358, 66219, + 72425, 43284, 68072, 7817, 1841, 11055, 66835, 194979, 74607, 1669, + 10776, 74534, 7701, 194980, 983450, 74992, 1732, 4030, 983442, 3963, + 65335, 127530, 41768, 6491, 65333, 65324, 914, 65323, 8071, 3538, 983845, + 2287, 65328, 92441, 74367, 7614, 0, 11819, 71908, 12009, 12399, 121217, + 67852, 65537, 0, 10841, 43430, 5301, 0, 92618, 5734, 8960, 0, 70123, + 65317, 77880, 0, 5876, 70374, 12304, 0, 0, 65315, 92670, 128511, 71862, + 0, 127957, 119621, 11114, 71909, 12447, 64486, 121236, 126562, 983129, 0, + 121393, 983802, 42767, 10915, 983174, 12007, 43695, 68033, 11975, 194878, + 0, 92604, 2555, 8629, 128640, 41133, 41872, 43706, 4496, 194879, 83108, + 120241, 128164, 0, 0, 983553, 64730, 70041, 66714, 68222, 0, 70076, + 65596, 67837, 11416, 4280, 67655, 8765, 12784, 7792, 1393, 78191, 11157, + 74386, 127274, 8233, 12820, 983730, 6683, 125112, 3442, 12144, 2841, + 12543, 0, 1473, 42820, 64329, 120880, 67243, 68642, 6488, 357, 1048, + 41100, 72417, 41104, 94003, 3406, 1054, 71320, 1040, 65450, 983385, 4434, + 1069, 194784, 118862, 65737, 121202, 128705, 0, 83211, 9693, 41943, + 68305, 41931, 41759, 12757, 4353, 983353, 1059, 9790, 8995, 119974, + 917770, 65937, 78572, 41758, 10646, 121159, 118833, 92372, 70424, 74830, + 78569, 12743, 983689, 6480, 917761, 41779, 42580, 66601, 12207, 77895, + 6335, 43919, 11312, 64807, 92962, 69989, 41767, 119629, 983764, 43020, + 74974, 3955, 74254, 120632, 983754, 917861, 70187, 69975, 9770, 9246, + 12230, 125047, 129105, 78580, 10448, 41783, 41786, 127093, 12797, 2755, + 64571, 78578, 194927, 4857, 983577, 4428, 12794, 73755, 128061, 78574, 0, + 11116, 43842, 5747, 78825, 70471, 7978, 41092, 74571, 0, 11924, 43812, + 42144, 65015, 0, 563, 0, 129412, 12798, 11271, 57, 92717, 83495, 917860, + 119043, 917618, 94051, 43137, 694, 983719, 9876, 0, 119168, 0, 70392, + 64537, 127914, 277, 74385, 7229, 12761, 983145, 74466, 13025, 64811, + 8757, 78824, 78188, 1574, 7381, 0, 2525, 4852, 5749, 68465, 13027, 42824, + 120574, 1039, 7151, 10155, 5745, 188, 41858, 11592, 129156, 69725, 9055, + 41853, 4858, 75000, 917990, 436, 4771, 917936, 2786, 93028, 4856, 8051, + 92500, 119609, 71327, 9644, 71133, 125009, 128873, 194916, 120732, 66710, + 68084, 983361, 73906, 67409, 127114, 917916, 10234, 5843, 11939, 70346, + 42157, 0, 3157, 194659, 68393, 75035, 3504, 70422, 0, 10822, 5149, 66029, + 10226, 65142, 128025, 3594, 42424, 124993, 40, 12657, 983665, 0, 386, + 121467, 8834, 120974, 12815, 43574, 121430, 73907, 127792, 70113, 7220, + 11839, 121143, 74316, 194752, 65322, 4304, 74503, 8160, 74314, 194753, + 121276, 0, 128526, 1348, 92349, 78597, 121139, 13303, 70406, 92392, + 128474, 7599, 1278, 43616, 13269, 127805, 127110, 74387, 78179, 78598, + 74492, 6097, 7568, 8780, 4982, 127464, 74501, 194763, 78592, 68745, 2672, + 3735, 127470, 13138, 42266, 9484, 10724, 41202, 71364, 128370, 43742, + 128373, 9487, 119959, 68785, 3842, 71911, 78668, 12442, 6193, 9791, + 119344, 0, 42516, 7228, 7559, 74803, 66721, 7873, 11399, 119219, 194691, + 70006, 194690, 127537, 3604, 120683, 119188, 128877, 78540, 78541, 42507, + 1962, 43305, 78476, 42505, 11660, 121021, 2072, 92312, 6995, 74173, 5437, + 74174, 10669, 8702, 7964, 92352, 983776, 199, 68075, 4105, 194845, + 127942, 75006, 194710, 67818, 13148, 7560, 78479, 9226, 78478, 195070, + 6472, 65814, 71919, 121218, 4724, 128491, 195041, 9191, 194645, 64432, + 120270, 82987, 119190, 10196, 7886, 0, 6585, 0, 6680, 195042, 983425, + 71872, 6679, 74412, 92251, 194866, 74421, 11382, 128254, 43862, 78591, + 113733, 194679, 194832, 6681, 127482, 12693, 194836, 42727, 78196, + 128252, 43874, 65442, 68047, 69733, 9989, 43248, 66248, 194816, 0, 11321, + 128845, 120809, 194819, 5297, 7042, 13284, 6112, 7968, 93010, 73927, + 92444, 127336, 65746, 118796, 69889, 74389, 128696, 4342, 42839, 121339, + 1677, 917592, 82989, 126590, 83415, 11091, 11011, 2719, 0, 0, 119595, + 10160, 0, 129150, 7585, 65169, 2052, 4308, 83414, 43000, 7505, 543, + 64916, 64736, 118835, 0, 64655, 983053, 118922, 2064, 0, 43158, 7902, + 983231, 65265, 194639, 121080, 127170, 127041, 128006, 92550, 983186, + 12994, 92728, 10828, 74378, 6228, 4307, 3482, 128527, 83231, 72389, + 83079, 506, 74573, 41194, 65735, 2055, 43255, 41195, 0, 8169, 121407, + 8841, 983747, 516, 93974, 2063, 119051, 34, 128850, 120186, 11504, 1612, + 74333, 120182, 11827, 67165, 12001, 120178, 10242, 64564, 120179, 67986, + 6584, 7749, 11037, 128743, 1758, 119074, 10667, 10560, 120197, 92593, + 1935, 11517, 120193, 120196, 83082, 1931, 120189, 74839, 120191, 1217, + 64702, 12643, 825, 127838, 194905, 12294, 92428, 78834, 9138, 78831, + 78833, 12631, 71871, 11080, 74554, 64000, 5591, 1239, 127199, 11313, + 194803, 3403, 983655, 120271, 64364, 92269, 121282, 72431, 8998, 12988, + 119983, 9152, 92161, 0, 126484, 67589, 41850, 64290, 3433, 92393, 12615, + 1594, 42192, 6914, 66392, 0, 119569, 74565, 41353, 67602, 67611, 4337, 0, + 127296, 918, 65035, 41351, 7681, 194900, 42577, 41393, 12668, 72395, + 2477, 127285, 121249, 118880, 0, 67604, 67683, 127235, 573, 127282, + 120543, 11417, 92661, 119814, 119309, 67599, 0, 72410, 67607, 11482, 0, + 3981, 3357, 0, 42223, 4207, 1288, 78503, 78839, 67728, 77907, 11589, + 42195, 74477, 119997, 127178, 64602, 67618, 92539, 121366, 42788, 68416, + 64480, 194875, 8423, 3348, 448, 66907, 9717, 119311, 0, 997, 0, 0, 92577, + 0, 11440, 11379, 42000, 13139, 42221, 65013, 126999, 127760, 72390, 0, + 119228, 12035, 0, 2818, 0, 74411, 73793, 983278, 4172, 71252, 119992, + 8373, 10873, 12197, 125074, 195014, 92265, 69706, 128540, 6834, 74347, + 74958, 129033, 126982, 74563, 64828, 11419, 194868, 766, 1257, 194598, + 118845, 11381, 3265, 66617, 3274, 126629, 83254, 71861, 983950, 74522, + 41989, 121317, 0, 113769, 3263, 917922, 65672, 69243, 3270, 64539, 11489, + 917911, 0, 0, 71127, 9505, 65518, 128498, 756, 194605, 0, 0, 194621, + 7261, 92547, 186, 0, 119156, 5770, 13179, 65830, 12612, 12949, 64856, + 12800, 983901, 74203, 64718, 11507, 78673, 92434, 74626, 113760, 11578, + 983837, 119296, 120970, 121127, 125101, 0, 70083, 9254, 66877, 1794, + 68310, 64521, 5624, 120220, 120221, 119958, 120223, 3617, 66636, 64886, + 94061, 68659, 120213, 120214, 1872, 66508, 120467, 41079, 10748, 5502, + 119330, 4452, 128088, 983771, 92526, 4511, 120958, 983877, 64678, 11425, + 0, 43245, 1231, 68861, 69903, 0, 9003, 8192, 0, 5305, 9653, 10616, 8694, + 9546, 0, 128332, 70421, 120200, 65205, 120202, 64063, 9878, 74780, + 119626, 78202, 64058, 8799, 42131, 128662, 64062, 1028, 64060, 64059, + 837, 10567, 72384, 43103, 0, 120754, 11427, 2902, 64043, 64042, 43749, + 10756, 64047, 42606, 64045, 64044, 43979, 10076, 64040, 43060, 194942, + 1034, 3392, 83336, 43091, 64033, 64032, 42735, 43498, 64037, 64036, + 64035, 4291, 129157, 64015, 64014, 64681, 83394, 83395, 78145, 71898, + 43090, 83391, 3476, 8973, 64012, 42473, 64010, 64008, 64007, 2003, 7706, + 64517, 78153, 2538, 64009, 204, 0, 4802, 4111, 8239, 9098, 4805, 64001, + 64057, 7885, 7247, 64054, 983268, 0, 4767, 9343, 64049, 64048, 120034, + 1133, 64053, 64052, 43453, 64050, 41340, 118975, 83261, 10005, 12329, + 41333, 83259, 8489, 1942, 917921, 194834, 42520, 65510, 125044, 68291, + 10760, 64023, 64022, 64021, 6582, 43670, 127798, 64025, 9167, 42151, + 78244, 983232, 2026, 64019, 64018, 64017, 64016, 12768, 121361, 7582, + 78252, 78248, 77914, 78246, 78247, 120791, 77915, 78766, 6788, 13094, + 77920, 7532, 41414, 78520, 3179, 78518, 64769, 78514, 78517, 11461, + 74454, 10751, 9051, 120720, 6708, 10535, 118955, 68218, 55274, 2008, + 64031, 64030, 294, 41874, 83383, 64790, 65929, 83376, 83337, 83379, + 83380, 64028, 8146, 64026, 41788, 194844, 0, 4351, 6343, 43247, 119888, + 70153, 119886, 119891, 72387, 119889, 11433, 119895, 119896, 194655, + 7801, 65578, 83361, 12915, 43968, 3297, 9699, 83357, 1135, 83350, 83351, + 83352, 1995, 6722, 983925, 128815, 2552, 41546, 60, 68394, 8649, 41549, + 78496, 72386, 83371, 6682, 83365, 78679, 43833, 41547, 983630, 2013, + 83362, 78530, 78532, 78528, 78529, 12832, 78493, 8081, 8362, 3537, + 119908, 9137, 7155, 8999, 917901, 78533, 3466, 0, 121466, 1996, 0, 3453, + 6282, 0, 2002, 2000, 120175, 537, 92976, 4179, 65119, 1998, 120746, 1842, + 0, 92674, 9628, 68446, 12081, 9826, 64502, 1767, 0, 983248, 120001, + 120201, 983646, 124975, 127952, 3059, 44024, 120204, 43491, 92693, 0, + 121472, 92452, 4100, 920, 1811, 1355, 43189, 0, 3592, 10078, 0, 78162, + 119558, 8592, 65870, 66417, 74504, 10742, 72400, 42918, 1994, 9281, 3296, + 12865, 1997, 1895, }; #define code_magic 47 @@ -19839,7 +23265,7 @@ static unsigned int code_hash[] = { #define code_poly 32771 static const unsigned int aliases_start = 0xf0000; -static const unsigned int aliases_end = 0xf01c9; +static const unsigned int aliases_end = 0xf01cb; static const unsigned int name_aliases[] = { 0x0000, 0x0000, @@ -20034,6 +23460,8 @@ static const unsigned int name_aliases[] = { 0x2118, 0x2448, 0x2449, + 0x2B7A, + 0x2B7C, 0xA015, 0xFE18, 0xFE00, diff --git a/Modules/winreparse.h b/Modules/winreparse.h new file mode 100644 index 000000000000..66f7775dd2e8 --- /dev/null +++ b/Modules/winreparse.h @@ -0,0 +1,53 @@ +#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 doesn't seem to be present in the Windows SDK (at least as included + with Visual Studio Express). */ +typedef struct _REPARSE_DATA_BUFFER { + 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; + }; +} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; + +#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\ + GenericReparseBuffer) +#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 ) + +#ifdef __cplusplus +} +#endif + +#endif /* MS_WINDOWS */ + +#endif /* !Py_WINREPARSE_H */ diff --git a/Modules/xxlimited.c b/Modules/xxlimited.c index 661b6e294af3..40c176063dba 100644 --- a/Modules/xxlimited.c +++ b/Modules/xxlimited.c @@ -40,11 +40,18 @@ newXxoObject(PyObject *arg) /* Xxo methods */ -static void -Xxo_dealloc(XxoObject *self) +static int +Xxo_traverse(XxoObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->x_attr); + return 0; +} + +static int +Xxo_finalize(XxoObject *self) { - Py_XDECREF(self->x_attr); - PyObject_Del(self); + Py_CLEAR(self->x_attr); + return 0; } static PyObject * @@ -102,7 +109,8 @@ Xxo_setattr(XxoObject *self, char *name, PyObject *v) static PyType_Slot Xxo_Type_slots[] = { {Py_tp_doc, "The Xxo type"}, - {Py_tp_dealloc, Xxo_dealloc}, + {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}, @@ -113,7 +121,7 @@ static PyType_Spec Xxo_Type_spec = { "xxlimited.Xxo", sizeof(XxoObject), 0, - Py_TPFLAGS_DEFAULT, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, Xxo_Type_slots }; @@ -169,7 +177,7 @@ xx_roj(PyObject *self, PyObject *args) /* ---------- */ -static PyType_Slot Str_Type_slots[] = { +static PyType_Slot Str_Type_slots[] = { {Py_tp_base, NULL}, /* filled out in module init function */ {0, 0}, }; @@ -222,25 +230,9 @@ static PyMethodDef xx_methods[] = { PyDoc_STRVAR(module_doc, "This is a template module just for instruction."); -/* Initialization function for the module (*must* be called PyInit_xx) */ - - -static struct PyModuleDef xxmodule = { - PyModuleDef_HEAD_INIT, - "xxlimited", - module_doc, - -1, - xx_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit_xxlimited(void) +static int +xx_modexec(PyObject *m) { - PyObject *m = NULL; PyObject *o; /* Due to cross platform compiler issues the slots must be filled @@ -254,11 +246,6 @@ PyInit_xxlimited(void) if (Xxo_Type == NULL) goto fail; - /* Create the module and add the functions */ - m = PyModule_Create(&xxmodule); - if (m == NULL) - goto fail; - /* Add some symbolic constants to the module */ if (ErrorObject == NULL) { ErrorObject = PyErr_NewException("xxlimited.error", NULL, NULL); @@ -268,6 +255,12 @@ PyInit_xxlimited(void) 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) @@ -279,8 +272,34 @@ PyInit_xxlimited(void) if (o == NULL) goto fail; PyModule_AddObject(m, "Null", o); - return m; + return 0; fail: Py_XDECREF(m); - return NULL; + 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/Modules/xxmodule.c b/Modules/xxmodule.c index 0feff662d539..85230d9c9766 100644 --- a/Modules/xxmodule.c +++ b/Modules/xxmodule.c @@ -334,26 +334,10 @@ static PyMethodDef xx_methods[] = { PyDoc_STRVAR(module_doc, "This is a template module just for instruction."); -/* Initialization function for the module (*must* be called PyInit_xx) */ - -static struct PyModuleDef xxmodule = { - PyModuleDef_HEAD_INIT, - "xx", - module_doc, - -1, - xx_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit_xx(void) +static int +xx_exec(PyObject *m) { - PyObject *m = NULL; - /* Due to cross platform compiler issues the slots must be filled * here. It's required for portability to Windows without requiring * C++. */ @@ -366,11 +350,6 @@ PyInit_xx(void) if (PyType_Ready(&Xxo_Type) < 0) goto fail; - /* Create the module and add the functions */ - m = PyModule_Create(&xxmodule); - if (m == NULL) - goto fail; - /* Add some symbolic constants to the module */ if (ErrorObject == NULL) { ErrorObject = PyErr_NewException("xx.error", NULL, NULL); @@ -389,8 +368,33 @@ PyInit_xx(void) if (PyType_Ready(&Null_Type) < 0) goto fail; PyModule_AddObject(m, "Null", (PyObject *)&Null_Type); - return m; + return 0; fail: Py_XDECREF(m); - return NULL; + 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/Modules/xxsubtype.c b/Modules/xxsubtype.c index 6944e377034f..8d0d6ae81493 100644 --- a/Modules/xxsubtype.c +++ b/Modules/xxsubtype.c @@ -257,53 +257,58 @@ static PyMethodDef xxsubtype_functions[] = { {NULL, NULL} /* sentinel */ }; -static struct PyModuleDef xxsubtypemodule = { - PyModuleDef_HEAD_INIT, - "xxsubtype", - xxsubtype__doc__, - -1, - xxsubtype_functions, - NULL, - NULL, - NULL, - NULL -}; - - -PyMODINIT_FUNC -PyInit_xxsubtype(void) +static int +xxsubtype_exec(PyObject* m) { - 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 NULL; + return -1; spamlist_type.tp_base = &PyList_Type; if (PyType_Ready(&spamlist_type) < 0) - return NULL; - - m = PyModule_Create(&xxsubtypemodule); - if (m == NULL) - return NULL; + return -1; if (PyType_Ready(&spamlist_type) < 0) - return NULL; + return -1; if (PyType_Ready(&spamdict_type) < 0) - return NULL; + return -1; Py_INCREF(&spamlist_type); if (PyModule_AddObject(m, "spamlist", (PyObject *) &spamlist_type) < 0) - return NULL; + return -1; Py_INCREF(&spamdict_type); if (PyModule_AddObject(m, "spamdict", (PyObject *) &spamdict_type) < 0) - return NULL; - return m; + 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/Modules/zipimport.c b/Modules/zipimport.c index 8fe919539fdf..06abb312b35f 100644 --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -20,15 +20,13 @@ _Py_IDENTIFIER(replace); /* zip_searchorder defines how we search for a module in the Zip archive: we first search for a package __init__, then for - non-package .pyc, .pyo and .py entries. The .pyc and .pyo entries + non-package .pyc, and .py entries. The .pyc entries are swapped by initzipimport() if we run in optimized mode. Also, '/' is replaced by SEP there. */ static struct st_zip_searchorder zip_searchorder[] = { {"/__init__.pyc", IS_PACKAGE | IS_BYTECODE}, - {"/__init__.pyo", IS_PACKAGE | IS_BYTECODE}, {"/__init__.py", IS_PACKAGE | IS_SOURCE}, {".pyc", IS_BYTECODE}, - {".pyo", IS_BYTECODE}, {".py", IS_SOURCE}, {"", 0} }; @@ -233,7 +231,7 @@ make_filename(PyObject *prefix, PyObject *name) Py_ssize_t len; len = PyUnicode_GET_LENGTH(prefix) + PyUnicode_GET_LENGTH(name) + 1; - p = buf = PyMem_Malloc(sizeof(Py_UCS4) * len); + p = buf = PyMem_New(Py_UCS4, len); if (buf == NULL) { PyErr_NoMemory(); return NULL; @@ -875,8 +873,12 @@ read_directory(PyObject *archive) fp = _Py_fopen_obj(archive, "rb"); if (fp == NULL) { - if (!PyErr_Occurred()) + if (PyErr_ExceptionMatches(PyExc_OSError)) { + PyObject *exc, *val, *tb; + PyErr_Fetch(&exc, &val, &tb); PyErr_Format(ZipImportError, "can't open Zip file: %R", archive); + _PyErr_ChainExceptions(exc, val, tb); + } return NULL; } @@ -939,6 +941,9 @@ read_directory(PyObject *archive) header_size = name_size + PyMarshal_ReadShortFromFile(fp) + PyMarshal_ReadShortFromFile(fp); + if (PyErr_Occurred()) + goto error; + if (fread(dummy, 1, 8, fp) != 8) /* Skip unused fields, avoid fseek */ goto file_error; file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset; @@ -1073,12 +1078,8 @@ get_data(PyObject *archive, PyObject *toc_entry) } fp = _Py_fopen_obj(archive, "rb"); - if (!fp) { - if (!PyErr_Occurred()) - PyErr_Format(PyExc_IOError, - "zipimport: can not open file %U", archive); + if (!fp) return NULL; - } /* Check to make sure the local file header is correct */ if (fseek(fp, file_offset, 0) == -1) { @@ -1315,7 +1316,7 @@ parse_dostime(int dostime, int dosdate) return mktime(&stm); } -/* Given a path to a .pyc or .pyo file in the archive, return the +/* Given a path to a .pyc file in the archive, return the modification time of the matching .py file, or 0 if no source is available. */ static time_t @@ -1478,17 +1479,6 @@ PyInit_zipimport(void) /* Correct directory separator */ zip_searchorder[0].suffix[0] = SEP; zip_searchorder[1].suffix[0] = SEP; - zip_searchorder[2].suffix[0] = SEP; - if (Py_OptimizeFlag) { - /* Reverse *.pyc and *.pyo */ - struct st_zip_searchorder tmp; - tmp = zip_searchorder[0]; - zip_searchorder[0] = zip_searchorder[1]; - zip_searchorder[1] = tmp; - tmp = zip_searchorder[3]; - zip_searchorder[3] = zip_searchorder[4]; - zip_searchorder[4] = tmp; - } mod = PyModule_Create(&zipimportmodule); if (mod == NULL) diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c index bf8c8e4d1212..1997b40d1827 100644 --- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -3,6 +3,7 @@ /* Windows users: read Python's PCbuild\readme.txt */ +#define PY_SSIZE_T_CLEAN #include "Python.h" #include "structmember.h" @@ -28,10 +29,9 @@ #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif -#define DEF_WBITS MAX_WBITS -/* The output buffer will be increased in chunks of DEFAULTALLOC bytes. */ -#define DEFAULTALLOC (16*1024) +/* Initial buffer size. */ +#define DEF_BUF_SIZE (16*1024) static PyTypeObject Comptype; static PyTypeObject Decomptype; @@ -81,42 +81,12 @@ zlib_error(z_stream zst, int err, char *msg) PyErr_Format(ZlibError, "Error %d %s: %.200s", err, msg, zmsg); } -/*[clinic] +/*[clinic input] module zlib -class zlib.Compress -class zlib.Decompress -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ - -PyDoc_STRVAR(compressobj__doc__, -"compressobj(level=-1, method=DEFLATED, wbits=15, memlevel=8,\n" -" strategy=Z_DEFAULT_STRATEGY[, zdict])\n" -" -- Return a compressor object.\n" -"\n" -"level is the compression level (an integer in the range 0-9; default is 6).\n" -"Higher compression levels are slower, but produce smaller results.\n" -"\n" -"method is the compression algorithm. If given, this must be DEFLATED.\n" -"\n" -"wbits is the base two logarithm of the window size (range: 8..15).\n" -"\n" -"memlevel controls the amount of memory used for internal compression state.\n" -"Valid values range from 1 to 9. Higher values result in higher memory usage,\n" -"faster compression, and smaller output.\n" -"\n" -"strategy is used to tune the compression algorithm. Possible values are\n" -"Z_DEFAULT_STRATEGY, Z_FILTERED, and Z_HUFFMAN_ONLY.\n" -"\n" -"zdict is the predefined compression dictionary - a sequence of bytes\n" -"containing subsequences that are likely to occur in the input data."); - -PyDoc_STRVAR(decompressobj__doc__, -"decompressobj([wbits[, zdict]]) -- Return a decompressor object.\n" -"\n" -"Optional arg wbits is the window buffer size.\n" -"\n" -"Optional arg zdict is the predefined compression dictionary. This must be\n" -"the same dictionary as used by the compressor that produced the input data."); +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) @@ -164,70 +134,21 @@ PyZlib_Free(voidpf ctx, void *ptr) PyMem_RawFree(ptr); } -/*[clinic] - +/*[clinic input] zlib.compress + bytes: Py_buffer Binary data to be compressed. - [ - level: int + level: int(c_default="Z_DEFAULT_COMPRESSION") = Z_DEFAULT_COMPRESSION Compression level, in 0-9. - ] / -Returns compressed string. - -[clinic]*/ - -PyDoc_STRVAR(zlib_compress__doc__, -"compress(bytes, [level])\n" -"Returns compressed string.\n" -"\n" -" bytes\n" -" Binary data to be compressed.\n" -" level\n" -" Compression level, in 0-9."); - -#define ZLIB_COMPRESS_METHODDEF \ - {"compress", (PyCFunction)zlib_compress, METH_VARARGS, zlib_compress__doc__}, +Returns a bytes object containing compressed data. +[clinic start generated code]*/ static PyObject * -zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int group_right_1, int level); - -static PyObject * -zlib_compress(PyModuleDef *module, PyObject *args) -{ - PyObject *return_value = NULL; - Py_buffer bytes; - int group_right_1 = 0; - int level = 0; - - switch (PyTuple_Size(args)) { - case 1: - if (!PyArg_ParseTuple(args, "y*:compress", &bytes)) - return NULL; - break; - case 2: - if (!PyArg_ParseTuple(args, "y*i:compress", &bytes, &level)) - return NULL; - group_right_1 = 1; - break; - default: - PyErr_SetString(PyExc_TypeError, "zlib.compress requires 1 to 2 arguments"); - return NULL; - } - return_value = zlib_compress_impl(module, &bytes, group_right_1, level); - - /* Cleanup for bytes */ - if (bytes.buf) - PyBuffer_Release(&bytes); - - return return_value; -} - -static PyObject * -zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int group_right_1, int level) -/*[clinic checksum: f490708eff84be652b5ebe7fe622ab73ac12c888]*/ +zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int level) +/*[clinic end generated code: output=5d7dd4588788efd3 input=be3abe9934bda4b3]*/ { PyObject *ReturnVal = NULL; Byte *input, *output = NULL; @@ -235,9 +156,6 @@ zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int group_right_1, int int err; z_stream zst; - if (!group_right_1) - level = Z_DEFAULT_COMPRESSION; - if ((size_t)bytes->len > UINT_MAX) { PyErr_SetString(PyExc_OverflowError, "Size does not fit in an unsigned int"); @@ -306,17 +224,15 @@ zlib_compress_impl(PyModuleDef *module, Py_buffer *bytes, int group_right_1, int return ReturnVal; } -/*[python] +/*[python input] class uint_converter(CConverter): type = 'unsigned int' converter = 'uint_converter' + c_ignored_default = "0" -class compobject_converter(self_converter): - type = "compobject *" - -[python]*/ -/*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=22263855f7a3ebfd]*/ static int uint_converter(PyObject *obj, void *ptr) @@ -329,11 +245,6 @@ uint_converter(PyObject *obj, void *ptr) 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; - } } else { if (val < 0) { @@ -344,39 +255,49 @@ uint_converter(PyObject *obj, void *ptr) uval = (unsigned long)val; } + 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; } -PyDoc_STRVAR(decompress__doc__, -"decompress(string[, wbits[, bufsize]]) -- Return decompressed string.\n" -"\n" -"Optional arg wbits is the window buffer size. Optional arg bufsize is\n" -"the initial output buffer size."); +/*[clinic input] +zlib.decompress + + data: Py_buffer + Compressed data. + wbits: int(c_default="MAX_WBITS") = MAX_WBITS + The window buffer size. + bufsize: uint(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 * -PyZlib_decompress(PyObject *self, PyObject *args) +zlib_decompress_impl(PyModuleDef *module, Py_buffer *data, int wbits, + unsigned int bufsize) +/*[clinic end generated code: output=444d0987f3429574 input=0f4b9abb7103f50e]*/ { PyObject *result_str = NULL; - Py_buffer pinput; Byte *input; unsigned int length; int err; - int wsize=DEF_WBITS; - unsigned int bufsize = DEFAULTALLOC, new_bufsize; + unsigned int new_bufsize; z_stream zst; - if (!PyArg_ParseTuple(args, "y*|iO&:decompress", - &pinput, &wsize, uint_converter, &bufsize)) - return NULL; - - if ((size_t)pinput.len > UINT_MAX) { + if ((size_t)data->len > UINT_MAX) { PyErr_SetString(PyExc_OverflowError, "Size does not fit in an unsigned int"); goto error; } - input = pinput.buf; - length = (unsigned int)pinput.len; + input = data->buf; + length = (unsigned int)data->len; if (bufsize == 0) bufsize = 1; @@ -392,7 +313,7 @@ PyZlib_decompress(PyObject *self, PyObject *args) zst.zfree = PyZlib_Free; zst.next_out = (Byte *)PyBytes_AS_STRING(result_str); zst.next_in = (Byte *)input; - err = inflateInit2(&zst, wsize); + err = inflateInit2(&zst, wbits); switch(err) { case(Z_OK): @@ -458,32 +379,46 @@ PyZlib_decompress(PyObject *self, PyObject *args) if (_PyBytes_Resize(&result_str, zst.total_out) < 0) goto error; - PyBuffer_Release(&pinput); return result_str; error: - PyBuffer_Release(&pinput); Py_XDECREF(result_str); 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; default is 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 + The base two logarithm of the window size (range: 8..15). + 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 * -PyZlib_compressobj(PyObject *selfptr, PyObject *args, PyObject *kwargs) +zlib_compressobj_impl(PyModuleDef *module, int level, int method, int wbits, + int memLevel, int strategy, Py_buffer *zdict) +/*[clinic end generated code: output=2949bbb9a5723ccd input=b034847f8821f6af]*/ { compobject *self = NULL; - int level=Z_DEFAULT_COMPRESSION, method=DEFLATED; - int wbits=MAX_WBITS, memLevel=DEF_MEM_LEVEL, strategy=0, err; - Py_buffer zdict; - static char *kwlist[] = {"level", "method", "wbits", - "memLevel", "strategy", "zdict", NULL}; - - zdict.buf = NULL; /* Sentinel, so we can tell whether zdict was supplied. */ - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iiiiiy*:compressobj", - kwlist, &level, &method, &wbits, - &memLevel, &strategy, &zdict)) - return NULL; + int err; - if (zdict.buf != NULL && (size_t)zdict.len > UINT_MAX) { + 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; @@ -501,11 +436,11 @@ PyZlib_compressobj(PyObject *selfptr, PyObject *args, PyObject *kwargs) switch(err) { case (Z_OK): self->is_initialised = 1; - if (zdict.buf == NULL) { + if (zdict->buf == NULL) { goto success; } else { err = deflateSetDictionary(&self->zst, - zdict.buf, (unsigned int)zdict.len); + zdict->buf, (unsigned int)zdict->len); switch (err) { case (Z_OK): goto success; @@ -530,25 +465,30 @@ PyZlib_compressobj(PyObject *selfptr, PyObject *args, PyObject *kwargs) } error: - Py_XDECREF(self); - self = NULL; + Py_CLEAR(self); success: - if (zdict.buf != NULL) - PyBuffer_Release(&zdict); return (PyObject*)self; } +/*[clinic input] +zlib.decompressobj + + wbits: int(c_default="MAX_WBITS") = MAX_WBITS + The window buffer size. + 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 * -PyZlib_decompressobj(PyObject *selfptr, PyObject *args, PyObject *kwargs) +zlib_decompressobj_impl(PyModuleDef *module, int wbits, PyObject *zdict) +/*[clinic end generated code: output=8ccd583fbd631798 input=67f05145a6920127]*/ { - static char *kwlist[] = {"wbits", "zdict", NULL}; - int wbits=DEF_WBITS, err; + int err; compobject *self; - PyObject *zdict=NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iO:decompressobj", - kwlist, &wbits, &zdict)) - return NULL; if (zdict != NULL && !PyObject_CheckBuffer(zdict)) { PyErr_SetString(PyExc_TypeError, "zdict argument must support the buffer protocol"); @@ -616,37 +556,41 @@ Decomp_dealloc(compobject *self) Dealloc(self); } -PyDoc_STRVAR(comp_compress__doc__, -"compress(data) -- Return a string containing data 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."); +/*[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 * -PyZlib_objcompress(compobject *self, PyObject *args) +zlib_Compress_compress_impl(compobject *self, Py_buffer *data) +/*[clinic end generated code: output=5d5cd791cbc6a7f4 input=0d95908d6e64fab8]*/ { int err; unsigned int inplen; - unsigned int length = DEFAULTALLOC, new_length; - PyObject *RetVal = NULL; - Py_buffer pinput; + unsigned int length = DEF_BUF_SIZE, new_length; + PyObject *RetVal; Byte *input; unsigned long start_total_out; - if (!PyArg_ParseTuple(args, "y*:compress", &pinput)) - return NULL; - if ((size_t)pinput.len > UINT_MAX) { + if ((size_t)data->len > UINT_MAX) { PyErr_SetString(PyExc_OverflowError, "Size does not fit in an unsigned int"); - goto error_outer; + return NULL; } - input = pinput.buf; - inplen = (unsigned int)pinput.len; + input = data->buf; + inplen = (unsigned int)data->len; if (!(RetVal = PyBytes_FromStringAndSize(NULL, length))) - goto error_outer; + return NULL; ENTER_ZLIB(self); @@ -669,7 +613,7 @@ PyZlib_objcompress(compobject *self, PyObject *args) new_length = UINT_MAX; if (_PyBytes_Resize(&RetVal, new_length) < 0) { Py_CLEAR(RetVal); - goto error; + goto done; } self->zst.next_out = (unsigned char *)PyBytes_AS_STRING(RetVal) + length; @@ -687,18 +631,15 @@ PyZlib_objcompress(compobject *self, PyObject *args) if (err != Z_OK && err != Z_BUF_ERROR) { zlib_error(self->zst, err, "while compressing data"); - Py_DECREF(RetVal); - RetVal = NULL; - goto error; + Py_CLEAR(RetVal); + goto done; } if (_PyBytes_Resize(&RetVal, self->zst.total_out - start_total_out) < 0) { Py_CLEAR(RetVal); } - error: + done: LEAVE_ZLIB(self); - error_outer: - PyBuffer_Release(&pinput); return RetVal; } @@ -745,12 +686,9 @@ save_unconsumed_input(compobject *self, int err) return 0; } -/*[clinic] - +/*[clinic input] zlib.Decompress.decompress - self: compobject - data: Py_buffer The binary data to decompress. max_length: uint = 0 @@ -759,61 +697,20 @@ zlib.Decompress.decompress the unconsumed_tail attribute. / -Return a string containing the decompressed version of the data. +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]*/ - -PyDoc_STRVAR(zlib_Decompress_decompress__doc__, -"decompress(data, max_length=0)\n" -"Return a string 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)zlib_Decompress_decompress, METH_VARARGS, zlib_Decompress_decompress__doc__}, - -static PyObject * -zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int max_length); +[clinic start generated code]*/ static PyObject * -zlib_Decompress_decompress(PyObject *self, PyObject *args) -{ - PyObject *return_value = NULL; - Py_buffer data; - unsigned int max_length = 0; - - if (!PyArg_ParseTuple(args, - "y*|O&:decompress", - &data, uint_converter, &max_length)) - goto exit; - return_value = zlib_Decompress_decompress_impl((compobject *)self, &data, max_length); - -exit: - /* Cleanup for data */ - if (data.buf) - PyBuffer_Release(&data); - - return return_value; -} - -static PyObject * -zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int max_length) -/*[clinic checksum: 3599698948f5a712f5a8309491671cc2ce969d2c]*/ +zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, + unsigned int max_length) +/*[clinic end generated code: output=b82e2a2c19f5fe7b input=02cfc047377cec86]*/ { int err; - unsigned int old_length, length = DEFAULTALLOC; + unsigned int old_length, length = DEF_BUF_SIZE; PyObject *RetVal = NULL; unsigned long start_total_out; @@ -930,29 +827,31 @@ zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int return RetVal; } -PyDoc_STRVAR(comp_flush__doc__, -"flush( [mode] ) -- Return a string containing any remaining compressed data.\n" -"\n" -"mode can be one of the constants Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH; the\n" -"default value used when mode is not specified is Z_FINISH.\n" -"If mode == Z_FINISH, the compressor object can no longer be used after\n" -"calling the flush() method. Otherwise, more data can still be compressed."); +/*[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 * -PyZlib_flush(compobject *self, PyObject *args) +zlib_Compress_flush_impl(compobject *self, int mode) +/*[clinic end generated code: output=a203f4cefc9de727 input=73ed066794bd15bc]*/ { int err; - unsigned int length = DEFAULTALLOC, new_length; + unsigned int length = DEF_BUF_SIZE, new_length; PyObject *RetVal; - int flushmode = Z_FINISH; unsigned long start_total_out; - if (!PyArg_ParseTuple(args, "|i:flush", &flushmode)) - return 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 (flushmode == Z_NO_FLUSH) { + if (mode == Z_NO_FLUSH) { return PyBytes_FromStringAndSize(NULL, 0); } @@ -967,7 +866,7 @@ PyZlib_flush(compobject *self, PyObject *args) self->zst.next_out = (unsigned char *)PyBytes_AS_STRING(RetVal); Py_BEGIN_ALLOW_THREADS - err = deflate(&(self->zst), flushmode); + err = deflate(&(self->zst), mode); Py_END_ALLOW_THREADS /* while Z_OK and the output buffer is full, there might be more output, @@ -987,14 +886,14 @@ PyZlib_flush(compobject *self, PyObject *args) length = new_length; Py_BEGIN_ALLOW_THREADS - err = deflate(&(self->zst), flushmode); + err = deflate(&(self->zst), mode); Py_END_ALLOW_THREADS } - /* If flushmode is Z_FINISH, we also have to call deflateEnd() to free + /* 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 - flushmode is Z_FINISH, but checking both for safety*/ - if (err == Z_STREAM_END && flushmode == Z_FINISH) { + 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"); @@ -1028,24 +927,15 @@ PyZlib_flush(compobject *self, PyObject *args) #ifdef HAVE_ZLIB_COPY -/*[clinic] +/*[clinic input] zlib.Compress.copy - self: compobject - Return a copy of the compression object. -[clinic]*/ - -PyDoc_STRVAR(zlib_Compress_copy__doc__, -"copy()\n" -"Return a copy of the compression object."); - -#define ZLIB_COMPRESS_COPY_METHODDEF \ - {"copy", (PyCFunction)zlib_Compress_copy, METH_NOARGS, zlib_Compress_copy__doc__}, +[clinic start generated code]*/ static PyObject * -zlib_Compress_copy(compobject *self) -/*[clinic checksum: 0b37c07f8f27deb7d4769951fbecf600a1006ef8]*/ +zlib_Compress_copy_impl(compobject *self) +/*[clinic end generated code: output=5144aa153c21e805 input=c656351f94b82718]*/ { compobject *retval = NULL; int err; @@ -1095,11 +985,15 @@ zlib_Compress_copy(compobject *self) return NULL; } -PyDoc_STRVAR(decomp_copy__doc__, -"copy() -- Return a copy of the decompression object."); +/*[clinic input] +zlib.Decompress.copy + +Return a copy of the decompression object. +[clinic start generated code]*/ static PyObject * -PyZlib_uncopy(compobject *self) +zlib_Decompress_copy_impl(compobject *self) +/*[clinic end generated code: output=02a883a2a510c8cc input=ba6c3e96712a596b]*/ { compobject *retval = NULL; int err; @@ -1151,24 +1045,26 @@ PyZlib_uncopy(compobject *self) } #endif -PyDoc_STRVAR(decomp_flush__doc__, -"flush( [length] ) -- Return a string containing any remaining\n" -"decompressed data. length, if given, is the initial size of the\n" -"output buffer.\n" -"\n" -"The decompressor object can no longer be used after this call."); +/*[clinic input] +zlib.Decompress.flush + + length: uint(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 * -PyZlib_unflush(compobject *self, PyObject *args) +zlib_Decompress_flush_impl(compobject *self, unsigned int length) +/*[clinic end generated code: output=db6fb753ab698e22 input=1580956505978993]*/ { int err; - unsigned int length = DEFAULTALLOC, new_length; + unsigned int new_length; PyObject * retval = NULL; unsigned long start_total_out; Py_ssize_t size; - if (!PyArg_ParseTuple(args, "|O&:flush", uint_converter, &length)) - return NULL; if (length == 0) { PyErr_SetString(PyExc_ValueError, "length must be greater than zero"); return NULL; @@ -1244,12 +1140,12 @@ PyZlib_unflush(compobject *self, PyObject *args) return retval; } +#include "clinic/zlibmodule.c.h" + static PyMethodDef comp_methods[] = { - {"compress", (binaryfunc)PyZlib_objcompress, METH_VARARGS, - comp_compress__doc__}, - {"flush", (binaryfunc)PyZlib_flush, METH_VARARGS, - comp_flush__doc__}, + ZLIB_COMPRESS_COMPRESS_METHODDEF + ZLIB_COMPRESS_FLUSH_METHODDEF #ifdef HAVE_ZLIB_COPY ZLIB_COMPRESS_COPY_METHODDEF #endif @@ -1259,11 +1155,9 @@ static PyMethodDef comp_methods[] = static PyMethodDef Decomp_methods[] = { ZLIB_DECOMPRESS_DECOMPRESS_METHODDEF - {"flush", (binaryfunc)PyZlib_unflush, METH_VARARGS, - decomp_flush__doc__}, + ZLIB_DECOMPRESS_FLUSH_METHODDEF #ifdef HAVE_ZLIB_COPY - {"copy", (PyCFunction)PyZlib_uncopy, METH_NOARGS, - decomp_copy__doc__}, + ZLIB_DECOMPRESS_COPY_METHODDEF #endif {NULL, NULL} }; @@ -1276,95 +1170,95 @@ static PyMemberDef Decomp_members[] = { {NULL}, }; -PyDoc_STRVAR(adler32__doc__, -"adler32(string[, start]) -- Compute an Adler-32 checksum of string.\n" -"\n" -"An optional starting value can be specified. The returned checksum is\n" -"an integer."); +/*[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 * -PyZlib_adler32(PyObject *self, PyObject *args) +zlib_adler32_impl(PyModuleDef *module, Py_buffer *data, unsigned int value) +/*[clinic end generated code: output=51d6d75ee655c78a input=6ff4557872160e88]*/ { - unsigned int adler32val = 1; /* adler32(0L, Z_NULL, 0) */ - Py_buffer pbuf; - - if (!PyArg_ParseTuple(args, "y*|I:adler32", &pbuf, &adler32val)) - return NULL; /* Releasing the GIL for very small buffers is inefficient and may lower performance */ - if (pbuf.len > 1024*5) { - unsigned char *buf = pbuf.buf; - Py_ssize_t len = pbuf.len; + 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) { - adler32val = adler32(adler32val, buf, UINT_MAX); + value = adler32(value, buf, UINT_MAX); buf += (size_t) UINT_MAX; len -= (size_t) UINT_MAX; } - adler32val = adler32(adler32val, buf, (unsigned int)len); + value = adler32(value, buf, (unsigned int)len); Py_END_ALLOW_THREADS } else { - adler32val = adler32(adler32val, pbuf.buf, (unsigned int)pbuf.len); + value = adler32(value, data->buf, (unsigned int)data->len); } - PyBuffer_Release(&pbuf); - return PyLong_FromUnsignedLong(adler32val & 0xffffffffU); + return PyLong_FromUnsignedLong(value & 0xffffffffU); } -PyDoc_STRVAR(crc32__doc__, -"crc32(string[, start]) -- Compute a CRC-32 checksum of string.\n" -"\n" -"An optional starting value can be specified. The returned checksum is\n" -"an integer."); +/*[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 * -PyZlib_crc32(PyObject *self, PyObject *args) +zlib_crc32_impl(PyModuleDef *module, Py_buffer *data, unsigned int value) +/*[clinic end generated code: output=c1e986e74fe7b623 input=26c3ed430fa00b4c]*/ { - unsigned int crc32val = 0; /* crc32(0L, Z_NULL, 0) */ - Py_buffer pbuf; int signed_val; - if (!PyArg_ParseTuple(args, "y*|I:crc32", &pbuf, &crc32val)) - return NULL; /* Releasing the GIL for very small buffers is inefficient and may lower performance */ - if (pbuf.len > 1024*5) { - unsigned char *buf = pbuf.buf; - Py_ssize_t len = pbuf.len; + 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) { - crc32val = crc32(crc32val, buf, UINT_MAX); + value = crc32(value, buf, UINT_MAX); buf += (size_t) UINT_MAX; len -= (size_t) UINT_MAX; } - signed_val = crc32(crc32val, buf, (unsigned int)len); + signed_val = crc32(value, buf, (unsigned int)len); Py_END_ALLOW_THREADS } else { - signed_val = crc32(crc32val, pbuf.buf, (unsigned int)pbuf.len); + signed_val = crc32(value, data->buf, (unsigned int)data->len); } - PyBuffer_Release(&pbuf); return PyLong_FromUnsignedLong(signed_val & 0xffffffffU); } static PyMethodDef zlib_methods[] = { - {"adler32", (PyCFunction)PyZlib_adler32, METH_VARARGS, - adler32__doc__}, + ZLIB_ADLER32_METHODDEF ZLIB_COMPRESS_METHODDEF - {"compressobj", (PyCFunction)PyZlib_compressobj, METH_VARARGS|METH_KEYWORDS, - compressobj__doc__}, - {"crc32", (PyCFunction)PyZlib_crc32, METH_VARARGS, - crc32__doc__}, - {"decompress", (PyCFunction)PyZlib_decompress, METH_VARARGS, - decompress__doc__}, - {"decompressobj", (PyCFunction)PyZlib_decompressobj, METH_VARARGS|METH_KEYWORDS, - decompressobj__doc__}, + ZLIB_COMPRESSOBJ_METHODDEF + ZLIB_CRC32_METHODDEF + ZLIB_DECOMPRESS_METHODDEF + ZLIB_DECOMPRESSOBJ_METHODDEF {NULL, NULL} }; @@ -1478,6 +1372,7 @@ PyInit_zlib(void) PyModule_AddIntMacro(m, MAX_WBITS); PyModule_AddIntMacro(m, DEFLATED); PyModule_AddIntMacro(m, DEF_MEM_LEVEL); + PyModule_AddIntMacro(m, DEF_BUF_SIZE); PyModule_AddIntMacro(m, Z_BEST_SPEED); PyModule_AddIntMacro(m, Z_BEST_COMPRESSION); PyModule_AddIntMacro(m, Z_DEFAULT_COMPRESSION); diff --git a/Objects/README b/Objects/README new file mode 100644 index 000000000000..854b103f7bd6 --- /dev/null +++ b/Objects/README @@ -0,0 +1 @@ +Source files for various builtin objects diff --git a/Objects/abstract.c b/Objects/abstract.c index 91df5da65579..039a4ca052c3 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -250,28 +250,7 @@ PyObject_AsCharBuffer(PyObject *obj, const char **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) { - PyErr_SetString(PyExc_TypeError, - "expected bytes, bytearray " - "or buffer compatible object"); - return -1; - } - if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE)) return -1; - - *buffer = view.buf; - *buffer_len = view.len; - if (pb->bf_releasebuffer != NULL) - (*pb->bf_releasebuffer)(obj, &view); - Py_XDECREF(view.obj); - return 0; + return PyObject_AsReadBuffer(obj, (const void **)buffer, buffer_len); } int @@ -295,28 +274,18 @@ int PyObject_AsReadBuffer(PyObject *obj, const 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) { - PyErr_SetString(PyExc_TypeError, - "expected an object with a buffer interface"); + if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) != 0) return -1; - } - - if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE)) return -1; *buffer = view.buf; *buffer_len = view.len; - if (pb->bf_releasebuffer != NULL) - (*pb->bf_releasebuffer)(obj, &view); - Py_XDECREF(view.obj); + PyBuffer_Release(&view); return 0; } @@ -336,15 +305,13 @@ int PyObject_AsWriteBuffer(PyObject *obj, pb->bf_getbuffer == NULL || ((*pb->bf_getbuffer)(obj, &view, PyBUF_WRITABLE) != 0)) { PyErr_SetString(PyExc_TypeError, - "expected an object with a writable buffer interface"); + "expected a writable bytes-like object"); return -1; } *buffer = view.buf; *buffer_len = view.len; - if (pb->bf_releasebuffer != NULL) - (*pb->bf_releasebuffer)(obj, &view); - Py_XDECREF(view.obj); + PyBuffer_Release(&view); return 0; } @@ -353,13 +320,15 @@ int PyObject_AsWriteBuffer(PyObject *obj, int PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags) { - if (!PyObject_CheckBuffer(obj)) { + PyBufferProcs *pb = obj->ob_type->tp_as_buffer; + + if (pb == NULL || pb->bf_getbuffer == NULL) { PyErr_Format(PyExc_TypeError, - "'%.100s' does not support the buffer interface", + "a bytes-like object is required, not '%.100s'", Py_TYPE(obj)->tp_name); return -1; } - return (*(obj->ob_type->tp_as_buffer->bf_getbuffer))(obj, view, flags); + return (*pb->bf_getbuffer)(obj, view, flags); } static int @@ -368,16 +337,35 @@ _IsFortranContiguous(const Py_buffer *view) Py_ssize_t sd, dim; int i; - if (view->ndim == 0) return 1; - if (view->strides == NULL) return (view->ndim == 1); + /* 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; - if (view->ndim == 1) return (view->shape[0] == 1 || - sd == view->strides[0]); for (i=0; indim; i++) { dim = view->shape[i]; - if (dim == 0) return 1; - if (view->strides[i] != sd) return 0; + if (dim > 1 && view->strides[i] != sd) { + return 0; + } sd *= dim; } return 1; @@ -389,16 +377,22 @@ _IsCContiguous(const Py_buffer *view) Py_ssize_t sd, dim; int i; - if (view->ndim == 0) return 1; - if (view->strides == NULL) return 1; + /* 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; - if (view->ndim == 1) return (view->shape[0] == 1 || - sd == view->strides[0]); for (i=view->ndim-1; i>=0; i--) { dim = view->shape[i]; - if (dim == 0) return 1; - if (view->strides[i] != sd) return 0; + if (dim > 1 && view->strides[i] != sd) { + return 0; + } sd *= dim; } return 1; @@ -488,7 +482,7 @@ PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort) /* Otherwise a more elaborate scheme is needed */ - /* XXX(nnorwitz): need to check for overflow! */ + /* view->ndim <= 64 */ indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*(view->ndim)); if (indices == NULL) { PyErr_NoMemory(); @@ -510,10 +504,10 @@ PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort) */ elements = len / view->itemsize; while (elements--) { - addone(view->ndim, indices, view->shape); ptr = PyBuffer_GetPointer(view, indices); memcpy(ptr, src, view->itemsize); src += view->itemsize; + addone(view->ndim, indices, view->shape); } PyMem_Free(indices); @@ -530,8 +524,8 @@ int PyObject_CopyData(PyObject *dest, PyObject *src) if (!PyObject_CheckBuffer(dest) || !PyObject_CheckBuffer(src)) { PyErr_SetString(PyExc_TypeError, - "both destination and source must have the "\ - "buffer interface"); + "both destination and source must be "\ + "bytes-like objects"); return -1; } @@ -618,7 +612,12 @@ int PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len, int readonly, int flags) { - if (view == NULL) return 0; /* XXX why not -1? */ + 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, @@ -652,10 +651,14 @@ void PyBuffer_Release(Py_buffer *view) { PyObject *obj = view->obj; - if (obj && Py_TYPE(obj)->tp_as_buffer && Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer) - Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer(obj, view); - Py_XDECREF(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 * @@ -687,8 +690,9 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) Py_DECREF(meth); if (result && !PyUnicode_Check(result)) { - PyErr_SetString(PyExc_TypeError, - "__format__ method did not return string"); + PyErr_Format(PyExc_TypeError, + "__format__ must return a str, not %.200s", + Py_TYPE(result)->tp_name); Py_DECREF(result); result = NULL; goto done; @@ -931,6 +935,12 @@ PyNumber_Multiply(PyObject *v, PyObject *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) { @@ -1012,6 +1022,7 @@ 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) @@ -1077,6 +1088,13 @@ PyNumber_InPlaceMultiply(PyObject *v, PyObject *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) { @@ -1155,7 +1173,7 @@ PyNumber_Absolute(PyObject *o) return type_error("bad operand type for abs(): '%.200s'", o); } -/* Return a Python int from the object item +/* 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. */ @@ -1169,21 +1187,30 @@ PyNumber_Index(PyObject *item) Py_INCREF(item); return item; } - if (PyIndex_Check(item)) { - result = item->ob_type->tp_as_number->nb_index(item); - if (result && !PyLong_Check(result)) { - PyErr_Format(PyExc_TypeError, - "__index__ returned non-int " - "(type %.200s)", - result->ob_type->tp_name); - Py_DECREF(result); - return NULL; - } - } - else { + 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; } @@ -1235,41 +1262,12 @@ PyNumber_AsSsize_t(PyObject *item, PyObject *err) } -/* - Returns the Integral instance converted to an int. The instance is expected - to be an int or have an __int__ method. Steals integral's - reference. error_format will be used to create the TypeError if integral - isn't actually an Integral instance. error_format should be a format string - that can accept a char* naming integral's type. -*/ -static PyObject * -convert_integral_to_int(PyObject *integral, const char *error_format) -{ - PyNumberMethods *nb; - if (PyLong_Check(integral)) - return integral; - nb = Py_TYPE(integral)->tp_as_number; - if (nb->nb_int) { - PyObject *as_int = nb->nb_int(integral); - if (!as_int || PyLong_Check(as_int)) { - Py_DECREF(integral); - return as_int; - } - Py_DECREF(as_int); - } - PyErr_Format(PyExc_TypeError, error_format, Py_TYPE(integral)->tp_name); - Py_DECREF(integral); - return NULL; -} - - PyObject * PyNumber_Long(PyObject *o) { PyNumberMethods *m; PyObject *trunc_func; - const char *buffer; - Py_ssize_t buffer_len; + Py_buffer view; _Py_IDENTIFIER(__trunc__); if (o == NULL) @@ -1280,49 +1278,49 @@ PyNumber_Long(PyObject *o) } m = o->ob_type->tp_as_number; if (m && m->nb_int) { /* This should include subclasses of int */ - PyObject *res = m->nb_int(o); - if (res && !PyLong_Check(res)) { - PyErr_Format(PyExc_TypeError, - "__int__ returned non-int (type %.200s)", - res->ob_type->tp_name); - Py_DECREF(res); - return NULL; - } - return res; + return (PyObject *)_PyLong_FromNbInt(o); } - if (PyLong_Check(o)) /* An int subclass without nb_int */ - return _PyLong_Copy((PyLongObject *)o); trunc_func = _PyObject_LookupSpecial(o, &PyId___trunc__); if (trunc_func) { PyObject *truncated = PyEval_CallObject(trunc_func, NULL); PyObject *int_instance; Py_DECREF(trunc_func); - if (truncated == NULL) - return NULL; + if (truncated == NULL || PyLong_Check(truncated)) + return truncated; /* __trunc__ is specified to return an Integral type, but int() needs to return a int. */ - int_instance = convert_integral_to_int(truncated, - "__trunc__ returned non-Integral (type %.200s)"); + m = truncated->ob_type->tp_as_number; + if (m == NULL || m->nb_int == NULL) { + PyErr_Format( + PyExc_TypeError, + "__trunc__ returned non-Integral (type %.200s)", + truncated->ob_type->tp_name); + Py_DECREF(truncated); + return NULL; + } + int_instance = (PyObject *)_PyLong_FromNbInt(truncated); + Py_DECREF(truncated); return int_instance; } if (PyErr_Occurred()) return NULL; - if (PyBytes_Check(o)) + if (PyUnicode_Check(o)) + /* The below check is done in PyLong_FromUnicode(). */ + return PyLong_FromUnicodeObject(o, 10); + + if (PyObject_GetBuffer(o, &view, PyBUF_SIMPLE) == 0) { /* 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 (PyUnicode_Check(o)) - /* The above check is done in PyLong_FromUnicode(). */ - return PyLong_FromUnicodeObject(o, 10); - if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len)) - return _PyLong_FromBytes(buffer, buffer_len, 10); + PyObject *result = _PyLong_FromBytes(view.buf, view.len, 10); + PyBuffer_Release(&view); + return result; + } - return type_error("int() argument must be a string or a " - "number, not '%.200s'", o); + return type_error("int() argument must be a string, a bytes-like object " + "or a number, not '%.200s'", o); } PyObject * @@ -1683,7 +1681,7 @@ PySequence_Tuple(PyObject *v) Py_INCREF(v); return v; } - if (PyList_Check(v)) + if (PyList_CheckExact(v)) return PyList_AsTuple(v); /* Get iterator. */ @@ -2075,31 +2073,82 @@ PyObject_CallObject(PyObject *o, PyObject *a) return PyEval_CallObjectWithKeywords(o, a, NULL); } -PyObject * -PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) +PyObject* +_Py_CheckFunctionResult(PyObject *func, PyObject *result, const char *where) { - ternaryfunc call; + int err_occurred = (PyErr_Occurred() != NULL); - if ((call = func->ob_type->tp_call) != NULL) { - PyObject *result; - if (Py_EnterRecursiveCall(" while calling a Python object")) + assert((func != NULL) ^ (where != NULL)); + + if (result == NULL) { + if (!err_occurred) { + if (func) + PyErr_Format(PyExc_SystemError, + "%R returned NULL without setting an error", + func); + else + PyErr_Format(PyExc_SystemError, + "%s returned NULL without setting an error", + where); +#ifdef Py_DEBUG + /* Ensure that the bug is catched in debug mode */ + Py_FatalError("a function returned NULL without setting an error"); +#endif return NULL; - result = (*call)(func, arg, kw); - Py_LeaveRecursiveCall(); -#ifdef NDEBUG - if (result == NULL && !PyErr_Occurred()) { - PyErr_SetString( - PyExc_SystemError, - "NULL result without error in PyObject_Call"); } -#else - assert(result != NULL || PyErr_Occurred()); + } + else { + if (err_occurred) { + PyObject *exc, *val, *tb; + PyErr_Fetch(&exc, &val, &tb); + + Py_DECREF(result); + + if (func) + PyErr_Format(PyExc_SystemError, + "%R returned a result with an error set", + func); + else + PyErr_Format(PyExc_SystemError, + "%s returned a result with an error set", + where); + _PyErr_ChainExceptions(exc, val, tb); +#ifdef Py_DEBUG + /* Ensure that the bug is catched in debug mode */ + Py_FatalError("a function returned a result with an error set"); #endif - return result; + return NULL; + } } - PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable", - func->ob_type->tp_name); - return NULL; + return result; +} + +PyObject * +PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) +{ + ternaryfunc call; + PyObject *result; + + /* PyObject_Call() must not be called with an exception set, + because it may clear it (directly or indirectly) and so the + caller loses its exception */ + assert(!PyErr_Occurred()); + + call = func->ob_type->tp_call; + if (call == NULL) { + PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable", + func->ob_type->tp_name); + return NULL; + } + + if (Py_EnterRecursiveCall(" while calling a Python object")) + return NULL; + + result = (*call)(func, arg, kw); + + Py_LeaveRecursiveCall(); + + return _Py_CheckFunctionResult(func, result, NULL); } static PyObject* @@ -2210,9 +2259,8 @@ PyObject_CallMethod(PyObject *o, const char *name, const char *format, ...) return null_error(); func = PyObject_GetAttrString(o, name); - if (func == NULL) { - return 0; - } + if (func == NULL) + return NULL; va_start(va, format); retval = callmethod(func, format, va, 0); @@ -2232,9 +2280,8 @@ _PyObject_CallMethodId(PyObject *o, _Py_Identifier *name, return null_error(); func = _PyObject_GetAttrId(o, name); - if (func == NULL) { - return 0; - } + if (func == NULL) + return NULL; va_start(va, format); retval = callmethod(func, format, va, 0); @@ -2254,9 +2301,8 @@ _PyObject_CallMethod_SizeT(PyObject *o, const char *name, return null_error(); func = PyObject_GetAttrString(o, name); - if (func == NULL) { - return 0; - } + if (func == NULL) + return NULL; va_start(va, format); retval = callmethod(func, format, va, 1); va_end(va); @@ -2541,6 +2587,11 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls) 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; @@ -2579,6 +2630,7 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls) } else if (PyErr_Occurred()) return -1; + /* Probably never reached anymore. */ return recursive_isinstance(inst, cls); } @@ -2606,6 +2658,14 @@ 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; @@ -2644,6 +2704,7 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls) } else if (PyErr_Occurred()) return -1; + /* Probably never reached anymore. */ return recursive_issubclass(derived, cls); } diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 31cc4ccebdc3..21031479b8b8 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -4,6 +4,13 @@ #include "Python.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[] = ""; @@ -54,18 +61,17 @@ _getbytevalue(PyObject* arg, int *value) static int bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags) { - int ret; void *ptr; if (view == NULL) { - obj->ob_exports++; - return 0; + PyErr_SetString(PyExc_BufferError, + "bytearray_getbuffer: view==NULL argument is obsolete"); + return -1; } ptr = (void *) PyByteArray_AS_STRING(obj); - ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags); - if (ret >= 0) { - obj->ob_exports++; - } - return ret; + /* 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 @@ -74,24 +80,6 @@ bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view) obj->ob_exports--; } -static Py_ssize_t -_getbuffer(PyObject *obj, Py_buffer *view) -{ - PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer; - - if (buffer == NULL || buffer->bf_getbuffer == NULL) - { - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't support the buffer API", - Py_TYPE(obj)->tp_name); - return -1; - } - - if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0) - return -1; - return view->len; -} - static int _canresize(PyByteArrayObject *self) { @@ -103,6 +91,8 @@ _canresize(PyByteArrayObject *self) return 1; } +#include "clinic/bytearrayobject.c.h" + /* Direct API functions */ PyObject * @@ -175,27 +165,29 @@ PyByteArray_AsString(PyObject *self) } int -PyByteArray_Resize(PyObject *self, Py_ssize_t size) +PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size) { void *sval; PyByteArrayObject *obj = ((PyByteArrayObject *)self); - Py_ssize_t alloc = obj->ob_alloc; - Py_ssize_t logical_offset = obj->ob_start - obj->ob_bytes; + /* 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(size >= 0); - assert(logical_offset >= 0); assert(logical_offset <= alloc); + assert(requested_size >= 0); - if (size == Py_SIZE(self)) { + if (requested_size == Py_SIZE(self)) { return 0; } if (!_canresize(obj)) { return -1; } - if (size + logical_offset + 1 < alloc) { + if (size + logical_offset + 1 <= alloc) { /* Current buffer is large enough to host the requested size, decide on a strategy. */ if (size < alloc / 2) { @@ -220,6 +212,10 @@ PyByteArray_Resize(PyObject *self, Py_ssize_t size) alloc = size + 1; } } + if (alloc > PY_SSIZE_T_MAX) { + PyErr_NoMemory(); + return -1; + } if (logical_offset > 0) { sval = PyObject_Malloc(alloc); @@ -227,7 +223,8 @@ PyByteArray_Resize(PyObject *self, Py_ssize_t size) PyErr_NoMemory(); return -1; } - memcpy(sval, PyByteArray_AS_STRING(self), Py_MIN(size, Py_SIZE(self))); + memcpy(sval, PyByteArray_AS_STRING(self), + Py_MIN(requested_size, Py_SIZE(self))); PyObject_Free(obj->ob_bytes); } else { @@ -255,8 +252,8 @@ PyByteArray_Concat(PyObject *a, PyObject *b) va.len = -1; vb.len = -1; - if (_getbuffer(a, &va) < 0 || - _getbuffer(b, &vb) < 0) { + 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(a)->tp_name, Py_TYPE(b)->tp_name); goto done; @@ -282,6 +279,19 @@ PyByteArray_Concat(PyObject *a, PyObject *b) return (PyObject *)result; } +static PyObject * +bytearray_format(PyByteArrayObject *self, PyObject *args) +{ + if (self == NULL || !PyByteArray_Check(self)) { + PyErr_BadInternalCall(); + return NULL; + } + + return _PyBytes_FormatEx(PyByteArray_AS_STRING(self), + PyByteArray_GET_SIZE(self), + args, 1); +} + /* Functions stuffed into the type object */ static Py_ssize_t @@ -297,7 +307,7 @@ bytearray_iconcat(PyByteArrayObject *self, PyObject *other) Py_ssize_t size; Py_buffer vo; - if (_getbuffer(other, &vo) < 0) { + 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; @@ -309,11 +319,7 @@ bytearray_iconcat(PyByteArrayObject *self, PyObject *other) PyBuffer_Release(&vo); return PyErr_NoMemory(); } - if (size < self->ob_alloc) { - Py_SIZE(self) = size; - PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0'; /* Trailing null byte */ - } - else if (PyByteArray_Resize((PyObject *)self, size) < 0) { + if (PyByteArray_Resize((PyObject *)self, size) < 0) { PyBuffer_Release(&vo); return NULL; } @@ -440,7 +446,9 @@ bytearray_subscript(PyByteArrayObject *self, PyObject *index) } } else { - PyErr_SetString(PyExc_TypeError, "bytearray indices must be integers"); + PyErr_Format(PyExc_TypeError, + "bytearray indices must be integers or slices, not %.200s", + Py_TYPE(index)->tp_name); return NULL; } } @@ -555,14 +563,14 @@ bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi, needed = 0; } else { - if (_getbuffer(values, &vbytes) < 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 (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) @@ -645,7 +653,9 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu } } else { - PyErr_SetString(PyExc_TypeError, "bytearray indices must be integer"); + PyErr_Format(PyExc_TypeError, + "bytearray indices must be integers or slices, not %.200s", + Py_TYPE(index)->tp_name); return -1; } @@ -869,8 +879,10 @@ bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds) goto error; /* Append the byte */ - if (Py_SIZE(self) < self->ob_alloc) + 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; @@ -989,13 +1001,17 @@ bytearray_richcompare(PyObject *self, PyObject *other, int op) Py_buffer self_bytes, other_bytes; PyObject *res; Py_ssize_t minsize; - int cmp; + 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. */ - if (PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type) || - PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type)) { + rc = PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type); + if (!rc) + rc = PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type); + if (rc < 0) + return NULL; + if (rc) { if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) { if (PyErr_WarnEx(PyExc_BytesWarning, "Comparison between bytearray and string", 1)) @@ -1005,18 +1021,18 @@ bytearray_richcompare(PyObject *self, PyObject *other, int op) Py_RETURN_NOTIMPLEMENTED; } - self_size = _getbuffer(self, &self_bytes); - if (self_size < 0) { + if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) { PyErr_Clear(); Py_RETURN_NOTIMPLEMENTED; } + self_size = self_bytes.len; - other_size = _getbuffer(other, &other_bytes); - if (other_size < 0) { + 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 */ @@ -1119,7 +1135,7 @@ bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir) char byte; Py_buffer subbuf; const char *sub; - Py_ssize_t sub_len; + Py_ssize_t len, sub_len; Py_ssize_t start=0, end=PY_SSIZE_T_MAX; Py_ssize_t res; @@ -1128,7 +1144,7 @@ bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir) return -2; if (subobj) { - if (_getbuffer(subobj, &subbuf) < 0) + if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0) return -2; sub = subbuf.buf; @@ -1138,15 +1154,34 @@ bytearray_find_internal(PyByteArrayObject *self, PyObject *args, int dir) sub = &byte; sub_len = 1; } + len = PyByteArray_GET_SIZE(self); - if (dir > 0) - res = stringlib_find_slice( - PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), - sub, sub_len, start, end); - else - res = stringlib_rfind_slice( - PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), - sub, sub_len, start, end); + ADJUST_INDICES(start, end, len); + if (end - start < sub_len) + res = -1; + else if (sub_len == 1 +#ifndef HAVE_MEMRCHR + && dir > 0 +#endif + ) { + unsigned char needle = *sub; + int mode = (dir > 0) ? FAST_SEARCH : FAST_RSEARCH; + res = stringlib_fastsearch_memchr_1char( + PyByteArray_AS_STRING(self) + start, end - start, + needle, needle, mode); + if (res >= 0) + res += start; + } + else { + if (dir > 0) + res = stringlib_find_slice( + PyByteArray_AS_STRING(self), len, + sub, sub_len, start, end); + else + res = stringlib_rfind_slice( + PyByteArray_AS_STRING(self), len, + sub, sub_len, start, end); + } if (subobj) PyBuffer_Release(&subbuf); @@ -1196,7 +1231,7 @@ bytearray_count(PyByteArrayObject *self, PyObject *args) return NULL; if (sub_obj) { - if (_getbuffer(sub_obj, &vsub) < 0) + if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0) return NULL; sub = vsub.buf; @@ -1219,26 +1254,34 @@ bytearray_count(PyByteArrayObject *self, PyObject *args) return count_obj; } -PyDoc_STRVAR(clear__doc__, -"B.clear() -> None\n\ -\n\ -Remove all items from B."); +/*[clinic input] +bytearray.clear + + self: self(type="PyByteArrayObject *") + +Remove all items from the bytearray. +[clinic start generated code]*/ static PyObject * -bytearray_clear(PyByteArrayObject *self) +bytearray_clear_impl(PyByteArrayObject *self) +/*[clinic end generated code: output=85c2fe6aede0956c input=e524fd330abcdc18]*/ { if (PyByteArray_Resize((PyObject *)self, 0) < 0) return NULL; Py_RETURN_NONE; } -PyDoc_STRVAR(copy__doc__, -"B.copy() -> bytearray\n\ -\n\ -Return a copy of B."); +/*[clinic input] +bytearray.copy + + self: self(type="PyByteArrayObject *") + +Return a copy of B. +[clinic start generated code]*/ static PyObject * -bytearray_copy(PyByteArrayObject *self) +bytearray_copy_impl(PyByteArrayObject *self) +/*[clinic end generated code: output=68cfbcfed484c132 input=6d5d2975aa0f33f3]*/ { return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self), PyByteArray_GET_SIZE(self)); @@ -1311,7 +1354,7 @@ bytearray_contains(PyObject *self, PyObject *arg) Py_buffer varg; Py_ssize_t pos; PyErr_Clear(); - if (_getbuffer(arg, &varg) < 0) + if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0) return -1; pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self), varg.buf, varg.len, 0); @@ -1342,7 +1385,7 @@ _bytearray_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start str = PyByteArray_AS_STRING(self); - if (_getbuffer(substr, &vsubstr) < 0) + if (PyObject_GetBuffer(substr, &vsubstr, PyBUF_SIMPLE) != 0) return -1; ADJUST_INDICES(start, end, len); @@ -1457,36 +1500,42 @@ bytearray_endswith(PyByteArrayObject *self, PyObject *args) } -PyDoc_STRVAR(translate__doc__, -"B.translate(table[, deletechars]) -> bytearray\n\ -\n\ -Return a copy of B, where all characters occurring in the\n\ -optional argument deletechars are removed, and the remaining\n\ -characters have been mapped through the given translation\n\ -table, which must be a bytes object of length 256."); +/*[clinic input] +bytearray.translate + + self: self(type="PyByteArrayObject *") + table: object + Translation table, which must be a bytes object of length 256. + [ + deletechars: object + ] + / + +Return a copy with each character mapped by the given translation table. + +All characters occurring in the optional argument deletechars are removed. +The remaining characters are mapped through the given translation table. +[clinic start generated code]*/ static PyObject * -bytearray_translate(PyByteArrayObject *self, PyObject *args) +bytearray_translate_impl(PyByteArrayObject *self, PyObject *table, + int group_right_1, PyObject *deletechars) +/*[clinic end generated code: output=2bebc86a9a1ff083 input=b749ad85f4860824]*/ { char *input, *output; - const char *table; + 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]; - PyObject *tableobj = NULL, *delobj = NULL; Py_buffer vtable, vdel; - if (!PyArg_UnpackTuple(args, "translate", 1, 2, - &tableobj, &delobj)) - return NULL; - - if (tableobj == Py_None) { + if (table == Py_None) { + table_chars = NULL; table = NULL; - tableobj = NULL; - } else if (_getbuffer(tableobj, &vtable) < 0) { + } else if (PyObject_GetBuffer(table, &vtable, PyBUF_SIMPLE) != 0) { return NULL; } else { if (vtable.len != 256) { @@ -1495,12 +1544,12 @@ bytearray_translate(PyByteArrayObject *self, PyObject *args) PyBuffer_Release(&vtable); return NULL; } - table = (const char*)vtable.buf; + table_chars = (const char*)vtable.buf; } - if (delobj != NULL) { - if (_getbuffer(delobj, &vdel) < 0) { - if (tableobj != NULL) + if (deletechars != NULL) { + if (PyObject_GetBuffer(deletechars, &vdel, PyBUF_SIMPLE) != 0) { + if (table != NULL) PyBuffer_Release(&vtable); return NULL; } @@ -1517,21 +1566,21 @@ bytearray_translate(PyByteArrayObject *self, PyObject *args) output_start = output = PyByteArray_AsString(result); input = PyByteArray_AS_STRING(input_obj); - if (vdel.len == 0 && table != NULL) { + 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[c]; + *output++ = table_chars[c]; } goto done; } - if (table == NULL) { + 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[i]); + trans_table[i] = Py_CHARMASK(table_chars[i]); } for (i = 0; i < vdel.len; i++) @@ -1551,18 +1600,36 @@ bytearray_translate(PyByteArrayObject *self, PyObject *args) } done: - if (tableobj != NULL) + if (table != NULL) PyBuffer_Release(&vtable); - if (delobj != NULL) + 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(PyObject *null, PyObject *args) +bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to) +/*[clinic end generated code: output=1df267d99f56b15e input=5925a81d2fbbf151]*/ { - return _Py_bytes_maketrans(args); + return _Py_bytes_maketrans(frm, to); } @@ -2053,67 +2120,63 @@ replace(PyByteArrayObject *self, } -PyDoc_STRVAR(replace__doc__, -"B.replace(old, new[, count]) -> bytearray\n\ -\n\ -Return a copy of B with all occurrences of subsection\n\ -old replaced by new. If the optional argument count is\n\ -given, only the first count occurrences are replaced."); +/*[clinic input] +bytearray.replace -static PyObject * -bytearray_replace(PyByteArrayObject *self, PyObject *args) -{ - Py_ssize_t count = -1; - PyObject *from, *to, *res; - Py_buffer vfrom, vto; + 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. + / - if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count)) - return NULL; +Return a copy with all occurrences of substring old replaced by new. - if (_getbuffer(from, &vfrom) < 0) - return NULL; - if (_getbuffer(to, &vto) < 0) { - PyBuffer_Release(&vfrom); - return NULL; - } - - res = (PyObject *)replace((PyByteArrayObject *) self, - vfrom.buf, vfrom.len, - vto.buf, vto.len, count); +If the optional argument count is given, only the first count occurrences are +replaced. +[clinic start generated code]*/ - PyBuffer_Release(&vfrom); - PyBuffer_Release(&vto); - return res; +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 (PyObject *)replace((PyByteArrayObject *) self, + old->buf, old->len, + new->buf, new->len, count); } -PyDoc_STRVAR(split__doc__, -"B.split(sep=None, maxsplit=-1) -> list of bytearrays\n\ -\n\ -Return a list of the sections in B, using sep as the delimiter.\n\ -If sep is not given, B is split on ASCII whitespace characters\n\ -(space, tab, return, newline, formfeed, vertical tab).\n\ -If maxsplit is given, at most maxsplit splits are done."); +/*[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(PyByteArrayObject *self, PyObject *args, PyObject *kwds) +bytearray_split_impl(PyByteArrayObject *self, PyObject *sep, + Py_ssize_t maxsplit) +/*[clinic end generated code: output=833e2cf385d9a04d input=24f82669f41bf523]*/ { - static char *kwlist[] = {"sep", "maxsplit", 0}; Py_ssize_t len = PyByteArray_GET_SIZE(self), n; - Py_ssize_t maxsplit = -1; const char *s = PyByteArray_AS_STRING(self), *sub; - PyObject *list, *subobj = Py_None; + PyObject *list; Py_buffer vsub; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:split", - kwlist, &subobj, &maxsplit)) - return NULL; if (maxsplit < 0) maxsplit = PY_SSIZE_T_MAX; - if (subobj == Py_None) + if (sep == Py_None) return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit); - if (_getbuffer(subobj, &vsub) < 0) + if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) return NULL; sub = vsub.buf; n = vsub.len; @@ -2125,19 +2188,30 @@ bytearray_split(PyByteArrayObject *self, PyObject *args, PyObject *kwds) return list; } -PyDoc_STRVAR(partition__doc__, -"B.partition(sep) -> (head, sep, tail)\n\ -\n\ -Search for the separator sep in B, and return the part before it,\n\ -the separator itself, and the part after it. If the separator is not\n\ -found, returns B and two empty bytearray objects."); +/*[clinic input] +bytearray.partition + + self: self(type="PyByteArrayObject *") + 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. + +If the separator is not found, returns a 3-tuple containing the original +bytearray object and two empty bytearray objects. +[clinic start generated code]*/ static PyObject * -bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj) +bytearray_partition(PyByteArrayObject *self, PyObject *sep) +/*[clinic end generated code: output=45d2525ddd35f957 input=7d7fe37b1696d506]*/ { PyObject *bytesep, *result; - bytesep = PyByteArray_FromObject(sep_obj); + bytesep = PyByteArray_FromObject(sep); if (! bytesep) return NULL; @@ -2152,20 +2226,30 @@ bytearray_partition(PyByteArrayObject *self, PyObject *sep_obj) return result; } -PyDoc_STRVAR(rpartition__doc__, -"B.rpartition(sep) -> (head, sep, tail)\n\ -\n\ -Search for the separator sep in B, starting at the end of B,\n\ -and return the part before it, the separator itself, and the\n\ -part after it. If the separator is not found, returns two empty\n\ -bytearray objects and B."); +/*[clinic input] +bytearray.rpartition + + self: self(type="PyByteArrayObject *") + sep: object + / + +Partition the bytes into three parts using the given separator. + +This will search for the separator sep in the bytearray, starting and 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 bytearray +objects and the original bytearray object. +[clinic start generated code]*/ static PyObject * -bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj) +bytearray_rpartition(PyByteArrayObject *self, PyObject *sep) +/*[clinic end generated code: output=440de3c9426115e8 input=9b8cd540c1b75853]*/ { PyObject *bytesep, *result; - bytesep = PyByteArray_FromObject(sep_obj); + bytesep = PyByteArray_FromObject(sep); if (! bytesep) return NULL; @@ -2180,35 +2264,31 @@ bytearray_rpartition(PyByteArrayObject *self, PyObject *sep_obj) return result; } -PyDoc_STRVAR(rsplit__doc__, -"B.rsplit(sep=None, maxsplit=-1) -> list of bytearrays\n\ -\n\ -Return a list of the sections in B, using sep as the delimiter,\n\ -starting at the end of B and working to the front.\n\ -If sep is not given, B is split on ASCII whitespace characters\n\ -(space, tab, return, newline, formfeed, vertical tab).\n\ -If maxsplit is given, at most maxsplit splits are done."); +/*[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(PyByteArrayObject *self, PyObject *args, PyObject *kwds) +bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep, + Py_ssize_t maxsplit) +/*[clinic end generated code: output=a55e0b5a03cb6190 input=a68286e4dd692ffe]*/ { - static char *kwlist[] = {"sep", "maxsplit", 0}; Py_ssize_t len = PyByteArray_GET_SIZE(self), n; - Py_ssize_t maxsplit = -1; const char *s = PyByteArray_AS_STRING(self), *sub; - PyObject *list, *subobj = Py_None; + PyObject *list; Py_buffer vsub; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:rsplit", - kwlist, &subobj, &maxsplit)) - return NULL; if (maxsplit < 0) maxsplit = PY_SSIZE_T_MAX; - if (subobj == Py_None) + if (sep == Py_None) return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit); - if (_getbuffer(subobj, &vsub) < 0) + if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) return NULL; sub = vsub.buf; n = vsub.len; @@ -2220,12 +2300,17 @@ bytearray_rsplit(PyByteArrayObject *self, PyObject *args, PyObject *kwds) return list; } -PyDoc_STRVAR(reverse__doc__, -"B.reverse() -> None\n\ -\n\ -Reverse the order of the values in B in place."); +/*[clinic input] +bytearray.reverse + + self: self(type="PyByteArrayObject *") + +Reverse the order of the values in B in place. +[clinic start generated code]*/ + static PyObject * -bytearray_reverse(PyByteArrayObject *self, PyObject *unused) +bytearray_reverse_impl(PyByteArrayObject *self) +/*[clinic end generated code: output=9f7616f29ab309d3 input=7933a499b8597bd1]*/ { char swap, *head, *tail; Py_ssize_t i, j, n = Py_SIZE(self); @@ -2242,57 +2327,74 @@ bytearray_reverse(PyByteArrayObject *self, PyObject *unused) Py_RETURN_NONE; } -PyDoc_STRVAR(insert__doc__, -"B.insert(index, int) -> None\n\ -\n\ -Insert a single item into the bytearray before the given index."); + +/*[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 + + self: self(type="PyByteArrayObject *") + 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(PyByteArrayObject *self, PyObject *args) +bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item) +/*[clinic end generated code: output=76c775a70e7b07b7 input=833766836ba30e1e]*/ { - PyObject *value; - int ival; - Py_ssize_t where, n = Py_SIZE(self); + Py_ssize_t n = Py_SIZE(self); char *buf; - if (!PyArg_ParseTuple(args, "nO:insert", &where, &value)) - return NULL; - if (n == PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_OverflowError, "cannot add more objects to bytearray"); return NULL; } - if (!_getbytevalue(value, &ival)) - return NULL; if (PyByteArray_Resize((PyObject *)self, n + 1) < 0) return NULL; buf = PyByteArray_AS_STRING(self); - if (where < 0) { - where += n; - if (where < 0) - where = 0; + if (index < 0) { + index += n; + if (index < 0) + index = 0; } - if (where > n) - where = n; - memmove(buf + where + 1, buf + where, n - where); - buf[where] = ival; + if (index > n) + index = n; + memmove(buf + index + 1, buf + index, n - index); + buf[index] = item; Py_RETURN_NONE; } -PyDoc_STRVAR(append__doc__, -"B.append(int) -> None\n\ -\n\ -Append a single item to the end of B."); +/*[clinic input] +bytearray.append + + self: self(type="PyByteArrayObject *") + 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(PyByteArrayObject *self, PyObject *arg) +bytearray_append_impl(PyByteArrayObject *self, int item) +/*[clinic end generated code: output=a154e19ed1886cb6 input=ae56ea87380407cc]*/ { - int value; Py_ssize_t n = Py_SIZE(self); - if (! _getbytevalue(arg, &value)) - return NULL; if (n == PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_OverflowError, "cannot add more objects to bytearray"); @@ -2301,18 +2403,25 @@ bytearray_append(PyByteArrayObject *self, PyObject *arg) if (PyByteArray_Resize((PyObject *)self, n + 1) < 0) return NULL; - PyByteArray_AS_STRING(self)[n] = value; + PyByteArray_AS_STRING(self)[n] = item; Py_RETURN_NONE; } -PyDoc_STRVAR(extend__doc__, -"B.extend(iterable_of_ints) -> None\n\ -\n\ -Append all the elements from the iterator or sequence to the\n\ -end of B."); +/*[clinic input] +bytearray.extend + + self: self(type="PyByteArrayObject *") + 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 *arg) +bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints) +/*[clinic end generated code: output=98155dbe249170b1 input=ce83a5d75b70d850]*/ { PyObject *it, *item, *bytearray_obj; Py_ssize_t buf_size = 0, len = 0; @@ -2320,19 +2429,19 @@ bytearray_extend(PyByteArrayObject *self, PyObject *arg) char *buf; /* bytearray_setslice code only accepts something supporting PEP 3118. */ - if (PyObject_CheckBuffer(arg)) { - if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), arg) == -1) + 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(arg); + it = PyObject_GetIter(iterable_of_ints); if (it == NULL) return NULL; /* Try to determine the length of the argument. 32 is arbitrary. */ - buf_size = PyObject_LengthHint(arg, 32); + buf_size = PyObject_LengthHint(iterable_of_ints, 32); if (buf_size == -1) { Py_DECREF(it); return NULL; @@ -2384,29 +2493,36 @@ bytearray_extend(PyByteArrayObject *self, PyObject *arg) Py_RETURN_NONE; } -PyDoc_STRVAR(pop__doc__, -"B.pop([index]) -> int\n\ -\n\ -Remove and return a single item from B. If no index\n\ -argument is given, will pop the last value."); +/*[clinic input] +bytearray.pop + + self: self(type="PyByteArrayObject *") + 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(PyByteArrayObject *self, PyObject *args) +bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index) +/*[clinic end generated code: output=e0ccd401f8021da8 input=0797e6c0ca9d5a85]*/ { int value; - Py_ssize_t where = -1, n = Py_SIZE(self); + Py_ssize_t n = Py_SIZE(self); char *buf; - if (!PyArg_ParseTuple(args, "|n:pop", &where)) - return NULL; - if (n == 0) { PyErr_SetString(PyExc_IndexError, "pop from empty bytearray"); return NULL; } - if (where < 0) - where += Py_SIZE(self); - if (where < 0 || where >= Py_SIZE(self)) { + 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; } @@ -2414,28 +2530,32 @@ bytearray_pop(PyByteArrayObject *self, PyObject *args) return NULL; buf = PyByteArray_AS_STRING(self); - value = buf[where]; - memmove(buf + where, buf + where + 1, n - where); + 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); } -PyDoc_STRVAR(remove__doc__, -"B.remove(int) -> None\n\ -\n\ -Remove the first occurrence of a value in B."); +/*[clinic input] +bytearray.remove + + self: self(type="PyByteArrayObject *") + value: bytesvalue + The value to remove. + / + +Remove the first occurrence of a value in the bytearray. +[clinic start generated code]*/ + static PyObject * -bytearray_remove(PyByteArrayObject *self, PyObject *arg) +bytearray_remove_impl(PyByteArrayObject *self, int value) +/*[clinic end generated code: output=d659e37866709c13 input=47560b11fd856c24]*/ { - int value; Py_ssize_t where, n = Py_SIZE(self); char *buf = PyByteArray_AS_STRING(self); - if (! _getbytevalue(arg, &value)) - return NULL; - for (where = 0; where < n; where++) { if (buf[where] == value) break; @@ -2476,132 +2596,145 @@ rstrip_helper(char *myptr, Py_ssize_t mysize, return i + 1; } -PyDoc_STRVAR(strip__doc__, -"B.strip([bytes]) -> bytearray\n\ -\n\ -Strip leading and trailing bytes contained in the argument\n\ -and return the result as a new bytearray.\n\ -If the argument is omitted, strip ASCII whitespace."); +/*[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(PyByteArrayObject *self, PyObject *args) +bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes) +/*[clinic end generated code: output=760412661a34ad5a input=ef7bb59b09c21d62]*/ { - Py_ssize_t left, right, mysize, argsize; - char *myptr, *argptr; - PyObject *arg = Py_None; - Py_buffer varg; - if (!PyArg_ParseTuple(args, "|O:strip", &arg)) - return NULL; - if (arg == Py_None) { - argptr = "\t\n\r\f\v "; - argsize = 6; + Py_ssize_t left, right, mysize, byteslen; + char *myptr, *bytesptr; + Py_buffer vbytes; + + if (bytes == Py_None) { + bytesptr = "\t\n\r\f\v "; + byteslen = 6; } else { - if (_getbuffer(arg, &varg) < 0) + if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0) return NULL; - argptr = (char *) varg.buf; - argsize = varg.len; + bytesptr = (char *) vbytes.buf; + byteslen = vbytes.len; } myptr = PyByteArray_AS_STRING(self); mysize = Py_SIZE(self); - left = lstrip_helper(myptr, mysize, argptr, argsize); + left = lstrip_helper(myptr, mysize, bytesptr, byteslen); if (left == mysize) right = left; else - right = rstrip_helper(myptr, mysize, argptr, argsize); - if (arg != Py_None) - PyBuffer_Release(&varg); + right = rstrip_helper(myptr, mysize, bytesptr, byteslen); + if (bytes != Py_None) + PyBuffer_Release(&vbytes); return PyByteArray_FromStringAndSize(myptr + left, right - left); } -PyDoc_STRVAR(lstrip__doc__, -"B.lstrip([bytes]) -> bytearray\n\ -\n\ -Strip leading bytes contained in the argument\n\ -and return the result as a new bytearray.\n\ -If the argument is omitted, strip leading ASCII whitespace."); +/*[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(PyByteArrayObject *self, PyObject *args) +bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes) +/*[clinic end generated code: output=d005c9d0ab909e66 input=80843f975dd7c480]*/ { - Py_ssize_t left, right, mysize, argsize; - char *myptr, *argptr; - PyObject *arg = Py_None; - Py_buffer varg; - if (!PyArg_ParseTuple(args, "|O:lstrip", &arg)) - return NULL; - if (arg == Py_None) { - argptr = "\t\n\r\f\v "; - argsize = 6; + Py_ssize_t left, right, mysize, byteslen; + char *myptr, *bytesptr; + Py_buffer vbytes; + + if (bytes == Py_None) { + bytesptr = "\t\n\r\f\v "; + byteslen = 6; } else { - if (_getbuffer(arg, &varg) < 0) + if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0) return NULL; - argptr = (char *) varg.buf; - argsize = varg.len; + bytesptr = (char *) vbytes.buf; + byteslen = vbytes.len; } myptr = PyByteArray_AS_STRING(self); mysize = Py_SIZE(self); - left = lstrip_helper(myptr, mysize, argptr, argsize); + left = lstrip_helper(myptr, mysize, bytesptr, byteslen); right = mysize; - if (arg != Py_None) - PyBuffer_Release(&varg); + if (bytes != Py_None) + PyBuffer_Release(&vbytes); return PyByteArray_FromStringAndSize(myptr + left, right - left); } -PyDoc_STRVAR(rstrip__doc__, -"B.rstrip([bytes]) -> bytearray\n\ -\n\ -Strip trailing bytes contained in the argument\n\ -and return the result as a new bytearray.\n\ -If the argument is omitted, strip trailing ASCII whitespace."); +/*[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(PyByteArrayObject *self, PyObject *args) +bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes) +/*[clinic end generated code: output=030e2fbd2f7276bd input=e728b994954cfd91]*/ { - Py_ssize_t right, mysize, argsize; - char *myptr, *argptr; - PyObject *arg = Py_None; - Py_buffer varg; - if (!PyArg_ParseTuple(args, "|O:rstrip", &arg)) - return NULL; - if (arg == Py_None) { - argptr = "\t\n\r\f\v "; - argsize = 6; + Py_ssize_t right, mysize, byteslen; + char *myptr, *bytesptr; + Py_buffer vbytes; + + if (bytes == Py_None) { + bytesptr = "\t\n\r\f\v "; + byteslen = 6; } else { - if (_getbuffer(arg, &varg) < 0) + if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0) return NULL; - argptr = (char *) varg.buf; - argsize = varg.len; + bytesptr = (char *) vbytes.buf; + byteslen = vbytes.len; } myptr = PyByteArray_AS_STRING(self); mysize = Py_SIZE(self); - right = rstrip_helper(myptr, mysize, argptr, argsize); - if (arg != Py_None) - PyBuffer_Release(&varg); + right = rstrip_helper(myptr, mysize, bytesptr, byteslen); + if (bytes != Py_None) + PyBuffer_Release(&vbytes); return PyByteArray_FromStringAndSize(myptr, right); } -PyDoc_STRVAR(decode_doc, -"B.decode(encoding='utf-8', errors='strict') -> str\n\ -\n\ -Decode B using the codec registered for encoding. Default encoding\n\ -is 'utf-8'. errors may be given to set a different error\n\ -handling scheme. Default is 'strict' meaning that encoding errors raise\n\ -a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\ -as well as any other name registered with codecs.register_error that is\n\ -able to handle UnicodeDecodeErrors."); +/*[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(PyObject *self, PyObject *args, PyObject *kwargs) +bytearray_decode_impl(PyByteArrayObject *self, const char *encoding, + const char *errors) +/*[clinic end generated code: output=f57d43f4a00b42c5 input=f28d8f903020257b]*/ { - const char *encoding = NULL; - const char *errors = NULL; - static char *kwlist[] = {"encoding", "errors", 0}; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors)) - return NULL; if (encoding == NULL) encoding = PyUnicode_GetDefaultEncoding(); - return PyUnicode_FromEncodedObject(self, encoding, errors); + return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors); } PyDoc_STRVAR(alloc_doc, @@ -2615,114 +2748,82 @@ bytearray_alloc(PyByteArrayObject *self) return PyLong_FromSsize_t(self->ob_alloc); } -PyDoc_STRVAR(join_doc, -"B.join(iterable_of_bytes) -> bytearray\n\ -\n\ -Concatenate any number of bytes/bytearray objects, with B\n\ -in between each pair, and return the result as a new bytearray."); +/*[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(PyObject *self, PyObject *iterable) +bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes) +/*[clinic end generated code: output=a8516370bf68ae08 input=aba6b1f9b30fcb8e]*/ { - return stringlib_bytes_join(self, iterable); + return stringlib_bytes_join((PyObject*)self, iterable_of_bytes); } -PyDoc_STRVAR(splitlines__doc__, -"B.splitlines([keepends]) -> list of lines\n\ -\n\ -Return a list of the lines in B, breaking at line boundaries.\n\ -Line breaks are not included in the resulting list unless keepends\n\ -is given and true."); +/*[clinic input] +bytearray.splitlines -static PyObject* -bytearray_splitlines(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"keepends", 0}; - int keepends = 0; + keepends: int(c_default="0") = False - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:splitlines", - kwlist, &keepends)) - return NULL; +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=8ccade941e5ea0bd]*/ +{ return stringlib_splitlines( (PyObject*) self, PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), keepends ); } -PyDoc_STRVAR(fromhex_doc, -"bytearray.fromhex(string) -> bytearray (static method)\n\ -\n\ -Create a bytearray object from a string of hexadecimal numbers.\n\ -Spaces between two numbers are accepted.\n\ -Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')."); +/*[clinic input] +@classmethod +bytearray.fromhex -static int -hex_digit_to_int(Py_UCS4 c) -{ - if (c >= 128) - return -1; - if (Py_ISDIGIT(c)) - return c - '0'; - else { - if (Py_ISUPPER(c)) - c = Py_TOLOWER(c); - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - } - return -1; -} + cls: self(type="PyObject*") + 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(PyObject *cls, PyObject *args) +bytearray_fromhex_impl(PyObject*cls, PyObject *string) +/*[clinic end generated code: output=df3da60129b3700c input=907bbd2d34d9367a]*/ { - PyObject *newbytes, *hexobj; - char *buf; - Py_ssize_t hexlen, byteslen, i, j; - int top, bot; - void *data; - unsigned int kind; - - if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj)) - return NULL; - assert(PyUnicode_Check(hexobj)); - if (PyUnicode_READY(hexobj)) - return NULL; - kind = PyUnicode_KIND(hexobj); - data = PyUnicode_DATA(hexobj); - hexlen = PyUnicode_GET_LENGTH(hexobj); + return _PyBytes_FromHex(string, 1); +} - byteslen = hexlen/2; /* This overestimates if there are spaces */ - newbytes = PyByteArray_FromStringAndSize(NULL, byteslen); - if (!newbytes) - return NULL; - buf = PyByteArray_AS_STRING(newbytes); - for (i = j = 0; i < hexlen; i += 2) { - /* skip over spaces in the input */ - while (PyUnicode_READ(kind, data, i) == ' ') - i++; - if (i >= hexlen) - break; - top = hex_digit_to_int(PyUnicode_READ(kind, data, i)); - bot = hex_digit_to_int(PyUnicode_READ(kind, data, i+1)); - if (top == -1 || bot == -1) { - PyErr_Format(PyExc_ValueError, - "non-hexadecimal number found in " - "fromhex() arg at position %zd", i); - goto error; - } - buf[j++] = (top << 4) + bot; - } - if (PyByteArray_Resize(newbytes, j) < 0) - goto error; - return newbytes; +PyDoc_STRVAR(hex__doc__, +"B.hex() -> string\n\ +\n\ +Create a string of hexadecimal numbers from a bytearray object.\n\ +Example: bytearray([0xb9, 0x01, 0xef]).hex() -> 'b901ef'."); - error: - Py_DECREF(newbytes); - return NULL; +static PyObject * +bytearray_hex(PyBytesObject *self) +{ + char* argbuf = PyByteArray_AS_STRING(self); + Py_ssize_t arglen = PyByteArray_GET_SIZE(self); + return _Py_strhex(argbuf, arglen); } - static PyObject * _common_reduce(PyByteArrayObject *self, int proto) { @@ -2758,33 +2859,49 @@ _common_reduce(PyByteArrayObject *self, int proto) } } -PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); +/*[clinic input] +bytearray.__reduce__ as bytearray_reduce + + self: self(type="PyByteArrayObject *") + +Return state information for pickling. +[clinic start generated code]*/ static PyObject * -bytearray_reduce(PyByteArrayObject *self) +bytearray_reduce_impl(PyByteArrayObject *self) +/*[clinic end generated code: output=52bf304086464cab input=fbb07de4d102a03a]*/ { return _common_reduce(self, 2); } -PyDoc_STRVAR(reduce_ex_doc, "Return state information for pickling."); +/*[clinic input] +bytearray.__reduce_ex__ as bytearray_reduce_ex -static PyObject * -bytearray_reduce_ex(PyByteArrayObject *self, PyObject *args) -{ - int proto = 0; + self: self(type="PyByteArrayObject *") + proto: int = 0 + / - if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", &proto)) - return NULL; +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=0e091a42ca6dbd91]*/ +{ return _common_reduce(self, proto); } -PyDoc_STRVAR(sizeof_doc, -"B.__sizeof__() -> int\n\ - \n\ -Returns the size of B in memory, in bytes"); +/*[clinic input] +bytearray.__sizeof__ as bytearray_sizeof + + self: self(type="PyByteArrayObject *") + +Returns the size of the bytearray object in memory, in bytes. +[clinic start generated code]*/ + static PyObject * -bytearray_sizeof(PyByteArrayObject *self) +bytearray_sizeof_impl(PyByteArrayObject *self) +/*[clinic end generated code: output=738abdd17951c427 input=6b23d305362b462b]*/ { Py_ssize_t res; @@ -2819,26 +2936,26 @@ static PyBufferProcs bytearray_as_buffer = { static PyMethodDef bytearray_methods[] = { {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc}, - {"__reduce__", (PyCFunction)bytearray_reduce, METH_NOARGS, reduce_doc}, - {"__reduce_ex__", (PyCFunction)bytearray_reduce_ex, METH_VARARGS, reduce_ex_doc}, - {"__sizeof__", (PyCFunction)bytearray_sizeof, METH_NOARGS, sizeof_doc}, - {"append", (PyCFunction)bytearray_append, METH_O, append__doc__}, + BYTEARRAY_REDUCE_METHODDEF + BYTEARRAY_REDUCE_EX_METHODDEF + BYTEARRAY_SIZEOF_METHODDEF + BYTEARRAY_APPEND_METHODDEF {"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS, _Py_capitalize__doc__}, {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__}, - {"clear", (PyCFunction)bytearray_clear, METH_NOARGS, clear__doc__}, - {"copy", (PyCFunction)bytearray_copy, METH_NOARGS, copy__doc__}, + BYTEARRAY_CLEAR_METHODDEF + BYTEARRAY_COPY_METHODDEF {"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__}, - {"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc}, + BYTEARRAY_DECODE_METHODDEF {"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__}, {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS, expandtabs__doc__}, - {"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__}, + BYTEARRAY_EXTEND_METHODDEF {"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__}, - {"fromhex", (PyCFunction)bytearray_fromhex, METH_VARARGS|METH_CLASS, - fromhex_doc}, + BYTEARRAY_FROMHEX_METHODDEF + {"hex", (PyCFunction)bytearray_hex, METH_NOARGS, hex__doc__}, {"index", (PyCFunction)bytearray_index, METH_VARARGS, index__doc__}, - {"insert", (PyCFunction)bytearray_insert, METH_VARARGS, insert__doc__}, + BYTEARRAY_INSERT_METHODDEF {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS, _Py_isalnum__doc__}, {"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS, @@ -2853,39 +2970,51 @@ bytearray_methods[] = { _Py_istitle__doc__}, {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS, _Py_isupper__doc__}, - {"join", (PyCFunction)bytearray_join, METH_O, join_doc}, + BYTEARRAY_JOIN_METHODDEF {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__}, {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, - {"lstrip", (PyCFunction)bytearray_lstrip, METH_VARARGS, lstrip__doc__}, - {"maketrans", (PyCFunction)bytearray_maketrans, METH_VARARGS|METH_STATIC, - _Py_maketrans__doc__}, - {"partition", (PyCFunction)bytearray_partition, METH_O, partition__doc__}, - {"pop", (PyCFunction)bytearray_pop, METH_VARARGS, pop__doc__}, - {"remove", (PyCFunction)bytearray_remove, METH_O, remove__doc__}, - {"replace", (PyCFunction)bytearray_replace, METH_VARARGS, replace__doc__}, - {"reverse", (PyCFunction)bytearray_reverse, METH_NOARGS, reverse__doc__}, + 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, rfind__doc__}, {"rindex", (PyCFunction)bytearray_rindex, METH_VARARGS, rindex__doc__}, {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__}, - {"rpartition", (PyCFunction)bytearray_rpartition, METH_O, rpartition__doc__}, - {"rsplit", (PyCFunction)bytearray_rsplit, METH_VARARGS | METH_KEYWORDS, rsplit__doc__}, - {"rstrip", (PyCFunction)bytearray_rstrip, METH_VARARGS, rstrip__doc__}, - {"split", (PyCFunction)bytearray_split, METH_VARARGS | METH_KEYWORDS, split__doc__}, - {"splitlines", (PyCFunction)bytearray_splitlines, - METH_VARARGS | METH_KEYWORDS, splitlines__doc__}, + BYTEARRAY_RPARTITION_METHODDEF + BYTEARRAY_RSPLIT_METHODDEF + BYTEARRAY_RSTRIP_METHODDEF + BYTEARRAY_SPLIT_METHODDEF + BYTEARRAY_SPLITLINES_METHODDEF {"startswith", (PyCFunction)bytearray_startswith, METH_VARARGS , startswith__doc__}, - {"strip", (PyCFunction)bytearray_strip, METH_VARARGS, strip__doc__}, + BYTEARRAY_STRIP_METHODDEF {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, _Py_swapcase__doc__}, {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, - {"translate", (PyCFunction)bytearray_translate, METH_VARARGS, - translate__doc__}, + BYTEARRAY_TRANSLATE_METHODDEF {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, {NULL} }; +static PyObject * +bytearray_mod(PyObject *v, PyObject *w) +{ + if (!PyByteArray_Check(v)) + Py_RETURN_NOTIMPLEMENTED; + return bytearray_format((PyByteArrayObject *)v, w); +} + +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\ @@ -2914,7 +3043,7 @@ PyTypeObject PyByteArray_Type = { 0, /* tp_setattr */ 0, /* tp_reserved */ (reprfunc)bytearray_repr, /* tp_repr */ - 0, /* tp_as_number */ + &bytearray_as_number, /* tp_as_number */ &bytearray_as_sequence, /* tp_as_sequence */ &bytearray_as_mapping, /* tp_as_mapping */ 0, /* tp_hash */ @@ -3025,9 +3154,13 @@ bytearrayiter_setstate(bytesiterobject *it, PyObject *state) Py_ssize_t index = PyLong_AsSsize_t(state); if (index == -1 && PyErr_Occurred()) return NULL; - if (index < 0) - index = 0; - it->it_index = index; + 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; } @@ -3037,7 +3170,7 @@ static PyMethodDef bytearrayiter_methods[] = { {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS, length_hint_doc}, {"__reduce__", (PyCFunction)bytearrayiter_reduce, METH_NOARGS, - reduce_doc}, + bytearray_reduce__doc__}, {"__setstate__", (PyCFunction)bytearrayiter_setstate, METH_O, setstate_doc}, {NULL, NULL} /* sentinel */ diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c index 4e8107b49112..a29991584a09 100644 --- a/Objects/bytes_methods.c +++ b/Objects/bytes_methods.c @@ -363,61 +363,27 @@ 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."); -static Py_ssize_t -_getbuffer(PyObject *obj, Py_buffer *view) -{ - PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer; - - if (buffer == NULL || buffer->bf_getbuffer == NULL) - { - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't support the buffer API", - Py_TYPE(obj)->tp_name); - return -1; - } - - if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0) - return -1; - return view->len; -} - PyObject * -_Py_bytes_maketrans(PyObject *args) +_Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to) { - PyObject *frm, *to, *res = NULL; - Py_buffer bfrm, bto; + PyObject *res = NULL; Py_ssize_t i; char *p; - bfrm.len = -1; - bto.len = -1; - - if (!PyArg_ParseTuple(args, "OO:maketrans", &frm, &to)) - return NULL; - if (_getbuffer(frm, &bfrm) < 0) - return NULL; - if (_getbuffer(to, &bto) < 0) - goto done; - if (bfrm.len != bto.len) { + if (frm->len != to->len) { PyErr_Format(PyExc_ValueError, "maketrans arguments must have same length"); - goto done; + return NULL; } res = PyBytes_FromStringAndSize(NULL, 256); - if (!res) { - goto done; - } + if (!res) + return NULL; p = PyBytes_AS_STRING(res); for (i = 0; i < 256; i++) p[i] = (char) i; - for (i = 0; i < bfrm.len; i++) { - p[((unsigned char *)bfrm.buf)[i]] = ((char *)bto.buf)[i]; + for (i = 0; i < frm->len; i++) { + p[((unsigned char *)frm->buf)[i]] = ((char *)to->buf)[i]; } -done: - if (bfrm.len != -1) - PyBuffer_Release(&bfrm); - if (bto.len != -1) - PyBuffer_Release(&bto); return res; } diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 8217b1eab30a..c10dbdfe053c 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -5,34 +5,15 @@ #include "Python.h" #include "bytes_methods.h" +#include "pystrhex.h" #include -static Py_ssize_t -_getbuffer(PyObject *obj, Py_buffer *view) -{ - PyBufferProcs *bufferprocs; - if (PyBytes_CheckExact(obj)) { - /* Fast path, e.g. for .join() of many bytes objects */ - Py_INCREF(obj); - view->obj = obj; - view->buf = PyBytes_AS_STRING(obj); - view->len = PyBytes_GET_SIZE(obj); - return view->len; - } - - bufferprocs = Py_TYPE(obj)->tp_as_buffer; - if (bufferprocs == NULL || bufferprocs->bf_getbuffer == NULL) - { - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't support the buffer API", - Py_TYPE(obj)->tp_name); - return -1; - } +/*[clinic input] +class bytes "PyBytesObject*" "&PyBytes_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1a1d9102afc1b00c]*/ - if (bufferprocs->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0) - return -1; - return view->len; -} +#include "clinic/bytesobject.c.h" #ifdef COUNT_ALLOCS Py_ssize_t null_strings, one_strings; @@ -49,6 +30,10 @@ static PyBytesObject *nullstring; */ #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. @@ -71,15 +56,12 @@ static PyBytesObject *nullstring; PyBytes_FromStringAndSize()) or the length of the string in the `str' parameter (for PyBytes_FromString()). */ -PyObject * -PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) +static PyObject * +_PyBytes_FromSize(Py_ssize_t size, int use_calloc) { PyBytesObject *op; - if (size < 0) { - PyErr_SetString(PyExc_SystemError, - "Negative size passed to PyBytes_FromStringAndSize"); - return NULL; - } + assert(size >= 0); + if (size == 0 && (op = nullstring) != NULL) { #ifdef COUNT_ALLOCS null_strings++; @@ -87,36 +69,60 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) Py_INCREF(op); return (PyObject *)op; } - if (size == 1 && str != NULL && - (op = characters[*str & UCHAR_MAX]) != NULL) - { -#ifdef COUNT_ALLOCS - one_strings++; -#endif - Py_INCREF(op); - return (PyObject *)op; - } - if (size > PY_SSIZE_T_MAX - PyBytesObject_SIZE) { + 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 */ - op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + size); + 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(); - PyObject_INIT_VAR(op, &PyBytes_Type, size); + (void)PyObject_INIT_VAR(op, &PyBytes_Type, size); op->ob_shash = -1; - if (str != NULL) - Py_MEMCPY(op->ob_sval, str, size); - op->ob_sval[size] = '\0'; - /* share short strings */ + if (!use_calloc) + op->ob_sval[size] = '\0'; + /* empty byte string singleton */ if (size == 0) { nullstring = op; Py_INCREF(op); - } else if (size == 1 && str != NULL) { + } + 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 + 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; + + Py_MEMCPY(op->ob_sval, str, size); + /* share short strings */ + if (size == 1) { characters[*str & UCHAR_MAX] = op; Py_INCREF(op); } @@ -155,7 +161,7 @@ PyBytes_FromString(const char *str) op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + size); if (op == NULL) return PyErr_NoMemory(); - PyObject_INIT_VAR(op, &PyBytes_Type, size); + (void)PyObject_INIT_VAR(op, &PyBytes_Type, size); op->ob_shash = -1; Py_MEMCPY(op->ob_sval, str, size+1); /* share short strings */ @@ -172,177 +178,184 @@ PyBytes_FromString(const char *str) PyObject * PyBytes_FromFormatV(const char *format, va_list vargs) { - va_list count; - Py_ssize_t n = 0; - const char* f; char *s; - PyObject* string; - - Py_VA_COPY(count, vargs); - /* step 1: figure out how large a buffer we need */ - for (f = format; *f; f++) { - if (*f == '%') { - const char* p = f; - while (*++f && *f != '%' && !Py_ISALPHA(*f)) - ; - - /* skip the 'l' or 'z' in {%ld, %zd, %lu, %zu} since - * they don't affect the amount of space we reserve. - */ - if ((*f == 'l' || *f == 'z') && - (f[1] == 'd' || f[1] == 'u')) - ++f; - - switch (*f) { - case 'c': - (void)va_arg(count, int); - /* fall through... */ - case '%': - n++; - break; - case 'd': case 'u': case 'i': case 'x': - (void) va_arg(count, int); - /* 20 bytes is enough to hold a 64-bit - integer. Decimal takes the most space. - This isn't enough for octal. */ - n += 20; - break; - case 's': - s = va_arg(count, char*); - n += strlen(s); - break; - case 'p': - (void) va_arg(count, int); - /* maximum 64-bit pointer representation: - * 0xffffffffffffffff - * so 19 characters is enough. - * XXX I count 18 -- what's the extra for? - */ - n += 19; - 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) */ - n += strlen(p); - goto expand; - } - } else - n++; - } - expand: - /* step 2: fill the buffer */ - /* Since we've analyzed how much space we need for the worst case, - use sprintf directly instead of the slower PyOS_snprintf. */ - string = PyBytes_FromStringAndSize(NULL, n); - if (!string) + 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; - s = PyBytes_AsString(string); +#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 == '%') { - const char* p = f++; - Py_ssize_t i; - int longflag = 0; - int size_tflag = 0; - /* parse the width.precision part (we're only - interested in the precision value, if any) */ - n = 0; - while (Py_ISDIGIT(*f)) - n = (n*10) + *f++ - '0'; - if (*f == '.') { - f++; - n = 0; - while (Py_ISDIGIT(*f)) - n = (n*10) + *f++ - '0'; + 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, but only for %ld and %lu. - others can be added when necessary. */ - if (*f == 'l' && (f[1] == 'd' || f[1] == 'u')) { - longflag = 1; - ++f; + } + + 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; + } + + /* substract 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; } - /* handle the size_t flag. */ - if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) { - size_tflag = 1; - ++f; + 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, char*); + i = strlen(p); + if (prec > 0 && i > prec) + i = prec; + 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; - switch (*f) { - case 'c': - *s++ = va_arg(vargs, int); - break; - case 'd': - if (longflag) - sprintf(s, "%ld", va_arg(vargs, long)); - else if (size_tflag) - sprintf(s, "%" PY_FORMAT_SIZE_T "d", - va_arg(vargs, Py_ssize_t)); - else - sprintf(s, "%d", va_arg(vargs, int)); - s += strlen(s); - break; - case 'u': - if (longflag) - sprintf(s, "%lu", - va_arg(vargs, unsigned long)); - else if (size_tflag) - sprintf(s, "%" PY_FORMAT_SIZE_T "u", - va_arg(vargs, size_t)); - else - sprintf(s, "%u", - va_arg(vargs, unsigned int)); - s += strlen(s); - break; - case 'i': - sprintf(s, "%i", va_arg(vargs, int)); - s += strlen(s); - break; - case 'x': - sprintf(s, "%x", va_arg(vargs, int)); - s += strlen(s); - break; - case 's': - p = va_arg(vargs, char*); - i = strlen(p); - if (n > 0 && i > n) - i = n; - Py_MEMCPY(s, p, i); - s += i; - break; - case 'p': - sprintf(s, "%p", va_arg(vargs, void*)); - /* %p is ill-defined: ensure leading 0x. */ - if (s[1] == 'X') - s[1] = 'x'; - else if (s[1] != 'x') { - memmove(s+2, s, strlen(s)+1); - s[0] = '0'; - s[1] = 'x'; - } - s += strlen(s); - break; - case '%': - *s++ = '%'; - break; - default: - strcpy(s, p); - s += strlen(s); - goto end; + 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++; } - } else - *s++ = *f; + + /* invalid format string: copy unformatted string and exit */ + WRITE_BYTES(p); + return _PyBytesWriter_Finish(&writer, s); + } } - end: - _PyBytes_Resize(&string, s - PyBytes_AS_STRING(string)); - return string; +#undef WRITE_BYTES + + return _PyBytesWriter_Finish(&writer, s); + + error: + _PyBytesWriter_Dealloc(&writer); + return NULL; } PyObject * @@ -361,6 +374,689 @@ PyBytes_FromFormat(const char *format, ...) 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; + Py_MEMCPY(str, p, len); + str += len; + return str; + } + + result = PyBytes_FromStringAndSize(p, len); + PyMem_Free(p); + *p_result = result; + return str; +} + +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_Size(arg) == 1) { + *p = PyBytes_AS_STRING(arg)[0]; + return 1; + } + else if (PyByteArray_Check(arg) && PyByteArray_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 * +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_CallFunctionObjArgs(func, NULL); + 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; + } + PyErr_Format(PyExc_TypeError, + "%%b requires bytes, 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 = strchr(fmt + 1, '%'); + if (pos != NULL) + len = pos - fmt; + else + len = format_len - (fmt - format); + assert(len != 0); + + Py_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; +#ifdef Py_DEBUG + char *before; +#endif + + fmt++; + 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; + } + if (c != '%') { + v = getnextarg(args, arglen, &argidx); + if (v == NULL) + goto error; + } + + if (fmtcnt < 0) { + /* last writer: disable writer overallocation */ + writer.overallocate = 0; + } + + sign = 0; + fill = ' '; + switch (c) { + case '%': + *res++ = '%'; + continue; + + 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: + assert(0 && "'type' not in [diuoxX]"); + 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; + } +#ifdef Py_DEBUG + 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 == '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 == 'x' || c == 'X')) { + assert(pbuf[0] == '0'); + assert(pbuf[1] == c); + *res++ = *pbuf++; + *res++ = *pbuf++; + } + } + + /* Copy bytes */ + Py_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) && c != '%') { + PyErr_SetString(PyExc_TypeError, + "not all arguments converted during bytes formatting"); + Py_XDECREF(temp); + goto error; + } + Py_XDECREF(temp); + +#ifdef Py_DEBUG + /* 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; +} + +/* =-= */ + static void bytes_dealloc(PyObject *op) { @@ -372,6 +1068,42 @@ bytes_dealloc(PyObject *op) 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--; /* substract 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, @@ -379,54 +1111,42 @@ PyObject *PyBytes_DecodeEscape(const char *s, const char *recode_encoding) { int c; - char *p, *buf; + char *p; const char *end; - PyObject *v; - Py_ssize_t newlen = recode_encoding ? 4*len:len; - v = PyBytes_FromStringAndSize((char *)NULL, newlen); - if (v == NULL) + _PyBytesWriter writer; + + _PyBytesWriter_Init(&writer); + + p = _PyBytesWriter_Alloc(&writer, len); + if (p == NULL) return NULL; - p = buf = PyBytes_AsString(v); + writer.overallocate = 1; + end = s + len; while (s < end) { if (*s != '\\') { non_esc: - if (recode_encoding && (*s & 0x80)) { - PyObject *u, *w; - char *r; - const char* t; - Py_ssize_t rn; - t = s; - /* Decode non-ASCII bytes as UTF-8. */ - while (t < end && (*t & 0x80)) t++; - u = PyUnicode_DecodeUTF8(s, t - s, errors); - if(!u) goto failed; - - /* Recode them in target encoding. */ - w = PyUnicode_AsEncodedString( - u, recode_encoding, errors); - Py_DECREF(u); - if (!w) goto failed; - - /* Append bytes to output buffer. */ - assert(PyBytes_Check(w)); - r = PyBytes_AS_STRING(w); - rn = PyBytes_GET_SIZE(w); - Py_MEMCPY(p, r, rn); - p += rn; - Py_DECREF(w); - s = t; - } else { + 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) { + if (s == end) { PyErr_SetString(PyExc_ValueError, "Trailing \\ in string"); goto failed; } + switch (*s++) { /* XXX This assumes ASCII! */ case '\n': break; @@ -451,28 +1171,18 @@ PyObject *PyBytes_DecodeEscape(const char *s, *p++ = c; break; case 'x': - if (s+1 < end && Py_ISXDIGIT(s[0]) && Py_ISXDIGIT(s[1])) { - unsigned int x = 0; - c = Py_CHARMASK(*s); - s++; - if (Py_ISDIGIT(c)) - x = c - '0'; - else if (Py_ISLOWER(c)) - x = 10 + c - 'a'; - else - x = 10 + c - 'A'; - x = x << 4; - c = Py_CHARMASK(*s); - s++; - if (Py_ISDIGIT(c)) - x += c - '0'; - else if (Py_ISLOWER(c)) - x += 10 + c - 'a'; - else - x += 10 + c - 'A'; - *p++ = x; - break; + 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 %d", @@ -494,6 +1204,7 @@ PyObject *PyBytes_DecodeEscape(const char *s, if (s < end && Py_ISXDIGIT(s[0])) s++; /* and a hexdigit */ break; + default: *p++ = '\\'; s--; @@ -501,11 +1212,11 @@ PyObject *PyBytes_DecodeEscape(const char *s, UTF-8 bytes may follow. */ } } - if (p-buf < newlen) - _PyBytes_Resize(&v, p - buf); - return v; + + return _PyBytesWriter_Finish(&writer, p); + failed: - Py_DECREF(v); + _PyBytesWriter_Dealloc(&writer); return NULL; } @@ -554,8 +1265,8 @@ PyBytes_AsStringAndSize(PyObject *obj, if (len != NULL) *len = PyBytes_GET_SIZE(obj); else if (strlen(*s) != (size_t)PyBytes_GET_SIZE(obj)) { - PyErr_SetString(PyExc_TypeError, - "expected bytes with no null"); + PyErr_SetString(PyExc_ValueError, + "embedded null byte"); return -1; } return 0; @@ -581,7 +1292,7 @@ PyBytes_Repr(PyObject *obj, int smartquotes) { PyBytesObject* op = (PyBytesObject*) obj; Py_ssize_t i, length = Py_SIZE(op); - size_t newsize, squotes, dquotes; + Py_ssize_t newsize, squotes, dquotes; PyObject *v; unsigned char quote, *s, *p; @@ -590,28 +1301,27 @@ PyBytes_Repr(PyObject *obj, int smartquotes) 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++; newsize++; break; - case '"': dquotes++; newsize++; break; + case '\'': squotes++; break; + case '"': dquotes++; break; case '\\': case '\t': case '\n': case '\r': - newsize += 2; break; /* \C */ + incr = 2; break; /* \C */ default: if (s[i] < ' ' || s[i] >= 0x7f) - newsize += 4; /* \xHH */ - else - newsize++; + incr = 4; /* \xHH */ } + if (newsize > PY_SSIZE_T_MAX - incr) + goto overflow; + newsize += incr; } quote = '\''; if (smartquotes && squotes && !dquotes) quote = '"'; - if (squotes && quote == '\'') + if (squotes && quote == '\'') { + if (newsize > PY_SSIZE_T_MAX - squotes) + goto overflow; newsize += squotes; - - if (newsize > (PY_SSIZE_T_MAX - sizeof(PyUnicodeObject) - 1)) { - PyErr_SetString(PyExc_OverflowError, - "bytes object is too large to make repr"); - return NULL; } v = PyUnicode_New(newsize, 127); @@ -643,6 +1353,11 @@ PyBytes_Repr(PyObject *obj, int smartquotes) *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 * @@ -678,8 +1393,8 @@ bytes_concat(PyObject *a, PyObject *b) va.len = -1; vb.len = -1; - if (_getbuffer(a, &va) < 0 || - _getbuffer(b, &vb) < 0) { + 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(a)->tp_name, Py_TYPE(b)->tp_name); goto done; @@ -749,7 +1464,7 @@ bytes_repeat(PyBytesObject *a, Py_ssize_t n) op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + nbytes); if (op == NULL) return PyErr_NoMemory(); - PyObject_INIT_VAR(op, &PyBytes_Type, size); + (void)PyObject_INIT_VAR(op, &PyBytes_Type, size); op->ob_shash = -1; op->ob_sval[size] = '\0'; if (Py_SIZE(a) == 1 && n > 0) { @@ -777,7 +1492,7 @@ bytes_contains(PyObject *self, PyObject *arg) Py_buffer varg; Py_ssize_t pos; PyErr_Clear(); - if (_getbuffer(arg, &varg) < 0) + if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0) return -1; pos = stringlib_find(PyBytes_AS_STRING(self), Py_SIZE(self), varg.buf, varg.len, 0); @@ -826,17 +1541,37 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op) Py_ssize_t len_a, len_b; Py_ssize_t min_len; PyObject *result; + int rc; /* Make sure both arguments are strings. */ if (!(PyBytes_Check(a) && PyBytes_Check(b))) { - if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE) && - (PyObject_IsInstance((PyObject*)a, - (PyObject*)&PyUnicode_Type) || - PyObject_IsInstance((PyObject*)b, - (PyObject*)&PyUnicode_Type))) { - if (PyErr_WarnEx(PyExc_BytesWarning, - "Comparison between bytes and string", 1)) + if (Py_BytesWarningFlag && (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; + } + } } result = Py_NotImplemented; } @@ -961,7 +1696,7 @@ bytes_subscript(PyBytesObject* self, PyObject* item) } else { PyErr_Format(PyExc_TypeError, - "byte indices must be integers, not %.200s", + "byte indices must be integers or slices, not %.200s", Py_TYPE(item)->tp_name); return NULL; } @@ -1001,37 +1736,34 @@ static PyBufferProcs bytes_as_buffer = { #define RIGHTSTRIP 1 #define BOTHSTRIP 2 -/* Arrays indexed by above */ -static const char *stripformat[] = {"|O:lstrip", "|O:rstrip", "|O:strip"}; +/*[clinic input] +bytes.split -#define STRIPNAME(i) (stripformat[i]+3) + 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. -PyDoc_STRVAR(split__doc__, -"B.split(sep=None, maxsplit=-1) -> list of bytes\n\ -\n\ -Return a list of the sections in B, using sep as the delimiter.\n\ -If sep is not specified or is None, B is split on ASCII whitespace\n\ -characters (space, tab, return, newline, formfeed, vertical tab).\n\ -If maxsplit is given, at most maxsplit splits are done."); +Return a list of the sections in the bytes, using sep as the delimiter. +[clinic start generated code]*/ static PyObject * -bytes_split(PyBytesObject *self, PyObject *args, PyObject *kwds) +bytes_split_impl(PyBytesObject*self, PyObject *sep, Py_ssize_t maxsplit) +/*[clinic end generated code: output=8bde44dacb36ef2e input=8b809b39074abbfa]*/ { - static char *kwlist[] = {"sep", "maxsplit", 0}; Py_ssize_t len = PyBytes_GET_SIZE(self), n; - Py_ssize_t maxsplit = -1; const char *s = PyBytes_AS_STRING(self), *sub; Py_buffer vsub; - PyObject *list, *subobj = Py_None; + PyObject *list; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:split", - kwlist, &subobj, &maxsplit)) - return NULL; if (maxsplit < 0) maxsplit = PY_SSIZE_T_MAX; - if (subobj == Py_None) + if (sep == Py_None) return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit); - if (_getbuffer(subobj, &vsub) < 0) + if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) return NULL; sub = vsub.buf; n = vsub.len; @@ -1041,89 +1773,84 @@ bytes_split(PyBytesObject *self, PyObject *args, PyObject *kwds) return list; } -PyDoc_STRVAR(partition__doc__, -"B.partition(sep) -> (head, sep, tail)\n\ -\n\ -Search for the separator sep in B, and return the part before it,\n\ -the separator itself, and the part after it. If the separator is not\n\ -found, returns B and two empty bytes objects."); +/*[clinic input] +bytes.partition -static PyObject * -bytes_partition(PyBytesObject *self, PyObject *sep_obj) -{ - const char *sep; - Py_ssize_t sep_len; + self: self(type="PyBytesObject *") + sep: Py_buffer + / - if (PyBytes_Check(sep_obj)) { - sep = PyBytes_AS_STRING(sep_obj); - sep_len = PyBytes_GET_SIZE(sep_obj); - } - else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len)) - return NULL; +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=bc855dc63ca949de]*/ +{ return stringlib_partition( (PyObject*) self, PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), - sep_obj, sep, sep_len + sep->obj, (const char *)sep->buf, sep->len ); } -PyDoc_STRVAR(rpartition__doc__, -"B.rpartition(sep) -> (head, sep, tail)\n\ -\n\ -Search for the separator sep in B, starting at the end of B,\n\ -and return the part before it, the separator itself, and the\n\ -part after it. If the separator is not found, returns two empty\n\ -bytes objects and B."); +/*[clinic input] +bytes.rpartition -static PyObject * -bytes_rpartition(PyBytesObject *self, PyObject *sep_obj) -{ - const char *sep; - Py_ssize_t sep_len; + self: self(type="PyBytesObject *") + sep: Py_buffer + / - if (PyBytes_Check(sep_obj)) { - sep = PyBytes_AS_STRING(sep_obj); - sep_len = PyBytes_GET_SIZE(sep_obj); - } - else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len)) - return NULL; +Partition the bytes into three parts using the given separator. + +This will search for the separator sep in the bytes, starting and 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=6588fff262a9170e]*/ +{ return stringlib_rpartition( (PyObject*) self, PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), - sep_obj, sep, sep_len + sep->obj, (const char *)sep->buf, sep->len ); } -PyDoc_STRVAR(rsplit__doc__, -"B.rsplit(sep=None, maxsplit=-1) -> list of bytes\n\ -\n\ -Return a list of the sections in B, using sep as the delimiter,\n\ -starting at the end of B and working to the front.\n\ -If sep is not given, B is split on ASCII whitespace characters\n\ -(space, tab, return, newline, formfeed, vertical tab).\n\ -If maxsplit is given, at most maxsplit splits are done."); +/*[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(PyBytesObject *self, PyObject *args, PyObject *kwds) +bytes_rsplit_impl(PyBytesObject*self, PyObject *sep, Py_ssize_t maxsplit) +/*[clinic end generated code: output=0b6570b977911d88 input=0f86c9f28f7d7b7b]*/ { - static char *kwlist[] = {"sep", "maxsplit", 0}; Py_ssize_t len = PyBytes_GET_SIZE(self), n; - Py_ssize_t maxsplit = -1; const char *s = PyBytes_AS_STRING(self), *sub; Py_buffer vsub; - PyObject *list, *subobj = Py_None; + PyObject *list; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|On:rsplit", - kwlist, &subobj, &maxsplit)) - return NULL; if (maxsplit < 0) maxsplit = PY_SSIZE_T_MAX; - if (subobj == Py_None) + if (sep == Py_None) return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit); - if (_getbuffer(subobj, &vsub) < 0) + if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) return NULL; sub = vsub.buf; n = vsub.len; @@ -1134,16 +1861,26 @@ bytes_rsplit(PyBytesObject *self, PyObject *args, PyObject *kwds) } -PyDoc_STRVAR(join__doc__, -"B.join(iterable_of_bytes) -> bytes\n\ -\n\ -Concatenate any number of bytes objects, with B in between each pair.\n\ -Example: b'.'.join([b'ab', b'pq', b'rs']) -> b'ab.pq.rs'."); +/*[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(PyObject *self, PyObject *iterable) +bytes_join(PyBytesObject*self, PyObject *iterable_of_bytes) +/*[clinic end generated code: output=634aff14764ff997 input=7fe377b95bd549d2]*/ { - return stringlib_bytes_join(self, iterable); + return stringlib_bytes_join((PyObject*)self, iterable_of_bytes); } PyObject * @@ -1151,7 +1888,7 @@ _PyBytes_Join(PyObject *sep, PyObject *x) { assert(sep != NULL && PyBytes_Check(sep)); assert(x != NULL); - return bytes_join(sep, x); + return bytes_join((PyBytesObject*)sep, x); } /* helper macro to fixup start/end slice values */ @@ -1176,7 +1913,7 @@ bytes_find_internal(PyBytesObject *self, PyObject *args, int dir) char byte; Py_buffer subbuf; const char *sub; - Py_ssize_t sub_len; + Py_ssize_t len, sub_len; Py_ssize_t start=0, end=PY_SSIZE_T_MAX; Py_ssize_t res; @@ -1185,7 +1922,7 @@ bytes_find_internal(PyBytesObject *self, PyObject *args, int dir) return -2; if (subobj) { - if (_getbuffer(subobj, &subbuf) < 0) + if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0) return -2; sub = subbuf.buf; @@ -1195,15 +1932,34 @@ bytes_find_internal(PyBytesObject *self, PyObject *args, int dir) sub = &byte; sub_len = 1; } + len = PyBytes_GET_SIZE(self); - if (dir > 0) - res = stringlib_find_slice( - PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), - sub, sub_len, start, end); - else - res = stringlib_rfind_slice( - PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), - sub, sub_len, start, end); + ADJUST_INDICES(start, end, len); + if (end - start < sub_len) + res = -1; + else if (sub_len == 1 +#ifndef HAVE_MEMRCHR + && dir > 0 +#endif + ) { + unsigned char needle = *sub; + int mode = (dir > 0) ? FAST_SEARCH : FAST_RSEARCH; + res = stringlib_fastsearch_memchr_1char( + PyBytes_AS_STRING(self) + start, end - start, + needle, needle, mode); + if (res >= 0) + res += start; + } + else { + if (dir > 0) + res = stringlib_find_slice( + PyBytes_AS_STRING(self), len, + sub, sub_len, start, end); + else + res = stringlib_rfind_slice( + PyBytes_AS_STRING(self), len, + sub, sub_len, start, end); + } if (subobj) PyBuffer_Release(&subbuf); @@ -1300,7 +2056,7 @@ do_xstrip(PyBytesObject *self, int striptype, PyObject *sepobj) Py_ssize_t seplen; Py_ssize_t i, j; - if (_getbuffer(sepobj, &vsep) < 0) + if (PyObject_GetBuffer(sepobj, &vsep, PyBUF_SIMPLE) != 0) return NULL; sep = vsep.buf; seplen = vsep.len; @@ -1362,62 +2118,69 @@ do_strip(PyBytesObject *self, int striptype) Py_LOCAL_INLINE(PyObject *) -do_argstrip(PyBytesObject *self, int striptype, PyObject *args) +do_argstrip(PyBytesObject *self, int striptype, PyObject *bytes) { - PyObject *sep = NULL; - - if (!PyArg_ParseTuple(args, stripformat[striptype], &sep)) - return NULL; - - if (sep != NULL && sep != Py_None) { - return do_xstrip(self, striptype, sep); + if (bytes != NULL && bytes != Py_None) { + return do_xstrip(self, striptype, bytes); } return do_strip(self, striptype); } +/*[clinic input] +bytes.strip + + self: self(type="PyBytesObject *") + 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]*/ -PyDoc_STRVAR(strip__doc__, -"B.strip([bytes]) -> bytes\n\ -\n\ -Strip leading and trailing bytes contained in the argument.\n\ -If the argument is omitted, strip leading and trailing ASCII whitespace."); static PyObject * -bytes_strip(PyBytesObject *self, PyObject *args) +bytes_strip_impl(PyBytesObject *self, PyObject *bytes) +/*[clinic end generated code: output=c7c228d3bd104a1b input=37daa5fad1395d95]*/ { - if (PyTuple_GET_SIZE(args) == 0) - return do_strip(self, BOTHSTRIP); /* Common case */ - else - return do_argstrip(self, BOTHSTRIP, args); + return do_argstrip(self, BOTHSTRIP, bytes); } +/*[clinic input] +bytes.lstrip + + self: self(type="PyBytesObject *") + 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]*/ -PyDoc_STRVAR(lstrip__doc__, -"B.lstrip([bytes]) -> bytes\n\ -\n\ -Strip leading bytes contained in the argument.\n\ -If the argument is omitted, strip leading ASCII whitespace."); static PyObject * -bytes_lstrip(PyBytesObject *self, PyObject *args) +bytes_lstrip_impl(PyBytesObject *self, PyObject *bytes) +/*[clinic end generated code: output=28602e586f524e82 input=88811b09dfbc2988]*/ { - if (PyTuple_GET_SIZE(args) == 0) - return do_strip(self, LEFTSTRIP); /* Common case */ - else - return do_argstrip(self, LEFTSTRIP, args); + return do_argstrip(self, LEFTSTRIP, bytes); } +/*[clinic input] +bytes.rstrip + + self: self(type="PyBytesObject *") + 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]*/ -PyDoc_STRVAR(rstrip__doc__, -"B.rstrip([bytes]) -> bytes\n\ -\n\ -Strip trailing bytes contained in the argument.\n\ -If the argument is omitted, strip trailing ASCII whitespace."); static PyObject * -bytes_rstrip(PyBytesObject *self, PyObject *args) +bytes_rstrip_impl(PyBytesObject *self, PyObject *bytes) +/*[clinic end generated code: output=547e3815c95447da input=8f93c9cd361f0140]*/ { - if (PyTuple_GET_SIZE(args) == 0) - return do_strip(self, RIGHTSTRIP); /* Common case */ - else - return do_argstrip(self, RIGHTSTRIP, args); + return do_argstrip(self, RIGHTSTRIP, bytes); } @@ -1445,7 +2208,7 @@ bytes_count(PyBytesObject *self, PyObject *args) return NULL; if (sub_obj) { - if (_getbuffer(sub_obj, &vsub) < 0) + if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0) return NULL; sub = vsub.buf; @@ -1469,92 +2232,119 @@ bytes_count(PyBytesObject *self, PyObject *args) } -PyDoc_STRVAR(translate__doc__, -"B.translate(table[, deletechars]) -> bytes\n\ -\n\ -Return a copy of B, where all characters occurring in the\n\ -optional argument deletechars are removed, and the remaining\n\ -characters have been mapped through the given translation\n\ -table, which must be a bytes object of length 256."); +/*[clinic input] +bytes.translate + + self: self(type="PyBytesObject *") + table: object + Translation table, which must be a bytes object of length 256. + [ + deletechars: object + ] + / + +Return a copy with each character mapped by the given translation table. + +All characters occurring in the optional argument deletechars are removed. +The remaining characters are mapped through the given translation table. +[clinic start generated code]*/ static PyObject * -bytes_translate(PyBytesObject *self, PyObject *args) +bytes_translate_impl(PyBytesObject *self, PyObject *table, int group_right_1, + PyObject *deletechars) +/*[clinic end generated code: output=233df850eb50bf8d input=d8fa5519d7cc4be7]*/ { char *input, *output; - const char *table; + 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=NULL; + const char *output_start, *del_table_chars=NULL; Py_ssize_t inlen, tablen, dellen = 0; PyObject *result; int trans_table[256]; - PyObject *tableobj, *delobj = NULL; - - if (!PyArg_UnpackTuple(args, "translate", 1, 2, - &tableobj, &delobj)) - return NULL; - if (PyBytes_Check(tableobj)) { - table = PyBytes_AS_STRING(tableobj); - tablen = PyBytes_GET_SIZE(tableobj); + if (PyBytes_Check(table)) { + table_chars = PyBytes_AS_STRING(table); + tablen = PyBytes_GET_SIZE(table); } - else if (tableobj == Py_None) { - table = NULL; + else if (table == Py_None) { + table_chars = NULL; tablen = 256; } - else if (PyObject_AsCharBuffer(tableobj, &table, &tablen)) - return NULL; + 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 (delobj != NULL) { - if (PyBytes_Check(delobj)) { - del_table = PyBytes_AS_STRING(delobj); - dellen = PyBytes_GET_SIZE(delobj); + 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 if (PyObject_AsCharBuffer(delobj, &del_table, &dellen)) - return NULL; } else { - del_table = NULL; + del_table_chars = NULL; dellen = 0; } inlen = PyBytes_GET_SIZE(input_obj); result = PyBytes_FromStringAndSize((char *)NULL, inlen); - if (result == NULL) + if (result == NULL) { + PyBuffer_Release(&del_table_view); + PyBuffer_Release(&table_view); return NULL; + } output_start = output = PyBytes_AsString(result); input = PyBytes_AS_STRING(input_obj); - if (dellen == 0 && table != NULL) { + 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[c])) != c) + if (Py_CHARMASK((*output++ = table_chars[c])) != c) changed = 1; } - if (changed || !PyBytes_CheckExact(input_obj)) - return result; - Py_DECREF(result); - Py_INCREF(input_obj); - return input_obj; + 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 == NULL) { + 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[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[i])] = -1; + trans_table[(int) Py_CHARMASK(del_table_chars[i])] = -1; + PyBuffer_Release(&del_table_view); for (i = inlen; --i >= 0; ) { c = Py_CHARMASK(*input++); @@ -1575,10 +2365,28 @@ bytes_translate(PyBytesObject *self, PyObject *args) } +/*[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(PyObject *null, PyObject *args) +bytes_maketrans_impl(Py_buffer *frm, Py_buffer *to) +/*[clinic end generated code: output=a36f6399d4b77f6f input=de7a8fc5632bb8f1]*/ { - return _Py_bytes_maketrans(args); + return _Py_bytes_maketrans(frm, to); } /* find and count characters and substrings */ @@ -2073,41 +2881,31 @@ replace(PyBytesObject *self, } } -PyDoc_STRVAR(replace__doc__, -"B.replace(old, new[, count]) -> bytes\n\ -\n\ -Return a copy of B with all occurrences of subsection\n\ -old replaced by new. If the optional argument count is\n\ -given, only first count occurances are replaced."); -static PyObject * -bytes_replace(PyBytesObject *self, PyObject *args) -{ - Py_ssize_t count = -1; - PyObject *from, *to; - const char *from_s, *to_s; - Py_ssize_t from_len, to_len; +/*[clinic input] +bytes.replace - if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count)) - return NULL; + 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. + / - if (PyBytes_Check(from)) { - from_s = PyBytes_AS_STRING(from); - from_len = PyBytes_GET_SIZE(from); - } - else if (PyObject_AsCharBuffer(from, &from_s, &from_len)) - return NULL; +Return a copy with all occurrences of substring old replaced by new. - if (PyBytes_Check(to)) { - to_s = PyBytes_AS_STRING(to); - to_len = PyBytes_GET_SIZE(to); - } - else if (PyObject_AsCharBuffer(to, &to_s, &to_len)) - return NULL; +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=403dc9d7a83c5a1d input=b2fbbf0bf04de8e5]*/ +{ return (PyObject *)replace((PyBytesObject *) self, - from_s, from_len, - to_s, to_len, count); + (const char *)old->buf, old->len, + (const char *)new->buf, new->len, count); } /** End DALKE **/ @@ -2122,6 +2920,7 @@ _bytes_tailmatch(PyBytesObject *self, PyObject *substr, Py_ssize_t start, { Py_ssize_t len = PyBytes_GET_SIZE(self); Py_ssize_t slen; + Py_buffer sub_view = {NULL, NULL}; const char* sub; const char* str; @@ -2129,8 +2928,12 @@ _bytes_tailmatch(PyBytesObject *self, PyObject *substr, Py_ssize_t start, sub = PyBytes_AS_STRING(substr); slen = PyBytes_GET_SIZE(substr); } - else if (PyObject_AsCharBuffer(substr, &sub, &slen)) - return -1; + else { + if (PyObject_GetBuffer(substr, &sub_view, PyBUF_SIMPLE) != 0) + return -1; + sub = sub_view.buf; + slen = sub_view.len; + } str = PyBytes_AS_STRING(self); ADJUST_INDICES(start, end, len); @@ -2138,17 +2941,25 @@ _bytes_tailmatch(PyBytesObject *self, PyObject *substr, Py_ssize_t start, if (direction < 0) { /* startswith */ if (start+slen > len) - return 0; + goto notfound; } else { /* endswith */ if (end-start < slen || start > len) - return 0; + goto notfound; if (end-slen > start) start = end - slen; } - if (end-start >= slen) - return ! memcmp(str+start, sub, 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; } @@ -2241,137 +3052,162 @@ bytes_endswith(PyBytesObject *self, PyObject *args) } -PyDoc_STRVAR(decode__doc__, -"B.decode(encoding='utf-8', errors='strict') -> str\n\ -\n\ -Decode B using the codec registered for encoding. Default encoding\n\ -is 'utf-8'. errors may be given to set a different error\n\ -handling scheme. Default is 'strict' meaning that encoding errors raise\n\ -a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\ -as well as any other name registerd with codecs.register_error that is\n\ -able to handle UnicodeDecodeErrors."); +/*[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(PyObject *self, PyObject *args, PyObject *kwargs) +bytes_decode_impl(PyBytesObject*self, const char *encoding, + const char *errors) +/*[clinic end generated code: output=2d2016ff8e0bb176 input=958174769d2a40ca]*/ { - const char *encoding = NULL; - const char *errors = NULL; - static char *kwlist[] = {"encoding", "errors", 0}; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors)) - return NULL; - return PyUnicode_FromEncodedObject(self, encoding, errors); + return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors); } -PyDoc_STRVAR(splitlines__doc__, -"B.splitlines([keepends]) -> list of lines\n\ -\n\ -Return a list of the lines in B, breaking at line boundaries.\n\ -Line breaks are not included in the resulting list unless keepends\n\ -is given and true."); +/*[clinic input] +bytes.splitlines -static PyObject* -bytes_splitlines(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"keepends", 0}; - int keepends = 0; + keepends: int(c_default="0") = False - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:splitlines", - kwlist, &keepends)) - return NULL; +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=995c3598f7833cad input=7f4aac67144f9944]*/ +{ return stringlib_splitlines( (PyObject*) self, PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), keepends ); } +/*[clinic input] +@classmethod +bytes.fromhex -PyDoc_STRVAR(fromhex_doc, -"bytes.fromhex(string) -> bytes\n\ -\n\ -Create a bytes object from a string of hexadecimal numbers.\n\ -Spaces between two numbers are accepted.\n\ -Example: bytes.fromhex('B9 01EF') -> b'\\xb9\\x01\\xef'."); + string: unicode + / -static int -hex_digit_to_int(Py_UCS4 c) +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]*/ { - if (c >= 128) - return -1; - if (Py_ISDIGIT(c)) - return c - '0'; - else { - if (Py_ISUPPER(c)) - c = Py_TOLOWER(c); - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - } - return -1; + return _PyBytes_FromHex(string, 0); } -static PyObject * -bytes_fromhex(PyObject *cls, PyObject *args) +PyObject* +_PyBytes_FromHex(PyObject *string, int use_bytearray) { - PyObject *newstring, *hexobj; char *buf; - Py_ssize_t hexlen, byteslen, i, j; - int top, bot; - void *data; - unsigned int kind; + Py_ssize_t hexlen, invalid_char; + unsigned int top, bot; + Py_UCS1 *str, *end; + _PyBytesWriter writer; + + _PyBytesWriter_Init(&writer); + writer.use_bytearray = use_bytearray; - if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj)) + assert(PyUnicode_Check(string)); + if (PyUnicode_READY(string)) return NULL; - assert(PyUnicode_Check(hexobj)); - if (PyUnicode_READY(hexobj)) + 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; - kind = PyUnicode_KIND(hexobj); - data = PyUnicode_DATA(hexobj); - hexlen = PyUnicode_GET_LENGTH(hexobj); - byteslen = hexlen/2; /* This overestimates if there are spaces */ - newstring = PyBytes_FromStringAndSize(NULL, byteslen); - if (!newstring) - return NULL; - buf = PyBytes_AS_STRING(newstring); - for (i = j = 0; i < hexlen; i += 2) { - /* skip over spaces in the input */ - while (PyUnicode_READ(kind, data, i) == ' ') - i++; - if (i >= hexlen) - break; - top = hex_digit_to_int(PyUnicode_READ(kind, data, i)); - bot = hex_digit_to_int(PyUnicode_READ(kind, data, i+1)); - if (top == -1 || bot == -1) { - PyErr_Format(PyExc_ValueError, - "non-hexadecimal number found in " - "fromhex() arg at position %zd", i); + end = str + hexlen; + while (str < end) { + /* skip over spaces in the input */ + if (*str == ' ') { + do { + str++; + } while (*str == ' '); + if (str >= end) + break; + } + + top = _PyLong_DigitValue[*str]; + if (top >= 16) { + invalid_char = str - PyUnicode_1BYTE_DATA(string); goto error; } - buf[j++] = (top << 4) + bot; + str++; + + bot = _PyLong_DigitValue[*str]; + if (bot >= 16) { + invalid_char = str - PyUnicode_1BYTE_DATA(string); + goto error; + } + str++; + + *buf++ = (unsigned char)((top << 4) + bot); } - if (j != byteslen && _PyBytes_Resize(&newstring, j) < 0) - goto error; - return newstring; + + return _PyBytesWriter_Finish(&writer, buf); error: - Py_XDECREF(newstring); + PyErr_Format(PyExc_ValueError, + "non-hexadecimal number found in " + "fromhex() arg at position %zd", invalid_char); + _PyBytesWriter_Dealloc(&writer); return NULL; } -PyDoc_STRVAR(sizeof__doc__, -"B.__sizeof__() -> size of B in memory, in bytes"); +PyDoc_STRVAR(hex__doc__, +"B.hex() -> string\n\ +\n\ +Create a string of hexadecimal numbers from a bytes object.\n\ +Example: b'\\xb9\\x01\\xef'.hex() -> 'b901ef'."); static PyObject * -bytes_sizeof(PyBytesObject *v) +bytes_hex(PyBytesObject *self) { - Py_ssize_t res; - res = PyBytesObject_SIZE + Py_SIZE(v) * Py_TYPE(v)->tp_itemsize; - return PyLong_FromSsize_t(res); + char* argbuf = PyBytes_AS_STRING(self); + Py_ssize_t arglen = PyBytes_GET_SIZE(self); + return _Py_strhex(argbuf, arglen); } - static PyObject * bytes_getnewargs(PyBytesObject *v) { @@ -2386,14 +3222,14 @@ bytes_methods[] = { _Py_capitalize__doc__}, {"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__}, {"count", (PyCFunction)bytes_count, METH_VARARGS, count__doc__}, - {"decode", (PyCFunction)bytes_decode, METH_VARARGS | METH_KEYWORDS, decode__doc__}, + BYTES_DECODE_METHODDEF {"endswith", (PyCFunction)bytes_endswith, METH_VARARGS, endswith__doc__}, {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS, expandtabs__doc__}, {"find", (PyCFunction)bytes_find, METH_VARARGS, find__doc__}, - {"fromhex", (PyCFunction)bytes_fromhex, METH_VARARGS|METH_CLASS, - fromhex_doc}, + BYTES_FROMHEX_METHODDEF + {"hex", (PyCFunction)bytes_hex, METH_NOARGS, hex__doc__}, {"index", (PyCFunction)bytes_index, METH_VARARGS, index__doc__}, {"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS, _Py_isalnum__doc__}, @@ -2409,39 +3245,52 @@ bytes_methods[] = { _Py_istitle__doc__}, {"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS, _Py_isupper__doc__}, - {"join", (PyCFunction)bytes_join, METH_O, join__doc__}, + BYTES_JOIN_METHODDEF {"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__}, {"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__}, - {"lstrip", (PyCFunction)bytes_lstrip, METH_VARARGS, lstrip__doc__}, - {"maketrans", (PyCFunction)bytes_maketrans, METH_VARARGS|METH_STATIC, - _Py_maketrans__doc__}, - {"partition", (PyCFunction)bytes_partition, METH_O, partition__doc__}, - {"replace", (PyCFunction)bytes_replace, METH_VARARGS, replace__doc__}, + BYTES_LSTRIP_METHODDEF + BYTES_MAKETRANS_METHODDEF + BYTES_PARTITION_METHODDEF + BYTES_REPLACE_METHODDEF {"rfind", (PyCFunction)bytes_rfind, METH_VARARGS, rfind__doc__}, {"rindex", (PyCFunction)bytes_rindex, METH_VARARGS, rindex__doc__}, {"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__}, - {"rpartition", (PyCFunction)bytes_rpartition, METH_O, - rpartition__doc__}, - {"rsplit", (PyCFunction)bytes_rsplit, METH_VARARGS | METH_KEYWORDS, rsplit__doc__}, - {"rstrip", (PyCFunction)bytes_rstrip, METH_VARARGS, rstrip__doc__}, - {"split", (PyCFunction)bytes_split, METH_VARARGS | METH_KEYWORDS, split__doc__}, - {"splitlines", (PyCFunction)bytes_splitlines, METH_VARARGS | METH_KEYWORDS, - splitlines__doc__}, + BYTES_RPARTITION_METHODDEF + BYTES_RSPLIT_METHODDEF + BYTES_RSTRIP_METHODDEF + BYTES_SPLIT_METHODDEF + BYTES_SPLITLINES_METHODDEF {"startswith", (PyCFunction)bytes_startswith, METH_VARARGS, startswith__doc__}, - {"strip", (PyCFunction)bytes_strip, METH_VARARGS, strip__doc__}, + BYTES_STRIP_METHODDEF {"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS, _Py_swapcase__doc__}, {"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__}, - {"translate", (PyCFunction)bytes_translate, METH_VARARGS, - translate__doc__}, + BYTES_TRANSLATE_METHODDEF {"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__}, {"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__}, - {"__sizeof__", (PyCFunction)bytes_sizeof, METH_NOARGS, - sizeof__doc__}, {NULL, NULL} /* sentinel */ }; +static PyObject * +bytes_mod(PyObject *self, PyObject *args) +{ + if (self == NULL || !PyBytes_Check(self)) { + PyErr_BadInternalCall(); + return NULL; + } + + return _PyBytes_FormatEx(PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), + args, 0); +} + +static PyNumberMethods bytes_as_number = { + 0, /*nb_add*/ + 0, /*nb_subtract*/ + 0, /*nb_multiply*/ + bytes_mod, /*nb_remainder*/ +}; + static PyObject * str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); @@ -2469,7 +3318,7 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) "argument"); return NULL; } - return PyBytes_FromString(""); + return PyBytes_FromStringAndSize(NULL, 0); } if (PyUnicode_Check(x)) { @@ -2486,6 +3335,13 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return new; } + /* If it's not unicode, there can't be encoding or errors */ + if (encoding != NULL || errors != NULL) { + PyErr_SetString(PyExc_TypeError, + "encoding or errors without a string argument"); + return NULL; + } + /* 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. */ @@ -2519,119 +3375,104 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } else { - new = PyBytes_FromStringAndSize(NULL, size); + new = _PyBytes_FromSize(size, 1); if (new == NULL) return NULL; - if (size > 0) - memset(((PyBytesObject*)new)->ob_sval, 0, size); return new; } - /* If it's not unicode, there can't be encoding or errors */ - if (encoding != NULL || errors != NULL) { - PyErr_SetString(PyExc_TypeError, - "encoding or errors without a string argument"); - return NULL; - } - return PyBytes_FromObject(x); } -PyObject * -PyBytes_FromObject(PyObject *x) +static PyObject* +_PyBytes_FromBuffer(PyObject *x) { - PyObject *new, *it; - Py_ssize_t i, size; + PyObject *new; + Py_buffer view; - if (x == NULL) { - PyErr_BadInternalCall(); + if (PyObject_GetBuffer(x, &view, PyBUF_FULL_RO) < 0) return NULL; - } - if (PyBytes_CheckExact(x)) { - Py_INCREF(x); - return x; - } + 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; - /* Use the modern buffer interface */ - if (PyObject_CheckBuffer(x)) { - 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; - } - if (PyUnicode_Check(x)) { - PyErr_SetString(PyExc_TypeError, - "cannot convert unicode object to bytes"); - return NULL; - } +fail: + Py_XDECREF(new); + PyBuffer_Release(&view); + return NULL; +} - if (PyList_CheckExact(x)) { - new = PyBytes_FromStringAndSize(NULL, Py_SIZE(x)); - if (new == NULL) - return NULL; - for (i = 0; i < Py_SIZE(x); i++) { - Py_ssize_t value = PyNumber_AsSsize_t( - PyList_GET_ITEM(x, i), PyExc_ValueError); - if (value == -1 && PyErr_Occurred()) { - Py_DECREF(new); - return NULL; - } - if (value < 0 || value >= 256) { - PyErr_SetString(PyExc_ValueError, - "bytes must be in range(0, 256)"); - Py_DECREF(new); - return NULL; - } - ((PyBytesObject *)new)->ob_sval[i] = (char) value; - } - return new; - } - if (PyTuple_CheckExact(x)) { - new = PyBytes_FromStringAndSize(NULL, Py_SIZE(x)); - if (new == NULL) - return NULL; - for (i = 0; i < Py_SIZE(x); i++) { - Py_ssize_t value = PyNumber_AsSsize_t( - PyTuple_GET_ITEM(x, i), PyExc_ValueError); - if (value == -1 && PyErr_Occurred()) { - Py_DECREF(new); - return NULL; - } - if (value < 0 || value >= 256) { - PyErr_SetString(PyExc_ValueError, - "bytes must be in range(0, 256)"); - Py_DECREF(new); - return NULL; - } - ((PyBytesObject *)new)->ob_sval[i] = (char) value; - } - return new; - } +#define _PyBytes_FROM_LIST_BODY(x, GET_ITEM) \ + do { \ + PyObject *bytes; \ + Py_ssize_t i; \ + Py_ssize_t value; \ + char *str; \ + PyObject *item; \ + \ + bytes = PyBytes_FromStringAndSize(NULL, Py_SIZE(x)); \ + if (bytes == NULL) \ + return NULL; \ + str = ((PyBytesObject *)bytes)->ob_sval; \ + \ + for (i = 0; i < Py_SIZE(x); i++) { \ + item = GET_ITEM((x), i); \ + value = PyNumber_AsSsize_t(item, PyExc_ValueError); \ + 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; \ + } while (0) + +static PyObject* +_PyBytes_FromList(PyObject *x) +{ + _PyBytes_FROM_LIST_BODY(x, PyList_GET_ITEM); +} + +static PyObject* +_PyBytes_FromTuple(PyObject *x) +{ + _PyBytes_FROM_LIST_BODY(x, PyTuple_GET_ITEM); +} + +static PyObject * +_PyBytes_FromIterator(PyObject *x) +{ + char *str; + PyObject *it; + Py_ssize_t i, size; + _PyBytesWriter writer; + + _PyBytesWriter_Init(&writer); /* For iterator version, create a string object and resize as needed */ size = PyObject_LengthHint(x, 64); if (size == -1 && PyErr_Occurred()) return NULL; - /* Allocate an extra byte to prevent PyBytes_FromStringAndSize() from - returning a shared empty bytes string. This required because we - want to call _PyBytes_Resize() the returned object, which we can - only do on bytes objects with refcount == 1. */ - size += 1; - new = PyBytes_FromStringAndSize(NULL, size); - if (new == NULL) + + str = _PyBytesWriter_Alloc(&writer, size); + if (str == NULL) return NULL; + writer.overallocate = 1; + size = writer.allocated; /* Get the iterator */ it = PyObject_GetIter(x); @@ -2666,24 +3507,55 @@ PyBytes_FromObject(PyObject *x) /* Append the byte */ if (i >= size) { - size = 2 * size + 1; - if (_PyBytes_Resize(&new, size) < 0) - goto error; + str = _PyBytesWriter_Resize(&writer, str, size+1); + if (str == NULL) + return NULL; + size = writer.allocated; } - ((PyBytesObject *)new)->ob_sval[i] = (char) value; + *str++ = (char) value; } - _PyBytes_Resize(&new, i); - - /* Clean up and return success */ Py_DECREF(it); - return new; + + return _PyBytesWriter_Finish(&writer, str); error: + _PyBytesWriter_Dealloc(&writer); Py_XDECREF(it); - Py_XDECREF(new); return NULL; } +PyObject * +PyBytes_FromObject(PyObject *x) +{ + 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)) { + PyErr_SetString(PyExc_TypeError, + "cannot convert unicode object to bytes"); + return NULL; + } + + return _PyBytes_FromIterator(x); +} + static PyObject * str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -2733,7 +3605,7 @@ PyTypeObject PyBytes_Type = { 0, /* tp_setattr */ 0, /* tp_reserved */ (reprfunc)bytes_repr, /* tp_repr */ - 0, /* tp_as_number */ + &bytes_as_number, /* tp_as_number */ &bytes_as_sequence, /* tp_as_sequence */ &bytes_as_mapping, /* tp_as_mapping */ (hashfunc)bytes_hash, /* tp_hash */ @@ -2768,7 +3640,6 @@ PyTypeObject PyBytes_Type = { void PyBytes_Concat(PyObject **pv, PyObject *w) { - PyObject *v; assert(pv != NULL); if (*pv == NULL) return; @@ -2776,9 +3647,45 @@ PyBytes_Concat(PyObject **pv, PyObject *w) Py_CLEAR(*pv); return; } - v = bytes_concat(*pv, w); - Py_DECREF(*pv); - *pv = v; + + if (Py_REFCNT(*pv) == 1 && PyBytes_CheckExact(*pv)) { + /* Only one reference, so we can resize in place */ + Py_ssize_t oldsize; + Py_buffer wb; + + wb.len = -1; + 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_DECREF(*pv); + *pv = v; + } } void @@ -2789,14 +3696,14 @@ PyBytes_ConcatAndDel(PyObject **pv, PyObject *w) } -/* The following function breaks the notion that strings are immutable: - it changes the size of a string. We get away with this only if there +/* 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 string object and destroying the old one, only - more efficiently. In any case, don't use this if the string may + 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 string, the original - string object at *pv is deallocated, *pv is set to NULL, an "out of + 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 @@ -2819,7 +3726,7 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) _Py_DEC_REFTOTAL; _Py_ForgetReference(v); *pv = (PyObject *) - PyObject_REALLOC((char *)v, PyBytesObject_SIZE + newsize); + PyObject_REALLOC(v, PyBytesObject_SIZE + newsize); if (*pv == NULL) { PyObject_Del(v); PyErr_NoMemory(); @@ -2924,9 +3831,13 @@ striter_setstate(striterobject *it, PyObject *state) Py_ssize_t index = PyLong_AsSsize_t(state); if (index == -1 && PyErr_Occurred()) return NULL; - if (index < 0) - index = 0; - it->it_index = index; + 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; } @@ -2993,3 +3904,277 @@ bytes_iter(PyObject *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)); +#ifdef Py_DEBUG + memset(writer->small_buffer, 0xCB, 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; +} + +Py_LOCAL_INLINE(void) +_PyBytesWriter_CheckConsistency(_PyBytesWriter *writer, char *str) +{ +#ifdef Py_DEBUG + 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); +#endif +} + +void* +_PyBytesWriter_Resize(_PyBytesWriter *writer, void *str, Py_ssize_t size) +{ + Py_ssize_t allocated, pos; + + _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); + Py_MEMCPY(dest, + writer->small_buffer, + pos); + } + + writer->use_small_buffer = 0; +#ifdef Py_DEBUG + memset(writer->small_buffer, 0xDB, sizeof(writer->small_buffer)); +#endif + } + writer->allocated = allocated; + + str = _PyBytesWriter_AsString(writer) + pos; + _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; + + _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; +#ifdef Py_DEBUG + 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; + + _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) { + 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; + + Py_MEMCPY(str, bytes, size); + str += size; + + return str; +} diff --git a/Objects/classobject.c b/Objects/classobject.c index 272f575dbac8..5e8ac59df25d 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -15,6 +15,7 @@ static int numfree = 0; #endif _Py_IDENTIFIER(__name__); +_Py_IDENTIFIER(__qualname__); PyObject * PyMethod_Function(PyObject *im) @@ -52,7 +53,7 @@ PyMethod_New(PyObject *func, PyObject *self) im = free_list; if (im != NULL) { free_list = (PyMethodObject *)(im->im_self); - PyObject_INIT(im, &PyMethod_Type); + (void)PyObject_INIT(im, &PyMethod_Type); numfree--; } else { @@ -243,51 +244,33 @@ method_repr(PyMethodObject *a) { PyObject *self = a->im_self; PyObject *func = a->im_func; - PyObject *klass; - PyObject *funcname = NULL ,*klassname = NULL, *result = NULL; - char *defname = "?"; + PyObject *funcname = NULL, *result = NULL; + const char *defname = "?"; - if (self == NULL) { - PyErr_BadInternalCall(); - return NULL; - } - klass = (PyObject*)Py_TYPE(self); - - funcname = _PyObject_GetAttrId(func, &PyId___name__); + funcname = _PyObject_GetAttrId(func, &PyId___qualname__); if (funcname == NULL) { if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return NULL; PyErr_Clear(); - } - else if (!PyUnicode_Check(funcname)) { - Py_DECREF(funcname); - funcname = NULL; - } - if (klass == NULL) - klassname = NULL; - else { - klassname = _PyObject_GetAttrId(klass, &PyId___name__); - if (klassname == NULL) { - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { - Py_XDECREF(funcname); + funcname = _PyObject_GetAttrId(func, &PyId___name__); + if (funcname == NULL) { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) return NULL; - } PyErr_Clear(); } - else if (!PyUnicode_Check(klassname)) { - Py_DECREF(klassname); - klassname = NULL; - } + } + + if (funcname != NULL && !PyUnicode_Check(funcname)) { + Py_DECREF(funcname); + funcname = NULL; } /* XXX Shouldn't use repr()/%R here! */ - result = PyUnicode_FromFormat("", - klassname, defname, + result = PyUnicode_FromFormat("", funcname, defname, self); Py_XDECREF(funcname); - Py_XDECREF(klassname); return result; } diff --git a/Objects/clinic/bytearrayobject.c.h b/Objects/clinic/bytearrayobject.c.h new file mode 100644 index 000000000000..e87a22127cfc --- /dev/null +++ b/Objects/clinic/bytearrayobject.c.h @@ -0,0 +1,698 @@ +/*[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(table, [deletechars])\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 deletechars are removed.\n" +"The remaining characters are mapped through the given translation table."); + +#define BYTEARRAY_TRANSLATE_METHODDEF \ + {"translate", (PyCFunction)bytearray_translate, METH_VARARGS, bytearray_translate__doc__}, + +static PyObject * +bytearray_translate_impl(PyByteArrayObject *self, PyObject *table, + int group_right_1, PyObject *deletechars); + +static PyObject * +bytearray_translate(PyByteArrayObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *table; + int group_right_1 = 0; + PyObject *deletechars = NULL; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O:translate", &table)) + goto exit; + break; + case 2: + if (!PyArg_ParseTuple(args, "OO:translate", &table, &deletechars)) + goto exit; + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "bytearray.translate requires 1 to 2 arguments"); + goto exit; + } + return_value = bytearray_translate_impl(self, table, group_right_1, 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)bytearray_maketrans, METH_VARARGS|METH_STATIC, bytearray_maketrans__doc__}, + +static PyObject * +bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to); + +static PyObject * +bytearray_maketrans(void *null, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer frm = {NULL, NULL}; + Py_buffer to = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, "y*y*:maketrans", + &frm, &to)) + 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)bytearray_replace, METH_VARARGS, 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 *args) +{ + PyObject *return_value = NULL; + Py_buffer old = {NULL, NULL}; + Py_buffer new = {NULL, NULL}; + Py_ssize_t count = -1; + + if (!PyArg_ParseTuple(args, "y*y*|n:replace", + &old, &new, &count)) + goto exit; + 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)bytearray_split, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"sep", "maxsplit", NULL}; + PyObject *sep = Py_None; + Py_ssize_t maxsplit = -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|On:split", _keywords, + &sep, &maxsplit)) + goto exit; + 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.\n" +"\n" +"If the separator is not found, returns a 3-tuple containing the original\n" +"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 bytes into three parts using the given separator.\n" +"\n" +"This will search for the separator sep in the bytearray, starting and 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.\n" +"\n" +"If the separator is not found, returns a 3-tuple containing two empty bytearray\n" +"objects and 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)bytearray_rsplit, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"sep", "maxsplit", NULL}; + PyObject *sep = Py_None; + Py_ssize_t maxsplit = -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|On:rsplit", _keywords, + &sep, &maxsplit)) + goto exit; + 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)bytearray_insert, METH_VARARGS, bytearray_insert__doc__}, + +static PyObject * +bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item); + +static PyObject * +bytearray_insert(PyByteArrayObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t index; + int item; + + if (!PyArg_ParseTuple(args, "nO&:insert", + &index, _getbytevalue, &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 (!PyArg_Parse(arg, "O&:append", _getbytevalue, &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)bytearray_pop, METH_VARARGS, bytearray_pop__doc__}, + +static PyObject * +bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index); + +static PyObject * +bytearray_pop(PyByteArrayObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + Py_ssize_t index = -1; + + if (!PyArg_ParseTuple(args, "|n:pop", + &index)) + goto exit; + 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 (!PyArg_Parse(arg, "O&:remove", _getbytevalue, &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)bytearray_strip, METH_VARARGS, bytearray_strip__doc__}, + +static PyObject * +bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes); + +static PyObject * +bytearray_strip(PyByteArrayObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!PyArg_UnpackTuple(args, "strip", + 0, 1, + &bytes)) + goto exit; + 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)bytearray_lstrip, METH_VARARGS, bytearray_lstrip__doc__}, + +static PyObject * +bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes); + +static PyObject * +bytearray_lstrip(PyByteArrayObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!PyArg_UnpackTuple(args, "lstrip", + 0, 1, + &bytes)) + goto exit; + 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)bytearray_rstrip, METH_VARARGS, bytearray_rstrip__doc__}, + +static PyObject * +bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes); + +static PyObject * +bytearray_rstrip(PyByteArrayObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!PyArg_UnpackTuple(args, "rstrip", + 0, 1, + &bytes)) + goto exit; + 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)bytearray_decode, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"encoding", "errors", NULL}; + const char *encoding = NULL; + const char *errors = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", _keywords, + &encoding, &errors)) + goto exit; + 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)bytearray_splitlines, METH_VARARGS|METH_KEYWORDS, bytearray_splitlines__doc__}, + +static PyObject * +bytearray_splitlines_impl(PyByteArrayObject *self, int keepends); + +static PyObject * +bytearray_splitlines(PyByteArrayObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"keepends", NULL}; + int keepends = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:splitlines", _keywords, + &keepends)) + goto exit; + 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(PyObject*cls, PyObject *string); + +static PyObject * +bytearray_fromhex(PyTypeObject *cls, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *string; + + if (!PyArg_Parse(arg, "U:fromhex", &string)) + goto exit; + return_value = bytearray_fromhex_impl((PyObject*)cls, string); + +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)bytearray_reduce_ex, METH_VARARGS, bytearray_reduce_ex__doc__}, + +static PyObject * +bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto); + +static PyObject * +bytearray_reduce_ex(PyByteArrayObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + int proto = 0; + + if (!PyArg_ParseTuple(args, "|i:__reduce_ex__", + &proto)) + goto exit; + 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=966c15ff22c5e243 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/bytesobject.c.h b/Objects/clinic/bytesobject.c.h new file mode 100644 index 000000000000..5a1a5e91a6a2 --- /dev/null +++ b/Objects/clinic/bytesobject.c.h @@ -0,0 +1,487 @@ +/*[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)bytes_split, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"sep", "maxsplit", NULL}; + PyObject *sep = Py_None; + Py_ssize_t maxsplit = -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|On:split", _keywords, + &sep, &maxsplit)) + goto exit; + 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 (!PyArg_Parse(arg, "y*:partition", &sep)) + 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 and 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 (!PyArg_Parse(arg, "y*:rpartition", &sep)) + 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)bytes_rsplit, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"sep", "maxsplit", NULL}; + PyObject *sep = Py_None; + Py_ssize_t maxsplit = -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|On:rsplit", _keywords, + &sep, &maxsplit)) + goto exit; + 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)bytes_strip, METH_VARARGS, bytes_strip__doc__}, + +static PyObject * +bytes_strip_impl(PyBytesObject *self, PyObject *bytes); + +static PyObject * +bytes_strip(PyBytesObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!PyArg_UnpackTuple(args, "strip", + 0, 1, + &bytes)) + goto exit; + 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)bytes_lstrip, METH_VARARGS, bytes_lstrip__doc__}, + +static PyObject * +bytes_lstrip_impl(PyBytesObject *self, PyObject *bytes); + +static PyObject * +bytes_lstrip(PyBytesObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!PyArg_UnpackTuple(args, "lstrip", + 0, 1, + &bytes)) + goto exit; + 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)bytes_rstrip, METH_VARARGS, bytes_rstrip__doc__}, + +static PyObject * +bytes_rstrip_impl(PyBytesObject *self, PyObject *bytes); + +static PyObject * +bytes_rstrip(PyBytesObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *bytes = Py_None; + + if (!PyArg_UnpackTuple(args, "rstrip", + 0, 1, + &bytes)) + goto exit; + return_value = bytes_rstrip_impl(self, bytes); + +exit: + return return_value; +} + +PyDoc_STRVAR(bytes_translate__doc__, +"translate(table, [deletechars])\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 deletechars are removed.\n" +"The remaining characters are mapped through the given translation table."); + +#define BYTES_TRANSLATE_METHODDEF \ + {"translate", (PyCFunction)bytes_translate, METH_VARARGS, bytes_translate__doc__}, + +static PyObject * +bytes_translate_impl(PyBytesObject *self, PyObject *table, int group_right_1, + PyObject *deletechars); + +static PyObject * +bytes_translate(PyBytesObject *self, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *table; + int group_right_1 = 0; + PyObject *deletechars = NULL; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O:translate", &table)) + goto exit; + break; + case 2: + if (!PyArg_ParseTuple(args, "OO:translate", &table, &deletechars)) + goto exit; + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "bytes.translate requires 1 to 2 arguments"); + goto exit; + } + return_value = bytes_translate_impl(self, table, group_right_1, 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)bytes_maketrans, METH_VARARGS|METH_STATIC, bytes_maketrans__doc__}, + +static PyObject * +bytes_maketrans_impl(Py_buffer *frm, Py_buffer *to); + +static PyObject * +bytes_maketrans(void *null, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer frm = {NULL, NULL}; + Py_buffer to = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, "y*y*:maketrans", + &frm, &to)) + 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)bytes_replace, METH_VARARGS, 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 *args) +{ + PyObject *return_value = NULL; + Py_buffer old = {NULL, NULL}; + Py_buffer new = {NULL, NULL}; + Py_ssize_t count = -1; + + if (!PyArg_ParseTuple(args, "y*y*|n:replace", + &old, &new, &count)) + goto exit; + 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)bytes_decode, METH_VARARGS|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 *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"encoding", "errors", NULL}; + const char *encoding = NULL; + const char *errors = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", _keywords, + &encoding, &errors)) + goto exit; + 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)bytes_splitlines, METH_VARARGS|METH_KEYWORDS, bytes_splitlines__doc__}, + +static PyObject * +bytes_splitlines_impl(PyBytesObject*self, int keepends); + +static PyObject * +bytes_splitlines(PyBytesObject*self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"keepends", NULL}; + int keepends = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:splitlines", _keywords, + &keepends)) + goto exit; + 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 (!PyArg_Parse(arg, "U:fromhex", &string)) + goto exit; + return_value = bytes_fromhex_impl(type, string); + +exit: + return return_value; +} +/*[clinic end generated code: output=bd0ce8f25d7e18f4 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/dictobject.c.h b/Objects/clinic/dictobject.c.h new file mode 100644 index 000000000000..5288b9a8b320 --- /dev/null +++ b/Objects/clinic/dictobject.c.h @@ -0,0 +1,42 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(dict_fromkeys__doc__, +"fromkeys($type, iterable, value=None, /)\n" +"--\n" +"\n" +"Returns a new dict with keys from iterable and values equal to value."); + +#define DICT_FROMKEYS_METHODDEF \ + {"fromkeys", (PyCFunction)dict_fromkeys, METH_VARARGS|METH_CLASS, dict_fromkeys__doc__}, + +static PyObject * +dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value); + +static PyObject * +dict_fromkeys(PyTypeObject *type, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *iterable; + PyObject *value = Py_None; + + if (!PyArg_UnpackTuple(args, "fromkeys", + 1, 2, + &iterable, &value)) + goto exit; + 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 D has a key k, else False."); + +#define DICT___CONTAINS___METHODDEF \ + {"__contains__", (PyCFunction)dict___contains__, METH_O|METH_COEXIST, dict___contains____doc__}, +/*[clinic end generated code: output=fe74d676332fdba6 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/unicodeobject.c.h b/Objects/clinic/unicodeobject.c.h new file mode 100644 index 000000000000..d42a70002a9c --- /dev/null +++ b/Objects/clinic/unicodeobject.c.h @@ -0,0 +1,41 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(unicode_maketrans__doc__, +"maketrans(x, y=None, z=None, /)\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)unicode_maketrans, METH_VARARGS|METH_STATIC, unicode_maketrans__doc__}, + +static PyObject * +unicode_maketrans_impl(PyObject *x, PyObject *y, PyObject *z); + +static PyObject * +unicode_maketrans(void *null, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *x; + PyObject *y = NULL; + PyObject *z = NULL; + + if (!PyArg_ParseTuple(args, "O|UU:maketrans", + &x, &y, &z)) + goto exit; + return_value = unicode_maketrans_impl(x, y, z); + +exit: + return return_value; +} +/*[clinic end generated code: output=94affdff5b2daff5 input=a9049054013a1b77]*/ diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 60a388fa2415..dc1212e4b798 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -13,7 +13,7 @@ static Py_complex c_1 = {1., 0.}; Py_complex -c_sum(Py_complex a, Py_complex b) +_Py_c_sum(Py_complex a, Py_complex b) { Py_complex r; r.real = a.real + b.real; @@ -22,7 +22,7 @@ c_sum(Py_complex a, Py_complex b) } Py_complex -c_diff(Py_complex a, Py_complex b) +_Py_c_diff(Py_complex a, Py_complex b) { Py_complex r; r.real = a.real - b.real; @@ -31,7 +31,7 @@ c_diff(Py_complex a, Py_complex b) } Py_complex -c_neg(Py_complex a) +_Py_c_neg(Py_complex a) { Py_complex r; r.real = -a.real; @@ -40,7 +40,7 @@ c_neg(Py_complex a) } Py_complex -c_prod(Py_complex a, Py_complex b) +_Py_c_prod(Py_complex a, Py_complex b) { Py_complex r; r.real = a.real*b.real - a.imag*b.imag; @@ -49,7 +49,7 @@ c_prod(Py_complex a, Py_complex b) } Py_complex -c_quot(Py_complex a, Py_complex b) +_Py_c_quot(Py_complex a, Py_complex b) { /****************************************************************** This was the original algorithm. It's grossly prone to spurious @@ -78,7 +78,7 @@ c_quot(Py_complex a, Py_complex b) 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) { + if (abs_breal >= abs_bimag) { /* divide tops and bottom by b.real */ if (abs_breal == 0.0) { errno = EDOM; @@ -91,7 +91,7 @@ c_quot(Py_complex a, Py_complex b) r.imag = (a.imag - a.real * ratio) / denom; } } - else { + 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; @@ -99,11 +99,15 @@ c_quot(Py_complex a, Py_complex b) 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; } Py_complex -c_pow(Py_complex a, Py_complex b) +_Py_c_pow(Py_complex a, Py_complex b) { Py_complex r; double vabs,len,at,phase; @@ -141,9 +145,9 @@ c_powu(Py_complex x, long n) p = x; while (mask > 0 && n >= mask) { if (n & mask) - r = c_prod(r,p); + r = _Py_c_prod(r,p); mask <<= 1; - p = c_prod(p,p); + p = _Py_c_prod(p,p); } return r; } @@ -156,17 +160,17 @@ c_powi(Py_complex x, long n) if (n > 100 || n < -100) { cn.real = (double) n; cn.imag = 0.; - return c_pow(x,cn); + return _Py_c_pow(x,cn); } else if (n > 0) return c_powu(x,n); else - return c_quot(c_1,c_powu(x,-n)); + return _Py_c_quot(c_1, c_powu(x,-n)); } double -c_abs(Py_complex z) +_Py_c_abs(Py_complex z) { /* sets errno = ERANGE on overflow; otherwise errno = 0 */ double result; @@ -217,7 +221,7 @@ PyComplex_FromCComplex(Py_complex cval) op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject)); if (op == NULL) return PyErr_NoMemory(); - PyObject_INIT(op, &PyComplex_Type); + (void)PyObject_INIT(op, &PyComplex_Type); op->cval = cval; return (PyObject *) op; } @@ -441,7 +445,7 @@ complex_add(PyObject *v, PyObject *w) TO_COMPLEX(v, a); TO_COMPLEX(w, b); PyFPE_START_PROTECT("complex_add", return 0) - result = c_sum(a, b); + result = _Py_c_sum(a, b); PyFPE_END_PROTECT(result) return PyComplex_FromCComplex(result); } @@ -454,7 +458,7 @@ complex_sub(PyObject *v, PyObject *w) TO_COMPLEX(v, a); TO_COMPLEX(w, b); PyFPE_START_PROTECT("complex_sub", return 0) - result = c_diff(a, b); + result = _Py_c_diff(a, b); PyFPE_END_PROTECT(result) return PyComplex_FromCComplex(result); } @@ -467,7 +471,7 @@ complex_mul(PyObject *v, PyObject *w) TO_COMPLEX(v, a); TO_COMPLEX(w, b); PyFPE_START_PROTECT("complex_mul", return 0) - result = c_prod(a, b); + result = _Py_c_prod(a, b); PyFPE_END_PROTECT(result) return PyComplex_FromCComplex(result); } @@ -481,7 +485,7 @@ complex_div(PyObject *v, PyObject *w) TO_COMPLEX(w, b); PyFPE_START_PROTECT("complex_div", return 0) errno = 0; - quot = c_quot(a, b); + quot = _Py_c_quot(a, b); PyFPE_END_PROTECT(quot) if (errno == EDOM) { PyErr_SetString(PyExc_ZeroDivisionError, "complex division by zero"); @@ -528,7 +532,7 @@ complex_pow(PyObject *v, PyObject *w, PyObject *z) if (exponent.imag == 0. && exponent.real == int_exponent) p = c_powi(a, int_exponent); else - p = c_pow(a, exponent); + p = _Py_c_pow(a, exponent); PyFPE_END_PROTECT(p) Py_ADJUST_ERANGE2(p.real, p.imag); @@ -579,7 +583,7 @@ complex_abs(PyComplexObject *v) double result; PyFPE_START_PROTECT("complex_abs", return 0) - result = c_abs(v->cval); + result = _Py_c_abs(v->cval); PyFPE_END_PROTECT(result) if (errno == ERANGE) { @@ -763,6 +767,7 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v) int got_bracket=0; PyObject *s_buffer = NULL; Py_ssize_t len; + Py_buffer view = {NULL, NULL}; if (PyUnicode_Check(v)) { s_buffer = _PyUnicode_TransformDecimalAndSpaceToASCII(v); @@ -772,7 +777,11 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v) if (s == NULL) goto error; } - else if (PyObject_AsCharBuffer(v, &s, &len)) { + else if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) == 0) { + s = (const char *)view.buf; + len = view.len; + } + else { PyErr_Format(PyExc_TypeError, "complex() argument must be a string or a number, not '%.200s'", Py_TYPE(v)->tp_name); @@ -886,6 +895,7 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v) if (s-start != len) goto parse_error; + PyBuffer_Release(&view); Py_XDECREF(s_buffer); return complex_subtype_from_doubles(type, x, y); @@ -893,6 +903,7 @@ complex_subtype_from_string(PyTypeObject *type, PyObject *v) PyErr_SetString(PyExc_ValueError, "complex() arg is a malformed string"); error: + PyBuffer_Release(&view); Py_XDECREF(s_buffer); return NULL; } diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 312fc402d320..9ffbca72eda6 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -353,11 +353,13 @@ wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds) static PyObject * method_get_doc(PyMethodDescrObject *descr, void *closure) { - if (descr->d_method->ml_doc == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - return PyUnicode_FromString(descr->d_method->ml_doc); + 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 * @@ -425,6 +427,7 @@ static PyMemberDef descr_members[] = { static PyGetSetDef method_getset[] = { {"__doc__", (getter)method_get_doc}, {"__qualname__", (getter)descr_get_qualname}, + {"__text_signature__", (getter)method_get_text_signature}, {0} }; @@ -463,16 +466,19 @@ static PyGetSetDef getset_getset[] = { static PyObject * wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure) { - if (descr->d_base->doc == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - return PyUnicode_FromString(descr->d_base->doc); + 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} }; @@ -1143,17 +1149,15 @@ wrapper_name(wrapperobject *wp) } static PyObject * -wrapper_doc(wrapperobject *wp) +wrapper_doc(wrapperobject *wp, void *closure) { - const char *s = wp->descr->d_base->doc; + return _PyType_GetDocFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc); +} - if (s == NULL) { - Py_INCREF(Py_None); - return Py_None; - } - else { - return PyUnicode_FromString(s); - } +static PyObject * +wrapper_text_signature(wrapperobject *wp, void *closure) +{ + return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc); } static PyObject * @@ -1167,6 +1171,7 @@ static PyGetSetDef wrapper_getsets[] = { {"__name__", (getter)wrapper_name}, {"__qualname__", (getter)wrapper_qualname}, {"__doc__", (getter)wrapper_doc}, + {"__text_signature__", (getter)wrapper_text_signature}, {0} }; @@ -1263,11 +1268,11 @@ PyWrapper_New(PyObject *d, PyObject *self) /* A built-in 'property' type */ /* - class property(object): +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__ + doc = fget.__doc__ self.__get = fget self.__set = fset self.__del = fdel @@ -1275,19 +1280,19 @@ PyWrapper_New(PyObject *d, PyObject *self) def __get__(self, inst, type=None): if inst is None: - return self + return self if self.__get is None: - raise AttributeError, "unreadable attribute" + raise AttributeError, "unreadable attribute" return self.__get(inst) def __set__(self, inst, value): if self.__set is None: - raise AttributeError, "can't set attribute" + 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" + raise AttributeError, "can't delete attribute" return self.__del(inst) */ @@ -1308,7 +1313,7 @@ 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), READONLY}, + {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), 0}, {0} }; @@ -1367,6 +1372,9 @@ property_dealloc(PyObject *self) static PyObject * property_descr_get(PyObject *self, PyObject *obj, PyObject *type) { + static PyObject * volatile cached_args = NULL; + PyObject *args; + PyObject *ret; propertyobject *gs = (propertyobject *)self; if (obj == NULL || obj == Py_None) { @@ -1377,7 +1385,29 @@ property_descr_get(PyObject *self, PyObject *obj, PyObject *type) PyErr_SetString(PyExc_AttributeError, "unreadable attribute"); return NULL; } - return PyObject_CallFunctionObjArgs(gs->prop_get, obj, NULL); + args = cached_args; + if (!args || Py_REFCNT(args) != 1) { + Py_CLEAR(cached_args); + if (!(cached_args = args = PyTuple_New(1))) + return NULL; + } + Py_INCREF(args); + assert (Py_REFCNT(args) == 2); + Py_INCREF(obj); + PyTuple_SET_ITEM(args, 0, obj); + ret = PyObject_Call(gs->prop_get, args, NULL); + if (args == cached_args) { + if (Py_REFCNT(args) == 2) { + obj = PyTuple_GET_ITEM(args, 0); + PyTuple_SET_ITEM(args, 0, NULL); + Py_XDECREF(obj); + } + else { + Py_CLEAR(cached_args); + } + } + Py_DECREF(args); + return ret; } static int @@ -1579,6 +1609,14 @@ property_traverse(PyObject *self, visitproc visit, void *arg) return 0; } +static int +property_clear(PyObject *self) +{ + propertyobject *pp = (propertyobject *)self; + Py_CLEAR(pp->prop_doc); + return 0; +} + PyTypeObject PyProperty_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "property", /* tp_name */ @@ -1604,7 +1642,7 @@ PyTypeObject PyProperty_Type = { Py_TPFLAGS_BASETYPE, /* tp_flags */ property_doc, /* tp_doc */ property_traverse, /* tp_traverse */ - 0, /* tp_clear */ + (inquiry)property_clear, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ diff --git a/Objects/dict-common.h b/Objects/dict-common.h new file mode 100644 index 000000000000..2912eb94eaeb --- /dev/null +++ b/Objects/dict-common.h @@ -0,0 +1,22 @@ +#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; + +typedef PyDictKeyEntry *(*dict_lookup_func) +(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject ***value_addr); + +struct _dictkeysobject { + Py_ssize_t dk_refcnt; + Py_ssize_t dk_size; + dict_lookup_func dk_lookup; + Py_ssize_t dk_usable; + PyDictKeyEntry dk_entries[1]; +}; + +#endif diff --git a/Objects/dictobject.c b/Objects/dictobject.c index bfc730ba705d..624ae9b88858 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -67,30 +67,13 @@ to the combined-table form. #define PyDict_MINSIZE_COMBINED 8 #include "Python.h" +#include "dict-common.h" #include "stringlib/eq.h" -/*[clinic] -class dict -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ - -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; - -typedef PyDictKeyEntry *(*dict_lookup_func) -(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject ***value_addr); - -struct _dictkeysobject { - Py_ssize_t dk_refcnt; - Py_ssize_t dk_size; - dict_lookup_func dk_lookup; - Py_ssize_t dk_usable; - PyDictKeyEntry dk_entries[1]; -}; +/*[clinic input] +class dict "PyDictObject *" "&PyDict_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f157a5a0ce9589d6]*/ /* @@ -233,6 +216,8 @@ static int dictresize(PyDictObject *mp, Py_ssize_t minused); static PyDictObject *free_list[PyDict_MAXFREELIST]; static int numfree = 0; +#include "clinic/dictobject.c.h" + int PyDict_ClearFreeList(void) { @@ -814,13 +799,14 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) if (ep == NULL) { return -1; } + assert(PyUnicode_CheckExact(key) || mp->ma_keys->dk_lookup == lookdict); Py_INCREF(value); MAINTAIN_TRACKING(mp, key, value); old_value = *value_addr; if (old_value != NULL) { assert(ep->me_key != NULL && ep->me_key != dummy); *value_addr = value; - Py_DECREF(old_value); /* which **CAN** re-enter */ + Py_DECREF(old_value); /* which **CAN** re-enter (see issue #22653) */ } else { if (ep->me_key == NULL) { @@ -851,9 +837,8 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) } mp->ma_used++; *value_addr = value; + assert(ep->me_key != NULL && ep->me_key != dummy); } - assert(ep->me_key != NULL && ep->me_key != dummy); - assert(PyUnicode_CheckExact(key) || mp->ma_keys->dk_lookup == lookdict); return 0; } @@ -1101,6 +1086,44 @@ PyDict_GetItem(PyObject *op, PyObject *key) return *value_addr; } +PyObject * +_PyDict_GetItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) +{ + PyDictObject *mp = (PyDictObject *)op; + PyDictKeyEntry *ep; + PyThreadState *tstate; + PyObject **value_addr; + + if (!PyDict_Check(op)) + 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_Current and not PyThreadState_GET() because in debug + mode, the latter complains if tstate is NULL. */ + tstate = (PyThreadState*)_Py_atomic_load_relaxed( + &_PyThreadState_Current); + if (tstate != NULL && tstate->curexc_type != NULL) { + /* preserve the existing exception */ + PyObject *err_type, *err_value, *err_tb; + PyErr_Fetch(&err_type, &err_value, &err_tb); + ep = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr); + /* ignore errors */ + PyErr_Restore(err_type, err_value, err_tb); + if (ep == NULL) + return NULL; + } + else { + ep = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr); + if (ep == NULL) { + PyErr_Clear(); + return NULL; + } + } + return *value_addr; +} + /* 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. @@ -1207,6 +1230,25 @@ PyDict_SetItem(PyObject *op, PyObject *key, PyObject *value) 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; + + /* insertdict() handles any resizing that might be necessary */ + return insertdict(mp, key, hash, value); +} + int PyDict_DelItem(PyObject *op, PyObject *key) { @@ -1249,6 +1291,42 @@ PyDict_DelItem(PyObject *op, PyObject *key) return 0; } +int +_PyDict_DelItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) +{ + PyDictObject *mp; + PyDictKeyEntry *ep; + PyObject *old_key, *old_value; + PyObject **value_addr; + + if (!PyDict_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + assert(key); + assert(hash != -1); + mp = (PyDictObject *)op; + ep = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr); + if (ep == NULL) + return -1; + if (*value_addr == NULL) { + _PyErr_SetKeyError(key); + return -1; + } + old_value = *value_addr; + *value_addr = NULL; + mp->ma_used--; + if (!_PyDict_HasSplitTable(mp)) { + ENSURE_ALLOWS_DELETIONS(mp); + old_key = ep->me_key; + Py_INCREF(dummy); + ep->me_key = dummy; + Py_DECREF(old_key); + } + Py_DECREF(old_value); + return 0; +} + void PyDict_Clear(PyObject *op) { @@ -1367,6 +1445,141 @@ _PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, return 1; } +/* Internal version of dict.pop(). */ +PyObject * +_PyDict_Pop(PyDictObject *mp, PyObject *key, PyObject *deflt) +{ + Py_hash_t hash; + PyObject *old_value, *old_key; + PyDictKeyEntry *ep; + PyObject **value_addr; + + if (mp->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; + } + ep = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr); + if (ep == NULL) + return NULL; + old_value = *value_addr; + if (old_value == NULL) { + if (deflt) { + Py_INCREF(deflt); + return deflt; + } + _PyErr_SetKeyError(key); + return NULL; + } + *value_addr = NULL; + mp->ma_used--; + if (!_PyDict_HasSplitTable(mp)) { + ENSURE_ALLOWS_DELETIONS(mp); + old_key = ep->me_key; + Py_INCREF(dummy); + ep->me_key = dummy; + Py_DECREF(old_key); + } + return old_value; +} + +/* 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_CallObject(cls, NULL); + 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, Py_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, 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 @@ -1691,96 +1904,21 @@ dict_items(PyDictObject *mp) return v; } -static PyObject * -dict_fromkeys(PyObject *cls, PyObject *args) -{ - PyObject *seq; - PyObject *value = Py_None; - PyObject *it; /* iter(seq) */ - PyObject *key; - PyObject *d; - int status; +/*[clinic input] +@classmethod +dict.fromkeys + iterable: object + value: object=None + / - if (!PyArg_UnpackTuple(args, "fromkeys", 1, 2, &seq, &value)) - return NULL; - - d = PyObject_CallObject(cls, NULL); - if (d == NULL) - return NULL; - - if (PyDict_CheckExact(d) && ((PyDictObject *)d)->ma_used == 0) { - if (PyDict_CheckExact(seq)) { - PyDictObject *mp = (PyDictObject *)d; - PyObject *oldvalue; - Py_ssize_t pos = 0; - PyObject *key; - Py_hash_t hash; - - if (dictresize(mp, Py_SIZE(seq))) { - Py_DECREF(d); - return NULL; - } - - while (_PyDict_Next(seq, &pos, &key, &oldvalue, &hash)) { - if (insertdict(mp, key, hash, value)) { - Py_DECREF(d); - return NULL; - } - } - return d; - } - if (PyAnySet_CheckExact(seq)) { - PyDictObject *mp = (PyDictObject *)d; - Py_ssize_t pos = 0; - PyObject *key; - Py_hash_t hash; - - if (dictresize(mp, PySet_GET_SIZE(seq))) { - Py_DECREF(d); - return NULL; - } - - while (_PySet_NextEntry(seq, &pos, &key, &hash)) { - if (insertdict(mp, key, hash, value)) { - Py_DECREF(d); - return NULL; - } - } - return d; - } - } +Returns a new dict with keys from iterable and values equal to value. +[clinic start generated code]*/ - it = PyObject_GetIter(seq); - 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; +static PyObject * +dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value) +/*[clinic end generated code: output=8fb98e4b10384999 input=b85a667f9bf4669d]*/ +{ + return _PyDict_FromKeys((PyObject *)type, iterable, value); } static int @@ -1938,20 +2076,32 @@ PyDict_Merge(PyObject *a, PyObject *b, int override) if (dictresize(mp, (mp->ma_used + other->ma_used)*2) != 0) return -1; for (i = 0, n = DK_SIZE(other->ma_keys); i < n; i++) { - PyObject *value; + PyObject *key, *value; + Py_hash_t hash; entry = &other->ma_keys->dk_entries[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 && - (override || - PyDict_GetItem(a, entry->me_key) == NULL)) { - if (insertdict(mp, entry->me_key, - entry->me_hash, - value) != 0) + if (value != NULL) { + int err = 0; + Py_INCREF(key); + Py_INCREF(value); + if (override || PyDict_GetItem(a, key) == NULL) + err = insertdict(mp, key, hash, value); + Py_DECREF(value); + Py_DECREF(key); + if (err != 0) + return -1; + + if (n != DK_SIZE(other->ma_keys)) { + PyErr_SetString(PyExc_RuntimeError, + "dict mutated during update"); return -1; + } } } } @@ -2164,7 +2314,7 @@ dict_richcompare(PyObject *v, PyObject *w, int op) return res; } -/*[clinic] +/*[clinic input] @coexist dict.__contains__ @@ -2172,21 +2322,14 @@ dict.__contains__ key: object / -True if D has a key k, else False" -[clinic]*/ - -PyDoc_STRVAR(dict___contains____doc__, -"__contains__(key)\n" -"True if D has a key k, else False\""); - -#define DICT___CONTAINS___METHODDEF \ - {"__contains__", (PyCFunction)dict___contains__, METH_O|METH_COEXIST, dict___contains____doc__}, +True if D has a key k, else False. +[clinic start generated code]*/ static PyObject * -dict___contains__(PyObject *self, PyObject *key) -/*[clinic checksum: 3bbac5ce898ae630d9668fa1c8b3afb645ff22e8]*/ +dict___contains__(PyDictObject *self, PyObject *key) +/*[clinic end generated code: output=a3d03db709ed6e6b input=b852b2a19b51ab24]*/ { - register PyDictObject *mp = (PyDictObject *)self; + register PyDictObject *mp = self; Py_hash_t hash; PyDictKeyEntry *ep; PyObject **value_addr; @@ -2299,50 +2442,12 @@ dict_clear(PyDictObject *mp) static PyObject * dict_pop(PyDictObject *mp, PyObject *args) { - Py_hash_t hash; - PyObject *old_value, *old_key; PyObject *key, *deflt = NULL; - PyDictKeyEntry *ep; - PyObject **value_addr; if(!PyArg_UnpackTuple(args, "pop", 1, 2, &key, &deflt)) return NULL; - if (mp->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; - } - ep = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr); - if (ep == NULL) - return NULL; - old_value = *value_addr; - if (old_value == NULL) { - if (deflt) { - Py_INCREF(deflt); - return deflt; - } - _PyErr_SetKeyError(key); - return NULL; - } - *value_addr = NULL; - mp->ma_used--; - if (!_PyDict_HasSplitTable(mp)) { - ENSURE_ALLOWS_DELETIONS(mp); - old_key = ep->me_key; - Py_INCREF(dummy); - ep->me_key = dummy; - Py_DECREF(old_key); - } - return old_value; + + return _PyDict_Pop(mp, key, deflt); } static PyObject * @@ -2449,8 +2554,8 @@ dict_tp_clear(PyObject *op) static PyObject *dictiter_new(PyDictObject *, PyTypeObject *); -static PyObject * -dict_sizeof(PyDictObject *mp) +PyObject * +_PyDict_SizeOf(PyDictObject *mp) { Py_ssize_t size, res; @@ -2496,10 +2601,6 @@ 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(fromkeys__doc__, -"dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.\n\ -v defaults to None."); - PyDoc_STRVAR(clear__doc__, "D.clear() -> None. Remove all items from D."); @@ -2522,7 +2623,7 @@ static PyMethodDef mapp_methods[] = { DICT___CONTAINS___METHODDEF {"__getitem__", (PyCFunction)dict_subscript, METH_O | METH_COEXIST, getitem__doc__}, - {"__sizeof__", (PyCFunction)dict_sizeof, METH_NOARGS, + {"__sizeof__", (PyCFunction)_PyDict_SizeOf, METH_NOARGS, sizeof__doc__}, {"get", (PyCFunction)dict_get, METH_VARARGS, get__doc__}, @@ -2540,8 +2641,7 @@ static PyMethodDef mapp_methods[] = { values__doc__}, {"update", (PyCFunction)dict_update, METH_VARARGS | METH_KEYWORDS, update__doc__}, - {"fromkeys", (PyCFunction)dict_fromkeys, METH_VARARGS | METH_CLASS, - fromkeys__doc__}, + DICT_FROMKEYS_METHODDEF {"clear", (PyCFunction)dict_clear, METH_NOARGS, clear__doc__}, {"copy", (PyCFunction)dict_copy, METH_NOARGS, @@ -3052,8 +3152,8 @@ static PyObject *dictiter_iternextitem(dictiterobject *di) value = *value_ptr; Py_INCREF(key); Py_INCREF(value); - PyTuple_SET_ITEM(result, 0, key); - PyTuple_SET_ITEM(result, 1, value); + PyTuple_SET_ITEM(result, 0, key); /* steals reference */ + PyTuple_SET_ITEM(result, 1, value); /* steals reference */ return result; fail: @@ -3148,28 +3248,22 @@ dictiter_reduce(dictiterobject *di) /* The instance lay-out is the same for all three; but the type differs. */ -typedef struct { - PyObject_HEAD - PyDictObject *dv_dict; -} dictviewobject; - - static void -dictview_dealloc(dictviewobject *dv) +dictview_dealloc(_PyDictViewObject *dv) { Py_XDECREF(dv->dv_dict); PyObject_GC_Del(dv); } static int -dictview_traverse(dictviewobject *dv, visitproc visit, void *arg) +dictview_traverse(_PyDictViewObject *dv, visitproc visit, void *arg) { Py_VISIT(dv->dv_dict); return 0; } static Py_ssize_t -dictview_len(dictviewobject *dv) +dictview_len(_PyDictViewObject *dv) { Py_ssize_t len = 0; if (dv->dv_dict != NULL) @@ -3177,10 +3271,10 @@ dictview_len(dictviewobject *dv) return len; } -static PyObject * -dictview_new(PyObject *dict, PyTypeObject *type) +PyObject * +_PyDictView_New(PyObject *dict, PyTypeObject *type) { - dictviewobject *dv; + _PyDictViewObject *dv; if (dict == NULL) { PyErr_BadInternalCall(); return NULL; @@ -3192,7 +3286,7 @@ dictview_new(PyObject *dict, PyTypeObject *type) type->tp_name, dict->ob_type->tp_name); return NULL; } - dv = PyObject_GC_New(dictviewobject, type); + dv = PyObject_GC_New(_PyDictViewObject, type); if (dv == NULL) return NULL; Py_INCREF(dict); @@ -3296,7 +3390,7 @@ dictview_richcompare(PyObject *self, PyObject *other, int op) } static PyObject * -dictview_repr(dictviewobject *dv) +dictview_repr(_PyDictViewObject *dv) { PyObject *seq; PyObject *result; @@ -3313,7 +3407,7 @@ dictview_repr(dictviewobject *dv) /*** dict_keys ***/ static PyObject * -dictkeys_iter(dictviewobject *dv) +dictkeys_iter(_PyDictViewObject *dv) { if (dv->dv_dict == NULL) { Py_RETURN_NONE; @@ -3322,7 +3416,7 @@ dictkeys_iter(dictviewobject *dv) } static int -dictkeys_contains(dictviewobject *dv, PyObject *obj) +dictkeys_contains(_PyDictViewObject *dv, PyObject *obj) { if (dv->dv_dict == NULL) return 0; @@ -3360,8 +3454,8 @@ dictviews_sub(PyObject* self, PyObject *other) return result; } -static PyObject* -dictviews_and(PyObject* self, PyObject *other) +PyObject* +_PyDictView_Intersect(PyObject* self, PyObject *other) { PyObject *result = PySet_New(self); PyObject *tmp; @@ -3435,7 +3529,7 @@ static PyNumberMethods dictviews_as_number = { 0, /*nb_invert*/ 0, /*nb_lshift*/ 0, /*nb_rshift*/ - (binaryfunc)dictviews_and, /*nb_and*/ + (binaryfunc)_PyDictView_Intersect, /*nb_and*/ (binaryfunc)dictviews_xor, /*nb_xor*/ (binaryfunc)dictviews_or, /*nb_or*/ }; @@ -3447,7 +3541,7 @@ dictviews_isdisjoint(PyObject *self, PyObject *other) PyObject *item = NULL; if (self == other) { - if (dictview_len((dictviewobject *)self) == 0) + if (dictview_len((_PyDictViewObject *)self) == 0) Py_RETURN_TRUE; else Py_RETURN_FALSE; @@ -3456,7 +3550,7 @@ dictviews_isdisjoint(PyObject *self, PyObject *other) /* Iterate over the shorter object (only if other is a set, * because PySequence_Contains may be expensive otherwise): */ if (PyAnySet_Check(other) || PyDictViewSet_Check(other)) { - Py_ssize_t len_self = dictview_len((dictviewobject *)self); + Py_ssize_t len_self = dictview_len((_PyDictViewObject *)self); Py_ssize_t len_other = PyObject_Size(other); if (len_other == -1) return NULL; @@ -3503,7 +3597,7 @@ static PyMethodDef dictkeys_methods[] = { PyTypeObject PyDictKeys_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "dict_keys", /* tp_name */ - sizeof(dictviewobject), /* tp_basicsize */ + sizeof(_PyDictViewObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)dictview_dealloc, /* tp_dealloc */ @@ -3536,13 +3630,13 @@ PyTypeObject PyDictKeys_Type = { static PyObject * dictkeys_new(PyObject *dict) { - return dictview_new(dict, &PyDictKeys_Type); + return _PyDictView_New(dict, &PyDictKeys_Type); } /*** dict_items ***/ static PyObject * -dictitems_iter(dictviewobject *dv) +dictitems_iter(_PyDictViewObject *dv) { if (dv->dv_dict == NULL) { Py_RETURN_NONE; @@ -3551,7 +3645,7 @@ dictitems_iter(dictviewobject *dv) } static int -dictitems_contains(dictviewobject *dv, PyObject *obj) +dictitems_contains(_PyDictViewObject *dv, PyObject *obj) { PyObject *key, *value, *found; if (dv->dv_dict == NULL) @@ -3589,7 +3683,7 @@ static PyMethodDef dictitems_methods[] = { PyTypeObject PyDictItems_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "dict_items", /* tp_name */ - sizeof(dictviewobject), /* tp_basicsize */ + sizeof(_PyDictViewObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)dictview_dealloc, /* tp_dealloc */ @@ -3622,13 +3716,13 @@ PyTypeObject PyDictItems_Type = { static PyObject * dictitems_new(PyObject *dict) { - return dictview_new(dict, &PyDictItems_Type); + return _PyDictView_New(dict, &PyDictItems_Type); } /*** dict_values ***/ static PyObject * -dictvalues_iter(dictviewobject *dv) +dictvalues_iter(_PyDictViewObject *dv) { if (dv->dv_dict == NULL) { Py_RETURN_NONE; @@ -3654,7 +3748,7 @@ static PyMethodDef dictvalues_methods[] = { PyTypeObject PyDictValues_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "dict_values", /* tp_name */ - sizeof(dictviewobject), /* tp_basicsize */ + sizeof(_PyDictViewObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)dictview_dealloc, /* tp_dealloc */ @@ -3687,7 +3781,7 @@ PyTypeObject PyDictValues_Type = { static PyObject * dictvalues_new(PyObject *dict) { - return dictview_new(dict, &PyDictValues_Type); + return _PyDictView_New(dict, &PyDictValues_Type); } /* Returns NULL if cannot allocate a new PyDictKeysObject, diff --git a/Objects/exceptions.c b/Objects/exceptions.c index af40bc8feae6..a27599781071 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -16,9 +16,6 @@ PyObject *PyExc_IOError = NULL; #ifdef MS_WINDOWS PyObject *PyExc_WindowsError = NULL; #endif -#ifdef __VMS -PyObject *PyExc_VMSError = NULL; -#endif /* The dict map from errno codes to OSError subclasses */ static PyObject *errnomap = NULL; @@ -475,6 +472,13 @@ SimpleExtendsException(PyExc_Exception, TypeError, "Inappropriate argument type."); +/* + * StopAsyncIteration extends Exception + */ +SimpleExtendsException(PyExc_Exception, StopAsyncIteration, + "Signal the end from iterator.__anext__()."); + + /* * StopIteration extends Exception */ @@ -727,13 +731,17 @@ ComplexExtendsException(PyExc_Exception, ImportError, * 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 **filename, PyObject **filename2 #ifdef MS_WINDOWS , PyObject **winerror #endif @@ -741,14 +749,23 @@ oserror_parse_args(PyObject **p_args, { 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); -#ifdef MS_WINDOWS - if (nargs >= 2 && nargs <= 4) { - if (!PyArg_UnpackTuple(args, "OSError", 2, 4, - myerrno, strerror, filename, winerror)) + 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; @@ -780,14 +797,8 @@ oserror_parse_args(PyObject **p_args, Py_DECREF(args); args = *p_args = newargs; } +#endif /* MS_WINDOWS */ } -#else - if (nargs >= 2 && nargs <= 3) { - if (!PyArg_UnpackTuple(args, "OSError", 2, 3, - myerrno, strerror, filename)) - return -1; - } -#endif return 0; } @@ -795,7 +806,7 @@ oserror_parse_args(PyObject **p_args, static int oserror_init(PyOSErrorObject *self, PyObject **p_args, PyObject *myerrno, PyObject *strerror, - PyObject *filename + PyObject *filename, PyObject *filename2 #ifdef MS_WINDOWS , PyObject *winerror #endif @@ -819,9 +830,14 @@ oserror_init(PyOSErrorObject *self, PyObject **p_args, Py_INCREF(filename); self->filename = filename; - if (nargs >= 2 && nargs <= 3) { - /* filename is removed from the args tuple (for compatibility - purposes, see test_exceptions.py) */ + 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; @@ -880,7 +896,8 @@ static PyObject * OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyOSErrorObject *self = NULL; - PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL; + PyObject *myerrno = NULL, *strerror = NULL; + PyObject *filename = NULL, *filename2 = NULL; #ifdef MS_WINDOWS PyObject *winerror = NULL; #endif @@ -891,7 +908,8 @@ OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (!_PyArg_NoKeywords(type->tp_name, kwds)) goto error; - if (oserror_parse_args(&args, &myerrno, &strerror, &filename + if (oserror_parse_args(&args, &myerrno, &strerror, + &filename, &filename2 #ifdef MS_WINDOWS , &winerror #endif @@ -920,7 +938,7 @@ OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->written = -1; if (!oserror_use_init(type)) { - if (oserror_init(self, &args, myerrno, strerror, filename + if (oserror_init(self, &args, myerrno, strerror, filename, filename2 #ifdef MS_WINDOWS , winerror #endif @@ -945,7 +963,8 @@ OSError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static int OSError_init(PyOSErrorObject *self, PyObject *args, PyObject *kwds) { - PyObject *myerrno = NULL, *strerror = NULL, *filename = NULL; + PyObject *myerrno = NULL, *strerror = NULL; + PyObject *filename = NULL, *filename2 = NULL; #ifdef MS_WINDOWS PyObject *winerror = NULL; #endif @@ -958,14 +977,14 @@ OSError_init(PyOSErrorObject *self, PyObject *args, PyObject *kwds) return -1; Py_INCREF(args); - if (oserror_parse_args(&args, &myerrno, &strerror, &filename + if (oserror_parse_args(&args, &myerrno, &strerror, &filename, &filename2 #ifdef MS_WINDOWS , &winerror #endif )) goto error; - if (oserror_init(self, &args, myerrno, strerror, filename + if (oserror_init(self, &args, myerrno, strerror, filename, filename2 #ifdef MS_WINDOWS , winerror #endif @@ -985,6 +1004,7 @@ 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 @@ -1006,6 +1026,7 @@ OSError_traverse(PyOSErrorObject *self, visitproc visit, Py_VISIT(self->myerrno); Py_VISIT(self->strerror); Py_VISIT(self->filename); + Py_VISIT(self->filename2); #ifdef MS_WINDOWS Py_VISIT(self->winerror); #endif @@ -1015,23 +1036,42 @@ OSError_traverse(PyOSErrorObject *self, visitproc visit, 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) - return PyUnicode_FromFormat("[WinError %S] %S: %R", - self->winerror ? self->winerror: Py_None, - self->strerror ? self->strerror: Py_None, - self->filename); + 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) - return PyUnicode_FromFormat("[Errno %S] %S: %R", - self->myerrno ? self->myerrno: Py_None, - self->strerror ? self->strerror: Py_None, - self->filename); + 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->myerrno: Py_None, @@ -1048,7 +1088,8 @@ OSError_reduce(PyOSErrorObject *self) /* 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) { - args = PyTuple_New(3); + Py_ssize_t size = self->filename2 ? 5 : 3; + args = PyTuple_New(size); if (!args) return NULL; @@ -1062,6 +1103,20 @@ OSError_reduce(PyOSErrorObject *self) 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); @@ -1101,6 +1156,8 @@ static PyMemberDef OSError_members[] = { 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")}, @@ -1174,6 +1231,11 @@ SimpleExtendsException(PyExc_Exception, EOFError, SimpleExtendsException(PyExc_Exception, RuntimeError, "Unspecified run-time error."); +/* + * RecursionError extends RuntimeError + */ +SimpleExtendsException(PyExc_RuntimeError, RecursionError, + "Recursion limit exceeded."); /* * NotImplementedError extends RuntimeError @@ -1204,6 +1266,9 @@ SimpleExtendsException(PyExc_Exception, AttributeError, * SyntaxError extends Exception */ +/* Helper function to customise error message for some syntax errors */ +static int _report_missing_parentheses(PySyntaxErrorObject *self); + static int SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds) { @@ -1248,6 +1313,13 @@ SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds) Py_INCREF(self->text); Py_DECREF(info); + + /* Issue #21669: Custom error for 'print' & 'exec' as statements */ + if (self->text && PyUnicode_Check(self->text)) { + if (_report_missing_parentheses(self) < 0) { + return -1; + } + } } return 0; } @@ -1787,6 +1859,10 @@ UnicodeEncodeError_str(PyObject *self) 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 contructed. */ reason_str = PyObject_Str(uself->reason); @@ -1858,8 +1934,6 @@ static int UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds) { PyUnicodeErrorObject *ude; - const char *data; - Py_ssize_t size; if (BaseException_init((PyBaseExceptionObject *)self, args, kwds) == -1) return -1; @@ -1880,21 +1954,27 @@ UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds) return -1; } - if (!PyBytes_Check(ude->object)) { - if (PyObject_AsReadBuffer(ude->object, (const void **)&data, &size)) { - ude->encoding = ude->object = ude->reason = NULL; - return -1; - } - ude->object = PyBytes_FromStringAndSize(data, size); - } - else { - Py_INCREF(ude->object); - } - 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_CLEAR(ude->object); + 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 * @@ -1905,6 +1985,10 @@ UnicodeDecodeError_str(PyObject *self) 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 contructed. */ reason_str = PyObject_Str(uself->reason); @@ -1999,6 +2083,10 @@ UnicodeTranslateError_str(PyObject *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 contructed. */ reason_str = PyObject_Str(uself->reason); @@ -2062,7 +2150,7 @@ _PyUnicodeTranslateError_Create( PyObject *object, Py_ssize_t start, Py_ssize_t end, const char *reason) { - return PyObject_CallFunction(PyExc_UnicodeTranslateError, "Ons", + return PyObject_CallFunction(PyExc_UnicodeTranslateError, "Onns", object, start, end, reason); } @@ -2297,7 +2385,7 @@ SimpleExtendsException(PyExc_Warning, ResourceWarning, -/* Pre-computed RuntimeError instance for when recursion depth is reached. +/* Pre-computed RecursionError instance for when recursion depth is reached. Meant to be used when normalizing the exception for exceeding the recursion depth will cause its own infinite recursion. */ @@ -2392,6 +2480,7 @@ _PyExc_Init(PyObject *bltinmod) PRE_INIT(BaseException) PRE_INIT(Exception) PRE_INIT(TypeError) + PRE_INIT(StopAsyncIteration) PRE_INIT(StopIteration) PRE_INIT(GeneratorExit) PRE_INIT(SystemExit) @@ -2400,6 +2489,7 @@ _PyExc_Init(PyObject *bltinmod) PRE_INIT(OSError) PRE_INIT(EOFError) PRE_INIT(RuntimeError) + PRE_INIT(RecursionError) PRE_INIT(NotImplementedError) PRE_INIT(NameError) PRE_INIT(UnboundLocalError) @@ -2462,6 +2552,7 @@ _PyExc_Init(PyObject *bltinmod) POST_INIT(BaseException) POST_INIT(Exception) POST_INIT(TypeError) + POST_INIT(StopAsyncIteration) POST_INIT(StopIteration) POST_INIT(GeneratorExit) POST_INIT(SystemExit) @@ -2472,12 +2563,10 @@ _PyExc_Init(PyObject *bltinmod) INIT_ALIAS(IOError, OSError) #ifdef MS_WINDOWS INIT_ALIAS(WindowsError, OSError) -#endif -#ifdef __VMS - INIT_ALIAS(VMSError, OSError) #endif POST_INIT(EOFError) POST_INIT(RuntimeError) + POST_INIT(RecursionError) POST_INIT(NotImplementedError) POST_INIT(NameError) POST_INIT(UnboundLocalError) @@ -2561,9 +2650,9 @@ _PyExc_Init(PyObject *bltinmod) preallocate_memerrors(); if (!PyExc_RecursionErrorInst) { - PyExc_RecursionErrorInst = BaseException_new(&_PyExc_RuntimeError, NULL, NULL); + PyExc_RecursionErrorInst = BaseException_new(&_PyExc_RecursionError, NULL, NULL); if (!PyExc_RecursionErrorInst) - Py_FatalError("Cannot pre-allocate RuntimeError instance for " + Py_FatalError("Cannot pre-allocate RecursionError instance for " "recursion errors"); else { PyBaseExceptionObject *err_inst = @@ -2572,15 +2661,15 @@ _PyExc_Init(PyObject *bltinmod) PyObject *exc_message; exc_message = PyUnicode_FromString("maximum recursion depth exceeded"); if (!exc_message) - Py_FatalError("cannot allocate argument for RuntimeError " + Py_FatalError("cannot allocate argument for RecursionError " "pre-allocation"); args_tuple = PyTuple_Pack(1, exc_message); if (!args_tuple) - Py_FatalError("cannot allocate tuple for RuntimeError " + Py_FatalError("cannot allocate tuple for RecursionError " "pre-allocation"); Py_DECREF(exc_message); if (BaseException_init(err_inst, args_tuple, NULL)) - Py_FatalError("init of pre-allocated RuntimeError failed"); + Py_FatalError("init of pre-allocated RecursionError failed"); Py_DECREF(args_tuple); } } @@ -2645,7 +2734,7 @@ _PyErr_TrySetFromCause(const char *format, ...) same_basic_size = ( caught_type_size == base_exc_size || (PyType_SUPPORTS_WEAKREFS(caught_type) && - (caught_type_size == base_exc_size + sizeof(PyObject *)) + (caught_type_size == base_exc_size + (Py_ssize_t)sizeof(PyObject *)) ) ); if (caught_type->tp_init != (initproc)BaseException_init || @@ -2695,8 +2784,11 @@ _PyErr_TrySetFromCause(const char *format, ...) * types as well, but that's quite a bit trickier due to the extra * state potentially stored on OSError instances. */ - - Py_XDECREF(tb); + /* 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); @@ -2721,3 +2813,128 @@ _PyErr_TrySetFromCause(const char *format, ...) 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 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); + 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; + } + } + if (PyUnicode_Tailmatch(self->text, print_prefix, + start, text_len, -1)) { + Py_CLEAR(self->msg); + self->msg = PyUnicode_FromString( + "Missing parentheses in call to 'print'"); + return 1; + } + + /* Check for legacy exec statements */ + if (exec_prefix == NULL) { + exec_prefix = PyUnicode_InternFromString("exec "); + if (exec_prefix == NULL) { + return -1; + } + } + if (PyUnicode_Tailmatch(self->text, exec_prefix, + start, text_len, -1)) { + Py_CLEAR(self->msg); + self->msg = PyUnicode_FromString( + "Missing parentheses in call to 'exec'"); + 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/Objects/fileobject.c b/Objects/fileobject.c index 596f909755d7..234d07e5c675 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -372,8 +372,11 @@ PyFile_NewStdPrinter(int fd) static PyObject * stdprinter_write(PyStdPrinter_Object *self, PyObject *args) { - char *c; + PyObject *unicode; + PyObject *bytes = NULL; + char *str; Py_ssize_t n; + int err; if (self->fd < 0) { /* fd might be invalid on Windows @@ -383,26 +386,33 @@ stdprinter_write(PyStdPrinter_Object *self, PyObject *args) Py_RETURN_NONE; } - if (!PyArg_ParseTuple(args, "s", &c)) { + if (!PyArg_ParseTuple(args, "U", &unicode)) return NULL; + + /* encode Unicode to UTF-8 */ + str = PyUnicode_AsUTF8AndSize(unicode, &n); + if (str == NULL) { + PyErr_Clear(); + bytes = _PyUnicode_AsUTF8String(unicode, "backslashreplace"); + if (bytes == NULL) + return NULL; + if (PyBytes_AsStringAndSize(bytes, &str, &n) < 0) { + Py_DECREF(bytes); + return NULL; + } } - n = strlen(c); - Py_BEGIN_ALLOW_THREADS - errno = 0; -#ifdef MS_WINDOWS - if (n > INT_MAX) - n = INT_MAX; - n = write(self->fd, c, (int)n); -#else - n = write(self->fd, c, n); -#endif - Py_END_ALLOW_THREADS + n = _Py_write(self->fd, str, n); + /* save errno, it can be modified indirectly by Py_XDECREF() */ + err = errno; - if (n < 0) { - if (errno == EAGAIN) + Py_XDECREF(bytes); + + if (n == -1) { + if (err == EAGAIN) { + PyErr_Clear(); Py_RETURN_NONE; - PyErr_SetFromErrno(PyExc_IOError); + } return NULL; } diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 29c3b32763c2..d6819814ef83 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -119,7 +119,7 @@ PyFloat_FromDouble(double fval) return PyErr_NoMemory(); } /* Inline PyObject_New */ - PyObject_INIT(op, &PyFloat_Type); + (void)PyObject_INIT(op, &PyFloat_Type); op->ob_fval = fval; return (PyObject *) op; } @@ -131,6 +131,7 @@ PyFloat_FromString(PyObject *v) double x; PyObject *s_buffer = NULL; Py_ssize_t len; + Py_buffer view = {NULL, NULL}; PyObject *result = NULL; if (PyUnicode_Check(v)) { @@ -143,7 +144,11 @@ PyFloat_FromString(PyObject *v) return NULL; } } - else if (PyObject_AsCharBuffer(v, &s, &len)) { + else if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) == 0) { + s = (const char *)view.buf; + len = view.len; + } + else { PyErr_Format(PyExc_TypeError, "float() argument must be a string or a number, not '%.200s'", Py_TYPE(v)->tp_name); @@ -170,6 +175,7 @@ PyFloat_FromString(PyObject *v) else result = PyFloat_FromDouble(x); + PyBuffer_Release(&view); Py_XDECREF(s_buffer); return result; } @@ -214,6 +220,7 @@ PyFloat_AsDouble(PyObject *op) if (fo == NULL) return -1; if (!PyFloat_Check(fo)) { + Py_DECREF(fo); PyErr_SetString(PyExc_TypeError, "nb_float should return float object"); return -1; @@ -979,8 +986,9 @@ float_round(PyObject *v, PyObject *args) x = PyFloat_AsDouble(v); if (!PyArg_ParseTuple(args, "|O", &o_ndigits)) return NULL; - if (o_ndigits == NULL) { - /* single-argument round: round to nearest integer */ + if (o_ndigits == NULL || 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 */ @@ -2026,7 +2034,7 @@ _PyFloat_Pack4(double x, unsigned char *p, int le) } else { float y = (float)x; - const char *s = (char*)&y; + const unsigned char *s = (unsigned char*)&y; int i, incr = 1; if (Py_IS_INFINITY(y) && !Py_IS_INFINITY(x)) @@ -2162,7 +2170,7 @@ _PyFloat_Pack8(double x, unsigned char *p, int le) return -1; } else { - const char *s = (char*)&x; + const unsigned char *s = (unsigned char*)&x; int i, incr = 1; if ((double_format == ieee_little_endian_format && !le) diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 63f03a64e056..172f2cb61b87 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -196,6 +196,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) case SETUP_EXCEPT: case SETUP_FINALLY: case SETUP_WITH: + case SETUP_ASYNC_WITH: blockstack[blockstack_top++] = addr; in_finally[blockstack_top-1] = 0; break; @@ -203,7 +204,8 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) case POP_BLOCK: assert(blockstack_top > 0); setup_op = code[blockstack[blockstack_top-1]]; - if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH) { + if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH + || setup_op == SETUP_ASYNC_WITH) { in_finally[blockstack_top-1] = 1; } else { @@ -218,7 +220,8 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) * be seeing such an END_FINALLY.) */ if (blockstack_top > 0) { setup_op = code[blockstack[blockstack_top-1]]; - if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH) { + if (setup_op == SETUP_FINALLY || setup_op == SETUP_WITH + || setup_op == SETUP_ASYNC_WITH) { blockstack_top--; } } @@ -281,6 +284,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) case SETUP_EXCEPT: case SETUP_FINALLY: case SETUP_WITH: + case SETUP_ASYNC_WITH: delta_iblock++; break; @@ -726,7 +730,6 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, Py_INCREF(locals); f->f_locals = locals; } - f->f_tstate = tstate; f->f_lasti = -1; f->f_lineno = code->co_firstlineno; @@ -787,7 +790,7 @@ map_to_dict(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values, PyObject *key = PyTuple_GET_ITEM(map, j); PyObject *value = values[j]; assert(PyUnicode_Check(key)); - if (deref) { + if (deref && value != NULL) { assert(PyCell_Check(value)); value = PyCell_GET(value); } diff --git a/Objects/genobject.c b/Objects/genobject.c index 08d30bf4b7b7..00ebbf1cf8dc 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -12,6 +12,8 @@ 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); return 0; } @@ -22,6 +24,18 @@ _PyGen_Finalize(PyObject *self) PyObject *res; PyObject *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 != NULL + && gen->gi_frame->f_lasti == -1 + && !PyErr_Occurred() + && PyErr_WarnFormat(PyExc_RuntimeWarning, 1, + "coroutine '%.50S' was never awaited", + gen->gi_qualname)) + return; + if (gen->gi_frame == NULL || gen->gi_frame->f_stacktop == NULL) /* Generator isn't paused, so no need to close */ return; @@ -58,6 +72,8 @@ gen_dealloc(PyGenObject *gen) _PyObject_GC_UNTRACK(self); Py_CLEAR(gen->gi_frame); Py_CLEAR(gen->gi_code); + Py_CLEAR(gen->gi_name); + Py_CLEAR(gen->gi_qualname); PyObject_GC_Del(gen); } @@ -69,8 +85,10 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc) PyObject *result; if (gen->gi_running) { - PyErr_SetString(PyExc_ValueError, - "generator already executing"); + char *msg = "generator already executing"; + if (PyCoro_CheckExact(gen)) + msg = "coroutine already executing"; + PyErr_SetString(PyExc_ValueError, msg); return NULL; } if (f == NULL || f->f_stacktop == NULL) { @@ -82,9 +100,12 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc) if (f->f_lasti == -1) { if (arg && arg != Py_None) { - PyErr_SetString(PyExc_TypeError, - "can't send non-None value to a " - "just-started generator"); + char *msg = "can't send non-None value to a " + "just-started generator"; + if (PyCoro_CheckExact(gen)) + msg = "can't send non-None value to a " + "just-started coroutine"; + PyErr_SetString(PyExc_TypeError, msg); return NULL; } } else { @@ -126,6 +147,50 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc) } Py_CLEAR(result); } + else if (!result && PyErr_ExceptionMatches(PyExc_StopIteration)) { + /* Check for __future__ generator_stop and conditionally turn + * a leaking StopIteration into RuntimeError (with its cause + * set appropriately). */ + if (((PyCodeObject *)gen->gi_code)->co_flags & + (CO_FUTURE_GENERATOR_STOP | CO_COROUTINE | CO_ITERABLE_COROUTINE)) + { + PyObject *exc, *val, *val2, *tb; + char *msg = "generator raised StopIteration"; + if (PyCoro_CheckExact(gen)) + msg = "coroutine raised StopIteration"; + PyErr_Fetch(&exc, &val, &tb); + PyErr_NormalizeException(&exc, &val, &tb); + if (tb != NULL) + PyException_SetTraceback(val, tb); + Py_DECREF(exc); + Py_XDECREF(tb); + PyErr_SetString(PyExc_RuntimeError, msg); + PyErr_Fetch(&exc, &val2, &tb); + PyErr_NormalizeException(&exc, &val2, &tb); + Py_INCREF(val); + PyException_SetCause(val2, val); + PyException_SetContext(val2, val); + PyErr_Restore(exc, val2, tb); + } + else { + PyObject *exc, *val, *tb; + + /* Pop the exception before issuing a warning. */ + PyErr_Fetch(&exc, &val, &tb); + + if (PyErr_WarnFormat(PyExc_PendingDeprecationWarning, 1, + "generator '%.50S' raised StopIteration", + gen->gi_qualname)) { + /* Warning was converted to an error. */ + Py_XDECREF(exc); + Py_XDECREF(val); + Py_XDECREF(tb); + } + else { + PyErr_Restore(exc, val, tb); + } + } + } if (!result || f->f_stacktop == NULL) { /* generator can't be rerun, so release the frame */ @@ -229,9 +294,11 @@ gen_close(PyGenObject *gen, PyObject *args) PyErr_SetNone(PyExc_GeneratorExit); retval = gen_send_ex(gen, Py_None, 1); if (retval) { + char *msg = "generator ignored GeneratorExit"; + if (PyCoro_CheckExact(gen)) + msg = "coroutine ignored GeneratorExit"; Py_DECREF(retval); - PyErr_SetString(PyExc_RuntimeError, - "generator ignored GeneratorExit"); + PyErr_SetString(PyExc_RuntimeError, msg); return NULL; } if (PyErr_ExceptionMatches(PyExc_StopIteration) @@ -373,11 +440,7 @@ gen_throw(PyGenObject *gen, PyObject *args) static PyObject * gen_iternext(PyGenObject *gen) { - PyObject *val = NULL; - PyObject *ret; - ret = gen_send_ex(gen, val, 0); - Py_XDECREF(val); - return ret; + return gen_send_ex(gen, NULL, 0); } /* @@ -396,13 +459,29 @@ _PyGen_FetchStopIterationValue(PyObject **pvalue) { if (PyErr_ExceptionMatches(PyExc_StopIteration)) { PyErr_Fetch(&et, &ev, &tb); - Py_XDECREF(et); - Py_XDECREF(tb); if (ev) { - value = ((PyStopIterationObject *)ev)->value; - Py_INCREF(value); - Py_DECREF(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) { + /* avoid normalisation and take ev as value */ + 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; } @@ -418,33 +497,84 @@ static PyObject * gen_repr(PyGenObject *gen) { return PyUnicode_FromFormat("", - ((PyCodeObject *)gen->gi_code)->co_name, - gen); + gen->gi_qualname, gen); } +static PyObject * +gen_get_name(PyGenObject *op) +{ + Py_INCREF(op->gi_name); + return op->gi_name; +} + +static int +gen_set_name(PyGenObject *op, PyObject *value) +{ + PyObject *tmp; + + /* 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; + } + tmp = op->gi_name; + Py_INCREF(value); + op->gi_name = value; + Py_DECREF(tmp); + return 0; +} static PyObject * -gen_get_name(PyGenObject *gen) +gen_get_qualname(PyGenObject *op) { - PyObject *name = ((PyCodeObject *)gen->gi_code)->co_name; - Py_INCREF(name); - return name; + Py_INCREF(op->gi_qualname); + return op->gi_qualname; } +static int +gen_set_qualname(PyGenObject *op, PyObject *value) +{ + PyObject *tmp; -PyDoc_STRVAR(gen__name__doc__, -"Return the name of the generator's associated code object."); + /* 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; + } + tmp = op->gi_qualname; + Py_INCREF(value); + op->gi_qualname = value; + Py_DECREF(tmp); + return 0; +} + +static PyObject * +gen_getyieldfrom(PyGenObject *gen) +{ + PyObject *yf = gen_yf(gen); + if (yf == NULL) + Py_RETURN_NONE; + return yf; +} static PyGetSetDef gen_getsetlist[] = { - {"__name__", (getter)gen_get_name, NULL, gen__name__doc__}, - {NULL} + {"__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}, + {"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 */ }; @@ -465,7 +595,7 @@ PyTypeObject PyGen_Type = { 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_reserved */ + 0, /* tp_as_async */ (reprfunc)gen_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -509,10 +639,11 @@ PyTypeObject PyGen_Type = { _PyGen_Finalize, /* tp_finalize */ }; -PyObject * -PyGen_New(PyFrameObject *f) +static PyObject * +gen_new_with_qualname(PyTypeObject *type, PyFrameObject *f, + PyObject *name, PyObject *qualname) { - PyGenObject *gen = PyObject_GC_New(PyGenObject, &PyGen_Type); + PyGenObject *gen = PyObject_GC_New(PyGenObject, type); if (gen == NULL) { Py_DECREF(f); return NULL; @@ -523,10 +654,32 @@ PyGen_New(PyFrameObject *f) gen->gi_code = (PyObject *)(f->f_code); gen->gi_running = 0; gen->gi_weakreflist = 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) { @@ -544,3 +697,289 @@ PyGen_NeedsFinalizing(PyGenObject *gen) /* No blocks except loops, 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) +{ + PyObject *yf = gen_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}, + {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_print */ + 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 | + Py_TPFLAGS_HAVE_FINALIZE, /* 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); +} + +static PyObject * +coro_wrapper_send(PyCoroWrapper *cw, PyObject *arg) +{ + return gen_send_ex((PyGenObject *)cw->cw_coroutine, arg, 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_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 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 */ + PyObject_Del, /* tp_free */ +}; + +PyObject * +PyCoro_New(PyFrameObject *f, PyObject *name, PyObject *qualname) +{ + return gen_new_with_qualname(&PyCoro_Type, f, name, qualname); +} diff --git a/Objects/iterobject.c b/Objects/iterobject.c index 77ff8106fd21..2fb0c8832a97 100644 --- a/Objects/iterobject.c +++ b/Objects/iterobject.c @@ -54,6 +54,11 @@ iter_iternext(PyObject *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) { @@ -212,7 +217,7 @@ calliter_iternext(calliterobject *it) Py_DECREF(args); if (result != NULL) { int ok; - ok = PyObject_RichCompareBool(it->it_sentinel, result, Py_EQ); + ok = PyObject_RichCompareBool(it->it_sentinel, result, Py_EQ); if (ok == 0) return result; /* Common case, fast path */ Py_DECREF(result); diff --git a/Objects/listobject.c b/Objects/listobject.c index 5b75968fb387..45e54ce31d20 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -1832,7 +1832,8 @@ merge_collapse(MergeState *ms) 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) { + 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) @@ -1960,8 +1961,10 @@ listsort(PyListObject *self, PyObject *args, PyObject *kwds) keys = &ms.temparray[saved_ob_size+1]; else { keys = PyMem_MALLOC(sizeof(PyObject *) * saved_ob_size); - if (keys == NULL) - return NULL; + if (keys == NULL) { + PyErr_NoMemory(); + goto keyfunc_fail; + } } for (i = 0; i < saved_ob_size ; i++) { @@ -1970,7 +1973,7 @@ listsort(PyListObject *self, PyObject *args, PyObject *kwds) if (keys[i] == NULL) { for (i=i-1 ; i>=0 ; i--) Py_DECREF(keys[i]); - if (keys != &ms.temparray[saved_ob_size+1]) + if (saved_ob_size >= MERGESTATE_TEMP_SIZE/2) PyMem_FREE(keys); goto keyfunc_fail; } @@ -2043,7 +2046,7 @@ listsort(PyListObject *self, PyObject *args, PyObject *kwds) if (keys != NULL) { for (i = 0; i < saved_ob_size; i++) Py_DECREF(keys[i]); - if (keys != &ms.temparray[saved_ob_size+1]) + if (saved_ob_size >= MERGESTATE_TEMP_SIZE/2) PyMem_FREE(keys); } @@ -2444,7 +2447,7 @@ list_subscript(PyListObject* self, PyObject* item) } else { PyErr_Format(PyExc_TypeError, - "list indices must be integers, not %.200s", + "list indices must be integers or slices, not %.200s", item->ob_type->tp_name); return NULL; } @@ -2608,7 +2611,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) } else { PyErr_Format(PyExc_TypeError, - "list indices must be integers, not %.200s", + "list indices must be integers or slices, not %.200s", item->ob_type->tp_name); return -1; } @@ -2811,6 +2814,8 @@ listiter_setstate(listiterobject *it, PyObject *state) 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; diff --git a/Objects/longobject.c b/Objects/longobject.c index a5c0d1b33f39..2cc158502901 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -21,7 +21,6 @@ Py_SIZE(x) < 0 ? -(sdigit)(x)->ob_digit[0] : \ (Py_SIZE(x) == 0 ? (sdigit)0 : \ (sdigit)(x)->ob_digit[0])) -#define ABS(x) ((x) < 0 ? -(x) : (x)) #if NSMALLNEGINTS + NSMALLPOSINTS > 0 /* Small integers are preallocated in this array so that they @@ -37,7 +36,9 @@ Py_ssize_t quick_int_allocs, quick_neg_int_allocs; static PyObject * get_small_int(sdigit ival) { - PyObject *v = (PyObject*)(small_ints + ival + NSMALLNEGINTS); + PyObject *v; + assert(-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS); + v = (PyObject *)&small_ints[ival + NSMALLNEGINTS]; Py_INCREF(v); #ifdef COUNT_ALLOCS if (ival >= 0) @@ -55,7 +56,7 @@ get_small_int(sdigit ival) static PyLongObject * maybe_small_long(PyLongObject *v) { - if (v && ABS(Py_SIZE(v)) <= 1) { + if (v && Py_ABS(Py_SIZE(v)) <= 1) { sdigit ival = MEDIUM_VALUE(v); if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { Py_DECREF(v); @@ -112,7 +113,7 @@ _PyLong_Negate(PyLongObject **x_p) static PyLongObject * long_normalize(PyLongObject *v) { - Py_ssize_t j = ABS(Py_SIZE(v)); + Py_ssize_t j = Py_ABS(Py_SIZE(v)); Py_ssize_t i = j; while (i > 0 && v->ob_digit[i-1] == 0) @@ -122,6 +123,56 @@ long_normalize(PyLongObject *v) 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. +*/ +PyLongObject * +_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 (PyLongObject *)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 (PyLongObject *)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 (PyLongObject *)result; +} + + /* Allocate a new int object with size digits. Return NULL and set exception if we run out of memory. */ @@ -353,28 +404,17 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) return -1; } - if (!PyLong_Check(vv)) { - PyNumberMethods *nb; - nb = vv->ob_type->tp_as_number; - if (nb == NULL || nb->nb_int == NULL) { - PyErr_SetString(PyExc_TypeError, - "an integer is required"); - return -1; - } - vv = (*nb->nb_int) (vv); - if (vv == NULL) + if (PyLong_Check(vv)) { + v = (PyLongObject *)vv; + } + else { + v = _PyLong_FromNbInt(vv); + if (v == NULL) return -1; do_decref = 1; - if (!PyLong_Check(vv)) { - Py_DECREF(vv); - PyErr_SetString(PyExc_TypeError, - "nb_int should return int object"); - return -1; - } } res = -1; - v = (PyLongObject *)vv; i = Py_SIZE(v); switch (i) { @@ -418,7 +458,7 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) } exit: if (do_decref) { - Py_DECREF(vv); + Py_DECREF(v); } return res; } @@ -636,36 +676,25 @@ _PyLong_AsUnsignedLongMask(PyObject *vv) unsigned long PyLong_AsUnsignedLongMask(PyObject *op) { - PyNumberMethods *nb; PyLongObject *lo; unsigned long val; - if (op && PyLong_Check(op)) - return _PyLong_AsUnsignedLongMask(op); - - if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL || - nb->nb_int == NULL) { - PyErr_SetString(PyExc_TypeError, "an integer is required"); + if (op == NULL) { + PyErr_BadInternalCall(); return (unsigned long)-1; } - lo = (PyLongObject*) (*nb->nb_int) (op); - if (lo == NULL) - return (unsigned long)-1; - if (PyLong_Check(lo)) { - val = _PyLong_AsUnsignedLongMask((PyObject *)lo); - Py_DECREF(lo); - if (PyErr_Occurred()) - return (unsigned long)-1; - return val; + if (PyLong_Check(op)) { + return _PyLong_AsUnsignedLongMask(op); } - else - { - Py_DECREF(lo); - PyErr_SetString(PyExc_TypeError, - "nb_int should return int object"); + + lo = _PyLong_FromNbInt(op); + if (lo == NULL) return (unsigned long)-1; - } + + val = _PyLong_AsUnsignedLongMask((PyObject *)lo); + Py_DECREF(lo); + return val; } int @@ -688,7 +717,7 @@ _PyLong_NumBits(PyObject *vv) assert(v != NULL); assert(PyLong_Check(v)); - ndigits = ABS(Py_SIZE(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]; @@ -1167,40 +1196,41 @@ PyLong_AsLongLong(PyObject *vv) PyLongObject *v; PY_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)) { - PyNumberMethods *nb; - PyObject *io; - if ((nb = vv->ob_type->tp_as_number) == NULL || - nb->nb_int == NULL) { - PyErr_SetString(PyExc_TypeError, "an integer is required"); - return -1; - } - io = (*nb->nb_int) (vv); - if (io == NULL) + + if (PyLong_Check(vv)) { + v = (PyLongObject *)vv; + } + else { + v = _PyLong_FromNbInt(vv); + if (v == NULL) return -1; - if (PyLong_Check(io)) { - bytes = PyLong_AsLongLong(io); - Py_DECREF(io); - return bytes; - } - Py_DECREF(io); - PyErr_SetString(PyExc_TypeError, "integer conversion failed"); - return -1; + do_decref = 1; } - v = (PyLongObject*)vv; + res = 0; switch(Py_SIZE(v)) { - case -1: return -(sdigit)v->ob_digit[0]; - case 0: return 0; - case 1: return v->ob_digit[0]; + 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); } - res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes, - SIZEOF_LONG_LONG, PY_LITTLE_ENDIAN, 1); /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */ if (res < 0) @@ -1280,36 +1310,25 @@ _PyLong_AsUnsignedLongLongMask(PyObject *vv) unsigned PY_LONG_LONG PyLong_AsUnsignedLongLongMask(PyObject *op) { - PyNumberMethods *nb; PyLongObject *lo; unsigned PY_LONG_LONG val; - if (op && PyLong_Check(op)) - return _PyLong_AsUnsignedLongLongMask(op); + if (op == NULL) { + PyErr_BadInternalCall(); + return (unsigned long)-1; + } - if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL || - nb->nb_int == NULL) { - PyErr_SetString(PyExc_TypeError, "an integer is required"); - return (unsigned PY_LONG_LONG)-1; + if (PyLong_Check(op)) { + return _PyLong_AsUnsignedLongLongMask(op); } - lo = (PyLongObject*) (*nb->nb_int) (op); + lo = _PyLong_FromNbInt(op); if (lo == NULL) return (unsigned PY_LONG_LONG)-1; - if (PyLong_Check(lo)) { - val = _PyLong_AsUnsignedLongLongMask((PyObject *)lo); - Py_DECREF(lo); - if (PyErr_Occurred()) - return (unsigned PY_LONG_LONG)-1; - return val; - } - else - { - Py_DECREF(lo); - PyErr_SetString(PyExc_TypeError, - "nb_int should return int object"); - return (unsigned PY_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 @@ -1339,28 +1358,17 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) return -1; } - if (!PyLong_Check(vv)) { - PyNumberMethods *nb; - nb = vv->ob_type->tp_as_number; - if (nb == NULL || nb->nb_int == NULL) { - PyErr_SetString(PyExc_TypeError, - "an integer is required"); - return -1; - } - vv = (*nb->nb_int) (vv); - if (vv == NULL) + if (PyLong_Check(vv)) { + v = (PyLongObject *)vv; + } + else { + v = _PyLong_FromNbInt(vv); + if (v == NULL) return -1; do_decref = 1; - if (!PyLong_Check(vv)) { - Py_DECREF(vv); - PyErr_SetString(PyExc_TypeError, - "nb_int should return int object"); - return -1; - } } res = -1; - v = (PyLongObject *)vv; i = Py_SIZE(v); switch (i) { @@ -1404,7 +1412,7 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) } exit: if (do_decref) { - Py_DECREF(vv); + Py_DECREF(v); } return res; } @@ -1556,7 +1564,7 @@ inplace_divrem1(digit *pout, digit *pin, Py_ssize_t size, digit n) static PyLongObject * divrem1(PyLongObject *a, digit n, digit *prem) { - const Py_ssize_t size = ABS(Py_SIZE(a)); + const Py_ssize_t size = Py_ABS(Py_SIZE(a)); PyLongObject *z; assert(n > 0 && n <= PyLong_MASK); @@ -1574,10 +1582,12 @@ divrem1(PyLongObject *a, digit n, digit *prem) static int long_to_decimal_string_internal(PyObject *aa, PyObject **p_output, - _PyUnicodeWriter *writer) + _PyUnicodeWriter *writer, + _PyBytesWriter *bytes_writer, + char **bytes_str) { PyLongObject *scratch, *a; - PyObject *str; + PyObject *str = NULL; Py_ssize_t size, strlen, size_a, i, j; digit *pout, *pin, rem, tenpow; int negative; @@ -1588,7 +1598,7 @@ long_to_decimal_string_internal(PyObject *aa, PyErr_BadInternalCall(); return -1; } - size_a = ABS(Py_SIZE(a)); + size_a = Py_ABS(Py_SIZE(a)); negative = Py_SIZE(a) < 0; /* quick and dirty upper bound for the number of digits @@ -1654,7 +1664,13 @@ long_to_decimal_string_internal(PyObject *aa, return -1; } kind = writer->kind; - str = NULL; + } + 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'); @@ -1665,13 +1681,8 @@ long_to_decimal_string_internal(PyObject *aa, kind = PyUnicode_KIND(str); } -#define WRITE_DIGITS(TYPE) \ +#define WRITE_DIGITS(p) \ do { \ - if (writer) \ - p = (TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos + strlen; \ - else \ - p = (TYPE*)PyUnicode_DATA(str) + strlen; \ - \ /* pout[0] through pout[size-2] contribute exactly \ _PyLong_DECIMAL_SHIFT digits each */ \ for (i=0; i < size - 1; i++) { \ @@ -1691,6 +1702,16 @@ long_to_decimal_string_internal(PyObject *aa, /* 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) \ @@ -1700,25 +1721,34 @@ long_to_decimal_string_internal(PyObject *aa, } while (0) /* fill the string right-to-left */ - if (kind == PyUnicode_1BYTE_KIND) { + 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_DIGITS(Py_UCS1); + WRITE_UNICODE_DIGITS(Py_UCS1); } else if (kind == PyUnicode_2BYTE_KIND) { Py_UCS2 *p; - WRITE_DIGITS(Py_UCS2); + WRITE_UNICODE_DIGITS(Py_UCS2); } else { Py_UCS4 *p; assert (kind == PyUnicode_4BYTE_KIND); - WRITE_DIGITS(Py_UCS4); + 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; @@ -1730,7 +1760,7 @@ static PyObject * long_to_decimal_string(PyObject *aa) { PyObject *v; - if (long_to_decimal_string_internal(aa, &v, NULL) == -1) + if (long_to_decimal_string_internal(aa, &v, NULL, NULL, NULL) == -1) return NULL; return v; } @@ -1742,10 +1772,11 @@ long_to_decimal_string(PyObject *aa) static int long_format_binary(PyObject *aa, int base, int alternate, - PyObject **p_output, _PyUnicodeWriter *writer) + PyObject **p_output, _PyUnicodeWriter *writer, + _PyBytesWriter *bytes_writer, char **bytes_str) { PyLongObject *a = (PyLongObject *)aa; - PyObject *v; + PyObject *v = NULL; Py_ssize_t sz; Py_ssize_t size_a; enum PyUnicode_Kind kind; @@ -1757,7 +1788,7 @@ long_format_binary(PyObject *aa, int base, int alternate, PyErr_BadInternalCall(); return -1; } - size_a = ABS(Py_SIZE(a)); + size_a = Py_ABS(Py_SIZE(a)); negative = Py_SIZE(a) < 0; /* Compute a rough upper bound for the length of the string */ @@ -1802,7 +1833,11 @@ long_format_binary(PyObject *aa, int base, int alternate, if (_PyUnicodeWriter_Prepare(writer, sz, 'x') == -1) return -1; kind = writer->kind; - v = NULL; + } + 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'); @@ -1811,13 +1846,8 @@ long_format_binary(PyObject *aa, int base, int alternate, kind = PyUnicode_KIND(v); } -#define WRITE_DIGITS(TYPE) \ +#define WRITE_DIGITS(p) \ do { \ - if (writer) \ - p = (TYPE*)PyUnicode_DATA(writer->buffer) + writer->pos + sz; \ - else \ - p = (TYPE*)PyUnicode_DATA(v) + sz; \ - \ if (size_a == 0) { \ *--p = '0'; \ } \ @@ -1852,30 +1882,50 @@ long_format_binary(PyObject *aa, int base, int alternate, } \ 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 (kind == PyUnicode_1BYTE_KIND) { + 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_DIGITS(Py_UCS1); + WRITE_UNICODE_DIGITS(Py_UCS1); } else if (kind == PyUnicode_2BYTE_KIND) { Py_UCS2 *p; - WRITE_DIGITS(Py_UCS2); + WRITE_UNICODE_DIGITS(Py_UCS2); } else { Py_UCS4 *p; assert (kind == PyUnicode_4BYTE_KIND); - WRITE_DIGITS(Py_UCS4); + 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; @@ -1889,9 +1939,9 @@ _PyLong_Format(PyObject *obj, int base) PyObject *str; int err; if (base == 10) - err = long_to_decimal_string_internal(obj, &str, NULL); + err = long_to_decimal_string_internal(obj, &str, NULL, NULL, NULL); else - err = long_format_binary(obj, base, 1, &str, NULL); + err = long_format_binary(obj, base, 1, &str, NULL, NULL, NULL); if (err == -1) return NULL; return str; @@ -1903,9 +1953,31 @@ _PyLong_FormatWriter(_PyUnicodeWriter *writer, int base, int alternate) { if (base == 10) - return long_to_decimal_string_internal(obj, NULL, writer); + return long_to_decimal_string_internal(obj, NULL, writer, + NULL, NULL); else - return long_format_binary(obj, base, alternate, NULL, writer); + 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. @@ -2304,7 +2376,7 @@ _PyLong_FromBytes(const char *s, Py_ssize_t len, int base) PyObject *result, *strobj; char *end = NULL; - result = PyLong_FromString((char*)s, &end, base); + result = PyLong_FromString(s, &end, base); if (end == NULL || (result != NULL && end == s + len)) return result; Py_XDECREF(result); @@ -2371,7 +2443,7 @@ static int long_divrem(PyLongObject *a, PyLongObject *b, PyLongObject **pdiv, PyLongObject **prem) { - Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(b)); + Py_ssize_t size_a = Py_ABS(Py_SIZE(a)), size_b = Py_ABS(Py_SIZE(b)); PyLongObject *z; if (size_b == 0) { @@ -2430,7 +2502,7 @@ long_divrem(PyLongObject *a, PyLongObject *b, } /* Unsigned int division with remainder -- the algorithm. The arguments v1 - and w1 should satisfy 2 <= ABS(Py_SIZE(w1)) <= ABS(Py_SIZE(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) @@ -2450,8 +2522,8 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) that won't overflow a digit. */ /* allocate space; w will also be used to hold the final remainder */ - size_v = ABS(Py_SIZE(v1)); - size_w = ABS(Py_SIZE(w1)); + 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) { @@ -2582,7 +2654,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) multiple of 4, rounding ties to a multiple of 8. */ static const int half_even_correction[8] = {0, -1, -2, 1, 0, -1, 2, 1}; - a_size = ABS(Py_SIZE(a)); + a_size = Py_ABS(Py_SIZE(a)); if (a_size == 0) { /* Special case for 0: significand 0.0, exponent 0. */ *e = 0; @@ -2723,7 +2795,7 @@ long_compare(PyLongObject *a, PyLongObject *b) sign = Py_SIZE(a) - Py_SIZE(b); } else { - Py_ssize_t i = ABS(Py_SIZE(a)); + Py_ssize_t i = Py_ABS(Py_SIZE(a)); while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i]) ; if (i < 0) @@ -2841,7 +2913,7 @@ long_hash(PyLongObject *v) static PyLongObject * x_add(PyLongObject *a, PyLongObject *b) { - Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(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; @@ -2875,7 +2947,7 @@ x_add(PyLongObject *a, PyLongObject *b) static PyLongObject * x_sub(PyLongObject *a, PyLongObject *b) { - Py_ssize_t size_a = ABS(Py_SIZE(a)), size_b = ABS(Py_SIZE(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; @@ -2935,7 +3007,7 @@ long_add(PyLongObject *a, PyLongObject *b) CHECK_BINOP(a, b); - if (ABS(Py_SIZE(a)) <= 1 && ABS(Py_SIZE(b)) <= 1) { + if (Py_ABS(Py_SIZE(a)) <= 1 && Py_ABS(Py_SIZE(b)) <= 1) { PyObject *result = PyLong_FromLong(MEDIUM_VALUE(a) + MEDIUM_VALUE(b)); return result; @@ -2965,7 +3037,7 @@ long_sub(PyLongObject *a, PyLongObject *b) CHECK_BINOP(a, b); - if (ABS(Py_SIZE(a)) <= 1 && ABS(Py_SIZE(b)) <= 1) { + if (Py_ABS(Py_SIZE(a)) <= 1 && Py_ABS(Py_SIZE(b)) <= 1) { PyObject* r; r = PyLong_FromLong(MEDIUM_VALUE(a)-MEDIUM_VALUE(b)); return r; @@ -2994,8 +3066,8 @@ static PyLongObject * x_mul(PyLongObject *a, PyLongObject *b) { PyLongObject *z; - Py_ssize_t size_a = ABS(Py_SIZE(a)); - Py_ssize_t size_b = ABS(Py_SIZE(b)); + 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); @@ -3089,7 +3161,7 @@ kmul_split(PyLongObject *n, { PyLongObject *hi, *lo; Py_ssize_t size_lo, size_hi; - const Py_ssize_t size_n = ABS(Py_SIZE(n)); + const Py_ssize_t size_n = Py_ABS(Py_SIZE(n)); size_lo = Py_MIN(size_n, size); size_hi = size_n - size_lo; @@ -3118,8 +3190,8 @@ static PyLongObject *k_lopsided_mul(PyLongObject *a, PyLongObject *b); static PyLongObject * k_mul(PyLongObject *a, PyLongObject *b) { - Py_ssize_t asize = ABS(Py_SIZE(a)); - Py_ssize_t bsize = ABS(Py_SIZE(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; @@ -3339,8 +3411,8 @@ ah*bh and al*bl too. static PyLongObject * k_lopsided_mul(PyLongObject *a, PyLongObject *b) { - const Py_ssize_t asize = ABS(Py_SIZE(a)); - Py_ssize_t bsize = ABS(Py_SIZE(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; @@ -3398,7 +3470,7 @@ long_mul(PyLongObject *a, PyLongObject *b) CHECK_BINOP(a, b); /* fast path for single-digit multiplication */ - if (ABS(Py_SIZE(a)) <= 1 && ABS(Py_SIZE(b)) <= 1) { + if (Py_ABS(Py_SIZE(a)) <= 1 && Py_ABS(Py_SIZE(b)) <= 1) { stwodigits v = (stwodigits)(MEDIUM_VALUE(a)) * MEDIUM_VALUE(b); #ifdef HAVE_LONG_LONG return PyLong_FromLongLong((PY_LONG_LONG)v); @@ -3605,8 +3677,8 @@ long_true_divide(PyObject *v, PyObject *w) */ /* Reduce to case where a and b are both positive. */ - a_size = ABS(Py_SIZE(a)); - b_size = ABS(Py_SIZE(b)); + 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, @@ -3722,7 +3794,7 @@ long_true_divide(PyObject *v, PyObject *w) inexact = 1; Py_DECREF(rem); } - x_size = ABS(Py_SIZE(x)); + 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]); @@ -3832,7 +3904,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) if (Py_SIZE(b) < 0) { /* if exponent is negative */ if (c) { - PyErr_SetString(PyExc_TypeError, "pow() 2nd argument " + PyErr_SetString(PyExc_ValueError, "pow() 2nd argument " "cannot be negative when 3rd argument specified"); goto Error; } @@ -3994,7 +4066,7 @@ long_invert(PyLongObject *v) /* Implement ~x as -(x+1) */ PyLongObject *x; PyLongObject *w; - if (ABS(Py_SIZE(v)) <=1) + if (Py_ABS(Py_SIZE(v)) <=1) return PyLong_FromLong(-(MEDIUM_VALUE(v)+1)); w = (PyLongObject *)PyLong_FromLong(1L); if (w == NULL) @@ -4011,7 +4083,7 @@ static PyObject * long_neg(PyLongObject *v) { PyLongObject *z; - if (ABS(Py_SIZE(v)) <= 1) + if (Py_ABS(Py_SIZE(v)) <= 1) return PyLong_FromLong(-MEDIUM_VALUE(v)); z = (PyLongObject *)_PyLong_Copy(v); if (z != NULL) @@ -4066,7 +4138,7 @@ long_rshift(PyLongObject *a, PyLongObject *b) goto rshift_error; } wordshift = shiftby / PyLong_SHIFT; - newsize = ABS(Py_SIZE(a)) - wordshift; + newsize = Py_ABS(Py_SIZE(a)) - wordshift; if (newsize <= 0) return PyLong_FromLong(0); loshift = shiftby % PyLong_SHIFT; @@ -4113,7 +4185,7 @@ long_lshift(PyObject *v, PyObject *w) wordshift = shiftby / PyLong_SHIFT; remshift = shiftby - wordshift * PyLong_SHIFT; - oldsize = ABS(Py_SIZE(a)); + oldsize = Py_ABS(Py_SIZE(a)); newsize = oldsize + wordshift; if (remshift) ++newsize; @@ -4174,7 +4246,7 @@ long_bitwise(PyLongObject *a, result back to sign-magnitude at the end. */ /* If a is negative, replace it by its two's complement. */ - size_a = ABS(Py_SIZE(a)); + size_a = Py_ABS(Py_SIZE(a)); nega = Py_SIZE(a) < 0; if (nega) { z = _PyLong_New(size_a); @@ -4188,7 +4260,7 @@ long_bitwise(PyLongObject *a, Py_INCREF(a); /* Same for b. */ - size_b = ABS(Py_SIZE(b)); + size_b = Py_ABS(Py_SIZE(b)); negb = Py_SIZE(b) < 0; if (negb) { z = _PyLong_New(size_b); @@ -4319,6 +4391,213 @@ long_long(PyObject *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 defined(PY_LONG_LONG) && 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 defined(PY_LONG_LONG) && 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) { @@ -4621,7 +4900,7 @@ long_sizeof(PyLongObject *v) { Py_ssize_t res; - res = offsetof(PyLongObject, ob_digit) + ABS(Py_SIZE(v))*sizeof(digit); + res = offsetof(PyLongObject, ob_digit) + Py_ABS(Py_SIZE(v))*sizeof(digit); return PyLong_FromSsize_t(res); } @@ -4635,7 +4914,7 @@ long_bit_length(PyLongObject *v) assert(v != NULL); assert(PyLong_Check(v)); - ndigits = ABS(Py_SIZE(v)); + ndigits = Py_ABS(Py_SIZE(v)); if (ndigits == 0) return PyLong_FromLong(0); @@ -4840,7 +5119,7 @@ long_from_bytes(PyTypeObject *type, PyObject *args, PyObject *kwds) if (type != &PyLong_Type && PyType_IsSubtype(type, &PyLong_Type)) { PyLongObject *newobj; int i; - Py_ssize_t n = ABS(Py_SIZE(long_obj)); + Py_ssize_t n = Py_ABS(Py_SIZE(long_obj)); newobj = (PyLongObject *)type->tp_alloc(type, n); if (newobj == NULL) { @@ -4865,9 +5144,7 @@ PyDoc_STRVAR(long_from_bytes_doc, \n\ Return the integer represented by the given array of bytes.\n\ \n\ -The bytes argument must either support the buffer protocol or be an\n\ -iterable object producing bytes. Bytes and bytearray are examples of\n\ -built-in objects that support the buffer protocol.\n\ +The bytes argument must be a bytes-like object (e.g. bytes or bytearray).\n\ \n\ The byteorder argument determines the byte order used to represent the\n\ integer. If byteorder is 'big', the most significant byte is at the\n\ @@ -5086,13 +5363,13 @@ _PyLong_Init(void) * to the original refcnt + 1 */ Py_REFCNT(op) = refcnt + 1; assert(Py_SIZE(op) == size); - assert(v->ob_digit[0] == abs(ival)); + assert(v->ob_digit[0] == (digit)abs(ival)); } else { - PyObject_INIT(v, &PyLong_Type); + (void)PyObject_INIT(v, &PyLong_Type); } Py_SIZE(v) = size; - v->ob_digit[0] = abs(ival); + v->ob_digit[0] = (digit)abs(ival); } #endif /* initialize int_info */ diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index cb644b822b7a..74cad7dc0ef5 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -1,6 +1,7 @@ /* Memoryview object implementation */ #include "Python.h" +#include "pystrhex.h" #include @@ -48,9 +49,6 @@ */ -#define XSTRINGIZE(v) #v -#define STRINGIZE(v) XSTRINGIZE(v) - #define CHECK_MBUF_RELEASED(mbuf) \ if (((_PyManagedBufferObject *)mbuf)->flags&_Py_MANAGED_BUFFER_RELEASED) { \ PyErr_SetString(PyExc_ValueError, \ @@ -195,10 +193,10 @@ PyTypeObject _PyManagedBuffer_Type = { #define VIEW_ADDR(mv) (&((PyMemoryViewObject *)mv)->view) /* Check for the presence of suboffsets in the first dimension. */ -#define HAVE_PTR(suboffsets) (suboffsets && suboffsets[0] >= 0) +#define HAVE_PTR(suboffsets, dim) (suboffsets && suboffsets[dim] >= 0) /* Adjust ptr if suboffsets are present. */ -#define ADJUST_PTR(ptr, suboffsets) \ - (HAVE_PTR(suboffsets) ? *((char**)ptr) + suboffsets[0] : ptr) +#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)) @@ -223,7 +221,7 @@ PyTypeObject _PyManagedBuffer_Type = { PyDoc_STRVAR(memory_doc, -"memoryview(object)\n\ +"memoryview($module, object)\n--\n\ \n\ Create a new memoryview object which references the given object."); @@ -335,11 +333,11 @@ copy_base(const Py_ssize_t *shape, Py_ssize_t itemsize, 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); + 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); + char *xdptr = ADJUST_PTR(dptr, dsuboffsets, 0); memcpy(xdptr, p, itemsize); } } @@ -367,8 +365,8 @@ copy_rec(const Py_ssize_t *shape, Py_ssize_t ndim, Py_ssize_t itemsize, } for (i = 0; i < shape[0]; dptr+=dstrides[0], sptr+=sstrides[0], i++) { - char *xdptr = ADJUST_PTR(dptr, dsuboffsets); - char *xsptr = ADJUST_PTR(sptr, ssuboffsets); + 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, @@ -660,7 +658,7 @@ mbuf_add_view(_PyManagedBufferObject *mbuf, const Py_buffer *src) if (src->ndim > PyBUF_MAX_NDIM) { PyErr_SetString(PyExc_ValueError, "memoryview: number of dimensions must not exceed " - STRINGIZE(PyBUF_MAX_NDIM)); + Py_STRINGIFY(PyBUF_MAX_NDIM)); return NULL; } @@ -795,7 +793,7 @@ PyMemoryView_FromObject(PyObject *v) } PyErr_Format(PyExc_TypeError, - "memoryview: %.200s object does not have the buffer interface", + "memoryview: a bytes-like object is required, not '%.200s'", Py_TYPE(v)->tp_name); return NULL; } @@ -895,7 +893,7 @@ memory_from_contiguous_copy(Py_buffer *src, char order) 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. @@ -1135,6 +1133,51 @@ get_native_fmtchar(char *result, const char *fmt) return -1; } +Py_LOCAL_INLINE(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"); + #ifdef HAVE_LONG_LONG + case 'q': RETURN("q"); + case 'Q': RETURN("Q"); + #endif + case 'n': RETURN("n"); + case 'N': RETURN("N"); + case 'f': RETURN("f"); + case 'd': RETURN("d"); + #ifdef HAVE_C99_BOOL + case '?': RETURN("?"); + #else + case '?': RETURN("?"); + #endif + 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 @@ -1154,13 +1197,6 @@ cast_to_1D(PyMemoryViewObject *mv, PyObject *format) assert(view->strides == mv->ob_array + view->ndim); assert(view->suboffsets == mv->ob_array + 2*view->ndim); - if (get_native_fmtchar(&srcchar, view->format) < 0) { - PyErr_SetString(PyExc_ValueError, - "memoryview: source format must be a native single character " - "format prefixed with an optional '@'"); - return ret; - } - asciifmt = PyUnicode_AsASCIIString(format); if (asciifmt == NULL) return ret; @@ -1173,7 +1209,8 @@ cast_to_1D(PyMemoryViewObject *mv, PyObject *format) goto out; } - if (!IS_BYTE_FORMAT(srcchar) && !IS_BYTE_FORMAT(destchar)) { + 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; @@ -1184,10 +1221,13 @@ cast_to_1D(PyMemoryViewObject *mv, PyObject *format) goto out; } - strncpy(mv->format, PyBytes_AS_STRING(asciifmt), - _Py_MEMORYVIEW_MAX_FORMAT); - mv->format[_Py_MEMORYVIEW_MAX_FORMAT-1] = '\0'; - view->format = mv->format; + view->format = 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; @@ -1196,7 +1236,7 @@ cast_to_1D(PyMemoryViewObject *mv, PyObject *format) view->suboffsets = NULL; init_flags(mv); - + ret = 0; out: @@ -1341,7 +1381,7 @@ memory_cast(PyMemoryViewObject *self, PyObject *args, PyObject *kwds) if (ndim > PyBUF_MAX_NDIM) { PyErr_SetString(PyExc_ValueError, "memoryview: number of dimensions must not exceed " - STRINGIZE(PyBUF_MAX_NDIM)); + Py_STRINGIFY(PyBUF_MAX_NDIM)); return NULL; } if (self->view.ndim != 1 && ndim != 1) { @@ -2012,7 +2052,7 @@ tolist_base(const char *ptr, const Py_ssize_t *shape, return NULL; for (i = 0; i < shape[0]; ptr+=strides[0], i++) { - const char *xptr = ADJUST_PTR(ptr, suboffsets); + const char *xptr = ADJUST_PTR(ptr, suboffsets, 0); item = unpack_single(xptr, fmt); if (item == NULL) { Py_DECREF(lst); @@ -2046,7 +2086,7 @@ tolist_rec(const char *ptr, Py_ssize_t ndim, const Py_ssize_t *shape, return NULL; for (i = 0; i < shape[0]; ptr+=strides[0], i++) { - const char *xptr = ADJUST_PTR(ptr, suboffsets); + const char *xptr = ADJUST_PTR(ptr, suboffsets, 0); item = tolist_rec(xptr, ndim-1, shape+1, strides+1, suboffsets ? suboffsets+1 : NULL, fmt); @@ -2112,6 +2152,14 @@ memory_tobytes(PyMemoryViewObject *self, PyObject *dummy) return bytes; } +static PyObject * +memory_hex(PyMemoryViewObject *self, PyObject *dummy) +{ + Py_buffer *src = VIEW_ADDR(self); + CHECK_RELEASED(self); + return _Py_strhex(src->buf, src->len); +} + static PyObject * memory_repr(PyMemoryViewObject *self) { @@ -2126,33 +2174,66 @@ memory_repr(PyMemoryViewObject *self) /* Indexing and slicing */ /**************************************************************************/ -/* Get the pointer to the item at index. */ static char * -ptr_from_index(Py_buffer *view, Py_ssize_t index) +lookup_dimension(Py_buffer *view, char *ptr, int dim, Py_ssize_t index) { - char *ptr; - Py_ssize_t nitems; /* items in the first dimension */ + Py_ssize_t nitems; /* items in the given dimension */ assert(view->shape); assert(view->strides); - nitems = view->shape[0]; + nitems = view->shape[dim]; if (index < 0) { index += nitems; } if (index < 0 || index >= nitems) { - PyErr_SetString(PyExc_IndexError, "index out of bounds"); + PyErr_Format(PyExc_IndexError, + "index out of bounds on dimension %d", dim + 1); return NULL; } - ptr = (char *)view->buf; - ptr += view->strides[0] * index; + ptr += view->strides[dim] * index; - ptr = ADJUST_PTR(ptr, view->suboffsets); + 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, 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. */ @@ -2184,6 +2265,32 @@ memory_item(PyMemoryViewObject *self, Py_ssize_t index) 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); +} + Py_LOCAL_INLINE(int) init_slice(Py_buffer *base, PyObject *key, int dim) { @@ -2232,6 +2339,22 @@ is_multislice(PyObject *key) 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. @@ -2243,7 +2366,7 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key) { Py_buffer *view; view = &(self->view); - + CHECK_RELEASED(self); if (view->ndim == 0) { @@ -2287,6 +2410,9 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key) 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"); @@ -2331,14 +2457,15 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value) return -1; } } - if (view->ndim != 1) { - PyErr_SetString(PyExc_NotImplementedError, - "memoryview assignments are currently restricted to ndim = 1"); - return -1; - } if (PyIndex_Check(key)) { - Py_ssize_t index = PyNumber_AsSsize_t(key, PyExc_IndexError); + 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); @@ -2373,7 +2500,19 @@ memory_ass_sub(PyMemoryViewObject *self, PyObject *key, PyObject *value) PyBuffer_Release(&src); return ret; } - else if (PySlice_Check(key) || is_multislice(key)) { + 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, @@ -2546,8 +2685,8 @@ cmp_base(const char *p, const char *q, const Py_ssize_t *shape, int equal; for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) { - const char *xp = ADJUST_PTR(p, psuboffsets); - const char *xq = ADJUST_PTR(q, qsuboffsets); + 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; @@ -2581,8 +2720,8 @@ cmp_rec(const char *p, const char *q, } for (i = 0; i < shape[0]; p+=pstrides[0], q+=qstrides[0], i++) { - const char *xp = ADJUST_PTR(p, psuboffsets); - const char *xq = ADJUST_PTR(q, qsuboffsets); + 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, @@ -2900,6 +3039,7 @@ PyDoc_STRVAR(memory_f_contiguous_doc, 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}, @@ -2917,25 +3057,30 @@ static PyGetSetDef memory_getsetlist[] = { }; PyDoc_STRVAR(memory_release_doc, -"M.release() -> None\n\ +"release($self, /)\n--\n\ \n\ Release the underlying buffer exposed by the memoryview object."); PyDoc_STRVAR(memory_tobytes_doc, -"M.tobytes() -> bytes\n\ +"tobytes($self, /)\n--\n\ \n\ Return the data in the buffer as a byte string."); +PyDoc_STRVAR(memory_hex_doc, +"hex($self, /)\n--\n\ +\n\ +Return the data in the buffer as a string of hexadecimal numbers."); PyDoc_STRVAR(memory_tolist_doc, -"M.tolist() -> list\n\ +"tolist($self, /)\n--\n\ \n\ Return the data in the buffer as a list of elements."); PyDoc_STRVAR(memory_cast_doc, -"M.cast(format[, shape]) -> memoryview\n\ +"cast($self, /, format, *, shape)\n--\n\ \n\ Cast a memoryview to a new format or shape."); static PyMethodDef memory_methods[] = { {"release", (PyCFunction)memory_release, METH_NOARGS, memory_release_doc}, {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, memory_tobytes_doc}, + {"hex", (PyCFunction)memory_hex, METH_NOARGS, memory_hex_doc}, {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, memory_tolist_doc}, {"cast", (PyCFunction)memory_cast, METH_VARARGS|METH_KEYWORDS, memory_cast_doc}, {"__enter__", memory_enter, METH_NOARGS, NULL}, diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 55a7d6a35eaf..946357f24a9a 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -16,7 +16,7 @@ static int numfree = 0; /* undefine macro trampoline to PyCFunction_NewEx */ #undef PyCFunction_New -PyObject * +PyAPI_FUNC(PyObject *) PyCFunction_New(PyMethodDef *ml, PyObject *self) { return PyCFunction_NewEx(ml, self, NULL); @@ -29,7 +29,7 @@ PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) op = free_list; if (op != NULL) { free_list = (PyCFunctionObject *)(op->m_self); - PyObject_INIT(op, &PyCFunction_Type); + (void)PyObject_INIT(op, &PyCFunction_Type); numfree--; } else { @@ -37,6 +37,7 @@ PyCFunction_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) if (op == NULL) return NULL; } + op->m_weakreflist = NULL; op->m_ml = ml; Py_XINCREF(self); op->m_self = self; @@ -77,68 +78,71 @@ PyCFunction_GetFlags(PyObject *op) } PyObject * -PyCFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) +PyCFunction_Call(PyObject *func, PyObject *args, PyObject *kwds) { -#define CHECK_RESULT(res) assert(res != NULL || PyErr_Occurred()) - PyCFunctionObject* f = (PyCFunctionObject*)func; PyCFunction meth = PyCFunction_GET_FUNCTION(func); PyObject *self = PyCFunction_GET_SELF(func); - PyObject *res; + PyObject *arg, *res; Py_ssize_t size; + int flags; - switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST)) { - case METH_VARARGS: - if (kw == NULL || PyDict_Size(kw) == 0) { - res = (*meth)(self, arg); - CHECK_RESULT(res); - return res; - } - break; - case METH_VARARGS | METH_KEYWORDS: - res = (*(PyCFunctionWithKeywords)meth)(self, arg, kw); - CHECK_RESULT(res); - return res; - case METH_NOARGS: - if (kw == NULL || PyDict_Size(kw) == 0) { - size = PyTuple_GET_SIZE(arg); - if (size == 0) { - res = (*meth)(self, NULL); - CHECK_RESULT(res); - return res; - } - PyErr_Format(PyExc_TypeError, - "%.200s() takes no arguments (%zd given)", - f->m_ml->ml_name, size); + /* PyCFunction_Call() must not be called with an exception set, + because it may clear it (directly or indirectly) and so the + caller loses its exception */ + assert(!PyErr_Occurred()); + + flags = PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST); + + if (flags == (METH_VARARGS | METH_KEYWORDS)) { + res = (*(PyCFunctionWithKeywords)meth)(self, args, kwds); + } + else { + if (kwds != NULL && PyDict_Size(kwds) != 0) { + PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", + f->m_ml->ml_name); return NULL; } - break; - case METH_O: - if (kw == NULL || PyDict_Size(kw) == 0) { - size = PyTuple_GET_SIZE(arg); - if (size == 1) { - res = (*meth)(self, PyTuple_GET_ITEM(arg, 0)); - CHECK_RESULT(res); - return res; + + switch (flags) { + case METH_VARARGS: + res = (*meth)(self, args); + break; + + case METH_NOARGS: + size = PyTuple_GET_SIZE(args); + if (size != 0) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes no arguments (%zd given)", + f->m_ml->ml_name, size); + return NULL; } - PyErr_Format(PyExc_TypeError, - "%.200s() takes exactly one argument (%zd given)", - f->m_ml->ml_name, size); + + res = (*meth)(self, NULL); + break; + + case METH_O: + size = PyTuple_GET_SIZE(args); + if (size != 1) { + PyErr_Format(PyExc_TypeError, + "%.200s() takes exactly one argument (%zd given)", + f->m_ml->ml_name, size); + return NULL; + } + + arg = PyTuple_GET_ITEM(args, 0); + res = (*meth)(self, arg); + break; + + default: + PyErr_SetString(PyExc_SystemError, + "Bad call flags in PyCFunction_Call. " + "METH_OLDARGS is no longer supported!"); return NULL; } - break; - default: - PyErr_SetString(PyExc_SystemError, "Bad call flags in " - "PyCFunction_Call. METH_OLDARGS is no " - "longer supported!"); - - return NULL; } - PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", - f->m_ml->ml_name); - return NULL; -#undef CHECK_RESULT + return _Py_CheckFunctionResult(func, res, NULL); } /* Methods (the standard built-in methods, that is) */ @@ -147,6 +151,9 @@ 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) { @@ -179,75 +186,16 @@ static PyMethodDef meth_methods[] = { {NULL, NULL} }; -/* - * finds the docstring's introspection signature. - * if present, returns a pointer pointing to the first '('. - * otherwise returns NULL. - */ -static const char *find_signature(PyCFunctionObject *m) -{ - const char *trace = m->m_ml->ml_doc; - const char *name = m->m_ml->ml_name; - size_t length; - if (!trace || !name) - return NULL; - length = strlen(name); - if (strncmp(trace, name, length)) - return NULL; - trace += length; - if (*trace != '(') - return NULL; - return trace; -} - -/* - * skips to the end of the docstring's instrospection signature. - */ -static const char *skip_signature(const char *trace) -{ - while (*trace && *trace != '\n') - trace++; - return trace; -} - -static const char *skip_eols(const char *trace) -{ - while (*trace == '\n') - trace++; - return trace; -} - static PyObject * meth_get__text_signature__(PyCFunctionObject *m, void *closure) { - const char *start = find_signature(m); - const char *trace; - - if (!start) { - Py_INCREF(Py_None); - return Py_None; - } - - trace = skip_signature(start); - return PyUnicode_FromStringAndSize(start, trace - start); + return _PyType_GetTextSignatureFromInternalDoc(m->m_ml->ml_name, m->m_ml->ml_doc); } static PyObject * meth_get__doc__(PyCFunctionObject *m, void *closure) { - const char *doc = find_signature(m); - - if (doc) - doc = skip_eols(skip_signature(doc)); - else - doc = m->m_ml->ml_doc; - - if (!doc) { - Py_INCREF(Py_None); - return Py_None; - } - - return PyUnicode_FromString(doc); + return _PyType_GetDocFromInternalDoc(m->m_ml->ml_name, m->m_ml->ml_doc); } static PyObject * @@ -411,7 +359,7 @@ PyTypeObject PyCFunction_Type = { (traverseproc)meth_traverse, /* tp_traverse */ 0, /* tp_clear */ meth_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ + offsetof(PyCFunctionObject, m_weakreflist), /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ meth_methods, /* tp_methods */ diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index d59475e2f3c3..7b41b0b6c474 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -20,7 +20,7 @@ static PyMemberDef module_members[] = { {0} }; -static PyTypeObject moduledef_type = { +PyTypeObject PyModuleDef_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "moduledef", /* tp_name */ sizeof(struct PyModuleDef), /* tp_size */ @@ -28,24 +28,44 @@ static PyTypeObject moduledef_type = { }; +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_SetItemString(md_dict, "__name__", name) != 0) + if (_PyDict_SetItemId(md_dict, &PyId___name__, name) != 0) return -1; - if (PyDict_SetItemString(md_dict, "__doc__", doc) != 0) + if (_PyDict_SetItemId(md_dict, &PyId___doc__, doc) != 0) return -1; - if (PyDict_SetItemString(md_dict, "__package__", Py_None) != 0) + if (_PyDict_SetItemId(md_dict, &PyId___package__, Py_None) != 0) return -1; - if (PyDict_SetItemString(md_dict, "__loader__", Py_None) != 0) + if (_PyDict_SetItemId(md_dict, &PyId___loader__, Py_None) != 0) return -1; - if (PyDict_SetItemString(md_dict, "__spec__", Py_None) != 0) + if (_PyDict_SetItemId(md_dict, &PyId___spec__, Py_None) != 0) return -1; if (PyUnicode_CheckExact(name)) { Py_INCREF(name); @@ -91,35 +111,45 @@ PyModule_New(const char *name) 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; +} PyObject * PyModule_Create2(struct PyModuleDef* module, int module_api_version) { - PyObject *d, *v, *n; - PyMethodDef *ml; const char* name; PyModuleObject *m; PyInterpreterState *interp = PyThreadState_Get()->interp; if (interp->modules == NULL) Py_FatalError("Python import machinery not initialized"); - if (PyType_Ready(&moduledef_type) < 0) + if (!PyModuleDef_Init(module)) return NULL; - if (module->m_base.m_index == 0) { - max_module_number++; - Py_REFCNT(module) = 1; - Py_TYPE(module) = &moduledef_type; - module->m_base.m_index = max_module_number; - } name = module->m_name; - if (module_api_version != PYTHON_API_VERSION && module_api_version != PYTHON_ABI_VERSION) { - int err; - err = PyErr_WarnFormat(PyExc_RuntimeWarning, 1, - "Python C API version mismatch for module %.100s: " - "This Python has API version %d, module %.100s has version %d.", - name, - PYTHON_API_VERSION, name, module_api_version); - if (err) - return NULL; + 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. @@ -150,52 +180,261 @@ PyModule_Create2(struct PyModuleDef* module, int module_api_version) memset(m->md_state, 0, module->m_size); } - d = PyModule_GetDict((PyObject*)m); if (module->m_methods != NULL) { - n = PyUnicode_FromString(name); - if (n == NULL) { + if (PyModule_AddFunctions((PyObject *) m, module->m_methods) != 0) { Py_DECREF(m); return NULL; } - for (ml = module->m_methods; ml->ml_name != NULL; ml++) { - if ((ml->ml_flags & METH_CLASS) || - (ml->ml_flags & METH_STATIC)) { - PyErr_SetString(PyExc_ValueError, - "module functions cannot set" - " METH_CLASS or METH_STATIC"); - Py_DECREF(n); - Py_DECREF(m); - return NULL; - } - v = PyCFunction_NewEx(ml, (PyObject*)m, n); - if (v == NULL) { - Py_DECREF(n); - Py_DECREF(m); - return NULL; - } - if (PyDict_SetItemString(d, ml->ml_name, v) != 0) { - Py_DECREF(v); - Py_DECREF(n); - Py_DECREF(m); - return NULL; - } - Py_DECREF(v); - } - Py_DECREF(n); } if (module->m_doc != NULL) { - v = PyUnicode_FromString(module->m_doc); - if (v == NULL || PyDict_SetItemString(d, "__doc__", v) != 0) { - Py_XDECREF(v); + if (PyModule_SetDocString((PyObject *) m, module->m_doc) != 0) { Py_DECREF(m); return NULL; } - Py_DECREF(v); } 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; + 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_New(name); + 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 = PyModule_AddFunctions(m, 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; + } + } + + 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 (PyModule_Check(module) && 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_CreateFromSlots */ + 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) +{ + PyObject *name, *func; + PyMethodDef *fdef; + + name = PyModule_GetNameObject(m); + if (name == NULL) { + return -1; + } + + 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"); + Py_DECREF(name); + return -1; + } + func = PyCFunction_NewEx(fdef, (PyObject*)m, name); + if (func == NULL) { + Py_DECREF(name); + return -1; + } + if (PyObject_SetAttrString(m, fdef->ml_name, func) != 0) { + Py_DECREF(func); + Py_DECREF(name); + return -1; + } + Py_DECREF(func); + } + Py_DECREF(name); + return 0; +} + +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) @@ -214,6 +453,7 @@ PyModule_GetDict(PyObject *m) PyObject* PyModule_GetNameObject(PyObject *m) { + _Py_IDENTIFIER(__name__); PyObject *d; PyObject *name; if (!PyModule_Check(m)) { @@ -222,7 +462,7 @@ PyModule_GetNameObject(PyObject *m) } d = ((PyModuleObject *)m)->md_dict; if (d == NULL || - (name = PyDict_GetItemString(d, "__name__")) == NULL || + (name = _PyDict_GetItemId(d, &PyId___name__)) == NULL || !PyUnicode_Check(name)) { PyErr_SetString(PyExc_SystemError, "nameless module"); @@ -245,6 +485,7 @@ PyModule_GetName(PyObject *m) PyObject* PyModule_GetFilenameObject(PyObject *m) { + _Py_IDENTIFIER(__file__); PyObject *d; PyObject *fileobj; if (!PyModule_Check(m)) { @@ -253,7 +494,7 @@ PyModule_GetFilenameObject(PyObject *m) } d = ((PyModuleObject *)m)->md_dict; if (d == NULL || - (fileobj = PyDict_GetItemString(d, "__file__")) == NULL || + (fileobj = _PyDict_GetItemId(d, &PyId___file__)) == NULL || !PyUnicode_Check(fileobj)) { PyErr_SetString(PyExc_SystemError, "module filename missing"); @@ -298,6 +539,14 @@ PyModule_GetState(PyObject* m) 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 @@ -308,11 +557,6 @@ _PyModule_Clear(PyObject *m) Py_ssize_t pos; PyObject *key, *value; - PyObject *d; - - d = ((PyModuleObject *)m)->md_dict; - if (d == NULL) - return; /* First, clear only names starting with a single underscore */ pos = 0; @@ -327,7 +571,8 @@ _PyModule_Clear(PyObject *m) else PyErr_Clear(); } - PyDict_SetItem(d, key, Py_None); + if (PyDict_SetItem(d, key, Py_None) != 0) + PyErr_Clear(); } } } @@ -346,7 +591,8 @@ _PyModule_Clear(PyObject *m) else PyErr_Clear(); } - PyDict_SetItem(d, key, Py_None); + if (PyDict_SetItem(d, key, Py_None) != 0) + PyErr_Clear(); } } } @@ -406,6 +652,31 @@ module_repr(PyModuleObject *m) return PyObject_CallMethod(interp->importlib, "_module_repr", "O", m); } +static PyObject* +module_getattro(PyModuleObject *m, PyObject *name) +{ + PyObject *attr, *mod_name; + attr = PyObject_GenericGetAttr((PyObject *)m, name); + if (attr || !PyErr_ExceptionMatches(PyExc_AttributeError)) + return attr; + PyErr_Clear(); + if (m->md_dict) { + _Py_IDENTIFIER(__name__); + mod_name = _PyDict_GetItemId(m->md_dict, &PyId___name__); + if (mod_name) { + PyErr_Format(PyExc_AttributeError, + "module '%U' has no attribute '%U'", mod_name, name); + return NULL; + } + else if (PyErr_Occurred()) { + PyErr_Clear(); + } + } + PyErr_Format(PyExc_AttributeError, + "module has no attribute '%U'", name); + return NULL; +} + static int module_traverse(PyModuleObject *m, visitproc visit, void *arg) { @@ -459,7 +730,6 @@ static PyMethodDef module_methods[] = { {0} }; - PyDoc_STRVAR(module_doc, "module(name[, doc])\n\ \n\ @@ -483,7 +753,7 @@ PyTypeObject PyModule_Type = { 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ + (getattrofunc)module_getattro, /* tp_getattro */ PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | diff --git a/Objects/namespaceobject.c b/Objects/namespaceobject.c index 720ac0d30fc0..3d27a95f1fe0 100644 --- a/Objects/namespaceobject.c +++ b/Objects/namespaceobject.c @@ -164,12 +164,11 @@ namespace_clear(_PyNamespaceObject *ns) static PyObject * namespace_richcompare(PyObject *self, PyObject *other, int op) { - if (PyObject_IsInstance(self, (PyObject *)&_PyNamespace_Type) && - PyObject_IsInstance(other, (PyObject *)&_PyNamespace_Type)) + if (PyObject_TypeCheck(self, &_PyNamespace_Type) && + PyObject_TypeCheck(other, &_PyNamespace_Type)) return PyObject_RichCompare(((_PyNamespaceObject *)self)->ns_dict, ((_PyNamespaceObject *)other)->ns_dict, op); - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; + Py_RETURN_NOTIMPLEMENTED; } diff --git a/Objects/object.c b/Objects/object.c index 62bdb49d1366..e1718eafcdbf 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -33,6 +33,22 @@ _Py_GetRefTotal(void) total -= o->ob_refcnt; return total; } + +void +_PyDebug_PrintTotalRefs(void) { + PyObject *xoptions, *value; + _Py_IDENTIFIER(showrefcount); + + xoptions = PySys_GetXOptions(); + if (xoptions == NULL) + return; + value = _PyDict_GetItemId(xoptions, &PyId_showrefcount); + if (value == Py_True) + 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. @@ -459,7 +475,7 @@ PyObject_Repr(PyObject *v) #ifdef Py_DEBUG /* PyObject_Repr() must not be called with an exception set, because it may clear it (directly or indirectly) and so the - caller looses its exception */ + caller loses its exception */ assert(!PyErr_Occurred()); #endif @@ -508,7 +524,7 @@ PyObject_Str(PyObject *v) #ifdef Py_DEBUG /* PyObject_Str() must not be called with an exception set, because it may clear it (directly or indirectly) and so the - caller looses its exception */ + caller loses its exception */ assert(!PyErr_Occurred()); #endif @@ -670,11 +686,10 @@ do_richcompare(PyObject *v, PyObject *w, int op) res = (v != w) ? Py_True : Py_False; break; default: - /* XXX Special-case None so it doesn't show as NoneType() */ PyErr_Format(PyExc_TypeError, - "unorderable types: %.100s() %s %.100s()", - v->ob_type->tp_name, + "'%s' not supported between instances of '%.100s' and '%.100s'", opstrings[op], + v->ob_type->tp_name, w->ob_type->tp_name); return NULL; } @@ -1543,6 +1558,9 @@ PyObject _Py_NotImplementedStruct = { void _Py_ReadyTypes(void) { + if (PyType_Ready(&PyBaseObject_Type) < 0) + Py_FatalError("Can't initialize object type"); + if (PyType_Ready(&PyType_Type) < 0) Py_FatalError("Can't initialize type type"); @@ -1555,6 +1573,9 @@ _Py_ReadyTypes(void) if (PyType_Ready(&_PyWeakref_ProxyType) < 0) Py_FatalError("Can't initialize weakref proxy type"); + if (PyType_Ready(&PyLong_Type) < 0) + Py_FatalError("Can't initialize int type"); + if (PyType_Ready(&PyBool_Type) < 0) Py_FatalError("Can't initialize bool type"); @@ -1579,15 +1600,27 @@ _Py_ReadyTypes(void) if (PyType_Ready(&PySuper_Type) < 0) Py_FatalError("Can't initialize super type"); - if (PyType_Ready(&PyBaseObject_Type) < 0) - Py_FatalError("Can't initialize object type"); - if (PyType_Ready(&PyRange_Type) < 0) Py_FatalError("Can't initialize range type"); if (PyType_Ready(&PyDict_Type) < 0) Py_FatalError("Can't initialize dict type"); + if (PyType_Ready(&PyODict_Type) < 0) + Py_FatalError("Can't initialize OrderedDict type"); + + if (PyType_Ready(&PyODictKeys_Type) < 0) + Py_FatalError("Can't initialize odict_keys type"); + + if (PyType_Ready(&PyODictItems_Type) < 0) + Py_FatalError("Can't initialize odict_items type"); + + if (PyType_Ready(&PyODictValues_Type) < 0) + Py_FatalError("Can't initialize odict_values type"); + + if (PyType_Ready(&PyODictIter_Type) < 0) + Py_FatalError("Can't initialize odict_keyiterator type"); + if (PyType_Ready(&PySet_Type) < 0) Py_FatalError("Can't initialize set type"); @@ -1606,9 +1639,6 @@ _Py_ReadyTypes(void) if (PyType_Ready(&PyFloat_Type) < 0) Py_FatalError("Can't initialize float type"); - if (PyType_Ready(&PyLong_Type) < 0) - Py_FatalError("Can't initialize int type"); - if (PyType_Ready(&PyFrozenSet_Type) < 0) Py_FatalError("Can't initialize frozenset type"); @@ -1695,6 +1725,12 @@ _Py_ReadyTypes(void) if (PyType_Ready(&PySeqIter_Type) < 0) Py_FatalError("Can't initialize sequence iterator type"); + + if (PyType_Ready(&PyCoro_Type) < 0) + Py_FatalError("Can't initialize coroutine type"); + + if (PyType_Ready(&_PyCoroWrapper_Type) < 0) + Py_FatalError("Can't initialize coroutine wrapper type"); } @@ -1809,9 +1845,6 @@ _Py_GetObjects(PyObject *self, PyObject *args) #endif -/* Hack to force loading of pycapsule.o */ -PyTypeObject *_PyCapsule_hack = &PyCapsule_Type; - /* Hack to force loading of abstract.o */ Py_ssize_t (*_Py_abstract_hack)(PyObject *) = PyObject_Size; @@ -1849,6 +1882,8 @@ Py_ReprEnter(PyObject *obj) 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_GetItemId(dict, &PyId_Py_Repr); diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index 004cfaac6174..7cc889f817b6 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -5,6 +5,7 @@ #ifdef PYMALLOC_DEBUG /* WITH_PYMALLOC && PYMALLOC_DEBUG */ /* Forward declaration */ static void* _PyMem_DebugMalloc(void *ctx, size_t size); +static void* _PyMem_DebugCalloc(void *ctx, size_t nelem, size_t elsize); static void _PyMem_DebugFree(void *ctx, void *p); static void* _PyMem_DebugRealloc(void *ctx, void *ptr, size_t size); @@ -43,6 +44,7 @@ static void _PyMem_DebugCheckAddress(char api_id, const void *p); /* 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 @@ -51,7 +53,7 @@ static void* _PyObject_Realloc(void *ctx, void *ptr, size_t size); static void * _PyMem_RawMalloc(void *ctx, size_t size) { - /* PyMem_Malloc(0) means malloc(1). Some systems would return NULL + /* 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. */ @@ -60,6 +62,20 @@ _PyMem_RawMalloc(void *ctx, size_t size) 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) { @@ -123,9 +139,9 @@ _PyObject_ArenaFree(void *ctx, void *ptr, size_t size) #endif -#define PYRAW_FUNCS _PyMem_RawMalloc, _PyMem_RawRealloc, _PyMem_RawFree +#define PYRAW_FUNCS _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree #ifdef WITH_PYMALLOC -# define PYOBJ_FUNCS _PyObject_Malloc, _PyObject_Realloc, _PyObject_Free +# define PYOBJ_FUNCS _PyObject_Malloc, _PyObject_Calloc, _PyObject_Realloc, _PyObject_Free #else # define PYOBJ_FUNCS PYRAW_FUNCS #endif @@ -135,7 +151,7 @@ _PyObject_ArenaFree(void *ctx, void *ptr, size_t size) typedef struct { /* We tag each block with an API ID in order to tag API violations */ char api_id; - PyMemAllocator alloc; + PyMemAllocatorEx alloc; } debug_alloc_api_t; static struct { debug_alloc_api_t raw; @@ -147,10 +163,10 @@ static struct { {'o', {NULL, PYOBJ_FUNCS}} }; -#define PYDBG_FUNCS _PyMem_DebugMalloc, _PyMem_DebugRealloc, _PyMem_DebugFree +#define PYDBG_FUNCS _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree #endif -static PyMemAllocator _PyMem_Raw = { +static PyMemAllocatorEx _PyMem_Raw = { #ifdef PYMALLOC_DEBUG &_PyMem_Debug.raw, PYDBG_FUNCS #else @@ -158,7 +174,7 @@ static PyMemAllocator _PyMem_Raw = { #endif }; -static PyMemAllocator _PyMem = { +static PyMemAllocatorEx _PyMem = { #ifdef PYMALLOC_DEBUG &_PyMem_Debug.mem, PYDBG_FUNCS #else @@ -166,7 +182,7 @@ static PyMemAllocator _PyMem = { #endif }; -static PyMemAllocator _PyObject = { +static PyMemAllocatorEx _PyObject = { #ifdef PYMALLOC_DEBUG &_PyMem_Debug.obj, PYDBG_FUNCS #else @@ -193,9 +209,10 @@ void PyMem_SetupDebugHooks(void) { #ifdef PYMALLOC_DEBUG - PyMemAllocator alloc; + PyMemAllocatorEx alloc; alloc.malloc = _PyMem_DebugMalloc; + alloc.calloc = _PyMem_DebugCalloc; alloc.realloc = _PyMem_DebugRealloc; alloc.free = _PyMem_DebugFree; @@ -220,7 +237,7 @@ PyMem_SetupDebugHooks(void) } void -PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocator *allocator) +PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) { switch(domain) { @@ -228,16 +245,17 @@ PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocator *allocator) case PYMEM_DOMAIN_MEM: *allocator = _PyMem; break; case PYMEM_DOMAIN_OBJ: *allocator = _PyObject; break; default: - /* unknown domain */ + /* 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, PyMemAllocator *allocator) +PyMem_SetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) { switch(domain) { @@ -272,10 +290,18 @@ PyMem_RawMalloc(size_t size) */ 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) { @@ -299,6 +325,15 @@ PyMem_Malloc(size_t size) 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) { @@ -351,6 +386,15 @@ PyObject_Malloc(size_t size) 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) { @@ -1122,8 +1166,9 @@ int Py_ADDRESS_IN_RANGE(void *P, poolp pool) Py_NO_INLINE; */ static void * -_PyObject_Malloc(void *ctx, size_t nbytes) +_PyObject_Alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) { + size_t nbytes; block *bp; poolp pool; poolp next; @@ -1131,6 +1176,9 @@ _PyObject_Malloc(void *ctx, size_t nbytes) _Py_AllocatedBlocks++; + assert(nelem <= PY_SSIZE_T_MAX / elsize); + nbytes = nelem * elsize; + #ifdef WITH_VALGRIND if (UNLIKELY(running_on_valgrind == -1)) running_on_valgrind = RUNNING_ON_VALGRIND; @@ -1138,9 +1186,9 @@ _PyObject_Malloc(void *ctx, size_t nbytes) goto redirect; #endif - /* - * This implicitly redirects malloc(0). - */ + if (nelem == 0 || elsize == 0) + goto redirect; + if ((nbytes - 1) < SMALL_REQUEST_THRESHOLD) { LOCK(); /* @@ -1158,6 +1206,8 @@ _PyObject_Malloc(void *ctx, size_t nbytes) assert(bp != NULL); if ((pool->freeblock = *(block **)bp) != NULL) { UNLOCK(); + if (use_calloc) + memset(bp, 0, nbytes); return (void *)bp; } /* @@ -1170,6 +1220,8 @@ _PyObject_Malloc(void *ctx, size_t nbytes) pool->nextoffset += INDEX2SIZE(size); *(block **)(pool->freeblock) = NULL; UNLOCK(); + if (use_calloc) + memset(bp, 0, nbytes); return (void *)bp; } /* Pool is full, unlink from used pools. */ @@ -1178,6 +1230,8 @@ _PyObject_Malloc(void *ctx, size_t nbytes) next->prevpool = pool; pool->nextpool = next; UNLOCK(); + if (use_calloc) + memset(bp, 0, nbytes); return (void *)bp; } @@ -1257,6 +1311,8 @@ _PyObject_Malloc(void *ctx, size_t nbytes) assert(bp != NULL); pool->freeblock = *(block **)bp; UNLOCK(); + if (use_calloc) + memset(bp, 0, nbytes); return (void *)bp; } /* @@ -1272,6 +1328,8 @@ _PyObject_Malloc(void *ctx, size_t nbytes) pool->freeblock = bp + size; *(block **)(pool->freeblock) = NULL; UNLOCK(); + if (use_calloc) + memset(bp, 0, nbytes); return (void *)bp; } @@ -1281,7 +1339,7 @@ _PyObject_Malloc(void *ctx, size_t nbytes) pool = (poolp)usable_arenas->pool_address; assert((block*)pool <= (block*)usable_arenas->address + ARENA_SIZE - POOL_SIZE); - pool->arenaindex = usable_arenas - arenas; + pool->arenaindex = (uint)(usable_arenas - arenas); assert(&arenas[pool->arenaindex] == usable_arenas); pool->szidx = DUMMY_SIZE_IDX; usable_arenas->pool_address += POOL_SIZE; @@ -1311,13 +1369,29 @@ _PyObject_Malloc(void *ctx, size_t nbytes) * has been reached. */ { - void *result = PyMem_RawMalloc(nbytes); + void *result; + if (use_calloc) + result = PyMem_RawCalloc(nelem, elsize); + else + result = PyMem_RawMalloc(nbytes); if (!result) _Py_AllocatedBlocks--; return result; } } +static void * +_PyObject_Malloc(void *ctx, size_t nbytes) +{ + return _PyObject_Alloc(0, ctx, 1, nbytes); +} + +static void * +_PyObject_Calloc(void *ctx, size_t nelem, size_t elsize) +{ + return _PyObject_Alloc(1, ctx, nelem, elsize); +} + /* free */ ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS @@ -1561,7 +1635,7 @@ _PyObject_Realloc(void *ctx, void *p, size_t nbytes) #endif if (p == NULL) - return _PyObject_Malloc(ctx, nbytes); + return _PyObject_Alloc(0, ctx, 1, nbytes); #ifdef WITH_VALGRIND /* Treat running_on_valgrind == -1 the same as 0 */ @@ -1589,7 +1663,7 @@ _PyObject_Realloc(void *ctx, void *p, size_t nbytes) } size = nbytes; } - bp = _PyObject_Malloc(ctx, nbytes); + bp = _PyObject_Alloc(0, ctx, 1, nbytes); if (bp != NULL) { memcpy(bp, p, size); _PyObject_Free(ctx, p); @@ -1745,7 +1819,7 @@ p[2*S+n+S: 2*S+n+2*S] */ static void * -_PyMem_DebugMalloc(void *ctx, size_t nbytes) +_PyMem_DebugAlloc(int use_calloc, void *ctx, size_t nbytes) { debug_alloc_api_t *api = (debug_alloc_api_t *)ctx; uchar *p; /* base address of malloc'ed block */ @@ -1754,11 +1828,14 @@ _PyMem_DebugMalloc(void *ctx, size_t nbytes) bumpserialno(); total = nbytes + 4*SST; - if (total < nbytes) - /* overflow: can't represent total as a size_t */ + if (nbytes > PY_SSIZE_T_MAX - 4*SST) + /* overflow: can't represent total as a Py_ssize_t */ return NULL; - p = (uchar *)api->alloc.malloc(api->alloc.ctx, total); + if (use_calloc) + p = (uchar *)api->alloc.calloc(api->alloc.ctx, 1, total); + else + p = (uchar *)api->alloc.malloc(api->alloc.ctx, total); if (p == NULL) return NULL; @@ -1767,7 +1844,7 @@ _PyMem_DebugMalloc(void *ctx, size_t nbytes) p[SST] = (uchar)api->api_id; memset(p + SST + 1, FORBIDDENBYTE, SST-1); - if (nbytes > 0) + if (nbytes > 0 && !use_calloc) memset(p + 2*SST, CLEANBYTE, nbytes); /* at tail, write pad (SST bytes) and serialno (SST bytes) */ @@ -1778,6 +1855,21 @@ _PyMem_DebugMalloc(void *ctx, size_t nbytes) return p + 2*SST; } +static void * +_PyMem_DebugMalloc(void *ctx, size_t nbytes) +{ + return _PyMem_DebugAlloc(0, ctx, nbytes); +} + +static void * +_PyMem_DebugCalloc(void *ctx, size_t nelem, size_t elsize) +{ + size_t nbytes; + assert(elsize == 0 || nelem <= PY_SSIZE_T_MAX / elsize); + nbytes = nelem * elsize; + return _PyMem_DebugAlloc(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 DEADBYTE. @@ -1811,14 +1903,14 @@ _PyMem_DebugRealloc(void *ctx, void *p, size_t nbytes) int i; if (p == NULL) - return _PyMem_DebugMalloc(ctx, nbytes); + return _PyMem_DebugAlloc(0, ctx, nbytes); _PyMem_DebugCheckAddress(api->api_id, p); bumpserialno(); original_nbytes = read_size_t(q - 2*SST); total = nbytes + 4*SST; - if (total < nbytes) - /* overflow: can't represent total as a size_t */ + if (nbytes > PY_SSIZE_T_MAX - 4*SST) + /* overflow: can't represent total as a Py_ssize_t */ return NULL; /* Resize and add decorations. We may get a new pointer here, in which diff --git a/Objects/odictobject.c b/Objects/odictobject.c new file mode 100644 index 000000000000..a0288841a424 --- /dev/null +++ b/Objects/odictobject.c @@ -0,0 +1,2396 @@ +/* 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_enties 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) + +For removing nodes: + +* _odict_clear_node(od, node) +* _odict_clear_nodes(od, clear_each) + +Others: + +* _odict_find_node(od, key) +* _odict_keys_equal(od1, od2) + +Used, but specific to the linked-list implementation: + +* _odict_free_fast_nodes(od) + +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 funcions. +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) +tp_new odict_new +================= ================ + +================= ================ +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 invalidate 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 "structmember.h" +#include "dict-common.h" +#include + + +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 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_uintptr_t 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)) + +#define _odict_FAST_SIZE(od) ((PyDictObject *)od)->ma_keys->dk_size + +static void +_odict_free_fast_nodes(PyODictObject *od) { + if (od->od_fast_nodes) { + PyMem_FREE(od->od_fast_nodes); + } +} + +/* Return the index into the hash table, regardless of a valid node. */ +static Py_ssize_t +_odict_get_index_hash(PyODictObject *od, PyObject *key, Py_hash_t hash) +{ + PyObject **value_addr = NULL; + PyDictKeyEntry *ep; + PyDictKeysObject *keys = ((PyDictObject *)od)->ma_keys; + + ep = (keys->dk_lookup)((PyDictObject *)od, key, hash, &value_addr); + if (ep == NULL) + return -1; + /* We use pointer arithmetic to get the entry's index into the table. */ + return ep - keys->dk_entries; +} + +/* 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_hash(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. */ + _odict_free_fast_nodes(od); + od->od_fast_nodes = fast_nodes; + od->od_resize_sentinel = (Py_uintptr_t)(((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); + hash = PyObject_Hash(key); + if (hash == -1) + return -1; + keys = ((PyDictObject *)od)->ma_keys; + + /* Ensure od_fast_nodes and dk_entries are in sync. */ + if (od->od_resize_sentinel != (Py_uintptr_t)keys) { + int resize_res = _odict_resize(od); + if (resize_res < 0) + return -1; + } + + return _odict_get_index_hash(od, key, hash); +} + +/* Returns NULL if there was some error or the key was not found. */ +static _ODictNode * +_odict_find_node(PyODictObject *od, PyObject *key) +{ + Py_ssize_t index; + + if (_odict_EMPTY(od)) + return NULL; + index = _odict_get_index(od, key); + if (index < 0) + return 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; + + hash = PyObject_Hash(key); + if (hash == -1) + return -1; + + Py_INCREF(key); + i = _odict_get_index(od, key); + if (i < 0) { + if (!PyErr_Occurred()) + PyErr_SetObject(PyExc_KeyError, key); + Py_DECREF(key); + return -1; + } + else 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_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); + if (i < 0) + return PyErr_Occurred() ? -1 : 0; + + 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; + + if (!_odict_EMPTY(od)) { + node = _odict_FIRST(od); + while (node != NULL) { + next = _odictnode_NEXT(node); + _odictnode_DEALLOC(node); + node = next; + } + _odict_FIRST(od) = NULL; + _odict_LAST(od) = NULL; + } + + _odict_free_fast_nodes(od); + od->od_fast_nodes = NULL; +} + +/* 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 + */ + +/* __delitem__() */ + +PyDoc_STRVAR(odict_delitem__doc__, "od.__delitem__(y) <==> del od[y]"); + +/* __eq__() */ + +PyDoc_STRVAR(odict_eq__doc__, +"od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive \n\ + while comparison to a regular mapping is order-insensitive.\n\ + "); + +/* forward */ +static PyObject * odict_richcompare(PyObject *v, PyObject *w, int op); + +static PyObject * +odict_eq(PyObject *a, PyObject *b) +{ + return odict_richcompare(a, b, Py_EQ); +} + +/* __init__() */ + +PyDoc_STRVAR(odict_init__doc__, +"Initialize an ordered dictionary. The signature is the same as\n\ + regular dictionaries, but keyword arguments are not recommended because\n\ + their insertion order is arbitrary.\n\ +\n\ + "); + +/* forward */ +static int odict_init(PyObject *self, PyObject *args, PyObject *kwds); + +/* __iter__() */ + +PyDoc_STRVAR(odict_iter__doc__, "od.__iter__() <==> iter(od)"); + +static PyObject * odict_iter(PyODictObject *self); /* forward */ + +/* __ne__() */ + +/* Mapping.__ne__() does not have a docstring. */ +PyDoc_STRVAR(odict_ne__doc__, ""); + +static PyObject * +odict_ne(PyObject *a, PyObject *b) +{ + return odict_richcompare(a, b, Py_NE); +} + +/* __repr__() */ + +PyDoc_STRVAR(odict_repr__doc__, "od.__repr__() <==> repr(od)"); + +static PyObject * odict_repr(PyODictObject *self); /* forward */ + +/* __setitem__() */ + +PyDoc_STRVAR(odict_setitem__doc__, "od.__setitem__(i, y) <==> od[i]=y"); + +/* fromkeys() */ + +PyDoc_STRVAR(odict_fromkeys__doc__, +"OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S.\n\ + If not specified, the value defaults to None.\n\ +\n\ + "); + +static PyObject * +odict_fromkeys(PyObject *cls, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = {"iterable", "value", 0}; + PyObject *seq; + PyObject *value = Py_None; + + /* both borrowed */ + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:fromkeys", kwlist, + &seq, &value)) { + return NULL; + } + return _PyDict_FromKeys(cls, seq, value); +} + +/* __sizeof__() */ + +/* OrderedDict.__sizeof__() does not have a docstring. */ +PyDoc_STRVAR(odict_sizeof__doc__, ""); + +static PyObject * +odict_sizeof(PyODictObject *od) +{ + PyObject *pylong; + Py_ssize_t res, temp; + + pylong = _PyDict_SizeOf((PyDictObject *)od); + if (pylong == NULL) + return NULL; + res = PyLong_AsSsize_t(pylong); + Py_DECREF(pylong); + if (res == -1 && PyErr_Occurred()) + return NULL; + + res += sizeof(PyODictObject) - sizeof(PyDictObject); + + /* instance dict */ + pylong = _PyDict_SizeOf((PyDictObject *)od->od_inst_dict); + if (pylong == NULL) + return NULL; + temp = PyLong_AsSsize_t(pylong); + Py_DECREF(pylong); + if (temp == -1 && PyErr_Occurred()) + return NULL; + res += temp; + + res += sizeof(_ODictNode *) * _odict_FAST_SIZE(od); /* 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) +{ + _Py_IDENTIFIER(__dict__); + _Py_IDENTIFIER(__class__); + _Py_IDENTIFIER(items); + PyObject *dict = NULL, *result = NULL, *cls = 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 */ + cls = _PyObject_GetAttrId((PyObject *)od, &PyId___class__); + if (cls == NULL) + goto Done; + + 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, cls, args, dict ? dict : Py_None, Py_None, items_iter); + Py_DECREF(items_iter); + +Done: + Py_XDECREF(dict); + Py_XDECREF(cls); + Py_XDECREF(args); + + return result; +} + +/* setdefault() */ + +PyDoc_STRVAR(odict_setdefault__doc__, + "od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od"); + +/* Skips __missing__() calls. */ +static PyObject * +odict_setdefault(register PyODictObject *od, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = {"key", "default", 0}; + PyObject *key, *result = NULL; + PyObject *failobj = Py_None; + + /* both borrowed */ + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:setdefault", kwlist, + &key, &failobj)) { + return NULL; + } + + if (PyODict_CheckExact(od)) { + result = PyODict_GetItemWithError(od, key); /* borrowed */ + if (result == NULL) { + if (PyErr_Occurred()) + return NULL; + assert(_odict_find_node(od, key) == NULL); + if (PyODict_SetItem((PyObject *)od, key, failobj) >= 0) { + result = failobj; + Py_INCREF(failobj); + } + } + else { + Py_INCREF(result); + } + } + else { + int exists = PySequence_Contains((PyObject *)od, key); + if (exists < 0) { + return NULL; + } + else if (exists) { + result = PyObject_GetItem((PyObject *)od, key); + } + else if (PyObject_SetItem((PyObject *)od, key, failobj) >= 0) { + result = failobj; + Py_INCREF(failobj); + } + } + + 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(PyObject *od, PyObject *key, PyObject *failobj) +{ + _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((PyODictObject *)od, key); + if (node == NULL) { + if (PyErr_Occurred()) + return NULL; + } + else { + int res = _odict_clear_node((PyODictObject *)od, node, key); + if (res < 0) { + return NULL; + } + } + + /* Now delete the value from the dict. */ + if (PyODict_CheckExact(od)) { + if (node != NULL) { + /* We could do PyDict_GetItem() and PyDict_DelItem() directly... */ + value = _PyDict_Pop((PyDictObject *)od, key, failobj); + } + } + 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; +} + +/* popitem() */ + +PyDoc_STRVAR(odict_popitem__doc__, +"od.popitem() -> (k, v), return and remove a (key, value) pair.\n\ + Pairs are returned in LIFO order if last is true or FIFO order if false.\n\ +\n\ + "); + +static PyObject * +odict_popitem(PyObject *od, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = {"last", 0}; + PyObject *key, *value, *item = NULL; + _ODictNode *node; + int last = 1; + + /* pull the item */ + + /* borrowed */ + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|p:popitem", kwlist, + &last)) { + return NULL; + } + + if (_odict_EMPTY(od)) { + PyErr_SetString(PyExc_KeyError, "dictionary is empty"); + return NULL; + } + + node = last ? _odict_LAST(od) : _odict_FIRST(od); + key = _odictnode_KEY(node); + Py_INCREF(key); + value = _odict_popkey(od, key, NULL); + 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); /* forward */ + +/* values() */ + +/* MutableMapping.values() does not have a docstring. */ +PyDoc_STRVAR(odict_values__doc__, ""); + +static PyObject * odictvalues_new(PyObject *od); /* forward */ + +/* items() */ + +/* MutableMapping.items() does not have a docstring. */ +PyDoc_STRVAR(odict_items__doc__, ""); + +static PyObject * odictitems_new(PyObject *od); /* 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) +{ + PyDict_Clear((PyObject *)od); + _odict_clear_nodes(od); + _odict_FIRST(od) = NULL; + _odict_LAST(od) = NULL; + if (_odict_resize(od) < 0) + return NULL; + Py_RETURN_NONE; +} + +/* copy() */ + +PyDoc_STRVAR(odict_copy__doc__, "od.copy() -> a shallow copy of od"); + +static PyObject * +odict_copy(register PyODictObject *od) +{ + _ODictNode *node; + PyObject *od_copy; + + if (PyODict_CheckExact(od)) + od_copy = PyODict_New(); + else + od_copy = PyObject_CallFunctionObjArgs((PyObject *)Py_TYPE(od), NULL); + 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((PyObject *)od_copy, key, value) != 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) +{ + return odictiter_new(od, _odict_ITER_KEYS|_odict_ITER_REVERSED); +} + +/* move_to_end() */ + +PyDoc_STRVAR(odict_move_to_end__doc__, +"Move an existing element to the end (or beginning if last==False).\n\ +\n\ + Raises KeyError if the element does not exist.\n\ + When last=True, acts like a fast version of self[key]=self.pop(key).\n\ +\n\ + "); + +static PyObject * +odict_move_to_end(PyODictObject *od, PyObject *args, PyObject *kwargs) +{ + static char *kwlist[] = {"key", "last", 0}; + PyObject *key; + int last = 1; + _ODictNode *node; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|p:move_to_end", kwlist, + &key, &last)) { + return NULL; + } + + if (_odict_EMPTY(od)) { + PyErr_SetObject(PyExc_KeyError, key); + return NULL; + } + node = last ? _odict_LAST(od) : _odict_FIRST(od); + if (key != _odictnode_KEY(node)) { + node = _odict_find_node(od, 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(od)) { + _odict_remove_node(od, node); + _odict_add_tail(od, node); + } + } + else { + /* Only move if not already the first one. */ + if (node != _odict_FIRST(od)) { + _odict_remove_node(od, node); + _odict_add_head(od, node); + } + } + } + Py_RETURN_NONE; +} + + +/* tp_methods */ + +static PyMethodDef odict_methods[] = { + + /* explicitly defined so we can align docstrings with + * collections.OrderedDict */ + {"__delitem__", (PyCFunction)odict_mp_ass_sub, METH_NOARGS, + odict_delitem__doc__}, + {"__eq__", (PyCFunction)odict_eq, METH_NOARGS, + odict_eq__doc__}, + {"__init__", (PyCFunction)odict_init, METH_NOARGS, + odict_init__doc__}, + {"__iter__", (PyCFunction)odict_iter, METH_NOARGS, + odict_iter__doc__}, + {"__ne__", (PyCFunction)odict_ne, METH_NOARGS, + odict_ne__doc__}, + {"__repr__", (PyCFunction)odict_repr, METH_NOARGS, + odict_repr__doc__}, + {"__setitem__", (PyCFunction)odict_mp_ass_sub, METH_NOARGS, + odict_setitem__doc__}, + {"fromkeys", (PyCFunction)odict_fromkeys, + METH_VARARGS | METH_KEYWORDS | METH_CLASS, odict_fromkeys__doc__}, + + /* overridden dict methods */ + {"__sizeof__", (PyCFunction)odict_sizeof, METH_NOARGS, + odict_sizeof__doc__}, + {"__reduce__", (PyCFunction)odict_reduce, METH_NOARGS, + odict_reduce__doc__}, + {"setdefault", (PyCFunction)odict_setdefault, + METH_VARARGS | METH_KEYWORDS, odict_setdefault__doc__}, + {"pop", (PyCFunction)odict_pop, + METH_VARARGS | METH_KEYWORDS, odict_pop__doc__}, + {"popitem", (PyCFunction)odict_popitem, + METH_VARARGS | METH_KEYWORDS, odict_popitem__doc__}, + {"keys", (PyCFunction)odictkeys_new, METH_NOARGS, + odict_keys__doc__}, + {"values", (PyCFunction)odictvalues_new, METH_NOARGS, + odict_values__doc__}, + {"items", (PyCFunction)odictitems_new, METH_NOARGS, + odict_items__doc__}, + {"update", (PyCFunction)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__}, + {"move_to_end", (PyCFunction)odict_move_to_end, + METH_VARARGS | METH_KEYWORDS, odict_move_to_end__doc__}, + + {NULL, NULL} /* sentinel */ +}; + + +/* ---------------------------------------------- + * OrderedDict members + */ + +/* tp_members */ + +static PyMemberDef odict_members[] = { + {"__dict__", T_OBJECT, offsetof(PyODictObject, od_inst_dict), READONLY}, + {0} +}; + + +/* ---------------------------------------------- + * OrderedDict type slot methods + */ + +/* tp_dealloc */ + +static void +odict_dealloc(PyODictObject *self) +{ + PyObject_GC_UnTrack(self); + Py_TRASHCAN_SAFE_BEGIN(self); + Py_XDECREF(self->od_inst_dict); + if (self->od_weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *)self); + + _odict_clear_nodes(self); + Py_TRASHCAN_SAFE_END(self); + + /* must be last */ + PyDict_Type.tp_dealloc((PyObject *)self); +}; + +/* tp_repr */ + +static PyObject * +odict_repr(PyODictObject *self) +{ + int i; + _Py_IDENTIFIER(__class__); + _Py_IDENTIFIER(__name__); + _Py_IDENTIFIER(items); + Py_ssize_t count = -1; + PyObject *pieces = NULL, *result = NULL, *cls = NULL; + PyObject *classname = NULL; + + i = Py_ReprEnter((PyObject *)self); + if (i != 0) { + return i > 0 ? PyUnicode_FromString("...") : NULL; + } + + if (PyODict_SIZE(self) == 0) { + /* "OrderedDict()" */ + goto Finish; + } + + if (PyODict_CheckExact(self)) { + _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; + + PyList_SET_ITEM(pieces, ++count, pair); /* steals reference */ + } + } + 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; + } + +Finish: + cls = _PyObject_GetAttrId((PyObject *)self, &PyId___class__); + if (cls == NULL) + goto Done; + classname = _PyObject_GetAttrId(cls, &PyId___name__); + if (classname == NULL) + goto Done; + + if (pieces == NULL) + result = PyUnicode_FromFormat("%S()", classname, pieces); + else + result = PyUnicode_FromFormat("%S(%R)", classname, pieces); + +Done: + Py_XDECREF(pieces); + Py_XDECREF(cls); + Py_XDECREF(classname); + 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) +{ + Py_VISIT(od->od_inst_dict); + Py_VISIT(od->od_weakreflist); + return PyDict_Type.tp_traverse((PyObject *)od, visit, arg); +} + +/* tp_clear */ + +static int +odict_tp_clear(PyODictObject *od) +{ + PyObject *res; + Py_CLEAR(od->od_inst_dict); + Py_CLEAR(od->od_weakreflist); + res = odict_clear(od); + if (res == NULL) + return -1; + Py_DECREF(res); + 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) { + char *msg = "expected at most 1 arguments, got %d"; + 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; + } +}; + +/* tp_new */ + +static PyObject * +odict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *dict; + PyODictObject *od; + + dict = PyDict_New(); + if (dict == NULL) + return NULL; + + od = (PyODictObject *)PyDict_Type.tp_new(type, args, kwds); + if (od == NULL) { + Py_DECREF(dict); + return NULL; + } + + od->od_inst_dict = dict; + /* type constructor fills the memory with zeros (see + PyType_GenericAlloc()), there is no need to set them to zero again */ + if (_odict_resize(od) < 0) { + Py_DECREF(od); + return NULL; + } + + return (PyObject*)od; +} + +/* 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_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (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 */ + odict_members, /* tp_members */ + 0, /* 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 */ + (newfunc)odict_new, /* tp_new */ + 0, /* tp_free */ +}; + + +/* ---------------------------------------------- + * the public OrderedDict API + */ + +PyObject * +PyODict_New(void) { + return odict_new(&PyODict_Type, NULL, NULL); +}; + +int +PyODict_SetItem(PyObject *od, PyObject *key, PyObject *value) { + int res = PyDict_SetItem(od, key, value); + if (res == 0) { + res = _odict_add_new_node((PyODictObject *)od, key); + /* XXX Revert setting the value on the dict? */ + } + return res; +}; + +int +PyODict_DelItem(PyObject *od, PyObject *key) { + int res = _odict_clear_node((PyODictObject *)od, NULL, key); + if (res < 0) + return -1; + return PyDict_DelItem(od, key); +}; + + +/* ------------------------------------------- + * 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) { + /* 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 *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; + } + + /* Handle the items case. */ + if (di->kind & _odict_ITER_KEYS) { + PyObject *result = di->di_result; + + 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); + + if (result->ob_refcnt == 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 */ + } + 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; + } + /* Handle the values case. */ + else { + value = PyODict_GetItem((PyObject *)di->di_odict, key); + Py_DECREF(key); + if (value == NULL) { + if (!PyErr_Occurred()) + PyErr_SetObject(PyExc_KeyError, key); + goto done; + } + Py_INCREF(value); + return value; + } + +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 *list, *iter; + + list = PyList_New(0); + if (!list) + return NULL; + + /* iterate the temporary into a list */ + for(;;) { + PyObject *element = odictiter_iternext(di); + if (element) { + if (PyList_Append(list, element)) { + Py_DECREF(element); + Py_DECREF(list); + return NULL; + } + Py_DECREF(element); + } + else { + /* done iterating? */ + break; + } + } + if (PyErr_Occurred()) { + Py_DECREF(list); + return NULL; + } + iter = _PyObject_GetBuiltin("iter"); + if (iter == NULL) { + Py_DECREF(list); + return NULL; + } + return Py_BuildValue("N(N)", 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_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | 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) +{ + 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_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + 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) +{ + 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) +{ + 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_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + 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) +{ + 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) +{ + 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_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + 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) +{ + return _PyDictView_New(od, &PyODictValues_Type); +} + + +/* ---------------------------------------------- + MutableMappping 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) { + char *msg = "update() takes at most 1 positional argument (%d given)"; + PyErr_Format(PyExc_TypeError, msg, len); + return NULL; + } + + if (len) { + PyObject *other = PyTuple_GET_ITEM(args, 0); /* borrowed reference */ + assert(other != NULL); + Py_INCREF(other); + if (PyDict_CheckExact(other) || + _PyObject_HasAttrId(other, &PyId_items)) { /* never fails */ + PyObject *items; + if (PyDict_CheckExact(other)) + items = PyDict_Items(other); + else + items = _PyObject_CallMethodId(other, &PyId_items, NULL); + Py_DECREF(other); + if (items == NULL) + return NULL; + res = mutablemapping_add_pairs(self, items); + Py_DECREF(items); + if (res == -1) + return NULL; + } + else if (_PyObject_HasAttrId(other, &PyId_keys)) { /* never fails */ + PyObject *keys, *iterator, *key; + keys = _PyObject_CallMethodIdObjArgs(other, &PyId_keys, NULL); + 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; + } + else { + res = mutablemapping_add_pairs(self, other); + Py_DECREF(other); + if (res != 0) + return NULL; + } + } + + /* now handle kwargs */ + assert(kwargs == NULL || PyDict_Check(kwargs)); + len = (kwargs != NULL) ? PyDict_Size(kwargs) : 0; + if (len > 0) { + 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/Objects/rangeobject.c b/Objects/rangeobject.c index a4d9fb3244ea..da1d703b3a0d 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -139,7 +139,11 @@ PyDoc_STRVAR(range_doc, "range(stop) -> range object\n\ range(start, stop[, step]) -> range object\n\ \n\ -Return a virtual sequence of numbers from start to stop by step."); +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) @@ -190,8 +194,11 @@ compute_range_length(PyObject *start, PyObject *stop, PyObject *step) } /* if (lo >= hi), return length of 0. */ - if (PyObject_RichCompareBool(lo, hi, Py_GE) == 1) { + cmp_result = PyObject_RichCompareBool(lo, hi, Py_GE); + if (cmp_result != 0) { Py_XDECREF(step); + if (cmp_result < 0) + return NULL; return PyLong_FromLong(0); } @@ -807,10 +814,11 @@ rangeiter_setstate(rangeiterobject *r, PyObject *state) long index = PyLong_AsLong(state); if (index == -1 && PyErr_Occurred()) return NULL; - if (index < 0 || index >= r->len) { - PyErr_SetString(PyExc_ValueError, "index out of range"); - 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; } @@ -985,6 +993,28 @@ longrangeiter_reduce(longrangeiterobject *r) static PyObject * longrangeiter_setstate(longrangeiterobject *r, PyObject *state) { + int cmp; + + /* clip the value */ + PyObject *zero = PyLong_FromLong(0); + if (zero == NULL) + return NULL; + cmp = PyObject_RichCompareBool(state, zero, Py_LT); + if (cmp > 0) { + Py_CLEAR(r->index); + r->index = zero; + Py_RETURN_NONE; + } + Py_DECREF(zero); + if (cmp < 0) + return NULL; + + cmp = PyObject_RichCompareBool(r->len, state, Py_LT); + if (cmp < 0) + return NULL; + if (cmp > 0) + state = r->len; + Py_CLEAR(r->index); r->index = state; Py_INCREF(r->index); diff --git a/Objects/setobject.c b/Objects/setobject.c index adc99da62765..03bb230961cc 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -4,7 +4,7 @@ Written and maintained by Raymond D. Hettinger Derived from Lib/sets.py and Objects/dictobject.c. - Copyright (c) 2003-2013 Python Software Foundation. + Copyright (c) 2003-2015 Python Software Foundation. All rights reserved. The basic lookup function used by all operations. @@ -23,22 +23,18 @@ All arithmetic on hash should ignore overflow. - Unlike the dictionary implementation, the lookkey functions can return + Unlike the dictionary implementation, the lookkey function can return NULL if the rich comparison returns an error. */ #include "Python.h" #include "structmember.h" -#include "stringlib/eq.h" /* Object used as dummy key to fill deleted entries */ static PyObject _dummy_struct; #define dummy (&_dummy_struct) -/* Exported for the gdb plugin's benefit. */ -PyObject *_PySet_Dummy = dummy; - /* ======================================================================== */ /* ======= Begin logic for probing the hash table ========================= */ @@ -54,130 +50,204 @@ PyObject *_PySet_Dummy = dummy; static setentry * set_lookkey(PySetObject *so, PyObject *key, Py_hash_t hash) { - setentry *table = so->table; - setentry *freeslot = NULL; + setentry *table; setentry *entry; - size_t perturb = hash; + size_t perturb; size_t mask = so->mask; - size_t i = (size_t)hash; /* Unsigned for defined overflow behavior. */ + size_t i = (size_t)hash & mask; /* Unsigned for defined overflow behavior */ size_t j; int cmp; - entry = &table[i & mask]; + entry = &so->table[i]; if (entry->key == NULL) return entry; + perturb = hash; + while (1) { - if (entry->key == key) - return entry; - if (entry->hash == hash && entry->key != dummy) { + 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) + if (cmp < 0) /* unlikely */ return NULL; - if (table != so->table || entry->key != startkey) + if (table != so->table || entry->key != startkey) /* unlikely */ return set_lookkey(so, key, hash); - if (cmp > 0) + if (cmp > 0) /* likely */ return entry; + mask = so->mask; /* help avoid a register spill */ } - if (entry->key == dummy && freeslot == NULL) - freeslot = entry; - for (j = 1 ; j <= LINEAR_PROBES ; j++) { - entry = &table[(i + j) & mask]; - if (entry->key == NULL) - goto found_null; - if (entry->key == key) - return entry; - if (entry->hash == hash && entry->key != dummy) { - PyObject *startkey = entry->key; - 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) + 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; + } } - if (entry->key == dummy && freeslot == NULL) - freeslot = entry; } perturb >>= PERTURB_SHIFT; - i = i * 5 + 1 + perturb; + i = (i * 5 + 1 + perturb) & mask; - entry = &table[i & mask]; + entry = &so->table[i]; if (entry->key == NULL) - goto found_null; + return entry; } - found_null: - return freeslot == NULL ? entry : freeslot; } -/* - * Hacked up version of set_lookkey which can assume keys are always unicode; - * This means we can always use unicode_eq directly and not have to check to - * see if the comparison altered the table. - */ -static setentry * -set_lookkey_unicode(PySetObject *so, PyObject *key, Py_hash_t hash) +static int set_table_resize(PySetObject *, Py_ssize_t); + +static int +set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) { - setentry *table = so->table; - setentry *freeslot = NULL; + setentry *table; + setentry *freeslot; setentry *entry; - size_t perturb = hash; - size_t mask = so->mask; - size_t i = (size_t)hash; + size_t perturb; + size_t mask; + size_t i; /* Unsigned for defined overflow behavior */ size_t j; + int cmp; - /* Make sure this function doesn't have to handle non-unicode keys, - including subclasses of str; e.g., one reason to subclass - strings is to override __eq__, and for speed we don't cater to - that here. */ - if (!PyUnicode_CheckExact(key)) { - so->lookup = set_lookkey; - return set_lookkey(so, key, hash); - } + /* Pre-increment is necessary to prevent arbitrary code in the rich + comparison from deallocating the key just before the insertion. */ + Py_INCREF(key); - entry = &table[i & mask]; + restart: + + mask = so->mask; + i = (size_t)hash & mask; + + entry = &so->table[i]; if (entry->key == NULL) - return entry; + goto found_unused; + + freeslot = NULL; + perturb = hash; while (1) { - if (entry->key == key - || (entry->hash == hash - && entry->key != dummy - && unicode_eq(entry->key, key))) - return entry; - if (entry->key == dummy && freeslot == NULL) + 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 == NULL) freeslot = entry; - for (j = 1 ; j <= LINEAR_PROBES ; j++) { - entry = &table[(i + j) & mask]; - if (entry->key == NULL) - goto found_null; - if (entry->key == key - || (entry->hash == hash - && entry->key != dummy - && unicode_eq(entry->key, key))) - return entry; - if (entry->key == dummy && freeslot == NULL) - 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 == NULL) + freeslot = entry; + } } perturb >>= PERTURB_SHIFT; - i = i * 5 + 1 + perturb; + i = (i * 5 + 1 + perturb) & mask; - entry = &table[i & mask]; + entry = &so->table[i]; if (entry->key == NULL) - goto found_null; + goto found_unused_or_dummy; } - found_null: - return freeslot == NULL ? entry : freeslot; + + 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*3 < mask*2) + return 0; + return set_table_resize(so, so->used); + + found_active: + Py_DECREF(key); + return 0; + + comparison_error: + Py_DECREF(key); + return -1; } /* @@ -195,20 +265,22 @@ set_insert_clean(PySetObject *so, PyObject *key, Py_hash_t hash) setentry *entry; size_t perturb = hash; size_t mask = (size_t)so->mask; - size_t i = (size_t)hash; + size_t i = (size_t)hash & mask; size_t j; while (1) { - entry = &table[i & mask]; + entry = &table[i]; if (entry->key == NULL) goto found_null; - for (j = 1 ; j <= LINEAR_PROBES ; j++) { - entry = &table[(i + j) & mask]; - 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; + i = (i * 5 + 1 + perturb) & mask; } found_null: entry->key = key; @@ -220,39 +292,6 @@ set_insert_clean(PySetObject *so, PyObject *key, Py_hash_t hash) /* ======== End logic for probing the hash table ========================== */ /* ======================================================================== */ - -/* -Internal routine to insert a new key into the table. -Used by the public insert routine. -Eats a reference to key. -*/ -static int -set_insert_key(PySetObject *so, PyObject *key, Py_hash_t hash) -{ - setentry *entry; - - assert(so->lookup != NULL); - entry = so->lookup(so, key, hash); - if (entry == NULL) - return -1; - if (entry->key == NULL) { - /* UNUSED */ - so->fill++; - entry->key = key; - entry->hash = hash; - so->used++; - } else if (entry->key == dummy) { - /* DUMMY */ - entry->key = key; - entry->hash = hash; - so->used++; - } else { - /* ACTIVE */ - Py_DECREF(key); - } - return 0; -} - /* Restructure the table by allocating a new table and reinserting all keys again. When entries have been deleted, the new table may @@ -263,13 +302,16 @@ set_table_resize(PySetObject *so, Py_ssize_t minused) { Py_ssize_t newsize; setentry *oldtable, *newtable, *entry; - Py_ssize_t i; + Py_ssize_t oldfill = so->fill; + Py_ssize_t oldused = so->used; int is_oldtable_malloced; setentry small_copy[PySet_MINSIZE]; assert(minused >= 0); + minused = (minused > 50000) ? minused * 2 : minused * 4; /* Find the smallest table size > minused. */ + /* XXX speed-up with intrinsics */ for (newsize = PySet_MINSIZE; newsize <= minused && newsize > 0; newsize <<= 1) @@ -313,19 +355,27 @@ set_table_resize(PySetObject *so, Py_ssize_t minused) /* Make the set empty, using the new table. */ assert(newtable != oldtable); - so->table = newtable; - so->mask = newsize - 1; memset(newtable, 0, sizeof(setentry) * newsize); - i = so->used; - so->used = 0; so->fill = 0; + so->used = 0; + 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 */ - for (entry = oldtable; i > 0; entry++) { - if (entry->key != NULL && entry->key != dummy) { - --i; - set_insert_clean(so, entry->key, entry->hash); + if (oldfill == oldused) { + for (entry = oldtable; oldused > 0; entry++) { + if (entry->key != NULL) { + oldused--; + set_insert_clean(so, entry->key, entry->hash); + } + } + } else { + for (entry = oldtable; oldused > 0; entry++) { + if (entry->key != NULL && entry->key != dummy) { + oldused--; + set_insert_clean(so, entry->key, entry->hash); + } } } @@ -334,32 +384,43 @@ set_table_resize(PySetObject *so, Py_ssize_t minused) return 0; } -/* CAUTION: set_add_key/entry() must guarantee it won't resize the table */ +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_add_entry(PySetObject *so, setentry *entry) +set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash) { - Py_ssize_t n_used; - PyObject *key = entry->key; - Py_hash_t hash = entry->hash; + setentry *entry; + PyObject *old_key; - assert(so->fill <= so->mask); /* at least one empty slot */ - n_used = so->used; - Py_INCREF(key); - if (set_insert_key(so, key, hash) == -1) { - Py_DECREF(key); + entry = set_lookkey(so, key, hash); + if (entry == NULL) return -1; - } - if (!(so->used > n_used && so->fill*3 >= (so->mask+1)*2)) - return 0; - return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4); + 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; - Py_ssize_t n_used; if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *) key)->hash) == -1) { @@ -367,46 +428,27 @@ set_add_key(PySetObject *so, PyObject *key) if (hash == -1) return -1; } - assert(so->fill <= so->mask); /* at least one empty slot */ - n_used = so->used; - Py_INCREF(key); - if (set_insert_key(so, key, hash) == -1) { - Py_DECREF(key); - return -1; - } - if (!(so->used > n_used && so->fill*3 >= (so->mask+1)*2)) - return 0; - return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4); + return set_add_entry(so, key, hash); } -#define DISCARD_NOTFOUND 0 -#define DISCARD_FOUND 1 - static int -set_discard_entry(PySetObject *so, setentry *oldentry) -{ setentry *entry; - PyObject *old_key; +set_contains_key(PySetObject *so, PyObject *key) +{ + Py_hash_t hash; - entry = (so->lookup)(so, oldentry->key, oldentry->hash); - if (entry == NULL) - return -1; - if (entry->key == NULL || entry->key == dummy) - return DISCARD_NOTFOUND; - old_key = entry->key; - entry->key = dummy; - so->used--; - Py_DECREF(old_key); - return DISCARD_FOUND; + 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; - setentry *entry; - PyObject *old_key; - - assert (PyAnySet_Check(so)); if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *) key)->hash) == -1) { @@ -414,16 +456,7 @@ set_discard_key(PySetObject *so, PyObject *key) if (hash == -1) return -1; } - entry = (so->lookup)(so, key, hash); - if (entry == NULL) - return -1; - if (entry->key == NULL || entry->key == dummy) - return DISCARD_NOTFOUND; - old_key = entry->key; - entry->key = dummy; - so->used--; - Py_DECREF(old_key); - return DISCARD_FOUND; + return set_discard_entry(so, key, hash); } static void @@ -440,20 +473,15 @@ set_empty_to_minsize(PySetObject *so) static int set_clear_internal(PySetObject *so) { - setentry *entry, *table; - int table_is_malloced; - Py_ssize_t fill; + 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]; -#ifdef Py_DEBUG - Py_ssize_t i = 0; - Py_ssize_t n = so->mask + 1; -#endif - assert (PyAnySet_Check(so)); - table = so->table; assert(table != NULL); - table_is_malloced = table != so->smalltable; /* This is delicate. During the process of clearing the set, * decrefs can cause the set to mutate. To avoid fatal confusion @@ -461,7 +489,6 @@ set_clear_internal(PySetObject *so) * clearing the slots, and never refer to anything via so->ref while * clearing. */ - fill = so->fill; if (table_is_malloced) set_empty_to_minsize(so); @@ -480,20 +507,11 @@ set_clear_internal(PySetObject *so) * 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; fill > 0; ++entry) { -#ifdef Py_DEBUG - assert(i < n); - ++i; -#endif - if (entry->key) { - --fill; - if (entry->key != dummy) - Py_DECREF(entry->key); + for (entry = table; used > 0; entry++) { + if (entry->key && entry->key != dummy) { + used--; + Py_DECREF(entry->key); } -#ifdef Py_DEBUG - else - assert(entry->key == NULL); -#endif } if (table_is_malloced) @@ -519,20 +537,22 @@ set_next(PySetObject *so, Py_ssize_t *pos_ptr, setentry **entry_ptr) { Py_ssize_t i; Py_ssize_t mask; - setentry *table; + setentry *entry; assert (PyAnySet_Check(so)); i = *pos_ptr; assert(i >= 0); - table = so->table; mask = so->mask; - while (i <= mask && (table[i].key == NULL || table[i].key == dummy)) + 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(table[i].key != NULL); - *entry_ptr = &table[i]; + assert(entry != NULL); + *entry_ptr = entry; return 1; } @@ -540,16 +560,16 @@ static void set_dealloc(PySetObject *so) { setentry *entry; - Py_ssize_t fill = so->fill; + Py_ssize_t used = so->used; + PyObject_GC_UnTrack(so); Py_TRASHCAN_SAFE_BEGIN(so) if (so->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) so); - for (entry = so->table; fill > 0; entry++) { - if (entry->key) { - --fill; - if (entry->key != dummy) + for (entry = so->table; used > 0; entry++) { + if (entry->key && entry->key != dummy) { + used--; Py_DECREF(entry->key); } } @@ -615,77 +635,74 @@ set_merge(PySetObject *so, PyObject *otherset) { PySetObject *other; PyObject *key; - Py_hash_t hash; Py_ssize_t i; - setentry *entry; + 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({}); nothing to do */ + /* 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)*3 >= (so->mask+1)*2) { - if (set_table_resize(so, (so->used + other->used)*2) != 0) + if ((so->fill + other->used)*3 >= so->mask*2) { + if (set_table_resize(so, so->used + other->used) != 0) return -1; } - for (i = 0; i <= other->mask; i++) { - entry = &other->table[i]; - key = entry->key; - hash = entry->hash; - if (key != NULL && - key != dummy) { - Py_INCREF(key); - if (set_insert_key(so, key, hash) == -1) { - Py_DECREF(key); - return -1; + 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; } - return 0; -} - -static int -set_contains_key(PySetObject *so, PyObject *key) -{ - Py_hash_t hash; - setentry *entry; - if (!PyUnicode_CheckExact(key) || - (hash = ((PyASCIIObject *) key)->hash) == -1) { - hash = PyObject_Hash(key); - if (hash == -1) - return -1; + /* If our table is empty, we can use set_insert_clean() */ + if (so->fill == 0) { + for (i = 0; i <= other->mask; i++, other_entry++) { + key = other_entry->key; + if (key != NULL && key != dummy) { + Py_INCREF(key); + set_insert_clean(so, key, other_entry->hash); + } + } + return 0; } - entry = (so->lookup)(so, key, hash); - if (entry == NULL) - return -1; - key = entry->key; - return key != NULL && key != dummy; -} -static int -set_contains_entry(PySetObject *so, setentry *entry) -{ - PyObject *key; - setentry *lu_entry; - - lu_entry = (so->lookup)(so, entry->key, entry->hash); - if (lu_entry == NULL) - return -1; - key = lu_entry->key; - return key != NULL && key != dummy; + /* 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) { - Py_ssize_t i = 0; + /* Make sure the search finger is in bounds */ + Py_ssize_t i = so->finger & so->mask; setentry *entry; PyObject *key; @@ -695,32 +712,16 @@ set_pop(PySetObject *so) return NULL; } - /* Set entry to "the first" unused or dummy set entry. We abuse - * the hash field of slot 0 to hold a search finger: - * If slot 0 has a value, use slot 0. - * Else slot 0 is being used to hold a search finger, - * and we use its hash value as the first index to look. - */ - entry = &so->table[0]; - if (entry->key == NULL || entry->key == dummy) { - i = entry->hash; - /* The hash field may be a real hash value, or it may be a - * legit search finger, or it may be a once-legit search - * finger that's out of bounds now because it wrapped around - * or the table shrunk -- simply make sure it's in bounds now. - */ - if (i > so->mask || i < 1) - i = 1; /* skip slot 0 */ - while ((entry = &so->table[i])->key == NULL || entry->key==dummy) { - i++; - if (i > so->mask) - i = 1; - } + while ((entry = &so->table[i])->key == NULL || entry->key==dummy) { + i++; + if (i > so->mask) + i = 0; } key = entry->key; entry->key = dummy; + entry->hash = -1; so->used--; - so->table[0].hash = i + 1; /* next place to start */ + so->finger = i + 1; /* next place to start */ return key; } @@ -738,30 +739,64 @@ set_traverse(PySetObject *so, visitproc visit, void *arg) 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 h, hash = 1927868237UL; + Py_uhash_t hash = 0; setentry *entry; - Py_ssize_t pos = 0; if (so->hash != -1) return so->hash; - hash *= (Py_uhash_t)PySet_GET_SIZE(self) + 1; - while (set_next(so, &pos, &entry)) { - /* Work to increase the bit dispersion for closely spaced hash - values. The is important because some use cases have many - combinations of a small number of elements with nearby - hashes so that many distinct combinations collapse to only - a handful of distinct hash values. */ - h = entry->hash; - hash ^= (h ^ (h << 16) ^ 89869747UL) * 3644798167UL; - } + /* 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 * 69069U + 907133923UL; - if (hash == -1) + + /* -1 is reserved as an error code */ + if (hash == (Py_uhash_t)-1) hash = 590923713UL; + so->hash = hash; return hash; } @@ -908,7 +943,7 @@ PyTypeObject PySetIter_Type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ 0, /* tp_doc */ (traverseproc)setiter_traverse, /* tp_traverse */ 0, /* tp_clear */ @@ -953,18 +988,14 @@ set_update_internal(PySetObject *so, PyObject *other) * incrementally resizing as we insert new keys. Expect * that there will be no (or few) overlapping keys. */ - if (dictsize == -1) + if (dictsize < 0) return -1; - if ((so->fill + dictsize)*3 >= (so->mask+1)*2) { - if (set_table_resize(so, (so->used + dictsize)*2) != 0) + if ((so->fill + dictsize)*3 >= so->mask*2) { + if (set_table_resize(so, so->used + dictsize) != 0) return -1; } while (_PyDict_Next(other, &pos, &key, &value, &hash)) { - setentry an_entry; - - an_entry.hash = hash; - an_entry.key = key; - if (set_add_entry(so, &an_entry) == -1) + if (set_add_entry(so, key, hash)) return -1; } return 0; @@ -975,7 +1006,7 @@ set_update_internal(PySetObject *so, PyObject *other) return -1; while ((key = PyIter_Next(it)) != NULL) { - if (set_add_key(so, key) == -1) { + if (set_add_key(so, key)) { Py_DECREF(it); Py_DECREF(key); return -1; @@ -995,7 +1026,7 @@ set_update(PySetObject *so, PyObject *args) for (i=0 ; iused = 0; so->mask = PySet_MINSIZE - 1; so->table = so->smalltable; - so->lookup = set_lookkey_unicode; so->hash = -1; + so->finger = 0; so->weakreflist = NULL; if (iterable != NULL) { - if (set_update_internal(so, iterable) == -1) { + if (set_update_internal(so, iterable)) { Py_DECREF(so); return NULL; } @@ -1107,10 +1144,8 @@ set_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 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 creating temporary frozensets from sets for membership testing - in __contains__(), discard(), and remove(). Also useful for operations - that update in-place (by allowing an intermediate result to be swapped - into one of the original inputs). + Useful for operations that update in-place (by allowing an intermediate + result to be swapped into one of the original inputs). */ static void @@ -1118,7 +1153,6 @@ set_swap_bodies(PySetObject *a, PySetObject *b) { Py_ssize_t t; setentry *u; - setentry *(*f)(PySetObject *so, PyObject *key, Py_ssize_t hash); setentry tab[PySet_MINSIZE]; Py_hash_t h; @@ -1134,8 +1168,6 @@ set_swap_bodies(PySetObject *a, PySetObject *b) a->table = a->smalltable; b->table = u; - f = a->lookup; a->lookup = b->lookup; b->lookup = f; - if (a->table == a->smalltable || b->table == b->smalltable) { memcpy(tab, a->smalltable, sizeof(tab)); memcpy(a->smalltable, b->smalltable, sizeof(tab)); @@ -1193,7 +1225,7 @@ set_union(PySetObject *so, PyObject *args) other = PyTuple_GET_ITEM(args, i); if ((PyObject *)so == other) continue; - if (set_update_internal(result, other) == -1) { + if (set_update_internal(result, other)) { Py_DECREF(result); return NULL; } @@ -1219,7 +1251,7 @@ set_or(PySetObject *so, PyObject *other) return NULL; if ((PyObject *)so == other) return (PyObject *)result; - if (set_update_internal(result, other) == -1) { + if (set_update_internal(result, other)) { Py_DECREF(result); return NULL; } @@ -1232,7 +1264,7 @@ set_ior(PySetObject *so, PyObject *other) if (!PyAnySet_Check(other)) Py_RETURN_NOTIMPLEMENTED; - if (set_update_internal(so, other) == -1) + if (set_update_internal(so, other)) return NULL; Py_INCREF(so); return (PyObject *)so; @@ -1243,6 +1275,8 @@ set_intersection(PySetObject *so, PyObject *other) { PySetObject *result; PyObject *key, *it, *tmp; + Py_hash_t hash; + int rv; if ((PyObject *)so == other) return set_copy(so); @@ -1262,13 +1296,15 @@ set_intersection(PySetObject *so, PyObject *other) } while (set_next((PySetObject *)other, &pos, &entry)) { - int rv = set_contains_entry(so, entry); - if (rv == -1) { + 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, entry) == -1) { + if (set_add_entry(result, key, hash)) { Py_DECREF(result); return NULL; } @@ -1284,32 +1320,15 @@ set_intersection(PySetObject *so, PyObject *other) } while ((key = PyIter_Next(it)) != NULL) { - int rv; - setentry entry; - Py_hash_t hash = PyObject_Hash(key); - - if (hash == -1) { - Py_DECREF(it); - Py_DECREF(result); - Py_DECREF(key); - return NULL; - } - entry.hash = hash; - entry.key = key; - rv = set_contains_entry(so, &entry); - if (rv == -1) { - Py_DECREF(it); - Py_DECREF(result); - Py_DECREF(key); - return 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, &entry) == -1) { - Py_DECREF(it); - Py_DECREF(result); - Py_DECREF(key); - return NULL; - } + if (set_add_entry(result, key, hash)) + goto error; } Py_DECREF(key); } @@ -1319,6 +1338,11 @@ set_intersection(PySetObject *so, PyObject *other) return NULL; } return (PyObject *)result; + error: + Py_DECREF(it); + Py_DECREF(result); + Py_DECREF(key); + return NULL; } static PyObject * @@ -1405,6 +1429,7 @@ static PyObject * set_isdisjoint(PySetObject *so, PyObject *other) { PyObject *key, *it, *tmp; + int rv; if ((PyObject *)so == other) { if (PySet_GET_SIZE(so) == 0) @@ -1423,8 +1448,8 @@ set_isdisjoint(PySetObject *so, PyObject *other) other = tmp; } while (set_next((PySetObject *)other, &pos, &entry)) { - int rv = set_contains_entry(so, entry); - if (rv == -1) + rv = set_contains_entry(so, entry->key, entry->hash); + if (rv < 0) return NULL; if (rv) Py_RETURN_FALSE; @@ -1437,8 +1462,6 @@ set_isdisjoint(PySetObject *so, PyObject *other) return NULL; while ((key = PyIter_Next(it)) != NULL) { - int rv; - setentry entry; Py_hash_t hash = PyObject_Hash(key); if (hash == -1) { @@ -1446,11 +1469,9 @@ set_isdisjoint(PySetObject *so, PyObject *other) Py_DECREF(it); return NULL; } - entry.hash = hash; - entry.key = key; - rv = set_contains_entry(so, &entry); + rv = set_contains_entry(so, key, hash); Py_DECREF(key); - if (rv == -1) { + if (rv < 0) { Py_DECREF(it); return NULL; } @@ -1479,7 +1500,7 @@ set_difference_update_internal(PySetObject *so, PyObject *other) Py_ssize_t pos = 0; while (set_next((PySetObject *)other, &pos, &entry)) - if (set_discard_entry(so, entry) == -1) + if (set_discard_entry(so, entry->key, entry->hash) < 0) return -1; } else { PyObject *key, *it; @@ -1488,7 +1509,7 @@ set_difference_update_internal(PySetObject *so, PyObject *other) return -1; while ((key = PyIter_Next(it)) != NULL) { - if (set_discard_key(so, key) == -1) { + if (set_discard_key(so, key) < 0) { Py_DECREF(it); Py_DECREF(key); return -1; @@ -1499,10 +1520,10 @@ set_difference_update_internal(PySetObject *so, PyObject *other) if (PyErr_Occurred()) return -1; } - /* If more than 1/5 are dummies, then resize them away. */ - if ((so->fill - so->used) * 5 < so->mask) + /* 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); + return set_table_resize(so, so->used); } static PyObject * @@ -1512,7 +1533,7 @@ set_difference_update(PySetObject *so, PyObject *args) for (i=0 ; ihash; - entrycopy.key = entry->key; - if (!_PyDict_Contains(other, entry->key, entry->hash)) { - if (set_add_entry((PySetObject *)result, &entrycopy) == -1) { + 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; } @@ -1573,13 +1601,15 @@ set_difference(PySetObject *so, PyObject *other) /* Iterate over so, checking for common elements in other. */ while (set_next(so, &pos, &entry)) { - int rv = set_contains_entry((PySetObject *)other, entry); - if (rv == -1) { + 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, entry) == -1) { + if (set_add_entry((PySetObject *)result, key, hash)) { Py_DECREF(result); return NULL; } @@ -1604,7 +1634,7 @@ set_difference_multi(PySetObject *so, PyObject *args) 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, entry) == -1) { + if (set_add_entry(so, key, hash)) { Py_DECREF(otherset); return NULL; } @@ -1751,6 +1778,7 @@ set_issubset(PySetObject *so, PyObject *other) { setentry *entry; Py_ssize_t pos = 0; + int rv; if (!PyAnySet_Check(other)) { PyObject *tmp, *result; @@ -1765,8 +1793,8 @@ set_issubset(PySetObject *so, PyObject *other) Py_RETURN_FALSE; while (set_next(so, &pos, &entry)) { - int rv = set_contains_entry((PySetObject *)other, entry); - if (rv == -1) + rv = set_contains_entry((PySetObject *)other, entry->key, entry->hash); + if (rv < 0) return NULL; if (!rv) Py_RETURN_FALSE; @@ -1797,7 +1825,8 @@ PyDoc_STRVAR(issuperset_doc, "Report whether this set contains another set."); static PyObject * set_richcompare(PySetObject *v, PyObject *w, int op) { - PyObject *r1, *r2; + PyObject *r1; + int r2; if(!PyAnySet_Check(w)) Py_RETURN_NOTIMPLEMENTED; @@ -1815,9 +1844,11 @@ set_richcompare(PySetObject *v, PyObject *w, int op) r1 = set_richcompare(v, w, Py_EQ); if (r1 == NULL) return NULL; - r2 = PyBool_FromLong(PyObject_Not(r1)); + r2 = PyObject_IsTrue(r1); Py_DECREF(r1); - return r2; + if (r2 < 0) + return NULL; + return PyBool_FromLong(!r2); case Py_LE: return set_issubset(v, w); case Py_GE: @@ -1837,7 +1868,7 @@ set_richcompare(PySetObject *v, PyObject *w, int op) static PyObject * set_add(PySetObject *so, PyObject *key) { - if (set_add_key(so, key) == -1) + if (set_add_key(so, key)) return NULL; Py_RETURN_NONE; } @@ -1854,7 +1885,7 @@ set_contains(PySetObject *so, PyObject *key) int rv; rv = set_contains_key(so, key); - if (rv == -1) { + if (rv < 0) { if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError)) return -1; PyErr_Clear(); @@ -1873,7 +1904,7 @@ set_direct_contains(PySetObject *so, PyObject *key) long result; result = set_contains(so, key); - if (result == -1) + if (result < 0) return NULL; return PyBool_FromLong(result); } @@ -1887,7 +1918,7 @@ set_remove(PySetObject *so, PyObject *key) int rv; rv = set_discard_key(so, key); - if (rv == -1) { + if (rv < 0) { if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError)) return NULL; PyErr_Clear(); @@ -1896,7 +1927,7 @@ set_remove(PySetObject *so, PyObject *key) return NULL; rv = set_discard_key(so, tmpkey); Py_DECREF(tmpkey); - if (rv == -1) + if (rv < 0) return NULL; } @@ -1919,7 +1950,7 @@ set_discard(PySetObject *so, PyObject *key) int rv; rv = set_discard_key(so, key); - if (rv == -1) { + if (rv < 0) { if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError)) return NULL; PyErr_Clear(); @@ -1928,7 +1959,7 @@ set_discard(PySetObject *so, PyObject *key) return NULL; rv = set_discard_key(so, tmpkey); Py_DECREF(tmpkey); - if (rv == -1) + if (rv < 0) return NULL; } Py_RETURN_NONE; @@ -2155,7 +2186,7 @@ static PyMethodDef frozenset_methods[] = { copy_doc}, {"difference", (PyCFunction)set_difference_multi, METH_VARARGS, difference_doc}, - {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS, + {"intersection", (PyCFunction)set_intersection_multi, METH_VARARGS, intersection_doc}, {"isdisjoint", (PyCFunction)set_isdisjoint, METH_O, isdisjoint_doc}, @@ -2226,7 +2257,7 @@ PyTypeObject PyFrozenSet_Type = { (traverseproc)set_traverse, /* tp_traverse */ (inquiry)set_clear_internal, /* tp_clear */ (richcmpfunc)set_richcompare, /* tp_richcompare */ - offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */ + offsetof(PySetObject, weakreflist), /* tp_weaklistoffset */ (getiterfunc)set_iter, /* tp_iter */ 0, /* tp_iternext */ frozenset_methods, /* tp_methods */ @@ -2345,6 +2376,9 @@ _PySet_Update(PyObject *set, PyObject *iterable) 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. @@ -2378,7 +2412,7 @@ test_c_api(PySetObject *so) if (str == NULL) return NULL; set_clear_internal(so); - if (set_update_internal(so, str) == -1) { + if (set_update_internal(so, str)) { Py_DECREF(str); return NULL; } diff --git a/Objects/stringlib/README.txt b/Objects/stringlib/README.txt index ab506d60f94b..8ff6ad8c4fa0 100644 --- a/Objects/stringlib/README.txt +++ b/Objects/stringlib/README.txt @@ -1,4 +1,4 @@ -bits shared by the stringobject and unicodeobject implementations (and +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 diff --git a/Objects/stringlib/codecs.h b/Objects/stringlib/codecs.h index 2eb2d1412fff..2beb604f1168 100644 --- a/Objects/stringlib/codecs.h +++ b/Objects/stringlib/codecs.h @@ -263,50 +263,34 @@ STRINGLIB(utf8_encoder)(PyObject *unicode, #define MAX_SHORT_UNICHARS 300 /* largest size we'll do on the stack */ Py_ssize_t i; /* index into s of next input byte */ - PyObject *result; /* result string object */ char *p; /* next free byte in output buffer */ - Py_ssize_t nallocated; /* number of result bytes allocated */ - Py_ssize_t nneeded; /* number of result bytes needed */ #if STRINGLIB_SIZEOF_CHAR > 1 - PyObject *errorHandler = NULL; + PyObject *error_handler_obj = NULL; PyObject *exc = NULL; PyObject *rep = NULL; + _Py_error_handler error_handler = _Py_ERROR_UNKNOWN; #endif #if STRINGLIB_SIZEOF_CHAR == 1 const Py_ssize_t max_char_size = 2; - char stackbuf[MAX_SHORT_UNICHARS * 2]; #elif STRINGLIB_SIZEOF_CHAR == 2 const Py_ssize_t max_char_size = 3; - char stackbuf[MAX_SHORT_UNICHARS * 3]; #else /* STRINGLIB_SIZEOF_CHAR == 4 */ const Py_ssize_t max_char_size = 4; - char stackbuf[MAX_SHORT_UNICHARS * 4]; #endif + _PyBytesWriter writer; assert(size >= 0); + _PyBytesWriter_Init(&writer); - if (size <= MAX_SHORT_UNICHARS) { - /* Write into the stack buffer; nallocated can't overflow. - * At the end, we'll allocate exactly as much heap space as it - * turns out we need. - */ - nallocated = Py_SAFE_DOWNCAST(sizeof(stackbuf), size_t, int); - result = NULL; /* will allocate after we're done */ - p = stackbuf; - } - else { - if (size > PY_SSIZE_T_MAX / max_char_size) { - /* integer overflow */ - return PyErr_NoMemory(); - } - /* Overallocate on the heap, and give the excess back at the end. */ - nallocated = size * max_char_size; - result = PyBytes_FromStringAndSize(NULL, nallocated); - if (result == NULL) - return NULL; - p = PyBytes_AS_STRING(result); + 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++]; @@ -326,72 +310,118 @@ STRINGLIB(utf8_encoder)(PyObject *unicode, } #if STRINGLIB_SIZEOF_CHAR > 1 else if (Py_UNICODE_IS_SURROGATE(ch)) { - Py_ssize_t newpos; - Py_ssize_t repsize, k, startpos; + Py_ssize_t startpos, endpos, newpos; + Py_ssize_t k; + if (error_handler == _Py_ERROR_UNKNOWN) + error_handler = get_error_handler(errors); + startpos = i-1; - rep = unicode_encode_call_errorhandler( - errors, &errorHandler, "utf-8", "surrogates not allowed", - unicode, &exc, startpos, startpos+1, &newpos); - if (!rep) - goto error; - - if (PyBytes_Check(rep)) - repsize = PyBytes_GET_SIZE(rep); - else - repsize = PyUnicode_GET_LENGTH(rep); + 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 the ignore handler */ + case _Py_ERROR_IGNORE: + i += (endpos - startpos - 1); + break; - if (repsize > max_char_size) { - Py_ssize_t offset; + 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; - if (result == NULL) - offset = p - stackbuf; - else - offset = p - PyBytes_AS_STRING(result); + case _Py_ERROR_BACKSLASHREPLACE: + /* substract 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; - if (nallocated > PY_SSIZE_T_MAX - repsize + max_char_size) { - /* integer overflow */ - PyErr_NoMemory(); + case _Py_ERROR_XMLCHARREFREPLACE: + /* substract 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; } - p = PyBytes_AS_STRING(result) + offset; - } + startpos = k; + assert(startpos < endpos); + /* fall through the default handler */ + default: + rep = unicode_encode_call_errorhandler( + errors, &error_handler_obj, "utf-8", "surrogates not allowed", + unicode, &exc, startpos, endpos, &newpos); + if (!rep) + goto error; - if (PyBytes_Check(rep)) { - char *prep = PyBytes_AS_STRING(rep); - for(k = repsize; k > 0; k--) - *p++ = *prep++; - } else /* rep is unicode */ { - enum PyUnicode_Kind repkind; - void *repdata; + /* substract preallocated bytes */ + writer.min_size -= max_char_size; - if (PyUnicode_READY(rep) < 0) - goto error; - repkind = PyUnicode_KIND(rep); - repdata = PyUnicode_DATA(rep); + 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; - for(k=0; k 2 @@ -416,31 +446,18 @@ STRINGLIB(utf8_encoder)(PyObject *unicode, #endif /* STRINGLIB_SIZEOF_CHAR > 1 */ } - if (result == NULL) { - /* This was stack allocated. */ - nneeded = p - stackbuf; - assert(nneeded <= nallocated); - result = PyBytes_FromStringAndSize(stackbuf, nneeded); - } - else { - /* Cut back to size actually needed. */ - nneeded = p - PyBytes_AS_STRING(result); - assert(nneeded <= nallocated); - _PyBytes_Resize(&result, nneeded); - } - #if STRINGLIB_SIZEOF_CHAR > 1 - Py_XDECREF(errorHandler); + Py_XDECREF(error_handler_obj); Py_XDECREF(exc); #endif - return result; + return _PyBytesWriter_Finish(&writer, p); #if STRINGLIB_SIZEOF_CHAR > 1 error: Py_XDECREF(rep); - Py_XDECREF(errorHandler); + Py_XDECREF(error_handler_obj); Py_XDECREF(exc); - Py_XDECREF(result); + _PyBytesWriter_Dealloc(&writer); return NULL; #endif @@ -660,7 +677,7 @@ STRINGLIB(utf16_encode)(const STRINGLIB_CHAR *in, if (ch < 0xd800) *out++ = ch; else if (ch < 0xe000) - /* reject surrogate characters (U+DC800-U+DFFF) */ + /* reject surrogate characters (U+D800-U+DFFF) */ goto fail; #if STRINGLIB_MAX_CHAR >= 0x10000 else if (ch >= 0x10000) { @@ -695,7 +712,7 @@ STRINGLIB(utf16_encode)(const STRINGLIB_CHAR *in, if (ch < 0xd800) *out++ = SWAB2((Py_UCS2)ch); else if (ch < 0xe000) - /* reject surrogate characters (U+DC800-U+DFFF) */ + /* reject surrogate characters (U+D800-U+DFFF) */ goto fail; #if STRINGLIB_MAX_CHAR >= 0x10000 else if (ch >= 0x10000) { @@ -718,6 +735,93 @@ STRINGLIB(utf16_encode)(const STRINGLIB_CHAR *in, 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 #endif /* STRINGLIB_IS_UNICODE */ diff --git a/Objects/stringlib/fastsearch.h b/Objects/stringlib/fastsearch.h index cd7cac40fa4a..cda68e77c8dc 100644 --- a/Objects/stringlib/fastsearch.h +++ b/Objects/stringlib/fastsearch.h @@ -36,7 +36,7 @@ Py_LOCAL_INLINE(Py_ssize_t) STRINGLIB(fastsearch_memchr_1char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch, unsigned char needle, - Py_ssize_t maxcount, int mode) + int mode) { if (mode == FAST_SEARCH) { const STRINGLIB_CHAR *ptr = s; @@ -115,7 +115,7 @@ FASTSEARCH(const STRINGLIB_CHAR* s, Py_ssize_t n, if (needle != 0) #endif return STRINGLIB(fastsearch_memchr_1char) - (s, n, p[0], needle, maxcount, mode); + (s, n, p[0], needle, mode); } if (mode == FAST_COUNT) { for (i = 0; i < n; i++) diff --git a/Objects/stringlib/find.h b/Objects/stringlib/find.h index 518e012b759f..14815f6e62bd 100644 --- a/Objects/stringlib/find.h +++ b/Objects/stringlib/find.h @@ -11,8 +11,7 @@ STRINGLIB(find)(const STRINGLIB_CHAR* str, Py_ssize_t str_len, { Py_ssize_t pos; - if (str_len < 0) - return -1; + assert(str_len >= 0); if (sub_len == 0) return offset; @@ -31,8 +30,7 @@ STRINGLIB(rfind)(const STRINGLIB_CHAR* str, Py_ssize_t str_len, { Py_ssize_t pos; - if (str_len < 0) - return -1; + assert(str_len >= 0); if (sub_len == 0) return str_len + offset; @@ -44,27 +42,11 @@ STRINGLIB(rfind)(const STRINGLIB_CHAR* str, Py_ssize_t str_len, return pos; } -/* helper macro to fixup start/end slice values */ -#define ADJUST_INDICES(start, end, len) \ - if (end > len) \ - end = len; \ - else if (end < 0) { \ - end += len; \ - if (end < 0) \ - end = 0; \ - } \ - if (start < 0) { \ - start += len; \ - if (start < 0) \ - start = 0; \ - } - Py_LOCAL_INLINE(Py_ssize_t) STRINGLIB(find_slice)(const STRINGLIB_CHAR* str, Py_ssize_t str_len, const STRINGLIB_CHAR* sub, Py_ssize_t sub_len, Py_ssize_t start, Py_ssize_t end) { - ADJUST_INDICES(start, end, str_len); return STRINGLIB(find)(str + start, end - start, sub, sub_len, start); } @@ -73,7 +55,6 @@ 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) { - ADJUST_INDICES(start, end, str_len); return STRINGLIB(rfind)(str + start, end - start, sub, sub_len, start); } diff --git a/Objects/stringlib/join.h b/Objects/stringlib/join.h index 5568b31dab86..cbf81be17068 100644 --- a/Objects/stringlib/join.h +++ b/Objects/stringlib/join.h @@ -53,15 +53,22 @@ STRINGLIB(bytes_join)(PyObject *sep, PyObject *iterable) /* 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 - * buffer-compatible. + * bytes-like. */ for (i = 0, nbufs = 0; i < seqlen; i++) { Py_ssize_t itemlen; item = PySequence_Fast_GET_ITEM(seq, i); - if (_getbuffer(item, &buffers[i]) < 0) { + 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 bytes, bytearray, " - "or an object with the buffer interface, %.80s found", + "sequence item %zd: expected a bytes-like object, " + "%.80s found", i, Py_TYPE(item)->tp_name); goto error; } diff --git a/Objects/stringlib/transmogrify.h b/Objects/stringlib/transmogrify.h index dd00976eacaa..b559b5356b8d 100644 --- a/Objects/stringlib/transmogrify.h +++ b/Objects/stringlib/transmogrify.h @@ -15,7 +15,7 @@ stringlib_expandtabs(PyObject *self, PyObject *args, PyObject *kwds) { const char *e, *p; char *q; - size_t i, j; + Py_ssize_t i, j; PyObject *u; static char *kwlist[] = {"tabsize", 0}; int tabsize = 8; @@ -27,35 +27,31 @@ stringlib_expandtabs(PyObject *self, PyObject *args, PyObject *kwds) /* 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++) + for (p = STRINGLIB_STR(self); p < e; p++) { if (*p == '\t') { if (tabsize > 0) { - j += tabsize - (j % tabsize); - if (j > PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, - "result is too long"); - return NULL; - } + 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) { - PyErr_SetString(PyExc_OverflowError, - "result is too long"); - return NULL; - } } } - - if ((i + j) > PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, "result is too long"); - return NULL; } + 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) @@ -64,7 +60,7 @@ stringlib_expandtabs(PyObject *self, PyObject *args, PyObject *kwds) j = 0; q = STRINGLIB_STR(u); - for (p = STRINGLIB_STR(self); p < e; p++) + for (p = STRINGLIB_STR(self); p < e; p++) { if (*p == '\t') { if (tabsize > 0) { i = tabsize - (j % tabsize); @@ -79,8 +75,12 @@ stringlib_expandtabs(PyObject *self, PyObject *args, PyObject *kwds) if (*p == '\n' || *p == '\r') j = 0; } + } return u; + overflow: + PyErr_SetString(PyExc_OverflowError, "result too long"); + return NULL; } Py_LOCAL_INLINE(PyObject *) diff --git a/Objects/stringlib/unicode_format.h b/Objects/stringlib/unicode_format.h index aec221acff9d..d72e47d348aa 100644 --- a/Objects/stringlib/unicode_format.h +++ b/Objects/stringlib/unicode_format.h @@ -67,7 +67,7 @@ SubString_new_object(SubString *str) return PyUnicode_Substring(str->str, str->start, str->end); } -/* return a new string. if str->str is NULL, return None */ +/* 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) { diff --git a/Objects/structseq.c b/Objects/structseq.c index 664344be6c07..720973816ecb 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -16,14 +16,14 @@ _Py_IDENTIFIER(n_fields); _Py_IDENTIFIER(n_unnamed_fields); #define VISIBLE_SIZE(op) Py_SIZE(op) -#define VISIBLE_SIZE_TP(tp) PyLong_AsLong( \ +#define VISIBLE_SIZE_TP(tp) PyLong_AsSsize_t( \ _PyDict_GetItemId((tp)->tp_dict, &PyId_n_sequence_fields)) -#define REAL_SIZE_TP(tp) PyLong_AsLong( \ +#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_AsLong( \ +#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)) @@ -164,7 +164,8 @@ structseq_repr(PyStructSequence *obj) #define TYPE_MAXSIZE 100 PyTypeObject *typ = Py_TYPE(obj); - int i, removelast = 0; + Py_ssize_t i; + int removelast = 0; Py_ssize_t len; char buf[REPR_BUFFER_SIZE]; char *endofbuf, *pbuf = buf; @@ -236,8 +237,7 @@ structseq_reduce(PyStructSequence* self) PyObject* tup = NULL; PyObject* dict = NULL; PyObject* result; - Py_ssize_t n_fields, n_visible_fields, n_unnamed_fields; - int i; + Py_ssize_t n_fields, n_visible_fields, n_unnamed_fields, i; n_fields = REAL_SIZE(self); n_visible_fields = VISIBLE_SIZE(self); @@ -325,7 +325,7 @@ PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc) { PyObject *dict; PyMemberDef* members; - int n_members, n_unnamed_members, i, k; + Py_ssize_t n_members, n_unnamed_members, i, k; PyObject *v; #ifdef Py_TRACE_REFS @@ -373,9 +373,9 @@ PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc) Py_INCREF(type); dict = type->tp_dict; -#define SET_DICT_FROM_INT(key, value) \ +#define SET_DICT_FROM_SIZE(key, value) \ do { \ - v = PyLong_FromLong((long) value); \ + v = PyLong_FromSsize_t(value); \ if (v == NULL) \ return -1; \ if (PyDict_SetItemString(dict, key, v) < 0) { \ @@ -385,9 +385,9 @@ PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc) Py_DECREF(v); \ } while (0) - SET_DICT_FROM_INT(visible_length_key, desc->n_in_sequence); - SET_DICT_FROM_INT(real_length_key, n_members); - SET_DICT_FROM_INT(unnamed_fields_key, n_unnamed_members); + 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; } diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 5625a6547c56..7efa1a6776a0 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -97,7 +97,7 @@ PyTuple_New(Py_ssize_t size) #endif { /* Check for overflow */ - if (size > (PY_SSIZE_T_MAX - sizeof(PyTupleObject) - + if ((size_t)size > ((size_t)PY_SSIZE_T_MAX - sizeof(PyTupleObject) - sizeof(PyObject *)) / sizeof(PyObject *)) { return PyErr_NoMemory(); } @@ -746,7 +746,7 @@ tuplesubscript(PyTupleObject* self, PyObject* item) } else { PyErr_Format(PyExc_TypeError, - "tuple indices must be integers, not %.200s", + "tuple indices must be integers or slices, not %.200s", Py_TYPE(item)->tp_name); return NULL; } @@ -759,27 +759,15 @@ tuple_getnewargs(PyTupleObject *v) } -static PyObject * -tuple_sizeof(PyTupleObject *self) -{ - Py_ssize_t res; - - res = PyTuple_Type.tp_basicsize + Py_SIZE(self) * sizeof(PyObject *); - return PyLong_FromSsize_t(res); -} - PyDoc_STRVAR(index_doc, "T.index(value, [start, [stop]]) -> integer -- return first index of value.\n" "Raises ValueError if the value is not present." ); PyDoc_STRVAR(count_doc, "T.count(value) -> integer -- return number of occurrences of value"); -PyDoc_STRVAR(sizeof_doc, -"T.__sizeof__() -- size of T in memory, in bytes"); static PyMethodDef tuple_methods[] = { {"__getnewargs__", (PyCFunction)tuple_getnewargs, METH_NOARGS}, - {"__sizeof__", (PyCFunction)tuple_sizeof, METH_NOARGS, sizeof_doc}, {"index", (PyCFunction)tupleindex, METH_VARARGS, index_doc}, {"count", (PyCFunction)tuplecount, METH_O, count_doc}, {NULL, NULL} /* sentinel */ @@ -879,8 +867,7 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) _Py_ForgetReference((PyObject *) v); /* DECREF items deleted by shrinkage */ for (i = newsize; i < oldsize; i++) { - Py_XDECREF(v->ob_item[i]); - v->ob_item[i] = NULL; + Py_CLEAR(v->ob_item[i]); } sv = PyObject_GC_Resize(PyTupleObject, v, newsize); if (sv == NULL) { @@ -926,8 +913,7 @@ 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_XDECREF(free_list[0]); - free_list[0] = NULL; + Py_CLEAR(free_list[0]); (void)PyTuple_ClearFreeList(); #endif @@ -1013,8 +999,8 @@ tupleiter_setstate(tupleiterobject *it, PyObject *state) if (it->it_seq != NULL) { if (index < 0) index = 0; - else if (it->it_seq != NULL && index > PyTuple_GET_SIZE(it->it_seq)) - index = PyTuple_GET_SIZE(it->it_seq); + 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; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 8b2ea1c1a667..bf0d30cac305 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -14,10 +14,11 @@ 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 9 +#define MCACHE_SIZE_EXP 12 #define MCACHE_HASH(version, name_hash) \ - (((unsigned int)(version) * (unsigned int)(name_hash)) \ - >> (8*sizeof(unsigned int) - MCACHE_SIZE_EXP)) + (((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) @@ -35,6 +36,14 @@ struct method_cache_entry { 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__); @@ -54,12 +63,129 @@ _Py_IDENTIFIER(builtins); static PyObject * slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds); +static void +clear_slotdefs(void); + +/* + * 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 instrospection 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; +} + +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_INCREF(Py_None); + return Py_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_INCREF(Py_None); + return Py_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 KB\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); @@ -75,6 +201,7 @@ void _PyType_Fini(void) { PyType_ClearCache(); + clear_slotdefs(); } void @@ -437,9 +564,11 @@ type_get_bases(PyTypeObject *type, void *context) } static PyTypeObject *best_base(PyObject *); -static int mro_internal(PyTypeObject *); +static int mro_internal(PyTypeObject *, PyObject **); +Py_LOCAL_INLINE(int) type_is_subtype_base_chain(PyTypeObject *, PyTypeObject *); static int compatible_for_assignment(PyTypeObject *, PyTypeObject *, 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 *); @@ -449,167 +578,194 @@ 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 PyObject *type_subclasses(PyTypeObject *type, PyObject *ignored); static int -mro_subclasses(PyTypeObject *type, PyObject* temp) +mro_hierarchy(PyTypeObject *type, PyObject *temp) { - PyTypeObject *subclass; - PyObject *ref, *subclasses, *old_mro; - Py_ssize_t i; + int res; + PyObject *new_mro, *old_mro; + PyObject *tuple; + PyObject *subclasses; + Py_ssize_t i, n; - subclasses = type->tp_subclasses; - if (subclasses == NULL) - return 0; - assert(PyDict_CheckExact(subclasses)); - i = 0; + res = mro_internal(type, &old_mro); + if (res <= 0) + /* error / reentrance */ + return res; + new_mro = type->tp_mro; - 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)); - old_mro = subclass->tp_mro; - if (mro_internal(subclass) < 0) { - subclass->tp_mro = old_mro; - return -1; - } - else { - PyObject* tuple; - tuple = PyTuple_Pack(2, subclass, old_mro); - Py_DECREF(old_mro); - if (!tuple) - return -1; - if (PyList_Append(temp, tuple) < 0) - return -1; - Py_DECREF(tuple); - } - if (mro_subclasses(subclass, temp) < 0) - return -1; + 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; } - return 0; + 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(type, NULL); + 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 *value, void *context) +type_set_bases(PyTypeObject *type, PyObject *new_bases, void *context) { - Py_ssize_t i; - int r = 0; - PyObject *ob, *temp; + int res = 0; + PyObject *temp; + PyObject *old_bases; PyTypeObject *new_base, *old_base; - PyObject *old_bases, *old_mro; + Py_ssize_t i; - if (!check_set_special_type_attr(type, value, "__bases__")) + if (!check_set_special_type_attr(type, new_bases, "__bases__")) return -1; - if (!PyTuple_Check(value)) { + if (!PyTuple_Check(new_bases)) { PyErr_Format(PyExc_TypeError, "can only assign tuple to %s.__bases__, not %s", - type->tp_name, Py_TYPE(value)->tp_name); + type->tp_name, Py_TYPE(new_bases)->tp_name); return -1; } - if (PyTuple_GET_SIZE(value) == 0) { + 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(value); i++) { - ob = PyTuple_GET_ITEM(value, i); + 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; } - if (PyType_IsSubtype((PyTypeObject*)ob, type)) { + + 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(value); - - if (!new_base) + 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); - Py_INCREF(value); old_bases = type->tp_bases; old_base = type->tp_base; - old_mro = type->tp_mro; - type->tp_bases = value; + type->tp_bases = new_bases; type->tp_base = new_base; - if (mro_internal(type) < 0) { - goto bail; - } - temp = PyList_New(0); - if (!temp) + if (temp == NULL) goto bail; + if (mro_hierarchy(type, temp) < 0) + goto undo; + Py_DECREF(temp); - r = mro_subclasses(type, 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. */ - if (r < 0) { - for (i = 0; i < PyList_Size(temp); i++) { - PyTypeObject* cls; - PyObject* mro; - PyArg_UnpackTuple(PyList_GET_ITEM(temp, i), - "", 2, 2, &cls, &mro); - Py_INCREF(mro); - ob = cls->tp_mro; - cls->tp_mro = mro; - Py_DECREF(ob); - } - Py_DECREF(temp); - goto bail; + /* 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(temp); - - /* 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 */ + Py_DECREF(old_bases); + Py_DECREF(old_base); - remove_all_subclasses(type, old_bases); + return res; - for (i = PyTuple_GET_SIZE(value) - 1; i >= 0; i--) { - ob = PyTuple_GET_ITEM(value, i); - if (PyType_Check(ob)) { - if (add_subclass((PyTypeObject*)ob, type) < 0) - r = -1; + 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); - update_all_slots(type); - - Py_DECREF(old_bases); - Py_DECREF(old_base); - Py_DECREF(old_mro); + bail: + if (type->tp_bases == new_bases) { + assert(type->tp_base == new_base); - return r; + type->tp_bases = old_bases; + type->tp_base = old_base; - bail: - Py_DECREF(type->tp_bases); - Py_DECREF(type->tp_base); - if (type->tp_mro != old_mro) { - Py_DECREF(type->tp_mro); + Py_DECREF(new_bases); + Py_DECREF(new_base); + } + else { + Py_DECREF(old_bases); + Py_DECREF(old_base); } - - type->tp_bases = old_bases; - type->tp_base = old_base; - type->tp_mro = old_mro; return -1; } @@ -628,8 +784,9 @@ static PyObject * type_get_doc(PyTypeObject *type, void *context) { PyObject *result; - if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL) - return PyUnicode_FromString(type->tp_doc); + if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL) { + return _PyType_GetDocFromInternalDoc(type->tp_name, type->tp_doc); + } result = _PyDict_GetItemId(type->tp_dict, &PyId___doc__); if (result == NULL) { result = Py_None; @@ -645,6 +802,12 @@ type_get_doc(PyTypeObject *type, void *context) 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) { @@ -691,6 +854,7 @@ static PyGetSetDef type_getsets[] = { (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} }; @@ -737,30 +901,38 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds) #ifdef Py_DEBUG /* type_call() must not be called with an exception set, because it may clear it (directly or indirectly) and so the - caller looses its exception */ + caller loses its exception */ assert(!PyErr_Occurred()); #endif obj = type->tp_new(type, args, kwds); - if (obj != 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_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) { - Py_DECREF(obj); - obj = NULL; - } + 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_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; @@ -787,7 +959,7 @@ PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems) Py_INCREF(type); if (type->tp_itemsize == 0) - PyObject_INIT(obj, type); + (void)PyObject_INIT(obj, type); else (void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems); @@ -1061,8 +1233,11 @@ subtype_dealloc(PyObject *self) assert(basedealloc); basedealloc(self); - /* Can't reference self beyond this point */ - Py_DECREF(type); + /* 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. */ + if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) + Py_DECREF(type); endlabel: ++_PyTrash_delete_nesting; @@ -1174,6 +1349,18 @@ static PyTypeObject *solid_base(PyTypeObject *type); /* type test with subclassing support */ +Py_LOCAL_INLINE(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) { @@ -1192,15 +1379,9 @@ PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b) } return 0; } - else { + else /* a is not completely initilized yet; follow tp_base */ - do { - if (a == b) - return 1; - a = a->tp_base; - } while (a != NULL); - return b == &PyBaseObject_Type; - } + return type_is_subtype_base_chain(a, b); } /* Internal routines to do a method lookup in the type @@ -1467,10 +1648,11 @@ consistent method resolution\norder (MRO) for bases"); } static int -pmerge(PyObject *acc, PyObject* to_merge) { +pmerge(PyObject *acc, PyObject* to_merge) +{ + int res = 0; Py_ssize_t i, j, to_merge_size, empty_cnt; int *remain; - int ok; to_merge_size = PyList_GET_SIZE(to_merge); @@ -1508,15 +1690,13 @@ pmerge(PyObject *acc, PyObject* to_merge) { candidate = PyList_GET_ITEM(cur_list, remain[i]); for (j = 0; j < to_merge_size; j++) { PyObject *j_lst = PyList_GET_ITEM(to_merge, j); - if (tail_contains(j_lst, remain[j], candidate)) { + if (tail_contains(j_lst, remain[j], candidate)) goto skip; /* continue outer loop */ - } - } - ok = PyList_Append(acc, candidate); - if (ok < 0) { - PyMem_FREE(remain); - return -1; } + res = PyList_Append(acc, candidate); + if (res < 0) + goto out; + for (j = 0; j < to_merge_size; j++) { PyObject *j_lst = PyList_GET_ITEM(to_merge, j); if (remain[j] < PyList_GET_SIZE(j_lst) && @@ -1528,22 +1708,25 @@ pmerge(PyObject *acc, PyObject* to_merge) { skip: ; } - if (empty_cnt == to_merge_size) { - PyMem_FREE(remain); - return 0; + if (empty_cnt != to_merge_size) { + set_mro_error(to_merge, remain); + res = -1; } - set_mro_error(to_merge, remain); + + out: PyMem_FREE(remain); - return -1; + + return res; } static PyObject * mro_implementation(PyTypeObject *type) { - Py_ssize_t i, n; - int ok; - PyObject *bases, *result; + PyObject *result = NULL; + PyObject *bases; PyObject *to_merge, *bases_aslist; + int res; + Py_ssize_t i, n; if (type->tp_dict == NULL) { if (PyType_Ready(type) < 0) @@ -1567,42 +1750,44 @@ mro_implementation(PyTypeObject *type) return NULL; for (i = 0; i < n; i++) { - PyObject *base = PyTuple_GET_ITEM(bases, i); - PyObject *parentMRO; - parentMRO = PySequence_List(((PyTypeObject*)base)->tp_mro); - if (parentMRO == NULL) { - Py_DECREF(to_merge); - return NULL; + PyTypeObject *base; + PyObject *base_mro_aslist; + + 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); + goto out; } - PyList_SET_ITEM(to_merge, i, parentMRO); + base_mro_aslist = PySequence_List(base->tp_mro); + if (base_mro_aslist == NULL) + goto out; + + PyList_SET_ITEM(to_merge, i, base_mro_aslist); } bases_aslist = PySequence_List(bases); - if (bases_aslist == NULL) { - Py_DECREF(to_merge); - return NULL; - } + if (bases_aslist == NULL) + goto out; /* This is just a basic sanity check. */ if (check_duplicates(bases_aslist) < 0) { - Py_DECREF(to_merge); Py_DECREF(bases_aslist); - return NULL; + goto out; } PyList_SET_ITEM(to_merge, n, bases_aslist); result = Py_BuildValue("[O]", (PyObject *)type); - if (result == NULL) { - Py_DECREF(to_merge); - return NULL; - } + if (result == NULL) + goto out; + + res = pmerge(result, to_merge); + if (res < 0) + Py_CLEAR(result); - ok = pmerge(result, to_merge); + out: Py_DECREF(to_merge); - if (ok < 0) { - Py_DECREF(result); - return NULL; - } return result; } @@ -1616,59 +1801,133 @@ mro_external(PyObject *self) } static int -mro_internal(PyTypeObject *type) +mro_check(PyTypeObject *type, PyObject *mro) { - PyObject *mro, *result, *tuple; - int checkit = 0; + 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; - if (Py_TYPE(type) == &PyType_Type) { - result = mro_implementation(type); + 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; + } } - else { + + 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); - checkit = 1; - mro = lookup_method((PyObject *)type, &PyId_mro); - if (mro == NULL) - return -1; - result = PyObject_CallObject(mro, NULL); - Py_DECREF(mro); + PyObject *mro_meth = lookup_method((PyObject *)type, &PyId_mro); + if (mro_meth == NULL) + return NULL; + mro_result = PyObject_CallObject(mro_meth, NULL); + Py_DECREF(mro_meth); } - if (result == NULL) - return -1; - tuple = PySequence_Tuple(result); - Py_DECREF(result); - if (tuple == NULL) - return -1; - if (checkit) { - Py_ssize_t i, len; - PyObject *cls; - PyTypeObject *solid; + 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; - solid = solid_base(type); + if (custom && mro_check(type, new_mro) < 0) { + Py_DECREF(new_mro); + return NULL; + } - len = PyTuple_GET_SIZE(tuple); + return new_mro; +} - for (i = 0; i < len; i++) { - PyTypeObject *t; - cls = PyTuple_GET_ITEM(tuple, i); - if (!PyType_Check(cls)) { - PyErr_Format(PyExc_TypeError, - "mro() returned a non-class ('%.500s')", - Py_TYPE(cls)->tp_name); - Py_DECREF(tuple); - return -1; - } - t = (PyTypeObject*)cls; - if (!PyType_IsSubtype(solid, solid_base(t))) { - PyErr_Format(PyExc_TypeError, - "mro() returned base with unsuitable layout ('%.500s')", - t->tp_name); - Py_DECREF(tuple); - return -1; - } - } +/* 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 = tuple; + + type->tp_mro = new_mro; type_mro_modified(type, type->tp_mro); /* corner case: the super class might have been hidden @@ -1677,7 +1936,12 @@ mro_internal(PyTypeObject *type) PyType_Modified(type); - return 0; + if (p_old_mro != NULL) + *p_old_mro = old_mro; /* transfer the ownership */ + else + Py_XDECREF(old_mro); + + return 1; } @@ -1709,6 +1973,12 @@ best_base(PyObject *bases) 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; @@ -2089,12 +2359,6 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) if (base == NULL) { goto error; } - if (!PyType_HasFeature(base, Py_TPFLAGS_BASETYPE)) { - PyErr_Format(PyExc_TypeError, - "type '%.100s' is not an acceptable base type", - base->tp_name); - goto error; - } dict = PyDict_Copy(orig_dict); if (dict == NULL) @@ -2250,6 +2514,7 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) type->tp_flags |= 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; @@ -2362,9 +2627,6 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) type->tp_dictoffset = slotoffset; slotoffset += sizeof(PyObject *); } - if (type->tp_dictoffset) { - et->ht_cached_keys = _PyDict_NewKeysForClass(); - } if (add_weak) { assert(!base->tp_itemsize); type->tp_weaklistoffset = slotoffset; @@ -2392,9 +2654,10 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) } type->tp_dealloc = subtype_dealloc; - /* Enable GC unless there are really no instance variables possible */ - if (!(type->tp_basicsize == sizeof(PyObject) && - type->tp_itemsize == 0)) + /* Enable GC unless this class is not adding new instance variables and + the base class did not use GC. */ + if ((base->tp_flags & Py_TPFLAGS_HAVE_GC) || + type->tp_basicsize > base->tp_basicsize) type->tp_flags |= Py_TPFLAGS_HAVE_GC; /* Always override allocation strategy to use regular heap */ @@ -2414,6 +2677,10 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) /* Put the proper slots in place */ fixup_slot_dispatchers(type); + if (type->tp_dictoffset) { + et->ht_cached_keys = _PyDict_NewKeysForClass(); + } + Py_DECREF(dict); return (PyObject *)type; @@ -2435,6 +2702,7 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) { PyHeapTypeObject *res = (PyHeapTypeObject*)PyType_GenericAlloc(&PyType_Type, 0); PyTypeObject *type, *base; + PyObject *modname; char *s; char *res_start = (char*)res; PyType_Slot *slot; @@ -2493,6 +2761,7 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) } /* 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; @@ -2507,7 +2776,8 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) type->tp_itemsize = spec->itemsize; for (slot = spec->slots; slot->slot; slot++) { - if (slot->slot >= Py_ARRAY_LENGTH(slotoffsets)) { + if (slot->slot < 0 + || (size_t)slot->slot >= Py_ARRAY_LENGTH(slotoffsets)) { PyErr_SetString(PyExc_RuntimeError, "invalid slot offset"); goto fail; } @@ -2519,19 +2789,17 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) /* need to make a copy of the docstring slot, which usually points to a static string literal */ if (slot->slot == Py_tp_doc) { - size_t len = strlen(slot->pfunc)+1; + 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) { PyErr_NoMemory(); goto fail; } - memcpy(tp_doc, slot->pfunc, len); + memcpy(tp_doc, old_doc, len); type->tp_doc = tp_doc; } } - if (type->tp_dictoffset) { - res->ht_cached_keys = _PyDict_NewKeysForClass(); - } 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 @@ -2542,12 +2810,26 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) 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) - _PyDict_SetItemId(type->tp_dict, &PyId___module__, - PyUnicode_FromStringAndSize( - spec->name, (Py_ssize_t)(s - spec->name))); + if (s != NULL) { + modname = PyUnicode_FromStringAndSize( + spec->name, (Py_ssize_t)(s - spec->name)); + if (modname == NULL) { + goto fail; + } + _PyDict_SetItemId(type->tp_dict, &PyId___module__, modname); + Py_DECREF(modname); + } else { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "builtin type %.200s has no __module__ attribute", + spec->name)) + goto fail; + } return (PyObject*)res; @@ -2562,6 +2844,19 @@ 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. This returns a borrowed reference, and doesn't set an exception! */ @@ -2577,8 +2872,12 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name) /* fast path */ h = MCACHE_HASH_METHOD(type, name); if (method_cache[h].version == type->tp_version_tag && - method_cache[h].name == name) + method_cache[h].name == name) { +#if MCACHE_STATS + method_cache_hits++; +#endif return method_cache[h].value; + } } /* Look in tp_dict of types in MRO */ @@ -2612,6 +2911,13 @@ _PyType_Lookup(PyTypeObject *type, PyObject *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_DECREF(method_cache[h].name); method_cache[h].name = name; } @@ -2909,6 +3215,8 @@ static PyMethodDef type_methods[] = { }; 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"); @@ -3220,9 +3528,14 @@ object_richcompare(PyObject *self, PyObject *other, int op) break; case Py_NE: - /* By default, != returns the opposite of ==, + /* By default, __ne__() delegates to __eq__() and inverts the result, unless the latter returns NotImplemented. */ - res = PyObject_RichCompare(self, other, Py_EQ); + 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); @@ -3255,17 +3568,18 @@ object_get_class(PyObject *self, void *closure) } static int -equiv_structs(PyTypeObject *a, PyTypeObject *b) +compatible_with_tp_base(PyTypeObject *child) { - return a == b || - (a != NULL && - b != NULL && - a->tp_basicsize == b->tp_basicsize && - a->tp_itemsize == b->tp_itemsize && - a->tp_dictoffset == b->tp_dictoffset && - a->tp_weaklistoffset == b->tp_weaklistoffset && - ((a->tp_flags & Py_TPFLAGS_HAVE_GC) == - (b->tp_flags & Py_TPFLAGS_HAVE_GC))); + 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 @@ -3283,6 +3597,10 @@ same_slots_added(PyTypeObject *a, PyTypeObject *b) 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) { @@ -3298,9 +3616,7 @@ compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, char* attr) { PyTypeObject *newbase, *oldbase; - if (newto->tp_dealloc != oldto->tp_dealloc || - newto->tp_free != oldto->tp_free) - { + if (newto->tp_free != oldto->tp_free) { PyErr_Format(PyExc_TypeError, "%s assignment: " "'%s' deallocator differs from '%s'", @@ -3309,11 +3625,21 @@ compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, char* attr) 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 (equiv_structs(newbase, newbase->tp_base)) + while (compatible_with_tp_base(newbase)) newbase = newbase->tp_base; - while (equiv_structs(oldbase, oldbase->tp_base)) + while (compatible_with_tp_base(oldbase)) oldbase = oldbase->tp_base; if (newbase != oldbase && (newbase->tp_base != oldbase->tp_base || @@ -3348,17 +3674,71 @@ object_set_class(PyObject *self, PyObject *value, void *closure) return -1; } newto = (PyTypeObject *)value; - if (!(newto->tp_flags & Py_TPFLAGS_HEAPTYPE) || - !(oldto->tp_flags & Py_TPFLAGS_HEAPTYPE)) - { + /* 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 for heap types"); + "__class__ assignment only supported for heap types " + "or ModuleType subclasses"); return -1; } + if (compatible_for_assignment(oldto, newto, "__class__")) { - Py_INCREF(newto); + if (newto->tp_flags & Py_TPFLAGS_HEAPTYPE) + Py_INCREF(newto); Py_TYPE(self) = newto; - Py_DECREF(oldto); + if (oldto->tp_flags & Py_TPFLAGS_HEAPTYPE) + Py_DECREF(oldto); return 0; } else { @@ -3480,7 +3860,7 @@ _PyObject_GetState(PyObject *obj) { PyObject **dict; dict = _PyObject_GetDictPtr(obj); - /* It is possible that the object's dict is not initialized + /* 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. @@ -3593,7 +3973,7 @@ _PyObject_GetNewArguments(PyObject *obj, PyObject **args, PyObject **kwargs) /* We first attempt to fetch the arguments for __new__ by calling __getnewargs_ex__ on the object. */ - getnewargs_ex = _PyObject_GetAttrId(obj, &PyId___getnewargs_ex__); + getnewargs_ex = _PyObject_LookupSpecial(obj, &PyId___getnewargs_ex__); if (getnewargs_ex != NULL) { PyObject *newargs = PyObject_CallObject(getnewargs_ex, NULL); Py_DECREF(getnewargs_ex); @@ -3640,16 +4020,13 @@ _PyObject_GetNewArguments(PyObject *obj, PyObject **args, PyObject **kwargs) return -1; } return 0; - } else { - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { - return -1; - } - PyErr_Clear(); + } else if (PyErr_Occurred()) { + return -1; } /* The object does not have __getnewargs_ex__ so we fallback on using __getnewargs__ instead. */ - getnewargs = _PyObject_GetAttrId(obj, &PyId___getnewargs__); + getnewargs = _PyObject_LookupSpecial(obj, &PyId___getnewargs__); if (getnewargs != NULL) { *args = PyObject_CallObject(getnewargs, NULL); Py_DECREF(getnewargs); @@ -3665,11 +4042,8 @@ _PyObject_GetNewArguments(PyObject *obj, PyObject **args, PyObject **kwargs) } *kwargs = NULL; return 0; - } else { - if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { - return -1; - } - PyErr_Clear(); + } else if (PyErr_Occurred()) { + return -1; } /* The object does not have __getnewargs_ex__ and __getnewargs__. This may @@ -3727,48 +4101,77 @@ _PyObject_GetItemsIter(PyObject *obj, PyObject **listitems, } static PyObject * -reduce_4(PyObject *obj) +reduce_newobj(PyObject *obj) { PyObject *args = NULL, *kwargs = NULL; PyObject *copyreg; PyObject *newobj, *newargs, *state, *listitems, *dictitems; PyObject *result; - _Py_IDENTIFIER(__newobj_ex__); - if (_PyObject_GetNewArguments(obj, &args, &kwargs) < 0) { + if (_PyObject_GetNewArguments(obj, &args, &kwargs) < 0) return NULL; - } + if (args == NULL) { args = PyTuple_New(0); - if (args == NULL) - return NULL; - } - if (kwargs == NULL) { - kwargs = PyDict_New(); - if (kwargs == NULL) + if (args == NULL) { + Py_XDECREF(kwargs); return NULL; + } } - copyreg = import_copyreg(); if (copyreg == NULL) { Py_DECREF(args); - Py_DECREF(kwargs); + Py_XDECREF(kwargs); return NULL; } - newobj = _PyObject_GetAttrId(copyreg, &PyId___newobj_ex__); - Py_DECREF(copyreg); - if (newobj == NULL) { + if (kwargs == NULL || PyDict_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_DECREF(args); + return NULL; + } + n = PyTuple_GET_SIZE(args); + newargs = PyTuple_New(n+1); + if (newargs == NULL) { + Py_DECREF(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_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 { + _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; + } } + state = _PyObject_GetState(obj); if (state == NULL) { Py_DECREF(newobj); @@ -3788,80 +4191,7 @@ reduce_4(PyObject *obj) Py_DECREF(state); Py_DECREF(listitems); Py_DECREF(dictitems); - return result; -} - -static PyObject * -reduce_2(PyObject *obj) -{ - PyObject *cls; - PyObject *args = NULL, *args2 = NULL, *kwargs = NULL; - PyObject *state = NULL, *listitems = NULL, *dictitems = NULL; - PyObject *copyreg = NULL, *newobj = NULL, *res = NULL; - Py_ssize_t i, n; - _Py_IDENTIFIER(__newobj__); - - if (_PyObject_GetNewArguments(obj, &args, &kwargs) < 0) { - return NULL; - } - if (args == NULL) { - assert(kwargs == NULL); - args = PyTuple_New(0); - if (args == NULL) { - return NULL; - } - } - else if (kwargs != NULL) { - if (PyDict_Size(kwargs) > 0) { - PyErr_SetString(PyExc_ValueError, - "must use protocol 4 or greater to copy this " - "object; since __getnewargs_ex__ returned " - "keyword arguments."); - Py_DECREF(args); - Py_DECREF(kwargs); - return NULL; - } - Py_CLEAR(kwargs); - } - - state = _PyObject_GetState(obj); - if (state == NULL) - goto end; - - if (_PyObject_GetItemsIter(obj, &listitems, &dictitems) < 0) - goto end; - - copyreg = import_copyreg(); - if (copyreg == NULL) - goto end; - newobj = _PyObject_GetAttrId(copyreg, &PyId___newobj__); - if (newobj == NULL) - goto end; - - n = PyTuple_GET_SIZE(args); - args2 = PyTuple_New(n+1); - if (args2 == NULL) - goto end; - cls = (PyObject *) Py_TYPE(obj); - Py_INCREF(cls); - PyTuple_SET_ITEM(args2, 0, cls); - for (i = 0; i < n; i++) { - PyObject *v = PyTuple_GET_ITEM(args, i); - Py_INCREF(v); - PyTuple_SET_ITEM(args2, i+1, v); - } - - res = PyTuple_Pack(5, newobj, args2, state, listitems, dictitems); - - end: - Py_XDECREF(args); - Py_XDECREF(args2); - Py_XDECREF(state); - Py_XDECREF(listitems); - Py_XDECREF(dictitems); - Py_XDECREF(copyreg); - Py_XDECREF(newobj); - return res; + return result; } /* @@ -3869,7 +4199,7 @@ reduce_2(PyObject *obj) * 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 RuntimeError. + * 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. @@ -3884,10 +4214,8 @@ _common_reduce(PyObject *self, int proto) { PyObject *copyreg, *res; - if (proto >= 4) - return reduce_4(self); - else if (proto >= 2) - return reduce_2(self); + if (proto >= 2) + return reduce_newobj(self); copyreg = import_copyreg(); if (!copyreg) @@ -3974,7 +4302,7 @@ PyDoc_STRVAR(object_subclasshook_doc, class object: def __format__(self, format_spec): - return format(str(self), format_spec) + return format(str(self), format_spec) */ static PyObject * object_format(PyObject *self, PyObject *args) @@ -4013,7 +4341,7 @@ object_sizeof(PyObject *self, PyObject *args) res = 0; isize = self->ob_type->tp_itemsize; if (isize > 0) - res = Py_SIZE(self->ob_type) * isize; + res = Py_SIZE(self) * isize; res += self->ob_type->tp_basicsize; return PyLong_FromSsize_t(res); @@ -4103,8 +4431,8 @@ PyTypeObject PyBaseObject_Type = { PyObject_GenericGetAttr, /* tp_getattro */ PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - PyDoc_STR("The most base type"), /* tp_doc */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + PyDoc_STR("object()\n--\n\nThe most base type"), /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ object_richcompare, /* tp_richcompare */ @@ -4302,6 +4630,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) #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) @@ -4347,6 +4676,17 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) 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) { @@ -4534,9 +4874,8 @@ PyType_Ready(PyTypeObject *type) } /* Calculate method resolution order */ - if (mro_internal(type) < 0) { + if (mro_internal(type, NULL) < 0) goto error; - } /* Inherit special flags from dominant base */ if (type->tp_base != NULL) @@ -4553,6 +4892,20 @@ PyType_Ready(PyTypeObject *type) 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)) { @@ -4571,7 +4924,9 @@ PyType_Ready(PyTypeObject *type) */ if (_PyDict_GetItemId(type->tp_dict, &PyId___doc__) == NULL) { if (type->tp_doc != NULL) { - PyObject *doc = PyUnicode_FromString(type->tp_doc); + 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) { @@ -4603,6 +4958,8 @@ PyType_Ready(PyTypeObject *type) /* 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) @@ -4623,16 +4980,6 @@ PyType_Ready(PyTypeObject *type) goto error; } - /* Warn for a type that implements tp_compare (now known as - tp_reserved) but not tp_richcompare. */ - if (type->tp_reserved && !type->tp_richcompare) { - PyErr_Format(PyExc_TypeError, - "Type %.100s defines tp_reserved (formerly tp_compare) " - "but not tp_richcompare. Comparisons may not behave as intended.", - type->tp_name); - goto error; - } - /* All done -- set the ready flag */ assert(type->tp_dict != NULL); type->tp_flags = @@ -4669,6 +5016,24 @@ add_subclass(PyTypeObject *base, PyTypeObject *type) 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) { @@ -5218,7 +5583,7 @@ tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds) "%s.__new__(%s) is not safe, use %s.__new__()", type->tp_name, subtype->tp_name, - staticbase == NULL ? "?" : staticbase->tp_name); + staticbase->tp_name); return NULL; } @@ -5232,8 +5597,9 @@ tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds) static struct PyMethodDef tp_new_methoddef[] = { {"__new__", (PyCFunction)tp_new_wrapper, METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("T.__new__(S, ...) -> " - "a new object with type S, a subtype of T")}, + PyDoc_STR("__new__($type, *args, **kwargs)\n--\n\n" + "Create and return a new object. " + "See help(type) for accurate signature.")}, {0} }; @@ -5480,6 +5846,7 @@ slot_mp_ass_subscript(PyObject *self, PyObject *key, PyObject *value) 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__") @@ -5573,6 +5940,7 @@ SLOT0(slot_nb_float, "__float__") SLOT1(slot_nb_inplace_add, "__iadd__", PyObject *, "O") SLOT1(slot_nb_inplace_subtract, "__isub__", PyObject *, "O") SLOT1(slot_nb_inplace_multiply, "__imul__", PyObject *, "O") +SLOT1(slot_nb_inplace_matrix_multiply, "__imatmul__", PyObject *, "O") SLOT1(slot_nb_inplace_remainder, "__imod__", PyObject *, "O") /* Can't use SLOT1 here, because nb_inplace_power is ternary */ static PyObject * @@ -5963,6 +6331,59 @@ slot_tp_finalize(PyObject *self) PyErr_Restore(error_type, error_value, error_traceback); } +static PyObject * +slot_am_await(PyObject *self) +{ + PyObject *func, *res; + _Py_IDENTIFIER(__await__); + + func = lookup_method(self, &PyId___await__); + if (func != NULL) { + res = PyEval_CallObject(func, NULL); + 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) +{ + PyObject *func, *res; + _Py_IDENTIFIER(__aiter__); + + func = lookup_method(self, &PyId___aiter__); + if (func != NULL) { + res = PyEval_CallObject(func, NULL); + 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) +{ + PyObject *func, *res; + _Py_IDENTIFIER(__anext__); + + func = lookup_method(self, &PyId___anext__); + if (func != NULL) { + res = PyEval_CallObject(func, NULL); + 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. @@ -5979,6 +6400,7 @@ typedef struct wrapperbase slotdef; #undef TPSLOT #undef FLSLOT +#undef AMSLOT #undef ETSLOT #undef SQSLOT #undef MPSLOT @@ -5997,6 +6419,8 @@ typedef struct wrapperbase slotdef; #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) \ @@ -6005,22 +6429,22 @@ typedef struct wrapperbase slotdef; ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC) #define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \ - "x." NAME "() <==> " DOC) + NAME "($self, /)\n--\n\n" DOC) #define IBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \ - "x." NAME "(y) <==> x" DOC "y") + NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") #define BINSLOT(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \ - "x." NAME "(y) <==> x" DOC "y") + NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") #define RBINSLOT(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ - "x." NAME "(y) <==> y" DOC "x") + NAME "($self, value, /)\n--\n\nReturn value" DOC "self.") #define BINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \ - "x." NAME "(y) <==> " DOC) + NAME "($self, value, /)\n--\n\n" DOC) #define RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ - "x." NAME "(y) <==> " DOC) + NAME "($self, value, /)\n--\n\n" DOC) static slotdef slotdefs[] = { TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""), @@ -6028,80 +6452,92 @@ static slotdef slotdefs[] = { TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""), TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""), TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc, - "x.__repr__() <==> repr(x)"), + "__repr__($self, /)\n--\n\nReturn repr(self)."), TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc, - "x.__hash__() <==> hash(x)"), + "__hash__($self, /)\n--\n\nReturn hash(self)."), FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)wrap_call, - "x.__call__(...) <==> x(...)", PyWrapperFlag_KEYWORDS), + "__call__($self, /, *args, **kwargs)\n--\n\nCall self as a function.", + PyWrapperFlag_KEYWORDS), TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc, - "x.__str__() <==> str(x)"), + "__str__($self, /)\n--\n\nReturn str(self)."), TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook, - wrap_binaryfunc, "x.__getattribute__('name') <==> x.name"), + 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, - "x.__setattr__('name', value) <==> x.name = value"), + "__setattr__($self, name, value, /)\n--\n\nImplement setattr(self, name, value)."), TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr, - "x.__delattr__('name') <==> del x.name"), + "__delattr__($self, name, /)\n--\n\nImplement delattr(self, name)."), TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt, - "x.__lt__(y) <==> x x<=y"), + "__le__($self, value, /)\n--\n\nReturn self<=value."), TPSLOT("__eq__", tp_richcompare, slot_tp_richcompare, richcmp_eq, - "x.__eq__(y) <==> x==y"), + "__eq__($self, value, /)\n--\n\nReturn self==value."), TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare, richcmp_ne, - "x.__ne__(y) <==> x!=y"), + "__ne__($self, value, /)\n--\n\nReturn self!=value."), TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare, richcmp_gt, - "x.__gt__(y) <==> x>y"), + "__gt__($self, value, /)\n--\n\nReturn self>value."), TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge, - "x.__ge__(y) <==> x>=y"), + "__ge__($self, value, /)\n--\n\nReturn self>=value."), TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc, - "x.__iter__() <==> iter(x)"), + "__iter__($self, /)\n--\n\nImplement iter(self)."), TPSLOT("__next__", tp_iternext, slot_tp_iternext, wrap_next, - "x.__next__() <==> next(x)"), + "__next__($self, /)\n--\n\nImplement next(self)."), TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get, - "descr.__get__(obj[, type]) -> value"), + "__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, - "descr.__set__(obj, value)"), + "__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, "descr.__delete__(obj)"), + wrap_descr_delete, + "__delete__($self, instance, /)\n--\n\nDelete an attribute of instance."), FLSLOT("__init__", tp_init, slot_tp_init, (wrapperfunc)wrap_init, - "x.__init__(...) initializes x; " - "see help(type(x)) for signature", + "__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, ""), + 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, - "divmod(x, y)"), + "Return divmod(self, value)."), RBINSLOTNOTINFIX("__rdivmod__", nb_divmod, slot_nb_divmod, - "divmod(y, x)"), + "Return divmod(value, self)."), NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc, - "x.__pow__(y[, z]) <==> pow(x, y[, z])"), + "__pow__($self, value, mod=None, /)\n--\n\nReturn pow(self, value, mod)."), NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r, - "y.__rpow__(x[, z]) <==> pow(x, y[, z])"), - UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-x"), - UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+x"), + "__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(x)"), + "abs(self)"), UNSLOT("__bool__", nb_bool, slot_nb_bool, wrap_inquirypred, - "x != 0"), - UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~x"), + "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, ">>"), @@ -6113,9 +6549,9 @@ static slotdef slotdefs[] = { BINSLOT("__or__", nb_or, slot_nb_or, "|"), RBINSLOT("__ror__", nb_or, slot_nb_or, "|"), UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc, - "int(x)"), + "int(self)"), UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc, - "float(x)"), + "float(self)"), IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add, wrap_binaryfunc, "+="), IBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract, @@ -6141,49 +6577,58 @@ static slotdef slotdefs[] = { 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, "//"), + slot_nb_inplace_floor_divide, wrap_binaryfunc, "//="), IBSLOT("__itruediv__", nb_inplace_true_divide, - slot_nb_inplace_true_divide, wrap_binaryfunc, "/"), + slot_nb_inplace_true_divide, wrap_binaryfunc, "/="), NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc, - "x[y:z] <==> x[y.__index__():z.__index__()]"), - + "__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, - "x.__len__() <==> len(x)"), + "__len__($self, /)\n--\n\nReturn len(self)."), MPSLOT("__getitem__", mp_subscript, slot_mp_subscript, wrap_binaryfunc, - "x.__getitem__(y) <==> x[y]"), + "__getitem__($self, key, /)\n--\n\nReturn self[key]."), MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript, wrap_objobjargproc, - "x.__setitem__(i, y) <==> x[i]=y"), + "__setitem__($self, key, value, /)\n--\n\nSet self[key] to value."), MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript, wrap_delitem, - "x.__delitem__(y) <==> del x[y]"), + "__delitem__($self, key, /)\n--\n\nDelete self[key]."), SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc, - "x.__len__() <==> len(x)"), + "__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, - "x.__add__(y) <==> x+y"), + "__add__($self, value, /)\n--\n\nReturn self+value."), SQSLOT("__mul__", sq_repeat, NULL, wrap_indexargfunc, - "x.__mul__(n) <==> x*n"), + "__mul__($self, value, /)\n--\n\nReturn self*value.n"), SQSLOT("__rmul__", sq_repeat, NULL, wrap_indexargfunc, - "x.__rmul__(n) <==> n*x"), + "__rmul__($self, value, /)\n--\n\nReturn self*value."), SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item, - "x.__getitem__(y) <==> x[y]"), + "__getitem__($self, key, /)\n--\n\nReturn self[key]."), SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem, - "x.__setitem__(i, y) <==> x[i]=y"), + "__setitem__($self, key, value, /)\n--\n\nSet self[key] to value."), SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem, - "x.__delitem__(y) <==> del x[y]"), + "__delitem__($self, key, /)\n--\n\nDelete self[key]."), SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc, - "x.__contains__(y) <==> y in x"), + "__contains__($self, key, /)\n--\n\nReturn key in self."), SQSLOT("__iadd__", sq_inplace_concat, NULL, - wrap_binaryfunc, "x.__iadd__(y) <==> x+=y"), + wrap_binaryfunc, + "__iadd__($self, value, /)\n--\n\nImplement self+=value."), SQSLOT("__imul__", sq_inplace_repeat, NULL, - wrap_indexargfunc, "x.__imul__(y) <==> x*=y"), + wrap_indexargfunc, + "__imul__($self, value, /)\n--\n\nImplement self*=value."), {NULL} }; @@ -6214,6 +6659,10 @@ slotptr(PyTypeObject *type, int ioffset) 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; } @@ -6365,15 +6814,15 @@ update_slots_callback(PyTypeObject *type, void *data) return 0; } +static int slotdefs_initialized = 0; /* Initialize the slotdefs table by adding interned string objects for the - names and sorting the entries. */ + names. */ static void init_slotdefs(void) { slotdef *p; - static int initialized = 0; - if (initialized) + if (slotdefs_initialized) return; for (p = slotdefs; p->name; p++) { /* Slots must be ordered by their offset in the PyHeapTypeObject. */ @@ -6382,7 +6831,17 @@ init_slotdefs(void) if (!p->name_strobj) Py_FatalError("Out of memory interning slotdef names"); } - initialized = 1; + 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. */ @@ -6613,70 +7072,74 @@ static PyObject * super_getattro(PyObject *self, PyObject *name) { superobject *su = (superobject *)self; - int skip = su->obj_type == NULL; + 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_CompareWithId(name, &PyId___class__) == 0) + goto skip; + + mro = starttype->tp_mro; + if (mro == NULL) + goto skip; + + assert(PyTuple_Check(mro)); + n = PyTuple_GET_SIZE(mro); - if (!skip) { - /* We want __class__ to return the class of the super object - (i.e. super, or a subclass), not the class of su->obj. */ - skip = (PyUnicode_Check(name) && - PyUnicode_GET_LENGTH(name) == 9 && - _PyUnicode_CompareWithId(name, &PyId___class__) == 0); + /* 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; - if (!skip) { - PyObject *mro, *res, *tmp, *dict; - PyTypeObject *starttype; + /* keep a strong reference to mro because starttype->tp_mro can be + replaced during PyDict_GetItem(dict, name) */ + Py_INCREF(mro); + do { + PyObject *res, *tmp, *dict; descrgetfunc f; - Py_ssize_t i, n; - starttype = su->obj_type; - mro = starttype->tp_mro; + tmp = PyTuple_GET_ITEM(mro, i); + assert(PyType_Check(tmp)); - if (mro == NULL) - n = 0; - else { - assert(PyTuple_Check(mro)); - n = PyTuple_GET_SIZE(mro); - } - for (i = 0; i < n; i++) { - if ((PyObject *)(su->type) == PyTuple_GET_ITEM(mro, i)) - break; - } - i++; - res = NULL; - /* keep a strong reference to mro because starttype->tp_mro can be - replaced during PyDict_GetItem(dict, name) */ - Py_INCREF(mro); - for (; i < n; i++) { - tmp = PyTuple_GET_ITEM(mro, i); - if (PyType_Check(tmp)) - dict = ((PyTypeObject *)tmp)->tp_dict; - else - continue; - res = PyDict_GetItem(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 *) - su->obj_type - ? (PyObject *)NULL - : su->obj), - (PyObject *)starttype); - Py_DECREF(res); - res = tmp; - } - Py_DECREF(mro); - return res; + dict = ((PyTypeObject *)tmp)->tp_dict; + assert(dict != NULL && PyDict_Check(dict)); + + res = PyDict_GetItem(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; } - Py_DECREF(mro); - } + + i++; + } while (i < n); + Py_DECREF(mro); + + skip: return PyObject_GenericGetAttr(self, name); } @@ -6786,9 +7249,16 @@ super_init(PyObject *self, PyObject *args, PyObject *kwds) if (type == NULL) { /* Call super(), without args -- fill in from __class__ and first local variable on the stack. */ - PyFrameObject *f = PyThreadState_GET()->frame; - PyCodeObject *co = f->f_code; + 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"); diff --git a/Objects/typeslots.inc b/Objects/typeslots.inc index caa1e035d679..dc750cc0c419 100644 --- a/Objects/typeslots.inc +++ b/Objects/typeslots.inc @@ -73,3 +73,9 @@ 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/Objects/typeslots.py b/Objects/typeslots.py old mode 100644 new mode 100755 index b24c7f404014..ba37c403975f --- a/Objects/typeslots.py +++ b/Objects/typeslots.py @@ -12,6 +12,8 @@ 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_"): diff --git a/Objects/unicodectype.c b/Objects/unicodectype.c index ea540d605def..d8c95c8b44ce 100644 --- a/Objects/unicodectype.c +++ b/Objects/unicodectype.c @@ -27,7 +27,7 @@ #define EXTENDED_CASE_MASK 0x4000 typedef struct { - /* + /* These are either deltas to the character or offsets in _PyUnicode_ExtendedCase. */ diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 34d51e404cc4..f5044c8a4a59 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -42,15 +42,16 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "Python.h" #include "ucnhash.h" #include "bytes_methods.h" +#include "stringlib/eq.h" #ifdef MS_WINDOWS #include #endif -/*[clinic] -class str -[clinic]*/ -/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ +/*[clinic input] +class str "PyUnicodeObject *" "&PyUnicode_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=604e916854800fa8]*/ /* --- Globals ------------------------------------------------------------ @@ -162,6 +163,14 @@ extern "C" { *_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 @@ -290,6 +299,40 @@ static unsigned char ascii_linebreak[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +#include "clinic/unicodeobject.c.h" + +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; + +static _Py_error_handler +get_error_handler(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; +} + /* 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 @@ -519,9 +562,128 @@ unicode_result_unchanged(PyObject *unicode) return _PyUnicode_Copy(unicode); } -#ifdef HAVE_MBCS -static OSVERSIONINFOEX winver; -#endif +/* 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 ----------------------------------------------------- */ @@ -645,7 +807,7 @@ make_bloom_mask(int kind, void* ptr, Py_ssize_t len) static PyObject * fixup(PyObject *self, Py_UCS4 (*fixfct)(PyObject *s)); -Py_LOCAL_INLINE(Py_ssize_t) findchar(void *s, int kind, +Py_LOCAL_INLINE(Py_ssize_t) findchar(const void *s, int kind, Py_ssize_t size, Py_UCS4 ch, int direction) { @@ -727,7 +889,7 @@ resize_compact(PyObject *unicode, Py_ssize_t length) _Py_DEC_REFTOTAL; _Py_ForgetReference(unicode); - new_unicode = (PyObject *)PyObject_REALLOC((char *)unicode, new_size); + new_unicode = (PyObject *)PyObject_REALLOC(unicode, new_size); if (new_unicode == NULL) { _Py_NewReference(unicode); PyErr_NoMemory(); @@ -816,7 +978,7 @@ resize_inplace(PyObject *unicode, Py_ssize_t length) assert(_PyUnicode_WSTR(unicode) != NULL); /* check for integer overflow */ - if (length > PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) { + if (length > PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(wchar_t) - 1) { PyErr_NoMemory(); return -1; } @@ -888,7 +1050,7 @@ _PyUnicode_New(Py_ssize_t length) } /* Ensure we won't overflow the size. */ - if (length > ((PY_SSIZE_T_MAX / sizeof(Py_UNICODE)) - 1)) { + if (length > ((PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(Py_UNICODE)) - 1)) { return (PyUnicodeObject *)PyErr_NoMemory(); } if (length < 0) { @@ -1011,17 +1173,19 @@ _PyUnicode_Dump(PyObject *op) } else data = unicode->data.any; - printf("%s: len=%zu, ",unicode_kind_name(op), ascii->length); + printf("%s: len=%" PY_FORMAT_SIZE_T "u, ", + unicode_kind_name(op), ascii->length); if (ascii->wstr == data) printf("shared "); printf("wstr=%p", ascii->wstr); if (!(ascii->state.ascii == 1 && ascii->state.compact == 1)) { - printf(" (%zu), ", compact->wstr_length); + printf(" (%" PY_FORMAT_SIZE_T "u), ", compact->wstr_length); if (!ascii->state.compact && compact->utf8 == unicode->data.any) printf("shared "); - printf("utf8=%p (%zu)", compact->utf8, compact->utf8_length); + printf("utf8=%p (%" PY_FORMAT_SIZE_T "u)", + compact->utf8, compact->utf8_length); } printf(", data=%p\n", data); } @@ -1533,6 +1697,10 @@ _PyUnicode_Ready(PyObject *unicode) /* 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(); @@ -1749,7 +1917,6 @@ unicode_write_cstr(PyObject *unicode, Py_ssize_t index, } } - static PyObject* get_latin1_char(unsigned char ch) { @@ -1766,6 +1933,34 @@ get_latin1_char(unsigned char ch) 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; + switch (PyUnicode_KIND(unicode)) { + case PyUnicode_1BYTE_KIND: + PyUnicode_1BYTE_DATA(unicode)[0] = (Py_UCS1)ch; + break; + case PyUnicode_2BYTE_KIND: + PyUnicode_2BYTE_DATA(unicode)[0] = (Py_UCS2)ch; + break; + default: + 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) { @@ -1875,8 +2070,7 @@ _PyUnicode_ClearStaticStrings() { _Py_Identifier *tmp, *s = static_strings; while (s) { - Py_DECREF(s->object); - s->object = NULL; + Py_CLEAR(s->object); tmp = s->next; s->next = NULL; s = tmp; @@ -1964,22 +2158,8 @@ _PyUnicode_FromUCS2(const Py_UCS2 *u, Py_ssize_t size) if (size == 0) _Py_RETURN_UNICODE_EMPTY(); assert(size > 0); - if (size == 1) { - Py_UCS4 ch = u[0]; - int kind; - void *data; - if (ch < 256) - return get_latin1_char((unsigned char)ch); - - res = PyUnicode_New(1, ch); - if (res == NULL) - return NULL; - kind = PyUnicode_KIND(res); - data = PyUnicode_DATA(res); - PyUnicode_WRITE(kind, data, 0, ch); - assert(_PyUnicode_CheckConsistency(res, 1)); - return res; - } + if (size == 1) + return unicode_char(u[0]); max_char = ucs2lib_find_max_char(u, u + size); res = PyUnicode_New(size, max_char); @@ -2004,22 +2184,8 @@ _PyUnicode_FromUCS4(const Py_UCS4 *u, Py_ssize_t size) if (size == 0) _Py_RETURN_UNICODE_EMPTY(); assert(size > 0); - if (size == 1) { - Py_UCS4 ch = u[0]; - int kind; - void *data; - if (ch < 256) - return get_latin1_char((unsigned char)ch); - - res = PyUnicode_New(1, ch); - if (res == NULL) - return NULL; - kind = PyUnicode_KIND(res); - data = PyUnicode_DATA(res); - PyUnicode_WRITE(kind, data, 0, ch); - assert(_PyUnicode_CheckConsistency(res, 1)); - return res; - } + if (size == 1) + return unicode_char(u[0]); max_char = ucs4lib_find_max_char(u, u + size); res = PyUnicode_New(size, max_char); @@ -2186,7 +2352,7 @@ _PyUnicode_AsKind(PyObject *s, unsigned int kind) } switch (kind) { case PyUnicode_2BYTE_KIND: - result = PyMem_Malloc(len * sizeof(Py_UCS2)); + result = PyMem_New(Py_UCS2, len); if (!result) return PyErr_NoMemory(); assert(skind == PyUnicode_1BYTE_KIND); @@ -2197,7 +2363,7 @@ _PyUnicode_AsKind(PyObject *s, unsigned int kind) result); return result; case PyUnicode_4BYTE_KIND: - result = PyMem_Malloc(len * sizeof(Py_UCS4)); + result = PyMem_New(Py_UCS4, len); if (!result) return PyErr_NoMemory(); if (skind == PyUnicode_2BYTE_KIND) { @@ -2239,11 +2405,7 @@ as_ucs4(PyObject *string, Py_UCS4 *target, Py_ssize_t targetsize, if (copy_null) targetlen++; if (!target) { - if (PY_SSIZE_T_MAX / sizeof(Py_UCS4) < targetlen) { - PyErr_NoMemory(); - return NULL; - } - target = PyMem_Malloc(targetlen * sizeof(Py_UCS4)); + target = PyMem_New(Py_UCS4, targetlen); if (!target) { PyErr_NoMemory(); return NULL; @@ -2313,35 +2475,6 @@ PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size) #endif /* HAVE_WCHAR_H */ -static void -makefmt(char *fmt, int longflag, int longlongflag, int size_tflag, - char c) -{ - *fmt++ = '%'; - if (longflag) - *fmt++ = 'l'; - else if (longlongflag) { - /* longlongflag should only ever be nonzero on machines with - HAVE_LONG_LONG defined */ -#ifdef HAVE_LONG_LONG - char *f = PY_FORMAT_LONG_LONG; - while (*f) - *fmt++ = *f++; -#else - /* we shouldn't ever get here */ - assert(0); - *fmt++ = 'l'; -#endif - } - else if (size_tflag) { - char *f = PY_FORMAT_SIZE_T; - while (*f) - *fmt++ = *f++; - } - *fmt++ = c; - *fmt = '\0'; -} - /* 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). */ @@ -2517,48 +2650,42 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, case 'x': { /* used by sprintf */ - char fmt[10]; /* should be enough for "%0lld\0" */ char buffer[MAX_LONG_LONG_CHARS]; Py_ssize_t arglen; if (*f == 'u') { - makefmt(fmt, longflag, longlongflag, size_tflag, *f); - if (longflag) - len = sprintf(buffer, fmt, + len = sprintf(buffer, "%lu", va_arg(*vargs, unsigned long)); #ifdef HAVE_LONG_LONG else if (longlongflag) - len = sprintf(buffer, fmt, + len = sprintf(buffer, "%" PY_FORMAT_LONG_LONG "u", va_arg(*vargs, unsigned PY_LONG_LONG)); #endif else if (size_tflag) - len = sprintf(buffer, fmt, + len = sprintf(buffer, "%" PY_FORMAT_SIZE_T "u", va_arg(*vargs, size_t)); else - len = sprintf(buffer, fmt, + len = sprintf(buffer, "%u", va_arg(*vargs, unsigned int)); } else if (*f == 'x') { - makefmt(fmt, 0, 0, 0, 'x'); - len = sprintf(buffer, fmt, va_arg(*vargs, int)); + len = sprintf(buffer, "%x", va_arg(*vargs, int)); } else { - makefmt(fmt, longflag, longlongflag, size_tflag, *f); - if (longflag) - len = sprintf(buffer, fmt, + len = sprintf(buffer, "%li", va_arg(*vargs, long)); #ifdef HAVE_LONG_LONG else if (longlongflag) - len = sprintf(buffer, fmt, + len = sprintf(buffer, "%" PY_FORMAT_LONG_LONG "i", va_arg(*vargs, PY_LONG_LONG)); #endif else if (size_tflag) - len = sprintf(buffer, fmt, + len = sprintf(buffer, "%" PY_FORMAT_SIZE_T "i", va_arg(*vargs, Py_ssize_t)); else - len = sprintf(buffer, fmt, + len = sprintf(buffer, "%i", va_arg(*vargs, int)); } assert(len >= 0); @@ -2852,12 +2979,7 @@ PyUnicode_AsWideCharString(PyObject *unicode, buflen = unicode_aswidechar(unicode, NULL, 0); if (buflen == -1) return NULL; - if (PY_SSIZE_T_MAX / sizeof(wchar_t) < buflen) { - PyErr_NoMemory(); - return NULL; - } - - buffer = PyMem_MALLOC(buflen * sizeof(wchar_t)); + buffer = PyMem_NEW(wchar_t, buflen); if (buffer == NULL) { PyErr_NoMemory(); return NULL; @@ -2877,27 +2999,13 @@ PyUnicode_AsWideCharString(PyObject *unicode, PyObject * PyUnicode_FromOrdinal(int ordinal) { - PyObject *v; - void *data; - int kind; - if (ordinal < 0 || ordinal > MAX_UNICODE) { PyErr_SetString(PyExc_ValueError, "chr() arg not in range(0x110000)"); return NULL; } - if ((Py_UCS4)ordinal < 256) - return get_latin1_char((unsigned char)ordinal); - - v = PyUnicode_New(1, ordinal); - if (v == NULL) - return NULL; - kind = PyUnicode_KIND(v); - data = PyUnicode_DATA(v); - PyUnicode_WRITE(kind, data, 0, ordinal); - assert(_PyUnicode_CheckConsistency(v, 1)); - return v; + return unicode_char((Py_UCS4)ordinal); } PyObject * @@ -2954,8 +3062,7 @@ PyUnicode_FromEncodedObject(PyObject *obj, /* Retrieve a bytes buffer view through the PEP 3118 buffer interface */ if (PyObject_GetBuffer(obj, &buffer, PyBUF_SIMPLE) < 0) { PyErr_Format(PyExc_TypeError, - "coercing to str: need bytes, bytearray " - "or buffer-like object, %.80s found", + "coercing to str: need a bytes-like object, %.80s found", Py_TYPE(obj)->tp_name); return NULL; } @@ -3219,24 +3326,22 @@ wcstombs_errorpos(const wchar_t *wstr) static int locale_error_handler(const char *errors, int *surrogateescape) { - if (errors == NULL) { - *surrogateescape = 0; - return 0; - } - - if (strcmp(errors, "strict") == 0) { + _Py_error_handler error_handler = get_error_handler(errors); + switch (error_handler) + { + case _Py_ERROR_STRICT: *surrogateescape = 0; return 0; - } - if (strcmp(errors, "surrogateescape") == 0) { + case _Py_ERROR_SURROGATEESCAPE: *surrogateescape = 1; return 0; + default: + PyErr_Format(PyExc_ValueError, + "only 'strict' and 'surrogateescape' error handlers " + "are supported, not '%s'", + errors); + return -1; } - PyErr_Format(PyExc_ValueError, - "only 'strict' and 'surrogateescape' error handlers " - "are supported, not '%s'", - errors); - return -1; } PyObject * @@ -3261,7 +3366,7 @@ PyUnicode_EncodeLocale(PyObject *unicode, const char *errors) wlen2 = wcslen(wstr); if (wlen2 != wlen) { PyMem_Free(wstr); - PyErr_SetString(PyExc_TypeError, "embedded null character"); + PyErr_SetString(PyExc_ValueError, "embedded null character"); return NULL; } @@ -3269,7 +3374,7 @@ PyUnicode_EncodeLocale(PyObject *unicode, const char *errors) /* "surrogateescape" error handler */ char *str; - str = _Py_wchar2char(wstr, &error_pos); + str = Py_EncodeLocale(wstr, &error_pos); if (str == NULL) { if (error_pos == (size_t)-1) { PyErr_NoMemory(); @@ -3322,7 +3427,7 @@ PyUnicode_EncodeLocale(PyObject *unicode, const char *errors) if (errmsg != NULL) { size_t errlen; - wstr = _Py_char2wchar(errmsg, &errlen); + wstr = Py_DecodeLocale(errmsg, &errlen); if (wstr != NULL) { reason = PyUnicode_FromWideChar(wstr, errlen); PyMem_RawFree(wstr); @@ -3497,7 +3602,7 @@ mbstowcs_errorpos(const char *str, size_t len) memset(&mbs, 0, sizeof mbs); while (len) { - converted = mbrtowc(&ch, (char*)str, len, &mbs); + converted = mbrtowc(&ch, str, len, &mbs); if (converted == 0) /* Reached end of string */ break; @@ -3528,19 +3633,20 @@ PyUnicode_DecodeLocaleAndSize(const char *str, Py_ssize_t len, int surrogateescape; size_t error_pos; char *errmsg; - PyObject *reason, *exc; + PyObject *reason = NULL; /* initialize to prevent gcc warning */ + PyObject *exc; if (locale_error_handler(errors, &surrogateescape) < 0) return NULL; - if (str[len] != '\0' || len != strlen(str)) { - PyErr_SetString(PyExc_TypeError, "embedded null character"); + if (str[len] != '\0' || (size_t)len != strlen(str)) { + PyErr_SetString(PyExc_ValueError, "embedded null byte"); return NULL; } if (surrogateescape) { /* "surrogateescape" error handler */ - wstr = _Py_char2wchar(str, &wlen); + wstr = Py_DecodeLocale(str, &wlen); if (wstr == NULL) { if (wlen == (size_t)-1) PyErr_NoMemory(); @@ -3565,10 +3671,7 @@ PyUnicode_DecodeLocaleAndSize(const char *str, Py_ssize_t len, wstr = smallbuf; } else { - if (wlen > PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) - return PyErr_NoMemory(); - - wstr = PyMem_Malloc((wlen+1) * sizeof(wchar_t)); + wstr = PyMem_New(wchar_t, wlen+1); if (!wstr) return PyErr_NoMemory(); } @@ -3589,20 +3692,20 @@ PyUnicode_DecodeLocaleAndSize(const char *str, Py_ssize_t len, return unicode; decode_error: + reason = NULL; errmsg = strerror(errno); assert(errmsg != NULL); error_pos = mbstowcs_errorpos(str, len); if (errmsg != NULL) { size_t errlen; - wstr = _Py_char2wchar(errmsg, &errlen); + wstr = Py_DecodeLocale(errmsg, &errlen); if (wstr != NULL) { reason = PyUnicode_FromWideChar(wstr, errlen); PyMem_RawFree(wstr); - } else - errmsg = NULL; + } } - if (errmsg == NULL) + if (reason == NULL) reason = PyUnicode_FromString( "mbstowcs() encountered an invalid multibyte sequence"); if (reason == NULL) @@ -3665,21 +3768,6 @@ PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size) } -int -_PyUnicode_HasNULChars(PyObject* str) -{ - Py_ssize_t pos; - - if (PyUnicode_READY(str) == -1) - return -1; - pos = findchar(PyUnicode_DATA(str), PyUnicode_KIND(str), - PyUnicode_GET_LENGTH(str), '\0', 1); - if (pos == -1) - return 0; - else - return 1; -} - int PyUnicode_FSConverter(PyObject* arg, void* addr) { @@ -3710,8 +3798,8 @@ PyUnicode_FSConverter(PyObject* arg, void* addr) } size = PyBytes_GET_SIZE(output); data = PyBytes_AS_STRING(output); - if (size != strlen(data)) { - PyErr_SetString(PyExc_TypeError, "embedded NUL character"); + if ((size_t)size != strlen(data)) { + PyErr_SetString(PyExc_ValueError, "embedded null byte"); Py_DECREF(output); return 0; } @@ -3755,7 +3843,7 @@ PyUnicode_FSDecoder(PyObject* arg, void* addr) } if (findchar(PyUnicode_DATA(output), PyUnicode_KIND(output), PyUnicode_GET_LENGTH(output), 0, 1) >= 0) { - PyErr_SetString(PyExc_TypeError, "embedded NUL character"); + PyErr_SetString(PyExc_ValueError, "embedded null character"); Py_DECREF(output); return 0; } @@ -3873,6 +3961,11 @@ PyUnicode_AsUnicodeAndSize(PyObject *unicode, Py_ssize_t *size) #endif } else { + if ((size_t)_PyUnicode_LENGTH(unicode) > + PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) { + PyErr_NoMemory(); + return NULL; + } _PyUnicode_WSTR(unicode) = (wchar_t *) PyObject_MALLOC(sizeof(wchar_t) * (_PyUnicode_LENGTH(unicode) + 1)); if (!_PyUnicode_WSTR(unicode)) { @@ -4020,8 +4113,7 @@ make_decode_exception(PyObject **exceptionObject, return; onError: - Py_DECREF(*exceptionObject); - *exceptionObject = NULL; + Py_CLEAR(*exceptionObject); } #ifdef HAVE_MBCS @@ -4108,16 +4200,21 @@ unicode_decode_call_errorhandler_wchar( 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 + repwlen + insize-newpos; + 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; if (requiredsize > outsize) { - if (requiredsize < 2*outsize) + if (outsize <= PY_SSIZE_T_MAX/2 && requiredsize < 2*outsize) requiredsize = 2*outsize; if (unicode_resize(output, requiredsize) < 0) goto onError; } wcsncpy(_PyUnicode_WSTR(*output) + *outpos, repwstr, repwlen); *outpos += repwlen; - *endinpos = newpos; *inptr = *input + newpos; @@ -4125,6 +4222,10 @@ unicode_decode_call_errorhandler_wchar( Py_XDECREF(restuple); return 0; + overflow: + PyErr_SetString(PyExc_OverflowError, + "decoded result is too long for a Python string"); + onError: Py_XDECREF(restuple); return -1; @@ -4197,9 +4298,13 @@ unicode_decode_call_errorhandler_writer( if (PyUnicode_READY(repunicode) < 0) goto onError; replen = PyUnicode_GET_LENGTH(repunicode); - writer->min_length += replen; - if (replen > 1) + if (replen > 1) { + writer->min_length += replen - 1; writer->overallocate = 1; + if (_PyUnicodeWriter_Prepare(writer, writer->min_length, + PyUnicode_MAX_CHAR_VALUE(repunicode)) == -1) + goto onError; + } if (_PyUnicodeWriter_WriteStr(writer, repunicode) == -1) goto onError; @@ -4387,31 +4492,31 @@ PyUnicode_DecodeUTF7Stateful(const char *s, } else { /* now leaving a base-64 section */ inShift = 0; - s++; - if (surrogate) { - if (_PyUnicodeWriter_WriteCharInline(&writer, surrogate) < 0) - goto onError; - surrogate = 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 (ch != '-') { + if (surrogate && DECODE_DIRECT(ch)) { + if (_PyUnicodeWriter_WriteCharInline(&writer, surrogate) < 0) + goto onError; + } + surrogate = 0; + if (ch == '-') { /* '-' is absorbed; other terminating characters are preserved */ - if (_PyUnicodeWriter_WriteCharInline(&writer, ch) < 0) - goto onError; + s++; } } } @@ -4425,6 +4530,7 @@ PyUnicode_DecodeUTF7Stateful(const char *s, } else { /* begin base64-encoded section */ inShift = 1; + surrogate = 0; shiftOutStart = writer.pos; base64bits = 0; base64buffer = 0; @@ -4456,6 +4562,7 @@ PyUnicode_DecodeUTF7Stateful(const char *s, 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)) { @@ -4474,8 +4581,16 @@ PyUnicode_DecodeUTF7Stateful(const char *s, /* return state */ if (consumed) { if (inShift) { - writer.pos = shiftOutStart; /* back off output */ *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; @@ -4731,8 +4846,9 @@ PyUnicode_DecodeUTF8Stateful(const char *s, Py_ssize_t startinpos; Py_ssize_t endinpos; const char *errmsg = ""; - PyObject *errorHandler = NULL; + PyObject *error_handler_obj = NULL; PyObject *exc = NULL; + _Py_error_handler error_handler = _Py_ERROR_UNKNOWN; if (size == 0) { if (consumed) @@ -4757,6 +4873,7 @@ PyUnicode_DecodeUTF8Stateful(const char *s, 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); @@ -4795,24 +4912,56 @@ PyUnicode_DecodeUTF8Stateful(const char *s, continue; } - if (unicode_decode_call_errorhandler_writer( - errors, &errorHandler, - "utf-8", errmsg, - &starts, &end, &startinpos, &endinpos, &exc, &s, - &writer)) - goto onError; + if (error_handler == _Py_ERROR_UNKNOWN) + error_handler = get_error_handler(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= 0; #endif const char *encoding; + Py_ssize_t nsize, pos; PyObject *errorHandler = NULL; PyObject *exc = NULL; PyObject *rep = NULL; -#define STORECHAR(CH) \ - do { \ - p[iorder[3]] = ((CH) >> 24) & 0xff; \ - p[iorder[2]] = ((CH) >> 16) & 0xff; \ - p[iorder[1]] = ((CH) >> 8) & 0xff; \ - p[iorder[0]] = (CH) & 0xff; \ - p += 4; \ - } while(0) - if (!PyUnicode_Check(str)) { PyErr_BadArgument(); return NULL; @@ -5136,59 +5275,53 @@ _PyUnicode_EncodeUTF32(PyObject *str, data = PyUnicode_DATA(str); len = PyUnicode_GET_LENGTH(str); - nsize = len + (byteorder == 0); - if (nsize > PY_SSIZE_T_MAX / 4) + 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; - p = (unsigned char *)PyBytes_AS_STRING(v); + /* output buffer is 4-bytes aligned */ + assert(_Py_IS_ALIGNED(PyBytes_AS_STRING(v), 4)); + out = (PY_UINT32_T *)PyBytes_AS_STRING(v); if (byteorder == 0) - STORECHAR(0xFEFF); + *out++ = 0xFEFF; if (len == 0) - return v; + goto done; - if (byteorder == -1) { - /* force LE */ - iorder[0] = 0; - iorder[1] = 1; - iorder[2] = 2; - iorder[3] = 3; + if (byteorder == -1) encoding = "utf-32-le"; - } - else if (byteorder == 1) { - /* force BE */ - iorder[0] = 3; - iorder[1] = 2; - iorder[2] = 1; - iorder[3] = 0; + else if (byteorder == 1) encoding = "utf-32-be"; - } else encoding = "utf-32"; if (kind == PyUnicode_1BYTE_KIND) { - for (i = 0; i < len; i++) - STORECHAR(PyUnicode_READ(kind, data, i)); - return v; + ucs1lib_utf32_encode((const Py_UCS1 *)data, len, &out, native_ordering); + goto done; } - for (i = 0; i < len;) { + pos = 0; + while (pos < len) { Py_ssize_t repsize, moreunits; - Py_UCS4 ch = PyUnicode_READ(kind, data, i); - i++; - assert(ch <= MAX_UNICODE); - if (!Py_UNICODE_IS_SURROGATE(ch)) { - STORECHAR(ch); - continue; + + 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, i-1, i, &i); - + str, &exc, pos, pos + 1, &pos); if (!rep) goto error; @@ -5196,7 +5329,7 @@ _PyUnicode_EncodeUTF32(PyObject *str, repsize = PyBytes_GET_SIZE(rep); if (repsize & 3) { raise_encode_exception(&exc, encoding, - str, i - 1, i, + str, pos - 1, pos, "surrogates not allowed"); goto error; } @@ -5209,7 +5342,7 @@ _PyUnicode_EncodeUTF32(PyObject *str, moreunits = repsize = PyUnicode_GET_LENGTH(rep); if (!PyUnicode_IS_ASCII(rep)) { raise_encode_exception(&exc, encoding, - str, i - 1, i, + str, pos - 1, pos, "surrogates not allowed"); goto error; } @@ -5217,7 +5350,7 @@ _PyUnicode_EncodeUTF32(PyObject *str, /* four bytes are reserved for each surrogate */ if (moreunits > 1) { - Py_ssize_t outpos = p - (unsigned char*) PyBytes_AS_STRING(v); + Py_ssize_t outpos = out - (PY_UINT32_T*) PyBytes_AS_STRING(v); Py_ssize_t morebytes = 4 * (moreunits - 1); if (PyBytes_GET_SIZE(v) > PY_SSIZE_T_MAX - morebytes) { /* integer overflow */ @@ -5226,20 +5359,16 @@ _PyUnicode_EncodeUTF32(PyObject *str, } if (_PyBytes_Resize(&v, PyBytes_GET_SIZE(v) + morebytes) < 0) goto error; - p = (unsigned char*) PyBytes_AS_STRING(v) + outpos; + out = (PY_UINT32_T*) PyBytes_AS_STRING(v) + outpos; } if (PyBytes_Check(rep)) { - Py_MEMCPY(p, PyBytes_AS_STRING(rep), repsize); - p += repsize; + Py_MEMCPY(out, PyBytes_AS_STRING(rep), repsize); + out += moreunits; } else /* rep is unicode */ { - const Py_UCS1 *repdata; assert(PyUnicode_KIND(rep) == PyUnicode_1BYTE_KIND); - repdata = PyUnicode_1BYTE_DATA(rep); - while (repsize--) { - Py_UCS4 ch = *repdata++; - STORECHAR(ch); - } + ucs1lib_utf32_encode(PyUnicode_1BYTE_DATA(rep), repsize, + &out, native_ordering); } Py_CLEAR(rep); @@ -5248,11 +5377,12 @@ _PyUnicode_EncodeUTF32(PyObject *str, /* 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 = p - (unsigned char*) PyBytes_AS_STRING(v); + 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); @@ -5260,7 +5390,6 @@ _PyUnicode_EncodeUTF32(PyObject *str, Py_XDECREF(exc); Py_XDECREF(v); return NULL; -#undef STORECHAR } PyObject * @@ -5923,11 +6052,10 @@ PyObject * PyUnicode_AsUnicodeEscapeString(PyObject *unicode) { Py_ssize_t i, len; - PyObject *repr; char *p; int kind; void *data; - Py_ssize_t expandsize = 0; + _PyBytesWriter writer; /* Initial allocation is based on the longest-possible character escape. @@ -5943,35 +6071,28 @@ PyUnicode_AsUnicodeEscapeString(PyObject *unicode) } if (PyUnicode_READY(unicode) == -1) return NULL; + + _PyBytesWriter_Init(&writer); + len = PyUnicode_GET_LENGTH(unicode); kind = PyUnicode_KIND(unicode); data = PyUnicode_DATA(unicode); - switch (kind) { - case PyUnicode_1BYTE_KIND: expandsize = 4; break; - case PyUnicode_2BYTE_KIND: expandsize = 6; break; - case PyUnicode_4BYTE_KIND: expandsize = 10; break; - } - - if (len == 0) - return PyBytes_FromStringAndSize(NULL, 0); - if (len > (PY_SSIZE_T_MAX - 2 - 1) / expandsize) - return PyErr_NoMemory(); - - repr = PyBytes_FromStringAndSize(NULL, - 2 - + expandsize*len - + 1); - if (repr == NULL) - return NULL; - - p = PyBytes_AS_STRING(repr); + p = _PyBytesWriter_Alloc(&writer, len); + if (p == NULL) + goto error; + writer.overallocate = 1; for (i = 0; i < len; i++) { Py_UCS4 ch = PyUnicode_READ(kind, data, i); /* Escape backslashes */ if (ch == '\\') { + /* -1: substract 1 preallocated byte */ + p = _PyBytesWriter_Prepare(&writer, p, 2-1); + if (p == NULL) + goto error; + *p++ = '\\'; *p++ = (char) ch; continue; @@ -5980,6 +6101,11 @@ PyUnicode_AsUnicodeEscapeString(PyObject *unicode) /* Map 21-bit characters to '\U00xxxxxx' */ else if (ch >= 0x10000) { assert(ch <= MAX_UNICODE); + + p = _PyBytesWriter_Prepare(&writer, p, 10-1); + if (p == NULL) + goto error; + *p++ = '\\'; *p++ = 'U'; *p++ = Py_hexdigits[(ch >> 28) & 0x0000000F]; @@ -5995,6 +6121,10 @@ PyUnicode_AsUnicodeEscapeString(PyObject *unicode) /* Map 16-bit characters to '\uxxxx' */ if (ch >= 256) { + p = _PyBytesWriter_Prepare(&writer, p, 6-1); + if (p == NULL) + goto error; + *p++ = '\\'; *p++ = 'u'; *p++ = Py_hexdigits[(ch >> 12) & 0x000F]; @@ -6005,20 +6135,37 @@ PyUnicode_AsUnicodeEscapeString(PyObject *unicode) /* Map special whitespace to '\t', \n', '\r' */ else if (ch == '\t') { + p = _PyBytesWriter_Prepare(&writer, p, 2-1); + if (p == NULL) + goto error; + *p++ = '\\'; *p++ = 't'; } else if (ch == '\n') { + p = _PyBytesWriter_Prepare(&writer, p, 2-1); + if (p == NULL) + goto error; + *p++ = '\\'; *p++ = 'n'; } else if (ch == '\r') { + p = _PyBytesWriter_Prepare(&writer, p, 2-1); + if (p == NULL) + goto error; + *p++ = '\\'; *p++ = 'r'; } /* Map non-printable US ASCII to '\xhh' */ else if (ch < ' ' || ch >= 0x7F) { + /* -1: substract 1 preallocated byte */ + p = _PyBytesWriter_Prepare(&writer, p, 4-1); + if (p == NULL) + goto error; + *p++ = '\\'; *p++ = 'x'; *p++ = Py_hexdigits[(ch >> 4) & 0x000F]; @@ -6030,10 +6177,11 @@ PyUnicode_AsUnicodeEscapeString(PyObject *unicode) *p++ = (char) ch; } - assert(p - PyBytes_AS_STRING(repr) > 0); - if (_PyBytes_Resize(&repr, p - PyBytes_AS_STRING(repr)) < 0) - return NULL; - return repr; + return _PyBytesWriter_Finish(&writer, p); + +error: + _PyBytesWriter_Dealloc(&writer); + return NULL; } PyObject * @@ -6162,13 +6310,12 @@ PyUnicode_DecodeRawUnicodeEscape(const char *s, PyObject * PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) { - PyObject *repr; char *p; - char *q; - Py_ssize_t expandsize, pos; + Py_ssize_t pos; int kind; void *data; Py_ssize_t len; + _PyBytesWriter writer; if (!PyUnicode_Check(unicode)) { PyErr_BadArgument(); @@ -6176,28 +6323,29 @@ PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) } if (PyUnicode_READY(unicode) == -1) return NULL; + + _PyBytesWriter_Init(&writer); + kind = PyUnicode_KIND(unicode); data = PyUnicode_DATA(unicode); len = PyUnicode_GET_LENGTH(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; - if (len == 0) - return repr; + p = _PyBytesWriter_Alloc(&writer, len); + if (p == NULL) + goto error; + writer.overallocate = 1; - p = q = PyBytes_AS_STRING(repr); for (pos = 0; pos < len; pos++) { Py_UCS4 ch = PyUnicode_READ(kind, data, pos); /* Map 32-bit characters to '\Uxxxxxxxx' */ if (ch >= 0x10000) { assert(ch <= MAX_UNICODE); + + /* -1: substract 1 preallocated byte */ + p = _PyBytesWriter_Prepare(&writer, p, 10-1); + if (p == NULL) + goto error; + *p++ = '\\'; *p++ = 'U'; *p++ = Py_hexdigits[(ch >> 28) & 0xf]; @@ -6211,6 +6359,11 @@ PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) } /* Map 16-bit characters to '\uxxxx' */ else if (ch >= 256) { + /* -1: substract 1 preallocated byte */ + p = _PyBytesWriter_Prepare(&writer, p, 6-1); + if (p == NULL) + goto error; + *p++ = '\\'; *p++ = 'u'; *p++ = Py_hexdigits[(ch >> 12) & 0xf]; @@ -6223,10 +6376,11 @@ PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) *p++ = (char) ch; } - assert(p > q); - if (_PyBytes_Resize(&repr, p - q) < 0) - return NULL; - return repr; + return _PyBytesWriter_Finish(&writer, p); + +error: + _PyBytesWriter_Dealloc(&writer); + return NULL; } PyObject * @@ -6373,8 +6527,7 @@ make_encode_exception(PyObject **exceptionObject, goto onError; return; onError: - Py_DECREF(*exceptionObject); - *exceptionObject = NULL; + Py_CLEAR(*exceptionObject); } } @@ -6458,25 +6611,22 @@ unicode_encode_call_errorhandler(const char *errors, static PyObject * unicode_encode_ucs1(PyObject *unicode, const char *errors, - unsigned int limit) + const Py_UCS4 limit) { /* input state */ Py_ssize_t pos=0, size; int kind; void *data; - /* output object */ - PyObject *res; /* pointer into the output */ char *str; - /* current output position */ - Py_ssize_t ressize; const char *encoding = (limit == 256) ? "latin-1" : "ascii"; const char *reason = (limit == 256) ? "ordinal not in range(256)" : "ordinal not in range(128)"; - PyObject *errorHandler = NULL; + PyObject *error_handler_obj = NULL; PyObject *exc = NULL; - /* the following variable is used for caching string comparisons - * -1=not initialized, 0=unknown, 1=strict, 2=replace, 3=ignore, 4=xmlcharrefreplace */ - int known_errorHandler = -1; + _Py_error_handler error_handler = _Py_ERROR_UNKNOWN; + PyObject *rep = NULL; + /* output object */ + _PyBytesWriter writer; if (PyUnicode_READY(unicode) == -1) return NULL; @@ -6487,165 +6637,157 @@ unicode_encode_ucs1(PyObject *unicode, replacements, if we need more, we'll resize */ if (size == 0) return PyBytes_FromStringAndSize(NULL, 0); - res = PyBytes_FromStringAndSize(NULL, size); - if (res == NULL) + + _PyBytesWriter_Init(&writer); + str = _PyBytesWriter_Alloc(&writer, size); + if (str == NULL) return NULL; - str = PyBytes_AS_STRING(res); - ressize = size; while (pos < size) { - Py_UCS4 c = PyUnicode_READ(kind, data, pos); + Py_UCS4 ch = PyUnicode_READ(kind, data, pos); /* can we encode this? */ - if (c=limit)) + + 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 (known_errorHandler==-1) { - if ((errors==NULL) || (!strcmp(errors, "strict"))) - known_errorHandler = 1; - else if (!strcmp(errors, "replace")) - known_errorHandler = 2; - else if (!strcmp(errors, "ignore")) - known_errorHandler = 3; - else if (!strcmp(errors, "xmlcharrefreplace")) - known_errorHandler = 4; - else - known_errorHandler = 0; - } - switch (known_errorHandler) { - case 1: /* strict */ + if (error_handler == _Py_ERROR_UNKNOWN) + error_handler = get_error_handler(errors); + + switch (error_handler) { + case _Py_ERROR_STRICT: raise_encode_exception(&exc, encoding, unicode, collstart, collend, reason); goto onError; - case 2: /* replace */ - while (collstart++ ressize) { - if (requiredsize<2*ressize) - requiredsize = 2*ressize; - if (_PyBytes_Resize(&res, requiredsize)) - goto onError; - str = PyBytes_AS_STRING(res) + respos; - ressize = requiredsize; - } - /* generate replacement */ - for (i = collstart; i < collend; ++i) { - str += sprintf(str, "&#%d;", PyUnicode_READ(kind, data, i)); - } + + case _Py_ERROR_BACKSLASHREPLACE: + /* substract preallocated bytes */ + writer.min_size -= (collend - collstart); + str = backslashreplace(&writer, str, + unicode, collstart, collend); + if (str == NULL) + goto onError; pos = collend; break; - default: - repunicode = unicode_encode_call_errorhandler(errors, &errorHandler, - encoding, reason, unicode, &exc, - collstart, collend, &newpos); - if (repunicode == NULL || (PyUnicode_Check(repunicode) && - PyUnicode_READY(repunicode) == -1)) + + case _Py_ERROR_XMLCHARREFREPLACE: + /* substract preallocated bytes */ + writer.min_size -= (collend - collstart); + str = xmlcharrefreplace(&writer, str, + unicode, collstart, collend); + if (str == NULL) goto onError; - if (PyBytes_Check(repunicode)) { - /* Directly copy bytes result to output. */ - repsize = PyBytes_Size(repunicode); - if (repsize > 1) { - /* Make room for all additional bytes. */ - respos = str - PyBytes_AS_STRING(res); - if (_PyBytes_Resize(&res, ressize+repsize-1)) { - Py_DECREF(repunicode); - goto onError; - } - str = PyBytes_AS_STRING(res) + respos; - ressize += repsize-1; + 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; } - memcpy(str, PyBytes_AsString(repunicode), repsize); - str += repsize; - pos = newpos; - Py_DECREF(repunicode); - break; + *str++ = (char)(ch - 0xdc00); + ++pos; } - /* need more space? (at least enough for what we - have+the replacement+the rest of the string, so - we won't have to check space for encodable characters) */ - respos = str - PyBytes_AS_STRING(res); - repsize = PyUnicode_GET_LENGTH(repunicode); - requiredsize = respos+repsize+(size-collend); - if (requiredsize > ressize) { - if (requiredsize<2*ressize) - requiredsize = 2*ressize; - if (_PyBytes_Resize(&res, requiredsize)) { - Py_DECREF(repunicode); + if (i >= collend) + break; + collstart = pos; + assert(collstart != collend); + /* fallback to general error handling */ + + default: + rep = unicode_encode_call_errorhandler(errors, &error_handler_obj, + encoding, reason, unicode, &exc, + collstart, collend, &newpos); + if (rep == NULL) + goto onError; + + /* substract preallocated bytes */ + writer.min_size -= 1; + + if (PyBytes_Check(rep)) { + /* Directly copy bytes result to output. */ + str = _PyBytesWriter_WriteBytes(&writer, str, + PyBytes_AS_STRING(rep), + PyBytes_GET_SIZE(rep)); + if (str == NULL) goto onError; - } - str = PyBytes_AS_STRING(res) + respos; - ressize = requiredsize; } - /* check if there is anything unencodable in the replacement - and copy it to the output */ - for (i = 0; repsize-->0; ++i, ++str) { - c = PyUnicode_READ_CHAR(repunicode, i); - if (c >= limit) { - raise_encode_exception(&exc, encoding, unicode, - pos, pos+1, reason); - Py_DECREF(repunicode); + else { + assert(PyUnicode_Check(rep)); + + if (PyUnicode_READY(rep) < 0) goto onError; + + if (PyUnicode_IS_ASCII(rep)) { + /* Fast path: all characters are smaller than limit */ + assert(limit >= 128); + assert(PyUnicode_KIND(rep) == PyUnicode_1BYTE_KIND); + str = _PyBytesWriter_WriteBytes(&writer, str, + PyUnicode_DATA(rep), + PyUnicode_GET_LENGTH(rep)); + } + else { + Py_ssize_t repsize = PyUnicode_GET_LENGTH(rep); + + str = _PyBytesWriter_Prepare(&writer, str, repsize); + if (str == NULL) + goto onError; + + /* check if there is anything unencodable in the + replacement and copy it to the output */ + for (i = 0; repsize-->0; ++i, ++str) { + ch = PyUnicode_READ_CHAR(rep, i); + if (ch >= limit) { + raise_encode_exception(&exc, encoding, unicode, + pos, pos+1, reason); + goto onError; + } + *str = (char)ch; + } } - *str = (char)c; } pos = newpos; - Py_DECREF(repunicode); + Py_CLEAR(rep); } + + /* If overallocation was disabled, ensure that it was the last + write. Otherwise, we missed an optimization */ + assert(writer.overallocate || pos == size); } } - /* Resize if we allocated to much */ - size = str - PyBytes_AS_STRING(res); - if (size < ressize) { /* If this falls res will be NULL */ - assert(size >= 0); - if (_PyBytes_Resize(&res, size) < 0) - goto onError; - } - Py_XDECREF(errorHandler); + Py_XDECREF(error_handler_obj); Py_XDECREF(exc); - return res; + return _PyBytesWriter_Finish(&writer, str); onError: - Py_XDECREF(res); - Py_XDECREF(errorHandler); + Py_XDECREF(rep); + _PyBytesWriter_Dealloc(&writer); + Py_XDECREF(error_handler_obj); Py_XDECREF(exc); return NULL; } @@ -6705,8 +6847,9 @@ PyUnicode_DecodeASCII(const char *s, Py_ssize_t endinpos; Py_ssize_t outpos; const char *e; - PyObject *errorHandler = NULL; + PyObject *error_handler_obj = NULL; PyObject *exc = NULL; + _Py_error_handler error_handler = _Py_ERROR_UNKNOWN; if (size == 0) _Py_RETURN_UNICODE_EMPTY(); @@ -6735,12 +6878,42 @@ PyUnicode_DecodeASCII(const char *s, PyUnicode_WRITE(kind, data, writer.pos, c); writer.pos++; ++s; + continue; } - else { + + /* byte outsize range 0x00..0x7f: call the error handler */ + + if (error_handler == _Py_ERROR_UNKNOWN) + error_handler = get_error_handler(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, &errorHandler, + errors, &error_handler_obj, "ascii", "ordinal not in range(128)", &starts, &e, &startinpos, &endinpos, &exc, &s, &writer)) @@ -6749,13 +6922,13 @@ PyUnicode_DecodeASCII(const char *s, data = writer.data; } } - Py_XDECREF(errorHandler); + Py_XDECREF(error_handler_obj); Py_XDECREF(exc); return _PyUnicodeWriter_Finish(&writer); onError: _PyUnicodeWriter_Dealloc(&writer); - Py_XDECREF(errorHandler); + Py_XDECREF(error_handler_obj); Py_XDECREF(exc); return NULL; } @@ -6827,28 +7000,6 @@ code_page_name(UINT code_page, PyObject **obj) return PyBytes_AS_STRING(*obj); } -static int -is_dbcs_lead_byte(UINT code_page, const char *s, int offset) -{ - const char *curr = s + offset; - const char *prev; - - if (!IsDBCSLeadByteEx(code_page, *curr)) - return 0; - - prev = CharPrevExA(code_page, s, curr, 0); - if (prev == curr) - return 1; - /* FIXME: This code is limited to "true" double-byte encodings, - as it assumes an incomplete character consists of a single - byte. */ - if (curr - prev == 2) - return 1; - if (!IsDBCSLeadByteEx(code_page, *prev)) - return 1; - return 0; -} - static DWORD decode_code_page_flags(UINT code_page) { @@ -6923,7 +7074,7 @@ static int decode_code_page_errors(UINT code_page, PyObject **v, const char *in, const int size, - const char *errors) + const char *errors, int final) { const char *startin = in; const char *endin = in + size; @@ -6950,7 +7101,7 @@ decode_code_page_errors(UINT code_page, if (encoding == NULL) return -1; - if (errors == NULL || strcmp(errors, "strict") == 0) { + 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); @@ -7013,6 +7164,10 @@ decode_code_page_errors(UINT code_page, 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 - PyUnicode_AS_UNICODE(*v); @@ -7041,7 +7196,8 @@ decode_code_page_errors(UINT code_page, assert(outsize <= PyUnicode_WSTR_LENGTH(*v)); if (unicode_resize(v, outsize) < 0) goto error; - ret = size; + /* (in - startin) <= size and size is an int */ + ret = Py_SAFE_DOWNCAST(in - startin, Py_ssize_t, int); error: Py_XDECREF(encoding_obj); @@ -7082,24 +7238,19 @@ decode_code_page_stateful(int code_page, done = 1; } - /* Skip trailing lead-byte unless 'final' is set */ - if (!final && is_dbcs_lead_byte(code_page, s, chunk_size - 1)) - --chunk_size; - if (chunk_size == 0 && done) { if (v != NULL) break; _Py_RETURN_UNICODE_EMPTY(); } - converted = decode_code_page_strict(code_page, &v, s, chunk_size); if (converted == -2) converted = decode_code_page_errors(code_page, &v, s, chunk_size, - errors); - assert(converted != 0); + errors, final); + assert(converted != 0 || done); if (converted < 0) { Py_XDECREF(v); @@ -7147,13 +7298,7 @@ static DWORD encode_code_page_flags(UINT code_page, const char *errors) { if (code_page == CP_UTF8) { - if (winver.dwMajorVersion >= 6) - /* CP_UTF8 supports WC_ERR_INVALID_CHARS on Windows Vista - and later */ - return WC_ERR_INVALID_CHARS; - else - /* CP_UTF8 only supports flags=0 on Windows older than Vista */ - return 0; + return WC_ERR_INVALID_CHARS; } else if (code_page == CP_UTF7) { /* CP_UTF7 only supports flags=0 */ @@ -7463,6 +7608,11 @@ encode_code_page(int code_page, 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); @@ -7536,10 +7686,6 @@ PyUnicode_EncodeCodePage(int code_page, PyObject * PyUnicode_AsMBCSString(PyObject *unicode) { - if (!PyUnicode_Check(unicode)) { - PyErr_BadArgument(); - return NULL; - } return PyUnicode_EncodeCodePage(CP_ACP, unicode, NULL); } @@ -8148,7 +8294,7 @@ static int charmap_encoding_error( PyObject *unicode, Py_ssize_t *inpos, PyObject *mapping, PyObject **exceptionObject, - int *known_errorHandler, PyObject **errorHandler, const char *errors, + _Py_error_handler *error_handler, PyObject **error_handler_obj, const char *errors, PyObject **res, Py_ssize_t *respos) { PyObject *repunicode = NULL; /* initialize to prevent gcc warning */ @@ -8195,23 +8341,15 @@ charmap_encoding_error( } /* cache callback name lookup * (if not done yet, i.e. it's the first error) */ - if (*known_errorHandler==-1) { - if ((errors==NULL) || (!strcmp(errors, "strict"))) - *known_errorHandler = 1; - else if (!strcmp(errors, "replace")) - *known_errorHandler = 2; - else if (!strcmp(errors, "ignore")) - *known_errorHandler = 3; - else if (!strcmp(errors, "xmlcharrefreplace")) - *known_errorHandler = 4; - else - *known_errorHandler = 0; - } - switch (*known_errorHandler) { - case 1: /* strict */ + if (*error_handler == _Py_ERROR_UNKNOWN) + *error_handler = get_error_handler(errors); + + switch (*error_handler) { + case _Py_ERROR_STRICT: raise_encode_exception(exceptionObject, encoding, unicode, collstartpos, collendpos, reason); return -1; - case 2: /* replace */ + + case _Py_ERROR_REPLACE: for (collpos = collstartpos; collpos max) { - PyErr_Format(PyExc_TypeError, - "character mapping must be in range(0x%x)", max+1); + 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; } @@ -8529,100 +8665,187 @@ charmaptranslate_lookup(Py_UCS4 c, PyObject *mapping, PyObject **result) return -1; } } -/* ensure that *outobj is at least requiredsize characters long, - if not reallocate and adjust various state variables. - Return 0 on success, -1 on error */ + +/* 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_makespace(Py_UCS4 **outobj, Py_ssize_t *psize, - Py_ssize_t requiredsize) -{ - Py_ssize_t oldsize = *psize; - Py_UCS4 *new_outobj; - if (requiredsize > oldsize) { - /* exponentially overallocate to minimize reallocations */ - if (requiredsize < 2 * oldsize) - requiredsize = 2 * oldsize; - new_outobj = PyMem_Realloc(*outobj, requiredsize * sizeof(Py_UCS4)); - if (new_outobj == 0) +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; - *outobj = new_outobj; - *psize = requiredsize; + } + Py_DECREF(item); + return 1; } - return 0; + + 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; } -/* lookup the character, put the result in the output string and adjust - various state variables. Return a new reference to the object that - was put in the output buffer in *result, or Py_None, if the mapping was - undefined (in which case no character was written). - The called must decref result. - Return 0 on success, -1 on error. */ + static int -charmaptranslate_output(PyObject *input, Py_ssize_t ipos, - PyObject *mapping, Py_UCS4 **output, - Py_ssize_t *osize, Py_ssize_t *opos, - PyObject **res) +unicode_fast_translate_lookup(PyObject *mapping, Py_UCS1 ch, + Py_UCS1 *translate) { - Py_UCS4 curinp = PyUnicode_READ_CHAR(input, ipos); - if (charmaptranslate_lookup(curinp, mapping, res)) + PyObject *item = NULL; + int ret = 0; + + if (charmaptranslate_lookup(ch, mapping, &item)) { return -1; - if (*res==NULL) { + } + + if (item == Py_None) { + /* deletion */ + translate[ch] = 0xfe; + } + else if (item == NULL) { /* not found => default to 1:1 mapping */ - (*output)[(*opos)++] = curinp; + translate[ch] = ch; + return 1; } - else if (*res==Py_None) - ; - else if (PyLong_Check(*res)) { - /* no overflow check, because we know that the space is enough */ - (*output)[(*opos)++] = (Py_UCS4)PyLong_AS_LONG(*res); + 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(*res)) { - Py_ssize_t repsize; - if (PyUnicode_READY(*res) == -1) + else if (PyUnicode_Check(item)) { + Py_UCS4 replace; + + if (PyUnicode_READY(item) == -1) { + Py_DECREF(item); return -1; - repsize = PyUnicode_GET_LENGTH(*res); - if (repsize==1) { - /* no overflow check, because we know that the space is enough */ - (*output)[(*opos)++] = PyUnicode_READ_CHAR(*res, 0); } - else if (repsize!=0) { - /* more than one character */ - Py_ssize_t requiredsize = *opos + - (PyUnicode_GET_LENGTH(input) - ipos) + - repsize - 1; - Py_ssize_t i; - if (charmaptranslate_makespace(output, osize, requiredsize)) + 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_UCS1 ascii_table[128], ch, ch2; + Py_ssize_t len; + Py_UCS1 *in, *end, *out; + int res = 0; + + if (PyUnicode_READY(input) == -1) + return -1; + if (!PyUnicode_IS_ASCII(input)) + return 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; - for(i = 0; i < repsize; i++) - (*output)[(*opos)++] = PyUnicode_READ_CHAR(*res, i); + if (translate == 0) + goto exit; + ch2 = ascii_table[ch]; + } + if (ch2 == 0xfe) { + if (ignore) + continue; + goto exit; } + assert(ch2 < 128); + *out = ch2; + out++; } - else - return -1; - return 0; + res = 1; + +exit: + writer->pos = out - PyUnicode_1BYTE_DATA(writer->buffer); + return res; } -PyObject * +static PyObject * _PyUnicode_TranslateCharmap(PyObject *input, PyObject *mapping, const char *errors) { /* input object */ - char *idata; + char *data; Py_ssize_t size, i; int kind; /* output buffer */ - Py_UCS4 *output = NULL; - Py_ssize_t osize; - PyObject *res; - /* current output position */ - Py_ssize_t opos; + _PyUnicodeWriter writer; + /* error handler */ char *reason = "character maps to "; PyObject *errorHandler = NULL; PyObject *exc = NULL; - /* the following variable is used for caching string comparisons - * -1=not initialized, 0=unknown, 1=strict, 2=replace, - * 3=ignore, 4=xmlcharrefreplace */ - int known_errorHandler = -1; + int ignore; + int res; if (mapping == NULL) { PyErr_BadArgument(); @@ -8631,10 +8854,9 @@ _PyUnicode_TranslateCharmap(PyObject *input, if (PyUnicode_READY(input) == -1) return NULL; - idata = (char*)PyUnicode_DATA(input); + data = (char*)PyUnicode_DATA(input); kind = PyUnicode_KIND(input); size = PyUnicode_GET_LENGTH(input); - i = 0; if (size == 0) { Py_INCREF(input); @@ -8643,121 +8865,81 @@ _PyUnicode_TranslateCharmap(PyObject *input, /* allocate enough for a simple 1:1 translation without replacements, if we need more, we'll resize */ - osize = size; - output = PyMem_Malloc(osize * sizeof(Py_UCS4)); - opos = 0; - if (output == NULL) { - PyErr_NoMemory(); + _PyUnicodeWriter_Init(&writer); + if (_PyUnicodeWriter_Prepare(&writer, size, 127) == -1) goto onError; + + ignore = (errors != NULL && strcmp(errors, "ignore") == 0); + + res = unicode_fast_translate(input, mapping, &writer, ignore); + if (res < 0) { + _PyUnicodeWriter_Dealloc(&writer); + return NULL; } + if (res == 1) + return _PyUnicodeWriter_Finish(&writer); + i = writer.pos; while (i adjust input pointer */ + + if (translate != 0) { + /* it worked => adjust input pointer */ ++i; - else { /* untranslatable character */ - PyObject *repunicode = NULL; /* initialize to prevent gcc warning */ - Py_ssize_t repsize; - Py_ssize_t newpos; - Py_ssize_t uni2; - /* startpos for collecting untranslatable chars */ - Py_ssize_t collstart = i; - Py_ssize_t collend = i+1; - Py_ssize_t coll; - - /* find all untranslatable characters */ - while (collend < size) { - if (charmaptranslate_lookup(PyUnicode_READ(kind,idata, collend), mapping, &x)) - goto onError; - Py_XDECREF(x); - if (x!=Py_None) - break; - ++collend; - } - /* cache callback name lookup - * (if not done yet, i.e. it's the first error) */ - if (known_errorHandler==-1) { - if ((errors==NULL) || (!strcmp(errors, "strict"))) - known_errorHandler = 1; - else if (!strcmp(errors, "replace")) - known_errorHandler = 2; - else if (!strcmp(errors, "ignore")) - known_errorHandler = 3; - else if (!strcmp(errors, "xmlcharrefreplace")) - known_errorHandler = 4; - else - known_errorHandler = 0; - } - switch (known_errorHandler) { - case 1: /* strict */ - make_translate_exception(&exc, - input, collstart, collend, reason); - if (exc != NULL) - PyCodec_StrictErrors(exc); + 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; - case 2: /* replace */ - /* No need to check for space, this is a 1:1 replacement */ - for (coll = collstart; coll0; ++uni2) - output[opos++] = PyUnicode_READ_CHAR(repunicode, uni2); - i = newpos; + ++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; } } - res = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, output, opos); - if (!res) - goto onError; - PyMem_Free(output); Py_XDECREF(exc); Py_XDECREF(errorHandler); - return res; + return _PyUnicodeWriter_Finish(&writer); onError: - PyMem_Free(output); + _PyUnicodeWriter_Dealloc(&writer); Py_XDECREF(exc); Py_XDECREF(errorHandler); return NULL; @@ -8859,7 +9041,7 @@ PyUnicode_TransformDecimalToASCII(Py_UNICODE *s, maxchar = 127; for (i = 0; i < length; i++) { - Py_UNICODE ch = s[i]; + Py_UCS4 ch = s[i]; if (ch > 127) { int decimal = Py_UNICODE_TODECIMAL(ch); if (decimal >= 0) @@ -8876,7 +9058,7 @@ PyUnicode_TransformDecimalToASCII(Py_UNICODE *s, data = PyUnicode_DATA(decimal); /* Iterate over code points */ for (i = 0; i < length; i++) { - Py_UNICODE ch = s[i]; + Py_UCS4 ch = s[i]; if (ch > 127) { int decimal = Py_UNICODE_TODECIMAL(ch); if (decimal >= 0) @@ -8957,35 +9139,61 @@ PyUnicode_EncodeDecimal(Py_UNICODE *s, /* --- 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(int direction, PyObject* s1, PyObject* s2, Py_ssize_t start, Py_ssize_t end) { - int kind1, kind2, kind; + int kind1, kind2; void *buf1, *buf2; Py_ssize_t len1, len2, result; kind1 = PyUnicode_KIND(s1); kind2 = PyUnicode_KIND(s2); - kind = kind1 > kind2 ? kind1 : kind2; + 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 (kind1 != kind) - buf1 = _PyUnicode_AsKind(s1, kind); - if (!buf1) - return -2; - if (kind2 != kind) - buf2 = _PyUnicode_AsKind(s2, kind); - if (!buf2) { - if (kind1 != kind) PyMem_Free(buf1); - return -2; + 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; } - len1 = PyUnicode_GET_LENGTH(s1); - len2 = PyUnicode_GET_LENGTH(s2); if (direction > 0) { - switch (kind) { + 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); @@ -9003,7 +9211,7 @@ any_find_slice(int direction, PyObject* s1, PyObject* s2, } } else { - switch (kind) { + 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); @@ -9021,9 +9229,7 @@ any_find_slice(int direction, PyObject* s1, PyObject* s2, } } - if (kind1 != kind) - PyMem_Free(buf1); - if (kind2 != kind) + if (kind2 != kind1) PyMem_Free(buf2); return result; @@ -9113,21 +9319,6 @@ _PyUnicode_InsertThousandsGrouping( } -/* 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_ssize_t PyUnicode_Count(PyObject *str, PyObject *substr, @@ -9137,7 +9328,7 @@ PyUnicode_Count(PyObject *str, Py_ssize_t result; PyObject* str_obj; PyObject* sub_obj; - int kind1, kind2, kind; + int kind1, kind2; void *buf1 = NULL, *buf2 = NULL; Py_ssize_t len1, len2; @@ -9152,29 +9343,35 @@ PyUnicode_Count(PyObject *str, if (PyUnicode_READY(sub_obj) == -1 || PyUnicode_READY(str_obj) == -1) { Py_DECREF(sub_obj); Py_DECREF(str_obj); - return -1; + return -1; + } + + kind1 = PyUnicode_KIND(str_obj); + kind2 = PyUnicode_KIND(sub_obj); + if (kind1 < kind2) { + Py_DECREF(sub_obj); + Py_DECREF(str_obj); + return 0; + } + + len1 = PyUnicode_GET_LENGTH(str_obj); + len2 = PyUnicode_GET_LENGTH(sub_obj); + ADJUST_INDICES(start, end, len1); + if (end - start < len2) { + Py_DECREF(sub_obj); + Py_DECREF(str_obj); + return 0; } - kind1 = PyUnicode_KIND(str_obj); - kind2 = PyUnicode_KIND(sub_obj); - kind = kind1; buf1 = PyUnicode_DATA(str_obj); buf2 = PyUnicode_DATA(sub_obj); - if (kind2 != kind) { - if (kind2 > kind) { - Py_DECREF(sub_obj); - Py_DECREF(str_obj); - return 0; - } - buf2 = _PyUnicode_AsKind(sub_obj, kind); + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(sub_obj, kind1); + if (!buf2) + goto onError; } - if (!buf2) - goto onError; - len1 = PyUnicode_GET_LENGTH(str_obj); - len2 = PyUnicode_GET_LENGTH(sub_obj); - ADJUST_INDICES(start, end, len1); - switch (kind) { + switch (kind1) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(str_obj) && PyUnicode_IS_ASCII(sub_obj)) result = asciilib_count( @@ -9206,14 +9403,14 @@ PyUnicode_Count(PyObject *str, Py_DECREF(sub_obj); Py_DECREF(str_obj); - if (kind2 != kind) + if (kind2 != kind1) PyMem_Free(buf2); return result; onError: Py_DECREF(sub_obj); Py_DECREF(str_obj); - if (kind2 != kind && buf2) + if (kind2 != kind1 && buf2) PyMem_Free(buf2); return -1; } @@ -9266,6 +9463,8 @@ PyUnicode_FindChar(PyObject *str, Py_UCS4 ch, } if (end > PyUnicode_GET_LENGTH(str)) end = PyUnicode_GET_LENGTH(str); + if (start >= end) + return -1; kind = PyUnicode_KIND(str); result = findchar(PyUnicode_1BYTE_DATA(str) + kind*start, kind, end-start, ch, direction); @@ -9294,14 +9493,14 @@ tailmatch(PyObject *self, PyUnicode_READY(substring) == -1) return -1; - if (PyUnicode_GET_LENGTH(substring) == 0) - 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); @@ -9453,7 +9652,7 @@ 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; + 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}) @@ -9630,6 +9829,10 @@ case_operation(PyObject *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(); @@ -9677,7 +9880,7 @@ PyUnicode_Join(PyObject *separator, PyObject *seq) PyObject *last_obj; unsigned int kind = 0; - fseq = PySequence_Fast(seq, ""); + fseq = PySequence_Fast(seq, "can only join an iterable"); if (fseq == NULL) { return NULL; } @@ -9866,8 +10069,8 @@ PyUnicode_Join(PyObject *separator, PyObject *seq) Py_UCS4 * to_ = (Py_UCS4 *)((data)) + (start); \ for (; i_ < (length); ++i_, ++to_) *to_ = (value); \ break; \ - default: assert(0); \ } \ + default: assert(0); \ } \ } while (0) @@ -10008,7 +10211,7 @@ split(PyObject *self, PyObject *substring, Py_ssize_t maxcount) { - int kind1, kind2, kind; + int kind1, kind2; void *buf1, *buf2; Py_ssize_t len1, len2; PyObject* out; @@ -10052,23 +10255,25 @@ split(PyObject *self, kind1 = PyUnicode_KIND(self); kind2 = PyUnicode_KIND(substring); - kind = kind1 > kind2 ? kind1 : kind2; + 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 (kind1 != kind) - buf1 = _PyUnicode_AsKind(self, kind); - if (!buf1) - return NULL; - if (kind2 != kind) - buf2 = _PyUnicode_AsKind(substring, kind); - if (!buf2) { - if (kind1 != kind) PyMem_Free(buf1); - return NULL; + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(substring, kind1); + if (!buf2) + return NULL; } - len1 = PyUnicode_GET_LENGTH(self); - len2 = PyUnicode_GET_LENGTH(substring); - switch (kind) { + switch (kind1) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(self) && PyUnicode_IS_ASCII(substring)) out = asciilib_split( @@ -10088,9 +10293,7 @@ split(PyObject *self, default: out = NULL; } - if (kind1 != kind) - PyMem_Free(buf1); - if (kind2 != kind) + if (kind2 != kind1) PyMem_Free(buf2); return out; } @@ -10100,7 +10303,7 @@ rsplit(PyObject *self, PyObject *substring, Py_ssize_t maxcount) { - int kind1, kind2, kind; + int kind1, kind2; void *buf1, *buf2; Py_ssize_t len1, len2; PyObject* out; @@ -10144,23 +10347,25 @@ rsplit(PyObject *self, kind1 = PyUnicode_KIND(self); kind2 = PyUnicode_KIND(substring); - kind = kind1 > kind2 ? kind1 : kind2; + 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 (kind1 != kind) - buf1 = _PyUnicode_AsKind(self, kind); - if (!buf1) - return NULL; - if (kind2 != kind) - buf2 = _PyUnicode_AsKind(substring, kind); - if (!buf2) { - if (kind1 != kind) PyMem_Free(buf1); - return NULL; + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(substring, kind1); + if (!buf2) + return NULL; } - len1 = PyUnicode_GET_LENGTH(self); - len2 = PyUnicode_GET_LENGTH(substring); - switch (kind) { + switch (kind1) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(self) && PyUnicode_IS_ASCII(substring)) out = asciilib_rsplit( @@ -10180,9 +10385,7 @@ rsplit(PyObject *self, default: out = NULL; } - if (kind1 != kind) - PyMem_Free(buf1); - if (kind2 != kind) + if (kind2 != kind1) PyMem_Free(buf2); return out; } @@ -10401,7 +10604,7 @@ replace(PyObject *self, PyObject *str1, } /* new_size = PyUnicode_GET_LENGTH(self) + n * (PyUnicode_GET_LENGTH(str2) - PyUnicode_GET_LENGTH(str1))); */ - if (len2 > len1 && len2 - len1 > (PY_SSIZE_T_MAX - slen) / n) { + if (len1 < len2 && len2 - len1 > (PY_SSIZE_T_MAX - slen) / n) { PyErr_SetString(PyExc_OverflowError, "replace string is too long"); goto error; @@ -10810,7 +11013,7 @@ PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str) } if (len1 > len2) return 1; /* uni is longer */ - if (len2 > len1) + if (len1 < len2) return -1; /* str is longer */ return 0; } @@ -10818,7 +11021,7 @@ PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str) 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 != str[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. */ @@ -10896,6 +11099,12 @@ PyUnicode_RichCompare(PyObject *left, PyObject *right, int op) return v; } +int +_PyUnicode_EQ(PyObject *aa, PyObject *bb) +{ + return unicode_eq(aa, bb); +} + int PyUnicode_Contains(PyObject *container, PyObject *element) { @@ -10922,23 +11131,35 @@ PyUnicode_Contains(PyObject *container, PyObject *element) kind1 = PyUnicode_KIND(str); kind2 = PyUnicode_KIND(sub); + if (kind1 < kind2) { + Py_DECREF(sub); + Py_DECREF(str); + return 0; + } + len1 = PyUnicode_GET_LENGTH(str); + len2 = PyUnicode_GET_LENGTH(sub); + if (len1 < len2) { + Py_DECREF(sub); + Py_DECREF(str); + return 0; + } buf1 = PyUnicode_DATA(str); buf2 = PyUnicode_DATA(sub); + if (len2 == 1) { + Py_UCS4 ch = PyUnicode_READ(kind2, buf2, 0); + result = findchar((const char *)buf1, kind1, len1, ch, 1) != -1; + Py_DECREF(sub); + Py_DECREF(str); + return result; + } if (kind2 != kind1) { - if (kind2 > kind1) { + buf2 = _PyUnicode_AsKind(sub, kind1); + if (!buf2) { Py_DECREF(sub); Py_DECREF(str); - return 0; + return -1; } - buf2 = _PyUnicode_AsKind(sub, kind1); - } - if (!buf2) { - Py_DECREF(sub); - Py_DECREF(str); - return -1; } - len1 = PyUnicode_GET_LENGTH(str); - len2 = PyUnicode_GET_LENGTH(sub); switch (kind1) { case PyUnicode_1BYTE_KIND: @@ -11119,11 +11340,11 @@ interpreted as in slice notation."); static PyObject * unicode_count(PyObject *self, PyObject *args) { - PyObject *substring; + 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, kind; + int kind1, kind2; void *buf1, *buf2; Py_ssize_t len1, len2, iresult; @@ -11133,24 +11354,27 @@ unicode_count(PyObject *self, PyObject *args) kind1 = PyUnicode_KIND(self); kind2 = PyUnicode_KIND(substring); - if (kind2 > kind1) { + if (kind1 < kind2) { Py_DECREF(substring); return PyLong_FromLong(0); } - kind = kind1; - buf1 = PyUnicode_DATA(self); - buf2 = PyUnicode_DATA(substring); - if (kind2 != kind) - buf2 = _PyUnicode_AsKind(substring, kind); - if (!buf2) { - Py_DECREF(substring); - return NULL; - } len1 = PyUnicode_GET_LENGTH(self); len2 = PyUnicode_GET_LENGTH(substring); - ADJUST_INDICES(start, end, len1); - switch (kind) { + if (end - start < len2) { + Py_DECREF(substring); + return PyLong_FromLong(0); + } + buf1 = PyUnicode_DATA(self); + buf2 = PyUnicode_DATA(substring); + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(substring, kind1); + if (!buf2) { + Py_DECREF(substring); + return NULL; + } + } + switch (kind1) { case PyUnicode_1BYTE_KIND: iresult = ucs1lib_count( ((Py_UCS1*)buf1) + start, end - start, @@ -11175,7 +11399,7 @@ unicode_count(PyObject *self, PyObject *args) result = PyLong_FromSsize_t(iresult); - if (kind2 != kind) + if (kind2 != kind1) PyMem_Free(buf2); Py_DECREF(substring); @@ -11307,9 +11531,10 @@ Return -1 on failure."); static PyObject * unicode_find(PyObject *self, PyObject *args) { - PyObject *substring; - Py_ssize_t start; - Py_ssize_t end; + /* initialize variables to prevent gcc warning */ + PyObject *substring = NULL; + Py_ssize_t start = 0; + Py_ssize_t end = 0; Py_ssize_t result; if (!stringlib_parse_args_finds_unicode("find", args, &substring, @@ -11341,7 +11566,6 @@ unicode_getitem(PyObject *self, Py_ssize_t index) void *data; enum PyUnicode_Kind kind; Py_UCS4 ch; - PyObject *res; if (!PyUnicode_Check(self) || PyUnicode_READY(self) == -1) { PyErr_BadArgument(); @@ -11354,17 +11578,7 @@ unicode_getitem(PyObject *self, Py_ssize_t index) kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); ch = PyUnicode_READ(kind, data, index); - if (ch < 256) - return get_latin1_char(ch); - - res = PyUnicode_New(1, ch); - if (res == NULL) - return NULL; - kind = PyUnicode_KIND(res); - data = PyUnicode_DATA(res); - PyUnicode_WRITE(kind, data, 0, ch); - assert(_PyUnicode_CheckConsistency(res, 1)); - return res; + return unicode_char(ch); } /* Believe it or not, this produces the same value for ASCII strings @@ -11396,7 +11610,6 @@ unicode_hash(PyObject *self) _PyUnicode_HASH(self) = x; return x; } -#undef HASH PyDoc_STRVAR(index__doc__, "S.index(sub[, start[, end]]) -> int\n\ @@ -11406,10 +11619,11 @@ Like S.find() but raise 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; - Py_ssize_t start; - Py_ssize_t end; + PyObject *substring = NULL; + Py_ssize_t start = 0; + Py_ssize_t end = 0; if (!stringlib_parse_args_finds_unicode("index", args, &substring, &start, &end)) @@ -12332,28 +12546,34 @@ unicode_repr(PyObject *unicode) 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++; osize++; break; - case '"': dquote++; osize++; break; + case '\'': squote++; break; + case '"': dquote++; break; case '\\': case '\t': case '\r': case '\n': - osize += 2; break; + incr = 2; + break; default: /* Fast-path ASCII */ if (ch < ' ' || ch == 0x7f) - osize += 4; /* \xHH */ + incr = 4; /* \xHH */ else if (ch < 0x7f) - osize++; - else if (Py_UNICODE_ISPRINTABLE(ch)) { - osize++; + ; + else if (Py_UNICODE_ISPRINTABLE(ch)) max = ch > max ? ch : max; - } else if (ch < 0x100) - osize += 4; /* \xHH */ + incr = 4; /* \xHH */ else if (ch < 0x10000) - osize += 6; /* \uHHHH */ + incr = 6; /* \uHHHH */ else - osize += 10; /* \uHHHHHHHH */ + 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 = '\''; @@ -12478,9 +12698,10 @@ Return -1 on failure."); static PyObject * unicode_rfind(PyObject *self, PyObject *args) { - PyObject *substring; - Py_ssize_t start; - Py_ssize_t end; + /* initialize variables to prevent gcc warning */ + PyObject *substring = NULL; + Py_ssize_t start = 0; + Py_ssize_t end = 0; Py_ssize_t result; if (!stringlib_parse_args_finds_unicode("rfind", args, &substring, @@ -12514,9 +12735,10 @@ Like S.rfind() but raise ValueError when the substring is not found."); static PyObject * unicode_rindex(PyObject *self, PyObject *args) { - PyObject *substring; - Py_ssize_t start; - Py_ssize_t end; + /* initialize variables to prevent gcc warning */ + PyObject *substring = NULL; + Py_ssize_t start = 0; + Py_ssize_t end = 0; Py_ssize_t result; if (!stringlib_parse_args_finds_unicode("rindex", args, &substring, @@ -12628,8 +12850,8 @@ PyUnicode_Partition(PyObject *str_in, PyObject *sep_in) PyObject* str_obj; PyObject* sep_obj; PyObject* out; - int kind1, kind2, kind; - void *buf1 = NULL, *buf2 = NULL; + int kind1, kind2; + void *buf1, *buf2; Py_ssize_t len1, len2; str_obj = PyUnicode_FromObject(str_in); @@ -12648,21 +12870,29 @@ PyUnicode_Partition(PyObject *str_in, PyObject *sep_in) kind1 = PyUnicode_KIND(str_obj); kind2 = PyUnicode_KIND(sep_obj); - kind = Py_MAX(kind1, kind2); - buf1 = PyUnicode_DATA(str_obj); - if (kind1 != kind) - buf1 = _PyUnicode_AsKind(str_obj, kind); - if (!buf1) - goto onError; - buf2 = PyUnicode_DATA(sep_obj); - if (kind2 != kind) - buf2 = _PyUnicode_AsKind(sep_obj, kind); - if (!buf2) - goto onError; 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); + } + Py_DECREF(sep_obj); + Py_DECREF(str_obj); + return out; + } + buf1 = PyUnicode_DATA(str_obj); + buf2 = PyUnicode_DATA(sep_obj); + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(sep_obj, kind1); + if (!buf2) + goto onError; + } - switch (PyUnicode_KIND(str_obj)) { + 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); @@ -12682,18 +12912,14 @@ PyUnicode_Partition(PyObject *str_in, PyObject *sep_in) Py_DECREF(sep_obj); Py_DECREF(str_obj); - if (kind1 != kind) - PyMem_Free(buf1); - if (kind2 != kind) + if (kind2 != kind1) PyMem_Free(buf2); return out; onError: Py_DECREF(sep_obj); Py_DECREF(str_obj); - if (kind1 != kind && buf1) - PyMem_Free(buf1); - if (kind2 != kind && buf2) + if (kind2 != kind1 && buf2) PyMem_Free(buf2); return NULL; } @@ -12705,8 +12931,8 @@ PyUnicode_RPartition(PyObject *str_in, PyObject *sep_in) PyObject* str_obj; PyObject* sep_obj; PyObject* out; - int kind1, kind2, kind; - void *buf1 = NULL, *buf2 = NULL; + int kind1, kind2; + void *buf1, *buf2; Py_ssize_t len1, len2; str_obj = PyUnicode_FromObject(str_in); @@ -12718,23 +12944,31 @@ PyUnicode_RPartition(PyObject *str_in, PyObject *sep_in) return NULL; } - kind1 = PyUnicode_KIND(str_in); + kind1 = PyUnicode_KIND(str_obj); kind2 = PyUnicode_KIND(sep_obj); - kind = Py_MAX(kind1, kind2); - buf1 = PyUnicode_DATA(str_in); - if (kind1 != kind) - buf1 = _PyUnicode_AsKind(str_in, kind); - if (!buf1) - goto onError; - buf2 = PyUnicode_DATA(sep_obj); - if (kind2 != kind) - buf2 = _PyUnicode_AsKind(sep_obj, kind); - if (!buf2) - goto onError; 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); + } + Py_DECREF(sep_obj); + Py_DECREF(str_obj); + return out; + } + buf1 = PyUnicode_DATA(str_obj); + buf2 = PyUnicode_DATA(sep_obj); + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(sep_obj, kind1); + if (!buf2) + goto onError; + } - switch (PyUnicode_KIND(str_in)) { + 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); @@ -12754,18 +12988,14 @@ PyUnicode_RPartition(PyObject *str_in, PyObject *sep_in) Py_DECREF(sep_obj); Py_DECREF(str_obj); - if (kind1 != kind) - PyMem_Free(buf1); - if (kind2 != kind) + if (kind2 != kind1) PyMem_Free(buf2); return out; onError: Py_DECREF(sep_obj); Py_DECREF(str_obj); - if (kind1 != kind && buf1) - PyMem_Free(buf1); - if (kind2 != kind && buf2) + if (kind2 != kind1 && buf2) PyMem_Free(buf2); return NULL; } @@ -12887,7 +13117,7 @@ unicode_swapcase(PyObject *self) return case_operation(self, do_swapcase); } -/*[clinic] +/*[clinic input] @staticmethod str.maketrans as unicode_maketrans @@ -12909,47 +13139,11 @@ 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]*/ - -PyDoc_STRVAR(unicode_maketrans__doc__, -"maketrans(x, y=None, z=None)\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)unicode_maketrans, METH_VARARGS|METH_STATIC, unicode_maketrans__doc__}, - -static PyObject * -unicode_maketrans_impl(void *null, PyObject *x, PyObject *y, PyObject *z); - -static PyObject * -unicode_maketrans(void *null, PyObject *args) -{ - PyObject *return_value = NULL; - PyObject *x; - PyObject *y = NULL; - PyObject *z = NULL; - - if (!PyArg_ParseTuple(args, - "O|UU:maketrans", - &x, &y, &z)) - goto exit; - return_value = unicode_maketrans_impl(null, x, y, z); - -exit: - return return_value; -} +[clinic start generated code]*/ static PyObject * -unicode_maketrans_impl(void *null, PyObject *x, PyObject *y, PyObject *z) -/*[clinic checksum: 7f76f414a0dfd0c614e0d4717872eeb520516da7]*/ +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; @@ -13056,11 +13250,12 @@ unicode_maketrans_impl(void *null, PyObject *x, PyObject *y, PyObject *z) PyDoc_STRVAR(translate__doc__, "S.translate(table) -> str\n\ \n\ -Return a copy of the string S, where all characters have been mapped\n\ -through the given translation table, which must be a mapping of\n\ -Unicode ordinals to Unicode ordinals, strings, or None.\n\ -Unmapped characters are left untouched. Characters mapped to None\n\ -are deleted."); +Return a copy of the string S in which each character has been mapped\n\ +through the given translation table. The table must implement\n\ +lookup/indexing via __getitem__, for instance a dictionary or list,\n\ +mapping Unicode ordinals to Unicode ordinals, strings, or None. If\n\ +this operation raises LookupError, the character is left untouched.\n\ +Characters mapped to None are deleted."); static PyObject* unicode_translate(PyObject *self, PyObject *table) @@ -13243,44 +13438,50 @@ unicode_endswith(PyObject *self, Py_LOCAL_INLINE(void) _PyUnicodeWriter_Update(_PyUnicodeWriter *writer) { - if (!writer->readonly) + 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; } - writer->maxchar = PyUnicode_MAX_CHAR_VALUE(writer->buffer); - writer->data = PyUnicode_DATA(writer->buffer); - writer->kind = PyUnicode_KIND(writer->buffer); } void _PyUnicodeWriter_Init(_PyUnicodeWriter *writer) { memset(writer, 0, sizeof(*writer)); -#ifdef Py_DEBUG - writer->kind = 5; /* invalid kind */ -#endif + + /* 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) { -#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 Py_ssize_t newlen; PyObject *newbuffer; - assert(length > 0); + /* 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(); @@ -13315,6 +13516,7 @@ _PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer, if (maxchar > writer->maxchar || writer->readonly) { /* resize + widen */ + maxchar = Py_MAX(maxchar, writer->maxchar); newbuffer = PyUnicode_New(newlen, maxchar); if (newbuffer == NULL) return -1; @@ -13346,6 +13548,28 @@ _PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer, #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 = 0x10ffff; break; + default: + assert(0 && "invalid kind"); + return -1; + } + + return _PyUnicodeWriter_PrepareInternal(writer, 0, maxchar); +} + Py_LOCAL_INLINE(int) _PyUnicodeWriter_WriteCharInline(_PyUnicodeWriter *writer, Py_UCS4 ch) { @@ -13376,6 +13600,7 @@ _PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer, PyObject *str) 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; @@ -13515,18 +13740,26 @@ _PyUnicodeWriter_Finish(_PyUnicodeWriter *writer) assert(PyUnicode_GET_LENGTH(str) == writer->pos); return str; } - if (PyUnicode_GET_LENGTH(writer->buffer) != writer->pos) { - PyObject *newbuffer; - newbuffer = resize_compact(writer->buffer, writer->pos); - if (newbuffer == NULL) { - Py_DECREF(writer->buffer); - writer->buffer = NULL; - return NULL; + if (writer->pos == 0) { + Py_CLEAR(writer->buffer); + + /* Get the empty Unicode string singleton ('') */ + _Py_INCREF_UNICODE_EMPTY(); + str = unicode_empty; + } + else { + str = writer->buffer; + writer->buffer = NULL; + + if (PyUnicode_GET_LENGTH(str) != writer->pos) { + PyObject *str2; + str2 = resize_compact(str, writer->pos); + if (str2 == NULL) + return NULL; + str = str2; } - writer->buffer = newbuffer; } - str = writer->buffer; - writer->buffer = NULL; + assert(_PyUnicode_CheckConsistency(str, 1)); return unicode_result_ready(str); } @@ -13885,8 +14118,8 @@ formatfloat(PyObject *v, struct unicode_format_arg_t *arg, * CAUTION: o, x and X conversions on regular ints can never * produce a '-' sign, but can for Python's unbounded ints. */ -static PyObject* -formatlong(PyObject *val, struct unicode_format_arg_t *arg) +PyObject * +_PyUnicode_FormatLong(PyObject *val, int alt, int prec, int type) { PyObject *result = NULL; char *buf; @@ -13896,8 +14129,6 @@ formatlong(PyObject *val, struct unicode_format_arg_t *arg) Py_ssize_t llen; int numdigits; /* len == numnondigits + numdigits */ int numnondigits = 0; - int prec = arg->prec; - int type = arg->ch; /* Avoid exceeding SSIZE_T_MAX */ if (prec > INT_MAX-3) { @@ -13946,7 +14177,7 @@ formatlong(PyObject *val, struct unicode_format_arg_t *arg) if (llen > INT_MAX) { Py_DECREF(result); PyErr_SetString(PyExc_ValueError, - "string too large in _PyBytes_FormatLong"); + "string too large in _PyUnicode_FormatLong"); return NULL; } len = (int)llen; @@ -13956,7 +14187,7 @@ formatlong(PyObject *val, struct unicode_format_arg_t *arg) assert(numdigits > 0); /* Get rid of base marker unless F_ALT */ - if (((arg->flags & F_ALT) == 0 && + if (((alt) == 0 && (type == 'o' || type == 'x' || type == 'X'))) { assert(buf[sign] == '0'); assert(buf[sign+1] == 'x' || buf[sign+1] == 'X' || @@ -14015,7 +14246,7 @@ formatlong(PyObject *val, struct unicode_format_arg_t *arg) return result; } -/* Format an integer. +/* 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 */ @@ -14031,12 +14262,23 @@ mainformatlong(PyObject *v, if (!PyNumber_Check(v)) goto wrongtype; + /* make sure number is a type of integer for o, x, and X */ if (!PyLong_Check(v)) { - iobj = PyNumber_Long(v); - if (iobj == NULL) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) - goto wrongtype; - return -1; + 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)); } @@ -14080,7 +14322,7 @@ mainformatlong(PyObject *v, return 1; } - res = formatlong(iobj, arg); + res = _PyUnicode_FormatLong(iobj, arg->flags & F_ALT, arg->prec, type); Py_DECREF(iobj); if (res == NULL) return -1; @@ -14088,10 +14330,23 @@ mainformatlong(PyObject *v, return 0; wrongtype: - PyErr_Format(PyExc_TypeError, - "%%%c format: a number is required, " - "not %.200s", - type, Py_TYPE(v)->tp_name); + 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; } @@ -14106,8 +14361,18 @@ formatchar(PyObject *v) goto onError; } else { - /* Integer input truncated to a character */ + 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; + } + v = iobj; + Py_DECREF(iobj); + } + /* Integer input truncated to a character */ x = PyLong_AsLong(v); if (x == -1 && PyErr_Occurred()) goto onError; @@ -14309,7 +14574,8 @@ unicode_format_arg_parse(struct unicode_formatter_t *ctx, /* Format one argument. Supported conversion specifiers: - "s", "r", "a": any type - - "i", "d", "u", "o", "x", "X": int + - "i", "d", "u": int or float + - "o", "x", "X": int - "e", "E", "f", "F", "g", "G": float - "c": int or str (1 character) @@ -14933,13 +15199,6 @@ int _PyUnicode_Init(void) if (PyType_Ready(&PyFormatterIter_Type) < 0) Py_FatalError("Can't initialize formatter iter type"); -#ifdef HAVE_MBCS - winver.dwOSVersionInfoSize = sizeof(winver); - if (!GetVersionEx((OSVERSIONINFO*)&winver)) { - PyErr_SetFromWindowsErr(0); - return -1; - } -#endif return 0; } @@ -15174,9 +15433,13 @@ unicodeiter_setstate(unicodeiterobject *it, PyObject *state) Py_ssize_t index = PyLong_AsSsize_t(state); if (index == -1 && PyErr_Occurred()) return NULL; - if (index < 0) - index = 0; - it->it_index = index; + 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; } @@ -15351,7 +15614,7 @@ PyUnicode_AsUnicodeCopy(PyObject *unicode) if (u == NULL) return NULL; /* Ensure we won't overflow the size. */ - if (len > ((PY_SSIZE_T_MAX / sizeof(Py_UNICODE)) - 1)) { + if (len > ((PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(Py_UNICODE)) - 1)) { PyErr_NoMemory(); return NULL; } diff --git a/Objects/unicodetype_db.h b/Objects/unicodetype_db.h index 1fdc092a3dd4..7c780b6c0456 100644 --- a/Objects/unicodetype_db.h +++ b/Objects/unicodetype_db.h @@ -82,25 +82,32 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {-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}, + {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}, @@ -122,6 +129,7 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {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}, @@ -143,110 +151,202 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {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}, {35332, 0, 35332, 0, 0, 9993}, {3814, 0, 3814, 0, 0, 9993}, - {33554509, 18874442, 33554509, 0, 0, 26377}, - {33554514, 18874447, 33554514, 0, 0, 26377}, - {33554519, 18874452, 33554519, 0, 0, 26377}, - {33554524, 18874457, 33554524, 0, 0, 26377}, - {33554529, 18874462, 33554529, 0, 0, 26377}, - {16777317, 17825891, 16777317, 0, 0, 26377}, - {16777321, 18874470, 16777321, 0, 0, 26497}, + {33554785, 18874718, 33554785, 0, 0, 26377}, + {33554790, 18874723, 33554790, 0, 0, 26377}, + {33554795, 18874728, 33554795, 0, 0, 26377}, + {33554800, 18874733, 33554800, 0, 0, 26377}, + {33554805, 18874738, 33554805, 0, 0, 26377}, + {16777593, 17826167, 16777593, 0, 0, 26377}, + {16777597, 18874746, 16777597, 0, 0, 26497}, {8, 0, 8, 0, 0, 9993}, {0, -8, 0, 0, 0, 10113}, - {33554541, 18874474, 33554541, 0, 0, 26377}, - {50331763, 19923055, 50331763, 0, 0, 26377}, - {50331770, 19923062, 50331770, 0, 0, 26377}, - {50331777, 19923069, 50331777, 0, 0, 26377}, + {33554817, 18874750, 33554817, 0, 0, 26377}, + {50332039, 19923331, 50332039, 0, 0, 26377}, + {50332046, 19923338, 50332046, 0, 0, 26377}, + {50332053, 19923345, 50332053, 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}, - {33554567, 18874500, 16777353, 0, 0, 26377}, - {33554573, 18874506, 16777359, 0, 0, 26377}, - {33554579, 18874512, 16777365, 0, 0, 26377}, - {33554585, 18874518, 16777371, 0, 0, 26377}, - {33554591, 18874524, 16777377, 0, 0, 26377}, - {33554597, 18874530, 16777383, 0, 0, 26377}, - {33554603, 18874536, 16777389, 0, 0, 26377}, - {33554609, 18874542, 16777395, 0, 0, 26377}, - {33554615, 18874548, 16777401, 0, 0, 26433}, - {33554621, 18874554, 16777407, 0, 0, 26433}, - {33554627, 18874560, 16777413, 0, 0, 26433}, - {33554633, 18874566, 16777419, 0, 0, 26433}, - {33554639, 18874572, 16777425, 0, 0, 26433}, - {33554645, 18874578, 16777431, 0, 0, 26433}, - {33554651, 18874584, 16777437, 0, 0, 26433}, - {33554657, 18874590, 16777443, 0, 0, 26433}, - {33554663, 18874596, 16777449, 0, 0, 26377}, - {33554669, 18874602, 16777455, 0, 0, 26377}, - {33554675, 18874608, 16777461, 0, 0, 26377}, - {33554681, 18874614, 16777467, 0, 0, 26377}, - {33554687, 18874620, 16777473, 0, 0, 26377}, - {33554693, 18874626, 16777479, 0, 0, 26377}, - {33554699, 18874632, 16777485, 0, 0, 26377}, - {33554705, 18874638, 16777491, 0, 0, 26377}, - {33554711, 18874644, 16777497, 0, 0, 26433}, - {33554717, 18874650, 16777503, 0, 0, 26433}, - {33554723, 18874656, 16777509, 0, 0, 26433}, - {33554729, 18874662, 16777515, 0, 0, 26433}, - {33554735, 18874668, 16777521, 0, 0, 26433}, - {33554741, 18874674, 16777527, 0, 0, 26433}, - {33554747, 18874680, 16777533, 0, 0, 26433}, - {33554753, 18874686, 16777539, 0, 0, 26433}, - {33554759, 18874692, 16777545, 0, 0, 26377}, - {33554765, 18874698, 16777551, 0, 0, 26377}, - {33554771, 18874704, 16777557, 0, 0, 26377}, - {33554777, 18874710, 16777563, 0, 0, 26377}, - {33554783, 18874716, 16777569, 0, 0, 26377}, - {33554789, 18874722, 16777575, 0, 0, 26377}, - {33554795, 18874728, 16777581, 0, 0, 26377}, - {33554801, 18874734, 16777587, 0, 0, 26377}, - {33554807, 18874740, 16777593, 0, 0, 26433}, - {33554813, 18874746, 16777599, 0, 0, 26433}, - {33554819, 18874752, 16777605, 0, 0, 26433}, - {33554825, 18874758, 16777611, 0, 0, 26433}, - {33554831, 18874764, 16777617, 0, 0, 26433}, - {33554837, 18874770, 16777623, 0, 0, 26433}, - {33554843, 18874776, 16777629, 0, 0, 26433}, - {33554849, 18874782, 16777635, 0, 0, 26433}, - {33554855, 18874788, 33554857, 0, 0, 26377}, - {33554862, 18874795, 16777648, 0, 0, 26377}, - {33554868, 18874801, 33554870, 0, 0, 26377}, - {33554875, 18874808, 33554875, 0, 0, 26377}, - {50332097, 19923389, 50332100, 0, 0, 26377}, + {33554843, 18874776, 16777629, 0, 0, 26377}, + {33554849, 18874782, 16777635, 0, 0, 26377}, + {33554855, 18874788, 16777641, 0, 0, 26377}, + {33554861, 18874794, 16777647, 0, 0, 26377}, + {33554867, 18874800, 16777653, 0, 0, 26377}, + {33554873, 18874806, 16777659, 0, 0, 26377}, + {33554879, 18874812, 16777665, 0, 0, 26377}, + {33554885, 18874818, 16777671, 0, 0, 26377}, + {33554891, 18874824, 16777677, 0, 0, 26433}, + {33554897, 18874830, 16777683, 0, 0, 26433}, + {33554903, 18874836, 16777689, 0, 0, 26433}, + {33554909, 18874842, 16777695, 0, 0, 26433}, + {33554915, 18874848, 16777701, 0, 0, 26433}, + {33554921, 18874854, 16777707, 0, 0, 26433}, + {33554927, 18874860, 16777713, 0, 0, 26433}, + {33554933, 18874866, 16777719, 0, 0, 26433}, + {33554939, 18874872, 16777725, 0, 0, 26377}, + {33554945, 18874878, 16777731, 0, 0, 26377}, + {33554951, 18874884, 16777737, 0, 0, 26377}, + {33554957, 18874890, 16777743, 0, 0, 26377}, + {33554963, 18874896, 16777749, 0, 0, 26377}, + {33554969, 18874902, 16777755, 0, 0, 26377}, + {33554975, 18874908, 16777761, 0, 0, 26377}, + {33554981, 18874914, 16777767, 0, 0, 26377}, + {33554987, 18874920, 16777773, 0, 0, 26433}, + {33554993, 18874926, 16777779, 0, 0, 26433}, + {33554999, 18874932, 16777785, 0, 0, 26433}, + {33555005, 18874938, 16777791, 0, 0, 26433}, + {33555011, 18874944, 16777797, 0, 0, 26433}, + {33555017, 18874950, 16777803, 0, 0, 26433}, + {33555023, 18874956, 16777809, 0, 0, 26433}, + {33555029, 18874962, 16777815, 0, 0, 26433}, + {33555035, 18874968, 16777821, 0, 0, 26377}, + {33555041, 18874974, 16777827, 0, 0, 26377}, + {33555047, 18874980, 16777833, 0, 0, 26377}, + {33555053, 18874986, 16777839, 0, 0, 26377}, + {33555059, 18874992, 16777845, 0, 0, 26377}, + {33555065, 18874998, 16777851, 0, 0, 26377}, + {33555071, 18875004, 16777857, 0, 0, 26377}, + {33555077, 18875010, 16777863, 0, 0, 26377}, + {33555083, 18875016, 16777869, 0, 0, 26433}, + {33555089, 18875022, 16777875, 0, 0, 26433}, + {33555095, 18875028, 16777881, 0, 0, 26433}, + {33555101, 18875034, 16777887, 0, 0, 26433}, + {33555107, 18875040, 16777893, 0, 0, 26433}, + {33555113, 18875046, 16777899, 0, 0, 26433}, + {33555119, 18875052, 16777905, 0, 0, 26433}, + {33555125, 18875058, 16777911, 0, 0, 26433}, + {33555131, 18875064, 33555133, 0, 0, 26377}, + {33555138, 18875071, 16777924, 0, 0, 26377}, + {33555144, 18875077, 33555146, 0, 0, 26377}, + {33555151, 18875084, 33555151, 0, 0, 26377}, + {50332373, 19923665, 50332376, 0, 0, 26377}, {0, -74, 0, 0, 0, 10113}, - {33554890, 18874823, 16777676, 0, 0, 26433}, - {16777679, 17826253, 16777679, 0, 0, 26377}, - {33554899, 18874832, 33554901, 0, 0, 26377}, - {33554906, 18874839, 16777692, 0, 0, 26377}, - {33554912, 18874845, 33554914, 0, 0, 26377}, - {33554919, 18874852, 33554919, 0, 0, 26377}, - {50332141, 19923433, 50332144, 0, 0, 26377}, + {33555166, 18875099, 16777952, 0, 0, 26433}, + {16777955, 17826529, 16777955, 0, 0, 26377}, + {33555175, 18875108, 33555177, 0, 0, 26377}, + {33555182, 18875115, 16777968, 0, 0, 26377}, + {33555188, 18875121, 33555190, 0, 0, 26377}, + {33555195, 18875128, 33555195, 0, 0, 26377}, + {50332417, 19923709, 50332420, 0, 0, 26377}, {0, -86, 0, 0, 0, 10113}, - {33554934, 18874867, 16777720, 0, 0, 26433}, - {50332157, 19923449, 50332157, 0, 0, 26377}, - {50332164, 19923456, 50332164, 0, 0, 26377}, - {33554954, 18874887, 33554954, 0, 0, 26377}, - {50332176, 19923468, 50332176, 0, 0, 26377}, + {33555210, 18875143, 16777996, 0, 0, 26433}, + {50332433, 19923725, 50332433, 0, 0, 26377}, + {50332440, 19923732, 50332440, 0, 0, 26377}, + {33555230, 18875163, 33555230, 0, 0, 26377}, + {50332452, 19923744, 50332452, 0, 0, 26377}, {0, -100, 0, 0, 0, 10113}, - {50332183, 19923475, 50332183, 0, 0, 26377}, - {50332190, 19923482, 50332190, 0, 0, 26377}, - {33554980, 18874913, 33554980, 0, 0, 26377}, - {33554985, 18874918, 33554985, 0, 0, 26377}, - {50332207, 19923499, 50332207, 0, 0, 26377}, + {50332459, 19923751, 50332459, 0, 0, 26377}, + {50332466, 19923758, 50332466, 0, 0, 26377}, + {33555256, 18875189, 33555256, 0, 0, 26377}, + {33555261, 18875194, 33555261, 0, 0, 26377}, + {50332483, 19923775, 50332483, 0, 0, 26377}, {0, -112, 0, 0, 0, 10113}, - {33554997, 18874930, 33554999, 0, 0, 26377}, - {33555004, 18874937, 16777790, 0, 0, 26377}, - {33555010, 18874943, 33555012, 0, 0, 26377}, - {33555017, 18874950, 33555017, 0, 0, 26377}, - {50332239, 19923531, 50332242, 0, 0, 26377}, + {33555273, 18875206, 33555275, 0, 0, 26377}, + {33555280, 18875213, 16778066, 0, 0, 26377}, + {33555286, 18875219, 33555288, 0, 0, 26377}, + {33555293, 18875226, 33555293, 0, 0, 26377}, + {50332515, 19923807, 50332518, 0, 0, 26377}, {0, -128, 0, 0, 0, 10113}, {0, -126, 0, 0, 0, 10113}, - {33555032, 18874965, 16777818, 0, 0, 26433}, + {33555308, 18875241, 16778094, 0, 0, 26433}, {0, 0, 0, 0, 0, 3076}, {0, 0, 0, 0, 4, 3076}, {0, 0, 0, 0, 5, 3076}, @@ -280,22 +380,111 @@ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { {0, -35332, 0, 0, 0, 10113}, {0, -42280, 0, 0, 0, 10113}, {0, -42308, 0, 0, 0, 10113}, - {33555038, 18874971, 33555040, 0, 0, 26377}, - {33555045, 18874978, 33555047, 0, 0, 26377}, - {33555052, 18874985, 33555054, 0, 0, 26377}, - {50332276, 19923568, 50332279, 0, 0, 26377}, - {50332286, 19923578, 50332289, 0, 0, 26377}, - {33555079, 18875012, 33555081, 0, 0, 26377}, - {33555086, 18875019, 33555088, 0, 0, 26377}, - {33555093, 18875026, 33555095, 0, 0, 26377}, - {33555100, 18875033, 33555102, 0, 0, 26377}, - {33555107, 18875040, 33555109, 0, 0, 26377}, - {33555114, 18875047, 33555116, 0, 0, 26377}, - {33555121, 18875054, 33555123, 0, 0, 26377}, + {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}, + {-928, 0, -928, 0, 0, 9993}, + {16778097, 17826671, 16778097, 0, 0, 26377}, + {16778100, 17826674, 16778100, 0, 0, 26377}, + {16778103, 17826677, 16778103, 0, 0, 26377}, + {16778106, 17826680, 16778106, 0, 0, 26377}, + {16778109, 17826683, 16778109, 0, 0, 26377}, + {16778112, 17826686, 16778112, 0, 0, 26377}, + {16778115, 17826689, 16778115, 0, 0, 26377}, + {16778118, 17826692, 16778118, 0, 0, 26377}, + {16778121, 17826695, 16778121, 0, 0, 26377}, + {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}, + {33555554, 18875487, 33555556, 0, 0, 26377}, + {33555561, 18875494, 33555563, 0, 0, 26377}, + {33555568, 18875501, 33555570, 0, 0, 26377}, + {50332792, 19924084, 50332795, 0, 0, 26377}, + {50332802, 19924094, 50332805, 0, 0, 26377}, + {33555595, 18875528, 33555597, 0, 0, 26377}, + {33555602, 18875535, 33555604, 0, 0, 26377}, + {33555609, 18875542, 33555611, 0, 0, 26377}, + {33555616, 18875549, 33555618, 0, 0, 26377}, + {33555623, 18875556, 33555625, 0, 0, 26377}, + {33555630, 18875563, 33555632, 0, 0, 26377}, + {33555637, 18875570, 33555639, 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, 0, 0, 0, 0, 9344}, }; /* extended case mappings */ @@ -375,6 +564,282 @@ const Py_UCS4 _PyUnicode_ExtendedCase[] = { 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, 7830, 104, 817, @@ -904,6 +1369,246 @@ const Py_UCS4 _PyUnicode_ExtendedCase[] = { 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, @@ -1029,405 +1734,511 @@ static unsigned char index1[] = { 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 128, 129, 130, 131, 132, 133, 134, 34, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 71, 145, 146, 147, 148, 149, 71, 71, 71, 71, 71, 71, 150, 71, 151, 152, - 153, 71, 154, 71, 155, 71, 71, 71, 156, 71, 71, 71, 157, 158, 159, 160, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 161, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 34, 34, 34, 34, 34, 34, 162, 71, - 163, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 34, 34, 34, 34, 34, 34, 34, 34, 164, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 34, 34, 34, 34, 165, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 166, 167, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 168, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 64, 169, 170, 171, 172, 71, 173, 71, 174, 175, 176, 177, 178, - 179, 180, 181, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 182, 183, 71, 71, 184, - 185, 186, 187, 188, 71, 189, 190, 191, 192, 193, 194, 195, 196, 65, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 197, 198, - 199, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 87, 200, - 34, 201, 202, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 145, 146, 147, 148, 149, 150, 151, 145, 34, 34, 152, 145, 153, 154, 155, + 156, 157, 158, 159, 160, 161, 162, 145, 145, 163, 145, 145, 145, 164, + 165, 166, 167, 168, 169, 170, 145, 145, 171, 145, 172, 173, 174, 175, + 145, 145, 176, 145, 145, 145, 177, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 34, 34, 34, 34, 34, 34, 34, 178, 179, 34, 180, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 34, 34, 34, 34, 34, 34, 34, 34, 181, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 34, 34, 34, 34, 182, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 34, 34, 34, 34, 183, 184, 185, 186, 145, 145, 145, 145, 145, + 145, 187, 188, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 189, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 190, 191, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 64, 192, + 193, 194, 195, 145, 196, 145, 197, 198, 199, 200, 201, 202, 203, 204, 64, + 64, 64, 64, 205, 206, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 34, 207, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 208, + 209, 145, 145, 210, 211, 212, 213, 214, 145, 64, 215, 64, 64, 216, 217, + 64, 218, 219, 220, 221, 222, 223, 224, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 225, 226, 227, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 87, 228, 34, 229, 230, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 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, 34, 34, 34, 34, 34, 34, 204, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 205, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 231, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 232, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 233, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 206, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 234, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 207, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 235, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 208, 34, 209, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 34, 203, 34, 34, 209, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 210, 71, 211, 212, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 127, 127, 127, 127, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 236, 34, 237, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 238, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 34, 231, 34, 34, 239, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 240, 145, 241, 242, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, @@ -1463,8 +2274,8 @@ static unsigned char index1[] = { 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 243, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 213, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, @@ -1500,7 +2311,7 @@ static unsigned char index1[] = { 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 213, + 127, 127, 127, 127, 243, }; static unsigned short index2[] = { @@ -1535,204 +2346,204 @@ static unsigned short index2[] = { 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, 20, 20, 20, - 20, 77, 20, 20, 80, 20, 81, 82, 20, 83, 84, 20, 85, 20, 20, 20, 84, 20, - 86, 87, 20, 20, 88, 20, 20, 20, 20, 20, 20, 20, 89, 20, 20, 90, 20, 20, - 90, 20, 20, 20, 20, 90, 91, 92, 92, 93, 20, 20, 20, 20, 20, 94, 20, 55, - 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, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 96, 96, 96, 96, 96, 96, 96, 95, 95, 6, 6, 6, 6, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 95, 95, - 95, 95, 95, 6, 6, 6, 6, 6, 6, 6, 96, 6, 96, 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, + 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, 20, 87, 88, 20, 20, 86, 20, + 89, 90, 20, 20, 91, 20, 20, 20, 20, 20, 20, 20, 92, 20, 20, 93, 20, 20, + 93, 20, 20, 20, 94, 93, 95, 96, 96, 97, 20, 20, 20, 20, 20, 98, 20, 55, + 20, 20, 20, 20, 20, 20, 20, 20, 99, 100, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 102, 102, 102, 102, 102, 102, 102, 101, 101, 6, 6, 6, 6, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 101, 101, 101, 101, 101, 6, 6, 6, 6, 6, 6, 6, + 102, 6, 102, 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, 103, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 97, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 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, 96, 6, 30, 31, 0, 0, - 98, 50, 50, 50, 5, 0, 0, 0, 0, 0, 6, 6, 99, 25, 100, 100, 100, 0, 101, 0, - 102, 102, 103, 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, 104, 105, 105, 105, - 106, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 107, 19, 19, 19, 19, 19, 19, 19, 19, 19, 108, 109, 109, 110, 111, 112, - 113, 113, 113, 114, 115, 116, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 117, 118, 119, 20, - 120, 121, 5, 30, 31, 122, 30, 31, 20, 64, 64, 64, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 17, 17, 17, + 25, 25, 30, 31, 30, 31, 102, 6, 30, 31, 0, 0, 104, 50, 50, 50, 5, 105, 0, + 0, 0, 0, 6, 6, 106, 25, 107, 107, 107, 0, 108, 0, 109, 109, 110, 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, 111, 112, 112, 112, 113, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 114, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 115, 116, 116, 117, 118, 119, 120, 120, 120, 121, 122, + 123, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 124, 125, 126, 127, 128, 129, 5, 30, 31, 130, + 30, 31, 20, 64, 64, 64, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 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, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 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, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 5, 25, 25, 25, 25, 25, 6, 6, 30, 31, 30, 31, + 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, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 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, 30, 31, 30, 31, 30, 31, 30, 31, 125, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 126, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 30, 31, 133, 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, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 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, 0, 0, 0, 0, 0, 0, 0, 0, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 0, 0, 96, 5, 5, 5, 5, 5, 5, - 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 129, 0, 5, 5, 0, 0, 0, - 0, 5, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 0, 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, 0, 0, 102, 5, 5, 5, 5, 5, 5, 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, 137, 0, 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, 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, 0, 55, 55, 55, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, - 21, 21, 0, 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, 96, 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, + 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, 0, 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, 102, + 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, 5, 55, 25, 25, 25, 25, 25, 25, 25, 21, 5, 25, 25, 25, - 25, 25, 25, 96, 96, 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, 5, 55, 25, 25, 25, 25, 25, 25, 25, 21, 5, 25, 25, 25, 25, 25, 25, + 102, 102, 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, 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, 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, - 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, 25, 96, 96, 5, 5, 5, 5, 96, - 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, 96, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 96, 25, 25, 25, 96, 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, 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, 102, 102, 5, 5, 5, 5, 102, 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, 102, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 102, 25, 25, 25, 102, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 25, 25, 25, + 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, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 0, 25, 25, 25, 18, 55, 55, 55, 55, 55, 55, 55, + 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, 96, 55, 55, 55, 55, 55, 55, 0, - 55, 55, 55, 55, 55, 55, 55, 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, 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, 0, 0, 0, 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, 0, 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, 0, 0, 0, 0, 0, 0, 0, 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, 0, 18, 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, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 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, 0, 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, 0, 27, 27, 27, 27, 27, 27, 27, 5, 0, 0, 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, 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, - 0, 0, 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, 0, 0, 55, 18, 18, 18, 25, 25, 25, 25, 0, 18, 18, 18, 0, - 18, 18, 18, 25, 55, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, - 55, 55, 25, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 27, 27, 27, - 27, 27, 27, 0, 0, 0, 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, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 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, 130, 25, 25, - 25, 25, 25, 25, 25, 0, 0, 0, 0, 5, 55, 55, 55, 55, 55, 55, 96, 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, 0, 55, 55, 0, 55, - 0, 0, 55, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 55, 0, 55, 0, 55, 0, 0, 55, 55, 0, 55, 55, 55, 55, 25, 55, - 130, 25, 25, 25, 25, 25, 25, 0, 25, 25, 55, 0, 0, 55, 55, 55, 55, 55, 0, - 96, 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, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 102, 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, 0, 0, 0, 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, 0, 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, 0, 0, 0, 0, 0, 0, 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, 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, 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, 0, 27, 27, 27, 27, 27, 27, 27, 5, 0, 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, + 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, 0, 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, 0, 0, 55, 18, 18, 18, 25, 25, 25, 25, + 0, 18, 18, 18, 0, 18, 18, 18, 25, 55, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, + 0, 0, 0, 0, 0, 55, 55, 55, 25, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 27, 27, 27, 27, 27, 27, 0, 0, 0, 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, 138, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 5, 55, 55, 55, + 55, 55, 55, 102, 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, 0, 55, 55, 0, 55, 0, 0, 55, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 0, + 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 0, 55, 0, 55, 0, 0, 55, 55, 0, + 55, 55, 55, 55, 25, 55, 138, 25, 25, 25, 25, 25, 25, 0, 25, 25, 55, 0, 0, + 55, 55, 55, 55, 55, 0, 102, 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, 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, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 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, 0, 0, 0, 0, 0, 131, 0, 0, + 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, - 55, 55, 55, 55, 55, 55, 55, 5, 96, 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, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 0, + 139, 0, 0, 0, 0, 0, 139, 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, 5, 102, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, @@ -1742,31 +2553,34 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, + 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, 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, 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, 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, 132, 133, 134, 135, 136, 137, 138, 139, 140, 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, 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, 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, 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, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 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, 149, 150, 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, 0, 0, 235, 236, + 237, 238, 239, 240, 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, @@ -1786,28 +2600,28 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, 141, 141, 141, 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, 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, 96, 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, 96, + 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, 241, 241, 241, 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, 102, 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, + 102, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, 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, 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, @@ -1815,71 +2629,73 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 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, 0, 0, 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, 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, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 55, 55, 55, 55, 55, 55, 55, 18, 18, 0, 0, 0, 0, 0, 0, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 132, 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, 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, 140, 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, 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, + 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, 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, 96, 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, + 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, 102, 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, 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, + 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, 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, 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, 18, 25, 25, 25, 25, 18, 18, 25, 25, 18, 25, 18, 18, 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, 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, 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, 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, 55, 96, 96, 96, 96, 96, 96, 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, + 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, 102, 102, 102, + 102, 102, 102, 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, 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, 18, 18, 25, 55, 55, 0, 0, 0, 0, 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, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 95, 142, 20, 20, 20, 143, 20, 20, 20, 20, 20, + 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, 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, 18, 18, 25, 55, 55, 0, 25, 25, 0, 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, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 101, 242, 20, + 20, 20, 243, 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, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 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, 0, 0, 0, 0, 0, 25, 25, 25, 25, 30, 31, 30, 31, 30, 31, 30, + 25, 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, 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, @@ -1887,51 +2703,51 @@ static unsigned short index2[] = { 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 144, - 145, 146, 147, 148, 149, 20, 20, 150, 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, 151, 151, - 151, 151, 151, 151, 151, 151, 152, 152, 152, 152, 152, 152, 152, 152, - 151, 151, 151, 151, 151, 151, 0, 0, 152, 152, 152, 152, 152, 152, 0, 0, - 151, 151, 151, 151, 151, 151, 151, 151, 152, 152, 152, 152, 152, 152, - 152, 152, 151, 151, 151, 151, 151, 151, 151, 151, 152, 152, 152, 152, - 152, 152, 152, 152, 151, 151, 151, 151, 151, 151, 0, 0, 152, 152, 152, - 152, 152, 152, 0, 0, 153, 151, 154, 151, 155, 151, 156, 151, 0, 152, 0, - 152, 0, 152, 0, 152, 151, 151, 151, 151, 151, 151, 151, 151, 152, 152, - 152, 152, 152, 152, 152, 152, 157, 157, 158, 158, 158, 158, 159, 159, - 160, 160, 161, 161, 162, 162, 0, 0, 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, 151, - 151, 211, 212, 213, 0, 214, 215, 152, 152, 216, 216, 217, 6, 218, 6, 6, - 6, 219, 220, 221, 0, 222, 223, 224, 224, 224, 224, 225, 6, 6, 6, 151, - 151, 226, 227, 0, 0, 228, 229, 152, 152, 230, 230, 0, 6, 6, 6, 151, 151, - 231, 232, 233, 119, 234, 235, 152, 152, 236, 236, 122, 6, 6, 6, 0, 0, - 237, 238, 239, 0, 240, 241, 242, 242, 243, 243, 244, 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, 245, 95, 0, 0, - 246, 247, 248, 249, 250, 251, 5, 5, 5, 5, 5, 95, 245, 26, 22, 23, 246, - 247, 248, 249, 250, 251, 5, 5, 5, 5, 5, 0, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 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, 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, 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, 113, 5, 5, - 5, 5, 113, 5, 5, 20, 113, 113, 113, 20, 20, 113, 113, 113, 20, 5, 113, 5, - 5, 252, 113, 113, 113, 113, 113, 5, 5, 5, 5, 5, 5, 113, 5, 253, 5, 113, - 5, 254, 255, 113, 113, 252, 20, 113, 113, 256, 113, 20, 55, 55, 55, 55, - 20, 5, 5, 20, 20, 113, 113, 5, 5, 5, 5, 5, 113, 20, 20, 20, 20, 5, 5, 5, - 5, 257, 5, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, - 258, 258, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, - 259, 259, 259, 259, 141, 141, 141, 30, 31, 141, 141, 141, 141, 27, 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, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 244, 245, 246, 247, 248, 249, 20, 20, 250, 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, 251, 251, 251, 251, 251, 251, 251, 251, 252, 252, 252, 252, + 252, 252, 252, 252, 251, 251, 251, 251, 251, 251, 0, 0, 252, 252, 252, + 252, 252, 252, 0, 0, 251, 251, 251, 251, 251, 251, 251, 251, 252, 252, + 252, 252, 252, 252, 252, 252, 251, 251, 251, 251, 251, 251, 251, 251, + 252, 252, 252, 252, 252, 252, 252, 252, 251, 251, 251, 251, 251, 251, 0, + 0, 252, 252, 252, 252, 252, 252, 0, 0, 253, 251, 254, 251, 255, 251, 256, + 251, 0, 252, 0, 252, 0, 252, 0, 252, 251, 251, 251, 251, 251, 251, 251, + 251, 252, 252, 252, 252, 252, 252, 252, 252, 257, 257, 258, 258, 258, + 258, 259, 259, 260, 260, 261, 261, 262, 262, 0, 0, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 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, 251, 251, 311, 312, 313, 0, 314, 315, 252, 252, 316, 316, 317, + 6, 318, 6, 6, 6, 319, 320, 321, 0, 322, 323, 324, 324, 324, 324, 325, 6, + 6, 6, 251, 251, 326, 327, 0, 0, 328, 329, 252, 252, 330, 330, 0, 6, 6, 6, + 251, 251, 331, 332, 333, 126, 334, 335, 252, 252, 336, 336, 130, 6, 6, 6, + 0, 0, 337, 338, 339, 0, 340, 341, 342, 342, 343, 343, 344, 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, 345, 101, + 0, 0, 346, 347, 348, 349, 350, 351, 5, 5, 5, 5, 5, 101, 345, 26, 22, 23, + 346, 347, 348, 349, 350, 351, 5, 5, 5, 5, 5, 0, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, + 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, 120, 5, 5, 5, 5, 120, 5, 5, 20, 120, 120, 120, 20, 20, 120, 120, + 120, 20, 5, 120, 5, 5, 352, 120, 120, 120, 120, 120, 5, 5, 5, 5, 5, 5, + 120, 5, 353, 5, 120, 5, 354, 355, 120, 120, 352, 20, 120, 120, 356, 120, + 20, 55, 55, 55, 55, 20, 5, 5, 20, 20, 120, 120, 5, 5, 5, 5, 5, 120, 20, + 20, 20, 20, 5, 5, 5, 5, 357, 5, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 358, 358, 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 359, 359, 359, 359, 359, 359, 359, 359, + 359, 359, 359, 359, 359, 359, 359, 359, 241, 241, 241, 30, 31, 241, 241, + 241, 241, 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, @@ -1946,134 +2762,134 @@ static unsigned short index2[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 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, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 246, 247, 248, 249, 250, - 251, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 22, 23, 246, 247, - 248, 249, 250, 251, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 22, - 23, 246, 247, 248, 249, 250, 251, 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, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, - 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, 261, - 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, - 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 261, 245, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 26, 22, 23, 246, 247, 248, 249, 250, 251, 27, - 245, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 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, 346, + 347, 348, 349, 350, 351, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, + 22, 23, 346, 347, 348, 349, 350, 351, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 26, 22, 23, 346, 347, 348, 349, 350, 351, 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, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, + 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, + 360, 360, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, 361, + 345, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 22, 23, 346, 347, 348, + 349, 350, 351, 27, 345, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 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, 246, 247, 248, 249, 250, 251, 27, 26, 22, 23, 246, 247, 248, 249, - 250, 251, 27, 26, 22, 23, 246, 247, 248, 249, 250, 251, 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, 26, 22, 23, 346, 347, 348, 349, 350, 351, 27, 26, 22, + 23, 346, 347, 348, 349, 350, 351, 27, 26, 22, 23, 346, 347, 348, 349, + 350, 351, 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, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 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, 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, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 136, 136, 136, 136, 136, 136, 136, 136, 136, 0, + 30, 31, 362, 363, 364, 365, 366, 30, 31, 30, 31, 30, 31, 367, 368, 369, + 370, 20, 30, 31, 20, 30, 31, 20, 20, 20, 20, 20, 101, 101, 371, 371, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, + 31, 30, 31, 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, 372, 372, 372, + 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, + 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, + 372, 372, 372, 372, 372, 372, 372, 0, 372, 0, 0, 0, 0, 0, 372, 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, 102, 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, 373, 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, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 30, 31, 262, 263, - 264, 265, 266, 30, 31, 30, 31, 30, 31, 267, 268, 269, 270, 20, 30, 31, - 20, 30, 31, 20, 20, 20, 20, 20, 95, 95, 271, 271, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 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, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 272, 272, 272, 272, 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, 272, 0, 0, 0, 0, 0, 272, 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, 96, 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, + 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, 273, 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, 5, 5, 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, 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, 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, 96, 55, 141, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 25, 25, 25, 25, 18, 18, 5, 96, - 96, 96, 96, 96, 5, 5, 141, 141, 141, 96, 55, 5, 5, 5, 0, 55, 55, 55, 55, + 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, 102, 55, 241, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 241, 241, 241, 241, 241, 241, 241, 241, 241, 25, + 25, 25, 25, 18, 18, 5, 102, 102, 102, 102, 102, 5, 5, 241, 241, 241, 102, + 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, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, 25, 6, 6, 96, 96, 55, - 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 25, 25, 6, 6, 102, 102, 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, 5, 96, 96, 96, 55, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 102, 102, 102, 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, 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, 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, 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, + 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, 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, 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, 5, 5, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 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, 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, 0, 55, 55, 55, - 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 5, 5, 5, 5, 5, 5, 5, 5, 0, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, @@ -2082,7 +2898,7 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, @@ -2091,56 +2907,56 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, + 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, 274, 55, 55, 274, 55, 55, 55, 274, 55, 274, 55, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 374, + 55, 55, 374, 55, 55, 55, 374, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, + 55, 55, 55, 55, 374, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 274, 55, 274, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 274, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, - 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 274, 55, 274, 55, + 55, 55, 55, 374, 55, 374, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 274, 274, 274, 55, 55, - 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 374, 55, 374, 374, 374, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 274, 274, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 374, 374, 374, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, @@ -2148,7 +2964,7 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, @@ -2156,25 +2972,24 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, - 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 274, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 274, 274, 274, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 374, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 374, 374, 374, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, @@ -2185,220 +3000,226 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 274, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, + 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, - 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 96, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 102, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, 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, 96, 96, 96, 96, 96, 96, 5, 5, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 96, 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, 96, 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, 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, 102, + 102, 102, 102, 102, 102, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 102, 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, 102, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, + 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 101, 101, 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, 55, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 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, 96, 96, 96, 96, 96, 96, 96, 96, 96, 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, 95, 20, 20, 20, 20, 20, 20, 20, 20, 30, 31, 30, 31, 275, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 96, 6, 6, 30, 31, 276, 20, 0, 30, 31, 30, - 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 277, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 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, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 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, 102, 102, 102, 102, 102, 102, 102, 102, 102, 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, 101, 20, 20, 20, 20, 20, 20, 20, 20, 30, 31, 30, 31, 375, 30, + 31, 30, 31, 30, 31, 30, 31, 30, 31, 102, 6, 6, 30, 31, 376, 20, 55, 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, 377, 378, 379, 380, 0, 0, 381, 382, 383, 384, + 30, 31, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 95, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 101, 101, + 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, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 25, 0, 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, - 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, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 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, - 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, 18, 18, 18, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 96, 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, 55, 55, 55, 55, 55, 55, 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, 0, 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, 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, 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, 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, 96, 55, 55, 55, 55, 55, 55, 5, 5, 5, 55, 18, 0, 0, 0, 0, 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, 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, 96, 5, 5, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 25, 25, 18, 18, 5, 5, 55, 96, 96, - 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, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 25, 18, 18, 25, 25, 25, 25, 18, 18, 25, 18, + 18, 18, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 102, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 5, 5, 55, 55, 55, 55, 55, 25, 102, + 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, 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, 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, 102, 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, 102, + 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 25, 25, 18, 18, 5, + 5, 55, 102, 102, 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, 385, 20, 20, 20, 20, 20, 20, 20, 6, 101, 101, 101, 101, 20, 20, + 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 386, 387, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 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, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, 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, 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, - 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, + 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, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 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, 274, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, - 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, + 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 274, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 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, 279, 280, 281, 282, 283, 284, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 285, 286, 287, 288, 289, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 466, 467, 468, 469, + 470, 471, 472, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 473, 474, 475, 476, + 477, 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, - 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, 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, @@ -2406,198 +3227,309 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 290, 290, 290, 290, 290, 290, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 478, 478, 478, 478, 478, 478, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, + 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, 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, + 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, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 290, 290, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 290, 55, 290, 55, 290, 0, 290, 55, 290, 55, - 290, 55, 290, 55, 290, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 478, 478, 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, + 478, 55, 478, 55, 478, 0, 478, 55, 478, 55, 478, 55, 478, 55, 478, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, 96, 55, 55, 55, 55, 55, 55, 55, 55, 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, 102, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 291, 291, 55, 55, 55, 55, 55, 55, 55, 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, 479, 479, 55, 55, 55, 55, 55, 55, 55, 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, 0, 0, 0, - 0, 0, 5, 5, 5, 0, 0, 0, 0, 27, 27, 27, 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, 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, 0, 0, 0, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 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, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 27, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 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, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 27, 27, 27, 27, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 27, 27, 5, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, + 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, 25, 0, 0, 55, + 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, 55, 55, 55, 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, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, 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, 0, 27, 27, 27, 27, 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, 141, 55, 55, 55, - 55, 55, 55, 55, 55, 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 27, 27, 27, 27, 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, + 241, 55, 55, 55, 55, 55, 55, 55, 55, 241, 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, 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, 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, 55, 55, 55, 55, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 5, 141, - 141, 141, 141, 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 293, 293, 293, 293, 293, 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, 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, 480, 480, + 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, + 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, + 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, 481, 481, 481, 481, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, 0, 0, 0, 0, + 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, + 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, 0, 0, 0, 0, 0, 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, + 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, 55, 55, 0, 0, 0, 0, 25, 25, 25, 0, 0, 0, 0, 25, - 26, 22, 23, 246, 27, 27, 27, 27, 0, 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, 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, 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, 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, 0, 0, + 0, 0, 25, 25, 25, 0, 0, 0, 0, 25, 26, 22, 23, 346, 27, 27, 27, 27, 0, 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, 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, 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, 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, + 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, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 22, 23, 246, 247, 248, 249, 250, 251, 27, + 0, 0, 0, 0, 0, 26, 22, 23, 346, 347, 348, 349, 350, 351, 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, 18, 25, 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 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, 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, 246, 247, 248, - 249, 250, 251, 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, 0, - 25, 25, 18, 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, 346, 347, 348, 349, 350, + 351, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 5, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 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, 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, 0, 0, 0, 0, 0, 25, 25, 18, 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, 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, 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, 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, + 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 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, 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, 55, 55, 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, + 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, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 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, 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, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, + 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, 0, @@ -2607,224 +3539,292 @@ static unsigned short index2[] = { 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 18, 18, 18, 18, 18, + 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, 102, 102, 102, 102, 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, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, - 25, 25, 25, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 0, 0, 0, + 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, + 25, 25, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 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, 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, + 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, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 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, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, + 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, 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, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 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, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 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, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 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, 113, 0, 113, 113, 0, 0, 113, 0, 0, - 113, 113, 0, 0, 113, 113, 113, 113, 0, 113, 113, 113, 113, 113, 113, 113, - 113, 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, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 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, 113, 113, 0, 113, - 113, 113, 113, 0, 0, 113, 113, 113, 113, 113, 113, 113, 113, 0, 113, 113, - 113, 113, 113, 113, 113, 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, 113, 113, 0, - 113, 113, 113, 113, 0, 113, 113, 113, 113, 113, 0, 113, 0, 0, 0, 113, - 113, 113, 113, 113, 113, 113, 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, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 20, 20, 20, 20, 20, 20, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 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, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 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, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 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, - 20, 20, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 20, 20, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 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, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 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, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 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, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 120, 0, 120, 120, 0, 0, 120, 0, 0, 120, 120, 0, 0, + 120, 120, 120, 120, 0, 120, 120, 120, 120, 120, 120, 120, 120, 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, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 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, 120, 120, 0, 120, 120, 120, 120, + 0, 0, 120, 120, 120, 120, 120, 120, 120, 120, 0, 120, 120, 120, 120, 120, + 120, 120, 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, 120, 120, 0, 120, 120, 120, + 120, 0, 120, 120, 120, 120, 120, 0, 120, 0, 0, 0, 120, 120, 120, 120, + 120, 120, 120, 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, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 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, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 20, 20, + 20, 20, 20, 20, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 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, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 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, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 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, 0, 0, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 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, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 5, 20, 20, + 20, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 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, 5, 20, 20, 20, 20, 20, 20, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 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, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 5, + 20, 20, 20, 20, 20, 20, 20, 0, 0, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 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, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 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, 20, 20, 20, 20, 5, 20, 20, 20, 20, 20, 20, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 113, 113, 113, 5, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 5, 20, 20, 20, 20, 20, 20, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 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, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 5, 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, 113, 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, 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, + 20, 20, 20, 20, 20, 5, 20, 20, 20, 20, 20, 20, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 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, 120, 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, 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, + 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 245, 26, 22, 23, 246, 247, 248, 249, - 250, 251, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 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, + 345, 345, 26, 22, 23, 346, 347, 348, 349, 350, 351, 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, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 0, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, + 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, + 482, 482, 5, 5, 5, 5, 5, 5, 482, 482, 482, 482, 482, 482, 482, 482, 482, + 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, + 482, 482, 482, 5, 5, 0, 0, 0, 0, 482, 482, 482, 482, 482, 482, 482, 482, + 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, + 482, 482, 482, 482, 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, 5, 5, 5, 5, 5, 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, 5, 5, 5, 5, 5, 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, 5, 5, 5, 0, 0, 0, 0, 0, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, - 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 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, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 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, 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, 0, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 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, 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, 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, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 55, 274, 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, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, - 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, @@ -2834,33 +3834,33 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, @@ -2870,34 +3870,48 @@ static unsigned short index2[] = { 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 274, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 374, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 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, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, + 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, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 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, @@ -2910,13 +3924,13 @@ static unsigned short index2[] = { 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 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, + 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, 0, 0, + 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 @@ -2941,6 +3955,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0C78: case 0x0CE6: case 0x0D66: + case 0x0DE6: case 0x0E50: case 0x0ED0: case 0x0F20: @@ -2969,6 +3984,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0xA8D0: case 0xA900: case 0xA9D0: + case 0xA9F0: case 0xAA50: case 0xABF0: case 0xF9B2: @@ -2979,7 +3995,14 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x110F0: case 0x11136: case 0x111D0: + case 0x112F0: + case 0x114D0: + case 0x11650: case 0x116C0: + case 0x11730: + case 0x118E0: + case 0x16A60: + case 0x16B50: case 0x1D7CE: case 0x1D7D8: case 0x1D7E2: @@ -2987,6 +4010,8 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7F6: case 0x1F100: case 0x1F101: + case 0x1F10B: + case 0x1F10C: return (double) 0.0; case 0x0031: case 0x00B9: @@ -3004,6 +4029,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0C7C: case 0x0CE7: case 0x0D67: + case 0x0DE7: case 0x0E51: case 0x0ED1: case 0x0F21: @@ -3047,6 +4073,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0xA8D1: case 0xA901: case 0xA9D1: + case 0xA9F1: case 0xAA51: case 0xABF1: case 0xFF11: @@ -3055,39 +4082,59 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) 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 0x10E60: case 0x11052: case 0x11067: case 0x110F1: case 0x11137: case 0x111D1: + case 0x111E1: + case 0x112F1: + case 0x114D1: + case 0x11651: case 0x116C1: + case 0x11731: + case 0x118E1: case 0x12415: case 0x1241E: case 0x1242C: case 0x12434: case 0x1244F: case 0x12458: + case 0x16A61: + case 0x16B51: case 0x1D360: case 0x1D7CF: case 0x1D7D9: case 0x1D7E3: case 0x1D7ED: case 0x1D7F7: + case 0x1E8C7: case 0x1F102: case 0x2092A: return (double) 1.0; case 0x2152: return (double) 1.0/10.0; + case 0x109F6: + return (double) 1.0/12.0; case 0x09F4: case 0x0B75: case 0xA833: @@ -3101,12 +4148,15 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10141: case 0x10175: case 0x10176: + case 0x109BD: case 0x10E7B: + case 0x12464: return (double) 1.0/2.0; case 0x2153: case 0x10E7D: case 0x1245A: case 0x1245D: + case 0x12465: return (double) 1.0/3.0; case 0x00BC: case 0x09F7: @@ -3114,9 +4164,11 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0D73: case 0xA830: case 0x10140: + case 0x1018B: case 0x10E7C: case 0x12460: case 0x12462: + case 0x12463: return (double) 1.0/4.0; case 0x2155: return (double) 1.0/5.0; @@ -3163,17 +4215,32 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) 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 0x1105B: + case 0x111EA: + case 0x1173A: + case 0x118EA: + case 0x16B5B: case 0x1D369: return (double) 10.0; + case 0x109FF: + return (double) 10.0/12.0; case 0x0BF1: case 0x0D71: case 0x137B: @@ -3186,14 +4253,23 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) 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 0x11064: + case 0x111F3: + case 0x16B5C: return (double) 100.0; case 0x0BF2: case 0x0D72: @@ -3208,10 +4284,13 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10154: case 0x10171: case 0x1085E: + case 0x109DB: case 0x10A47: case 0x10B5F: case 0x10B7F: + case 0x10CFF: case 0x11065: + case 0x111F4: return (double) 1000.0; case 0x137C: case 0x2182: @@ -3220,13 +4299,22 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1012B: case 0x10155: case 0x1085F: + case 0x109E4: + case 0x16B5D: return (double) 10000.0; case 0x2188: + case 0x109ED: return (double) 100000.0; + case 0x16B5E: + return (double) 1000000.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: @@ -3235,6 +4323,8 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2492: case 0x24EB: return (double) 11.0; + case 0x109BC: + return (double) 11.0/12.0; case 0x0F2F: return (double) 11.0/2.0; case 0x216B: @@ -3305,6 +4395,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0C7D: case 0x0CE8: case 0x0D68: + case 0x0DE8: case 0x0E52: case 0x0ED2: case 0x0F22: @@ -3349,6 +4440,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0xA8D2: case 0xA902: case 0xA9D2: + case 0xA9F2: case 0xAA52: case 0xABF2: case 0xF978: @@ -3358,20 +4450,31 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) 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 0x10E61: case 0x11053: case 0x11068: case 0x110F2: case 0x11138: case 0x111D2: + case 0x111E2: + case 0x112F2: + case 0x114D2: + case 0x11652: case 0x116C2: + case 0x11732: + case 0x118E2: case 0x12400: case 0x12416: case 0x1241F: @@ -3382,20 +4485,26 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x12450: case 0x12456: case 0x12459: + case 0x16A62: + case 0x16B52: case 0x1D361: case 0x1D7D0: case 0x1D7DA: case 0x1D7E4: case 0x1D7EE: case 0x1D7F8: + case 0x1E8C8: 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; @@ -3409,23 +4518,40 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) 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 0x1105C: + case 0x111EB: + case 0x1173B: + case 0x118EB: case 0x1D36A: return (double) 20.0; case 0x1011A: + case 0x102F4: + case 0x109D3: case 0x10E73: return (double) 200.0; case 0x10123: + case 0x109DC: return (double) 2000.0; case 0x1012C: + case 0x109E5: return (double) 20000.0; + case 0x109EE: + return (double) 200000.0; case 0x3251: return (double) 21.0; case 0x12432: @@ -3462,6 +4588,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0C7E: case 0x0CE9: case 0x0D69: + case 0x0DE9: case 0x0E53: case 0x0ED3: case 0x0F23: @@ -3505,24 +4632,36 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) 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 0x10E62: case 0x11054: case 0x11069: case 0x110F3: case 0x11139: case 0x111D3: + case 0x111E3: + case 0x112F3: + case 0x114D3: + case 0x11653: case 0x116C3: + case 0x11733: + case 0x118E3: case 0x12401: case 0x12408: case 0x12417: @@ -3538,18 +4677,23 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1244B: case 0x12451: case 0x12457: + case 0x16A63: + case 0x16B53: case 0x1D362: case 0x1D7D1: case 0x1D7DB: case 0x1D7E5: case 0x1D7EF: case 0x1D7F9: + case 0x1E8C9: 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 0xA835: @@ -3574,19 +4718,29 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x5345: case 0x10112: case 0x10165: + case 0x102EC: + case 0x109CB: case 0x10E6B: case 0x1105D: + case 0x111EC: + case 0x118EC: case 0x1D36B: case 0x20983: return (double) 30.0; case 0x1011B: case 0x1016B: + case 0x102F5: + case 0x109D4: case 0x10E74: return (double) 300.0; case 0x10124: + case 0x109DD: return (double) 3000.0; case 0x1012D: + case 0x109E6: return (double) 30000.0; + case 0x109EF: + return (double) 300000.0; case 0x325B: return (double) 31.0; case 0x325C: @@ -3618,6 +4772,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0C6A: case 0x0CEA: case 0x0D6A: + case 0x0DEA: case 0x0E54: case 0x0ED4: case 0x0F24: @@ -3658,21 +4813,34 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) 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 0x10E63: case 0x11055: case 0x1106A: case 0x110F4: case 0x1113A: case 0x111D4: + case 0x111E4: + case 0x112F4: + case 0x114D4: + case 0x11654: case 0x116C4: + case 0x11734: + case 0x118E4: case 0x12402: case 0x12409: case 0x1240F: @@ -3688,17 +4856,23 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1244C: case 0x12452: case 0x12453: + case 0x12469: + case 0x16A64: + case 0x16B54: case 0x1D363: case 0x1D7D2: case 0x1D7DC: case 0x1D7E6: case 0x1D7F0: case 0x1D7FA: + case 0x1E8CA: 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: @@ -3706,19 +4880,30 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x32B5: case 0x534C: case 0x10113: + case 0x102ED: + case 0x109CC: case 0x10E6C: case 0x1105E: + case 0x111ED: + case 0x118ED: + case 0x12467: case 0x1D36C: case 0x2098C: case 0x2099C: return (double) 40.0; case 0x1011C: + case 0x102F6: + case 0x109D5: case 0x10E75: return (double) 400.0; case 0x10125: + case 0x109DE: return (double) 4000.0; case 0x1012E: + case 0x109E7: return (double) 40000.0; + case 0x109F0: + return (double) 400000.0; case 0x32B6: return (double) 41.0; case 0x32B7: @@ -3752,6 +4937,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0C6B: case 0x0CEB: case 0x0D6B: + case 0x0DEB: case 0x0E55: case 0x0ED5: case 0x0F25: @@ -3792,6 +4978,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0xA8D5: case 0xA905: case 0xA9D5: + case 0xA9F5: case 0xAA55: case 0xABF5: case 0xFF15: @@ -3801,15 +4988,28 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) 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 0x10E64: case 0x11056: case 0x1106B: case 0x110F5: case 0x1113B: case 0x111D5: + case 0x111E5: + case 0x112F5: + case 0x114D5: + case 0x11655: case 0x116C5: + case 0x11735: + case 0x118E5: case 0x12403: case 0x1240A: case 0x12410: @@ -3821,15 +5021,21 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1244D: case 0x12454: case 0x12455: + case 0x1246A: + case 0x16A65: + case 0x16B55: case 0x1D364: case 0x1D7D3: case 0x1D7DD: case 0x1D7E7: case 0x1D7F1: case 0x1D7FB: + case 0x1E8CB: 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: @@ -3852,10 +5058,16 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) 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 0x12468: case 0x1D36D: return (double) 50.0; case 0x216E: @@ -3869,6 +5081,8 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1016E: case 0x1016F: case 0x10170: + case 0x102F7: + case 0x109D6: case 0x10E76: return (double) 500.0; case 0x2181: @@ -3876,12 +5090,16 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x10146: case 0x1014E: case 0x10172: + case 0x109DF: return (double) 5000.0; case 0x2187: case 0x1012F: case 0x10147: case 0x10156: + case 0x109E8: return (double) 50000.0; + case 0x109F1: + return (double) 500000.0; case 0x0036: case 0x0666: case 0x06F6: @@ -3895,6 +5113,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0C6C: case 0x0CEC: case 0x0D6C: + case 0x0DEC: case 0x0E56: case 0x0ED6: case 0x0F26: @@ -3935,20 +5154,29 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) 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 0x10E65: case 0x11057: case 0x1106C: case 0x110F6: case 0x1113C: case 0x111D6: + case 0x111E6: + case 0x112F6: + case 0x114D6: + case 0x11656: case 0x116C6: + case 0x11736: + case 0x118E6: case 0x12404: case 0x1240B: case 0x12411: @@ -3956,29 +5184,45 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x12428: case 0x12440: case 0x1244E: + case 0x1246B: + case 0x16A66: + case 0x16B56: case 0x1D365: case 0x1D7D4: case 0x1D7DE: case 0x1D7E8: case 0x1D7F2: case 0x1D7FC: + case 0x1E8CC: 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 0x1D36E: return (double) 60.0; case 0x1011E: + case 0x102F8: + case 0x109D7: case 0x10E77: return (double) 600.0; case 0x10127: + case 0x109E0: return (double) 6000.0; case 0x10130: + case 0x109E9: return (double) 60000.0; + case 0x109F2: + return (double) 600000.0; case 0x0037: case 0x0667: case 0x06F7: @@ -3992,6 +5236,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0C6D: case 0x0CED: case 0x0D6D: + case 0x0DED: case 0x0E57: case 0x0ED7: case 0x0F27: @@ -4032,18 +5277,27 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0xA8D7: case 0xA907: case 0xA9D7: + case 0xA9F7: case 0xAA57: case 0xABF7: case 0xFF17: case 0x1010D: + case 0x102E7: case 0x104A7: + case 0x109C6: case 0x10E66: case 0x11058: case 0x1106D: case 0x110F7: case 0x1113D: case 0x111D7: + case 0x111E7: + case 0x112F7: + case 0x114D7: + case 0x11657: case 0x116C7: + case 0x11737: + case 0x118E7: case 0x12405: case 0x1240C: case 0x12412: @@ -4052,15 +5306,21 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x12441: case 0x12442: case 0x12443: + case 0x1246C: + case 0x16A67: + case 0x16B57: case 0x1D366: case 0x1D7D5: case 0x1D7DF: case 0x1D7E9: case 0x1D7F3: case 0x1D7FD: + case 0x1E8CD: 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: @@ -4068,17 +5328,27 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1378: case 0x324E: case 0x10116: + case 0x102F0: + case 0x109CF: case 0x10E6F: case 0x11061: + case 0x111F0: + case 0x118F0: case 0x1D36F: return (double) 70.0; case 0x1011F: + case 0x102F9: + case 0x109D8: case 0x10E78: return (double) 700.0; case 0x10128: + case 0x109E1: return (double) 7000.0; case 0x10131: + case 0x109EA: return (double) 70000.0; + case 0x109F3: + return (double) 700000.0; case 0x0038: case 0x0668: case 0x06F8: @@ -4092,6 +5362,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0C6E: case 0x0CEE: case 0x0D6E: + case 0x0DEE: case 0x0E58: case 0x0ED8: case 0x0F28: @@ -4130,18 +5401,27 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0xA8D8: case 0xA908: case 0xA9D8: + case 0xA9F8: case 0xAA58: case 0xABF8: case 0xFF18: case 0x1010E: + case 0x102E8: case 0x104A8: + case 0x109C7: case 0x10E67: case 0x11059: case 0x1106E: case 0x110F8: case 0x1113E: case 0x111D8: + case 0x111E8: + case 0x112F8: + case 0x114D8: + case 0x11658: case 0x116C8: + case 0x11738: + case 0x118E8: case 0x12406: case 0x1240D: case 0x12413: @@ -4149,28 +5429,43 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1242A: case 0x12444: case 0x12445: + case 0x1246D: + case 0x16A68: + case 0x16B58: case 0x1D367: case 0x1D7D6: case 0x1D7E0: case 0x1D7EA: case 0x1D7F4: case 0x1D7FE: + case 0x1E8CE: 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 0x1D370: return (double) 80.0; case 0x10120: + case 0x102FA: + case 0x109D9: case 0x10E79: return (double) 800.0; case 0x10129: + case 0x109E2: return (double) 8000.0; case 0x10132: + case 0x109EB: return (double) 80000.0; + case 0x109F4: + return (double) 800000.0; case 0x0039: case 0x0669: case 0x06F9: @@ -4184,6 +5479,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x0C6F: case 0x0CEF: case 0x0D6F: + case 0x0DEF: case 0x0E59: case 0x0ED9: case 0x0F29: @@ -4223,18 +5519,27 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0xA8D9: case 0xA909: case 0xA9D9: + case 0xA9F9: case 0xAA59: case 0xABF9: case 0xFF19: case 0x1010F: + case 0x102E9: case 0x104A9: + case 0x109C8: case 0x10E68: case 0x1105A: case 0x1106F: case 0x110F9: case 0x1113F: case 0x111D9: + case 0x111E9: + case 0x112F9: + case 0x114D9: + case 0x11659: case 0x116C9: + case 0x11739: + case 0x118E9: case 0x12407: case 0x1240E: case 0x12414: @@ -4244,32 +5549,47 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x12447: case 0x12448: case 0x12449: + case 0x1246E: + case 0x16A69: + case 0x16B59: case 0x1D368: case 0x1D7D7: case 0x1D7E1: case 0x1D7EB: case 0x1D7F5: case 0x1D7FF: + case 0x1E8CF: 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 0x1D371: return (double) 90.0; case 0x10121: + case 0x102FB: case 0x1034A: + case 0x109DA: case 0x10E7A: return (double) 900.0; case 0x1012A: + case 0x109E3: return (double) 9000.0; case 0x10133: + case 0x109EC: return (double) 90000.0; + case 0x109F5: + return (double) 900000.0; } return -1.0; } diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index c083f8fce5e8..d4d52e60aea8 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -900,11 +900,9 @@ PyObject_ClearWeakRefs(PyObject *object) if (*list != NULL) { PyWeakReference *current = *list; Py_ssize_t count = _PyWeakref_GetWeakrefCount(current); - int restore_error = PyErr_Occurred() ? 1 : 0; PyObject *err_type, *err_value, *err_tb; - if (restore_error) - PyErr_Fetch(&err_type, &err_value, &err_tb); + PyErr_Fetch(&err_type, &err_value, &err_tb); if (count == 1) { PyObject *callback = current->wr_callback; @@ -922,8 +920,7 @@ PyObject_ClearWeakRefs(PyObject *object) tuple = PyTuple_New(count * 2); if (tuple == NULL) { - if (restore_error) - PyErr_Fetch(&err_type, &err_value, &err_tb); + _PyErr_ChainExceptions(err_type, err_value, err_tb); return; } @@ -954,7 +951,7 @@ PyObject_ClearWeakRefs(PyObject *object) } Py_DECREF(tuple); } - if (restore_error) - PyErr_Restore(err_type, err_value, err_tb); + assert(!PyErr_Occurred()); + PyErr_Restore(err_type, err_value, err_tb); } } diff --git a/PC/VS9.0/_bz2.vcproj b/PC/VS9.0/_bz2.vcproj deleted file mode 100644 index 7ceb8c7f089b..000000000000 --- a/PC/VS9.0/_bz2.vcproj +++ /dev/null @@ -1,581 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_ctypes.vcproj b/PC/VS9.0/_ctypes.vcproj deleted file mode 100644 index 8e5cba14fc8d..000000000000 --- a/PC/VS9.0/_ctypes.vcproj +++ /dev/null @@ -1,705 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_ctypes_test.vcproj b/PC/VS9.0/_ctypes_test.vcproj deleted file mode 100644 index 70335462113d..000000000000 --- a/PC/VS9.0/_ctypes_test.vcproj +++ /dev/null @@ -1,521 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_decimal.vcproj b/PC/VS9.0/_decimal.vcproj deleted file mode 100644 index b9fabb0cb95f..000000000000 --- a/PC/VS9.0/_decimal.vcproj +++ /dev/null @@ -1,743 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_elementtree.vcproj b/PC/VS9.0/_elementtree.vcproj deleted file mode 100644 index f9d7375c0c1f..000000000000 --- a/PC/VS9.0/_elementtree.vcproj +++ /dev/null @@ -1,613 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_hashlib.vcproj b/PC/VS9.0/_hashlib.vcproj deleted file mode 100644 index 77417ec0f5f4..000000000000 --- a/PC/VS9.0/_hashlib.vcproj +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_lzma.vcproj b/PC/VS9.0/_lzma.vcproj deleted file mode 100644 index 7c6003f10e2a..000000000000 --- a/PC/VS9.0/_lzma.vcproj +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_msi.vcproj b/PC/VS9.0/_msi.vcproj deleted file mode 100644 index cb230e10d0dc..000000000000 --- a/PC/VS9.0/_msi.vcproj +++ /dev/null @@ -1,529 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_multiprocessing.vcproj b/PC/VS9.0/_multiprocessing.vcproj deleted file mode 100644 index fb3d1e70bcc6..000000000000 --- a/PC/VS9.0/_multiprocessing.vcproj +++ /dev/null @@ -1,541 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_sha3.vcproj b/PC/VS9.0/_sha3.vcproj deleted file mode 100644 index 5fe18d5b5738..000000000000 --- a/PC/VS9.0/_sha3.vcproj +++ /dev/null @@ -1,513 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_socket.vcproj b/PC/VS9.0/_socket.vcproj deleted file mode 100644 index ff1f6d4e3f57..000000000000 --- a/PC/VS9.0/_socket.vcproj +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_sqlite3.vcproj b/PC/VS9.0/_sqlite3.vcproj deleted file mode 100644 index 82c57ae25fd7..000000000000 --- a/PC/VS9.0/_sqlite3.vcproj +++ /dev/null @@ -1,609 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_ssl.vcproj b/PC/VS9.0/_ssl.vcproj deleted file mode 100644 index b47dc2740c5b..000000000000 --- a/PC/VS9.0/_ssl.vcproj +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_testbuffer.vcproj b/PC/VS9.0/_testbuffer.vcproj deleted file mode 100644 index 03377e17721a..000000000000 --- a/PC/VS9.0/_testbuffer.vcproj +++ /dev/null @@ -1,521 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_testcapi.vcproj b/PC/VS9.0/_testcapi.vcproj deleted file mode 100644 index 453300a64271..000000000000 --- a/PC/VS9.0/_testcapi.vcproj +++ /dev/null @@ -1,521 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_testimportmultiple.vcproj b/PC/VS9.0/_testimportmultiple.vcproj deleted file mode 100644 index 14d910dfdf51..000000000000 --- a/PC/VS9.0/_testimportmultiple.vcproj +++ /dev/null @@ -1,521 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/_tkinter.vcproj b/PC/VS9.0/_tkinter.vcproj deleted file mode 100644 index 5163317575c6..000000000000 --- a/PC/VS9.0/_tkinter.vcproj +++ /dev/null @@ -1,541 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/bdist_wininst.vcproj b/PC/VS9.0/bdist_wininst.vcproj deleted file mode 100644 index b8cc7ad6a875..000000000000 --- a/PC/VS9.0/bdist_wininst.vcproj +++ /dev/null @@ -1,270 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/debug.vsprops b/PC/VS9.0/debug.vsprops deleted file mode 100644 index bc643cb6be57..000000000000 --- a/PC/VS9.0/debug.vsprops +++ /dev/null @@ -1,15 +0,0 @@ - - - - - diff --git a/PC/VS9.0/kill_python.c b/PC/VS9.0/kill_python.c deleted file mode 100644 index 604731f3f81c..000000000000 --- a/PC/VS9.0/kill_python.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Helper program for killing lingering python[_d].exe processes before - * building, thus attempting to avoid build failures due to files being - * locked. - */ - -#include -#include -#include -#include - -#pragma comment(lib, "psapi") - -#ifdef _DEBUG -#define PYTHON_EXE (L"python_d.exe") -#define PYTHON_EXE_LEN (12) -#define KILL_PYTHON_EXE (L"kill_python_d.exe") -#define KILL_PYTHON_EXE_LEN (17) -#else -#define PYTHON_EXE (L"python.exe") -#define PYTHON_EXE_LEN (10) -#define KILL_PYTHON_EXE (L"kill_python.exe") -#define KILL_PYTHON_EXE_LEN (15) -#endif - -int -main(int argc, char **argv) -{ - HANDLE hp, hsp, hsm; /* process, snapshot processes, snapshot modules */ - DWORD dac, our_pid; - size_t len; - wchar_t path[MAX_PATH+1]; - - MODULEENTRY32W me; - PROCESSENTRY32W pe; - - me.dwSize = sizeof(MODULEENTRY32W); - pe.dwSize = sizeof(PROCESSENTRY32W); - - memset(path, 0, MAX_PATH+1); - - our_pid = GetCurrentProcessId(); - - hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, our_pid); - if (hsm == INVALID_HANDLE_VALUE) { - printf("CreateToolhelp32Snapshot[1] failed: %d\n", GetLastError()); - return 1; - } - - if (!Module32FirstW(hsm, &me)) { - printf("Module32FirstW[1] failed: %d\n", GetLastError()); - CloseHandle(hsm); - return 1; - } - - /* - * Enumerate over the modules for the current process in order to find - * kill_process[_d].exe, then take a note of the directory it lives in. - */ - do { - if (_wcsnicmp(me.szModule, KILL_PYTHON_EXE, KILL_PYTHON_EXE_LEN)) - continue; - - len = wcsnlen_s(me.szExePath, MAX_PATH) - KILL_PYTHON_EXE_LEN; - wcsncpy_s(path, MAX_PATH+1, me.szExePath, len); - - break; - - } while (Module32NextW(hsm, &me)); - - CloseHandle(hsm); - - if (path == NULL) { - printf("failed to discern directory of running process\n"); - return 1; - } - - /* - * Take a snapshot of system processes. Enumerate over the snapshot, - * looking for python processes. When we find one, verify it lives - * in the same directory we live in. If it does, kill it. If we're - * unable to kill it, treat this as a fatal error and return 1. - * - * The rationale behind this is that we're called at the start of the - * build process on the basis that we'll take care of killing any - * running instances, such that the build won't encounter permission - * denied errors during linking. If we can't kill one of the processes, - * we can't provide this assurance, and the build shouldn't start. - */ - - hsp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if (hsp == INVALID_HANDLE_VALUE) { - printf("CreateToolhelp32Snapshot[2] failed: %d\n", GetLastError()); - return 1; - } - - if (!Process32FirstW(hsp, &pe)) { - printf("Process32FirstW failed: %d\n", GetLastError()); - CloseHandle(hsp); - return 1; - } - - dac = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE; - do { - - /* - * XXX TODO: if we really wanted to be fancy, we could check the - * modules for all processes (not just the python[_d].exe ones) - * and see if any of our DLLs are loaded (i.e. python34[_d].dll), - * as that would also inhibit our ability to rebuild the solution. - * Not worth loosing sleep over though; for now, a simple check - * for just the python executable should be sufficient. - */ - - if (_wcsnicmp(pe.szExeFile, PYTHON_EXE, PYTHON_EXE_LEN)) - /* This isn't a python process. */ - continue; - - /* It's a python process, so figure out which directory it's in... */ - hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pe.th32ProcessID); - if (hsm == INVALID_HANDLE_VALUE) - /* - * If our module snapshot fails (which will happen if we don't own - * the process), just ignore it and continue. (It seems different - * versions of Windows return different values for GetLastError() - * in this situation; it's easier to just ignore it and move on vs. - * stopping the build for what could be a false positive.) - */ - continue; - - if (!Module32FirstW(hsm, &me)) { - printf("Module32FirstW[2] failed: %d\n", GetLastError()); - CloseHandle(hsp); - CloseHandle(hsm); - return 1; - } - - do { - if (_wcsnicmp(me.szModule, PYTHON_EXE, PYTHON_EXE_LEN)) - /* Wrong module, we're looking for python[_d].exe... */ - continue; - - if (_wcsnicmp(path, me.szExePath, len)) - /* Process doesn't live in our directory. */ - break; - - /* Python process residing in the right directory, kill it! */ - hp = OpenProcess(dac, FALSE, pe.th32ProcessID); - if (!hp) { - printf("OpenProcess failed: %d\n", GetLastError()); - CloseHandle(hsp); - CloseHandle(hsm); - return 1; - } - - if (!TerminateProcess(hp, 1)) { - printf("TerminateProcess failed: %d\n", GetLastError()); - CloseHandle(hsp); - CloseHandle(hsm); - CloseHandle(hp); - return 1; - } - - CloseHandle(hp); - break; - - } while (Module32NextW(hsm, &me)); - - CloseHandle(hsm); - - } while (Process32NextW(hsp, &pe)); - - CloseHandle(hsp); - - return 0; -} - -/* vi: set ts=8 sw=4 sts=4 expandtab */ diff --git a/PC/VS9.0/kill_python.vcproj b/PC/VS9.0/kill_python.vcproj deleted file mode 100644 index a34107aab7a2..000000000000 --- a/PC/VS9.0/kill_python.vcproj +++ /dev/null @@ -1,279 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/make_buildinfo.c b/PC/VS9.0/make_buildinfo.c deleted file mode 100644 index fb4a64a97182..000000000000 --- a/PC/VS9.0/make_buildinfo.c +++ /dev/null @@ -1,195 +0,0 @@ -#include -#include -#include -#include -#include - -#define CMD_SIZE 500 - -/* This file creates the getbuildinfo.o object, by first - invoking subwcrev.exe (if found), and then invoking cl.exe. - As a side effect, it might generate PCBuild\getbuildinfo2.c - also. If this isn't a subversion checkout, or subwcrev isn't - found, it compiles ..\\..\\Modules\\getbuildinfo.c instead. - - Currently, subwcrev.exe is found from the registry entries - of TortoiseSVN. - - No attempt is made to place getbuildinfo.o into the proper - binary directory. This isn't necessary, as this tool is - invoked as a pre-link step for pythoncore, so that overwrites - any previous getbuildinfo.o. - - However, if a second argument is provided, this will be used - as a temporary directory where any getbuildinfo2.c and - getbuildinfo.o files are put. This is useful if multiple - configurations are being built in parallel, to avoid them - trampling each other's files. - -*/ - -int make_buildinfo2(const char *tmppath) -{ - struct _stat st; - HKEY hTortoise; - char command[CMD_SIZE+1]; - DWORD type, size; - if (_stat(".svn", &st) < 0) - return 0; - /* Allow suppression of subwcrev.exe invocation if a no_subwcrev file is present. */ - if (_stat("no_subwcrev", &st) == 0) - return 0; - if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\TortoiseSVN", &hTortoise) != ERROR_SUCCESS && - RegOpenKey(HKEY_CURRENT_USER, "Software\\TortoiseSVN", &hTortoise) != ERROR_SUCCESS) - /* Tortoise not installed */ - return 0; - command[0] = '"'; /* quote the path to the executable */ - size = sizeof(command) - 1; - if (RegQueryValueEx(hTortoise, "Directory", 0, &type, command+1, &size) != ERROR_SUCCESS || - type != REG_SZ) - /* Registry corrupted */ - return 0; - strcat_s(command, CMD_SIZE, "bin\\subwcrev.exe"); - if (_stat(command+1, &st) < 0) - /* subwcrev.exe not part of the release */ - return 0; - strcat_s(command, CMD_SIZE, "\" ..\\.. ..\\..\\Modules\\getbuildinfo.c \""); - strcat_s(command, CMD_SIZE, tmppath); /* quoted tmppath */ - strcat_s(command, CMD_SIZE, "getbuildinfo2.c\""); - - puts(command); fflush(stdout); - if (system(command) < 0) - return 0; - return 1; -} - -const char DELIMS[] = { " \n" }; - -int get_mercurial_info(char * hgbranch, char * hgtag, char * hgrev, int size) -{ - int result = 0; - char filename[CMD_SIZE]; - char cmdline[CMD_SIZE]; - - strcpy_s(filename, CMD_SIZE, "tmpXXXXXX"); - if (_mktemp_s(filename, CMD_SIZE) == 0) { - int rc; - - strcpy_s(cmdline, CMD_SIZE, "hg id -bit > "); - strcat_s(cmdline, CMD_SIZE, filename); - rc = system(cmdline); - if (rc == 0) { - FILE * fp; - - if (fopen_s(&fp, filename, "r") == 0) { - char * cp = fgets(cmdline, CMD_SIZE, fp); - - if (cp) { - char * context = NULL; - char * tp = strtok_s(cp, DELIMS, &context); - if (tp) { - strcpy_s(hgrev, size, tp); - tp = strtok_s(NULL, DELIMS, &context); - if (tp) { - strcpy_s(hgbranch, size, tp); - tp = strtok_s(NULL, DELIMS, &context); - if (tp) { - strcpy_s(hgtag, size, tp); - result = 1; - } - } - } - } - fclose(fp); - } - } - _unlink(filename); - } - return result; -} - -int main(int argc, char*argv[]) -{ - char command[CMD_SIZE] = "cl.exe -c -D_WIN32 -DUSE_DL_EXPORT -D_WINDOWS -DWIN32 -D_WINDLL "; - char tmppath[CMD_SIZE] = ""; - int do_unlink, result; - char *tmpdir = NULL; - if (argc <= 2 || argc > 3) { - fprintf(stderr, "make_buildinfo $(ConfigurationName) [tmpdir]\n"); - return EXIT_FAILURE; - } - if (strcmp(argv[1], "Release") == 0) { - strcat_s(command, CMD_SIZE, "-MD "); - } - else if (strcmp(argv[1], "Debug") == 0) { - strcat_s(command, CMD_SIZE, "-D_DEBUG -MDd "); - } - else if (strcmp(argv[1], "ReleaseItanium") == 0) { - strcat_s(command, CMD_SIZE, "-MD /USECL:MS_ITANIUM "); - } - else if (strcmp(argv[1], "ReleaseAMD64") == 0) { - strcat_s(command, CMD_SIZE, "-MD "); - strcat_s(command, CMD_SIZE, "-MD /USECL:MS_OPTERON "); - } - else { - fprintf(stderr, "unsupported configuration %s\n", argv[1]); - return EXIT_FAILURE; - } - if (argc > 2) { - tmpdir = argv[2]; - strcat_s(tmppath, _countof(tmppath), tmpdir); - /* Hack fix for bad command line: If the command is issued like this: - * $(SolutionDir)make_buildinfo.exe" Debug "$(IntDir)" - * we will get a trailing quote because IntDir ends with a backslash that then - * escapes the final ". To simplify the life for developers, catch that problem - * here by cutting it off. - * The proper command line, btw is: - * $(SolutionDir)make_buildinfo.exe" Debug "$(IntDir)\" - * Hooray for command line parsing on windows. - */ - if (strlen(tmppath) > 0 && tmppath[strlen(tmppath)-1] == '"') - tmppath[strlen(tmppath)-1] = '\0'; - strcat_s(tmppath, _countof(tmppath), "\\"); - } - - if ((do_unlink = make_buildinfo2(tmppath))) { - strcat_s(command, CMD_SIZE, "\""); - strcat_s(command, CMD_SIZE, tmppath); - strcat_s(command, CMD_SIZE, "getbuildinfo2.c\" -DSUBWCREV "); - } - else { - char hgtag[CMD_SIZE]; - char hgbranch[CMD_SIZE]; - char hgrev[CMD_SIZE]; - - if (get_mercurial_info(hgbranch, hgtag, hgrev, CMD_SIZE)) { - strcat_s(command, CMD_SIZE, "-DHGBRANCH=\\\""); - strcat_s(command, CMD_SIZE, hgbranch); - strcat_s(command, CMD_SIZE, "\\\""); - - strcat_s(command, CMD_SIZE, " -DHGTAG=\\\""); - strcat_s(command, CMD_SIZE, hgtag); - strcat_s(command, CMD_SIZE, "\\\""); - - strcat_s(command, CMD_SIZE, " -DHGVERSION=\\\""); - strcat_s(command, CMD_SIZE, hgrev); - strcat_s(command, CMD_SIZE, "\\\" "); - } - strcat_s(command, CMD_SIZE, "..\\..\\Modules\\getbuildinfo.c"); - } - strcat_s(command, CMD_SIZE, " -Fo\""); - strcat_s(command, CMD_SIZE, tmppath); - strcat_s(command, CMD_SIZE, "getbuildinfo.o\" -I..\\..\\Include -I..\\..\\PC"); - puts(command); fflush(stdout); - result = system(command); - if (do_unlink) { - command[0] = '\0'; - strcat_s(command, CMD_SIZE, "\""); - strcat_s(command, CMD_SIZE, tmppath); - strcat_s(command, CMD_SIZE, "getbuildinfo2.c\""); - _unlink(command); - } - if (result < 0) - return EXIT_FAILURE; - return 0; -} diff --git a/PC/VS9.0/make_buildinfo.vcproj b/PC/VS9.0/make_buildinfo.vcproj deleted file mode 100644 index 924065db42bc..000000000000 --- a/PC/VS9.0/make_buildinfo.vcproj +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/make_versioninfo.vcproj b/PC/VS9.0/make_versioninfo.vcproj deleted file mode 100644 index 0a1fd28bc41d..000000000000 --- a/PC/VS9.0/make_versioninfo.vcproj +++ /dev/null @@ -1,324 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/pcbuild.sln b/PC/VS9.0/pcbuild.sln deleted file mode 100644 index 3b73fce490c8..000000000000 --- a/PC/VS9.0/pcbuild.sln +++ /dev/null @@ -1,692 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058} = {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_versioninfo", "make_versioninfo.vcproj", "{F0E0541E-F17D-430B-97C4-93ADF0DD284E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}" - ProjectSection(ProjectDependencies) = postProject - {F0E0541E-F17D-430B-97C4-93ADF0DD284E} = {F0E0541E-F17D-430B-97C4-93ADF0DD284E} - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31} - {C73F0EC1-358B-4177-940F-0846AC8B04CD} = {C73F0EC1-358B-4177-940F-0846AC8B04CD} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonw", "pythonw.vcproj", "{F4229CC3-873C-49AE-9729-DD308ED4CD4A}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_buildinfo", "make_buildinfo.vcproj", "{C73F0EC1-358B-4177-940F-0846AC8B04CD}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{553EC33E-9816-4996-A660-5D6186A0B0B3}" - ProjectSection(SolutionItems) = preProject - ..\..\Modules\getbuildinfo.c = ..\..\Modules\getbuildinfo.c - readme.txt = readme.txt - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winsound", "winsound.vcproj", "{28B5D777-DDF2-4B6B-B34F-31D938813856}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_decimal", "_decimal.vcproj", "{0E9791DB-593A-465F-98BC-681011311617}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ctypes", "_ctypes.vcproj", "{0E9791DB-593A-465F-98BC-681011311618}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ctypes_test", "_ctypes_test.vcproj", "{9EC7190A-249F-4180-A900-548FDCF3055F}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_elementtree", "_elementtree.vcproj", "{17E1E049-C309-4D79-843F-AE483C264AEA}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_msi", "_msi.vcproj", "{31FFC478-7B4A-43E8-9954-8D03E2187E9C}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_socket", "_socket.vcproj", "{86937F53-C189-40EF-8CE8-8759D8E7D480}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_sqlite3", "_sqlite3.vcproj", "{13CECB97-4119-4316-9D42-8534019A5A44}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - {A1A295E5-463C-437F-81CA-1F32367685DA} = {A1A295E5-463C-437F-81CA-1F32367685DA} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ssl", "_ssl.vcproj", "{C6E20F84-3247-4AD6-B051-B073268F73BA}" - ProjectSection(ProjectDependencies) = postProject - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} = {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} - {86937F53-C189-40EF-8CE8-8759D8E7D480} = {86937F53-C189-40EF-8CE8-8759D8E7D480} - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0} = {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0} - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testcapi", "_testcapi.vcproj", "{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testimportmultiple", "_testimportmultiple.vcproj", "{36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_tkinter", "_tkinter.vcproj", "{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_bz2", "_bz2.vcproj", "{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_lzma", "_lzma.vcproj", "{F9D71780-F393-11E0-BE50-0800200C9A66}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "select", "select.vcproj", "{18CAE28C-B454-46C1-87A0-493D91D97F03}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unicodedata", "unicodedata.vcproj", "{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyexpat", "pyexpat.vcproj", "{D06B6426-4762-44CC-8BAD-D79052507F2F}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bdist_wininst", "bdist_wininst.vcproj", "{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_hashlib", "_hashlib.vcproj", "{447F05A8-F581-4CAC-A466-5AC7936E207E}" - ProjectSection(ProjectDependencies) = postProject - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} = {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0} = {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0} - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite3", "sqlite3.vcproj", "{A1A295E5-463C-437F-81CA-1F32367685DA}" - ProjectSection(ProjectDependencies) = postProject - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31} = {6DE10744-E396-40A5-B4E2-1B69AA7C8D31} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_multiprocessing", "_multiprocessing.vcproj", "{9E48B300-37D1-11DD-8C41-005056C00008}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssl", "ssl.vcproj", "{E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}" - ProjectSection(ProjectDependencies) = postProject - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} = {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kill_python", "kill_python.vcproj", "{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python3dll", "python3dll.vcproj", "{885D4898-D08D-4091-9C40-C700CFE3FC5A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xxlimited", "xxlimited.vcproj", "{F749B822-B489-4CA5-A3AD-CE078F5F338A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testbuffer", "_testbuffer.vcproj", "{A2697BD3-28C1-4AEC-9106-8B748639FD16}" - ProjectSection(ProjectDependencies) = postProject - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} = {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_sha3", "_sha3.vcproj", "{04F37400-883C-42D7-AE28-6CF9953BF975}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - PGInstrument|Win32 = PGInstrument|Win32 - PGInstrument|x64 = PGInstrument|x64 - PGUpdate|Win32 = PGUpdate|Win32 - PGUpdate|x64 = PGUpdate|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|Win32.ActiveCfg = Debug|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|Win32.Build.0 = Debug|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.ActiveCfg = Debug|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.Build.0 = Debug|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.ActiveCfg = Release|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.Build.0 = Release|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.ActiveCfg = Release|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.Build.0 = Release|x64 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|Win32.ActiveCfg = Debug|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|Win32.Build.0 = Debug|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|x64.ActiveCfg = Debug|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|x64.Build.0 = Debug|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|Win32.Build.0 = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|x64.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|x64.Build.0 = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|Win32.Build.0 = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|x64.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|x64.Build.0 = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|Win32.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|Win32.Build.0 = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|x64.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|x64.Build.0 = Release|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.ActiveCfg = Debug|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.Build.0 = Debug|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|x64.ActiveCfg = Debug|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|x64.Build.0 = Debug|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|Win32.ActiveCfg = Release|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|Win32.Build.0 = Release|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|x64.ActiveCfg = Release|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|x64.Build.0 = Release|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|Win32.ActiveCfg = Debug|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|Win32.Build.0 = Debug|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.ActiveCfg = Debug|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.Build.0 = Debug|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.ActiveCfg = Release|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.Build.0 = Release|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.ActiveCfg = Release|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.Build.0 = Release|x64 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug|Win32.ActiveCfg = Debug|Win32 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug|Win32.Build.0 = Debug|Win32 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug|x64.ActiveCfg = Debug|x64 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Debug|x64.Build.0 = Debug|x64 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release|Win32.ActiveCfg = Release|Win32 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release|Win32.Build.0 = Release|Win32 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release|x64.ActiveCfg = Release|x64 - {E9E0A1F6-0009-4E8C-B8F8-1B8F5D49A058}.Release|x64.Build.0 = Release|x64 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|Win32.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|Win32.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|x64.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|x64.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|Win32.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|x64.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|x64.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|Win32.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|x64.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|x64.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|Win32.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|Win32.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|x64.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|x64.Build.0 = Release|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|Win32.ActiveCfg = Debug|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|Win32.Build.0 = Debug|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|x64.ActiveCfg = Debug|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|x64.Build.0 = Debug|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|Win32.ActiveCfg = Release|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|Win32.Build.0 = Release|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|x64.ActiveCfg = Release|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|x64.Build.0 = Release|x64 - {0E9791DB-593A-465F-98BC-681011311617}.Debug|Win32.ActiveCfg = Debug|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.Debug|Win32.Build.0 = Debug|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.Debug|x64.ActiveCfg = Debug|x64 - {0E9791DB-593A-465F-98BC-681011311617}.Debug|x64.Build.0 = Debug|x64 - {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {0E9791DB-593A-465F-98BC-681011311617}.Release|Win32.ActiveCfg = Release|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.Release|Win32.Build.0 = Release|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.Release|x64.ActiveCfg = Release|x64 - {0E9791DB-593A-465F-98BC-681011311617}.Release|x64.Build.0 = Release|x64 - {0E9791DB-593A-465F-98BC-681011311618}.Debug|Win32.ActiveCfg = Debug|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.Debug|Win32.Build.0 = Debug|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.Debug|x64.ActiveCfg = Debug|x64 - {0E9791DB-593A-465F-98BC-681011311618}.Debug|x64.Build.0 = Debug|x64 - {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {0E9791DB-593A-465F-98BC-681011311618}.Release|Win32.ActiveCfg = Release|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.Release|Win32.Build.0 = Release|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.Release|x64.ActiveCfg = Release|x64 - {0E9791DB-593A-465F-98BC-681011311618}.Release|x64.Build.0 = Release|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|Win32.ActiveCfg = Debug|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|Win32.Build.0 = Debug|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|x64.ActiveCfg = Debug|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|x64.Build.0 = Debug|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|Win32.ActiveCfg = Release|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|Win32.Build.0 = Release|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|x64.ActiveCfg = Release|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|x64.Build.0 = Release|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|Win32.ActiveCfg = Debug|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|Win32.Build.0 = Debug|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|x64.ActiveCfg = Debug|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|x64.Build.0 = Debug|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|Win32.ActiveCfg = Release|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|Win32.Build.0 = Release|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.ActiveCfg = Release|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.Build.0 = Release|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|Win32.ActiveCfg = Debug|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|Win32.Build.0 = Debug|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|x64.ActiveCfg = Debug|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|x64.Build.0 = Debug|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|Win32.ActiveCfg = Release|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|Win32.Build.0 = Release|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|x64.ActiveCfg = Release|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|x64.Build.0 = Release|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|Win32.ActiveCfg = Debug|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|Win32.Build.0 = Debug|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|x64.ActiveCfg = Debug|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|x64.Build.0 = Debug|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|Win32.ActiveCfg = Release|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|Win32.Build.0 = Release|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|x64.ActiveCfg = Release|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|x64.Build.0 = Release|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|Win32.ActiveCfg = Debug|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|Win32.Build.0 = Debug|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|x64.ActiveCfg = Debug|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|x64.Build.0 = Debug|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.Release|Win32.ActiveCfg = Release|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.Release|Win32.Build.0 = Release|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.Release|x64.ActiveCfg = Release|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.Release|x64.Build.0 = Release|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|Win32.ActiveCfg = Debug|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|Win32.Build.0 = Debug|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|x64.ActiveCfg = Debug|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|x64.Build.0 = Debug|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|Win32.ActiveCfg = Release|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|Win32.Build.0 = Release|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|x64.ActiveCfg = Release|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|x64.Build.0 = Release|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|Win32.ActiveCfg = Debug|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|Win32.Build.0 = Debug|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|x64.ActiveCfg = Debug|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|x64.Build.0 = Debug|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|Win32.ActiveCfg = Release|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|Win32.Build.0 = Release|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.ActiveCfg = Release|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.Build.0 = Release|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|Win32.ActiveCfg = Debug|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|Win32.Build.0 = Debug|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|x64.ActiveCfg = Debug|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|x64.Build.0 = Debug|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|Win32.ActiveCfg = Release|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|Win32.Build.0 = Release|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|x64.ActiveCfg = Release|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|x64.Build.0 = Release|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.ActiveCfg = Debug|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.Build.0 = Debug|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|x64.ActiveCfg = Debug|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|x64.Build.0 = Debug|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|Win32.ActiveCfg = Release|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|Win32.Build.0 = Release|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|x64.ActiveCfg = Release|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|x64.Build.0 = Release|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|Win32.ActiveCfg = Debug|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|Win32.Build.0 = Debug|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|x64.ActiveCfg = Debug|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|x64.Build.0 = Debug|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|Win32.ActiveCfg = Release|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|Win32.Build.0 = Release|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|x64.ActiveCfg = Release|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|x64.Build.0 = Release|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|Win32.ActiveCfg = Debug|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|Win32.Build.0 = Debug|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|x64.ActiveCfg = Debug|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|x64.Build.0 = Debug|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|Win32.ActiveCfg = Release|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|Win32.Build.0 = Release|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|x64.ActiveCfg = Release|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|x64.Build.0 = Release|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|Win32.ActiveCfg = Debug|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|Win32.Build.0 = Debug|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|x64.ActiveCfg = Debug|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|x64.Build.0 = Debug|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|Win32.ActiveCfg = Release|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|Win32.Build.0 = Release|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|x64.ActiveCfg = Release|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|x64.Build.0 = Release|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|Win32.ActiveCfg = Debug|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|Win32.Build.0 = Debug|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|x64.ActiveCfg = Debug|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|x64.Build.0 = Debug|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|Win32.ActiveCfg = Release|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|Win32.Build.0 = Release|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|x64.ActiveCfg = Release|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|x64.Build.0 = Release|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|Win32.ActiveCfg = Debug|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|Win32.Build.0 = Debug|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|x64.ActiveCfg = Debug|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|x64.Build.0 = Debug|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.ActiveCfg = Release|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.Build.0 = Release|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.ActiveCfg = Release|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.Build.0 = Release|x64 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|Win32.ActiveCfg = Release|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|x64.ActiveCfg = Release|x64 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|x64.ActiveCfg = Release|x64 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|x64.ActiveCfg = Release|x64 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|Win32.ActiveCfg = Release|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|x64.ActiveCfg = Release|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.ActiveCfg = Debug|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.Build.0 = Debug|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.ActiveCfg = Debug|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.Build.0 = Debug|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|Win32.ActiveCfg = Release|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|Win32.Build.0 = Release|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|x64.ActiveCfg = Release|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|x64.Build.0 = Release|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|Win32.ActiveCfg = Debug|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|Win32.Build.0 = Debug|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|x64.ActiveCfg = Debug|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|x64.Build.0 = Debug|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|Win32.ActiveCfg = Release|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|Win32.Build.0 = Release|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|x64.ActiveCfg = Release|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|x64.Build.0 = Release|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|Win32.ActiveCfg = Debug|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|Win32.Build.0 = Debug|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|x64.ActiveCfg = Debug|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|x64.Build.0 = Debug|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.ActiveCfg = Release|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.Build.0 = Release|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.ActiveCfg = Release|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.Build.0 = Release|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|Win32.ActiveCfg = Debug|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|Win32.Build.0 = Debug|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|x64.ActiveCfg = Debug|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|x64.Build.0 = Debug|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|Win32.ActiveCfg = Release|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|Win32.Build.0 = Release|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|x64.ActiveCfg = Release|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|x64.Build.0 = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|Win32.ActiveCfg = Debug|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|Win32.Build.0 = Debug|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|x64.ActiveCfg = Debug|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|x64.Build.0 = Debug|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|Win32.Build.0 = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|x64.ActiveCfg = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|x64.Build.0 = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|Win32.Build.0 = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|x64.ActiveCfg = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|x64.Build.0 = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|Win32.ActiveCfg = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|Win32.Build.0 = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.ActiveCfg = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.Build.0 = Release|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.ActiveCfg = PGInstrument|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.ActiveCfg = PGUpdate|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.Build.0 = PGUpdate|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.ActiveCfg = Release|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.Build.0 = Release|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|x64.ActiveCfg = Release|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|x64.Build.0 = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|Win32.ActiveCfg = Debug|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|Win32.Build.0 = Debug|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|x64.ActiveCfg = Debug|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|x64.Build.0 = Debug|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|Win32.Build.0 = Release|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|x64.ActiveCfg = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|x64.Build.0 = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|Win32.Build.0 = Release|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|x64.ActiveCfg = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|x64.Build.0 = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|Win32.ActiveCfg = Release|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|Win32.Build.0 = Release|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|x64.ActiveCfg = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|x64.Build.0 = Release|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|Win32.ActiveCfg = Debug|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|Win32.Build.0 = Debug|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|x64.ActiveCfg = Debug|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|x64.Build.0 = Debug|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|Win32.ActiveCfg = Release|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|Win32.Build.0 = Release|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|x64.ActiveCfg = Release|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|x64.Build.0 = Release|x64 - {04F37400-883C-42D7-AE28-6CF9953BF975}.Debug|Win32.ActiveCfg = Debug|Win32 - {04F37400-883C-42D7-AE28-6CF9953BF975}.Debug|Win32.Build.0 = Debug|Win32 - {04F37400-883C-42D7-AE28-6CF9953BF975}.Debug|x64.ActiveCfg = Debug|x64 - {04F37400-883C-42D7-AE28-6CF9953BF975}.Debug|x64.Build.0 = Debug|x64 - {04F37400-883C-42D7-AE28-6CF9953BF975}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {04F37400-883C-42D7-AE28-6CF9953BF975}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {04F37400-883C-42D7-AE28-6CF9953BF975}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {04F37400-883C-42D7-AE28-6CF9953BF975}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {04F37400-883C-42D7-AE28-6CF9953BF975}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {04F37400-883C-42D7-AE28-6CF9953BF975}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {04F37400-883C-42D7-AE28-6CF9953BF975}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {04F37400-883C-42D7-AE28-6CF9953BF975}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {04F37400-883C-42D7-AE28-6CF9953BF975}.Release|Win32.ActiveCfg = Release|Win32 - {04F37400-883C-42D7-AE28-6CF9953BF975}.Release|Win32.Build.0 = Release|Win32 - {04F37400-883C-42D7-AE28-6CF9953BF975}.Release|x64.ActiveCfg = Release|x64 - {04F37400-883C-42D7-AE28-6CF9953BF975}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/PC/VS9.0/pginstrument.vsprops b/PC/VS9.0/pginstrument.vsprops deleted file mode 100644 index 99c117b15267..000000000000 --- a/PC/VS9.0/pginstrument.vsprops +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - diff --git a/PC/VS9.0/pgupdate.vsprops b/PC/VS9.0/pgupdate.vsprops deleted file mode 100644 index 26cfc2d0dd9c..000000000000 --- a/PC/VS9.0/pgupdate.vsprops +++ /dev/null @@ -1,14 +0,0 @@ - - - - diff --git a/PC/VS9.0/pyd.vsprops b/PC/VS9.0/pyd.vsprops deleted file mode 100644 index 34c21e15c5e6..000000000000 --- a/PC/VS9.0/pyd.vsprops +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - diff --git a/PC/VS9.0/pyd_d.vsprops b/PC/VS9.0/pyd_d.vsprops deleted file mode 100644 index 313a30b782fd..000000000000 --- a/PC/VS9.0/pyd_d.vsprops +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - diff --git a/PC/VS9.0/pyexpat.vcproj b/PC/VS9.0/pyexpat.vcproj deleted file mode 100644 index a8d2cd752728..000000000000 --- a/PC/VS9.0/pyexpat.vcproj +++ /dev/null @@ -1,553 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/pyproject.vsprops b/PC/VS9.0/pyproject.vsprops deleted file mode 100644 index ed5464d202e9..000000000000 --- a/PC/VS9.0/pyproject.vsprops +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/python.vcproj b/PC/VS9.0/python.vcproj deleted file mode 100644 index b07de2183ff1..000000000000 --- a/PC/VS9.0/python.vcproj +++ /dev/null @@ -1,637 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/python3dll.vcproj b/PC/VS9.0/python3dll.vcproj deleted file mode 100644 index ed7333bc5677..000000000000 --- a/PC/VS9.0/python3dll.vcproj +++ /dev/null @@ -1,246 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/pythoncore.vcproj b/PC/VS9.0/pythoncore.vcproj deleted file mode 100644 index cf60470ce2c3..000000000000 --- a/PC/VS9.0/pythoncore.vcproj +++ /dev/null @@ -1,1877 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/pythonw.vcproj b/PC/VS9.0/pythonw.vcproj deleted file mode 100644 index 7f5c04b9b554..000000000000 --- a/PC/VS9.0/pythonw.vcproj +++ /dev/null @@ -1,618 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/release.vsprops b/PC/VS9.0/release.vsprops deleted file mode 100644 index 08def90651b0..000000000000 --- a/PC/VS9.0/release.vsprops +++ /dev/null @@ -1,15 +0,0 @@ - - - - - diff --git a/PC/VS9.0/select.vcproj b/PC/VS9.0/select.vcproj deleted file mode 100644 index 637fd972ce0e..000000000000 --- a/PC/VS9.0/select.vcproj +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/sqlite3.vcproj b/PC/VS9.0/sqlite3.vcproj deleted file mode 100644 index ef8c328c6992..000000000000 --- a/PC/VS9.0/sqlite3.vcproj +++ /dev/null @@ -1,537 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/sqlite3.vsprops b/PC/VS9.0/sqlite3.vsprops deleted file mode 100644 index b502df5ace36..000000000000 --- a/PC/VS9.0/sqlite3.vsprops +++ /dev/null @@ -1,14 +0,0 @@ - - - - diff --git a/PC/VS9.0/ssl.vcproj b/PC/VS9.0/ssl.vcproj deleted file mode 100644 index d30e877024f6..000000000000 --- a/PC/VS9.0/ssl.vcproj +++ /dev/null @@ -1,189 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/unicodedata.vcproj b/PC/VS9.0/unicodedata.vcproj deleted file mode 100644 index b66ff72228fb..000000000000 --- a/PC/VS9.0/unicodedata.vcproj +++ /dev/null @@ -1,533 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/winsound.vcproj b/PC/VS9.0/winsound.vcproj deleted file mode 100644 index 47dbf29322c9..000000000000 --- a/PC/VS9.0/winsound.vcproj +++ /dev/null @@ -1,523 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/VS9.0/x64.vsprops b/PC/VS9.0/x64.vsprops deleted file mode 100644 index d06f470cebad..000000000000 --- a/PC/VS9.0/x64.vsprops +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - diff --git a/PC/VS9.0/xxlimited.vcproj b/PC/VS9.0/xxlimited.vcproj deleted file mode 100644 index a3aaad65836e..000000000000 --- a/PC/VS9.0/xxlimited.vcproj +++ /dev/null @@ -1,417 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/_msi.c b/PC/_msi.c index 6a99b40cda8d..86a594310644 100644 --- a/PC/_msi.c +++ b/PC/_msi.c @@ -243,8 +243,13 @@ static PyObject* fcicreate(PyObject* obj, PyObject* args) for (i=0; i < PyList_GET_SIZE(files); i++) { PyObject *item = PyList_GET_ITEM(files, i); char *filename, *cabname; - if (!PyArg_ParseTuple(item, "ss", &filename, &cabname)) - goto err; + + if (!PyArg_ParseTuple(item, "ss", &filename, &cabname)) { + PyErr_SetString(PyExc_TypeError, "FCICreate expects a list of tuples containing two strings"); + FCIDestroy(hfci); + return NULL; + } + if (!FCIAddFile(hfci, filename, cabname, FALSE, cb_getnextcabinet, cb_status, cb_getopeninfo, tcompTYPE_MSZIP)) @@ -260,7 +265,11 @@ static PyObject* fcicreate(PyObject* obj, PyObject* args) Py_INCREF(Py_None); return Py_None; err: - PyErr_Format(PyExc_ValueError, "FCI error %d", erf.erfOper); /* XXX better error type */ + if(erf.fError) + PyErr_Format(PyExc_ValueError, "FCI error %d", erf.erfOper); /* XXX better error type */ + else + PyErr_SetString(PyExc_ValueError, "FCI general error"); + FCIDestroy(hfci); return NULL; } diff --git a/PC/bdist_wininst/archive.h b/PC/bdist_wininst/archive.h index 31a7805fd1d0..50ff15cdddf0 100644 --- a/PC/bdist_wininst/archive.h +++ b/PC/bdist_wininst/archive.h @@ -1,10 +1,9 @@ /* - IMPORTANT NOTE: IF THIS FILE IS CHANGED, WININST-6.EXE MUST BE RECOMPILED - WITH THE MSVC6 WININST.DSW WORKSPACE FILE MANUALLY, AND WININST-7.1.EXE MUST - BE RECOMPILED WITH THE MSVC 2003.NET WININST-7.1.VCPROJ FILE MANUALLY. + IMPORTANT NOTE: IF THIS FILE IS CHANGED, PCBUILD\BDIST_WININST.VCXPROJ MUST + BE REBUILT AS WELL. - IF CHANGES TO THIS FILE ARE CHECKED INTO PYTHON CVS, THE RECOMPILED BINARIES - MUST BE CHECKED IN AS WELL! + IF CHANGES TO THIS FILE ARE CHECKED IN, THE RECOMPILED BINARIES MUST BE + CHECKED IN AS WELL! */ #pragma pack(1) diff --git a/PC/bdist_wininst/bdist_wininst.vcxproj b/PC/bdist_wininst/bdist_wininst.vcxproj new file mode 100644 index 000000000000..2ab474e43967 --- /dev/null +++ b/PC/bdist_wininst/bdist_wininst.vcxproj @@ -0,0 +1,103 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Release + Win32 + + + Release + x64 + + + + {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C} + wininst + ClCompile + false + + + + + Application + false + NotSet + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(PySourcePath)lib\distutils\command\ + false + wininst-$(VisualStudioVersion) + $(TargetName)-amd64 + .exe + + + + $(OutDir)wininst.tlb + + + MinSpace + $(PySourcePath)Modules\zlib;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) + + + $(PySourcePath)PC\bdist_wininst;%(AdditionalIncludeDirectories) + + + comctl32.lib;imagehlp.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/bdist_wininst.vcxproj.filters b/PC/bdist_wininst/bdist_wininst.vcxproj.filters similarity index 100% rename from PCbuild/bdist_wininst.vcxproj.filters rename to PC/bdist_wininst/bdist_wininst.vcxproj.filters diff --git a/PC/bdist_wininst/build.bat b/PC/bdist_wininst/build.bat new file mode 100644 index 000000000000..25f565ce0a16 --- /dev/null +++ b/PC/bdist_wininst/build.bat @@ -0,0 +1,22 @@ +@echo off +setlocal + +set D=%~dp0 +set PCBUILD=%~dp0..\..\PCBuild\ + + +echo Building Lib\distutils\command\wininst-xx.0.exe + +call "%PCBUILD%env.bat" x86 +if errorlevel 1 goto :eof + +msbuild "%D%bdist_wininst.vcxproj" "/p:SolutionDir=%PCBUILD%\" /p:Configuration=Release /p:Platform=Win32 +if errorlevel 1 goto :eof + + +echo Building Lib\distutils\command\wininst-xx.0-amd64.exe + +call "%PCBUILD%env.bat" x86_amd64 +if errorlevel 1 goto :eof + +msbuild "%D%bdist_wininst.vcxproj" "/p:SolutionDir=%PCBUILD%\" /p:Configuration=Release /p:Platform=x64 diff --git a/PC/bdist_wininst/extract.c b/PC/bdist_wininst/extract.c index aec8eda2be85..0249d9ff542f 100644 --- a/PC/bdist_wininst/extract.c +++ b/PC/bdist_wininst/extract.c @@ -1,10 +1,9 @@ /* - IMPORTANT NOTE: IF THIS FILE IS CHANGED, WININST-6.EXE MUST BE RECOMPILED - WITH THE MSVC6 WININST.DSW WORKSPACE FILE MANUALLY, AND WININST-7.1.EXE MUST - BE RECOMPILED WITH THE MSVC 2003.NET WININST-7.1.VCPROJ FILE MANUALLY. + IMPORTANT NOTE: IF THIS FILE IS CHANGED, PCBUILD\BDIST_WININST.VCXPROJ MUST + BE REBUILT AS WELL. - IF CHANGES TO THIS FILE ARE CHECKED INTO PYTHON CVS, THE RECOMPILED BINARIES - MUST BE CHECKED IN AS WELL! + IF CHANGES TO THIS FILE ARE CHECKED IN, THE RECOMPILED BINARIES MUST BE + CHECKED IN AS WELL! */ #include diff --git a/PC/bdist_wininst/install.c b/PC/bdist_wininst/install.c index e9401d9f3f57..f39b3819dc08 100644 --- a/PC/bdist_wininst/install.c +++ b/PC/bdist_wininst/install.c @@ -1,10 +1,9 @@ /* - IMPORTANT NOTE: IF THIS FILE IS CHANGED, WININST-6.EXE MUST BE RECOMPILED - WITH THE MSVC6 WININST.DSW WORKSPACE FILE MANUALLY, AND WININST-7.1.EXE MUST - BE RECOMPILED WITH THE MSVC 2003.NET WININST-7.1.VCPROJ FILE MANUALLY. + IMPORTANT NOTE: IF THIS FILE IS CHANGED, PCBUILD\BDIST_WININST.VCXPROJ MUST + BE REBUILT AS WELL. - IF CHANGES TO THIS FILE ARE CHECKED INTO PYTHON CVS, THE RECOMPILED BINARIES - MUST BE CHECKED IN AS WELL! + IF CHANGES TO THIS FILE ARE CHECKED IN, THE RECOMPILED BINARIES MUST BE + CHECKED IN AS WELL! */ /* @@ -1216,7 +1215,7 @@ static void CenterWindow(HWND hwnd) #include -BOOL CALLBACK +INT_PTR CALLBACK IntroDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { LPNMHDR lpnm; @@ -1565,7 +1564,7 @@ SCHEME *GetScheme(int major, int minor) return old_scheme; } -BOOL CALLBACK +INT_PTR CALLBACK SelectPythonDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { LPNMHDR lpnm; @@ -1774,6 +1773,16 @@ static BOOL OpenLogfile(char *dir) sprintf(buffer, "%s\\%s-wininst.log", dir, meta_name); logfile = fopen(buffer, "a"); + if (!logfile) { + char error[1024]; + + sprintf(error, "Can't create \"%s\" (%s).\n\n" + "Try to execute the installer as administrator.", + buffer, strerror(errno)); + MessageBox(GetFocus(), error, NULL, MB_OK | MB_ICONSTOP); + return FALSE; + } + time(<ime); now = localtime(<ime); strftime(buffer, sizeof(buffer), @@ -1857,7 +1866,7 @@ static void CloseLogfile(void) fclose(logfile); } -BOOL CALLBACK +INT_PTR CALLBACK InstallFilesDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { LPNMHDR lpnm; @@ -1931,21 +1940,21 @@ InstallFilesDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) /* * The scheme we have to use depends on the Python version... if sys.version < "2.2": - WINDOWS_SCHEME = { - 'purelib': '$base', - 'platlib': '$base', - 'headers': '$base/Include/$dist_name', - 'scripts': '$base/Scripts', - 'data' : '$base', - } + WINDOWS_SCHEME = { + 'purelib': '$base', + 'platlib': '$base', + 'headers': '$base/Include/$dist_name', + 'scripts': '$base/Scripts', + 'data' : '$base', + } else: - WINDOWS_SCHEME = { - 'purelib': '$base/Lib/site-packages', - 'platlib': '$base/Lib/site-packages', - 'headers': '$base/Include/$dist_name', - 'scripts': '$base/Scripts', - 'data' : '$base', - } + WINDOWS_SCHEME = { + 'purelib': '$base/Lib/site-packages', + 'platlib': '$base/Lib/site-packages', + 'headers': '$base/Include/$dist_name', + 'scripts': '$base/Scripts', + 'data' : '$base', + } */ scheme = GetScheme(py_major, py_minor); /* Run the pre-install script. */ @@ -2012,7 +2021,7 @@ InstallFilesDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) } -BOOL CALLBACK +INT_PTR CALLBACK FinishedDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { LPNMHDR lpnm; @@ -2188,23 +2197,6 @@ BOOL NeedAutoUAC() return TRUE; } -// Returns TRUE if the platform supports UAC. -BOOL PlatformSupportsUAC() -{ - // Note that win2k does seem to support ShellExecute with 'runas', - // but does *not* support IsUserAnAdmin - so we just pretend things - // only work on XP and later. - BOOL bIsWindowsXPorLater; - OSVERSIONINFO winverinfo; - winverinfo.dwOSVersionInfoSize = sizeof(winverinfo); - if (!GetVersionEx(&winverinfo)) - return FALSE; // something bad has gone wrong - bIsWindowsXPorLater = - ( (winverinfo.dwMajorVersion > 5) || - ( (winverinfo.dwMajorVersion == 5) && (winverinfo.dwMinorVersion >= 1) )); - return bIsWindowsXPorLater; -} - // Spawn ourself as an elevated application. On failure, a message is // displayed to the user - but this app will always terminate, even // on error. @@ -2260,7 +2252,7 @@ int DoInstall(void) // See if we need to do the Vista UAC magic. if (strcmp(user_access_control, "force")==0) { - if (PlatformSupportsUAC() && !MyIsUserAnAdmin()) { + if (!MyIsUserAnAdmin()) { SpawnUAC(); return 0; } @@ -2268,7 +2260,7 @@ int DoInstall(void) } else if (strcmp(user_access_control, "auto")==0) { // Check if it looks like we need UAC control, based // on how Python itself was installed. - if (PlatformSupportsUAC() && !MyIsUserAnAdmin() && NeedAutoUAC()) { + if (!MyIsUserAnAdmin() && NeedAutoUAC()) { SpawnUAC(); return 0; } diff --git a/PC/bdist_wininst/install.rc b/PC/bdist_wininst/install.rc index d018b484b0a9..dfa2ffcd7415 100644 --- a/PC/bdist_wininst/install.rc +++ b/PC/bdist_wininst/install.rc @@ -1,97 +1,20 @@ /* - IMPORTANT NOTE: IF THIS FILE IS CHANGED, WININST-6.EXE MUST BE RECOMPILED - WITH THE MSVC6 WININST.DSW WORKSPACE FILE MANUALLY, AND WININST-7.1.EXE MUST - BE RECOMPILED WITH THE MSVC 2003.NET WININST-7.1.VCPROJ FILE MANUALLY. + IMPORTANT NOTE: IF THIS FILE IS CHANGED, PCBUILD\BDIST_WININST.VCXPROJ MUST + BE REBUILT AS WELL. - IF CHANGES TO THIS FILE ARE CHECKED INTO PYTHON CVS, THE RECOMPILED BINARIES - MUST BE CHECKED IN AS WELL! + IF CHANGES TO THIS FILE ARE CHECKED IN, THE RECOMPILED BINARIES MUST BE + CHECKED IN AS WELL! */ -//Microsoft Developer Studio generated resource script. -// +#include #include "resource.h" -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Neutral resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) -#ifdef _WIN32 LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL #pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Bitmap -// IDB_BITMAP BITMAP DISCARDABLE "PythonPowered.bmp" -#endif // Neutral resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// German (Germany) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) -#ifdef _WIN32 -LANGUAGE LANG_GERMAN, SUBLANG_GERMAN -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE DISCARDABLE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE DISCARDABLE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE DISCARDABLE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // German (Germany) resources -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - IDD_INTRO DIALOGEX 0, 0, 379, 178 STYLE WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Setup" @@ -152,78 +75,3 @@ BEGIN EDITTEXT IDC_INFO,125,40,247,131,ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_HSCROLL | NOT WS_TABSTOP END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO DISCARDABLE -BEGIN - IDD_INTRO, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 372 - VERTGUIDE, 125 - VERTGUIDE, 372 - TOPMARGIN, 7 - BOTTOMMARGIN, 171 - HORZGUIDE, 8 - HORZGUIDE, 31 - END - - IDD_SELECTPYTHON, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 372 - VERTGUIDE, 125 - VERTGUIDE, 372 - TOPMARGIN, 7 - BOTTOMMARGIN, 171 - HORZGUIDE, 8 - HORZGUIDE, 41 - END - - IDD_INSTALLFILES, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 372 - VERTGUIDE, 125 - VERTGUIDE, 371 - TOPMARGIN, 7 - BOTTOMMARGIN, 171 - HORZGUIDE, 8 - HORZGUIDE, 41 - END - - IDD_FINISHED, DIALOG - BEGIN - LEFTMARGIN, 6 - RIGHTMARGIN, 372 - VERTGUIDE, 125 - VERTGUIDE, 372 - TOPMARGIN, 7 - BOTTOMMARGIN, 171 - HORZGUIDE, 8 - HORZGUIDE, 41 - END -END -#endif // APSTUDIO_INVOKED - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/PC/bdist_wininst/resource.h b/PC/bdist_wininst/resource.h index 35ba3c2534d5..86aeabb13ad5 100644 --- a/PC/bdist_wininst/resource.h +++ b/PC/bdist_wininst/resource.h @@ -1,16 +1,11 @@ /* - IMPORTANT NOTE: IF THIS FILE IS CHANGED, WININST-6.EXE MUST BE RECOMPILED - WITH THE MSVC6 WININST.DSW WORKSPACE FILE MANUALLY, AND WININST-7.1.EXE MUST - BE RECOMPILED WITH THE MSVC 2003.NET WININST-7.1.VCPROJ FILE MANUALLY. + IMPORTANT NOTE: IF THIS FILE IS CHANGED, PCBUILD\BDIST_WININST.VCXPROJ MUST + BE REBUILT AS WELL. - IF CHANGES TO THIS FILE ARE CHECKED INTO PYTHON CVS, THE RECOMPILED BINARIES - MUST BE CHECKED IN AS WELL! + IF CHANGES TO THIS FILE ARE CHECKED IN, THE RECOMPILED BINARIES MUST BE + CHECKED IN AS WELL! */ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by install.rc -// #define IDD_DIALOG1 101 #define IDB_BITMAP1 103 #define IDD_INTRO 107 @@ -34,14 +29,3 @@ #define IDC_BUILD_INFO 1024 #define IDC_BITMAP 1025 #define IDC_OTHERPYTHON 1026 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 112 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1028 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/PC/bdist_wininst/wininst-7.1.sln b/PC/bdist_wininst/wininst-7.1.sln deleted file mode 100644 index e205d25c507a..000000000000 --- a/PC/bdist_wininst/wininst-7.1.sln +++ /dev/null @@ -1,21 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wininst", "wininst-7.1.vcproj", "{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Release = Release - EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug.ActiveCfg = Debug|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug.Build.0 = Debug|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release.ActiveCfg = Release|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution - EndGlobalSection -EndGlobal diff --git a/PC/bdist_wininst/wininst-7.1.vcproj b/PC/bdist_wininst/wininst-7.1.vcproj deleted file mode 100644 index 30daae9ff6d1..000000000000 --- a/PC/bdist_wininst/wininst-7.1.vcproj +++ /dev/null @@ -1,214 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/bdist_wininst/wininst-8.sln b/PC/bdist_wininst/wininst-8.sln deleted file mode 100644 index 25f16cfba273..000000000000 --- a/PC/bdist_wininst/wininst-8.sln +++ /dev/null @@ -1,19 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wininst", "wininst-8.vcproj", "{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|Win32.ActiveCfg = Debug|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|Win32.Build.0 = Debug|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|Win32.ActiveCfg = Release|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/PC/bdist_wininst/wininst-8.vcproj b/PC/bdist_wininst/wininst-8.vcproj deleted file mode 100644 index 0147d1b3fbfa..000000000000 --- a/PC/bdist_wininst/wininst-8.vcproj +++ /dev/null @@ -1,320 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/bdist_wininst/wininst.dsp b/PC/bdist_wininst/wininst.dsp deleted file mode 100644 index 698556980deb..000000000000 --- a/PC/bdist_wininst/wininst.dsp +++ /dev/null @@ -1,123 +0,0 @@ -# Microsoft Developer Studio Project File - Name="wininst" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Application" 0x0101 - -CFG=wininst - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "wininst.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "wininst.mak" CFG="wininst - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "wininst - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "wininst - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "wininst - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "..\..\lib\distutils\command" -# PROP Intermediate_Dir "temp-release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /O1 /I "..\..\Include" /I "..\..\..\zlib-1.2.3" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x407 /d "NDEBUG" -# ADD RSC /l 0x407 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 ..\..\..\zlib-1.2.3\zlib.lib imagehlp.lib comdlg32.lib ole32.lib comctl32.lib kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"LIBC" /out:"..\..\lib\distutils\command/wininst-6.0.exe" - -!ELSEIF "$(CFG)" == "wininst - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "." -# PROP Intermediate_Dir "temp-debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MD /W3 /Z7 /Od /I "..\..\Include" /I "..\..\..\zlib-1.2.1" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x407 /d "_DEBUG" -# ADD RSC /l 0x407 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept -# ADD LINK32 ..\..\..\zlib-1.2.3\zlib.lib imagehlp.lib comdlg32.lib ole32.lib comctl32.lib kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib /nologo /subsystem:windows /pdb:none /debug /machine:I386 /nodefaultlib:"LIBC" /out:"..\..\lib\distutils\command/wininst-6.0_d.exe" - -!ENDIF - -# Begin Target - -# Name "wininst - Win32 Release" -# Name "wininst - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\extract.c -# End Source File -# Begin Source File - -SOURCE=.\install.c -# End Source File -# Begin Source File - -SOURCE=.\install.rc -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\archive.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# Begin Source File - -SOURCE=.\PythonPowered.bmp -# End Source File -# End Group -# End Target -# End Project diff --git a/PC/bdist_wininst/wininst.dsw b/PC/bdist_wininst/wininst.dsw deleted file mode 100644 index fbc66aa97349..000000000000 --- a/PC/bdist_wininst/wininst.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "wininst"=.\wininst.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/PC/clinic/msvcrtmodule.c.h b/PC/clinic/msvcrtmodule.c.h new file mode 100644 index 000000000000..c8e6ed8533f8 --- /dev/null +++ b/PC/clinic/msvcrtmodule.c.h @@ -0,0 +1,554 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(msvcrt_heapmin__doc__, +"heapmin($module, /)\n" +"--\n" +"\n" +"Minimize the malloc() heap.\n" +"\n" +"Force the malloc() heap to clean itself up and return unused blocks\n" +"to the operating system. On failure, this raises OSError."); + +#define MSVCRT_HEAPMIN_METHODDEF \ + {"heapmin", (PyCFunction)msvcrt_heapmin, METH_NOARGS, msvcrt_heapmin__doc__}, + +static PyObject * +msvcrt_heapmin_impl(PyModuleDef *module); + +static PyObject * +msvcrt_heapmin(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + return msvcrt_heapmin_impl(module); +} + +PyDoc_STRVAR(msvcrt_locking__doc__, +"locking($module, fd, mode, nbytes, /)\n" +"--\n" +"\n" +"Lock part of a file based on file descriptor fd from the C runtime.\n" +"\n" +"Raises IOError on failure. The locked region of the file extends from\n" +"the current file position for nbytes bytes, and may continue beyond\n" +"the end of the file. mode must be one of the LK_* constants listed\n" +"below. Multiple regions in a file may be locked at the same time, but\n" +"may not overlap. Adjacent regions are not merged; they must be unlocked\n" +"individually."); + +#define MSVCRT_LOCKING_METHODDEF \ + {"locking", (PyCFunction)msvcrt_locking, METH_VARARGS, msvcrt_locking__doc__}, + +static PyObject * +msvcrt_locking_impl(PyModuleDef *module, int fd, int mode, long nbytes); + +static PyObject * +msvcrt_locking(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + int mode; + long nbytes; + + if (!PyArg_ParseTuple(args, "iil:locking", + &fd, &mode, &nbytes)) + goto exit; + return_value = msvcrt_locking_impl(module, fd, mode, nbytes); + +exit: + return return_value; +} + +PyDoc_STRVAR(msvcrt_setmode__doc__, +"setmode($module, fd, mode, /)\n" +"--\n" +"\n" +"Set the line-end translation mode for the file descriptor fd.\n" +"\n" +"To set it to text mode, flags should be os.O_TEXT; for binary, it\n" +"should be os.O_BINARY.\n" +"\n" +"Return value is the previous mode."); + +#define MSVCRT_SETMODE_METHODDEF \ + {"setmode", (PyCFunction)msvcrt_setmode, METH_VARARGS, msvcrt_setmode__doc__}, + +static long +msvcrt_setmode_impl(PyModuleDef *module, int fd, int flags); + +static PyObject * +msvcrt_setmode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int fd; + int flags; + long _return_value; + + if (!PyArg_ParseTuple(args, "ii:setmode", + &fd, &flags)) + goto exit; + _return_value = msvcrt_setmode_impl(module, fd, flags); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(msvcrt_open_osfhandle__doc__, +"open_osfhandle($module, handle, flags, /)\n" +"--\n" +"\n" +"Create a C runtime file descriptor from the file handle handle.\n" +"\n" +"The flags parameter should be a bitwise OR of os.O_APPEND, os.O_RDONLY,\n" +"and os.O_TEXT. The returned file descriptor may be used as a parameter\n" +"to os.fdopen() to create a file object."); + +#define MSVCRT_OPEN_OSFHANDLE_METHODDEF \ + {"open_osfhandle", (PyCFunction)msvcrt_open_osfhandle, METH_VARARGS, msvcrt_open_osfhandle__doc__}, + +static long +msvcrt_open_osfhandle_impl(PyModuleDef *module, Py_intptr_t handle, + int flags); + +static PyObject * +msvcrt_open_osfhandle(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_intptr_t handle; + int flags; + long _return_value; + + if (!PyArg_ParseTuple(args, ""_Py_PARSE_INTPTR"i:open_osfhandle", + &handle, &flags)) + goto exit; + _return_value = msvcrt_open_osfhandle_impl(module, handle, flags); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(msvcrt_get_osfhandle__doc__, +"get_osfhandle($module, fd, /)\n" +"--\n" +"\n" +"Return the file handle for the file descriptor fd.\n" +"\n" +"Raises IOError if fd is not recognized."); + +#define MSVCRT_GET_OSFHANDLE_METHODDEF \ + {"get_osfhandle", (PyCFunction)msvcrt_get_osfhandle, METH_O, msvcrt_get_osfhandle__doc__}, + +static Py_intptr_t +msvcrt_get_osfhandle_impl(PyModuleDef *module, int fd); + +static PyObject * +msvcrt_get_osfhandle(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + Py_intptr_t _return_value; + + if (!PyArg_Parse(arg, "i:get_osfhandle", &fd)) + goto exit; + _return_value = msvcrt_get_osfhandle_impl(module, fd); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromVoidPtr((void *)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(msvcrt_kbhit__doc__, +"kbhit($module, /)\n" +"--\n" +"\n" +"Return true if a keypress is waiting to be read."); + +#define MSVCRT_KBHIT_METHODDEF \ + {"kbhit", (PyCFunction)msvcrt_kbhit, METH_NOARGS, msvcrt_kbhit__doc__}, + +static long +msvcrt_kbhit_impl(PyModuleDef *module); + +static PyObject * +msvcrt_kbhit(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + long _return_value; + + _return_value = msvcrt_kbhit_impl(module); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(msvcrt_getch__doc__, +"getch($module, /)\n" +"--\n" +"\n" +"Read a keypress and return the resulting character as a byte string.\n" +"\n" +"Nothing is echoed to the console. This call will block if a keypress is\n" +"not already available, but will not wait for Enter to be pressed. If the\n" +"pressed key was a special function key, this will return \'\\000\' or\n" +"\'\\xe0\'; the next call will return the keycode. The Control-C keypress\n" +"cannot be read with this function."); + +#define MSVCRT_GETCH_METHODDEF \ + {"getch", (PyCFunction)msvcrt_getch, METH_NOARGS, msvcrt_getch__doc__}, + +static int +msvcrt_getch_impl(PyModuleDef *module); + +static PyObject * +msvcrt_getch(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + char s[1]; + + s[0] = msvcrt_getch_impl(module); + return_value = PyBytes_FromStringAndSize(s, 1); + + return return_value; +} + +PyDoc_STRVAR(msvcrt_getwch__doc__, +"getwch($module, /)\n" +"--\n" +"\n" +"Wide char variant of getch(), returning a Unicode value."); + +#define MSVCRT_GETWCH_METHODDEF \ + {"getwch", (PyCFunction)msvcrt_getwch, METH_NOARGS, msvcrt_getwch__doc__}, + +static wchar_t +msvcrt_getwch_impl(PyModuleDef *module); + +static PyObject * +msvcrt_getwch(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + wchar_t _return_value; + + _return_value = msvcrt_getwch_impl(module); + return_value = PyUnicode_FromOrdinal(_return_value); + + return return_value; +} + +PyDoc_STRVAR(msvcrt_getche__doc__, +"getche($module, /)\n" +"--\n" +"\n" +"Similar to getch(), but the keypress will be echoed if possible."); + +#define MSVCRT_GETCHE_METHODDEF \ + {"getche", (PyCFunction)msvcrt_getche, METH_NOARGS, msvcrt_getche__doc__}, + +static int +msvcrt_getche_impl(PyModuleDef *module); + +static PyObject * +msvcrt_getche(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + char s[1]; + + s[0] = msvcrt_getche_impl(module); + return_value = PyBytes_FromStringAndSize(s, 1); + + return return_value; +} + +PyDoc_STRVAR(msvcrt_getwche__doc__, +"getwche($module, /)\n" +"--\n" +"\n" +"Wide char variant of getche(), returning a Unicode value."); + +#define MSVCRT_GETWCHE_METHODDEF \ + {"getwche", (PyCFunction)msvcrt_getwche, METH_NOARGS, msvcrt_getwche__doc__}, + +static wchar_t +msvcrt_getwche_impl(PyModuleDef *module); + +static PyObject * +msvcrt_getwche(PyModuleDef *module, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + wchar_t _return_value; + + _return_value = msvcrt_getwche_impl(module); + return_value = PyUnicode_FromOrdinal(_return_value); + + return return_value; +} + +PyDoc_STRVAR(msvcrt_putch__doc__, +"putch($module, char, /)\n" +"--\n" +"\n" +"Print the byte string char to the console without buffering."); + +#define MSVCRT_PUTCH_METHODDEF \ + {"putch", (PyCFunction)msvcrt_putch, METH_O, msvcrt_putch__doc__}, + +static PyObject * +msvcrt_putch_impl(PyModuleDef *module, char char_value); + +static PyObject * +msvcrt_putch(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + char char_value; + + if (!PyArg_Parse(arg, "c:putch", &char_value)) + goto exit; + return_value = msvcrt_putch_impl(module, char_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(msvcrt_putwch__doc__, +"putwch($module, unicode_char, /)\n" +"--\n" +"\n" +"Wide char variant of putch(), accepting a Unicode value."); + +#define MSVCRT_PUTWCH_METHODDEF \ + {"putwch", (PyCFunction)msvcrt_putwch, METH_O, msvcrt_putwch__doc__}, + +static PyObject * +msvcrt_putwch_impl(PyModuleDef *module, int unicode_char); + +static PyObject * +msvcrt_putwch(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int unicode_char; + + if (!PyArg_Parse(arg, "C:putwch", &unicode_char)) + goto exit; + return_value = msvcrt_putwch_impl(module, unicode_char); + +exit: + return return_value; +} + +PyDoc_STRVAR(msvcrt_ungetch__doc__, +"ungetch($module, char, /)\n" +"--\n" +"\n" +"Opposite of getch.\n" +"\n" +"Cause the byte string char to be \"pushed back\" into the\n" +"console buffer; it will be the next character read by\n" +"getch() or getche()."); + +#define MSVCRT_UNGETCH_METHODDEF \ + {"ungetch", (PyCFunction)msvcrt_ungetch, METH_O, msvcrt_ungetch__doc__}, + +static PyObject * +msvcrt_ungetch_impl(PyModuleDef *module, char char_value); + +static PyObject * +msvcrt_ungetch(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + char char_value; + + if (!PyArg_Parse(arg, "c:ungetch", &char_value)) + goto exit; + return_value = msvcrt_ungetch_impl(module, char_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(msvcrt_ungetwch__doc__, +"ungetwch($module, unicode_char, /)\n" +"--\n" +"\n" +"Wide char variant of ungetch(), accepting a Unicode value."); + +#define MSVCRT_UNGETWCH_METHODDEF \ + {"ungetwch", (PyCFunction)msvcrt_ungetwch, METH_O, msvcrt_ungetwch__doc__}, + +static PyObject * +msvcrt_ungetwch_impl(PyModuleDef *module, int unicode_char); + +static PyObject * +msvcrt_ungetwch(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int unicode_char; + + if (!PyArg_Parse(arg, "C:ungetwch", &unicode_char)) + goto exit; + return_value = msvcrt_ungetwch_impl(module, unicode_char); + +exit: + return return_value; +} + +#if defined(_DEBUG) + +PyDoc_STRVAR(msvcrt_CrtSetReportFile__doc__, +"CrtSetReportFile($module, type, file, /)\n" +"--\n" +"\n" +"Wrapper around _CrtSetReportFile.\n" +"\n" +"Only available on Debug builds."); + +#define MSVCRT_CRTSETREPORTFILE_METHODDEF \ + {"CrtSetReportFile", (PyCFunction)msvcrt_CrtSetReportFile, METH_VARARGS, msvcrt_CrtSetReportFile__doc__}, + +static long +msvcrt_CrtSetReportFile_impl(PyModuleDef *module, int type, int file); + +static PyObject * +msvcrt_CrtSetReportFile(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int type; + int file; + long _return_value; + + if (!PyArg_ParseTuple(args, "ii:CrtSetReportFile", + &type, &file)) + goto exit; + _return_value = msvcrt_CrtSetReportFile_impl(module, type, file); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +#endif /* defined(_DEBUG) */ + +#if defined(_DEBUG) + +PyDoc_STRVAR(msvcrt_CrtSetReportMode__doc__, +"CrtSetReportMode($module, type, mode, /)\n" +"--\n" +"\n" +"Wrapper around _CrtSetReportMode.\n" +"\n" +"Only available on Debug builds."); + +#define MSVCRT_CRTSETREPORTMODE_METHODDEF \ + {"CrtSetReportMode", (PyCFunction)msvcrt_CrtSetReportMode, METH_VARARGS, msvcrt_CrtSetReportMode__doc__}, + +static long +msvcrt_CrtSetReportMode_impl(PyModuleDef *module, int type, int mode); + +static PyObject * +msvcrt_CrtSetReportMode(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int type; + int mode; + long _return_value; + + if (!PyArg_ParseTuple(args, "ii:CrtSetReportMode", + &type, &mode)) + goto exit; + _return_value = msvcrt_CrtSetReportMode_impl(module, type, mode); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +#endif /* defined(_DEBUG) */ + +#if defined(_DEBUG) + +PyDoc_STRVAR(msvcrt_set_error_mode__doc__, +"set_error_mode($module, mode, /)\n" +"--\n" +"\n" +"Wrapper around _set_error_mode.\n" +"\n" +"Only available on Debug builds."); + +#define MSVCRT_SET_ERROR_MODE_METHODDEF \ + {"set_error_mode", (PyCFunction)msvcrt_set_error_mode, METH_O, msvcrt_set_error_mode__doc__}, + +static long +msvcrt_set_error_mode_impl(PyModuleDef *module, int mode); + +static PyObject * +msvcrt_set_error_mode(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int mode; + long _return_value; + + if (!PyArg_Parse(arg, "i:set_error_mode", &mode)) + goto exit; + _return_value = msvcrt_set_error_mode_impl(module, mode); + if ((_return_value == -1) && PyErr_Occurred()) + goto exit; + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +#endif /* defined(_DEBUG) */ + +PyDoc_STRVAR(msvcrt_SetErrorMode__doc__, +"SetErrorMode($module, mode, /)\n" +"--\n" +"\n" +"Wrapper around SetErrorMode."); + +#define MSVCRT_SETERRORMODE_METHODDEF \ + {"SetErrorMode", (PyCFunction)msvcrt_SetErrorMode, METH_O, msvcrt_SetErrorMode__doc__}, + +static PyObject * +msvcrt_SetErrorMode_impl(PyModuleDef *module, unsigned int mode); + +static PyObject * +msvcrt_SetErrorMode(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + unsigned int mode; + + if (!PyArg_Parse(arg, "I:SetErrorMode", &mode)) + goto exit; + return_value = msvcrt_SetErrorMode_impl(module, mode); + +exit: + return return_value; +} + +#ifndef MSVCRT_CRTSETREPORTFILE_METHODDEF + #define MSVCRT_CRTSETREPORTFILE_METHODDEF +#endif /* !defined(MSVCRT_CRTSETREPORTFILE_METHODDEF) */ + +#ifndef MSVCRT_CRTSETREPORTMODE_METHODDEF + #define MSVCRT_CRTSETREPORTMODE_METHODDEF +#endif /* !defined(MSVCRT_CRTSETREPORTMODE_METHODDEF) */ + +#ifndef MSVCRT_SET_ERROR_MODE_METHODDEF + #define MSVCRT_SET_ERROR_MODE_METHODDEF +#endif /* !defined(MSVCRT_SET_ERROR_MODE_METHODDEF) */ +/*[clinic end generated code: output=16613d3119a1fd44 input=a9049054013a1b77]*/ diff --git a/PC/clinic/winreg.c.h b/PC/clinic/winreg.c.h new file mode 100644 index 000000000000..22b332fbf2a7 --- /dev/null +++ b/PC/clinic/winreg.c.h @@ -0,0 +1,1059 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(winreg_HKEYType_Close__doc__, +"Close($self, /)\n" +"--\n" +"\n" +"Closes the underlying Windows handle.\n" +"\n" +"If the handle is already closed, no error is raised."); + +#define WINREG_HKEYTYPE_CLOSE_METHODDEF \ + {"Close", (PyCFunction)winreg_HKEYType_Close, METH_NOARGS, winreg_HKEYType_Close__doc__}, + +static PyObject * +winreg_HKEYType_Close_impl(PyHKEYObject *self); + +static PyObject * +winreg_HKEYType_Close(PyHKEYObject *self, PyObject *Py_UNUSED(ignored)) +{ + return winreg_HKEYType_Close_impl(self); +} + +PyDoc_STRVAR(winreg_HKEYType_Detach__doc__, +"Detach($self, /)\n" +"--\n" +"\n" +"Detaches the Windows handle from the handle object.\n" +"\n" +"The result is the value of the handle before it is detached. If the\n" +"handle is already detached, this will return zero.\n" +"\n" +"After calling this function, the handle is effectively invalidated,\n" +"but the handle is not closed. You would call this function when you\n" +"need the underlying win32 handle to exist beyond the lifetime of the\n" +"handle object."); + +#define WINREG_HKEYTYPE_DETACH_METHODDEF \ + {"Detach", (PyCFunction)winreg_HKEYType_Detach, METH_NOARGS, winreg_HKEYType_Detach__doc__}, + +static PyObject * +winreg_HKEYType_Detach_impl(PyHKEYObject *self); + +static PyObject * +winreg_HKEYType_Detach(PyHKEYObject *self, PyObject *Py_UNUSED(ignored)) +{ + return winreg_HKEYType_Detach_impl(self); +} + +PyDoc_STRVAR(winreg_HKEYType___enter____doc__, +"__enter__($self, /)\n" +"--\n" +"\n"); + +#define WINREG_HKEYTYPE___ENTER___METHODDEF \ + {"__enter__", (PyCFunction)winreg_HKEYType___enter__, METH_NOARGS, winreg_HKEYType___enter____doc__}, + +static PyHKEYObject * +winreg_HKEYType___enter___impl(PyHKEYObject *self); + +static PyObject * +winreg_HKEYType___enter__(PyHKEYObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *return_value = NULL; + PyHKEYObject *_return_value; + + _return_value = winreg_HKEYType___enter___impl(self); + return_value = (PyObject *)_return_value; + + return return_value; +} + +PyDoc_STRVAR(winreg_HKEYType___exit____doc__, +"__exit__($self, /, exc_type, exc_value, traceback)\n" +"--\n" +"\n"); + +#define WINREG_HKEYTYPE___EXIT___METHODDEF \ + {"__exit__", (PyCFunction)winreg_HKEYType___exit__, METH_VARARGS|METH_KEYWORDS, winreg_HKEYType___exit____doc__}, + +static PyObject * +winreg_HKEYType___exit___impl(PyHKEYObject *self, PyObject *exc_type, + PyObject *exc_value, PyObject *traceback); + +static PyObject * +winreg_HKEYType___exit__(PyHKEYObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"exc_type", "exc_value", "traceback", NULL}; + PyObject *exc_type; + PyObject *exc_value; + PyObject *traceback; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOO:__exit__", _keywords, + &exc_type, &exc_value, &traceback)) + goto exit; + return_value = winreg_HKEYType___exit___impl(self, exc_type, exc_value, traceback); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_CloseKey__doc__, +"CloseKey($module, hkey, /)\n" +"--\n" +"\n" +"Closes a previously opened registry key.\n" +"\n" +" hkey\n" +" A previously opened key.\n" +"\n" +"Note that if the key is not closed using this method, it will be\n" +"closed when the hkey object is destroyed by Python."); + +#define WINREG_CLOSEKEY_METHODDEF \ + {"CloseKey", (PyCFunction)winreg_CloseKey, METH_O, winreg_CloseKey__doc__}, + +PyDoc_STRVAR(winreg_ConnectRegistry__doc__, +"ConnectRegistry($module, computer_name, key, /)\n" +"--\n" +"\n" +"Establishes a connection to the registry on on another computer.\n" +"\n" +" computer_name\n" +" The name of the remote computer, of the form r\"\\\\computername\". If\n" +" None, the local computer is used.\n" +" key\n" +" The predefined key to connect to.\n" +"\n" +"The return value is the handle of the opened key.\n" +"If the function fails, an OSError exception is raised."); + +#define WINREG_CONNECTREGISTRY_METHODDEF \ + {"ConnectRegistry", (PyCFunction)winreg_ConnectRegistry, METH_VARARGS, winreg_ConnectRegistry__doc__}, + +static HKEY +winreg_ConnectRegistry_impl(PyModuleDef *module, Py_UNICODE *computer_name, + HKEY key); + +static PyObject * +winreg_ConnectRegistry(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_UNICODE *computer_name; + HKEY key; + HKEY _return_value; + + if (!PyArg_ParseTuple(args, "ZO&:ConnectRegistry", + &computer_name, clinic_HKEY_converter, &key)) + goto exit; + _return_value = winreg_ConnectRegistry_impl(module, computer_name, key); + if (_return_value == NULL) + goto exit; + return_value = PyHKEY_FromHKEY(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_CreateKey__doc__, +"CreateKey($module, key, sub_key, /)\n" +"--\n" +"\n" +"Creates or opens the specified key.\n" +"\n" +" key\n" +" An already open key, or one of the predefined HKEY_* constants.\n" +" sub_key\n" +" The name of the key this method opens or creates.\n" +"\n" +"If key is one of the predefined keys, sub_key may be None. In that case,\n" +"the handle returned is the same key handle passed in to the function.\n" +"\n" +"If the key already exists, this function opens the existing key.\n" +"\n" +"The return value is the handle of the opened key.\n" +"If the function fails, an OSError exception is raised."); + +#define WINREG_CREATEKEY_METHODDEF \ + {"CreateKey", (PyCFunction)winreg_CreateKey, METH_VARARGS, winreg_CreateKey__doc__}, + +static HKEY +winreg_CreateKey_impl(PyModuleDef *module, HKEY key, Py_UNICODE *sub_key); + +static PyObject * +winreg_CreateKey(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + HKEY key; + Py_UNICODE *sub_key; + HKEY _return_value; + + if (!PyArg_ParseTuple(args, "O&Z:CreateKey", + clinic_HKEY_converter, &key, &sub_key)) + goto exit; + _return_value = winreg_CreateKey_impl(module, key, sub_key); + if (_return_value == NULL) + goto exit; + return_value = PyHKEY_FromHKEY(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_CreateKeyEx__doc__, +"CreateKeyEx($module, /, key, sub_key, reserved=0,\n" +" access=winreg.KEY_WRITE)\n" +"--\n" +"\n" +"Creates or opens the specified key.\n" +"\n" +" key\n" +" An already open key, or one of the predefined HKEY_* constants.\n" +" sub_key\n" +" The name of the key this method opens or creates.\n" +" reserved\n" +" A reserved integer, and must be zero. Default is zero.\n" +" access\n" +" An integer that specifies an access mask that describes the\n" +" desired security access for the key. Default is KEY_WRITE.\n" +"\n" +"If key is one of the predefined keys, sub_key may be None. In that case,\n" +"the handle returned is the same key handle passed in to the function.\n" +"\n" +"If the key already exists, this function opens the existing key\n" +"\n" +"The return value is the handle of the opened key.\n" +"If the function fails, an OSError exception is raised."); + +#define WINREG_CREATEKEYEX_METHODDEF \ + {"CreateKeyEx", (PyCFunction)winreg_CreateKeyEx, METH_VARARGS|METH_KEYWORDS, winreg_CreateKeyEx__doc__}, + +static HKEY +winreg_CreateKeyEx_impl(PyModuleDef *module, HKEY key, Py_UNICODE *sub_key, + int reserved, REGSAM access); + +static PyObject * +winreg_CreateKeyEx(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"key", "sub_key", "reserved", "access", NULL}; + HKEY key; + Py_UNICODE *sub_key; + int reserved = 0; + REGSAM access = KEY_WRITE; + HKEY _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&Z|ii:CreateKeyEx", _keywords, + clinic_HKEY_converter, &key, &sub_key, &reserved, &access)) + goto exit; + _return_value = winreg_CreateKeyEx_impl(module, key, sub_key, reserved, access); + if (_return_value == NULL) + goto exit; + return_value = PyHKEY_FromHKEY(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_DeleteKey__doc__, +"DeleteKey($module, key, sub_key, /)\n" +"--\n" +"\n" +"Deletes the specified key.\n" +"\n" +" key\n" +" An already open key, or any one of the predefined HKEY_* constants.\n" +" sub_key\n" +" A string that must be the name of a subkey of the key identified by\n" +" the key parameter. This value must not be None, and the key may not\n" +" have subkeys.\n" +"\n" +"This method can not delete keys with subkeys.\n" +"\n" +"If the function succeeds, the entire key, including all of its values,\n" +"is removed. If the function fails, an OSError exception is raised."); + +#define WINREG_DELETEKEY_METHODDEF \ + {"DeleteKey", (PyCFunction)winreg_DeleteKey, METH_VARARGS, winreg_DeleteKey__doc__}, + +static PyObject * +winreg_DeleteKey_impl(PyModuleDef *module, HKEY key, Py_UNICODE *sub_key); + +static PyObject * +winreg_DeleteKey(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + HKEY key; + Py_UNICODE *sub_key; + + if (!PyArg_ParseTuple(args, "O&u:DeleteKey", + clinic_HKEY_converter, &key, &sub_key)) + goto exit; + return_value = winreg_DeleteKey_impl(module, key, sub_key); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_DeleteKeyEx__doc__, +"DeleteKeyEx($module, /, key, sub_key, access=winreg.KEY_WOW64_64KEY,\n" +" reserved=0)\n" +"--\n" +"\n" +"Deletes the specified key (64-bit OS only).\n" +"\n" +" key\n" +" An already open key, or any one of the predefined HKEY_* constants.\n" +" sub_key\n" +" A string that must be the name of a subkey of the key identified by\n" +" the key parameter. This value must not be None, and the key may not\n" +" have subkeys.\n" +" access\n" +" An integer that specifies an access mask that describes the\n" +" desired security access for the key. Default is KEY_WOW64_64KEY.\n" +" reserved\n" +" A reserved integer, and must be zero. Default is zero.\n" +"\n" +"This method can not delete keys with subkeys.\n" +"\n" +"If the function succeeds, the entire key, including all of its values,\n" +"is removed. If the function fails, an OSError exception is raised.\n" +"On unsupported Windows versions, NotImplementedError is raised."); + +#define WINREG_DELETEKEYEX_METHODDEF \ + {"DeleteKeyEx", (PyCFunction)winreg_DeleteKeyEx, METH_VARARGS|METH_KEYWORDS, winreg_DeleteKeyEx__doc__}, + +static PyObject * +winreg_DeleteKeyEx_impl(PyModuleDef *module, HKEY key, Py_UNICODE *sub_key, + REGSAM access, int reserved); + +static PyObject * +winreg_DeleteKeyEx(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"key", "sub_key", "access", "reserved", NULL}; + HKEY key; + Py_UNICODE *sub_key; + REGSAM access = KEY_WOW64_64KEY; + int reserved = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&u|ii:DeleteKeyEx", _keywords, + clinic_HKEY_converter, &key, &sub_key, &access, &reserved)) + goto exit; + return_value = winreg_DeleteKeyEx_impl(module, key, sub_key, access, reserved); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_DeleteValue__doc__, +"DeleteValue($module, key, value, /)\n" +"--\n" +"\n" +"Removes a named value from a registry key.\n" +"\n" +" key\n" +" An already open key, or any one of the predefined HKEY_* constants.\n" +" value\n" +" A string that identifies the value to remove."); + +#define WINREG_DELETEVALUE_METHODDEF \ + {"DeleteValue", (PyCFunction)winreg_DeleteValue, METH_VARARGS, winreg_DeleteValue__doc__}, + +static PyObject * +winreg_DeleteValue_impl(PyModuleDef *module, HKEY key, Py_UNICODE *value); + +static PyObject * +winreg_DeleteValue(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + HKEY key; + Py_UNICODE *value; + + if (!PyArg_ParseTuple(args, "O&Z:DeleteValue", + clinic_HKEY_converter, &key, &value)) + goto exit; + return_value = winreg_DeleteValue_impl(module, key, value); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_EnumKey__doc__, +"EnumKey($module, key, index, /)\n" +"--\n" +"\n" +"Enumerates subkeys of an open registry key.\n" +"\n" +" key\n" +" An already open key, or any one of the predefined HKEY_* constants.\n" +" index\n" +" An integer that identifies the index of the key to retrieve.\n" +"\n" +"The function retrieves the name of one subkey each time it is called.\n" +"It is typically called repeatedly until an OSError exception is\n" +"raised, indicating no more values are available."); + +#define WINREG_ENUMKEY_METHODDEF \ + {"EnumKey", (PyCFunction)winreg_EnumKey, METH_VARARGS, winreg_EnumKey__doc__}, + +static PyObject * +winreg_EnumKey_impl(PyModuleDef *module, HKEY key, int index); + +static PyObject * +winreg_EnumKey(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + HKEY key; + int index; + + if (!PyArg_ParseTuple(args, "O&i:EnumKey", + clinic_HKEY_converter, &key, &index)) + goto exit; + return_value = winreg_EnumKey_impl(module, key, index); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_EnumValue__doc__, +"EnumValue($module, key, index, /)\n" +"--\n" +"\n" +"Enumerates values of an open registry key.\n" +"\n" +" key\n" +" An already open key, or any one of the predefined HKEY_* constants.\n" +" index\n" +" An integer that identifies the index of the value to retrieve.\n" +"\n" +"The function retrieves the name of one subkey each time it is called.\n" +"It is typically called repeatedly, until an OSError exception\n" +"is raised, indicating no more values.\n" +"\n" +"The result is a tuple of 3 items:\n" +" value_name\n" +" A string that identifies the value.\n" +" value_data\n" +" An object that holds the value data, and whose type depends\n" +" on the underlying registry type.\n" +" data_type\n" +" An integer that identifies the type of the value data."); + +#define WINREG_ENUMVALUE_METHODDEF \ + {"EnumValue", (PyCFunction)winreg_EnumValue, METH_VARARGS, winreg_EnumValue__doc__}, + +static PyObject * +winreg_EnumValue_impl(PyModuleDef *module, HKEY key, int index); + +static PyObject * +winreg_EnumValue(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + HKEY key; + int index; + + if (!PyArg_ParseTuple(args, "O&i:EnumValue", + clinic_HKEY_converter, &key, &index)) + goto exit; + return_value = winreg_EnumValue_impl(module, key, index); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_ExpandEnvironmentStrings__doc__, +"ExpandEnvironmentStrings($module, string, /)\n" +"--\n" +"\n" +"Expand environment vars."); + +#define WINREG_EXPANDENVIRONMENTSTRINGS_METHODDEF \ + {"ExpandEnvironmentStrings", (PyCFunction)winreg_ExpandEnvironmentStrings, METH_O, winreg_ExpandEnvironmentStrings__doc__}, + +static PyObject * +winreg_ExpandEnvironmentStrings_impl(PyModuleDef *module, Py_UNICODE *string); + +static PyObject * +winreg_ExpandEnvironmentStrings(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_UNICODE *string; + + if (!PyArg_Parse(arg, "u:ExpandEnvironmentStrings", &string)) + goto exit; + return_value = winreg_ExpandEnvironmentStrings_impl(module, string); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_FlushKey__doc__, +"FlushKey($module, key, /)\n" +"--\n" +"\n" +"Writes all the attributes of a key to the registry.\n" +"\n" +" key\n" +" An already open key, or any one of the predefined HKEY_* constants.\n" +"\n" +"It is not necessary to call FlushKey to change a key. Registry changes\n" +"are flushed to disk by the registry using its lazy flusher. Registry\n" +"changes are also flushed to disk at system shutdown. Unlike\n" +"CloseKey(), the FlushKey() method returns only when all the data has\n" +"been written to the registry.\n" +"\n" +"An application should only call FlushKey() if it requires absolute\n" +"certainty that registry changes are on disk. If you don\'t know whether\n" +"a FlushKey() call is required, it probably isn\'t."); + +#define WINREG_FLUSHKEY_METHODDEF \ + {"FlushKey", (PyCFunction)winreg_FlushKey, METH_O, winreg_FlushKey__doc__}, + +static PyObject * +winreg_FlushKey_impl(PyModuleDef *module, HKEY key); + +static PyObject * +winreg_FlushKey(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + HKEY key; + + if (!PyArg_Parse(arg, "O&:FlushKey", clinic_HKEY_converter, &key)) + goto exit; + return_value = winreg_FlushKey_impl(module, key); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_LoadKey__doc__, +"LoadKey($module, key, sub_key, file_name, /)\n" +"--\n" +"\n" +"Insert data into the registry from a file.\n" +"\n" +" key\n" +" An already open key, or any one of the predefined HKEY_* constants.\n" +" sub_key\n" +" A string that identifies the sub-key to load.\n" +" file_name\n" +" The name of the file to load registry data from. This file must\n" +" have been created with the SaveKey() function. Under the file\n" +" allocation table (FAT) file system, the filename may not have an\n" +" extension.\n" +"\n" +"Creates a subkey under the specified key and stores registration\n" +"information from a specified file into that subkey.\n" +"\n" +"A call to LoadKey() fails if the calling process does not have the\n" +"SE_RESTORE_PRIVILEGE privilege.\n" +"\n" +"If key is a handle returned by ConnectRegistry(), then the path\n" +"specified in fileName is relative to the remote computer.\n" +"\n" +"The MSDN docs imply key must be in the HKEY_USER or HKEY_LOCAL_MACHINE\n" +"tree."); + +#define WINREG_LOADKEY_METHODDEF \ + {"LoadKey", (PyCFunction)winreg_LoadKey, METH_VARARGS, winreg_LoadKey__doc__}, + +static PyObject * +winreg_LoadKey_impl(PyModuleDef *module, HKEY key, Py_UNICODE *sub_key, + Py_UNICODE *file_name); + +static PyObject * +winreg_LoadKey(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + HKEY key; + Py_UNICODE *sub_key; + Py_UNICODE *file_name; + + if (!PyArg_ParseTuple(args, "O&uu:LoadKey", + clinic_HKEY_converter, &key, &sub_key, &file_name)) + goto exit; + return_value = winreg_LoadKey_impl(module, key, sub_key, file_name); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_OpenKey__doc__, +"OpenKey($module, /, key, sub_key, reserved=0, access=winreg.KEY_READ)\n" +"--\n" +"\n" +"Opens the specified key.\n" +"\n" +" key\n" +" An already open key, or any one of the predefined HKEY_* constants.\n" +" sub_key\n" +" A string that identifies the sub_key to open.\n" +" reserved\n" +" A reserved integer that must be zero. Default is zero.\n" +" access\n" +" An integer that specifies an access mask that describes the desired\n" +" security access for the key. Default is KEY_READ.\n" +"\n" +"The result is a new handle to the specified key.\n" +"If the function fails, an OSError exception is raised."); + +#define WINREG_OPENKEY_METHODDEF \ + {"OpenKey", (PyCFunction)winreg_OpenKey, METH_VARARGS|METH_KEYWORDS, winreg_OpenKey__doc__}, + +static HKEY +winreg_OpenKey_impl(PyModuleDef *module, HKEY key, Py_UNICODE *sub_key, + int reserved, REGSAM access); + +static PyObject * +winreg_OpenKey(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"key", "sub_key", "reserved", "access", NULL}; + HKEY key; + Py_UNICODE *sub_key; + int reserved = 0; + REGSAM access = KEY_READ; + HKEY _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&Z|ii:OpenKey", _keywords, + clinic_HKEY_converter, &key, &sub_key, &reserved, &access)) + goto exit; + _return_value = winreg_OpenKey_impl(module, key, sub_key, reserved, access); + if (_return_value == NULL) + goto exit; + return_value = PyHKEY_FromHKEY(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_OpenKeyEx__doc__, +"OpenKeyEx($module, /, key, sub_key, reserved=0, access=winreg.KEY_READ)\n" +"--\n" +"\n" +"Opens the specified key.\n" +"\n" +" key\n" +" An already open key, or any one of the predefined HKEY_* constants.\n" +" sub_key\n" +" A string that identifies the sub_key to open.\n" +" reserved\n" +" A reserved integer that must be zero. Default is zero.\n" +" access\n" +" An integer that specifies an access mask that describes the desired\n" +" security access for the key. Default is KEY_READ.\n" +"\n" +"The result is a new handle to the specified key.\n" +"If the function fails, an OSError exception is raised."); + +#define WINREG_OPENKEYEX_METHODDEF \ + {"OpenKeyEx", (PyCFunction)winreg_OpenKeyEx, METH_VARARGS|METH_KEYWORDS, winreg_OpenKeyEx__doc__}, + +static HKEY +winreg_OpenKeyEx_impl(PyModuleDef *module, HKEY key, Py_UNICODE *sub_key, + int reserved, REGSAM access); + +static PyObject * +winreg_OpenKeyEx(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"key", "sub_key", "reserved", "access", NULL}; + HKEY key; + Py_UNICODE *sub_key; + int reserved = 0; + REGSAM access = KEY_READ; + HKEY _return_value; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&Z|ii:OpenKeyEx", _keywords, + clinic_HKEY_converter, &key, &sub_key, &reserved, &access)) + goto exit; + _return_value = winreg_OpenKeyEx_impl(module, key, sub_key, reserved, access); + if (_return_value == NULL) + goto exit; + return_value = PyHKEY_FromHKEY(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_QueryInfoKey__doc__, +"QueryInfoKey($module, key, /)\n" +"--\n" +"\n" +"Returns information about a key.\n" +"\n" +" key\n" +" An already open key, or any one of the predefined HKEY_* constants.\n" +"\n" +"The result is a tuple of 3 items:\n" +"An integer that identifies the number of sub keys this key has.\n" +"An integer that identifies the number of values this key has.\n" +"An integer that identifies when the key was last modified (if available)\n" +"as 100\'s of nanoseconds since Jan 1, 1600."); + +#define WINREG_QUERYINFOKEY_METHODDEF \ + {"QueryInfoKey", (PyCFunction)winreg_QueryInfoKey, METH_O, winreg_QueryInfoKey__doc__}, + +static PyObject * +winreg_QueryInfoKey_impl(PyModuleDef *module, HKEY key); + +static PyObject * +winreg_QueryInfoKey(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + HKEY key; + + if (!PyArg_Parse(arg, "O&:QueryInfoKey", clinic_HKEY_converter, &key)) + goto exit; + return_value = winreg_QueryInfoKey_impl(module, key); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_QueryValue__doc__, +"QueryValue($module, key, sub_key, /)\n" +"--\n" +"\n" +"Retrieves the unnamed value for a key.\n" +"\n" +" key\n" +" An already open key, or any one of the predefined HKEY_* constants.\n" +" sub_key\n" +" A string that holds the name of the subkey with which the value\n" +" is associated. If this parameter is None or empty, the function\n" +" retrieves the value set by the SetValue() method for the key\n" +" identified by key.\n" +"\n" +"Values in the registry have name, type, and data components. This method\n" +"retrieves the data for a key\'s first value that has a NULL name.\n" +"But since the underlying API call doesn\'t return the type, you\'ll\n" +"probably be happier using QueryValueEx; this function is just here for\n" +"completeness."); + +#define WINREG_QUERYVALUE_METHODDEF \ + {"QueryValue", (PyCFunction)winreg_QueryValue, METH_VARARGS, winreg_QueryValue__doc__}, + +static PyObject * +winreg_QueryValue_impl(PyModuleDef *module, HKEY key, Py_UNICODE *sub_key); + +static PyObject * +winreg_QueryValue(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + HKEY key; + Py_UNICODE *sub_key; + + if (!PyArg_ParseTuple(args, "O&Z:QueryValue", + clinic_HKEY_converter, &key, &sub_key)) + goto exit; + return_value = winreg_QueryValue_impl(module, key, sub_key); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_QueryValueEx__doc__, +"QueryValueEx($module, key, name, /)\n" +"--\n" +"\n" +"Retrieves the type and value of a specified sub-key.\n" +"\n" +" key\n" +" An already open key, or any one of the predefined HKEY_* constants.\n" +" name\n" +" A string indicating the value to query.\n" +"\n" +"Behaves mostly like QueryValue(), but also returns the type of the\n" +"specified value name associated with the given open registry key.\n" +"\n" +"The return value is a tuple of the value and the type_id."); + +#define WINREG_QUERYVALUEEX_METHODDEF \ + {"QueryValueEx", (PyCFunction)winreg_QueryValueEx, METH_VARARGS, winreg_QueryValueEx__doc__}, + +static PyObject * +winreg_QueryValueEx_impl(PyModuleDef *module, HKEY key, Py_UNICODE *name); + +static PyObject * +winreg_QueryValueEx(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + HKEY key; + Py_UNICODE *name; + + if (!PyArg_ParseTuple(args, "O&Z:QueryValueEx", + clinic_HKEY_converter, &key, &name)) + goto exit; + return_value = winreg_QueryValueEx_impl(module, key, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_SaveKey__doc__, +"SaveKey($module, key, file_name, /)\n" +"--\n" +"\n" +"Saves the specified key, and all its subkeys to the specified file.\n" +"\n" +" key\n" +" An already open key, or any one of the predefined HKEY_* constants.\n" +" file_name\n" +" The name of the file to save registry data to. This file cannot\n" +" already exist. If this filename includes an extension, it cannot be\n" +" used on file allocation table (FAT) file systems by the LoadKey(),\n" +" ReplaceKey() or RestoreKey() methods.\n" +"\n" +"If key represents a key on a remote computer, the path described by\n" +"file_name is relative to the remote computer.\n" +"\n" +"The caller of this method must possess the SeBackupPrivilege\n" +"security privilege. This function passes NULL for security_attributes\n" +"to the API."); + +#define WINREG_SAVEKEY_METHODDEF \ + {"SaveKey", (PyCFunction)winreg_SaveKey, METH_VARARGS, winreg_SaveKey__doc__}, + +static PyObject * +winreg_SaveKey_impl(PyModuleDef *module, HKEY key, Py_UNICODE *file_name); + +static PyObject * +winreg_SaveKey(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + HKEY key; + Py_UNICODE *file_name; + + if (!PyArg_ParseTuple(args, "O&u:SaveKey", + clinic_HKEY_converter, &key, &file_name)) + goto exit; + return_value = winreg_SaveKey_impl(module, key, file_name); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_SetValue__doc__, +"SetValue($module, key, sub_key, type, value, /)\n" +"--\n" +"\n" +"Associates a value with a specified key.\n" +"\n" +" key\n" +" An already open key, or any one of the predefined HKEY_* constants.\n" +" sub_key\n" +" A string that names the subkey with which the value is associated.\n" +" type\n" +" An integer that specifies the type of the data. Currently this must\n" +" be REG_SZ, meaning only strings are supported.\n" +" value\n" +" A string that specifies the new value.\n" +"\n" +"If the key specified by the sub_key parameter does not exist, the\n" +"SetValue function creates it.\n" +"\n" +"Value lengths are limited by available memory. Long values (more than\n" +"2048 bytes) should be stored as files with the filenames stored in\n" +"the configuration registry to help the registry perform efficiently.\n" +"\n" +"The key identified by the key parameter must have been opened with\n" +"KEY_SET_VALUE access."); + +#define WINREG_SETVALUE_METHODDEF \ + {"SetValue", (PyCFunction)winreg_SetValue, METH_VARARGS, winreg_SetValue__doc__}, + +static PyObject * +winreg_SetValue_impl(PyModuleDef *module, HKEY key, Py_UNICODE *sub_key, + DWORD type, Py_UNICODE *value, + Py_ssize_clean_t value_length); + +static PyObject * +winreg_SetValue(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + HKEY key; + Py_UNICODE *sub_key; + DWORD type; + Py_UNICODE *value; + Py_ssize_clean_t value_length; + + if (!PyArg_ParseTuple(args, "O&Zku#:SetValue", + clinic_HKEY_converter, &key, &sub_key, &type, &value, &value_length)) + goto exit; + return_value = winreg_SetValue_impl(module, key, sub_key, type, value, value_length); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_SetValueEx__doc__, +"SetValueEx($module, key, value_name, reserved, type, value, /)\n" +"--\n" +"\n" +"Stores data in the value field of an open registry key.\n" +"\n" +" key\n" +" An already open key, or any one of the predefined HKEY_* constants.\n" +" value_name\n" +" A string containing the name of the value to set, or None.\n" +" reserved\n" +" Can be anything - zero is always passed to the API.\n" +" type\n" +" An integer that specifies the type of the data, one of:\n" +" REG_BINARY -- Binary data in any form.\n" +" REG_DWORD -- A 32-bit number.\n" +" REG_DWORD_LITTLE_ENDIAN -- A 32-bit number in little-endian format.\n" +" REG_DWORD_BIG_ENDIAN -- A 32-bit number in big-endian format.\n" +" REG_EXPAND_SZ -- A null-terminated string that contains unexpanded\n" +" references to environment variables (for example,\n" +" %PATH%).\n" +" REG_LINK -- A Unicode symbolic link.\n" +" REG_MULTI_SZ -- An sequence of null-terminated strings, terminated\n" +" by two null characters. Note that Python handles\n" +" this termination automatically.\n" +" REG_NONE -- No defined value type.\n" +" REG_RESOURCE_LIST -- A device-driver resource list.\n" +" REG_SZ -- A null-terminated string.\n" +" value\n" +" A string that specifies the new value.\n" +"\n" +"This method can also set additional value and type information for the\n" +"specified key. The key identified by the key parameter must have been\n" +"opened with KEY_SET_VALUE access.\n" +"\n" +"To open the key, use the CreateKeyEx() or OpenKeyEx() methods.\n" +"\n" +"Value lengths are limited by available memory. Long values (more than\n" +"2048 bytes) should be stored as files with the filenames stored in\n" +"the configuration registry to help the registry perform efficiently."); + +#define WINREG_SETVALUEEX_METHODDEF \ + {"SetValueEx", (PyCFunction)winreg_SetValueEx, METH_VARARGS, winreg_SetValueEx__doc__}, + +static PyObject * +winreg_SetValueEx_impl(PyModuleDef *module, HKEY key, Py_UNICODE *value_name, + PyObject *reserved, DWORD type, PyObject *value); + +static PyObject * +winreg_SetValueEx(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + HKEY key; + Py_UNICODE *value_name; + PyObject *reserved; + DWORD type; + PyObject *value; + + if (!PyArg_ParseTuple(args, "O&ZOkO:SetValueEx", + clinic_HKEY_converter, &key, &value_name, &reserved, &type, &value)) + goto exit; + return_value = winreg_SetValueEx_impl(module, key, value_name, reserved, type, value); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_DisableReflectionKey__doc__, +"DisableReflectionKey($module, key, /)\n" +"--\n" +"\n" +"Disables registry reflection for 32bit processes running on a 64bit OS.\n" +"\n" +" key\n" +" An already open key, or any one of the predefined HKEY_* constants.\n" +"\n" +"Will generally raise NotImplemented if executed on a 32bit OS.\n" +"\n" +"If the key is not on the reflection list, the function succeeds but has\n" +"no effect. Disabling reflection for a key does not affect reflection\n" +"of any subkeys."); + +#define WINREG_DISABLEREFLECTIONKEY_METHODDEF \ + {"DisableReflectionKey", (PyCFunction)winreg_DisableReflectionKey, METH_O, winreg_DisableReflectionKey__doc__}, + +static PyObject * +winreg_DisableReflectionKey_impl(PyModuleDef *module, HKEY key); + +static PyObject * +winreg_DisableReflectionKey(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + HKEY key; + + if (!PyArg_Parse(arg, "O&:DisableReflectionKey", clinic_HKEY_converter, &key)) + goto exit; + return_value = winreg_DisableReflectionKey_impl(module, key); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_EnableReflectionKey__doc__, +"EnableReflectionKey($module, key, /)\n" +"--\n" +"\n" +"Restores registry reflection for the specified disabled key.\n" +"\n" +" key\n" +" An already open key, or any one of the predefined HKEY_* constants.\n" +"\n" +"Will generally raise NotImplemented if executed on a 32bit OS.\n" +"Restoring reflection for a key does not affect reflection of any\n" +"subkeys."); + +#define WINREG_ENABLEREFLECTIONKEY_METHODDEF \ + {"EnableReflectionKey", (PyCFunction)winreg_EnableReflectionKey, METH_O, winreg_EnableReflectionKey__doc__}, + +static PyObject * +winreg_EnableReflectionKey_impl(PyModuleDef *module, HKEY key); + +static PyObject * +winreg_EnableReflectionKey(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + HKEY key; + + if (!PyArg_Parse(arg, "O&:EnableReflectionKey", clinic_HKEY_converter, &key)) + goto exit; + return_value = winreg_EnableReflectionKey_impl(module, key); + +exit: + return return_value; +} + +PyDoc_STRVAR(winreg_QueryReflectionKey__doc__, +"QueryReflectionKey($module, key, /)\n" +"--\n" +"\n" +"Returns the reflection state for the specified key as a bool.\n" +"\n" +" key\n" +" An already open key, or any one of the predefined HKEY_* constants.\n" +"\n" +"Will generally raise NotImplemented if executed on a 32bit OS."); + +#define WINREG_QUERYREFLECTIONKEY_METHODDEF \ + {"QueryReflectionKey", (PyCFunction)winreg_QueryReflectionKey, METH_O, winreg_QueryReflectionKey__doc__}, + +static PyObject * +winreg_QueryReflectionKey_impl(PyModuleDef *module, HKEY key); + +static PyObject * +winreg_QueryReflectionKey(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + HKEY key; + + if (!PyArg_Parse(arg, "O&:QueryReflectionKey", clinic_HKEY_converter, &key)) + goto exit; + return_value = winreg_QueryReflectionKey_impl(module, key); + +exit: + return return_value; +} +/*[clinic end generated code: output=71f5bc30b646807b input=a9049054013a1b77]*/ diff --git a/PC/clinic/winsound.c.h b/PC/clinic/winsound.c.h new file mode 100644 index 000000000000..dca5a429f360 --- /dev/null +++ b/PC/clinic/winsound.c.h @@ -0,0 +1,100 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(winsound_PlaySound__doc__, +"PlaySound($module, sound, flags, /)\n" +"--\n" +"\n" +"A wrapper around the Windows PlaySound API.\n" +"\n" +" sound\n" +" The sound to play; a filename, data, or None.\n" +" flags\n" +" Flag values, ored together. See module documentation."); + +#define WINSOUND_PLAYSOUND_METHODDEF \ + {"PlaySound", (PyCFunction)winsound_PlaySound, METH_VARARGS, winsound_PlaySound__doc__}, + +static PyObject * +winsound_PlaySound_impl(PyModuleDef *module, Py_UNICODE *sound, int flags); + +static PyObject * +winsound_PlaySound(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_UNICODE *sound; + int flags; + + if (!PyArg_ParseTuple(args, "Zi:PlaySound", + &sound, &flags)) + goto exit; + return_value = winsound_PlaySound_impl(module, sound, flags); + +exit: + return return_value; +} + +PyDoc_STRVAR(winsound_Beep__doc__, +"Beep($module, frequency, duration, /)\n" +"--\n" +"\n" +"A wrapper around the Windows Beep API.\n" +"\n" +" frequency\n" +" Frequency of the sound in hertz.\n" +" Must be in the range 37 through 32,767.\n" +" duration\n" +" How long the sound should play, in milliseconds."); + +#define WINSOUND_BEEP_METHODDEF \ + {"Beep", (PyCFunction)winsound_Beep, METH_VARARGS, winsound_Beep__doc__}, + +static PyObject * +winsound_Beep_impl(PyModuleDef *module, int frequency, int duration); + +static PyObject * +winsound_Beep(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int frequency; + int duration; + + if (!PyArg_ParseTuple(args, "ii:Beep", + &frequency, &duration)) + goto exit; + return_value = winsound_Beep_impl(module, frequency, duration); + +exit: + return return_value; +} + +PyDoc_STRVAR(winsound_MessageBeep__doc__, +"MessageBeep($module, x=MB_OK, /)\n" +"--\n" +"\n" +"Call Windows MessageBeep(x).\n" +"\n" +"x defaults to MB_OK."); + +#define WINSOUND_MESSAGEBEEP_METHODDEF \ + {"MessageBeep", (PyCFunction)winsound_MessageBeep, METH_VARARGS, winsound_MessageBeep__doc__}, + +static PyObject * +winsound_MessageBeep_impl(PyModuleDef *module, int x); + +static PyObject * +winsound_MessageBeep(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int x = MB_OK; + + if (!PyArg_ParseTuple(args, "|i:MessageBeep", + &x)) + goto exit; + return_value = winsound_MessageBeep_impl(module, x); + +exit: + return return_value; +} +/*[clinic end generated code: output=c5b018ac9dc1f500 input=a9049054013a1b77]*/ diff --git a/PC/config.c b/PC/config.c index 72c938113008..66bf4580a012 100644 --- a/PC/config.c +++ b/PC/config.c @@ -1,7 +1,7 @@ /* Module configuration */ /* This file contains the table of built-in modules. - See init_builtin() in import.c. */ + See create_builtin() in import.c. */ #include "Python.h" @@ -19,7 +19,7 @@ extern PyObject* PyInit_math(void); extern PyObject* PyInit__md5(void); extern PyObject* PyInit_nt(void); extern PyObject* PyInit__operator(void); -extern PyObject* PyInit_signal(void); +extern PyObject* PyInit__signal(void); extern PyObject* PyInit__sha1(void); extern PyObject* PyInit__sha256(void); extern PyObject* PyInit__sha512(void); @@ -91,7 +91,7 @@ struct _inittab _PyImport_Inittab[] = { {"math", PyInit_math}, {"nt", PyInit_nt}, /* Use the NT os functions, not posix */ {"_operator", PyInit__operator}, - {"signal", PyInit_signal}, + {"_signal", PyInit__signal}, {"_md5", PyInit__md5}, {"_sha1", PyInit__sha1}, {"_sha256", PyInit__sha256}, diff --git a/PC/dl_nt.c b/PC/dl_nt.c index ae10fb56231b..c87c51eb559f 100644 --- a/PC/dl_nt.c +++ b/PC/dl_nt.c @@ -12,7 +12,12 @@ forgotten) from the programmer. #include "windows.h" #ifdef Py_ENABLE_SHARED +#ifdef MS_DLL_ID +// The string is available at build, so fill the buffer immediately +char dllVersionBuffer[16] = MS_DLL_ID; +#else char dllVersionBuffer[16] = ""; // a private buffer +#endif // Python Globals HMODULE PyWin_DLLhModule = NULL; @@ -88,8 +93,11 @@ BOOL WINAPI DllMain (HANDLE hInst, { case DLL_PROCESS_ATTACH: PyWin_DLLhModule = hInst; +#ifndef MS_DLL_ID + // If we have MS_DLL_ID, we don't need to load the string. // 1000 is a magic number I picked out of the air. Could do with a #define, I spose... LoadString(hInst, 1000, dllVersionBuffer, sizeof(dllVersionBuffer)); +#endif #if HAVE_SXS // and capture our activation context for use when loading extensions. diff --git a/PC/example_nt/example.c b/PC/example_nt/example.c deleted file mode 100644 index 669d11b269fb..000000000000 --- a/PC/example_nt/example.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "Python.h" - -static PyObject * -ex_foo(PyObject *self, PyObject *args) -{ - printf("Hello, world\n"); - Py_INCREF(Py_None); - return Py_None; -} - -static PyMethodDef example_methods[] = { - {"foo", ex_foo, METH_VARARGS, "foo() doc string"}, - {NULL, NULL} -}; - -static struct PyModuleDef examplemodule = { - PyModuleDef_HEAD_INIT, - "example", - "example module doc string", - -1, - example_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit_example(void) -{ - return PyModule_Create(&examplemodule); -} diff --git a/PC/example_nt/example.sln b/PC/example_nt/example.sln deleted file mode 100644 index d8a3119f2f90..000000000000 --- a/PC/example_nt/example.sln +++ /dev/null @@ -1,21 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example", "example.vcproj", "{A0608D6F-84ED-44AE-A2A6-A3CC7F4A4030}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Release = Release - EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {A0608D6F-84ED-44AE-A2A6-A3CC7F4A4030}.Debug.ActiveCfg = Debug|Win32 - {A0608D6F-84ED-44AE-A2A6-A3CC7F4A4030}.Debug.Build.0 = Debug|Win32 - {A0608D6F-84ED-44AE-A2A6-A3CC7F4A4030}.Release.ActiveCfg = Release|Win32 - {A0608D6F-84ED-44AE-A2A6-A3CC7F4A4030}.Release.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution - EndGlobalSection -EndGlobal diff --git a/PC/example_nt/example.vcproj b/PC/example_nt/example.vcproj deleted file mode 100644 index df36341137ad..000000000000 --- a/PC/example_nt/example.vcproj +++ /dev/null @@ -1,189 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/PC/example_nt/readme.txt b/PC/example_nt/readme.txt deleted file mode 100644 index b83888c99164..000000000000 --- a/PC/example_nt/readme.txt +++ /dev/null @@ -1,183 +0,0 @@ -Example Python extension for Windows NT -======================================= - -This directory contains everything needed (except for the Python -distribution!) to build a Python extension module using Microsoft VC++. -Notice that you need to use the same compiler version that was used to build -Python itself. - -The simplest way to build this example is to use the distutils script -'setup.py'. To do this, simply execute: - - % python setup.py install - -after everything builds and installs, you can test it: - - % python -c "import example; example.foo()" - Hello, world - -See setup.py for more details. alternatively, see below for instructions on -how to build inside the Visual Studio environment. - -Visual Studio Build Instructions -================================ - -These are instructions how to build an extension using Visual C++. The -instructions and project files have not been updated to the latest VC -version. In general, it is recommended you use the 'setup.py' instructions -above. - -It has been tested with VC++ 7.1 on Python 2.4. You can also use earlier -versions of VC to build Python extensions, but the sample VC project file -(example.dsw in this directory) is in VC 7.1 format. - -COPY THIS DIRECTORY! --------------------- -This "example_nt" directory is a subdirectory of the PC directory, in order -to keep all the PC-specific files under the same directory. However, the -example_nt directory can't actually be used from this location. You first -need to copy or move it up one level, so that example_nt is a direct -sibling of the PC\ and Include\ directories. Do all your work from within -this new location -- sorry, but you'll be sorry if you don't. - -OPEN THE PROJECT ----------------- -From VC 7.1, use the - File -> Open Solution... -dialog (*not* the "File -> Open..." dialog!). Navigate to and select the -file "example.sln", in the *copy* of the example_nt directory you made -above. -Click Open. - -BUILD THE EXAMPLE DLL ---------------------- -In order to check that everything is set up right, try building: - -1. Select a configuration. This step is optional. Do - Build -> Configuration Manager... -> Active Solution Configuration - and select either "Release" or "Debug". - If you skip this step, you'll use the Debug configuration by default. - -2. Build the DLL. Do - Build -> Build Solution - This creates all intermediate and result files in a subdirectory which - is called either Debug or Release, depending on which configuration you - picked in the preceding step. - -TESTING THE DEBUG-MODE DLL --------------------------- -Once the Debug build has succeeded, bring up a DOS box, and cd to -example_nt\Debug. You should now be able to repeat the following session -("C>" is the DOS prompt, ">>>" is the Python prompt) (note that various -debug output from Python may not match this screen dump exactly): - - C>..\..\PCbuild\python_d - Adding parser accelerators ... - Done. - Python 2.2c1+ (#28, Dec 14 2001, 18:06:39) [MSC 32 bit (Intel)] on win32 - Type "help", "copyright", "credits" or "license" for more information. - >>> import example - [7052 refs] - >>> example.foo() - Hello, world - [7052 refs] - >>> - -TESTING THE RELEASE-MODE DLL ----------------------------- -Once the Release build has succeeded, bring up a DOS box, and cd to -example_nt\Release. You should now be able to repeat the following session -("C>" is the DOS prompt, ">>>" is the Python prompt): - - C>..\..\PCbuild\python - Python 2.2c1+ (#28, Dec 14 2001, 18:06:04) [MSC 32 bit (Intel)] on win32 - Type "help", "copyright", "credits" or "license" for more information. - >>> import example - >>> example.foo() - Hello, world - >>> - -Congratulations! You've successfully built your first Python extension -module. - -CREATING YOUR OWN PROJECT -------------------------- -Choose a name ("spam" is always a winner :-) and create a directory for -it. Copy your C sources into it. Note that the module source file name -does not necessarily have to match the module name, but the "init" function -name should match the module name -- i.e. you can only import a module -"spam" if its init function is called "initspam()", and it should call -Py_InitModule with the string "spam" as its first argument (use the minimal -example.c in this directory as a guide). By convention, it lives in a file -called "spam.c" or "spammodule.c". The output file should be called -"spam.dll" or "spam.pyd" (the latter is supported to avoid confusion with a -system library "spam.dll" to which your module could be a Python interface) -in Release mode, or spam_d.dll or spam_d.pyd in Debug mode. - -Now your options are: - -1) Copy example.sln and example.vcproj, rename them to spam.*, and edit them -by hand. - -or - -2) Create a brand new project; instructions are below. - -In either case, copy example_nt\example.def to spam\spam.def, and edit the -new spam.def so its second line contains the string "initspam". If you -created a new project yourself, add the file spam.def to the project now. -(This is an annoying little file with only two lines. An alternative -approach is to forget about the .def file, and add the option -"/export:initspam" somewhere to the Link settings, by manually editing the -"Project -> Properties -> Linker -> Command Line -> Additional Options" -box). - -You are now all set to build your extension, unless it requires other -external libraries, include files, etc. See Python's Extending and -Embedding manual for instructions on how to write an extension. - - -CREATING A BRAND NEW PROJECT ----------------------------- -Use the - File -> New -> Project... -dialog to create a new Project Workspace. Select "Visual C++ Projects/Win32/ -Win32 Project", enter the name ("spam"), and make sure the "Location" is -set to parent of the spam directory you have created (which should be a direct -subdirectory of the Python build tree, a sibling of Include and PC). -In "Application Settings", select "DLL", and "Empty Project". Click OK. - -You should now create the file spam.def as instructed in the previous -section. Add the source files (including the .def file) to the project, -using "Project", "Add Existing Item". - -Now open the - Project -> spam properties... -dialog. (Impressive, isn't it? :-) You only need to change a few -settings. Make sure "All Configurations" is selected from the "Settings -for:" dropdown list. Select the "C/C++" tab. Choose the "General" -category in the popup menu at the top. Type the following text in the -entry box labeled "Addditional Include Directories:" - - ..\Include,..\PC - -Then, choose the "General" category in the "Linker" tab, and enter - ..\PCbuild -in the "Additional library Directories" box. - -Now you need to add some mode-specific settings (select "Accept" -when asked to confirm your changes): - -Select "Release" in the "Configuration" dropdown list. Click the -"Link" tab, choose the "Input" Category, and append "python24.lib" to the -list in the "Additional Dependencies" box. - -Select "Debug" in the "Settings for:" dropdown list, and append -"python24_d.lib" to the list in the Additional Dependencies" box. Then -click on the C/C++ tab, select "Code Generation", and select -"Multi-threaded Debug DLL" from the "Runtime library" dropdown list. - -Select "Release" again from the "Settings for:" dropdown list. -Select "Multi-threaded DLL" from the "Use run-time library:" dropdown list. - -That's all . diff --git a/PC/example_nt/setup.py b/PC/example_nt/setup.py deleted file mode 100644 index 0443bc700094..000000000000 --- a/PC/example_nt/setup.py +++ /dev/null @@ -1,22 +0,0 @@ -# This is an example of a distutils 'setup' script for the example_nt -# sample. This provides a simpler way of building your extension -# and means you can avoid keeping MSVC solution files etc in source-control. -# It also means it should magically build with all compilers supported by -# python. - -# USAGE: you probably want 'setup.py install' - but execute 'setup.py --help' -# for all the details. - -# NOTE: This is *not* a sample for distutils - it is just the smallest -# script that can build this. See distutils docs for more info. - -from distutils.core import setup, Extension - -example_mod = Extension('example', sources = ['example.c']) - - -setup(name = "example", - version = "1.0", - description = "A sample extension module", - ext_modules = [example_mod], -) diff --git a/PC/getpathp.c b/PC/getpathp.c index deb40e76f362..25b328b260c1 100644 --- a/PC/getpathp.c +++ b/PC/getpathp.c @@ -113,7 +113,10 @@ is_sep(wchar_t ch) /* determine if "ch" is a separator character */ static void reduce(wchar_t *dir) { - size_t i = wcslen(dir); + size_t i = wcsnlen_s(dir, MAXPATHLEN+1); + if (i >= MAXPATHLEN+1) + Py_FatalError("buffer overflow in getpathp.c's reduce()"); + while (i > 0 && !is_sep(dir[i])) --i; dir[i] = '\0'; @@ -130,16 +133,23 @@ exists(wchar_t *filename) may extend 'filename' by one character. */ static int -ismodule(wchar_t *filename) /* Is module -- check for .pyc/.pyo too */ +ismodule(wchar_t *filename, int update_filename) /* Is module -- check for .pyc/.pyo too */ { + int n; + if (exists(filename)) return 1; /* Check for the compiled version of prefix. */ - if (wcslen(filename) < MAXPATHLEN) { - wcscat(filename, Py_OptimizeFlag ? L"o" : L"c"); - if (exists(filename)) - return 1; + n = wcsnlen_s(filename, MAXPATHLEN+1); + if (n < MAXPATHLEN) { + int exist = 0; + filename[n] = Py_OptimizeFlag ? L'o' : L'c'; + filename[n + 1] = L'\0'; + exist = exists(filename); + if (!update_filename) + filename[n] = L'\0'; + return exist; } return 0; } @@ -154,23 +164,23 @@ ismodule(wchar_t *filename) /* Is module -- check for .pyc/.pyo too */ stuff as fits will be appended. */ static void -join(wchar_t *buffer, wchar_t *stuff) +join(wchar_t *buffer, const wchar_t *stuff) { - size_t n, k; - if (is_sep(stuff[0])) - n = 0; - else { - n = wcslen(buffer); - if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN) - buffer[n++] = SEP; + size_t n; + if (is_sep(stuff[0]) || + (wcsnlen_s(stuff, 4) >= 3 && stuff[1] == ':' && is_sep(stuff[2]))) { + if (wcscpy_s(buffer, MAXPATHLEN+1, stuff) != 0) + Py_FatalError("buffer overflow in getpathp.c's join()"); + return; + } + + n = wcsnlen_s(buffer, MAXPATHLEN+1); + if (n > 0 && !is_sep(buffer[n - 1]) && n < MAXPATHLEN) { + buffer[n] = SEP; + buffer[n + 1] = '\0'; } - if (n > MAXPATHLEN) - Py_FatalError("buffer overflow in getpathp.c's joinpath()"); - k = wcslen(stuff); - if (n + k > MAXPATHLEN) - k = MAXPATHLEN - n; - wcsncpy(buffer+n, stuff, k); - buffer[n+k] = '\0'; + if (wcscat_s(buffer, MAXPATHLEN+1, stuff) != 0) + Py_FatalError("buffer overflow in getpathp.c's join()"); } /* gotlandmark only called by search_for_prefix, which ensures @@ -181,11 +191,10 @@ static int gotlandmark(wchar_t *landmark) { int ok; - Py_ssize_t n; + Py_ssize_t n = wcsnlen_s(prefix, MAXPATHLEN); - n = wcslen(prefix); join(prefix, landmark); - ok = ismodule(prefix); + ok = ismodule(prefix, FALSE); prefix[n] = '\0'; return ok; } @@ -196,7 +205,7 @@ static int search_for_prefix(wchar_t *argv0_path, wchar_t *landmark) { /* Search from argv0_path, until landmark is found */ - wcscpy(prefix, argv0_path); + wcscpy_s(prefix, MAXPATHLEN + 1, argv0_path); do { if (gotlandmark(landmark)) return 1; @@ -236,7 +245,7 @@ getpythonregpath(HKEY keyBase, int skipcore) WCHAR *dataBuf = NULL; static const WCHAR keyPrefix[] = L"Software\\Python\\PythonCore\\"; static const WCHAR keySuffix[] = L"\\PythonPath"; - size_t versionLen; + size_t versionLen, keyBufLen; DWORD index; WCHAR *keyBuf = NULL; WCHAR *keyBufPtr; @@ -245,12 +254,13 @@ getpythonregpath(HKEY keyBase, int skipcore) /* Tried to use sysget("winver") but here is too early :-( */ versionLen = strlen(PyWin_DLLVersionString); /* Space for all the chars, plus one \0 */ - keyBuf = keyBufPtr = PyMem_RawMalloc(sizeof(keyPrefix) + - sizeof(WCHAR)*(versionLen-1) + - sizeof(keySuffix)); + keyBufLen = sizeof(keyPrefix) + + sizeof(WCHAR)*(versionLen-1) + + sizeof(keySuffix); + keyBuf = keyBufPtr = PyMem_RawMalloc(keyBufLen); if (keyBuf==NULL) goto done; - memcpy(keyBufPtr, keyPrefix, sizeof(keyPrefix)-sizeof(WCHAR)); + memcpy_s(keyBufPtr, keyBufLen, keyPrefix, sizeof(keyPrefix)-sizeof(WCHAR)); keyBufPtr += Py_ARRAY_LENGTH(keyPrefix) - 1; mbstowcs(keyBufPtr, PyWin_DLLVersionString, versionLen); keyBufPtr += versionLen; @@ -451,11 +461,12 @@ find_env_config_value(FILE * env_file, const wchar_t * key, wchar_t * value) tmpbuffer, MAXPATHLEN * 2); Py_DECREF(decoded); if (k >= 0) { - wchar_t * tok = wcstok(tmpbuffer, L" \t\r\n"); + wchar_t * context = NULL; + wchar_t * tok = wcstok_s(tmpbuffer, L" \t\r\n", &context); if ((tok != NULL) && !wcscmp(tok, key)) { - tok = wcstok(NULL, L" \t"); + tok = wcstok_s(NULL, L" \t", &context); if ((tok != NULL) && !wcscmp(tok, L"=")) { - tok = wcstok(NULL, L"\r\n"); + tok = wcstok_s(NULL, L"\r\n", &context); if (tok != NULL) { wcsncpy(value, tok, MAXPATHLEN); result = 1; @@ -483,7 +494,7 @@ calculate_path(void) wchar_t *machinepath = NULL; wchar_t *userpath = NULL; wchar_t zip_path[MAXPATHLEN+1]; - size_t len; + int applocal = 0; if (!Py_IgnoreEnvironmentFlag) { envpath = _wgetenv(L"PYTHONPATH"); @@ -501,7 +512,7 @@ calculate_path(void) get_progpath(); /* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */ - wcscpy(argv0_path, progpath); + wcscpy_s(argv0_path, MAXPATHLEN+1, progpath); reduce(argv0_path); /* Search for an environment configuration file, first in the @@ -510,27 +521,39 @@ calculate_path(void) */ { + wchar_t envbuffer[MAXPATHLEN+1]; wchar_t tmpbuffer[MAXPATHLEN+1]; - wchar_t *env_cfg = L"pyvenv.cfg"; + const wchar_t *env_cfg = L"pyvenv.cfg"; FILE * env_file = NULL; - wcscpy(tmpbuffer, argv0_path); - join(tmpbuffer, env_cfg); - env_file = _Py_wfopen(tmpbuffer, L"r"); + wcscpy_s(envbuffer, MAXPATHLEN+1, argv0_path); + join(envbuffer, env_cfg); + env_file = _Py_wfopen(envbuffer, L"r"); if (env_file == NULL) { errno = 0; - reduce(tmpbuffer); - reduce(tmpbuffer); - join(tmpbuffer, env_cfg); - env_file = _Py_wfopen(tmpbuffer, L"r"); + reduce(envbuffer); + reduce(envbuffer); + join(envbuffer, env_cfg); + env_file = _Py_wfopen(envbuffer, L"r"); if (env_file == NULL) { errno = 0; } } if (env_file != NULL) { + /* Look for an 'applocal' variable and, if true, ignore all registry + * keys and environment variables, but retain the default paths + * (DLLs, Lib) and the zip file. Setting pythonhome here suppresses + * the search for LANDMARK below and overrides %PYTHONHOME%. + */ + if (find_env_config_value(env_file, L"applocal", tmpbuffer) && + (applocal = (wcsicmp(tmpbuffer, L"true") == 0))) { + envpath = NULL; + pythonhome = argv0_path; + } + /* Look for a 'home' variable and set argv0_path to it, if found */ if (find_env_config_value(env_file, L"home", tmpbuffer)) { - wcscpy(argv0_path, tmpbuffer); + wcscpy_s(argv0_path, MAXPATHLEN+1, tmpbuffer); } fclose(env_file); env_file = NULL; @@ -544,33 +567,30 @@ calculate_path(void) pythonhome = NULL; } else - wcsncpy(prefix, pythonhome, MAXPATHLEN); + wcscpy_s(prefix, MAXPATHLEN+1, pythonhome); if (envpath && *envpath == '\0') envpath = NULL; #ifdef MS_WINDOWS - /* Calculate zip archive path */ - if (dllpath[0]) /* use name of python DLL */ - wcsncpy(zip_path, dllpath, MAXPATHLEN); - else /* use name of executable program */ - wcsncpy(zip_path, progpath, MAXPATHLEN); - zip_path[MAXPATHLEN] = '\0'; - len = wcslen(zip_path); - if (len > 4) { - zip_path[len-3] = 'z'; /* change ending to "zip" */ - zip_path[len-2] = 'i'; - zip_path[len-1] = 'p'; - } + /* Calculate zip archive path from DLL or exe path */ + if (wcscpy_s(zip_path, MAXPATHLEN+1, dllpath[0] ? dllpath : progpath)) + /* exceeded buffer length - ignore zip_path */ + zip_path[0] = '\0'; else { - zip_path[0] = 0; + wchar_t *dot = wcsrchr(zip_path, '.'); + if (!dot || wcscpy_s(dot, MAXPATHLEN+1 - (dot - zip_path), L".zip")) + /* exceeded buffer length - ignore zip_path */ + zip_path[0] = L'\0'; } skiphome = pythonhome==NULL ? 0 : 1; #ifdef Py_ENABLE_SHARED - machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome); - userpath = getpythonregpath(HKEY_CURRENT_USER, skiphome); + if (!applocal) { + machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome); + userpath = getpythonregpath(HKEY_CURRENT_USER, skiphome); + } #endif /* We only use the default relative PYTHONPATH if we havent anything better to use! */ @@ -589,6 +609,7 @@ calculate_path(void) Extra rules: - If PYTHONHOME is set (in any way) item (3) is ignored. - If registry values are used, (4) and (5) are ignored. + - If applocal is set, (1), (3), and registry values are ignored */ /* Calculate size of return buffer */ @@ -606,9 +627,9 @@ calculate_path(void) bufsz += wcslen(PYTHONPATH) + 1; bufsz += wcslen(argv0_path) + 1; #ifdef MS_WINDOWS - if (userpath) + if (!applocal && userpath) bufsz += wcslen(userpath) + 1; - if (machinepath) + if (!applocal && machinepath) bufsz += wcslen(machinepath) + 1; bufsz += wcslen(zip_path) + 1; #endif @@ -635,38 +656,45 @@ calculate_path(void) } if (envpath) { - wcscpy(buf, envpath); + if (wcscpy_s(buf, bufsz - (buf - module_search_path), envpath)) + Py_FatalError("buffer overflow in getpathp.c's calculate_path()"); buf = wcschr(buf, L'\0'); *buf++ = DELIM; } #ifdef MS_WINDOWS if (zip_path[0]) { - wcscpy(buf, zip_path); + if (wcscpy_s(buf, bufsz - (buf - module_search_path), zip_path)) + Py_FatalError("buffer overflow in getpathp.c's calculate_path()"); buf = wcschr(buf, L'\0'); *buf++ = DELIM; } if (userpath) { - wcscpy(buf, userpath); + if (wcscpy_s(buf, bufsz - (buf - module_search_path), userpath)) + Py_FatalError("buffer overflow in getpathp.c's calculate_path()"); buf = wcschr(buf, L'\0'); *buf++ = DELIM; PyMem_RawFree(userpath); } if (machinepath) { - wcscpy(buf, machinepath); + if (wcscpy_s(buf, bufsz - (buf - module_search_path), machinepath)) + Py_FatalError("buffer overflow in getpathp.c's calculate_path()"); buf = wcschr(buf, L'\0'); *buf++ = DELIM; PyMem_RawFree(machinepath); } if (pythonhome == NULL) { if (!skipdefault) { - wcscpy(buf, PYTHONPATH); + if (wcscpy_s(buf, bufsz - (buf - module_search_path), PYTHONPATH)) + Py_FatalError("buffer overflow in getpathp.c's calculate_path()"); buf = wcschr(buf, L'\0'); + *buf++ = DELIM; } } #else if (pythonhome == NULL) { wcscpy(buf, PYTHONPATH); buf = wcschr(buf, L'\0'); + *buf++ = DELIM; } #endif /* MS_WINDOWS */ else { @@ -680,25 +708,26 @@ calculate_path(void) else n = q-p; if (p[0] == '.' && is_sep(p[1])) { - wcscpy(buf, pythonhome); + if (wcscpy_s(buf, bufsz - (buf - module_search_path), pythonhome)) + Py_FatalError("buffer overflow in getpathp.c's calculate_path()"); buf = wcschr(buf, L'\0'); p++; n--; } wcsncpy(buf, p, n); buf += n; + *buf++ = DELIM; if (q == NULL) break; - *buf++ = DELIM; p = q+1; } } if (argv0_path) { - *buf++ = DELIM; wcscpy(buf, argv0_path); buf = wcschr(buf, L'\0'); + *buf++ = DELIM; } - *buf = L'\0'; + *(buf - 1) = L'\0'; /* Now to pull one last hack/trick. If sys.prefix is empty, then try and find it somewhere on the paths we calculated. We scan backwards, as our general policy diff --git a/PC/invalid_parameter_handler.c b/PC/invalid_parameter_handler.c new file mode 100644 index 000000000000..d634710cbec7 --- /dev/null +++ b/PC/invalid_parameter_handler.c @@ -0,0 +1,22 @@ +#ifdef _MSC_VER + +#include + +#if _MSC_VER >= 1900 +/* pyconfig.h uses this function in the _Py_BEGIN/END_SUPPRESS_IPH + * macros. It does not need to be defined when building using MSVC + * earlier than 14.0 (_MSC_VER == 1900). + */ + +static void __cdecl _silent_invalid_parameter_handler( + wchar_t const* expression, + wchar_t const* function, + wchar_t const* file, + unsigned int line, + uintptr_t pReserved) { } + +_invalid_parameter_handler _Py_silent_invalid_parameter_handler = _silent_invalid_parameter_handler; + +#endif + +#endif diff --git a/PC/launcher.c b/PC/launcher.c index ee3cd44ddc4c..fada4c9c16ad 100644 --- a/PC/launcher.c +++ b/PC/launcher.c @@ -87,16 +87,16 @@ error(int rc, wchar_t * format, ... ) if (rc == 0) { /* a Windows error */ winerror(GetLastError(), win_message, MSGSIZE); if (len >= 0) { - _snwprintf_s(&message[len], MSGSIZE - len, _TRUNCATE, L": %s", + _snwprintf_s(&message[len], MSGSIZE - len, _TRUNCATE, L": %ls", win_message); } } #if !defined(_WINDOWS) - fwprintf(stderr, L"%s\n", message); + fwprintf(stderr, L"%ls\n", message); #else MessageBox(NULL, message, TEXT("Python Launcher is sorry to say ..."), - MB_OK); + MB_OK); #endif ExitProcess(rc); } @@ -157,14 +157,19 @@ static INSTALLED_PYTHON installed_pythons[MAX_INSTALLED_PYTHONS]; static size_t num_installed_pythons = 0; -/* to hold SOFTWARE\Python\PythonCore\X.Y\InstallPath */ +/* + * To hold SOFTWARE\Python\PythonCore\X.Y...\InstallPath + * The version name can be longer than MAX_VERSION_SIZE, but will be + * truncated to just X.Y for comparisons. + */ #define IP_BASE_SIZE 40 -#define IP_SIZE (IP_BASE_SIZE + MAX_VERSION_SIZE) +#define IP_VERSION_SIZE 8 +#define IP_SIZE (IP_BASE_SIZE + IP_VERSION_SIZE) #define CORE_PATH L"SOFTWARE\\Python\\PythonCore" static wchar_t * location_checks[] = { L"\\", - L"\\PCBuild\\", + L"\\PCBuild\\win32\\", L"\\PCBuild\\amd64\\", NULL }; @@ -196,35 +201,38 @@ locate_pythons_for_key(HKEY root, REGSAM flags) BOOL ok; DWORD type, data_size, attrs; INSTALLED_PYTHON * ip, * pip; + wchar_t ip_version[IP_VERSION_SIZE]; wchar_t ip_path[IP_SIZE]; wchar_t * check; wchar_t ** checkp; wchar_t *key_name = (root == HKEY_LOCAL_MACHINE) ? L"HKLM" : L"HKCU"; if (status != ERROR_SUCCESS) - debug(L"locate_pythons_for_key: unable to open PythonCore key in %s\n", + debug(L"locate_pythons_for_key: unable to open PythonCore key in %ls\n", key_name); else { ip = &installed_pythons[num_installed_pythons]; for (i = 0; num_installed_pythons < MAX_INSTALLED_PYTHONS; i++) { - status = RegEnumKeyW(core_root, i, ip->version, MAX_VERSION_SIZE); + status = RegEnumKeyW(core_root, i, ip_version, IP_VERSION_SIZE); if (status != ERROR_SUCCESS) { if (status != ERROR_NO_MORE_ITEMS) { /* unexpected error */ winerror(status, message, MSGSIZE); - debug(L"Can't enumerate registry key for version %s: %s\n", - ip->version, message); + debug(L"Can't enumerate registry key for version %ls: %ls\n", + ip_version, message); } break; } else { + wcsncpy_s(ip->version, MAX_VERSION_SIZE, ip_version, + MAX_VERSION_SIZE-1); _snwprintf_s(ip_path, IP_SIZE, _TRUNCATE, - L"%s\\%s\\InstallPath", CORE_PATH, ip->version); + L"%ls\\%ls\\InstallPath", CORE_PATH, ip_version); status = RegOpenKeyExW(root, ip_path, 0, flags, &ip_key); if (status != ERROR_SUCCESS) { winerror(status, message, MSGSIZE); // Note: 'message' already has a trailing \n - debug(L"%s\\%s: %s", key_name, ip_path, message); + debug(L"%ls\\%ls: %ls", key_name, ip_path, message); continue; } data_size = sizeof(ip->executable) - 1; @@ -233,7 +241,7 @@ locate_pythons_for_key(HKEY root, REGSAM flags) RegCloseKey(ip_key); if (status != ERROR_SUCCESS) { winerror(status, message, MSGSIZE); - debug(L"%s\\%s: %s\n", key_name, ip_path, message); + debug(L"%ls\\%ls: %ls\n", key_name, ip_path, message); continue; } if (type == REG_SZ) { @@ -246,27 +254,27 @@ locate_pythons_for_key(HKEY root, REGSAM flags) _snwprintf_s(&ip->executable[data_size], MAX_PATH - data_size, MAX_PATH - data_size, - L"%s%s", check, PYTHON_EXECUTABLE); + L"%ls%ls", check, PYTHON_EXECUTABLE); attrs = GetFileAttributesW(ip->executable); if (attrs == INVALID_FILE_ATTRIBUTES) { winerror(GetLastError(), message, MSGSIZE); - debug(L"locate_pythons_for_key: %s: %s", + debug(L"locate_pythons_for_key: %ls: %ls", ip->executable, message); } else if (attrs & FILE_ATTRIBUTE_DIRECTORY) { - debug(L"locate_pythons_for_key: '%s' is a \ + debug(L"locate_pythons_for_key: '%ls' is a \ directory\n", ip->executable, attrs); } else if (find_existing_python(ip->executable)) { - debug(L"locate_pythons_for_key: %s: already \ -found: %s\n", ip->executable); + debug(L"locate_pythons_for_key: %ls: already \ +found\n", ip->executable); } else { /* check the executable type. */ ok = GetBinaryTypeW(ip->executable, &attrs); if (!ok) { - debug(L"Failure getting binary type: %s\n", + debug(L"Failure getting binary type: %ls\n", ip->executable); } else { @@ -277,7 +285,7 @@ found: %s\n", ip->executable); else ip->bits = 0; if (ip->bits == 0) { - debug(L"locate_pythons_for_key: %s: \ + debug(L"locate_pythons_for_key: %ls: \ invalid binary type: %X\n", ip->executable, attrs); } @@ -291,7 +299,7 @@ invalid binary type: %X\n", ip->executable[n + 1] = L'\"'; ip->executable[n + 2] = L'\0'; } - debug(L"locate_pythons_for_key: %s \ + debug(L"locate_pythons_for_key: %ls \ is a %dbit executable\n", ip->executable, ip->bits); ++num_installed_pythons; @@ -341,7 +349,7 @@ locate_all_pythons() locate_pythons_for_key(HKEY_CURRENT_USER, KEY_READ | KEY_WOW64_64KEY); locate_pythons_for_key(HKEY_LOCAL_MACHINE, KEY_READ | KEY_WOW64_64KEY); } -#endif +#endif // now hit the "native" key for this process bittedness. debug(L"locating Pythons in native registry\n"); locate_pythons_for_key(HKEY_CURRENT_USER, KEY_READ); @@ -376,6 +384,31 @@ find_python_by_version(wchar_t const * wanted_ver) } +static wchar_t * +find_python_by_venv() +{ + static wchar_t venv_python[MAX_PATH]; + wchar_t *virtual_env = get_env(L"VIRTUAL_ENV"); + DWORD attrs; + + /* Check for VIRTUAL_ENV environment variable */ + if (virtual_env == NULL || virtual_env[0] == L'\0') { + return NULL; + } + + /* Check for a python executable in the venv */ + debug(L"Checking for Python executable in virtual env '%ls'\n", virtual_env); + _snwprintf_s(venv_python, MAX_PATH, _TRUNCATE, + L"%ls\\Scripts\\%ls", virtual_env, PYTHON_EXECUTABLE); + attrs = GetFileAttributesW(venv_python); + if (attrs == INVALID_FILE_ATTRIBUTES) { + debug(L"Python executable %ls missing from virtual env\n", venv_python); + return NULL; + } + + return venv_python; +} + static wchar_t appdata_ini_path[MAX_PATH]; static wchar_t launcher_ini_path[MAX_PATH]; @@ -397,7 +430,7 @@ get_configured_value(wchar_t * key) DWORD size; /* First, search the environment. */ - _snwprintf_s(configured_value, MSGSIZE, _TRUNCATE, L"py_%s", key); + _snwprintf_s(configured_value, MSGSIZE, _TRUNCATE, L"py_%ls", key); result = get_env(configured_value); if (result == NULL && appdata_ini_path[0]) { /* Not in environment: check local configuration. */ @@ -420,10 +453,10 @@ get_configured_value(wchar_t * key) } } if (result) { - debug(L"found configured value '%s=%s' in %s\n", + debug(L"found configured value '%ls=%ls' in %ls\n", key, result, found_in ? found_in : L"(unknown)"); } else { - debug(L"found no configured value for '%s'\n", key); + debug(L"found no configured value for '%ls'\n", key); } return result; } @@ -449,9 +482,9 @@ locate_python(wchar_t * wanted_ver) } if (*wanted_ver) { result = find_python_by_version(wanted_ver); - debug(L"search for Python version '%s' found ", wanted_ver); + debug(L"search for Python version '%ls' found ", wanted_ver); if (result) { - debug(L"'%s'\n", result->executable); + debug(L"'%ls'\n", result->executable); } else { debug(L"no interpreter\n"); } @@ -467,7 +500,7 @@ locate_python(wchar_t * wanted_ver) result = find_python_by_version(L"3"); debug(L"search for default Python found "); if (result) { - debug(L"version %s at '%s'\n", + debug(L"version %ls at '%ls'\n", result->version, result->executable); } else { debug(L"no interpreter\n"); @@ -505,19 +538,19 @@ locate_wrapped_script() plen = GetModuleFileNameW(NULL, wrapped_script_path, MAX_PATH); p = wcsrchr(wrapped_script_path, L'.'); if (p == NULL) { - debug(L"GetModuleFileNameW returned value has no extension: %s\n", + debug(L"GetModuleFileNameW returned value has no extension: %ls\n", wrapped_script_path); - error(RC_NO_SCRIPT, L"Wrapper name '%s' is not valid.", wrapped_script_path); + error(RC_NO_SCRIPT, L"Wrapper name '%ls' is not valid.", wrapped_script_path); } wcsncpy_s(p, MAX_PATH - (p - wrapped_script_path) + 1, SCRIPT_SUFFIX, _TRUNCATE); attrs = GetFileAttributesW(wrapped_script_path); if (attrs == INVALID_FILE_ATTRIBUTES) { - debug(L"File '%s' non-existent\n", wrapped_script_path); - error(RC_NO_SCRIPT, L"Script file '%s' is not present.", wrapped_script_path); + debug(L"File '%ls' non-existent\n", wrapped_script_path); + error(RC_NO_SCRIPT, L"Script file '%ls' is not present.", wrapped_script_path); } - debug(L"Using wrapped script file '%s'\n", wrapped_script_path); + debug(L"Using wrapped script file '%ls'\n", wrapped_script_path); } #endif @@ -571,7 +604,7 @@ run_child(wchar_t * cmdline) // window, or fetching a message). As this launcher doesn't do this // directly, that cursor remains even after the child process does these // things. We avoid that by doing a simple post+get message. - // See http://bugs.python.org/issue17290 and + // See http://bugs.python.org/issue17290 and // https://bitbucket.org/vinay.sajip/pylauncher/issue/20/busy-cursor-for-a-long-time-when-running MSG msg; @@ -579,7 +612,7 @@ run_child(wchar_t * cmdline) GetMessage(&msg, 0, 0, 0); #endif - debug(L"run_child: about to run '%s'\n", cmdline); + debug(L"run_child: about to run '%ls'\n", cmdline); job = CreateJobObject(NULL, NULL); ok = QueryInformationJobObject(job, JobObjectExtendedLimitInformation, &info, sizeof(info), &rc); @@ -611,7 +644,7 @@ run_child(wchar_t * cmdline) ok = CreateProcessW(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); if (!ok) - error(RC_CREATE_PROCESS, L"Unable to create process using '%s'", cmdline); + error(RC_CREATE_PROCESS, L"Unable to create process using '%ls'", cmdline); AssignProcessToJobObject(job, pi.hProcess); CloseHandle(pi.hThread); WaitForSingleObjectEx(pi.hProcess, INFINITE, FALSE); @@ -648,11 +681,11 @@ invoke_child(wchar_t * executable, wchar_t * suffix, wchar_t * cmdline) child_command_size); if (no_suffix) _snwprintf_s(child_command, child_command_size, - child_command_size - 1, L"%s %s", + child_command_size - 1, L"%ls %ls", executable, cmdline); else _snwprintf_s(child_command, child_command_size, - child_command_size - 1, L"%s %s %s", + child_command_size - 1, L"%ls %ls %ls", executable, suffix, cmdline); run_child(child_command); free(child_command); @@ -791,7 +824,7 @@ static void add_command(wchar_t * name, wchar_t * cmdline) { if (num_commands >= MAX_COMMANDS) { - debug(L"can't add %s = '%s': no room\n", name, cmdline); + debug(L"can't add %ls = '%ls': no room\n", name, cmdline); } else { COMMAND * cp = &commands[num_commands++]; @@ -813,14 +846,14 @@ read_config_file(wchar_t * config_path) read = GetPrivateProfileStringW(L"commands", NULL, NULL, keynames, MSGSIZE, config_path); if (read == MSGSIZE - 1) { - debug(L"read_commands: %s: not enough space for names\n", config_path); + debug(L"read_commands: %ls: not enough space for names\n", config_path); } key = keynames; while (*key) { read = GetPrivateProfileStringW(L"commands", key, NULL, value, MSGSIZE, config_path); if (read == MSGSIZE - 1) { - debug(L"read_commands: %s: not enough space for %s\n", + debug(L"read_commands: %ls: not enough space for %ls\n", config_path, key); } cmdp = skip_whitespace(value); @@ -1097,7 +1130,7 @@ maybe_handle_shebang(wchar_t ** argv, wchar_t * cmdline) if ((read >= 4) && (buffer[3] == '\n') && (buffer[2] == '\r')) { ip = find_by_magic((buffer[1] << 8 | buffer[0]) & 0xFFFF); if (ip != NULL) { - debug(L"script file is compiled against Python %s\n", + debug(L"script file is compiled against Python %ls\n", ip->version); invoke_child(ip->executable, NULL, cmdline); } @@ -1200,7 +1233,7 @@ of bytes: %d\n", header_len); is_virt = parse_shebang(shebang_line, nchars, &command, &suffix, &search); if (command != NULL) { - debug(L"parse_shebang: found command: %s\n", command); + debug(L"parse_shebang: found command: %ls\n", command); if (!is_virt) { invoke_child(command, suffix, cmdline); } @@ -1212,7 +1245,7 @@ of bytes: %d\n", header_len); } if (wcsncmp(command, L"python", 6)) error(RC_BAD_VIRTUAL_PATH, L"Unknown virtual \ -path '%s'", command); +path '%ls'", command); command += 6; /* skip past "python" */ if (search && ((*command == L'\0') || isspace(*command))) { /* Command is eligible for path search, and there @@ -1220,9 +1253,9 @@ path '%s'", command); */ debug(L"searching PATH for python executable\n"); cmd = find_on_path(L"python"); - debug(L"Python on path: %s\n", cmd ? cmd->value : L""); + debug(L"Python on path: %ls\n", cmd ? cmd->value : L""); if (cmd) { - debug(L"located python on PATH: %s\n", cmd->value); + debug(L"located python on PATH: %ls\n", cmd->value); invoke_child(cmd->value, suffix, cmdline); /* Exit here, as we have found the command */ return; @@ -1233,14 +1266,14 @@ path '%s'", command); } if (*command && !validate_version(command)) error(RC_BAD_VIRTUAL_PATH, L"Invalid version \ -specification: '%s'.\nIn the first line of the script, 'python' needs to be \ +specification: '%ls'.\nIn the first line of the script, 'python' needs to be \ followed by a valid version specifier.\nPlease check the documentation.", command); /* TODO could call validate_version(command) */ ip = locate_python(command); if (ip == NULL) { error(RC_NO_PYTHON, L"Requested Python version \ -(%s) is not installed", command); +(%ls) is not installed", command); } else { invoke_child(ip->executable, suffix, cmdline); @@ -1301,6 +1334,7 @@ process(int argc, wchar_t ** argv) { wchar_t * wp; wchar_t * command; + wchar_t * executable; wchar_t * p; int rc = 0; size_t plen; @@ -1347,17 +1381,17 @@ process(int argc, wchar_t ** argv) wcsncpy_s(p, MAX_PATH - plen, L"\\py.ini", _TRUNCATE); attrs = GetFileAttributesW(appdata_ini_path); if (attrs == INVALID_FILE_ATTRIBUTES) { - debug(L"File '%s' non-existent\n", appdata_ini_path); + debug(L"File '%ls' non-existent\n", appdata_ini_path); appdata_ini_path[0] = L'\0'; } else { - debug(L"Using local configuration file '%s'\n", appdata_ini_path); + debug(L"Using local configuration file '%ls'\n", appdata_ini_path); } } plen = GetModuleFileNameW(NULL, launcher_ini_path, MAX_PATH); size = GetFileVersionInfoSizeW(launcher_ini_path, &size); if (size == 0) { winerror(GetLastError(), message, MSGSIZE); - debug(L"GetFileVersionInfoSize failed: %s\n", message); + debug(L"GetFileVersionInfoSize failed: %ls\n", message); } else { version_data = malloc(size); @@ -1381,7 +1415,7 @@ process(int argc, wchar_t ** argv) } p = wcsrchr(launcher_ini_path, L'\\'); if (p == NULL) { - debug(L"GetModuleFileNameW returned value has no backslash: %s\n", + debug(L"GetModuleFileNameW returned value has no backslash: %ls\n", launcher_ini_path); launcher_ini_path[0] = L'\0'; } @@ -1390,15 +1424,15 @@ process(int argc, wchar_t ** argv) _TRUNCATE); attrs = GetFileAttributesW(launcher_ini_path); if (attrs == INVALID_FILE_ATTRIBUTES) { - debug(L"File '%s' non-existent\n", launcher_ini_path); + debug(L"File '%ls' non-existent\n", launcher_ini_path); launcher_ini_path[0] = L'\0'; } else { - debug(L"Using global configuration file '%s'\n", launcher_ini_path); + debug(L"Using global configuration file '%ls'\n", launcher_ini_path); } } command = skip_me(GetCommandLineW()); - debug(L"Called with command line: %s\n", command); + debug(L"Called with command line: %ls\n", command); #if defined(SCRIPT_WRAPPER) /* The launcher is being used in "script wrapper" mode. @@ -1422,7 +1456,7 @@ process(int argc, wchar_t ** argv) wcscpy_s(newcommand, newlen, wrapped_script_path); wcscat_s(newcommand, newlen, L" "); wcscat_s(newcommand, newlen, command); - debug(L"Running wrapped script with command line '%s'\n", newcommand); + debug(L"Running wrapped script with command line '%ls'\n", newcommand); read_commands(); av[0] = wrapped_script_path; av[1] = NULL; @@ -1443,8 +1477,9 @@ process(int argc, wchar_t ** argv) if (valid) { ip = locate_python(&p[1]); if (ip == NULL) - error(RC_NO_PYTHON, L"Requested Python version (%s) not \ + error(RC_NO_PYTHON, L"Requested Python version (%ls) not \ installed", &p[1]); + executable = ip->executable; command += wcslen(p); command = skip_whitespace(command); } @@ -1462,9 +1497,16 @@ installed", &p[1]); #endif if (!valid) { - ip = locate_python(L""); - if (ip == NULL) - error(RC_NO_PYTHON, L"Can't find a default Python."); + /* Look for an active virtualenv */ + executable = find_python_by_venv(); + + /* If we didn't find one, look for the default Python */ + if (executable == NULL) { + ip = locate_python(L""); + if (ip == NULL) + error(RC_NO_PYTHON, L"Can't find a default Python."); + executable = ip->executable; + } if ((argc == 2) && (!_wcsicmp(p, L"-h") || !_wcsicmp(p, L"--help"))) { #if defined(_M_X64) BOOL canDo64bit = TRUE; @@ -1476,9 +1518,9 @@ installed", &p[1]); get_version_info(version_text, MAX_PATH); fwprintf(stdout, L"\ -Python Launcher for Windows Version %s\n\n", version_text); +Python Launcher for Windows Version %ls\n\n", version_text); fwprintf(stdout, L"\ -usage: %s [ launcher-arguments ] [ python-arguments ] script [ script-arguments ]\n\n", argv[0]); +usage: %ls [ launcher-arguments ] [ python-arguments ] script [ script-arguments ]\n\n", argv[0]); fputws(L"\ Launcher arguments:\n\n\ -2 : Launch the latest Python 2.x version\n\ @@ -1492,7 +1534,7 @@ Launcher arguments:\n\n\ fflush(stdout); } } - invoke_child(ip->executable, NULL, command); + invoke_child(executable, NULL, command); return rc; } diff --git a/PC/msvcrtmodule.c b/PC/msvcrtmodule.c old mode 100755 new mode 100644 index 18dec6dbe864..d73ce792237a --- a/PC/msvcrtmodule.c +++ b/PC/msvcrtmodule.c @@ -32,421 +32,451 @@ #endif #endif -// Force the malloc heap to clean itself up, and free unused blocks -// back to the OS. (According to the docs, only works on NT.) +/*[python input] +class Py_intptr_t_converter(CConverter): + type = 'Py_intptr_t' + format_unit = '"_Py_PARSE_INTPTR"' + +class handle_return_converter(long_return_converter): + type = 'Py_intptr_t' + cast = '(void *)' + conversion_fn = 'PyLong_FromVoidPtr' + +class byte_char_return_converter(CReturnConverter): + type = 'int' + + def render(self, function, data): + data.declarations.append('char s[1];') + data.return_value = 's[0]' + data.return_conversion.append( + 'return_value = PyBytes_FromStringAndSize(s, 1);\n') + +class wchar_t_return_converter(CReturnConverter): + type = 'wchar_t' + + def render(self, function, data): + self.declare(data) + data.return_conversion.append( + 'return_value = PyUnicode_FromOrdinal(_return_value);\n') +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=6a54fc4e73d0b367]*/ + +/*[clinic input] +module msvcrt +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f31a87a783d036cd]*/ + +#include "clinic/msvcrtmodule.c.h" + +/*[clinic input] +msvcrt.heapmin + +Minimize the malloc() heap. + +Force the malloc() heap to clean itself up and return unused blocks +to the operating system. On failure, this raises OSError. +[clinic start generated code]*/ + static PyObject * -msvcrt_heapmin(PyObject *self, PyObject *args) +msvcrt_heapmin_impl(PyModuleDef *module) +/*[clinic end generated code: output=464f866feb57c436 input=82e1771d21bde2d8]*/ { - if (!PyArg_ParseTuple(args, ":heapmin")) - return NULL; - if (_heapmin() != 0) return PyErr_SetFromErrno(PyExc_IOError); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } +/*[clinic input] +msvcrt.locking + + fd: int + mode: int + nbytes: long + / -PyDoc_STRVAR(heapmin_doc, -"heapmin() -> None\n\ -\n\ -Force the malloc() heap to clean itself up and return unused blocks\n\ -to the operating system. On failure, this raises IOError."); +Lock part of a file based on file descriptor fd from the C runtime. + +Raises IOError on failure. The locked region of the file extends from +the current file position for nbytes bytes, and may continue beyond +the end of the file. mode must be one of the LK_* constants listed +below. Multiple regions in a file may be locked at the same time, but +may not overlap. Adjacent regions are not merged; they must be unlocked +individually. +[clinic start generated code]*/ -// Perform locking operations on a C runtime file descriptor. static PyObject * -msvcrt_locking(PyObject *self, PyObject *args) +msvcrt_locking_impl(PyModuleDef *module, int fd, int mode, long nbytes) +/*[clinic end generated code: output=dff41e5e76d544de input=d9f13f0f6a713ba7]*/ { - int fd; - int mode; - long nbytes; int err; - if (!PyArg_ParseTuple(args, "iil:locking", &fd, &mode, &nbytes)) - return NULL; - Py_BEGIN_ALLOW_THREADS err = _locking(fd, mode, nbytes); Py_END_ALLOW_THREADS if (err != 0) return PyErr_SetFromErrno(PyExc_IOError); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(locking_doc, -"locking(fd, mode, nbytes) -> None\n\ -\n\ -Lock part of a file based on file descriptor fd from the C runtime.\n\ -Raises IOError on failure. The locked region of the file extends from\n\ -the current file position for nbytes bytes, and may continue beyond\n\ -the end of the file. mode must be one of the LK_* constants listed\n\ -below. Multiple regions in a file may be locked at the same time, but\n\ -may not overlap. Adjacent regions are not merged; they must be unlocked\n\ -individually."); - -// Set the file translation mode for a C runtime file descriptor. -static PyObject * -msvcrt_setmode(PyObject *self, PyObject *args) -{ - int fd; - int flags; - if (!PyArg_ParseTuple(args,"ii:setmode", &fd, &flags)) - return NULL; +/*[clinic input] +msvcrt.setmode -> long + fd: int + mode as flags: int + / + +Set the line-end translation mode for the file descriptor fd. + +To set it to text mode, flags should be os.O_TEXT; for binary, it +should be os.O_BINARY. + +Return value is the previous mode. +[clinic start generated code]*/ + +static long +msvcrt_setmode_impl(PyModuleDef *module, int fd, int flags) +/*[clinic end generated code: output=8c84e5b37c586d0d input=76e7c01f6b137f75]*/ +{ flags = _setmode(fd, flags); if (flags == -1) - return PyErr_SetFromErrno(PyExc_IOError); + PyErr_SetFromErrno(PyExc_IOError); - return PyLong_FromLong(flags); + return flags; } -PyDoc_STRVAR(setmode_doc, -"setmode(fd, mode) -> Previous mode\n\ -\n\ -Set the line-end translation mode for the file descriptor fd. To set\n\ -it to text mode, flags should be os.O_TEXT; for binary, it should be\n\ -os.O_BINARY."); +/*[clinic input] +msvcrt.open_osfhandle -> long -// Convert an OS file handle to a C runtime file descriptor. -static PyObject * -msvcrt_open_osfhandle(PyObject *self, PyObject *args) + handle: Py_intptr_t + flags: int + / + +Create a C runtime file descriptor from the file handle handle. + +The flags parameter should be a bitwise OR of os.O_APPEND, os.O_RDONLY, +and os.O_TEXT. The returned file descriptor may be used as a parameter +to os.fdopen() to create a file object. +[clinic start generated code]*/ + +static long +msvcrt_open_osfhandle_impl(PyModuleDef *module, Py_intptr_t handle, + int flags) +/*[clinic end generated code: output=86bce32582c49c06 input=4d8516ed32db8f65]*/ { - Py_intptr_t handle; - int flags; int fd; - if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:open_osfhandle", - &handle, &flags)) - return NULL; - fd = _open_osfhandle(handle, flags); if (fd == -1) - return PyErr_SetFromErrno(PyExc_IOError); + PyErr_SetFromErrno(PyExc_IOError); - return PyLong_FromLong(fd); + return fd; } -PyDoc_STRVAR(open_osfhandle_doc, -"open_osfhandle(handle, flags) -> file descriptor\n\ -\n\ -Create a C runtime file descriptor from the file handle handle. The\n\ -flags parameter should be a bitwise OR of os.O_APPEND, os.O_RDONLY,\n\ -and os.O_TEXT. The returned file descriptor may be used as a parameter\n\ -to os.fdopen() to create a file object."); +/*[clinic input] +msvcrt.get_osfhandle -> handle -// Convert a C runtime file descriptor to an OS file handle. -static PyObject * -msvcrt_get_osfhandle(PyObject *self, PyObject *args) -{ - int fd; - Py_intptr_t handle; + fd: int + / - if (!PyArg_ParseTuple(args,"i:get_osfhandle", &fd)) - return NULL; +Return the file handle for the file descriptor fd. - if (!_PyVerify_fd(fd)) - return PyErr_SetFromErrno(PyExc_IOError); +Raises IOError if fd is not recognized. +[clinic start generated code]*/ - handle = _get_osfhandle(fd); - if (handle == -1) - return PyErr_SetFromErrno(PyExc_IOError); +static Py_intptr_t +msvcrt_get_osfhandle_impl(PyModuleDef *module, int fd) +/*[clinic end generated code: output=376bff52586b55a6 input=c7d18d02c8017ec1]*/ +{ + Py_intptr_t handle = -1; - /* technically 'handle' is not a pointer, but a integer as - large as a pointer, Python's *VoidPtr interface is the - most appropriate here */ - return PyLong_FromVoidPtr((void*)handle); -} + if (!_PyVerify_fd(fd)) { + PyErr_SetFromErrno(PyExc_IOError); + } + else { + _Py_BEGIN_SUPPRESS_IPH + handle = _get_osfhandle(fd); + _Py_END_SUPPRESS_IPH + if (handle == -1) + PyErr_SetFromErrno(PyExc_IOError); + } -PyDoc_STRVAR(get_osfhandle_doc, -"get_osfhandle(fd) -> file handle\n\ -\n\ -Return the file handle for the file descriptor fd. Raises IOError\n\ -if fd is not recognized."); + return handle; +} /* Console I/O */ +/*[clinic input] +msvcrt.kbhit -> long -static PyObject * -msvcrt_kbhit(PyObject *self, PyObject *args) +Return true if a keypress is waiting to be read. +[clinic start generated code]*/ + +static long +msvcrt_kbhit_impl(PyModuleDef *module) +/*[clinic end generated code: output=2b7293fcbe5cb24e input=e70d678a5c2f6acc]*/ { - int ok; + return _kbhit(); +} - if (!PyArg_ParseTuple(args, ":kbhit")) - return NULL; +/*[clinic input] +msvcrt.getch -> byte_char - ok = _kbhit(); - return PyLong_FromLong(ok); -} +Read a keypress and return the resulting character as a byte string. -PyDoc_STRVAR(kbhit_doc, -"kbhit() -> bool\n\ -\n\ -Return true if a keypress is waiting to be read."); +Nothing is echoed to the console. This call will block if a keypress is +not already available, but will not wait for Enter to be pressed. If the +pressed key was a special function key, this will return '\000' or +'\xe0'; the next call will return the keycode. The Control-C keypress +cannot be read with this function. +[clinic start generated code]*/ -static PyObject * -msvcrt_getch(PyObject *self, PyObject *args) +static int +msvcrt_getch_impl(PyModuleDef *module) +/*[clinic end generated code: output=199e3d89f49c166a input=37a40cf0ed0d1153]*/ { int ch; - char s[1]; - - if (!PyArg_ParseTuple(args, ":getch")) - return NULL; Py_BEGIN_ALLOW_THREADS ch = _getch(); Py_END_ALLOW_THREADS - s[0] = ch; - return PyBytes_FromStringAndSize(s, 1); + return ch; } -PyDoc_STRVAR(getch_doc, -"getch() -> key character\n\ -\n\ -Read a keypress and return the resulting character as a byte string.\n\ -Nothing is echoed to the console. This call will block if a keypress is\n\ -not already available, but will not wait for Enter to be pressed. If the\n\ -pressed key was a special function key, this will return '\\000' or\n\ -'\\xe0'; the next call will return the keycode. The Control-C keypress\n\ -cannot be read with this function."); - -#ifdef _WCONIO_DEFINED -static PyObject * -msvcrt_getwch(PyObject *self, PyObject *args) +/*[clinic input] +msvcrt.getwch -> wchar_t + +Wide char variant of getch(), returning a Unicode value. +[clinic start generated code]*/ + +static wchar_t +msvcrt_getwch_impl(PyModuleDef *module) +/*[clinic end generated code: output=9d3762861328b1fe input=27b3dec8ad823d7c]*/ { wchar_t ch; - if (!PyArg_ParseTuple(args, ":getwch")) - return NULL; - Py_BEGIN_ALLOW_THREADS ch = _getwch(); Py_END_ALLOW_THREADS - return PyUnicode_FromOrdinal(ch); + return ch; } -PyDoc_STRVAR(getwch_doc, -"getwch() -> Unicode key character\n\ -\n\ -Wide char variant of getch(), returning a Unicode value."); -#endif +/*[clinic input] +msvcrt.getche -> byte_char -static PyObject * -msvcrt_getche(PyObject *self, PyObject *args) +Similar to getch(), but the keypress will be echoed if possible. +[clinic start generated code]*/ + +static int +msvcrt_getche_impl(PyModuleDef *module) +/*[clinic end generated code: output=8aa369be6550068e input=43311ade9ed4a9c0]*/ { int ch; - char s[1]; - - if (!PyArg_ParseTuple(args, ":getche")) - return NULL; Py_BEGIN_ALLOW_THREADS ch = _getche(); Py_END_ALLOW_THREADS - s[0] = ch; - return PyBytes_FromStringAndSize(s, 1); + return ch; } -PyDoc_STRVAR(getche_doc, -"getche() -> key character\n\ -\n\ -Similar to getch(), but the keypress will be echoed if it represents\n\ -a printable character."); +/*[clinic input] +msvcrt.getwche -> wchar_t -#ifdef _WCONIO_DEFINED -static PyObject * -msvcrt_getwche(PyObject *self, PyObject *args) +Wide char variant of getche(), returning a Unicode value. +[clinic start generated code]*/ + +static wchar_t +msvcrt_getwche_impl(PyModuleDef *module) +/*[clinic end generated code: output=3693cf78e3ea0cf6 input=49337d59d1a591f8]*/ { wchar_t ch; - if (!PyArg_ParseTuple(args, ":getwche")) - return NULL; - Py_BEGIN_ALLOW_THREADS ch = _getwche(); Py_END_ALLOW_THREADS - return PyUnicode_FromOrdinal(ch); + return ch; } -PyDoc_STRVAR(getwche_doc, -"getwche() -> Unicode key character\n\ -\n\ -Wide char variant of getche(), returning a Unicode value."); -#endif +/*[clinic input] +msvcrt.putch + + char: char + / + +Print the byte string char to the console without buffering. +[clinic start generated code]*/ static PyObject * -msvcrt_putch(PyObject *self, PyObject *args) +msvcrt_putch_impl(PyModuleDef *module, char char_value) +/*[clinic end generated code: output=c05548b11554f36f input=ec078dd10cb054d6]*/ { - char ch; + _putch(char_value); + Py_RETURN_NONE; +} - if (!PyArg_ParseTuple(args, "c:putch", &ch)) - return NULL; +/*[clinic input] +msvcrt.putwch - _putch(ch); - Py_INCREF(Py_None); - return Py_None; -} + unicode_char: int(accept={str}) + / -PyDoc_STRVAR(putch_doc, -"putch(char) -> None\n\ -\n\ -Print the byte string char to the console without buffering."); +Wide char variant of putch(), accepting a Unicode value. +[clinic start generated code]*/ -#ifdef _WCONIO_DEFINED static PyObject * -msvcrt_putwch(PyObject *self, PyObject *args) +msvcrt_putwch_impl(PyModuleDef *module, int unicode_char) +/*[clinic end generated code: output=c216a73694ca73dd input=996ccd0bbcbac4c3]*/ { - int ch; - - if (!PyArg_ParseTuple(args, "C:putwch", &ch)) - return NULL; - - _putwch(ch); + _putwch(unicode_char); Py_RETURN_NONE; } -PyDoc_STRVAR(putwch_doc, -"putwch(unicode_char) -> None\n\ -\n\ -Wide char variant of putch(), accepting a Unicode value."); -#endif +/*[clinic input] +msvcrt.ungetch -static PyObject * -msvcrt_ungetch(PyObject *self, PyObject *args) -{ - char ch; + char: char + / - if (!PyArg_ParseTuple(args, "c:ungetch", &ch)) - return NULL; +Opposite of getch. + +Cause the byte string char to be "pushed back" into the +console buffer; it will be the next character read by +getch() or getche(). +[clinic start generated code]*/ - if (_ungetch(ch) == EOF) +static PyObject * +msvcrt_ungetch_impl(PyModuleDef *module, char char_value) +/*[clinic end generated code: output=19a4cd3249709ec9 input=22f07ee9001bbf0f]*/ +{ + if (_ungetch(char_value) == EOF) return PyErr_SetFromErrno(PyExc_IOError); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(ungetch_doc, -"ungetch(char) -> None\n\ -\n\ -Cause the byte string char to be \"pushed back\" into the\n\ -console buffer; it will be the next character read by\n\ -getch() or getche()."); +/*[clinic input] +msvcrt.ungetwch -#ifdef _WCONIO_DEFINED -static PyObject * -msvcrt_ungetwch(PyObject *self, PyObject *args) -{ - int ch; + unicode_char: int(accept={str}) + / - if (!PyArg_ParseTuple(args, "C:ungetwch", &ch)) - return NULL; +Wide char variant of ungetch(), accepting a Unicode value. +[clinic start generated code]*/ - if (_ungetwch(ch) == WEOF) +static PyObject * +msvcrt_ungetwch_impl(PyModuleDef *module, int unicode_char) +/*[clinic end generated code: output=1ee7674710322bd1 input=83ec0492be04d564]*/ +{ + if (_ungetwch(unicode_char) == WEOF) return PyErr_SetFromErrno(PyExc_IOError); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -PyDoc_STRVAR(ungetwch_doc, -"ungetwch(unicode_char) -> None\n\ -\n\ -Wide char variant of ungetch(), accepting a Unicode value."); -#endif +#ifdef _DEBUG +/*[clinic input] +msvcrt.CrtSetReportFile -> long -static void -insertint(PyObject *d, char *name, int value) + type: int + file: int + / + +Wrapper around _CrtSetReportFile. + +Only available on Debug builds. +[clinic start generated code]*/ + +static long +msvcrt_CrtSetReportFile_impl(PyModuleDef *module, int type, int file) +/*[clinic end generated code: output=8c3644fb2edfa808 input=bb8f721a604fcc45]*/ { - PyObject *v = PyLong_FromLong((long) value); - if (v == NULL) { - /* Don't bother reporting this error */ - PyErr_Clear(); - } - else { - PyDict_SetItemString(d, name, v); - Py_DECREF(v); - } + return (long)_CrtSetReportFile(type, (_HFILE)file); } -#ifdef _DEBUG +/*[clinic input] +msvcrt.CrtSetReportMode -> long -static PyObject* -msvcrt_setreportfile(PyObject *self, PyObject *args) -{ - int type, file; - _HFILE res; + type: int + mode: int + / - if (!PyArg_ParseTuple(args, "ii", &type, &file)) - return NULL; - res = _CrtSetReportFile(type, (_HFILE)file); - return PyLong_FromLong((long)res); - Py_INCREF(Py_None); - return Py_None; -} +Wrapper around _CrtSetReportMode. + +Only available on Debug builds. +[clinic start generated code]*/ -static PyObject* -msvcrt_setreportmode(PyObject *self, PyObject *args) +static long +msvcrt_CrtSetReportMode_impl(PyModuleDef *module, int type, int mode) +/*[clinic end generated code: output=b407fbf8716a52b9 input=9319d29b4319426b]*/ { - int type, mode; int res; - if (!PyArg_ParseTuple(args, "ii", &type, &mode)) - return NULL; res = _CrtSetReportMode(type, mode); if (res == -1) - return PyErr_SetFromErrno(PyExc_IOError); - return PyLong_FromLong(res); + PyErr_SetFromErrno(PyExc_IOError); + return res; } -static PyObject* -msvcrt_seterrormode(PyObject *self, PyObject *args) -{ - int mode, res; +/*[clinic input] +msvcrt.set_error_mode -> long - if (!PyArg_ParseTuple(args, "i", &mode)) - return NULL; - res = _set_error_mode(mode); - return PyLong_FromLong(res); + mode: int + / + +Wrapper around _set_error_mode. + +Only available on Debug builds. +[clinic start generated code]*/ + +static long +msvcrt_set_error_mode_impl(PyModuleDef *module, int mode) +/*[clinic end generated code: output=62148adffa90867d input=046fca59c0f20872]*/ +{ + return _set_error_mode(mode); } +#endif /* _DEBUG */ -#endif +/*[clinic input] +msvcrt.SetErrorMode + + mode: unsigned_int(bitwise=True) + / -static PyObject* -seterrormode(PyObject *self, PyObject *args) +Wrapper around SetErrorMode. +[clinic start generated code]*/ + +static PyObject * +msvcrt_SetErrorMode_impl(PyModuleDef *module, unsigned int mode) +/*[clinic end generated code: output=544c60b085be79c6 input=d8b167258d32d907]*/ { - unsigned int mode, res; + unsigned int res; - if (!PyArg_ParseTuple(args, "I", &mode)) - return NULL; res = SetErrorMode(mode); return PyLong_FromUnsignedLong(res); } +/*[clinic input] +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=da39a3ee5e6b4b0d]*/ /* List of functions exported by this module */ static struct PyMethodDef msvcrt_functions[] = { - {"heapmin", msvcrt_heapmin, METH_VARARGS, heapmin_doc}, - {"locking", msvcrt_locking, METH_VARARGS, locking_doc}, - {"setmode", msvcrt_setmode, METH_VARARGS, setmode_doc}, - {"open_osfhandle", msvcrt_open_osfhandle, METH_VARARGS, open_osfhandle_doc}, - {"get_osfhandle", msvcrt_get_osfhandle, METH_VARARGS, get_osfhandle_doc}, - {"kbhit", msvcrt_kbhit, METH_VARARGS, kbhit_doc}, - {"getch", msvcrt_getch, METH_VARARGS, getch_doc}, - {"getche", msvcrt_getche, METH_VARARGS, getche_doc}, - {"putch", msvcrt_putch, METH_VARARGS, putch_doc}, - {"ungetch", msvcrt_ungetch, METH_VARARGS, ungetch_doc}, - {"SetErrorMode", seterrormode, METH_VARARGS}, -#ifdef _DEBUG - {"CrtSetReportFile", msvcrt_setreportfile, METH_VARARGS}, - {"CrtSetReportMode", msvcrt_setreportmode, METH_VARARGS}, - {"set_error_mode", msvcrt_seterrormode, METH_VARARGS}, -#endif -#ifdef _WCONIO_DEFINED - {"getwch", msvcrt_getwch, METH_VARARGS, getwch_doc}, - {"getwche", msvcrt_getwche, METH_VARARGS, getwche_doc}, - {"putwch", msvcrt_putwch, METH_VARARGS, putwch_doc}, - {"ungetwch", msvcrt_ungetwch, METH_VARARGS, ungetwch_doc}, -#endif + MSVCRT_HEAPMIN_METHODDEF + MSVCRT_LOCKING_METHODDEF + MSVCRT_SETMODE_METHODDEF + MSVCRT_OPEN_OSFHANDLE_METHODDEF + MSVCRT_GET_OSFHANDLE_METHODDEF + MSVCRT_KBHIT_METHODDEF + MSVCRT_GETCH_METHODDEF + MSVCRT_GETCHE_METHODDEF + MSVCRT_PUTCH_METHODDEF + MSVCRT_UNGETCH_METHODDEF + MSVCRT_SETERRORMODE_METHODDEF + MSVCRT_CRTSETREPORTFILE_METHODDEF + MSVCRT_CRTSETREPORTMODE_METHODDEF + MSVCRT_SET_ERROR_MODE_METHODDEF + MSVCRT_GETWCH_METHODDEF + MSVCRT_GETWCHE_METHODDEF + MSVCRT_PUTWCH_METHODDEF + MSVCRT_UNGETWCH_METHODDEF {NULL, NULL} }; @@ -463,6 +493,20 @@ static struct PyModuleDef msvcrtmodule = { NULL }; +static void +insertint(PyObject *d, char *name, int value) +{ + PyObject *v = PyLong_FromLong((long) value); + if (v == NULL) { + /* Don't bother reporting this error */ + PyErr_Clear(); + } + else { + PyDict_SetItemString(d, name, v); + Py_DECREF(v); + } +} + PyMODINIT_FUNC PyInit_msvcrt(void) { @@ -497,7 +541,6 @@ PyInit_msvcrt(void) #endif /* constants for the crt versions */ - (void)st; #ifdef _VC_ASSEMBLY_PUBLICKEYTOKEN st = PyModule_AddStringConstant(m, "VC_ASSEMBLY_PUBLICKEYTOKEN", _VC_ASSEMBLY_PUBLICKEYTOKEN); @@ -523,6 +566,8 @@ PyInit_msvcrt(void) st = PyModule_AddObject(m, "CRT_ASSEMBLY_VERSION", version); if (st < 0) return NULL; #endif + /* make compiler warning quiet if st is unused */ + (void)st; return m; } diff --git a/PC/pyconfig.h b/PC/pyconfig.h index 299527db7d40..886114806176 100644 --- a/PC/pyconfig.h +++ b/PC/pyconfig.h @@ -145,18 +145,24 @@ WIN32 is still required for the locale module. #if defined(_M_IA64) #define COMPILER _Py_PASTE_VERSION("64 bit (Itanium)") #define MS_WINI64 +#define PYD_PLATFORM_TAG "win_ia64" #elif defined(_M_X64) || defined(_M_AMD64) +#if defined(__INTEL_COMPILER) +#define COMPILER ("[ICC v." _Py_STRINGIZE(__INTEL_COMPILER) " 64 bit (amd64) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") +#else #define COMPILER _Py_PASTE_VERSION("64 bit (AMD64)") +#endif /* __INTEL_COMPILER */ #define MS_WINX64 +#define PYD_PLATFORM_TAG "win_amd64" #else #define COMPILER _Py_PASTE_VERSION("64 bit (Unknown)") #endif #endif /* MS_WIN64 */ /* set the version macros for the windows headers */ -/* Python 3.4+ requires Windows XP or greater */ -#define Py_WINVER 0x0501 /* _WIN32_WINNT_WINXP */ -#define Py_NTDDI NTDDI_WINXP +/* Python 3.5+ requires Windows Vista or greater */ +#define Py_WINVER 0x0600 /* _WIN32_WINNT_VISTA */ +#define Py_NTDDI NTDDI_VISTA /* We only set these values when building Python - we don't want to force these values on extensions, as that will affect the prototypes and @@ -192,9 +198,15 @@ typedef _W64 int ssize_t; #if defined(MS_WIN32) && !defined(MS_WIN64) #if defined(_M_IX86) +#if defined(__INTEL_COMPILER) +#define COMPILER ("[ICC v." _Py_STRINGIZE(__INTEL_COMPILER) " 32 bit (Intel) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") +#else #define COMPILER _Py_PASTE_VERSION("32 bit (Intel)") +#endif /* __INTEL_COMPILER */ +#define PYD_PLATFORM_TAG "win32" #elif defined(_M_ARM) #define COMPILER _Py_PASTE_VERSION("32 bit (ARM)") +#define PYD_PLATFORM_TAG "win_arm" #else #define COMPILER _Py_PASTE_VERSION("32 bit (Unknown)") #endif @@ -207,7 +219,18 @@ typedef int pid_t; #define Py_IS_INFINITY(X) (!_finite(X) && !_isnan(X)) #define Py_IS_FINITE(X) _finite(X) #define copysign _copysign + +/* VS 2010 and above already defines hypot as _hypot */ +#if _MSC_VER < 1600 #define hypot _hypot +#endif + +/* VS 2015 defines these names with a leading underscore */ +#if _MSC_VER >= 1900 +#define timezone _timezone +#define daylight _daylight +#define tzname _tzname +#endif /* Side by Side assemblies supported in VS 2005 and VS 2008 but not 2010*/ #if _MSC_VER >= 1400 && _MSC_VER < 1600 @@ -222,35 +245,6 @@ typedef int pid_t; #endif /* _MSC_VER */ -/* ------------------------------------------------------------------------*/ -/* The Borland compiler defines __BORLANDC__ */ -/* XXX These defines are likely incomplete, but should be easy to fix. */ -#ifdef __BORLANDC__ -#define COMPILER "[Borland]" - -#ifdef _WIN32 -/* tested with BCC 5.5 (__BORLANDC__ >= 0x0550) - */ - -typedef int pid_t; -/* BCC55 seems to understand __declspec(dllimport), it is used in its - own header files (winnt.h, ...) - so we can do nothing and get the default*/ - -#undef HAVE_SYS_UTIME_H -#define HAVE_UTIME_H -#define HAVE_DIRENT_H - -/* rename a few functions for the Borland compiler */ -#include -#define _chsize chsize -#define _setmode setmode - -#else /* !_WIN32 */ -#error "Only Win32 and later are supported" -#endif /* !_WIN32 */ - -#endif /* BORLANDC */ - /* ------------------------------------------------------------------------*/ /* egcs/gnu-win32 defines __GNUC__ and _WIN32 */ #if defined(__GNUC__) && defined(_WIN32) @@ -318,11 +312,11 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ their Makefile (other compilers are generally taken care of by distutils.) */ # if defined(_DEBUG) -# pragma comment(lib,"python34_d.lib") +# pragma comment(lib,"python36_d.lib") # elif defined(Py_LIMITED_API) # pragma comment(lib,"python3.lib") # else -# pragma comment(lib,"python34.lib") +# pragma comment(lib,"python36.lib") # endif /* _DEBUG */ # endif /* _MSC_VER */ # endif /* Py_BUILD_CORE */ @@ -386,7 +380,7 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ #else /* VC6, VS 2002 and eVC4 don't support the C99 LL suffix for 64-bit integer literals */ #define Py_LL(x) x##I64 -#endif /* _MSC_VER > 1200 */ +#endif /* _MSC_VER > 1300 */ #endif /* _MSC_VER */ #endif @@ -432,6 +426,11 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ /* Define to 1 if you have the `copysign' function. */ #define HAVE_COPYSIGN 1 +/* Define to 1 if you have the `round' function. */ +#if _MSC_VER >= 1800 +#define HAVE_ROUND 1 +#endif + /* Define to 1 if you have the `isinf' macro. */ #define HAVE_DECL_ISINF 1 diff --git a/PC/pylauncher.rc b/PC/pylauncher.rc index df5824a6635e..a8db0a842f84 100644 --- a/PC/pylauncher.rc +++ b/PC/pylauncher.rc @@ -1,51 +1,50 @@ #include -#define MS_WINDOWS -#include "..\Include\modsupport.h" -#include "..\Include\patchlevel.h" -#ifdef _DEBUG -# include "pythonnt_rc_d.h" -#else -# include "pythonnt_rc.h" -#endif +#include "python_ver_rc.h" + +// Include the manifest file that indicates we support all +// current versions of Windows. +#include +1 RT_MANIFEST "python.manifest" -#define PYTHON_VERSION PY_VERSION "\0" -#define PYVERSION64 PY_MAJOR_VERSION, PY_MINOR_VERSION, FIELD3, PYTHON_API_VERSION +1 ICON DISCARDABLE "launcher.ico" +2 ICON DISCARDABLE "py.ico" +3 ICON DISCARDABLE "pyc.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// VS_VERSION_INFO VERSIONINFO FILEVERSION PYVERSION64 PRODUCTVERSION PYVERSION64 - FILEFLAGSMASK 0x17L + FILEFLAGSMASK 0x3fL #ifdef _DEBUG - FILEFLAGS 0x1L + FILEFLAGS VS_FF_DEBUG #else FILEFLAGS 0x0L #endif - FILEOS 0x4L - FILETYPE 0x1L + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN - BLOCK "080904b0" + BLOCK "000004b0" BEGIN - VALUE "Comments", "Python Launcher for Windows" - VALUE "CompanyName", "Python Software Foundation" - VALUE "FileDescription", "Python Launcher for Windows (Console)" + VALUE "CompanyName", PYTHON_COMPANY "\0" + VALUE "FileDescription", "Python\0" VALUE "FileVersion", PYTHON_VERSION - VALUE "InternalName", "py" - VALUE "LegalCopyright", "Copyright (C) 2011-2012 Python Software Foundation" - VALUE "OriginalFilename", "py" - VALUE "ProductName", "Python Launcher for Windows" + VALUE "InternalName", "Python Launcher\0" + VALUE "LegalCopyright", PYTHON_COPYRIGHT "\0" + VALUE "OriginalFilename", "py" PYTHON_DEBUG_EXT ".exe\0" + VALUE "ProductName", "Python\0" VALUE "ProductVersion", PYTHON_VERSION END END BLOCK "VarFileInfo" BEGIN - VALUE "Translation", 0x809, 1200 + VALUE "Translation", 0x0, 1200 END -END - -IDI_ICON1 ICON "launcher.ico" - - +END \ No newline at end of file diff --git a/PC/python.manifest b/PC/python.manifest new file mode 100644 index 000000000000..9b7b2f8e5156 --- /dev/null +++ b/PC/python.manifest @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PC/python3.def b/PC/python3.def index 0cf0d944d9fc..e146e8fae4d8 100644 --- a/PC/python3.def +++ b/PC/python3.def @@ -1,700 +1,713 @@ -; When changing this file, run python34gen.py +; This file specifies the import forwarding for python3.dll +; It is used when building python3dll.vcxproj LIBRARY "python3" EXPORTS - PyArg_Parse=python34.PyArg_Parse - PyArg_ParseTuple=python34.PyArg_ParseTuple - PyArg_ParseTupleAndKeywords=python34.PyArg_ParseTupleAndKeywords - PyArg_UnpackTuple=python34.PyArg_UnpackTuple - PyArg_VaParse=python34.PyArg_VaParse - PyArg_VaParseTupleAndKeywords=python34.PyArg_VaParseTupleAndKeywords - PyArg_ValidateKeywordArguments=python34.PyArg_ValidateKeywordArguments - PyBaseObject_Type=python34.PyBaseObject_Type DATA - PyBool_FromLong=python34.PyBool_FromLong - PyBool_Type=python34.PyBool_Type DATA - PyByteArrayIter_Type=python34.PyByteArrayIter_Type DATA - PyByteArray_AsString=python34.PyByteArray_AsString - PyByteArray_Concat=python34.PyByteArray_Concat - PyByteArray_FromObject=python34.PyByteArray_FromObject - PyByteArray_FromStringAndSize=python34.PyByteArray_FromStringAndSize - PyByteArray_Resize=python34.PyByteArray_Resize - PyByteArray_Size=python34.PyByteArray_Size - PyByteArray_Type=python34.PyByteArray_Type DATA - PyBytesIter_Type=python34.PyBytesIter_Type DATA - PyBytes_AsString=python34.PyBytes_AsString - PyBytes_AsStringAndSize=python34.PyBytes_AsStringAndSize - PyBytes_Concat=python34.PyBytes_Concat - PyBytes_ConcatAndDel=python34.PyBytes_ConcatAndDel - PyBytes_DecodeEscape=python34.PyBytes_DecodeEscape - PyBytes_FromFormat=python34.PyBytes_FromFormat - PyBytes_FromFormatV=python34.PyBytes_FromFormatV - PyBytes_FromObject=python34.PyBytes_FromObject - PyBytes_FromString=python34.PyBytes_FromString - PyBytes_FromStringAndSize=python34.PyBytes_FromStringAndSize - PyBytes_Repr=python34.PyBytes_Repr - PyBytes_Size=python34.PyBytes_Size - PyBytes_Type=python34.PyBytes_Type DATA - PyCFunction_Call=python34.PyCFunction_Call - PyCFunction_ClearFreeList=python34.PyCFunction_ClearFreeList - PyCFunction_GetFlags=python34.PyCFunction_GetFlags - PyCFunction_GetFunction=python34.PyCFunction_GetFunction - PyCFunction_GetSelf=python34.PyCFunction_GetSelf - PyCFunction_New=python34.PyCFunction_New - PyCFunction_NewEx=python34.PyCFunction_NewEx - PyCFunction_Type=python34.PyCFunction_Type DATA - PyCallIter_New=python34.PyCallIter_New - PyCallIter_Type=python34.PyCallIter_Type DATA - PyCallable_Check=python34.PyCallable_Check - PyCapsule_GetContext=python34.PyCapsule_GetContext - PyCapsule_GetDestructor=python34.PyCapsule_GetDestructor - PyCapsule_GetName=python34.PyCapsule_GetName - PyCapsule_GetPointer=python34.PyCapsule_GetPointer - PyCapsule_Import=python34.PyCapsule_Import - PyCapsule_IsValid=python34.PyCapsule_IsValid - PyCapsule_New=python34.PyCapsule_New - PyCapsule_SetContext=python34.PyCapsule_SetContext - PyCapsule_SetDestructor=python34.PyCapsule_SetDestructor - PyCapsule_SetName=python34.PyCapsule_SetName - PyCapsule_SetPointer=python34.PyCapsule_SetPointer - PyCapsule_Type=python34.PyCapsule_Type DATA - PyClassMethodDescr_Type=python34.PyClassMethodDescr_Type DATA - PyCodec_BackslashReplaceErrors=python34.PyCodec_BackslashReplaceErrors - PyCodec_Decode=python34.PyCodec_Decode - PyCodec_Decoder=python34.PyCodec_Decoder - PyCodec_Encode=python34.PyCodec_Encode - PyCodec_Encoder=python34.PyCodec_Encoder - PyCodec_IgnoreErrors=python34.PyCodec_IgnoreErrors - PyCodec_IncrementalDecoder=python34.PyCodec_IncrementalDecoder - PyCodec_IncrementalEncoder=python34.PyCodec_IncrementalEncoder - PyCodec_KnownEncoding=python34.PyCodec_KnownEncoding - PyCodec_LookupError=python34.PyCodec_LookupError - PyCodec_Register=python34.PyCodec_Register - PyCodec_RegisterError=python34.PyCodec_RegisterError - PyCodec_ReplaceErrors=python34.PyCodec_ReplaceErrors - PyCodec_StreamReader=python34.PyCodec_StreamReader - PyCodec_StreamWriter=python34.PyCodec_StreamWriter - PyCodec_StrictErrors=python34.PyCodec_StrictErrors - PyCodec_XMLCharRefReplaceErrors=python34.PyCodec_XMLCharRefReplaceErrors - PyComplex_FromDoubles=python34.PyComplex_FromDoubles - PyComplex_ImagAsDouble=python34.PyComplex_ImagAsDouble - PyComplex_RealAsDouble=python34.PyComplex_RealAsDouble - PyComplex_Type=python34.PyComplex_Type DATA - PyDescr_NewClassMethod=python34.PyDescr_NewClassMethod - PyDescr_NewGetSet=python34.PyDescr_NewGetSet - PyDescr_NewMember=python34.PyDescr_NewMember - PyDescr_NewMethod=python34.PyDescr_NewMethod - PyDictItems_Type=python34.PyDictItems_Type DATA - PyDictIterItem_Type=python34.PyDictIterItem_Type DATA - PyDictIterKey_Type=python34.PyDictIterKey_Type DATA - PyDictIterValue_Type=python34.PyDictIterValue_Type DATA - PyDictKeys_Type=python34.PyDictKeys_Type DATA - PyDictProxy_New=python34.PyDictProxy_New - PyDictProxy_Type=python34.PyDictProxy_Type DATA - PyDictValues_Type=python34.PyDictValues_Type DATA - PyDict_Clear=python34.PyDict_Clear - PyDict_Contains=python34.PyDict_Contains - PyDict_Copy=python34.PyDict_Copy - PyDict_DelItem=python34.PyDict_DelItem - PyDict_DelItemString=python34.PyDict_DelItemString - PyDict_GetItem=python34.PyDict_GetItem - PyDict_GetItemString=python34.PyDict_GetItemString - PyDict_GetItemWithError=python34.PyDict_GetItemWithError - PyDict_Items=python34.PyDict_Items - PyDict_Keys=python34.PyDict_Keys - PyDict_Merge=python34.PyDict_Merge - PyDict_MergeFromSeq2=python34.PyDict_MergeFromSeq2 - PyDict_New=python34.PyDict_New - PyDict_Next=python34.PyDict_Next - PyDict_SetItem=python34.PyDict_SetItem - PyDict_SetItemString=python34.PyDict_SetItemString - PyDict_Size=python34.PyDict_Size - PyDict_Type=python34.PyDict_Type DATA - PyDict_Update=python34.PyDict_Update - PyDict_Values=python34.PyDict_Values - PyEllipsis_Type=python34.PyEllipsis_Type DATA - PyEnum_Type=python34.PyEnum_Type DATA - PyErr_BadArgument=python34.PyErr_BadArgument - PyErr_BadInternalCall=python34.PyErr_BadInternalCall - PyErr_CheckSignals=python34.PyErr_CheckSignals - PyErr_Clear=python34.PyErr_Clear - PyErr_Display=python34.PyErr_Display - PyErr_ExceptionMatches=python34.PyErr_ExceptionMatches - PyErr_Fetch=python34.PyErr_Fetch - PyErr_Format=python34.PyErr_Format - PyErr_GivenExceptionMatches=python34.PyErr_GivenExceptionMatches - PyErr_NewException=python34.PyErr_NewException - PyErr_NewExceptionWithDoc=python34.PyErr_NewExceptionWithDoc - PyErr_NoMemory=python34.PyErr_NoMemory - PyErr_NormalizeException=python34.PyErr_NormalizeException - PyErr_Occurred=python34.PyErr_Occurred - PyErr_Print=python34.PyErr_Print - PyErr_PrintEx=python34.PyErr_PrintEx - PyErr_ProgramText=python34.PyErr_ProgramText - PyErr_Restore=python34.PyErr_Restore - PyErr_SetFromErrno=python34.PyErr_SetFromErrno - PyErr_SetFromErrnoWithFilename=python34.PyErr_SetFromErrnoWithFilename - PyErr_SetFromErrnoWithFilenameObject=python34.PyErr_SetFromErrnoWithFilenameObject - PyErr_SetInterrupt=python34.PyErr_SetInterrupt - PyErr_SetNone=python34.PyErr_SetNone - PyErr_SetObject=python34.PyErr_SetObject - PyErr_SetString=python34.PyErr_SetString - PyErr_SyntaxLocation=python34.PyErr_SyntaxLocation - PyErr_WarnEx=python34.PyErr_WarnEx - PyErr_WarnExplicit=python34.PyErr_WarnExplicit - PyErr_WarnFormat=python34.PyErr_WarnFormat - PyErr_WriteUnraisable=python34.PyErr_WriteUnraisable - PyEval_AcquireLock=python34.PyEval_AcquireLock - PyEval_AcquireThread=python34.PyEval_AcquireThread - PyEval_CallFunction=python34.PyEval_CallFunction - PyEval_CallMethod=python34.PyEval_CallMethod - PyEval_CallObjectWithKeywords=python34.PyEval_CallObjectWithKeywords - PyEval_EvalCode=python34.PyEval_EvalCode - PyEval_EvalCodeEx=python34.PyEval_EvalCodeEx - PyEval_EvalFrame=python34.PyEval_EvalFrame - PyEval_EvalFrameEx=python34.PyEval_EvalFrameEx - PyEval_GetBuiltins=python34.PyEval_GetBuiltins - PyEval_GetCallStats=python34.PyEval_GetCallStats - PyEval_GetFrame=python34.PyEval_GetFrame - PyEval_GetFuncDesc=python34.PyEval_GetFuncDesc - PyEval_GetFuncName=python34.PyEval_GetFuncName - PyEval_GetGlobals=python34.PyEval_GetGlobals - PyEval_GetLocals=python34.PyEval_GetLocals - PyEval_InitThreads=python34.PyEval_InitThreads - PyEval_ReInitThreads=python34.PyEval_ReInitThreads - PyEval_ReleaseLock=python34.PyEval_ReleaseLock - PyEval_ReleaseThread=python34.PyEval_ReleaseThread - PyEval_RestoreThread=python34.PyEval_RestoreThread - PyEval_SaveThread=python34.PyEval_SaveThread - PyEval_ThreadsInitialized=python34.PyEval_ThreadsInitialized - PyExc_ArithmeticError=python34.PyExc_ArithmeticError DATA - PyExc_AssertionError=python34.PyExc_AssertionError DATA - PyExc_AttributeError=python34.PyExc_AttributeError DATA - PyExc_BaseException=python34.PyExc_BaseException DATA - PyExc_BufferError=python34.PyExc_BufferError DATA - PyExc_BytesWarning=python34.PyExc_BytesWarning DATA - PyExc_DeprecationWarning=python34.PyExc_DeprecationWarning DATA - PyExc_EOFError=python34.PyExc_EOFError DATA - PyExc_EnvironmentError=python34.PyExc_EnvironmentError DATA - PyExc_Exception=python34.PyExc_Exception DATA - PyExc_FloatingPointError=python34.PyExc_FloatingPointError DATA - PyExc_FutureWarning=python34.PyExc_FutureWarning DATA - PyExc_GeneratorExit=python34.PyExc_GeneratorExit DATA - PyExc_IOError=python34.PyExc_IOError DATA - PyExc_ImportError=python34.PyExc_ImportError DATA - PyExc_ImportWarning=python34.PyExc_ImportWarning DATA - PyExc_IndentationError=python34.PyExc_IndentationError DATA - PyExc_IndexError=python34.PyExc_IndexError DATA - PyExc_KeyError=python34.PyExc_KeyError DATA - PyExc_KeyboardInterrupt=python34.PyExc_KeyboardInterrupt DATA - PyExc_LookupError=python34.PyExc_LookupError DATA - PyExc_MemoryError=python34.PyExc_MemoryError DATA - PyExc_MemoryErrorInst=python34.PyExc_MemoryErrorInst DATA - PyExc_NameError=python34.PyExc_NameError DATA - PyExc_NotImplementedError=python34.PyExc_NotImplementedError DATA - PyExc_OSError=python34.PyExc_OSError DATA - PyExc_OverflowError=python34.PyExc_OverflowError DATA - PyExc_PendingDeprecationWarning=python34.PyExc_PendingDeprecationWarning DATA - PyExc_RecursionErrorInst=python34.PyExc_RecursionErrorInst DATA - PyExc_ReferenceError=python34.PyExc_ReferenceError DATA - PyExc_RuntimeError=python34.PyExc_RuntimeError DATA - PyExc_RuntimeWarning=python34.PyExc_RuntimeWarning DATA - PyExc_StopIteration=python34.PyExc_StopIteration DATA - PyExc_SyntaxError=python34.PyExc_SyntaxError DATA - PyExc_SyntaxWarning=python34.PyExc_SyntaxWarning DATA - PyExc_SystemError=python34.PyExc_SystemError DATA - PyExc_SystemExit=python34.PyExc_SystemExit DATA - PyExc_TabError=python34.PyExc_TabError DATA - PyExc_TypeError=python34.PyExc_TypeError DATA - PyExc_UnboundLocalError=python34.PyExc_UnboundLocalError DATA - PyExc_UnicodeDecodeError=python34.PyExc_UnicodeDecodeError DATA - PyExc_UnicodeEncodeError=python34.PyExc_UnicodeEncodeError DATA - PyExc_UnicodeError=python34.PyExc_UnicodeError DATA - PyExc_UnicodeTranslateError=python34.PyExc_UnicodeTranslateError DATA - PyExc_UnicodeWarning=python34.PyExc_UnicodeWarning DATA - PyExc_UserWarning=python34.PyExc_UserWarning DATA - PyExc_ValueError=python34.PyExc_ValueError DATA - PyExc_Warning=python34.PyExc_Warning DATA - PyExc_ZeroDivisionError=python34.PyExc_ZeroDivisionError DATA - PyException_GetCause=python34.PyException_GetCause - PyException_GetContext=python34.PyException_GetContext - PyException_GetTraceback=python34.PyException_GetTraceback - PyException_SetCause=python34.PyException_SetCause - PyException_SetContext=python34.PyException_SetContext - PyException_SetTraceback=python34.PyException_SetTraceback - PyFile_FromFd=python34.PyFile_FromFd - PyFile_GetLine=python34.PyFile_GetLine - PyFile_WriteObject=python34.PyFile_WriteObject - PyFile_WriteString=python34.PyFile_WriteString - PyFilter_Type=python34.PyFilter_Type DATA - PyFloat_AsDouble=python34.PyFloat_AsDouble - PyFloat_FromDouble=python34.PyFloat_FromDouble - PyFloat_FromString=python34.PyFloat_FromString - PyFloat_GetInfo=python34.PyFloat_GetInfo - PyFloat_GetMax=python34.PyFloat_GetMax - PyFloat_GetMin=python34.PyFloat_GetMin - PyFloat_Type=python34.PyFloat_Type DATA - PyFrozenSet_New=python34.PyFrozenSet_New - PyFrozenSet_Type=python34.PyFrozenSet_Type DATA - PyGC_Collect=python34.PyGC_Collect - PyGILState_Ensure=python34.PyGILState_Ensure - PyGILState_GetThisThreadState=python34.PyGILState_GetThisThreadState - PyGILState_Release=python34.PyGILState_Release - PyGetSetDescr_Type=python34.PyGetSetDescr_Type DATA - PyImport_AddModule=python34.PyImport_AddModule - PyImport_AppendInittab=python34.PyImport_AppendInittab - PyImport_Cleanup=python34.PyImport_Cleanup - PyImport_ExecCodeModule=python34.PyImport_ExecCodeModule - PyImport_ExecCodeModuleEx=python34.PyImport_ExecCodeModuleEx - PyImport_ExecCodeModuleWithPathnames=python34.PyImport_ExecCodeModuleWithPathnames - PyImport_GetImporter=python34.PyImport_GetImporter - PyImport_GetMagicNumber=python34.PyImport_GetMagicNumber - PyImport_GetMagicTag=python34.PyImport_GetMagicTag - PyImport_GetModuleDict=python34.PyImport_GetModuleDict - PyImport_Import=python34.PyImport_Import - PyImport_ImportFrozenModule=python34.PyImport_ImportFrozenModule - PyImport_ImportModule=python34.PyImport_ImportModule - PyImport_ImportModuleLevel=python34.PyImport_ImportModuleLevel - PyImport_ImportModuleNoBlock=python34.PyImport_ImportModuleNoBlock - PyImport_ReloadModule=python34.PyImport_ReloadModule - PyInterpreterState_Clear=python34.PyInterpreterState_Clear - PyInterpreterState_Delete=python34.PyInterpreterState_Delete - PyInterpreterState_New=python34.PyInterpreterState_New - PyIter_Next=python34.PyIter_Next - PyListIter_Type=python34.PyListIter_Type DATA - PyListRevIter_Type=python34.PyListRevIter_Type DATA - PyList_Append=python34.PyList_Append - PyList_AsTuple=python34.PyList_AsTuple - PyList_GetItem=python34.PyList_GetItem - PyList_GetSlice=python34.PyList_GetSlice - PyList_Insert=python34.PyList_Insert - PyList_New=python34.PyList_New - PyList_Reverse=python34.PyList_Reverse - PyList_SetItem=python34.PyList_SetItem - PyList_SetSlice=python34.PyList_SetSlice - PyList_Size=python34.PyList_Size - PyList_Sort=python34.PyList_Sort - PyList_Type=python34.PyList_Type DATA - PyLongRangeIter_Type=python34.PyLongRangeIter_Type DATA - PyLong_AsDouble=python34.PyLong_AsDouble - PyLong_AsLong=python34.PyLong_AsLong - PyLong_AsLongAndOverflow=python34.PyLong_AsLongAndOverflow - PyLong_AsLongLong=python34.PyLong_AsLongLong - PyLong_AsLongLongAndOverflow=python34.PyLong_AsLongLongAndOverflow - PyLong_AsSize_t=python34.PyLong_AsSize_t - PyLong_AsSsize_t=python34.PyLong_AsSsize_t - PyLong_AsUnsignedLong=python34.PyLong_AsUnsignedLong - PyLong_AsUnsignedLongLong=python34.PyLong_AsUnsignedLongLong - PyLong_AsUnsignedLongLongMask=python34.PyLong_AsUnsignedLongLongMask - PyLong_AsUnsignedLongMask=python34.PyLong_AsUnsignedLongMask - PyLong_AsVoidPtr=python34.PyLong_AsVoidPtr - PyLong_FromDouble=python34.PyLong_FromDouble - PyLong_FromLong=python34.PyLong_FromLong - PyLong_FromLongLong=python34.PyLong_FromLongLong - PyLong_FromSize_t=python34.PyLong_FromSize_t - PyLong_FromSsize_t=python34.PyLong_FromSsize_t - PyLong_FromString=python34.PyLong_FromString - PyLong_FromUnsignedLong=python34.PyLong_FromUnsignedLong - PyLong_FromUnsignedLongLong=python34.PyLong_FromUnsignedLongLong - PyLong_FromVoidPtr=python34.PyLong_FromVoidPtr - PyLong_GetInfo=python34.PyLong_GetInfo - PyLong_Type=python34.PyLong_Type DATA - PyMap_Type=python34.PyMap_Type DATA - PyMapping_Check=python34.PyMapping_Check - PyMapping_GetItemString=python34.PyMapping_GetItemString - PyMapping_HasKey=python34.PyMapping_HasKey - PyMapping_HasKeyString=python34.PyMapping_HasKeyString - PyMapping_Items=python34.PyMapping_Items - PyMapping_Keys=python34.PyMapping_Keys - PyMapping_Length=python34.PyMapping_Length - PyMapping_SetItemString=python34.PyMapping_SetItemString - PyMapping_Size=python34.PyMapping_Size - PyMapping_Values=python34.PyMapping_Values - PyMem_Free=python34.PyMem_Free - PyMem_Malloc=python34.PyMem_Malloc - PyMem_Realloc=python34.PyMem_Realloc - PyMemberDescr_Type=python34.PyMemberDescr_Type DATA - PyMemoryView_FromObject=python34.PyMemoryView_FromObject - PyMemoryView_GetContiguous=python34.PyMemoryView_GetContiguous - PyMemoryView_Type=python34.PyMemoryView_Type DATA - PyMethodDescr_Type=python34.PyMethodDescr_Type DATA - PyModule_AddIntConstant=python34.PyModule_AddIntConstant - PyModule_AddObject=python34.PyModule_AddObject - PyModule_AddStringConstant=python34.PyModule_AddStringConstant - PyModule_Create2=python34.PyModule_Create2 - PyModule_GetDef=python34.PyModule_GetDef - PyModule_GetDict=python34.PyModule_GetDict - PyModule_GetFilename=python34.PyModule_GetFilename - PyModule_GetFilenameObject=python34.PyModule_GetFilenameObject - PyModule_GetName=python34.PyModule_GetName - PyModule_GetState=python34.PyModule_GetState - PyModule_New=python34.PyModule_New - PyModule_Type=python34.PyModule_Type DATA - PyNullImporter_Type=python34.PyNullImporter_Type DATA - PyNumber_Absolute=python34.PyNumber_Absolute - PyNumber_Add=python34.PyNumber_Add - PyNumber_And=python34.PyNumber_And - PyNumber_AsSsize_t=python34.PyNumber_AsSsize_t - PyNumber_Check=python34.PyNumber_Check - PyNumber_Divmod=python34.PyNumber_Divmod - PyNumber_Float=python34.PyNumber_Float - PyNumber_FloorDivide=python34.PyNumber_FloorDivide - PyNumber_InPlaceAdd=python34.PyNumber_InPlaceAdd - PyNumber_InPlaceAnd=python34.PyNumber_InPlaceAnd - PyNumber_InPlaceFloorDivide=python34.PyNumber_InPlaceFloorDivide - PyNumber_InPlaceLshift=python34.PyNumber_InPlaceLshift - PyNumber_InPlaceMultiply=python34.PyNumber_InPlaceMultiply - PyNumber_InPlaceOr=python34.PyNumber_InPlaceOr - PyNumber_InPlacePower=python34.PyNumber_InPlacePower - PyNumber_InPlaceRemainder=python34.PyNumber_InPlaceRemainder - PyNumber_InPlaceRshift=python34.PyNumber_InPlaceRshift - PyNumber_InPlaceSubtract=python34.PyNumber_InPlaceSubtract - PyNumber_InPlaceTrueDivide=python34.PyNumber_InPlaceTrueDivide - PyNumber_InPlaceXor=python34.PyNumber_InPlaceXor - PyNumber_Index=python34.PyNumber_Index - PyNumber_Invert=python34.PyNumber_Invert - PyNumber_Long=python34.PyNumber_Long - PyNumber_Lshift=python34.PyNumber_Lshift - PyNumber_Multiply=python34.PyNumber_Multiply - PyNumber_Negative=python34.PyNumber_Negative - PyNumber_Or=python34.PyNumber_Or - PyNumber_Positive=python34.PyNumber_Positive - PyNumber_Power=python34.PyNumber_Power - PyNumber_Remainder=python34.PyNumber_Remainder - PyNumber_Rshift=python34.PyNumber_Rshift - PyNumber_Subtract=python34.PyNumber_Subtract - PyNumber_ToBase=python34.PyNumber_ToBase - PyNumber_TrueDivide=python34.PyNumber_TrueDivide - PyNumber_Xor=python34.PyNumber_Xor - PyOS_AfterFork=python34.PyOS_AfterFork - PyOS_InitInterrupts=python34.PyOS_InitInterrupts - PyOS_InputHook=python34.PyOS_InputHook DATA - PyOS_InterruptOccurred=python34.PyOS_InterruptOccurred - PyOS_ReadlineFunctionPointer=python34.PyOS_ReadlineFunctionPointer DATA - PyOS_double_to_string=python34.PyOS_double_to_string - PyOS_getsig=python34.PyOS_getsig - PyOS_mystricmp=python34.PyOS_mystricmp - PyOS_mystrnicmp=python34.PyOS_mystrnicmp - PyOS_setsig=python34.PyOS_setsig - PyOS_snprintf=python34.PyOS_snprintf - PyOS_string_to_double=python34.PyOS_string_to_double - PyOS_strtol=python34.PyOS_strtol - PyOS_strtoul=python34.PyOS_strtoul - PyOS_vsnprintf=python34.PyOS_vsnprintf - PyObject_ASCII=python34.PyObject_ASCII - PyObject_AsCharBuffer=python34.PyObject_AsCharBuffer - PyObject_AsFileDescriptor=python34.PyObject_AsFileDescriptor - PyObject_AsReadBuffer=python34.PyObject_AsReadBuffer - PyObject_AsWriteBuffer=python34.PyObject_AsWriteBuffer - PyObject_Bytes=python34.PyObject_Bytes - PyObject_Call=python34.PyObject_Call - PyObject_CallFunction=python34.PyObject_CallFunction - PyObject_CallFunctionObjArgs=python34.PyObject_CallFunctionObjArgs - PyObject_CallMethod=python34.PyObject_CallMethod - PyObject_CallMethodObjArgs=python34.PyObject_CallMethodObjArgs - PyObject_CallObject=python34.PyObject_CallObject - PyObject_CheckReadBuffer=python34.PyObject_CheckReadBuffer - PyObject_ClearWeakRefs=python34.PyObject_ClearWeakRefs - PyObject_DelItem=python34.PyObject_DelItem - PyObject_DelItemString=python34.PyObject_DelItemString - PyObject_Dir=python34.PyObject_Dir - PyObject_Format=python34.PyObject_Format - PyObject_Free=python34.PyObject_Free - PyObject_GC_Del=python34.PyObject_GC_Del - PyObject_GC_Track=python34.PyObject_GC_Track - PyObject_GC_UnTrack=python34.PyObject_GC_UnTrack - PyObject_GenericGetAttr=python34.PyObject_GenericGetAttr - PyObject_GenericSetAttr=python34.PyObject_GenericSetAttr - PyObject_GetAttr=python34.PyObject_GetAttr - PyObject_GetAttrString=python34.PyObject_GetAttrString - PyObject_GetItem=python34.PyObject_GetItem - PyObject_GetIter=python34.PyObject_GetIter - PyObject_HasAttr=python34.PyObject_HasAttr - PyObject_HasAttrString=python34.PyObject_HasAttrString - PyObject_Hash=python34.PyObject_Hash - PyObject_HashNotImplemented=python34.PyObject_HashNotImplemented - PyObject_Init=python34.PyObject_Init - PyObject_InitVar=python34.PyObject_InitVar - PyObject_IsInstance=python34.PyObject_IsInstance - PyObject_IsSubclass=python34.PyObject_IsSubclass - PyObject_IsTrue=python34.PyObject_IsTrue - PyObject_Length=python34.PyObject_Length - PyObject_Malloc=python34.PyObject_Malloc - PyObject_Not=python34.PyObject_Not - PyObject_Realloc=python34.PyObject_Realloc - PyObject_Repr=python34.PyObject_Repr - PyObject_RichCompare=python34.PyObject_RichCompare - PyObject_RichCompareBool=python34.PyObject_RichCompareBool - PyObject_SelfIter=python34.PyObject_SelfIter - PyObject_SetAttr=python34.PyObject_SetAttr - PyObject_SetAttrString=python34.PyObject_SetAttrString - PyObject_SetItem=python34.PyObject_SetItem - PyObject_Size=python34.PyObject_Size - PyObject_Str=python34.PyObject_Str - PyObject_Type=python34.PyObject_Type DATA - PyParser_SimpleParseFileFlags=python34.PyParser_SimpleParseFileFlags - PyParser_SimpleParseStringFlags=python34.PyParser_SimpleParseStringFlags - PyProperty_Type=python34.PyProperty_Type DATA - PyRangeIter_Type=python34.PyRangeIter_Type DATA - PyRange_Type=python34.PyRange_Type DATA - PyReversed_Type=python34.PyReversed_Type DATA - PySeqIter_New=python34.PySeqIter_New - PySeqIter_Type=python34.PySeqIter_Type DATA - PySequence_Check=python34.PySequence_Check - PySequence_Concat=python34.PySequence_Concat - PySequence_Contains=python34.PySequence_Contains - PySequence_Count=python34.PySequence_Count - PySequence_DelItem=python34.PySequence_DelItem - PySequence_DelSlice=python34.PySequence_DelSlice - PySequence_Fast=python34.PySequence_Fast - PySequence_GetItem=python34.PySequence_GetItem - PySequence_GetSlice=python34.PySequence_GetSlice - PySequence_In=python34.PySequence_In - PySequence_InPlaceConcat=python34.PySequence_InPlaceConcat - PySequence_InPlaceRepeat=python34.PySequence_InPlaceRepeat - PySequence_Index=python34.PySequence_Index - PySequence_Length=python34.PySequence_Length - PySequence_List=python34.PySequence_List - PySequence_Repeat=python34.PySequence_Repeat - PySequence_SetItem=python34.PySequence_SetItem - PySequence_SetSlice=python34.PySequence_SetSlice - PySequence_Size=python34.PySequence_Size - PySequence_Tuple=python34.PySequence_Tuple - PySetIter_Type=python34.PySetIter_Type DATA - PySet_Add=python34.PySet_Add - PySet_Clear=python34.PySet_Clear - PySet_Contains=python34.PySet_Contains - PySet_Discard=python34.PySet_Discard - PySet_New=python34.PySet_New - PySet_Pop=python34.PySet_Pop - PySet_Size=python34.PySet_Size - PySet_Type=python34.PySet_Type DATA - PySlice_GetIndices=python34.PySlice_GetIndices - PySlice_GetIndicesEx=python34.PySlice_GetIndicesEx - PySlice_New=python34.PySlice_New - PySlice_Type=python34.PySlice_Type DATA - PySortWrapper_Type=python34.PySortWrapper_Type DATA - PyState_FindModule=python34.PyState_FindModule - PyState_AddModule=python34.PyState_AddModule - PyState_RemoveModule=python34.PyState_RemoveModule - PyStructSequence_GetItem=python34.PyStructSequence_GetItem - PyStructSequence_New=python34.PyStructSequence_New - PyStructSequence_NewType=python34.PyStructSequence_NewType - PyStructSequence_SetItem=python34.PyStructSequence_SetItem - PySuper_Type=python34.PySuper_Type DATA - PySys_AddWarnOption=python34.PySys_AddWarnOption - PySys_AddWarnOptionUnicode=python34.PySys_AddWarnOptionUnicode - PySys_FormatStderr=python34.PySys_FormatStderr - PySys_FormatStdout=python34.PySys_FormatStdout - PySys_GetObject=python34.PySys_GetObject - PySys_HasWarnOptions=python34.PySys_HasWarnOptions - PySys_ResetWarnOptions=python34.PySys_ResetWarnOptions - PySys_SetArgv=python34.PySys_SetArgv - PySys_SetArgvEx=python34.PySys_SetArgvEx - PySys_SetObject=python34.PySys_SetObject - PySys_SetPath=python34.PySys_SetPath - PySys_WriteStderr=python34.PySys_WriteStderr - PySys_WriteStdout=python34.PySys_WriteStdout - PyThreadState_Clear=python34.PyThreadState_Clear - PyThreadState_Delete=python34.PyThreadState_Delete - PyThreadState_DeleteCurrent=python34.PyThreadState_DeleteCurrent - PyThreadState_Get=python34.PyThreadState_Get - PyThreadState_GetDict=python34.PyThreadState_GetDict - PyThreadState_New=python34.PyThreadState_New - PyThreadState_SetAsyncExc=python34.PyThreadState_SetAsyncExc - PyThreadState_Swap=python34.PyThreadState_Swap - PyTraceBack_Here=python34.PyTraceBack_Here - PyTraceBack_Print=python34.PyTraceBack_Print - PyTraceBack_Type=python34.PyTraceBack_Type DATA - PyTupleIter_Type=python34.PyTupleIter_Type DATA - PyTuple_ClearFreeList=python34.PyTuple_ClearFreeList - PyTuple_GetItem=python34.PyTuple_GetItem - PyTuple_GetSlice=python34.PyTuple_GetSlice - PyTuple_New=python34.PyTuple_New - PyTuple_Pack=python34.PyTuple_Pack - PyTuple_SetItem=python34.PyTuple_SetItem - PyTuple_Size=python34.PyTuple_Size - PyTuple_Type=python34.PyTuple_Type DATA - PyType_ClearCache=python34.PyType_ClearCache - PyType_FromSpec=python34.PyType_FromSpec - PyType_FromSpecWithBases=python34.PyType_FromSpecWithBases - PyType_GenericAlloc=python34.PyType_GenericAlloc - PyType_GenericNew=python34.PyType_GenericNew - PyType_GetFlags=python34.PyType_GetFlags - PyType_IsSubtype=python34.PyType_IsSubtype - PyType_Modified=python34.PyType_Modified - PyType_Ready=python34.PyType_Ready - PyType_Type=python34.PyType_Type DATA - PyUnicodeDecodeError_Create=python34.PyUnicodeDecodeError_Create - PyUnicodeDecodeError_GetEncoding=python34.PyUnicodeDecodeError_GetEncoding - PyUnicodeDecodeError_GetEnd=python34.PyUnicodeDecodeError_GetEnd - PyUnicodeDecodeError_GetObject=python34.PyUnicodeDecodeError_GetObject - PyUnicodeDecodeError_GetReason=python34.PyUnicodeDecodeError_GetReason - PyUnicodeDecodeError_GetStart=python34.PyUnicodeDecodeError_GetStart - PyUnicodeDecodeError_SetEnd=python34.PyUnicodeDecodeError_SetEnd - PyUnicodeDecodeError_SetReason=python34.PyUnicodeDecodeError_SetReason - PyUnicodeDecodeError_SetStart=python34.PyUnicodeDecodeError_SetStart - PyUnicodeEncodeError_GetEncoding=python34.PyUnicodeEncodeError_GetEncoding - PyUnicodeEncodeError_GetEnd=python34.PyUnicodeEncodeError_GetEnd - PyUnicodeEncodeError_GetObject=python34.PyUnicodeEncodeError_GetObject - PyUnicodeEncodeError_GetReason=python34.PyUnicodeEncodeError_GetReason - PyUnicodeEncodeError_GetStart=python34.PyUnicodeEncodeError_GetStart - PyUnicodeEncodeError_SetEnd=python34.PyUnicodeEncodeError_SetEnd - PyUnicodeEncodeError_SetReason=python34.PyUnicodeEncodeError_SetReason - PyUnicodeEncodeError_SetStart=python34.PyUnicodeEncodeError_SetStart - PyUnicodeIter_Type=python34.PyUnicodeIter_Type DATA - PyUnicodeTranslateError_GetEnd=python34.PyUnicodeTranslateError_GetEnd - PyUnicodeTranslateError_GetObject=python34.PyUnicodeTranslateError_GetObject - PyUnicodeTranslateError_GetReason=python34.PyUnicodeTranslateError_GetReason - PyUnicodeTranslateError_GetStart=python34.PyUnicodeTranslateError_GetStart - PyUnicodeTranslateError_SetEnd=python34.PyUnicodeTranslateError_SetEnd - PyUnicodeTranslateError_SetReason=python34.PyUnicodeTranslateError_SetReason - PyUnicodeTranslateError_SetStart=python34.PyUnicodeTranslateError_SetStart - PyUnicode_Append=python34.PyUnicodeUCS2_Append - PyUnicode_AppendAndDel=python34.PyUnicodeUCS2_AppendAndDel - PyUnicode_AsASCIIString=python34.PyUnicodeUCS2_AsASCIIString - PyUnicode_AsCharmapString=python34.PyUnicodeUCS2_AsCharmapString - PyUnicode_AsDecodedObject=python34.PyUnicodeUCS2_AsDecodedObject - PyUnicode_AsDecodedUnicode=python34.PyUnicodeUCS2_AsDecodedUnicode - PyUnicode_AsEncodedObject=python34.PyUnicodeUCS2_AsEncodedObject - PyUnicode_AsEncodedString=python34.PyUnicodeUCS2_AsEncodedString - PyUnicode_AsEncodedUnicode=python34.PyUnicodeUCS2_AsEncodedUnicode - PyUnicode_AsLatin1String=python34.PyUnicodeUCS2_AsLatin1String - PyUnicode_AsRawUnicodeEscapeString=python34.PyUnicodeUCS2_AsRawUnicodeEscapeString - PyUnicode_AsUTF16String=python34.PyUnicodeUCS2_AsUTF16String - PyUnicode_AsUTF32String=python34.PyUnicodeUCS2_AsUTF32String - PyUnicode_AsUTF8String=python34.PyUnicodeUCS2_AsUTF8String - PyUnicode_AsUnicodeEscapeString=python34.PyUnicodeUCS2_AsUnicodeEscapeString - PyUnicode_AsWideChar=python34.PyUnicodeUCS2_AsWideChar - PyUnicode_ClearFreelist=python34.PyUnicodeUCS2_ClearFreelist - PyUnicode_Compare=python34.PyUnicodeUCS2_Compare - PyUnicode_Concat=python34.PyUnicodeUCS2_Concat - PyUnicode_Contains=python34.PyUnicodeUCS2_Contains - PyUnicode_Count=python34.PyUnicodeUCS2_Count - PyUnicode_Decode=python34.PyUnicodeUCS2_Decode - PyUnicode_DecodeASCII=python34.PyUnicodeUCS2_DecodeASCII - PyUnicode_DecodeCharmap=python34.PyUnicodeUCS2_DecodeCharmap - PyUnicode_DecodeFSDefault=python34.PyUnicodeUCS2_DecodeFSDefault - PyUnicode_DecodeFSDefaultAndSize=python34.PyUnicodeUCS2_DecodeFSDefaultAndSize - PyUnicode_DecodeLatin1=python34.PyUnicodeUCS2_DecodeLatin1 - PyUnicode_DecodeRawUnicodeEscape=python34.PyUnicodeUCS2_DecodeRawUnicodeEscape - PyUnicode_DecodeUTF16=python34.PyUnicodeUCS2_DecodeUTF16 - PyUnicode_DecodeUTF16Stateful=python34.PyUnicodeUCS2_DecodeUTF16Stateful - PyUnicode_DecodeUTF32=python34.PyUnicodeUCS2_DecodeUTF32 - PyUnicode_DecodeUTF32Stateful=python34.PyUnicodeUCS2_DecodeUTF32Stateful - PyUnicode_DecodeUTF8=python34.PyUnicodeUCS2_DecodeUTF8 - PyUnicode_DecodeUTF8Stateful=python34.PyUnicodeUCS2_DecodeUTF8Stateful - PyUnicode_DecodeUnicodeEscape=python34.PyUnicodeUCS2_DecodeUnicodeEscape - PyUnicode_FSConverter=python34.PyUnicodeUCS2_FSConverter - PyUnicode_FSDecoder=python34.PyUnicodeUCS2_FSDecoder - PyUnicode_Find=python34.PyUnicodeUCS2_Find - PyUnicode_Format=python34.PyUnicodeUCS2_Format - PyUnicode_FromEncodedObject=python34.PyUnicodeUCS2_FromEncodedObject - PyUnicode_FromFormat=python34.PyUnicodeUCS2_FromFormat - PyUnicode_FromFormatV=python34.PyUnicodeUCS2_FromFormatV - PyUnicode_FromObject=python34.PyUnicodeUCS2_FromObject - PyUnicode_FromOrdinal=python34.PyUnicodeUCS2_FromOrdinal - PyUnicode_FromString=python34.PyUnicodeUCS2_FromString - PyUnicode_FromStringAndSize=python34.PyUnicodeUCS2_FromStringAndSize - PyUnicode_FromWideChar=python34.PyUnicodeUCS2_FromWideChar - PyUnicode_GetDefaultEncoding=python34.PyUnicodeUCS2_GetDefaultEncoding - PyUnicode_GetSize=python34.PyUnicodeUCS2_GetSize - PyUnicode_IsIdentifier=python34.PyUnicodeUCS2_IsIdentifier - PyUnicode_Join=python34.PyUnicodeUCS2_Join - PyUnicode_Partition=python34.PyUnicodeUCS2_Partition - PyUnicode_RPartition=python34.PyUnicodeUCS2_RPartition - PyUnicode_RSplit=python34.PyUnicodeUCS2_RSplit - PyUnicode_Replace=python34.PyUnicodeUCS2_Replace - PyUnicode_Resize=python34.PyUnicodeUCS2_Resize - PyUnicode_RichCompare=python34.PyUnicodeUCS2_RichCompare - PyUnicode_SetDefaultEncoding=python34.PyUnicodeUCS2_SetDefaultEncoding - PyUnicode_Split=python34.PyUnicodeUCS2_Split - PyUnicode_Splitlines=python34.PyUnicodeUCS2_Splitlines - PyUnicode_Tailmatch=python34.PyUnicodeUCS2_Tailmatch - PyUnicode_Translate=python34.PyUnicodeUCS2_Translate - PyUnicode_BuildEncodingMap=python34.PyUnicode_BuildEncodingMap - PyUnicode_CompareWithASCIIString=python34.PyUnicode_CompareWithASCIIString - PyUnicode_DecodeUTF7=python34.PyUnicode_DecodeUTF7 - PyUnicode_DecodeUTF7Stateful=python34.PyUnicode_DecodeUTF7Stateful - PyUnicode_EncodeFSDefault=python34.PyUnicode_EncodeFSDefault - PyUnicode_InternFromString=python34.PyUnicode_InternFromString - PyUnicode_InternImmortal=python34.PyUnicode_InternImmortal - PyUnicode_InternInPlace=python34.PyUnicode_InternInPlace - PyUnicode_Type=python34.PyUnicode_Type DATA - PyWeakref_GetObject=python34.PyWeakref_GetObject DATA - PyWeakref_NewProxy=python34.PyWeakref_NewProxy - PyWeakref_NewRef=python34.PyWeakref_NewRef - PyWrapperDescr_Type=python34.PyWrapperDescr_Type DATA - PyWrapper_New=python34.PyWrapper_New - PyZip_Type=python34.PyZip_Type DATA - Py_AddPendingCall=python34.Py_AddPendingCall - Py_AtExit=python34.Py_AtExit - Py_BuildValue=python34.Py_BuildValue - Py_CompileString=python34.Py_CompileString - Py_DecRef=python34.Py_DecRef - Py_EndInterpreter=python34.Py_EndInterpreter - Py_Exit=python34.Py_Exit - Py_FatalError=python34.Py_FatalError - Py_FileSystemDefaultEncoding=python34.Py_FileSystemDefaultEncoding DATA - Py_Finalize=python34.Py_Finalize - Py_GetBuildInfo=python34.Py_GetBuildInfo - Py_GetCompiler=python34.Py_GetCompiler - Py_GetCopyright=python34.Py_GetCopyright - Py_GetExecPrefix=python34.Py_GetExecPrefix - Py_GetPath=python34.Py_GetPath - Py_GetPlatform=python34.Py_GetPlatform - Py_GetPrefix=python34.Py_GetPrefix - Py_GetProgramFullPath=python34.Py_GetProgramFullPath - Py_GetProgramName=python34.Py_GetProgramName - Py_GetPythonHome=python34.Py_GetPythonHome - Py_GetRecursionLimit=python34.Py_GetRecursionLimit - Py_GetVersion=python34.Py_GetVersion - Py_HasFileSystemDefaultEncoding=python34.Py_HasFileSystemDefaultEncoding DATA - Py_IncRef=python34.Py_IncRef - Py_Initialize=python34.Py_Initialize - Py_InitializeEx=python34.Py_InitializeEx - Py_IsInitialized=python34.Py_IsInitialized - Py_Main=python34.Py_Main - Py_MakePendingCalls=python34.Py_MakePendingCalls - Py_NewInterpreter=python34.Py_NewInterpreter - Py_ReprEnter=python34.Py_ReprEnter - Py_ReprLeave=python34.Py_ReprLeave - Py_SetProgramName=python34.Py_SetProgramName - Py_SetPythonHome=python34.Py_SetPythonHome - Py_SetRecursionLimit=python34.Py_SetRecursionLimit - Py_SymtableString=python34.Py_SymtableString - Py_VaBuildValue=python34.Py_VaBuildValue - _PyErr_BadInternalCall=python34._PyErr_BadInternalCall - _PyObject_CallFunction_SizeT=python34._PyObject_CallFunction_SizeT - _PyObject_CallMethod_SizeT=python34._PyObject_CallMethod_SizeT - _PyObject_GC_Malloc=python34._PyObject_GC_Malloc - _PyObject_GC_New=python34._PyObject_GC_New - _PyObject_GC_NewVar=python34._PyObject_GC_NewVar - _PyObject_GC_Resize=python34._PyObject_GC_Resize - _PyObject_New=python34._PyObject_New - _PyObject_NewVar=python34._PyObject_NewVar - _PyState_AddModule=python34._PyState_AddModule - _PyThreadState_Init=python34._PyThreadState_Init - _PyThreadState_Prealloc=python34._PyThreadState_Prealloc - _PyTrash_delete_later=python34._PyTrash_delete_later DATA - _PyTrash_delete_nesting=python34._PyTrash_delete_nesting DATA - _PyTrash_deposit_object=python34._PyTrash_deposit_object - _PyTrash_destroy_chain=python34._PyTrash_destroy_chain - _PyWeakref_CallableProxyType=python34._PyWeakref_CallableProxyType DATA - _PyWeakref_ProxyType=python34._PyWeakref_ProxyType DATA - _PyWeakref_RefType=python34._PyWeakref_RefType DATA - _Py_BuildValue_SizeT=python34._Py_BuildValue_SizeT - _Py_CheckRecursionLimit=python34._Py_CheckRecursionLimit DATA - _Py_CheckRecursiveCall=python34._Py_CheckRecursiveCall - _Py_Dealloc=python34._Py_Dealloc - _Py_EllipsisObject=python34._Py_EllipsisObject DATA - _Py_FalseStruct=python34._Py_FalseStruct DATA - _Py_NoneStruct=python34._Py_NoneStruct DATA - _Py_NotImplementedStruct=python34._Py_NotImplementedStruct DATA - _Py_SwappedOp=python34._Py_SwappedOp DATA - _Py_TrueStruct=python34._Py_TrueStruct DATA - _Py_VaBuildValue_SizeT=python34._Py_VaBuildValue_SizeT - _PyArg_Parse_SizeT=python34._PyArg_Parse_SizeT - _PyArg_ParseTuple_SizeT=python34._PyArg_ParseTuple_SizeT - _PyArg_ParseTupleAndKeywords_SizeT=python34._PyArg_ParseTupleAndKeywords_SizeT - _PyArg_VaParse_SizeT=python34._PyArg_VaParse_SizeT - _PyArg_VaParseTupleAndKeywords_SizeT=python34._PyArg_VaParseTupleAndKeywords_SizeT - _Py_BuildValue_SizeT=python34._Py_BuildValue_SizeT + PyArg_Parse=python36.PyArg_Parse + PyArg_ParseTuple=python36.PyArg_ParseTuple + PyArg_ParseTupleAndKeywords=python36.PyArg_ParseTupleAndKeywords + PyArg_UnpackTuple=python36.PyArg_UnpackTuple + PyArg_VaParse=python36.PyArg_VaParse + PyArg_VaParseTupleAndKeywords=python36.PyArg_VaParseTupleAndKeywords + PyArg_ValidateKeywordArguments=python36.PyArg_ValidateKeywordArguments + PyBaseObject_Type=python36.PyBaseObject_Type DATA + PyBool_FromLong=python36.PyBool_FromLong + PyBool_Type=python36.PyBool_Type DATA + PyByteArrayIter_Type=python36.PyByteArrayIter_Type DATA + PyByteArray_AsString=python36.PyByteArray_AsString + PyByteArray_Concat=python36.PyByteArray_Concat + PyByteArray_FromObject=python36.PyByteArray_FromObject + PyByteArray_FromStringAndSize=python36.PyByteArray_FromStringAndSize + PyByteArray_Resize=python36.PyByteArray_Resize + PyByteArray_Size=python36.PyByteArray_Size + PyByteArray_Type=python36.PyByteArray_Type DATA + PyBytesIter_Type=python36.PyBytesIter_Type DATA + PyBytes_AsString=python36.PyBytes_AsString + PyBytes_AsStringAndSize=python36.PyBytes_AsStringAndSize + PyBytes_Concat=python36.PyBytes_Concat + PyBytes_ConcatAndDel=python36.PyBytes_ConcatAndDel + PyBytes_DecodeEscape=python36.PyBytes_DecodeEscape + PyBytes_FromFormat=python36.PyBytes_FromFormat + PyBytes_FromFormatV=python36.PyBytes_FromFormatV + PyBytes_FromObject=python36.PyBytes_FromObject + PyBytes_FromString=python36.PyBytes_FromString + PyBytes_FromStringAndSize=python36.PyBytes_FromStringAndSize + PyBytes_Repr=python36.PyBytes_Repr + PyBytes_Size=python36.PyBytes_Size + PyBytes_Type=python36.PyBytes_Type DATA + PyCFunction_Call=python36.PyCFunction_Call + PyCFunction_ClearFreeList=python36.PyCFunction_ClearFreeList + PyCFunction_GetFlags=python36.PyCFunction_GetFlags + PyCFunction_GetFunction=python36.PyCFunction_GetFunction + PyCFunction_GetSelf=python36.PyCFunction_GetSelf + PyCFunction_New=python36.PyCFunction_New + PyCFunction_NewEx=python36.PyCFunction_NewEx + PyCFunction_Type=python36.PyCFunction_Type DATA + PyCallIter_New=python36.PyCallIter_New + PyCallIter_Type=python36.PyCallIter_Type DATA + PyCallable_Check=python36.PyCallable_Check + PyCapsule_GetContext=python36.PyCapsule_GetContext + PyCapsule_GetDestructor=python36.PyCapsule_GetDestructor + PyCapsule_GetName=python36.PyCapsule_GetName + PyCapsule_GetPointer=python36.PyCapsule_GetPointer + PyCapsule_Import=python36.PyCapsule_Import + PyCapsule_IsValid=python36.PyCapsule_IsValid + PyCapsule_New=python36.PyCapsule_New + PyCapsule_SetContext=python36.PyCapsule_SetContext + PyCapsule_SetDestructor=python36.PyCapsule_SetDestructor + PyCapsule_SetName=python36.PyCapsule_SetName + PyCapsule_SetPointer=python36.PyCapsule_SetPointer + PyCapsule_Type=python36.PyCapsule_Type DATA + PyClassMethodDescr_Type=python36.PyClassMethodDescr_Type DATA + PyCodec_BackslashReplaceErrors=python36.PyCodec_BackslashReplaceErrors + PyCodec_Decode=python36.PyCodec_Decode + PyCodec_Decoder=python36.PyCodec_Decoder + PyCodec_Encode=python36.PyCodec_Encode + PyCodec_Encoder=python36.PyCodec_Encoder + PyCodec_IgnoreErrors=python36.PyCodec_IgnoreErrors + PyCodec_IncrementalDecoder=python36.PyCodec_IncrementalDecoder + PyCodec_IncrementalEncoder=python36.PyCodec_IncrementalEncoder + PyCodec_KnownEncoding=python36.PyCodec_KnownEncoding + PyCodec_LookupError=python36.PyCodec_LookupError + PyCodec_Register=python36.PyCodec_Register + PyCodec_RegisterError=python36.PyCodec_RegisterError + PyCodec_ReplaceErrors=python36.PyCodec_ReplaceErrors + PyCodec_StreamReader=python36.PyCodec_StreamReader + PyCodec_StreamWriter=python36.PyCodec_StreamWriter + PyCodec_StrictErrors=python36.PyCodec_StrictErrors + PyCodec_XMLCharRefReplaceErrors=python36.PyCodec_XMLCharRefReplaceErrors + PyComplex_FromDoubles=python36.PyComplex_FromDoubles + PyComplex_ImagAsDouble=python36.PyComplex_ImagAsDouble + PyComplex_RealAsDouble=python36.PyComplex_RealAsDouble + PyComplex_Type=python36.PyComplex_Type DATA + PyDescr_NewClassMethod=python36.PyDescr_NewClassMethod + PyDescr_NewGetSet=python36.PyDescr_NewGetSet + PyDescr_NewMember=python36.PyDescr_NewMember + PyDescr_NewMethod=python36.PyDescr_NewMethod + PyDictItems_Type=python36.PyDictItems_Type DATA + PyDictIterItem_Type=python36.PyDictIterItem_Type DATA + PyDictIterKey_Type=python36.PyDictIterKey_Type DATA + PyDictIterValue_Type=python36.PyDictIterValue_Type DATA + PyDictKeys_Type=python36.PyDictKeys_Type DATA + PyDictProxy_New=python36.PyDictProxy_New + PyDictProxy_Type=python36.PyDictProxy_Type DATA + PyDictValues_Type=python36.PyDictValues_Type DATA + PyDict_Clear=python36.PyDict_Clear + PyDict_Contains=python36.PyDict_Contains + PyDict_Copy=python36.PyDict_Copy + PyDict_DelItem=python36.PyDict_DelItem + PyDict_DelItemString=python36.PyDict_DelItemString + PyDict_GetItem=python36.PyDict_GetItem + PyDict_GetItemString=python36.PyDict_GetItemString + PyDict_GetItemWithError=python36.PyDict_GetItemWithError + PyDict_Items=python36.PyDict_Items + PyDict_Keys=python36.PyDict_Keys + PyDict_Merge=python36.PyDict_Merge + PyDict_MergeFromSeq2=python36.PyDict_MergeFromSeq2 + PyDict_New=python36.PyDict_New + PyDict_Next=python36.PyDict_Next + PyDict_SetItem=python36.PyDict_SetItem + PyDict_SetItemString=python36.PyDict_SetItemString + PyDict_Size=python36.PyDict_Size + PyDict_Type=python36.PyDict_Type DATA + PyDict_Update=python36.PyDict_Update + PyDict_Values=python36.PyDict_Values + PyEllipsis_Type=python36.PyEllipsis_Type DATA + PyEnum_Type=python36.PyEnum_Type DATA + PyErr_BadArgument=python36.PyErr_BadArgument + PyErr_BadInternalCall=python36.PyErr_BadInternalCall + PyErr_CheckSignals=python36.PyErr_CheckSignals + PyErr_Clear=python36.PyErr_Clear + PyErr_Display=python36.PyErr_Display + PyErr_ExceptionMatches=python36.PyErr_ExceptionMatches + PyErr_Fetch=python36.PyErr_Fetch + PyErr_Format=python36.PyErr_Format + PyErr_FormatV=python36.PyErr_FormatV + PyErr_GivenExceptionMatches=python36.PyErr_GivenExceptionMatches + PyErr_NewException=python36.PyErr_NewException + PyErr_NewExceptionWithDoc=python36.PyErr_NewExceptionWithDoc + PyErr_NoMemory=python36.PyErr_NoMemory + PyErr_NormalizeException=python36.PyErr_NormalizeException + PyErr_Occurred=python36.PyErr_Occurred + PyErr_Print=python36.PyErr_Print + PyErr_PrintEx=python36.PyErr_PrintEx + PyErr_ProgramText=python36.PyErr_ProgramText + PyErr_Restore=python36.PyErr_Restore + PyErr_SetFromErrno=python36.PyErr_SetFromErrno + PyErr_SetFromErrnoWithFilename=python36.PyErr_SetFromErrnoWithFilename + PyErr_SetFromErrnoWithFilenameObject=python36.PyErr_SetFromErrnoWithFilenameObject + PyErr_SetInterrupt=python36.PyErr_SetInterrupt + PyErr_SetNone=python36.PyErr_SetNone + PyErr_SetObject=python36.PyErr_SetObject + PyErr_SetString=python36.PyErr_SetString + PyErr_SyntaxLocation=python36.PyErr_SyntaxLocation + PyErr_WarnEx=python36.PyErr_WarnEx + PyErr_WarnExplicit=python36.PyErr_WarnExplicit + PyErr_WarnFormat=python36.PyErr_WarnFormat + PyErr_WriteUnraisable=python36.PyErr_WriteUnraisable + PyEval_AcquireLock=python36.PyEval_AcquireLock + PyEval_AcquireThread=python36.PyEval_AcquireThread + PyEval_CallFunction=python36.PyEval_CallFunction + PyEval_CallMethod=python36.PyEval_CallMethod + PyEval_CallObjectWithKeywords=python36.PyEval_CallObjectWithKeywords + PyEval_EvalCode=python36.PyEval_EvalCode + PyEval_EvalCodeEx=python36.PyEval_EvalCodeEx + PyEval_EvalFrame=python36.PyEval_EvalFrame + PyEval_EvalFrameEx=python36.PyEval_EvalFrameEx + PyEval_GetBuiltins=python36.PyEval_GetBuiltins + PyEval_GetCallStats=python36.PyEval_GetCallStats + PyEval_GetFrame=python36.PyEval_GetFrame + PyEval_GetFuncDesc=python36.PyEval_GetFuncDesc + PyEval_GetFuncName=python36.PyEval_GetFuncName + PyEval_GetGlobals=python36.PyEval_GetGlobals + PyEval_GetLocals=python36.PyEval_GetLocals + PyEval_InitThreads=python36.PyEval_InitThreads + PyEval_ReInitThreads=python36.PyEval_ReInitThreads + PyEval_ReleaseLock=python36.PyEval_ReleaseLock + PyEval_ReleaseThread=python36.PyEval_ReleaseThread + PyEval_RestoreThread=python36.PyEval_RestoreThread + PyEval_SaveThread=python36.PyEval_SaveThread + PyEval_ThreadsInitialized=python36.PyEval_ThreadsInitialized + PyExc_ArithmeticError=python36.PyExc_ArithmeticError DATA + PyExc_AssertionError=python36.PyExc_AssertionError DATA + PyExc_AttributeError=python36.PyExc_AttributeError DATA + PyExc_BaseException=python36.PyExc_BaseException DATA + PyExc_BufferError=python36.PyExc_BufferError DATA + PyExc_BytesWarning=python36.PyExc_BytesWarning DATA + PyExc_DeprecationWarning=python36.PyExc_DeprecationWarning DATA + PyExc_EOFError=python36.PyExc_EOFError DATA + PyExc_EnvironmentError=python36.PyExc_EnvironmentError DATA + PyExc_Exception=python36.PyExc_Exception DATA + PyExc_FloatingPointError=python36.PyExc_FloatingPointError DATA + PyExc_FutureWarning=python36.PyExc_FutureWarning DATA + PyExc_GeneratorExit=python36.PyExc_GeneratorExit DATA + PyExc_IOError=python36.PyExc_IOError DATA + PyExc_ImportError=python36.PyExc_ImportError DATA + PyExc_ImportWarning=python36.PyExc_ImportWarning DATA + PyExc_IndentationError=python36.PyExc_IndentationError DATA + PyExc_IndexError=python36.PyExc_IndexError DATA + PyExc_KeyError=python36.PyExc_KeyError DATA + PyExc_KeyboardInterrupt=python36.PyExc_KeyboardInterrupt DATA + PyExc_LookupError=python36.PyExc_LookupError DATA + PyExc_MemoryError=python36.PyExc_MemoryError DATA + PyExc_MemoryErrorInst=python36.PyExc_MemoryErrorInst DATA + PyExc_NameError=python36.PyExc_NameError DATA + PyExc_NotImplementedError=python36.PyExc_NotImplementedError DATA + PyExc_OSError=python36.PyExc_OSError DATA + PyExc_OverflowError=python36.PyExc_OverflowError DATA + PyExc_PendingDeprecationWarning=python36.PyExc_PendingDeprecationWarning DATA + PyExc_RecursionErrorInst=python36.PyExc_RecursionErrorInst DATA + PyExc_ReferenceError=python36.PyExc_ReferenceError DATA + PyExc_RuntimeError=python36.PyExc_RuntimeError DATA + PyExc_RuntimeWarning=python36.PyExc_RuntimeWarning DATA + PyExc_StopIteration=python36.PyExc_StopIteration DATA + PyExc_SyntaxError=python36.PyExc_SyntaxError DATA + PyExc_SyntaxWarning=python36.PyExc_SyntaxWarning DATA + PyExc_SystemError=python36.PyExc_SystemError DATA + PyExc_SystemExit=python36.PyExc_SystemExit DATA + PyExc_TabError=python36.PyExc_TabError DATA + PyExc_TypeError=python36.PyExc_TypeError DATA + PyExc_UnboundLocalError=python36.PyExc_UnboundLocalError DATA + PyExc_UnicodeDecodeError=python36.PyExc_UnicodeDecodeError DATA + PyExc_UnicodeEncodeError=python36.PyExc_UnicodeEncodeError DATA + PyExc_UnicodeError=python36.PyExc_UnicodeError DATA + PyExc_UnicodeTranslateError=python36.PyExc_UnicodeTranslateError DATA + PyExc_UnicodeWarning=python36.PyExc_UnicodeWarning DATA + PyExc_UserWarning=python36.PyExc_UserWarning DATA + PyExc_ValueError=python36.PyExc_ValueError DATA + PyExc_Warning=python36.PyExc_Warning DATA + PyExc_ZeroDivisionError=python36.PyExc_ZeroDivisionError DATA + PyException_GetCause=python36.PyException_GetCause + PyException_GetContext=python36.PyException_GetContext + PyException_GetTraceback=python36.PyException_GetTraceback + PyException_SetCause=python36.PyException_SetCause + PyException_SetContext=python36.PyException_SetContext + PyException_SetTraceback=python36.PyException_SetTraceback + PyFile_FromFd=python36.PyFile_FromFd + PyFile_GetLine=python36.PyFile_GetLine + PyFile_WriteObject=python36.PyFile_WriteObject + PyFile_WriteString=python36.PyFile_WriteString + PyFilter_Type=python36.PyFilter_Type DATA + PyFloat_AsDouble=python36.PyFloat_AsDouble + PyFloat_FromDouble=python36.PyFloat_FromDouble + PyFloat_FromString=python36.PyFloat_FromString + PyFloat_GetInfo=python36.PyFloat_GetInfo + PyFloat_GetMax=python36.PyFloat_GetMax + PyFloat_GetMin=python36.PyFloat_GetMin + PyFloat_Type=python36.PyFloat_Type DATA + PyFrozenSet_New=python36.PyFrozenSet_New + PyFrozenSet_Type=python36.PyFrozenSet_Type DATA + PyGC_Collect=python36.PyGC_Collect + PyGILState_Ensure=python36.PyGILState_Ensure + PyGILState_GetThisThreadState=python36.PyGILState_GetThisThreadState + PyGILState_Release=python36.PyGILState_Release + PyGetSetDescr_Type=python36.PyGetSetDescr_Type DATA + PyImport_AddModule=python36.PyImport_AddModule + PyImport_AppendInittab=python36.PyImport_AppendInittab + PyImport_Cleanup=python36.PyImport_Cleanup + PyImport_ExecCodeModule=python36.PyImport_ExecCodeModule + PyImport_ExecCodeModuleEx=python36.PyImport_ExecCodeModuleEx + PyImport_ExecCodeModuleWithPathnames=python36.PyImport_ExecCodeModuleWithPathnames + PyImport_GetImporter=python36.PyImport_GetImporter + PyImport_GetMagicNumber=python36.PyImport_GetMagicNumber + PyImport_GetMagicTag=python36.PyImport_GetMagicTag + PyImport_GetModuleDict=python36.PyImport_GetModuleDict + PyImport_Import=python36.PyImport_Import + PyImport_ImportFrozenModule=python36.PyImport_ImportFrozenModule + PyImport_ImportModule=python36.PyImport_ImportModule + PyImport_ImportModuleLevel=python36.PyImport_ImportModuleLevel + PyImport_ImportModuleNoBlock=python36.PyImport_ImportModuleNoBlock + PyImport_ReloadModule=python36.PyImport_ReloadModule + PyInterpreterState_Clear=python36.PyInterpreterState_Clear + PyInterpreterState_Delete=python36.PyInterpreterState_Delete + PyInterpreterState_New=python36.PyInterpreterState_New + PyIter_Next=python36.PyIter_Next + PyListIter_Type=python36.PyListIter_Type DATA + PyListRevIter_Type=python36.PyListRevIter_Type DATA + PyList_Append=python36.PyList_Append + PyList_AsTuple=python36.PyList_AsTuple + PyList_GetItem=python36.PyList_GetItem + PyList_GetSlice=python36.PyList_GetSlice + PyList_Insert=python36.PyList_Insert + PyList_New=python36.PyList_New + PyList_Reverse=python36.PyList_Reverse + PyList_SetItem=python36.PyList_SetItem + PyList_SetSlice=python36.PyList_SetSlice + PyList_Size=python36.PyList_Size + PyList_Sort=python36.PyList_Sort + PyList_Type=python36.PyList_Type DATA + PyLongRangeIter_Type=python36.PyLongRangeIter_Type DATA + PyLong_AsDouble=python36.PyLong_AsDouble + PyLong_AsLong=python36.PyLong_AsLong + PyLong_AsLongAndOverflow=python36.PyLong_AsLongAndOverflow + PyLong_AsLongLong=python36.PyLong_AsLongLong + PyLong_AsLongLongAndOverflow=python36.PyLong_AsLongLongAndOverflow + PyLong_AsSize_t=python36.PyLong_AsSize_t + PyLong_AsSsize_t=python36.PyLong_AsSsize_t + PyLong_AsUnsignedLong=python36.PyLong_AsUnsignedLong + PyLong_AsUnsignedLongLong=python36.PyLong_AsUnsignedLongLong + PyLong_AsUnsignedLongLongMask=python36.PyLong_AsUnsignedLongLongMask + PyLong_AsUnsignedLongMask=python36.PyLong_AsUnsignedLongMask + PyLong_AsVoidPtr=python36.PyLong_AsVoidPtr + PyLong_FromDouble=python36.PyLong_FromDouble + PyLong_FromLong=python36.PyLong_FromLong + PyLong_FromLongLong=python36.PyLong_FromLongLong + PyLong_FromSize_t=python36.PyLong_FromSize_t + PyLong_FromSsize_t=python36.PyLong_FromSsize_t + PyLong_FromString=python36.PyLong_FromString + PyLong_FromUnsignedLong=python36.PyLong_FromUnsignedLong + PyLong_FromUnsignedLongLong=python36.PyLong_FromUnsignedLongLong + PyLong_FromVoidPtr=python36.PyLong_FromVoidPtr + PyLong_GetInfo=python36.PyLong_GetInfo + PyLong_Type=python36.PyLong_Type DATA + PyMap_Type=python36.PyMap_Type DATA + PyMapping_Check=python36.PyMapping_Check + PyMapping_GetItemString=python36.PyMapping_GetItemString + PyMapping_HasKey=python36.PyMapping_HasKey + PyMapping_HasKeyString=python36.PyMapping_HasKeyString + PyMapping_Items=python36.PyMapping_Items + PyMapping_Keys=python36.PyMapping_Keys + PyMapping_Length=python36.PyMapping_Length + PyMapping_SetItemString=python36.PyMapping_SetItemString + PyMapping_Size=python36.PyMapping_Size + PyMapping_Values=python36.PyMapping_Values + PyMem_Free=python36.PyMem_Free + PyMem_Malloc=python36.PyMem_Malloc + PyMem_Realloc=python36.PyMem_Realloc + PyMemberDescr_Type=python36.PyMemberDescr_Type DATA + PyMemoryView_FromObject=python36.PyMemoryView_FromObject + PyMemoryView_GetContiguous=python36.PyMemoryView_GetContiguous + PyMemoryView_Type=python36.PyMemoryView_Type DATA + PyMethodDescr_Type=python36.PyMethodDescr_Type DATA + PyModule_AddIntConstant=python36.PyModule_AddIntConstant + PyModule_AddObject=python36.PyModule_AddObject + PyModule_AddStringConstant=python36.PyModule_AddStringConstant + PyModule_Create2=python36.PyModule_Create2 + PyModule_GetDef=python36.PyModule_GetDef + PyModule_GetDict=python36.PyModule_GetDict + PyModule_GetFilename=python36.PyModule_GetFilename + PyModule_GetFilenameObject=python36.PyModule_GetFilenameObject + PyModule_GetName=python36.PyModule_GetName + PyModule_GetState=python36.PyModule_GetState + PyModule_New=python36.PyModule_New + PyModule_Type=python36.PyModule_Type DATA + PyModuleDef_Init=python36.PyModuleDef_Init + PyModuleDef_Type=python36.PyModuleDef_Type DATA + PyNullImporter_Type=python36.PyNullImporter_Type DATA + PyNumber_Absolute=python36.PyNumber_Absolute + PyNumber_Add=python36.PyNumber_Add + PyNumber_And=python36.PyNumber_And + PyNumber_AsSsize_t=python36.PyNumber_AsSsize_t + PyNumber_Check=python36.PyNumber_Check + PyNumber_Divmod=python36.PyNumber_Divmod + PyNumber_Float=python36.PyNumber_Float + PyNumber_FloorDivide=python36.PyNumber_FloorDivide + PyNumber_InPlaceAdd=python36.PyNumber_InPlaceAdd + PyNumber_InPlaceAnd=python36.PyNumber_InPlaceAnd + PyNumber_InPlaceFloorDivide=python36.PyNumber_InPlaceFloorDivide + PyNumber_InPlaceLshift=python36.PyNumber_InPlaceLshift + PyNumber_InPlaceMultiply=python36.PyNumber_InPlaceMultiply + PyNumber_InPlaceOr=python36.PyNumber_InPlaceOr + PyNumber_InPlacePower=python36.PyNumber_InPlacePower + PyNumber_InPlaceRemainder=python36.PyNumber_InPlaceRemainder + PyNumber_InPlaceRshift=python36.PyNumber_InPlaceRshift + PyNumber_InPlaceSubtract=python36.PyNumber_InPlaceSubtract + PyNumber_InPlaceTrueDivide=python36.PyNumber_InPlaceTrueDivide + PyNumber_InPlaceXor=python36.PyNumber_InPlaceXor + PyNumber_Index=python36.PyNumber_Index + PyNumber_Invert=python36.PyNumber_Invert + PyNumber_Long=python36.PyNumber_Long + PyNumber_Lshift=python36.PyNumber_Lshift + PyNumber_Multiply=python36.PyNumber_Multiply + PyNumber_Negative=python36.PyNumber_Negative + PyNumber_Or=python36.PyNumber_Or + PyNumber_Positive=python36.PyNumber_Positive + PyNumber_Power=python36.PyNumber_Power + PyNumber_Remainder=python36.PyNumber_Remainder + PyNumber_Rshift=python36.PyNumber_Rshift + PyNumber_Subtract=python36.PyNumber_Subtract + PyNumber_ToBase=python36.PyNumber_ToBase + PyNumber_TrueDivide=python36.PyNumber_TrueDivide + PyNumber_Xor=python36.PyNumber_Xor + PyOS_AfterFork=python36.PyOS_AfterFork + PyOS_InitInterrupts=python36.PyOS_InitInterrupts + PyOS_InputHook=python36.PyOS_InputHook DATA + PyOS_InterruptOccurred=python36.PyOS_InterruptOccurred + PyOS_ReadlineFunctionPointer=python36.PyOS_ReadlineFunctionPointer DATA + PyOS_double_to_string=python36.PyOS_double_to_string + PyOS_getsig=python36.PyOS_getsig + PyOS_mystricmp=python36.PyOS_mystricmp + PyOS_mystrnicmp=python36.PyOS_mystrnicmp + PyOS_setsig=python36.PyOS_setsig + PyOS_snprintf=python36.PyOS_snprintf + PyOS_string_to_double=python36.PyOS_string_to_double + PyOS_strtol=python36.PyOS_strtol + PyOS_strtoul=python36.PyOS_strtoul + PyOS_vsnprintf=python36.PyOS_vsnprintf + PyObject_ASCII=python36.PyObject_ASCII + PyObject_AsCharBuffer=python36.PyObject_AsCharBuffer + PyObject_AsFileDescriptor=python36.PyObject_AsFileDescriptor + PyObject_AsReadBuffer=python36.PyObject_AsReadBuffer + PyObject_AsWriteBuffer=python36.PyObject_AsWriteBuffer + PyObject_Bytes=python36.PyObject_Bytes + PyObject_Call=python36.PyObject_Call + PyObject_CallFunction=python36.PyObject_CallFunction + PyObject_CallFunctionObjArgs=python36.PyObject_CallFunctionObjArgs + PyObject_CallMethod=python36.PyObject_CallMethod + PyObject_CallMethodObjArgs=python36.PyObject_CallMethodObjArgs + PyObject_CallObject=python36.PyObject_CallObject + PyObject_CheckReadBuffer=python36.PyObject_CheckReadBuffer + PyObject_ClearWeakRefs=python36.PyObject_ClearWeakRefs + PyObject_DelItem=python36.PyObject_DelItem + PyObject_DelItemString=python36.PyObject_DelItemString + PyObject_Dir=python36.PyObject_Dir + PyObject_Format=python36.PyObject_Format + PyObject_Free=python36.PyObject_Free + PyObject_GC_Del=python36.PyObject_GC_Del + PyObject_GC_Track=python36.PyObject_GC_Track + PyObject_GC_UnTrack=python36.PyObject_GC_UnTrack + PyObject_GenericGetAttr=python36.PyObject_GenericGetAttr + PyObject_GenericSetAttr=python36.PyObject_GenericSetAttr + PyObject_GetAttr=python36.PyObject_GetAttr + PyObject_GetAttrString=python36.PyObject_GetAttrString + PyObject_GetItem=python36.PyObject_GetItem + PyObject_GetIter=python36.PyObject_GetIter + PyObject_HasAttr=python36.PyObject_HasAttr + PyObject_HasAttrString=python36.PyObject_HasAttrString + PyObject_Hash=python36.PyObject_Hash + PyObject_HashNotImplemented=python36.PyObject_HashNotImplemented + PyObject_Init=python36.PyObject_Init + PyObject_InitVar=python36.PyObject_InitVar + PyObject_IsInstance=python36.PyObject_IsInstance + PyObject_IsSubclass=python36.PyObject_IsSubclass + PyObject_IsTrue=python36.PyObject_IsTrue + PyObject_Length=python36.PyObject_Length + PyObject_Malloc=python36.PyObject_Malloc + PyObject_Not=python36.PyObject_Not + PyObject_Realloc=python36.PyObject_Realloc + PyObject_Repr=python36.PyObject_Repr + PyObject_RichCompare=python36.PyObject_RichCompare + PyObject_RichCompareBool=python36.PyObject_RichCompareBool + PyObject_SelfIter=python36.PyObject_SelfIter + PyObject_SetAttr=python36.PyObject_SetAttr + PyObject_SetAttrString=python36.PyObject_SetAttrString + PyObject_SetItem=python36.PyObject_SetItem + PyObject_Size=python36.PyObject_Size + PyObject_Str=python36.PyObject_Str + PyObject_Type=python36.PyObject_Type DATA + PyODict_DelItem=python36.PyODict_DelItem + PyODict_New=python36.PyODict_New + PyODict_SetItem=python36.PyODict_SetItem + PyODict_Type=python36.PyODict_Type DATA + PyODictItems_Type=python36.PyODictItems_Type DATA + PyODictIter_Type=python36.PyODictIter_Type DATA + PyODictKeys_Type=python36.PyODictKeys_Type DATA + PyODictValues_Type=python36.PyODictValues_Type DATA + PyParser_SimpleParseFileFlags=python36.PyParser_SimpleParseFileFlags + PyParser_SimpleParseStringFlags=python36.PyParser_SimpleParseStringFlags + PyProperty_Type=python36.PyProperty_Type DATA + PyRangeIter_Type=python36.PyRangeIter_Type DATA + PyRange_Type=python36.PyRange_Type DATA + PyReversed_Type=python36.PyReversed_Type DATA + PySeqIter_New=python36.PySeqIter_New + PySeqIter_Type=python36.PySeqIter_Type DATA + PySequence_Check=python36.PySequence_Check + PySequence_Concat=python36.PySequence_Concat + PySequence_Contains=python36.PySequence_Contains + PySequence_Count=python36.PySequence_Count + PySequence_DelItem=python36.PySequence_DelItem + PySequence_DelSlice=python36.PySequence_DelSlice + PySequence_Fast=python36.PySequence_Fast + PySequence_GetItem=python36.PySequence_GetItem + PySequence_GetSlice=python36.PySequence_GetSlice + PySequence_In=python36.PySequence_In + PySequence_InPlaceConcat=python36.PySequence_InPlaceConcat + PySequence_InPlaceRepeat=python36.PySequence_InPlaceRepeat + PySequence_Index=python36.PySequence_Index + PySequence_Length=python36.PySequence_Length + PySequence_List=python36.PySequence_List + PySequence_Repeat=python36.PySequence_Repeat + PySequence_SetItem=python36.PySequence_SetItem + PySequence_SetSlice=python36.PySequence_SetSlice + PySequence_Size=python36.PySequence_Size + PySequence_Tuple=python36.PySequence_Tuple + PySetIter_Type=python36.PySetIter_Type DATA + PySet_Add=python36.PySet_Add + PySet_Clear=python36.PySet_Clear + PySet_Contains=python36.PySet_Contains + PySet_Discard=python36.PySet_Discard + PySet_New=python36.PySet_New + PySet_Pop=python36.PySet_Pop + PySet_Size=python36.PySet_Size + PySet_Type=python36.PySet_Type DATA + PySlice_GetIndices=python36.PySlice_GetIndices + PySlice_GetIndicesEx=python36.PySlice_GetIndicesEx + PySlice_New=python36.PySlice_New + PySlice_Type=python36.PySlice_Type DATA + PySortWrapper_Type=python36.PySortWrapper_Type DATA + PyState_FindModule=python36.PyState_FindModule + PyState_AddModule=python36.PyState_AddModule + PyState_RemoveModule=python36.PyState_RemoveModule + PyStructSequence_GetItem=python36.PyStructSequence_GetItem + PyStructSequence_New=python36.PyStructSequence_New + PyStructSequence_NewType=python36.PyStructSequence_NewType + PyStructSequence_SetItem=python36.PyStructSequence_SetItem + PySuper_Type=python36.PySuper_Type DATA + PySys_AddWarnOption=python36.PySys_AddWarnOption + PySys_AddWarnOptionUnicode=python36.PySys_AddWarnOptionUnicode + PySys_FormatStderr=python36.PySys_FormatStderr + PySys_FormatStdout=python36.PySys_FormatStdout + PySys_GetObject=python36.PySys_GetObject + PySys_HasWarnOptions=python36.PySys_HasWarnOptions + PySys_ResetWarnOptions=python36.PySys_ResetWarnOptions + PySys_SetArgv=python36.PySys_SetArgv + PySys_SetArgvEx=python36.PySys_SetArgvEx + PySys_SetObject=python36.PySys_SetObject + PySys_SetPath=python36.PySys_SetPath + PySys_WriteStderr=python36.PySys_WriteStderr + PySys_WriteStdout=python36.PySys_WriteStdout + PyThreadState_Clear=python36.PyThreadState_Clear + PyThreadState_Delete=python36.PyThreadState_Delete + PyThreadState_DeleteCurrent=python36.PyThreadState_DeleteCurrent + PyThreadState_Get=python36.PyThreadState_Get + PyThreadState_GetDict=python36.PyThreadState_GetDict + PyThreadState_New=python36.PyThreadState_New + PyThreadState_SetAsyncExc=python36.PyThreadState_SetAsyncExc + PyThreadState_Swap=python36.PyThreadState_Swap + PyTraceBack_Here=python36.PyTraceBack_Here + PyTraceBack_Print=python36.PyTraceBack_Print + PyTraceBack_Type=python36.PyTraceBack_Type DATA + PyTupleIter_Type=python36.PyTupleIter_Type DATA + PyTuple_ClearFreeList=python36.PyTuple_ClearFreeList + PyTuple_GetItem=python36.PyTuple_GetItem + PyTuple_GetSlice=python36.PyTuple_GetSlice + PyTuple_New=python36.PyTuple_New + PyTuple_Pack=python36.PyTuple_Pack + PyTuple_SetItem=python36.PyTuple_SetItem + PyTuple_Size=python36.PyTuple_Size + PyTuple_Type=python36.PyTuple_Type DATA + PyType_ClearCache=python36.PyType_ClearCache + PyType_FromSpec=python36.PyType_FromSpec + PyType_FromSpecWithBases=python36.PyType_FromSpecWithBases + PyType_GenericAlloc=python36.PyType_GenericAlloc + PyType_GenericNew=python36.PyType_GenericNew + PyType_GetFlags=python36.PyType_GetFlags + PyType_GetSlot=python36.PyType_GetSlot + PyType_IsSubtype=python36.PyType_IsSubtype + PyType_Modified=python36.PyType_Modified + PyType_Ready=python36.PyType_Ready + PyType_Type=python36.PyType_Type DATA + PyUnicodeDecodeError_Create=python36.PyUnicodeDecodeError_Create + PyUnicodeDecodeError_GetEncoding=python36.PyUnicodeDecodeError_GetEncoding + PyUnicodeDecodeError_GetEnd=python36.PyUnicodeDecodeError_GetEnd + PyUnicodeDecodeError_GetObject=python36.PyUnicodeDecodeError_GetObject + PyUnicodeDecodeError_GetReason=python36.PyUnicodeDecodeError_GetReason + PyUnicodeDecodeError_GetStart=python36.PyUnicodeDecodeError_GetStart + PyUnicodeDecodeError_SetEnd=python36.PyUnicodeDecodeError_SetEnd + PyUnicodeDecodeError_SetReason=python36.PyUnicodeDecodeError_SetReason + PyUnicodeDecodeError_SetStart=python36.PyUnicodeDecodeError_SetStart + PyUnicodeEncodeError_GetEncoding=python36.PyUnicodeEncodeError_GetEncoding + PyUnicodeEncodeError_GetEnd=python36.PyUnicodeEncodeError_GetEnd + PyUnicodeEncodeError_GetObject=python36.PyUnicodeEncodeError_GetObject + PyUnicodeEncodeError_GetReason=python36.PyUnicodeEncodeError_GetReason + PyUnicodeEncodeError_GetStart=python36.PyUnicodeEncodeError_GetStart + PyUnicodeEncodeError_SetEnd=python36.PyUnicodeEncodeError_SetEnd + PyUnicodeEncodeError_SetReason=python36.PyUnicodeEncodeError_SetReason + PyUnicodeEncodeError_SetStart=python36.PyUnicodeEncodeError_SetStart + PyUnicodeIter_Type=python36.PyUnicodeIter_Type DATA + PyUnicodeTranslateError_GetEnd=python36.PyUnicodeTranslateError_GetEnd + PyUnicodeTranslateError_GetObject=python36.PyUnicodeTranslateError_GetObject + PyUnicodeTranslateError_GetReason=python36.PyUnicodeTranslateError_GetReason + PyUnicodeTranslateError_GetStart=python36.PyUnicodeTranslateError_GetStart + PyUnicodeTranslateError_SetEnd=python36.PyUnicodeTranslateError_SetEnd + PyUnicodeTranslateError_SetReason=python36.PyUnicodeTranslateError_SetReason + PyUnicodeTranslateError_SetStart=python36.PyUnicodeTranslateError_SetStart + PyUnicode_Append=python36.PyUnicode_Append + PyUnicode_AppendAndDel=python36.PyUnicode_AppendAndDel + PyUnicode_AsASCIIString=python36.PyUnicode_AsASCIIString + PyUnicode_AsCharmapString=python36.PyUnicode_AsCharmapString + PyUnicode_AsDecodedObject=python36.PyUnicode_AsDecodedObject + PyUnicode_AsDecodedUnicode=python36.PyUnicode_AsDecodedUnicode + PyUnicode_AsEncodedObject=python36.PyUnicode_AsEncodedObject + PyUnicode_AsEncodedString=python36.PyUnicode_AsEncodedString + PyUnicode_AsEncodedUnicode=python36.PyUnicode_AsEncodedUnicode + PyUnicode_AsLatin1String=python36.PyUnicode_AsLatin1String + PyUnicode_AsRawUnicodeEscapeString=python36.PyUnicode_AsRawUnicodeEscapeString + PyUnicode_AsUTF16String=python36.PyUnicode_AsUTF16String + PyUnicode_AsUTF32String=python36.PyUnicode_AsUTF32String + PyUnicode_AsUTF8String=python36.PyUnicode_AsUTF8String + PyUnicode_AsUnicodeEscapeString=python36.PyUnicode_AsUnicodeEscapeString + PyUnicode_AsWideChar=python36.PyUnicode_AsWideChar + PyUnicode_ClearFreelist=python36.PyUnicode_ClearFreelist + PyUnicode_Compare=python36.PyUnicode_Compare + PyUnicode_Concat=python36.PyUnicode_Concat + PyUnicode_Contains=python36.PyUnicode_Contains + PyUnicode_Count=python36.PyUnicode_Count + PyUnicode_Decode=python36.PyUnicode_Decode + PyUnicode_DecodeASCII=python36.PyUnicode_DecodeASCII + PyUnicode_DecodeCharmap=python36.PyUnicode_DecodeCharmap + PyUnicode_DecodeFSDefault=python36.PyUnicode_DecodeFSDefault + PyUnicode_DecodeFSDefaultAndSize=python36.PyUnicode_DecodeFSDefaultAndSize + PyUnicode_DecodeLatin1=python36.PyUnicode_DecodeLatin1 + PyUnicode_DecodeRawUnicodeEscape=python36.PyUnicode_DecodeRawUnicodeEscape + PyUnicode_DecodeUTF16=python36.PyUnicode_DecodeUTF16 + PyUnicode_DecodeUTF16Stateful=python36.PyUnicode_DecodeUTF16Stateful + PyUnicode_DecodeUTF32=python36.PyUnicode_DecodeUTF32 + PyUnicode_DecodeUTF32Stateful=python36.PyUnicode_DecodeUTF32Stateful + PyUnicode_DecodeUTF8=python36.PyUnicode_DecodeUTF8 + PyUnicode_DecodeUTF8Stateful=python36.PyUnicode_DecodeUTF8Stateful + PyUnicode_DecodeUnicodeEscape=python36.PyUnicode_DecodeUnicodeEscape + PyUnicode_FSConverter=python36.PyUnicode_FSConverter + PyUnicode_FSDecoder=python36.PyUnicode_FSDecoder + PyUnicode_Find=python36.PyUnicode_Find + PyUnicode_Format=python36.PyUnicode_Format + PyUnicode_FromEncodedObject=python36.PyUnicode_FromEncodedObject + PyUnicode_FromFormat=python36.PyUnicode_FromFormat + PyUnicode_FromFormatV=python36.PyUnicode_FromFormatV + PyUnicode_FromObject=python36.PyUnicode_FromObject + PyUnicode_FromOrdinal=python36.PyUnicode_FromOrdinal + PyUnicode_FromString=python36.PyUnicode_FromString + PyUnicode_FromStringAndSize=python36.PyUnicode_FromStringAndSize + PyUnicode_FromWideChar=python36.PyUnicode_FromWideChar + PyUnicode_GetDefaultEncoding=python36.PyUnicode_GetDefaultEncoding + PyUnicode_GetSize=python36.PyUnicode_GetSize + PyUnicode_IsIdentifier=python36.PyUnicode_IsIdentifier + PyUnicode_Join=python36.PyUnicode_Join + PyUnicode_Partition=python36.PyUnicode_Partition + PyUnicode_RPartition=python36.PyUnicode_RPartition + PyUnicode_RSplit=python36.PyUnicode_RSplit + PyUnicode_Replace=python36.PyUnicode_Replace + PyUnicode_Resize=python36.PyUnicode_Resize + PyUnicode_RichCompare=python36.PyUnicode_RichCompare + PyUnicode_SetDefaultEncoding=python36.PyUnicode_SetDefaultEncoding + PyUnicode_Split=python36.PyUnicode_Split + PyUnicode_Splitlines=python36.PyUnicode_Splitlines + PyUnicode_Tailmatch=python36.PyUnicode_Tailmatch + PyUnicode_Translate=python36.PyUnicode_Translate + PyUnicode_BuildEncodingMap=python36.PyUnicode_BuildEncodingMap + PyUnicode_CompareWithASCIIString=python36.PyUnicode_CompareWithASCIIString + PyUnicode_DecodeUTF7=python36.PyUnicode_DecodeUTF7 + PyUnicode_DecodeUTF7Stateful=python36.PyUnicode_DecodeUTF7Stateful + PyUnicode_EncodeFSDefault=python36.PyUnicode_EncodeFSDefault + PyUnicode_InternFromString=python36.PyUnicode_InternFromString + PyUnicode_InternImmortal=python36.PyUnicode_InternImmortal + PyUnicode_InternInPlace=python36.PyUnicode_InternInPlace + PyUnicode_Type=python36.PyUnicode_Type DATA + PyWeakref_GetObject=python36.PyWeakref_GetObject DATA + PyWeakref_NewProxy=python36.PyWeakref_NewProxy + PyWeakref_NewRef=python36.PyWeakref_NewRef + PyWrapperDescr_Type=python36.PyWrapperDescr_Type DATA + PyWrapper_New=python36.PyWrapper_New + PyZip_Type=python36.PyZip_Type DATA + Py_AddPendingCall=python36.Py_AddPendingCall + Py_AtExit=python36.Py_AtExit + Py_BuildValue=python36.Py_BuildValue + Py_CompileString=python36.Py_CompileString + Py_DecRef=python36.Py_DecRef + Py_EndInterpreter=python36.Py_EndInterpreter + Py_Exit=python36.Py_Exit + Py_FatalError=python36.Py_FatalError + Py_FileSystemDefaultEncoding=python36.Py_FileSystemDefaultEncoding DATA + Py_Finalize=python36.Py_Finalize + Py_GetBuildInfo=python36.Py_GetBuildInfo + Py_GetCompiler=python36.Py_GetCompiler + Py_GetCopyright=python36.Py_GetCopyright + Py_GetExecPrefix=python36.Py_GetExecPrefix + Py_GetPath=python36.Py_GetPath + Py_GetPlatform=python36.Py_GetPlatform + Py_GetPrefix=python36.Py_GetPrefix + Py_GetProgramFullPath=python36.Py_GetProgramFullPath + Py_GetProgramName=python36.Py_GetProgramName + Py_GetPythonHome=python36.Py_GetPythonHome + Py_GetRecursionLimit=python36.Py_GetRecursionLimit + Py_GetVersion=python36.Py_GetVersion + Py_HasFileSystemDefaultEncoding=python36.Py_HasFileSystemDefaultEncoding DATA + Py_IncRef=python36.Py_IncRef + Py_Initialize=python36.Py_Initialize + Py_InitializeEx=python36.Py_InitializeEx + Py_IsInitialized=python36.Py_IsInitialized + Py_Main=python36.Py_Main + Py_MakePendingCalls=python36.Py_MakePendingCalls + Py_NewInterpreter=python36.Py_NewInterpreter + Py_ReprEnter=python36.Py_ReprEnter + Py_ReprLeave=python36.Py_ReprLeave + Py_SetProgramName=python36.Py_SetProgramName + Py_SetPythonHome=python36.Py_SetPythonHome + Py_SetRecursionLimit=python36.Py_SetRecursionLimit + Py_SymtableString=python36.Py_SymtableString + Py_VaBuildValue=python36.Py_VaBuildValue + _PyErr_BadInternalCall=python36._PyErr_BadInternalCall + _PyObject_CallFunction_SizeT=python36._PyObject_CallFunction_SizeT + _PyObject_CallMethod_SizeT=python36._PyObject_CallMethod_SizeT + _PyObject_GC_Malloc=python36._PyObject_GC_Malloc + _PyObject_GC_New=python36._PyObject_GC_New + _PyObject_GC_NewVar=python36._PyObject_GC_NewVar + _PyObject_GC_Resize=python36._PyObject_GC_Resize + _PyObject_New=python36._PyObject_New + _PyObject_NewVar=python36._PyObject_NewVar + _PyState_AddModule=python36._PyState_AddModule + _PyThreadState_Init=python36._PyThreadState_Init + _PyThreadState_Prealloc=python36._PyThreadState_Prealloc + _PyTrash_delete_later=python36._PyTrash_delete_later DATA + _PyTrash_delete_nesting=python36._PyTrash_delete_nesting DATA + _PyTrash_deposit_object=python36._PyTrash_deposit_object + _PyTrash_destroy_chain=python36._PyTrash_destroy_chain + _PyWeakref_CallableProxyType=python36._PyWeakref_CallableProxyType DATA + _PyWeakref_ProxyType=python36._PyWeakref_ProxyType DATA + _PyWeakref_RefType=python36._PyWeakref_RefType DATA + _Py_BuildValue_SizeT=python36._Py_BuildValue_SizeT + _Py_CheckRecursionLimit=python36._Py_CheckRecursionLimit DATA + _Py_CheckRecursiveCall=python36._Py_CheckRecursiveCall + _Py_Dealloc=python36._Py_Dealloc + _Py_EllipsisObject=python36._Py_EllipsisObject DATA + _Py_FalseStruct=python36._Py_FalseStruct DATA + _Py_NoneStruct=python36._Py_NoneStruct DATA + _Py_NotImplementedStruct=python36._Py_NotImplementedStruct DATA + _Py_SwappedOp=python36._Py_SwappedOp DATA + _Py_TrueStruct=python36._Py_TrueStruct DATA + _Py_VaBuildValue_SizeT=python36._Py_VaBuildValue_SizeT + _PyArg_Parse_SizeT=python36._PyArg_Parse_SizeT + _PyArg_ParseTuple_SizeT=python36._PyArg_ParseTuple_SizeT + _PyArg_ParseTupleAndKeywords_SizeT=python36._PyArg_ParseTupleAndKeywords_SizeT + _PyArg_VaParse_SizeT=python36._PyArg_VaParse_SizeT + _PyArg_VaParseTupleAndKeywords_SizeT=python36._PyArg_VaParseTupleAndKeywords_SizeT + _Py_BuildValue_SizeT=python36._Py_BuildValue_SizeT diff --git a/PC/python3.mak b/PC/python3.mak deleted file mode 100644 index fb8e7aac0977..000000000000 --- a/PC/python3.mak +++ /dev/null @@ -1,14 +0,0 @@ -$(OutDir)python3.dll: python3.def $(OutDir)python34stub.lib - cl /LD /Fe$(OutDir)python3.dll python3dll.c python3.def $(OutDir)python34stub.lib - -$(OutDir)python34stub.lib: python34stub.def - lib /def:python34stub.def /out:$(OutDir)python34stub.lib /MACHINE:$(MACHINE) - -clean: - IF EXIST $(OutDir)python3.dll del $(OutDir)python3.dll - IF EXIST $(OutDir)python3.lib del $(OutDir)python3.lib - IF EXIST $(OutDir)python34stub.lib del $(OutDir)python34stub.lib - IF EXIST $(OutDir)python3.exp del $(OutDir)python3.exp - IF EXIST $(OutDir)python34stub.exp del $(OutDir)python34stub.exp - -rebuild: clean $(OutDir)python3.dll diff --git a/PC/python34gen.py b/PC/python34gen.py deleted file mode 100644 index 180ce11fd28b..000000000000 --- a/PC/python34gen.py +++ /dev/null @@ -1,26 +0,0 @@ -# Generate python34stub.def out of python3.def -# The regular import library cannot be used, -# since it doesn't provide the right symbols for -# data forwarding -out = open("python34stub.def", "w") -out.write('LIBRARY "python34"\n') -out.write('EXPORTS\n') - -inp = open("python3.def") -line = inp.readline() -while line.strip().startswith(';'): - line = inp.readline() -line = inp.readline() # LIBRARY -assert line.strip()=='EXPORTS' - -for line in inp: - # SYM1=python34.SYM2[ DATA] - head, tail = line.split('.') - if 'DATA' in tail: - symbol, tail = tail.split(' ') - else: - symbol = tail.strip() - out.write(symbol+'\n') - -inp.close() -out.close() diff --git a/PC/python34stub.def b/PC/python34stub.def deleted file mode 100644 index c0f3b35fe9b0..000000000000 --- a/PC/python34stub.def +++ /dev/null @@ -1,699 +0,0 @@ -LIBRARY "python34" -EXPORTS -PyArg_Parse -PyArg_ParseTuple -PyArg_ParseTupleAndKeywords -PyArg_UnpackTuple -PyArg_VaParse -PyArg_VaParseTupleAndKeywords -PyArg_ValidateKeywordArguments -PyBaseObject_Type -PyBool_FromLong -PyBool_Type -PyByteArrayIter_Type -PyByteArray_AsString -PyByteArray_Concat -PyByteArray_FromObject -PyByteArray_FromStringAndSize -PyByteArray_Resize -PyByteArray_Size -PyByteArray_Type -PyBytesIter_Type -PyBytes_AsString -PyBytes_AsStringAndSize -PyBytes_Concat -PyBytes_ConcatAndDel -PyBytes_DecodeEscape -PyBytes_FromFormat -PyBytes_FromFormatV -PyBytes_FromObject -PyBytes_FromString -PyBytes_FromStringAndSize -PyBytes_Repr -PyBytes_Size -PyBytes_Type -PyCFunction_Call -PyCFunction_ClearFreeList -PyCFunction_GetFlags -PyCFunction_GetFunction -PyCFunction_GetSelf -PyCFunction_New -PyCFunction_NewEx -PyCFunction_Type -PyCallIter_New -PyCallIter_Type -PyCallable_Check -PyCapsule_GetContext -PyCapsule_GetDestructor -PyCapsule_GetName -PyCapsule_GetPointer -PyCapsule_Import -PyCapsule_IsValid -PyCapsule_New -PyCapsule_SetContext -PyCapsule_SetDestructor -PyCapsule_SetName -PyCapsule_SetPointer -PyCapsule_Type -PyClassMethodDescr_Type -PyCodec_BackslashReplaceErrors -PyCodec_Decode -PyCodec_Decoder -PyCodec_Encode -PyCodec_Encoder -PyCodec_IgnoreErrors -PyCodec_IncrementalDecoder -PyCodec_IncrementalEncoder -PyCodec_KnownEncoding -PyCodec_LookupError -PyCodec_Register -PyCodec_RegisterError -PyCodec_ReplaceErrors -PyCodec_StreamReader -PyCodec_StreamWriter -PyCodec_StrictErrors -PyCodec_XMLCharRefReplaceErrors -PyComplex_FromDoubles -PyComplex_ImagAsDouble -PyComplex_RealAsDouble -PyComplex_Type -PyDescr_NewClassMethod -PyDescr_NewGetSet -PyDescr_NewMember -PyDescr_NewMethod -PyDictItems_Type -PyDictIterItem_Type -PyDictIterKey_Type -PyDictIterValue_Type -PyDictKeys_Type -PyDictProxy_New -PyDictProxy_Type -PyDictValues_Type -PyDict_Clear -PyDict_Contains -PyDict_Copy -PyDict_DelItem -PyDict_DelItemString -PyDict_GetItem -PyDict_GetItemString -PyDict_GetItemWithError -PyDict_Items -PyDict_Keys -PyDict_Merge -PyDict_MergeFromSeq2 -PyDict_New -PyDict_Next -PyDict_SetItem -PyDict_SetItemString -PyDict_Size -PyDict_Type -PyDict_Update -PyDict_Values -PyEllipsis_Type -PyEnum_Type -PyErr_BadArgument -PyErr_BadInternalCall -PyErr_CheckSignals -PyErr_Clear -PyErr_Display -PyErr_ExceptionMatches -PyErr_Fetch -PyErr_Format -PyErr_GivenExceptionMatches -PyErr_NewException -PyErr_NewExceptionWithDoc -PyErr_NoMemory -PyErr_NormalizeException -PyErr_Occurred -PyErr_Print -PyErr_PrintEx -PyErr_ProgramText -PyErr_Restore -PyErr_SetFromErrno -PyErr_SetFromErrnoWithFilename -PyErr_SetFromErrnoWithFilenameObject -PyErr_SetInterrupt -PyErr_SetNone -PyErr_SetObject -PyErr_SetString -PyErr_SyntaxLocation -PyErr_WarnEx -PyErr_WarnExplicit -PyErr_WarnFormat -PyErr_WriteUnraisable -PyEval_AcquireLock -PyEval_AcquireThread -PyEval_CallFunction -PyEval_CallMethod -PyEval_CallObjectWithKeywords -PyEval_EvalCode -PyEval_EvalCodeEx -PyEval_EvalFrame -PyEval_EvalFrameEx -PyEval_GetBuiltins -PyEval_GetCallStats -PyEval_GetFrame -PyEval_GetFuncDesc -PyEval_GetFuncName -PyEval_GetGlobals -PyEval_GetLocals -PyEval_InitThreads -PyEval_ReInitThreads -PyEval_ReleaseLock -PyEval_ReleaseThread -PyEval_RestoreThread -PyEval_SaveThread -PyEval_ThreadsInitialized -PyExc_ArithmeticError -PyExc_AssertionError -PyExc_AttributeError -PyExc_BaseException -PyExc_BufferError -PyExc_BytesWarning -PyExc_DeprecationWarning -PyExc_EOFError -PyExc_EnvironmentError -PyExc_Exception -PyExc_FloatingPointError -PyExc_FutureWarning -PyExc_GeneratorExit -PyExc_IOError -PyExc_ImportError -PyExc_ImportWarning -PyExc_IndentationError -PyExc_IndexError -PyExc_KeyError -PyExc_KeyboardInterrupt -PyExc_LookupError -PyExc_MemoryError -PyExc_MemoryErrorInst -PyExc_NameError -PyExc_NotImplementedError -PyExc_OSError -PyExc_OverflowError -PyExc_PendingDeprecationWarning -PyExc_RecursionErrorInst -PyExc_ReferenceError -PyExc_RuntimeError -PyExc_RuntimeWarning -PyExc_StopIteration -PyExc_SyntaxError -PyExc_SyntaxWarning -PyExc_SystemError -PyExc_SystemExit -PyExc_TabError -PyExc_TypeError -PyExc_UnboundLocalError -PyExc_UnicodeDecodeError -PyExc_UnicodeEncodeError -PyExc_UnicodeError -PyExc_UnicodeTranslateError -PyExc_UnicodeWarning -PyExc_UserWarning -PyExc_ValueError -PyExc_Warning -PyExc_ZeroDivisionError -PyException_GetCause -PyException_GetContext -PyException_GetTraceback -PyException_SetCause -PyException_SetContext -PyException_SetTraceback -PyFile_FromFd -PyFile_GetLine -PyFile_WriteObject -PyFile_WriteString -PyFilter_Type -PyFloat_AsDouble -PyFloat_FromDouble -PyFloat_FromString -PyFloat_GetInfo -PyFloat_GetMax -PyFloat_GetMin -PyFloat_Type -PyFrozenSet_New -PyFrozenSet_Type -PyGC_Collect -PyGILState_Ensure -PyGILState_GetThisThreadState -PyGILState_Release -PyGetSetDescr_Type -PyImport_AddModule -PyImport_AppendInittab -PyImport_Cleanup -PyImport_ExecCodeModule -PyImport_ExecCodeModuleEx -PyImport_ExecCodeModuleWithPathnames -PyImport_GetImporter -PyImport_GetMagicNumber -PyImport_GetMagicTag -PyImport_GetModuleDict -PyImport_Import -PyImport_ImportFrozenModule -PyImport_ImportModule -PyImport_ImportModuleLevel -PyImport_ImportModuleNoBlock -PyImport_ReloadModule -PyInterpreterState_Clear -PyInterpreterState_Delete -PyInterpreterState_New -PyIter_Next -PyListIter_Type -PyListRevIter_Type -PyList_Append -PyList_AsTuple -PyList_GetItem -PyList_GetSlice -PyList_Insert -PyList_New -PyList_Reverse -PyList_SetItem -PyList_SetSlice -PyList_Size -PyList_Sort -PyList_Type -PyLongRangeIter_Type -PyLong_AsDouble -PyLong_AsLong -PyLong_AsLongAndOverflow -PyLong_AsLongLong -PyLong_AsLongLongAndOverflow -PyLong_AsSize_t -PyLong_AsSsize_t -PyLong_AsUnsignedLong -PyLong_AsUnsignedLongLong -PyLong_AsUnsignedLongLongMask -PyLong_AsUnsignedLongMask -PyLong_AsVoidPtr -PyLong_FromDouble -PyLong_FromLong -PyLong_FromLongLong -PyLong_FromSize_t -PyLong_FromSsize_t -PyLong_FromString -PyLong_FromUnsignedLong -PyLong_FromUnsignedLongLong -PyLong_FromVoidPtr -PyLong_GetInfo -PyLong_Type -PyMap_Type -PyMapping_Check -PyMapping_GetItemString -PyMapping_HasKey -PyMapping_HasKeyString -PyMapping_Items -PyMapping_Keys -PyMapping_Length -PyMapping_SetItemString -PyMapping_Size -PyMapping_Values -PyMem_Free -PyMem_Malloc -PyMem_Realloc -PyMemberDescr_Type -PyMemoryView_FromObject -PyMemoryView_GetContiguous -PyMemoryView_Type -PyMethodDescr_Type -PyModule_AddIntConstant -PyModule_AddObject -PyModule_AddStringConstant -PyModule_Create2 -PyModule_GetDef -PyModule_GetDict -PyModule_GetFilename -PyModule_GetFilenameObject -PyModule_GetName -PyModule_GetState -PyModule_New -PyModule_Type -PyNullImporter_Type -PyNumber_Absolute -PyNumber_Add -PyNumber_And -PyNumber_AsSsize_t -PyNumber_Check -PyNumber_Divmod -PyNumber_Float -PyNumber_FloorDivide -PyNumber_InPlaceAdd -PyNumber_InPlaceAnd -PyNumber_InPlaceFloorDivide -PyNumber_InPlaceLshift -PyNumber_InPlaceMultiply -PyNumber_InPlaceOr -PyNumber_InPlacePower -PyNumber_InPlaceRemainder -PyNumber_InPlaceRshift -PyNumber_InPlaceSubtract -PyNumber_InPlaceTrueDivide -PyNumber_InPlaceXor -PyNumber_Index -PyNumber_Invert -PyNumber_Long -PyNumber_Lshift -PyNumber_Multiply -PyNumber_Negative -PyNumber_Or -PyNumber_Positive -PyNumber_Power -PyNumber_Remainder -PyNumber_Rshift -PyNumber_Subtract -PyNumber_ToBase -PyNumber_TrueDivide -PyNumber_Xor -PyOS_AfterFork -PyOS_InitInterrupts -PyOS_InputHook -PyOS_InterruptOccurred -PyOS_ReadlineFunctionPointer -PyOS_double_to_string -PyOS_getsig -PyOS_mystricmp -PyOS_mystrnicmp -PyOS_setsig -PyOS_snprintf -PyOS_string_to_double -PyOS_strtol -PyOS_strtoul -PyOS_vsnprintf -PyObject_ASCII -PyObject_AsCharBuffer -PyObject_AsFileDescriptor -PyObject_AsReadBuffer -PyObject_AsWriteBuffer -PyObject_Bytes -PyObject_Call -PyObject_CallFunction -PyObject_CallFunctionObjArgs -PyObject_CallMethod -PyObject_CallMethodObjArgs -PyObject_CallObject -PyObject_CheckReadBuffer -PyObject_ClearWeakRefs -PyObject_DelItem -PyObject_DelItemString -PyObject_Dir -PyObject_Format -PyObject_Free -PyObject_GC_Del -PyObject_GC_Track -PyObject_GC_UnTrack -PyObject_GenericGetAttr -PyObject_GenericSetAttr -PyObject_GetAttr -PyObject_GetAttrString -PyObject_GetItem -PyObject_GetIter -PyObject_HasAttr -PyObject_HasAttrString -PyObject_Hash -PyObject_HashNotImplemented -PyObject_Init -PyObject_InitVar -PyObject_IsInstance -PyObject_IsSubclass -PyObject_IsTrue -PyObject_Length -PyObject_Malloc -PyObject_Not -PyObject_Realloc -PyObject_Repr -PyObject_RichCompare -PyObject_RichCompareBool -PyObject_SelfIter -PyObject_SetAttr -PyObject_SetAttrString -PyObject_SetItem -PyObject_Size -PyObject_Str -PyObject_Type -PyParser_SimpleParseFileFlags -PyParser_SimpleParseStringFlags -PyProperty_Type -PyRangeIter_Type -PyRange_Type -PyReversed_Type -PySeqIter_New -PySeqIter_Type -PySequence_Check -PySequence_Concat -PySequence_Contains -PySequence_Count -PySequence_DelItem -PySequence_DelSlice -PySequence_Fast -PySequence_GetItem -PySequence_GetSlice -PySequence_In -PySequence_InPlaceConcat -PySequence_InPlaceRepeat -PySequence_Index -PySequence_Length -PySequence_List -PySequence_Repeat -PySequence_SetItem -PySequence_SetSlice -PySequence_Size -PySequence_Tuple -PySetIter_Type -PySet_Add -PySet_Clear -PySet_Contains -PySet_Discard -PySet_New -PySet_Pop -PySet_Size -PySet_Type -PySlice_GetIndices -PySlice_GetIndicesEx -PySlice_New -PySlice_Type -PySortWrapper_Type -PyState_FindModule -PyState_AddModule -PyState_RemoveModule -PyStructSequence_GetItem -PyStructSequence_New -PyStructSequence_NewType -PyStructSequence_SetItem -PySuper_Type -PySys_AddWarnOption -PySys_AddWarnOptionUnicode -PySys_FormatStderr -PySys_FormatStdout -PySys_GetObject -PySys_HasWarnOptions -PySys_ResetWarnOptions -PySys_SetArgv -PySys_SetArgvEx -PySys_SetObject -PySys_SetPath -PySys_WriteStderr -PySys_WriteStdout -PyThreadState_Clear -PyThreadState_Delete -PyThreadState_DeleteCurrent -PyThreadState_Get -PyThreadState_GetDict -PyThreadState_New -PyThreadState_SetAsyncExc -PyThreadState_Swap -PyTraceBack_Here -PyTraceBack_Print -PyTraceBack_Type -PyTupleIter_Type -PyTuple_ClearFreeList -PyTuple_GetItem -PyTuple_GetSlice -PyTuple_New -PyTuple_Pack -PyTuple_SetItem -PyTuple_Size -PyTuple_Type -PyType_ClearCache -PyType_FromSpec -PyType_FromSpecWithBases -PyType_GenericAlloc -PyType_GenericNew -PyType_GetFlags -PyType_IsSubtype -PyType_Modified -PyType_Ready -PyType_Type -PyUnicodeDecodeError_Create -PyUnicodeDecodeError_GetEncoding -PyUnicodeDecodeError_GetEnd -PyUnicodeDecodeError_GetObject -PyUnicodeDecodeError_GetReason -PyUnicodeDecodeError_GetStart -PyUnicodeDecodeError_SetEnd -PyUnicodeDecodeError_SetReason -PyUnicodeDecodeError_SetStart -PyUnicodeEncodeError_GetEncoding -PyUnicodeEncodeError_GetEnd -PyUnicodeEncodeError_GetObject -PyUnicodeEncodeError_GetReason -PyUnicodeEncodeError_GetStart -PyUnicodeEncodeError_SetEnd -PyUnicodeEncodeError_SetReason -PyUnicodeEncodeError_SetStart -PyUnicodeIter_Type -PyUnicodeTranslateError_GetEnd -PyUnicodeTranslateError_GetObject -PyUnicodeTranslateError_GetReason -PyUnicodeTranslateError_GetStart -PyUnicodeTranslateError_SetEnd -PyUnicodeTranslateError_SetReason -PyUnicodeTranslateError_SetStart -PyUnicodeUCS2_Append -PyUnicodeUCS2_AppendAndDel -PyUnicodeUCS2_AsASCIIString -PyUnicodeUCS2_AsCharmapString -PyUnicodeUCS2_AsDecodedObject -PyUnicodeUCS2_AsDecodedUnicode -PyUnicodeUCS2_AsEncodedObject -PyUnicodeUCS2_AsEncodedString -PyUnicodeUCS2_AsEncodedUnicode -PyUnicodeUCS2_AsLatin1String -PyUnicodeUCS2_AsRawUnicodeEscapeString -PyUnicodeUCS2_AsUTF16String -PyUnicodeUCS2_AsUTF32String -PyUnicodeUCS2_AsUTF8String -PyUnicodeUCS2_AsUnicodeEscapeString -PyUnicodeUCS2_AsWideChar -PyUnicodeUCS2_ClearFreelist -PyUnicodeUCS2_Compare -PyUnicodeUCS2_Concat -PyUnicodeUCS2_Contains -PyUnicodeUCS2_Count -PyUnicodeUCS2_Decode -PyUnicodeUCS2_DecodeASCII -PyUnicodeUCS2_DecodeCharmap -PyUnicodeUCS2_DecodeFSDefault -PyUnicodeUCS2_DecodeFSDefaultAndSize -PyUnicodeUCS2_DecodeLatin1 -PyUnicodeUCS2_DecodeRawUnicodeEscape -PyUnicodeUCS2_DecodeUTF16 -PyUnicodeUCS2_DecodeUTF16Stateful -PyUnicodeUCS2_DecodeUTF32 -PyUnicodeUCS2_DecodeUTF32Stateful -PyUnicodeUCS2_DecodeUTF8 -PyUnicodeUCS2_DecodeUTF8Stateful -PyUnicodeUCS2_DecodeUnicodeEscape -PyUnicodeUCS2_FSConverter -PyUnicodeUCS2_FSDecoder -PyUnicodeUCS2_Find -PyUnicodeUCS2_Format -PyUnicodeUCS2_FromEncodedObject -PyUnicodeUCS2_FromFormat -PyUnicodeUCS2_FromFormatV -PyUnicodeUCS2_FromObject -PyUnicodeUCS2_FromOrdinal -PyUnicodeUCS2_FromString -PyUnicodeUCS2_FromStringAndSize -PyUnicodeUCS2_FromWideChar -PyUnicodeUCS2_GetDefaultEncoding -PyUnicodeUCS2_GetSize -PyUnicodeUCS2_IsIdentifier -PyUnicodeUCS2_Join -PyUnicodeUCS2_Partition -PyUnicodeUCS2_RPartition -PyUnicodeUCS2_RSplit -PyUnicodeUCS2_Replace -PyUnicodeUCS2_Resize -PyUnicodeUCS2_RichCompare -PyUnicodeUCS2_SetDefaultEncoding -PyUnicodeUCS2_Split -PyUnicodeUCS2_Splitlines -PyUnicodeUCS2_Tailmatch -PyUnicodeUCS2_Translate -PyUnicode_BuildEncodingMap -PyUnicode_CompareWithASCIIString -PyUnicode_DecodeUTF7 -PyUnicode_DecodeUTF7Stateful -PyUnicode_EncodeFSDefault -PyUnicode_InternFromString -PyUnicode_InternImmortal -PyUnicode_InternInPlace -PyUnicode_Type -PyWeakref_GetObject -PyWeakref_NewProxy -PyWeakref_NewRef -PyWrapperDescr_Type -PyWrapper_New -PyZip_Type -Py_AddPendingCall -Py_AtExit -Py_BuildValue -Py_CompileString -Py_DecRef -Py_EndInterpreter -Py_Exit -Py_FatalError -Py_FileSystemDefaultEncoding -Py_Finalize -Py_GetBuildInfo -Py_GetCompiler -Py_GetCopyright -Py_GetExecPrefix -Py_GetPath -Py_GetPlatform -Py_GetPrefix -Py_GetProgramFullPath -Py_GetProgramName -Py_GetPythonHome -Py_GetRecursionLimit -Py_GetVersion -Py_HasFileSystemDefaultEncoding -Py_IncRef -Py_Initialize -Py_InitializeEx -Py_IsInitialized -Py_Main -Py_MakePendingCalls -Py_NewInterpreter -Py_ReprEnter -Py_ReprLeave -Py_SetProgramName -Py_SetPythonHome -Py_SetRecursionLimit -Py_SymtableString -Py_VaBuildValue -_PyErr_BadInternalCall -_PyObject_CallFunction_SizeT -_PyObject_CallMethod_SizeT -_PyObject_GC_Malloc -_PyObject_GC_New -_PyObject_GC_NewVar -_PyObject_GC_Resize -_PyObject_New -_PyObject_NewVar -_PyState_AddModule -_PyThreadState_Init -_PyThreadState_Prealloc -_PyTrash_delete_later -_PyTrash_delete_nesting -_PyTrash_deposit_object -_PyTrash_destroy_chain -_PyWeakref_CallableProxyType -_PyWeakref_ProxyType -_PyWeakref_RefType -_Py_BuildValue_SizeT -_Py_CheckRecursionLimit -_Py_CheckRecursiveCall -_Py_Dealloc -_Py_EllipsisObject -_Py_FalseStruct -_Py_NoneStruct -_Py_NotImplementedStruct -_Py_SwappedOp -_Py_TrueStruct -_Py_VaBuildValue_SizeT -_PyArg_Parse_SizeT -_PyArg_ParseTuple_SizeT -_PyArg_ParseTupleAndKeywords_SizeT -_PyArg_VaParse_SizeT -_PyArg_VaParseTupleAndKeywords_SizeT -_Py_BuildValue_SizeT diff --git a/PC/python_exe.rc b/PC/python_exe.rc index 14e2574377b7..91785a1e0640 100644 --- a/PC/python_exe.rc +++ b/PC/python_exe.rc @@ -1 +1,49 @@ -1 ICON DISCARDABLE "pycon.ico" +// Resource script for Python console EXEs. + +#include "python_ver_rc.h" + +// Include the manifest file that indicates we support all +// current versions of Windows. +#include +1 RT_MANIFEST "python.manifest" + +1 ICON DISCARDABLE "pycon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION PYVERSION64 + PRODUCTVERSION PYVERSION64 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "CompanyName", PYTHON_COMPANY "\0" + VALUE "FileDescription", "Python\0" + VALUE "FileVersion", PYTHON_VERSION + VALUE "InternalName", "Python Console\0" + VALUE "LegalCopyright", PYTHON_COPYRIGHT "\0" + VALUE "OriginalFilename", "python" PYTHON_DEBUG_EXT ".exe\0" + VALUE "ProductName", "Python\0" + VALUE "ProductVersion", PYTHON_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END diff --git a/PC/python_nt.rc b/PC/python_nt.rc index 199533cad9d7..fac6105d8a77 100644 --- a/PC/python_nt.rc +++ b/PC/python_nt.rc @@ -1,33 +1,11 @@ // Resource script for Python core DLL. -// Currently only holds version information. -// -#include "winver.h" - -#define MS_WINDOWS -#include "modsupport.h" -#include "patchlevel.h" -#ifdef _DEBUG -# include "pythonnt_rc_d.h" -#else -# include "pythonnt_rc.h" -#endif -/* e.g., 3.3.0a1 - * PY_VERSION comes from patchevel.h - */ -#define PYTHON_VERSION PY_VERSION "\0" +#include "python_ver_rc.h" -/* 64-bit version number as comma-separated list of 4 16-bit ints */ -#if PY_MICRO_VERSION > 64 -# error "PY_MICRO_VERSION > 64" -#endif -#if PY_RELEASE_LEVEL > 99 -# error "PY_RELEASE_LEVEL > 99" -#endif -#if PY_RELEASE_SERIAL > 9 -# error "PY_RELEASE_SERIAL > 9" -#endif -#define PYVERSION64 PY_MAJOR_VERSION, PY_MINOR_VERSION, FIELD3, PYTHON_API_VERSION +// Include the manifest file that indicates we support all +// current versions of Windows. +#include +2 RT_MANIFEST "python.manifest" // String Tables STRINGTABLE DISCARDABLE @@ -45,23 +23,23 @@ VS_VERSION_INFO VERSIONINFO PRODUCTVERSION PYVERSION64 FILEFLAGSMASK 0x3fL #ifdef _DEBUG - FILEFLAGS 0x1L + FILEFLAGS VS_FF_DEBUG #else FILEFLAGS 0x0L #endif - FILEOS 0x40004L - FILETYPE 0x1L + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "000004b0" BEGIN - VALUE "CompanyName", "Python Software Foundation\0" + VALUE "CompanyName", PYTHON_COMPANY "\0" VALUE "FileDescription", "Python Core\0" VALUE "FileVersion", PYTHON_VERSION VALUE "InternalName", "Python DLL\0" - VALUE "LegalCopyright", "Copyright � 2001-2013 Python Software Foundation. Copyright � 2000 BeOpen.com. Copyright � 1995-2001 CNRI. Copyright � 1991-1995 SMC.\0" + VALUE "LegalCopyright", PYTHON_COPYRIGHT "\0" VALUE "OriginalFilename", PYTHON_DLL_NAME "\0" VALUE "ProductName", "Python\0" VALUE "ProductVersion", PYTHON_VERSION diff --git a/PC/python_ver_rc.h b/PC/python_ver_rc.h new file mode 100644 index 000000000000..827e9be52831 --- /dev/null +++ b/PC/python_ver_rc.h @@ -0,0 +1,35 @@ +// Resource script for Python core DLL. +// Currently only holds version information. +// +#include "winver.h" + +#define PYTHON_COMPANY "Python Software Foundation" +#define PYTHON_COPYRIGHT "Copyright \xA9 2001-2015 Python Software Foundation. Copyright \xA9 2000 BeOpen.com. Copyright \xA9 1995-2001 CNRI. Copyright \xA9 1991-1995 SMC." + +#define MS_WINDOWS +#include "modsupport.h" +#include "patchlevel.h" +#ifdef _DEBUG +# include "pythonnt_rc_d.h" +# define PYTHON_DEBUG_EXT "_d" +#else +# include "pythonnt_rc.h" +# define PYTHON_DEBUG_EXT +#endif + +/* e.g., 3.3.0a1 + * PY_VERSION comes from patchlevel.h + */ +#define PYTHON_VERSION PY_VERSION "\0" + +/* 64-bit version number as comma-separated list of 4 16-bit ints */ +#if PY_MICRO_VERSION > 64 +# error "PY_MICRO_VERSION > 64" +#endif +#if PY_RELEASE_LEVEL > 99 +# error "PY_RELEASE_LEVEL > 99" +#endif +#if PY_RELEASE_SERIAL > 9 +# error "PY_RELEASE_SERIAL > 9" +#endif +#define PYVERSION64 PY_MAJOR_VERSION, PY_MINOR_VERSION, FIELD3, PYTHON_API_VERSION diff --git a/PC/readme.txt b/PC/readme.txt index 60f231e513ef..0a96d269b097 100644 --- a/PC/readme.txt +++ b/PC/readme.txt @@ -71,13 +71,6 @@ getpathp.c Default sys.path calculations (for all PC platforms). dllbase_nt.txt A (manually maintained) list of base addresses for various DLLs, to avoid run-time relocation. -example_nt A subdirectory showing how to build an extension as a - DLL. - -Legacy support for older versions of Visual Studio -================================================== -The subdirectories VC6, VS7.1 and VS8.0 contain legacy support older -versions of Microsoft Visual Studio. See PCbuild/readme.txt. Note for Windows 3.x and DOS users ================================== diff --git a/PC/winreg.c b/PC/winreg.c index 563a3ebcf59a..3313202bc43c 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -17,6 +17,7 @@ #include "windows.h" static BOOL PyHKEY_AsHKEY(PyObject *ob, HKEY *pRes, BOOL bNoneOK); +static BOOL clinic_HKEY_converter(PyObject *ob, void *p); static PyObject *PyHKEY_FromHKEY(HKEY h); static BOOL PyHKEY_Close(PyObject *obHandle); @@ -46,10 +47,12 @@ PyDoc_STRVAR(module_doc, "DeleteValue() - Removes a named value from the specified registry key.\n" "EnumKey() - Enumerates subkeys of the specified open registry key.\n" "EnumValue() - Enumerates values of the specified open registry key.\n" -"ExpandEnvironmentStrings() - Expand the env strings in a REG_EXPAND_SZ string.\n" +"ExpandEnvironmentStrings() - Expand the env strings in a REG_EXPAND_SZ\n" +" string.\n" "FlushKey() - Writes all the attributes of the specified key to the registry.\n" -"LoadKey() - Creates a subkey under HKEY_USER or HKEY_LOCAL_MACHINE and stores\n" -" registration information from a specified file into that subkey.\n" +"LoadKey() - Creates a subkey under HKEY_USER or HKEY_LOCAL_MACHINE and\n" +" stores registration information from a specified file into that\n" +" subkey.\n" "OpenKey() - Opens the specified key.\n" "OpenKeyEx() - Alias of OpenKey().\n" "QueryValue() - Retrieves the value associated with the unnamed value for a\n" @@ -71,299 +74,6 @@ PyDoc_STRVAR(module_doc, "to see what constants are used, and where."); -PyDoc_STRVAR(CloseKey_doc, -"CloseKey(hkey)\n" -"Closes a previously opened registry key.\n" -"\n" -"The hkey argument specifies a previously opened key.\n" -"\n" -"Note that if the key is not closed using this method, it will be\n" -"closed when the hkey object is destroyed by Python."); - -PyDoc_STRVAR(ConnectRegistry_doc, -"ConnectRegistry(computer_name, key) -> key\n" -"Establishes a connection to a predefined registry handle on another computer.\n" -"\n" -"computer_name is the name of the remote computer, of the form \\\\computername.\n" -" If None, the local computer is used.\n" -"key is the predefined handle to connect to.\n" -"\n" -"The return value is the handle of the opened key.\n" -"If the function fails, an OSError exception is raised."); - -PyDoc_STRVAR(CreateKey_doc, -"CreateKey(key, sub_key) -> key\n" -"Creates or opens the specified key.\n" -"\n" -"key is an already open key, or one of the predefined HKEY_* constants.\n" -"sub_key is a string that names the key this method opens or creates.\n" -"\n" -"If key is one of the predefined keys, sub_key may be None. In that case,\n" -"the handle returned is the same key handle passed in to the function.\n" -"\n" -"If the key already exists, this function opens the existing key.\n" -"\n" -"The return value is the handle of the opened key.\n" -"If the function fails, an OSError exception is raised."); - -PyDoc_STRVAR(CreateKeyEx_doc, -"CreateKeyEx(key, sub_key, reserved=0, access=KEY_WRITE) -> key\n" -"Creates or opens the specified key.\n" -"\n" -"key is an already open key, or one of the predefined HKEY_* constants\n" -"sub_key is a string that names the key this method opens or creates.\n" -"reserved is a reserved integer, and must be zero. Default is zero.\n" -"access is an integer that specifies an access mask that describes the \n" -" desired security access for the key. Default is KEY_WRITE.\n" -"\n" -"If key is one of the predefined keys, sub_key may be None. In that case,\n" -"the handle returned is the same key handle passed in to the function.\n" -"\n" -"If the key already exists, this function opens the existing key\n" -"\n" -"The return value is the handle of the opened key.\n" -"If the function fails, an OSError exception is raised."); - -PyDoc_STRVAR(DeleteKey_doc, -"DeleteKey(key, sub_key)\n" -"Deletes the specified key.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"sub_key is a string that must be a subkey of the key identified by the key\n" -" parameter. This value must not be None, and the key may not have\n" -" subkeys.\n" -"\n" -"This method can not delete keys with subkeys.\n" -"\n" -"If the function succeeds, the entire key, including all of its values,\n" -"is removed. If the function fails, an OSError exception is raised."); - -PyDoc_STRVAR(DeleteKeyEx_doc, -"DeleteKeyEx(key, sub_key, access=KEY_WOW64_64KEY, reserved=0)\n" -"Deletes the specified key (64-bit OS only).\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"sub_key is a string that must be a subkey of the key identified by the key\n" -" parameter. This value must not be None, and the key may not have\n" -" subkeys.\n" -"reserved is a reserved integer, and must be zero. Default is zero.\n" -"access is an integer that specifies an access mask that describes the \n" -" desired security access for the key. Default is KEY_WOW64_64KEY.\n" -"\n" -"This method can not delete keys with subkeys.\n" -"\n" -"If the function succeeds, the entire key, including all of its values,\n" -"is removed. If the function fails, an OSError exception is raised.\n" -"On unsupported Windows versions, NotImplementedError is raised."); - -PyDoc_STRVAR(DeleteValue_doc, -"DeleteValue(key, value)\n" -"Removes a named value from a registry key.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"value is a string that identifies the value to remove."); - -PyDoc_STRVAR(EnumKey_doc, -"EnumKey(key, index) -> string\n" -"Enumerates subkeys of an open registry key.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"index is an integer that identifies the index of the key to retrieve.\n" -"\n" -"The function retrieves the name of one subkey each time it is called.\n" -"It is typically called repeatedly until an OSError exception is\n" -"raised, indicating no more values are available."); - -PyDoc_STRVAR(EnumValue_doc, -"EnumValue(key, index) -> tuple\n" -"Enumerates values of an open registry key.\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"index is an integer that identifies the index of the value to retrieve.\n" -"\n" -"The function retrieves the name of one subkey each time it is called.\n" -"It is typically called repeatedly, until an OSError exception\n" -"is raised, indicating no more values.\n" -"\n" -"The result is a tuple of 3 items:\n" -"value_name is a string that identifies the value.\n" -"value_data is an object that holds the value data, and whose type depends\n" -" on the underlying registry type.\n" -"data_type is an integer that identifies the type of the value data."); - -PyDoc_STRVAR(ExpandEnvironmentStrings_doc, -"ExpandEnvironmentStrings(string) -> string\n" -"Expand environment vars.\n"); - -PyDoc_STRVAR(FlushKey_doc, -"FlushKey(key)\n" -"Writes all the attributes of a key to the registry.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"\n" -"It is not necessary to call FlushKey to change a key. Registry changes are\n" -"flushed to disk by the registry using its lazy flusher. Registry changes are\n" -"also flushed to disk at system shutdown. Unlike CloseKey(), the FlushKey()\n" -"method returns only when all the data has been written to the registry.\n" -"\n" -"An application should only call FlushKey() if it requires absolute certainty\n" -"that registry changes are on disk. If you don't know whether a FlushKey()\n" -"call is required, it probably isn't."); - -PyDoc_STRVAR(LoadKey_doc, -"LoadKey(key, sub_key, file_name)\n" -"Creates a subkey under the specified key and stores registration information\n" -"from a specified file into that subkey.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"sub_key is a string that identifies the sub_key to load.\n" -"file_name is the name of the file to load registry data from. This file must\n" -" have been created with the SaveKey() function. Under the file\n" -" allocation table (FAT) file system, the filename may not have an\n" -" extension.\n" -"\n" -"A call to LoadKey() fails if the calling process does not have the\n" -"SE_RESTORE_PRIVILEGE privilege.\n" -"\n" -"If key is a handle returned by ConnectRegistry(), then the path specified\n" -"in fileName is relative to the remote computer.\n" -"\n" -"The docs imply key must be in the HKEY_USER or HKEY_LOCAL_MACHINE tree"); - -PyDoc_STRVAR(OpenKey_doc, -"OpenKey(key, sub_key, reserved=0, access=KEY_READ) -> key\n" -"Opens the specified key.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"sub_key is a string that identifies the sub_key to open.\n" -"reserved is a reserved integer, and must be zero. Default is zero.\n" -"access is an integer that specifies an access mask that describes the desired\n" -" security access for the key. Default is KEY_READ\n" -"\n" -"The result is a new handle to the specified key\n" -"If the function fails, an OSError exception is raised."); - -PyDoc_STRVAR(OpenKeyEx_doc, "See OpenKey()"); - -PyDoc_STRVAR(QueryInfoKey_doc, -"QueryInfoKey(key) -> tuple\n" -"Returns information about a key.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"\n" -"The result is a tuple of 3 items:" -"An integer that identifies the number of sub keys this key has.\n" -"An integer that identifies the number of values this key has.\n" -"An integer that identifies when the key was last modified (if available)\n" -" as 100's of nanoseconds since Jan 1, 1600."); - -PyDoc_STRVAR(QueryValue_doc, -"QueryValue(key, sub_key) -> string\n" -"Retrieves the unnamed value for a key.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"sub_key is a string that holds the name of the subkey with which the value\n" -" is associated. If this parameter is None or empty, the function\n" -" retrieves the value set by the SetValue() method for the key\n" -" identified by key." -"\n" -"Values in the registry have name, type, and data components. This method\n" -"retrieves the data for a key's first value that has a NULL name.\n" -"But the underlying API call doesn't return the type, Lame Lame Lame, DONT USE THIS!!!"); - -PyDoc_STRVAR(QueryValueEx_doc, -"QueryValueEx(key, value_name) -> (value, type_id)\n" -"Retrieves the type and data for a specified value name associated with an\n" -"open registry key.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"value_name is a string indicating the value to query"); - -PyDoc_STRVAR(SaveKey_doc, -"SaveKey(key, file_name)\n" -"Saves the specified key, and all its subkeys to the specified file.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"file_name is the name of the file to save registry data to. This file cannot\n" -" already exist. If this filename includes an extension, it cannot be\n" -" used on file allocation table (FAT) file systems by the LoadKey(),\n" -" ReplaceKey() or RestoreKey() methods.\n" -"\n" -"If key represents a key on a remote computer, the path described by file_name\n" -"is relative to the remote computer.\n" -"\n" -"The caller of this method must possess the SeBackupPrivilege security\n" -"privilege. This function passes NULL for security_attributes to the API."); - -PyDoc_STRVAR(SetValue_doc, -"SetValue(key, sub_key, type, value)\n" -"Associates a value with a specified key.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"sub_key is a string that names the subkey with which the value is associated.\n" -"type is an integer that specifies the type of the data. Currently this must\n" -" be REG_SZ, meaning only strings are supported.\n" -"value is a string that specifies the new value.\n" -"\n" -"If the key specified by the sub_key parameter does not exist, the SetValue\n" -"function creates it.\n" -"\n" -"Value lengths are limited by available memory. Long values (more than\n" -"2048 bytes) should be stored as files with the filenames stored in \n" -"the configuration registry. This helps the registry perform efficiently.\n" -"\n" -"The key identified by the key parameter must have been opened with\n" -"KEY_SET_VALUE access."); - -PyDoc_STRVAR(SetValueEx_doc, -"SetValueEx(key, value_name, reserved, type, value)\n" -"Stores data in the value field of an open registry key.\n" -"\n" -"key is an already open key, or any one of the predefined HKEY_* constants.\n" -"value_name is a string containing the name of the value to set, or None.\n" -"reserved can be anything - zero is always passed to the API.\n" -"type is an integer that specifies the type of the data. This should be one of:\n" -" REG_BINARY -- Binary data in any form.\n" -" REG_DWORD -- A 32-bit number.\n" -" REG_DWORD_LITTLE_ENDIAN -- A 32-bit number in little-endian format.\n" -" REG_DWORD_BIG_ENDIAN -- A 32-bit number in big-endian format.\n" -" REG_EXPAND_SZ -- A null-terminated string that contains unexpanded references\n" -" to environment variables (for example, %PATH%).\n" -" REG_LINK -- A Unicode symbolic link.\n" -" REG_MULTI_SZ -- An sequence of null-terminated strings, terminated by\n" -" two null characters. Note that Python handles this\n" -" termination automatically.\n" -" REG_NONE -- No defined value type.\n" -" REG_RESOURCE_LIST -- A device-driver resource list.\n" -" REG_SZ -- A null-terminated string.\n" -"value is a string that specifies the new value.\n" -"\n" -"This method can also set additional value and type information for the\n" -"specified key. The key identified by the key parameter must have been\n" -"opened with KEY_SET_VALUE access.\n" -"\n" -"To open the key, use the CreateKeyEx() or OpenKeyEx() methods.\n" -"\n" -"Value lengths are limited by available memory. Long values (more than\n" -"2048 bytes) should be stored as files with the filenames stored in \n" -"the configuration registry. This helps the registry perform efficiently."); - -PyDoc_STRVAR(DisableReflectionKey_doc, -"Disables registry reflection for 32-bit processes running on a 64-bit\n" -"Operating System. Will generally raise NotImplemented if executed on\n" -"a 32-bit Operating System.\n" -"\n" -"If the key is not on the reflection list, the function succeeds but has no effect.\n" -"Disabling reflection for a key does not affect reflection of any subkeys."); - -PyDoc_STRVAR(EnableReflectionKey_doc, -"Restores registry reflection for the specified disabled key.\n" -"Will generally raise NotImplemented if executed on a 32-bit Operating System.\n" -"Restoring reflection for a key does not affect reflection of any subkeys."); - -PyDoc_STRVAR(QueryReflectionKey_doc, -"QueryReflectionKey(hkey) -> bool\n" -"Determines the reflection state for the specified key.\n" -"Will generally raise NotImplemented if executed on a 32-bit Operating System.\n"); /* PyHKEY docstrings */ PyDoc_STRVAR(PyHKEY_doc, @@ -389,24 +99,6 @@ PyDoc_STRVAR(PyHKEY_doc, "rich comparison - Handle objects are compared using the handle value."); -PyDoc_STRVAR(PyHKEY_Close_doc, -"key.Close()\n" -"Closes the underlying Windows handle.\n" -"\n" -"If the handle is already closed, no error is raised."); - -PyDoc_STRVAR(PyHKEY_Detach_doc, -"key.Detach() -> int\n" -"Detaches the Windows handle from the handle object.\n" -"\n" -"The result is the value of the handle before it is detached. If the\n" -"handle is already detached, this will return zero.\n" -"\n" -"After calling this function, the handle is effectively invalidated,\n" -"but the handle is not closed. You would call this function when you\n" -"need the underlying win32 handle to exist beyond the lifetime of the\n" -"handle object."); - /************************************************************************ @@ -516,16 +208,135 @@ static PyNumberMethods PyHKEY_NumberMethods = PyHKEY_unaryFailureFunc, /* nb_float */ }; -static PyObject *PyHKEY_CloseMethod(PyObject *self, PyObject *args); -static PyObject *PyHKEY_DetachMethod(PyObject *self, PyObject *args); -static PyObject *PyHKEY_Enter(PyObject *self); -static PyObject *PyHKEY_Exit(PyObject *self, PyObject *args); +/*[clinic input] +module winreg +class winreg.HKEYType "PyHKEYObject *" "&PyHKEY_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=4c964eba3bf914d6]*/ + +/*[python input] +class REGSAM_converter(CConverter): + type = 'REGSAM' + format_unit = 'i' + +class DWORD_converter(CConverter): + type = 'DWORD' + format_unit = 'k' + +class HKEY_converter(CConverter): + type = 'HKEY' + converter = 'clinic_HKEY_converter' + +class HKEY_return_converter(CReturnConverter): + type = 'HKEY' + + def render(self, function, data): + self.declare(data) + self.err_occurred_if_null_pointer("_return_value", data) + data.return_conversion.append( + 'return_value = PyHKEY_FromHKEY(_return_value);\n') + +# HACK: this only works for PyHKEYObjects, nothing else. +# Should this be generalized and enshrined in clinic.py, +# destroy this converter with prejudice. +class self_return_converter(CReturnConverter): + type = 'PyHKEYObject *' + + def render(self, function, data): + self.declare(data) + data.return_conversion.append( + 'return_value = (PyObject *)_return_value;\n') +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=22f7aedc6d68e80e]*/ + +#include "clinic/winreg.c.h" + +/************************************************************************ + + The PyHKEY object methods + +************************************************************************/ +/*[clinic input] +winreg.HKEYType.Close + +Closes the underlying Windows handle. + +If the handle is already closed, no error is raised. +[clinic start generated code]*/ + +static PyObject * +winreg_HKEYType_Close_impl(PyHKEYObject *self) +/*[clinic end generated code: output=fced3a624fb0c344 input=6786ac75f6b89de6]*/ +{ + if (!PyHKEY_Close((PyObject *)self)) + return NULL; + Py_RETURN_NONE; +} + +/*[clinic input] +winreg.HKEYType.Detach + +Detaches the Windows handle from the handle object. + +The result is the value of the handle before it is detached. If the +handle is already detached, this will return zero. + +After calling this function, the handle is effectively invalidated, +but the handle is not closed. You would call this function when you +need the underlying win32 handle to exist beyond the lifetime of the +handle object. +[clinic start generated code]*/ + +static PyObject * +winreg_HKEYType_Detach_impl(PyHKEYObject *self) +/*[clinic end generated code: output=dda5a9e1a01ae78f input=dd2cc09e6c6ba833]*/ +{ + void* ret; + ret = (void*)self->hkey; + self->hkey = 0; + return PyLong_FromVoidPtr(ret); +} + +/*[clinic input] +winreg.HKEYType.__enter__ -> self +[clinic start generated code]*/ + +static PyHKEYObject * +winreg_HKEYType___enter___impl(PyHKEYObject *self) +/*[clinic end generated code: output=52c34986dab28990 input=c40fab1f0690a8e2]*/ +{ + Py_XINCREF(self); + return self; +} + + +/*[clinic input] +winreg.HKEYType.__exit__ + + exc_type: object + exc_value: object + traceback: object +[clinic start generated code]*/ + +static PyObject * +winreg_HKEYType___exit___impl(PyHKEYObject *self, PyObject *exc_type, + PyObject *exc_value, PyObject *traceback) +/*[clinic end generated code: output=923ebe7389e6a263 input=fb32489ee92403c7]*/ +{ + if (!PyHKEY_Close((PyObject *)self)) + return NULL; + Py_RETURN_NONE; +} + +/*[clinic input] +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=da39a3ee5e6b4b0d]*/ static struct PyMethodDef PyHKEY_methods[] = { - {"Close", PyHKEY_CloseMethod, METH_VARARGS, PyHKEY_Close_doc}, - {"Detach", PyHKEY_DetachMethod, METH_VARARGS, PyHKEY_Detach_doc}, - {"__enter__", (PyCFunction)PyHKEY_Enter, METH_NOARGS, NULL}, - {"__exit__", PyHKEY_Exit, METH_VARARGS, NULL}, + WINREG_HKEYTYPE_CLOSE_METHODDEF + WINREG_HKEYTYPE_DETACH_METHODDEF + WINREG_HKEYTYPE___ENTER___METHODDEF + WINREG_HKEYTYPE___EXIT___METHODDEF {NULL} }; @@ -569,50 +380,6 @@ PyTypeObject PyHKEY_Type = PyHKEY_memberlist, /*tp_members*/ }; -/************************************************************************ - - The PyHKEY object methods - -************************************************************************/ -static PyObject * -PyHKEY_CloseMethod(PyObject *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, ":Close")) - return NULL; - if (!PyHKEY_Close(self)) - return NULL; - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -PyHKEY_DetachMethod(PyObject *self, PyObject *args) -{ - void* ret; - PyHKEYObject *pThis = (PyHKEYObject *)self; - if (!PyArg_ParseTuple(args, ":Detach")) - return NULL; - ret = (void*)pThis->hkey; - pThis->hkey = 0; - return PyLong_FromVoidPtr(ret); -} - -static PyObject * -PyHKEY_Enter(PyObject *self) -{ - Py_XINCREF(self); - return self; -} - -static PyObject * -PyHKEY_Exit(PyObject *self, PyObject *args) -{ - if (!PyHKEY_Close(self)) - return NULL; - Py_RETURN_NONE; -} - - /************************************************************************ The public PyHKEY API (well, not public yet :-) ************************************************************************/ @@ -675,6 +442,14 @@ PyHKEY_AsHKEY(PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK) return TRUE; } +BOOL +clinic_HKEY_converter(PyObject *ob, void *p) +{ + if (!PyHKEY_AsHKEY(ob, (HKEY *)p, FALSE)) + return FALSE; + return TRUE; +} + PyObject * PyHKEY_FromHKEY(HKEY h) { @@ -871,8 +646,10 @@ Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize) /* ALSO handle ALL unknown data types here. Even if we can't support it natively, we should handle the bits. */ default: - if (value == Py_None) + if (value == Py_None) { *retDataSize = 0; + *retDataBuf = NULL; + } else { Py_buffer view; @@ -937,14 +714,16 @@ Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ) wchar_t *data = (wchar_t *)retDataBuf; int len = retDataSize / 2; int s = countStrings(data, len); - wchar_t **str = (wchar_t **)PyMem_Malloc(sizeof(wchar_t *)*s); + wchar_t **str = PyMem_New(wchar_t *, s); if (str == NULL) return PyErr_NoMemory(); fixupMultiSZ(str, data, len); obData = PyList_New(s); - if (obData == NULL) + if (obData == NULL) { + PyMem_Free(str); return NULL; + } for (index = 0; index < s; index++) { size_t len = wcslen(str[index]); @@ -952,6 +731,7 @@ Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ) PyErr_SetString(PyExc_OverflowError, "registry string is too long for a Python string"); Py_DECREF(obData); + PyMem_Free(str); return NULL; } PyList_SetItem(obData, @@ -980,120 +760,199 @@ Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ) /* The Python methods */ +/*[clinic input] +winreg.CloseKey + + hkey: object + A previously opened key. + / + +Closes a previously opened registry key. + +Note that if the key is not closed using this method, it will be +closed when the hkey object is destroyed by Python. +[clinic start generated code]*/ + static PyObject * -PyCloseKey(PyObject *self, PyObject *args) +winreg_CloseKey(PyModuleDef *module, PyObject *hkey) +/*[clinic end generated code: output=d96f73439403a064 input=5b1aac65ba5127ad]*/ { - PyObject *obKey; - if (!PyArg_ParseTuple(args, "O:CloseKey", &obKey)) - return NULL; - if (!PyHKEY_Close(obKey)) + if (!PyHKEY_Close(hkey)) return NULL; - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -static PyObject * -PyConnectRegistry(PyObject *self, PyObject *args) +/*[clinic input] +winreg.ConnectRegistry -> HKEY + + computer_name: Py_UNICODE(accept={str, NoneType}) + The name of the remote computer, of the form r"\\computername". If + None, the local computer is used. + key: HKEY + The predefined key to connect to. + / + +Establishes a connection to the registry on on another computer. + +The return value is the handle of the opened key. +If the function fails, an OSError exception is raised. +[clinic start generated code]*/ + +static HKEY +winreg_ConnectRegistry_impl(PyModuleDef *module, Py_UNICODE *computer_name, + HKEY key) +/*[clinic end generated code: output=5c52f6f7ba6e7b46 input=9a056558ce318433]*/ { - HKEY hKey; - PyObject *obKey; - wchar_t *szCompName = NULL; HKEY retKey; long rc; - if (!PyArg_ParseTuple(args, "ZO:ConnectRegistry", &szCompName, &obKey)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; Py_BEGIN_ALLOW_THREADS - rc = RegConnectRegistryW(szCompName, hKey, &retKey); + rc = RegConnectRegistryW(computer_name, key, &retKey); Py_END_ALLOW_THREADS - if (rc != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, - "ConnectRegistry"); - return PyHKEY_FromHKEY(retKey); + if (rc != ERROR_SUCCESS) { + PyErr_SetFromWindowsErrWithFunction(rc, "ConnectRegistry"); + return NULL; + } + return retKey; } -static PyObject * -PyCreateKey(PyObject *self, PyObject *args) +/*[clinic input] +winreg.CreateKey -> HKEY + + key: HKEY + An already open key, or one of the predefined HKEY_* constants. + sub_key: Py_UNICODE(accept={str, NoneType}) + The name of the key this method opens or creates. + / + +Creates or opens the specified key. + +If key is one of the predefined keys, sub_key may be None. In that case, +the handle returned is the same key handle passed in to the function. + +If the key already exists, this function opens the existing key. + +The return value is the handle of the opened key. +If the function fails, an OSError exception is raised. +[clinic start generated code]*/ + +static HKEY +winreg_CreateKey_impl(PyModuleDef *module, HKEY key, Py_UNICODE *sub_key) +/*[clinic end generated code: output=cd6843f30a73fc0e input=3cdd1622488acea2]*/ { - HKEY hKey; - PyObject *obKey; - wchar_t *subKey; HKEY retKey; long rc; - if (!PyArg_ParseTuple(args, "OZ:CreateKey", &obKey, &subKey)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) + + rc = RegCreateKeyW(key, sub_key, &retKey); + if (rc != ERROR_SUCCESS) { + PyErr_SetFromWindowsErrWithFunction(rc, "CreateKey"); return NULL; - rc = RegCreateKeyW(hKey, subKey, &retKey); - if (rc != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, "CreateKey"); - return PyHKEY_FromHKEY(retKey); + } + return retKey; } -static PyObject * -PyCreateKeyEx(PyObject *self, PyObject *args, PyObject *kwargs) +/*[clinic input] +winreg.CreateKeyEx -> HKEY + + key: HKEY + An already open key, or one of the predefined HKEY_* constants. + sub_key: Py_UNICODE(accept={str, NoneType}) + The name of the key this method opens or creates. + reserved: int = 0 + A reserved integer, and must be zero. Default is zero. + access: REGSAM(c_default='KEY_WRITE') = winreg.KEY_WRITE + An integer that specifies an access mask that describes the + desired security access for the key. Default is KEY_WRITE. + +Creates or opens the specified key. + +If key is one of the predefined keys, sub_key may be None. In that case, +the handle returned is the same key handle passed in to the function. + +If the key already exists, this function opens the existing key + +The return value is the handle of the opened key. +If the function fails, an OSError exception is raised. +[clinic start generated code]*/ + +static HKEY +winreg_CreateKeyEx_impl(PyModuleDef *module, HKEY key, Py_UNICODE *sub_key, + int reserved, REGSAM access) +/*[clinic end generated code: output=db835d5be84e72b2 input=42c2b03f98406b66]*/ { - HKEY hKey; - PyObject *key; - wchar_t *sub_key; HKEY retKey; - int reserved = 0; - REGSAM access = KEY_WRITE; long rc; - char *kwlist[] = {"key", "sub_key", "reserved", "access", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OZ|ii:CreateKeyEx", kwlist, - &key, &sub_key, &reserved, &access)) - return NULL; - if (!PyHKEY_AsHKEY(key, &hKey, FALSE)) - return NULL; - - rc = RegCreateKeyExW(hKey, sub_key, reserved, NULL, (DWORD)NULL, + rc = RegCreateKeyExW(key, sub_key, reserved, NULL, (DWORD)NULL, access, NULL, &retKey, NULL); - if (rc != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, "CreateKeyEx"); - return PyHKEY_FromHKEY(retKey); + if (rc != ERROR_SUCCESS) { + PyErr_SetFromWindowsErrWithFunction(rc, "CreateKeyEx"); + return NULL; + } + return retKey; } +/*[clinic input] +winreg.DeleteKey + key: HKEY + An already open key, or any one of the predefined HKEY_* constants. + sub_key: Py_UNICODE + A string that must be the name of a subkey of the key identified by + the key parameter. This value must not be None, and the key may not + have subkeys. + / + +Deletes the specified key. + +This method can not delete keys with subkeys. + +If the function succeeds, the entire key, including all of its values, +is removed. If the function fails, an OSError exception is raised. +[clinic start generated code]*/ + static PyObject * -PyDeleteKey(PyObject *self, PyObject *args) +winreg_DeleteKey_impl(PyModuleDef *module, HKEY key, Py_UNICODE *sub_key) +/*[clinic end generated code: output=875c8917dacbc99d input=b31d225b935e4211]*/ { - HKEY hKey; - PyObject *obKey; - wchar_t *subKey; long rc; - if (!PyArg_ParseTuple(args, "Ou:DeleteKey", &obKey, &subKey)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - rc = RegDeleteKeyW(hKey, subKey ); + rc = RegDeleteKeyW(key, sub_key ); if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKey"); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } +/*[clinic input] +winreg.DeleteKeyEx + + key: HKEY + An already open key, or any one of the predefined HKEY_* constants. + sub_key: Py_UNICODE + A string that must be the name of a subkey of the key identified by + the key parameter. This value must not be None, and the key may not + have subkeys. + access: REGSAM(c_default='KEY_WOW64_64KEY') = winreg.KEY_WOW64_64KEY + An integer that specifies an access mask that describes the + desired security access for the key. Default is KEY_WOW64_64KEY. + reserved: int = 0 + A reserved integer, and must be zero. Default is zero. + +Deletes the specified key (64-bit OS only). + +This method can not delete keys with subkeys. + +If the function succeeds, the entire key, including all of its values, +is removed. If the function fails, an OSError exception is raised. +On unsupported Windows versions, NotImplementedError is raised. +[clinic start generated code]*/ + static PyObject * -PyDeleteKeyEx(PyObject *self, PyObject *args, PyObject *kwargs) +winreg_DeleteKeyEx_impl(PyModuleDef *module, HKEY key, Py_UNICODE *sub_key, + REGSAM access, int reserved) +/*[clinic end generated code: output=0362a0ac6502379f input=711d9d89e7ecbed7]*/ { - HKEY hKey; - PyObject *key; HMODULE hMod; typedef LONG (WINAPI *RDKEFunc)(HKEY, const wchar_t*, REGSAM, int); RDKEFunc pfn = NULL; - wchar_t *sub_key; long rc; - int reserved = 0; - REGSAM access = KEY_WOW64_64KEY; - - char *kwlist[] = {"key", "sub_key", "access", "reserved", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Ou|ii:DeleteKeyEx", kwlist, - &key, &sub_key, &access, &reserved)) - return NULL; - if (!PyHKEY_AsHKEY(key, &hKey, FALSE)) - return NULL; /* Only available on 64bit platforms, so we must load it dynamically. */ @@ -1107,42 +966,60 @@ PyDeleteKeyEx(PyObject *self, PyObject *args, PyObject *kwargs) return NULL; } Py_BEGIN_ALLOW_THREADS - rc = (*pfn)(hKey, sub_key, access, reserved); + rc = (*pfn)(key, sub_key, access, reserved); Py_END_ALLOW_THREADS if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteKeyEx"); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } +/*[clinic input] +winreg.DeleteValue + + key: HKEY + An already open key, or any one of the predefined HKEY_* constants. + value: Py_UNICODE(accept={str, NoneType}) + A string that identifies the value to remove. + / + +Removes a named value from a registry key. +[clinic start generated code]*/ + static PyObject * -PyDeleteValue(PyObject *self, PyObject *args) +winreg_DeleteValue_impl(PyModuleDef *module, HKEY key, Py_UNICODE *value) +/*[clinic end generated code: output=308550b8cdcfd8e1 input=a78d3407a4197b21]*/ { - HKEY hKey; - PyObject *obKey; - wchar_t *subKey; long rc; - if (!PyArg_ParseTuple(args, "OZ:DeleteValue", &obKey, &subKey)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; Py_BEGIN_ALLOW_THREADS - rc = RegDeleteValueW(hKey, subKey); + rc = RegDeleteValueW(key, value); Py_END_ALLOW_THREADS if (rc !=ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegDeleteValue"); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } +/*[clinic input] +winreg.EnumKey + + key: HKEY + An already open key, or any one of the predefined HKEY_* constants. + index: int + An integer that identifies the index of the key to retrieve. + / + +Enumerates subkeys of an open registry key. + +The function retrieves the name of one subkey each time it is called. +It is typically called repeatedly until an OSError exception is +raised, indicating no more values are available. +[clinic start generated code]*/ + static PyObject * -PyEnumKey(PyObject *self, PyObject *args) +winreg_EnumKey_impl(PyModuleDef *module, HKEY key, int index) +/*[clinic end generated code: output=58074ffabbc67896 input=fad9a7c00ab0e04b]*/ { - HKEY hKey; - PyObject *obKey; - int index; long rc; PyObject *retStr; @@ -1155,13 +1032,8 @@ PyEnumKey(PyObject *self, PyObject *args) wchar_t tmpbuf[257]; DWORD len = sizeof(tmpbuf)/sizeof(wchar_t); /* includes NULL terminator */ - if (!PyArg_ParseTuple(args, "Oi:EnumKey", &obKey, &index)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - Py_BEGIN_ALLOW_THREADS - rc = RegEnumKeyExW(hKey, index, tmpbuf, &len, NULL, NULL, NULL, NULL); + rc = RegEnumKeyExW(key, index, tmpbuf, &len, NULL, NULL, NULL, NULL); Py_END_ALLOW_THREADS if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegEnumKeyEx"); @@ -1170,12 +1042,35 @@ PyEnumKey(PyObject *self, PyObject *args) return retStr; /* can be NULL */ } +/*[clinic input] +winreg.EnumValue + + key: HKEY + An already open key, or any one of the predefined HKEY_* constants. + index: int + An integer that identifies the index of the value to retrieve. + / + +Enumerates values of an open registry key. + +The function retrieves the name of one subkey each time it is called. +It is typically called repeatedly, until an OSError exception +is raised, indicating no more values. + +The result is a tuple of 3 items: + value_name + A string that identifies the value. + value_data + An object that holds the value data, and whose type depends + on the underlying registry type. + data_type + An integer that identifies the type of the value data. +[clinic start generated code]*/ + static PyObject * -PyEnumValue(PyObject *self, PyObject *args) +winreg_EnumValue_impl(PyModuleDef *module, HKEY key, int index) +/*[clinic end generated code: output=4570367ebaf0e979 input=4414f47a6fb238b5]*/ { - HKEY hKey; - PyObject *obKey; - int index; long rc; wchar_t *retValueBuf; BYTE *tmpBuf; @@ -1186,12 +1081,7 @@ PyEnumValue(PyObject *self, PyObject *args) PyObject *obData; PyObject *retVal; - if (!PyArg_ParseTuple(args, "Oi:EnumValue", &obKey, &index)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - - if ((rc = RegQueryInfoKeyW(hKey, NULL, NULL, NULL, NULL, NULL, NULL, + if ((rc = RegQueryInfoKeyW(key, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &retValueSize, &retDataSize, NULL, NULL)) != ERROR_SUCCESS) @@ -1201,7 +1091,7 @@ PyEnumValue(PyObject *self, PyObject *args) ++retDataSize; bufDataSize = retDataSize; bufValueSize = retValueSize; - retValueBuf = (wchar_t *)PyMem_Malloc(sizeof(wchar_t) * retValueSize); + retValueBuf = PyMem_New(wchar_t, retValueSize); if (retValueBuf == NULL) return PyErr_NoMemory(); retDataBuf = (BYTE *)PyMem_Malloc(retDataSize); @@ -1212,7 +1102,7 @@ PyEnumValue(PyObject *self, PyObject *args) while (1) { Py_BEGIN_ALLOW_THREADS - rc = RegEnumValueW(hKey, + rc = RegEnumValueW(key, index, retValueBuf, &retValueSize, @@ -1255,29 +1145,35 @@ PyEnumValue(PyObject *self, PyObject *args) return retVal; } +/*[clinic input] +winreg.ExpandEnvironmentStrings + + string: Py_UNICODE + / + +Expand environment vars. +[clinic start generated code]*/ + static PyObject * -PyExpandEnvironmentStrings(PyObject *self, PyObject *args) +winreg_ExpandEnvironmentStrings_impl(PyModuleDef *module, Py_UNICODE *string) +/*[clinic end generated code: output=4cb6914065a8663c input=b2a9714d2b751aa6]*/ { wchar_t *retValue = NULL; - wchar_t *src; DWORD retValueSize; DWORD rc; PyObject *o; - if (!PyArg_ParseTuple(args, "u:ExpandEnvironmentStrings", &src)) - return NULL; - - retValueSize = ExpandEnvironmentStringsW(src, retValue, 0); + retValueSize = ExpandEnvironmentStringsW(string, retValue, 0); if (retValueSize == 0) { return PyErr_SetFromWindowsErrWithFunction(retValueSize, "ExpandEnvironmentStrings"); } - retValue = (wchar_t *)PyMem_Malloc(retValueSize * sizeof(wchar_t)); + retValue = PyMem_New(wchar_t, retValueSize); if (retValue == NULL) { return PyErr_NoMemory(); } - rc = ExpandEnvironmentStringsW(src, retValue, retValueSize); + rc = ExpandEnvironmentStringsW(string, retValue, retValueSize); if (rc == 0) { PyMem_Free(retValue); return PyErr_SetFromWindowsErrWithFunction(retValueSize, @@ -1288,90 +1184,166 @@ PyExpandEnvironmentStrings(PyObject *self, PyObject *args) return o; } +/*[clinic input] +winreg.FlushKey + + key: HKEY + An already open key, or any one of the predefined HKEY_* constants. + / + +Writes all the attributes of a key to the registry. + +It is not necessary to call FlushKey to change a key. Registry changes +are flushed to disk by the registry using its lazy flusher. Registry +changes are also flushed to disk at system shutdown. Unlike +CloseKey(), the FlushKey() method returns only when all the data has +been written to the registry. + +An application should only call FlushKey() if it requires absolute +certainty that registry changes are on disk. If you don't know whether +a FlushKey() call is required, it probably isn't. +[clinic start generated code]*/ + static PyObject * -PyFlushKey(PyObject *self, PyObject *args) +winreg_FlushKey_impl(PyModuleDef *module, HKEY key) +/*[clinic end generated code: output=b9a7a6e405466420 input=f57457c12297d82f]*/ { - HKEY hKey; - PyObject *obKey; long rc; - if (!PyArg_ParseTuple(args, "O:FlushKey", &obKey)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; Py_BEGIN_ALLOW_THREADS - rc = RegFlushKey(hKey); + rc = RegFlushKey(key); Py_END_ALLOW_THREADS if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegFlushKey"); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } + + +/*[clinic input] +winreg.LoadKey + + key: HKEY + An already open key, or any one of the predefined HKEY_* constants. + sub_key: Py_UNICODE + A string that identifies the sub-key to load. + file_name: Py_UNICODE + The name of the file to load registry data from. This file must + have been created with the SaveKey() function. Under the file + allocation table (FAT) file system, the filename may not have an + extension. + / + +Insert data into the registry from a file. + +Creates a subkey under the specified key and stores registration +information from a specified file into that subkey. + +A call to LoadKey() fails if the calling process does not have the +SE_RESTORE_PRIVILEGE privilege. + +If key is a handle returned by ConnectRegistry(), then the path +specified in fileName is relative to the remote computer. + +The MSDN docs imply key must be in the HKEY_USER or HKEY_LOCAL_MACHINE +tree. +[clinic start generated code]*/ + static PyObject * -PyLoadKey(PyObject *self, PyObject *args) +winreg_LoadKey_impl(PyModuleDef *module, HKEY key, Py_UNICODE *sub_key, + Py_UNICODE *file_name) +/*[clinic end generated code: output=b8b700e39c695b90 input=e3b5b45ade311582]*/ { - HKEY hKey; - PyObject *obKey; - wchar_t *subKey; - wchar_t *fileName; - long rc; - if (!PyArg_ParseTuple(args, "Ouu:LoadKey", &obKey, &subKey, &fileName)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; + Py_BEGIN_ALLOW_THREADS - rc = RegLoadKeyW(hKey, subKey, fileName ); + rc = RegLoadKeyW(key, sub_key, file_name ); Py_END_ALLOW_THREADS if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegLoadKey"); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } -static PyObject * -PyOpenKey(PyObject *self, PyObject *args, PyObject *kwargs) +/*[clinic input] +winreg.OpenKey -> HKEY + + key: HKEY + An already open key, or any one of the predefined HKEY_* constants. + sub_key: Py_UNICODE(accept={str, NoneType}) + A string that identifies the sub_key to open. + reserved: int = 0 + A reserved integer that must be zero. Default is zero. + access: REGSAM(c_default='KEY_READ') = winreg.KEY_READ + An integer that specifies an access mask that describes the desired + security access for the key. Default is KEY_READ. + +Opens the specified key. + +The result is a new handle to the specified key. +If the function fails, an OSError exception is raised. +[clinic start generated code]*/ + +static HKEY +winreg_OpenKey_impl(PyModuleDef *module, HKEY key, Py_UNICODE *sub_key, + int reserved, REGSAM access) +/*[clinic end generated code: output=79818ea356490a55 input=098505ac36a9ae28]*/ { - HKEY hKey; - PyObject *key; - wchar_t *sub_key; - int reserved = 0; HKEY retKey; long rc; - REGSAM access = KEY_READ; - - char *kwlist[] = {"key", "sub_key", "reserved", "access", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OZ|ii:OpenKey", kwlist, - &key, &sub_key, &reserved, &access)) - return NULL; - if (!PyHKEY_AsHKEY(key, &hKey, FALSE)) - return NULL; Py_BEGIN_ALLOW_THREADS - rc = RegOpenKeyExW(hKey, sub_key, reserved, access, &retKey); + rc = RegOpenKeyExW(key, sub_key, reserved, access, &retKey); Py_END_ALLOW_THREADS - if (rc != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, "RegOpenKeyEx"); - return PyHKEY_FromHKEY(retKey); + if (rc != ERROR_SUCCESS) { + PyErr_SetFromWindowsErrWithFunction(rc, "RegOpenKeyEx"); + return NULL; + } + return retKey; +} + +/*[clinic input] +winreg.OpenKeyEx = winreg.OpenKey + +Opens the specified key. + +The result is a new handle to the specified key. +If the function fails, an OSError exception is raised. +[clinic start generated code]*/ + +static HKEY +winreg_OpenKeyEx_impl(PyModuleDef *module, HKEY key, Py_UNICODE *sub_key, + int reserved, REGSAM access) +/*[clinic end generated code: output=2dd9f29e84ea2dbc input=c6c4972af8622959]*/ +{ + return winreg_OpenKey_impl(module, key, sub_key, reserved, access); } +/*[clinic input] +winreg.QueryInfoKey + + key: HKEY + An already open key, or any one of the predefined HKEY_* constants. + / + +Returns information about a key. + +The result is a tuple of 3 items: +An integer that identifies the number of sub keys this key has. +An integer that identifies the number of values this key has. +An integer that identifies when the key was last modified (if available) +as 100's of nanoseconds since Jan 1, 1600. +[clinic start generated code]*/ static PyObject * -PyQueryInfoKey(PyObject *self, PyObject *args) +winreg_QueryInfoKey_impl(PyModuleDef *module, HKEY key) +/*[clinic end generated code: output=ae885222fe966a34 input=c3593802390cde1f]*/ { - HKEY hKey; - PyObject *obKey; long rc; DWORD nSubKeys, nValues; FILETIME ft; LARGE_INTEGER li; PyObject *l; PyObject *ret; - if (!PyArg_ParseTuple(args, "O:QueryInfoKey", &obKey)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - if ((rc = RegQueryInfoKey(hKey, NULL, NULL, 0, &nSubKeys, NULL, NULL, + + if ((rc = RegQueryInfoKey(key, NULL, NULL, 0, &nSubKeys, NULL, NULL, &nValues, NULL, NULL, NULL, &ft)) != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegQueryInfoKey"); @@ -1385,12 +1357,31 @@ PyQueryInfoKey(PyObject *self, PyObject *args) return ret; } +/*[clinic input] +winreg.QueryValue + + key: HKEY + An already open key, or any one of the predefined HKEY_* constants. + sub_key: Py_UNICODE(accept={str, NoneType}) + A string that holds the name of the subkey with which the value + is associated. If this parameter is None or empty, the function + retrieves the value set by the SetValue() method for the key + identified by key. + / + +Retrieves the unnamed value for a key. + +Values in the registry have name, type, and data components. This method +retrieves the data for a key's first value that has a NULL name. +But since the underlying API call doesn't return the type, you'll +probably be happier using QueryValueEx; this function is just here for +completeness. +[clinic start generated code]*/ + static PyObject * -PyQueryValue(PyObject *self, PyObject *args) +winreg_QueryValue_impl(PyModuleDef *module, HKEY key, Py_UNICODE *sub_key) +/*[clinic end generated code: output=f91cb6f623c3b65a input=41cafbbf423b21d6]*/ { - HKEY hKey; - PyObject *obKey; - wchar_t *subKey; long rc; PyObject *retStr; wchar_t *retBuf; @@ -1398,13 +1389,7 @@ PyQueryValue(PyObject *self, PyObject *args) DWORD retSize = 0; wchar_t *tmp; - if (!PyArg_ParseTuple(args, "OZ:QueryValue", &obKey, &subKey)) - return NULL; - - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - - rc = RegQueryValueW(hKey, subKey, NULL, &retSize); + rc = RegQueryValueW(key, sub_key, NULL, &retSize); if (rc == ERROR_MORE_DATA) retSize = 256; else if (rc != ERROR_SUCCESS) @@ -1418,7 +1403,7 @@ PyQueryValue(PyObject *self, PyObject *args) while (1) { retSize = bufSize; - rc = RegQueryValueW(hKey, subKey, retBuf, &retSize); + rc = RegQueryValueW(key, sub_key, retBuf, &retSize); if (rc != ERROR_MORE_DATA) break; @@ -1442,13 +1427,28 @@ PyQueryValue(PyObject *self, PyObject *args) return retStr; } + +/*[clinic input] +winreg.QueryValueEx + + key: HKEY + An already open key, or any one of the predefined HKEY_* constants. + name: Py_UNICODE(accept={str, NoneType}) + A string indicating the value to query. + / + +Retrieves the type and value of a specified sub-key. + +Behaves mostly like QueryValue(), but also returns the type of the +specified value name associated with the given open registry key. + +The return value is a tuple of the value and the type_id. +[clinic start generated code]*/ + static PyObject * -PyQueryValueEx(PyObject *self, PyObject *args) +winreg_QueryValueEx_impl(PyModuleDef *module, HKEY key, Py_UNICODE *name) +/*[clinic end generated code: output=a4b07f7807194f23 input=cf366cada4836891]*/ { - HKEY hKey; - PyObject *obKey; - wchar_t *valueName; - long rc; BYTE *retBuf, *tmp; DWORD bufSize = 0, retSize; @@ -1456,13 +1456,7 @@ PyQueryValueEx(PyObject *self, PyObject *args) PyObject *obData; PyObject *result; - if (!PyArg_ParseTuple(args, "OZ:QueryValueEx", &obKey, &valueName)) - return NULL; - - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - - rc = RegQueryValueExW(hKey, valueName, NULL, NULL, NULL, &bufSize); + rc = RegQueryValueExW(key, name, NULL, NULL, NULL, &bufSize); if (rc == ERROR_MORE_DATA) bufSize = 256; else if (rc != ERROR_SUCCESS) @@ -1474,7 +1468,7 @@ PyQueryValueEx(PyObject *self, PyObject *args) while (1) { retSize = bufSize; - rc = RegQueryValueExW(hKey, valueName, NULL, &typ, + rc = RegQueryValueExW(key, name, NULL, &typ, (BYTE *)retBuf, &retSize); if (rc != ERROR_MORE_DATA) break; @@ -1502,91 +1496,149 @@ PyQueryValueEx(PyObject *self, PyObject *args) return result; } +/*[clinic input] +winreg.SaveKey + + key: HKEY + An already open key, or any one of the predefined HKEY_* constants. + file_name: Py_UNICODE + The name of the file to save registry data to. This file cannot + already exist. If this filename includes an extension, it cannot be + used on file allocation table (FAT) file systems by the LoadKey(), + ReplaceKey() or RestoreKey() methods. + / + +Saves the specified key, and all its subkeys to the specified file. + +If key represents a key on a remote computer, the path described by +file_name is relative to the remote computer. + +The caller of this method must possess the SeBackupPrivilege +security privilege. This function passes NULL for security_attributes +to the API. +[clinic start generated code]*/ static PyObject * -PySaveKey(PyObject *self, PyObject *args) +winreg_SaveKey_impl(PyModuleDef *module, HKEY key, Py_UNICODE *file_name) +/*[clinic end generated code: output=33109b96bfabef8f input=da735241f91ac7a2]*/ { - HKEY hKey; - PyObject *obKey; - wchar_t *fileName; LPSECURITY_ATTRIBUTES pSA = NULL; long rc; - if (!PyArg_ParseTuple(args, "Ou:SaveKey", &obKey, &fileName)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; /* One day we may get security into the core? if (!PyWinObject_AsSECURITY_ATTRIBUTES(obSA, &pSA, TRUE)) return NULL; */ Py_BEGIN_ALLOW_THREADS - rc = RegSaveKeyW(hKey, fileName, pSA ); + rc = RegSaveKeyW(key, file_name, pSA ); Py_END_ALLOW_THREADS if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegSaveKey"); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } +/*[clinic input] +winreg.SetValue + + key: HKEY + An already open key, or any one of the predefined HKEY_* constants. + sub_key: Py_UNICODE(accept={str, NoneType}) + A string that names the subkey with which the value is associated. + type: DWORD + An integer that specifies the type of the data. Currently this must + be REG_SZ, meaning only strings are supported. + value: Py_UNICODE(zeroes=True) + A string that specifies the new value. + / + +Associates a value with a specified key. + +If the key specified by the sub_key parameter does not exist, the +SetValue function creates it. + +Value lengths are limited by available memory. Long values (more than +2048 bytes) should be stored as files with the filenames stored in +the configuration registry to help the registry perform efficiently. + +The key identified by the key parameter must have been opened with +KEY_SET_VALUE access. +[clinic start generated code]*/ + static PyObject * -PySetValue(PyObject *self, PyObject *args) +winreg_SetValue_impl(PyModuleDef *module, HKEY key, Py_UNICODE *sub_key, + DWORD type, Py_UNICODE *value, + Py_ssize_clean_t value_length) +/*[clinic end generated code: output=3c9c7c2769e8f953 input=2cd2adab79339c53]*/ { - HKEY hKey; - PyObject *obKey; - wchar_t *subKey; - wchar_t *str; - DWORD typ; - DWORD len; long rc; - if (!PyArg_ParseTuple(args, "OZiu#:SetValue", - &obKey, - &subKey, - &typ, - &str, - &len)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - if (typ != REG_SZ) { + + if (type != REG_SZ) { PyErr_SetString(PyExc_TypeError, "Type must be winreg.REG_SZ"); return NULL; } Py_BEGIN_ALLOW_THREADS - rc = RegSetValueW(hKey, subKey, REG_SZ, str, len+1); + rc = RegSetValueW(key, sub_key, REG_SZ, value, value_length+1); Py_END_ALLOW_THREADS if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegSetValue"); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } +/*[clinic input] +winreg.SetValueEx + + key: HKEY + An already open key, or any one of the predefined HKEY_* constants. + value_name: Py_UNICODE(accept={str, NoneType}) + A string containing the name of the value to set, or None. + reserved: object + Can be anything - zero is always passed to the API. + type: DWORD + An integer that specifies the type of the data, one of: + REG_BINARY -- Binary data in any form. + REG_DWORD -- A 32-bit number. + REG_DWORD_LITTLE_ENDIAN -- A 32-bit number in little-endian format. + REG_DWORD_BIG_ENDIAN -- A 32-bit number in big-endian format. + REG_EXPAND_SZ -- A null-terminated string that contains unexpanded + references to environment variables (for example, + %PATH%). + REG_LINK -- A Unicode symbolic link. + REG_MULTI_SZ -- An sequence of null-terminated strings, terminated + by two null characters. Note that Python handles + this termination automatically. + REG_NONE -- No defined value type. + REG_RESOURCE_LIST -- A device-driver resource list. + REG_SZ -- A null-terminated string. + value: object + A string that specifies the new value. + / + +Stores data in the value field of an open registry key. + +This method can also set additional value and type information for the +specified key. The key identified by the key parameter must have been +opened with KEY_SET_VALUE access. + +To open the key, use the CreateKeyEx() or OpenKeyEx() methods. + +Value lengths are limited by available memory. Long values (more than +2048 bytes) should be stored as files with the filenames stored in +the configuration registry to help the registry perform efficiently. +[clinic start generated code]*/ + static PyObject * -PySetValueEx(PyObject *self, PyObject *args) +winreg_SetValueEx_impl(PyModuleDef *module, HKEY key, Py_UNICODE *value_name, + PyObject *reserved, DWORD type, PyObject *value) +/*[clinic end generated code: output=ea092a935c361582 input=e73dec535ebeea7d]*/ { - HKEY hKey; - PyObject *obKey; - wchar_t *valueName; - PyObject *obRes; - PyObject *value; BYTE *data; DWORD len; - DWORD typ; LONG rc; - if (!PyArg_ParseTuple(args, "OZOiO:SetValueEx", - &obKey, - &valueName, - &obRes, - &typ, - &value)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - if (!Py2Reg(value, typ, &data, &len)) + if (!Py2Reg(value, type, &data, &len)) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_ValueError, @@ -1594,31 +1646,40 @@ PySetValueEx(PyObject *self, PyObject *args) return NULL; } Py_BEGIN_ALLOW_THREADS - rc = RegSetValueExW(hKey, valueName, 0, typ, data, len); + rc = RegSetValueExW(key, value_name, 0, type, data, len); Py_END_ALLOW_THREADS PyMem_DEL(data); if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegSetValueEx"); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } +/*[clinic input] +winreg.DisableReflectionKey + + key: HKEY + An already open key, or any one of the predefined HKEY_* constants. + / + +Disables registry reflection for 32bit processes running on a 64bit OS. + +Will generally raise NotImplemented if executed on a 32bit OS. + +If the key is not on the reflection list, the function succeeds but has +no effect. Disabling reflection for a key does not affect reflection +of any subkeys. +[clinic start generated code]*/ + static PyObject * -PyDisableReflectionKey(PyObject *self, PyObject *args) +winreg_DisableReflectionKey_impl(PyModuleDef *module, HKEY key) +/*[clinic end generated code: output=50fe6e2604324cdd input=a6c9e5ca5410193c]*/ { - HKEY hKey; - PyObject *obKey; HMODULE hMod; typedef LONG (WINAPI *RDRKFunc)(HKEY); RDRKFunc pfn = NULL; LONG rc; - if (!PyArg_ParseTuple(args, "O:DisableReflectionKey", &obKey)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - /* Only available on 64bit platforms, so we must load it dynamically.*/ hMod = GetModuleHandleW(L"advapi32.dll"); @@ -1631,30 +1692,37 @@ PyDisableReflectionKey(PyObject *self, PyObject *args) return NULL; } Py_BEGIN_ALLOW_THREADS - rc = (*pfn)(hKey); + rc = (*pfn)(key); Py_END_ALLOW_THREADS if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegDisableReflectionKey"); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } +/*[clinic input] +winreg.EnableReflectionKey + + key: HKEY + An already open key, or any one of the predefined HKEY_* constants. + / + +Restores registry reflection for the specified disabled key. + +Will generally raise NotImplemented if executed on a 32bit OS. +Restoring reflection for a key does not affect reflection of any +subkeys. +[clinic start generated code]*/ + static PyObject * -PyEnableReflectionKey(PyObject *self, PyObject *args) +winreg_EnableReflectionKey_impl(PyModuleDef *module, HKEY key) +/*[clinic end generated code: output=e3f23edb414f24a4 input=7748abbacd1e166a]*/ { - HKEY hKey; - PyObject *obKey; HMODULE hMod; typedef LONG (WINAPI *RERKFunc)(HKEY); RERKFunc pfn = NULL; LONG rc; - if (!PyArg_ParseTuple(args, "O:EnableReflectionKey", &obKey)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - /* Only available on 64bit platforms, so we must load it dynamically.*/ hMod = GetModuleHandleW(L"advapi32.dll"); @@ -1667,31 +1735,36 @@ PyEnableReflectionKey(PyObject *self, PyObject *args) return NULL; } Py_BEGIN_ALLOW_THREADS - rc = (*pfn)(hKey); + rc = (*pfn)(key); Py_END_ALLOW_THREADS if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, "RegEnableReflectionKey"); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } +/*[clinic input] +winreg.QueryReflectionKey + + key: HKEY + An already open key, or any one of the predefined HKEY_* constants. + / + +Returns the reflection state for the specified key as a bool. + +Will generally raise NotImplemented if executed on a 32bit OS. +[clinic start generated code]*/ + static PyObject * -PyQueryReflectionKey(PyObject *self, PyObject *args) +winreg_QueryReflectionKey_impl(PyModuleDef *module, HKEY key) +/*[clinic end generated code: output=2a49c564ca162e50 input=9f325eacb5a65d88]*/ { - HKEY hKey; - PyObject *obKey; HMODULE hMod; typedef LONG (WINAPI *RQRKFunc)(HKEY, BOOL *); RQRKFunc pfn = NULL; BOOL result; LONG rc; - if (!PyArg_ParseTuple(args, "O:QueryReflectionKey", &obKey)) - return NULL; - if (!PyHKEY_AsHKEY(obKey, &hKey, FALSE)) - return NULL; - /* Only available on 64bit platforms, so we must load it dynamically.*/ hMod = GetModuleHandleW(L"advapi32.dll"); @@ -1704,7 +1777,7 @@ PyQueryReflectionKey(PyObject *self, PyObject *args) return NULL; } Py_BEGIN_ALLOW_THREADS - rc = (*pfn)(hKey, &result); + rc = (*pfn)(key, &result); Py_END_ALLOW_THREADS if (rc != ERROR_SUCCESS) return PyErr_SetFromWindowsErrWithFunction(rc, @@ -1713,34 +1786,29 @@ PyQueryReflectionKey(PyObject *self, PyObject *args) } static struct PyMethodDef winreg_methods[] = { - {"CloseKey", PyCloseKey, METH_VARARGS, CloseKey_doc}, - {"ConnectRegistry", PyConnectRegistry, METH_VARARGS, ConnectRegistry_doc}, - {"CreateKey", PyCreateKey, METH_VARARGS, CreateKey_doc}, - {"CreateKeyEx", (PyCFunction)PyCreateKeyEx, - METH_VARARGS | METH_KEYWORDS, CreateKeyEx_doc}, - {"DeleteKey", PyDeleteKey, METH_VARARGS, DeleteKey_doc}, - {"DeleteKeyEx", (PyCFunction)PyDeleteKeyEx, - METH_VARARGS | METH_KEYWORDS, DeleteKeyEx_doc}, - {"DeleteValue", PyDeleteValue, METH_VARARGS, DeleteValue_doc}, - {"DisableReflectionKey", PyDisableReflectionKey, METH_VARARGS, DisableReflectionKey_doc}, - {"EnableReflectionKey", PyEnableReflectionKey, METH_VARARGS, EnableReflectionKey_doc}, - {"EnumKey", PyEnumKey, METH_VARARGS, EnumKey_doc}, - {"EnumValue", PyEnumValue, METH_VARARGS, EnumValue_doc}, - {"ExpandEnvironmentStrings", PyExpandEnvironmentStrings, METH_VARARGS, - ExpandEnvironmentStrings_doc }, - {"FlushKey", PyFlushKey, METH_VARARGS, FlushKey_doc}, - {"LoadKey", PyLoadKey, METH_VARARGS, LoadKey_doc}, - {"OpenKey", (PyCFunction)PyOpenKey, METH_VARARGS | METH_KEYWORDS, - OpenKey_doc}, - {"OpenKeyEx", (PyCFunction)PyOpenKey, METH_VARARGS | METH_KEYWORDS, - OpenKeyEx_doc}, - {"QueryValue", PyQueryValue, METH_VARARGS, QueryValue_doc}, - {"QueryValueEx", PyQueryValueEx, METH_VARARGS, QueryValueEx_doc}, - {"QueryInfoKey", PyQueryInfoKey, METH_VARARGS, QueryInfoKey_doc}, - {"QueryReflectionKey",PyQueryReflectionKey,METH_VARARGS, QueryReflectionKey_doc}, - {"SaveKey", PySaveKey, METH_VARARGS, SaveKey_doc}, - {"SetValue", PySetValue, METH_VARARGS, SetValue_doc}, - {"SetValueEx", PySetValueEx, METH_VARARGS, SetValueEx_doc}, + WINREG_CLOSEKEY_METHODDEF + WINREG_CONNECTREGISTRY_METHODDEF + WINREG_CREATEKEY_METHODDEF + WINREG_CREATEKEYEX_METHODDEF + WINREG_DELETEKEY_METHODDEF + WINREG_DELETEKEYEX_METHODDEF + WINREG_DELETEVALUE_METHODDEF + WINREG_DISABLEREFLECTIONKEY_METHODDEF + WINREG_ENABLEREFLECTIONKEY_METHODDEF + WINREG_ENUMKEY_METHODDEF + WINREG_ENUMVALUE_METHODDEF + WINREG_EXPANDENVIRONMENTSTRINGS_METHODDEF + WINREG_FLUSHKEY_METHODDEF + WINREG_LOADKEY_METHODDEF + WINREG_OPENKEY_METHODDEF + WINREG_OPENKEYEX_METHODDEF + WINREG_QUERYVALUE_METHODDEF + WINREG_QUERYVALUEEX_METHODDEF + WINREG_QUERYINFOKEY_METHODDEF + WINREG_QUERYREFLECTIONKEY_METHODDEF + WINREG_SAVEKEY_METHODDEF + WINREG_SETVALUE_METHODDEF + WINREG_SETVALUEEX_METHODDEF NULL, }; diff --git a/PC/winsound.c b/PC/winsound.c index b564eaba780c..8e77d1387e10 100644 --- a/PC/winsound.c +++ b/PC/winsound.c @@ -39,22 +39,6 @@ #include #include -PyDoc_STRVAR(sound_playsound_doc, -"PlaySound(sound, flags) - a wrapper around the Windows PlaySound API\n" -"\n" -"The sound argument can be a filename, data, or None.\n" -"For flag values, ored together, see module documentation."); - -PyDoc_STRVAR(sound_beep_doc, -"Beep(frequency, duration) - a wrapper around the Windows Beep API\n" -"\n" -"The frequency argument specifies frequency, in hertz, of the sound.\n" -"This parameter must be in the range 37 through 32,767.\n" -"The duration argument specifies the number of milliseconds.\n"); - -PyDoc_STRVAR(sound_msgbeep_doc, -"MessageBeep(x) - call Windows MessageBeep(x). x defaults to MB_OK."); - PyDoc_STRVAR(sound_module_doc, "PlaySound(sound, flags) - play a sound\n" "SND_FILENAME - sound is a wav file name\n" @@ -67,79 +51,112 @@ PyDoc_STRVAR(sound_module_doc, "SND_NOSTOP - Do not interrupt any sounds currently playing\n" // Raising RuntimeError if needed "SND_NOWAIT - Return immediately if the sound driver is busy\n" // Without any errors "\n" -"Beep(frequency, duration) - Make a beep through the PC speaker."); +"Beep(frequency, duration) - Make a beep through the PC speaker.\n" +"MessageBeep(x) - Call Windows MessageBeep."); + +/*[clinic input] +module winsound +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a18401142d97b8d5]*/ + +#include "clinic/winsound.c.h" + +/*[clinic input] +winsound.PlaySound + + sound: Py_UNICODE(accept={str, NoneType}) + The sound to play; a filename, data, or None. + flags: int + Flag values, ored together. See module documentation. + / + +A wrapper around the Windows PlaySound API. +[clinic start generated code]*/ static PyObject * -sound_playsound(PyObject *s, PyObject *args) +winsound_PlaySound_impl(PyModuleDef *module, Py_UNICODE *sound, int flags) +/*[clinic end generated code: output=614273784bf59e5c input=3411b1b7c1f36d93]*/ { - wchar_t *wsound; - int flags; int ok; - if (PyArg_ParseTuple(args, "Zi:PlaySound", &wsound, &flags)) { - if (flags & SND_ASYNC && flags & SND_MEMORY) { - /* Sidestep reference counting headache; unfortunately this also - prevent SND_LOOP from memory. */ - PyErr_SetString(PyExc_RuntimeError, "Cannot play asynchronously from memory"); - return NULL; - } - Py_BEGIN_ALLOW_THREADS - ok = PlaySoundW(wsound, NULL, flags); - Py_END_ALLOW_THREADS - if (!ok) { - PyErr_SetString(PyExc_RuntimeError, "Failed to play sound"); - return NULL; - } - Py_INCREF(Py_None); - return Py_None; + if (flags & SND_ASYNC && flags & SND_MEMORY) { + /* Sidestep reference counting headache; unfortunately this also + prevent SND_LOOP from memory. */ + PyErr_SetString(PyExc_RuntimeError, + "Cannot play asynchronously from memory"); + return NULL; } - return NULL; + + Py_BEGIN_ALLOW_THREADS + ok = PlaySoundW(sound, NULL, flags); + Py_END_ALLOW_THREADS + if (!ok) { + PyErr_SetString(PyExc_RuntimeError, "Failed to play sound"); + return NULL; + } + Py_RETURN_NONE; } +/*[clinic input] +winsound.Beep + + frequency: int + Frequency of the sound in hertz. + Must be in the range 37 through 32,767. + duration: int + How long the sound should play, in milliseconds. + / + +A wrapper around the Windows Beep API. +[clinic start generated code]*/ + static PyObject * -sound_beep(PyObject *self, PyObject *args) +winsound_Beep_impl(PyModuleDef *module, int frequency, int duration) +/*[clinic end generated code: output=c75f282035a872bd input=628a99d2ddf73798]*/ { - int freq; - int dur; BOOL ok; - if (!PyArg_ParseTuple(args, "ii:Beep", &freq, &dur)) - return NULL; - - if (freq < 37 || freq > 32767) { + if (frequency < 37 || frequency > 32767) { PyErr_SetString(PyExc_ValueError, "frequency must be in 37 thru 32767"); return NULL; } Py_BEGIN_ALLOW_THREADS - ok = Beep(freq, dur); + ok = Beep(frequency, duration); Py_END_ALLOW_THREADS if (!ok) { PyErr_SetString(PyExc_RuntimeError,"Failed to beep"); return NULL; } - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } +/*[clinic input] +winsound.MessageBeep + + x: int(c_default="MB_OK") = MB_OK + / + +Call Windows MessageBeep(x). + +x defaults to MB_OK. +[clinic start generated code]*/ + static PyObject * -sound_msgbeep(PyObject *self, PyObject *args) +winsound_MessageBeep_impl(PyModuleDef *module, int x) +/*[clinic end generated code: output=92aa6a822bdc66ad input=a776c8a85c9853f6]*/ { - int x = MB_OK; - if (!PyArg_ParseTuple(args, "|i:MessageBeep", &x)) - return NULL; MessageBeep(x); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } static struct PyMethodDef sound_methods[] = { - {"PlaySound", sound_playsound, METH_VARARGS, sound_playsound_doc}, - {"Beep", sound_beep, METH_VARARGS, sound_beep_doc}, - {"MessageBeep", sound_msgbeep, METH_VARARGS, sound_msgbeep_doc}, + WINSOUND_PLAYSOUND_METHODDEF + WINSOUND_BEEP_METHODDEF + WINSOUND_MESSAGEBEEP_METHODDEF {NULL, NULL} }; diff --git a/PCbuild/_bz2.vcxproj b/PCbuild/_bz2.vcxproj index 9387e54b3a8e..64c3dcde14fa 100644 --- a/PCbuild/_bz2.vcxproj +++ b/PCbuild/_bz2.vcxproj @@ -39,200 +39,34 @@ bz2 Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + + .pyd + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - $(bz2Dir);%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - - - 0x1D170000 - - - - - X64 - - - $(bz2Dir);%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - - - 0x1D170000 - - - - - $(bz2Dir);%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - - - 0x1D170000 - - - - - X64 - - - $(bz2Dir);%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - - - 0x1D170000 - - - - - $(bz2Dir);%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - - - 0x1D170000 - - - - - X64 - - - $(bz2Dir);%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - - - 0x1D170000 - MachineX64 - - - - - $(bz2Dir);%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - - - 0x1D170000 - - - - - X64 - + $(bz2Dir);%(AdditionalIncludeDirectories) WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) 0x1D170000 - MachineX64 diff --git a/PCbuild/_ctypes.vcxproj b/PCbuild/_ctypes.vcxproj index 202cb1f42bbb..68b8e2971d1b 100644 --- a/PCbuild/_ctypes.vcxproj +++ b/PCbuild/_ctypes.vcxproj @@ -39,204 +39,33 @@ _ctypes Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.40219.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - + ..\Modules\_ctypes\libffi_msvc;%(AdditionalIncludeDirectories) 0x1D1A0000 - - - - - X64 - - - ..\Modules\_ctypes\libffi_msvc;%(AdditionalIncludeDirectories) - - - 0x1D1A0000 - - - - - ..\Modules\_ctypes\libffi_msvc;%(AdditionalIncludeDirectories) - - - /EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE %(AdditionalOptions) - NotSet - 0x1D1A0000 - - - - - X64 - - - ..\Modules\_ctypes\libffi_msvc;%(AdditionalIncludeDirectories) - - /EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE %(AdditionalOptions) - NotSet - 0x1D1A0000 - - - - - ..\Modules\_ctypes\libffi_msvc;%(AdditionalIncludeDirectories) - - - /EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE %(AdditionalOptions) - NotSet - 0x1D1A0000 - - - - - X64 - - - ..\Modules\_ctypes\libffi_msvc;%(AdditionalIncludeDirectories) - - - /EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE %(AdditionalOptions) - NotSet - 0x1D1A0000 - MachineX64 - - - - - ..\Modules\_ctypes\libffi_msvc;%(AdditionalIncludeDirectories) - - - /EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE %(AdditionalOptions) - NotSet - 0x1D1A0000 - - - - - X64 - - - ..\Modules\_ctypes\libffi_msvc;%(AdditionalIncludeDirectories) - - - /EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE %(AdditionalOptions) - NotSet - 0x1D1A0000 - MachineX64 @@ -257,30 +86,14 @@ - true - true - true - true + true - true - ml64 /nologo /c /Zi /Fo "$(IntDir)win64.obj" "%(FullPath)" - - $(IntDir)win64.obj;%(Outputs) - true - ml64 /nologo /c /Fo "$(IntDir)win64.obj" "%(FullPath)" - - $(IntDir)win64.obj;%(Outputs) - true - ml64 /nologo /c /Fo "$(IntDir)win64.obj" "%(FullPath)" - - $(IntDir)win64.obj;%(Outputs) - true - ml64 /nologo /c /Fo "$(IntDir)win64.obj" "%(FullPath)" - - $(IntDir)win64.obj;%(Outputs) + true + ml64 /nologo /c /Zi /Fo "$(IntDir)win64.obj" "%(FullPath)" + $(IntDir)win64.obj;%(Outputs) diff --git a/PCbuild/_ctypes_test.vcxproj b/PCbuild/_ctypes_test.vcxproj index 35e299b8867a..c1260b53f3ec 100644 --- a/PCbuild/_ctypes_test.vcxproj +++ b/PCbuild/_ctypes_test.vcxproj @@ -38,143 +38,28 @@ {9EC7190A-249F-4180-A900-548FDCF3055F} _ctypes_test Win32Proj + false + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - X64 - - - - - X64 - - - - - X64 - - - MachineX64 - - - - - X64 - - - MachineX64 - - diff --git a/PCbuild/_decimal.vcxproj b/PCbuild/_decimal.vcxproj index 98ba81db234a..943bfb099034 100644 --- a/PCbuild/_decimal.vcxproj +++ b/PCbuild/_decimal.vcxproj @@ -39,206 +39,35 @@ _decimal Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.40219.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - /D_CRT_SECURE_NO_WARNINGS /DCONFIG_32 /DPPRO /DMASM %(AdditionalOptions) - ..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories) - - - 0x1D1A0000 - - - - - X64 - - - /D_CRT_SECURE_NO_WARNINGS /DCONFIG_64 /DMASM %(AdditionalOptions) - ..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories) - - - 0x1D1A0000 - - - - - /D_CRT_SECURE_NO_WARNINGS /DCONFIG_32 /DPPRO /DMASM %(AdditionalOptions) - ..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories) - - - NotSet - 0x1D1A0000 - - - - - X64 - - - /D_CRT_SECURE_NO_WARNINGS /DCONFIG_64 /DMASM %(AdditionalOptions) - ..\Modules\_decimal;..\Modules\_decimal\libmpdec;..\Include;..\PC;%(AdditionalIncludeDirectories) - - - NotSet - 0x1D1A0000 - - - - - /D_CRT_SECURE_NO_WARNINGS /DCONFIG_32 /DPPRO /DMASM %(AdditionalOptions) - ..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories) - - - NotSet - 0x1D1A0000 - - - - - X64 - - - /D_CRT_SECURE_NO_WARNINGS /DCONFIG_64 /DMASM %(AdditionalOptions) - ..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories) - - - NotSet - 0x1D1A0000 - MachineX64 - - - - - /D_CRT_SECURE_NO_WARNINGS /DCONFIG_32 /DPPRO /DMASM %(AdditionalOptions) - ..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories) - - - NotSet - 0x1D1A0000 - - - - - X64 - + - /D_CRT_SECURE_NO_WARNINGS /DCONFIG_64 /DMASM %(AdditionalOptions) + _CRT_SECURE_NO_WARNINGS;MASM;%(PreprocessorDefinitions) + CONFIG_32;PPRO;%(PreprocessorDefinitions) + CONFIG_64;%(PreprocessorDefinitions) ..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories) - NotSet 0x1D1A0000 - MachineX64 @@ -279,22 +108,9 @@ - true - ml64 /nologo /c /Zi /Fo "$(IntDir)vcdiv64.obj" "%(FullPath)" - - $(IntDir)vcdiv64.obj;%(Outputs) - true - ml64 /nologo /c /Fo "$(IntDir)vcdiv64.obj" "%(FullPath)" - - $(IntDir)vcdiv64.obj;%(Outputs) - true - ml64 /nologo /c /Fo "$(IntDir)vcdiv64.obj" "%(FullPath)" - - $(IntDir)vcdiv64.obj;%(Outputs) - true - ml64 /nologo /c /Zi /Fo "$(IntDir)vcdiv64.obj" "%(FullPath)" - - $(IntDir)vcdiv64.obj;%(Outputs) + true + ml64 /nologo /c /Zi /Fo "$(IntDir)vcdiv64.obj" "%(FullPath)" + $(IntDir)vcdiv64.obj;%(Outputs) diff --git a/PCbuild/_elementtree.vcxproj b/PCbuild/_elementtree.vcxproj index 7802ab30ae22..414bd8bebb82 100644 --- a/PCbuild/_elementtree.vcxproj +++ b/PCbuild/_elementtree.vcxproj @@ -39,200 +39,33 @@ _elementtree Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - ..\Modules\expat;%(AdditionalIncludeDirectories) - XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - 0x1D100000 - - - - - X64 - - - ..\Modules\expat;%(AdditionalIncludeDirectories) - XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - 0x1D100000 - - - - - ..\Modules\expat;%(AdditionalIncludeDirectories) - XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - 0x1D100000 - - - - - X64 - - - ..\Modules\expat;%(AdditionalIncludeDirectories) - XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - 0x1D100000 - - - - - ..\Modules\expat;%(AdditionalIncludeDirectories) - XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - 0x1D100000 - - - - - X64 - - - ..\Modules\expat;%(AdditionalIncludeDirectories) - XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - 0x1D100000 - MachineX64 - - - - - ..\Modules\expat;%(AdditionalIncludeDirectories) - XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - 0x1D100000 - - - - - X64 - + ..\Modules\expat;%(AdditionalIncludeDirectories) XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) 0x1D100000 - MachineX64 diff --git a/PCbuild/_freeze_importlib.vcxproj b/PCbuild/_freeze_importlib.vcxproj index 55197af8b281..f7714c003af9 100644 --- a/PCbuild/_freeze_importlib.vcxproj +++ b/PCbuild/_freeze_importlib.vcxproj @@ -9,6 +9,22 @@ Debug x64 + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + Release Win32 @@ -22,152 +38,32 @@ {19C0C13F-47CA-4432-AFF3-799A296A4DDC} Win32Proj _freeze_importlib + false + - - Application - true - Unicode - - - Application - true - Unicode - - - Application - false - true - Unicode - - + Application - false - true Unicode - - - - - - - - - - - - - - - - + - - - true - - - true - - - false - - - false - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - - - $(TargetPath) ..\Lib\importlib\_bootstrap.py ..\Python\importlib.h - - - creating importlib.h - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - - - $(TargetPath) ..\Lib\importlib\_bootstrap.py ..\Python\importlib.h - - - creating importlib.h - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - true - true - - - $(TargetPath) ..\Lib\importlib\_bootstrap.py ..\Python\importlib.h - - - creating importlib.h - - - + - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CONSOLE;%(PreprocessorDefinitions) Console - true - true - true - - $(TargetPath) ..\Lib\importlib\_bootstrap.py ..\Python\importlib.h - - - creating importlib.h - - + @@ -185,4 +81,26 @@ - \ No newline at end of file + + + + + <_OldContent Condition="Exists('$(PySourcePath)Python\importlib.h')">$([System.IO.File]::ReadAllText('$(PySourcePath)Python\importlib.h').Replace(` `, ` `)) + <_NewContent Condition="Exists('$(IntDir)importlib.g.h')">$([System.IO.File]::ReadAllText('$(IntDir)importlib.g.h').Replace(` `, ` `)) + + + + + + + + + + + + + diff --git a/PCbuild/_freeze_importlib.vcxproj.filters b/PCbuild/_freeze_importlib.vcxproj.filters index 50ec1933f38b..ccad053a9f53 100644 --- a/PCbuild/_freeze_importlib.vcxproj.filters +++ b/PCbuild/_freeze_importlib.vcxproj.filters @@ -15,7 +15,7 @@ - + Source Files @@ -24,4 +24,4 @@ Source Files - \ No newline at end of file + diff --git a/PCbuild/_hashlib.vcxproj b/PCbuild/_hashlib.vcxproj index 52433ed6969e..d82b266902a9 100644 --- a/PCbuild/_hashlib.vcxproj +++ b/PCbuild/_hashlib.vcxproj @@ -39,239 +39,47 @@ _hashlib Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - $(opensslDir)\inc32;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;$(opensslDir)\out32\libeay32.lib;$(opensslDir)\out32\ssleay32.lib;%(AdditionalDependencies) - - - - - X64 - - - $(opensslDir)\inc64;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;$(opensslDir)\out64\libeay32.lib;$(opensslDir)\out64\ssleay32.lib;%(AdditionalDependencies) - - - - - $(opensslDir)\inc32;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;$(opensslDir)\out32\libeay32.lib;$(opensslDir)\out32\ssleay32.lib;%(AdditionalDependencies) - - - - - X64 - - - $(opensslDir)\inc64;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;$(opensslDir)\out64\libeay32.lib;$(opensslDir)\out64\ssleay32.lib;%(AdditionalDependencies) - - - + - $(opensslDir)\inc32;%(AdditionalIncludeDirectories) + $(opensslDir)include;%(AdditionalIncludeDirectories) - - - - - ws2_32.lib;$(opensslDir)\out32\libeay32.lib;$(opensslDir)\out32\ssleay32.lib;%(AdditionalDependencies) - - - - - X64 - - - $(opensslDir)\inc64;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;$(opensslDir)\out64\libeay32.lib;$(opensslDir)\out64\ssleay32.lib;%(AdditionalDependencies) - MachineX64 - - - - - $(opensslDir)\inc32;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;$(opensslDir)\out32\libeay32.lib;$(opensslDir)\out32\ssleay32.lib;%(AdditionalDependencies) - - - - - X64 - - - $(opensslDir)\inc64;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;$(opensslDir)\out64\libeay32.lib;$(opensslDir)\out64\ssleay32.lib;%(AdditionalDependencies) - MachineX64 + ws2_32.lib;$(OutDir)libeay$(PyDebugExt).lib;$(OutDir)ssleay$(PyDebugExt).lib;%(AdditionalDependencies) - - {b11d750f-cd1f-4a96-85ce-e69a5c5259f9} - false - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} false - + + {10615b24-73bf-4efa-93aa-236916321317} + false + + {e5b04cc0-eb4c-42ab-b4dc-18ef95f864b0} false diff --git a/PCbuild/_lzma.vcxproj b/PCbuild/_lzma.vcxproj index ac25c804adde..af50494ebde6 100644 --- a/PCbuild/_lzma.vcxproj +++ b/PCbuild/_lzma.vcxproj @@ -39,200 +39,35 @@ lzma Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - $(lzmaDir)\include;%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) - - - $(lzmaDir)\bin_i486\liblzma.a;%(AdditionalDependencies) - - - - - X64 - - - $(lzmaDir)\include;%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) - - - $(lzmaDir)\bin_x86-64\liblzma.a;%(AdditionalDependencies) - - - - - $(lzmaDir)\include;%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) - - - $(lzmaDir)\bin_i486\liblzma.a;%(AdditionalDependencies) - - - - - X64 - - - $(lzmaDir)\include;%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) - - - $(lzmaDir)\bin_x86-64\liblzma.a;%(AdditionalDependencies) - - - - - $(lzmaDir)\include;%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) - - - $(lzmaDir)\bin_i486\liblzma.a;%(AdditionalDependencies) - - - - - X64 - - - $(lzmaDir)\include;%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) - - - $(lzmaDir)\bin_x86-64\liblzma.a;%(AdditionalDependencies) - MachineX64 - - - - - $(lzmaDir)\include;%(AdditionalIncludeDirectories) - WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) - - - $(lzmaDir)\bin_i486\liblzma.a;%(AdditionalDependencies) - - - - - X64 - + - $(lzmaDir)\include;%(AdditionalIncludeDirectories) + $(lzmaDir)include;%(AdditionalIncludeDirectories) WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) - $(lzmaDir)\bin_x86-64\liblzma.a;%(AdditionalDependencies) - MachineX64 + $(lzmaDir)\bin_i486\liblzma.a;%(AdditionalDependencies) + $(lzmaDir)\bin_x86-64\liblzma.a;%(AdditionalDependencies) + false diff --git a/PCbuild/_msi.vcxproj b/PCbuild/_msi.vcxproj index 1323d169df34..f5ba7bff7627 100644 --- a/PCbuild/_msi.vcxproj +++ b/PCbuild/_msi.vcxproj @@ -39,176 +39,30 @@ _msi Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - fci.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies) - 0x1D160000 - - - - - X64 - - - fci.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies) - 0x1D160000 - - - - - fci.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies) - 0x1D160000 - - - - - X64 - - - fci.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies) - 0x1D160000 - - - - - fci.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies) - 0x1D160000 - - - - - X64 - - - fci.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies) - 0x1D160000 - MachineX64 - - - - - fci.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies) - 0x1D160000 - - - - - X64 - + - fci.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies) + cabinet.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies) 0x1D160000 - MachineX64 diff --git a/PCbuild/_multiprocessing.vcxproj b/PCbuild/_multiprocessing.vcxproj index b4bb568538a5..1eb92b67dc24 100644 --- a/PCbuild/_multiprocessing.vcxproj +++ b/PCbuild/_multiprocessing.vcxproj @@ -39,176 +39,30 @@ _multiprocessing Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - MachineX64 - - - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - X64 - + ws2_32.lib;%(AdditionalDependencies) 0x1e1D0000 - MachineX64 diff --git a/PCbuild/_overlapped.vcxproj b/PCbuild/_overlapped.vcxproj index d0ee72fb5a13..55301ea9dc29 100644 --- a/PCbuild/_overlapped.vcxproj +++ b/PCbuild/_overlapped.vcxproj @@ -39,184 +39,30 @@ _overlapped Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - MachineX64 - - - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - + ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) 0x1D110000 - MachineX64 diff --git a/PCbuild/kill_python.vcxproj.filters b/PCbuild/_overlapped.vcxproj.filters similarity index 73% rename from PCbuild/kill_python.vcxproj.filters rename to PCbuild/_overlapped.vcxproj.filters index 433d75159687..78de89505590 100644 --- a/PCbuild/kill_python.vcxproj.filters +++ b/PCbuild/_overlapped.vcxproj.filters @@ -2,11 +2,11 @@ - {48606591-c8b6-41a5-95c5-9a0890c5504f} + {6f67c8db-7de7-4714-a967-2b0d4bc71f2e} - + Source Files diff --git a/PCbuild/_sha3.vcxproj b/PCbuild/_sha3.vcxproj deleted file mode 100644 index f24cbdc830d6..000000000000 --- a/PCbuild/_sha3.vcxproj +++ /dev/null @@ -1,218 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - PGInstrument - Win32 - - - PGInstrument - x64 - - - PGUpdate - Win32 - - - PGUpdate - x64 - - - Release - Win32 - - - Release - x64 - - - - {254A0C05-6696-4B08-8CB2-EF7D533AEE01} - _sha3 - Win32Proj - - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - - %(AdditionalDependencies) - - - - - X64 - - - %(AdditionalDependencies) - - - - - %(AdditionalDependencies) - - - - - X64 - - - %(AdditionalDependencies) - - - - - %(AdditionalDependencies) - - - - - X64 - - - %(AdditionalDependencies) - MachineX64 - - - - - %(AdditionalDependencies) - - - - - X64 - - - %(AdditionalDependencies) - MachineX64 - - - - - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} - false - - - - - - - - - \ No newline at end of file diff --git a/PCbuild/_socket.vcxproj b/PCbuild/_socket.vcxproj index 63836e9261cc..03b6f7558eb4 100644 --- a/PCbuild/_socket.vcxproj +++ b/PCbuild/_socket.vcxproj @@ -39,176 +39,30 @@ _socket Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - MachineX64 - - - - - ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 - - - - - X64 - + ws2_32.lib;%(AdditionalDependencies) 0x1e1D0000 - MachineX64 diff --git a/PCbuild/_sqlite3.vcxproj b/PCbuild/_sqlite3.vcxproj index ed35d5bc0c31..5e889d0de00f 100644 --- a/PCbuild/_sqlite3.vcxproj +++ b/PCbuild/_sqlite3.vcxproj @@ -39,200 +39,33 @@ _sqlite3 Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - $(sqlite3Dir);%(AdditionalIncludeDirectories) - MODULE_NAME="sqlite3";%(PreprocessorDefinitions) - - - 0x1e180000 - - - - - X64 - - - $(sqlite3Dir);%(AdditionalIncludeDirectories) - MODULE_NAME="sqlite3";%(PreprocessorDefinitions) - - - 0x1e180000 - - - - - $(sqlite3Dir);%(AdditionalIncludeDirectories) - MODULE_NAME="sqlite3";%(PreprocessorDefinitions) - - - 0x1e180000 - - - - - X64 - - - $(sqlite3Dir);%(AdditionalIncludeDirectories) - MODULE_NAME="sqlite3";%(PreprocessorDefinitions) - - - 0x1e180000 - - - - - $(sqlite3Dir);%(AdditionalIncludeDirectories) - MODULE_NAME="sqlite3";%(PreprocessorDefinitions) - - - 0x1e180000 - - - - - X64 - - - $(sqlite3Dir);%(AdditionalIncludeDirectories) - MODULE_NAME="sqlite3";%(PreprocessorDefinitions) - - - 0x1e180000 - MachineX64 - - - - - $(sqlite3Dir);%(AdditionalIncludeDirectories) - MODULE_NAME="sqlite3";%(PreprocessorDefinitions) - - - 0x1e180000 - - - - - X64 - + $(sqlite3Dir);%(AdditionalIncludeDirectories) MODULE_NAME="sqlite3";%(PreprocessorDefinitions) 0x1e180000 - MachineX64 diff --git a/PCbuild/_ssl.vcxproj b/PCbuild/_ssl.vcxproj index 7378794b3d9e..8594a0696602 100644 --- a/PCbuild/_ssl.vcxproj +++ b/PCbuild/_ssl.vcxproj @@ -39,242 +39,50 @@ _ssl Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - $(opensslDir)\inc32;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;crypt32.lib;$(opensslDir)\out32\libeay32.lib;$(opensslDir)\out32\ssleay32.lib;%(AdditionalDependencies) - - - - - X64 - - - $(opensslDir)\inc64;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;crypt32.lib;$(opensslDir)\out64\libeay32.lib;$(opensslDir)\out64\ssleay32.lib;%(AdditionalDependencies) - - - - - $(opensslDir)\inc32;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;crypt32.lib;$(opensslDir)\out32\libeay32.lib;$(opensslDir)\out32\ssleay32.lib;%(AdditionalDependencies) - - - - - X64 - - - $(opensslDir)\inc64;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;crypt32.lib;$(opensslDir)\out64\libeay32.lib;$(opensslDir)\out64\ssleay32.lib;%(AdditionalDependencies) - - - + - $(opensslDir)\inc32;%(AdditionalIncludeDirectories) + $(opensslDir)include;%(AdditionalIncludeDirectories) - - - - - ws2_32.lib;crypt32.lib;$(opensslDir)\out32\libeay32.lib;$(opensslDir)\out32\ssleay32.lib;%(AdditionalDependencies) - - - - - X64 - - - $(opensslDir)\inc64;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;crypt32.lib;$(opensslDir)\out64\libeay32.lib;$(opensslDir)\out64\ssleay32.lib;%(AdditionalDependencies) - MachineX64 - - - - - $(opensslDir)\inc32;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;crypt32.lib;$(opensslDir)\out32\libeay32.lib;$(opensslDir)\out32\ssleay32.lib;%(AdditionalDependencies) - - - - - X64 - - - $(opensslDir)\inc64;%(AdditionalIncludeDirectories) - - - - - - - ws2_32.lib;crypt32.lib;$(opensslDir)\out64\libeay32.lib;$(opensslDir)\out64\ssleay32.lib;%(AdditionalDependencies) - MachineX64 + ws2_32.lib;crypt32.lib;$(OutDir)libeay$(PyDebugExt).lib;$(OutDir)ssleay$(PyDebugExt).lib;%(AdditionalDependencies) - - {b11d750f-cd1f-4a96-85ce-e69a5c5259f9} - false - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} false - + {e5b04cc0-eb4c-42ab-b4dc-18ef95f864b0} false + + {10615b24-73bf-4efa-93aa-236916321317} + false + {86937f53-c189-40ef-8ce8-8759d8e7d480} false diff --git a/PCbuild/_testbuffer.vcxproj b/PCbuild/_testbuffer.vcxproj index e1265f684147..8cbf1251c365 100644 --- a/PCbuild/_testbuffer.vcxproj +++ b/PCbuild/_testbuffer.vcxproj @@ -38,169 +38,31 @@ {A2697BD3-28C1-4AEC-9106-8B748639FD16} _testbuffer Win32Proj + false + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.40219.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - 0x1e1F0000 - - - - - X64 - - - 0x1e1F0000 - - - - - 0x1e1F0000 - - - - - X64 - - - 0x1e1F0000 - - - - - 0x1e1F0000 - - - - - X64 - - - 0x1e1F0000 - MachineX64 - - - - - 0x1e1F0000 - - - - - X64 - + 0x1e1F0000 - MachineX64 diff --git a/PCbuild/_testcapi.vcxproj b/PCbuild/_testcapi.vcxproj index e99a7e4f3fe0..dbf44e6e9414 100644 --- a/PCbuild/_testcapi.vcxproj +++ b/PCbuild/_testcapi.vcxproj @@ -38,169 +38,31 @@ {6901D91C-6E48-4BB7-9FEC-700C8131DF1D} _testcapi Win32Proj + false + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - 0x1e1F0000 - - - - - X64 - - - 0x1e1F0000 - - - - - 0x1e1F0000 - - - - - X64 - - - 0x1e1F0000 - - - - - 0x1e1F0000 - - - - - X64 - - - 0x1e1F0000 - MachineX64 - - - - - 0x1e1F0000 - - - - - X64 - + 0x1e1F0000 - MachineX64 diff --git a/PCbuild/_testembed.vcxproj b/PCbuild/_testembed.vcxproj index 83c7ad21e720..f0e4d9f87465 100644 --- a/PCbuild/_testembed.vcxproj +++ b/PCbuild/_testembed.vcxproj @@ -9,6 +9,22 @@ Debug x64 + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + Release Win32 @@ -22,137 +38,37 @@ {6DAC66D9-E703-4624-BE03-49112AB5AA62} Win32Proj _testembed + false + - - Application - true - Unicode - - - Application - true - Unicode - - - Application - false - true - Unicode - - + Application - false - true Unicode - - - - - - - - - - - - - - - - + - - - false - - - false - - - false - - - false - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - - - Console - true - true - true - - - + - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _CONSOLE;%(PreprocessorDefinitions) Console - true - true - true - + {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} - true - true - false - true - false + false diff --git a/PCbuild/_testembed.vcxproj.filters b/PCbuild/_testembed.vcxproj.filters index dea54d4ad46e..f7f9abeb1dfa 100644 --- a/PCbuild/_testembed.vcxproj.filters +++ b/PCbuild/_testembed.vcxproj.filters @@ -15,7 +15,7 @@ - + Source Files diff --git a/PCbuild/_testimportmultiple.vcxproj b/PCbuild/_testimportmultiple.vcxproj index 84984ff2f704..cec042c202c6 100644 --- a/PCbuild/_testimportmultiple.vcxproj +++ b/PCbuild/_testimportmultiple.vcxproj @@ -38,169 +38,31 @@ {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781} _testimportmultiple Win32Proj + false + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - 0x1e1F0000 - - - - - X64 - - - 0x1e1F0000 - - - - - 0x1e1F0000 - - - - - X64 - - - 0x1e1F0000 - - - - - 0x1e1F0000 - - - - - X64 - - - 0x1e1F0000 - MachineX64 - - - - - 0x1e1F0000 - - - - - X64 - + 0x1e1F0000 - MachineX64 diff --git a/PCbuild/_testmultiphase.vcxproj b/PCbuild/_testmultiphase.vcxproj new file mode 100644 index 000000000000..647b38029de9 --- /dev/null +++ b/PCbuild/_testmultiphase.vcxproj @@ -0,0 +1,80 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Release + Win32 + + + Release + x64 + + + + {16BFE6F0-22EF-40B5-B831-7E937119EF10} + Win32Proj + _testmultiphase + false + + + + + DynamicLibrary + NotSet + + + + .pyd + + + + + + + + + + + _CONSOLE;%(PreprocessorDefinitions) + + + Console + + + + + + + + {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} + false + + + + + + \ No newline at end of file diff --git a/PCbuild/_testmultiphase.vcxproj.filters b/PCbuild/_testmultiphase.vcxproj.filters new file mode 100644 index 000000000000..0c25101e1b4f --- /dev/null +++ b/PCbuild/_testmultiphase.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/PCbuild/_tkinter.vcxproj b/PCbuild/_tkinter.vcxproj index 67f72fe38b69..f3185eb28b8c 100644 --- a/PCbuild/_tkinter.vcxproj +++ b/PCbuild/_tkinter.vcxproj @@ -39,202 +39,36 @@ _tkinter Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - + - $(tcltkDir)\include;%(AdditionalIncludeDirectories) - WITH_APPINIT;%(PreprocessorDefinitions) - - - $(tcltkLibDebug);%(AdditionalDependencies) - - - - - X64 - - - $(tcltk64Dir)\include;%(AdditionalIncludeDirectories) - WITH_APPINIT;%(PreprocessorDefinitions) - - - $(tcltk64LibDebug);%(AdditionalDependencies) - - - - - $(tcltkDir)\include;%(AdditionalIncludeDirectories) + $(tcltkDir)include;%(AdditionalIncludeDirectories) WITH_APPINIT;%(PreprocessorDefinitions) + Py_TCLTK_DIR="$(tcltkDir.TrimEnd('\').Replace('\', '\\'))";%(PreprocessorDefinitions) $(tcltkLib);%(AdditionalDependencies) - - - X64 - - - $(tcltk64Dir)\include;%(AdditionalIncludeDirectories) - WITH_APPINIT;%(PreprocessorDefinitions) - - - $(tcltk64Lib);%(AdditionalDependencies) - - - - - $(tcltkDir)\include;%(AdditionalIncludeDirectories) - WITH_APPINIT;%(PreprocessorDefinitions) - - - $(tcltkLib);%(AdditionalDependencies) - - - - - X64 - - - $(tcltk64Dir)\include;%(AdditionalIncludeDirectories) - WITH_APPINIT;%(PreprocessorDefinitions) - - - $(tcltk64Lib);%(AdditionalDependencies) - MachineX64 - - - - - $(tcltkDir)\include;%(AdditionalIncludeDirectories) - WITH_APPINIT;%(PreprocessorDefinitions) - - - $(tcltkLib);%(AdditionalDependencies) - - - - - X64 - - - $(tcltk64Dir)\include;%(AdditionalIncludeDirectories) - WITH_APPINIT;%(PreprocessorDefinitions) - - - $(tcltk64Lib);%(AdditionalDependencies) - MachineX64 - - @@ -244,6 +78,12 @@ {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} false + + {b5fd6f1d-129e-4bff-9340-03606fac7283} + + + {7e85eccf-a72c-4da4-9e52-884508e80ba1} + diff --git a/PCbuild/bdist_wininst.vcxproj b/PCbuild/bdist_wininst.vcxproj deleted file mode 100644 index 49276a2e41e2..000000000000 --- a/PCbuild/bdist_wininst.vcxproj +++ /dev/null @@ -1,158 +0,0 @@ - - - - - Release - Win32 - - - Release - x64 - - - - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C} - wininst - - - - Application - false - NotSet - - - Application - false - NotSet - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - ..\lib\distutils\command\ - false - ..\lib\distutils\command\ - $(SolutionDir)$(PlatformName)-temp-$(Configuration)\$(ProjectName)\ - false - AllRules.ruleset - - - AllRules.ruleset - - - .exe - .exe - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - Win32 - .\..\lib\distutils\command\wininst.tlb - - - - - MinSpace - OnlyExplicitInline - ..\PC\bdist_wininst;..\Include;..\Modules\zlib;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - true - MultiThreaded - true - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0000 - ..\PC;..\PC\bdist_wininst;..\Include;%(AdditionalIncludeDirectories) - - - comctl32.lib;imagehlp.lib;%(AdditionalDependencies) - ..\lib\distutils\command\wininst-10.0.exe - true - LIBC;%(IgnoreSpecificDefaultLibraries) - ..\lib\distutils\command\wininst-10.0.pdb - Windows - false - - - MachineX86 - - - - - NDEBUG;%(PreprocessorDefinitions) - true - true - X64 - .\..\lib\distutils\command\wininst.tlb - - - - - MinSpace - OnlyExplicitInline - ..\PC\bdist_wininst;..\Include;..\Modules\zlib;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) - true - MultiThreaded - true - Level3 - true - - - NDEBUG;%(PreprocessorDefinitions) - 0x0000 - ..\PC;..\PC\bdist_wininst;..\Include;%(AdditionalIncludeDirectories) - - - comctl32.lib;imagehlp.lib;%(AdditionalDependencies) - ..\lib\distutils\command\wininst-10.0-amd64.exe - true - LIBC;%(IgnoreSpecificDefaultLibraries) - ..\lib\distutils\command\wininst-9.0-amd64.pdb - Windows - false - - - MachineX64 - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/PCbuild/build.bat b/PCbuild/build.bat index fa0d95b0cc03..2c41fb21eb2d 100644 --- a/PCbuild/build.bat +++ b/PCbuild/build.bat @@ -1,19 +1,102 @@ -@echo off -rem A batch program to build or rebuild a particular configuration. -rem just for convenience. - -setlocal -set platf=Win32 -set conf=Release -set target=build -set dir=%~dp0 - -:CheckOpts -if "%1"=="-c" (set conf=%2) & shift & shift & goto CheckOpts -if "%1"=="-p" (set platf=%2) & shift & shift & goto CheckOpts -if "%1"=="-r" (set target=rebuild) & shift & goto CheckOpts -if "%1"=="-d" (set conf=Debug) & shift & goto CheckOpts - -set cmd=msbuild /p:useenv=true %dir%pcbuild.sln /t:%target% /p:Configuration=%conf% /p:Platform=%platf% -echo %cmd% -%cmd% +@echo off +goto Run +:Usage +echo.%~nx0 [flags and arguments] [quoted MSBuild options] +echo. +echo.Build CPython from the command line. Requires the appropriate +echo.version(s) of Microsoft Visual Studio to be installed (see readme.txt). +echo.Also requires Subversion (svn.exe) to be on PATH if the '-e' flag is +echo.given. +echo. +echo.After the flags recognized by this script, up to 9 arguments to be passed +echo.directly to MSBuild may be passed. If the argument contains an '=', the +echo.entire argument must be quoted (e.g. `%~nx0 "/p:PlatformToolset=v100"`) +echo. +echo.Available flags: +echo. -h Display this help message +echo. -V Display version information for the current build +echo. -r Target Rebuild instead of Build +echo. -d Set the configuration to Debug +echo. -e Build external libraries fetched by get_externals.bat +echo. Extension modules that depend on external libraries will not attempt +echo. to build if this flag is not present +echo. -m Enable parallel build (enabled by default) +echo. -M Disable parallel build +echo. -v Increased output messages +echo. -k Attempt to kill any running Pythons before building (usually done +echo. automatically by the pythoncore project) +echo. +echo.Available flags to avoid building certain modules. +echo.These flags have no effect if '-e' is not given: +echo. --no-ssl Do not attempt to build _ssl +echo. --no-tkinter Do not attempt to build Tkinter +echo. +echo.Available arguments: +echo. -c Release ^| Debug ^| PGInstrument ^| PGUpdate +echo. Set the configuration (default: Release) +echo. -p x64 ^| Win32 +echo. Set the platform (default: Win32) +echo. -t Build ^| Rebuild ^| Clean ^| CleanAll +echo. Set the target manually +exit /b 127 + +:Run +setlocal +set platf=Win32 +set vs_platf=x86 +set conf=Release +set target=Build +set dir=%~dp0 +set parallel=/m +set verbose=/nologo /v:m +set kill= + +:CheckOpts +if "%~1"=="-h" goto Usage +if "%~1"=="-c" (set conf=%2) & shift & shift & goto CheckOpts +if "%~1"=="-p" (set platf=%2) & shift & shift & goto CheckOpts +if "%~1"=="-r" (set target=Rebuild) & shift & goto CheckOpts +if "%~1"=="-t" (set target=%2) & shift & shift & goto CheckOpts +if "%~1"=="-d" (set conf=Debug) & shift & goto CheckOpts +if "%~1"=="-m" (set parallel=/m) & shift & goto CheckOpts +if "%~1"=="-M" (set parallel=) & shift & goto CheckOpts +if "%~1"=="-v" (set verbose=/v:n) & shift & goto CheckOpts +if "%~1"=="-k" (set kill=true) & shift & goto CheckOpts +if "%~1"=="-V" shift & goto Version +rem These use the actual property names used by MSBuild. We could just let +rem them in through the environment, but we specify them on the command line +rem anyway for visibility so set defaults after this +if "%~1"=="-e" (set IncludeExternals=true) & shift & goto CheckOpts +if "%~1"=="--no-ssl" (set IncludeSSL=false) & shift & goto CheckOpts +if "%~1"=="--no-tkinter" (set IncludeTkinter=false) & shift & goto CheckOpts + +if "%IncludeExternals%"=="" set IncludeExternals=false +if "%IncludeSSL%"=="" set IncludeSSL=true +if "%IncludeTkinter%"=="" set IncludeTkinter=true + +if "%IncludeExternals%"=="true" call "%dir%get_externals.bat" + +if "%platf%"=="x64" (set vs_platf=x86_amd64) + +rem Setup the environment +call "%dir%env.bat" %vs_platf% >nul + +if "%kill%"=="true" ( + msbuild /v:m /nologo /target:KillPython "%dir%\pythoncore.vcxproj" /p:Configuration=%conf% /p:Platform=%platf% /p:KillPython=true +) + +rem Call on MSBuild to do the work, echo the command. +rem Passing %1-9 is not the preferred option, but argument parsing in +rem batch is, shall we say, "lackluster" +echo on +msbuild "%dir%pcbuild.proj" /t:%target% %parallel% %verbose%^ + /p:Configuration=%conf% /p:Platform=%platf%^ + /p:IncludeExternals=%IncludeExternals%^ + /p:IncludeSSL=%IncludeSSL% /p:IncludeTkinter=%IncludeTkinter%^ + %1 %2 %3 %4 %5 %6 %7 %8 %9 + +@goto :eof + +:Version +rem Display the current build version information +msbuild "%dir%python.props" /t:ShowVersionInfo /v:m /nologo %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/PCbuild/build_env.bat b/PCbuild/build_env.bat index 4c67ae3ac253..01024cff215d 100644 --- a/PCbuild/build_env.bat +++ b/PCbuild/build_env.bat @@ -1 +1 @@ -@%comspec% /k env.bat %* +@%comspec% /k env.bat %* diff --git a/PCbuild/build_pgo.bat b/PCbuild/build_pgo.bat index 0c0a473b2c45..79ec2670b043 100644 --- a/PCbuild/build_pgo.bat +++ b/PCbuild/build_pgo.bat @@ -1,41 +1,48 @@ -@echo off -rem A batch program to build PGO (Profile guided optimization) by first -rem building instrumented binaries, then running the testsuite, and -rem finally building the optimized code. -rem Note, after the first instrumented run, one can just keep on -rem building the PGUpdate configuration while developing. - -setlocal -set platf=Win32 - -rem use the performance testsuite. This is quick and simple -set job1=..\tools\pybench\pybench.py -n 1 -C 1 --with-gc -set path1=..\tools\pybench - -rem or the whole testsuite for more thorough testing -set job2=..\lib\test\regrtest.py -set path2=..\lib - -set job=%job1% -set clrpath=%path1% - -:CheckOpts -if "%1"=="-p" (set platf=%2) & shift & shift & goto CheckOpts -if "%1"=="-2" (set job=%job2%) & (set clrpath=%path2%) & shift & goto CheckOpts - -set PGI=%platf%-pgi -set PGO=%platf%-pgo - -@echo on -rem build the instrumented version -call build -p %platf% -c PGInstrument - -rem remove .pyc files, .pgc files and execute the job -%PGI%\python.exe rmpyc.py %clrpath% -del %PGI%\*.pgc -%PGI%\python.exe %job% - -rem finally build the optimized version -if exist %PGO% del /s /q %PGO% -call build -p %platf% -c PGUpdate - +@echo off +rem A batch program to build PGO (Profile guided optimization) by first +rem building instrumented binaries, then running the testsuite, and +rem finally building the optimized code. +rem Note, after the first instrumented run, one can just keep on +rem building the PGUpdate configuration while developing. + +setlocal +set platf=Win32 +set parallel=/m +set dir=%~dp0 + +rem use the performance testsuite. This is quick and simple +set job1="%dir%..\tools\pybench\pybench.py" -n 1 -C 1 --with-gc +set path1="%dir%..\tools\pybench" + +rem or the whole testsuite for more thorough testing +set job2="%dir%..\lib\test\regrtest.py" +set path2="%dir%..\lib" + +set job=%job1% +set clrpath=%path1% + +:CheckOpts +if "%1"=="-p" (set platf=%2) & shift & shift & goto CheckOpts +if "%1"=="-2" (set job=%job2%) & (set clrpath=%path2%) & shift & goto CheckOpts +if "%1"=="-M" (set parallel=) & shift & goto CheckOpts + + +rem We cannot cross compile PGO builds, as the optimization needs to be run natively +set vs_platf=x86 +set PGO=%dir%win32-pgo + +if "%platf%"=="x64" (set vs_platf=amd64) & (set PGO=%dir%amd64-pgo) +rem Setup the environment +call "%dir%env.bat" %vs_platf% + + +rem build the instrumented version +msbuild "%dir%pcbuild.proj" %parallel% /t:Build /p:Configuration=PGInstrument /p:Platform=%platf% %1 %2 %3 %4 %5 %6 %7 %8 %9 + +rem remove .pyc files, .pgc files and execute the job +"%PGO%\python.exe" "%dir%rmpyc.py" %clrpath% +del "%PGO%\*.pgc" +"%PGO%\python.exe" %job% + +rem build optimized version +msbuild "%dir%pcbuild.proj" %parallel% /t:Build /p:Configuration=PGUpdate /p:Platform=%platf% %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/PCbuild/build_ssl.py b/PCbuild/build_ssl.py deleted file mode 100644 index 5a7a89e4ec9b..000000000000 --- a/PCbuild/build_ssl.py +++ /dev/null @@ -1,253 +0,0 @@ -# Script for building the _ssl and _hashlib modules for Windows. -# Uses Perl to setup the OpenSSL environment correctly -# and build OpenSSL, then invokes a simple nmake session -# for the actual _ssl.pyd and _hashlib.pyd DLLs. - -# THEORETICALLY, you can: -# * Unpack the latest SSL release one level above your main Python source -# directory. It is likely you will already find the zlib library and -# any other external packages there. -# * Install ActivePerl and ensure it is somewhere on your path. -# * Run this script from the PCBuild directory. -# -# it should configure and build SSL, then build the _ssl and _hashlib -# Python extensions without intervention. - -# Modified by Christian Heimes -# Now this script supports pre-generated makefiles and assembly files. -# Developers don't need an installation of Perl anymore to build Python. A svn -# checkout from our svn repository is enough. -# -# In Order to create the files in the case of an update you still need Perl. -# Run build_ssl in this order: -# python.exe build_ssl.py Release x64 -# python.exe build_ssl.py Release Win32 - -import os, sys, re, shutil - -# Find all "foo.exe" files on the PATH. -def find_all_on_path(filename, extras = None): - entries = os.environ["PATH"].split(os.pathsep) - ret = [] - for p in entries: - fname = os.path.abspath(os.path.join(p, filename)) - if os.path.isfile(fname) and fname not in ret: - ret.append(fname) - if extras: - for p in extras: - fname = os.path.abspath(os.path.join(p, filename)) - if os.path.isfile(fname) and fname not in ret: - ret.append(fname) - return ret - -# Find a suitable Perl installation for OpenSSL. -# cygwin perl does *not* work. ActivePerl does. -# Being a Perl dummy, the simplest way I can check is if the "Win32" package -# is available. -def find_working_perl(perls): - for perl in perls: - fh = os.popen('"%s" -e "use Win32;"' % perl) - fh.read() - rc = fh.close() - if rc: - continue - return perl - print("Can not find a suitable PERL:") - if perls: - print(" the following perl interpreters were found:") - for p in perls: - print(" ", p) - print(" None of these versions appear suitable for building OpenSSL") - else: - print(" NO perl interpreters were found on this machine at all!") - print(" Please install ActivePerl and ensure it appears on your path") - return None - -# Fetch SSL directory from VC properties -def get_ssl_dir(): - propfile = (os.path.join(os.path.dirname(__file__), 'pyproject.props')) - with open(propfile) as f: - m = re.search('openssl-([^<]+)<', f.read()) - return "..\..\openssl-"+m.group(1) - - -def create_makefile64(makefile, m32): - """Create and fix makefile for 64bit - - Replace 32 with 64bit directories - """ - if not os.path.isfile(m32): - return - with open(m32) as fin: - with open(makefile, 'w') as fout: - for line in fin: - line = line.replace("=tmp32", "=tmp64") - line = line.replace("=out32", "=out64") - line = line.replace("=inc32", "=inc64") - # force 64 bit machine - line = line.replace("MKLIB=lib", "MKLIB=lib /MACHINE:X64") - line = line.replace("LFLAGS=", "LFLAGS=/MACHINE:X64 ") - # don't link against the lib on 64bit systems - line = line.replace("bufferoverflowu.lib", "") - fout.write(line) - os.unlink(m32) - -def fix_makefile(makefile): - """Fix some stuff in all makefiles - """ - if not os.path.isfile(makefile): - return - with open(makefile) as fin: - lines = fin.readlines() - with open(makefile, 'w') as fout: - for line in lines: - if line.startswith("PERL="): - continue - if line.startswith("CP="): - line = "CP=copy\n" - if line.startswith("MKDIR="): - line = "MKDIR=mkdir\n" - if line.startswith("CFLAG="): - line = line.strip() - for algo in ("RC5", "MDC2", "IDEA"): - noalgo = " -DOPENSSL_NO_%s" % algo - if noalgo not in line: - line = line + noalgo - line = line + '\n' - fout.write(line) - -def run_configure(configure, do_script): - print("perl Configure "+configure+" no-idea no-mdc2") - os.system("perl Configure "+configure+" no-idea no-mdc2") - print(do_script) - os.system(do_script) - -def cmp(f1, f2): - bufsize = 1024 * 8 - with open(f1, 'rb') as fp1, open(f2, 'rb') as fp2: - while True: - b1 = fp1.read(bufsize) - b2 = fp2.read(bufsize) - if b1 != b2: - return False - if not b1: - return True - -def copy(src, dst): - if os.path.isfile(dst) and cmp(src, dst): - return - shutil.copy(src, dst) - -def main(): - build_all = "-a" in sys.argv - if sys.argv[1] == "Release": - debug = False - elif sys.argv[1] == "Debug": - debug = True - else: - raise ValueError(str(sys.argv)) - - if sys.argv[2] == "Win32": - arch = "x86" - configure = "VC-WIN32" - do_script = "ms\\do_nasm" - makefile="ms\\nt.mak" - m32 = makefile - dirsuffix = "32" - elif sys.argv[2] == "x64": - arch="amd64" - configure = "VC-WIN64A" - do_script = "ms\\do_win64a" - makefile = "ms\\nt64.mak" - m32 = makefile.replace('64', '') - dirsuffix = "64" - #os.environ["VSEXTCOMP_USECL"] = "MS_OPTERON" - else: - raise ValueError(str(sys.argv)) - - make_flags = "" - if build_all: - make_flags = "-a" - # perl should be on the path, but we also look in "\perl" and "c:\\perl" - # as "well known" locations - perls = find_all_on_path("perl.exe", ["\\perl\\bin", "C:\\perl\\bin"]) - perl = find_working_perl(perls) - if perl: - print("Found a working perl at '%s'" % (perl,)) - else: - print("No Perl installation was found. Existing Makefiles are used.") - sys.stdout.flush() - # Look for SSL 2 levels up from pcbuild - ie, same place zlib etc all live. - ssl_dir = get_ssl_dir() - if ssl_dir is None: - sys.exit(1) - - old_cd = os.getcwd() - try: - os.chdir(ssl_dir) - # rebuild makefile when we do the role over from 32 to 64 build - if arch == "amd64" and os.path.isfile(m32) and not os.path.isfile(makefile): - os.unlink(m32) - - # If the ssl makefiles do not exist, we invoke Perl to generate them. - # Due to a bug in this script, the makefile sometimes ended up empty - # Force a regeneration if it is. - if not os.path.isfile(makefile) or os.path.getsize(makefile)==0: - if perl is None: - print("Perl is required to build the makefiles!") - sys.exit(1) - - print("Creating the makefiles...") - sys.stdout.flush() - # Put our working Perl at the front of our path - os.environ["PATH"] = os.path.dirname(perl) + \ - os.pathsep + \ - os.environ["PATH"] - run_configure(configure, do_script) - if debug: - print("OpenSSL debug builds aren't supported.") - #if arch=="x86" and debug: - # # the do_masm script in openssl doesn't generate a debug - # # build makefile so we generate it here: - # os.system("perl util\mk1mf.pl debug "+configure+" >"+makefile) - - if arch == "amd64": - create_makefile64(makefile, m32) - fix_makefile(makefile) - copy(r"crypto\buildinf.h", r"crypto\buildinf_%s.h" % arch) - copy(r"crypto\opensslconf.h", r"crypto\opensslconf_%s.h" % arch) - - # If the assembler files don't exist in tmpXX, copy them there - if perl is None and os.path.exists("asm"+dirsuffix): - if not os.path.exists("tmp"+dirsuffix): - os.mkdir("tmp"+dirsuffix) - for f in os.listdir("asm"+dirsuffix): - if not f.endswith(".asm"): continue - if os.path.isfile(r"tmp%s\%s" % (dirsuffix, f)): continue - shutil.copy(r"asm%s\%s" % (dirsuffix, f), "tmp"+dirsuffix) - - # Now run make. - if arch == "amd64": - rc = os.system("nasm -f win64 -DNEAR -Ox -g ms\\uptable.asm") - if rc: - print("nasm assembler has failed.") - sys.exit(rc) - - copy(r"crypto\buildinf_%s.h" % arch, r"crypto\buildinf.h") - copy(r"crypto\opensslconf_%s.h" % arch, r"crypto\opensslconf.h") - - #makeCommand = "nmake /nologo PERL=\"%s\" -f \"%s\"" %(perl, makefile) - makeCommand = "nmake /nologo -f \"%s\"" % makefile - print("Executing ssl makefiles:", makeCommand) - sys.stdout.flush() - rc = os.system(makeCommand) - if rc: - print("Executing "+makefile+" failed") - print(rc) - sys.exit(rc) - finally: - os.chdir(old_cd) - sys.exit(rc) - -if __name__=='__main__': - main() diff --git a/PCbuild/build_tkinter.py b/PCbuild/build_tkinter.py deleted file mode 100644 index c807e7b19cf6..000000000000 --- a/PCbuild/build_tkinter.py +++ /dev/null @@ -1,78 +0,0 @@ -"""Script to compile the dependencies of _tkinter - -Copyright (c) 2007 by Christian Heimes - -Licensed to PSF under a Contributor Agreement. -""" - -import os -import sys - -here = os.path.abspath(os.path.dirname(__file__)) -par = os.path.pardir - -TCL = "tcl8.6.1" -TK = "tk8.6.1" -TIX = "tix-8.4.3.3" - -ROOT = os.path.abspath(os.path.join(here, par, par)) -NMAKE = ('nmake /nologo /f %s %s %s') - -def nmake(makefile, command="", **kw): - defines = ' '.join(k+'='+str(v) for k, v in kw.items()) - cmd = NMAKE % (makefile, defines, command) - print("\n\n"+cmd+"\n") - if os.system(cmd) != 0: - raise RuntimeError(cmd) - -def build(platform, clean): - if platform == "Win32": - dest = os.path.join(ROOT, "tcltk") - machine = "IX86" - elif platform == "AMD64": - dest = os.path.join(ROOT, "tcltk64") - machine = "AMD64" - else: - raise ValueError(platform) - - # TCL - tcldir = os.path.join(ROOT, TCL) - if 1: - os.chdir(os.path.join(tcldir, "win")) - if clean: - nmake("makefile.vc", "clean") - nmake("makefile.vc", MACHINE=machine) - nmake("makefile.vc", "install", INSTALLDIR=dest, MACHINE=machine) - - # TK - if 1: - os.chdir(os.path.join(ROOT, TK, "win")) - if clean: - nmake("makefile.vc", "clean", DEBUG=0, TCLDIR=tcldir) - nmake("makefile.vc", DEBUG=0, MACHINE=machine, TCLDIR=tcldir) - nmake("makefile.vc", "install", DEBUG=0, INSTALLDIR=dest, MACHINE=machine, TCLDIR=tcldir) - - # TIX - if 1: - # python9.mak is available at http://svn.python.org - os.chdir(os.path.join(ROOT, TIX, "win")) - if clean: - nmake("python.mak", "clean") - nmake("python.mak", MACHINE=machine, INSTALL_DIR=dest) - nmake("python.mak", "install", MACHINE=machine, INSTALL_DIR=dest) - -def main(): - if len(sys.argv) < 2 or sys.argv[1] not in ("Win32", "AMD64"): - print("%s Win32|AMD64" % sys.argv[0]) - sys.exit(1) - - if "-c" in sys.argv: - clean = True - else: - clean = False - - build(sys.argv[1], clean) - - -if __name__ == '__main__': - main() diff --git a/PCbuild/clean.bat b/PCbuild/clean.bat new file mode 100644 index 000000000000..78517d225f9f --- /dev/null +++ b/PCbuild/clean.bat @@ -0,0 +1,5 @@ +@echo off +rem A batch program to clean a particular configuration, +rem just for convenience. + +call %~dp0build.bat -t Clean %* diff --git a/PCbuild/debug.props b/PCbuild/debug.props deleted file mode 100644 index 9b7a65af4d00..000000000000 --- a/PCbuild/debug.props +++ /dev/null @@ -1,27 +0,0 @@ - - - - _d - $(OutDir)kill_python_d.exe - - - <_ProjectFileVersion>10.0.30319.1 - $(ProjectName)_d - - - - _DEBUG;%(PreprocessorDefinitions) - - - _DEBUG - - - - - $(PyDebugExt) - - - $(KillPythonExe) - - - \ No newline at end of file diff --git a/PCbuild/env.bat b/PCbuild/env.bat index 08dc8ef5253e..2b2c0051ce91 100644 --- a/PCbuild/env.bat +++ b/PCbuild/env.bat @@ -1,9 +1,16 @@ -@echo off -set VS10=%ProgramFiles(x86)%\Microsoft Visual Studio 10.0 -IF EXIST "%VS10%" GOTO ok -set VS10=%ProgramFiles%\Microsoft Visual Studio 10.0 -:ok - -echo Build environments: x86, ia64, amd64, x86_amd64, x86_ia64 -echo. -call "%VS10%\VC\vcvarsall.bat" %1 +@echo off +rem This script adds the latest available tools to the path for the current +rem command window. However, most builds of Python will ignore the version +rem of the tools on PATH and use PlatformToolset instead. Ideally, both sets of +rem tools should be the same version to avoid potential conflicts. +rem +rem To build Python with an earlier toolset, pass "/p:PlatformToolset=v100" (or +rem 'v110', 'v120' or 'v140') to the build script. + +echo Build environments: x86, amd64, x86_amd64 +echo. +set VSTOOLS=%VS140COMNTOOLS% +if "%VSTOOLS%"=="" set VSTOOLS=%VS120COMNTOOLS% +if "%VSTOOLS%"=="" set VSTOOLS=%VS110COMNTOOLS% +if "%VSTOOLS%"=="" set VSTOOLS=%VS100COMNTOOLS% +call "%VSTOOLS%..\..\VC\vcvarsall.bat" %* diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat new file mode 100644 index 000000000000..0b3c08b66e36 --- /dev/null +++ b/PCbuild/get_externals.bat @@ -0,0 +1,104 @@ +@echo off +setlocal +rem Simple script to fetch source for external libraries + +if not exist "%~dp0..\externals" mkdir "%~dp0..\externals" +pushd "%~dp0..\externals" + +if "%SVNROOT%"=="" set SVNROOT=http://svn.python.org/projects/external/ + +rem Optionally clean up first. Be warned that this can be very destructive! +if not "%1"=="" ( + for %%c in (-c --clean --clean-only) do ( + if "%1"=="%%c" goto clean + ) + goto usage +) +goto fetch + +:clean +echo.Cleaning up external libraries. +for /D %%d in ( + bzip2-* + db-* + nasm-* + openssl-* + tcl-* + tcltk* + tk-* + tix-* + sqlite-* + xz-* + ) do ( + echo.Removing %%d + rmdir /s /q %%d +) +if "%1"=="--clean-only" ( + goto end +) + +:fetch +rem Fetch current versions + +svn --version > nul 2>&1 +if ERRORLEVEL 9009 ( + echo.svn.exe must be on your PATH. + echo.Try TortoiseSVN (http://tortoisesvn.net/^) and be sure to check the + echo.command line tools option. + popd + exit /b 1 +) + +echo.Fetching external libraries... + +set libraries= +set libraries=%libraries% bzip2-1.0.6 +if NOT "%IncludeSSL%"=="false" set libraries=%libraries% nasm-2.11.06 +if NOT "%IncludeSSL%"=="false" set libraries=%libraries% openssl-1.0.2d +set libraries=%libraries% sqlite-3.8.11.0 +if NOT "%IncludeTkinter%"=="false" set libraries=%libraries% tcl-core-8.6.4.2 +if NOT "%IncludeTkinter%"=="false" set libraries=%libraries% tk-8.6.4.2 +if NOT "%IncludeTkinter%"=="false" set libraries=%libraries% tix-8.4.3.6 +set libraries=%libraries% xz-5.0.5 + +for %%e in (%libraries%) do ( + if exist %%e ( + echo.%%e already exists, skipping. + ) else ( + echo.Fetching %%e... + svn export %SVNROOT%%%e + ) +) + +goto end + +:usage +echo.invalid argument: %1 +echo.usage: %~n0 [[ -c ^| --clean ] ^| --clean-only ] +echo. +echo.Pull all sources necessary for compiling optional extension modules +echo.that rely on external libraries. Requires svn.exe to be on your PATH +echo.and pulls sources from %SVNROOT%. +echo. +echo.Use the -c or --clean option to clean up all external library sources +echo.before pulling in the current versions. +echo. +echo.Use the --clean-only option to do the same cleaning, without pulling in +echo.anything new. +echo. +echo.Only the first argument is checked, all others are ignored. +echo. +echo.**WARNING**: the cleaning options unconditionally remove any directory +echo.that is a child of +echo. %CD% +echo.and matches wildcard patterns beginning with bzip2-, db-, nasm-, openssl-, +echo.tcl-, tcltk, tk-, tix-, sqlite-, or xz-, and as such has the potential +echo.to be very destructive if you are not aware of what it is doing. Use with +echo.caution! +popd +exit /b -1 + + +:end +echo Finished. +popd diff --git a/PCbuild/idle.bat b/PCbuild/idle.bat index dcb0485af7d3..bacaaa8414a2 100644 --- a/PCbuild/idle.bat +++ b/PCbuild/idle.bat @@ -1,15 +1,15 @@ -@echo off -rem start idle -rem Usage: idle [-d] -rem -d Run Debug build (python_d.exe). Else release build. - -setlocal -set exe=python -PATH %PATH%;..\..\tcltk\bin - -if "%1"=="-d" (set exe=python_d) & shift - -set cmd=%exe% ../Lib/idlelib/idle.py %1 %2 %3 %4 %5 %6 %7 %8 %9 - -echo on -%cmd% +@echo off +rem start idle +rem Usage: idle [-d] +rem -d Run Debug build (python_d.exe). Else release build. + +setlocal +set exe=win32\python +PATH %PATH%;..\externals\tcltk\bin + +if "%1"=="-d" (set exe=%exe%_d) & shift + +set cmd=%exe% ../Lib/idlelib/idle.py %1 %2 %3 %4 %5 %6 %7 %8 %9 + +echo on +%cmd% diff --git a/PCbuild/installer.bmp b/PCbuild/installer.bmp deleted file mode 100644 index 1875e194ba27..000000000000 Binary files a/PCbuild/installer.bmp and /dev/null differ diff --git a/PCbuild/kill_python.c b/PCbuild/kill_python.c deleted file mode 100644 index 604731f3f81c..000000000000 --- a/PCbuild/kill_python.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Helper program for killing lingering python[_d].exe processes before - * building, thus attempting to avoid build failures due to files being - * locked. - */ - -#include -#include -#include -#include - -#pragma comment(lib, "psapi") - -#ifdef _DEBUG -#define PYTHON_EXE (L"python_d.exe") -#define PYTHON_EXE_LEN (12) -#define KILL_PYTHON_EXE (L"kill_python_d.exe") -#define KILL_PYTHON_EXE_LEN (17) -#else -#define PYTHON_EXE (L"python.exe") -#define PYTHON_EXE_LEN (10) -#define KILL_PYTHON_EXE (L"kill_python.exe") -#define KILL_PYTHON_EXE_LEN (15) -#endif - -int -main(int argc, char **argv) -{ - HANDLE hp, hsp, hsm; /* process, snapshot processes, snapshot modules */ - DWORD dac, our_pid; - size_t len; - wchar_t path[MAX_PATH+1]; - - MODULEENTRY32W me; - PROCESSENTRY32W pe; - - me.dwSize = sizeof(MODULEENTRY32W); - pe.dwSize = sizeof(PROCESSENTRY32W); - - memset(path, 0, MAX_PATH+1); - - our_pid = GetCurrentProcessId(); - - hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, our_pid); - if (hsm == INVALID_HANDLE_VALUE) { - printf("CreateToolhelp32Snapshot[1] failed: %d\n", GetLastError()); - return 1; - } - - if (!Module32FirstW(hsm, &me)) { - printf("Module32FirstW[1] failed: %d\n", GetLastError()); - CloseHandle(hsm); - return 1; - } - - /* - * Enumerate over the modules for the current process in order to find - * kill_process[_d].exe, then take a note of the directory it lives in. - */ - do { - if (_wcsnicmp(me.szModule, KILL_PYTHON_EXE, KILL_PYTHON_EXE_LEN)) - continue; - - len = wcsnlen_s(me.szExePath, MAX_PATH) - KILL_PYTHON_EXE_LEN; - wcsncpy_s(path, MAX_PATH+1, me.szExePath, len); - - break; - - } while (Module32NextW(hsm, &me)); - - CloseHandle(hsm); - - if (path == NULL) { - printf("failed to discern directory of running process\n"); - return 1; - } - - /* - * Take a snapshot of system processes. Enumerate over the snapshot, - * looking for python processes. When we find one, verify it lives - * in the same directory we live in. If it does, kill it. If we're - * unable to kill it, treat this as a fatal error and return 1. - * - * The rationale behind this is that we're called at the start of the - * build process on the basis that we'll take care of killing any - * running instances, such that the build won't encounter permission - * denied errors during linking. If we can't kill one of the processes, - * we can't provide this assurance, and the build shouldn't start. - */ - - hsp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if (hsp == INVALID_HANDLE_VALUE) { - printf("CreateToolhelp32Snapshot[2] failed: %d\n", GetLastError()); - return 1; - } - - if (!Process32FirstW(hsp, &pe)) { - printf("Process32FirstW failed: %d\n", GetLastError()); - CloseHandle(hsp); - return 1; - } - - dac = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE; - do { - - /* - * XXX TODO: if we really wanted to be fancy, we could check the - * modules for all processes (not just the python[_d].exe ones) - * and see if any of our DLLs are loaded (i.e. python34[_d].dll), - * as that would also inhibit our ability to rebuild the solution. - * Not worth loosing sleep over though; for now, a simple check - * for just the python executable should be sufficient. - */ - - if (_wcsnicmp(pe.szExeFile, PYTHON_EXE, PYTHON_EXE_LEN)) - /* This isn't a python process. */ - continue; - - /* It's a python process, so figure out which directory it's in... */ - hsm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pe.th32ProcessID); - if (hsm == INVALID_HANDLE_VALUE) - /* - * If our module snapshot fails (which will happen if we don't own - * the process), just ignore it and continue. (It seems different - * versions of Windows return different values for GetLastError() - * in this situation; it's easier to just ignore it and move on vs. - * stopping the build for what could be a false positive.) - */ - continue; - - if (!Module32FirstW(hsm, &me)) { - printf("Module32FirstW[2] failed: %d\n", GetLastError()); - CloseHandle(hsp); - CloseHandle(hsm); - return 1; - } - - do { - if (_wcsnicmp(me.szModule, PYTHON_EXE, PYTHON_EXE_LEN)) - /* Wrong module, we're looking for python[_d].exe... */ - continue; - - if (_wcsnicmp(path, me.szExePath, len)) - /* Process doesn't live in our directory. */ - break; - - /* Python process residing in the right directory, kill it! */ - hp = OpenProcess(dac, FALSE, pe.th32ProcessID); - if (!hp) { - printf("OpenProcess failed: %d\n", GetLastError()); - CloseHandle(hsp); - CloseHandle(hsm); - return 1; - } - - if (!TerminateProcess(hp, 1)) { - printf("TerminateProcess failed: %d\n", GetLastError()); - CloseHandle(hsp); - CloseHandle(hsm); - CloseHandle(hp); - return 1; - } - - CloseHandle(hp); - break; - - } while (Module32NextW(hsm, &me)); - - CloseHandle(hsm); - - } while (Process32NextW(hsp, &pe)); - - CloseHandle(hsp); - - return 0; -} - -/* vi: set ts=8 sw=4 sts=4 expandtab */ diff --git a/PCbuild/kill_python.vcxproj b/PCbuild/kill_python.vcxproj deleted file mode 100644 index 9f67c4081fd3..000000000000 --- a/PCbuild/kill_python.vcxproj +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31} - kill_python - Win32Proj - - - - Application - NotSet - true - - - Application - NotSet - - - Application - NotSet - true - - - Application - NotSet - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - - $(OutDir)$(ProjectName)_d.exe - Console - - - - - X64 - - - $(OutDir)$(ProjectName)_d.exe - Console - - - - - Console - - - - - X64 - - - Console - - - - - - - - - \ No newline at end of file diff --git a/PCbuild/libeay.vcxproj b/PCbuild/libeay.vcxproj new file mode 100644 index 000000000000..9662cd4b7150 --- /dev/null +++ b/PCbuild/libeay.vcxproj @@ -0,0 +1,907 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Debug + x64 + + + Release + x64 + + + + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0} + libeay + + + + + + + StaticLibrary + + + + + + + + <_DATEValue>#define DATE "$([System.DateTime]::Now.ToString(`ddd MMM dd HH':'mm':'ss yyyy`))" + <_CFLAGSValue>#define CFLAGS "cl /MD /Ox -W3 -Gs0 -Gy -nologo @(PreprocessorDefinitions->'-D%(Identity)',' ')" + <_PLATFORMValue Condition="$(Platform)=='Win32'">#define PLATFORM "VC-WIN32" + <_PLATFORMValue Condition="$(Platform)=='x64'">#define PLATFORM "VC-WIN64A" + + + + + + + + + + + + $(IntDir);%(AdditionalIncludeDirectories) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/make_buildinfo.c b/PCbuild/make_buildinfo.c deleted file mode 100644 index f9aadee65f97..000000000000 --- a/PCbuild/make_buildinfo.c +++ /dev/null @@ -1,194 +0,0 @@ -#include -#include -#include -#include -#include - -#define CMD_SIZE 500 - -/* This file creates the getbuildinfo.o object, by first - invoking subwcrev.exe (if found), and then invoking cl.exe. - As a side effect, it might generate PCBuild\getbuildinfo2.c - also. If this isn't a subversion checkout, or subwcrev isn't - found, it compiles ..\\Modules\\getbuildinfo.c instead. - - Currently, subwcrev.exe is found from the registry entries - of TortoiseSVN. - - No attempt is made to place getbuildinfo.o into the proper - binary directory. This isn't necessary, as this tool is - invoked as a pre-link step for pythoncore, so that overwrites - any previous getbuildinfo.o. - - However, if a second argument is provided, this will be used - as a temporary directory where any getbuildinfo2.c and - getbuildinfo.o files are put. This is useful if multiple - configurations are being built in parallel, to avoid them - trampling each other's files. - -*/ - -int make_buildinfo2(const char *tmppath) -{ - struct _stat st; - HKEY hTortoise; - char command[CMD_SIZE+1]; - DWORD type, size; - if (_stat(".svn", &st) < 0) - return 0; - /* Allow suppression of subwcrev.exe invocation if a no_subwcrev file is present. */ - if (_stat("no_subwcrev", &st) == 0) - return 0; - if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\TortoiseSVN", &hTortoise) != ERROR_SUCCESS && - RegOpenKey(HKEY_CURRENT_USER, "Software\\TortoiseSVN", &hTortoise) != ERROR_SUCCESS) - /* Tortoise not installed */ - return 0; - command[0] = '"'; /* quote the path to the executable */ - size = sizeof(command) - 1; - if (RegQueryValueEx(hTortoise, "Directory", 0, &type, command+1, &size) != ERROR_SUCCESS || - type != REG_SZ) - /* Registry corrupted */ - return 0; - strcat_s(command, CMD_SIZE, "bin\\subwcrev.exe"); - if (_stat(command+1, &st) < 0) - /* subwcrev.exe not part of the release */ - return 0; - strcat_s(command, CMD_SIZE, "\" .. ..\\Modules\\getbuildinfo.c \""); - strcat_s(command, CMD_SIZE, tmppath); /* quoted tmppath */ - strcat_s(command, CMD_SIZE, "getbuildinfo2.c\""); - puts(command); fflush(stdout); - if (system(command) < 0) - return 0; - return 1; -} - -const char DELIMS[] = { " \n" }; - -int get_mercurial_info(char * hgbranch, char * hgtag, char * hgrev, int size) -{ - int result = 0; - char filename[CMD_SIZE]; - char cmdline[CMD_SIZE]; - - strcpy_s(filename, CMD_SIZE, "tmpXXXXXX"); - if (_mktemp_s(filename, CMD_SIZE) == 0) { - int rc; - - strcpy_s(cmdline, CMD_SIZE, "hg id -bit > "); - strcat_s(cmdline, CMD_SIZE, filename); - rc = system(cmdline); - if (rc == 0) { - FILE * fp; - - if (fopen_s(&fp, filename, "r") == 0) { - char * cp = fgets(cmdline, CMD_SIZE, fp); - - if (cp) { - char * context = NULL; - char * tp = strtok_s(cp, DELIMS, &context); - if (tp) { - strcpy_s(hgrev, size, tp); - tp = strtok_s(NULL, DELIMS, &context); - if (tp) { - strcpy_s(hgbranch, size, tp); - tp = strtok_s(NULL, DELIMS, &context); - if (tp) { - strcpy_s(hgtag, size, tp); - result = 1; - } - } - } - } - fclose(fp); - } - } - _unlink(filename); - } - return result; -} - -int main(int argc, char*argv[]) -{ - char command[CMD_SIZE] = "cl.exe -c -D_WIN32 -DUSE_DL_EXPORT -D_WINDOWS -DWIN32 -D_WINDLL "; - char tmppath[CMD_SIZE] = ""; - int do_unlink, result; - char *tmpdir = NULL; - if (argc <= 2 || argc > 3) { - fprintf(stderr, "make_buildinfo $(ConfigurationName) [tmpdir]\n"); - return EXIT_FAILURE; - } - if (strcmp(argv[1], "Release") == 0) { - strcat_s(command, CMD_SIZE, "-MD "); - } - else if (strcmp(argv[1], "Debug") == 0) { - strcat_s(command, CMD_SIZE, "-D_DEBUG -MDd "); - } - else if (strcmp(argv[1], "ReleaseItanium") == 0) { - strcat_s(command, CMD_SIZE, "-MD /USECL:MS_ITANIUM "); - } - else if (strcmp(argv[1], "ReleaseAMD64") == 0) { - strcat_s(command, CMD_SIZE, "-MD "); - strcat_s(command, CMD_SIZE, "-MD /USECL:MS_OPTERON "); - } - else { - fprintf(stderr, "unsupported configuration %s\n", argv[1]); - return EXIT_FAILURE; - } - if (argc > 2) { - tmpdir = argv[2]; - strcat_s(tmppath, _countof(tmppath), tmpdir); - /* Hack fix for bad command line: If the command is issued like this: - * $(SolutionDir)make_buildinfo.exe" Debug "$(IntDir)" - * we will get a trailing quote because IntDir ends with a backslash that then - * escapes the final ". To simplify the life for developers, catch that problem - * here by cutting it off. - * The proper command line, btw is: - * $(SolutionDir)make_buildinfo.exe" Debug "$(IntDir)\" - * Hooray for command line parsing on windows. - */ - if (strlen(tmppath) > 0 && tmppath[strlen(tmppath)-1] == '"') - tmppath[strlen(tmppath)-1] = '\0'; - strcat_s(tmppath, _countof(tmppath), "\\"); - } - - if ((do_unlink = make_buildinfo2(tmppath))) { - strcat_s(command, CMD_SIZE, "\""); - strcat_s(command, CMD_SIZE, tmppath); - strcat_s(command, CMD_SIZE, "getbuildinfo2.c\" -DSUBWCREV "); - } - else { - char hgtag[CMD_SIZE]; - char hgbranch[CMD_SIZE]; - char hgrev[CMD_SIZE]; - - if (get_mercurial_info(hgbranch, hgtag, hgrev, CMD_SIZE)) { - strcat_s(command, CMD_SIZE, "-DHGBRANCH=\\\""); - strcat_s(command, CMD_SIZE, hgbranch); - strcat_s(command, CMD_SIZE, "\\\""); - - strcat_s(command, CMD_SIZE, " -DHGTAG=\\\""); - strcat_s(command, CMD_SIZE, hgtag); - strcat_s(command, CMD_SIZE, "\\\""); - - strcat_s(command, CMD_SIZE, " -DHGVERSION=\\\""); - strcat_s(command, CMD_SIZE, hgrev); - strcat_s(command, CMD_SIZE, "\\\" "); - } - strcat_s(command, CMD_SIZE, "..\\Modules\\getbuildinfo.c"); - } - strcat_s(command, CMD_SIZE, " -Fo\""); - strcat_s(command, CMD_SIZE, tmppath); - strcat_s(command, CMD_SIZE, "getbuildinfo.o\" -I..\\Include -I..\\PC"); - puts(command); fflush(stdout); - result = system(command); - if (do_unlink) { - command[0] = '\0'; - strcat_s(command, CMD_SIZE, "\""); - strcat_s(command, CMD_SIZE, tmppath); - strcat_s(command, CMD_SIZE, "getbuildinfo2.c\""); - _unlink(command); - } - if (result < 0) - return EXIT_FAILURE; - return 0; -} diff --git a/PCbuild/make_buildinfo.vcxproj b/PCbuild/make_buildinfo.vcxproj deleted file mode 100644 index eee7f91eac8c..000000000000 --- a/PCbuild/make_buildinfo.vcxproj +++ /dev/null @@ -1,52 +0,0 @@ - - - - - Release - Win32 - - - - {C73F0EC1-358B-4177-940F-0846AC8B04CD} - make_buildinfo - Win32Proj - - - - Application - NotSet - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - AllRules.ruleset - - - - - - Disabled - OnlyExplicitInline - _CONSOLE;%(PreprocessorDefinitions) - MultiThreaded - - - $(OutDir)make_buildinfo.exe - Console - - - - - - - - - \ No newline at end of file diff --git a/PCbuild/make_buildinfo.vcxproj.filters b/PCbuild/make_buildinfo.vcxproj.filters deleted file mode 100644 index 2227f8ce7bd7..000000000000 --- a/PCbuild/make_buildinfo.vcxproj.filters +++ /dev/null @@ -1,14 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - Source Files - - - \ No newline at end of file diff --git a/PCbuild/make_versioninfo.vcxproj b/PCbuild/make_versioninfo.vcxproj deleted file mode 100644 index 9cf507bbb6a8..000000000000 --- a/PCbuild/make_versioninfo.vcxproj +++ /dev/null @@ -1,200 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {F0E0541E-F17D-430B-97C4-93ADF0DD284E} - make_versioninfo - - - - Application - false - NotSet - - - Application - false - MultiByte - - - Application - - - Application - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - - Build PC/pythonnt_rc(_d).h - cd $(SolutionDir) -make_versioninfo.exe > ..\PC\pythonnt_rc.h - - $(SolutionDir)..\PC\pythonnt_rc.h;%(Outputs) - $(SolutionDir)make_versioninfo.exe - - - MaxSpeed - OnlyExplicitInline - true - %(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - $(SolutionDir)make_versioninfo.exe - Console - 0x1d000000 - - - - - - - - - - Build PC/pythonnt_rc(_d).h - cd $(SolutionDir) -make_versioninfo.exe > ..\PC\pythonnt_rc.h - - $(SolutionDir)..\PC\pythonnt_rc.h;%(Outputs) - - - MaxSpeed - OnlyExplicitInline - true - _CONSOLE;%(PreprocessorDefinitions) - - - $(SolutionDir)make_versioninfo.exe - - - cd $(SolutionDir) -make_versioninfo.exe > ..\PC\python_nt.h - - - - - - Build PC/pythonnt_rc(_d).h - cd $(SolutionDir) -make_versioninfo_d.exe > ..\PC\pythonnt_rc_d.h - - $(SolutionDir)..\PC\pythonnt_rc_d.h;%(Outputs) - $(SolutionDir)make_versioninfo_d.exe - - - Disabled - OnlyExplicitInline - false - %(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - $(SolutionDir)make_versioninfo_d.exe - Console - 0x1d000000 - - - - - - - - - Build PC/pythonnt_rc(_d).h - cd $(SolutionDir) -make_versioninfo_d.exe > ..\PC\pythonnt_rc_d.h - - $(SolutionDir)..\PC\pythonnt_rc_d.h;%(Outputs) - - - X64 - - - Disabled - OnlyExplicitInline - false - _CONSOLE;%(PreprocessorDefinitions) - - - $(SolutionDir)make_versioninfo_d.exe - MachineX64 - - - cd $(SolutionDir) -make_versioninfo_d.exe > ..\PC\python_nt_d.h - - - - - - - - - - \ No newline at end of file diff --git a/PCbuild/make_versioninfo.vcxproj.filters b/PCbuild/make_versioninfo.vcxproj.filters deleted file mode 100644 index 96c0434e8776..000000000000 --- a/PCbuild/make_versioninfo.vcxproj.filters +++ /dev/null @@ -1,13 +0,0 @@ - - - - - {e4180954-c3a5-4749-b9a4-31b804ee4fa8} - - - - - Source Files - - - \ No newline at end of file diff --git a/PCbuild/openssl.props b/PCbuild/openssl.props new file mode 100644 index 000000000000..d094e59ba8c2 --- /dev/null +++ b/PCbuild/openssl.props @@ -0,0 +1,77 @@ + + + + $(opensslDir)tmp\ + + + + + + StaticLibrary + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_PreprocessorDefinitionList>@(PreprocessorDefinitions) + + + + + + 4244;4267 + $(opensslDir);$(opensslDir)include;$(opensslDir)crypto;$(opensslDir)crypto\asn1;$(opensslDir)crypto\evp;$(opensslDir)crypto\modes + $(_PreprocessorDefinitionList);%(PreprocessorDefinitions) + + + + + + nasm.exe -f win32 + nasm.exe -f win64 -DNEAR -Ox -g + + + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/pcbuild.proj b/PCbuild/pcbuild.proj new file mode 100644 index 000000000000..36621c910cd8 --- /dev/null +++ b/PCbuild/pcbuild.proj @@ -0,0 +1,90 @@ + + + + {CC9B93A2-439D-4058-9D29-6DCF43774405} + Win32 + Release + true + true + true + true + true + + + + + $(Platform) + $(Configuration) + + Build + Clean + CleanAll + true + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln index e431c914064a..766a870684ea 100644 --- a/PCbuild/pcbuild.sln +++ b/PCbuild/pcbuild.sln @@ -1,5 +1,7 @@ -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.22823.1 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{553EC33E-9816-4996-A660-5D6186A0B0B3}" ProjectSection(SolutionItems) = preProject ..\Modules\getbuildinfo.c = ..\Modules\getbuildinfo.c @@ -8,14 +10,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcxproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_versioninfo", "make_versioninfo.vcxproj", "{F0E0541E-F17D-430B-97C4-93ADF0DD284E}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcxproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonw", "pythonw.vcxproj", "{F4229CC3-873C-49AE-9729-DD308ED4CD4A}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_buildinfo", "make_buildinfo.vcxproj", "{C73F0EC1-358B-4177-940F-0846AC8B04CD}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winsound", "winsound.vcxproj", "{28B5D777-DDF2-4B6B-B34F-31D938813856}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_decimal", "_decimal.vcxproj", "{0E9791DB-593A-465F-98BC-681011311617}" @@ -50,7 +48,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unicodedata", "unicodedata. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyexpat", "pyexpat.vcxproj", "{D06B6426-4762-44CC-8BAD-D79052507F2F}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bdist_wininst", "bdist_wininst.vcxproj", "{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bdist_wininst", "..\PC\bdist_wininst\bdist_wininst.vcxproj", "{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_hashlib", "_hashlib.vcxproj", "{447F05A8-F581-4CAC-A466-5AC7936E207E}" EndProject @@ -58,10 +56,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite3", "sqlite3.vcxproj" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_multiprocessing", "_multiprocessing.vcxproj", "{9E48B300-37D1-11DD-8C41-005056C00008}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssl", "ssl.vcxproj", "{E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kill_python", "kill_python.vcxproj", "{6DE10744-E396-40A5-B4E2-1B69AA7C8D31}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python3dll", "python3dll.vcxproj", "{885D4898-D08D-4091-9C40-C700CFE3FC5A}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xxlimited", "xxlimited.vcxproj", "{F749B822-B489-4CA5-A3AD-CE078F5F338A}" @@ -74,12 +68,22 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pywlauncher", "pywlauncher. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_freeze_importlib", "_freeze_importlib.vcxproj", "{19C0C13F-47CA-4432-AFF3-799A296A4DDC}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_sha3", "_sha3.vcxproj", "{254A0C05-6696-4B08-8CB2-EF7D533AEE01}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_overlapped", "_overlapped.vcxproj", "{EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testembed", "_testembed.vcxproj", "{6DAC66D9-E703-4624-BE03-49112AB5AA62}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testmultiphase", "_testmultiphase.vcxproj", "{16BFE6F0-22EF-40B5-B831-7E937119EF10}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tcl", "tcl.vcxproj", "{B5FD6F1D-129E-4BFF-9340-03606FAC7283}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tix", "tix.vcxproj", "{C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tk", "tk.vcxproj", "{7E85ECCF-A72C-4DA4-9E52-884508E80BA1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libeay", "libeay.vcxproj", "{E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssleay", "ssleay.vcxproj", "{10615B24-73BF-4EFA-93AA-236916321317}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -108,22 +112,6 @@ Global {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.Build.0 = Release|Win32 {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.ActiveCfg = Release|x64 {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.Build.0 = Release|x64 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|Win32.ActiveCfg = Debug|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|Win32.Build.0 = Debug|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|x64.ActiveCfg = Debug|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Debug|x64.Build.0 = Debug|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|Win32.Build.0 = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|x64.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGInstrument|x64.Build.0 = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|Win32.Build.0 = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|x64.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.PGUpdate|x64.Build.0 = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|Win32.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|Win32.Build.0 = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|x64.ActiveCfg = Release|Win32 - {F0E0541E-F17D-430B-97C4-93ADF0DD284E}.Release|x64.Build.0 = Release|Win32 {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.ActiveCfg = Debug|Win32 {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.Build.0 = Debug|Win32 {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|x64.ActiveCfg = Debug|x64 @@ -144,34 +132,18 @@ Global {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|Win32.Build.0 = Debug|Win32 {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.ActiveCfg = Debug|x64 {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.Build.0 = Debug|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.Build.0 = Release|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.ActiveCfg = Release|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.Build.0 = Release|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.Build.0 = Release|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.ActiveCfg = Release|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.Build.0 = Release|x64 {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.ActiveCfg = Release|Win32 {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.Build.0 = Release|Win32 {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.ActiveCfg = Release|x64 {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.Build.0 = Release|x64 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|Win32.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|Win32.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|x64.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Debug|x64.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|Win32.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|x64.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGInstrument|x64.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|Win32.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|x64.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.PGUpdate|x64.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|Win32.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|Win32.Build.0 = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|x64.ActiveCfg = Release|Win32 - {C73F0EC1-358B-4177-940F-0846AC8B04CD}.Release|x64.Build.0 = Release|Win32 {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|Win32.ActiveCfg = Debug|Win32 {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|Win32.Build.0 = Debug|Win32 {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|x64.ActiveCfg = Debug|x64 @@ -224,14 +196,14 @@ Global {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|Win32.Build.0 = Debug|Win32 {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|x64.ActiveCfg = Debug|x64 {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|x64.Build.0 = Debug|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.Build.0 = Release|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.ActiveCfg = Release|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.Build.0 = Release|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.Build.0 = Release|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.ActiveCfg = Release|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.Build.0 = Release|x64 {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|Win32.ActiveCfg = Release|Win32 {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|Win32.Build.0 = Release|Win32 {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|x64.ActiveCfg = Release|x64 @@ -336,14 +308,14 @@ Global {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|Win32.Build.0 = Debug|Win32 {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|x64.ActiveCfg = Debug|x64 {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|x64.Build.0 = Debug|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.Build.0 = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.ActiveCfg = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.Build.0 = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.Build.0 = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.ActiveCfg = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.Build.0 = Release|x64 {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|Win32.ActiveCfg = Release|Win32 {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|Win32.Build.0 = Release|Win32 {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|x64.ActiveCfg = Release|x64 @@ -444,7 +416,7 @@ Global {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.Build.0 = Release|Win32 {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.ActiveCfg = Release|x64 {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.Build.0 = Release|x64 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|Win32.ActiveCfg = Release|Win32 + {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|Win32.ActiveCfg = Debug|Win32 {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|x64.ActiveCfg = Release|x64 {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|Win32.ActiveCfg = Release|Win32 {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|x64.ActiveCfg = Release|x64 @@ -500,49 +472,18 @@ Global {9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.Build.0 = Release|Win32 {9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.ActiveCfg = Release|x64 {9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.Build.0 = Release|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|Win32.ActiveCfg = Debug|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|Win32.Build.0 = Debug|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|x64.ActiveCfg = Debug|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|x64.Build.0 = Debug|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|Win32.ActiveCfg = Release|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|Win32.Build.0 = Release|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|x64.ActiveCfg = Release|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|x64.Build.0 = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|Win32.ActiveCfg = Debug|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|Win32.Build.0 = Debug|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|x64.ActiveCfg = Debug|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Debug|x64.Build.0 = Debug|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|Win32.Build.0 = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|x64.ActiveCfg = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGInstrument|x64.Build.0 = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|Win32.Build.0 = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|x64.ActiveCfg = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.PGUpdate|x64.Build.0 = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|Win32.ActiveCfg = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|Win32.Build.0 = Release|Win32 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.ActiveCfg = Release|x64 - {6DE10744-E396-40A5-B4E2-1B69AA7C8D31}.Release|x64.Build.0 = Release|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.ActiveCfg = PGInstrument|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.ActiveCfg = PGUpdate|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.Build.0 = PGUpdate|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.ActiveCfg = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.Build.0 = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.ActiveCfg = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.Build.0 = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.ActiveCfg = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.Build.0 = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.ActiveCfg = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.Build.0 = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.ActiveCfg = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.Build.0 = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.ActiveCfg = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.Build.0 = Debug|x64 {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.ActiveCfg = Release|Win32 {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.Build.0 = Release|Win32 {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|x64.ActiveCfg = Release|x64 @@ -565,14 +506,14 @@ Global {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|Win32.Build.0 = Debug|Win32 {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|x64.ActiveCfg = Debug|x64 {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|x64.Build.0 = Debug|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|Win32.Build.0 = Release|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|x64.ActiveCfg = Release|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|x64.Build.0 = Release|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|Win32.Build.0 = Release|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|x64.ActiveCfg = Release|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|x64.Build.0 = Release|x64 {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|Win32.ActiveCfg = Release|Win32 {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|Win32.Build.0 = Release|Win32 {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|x64.ActiveCfg = Release|x64 @@ -581,34 +522,34 @@ Global {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|Win32.Build.0 = Debug|Win32 {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|x64.ActiveCfg = Debug|x64 {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|x64.Build.0 = Debug|x64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|x64.ActiveCfg = PGInstrument|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|x64.Build.0 = PGInstrument|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.ActiveCfg = PGUpdate|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.Build.0 = PGUpdate|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.Build.0 = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|x64.ActiveCfg = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|x64.Build.0 = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|Win32.Build.0 = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.ActiveCfg = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.Build.0 = Release|x64 {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.ActiveCfg = Release|Win32 {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.Build.0 = Release|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.ActiveCfg = Release|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.Build.0 = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.ActiveCfg = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.Build.0 = Release|x64 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|Win32.ActiveCfg = Debug|Win32 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|Win32.Build.0 = Debug|Win32 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|x64.ActiveCfg = Debug|x64 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|x64.Build.0 = Debug|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.ActiveCfg = PGInstrument|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.Build.0 = PGInstrument|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.ActiveCfg = PGUpdate|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.Build.0 = PGUpdate|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|Win32.Build.0 = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.ActiveCfg = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.Build.0 = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|Win32.Build.0 = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.ActiveCfg = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.Build.0 = Release|x64 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|Win32.ActiveCfg = Release|Win32 {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|Win32.Build.0 = Release|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.ActiveCfg = Release|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.Build.0 = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.ActiveCfg = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.Build.0 = Release|x64 {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|Win32.ActiveCfg = Debug|Win32 {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|x64.ActiveCfg = Debug|x64 {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|Win32.ActiveCfg = Release|Win32 @@ -616,39 +557,9 @@ Global {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|Win32.ActiveCfg = Release|Win32 {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|x64.ActiveCfg = Release|Win32 {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|Win32.ActiveCfg = Release|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|Win32.Build.0 = Release|Win32 {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|x64.ActiveCfg = Release|x64 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Debug|Win32.ActiveCfg = Debug|Win32 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Debug|Win32.Build.0 = Debug|Win32 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Debug|x64.ActiveCfg = Debug|x64 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Debug|x64.Build.0 = Debug|x64 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Release|Win32.ActiveCfg = Release|Win32 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Release|Win32.Build.0 = Release|Win32 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Release|x64.ActiveCfg = Release|x64 - {254A0C05-6696-4B08-8CB2-EF7D533AEE01}.Release|x64.Build.0 = Release|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|Win32.ActiveCfg = Debug|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|Win32.Build.0 = Debug|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|x64.ActiveCfg = Debug|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|x64.Build.0 = Debug|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|Win32.ActiveCfg = Release|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|Win32.Build.0 = Release|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|x64.ActiveCfg = Release|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|x64.Build.0 = Release|x64 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|x64.Build.0 = Release|x64 {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|Win32.ActiveCfg = Debug|Win32 {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|Win32.Build.0 = Debug|Win32 {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|x64.ActiveCfg = Debug|x64 @@ -665,6 +576,114 @@ Global {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|Win32.Build.0 = Release|Win32 {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|x64.ActiveCfg = Release|x64 {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|x64.Build.0 = Release|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|Win32.ActiveCfg = Debug|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|Win32.Build.0 = Debug|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|x64.ActiveCfg = Debug|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|x64.Build.0 = Debug|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|x64.ActiveCfg = Release|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|Win32.Build.0 = Release|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|x64.ActiveCfg = Release|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|x64.Build.0 = Release|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|Win32.ActiveCfg = Release|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|Win32.Build.0 = Release|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|x64.ActiveCfg = Release|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|x64.Build.0 = Release|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|Win32.ActiveCfg = Debug|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|Win32.Build.0 = Debug|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|x64.ActiveCfg = Debug|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|x64.Build.0 = Debug|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGInstrument|x64.ActiveCfg = Release|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|Win32.Build.0 = Release|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|x64.ActiveCfg = Release|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|x64.Build.0 = Release|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|Win32.ActiveCfg = Release|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|Win32.Build.0 = Release|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|x64.ActiveCfg = Release|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|x64.Build.0 = Release|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Debug|Win32.ActiveCfg = Debug|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Debug|Win32.Build.0 = Debug|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Debug|x64.ActiveCfg = Debug|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Debug|x64.Build.0 = Debug|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGInstrument|Win32.Build.0 = Release|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGInstrument|x64.ActiveCfg = Release|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGInstrument|x64.Build.0 = Release|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGUpdate|Win32.Build.0 = Release|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGUpdate|x64.ActiveCfg = Release|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGUpdate|x64.Build.0 = Release|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Release|Win32.ActiveCfg = Release|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Release|Win32.Build.0 = Release|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Release|x64.ActiveCfg = Release|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Release|x64.Build.0 = Release|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Debug|Win32.ActiveCfg = Debug|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Debug|Win32.Build.0 = Debug|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Debug|x64.ActiveCfg = Debug|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Debug|x64.Build.0 = Debug|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGInstrument|Win32.Build.0 = Release|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGInstrument|x64.ActiveCfg = Release|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGInstrument|x64.Build.0 = Release|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGUpdate|Win32.Build.0 = Release|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGUpdate|x64.ActiveCfg = Release|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGUpdate|x64.Build.0 = Release|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Release|Win32.ActiveCfg = Release|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Release|Win32.Build.0 = Release|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Release|x64.ActiveCfg = Release|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Release|x64.Build.0 = Release|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Debug|Win32.ActiveCfg = Debug|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Debug|Win32.Build.0 = Debug|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Debug|x64.ActiveCfg = Debug|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Debug|x64.Build.0 = Debug|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGInstrument|Win32.Build.0 = Release|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGInstrument|x64.ActiveCfg = Release|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGInstrument|x64.Build.0 = Release|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGUpdate|Win32.Build.0 = Release|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGUpdate|x64.ActiveCfg = Release|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGUpdate|x64.Build.0 = Release|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Release|Win32.ActiveCfg = Release|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Release|Win32.Build.0 = Release|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Release|x64.ActiveCfg = Release|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Release|x64.Build.0 = Release|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|Win32.ActiveCfg = Debug|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|Win32.Build.0 = Debug|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|x64.ActiveCfg = Debug|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|x64.Build.0 = Debug|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|Win32.Build.0 = Release|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|x64.ActiveCfg = Release|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|x64.Build.0 = Release|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|Win32.Build.0 = Release|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|x64.ActiveCfg = Release|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|x64.Build.0 = Release|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|Win32.ActiveCfg = Release|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|Win32.Build.0 = Release|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|x64.ActiveCfg = Release|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|x64.Build.0 = Release|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.Debug|Win32.ActiveCfg = Debug|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.Debug|Win32.Build.0 = Debug|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.Debug|x64.ActiveCfg = Debug|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.Debug|x64.Build.0 = Debug|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.PGInstrument|Win32.Build.0 = Release|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.PGInstrument|x64.ActiveCfg = Release|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.PGInstrument|x64.Build.0 = Release|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.PGUpdate|Win32.Build.0 = Release|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.PGUpdate|x64.ActiveCfg = Release|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.PGUpdate|x64.Build.0 = Release|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.Release|Win32.ActiveCfg = Release|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.Release|Win32.Build.0 = Release|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.Release|x64.ActiveCfg = Release|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/PCbuild/pginstrument.props b/PCbuild/pginstrument.props deleted file mode 100644 index 5584995d2008..000000000000 --- a/PCbuild/pginstrument.props +++ /dev/null @@ -1,38 +0,0 @@ - - - - $(SolutionDir)$(Platform)-pgi\ - - - <_ProjectFileVersion>10.0.30319.1 - $(OutDirPGI)\ - $(SolutionDir)$(PlatformName)-temp-pgi\$(ProjectName)\ - - - - MaxSpeed - OnlyExplicitInline - false - Size - true - false - true - true - - - false - - - true - false - PGInstrument - $(SolutionDir)$(Platform)-pgi\$(TargetName).pgd - $(OutDirPGI)\$(TargetName).lib - - - - - $(OutDirPGI) - - - diff --git a/PCbuild/pgupdate.props b/PCbuild/pgupdate.props deleted file mode 100644 index d775a02c73a9..000000000000 --- a/PCbuild/pgupdate.props +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir)$(PlatformName)-pgo\ - - - - %(AdditionalManifestDependencies) - PGUpdate - $(OutDir)$(TargetName).lib - - - \ No newline at end of file diff --git a/PCbuild/build_ssl.bat b/PCbuild/prepare_ssl.bat similarity index 51% rename from PCbuild/build_ssl.bat rename to PCbuild/prepare_ssl.bat index 805d77a6dc76..3153615df12e 100644 --- a/PCbuild/build_ssl.bat +++ b/PCbuild/prepare_ssl.bat @@ -1,12 +1,12 @@ -@echo off -if not defined HOST_PYTHON ( - if %1 EQU Debug ( - set HOST_PYTHON=python_d.exe - if not exist python34_d.dll exit 1 - ) ELSE ( - set HOST_PYTHON=python.exe - if not exist python34.dll exit 1 - ) -) -%HOST_PYTHON% build_ssl.py %1 %2 %3 - +@echo off +if not defined HOST_PYTHON ( + if %1 EQU Debug ( + shift + set HOST_PYTHON=python_d.exe + if not exist python36_d.dll exit 1 + ) ELSE ( + set HOST_PYTHON=python.exe + if not exist python36.dll exit 1 + ) +) +%HOST_PYTHON% prepare_ssl.py %1 diff --git a/PCbuild/prepare_ssl.py b/PCbuild/prepare_ssl.py new file mode 100644 index 000000000000..4203dab2f8ed --- /dev/null +++ b/PCbuild/prepare_ssl.py @@ -0,0 +1,248 @@ +#! /usr/bin/env python3 +# Script for preparing OpenSSL for building on Windows. +# Uses Perl to create nmake makefiles and otherwise prepare the way +# for building on 32 or 64 bit platforms. + +# Script originally authored by Mark Hammond. +# Major revisions by: +# Martin v. Löwis +# Christian Heimes +# Zachary Ware + +# THEORETICALLY, you can: +# * Unpack the latest OpenSSL release where $(opensslDir) in +# PCbuild\pyproject.props expects it to be. +# * Install ActivePerl and ensure it is somewhere on your path. +# * Run this script with the OpenSSL source dir as the only argument. +# +# it should configure OpenSSL such that it is ready to be built by +# ssl.vcxproj on 32 or 64 bit platforms. + +import os +import re +import sys +import shutil +import subprocess + +# Find all "foo.exe" files on the PATH. +def find_all_on_path(filename, extras = None): + entries = os.environ["PATH"].split(os.pathsep) + ret = [] + for p in entries: + fname = os.path.abspath(os.path.join(p, filename)) + if os.path.isfile(fname) and fname not in ret: + ret.append(fname) + if extras: + for p in extras: + fname = os.path.abspath(os.path.join(p, filename)) + if os.path.isfile(fname) and fname not in ret: + ret.append(fname) + return ret + +# Find a suitable Perl installation for OpenSSL. +# cygwin perl does *not* work. ActivePerl does. +# Being a Perl dummy, the simplest way I can check is if the "Win32" package +# is available. +def find_working_perl(perls): + for perl in perls: + try: + subprocess.check_output([perl, "-e", "use Win32;"]) + except subprocess.CalledProcessError: + continue + else: + return perl + + if perls: + print("The following perl interpreters were found:") + for p in perls: + print(" ", p) + print(" None of these versions appear suitable for building OpenSSL") + else: + print("NO perl interpreters were found on this machine at all!") + print(" Please install ActivePerl and ensure it appears on your path") + +def create_makefile64(makefile, m32): + """Create and fix makefile for 64bit + + Replace 32 with 64bit directories + """ + if not os.path.isfile(m32): + return + with open(m32) as fin: + with open(makefile, 'w') as fout: + for line in fin: + line = line.replace("=tmp32", "=tmp64") + line = line.replace("=out32", "=out64") + line = line.replace("=inc32", "=inc64") + # force 64 bit machine + line = line.replace("MKLIB=lib", "MKLIB=lib /MACHINE:X64") + line = line.replace("LFLAGS=", "LFLAGS=/MACHINE:X64 ") + # don't link against the lib on 64bit systems + line = line.replace("bufferoverflowu.lib", "") + fout.write(line) + os.unlink(m32) + +def create_asms(makefile): + #create a custom makefile out of the provided one + asm_makefile = os.path.splitext(makefile)[0] + '.asm.mak' + with open(makefile) as fin: + with open(asm_makefile, 'w') as fout: + for line in fin: + # Keep everything up to the install target (it's convenient) + if line.startswith('install: all'): + break + else: + fout.write(line) + asms = [] + for line in fin: + if '.asm' in line and line.strip().endswith('.pl'): + asms.append(line.split(':')[0]) + while line.strip(): + fout.write(line) + line = next(fin) + fout.write('\n') + + fout.write('asms: $(TMP_D) ') + fout.write(' '.join(asms)) + fout.write('\n') + + os.system('nmake /f {} PERL=perl asms'.format(asm_makefile)) + os.unlink(asm_makefile) + + + +def fix_makefile(makefile): + """Fix some stuff in all makefiles + """ + if not os.path.isfile(makefile): + return + copy_if_different = r'$(PERL) $(SRC_D)\util\copy-if-different.pl' + with open(makefile) as fin: + lines = fin.readlines() + with open(makefile, 'w') as fout: + for line in lines: + if line.startswith("PERL="): + continue + if line.startswith("CP="): + line = "CP=copy\n" + if line.startswith("MKDIR="): + line = "MKDIR=mkdir\n" + if line.startswith("CFLAG="): + line = line.strip() + for algo in ("RC5", "MDC2", "IDEA"): + noalgo = " -DOPENSSL_NO_%s" % algo + if noalgo not in line: + line = line + noalgo + line = line + '\n' + if copy_if_different in line: + line = line.replace(copy_if_different, 'copy /Y') + fout.write(line) + +def run_configure(configure, do_script): + print("perl Configure "+configure+" no-idea no-mdc2") + os.system("perl Configure "+configure+" no-idea no-mdc2") + print(do_script) + os.system(do_script) + +def cmp(f1, f2): + bufsize = 1024 * 8 + with open(f1, 'rb') as fp1, open(f2, 'rb') as fp2: + while True: + b1 = fp1.read(bufsize) + b2 = fp2.read(bufsize) + if b1 != b2: + return False + if not b1: + return True + +def copy(src, dst): + if os.path.isfile(dst) and cmp(src, dst): + return + shutil.copy(src, dst) + +def prep(arch): + if arch == "x86": + configure = "VC-WIN32" + do_script = "ms\\do_nasm" + makefile="ms\\nt.mak" + m32 = makefile + dirsuffix = "32" + elif arch == "amd64": + configure = "VC-WIN64A" + do_script = "ms\\do_win64a" + makefile = "ms\\nt64.mak" + m32 = makefile.replace('64', '') + dirsuffix = "64" + #os.environ["VSEXTCOMP_USECL"] = "MS_OPTERON" + else: + raise ValueError('Unrecognized platform: %s' % arch) + + # rebuild makefile when we do the role over from 32 to 64 build + if arch == "amd64" and os.path.isfile(m32) and not os.path.isfile(makefile): + os.unlink(m32) + + # If the ssl makefiles do not exist, we invoke Perl to generate them. + # Due to a bug in this script, the makefile sometimes ended up empty + # Force a regeneration if it is. + if not os.path.isfile(makefile) or os.path.getsize(makefile)==0: + print("Creating the makefiles...") + sys.stdout.flush() + run_configure(configure, do_script) + + if arch == "amd64": + create_makefile64(makefile, m32) + fix_makefile(makefile) + copy(r"crypto\buildinf.h", r"crypto\buildinf_%s.h" % arch) + copy(r"crypto\opensslconf.h", r"crypto\opensslconf_%s.h" % arch) + else: + print(makefile, 'already exists!') + + print('creating asms...') + create_asms(makefile) + +def main(): + if len(sys.argv) == 1: + print("Not enough arguments: directory containing OpenSSL", + "sources must be supplied") + sys.exit(1) + + if len(sys.argv) > 2: + print("Too many arguments supplied, all we need is the directory", + "containing OpenSSL sources") + sys.exit(1) + + ssl_dir = sys.argv[1] + + if not os.path.isdir(ssl_dir): + print(ssl_dir, "is not an existing directory!") + sys.exit(1) + + # perl should be on the path, but we also look in "\perl" and "c:\\perl" + # as "well known" locations + perls = find_all_on_path("perl.exe", [r"\perl\bin", + r"C:\perl\bin", + r"\perl64\bin", + r"C:\perl64\bin", + ]) + perl = find_working_perl(perls) + if perl: + print("Found a working perl at '%s'" % (perl,)) + else: + sys.exit(1) + sys.stdout.flush() + + # Put our working Perl at the front of our path + os.environ["PATH"] = os.path.dirname(perl) + \ + os.pathsep + \ + os.environ["PATH"] + + old_cwd = os.getcwd() + try: + os.chdir(ssl_dir) + for arch in ['amd64', 'x86']: + prep(arch) + finally: + os.chdir(old_cwd) + +if __name__=='__main__': + main() diff --git a/PCbuild/pyd.props b/PCbuild/pyd.props deleted file mode 100644 index 469966ede6b3..000000000000 --- a/PCbuild/pyd.props +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - false - false - .pyd - - - - Py_BUILD_CORE_MODULE;%(PreprocessorDefinitions) - MultiThreadedDLL - - - - - - - - - \ No newline at end of file diff --git a/PCbuild/pyd_d.props b/PCbuild/pyd_d.props deleted file mode 100644 index b023288fbad1..000000000000 --- a/PCbuild/pyd_d.props +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - false - false - false - .pyd - $(ProjectName)_d - - - - Disabled - Default - false - Py_BUILD_CORE_MODULE;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - - - - - - - - - \ No newline at end of file diff --git a/PCbuild/pyexpat.vcxproj b/PCbuild/pyexpat.vcxproj index 974fd3d6cbc4..4e7621ec926b 100644 --- a/PCbuild/pyexpat.vcxproj +++ b/PCbuild/pyexpat.vcxproj @@ -35,185 +35,32 @@ + <_ProjectFileVersion>10.0.30319.1 {D06B6426-4762-44CC-8BAD-D79052507F2F} pyexpat - Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - - .\..\Modules\expat;%(AdditionalIncludeDirectories) - PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - - - X64 - - - .\..\Modules\expat;%(AdditionalIncludeDirectories) - PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - - - .\..\Modules\expat;%(AdditionalIncludeDirectories) - PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - - - X64 - - - .\..\Modules\expat;%(AdditionalIncludeDirectories) - PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - - - .\..\Modules\expat;%(AdditionalIncludeDirectories) - PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - - - X64 - - - .\..\Modules\expat;%(AdditionalIncludeDirectories) - PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - MachineX64 - - - - - .\..\Modules\expat;%(AdditionalIncludeDirectories) - PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - - - - X64 - + - .\..\Modules\expat;%(AdditionalIncludeDirectories) + $(PySourcePath)Modules\expat;%(AdditionalIncludeDirectories) PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) - - MachineX64 - diff --git a/PCbuild/pylauncher.vcxproj b/PCbuild/pylauncher.vcxproj index 9fa93dd141e8..6a2178583e1e 100644 --- a/PCbuild/pylauncher.vcxproj +++ b/PCbuild/pylauncher.vcxproj @@ -37,256 +37,33 @@ {7B2727B5-5A3F-40EE-A866-43A13CD31446} pylauncher + py + ClCompile + false + - - Application - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - + Application - false - true MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + ClCompile + + - - - - - py_d - - - py_d - - - py - - - py - - - py - - - py - - - py - - - py - - - - Level3 - Disabled - _CONSOLE;%(PreprocessorDefinitions) - - - true - version.lib;%(AdditionalDependencies) - false - Console - $(OutDir)$(TargetName)$(TargetExt) - - - + - Level3 - Disabled _CONSOLE;%(PreprocessorDefinitions) + MultiThreaded - true - version.lib;%(AdditionalDependencies) - false - Console - $(OutDir)$(TargetName)$(TargetExt) - - - - - Level3 - MaxSpeed - true - true - _CONSOLE;NDEBUG;%(PreprocessorDefinitions) - - - true - false - true - false - version.lib;%(AdditionalDependencies) - Console - - - - - Level3 - MaxSpeed - true - true - _CONSOLE;NDEBUG;%(PreprocessorDefinitions) - - - true - false - true - false - version.lib;%(AdditionalDependencies) - Console - - - - - Level3 - MaxSpeed - true - true - _CONSOLE;NDEBUG;%(PreprocessorDefinitions) - - - true - false - true - false - version.lib;%(AdditionalDependencies) - Console - - - - - Level3 - MaxSpeed - true - true - _CONSOLE;NDEBUG;%(PreprocessorDefinitions) - - - true - false - true - false - version.lib;%(AdditionalDependencies) - Console - - - - - Level3 - MaxSpeed - true - true - _CONSOLE;NDEBUG;%(PreprocessorDefinitions) - - - true - false - true - false - version.lib;%(AdditionalDependencies) - Console - - - - - Level3 - MaxSpeed - true - true - _CONSOLE;NDEBUG;%(PreprocessorDefinitions) - - - true - false - true - false version.lib;%(AdditionalDependencies) Console @@ -300,11 +77,6 @@ - - - {f0e0541e-f17d-430b-97c4-93adf0dd284e} - - diff --git a/PCbuild/pyproject.props b/PCbuild/pyproject.props index 7b65961073c4..a2c44f33cb00 100644 --- a/PCbuild/pyproject.props +++ b/PCbuild/pyproject.props @@ -1,48 +1,54 @@  - - + + <_ProjectFileVersion>10.0.30319.1 - $(SolutionDir) - $(SolutionDir)$(PlatformName)-temp-$(Configuration)\$(ProjectName)\ - false - - - <_ProjectFileVersion>10.0.30319.1 - <_PropertySheetDisplayName>amd64 - $(SolutionDir)amd64\ - $(SolutionDir)$(PlatformName)-temp-$(Configuration)\$(ProjectName)\ + 10.0 + $(BuildPath) + $(Py_OutDir) + $(OutDir)\ + $(SolutionDir)obj\ + $(IntDir)\ + $(Py_IntDir)\$(ArchName)_$(Configuration)\$(ProjectName)\ + $(Py_IntDir)\$(ArchName)_PGO\$(ProjectName)\ + $(ProjectName) + $(TargetName)$(PyDebugExt) + false + false + true + true + false + false - - python34$(PyDebugExt) - $(OutDir)python$(PyDebugExt).exe - $(OutDir)kill_python$(PyDebugExt).exe - ..\.. - $(externalsDir)\sqlite-3.8.1 - $(externalsDir)\bzip2-1.0.6 - $(externalsDir)\xz-5.0.5 - $(externalsDir)\openssl-1.0.1e - $(externalsDir)\tcltk - $(externalsDir)\tcltk64 - $(tcltkDir)\lib\tcl86t.lib;$(tcltkDir)\lib\tk86t.lib - $(tcltkDir)\lib\tcl86tg.lib;$(tcltkDir)\lib\tk86tg.lib - $(tcltk64Dir)\lib\tcl86t.lib;$(tcltk64Dir)\lib\tk86t.lib - $(tcltk64Dir)\lib\tcl86tg.lib;$(tcltk64Dir)\lib\tk86tg.lib + + + <_DebugPreprocessorDefinition>NDEBUG; + <_DebugPreprocessorDefinition Condition="$(Configuration) == 'Debug'">_DEBUG; + <_PlatformPreprocessorDefinition>_WIN32; + <_PlatformPreprocessorDefinition Condition="$(Platform) == 'x64'">_WIN64;_M_X64; + <_PydPreprocessorDefinition Condition="$(TargetExt) == '.pyd'">Py_BUILD_CORE_MODULE; + $(PySourcePath)Include;$(PySourcePath)PC;%(AdditionalIncludeDirectories) + WIN32;$(_PlatformPreprocessorDefinition)$(_DebugPreprocessorDefinition)$(_PydPreprocessorDefinition)%(PreprocessorDefinitions) + MaxSpeed - OnlyExplicitInline true - ..\Include; ..\PC;%(AdditionalIncludeDirectories) - _WIN32;%(PreprocessorDefinitions) true - - - MultiThreaded + + MultiThreadedDLL true Level3 ProgramDatabase Default + true + true + NoExtensions + + + Disabled + false + MultiThreadedDebugDLL $(OutDir);%(AdditionalLibraryDirectories) @@ -51,54 +57,105 @@ Windows true true + true + LIBC;%(IgnoreSpecificDefaultLibraries) MachineX86 + MachineX64 + $(OutDir)$(TargetName).pgd + UseLinkTimeCodeGeneration + PGInstrument + PGUpdate + + true + true + true + - ..\PC;..\Include;%(AdditionalIncludeDirectories) + $(PySourcePath)PC;$(PySourcePath)Include;%(AdditionalIncludeDirectories) + $(_DebugPreprocessorDefinition)%(PreprocessorDefinitions) + 0x0409 + + $(_DebugPreprocessorDefinition)%(PreprocessorDefinitions) + true + true + Win32 + X64 + $(OutDir)wininst.tlb + + + - - - $(PyDllName) - - - $(PythonExe) - - - $(KillPythonExe) - - - $(externalsDir) - - - $(sqlite3Dir) - - - $(bz2Dir) - - - $(lzmaDir) - - - $(opensslDir) - - - $(tcltkDir) - - - $(tcltk64Dir) - - - $(tcltkLib) - - - $(tcltkLibDebug) - - - $(tcltk64Lib) - - - $(tcltk64LibDebug) - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Kits\Installed Roots@KitsRoot81)\bin\x86\signtool.exe + $(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Kits\Installed Roots@KitsRoot)\bin\x86\signtool.exe + $(registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1A@InstallationFolder)\Bin\signtool.exe + <_SignCommand Condition="Exists($(SignToolPath))">"$(SignToolPath)" sign /q /n "$(SigningCertificate)" /t http://timestamp.verisign.com/scripts/timestamp.dll /d "Python $(PythonVersion)" + + + + + + + \ No newline at end of file diff --git a/PCbuild/python.props b/PCbuild/python.props new file mode 100644 index 000000000000..25d6d9201045 --- /dev/null +++ b/PCbuild/python.props @@ -0,0 +1,152 @@ + + + + Win32 + Release + + v140 + v120 + v110 + v100 + + + amd64 + win32 + $(ArchName)-pgo + + + $([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)\..\)) + $(PySourcePath)\ + + + $(PySourcePath)PCBuild\$(ArchName)\ + $(PyBuildPath) + $(BuildPath)\ + + + $([System.IO.Path]::GetFullPath(`$(PySourcePath)externals\`)) + $(ExternalsDir)sqlite-3.8.11.0\ + $(ExternalsDir)bzip2-1.0.6\ + $(ExternalsDir)xz-5.0.5\ + $(ExternalsDir)openssl-1.0.2d\ + $(ExternalsDir)\nasm-2.11.06\ + + + _d + + + $(BuildPath)python$(PyDebugExt).exe + + + + + <_PatchLevelContent>$([System.IO.File]::ReadAllText(`$(PySourcePath)Include\patchlevel.h`)) + $([System.Text.RegularExpressions.Regex]::Match($(_PatchLevelContent), `define\s+PY_MAJOR_VERSION\s+(\d+)`).Groups[1].Value) + $([System.Text.RegularExpressions.Regex]::Match($(_PatchLevelContent), `define\s+PY_MINOR_VERSION\s+(\d+)`).Groups[1].Value) + $([System.Text.RegularExpressions.Regex]::Match($(_PatchLevelContent), `define\s+PY_MICRO_VERSION\s+(\d+)`).Groups[1].Value) + <_ReleaseLevel>$([System.Text.RegularExpressions.Regex]::Match($(_PatchLevelContent), `define\s+PY_RELEASE_LEVEL\s+PY_RELEASE_LEVEL_(\w+)`).Groups[1].Value) + $([System.Text.RegularExpressions.Regex]::Match($(_PatchLevelContent), `define\s+PY_RELEASE_SERIAL\s+(\d+)`).Groups[1].Value) + 15 + 10 + 11 + 12 + a$(ReleaseSerial) + b$(ReleaseSerial) + rc$(ReleaseSerial) + + + + + $([System.Text.RegularExpressions.Regex]::Match($(OverrideVersion), `(\d+)\.(\d+)\.(\d+)((a|b|rc)(\d))?`).Groups[1].Value) + $([System.Text.RegularExpressions.Regex]::Match($(OverrideVersion), `(\d+)\.(\d+)\.(\d+)((a|b|rc)(\d))?`).Groups[2].Value) + $([System.Text.RegularExpressions.Regex]::Match($(OverrideVersion), `(\d+)\.(\d+)\.(\d+)((a|b|rc)(\d))?`).Groups[3].Value) + $([System.Text.RegularExpressions.Regex]::Match($(OverrideVersion), `(\d+)\.(\d+)\.(\d+)((a|b|rc)(\d))?`).Groups[4].Value) + <_ReleaseLevel>$([System.Text.RegularExpressions.Regex]::Match($(OverrideVersion), `(\d+)\.(\d+)\.(\d+)((a|b|rc)(\d))?`).Groups[5].Value) + $([System.Text.RegularExpressions.Regex]::Match($(OverrideVersion), `(\d+)\.(\d+)\.(\d+)((a|b|rc)(\d))?`).Groups[6].Value) + 0 + 15 + 10 + 11 + 12 + + + + $(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber) + $(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)$(ReleaseLevelName) + $([msbuild]::BitwiseOr( + $([msbuild]::Multiply($(MajorVersionNumber), 16777216)), + $([msbuild]::BitwiseOr( + $([msbuild]::Multiply($(MinorVersionNumber), 65536)), + $([msbuild]::BitwiseOr( + $([msbuild]::Multiply($(MicroVersionNumber), 256)), + $([msbuild]::BitwiseOr( + $([msbuild]::Multiply($(ReleaseLevelNumber), 16)), + $(ReleaseSerial) + )) + )) + )) + )) + $([msbuild]::Add( + $(ReleaseSerial), + $([msbuild]::Add( + $([msbuild]::Multiply($(ReleaseLevelNumber), 10)), + $([msbuild]::Multiply($(MicroVersionNumber), 1000)) + )) + )) + + + python$(MajorVersionNumber)$(MinorVersionNumber)$(PyDebugExt) + + + .cp$(MajorVersionNumber)$(MinorVersionNumber)-win32 + .cp$(MajorVersionNumber)$(MinorVersionNumber)-win_amd64 + + + $(MajorVersionNumber).$(MinorVersionNumber) + $(SysWinVer)-32 + + + + + + + + + + diff --git a/PCbuild/python.vcxproj b/PCbuild/python.vcxproj index bd1262459636..0ae4882ad16a 100644 --- a/PCbuild/python.vcxproj +++ b/PCbuild/python.vcxproj @@ -36,44 +36,11 @@ {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} + ClCompile + - - Application - false - MultiByte - - - Application - false - MultiByte - - - Application - false - NotSet - - - Application - false - MultiByte - - - Application - false - MultiByte - - - Application - false - MultiByte - - - Application - false - MultiByte - - + Application false MultiByte @@ -81,266 +48,22 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - %(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)python.exe - Console - 2000000 - 0x1d000000 - - - - - X64 - - - %(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)python.exe - Console - 2000000 - 0x1d000000 - - - - - Disabled - false - %(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - Default - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - ..\Include;%(AdditionalIncludeDirectories) - - - $(OutDir)python_d.exe - Console - 2000000 - 0x1d000000 - - - - - X64 - - - Disabled - false - %(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - true - Default - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - ..\Include;%(AdditionalIncludeDirectories) - - - $(OutDir)python_d.exe - Console - 4194304 - 0x1d000000 - - - - - %(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)python.exe - Console - 2000000 - 0x1d000000 - - - - - - - X64 - - - %(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)python.exe - Console - 2000000 - 0x1d000000 - - - MachineX64 - - - - - %(AdditionalIncludeDirectories) - _CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)python.exe - Console - 2000000 - 0x1d000000 - - - - - - - X64 - + - %(AdditionalIncludeDirectories) _CONSOLE;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - $(OutDir)python.exe Console 2000000 0x1d000000 - - - MachineX64 @@ -350,7 +73,7 @@ - + @@ -361,4 +84,19 @@ - + + + <_Content>@rem This script invokes the most recently built Python with all arguments +@rem passed through to the interpreter. This file is generated by the +@rem build process and any changes *will* be thrown away by the next +@rem rebuild. +@rem This is only meant as a convenience for developing CPython +@rem and using it outside of that context is ill-advised. +@echo Running $(Configuration)^|$(Platform) interpreter... +@"$(OutDir)python$(PyDebugExt).exe" %* + + <_ExistingContent Condition="Exists('$(PySourcePath)python.bat')">$([System.IO.File]::ReadAllText('$(PySourcePath)python.bat')) + + + + \ No newline at end of file diff --git a/PCbuild/python.vcxproj.filters b/PCbuild/python.vcxproj.filters index e4906a40d7f7..0662a4e7f5f9 100644 --- a/PCbuild/python.vcxproj.filters +++ b/PCbuild/python.vcxproj.filters @@ -19,8 +19,8 @@ - + Source Files - \ No newline at end of file + diff --git a/PCbuild/python3dll.vcxproj b/PCbuild/python3dll.vcxproj index bc8ff31ca223..18ff4a83e912 100644 --- a/PCbuild/python3dll.vcxproj +++ b/PCbuild/python3dll.vcxproj @@ -1,6 +1,14 @@  + + Debug + Win32 + + + Debug + x64 + PGInstrument Win32 @@ -30,144 +38,43 @@ {885D4898-D08D-4091-9C40-C700CFE3FC5A} python3dll Win32Proj + python3 + ClCompile + false + - - Makefile - - - Makefile - - - Makefile - true - - - Makefile - - - Makefile - - - Makefile + + DynamicLibrary - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - <_ProjectFileVersion>10.0.30319.1 - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x86 OutDir=$(OutDir) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x86 OutDir=$(OutDir) rebuild - cd $(ProjectDir)\..\PC -"$(VSInstallDir)\VC\bin\nmake.exe" /f python3.mak MACHINE=x86 OutDir=$(OutDir) clean - $(OutDir)python3.dll - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x64 OutDir=$(OutDir) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x64 OutDir=$(OutDir) rebuild - cd $(ProjectDir)\..\PC -"$(VSInstallDir)\VC\bin\nmake.exe" /f python3.mak MACHINE=x64 OutDir=$(OutDir) clean - $(OutDir)python3.dll - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x86 OutDir=$(OutDir) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x86 OutDir=$(OutDir) rebuild - cd $(ProjectDir)\..\PC -"$(VSInstallDir)\VC\bin\nmake.exe" /f python3.mak MACHINE=x86 OutDir=$(OutDir) clean - $(OutDir)python3.dll - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x64 OutDir=$(OutDir) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x64 OutDir=$(OutDir) rebuild - cd $(ProjectDir)\..\PC -"$(VSInstallDir)\VC\bin\nmake.exe" /f python3.mak MACHINE=x64 OutDir=$(OutDir) clean - $(OutDir)python3.dll - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x86 OutDir=$(OutDir) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x86 OutDir=$(OutDir) rebuild - cd $(ProjectDir)\..\PC -"$(VSInstallDir)\VC\bin\nmake.exe" /f python3.mak MACHINE=x86 OutDir=$(OutDir) clean - $(OutDir)python3.dll - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x64 OutDir=$(OutDir) - cd $(ProjectDir)\..\PC -nmake /f python3.mak MACHINE=x64 OutDir=$(OutDir) rebuild - cd $(ProjectDir)\..\PC -"$(VSInstallDir)\VC\bin\nmake.exe" /f python3.mak MACHINE=x64 OutDir=$(OutDir) clean - $(OutDir)python3.dll - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) + <_Machine>X86 + <_Machine Condition="$(Platform) == 'x64'">X64 + + false + + + $(OutDir)$(TargetName)stub.lib + $(PySourcePath)PC\python3.def + $(IntDir)python3_d.def + DllMain + + + lib /nologo /def:"$(IntDir)python3stub.def" /out:"$(OutDir)$(TargetName)stub.lib" /MACHINE:$(_Machine) + Rebuilding $(TargetName)stub.lib + $(OutDir)$(TargetName)stub.lib + @@ -181,4 +88,55 @@ nmake /f python3.mak MACHINE=x64 OutDir=$(OutDir) rebuild + + + + <_DefLines Remove="@(_DefLines)" /> + <_Lines Remove="@(_Lines)" /> + + + + + + <_Pattern1>(=python$(MajorVersionNumber)$(MinorVersionNumber))\. + <_Sub1>$1_d. + <_Pattern2>"python3" + <_Sub2>"python3_d" + + + <_Lines Include="@(_DefLines)"> + $([System.Text.RegularExpressions.Regex]::Replace($([System.Text.RegularExpressions.Regex]::Replace(`%(Identity)`, `$(_Pattern1)`, `$(_Sub1)`)), `$(_Pattern2)`, `$(_Sub2)`)) + + + + + + + + + <_DefLines Remove="@(_DefLines)" /> + <_Lines Remove="@(_Lines)" /> + + + + + + <_Pattern>^[\w.]+=.+?\.([^ ]+).*$ + <_Sub>$1 + + + <_Lines Include="EXPORTS" /> + <_Symbols Include="@(_DefLines)" Condition="$([System.Text.RegularExpressions.Regex]::IsMatch(`%(Identity)`, `$(_Pattern)`))"> + $([System.Text.RegularExpressions.Regex]::Replace(`%(Identity)`, `$(_Pattern)`, `$(_Sub)`)) + + <_Lines Include="@(_Symbols->'%(Symbol)')" /> + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 11b7054d3fb9..9cbe8b9384c0 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -38,373 +38,41 @@ {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} pythoncore + - - DynamicLibrary - false - - - DynamicLibrary - false - - - DynamicLibrary - false - NotSet - - - DynamicLibrary - false - - - DynamicLibrary - false - - - DynamicLibrary - false - - - DynamicLibrary - false - - + DynamicLibrary false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + ClCompile + true + + - - <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - $(PyDllName) - $(PyDllName) - $(PyDllName) - $(PyDllName) - $(PyDllName) - $(PyDllName) - $(PyDllName) - $(PyDllName) + $(PyDllName) - - - /Zm200 %(AdditionalOptions) - ..\Python;..\Modules\zlib;%(AdditionalIncludeDirectories) - _USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32;%(PreprocessorDefinitions) - MultiThreadedDLL - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - ..\Include;%(AdditionalIncludeDirectories) - - - Generate build information... - "$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)" - - - $(IntDir)getbuildinfo.o;%(AdditionalDependencies) - $(OutDir)$(PyDllName).dll - libc;%(IgnoreSpecificDefaultLibraries) - 0x1e000000 - - - $(KillPythonExe) - - - Killing any running $(PythonExe) instances... - - - - - X64 - - - /Zm200 %(AdditionalOptions) - ..\Python;..\Modules\zlib;%(AdditionalIncludeDirectories) - _USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32;%(PreprocessorDefinitions) - MultiThreadedDLL - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - ..\Include;%(AdditionalIncludeDirectories) - - - Generate build information... - "$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)" - - - $(IntDir)getbuildinfo.o;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1e000000 - - - $(KillPythonExe) - - - Killing any running $(PythonExe) instances... - - - - - /Zm200 %(AdditionalOptions) - Disabled - Default - false - ..\Python;..\Modules\zlib;%(AdditionalIncludeDirectories) - _USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - ..\Include;%(AdditionalIncludeDirectories) - - - Generate build information... - "$(SolutionDir)make_buildinfo.exe" Debug "$(IntDir)" - - - $(IntDir)getbuildinfo.o;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1e000000 - - - $(KillPythonExe) - - - Killing any running $(PythonExe) instances... - - - - - X64 - - - /Zm200 %(AdditionalOptions) - Disabled - Default - false - ..\Python;..\Modules\zlib;%(AdditionalIncludeDirectories) - _USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - ..\Include;%(AdditionalIncludeDirectories) - - - Generate build information... - "$(SolutionDir)make_buildinfo.exe" Debug "$(IntDir)" - - - $(IntDir)getbuildinfo.o;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1e000000 - - - $(KillPythonExe) - - - Killing any running $(PythonExe) instances... - - - - - /Zm200 %(AdditionalOptions) - ..\Python;..\Modules\zlib;%(AdditionalIncludeDirectories) - _USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32;%(PreprocessorDefinitions) - MultiThreadedDLL - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - ..\Include;%(AdditionalIncludeDirectories) - - - Generate build information... - "$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)" - - - $(IntDir)getbuildinfo.o;%(AdditionalDependencies) - $(OutDir)$(PyDllName).dll - libc;%(IgnoreSpecificDefaultLibraries) - 0x1e000000 - - - $(KillPythonExe) - - - Killing any running $(PythonExe) instances... - - - - - X64 - - - /Zm200 %(AdditionalOptions) - ..\Python;..\Modules\zlib;%(AdditionalIncludeDirectories) - _USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32;%(PreprocessorDefinitions) - MultiThreadedDLL - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - ..\Include;%(AdditionalIncludeDirectories) - - - Generate build information... - "$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)" - - - $(IntDir)getbuildinfo.o;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1e000000 - MachineX64 - - - $(KillPythonExe) - - - Killing any running $(PythonExe) instances... - - - - - /Zm200 %(AdditionalOptions) - ..\Python;..\Modules\zlib;%(AdditionalIncludeDirectories) - _USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32;%(PreprocessorDefinitions) - MultiThreadedDLL - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - ..\Include;%(AdditionalIncludeDirectories) - - - Generate build information... - "$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)" - - - $(IntDir)getbuildinfo.o;%(AdditionalDependencies) - $(OutDir)$(PyDllName).dll - libc;%(IgnoreSpecificDefaultLibraries) - 0x1e000000 - - - $(KillPythonExe) - - - Killing any running $(PythonExe) instances... - - - - - X64 - + + Link + + /Zm200 %(AdditionalOptions) - ..\Python;..\Modules\zlib;%(AdditionalIncludeDirectories) - _USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;WIN32;%(PreprocessorDefinitions) - MultiThreadedDLL + $(PySourcePath)Python;$(PySourcePath)Modules\zlib;%(AdditionalIncludeDirectories) + _USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;MS_DLL_ID="$(SysWinVer)";%(PreprocessorDefinitions) - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - ..\Include;%(AdditionalIncludeDirectories) - - - Generate build information... - "$(SolutionDir)make_buildinfo.exe" Release "$(IntDir)" - - $(IntDir)getbuildinfo.o;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) + ws2_32.lib;%(AdditionalDependencies) 0x1e000000 - MachineX64 - - $(KillPythonExe) - - - Killing any running $(PythonExe) instances... - @@ -454,6 +122,7 @@ + @@ -470,6 +139,7 @@ + @@ -478,6 +148,7 @@ + @@ -643,6 +314,7 @@ + @@ -664,9 +336,9 @@ + - @@ -702,10 +374,12 @@ + + @@ -717,23 +391,30 @@ - + - - {6de10744-e396-40a5-b4e2-1b69aa7c8d31} - false - - - {c73f0ec1-358b-4177-940f-0846ac8b04cd} - false - - - {f0e0541e-f17d-430b-97c4-93adf0dd284e} - false - + - + + + + + + $([System.IO.File]::ReadAllText('$(IntDir)hgbranch.txt').Trim()) + $([System.IO.File]::ReadAllText('$(IntDir)hgversion.txt').Trim()) + $([System.IO.File]::ReadAllText('$(IntDir)hgtag.txt').Trim()) + + + + HGVERSION="$(HgVersion)";HGTAG="$(HgTag)";HGBRANCH="$(HgBranch)";%(PreprocessorDefinitions) + + + + + + + \ No newline at end of file diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 41fe1b2dbbdc..837b73690a12 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -216,6 +216,9 @@ Include + + Include + Include @@ -240,6 +243,9 @@ Include + + Include + Include @@ -414,7 +420,6 @@ Python - Python @@ -424,6 +429,15 @@ Include + + Include + + + Modules + + + Include + @@ -885,6 +899,9 @@ Python + + Python + Python @@ -897,6 +914,9 @@ Python + + Python + Python @@ -930,13 +950,30 @@ PC - Modules Python + + Objects + + + Modules + + + Modules + + + Modules + + + PC + + + Objects + diff --git a/PCbuild/pythonw.vcxproj b/PCbuild/pythonw.vcxproj index 1214569eb98f..b0a209af42f5 100644 --- a/PCbuild/pythonw.vcxproj +++ b/PCbuild/pythonw.vcxproj @@ -36,296 +36,30 @@ {F4229CC3-873C-49AE-9729-DD308ED4CD4A} + ClCompile + false + - - Application - false - - - Application - false - - - Application - false - - - Application - false - NotSet - - - Application - false - - - Application - false - - - Application - false - - + Application false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - Disabled - false - %(AdditionalIncludeDirectories) - _WINDOWS;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - Default - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)pythonw_d.exe - 2000000 - 0x1d000000 - MachineX86 - - - - - X64 - - - Disabled - false - %(AdditionalIncludeDirectories) - _WINDOWS;%(PreprocessorDefinitions) - MultiThreadedDebugDLL - Default - - - _DEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)pythonw_d.exe - 2000000 - 0x1d000000 - - - - - %(AdditionalIncludeDirectories) - _WINDOWS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)pythonw.exe - 2000000 - 0x1d000000 - MachineX86 - - - - - X64 - - - %(AdditionalIncludeDirectories) - _WINDOWS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)pythonw.exe - 2000000 - 0x1d000000 - - - - - %(AdditionalIncludeDirectories) - _WINDOWS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)pythonw.exe - 2000000 - 0x1d000000 - - - MachineX86 - - - - - X64 - - - %(AdditionalIncludeDirectories) - _WINDOWS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)pythonw.exe - 2000000 - 0x1d000000 - - - MachineX64 - - - - - %(AdditionalIncludeDirectories) - _WINDOWS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - - - $(OutDir)pythonw.exe - 2000000 - 0x1d000000 - - - MachineX86 - - - - - X64 - - - %(AdditionalIncludeDirectories) - _WINDOWS;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - Default - - - NDEBUG;%(PreprocessorDefinitions) - 0x0409 - + - $(OutDir)pythonw.exe 2000000 0x1d000000 - - - MachineX64 diff --git a/PCbuild/pywlauncher.vcxproj b/PCbuild/pywlauncher.vcxproj index 08e35a77411a..882f1c4d24bd 100644 --- a/PCbuild/pywlauncher.vcxproj +++ b/PCbuild/pywlauncher.vcxproj @@ -37,200 +37,37 @@ {1D4B18D3-7C12-4ECB-9179-8531FF876CE6} pywlauncher + pyw + ClCompile + false + - - Application - true - Unicode - - - Application - true - Unicode - - - Application - false - true - Unicode - - + Application - false - true - Unicode - - - Unicode - - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + ClCompile + + - - - - - pyw_d - - - pyw_d - - - pyw - - - pyw - - - pyw - - - pyw - - + - Level3 - Disabled _WINDOWS;%(PreprocessorDefinitions) + MultiThreaded - true version.lib;%(AdditionalDependencies) - false Windows - $(OutDir)$(TargetName)$(TargetExt) - - - Level3 - Disabled - _WINDOWS;%(PreprocessorDefinitions) - - - true - version.lib;%(AdditionalDependencies) - false - Windows - $(OutDir)$(TargetName)$(TargetExt) - - - - - Level3 - MaxSpeed - true - true - _WINDOWS;NDEBUG;%(PreprocessorDefinitions) - - - true - false - true - false - version.lib;%(AdditionalDependencies) - Windows - - - - - Level3 - MaxSpeed - true - true - _WINDOWS;NDEBUG;%(PreprocessorDefinitions) - - - true - false - true - false - version.lib;%(AdditionalDependencies) - Windows - - - - - version.lib;%(AdditionalDependencies) - - - _WINDOWS;NDEBUG;%(PreprocessorDefinitions) - - - - - version.lib;%(AdditionalDependencies) - - - _WINDOWS;NDEBUG;%(PreprocessorDefinitions) - - - - - version.lib;%(AdditionalDependencies) - - - _WINDOWS;NDEBUG;_WIN64;_M_X64;%(PreprocessorDefinitions) - - - - - version.lib;%(AdditionalDependencies) - - - _WINDOWS;NDEBUG;_WIN64;_M_X64;%(PreprocessorDefinitions) - - diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index 32635709c132..5be66f40b94d 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -1,347 +1,300 @@ -Building Python using Microsoft Visual C++ ------------------------------------------- - -This directory is used to build CPython for Microsoft Windows NT version -5.1 or higher (Windows XP, Windows Server 2003, or later) on 32 and 64 -bit platforms. Using this directory requires an installation of -Microsoft Visual C++ 2010 (MSVC 10.0) of any edition. The specific -requirements are as follows: -Visual C++ 2010 Express Edition - Required for building 32-bit Debug and Release configuration builds. - This edition does not support "solution folders", which pcbuild.sln - uses; this will not prevent building. -Visual Studio 2010 Standard Edition - Required for building 64-bit Debug and Release configuration builds -Visual Studio 2010 Professional Edition - Required for building Release configuration builds that make use of - Profile Guided Optimization (PGO), on either platform. The official - Python releases are built with Professional Edition using PGO. - -All you need to do to build is open the solution "pcbuild.sln" in Visual -Studio, select the desired combination of configuration and platform, -then build with "Build Solution" or the F7 keyboard shortcut. You can -also build from the command line using the "build.bat" script in this -directory. The solution is configured to build the projects in the -correct order. - -The solution currently supports two platforms. The Win32 platform is -used to build standard x86-compatible 32-bit binaries, output into this -directory. The x64 platform is used for building 64-bit AMD64 (aka -x86_64 or EM64T) binaries, output into the amd64 sub-directory which -will be created if it doesn't already exist. The Itanium (IA-64) -platform is no longer supported. See the "Building for AMD64" section -below for more information about 64-bit builds. - -Four configuration options are supported by the solution: -Debug - Used to build Python with extra debugging capabilities, equivalent - to using ./configure --with-pydebug on UNIX. All binaries built - using this configuration have "_d" added to their name: - python34_d.dll, python_d.exe, parser_d.pyd, and so on. Both the - build and rt (run test) batch files in this directory accept a -d - option for debug builds. If you are building Python to help with - development of CPython, you will most likely use this configuration. -PGInstrument, PGUpdate - Used to build Python in Release configuration using PGO, which - requires Professional Edition of Visual Studio. See the "Profile - Guided Optimization" section below for more information. Build - output from each of these configurations lands in its own - sub-directory of this directory. The official Python releases are - built using these configurations. -Release - Used to build Python as it is meant to be used in production - settings, though without PGO. - - -Legacy support --------------- - -You can find build directories for older versions of Visual Studio and -Visual C++ in the PC directory. The legacy build directories are no -longer actively maintained and may not work out of the box. - -Currently, the only legacy build directory is PC\VS9.0, for Visual -Studio 2008 (9.0). - - -C Runtime ---------- - -Visual Studio 2010 uses version 10 of the C runtime (MSVCRT10). The -executables no longer use the "Side by Side" assemblies used in previous -versions of the compiler. This simplifies distribution of applications. - -The run time libraries are available under the VC/Redist folder of your -Visual Studio distribution. For more info, see the Readme in the -VC/Redist folder. - - -Sub-Projects ------------- - -The CPython project is split up into several smaller sub-projects which -are managed by the pcbuild.sln solution file. Each sub-project is -represented by a .vcxproj and a .vcxproj.filters file starting with the -name of the sub-project. These sub-projects fall into a few general -categories: - -The following sub-projects represent the bare minimum required to build -a functioning CPython interpreter. If nothing else builds but these, -you'll have a very limited but usable python.exe: -pythoncore - .dll and .lib -python - .exe -kill_python - kill_python.exe, a small program designed to kill any instances of - python(_d).exe that are running and live in the build output - directory; this is meant to avoid build issues due to locked files -make_buildinfo, make_versioninfo - helpers to provide necessary information to the build process - -These sub-projects provide extra executables that are useful for running -CPython in different ways: -pythonw - pythonw.exe, a variant of python.exe that doesn't open a Command - Prompt window -pylauncher - py.exe, the Python Launcher for Windows, see - http://docs.python.org/3/using/windows.html#launcher -pywlauncher - pyw.exe, a variant of py.exe that doesn't open a Command Prompt - window -_testembed - _testembed.exe, a small program that embeds Python for testing - purposes, used by test_capi.py - -These are miscellaneous sub-projects that don't really fit the other -categories. By default, these projects do not build in Debug -configuration: -_freeze_importlib - _freeze_importlib.exe, used to regenerate Python\importlib.h after - changes have been made to Lib\importlib\_bootstrap.py -bdist_wininst - ..\Lib\distutils\command\wininst-10.0[-amd64].exe, the base - executable used by the distutils bdist_wininst command -python3dll - python3.dll, the PEP 384 Stable ABI dll -xxlimited - builds an example module that makes use of the PEP 384 Stable ABI, - see Modules\xxlimited.c - -The following sub-projects are for individual modules of the standard -library which are implemented in C; each one builds a DLL (renamed to -.pyd) of the same name as the project: -_ctypes -_ctypes_test -_decimal -_elementtree -_hashlib -_msi -_multiprocessing -_overlapped -_sha3 -_socket -_testcapi -_testbuffer -_testimportmultiple -pyexpat -select -unicodedata -winsound - -The following Python-controlled sub-projects wrap external projects. -Note that these external libraries are not necessary for a working -interpreter, but they do implement several major features. See the -"Getting External Sources" section below for additional information -about getting the source for building these libraries. The sub-projects -are: -_bz2 - Python wrapper for version 1.0.6 of the libbzip2 compression library - Homepage: - http://www.bzip.org/ -_lzma - Python wrapper for the liblzma compression library, using pre-built - binaries of XZ Utils version 5.0.5 - Homepage: - http://tukaani.org/xz/ -_ssl - Python wrapper for version 1.0.1e of the OpenSSL secure sockets - library, which is built by ssl.vcxproj - Homepage: - http://www.openssl.org/ - - Building OpenSSL requires nasm.exe (the Netwide Assembler), version - 2.10 or newer from - http://www.nasm.us/ - to be somewhere on your PATH. More recent versions of OpenSSL may - need a later version of NASM. If OpenSSL's self tests don't pass, - you should first try to update NASM and do a full rebuild of - OpenSSL. - - If you like to use the official sources instead of the files from - python.org's subversion repository, Perl is required to build the - necessary makefiles and assembly files. ActivePerl is available - from - http://www.activestate.com/activeperl/ - The svn.python.org version contains pre-built makefiles and assembly - files. - - The build process makes sure that no patented algorithms are - included. For now RC5, MDC2 and IDEA are excluded from the build. - You may have to manually remove $(OBJ_D)\i_*.obj from ms\nt.mak if - using official sources; the svn.python.org-hosted version is already - fixed. - - The ssl.vcxproj sub-project simply invokes PCbuild/build_ssl.py, - which locates and builds OpenSSL. - - build_ssl.py attempts to catch the most common errors (such as not - being able to find OpenSSL sources, or not being able to find a Perl - that works with OpenSSL) and give a reasonable error message. If - you have a problem that doesn't seem to be handled correctly (e.g., - you know you have ActivePerl but we can't find it), please take a - peek at build_ssl.py and suggest patches. Note that build_ssl.py - should be able to be run directly from the command-line. - - The ssl sub-project does not have the ability to clean the OpenSSL - build; if you need to rebuild, you'll have to clean it by hand. -_sqlite3 - Wraps SQLite 3.8.1, which is itself built by sqlite3.vcxproj - Homepage: - http://www.sqlite.org/ -_tkinter - Wraps version 8.6.1 of the Tk windowing system. - Homepage: - http://www.tcl.tk/ - - Unlike the other external libraries listed above, Tk must be built - separately before the _tkinter module can be built. This means that - a pre-built Tcl/Tk installation is expected in ..\..\tcltk (tcltk64 - for 64-bit) relative to this directory. See "Getting External - Sources" below for the easiest method to ensure Tcl/Tk is built. - - -Getting External Sources ------------------------- - -The last category of sub-projects listed above wrap external projects -Python doesn't control, and as such a little more work is required in -order to download the relevant source files for each project before they -can be built. The buildbots must ensure that all libraries are present -before building, so the easiest approach is to run either external.bat -or external-amd64.bat (depending on platform) in the ..\Tools\buildbot -directory from ..\, i.e.: - - C:\python\cpython\PCbuild>cd .. - C:\python\cpython>Tools\buildbot\external.bat - -This extracts all the external sub-projects from - http://svn.python.org/projects/external -via Subversion (so you'll need an svn.exe on your PATH) and places them -in ..\.. (relative to this directory). - -It is also possible to download sources from each project's homepage, -though you may have to change the names of some folders in order to make -things work. For instance, if you were to download a version 5.0.7 of -XZ Utils, you would need to extract the archive into ..\..\xz-5.0.5 -anyway, since that is where the solution is set to look for xz. The -same is true for all other external projects. - -The external(-amd64).bat scripts will also build a debug build of -Tcl/Tk, but there aren't any equivalent batch files for building release -versions of Tcl/Tk currently available. If you need to build a release -version of Tcl/Tk, just take a look at the relevant external(-amd64).bat -file and find the two nmake lines, then call each one without the -'DEBUG=1' parameter, i.e.: - -The external-amd64.bat file contains this for tcl: - nmake -f makefile.vc DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 clean all install - -So for a release build, you'd call it as: - nmake -f makefile.vc MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 clean all install - -Note that the above command is called from within ..\..\tcl-8.6.1.0\win -(relative to this directory); don't forget to build Tk as well as Tcl! - -This will be cleaned up in the future; http://bugs.python.org/issue15968 -tracks adding a new tcltk.vcxproj file that will build Tcl/Tk and Tix -the same way the other external projects listed above are built. - - -Building for AMD64 ------------------- - -The build process for AMD64 / x64 is very similar to standard builds, -you just have to set x64 as platform. In addition, the HOST_PYTHON -environment variable must point to a Python interpreter (at least 2.4), -to support cross-compilation from Win32. Note that Visual Studio -requires either Standard Edition or better, or Express Edition with the -Windows SDK 64-bit compilers to be available in order to build 64-bit -binaries. - - -Profile Guided Optimization ---------------------------- - -The solution has two configurations for PGO. The PGInstrument -configuration must be built first. The PGInstrument binaries are linked -against a profiling library and contain extra debug information. The -PGUpdate configuration takes the profiling data and generates optimized -binaries. - -The build_pgo.bat script automates the creation of optimized binaries. -It creates the PGI files, runs the unit test suite or PyBench with the -PGI python, and finally creates the optimized files. - -See - http://msdn.microsoft.com/en-us/library/e7k32f4k(VS.100).aspx -for more on this topic. - - -Static library --------------- - -The solution has no configuration for static libraries. However it is -easy to build a static library instead of a DLL. You simply have to set -the "Configuration Type" to "Static Library (.lib)" and alter the -preprocessor macro "Py_ENABLE_SHARED" to "Py_NO_ENABLE_SHARED". You may -also have to change the "Runtime Library" from "Multi-threaded DLL -(/MD)" to "Multi-threaded (/MT)". - - -Visual Studio properties ------------------------- - -The PCbuild solution makes heavy use of Visual Studio property files -(*.props). The properties can be viewed and altered in the Property -Manager (View -> Other Windows -> Property Manager). - -The property files used are (+-- = "also imports"): - * debug (debug macro: _DEBUG) - * pginstrument (PGO) - * pgupdate (PGO) - +-- pginstrument - * pyd (python extension, release build) - +-- release - +-- pyproject - * pyd_d (python extension, debug build) - +-- debug - +-- pyproject - * pyproject (base settings for all projects, user macros like PyDllName) - * release (release macro: NDEBUG) - * sqlite3 (used only by sqlite3.vcxproj) - * x64 (AMD64 / x64 platform specific settings) - -The pyproject property file defines _WIN32 and x64 defines _WIN64 and -_M_X64 although the macros are set by the compiler, too. The GUI doesn't -always know about the macros and confuse the user with false -information. - - -Your Own Extension DLLs ------------------------ - -If you want to create your own extension module DLL (.pyd), there's an -example with easy-to-follow instructions in ..\PC\example\; read the -file readme.txt there first. +Quick Start Guide +----------------- + +1. Install Microsoft Visual Studio 2015, any edition. +2. Install Subversion, and make sure 'svn.exe' is on your PATH. +3. Run "build.bat -e" to build Python in 32-bit Release configuration. +4. (Optional, but recommended) Run the test suite with "rt.bat -q". + + +Building Python using Microsoft Visual C++ +------------------------------------------ + +This directory is used to build CPython for Microsoft Windows NT version +6.0 or higher (Windows Vista, Windows Server 2008, or later) on 32 and 64 +bit platforms. Using this directory requires an installation of +Microsoft Visual C++ 2015 (MSVC 14.0) of any edition. The specific +requirements are as follows: + +Visual Studio Express 2015 for Desktop +Visual Studio Professional 2015 + Either edition is sufficient for building all configurations except + for Profile Guided Optimization. + The Python build solution pcbuild.sln makes use of Solution Folders, + which this edition does not support. Any time pcbuild.sln is opened + or reloaded by Visual Studio, a warning about Solution Folders will + be displayed, which can be safely dismissed with no impact on your + ability to build Python. + Required for building 64-bit Debug and Release configuration builds +Visual Studio Premium 2015 + Required for building Release configuration builds that make use of + Profile Guided Optimization (PGO), on either platform. + +All you need to do to build is open the solution "pcbuild.sln" in Visual +Studio, select the desired combination of configuration and platform, +then build with "Build Solution". You can also build from the command +line using the "build.bat" script in this directory; see below for +details. The solution is configured to build the projects in the correct +order. + +The solution currently supports two platforms. The Win32 platform is +used to build standard x86-compatible 32-bit binaries, output into the +win32 sub-directory. The x64 platform is used for building 64-bit AMD64 +(aka x86_64 or EM64T) binaries, output into the amd64 sub-directory. +The Itanium (IA-64) platform is no longer supported. + +Four configuration options are supported by the solution: +Debug + Used to build Python with extra debugging capabilities, equivalent + to using ./configure --with-pydebug on UNIX. All binaries built + using this configuration have "_d" added to their name: + python36_d.dll, python_d.exe, parser_d.pyd, and so on. Both the + build and rt (run test) batch files in this directory accept a -d + option for debug builds. If you are building Python to help with + development of CPython, you will most likely use this configuration. +PGInstrument, PGUpdate + Used to build Python in Release configuration using PGO, which + requires Premium Edition of Visual Studio. See the "Profile + Guided Optimization" section below for more information. Build + output from each of these configurations lands in its own + sub-directory of this directory. The official Python releases may + be built using these configurations. +Release + Used to build Python as it is meant to be used in production + settings, though without PGO. + + +Building Python using the build.bat script +---------------------------------------------- + +In this directory you can find build.bat, a script designed to make +building Python on Windows simpler. This script will use the env.bat +script to detect one of Visual Studio 2015, 2013, 2012, or 2010, any of +which may be used to build Python, though only Visual Studio 2015 is +officially supported. + +By default, build.bat will build Python in Release configuration for +the 32-bit Win32 platform. It accepts several arguments to change +this behavior, try `build.bat -h` to learn more. + + +C Runtime +--------- + +Visual Studio 2015 uses version 14 of the C runtime (MSVCRT14). The +executables no longer use the "Side by Side" assemblies used in previous +versions of the compiler. This simplifies distribution of applications. + +The run time libraries are available under the VC/Redist folder of your +Visual Studio distribution. For more info, see the Readme in the +VC/Redist folder. + + +Sub-Projects +------------ + +The CPython project is split up into several smaller sub-projects which +are managed by the pcbuild.sln solution file. Each sub-project is +represented by a .vcxproj and a .vcxproj.filters file starting with the +name of the sub-project. These sub-projects fall into a few general +categories: + +The following sub-projects represent the bare minimum required to build +a functioning CPython interpreter. If nothing else builds but these, +you'll have a very limited but usable python.exe: +pythoncore + .dll and .lib +python + .exe + +These sub-projects provide extra executables that are useful for running +CPython in different ways: +pythonw + pythonw.exe, a variant of python.exe that doesn't open a Command + Prompt window +pylauncher + py.exe, the Python Launcher for Windows, see + http://docs.python.org/3/using/windows.html#launcher +pywlauncher + pyw.exe, a variant of py.exe that doesn't open a Command Prompt + window +_testembed + _testembed.exe, a small program that embeds Python for testing + purposes, used by test_capi.py + +These are miscellaneous sub-projects that don't really fit the other +categories: +_freeze_importlib + _freeze_importlib.exe, used to regenerate Python\importlib.h after + changes have been made to Lib\importlib\_bootstrap.py +python3dll + python3.dll, the PEP 384 Stable ABI dll +xxlimited + builds an example module that makes use of the PEP 384 Stable ABI, + see Modules\xxlimited.c + +The following sub-projects are for individual modules of the standard +library which are implemented in C; each one builds a DLL (renamed to +.pyd) of the same name as the project: +_ctypes +_ctypes_test +_decimal +_elementtree +_hashlib +_msi +_multiprocessing +_overlapped +_socket +_testcapi +_testbuffer +_testimportmultiple +pyexpat +select +unicodedata +winsound + +The following Python-controlled sub-projects wrap external projects. +Note that these external libraries are not necessary for a working +interpreter, but they do implement several major features. See the +"Getting External Sources" section below for additional information +about getting the source for building these libraries. The sub-projects +are: +_bz2 + Python wrapper for version 1.0.6 of the libbzip2 compression library + Homepage: + http://www.bzip.org/ +_lzma + Python wrapper for the liblzma compression library, using pre-built + binaries of XZ Utils version 5.0.5 + Homepage: + http://tukaani.org/xz/ +_ssl + Python wrapper for version 1.0.2d of the OpenSSL secure sockets + library, which is built by ssl.vcxproj + Homepage: + http://www.openssl.org/ + + Building OpenSSL requires nasm.exe (the Netwide Assembler), version + 2.10 or newer from + http://www.nasm.us/ + to be somewhere on your PATH. More recent versions of OpenSSL may + need a later version of NASM. If OpenSSL's self tests don't pass, + you should first try to update NASM and do a full rebuild of + OpenSSL. If you use the PCbuild\get_externals.bat method + for getting sources, it also downloads a version of NASM which the + libeay/ssleay sub-projects use. + + The libeay/ssleay sub-projects expect your OpenSSL sources to have + already been configured and be ready to build. If you get your sources + from svn.python.org as suggested in the "Getting External Sources" + section below, the OpenSSL source will already be ready to go. If + you want to build a different version, you will need to run + + PCbuild\prepare_ssl.py path\to\openssl-source-dir + + That script will prepare your OpenSSL sources in the same way that + those available on svn.python.org have been prepared. Note that + Perl must be installed and available on your PATH to configure + OpenSSL. ActivePerl is recommended and is available from + http://www.activestate.com/activeperl/ + + The libeay and ssleay sub-projects will build the modules of OpenSSL + required by _ssl and _hashlib and may need to be manually updated when + upgrading to a newer version of OpenSSL or when adding new + functionality to _ssl or _hashlib. They will not clean up their output + with the normal Clean target; CleanAll should be used instead. +_sqlite3 + Wraps SQLite 3.8.11.0, which is itself built by sqlite3.vcxproj + Homepage: + http://www.sqlite.org/ +_tkinter + Wraps version 8.6.4 of the Tk windowing system. + Homepage: + http://www.tcl.tk/ + + Tkinter's dependencies are built by the tcl.vcxproj and tk.vcxproj + projects. The tix.vcxproj project also builds the Tix extended + widget set for use with Tkinter. + + Those three projects install their respective components in a + directory alongside the source directories called "tcltk" on + Win32 and "tcltk64" on x64. They also copy the Tcl and Tk DLLs + into the current output directory, which should ensure that Tkinter + is able to load Tcl/Tk without having to change your PATH. + + The tcl, tk, and tix sub-projects do not clean their builds with + the normal Clean target; if you need to rebuild, you should use the + CleanAll target or manually delete their builds. + + +Getting External Sources +------------------------ + +The last category of sub-projects listed above wrap external projects +Python doesn't control, and as such a little more work is required in +order to download the relevant source files for each project before they +can be built. However, a simple script is provided to make this as +painless as possible, called "get_externals.bat" and located in this +directory. This script extracts all the external sub-projects from + http://svn.python.org/projects/external +via Subversion (so you'll need svn.exe on your PATH) and places them +in ..\externals (relative to this directory). + +It is also possible to download sources from each project's homepage, +though you may have to change folder names or pass the names to MSBuild +as the values of certain properties in order for the build solution to +find them. This is an advanced topic and not necessarily fully +supported. + +The get_externals.bat script is called automatically by build.bat when +you pass the '-e' option to it. + + +Profile Guided Optimization +--------------------------- + +The solution has two configurations for PGO. The PGInstrument +configuration must be built first. The PGInstrument binaries are linked +against a profiling library and contain extra debug information. The +PGUpdate configuration takes the profiling data and generates optimized +binaries. + +The build_pgo.bat script automates the creation of optimized binaries. +It creates the PGI files, runs the unit test suite or PyBench with the +PGI python, and finally creates the optimized files. + +See + http://msdn.microsoft.com/en-us/library/e7k32f4k(VS.140).aspx +for more on this topic. + + +Static library +-------------- + +The solution has no configuration for static libraries. However it is +easy to build a static library instead of a DLL. You simply have to set +the "Configuration Type" to "Static Library (.lib)" and alter the +preprocessor macro "Py_ENABLE_SHARED" to "Py_NO_ENABLE_SHARED". You may +also have to change the "Runtime Library" from "Multi-threaded DLL +(/MD)" to "Multi-threaded (/MT)". + + +Visual Studio properties +------------------------ + +The PCbuild solution makes use of Visual Studio property files (*.props) +to simplify each project. The properties can be viewed in the Property +Manager (View -> Other Windows -> Property Manager) but should be +carefully modified by hand. + +The property files used are: + * python (versions, directories and build names) + * pyproject (base settings for all projects) + * openssl (used by libeay and ssleay projects) + * tcltk (used by _tkinter, tcl, tk and tix projects) + +The pyproject property file defines all of the build settings for each +project, with some projects overriding certain specific values. The GUI +doesn't always reflect the correct settings and may confuse the user +with false information, especially for settings that automatically adapt +for diffirent configurations. diff --git a/PCbuild/release.props b/PCbuild/release.props deleted file mode 100644 index acfe3e45ba2e..000000000000 --- a/PCbuild/release.props +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - - NDEBUG;%(PreprocessorDefinitions) - - - - - $(PyDebugExt) - - - \ No newline at end of file diff --git a/PCbuild/rt.bat b/PCbuild/rt.bat index 7129e203491f..2d93b80a499f 100644 --- a/PCbuild/rt.bat +++ b/PCbuild/rt.bat @@ -1,58 +1,60 @@ -@echo off -rem Run Tests. Run the regression test suite. -rem Usage: rt [-d] [-O] [-q] [-x64] regrtest_args -rem -d Run Debug build (python_d.exe). Else release build. -rem -O Run python.exe or python_d.exe (see -d) with -O. -rem -q "quick" -- normally the tests are run twice, the first time -rem after deleting all the .py[co] files reachable from Lib/. -rem -q runs the tests just once, and without deleting .py[co] files. -rem -x64 Run the 64-bit build of python (or python_d if -d was specified) -rem from the 'amd64' dir instead of the 32-bit build in this dir. -rem All leading instances of these switches are shifted off, and -rem whatever remains is passed to regrtest.py. For example, -rem rt -O -d -x test_thread -rem runs -rem python_d -O ../lib/test/regrtest.py -x test_thread -rem twice, and -rem rt -q -g test_binascii -rem runs -rem python_d ../lib/test/regrtest.py -g test_binascii -rem to generate the expected-output file for binascii quickly. -rem -rem Confusing: if you want to pass a comma-separated list, like -rem -u network,largefile -rem then you have to quote it on the rt line, like -rem rt -u "network,largefile" - -setlocal - -set prefix=.\ -set suffix= -set qmode= -set dashO= -set tcltk=tcltk - -:CheckOpts -if "%1"=="-O" (set dashO=-O) & shift & goto CheckOpts -if "%1"=="-q" (set qmode=yes) & shift & goto CheckOpts -if "%1"=="-d" (set suffix=_d) & shift & goto CheckOpts -if "%1"=="-x64" (set prefix=amd64) & (set tcltk=tcltk64) & shift & goto CheckOpts - -PATH %PATH%;%~dp0..\..\%tcltk%\bin -set exe=%prefix%\python%suffix% -set cmd=%exe% %dashO% -Wd -E -bb ../lib/test/regrtest.py %1 %2 %3 %4 %5 %6 %7 %8 %9 -if defined qmode goto Qmode - -echo Deleting .pyc/.pyo files ... -%exe% rmpyc.py - -echo on -%cmd% -@echo off - -echo About to run again without deleting .pyc/.pyo first: -pause - -:Qmode -echo on -%cmd% +@echo off +rem Run Tests. Run the regression test suite. +rem Usage: rt [-d] [-O] [-q] [-x64] regrtest_args +rem -d Run Debug build (python_d.exe). Else release build. +rem -O Run python.exe or python_d.exe (see -d) with -O. +rem -q "quick" -- normally the tests are run twice, the first time +rem after deleting all the .py[co] files reachable from Lib/. +rem -q runs the tests just once, and without deleting .py[co] files. +rem -x64 Run the 64-bit build of python (or python_d if -d was specified) +rem from the 'amd64' dir instead of the 32-bit build in this dir. +rem All leading instances of these switches are shifted off, and +rem whatever remains (up to 9 arguments) is passed to regrtest.py. +rem For example, +rem rt -O -d -x test_thread +rem runs +rem python_d -O ../lib/test/regrtest.py -x test_thread +rem twice, and +rem rt -q -g test_binascii +rem runs +rem python_d ../lib/test/regrtest.py -g test_binascii +rem to generate the expected-output file for binascii quickly. +rem +rem Confusing: if you want to pass a comma-separated list, like +rem -u network,largefile +rem then you have to quote it on the rt line, like +rem rt -u "network,largefile" + +setlocal + +set pcbuild=%~dp0 +set prefix=%pcbuild%win32\ +set suffix= +set qmode= +set dashO= +set regrtestargs= + +:CheckOpts +if "%1"=="-O" (set dashO=-O) & shift & goto CheckOpts +if "%1"=="-q" (set qmode=yes) & shift & goto CheckOpts +if "%1"=="-d" (set suffix=_d) & shift & goto CheckOpts +if "%1"=="-x64" (set prefix=%pcbuild%amd64\) & shift & goto CheckOpts +if NOT "%1"=="" (set regrtestargs=%regrtestargs% %1) & shift & goto CheckOpts + +set exe=%prefix%python%suffix%.exe +set cmd="%exe%" %dashO% -Wd -E -bb "%pcbuild%..\lib\test\regrtest.py" %regrtestargs% +if defined qmode goto Qmode + +echo Deleting .pyc/.pyo files ... +"%exe%" "%pcbuild%rmpyc.py" + +echo on +%cmd% +@echo off + +echo About to run again without deleting .pyc/.pyo first: +pause + +:Qmode +echo on +%cmd% diff --git a/PCbuild/select.vcxproj b/PCbuild/select.vcxproj index 7c36d646b724..3cd0694baa5f 100644 --- a/PCbuild/select.vcxproj +++ b/PCbuild/select.vcxproj @@ -37,186 +37,31 @@ {18CAE28C-B454-46C1-87A0-493D91D97F03} select - Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - MachineX64 - - - - - ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - + ws2_32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) 0x1D110000 - MachineX64 diff --git a/PCbuild/sqlite3.props b/PCbuild/sqlite3.props deleted file mode 100644 index d3ee02cf756d..000000000000 --- a/PCbuild/sqlite3.props +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - <_ProjectFileVersion>10.0.30319.1 - - - - $(sqlite3Dir);%(AdditionalIncludeDirectories) - SQLITE_API=__declspec(dllexport);%(PreprocessorDefinitions) - Level1 - - - \ No newline at end of file diff --git a/PCbuild/sqlite3.vcxproj b/PCbuild/sqlite3.vcxproj index daf010dae045..b6246fa78c54 100644 --- a/PCbuild/sqlite3.vcxproj +++ b/PCbuild/sqlite3.vcxproj @@ -37,188 +37,31 @@ {A1A295E5-463C-437F-81CA-1F32367685DA} sqlite3 - Win32Proj + .pyd + false + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - %(AdditionalIncludeDirectories) - - - $(OutDir)$(ProjectName)_d.dll - - - - - X64 - - - %(AdditionalIncludeDirectories) - - - $(OutDir)$(ProjectName)_d.dll - - - - - %(AdditionalIncludeDirectories) - - - $(OutDir)$(ProjectName).dll - - - - - X64 - - - %(AdditionalIncludeDirectories) - - - $(OutDir)$(ProjectName).dll - - - + $(sqlite3Dir);%(AdditionalIncludeDirectories) - - - $(OutDir)$(ProjectName).dll - - - - - X64 - - - %(AdditionalIncludeDirectories) - - - - - %(AdditionalIncludeDirectories) - - - $(OutDir)$(ProjectName).dll - - - - - X64 - - - %(AdditionalIncludeDirectories) + SQLITE_API=__declspec(dllexport);%(PreprocessorDefinitions) + Level1 @@ -228,12 +71,6 @@ - - - {6de10744-e396-40a5-b4e2-1b69aa7c8d31} - false - - diff --git a/PCbuild/ssl.vcxproj b/PCbuild/ssl.vcxproj deleted file mode 100644 index d5eac9ae0435..000000000000 --- a/PCbuild/ssl.vcxproj +++ /dev/null @@ -1,221 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - PGInstrument - Win32 - - - PGInstrument - x64 - - - PGUpdate - Win32 - - - PGUpdate - x64 - - - Release - Win32 - - - Release - x64 - - - - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0} - ssl - MakeFileProj - - - - Makefile - NotSet - - - Makefile - NotSet - - - Makefile - NotSet - - - Makefile - NotSet - - - Makefile - NotSet - - - Makefile - NotSet - - - Makefile - NotSet - - - Makefile - NotSet - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - echo OpenSSL must be cleaned manually if you want to rebuild it. - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - echo OpenSSL must be cleaned manually if you want to rebuild it. - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - echo OpenSSL must be cleaned manually if you want to rebuild it. - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - echo OpenSSL must be cleaned manually if you want to rebuild it. - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - echo OpenSSL must be cleaned manually if you want to rebuild it. - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - echo OpenSSL must be cleaned manually if you want to rebuild it. - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - echo OpenSSL must be cleaned manually if you want to rebuild it. - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - cd "$(SolutionDir)" -"$(PythonExe)" build_ssl.py Release $(Platform) -a - - - echo OpenSSL must be cleaned manually if you want to rebuild it. - - $(NMakePreprocessorDefinitions) - $(NMakeIncludeSearchPath) - $(NMakeForcedIncludes) - $(NMakeAssemblySearchPath) - $(NMakeForcedUsingAssemblies) - - - - - - {b11d750f-cd1f-4a96-85ce-e69a5c5259f9} - false - - - - - - \ No newline at end of file diff --git a/PCbuild/ssleay.vcxproj b/PCbuild/ssleay.vcxproj new file mode 100644 index 000000000000..439e3ac67452 --- /dev/null +++ b/PCbuild/ssleay.vcxproj @@ -0,0 +1,119 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Debug + x64 + + + Release + x64 + + + + {10615B24-73BF-4EFA-93AA-236916321317} + ssleay + + + + + + + StaticLibrary + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/tcl.vcxproj b/PCbuild/tcl.vcxproj new file mode 100644 index 000000000000..464c83ce80cf --- /dev/null +++ b/PCbuild/tcl.vcxproj @@ -0,0 +1,91 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Debug + x64 + + + Release + x64 + + + + {B5FD6F1D-129E-4BFF-9340-03606FAC7283} + + + + + + + + Makefile + $(tcltkDir) + $(OutDir)bin\$(tclDLLName) + + + + + + + + + + msvcrt + symbols,msvcrt + INSTALLDIR="$(OutDir.TrimEnd(`\`))" INSTALL_DIR="$(OutDir.TrimEnd(`\`))" + DEBUGFLAGS="-wd4456 -wd4457 -wd4458 -wd4459 -wd4996" + setlocal +@(ExpectedOutputs->'if not exist "%(FullPath)" goto build',' +') +goto :eof +:build +set VCINSTALLDIR=$(VCInstallDir) +cd /D "$(tclDir)win" +nmake -f makefile.vc MACHINE=$(TclMachine) OPTS=$(TclOpts) $(TclDirs) $(DebugFlags) core shell dlls +nmake -f makefile.vc MACHINE=$(TclMachine) OPTS=$(TclOpts) $(TclDirs) $(DebugFlags) install-binaries install-libraries + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/tcltk.props b/PCbuild/tcltk.props new file mode 100644 index 000000000000..5e794e553759 --- /dev/null +++ b/PCbuild/tcltk.props @@ -0,0 +1,45 @@ + + + + + 8 + 6 + 4 + 2 + $(TclMajorVersion) + $(TclMinorVersion) + $(TclPatchLevel) + $(TclRevision) + 8 + 4 + 3 + 6 + $(ExternalsDir)tcl-core-$(TclMajorVersion).$(TclMinorVersion).$(TclPatchLevel).$(TclRevision)\ + $(ExternalsDir)tk-$(TkMajorVersion).$(TkMinorVersion).$(TkPatchLevel).$(TkRevision)\ + $(ExternalsDir)tix-$(TixMajorVersion).$(TixMinorVersion).$(TixPatchLevel).$(TixRevision)\ + $(ExternalsDir)tcltk\ + $(ExternalsDir)tcltk64\ + g + tcl$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).dll + tcl$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).lib + tclsh$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).exe + tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).dll + tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).lib + tix$(TixMajorVersion)$(TixMinorVersion)$(TclDebugExt).dll + $(tcltkDir)lib\tix$(TixMajorVersion).$(TixMinorVersion).$(TixPatchLevel)\$(tixDLLName) + $(tcltkDir)lib\tcl$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).lib;$(tcltkDir)lib\tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).lib + IX86 + AMD64 + TCL_MAJOR_VERSION=$(TclMajorVersion) TCL_MINOR_VERSION=$(TclMinorVersion) TCL_PATCH_LEVEL=$(TclPatchLevel) + TCL_MAJOR=$(TclMajorVersion) TCL_MINOR=$(TclMinorVersion) TCL_PATCH=$(TclPatchLevel) + TK_MAJOR_VERSION=$(TkMajorVersion) TK_MINOR_VERSION=$(TkMinorVersion) TK_PATCH_LEVEL=$(TkPatchLevel) + + Release + Debug + $(BuildDirTop)_$(TclMachine) + $(BuildDirTop)_VC13 + $(BuildDirTop)_VC12 + $(BuildDirTop)_VC11 + $(BuildDirTop)_VC10 + + \ No newline at end of file diff --git a/PCbuild/tix.vcxproj b/PCbuild/tix.vcxproj new file mode 100644 index 000000000000..f857f9e67f17 --- /dev/null +++ b/PCbuild/tix.vcxproj @@ -0,0 +1,92 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Debug + x64 + + + Release + x64 + + + + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555} + tix + + + + + + + + Makefile + $(tcltkDir) + $(tixDLLPath) + + + + + + + + + + BUILDDIRTOP="$(BuildDirTop)" TCL_DIR="$(tclDir.TrimEnd(`\`))" TK_DIR="$(tkDir.TrimEnd(`\`))" INSTALL_DIR="$(OutDir.TrimEnd(`\`))" + DEBUG=1 NODEBUG=0 TCL_DBGX=g TK_DBGX=g + DEBUG=0 NODEBUG=1 + setlocal +@(ExpectedOutputs->'if not exist "%(FullPath)" goto build',' +') +goto :eof +:build +set VCINSTALLDIR=$(VCInstallDir) +cd /D "$(tixDir)win" +nmake /nologo -f makefile.vc MACHINE=$(TclMachine) $(DebugFlags) $(TclShortVersions) $(TixDirs) all install + + rmdir /q/s "$(OutDir.TrimEnd(`\`))" + + + + + {b5fd6f1d-129e-4bff-9340-03606fac7283} + false + + + {7e85eccf-a72c-4da4-9e52-884508e80ba1} + false + + + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/tk.vcxproj b/PCbuild/tk.vcxproj new file mode 100644 index 000000000000..20749f719f59 --- /dev/null +++ b/PCbuild/tk.vcxproj @@ -0,0 +1,95 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + PGInstrument + Win32 + + + PGInstrument + x64 + + + PGUpdate + Win32 + + + PGUpdate + x64 + + + Debug + x64 + + + Release + x64 + + + + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1} + tk + + + + + + + + Makefile + $(tcltkDir) + $(OutDir)bin\$(tkDLLName) + + + + + + + + + + msvcrt + symbols,msvcrt + TCLDIR="$(tclDir.TrimEnd(`\`))" INSTALLDIR="$(OutDir.TrimEnd(`\`))" + DEBUGFLAGS="-wd4456 -wd4457 -wd4458 -wd4459 -wd4996" + setlocal +@(ExpectedOutputs->'if not exist "%(FullPath)" goto build',' +') +goto :eof +:build +set VCINSTALLDIR=$(VCInstallDir) +cd /D "$(tkDir)win" +nmake /nologo -f makefile.vc RC=rc MACHINE=$(TclMachine) OPTS=$(TkOpts) $(TkDirs) $(DebugFlags) all +nmake /nologo -f makefile.vc RC=rc MACHINE=$(TclMachine) OPTS=$(TkOpts) $(TkDirs) $(DebugFlags) install-binaries install-libraries + + + + + {b5fd6f1d-129e-4bff-9340-03606fac7283} + false + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PCbuild/unicodedata.vcxproj b/PCbuild/unicodedata.vcxproj index c9d5278684a3..a3071fbf8eea 100644 --- a/PCbuild/unicodedata.vcxproj +++ b/PCbuild/unicodedata.vcxproj @@ -39,168 +39,29 @@ unicodedata Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - 0x1D120000 - - - - - X64 - - - 0x1D120000 - - - - - 0x1D120000 - - - - - X64 - - - 0x1D120000 - - - - - 0x1D120000 - - - - - X64 - - - 0x1D120000 - MachineX64 - - - - - 0x1D120000 - - - - - X64 - + 0x1D120000 - MachineX64 diff --git a/PCbuild/vs9to10.py b/PCbuild/vs9to10.py deleted file mode 100644 index eb7dab50b882..000000000000 --- a/PCbuild/vs9to10.py +++ /dev/null @@ -1,56 +0,0 @@ -#Run this file after automatic conversion of the VisualStudio 2008 solution by VisualStudio 2010. -#This can be done whenever the 2008 solution changes. -#It will make the necessary cleanup and updates to the vcxproj files -#the .props files need to be maintained by hand if the .vsprops files change - -from __future__ import with_statement -import sys -import os -import os.path - -def vs9to10(src, dest): - for name in os.listdir(src): - path, ext = os.path.splitext(name) - if ext.lower() not in ('.vcxproj',): - continue - - filename = os.path.normpath(os.path.join(src, name)) - destname = os.path.normpath(os.path.join(dest, name)) - print("%s -> %s" % (filename, destname)) - - lines = [] - lastline = b"" - importgroup = False - with open(filename, 'rb') as fin: - for line in fin: - #remove redundant linker output info - if b"" in line: - continue - if b"" in line: - continue - if b"" in line and b"" in line: - continue - - #add new property sheet to the pythoncore - if importgroup and "pythoncore" in name.lower(): - if b"" in line: - if b"debug.props" in lastline: - lines.append(b' \r\n') - elif b"pythoncore" not in lastline: - lines.append(b' \r\n') - if b"" in line: - importgroup = False - lines.append(line) - lastline = line - with open(destname, 'wb') as fout: - for line in lines: - fout.write(line) - -if __name__ == "__main__": - src = "." if len(sys.argv) < 2 else sys.argv[1] - name = os.path.basename(os.path.abspath(src)) - dest = os.path.abspath(os.path.join(src, "..", name + "Upd")) - os.makedirs(dest) - vs9to10(src, dest) diff --git a/PCbuild/vs9to8.py b/PCbuild/vs9to8.py deleted file mode 100644 index 3b88a16c27c5..000000000000 --- a/PCbuild/vs9to8.py +++ /dev/null @@ -1,34 +0,0 @@ -from __future__ import with_statement -import os - -def vs9to8(src, dest): - for name in os.listdir(src): - path, ext = os.path.splitext(name) - if ext.lower() not in ('.sln', '.vcproj', '.vsprops'): - continue - - filename = os.path.normpath(os.path.join(src, name)) - destname = os.path.normpath(os.path.join(dest, name)) - print("%s -> %s" % (filename, destname)) - - with open(filename, 'rU') as fin: - lines = fin.read() - lines = lines.replace('Version="9,00"', 'Version="8.00"') - lines = lines.replace('Version="9.00"', 'Version="8.00"') - lines = lines.replace('Format Version 10.00', 'Format Version 9.00') - lines = lines.replace('Visual Studio 2008', 'Visual Studio 2005') - - lines = lines.replace('wininst-9.0', 'wininst-8.0') - lines = lines.replace('..\\', '..\\..\\') - lines = lines.replace('..\\..\\..\\..\\', '..\\..\\..\\') - - # Bah. VS8.0 does not expand macros in file names. - # Replace them here. - lines = lines.replace('$(sqlite3Dir)', '..\\..\\..\\sqlite-3.6.21') - - with open(destname, 'wb') as fout: - lines = lines.replace("\n", "\r\n").encode() - fout.write(lines) - -if __name__ == "__main__": - vs9to8(src="http://github.com/", dest="../PC/VS8.0") diff --git a/PCbuild/winsound.vcxproj b/PCbuild/winsound.vcxproj index cf518e993642..540235af22e2 100644 --- a/PCbuild/winsound.vcxproj +++ b/PCbuild/winsound.vcxproj @@ -39,168 +39,29 @@ winsound Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - winmm.lib;%(AdditionalDependencies) - - - - - X64 - - - winmm.lib;%(AdditionalDependencies) - - - - - winmm.lib;%(AdditionalDependencies) - - - - - X64 - - - winmm.lib;%(AdditionalDependencies) - - - - - winmm.lib;%(AdditionalDependencies) - - - - - X64 - - - winmm.lib;%(AdditionalDependencies) - MachineX64 - - - - - winmm.lib;%(AdditionalDependencies) - - - - - X64 - + winmm.lib;%(AdditionalDependencies) - MachineX64 diff --git a/PCbuild/x64.props b/PCbuild/x64.props deleted file mode 100644 index 985c0ef7f7f8..000000000000 --- a/PCbuild/x64.props +++ /dev/null @@ -1,20 +0,0 @@ - - - - $(HOST_PYTHON) - - - - false - _WIN64;_M_X64;%(PreprocessorDefinitions) - - - MachineX64 - - - - - $(PythonExe) - - - diff --git a/PCbuild/xxlimited.vcxproj b/PCbuild/xxlimited.vcxproj index 26bc20d6ec56..9dbdc77335dd 100644 --- a/PCbuild/xxlimited.vcxproj +++ b/PCbuild/xxlimited.vcxproj @@ -1,6 +1,14 @@  + + Debug + Win32 + + + Debug + x64 + PGInstrument Win32 @@ -31,161 +39,42 @@ xxlimited Win32Proj + - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - - DynamicLibrary - NotSet - true - - + DynamicLibrary NotSet - true + false + + .pyd + - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + <_ProjectFileVersion>10.0.30319.1 - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - - - NDEBUG;_WIN32;_WINDLL;Py_LIMITED_API - - - wsock32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - - - wsock32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - Py_LIMITED_API;%(PreprocessorDefinitions) - - - wsock32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - - - wsock32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - MachineX64 - - - + - Py_LIMITED_API;%(PreprocessorDefinitions) + %(PreprocessorDefinitions);Py_LIMITED_API=0x03060000 wsock32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) - 0x1D110000 - - - - - X64 - - - wsock32.lib;%(AdditionalDependencies) - libc;%(IgnoreSpecificDefaultLibraries) 0x1D110000 - MachineX64 - - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} + + {885d4898-d08d-4091-9c40-c700cfe3fc5a} diff --git a/Parser/Python.asdl b/Parser/Python.asdl index debd89edb851..22775c683593 100644 --- a/Parser/Python.asdl +++ b/Parser/Python.asdl @@ -9,13 +9,14 @@ module Python -- 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) - | ClassDef(identifier name, + stmt = FunctionDef(identifier name, arguments args, + stmt* body, expr* decorator_list, expr? returns) + | AsyncFunctionDef(identifier name, arguments args, + stmt* body, expr* decorator_list, expr? returns) + + | ClassDef(identifier name, expr* bases, keyword* keywords, - expr? starargs, - expr? kwargs, stmt* body, expr* decorator_list) | Return(expr? value) @@ -26,9 +27,11 @@ module Python -- use 'orelse' because else is a keyword in target languages | For(expr target, expr iter, stmt* body, stmt* orelse) + | AsyncFor(expr target, expr iter, stmt* body, stmt* orelse) | While(expr test, stmt* body, stmt* orelse) | If(expr test, stmt* body, stmt* orelse) | With(withitem* items, stmt* body) + | AsyncWith(withitem* items, stmt* body) | Raise(expr? exc, expr? cause) | Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody) @@ -59,15 +62,17 @@ module Python | 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, - expr? starargs, expr? kwargs) + | Call(expr func, expr* args, keyword* keywords) | Num(object n) -- a number as a PyObject. | Str(string s) -- need to specify raw, unicode, etc? + | FormattedValue(expr value, int? conversion, expr? format_spec) + | JoinedStr(expr* values) | Bytes(bytes s) | NameConstant(singleton value) | Ellipsis @@ -77,7 +82,7 @@ module Python | 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) + | 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 @@ -85,13 +90,13 @@ module Python expr_context = Load | Store | Del | AugLoad | AugStore | Param - slice = Slice(expr? lower, expr? upper, expr? step) - | ExtSlice(slice* dims) - | Index(expr value) + slice = Slice(expr? lower, expr? upper, expr? step) + | ExtSlice(slice* dims) + | Index(expr value) - boolop = And | Or + boolop = And | Or - operator = Add | Sub | Mult | Div | Mod | Pow | LShift + operator = Add | Sub | Mult | MatMult | Div | Mod | Pow | LShift | RShift | BitOr | BitXor | BitAnd | FloorDiv unaryop = Invert | Not | UAdd | USub @@ -109,8 +114,8 @@ module Python arg = (identifier arg, expr? annotation) attributes (int lineno, int col_offset) - -- keyword arguments supplied to call - keyword = (identifier arg, expr value) + -- 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) diff --git a/Parser/asdl.py b/Parser/asdl.py index fc1b16c66815..121cdab95203 100644 --- a/Parser/asdl.py +++ b/Parser/asdl.py @@ -1,255 +1,52 @@ -"""An implementation of the Zephyr Abstract Syntax Definition Language. - -See http://asdl.sourceforge.net/ and -http://www.cs.princeton.edu/research/techreps/TR-554-97 - -Only supports top level module decl, not view. I'm guessing that view -is intended to support the browser and I'm not interested in the -browser. - -Changes for Python: Add support for module versions -""" - -import os -import sys -import traceback - -import spark - -def output(*strings): - for s in strings: - sys.stdout.write(str(s) + "\n") - - -class Token(object): - # spark seems to dispatch in the parser based on a token's - # type attribute - def __init__(self, type, lineno): - self.type = type - self.lineno = lineno - - def __str__(self): - return self.type - +#------------------------------------------------------------------------------- +# 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'} + +class AST: def __repr__(self): - return str(self) - -class Id(Token): - def __init__(self, value, lineno): - self.type = 'Id' - self.value = value - self.lineno = lineno - - def __str__(self): - return self.value - -class String(Token): - def __init__(self, value, lineno): - self.type = 'String' - self.value = value - self.lineno = lineno - -class ASDLSyntaxError(Exception): - - def __init__(self, lineno, token=None, msg=None): - self.lineno = lineno - self.token = token - self.msg = msg - - def __str__(self): - if self.msg is None: - return "Error at '%s', line %d" % (self.token, self.lineno) - else: - return "%s, line %d" % (self.msg, self.lineno) - -class ASDLScanner(spark.GenericScanner, object): - - def tokenize(self, input): - self.rv = [] - self.lineno = 1 - super(ASDLScanner, self).tokenize(input) - return self.rv - - def t_id(self, s): - r"[\w\.]+" - # XXX doesn't distinguish upper vs. lower, which is - # significant for ASDL. - self.rv.append(Id(s, self.lineno)) - - def t_string(self, s): - r'"[^"]*"' - self.rv.append(String(s, self.lineno)) - - def t_xxx(self, s): # not sure what this production means - r"<=" - self.rv.append(Token(s, self.lineno)) - - def t_punctuation(self, s): - r"[\{\}\*\=\|\(\)\,\?\:]" - self.rv.append(Token(s, self.lineno)) - - def t_comment(self, s): - r"\-\-[^\n]*" - pass - - def t_newline(self, s): - r"\n" - self.lineno += 1 - - def t_whitespace(self, s): - r"[ \t]+" - pass - - def t_default(self, s): - r" . +" - raise ValueError("unmatched input: %r" % s) - -class ASDLParser(spark.GenericParser, object): - def __init__(self): - super(ASDLParser, self).__init__("module") - - def typestring(self, tok): - return tok.type - - def error(self, tok): - raise ASDLSyntaxError(tok.lineno, tok) - - def p_module_0(self, info): - " module ::= Id Id { } " - module, name, _0, _1 = info - if module.value != "module": - raise ASDLSyntaxError(module.lineno, - msg="expected 'module', found %s" % module) - return Module(name, None) - - def p_module(self, info): - " module ::= Id Id { definitions } " - module, name, _0, definitions, _1 = info - if module.value != "module": - raise ASDLSyntaxError(module.lineno, - msg="expected 'module', found %s" % module) - return Module(name, definitions) - - def p_definition_0(self, definition): - " definitions ::= definition " - return definition[0] - - def p_definition_1(self, definitions): - " definitions ::= definition definitions " - return definitions[0] + definitions[1] - - def p_definition(self, info): - " definition ::= Id = type " - id, _, type = info - return [Type(id, type)] - - def p_type_0(self, product): - " type ::= product " - return product[0] - - def p_type_1(self, sum): - " type ::= sum " - return Sum(sum[0]) - - def p_type_2(self, info): - " type ::= sum Id ( fields ) " - sum, id, _0, attributes, _1 = info - if id.value != "attributes": - raise ASDLSyntaxError(id.lineno, - msg="expected attributes, found %s" % id) - return Sum(sum, attributes) - - def p_product_0(self, info): - " product ::= ( fields ) " - _0, fields, _1 = info - return Product(fields) - - def p_product_1(self, info): - " product ::= ( fields ) Id ( fields ) " - _0, fields, _1, id, _2, attributes, _3 = info - if id.value != "attributes": - raise ASDLSyntaxError(id.lineno, - msg="expected attributes, found %s" % id) - return Product(fields, attributes) - - def p_sum_0(self, constructor): - " sum ::= constructor " - return [constructor[0]] - - def p_sum_1(self, info): - " sum ::= constructor | sum " - constructor, _, sum = info - return [constructor] + sum - - def p_sum_2(self, info): - " sum ::= constructor | sum " - constructor, _, sum = info - return [constructor] + sum - - def p_constructor_0(self, id): - " constructor ::= Id " - return Constructor(id[0]) - - def p_constructor_1(self, info): - " constructor ::= Id ( fields ) " - id, _0, fields, _1 = info - return Constructor(id, fields) - - def p_fields_0(self, field): - " fields ::= field " - return [field[0]] - - def p_fields_1(self, info): - " fields ::= fields , field " - fields, _, field = info - return fields + [field] - - def p_field_0(self, type_): - " field ::= Id " - return Field(type_[0]) - - def p_field_1(self, info): - " field ::= Id Id " - type, name = info - return Field(type, name) - - def p_field_2(self, info): - " field ::= Id * Id " - type, _, name = info - return Field(type, name, seq=True) - - def p_field_3(self, info): - " field ::= Id ? Id " - type, _, name = info - return Field(type, name, opt=True) - - def p_field_4(self, type_): - " field ::= Id * " - return Field(type_[0], seq=True) - - def p_field_5(self, type_): - " field ::= Id ? " - return Field(type[0], opt=True) - -builtin_types = ("identifier", "string", "bytes", "int", "object", "singleton") - -# below is a collection of classes to capture the AST of an AST :-) -# not sure if any of the methods are useful yet, but I'm adding them -# piecemeal as they seem helpful - -class AST(object): - pass # a marker class + raise NotImplementedError class Module(AST): def __init__(self, name, dfns): self.name = name self.dfns = dfns - self.types = {} # maps type name to value (from dfns) - for type in dfns: - self.types[type.name.value] = type.value + self.types = {type.name: type.value for type in dfns} def __repr__(self): - return "Module(%s, %s)" % (self.name, self.dfns) + return 'Module({0.name}, {0.dfns})'.format(self) class Type(AST): def __init__(self, name, value): @@ -257,7 +54,7 @@ def __init__(self, name, value): self.value = value def __repr__(self): - return "Type(%s, %s)" % (self.name, self.value) + return 'Type({0.name}, {0.value})'.format(self) class Constructor(AST): def __init__(self, name, fields=None): @@ -265,7 +62,7 @@ def __init__(self, name, fields=None): self.fields = fields or [] def __repr__(self): - return "Constructor(%s, %s)" % (self.name, self.fields) + return 'Constructor({0.name}, {0.fields})'.format(self) class Field(AST): def __init__(self, type, name=None, seq=False, opt=False): @@ -282,9 +79,9 @@ def __repr__(self): else: extra = "" if self.name is None: - return "Field(%s%s)" % (self.type, extra) + return 'Field({0.type}{1})'.format(self, extra) else: - return "Field(%s, %s%s)" % (self.type, self.name, extra) + return 'Field({0.type}, {0.name}{1})'.format(self, extra) class Sum(AST): def __init__(self, types, attributes=None): @@ -292,10 +89,10 @@ def __init__(self, types, attributes=None): self.attributes = attributes or [] def __repr__(self): - if self.attributes is None: - return "Sum(%s)" % self.types + if self.attributes: + return 'Sum({0.types}, {0.attributes})'.format(self) else: - return "Sum(%s, %s)" % (self.types, self.attributes) + return 'Sum({0.types})'.format(self) class Product(AST): def __init__(self, fields, attributes=None): @@ -303,49 +100,43 @@ def __init__(self, fields, attributes=None): self.attributes = attributes or [] def __repr__(self): - if self.attributes is None: - return "Product(%s)" % self.fields + if self.attributes: + return 'Product({0.fields}, {0.attributes})'.format(self) else: - return "Product(%s, %s)" % (self.fields, self.attributes) + return 'Product({0.fields})'.format(self) -class VisitorBase(object): +# 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. - def __init__(self, skip=False): +class VisitorBase(object): + """Generic tree visitor for ASTs.""" + def __init__(self): self.cache = {} - self.skip = skip - def visit(self, object, *args): - meth = self._dispatch(object) - if meth is None: - return - try: - meth(object, *args) - except Exception: - output("Error visiting" + repr(object)) - output(str(sys.exc_info()[1])) - traceback.print_exc() - # XXX hack - if hasattr(self, 'file'): - self.file.flush() - os._exit(1) - - def _dispatch(self, object): - assert isinstance(object, AST), repr(object) - klass = object.__class__ + def visit(self, obj, *args): + klass = obj.__class__ meth = self.cache.get(klass) if meth is None: methname = "visit" + klass.__name__ - if self.skip: - meth = getattr(self, methname, None) - else: - meth = getattr(self, methname) + meth = getattr(self, methname, None) self.cache[klass] = meth - return 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__(skip=True) + super(Check, self).__init__() self.cons = {} self.errors = 0 self.types = {} @@ -367,8 +158,8 @@ def visitConstructor(self, cons, name): if conflict is None: self.cons[key] = name else: - output("Redefinition of constructor %s" % key) - output("Defined in %s and %s" % (conflict, name)) + 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) @@ -383,6 +174,11 @@ def visitProduct(self, prod, name): 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) @@ -390,47 +186,190 @@ def check(mod): if t not in mod.types and not t in builtin_types: v.errors += 1 uses = ", ".join(v.types[t]) - output("Undefined type %s, used in %s" % (t, uses)) - + print('Undefined type {}, used in {}'.format(t, uses)) return not v.errors -def parse(file): - scanner = ASDLScanner() - parser = ASDLParser() - - f = open(file) - try: - buf = f.read() - finally: - f.close() - tokens = scanner.tokenize(buf) - try: - return parser.parse(tokens) - except ASDLSyntaxError: - err = sys.exc_info()[1] - output(str(err)) - lines = buf.split("\n") - output(lines[err.lineno - 1]) # lines starts at 0, files at 1 - -if __name__ == "__main__": - import glob - import sys - - if len(sys.argv) > 1: - files = sys.argv[1:] - else: - testdir = "tests" - files = glob.glob(testdir + "/*.asdl") - - for file in files: - output(file) - mod = parse(file) - if not mod: - break - output("module", mod.name) - output(len(mod.dfns), "definitions") - if not check(mod): - output("Check failed") +# 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: - for dfn in mod.dfns: - output(dfn.name, dfn.value) + 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/Parser/asdl_c.py b/Parser/asdl_c.py old mode 100755 new mode 100644 index 80e432a3e960..d5971226b188 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -1,9 +1,6 @@ #! /usr/bin/env python """Generate C code from an ASDL description.""" -# TO DO -# handle fields that have a type but no name - import os, sys import asdl @@ -14,12 +11,8 @@ 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: - identifier, string, int. + This function special cases the default types provided by asdl. """ - # XXX ack! need to figure out where Id is useful and where string - if isinstance(name, asdl.Id): - name = name.value if name in asdl.builtin_types: return name else: @@ -144,7 +137,7 @@ def visitProduct(self, product, name, depth): class StructVisitor(EmitVisitor): - """Visitor to generate typdefs for AST.""" + """Visitor to generate typedefs for AST.""" def visitModule(self, mod): for dfn in mod.dfns: @@ -188,9 +181,6 @@ def visitConstructor(self, cons, depth): self.visit(f, depth + 1) self.emit("} %s;" % cons.name, depth) self.emit("", depth) - else: - # XXX not sure what I want here, nothing is probably fine - pass def visitField(self, field, depth): # XXX need to lookup field.type, because it might be something @@ -198,7 +188,7 @@ def visitField(self, field, depth): ctype = get_c_type(field.type) name = field.name if field.seq: - if field.type.value in ('cmpop',): + if field.type == 'cmpop': self.emit("asdl_int_seq *%(name)s;" % locals(), depth) else: self.emit("asdl_seq *%(name)s;" % locals(), depth) @@ -253,7 +243,7 @@ def get_args(self, fields): name = f.name # XXX should extend get_c_type() to handle this if f.seq: - if f.type.value in ('cmpop',): + if f.type == 'cmpop': ctype = "asdl_int_seq *" else: ctype = "asdl_seq *" @@ -437,7 +427,7 @@ def complexSum(self, sum, name): self.emit("", 0) for f in t.fields: self.visitField(f, t.name, sum=sum, depth=2) - args = [f.name.value for f in t.fields] + [a.name.value for a in sum.attributes] + 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) @@ -465,7 +455,7 @@ def visitProduct(self, prod, name): self.emit("", 0) for f in prod.fields: self.visitField(f, name, prod=prod, depth=1) - args = [f.name.value for f in prod.fields] + args = [f.name for f in prod.fields] self.emit("*out = %s(%s);" % (name, self.buildArgs(args)), 1) self.emit("return 0;", 1) self.emit("failed:", 0) @@ -487,8 +477,8 @@ def visitFieldDeclaration(self, field, name, sum=None, prod=None, depth=0): def isSimpleSum(self, field): # XXX can the members of this list be determined automatically? - return field.type.value in ('expr_context', 'boolop', 'operator', - 'unaryop', 'cmpop') + return field.type in ('expr_context', 'boolop', 'operator', + 'unaryop', 'cmpop') def isNumeric(self, field): return get_c_type(field.type) in ("int", "bool") @@ -908,7 +898,7 @@ def visitModule(self, mod): return 1; } - i = (int)PyLong_AsLong(obj); + i = _PyLong_AsInt(obj); if (i == -1 && PyErr_Occurred()) return 1; *out = i; @@ -960,7 +950,7 @@ def visitModule(self, mod): def visitProduct(self, prod, name): if prod.fields: - fields = name.value+"_fields" + fields = name+"_fields" else: fields = "NULL" self.emit('%s_type = make_type("%s", &AST_type, %s, %d);' % @@ -987,7 +977,7 @@ def visitSum(self, sum, name): def visitConstructor(self, cons, name, simple): if cons.fields: - fields = cons.name.value+"_fields" + fields = cons.name+"_fields" else: fields = "NULL" self.emit('%s_type = make_type("%s", %s_type, %s, %d);' % @@ -1170,7 +1160,7 @@ def emitSeq(self, field, value, depth, emit): 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.value == "cmpop": + if field.type == "cmpop": # While the sequence elements are stored as void*, # ast2obj_cmpop expects an enum self.emit("{", depth) @@ -1203,10 +1193,14 @@ class PartingShots(StaticVisitor): mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode) { mod_ty res; - PyObject *req_type[] = {(PyObject*)Module_type, (PyObject*)Expression_type, - (PyObject*)Interactive_type}; + PyObject *req_type[3]; char *req_name[] = {"Module", "Expression", "Interactive"}; int isinstance; + + 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()) @@ -1245,12 +1239,15 @@ def visit(self, object): common_msg = "/* File automatically generated by %s. */\n\n" -def main(srcfile): +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 INC_DIR: @@ -1297,16 +1294,19 @@ def main(srcfile): INC_DIR = '' SRC_DIR = '' - opts, args = getopt.getopt(sys.argv[1:], "h:c:") - if len(opts) != 1: - sys.stdout.write("Must specify exactly one output file\n") - sys.exit(1) + dump_module = False + opts, args = getopt.getopt(sys.argv[1:], "dh:c:") for o, v in opts: if o == '-h': INC_DIR = v if o == '-c': SRC_DIR = v - if len(args) != 1: - sys.stdout.write("Must specify single input file\n") + if o == '-d': + dump_module = True + if INC_DIR and SRC_DIR: + 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]) + main(args[0], dump_module) diff --git a/Parser/myreadline.c b/Parser/myreadline.c index a1c4b5c896ae..28c7b6d7fff8 100644 --- a/Parser/myreadline.c +++ b/Parser/myreadline.c @@ -15,10 +15,6 @@ #include "windows.h" #endif /* MS_WINDOWS */ -#ifdef __VMS -extern char* vms__StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt); -#endif - PyThreadState* _PyOS_ReadlineTState; @@ -189,11 +185,7 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) if (PyOS_ReadlineFunctionPointer == NULL) { -#ifdef __VMS - PyOS_ReadlineFunctionPointer = vms__StdioReadline; -#else PyOS_ReadlineFunctionPointer = PyOS_StdioReadline; -#endif } #ifdef WITH_THREAD diff --git a/Parser/node.c b/Parser/node.c index b26ce61c015a..00103240afd5 100644 --- a/Parser/node.c +++ b/Parser/node.c @@ -70,8 +70,8 @@ fancy_roundup(int n) * 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 ? _Py_SIZE_ROUND_UP((n), 4) : \ +#define XXXROUNDUP(n) ((n) <= 1 ? (n) : \ + (n) <= 128 ? (int)_Py_SIZE_ROUND_UP((n), 4) : \ fancy_roundup(n)) @@ -91,7 +91,7 @@ PyNode_AddChild(node *n1, int type, char *str, int lineno, int col_offset) if (current_capacity < 0 || required_capacity < 0) return E_OVERFLOW; if (current_capacity < required_capacity) { - if (required_capacity > PY_SIZE_MAX / sizeof(node)) { + if ((size_t)required_capacity > PY_SIZE_MAX / sizeof(node)) { return E_NOMEM; } n = n1->n_child; diff --git a/Parser/pgen.c b/Parser/pgen.c index b2f84709fc42..f3031aea0b6d 100644 --- a/Parser/pgen.c +++ b/Parser/pgen.c @@ -136,11 +136,12 @@ addnfa(nfagrammar *gr, char *name) static char REQNFMT[] = "metacompile: less than %d children\n"; -#define REQN(i, count) \ +#define REQN(i, count) do { \ if (i < count) { \ fprintf(stderr, REQNFMT, count); \ Py_FatalError("REQN"); \ - } else + } \ +} while (0) #else #define REQN(i, count) /* empty */ diff --git a/Parser/pgenmain.c b/Parser/pgenmain.c index 017a4f927430..0f055d630874 100644 --- a/Parser/pgenmain.c +++ b/Parser/pgenmain.c @@ -96,10 +96,11 @@ getgrammar(char *filename) fprintf(stderr, "Parsing error %d, line %d.\n", err.error, err.lineno); if (err.text != NULL) { - size_t i; + size_t len; + int i; fprintf(stderr, "%s", err.text); - i = strlen(err.text); - if (i == 0 || err.text[i-1] != '\n') + len = strlen(err.text); + if (len == 0 || err.text[len-1] != '\n') fprintf(stderr, "\n"); for (i = 0; i < err.offset; i++) { if (err.text[i] == '\t') diff --git a/Parser/printgrammar.c b/Parser/printgrammar.c index dd7e6ae2ef20..7311e55170de 100644 --- a/Parser/printgrammar.c +++ b/Parser/printgrammar.c @@ -84,7 +84,7 @@ static void printdfas(grammar *g, FILE *fp) { dfa *d; - int i, j; + int i, j, n; printstates(g, fp); fprintf(fp, "static dfa dfas[%d] = {\n", g->g_ndfas); @@ -93,7 +93,8 @@ printdfas(grammar *g, FILE *fp) fprintf(fp, " {%d, \"%s\", %d, %d, states_%d,\n", d->d_type, d->d_name, d->d_initial, d->d_nstates, i); fprintf(fp, " \""); - for (j = 0; j < NBYTES(g->g_ll.ll_nlabels); j++) + n = NBYTES(g->g_ll.ll_nlabels); + for (j = 0; j < n; j++) fprintf(fp, "\\%03o", d->d_first[j] & 0xff); fprintf(fp, "\"},\n"); } diff --git a/Parser/spark.py b/Parser/spark.py deleted file mode 100644 index 88c1a89a2793..000000000000 --- a/Parser/spark.py +++ /dev/null @@ -1,849 +0,0 @@ -# Copyright (c) 1998-2002 John Aycock -# -# 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. - -__version__ = 'SPARK-0.7 (pre-alpha-5)' - -import re - -# Compatibility with older pythons. -def output(string='', end='\n'): - sys.stdout.write(string + end) - -try: - sorted -except NameError: - def sorted(seq): - seq2 = seq[:] - seq2.sort() - return seq2 - -def _namelist(instance): - namelist, namedict, classlist = [], {}, [instance.__class__] - for c in classlist: - for b in c.__bases__: - classlist.append(b) - for name in c.__dict__.keys(): - if name not in namedict: - namelist.append(name) - namedict[name] = 1 - return namelist - -class GenericScanner: - def __init__(self, flags=0): - pattern = self.reflect() - self.re = re.compile(pattern, re.VERBOSE|flags) - - self.index2func = {} - for name, number in self.re.groupindex.items(): - self.index2func[number-1] = getattr(self, 't_' + name) - - def makeRE(self, name): - doc = getattr(self, name).__doc__ - rv = '(?P<%s>%s)' % (name[2:], doc) - return rv - - def reflect(self): - rv = [] - for name in _namelist(self): - if name[:2] == 't_' and name != 't_default': - rv.append(self.makeRE(name)) - - rv.append(self.makeRE('t_default')) - return '|'.join(rv) - - def error(self, s, pos): - output("Lexical error at position %s" % pos) - raise SystemExit - - def tokenize(self, s): - pos = 0 - n = len(s) - while pos < n: - m = self.re.match(s, pos) - if m is None: - self.error(s, pos) - - groups = m.groups() - for i in range(len(groups)): - if groups[i] and i in self.index2func: - self.index2func[i](groups[i]) - pos = m.end() - - def t_default(self, s): - r'( . | \n )+' - output("Specification error: unmatched input") - raise SystemExit - -# -# Extracted from GenericParser and made global so that [un]picking works. -# -class _State: - def __init__(self, stateno, items): - self.T, self.complete, self.items = [], [], items - self.stateno = stateno - -class GenericParser: - # - # An Earley parser, as per J. Earley, "An Efficient Context-Free - # Parsing Algorithm", CACM 13(2), pp. 94-102. Also J. C. Earley, - # "An Efficient Context-Free Parsing Algorithm", Ph.D. thesis, - # Carnegie-Mellon University, August 1968. New formulation of - # the parser according to J. Aycock, "Practical Earley Parsing - # and the SPARK Toolkit", Ph.D. thesis, University of Victoria, - # 2001, and J. Aycock and R. N. Horspool, "Practical Earley - # Parsing", unpublished paper, 2001. - # - - def __init__(self, start): - self.rules = {} - self.rule2func = {} - self.rule2name = {} - self.collectRules() - self.augment(start) - self.ruleschanged = 1 - - _NULLABLE = '\e_' - _START = 'START' - _BOF = '|-' - - # - # When pickling, take the time to generate the full state machine; - # some information is then extraneous, too. Unfortunately we - # can't save the rule2func map. - # - def __getstate__(self): - if self.ruleschanged: - # - # XXX - duplicated from parse() - # - self.computeNull() - self.newrules = {} - self.new2old = {} - self.makeNewRules() - self.ruleschanged = 0 - self.edges, self.cores = {}, {} - self.states = { 0: self.makeState0() } - self.makeState(0, self._BOF) - # - # XXX - should find a better way to do this.. - # - changes = 1 - while changes: - changes = 0 - for k, v in self.edges.items(): - if v is None: - state, sym = k - if state in self.states: - self.goto(state, sym) - changes = 1 - rv = self.__dict__.copy() - for s in self.states.values(): - del s.items - del rv['rule2func'] - del rv['nullable'] - del rv['cores'] - return rv - - def __setstate__(self, D): - self.rules = {} - self.rule2func = {} - self.rule2name = {} - self.collectRules() - start = D['rules'][self._START][0][1][1] # Blech. - self.augment(start) - D['rule2func'] = self.rule2func - D['makeSet'] = self.makeSet_fast - self.__dict__ = D - - # - # A hook for GenericASTBuilder and GenericASTMatcher. Mess - # thee not with this; nor shall thee toucheth the _preprocess - # argument to addRule. - # - def preprocess(self, rule, func): return rule, func - - def addRule(self, doc, func, _preprocess=1): - fn = func - rules = doc.split() - - index = [] - for i in range(len(rules)): - if rules[i] == '::=': - index.append(i-1) - index.append(len(rules)) - - for i in range(len(index)-1): - lhs = rules[index[i]] - rhs = rules[index[i]+2:index[i+1]] - rule = (lhs, tuple(rhs)) - - if _preprocess: - rule, fn = self.preprocess(rule, func) - - if lhs in self.rules: - self.rules[lhs].append(rule) - else: - self.rules[lhs] = [ rule ] - self.rule2func[rule] = fn - self.rule2name[rule] = func.__name__[2:] - self.ruleschanged = 1 - - def collectRules(self): - for name in _namelist(self): - if name[:2] == 'p_': - func = getattr(self, name) - doc = func.__doc__ - self.addRule(doc, func) - - def augment(self, start): - rule = '%s ::= %s %s' % (self._START, self._BOF, start) - self.addRule(rule, lambda args: args[1], 0) - - def computeNull(self): - self.nullable = {} - tbd = [] - - for rulelist in self.rules.values(): - lhs = rulelist[0][0] - self.nullable[lhs] = 0 - for rule in rulelist: - rhs = rule[1] - if len(rhs) == 0: - self.nullable[lhs] = 1 - continue - # - # We only need to consider rules which - # consist entirely of nonterminal symbols. - # This should be a savings on typical - # grammars. - # - for sym in rhs: - if sym not in self.rules: - break - else: - tbd.append(rule) - changes = 1 - while changes: - changes = 0 - for lhs, rhs in tbd: - if self.nullable[lhs]: - continue - for sym in rhs: - if not self.nullable[sym]: - break - else: - self.nullable[lhs] = 1 - changes = 1 - - def makeState0(self): - s0 = _State(0, []) - for rule in self.newrules[self._START]: - s0.items.append((rule, 0)) - return s0 - - def finalState(self, tokens): - # - # Yuck. - # - if len(self.newrules[self._START]) == 2 and len(tokens) == 0: - return 1 - start = self.rules[self._START][0][1][1] - return self.goto(1, start) - - def makeNewRules(self): - worklist = [] - for rulelist in self.rules.values(): - for rule in rulelist: - worklist.append((rule, 0, 1, rule)) - - for rule, i, candidate, oldrule in worklist: - lhs, rhs = rule - n = len(rhs) - while i < n: - sym = rhs[i] - if sym not in self.rules or \ - not self.nullable[sym]: - candidate = 0 - i = i + 1 - continue - - newrhs = list(rhs) - newrhs[i] = self._NULLABLE+sym - newrule = (lhs, tuple(newrhs)) - worklist.append((newrule, i+1, - candidate, oldrule)) - candidate = 0 - i = i + 1 - else: - if candidate: - lhs = self._NULLABLE+lhs - rule = (lhs, rhs) - if lhs in self.newrules: - self.newrules[lhs].append(rule) - else: - self.newrules[lhs] = [ rule ] - self.new2old[rule] = oldrule - - def typestring(self, token): - return None - - def error(self, token): - output("Syntax error at or near `%s' token" % token) - raise SystemExit - - def parse(self, tokens): - sets = [ [(1,0), (2,0)] ] - self.links = {} - - if self.ruleschanged: - self.computeNull() - self.newrules = {} - self.new2old = {} - self.makeNewRules() - self.ruleschanged = 0 - self.edges, self.cores = {}, {} - self.states = { 0: self.makeState0() } - self.makeState(0, self._BOF) - - for i in range(len(tokens)): - sets.append([]) - - if sets[i] == []: - break - self.makeSet(tokens[i], sets, i) - else: - sets.append([]) - self.makeSet(None, sets, len(tokens)) - - #_dump(tokens, sets, self.states) - - finalitem = (self.finalState(tokens), 0) - if finalitem not in sets[-2]: - if len(tokens) > 0: - self.error(tokens[i-1]) - else: - self.error(None) - - return self.buildTree(self._START, finalitem, - tokens, len(sets)-2) - - def isnullable(self, sym): - # - # For symbols in G_e only. If we weren't supporting 1.5, - # could just use sym.startswith(). - # - return self._NULLABLE == sym[0:len(self._NULLABLE)] - - def skip(self, hs, pos=0): - n = len(hs[1]) - while pos < n: - if not self.isnullable(hs[1][pos]): - break - pos = pos + 1 - return pos - - def makeState(self, state, sym): - assert sym is not None - # - # Compute \epsilon-kernel state's core and see if - # it exists already. - # - kitems = [] - for rule, pos in self.states[state].items: - lhs, rhs = rule - if rhs[pos:pos+1] == (sym,): - kitems.append((rule, self.skip(rule, pos+1))) - core = kitems - - core.sort() - tcore = tuple(core) - if tcore in self.cores: - return self.cores[tcore] - # - # Nope, doesn't exist. Compute it and the associated - # \epsilon-nonkernel state together; we'll need it right away. - # - k = self.cores[tcore] = len(self.states) - K, NK = _State(k, kitems), _State(k+1, []) - self.states[k] = K - predicted = {} - - edges = self.edges - rules = self.newrules - for X in K, NK: - worklist = X.items - for item in worklist: - rule, pos = item - lhs, rhs = rule - if pos == len(rhs): - X.complete.append(rule) - continue - - nextSym = rhs[pos] - key = (X.stateno, nextSym) - if nextSym not in rules: - if key not in edges: - edges[key] = None - X.T.append(nextSym) - else: - edges[key] = None - if nextSym not in predicted: - predicted[nextSym] = 1 - for prule in rules[nextSym]: - ppos = self.skip(prule) - new = (prule, ppos) - NK.items.append(new) - # - # Problem: we know K needs generating, but we - # don't yet know about NK. Can't commit anything - # regarding NK to self.edges until we're sure. Should - # we delay committing on both K and NK to avoid this - # hacky code? This creates other problems.. - # - if X is K: - edges = {} - - if NK.items == []: - return k - - # - # Check for \epsilon-nonkernel's core. Unfortunately we - # need to know the entire set of predicted nonterminals - # to do this without accidentally duplicating states. - # - core = sorted(predicted.keys()) - tcore = tuple(core) - if tcore in self.cores: - self.edges[(k, None)] = self.cores[tcore] - return k - - nk = self.cores[tcore] = self.edges[(k, None)] = NK.stateno - self.edges.update(edges) - self.states[nk] = NK - return k - - def goto(self, state, sym): - key = (state, sym) - if key not in self.edges: - # - # No transitions from state on sym. - # - return None - - rv = self.edges[key] - if rv is None: - # - # Target state isn't generated yet. Remedy this. - # - rv = self.makeState(state, sym) - self.edges[key] = rv - return rv - - def gotoT(self, state, t): - return [self.goto(state, t)] - - def gotoST(self, state, st): - rv = [] - for t in self.states[state].T: - if st == t: - rv.append(self.goto(state, t)) - return rv - - def add(self, set, item, i=None, predecessor=None, causal=None): - if predecessor is None: - if item not in set: - set.append(item) - else: - key = (item, i) - if item not in set: - self.links[key] = [] - set.append(item) - self.links[key].append((predecessor, causal)) - - def makeSet(self, token, sets, i): - cur, next = sets[i], sets[i+1] - - ttype = token is not None and self.typestring(token) or None - if ttype is not None: - fn, arg = self.gotoT, ttype - else: - fn, arg = self.gotoST, token - - for item in cur: - ptr = (item, i) - state, parent = item - add = fn(state, arg) - for k in add: - if k is not None: - self.add(next, (k, parent), i+1, ptr) - nk = self.goto(k, None) - if nk is not None: - self.add(next, (nk, i+1)) - - if parent == i: - continue - - for rule in self.states[state].complete: - lhs, rhs = rule - for pitem in sets[parent]: - pstate, pparent = pitem - k = self.goto(pstate, lhs) - if k is not None: - why = (item, i, rule) - pptr = (pitem, parent) - self.add(cur, (k, pparent), - i, pptr, why) - nk = self.goto(k, None) - if nk is not None: - self.add(cur, (nk, i)) - - def makeSet_fast(self, token, sets, i): - # - # Call *only* when the entire state machine has been built! - # It relies on self.edges being filled in completely, and - # then duplicates and inlines code to boost speed at the - # cost of extreme ugliness. - # - cur, next = sets[i], sets[i+1] - ttype = token is not None and self.typestring(token) or None - - for item in cur: - ptr = (item, i) - state, parent = item - if ttype is not None: - k = self.edges.get((state, ttype), None) - if k is not None: - #self.add(next, (k, parent), i+1, ptr) - #INLINED --v - new = (k, parent) - key = (new, i+1) - if new not in next: - self.links[key] = [] - next.append(new) - self.links[key].append((ptr, None)) - #INLINED --^ - #nk = self.goto(k, None) - nk = self.edges.get((k, None), None) - if nk is not None: - #self.add(next, (nk, i+1)) - #INLINED --v - new = (nk, i+1) - if new not in next: - next.append(new) - #INLINED --^ - else: - add = self.gotoST(state, token) - for k in add: - if k is not None: - self.add(next, (k, parent), i+1, ptr) - #nk = self.goto(k, None) - nk = self.edges.get((k, None), None) - if nk is not None: - self.add(next, (nk, i+1)) - - if parent == i: - continue - - for rule in self.states[state].complete: - lhs, rhs = rule - for pitem in sets[parent]: - pstate, pparent = pitem - #k = self.goto(pstate, lhs) - k = self.edges.get((pstate, lhs), None) - if k is not None: - why = (item, i, rule) - pptr = (pitem, parent) - #self.add(cur, (k, pparent), - # i, pptr, why) - #INLINED --v - new = (k, pparent) - key = (new, i) - if new not in cur: - self.links[key] = [] - cur.append(new) - self.links[key].append((pptr, why)) - #INLINED --^ - #nk = self.goto(k, None) - nk = self.edges.get((k, None), None) - if nk is not None: - #self.add(cur, (nk, i)) - #INLINED --v - new = (nk, i) - if new not in cur: - cur.append(new) - #INLINED --^ - - def predecessor(self, key, causal): - for p, c in self.links[key]: - if c == causal: - return p - assert 0 - - def causal(self, key): - links = self.links[key] - if len(links) == 1: - return links[0][1] - choices = [] - rule2cause = {} - for p, c in links: - rule = c[2] - choices.append(rule) - rule2cause[rule] = c - return rule2cause[self.ambiguity(choices)] - - def deriveEpsilon(self, nt): - if len(self.newrules[nt]) > 1: - rule = self.ambiguity(self.newrules[nt]) - else: - rule = self.newrules[nt][0] - #output(rule) - - rhs = rule[1] - attr = [None] * len(rhs) - - for i in range(len(rhs)-1, -1, -1): - attr[i] = self.deriveEpsilon(rhs[i]) - return self.rule2func[self.new2old[rule]](attr) - - def buildTree(self, nt, item, tokens, k): - state, parent = item - - choices = [] - for rule in self.states[state].complete: - if rule[0] == nt: - choices.append(rule) - rule = choices[0] - if len(choices) > 1: - rule = self.ambiguity(choices) - #output(rule) - - rhs = rule[1] - attr = [None] * len(rhs) - - for i in range(len(rhs)-1, -1, -1): - sym = rhs[i] - if sym not in self.newrules: - if sym != self._BOF: - attr[i] = tokens[k-1] - key = (item, k) - item, k = self.predecessor(key, None) - #elif self.isnullable(sym): - elif self._NULLABLE == sym[0:len(self._NULLABLE)]: - attr[i] = self.deriveEpsilon(sym) - else: - key = (item, k) - why = self.causal(key) - attr[i] = self.buildTree(sym, why[0], - tokens, why[1]) - item, k = self.predecessor(key, why) - return self.rule2func[self.new2old[rule]](attr) - - def ambiguity(self, rules): - # - # XXX - problem here and in collectRules() if the same rule - # appears in >1 method. Also undefined results if rules - # causing the ambiguity appear in the same method. - # - sortlist = [] - name2index = {} - for i in range(len(rules)): - lhs, rhs = rule = rules[i] - name = self.rule2name[self.new2old[rule]] - sortlist.append((len(rhs), name)) - name2index[name] = i - sortlist.sort() - list = [b for a, b in sortlist] - return rules[name2index[self.resolve(list)]] - - def resolve(self, list): - # - # Resolve ambiguity in favor of the shortest RHS. - # Since we walk the tree from the top down, this - # should effectively resolve in favor of a "shift". - # - return list[0] - -# -# GenericASTBuilder automagically constructs a concrete/abstract syntax tree -# for a given input. The extra argument is a class (not an instance!) -# which supports the "__setslice__" and "__len__" methods. -# -# XXX - silently overrides any user code in methods. -# - -class GenericASTBuilder(GenericParser): - def __init__(self, AST, start): - GenericParser.__init__(self, start) - self.AST = AST - - def preprocess(self, rule, func): - rebind = lambda lhs, self=self: \ - lambda args, lhs=lhs, self=self: \ - self.buildASTNode(args, lhs) - lhs, rhs = rule - return rule, rebind(lhs) - - def buildASTNode(self, args, lhs): - children = [] - for arg in args: - if isinstance(arg, self.AST): - children.append(arg) - else: - children.append(self.terminal(arg)) - return self.nonterminal(lhs, children) - - def terminal(self, token): return token - - def nonterminal(self, type, args): - rv = self.AST(type) - rv[:len(args)] = args - return rv - -# -# GenericASTTraversal is a Visitor pattern according to Design Patterns. For -# each node it attempts to invoke the method n_, falling -# back onto the default() method if the n_* can't be found. The preorder -# traversal also looks for an exit hook named n__exit (no default -# routine is called if it's not found). To prematurely halt traversal -# of a subtree, call the prune() method -- this only makes sense for a -# preorder traversal. Node type is determined via the typestring() method. -# - -class GenericASTTraversalPruningException: - pass - -class GenericASTTraversal: - def __init__(self, ast): - self.ast = ast - - def typestring(self, node): - return node.type - - def prune(self): - raise GenericASTTraversalPruningException - - def preorder(self, node=None): - if node is None: - node = self.ast - - try: - name = 'n_' + self.typestring(node) - if hasattr(self, name): - func = getattr(self, name) - func(node) - else: - self.default(node) - except GenericASTTraversalPruningException: - return - - for kid in node: - self.preorder(kid) - - name = name + '_exit' - if hasattr(self, name): - func = getattr(self, name) - func(node) - - def postorder(self, node=None): - if node is None: - node = self.ast - - for kid in node: - self.postorder(kid) - - name = 'n_' + self.typestring(node) - if hasattr(self, name): - func = getattr(self, name) - func(node) - else: - self.default(node) - - - def default(self, node): - pass - -# -# GenericASTMatcher. AST nodes must have "__getitem__" and "__cmp__" -# implemented. -# -# XXX - makes assumptions about how GenericParser walks the parse tree. -# - -class GenericASTMatcher(GenericParser): - def __init__(self, start, ast): - GenericParser.__init__(self, start) - self.ast = ast - - def preprocess(self, rule, func): - rebind = lambda func, self=self: \ - lambda args, func=func, self=self: \ - self.foundMatch(args, func) - lhs, rhs = rule - rhslist = list(rhs) - rhslist.reverse() - - return (lhs, tuple(rhslist)), rebind(func) - - def foundMatch(self, args, func): - func(args[-1]) - return args[-1] - - def match_r(self, node): - self.input.insert(0, node) - children = 0 - - for child in node: - if children == 0: - self.input.insert(0, '(') - children = children + 1 - self.match_r(child) - - if children > 0: - self.input.insert(0, ')') - - def match(self, ast=None): - if ast is None: - ast = self.ast - self.input = [] - - self.match_r(ast) - self.parse(self.input) - - def resolve(self, list): - # - # Resolve ambiguity in favor of the longest RHS. - # - return list[-1] - -def _dump(tokens, sets, states): - for i in range(len(sets)): - output('set %d' % i) - for item in sets[i]: - output('\t', item) - for (lhs, rhs), pos in states[item[0]].items: - output('\t\t', lhs, '::=', end='') - output(' '.join(rhs[:pos]), end='') - output('.', end='') - output(' '.join(rhs[pos:])) - if i < len(tokens): - output() - output('token %s' % str(tokens[i])) - output() diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index 5bf7e84f2616..2369be46ae92 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -98,10 +98,13 @@ const char *_PyParser_TokenNames[] = { "DOUBLESLASH", "DOUBLESLASHEQUAL", "AT", + "ATEQUAL", "RARROW", "ELLIPSIS", /* This table must match the #defines in token.h! */ "OP", + "AWAIT", + "ASYNC", "", "" }; @@ -123,6 +126,7 @@ tok_new(void) tok->tabsize = TABSIZE; tok->indent = 0; tok->indstack[0] = 0; + tok->atbol = 1; tok->pendin = 0; tok->prompt = tok->nextprompt = NULL; @@ -143,6 +147,11 @@ tok_new(void) tok->decoding_readline = NULL; tok->decoding_buffer = NULL; #endif + + tok->async_def = 0; + tok->async_def_indent = 0; + tok->async_def_nl = 0; + return tok; } @@ -283,13 +292,27 @@ check_coding_spec(const char* line, Py_ssize_t size, struct tok_state *tok, char *cs; int r = 1; - if (tok->cont_line) + 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) + 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); @@ -476,13 +499,21 @@ fp_setreadl(struct tok_state *tok, const char* enc) _Py_IDENTIFIER(open); _Py_IDENTIFIER(readline); int fd; + long pos; io = PyImport_ImportModuleNoBlock("io"); if (io == NULL) goto cleanup; fd = fileno(tok->fp); - if (lseek(fd, 0, SEEK_SET) == (off_t)-1) { + /* 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); goto cleanup; } @@ -495,14 +526,12 @@ fp_setreadl(struct tok_state *tok, const char* enc) Py_XDECREF(tok->decoding_readline); readline = _PyObject_GetAttrId(stream, &PyId_readline); tok->decoding_readline = readline; - - /* The file has been reopened; parsing will restart from - * the beginning of the file, we have to reset the line number. - * But this function has been called from inside tok_nextc() which - * will increment lineno before it returns. So we set it -1 so that - * the next call to tok_nextc() will start with tok->lineno == 0. - */ - tok->lineno = -1; + if (pos > 0) { + if (PyObject_CallObject(readline, NULL) == NULL) { + readline = NULL; + goto cleanup; + } + } cleanup: Py_XDECREF(stream); @@ -752,7 +781,7 @@ decode_str(const char *input, int single, struct tok_state *tok) if (newl[0]) { if (!check_coding_spec(str, newl[0] - str, tok, buf_setreadl)) return error_ret(tok); - if (tok->enc == NULL && newl[1]) { + 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); @@ -1111,7 +1140,7 @@ PyToken_OneChar(int c) case '}': return RBRACE; case '^': return CIRCUMFLEX; case '~': return TILDE; - case '@': return AT; + case '@': return AT; default: return OP; } } @@ -1187,6 +1216,11 @@ PyToken_TwoChars(int c1, int c2) case '=': return CIRCUMFLEXEQUAL; } break; + case '@': + switch (c2) { + case '=': return ATEQUAL; + } + break; } return OP; } @@ -1281,6 +1315,8 @@ 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 || PyUnicode_READY(s) == -1) { if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { @@ -1402,6 +1438,21 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end) } } + if (tok->async_def + && !blankline + && 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 */ @@ -1426,17 +1477,19 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end) nonascii = 0; if (is_potential_identifier_start(c)) { /* Process b"", r"", u"", br"" and rb"" */ - int saw_b = 0, saw_r = 0, saw_u = 0; + int saw_b = 0, saw_r = 0, saw_u = 0, saw_f = 0; while (1) { - if (!(saw_b || saw_u) && (c == 'b' || c == 'B')) + 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) && (c == 'u' || c == 'U')) + 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); @@ -1449,13 +1502,46 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end) c = tok_nextc(tok); } tok_backup(tok, c); - if (nonascii && - !verify_identifier(tok)) { - tok->done = E_IDENTIFIER; + 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) { + /* Current token length is 5. */ + if (tok->async_def) { + /* We're inside an 'async def' function. */ + 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.*/ + + 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 'async' NAME token, we return ASYNC. */ + tok->async_def_indent = tok->indent; + tok->async_def = 1; + return ASYNC; + } + } + } + return NAME; } @@ -1467,6 +1553,11 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end) *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; } @@ -1577,15 +1668,24 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end) } while (isdigit(c)); } if (c == 'e' || c == 'E') { - exponent: + int e; + exponent: + e = c; /* Exponent part */ c = tok_nextc(tok); - if (c == '+' || c == '-') + if (c == '+' || c == '-') { c = tok_nextc(tok); - if (!isdigit(c)) { - tok->done = E_TOKEN; + if (!isdigit(c)) { + tok->done = E_TOKEN; + tok_backup(tok, c); + return ERRORTOKEN; + } + } else if (!isdigit(c)) { tok_backup(tok, c); - return ERRORTOKEN; + tok_backup(tok, e); + *p_start = tok->start; + *p_end = tok->cur; + return NUMBER; } do { c = tok_nextc(tok); @@ -1643,7 +1743,7 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end) else { end_quote_size = 0; if (c == '\\') - c = tok_nextc(tok); /* skip escaped char */ + c = tok_nextc(tok); /* skip escaped char */ } } diff --git a/Parser/tokenizer.h b/Parser/tokenizer.h index 1ce6eeba8ca5..af053e250a3e 100644 --- a/Parser/tokenizer.h +++ b/Parser/tokenizer.h @@ -65,6 +65,13 @@ struct tok_state { const char* enc; /* Encoding for the current str. */ const char* str; const char* input; /* Tokenizer's newline translated copy of the string. */ + + /* async/await related fields; can be removed in 3.7 when async and await + become normal 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); diff --git a/Programs/README b/Programs/README new file mode 100644 index 000000000000..c24578bc08d2 --- /dev/null +++ b/Programs/README @@ -0,0 +1 @@ +Source files for binary executables (as opposed to shared modules) diff --git a/Modules/_freeze_importlib.c b/Programs/_freeze_importlib.c similarity index 82% rename from Modules/_freeze_importlib.c rename to Programs/_freeze_importlib.c index 57b1ac06624b..aecb1232af16 100644 --- a/Modules/_freeze_importlib.c +++ b/Programs/_freeze_importlib.c @@ -12,12 +12,11 @@ #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. */ -const static struct _frozen _PyImport_FrozenModules[] = { +static const struct _frozen _PyImport_FrozenModules[] = { {0, 0, 0} /* sentinel */ }; @@ -28,18 +27,19 @@ const static struct _frozen _PyImport_FrozenModules[] = { const struct _frozen *PyImport_FrozenModules; #endif -const char header[] = "/* Auto-generated by Modules/_freeze_importlib.c */"; +const char header[] = "/* Auto-generated by Programs/_freeze_importlib.c */"; int main(int argc, char *argv[]) { - char *inpath, *outpath; + char *inpath, *outpath, *code_name; FILE *infile = NULL, *outfile = NULL; - struct stat st; + struct _Py_stat_struct status; size_t text_size, data_size, n; char *text = NULL; unsigned char *data; PyObject *code = NULL, *marshalled = NULL; + int is_bootstrap = 1; PyImport_FrozenModules = _PyImport_FrozenModules; @@ -54,11 +54,11 @@ main(int argc, char *argv[]) fprintf(stderr, "cannot open '%s' for reading\n", inpath); goto error; } - if (fstat(fileno(infile), &st)) { + if (_Py_fstat_noraise(fileno(infile), &status)) { fprintf(stderr, "cannot fstat '%s'\n", inpath); goto error; } - text_size = st.st_size; + text_size = status.st_size; text = (char *) malloc(text_size + 1); if (text == NULL) { fprintf(stderr, "could not allocate %ld bytes\n", (long) text_size); @@ -82,8 +82,14 @@ main(int argc, char *argv[]) /* Don't install importlib, since it could execute outdated bytecode. */ _Py_InitializeEx_Private(1, 0); - code = Py_CompileStringExFlags(text, "", - Py_file_input, NULL, 0); + if (strstr(inpath, "_external") != NULL) { + is_bootstrap = 0; + } + + code_name = is_bootstrap ? + "" : + ""; + code = Py_CompileStringExFlags(text, code_name, Py_file_input, NULL, 0); if (code == NULL) goto error; free(text); @@ -106,7 +112,11 @@ main(int argc, char *argv[]) goto error; } fprintf(outfile, "%s\n", header); - fprintf(outfile, "const unsigned char _Py_M__importlib[] = {\n"); + if (is_bootstrap) + fprintf(outfile, "const unsigned char _Py_M__importlib[] = {\n"); + else + fprintf(outfile, + "const unsigned char _Py_M__importlib_external[] = {\n"); for (n = 0; n < data_size; n += 16) { size_t i, end = Py_MIN(n + 16, data_size); fprintf(outfile, " "); diff --git a/Modules/_testembed.c b/Programs/_testembed.c similarity index 97% rename from Modules/_testembed.c rename to Programs/_testembed.c index a21d2518be34..39ff0977c8fd 100644 --- a/Modules/_testembed.c +++ b/Programs/_testembed.c @@ -109,11 +109,11 @@ static void test_forced_io_encoding(void) printf("--- Use defaults ---\n"); check_stdio_details(NULL, NULL); printf("--- Set errors only ---\n"); - check_stdio_details(NULL, "surrogateescape"); + check_stdio_details(NULL, "ignore"); printf("--- Set encoding only ---\n"); check_stdio_details("latin-1", NULL); printf("--- Set encoding and errors ---\n"); - check_stdio_details("latin-1", "surrogateescape"); + check_stdio_details("latin-1", "replace"); /* Check calling after initialization fails */ Py_Initialize(); diff --git a/Modules/python.c b/Programs/python.c similarity index 97% rename from Modules/python.c rename to Programs/python.c index 9811c01d4918..2e5e4e368f0e 100644 --- a/Modules/python.c +++ b/Programs/python.c @@ -52,7 +52,7 @@ main(int argc, char **argv) setlocale(LC_ALL, ""); for (i = 0; i < argc; i++) { - argv_copy[i] = _Py_char2wchar(argv[i], NULL); + argv_copy[i] = Py_DecodeLocale(argv[i], NULL); if (!argv_copy[i]) { PyMem_RawFree(oldloc); fprintf(stderr, "Fatal Python error: " diff --git a/Python/Python-ast.c b/Python/Python-ast.c index e07a93fee8fb..a2e981648696 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -45,17 +45,21 @@ static char *FunctionDef_fields[]={ "decorator_list", "returns", }; +static PyTypeObject *AsyncFunctionDef_type; +static char *AsyncFunctionDef_fields[]={ + "name", + "args", + "body", + "decorator_list", + "returns", +}; static PyTypeObject *ClassDef_type; _Py_IDENTIFIER(bases); _Py_IDENTIFIER(keywords); -_Py_IDENTIFIER(starargs); -_Py_IDENTIFIER(kwargs); static char *ClassDef_fields[]={ "name", "bases", "keywords", - "starargs", - "kwargs", "body", "decorator_list", }; @@ -91,6 +95,13 @@ static char *For_fields[]={ "body", "orelse", }; +static PyTypeObject *AsyncFor_type; +static char *AsyncFor_fields[]={ + "target", + "iter", + "body", + "orelse", +}; static PyTypeObject *While_type; _Py_IDENTIFIER(test); static char *While_fields[]={ @@ -110,6 +121,11 @@ static char *With_fields[]={ "items", "body", }; +static PyTypeObject *AsyncWith_type; +static char *AsyncWith_fields[]={ + "items", + "body", +}; static PyTypeObject *Raise_type; _Py_IDENTIFIER(exc); _Py_IDENTIFIER(cause); @@ -232,6 +248,10 @@ static char *GeneratorExp_fields[]={ "elt", "generators", }; +static PyTypeObject *Await_type; +static char *Await_fields[]={ + "value", +}; static PyTypeObject *Yield_type; static char *Yield_fields[]={ "value", @@ -254,8 +274,6 @@ static char *Call_fields[]={ "func", "args", "keywords", - "starargs", - "kwargs", }; static PyTypeObject *Num_type; _Py_IDENTIFIER(n); @@ -267,6 +285,18 @@ _Py_IDENTIFIER(s); static char *Str_fields[]={ "s", }; +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 *Bytes_type; static char *Bytes_fields[]={ "s", @@ -349,13 +379,14 @@ static PyTypeObject *And_type; static PyTypeObject *Or_type; static PyTypeObject *operator_type; static PyObject *Add_singleton, *Sub_singleton, *Mult_singleton, -*Div_singleton, *Mod_singleton, *Pow_singleton, *LShift_singleton, -*RShift_singleton, *BitOr_singleton, *BitXor_singleton, *BitAnd_singleton, -*FloorDiv_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; @@ -750,7 +781,7 @@ static int obj2ast_int(PyObject* obj, int* out, PyArena* arena) return 1; } - i = (int)PyLong_AsLong(obj); + i = _PyLong_AsInt(obj); if (i == -1 && PyErr_Occurred()) return 1; *out = i; @@ -811,7 +842,10 @@ static int init_types(void) FunctionDef_type = make_type("FunctionDef", stmt_type, FunctionDef_fields, 5); if (!FunctionDef_type) return 0; - ClassDef_type = make_type("ClassDef", stmt_type, ClassDef_fields, 7); + AsyncFunctionDef_type = make_type("AsyncFunctionDef", stmt_type, + AsyncFunctionDef_fields, 5); + 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; @@ -823,12 +857,16 @@ static int init_types(void) if (!AugAssign_type) return 0; For_type = make_type("For", stmt_type, For_fields, 4); if (!For_type) return 0; + AsyncFor_type = make_type("AsyncFor", stmt_type, AsyncFor_fields, 4); + 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, 2); if (!With_type) return 0; + AsyncWith_type = make_type("AsyncWith", stmt_type, AsyncWith_fields, 2); + 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); @@ -877,18 +915,25 @@ static int init_types(void) 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, 5); + Call_type = make_type("Call", expr_type, Call_fields, 3); if (!Call_type) return 0; Num_type = make_type("Num", expr_type, Num_fields, 1); if (!Num_type) return 0; Str_type = make_type("Str", expr_type, Str_fields, 1); if (!Str_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; Bytes_type = make_type("Bytes", expr_type, Bytes_fields, 1); if (!Bytes_type) return 0; NameConstant_type = make_type("NameConstant", expr_type, @@ -970,6 +1015,10 @@ static int init_types(void) 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); @@ -1202,9 +1251,39 @@ FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq * } stmt_ty -ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, expr_ty - starargs, expr_ty kwargs, asdl_seq * body, asdl_seq * decorator_list, - int lineno, int col_offset, PyArena *arena) +AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq + * decorator_list, expr_ty returns, int lineno, int 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->lineno = lineno; + p->col_offset = 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, PyArena + *arena) { stmt_ty p; if (!name) { @@ -1219,8 +1298,6 @@ ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords, expr_ty p->v.ClassDef.name = name; p->v.ClassDef.bases = bases; p->v.ClassDef.keywords = keywords; - p->v.ClassDef.starargs = starargs; - p->v.ClassDef.kwargs = kwargs; p->v.ClassDef.body = body; p->v.ClassDef.decorator_list = decorator_list; p->lineno = lineno; @@ -1337,6 +1414,34 @@ For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, int return p; } +stmt_ty +AsyncFor(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, int + lineno, int 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->lineno = lineno; + p->col_offset = col_offset; + return p; +} + stmt_ty While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int col_offset, PyArena *arena) @@ -1397,6 +1502,22 @@ With(asdl_seq * items, asdl_seq * body, int lineno, int col_offset, PyArena return p; } +stmt_ty +AsyncWith(asdl_seq * items, asdl_seq * body, int lineno, int 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->lineno = lineno; + p->col_offset = col_offset; + return p; +} + stmt_ty Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, PyArena *arena) { @@ -1824,6 +1945,25 @@ GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int col_offset, return p; } +expr_ty +Await(expr_ty value, int lineno, int 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; + return p; +} + expr_ty Yield(expr_ty value, int lineno, int col_offset, PyArena *arena) { @@ -1880,8 +2020,8 @@ Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, int lineno, } expr_ty -Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty starargs, - expr_ty kwargs, int lineno, int col_offset, PyArena *arena) +Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, int lineno, int + col_offset, PyArena *arena) { expr_ty p; if (!func) { @@ -1896,8 +2036,6 @@ Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty starargs, p->v.Call.func = func; p->v.Call.args = args; p->v.Call.keywords = keywords; - p->v.Call.starargs = starargs; - p->v.Call.kwargs = kwargs; p->lineno = lineno; p->col_offset = col_offset; return p; @@ -1941,6 +2079,42 @@ Str(string s, int lineno, int col_offset, PyArena *arena) return p; } +expr_ty +FormattedValue(expr_ty value, int conversion, expr_ty format_spec, int lineno, + int 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; + return p; +} + +expr_ty +JoinedStr(asdl_seq * values, int lineno, int 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; + return p; +} + expr_ty Bytes(bytes s, int lineno, int col_offset, PyArena *arena) { @@ -2271,11 +2445,6 @@ keyword_ty keyword(identifier arg, expr_ty value, PyArena *arena) { keyword_ty p; - if (!arg) { - PyErr_SetString(PyExc_ValueError, - "field arg is required for keyword"); - return NULL; - } if (!value) { PyErr_SetString(PyExc_ValueError, "field value is required for keyword"); @@ -2419,6 +2588,36 @@ ast2obj_stmt(void* _o) 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); + break; case ClassDef_kind: result = PyType_GenericNew(ClassDef_type, NULL, NULL); if (!result) goto failed; @@ -2437,16 +2636,6 @@ ast2obj_stmt(void* _o) if (_PyObject_SetAttrId(result, &PyId_keywords, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(o->v.ClassDef.starargs); - if (!value) goto failed; - if (_PyObject_SetAttrId(result, &PyId_starargs, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(o->v.ClassDef.kwargs); - if (!value) goto failed; - if (_PyObject_SetAttrId(result, &PyId_kwargs, 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) @@ -2533,6 +2722,30 @@ ast2obj_stmt(void* _o) 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); + break; case While_kind: result = PyType_GenericNew(While_type, NULL, NULL); if (!result) goto failed; @@ -2585,6 +2798,20 @@ ast2obj_stmt(void* _o) 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); + break; case Raise_kind: result = PyType_GenericNew(Raise_type, NULL, NULL); if (!result) goto failed; @@ -2898,6 +3125,15 @@ ast2obj_expr(void* _o) 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; @@ -2959,16 +3195,6 @@ ast2obj_expr(void* _o) if (_PyObject_SetAttrId(result, &PyId_keywords, value) == -1) goto failed; Py_DECREF(value); - value = ast2obj_expr(o->v.Call.starargs); - if (!value) goto failed; - if (_PyObject_SetAttrId(result, &PyId_starargs, value) == -1) - goto failed; - Py_DECREF(value); - value = ast2obj_expr(o->v.Call.kwargs); - if (!value) goto failed; - if (_PyObject_SetAttrId(result, &PyId_kwargs, value) == -1) - goto failed; - Py_DECREF(value); break; case Num_kind: result = PyType_GenericNew(Num_type, NULL, NULL); @@ -2988,6 +3214,34 @@ ast2obj_expr(void* _o) 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 Bytes_kind: result = PyType_GenericNew(Bytes_type, NULL, NULL); if (!result) goto failed; @@ -3232,6 +3486,9 @@ PyObject* ast2obj_operator(operator_ty o) 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; @@ -3859,18 +4116,16 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena) if (*out == NULL) goto failed; return 0; } - isinstance = PyObject_IsInstance(obj, (PyObject*)ClassDef_type); + isinstance = PyObject_IsInstance(obj, (PyObject*)AsyncFunctionDef_type); if (isinstance == -1) { return 1; } if (isinstance) { identifier name; - asdl_seq* bases; - asdl_seq* keywords; - expr_ty starargs; - expr_ty kwargs; + arguments_ty args; asdl_seq* body; asdl_seq* decorator_list; + expr_ty returns; if (_PyObject_HasAttrId(obj, &PyId_name)) { int res; @@ -3880,76 +4135,152 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } else { - PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from ClassDef"); + PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from AsyncFunctionDef"); return 1; } - if (_PyObject_HasAttrId(obj, &PyId_bases)) { + if (_PyObject_HasAttrId(obj, &PyId_args)) { + int res; + tmp = _PyObject_GetAttrId(obj, &PyId_args); + if (tmp == NULL) goto failed; + res = obj2ast_arguments(tmp, &args, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from AsyncFunctionDef"); + return 1; + } + if (_PyObject_HasAttrId(obj, &PyId_body)) { int res; Py_ssize_t len; Py_ssize_t i; - tmp = _PyObject_GetAttrId(obj, &PyId_bases); + tmp = _PyObject_GetAttrId(obj, &PyId_body); if (tmp == NULL) goto failed; if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "ClassDef field \"bases\" must be a list, not a %.200s", tmp->ob_type->tp_name); + 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); - bases = _Py_asdl_seq_new(len, arena); - if (bases == NULL) goto failed; + body = _Py_asdl_seq_new(len, arena); + if (body == NULL) goto failed; for (i = 0; i < len; i++) { - expr_ty value; - res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &value, arena); + stmt_ty value; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &value, arena); if (res != 0) goto failed; - asdl_seq_SET(bases, i, value); + asdl_seq_SET(body, i, value); } Py_CLEAR(tmp); } else { - PyErr_SetString(PyExc_TypeError, "required field \"bases\" missing from ClassDef"); + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from AsyncFunctionDef"); return 1; } - if (_PyObject_HasAttrId(obj, &PyId_keywords)) { + if (_PyObject_HasAttrId(obj, &PyId_decorator_list)) { int res; Py_ssize_t len; Py_ssize_t i; - tmp = _PyObject_GetAttrId(obj, &PyId_keywords); + tmp = _PyObject_GetAttrId(obj, &PyId_decorator_list); if (tmp == NULL) goto failed; if (!PyList_Check(tmp)) { - PyErr_Format(PyExc_TypeError, "ClassDef field \"keywords\" must be a list, not a %.200s", tmp->ob_type->tp_name); + 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); - keywords = _Py_asdl_seq_new(len, arena); - if (keywords == NULL) goto failed; + decorator_list = _Py_asdl_seq_new(len, arena); + if (decorator_list == NULL) goto failed; for (i = 0; i < len; i++) { - keyword_ty value; - res = obj2ast_keyword(PyList_GET_ITEM(tmp, i), &value, arena); + expr_ty value; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &value, arena); if (res != 0) goto failed; - asdl_seq_SET(keywords, i, value); + asdl_seq_SET(decorator_list, i, value); } Py_CLEAR(tmp); } else { - PyErr_SetString(PyExc_TypeError, "required field \"keywords\" missing from ClassDef"); + PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from AsyncFunctionDef"); return 1; } - if (exists_not_none(obj, &PyId_starargs)) { + if (exists_not_none(obj, &PyId_returns)) { int res; - tmp = _PyObject_GetAttrId(obj, &PyId_starargs); + tmp = _PyObject_GetAttrId(obj, &PyId_returns); if (tmp == NULL) goto failed; - res = obj2ast_expr(tmp, &starargs, arena); + res = obj2ast_expr(tmp, &returns, arena); if (res != 0) goto failed; Py_CLEAR(tmp); } else { - starargs = NULL; + returns = NULL; } - if (exists_not_none(obj, &PyId_kwargs)) { - int res; - tmp = _PyObject_GetAttrId(obj, &PyId_kwargs); - if (tmp == NULL) goto failed; - res = obj2ast_expr(tmp, &kwargs, arena); - if (res != 0) goto failed; - Py_CLEAR(tmp); + *out = AsyncFunctionDef(name, args, body, decorator_list, returns, + lineno, 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_HasAttrId(obj, &PyId_name)) { + int res; + tmp = _PyObject_GetAttrId(obj, &PyId_name); + if (tmp == NULL) goto failed; + res = obj2ast_identifier(tmp, &name, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from ClassDef"); + return 1; + } + if (_PyObject_HasAttrId(obj, &PyId_bases)) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = _PyObject_GetAttrId(obj, &PyId_bases); + if (tmp == NULL) goto failed; + 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 value; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(bases, i, value); + } + Py_CLEAR(tmp); } else { - kwargs = NULL; + PyErr_SetString(PyExc_TypeError, "required field \"bases\" missing from ClassDef"); + return 1; + } + if (_PyObject_HasAttrId(obj, &PyId_keywords)) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = _PyObject_GetAttrId(obj, &PyId_keywords); + if (tmp == NULL) goto failed; + 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 value; + res = obj2ast_keyword(PyList_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(keywords, i, value); + } + Py_CLEAR(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "required field \"keywords\" missing from ClassDef"); + return 1; } if (_PyObject_HasAttrId(obj, &PyId_body)) { int res; @@ -3999,8 +4330,8 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena) PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from ClassDef"); return 1; } - *out = ClassDef(name, bases, keywords, starargs, kwargs, body, - decorator_list, lineno, col_offset, arena); + *out = ClassDef(name, bases, keywords, body, decorator_list, lineno, + col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -4237,6 +4568,90 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* 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; + + if (_PyObject_HasAttrId(obj, &PyId_target)) { + int res; + tmp = _PyObject_GetAttrId(obj, &PyId_target); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &target, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "required field \"target\" missing from AsyncFor"); + return 1; + } + if (_PyObject_HasAttrId(obj, &PyId_iter)) { + int res; + tmp = _PyObject_GetAttrId(obj, &PyId_iter); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &iter, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "required field \"iter\" missing from AsyncFor"); + return 1; + } + if (_PyObject_HasAttrId(obj, &PyId_body)) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = _PyObject_GetAttrId(obj, &PyId_body); + if (tmp == NULL) goto failed; + 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 value; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(body, i, value); + } + Py_CLEAR(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from AsyncFor"); + return 1; + } + if (_PyObject_HasAttrId(obj, &PyId_orelse)) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = _PyObject_GetAttrId(obj, &PyId_orelse); + if (tmp == NULL) goto failed; + 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 value; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(orelse, i, value); + } + Py_CLEAR(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from AsyncFor"); + return 1; + } + *out = AsyncFor(target, iter, body, orelse, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } isinstance = PyObject_IsInstance(obj, (PyObject*)While_type); if (isinstance == -1) { return 1; @@ -4441,6 +4856,66 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* 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; + + if (_PyObject_HasAttrId(obj, &PyId_items)) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = _PyObject_GetAttrId(obj, &PyId_items); + if (tmp == NULL) goto failed; + 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 value; + res = obj2ast_withitem(PyList_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(items, i, value); + } + Py_CLEAR(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "required field \"items\" missing from AsyncWith"); + return 1; + } + if (_PyObject_HasAttrId(obj, &PyId_body)) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = _PyObject_GetAttrId(obj, &PyId_body); + if (tmp == NULL) goto failed; + 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 value; + res = obj2ast_stmt(PyList_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(body, i, value); + } + Py_CLEAR(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from AsyncWith"); + return 1; + } + *out = AsyncWith(items, body, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } isinstance = PyObject_IsInstance(obj, (PyObject*)Raise_type); if (isinstance == -1) { return 1; @@ -5375,6 +5850,28 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* 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_HasAttrId(obj, &PyId_value)) { + int res; + tmp = _PyObject_GetAttrId(obj, &PyId_value); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from Await"); + return 1; + } + *out = Await(value, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } isinstance = PyObject_IsInstance(obj, (PyObject*)Yield_type); if (isinstance == -1) { return 1; @@ -5498,8 +5995,6 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena) expr_ty func; asdl_seq* args; asdl_seq* keywords; - expr_ty starargs; - expr_ty kwargs; if (_PyObject_HasAttrId(obj, &PyId_func)) { int res; @@ -5560,28 +6055,7 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* arena) PyErr_SetString(PyExc_TypeError, "required field \"keywords\" missing from Call"); return 1; } - if (exists_not_none(obj, &PyId_starargs)) { - int res; - tmp = _PyObject_GetAttrId(obj, &PyId_starargs); - if (tmp == NULL) goto failed; - res = obj2ast_expr(tmp, &starargs, arena); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } else { - starargs = NULL; - } - if (exists_not_none(obj, &PyId_kwargs)) { - int res; - tmp = _PyObject_GetAttrId(obj, &PyId_kwargs); - if (tmp == NULL) goto failed; - res = obj2ast_expr(tmp, &kwargs, arena); - if (res != 0) goto failed; - Py_CLEAR(tmp); - } else { - kwargs = NULL; - } - *out = Call(func, args, keywords, starargs, kwargs, lineno, col_offset, - arena); + *out = Call(func, args, keywords, lineno, col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -5629,6 +6103,86 @@ obj2ast_expr(PyObject* obj, expr_ty* out, PyArena* 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_HasAttrId(obj, &PyId_value)) { + int res; + tmp = _PyObject_GetAttrId(obj, &PyId_value); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &value, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from FormattedValue"); + return 1; + } + if (exists_not_none(obj, &PyId_conversion)) { + int res; + tmp = _PyObject_GetAttrId(obj, &PyId_conversion); + if (tmp == NULL) goto failed; + res = obj2ast_int(tmp, &conversion, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } else { + conversion = 0; + } + if (exists_not_none(obj, &PyId_format_spec)) { + int res; + tmp = _PyObject_GetAttrId(obj, &PyId_format_spec); + if (tmp == NULL) goto failed; + res = obj2ast_expr(tmp, &format_spec, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } else { + format_spec = NULL; + } + *out = FormattedValue(value, conversion, format_spec, lineno, + 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_HasAttrId(obj, &PyId_values)) { + int res; + Py_ssize_t len; + Py_ssize_t i; + tmp = _PyObject_GetAttrId(obj, &PyId_values); + if (tmp == NULL) goto failed; + 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 value; + res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &value, arena); + if (res != 0) goto failed; + asdl_seq_SET(values, i, value); + } + Py_CLEAR(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "required field \"values\" missing from JoinedStr"); + return 1; + } + *out = JoinedStr(values, lineno, col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } isinstance = PyObject_IsInstance(obj, (PyObject*)Bytes_type); if (isinstance == -1) { return 1; @@ -6175,6 +6729,14 @@ obj2ast_operator(PyObject* obj, operator_ty* out, PyArena* arena) *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; @@ -6721,7 +7283,7 @@ obj2ast_keyword(PyObject* obj, keyword_ty* out, PyArena* arena) identifier arg; expr_ty value; - if (_PyObject_HasAttrId(obj, &PyId_arg)) { + if (exists_not_none(obj, &PyId_arg)) { int res; tmp = _PyObject_GetAttrId(obj, &PyId_arg); if (tmp == NULL) goto failed; @@ -6729,8 +7291,7 @@ obj2ast_keyword(PyObject* obj, keyword_ty* out, PyArena* arena) if (res != 0) goto failed; Py_CLEAR(tmp); } else { - PyErr_SetString(PyExc_TypeError, "required field \"arg\" missing from keyword"); - return 1; + arg = NULL; } if (_PyObject_HasAttrId(obj, &PyId_value)) { int res; @@ -6847,6 +7408,8 @@ PyInit__ast(void) 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 @@ -6858,10 +7421,14 @@ PyInit__ast(void) if (PyDict_SetItemString(d, "AugAssign", (PyObject*)AugAssign_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; @@ -6902,6 +7469,8 @@ PyInit__ast(void) 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) @@ -6911,6 +7480,10 @@ PyInit__ast(void) if (PyDict_SetItemString(d, "Call", (PyObject*)Call_type) < 0) return NULL; if (PyDict_SetItemString(d, "Num", (PyObject*)Num_type) < 0) return NULL; if (PyDict_SetItemString(d, "Str", (PyObject*)Str_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, "Bytes", (PyObject*)Bytes_type) < 0) return NULL; if (PyDict_SetItemString(d, "NameConstant", (PyObject*)NameConstant_type) < @@ -6956,6 +7529,8 @@ PyInit__ast(void) 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; @@ -7023,10 +7598,14 @@ PyObject* PyAST_mod2obj(mod_ty t) mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode) { mod_ty res; - PyObject *req_type[] = {(PyObject*)Module_type, (PyObject*)Expression_type, - (PyObject*)Interactive_type}; + PyObject *req_type[3]; char *req_name[] = {"Module", "Expression", "Interactive"}; int isinstance; + + 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()) diff --git a/Python/README b/Python/README new file mode 100644 index 000000000000..153b628bd5b4 --- /dev/null +++ b/Python/README @@ -0,0 +1 @@ +Miscellaneous source files for the main Python shared library diff --git a/Python/_warnings.c b/Python/_warnings.c index 6013d7d7d48c..9ca83145c94c 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -12,6 +12,7 @@ MODULE_NAME " provides basic warning filtering support.\n" static PyObject *_filters; /* List */ static PyObject *_once_registry; /* Dict */ static PyObject *_default_action; /* String */ +static long _filters_version; _Py_IDENTIFIER(argv); _Py_IDENTIFIER(stderr); @@ -100,7 +101,7 @@ get_default_action(void) } -/* The item is a borrowed reference. */ +/* The item is a new reference. */ static PyObject* get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, PyObject *module, PyObject **item) @@ -131,14 +132,15 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, Py_ssize_t ln; int is_subclass, good_msg, good_mod; - tmp_item = *item = PyList_GET_ITEM(_filters, i); - if (PyTuple_Size(tmp_item) != 5) { + 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); @@ -146,28 +148,43 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, ln_obj = PyTuple_GET_ITEM(tmp_item, 4); good_msg = check_matched(msg, text); - if (good_msg == -1) + if (good_msg == -1) { + Py_DECREF(tmp_item); return NULL; + } good_mod = check_matched(mod, module); - if (good_mod == -1) + if (good_mod == -1) { + Py_DECREF(tmp_item); return NULL; + } is_subclass = PyObject_IsSubclass(category, cat); - if (is_subclass == -1) + if (is_subclass == -1) { + Py_DECREF(tmp_item); return NULL; + } ln = PyLong_AsSsize_t(ln_obj); - if (ln == -1 && PyErr_Occurred()) + if (ln == -1 && PyErr_Occurred()) { + Py_DECREF(tmp_item); return NULL; + } - if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) + if (good_msg && is_subclass && good_mod && (ln == 0 || lineno == ln)) { + *item = tmp_item; return action; + } + + Py_DECREF(tmp_item); } action = get_default_action(); - if (action != NULL) + if (action != NULL) { + Py_INCREF(Py_None); + *item = Py_None; return action; + } PyErr_SetString(PyExc_ValueError, MODULE_NAME ".defaultaction not found"); @@ -178,16 +195,33 @@ get_filter(PyObject *category, PyObject *text, Py_ssize_t lineno, static int already_warned(PyObject *registry, PyObject *key, int should_set) { - PyObject *already_warned; + PyObject *version_obj, *already_warned; + _Py_IDENTIFIER(version); if (key == NULL) return -1; - already_warned = PyDict_GetItem(registry, key); - if (already_warned != NULL) { - int rc = PyObject_IsTrue(already_warned); - if (rc != 0) - return rc; + version_obj = _PyDict_GetItemId(registry, &PyId_version); + if (version_obj == NULL + || !PyLong_CheckExact(version_obj) + || PyLong_AsLong(version_obj) != _filters_version) { + PyDict_Clear(registry); + version_obj = PyLong_FromLong(_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_GetItem(registry, key); + if (already_warned != NULL) { + int rc = PyObject_IsTrue(already_warned); + if (rc != 0) + return rc; + } } /* This warning wasn't found in the registry, set it. */ @@ -331,7 +365,7 @@ warn_explicit(PyObject *category, PyObject *message, PyObject *module, PyObject *registry, PyObject *sourceline) { PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL; - PyObject *item = Py_None; + PyObject *item = NULL; PyObject *action; int rc; @@ -470,6 +504,7 @@ warn_explicit(PyObject *category, PyObject *message, Py_INCREF(result); cleanup: + Py_XDECREF(item); Py_XDECREF(key); Py_XDECREF(text); Py_XDECREF(lineno_obj); @@ -478,6 +513,64 @@ warn_explicit(PyObject *category, PyObject *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 @@ -488,8 +581,18 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, /* Setup globals and lineno. */ PyFrameObject *f = PyThreadState_GET()->frame; - while (--stack_level > 0 && f != NULL) - f = f->f_back; + // 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 = PyThreadState_Get()->interp->sysdict; @@ -545,13 +648,12 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, data = PyUnicode_DATA(*filename); #define ascii_lower(c) ((c <= 127) ? Py_TOLOWER(c) : 0) - /* if filename.lower().endswith((".pyc", ".pyo")): */ + /* if filename.lower().endswith(".pyc"): */ if (len >= 4 && PyUnicode_READ(kind, data, len-4) == '.' && ascii_lower(PyUnicode_READ(kind, data, len-3)) == 'p' && ascii_lower(PyUnicode_READ(kind, data, len-2)) == 'y' && - (ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'c' || - ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'o')) + ascii_lower(PyUnicode_READ(kind, data, len-1)) == 'c') { *filename = PyUnicode_Substring(*filename, 0, PyUnicode_GET_LENGTH(*filename)-1); @@ -619,16 +721,17 @@ get_category(PyObject *message, PyObject *category) if (rc == 1) category = (PyObject*)message->ob_type; - else if (category == NULL) + else if (category == NULL || category == Py_None) category = PyExc_UserWarning; /* Validate category. */ rc = PyObject_IsSubclass(category, PyExc_Warning); - if (rc == -1) - return NULL; - if (rc == 0) { - PyErr_SetString(PyExc_ValueError, - "category is not a subclass of 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; } @@ -750,6 +853,13 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds) registry, NULL); } +static PyObject * +warnings_filters_mutated(PyObject *self, PyObject *args) +{ + _filters_version++; + Py_RETURN_NONE; +} + /* Function to issue a warning message; may raise an exception. */ @@ -917,6 +1027,8 @@ static PyMethodDef warnings_functions[] = { warn_doc}, {"warn_explicit", (PyCFunction)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 */ @@ -1069,5 +1181,7 @@ _PyWarnings_Init(void) Py_INCREF(_default_action); if (PyModule_AddObject(m, "_defaultaction", _default_action) < 0) return NULL; + + _filters_version = 0; return m; } diff --git a/Python/asdl.c b/Python/asdl.c index 74fa9410e493..df387b2119b6 100644 --- a/Python/asdl.c +++ b/Python/asdl.c @@ -5,21 +5,21 @@ asdl_seq * _Py_asdl_seq_new(Py_ssize_t size, PyArena *arena) { asdl_seq *seq = NULL; - size_t n = (size ? (sizeof(void *) * (size - 1)) : 0); + size_t n; /* check size is sane */ - if (size < 0 || size == INT_MIN || - (size && ((size - 1) > (PY_SIZE_MAX / sizeof(void *))))) { + if (size < 0 || + (size && (((size_t)size - 1) > (PY_SIZE_MAX / sizeof(void *))))) { PyErr_NoMemory(); return NULL; } + n = (size ? (sizeof(void *) * (size - 1)) : 0); /* check if size can be added safely */ if (n > PY_SIZE_MAX - sizeof(asdl_seq)) { PyErr_NoMemory(); return NULL; } - n += sizeof(asdl_seq); seq = (asdl_seq *)PyArena_Malloc(arena, n); @@ -36,21 +36,21 @@ asdl_int_seq * _Py_asdl_int_seq_new(Py_ssize_t size, PyArena *arena) { asdl_int_seq *seq = NULL; - size_t n = (size ? (sizeof(void *) * (size - 1)) : 0); + size_t n; /* check size is sane */ - if (size < 0 || size == INT_MIN || - (size && ((size - 1) > (PY_SIZE_MAX / sizeof(void *))))) { + if (size < 0 || + (size && (((size_t)size - 1) > (PY_SIZE_MAX / sizeof(void *))))) { PyErr_NoMemory(); return NULL; } + n = (size ? (sizeof(void *) * (size - 1)) : 0); /* check if size can be added safely */ if (n > PY_SIZE_MAX - sizeof(asdl_seq)) { PyErr_NoMemory(); return NULL; } - n += sizeof(asdl_seq); seq = (asdl_int_seq *)PyArena_Malloc(arena, n); diff --git a/Python/ast.c b/Python/ast.c index 3bd24fdb1410..5a7a745c61b3 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -115,7 +115,7 @@ validate_arguments(arguments_ty args) } if (!validate_args(args->kwonlyargs)) return 0; - if (args->kwarg && args->kwarg->annotation + if (args->kwarg && args->kwarg->annotation && !validate_expr(args->kwarg->annotation, Load)) { return 0; } @@ -164,6 +164,8 @@ validate_expr(expr_ty exp, expr_context_ty 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", @@ -197,8 +199,10 @@ validate_expr(expr_ty exp, expr_context_ty ctx) "Dict doesn't have the same number of keys as values"); return 0; } - return validate_exprs(exp->v.Dict.keys, Load, 0) && - validate_exprs(exp->v.Dict.values, Load, 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) \ @@ -217,6 +221,8 @@ validate_expr(expr_ty exp, expr_context_ty ctx) 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"); @@ -233,9 +239,7 @@ validate_expr(expr_ty exp, expr_context_ty ctx) 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) && - (!exp->v.Call.starargs || validate_expr(exp->v.Call.starargs, Load)) && - (!exp->v.Call.kwargs || validate_expr(exp->v.Call.kwargs, Load)); + validate_keywords(exp->v.Call.keywords); case Num_kind: { PyObject *n = exp->v.Num.n; if (!PyLong_CheckExact(n) && !PyFloat_CheckExact(n) && @@ -253,6 +257,14 @@ validate_expr(expr_ty exp, expr_context_ty ctx) } 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 Bytes_kind: { PyObject *b = exp->v.Bytes.s; if (!PyBytes_CheckExact(b)) { @@ -320,9 +332,7 @@ validate_stmt(stmt_ty stmt) 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) && - (!stmt->v.ClassDef.starargs || validate_expr(stmt->v.ClassDef.starargs, Load)) && - (!stmt->v.ClassDef.kwargs || validate_expr(stmt->v.ClassDef.kwargs, Load)); + 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: @@ -338,6 +348,11 @@ validate_stmt(stmt_ty stmt) 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") && @@ -356,6 +371,16 @@ validate_stmt(stmt_ty stmt) 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) && @@ -407,6 +432,12 @@ validate_stmt(stmt_ty stmt) 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: @@ -451,7 +482,7 @@ validate_exprs(asdl_seq *exprs, expr_context_ty ctx, int null_ok) "None disallowed in expression list"); return 0; } - + } return 1; } @@ -490,7 +521,7 @@ PyAST_Validate(mod_ty mod) /* Data structure used internally */ struct compiling { char *c_encoding; /* source encoding */ - PyArena *c_arena; /* arena for allocating memeory */ + PyArena *c_arena; /* Arena for allocating memory. */ PyObject *c_filename; /* filename */ PyObject *c_normalize; /* Normalization function from unicodedata. */ PyObject *c_normalize_args; /* Normalization argument tuple. */ @@ -505,13 +536,14 @@ static asdl_seq *ast_for_exprlist(struct compiling *, const node *, 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 *, int); +static stmt_ty ast_for_for_stmt(struct compiling *, const node *, int); + /* Note different signature for ast_for_call */ static expr_ty ast_for_call(struct compiling *, const node *, expr_ty); static PyObject *parsenumber(struct compiling *, const char *); -static PyObject *parsestr(struct compiling *, const node *n, int *bytesmode); -static PyObject *parsestrplus(struct compiling *, const node *n, - int *bytesmode); +static expr_ty parsestrplus(struct compiling *, const node *n); #define COMP_GENEXP 0 #define COMP_LISTCOMP 1 @@ -825,6 +857,8 @@ get_operator(const node *n) return Sub; case STAR: return Mult; + case AT: + return MatMult; case SLASH: return Div; case DOUBLESLASH: @@ -844,7 +878,8 @@ static const char* FORBIDDEN[] = { }; static int -forbidden_name(struct compiling *c, identifier name, const node *n, int full_checks) +forbidden_name(struct compiling *c, identifier name, const node *n, + int full_checks) { assert(PyUnicode_Check(name)); if (PyUnicode_CompareWithASCIIString(name, "__debug__") == 0) { @@ -940,6 +975,9 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n) case YieldFrom_kind: expr_name = "yield expression"; break; + case Await_kind: + expr_name = "await expression"; + break; case ListComp_kind: expr_name = "list comprehension"; break; @@ -954,6 +992,8 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n) case Num_kind: case Str_kind: case Bytes_kind: + case JoinedStr_kind: + case FormattedValue_kind: expr_name = "literal"; break; case NameConstant_kind: @@ -1030,6 +1070,8 @@ ast_for_augassign(struct compiling *c, const node *n) return Pow; else return Mult; + case '@': + return MatMult; default: PyErr_Format(PyExc_SystemError, "invalid augassign: %s", STR(n)); return (operator_ty)0; @@ -1123,7 +1165,7 @@ ast_for_arg(struct compiling *c, const node *n) identifier name; expr_ty annotation = NULL; node *ch; - arg_ty tmp; + arg_ty ret; assert(TYPE(n) == tfpdef || TYPE(n) == vfpdef); ch = CHILD(n, 0); @@ -1139,13 +1181,12 @@ ast_for_arg(struct compiling *c, const node *n) return NULL; } - tmp = arg(name, annotation, c->c_arena); - if (!tmp) + ret = arg(name, annotation, c->c_arena); + if (!ret) return NULL; - - tmp->lineno = LINENO(n); - tmp->col_offset = n->n_col_offset; - return tmp; + ret->lineno = LINENO(n); + ret->col_offset = n->n_col_offset; + return ret; } /* returns -1 if failed to handle keyword only arguments @@ -1203,6 +1244,8 @@ handle_keywordonly_args(struct compiling *c, const node *n, int start, arg = arg(argname, annotation, c->c_arena); if (!arg) goto error; + arg->lineno = LINENO(ch); + arg->col_offset = ch->n_col_offset; asdl_seq_SET(kwonlyargs, j++, arg); i += 2; /* the name and the comma */ break; @@ -1227,16 +1270,20 @@ ast_for_arguments(struct compiling *c, const node *n) and varargslist (lambda definition). parameters: '(' [typedargslist] ')' - typedargslist: ((tfpdef ['=' test] ',')* - ('*' [tfpdef] (',' tfpdef ['=' test])* [',' '**' tfpdef] - | '**' tfpdef) - | tfpdef ['=' test] (',' tfpdef ['=' test])* [',']) + typedargslist: (tfpdef ['=' test] (',' tfpdef ['=' test])* [',' [ + '*' [tfpdef] (',' tfpdef ['=' test])* [',' ['**' tfpdef [',']]] + | '**' tfpdef [',']]] + | '*' [tfpdef] (',' tfpdef ['=' test])* [',' ['**' tfpdef [',']]] + | '**' tfpdef [',']) tfpdef: NAME [':' test] - varargslist: ((vfpdef ['=' test] ',')* - ('*' [vfpdef] (',' vfpdef ['=' test])* [',' '**' vfpdef] - | '**' vfpdef) - | vfpdef ['=' test] (',' vfpdef ['=' test])* [',']) + varargslist: (vfpdef ['=' test] (',' vfpdef ['=' test])* [',' [ + '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]] + | '**' vfpdef [',']]] + | '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]] + | '**' vfpdef [','] + ) vfpdef: NAME + */ int i, j, k, nposargs = 0, nkwonlyargs = 0; int nposdefaults = 0, found_default = 0; @@ -1338,7 +1385,8 @@ ast_for_arguments(struct compiling *c, const node *n) i += 2; /* the name and the comma */ break; case STAR: - if (i+1 >= NCH(n)) { + if (i+1 >= NCH(n) || + (i+2 == NCH(n) && TYPE(CHILD(n, i+1)) == COMMA)) { ast_error(c, CHILD(n, i), "named arguments must follow bare *"); return NULL; @@ -1438,7 +1486,7 @@ ast_for_decorator(struct compiling *c, const node *n) name_expr = NULL; } else if (NCH(n) == 5) { /* Call with no arguments */ - d = Call(name_expr, NULL, NULL, NULL, NULL, LINENO(n), + d = Call(name_expr, NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena); if (!d) return NULL; @@ -1476,7 +1524,8 @@ ast_for_decorators(struct compiling *c, const node *n) } static stmt_ty -ast_for_funcdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) +ast_for_funcdef_impl(struct compiling *c, const node *n, + asdl_seq *decorator_seq, int is_async) { /* funcdef: 'def' NAME parameters ['->' test] ':' suite */ identifier name; @@ -1505,14 +1554,68 @@ ast_for_funcdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) if (!body) return NULL; - return FunctionDef(name, args, body, decorator_seq, returns, LINENO(n), - n->n_col_offset, c->c_arena); + if (is_async) + return AsyncFunctionDef(name, args, body, decorator_seq, returns, + LINENO(n), + n->n_col_offset, c->c_arena); + else + return FunctionDef(name, args, body, decorator_seq, returns, + LINENO(n), + n->n_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, CHILD(n, 1), decorator_seq, + 1 /* 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, + 0 /* 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, CHILD(n, 1), NULL, + 1 /* is_async */); + case with_stmt: + return ast_for_with_stmt(c, CHILD(n, 1), + 1 /* is_async */); + + case for_stmt: + return ast_for_for_stmt(c, CHILD(n, 1), + 1 /* 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) */ + /* decorated: decorators (classdef | funcdef | async_funcdef) */ stmt_ty thing = NULL; asdl_seq *decorator_seq = NULL; @@ -1523,12 +1626,15 @@ ast_for_decorated(struct compiling *c, const node *n) 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); } /* we count the decorators in when talking about the class' or * function's line number */ @@ -1728,16 +1834,22 @@ ast_for_comprehension(struct compiling *c, const node *n) static expr_ty ast_for_itercomp(struct compiling *c, const node *n, int type) { - /* testlist_comp: test ( comp_for | (',' test)* [','] ) - argument: [test '='] test [comp_for] # Really [keyword '='] test */ + /* testlist_comp: (test|star_expr) + * ( comp_for | (',' (test|star_expr))* [','] ) */ expr_ty elt; asdl_seq *comps; + node *ch; assert(NCH(n) > 1); - elt = ast_for_expr(c, CHILD(n, 0)); + 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) @@ -1754,29 +1866,98 @@ ast_for_itercomp(struct compiling *c, const node *n, int type) 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; - assert(NCH(n) > 3); - REQ(CHILD(n, 1), COLON); - - key = ast_for_expr(c, CHILD(n, 0)); - if (!key) - return NULL; - value = ast_for_expr(c, CHILD(n, 2)); - if (!value) + 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, 3)); + comps = ast_for_comprehension(c, CHILD(n, i)); if (!comps) return NULL; return DictComp(key, value, comps, LINENO(n), n->n_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, c->c_arena); +} + static expr_ty ast_for_genexp(struct compiling *c, const node *n) { @@ -1798,6 +1979,27 @@ ast_for_setcomp(struct compiling *c, const node *n) 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, c->c_arena); +} static expr_ty ast_for_atom(struct compiling *c, const node *n) @@ -1807,7 +2009,6 @@ ast_for_atom(struct compiling *c, const node *n) | '...' | 'None' | 'True' | 'False' */ node *ch = CHILD(n, 0); - int bytesmode = 0; switch (TYPE(ch)) { case NAME: { @@ -1829,7 +2030,7 @@ ast_for_atom(struct compiling *c, const node *n) return Name(name, Load, LINENO(n), n->n_col_offset, c->c_arena); } case STRING: { - PyObject *str = parsestrplus(c, n, &bytesmode); + expr_ty str = parsestrplus(c, n); if (!str) { const char *errtype = NULL; if (PyErr_ExceptionMatches(PyExc_UnicodeError)) @@ -1846,6 +2047,7 @@ ast_for_atom(struct compiling *c, const node *n) PyOS_snprintf(buf, sizeof(buf), "(%s) %s", errtype, s); Py_DECREF(errstr); } else { + PyErr_Clear(); PyOS_snprintf(buf, sizeof(buf), "(%s) unknown error", errtype); } ast_error(c, n, buf); @@ -1855,14 +2057,7 @@ ast_for_atom(struct compiling *c, const node *n) } return NULL; } - if (PyArena_AddPyObject(c->c_arena, str) < 0) { - Py_DECREF(str); - return NULL; - } - if (bytesmode) - return Bytes(str, LINENO(n), n->n_col_offset, c->c_arena); - else - return Str(str, LINENO(n), n->n_col_offset, c->c_arena); + return str; } case NUMBER: { PyObject *pynum = parsenumber(c, STR(ch)); @@ -1908,62 +2103,48 @@ ast_for_atom(struct compiling *c, const node *n) else return ast_for_listcomp(c, ch); case LBRACE: { - /* dictorsetmaker: test ':' test (',' test ':' test)* [','] | - * test (gen_for | (',' test)* [',']) */ - int i, size; - asdl_seq *keys, *values; - + /* 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 */ + /* It's an empty dict. */ return Dict(NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena); - } else if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) { - /* it's a simple set */ - asdl_seq *elts; - size = (NCH(ch) + 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(ch); i += 2) { - expr_ty expression; - expression = ast_for_expr(c, CHILD(ch, i)); - if (!expression) - return NULL; - asdl_seq_SET(elts, i / 2, expression); - } - return Set(elts, LINENO(n), n->n_col_offset, c->c_arena); - } else if (TYPE(CHILD(ch, 1)) == comp_for) { - /* it's a set comprehension */ - return ast_for_setcomp(c, ch); - } else if (NCH(ch) > 3 && TYPE(CHILD(ch, 3)) == comp_for) { - return ast_for_dictcomp(c, ch); - } else { - /* it's a dict */ - size = (NCH(ch) + 1) / 4; /* +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; - - for (i = 0; i < NCH(ch); i += 4) { - expr_ty expression; - - expression = ast_for_expr(c, CHILD(ch, i)); - if (!expression) - return NULL; - - asdl_seq_SET(keys, i / 4, expression); - - expression = ast_for_expr(c, CHILD(ch, i + 2)); - if (!expression) + } + 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; - - asdl_seq_SET(values, i / 4, expression); + } + res = ast_for_dictcomp(c, ch); + } + else { + /* It's a dictionary display. */ + res = ast_for_dictdisplay(c, ch); + } + if (res) { + res->lineno = LINENO(n); + res->col_offset = n->n_col_offset; } - return Dict(keys, values, LINENO(n), n->n_col_offset, c->c_arena); + return res; } } default: @@ -2099,24 +2280,17 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) REQ(n, trailer); if (TYPE(CHILD(n, 0)) == LPAR) { if (NCH(n) == 2) - return Call(left_expr, NULL, NULL, NULL, NULL, LINENO(n), + return Call(left_expr, NULL, NULL, LINENO(n), n->n_col_offset, c->c_arena); - else { - expr_ty tmp = ast_for_call(c, CHILD(n, 1), left_expr); - if (!tmp) - return NULL; - - tmp->lineno = LINENO(n); - tmp->col_offset = n->n_col_offset; - return tmp; - } + else + return ast_for_call(c, CHILD(n, 1), left_expr); } - else if (TYPE(CHILD(n, 0)) == DOT ) { + 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(CHILD(n, 1)), CHILD(n, 1)->n_col_offset, c->c_arena); + LINENO(n), n->n_col_offset, c->c_arena); } else { REQ(CHILD(n, 0), LSQB); @@ -2198,35 +2372,66 @@ ast_for_factor(struct compiling *c, const node *n) } static expr_ty -ast_for_power(struct compiling *c, const node *n) +ast_for_atom_expr(struct compiling *c, const node *n) { - /* power: atom trailer* ('**' factor)* - */ - int i; + int i, nch, start = 0; expr_ty e, tmp; - REQ(n, power); - e = ast_for_atom(c, CHILD(n, 0)); + + REQ(n, atom_expr); + nch = NCH(n); + + if (TYPE(CHILD(n, 0)) == AWAIT) { + start = 1; + assert(nch > 1); + } + + e = ast_for_atom(c, CHILD(n, start)); if (!e) return NULL; - if (NCH(n) == 1) + if (nch == 1) return e; - for (i = 1; i < NCH(n); i++) { + if (start && nch == 2) { + return Await(e, LINENO(n), n->n_col_offset, c->c_arena); + } + + for (i = start + 1; i < nch; i++) { node *ch = CHILD(n, i); if (TYPE(ch) != trailer) break; tmp = ast_for_trailer(c, ch, e); if (!tmp) return NULL; + tmp->lineno = e->lineno; + tmp->col_offset = e->col_offset; e = tmp; } + + if (start) { + /* there was an AWAIT */ + return Await(e, LINENO(n), n->n_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; - tmp = BinOp(e, Pow, f, LINENO(n), n->n_col_offset, c->c_arena); - if (!tmp) - return NULL; - e = tmp; + e = BinOp(e, Pow, f, LINENO(n), n->n_col_offset, c->c_arena); } return e; } @@ -2264,9 +2469,11 @@ ast_for_expr(struct compiling *c, const node *n) and_expr: shift_expr ('&' shift_expr)* shift_expr: arith_expr (('<<'|'>>') arith_expr)* arith_expr: term (('+'|'-') term)* - term: factor (('*'|'/'|'%'|'//') factor)* + term: factor (('*'|'@'|'/'|'%'|'//') factor)* factor: ('+'|'-'|'~') factor | power - power: atom trailer* ('**' factor)* + power: atom_expr ['**' factor] + atom_expr: [AWAIT] atom trailer* + yield_expr: 'yield' [yield_arg] */ asdl_seq *seq; @@ -2416,15 +2623,14 @@ static expr_ty ast_for_call(struct compiling *c, const node *n, expr_ty func) { /* - arglist: (argument ',')* (argument [',']| '*' test [',' '**' test] - | '**' test) - argument: [test '='] (test) [comp_for] # Really [keyword '='] test + arglist: argument (',' argument)* [','] + argument: ( test [comp_for] | '*' test | test '=' test | '**' test ) */ int i, nargs, nkeywords, ngens; + int ndoublestars; asdl_seq *args; asdl_seq *keywords; - expr_ty vararg = NULL, kwarg = NULL; REQ(n, arglist); @@ -2438,7 +2644,10 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func) nargs++; else if (TYPE(CHILD(ch, 1)) == comp_for) ngens++; + else if (TYPE(CHILD(ch, 0)) == STAR) + nargs++; else + /* TYPE(CHILD(ch, 0)) == DOUBLESTAR or keyword argument */ nkeywords++; } } @@ -2459,41 +2668,81 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func) keywords = _Py_asdl_seq_new(nkeywords, c->c_arena); if (!keywords) return NULL; - nargs = 0; - nkeywords = 0; + + 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) { - ast_error(c, CHILD(ch, 0), - "non-keyword arg after keyword arg"); + if (ndoublestars) { + ast_error(c, chch, + "positional argument follows " + "keyword argument unpacking"); + } + else { + ast_error(c, chch, + "positional argument follows " + "keyword argument"); + } return NULL; } - if (vararg) { - ast_error(c, CHILD(ch, 0), - "only named arguments may follow *expression"); + 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, 0)); + e = ast_for_expr(c, CHILD(ch, 1)); if (!e) return NULL; - asdl_seq_SET(args, nargs++, e); + starred = Starred(e, Load, LINENO(chch), + chch->n_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 = ast_for_genexp(c, ch); if (!e) return NULL; asdl_seq_SET(args, nargs++, e); } else { + /* a keyword argument */ keyword_ty kw; identifier key, tmp; int k; - /* CHILD(ch, 0) is test, but must be an identifier? */ - e = ast_for_expr(c, CHILD(ch, 0)); + /* chch is test, but must be an identifier? */ + e = ast_for_expr(c, chch); if (!e) return NULL; /* f(lambda x: x[0] = 3) ends up getting parsed with @@ -2502,19 +2751,24 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func) * then is very confusing. */ if (e->kind == Lambda_kind) { - ast_error(c, CHILD(ch, 0), "lambda cannot contain assignment"); + ast_error(c, chch, + "lambda cannot contain assignment"); return NULL; - } else if (e->kind != Name_kind) { - ast_error(c, CHILD(ch, 0), "keyword can't be an expression"); + } + else if (e->kind != Name_kind) { + ast_error(c, chch, + "keyword can't be an expression"); return NULL; - } else if (forbidden_name(c, e->v.Name.id, ch, 1)) { + } + else if (forbidden_name(c, e->v.Name.id, ch, 1)) { return NULL; } key = e->v.Name.id; for (k = 0; k < nkeywords; k++) { tmp = ((keyword_ty)asdl_seq_GET(keywords, k))->arg; - if (!PyUnicode_Compare(tmp, key)) { - ast_error(c, CHILD(ch, 0), "keyword argument repeated"); + if (tmp && !PyUnicode_Compare(tmp, key)) { + ast_error(c, chch, + "keyword argument repeated"); return NULL; } } @@ -2527,21 +2781,9 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func) asdl_seq_SET(keywords, nkeywords++, kw); } } - else if (TYPE(ch) == STAR) { - vararg = ast_for_expr(c, CHILD(n, i+1)); - if (!vararg) - return NULL; - i++; - } - else if (TYPE(ch) == DOUBLESTAR) { - kwarg = ast_for_expr(c, CHILD(n, i+1)); - if (!kwarg) - return NULL; - i++; - } } - return Call(func, args, keywords, vararg, kwarg, func->lineno, func->col_offset, c->c_arena); + return Call(func, args, keywords, func->lineno, func->col_offset, c->c_arena); } static expr_ty @@ -2575,7 +2817,7 @@ ast_for_expr_stmt(struct compiling *c, const node *n) /* expr_stmt: testlist_star_expr (augassign (yield_expr|testlist) | ('=' (yield_expr|testlist))*) testlist_star_expr: (test|star_expr) (',' test|star_expr)* [','] - augassign: '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' + augassign: '+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=' | '**=' | '//=' test: ... here starts the operator precendence dance */ @@ -3295,7 +3537,7 @@ ast_for_while_stmt(struct compiling *c, const node *n) } static stmt_ty -ast_for_for_stmt(struct compiling *c, const node *n) +ast_for_for_stmt(struct compiling *c, const node *n, int is_async) { asdl_seq *_target, *seq = NULL, *suite_seq; expr_ty expression; @@ -3329,8 +3571,14 @@ ast_for_for_stmt(struct compiling *c, const node *n) if (!suite_seq) return NULL; - return For(target, expression, suite_seq, seq, LINENO(n), n->n_col_offset, - c->c_arena); + if (is_async) + return AsyncFor(target, expression, suite_seq, seq, + LINENO(n), n->n_col_offset, + c->c_arena); + else + return For(target, expression, suite_seq, seq, + LINENO(n), n->n_col_offset, + c->c_arena); } static excepthandler_ty @@ -3477,7 +3725,7 @@ ast_for_with_item(struct compiling *c, const node *n) /* with_stmt: 'with' with_item (',' with_item)* ':' suite */ static stmt_ty -ast_for_with_stmt(struct compiling *c, const node *n) +ast_for_with_stmt(struct compiling *c, const node *n, int is_async) { int i, n_items; asdl_seq *items, *body; @@ -3499,7 +3747,10 @@ ast_for_with_stmt(struct compiling *c, const node *n) if (!body) return NULL; - return With(items, body, LINENO(n), n->n_col_offset, c->c_arena); + if (is_async) + return AsyncWith(items, body, LINENO(n), n->n_col_offset, c->c_arena); + else + return With(items, body, LINENO(n), n->n_col_offset, c->c_arena); } static stmt_ty @@ -3521,8 +3772,8 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) return NULL; if (forbidden_name(c, classname, CHILD(n, 3), 0)) return NULL; - return ClassDef(classname, NULL, NULL, NULL, NULL, s, decorator_seq, - LINENO(n), n->n_col_offset, c->c_arena); + return ClassDef(classname, NULL, NULL, s, decorator_seq, LINENO(n), + n->n_col_offset, c->c_arena); } if (TYPE(CHILD(n, 3)) == RPAR) { /* class NAME '(' ')' ':' suite */ @@ -3534,8 +3785,8 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) return NULL; if (forbidden_name(c, classname, CHILD(n, 3), 0)) return NULL; - return ClassDef(classname, NULL, NULL, NULL, NULL, s, decorator_seq, - LINENO(n), n->n_col_offset, c->c_arena); + return ClassDef(classname, NULL, NULL, s, decorator_seq, LINENO(n), + n->n_col_offset, c->c_arena); } /* class NAME '(' arglist ')' ':' suite */ @@ -3560,8 +3811,7 @@ ast_for_classdef(struct compiling *c, const node *n, asdl_seq *decorator_seq) if (forbidden_name(c, classname, CHILD(n, 1), 0)) return NULL; - return ClassDef(classname, call->v.Call.args, call->v.Call.keywords, - call->v.Call.starargs, call->v.Call.kwargs, s, + return ClassDef(classname, call->v.Call.args, call->v.Call.keywords, s, decorator_seq, LINENO(n), n->n_col_offset, c->c_arena); } @@ -3607,7 +3857,7 @@ ast_for_stmt(struct compiling *c, const node *n) } else { /* compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt - | funcdef | classdef | decorated + | funcdef | classdef | decorated | async_stmt */ node *ch = CHILD(n, 0); REQ(n, compound_stmt); @@ -3617,17 +3867,19 @@ ast_for_stmt(struct compiling *c, const node *n) case while_stmt: return ast_for_while_stmt(c, ch); case for_stmt: - return ast_for_for_stmt(c, ch); + 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); + 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 small_stmt: TYPE=%d NCH=%d\n", @@ -3692,7 +3944,7 @@ decode_utf8(struct compiling *c, const char **sPtr, const char *end) } static PyObject * -decode_unicode(struct compiling *c, const char *s, size_t len, int rawmode, const char *encoding) +decode_unicode(struct compiling *c, const char *s, size_t len, const char *encoding) { PyObject *v, *u; char *buf; @@ -3748,20 +4000,878 @@ decode_unicode(struct compiling *c, const char *s, size_t len, int rawmode, cons len = p - buf; s = buf; } - if (rawmode) - v = PyUnicode_DecodeRawUnicodeEscape(s, len, NULL); - else - v = PyUnicode_DecodeUnicodeEscape(s, len, NULL); + v = PyUnicode_DecodeUnicodeEscape(s, len, NULL); Py_XDECREF(u); return v; } -/* s is a Python string literal, including the bracketing quote characters, - * and r &/or b prefixes (if any), and embedded escape sequences (if any). - * parsestr parses it, and returns the decoded Python string object. - */ +/* Compile this expression in to an expr_ty. We know that we can + temporarily modify the character before the start of this string + (it's '{'), and we know we can temporarily modify the character + after this string (it is a '}'). Leverage this to create a + sub-string with enough room for us to add parens around the + expression. This is to allow strings with embedded newlines, for + example. */ +static expr_ty +fstring_compile_expr(PyObject *str, Py_ssize_t expr_start, + Py_ssize_t expr_end, struct compiling *c, const node *n) + +{ + PyCompilerFlags cf; + mod_ty mod; + char *utf_expr; + Py_ssize_t i; + Py_UCS4 end_ch = -1; + int all_whitespace; + PyObject *sub = NULL; + + /* We only decref sub if we allocated it with a PyUnicode_Substring. + decref_sub records that. */ + int decref_sub = 0; + + assert(str); + + assert(expr_start >= 0 && expr_start < PyUnicode_GET_LENGTH(str)); + assert(expr_end >= 0 && expr_end < PyUnicode_GET_LENGTH(str)); + assert(expr_end >= expr_start); + + /* There has to be at least one character on each side of the + expression inside this str. This will have been caught before + we're called. */ + assert(expr_start >= 1); + assert(expr_end <= PyUnicode_GET_LENGTH(str)-1); + + /* If the substring is all whitespace, it's an error. We need to + catch this here, and not when we call PyParser_ASTFromString, + because turning the expression '' in to '()' would go from + being invalid to valid. */ + /* Note that this code says an empty string is all + whitespace. That's important. There's a test for it: f'{}'. */ + all_whitespace = 1; + for (i = expr_start; i < expr_end; i++) { + if (!Py_UNICODE_ISSPACE(PyUnicode_READ_CHAR(str, i))) { + all_whitespace = 0; + break; + } + } + if (all_whitespace) { + ast_error(c, n, "f-string: empty expression not allowed"); + goto error; + } + + /* If the substring will be the entire source string, we can't use + PyUnicode_Substring, since it will return another reference to + our original string. Because we're modifying the string in + place, that's a no-no. So, detect that case and just use our + string directly. */ + + if (expr_start-1 == 0 && expr_end+1 == PyUnicode_GET_LENGTH(str)) { + /* If str is well formed, then the first and last chars must + be '{' and '}', respectively. But, if there's a syntax + error, for example f'{3!', then the last char won't be a + closing brace. So, remember the last character we read in + order for us to restore it. */ + end_ch = PyUnicode_ReadChar(str, expr_end-expr_start+1); + assert(end_ch != (Py_UCS4)-1); + + /* In all cases, however, start_ch must be '{'. */ + assert(PyUnicode_ReadChar(str, 0) == '{'); + + sub = str; + } else { + /* Create a substring object. It must be a new object, with + refcount==1, so that we can modify it. */ + sub = PyUnicode_Substring(str, expr_start-1, expr_end+1); + if (!sub) + goto error; + assert(sub != str); /* Make sure it's a new string. */ + decref_sub = 1; /* Remember to deallocate it on error. */ + } + + /* Put () around the expression. */ + if (PyUnicode_WriteChar(sub, 0, '(') < 0 || + PyUnicode_WriteChar(sub, expr_end-expr_start+1, ')') < 0) + goto error; + + /* No need to free the memory returned here: it's managed by the + string. */ + utf_expr = PyUnicode_AsUTF8(sub); + if (!utf_expr) + goto error; + + cf.cf_flags = PyCF_ONLY_AST; + mod = PyParser_ASTFromString(utf_expr, "", + Py_eval_input, &cf, c->c_arena); + if (!mod) + goto error; + + if (sub != str) + /* Clear instead of decref in case we ever modify this code to change + the error handling: this is safest because the XDECREF won't try + and decref it when it's NULL. */ + /* No need to restore the chars in sub, since we know it's getting + ready to get deleted (refcount must be 1, since we got a new string + in PyUnicode_Substring). */ + Py_CLEAR(sub); + else { + assert(!decref_sub); + assert(end_ch != (Py_UCS4)-1); + /* Restore str, which we earlier modified directly. */ + if (PyUnicode_WriteChar(str, 0, '{') < 0 || + PyUnicode_WriteChar(str, expr_end-expr_start+1, end_ch) < 0) + goto error; + } + return mod->v.Expression.body; + +error: + /* Only decref sub if it was the result of a call to SubString. */ + if (decref_sub) + Py_XDECREF(sub); + + if (end_ch != (Py_UCS4)-1) { + /* We only get here if we modified str. Make sure that's the + case: str will be equal to sub. */ + if (str == sub) { + /* Don't check the error, because we've already set the + error state (that's why we're in 'error', after + all). */ + PyUnicode_WriteChar(str, 0, '{'); + PyUnicode_WriteChar(str, expr_end-expr_start+1, end_ch); + } + } + return NULL; +} + +/* 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(PyObject *str, Py_ssize_t *ofs, PyObject **literal, + int recurse_lvl, struct compiling *c, const node *n) +{ + /* Get any literal string. It ends when we hit an un-doubled brace, or the + end of the string. */ + + Py_ssize_t literal_start, literal_end; + int result = 0; + + enum PyUnicode_Kind kind = PyUnicode_KIND(str); + void *data = PyUnicode_DATA(str); + + assert(*literal == NULL); + + literal_start = *ofs; + for (; *ofs < PyUnicode_GET_LENGTH(str); *ofs += 1) { + Py_UCS4 ch = PyUnicode_READ(kind, data, *ofs); + 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 (*ofs + 1 < PyUnicode_GET_LENGTH(str) && + PyUnicode_READ(kind, data, *ofs + 1) == 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. */ + literal_end = *ofs + 1; + *ofs += 2; + result = 1; + goto done; + } + + /* Where a single '{' is the start of a new expression, a + single '}' is not allowed. */ + if (ch == '}') { + 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). */ + break; + } + } + literal_end = *ofs; + + assert(*ofs == PyUnicode_GET_LENGTH(str) || + PyUnicode_READ(kind, data, *ofs) == '{' || + PyUnicode_READ(kind, data, *ofs) == '}'); +done: + if (literal_start != literal_end) { + *literal = PyUnicode_Substring(str, literal_start, literal_end); + if (!*literal) + return -1; + } + + return result; +} + +/* Forward declaration because parsing is recursive. */ +static expr_ty +fstring_parse(PyObject *str, Py_ssize_t *ofs, int recurse_lvl, + struct compiling *c, const node *n); + +/* Parse the f-string str, starting at ofs. We know *ofs starts an + expression (so it must be a '{'). Returns the FormattedValue node, + which includes the expression, conversion character, and + format_spec expression. + + 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. */ +static int +fstring_find_expr(PyObject *str, Py_ssize_t *ofs, int recurse_lvl, + expr_ty *expression, struct compiling *c, const node *n) +{ + /* Return -1 on error, else 0. */ + + Py_ssize_t expr_start; + Py_ssize_t expr_end; + expr_ty simple_expression; + expr_ty format_spec = NULL; /* Optional format specifier. */ + Py_UCS4 conversion = -1; /* The conversion char. -1 if not specified. */ + + enum PyUnicode_Kind kind = PyUnicode_KIND(str); + void *data = PyUnicode_DATA(str); + + /* 0 if we're not in a string, else the quote char we're trying to + match (single or double quote). */ + Py_UCS4 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; + + /* Can only nest one level deep. */ + if (recurse_lvl >= 2) { + ast_error(c, n, "f-string: expressions nested too deeply"); + return -1; + } + + /* The first char must be a left brace, or we wouldn't have gotten + here. Skip over it. */ + assert(PyUnicode_READ(kind, data, *ofs) == '{'); + *ofs += 1; + + expr_start = *ofs; + for (; *ofs < PyUnicode_GET_LENGTH(str); *ofs += 1) { + Py_UCS4 ch; + + /* Loop invariants. */ + assert(nested_depth >= 0); + assert(*ofs >= expr_start); + if (quote_char) + assert(string_type == 1 || string_type == 3); + else + assert(string_type == 0); + + ch = PyUnicode_READ(kind, data, *ofs); + 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 (*ofs+2 < PyUnicode_GET_LENGTH(str) && + PyUnicode_READ(kind, data, *ofs+1) == ch && + PyUnicode_READ(kind, data, *ofs+2) == ch) { + /* We're at the end of a triple quoted string. */ + *ofs += 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; + } + } + /* We're inside a string, and not finished with the + string. If this is a backslash, skip the next char (it + might be an end quote that needs skipping). Otherwise, + just consume this character normally. */ + if (ch == '\\' && *ofs+1 < PyUnicode_GET_LENGTH(str)) { + /* Just skip the next char, whatever it is. */ + *ofs += 1; + } + } else if (ch == '\'' || ch == '"') { + /* Is this a triple quoted string? */ + if (*ofs+2 < PyUnicode_GET_LENGTH(str) && + PyUnicode_READ(kind, data, *ofs+1) == ch && + PyUnicode_READ(kind, data, *ofs+2) == ch) { + string_type = 3; + *ofs += 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 == '(') { + nested_depth++; + } else if (nested_depth != 0 && + (ch == ']' || ch == '}' || ch == ')')) { + nested_depth--; + } else if (ch == '#') { + /* Error: can't include a comment character, inside parens + or not. */ + ast_error(c, n, "f-string cannot include '#'"); + return -1; + } else if (nested_depth == 0 && + (ch == '!' || ch == ':' || ch == '}')) { + /* First, test for the special case of "!=". Since '=' is + not an allowed conversion character, nothing is lost in + this test. */ + if (ch == '!' && *ofs+1 < PyUnicode_GET_LENGTH(str) && + PyUnicode_READ(kind, data, *ofs+1) == '=') + /* This isn't a conversion character, just continue. */ + continue; + + /* Normal way out of this loop. */ + break; + } else { + /* Just consume this char and loop around. */ + } + } + expr_end = *ofs; + /* 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"); + return -1; + } + if (nested_depth) { + ast_error(c, n, "f-string: mismatched '(', '{', or '['"); + return -1; + } + + if (*ofs >= PyUnicode_GET_LENGTH(str)) + 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(str, expr_start, expr_end, c, n); + if (!simple_expression) + return -1; + + /* Check for a conversion char, if present. */ + if (PyUnicode_READ(kind, data, *ofs) == '!') { + *ofs += 1; + if (*ofs >= PyUnicode_GET_LENGTH(str)) + goto unexpected_end_of_string; + + conversion = PyUnicode_READ(kind, data, *ofs); + *ofs += 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'"); + return -1; + } + } + + /* Check for the format spec, if present. */ + if (*ofs >= PyUnicode_GET_LENGTH(str)) + goto unexpected_end_of_string; + if (PyUnicode_READ(kind, data, *ofs) == ':') { + *ofs += 1; + if (*ofs >= PyUnicode_GET_LENGTH(str)) + goto unexpected_end_of_string; + + /* Parse the format spec. */ + format_spec = fstring_parse(str, ofs, recurse_lvl+1, c, n); + if (!format_spec) + return -1; + } + + if (*ofs >= PyUnicode_GET_LENGTH(str) || + PyUnicode_READ(kind, data, *ofs) != '}') + goto unexpected_end_of_string; + + /* We're at a right brace. Consume it. */ + assert(*ofs < PyUnicode_GET_LENGTH(str)); + assert(PyUnicode_READ(kind, data, *ofs) == '}'); + *ofs += 1; + + /* And now create the FormattedValue node that represents this entire + expression with the conversion and format spec. */ + *expression = FormattedValue(simple_expression, (int)conversion, + format_spec, LINENO(n), n->n_col_offset, + c->c_arena); + if (!*expression) + return -1; + + return 0; + +unexpected_end_of_string: + ast_error(c, n, "f-string: expecting '}'"); + 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(PyObject *str, Py_ssize_t *ofs, int recurse_lvl, + PyObject **literal, 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, ofs, 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; + + assert(*ofs <= PyUnicode_GET_LENGTH(str)); + + if (*ofs >= PyUnicode_GET_LENGTH(str) || + PyUnicode_READ_CHAR(str, *ofs) == '}') + /* 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(*ofs < PyUnicode_GET_LENGTH(str) && + PyUnicode_READ_CHAR(str, *ofs) == '{'); + + if (fstring_find_expr(str, ofs, recurse_lvl, expression, c, n) < 0) + goto error; + + return 0; + +error: + Py_XDECREF(*literal); + *literal = NULL; + 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 + Str for the literal 'a'. So you add expr_ty's about twice as + fast as you add exressions 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_RawMalloc(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_RawRealloc(l->p, sizeof(expr_ty) * new_size); + if (!tmp) { + PyMem_RawFree(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_RawFree(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; +} 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; + 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); +} + +/* Make a Str 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; + *str = NULL; + assert(PyUnicode_CheckExact(s)); + if (PyArena_AddPyObject(c->c_arena, s) < 0) { + Py_DECREF(s); + return NULL; + } + return Str(s, LINENO(n), n->n_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. */ + PyObject *temp = PyUnicode_Concat(state->last_str, str); + Py_DECREF(state->last_str); + Py_DECREF(str); + state->last_str = temp; + if (!temp) + return -1; + } + FstringParser_check_invariants(state); + return 0; +} + +/* Parse an f-string. The f-string is in str, starting at ofs, with no 'f' + or quotes. str is not decref'd, since we don't know if it's used elsewhere. + And if we're only looking at a part of a string, then decref'ing is + definitely not the right thing to do! */ +static int +FstringParser_ConcatFstring(FstringParser *state, PyObject *str, + Py_ssize_t *ofs, int recurse_lvl, + struct compiling *c, const node *n) +{ + FstringParser_check_invariants(state); + + /* Parse the f-string. */ + while (1) { + PyObject *literal = 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, ofs, recurse_lvl, + &literal, &expression, + c, n); + if (result < 0) + return -1; + + /* Add the literal, if any. */ + if (!literal) { + /* Do nothing. Just leave last_str alone (and possibly + NULL). */ + } else if (!state->last_str) { + state->last_str = literal; + literal = NULL; + } else { + /* We have a literal, concatenate it. */ + assert(PyUnicode_GET_LENGTH(literal) != 0); + if (FstringParser_ConcatAndDel(state, literal) < 0) + return -1; + literal = NULL; + } + assert(!state->last_str || + PyUnicode_GET_LENGTH(state->last_str) != 0); + + /* We've dealt with the literal now. It can't be leaked on further + errors. */ + assert(literal == NULL); + + /* 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 Str node. */ + if (!state->last_str) { + /* Do nothing. No previous literal. */ + } else { + /* Convert the existing last_str literal to a Str 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; + } + + assert(*ofs <= PyUnicode_GET_LENGTH(str)); + + /* 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 && *ofs < PyUnicode_GET_LENGTH(str)) { + ast_error(c, n, "f-string: unexpected end of string"); + return -1; + } + if (recurse_lvl != 0 && PyUnicode_READ_CHAR(str, *ofs) != '}') { + 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 Str, 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->expr_list.size == 0) { + 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 Str 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; + + /* If there's only one expression, return it. Otherwise, we need + to join them together. */ + if (seq->size == 1) + return seq->elements[0]; + + return JoinedStr(seq, LINENO(n), n->n_col_offset, c->c_arena); + +error: + FstringParser_Dealloc(state); + return NULL; +} + +/* Given an f-string (with no 'f' or quotes) that's in str starting at + ofs, parse it into an expr_ty. Return NULL on error. Does not + decref str. */ +static expr_ty +fstring_parse(PyObject *str, Py_ssize_t *ofs, int recurse_lvl, + struct compiling *c, const node *n) +{ + FstringParser state; + + FstringParser_Init(&state); + if (FstringParser_ConcatFstring(&state, str, ofs, 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 returns the + decoded Python string object. If the string is an f-string, set + *fmode and return the unparsed string object. +*/ static PyObject * -parsestr(struct compiling *c, const node *n, int *bytesmode) +parsestr(struct compiling *c, const node *n, int *bytesmode, int *fmode) { size_t len; const char *s = STR(n); @@ -3781,15 +4891,24 @@ parsestr(struct compiling *c, const node *n, int *bytesmode) quote = *++s; rawmode = 1; } + else if (quote == 'f' || quote == 'F') { + quote = *++s; + *fmode = 1; + } else { break; } } } + if (*fmode && *bytesmode) { + PyErr_BadInternalCall(); + return NULL; + } if (quote != '\'' && quote != '\"') { PyErr_BadInternalCall(); return NULL; } + /* Skip the leading quote char. */ s++; len = strlen(s); if (len > INT_MAX) { @@ -3798,19 +4917,24 @@ parsestr(struct compiling *c, const node *n, int *bytesmode) return NULL; } if (s[--len] != quote) { + /* Last quote char must match the first. */ PyErr_BadInternalCall(); return NULL; } 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 NULL; } } if (!*bytesmode && !rawmode) { - return decode_unicode(c, s, len, rawmode, c->c_encoding); + return decode_unicode(c, s, len, c->c_encoding); } if (*bytesmode) { /* Disallow non-ascii characters (but not escapes) */ @@ -3842,51 +4966,84 @@ parsestr(struct compiling *c, const node *n, int *bytesmode) } } return PyBytes_DecodeEscape(s, len, NULL, 1, - need_encoding ? c->c_encoding : NULL); + need_encoding ? c->c_encoding : NULL); } -/* Build a Python string object out of a STRING+ atom. This takes care of - * compile-time literal catenation, calling parsestr() on each piece, and - * pasting the intermediate results together. - */ -static PyObject * -parsestrplus(struct compiling *c, const node *n, int *bytesmode) +/* 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 Bytes node. For + normal strings and f-strings, concatenate them together. The result + will be a Str 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) { - PyObject *v; + int bytesmode = 0; + PyObject *bytes_str = NULL; int i; - REQ(CHILD(n, 0), STRING); - v = parsestr(c, CHILD(n, 0), bytesmode); - if (v != NULL) { - /* String literal concatenation */ - for (i = 1; i < NCH(n); i++) { - PyObject *s; - int subbm = 0; - s = parsestr(c, CHILD(n, i), &subbm); - if (s == NULL) - goto onError; - if (*bytesmode != subbm) { - ast_error(c, n, "cannot mix bytes and nonbytes literals"); - Py_DECREF(s); - goto onError; - } - if (PyBytes_Check(v) && PyBytes_Check(s)) { - PyBytes_ConcatAndDel(&v, s); - if (v == NULL) - goto onError; - } - else { - PyObject *temp = PyUnicode_Concat(v, s); - Py_DECREF(s); - Py_DECREF(v); - v = temp; - if (v == NULL) - goto onError; + + FstringParser state; + FstringParser_Init(&state); + + for (i = 0; i < NCH(n); i++) { + int this_bytesmode = 0; + int this_fmode = 0; + PyObject *s; + + REQ(CHILD(n, i), STRING); + s = parsestr(c, CHILD(n, i), &this_bytesmode, &this_fmode); + if (!s) + 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"); + Py_DECREF(s); + goto error; + } + bytesmode = this_bytesmode; + + 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 if (this_fmode) { + /* This is an f-string. Concatenate and decref it. */ + Py_ssize_t ofs = 0; + int result = FstringParser_ConcatFstring(&state, s, &ofs, 0, c, n); + Py_DECREF(s); + if (result < 0) + goto error; + } else { + /* This is a regular string. Concatenate it. */ + if (FstringParser_ConcatAndDel(&state, s) < 0) + goto error; } } - return v; + if (bytesmode) { + /* Just return the bytes object and we're done. */ + if (PyArena_AddPyObject(c->c_arena, bytes_str) < 0) + goto error; + return Bytes(bytes_str, LINENO(n), n->n_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); - onError: - Py_XDECREF(v); +error: + Py_XDECREF(bytes_str); + FstringParser_Dealloc(&state); return NULL; } diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 057ab47e974a..3b707184fb17 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -46,13 +46,16 @@ _Py_IDENTIFIER(stdin); _Py_IDENTIFIER(stdout); _Py_IDENTIFIER(stderr); +#include "clinic/bltinmodule.c.h" + +/* AC: cannot convert yet, waiting for *args support */ static PyObject * builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds) { PyObject *func, *name, *bases, *mkw, *meta, *winner, *prep, *ns, *cell; PyObject *cls = NULL; Py_ssize_t nargs; - int isclass; + int isclass = 0; /* initialize to prevent gcc warning */ assert(args != NULL); if (!PyTuple_Check(args)) { @@ -69,7 +72,7 @@ builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds) func = PyTuple_GET_ITEM(args, 0); /* Better be callable */ if (!PyFunction_Check(func)) { PyErr_SetString(PyExc_TypeError, - "__build__class__: func must be a function"); + "__build_class__: func must be a function"); return NULL; } name = PyTuple_GET_ITEM(args, 1); @@ -229,25 +232,42 @@ 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 *self, PyObject *v) +builtin_abs(PyModuleDef *module, PyObject *x) +/*[clinic end generated code: output=6833047c493ecea2 input=bed4ca14e29c20d1]*/ { - return PyNumber_Absolute(v); + return PyNumber_Absolute(x); } -PyDoc_STRVAR(abs_doc, -"abs(number) -> number\n\ -\n\ -Return the absolute value of the argument."); +/*[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 *self, PyObject *v) +builtin_all(PyModuleDef *module, PyObject *iterable) +/*[clinic end generated code: output=089e6d1b7bde27b1 input=1a7c5d1bc3438a21]*/ { PyObject *it, *item; PyObject *(*iternext)(PyObject *); int cmp; - it = PyObject_GetIter(v); + it = PyObject_GetIter(iterable); if (it == NULL) return NULL; iternext = *Py_TYPE(it)->tp_iternext; @@ -277,20 +297,26 @@ builtin_all(PyObject *self, PyObject *v) Py_RETURN_TRUE; } -PyDoc_STRVAR(all_doc, -"all(iterable) -> bool\n\ -\n\ -Return True if bool(x) is True for all values x in the iterable.\n\ -If the iterable is empty, 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 *self, PyObject *v) +builtin_any(PyModuleDef *module, PyObject *iterable) +/*[clinic end generated code: output=1be994b2c2307492 input=41d7451c23384f24]*/ { PyObject *it, *item; PyObject *(*iternext)(PyObject *); int cmp; - it = PyObject_GetIter(v); + it = PyObject_GetIter(iterable); if (it == NULL) return NULL; iternext = *Py_TYPE(it)->tp_iternext; @@ -305,7 +331,7 @@ builtin_any(PyObject *self, PyObject *v) Py_DECREF(it); return NULL; } - if (cmp == 1) { + if (cmp > 0) { Py_DECREF(it); Py_RETURN_TRUE; } @@ -320,56 +346,67 @@ builtin_any(PyObject *self, PyObject *v) Py_RETURN_FALSE; } -PyDoc_STRVAR(any_doc, -"any(iterable) -> bool\n\ -\n\ -Return True if bool(x) is True for any x in the iterable.\n\ -If the iterable is empty, 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 *self, PyObject *v) +builtin_ascii(PyModuleDef *module, PyObject *obj) +/*[clinic end generated code: output=d4e862c48af2a933 input=4c62732e1b3a3cc9]*/ { - return PyObject_ASCII(v); + return PyObject_ASCII(obj); } -PyDoc_STRVAR(ascii_doc, -"ascii(object) -> string\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."); +/*[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 *self, PyObject *v) +builtin_bin(PyModuleDef *module, PyObject *number) +/*[clinic end generated code: output=25ee26c6cf3bbb54 input=53f8a0264bacaf90]*/ { - return PyNumber_ToBase(v, 2); + return PyNumber_ToBase(number, 2); } -PyDoc_STRVAR(bin_doc, -"bin(number) -> string\n\ -\n\ -Return the binary representation of an integer.\n\ -\n\ - >>> bin(2796202)\n\ - '0b1010101010101010101010'\n\ -"); +/*[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 *self, PyObject *v) +builtin_callable(PyModuleDef *module, PyObject *obj) +/*[clinic end generated code: output=f4df2ce92364b656 input=1423bab99cc41f58]*/ { - return PyBool_FromLong((long)PyCallable_Check(v)); + return PyBool_FromLong((long)PyCallable_Check(obj)); } -PyDoc_STRVAR(callable_doc, -"callable(object) -> bool\n\ -\n\ -Return whether the object is callable (i.e., some kind of function).\n\ -Note that classes are callable, as are instances of classes with a\n\ -__call__() method."); - typedef struct { PyObject_HEAD @@ -432,6 +469,7 @@ filter_next(filterobject *lz) 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 (;;) { @@ -439,12 +477,11 @@ filter_next(filterobject *lz) if (item == NULL) return NULL; - if (lz->func == Py_None || lz->func == (PyObject *)&PyBool_Type) { + if (checktrue) { ok = PyObject_IsTrue(item); } else { PyObject *good; - good = PyObject_CallFunctionObjArgs(lz->func, - item, NULL); + good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); if (good == NULL) { Py_DECREF(item); return NULL; @@ -524,45 +561,47 @@ PyTypeObject PyFilter_Type = { }; -static PyObject * -builtin_format(PyObject *self, PyObject *args) -{ - PyObject *value; - PyObject *format_spec = NULL; +/*[clinic input] +format as builtin_format - if (!PyArg_ParseTuple(args, "O|U:format", &value, &format_spec)) - return NULL; + value: object + format_spec: unicode(c_default="NULL") = '' + / - return PyObject_Format(value, format_spec); -} +Return value.__format__(format_spec) -PyDoc_STRVAR(format_doc, -"format(value[, format_spec]) -> string\n\ -\n\ -Returns value.__format__(format_spec)\n\ -format_spec defaults to \"\""); +format_spec defaults to the empty string +[clinic start generated code]*/ static PyObject * -builtin_chr(PyObject *self, PyObject *args) +builtin_format_impl(PyModuleDef *module, PyObject *value, + PyObject *format_spec) +/*[clinic end generated code: output=4341fd78a5f01764 input=6325e751a1b29b86]*/ { - int x; + return PyObject_Format(value, format_spec); +} - if (!PyArg_ParseTuple(args, "i:chr", &x)) - return NULL; +/*[clinic input] +chr as builtin_chr - return PyUnicode_FromOrdinal(x); -} + i: int + / -PyDoc_STRVAR(chr_doc, -"chr(i) -> Unicode character\n\ -\n\ -Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff."); +Return a Unicode string of one character with ordinal i; 0 <= i <= 0x10ffff. +[clinic start generated code]*/ + +static PyObject * +builtin_chr_impl(PyModuleDef *module, int i) +/*[clinic end generated code: output=67fe4d87e690f373 input=3f604ef45a70750d]*/ +{ + return PyUnicode_FromOrdinal(i); +} -static char * -source_as_string(PyObject *cmd, char *funcname, char *what, PyCompilerFlags *cf) +static const char * +source_as_string(PyObject *cmd, const char *funcname, const char *what, PyCompilerFlags *cf, Py_buffer *view) { - char *str; + const char *str; Py_ssize_t size; if (PyUnicode_Check(cmd)) { @@ -571,52 +610,67 @@ source_as_string(PyObject *cmd, char *funcname, char *what, PyCompilerFlags *cf) if (str == NULL) return NULL; } - else if (!PyObject_CheckReadBuffer(cmd)) { + else if (PyObject_GetBuffer(cmd, view, PyBUF_SIMPLE) == 0) { + str = (const char *)view->buf; + size = view->len; + } + else { PyErr_Format(PyExc_TypeError, "%s() arg 1 must be a %s object", funcname, what); return NULL; } - else if (PyObject_AsReadBuffer(cmd, (const void **)&str, &size) < 0) { - return NULL; - } - if (strlen(str) != size) { - PyErr_SetString(PyExc_TypeError, + if (strlen(str) != (size_t)size) { + PyErr_SetString(PyExc_ValueError, "source code string cannot contain null bytes"); + PyBuffer_Release(view); return NULL; } return str; } +/*[clinic input] +compile as builtin_compile + + source: object + filename: object(converter="PyUnicode_FSDecoder") + mode: str + flags: int = 0 + dont_inherit: int(c_default="0") = False + optimize: 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(PyObject *self, PyObject *args, PyObject *kwds) +builtin_compile_impl(PyModuleDef *module, PyObject *source, + PyObject *filename, const char *mode, int flags, + int dont_inherit, int optimize) +/*[clinic end generated code: output=31881762c1bb90c4 input=9d53e8cfb3c86414]*/ { - char *str; - PyObject *filename; - char *startstr; - int mode = -1; - int dont_inherit = 0; - int supplied_flags = 0; - int optimize = -1; + Py_buffer view = {NULL, NULL}; + const char *str; + int compile_mode = -1; int is_ast; PyCompilerFlags cf; - PyObject *cmd; - static char *kwlist[] = {"source", "filename", "mode", "flags", - "dont_inherit", "optimize", NULL}; int start[] = {Py_file_input, Py_eval_input, Py_single_input}; PyObject *result; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&s|iii:compile", kwlist, - &cmd, - PyUnicode_FSDecoder, &filename, - &startstr, &supplied_flags, - &dont_inherit, &optimize)) - return NULL; - - cf.cf_flags = supplied_flags | PyCF_SOURCE_IS_UTF8; + cf.cf_flags = flags | PyCF_SOURCE_IS_UTF8; - if (supplied_flags & + if (flags & ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_DONT_IMPLY_DEDENT | PyCF_ONLY_AST)) { PyErr_SetString(PyExc_ValueError, @@ -635,25 +689,25 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) PyEval_MergeCompilerFlags(&cf); } - if (strcmp(startstr, "exec") == 0) - mode = 0; - else if (strcmp(startstr, "eval") == 0) - mode = 1; - else if (strcmp(startstr, "single") == 0) - mode = 2; + 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 { PyErr_SetString(PyExc_ValueError, - "compile() arg 3 must be 'exec', 'eval' or 'single'"); + "compile() mode must be 'exec', 'eval' or 'single'"); goto error; } - is_ast = PyAST_Check(cmd); + is_ast = PyAST_Check(source); if (is_ast == -1) goto error; if (is_ast) { - if (supplied_flags & PyCF_ONLY_AST) { - Py_INCREF(cmd); - result = cmd; + if (flags & PyCF_ONLY_AST) { + Py_INCREF(source); + result = source; } else { PyArena *arena; @@ -662,7 +716,7 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) arena = PyArena_New(); if (arena == NULL) goto error; - mod = PyAST_obj2mod(cmd, arena, mode); + mod = PyAST_obj2mod(source, arena, compile_mode); if (mod == NULL) { PyArena_Free(arena); goto error; @@ -678,11 +732,12 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) goto finally; } - str = source_as_string(cmd, "compile", "string, bytes or AST", &cf); + str = source_as_string(source, "compile", "string, bytes or AST", &cf, &view); if (str == NULL) goto error; - result = Py_CompileStringObject(str, filename, start[mode], &cf, optimize); + result = Py_CompileStringObject(str, filename, start[compile_mode], &cf, optimize); + PyBuffer_Release(&view); goto finally; error: @@ -692,21 +747,7 @@ builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) return result; } -PyDoc_STRVAR(compile_doc, -"compile(source, filename, mode[, flags[, dont_inherit]]) -> code object\n\ -\n\ -Compile the source string (a Python module, statement or expression)\n\ -into a code object that can be executed by exec() or eval().\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 non-zero, stops the compilation inheriting\n\ -the effects of any future statements in effect in the code calling\n\ -compile; if absent or zero these statements do influence the compilation,\n\ -in addition to any features explicitly specified."); - +/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ static PyObject * builtin_dir(PyObject *self, PyObject *args) { @@ -731,32 +772,51 @@ PyDoc_STRVAR(dir_doc, " 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-x%y)/y, x%y). Invariant: div*y + mod == x. +[clinic start generated code]*/ + static PyObject * -builtin_divmod(PyObject *self, PyObject *args) +builtin_divmod_impl(PyModuleDef *module, PyObject *x, PyObject *y) +/*[clinic end generated code: output=9ad0076120ebf9ac input=7fdb15f8a97a5fe7]*/ { - PyObject *v, *w; - - if (!PyArg_UnpackTuple(args, "divmod", 2, 2, &v, &w)) - return NULL; - return PyNumber_Divmod(v, w); + return PyNumber_Divmod(x, y); } -PyDoc_STRVAR(divmod_doc, -"divmod(x, y) -> (div, mod)\n\ -\n\ -Return the tuple ((x-x%y)/y, x%y). Invariant: div*y + mod == x."); +/*[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(PyObject *self, PyObject *args) +builtin_eval_impl(PyModuleDef *module, PyObject *source, PyObject *globals, + PyObject *locals) +/*[clinic end generated code: output=7284501fb7b4d666 input=11ee718a8640e527]*/ { - PyObject *cmd, *result, *tmp = NULL; - PyObject *globals = Py_None, *locals = Py_None; - char *str; + PyObject *result, *tmp = NULL; + Py_buffer view = {NULL, NULL}; + const char *str; PyCompilerFlags cf; - if (!PyArg_UnpackTuple(args, "eval", 1, 3, &cmd, &globals, &locals)) - return NULL; if (locals != Py_None && !PyMapping_Check(locals)) { PyErr_SetString(PyExc_TypeError, "locals must be a mapping"); return NULL; @@ -791,17 +851,17 @@ builtin_eval(PyObject *self, PyObject *args) return NULL; } - if (PyCode_Check(cmd)) { - if (PyCode_GetNumFree((PyCodeObject *)cmd) > 0) { + if (PyCode_Check(source)) { + 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(cmd, globals, locals); + return PyEval_EvalCode(source, globals, locals); } cf.cf_flags = PyCF_SOURCE_IS_UTF8; - str = source_as_string(cmd, "eval", "string, bytes or code", &cf); + str = source_as_string(source, "eval", "string, bytes or code", &cf, &view); if (str == NULL) return NULL; @@ -810,28 +870,34 @@ builtin_eval(PyObject *self, PyObject *args) (void)PyEval_MergeCompilerFlags(&cf); result = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf); + PyBuffer_Release(&view); Py_XDECREF(tmp); return result; } -PyDoc_STRVAR(eval_doc, -"eval(source[, globals[, locals]]) -> value\n\ -\n\ -Evaluate the source in the context of globals and locals.\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.\n"); +/*[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(PyObject *self, PyObject *args) +builtin_exec_impl(PyModuleDef *module, PyObject *source, PyObject *globals, + PyObject *locals) +/*[clinic end generated code: output=83d574ef9d5d0b46 input=01ca3e1c01692829]*/ { PyObject *v; - PyObject *prog, *globals = Py_None, *locals = Py_None; - - if (!PyArg_UnpackTuple(args, "exec", 1, 3, &prog, &globals, &locals)) - return NULL; if (globals == Py_None) { globals = PyEval_GetGlobals(); @@ -850,13 +916,13 @@ builtin_exec(PyObject *self, PyObject *args) locals = globals; if (!PyDict_Check(globals)) { - PyErr_Format(PyExc_TypeError, "exec() arg 2 must be a dict, not %.100s", + 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, - "arg 3 must be a mapping or None, not %.100s", + "locals must be a mapping or None, not %.100s", locals->ob_type->tp_name); return NULL; } @@ -866,21 +932,22 @@ builtin_exec(PyObject *self, PyObject *args) return NULL; } - if (PyCode_Check(prog)) { - if (PyCode_GetNumFree((PyCodeObject *)prog) > 0) { + if (PyCode_Check(source)) { + 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(prog, globals, locals); + v = PyEval_EvalCode(source, globals, locals); } else { - char *str; + Py_buffer view = {NULL, NULL}; + const char *str; PyCompilerFlags cf; cf.cf_flags = PyCF_SOURCE_IS_UTF8; - str = source_as_string(prog, "exec", - "string, bytes or code", &cf); + str = source_as_string(source, "exec", + "string, bytes or code", &cf, &view); if (str == NULL) return NULL; if (PyEval_MergeCompilerFlags(&cf)) @@ -888,6 +955,7 @@ builtin_exec(PyObject *self, PyObject *args) locals, &cf); else v = PyRun_String(str, Py_file_input, globals, locals); + PyBuffer_Release(&view); } if (v == NULL) return NULL; @@ -895,15 +963,8 @@ builtin_exec(PyObject *self, PyObject *args) Py_RETURN_NONE; } -PyDoc_STRVAR(exec_doc, -"exec(object[, globals[, locals]])\n\ -\n\ -Read and execute code from an object, which can be a string or a code\n\ -object.\n\ -The globals and locals are dictionaries, defaulting to the current\n\ -globals and locals. If only globals is given, locals defaults to it."); - +/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ static PyObject * builtin_getattr(PyObject *self, PyObject *args) { @@ -937,8 +998,18 @@ 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(PyObject *self) +builtin_globals_impl(PyModuleDef *module) +/*[clinic end generated code: output=4958645e96dd8138 input=9327576f92bb48ba]*/ { PyObject *d; @@ -947,26 +1018,31 @@ builtin_globals(PyObject *self) return d; } -PyDoc_STRVAR(globals_doc, -"globals() -> dictionary\n\ -\n\ -Return the dictionary containing the current scope's global variables."); +/*[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(PyObject *self, PyObject *args) +builtin_hasattr_impl(PyModuleDef *module, PyObject *obj, PyObject *name) +/*[clinic end generated code: output=81154fdd63634696 input=0faec9787d979542]*/ { PyObject *v; - PyObject *name; - if (!PyArg_UnpackTuple(args, "hasattr", 2, 2, &v, &name)) - return NULL; if (!PyUnicode_Check(name)) { PyErr_SetString(PyExc_TypeError, "hasattr(): attribute name must be string"); return NULL; } - v = PyObject_GetAttr(v, name); + v = PyObject_GetAttr(obj, name); if (v == NULL) { if (PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear(); @@ -978,25 +1054,31 @@ builtin_hasattr(PyObject *self, PyObject *args) Py_RETURN_TRUE; } -PyDoc_STRVAR(hasattr_doc, -"hasattr(object, name) -> bool\n\ -\n\ -Return whether the object has an attribute with the given name.\n\ -(This is done by calling getattr(object, name) and catching AttributeError.)"); +/* 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(PyObject *self, PyObject *v) +builtin_id(PyModuleDef *self, PyObject *v) +/*[clinic end generated code: output=0aa640785f697f65 input=5a534136419631f4]*/ { return PyLong_FromVoidPtr(v); } -PyDoc_STRVAR(id_doc, -"id(object) -> integer\n\ -\n\ -Return the identity of an object. This is guaranteed to be unique among\n\ -simultaneously existing objects. (Hint: it's the object's memory address.)"); - /* map object ************************************************************/ @@ -1076,13 +1158,14 @@ map_next(mapobject *lz) PyObject *result; Py_ssize_t numargs, i; - numargs = PyTuple_Size(lz->iters); + numargs = PyTuple_GET_SIZE(lz->iters); argtuple = PyTuple_New(numargs); if (argtuple == NULL) return NULL; for (i=0 ; iiters, i)); + PyObject *it = PyTuple_GET_ITEM(lz->iters, i); + val = Py_TYPE(it)->tp_iternext(it); if (val == NULL) { Py_DECREF(argtuple); return NULL; @@ -1169,6 +1252,8 @@ PyTypeObject PyMap_Type = { PyObject_GC_Del, /* tp_free */ }; + +/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ static PyObject * builtin_next(PyObject *self, PyObject *args) { @@ -1210,83 +1295,100 @@ 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(PyObject *self, PyObject *args) +builtin_setattr_impl(PyModuleDef *module, PyObject *obj, PyObject *name, + PyObject *value) +/*[clinic end generated code: output=d881c655c0f7e34f input=bd2b7ca6875a1899]*/ { - PyObject *v; - PyObject *name; - PyObject *value; - - if (!PyArg_UnpackTuple(args, "setattr", 3, 3, &v, &name, &value)) - return NULL; - if (PyObject_SetAttr(v, name, value) != 0) + if (PyObject_SetAttr(obj, name, value) != 0) return NULL; Py_INCREF(Py_None); return Py_None; } -PyDoc_STRVAR(setattr_doc, -"setattr(object, name, value)\n\ -\n\ -Set a named attribute on an object; setattr(x, 'y', v) is equivalent to\n\ -``x.y = v''."); +/*[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(PyObject *self, PyObject *args) +builtin_delattr_impl(PyModuleDef *module, PyObject *obj, PyObject *name) +/*[clinic end generated code: output=ef653e698a0b4187 input=db16685d6b4b9410]*/ { - PyObject *v; - PyObject *name; - - if (!PyArg_UnpackTuple(args, "delattr", 2, 2, &v, &name)) - return NULL; - if (PyObject_SetAttr(v, name, (PyObject *)NULL) != 0) + if (PyObject_SetAttr(obj, name, (PyObject *)NULL) != 0) return NULL; Py_INCREF(Py_None); return Py_None; } -PyDoc_STRVAR(delattr_doc, -"delattr(object, name)\n\ -\n\ -Delete a named attribute on an object; delattr(x, 'y') is equivalent to\n\ -``del x.y''."); +/*[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 *self, PyObject *v) +builtin_hash(PyModuleDef *module, PyObject *obj) +/*[clinic end generated code: output=1f32ff154c1f751a input=58c48be822bf9c54]*/ { Py_hash_t x; - x = PyObject_Hash(v); + x = PyObject_Hash(obj); if (x == -1) return NULL; return PyLong_FromSsize_t(x); } -PyDoc_STRVAR(hash_doc, -"hash(object) -> integer\n\ -\n\ -Return a hash value for the object. Two objects with the same value have\n\ -the same hash value. The reverse is not necessarily true, but likely."); +/*[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 *self, PyObject *v) +builtin_hex(PyModuleDef *module, PyObject *number) +/*[clinic end generated code: output=618489ce3cbc5858 input=e645aff5fc7d540e]*/ { - return PyNumber_ToBase(v, 16); + return PyNumber_ToBase(number, 16); } -PyDoc_STRVAR(hex_doc, -"hex(number) -> string\n\ -\n\ -Return the hexadecimal representation of an integer.\n\ -\n\ - >>> hex(3735928559)\n\ - '0xdeadbeef'\n\ -"); - +/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ static PyObject * builtin_iter(PyObject *self, PyObject *args) { @@ -1313,25 +1415,41 @@ 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 *self, PyObject *v) +builtin_len(PyModuleDef *module, PyObject *obj) +/*[clinic end generated code: output=8e5837b6f81d915b input=bc55598da9e9c9b5]*/ { Py_ssize_t res; - res = PyObject_Size(v); + res = PyObject_Size(obj); if (res < 0 && PyErr_Occurred()) return NULL; return PyLong_FromSsize_t(res); } -PyDoc_STRVAR(len_doc, -"len(object) -> integer\n\ -\n\ -Return the number of items of a sequence or mapping."); +/*[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(PyObject *self) +builtin_locals_impl(PyModuleDef *module) +/*[clinic end generated code: output=8b5a41f12e19d13a input=7874018d478d5c4b]*/ { PyObject *d; @@ -1340,11 +1458,6 @@ builtin_locals(PyObject *self) return d; } -PyDoc_STRVAR(locals_doc, -"locals() -> dictionary\n\ -\n\ -Update and return a dictionary containing the current scope's local variables."); - static PyObject * min_max(PyObject *args, PyObject *kwds, int op) @@ -1447,6 +1560,7 @@ min_max(PyObject *args, PyObject *kwds, int op) return NULL; } +/* AC: cannot convert yet, waiting for *args support */ static PyObject * builtin_min(PyObject *self, PyObject *args, PyObject *kwds) { @@ -1454,13 +1568,16 @@ builtin_min(PyObject *self, PyObject *args, PyObject *kwds) } PyDoc_STRVAR(min_doc, -"min(iterable[, key=func]) -> value\n\ -min(a, b, c, ...[, key=func]) -> value\n\ +"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.\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) { @@ -1468,63 +1585,79 @@ builtin_max(PyObject *self, PyObject *args, PyObject *kwds) } PyDoc_STRVAR(max_doc, -"max(iterable[, key=func]) -> value\n\ -max(a, b, c, ...[, key=func]) -> value\n\ +"max(iterable, *[, default=obj, key=func]) -> value\n\ +max(arg1, arg2, *args, *[, key=func]) -> value\n\ \n\ -With a single iterable argument, return its largest item.\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 *self, PyObject *v) +builtin_oct(PyModuleDef *module, PyObject *number) +/*[clinic end generated code: output=18f701bc6d8f804a input=ad6b274af4016c72]*/ { - return PyNumber_ToBase(v, 8); + return PyNumber_ToBase(number, 8); } -PyDoc_STRVAR(oct_doc, -"oct(number) -> string\n\ -\n\ -Return the octal representation of an integer.\n\ -\n\ - >>> oct(342391)\n\ - '0o1234567'\n\ -"); +/*[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 *self, PyObject* obj) +builtin_ord(PyModuleDef *module, PyObject *c) +/*[clinic end generated code: output=04fd27272d9462f6 input=3064e5d6203ad012]*/ { long ord; Py_ssize_t size; - if (PyBytes_Check(obj)) { - size = PyBytes_GET_SIZE(obj); + if (PyBytes_Check(c)) { + size = PyBytes_GET_SIZE(c); if (size == 1) { - ord = (long)((unsigned char)*PyBytes_AS_STRING(obj)); + ord = (long)((unsigned char)*PyBytes_AS_STRING(c)); return PyLong_FromLong(ord); } } - else if (PyUnicode_Check(obj)) { - if (PyUnicode_READY(obj) == -1) + else if (PyUnicode_Check(c)) { + if (PyUnicode_READY(c) == -1) return NULL; - size = PyUnicode_GET_LENGTH(obj); + size = PyUnicode_GET_LENGTH(c); if (size == 1) { - ord = (long)PyUnicode_READ_CHAR(obj, 0); + ord = (long)PyUnicode_READ_CHAR(c, 0); return PyLong_FromLong(ord); } } - else if (PyByteArray_Check(obj)) { + else if (PyByteArray_Check(c)) { /* XXX Hopefully this is temporary */ - size = PyByteArray_GET_SIZE(obj); + size = PyByteArray_GET_SIZE(c); if (size == 1) { - ord = (long)((unsigned char)*PyByteArray_AS_STRING(obj)); + 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", obj->ob_type->tp_name); + "%.200s found", c->ob_type->tp_name); return NULL; } @@ -1535,31 +1668,30 @@ builtin_ord(PyObject *self, PyObject* obj) return NULL; } -PyDoc_VAR(ord_doc) = PyDoc_STR( -"ord(c) -> integer\n\ -\n\ -Return the integer ordinal of a one-character string." -); +/*[clinic input] +pow as builtin_pow -static PyObject * -builtin_pow(PyObject *self, PyObject *args) -{ - PyObject *v, *w, *z = Py_None; + x: object + y: object + z: object = None + / - if (!PyArg_UnpackTuple(args, "pow", 2, 3, &v, &w, &z)) - return NULL; - return PyNumber_Power(v, w, z); -} +Equivalent to x**y (with two arguments) or x**y % z (with three arguments) -PyDoc_STRVAR(pow_doc, -"pow(x, y[, z]) -> number\n\ -\n\ -With two arguments, equivalent to x**y. With three arguments,\n\ -equivalent to (x**y) % z, but may be more efficient (e.g. for ints)."); +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(PyModuleDef *module, PyObject *x, PyObject *y, PyObject *z) +/*[clinic end generated code: output=1fba268adba9b45f input=653d57d38d41fc07]*/ +{ + return PyNumber_Power(x, y, z); +} +/* AC: cannot convert yet, waiting for *args support */ static PyObject * builtin_print(PyObject *self, PyObject *args, PyObject *kwds) { @@ -1655,10 +1787,25 @@ 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(PyObject *self, PyObject *args) +builtin_input_impl(PyModuleDef *module, PyObject *prompt) +/*[clinic end generated code: output=b77731f59e1515c4 input=5e8bb70c2908fe3c]*/ { - PyObject *promptarg = NULL; PyObject *fin = _PySys_GetObjectId(&PyId_stdin); PyObject *fout = _PySys_GetObjectId(&PyId_stdout); PyObject *ferr = _PySys_GetObjectId(&PyId_stderr); @@ -1666,10 +1813,6 @@ builtin_input(PyObject *self, PyObject *args) long fd; int tty; - /* Parse arguments */ - if (!PyArg_UnpackTuple(args, "input", 0, 1, &promptarg)) - return NULL; - /* Check that stdin/out/err are intact */ if (fin == NULL || fin == Py_None) { PyErr_SetString(PyExc_RuntimeError, @@ -1711,8 +1854,10 @@ builtin_input(PyObject *self, PyObject *args) } if (tty) { tmp = _PyObject_CallMethodId(fout, &PyId_fileno, ""); - if (tmp == NULL) + if (tmp == NULL) { PyErr_Clear(); + tty = 0; + } else { fd = PyLong_AsLong(tmp); Py_DECREF(tmp); @@ -1725,7 +1870,7 @@ builtin_input(PyObject *self, PyObject *args) /* If we're interactive, use (GNU) readline */ if (tty) { PyObject *po = NULL; - char *prompt; + char *promptstr; char *s = NULL; PyObject *stdin_encoding = NULL, *stdin_errors = NULL; PyObject *stdout_encoding = NULL, *stdout_errors = NULL; @@ -1748,7 +1893,7 @@ builtin_input(PyObject *self, PyObject *args) PyErr_Clear(); else Py_DECREF(tmp); - if (promptarg != NULL) { + if (prompt != NULL) { /* We have a prompt, encode it as stdout would */ char *stdout_encoding_str, *stdout_errors_str; PyObject *stringpo; @@ -1760,7 +1905,7 @@ builtin_input(PyObject *self, PyObject *args) stdout_errors_str = _PyUnicode_AsString(stdout_errors); if (!stdout_encoding_str || !stdout_errors_str) goto _readline_errors; - stringpo = PyObject_Str(promptarg); + stringpo = PyObject_Str(prompt); if (stringpo == NULL) goto _readline_errors; po = PyUnicode_AsEncodedString(stringpo, @@ -1770,15 +1915,15 @@ builtin_input(PyObject *self, PyObject *args) Py_CLEAR(stringpo); if (po == NULL) goto _readline_errors; - prompt = PyBytes_AsString(po); - if (prompt == NULL) + promptstr = PyBytes_AsString(po); + if (promptstr == NULL) goto _readline_errors; } else { po = NULL; - prompt = ""; + promptstr = ""; } - s = PyOS_Readline(stdin, stdout, prompt); + s = PyOS_Readline(stdin, stdout, promptstr); if (s == NULL) { PyErr_CheckSignals(); if (!PyErr_Occurred()) @@ -1820,8 +1965,8 @@ builtin_input(PyObject *self, PyObject *args) } /* Fallback if we're not interactive */ - if (promptarg != NULL) { - if (PyFile_WriteObject(promptarg, fout, Py_PRINT_RAW) != 0) + if (prompt != NULL) { + if (PyFile_WriteObject(prompt, fout, Py_PRINT_RAW) != 0) return NULL; } tmp = _PyObject_CallMethodId(fout, &PyId_flush, ""); @@ -1832,28 +1977,29 @@ builtin_input(PyObject *self, PyObject *args) return PyFile_GetLine(fin, -1); } -PyDoc_STRVAR(input_doc, -"input([prompt]) -> string\n\ -\n\ -Read a string from standard input. The trailing newline is stripped.\n\ -If the user hits EOF (Unix: Ctl-D, Windows: Ctl-Z+Return), raise EOFError.\n\ -On Unix, GNU readline is used if enabled. The prompt string, if given,\n\ -is printed without a trailing newline before reading."); +/*[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 *self, PyObject *v) +builtin_repr(PyModuleDef *module, PyObject *obj) +/*[clinic end generated code: output=dc41784fa4341834 input=1c9e6d66d3e3be04]*/ { - return PyObject_Repr(v); + return PyObject_Repr(obj); } -PyDoc_STRVAR(repr_doc, -"repr(object) -> string\n\ -\n\ -Return the canonical string representation of the object.\n\ -For most object types, eval(repr(object)) == object."); - +/* AC: cannot convert yet, as needs PEP 457 group support in inspect + * or a semantic change to accept None for "ndigits" + */ static PyObject * builtin_round(PyObject *self, PyObject *args, PyObject *kwds) { @@ -1895,6 +2041,35 @@ This returns an int when called with one argument, otherwise the\n\ same type as the number. ndigits may be negative."); +/*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 customise 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 customise the sort order, and the\n" +"reverse flag can be set to request the result in descending order."); + +#define BUILTIN_SORTED_METHODDEF \ + {"sorted", (PyCFunction)builtin_sorted, METH_VARARGS|METH_KEYWORDS, builtin_sorted__doc__}, + static PyObject * builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds) { @@ -1936,9 +2111,8 @@ builtin_sorted(PyObject *self, PyObject *args, PyObject *kwds) return newlist; } -PyDoc_STRVAR(sorted_doc, -"sorted(iterable, key=None, reverse=False) --> new sorted list"); +/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ static PyObject * builtin_vars(PyObject *self, PyObject *args) { @@ -1970,17 +2144,29 @@ PyDoc_STRVAR(vars_doc, Without arguments, equivalent to locals().\n\ With an argument, equivalent to object.__dict__."); -static PyObject* -builtin_sum(PyObject *self, PyObject *args) + +/*[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(PyModuleDef *module, PyObject *iterable, PyObject *start) +/*[clinic end generated code: output=33655b248b21d581 input=3b5b7a9d7611c73a]*/ { - PyObject *seq; - PyObject *result = NULL; + PyObject *result = start; PyObject *temp, *item, *iter; - if (!PyArg_UnpackTuple(args, "sum", 1, 2, &seq, &result)) - return NULL; - - iter = PyObject_GetIter(seq); + iter = PyObject_GetIter(iterable); if (iter == NULL) return NULL; @@ -2010,7 +2196,6 @@ builtin_sum(PyObject *self, PyObject *args) Py_DECREF(iter); return NULL; } - Py_INCREF(result); } @@ -2136,62 +2321,62 @@ builtin_sum(PyObject *self, PyObject *args) return result; } -PyDoc_STRVAR(sum_doc, -"sum(iterable[, start]) -> value\n\ -\n\ -Return the sum of an iterable of numbers (NOT strings) plus the value\n\ -of parameter 'start' (which defaults to 0). When the iterable is\n\ -empty, return start."); +/*[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(PyObject *self, PyObject *args) +builtin_isinstance_impl(PyModuleDef *module, PyObject *obj, + PyObject *class_or_tuple) +/*[clinic end generated code: output=f960b7c12dbbeda0 input=ffa743db1daf7549]*/ { - PyObject *inst; - PyObject *cls; int retval; - if (!PyArg_UnpackTuple(args, "isinstance", 2, 2, &inst, &cls)) - return NULL; - - retval = PyObject_IsInstance(inst, cls); + retval = PyObject_IsInstance(obj, class_or_tuple); if (retval < 0) return NULL; return PyBool_FromLong(retval); } -PyDoc_STRVAR(isinstance_doc, -"isinstance(object, class-or-type-or-tuple) -> bool\n\ -\n\ -Return whether an object is an instance of a class or of a subclass thereof.\n\ -With a type as second argument, return whether that is the object's type.\n\ -The form using a tuple, isinstance(x, (A, B, ...)), is a shortcut for\n\ -isinstance(x, A) or isinstance(x, B) or ... (etc.)."); +/*[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(PyObject *self, PyObject *args) +builtin_issubclass_impl(PyModuleDef *module, PyObject *cls, + PyObject *class_or_tuple) +/*[clinic end generated code: output=8b012a151940bbf2 input=af5f35e9ceaddaf6]*/ { - PyObject *derived; - PyObject *cls; int retval; - if (!PyArg_UnpackTuple(args, "issubclass", 2, 2, &derived, &cls)) - return NULL; - - retval = PyObject_IsSubclass(derived, cls); + retval = PyObject_IsSubclass(cls, class_or_tuple); if (retval < 0) return NULL; return PyBool_FromLong(retval); } -PyDoc_STRVAR(issubclass_doc, -"issubclass(C, B) -> bool\n\ -\n\ -Return whether class C is a subclass (i.e., a derived class) of class B.\n\ -When using a tuple as the second argument issubclass(X, (A, B, ...)),\n\ -is a shortcut for issubclass(X, A) or issubclass(X, B) or ... (etc.)."); - typedef struct { PyObject_HEAD @@ -2386,44 +2571,44 @@ static PyMethodDef builtin_methods[] = { {"__build_class__", (PyCFunction)builtin___build_class__, METH_VARARGS | METH_KEYWORDS, build_class_doc}, {"__import__", (PyCFunction)builtin___import__, METH_VARARGS | METH_KEYWORDS, import_doc}, - {"abs", builtin_abs, METH_O, abs_doc}, - {"all", builtin_all, METH_O, all_doc}, - {"any", builtin_any, METH_O, any_doc}, - {"ascii", builtin_ascii, METH_O, ascii_doc}, - {"bin", builtin_bin, METH_O, bin_doc}, - {"callable", builtin_callable, METH_O, callable_doc}, - {"chr", builtin_chr, METH_VARARGS, chr_doc}, - {"compile", (PyCFunction)builtin_compile, METH_VARARGS | METH_KEYWORDS, compile_doc}, - {"delattr", builtin_delattr, METH_VARARGS, delattr_doc}, + BUILTIN_ABS_METHODDEF + BUILTIN_ALL_METHODDEF + BUILTIN_ANY_METHODDEF + BUILTIN_ASCII_METHODDEF + BUILTIN_BIN_METHODDEF + BUILTIN_CALLABLE_METHODDEF + BUILTIN_CHR_METHODDEF + BUILTIN_COMPILE_METHODDEF + BUILTIN_DELATTR_METHODDEF {"dir", builtin_dir, METH_VARARGS, dir_doc}, - {"divmod", builtin_divmod, METH_VARARGS, divmod_doc}, - {"eval", builtin_eval, METH_VARARGS, eval_doc}, - {"exec", builtin_exec, METH_VARARGS, exec_doc}, - {"format", builtin_format, METH_VARARGS, format_doc}, + BUILTIN_DIVMOD_METHODDEF + BUILTIN_EVAL_METHODDEF + BUILTIN_EXEC_METHODDEF + BUILTIN_FORMAT_METHODDEF {"getattr", builtin_getattr, METH_VARARGS, getattr_doc}, - {"globals", (PyCFunction)builtin_globals, METH_NOARGS, globals_doc}, - {"hasattr", builtin_hasattr, METH_VARARGS, hasattr_doc}, - {"hash", builtin_hash, METH_O, hash_doc}, - {"hex", builtin_hex, METH_O, hex_doc}, - {"id", builtin_id, METH_O, id_doc}, - {"input", builtin_input, METH_VARARGS, input_doc}, - {"isinstance", builtin_isinstance, METH_VARARGS, isinstance_doc}, - {"issubclass", builtin_issubclass, METH_VARARGS, issubclass_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", builtin_iter, METH_VARARGS, iter_doc}, - {"len", builtin_len, METH_O, len_doc}, - {"locals", (PyCFunction)builtin_locals, METH_NOARGS, locals_doc}, + BUILTIN_LEN_METHODDEF + BUILTIN_LOCALS_METHODDEF {"max", (PyCFunction)builtin_max, METH_VARARGS | METH_KEYWORDS, max_doc}, {"min", (PyCFunction)builtin_min, METH_VARARGS | METH_KEYWORDS, min_doc}, {"next", (PyCFunction)builtin_next, METH_VARARGS, next_doc}, - {"oct", builtin_oct, METH_O, oct_doc}, - {"ord", builtin_ord, METH_O, ord_doc}, - {"pow", builtin_pow, METH_VARARGS, pow_doc}, + BUILTIN_OCT_METHODDEF + BUILTIN_ORD_METHODDEF + BUILTIN_POW_METHODDEF {"print", (PyCFunction)builtin_print, METH_VARARGS | METH_KEYWORDS, print_doc}, - {"repr", builtin_repr, METH_O, repr_doc}, + BUILTIN_REPR_METHODDEF {"round", (PyCFunction)builtin_round, METH_VARARGS | METH_KEYWORDS, round_doc}, - {"setattr", builtin_setattr, METH_VARARGS, setattr_doc}, - {"sorted", (PyCFunction)builtin_sorted, METH_VARARGS | METH_KEYWORDS, sorted_doc}, - {"sum", builtin_sum, METH_VARARGS, sum_doc}, + BUILTIN_SETATTR_METHODDEF + BUILTIN_SORTED_METHODDEF + BUILTIN_SUM_METHODDEF {"vars", builtin_vars, METH_VARARGS, vars_doc}, {NULL, NULL}, }; diff --git a/Python/ceval.c b/Python/ceval.c index 82f0651e8997..f9e8ef885995 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -12,8 +12,10 @@ #include "Python.h" #include "code.h" +#include "dictobject.h" #include "frameobject.h" #include "opcode.h" +#include "setobject.h" #include "structmember.h" #include @@ -65,9 +67,11 @@ ppc_getcounter(uint64 *v) even in 64-bit mode, we need to use "a" and "d" for the lower and upper 32-bit pieces of the result. */ -#define READ_TIMESTAMP(val) \ - __asm__ __volatile__("rdtsc" : \ - "=a" (((int*)&(val))[0]), "=d" (((int*)&(val))[1])); +#define READ_TIMESTAMP(val) do { \ + unsigned int h, l; \ + __asm__ __volatile__("rdtsc" : "=a" (l), "=d" (h)); \ + (val) = ((uint64)l) | (((uint64)h) << 32); \ + } while(0) #else @@ -123,13 +127,16 @@ static PyObject * load_args(PyObject ***, int); static int lltrace; static int prtrace(PyObject *, char *); #endif -static int call_trace(Py_tracefunc, PyObject *, PyFrameObject *, +static int call_trace(Py_tracefunc, PyObject *, + PyThreadState *, PyFrameObject *, int, PyObject *); static int call_trace_protected(Py_tracefunc, PyObject *, - PyFrameObject *, int, PyObject *); -static void call_exc_trace(Py_tracefunc, PyObject *, PyFrameObject *); + PyThreadState *, PyFrameObject *, + int, PyObject *); +static void call_exc_trace(Py_tracefunc, PyObject *, + PyThreadState *, PyFrameObject *); static int maybe_call_line_trace(Py_tracefunc, PyObject *, - PyFrameObject *, int *, int *, int *); + PyThreadState *, PyFrameObject *, int *, int *, int *); static PyObject * cmp_outcome(int, PyObject *, PyObject *); static PyObject * import_from(PyObject *, PyObject *); @@ -705,7 +712,7 @@ Py_SetRecursionLimit(int new_limit) to guarantee that _Py_CheckRecursiveCall() is regularly called. Without USE_STACKCHECK, there is no need for this. */ int -_Py_CheckRecursiveCall(char *where) +_Py_CheckRecursiveCall(const char *where) { PyThreadState *tstate = PyThreadState_GET(); @@ -730,7 +737,7 @@ _Py_CheckRecursiveCall(char *where) if (tstate->recursion_depth > recursion_limit) { --tstate->recursion_depth; tstate->overflowed = 1; - PyErr_Format(PyExc_RuntimeError, + PyErr_Format(PyExc_RecursionError, "maximum recursion depth exceeded%s", where); return -1; @@ -1136,7 +1143,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) whenever an exception is detected. */ if (call_trace_protected(tstate->c_tracefunc, tstate->c_traceobj, - f, PyTrace_CALL, Py_None)) { + tstate, f, PyTrace_CALL, Py_None)) { /* Trace function raised an error */ goto exit_eval_frame; } @@ -1146,7 +1153,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) return itself and isn't called for "line" events */ if (call_trace_protected(tstate->c_profilefunc, tstate->c_profileobj, - f, PyTrace_CALL, Py_None)) { + tstate, f, PyTrace_CALL, Py_None)) { /* Profile function raised an error */ goto exit_eval_frame; } @@ -1184,8 +1191,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) f->f_stacktop = NULL; /* remains NULL unless yield suspends frame */ f->f_executing = 1; - if (co->co_flags & CO_GENERATOR && !throwflag) { - if (f->f_exc_type != NULL && f->f_exc_type != Py_None) { + if (co->co_flags & (CO_GENERATOR | CO_COROUTINE)) { + if (!throwflag && f->f_exc_type != NULL && f->f_exc_type != Py_None) { /* We were in an except handler when we left, restore the exception state which was put aside (see YIELD_VALUE). */ @@ -1207,7 +1214,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) #ifdef Py_DEBUG /* PyEval_EvalFrameEx() must not be called with an exception set, because it may clear it (directly or indirectly) and so the - caller looses its exception */ + caller loses its exception */ assert(!PyErr_Occurred()); #endif @@ -1264,6 +1271,13 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) /* Other threads may run now */ take_gil(tstate); + + /* Check if we should make a quick exit. */ + if (_Py_Finalizing && _Py_Finalizing != tstate) { + drop_gil(tstate); + PyThread_exit_thread(); + } + if (PyThreadState_Swap(tstate) != NULL) Py_FatalError("ceval: orphan tstate"); } @@ -1293,8 +1307,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) err = maybe_call_line_trace(tstate->c_tracefunc, tstate->c_traceobj, - f, &instr_lb, &instr_ub, - &instr_prev); + tstate, f, + &instr_lb, &instr_ub, &instr_prev); /* Reload possibly changed frame fields */ JUMPTO(f->f_lasti); if (f->f_stacktop != NULL) { @@ -1492,6 +1506,18 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) DISPATCH(); } + 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(); + } + TARGET(BINARY_TRUE_DIVIDE) { PyObject *divisor = POP(); PyObject *dividend = TOP(); @@ -1682,6 +1708,18 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) DISPATCH(); } + 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(); + } + TARGET(INPLACE_TRUE_DIVIDE) { PyObject *divisor = POP(); PyObject *dividend = TOP(); @@ -1888,25 +1926,129 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) goto fast_block_end; } + TARGET(GET_AITER) { + unaryfunc getter = NULL; + PyObject *iter = NULL; + PyObject *awaitable = 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( + PyExc_TypeError, + "'async for' requires an object with " + "__aiter__ method, got %.100s", + type->tp_name); + Py_DECREF(obj); + goto error; + } + + awaitable = _PyCoro_GetAwaitableIter(iter); + if (awaitable == NULL) { + SET_TOP(NULL); + PyErr_Format( + PyExc_TypeError, + "'async for' received an invalid object " + "from __aiter__: %.100s", + Py_TYPE(iter)->tp_name); + + Py_DECREF(iter); + goto error; + } else + Py_DECREF(iter); + + SET_TOP(awaitable); + DISPATCH(); + } + + TARGET(GET_ANEXT) { + unaryfunc getter = NULL; + PyObject *next_iter = NULL; + PyObject *awaitable = NULL; + PyObject *aiter = TOP(); + PyTypeObject *type = Py_TYPE(aiter); + + 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( + 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_Format( + 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); + DISPATCH(); + } + + TARGET(GET_AWAITABLE) { + PyObject *iterable = TOP(); + PyObject *iter = _PyCoro_GetAwaitableIter(iterable); + + Py_DECREF(iterable); + + SET_TOP(iter); /* Even if it's NULL */ + + if (iter == NULL) { + goto error; + } + + DISPATCH(); + } + TARGET(YIELD_FROM) { PyObject *v = POP(); PyObject *reciever = TOP(); int err; - if (PyGen_CheckExact(reciever)) { + if (PyGen_CheckExact(reciever) || PyCoro_CheckExact(reciever)) { retval = _PyGen_Send((PyGenObject *)reciever, v); } else { _Py_IDENTIFIER(send); if (v == Py_None) retval = Py_TYPE(reciever)->tp_iternext(reciever); else - retval = _PyObject_CallMethodId(reciever, &PyId_send, "O", v); + retval = _PyObject_CallMethodIdObjArgs(reciever, &PyId_send, v, NULL); } Py_DECREF(v); if (retval == NULL) { PyObject *val; if (tstate->c_tracefunc != NULL && PyErr_ExceptionMatches(PyExc_StopIteration)) - call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, f); + call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f); err = _PyGen_FetchStopIterationValue(&val); if (err < 0) goto error; @@ -2343,6 +2485,43 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) DISPATCH(); } + TARGET_WITH_IMPL(BUILD_TUPLE_UNPACK, _build_list_unpack) + TARGET(BUILD_LIST_UNPACK) + _build_list_unpack: { + int convert_to_tuple = opcode == BUILD_TUPLE_UNPACK; + int 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) { + 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(); + } + TARGET(BUILD_SET) { PyObject *set = PySet_New(NULL); int err = 0; @@ -2362,26 +2541,127 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) DISPATCH(); } + TARGET(BUILD_SET_UNPACK) { + int 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(); + } + TARGET(BUILD_MAP) { + int 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(); } - TARGET(STORE_MAP) { - PyObject *key = TOP(); - PyObject *value = SECOND(); - PyObject *map = THIRD(); - int err; - STACKADJ(-2); - assert(PyDict_CheckExact(map)); - err = PyDict_SetItem(map, key, value); - Py_DECREF(value); - Py_DECREF(key); - if (err != 0) + TARGET_WITH_IMPL(BUILD_MAP_UNPACK_WITH_CALL, _build_map_unpack) + TARGET(BUILD_MAP_UNPACK) + _build_map_unpack: { + int with_call = opcode == BUILD_MAP_UNPACK_WITH_CALL; + int num_maps; + int function_location; + int i; + PyObject *sum = PyDict_New(); + if (sum == NULL) goto error; + if (with_call) { + num_maps = oparg & 0xff; + function_location = (oparg>>8) & 0xff; + } + else { + num_maps = oparg; + } + + for (i = num_maps; i > 0; i--) { + PyObject *arg = PEEK(i); + if (with_call) { + PyObject *intersection = _PyDictView_Intersect(sum, arg); + + if (intersection == NULL) { + if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyObject *func = ( + PEEK(function_location + num_maps)); + PyErr_Format(PyExc_TypeError, + "%.200s%.200s argument after ** " + "must be a mapping, not %.200s", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func), + arg->ob_type->tp_name); + } + Py_DECREF(sum); + goto error; + } + + if (PySet_GET_SIZE(intersection)) { + Py_ssize_t idx = 0; + PyObject *key; + PyObject *func = PEEK(function_location + num_maps); + Py_hash_t hash; + _PySet_NextEntry(intersection, &idx, &key, &hash); + if (!PyUnicode_Check(key)) { + PyErr_Format(PyExc_TypeError, + "%.200s%.200s keywords must be strings", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func)); + } else { + PyErr_Format(PyExc_TypeError, + "%.200s%.200s got multiple " + "values for keyword argument '%U'", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func), + key); + } + Py_DECREF(intersection); + Py_DECREF(sum); + goto error; + } + Py_DECREF(intersection); + } + + if (PyDict_Update(sum, arg) < 0) { + if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Format(PyExc_TypeError, + "'%.200s' object is not a mapping", + arg->ob_type->tp_name); + } + Py_DECREF(sum); + goto error; + } + } + + while (num_maps--) + Py_DECREF(POP()); + PUSH(sum); DISPATCH(); } @@ -2643,6 +2923,34 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) DISPATCH(); } + 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(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; + } + DISPATCH(); + } + PREDICTED_WITH_ARG(FOR_ITER); TARGET(FOR_ITER) { /* before: [iter]; after: [iter, iter()] *or* [] */ @@ -2658,7 +2966,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) if (!PyErr_ExceptionMatches(PyExc_StopIteration)) goto error; else if (tstate->c_tracefunc != NULL) - call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, f); + call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, f); PyErr_Clear(); } /* iterator ended normally */ @@ -2695,6 +3003,39 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) DISPATCH(); } + TARGET(BEFORE_ASYNC_WITH) { + _Py_IDENTIFIER(__aexit__); + _Py_IDENTIFIER(__aenter__); + + PyObject *mgr = TOP(); + PyObject *exit = special_lookup(mgr, &PyId___aexit__), + *enter; + PyObject *res; + if (exit == NULL) + goto error; + SET_TOP(exit); + enter = special_lookup(mgr, &PyId___aenter__); + Py_DECREF(mgr); + if (enter == NULL) + goto error; + res = PyObject_CallFunctionObjArgs(enter, NULL); + Py_DECREF(enter); + if (res == NULL) + goto error; + PUSH(res); + DISPATCH(); + } + + 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(); + } + TARGET(SETUP_WITH) { _Py_IDENTIFIER(__exit__); _Py_IDENTIFIER(__enter__); @@ -2721,7 +3062,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) DISPATCH(); } - TARGET(WITH_CLEANUP) { + TARGET(WITH_CLEANUP_START) { /* At the top of the stack are 1-6 values indicating how/why we entered the finally clause: - TOP = None @@ -2749,7 +3090,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) PyObject *exit_func; PyObject *exc = TOP(), *val = Py_None, *tb = Py_None, *res; - int err; if (exc == Py_None) { (void)POP(); exit_func = TOP(); @@ -2799,11 +3139,26 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) if (res == NULL) goto error; + Py_INCREF(exc); /* Duplicating the exception on the stack */ + PUSH(exc); + PUSH(res); + PREDICT(WITH_CLEANUP_FINISH); + DISPATCH(); + } + + PREDICTED(WITH_CLEANUP_FINISH); + TARGET(WITH_CLEANUP_FINISH) { + 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; @@ -3014,6 +3369,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) goto dispatch_opcode; } + #if USE_COMPUTED_GOTOS _unknown_opcode: #endif @@ -3054,7 +3410,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) PyTraceBack_Here(f); if (tstate->c_tracefunc != NULL) - call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, f); + call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, + tstate, f); fast_block_end: assert(why != WHY_NOT); @@ -3155,11 +3512,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) if (why != WHY_RETURN) retval = NULL; - assert((retval != NULL && !PyErr_Occurred()) - || (retval == NULL && PyErr_Occurred())); + assert((retval != NULL) ^ (PyErr_Occurred() != NULL)); fast_yield: - if (co->co_flags & CO_GENERATOR && (why == WHY_YIELD || why == WHY_RETURN)) { + if (co->co_flags & (CO_GENERATOR | CO_COROUTINE)) { + /* The purpose of this block is to put aside the generator's exception state and restore that of the calling frame. If the current exception state is from the caller, we clear the exception values @@ -3182,30 +3539,29 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) if (tstate->use_tracing) { if (tstate->c_tracefunc) { if (why == WHY_RETURN || why == WHY_YIELD) { - if (call_trace(tstate->c_tracefunc, - tstate->c_traceobj, f, + if (call_trace(tstate->c_tracefunc, tstate->c_traceobj, + tstate, f, PyTrace_RETURN, retval)) { - Py_XDECREF(retval); - retval = NULL; + Py_CLEAR(retval); why = WHY_EXCEPTION; } } else if (why == WHY_EXCEPTION) { - call_trace_protected(tstate->c_tracefunc, - tstate->c_traceobj, f, + call_trace_protected(tstate->c_tracefunc, tstate->c_traceobj, + tstate, f, PyTrace_RETURN, NULL); } } if (tstate->c_profilefunc) { if (why == WHY_EXCEPTION) call_trace_protected(tstate->c_profilefunc, - tstate->c_profileobj, f, + tstate->c_profileobj, + tstate, f, PyTrace_RETURN, NULL); - else if (call_trace(tstate->c_profilefunc, - tstate->c_profileobj, f, + else if (call_trace(tstate->c_profilefunc, tstate->c_profileobj, + tstate, f, PyTrace_RETURN, retval)) { - Py_XDECREF(retval); - retval = NULL; + Py_CLEAR(retval); /* why = WHY_EXCEPTION; */ } } @@ -3217,7 +3573,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) f->f_executing = 0; tstate->frame = f->f_back; - return retval; + return _Py_CheckFunctionResult(NULL, retval, "PyEval_EvalFrameEx"); } static void @@ -3374,10 +3730,11 @@ too_many_positional(PyCodeObject *co, int given, int defcount, PyObject **fastlo PyEval_EvalFrame() and PyEval_EvalCodeEx() you will need to adjust the test in the if statements in Misc/gdbinit (pystack and pystackv). */ -PyObject * -PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, +static PyObject * +_PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals, PyObject **args, int argcount, PyObject **kws, int kwcount, - PyObject **defs, int defcount, PyObject *kwdefs, PyObject *closure) + PyObject **defs, int defcount, PyObject *kwdefs, PyObject *closure, + PyObject *name, PyObject *qualname) { PyCodeObject* co = (PyCodeObject*)_co; PyFrameObject *f; @@ -3560,17 +3917,46 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o; } - if (co->co_flags & CO_GENERATOR) { + if (co->co_flags & (CO_GENERATOR | CO_COROUTINE)) { + PyObject *gen; + PyObject *coro_wrapper = tstate->coroutine_wrapper; + int is_coro = co->co_flags & CO_COROUTINE; + + if (is_coro && tstate->in_coroutine_wrapper) { + assert(coro_wrapper != NULL); + PyErr_Format(PyExc_RuntimeError, + "coroutine wrapper %.200R attempted " + "to recursively wrap %.200R", + coro_wrapper, + co); + goto fail; + } + /* Don't need to keep the reference to f_back, it will be set * when the generator is resumed. */ - Py_XDECREF(f->f_back); - f->f_back = NULL; + Py_CLEAR(f->f_back); PCALL(PCALL_GENERATOR); /* Create a new generator that owns the ready to run frame * and return that as the value. */ - return PyGen_New(f); + if (is_coro) { + gen = PyCoro_New(f, name, qualname); + } else { + gen = PyGen_NewWithQualName(f, name, qualname); + } + if (gen == NULL) + return NULL; + + if (is_coro && coro_wrapper != NULL) { + PyObject *wrapped; + tstate->in_coroutine_wrapper = 1; + wrapped = PyObject_CallFunction(coro_wrapper, "N", gen); + tstate->in_coroutine_wrapper = 0; + return wrapped; + } + + return gen; } retval = PyEval_EvalFrameEx(f,0); @@ -3589,6 +3975,16 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, return retval; } +PyObject * +PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, + PyObject **args, int argcount, PyObject **kws, int kwcount, + PyObject **defs, int defcount, PyObject *kwdefs, PyObject *closure) +{ + return _PyEval_EvalCodeWithName(_co, globals, locals, + args, argcount, kws, kwcount, + defs, defcount, kwdefs, closure, + NULL, NULL); +} static PyObject * special_lookup(PyObject *o, _Py_Identifier *id) @@ -3779,9 +4175,17 @@ unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp) if (w == NULL) { /* Iterator done, via error or exhaustion. */ if (!PyErr_Occurred()) { - PyErr_Format(PyExc_ValueError, - "need more than %d value%s to unpack", - i, i == 1 ? "" : "s"); + if (argcntafter == -1) { + PyErr_Format(PyExc_ValueError, + "not enough values to unpack (expected %d, got %d)", + argcnt, i); + } + else { + PyErr_Format(PyExc_ValueError, + "not enough values to unpack " + "(expected at least %d, got %d)", + argcnt + argcntafter, i); + } } goto Error; } @@ -3798,8 +4202,9 @@ unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp) return 1; } Py_DECREF(w); - PyErr_Format(PyExc_ValueError, "too many values to unpack " - "(expected %d)", argcnt); + PyErr_Format(PyExc_ValueError, + "too many values to unpack (expected %d)", + argcnt); goto Error; } @@ -3811,8 +4216,9 @@ unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp) ll = PyList_GET_SIZE(l); if (ll < argcntafter) { - PyErr_Format(PyExc_ValueError, "need more than %zd values to unpack", - argcnt + ll); + PyErr_Format(PyExc_ValueError, + "not enough values to unpack (expected at least %d, got %zd)", + argcnt + argcntafter, argcnt + ll); goto Error; } @@ -3846,7 +4252,8 @@ prtrace(PyObject *v, char *str) #endif static void -call_exc_trace(Py_tracefunc func, PyObject *self, PyFrameObject *f) +call_exc_trace(Py_tracefunc func, PyObject *self, + PyThreadState *tstate, PyFrameObject *f) { PyObject *type, *value, *traceback, *orig_traceback, *arg; int err; @@ -3862,7 +4269,7 @@ call_exc_trace(Py_tracefunc func, PyObject *self, PyFrameObject *f) PyErr_Restore(type, value, orig_traceback); return; } - err = call_trace(func, self, f, PyTrace_EXCEPTION, arg); + err = call_trace(func, self, tstate, f, PyTrace_EXCEPTION, arg); Py_DECREF(arg); if (err == 0) PyErr_Restore(type, value, orig_traceback); @@ -3874,13 +4281,14 @@ call_exc_trace(Py_tracefunc func, PyObject *self, PyFrameObject *f) } static int -call_trace_protected(Py_tracefunc func, PyObject *obj, PyFrameObject *frame, +call_trace_protected(Py_tracefunc func, PyObject *obj, + PyThreadState *tstate, PyFrameObject *frame, int what, PyObject *arg) { PyObject *type, *value, *traceback; int err; PyErr_Fetch(&type, &value, &traceback); - err = call_trace(func, obj, frame, what, arg); + err = call_trace(func, obj, tstate, frame, what, arg); if (err == 0) { PyErr_Restore(type, value, traceback); @@ -3895,10 +4303,10 @@ call_trace_protected(Py_tracefunc func, PyObject *obj, PyFrameObject *frame, } static int -call_trace(Py_tracefunc func, PyObject *obj, PyFrameObject *frame, +call_trace(Py_tracefunc func, PyObject *obj, + PyThreadState *tstate, PyFrameObject *frame, int what, PyObject *arg) { - PyThreadState *tstate = frame->f_tstate; int result; if (tstate->tracing) return 0; @@ -3914,8 +4322,7 @@ call_trace(Py_tracefunc func, PyObject *obj, PyFrameObject *frame, PyObject * _PyEval_CallTracing(PyObject *func, PyObject *args) { - PyFrameObject *frame = PyEval_GetFrame(); - PyThreadState *tstate = frame->f_tstate; + PyThreadState *tstate = PyThreadState_GET(); int save_tracing = tstate->tracing; int save_use_tracing = tstate->use_tracing; PyObject *result; @@ -3932,8 +4339,8 @@ _PyEval_CallTracing(PyObject *func, PyObject *args) /* See Objects/lnotab_notes.txt for a description of how tracing works. */ static int maybe_call_line_trace(Py_tracefunc func, PyObject *obj, - PyFrameObject *frame, int *instr_lb, int *instr_ub, - int *instr_prev) + PyThreadState *tstate, PyFrameObject *frame, + int *instr_lb, int *instr_ub, int *instr_prev) { int result = 0; int line = frame->f_lineno; @@ -3953,7 +4360,7 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj, number and call the trace function. */ if (frame->f_lasti == *instr_lb || frame->f_lasti < *instr_prev) { frame->f_lineno = line; - result = call_trace(func, obj, frame, PyTrace_LINE, Py_None); + result = call_trace(func, obj, tstate, frame, PyTrace_LINE, Py_None); } *instr_prev = frame->f_lasti; return result; @@ -3995,6 +4402,24 @@ PyEval_SetTrace(Py_tracefunc func, PyObject *arg) || (tstate->c_profilefunc != NULL)); } +void +_PyEval_SetCoroutineWrapper(PyObject *wrapper) +{ + PyThreadState *tstate = PyThreadState_GET(); + + Py_CLEAR(tstate->coroutine_wrapper); + + Py_XINCREF(wrapper); + tstate->coroutine_wrapper = wrapper; +} + +PyObject * +_PyEval_GetCoroutineWrapper(void) +{ + PyThreadState *tstate = PyThreadState_GET(); + return tstate->coroutine_wrapper; +} + PyObject * PyEval_GetBuiltins(void) { @@ -4073,8 +4498,8 @@ PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw) #ifdef Py_DEBUG /* PyEval_CallObjectWithKeywords() must not be called with an exception - set, because it may clear it (directly or indirectly) - and so the caller looses its 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 @@ -4101,8 +4526,6 @@ PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw) result = PyObject_Call(func, arg, kw); Py_DECREF(arg); - assert((result != NULL && !PyErr_Occurred()) - || (result == NULL && PyErr_Occurred())); return result; } @@ -4149,10 +4572,9 @@ err_args(PyObject *func, int flags, int nargs) #define C_TRACE(x, call) \ if (tstate->use_tracing && tstate->c_profilefunc) { \ - if (call_trace(tstate->c_profilefunc, \ - tstate->c_profileobj, \ - tstate->frame, PyTrace_C_CALL, \ - func)) { \ + if (call_trace(tstate->c_profilefunc, tstate->c_profileobj, \ + tstate, tstate->frame, \ + PyTrace_C_CALL, func)) { \ x = NULL; \ } \ else { \ @@ -4161,14 +4583,14 @@ if (tstate->use_tracing && tstate->c_profilefunc) { \ if (x == NULL) { \ call_trace_protected(tstate->c_profilefunc, \ tstate->c_profileobj, \ - tstate->frame, PyTrace_C_EXCEPTION, \ - func); \ + tstate, tstate->frame, \ + PyTrace_C_EXCEPTION, func); \ /* XXX should pass (type, value, tb) */ \ } else { \ if (call_trace(tstate->c_profilefunc, \ tstate->c_profileobj, \ - tstate->frame, PyTrace_C_RETURN, \ - func)) { \ + tstate, tstate->frame, \ + PyTrace_C_RETURN, func)) { \ Py_DECREF(x); \ x = NULL; \ } \ @@ -4206,11 +4628,15 @@ call_function(PyObject ***pp_stack, int oparg PyObject *self = PyCFunction_GET_SELF(func); if (flags & METH_NOARGS && na == 0) { C_TRACE(x, (*meth)(self,NULL)); + + x = _Py_CheckFunctionResult(func, x, NULL); } else if (flags & METH_O && na == 1) { PyObject *arg = EXT_POP(*pp_stack); C_TRACE(x, (*meth)(self,arg)); Py_DECREF(arg); + + x = _Py_CheckFunctionResult(func, x, NULL); } else { err_args(func, flags, na); @@ -4230,7 +4656,8 @@ call_function(PyObject ***pp_stack, int oparg x = NULL; } } - } else { + } + else { if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) { /* optimize access to bound methods */ PyObject *self = PyMethod_GET_SELF(func); @@ -4252,9 +4679,9 @@ call_function(PyObject ***pp_stack, int oparg x = do_call(func, pp_stack, na, nk); READ_TIMESTAMP(*pintr1); Py_DECREF(func); + + assert((x != NULL) ^ (PyErr_Occurred() != NULL)); } - assert((x != NULL && !PyErr_Occurred()) - || (x == NULL && PyErr_Occurred())); /* Clear the stack of the function object. Also removes the arguments in case they weren't consumed already @@ -4266,8 +4693,7 @@ call_function(PyObject ***pp_stack, int oparg PCALL(PCALL_POP); } - assert((x != NULL && !PyErr_Occurred()) - || (x == NULL && PyErr_Occurred())); + assert((x != NULL) ^ (PyErr_Occurred() != NULL)); return x; } @@ -4287,6 +4713,8 @@ fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk) PyObject *globals = PyFunction_GET_GLOBALS(func); PyObject *argdefs = PyFunction_GET_DEFAULTS(func); PyObject *kwdefs = PyFunction_GET_KW_DEFAULTS(func); + PyObject *name = ((PyFunctionObject *)func) -> func_name; + PyObject *qualname = ((PyFunctionObject *)func) -> func_qualname; PyObject **d = NULL; int nd = 0; @@ -4329,10 +4757,11 @@ fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk) d = &PyTuple_GET_ITEM(argdefs, 0); nd = Py_SIZE(argdefs); } - return PyEval_EvalCodeEx((PyObject*)co, globals, - (PyObject *)NULL, (*pp_stack)-n, na, - (*pp_stack)-2*nk, nk, d, nd, kwdefs, - PyFunction_GET_CLOSURE(func)); + return _PyEval_EvalCodeWithName((PyObject*)co, globals, + (PyObject *)NULL, (*pp_stack)-n, na, + (*pp_stack)-2*nk, nk, d, nd, kwdefs, + PyFunction_GET_CLOSURE(func), + name, qualname); } static PyObject * @@ -4496,6 +4925,12 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk) kwdict = d; } } + if (nk > 0) { + kwdict = update_keyword_args(kwdict, nk, pp_stack, func); + if (kwdict == NULL) + goto ext_call_fail; + } + if (flags & CALL_FLAG_VAR) { stararg = EXT_POP(*pp_stack); if (!PyTuple_Check(stararg)) { @@ -4517,11 +4952,6 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk) } nstar = PyTuple_GET_SIZE(stararg); } - if (nk > 0) { - kwdict = update_keyword_args(kwdict, nk, pp_stack, func); - if (kwdict == NULL) - goto ext_call_fail; - } callargs = update_star_args(na, nstar, stararg, pp_stack); if (callargs == NULL) goto ext_call_fail; @@ -4551,12 +4981,10 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk) Py_XDECREF(callargs); Py_XDECREF(kwdict); Py_XDECREF(stararg); - assert((result != NULL && !PyErr_Occurred()) - || (result == NULL && PyErr_Occurred())); return result; } -/* Extract a slice index from a PyInt or PyLong or an object with the +/* 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_MAX-1 to -PY_SSIZE_T_MAX-1. @@ -4646,12 +5074,35 @@ static PyObject * import_from(PyObject *v, PyObject *name) { PyObject *x; + _Py_IDENTIFIER(__name__); + PyObject *fullmodname, *pkgname; x = PyObject_GetAttr(v, name); - if (x == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Format(PyExc_ImportError, "cannot import name %R", name); + if (x != NULL || !PyErr_ExceptionMatches(PyExc_AttributeError)) + 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. */ + PyErr_Clear(); + pkgname = _PyObject_GetAttrId(v, &PyId___name__); + if (pkgname == NULL) { + goto error; + } + fullmodname = PyUnicode_FromFormat("%U.%U", pkgname, name); + Py_DECREF(pkgname); + if (fullmodname == NULL) { + return NULL; + } + x = PyDict_GetItem(PyImport_GetModuleDict(), fullmodname); + Py_DECREF(fullmodname); + if (x == NULL) { + goto error; } + Py_INCREF(x); return x; + error: + PyErr_Format(PyExc_ImportError, "cannot import name %R", name); + return NULL; } static int diff --git a/Python/ceval_gil.h b/Python/ceval_gil.h index 2702d5cbddb2..aafcbc2bc9c5 100644 --- a/Python/ceval_gil.h +++ b/Python/ceval_gil.h @@ -31,7 +31,7 @@ static unsigned long gil_interval = DEFAULT_INTERVAL; 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 @@ -41,7 +41,7 @@ static unsigned long gil_interval = DEFAULT_INTERVAL; 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()`. @@ -51,7 +51,7 @@ static unsigned long gil_interval = DEFAULT_INTERVAL; the value of gil_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" @@ -186,12 +186,12 @@ static void drop_gil(PyThreadState *tstate) _Py_atomic_store_relaxed(&gil_locked, 0); COND_SIGNAL(gil_cond); MUTEX_UNLOCK(gil_mutex); - + #ifdef FORCE_SWITCHING if (_Py_atomic_load_relaxed(&gil_drop_request) && tstate != NULL) { MUTEX_LOCK(switch_mutex); /* Not switched yet => wait */ - if (_Py_atomic_load_relaxed(&gil_last_holder) == tstate) { + if ((PyThreadState*)_Py_atomic_load_relaxed(&gil_last_holder) == tstate) { RESET_GIL_DROP_REQUEST(); /* NOTE: if COND_WAIT does not atomically start waiting when releasing the mutex, another thread can run through, take @@ -215,7 +215,7 @@ static void take_gil(PyThreadState *tstate) if (!_Py_atomic_load_relaxed(&gil_locked)) goto _ready; - + while (_Py_atomic_load_relaxed(&gil_locked)) { int timed_out = 0; unsigned long saved_switchnum; @@ -239,7 +239,7 @@ static void take_gil(PyThreadState *tstate) _Py_atomic_store_relaxed(&gil_locked, 1); _Py_ANNOTATE_RWLOCK_ACQUIRED(&gil_locked, /*is_write=*/1); - if (tstate != _Py_atomic_load_relaxed(&gil_last_holder)) { + if (tstate != (PyThreadState*)_Py_atomic_load_relaxed(&gil_last_holder)) { _Py_atomic_store_relaxed(&gil_last_holder, tstate); ++gil_switch_number; } @@ -254,7 +254,7 @@ static void take_gil(PyThreadState *tstate) if (tstate->async_exc != NULL) { _PyEval_SignalAsyncExc(); } - + MUTEX_UNLOCK(gil_mutex); errno = err; } diff --git a/Python/clinic/bltinmodule.c.h b/Python/clinic/bltinmodule.c.h new file mode 100644 index 000000000000..7369148b23a9 --- /dev/null +++ b/Python/clinic/bltinmodule.c.h @@ -0,0 +1,663 @@ +/*[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"); + +#define BUILTIN_FORMAT_METHODDEF \ + {"format", (PyCFunction)builtin_format, METH_VARARGS, builtin_format__doc__}, + +static PyObject * +builtin_format_impl(PyModuleDef *module, PyObject *value, + PyObject *format_spec); + +static PyObject * +builtin_format(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *value; + PyObject *format_spec = NULL; + + if (!PyArg_ParseTuple(args, "O|U:format", + &value, &format_spec)) + goto exit; + 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(PyModuleDef *module, int i); + +static PyObject * +builtin_chr(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int i; + + if (!PyArg_Parse(arg, "i:chr", &i)) + 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)\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)builtin_compile, METH_VARARGS|METH_KEYWORDS, builtin_compile__doc__}, + +static PyObject * +builtin_compile_impl(PyModuleDef *module, PyObject *source, + PyObject *filename, const char *mode, int flags, + int dont_inherit, int optimize); + +static PyObject * +builtin_compile(PyModuleDef *module, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static char *_keywords[] = {"source", "filename", "mode", "flags", "dont_inherit", "optimize", NULL}; + PyObject *source; + PyObject *filename; + const char *mode; + int flags = 0; + int dont_inherit = 0; + int optimize = -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO&s|iii:compile", _keywords, + &source, PyUnicode_FSDecoder, &filename, &mode, &flags, &dont_inherit, &optimize)) + goto exit; + return_value = builtin_compile_impl(module, source, filename, mode, flags, dont_inherit, optimize); + +exit: + return return_value; +} + +PyDoc_STRVAR(builtin_divmod__doc__, +"divmod($module, x, y, /)\n" +"--\n" +"\n" +"Return the tuple ((x-x%y)/y, x%y). Invariant: div*y + mod == x."); + +#define BUILTIN_DIVMOD_METHODDEF \ + {"divmod", (PyCFunction)builtin_divmod, METH_VARARGS, builtin_divmod__doc__}, + +static PyObject * +builtin_divmod_impl(PyModuleDef *module, PyObject *x, PyObject *y); + +static PyObject * +builtin_divmod(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *x; + PyObject *y; + + if (!PyArg_UnpackTuple(args, "divmod", + 2, 2, + &x, &y)) + goto exit; + 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)builtin_eval, METH_VARARGS, builtin_eval__doc__}, + +static PyObject * +builtin_eval_impl(PyModuleDef *module, PyObject *source, PyObject *globals, + PyObject *locals); + +static PyObject * +builtin_eval(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *source; + PyObject *globals = Py_None; + PyObject *locals = Py_None; + + if (!PyArg_UnpackTuple(args, "eval", + 1, 3, + &source, &globals, &locals)) + goto exit; + 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)builtin_exec, METH_VARARGS, builtin_exec__doc__}, + +static PyObject * +builtin_exec_impl(PyModuleDef *module, PyObject *source, PyObject *globals, + PyObject *locals); + +static PyObject * +builtin_exec(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *source; + PyObject *globals = Py_None; + PyObject *locals = Py_None; + + if (!PyArg_UnpackTuple(args, "exec", + 1, 3, + &source, &globals, &locals)) + goto exit; + 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(PyModuleDef *module); + +static PyObject * +builtin_globals(PyModuleDef *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)builtin_hasattr, METH_VARARGS, builtin_hasattr__doc__}, + +static PyObject * +builtin_hasattr_impl(PyModuleDef *module, PyObject *obj, PyObject *name); + +static PyObject * +builtin_hasattr(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *obj; + PyObject *name; + + if (!PyArg_UnpackTuple(args, "hasattr", + 2, 2, + &obj, &name)) + goto exit; + 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)builtin_setattr, METH_VARARGS, builtin_setattr__doc__}, + +static PyObject * +builtin_setattr_impl(PyModuleDef *module, PyObject *obj, PyObject *name, + PyObject *value); + +static PyObject * +builtin_setattr(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *obj; + PyObject *name; + PyObject *value; + + if (!PyArg_UnpackTuple(args, "setattr", + 3, 3, + &obj, &name, &value)) + goto exit; + 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)builtin_delattr, METH_VARARGS, builtin_delattr__doc__}, + +static PyObject * +builtin_delattr_impl(PyModuleDef *module, PyObject *obj, PyObject *name); + +static PyObject * +builtin_delattr(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *obj; + PyObject *name; + + if (!PyArg_UnpackTuple(args, "delattr", + 2, 2, + &obj, &name)) + goto exit; + 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(PyModuleDef *module); + +static PyObject * +builtin_locals(PyModuleDef *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, x, y, z=None, /)\n" +"--\n" +"\n" +"Equivalent to x**y (with two arguments) or x**y % z (with three 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)builtin_pow, METH_VARARGS, builtin_pow__doc__}, + +static PyObject * +builtin_pow_impl(PyModuleDef *module, PyObject *x, PyObject *y, PyObject *z); + +static PyObject * +builtin_pow(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *x; + PyObject *y; + PyObject *z = Py_None; + + if (!PyArg_UnpackTuple(args, "pow", + 2, 3, + &x, &y, &z)) + goto exit; + return_value = builtin_pow_impl(module, x, y, z); + +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)builtin_input, METH_VARARGS, builtin_input__doc__}, + +static PyObject * +builtin_input_impl(PyModuleDef *module, PyObject *prompt); + +static PyObject * +builtin_input(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *prompt = NULL; + + if (!PyArg_UnpackTuple(args, "input", + 0, 1, + &prompt)) + goto exit; + 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_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)builtin_sum, METH_VARARGS, builtin_sum__doc__}, + +static PyObject * +builtin_sum_impl(PyModuleDef *module, PyObject *iterable, PyObject *start); + +static PyObject * +builtin_sum(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *iterable; + PyObject *start = NULL; + + if (!PyArg_UnpackTuple(args, "sum", + 1, 2, + &iterable, &start)) + goto exit; + 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)builtin_isinstance, METH_VARARGS, builtin_isinstance__doc__}, + +static PyObject * +builtin_isinstance_impl(PyModuleDef *module, PyObject *obj, + PyObject *class_or_tuple); + +static PyObject * +builtin_isinstance(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *obj; + PyObject *class_or_tuple; + + if (!PyArg_UnpackTuple(args, "isinstance", + 2, 2, + &obj, &class_or_tuple)) + goto exit; + 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)builtin_issubclass, METH_VARARGS, builtin_issubclass__doc__}, + +static PyObject * +builtin_issubclass_impl(PyModuleDef *module, PyObject *cls, + PyObject *class_or_tuple); + +static PyObject * +builtin_issubclass(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *cls; + PyObject *class_or_tuple; + + if (!PyArg_UnpackTuple(args, "issubclass", + 2, 2, + &cls, &class_or_tuple)) + goto exit; + return_value = builtin_issubclass_impl(module, cls, class_or_tuple); + +exit: + return return_value; +} +/*[clinic end generated code: output=bec3399c0aee98d7 input=a9049054013a1b77]*/ diff --git a/Python/clinic/import.c.h b/Python/clinic/import.c.h new file mode 100644 index 000000000000..247766519e1a --- /dev/null +++ b/Python/clinic/import.c.h @@ -0,0 +1,355 @@ +/*[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(PyModuleDef *module); + +static PyObject * +_imp_lock_held(PyModuleDef *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(PyModuleDef *module); + +static PyObject * +_imp_acquire_lock(PyModuleDef *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(PyModuleDef *module); + +static PyObject * +_imp_release_lock(PyModuleDef *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)_imp__fix_co_filename, METH_VARARGS, _imp__fix_co_filename__doc__}, + +static PyObject * +_imp__fix_co_filename_impl(PyModuleDef *module, PyCodeObject *code, + PyObject *path); + +static PyObject * +_imp__fix_co_filename(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyCodeObject *code; + PyObject *path; + + if (!PyArg_ParseTuple(args, "O!U:_fix_co_filename", + &PyCode_Type, &code, &path)) + goto exit; + 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(PyModuleDef *module); + +static PyObject * +_imp_extension_suffixes(PyModuleDef *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(PyModuleDef *module, PyObject *name); + +static PyObject * +_imp_init_frozen(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *name; + + if (!PyArg_Parse(arg, "U:init_frozen", &name)) + goto exit; + 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(PyModuleDef *module, PyObject *name); + +static PyObject * +_imp_get_frozen_object(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *name; + + if (!PyArg_Parse(arg, "U:get_frozen_object", &name)) + goto exit; + 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(PyModuleDef *module, PyObject *name); + +static PyObject * +_imp_is_frozen_package(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *name; + + if (!PyArg_Parse(arg, "U:is_frozen_package", &name)) + goto exit; + 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(PyModuleDef *module, PyObject *name); + +static PyObject * +_imp_is_builtin(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *name; + + if (!PyArg_Parse(arg, "U:is_builtin", &name)) + goto exit; + 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(PyModuleDef *module, PyObject *name); + +static PyObject * +_imp_is_frozen(PyModuleDef *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyObject *name; + + if (!PyArg_Parse(arg, "U:is_frozen", &name)) + goto exit; + 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=None, /)\n" +"--\n" +"\n" +"Create an extension module."); + +#define _IMP_CREATE_DYNAMIC_METHODDEF \ + {"create_dynamic", (PyCFunction)_imp_create_dynamic, METH_VARARGS, _imp_create_dynamic__doc__}, + +static PyObject * +_imp_create_dynamic_impl(PyModuleDef *module, PyObject *spec, PyObject *file); + +static PyObject * +_imp_create_dynamic(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *spec; + PyObject *file = NULL; + + if (!PyArg_UnpackTuple(args, "create_dynamic", + 1, 2, + &spec, &file)) + goto exit; + 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(PyModuleDef *module, PyObject *mod); + +static PyObject * +_imp_exec_dynamic(PyModuleDef *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(PyModuleDef *module, PyObject *mod); + +static PyObject * +_imp_exec_builtin(PyModuleDef *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; +} + +#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=32324a5e46cdfc4b input=a9049054013a1b77]*/ diff --git a/Python/codecs.c b/Python/codecs.c index 5ff41b57df29..d90bf7374d49 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -9,6 +9,7 @@ Copyright (c) Corporation for National Research Initiatives. ------------------------------------------------------------------------ */ #include "Python.h" +#include "ucnhash.h" #include const char *Py_hexdigits = "0123456789abcdef"; @@ -185,6 +186,32 @@ PyObject *_PyCodec_Lookup(const char *encoding) return NULL; } +int _PyCodec_Forget(const char *encoding) +{ + PyInterpreterState *interp; + PyObject *v; + int result; + + interp = PyThreadState_GET()->interp; + 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) @@ -243,20 +270,15 @@ PyObject *codec_getitem(const char *encoding, int index) return v; } -/* Helper function to create an incremental codec. */ - +/* Helper functions to create an incremental codec. */ static -PyObject *codec_getincrementalcodec(const char *encoding, - const char *errors, - const char *attrname) +PyObject *codec_makeincrementalcodec(PyObject *codec_info, + const char *errors, + const char *attrname) { - PyObject *codecs, *ret, *inccodec; + PyObject *ret, *inccodec; - codecs = _PyCodec_Lookup(encoding); - if (codecs == NULL) - return NULL; - inccodec = PyObject_GetAttrString(codecs, attrname); - Py_DECREF(codecs); + inccodec = PyObject_GetAttrString(codec_info, attrname); if (inccodec == NULL) return NULL; if (errors) @@ -267,6 +289,21 @@ PyObject *codec_getincrementalcodec(const char *encoding, 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 @@ -290,6 +327,24 @@ PyObject *codec_getstreamcodec(const char *encoding, 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. @@ -467,15 +522,12 @@ PyObject *PyCodec_Decode(PyObject *object, } /* Text encoding/decoding API */ -static -PyObject *codec_getitem_checked(const char *encoding, - const char *operation_name, - int index) +PyObject * _PyCodec_LookupTextEncoding(const char *encoding, + const char *alternate_command) { _Py_IDENTIFIER(_is_text_encoding); PyObject *codec; PyObject *attr; - PyObject *v; int is_text_codec; codec = _PyCodec_Lookup(encoding); @@ -498,31 +550,49 @@ PyObject *codec_getitem_checked(const char *encoding, } else { is_text_codec = PyObject_IsTrue(attr); Py_DECREF(attr); - if (!is_text_codec) { + if (is_text_codec <= 0) { Py_DECREF(codec); - PyErr_Format(PyExc_LookupError, - "'%.400s' is not a text encoding; " - "use codecs.%s() to handle arbitrary codecs", - encoding, operation_name); + 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_DECREF(codec); Py_INCREF(v); + Py_DECREF(codec); return v; } static PyObject * _PyCodec_TextEncoder(const char *encoding) { - return codec_getitem_checked(encoding, "encode", 0); + return codec_getitem_checked(encoding, "codecs.encode()", 0); } static PyObject * _PyCodec_TextDecoder(const char *encoding) { - return codec_getitem_checked(encoding, "decode", 1); + return codec_getitem_checked(encoding, "codecs.decode()", 1); } PyObject *_PyCodec_EncodeText(PyObject *object, @@ -593,18 +663,9 @@ PyObject *PyCodec_LookupError(const char *name) static void wrong_exception_type(PyObject *exc) { - _Py_IDENTIFIER(__class__); - _Py_IDENTIFIER(__name__); - PyObject *type = _PyObject_GetAttrId(exc, &PyId___class__); - if (type != NULL) { - PyObject *name = _PyObject_GetAttrId(type, &PyId___name__); - Py_DECREF(type); - if (name != NULL) { - PyErr_Format(PyExc_TypeError, - "don't know how to handle %S in error callback", name); - Py_DECREF(name); - } - } + PyErr_Format(PyExc_TypeError, + "don't know how to handle %.200s in error callback", + exc->ob_type->tp_name); } PyObject *PyCodec_StrictErrors(PyObject *exc) @@ -620,15 +681,16 @@ PyObject *PyCodec_StrictErrors(PyObject *exc) PyObject *PyCodec_IgnoreErrors(PyObject *exc) { Py_ssize_t end; - if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { + + if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) { if (PyUnicodeEncodeError_GetEnd(exc, &end)) return NULL; } - else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { + else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) { if (PyUnicodeDecodeError_GetEnd(exc, &end)) return NULL; } - else if (PyObject_IsInstance(exc, PyExc_UnicodeTranslateError)) { + else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeTranslateError)) { if (PyUnicodeTranslateError_GetEnd(exc, &end)) return NULL; } @@ -644,7 +706,7 @@ PyObject *PyCodec_ReplaceErrors(PyObject *exc) { Py_ssize_t start, end, i, len; - if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { + if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) { PyObject *res; int kind; void *data; @@ -663,14 +725,14 @@ PyObject *PyCodec_ReplaceErrors(PyObject *exc) assert(_PyUnicode_CheckConsistency(res, 1)); return Py_BuildValue("(Nn)", res, end); } - else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { + 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_IsInstance(exc, PyExc_UnicodeTranslateError)) { + else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeTranslateError)) { PyObject *res; int kind; void *data; @@ -697,7 +759,7 @@ PyObject *PyCodec_ReplaceErrors(PyObject *exc) PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc) { - if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { + if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) { PyObject *restuple; PyObject *object; Py_ssize_t i; @@ -705,7 +767,7 @@ PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc) Py_ssize_t end; PyObject *res; unsigned char *outp; - int ressize; + Py_ssize_t ressize; Py_UCS4 ch; if (PyUnicodeEncodeError_GetStart(exc, &start)) return NULL; @@ -713,6 +775,8 @@ PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc) 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); @@ -793,7 +857,119 @@ PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc) PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc) { - if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { + 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)) { + unsigned char *p; + if (PyUnicodeDecodeError_GetStart(exc, &start)) + return NULL; + if (PyUnicodeDecodeError_GetEnd(exc, &end)) + return NULL; + if (!(object = PyUnicodeDecodeError_GetObject(exc))) + return NULL; + if (!(p = (unsigned char*)PyBytes_AsString(object))) { + Py_DECREF(object); + return NULL; + } + 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; @@ -801,26 +977,42 @@ PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc) Py_ssize_t end; PyObject *res; unsigned char *outp; - int ressize; + 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 (c >= 0x10000) { - ressize += 1+1+8; + 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) { - ressize += 1+1+4; + replsize = 1+1+4; } else - ressize += 1+1+2; + 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; @@ -828,6 +1020,14 @@ PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc) 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]; @@ -848,6 +1048,7 @@ PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc) *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); @@ -859,6 +1060,7 @@ PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc) } } +#define ENC_UNKNOWN -1 #define ENC_UTF8 0 #define ENC_UTF16BE 1 #define ENC_UTF16LE 2 @@ -874,7 +1076,11 @@ get_standard_encoding(const char *encoding, int *bytelength) encoding += 3; if (*encoding == '-' || *encoding == '_' ) encoding++; - if (encoding[0] == '1' && encoding[1] == '6') { + 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') { @@ -913,9 +1119,11 @@ get_standard_encoding(const char *encoding, int *bytelength) } } } - /* utf-8 */ - *bytelength = 3; - return ENC_UTF8; + else if (strcmp(encoding, "CP_UTF8") == 0) { + *bytelength = 3; + return ENC_UTF8; + } + return ENC_UNKNOWN; } /* This handler is declared static until someone demonstrates @@ -933,7 +1141,8 @@ PyCodec_SurrogatePassErrors(PyObject *exc) Py_ssize_t start; Py_ssize_t end; PyObject *res; - if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { + + if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) { unsigned char *outp; if (PyUnicodeEncodeError_GetStart(exc, &start)) return NULL; @@ -952,7 +1161,15 @@ PyCodec_SurrogatePassErrors(PyObject *exc) } 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); @@ -1002,7 +1219,7 @@ PyCodec_SurrogatePassErrors(PyObject *exc) Py_DECREF(object); return restuple; } - else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { + else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) { unsigned char *p; Py_UCS4 ch = 0; if (PyUnicodeDecodeError_GetStart(exc, &start)) @@ -1026,6 +1243,12 @@ PyCodec_SurrogatePassErrors(PyObject *exc) } 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. */ @@ -1081,7 +1304,8 @@ PyCodec_SurrogateEscapeErrors(PyObject *exc) Py_ssize_t start; Py_ssize_t end; PyObject *res; - if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) { + + if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) { char *outp; if (PyUnicodeEncodeError_GetStart(exc, &start)) return NULL; @@ -1112,7 +1336,7 @@ PyCodec_SurrogateEscapeErrors(PyObject *exc) Py_DECREF(object); return restuple; } - else if (PyObject_IsInstance(exc, PyExc_UnicodeDecodeError)) { + else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) { PyObject *str; unsigned char *p; Py_UCS2 ch[4]; /* decode up to 4 bad bytes. */ @@ -1181,6 +1405,11 @@ 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); @@ -1246,8 +1475,19 @@ static int _PyCodecRegistry_Init(void) 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 " - "backslashed escape sequence.") + "\\N{...} escape sequence.") } }, { diff --git a/Python/compile.c b/Python/compile.c index 0fc91864fff0..3a49ecec281b 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -30,8 +30,6 @@ #include "symtable.h" #include "opcode.h" -int Py_OptimizeFlag = 0; - #define DEFAULT_BLOCK_SIZE 16 #define DEFAULT_BLOCKS 8 #define DEFAULT_CODE_SIZE 128 @@ -94,6 +92,7 @@ enum { COMPILER_SCOPE_MODULE, COMPILER_SCOPE_CLASS, COMPILER_SCOPE_FUNCTION, + COMPILER_SCOPE_ASYNC_FUNCTION, COMPILER_SCOPE_LAMBDA, COMPILER_SCOPE_COMPREHENSION, }; @@ -195,18 +194,18 @@ static int inplace_binop(struct compiler *, operator_ty); static int expr_constant(struct compiler *, 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, Py_ssize_t n, asdl_seq *args, - asdl_seq *keywords, - expr_ty starargs, - expr_ty kwargs); + asdl_seq *keywords); static int compiler_try_except(struct compiler *, stmt_ty); static int compiler_set_qualname(struct compiler *); static PyCodeObject *assemble(struct compiler *, int addNone); static PyObject *__doc__; -#define COMPILER_CAPSULE_NAME_COMPILER_UNIT "compile.c compiler unit" +#define CAPSULE_NAME "compile.c compiler unit" PyObject * _Py_Mangle(PyObject *privateobj, PyObject *ident) @@ -608,7 +607,7 @@ compiler_enter_scope(struct compiler *c, identifier name, /* Push the old compiler_unit on the stack. */ if (c->u) { - PyObject *capsule = PyCapsule_New(c->u, COMPILER_CAPSULE_NAME_COMPILER_UNIT, NULL); + 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); @@ -644,7 +643,7 @@ compiler_exit_scope(struct compiler *c) 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, COMPILER_CAPSULE_NAME_COMPILER_UNIT); + 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) @@ -674,10 +673,12 @@ compiler_set_qualname(struct compiler *c) PyObject *mangled, *capsule; capsule = PyList_GET_ITEM(c->c_stack, stack_size - 1); - parent = (struct compiler_unit *)PyCapsule_GetPointer(capsule, COMPILER_CAPSULE_NAME_COMPILER_UNIT); + 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_CLASS) { + 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) @@ -691,6 +692,7 @@ compiler_set_qualname(struct compiler *c) 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) @@ -729,6 +731,7 @@ compiler_set_qualname(struct compiler *c) return 1; } + /* Allocate a new block and return a pointer to it. Returns NULL on error. */ @@ -881,6 +884,7 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg) case BINARY_POWER: case BINARY_MULTIPLY: + case BINARY_MATRIX_MULTIPLY: case BINARY_MODULO: case BINARY_ADD: case BINARY_SUBTRACT: @@ -895,12 +899,11 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg) case INPLACE_ADD: case INPLACE_SUBTRACT: case INPLACE_MULTIPLY: + case INPLACE_MATRIX_MULTIPLY: case INPLACE_MODULO: return -1; case STORE_SUBSCR: return -3; - case STORE_MAP: - return -2; case DELETE_SUBSCR: return -2; @@ -929,7 +932,9 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg) return 0; case SETUP_WITH: return 7; - case WITH_CLEANUP: + case WITH_CLEANUP_START: + return 1; + case WITH_CLEANUP_FINISH: return -1; /* XXX Sometimes more */ case RETURN_VALUE: return -1; @@ -973,8 +978,15 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg) case BUILD_LIST: case BUILD_SET: return 1-oparg; + case BUILD_LIST_UNPACK: + case BUILD_TUPLE_UNPACK: + case BUILD_SET_UNPACK: + case BUILD_MAP_UNPACK: + return 1 - oparg; + case BUILD_MAP_UNPACK_WITH_CALL: + return 1 - (oparg & 0xFF); case BUILD_MAP: - return 1; + return 1 - 2*oparg; case LOAD_ATTR: return 0; case COMPARE_OP: @@ -1043,6 +1055,18 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg) return -1; case DELETE_DEREF: return 0; + case GET_AWAITABLE: + return 0; + case SETUP_ASYNC_WITH: + return 6; + case BEFORE_ASYNC_WITH: + return 1; + case GET_AITER: + return 0; + case GET_ANEXT: + return 1; + case GET_YIELD_FROM_ITER: + return 0; default: return PY_INVALID_STACK_EFFECT; } @@ -1123,8 +1147,10 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o) v = PyDict_GetItem(dict, t); if (!v) { - if (PyErr_Occurred()) + if (PyErr_Occurred()) { + Py_DECREF(t); return -1; + } arg = PyDict_Size(dict); v = PyLong_FromSsize_t(arg); if (!v) { @@ -1412,12 +1438,12 @@ get_ref_type(struct compiler *c, PyObject *name) PyOS_snprintf(buf, sizeof(buf), "unknown scope for %.100s in %.100s(%s)\n" "symbols: %s\nlocals: %s\nglobals: %s", - PyBytes_AS_STRING(name), - PyBytes_AS_STRING(c->u->u_name), - PyObject_REPR(c->u->u_ste->ste_id), - PyObject_REPR(c->u->u_ste->ste_symbols), - PyObject_REPR(c->u->u_varnames), - PyObject_REPR(c->u->u_names) + 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); } @@ -1474,11 +1500,11 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t args, PyO fprintf(stderr, "lookup %s in %s %d %d\n" "freevars of %s: %s\n", - PyObject_REPR(name), - PyBytes_AS_STRING(c->u->u_name), + PyUnicode_AsUTF8(PyObject_Repr(name)), + PyUnicode_AsUTF8(c->u->u_name), reftype, arg, - _PyUnicode_AsString(co->co_name), - PyObject_REPR(co->co_freevars)); + PyUnicode_AsUTF8(co->co_name), + PyUnicode_AsUTF8(PyObject_Repr(co->co_freevars))); Py_FatalError("compiler_make_closure()"); } ADDOP_I(c, LOAD_CLOSURE, arg); @@ -1532,29 +1558,35 @@ compiler_visit_argannotation(struct compiler *c, identifier id, expr_ty annotation, PyObject *names) { if (annotation) { + PyObject *mangled; VISIT(c, expr, annotation); - if (PyList_Append(names, id)) - return -1; + 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 0; + return 1; } static int compiler_visit_argannotations(struct compiler *c, asdl_seq* args, PyObject *names) { - int i, error; + int i; for (i = 0; i < asdl_seq_LEN(args); i++) { arg_ty arg = (arg_ty)asdl_seq_GET(args, i); - error = compiler_visit_argannotation( + if (!compiler_visit_argannotation( c, arg->arg, arg->annotation, - names); - if (error) - return error; + names)) + return 0; } - return 0; + return 1; } static int @@ -1574,16 +1606,16 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args, if (!names) return -1; - if (compiler_visit_argannotations(c, args->args, names)) + if (!compiler_visit_argannotations(c, args->args, names)) goto error; if (args->vararg && args->vararg->annotation && - compiler_visit_argannotation(c, args->vararg->arg, + !compiler_visit_argannotation(c, args->vararg->arg, args->vararg->annotation, names)) goto error; - if (compiler_visit_argannotations(c, args->kwonlyargs, names)) + if (!compiler_visit_argannotations(c, args->kwonlyargs, names)) goto error; if (args->kwarg && args->kwarg->annotation && - compiler_visit_argannotation(c, args->kwarg->arg, + !compiler_visit_argannotation(c, args->kwarg->arg, args->kwarg->annotation, names)) goto error; @@ -1592,7 +1624,7 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args, if (!return_str) goto error; } - if (compiler_visit_argannotation(c, return_str, returns, names)) { + if (!compiler_visit_argannotation(c, return_str, returns, names)) { goto error; } @@ -1630,19 +1662,43 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args, } static int -compiler_function(struct compiler *c, stmt_ty s) +compiler_function(struct compiler *c, stmt_ty s, int is_async) { PyCodeObject *co; PyObject *qualname, *first_const = Py_None; - arguments_ty args = s->v.FunctionDef.args; - expr_ty returns = s->v.FunctionDef.returns; - asdl_seq* decos = s->v.FunctionDef.decorator_list; + arguments_ty args; + expr_ty returns; + identifier name; + asdl_seq* decos; + asdl_seq *body; stmt_ty st; Py_ssize_t i, n, arglength; int docstring, kw_default_count = 0; int num_annotations; + int scope_type; + + + 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); - 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; @@ -1660,12 +1716,12 @@ compiler_function(struct compiler *c, stmt_ty s) return 0; assert((num_annotations & 0xFFFF) == num_annotations); - if (!compiler_enter_scope(c, s->v.FunctionDef.name, - COMPILER_SCOPE_FUNCTION, (void *)s, + if (!compiler_enter_scope(c, name, + scope_type, (void *)s, s->lineno)) return 0; - st = (stmt_ty)asdl_seq_GET(s->v.FunctionDef.body, 0); + st = (stmt_ty)asdl_seq_GET(body, 0); docstring = compiler_isdocstring(st); if (docstring && c->c_optimize < 2) first_const = st->v.Expr.value->v.Str.s; @@ -1676,10 +1732,10 @@ compiler_function(struct compiler *c, stmt_ty s) c->u->u_argcount = asdl_seq_LEN(args->args); c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs); - n = asdl_seq_LEN(s->v.FunctionDef.body); + n = asdl_seq_LEN(body); /* if there was a docstring, we need to skip the first statement */ for (i = docstring; i < n; i++) { - st = (stmt_ty)asdl_seq_GET(s->v.FunctionDef.body, i); + st = (stmt_ty)asdl_seq_GET(body, i); VISIT_IN_SCOPE(c, stmt, st); } co = assemble(c, 1); @@ -1695,6 +1751,8 @@ compiler_function(struct compiler *c, stmt_ty s) arglength = asdl_seq_LEN(args->defaults); arglength |= kw_default_count << 8; arglength |= num_annotations << 16; + if (is_async) + co->co_flags |= CO_COROUTINE; compiler_make_closure(c, co, arglength, qualname); Py_DECREF(qualname); Py_DECREF(co); @@ -1704,7 +1762,7 @@ compiler_function(struct compiler *c, stmt_ty s) ADDOP_I(c, CALL_FUNCTION, 1); } - return compiler_nameop(c, s->v.FunctionDef.name, Store); + return compiler_nameop(c, name, Store); } static int @@ -1814,9 +1872,7 @@ compiler_class(struct compiler *c, stmt_ty s) /* 5. generate the rest of the code for the call */ if (!compiler_call_helper(c, 2, s->v.ClassDef.bases, - s->v.ClassDef.keywords, - s->v.ClassDef.starargs, - s->v.ClassDef.kwargs)) + s->v.ClassDef.keywords)) return 0; /* 6. apply decorators */ @@ -1890,12 +1946,12 @@ compiler_lambda(struct compiler *c, expr_ty e) 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) { - ADDOP_IN_SCOPE(c, POP_TOP); + co = assemble(c, 0); } else { ADDOP_IN_SCOPE(c, RETURN_VALUE); + co = assemble(c, 1); } - co = assemble(c, 1); qualname = c->u->u_qualname; Py_INCREF(qualname); compiler_exit_scope(c); @@ -1931,7 +1987,7 @@ compiler_if(struct compiler *c, stmt_ty s) } else if (constant == 1) { VISIT_SEQ(c, stmt, s->v.If.body); } else { - if (s->v.If.orelse) { + if (asdl_seq_LEN(s->v.If.orelse)) { next = compiler_new_block(c); if (next == NULL) return 0; @@ -1941,8 +1997,8 @@ compiler_if(struct compiler *c, stmt_ty s) VISIT(c, expr, s->v.If.test); ADDOP_JABS(c, POP_JUMP_IF_FALSE, next); VISIT_SEQ(c, stmt, s->v.If.body); - ADDOP_JREL(c, JUMP_FORWARD, end); - if (s->v.If.orelse) { + 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); } @@ -1979,6 +2035,92 @@ compiler_for(struct compiler *c, stmt_ty s) return 1; } + +static int +compiler_async_for(struct compiler *c, stmt_ty s) +{ + static PyObject *stopiter_error = NULL; + basicblock *try, *except, *end, *after_try, *try_cleanup, + *after_loop, *after_loop_else; + + if (stopiter_error == NULL) { + stopiter_error = PyUnicode_InternFromString("StopAsyncIteration"); + if (stopiter_error == NULL) + return 0; + } + + try = compiler_new_block(c); + except = compiler_new_block(c); + end = compiler_new_block(c); + after_try = compiler_new_block(c); + try_cleanup = compiler_new_block(c); + after_loop = compiler_new_block(c); + after_loop_else = compiler_new_block(c); + + if (try == NULL || except == NULL || end == NULL + || after_try == NULL || try_cleanup == NULL) + return 0; + + ADDOP_JREL(c, SETUP_LOOP, after_loop); + if (!compiler_push_fblock(c, LOOP, try)) + return 0; + + VISIT(c, expr, s->v.AsyncFor.iter); + ADDOP(c, GET_AITER); + ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP(c, YIELD_FROM); + + compiler_use_next_block(c, try); + + + ADDOP_JREL(c, SETUP_EXCEPT, except); + if (!compiler_push_fblock(c, EXCEPT, try)) + return 0; + + ADDOP(c, GET_ANEXT); + ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP(c, YIELD_FROM); + VISIT(c, expr, s->v.AsyncFor.target); + ADDOP(c, POP_BLOCK); + compiler_pop_fblock(c, EXCEPT, try); + ADDOP_JREL(c, JUMP_FORWARD, after_try); + + + compiler_use_next_block(c, except); + ADDOP(c, DUP_TOP); + ADDOP_O(c, LOAD_GLOBAL, stopiter_error, names); + ADDOP_I(c, COMPARE_OP, PyCmp_EXC_MATCH); + ADDOP_JABS(c, POP_JUMP_IF_FALSE, try_cleanup); + + ADDOP(c, POP_TOP); + ADDOP(c, POP_TOP); + ADDOP(c, POP_TOP); + ADDOP(c, POP_EXCEPT); /* for SETUP_EXCEPT */ + ADDOP(c, POP_BLOCK); /* for SETUP_LOOP */ + ADDOP_JABS(c, JUMP_ABSOLUTE, after_loop_else); + + + compiler_use_next_block(c, try_cleanup); + ADDOP(c, END_FINALLY); + + compiler_use_next_block(c, after_try); + VISIT_SEQ(c, stmt, s->v.AsyncFor.body); + ADDOP_JABS(c, JUMP_ABSOLUTE, try); + + ADDOP(c, POP_BLOCK); /* for SETUP_LOOP */ + compiler_pop_fblock(c, LOOP, try); + + compiler_use_next_block(c, after_loop); + ADDOP_JABS(c, JUMP_ABSOLUTE, end); + + compiler_use_next_block(c, after_loop_else); + 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) { @@ -2022,10 +2164,9 @@ compiler_while(struct compiler *c, stmt_ty s) if there is no else clause ? */ - if (constant == -1) { + if (constant == -1) compiler_use_next_block(c, anchor); - ADDOP(c, POP_BLOCK); - } + ADDOP(c, POP_BLOCK); compiler_pop_fblock(c, LOOP, loop); if (orelse != NULL) /* what if orelse is just pass? */ VISIT_SEQ(c, stmt, s->v.While.orelse); @@ -2506,7 +2647,7 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) switch (s->kind) { case FunctionDef_kind: - return compiler_function(c, s); + return compiler_function(c, s, 0); case ClassDef_kind: return compiler_class(c, s); case Return_kind: @@ -2585,7 +2726,14 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) 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; } @@ -2618,6 +2766,8 @@ binop(struct compiler *c, operator_ty op) return BINARY_SUBTRACT; case Mult: return BINARY_MULTIPLY; + case MatMult: + return BINARY_MATRIX_MULTIPLY; case Div: return BINARY_TRUE_DIVIDE; case Mod: @@ -2682,6 +2832,8 @@ inplace_binop(struct compiler *c, operator_ty op) return INPLACE_SUBTRACT; case Mult: return INPLACE_MULTIPLY; + case MatMult: + return INPLACE_MATRIX_MULTIPLY; case Div: return INPLACE_TRUE_DIVIDE; case Mod: @@ -2743,8 +2895,7 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) optype = OP_FAST; break; case GLOBAL_IMPLICIT: - if (c->u->u_ste->ste_type == FunctionBlock && - !c->u->u_ste->ste_unoptimized) + if (c->u->u_ste->ste_type == FunctionBlock) optype = OP_GLOBAL; break; case GLOBAL_EXPLICIT: @@ -2862,67 +3013,145 @@ compiler_boolop(struct compiler *c, expr_ty e) } static int -compiler_list(struct compiler *c, expr_ty e) +starunpack_helper(struct compiler *c, asdl_seq *elts, + int single_op, int inner_op, int outer_op) { - Py_ssize_t n = asdl_seq_LEN(e->v.List.elts); - if (e->v.List.ctx == Store) { - int i, seen_star = 0; - for (i = 0; i < n; i++) { - expr_ty elt = asdl_seq_GET(e->v.List.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(e->v.List.elts, i, elt->v.Starred.value); - } else if (elt->kind == Starred_kind) { - return compiler_error(c, - "two starred expressions in assignment"); + 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); } - if (!seen_star) { - ADDOP_I(c, UNPACK_SEQUENCE, n); + else if (elt->kind == Starred_kind) { + return compiler_error(c, + "two starred expressions in assignment"); } } - VISIT_SEQ(c, expr, e->v.List.elts); - if (e->v.List.ctx == Load) { - ADDOP_I(c, BUILD_LIST, n); + 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) { - Py_ssize_t n = asdl_seq_LEN(e->v.Tuple.elts); + asdl_seq *elts = e->v.Tuple.elts; if (e->v.Tuple.ctx == Store) { - int i, seen_star = 0; - for (i = 0; i < n; i++) { - expr_ty elt = asdl_seq_GET(e->v.Tuple.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(e->v.Tuple.elts, i, elt->v.Starred.value); - } else if (elt->kind == Starred_kind) { - return compiler_error(c, - "two starred expressions in assignment"); - } + 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 +compiler_dict(struct compiler *c, expr_ty e) +{ + Py_ssize_t i, n, containers, elements; + 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)) { + ADDOP_I(c, BUILD_MAP, elements); + containers++; + elements = 0; } - if (!seen_star) { - ADDOP_I(c, UNPACK_SEQUENCE, n); + if (is_unpacking) { + VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); + containers++; + } + else { + 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)); + elements++; } } - VISIT_SEQ(c, expr, e->v.Tuple.elts); - if (e->v.Tuple.ctx == Load) { - ADDOP_I(c, BUILD_TUPLE, n); + if (elements || containers == 0) { + ADDOP_I(c, BUILD_MAP, elements); + 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." */ + while (containers > 1 || is_unpacking) { + int oparg = containers < 255 ? containers : 255; + ADDOP_I(c, BUILD_MAP_UNPACK, oparg); + containers -= (oparg - 1); + is_unpacking = 0; } return 1; } @@ -2978,9 +3207,118 @@ compiler_call(struct compiler *c, expr_ty e) VISIT(c, expr, e->v.Call.func); return compiler_call_helper(c, 0, e->v.Call.args, - e->v.Call.keywords, - e->v.Call.starargs, - e->v.Call.kwargs); + e->v.Call.keywords); +} + +static int +compiler_joined_str(struct compiler *c, expr_ty e) +{ + /* Concatenate parts of a string using ''.join(parts). There are + probably better ways of doing this. + + This is used for constructs like "'x=' f'{42}'", which have to + be evaluated at compile time. */ + + static PyObject *empty_string; + static PyObject *join_string; + + if (!empty_string) { + empty_string = PyUnicode_FromString(""); + if (!empty_string) + return 0; + } + if (!join_string) { + join_string = PyUnicode_FromString("join"); + if (!join_string) + return 0; + } + + ADDOP_O(c, LOAD_CONST, empty_string, consts); + ADDOP_NAME(c, LOAD_ATTR, join_string, names); + VISIT_SEQ(c, expr, e->v.JoinedStr.values); + ADDOP_I(c, BUILD_LIST, asdl_seq_LEN(e->v.JoinedStr.values)); + ADDOP_I(c, CALL_FUNCTION, 1); + return 1; +} + +/* Note that this code uses the builtin functions format(), str(), + repr(), and ascii(). You can break this code, or make it do odd + things, by redefining those functions. */ +static int +compiler_formatted_value(struct compiler *c, expr_ty e) +{ + PyObject *conversion_name = NULL; + + static PyObject *format_string; + static PyObject *str_string; + static PyObject *repr_string; + static PyObject *ascii_string; + + if (!format_string) { + format_string = PyUnicode_InternFromString("format"); + if (!format_string) + return 0; + } + + if (!str_string) { + str_string = PyUnicode_InternFromString("str"); + if (!str_string) + return 0; + } + + if (!repr_string) { + repr_string = PyUnicode_InternFromString("repr"); + if (!repr_string) + return 0; + } + if (!ascii_string) { + ascii_string = PyUnicode_InternFromString("ascii"); + if (!ascii_string) + return 0; + } + + ADDOP_NAME(c, LOAD_GLOBAL, format_string, names); + + /* If needed, convert via str, repr, or ascii. */ + if (e->v.FormattedValue.conversion != -1) { + switch (e->v.FormattedValue.conversion) { + case 's': + conversion_name = str_string; + break; + case 'r': + conversion_name = repr_string; + break; + case 'a': + conversion_name = ascii_string; + break; + default: + PyErr_SetString(PyExc_SystemError, + "Unrecognized conversion character"); + return 0; + } + ADDOP_NAME(c, LOAD_GLOBAL, conversion_name, names); + } + + /* Evaluate the value. */ + VISIT(c, expr, e->v.FormattedValue.value); + + /* If needed, convert via str, repr, or ascii. */ + if (conversion_name) { + /* Call the function we previously pushed. */ + ADDOP_I(c, CALL_FUNCTION, 1); + } + + /* If we have a format spec, use format(value, format_spec). Otherwise, + use the single argument form. */ + if (e->v.FormattedValue.format_spec) { + VISIT(c, expr, e->v.FormattedValue.format_spec); + ADDOP_I(c, CALL_FUNCTION, 2); + } else { + /* No format spec specified, call format(value). */ + ADDOP_I(c, CALL_FUNCTION, 1); + } + + return 1; } /* shared code between compiler_call and compiler_class */ @@ -2988,26 +3326,102 @@ static int compiler_call_helper(struct compiler *c, Py_ssize_t n, /* Args already pushed */ asdl_seq *args, - asdl_seq *keywords, - expr_ty starargs, - expr_ty kwargs) + asdl_seq *keywords) { int code = 0; - - n += asdl_seq_LEN(args); - VISIT_SEQ(c, expr, args); - if (keywords) { - VISIT_SEQ(c, keyword, keywords); - n |= asdl_seq_LEN(keywords) << 8; + Py_ssize_t nelts, i, nseen, nkw; + + /* the number of tuples and dictionaries on the stack */ + Py_ssize_t nsubargs = 0, nsubkwargs = 0; + + nkw = 0; + nseen = 0; /* the number of positional arguments on the stack */ + nelts = asdl_seq_LEN(args); + 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 if (nsubargs) { + /* We've seen star-args already, so we + count towards items-to-pack-into-tuple. */ + VISIT(c, expr, elt); + nseen++; + } + else { + /* Positional arguments before star-arguments + are left on the stack. */ + VISIT(c, expr, elt); + n++; + } } - if (starargs) { - VISIT(c, expr, starargs); + if (nseen) { + /* Pack up any trailing positional arguments. */ + ADDOP_I(c, BUILD_TUPLE, nseen); + nsubargs++; + } + if (nsubargs) { code |= 1; + 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_LIST_UNPACK, nsubargs); + } } - if (kwargs) { - VISIT(c, expr, kwargs); + + /* Same dance again for keyword arguments */ + nseen = 0; /* the number of keyword arguments on the stack following */ + nelts = asdl_seq_LEN(keywords); + for (i = 0; i < nelts; i++) { + keyword_ty kw = asdl_seq_GET(keywords, i); + if (kw->arg == NULL) { + /* A keyword argument unpacking. */ + if (nseen) { + ADDOP_I(c, BUILD_MAP, nseen); + nseen = 0; + nsubkwargs++; + } + VISIT(c, expr, kw->value); + nsubkwargs++; + } + else if (nsubkwargs) { + /* A keyword argument and we already have a dict. */ + ADDOP_O(c, LOAD_CONST, kw->arg, consts); + VISIT(c, expr, kw->value); + nseen++; + } + else { + /* keyword argument */ + VISIT(c, keyword, kw) + nkw++; + } + } + if (nseen) { + /* Pack up any trailing keyword arguments. */ + ADDOP_I(c, BUILD_MAP, nseen); + nsubkwargs++; + } + if (nsubkwargs) { code |= 2; + if (nsubkwargs > 1) { + /* Pack it all up */ + int function_pos = n + (code & 1) + nkw + 1; + ADDOP_I(c, BUILD_MAP_UNPACK_WITH_CALL, nsubkwargs | (function_pos << 8)); + } } + assert(n < 1<<8); + assert(nkw < 1<<24); + n |= nkw << 8; + switch (code) { case 0: ADDOP_I(c, CALL_FUNCTION, n); @@ -3132,8 +3546,9 @@ compiler_comprehension_generator(struct compiler *c, } static int -compiler_comprehension(struct compiler *c, expr_ty e, int type, identifier name, - asdl_seq *generators, expr_ty elt, expr_ty val) +compiler_comprehension(struct compiler *c, expr_ty e, int type, + identifier name, asdl_seq *generators, expr_ty elt, + expr_ty val) { PyCodeObject *co = NULL; expr_ty outermost_iter; @@ -3306,6 +3721,102 @@ expr_constant(struct compiler *c, expr_ty e) } } + +/* + 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); + + 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_O(c, LOAD_CONST, Py_None, consts); + 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, FINALLY_TRY, block)) { + 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); + compiler_pop_fblock(c, FINALLY_TRY, block); + + ADDOP_O(c, LOAD_CONST, Py_None, consts); + compiler_use_next_block(c, finally); + if (!compiler_push_fblock(c, FINALLY_END, finally)) + 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_O(c, LOAD_CONST, Py_None, consts); + 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. @@ -3324,9 +3835,9 @@ expr_constant(struct compiler *c, expr_ty e) BLOCK finally: if an exception was raised: - exc = copy of (exception, instance, traceback) + exc = copy of (exception, instance, traceback) else: - exc = (None, None, None) + exc = (None, None, None) exit(*exc) */ static int @@ -3379,7 +3890,8 @@ compiler_with(struct compiler *c, stmt_ty s, int pos) /* Finally block starts; context.__exit__ is on the stack under the exception or return information. Just issue our magic opcode. */ - ADDOP(c, WITH_CLEANUP); + ADDOP(c, WITH_CLEANUP_START); + ADDOP(c, WITH_CLEANUP_FINISH); /* Finally block ends. */ ADDOP(c, END_FINALLY); @@ -3390,8 +3902,6 @@ compiler_with(struct compiler *c, stmt_ty s, int pos) static int compiler_visit_expr(struct compiler *c, expr_ty e) { - Py_ssize_t i, n; - /* If expr e has a different line number than the last expr/stmt, set a new line number for the next instruction. */ @@ -3418,23 +3928,9 @@ compiler_visit_expr(struct compiler *c, expr_ty e) case IfExp_kind: return compiler_ifexp(c, e); case Dict_kind: - n = asdl_seq_LEN(e->v.Dict.values); - /* BUILD_MAP parameter is only used to preallocate the dictionary, - it doesn't need to be exact */ - ADDOP_I(c, BUILD_MAP, (n>0xFFFF ? 0xFFFF : n)); - for (i = 0; i < n; i++) { - VISIT(c, expr, - (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); - VISIT(c, expr, - (expr_ty)asdl_seq_GET(e->v.Dict.keys, i)); - ADDOP(c, STORE_MAP); - } - break; + return compiler_dict(c, e); case Set_kind: - n = asdl_seq_LEN(e->v.Set.elts); - VISIT_SEQ(c, expr, e->v.Set.elts); - ADDOP_I(c, BUILD_SET, n); - break; + return compiler_set(c, e); case GeneratorExp_kind: return compiler_genexp(c, e); case ListComp_kind: @@ -3446,6 +3942,8 @@ compiler_visit_expr(struct compiler *c, expr_ty e) case Yield_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' inside async function"); if (e->v.Yield.value) { VISIT(c, expr, e->v.Yield.value); } @@ -3457,8 +3955,28 @@ compiler_visit_expr(struct compiler *c, expr_ty e) 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_ITER); + ADDOP(c, GET_YIELD_FROM_ITER); + ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP(c, YIELD_FROM); + break; + case Await_kind: + if (c->u->u_ste->ste_type != FunctionBlock) + return compiler_error(c, "'await' outside function"); + + if (c->u->u_scope_type == COMPILER_SCOPE_COMPREHENSION) + return compiler_error( + c, "'await' expressions in comprehensions are not supported"); + + if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION) + return compiler_error(c, "'await' outside async function"); + + VISIT(c, expr, e->v.Await.value); + ADDOP(c, GET_AWAITABLE); ADDOP_O(c, LOAD_CONST, Py_None, consts); ADDOP(c, YIELD_FROM); break; @@ -3472,6 +3990,10 @@ compiler_visit_expr(struct compiler *c, expr_ty e) case Str_kind: ADDOP_O(c, LOAD_CONST, e->v.Str.s, consts); break; + case JoinedStr_kind: + return compiler_joined_str(c, e); + case FormattedValue_kind: + return compiler_formatted_value(c, e); case Bytes_kind: ADDOP_O(c, LOAD_CONST, e->v.Bytes.s, consts); break; @@ -3545,7 +4067,7 @@ compiler_visit_expr(struct compiler *c, expr_ty e) "starred assignment target must be in a list or tuple"); default: return compiler_error(c, - "can use starred expression only as assignment target"); + "can't use starred expression here"); } break; case Name_kind: @@ -3849,12 +4371,16 @@ stackdepth_walk(struct compiler *c, basicblock *b, int depth, int maxdepth) target_depth = depth; if (instr->i_opcode == FOR_ITER) { target_depth = depth-2; - } else if (instr->i_opcode == SETUP_FINALLY || - instr->i_opcode == SETUP_EXCEPT) { + } + else if (instr->i_opcode == SETUP_FINALLY || + instr->i_opcode == SETUP_EXCEPT) { target_depth = depth+3; if (target_depth > maxdepth) maxdepth = target_depth; } + else if (instr->i_opcode == JUMP_IF_TRUE_OR_POP || + instr->i_opcode == JUMP_IF_FALSE_OR_POP) + depth = depth - 1; maxdepth = stackdepth_walk(c, instr->i_target, target_depth, maxdepth); if (instr->i_opcode == JUMP_ABSOLUTE || @@ -3899,7 +4425,7 @@ assemble_init(struct assembler *a, int nblocks, int firstlineno) a->a_lnotab = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE); if (!a->a_lnotab) return 0; - if (nblocks > PY_SIZE_MAX / sizeof(basicblock *)) { + if ((size_t)nblocks > PY_SIZE_MAX / sizeof(basicblock *)) { PyErr_NoMemory(); return 0; } @@ -4171,9 +4697,7 @@ compute_code_flags(struct compiler *c) int flags = 0; Py_ssize_t n; if (ste->ste_type == FunctionBlock) { - flags |= CO_NEWLOCALS; - if (!ste->ste_unoptimized) - flags |= CO_OPTIMIZED; + flags |= CO_NEWLOCALS | CO_OPTIMIZED; if (ste->ste_nested) flags |= CO_NESTED; if (ste->ste_generator) @@ -4376,4 +4900,3 @@ PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags, { return PyAST_CompileEx(mod, filename, flags, -1, arena); } - diff --git a/Python/condvar.h b/Python/condvar.h index e022dc793883..bb5b1b661f1c 100644 --- a/Python/condvar.h +++ b/Python/condvar.h @@ -1,4 +1,4 @@ -/* +/* * Portable condition variable support for windows and pthreads. * Everything is inline, this header can be included where needed. * @@ -60,7 +60,7 @@ #include #define PyCOND_ADD_MICROSECONDS(tv, interval) \ -do { \ +do { /* TODO: add overflow and truncation checks */ \ tv.tv_usec += (long) interval; \ tv.tv_sec += tv.tv_usec / 1000000; \ tv.tv_usec %= 1000000; \ @@ -89,7 +89,7 @@ do { \ /* return 0 for success, 1 on timeout, -1 on error */ Py_LOCAL_INLINE(int) -PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, long us) +PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, PY_LONG_LONG us) { int r; struct timespec ts; @@ -105,7 +105,7 @@ PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, long us) return 1; else if (r) return -1; - else + else return 0; } @@ -255,7 +255,7 @@ _PyCOND_WAIT_MS(PyCOND_T *cv, PyMUTEX_T *cs, DWORD ms) * a new thread comes along, it will pass right throuhgh, having * adjusted it to (waiting == 0 && sem.count == 0). */ - + if (wait == WAIT_FAILED) return -1; /* return 0 on success, 1 on timeout */ @@ -270,9 +270,9 @@ PyCOND_WAIT(PyCOND_T *cv, PyMUTEX_T *cs) } Py_LOCAL_INLINE(int) -PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, long us) +PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, PY_LONG_LONG us) { - return _PyCOND_WAIT_MS(cv, cs, us/1000); + return _PyCOND_WAIT_MS(cv, cs, (DWORD)(us/1000)); } Py_LOCAL_INLINE(int) @@ -363,9 +363,9 @@ PyCOND_WAIT(PyCOND_T *cv, PyMUTEX_T *cs) * 2 to indicate that we don't know. */ Py_LOCAL_INLINE(int) -PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, long us) +PyCOND_TIMEDWAIT(PyCOND_T *cv, PyMUTEX_T *cs, PY_LONG_LONG us) { - return SleepConditionVariableSRW(cv, cs, us/1000, 0) ? 2 : -1; + return SleepConditionVariableSRW(cv, cs, (DWORD)(us/1000), 0) ? 2 : -1; } Py_LOCAL_INLINE(int) diff --git a/Python/dtoa.c b/Python/dtoa.c index 8996a7210c0b..3da546ed0709 100644 --- a/Python/dtoa.c +++ b/Python/dtoa.c @@ -373,7 +373,7 @@ Balloc(int k) x = 1 << k; len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) /sizeof(double); - if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) { + if (k <= Kmax && pmem_next - private_mem + len <= (Py_ssize_t)PRIVATE_mem) { rv = (Bigint*)pmem_next; pmem_next += len; } @@ -1087,7 +1087,7 @@ sd2b(U *d, int scale, int *e) 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); diff --git a/Python/dynload_aix.c b/Python/dynload_aix.c index 5ac30ed5f13a..b3ff8e288c1a 100644 --- a/Python/dynload_aix.c +++ b/Python/dynload_aix.c @@ -154,8 +154,9 @@ aix_loaderror(const char *pathname) } -dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname, - const char *pathname, FILE *fp) +dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix, + const char *shortname, + const char *pathname, FILE *fp) { dl_funcptr p; diff --git a/Python/dynload_dl.c b/Python/dynload_dl.c index 5836cb3b2920..2bec645fbd7a 100644 --- a/Python/dynload_dl.c +++ b/Python/dynload_dl.c @@ -12,11 +12,12 @@ extern char *Py_GetProgramName(void); const char *_PyImport_DynLoadFiletab[] = {".o", NULL}; -dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname, - const char *pathname, FILE *fp) +dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix, + const char *shortname, + const char *pathname, FILE *fp) { char funcname[258]; - PyOS_snprintf(funcname, sizeof(funcname), "PyInit_%.200s", shortname); + PyOS_snprintf(funcname, sizeof(funcname), "%.20s_%.200s", prefix, shortname); return dl_loadmod(Py_GetProgramName(), pathname, funcname); } diff --git a/Python/dynload_hpux.c b/Python/dynload_hpux.c index c9554148cc5f..4967afc39c12 100644 --- a/Python/dynload_hpux.c +++ b/Python/dynload_hpux.c @@ -8,15 +8,16 @@ #include "importdl.h" #if defined(__hp9000s300) -#define FUNCNAME_PATTERN "_PyInit_%.200s" +#define FUNCNAME_PATTERN "_%.20s_%.200s" #else -#define FUNCNAME_PATTERN "PyInit_%.200s" +#define FUNCNAME_PATTERN "%.20s_%.200s" #endif const char *_PyImport_DynLoadFiletab[] = {SHLIB_EXT, NULL}; -dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname, - const char *pathname, FILE *fp) +dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix, + const char *shortname, + const char *pathname, FILE *fp) { dl_funcptr p; shl_t lib; @@ -50,7 +51,8 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname, Py_DECREF(pathname_ob); return NULL; } - PyOS_snprintf(funcname, sizeof(funcname), FUNCNAME_PATTERN, shortname); + PyOS_snprintf(funcname, sizeof(funcname), FUNCNAME_PATTERN, + prefix, shortname); if (Py_VerboseFlag) printf("shl_findsym %s\n", funcname); if (shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p) == -1) { diff --git a/Python/dynload_next.c b/Python/dynload_next.c index 85c95b41bb55..83a8b2bb3198 100644 --- a/Python/dynload_next.c +++ b/Python/dynload_next.c @@ -27,8 +27,9 @@ const char *_PyImport_DynLoadFiletab[] = {".so", NULL}; #define LINKOPTIONS NSLINKMODULE_OPTION_BINDNOW| \ NSLINKMODULE_OPTION_RETURN_ON_ERROR|NSLINKMODULE_OPTION_PRIVATE #endif -dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname, - const char *pathname, FILE *fp) +dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix, + const char *shortname, + const char *pathname, FILE *fp) { dl_funcptr p = NULL; char funcname[258]; @@ -39,7 +40,7 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname, const char *errString; char errBuf[512]; - PyOS_snprintf(funcname, sizeof(funcname), "_PyInit_%.200s", shortname); + PyOS_snprintf(funcname, sizeof(funcname), "_%.20s_%.200s", prefix, shortname); #ifdef USE_DYLD_GLOBAL_NAMESPACE if (NSIsSymbolNameDefined(funcname)) { diff --git a/Python/dynload_shlib.c b/Python/dynload_shlib.c index 888fbfcc68c6..7f8f134d60b3 100644 --- a/Python/dynload_shlib.c +++ b/Python/dynload_shlib.c @@ -36,32 +36,25 @@ const char *_PyImport_DynLoadFiletab[] = { #ifdef __CYGWIN__ ".dll", #else /* !__CYGWIN__ */ -#ifdef __VMS - ".exe", - ".EXE", -#else /* !__VMS */ "." SOABI ".so", ".abi" PYTHON_ABI_STRING ".so", ".so", -#endif /* __VMS */ #endif /* __CYGWIN__ */ NULL, }; static struct { dev_t dev; -#ifdef __VMS - ino_t ino[3]; -#else ino_t ino; -#endif void *handle; } handles[128]; static int nhandles = 0; -dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname, - const char *pathname, FILE *fp) +dl_funcptr +_PyImport_FindSharedFuncptr(const char *prefix, + const char *shortname, + const char *pathname, FILE *fp) { dl_funcptr p; void *handle; @@ -76,48 +69,29 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname, } PyOS_snprintf(funcname, sizeof(funcname), - LEAD_UNDERSCORE "PyInit_%.200s", shortname); + LEAD_UNDERSCORE "%.20s_%.200s", prefix, shortname); if (fp != NULL) { int i; - struct stat statb; - if (fstat(fileno(fp), &statb) == -1) { - PyErr_SetFromErrno(PyExc_IOError); + struct _Py_stat_struct status; + if (_Py_fstat(fileno(fp), &status) == -1) return NULL; - } for (i = 0; i < nhandles; i++) { - if (statb.st_dev == handles[i].dev && - statb.st_ino == handles[i].ino) { + 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 = statb.st_dev; -#ifdef __VMS - handles[nhandles].ino[0] = statb.st_ino[0]; - handles[nhandles].ino[1] = statb.st_ino[1]; - handles[nhandles].ino[2] = statb.st_ino[2]; -#else - handles[nhandles].ino = statb.st_ino; -#endif + handles[nhandles].dev = status.st_dev; + handles[nhandles].ino = status.st_ino; } } dlopenflags = PyThreadState_GET()->interp->dlopenflags; -#ifdef __VMS - /* VMS currently don't allow a pathname, use a logical name instead */ - /* Concatenate 'python_module_' and shortname */ - /* so "import vms.bar" will use the logical python_module_bar */ - /* As C module use only one name space this is probably not a */ - /* important limitation */ - PyOS_snprintf(pathbuf, sizeof(pathbuf), "python_module_%-.200s", - shortname); - pathname = pathbuf; -#endif - handle = dlopen(pathname, dlopenflags); if (handle == NULL) { diff --git a/Python/dynload_win.c b/Python/dynload_win.c index ffcf0ee1d739..f2c796e94d2e 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -9,6 +9,7 @@ #include #include "importdl.h" +#include "patchlevel.h" #include // "activation context" magic - see dl_nt.c... @@ -17,16 +18,28 @@ extern ULONG_PTR _Py_ActivateActCtx(); void _Py_DeactivateActCtx(ULONG_PTR cookie); #endif -const char *_PyImport_DynLoadFiletab[] = { #ifdef _DEBUG - "_d.pyd", +#define PYD_DEBUG_SUFFIX "_d" +#else +#define PYD_DEBUG_SUFFIX "" +#endif + +#define STRINGIZE2(x) #x +#define STRINGIZE(x) STRINGIZE2(x) +#ifdef PYD_PLATFORM_TAG +#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" STRINGIZE(PY_MAJOR_VERSION) STRINGIZE(PY_MINOR_VERSION) "-" PYD_PLATFORM_TAG ".pyd" #else - ".pyd", +#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" STRINGIZE(PY_MAJOR_VERSION) STRINGIZE(PY_MINOR_VERSION) ".pyd" #endif + +#define PYD_UNTAGGED_SUFFIX PYD_DEBUG_SUFFIX ".pyd" + +const char *_PyImport_DynLoadFiletab[] = { + PYD_TAGGED_SUFFIX, + PYD_UNTAGGED_SUFFIX, NULL }; - /* Case insensitive string compare, to avoid any dependencies on particular C RTL implementations */ @@ -173,8 +186,9 @@ static char *GetPythonImport (HINSTANCE hModule) return NULL; } -dl_funcptr _PyImport_GetDynLoadWindows(const char *shortname, - PyObject *pathname, FILE *fp) +dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, + const char *shortname, + PyObject *pathname, FILE *fp) { dl_funcptr p; char funcname[258], *import_python; @@ -188,7 +202,7 @@ dl_funcptr _PyImport_GetDynLoadWindows(const char *shortname, if (wpathname == NULL) return NULL; - PyOS_snprintf(funcname, sizeof(funcname), "PyInit_%.200s", shortname); + PyOS_snprintf(funcname, sizeof(funcname), "%.20s_%.200s", prefix, shortname); { HINSTANCE hDLL = NULL; diff --git a/Python/errors.c b/Python/errors.c index 90dc729fd1d1..aed2bdc12d6b 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -74,11 +74,11 @@ PyErr_SetObject(PyObject *exception, PyObject *value) if (value == NULL || !PyExceptionInstance_Check(value)) { /* We must normalize the value right now */ PyObject *args, *fixed_value; -#ifdef Py_DEBUG - /* in debug mode, PyEval_EvalFrameEx() fails with an assertion - error if an exception is set when it is called */ + + /* Issue #23571: PyEval_CallObject() must not be called with an + exception set */ PyErr_Clear(); -#endif + if (value == NULL || value == Py_None) args = PyTuple_New(0); else if (PyTuple_Check(value)) { @@ -319,7 +319,7 @@ PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb) Py_DECREF(*exc); Py_DECREF(*val); /* ... and use the recursion error instead */ - *exc = PyExc_RuntimeError; + *exc = PyExc_RecursionError; *val = PyExc_RecursionErrorInst; Py_INCREF(*exc); Py_INCREF(*val); @@ -384,6 +384,30 @@ PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback) 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; + + if (PyErr_Occurred()) { + PyObject *exc2, *val2, *tb2; + PyErr_Fetch(&exc2, &val2, &tb2); + PyErr_NormalizeException(&exc, &val, &tb); + Py_DECREF(exc); + Py_XDECREF(tb); + PyErr_NormalizeException(&exc2, &val2, &tb2); + PyException_SetContext(val2, val); + PyErr_Restore(exc2, val2, tb2); + } + else { + PyErr_Restore(exc, val, tb); + } +} + /* Convenience functions to set a type error exception and return 0 */ int @@ -409,6 +433,12 @@ PyErr_NoMemory(void) PyObject * PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject) +{ + return PyErr_SetFromErrnoWithFilenameObjects(exc, filenameObject, NULL); +} + +PyObject * +PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, PyObject *filenameObject2) { PyObject *message; PyObject *v, *args; @@ -461,7 +491,7 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject) /* Only ever seen this in out-of-mem situations */ s_buf = NULL; - message = PyUnicode_FromFormat("Windows Error 0x%X", i); + 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'.')) @@ -480,10 +510,15 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject) return NULL; } - if (filenameObject != NULL) - args = Py_BuildValue("(iOO)", i, message, filenameObject); - else + 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) { @@ -500,12 +535,11 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject) return NULL; } - PyObject * PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename) { PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; - PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name); + PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL); Py_XDECREF(name); return result; } @@ -517,7 +551,7 @@ PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, const Py_UNICODE *filename) PyObject *name = filename ? PyUnicode_FromUnicode(filename, wcslen(filename)) : NULL; - PyObject *result = PyErr_SetFromErrnoWithFilenameObject(exc, name); + PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL); Py_XDECREF(name); return result; } @@ -526,7 +560,7 @@ PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, const Py_UNICODE *filename) PyObject * PyErr_SetFromErrno(PyObject *exc) { - return PyErr_SetFromErrnoWithFilenameObject(exc, NULL); + return PyErr_SetFromErrnoWithFilenameObjects(exc, NULL, NULL); } #ifdef MS_WINDOWS @@ -535,6 +569,16 @@ 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) { int len; WCHAR *s_buf = NULL; /* Free via LocalFree */ @@ -556,7 +600,7 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject( NULL); /* no args */ if (len==0) { /* Only seen this in out of mem situations */ - message = PyUnicode_FromFormat("Windows Error 0x%X", err); + message = PyUnicode_FromFormat("Windows Error 0x%x", err); s_buf = NULL; } else { /* remove trailing cr/lf and dots */ @@ -571,11 +615,15 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject( return NULL; } - if (filenameObject == NULL) - filenameObject = Py_None; - /* This is the constructor signature for passing a Windows error code. + 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("(iOOi)", 0, message, filenameObject, err); + args = Py_BuildValue("(iOOiO)", 0, message, filenameObject, err, filenameObject2); Py_DECREF(message); if (args != NULL) { @@ -596,9 +644,10 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilename( const char *filename) { PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; - PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc, + PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, ierr, - name); + name, + NULL); Py_XDECREF(name); return ret; } @@ -611,9 +660,10 @@ PyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilename( PyObject *name = filename ? PyUnicode_FromUnicode(filename, wcslen(filename)) : NULL; - PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObject(exc, + PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, ierr, - name); + name, + NULL); Py_XDECREF(name); return ret; } @@ -628,14 +678,15 @@ 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_SetExcFromWindowsErrWithFilenameObject( + PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects( PyExc_OSError, - ierr, name); + ierr, name, NULL); Py_XDECREF(name); return result; } @@ -647,9 +698,9 @@ PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename( PyObject *name = filename ? PyUnicode_FromUnicode(filename, wcslen(filename)) : NULL; - PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObject( + PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects( PyExc_OSError, - ierr, name); + ierr, name, NULL); Py_XDECREF(name); return result; } @@ -722,34 +773,38 @@ PyErr_BadInternalCall(void) #define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__) +PyObject * +PyErr_FormatV(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(); + + string = PyUnicode_FromFormatV(format, vargs); + + PyErr_SetObject(exception, string); + Py_XDECREF(string); + return NULL; +} + PyObject * PyErr_Format(PyObject *exception, const char *format, ...) { va_list vargs; - PyObject* string; - #ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); #else va_start(vargs); #endif - -#ifdef Py_DEBUG - /* in debug mode, PyEval_EvalFrameEx() fails with an assertion error - if an exception is set when it is called */ - PyErr_Clear(); -#endif - - string = PyUnicode_FromFormatV(format, vargs); - PyErr_SetObject(exception, string); - Py_XDECREF(string); + PyErr_FormatV(exception, format, vargs); va_end(vargs); return NULL; } - PyObject * PyErr_NewException(const char *name, PyObject *base, PyObject *dict) { @@ -1070,6 +1125,10 @@ PyErr_ProgramTextObject(PyObject *filename, int lineno) if (filename == NULL || lineno <= 0) return NULL; fp = _Py_fopen_obj(filename, "r" PY_STDIOTEXTMODE); + if (fp == NULL) { + PyErr_Clear(); + return NULL; + } return err_programtext(fp, lineno); } diff --git a/Python/fileutils.c b/Python/fileutils.c index 814f0765a3db..079918c4a302 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -1,11 +1,14 @@ #include "Python.h" #include "osdefs.h" +#include + #ifdef MS_WINDOWS +# include # include +extern int winerror_to_errno(int); #endif #ifdef HAVE_LANGINFO_H -#include #include #endif @@ -28,7 +31,8 @@ extern wchar_t* _Py_DecodeUTF8_surrogateescape(const char *s, Py_ssize_t size); 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(), io.FileIO and os.open() */ + The flag is used by _Py_open(), _Py_open_noraise(), io.FileIO + and os.open(). */ int _Py_open_cloexec_works = -1; #endif @@ -38,9 +42,13 @@ _Py_device_encoding(int fd) #if defined(MS_WINDOWS) UINT cp; #endif - if (!_PyVerify_fd(fd) || !isatty(fd)) { + int valid; + _Py_BEGIN_SUPPRESS_IPH + valid = _PyVerify_fd(fd) && isatty(fd); + _Py_END_SUPPRESS_IPH + if (!valid) Py_RETURN_NONE; - } + #if defined(MS_WINDOWS) if (fd == 0) cp = GetConsoleCP(); @@ -81,11 +89,11 @@ extern int _Py_normalize_encoding(const char *, char *, size_t); Values of force_ascii: - 1: the workaround is used: _Py_wchar2char() uses - encode_ascii_surrogateescape() and _Py_char2wchar() uses + 1: the workaround is used: Py_EncodeLocale() uses + encode_ascii_surrogateescape() and Py_DecodeLocale() uses decode_ascii_surrogateescape() - 0: the workaround is not used: _Py_wchar2char() uses wcstombs() and - _Py_char2wchar() uses mbstowcs() + 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; @@ -219,8 +227,11 @@ decode_ascii_surrogateescape(const char *arg, size_t *size) wchar_t *res; unsigned char *in; wchar_t *out; + size_t argsize = strlen(arg) + 1; - res = PyMem_RawMalloc((strlen(arg)+1)*sizeof(wchar_t)); + if (argsize > PY_SSIZE_T_MAX/sizeof(wchar_t)) + return NULL; + res = PyMem_RawMalloc(argsize*sizeof(wchar_t)); if (!res) return NULL; @@ -240,24 +251,26 @@ decode_ascii_surrogateescape(const char *arg, size_t *size) /* 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 + 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. - Use _Py_wchar2char() to encode the character string back to a byte string. + 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 a pointer to a newly allocated wide character string (use - PyMem_RawFree() to free the memory) and write the number of written wide - characters excluding the null character into *size if size is not NULL, or - NULL on error (decoding or memory allocation error). If size is not NULL, - *size is set to (size_t)-1 on memory error and (size_t)-2 on decoding - error. + 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. - Conversion errors should never happen, unless there is a bug in the C - library. */ + 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_char2wchar(const char* arg, size_t *size) +Py_DecodeLocale(const char* arg, size_t *size) { #ifdef __APPLE__ wchar_t *wstr; @@ -302,10 +315,15 @@ _Py_char2wchar(const char* arg, size_t *size) argsize = mbstowcs(NULL, arg, 0); #endif if (argsize != (size_t)-1) { - res = (wchar_t *)PyMem_RawMalloc((argsize+1)*sizeof(wchar_t)); + if (argsize == PY_SSIZE_T_MAX) + goto oom; + argsize += 1; + if (argsize > PY_SSIZE_T_MAX/sizeof(wchar_t)) + goto oom; + res = (wchar_t *)PyMem_RawMalloc(argsize*sizeof(wchar_t)); if (!res) goto oom; - count = mbstowcs(res, arg, argsize+1); + count = mbstowcs(res, arg, argsize); if (count != (size_t)-1) { wchar_t *tmp; /* Only use the result if it contains no @@ -328,6 +346,8 @@ _Py_char2wchar(const char* arg, size_t *size) /* 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)) + goto oom; res = (wchar_t*)PyMem_RawMalloc(argsize*sizeof(wchar_t)); if (!res) goto oom; @@ -388,19 +408,20 @@ _Py_char2wchar(const char* arg, size_t *size) #endif /* __APPLE__ */ } -/* Encode a (wide) character string to the locale encoding with the - surrogateescape error handler (characters in range U+DC80..U+DCFF are - converted to bytes 0x80..0xFF). +/* 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. - This function is the reverse of _Py_char2wchar(). + Return a pointer to a newly allocated byte string, use PyMem_Free() to free + the memory. Return NULL on encoding or memory allocation error. - Return a pointer to a newly allocated byte string (use PyMem_Free() to free - the memory), or NULL on encoding or memory allocation error. + If error_pos is not NULL, *error_pos is set to the index of the invalid + character on encoding error, or set to (size_t)-1 otherwise. - If error_pos is not NULL: *error_pos is the index of the invalid character - on encoding error, or (size_t)-1 otherwise. */ + Use the Py_DecodeLocale() function to decode the bytes string back to a wide + character string. */ char* -_Py_wchar2char(const wchar_t *text, size_t *error_pos) +Py_EncodeLocale(const wchar_t *text, size_t *error_pos) { #ifdef __APPLE__ Py_ssize_t len; @@ -503,34 +524,179 @@ _Py_wchar2char(const wchar_t *text, size_t *error_pos) #endif /* __APPLE__ */ } -/* In principle, this should use HAVE__WSTAT, and _wstat - should be detected by autoconf. However, no current - POSIX system provides that function, so testing for - it is pointless. - Not sure whether the MS_WINDOWS guards are necessary: - perhaps for cygwin/mingw builds? -*/ -#if defined(HAVE_STAT) && !defined(MS_WINDOWS) -/* Get file status. Encode the path to the locale encoding. */ +#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 = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow; + if (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 GB. fstat() may fail with EOVERFLOW on files larger + than 2 GB because the file size type is an 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_wstat(const wchar_t* path, struct stat *buf) +_Py_fstat_noraise(int fd, struct _Py_stat_struct *status) { - int err; - char *fname; - fname = _Py_wchar2char(path, NULL); - if (fname == NULL) { - errno = EINVAL; +#ifdef MS_WINDOWS + BY_HANDLE_FILE_INFORMATION info; + HANDLE h; + int type; + + if (!_PyVerify_fd(fd)) + h = INVALID_HANDLE_VALUE; + else { + _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; } - err = stat(fname, buf); - PyMem_Free(fname); - return err; -} + 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 = (((__int64)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 GB. fstat() may fail with EOVERFLOW on files larger + than 2 GB because the file size type is an signed 32-bit integer: see issue + #23152. -#ifdef HAVE_STAT + 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; + + 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. @@ -564,7 +730,6 @@ _Py_stat(PyObject *path, struct stat *statbuf) #endif } -#endif static int get_inheritable(int fd, int raise) @@ -579,10 +744,12 @@ get_inheritable(int fd, int raise) return -1; } + _Py_BEGIN_SUPPRESS_IPH handle = (HANDLE)_get_osfhandle(fd); + _Py_END_SUPPRESS_IPH if (handle == INVALID_HANDLE_VALUE) { if (raise) - PyErr_SetFromWindowsErr(0); + PyErr_SetFromErrno(PyExc_OSError); return -1; } @@ -621,10 +788,12 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works) #ifdef MS_WINDOWS HANDLE handle; DWORD flags; -#elif defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX) +#else +#if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX) + static int ioctl_works = -1; int request; int err; -#elif defined(HAVE_FCNTL_H) +#endif int flags; int res; #endif @@ -635,10 +804,10 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works) if (atomic_flag_works != NULL && !inheritable) { if (*atomic_flag_works == -1) { - int inheritable = get_inheritable(fd, raise); - if (inheritable == -1) + int isInheritable = get_inheritable(fd, raise); + if (isInheritable == -1) return -1; - *atomic_flag_works = !inheritable; + *atomic_flag_works = !isInheritable; } if (*atomic_flag_works) @@ -652,10 +821,12 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works) return -1; } + _Py_BEGIN_SUPPRESS_IPH handle = (HANDLE)_get_osfhandle(fd); + _Py_END_SUPPRESS_IPH if (handle == INVALID_HANDLE_VALUE) { if (raise) - PyErr_SetFromWindowsErr(0); + PyErr_SetFromErrno(PyExc_OSError); return -1; } @@ -670,20 +841,38 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works) } return 0; -#elif defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX) - if (inheritable) - request = FIONCLEX; - else - request = FIOCLEX; - err = ioctl(fd, request, NULL); - if (err) { - if (raise) - PyErr_SetFromErrno(PyExc_OSError); - return -1; +#else + +#if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX) + if (ioctl_works != 0) { + /* fast-path: ioctl() only requires one syscall */ + if (inheritable) + request = FIONCLEX; + else + request = FIOCLEX; + err = ioctl(fd, request, NULL); + if (!err) { + ioctl_works = 1; + return 0; + } + + if (errno != ENOTTY) { + 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. */ + ioctl_works = 0; + } + /* fallback to fcntl() if ioctl() does not work */ } - return 0; +#endif -#else + /* slow-path: fcntl() requires two syscalls */ flags = fcntl(fd, F_GETFD); if (flags < 0) { if (raise) @@ -736,40 +925,92 @@ _Py_set_inheritable(int fd, int inheritable, int *atomic_flag_works) return set_inheritable(fd, inheritable, 1, atomic_flag_works); } -/* Open a file with the specified flags (wrapper to open() function). - The file descriptor is created non-inheritable. */ -int -_Py_open(const char *pathname, int flags) +static int +_Py_open_impl(const char *pathname, int flags, int gil_held) { int fd; -#ifdef MS_WINDOWS - fd = open(pathname, flags | O_NOINHERIT); - if (fd < 0) - return fd; -#else - + int async_err = 0; +#ifndef MS_WINDOWS int *atomic_flag_works; -#ifdef O_CLOEXEC +#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 - fd = open(pathname, flags); - if (fd < 0) - return fd; - if (set_inheritable(fd, 0, 0, atomic_flag_works) < 0) { + if (gil_held) { + 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) + return -1; + if (fd < 0) { + PyErr_SetFromErrnoWithFilename(PyExc_OSError, pathname); + return -1; + } + } + 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 /* !MS_WINDOWS */ +#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) +{ +#ifdef WITH_THREAD + /* _Py_open() must be called with the GIL held. */ + assert(PyGILState_Check()); +#endif + 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. */ + 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) { @@ -783,7 +1024,7 @@ _Py_wfopen(const wchar_t *path, const wchar_t *mode) errno = EINVAL; return NULL; } - cpath = _Py_wchar2char(path, NULL); + cpath = Py_EncodeLocale(path, NULL); if (cpath == NULL) return NULL; f = fopen(cpath, cmode); @@ -800,7 +1041,11 @@ _Py_wfopen(const wchar_t *path, const wchar_t *mode) return f; } -/* Wrapper to fopen(). The file descriptor is created non-inheritable. */ +/* 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) { @@ -815,20 +1060,32 @@ _Py_fopen(const char *pathname, const char *mode) } /* Open a file. Call _wfopen() on Windows, or encode the path to the filesystem - encoding and call fopen() otherwise. The file descriptor is created - non-inheritable. + encoding and call fopen() otherwise. + + Return the new file object on success. Raise an exception and return NULL + on error. - Return the new file object on success, or NULL if the file cannot be open or - (if PyErr_Occurred()) on unicode 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 wchar_t *wpath; wchar_t wmode[10]; int usize; +#ifdef WITH_THREAD + assert(PyGILState_Check()); +#endif + if (!PyUnicode_Check(path)) { PyErr_Format(PyExc_TypeError, "str file path expected under Windows, got %R", @@ -840,26 +1097,249 @@ _Py_fopen_obj(PyObject *path, const char *mode) return NULL; usize = MultiByteToWideChar(CP_ACP, 0, mode, -1, wmode, sizeof(wmode)); - if (usize == 0) + if (usize == 0) { + PyErr_SetFromWindowsErr(0); return NULL; + } - f = _wfopen(wpath, wmode); + 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; + +#ifdef WITH_THREAD + assert(PyGILState_Check()); +#endif + if (!PyUnicode_FSConverter(path, &bytes)) return NULL; - f = fopen(PyBytes_AS_STRING(bytes), mode); + path_bytes = PyBytes_AS_STRING(bytes); + + 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 (f == NULL) + if (async_err) return NULL; - if (make_non_inheritable(fileno(f)) < 0) { + + 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; + + /* _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 (!_PyVerify_fd(fd)) { + /* save/restore errno because PyErr_SetFromErrno() can modify it */ + err = errno; + PyErr_SetFromErrno(PyExc_OSError); + errno = err; + return -1; + } + +#ifdef MS_WINDOWS + if (count > INT_MAX) { + /* On Windows, the count parameter of read() is an int */ + count = INT_MAX; + } +#else + if (count > PY_SSIZE_T_MAX) { + /* if count is greater than PY_SSIZE_T_MAX, + * read() result is undefined */ + count = PY_SSIZE_T_MAX; + } +#endif + + _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; + + if (!_PyVerify_fd(fd)) { + if (gil_held) { + /* save/restore errno because PyErr_SetFromErrno() can modify it */ + err = errno; + PyErr_SetFromErrno(PyExc_OSError); + errno = err; + } + return -1; + } + + _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; + } + else if (count > INT_MAX) + count = INT_MAX; +#else + if (count > PY_SSIZE_T_MAX) { + /* write() should truncate count to PY_SSIZE_T_MAX, but it's safer + * to do it ourself to have a portable behaviour. */ + count = PY_SSIZE_T_MAX; + } +#endif + + 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) +{ + /* _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 @@ -874,7 +1354,7 @@ _Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t bufsiz) int res; size_t r1; - cpath = _Py_wchar2char(path, NULL); + cpath = Py_EncodeLocale(path, NULL); if (cpath == NULL) { errno = EINVAL; return -1; @@ -888,7 +1368,7 @@ _Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t bufsiz) return -1; } cbuf[res] = '\0'; /* buf will be null terminated */ - wbuf = _Py_char2wchar(cbuf, &r1); + wbuf = Py_DecodeLocale(cbuf, &r1); if (wbuf == NULL) { errno = EINVAL; return -1; @@ -919,7 +1399,7 @@ _Py_wrealpath(const wchar_t *path, wchar_t *wresolved_path; char *res; size_t r; - cpath = _Py_wchar2char(path, NULL); + cpath = Py_EncodeLocale(path, NULL); if (cpath == NULL) { errno = EINVAL; return NULL; @@ -929,7 +1409,7 @@ _Py_wrealpath(const wchar_t *path, if (res == NULL) return NULL; - wresolved_path = _Py_char2wchar(cresolved_path, &r); + wresolved_path = Py_DecodeLocale(cresolved_path, &r); if (wresolved_path == NULL) { errno = EINVAL; return NULL; @@ -962,7 +1442,7 @@ _Py_wgetcwd(wchar_t *buf, size_t size) if (getcwd(fname, Py_ARRAY_LENGTH(fname)) == NULL) return NULL; - wname = _Py_char2wchar(fname, &len); + wname = Py_DecodeLocale(fname, &len); if (wname == NULL) return NULL; if (size <= len) { @@ -994,9 +1474,11 @@ _Py_dup(int fd) } #ifdef MS_WINDOWS + _Py_BEGIN_SUPPRESS_IPH handle = (HANDLE)_get_osfhandle(fd); + _Py_END_SUPPRESS_IPH if (handle == INVALID_HANDLE_VALUE) { - PyErr_SetFromWindowsErr(0); + PyErr_SetFromErrno(PyExc_OSError); return -1; } @@ -1004,7 +1486,9 @@ _Py_dup(int fd) ftype = GetFileType(handle); 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); @@ -1014,13 +1498,17 @@ _Py_dup(int fd) /* Character files like console cannot be make non-inheritable */ if (ftype != FILE_TYPE_CHAR) { 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); @@ -1029,7 +1517,9 @@ _Py_dup(int fd) #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); @@ -1037,10 +1527,152 @@ _Py_dup(int fd) } 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 + +#if defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900 +/* Legacy implementation of _PyVerify_fd while transitioning to + * MSVC 14.0. This should eventually be removed. (issue23524) + */ + +/* Microsoft CRT in VS2005 and higher will verify that a filehandle is + * valid and raise an assertion if it isn't. + * Normally, an invalid fd is likely to be a C program error and therefore + * an assertion can be useful, but it does contradict the POSIX standard + * which for write(2) states: + * "Otherwise, -1 shall be returned and errno set to indicate the error." + * "[EBADF] The fildes argument is not a valid file descriptor open for + * writing." + * Furthermore, python allows the user to enter any old integer + * as a fd and should merely raise a python exception on error. + * The Microsoft CRT doesn't provide an official way to check for the + * validity of a file descriptor, but we can emulate its internal behaviour + * by using the exported __pinfo data member and knowledge of the + * internal structures involved. + * The structures below must be updated for each version of visual studio + * according to the file internal.h in the CRT source, until MS comes + * up with a less hacky way to do this. + * (all of this is to avoid globally modifying the CRT behaviour using + * _set_invalid_parameter_handler() and _CrtSetReportMode()) + */ +/* The actual size of the structure is determined at runtime. + * Only the first items must be present. + */ +typedef struct { + intptr_t osfhnd; + char osfile; +} my_ioinfo; + +extern __declspec(dllimport) char * __pioinfo[]; +#define IOINFO_L2E 5 +#define IOINFO_ARRAYS 64 +#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) +#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS) +#define FOPEN 0x01 +#define _NO_CONSOLE_FILENO (intptr_t)-2 + +/* This function emulates what the windows CRT does to validate file handles */ +int +_PyVerify_fd(int fd) +{ + const int i1 = fd >> IOINFO_L2E; + const int i2 = fd & ((1 << IOINFO_L2E) - 1); + + static size_t sizeof_ioinfo = 0; + + /* Determine the actual size of the ioinfo structure, + * as used by the CRT loaded in memory + */ + if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) { + sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS; + } + if (sizeof_ioinfo == 0) { + /* This should not happen... */ + goto fail; + } + + /* See that it isn't a special CLEAR fileno */ + if (fd != _NO_CONSOLE_FILENO) { + /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead + * we check pointer validity and other info + */ + if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) { + /* finally, check that the file is open */ + my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo); + if (info->osfile & FOPEN) { + return 1; + } + } + } + fail: + errno = EBADF; + return 0; +} + +#endif /* defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900 */ diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index 0a3cc593d646..056bb7690259 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -156,8 +156,9 @@ parse_internal_render_format_spec(PyObject *format_spec, Py_ssize_t consumed; int align_specified = 0; + int fill_char_specified = 0; - format->fill_char = '\0'; + format->fill_char = ' '; format->align = default_align; format->alternate = 0; format->sign = '\0'; @@ -171,6 +172,7 @@ parse_internal_render_format_spec(PyObject *format_spec, 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; } @@ -194,7 +196,7 @@ parse_internal_render_format_spec(PyObject *format_spec, } /* The special case for 0-padding (backwards compat) */ - if (format->fill_char == '\0' && end-pos >= 1 && READ_spec(pos) == '0') { + if (!fill_char_specified && end-pos >= 1 && READ_spec(pos) == '0') { format->fill_char = '0'; if (!align_specified) { format->align = '='; @@ -784,9 +786,7 @@ format_string_internal(PyObject *value, const InternalFormatSpec *format, goto done; /* Write into that space. First the padding. */ - result = fill_padding(writer, len, - format->fill_char=='\0'?' ':format->fill_char, - lpad, rpad); + result = fill_padding(writer, len, format->fill_char, lpad, rpad); if (result == -1) goto done; @@ -846,6 +846,13 @@ format_long_internal(PyObject *value, const InternalFormatSpec *format, " 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 */ @@ -956,8 +963,7 @@ format_long_internal(PyObject *value, const InternalFormatSpec *format, /* Populate the memory. */ result = fill_number(writer, &spec, tmp, inumeric_chars, inumeric_chars + n_digits, - tmp, prefix, - format->fill_char == '\0' ? ' ' : format->fill_char, + tmp, prefix, format->fill_char, &locale, format->type == 'X'); done: @@ -1104,8 +1110,7 @@ format_float_internal(PyObject *value, /* Populate the memory. */ result = fill_number(writer, &spec, unicode_tmp, index, index + n_digits, - NULL, 0, - format->fill_char == '\0' ? ' ' : format->fill_char, + NULL, 0, format->fill_char, &locale, 0); done: @@ -1311,8 +1316,7 @@ format_complex_internal(PyObject *value, /* Populate the memory. First, the padding. */ result = fill_padding(writer, n_re_total + n_im_total + 1 + add_parens * 2, - format->fill_char=='\0' ? ' ' : format->fill_char, - lpad, rpad); + format->fill_char, lpad, rpad); if (result == -1) goto done; diff --git a/Python/frozen.c b/Python/frozen.c index 9bc662b99435..676f395488c1 100644 --- a/Python/frozen.c +++ b/Python/frozen.c @@ -3,6 +3,7 @@ #include "Python.h" #include "importlib.h" +#include "importlib_external.h" /* In order to test the support for frozen modules, by default we define a single frozen module, __hello__. Loading it will print @@ -31,6 +32,8 @@ static unsigned char M___hello__[] = { static const struct _frozen _PyImport_FrozenModules[] = { /* importlib */ {"_frozen_importlib", _Py_M__importlib, (int)sizeof(_Py_M__importlib)}, + {"_frozen_importlib_external", _Py_M__importlib_external, + (int)sizeof(_Py_M__importlib_external)}, /* Test module */ {"__hello__", M___hello__, SIZE}, /* Test package (negative size indicates package-ness) */ diff --git a/Python/frozenmain.c b/Python/frozenmain.c index 55d05fc26f02..de8bd35453a9 100644 --- a/Python/frozenmain.c +++ b/Python/frozenmain.c @@ -24,11 +24,13 @@ Py_FrozenMain(int argc, char **argv) /* We need a second copies, as Python might modify the first one. */ wchar_t **argv_copy2 = NULL; - 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; + 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; + } } Py_FrozenFlag = 1; /* Suppress errors from getpath.c */ @@ -52,7 +54,7 @@ Py_FrozenMain(int argc, char **argv) setlocale(LC_ALL, ""); for (i = 0; i < argc; i++) { - argv_copy[i] = _Py_char2wchar(argv[i], NULL); + 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", @@ -68,7 +70,8 @@ Py_FrozenMain(int argc, char **argv) #ifdef MS_WINDOWS PyInitFrozenExtensions(); #endif /* MS_WINDOWS */ - Py_SetProgramName(argv_copy[0]); + if (argc >= 1) + Py_SetProgramName(argv_copy[0]); Py_Initialize(); #ifdef MS_WINDOWS PyWinFreeze_ExeInit(); diff --git a/Python/future.c b/Python/future.c index 81eab54dd62f..163f87f673da 100644 --- a/Python/future.c +++ b/Python/future.c @@ -40,6 +40,8 @@ future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename) 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) { + ff->ff_features |= CO_FUTURE_GENERATOR_STOP; } else if (strcmp(feature, "braces") == 0) { PyErr_SetString(PyExc_SyntaxError, "not a chance"); diff --git a/Python/getargs.c b/Python/getargs.c index 60845680fc2a..c365fc25a39d 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -200,8 +200,6 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) { char msgbuf[256]; int levels[32]; - freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; - freelist_t freelist = {static_entries, 0, 0}; const char *fname = NULL; const char *message = NULL; int min = -1; @@ -212,6 +210,12 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags) Py_ssize_t i, len; char *msg; int compat = flags & FLAG_COMPAT; + freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; + freelist_t freelist; + + freelist.entries = static_entries; + freelist.first_available = 0; + freelist.entries_malloced = 0; assert(compat || (args != (PyObject*)NULL)); flags = flags & ~FLAG_COMPAT; @@ -845,7 +849,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, /* XXX WAAAAH! 's', 'y', 'z', 'u', 'Z', 'e', 'w' codes all need to be cleaned up! */ - case 'y': {/* any buffer-like object, but not PyUnicode */ + case 'y': {/* any bytes-like object */ void **p = (void **)va_arg(*p_va, char **); char *buf; Py_ssize_t count; @@ -868,16 +872,16 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, STORE_SIZE(count); format++; } else { - if (strlen(*p) != count) - return converterr( - "bytes without null bytes", - arg, msgbuf, bufsize); + if (strlen(*p) != (size_t)count) { + PyErr_SetString(PyExc_ValueError, "embedded null byte"); + RETURN_ERR_OCCURRED; + } } break; } - case 's': /* text string */ - case 'z': /* text string or None */ + case 's': /* text string or bytes-like object */ + case 'z': /* text string, bytes-like object or None */ { if (*format == '*') { /* "s*" or "z*" */ @@ -893,7 +897,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, arg, msgbuf, bufsize); PyBuffer_FillInfo(p, arg, sarg, len, 1, 0); } - else { /* any buffer-like object */ + else { /* any bytes-like object */ char *buf; if (getbuffer(arg, p, &buf) < 0) return converterr(buf, arg, msgbuf, bufsize); @@ -904,7 +908,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, arg, msgbuf, bufsize); } format++; - } else if (*format == '#') { /* any buffer-like object */ + } else if (*format == '#') { /* a string or read-only bytes-like object */ /* "s#" or "z#" */ void **p = (void **)va_arg(*p_va, char **); FETCH_SIZE; @@ -922,7 +926,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, *p = sarg; STORE_SIZE(len); } - else { /* any buffer-like object */ + else { /* read-only bytes-like object */ /* XXX Really? */ char *buf; Py_ssize_t count = convertbuffer(arg, p, &buf); @@ -944,16 +948,15 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, 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); - if (*p != NULL && sarg != NULL && (Py_ssize_t) strlen(*p) != len) - return converterr( - c == 'z' ? "str without null characters or None" - : "str without null characters", - arg, msgbuf, bufsize); } break; } @@ -963,8 +966,8 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, { Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **); - if (*format == '#') { /* any buffer-like object */ - /* "s#" or "Z#" */ + if (*format == '#') { + /* "u#" or "Z#" */ FETCH_SIZE; if (c == 'Z' && arg == Py_None) { @@ -979,10 +982,11 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, STORE_SIZE(len); } else - return converterr("str or None", arg, msgbuf, bufsize); + return converterr(c == 'Z' ? "str or None" : "str", + arg, msgbuf, bufsize); format++; } else { - /* "s" or "Z" */ + /* "u" or "Z" */ if (c == 'Z' && arg == Py_None) *p = NULL; else if (PyUnicode_Check(arg)) { @@ -990,10 +994,10 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, *p = PyUnicode_AsUnicodeAndSize(arg, &len); if (*p == NULL) RETURN_ERR_OCCURRED; - if (Py_UNICODE_strlen(*p) != len) - return converterr( - "str without null characters or None", - arg, msgbuf, bufsize); + if (Py_UNICODE_strlen(*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); @@ -1241,7 +1245,8 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, supports it directly. */ if (PyObject_GetBuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) { PyErr_Clear(); - return converterr("read-write buffer", arg, msgbuf, bufsize); + return converterr("read-write bytes-like object", + arg, msgbuf, bufsize); } if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C')) { PyBuffer_Release((Py_buffer*)p); @@ -1279,7 +1284,7 @@ convertbuffer(PyObject *arg, void **p, char **errmsg) *errmsg = NULL; *p = NULL; if (pb != NULL && pb->bf_releasebuffer != NULL) { - *errmsg = "read-only pinned buffer"; + *errmsg = "read-only bytes-like object"; return -1; } @@ -1295,7 +1300,7 @@ static int getbuffer(PyObject *arg, Py_buffer *view, char **errmsg) { if (PyObject_GetBuffer(arg, view, PyBUF_SIMPLE) != 0) { - *errmsg = "bytes or buffer"; + *errmsg = "bytes-like object"; return -1; } if (!PyBuffer_IsContiguous(view, 'C')) { @@ -1439,7 +1444,11 @@ vgetargskeywords(PyObject *args, PyObject *keywords, const char *format, Py_ssize_t nargs, nkeywords; PyObject *current_arg; freelistentry_t static_entries[STATIC_FREELIST_ENTRIES]; - freelist_t freelist = {static_entries, 0, 0}; + freelist_t freelist; + + freelist.entries = static_entries; + freelist.first_available = 0; + freelist.entries_malloced = 0; assert(args != NULL && PyTuple_Check(args)); assert(keywords == NULL || PyDict_Check(keywords)); @@ -1805,7 +1814,7 @@ PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t m /* For type constructors that don't take keyword args * - * Sets a TypeError and returns 0 if the kwds dict is + * Sets a TypeError and returns 0 if the args/kwargs is * not empty, returns 1 otherwise */ int @@ -1824,6 +1833,25 @@ _PyArg_NoKeywords(const char *funcname, PyObject *kw) 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, "%s does not take positional arguments", + funcname); + return 0; +} + #ifdef __cplusplus }; #endif diff --git a/Python/getcopyright.c b/Python/getcopyright.c index 2b19622d4368..2ad2848aa80b 100644 --- a/Python/getcopyright.c +++ b/Python/getcopyright.c @@ -4,7 +4,7 @@ static const char cprt[] = "\ -Copyright (c) 2001-2013 Python Software Foundation.\n\ +Copyright (c) 2001-2015 Python Software Foundation.\n\ All Rights Reserved.\n\ \n\ Copyright (c) 2000 BeOpen.com.\n\ diff --git a/Python/graminit.c b/Python/graminit.c index e04999bbff2f..354dc121b029 100644 --- a/Python/graminit.c +++ b/Python/graminit.c @@ -92,393 +92,420 @@ static state states_4[2] = { static arc arcs_5_0[1] = { {16, 1}, }; -static arc arcs_5_1[2] = { +static arc arcs_5_1[3] = { {18, 2}, {19, 2}, + {20, 2}, }; static arc arcs_5_2[1] = { {0, 2}, }; static state states_5[3] = { {1, arcs_5_0}, - {2, arcs_5_1}, + {3, arcs_5_1}, {1, arcs_5_2}, }; static arc arcs_6_0[1] = { - {20, 1}, + {21, 1}, }; static arc arcs_6_1[1] = { - {21, 2}, + {19, 2}, }; static arc arcs_6_2[1] = { - {22, 3}, + {0, 2}, }; -static arc arcs_6_3[2] = { - {23, 4}, - {25, 5}, +static state states_6[3] = { + {1, arcs_6_0}, + {1, arcs_6_1}, + {1, arcs_6_2}, +}; +static arc arcs_7_0[1] = { + {22, 1}, }; -static arc arcs_6_4[1] = { - {24, 6}, +static arc arcs_7_1[1] = { + {23, 2}, }; -static arc arcs_6_5[1] = { - {26, 7}, +static arc arcs_7_2[1] = { + {24, 3}, +}; +static arc arcs_7_3[2] = { + {25, 4}, + {27, 5}, +}; +static arc arcs_7_4[1] = { + {26, 6}, }; -static arc arcs_6_6[1] = { - {25, 5}, +static arc arcs_7_5[1] = { + {28, 7}, }; -static arc arcs_6_7[1] = { +static arc arcs_7_6[1] = { + {27, 5}, +}; +static arc arcs_7_7[1] = { {0, 7}, }; -static state states_6[8] = { - {1, arcs_6_0}, - {1, arcs_6_1}, - {1, arcs_6_2}, - {2, arcs_6_3}, - {1, arcs_6_4}, - {1, arcs_6_5}, - {1, arcs_6_6}, - {1, arcs_6_7}, +static state states_7[8] = { + {1, arcs_7_0}, + {1, arcs_7_1}, + {1, arcs_7_2}, + {2, arcs_7_3}, + {1, arcs_7_4}, + {1, arcs_7_5}, + {1, arcs_7_6}, + {1, arcs_7_7}, }; -static arc arcs_7_0[1] = { +static arc arcs_8_0[1] = { {13, 1}, }; -static arc arcs_7_1[2] = { - {27, 2}, +static arc arcs_8_1[2] = { + {29, 2}, {15, 3}, }; -static arc arcs_7_2[1] = { +static arc arcs_8_2[1] = { {15, 3}, }; -static arc arcs_7_3[1] = { +static arc arcs_8_3[1] = { {0, 3}, }; -static state states_7[4] = { - {1, arcs_7_0}, - {2, arcs_7_1}, - {1, arcs_7_2}, - {1, arcs_7_3}, +static state states_8[4] = { + {1, arcs_8_0}, + {2, arcs_8_1}, + {1, arcs_8_2}, + {1, arcs_8_3}, }; -static arc arcs_8_0[3] = { - {28, 1}, - {31, 2}, - {32, 3}, +static arc arcs_9_0[3] = { + {30, 1}, + {33, 2}, + {34, 3}, }; -static arc arcs_8_1[3] = { - {29, 4}, - {30, 5}, +static arc arcs_9_1[3] = { + {31, 4}, + {32, 5}, {0, 1}, }; -static arc arcs_8_2[3] = { - {28, 6}, - {30, 7}, +static arc arcs_9_2[3] = { + {30, 6}, + {32, 7}, {0, 2}, }; -static arc arcs_8_3[1] = { - {28, 8}, +static arc arcs_9_3[1] = { + {30, 8}, }; -static arc arcs_8_4[1] = { - {24, 9}, +static arc arcs_9_4[1] = { + {26, 9}, }; -static arc arcs_8_5[4] = { - {28, 10}, - {31, 11}, - {32, 3}, +static arc arcs_9_5[4] = { + {30, 10}, + {33, 11}, + {34, 3}, {0, 5}, }; -static arc arcs_8_6[2] = { - {30, 7}, +static arc arcs_9_6[2] = { + {32, 7}, {0, 6}, }; -static arc arcs_8_7[2] = { - {28, 12}, - {32, 3}, +static arc arcs_9_7[3] = { + {30, 12}, + {34, 3}, + {0, 7}, }; -static arc arcs_8_8[1] = { +static arc arcs_9_8[2] = { + {32, 13}, {0, 8}, }; -static arc arcs_8_9[2] = { - {30, 5}, +static arc arcs_9_9[2] = { + {32, 5}, {0, 9}, }; -static arc arcs_8_10[3] = { - {30, 5}, - {29, 4}, +static arc arcs_9_10[3] = { + {32, 5}, + {31, 4}, {0, 10}, }; -static arc arcs_8_11[3] = { - {28, 13}, +static arc arcs_9_11[3] = { {30, 14}, + {32, 15}, {0, 11}, }; -static arc arcs_8_12[3] = { - {30, 7}, - {29, 15}, +static arc arcs_9_12[3] = { + {32, 7}, + {31, 16}, {0, 12}, }; -static arc arcs_8_13[2] = { - {30, 14}, +static arc arcs_9_13[1] = { {0, 13}, }; -static arc arcs_8_14[2] = { - {28, 16}, - {32, 3}, +static arc arcs_9_14[2] = { + {32, 15}, + {0, 14}, }; -static arc arcs_8_15[1] = { - {24, 6}, +static arc arcs_9_15[3] = { + {30, 17}, + {34, 3}, + {0, 15}, }; -static arc arcs_8_16[3] = { - {30, 14}, - {29, 17}, - {0, 16}, +static arc arcs_9_16[1] = { + {26, 6}, }; -static arc arcs_8_17[1] = { - {24, 13}, +static arc arcs_9_17[3] = { + {32, 15}, + {31, 18}, + {0, 17}, }; -static state states_8[18] = { - {3, arcs_8_0}, - {3, arcs_8_1}, - {3, arcs_8_2}, - {1, arcs_8_3}, - {1, arcs_8_4}, - {4, arcs_8_5}, - {2, arcs_8_6}, - {2, arcs_8_7}, - {1, arcs_8_8}, - {2, arcs_8_9}, - {3, arcs_8_10}, - {3, arcs_8_11}, - {3, arcs_8_12}, - {2, arcs_8_13}, - {2, arcs_8_14}, - {1, arcs_8_15}, - {3, arcs_8_16}, - {1, arcs_8_17}, -}; -static arc arcs_9_0[1] = { - {21, 1}, +static arc arcs_9_18[1] = { + {26, 14}, }; -static arc arcs_9_1[2] = { - {25, 2}, +static state states_9[19] = { + {3, arcs_9_0}, + {3, arcs_9_1}, + {3, arcs_9_2}, + {1, arcs_9_3}, + {1, arcs_9_4}, + {4, arcs_9_5}, + {2, arcs_9_6}, + {3, arcs_9_7}, + {2, arcs_9_8}, + {2, arcs_9_9}, + {3, arcs_9_10}, + {3, arcs_9_11}, + {3, arcs_9_12}, + {1, arcs_9_13}, + {2, arcs_9_14}, + {3, arcs_9_15}, + {1, arcs_9_16}, + {3, arcs_9_17}, + {1, arcs_9_18}, +}; +static arc arcs_10_0[1] = { + {23, 1}, +}; +static arc arcs_10_1[2] = { + {27, 2}, {0, 1}, }; -static arc arcs_9_2[1] = { - {24, 3}, +static arc arcs_10_2[1] = { + {26, 3}, }; -static arc arcs_9_3[1] = { +static arc arcs_10_3[1] = { {0, 3}, }; -static state states_9[4] = { - {1, arcs_9_0}, - {2, arcs_9_1}, - {1, arcs_9_2}, - {1, arcs_9_3}, +static state states_10[4] = { + {1, arcs_10_0}, + {2, arcs_10_1}, + {1, arcs_10_2}, + {1, arcs_10_3}, }; -static arc arcs_10_0[3] = { - {34, 1}, - {31, 2}, - {32, 3}, +static arc arcs_11_0[3] = { + {36, 1}, + {33, 2}, + {34, 3}, }; -static arc arcs_10_1[3] = { - {29, 4}, - {30, 5}, +static arc arcs_11_1[3] = { + {31, 4}, + {32, 5}, {0, 1}, }; -static arc arcs_10_2[3] = { - {34, 6}, - {30, 7}, +static arc arcs_11_2[3] = { + {36, 6}, + {32, 7}, {0, 2}, }; -static arc arcs_10_3[1] = { - {34, 8}, +static arc arcs_11_3[1] = { + {36, 8}, }; -static arc arcs_10_4[1] = { - {24, 9}, +static arc arcs_11_4[1] = { + {26, 9}, }; -static arc arcs_10_5[4] = { - {34, 10}, - {31, 11}, - {32, 3}, +static arc arcs_11_5[4] = { + {36, 10}, + {33, 11}, + {34, 3}, {0, 5}, }; -static arc arcs_10_6[2] = { - {30, 7}, +static arc arcs_11_6[2] = { + {32, 7}, {0, 6}, }; -static arc arcs_10_7[2] = { - {34, 12}, - {32, 3}, +static arc arcs_11_7[3] = { + {36, 12}, + {34, 3}, + {0, 7}, }; -static arc arcs_10_8[1] = { +static arc arcs_11_8[2] = { + {32, 13}, {0, 8}, }; -static arc arcs_10_9[2] = { - {30, 5}, +static arc arcs_11_9[2] = { + {32, 5}, {0, 9}, }; -static arc arcs_10_10[3] = { - {30, 5}, - {29, 4}, +static arc arcs_11_10[3] = { + {32, 5}, + {31, 4}, {0, 10}, }; -static arc arcs_10_11[3] = { - {34, 13}, - {30, 14}, +static arc arcs_11_11[3] = { + {36, 14}, + {32, 15}, {0, 11}, }; -static arc arcs_10_12[3] = { - {30, 7}, - {29, 15}, +static arc arcs_11_12[3] = { + {32, 7}, + {31, 16}, {0, 12}, }; -static arc arcs_10_13[2] = { - {30, 14}, +static arc arcs_11_13[1] = { {0, 13}, }; -static arc arcs_10_14[2] = { - {34, 16}, - {32, 3}, -}; -static arc arcs_10_15[1] = { - {24, 6}, +static arc arcs_11_14[2] = { + {32, 15}, + {0, 14}, }; -static arc arcs_10_16[3] = { - {30, 14}, - {29, 17}, - {0, 16}, +static arc arcs_11_15[3] = { + {36, 17}, + {34, 3}, + {0, 15}, }; -static arc arcs_10_17[1] = { - {24, 13}, +static arc arcs_11_16[1] = { + {26, 6}, }; -static state states_10[18] = { - {3, arcs_10_0}, - {3, arcs_10_1}, - {3, arcs_10_2}, - {1, arcs_10_3}, - {1, arcs_10_4}, - {4, arcs_10_5}, - {2, arcs_10_6}, - {2, arcs_10_7}, - {1, arcs_10_8}, - {2, arcs_10_9}, - {3, arcs_10_10}, - {3, arcs_10_11}, - {3, arcs_10_12}, - {2, arcs_10_13}, - {2, arcs_10_14}, - {1, arcs_10_15}, - {3, arcs_10_16}, - {1, arcs_10_17}, -}; -static arc arcs_11_0[1] = { - {21, 1}, +static arc arcs_11_17[3] = { + {32, 15}, + {31, 18}, + {0, 17}, +}; +static arc arcs_11_18[1] = { + {26, 14}, +}; +static state states_11[19] = { + {3, arcs_11_0}, + {3, arcs_11_1}, + {3, arcs_11_2}, + {1, arcs_11_3}, + {1, arcs_11_4}, + {4, arcs_11_5}, + {2, arcs_11_6}, + {3, arcs_11_7}, + {2, arcs_11_8}, + {2, arcs_11_9}, + {3, arcs_11_10}, + {3, arcs_11_11}, + {3, arcs_11_12}, + {1, arcs_11_13}, + {2, arcs_11_14}, + {3, arcs_11_15}, + {1, arcs_11_16}, + {3, arcs_11_17}, + {1, arcs_11_18}, +}; +static arc arcs_12_0[1] = { + {23, 1}, }; -static arc arcs_11_1[1] = { +static arc arcs_12_1[1] = { {0, 1}, }; -static state states_11[2] = { - {1, arcs_11_0}, - {1, arcs_11_1}, +static state states_12[2] = { + {1, arcs_12_0}, + {1, arcs_12_1}, }; -static arc arcs_12_0[2] = { +static arc arcs_13_0[2] = { {3, 1}, {4, 1}, }; -static arc arcs_12_1[1] = { +static arc arcs_13_1[1] = { {0, 1}, }; -static state states_12[2] = { - {2, arcs_12_0}, - {1, arcs_12_1}, +static state states_13[2] = { + {2, arcs_13_0}, + {1, arcs_13_1}, }; -static arc arcs_13_0[1] = { - {35, 1}, +static arc arcs_14_0[1] = { + {37, 1}, }; -static arc arcs_13_1[2] = { - {36, 2}, +static arc arcs_14_1[2] = { + {38, 2}, {2, 3}, }; -static arc arcs_13_2[2] = { - {35, 1}, +static arc arcs_14_2[2] = { + {37, 1}, {2, 3}, }; -static arc arcs_13_3[1] = { +static arc arcs_14_3[1] = { {0, 3}, }; -static state states_13[4] = { - {1, arcs_13_0}, - {2, arcs_13_1}, - {2, arcs_13_2}, - {1, arcs_13_3}, +static state states_14[4] = { + {1, arcs_14_0}, + {2, arcs_14_1}, + {2, arcs_14_2}, + {1, arcs_14_3}, }; -static arc arcs_14_0[8] = { - {37, 1}, - {38, 1}, +static arc arcs_15_0[8] = { {39, 1}, {40, 1}, {41, 1}, {42, 1}, {43, 1}, {44, 1}, + {45, 1}, + {46, 1}, }; -static arc arcs_14_1[1] = { +static arc arcs_15_1[1] = { {0, 1}, }; -static state states_14[2] = { - {8, arcs_14_0}, - {1, arcs_14_1}, +static state states_15[2] = { + {8, arcs_15_0}, + {1, arcs_15_1}, }; -static arc arcs_15_0[1] = { - {45, 1}, +static arc arcs_16_0[1] = { + {47, 1}, }; -static arc arcs_15_1[3] = { - {46, 2}, - {29, 3}, +static arc arcs_16_1[3] = { + {48, 2}, + {31, 3}, {0, 1}, }; -static arc arcs_15_2[2] = { - {47, 4}, +static arc arcs_16_2[2] = { + {49, 4}, {9, 4}, }; -static arc arcs_15_3[2] = { +static arc arcs_16_3[2] = { + {49, 5}, {47, 5}, - {45, 5}, }; -static arc arcs_15_4[1] = { +static arc arcs_16_4[1] = { {0, 4}, }; -static arc arcs_15_5[2] = { - {29, 3}, +static arc arcs_16_5[2] = { + {31, 3}, {0, 5}, }; -static state states_15[6] = { - {1, arcs_15_0}, - {3, arcs_15_1}, - {2, arcs_15_2}, - {2, arcs_15_3}, - {1, arcs_15_4}, - {2, arcs_15_5}, +static state states_16[6] = { + {1, arcs_16_0}, + {3, arcs_16_1}, + {2, arcs_16_2}, + {2, arcs_16_3}, + {1, arcs_16_4}, + {2, arcs_16_5}, }; -static arc arcs_16_0[2] = { - {24, 1}, - {48, 1}, +static arc arcs_17_0[2] = { + {26, 1}, + {50, 1}, }; -static arc arcs_16_1[2] = { - {30, 2}, +static arc arcs_17_1[2] = { + {32, 2}, {0, 1}, }; -static arc arcs_16_2[3] = { - {24, 1}, - {48, 1}, +static arc arcs_17_2[3] = { + {26, 1}, + {50, 1}, {0, 2}, }; -static state states_16[3] = { - {2, arcs_16_0}, - {2, arcs_16_1}, - {3, arcs_16_2}, +static state states_17[3] = { + {2, arcs_17_0}, + {2, arcs_17_1}, + {3, arcs_17_2}, }; -static arc arcs_17_0[12] = { - {49, 1}, - {50, 1}, +static arc arcs_18_0[13] = { {51, 1}, {52, 1}, {53, 1}, @@ -489,64 +516,57 @@ static arc arcs_17_0[12] = { {58, 1}, {59, 1}, {60, 1}, -}; -static arc arcs_17_1[1] = { - {0, 1}, -}; -static state states_17[2] = { - {12, arcs_17_0}, - {1, arcs_17_1}, -}; -static arc arcs_18_0[1] = { {61, 1}, + {62, 1}, + {63, 1}, }; static arc arcs_18_1[1] = { - {62, 2}, -}; -static arc arcs_18_2[1] = { - {0, 2}, + {0, 1}, }; -static state states_18[3] = { - {1, arcs_18_0}, +static state states_18[2] = { + {13, arcs_18_0}, {1, arcs_18_1}, - {1, arcs_18_2}, }; static arc arcs_19_0[1] = { - {63, 1}, + {64, 1}, }; static arc arcs_19_1[1] = { - {0, 1}, + {65, 2}, }; -static state states_19[2] = { +static arc arcs_19_2[1] = { + {0, 2}, +}; +static state states_19[3] = { {1, arcs_19_0}, {1, arcs_19_1}, + {1, arcs_19_2}, }; -static arc arcs_20_0[5] = { - {64, 1}, - {65, 1}, +static arc arcs_20_0[1] = { {66, 1}, - {67, 1}, - {68, 1}, }; static arc arcs_20_1[1] = { {0, 1}, }; static state states_20[2] = { - {5, arcs_20_0}, + {1, arcs_20_0}, {1, arcs_20_1}, }; -static arc arcs_21_0[1] = { +static arc arcs_21_0[5] = { + {67, 1}, + {68, 1}, {69, 1}, + {70, 1}, + {71, 1}, }; static arc arcs_21_1[1] = { {0, 1}, }; static state states_21[2] = { - {1, arcs_21_0}, + {5, arcs_21_0}, {1, arcs_21_1}, }; static arc arcs_22_0[1] = { - {70, 1}, + {72, 1}, }; static arc arcs_22_1[1] = { {0, 1}, @@ -556,148 +576,139 @@ static state states_22[2] = { {1, arcs_22_1}, }; static arc arcs_23_0[1] = { - {71, 1}, + {73, 1}, }; -static arc arcs_23_1[2] = { - {9, 2}, +static arc arcs_23_1[1] = { {0, 1}, }; -static arc arcs_23_2[1] = { - {0, 2}, -}; -static state states_23[3] = { +static state states_23[2] = { {1, arcs_23_0}, - {2, arcs_23_1}, - {1, arcs_23_2}, + {1, arcs_23_1}, }; static arc arcs_24_0[1] = { - {47, 1}, + {74, 1}, }; -static arc arcs_24_1[1] = { +static arc arcs_24_1[2] = { + {9, 2}, {0, 1}, }; -static state states_24[2] = { +static arc arcs_24_2[1] = { + {0, 2}, +}; +static state states_24[3] = { {1, arcs_24_0}, - {1, arcs_24_1}, + {2, arcs_24_1}, + {1, arcs_24_2}, }; static arc arcs_25_0[1] = { - {72, 1}, + {49, 1}, +}; +static arc arcs_25_1[1] = { + {0, 1}, +}; +static state states_25[2] = { + {1, arcs_25_0}, + {1, arcs_25_1}, +}; +static arc arcs_26_0[1] = { + {75, 1}, }; -static arc arcs_25_1[2] = { - {24, 2}, +static arc arcs_26_1[2] = { + {26, 2}, {0, 1}, }; -static arc arcs_25_2[2] = { - {73, 3}, +static arc arcs_26_2[2] = { + {76, 3}, {0, 2}, }; -static arc arcs_25_3[1] = { - {24, 4}, +static arc arcs_26_3[1] = { + {26, 4}, }; -static arc arcs_25_4[1] = { +static arc arcs_26_4[1] = { {0, 4}, }; -static state states_25[5] = { - {1, arcs_25_0}, - {2, arcs_25_1}, - {2, arcs_25_2}, - {1, arcs_25_3}, - {1, arcs_25_4}, +static state states_26[5] = { + {1, arcs_26_0}, + {2, arcs_26_1}, + {2, arcs_26_2}, + {1, arcs_26_3}, + {1, arcs_26_4}, }; -static arc arcs_26_0[2] = { - {74, 1}, - {75, 1}, +static arc arcs_27_0[2] = { + {77, 1}, + {78, 1}, }; -static arc arcs_26_1[1] = { +static arc arcs_27_1[1] = { {0, 1}, }; -static state states_26[2] = { - {2, arcs_26_0}, - {1, arcs_26_1}, +static state states_27[2] = { + {2, arcs_27_0}, + {1, arcs_27_1}, }; -static arc arcs_27_0[1] = { - {76, 1}, +static arc arcs_28_0[1] = { + {79, 1}, }; -static arc arcs_27_1[1] = { - {77, 2}, +static arc arcs_28_1[1] = { + {80, 2}, }; -static arc arcs_27_2[1] = { +static arc arcs_28_2[1] = { {0, 2}, }; -static state states_27[3] = { - {1, arcs_27_0}, - {1, arcs_27_1}, - {1, arcs_27_2}, +static state states_28[3] = { + {1, arcs_28_0}, + {1, arcs_28_1}, + {1, arcs_28_2}, }; -static arc arcs_28_0[1] = { - {73, 1}, +static arc arcs_29_0[1] = { + {76, 1}, }; -static arc arcs_28_1[3] = { - {78, 2}, - {79, 2}, +static arc arcs_29_1[3] = { + {81, 2}, + {82, 2}, {12, 3}, }; -static arc arcs_28_2[4] = { - {78, 2}, - {79, 2}, +static arc arcs_29_2[4] = { + {81, 2}, + {82, 2}, {12, 3}, - {76, 4}, + {79, 4}, }; -static arc arcs_28_3[1] = { - {76, 4}, +static arc arcs_29_3[1] = { + {79, 4}, }; -static arc arcs_28_4[3] = { - {31, 5}, +static arc arcs_29_4[3] = { + {33, 5}, {13, 6}, - {80, 5}, + {83, 5}, }; -static arc arcs_28_5[1] = { +static arc arcs_29_5[1] = { {0, 5}, }; -static arc arcs_28_6[1] = { - {80, 7}, +static arc arcs_29_6[1] = { + {83, 7}, }; -static arc arcs_28_7[1] = { +static arc arcs_29_7[1] = { {15, 5}, }; -static state states_28[8] = { - {1, arcs_28_0}, - {3, arcs_28_1}, - {4, arcs_28_2}, - {1, arcs_28_3}, - {3, arcs_28_4}, - {1, arcs_28_5}, - {1, arcs_28_6}, - {1, arcs_28_7}, -}; -static arc arcs_29_0[1] = { - {21, 1}, -}; -static arc arcs_29_1[2] = { - {82, 2}, - {0, 1}, -}; -static arc arcs_29_2[1] = { - {21, 3}, -}; -static arc arcs_29_3[1] = { - {0, 3}, -}; -static state states_29[4] = { +static state states_29[8] = { {1, arcs_29_0}, - {2, arcs_29_1}, - {1, arcs_29_2}, + {3, arcs_29_1}, + {4, arcs_29_2}, {1, arcs_29_3}, + {3, arcs_29_4}, + {1, arcs_29_5}, + {1, arcs_29_6}, + {1, arcs_29_7}, }; static arc arcs_30_0[1] = { - {12, 1}, + {23, 1}, }; static arc arcs_30_1[2] = { - {82, 2}, + {85, 2}, {0, 1}, }; static arc arcs_30_2[1] = { - {21, 3}, + {23, 3}, }; static arc arcs_30_3[1] = { {0, 3}, @@ -709,37 +720,45 @@ static state states_30[4] = { {1, arcs_30_3}, }; static arc arcs_31_0[1] = { - {81, 1}, + {12, 1}, }; static arc arcs_31_1[2] = { - {30, 2}, + {85, 2}, {0, 1}, }; -static arc arcs_31_2[2] = { - {81, 1}, - {0, 2}, +static arc arcs_31_2[1] = { + {23, 3}, +}; +static arc arcs_31_3[1] = { + {0, 3}, }; -static state states_31[3] = { +static state states_31[4] = { {1, arcs_31_0}, {2, arcs_31_1}, - {2, arcs_31_2}, + {1, arcs_31_2}, + {1, arcs_31_3}, }; static arc arcs_32_0[1] = { - {83, 1}, + {84, 1}, }; static arc arcs_32_1[2] = { - {30, 0}, + {32, 2}, {0, 1}, }; -static state states_32[2] = { +static arc arcs_32_2[2] = { + {84, 1}, + {0, 2}, +}; +static state states_32[3] = { {1, arcs_32_0}, {2, arcs_32_1}, + {2, arcs_32_2}, }; static arc arcs_33_0[1] = { - {21, 1}, + {86, 1}, }; static arc arcs_33_1[2] = { - {78, 0}, + {32, 0}, {0, 1}, }; static state states_33[2] = { @@ -747,28 +766,24 @@ static state states_33[2] = { {2, arcs_33_1}, }; static arc arcs_34_0[1] = { - {84, 1}, -}; -static arc arcs_34_1[1] = { - {21, 2}, + {23, 1}, }; -static arc arcs_34_2[2] = { - {30, 1}, - {0, 2}, +static arc arcs_34_1[2] = { + {81, 0}, + {0, 1}, }; -static state states_34[3] = { +static state states_34[2] = { {1, arcs_34_0}, - {1, arcs_34_1}, - {2, arcs_34_2}, + {2, arcs_34_1}, }; static arc arcs_35_0[1] = { - {85, 1}, + {87, 1}, }; static arc arcs_35_1[1] = { - {21, 2}, + {23, 2}, }; static arc arcs_35_2[2] = { - {30, 1}, + {32, 1}, {0, 2}, }; static state states_35[3] = { @@ -777,504 +792,514 @@ static state states_35[3] = { {2, arcs_35_2}, }; static arc arcs_36_0[1] = { - {86, 1}, + {88, 1}, }; static arc arcs_36_1[1] = { - {24, 2}, + {23, 2}, }; static arc arcs_36_2[2] = { - {30, 3}, + {32, 1}, {0, 2}, }; -static arc arcs_36_3[1] = { - {24, 4}, -}; -static arc arcs_36_4[1] = { - {0, 4}, -}; -static state states_36[5] = { +static state states_36[3] = { {1, arcs_36_0}, {1, arcs_36_1}, {2, arcs_36_2}, - {1, arcs_36_3}, - {1, arcs_36_4}, }; -static arc arcs_37_0[8] = { - {87, 1}, - {88, 1}, +static arc arcs_37_0[1] = { {89, 1}, - {90, 1}, - {91, 1}, - {19, 1}, - {18, 1}, - {17, 1}, }; static arc arcs_37_1[1] = { - {0, 1}, -}; -static state states_37[2] = { - {8, arcs_37_0}, - {1, arcs_37_1}, -}; -static arc arcs_38_0[1] = { - {92, 1}, + {26, 2}, }; -static arc arcs_38_1[1] = { - {24, 2}, -}; -static arc arcs_38_2[1] = { - {25, 3}, +static arc arcs_37_2[2] = { + {32, 3}, + {0, 2}, }; -static arc arcs_38_3[1] = { +static arc arcs_37_3[1] = { {26, 4}, }; -static arc arcs_38_4[3] = { - {93, 1}, - {94, 5}, +static arc arcs_37_4[1] = { {0, 4}, }; -static arc arcs_38_5[1] = { - {25, 6}, +static state states_37[5] = { + {1, arcs_37_0}, + {1, arcs_37_1}, + {2, arcs_37_2}, + {1, arcs_37_3}, + {1, arcs_37_4}, }; -static arc arcs_38_6[1] = { - {26, 7}, +static arc arcs_38_0[9] = { + {90, 1}, + {91, 1}, + {92, 1}, + {93, 1}, + {94, 1}, + {19, 1}, + {18, 1}, + {17, 1}, + {95, 1}, }; -static arc arcs_38_7[1] = { - {0, 7}, +static arc arcs_38_1[1] = { + {0, 1}, }; -static state states_38[8] = { - {1, arcs_38_0}, +static state states_38[2] = { + {9, arcs_38_0}, {1, arcs_38_1}, - {1, arcs_38_2}, - {1, arcs_38_3}, - {3, arcs_38_4}, - {1, arcs_38_5}, - {1, arcs_38_6}, - {1, arcs_38_7}, }; static arc arcs_39_0[1] = { - {95, 1}, + {21, 1}, }; -static arc arcs_39_1[1] = { - {24, 2}, +static arc arcs_39_1[3] = { + {19, 2}, + {94, 2}, + {92, 2}, }; static arc arcs_39_2[1] = { - {25, 3}, -}; -static arc arcs_39_3[1] = { - {26, 4}, -}; -static arc arcs_39_4[2] = { - {94, 5}, - {0, 4}, -}; -static arc arcs_39_5[1] = { - {25, 6}, -}; -static arc arcs_39_6[1] = { - {26, 7}, -}; -static arc arcs_39_7[1] = { - {0, 7}, + {0, 2}, }; -static state states_39[8] = { +static state states_39[3] = { {1, arcs_39_0}, - {1, arcs_39_1}, + {3, arcs_39_1}, {1, arcs_39_2}, - {1, arcs_39_3}, - {2, arcs_39_4}, - {1, arcs_39_5}, - {1, arcs_39_6}, - {1, arcs_39_7}, }; static arc arcs_40_0[1] = { {96, 1}, }; static arc arcs_40_1[1] = { - {62, 2}, + {26, 2}, }; static arc arcs_40_2[1] = { - {97, 3}, + {27, 3}, }; static arc arcs_40_3[1] = { - {9, 4}, + {28, 4}, }; -static arc arcs_40_4[1] = { - {25, 5}, +static arc arcs_40_4[3] = { + {97, 1}, + {98, 5}, + {0, 4}, }; static arc arcs_40_5[1] = { - {26, 6}, + {27, 6}, }; -static arc arcs_40_6[2] = { - {94, 7}, - {0, 6}, +static arc arcs_40_6[1] = { + {28, 7}, }; static arc arcs_40_7[1] = { - {25, 8}, -}; -static arc arcs_40_8[1] = { - {26, 9}, -}; -static arc arcs_40_9[1] = { - {0, 9}, + {0, 7}, }; -static state states_40[10] = { +static state states_40[8] = { {1, arcs_40_0}, {1, arcs_40_1}, {1, arcs_40_2}, {1, arcs_40_3}, - {1, arcs_40_4}, + {3, arcs_40_4}, {1, arcs_40_5}, - {2, arcs_40_6}, + {1, arcs_40_6}, {1, arcs_40_7}, - {1, arcs_40_8}, - {1, arcs_40_9}, }; static arc arcs_41_0[1] = { - {98, 1}, + {99, 1}, }; static arc arcs_41_1[1] = { - {25, 2}, + {26, 2}, }; static arc arcs_41_2[1] = { - {26, 3}, + {27, 3}, }; -static arc arcs_41_3[2] = { - {99, 4}, - {100, 5}, +static arc arcs_41_3[1] = { + {28, 4}, }; -static arc arcs_41_4[1] = { - {25, 6}, +static arc arcs_41_4[2] = { + {98, 5}, + {0, 4}, }; static arc arcs_41_5[1] = { - {25, 7}, + {27, 6}, }; static arc arcs_41_6[1] = { - {26, 8}, + {28, 7}, }; static arc arcs_41_7[1] = { - {26, 9}, -}; -static arc arcs_41_8[4] = { - {99, 4}, - {94, 10}, - {100, 5}, - {0, 8}, -}; -static arc arcs_41_9[1] = { - {0, 9}, -}; -static arc arcs_41_10[1] = { - {25, 11}, -}; -static arc arcs_41_11[1] = { - {26, 12}, -}; -static arc arcs_41_12[2] = { - {100, 5}, - {0, 12}, + {0, 7}, }; -static state states_41[13] = { +static state states_41[8] = { {1, arcs_41_0}, {1, arcs_41_1}, {1, arcs_41_2}, - {2, arcs_41_3}, - {1, arcs_41_4}, + {1, arcs_41_3}, + {2, arcs_41_4}, {1, arcs_41_5}, {1, arcs_41_6}, {1, arcs_41_7}, - {4, arcs_41_8}, - {1, arcs_41_9}, - {1, arcs_41_10}, - {1, arcs_41_11}, - {2, arcs_41_12}, }; static arc arcs_42_0[1] = { - {101, 1}, + {100, 1}, }; static arc arcs_42_1[1] = { - {102, 2}, + {65, 2}, }; -static arc arcs_42_2[2] = { - {30, 1}, - {25, 3}, +static arc arcs_42_2[1] = { + {101, 3}, }; static arc arcs_42_3[1] = { - {26, 4}, + {9, 4}, }; static arc arcs_42_4[1] = { - {0, 4}, + {27, 5}, +}; +static arc arcs_42_5[1] = { + {28, 6}, +}; +static arc arcs_42_6[2] = { + {98, 7}, + {0, 6}, }; -static state states_42[5] = { +static arc arcs_42_7[1] = { + {27, 8}, +}; +static arc arcs_42_8[1] = { + {28, 9}, +}; +static arc arcs_42_9[1] = { + {0, 9}, +}; +static state states_42[10] = { {1, arcs_42_0}, {1, arcs_42_1}, - {2, arcs_42_2}, + {1, arcs_42_2}, {1, arcs_42_3}, {1, arcs_42_4}, + {1, arcs_42_5}, + {2, arcs_42_6}, + {1, arcs_42_7}, + {1, arcs_42_8}, + {1, arcs_42_9}, }; static arc arcs_43_0[1] = { - {24, 1}, + {102, 1}, }; -static arc arcs_43_1[2] = { - {82, 2}, - {0, 1}, +static arc arcs_43_1[1] = { + {27, 2}, }; static arc arcs_43_2[1] = { - {103, 3}, + {28, 3}, }; -static arc arcs_43_3[1] = { - {0, 3}, +static arc arcs_43_3[2] = { + {103, 4}, + {104, 5}, +}; +static arc arcs_43_4[1] = { + {27, 6}, +}; +static arc arcs_43_5[1] = { + {27, 7}, +}; +static arc arcs_43_6[1] = { + {28, 8}, +}; +static arc arcs_43_7[1] = { + {28, 9}, +}; +static arc arcs_43_8[4] = { + {103, 4}, + {98, 10}, + {104, 5}, + {0, 8}, +}; +static arc arcs_43_9[1] = { + {0, 9}, +}; +static arc arcs_43_10[1] = { + {27, 11}, +}; +static arc arcs_43_11[1] = { + {28, 12}, +}; +static arc arcs_43_12[2] = { + {104, 5}, + {0, 12}, }; -static state states_43[4] = { +static state states_43[13] = { {1, arcs_43_0}, - {2, arcs_43_1}, + {1, arcs_43_1}, {1, arcs_43_2}, - {1, arcs_43_3}, + {2, arcs_43_3}, + {1, arcs_43_4}, + {1, arcs_43_5}, + {1, arcs_43_6}, + {1, arcs_43_7}, + {4, arcs_43_8}, + {1, arcs_43_9}, + {1, arcs_43_10}, + {1, arcs_43_11}, + {2, arcs_43_12}, }; static arc arcs_44_0[1] = { - {104, 1}, + {105, 1}, }; -static arc arcs_44_1[2] = { - {24, 2}, - {0, 1}, +static arc arcs_44_1[1] = { + {106, 2}, }; static arc arcs_44_2[2] = { - {82, 3}, - {0, 2}, + {32, 1}, + {27, 3}, }; static arc arcs_44_3[1] = { - {21, 4}, + {28, 4}, }; static arc arcs_44_4[1] = { {0, 4}, }; static state states_44[5] = { {1, arcs_44_0}, - {2, arcs_44_1}, + {1, arcs_44_1}, {2, arcs_44_2}, {1, arcs_44_3}, {1, arcs_44_4}, }; -static arc arcs_45_0[2] = { - {3, 1}, - {2, 2}, +static arc arcs_45_0[1] = { + {26, 1}, }; -static arc arcs_45_1[1] = { +static arc arcs_45_1[2] = { + {85, 2}, {0, 1}, }; static arc arcs_45_2[1] = { - {105, 3}, + {107, 3}, }; static arc arcs_45_3[1] = { - {6, 4}, -}; -static arc arcs_45_4[2] = { - {6, 4}, - {106, 1}, + {0, 3}, }; -static state states_45[5] = { - {2, arcs_45_0}, - {1, arcs_45_1}, +static state states_45[4] = { + {1, arcs_45_0}, + {2, arcs_45_1}, {1, arcs_45_2}, {1, arcs_45_3}, - {2, arcs_45_4}, }; -static arc arcs_46_0[2] = { - {107, 1}, - {108, 2}, +static arc arcs_46_0[1] = { + {108, 1}, }; static arc arcs_46_1[2] = { - {92, 3}, + {26, 2}, {0, 1}, }; -static arc arcs_46_2[1] = { +static arc arcs_46_2[2] = { + {85, 3}, {0, 2}, }; static arc arcs_46_3[1] = { - {107, 4}, + {23, 4}, }; static arc arcs_46_4[1] = { - {94, 5}, -}; -static arc arcs_46_5[1] = { - {24, 2}, + {0, 4}, }; -static state states_46[6] = { - {2, arcs_46_0}, +static state states_46[5] = { + {1, arcs_46_0}, {2, arcs_46_1}, - {1, arcs_46_2}, + {2, arcs_46_2}, {1, arcs_46_3}, {1, arcs_46_4}, - {1, arcs_46_5}, }; static arc arcs_47_0[2] = { - {107, 1}, - {110, 1}, + {3, 1}, + {2, 2}, }; static arc arcs_47_1[1] = { {0, 1}, }; -static state states_47[2] = { +static arc arcs_47_2[1] = { + {109, 3}, +}; +static arc arcs_47_3[1] = { + {6, 4}, +}; +static arc arcs_47_4[2] = { + {6, 4}, + {110, 1}, +}; +static state states_47[5] = { {2, arcs_47_0}, {1, arcs_47_1}, + {1, arcs_47_2}, + {1, arcs_47_3}, + {2, arcs_47_4}, }; -static arc arcs_48_0[1] = { +static arc arcs_48_0[2] = { {111, 1}, + {112, 2}, }; static arc arcs_48_1[2] = { - {33, 2}, - {25, 3}, + {96, 3}, + {0, 1}, }; static arc arcs_48_2[1] = { - {25, 3}, + {0, 2}, }; static arc arcs_48_3[1] = { - {24, 4}, + {111, 4}, }; static arc arcs_48_4[1] = { - {0, 4}, + {98, 5}, +}; +static arc arcs_48_5[1] = { + {26, 2}, }; -static state states_48[5] = { - {1, arcs_48_0}, +static state states_48[6] = { + {2, arcs_48_0}, {2, arcs_48_1}, {1, arcs_48_2}, {1, arcs_48_3}, {1, arcs_48_4}, + {1, arcs_48_5}, }; -static arc arcs_49_0[1] = { +static arc arcs_49_0[2] = { {111, 1}, + {114, 1}, }; -static arc arcs_49_1[2] = { - {33, 2}, - {25, 3}, +static arc arcs_49_1[1] = { + {0, 1}, }; -static arc arcs_49_2[1] = { - {25, 3}, +static state states_49[2] = { + {2, arcs_49_0}, + {1, arcs_49_1}, }; -static arc arcs_49_3[1] = { - {109, 4}, +static arc arcs_50_0[1] = { + {115, 1}, }; -static arc arcs_49_4[1] = { - {0, 4}, +static arc arcs_50_1[2] = { + {35, 2}, + {27, 3}, }; -static state states_49[5] = { - {1, arcs_49_0}, - {2, arcs_49_1}, - {1, arcs_49_2}, - {1, arcs_49_3}, - {1, arcs_49_4}, +static arc arcs_50_2[1] = { + {27, 3}, }; -static arc arcs_50_0[1] = { - {112, 1}, +static arc arcs_50_3[1] = { + {26, 4}, }; -static arc arcs_50_1[2] = { - {113, 0}, - {0, 1}, +static arc arcs_50_4[1] = { + {0, 4}, }; -static state states_50[2] = { +static state states_50[5] = { {1, arcs_50_0}, {2, arcs_50_1}, + {1, arcs_50_2}, + {1, arcs_50_3}, + {1, arcs_50_4}, }; static arc arcs_51_0[1] = { - {114, 1}, + {115, 1}, }; static arc arcs_51_1[2] = { - {115, 0}, - {0, 1}, + {35, 2}, + {27, 3}, }; -static state states_51[2] = { +static arc arcs_51_2[1] = { + {27, 3}, +}; +static arc arcs_51_3[1] = { + {113, 4}, +}; +static arc arcs_51_4[1] = { + {0, 4}, +}; +static state states_51[5] = { {1, arcs_51_0}, {2, arcs_51_1}, + {1, arcs_51_2}, + {1, arcs_51_3}, + {1, arcs_51_4}, }; -static arc arcs_52_0[2] = { +static arc arcs_52_0[1] = { {116, 1}, - {117, 2}, -}; -static arc arcs_52_1[1] = { - {114, 2}, }; -static arc arcs_52_2[1] = { - {0, 2}, +static arc arcs_52_1[2] = { + {117, 0}, + {0, 1}, }; -static state states_52[3] = { - {2, arcs_52_0}, - {1, arcs_52_1}, - {1, arcs_52_2}, +static state states_52[2] = { + {1, arcs_52_0}, + {2, arcs_52_1}, }; static arc arcs_53_0[1] = { - {103, 1}, + {118, 1}, }; static arc arcs_53_1[2] = { - {118, 0}, + {119, 0}, {0, 1}, }; static state states_53[2] = { {1, arcs_53_0}, {2, arcs_53_1}, }; -static arc arcs_54_0[10] = { - {119, 1}, +static arc arcs_54_0[2] = { {120, 1}, - {121, 1}, - {122, 1}, - {123, 1}, - {124, 1}, - {125, 1}, - {97, 1}, - {116, 2}, - {126, 3}, + {121, 2}, }; static arc arcs_54_1[1] = { - {0, 1}, + {118, 2}, }; static arc arcs_54_2[1] = { - {97, 1}, -}; -static arc arcs_54_3[2] = { - {116, 1}, - {0, 3}, + {0, 2}, }; -static state states_54[4] = { - {10, arcs_54_0}, +static state states_54[3] = { + {2, arcs_54_0}, {1, arcs_54_1}, {1, arcs_54_2}, - {2, arcs_54_3}, }; static arc arcs_55_0[1] = { - {31, 1}, -}; -static arc arcs_55_1[1] = { - {103, 2}, + {107, 1}, }; -static arc arcs_55_2[1] = { - {0, 2}, +static arc arcs_55_1[2] = { + {122, 0}, + {0, 1}, }; -static state states_55[3] = { +static state states_55[2] = { {1, arcs_55_0}, - {1, arcs_55_1}, - {1, arcs_55_2}, + {2, arcs_55_1}, }; -static arc arcs_56_0[1] = { +static arc arcs_56_0[10] = { + {123, 1}, + {124, 1}, + {125, 1}, + {126, 1}, {127, 1}, + {128, 1}, + {129, 1}, + {101, 1}, + {120, 2}, + {130, 3}, }; -static arc arcs_56_1[2] = { - {128, 0}, +static arc arcs_56_1[1] = { {0, 1}, }; -static state states_56[2] = { - {1, arcs_56_0}, - {2, arcs_56_1}, +static arc arcs_56_2[1] = { + {101, 1}, +}; +static arc arcs_56_3[2] = { + {120, 1}, + {0, 3}, +}; +static state states_56[4] = { + {10, arcs_56_0}, + {1, arcs_56_1}, + {1, arcs_56_2}, + {2, arcs_56_3}, }; static arc arcs_57_0[1] = { - {129, 1}, + {33, 1}, }; -static arc arcs_57_1[2] = { - {130, 0}, - {0, 1}, +static arc arcs_57_1[1] = { + {107, 2}, +}; +static arc arcs_57_2[1] = { + {0, 2}, }; -static state states_57[2] = { +static state states_57[3] = { {1, arcs_57_0}, - {2, arcs_57_1}, + {1, arcs_57_1}, + {1, arcs_57_2}, }; static arc arcs_58_0[1] = { {131, 1}, @@ -1290,752 +1315,793 @@ static state states_58[2] = { static arc arcs_59_0[1] = { {133, 1}, }; -static arc arcs_59_1[3] = { +static arc arcs_59_1[2] = { {134, 0}, - {135, 0}, {0, 1}, }; static state states_59[2] = { {1, arcs_59_0}, - {3, arcs_59_1}, + {2, arcs_59_1}, }; static arc arcs_60_0[1] = { - {136, 1}, + {135, 1}, }; -static arc arcs_60_1[3] = { - {137, 0}, - {138, 0}, +static arc arcs_60_1[2] = { + {136, 0}, {0, 1}, }; static state states_60[2] = { {1, arcs_60_0}, - {3, arcs_60_1}, + {2, arcs_60_1}, }; static arc arcs_61_0[1] = { - {139, 1}, + {137, 1}, }; -static arc arcs_61_1[5] = { - {31, 0}, - {140, 0}, - {141, 0}, - {142, 0}, +static arc arcs_61_1[3] = { + {138, 0}, + {139, 0}, {0, 1}, }; static state states_61[2] = { {1, arcs_61_0}, - {5, arcs_61_1}, + {3, arcs_61_1}, }; -static arc arcs_62_0[4] = { - {137, 1}, - {138, 1}, +static arc arcs_62_0[1] = { + {140, 1}, +}; +static arc arcs_62_1[3] = { + {141, 0}, + {142, 0}, + {0, 1}, +}; +static state states_62[2] = { + {1, arcs_62_0}, + {3, arcs_62_1}, +}; +static arc arcs_63_0[1] = { {143, 1}, - {144, 2}, }; -static arc arcs_62_1[1] = { - {139, 2}, +static arc arcs_63_1[6] = { + {33, 0}, + {11, 0}, + {144, 0}, + {145, 0}, + {146, 0}, + {0, 1}, }; -static arc arcs_62_2[1] = { +static state states_63[2] = { + {1, arcs_63_0}, + {6, arcs_63_1}, +}; +static arc arcs_64_0[4] = { + {141, 1}, + {142, 1}, + {147, 1}, + {148, 2}, +}; +static arc arcs_64_1[1] = { + {143, 2}, +}; +static arc arcs_64_2[1] = { {0, 2}, }; -static state states_62[3] = { - {4, arcs_62_0}, - {1, arcs_62_1}, - {1, arcs_62_2}, +static state states_64[3] = { + {4, arcs_64_0}, + {1, arcs_64_1}, + {1, arcs_64_2}, }; -static arc arcs_63_0[1] = { - {145, 1}, +static arc arcs_65_0[1] = { + {149, 1}, }; -static arc arcs_63_1[3] = { - {146, 1}, - {32, 2}, +static arc arcs_65_1[2] = { + {34, 2}, {0, 1}, }; -static arc arcs_63_2[1] = { - {139, 3}, +static arc arcs_65_2[1] = { + {143, 3}, }; -static arc arcs_63_3[1] = { +static arc arcs_65_3[1] = { {0, 3}, }; -static state states_63[4] = { - {1, arcs_63_0}, - {3, arcs_63_1}, - {1, arcs_63_2}, - {1, arcs_63_3}, +static state states_65[4] = { + {1, arcs_65_0}, + {2, arcs_65_1}, + {1, arcs_65_2}, + {1, arcs_65_3}, +}; +static arc arcs_66_0[2] = { + {150, 1}, + {151, 2}, }; -static arc arcs_64_0[10] = { +static arc arcs_66_1[1] = { + {151, 2}, +}; +static arc arcs_66_2[2] = { + {152, 2}, + {0, 2}, +}; +static state states_66[3] = { + {2, arcs_66_0}, + {1, arcs_66_1}, + {2, arcs_66_2}, +}; +static arc arcs_67_0[10] = { {13, 1}, - {148, 2}, - {150, 3}, - {21, 4}, - {153, 4}, - {154, 5}, - {79, 4}, - {155, 4}, - {156, 4}, - {157, 4}, + {154, 2}, + {156, 3}, + {23, 4}, + {159, 4}, + {160, 5}, + {82, 4}, + {161, 4}, + {162, 4}, + {163, 4}, }; -static arc arcs_64_1[3] = { - {47, 6}, - {147, 6}, +static arc arcs_67_1[3] = { + {49, 6}, + {153, 6}, {15, 4}, }; -static arc arcs_64_2[2] = { - {147, 7}, - {149, 4}, +static arc arcs_67_2[2] = { + {153, 7}, + {155, 4}, }; -static arc arcs_64_3[2] = { - {151, 8}, - {152, 4}, +static arc arcs_67_3[2] = { + {157, 8}, + {158, 4}, }; -static arc arcs_64_4[1] = { +static arc arcs_67_4[1] = { {0, 4}, }; -static arc arcs_64_5[2] = { - {154, 5}, +static arc arcs_67_5[2] = { + {160, 5}, {0, 5}, }; -static arc arcs_64_6[1] = { +static arc arcs_67_6[1] = { {15, 4}, }; -static arc arcs_64_7[1] = { - {149, 4}, -}; -static arc arcs_64_8[1] = { - {152, 4}, -}; -static state states_64[9] = { - {10, arcs_64_0}, - {3, arcs_64_1}, - {2, arcs_64_2}, - {2, arcs_64_3}, - {1, arcs_64_4}, - {2, arcs_64_5}, - {1, arcs_64_6}, - {1, arcs_64_7}, - {1, arcs_64_8}, -}; -static arc arcs_65_0[2] = { - {24, 1}, - {48, 1}, -}; -static arc arcs_65_1[3] = { - {158, 2}, - {30, 3}, +static arc arcs_67_7[1] = { + {155, 4}, +}; +static arc arcs_67_8[1] = { + {158, 4}, +}; +static state states_67[9] = { + {10, arcs_67_0}, + {3, arcs_67_1}, + {2, arcs_67_2}, + {2, arcs_67_3}, + {1, arcs_67_4}, + {2, arcs_67_5}, + {1, arcs_67_6}, + {1, arcs_67_7}, + {1, arcs_67_8}, +}; +static arc arcs_68_0[2] = { + {26, 1}, + {50, 1}, +}; +static arc arcs_68_1[3] = { + {164, 2}, + {32, 3}, {0, 1}, }; -static arc arcs_65_2[1] = { +static arc arcs_68_2[1] = { {0, 2}, }; -static arc arcs_65_3[3] = { - {24, 4}, - {48, 4}, +static arc arcs_68_3[3] = { + {26, 4}, + {50, 4}, {0, 3}, }; -static arc arcs_65_4[2] = { - {30, 3}, +static arc arcs_68_4[2] = { + {32, 3}, {0, 4}, }; -static state states_65[5] = { - {2, arcs_65_0}, - {3, arcs_65_1}, - {1, arcs_65_2}, - {3, arcs_65_3}, - {2, arcs_65_4}, +static state states_68[5] = { + {2, arcs_68_0}, + {3, arcs_68_1}, + {1, arcs_68_2}, + {3, arcs_68_3}, + {2, arcs_68_4}, }; -static arc arcs_66_0[3] = { +static arc arcs_69_0[3] = { {13, 1}, - {148, 2}, - {78, 3}, + {154, 2}, + {81, 3}, }; -static arc arcs_66_1[2] = { +static arc arcs_69_1[2] = { {14, 4}, {15, 5}, }; -static arc arcs_66_2[1] = { - {159, 6}, +static arc arcs_69_2[1] = { + {165, 6}, }; -static arc arcs_66_3[1] = { - {21, 5}, +static arc arcs_69_3[1] = { + {23, 5}, }; -static arc arcs_66_4[1] = { +static arc arcs_69_4[1] = { {15, 5}, }; -static arc arcs_66_5[1] = { +static arc arcs_69_5[1] = { {0, 5}, }; -static arc arcs_66_6[1] = { - {149, 5}, +static arc arcs_69_6[1] = { + {155, 5}, }; -static state states_66[7] = { - {3, arcs_66_0}, - {2, arcs_66_1}, - {1, arcs_66_2}, - {1, arcs_66_3}, - {1, arcs_66_4}, - {1, arcs_66_5}, - {1, arcs_66_6}, +static state states_69[7] = { + {3, arcs_69_0}, + {2, arcs_69_1}, + {1, arcs_69_2}, + {1, arcs_69_3}, + {1, arcs_69_4}, + {1, arcs_69_5}, + {1, arcs_69_6}, }; -static arc arcs_67_0[1] = { - {160, 1}, +static arc arcs_70_0[1] = { + {166, 1}, }; -static arc arcs_67_1[2] = { - {30, 2}, +static arc arcs_70_1[2] = { + {32, 2}, {0, 1}, }; -static arc arcs_67_2[2] = { - {160, 1}, +static arc arcs_70_2[2] = { + {166, 1}, {0, 2}, }; -static state states_67[3] = { - {1, arcs_67_0}, - {2, arcs_67_1}, - {2, arcs_67_2}, +static state states_70[3] = { + {1, arcs_70_0}, + {2, arcs_70_1}, + {2, arcs_70_2}, }; -static arc arcs_68_0[2] = { - {24, 1}, - {25, 2}, +static arc arcs_71_0[2] = { + {26, 1}, + {27, 2}, }; -static arc arcs_68_1[2] = { - {25, 2}, +static arc arcs_71_1[2] = { + {27, 2}, {0, 1}, }; -static arc arcs_68_2[3] = { - {24, 3}, - {161, 4}, +static arc arcs_71_2[3] = { + {26, 3}, + {167, 4}, {0, 2}, }; -static arc arcs_68_3[2] = { - {161, 4}, +static arc arcs_71_3[2] = { + {167, 4}, {0, 3}, }; -static arc arcs_68_4[1] = { +static arc arcs_71_4[1] = { {0, 4}, }; -static state states_68[5] = { - {2, arcs_68_0}, - {2, arcs_68_1}, - {3, arcs_68_2}, - {2, arcs_68_3}, - {1, arcs_68_4}, +static state states_71[5] = { + {2, arcs_71_0}, + {2, arcs_71_1}, + {3, arcs_71_2}, + {2, arcs_71_3}, + {1, arcs_71_4}, }; -static arc arcs_69_0[1] = { - {25, 1}, +static arc arcs_72_0[1] = { + {27, 1}, }; -static arc arcs_69_1[2] = { - {24, 2}, +static arc arcs_72_1[2] = { + {26, 2}, {0, 1}, }; -static arc arcs_69_2[1] = { +static arc arcs_72_2[1] = { {0, 2}, }; -static state states_69[3] = { - {1, arcs_69_0}, - {2, arcs_69_1}, - {1, arcs_69_2}, +static state states_72[3] = { + {1, arcs_72_0}, + {2, arcs_72_1}, + {1, arcs_72_2}, }; -static arc arcs_70_0[2] = { - {103, 1}, - {48, 1}, +static arc arcs_73_0[2] = { + {107, 1}, + {50, 1}, }; -static arc arcs_70_1[2] = { - {30, 2}, +static arc arcs_73_1[2] = { + {32, 2}, {0, 1}, }; -static arc arcs_70_2[3] = { - {103, 1}, - {48, 1}, +static arc arcs_73_2[3] = { + {107, 1}, + {50, 1}, {0, 2}, }; -static state states_70[3] = { - {2, arcs_70_0}, - {2, arcs_70_1}, - {3, arcs_70_2}, +static state states_73[3] = { + {2, arcs_73_0}, + {2, arcs_73_1}, + {3, arcs_73_2}, }; -static arc arcs_71_0[1] = { - {24, 1}, +static arc arcs_74_0[1] = { + {26, 1}, }; -static arc arcs_71_1[2] = { - {30, 2}, +static arc arcs_74_1[2] = { + {32, 2}, {0, 1}, }; -static arc arcs_71_2[2] = { - {24, 1}, +static arc arcs_74_2[2] = { + {26, 1}, {0, 2}, }; -static state states_71[3] = { - {1, arcs_71_0}, - {2, arcs_71_1}, - {2, arcs_71_2}, +static state states_74[3] = { + {1, arcs_74_0}, + {2, arcs_74_1}, + {2, arcs_74_2}, }; -static arc arcs_72_0[1] = { - {24, 1}, +static arc arcs_75_0[3] = { + {26, 1}, + {34, 2}, + {50, 3}, }; -static arc arcs_72_1[4] = { - {25, 2}, - {158, 3}, - {30, 4}, +static arc arcs_75_1[4] = { + {27, 4}, + {164, 5}, + {32, 6}, {0, 1}, }; -static arc arcs_72_2[1] = { - {24, 5}, +static arc arcs_75_2[1] = { + {107, 7}, }; -static arc arcs_72_3[1] = { +static arc arcs_75_3[3] = { + {164, 5}, + {32, 6}, {0, 3}, }; -static arc arcs_72_4[2] = { - {24, 6}, - {0, 4}, +static arc arcs_75_4[1] = { + {26, 7}, }; -static arc arcs_72_5[3] = { - {158, 3}, - {30, 7}, +static arc arcs_75_5[1] = { {0, 5}, }; -static arc arcs_72_6[2] = { - {30, 4}, +static arc arcs_75_6[3] = { + {26, 8}, + {50, 8}, {0, 6}, }; -static arc arcs_72_7[2] = { - {24, 8}, +static arc arcs_75_7[3] = { + {164, 5}, + {32, 9}, {0, 7}, }; -static arc arcs_72_8[1] = { - {25, 9}, +static arc arcs_75_8[2] = { + {32, 6}, + {0, 8}, }; -static arc arcs_72_9[1] = { - {24, 10}, +static arc arcs_75_9[3] = { + {26, 10}, + {34, 11}, + {0, 9}, }; -static arc arcs_72_10[2] = { - {30, 7}, - {0, 10}, +static arc arcs_75_10[1] = { + {27, 12}, }; -static state states_72[11] = { - {1, arcs_72_0}, - {4, arcs_72_1}, - {1, arcs_72_2}, - {1, arcs_72_3}, - {2, arcs_72_4}, - {3, arcs_72_5}, - {2, arcs_72_6}, - {2, arcs_72_7}, - {1, arcs_72_8}, - {1, arcs_72_9}, - {2, arcs_72_10}, -}; -static arc arcs_73_0[1] = { - {162, 1}, -}; -static arc arcs_73_1[1] = { - {21, 2}, -}; -static arc arcs_73_2[2] = { +static arc arcs_75_11[1] = { + {107, 13}, +}; +static arc arcs_75_12[1] = { + {26, 13}, +}; +static arc arcs_75_13[2] = { + {32, 9}, + {0, 13}, +}; +static state states_75[14] = { + {3, arcs_75_0}, + {4, arcs_75_1}, + {1, arcs_75_2}, + {3, arcs_75_3}, + {1, arcs_75_4}, + {1, arcs_75_5}, + {3, arcs_75_6}, + {3, arcs_75_7}, + {2, arcs_75_8}, + {3, arcs_75_9}, + {1, arcs_75_10}, + {1, arcs_75_11}, + {1, arcs_75_12}, + {2, arcs_75_13}, +}; +static arc arcs_76_0[1] = { + {168, 1}, +}; +static arc arcs_76_1[1] = { + {23, 2}, +}; +static arc arcs_76_2[2] = { {13, 3}, - {25, 4}, + {27, 4}, }; -static arc arcs_73_3[2] = { +static arc arcs_76_3[2] = { {14, 5}, {15, 6}, }; -static arc arcs_73_4[1] = { - {26, 7}, +static arc arcs_76_4[1] = { + {28, 7}, }; -static arc arcs_73_5[1] = { +static arc arcs_76_5[1] = { {15, 6}, }; -static arc arcs_73_6[1] = { - {25, 4}, +static arc arcs_76_6[1] = { + {27, 4}, }; -static arc arcs_73_7[1] = { +static arc arcs_76_7[1] = { {0, 7}, }; -static state states_73[8] = { - {1, arcs_73_0}, - {1, arcs_73_1}, - {2, arcs_73_2}, - {2, arcs_73_3}, - {1, arcs_73_4}, - {1, arcs_73_5}, - {1, arcs_73_6}, - {1, arcs_73_7}, -}; -static arc arcs_74_0[3] = { - {163, 1}, - {31, 2}, - {32, 3}, -}; -static arc arcs_74_1[2] = { - {30, 4}, - {0, 1}, -}; -static arc arcs_74_2[1] = { - {24, 5}, +static state states_76[8] = { + {1, arcs_76_0}, + {1, arcs_76_1}, + {2, arcs_76_2}, + {2, arcs_76_3}, + {1, arcs_76_4}, + {1, arcs_76_5}, + {1, arcs_76_6}, + {1, arcs_76_7}, }; -static arc arcs_74_3[1] = { - {24, 6}, +static arc arcs_77_0[1] = { + {169, 1}, }; -static arc arcs_74_4[4] = { - {163, 1}, - {31, 2}, - {32, 3}, - {0, 4}, +static arc arcs_77_1[2] = { + {32, 2}, + {0, 1}, }; -static arc arcs_74_5[2] = { - {30, 7}, - {0, 5}, +static arc arcs_77_2[2] = { + {169, 1}, + {0, 2}, }; -static arc arcs_74_6[1] = { - {0, 6}, +static state states_77[3] = { + {1, arcs_77_0}, + {2, arcs_77_1}, + {2, arcs_77_2}, }; -static arc arcs_74_7[2] = { - {163, 5}, - {32, 3}, +static arc arcs_78_0[3] = { + {26, 1}, + {34, 2}, + {33, 2}, }; -static state states_74[8] = { - {3, arcs_74_0}, - {2, arcs_74_1}, - {1, arcs_74_2}, - {1, arcs_74_3}, - {4, arcs_74_4}, - {2, arcs_74_5}, - {1, arcs_74_6}, - {2, arcs_74_7}, -}; -static arc arcs_75_0[1] = { - {24, 1}, -}; -static arc arcs_75_1[3] = { - {158, 2}, - {29, 3}, +static arc arcs_78_1[3] = { + {164, 3}, + {31, 2}, {0, 1}, }; -static arc arcs_75_2[1] = { - {0, 2}, +static arc arcs_78_2[1] = { + {26, 3}, }; -static arc arcs_75_3[1] = { - {24, 2}, +static arc arcs_78_3[1] = { + {0, 3}, }; -static state states_75[4] = { - {1, arcs_75_0}, - {3, arcs_75_1}, - {1, arcs_75_2}, - {1, arcs_75_3}, +static state states_78[4] = { + {3, arcs_78_0}, + {3, arcs_78_1}, + {1, arcs_78_2}, + {1, arcs_78_3}, }; -static arc arcs_76_0[2] = { - {158, 1}, - {165, 1}, +static arc arcs_79_0[2] = { + {164, 1}, + {171, 1}, }; -static arc arcs_76_1[1] = { +static arc arcs_79_1[1] = { {0, 1}, }; -static state states_76[2] = { - {2, arcs_76_0}, - {1, arcs_76_1}, +static state states_79[2] = { + {2, arcs_79_0}, + {1, arcs_79_1}, }; -static arc arcs_77_0[1] = { - {96, 1}, +static arc arcs_80_0[1] = { + {100, 1}, }; -static arc arcs_77_1[1] = { - {62, 2}, +static arc arcs_80_1[1] = { + {65, 2}, }; -static arc arcs_77_2[1] = { - {97, 3}, +static arc arcs_80_2[1] = { + {101, 3}, }; -static arc arcs_77_3[1] = { - {107, 4}, +static arc arcs_80_3[1] = { + {111, 4}, }; -static arc arcs_77_4[2] = { - {164, 5}, +static arc arcs_80_4[2] = { + {170, 5}, {0, 4}, }; -static arc arcs_77_5[1] = { +static arc arcs_80_5[1] = { {0, 5}, }; -static state states_77[6] = { - {1, arcs_77_0}, - {1, arcs_77_1}, - {1, arcs_77_2}, - {1, arcs_77_3}, - {2, arcs_77_4}, - {1, arcs_77_5}, +static state states_80[6] = { + {1, arcs_80_0}, + {1, arcs_80_1}, + {1, arcs_80_2}, + {1, arcs_80_3}, + {2, arcs_80_4}, + {1, arcs_80_5}, }; -static arc arcs_78_0[1] = { - {92, 1}, +static arc arcs_81_0[1] = { + {96, 1}, }; -static arc arcs_78_1[1] = { - {109, 2}, +static arc arcs_81_1[1] = { + {113, 2}, }; -static arc arcs_78_2[2] = { - {164, 3}, +static arc arcs_81_2[2] = { + {170, 3}, {0, 2}, }; -static arc arcs_78_3[1] = { +static arc arcs_81_3[1] = { {0, 3}, }; -static state states_78[4] = { - {1, arcs_78_0}, - {1, arcs_78_1}, - {2, arcs_78_2}, - {1, arcs_78_3}, +static state states_81[4] = { + {1, arcs_81_0}, + {1, arcs_81_1}, + {2, arcs_81_2}, + {1, arcs_81_3}, }; -static arc arcs_79_0[1] = { - {21, 1}, +static arc arcs_82_0[1] = { + {23, 1}, }; -static arc arcs_79_1[1] = { +static arc arcs_82_1[1] = { {0, 1}, }; -static state states_79[2] = { - {1, arcs_79_0}, - {1, arcs_79_1}, +static state states_82[2] = { + {1, arcs_82_0}, + {1, arcs_82_1}, }; -static arc arcs_80_0[1] = { - {167, 1}, +static arc arcs_83_0[1] = { + {173, 1}, }; -static arc arcs_80_1[2] = { - {168, 2}, +static arc arcs_83_1[2] = { + {174, 2}, {0, 1}, }; -static arc arcs_80_2[1] = { +static arc arcs_83_2[1] = { {0, 2}, }; -static state states_80[3] = { - {1, arcs_80_0}, - {2, arcs_80_1}, - {1, arcs_80_2}, +static state states_83[3] = { + {1, arcs_83_0}, + {2, arcs_83_1}, + {1, arcs_83_2}, }; -static arc arcs_81_0[2] = { - {73, 1}, +static arc arcs_84_0[2] = { + {76, 1}, {9, 2}, }; -static arc arcs_81_1[1] = { - {24, 2}, +static arc arcs_84_1[1] = { + {26, 2}, }; -static arc arcs_81_2[1] = { +static arc arcs_84_2[1] = { {0, 2}, }; -static state states_81[3] = { - {2, arcs_81_0}, - {1, arcs_81_1}, - {1, arcs_81_2}, +static state states_84[3] = { + {2, arcs_84_0}, + {1, arcs_84_1}, + {1, arcs_84_2}, }; -static dfa dfas[82] = { +static dfa dfas[85] = { {256, "single_input", 0, 3, states_0, - "\004\050\060\200\000\000\000\240\340\223\160\220\045\200\020\000\000\206\120\076\204\000"}, + "\004\050\340\000\002\000\000\000\005\237\204\003\131\002\010\001\000\140\110\224\017\041"}, {257, "file_input", 0, 2, states_1, - "\204\050\060\200\000\000\000\240\340\223\160\220\045\200\020\000\000\206\120\076\204\000"}, + "\204\050\340\000\002\000\000\000\005\237\204\003\131\002\010\001\000\140\110\224\017\041"}, {258, "eval_input", 0, 3, states_2, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, + "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, {259, "decorator", 0, 7, states_3, "\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {260, "decorators", 0, 2, states_4, "\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {261, "decorated", 0, 3, states_5, "\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {262, "funcdef", 0, 8, states_6, - "\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {263, "parameters", 0, 4, states_7, - "\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {264, "typedargslist", 0, 18, states_8, - "\000\000\040\200\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {265, "tfpdef", 0, 4, states_9, + {262, "async_funcdef", 0, 3, states_6, "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {266, "varargslist", 0, 18, states_10, - "\000\000\040\200\001\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {267, "vfpdef", 0, 2, states_11, - "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {268, "stmt", 0, 2, states_12, - "\000\050\060\200\000\000\000\240\340\223\160\220\045\200\020\000\000\206\120\076\204\000"}, - {269, "simple_stmt", 0, 4, states_13, - "\000\040\040\200\000\000\000\240\340\223\160\000\000\200\020\000\000\206\120\076\200\000"}, - {270, "small_stmt", 0, 2, states_14, - "\000\040\040\200\000\000\000\240\340\223\160\000\000\200\020\000\000\206\120\076\200\000"}, - {271, "expr_stmt", 0, 6, states_15, - "\000\040\040\200\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, - {272, "testlist_star_expr", 0, 3, states_16, - "\000\040\040\200\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, - {273, "augassign", 0, 2, states_17, - "\000\000\000\000\000\000\376\037\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {274, "del_stmt", 0, 3, states_18, - "\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {275, "pass_stmt", 0, 2, states_19, - "\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {276, "flow_stmt", 0, 2, states_20, - "\000\000\000\000\000\000\000\000\340\001\000\000\000\000\000\000\000\000\000\000\200\000"}, - {277, "break_stmt", 0, 2, states_21, - "\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {278, "continue_stmt", 0, 2, states_22, - "\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {279, "return_stmt", 0, 3, states_23, - "\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {280, "yield_stmt", 0, 2, states_24, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000"}, - {281, "raise_stmt", 0, 5, states_25, + {263, "funcdef", 0, 8, states_7, + "\000\000\100\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {264, "parameters", 0, 4, states_8, + "\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {265, "typedargslist", 0, 19, states_9, + "\000\000\200\000\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {266, "tfpdef", 0, 4, states_10, + "\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {267, "varargslist", 0, 19, states_11, + "\000\000\200\000\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {268, "vfpdef", 0, 2, states_12, + "\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {269, "stmt", 0, 2, states_13, + "\000\050\340\000\002\000\000\000\005\237\204\003\131\002\010\001\000\140\110\224\017\041"}, + {270, "simple_stmt", 0, 4, states_14, + "\000\040\200\000\002\000\000\000\005\237\204\003\000\000\010\001\000\140\110\224\017\040"}, + {271, "small_stmt", 0, 2, states_15, + "\000\040\200\000\002\000\000\000\005\237\204\003\000\000\010\001\000\140\110\224\017\040"}, + {272, "expr_stmt", 0, 6, states_16, + "\000\040\200\000\002\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, + {273, "testlist_star_expr", 0, 3, states_17, + "\000\040\200\000\002\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, + {274, "augassign", 0, 2, states_18, + "\000\000\000\000\000\000\370\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {275, "del_stmt", 0, 3, states_19, + "\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {276, "pass_stmt", 0, 2, states_20, + "\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {277, "flow_stmt", 0, 2, states_21, + "\000\000\000\000\000\000\000\000\000\017\000\000\000\000\000\000\000\000\000\000\000\040"}, + {278, "break_stmt", 0, 2, states_22, "\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000"}, - {282, "import_stmt", 0, 2, states_26, - "\000\000\000\000\000\000\000\000\000\022\000\000\000\000\000\000\000\000\000\000\000\000"}, - {283, "import_name", 0, 3, states_27, - "\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000"}, - {284, "import_from", 0, 8, states_28, + {279, "continue_stmt", 0, 2, states_23, "\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000"}, - {285, "import_as_name", 0, 4, states_29, - "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {286, "dotted_as_name", 0, 4, states_30, - "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {287, "import_as_names", 0, 3, states_31, - "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {288, "dotted_as_names", 0, 2, states_32, - "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {289, "dotted_name", 0, 2, states_33, + {280, "return_stmt", 0, 3, states_24, + "\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000"}, + {281, "yield_stmt", 0, 2, states_25, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\040"}, + {282, "raise_stmt", 0, 5, states_26, + "\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000"}, + {283, "import_stmt", 0, 2, states_27, + "\000\000\000\000\000\000\000\000\000\220\000\000\000\000\000\000\000\000\000\000\000\000"}, + {284, "import_name", 0, 3, states_28, + "\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000"}, + {285, "import_from", 0, 8, states_29, + "\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000"}, + {286, "import_as_name", 0, 4, states_30, + "\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {287, "dotted_as_name", 0, 4, states_31, + "\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {288, "import_as_names", 0, 3, states_32, + "\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {289, "dotted_as_names", 0, 2, states_33, + "\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {290, "dotted_name", 0, 2, states_34, + "\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {291, "global_stmt", 0, 3, states_35, + "\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000"}, + {292, "nonlocal_stmt", 0, 3, states_36, + "\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000"}, + {293, "assert_stmt", 0, 5, states_37, + "\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000"}, + {294, "compound_stmt", 0, 2, states_38, + "\000\010\140\000\000\000\000\000\000\000\000\000\131\002\000\000\000\000\000\000\000\001"}, + {295, "async_stmt", 0, 3, states_39, "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {290, "global_stmt", 0, 3, states_34, - "\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000"}, - {291, "nonlocal_stmt", 0, 3, states_35, - "\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000"}, - {292, "assert_stmt", 0, 5, states_36, - "\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000\000\000"}, - {293, "compound_stmt", 0, 2, states_37, - "\000\010\020\000\000\000\000\000\000\000\000\220\045\000\000\000\000\000\000\000\004\000"}, - {294, "if_stmt", 0, 8, states_38, - "\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000"}, - {295, "while_stmt", 0, 8, states_39, - "\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000"}, - {296, "for_stmt", 0, 10, states_40, + {296, "if_stmt", 0, 8, states_40, "\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000"}, - {297, "try_stmt", 0, 13, states_41, - "\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000"}, - {298, "with_stmt", 0, 5, states_42, - "\000\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"}, - {299, "with_item", 0, 4, states_43, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, - {300, "except_clause", 0, 5, states_44, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000"}, - {301, "suite", 0, 5, states_45, - "\004\040\040\200\000\000\000\240\340\223\160\000\000\200\020\000\000\206\120\076\200\000"}, - {302, "test", 0, 6, states_46, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, - {303, "test_nocond", 0, 2, states_47, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, - {304, "lambdef", 0, 5, states_48, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000"}, - {305, "lambdef_nocond", 0, 5, states_49, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000"}, - {306, "or_test", 0, 2, states_50, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\020\000\000\206\120\076\000\000"}, - {307, "and_test", 0, 2, states_51, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\020\000\000\206\120\076\000\000"}, - {308, "not_test", 0, 3, states_52, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\020\000\000\206\120\076\000\000"}, - {309, "comparison", 0, 2, states_53, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"}, - {310, "comp_op", 0, 4, states_54, - "\000\000\000\000\000\000\000\000\000\000\000\000\002\000\220\177\000\000\000\000\000\000"}, - {311, "star_expr", 0, 3, states_55, - "\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {312, "expr", 0, 2, states_56, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"}, - {313, "xor_expr", 0, 2, states_57, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"}, - {314, "and_expr", 0, 2, states_58, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"}, - {315, "shift_expr", 0, 2, states_59, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"}, - {316, "arith_expr", 0, 2, states_60, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"}, - {317, "term", 0, 2, states_61, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"}, - {318, "factor", 0, 3, states_62, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"}, - {319, "power", 0, 4, states_63, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\120\076\000\000"}, - {320, "atom", 0, 9, states_64, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\120\076\000\000"}, - {321, "testlist_comp", 0, 5, states_65, - "\000\040\040\200\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, - {322, "trailer", 0, 7, states_66, - "\000\040\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\020\000\000\000"}, - {323, "subscriptlist", 0, 3, states_67, - "\000\040\040\002\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, - {324, "subscript", 0, 5, states_68, - "\000\040\040\002\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, - {325, "sliceop", 0, 3, states_69, - "\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {326, "exprlist", 0, 3, states_70, - "\000\040\040\200\000\000\000\000\000\200\000\000\000\000\000\000\000\206\120\076\000\000"}, - {327, "testlist", 0, 3, states_71, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, - {328, "dictorsetmaker", 0, 11, states_72, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, - {329, "classdef", 0, 8, states_73, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000"}, - {330, "arglist", 0, 8, states_74, - "\000\040\040\200\001\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, - {331, "argument", 0, 4, states_75, - "\000\040\040\000\000\000\000\000\000\200\000\000\000\200\020\000\000\206\120\076\000\000"}, - {332, "comp_iter", 0, 2, states_76, - "\000\000\000\000\000\000\000\000\000\000\000\020\001\000\000\000\000\000\000\000\000\000"}, - {333, "comp_for", 0, 6, states_77, + {297, "while_stmt", 0, 8, states_41, + "\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000"}, + {298, "for_stmt", 0, 10, states_42, + "\000\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000"}, + {299, "try_stmt", 0, 13, states_43, + "\000\000\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000"}, + {300, "with_stmt", 0, 5, states_44, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000"}, + {301, "with_item", 0, 4, states_45, + "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, + {302, "except_clause", 0, 5, states_46, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000"}, + {303, "suite", 0, 5, states_47, + "\004\040\200\000\002\000\000\000\005\237\204\003\000\000\010\001\000\140\110\224\017\040"}, + {304, "test", 0, 6, states_48, + "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, + {305, "test_nocond", 0, 2, states_49, + "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, + {306, "lambdef", 0, 5, states_50, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000"}, + {307, "lambdef_nocond", 0, 5, states_51, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000"}, + {308, "or_test", 0, 2, states_52, + "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\001\000\140\110\224\017\000"}, + {309, "and_test", 0, 2, states_53, + "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\001\000\140\110\224\017\000"}, + {310, "not_test", 0, 3, states_54, + "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\001\000\140\110\224\017\000"}, + {311, "comparison", 0, 2, states_55, + "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\140\110\224\017\000"}, + {312, "comp_op", 0, 4, states_56, + "\000\000\000\000\000\000\000\000\000\000\000\000\040\000\000\371\007\000\000\000\000\000"}, + {313, "star_expr", 0, 3, states_57, + "\000\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {314, "expr", 0, 2, states_58, + "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\140\110\224\017\000"}, + {315, "xor_expr", 0, 2, states_59, + "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\140\110\224\017\000"}, + {316, "and_expr", 0, 2, states_60, + "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\140\110\224\017\000"}, + {317, "shift_expr", 0, 2, states_61, + "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\140\110\224\017\000"}, + {318, "arith_expr", 0, 2, states_62, + "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\140\110\224\017\000"}, + {319, "term", 0, 2, states_63, + "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\140\110\224\017\000"}, + {320, "factor", 0, 3, states_64, + "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\140\110\224\017\000"}, + {321, "power", 0, 4, states_65, + "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\100\224\017\000"}, + {322, "atom_expr", 0, 3, states_66, + "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\100\224\017\000"}, + {323, "atom", 0, 9, states_67, + "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\224\017\000"}, + {324, "testlist_comp", 0, 5, states_68, + "\000\040\200\000\002\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, + {325, "trailer", 0, 7, states_69, + "\000\040\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\004\000\000"}, + {326, "subscriptlist", 0, 3, states_70, + "\000\040\200\010\000\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, + {327, "subscript", 0, 5, states_71, + "\000\040\200\010\000\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, + {328, "sliceop", 0, 3, states_72, + "\000\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {329, "exprlist", 0, 3, states_73, + "\000\040\200\000\002\000\000\000\000\000\004\000\000\000\000\000\000\140\110\224\017\000"}, + {330, "testlist", 0, 3, states_74, + "\000\040\200\000\000\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, + {331, "dictorsetmaker", 0, 14, states_75, + "\000\040\200\000\006\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, + {332, "classdef", 0, 8, states_76, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001"}, + {333, "arglist", 0, 3, states_77, + "\000\040\200\000\006\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, + {334, "argument", 0, 4, states_78, + "\000\040\200\000\006\000\000\000\000\000\004\000\000\000\010\001\000\140\110\224\017\000"}, + {335, "comp_iter", 0, 2, states_79, + "\000\000\000\000\000\000\000\000\000\000\000\000\021\000\000\000\000\000\000\000\000\000"}, + {336, "comp_for", 0, 6, states_80, + "\000\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000"}, + {337, "comp_if", 0, 4, states_81, "\000\000\000\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000"}, - {334, "comp_if", 0, 4, states_78, - "\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000"}, - {335, "encoding_decl", 0, 2, states_79, - "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {336, "yield_expr", 0, 3, states_80, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000"}, - {337, "yield_arg", 0, 3, states_81, - "\000\040\040\000\000\000\000\000\000\202\000\000\000\200\020\000\000\206\120\076\000\000"}, -}; -static label labels[169] = { + {338, "encoding_decl", 0, 2, states_82, + "\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {339, "yield_expr", 0, 3, states_83, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\040"}, + {340, "yield_arg", 0, 3, states_84, + "\000\040\200\000\000\000\000\000\000\020\004\000\000\000\010\001\000\140\110\224\017\000"}, +}; +static label labels[175] = { {0, "EMPTY"}, {256, 0}, {4, 0}, - {269, 0}, - {293, 0}, + {270, 0}, + {294, 0}, {257, 0}, - {268, 0}, + {269, 0}, {0, 0}, {258, 0}, - {327, 0}, + {330, 0}, {259, 0}, {49, 0}, - {289, 0}, + {290, 0}, {7, 0}, - {330, 0}, + {333, 0}, {8, 0}, {260, 0}, {261, 0}, - {329, 0}, + {332, 0}, + {263, 0}, {262, 0}, + {55, 0}, {1, "def"}, {1, 0}, - {263, 0}, - {50, 0}, - {302, 0}, - {11, 0}, - {301, 0}, {264, 0}, + {51, 0}, + {304, 0}, + {11, 0}, + {303, 0}, {265, 0}, + {266, 0}, {22, 0}, {12, 0}, {16, 0}, {35, 0}, - {266, 0}, {267, 0}, - {270, 0}, - {13, 0}, + {268, 0}, {271, 0}, - {274, 0}, + {13, 0}, + {272, 0}, {275, 0}, {276, 0}, - {282, 0}, - {290, 0}, + {277, 0}, + {283, 0}, {291, 0}, {292, 0}, - {272, 0}, + {293, 0}, {273, 0}, - {336, 0}, - {311, 0}, + {274, 0}, + {339, 0}, + {313, 0}, {36, 0}, {37, 0}, {38, 0}, + {50, 0}, {39, 0}, {40, 0}, {41, 0}, @@ -2046,36 +2112,37 @@ static label labels[169] = { {46, 0}, {48, 0}, {1, "del"}, - {326, 0}, + {329, 0}, {1, "pass"}, - {277, 0}, {278, 0}, {279, 0}, - {281, 0}, {280, 0}, + {282, 0}, + {281, 0}, {1, "break"}, {1, "continue"}, {1, "return"}, {1, "raise"}, {1, "from"}, - {283, 0}, {284, 0}, + {285, 0}, {1, "import"}, - {288, 0}, + {289, 0}, {23, 0}, - {51, 0}, - {287, 0}, - {285, 0}, - {1, "as"}, + {52, 0}, + {288, 0}, {286, 0}, + {1, "as"}, + {287, 0}, {1, "global"}, {1, "nonlocal"}, {1, "assert"}, - {294, 0}, - {295, 0}, {296, 0}, {297, 0}, {298, 0}, + {299, 0}, + {300, 0}, + {295, 0}, {1, "if"}, {1, "elif"}, {1, "else"}, @@ -2083,26 +2150,26 @@ static label labels[169] = { {1, "for"}, {1, "in"}, {1, "try"}, - {300, 0}, + {302, 0}, {1, "finally"}, {1, "with"}, - {299, 0}, - {312, 0}, + {301, 0}, + {314, 0}, {1, "except"}, {5, 0}, {6, 0}, + {308, 0}, {306, 0}, - {304, 0}, - {303, 0}, {305, 0}, - {1, "lambda"}, {307, 0}, + {1, "lambda"}, + {309, 0}, {1, "or"}, - {308, 0}, + {310, 0}, {1, "and"}, {1, "not"}, - {309, 0}, - {310, 0}, + {311, 0}, + {312, 0}, {20, 0}, {21, 0}, {27, 0}, @@ -2111,52 +2178,54 @@ static label labels[169] = { {28, 0}, {28, 0}, {1, "is"}, - {313, 0}, + {315, 0}, {18, 0}, - {314, 0}, + {316, 0}, {32, 0}, - {315, 0}, + {317, 0}, {19, 0}, - {316, 0}, + {318, 0}, {33, 0}, {34, 0}, - {317, 0}, + {319, 0}, {14, 0}, {15, 0}, - {318, 0}, + {320, 0}, {17, 0}, {24, 0}, {47, 0}, {31, 0}, - {319, 0}, - {320, 0}, - {322, 0}, {321, 0}, + {322, 0}, + {54, 0}, + {323, 0}, + {325, 0}, + {324, 0}, {9, 0}, {10, 0}, {25, 0}, - {328, 0}, + {331, 0}, {26, 0}, {2, 0}, {3, 0}, {1, "None"}, {1, "True"}, {1, "False"}, - {333, 0}, - {323, 0}, - {324, 0}, - {325, 0}, + {336, 0}, + {326, 0}, + {327, 0}, + {328, 0}, {1, "class"}, - {331, 0}, - {332, 0}, {334, 0}, {335, 0}, - {1, "yield"}, {337, 0}, + {338, 0}, + {1, "yield"}, + {340, 0}, }; grammar _PyParser_Grammar = { - 82, + 85, dfas, - {169, labels}, + {175, labels}, 256 }; diff --git a/Python/import.c b/Python/import.c index 584b1b41cd3c..edf030d87ae9 100644 --- a/Python/import.c +++ b/Python/import.c @@ -31,14 +31,33 @@ struct _inittab *PyImport_Inittab = _PyImport_Inittab; static PyObject *initstr = NULL; +/*[clinic input] +module _imp +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9c332475d8686284]*/ + +#include "clinic/import.c.h" + +/*[python input] +class fs_unicode_converter(CConverter): + type = 'PyObject *' + converter = 'PyUnicode_FSDecoder' + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=9d6786230166006e]*/ + /* Initialize things */ void _PyImport_Init(void) { + PyInterpreterState *interp = PyThreadState_Get()->interp; initstr = PyUnicode_InternFromString("__init__"); if (initstr == NULL) Py_FatalError("Can't initialize import variables"); + interp->builtins_copy = PyDict_Copy(interp->builtins); + if (interp->builtins_copy == NULL) + Py_FatalError("Can't backup builtins dict"); } void @@ -190,8 +209,12 @@ _PyImport_ReleaseLock(void) void _PyImport_ReInitLock(void) { - if (import_lock != NULL) + 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 */ long me = PyThread_get_thread_ident(); @@ -210,8 +233,17 @@ _PyImport_ReInitLock(void) #endif +/*[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(PyObject *self, PyObject *noargs) +_imp_lock_held_impl(PyModuleDef *module) +/*[clinic end generated code: output=d7a8cc3a5169081a input=9b088f9b217d9bdf]*/ { #ifdef WITH_THREAD return PyBool_FromLong(import_lock_thread != -1); @@ -220,8 +252,18 @@ imp_lock_held(PyObject *self, PyObject *noargs) #endif } +/*[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(PyObject *self, PyObject *noargs) +_imp_acquire_lock_impl(PyModuleDef *module) +/*[clinic end generated code: output=cc143b1d16422cae input=4a2d4381866d5fdc]*/ { #ifdef WITH_THREAD _PyImport_AcquireLock(); @@ -230,8 +272,17 @@ imp_acquire_lock(PyObject *self, PyObject *noargs) return Py_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(PyObject *self, PyObject *noargs) +_imp_release_lock_impl(PyModuleDef *module) +/*[clinic end generated code: output=74d28e38ebe2b224 input=934fb11516dd778b]*/ { #ifdef WITH_THREAD if (_PyImport_ReleaseLock() < 0) { @@ -247,8 +298,7 @@ imp_release_lock(PyObject *self, PyObject *noargs) void _PyImport_Fini(void) { - Py_XDECREF(extensions); - extensions = NULL; + Py_CLEAR(extensions); #ifdef WITH_THREAD if (import_lock != NULL) { PyThread_free_lock(import_lock); @@ -296,8 +346,8 @@ PyImport_Cleanup(void) PyObject *key, *value, *dict; PyInterpreterState *interp = PyThreadState_GET()->interp; PyObject *modules = interp->modules; - PyObject *builtins = interp->builtins; PyObject *weaklist = NULL; + char **p; if (modules == NULL) return; /* Already done */ @@ -310,31 +360,22 @@ PyImport_Cleanup(void) /* XXX Perhaps these precautions are obsolete. Who knows? */ - value = PyDict_GetItemString(modules, "builtins"); - if (value != NULL && PyModule_Check(value)) { - dict = PyModule_GetDict(value); + if (Py_VerboseFlag) + PySys_WriteStderr("# clear builtins._\n"); + PyDict_SetItemString(interp->builtins, "_", Py_None); + + for (p = sys_deletes; *p != NULL; p++) { if (Py_VerboseFlag) - PySys_WriteStderr("# clear builtins._\n"); - PyDict_SetItemString(dict, "_", Py_None); - } - value = PyDict_GetItemString(modules, "sys"); - if (value != NULL && PyModule_Check(value)) { - char **p; - PyObject *v; - dict = PyModule_GetDict(value); - for (p = sys_deletes; *p != NULL; p++) { - if (Py_VerboseFlag) - PySys_WriteStderr("# clear sys.%s\n", *p); - PyDict_SetItemString(dict, *p, Py_None); - } - for (p = sys_files; *p != NULL; p+=2) { - if (Py_VerboseFlag) - PySys_WriteStderr("# restore sys.%s\n", *p); - v = PyDict_GetItemString(dict, *(p+1)); - if (v == NULL) - v = Py_None; - PyDict_SetItemString(dict, *p, v); - } + PySys_WriteStderr("# clear sys.%s\n", *p); + PyDict_SetItemString(interp->sysdict, *p, Py_None); + } + for (p = sys_files; *p != NULL; p+=2) { + if (Py_VerboseFlag) + PySys_WriteStderr("# restore sys.%s\n", *p); + value = PyDict_GetItemString(interp->sysdict, *(p+1)); + if (value == NULL) + value = Py_None; + PyDict_SetItemString(interp->sysdict, *p, value); } /* We prepare a list which will receive (name, weakref) tuples of @@ -364,7 +405,7 @@ PyImport_Cleanup(void) while (PyDict_Next(modules, &pos, &key, &value)) { if (PyModule_Check(value)) { if (Py_VerboseFlag && PyUnicode_Check(key)) - PySys_FormatStderr("# cleanup[2] removing %U\n", key, value); + PySys_FormatStderr("# cleanup[2] removing %U\n", key); STORE_MODULE_WEAKREF(key, value); PyDict_SetItem(modules, key, Py_None); } @@ -372,11 +413,15 @@ PyImport_Cleanup(void) /* Clear the modules dict. */ PyDict_Clear(modules); - /* Replace the interpreter's reference to builtins with an empty dict - (module globals still have a reference to the original builtins). */ - builtins = interp->builtins; - interp->builtins = PyDict_New(); - Py_DECREF(builtins); + /* Restore the original builtins dict, to ensure that any + user data gets cleared. */ + dict = PyDict_Copy(interp->builtins); + if (dict == NULL) + PyErr_Clear(); + 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 */ @@ -387,7 +432,15 @@ PyImport_Cleanup(void) /* 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. */ + 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, n; n = PyList_GET_SIZE(weaklist); @@ -397,17 +450,27 @@ PyImport_Cleanup(void) PyObject *mod = PyWeakref_GET_OBJECT(PyTuple_GET_ITEM(tup, 1)); if (mod == Py_None) continue; - Py_INCREF(mod); assert(PyModule_Check(mod)); + dict = PyModule_GetDict(mod); + if (dict == interp->builtins || dict == interp->sysdict) + continue; + Py_INCREF(mod); if (Py_VerboseFlag && PyUnicode_Check(name)) - PySys_FormatStderr("# cleanup[3] wiping %U\n", - name, mod); + 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 (Py_VerboseFlag) + PySys_FormatStderr("# cleanup[3] wiping sys\n"); + _PyModule_ClearDict(interp->sysdict); + if (Py_VerboseFlag) + 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. */ @@ -428,8 +491,13 @@ PyImport_GetMagicNumber(void) { long res; PyInterpreterState *interp = PyThreadState_Get()->interp; - PyObject *pyc_magic = PyObject_GetAttrString(interp->importlib, - "_RAW_MAGIC_NUMBER"); + 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); @@ -496,8 +564,7 @@ _PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, /* Somebody already imported the module, likely under a different name. XXX this should really not happen. */ - Py_DECREF(def->m_base.m_copy); - def->m_base.m_copy = NULL; + Py_CLEAR(def->m_base.m_copy); } dict = PyModule_GetDict(mod); if (dict == NULL) @@ -675,7 +742,7 @@ PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, const char *cpathname) { PyObject *m = NULL; - PyObject *nameobj, *pathobj = NULL, *cpathobj = NULL; + PyObject *nameobj, *pathobj = NULL, *cpathobj = NULL, *external= NULL; nameobj = PyUnicode_FromString(name); if (nameobj == NULL) @@ -703,9 +770,14 @@ PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, "no interpreter!"); } - pathobj = _PyObject_CallMethodIdObjArgs(interp->importlib, - &PyId__get_sourcefile, cpathobj, - NULL); + 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(); } @@ -720,12 +792,10 @@ PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, return m; } -PyObject* -PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, - PyObject *cpathname) +static PyObject * +module_dict_for_exec(PyObject *name) { - PyObject *modules = PyImport_GetModuleDict(); - PyObject *m, *d, *v; + PyObject *m, *d = NULL; m = PyImport_AddModuleObject(name); if (m == NULL) @@ -735,31 +805,26 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, d = PyModule_GetDict(m); if (PyDict_GetItemString(d, "__builtins__") == NULL) { if (PyDict_SetItemString(d, "__builtins__", - PyEval_GetBuiltins()) != 0) - goto error; - } - if (pathname != NULL) { - v = pathname; - } - else { - v = ((PyCodeObject *)co)->co_filename; + PyEval_GetBuiltins()) != 0) { + remove_module(name); + return NULL; + } } - Py_INCREF(v); - if (PyDict_SetItemString(d, "__file__", v) != 0) - PyErr_Clear(); /* Not important enough to report */ - Py_DECREF(v); - /* Remember the pyc path name as the __cached__ attribute. */ - if (cpathname != NULL) - v = cpathname; - else - v = Py_None; - if (PyDict_SetItemString(d, "__cached__", v) != 0) - PyErr_Clear(); /* Not important enough to report */ + return d; /* Return a borrowed reference. */ +} - v = PyEval_EvalCode(co, d, d); - if (v == NULL) - goto error; +static PyObject * +exec_code_in_module(PyObject *name, PyObject *module_dict, PyObject *code_object) +{ + PyObject *modules = PyImport_GetModuleDict(); + PyObject *v, *m; + + v = PyEval_EvalCode(code_object, module_dict, module_dict); + if (v == NULL) { + remove_module(name); + return NULL; + } Py_DECREF(v); if ((m = PyDict_GetItem(modules, name)) == NULL) { @@ -772,10 +837,36 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, Py_INCREF(m); return m; +} - error: - remove_module(name); - return NULL; +PyObject* +PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, + PyObject *cpathname) +{ + PyObject *d, *external, *res; + PyInterpreterState *interp = PyThreadState_GET()->interp; + _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; } @@ -817,28 +908,26 @@ update_compiled_module(PyCodeObject *co, PyObject *newname) Py_DECREF(oldname); } -static PyObject * -imp_fix_co_filename(PyObject *self, PyObject *args) -{ - PyObject *co; - PyObject *file_path; +/*[clinic input] +_imp._fix_co_filename - if (!PyArg_ParseTuple(args, "OO:_fix_co_filename", &co, &file_path)) - return NULL; + code: object(type="PyCodeObject *", subclass_of="&PyCode_Type") + Code object to change. - if (!PyCode_Check(co)) { - PyErr_SetString(PyExc_TypeError, - "first argument must be a code object"); - return NULL; - } + path: unicode + File path to use. + / - if (!PyUnicode_Check(file_path)) { - PyErr_SetString(PyExc_TypeError, - "second argument must be a string"); - return NULL; - } +Changes code.co_filename to specify the passed-in file path. +[clinic start generated code]*/ - update_compiled_module((PyCodeObject*)co, file_path); +static PyObject * +_imp__fix_co_filename_impl(PyModuleDef *module, PyCodeObject *code, + PyObject *path) +/*[clinic end generated code: output=f4db56aac0a1327f input=895ba50e78b82f05]*/ + +{ + update_compiled_module(code, path); Py_RETURN_NONE; } @@ -937,50 +1026,74 @@ PyImport_GetImporter(PyObject *path) { return importer; } +/*[clinic input] +_imp.create_builtin -static int init_builtin(PyObject *); /* Forward */ + spec: object + / -/* Initialize a built-in module. - Return 1 for success, 0 if the module is not found, and -1 with - an exception set if the initialization failed. */ +Create an extension module. +[clinic start generated code]*/ -static int -init_builtin(PyObject *name) +static PyObject * +_imp_create_builtin(PyModuleDef *module, PyObject *spec) +/*[clinic end generated code: output=5038f467617226bd input=37f966f890384e47]*/ { struct _inittab *p; + PyObject *name; + char *namestr; PyObject *mod; + name = PyObject_GetAttrString(spec, "name"); + if (name == NULL) { + return NULL; + } + mod = _PyImport_FindExtensionObject(name, name); - if (PyErr_Occurred()) - return -1; - if (mod != NULL) - return 1; + if (mod || PyErr_Occurred()) { + Py_DECREF(name); + Py_INCREF(mod); + return mod; + } + + namestr = PyUnicode_AsUTF8(name); + if (namestr == NULL) { + Py_DECREF(name); + return NULL; + } for (p = PyImport_Inittab; p->name != NULL; p++) { - PyObject *mod; PyModuleDef *def; if (PyUnicode_CompareWithASCIIString(name, p->name) == 0) { if (p->initfunc == NULL) { - PyErr_Format(PyExc_ImportError, - "Cannot re-init internal module %R", - name); - return -1; + /* Cannot re-init internal module ("sys" or "builtins") */ + mod = PyImport_AddModule(namestr); + Py_DECREF(name); + return mod; } mod = (*p->initfunc)(); - if (mod == 0) - return -1; - /* Remember pointer to module init function. */ - def = PyModule_GetDef(mod); - def->m_base.m_init = p->initfunc; - if (_PyImport_FixupExtensionObject(mod, name, name) < 0) - return -1; - /* FixupExtension has put the module into sys.modules, - so we can release our own reference. */ - Py_DECREF(mod); - return 1; + 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); + def->m_base.m_init = p->initfunc; + if (_PyImport_FixupExtensionObject(mod, name, name) < 0) { + Py_DECREF(name); + return NULL; + } + Py_DECREF(name); + return mod; + } } } - return 0; + Py_DECREF(name); + Py_RETURN_NONE; } @@ -1058,7 +1171,7 @@ int PyImport_ImportFrozenModuleObject(PyObject *name) { const struct _frozen *p; - PyObject *co, *m, *path; + PyObject *co, *m, *d; int ispackage; int size; @@ -1087,7 +1200,7 @@ PyImport_ImportFrozenModuleObject(PyObject *name) } if (ispackage) { /* Set __path__ to the empty list */ - PyObject *d, *l; + PyObject *l; int err; m = PyImport_AddModuleObject(name); if (m == NULL) @@ -1102,11 +1215,11 @@ PyImport_ImportFrozenModuleObject(PyObject *name) if (err != 0) goto err_return; } - path = PyUnicode_FromString(""); - if (path == NULL) + d = module_dict_for_exec(name); + if (d == NULL) { goto err_return; - m = PyImport_ExecCodeModuleObject(name, co, path, NULL); - Py_DECREF(path); + } + m = exec_code_in_module(name, d, co); if (m == NULL) goto err_return; Py_DECREF(co); @@ -1170,6 +1283,7 @@ static void remove_importlib_frames(void) { const char *importlib_filename = ""; + const char *external_filename = ""; const char *remove_frames = "_call_with_frames_removed"; int always_trim = 0; int in_importlib = 0; @@ -1199,7 +1313,10 @@ remove_importlib_frames(void) assert(PyTraceBack_Check(tb)); now_in_importlib = (PyUnicode_CompareWithASCIIString( code->co_filename, - importlib_filename) == 0); + importlib_filename) == 0) || + (PyUnicode_CompareWithASCIIString( + code->co_filename, + external_filename) == 0); if (now_in_importlib && !in_importlib) { /* This is the link to this chunk of importlib tracebacks */ outer_link = prev_link; @@ -1249,6 +1366,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, PyObject *globals = NULL; PyObject *fromlist = NULL; PyInterpreterState *interp = PyThreadState_GET()->interp; + int has_from; /* Make sure to use default values so as to not have PyObject_CallMethodObjArgs() truncate the parameter list because of a @@ -1479,7 +1597,10 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, } /* From now on we don't hold the import lock anymore. */ - if (PyObject_Not(fromlist)) { + has_from = PyObject_IsTrue(fromlist); + if (has_from < 0) + goto error; + if (!has_from) { if (level == 0 || PyUnicode_GET_LENGTH(name) > 0) { PyObject *front = NULL; PyObject *partition = NULL; @@ -1691,8 +1812,15 @@ PyImport_Import(PyObject *module_name) 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(PyObject *self, PyObject *noargs) +_imp_extension_suffixes_impl(PyModuleDef *module) +/*[clinic end generated code: output=d44c1566ef362229 input=ecdeeecfcb6f839e]*/ { PyObject *list; const char *suffix; @@ -1720,34 +1848,22 @@ imp_extension_suffixes(PyObject *self, PyObject *noargs) return list; } -static PyObject * -imp_init_builtin(PyObject *self, PyObject *args) -{ - PyObject *name; - int ret; - PyObject *m; - if (!PyArg_ParseTuple(args, "U:init_builtin", &name)) - return NULL; - ret = init_builtin(name); - if (ret < 0) - return NULL; - if (ret == 0) { - Py_INCREF(Py_None); - return Py_None; - } - m = PyImport_AddModuleObject(name); - Py_XINCREF(m); - return m; -} +/*[clinic input] +_imp.init_frozen + + name: unicode + / + +Initializes a frozen module. +[clinic start generated code]*/ static PyObject * -imp_init_frozen(PyObject *self, PyObject *args) +_imp_init_frozen_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: output=a9de493bdd711878 input=13019adfc04f3fb3]*/ { - PyObject *name; int ret; PyObject *m; - if (!PyArg_ParseTuple(args, "U:init_frozen", &name)) - return NULL; + ret = PyImport_ImportFrozenModuleObject(name); if (ret < 0) return NULL; @@ -1760,121 +1876,219 @@ imp_init_frozen(PyObject *self, PyObject *args) 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(PyObject *self, PyObject *args) +_imp_get_frozen_object_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: output=3114c970a47f2e3c input=ed689bc05358fdbd]*/ { - PyObject *name; - - if (!PyArg_ParseTuple(args, "U:get_frozen_object", &name)) - return NULL; 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(PyObject *self, PyObject *args) +_imp_is_frozen_package_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: output=3e4cab802b56d649 input=81b6cdecd080fbb8]*/ { - PyObject *name; - - if (!PyArg_ParseTuple(args, "U:is_frozen_package", &name)) - return NULL; 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(PyObject *self, PyObject *args) +_imp_is_builtin_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: output=2deec9cac6fb9a7e input=86befdac021dd1c7]*/ { - PyObject *name; - if (!PyArg_ParseTuple(args, "U:is_builtin", &name)) - return NULL; 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(PyObject *self, PyObject *args) +_imp_is_frozen_impl(PyModuleDef *module, PyObject *name) +/*[clinic end generated code: output=7de8e260c8e36aed input=7301dbca1897d66b]*/ { - PyObject *name; const struct _frozen *p; - if (!PyArg_ParseTuple(args, "U:is_frozen", &name)) - return NULL; + 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) { + PyModuleDef *def; + void *state; + + if (!PyModule_Check(mod)) { + return 0; + } + + def = PyModule_GetDef(mod); + if (def == NULL) { + if (PyErr_Occurred()) { + return -1; + } + return 0; + } + state = PyModule_GetState(mod); + if (PyErr_Occurred()) { + return -1; + } + 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_load_dynamic(PyObject *self, PyObject *args) +_imp_create_dynamic_impl(PyModuleDef *module, PyObject *spec, PyObject *file) +/*[clinic end generated code: output=935cde5b3872d56d input=c31b954f4cf4e09d]*/ { - PyObject *name, *pathname, *fob = NULL, *mod; + PyObject *mod, *name, *path; FILE *fp; - if (!PyArg_ParseTuple(args, "UO&|O:load_dynamic", - &name, PyUnicode_FSDecoder, &pathname, &fob)) + name = PyObject_GetAttrString(spec, "name"); + if (name == NULL) { + return NULL; + } + + path = PyObject_GetAttrString(spec, "origin"); + if (path == NULL) { + Py_DECREF(name); return NULL; - if (fob != NULL) { - fp = _Py_fopen_obj(pathname, "r"); + } + + mod = _PyImport_FindExtensionObject(name, path); + if (mod != NULL) { + Py_DECREF(name); + Py_DECREF(path); + Py_INCREF(mod); + return mod; + } + + if (file != NULL) { + fp = _Py_fopen_obj(path, "r"); if (fp == NULL) { - Py_DECREF(pathname); - if (!PyErr_Occurred()) - PyErr_SetFromErrno(PyExc_IOError); + Py_DECREF(name); + Py_DECREF(path); return NULL; } } else fp = NULL; - mod = _PyImport_LoadDynamicModule(name, pathname, fp); - Py_DECREF(pathname); + + 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(PyModuleDef *module, PyObject *mod) +/*[clinic end generated code: output=4b84f1301b22d4bd input=9fdbfcb250280d3a]*/ +{ + return exec_builtin_or_dynamic(mod); +} + + #endif /* HAVE_DYNAMIC_LOADING */ +/*[clinic input] +_imp.exec_builtin -> int -/* Doc strings */ + mod: object + / -PyDoc_STRVAR(doc_imp, -"(Extremely) low-level import machinery bits as used by importlib and imp."); +Initialize a built-in module. +[clinic start generated code]*/ -PyDoc_STRVAR(doc_extension_suffixes, -"extension_suffixes() -> list of strings\n\ -Returns the list of file suffixes used to identify extension modules."); +static int +_imp_exec_builtin_impl(PyModuleDef *module, PyObject *mod) +/*[clinic end generated code: output=215e99876a27e284 input=7beed5a2f12a60ca]*/ +{ + return exec_builtin_or_dynamic(mod); +} -PyDoc_STRVAR(doc_lock_held, -"lock_held() -> boolean\n\ -Return True if the import lock is currently held, else False.\n\ -On platforms without threads, return False."); +/*[clinic input] +dump buffer +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/ -PyDoc_STRVAR(doc_acquire_lock, -"acquire_lock() -> None\n\ -Acquires the interpreter's import lock for the current thread.\n\ -This lock should be used by import hooks to ensure thread-safety\n\ -when importing modules.\n\ -On platforms without threads, this function does nothing."); -PyDoc_STRVAR(doc_release_lock, -"release_lock() -> None\n\ -Release the interpreter's import lock.\n\ -On platforms without threads, this function does nothing."); +PyDoc_STRVAR(doc_imp, +"(Extremely) low-level import machinery bits as used by importlib and imp."); static PyMethodDef imp_methods[] = { - {"extension_suffixes", imp_extension_suffixes, METH_NOARGS, - doc_extension_suffixes}, - {"lock_held", imp_lock_held, METH_NOARGS, doc_lock_held}, - {"acquire_lock", imp_acquire_lock, METH_NOARGS, doc_acquire_lock}, - {"release_lock", imp_release_lock, METH_NOARGS, doc_release_lock}, - {"get_frozen_object", imp_get_frozen_object, METH_VARARGS}, - {"is_frozen_package", imp_is_frozen_package, METH_VARARGS}, - {"init_builtin", imp_init_builtin, METH_VARARGS}, - {"init_frozen", imp_init_frozen, METH_VARARGS}, - {"is_builtin", imp_is_builtin, METH_VARARGS}, - {"is_frozen", imp_is_frozen, METH_VARARGS}, -#ifdef HAVE_DYNAMIC_LOADING - {"load_dynamic", imp_load_dynamic, METH_VARARGS}, -#endif - {"_fix_co_filename", imp_fix_co_filename, METH_VARARGS}, - {NULL, NULL} /* sentinel */ + _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 + {NULL, NULL} /* sentinel */ }; @@ -1955,7 +2169,7 @@ PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void)) memset(newtab, '\0', sizeof newtab); - newtab[0].name = (char *)name; + newtab[0].name = name; newtab[0].initfunc = initfunc; return PyImport_ExtendInittab(newtab); diff --git a/Python/importdl.c b/Python/importdl.c index b60f1c75fbd3..1aa585d5e811 100644 --- a/Python/importdl.c +++ b/Python/importdl.c @@ -13,87 +13,185 @@ #include "importdl.h" #ifdef MS_WINDOWS -extern dl_funcptr _PyImport_GetDynLoadWindows(const char *shortname, - PyObject *pathname, FILE *fp); +extern dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, + const char *shortname, + PyObject *pathname, + FILE *fp); #else -extern dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname, - const char *pathname, FILE *fp); +extern dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix, + const char *shortname, + const char *pathname, FILE *fp); #endif +static const char *ascii_only_prefix = "PyInit"; +static const char *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_LoadDynamicModule(PyObject *name, PyObject *path, FILE *fp) +_PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp) { - PyObject *m = NULL; #ifndef MS_WINDOWS - PyObject *pathbytes; + PyObject *pathbytes = NULL; #endif - PyObject *nameascii; - char *namestr, *lastdot, *shortname, *packagecontext, *oldcontext; - dl_funcptr p0; - PyObject* (*p)(void); - struct PyModuleDef *def; - - m = _PyImport_FindExtensionObject(name, path); - if (m != NULL) { - Py_INCREF(m); - return m; - } - - /* name must be encodable to ASCII because dynamic module must have a - function called "PyInit_NAME", they are written in C, and the C language - doesn't accept non-ASCII identifiers. */ - nameascii = PyUnicode_AsEncodedString(name, "ascii", NULL); - if (nameascii == NULL) + PyObject *name_unicode = NULL, *name = NULL, *path = NULL, *m = NULL; + const char *name_buf, *hook_prefix; + char *oldcontext; + dl_funcptr exportfunc; + PyModuleDef *def; + PyObject *(*p0)(void); + + name_unicode = PyObject_GetAttrString(spec, "name"); + if (name_unicode == NULL) { return NULL; + } - namestr = PyBytes_AS_STRING(nameascii); - if (namestr == NULL) + name = get_encoded_name(name_unicode, &hook_prefix); + if (name == NULL) { goto error; - - lastdot = strrchr(namestr, '.'); - if (lastdot == NULL) { - packagecontext = NULL; - shortname = namestr; - } - else { - packagecontext = namestr; - shortname = lastdot+1; } + name_buf = PyBytes_AS_STRING(name); + + path = PyObject_GetAttrString(spec, "origin"); + if (path == NULL) + goto error; #ifdef MS_WINDOWS - p0 = _PyImport_GetDynLoadWindows(shortname, path, fp); + exportfunc = _PyImport_FindSharedFuncptrWindows(hook_prefix, name_buf, + path, fp); #else pathbytes = PyUnicode_EncodeFSDefault(path); if (pathbytes == NULL) goto error; - p0 = _PyImport_GetDynLoadFunc(shortname, - PyBytes_AS_STRING(pathbytes), fp); + exportfunc = _PyImport_FindSharedFuncptr(hook_prefix, name_buf, + PyBytes_AS_STRING(pathbytes), + fp); Py_DECREF(pathbytes); #endif - p = (PyObject*(*)(void))p0; - if (PyErr_Occurred()) - goto error; - if (p == NULL) { - PyObject *msg = PyUnicode_FromFormat("dynamic module does not define " - "init function (PyInit_%s)", - shortname); - if (msg == NULL) - goto error; - PyErr_SetImportError(msg, name, path); - Py_DECREF(msg); + + 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 = packagecontext; - m = (*p)(); + _Py_PackageContext = PyUnicode_AsUTF8(name_unicode); + m = p0(); _Py_PackageContext = oldcontext; - if (m == NULL) - goto error; - if (PyErr_Occurred()) { + 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, - "initialization of %s raised unreported exception", - shortname); + "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; } @@ -102,10 +200,10 @@ _PyImport_LoadDynamicModule(PyObject *name, PyObject *path, FILE *fp) if (def == NULL) { PyErr_Format(PyExc_SystemError, "initialization of %s did not return an extension " - "module", shortname); + "module", name_buf); goto error; } - def->m_base.m_init = p; + def->m_base.m_init = p0; /* Remember the filename as the __file__ attribute */ if (PyModule_AddObject(m, "__file__", path) < 0) @@ -113,13 +211,19 @@ _PyImport_LoadDynamicModule(PyObject *name, PyObject *path, FILE *fp) else Py_INCREF(path); - if (_PyImport_FixupExtensionObject(m, name, path) < 0) + if (_PyImport_FixupExtensionObject(m, name_unicode, path) < 0) goto error; - Py_DECREF(nameascii); + + Py_DECREF(name_unicode); + Py_DECREF(name); + Py_DECREF(path); + return m; error: - Py_DECREF(nameascii); + Py_DECREF(name_unicode); + Py_XDECREF(name); + Py_XDECREF(path); Py_XDECREF(m); return NULL; } diff --git a/Python/importdl.h b/Python/importdl.h index 6a51a91d2c0c..9847652b1f1b 100644 --- a/Python/importdl.h +++ b/Python/importdl.h @@ -8,8 +8,7 @@ extern "C" { extern const char *_PyImport_DynLoadFiletab[]; -extern PyObject *_PyImport_LoadDynamicModule(PyObject *name, PyObject *pathname, - FILE *); +extern PyObject *_PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *); /* Max length of module suffix searched for -- accommodates "module.slb" */ #define MAXSUFFIXSIZE 12 diff --git a/Python/importlib.h b/Python/importlib.h index dd9b97863c2e..a4daf621e24c 100644 --- a/Python/importlib.h +++ b/Python/importlib.h @@ -1,84 +1,50 @@ -/* Auto-generated by Modules/_freeze_importlib.c */ +/* Auto-generated by Programs/_freeze_importlib.c */ const unsigned char _Py_M__importlib[] = { - 99,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0, - 0,64,0,0,0,115,201,4,0,0,100,0,0,90,0,0, - 100,159,0,90,1,0,100,4,0,100,5,0,132,0,0,90, - 2,0,100,6,0,100,7,0,132,0,0,90,3,0,100,8, - 0,100,9,0,132,0,0,90,4,0,100,10,0,100,11,0, - 132,0,0,90,5,0,100,12,0,100,13,0,132,0,0,90, - 6,0,100,14,0,100,15,0,132,0,0,90,7,0,100,16, - 0,100,17,0,132,0,0,90,8,0,100,18,0,100,19,0, - 132,0,0,90,9,0,100,20,0,100,21,0,132,0,0,90, - 10,0,100,22,0,100,23,0,100,24,0,132,1,0,90,11, - 0,100,25,0,100,26,0,132,0,0,90,12,0,100,27,0, - 100,28,0,132,0,0,90,13,0,101,14,0,101,12,0,106, - 15,0,131,1,0,90,16,0,71,100,29,0,100,30,0,132, - 0,0,100,30,0,131,2,0,90,17,0,105,0,0,90,18, - 0,105,0,0,90,19,0,71,100,31,0,100,32,0,132,0, - 0,100,32,0,101,20,0,131,3,0,90,21,0,71,100,33, - 0,100,34,0,132,0,0,100,34,0,131,2,0,90,22,0, - 71,100,35,0,100,36,0,132,0,0,100,36,0,131,2,0, - 90,23,0,71,100,37,0,100,38,0,132,0,0,100,38,0, - 131,2,0,90,24,0,100,39,0,100,40,0,132,0,0,90, - 25,0,100,41,0,100,42,0,132,0,0,90,26,0,100,43, - 0,100,44,0,132,0,0,90,27,0,100,45,0,106,28,0, - 100,46,0,100,47,0,131,2,0,100,48,0,23,90,29,0, - 101,30,0,106,31,0,101,29,0,100,47,0,131,2,0,90, - 32,0,100,49,0,90,33,0,100,50,0,103,1,0,90,34, - 0,100,51,0,103,1,0,90,35,0,100,52,0,103,1,0, - 90,36,0,100,53,0,100,54,0,100,55,0,132,1,0,90, - 37,0,100,56,0,100,57,0,132,0,0,90,38,0,100,58, - 0,100,59,0,132,0,0,90,39,0,100,60,0,100,61,0, - 132,0,0,90,40,0,100,62,0,100,63,0,100,64,0,100, - 65,0,132,0,1,90,41,0,100,66,0,100,67,0,132,0, - 0,90,42,0,100,68,0,100,69,0,132,0,0,90,43,0, - 100,70,0,100,71,0,132,0,0,90,44,0,100,72,0,100, - 73,0,132,0,0,90,45,0,100,74,0,100,75,0,132,0, - 0,90,46,0,100,53,0,100,53,0,100,53,0,100,76,0, - 100,77,0,132,3,0,90,47,0,100,53,0,100,53,0,100, - 53,0,100,78,0,100,79,0,132,3,0,90,48,0,100,80, - 0,100,80,0,100,81,0,100,82,0,132,2,0,90,49,0, - 100,83,0,100,84,0,132,0,0,90,50,0,100,85,0,100, - 86,0,132,0,0,90,51,0,71,100,87,0,100,88,0,132, - 0,0,100,88,0,131,2,0,90,52,0,71,100,89,0,100, - 90,0,132,0,0,100,90,0,131,2,0,90,53,0,100,91, - 0,100,53,0,100,92,0,100,53,0,100,93,0,100,94,0, - 132,0,2,90,54,0,101,55,0,131,0,0,90,56,0,100, - 53,0,100,95,0,100,53,0,100,96,0,101,56,0,100,97, - 0,100,98,0,132,1,2,90,57,0,100,53,0,100,53,0, - 100,99,0,100,100,0,132,2,0,90,58,0,71,100,101,0, - 100,102,0,132,0,0,100,102,0,131,2,0,90,59,0,71, - 100,103,0,100,104,0,132,0,0,100,104,0,131,2,0,90, - 60,0,71,100,105,0,100,106,0,132,0,0,100,106,0,131, - 2,0,90,61,0,71,100,107,0,100,108,0,132,0,0,100, - 108,0,131,2,0,90,62,0,71,100,109,0,100,110,0,132, - 0,0,100,110,0,131,2,0,90,63,0,71,100,111,0,100, - 112,0,132,0,0,100,112,0,101,63,0,131,3,0,90,64, - 0,71,100,113,0,100,114,0,132,0,0,100,114,0,131,2, - 0,90,65,0,71,100,115,0,100,116,0,132,0,0,100,116, - 0,101,65,0,101,64,0,131,4,0,90,66,0,71,100,117, - 0,100,118,0,132,0,0,100,118,0,101,65,0,101,63,0, - 131,4,0,90,67,0,103,0,0,90,68,0,71,100,119,0, - 100,120,0,132,0,0,100,120,0,131,2,0,90,69,0,71, - 100,121,0,100,122,0,132,0,0,100,122,0,131,2,0,90, - 70,0,71,100,123,0,100,124,0,132,0,0,100,124,0,131, - 2,0,90,71,0,71,100,125,0,100,126,0,132,0,0,100, - 126,0,131,2,0,90,72,0,71,100,127,0,100,128,0,132, - 0,0,100,128,0,131,2,0,90,73,0,71,100,129,0,100, - 130,0,132,0,0,100,130,0,131,2,0,90,74,0,100,131, - 0,100,132,0,132,0,0,90,75,0,100,53,0,100,133,0, - 100,134,0,132,1,0,90,76,0,100,135,0,100,136,0,132, - 0,0,90,77,0,100,137,0,90,78,0,101,78,0,100,138, - 0,23,90,79,0,100,139,0,100,140,0,132,0,0,90,80, - 0,100,141,0,100,142,0,132,0,0,90,81,0,100,53,0, - 100,80,0,100,143,0,100,144,0,132,2,0,90,82,0,100, - 145,0,100,146,0,132,0,0,90,83,0,100,147,0,100,148, - 0,132,0,0,90,84,0,100,149,0,100,150,0,132,0,0, - 90,85,0,100,53,0,100,53,0,102,0,0,100,80,0,100, - 151,0,100,152,0,132,4,0,90,86,0,100,153,0,100,154, - 0,132,0,0,90,87,0,100,155,0,100,156,0,132,0,0, - 90,88,0,100,157,0,100,158,0,132,0,0,90,89,0,100, - 53,0,83,41,160,97,83,1,0,0,67,111,114,101,32,105, + 99,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0, + 0,64,0,0,0,115,169,2,0,0,100,0,0,90,0,0, + 100,1,0,97,1,0,100,2,0,100,3,0,132,0,0,90, + 2,0,100,4,0,100,5,0,132,0,0,90,3,0,71,100, + 6,0,100,7,0,132,0,0,100,7,0,131,2,0,90,4, + 0,105,0,0,90,5,0,105,0,0,90,6,0,71,100,8, + 0,100,9,0,132,0,0,100,9,0,101,7,0,131,3,0, + 90,8,0,71,100,10,0,100,11,0,132,0,0,100,11,0, + 131,2,0,90,9,0,71,100,12,0,100,13,0,132,0,0, + 100,13,0,131,2,0,90,10,0,71,100,14,0,100,15,0, + 132,0,0,100,15,0,131,2,0,90,11,0,100,16,0,100, + 17,0,132,0,0,90,12,0,100,18,0,100,19,0,132,0, + 0,90,13,0,100,20,0,100,21,0,132,0,0,90,14,0, + 100,22,0,100,23,0,100,24,0,100,25,0,132,0,1,90, + 15,0,100,26,0,100,27,0,132,0,0,90,16,0,100,28, + 0,100,29,0,132,0,0,90,17,0,100,30,0,100,31,0, + 132,0,0,90,18,0,100,32,0,100,33,0,132,0,0,90, + 19,0,71,100,34,0,100,35,0,132,0,0,100,35,0,131, + 2,0,90,20,0,71,100,36,0,100,37,0,132,0,0,100, + 37,0,131,2,0,90,21,0,100,38,0,100,1,0,100,39, + 0,100,1,0,100,40,0,100,41,0,132,0,2,90,22,0, + 101,23,0,131,0,0,90,24,0,100,1,0,100,1,0,100, + 42,0,100,43,0,132,2,0,90,25,0,100,44,0,100,45, + 0,100,46,0,100,47,0,132,0,1,90,26,0,100,48,0, + 100,49,0,132,0,0,90,27,0,100,50,0,100,51,0,132, + 0,0,90,28,0,100,52,0,100,53,0,132,0,0,90,29, + 0,100,54,0,100,55,0,132,0,0,90,30,0,100,56,0, + 100,57,0,132,0,0,90,31,0,100,58,0,100,59,0,132, + 0,0,90,32,0,71,100,60,0,100,61,0,132,0,0,100, + 61,0,131,2,0,90,33,0,71,100,62,0,100,63,0,132, + 0,0,100,63,0,131,2,0,90,34,0,71,100,64,0,100, + 65,0,132,0,0,100,65,0,131,2,0,90,35,0,100,66, + 0,100,67,0,132,0,0,90,36,0,100,68,0,100,69,0, + 132,0,0,90,37,0,100,1,0,100,70,0,100,71,0,132, + 1,0,90,38,0,100,72,0,100,73,0,132,0,0,90,39, + 0,100,74,0,90,40,0,101,40,0,100,75,0,23,90,41, + 0,100,76,0,100,77,0,132,0,0,90,42,0,100,78,0, + 100,79,0,132,0,0,90,43,0,100,1,0,100,80,0,100, + 81,0,100,82,0,132,2,0,90,44,0,100,83,0,100,84, + 0,132,0,0,90,45,0,100,85,0,100,86,0,132,0,0, + 90,46,0,100,1,0,100,1,0,102,0,0,100,80,0,100, + 87,0,100,88,0,132,4,0,90,47,0,100,89,0,100,90, + 0,132,0,0,90,48,0,100,91,0,100,92,0,132,0,0, + 90,49,0,100,93,0,100,94,0,132,0,0,90,50,0,100, + 1,0,83,41,95,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, @@ -99,551 +65,362 @@ const unsigned char _Py_M__importlib[] = { 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,218,3,119, - 105,110,218,6,99,121,103,119,105,110,218,6,100,97,114,119, - 105,110,99,0,0,0,0,0,0,0,0,1,0,0,0,2, - 0,0,0,67,0,0,0,115,49,0,0,0,116,0,0,106, - 1,0,106,2,0,116,3,0,131,1,0,114,33,0,100,1, - 0,100,2,0,132,0,0,125,0,0,110,12,0,100,3,0, - 100,2,0,132,0,0,125,0,0,124,0,0,83,41,4,78, - 99,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0, - 0,83,0,0,0,115,13,0,0,0,100,1,0,116,0,0, - 106,1,0,107,6,0,83,41,2,122,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, - 115,12,0,0,0,80,89,84,72,79,78,67,65,83,69,79, - 75,41,2,218,3,95,111,115,90,7,101,110,118,105,114,111, - 110,169,0,114,4,0,0,0,114,4,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,11,95,114, - 101,108,97,120,95,99,97,115,101,30,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,1,0,0,0,83,0,0,0, - 115,4,0,0,0,100,1,0,83,41,2,122,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,70,114,4,0,0,0,114,4,0,0,0,114,4,0, - 0,0,114,4,0,0,0,114,5,0,0,0,114,6,0,0, - 0,34,0,0,0,115,2,0,0,0,0,2,41,4,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,41,1,114,6,0,0,0,114,4,0, - 0,0,114,4,0,0,0,114,5,0,0,0,218,16,95,109, - 97,107,101,95,114,101,108,97,120,95,99,97,115,101,28,0, - 0,0,115,8,0,0,0,0,1,18,1,15,4,12,3,114, - 11,0,0,0,99,1,0,0,0,0,0,0,0,1,0,0, - 0,3,0,0,0,67,0,0,0,115,26,0,0,0,116,0, - 0,124,0,0,131,1,0,100,1,0,64,106,1,0,100,2, - 0,100,3,0,131,2,0,83,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,108,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,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,7,95,119,95,108,111,110,103,40,0,0,0, - 115,2,0,0,0,0,2,114,17,0,0,0,99,1,0,0, - 0,0,0,0,0,1,0,0,0,3,0,0,0,67,0,0, - 0,115,16,0,0,0,116,0,0,106,1,0,124,0,0,100, - 1,0,131,2,0,83,41,2,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,13,0,0,0,41,2, - 114,14,0,0,0,218,10,102,114,111,109,95,98,121,116,101, - 115,41,1,90,9,105,110,116,95,98,121,116,101,115,114,4, - 0,0,0,114,4,0,0,0,114,5,0,0,0,218,7,95, - 114,95,108,111,110,103,45,0,0,0,115,2,0,0,0,0, - 2,114,19,0,0,0,99,0,0,0,0,0,0,0,0,1, - 0,0,0,3,0,0,0,71,0,0,0,115,26,0,0,0, - 116,0,0,106,1,0,100,1,0,100,2,0,132,0,0,124, - 0,0,68,131,1,0,131,1,0,83,41,3,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,106,111,105,110,40,41,46,99,1,0, - 0,0,0,0,0,0,2,0,0,0,4,0,0,0,83,0, - 0,0,115,37,0,0,0,103,0,0,124,0,0,93,27,0, - 125,1,0,124,1,0,114,6,0,124,1,0,106,0,0,116, - 1,0,131,1,0,145,2,0,113,6,0,83,114,4,0,0, - 0,41,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,41,2,218,2, - 46,48,218,4,112,97,114,116,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,250,10,60,108,105,115,116,99,111, - 109,112,62,52,0,0,0,115,2,0,0,0,9,1,122,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,2, - 218,8,112,97,116,104,95,115,101,112,218,4,106,111,105,110, - 41,1,218,10,112,97,116,104,95,112,97,114,116,115,114,4, - 0,0,0,114,4,0,0,0,114,5,0,0,0,218,10,95, - 112,97,116,104,95,106,111,105,110,50,0,0,0,115,4,0, - 0,0,0,2,15,1,114,28,0,0,0,99,1,0,0,0, - 0,0,0,0,5,0,0,0,5,0,0,0,67,0,0,0, - 115,134,0,0,0,116,0,0,116,1,0,131,1,0,100,1, - 0,107,2,0,114,52,0,124,0,0,106,2,0,116,3,0, - 131,1,0,92,3,0,125,1,0,125,2,0,125,3,0,124, - 1,0,124,3,0,102,2,0,83,120,69,0,116,4,0,124, - 0,0,131,1,0,68,93,55,0,125,4,0,124,4,0,116, - 1,0,107,6,0,114,65,0,124,0,0,106,5,0,124,4, - 0,100,2,0,100,1,0,131,1,1,92,2,0,125,1,0, - 125,3,0,124,1,0,124,3,0,102,2,0,83,113,65,0, - 87,100,3,0,124,0,0,102,2,0,83,41,4,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,233, - 1,0,0,0,90,8,109,97,120,115,112,108,105,116,218,0, - 41,6,218,3,108,101,110,114,21,0,0,0,218,10,114,112, - 97,114,116,105,116,105,111,110,114,25,0,0,0,218,8,114, - 101,118,101,114,115,101,100,218,6,114,115,112,108,105,116,41, - 5,218,4,112,97,116,104,90,5,102,114,111,110,116,218,1, - 95,218,4,116,97,105,108,114,16,0,0,0,114,4,0,0, - 0,114,4,0,0,0,114,5,0,0,0,218,11,95,112,97, - 116,104,95,115,112,108,105,116,56,0,0,0,115,16,0,0, - 0,0,2,18,1,24,1,10,1,19,1,12,1,27,1,14, - 1,114,38,0,0,0,99,1,0,0,0,0,0,0,0,1, - 0,0,0,2,0,0,0,67,0,0,0,115,13,0,0,0, - 116,0,0,106,1,0,124,0,0,131,1,0,83,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,3,0,0,0,90,4,115,116,97,116,41,1,114,35, - 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, - 0,0,218,10,95,112,97,116,104,95,115,116,97,116,68,0, - 0,0,115,2,0,0,0,0,7,114,39,0,0,0,99,2, - 0,0,0,0,0,0,0,3,0,0,0,11,0,0,0,67, - 0,0,0,115,58,0,0,0,121,16,0,116,0,0,124,0, - 0,131,1,0,125,2,0,87,110,22,0,4,116,1,0,107, - 10,0,114,40,0,1,1,1,100,1,0,83,89,110,1,0, - 88,124,2,0,106,2,0,100,2,0,64,124,1,0,107,2, - 0,83,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, - 39,0,0,0,218,7,79,83,69,114,114,111,114,218,7,115, - 116,95,109,111,100,101,41,3,114,35,0,0,0,218,4,109, - 111,100,101,90,9,115,116,97,116,95,105,110,102,111,114,4, - 0,0,0,114,4,0,0,0,114,5,0,0,0,218,18,95, - 112,97,116,104,95,105,115,95,109,111,100,101,95,116,121,112, - 101,78,0,0,0,115,10,0,0,0,0,2,3,1,16,1, - 13,1,9,1,114,43,0,0,0,99,1,0,0,0,0,0, - 0,0,1,0,0,0,3,0,0,0,67,0,0,0,115,13, - 0,0,0,116,0,0,124,0,0,100,1,0,131,2,0,83, - 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,43,0,0,0,41, - 1,114,35,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,218,12,95,112,97,116,104,95,105,115,102, - 105,108,101,87,0,0,0,115,2,0,0,0,0,2,114,44, - 0,0,0,99,1,0,0,0,0,0,0,0,1,0,0,0, - 3,0,0,0,67,0,0,0,115,34,0,0,0,124,0,0, - 115,21,0,116,0,0,106,1,0,131,0,0,125,0,0,110, - 0,0,116,2,0,124,0,0,100,1,0,131,2,0,83,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,3,0,0,0,218,6,103, - 101,116,99,119,100,114,43,0,0,0,41,1,114,35,0,0, - 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 218,11,95,112,97,116,104,95,105,115,100,105,114,92,0,0, - 0,115,6,0,0,0,0,2,6,1,15,1,114,46,0,0, - 0,105,182,1,0,0,99,3,0,0,0,0,0,0,0,6, - 0,0,0,17,0,0,0,67,0,0,0,115,192,0,0,0, - 100,1,0,106,0,0,124,0,0,116,1,0,124,0,0,131, - 1,0,131,2,0,125,3,0,116,2,0,106,3,0,124,3, - 0,116,2,0,106,4,0,116,2,0,106,5,0,66,116,2, - 0,106,6,0,66,124,2,0,100,2,0,64,131,3,0,125, - 4,0,121,60,0,116,7,0,106,8,0,124,4,0,100,3, - 0,131,2,0,143,20,0,125,5,0,124,5,0,106,9,0, - 124,1,0,131,1,0,1,87,100,4,0,81,88,116,2,0, - 106,10,0,124,3,0,124,0,0,131,2,0,1,87,110,59, - 0,4,116,11,0,107,10,0,114,187,0,1,1,1,121,17, - 0,116,2,0,106,12,0,124,3,0,131,1,0,1,87,110, - 18,0,4,116,11,0,107,10,0,114,179,0,1,1,1,89, - 110,1,0,88,130,0,0,89,110,1,0,88,100,4,0,83, - 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,122,5,123,125,46,123,125,105,182,1, - 0,0,90,2,119,98,78,41,13,218,6,102,111,114,109,97, - 116,218,2,105,100,114,3,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,218, - 7,114,101,112,108,97,99,101,114,40,0,0,0,90,6,117, - 110,108,105,110,107,41,6,114,35,0,0,0,218,4,100,97, - 116,97,114,42,0,0,0,90,8,112,97,116,104,95,116,109, - 112,90,2,102,100,218,4,102,105,108,101,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,218,13,95,119,114,105, - 116,101,95,97,116,111,109,105,99,99,0,0,0,115,26,0, - 0,0,0,5,24,1,9,1,33,1,3,3,21,1,19,1, - 20,1,13,1,3,1,17,1,13,1,5,1,114,55,0,0, - 0,99,2,0,0,0,0,0,0,0,3,0,0,0,7,0, - 0,0,67,0,0,0,115,95,0,0,0,120,69,0,100,1, - 0,100,2,0,100,3,0,100,4,0,103,4,0,68,93,49, - 0,125,2,0,116,0,0,124,1,0,124,2,0,131,2,0, - 114,19,0,116,1,0,124,0,0,124,2,0,116,2,0,124, - 1,0,124,2,0,131,2,0,131,3,0,1,113,19,0,113, - 19,0,87,124,0,0,106,3,0,106,4,0,124,1,0,106, - 3,0,131,1,0,1,100,5,0,83,41,6,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,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,114,52,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,218,5,95,119,114,97, - 112,121,0,0,0,115,8,0,0,0,0,2,25,1,15,1, - 32,1,114,65,0,0,0,99,1,0,0,0,0,0,0,0, - 1,0,0,0,2,0,0,0,67,0,0,0,115,16,0,0, - 0,116,0,0,116,1,0,131,1,0,124,0,0,131,1,0, - 83,41,1,78,41,2,218,4,116,121,112,101,114,7,0,0, - 0,41,1,218,4,110,97,109,101,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,218,11,95,110,101,119,95,109, - 111,100,117,108,101,129,0,0,0,115,2,0,0,0,0,1, - 114,68,0,0,0,99,0,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,64,0,0,0,115,58,0,0,0,101, - 0,0,90,1,0,100,0,0,90,2,0,100,1,0,90,3, - 0,100,2,0,100,3,0,132,0,0,90,4,0,100,4,0, - 100,5,0,132,0,0,90,5,0,100,6,0,100,7,0,132, - 0,0,90,6,0,100,8,0,83,41,9,218,13,95,77,97, - 110,97,103,101,82,101,108,111,97,100,122,63,77,97,110,97, - 103,101,115,32,116,104,101,32,112,111,115,115,105,98,108,101, - 32,99,108,101,97,110,45,117,112,32,111,102,32,115,121,115, - 46,109,111,100,117,108,101,115,32,102,111,114,32,108,111,97, - 100,95,109,111,100,117,108,101,40,41,46,99,2,0,0,0, - 0,0,0,0,2,0,0,0,2,0,0,0,67,0,0,0, - 115,13,0,0,0,124,1,0,124,0,0,95,0,0,100,0, - 0,83,41,1,78,41,1,218,5,95,110,97,109,101,41,2, - 218,4,115,101,108,102,114,67,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,218,8,95,95,105,110, - 105,116,95,95,141,0,0,0,115,2,0,0,0,0,1,122, - 22,95,77,97,110,97,103,101,82,101,108,111,97,100,46,95, - 95,105,110,105,116,95,95,99,1,0,0,0,0,0,0,0, - 1,0,0,0,2,0,0,0,67,0,0,0,115,25,0,0, - 0,124,0,0,106,0,0,116,1,0,106,2,0,107,6,0, - 124,0,0,95,3,0,100,0,0,83,41,1,78,41,4,114, - 70,0,0,0,114,7,0,0,0,218,7,109,111,100,117,108, - 101,115,218,10,95,105,115,95,114,101,108,111,97,100,41,1, - 114,71,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,218,9,95,95,101,110,116,101,114,95,95,144, - 0,0,0,115,2,0,0,0,0,1,122,23,95,77,97,110, - 97,103,101,82,101,108,111,97,100,46,95,95,101,110,116,101, - 114,95,95,99,1,0,0,0,0,0,0,0,2,0,0,0, - 12,0,0,0,71,0,0,0,115,80,0,0,0,116,0,0, - 100,1,0,100,2,0,132,0,0,124,1,0,68,131,1,0, - 131,1,0,114,76,0,124,0,0,106,1,0,12,114,76,0, - 121,17,0,116,2,0,106,3,0,124,0,0,106,4,0,61, - 87,113,76,0,4,116,5,0,107,10,0,114,72,0,1,1, - 1,89,113,76,0,88,110,0,0,100,0,0,83,41,3,78, - 99,1,0,0,0,0,0,0,0,2,0,0,0,3,0,0, - 0,115,0,0,0,115,27,0,0,0,124,0,0,93,17,0, - 125,1,0,124,1,0,100,0,0,107,9,0,86,1,113,3, - 0,100,0,0,83,41,1,78,114,4,0,0,0,41,2,114, - 22,0,0,0,218,3,97,114,103,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,250,9,60,103,101,110,101,120, - 112,114,62,148,0,0,0,115,2,0,0,0,6,0,122,41, - 95,77,97,110,97,103,101,82,101,108,111,97,100,46,95,95, - 101,120,105,116,95,95,46,60,108,111,99,97,108,115,62,46, - 60,103,101,110,101,120,112,114,62,41,6,218,3,97,110,121, - 114,74,0,0,0,114,7,0,0,0,114,73,0,0,0,114, - 70,0,0,0,218,8,75,101,121,69,114,114,111,114,41,2, - 114,71,0,0,0,218,4,97,114,103,115,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,218,8,95,95,101,120, - 105,116,95,95,147,0,0,0,115,10,0,0,0,0,1,35, - 1,3,1,17,1,13,1,122,22,95,77,97,110,97,103,101, - 82,101,108,111,97,100,46,95,95,101,120,105,116,95,95,78, - 41,7,114,57,0,0,0,114,56,0,0,0,114,58,0,0, - 0,114,59,0,0,0,114,72,0,0,0,114,75,0,0,0, - 114,81,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,114,69,0,0,0,137,0, - 0,0,115,8,0,0,0,12,2,6,2,12,3,12,3,114, - 69,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, - 0,1,0,0,0,64,0,0,0,115,16,0,0,0,101,0, - 0,90,1,0,100,0,0,90,2,0,100,1,0,83,41,2, - 218,14,95,68,101,97,100,108,111,99,107,69,114,114,111,114, - 78,41,3,114,57,0,0,0,114,56,0,0,0,114,58,0, - 0,0,114,4,0,0,0,114,4,0,0,0,114,4,0,0, - 0,114,5,0,0,0,114,82,0,0,0,162,0,0,0,115, - 2,0,0,0,12,1,114,82,0,0,0,99,0,0,0,0, + 104,105,115,32,109,111,100,117,108,101,46,10,10,78,99,2, + 0,0,0,0,0,0,0,3,0,0,0,7,0,0,0,67, + 0,0,0,115,92,0,0,0,120,66,0,100,1,0,100,2, + 0,100,3,0,100,4,0,103,4,0,68,93,46,0,125,2, + 0,116,0,0,124,1,0,124,2,0,131,2,0,114,19,0, + 116,1,0,124,0,0,124,2,0,116,2,0,124,1,0,124, + 2,0,131,2,0,131,3,0,1,113,19,0,87,124,0,0, + 106,3,0,106,4,0,124,1,0,106,3,0,131,1,0,1, + 100,5,0,83,41,6,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,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,25,1,15,1,29,1,114,12,0,0,0,99,1,0,0, + 0,0,0,0,0,1,0,0,0,2,0,0,0,67,0,0, + 0,115,16,0,0,0,116,0,0,116,1,0,131,1,0,124, + 0,0,131,1,0,83,41,1,78,41,2,218,4,116,121,112, + 101,218,3,115,121,115,41,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,16,0,0,0,99,0,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,64,0,0,0,115, + 58,0,0,0,101,0,0,90,1,0,100,0,0,90,2,0, + 100,1,0,90,3,0,100,2,0,100,3,0,132,0,0,90, + 4,0,100,4,0,100,5,0,132,0,0,90,5,0,100,6, + 0,100,7,0,132,0,0,90,6,0,100,8,0,83,41,9, + 218,13,95,77,97,110,97,103,101,82,101,108,111,97,100,122, + 63,77,97,110,97,103,101,115,32,116,104,101,32,112,111,115, + 115,105,98,108,101,32,99,108,101,97,110,45,117,112,32,111, + 102,32,115,121,115,46,109,111,100,117,108,101,115,32,102,111, + 114,32,108,111,97,100,95,109,111,100,117,108,101,40,41,46, + 99,2,0,0,0,0,0,0,0,2,0,0,0,2,0,0, + 0,67,0,0,0,115,13,0,0,0,124,1,0,124,0,0, + 95,0,0,100,0,0,83,41,1,78,41,1,218,5,95,110, + 97,109,101,41,2,218,4,115,101,108,102,114,15,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,43,0,0,0,115,2,0, + 0,0,0,1,122,22,95,77,97,110,97,103,101,82,101,108, + 111,97,100,46,95,95,105,110,105,116,95,95,99,1,0,0, + 0,0,0,0,0,1,0,0,0,2,0,0,0,67,0,0, + 0,115,25,0,0,0,124,0,0,106,0,0,116,1,0,106, + 2,0,107,6,0,124,0,0,95,3,0,100,0,0,83,41, + 1,78,41,4,114,18,0,0,0,114,14,0,0,0,218,7, + 109,111,100,117,108,101,115,218,10,95,105,115,95,114,101,108, + 111,97,100,41,1,114,19,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,46,0,0,0,115,2,0,0,0,0,1,122, + 23,95,77,97,110,97,103,101,82,101,108,111,97,100,46,95, + 95,101,110,116,101,114,95,95,99,1,0,0,0,0,0,0, + 0,2,0,0,0,11,0,0,0,71,0,0,0,115,77,0, + 0,0,116,0,0,100,1,0,100,2,0,132,0,0,124,1, + 0,68,131,1,0,131,1,0,114,73,0,124,0,0,106,1, + 0,12,114,73,0,121,17,0,116,2,0,106,3,0,124,0, + 0,106,4,0,61,87,110,18,0,4,116,5,0,107,10,0, + 114,72,0,1,1,1,89,110,1,0,88,100,0,0,83,41, + 3,78,99,1,0,0,0,0,0,0,0,2,0,0,0,3, + 0,0,0,115,0,0,0,115,27,0,0,0,124,0,0,93, + 17,0,125,1,0,124,1,0,100,0,0,107,9,0,86,1, + 113,3,0,100,0,0,83,41,1,78,114,10,0,0,0,41, + 2,218,2,46,48,218,3,97,114,103,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,250,9,60,103,101,110,101, + 120,112,114,62,50,0,0,0,115,2,0,0,0,6,0,122, + 41,95,77,97,110,97,103,101,82,101,108,111,97,100,46,95, + 95,101,120,105,116,95,95,46,60,108,111,99,97,108,115,62, + 46,60,103,101,110,101,120,112,114,62,41,6,218,3,97,110, + 121,114,22,0,0,0,114,14,0,0,0,114,21,0,0,0, + 114,18,0,0,0,218,8,75,101,121,69,114,114,111,114,41, + 2,114,19,0,0,0,218,4,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,49,0,0,0,115,10,0,0,0,0,1, + 35,1,3,1,17,1,13,1,122,22,95,77,97,110,97,103, + 101,82,101,108,111,97,100,46,95,95,101,120,105,116,95,95, + 78,41,7,114,1,0,0,0,114,0,0,0,0,114,2,0, + 0,0,114,3,0,0,0,114,20,0,0,0,114,23,0,0, + 0,114,30,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,17,0,0,0,39, + 0,0,0,115,8,0,0,0,12,2,6,2,12,3,12,3, + 114,17,0,0,0,99,0,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,64,0,0,0,115,16,0,0,0,101, + 0,0,90,1,0,100,0,0,90,2,0,100,1,0,83,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,31,0,0,0,64,0,0,0, + 115,2,0,0,0,12,1,114,31,0,0,0,99,0,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,64,0,0, + 0,115,82,0,0,0,101,0,0,90,1,0,100,0,0,90, + 2,0,100,1,0,90,3,0,100,2,0,100,3,0,132,0, + 0,90,4,0,100,4,0,100,5,0,132,0,0,90,5,0, + 100,6,0,100,7,0,132,0,0,90,6,0,100,8,0,100, + 9,0,132,0,0,90,7,0,100,10,0,100,11,0,132,0, + 0,90,8,0,100,12,0,83,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,2,0,0,0,2, + 0,0,0,67,0,0,0,115,70,0,0,0,116,0,0,106, + 1,0,131,0,0,124,0,0,95,2,0,116,0,0,106,1, + 0,131,0,0,124,0,0,95,3,0,124,1,0,124,0,0, + 95,4,0,100,0,0,124,0,0,95,5,0,100,1,0,124, + 0,0,95,6,0,100,1,0,124,0,0,95,7,0,100,0, + 0,83,41,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,15,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,41,2, + 114,19,0,0,0,114,15,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,20,0,0,0,74,0, + 0,0,115,12,0,0,0,0,1,15,1,15,1,9,1,9, + 1,9,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,4,0,0,0,2,0,0,0,67,0,0,0,115,88, + 0,0,0,116,0,0,106,1,0,131,0,0,125,1,0,124, + 0,0,106,2,0,125,2,0,120,60,0,116,3,0,106,4, + 0,124,2,0,131,1,0,125,3,0,124,3,0,100,0,0, + 107,8,0,114,55,0,100,1,0,83,124,3,0,106,2,0, + 125,2,0,124,2,0,124,1,0,107,2,0,114,24,0,100, + 2,0,83,113,24,0,87,100,0,0,83,41,3,78,70,84, + 41,5,114,34,0,0,0,218,9,103,101,116,95,105,100,101, + 110,116,114,37,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,19,0,0, + 0,90,2,109,101,218,3,116,105,100,114,35,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,82,0,0,0, + 115,18,0,0,0,0,2,12,1,9,1,3,1,15,1,12, + 1,4,1,9,1,12,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,2,0,0,0,16,0, + 0,0,67,0,0,0,115,210,0,0,0,116,0,0,106,1, + 0,131,0,0,125,1,0,124,0,0,116,2,0,124,1,0, + 60,122,173,0,120,166,0,124,0,0,106,3,0,143,124,0, + 1,124,0,0,106,4,0,100,1,0,107,2,0,115,68,0, + 124,0,0,106,5,0,124,1,0,107,2,0,114,96,0,124, + 1,0,124,0,0,95,5,0,124,0,0,4,106,4,0,100, + 2,0,55,2,95,4,0,100,3,0,83,124,0,0,106,6, + 0,131,0,0,114,124,0,116,7,0,100,4,0,124,0,0, + 22,131,1,0,130,1,0,124,0,0,106,8,0,106,9,0, + 100,5,0,131,1,0,114,157,0,124,0,0,4,106,10,0, + 100,2,0,55,2,95,10,0,87,100,6,0,81,82,88,124, + 0,0,106,8,0,106,9,0,131,0,0,1,124,0,0,106, + 8,0,106,11,0,131,0,0,1,113,28,0,87,87,100,6, + 0,116,2,0,124,1,0,61,88,100,6,0,83,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,33,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,34,0,0,0,114,40,0,0,0,114,41,0,0, + 0,114,35,0,0,0,114,38,0,0,0,114,37,0,0,0, + 114,44,0,0,0,114,31,0,0,0,114,36,0,0,0,218, + 7,97,99,113,117,105,114,101,114,39,0,0,0,218,7,114, + 101,108,101,97,115,101,41,2,114,19,0,0,0,114,43,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,46,0,0,0,94,0,0,0,115,32,0,0,0,0, + 6,12,1,10,1,3,1,3,1,10,1,30,1,9,1,15, + 1,4,1,12,1,16,1,18,1,22,2,13,1,21,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,2,0,0, + 0,10,0,0,0,67,0,0,0,115,157,0,0,0,116,0, + 0,106,1,0,131,0,0,125,1,0,124,0,0,106,2,0, + 143,129,0,1,124,0,0,106,3,0,124,1,0,107,3,0, + 114,49,0,116,4,0,100,1,0,131,1,0,130,1,0,124, + 0,0,106,5,0,100,2,0,107,4,0,115,70,0,116,6, + 0,130,1,0,124,0,0,4,106,5,0,100,3,0,56,2, + 95,5,0,124,0,0,106,5,0,100,2,0,107,2,0,114, + 146,0,100,0,0,124,0,0,95,3,0,124,0,0,106,7, + 0,114,146,0,124,0,0,4,106,7,0,100,3,0,56,2, + 95,7,0,124,0,0,106,8,0,106,9,0,131,0,0,1, + 87,100,0,0,81,82,88,100,0,0,83,41,4,78,122,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, + 33,0,0,0,114,45,0,0,0,41,10,114,34,0,0,0, + 114,40,0,0,0,114,35,0,0,0,114,37,0,0,0,218, + 12,82,117,110,116,105,109,101,69,114,114,111,114,114,38,0, + 0,0,218,14,65,115,115,101,114,116,105,111,110,69,114,114, + 111,114,114,39,0,0,0,114,36,0,0,0,114,47,0,0, + 0,41,2,114,19,0,0,0,114,43,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,114,47,0,0, + 0,119,0,0,0,115,22,0,0,0,0,1,12,1,10,1, + 15,1,12,1,21,1,15,1,15,1,9,1,9,1,15,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,1,0, + 0,0,4,0,0,0,67,0,0,0,115,25,0,0,0,100, + 1,0,106,0,0,124,0,0,106,1,0,116,2,0,124,0, + 0,131,1,0,131,2,0,83,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,41,3,218,6,102,111,114,109,97,116,114,15, + 0,0,0,218,2,105,100,41,1,114,19,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,132,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, + 20,0,0,0,114,44,0,0,0,114,46,0,0,0,114,47, + 0,0,0,114,52,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,0,0, + 0,68,0,0,0,115,12,0,0,0,12,4,6,2,12,8, + 12,12,12,25,12,13,114,32,0,0,0,99,0,0,0,0, 0,0,0,0,0,0,0,0,2,0,0,0,64,0,0,0, - 115,82,0,0,0,101,0,0,90,1,0,100,0,0,90,2, + 115,70,0,0,0,101,0,0,90,1,0,100,0,0,90,2, 0,100,1,0,90,3,0,100,2,0,100,3,0,132,0,0, 90,4,0,100,4,0,100,5,0,132,0,0,90,5,0,100, 6,0,100,7,0,132,0,0,90,6,0,100,8,0,100,9, - 0,132,0,0,90,7,0,100,10,0,100,11,0,132,0,0, - 90,8,0,100,12,0,83,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,2,0,0,0,2,0, - 0,0,67,0,0,0,115,70,0,0,0,116,0,0,106,1, - 0,131,0,0,124,0,0,95,2,0,116,0,0,106,1,0, - 131,0,0,124,0,0,95,3,0,124,1,0,124,0,0,95, - 4,0,100,0,0,124,0,0,95,5,0,100,1,0,124,0, - 0,95,6,0,100,1,0,124,0,0,95,7,0,100,0,0, - 83,41,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,67,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,41,2,114, - 71,0,0,0,114,67,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,72,0,0,0,172,0,0, - 0,115,12,0,0,0,0,1,15,1,15,1,9,1,9,1, - 9,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,4,0,0,0,2,0,0,0,67,0,0,0,115,87,0, - 0,0,116,0,0,106,1,0,131,0,0,125,1,0,124,0, - 0,106,2,0,125,2,0,120,59,0,116,3,0,106,4,0, - 124,2,0,131,1,0,125,3,0,124,3,0,100,0,0,107, - 8,0,114,55,0,100,1,0,83,124,3,0,106,2,0,125, - 2,0,124,2,0,124,1,0,107,2,0,114,24,0,100,2, - 0,83,113,24,0,100,0,0,83,41,3,78,70,84,41,5, - 114,85,0,0,0,218,9,103,101,116,95,105,100,101,110,116, - 114,88,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,71,0,0,0,218, - 2,109,101,218,3,116,105,100,114,86,0,0,0,114,4,0, - 0,0,114,4,0,0,0,114,5,0,0,0,218,12,104,97, - 115,95,100,101,97,100,108,111,99,107,180,0,0,0,115,18, - 0,0,0,0,2,12,1,9,1,3,1,15,1,12,1,4, - 1,9,1,12,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,2,0,0,0,17,0,0,0, - 67,0,0,0,115,214,0,0,0,116,0,0,106,1,0,131, - 0,0,125,1,0,124,0,0,116,2,0,124,1,0,60,122, - 177,0,120,170,0,124,0,0,106,3,0,143,130,0,1,124, - 0,0,106,4,0,100,1,0,107,2,0,115,68,0,124,0, - 0,106,5,0,124,1,0,107,2,0,114,96,0,124,1,0, - 124,0,0,95,5,0,124,0,0,4,106,4,0,100,2,0, - 55,2,95,4,0,100,3,0,83,124,0,0,106,6,0,131, - 0,0,114,127,0,116,7,0,100,4,0,124,0,0,22,131, - 1,0,130,1,0,110,0,0,124,0,0,106,8,0,106,9, - 0,100,5,0,131,1,0,114,163,0,124,0,0,4,106,10, - 0,100,2,0,55,2,95,10,0,110,0,0,87,100,6,0, - 81,88,124,0,0,106,8,0,106,9,0,131,0,0,1,124, - 0,0,106,8,0,106,11,0,131,0,0,1,113,28,0,87, - 100,6,0,116,2,0,124,1,0,61,88,100,6,0,83,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,84,0,0, - 0,114,29,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,85,0,0,0,114,91,0,0,0,114,92, - 0,0,0,114,86,0,0,0,114,89,0,0,0,114,88,0, - 0,0,114,96,0,0,0,114,82,0,0,0,114,87,0,0, - 0,218,7,97,99,113,117,105,114,101,114,90,0,0,0,218, - 7,114,101,108,101,97,115,101,41,2,114,71,0,0,0,114, - 95,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,97,0,0,0,192,0,0,0,115,32,0,0, - 0,0,6,12,1,10,1,3,1,3,1,10,1,30,1,9, - 1,15,1,4,1,12,1,19,1,18,1,24,2,13,1,20, - 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,2, - 0,0,0,10,0,0,0,67,0,0,0,115,165,0,0,0, - 116,0,0,106,1,0,131,0,0,125,1,0,124,0,0,106, - 2,0,143,138,0,1,124,0,0,106,3,0,124,1,0,107, - 3,0,114,52,0,116,4,0,100,1,0,131,1,0,130,1, - 0,110,0,0,124,0,0,106,5,0,100,2,0,107,4,0, - 115,73,0,116,6,0,130,1,0,124,0,0,4,106,5,0, - 100,3,0,56,2,95,5,0,124,0,0,106,5,0,100,2, - 0,107,2,0,114,155,0,100,0,0,124,0,0,95,3,0, - 124,0,0,106,7,0,114,155,0,124,0,0,4,106,7,0, - 100,3,0,56,2,95,7,0,124,0,0,106,8,0,106,9, - 0,131,0,0,1,113,155,0,110,0,0,87,100,0,0,81, - 88,100,0,0,83,41,4,78,122,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,84,0,0,0,114,29, - 0,0,0,41,10,114,85,0,0,0,114,91,0,0,0,114, - 86,0,0,0,114,88,0,0,0,218,12,82,117,110,116,105, - 109,101,69,114,114,111,114,114,89,0,0,0,218,14,65,115, - 115,101,114,116,105,111,110,69,114,114,111,114,114,90,0,0, - 0,114,87,0,0,0,114,98,0,0,0,41,2,114,71,0, - 0,0,114,95,0,0,0,114,4,0,0,0,114,4,0,0, - 0,114,5,0,0,0,114,98,0,0,0,217,0,0,0,115, - 22,0,0,0,0,1,12,1,10,1,15,1,15,1,21,1, - 15,1,15,1,9,1,9,1,15,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,1,0,0,0,4,0,0,0, - 67,0,0,0,115,25,0,0,0,100,1,0,106,0,0,124, - 0,0,106,1,0,116,2,0,124,0,0,131,1,0,131,2, - 0,83,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,41,3, - 114,47,0,0,0,114,67,0,0,0,114,48,0,0,0,41, - 1,114,71,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,218,8,95,95,114,101,112,114,95,95,230, - 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,57,0,0,0,114,56,0,0,0,114,58,0, - 0,0,114,59,0,0,0,114,72,0,0,0,114,96,0,0, - 0,114,97,0,0,0,114,98,0,0,0,114,101,0,0,0, - 114,4,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,114,83,0,0,0,166,0,0,0,115,12,0, - 0,0,12,4,6,2,12,8,12,12,12,25,12,13,114,83, - 0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,64,0,0,0,115,70,0,0,0,101,0,0, - 90,1,0,100,0,0,90,2,0,100,1,0,90,3,0,100, - 2,0,100,3,0,132,0,0,90,4,0,100,4,0,100,5, - 0,132,0,0,90,5,0,100,6,0,100,7,0,132,0,0, - 90,6,0,100,8,0,100,9,0,132,0,0,90,7,0,100, - 10,0,83,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,2,0,0,0,2,0,0,0, - 67,0,0,0,115,22,0,0,0,124,1,0,124,0,0,95, - 0,0,100,1,0,124,0,0,95,1,0,100,0,0,83,41, - 2,78,114,84,0,0,0,41,2,114,67,0,0,0,114,89, - 0,0,0,41,2,114,71,0,0,0,114,67,0,0,0,114, - 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,72, - 0,0,0,238,0,0,0,115,4,0,0,0,0,1,9,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,1,0,0,0,3,0,0,0,67,0,0,0, - 115,19,0,0,0,124,0,0,4,106,0,0,100,1,0,55, - 2,95,0,0,100,2,0,83,41,3,78,114,29,0,0,0, - 84,41,1,114,89,0,0,0,41,1,114,71,0,0,0,114, - 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,97, - 0,0,0,242,0,0,0,115,4,0,0,0,0,1,15,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,1,0,0,0,3,0,0,0,67,0,0,0,115, - 49,0,0,0,124,0,0,106,0,0,100,1,0,107,2,0, - 114,30,0,116,1,0,100,2,0,131,1,0,130,1,0,110, - 0,0,124,0,0,4,106,0,0,100,3,0,56,2,95,0, - 0,100,0,0,83,41,4,78,114,84,0,0,0,122,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,29, - 0,0,0,41,2,114,89,0,0,0,114,99,0,0,0,41, - 1,114,71,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,98,0,0,0,246,0,0,0,115,6, - 0,0,0,0,1,15,1,15,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,1,0,0,0, - 4,0,0,0,67,0,0,0,115,25,0,0,0,100,1,0, - 106,0,0,124,0,0,106,1,0,116,2,0,124,0,0,131, - 1,0,131,2,0,83,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,41,3,114,47,0,0,0,114,67, - 0,0,0,114,48,0,0,0,41,1,114,71,0,0,0,114, - 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,101, - 0,0,0,251,0,0,0,115,2,0,0,0,0,1,122,25, + 0,132,0,0,90,7,0,100,10,0,83,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, + 2,0,0,0,2,0,0,0,67,0,0,0,115,22,0,0, + 0,124,1,0,124,0,0,95,0,0,100,1,0,124,0,0, + 95,1,0,100,0,0,83,41,2,78,114,33,0,0,0,41, + 2,114,15,0,0,0,114,38,0,0,0,41,2,114,19,0, + 0,0,114,15,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,114,20,0,0,0,140,0,0,0,115, + 4,0,0,0,0,1,9,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,1,0,0,0, + 3,0,0,0,67,0,0,0,115,19,0,0,0,124,0,0, + 4,106,0,0,100,1,0,55,2,95,0,0,100,2,0,83, + 41,3,78,114,45,0,0,0,84,41,1,114,38,0,0,0, + 41,1,114,19,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,114,46,0,0,0,144,0,0,0,115, + 4,0,0,0,0,1,15,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,1,0,0,0,3, + 0,0,0,67,0,0,0,115,46,0,0,0,124,0,0,106, + 0,0,100,1,0,107,2,0,114,27,0,116,1,0,100,2, + 0,131,1,0,130,1,0,124,0,0,4,106,0,0,100,3, + 0,56,2,95,0,0,100,0,0,83,41,4,78,114,33,0, + 0,0,122,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,45,0,0,0,41,2,114,38,0,0,0,114, + 48,0,0,0,41,1,114,19,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,47,0,0,0,148, + 0,0,0,115,6,0,0,0,0,1,15,1,12,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,1,0,0,0,4,0,0,0,67,0,0,0,115,25,0, + 0,0,100,1,0,106,0,0,124,0,0,106,1,0,116,2, + 0,124,0,0,131,1,0,131,2,0,83,41,2,78,122,28, 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,57,0,0, - 0,114,56,0,0,0,114,58,0,0,0,114,59,0,0,0, - 114,72,0,0,0,114,97,0,0,0,114,98,0,0,0,114, - 101,0,0,0,114,4,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,102,0,0,0,234,0,0, - 0,115,10,0,0,0,12,2,6,2,12,4,12,4,12,5, - 114,102,0,0,0,99,0,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,64,0,0,0,115,52,0,0,0,101, - 0,0,90,1,0,100,0,0,90,2,0,100,1,0,100,2, - 0,132,0,0,90,3,0,100,3,0,100,4,0,132,0,0, - 90,4,0,100,5,0,100,6,0,132,0,0,90,5,0,100, - 7,0,83,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,2,0,0,0,2,0,0,0,67,0,0,0,115,22, - 0,0,0,124,1,0,124,0,0,95,0,0,100,0,0,124, - 0,0,95,1,0,100,0,0,83,41,1,78,41,2,114,70, - 0,0,0,218,5,95,108,111,99,107,41,2,114,71,0,0, - 0,114,67,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,72,0,0,0,1,1,0,0,115,4, - 0,0,0,0,1,9,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,1,0,0, - 0,10,0,0,0,67,0,0,0,115,53,0,0,0,122,22, - 0,116,0,0,124,0,0,106,1,0,131,1,0,124,0,0, - 95,2,0,87,100,0,0,116,3,0,106,4,0,131,0,0, - 1,88,124,0,0,106,2,0,106,5,0,131,0,0,1,100, - 0,0,83,41,1,78,41,6,218,16,95,103,101,116,95,109, - 111,100,117,108,101,95,108,111,99,107,114,70,0,0,0,114, - 104,0,0,0,218,4,95,105,109,112,218,12,114,101,108,101, - 97,115,101,95,108,111,99,107,114,97,0,0,0,41,1,114, - 71,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,75,0,0,0,5,1,0,0,115,8,0,0, - 0,0,1,3,1,22,2,11,1,122,28,95,77,111,100,117, + 40,123,33,114,125,41,32,97,116,32,123,125,41,3,114,50, + 0,0,0,114,15,0,0,0,114,51,0,0,0,41,1,114, + 19,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,114,52,0,0,0,153,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,20,0,0,0,114,46,0,0,0,114, + 47,0,0,0,114,52,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,53,0, + 0,0,136,0,0,0,115,10,0,0,0,12,2,6,2,12, + 4,12,4,12,5,114,53,0,0,0,99,0,0,0,0,0, + 0,0,0,0,0,0,0,2,0,0,0,64,0,0,0,115, + 52,0,0,0,101,0,0,90,1,0,100,0,0,90,2,0, + 100,1,0,100,2,0,132,0,0,90,3,0,100,3,0,100, + 4,0,132,0,0,90,4,0,100,5,0,100,6,0,132,0, + 0,90,5,0,100,7,0,83,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,2,0,0,0,2,0,0,0,67, + 0,0,0,115,22,0,0,0,124,1,0,124,0,0,95,0, + 0,100,0,0,124,0,0,95,1,0,100,0,0,83,41,1, + 78,41,2,114,18,0,0,0,218,5,95,108,111,99,107,41, + 2,114,19,0,0,0,114,15,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,20,0,0,0,159, + 0,0,0,115,4,0,0,0,0,1,9,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,1,0,0,0,10,0,0,0,67,0,0,0,115,53, + 0,0,0,122,22,0,116,0,0,124,0,0,106,1,0,131, + 1,0,124,0,0,95,2,0,87,100,0,0,116,3,0,106, + 4,0,131,0,0,1,88,124,0,0,106,2,0,106,5,0, + 131,0,0,1,100,0,0,83,41,1,78,41,6,218,16,95, + 103,101,116,95,109,111,100,117,108,101,95,108,111,99,107,114, + 18,0,0,0,114,55,0,0,0,218,4,95,105,109,112,218, + 12,114,101,108,101,97,115,101,95,108,111,99,107,114,46,0, + 0,0,41,1,114,19,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,23,0,0,0,163,0,0, + 0,115,8,0,0,0,0,1,3,1,22,2,11,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,3,0,0,0,1,0,0,0,79,0,0, + 0,115,17,0,0,0,124,0,0,106,0,0,106,1,0,131, + 0,0,1,100,0,0,83,41,1,78,41,2,114,55,0,0, + 0,114,47,0,0,0,41,3,114,19,0,0,0,114,29,0, + 0,0,90,6,107,119,97,114,103,115,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,30,0,0,0,170,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,110,116,101,114,95,95,99,1,0,0,0,0,0,0,0, - 3,0,0,0,1,0,0,0,79,0,0,0,115,17,0,0, - 0,124,0,0,106,0,0,106,1,0,131,0,0,1,100,0, - 0,83,41,1,78,41,2,114,104,0,0,0,114,98,0,0, - 0,41,3,114,71,0,0,0,114,80,0,0,0,218,6,107, - 119,97,114,103,115,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,114,81,0,0,0,12,1,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,57,0,0,0,114,56,0,0,0,114,58, - 0,0,0,114,72,0,0,0,114,75,0,0,0,114,81,0, - 0,0,114,4,0,0,0,114,4,0,0,0,114,4,0,0, - 0,114,5,0,0,0,114,103,0,0,0,255,0,0,0,115, - 6,0,0,0,12,2,12,4,12,7,114,103,0,0,0,99, - 1,0,0,0,0,0,0,0,3,0,0,0,11,0,0,0, - 3,0,0,0,115,142,0,0,0,100,1,0,125,1,0,121, - 17,0,116,0,0,136,0,0,25,131,0,0,125,1,0,87, - 110,18,0,4,116,1,0,107,10,0,114,43,0,1,1,1, - 89,110,1,0,88,124,1,0,100,1,0,107,8,0,114,138, - 0,116,2,0,100,1,0,107,8,0,114,83,0,116,3,0, - 136,0,0,131,1,0,125,1,0,110,12,0,116,4,0,136, - 0,0,131,1,0,125,1,0,135,0,0,102,1,0,100,2, - 0,100,3,0,134,0,0,125,2,0,116,5,0,106,6,0, - 124,1,0,124,2,0,131,2,0,116,0,0,136,0,0,60, - 110,0,0,124,1,0,83,41,4,122,109,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,83,104,111,117,108,100,32,111,110, - 108,121,32,98,101,32,99,97,108,108,101,100,32,119,105,116, - 104,32,116,104,101,32,105,109,112,111,114,116,32,108,111,99, - 107,32,116,97,107,101,110,46,78,99,1,0,0,0,0,0, - 0,0,1,0,0,0,2,0,0,0,19,0,0,0,115,11, - 0,0,0,116,0,0,136,0,0,61,100,0,0,83,41,1, - 78,41,1,218,13,95,109,111,100,117,108,101,95,108,111,99, - 107,115,41,1,114,36,0,0,0,41,1,114,67,0,0,0, - 114,4,0,0,0,114,5,0,0,0,218,2,99,98,32,1, + 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,20,0,0,0,114,23,0, + 0,0,114,30,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,54,0,0,0, + 157,0,0,0,115,6,0,0,0,12,2,12,4,12,7,114, + 54,0,0,0,99,1,0,0,0,0,0,0,0,3,0,0, + 0,11,0,0,0,3,0,0,0,115,139,0,0,0,100,1, + 0,125,1,0,121,17,0,116,0,0,136,0,0,25,131,0, + 0,125,1,0,87,110,18,0,4,116,1,0,107,10,0,114, + 43,0,1,1,1,89,110,1,0,88,124,1,0,100,1,0, + 107,8,0,114,135,0,116,2,0,100,1,0,107,8,0,114, + 83,0,116,3,0,136,0,0,131,1,0,125,1,0,110,12, + 0,116,4,0,136,0,0,131,1,0,125,1,0,135,0,0, + 102,1,0,100,2,0,100,3,0,134,0,0,125,2,0,116, + 5,0,106,6,0,124,1,0,124,2,0,131,2,0,116,0, + 0,136,0,0,60,124,1,0,83,41,4,122,109,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,83,104,111,117,108,100,32, + 111,110,108,121,32,98,101,32,99,97,108,108,101,100,32,119, + 105,116,104,32,116,104,101,32,105,109,112,111,114,116,32,108, + 111,99,107,32,116,97,107,101,110,46,78,99,1,0,0,0, + 0,0,0,0,1,0,0,0,2,0,0,0,19,0,0,0, + 115,11,0,0,0,116,0,0,136,0,0,61,100,0,0,83, + 41,1,78,41,1,218,13,95,109,111,100,117,108,101,95,108, + 111,99,107,115,41,1,218,1,95,41,1,114,15,0,0,0, + 114,10,0,0,0,114,11,0,0,0,218,2,99,98,190,0, 0,0,115,2,0,0,0,0,1,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,7,114,109,0,0,0,114,79, - 0,0,0,114,85,0,0,0,114,102,0,0,0,114,83,0, + 97,108,115,62,46,99,98,41,7,114,59,0,0,0,114,28, + 0,0,0,114,34,0,0,0,114,53,0,0,0,114,32,0, 0,0,218,8,95,119,101,97,107,114,101,102,90,3,114,101, - 102,41,3,114,67,0,0,0,114,86,0,0,0,114,110,0, - 0,0,114,4,0,0,0,41,1,114,67,0,0,0,114,5, - 0,0,0,114,105,0,0,0,18,1,0,0,115,24,0,0, + 102,41,3,114,15,0,0,0,114,35,0,0,0,114,61,0, + 0,0,114,10,0,0,0,41,1,114,15,0,0,0,114,11, + 0,0,0,114,56,0,0,0,176,0,0,0,115,24,0,0, 0,0,4,6,1,3,1,17,1,13,1,5,1,12,1,12, - 1,15,2,12,1,18,2,25,1,114,105,0,0,0,99,1, + 1,15,2,12,1,18,2,22,1,114,56,0,0,0,99,1, 0,0,0,0,0,0,0,2,0,0,0,11,0,0,0,67, 0,0,0,115,71,0,0,0,116,0,0,124,0,0,131,1, 0,125,1,0,116,1,0,106,2,0,131,0,0,1,121,14, @@ -667,14 +444,14 @@ const unsigned char _Py_M__importlib[] = { 101,97,100,46,10,10,32,32,32,32,83,104,111,117,108,100, 32,111,110,108,121,32,98,101,32,99,97,108,108,101,100,32, 119,105,116,104,32,116,104,101,32,105,109,112,111,114,116,32, - 108,111,99,107,32,116,97,107,101,110,46,78,41,6,114,105, - 0,0,0,114,106,0,0,0,114,107,0,0,0,114,97,0, - 0,0,114,82,0,0,0,114,98,0,0,0,41,2,114,67, - 0,0,0,114,86,0,0,0,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,218,19,95,108,111,99,107,95,117, - 110,108,111,99,107,95,109,111,100,117,108,101,37,1,0,0, + 108,111,99,107,32,116,97,107,101,110,46,78,41,6,114,56, + 0,0,0,114,57,0,0,0,114,58,0,0,0,114,46,0, + 0,0,114,31,0,0,0,114,47,0,0,0,41,2,114,15, + 0,0,0,114,35,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,195,0,0,0, 115,14,0,0,0,0,7,12,1,10,1,3,1,14,1,13, - 3,5,2,114,112,0,0,0,99,1,0,0,0,0,0,0, + 3,5,2,114,63,0,0,0,99,1,0,0,0,0,0,0, 0,3,0,0,0,3,0,0,0,79,0,0,0,115,13,0, 0,0,124,0,0,124,1,0,124,2,0,142,0,0,83,41, 1,97,46,1,0,0,114,101,109,111,118,101,95,105,109,112, @@ -696,1479 +473,900 @@ const unsigned char _Py_M__importlib[] = { 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,4,0,0,0,41,3,218,1,102,114,80, - 0,0,0,90,4,107,119,100,115,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,218,25,95,99,97,108,108,95, + 32,32,32,32,114,10,0,0,0,41,3,218,1,102,114,29, + 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,57,1,0,0,115,2,0,0,0,0,8,114,114, - 0,0,0,105,228,12,0,0,233,2,0,0,0,114,13,0, - 0,0,115,2,0,0,0,13,10,90,11,95,95,112,121,99, - 97,99,104,101,95,95,122,3,46,112,121,122,4,46,112,121, - 99,122,4,46,112,121,111,78,99,2,0,0,0,0,0,0, - 0,11,0,0,0,6,0,0,0,67,0,0,0,115,180,0, - 0,0,124,1,0,100,1,0,107,8,0,114,25,0,116,0, - 0,106,1,0,106,2,0,12,110,3,0,124,1,0,125,2, - 0,124,2,0,114,46,0,116,3,0,125,3,0,110,6,0, - 116,4,0,125,3,0,116,5,0,124,0,0,131,1,0,92, - 2,0,125,4,0,125,5,0,124,5,0,106,6,0,100,2, - 0,131,1,0,92,3,0,125,6,0,125,7,0,125,8,0, - 116,0,0,106,7,0,106,8,0,125,9,0,124,9,0,100, - 1,0,107,8,0,114,133,0,116,9,0,100,3,0,131,1, - 0,130,1,0,110,0,0,100,4,0,106,10,0,124,6,0, - 124,7,0,124,9,0,124,3,0,100,5,0,25,103,4,0, - 131,1,0,125,10,0,116,11,0,124,4,0,116,12,0,124, - 10,0,131,3,0,83,41,6,97,244,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,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,47,46,112,121,111,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,47,46,112,121,111,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,32, - 32,84,104,101,32,101,120,116,101,110,115,105,111,110,10,32, - 32,32,32,119,105,108,108,32,98,101,32,46,112,121,99,32, - 117,110,108,101,115,115,32,115,121,115,46,102,108,97,103,115, - 46,111,112,116,105,109,105,122,101,32,105,115,32,110,111,110, - 45,122,101,114,111,44,32,116,104,101,110,32,105,116,32,119, - 105,108,108,32,98,101,32,46,112,121,111,46,10,10,32,32, - 32,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, - 32,116,104,101,110,32,105,116,32,109,117,115,116,32,98,101, - 32,97,32,98,111,111,108,101,97,110,32,97,110,100,32,105, - 115,32,117,115,101,100,32,105,110,10,32,32,32,32,112,108, - 97,99,101,32,111,102,32,115,121,115,46,102,108,97,103,115, - 46,111,112,116,105,109,105,122,101,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,218,1,46,122,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,30,0,0,0, - 114,84,0,0,0,41,13,114,7,0,0,0,218,5,102,108, - 97,103,115,218,8,111,112,116,105,109,105,122,101,218,23,68, - 69,66,85,71,95,66,89,84,69,67,79,68,69,95,83,85, - 70,70,73,88,69,83,218,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,38,0,0,0,218,9,112,97,114,116,105,116, - 105,111,110,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,26,0,0,0,114,28,0,0,0,218,8,95, - 80,89,67,65,67,72,69,41,11,114,35,0,0,0,90,14, - 100,101,98,117,103,95,111,118,101,114,114,105,100,101,218,5, - 100,101,98,117,103,218,8,115,117,102,102,105,120,101,115,218, - 4,104,101,97,100,114,37,0,0,0,218,13,98,97,115,101, - 95,102,105,108,101,110,97,109,101,218,3,115,101,112,114,36, - 0,0,0,90,3,116,97,103,218,8,102,105,108,101,110,97, - 109,101,114,4,0,0,0,114,4,0,0,0,114,5,0,0, - 0,218,17,99,97,99,104,101,95,102,114,111,109,95,115,111, - 117,114,99,101,180,1,0,0,115,22,0,0,0,0,13,31, - 1,6,1,9,2,6,1,18,1,24,1,12,1,12,1,15, - 1,31,1,114,132,0,0,0,99,1,0,0,0,0,0,0, - 0,5,0,0,0,5,0,0,0,67,0,0,0,115,193,0, - 0,0,116,0,0,106,1,0,106,2,0,100,1,0,107,8, - 0,114,33,0,116,3,0,100,2,0,131,1,0,130,1,0, - 110,0,0,116,4,0,124,0,0,131,1,0,92,2,0,125, - 1,0,125,2,0,116,4,0,124,1,0,131,1,0,92,2, - 0,125,1,0,125,3,0,124,3,0,116,5,0,107,3,0, - 114,108,0,116,6,0,100,3,0,106,7,0,116,5,0,124, - 0,0,131,2,0,131,1,0,130,1,0,110,0,0,124,2, - 0,106,8,0,100,4,0,131,1,0,100,5,0,107,3,0, - 114,153,0,116,6,0,100,6,0,106,7,0,124,2,0,131, - 1,0,131,1,0,130,1,0,110,0,0,124,2,0,106,9, - 0,100,4,0,131,1,0,100,7,0,25,125,4,0,116,10, - 0,124,1,0,124,4,0,116,11,0,100,7,0,25,23,131, - 2,0,83,41,8,97,121,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,47,46,112,121,111,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,47,46,112, - 121,111,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,47,46,112,121,111,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,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,122,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,122,37,123,125,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,123,33,114, - 125,114,116,0,0,0,114,115,0,0,0,122,28,101,120,112, - 101,99,116,101,100,32,111,110,108,121,32,50,32,100,111,116, - 115,32,105,110,32,123,33,114,125,114,84,0,0,0,41,12, - 114,7,0,0,0,114,122,0,0,0,114,123,0,0,0,114, - 124,0,0,0,114,38,0,0,0,114,125,0,0,0,218,10, - 86,97,108,117,101,69,114,114,111,114,114,47,0,0,0,114, - 89,0,0,0,114,121,0,0,0,114,28,0,0,0,218,15, - 83,79,85,82,67,69,95,83,85,70,70,73,88,69,83,41, - 5,114,35,0,0,0,114,128,0,0,0,90,16,112,121,99, - 97,99,104,101,95,102,105,108,101,110,97,109,101,90,7,112, - 121,99,97,99,104,101,114,129,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,218,17,115,111,117,114, - 99,101,95,102,114,111,109,95,99,97,99,104,101,207,1,0, - 0,115,24,0,0,0,0,9,18,1,15,1,18,1,18,1, - 12,1,3,1,24,1,21,1,3,1,21,1,19,1,114,135, - 0,0,0,99,1,0,0,0,0,0,0,0,5,0,0,0, - 13,0,0,0,67,0,0,0,115,164,0,0,0,116,0,0, - 124,0,0,131,1,0,100,1,0,107,2,0,114,22,0,100, - 2,0,83,124,0,0,106,1,0,100,3,0,131,1,0,92, - 3,0,125,1,0,125,2,0,125,3,0,124,1,0,12,115, - 81,0,124,3,0,106,2,0,131,0,0,100,7,0,100,8, - 0,133,2,0,25,100,6,0,107,3,0,114,85,0,124,0, - 0,83,121,16,0,116,3,0,124,0,0,131,1,0,125,4, - 0,87,110,40,0,4,116,4,0,116,5,0,102,2,0,107, - 10,0,114,143,0,1,1,1,124,0,0,100,2,0,100,9, - 0,133,2,0,25,125,4,0,89,110,1,0,88,116,6,0, - 124,4,0,131,1,0,114,160,0,124,4,0,83,124,0,0, - 83,41,10,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,84,0,0,0,78,114,116,0,0,0,233,3,0,0, - 0,114,29,0,0,0,90,2,112,121,233,253,255,255,255,233, - 255,255,255,255,114,138,0,0,0,41,7,114,31,0,0,0, - 114,32,0,0,0,218,5,108,111,119,101,114,114,135,0,0, - 0,114,124,0,0,0,114,133,0,0,0,114,44,0,0,0, - 41,5,218,13,98,121,116,101,99,111,100,101,95,112,97,116, - 104,90,4,114,101,115,116,114,36,0,0,0,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,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,15,95,103,101,116,95,115,111,117,114,99,101, - 102,105,108,101,230,1,0,0,115,20,0,0,0,0,7,18, - 1,4,1,24,1,35,1,4,1,3,1,16,1,19,1,21, - 1,114,142,0,0,0,99,1,0,0,0,0,0,0,0,2, - 0,0,0,11,0,0,0,67,0,0,0,115,60,0,0,0, - 121,19,0,116,0,0,124,0,0,131,1,0,106,1,0,125, - 1,0,87,110,24,0,4,116,2,0,107,10,0,114,45,0, - 1,1,1,100,1,0,125,1,0,89,110,1,0,88,124,1, - 0,100,2,0,79,125,1,0,124,1,0,83,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,105,182,1,0,0,233,128,0,0,0,41,3,114, - 39,0,0,0,114,41,0,0,0,114,40,0,0,0,41,2, - 114,35,0,0,0,114,42,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,218,10,95,99,97,108,99, - 95,109,111,100,101,249,1,0,0,115,12,0,0,0,0,2, - 3,1,19,1,13,1,11,3,10,1,114,144,0,0,0,218, - 9,118,101,114,98,111,115,105,116,121,114,29,0,0,0,99, - 1,0,0,0,1,0,0,0,3,0,0,0,4,0,0,0, - 71,0,0,0,115,81,0,0,0,116,0,0,106,1,0,106, - 2,0,124,1,0,107,5,0,114,77,0,124,0,0,106,3, - 0,100,6,0,131,1,0,115,46,0,100,3,0,124,0,0, - 23,125,0,0,110,0,0,116,4,0,124,0,0,106,5,0, - 124,2,0,140,0,0,100,4,0,116,0,0,106,6,0,131, - 1,1,1,110,0,0,100,5,0,83,41,7,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,250,1,35,250,7, - 105,109,112,111,114,116,32,122,2,35,32,114,54,0,0,0, - 78,41,2,114,146,0,0,0,114,147,0,0,0,41,7,114, - 7,0,0,0,114,117,0,0,0,218,7,118,101,114,98,111, - 115,101,114,9,0,0,0,218,5,112,114,105,110,116,114,47, - 0,0,0,218,6,115,116,100,101,114,114,41,3,218,7,109, - 101,115,115,97,103,101,114,145,0,0,0,114,80,0,0,0, - 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,218, - 16,95,118,101,114,98,111,115,101,95,109,101,115,115,97,103, - 101,5,2,0,0,115,8,0,0,0,0,2,18,1,15,1, - 13,1,114,152,0,0,0,99,1,0,0,0,0,0,0,0, - 2,0,0,0,4,0,0,0,3,0,0,0,115,38,0,0, - 0,100,1,0,135,0,0,102,1,0,100,2,0,100,3,0, - 134,1,0,125,1,0,116,0,0,124,1,0,136,0,0,131, - 2,0,1,124,1,0,83,41,4,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,4,0,0,0,5,0,0,0,31,0,0,0,115,83,0, - 0,0,124,1,0,100,0,0,107,8,0,114,24,0,124,0, - 0,106,0,0,125,1,0,110,40,0,124,0,0,106,0,0, - 124,1,0,107,3,0,114,64,0,116,1,0,100,1,0,124, - 1,0,22,100,2,0,124,1,0,131,1,1,130,1,0,110, - 0,0,136,0,0,124,0,0,124,1,0,124,2,0,124,3, - 0,142,2,0,83,41,3,78,122,23,108,111,97,100,101,114, - 32,99,97,110,110,111,116,32,104,97,110,100,108,101,32,37, - 115,114,67,0,0,0,41,2,114,67,0,0,0,218,11,73, - 109,112,111,114,116,69,114,114,111,114,41,4,114,71,0,0, - 0,114,67,0,0,0,114,80,0,0,0,114,108,0,0,0, - 41,1,218,6,109,101,116,104,111,100,114,4,0,0,0,114, - 5,0,0,0,218,19,95,99,104,101,99,107,95,110,97,109, - 101,95,119,114,97,112,112,101,114,21,2,0,0,115,10,0, - 0,0,0,1,12,1,12,1,15,1,25,1,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,41,1,114,65,0,0,0,41,2,114, - 154,0,0,0,114,155,0,0,0,114,4,0,0,0,41,1, - 114,154,0,0,0,114,5,0,0,0,218,11,95,99,104,101, - 99,107,95,110,97,109,101,13,2,0,0,115,6,0,0,0, - 0,8,21,6,13,1,114,156,0,0,0,99,1,0,0,0, - 0,0,0,0,2,0,0,0,3,0,0,0,3,0,0,0, - 115,35,0,0,0,135,0,0,102,1,0,100,1,0,100,2, - 0,134,0,0,125,1,0,116,0,0,124,1,0,136,0,0, - 131,2,0,1,124,1,0,83,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,2,0,0,0,4,0,0,0,19,0, - 0,0,115,58,0,0,0,124,1,0,116,0,0,106,1,0, - 107,7,0,114,45,0,116,2,0,100,1,0,106,3,0,124, - 1,0,131,1,0,100,2,0,124,1,0,131,1,1,130,1, - 0,110,0,0,136,0,0,124,0,0,124,1,0,131,2,0, - 83,41,3,78,122,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,67,0,0,0,41,4,114,7,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,114,153,0,0,0,114,47,0,0,0,41, - 2,114,71,0,0,0,218,8,102,117,108,108,110,97,109,101, - 41,1,218,3,102,120,110,114,4,0,0,0,114,5,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,33,2,0,0, - 115,8,0,0,0,0,1,15,1,18,1,12,1,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,41,1,114,65,0,0,0,41,2,114,159,0,0, - 0,114,160,0,0,0,114,4,0,0,0,41,1,114,159,0, - 0,0,114,5,0,0,0,218,17,95,114,101,113,117,105,114, - 101,115,95,98,117,105,108,116,105,110,31,2,0,0,115,6, - 0,0,0,0,2,18,5,13,1,114,161,0,0,0,99,1, - 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,3, - 0,0,0,115,35,0,0,0,135,0,0,102,1,0,100,1, - 0,100,2,0,134,0,0,125,1,0,116,0,0,124,1,0, - 136,0,0,131,2,0,1,124,1,0,83,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,2,0,0,0,4,0,0,0,19, - 0,0,0,115,58,0,0,0,116,0,0,106,1,0,124,1, - 0,131,1,0,115,45,0,116,2,0,100,1,0,106,3,0, - 124,1,0,131,1,0,100,2,0,124,1,0,131,1,1,130, - 1,0,110,0,0,136,0,0,124,0,0,124,1,0,131,2, - 0,83,41,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,67,0,0,0,41,4,114,106,0,0,0,218,9, - 105,115,95,102,114,111,122,101,110,114,153,0,0,0,114,47, - 0,0,0,41,2,114,71,0,0,0,114,158,0,0,0,41, - 1,114,159,0,0,0,114,4,0,0,0,114,5,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,44,2,0,0,115,8, - 0,0,0,0,1,15,1,18,1,12,1,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,41, - 1,114,65,0,0,0,41,2,114,159,0,0,0,114,163,0, - 0,0,114,4,0,0,0,41,1,114,159,0,0,0,114,5, - 0,0,0,218,16,95,114,101,113,117,105,114,101,115,95,102, - 114,111,122,101,110,42,2,0,0,115,6,0,0,0,0,2, - 18,5,13,1,114,164,0,0,0,99,2,0,0,0,0,0, - 0,0,5,0,0,0,5,0,0,0,67,0,0,0,115,87, - 0,0,0,124,0,0,106,0,0,124,1,0,131,1,0,92, - 2,0,125,2,0,125,3,0,124,2,0,100,1,0,107,8, - 0,114,83,0,116,1,0,124,3,0,131,1,0,114,83,0, - 100,2,0,125,4,0,116,2,0,106,3,0,124,4,0,106, - 4,0,124,3,0,100,3,0,25,131,1,0,116,5,0,131, - 2,0,1,110,0,0,124,2,0,83,41,4,122,86,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,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,84,0,0,0,41,6,218,11,102,105,110,100, - 95,108,111,97,100,101,114,114,31,0,0,0,218,9,95,119, - 97,114,110,105,110,103,115,218,4,119,97,114,110,114,47,0, - 0,0,218,13,73,109,112,111,114,116,87,97,114,110,105,110, - 103,41,5,114,71,0,0,0,114,158,0,0,0,218,6,108, - 111,97,100,101,114,218,8,112,111,114,116,105,111,110,115,218, - 3,109,115,103,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,17,95,102,105,110,100,95,109,111,100,117,108, - 101,95,115,104,105,109,53,2,0,0,115,10,0,0,0,0, - 6,21,1,24,1,6,1,32,1,114,172,0,0,0,99,2, - 0,0,0,0,0,0,0,5,0,0,0,3,0,0,0,67, - 0,0,0,115,93,0,0,0,116,0,0,124,1,0,124,0, - 0,131,2,0,125,2,0,116,1,0,124,2,0,131,1,0, - 125,3,0,124,1,0,116,2,0,106,3,0,107,6,0,114, - 79,0,116,2,0,106,3,0,124,1,0,25,125,4,0,124, - 3,0,106,4,0,124,4,0,131,1,0,1,116,2,0,106, - 3,0,124,1,0,25,83,124,3,0,106,5,0,131,0,0, - 83,100,1,0,83,41,2,122,57,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,78,41,6,218,16,115,112,101,99,95,102,114,111,109, - 95,108,111,97,100,101,114,218,12,95,83,112,101,99,77,101, - 116,104,111,100,115,114,7,0,0,0,114,73,0,0,0,218, - 4,101,120,101,99,218,4,108,111,97,100,41,5,114,71,0, - 0,0,114,158,0,0,0,218,4,115,112,101,99,218,7,109, - 101,116,104,111,100,115,218,6,109,111,100,117,108,101,114,4, - 0,0,0,114,4,0,0,0,114,5,0,0,0,218,17,95, - 108,111,97,100,95,109,111,100,117,108,101,95,115,104,105,109, - 66,2,0,0,115,14,0,0,0,0,3,15,1,12,1,15, - 1,13,1,13,1,11,2,114,180,0,0,0,99,4,0,0, - 0,0,0,0,0,11,0,0,0,19,0,0,0,67,0,0, - 0,115,243,1,0,0,105,0,0,125,4,0,124,2,0,100, - 1,0,107,9,0,114,31,0,124,2,0,124,4,0,100,2, - 0,60,110,6,0,100,3,0,125,2,0,124,3,0,100,1, - 0,107,9,0,114,62,0,124,3,0,124,4,0,100,4,0, - 60,110,0,0,124,0,0,100,1,0,100,5,0,133,2,0, - 25,125,5,0,124,0,0,100,5,0,100,6,0,133,2,0, - 25,125,6,0,124,0,0,100,6,0,100,7,0,133,2,0, - 25,125,7,0,124,5,0,116,0,0,107,3,0,114,168,0, - 100,8,0,106,1,0,124,2,0,124,5,0,131,2,0,125, - 8,0,116,2,0,124,8,0,131,1,0,1,116,3,0,124, - 8,0,124,4,0,141,1,0,130,1,0,110,116,0,116,4, - 0,124,6,0,131,1,0,100,5,0,107,3,0,114,226,0, - 100,9,0,106,1,0,124,2,0,131,1,0,125,8,0,116, - 2,0,124,8,0,131,1,0,1,116,5,0,124,8,0,131, - 1,0,130,1,0,110,58,0,116,4,0,124,7,0,131,1, - 0,100,5,0,107,3,0,114,28,1,100,10,0,106,1,0, - 124,2,0,131,1,0,125,8,0,116,2,0,124,8,0,131, - 1,0,1,116,5,0,124,8,0,131,1,0,130,1,0,110, - 0,0,124,1,0,100,1,0,107,9,0,114,229,1,121,20, - 0,116,6,0,124,1,0,100,11,0,25,131,1,0,125,9, - 0,87,110,18,0,4,116,7,0,107,10,0,114,80,1,1, - 1,1,89,110,62,0,88,116,8,0,124,6,0,131,1,0, - 124,9,0,107,3,0,114,142,1,100,12,0,106,1,0,124, - 2,0,131,1,0,125,8,0,116,2,0,124,8,0,131,1, - 0,1,116,3,0,124,8,0,124,4,0,141,1,0,130,1, - 0,110,0,0,121,18,0,124,1,0,100,13,0,25,100,14, - 0,64,125,10,0,87,110,18,0,4,116,7,0,107,10,0, - 114,180,1,1,1,1,89,113,229,1,88,116,8,0,124,7, - 0,131,1,0,124,10,0,107,3,0,114,229,1,116,3,0, - 100,12,0,106,1,0,124,2,0,131,1,0,124,4,0,141, - 1,0,130,1,0,113,229,1,110,0,0,124,0,0,100,7, - 0,100,1,0,133,2,0,25,83,41,15,97,122,1,0,0, - 86,97,108,105,100,97,116,101,32,116,104,101,32,104,101,97, - 100,101,114,32,111,102,32,116,104,101,32,112,97,115,115,101, - 100,45,105,110,32,98,121,116,101,99,111,100,101,32,97,103, - 97,105,110,115,116,32,115,111,117,114,99,101,95,115,116,97, - 116,115,32,40,105,102,10,32,32,32,32,103,105,118,101,110, - 41,32,97,110,100,32,114,101,116,117,114,110,105,110,103,32, - 116,104,101,32,98,121,116,101,99,111,100,101,32,116,104,97, - 116,32,99,97,110,32,98,101,32,99,111,109,112,105,108,101, - 100,32,98,121,32,99,111,109,112,105,108,101,40,41,46,10, - 10,32,32,32,32,65,108,108,32,111,116,104,101,114,32,97, - 114,103,117,109,101,110,116,115,32,97,114,101,32,117,115,101, - 100,32,116,111,32,101,110,104,97,110,99,101,32,101,114,114, - 111,114,32,114,101,112,111,114,116,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,116, - 104,101,32,98,121,116,101,99,111,100,101,32,105,115,10,32, - 32,32,32,102,111,117,110,100,32,116,111,32,98,101,32,115, - 116,97,108,101,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,10,32,32,32,32,116,114,117,110,99,97, - 116,101,100,46,10,10,32,32,32,32,78,114,67,0,0,0, - 122,10,60,98,121,116,101,99,111,100,101,62,114,35,0,0, - 0,114,12,0,0,0,233,8,0,0,0,233,12,0,0,0, - 122,30,98,97,100,32,109,97,103,105,99,32,110,117,109,98, - 101,114,32,105,110,32,123,33,114,125,58,32,123,33,114,125, - 122,43,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,116,105,109,101, - 115,116,97,109,112,32,105,110,32,123,33,114,125,122,48,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,115,105,122,101,32,111,102, - 32,115,111,117,114,99,101,32,105,110,32,123,33,114,125,218, - 5,109,116,105,109,101,122,26,98,121,116,101,99,111,100,101, - 32,105,115,32,115,116,97,108,101,32,102,111,114,32,123,33, - 114,125,218,4,115,105,122,101,108,3,0,0,0,255,127,255, - 127,3,0,41,9,218,12,77,65,71,73,67,95,78,85,77, - 66,69,82,114,47,0,0,0,114,152,0,0,0,114,153,0, - 0,0,114,31,0,0,0,218,8,69,79,70,69,114,114,111, - 114,114,14,0,0,0,114,79,0,0,0,114,19,0,0,0, - 41,11,114,53,0,0,0,218,12,115,111,117,114,99,101,95, - 115,116,97,116,115,114,67,0,0,0,114,35,0,0,0,90, - 11,101,120,99,95,100,101,116,97,105,108,115,90,5,109,97, - 103,105,99,90,13,114,97,119,95,116,105,109,101,115,116,97, - 109,112,90,8,114,97,119,95,115,105,122,101,114,151,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,4,0,0, - 0,114,4,0,0,0,114,5,0,0,0,218,25,95,118,97, - 108,105,100,97,116,101,95,98,121,116,101,99,111,100,101,95, - 104,101,97,100,101,114,79,2,0,0,115,76,0,0,0,0, - 11,6,1,12,1,13,3,6,1,12,1,13,1,16,1,16, - 1,16,1,12,1,18,1,10,1,18,1,18,1,15,1,10, - 1,15,1,18,1,15,1,10,1,15,1,12,1,3,1,20, - 1,13,1,5,2,18,1,15,1,10,1,18,1,3,1,18, - 1,13,1,5,2,18,1,15,1,15,1,114,190,0,0,0, - 99,4,0,0,0,0,0,0,0,5,0,0,0,6,0,0, - 0,67,0,0,0,115,115,0,0,0,116,0,0,106,1,0, - 124,0,0,131,1,0,125,4,0,116,2,0,124,4,0,116, - 3,0,131,2,0,114,78,0,116,4,0,100,1,0,124,2, - 0,131,2,0,1,124,3,0,100,2,0,107,9,0,114,74, - 0,116,5,0,106,6,0,124,4,0,124,3,0,131,2,0, - 1,110,0,0,124,4,0,83,116,7,0,100,3,0,106,8, - 0,124,2,0,131,1,0,100,4,0,124,1,0,100,5,0, - 124,2,0,131,1,2,130,1,0,100,2,0,83,41,6,122, - 60,67,111,109,112,105,108,101,32,98,121,116,101,99,111,100, - 101,32,97,115,32,114,101,116,117,114,110,101,100,32,98,121, - 32,95,118,97,108,105,100,97,116,101,95,98,121,116,101,99, - 111,100,101,95,104,101,97,100,101,114,40,41,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,114,67, - 0,0,0,114,35,0,0,0,41,9,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,152,0,0,0,114,106,0,0,0,90,16,95,102, - 105,120,95,99,111,95,102,105,108,101,110,97,109,101,114,153, - 0,0,0,114,47,0,0,0,41,5,114,53,0,0,0,114, - 67,0,0,0,114,140,0,0,0,114,141,0,0,0,218,4, - 99,111,100,101,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,17,95,99,111,109,112,105,108,101,95,98,121, - 116,101,99,111,100,101,134,2,0,0,115,16,0,0,0,0, - 2,15,1,15,1,13,1,12,1,19,1,4,2,18,1,114, - 195,0,0,0,114,84,0,0,0,99,3,0,0,0,0,0, - 0,0,4,0,0,0,3,0,0,0,67,0,0,0,115,76, - 0,0,0,116,0,0,116,1,0,131,1,0,125,3,0,124, - 3,0,106,2,0,116,3,0,124,1,0,131,1,0,131,1, - 0,1,124,3,0,106,2,0,116,3,0,124,2,0,131,1, - 0,131,1,0,1,124,3,0,106,2,0,116,4,0,106,5, - 0,124,0,0,131,1,0,131,1,0,1,124,3,0,83,41, - 1,122,80,67,111,109,112,105,108,101,32,97,32,99,111,100, - 101,32,111,98,106,101,99,116,32,105,110,116,111,32,98,121, - 116,101,99,111,100,101,32,102,111,114,32,119,114,105,116,105, - 110,103,32,111,117,116,32,116,111,32,97,32,98,121,116,101, - 45,99,111,109,112,105,108,101,100,10,32,32,32,32,102,105, - 108,101,46,41,6,218,9,98,121,116,101,97,114,114,97,121, - 114,185,0,0,0,218,6,101,120,116,101,110,100,114,17,0, - 0,0,114,191,0,0,0,90,5,100,117,109,112,115,41,4, - 114,194,0,0,0,114,183,0,0,0,114,189,0,0,0,114, - 53,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,17,95,99,111,100,101,95,116,111,95,98,121, - 116,101,99,111,100,101,146,2,0,0,115,10,0,0,0,0, - 3,12,1,19,1,19,1,22,1,114,198,0,0,0,99,1, - 0,0,0,0,0,0,0,5,0,0,0,4,0,0,0,67, - 0,0,0,115,89,0,0,0,100,1,0,100,2,0,108,0, - 0,125,1,0,116,1,0,106,2,0,124,0,0,131,1,0, - 106,3,0,125,2,0,124,1,0,106,4,0,124,2,0,131, - 1,0,125,3,0,116,1,0,106,5,0,100,2,0,100,3, - 0,131,2,0,125,4,0,124,4,0,106,6,0,124,0,0, - 106,6,0,124,3,0,100,1,0,25,131,1,0,131,1,0, - 83,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,84, - 0,0,0,78,84,41,7,218,8,116,111,107,101,110,105,122, - 101,114,49,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,199,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,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,13,100,101,99,111,100,101,95,115,111,117,114, - 99,101,156,2,0,0,115,10,0,0,0,0,5,12,1,18, - 1,15,1,18,1,114,203,0,0,0,99,1,0,0,0,0, - 0,0,0,5,0,0,0,35,0,0,0,67,0,0,0,115, - 15,1,0,0,116,0,0,124,0,0,100,1,0,100,0,0, - 131,3,0,125,1,0,116,1,0,124,1,0,100,2,0,131, - 2,0,114,74,0,121,17,0,124,1,0,106,2,0,124,0, - 0,131,1,0,83,87,113,74,0,4,116,3,0,107,10,0, - 114,70,0,1,1,1,89,113,74,0,88,110,0,0,121,13, - 0,124,0,0,106,4,0,125,2,0,87,110,18,0,4,116, - 5,0,107,10,0,114,107,0,1,1,1,89,110,29,0,88, - 124,2,0,100,0,0,107,9,0,114,136,0,116,6,0,124, - 2,0,131,1,0,106,2,0,131,0,0,83,121,13,0,124, - 0,0,106,7,0,125,3,0,87,110,24,0,4,116,5,0, - 107,10,0,114,175,0,1,1,1,100,3,0,125,3,0,89, - 110,1,0,88,121,13,0,124,0,0,106,8,0,125,4,0, - 87,110,59,0,4,116,5,0,107,10,0,114,250,0,1,1, - 1,124,1,0,100,0,0,107,8,0,114,230,0,100,4,0, - 106,9,0,124,3,0,131,1,0,83,100,5,0,106,9,0, - 124,3,0,124,1,0,131,2,0,83,89,110,17,0,88,100, - 6,0,106,9,0,124,3,0,124,4,0,131,2,0,83,100, - 0,0,83,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,122,13,60,109,111,100,117,108,101,32,123,33,114,125, - 62,122,20,60,109,111,100,117,108,101,32,123,33,114,125,32, - 40,123,33,114,125,41,62,122,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,62,0,0,0,114,60,0,0,0,114,205,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,114,174,0,0,0,114,57,0,0,0, - 218,8,95,95,102,105,108,101,95,95,114,47,0,0,0,41, - 5,114,179,0,0,0,114,169,0,0,0,114,177,0,0,0, - 114,67,0,0,0,114,131,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,218,12,95,109,111,100,117, - 108,101,95,114,101,112,114,170,2,0,0,115,46,0,0,0, - 0,2,18,1,15,2,3,1,17,1,13,1,8,1,3,1, - 13,1,13,1,5,2,12,1,16,4,3,1,13,1,13,1, - 11,1,3,1,13,1,13,1,12,1,13,2,21,2,114,211, + 118,101,100,214,0,0,0,115,2,0,0,0,0,8,114,65, + 0,0,0,218,9,118,101,114,98,111,115,105,116,121,114,45, + 0,0,0,99,1,0,0,0,1,0,0,0,3,0,0,0, + 4,0,0,0,71,0,0,0,115,75,0,0,0,116,0,0, + 106,1,0,106,2,0,124,1,0,107,5,0,114,71,0,124, + 0,0,106,3,0,100,6,0,131,1,0,115,43,0,100,3, + 0,124,0,0,23,125,0,0,116,4,0,124,0,0,106,5, + 0,124,2,0,140,0,0,100,4,0,116,0,0,106,6,0, + 131,1,1,1,100,5,0,83,41,7,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,250,1,35,250,7,105,109, + 112,111,114,116,32,122,2,35,32,90,4,102,105,108,101,78, + 41,2,114,67,0,0,0,114,68,0,0,0,41,7,114,14, + 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,50,0,0,0,218,6,115,116,100, + 101,114,114,41,3,218,7,109,101,115,115,97,103,101,114,66, + 0,0,0,114,29,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,225,0,0,0,115,8,0, + 0,0,0,2,18,1,15,1,10,1,114,75,0,0,0,99, + 1,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, + 3,0,0,0,115,35,0,0,0,135,0,0,102,1,0,100, + 1,0,100,2,0,134,0,0,125,1,0,116,0,0,124,1, + 0,136,0,0,131,2,0,1,124,1,0,83,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,2,0,0,0,4,0, + 0,0,19,0,0,0,115,55,0,0,0,124,1,0,116,0, + 0,106,1,0,107,7,0,114,42,0,116,2,0,100,1,0, + 106,3,0,124,1,0,131,1,0,100,2,0,124,1,0,131, + 1,1,130,1,0,136,0,0,124,0,0,124,1,0,131,2, + 0,83,41,3,78,122,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,15,0,0,0,41,4,114,14,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,50,0,0,0,41,2,114,19,0,0,0,218, + 8,102,117,108,108,110,97,109,101,41,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,235,0,0,0,115,8,0,0,0,0,1, + 15,1,18,1,9,1,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,41,1,114,12, + 0,0,0,41,2,114,79,0,0,0,114,80,0,0,0,114, + 10,0,0,0,41,1,114,79,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,233,0,0,0,115,6,0,0,0,0,2,18,5, + 13,1,114,81,0,0,0,99,1,0,0,0,0,0,0,0, + 2,0,0,0,3,0,0,0,3,0,0,0,115,35,0,0, + 0,135,0,0,102,1,0,100,1,0,100,2,0,134,0,0, + 125,1,0,116,0,0,124,1,0,136,0,0,131,2,0,1, + 124,1,0,83,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, + 2,0,0,0,4,0,0,0,19,0,0,0,115,55,0,0, + 0,116,0,0,106,1,0,124,1,0,131,1,0,115,42,0, + 116,2,0,100,1,0,106,3,0,124,1,0,131,1,0,100, + 2,0,124,1,0,131,1,1,130,1,0,136,0,0,124,0, + 0,124,1,0,131,2,0,83,41,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,15,0,0,0,41,4,114, + 57,0,0,0,218,9,105,115,95,102,114,111,122,101,110,114, + 77,0,0,0,114,50,0,0,0,41,2,114,19,0,0,0, + 114,78,0,0,0,41,1,114,79,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, + 246,0,0,0,115,8,0,0,0,0,1,15,1,18,1,9, + 1,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,41,1,114,12,0,0,0,41,2,114,79, + 0,0,0,114,83,0,0,0,114,10,0,0,0,41,1,114, + 79,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,244,0,0,0,115, + 6,0,0,0,0,2,18,5,13,1,114,84,0,0,0,99, + 2,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0, + 67,0,0,0,115,81,0,0,0,116,0,0,124,1,0,124, + 0,0,131,2,0,125,2,0,124,1,0,116,1,0,106,2, + 0,107,6,0,114,67,0,116,1,0,106,2,0,124,1,0, + 25,125,3,0,116,3,0,124,2,0,124,3,0,131,2,0, + 1,116,1,0,106,2,0,124,1,0,25,83,116,4,0,124, + 2,0,131,1,0,83,100,1,0,83,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,14,0,0,0,114,21,0,0,0,218,5,95, + 101,120,101,99,218,5,95,108,111,97,100,41,4,114,19,0, + 0,0,114,78,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,0,1,0,0,115,12,0,0,0, + 0,6,15,1,15,1,13,1,13,1,11,2,114,90,0,0, + 0,99,1,0,0,0,0,0,0,0,5,0,0,0,35,0, + 0,0,67,0,0,0,115,6,1,0,0,116,0,0,124,0, + 0,100,1,0,100,0,0,131,3,0,125,1,0,116,1,0, + 124,1,0,100,2,0,131,2,0,114,71,0,121,17,0,124, + 1,0,106,2,0,124,0,0,131,1,0,83,87,110,18,0, + 4,116,3,0,107,10,0,114,70,0,1,1,1,89,110,1, + 0,88,121,13,0,124,0,0,106,4,0,125,2,0,87,110, + 18,0,4,116,5,0,107,10,0,114,104,0,1,1,1,89, + 110,23,0,88,124,2,0,100,0,0,107,9,0,114,127,0, + 116,6,0,124,2,0,131,1,0,83,121,13,0,124,0,0, + 106,7,0,125,3,0,87,110,24,0,4,116,5,0,107,10, + 0,114,166,0,1,1,1,100,3,0,125,3,0,89,110,1, + 0,88,121,13,0,124,0,0,106,8,0,125,4,0,87,110, + 59,0,4,116,5,0,107,10,0,114,241,0,1,1,1,124, + 1,0,100,0,0,107,8,0,114,221,0,100,4,0,106,9, + 0,124,3,0,131,1,0,83,100,5,0,106,9,0,124,3, + 0,124,1,0,131,2,0,83,89,110,17,0,88,100,6,0, + 106,9,0,124,3,0,124,4,0,131,2,0,83,100,0,0, + 83,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, + 122,13,60,109,111,100,117,108,101,32,123,33,114,125,62,122, + 20,60,109,111,100,117,108,101,32,123,33,114,125,32,40,123, + 33,114,125,41,62,122,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,92,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,50,0,0,0, + 41,5,114,89,0,0,0,218,6,108,111,97,100,101,114,114, + 88,0,0,0,114,15,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, + 16,1,0,0,115,46,0,0,0,0,2,18,1,15,4,3, + 1,17,1,13,1,5,1,3,1,13,1,13,1,5,2,12, + 1,10,4,3,1,13,1,13,1,11,1,3,1,13,1,13, + 1,12,1,13,2,21,2,114,101,0,0,0,99,0,0,0, + 0,0,0,0,0,0,0,0,0,2,0,0,0,64,0,0, + 0,115,52,0,0,0,101,0,0,90,1,0,100,0,0,90, + 2,0,100,1,0,100,2,0,132,0,0,90,3,0,100,3, + 0,100,4,0,132,0,0,90,4,0,100,5,0,100,6,0, + 132,0,0,90,5,0,100,7,0,83,41,8,218,17,95,105, + 110,115,116,97,108,108,101,100,95,115,97,102,101,108,121,99, + 2,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0, + 67,0,0,0,115,25,0,0,0,124,1,0,124,0,0,95, + 0,0,124,1,0,106,1,0,124,0,0,95,2,0,100,0, + 0,83,41,1,78,41,3,218,7,95,109,111,100,117,108,101, + 114,95,0,0,0,218,5,95,115,112,101,99,41,2,114,19, + 0,0,0,114,89,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,20,0,0,0,54,1,0,0, + 115,4,0,0,0,0,1,9,1,122,26,95,105,110,115,116, + 97,108,108,101,100,95,115,97,102,101,108,121,46,95,95,105, + 110,105,116,95,95,99,1,0,0,0,0,0,0,0,1,0, + 0,0,3,0,0,0,67,0,0,0,115,38,0,0,0,100, + 1,0,124,0,0,106,0,0,95,1,0,124,0,0,106,2, + 0,116,3,0,106,4,0,124,0,0,106,0,0,106,5,0, + 60,100,0,0,83,41,2,78,84,41,6,114,104,0,0,0, + 218,13,95,105,110,105,116,105,97,108,105,122,105,110,103,114, + 103,0,0,0,114,14,0,0,0,114,21,0,0,0,114,15, + 0,0,0,41,1,114,19,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,23,0,0,0,58,1, + 0,0,115,4,0,0,0,0,4,12,1,122,27,95,105,110, + 115,116,97,108,108,101,100,95,115,97,102,101,108,121,46,95, + 95,101,110,116,101,114,95,95,99,1,0,0,0,0,0,0, + 0,3,0,0,0,17,0,0,0,71,0,0,0,115,121,0, + 0,0,122,101,0,124,0,0,106,0,0,125,2,0,116,1, + 0,100,1,0,100,2,0,132,0,0,124,1,0,68,131,1, + 0,131,1,0,114,78,0,121,17,0,116,2,0,106,3,0, + 124,2,0,106,4,0,61,87,113,100,0,4,116,5,0,107, + 10,0,114,74,0,1,1,1,89,113,100,0,88,110,22,0, + 116,6,0,100,3,0,124,2,0,106,4,0,124,2,0,106, + 7,0,131,3,0,1,87,100,0,0,100,4,0,124,0,0, + 106,0,0,95,8,0,88,100,0,0,83,41,5,78,99,1, + 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,115, + 0,0,0,115,27,0,0,0,124,0,0,93,17,0,125,1, + 0,124,1,0,100,0,0,107,9,0,86,1,113,3,0,100, + 0,0,83,41,1,78,114,10,0,0,0,41,2,114,24,0, + 0,0,114,25,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,114,26,0,0,0,68,1,0,0,115, + 2,0,0,0,6,0,122,45,95,105,110,115,116,97,108,108, + 101,100,95,115,97,102,101,108,121,46,95,95,101,120,105,116, + 95,95,46,60,108,111,99,97,108,115,62,46,60,103,101,110, + 101,120,112,114,62,122,18,105,109,112,111,114,116,32,123,33, + 114,125,32,35,32,123,33,114,125,70,41,9,114,104,0,0, + 0,114,27,0,0,0,114,14,0,0,0,114,21,0,0,0, + 114,15,0,0,0,114,28,0,0,0,114,75,0,0,0,114, + 99,0,0,0,114,105,0,0,0,41,3,114,19,0,0,0, + 114,29,0,0,0,114,88,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,30,0,0,0,65,1, + 0,0,115,18,0,0,0,0,1,3,1,9,1,25,1,3, + 1,17,1,13,1,8,2,26,2,122,26,95,105,110,115,116, + 97,108,108,101,100,95,115,97,102,101,108,121,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,20,0,0,0,114,23,0,0, + 0,114,30,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,102,0,0,0,52, + 1,0,0,115,6,0,0,0,12,2,12,4,12,7,114,102, 0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, - 2,0,0,0,64,0,0,0,115,52,0,0,0,101,0,0, - 90,1,0,100,0,0,90,2,0,100,1,0,100,2,0,132, - 0,0,90,3,0,100,3,0,100,4,0,132,0,0,90,4, - 0,100,5,0,100,6,0,132,0,0,90,5,0,100,7,0, - 83,41,8,218,17,95,105,110,115,116,97,108,108,101,100,95, - 115,97,102,101,108,121,99,2,0,0,0,0,0,0,0,2, - 0,0,0,2,0,0,0,67,0,0,0,115,25,0,0,0, - 124,1,0,124,0,0,95,0,0,124,1,0,106,1,0,124, - 0,0,95,2,0,100,0,0,83,41,1,78,41,3,218,7, - 95,109,111,100,117,108,101,114,208,0,0,0,218,5,95,115, - 112,101,99,41,2,114,71,0,0,0,114,179,0,0,0,114, - 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,72, - 0,0,0,206,2,0,0,115,4,0,0,0,0,1,9,1, - 122,26,95,105,110,115,116,97,108,108,101,100,95,115,97,102, - 101,108,121,46,95,95,105,110,105,116,95,95,99,1,0,0, - 0,0,0,0,0,1,0,0,0,3,0,0,0,67,0,0, - 0,115,38,0,0,0,100,1,0,124,0,0,106,0,0,95, - 1,0,124,0,0,106,2,0,116,3,0,106,4,0,124,0, - 0,106,0,0,106,5,0,60,100,0,0,83,41,2,78,84, - 41,6,114,214,0,0,0,218,13,95,105,110,105,116,105,97, - 108,105,122,105,110,103,114,213,0,0,0,114,7,0,0,0, - 114,73,0,0,0,114,67,0,0,0,41,1,114,71,0,0, - 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,75,0,0,0,210,2,0,0,115,4,0,0,0,0,4, - 12,1,122,27,95,105,110,115,116,97,108,108,101,100,95,115, - 97,102,101,108,121,46,95,95,101,110,116,101,114,95,95,99, - 1,0,0,0,0,0,0,0,3,0,0,0,17,0,0,0, - 71,0,0,0,115,121,0,0,0,122,101,0,124,0,0,106, - 0,0,125,2,0,116,1,0,100,1,0,100,2,0,132,0, - 0,124,1,0,68,131,1,0,131,1,0,114,78,0,121,17, - 0,116,2,0,106,3,0,124,2,0,106,4,0,61,87,113, - 100,0,4,116,5,0,107,10,0,114,74,0,1,1,1,89, - 113,100,0,88,110,22,0,116,6,0,100,3,0,124,2,0, - 106,4,0,124,2,0,106,7,0,131,3,0,1,87,100,0, - 0,100,4,0,124,0,0,106,0,0,95,8,0,88,100,0, - 0,83,41,5,78,99,1,0,0,0,0,0,0,0,2,0, - 0,0,3,0,0,0,115,0,0,0,115,27,0,0,0,124, - 0,0,93,17,0,125,1,0,124,1,0,100,0,0,107,9, - 0,86,1,113,3,0,100,0,0,83,41,1,78,114,4,0, - 0,0,41,2,114,22,0,0,0,114,76,0,0,0,114,4, - 0,0,0,114,4,0,0,0,114,5,0,0,0,114,77,0, - 0,0,220,2,0,0,115,2,0,0,0,6,0,122,45,95, - 105,110,115,116,97,108,108,101,100,95,115,97,102,101,108,121, - 46,95,95,101,120,105,116,95,95,46,60,108,111,99,97,108, - 115,62,46,60,103,101,110,101,120,112,114,62,122,18,105,109, - 112,111,114,116,32,123,33,114,125,32,35,32,123,33,114,125, - 70,41,9,114,214,0,0,0,114,78,0,0,0,114,7,0, - 0,0,114,73,0,0,0,114,67,0,0,0,114,79,0,0, - 0,114,152,0,0,0,114,169,0,0,0,114,215,0,0,0, - 41,3,114,71,0,0,0,114,80,0,0,0,114,177,0,0, - 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,81,0,0,0,217,2,0,0,115,18,0,0,0,0,1, - 3,1,9,1,25,1,3,1,17,1,13,1,8,2,26,2, - 122,26,95,105,110,115,116,97,108,108,101,100,95,115,97,102, - 101,108,121,46,95,95,101,120,105,116,95,95,78,41,6,114, - 57,0,0,0,114,56,0,0,0,114,58,0,0,0,114,72, - 0,0,0,114,75,0,0,0,114,81,0,0,0,114,4,0, - 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, - 0,114,212,0,0,0,204,2,0,0,115,6,0,0,0,12, - 2,12,4,12,7,114,212,0,0,0,99,0,0,0,0,0, - 0,0,0,0,0,0,0,8,0,0,0,64,0,0,0,115, - 151,0,0,0,101,0,0,90,1,0,100,0,0,90,2,0, - 100,1,0,90,3,0,100,2,0,100,3,0,100,4,0,100, - 3,0,100,5,0,100,3,0,100,6,0,100,7,0,132,0, - 3,90,4,0,100,8,0,100,9,0,132,0,0,90,5,0, - 100,10,0,100,11,0,132,0,0,90,6,0,101,7,0,100, - 12,0,100,13,0,132,0,0,131,1,0,90,8,0,101,8, - 0,106,9,0,100,14,0,100,13,0,132,0,0,131,1,0, - 90,8,0,101,7,0,100,15,0,100,16,0,132,0,0,131, - 1,0,90,10,0,101,7,0,100,17,0,100,18,0,132,0, - 0,131,1,0,90,11,0,100,3,0,83,41,19,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,218,6, - 111,114,105,103,105,110,78,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,3,0,0,0,6,0,0,0,2,0, - 0,0,67,0,0,0,115,79,0,0,0,124,1,0,124,0, - 0,95,0,0,124,2,0,124,0,0,95,1,0,124,3,0, - 124,0,0,95,2,0,124,4,0,124,0,0,95,3,0,124, - 5,0,114,48,0,103,0,0,110,3,0,100,0,0,124,0, - 0,95,4,0,100,1,0,124,0,0,95,5,0,100,0,0, - 124,0,0,95,6,0,100,0,0,83,41,2,78,70,41,7, - 114,67,0,0,0,114,169,0,0,0,114,217,0,0,0,114, - 218,0,0,0,218,26,115,117,98,109,111,100,117,108,101,95, + 8,0,0,0,64,0,0,0,115,172,0,0,0,101,0,0, + 90,1,0,100,0,0,90,2,0,100,1,0,90,3,0,100, + 2,0,100,3,0,100,4,0,100,3,0,100,5,0,100,3, + 0,100,6,0,100,7,0,132,0,3,90,4,0,100,8,0, + 100,9,0,132,0,0,90,5,0,100,10,0,100,11,0,132, + 0,0,90,6,0,101,7,0,100,12,0,100,13,0,132,0, + 0,131,1,0,90,8,0,101,8,0,106,9,0,100,14,0, + 100,13,0,132,0,0,131,1,0,90,8,0,101,7,0,100, + 15,0,100,16,0,132,0,0,131,1,0,90,10,0,101,7, + 0,100,17,0,100,18,0,132,0,0,131,1,0,90,11,0, + 101,11,0,106,9,0,100,19,0,100,18,0,132,0,0,131, + 1,0,90,11,0,100,3,0,83,41,20,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, - 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,71,0,0,0,114, - 67,0,0,0,114,169,0,0,0,114,217,0,0,0,114,218, - 0,0,0,114,219,0,0,0,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,114,72,0,0,0,12,3,0,0, - 115,14,0,0,0,0,2,9,1,9,1,9,1,9,1,21, - 3,9,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,2,0,0,0,4,0,0,0,67,0,0,0,115,153,0, - 0,0,100,1,0,106,0,0,124,0,0,106,1,0,131,1, - 0,100,2,0,106,0,0,124,0,0,106,2,0,131,1,0, - 103,2,0,125,1,0,124,0,0,106,3,0,100,0,0,107, - 9,0,114,79,0,124,1,0,106,4,0,100,3,0,106,0, - 0,124,0,0,106,3,0,131,1,0,131,1,0,1,110,0, - 0,124,0,0,106,5,0,100,0,0,107,9,0,114,122,0, - 124,1,0,106,4,0,100,4,0,106,0,0,124,0,0,106, - 5,0,131,1,0,131,1,0,1,110,0,0,100,5,0,106, - 0,0,124,0,0,106,6,0,106,7,0,100,6,0,106,8, - 0,124,1,0,131,1,0,131,2,0,83,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,47,0,0,0,114,67,0,0,0,114,169,0,0,0,114, - 217,0,0,0,218,6,97,112,112,101,110,100,114,220,0,0, - 0,218,9,95,95,99,108,97,115,115,95,95,114,57,0,0, - 0,114,26,0,0,0,41,2,114,71,0,0,0,114,80,0, - 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, - 0,114,101,0,0,0,24,3,0,0,115,16,0,0,0,0, - 1,15,1,21,1,15,1,28,1,15,1,6,1,22,1,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,3,0,0, - 0,13,0,0,0,67,0,0,0,115,145,0,0,0,124,0, - 0,106,0,0,125,2,0,121,107,0,124,0,0,106,1,0, - 124,1,0,106,1,0,107,2,0,111,114,0,124,0,0,106, - 2,0,124,1,0,106,2,0,107,2,0,111,114,0,124,0, - 0,106,3,0,124,1,0,106,3,0,107,2,0,111,114,0, - 124,2,0,124,1,0,106,0,0,107,2,0,111,114,0,124, - 0,0,106,4,0,124,1,0,106,4,0,107,2,0,111,114, - 0,124,0,0,106,5,0,124,1,0,106,5,0,107,2,0, - 83,87,110,22,0,4,116,6,0,107,10,0,114,140,0,1, - 1,1,100,1,0,83,89,110,1,0,88,100,0,0,83,41, - 2,78,70,41,7,114,220,0,0,0,114,67,0,0,0,114, - 169,0,0,0,114,217,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, - 209,0,0,0,41,3,114,71,0,0,0,90,5,111,116,104, - 101,114,90,4,115,109,115,108,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,218,6,95,95,101,113,95,95,34, - 3,0,0,115,20,0,0,0,0,1,9,1,3,1,18,1, - 18,1,18,1,15,1,18,1,20,1,13,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,2,0,0,0,12,0,0,0, - 67,0,0,0,115,158,0,0,0,124,0,0,106,0,0,100, - 0,0,107,8,0,114,151,0,124,0,0,106,1,0,100,0, - 0,107,9,0,114,151,0,124,0,0,106,2,0,114,151,0, - 124,0,0,106,1,0,125,1,0,124,1,0,106,3,0,116, - 4,0,116,5,0,131,1,0,131,1,0,114,112,0,121,19, - 0,116,6,0,124,1,0,131,1,0,124,0,0,95,0,0, - 87,113,145,0,4,116,7,0,107,10,0,114,108,0,1,1, - 1,89,113,145,0,88,113,148,0,124,1,0,106,3,0,116, - 4,0,116,8,0,131,1,0,131,1,0,114,148,0,124,1, - 0,124,0,0,95,0,0,113,148,0,113,151,0,110,0,0, - 124,0,0,106,0,0,83,41,1,78,41,9,114,222,0,0, - 0,114,217,0,0,0,114,221,0,0,0,218,8,101,110,100, - 115,119,105,116,104,218,5,116,117,112,108,101,114,134,0,0, - 0,114,132,0,0,0,114,124,0,0,0,218,17,66,89,84, - 69,67,79,68,69,95,83,85,70,70,73,88,69,83,41,2, - 114,71,0,0,0,114,131,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,114,225,0,0,0,46,3, - 0,0,115,22,0,0,0,0,2,15,1,24,1,9,1,21, - 1,3,1,19,1,13,1,8,1,21,1,18,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,2,0,0,0,2,0,0, - 0,67,0,0,0,115,13,0,0,0,124,1,0,124,0,0, - 95,0,0,100,0,0,83,41,1,78,41,1,114,222,0,0, - 0,41,2,114,71,0,0,0,114,225,0,0,0,114,4,0, - 0,0,114,4,0,0,0,114,5,0,0,0,114,225,0,0, - 0,60,3,0,0,115,2,0,0,0,0,2,99,1,0,0, - 0,0,0,0,0,1,0,0,0,2,0,0,0,67,0,0, - 0,115,46,0,0,0,124,0,0,106,0,0,100,1,0,107, - 8,0,114,35,0,124,0,0,106,1,0,106,2,0,100,2, - 0,131,1,0,100,3,0,25,83,124,0,0,106,1,0,83, - 100,1,0,83,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,114,116,0,0,0,114,84, - 0,0,0,41,3,114,220,0,0,0,114,67,0,0,0,114, - 32,0,0,0,41,1,114,71,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,218,6,112,97,114,101, - 110,116,64,3,0,0,115,6,0,0,0,0,3,15,1,20, - 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,1,0,0, - 0,1,0,0,0,67,0,0,0,115,7,0,0,0,124,0, - 0,106,0,0,83,41,1,78,41,1,114,221,0,0,0,41, - 1,114,71,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,226,0,0,0,72,3,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,41,12, - 114,57,0,0,0,114,56,0,0,0,114,58,0,0,0,114, - 59,0,0,0,114,72,0,0,0,114,101,0,0,0,114,227, - 0,0,0,218,8,112,114,111,112,101,114,116,121,114,225,0, - 0,0,218,6,115,101,116,116,101,114,114,231,0,0,0,114, - 226,0,0,0,114,4,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,216,0,0,0,231,2,0, - 0,115,18,0,0,0,12,35,6,2,15,1,15,11,12,10, - 12,12,18,14,21,4,18,8,114,216,0,0,0,114,217,0, - 0,0,114,219,0,0,0,99,2,0,0,0,2,0,0,0, - 5,0,0,0,15,0,0,0,67,0,0,0,115,193,0,0, - 0,116,0,0,124,1,0,100,1,0,131,2,0,114,83,0, - 124,3,0,100,2,0,107,8,0,114,43,0,116,1,0,124, - 0,0,100,3,0,124,1,0,131,1,1,83,124,3,0,114, - 55,0,103,0,0,110,3,0,100,2,0,125,4,0,116,1, - 0,124,0,0,100,3,0,124,1,0,100,4,0,124,4,0, - 131,1,2,83,124,3,0,100,2,0,107,8,0,114,168,0, - 116,0,0,124,1,0,100,5,0,131,2,0,114,159,0,121, - 19,0,124,1,0,106,2,0,124,0,0,131,1,0,125,3, - 0,87,113,165,0,4,116,3,0,107,10,0,114,155,0,1, - 1,1,100,2,0,125,3,0,89,113,165,0,88,113,168,0, - 100,6,0,125,3,0,110,0,0,116,4,0,124,0,0,124, - 1,0,100,7,0,124,2,0,100,5,0,124,3,0,131,2, - 2,83,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,218,12,103,101,116, - 95,102,105,108,101,110,97,109,101,78,114,169,0,0,0,114, - 220,0,0,0,114,219,0,0,0,70,114,217,0,0,0,41, - 5,114,60,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, - 219,0,0,0,114,153,0,0,0,114,216,0,0,0,41,5, - 114,67,0,0,0,114,169,0,0,0,114,217,0,0,0,114, - 219,0,0,0,90,6,115,101,97,114,99,104,114,4,0,0, - 0,114,4,0,0,0,114,5,0,0,0,114,173,0,0,0, - 77,3,0,0,115,28,0,0,0,0,2,15,1,12,1,16, - 1,18,1,15,1,7,2,12,1,15,1,3,1,19,1,13, - 1,14,3,9,2,114,173,0,0,0,114,169,0,0,0,114, - 220,0,0,0,99,2,0,0,0,2,0,0,0,9,0,0, - 0,19,0,0,0,67,0,0,0,115,110,1,0,0,124,1, - 0,100,1,0,107,8,0,114,79,0,100,2,0,125,1,0, - 116,0,0,124,2,0,100,3,0,131,2,0,114,79,0,121, - 19,0,124,2,0,106,1,0,124,0,0,131,1,0,125,1, - 0,87,113,76,0,4,116,2,0,107,10,0,114,72,0,1, - 1,1,89,113,76,0,88,113,79,0,110,0,0,116,3,0, - 124,0,0,124,2,0,100,4,0,124,1,0,131,2,1,125, - 4,0,100,5,0,124,4,0,95,4,0,124,2,0,100,1, - 0,107,8,0,114,203,0,120,79,0,116,5,0,131,0,0, - 68,93,61,0,92,2,0,125,5,0,125,6,0,124,1,0, - 106,6,0,116,7,0,124,6,0,131,1,0,131,1,0,114, - 131,0,124,5,0,124,0,0,124,1,0,131,2,0,125,2, - 0,124,2,0,124,4,0,95,8,0,80,113,131,0,113,131, - 0,87,100,1,0,83,110,0,0,124,3,0,116,9,0,107, - 8,0,114,38,1,116,0,0,124,2,0,100,6,0,131,2, - 0,114,47,1,121,19,0,124,2,0,106,10,0,124,0,0, - 131,1,0,125,7,0,87,110,18,0,4,116,2,0,107,10, - 0,114,13,1,1,1,1,89,113,35,1,88,124,7,0,114, - 35,1,103,0,0,124,4,0,95,11,0,113,35,1,113,47, - 1,110,9,0,124,3,0,124,4,0,95,11,0,124,4,0, - 106,11,0,103,0,0,107,2,0,114,106,1,124,1,0,114, - 106,1,116,12,0,124,1,0,131,1,0,100,7,0,25,125, - 8,0,124,4,0,106,11,0,106,13,0,124,8,0,131,1, - 0,1,113,106,1,110,0,0,124,4,0,83,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,114,234,0,0, - 0,114,217,0,0,0,84,114,219,0,0,0,114,84,0,0, - 0,41,14,114,60,0,0,0,114,234,0,0,0,114,153,0, - 0,0,114,216,0,0,0,114,221,0,0,0,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,228,0,0,0,114,229, - 0,0,0,114,169,0,0,0,218,9,95,80,79,80,85,76, - 65,84,69,114,219,0,0,0,114,220,0,0,0,114,38,0, - 0,0,114,223,0,0,0,41,9,114,67,0,0,0,218,8, - 108,111,99,97,116,105,111,110,114,169,0,0,0,114,220,0, - 0,0,114,177,0,0,0,218,12,108,111,97,100,101,114,95, - 99,108,97,115,115,114,127,0,0,0,114,219,0,0,0,90, - 7,100,105,114,110,97,109,101,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,114,235,0,0,0,102,3,0,0, - 115,60,0,0,0,0,12,12,4,6,1,15,2,3,1,19, - 1,13,1,11,8,21,1,9,3,12,1,22,1,21,1,15, - 1,9,1,8,2,7,3,12,2,15,1,3,1,19,1,13, - 1,5,2,6,1,18,2,9,1,15,1,6,1,16,1,22, - 2,114,235,0,0,0,99,3,0,0,0,0,0,0,0,8, - 0,0,0,53,0,0,0,67,0,0,0,115,124,1,0,0, - 121,13,0,124,0,0,106,0,0,125,3,0,87,110,18,0, - 4,116,1,0,107,10,0,114,33,0,1,1,1,89,110,17, - 0,88,124,3,0,100,0,0,107,9,0,114,50,0,124,3, - 0,83,124,0,0,106,2,0,125,4,0,124,1,0,100,0, - 0,107,8,0,114,108,0,121,13,0,124,0,0,106,3,0, - 125,1,0,87,113,108,0,4,116,1,0,107,10,0,114,104, - 0,1,1,1,89,113,108,0,88,110,0,0,121,13,0,124, - 0,0,106,4,0,125,5,0,87,110,24,0,4,116,1,0, - 107,10,0,114,147,0,1,1,1,100,0,0,125,5,0,89, - 110,1,0,88,124,2,0,100,0,0,107,8,0,114,224,0, - 124,5,0,100,0,0,107,8,0,114,215,0,121,13,0,124, - 1,0,106,5,0,125,2,0,87,113,221,0,4,116,1,0, - 107,10,0,114,211,0,1,1,1,100,0,0,125,2,0,89, - 113,221,0,88,113,224,0,124,5,0,125,2,0,110,0,0, - 121,13,0,124,0,0,106,6,0,125,6,0,87,110,24,0, - 4,116,1,0,107,10,0,114,7,1,1,1,1,100,0,0, - 125,6,0,89,110,1,0,88,121,19,0,116,7,0,124,0, - 0,106,8,0,131,1,0,125,7,0,87,110,24,0,4,116, - 1,0,107,10,0,114,53,1,1,1,1,100,0,0,125,7, - 0,89,110,1,0,88,116,9,0,124,4,0,124,1,0,100, - 1,0,124,2,0,131,2,1,125,3,0,124,5,0,100,0, - 0,107,8,0,114,93,1,100,2,0,110,3,0,100,3,0, - 124,3,0,95,10,0,124,6,0,124,3,0,95,11,0,124, - 7,0,124,3,0,95,12,0,124,3,0,83,41,4,78,114, - 217,0,0,0,70,84,41,13,114,208,0,0,0,114,209,0, - 0,0,114,57,0,0,0,114,204,0,0,0,114,210,0,0, - 0,90,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,216,0,0,0,114,221,0,0,0, - 114,225,0,0,0,114,220,0,0,0,41,8,114,179,0,0, - 0,114,169,0,0,0,114,217,0,0,0,114,177,0,0,0, - 114,67,0,0,0,114,238,0,0,0,114,225,0,0,0,114, - 220,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,17,95,115,112,101,99,95,102,114,111,109,95, - 109,111,100,117,108,101,166,3,0,0,115,72,0,0,0,0, - 2,3,1,13,1,13,1,5,2,12,1,4,2,9,1,12, - 1,3,1,13,1,13,2,8,1,3,1,13,1,13,1,11, - 1,12,1,12,1,3,1,13,1,13,1,14,2,9,1,3, - 1,13,1,13,1,11,1,3,1,19,1,13,1,11,2,21, - 1,27,1,9,1,9,1,114,243,0,0,0,99,0,0,0, - 0,0,0,0,0,0,0,0,0,6,0,0,0,64,0,0, - 0,115,172,0,0,0,101,0,0,90,1,0,100,0,0,90, - 2,0,100,1,0,90,3,0,100,2,0,100,3,0,132,0, - 0,90,4,0,101,5,0,100,4,0,100,5,0,132,0,0, - 131,1,0,90,6,0,100,6,0,100,7,0,132,0,0,90, - 7,0,100,8,0,100,9,0,100,10,0,100,11,0,100,12, - 0,100,13,0,132,0,2,90,8,0,100,14,0,100,15,0, - 132,0,0,90,9,0,100,16,0,100,17,0,132,0,0,90, - 10,0,100,18,0,100,19,0,132,0,0,90,11,0,100,20, - 0,100,21,0,132,0,0,90,12,0,100,22,0,100,23,0, - 132,0,0,90,13,0,100,24,0,100,25,0,132,0,0,90, - 14,0,100,26,0,100,27,0,132,0,0,90,15,0,100,28, - 0,83,41,29,114,174,0,0,0,122,77,67,111,110,118,101, - 110,105,101,110,99,101,32,119,114,97,112,112,101,114,32,97, - 114,111,117,110,100,32,115,112,101,99,32,111,98,106,101,99, - 116,115,32,116,111,32,112,114,111,118,105,100,101,32,115,112, - 101,99,45,115,112,101,99,105,102,105,99,10,32,32,32,32, - 109,101,116,104,111,100,115,46,99,2,0,0,0,0,0,0, - 0,2,0,0,0,2,0,0,0,67,0,0,0,115,13,0, - 0,0,124,1,0,124,0,0,95,0,0,100,0,0,83,41, - 1,78,41,1,114,177,0,0,0,41,2,114,71,0,0,0, - 114,177,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,114,72,0,0,0,216,3,0,0,115,2,0, - 0,0,0,1,122,21,95,83,112,101,99,77,101,116,104,111, - 100,115,46,95,95,105,110,105,116,95,95,99,2,0,0,0, - 0,0,0,0,4,0,0,0,17,0,0,0,67,0,0,0, - 115,144,0,0,0,121,13,0,124,1,0,106,0,0,125,2, - 0,87,110,118,0,4,116,1,0,107,10,0,114,133,0,1, - 1,1,121,13,0,124,2,0,106,2,0,125,3,0,87,110, - 66,0,4,116,1,0,107,10,0,114,110,0,1,1,1,116, - 3,0,124,1,0,106,4,0,131,1,0,125,2,0,124,2, - 0,100,1,0,107,8,0,114,106,0,116,5,0,124,1,0, - 106,4,0,124,3,0,131,2,0,125,2,0,110,0,0,89, - 110,19,0,88,116,5,0,124,1,0,106,4,0,124,3,0, - 131,2,0,125,2,0,89,110,1,0,88,124,0,0,124,2, - 0,131,1,0,83,41,2,122,41,67,114,101,97,116,101,32, - 97,32,115,112,101,99,32,102,114,111,109,32,97,32,109,111, - 100,117,108,101,39,115,32,97,116,116,114,105,98,117,116,101, - 115,46,78,41,6,114,208,0,0,0,114,209,0,0,0,114, - 204,0,0,0,218,10,95,102,105,110,100,95,115,112,101,99, - 114,57,0,0,0,114,173,0,0,0,41,4,218,3,99,108, - 115,114,179,0,0,0,114,177,0,0,0,114,169,0,0,0, - 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,218, - 11,102,114,111,109,95,109,111,100,117,108,101,219,3,0,0, - 115,22,0,0,0,0,3,3,1,13,1,13,1,3,1,13, - 1,13,1,15,1,12,1,26,2,23,1,122,24,95,83,112, - 101,99,77,101,116,104,111,100,115,46,102,114,111,109,95,109, - 111,100,117,108,101,99,1,0,0,0,0,0,0,0,3,0, - 0,0,3,0,0,0,67,0,0,0,115,158,0,0,0,124, - 0,0,106,0,0,125,1,0,124,1,0,106,1,0,100,1, - 0,107,8,0,114,30,0,100,2,0,110,6,0,124,1,0, - 106,1,0,125,2,0,124,1,0,106,2,0,100,1,0,107, - 8,0,114,104,0,124,1,0,106,3,0,100,1,0,107,8, - 0,114,82,0,100,3,0,106,4,0,124,2,0,131,1,0, - 83,100,4,0,106,4,0,124,2,0,124,1,0,106,3,0, - 131,2,0,83,110,50,0,124,1,0,106,5,0,114,132,0, - 100,5,0,106,4,0,124,2,0,124,1,0,106,2,0,131, - 2,0,83,100,6,0,106,4,0,124,1,0,106,1,0,124, - 1,0,106,2,0,131,2,0,83,100,1,0,83,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,206,0,0,0,122,13,60, - 109,111,100,117,108,101,32,123,33,114,125,62,122,20,60,109, - 111,100,117,108,101,32,123,33,114,125,32,40,123,33,114,125, - 41,62,122,23,60,109,111,100,117,108,101,32,123,33,114,125, - 32,102,114,111,109,32,123,33,114,125,62,122,18,60,109,111, - 100,117,108,101,32,123,33,114,125,32,40,123,125,41,62,41, - 6,114,177,0,0,0,114,67,0,0,0,114,217,0,0,0, - 114,169,0,0,0,114,47,0,0,0,114,226,0,0,0,41, - 3,114,71,0,0,0,114,177,0,0,0,114,67,0,0,0, - 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, - 205,0,0,0,235,3,0,0,115,18,0,0,0,0,3,9, - 1,30,1,15,1,15,1,13,2,22,2,9,1,19,2,122, - 24,95,83,112,101,99,77,101,116,104,111,100,115,46,109,111, - 100,117,108,101,95,114,101,112,114,218,9,95,111,118,101,114, - 114,105,100,101,70,218,11,95,102,111,114,99,101,95,110,97, - 109,101,84,99,2,0,0,0,2,0,0,0,6,0,0,0, - 66,0,0,0,67,0,0,0,115,75,2,0,0,124,0,0, - 106,0,0,125,4,0,124,2,0,115,45,0,124,3,0,115, - 45,0,116,1,0,124,1,0,100,1,0,100,2,0,131,3, - 0,100,2,0,107,8,0,114,85,0,121,16,0,124,4,0, - 106,2,0,124,1,0,95,3,0,87,113,85,0,4,116,4, - 0,107,10,0,114,81,0,1,1,1,89,113,85,0,88,110, - 0,0,124,2,0,115,115,0,116,1,0,124,1,0,100,3, - 0,100,2,0,131,3,0,100,2,0,107,8,0,114,221,0, - 124,4,0,106,5,0,125,5,0,124,5,0,100,2,0,107, - 8,0,114,184,0,124,4,0,106,6,0,100,2,0,107,9, - 0,114,184,0,116,7,0,106,8,0,116,7,0,131,1,0, - 125,5,0,124,4,0,106,6,0,124,5,0,95,9,0,113, - 184,0,110,0,0,121,13,0,124,5,0,124,1,0,95,10, - 0,87,113,221,0,4,116,4,0,107,10,0,114,217,0,1, - 1,1,89,113,221,0,88,110,0,0,124,2,0,115,251,0, - 116,1,0,124,1,0,100,4,0,100,2,0,131,3,0,100, - 2,0,107,8,0,114,35,1,121,16,0,124,4,0,106,11, - 0,124,1,0,95,12,0,87,113,35,1,4,116,4,0,107, - 10,0,114,31,1,1,1,1,89,113,35,1,88,110,0,0, - 121,13,0,124,4,0,124,1,0,95,13,0,87,110,18,0, - 4,116,4,0,107,10,0,114,68,1,1,1,1,89,110,1, - 0,88,124,2,0,115,99,1,116,1,0,124,1,0,100,5, - 0,100,2,0,131,3,0,100,2,0,107,8,0,114,157,1, - 124,4,0,106,6,0,100,2,0,107,9,0,114,157,1,121, - 16,0,124,4,0,106,6,0,124,1,0,95,14,0,87,113, - 154,1,4,116,4,0,107,10,0,114,150,1,1,1,1,89, - 113,154,1,88,113,157,1,110,0,0,124,4,0,106,15,0, - 114,71,2,124,2,0,115,196,1,116,1,0,124,1,0,100, - 6,0,100,2,0,131,3,0,100,2,0,107,8,0,114,236, - 1,121,16,0,124,4,0,106,16,0,124,1,0,95,17,0, - 87,113,236,1,4,116,4,0,107,10,0,114,232,1,1,1, - 1,89,113,236,1,88,110,0,0,124,2,0,115,10,2,116, - 1,0,124,1,0,100,7,0,100,2,0,131,3,0,100,2, - 0,107,8,0,114,71,2,124,4,0,106,18,0,100,2,0, - 107,9,0,114,68,2,121,16,0,124,4,0,106,18,0,124, - 1,0,95,19,0,87,113,65,2,4,116,4,0,107,10,0, - 114,61,2,1,1,1,89,113,65,2,88,113,68,2,113,71, - 2,110,0,0,100,2,0,83,41,8,97,29,2,0,0,83, - 101,116,32,116,104,101,32,109,111,100,117,108,101,39,115,32, - 97,116,116,114,105,98,117,116,101,115,46,10,10,32,32,32, - 32,32,32,32,32,65,108,108,32,109,105,115,115,105,110,103, - 32,105,109,112,111,114,116,45,114,101,108,97,116,101,100,32, - 109,111,100,117,108,101,32,97,116,116,114,105,98,117,116,101, - 115,32,119,105,108,108,32,98,101,32,115,101,116,46,32,32, - 72,101,114,101,10,32,32,32,32,32,32,32,32,105,115,32, - 104,111,119,32,116,104,101,32,115,112,101,99,32,97,116,116, - 114,105,98,117,116,101,115,32,109,97,112,32,111,110,116,111, - 32,116,104,101,32,109,111,100,117,108,101,58,10,10,32,32, - 32,32,32,32,32,32,115,112,101,99,46,110,97,109,101,32, - 45,62,32,109,111,100,117,108,101,46,95,95,110,97,109,101, - 95,95,10,32,32,32,32,32,32,32,32,115,112,101,99,46, - 108,111,97,100,101,114,32,45,62,32,109,111,100,117,108,101, - 46,95,95,108,111,97,100,101,114,95,95,10,32,32,32,32, - 32,32,32,32,115,112,101,99,46,112,97,114,101,110,116,32, - 45,62,32,109,111,100,117,108,101,46,95,95,112,97,99,107, - 97,103,101,95,95,10,32,32,32,32,32,32,32,32,115,112, - 101,99,32,45,62,32,109,111,100,117,108,101,46,95,95,115, - 112,101,99,95,95,10,10,32,32,32,32,32,32,32,32,79, - 112,116,105,111,110,97,108,58,10,32,32,32,32,32,32,32, - 32,115,112,101,99,46,111,114,105,103,105,110,32,45,62,32, - 109,111,100,117,108,101,46,95,95,102,105,108,101,95,95,32, - 40,105,102,32,115,112,101,99,46,115,101,116,95,102,105,108, - 101,97,116,116,114,32,105,115,32,116,114,117,101,41,10,32, - 32,32,32,32,32,32,32,115,112,101,99,46,99,97,99,104, - 101,100,32,45,62,32,109,111,100,117,108,101,46,95,95,99, - 97,99,104,101,100,95,95,32,40,105,102,32,95,95,102,105, - 108,101,95,95,32,97,108,115,111,32,115,101,116,41,10,32, - 32,32,32,32,32,32,32,115,112,101,99,46,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,45,62,32,109,111,100,117,108,101, - 46,95,95,112,97,116,104,95,95,32,40,105,102,32,115,101, - 116,41,10,10,32,32,32,32,32,32,32,32,114,57,0,0, - 0,78,114,204,0,0,0,218,11,95,95,112,97,99,107,97, - 103,101,95,95,114,242,0,0,0,114,210,0,0,0,114,240, - 0,0,0,41,20,114,177,0,0,0,114,62,0,0,0,114, - 67,0,0,0,114,57,0,0,0,114,209,0,0,0,114,169, - 0,0,0,114,220,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,218,5,95,112,97,116,104,114,204,0,0,0,114, - 231,0,0,0,114,249,0,0,0,114,208,0,0,0,114,242, - 0,0,0,114,226,0,0,0,114,217,0,0,0,114,210,0, - 0,0,114,225,0,0,0,114,240,0,0,0,41,6,114,71, - 0,0,0,114,179,0,0,0,114,247,0,0,0,114,248,0, - 0,0,114,177,0,0,0,114,169,0,0,0,114,4,0,0, - 0,114,4,0,0,0,114,5,0,0,0,218,17,105,110,105, - 116,95,109,111,100,117,108,101,95,97,116,116,114,115,251,3, - 0,0,115,88,0,0,0,0,17,9,6,12,1,24,1,3, - 1,16,1,13,1,8,3,30,1,9,1,12,2,15,1,15, - 1,18,1,3,1,13,1,13,1,8,3,30,1,3,1,16, - 1,13,1,8,3,3,1,13,1,13,1,5,3,30,1,15, - 1,3,1,16,1,13,1,11,2,9,2,30,1,3,1,16, - 1,13,1,8,3,30,1,15,1,3,1,16,1,13,1,122, - 30,95,83,112,101,99,77,101,116,104,111,100,115,46,105,110, - 105,116,95,109,111,100,117,108,101,95,97,116,116,114,115,99, - 1,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0, - 67,0,0,0,115,101,0,0,0,124,0,0,106,0,0,125, - 1,0,116,1,0,124,1,0,106,2,0,100,1,0,131,2, - 0,114,48,0,124,1,0,106,2,0,106,3,0,124,1,0, - 131,1,0,125,2,0,110,6,0,100,2,0,125,2,0,124, - 2,0,100,2,0,107,8,0,114,84,0,116,4,0,124,1, - 0,106,5,0,131,1,0,125,2,0,110,0,0,124,0,0, - 106,6,0,124,2,0,131,1,0,1,124,2,0,83,41,3, - 122,153,82,101,116,117,114,110,32,97,32,110,101,119,32,109, - 111,100,117,108,101,32,116,111,32,98,101,32,108,111,97,100, - 101,100,46,10,10,32,32,32,32,32,32,32,32,84,104,101, - 32,105,109,112,111,114,116,45,114,101,108,97,116,101,100,32, - 109,111,100,117,108,101,32,97,116,116,114,105,98,117,116,101, - 115,32,97,114,101,32,97,108,115,111,32,115,101,116,32,119, - 105,116,104,32,116,104,101,10,32,32,32,32,32,32,32,32, - 97,112,112,114,111,112,114,105,97,116,101,32,118,97,108,117, - 101,115,32,102,114,111,109,32,116,104,101,32,115,112,101,99, - 46,10,10,32,32,32,32,32,32,32,32,218,13,99,114,101, - 97,116,101,95,109,111,100,117,108,101,78,41,7,114,177,0, - 0,0,114,60,0,0,0,114,169,0,0,0,114,254,0,0, - 0,114,68,0,0,0,114,67,0,0,0,114,253,0,0,0, - 41,3,114,71,0,0,0,114,177,0,0,0,114,179,0,0, - 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 218,6,99,114,101,97,116,101,75,4,0,0,115,16,0,0, - 0,0,7,9,2,18,3,21,2,6,1,12,4,18,1,13, - 1,122,19,95,83,112,101,99,77,101,116,104,111,100,115,46, - 99,114,101,97,116,101,99,2,0,0,0,0,0,0,0,2, - 0,0,0,2,0,0,0,67,0,0,0,115,23,0,0,0, - 124,0,0,106,0,0,106,1,0,106,2,0,124,1,0,131, - 1,0,1,100,1,0,83,41,2,122,189,68,111,32,101,118, - 101,114,121,116,104,105,110,103,32,110,101,99,101,115,115,97, - 114,121,32,116,111,32,101,120,101,99,117,116,101,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,110,97,109,101,115,112,97,99,101, - 32,111,102,32,96,109,111,100,117,108,101,96,32,105,115,32, - 117,115,101,100,32,97,115,32,116,104,101,32,116,97,114,103, - 101,116,32,111,102,32,101,120,101,99,117,116,105,111,110,46, - 10,32,32,32,32,32,32,32,32,84,104,105,115,32,109,101, - 116,104,111,100,32,117,115,101,115,32,116,104,101,32,108,111, - 97,100,101,114,39,115,32,96,101,120,101,99,95,109,111,100, - 117,108,101,40,41,96,32,109,101,116,104,111,100,46,10,10, - 32,32,32,32,32,32,32,32,78,41,3,114,177,0,0,0, - 114,169,0,0,0,218,11,101,120,101,99,95,109,111,100,117, - 108,101,41,2,114,71,0,0,0,114,179,0,0,0,114,4, - 0,0,0,114,4,0,0,0,114,5,0,0,0,218,5,95, - 101,120,101,99,98,4,0,0,115,2,0,0,0,0,7,122, - 18,95,83,112,101,99,77,101,116,104,111,100,115,46,95,101, - 120,101,99,99,2,0,0,0,0,0,0,0,4,0,0,0, - 11,0,0,0,67,0,0,0,115,17,1,0,0,124,0,0, - 106,0,0,106,1,0,125,2,0,116,2,0,106,3,0,131, - 0,0,1,116,4,0,124,2,0,131,1,0,143,226,0,1, - 116,5,0,106,6,0,106,7,0,124,2,0,131,1,0,124, - 1,0,107,9,0,114,95,0,100,1,0,106,8,0,124,2, - 0,131,1,0,125,3,0,116,9,0,124,3,0,100,2,0, - 124,2,0,131,1,1,130,1,0,110,0,0,124,0,0,106, - 0,0,106,10,0,100,3,0,107,8,0,114,181,0,124,0, - 0,106,0,0,106,11,0,100,3,0,107,8,0,114,158,0, - 116,9,0,100,4,0,100,2,0,124,0,0,106,0,0,106, - 1,0,131,1,1,130,1,0,110,0,0,124,0,0,106,12, - 0,124,1,0,100,5,0,100,6,0,131,1,1,1,124,1, - 0,83,124,0,0,106,12,0,124,1,0,100,5,0,100,6, - 0,131,1,1,1,116,13,0,124,0,0,106,0,0,106,10, - 0,100,7,0,131,2,0,115,243,0,124,0,0,106,0,0, - 106,10,0,106,14,0,124,2,0,131,1,0,1,110,13,0, - 124,0,0,106,15,0,124,1,0,131,1,0,1,87,100,3, - 0,81,88,116,5,0,106,6,0,124,2,0,25,83,41,8, - 122,51,69,120,101,99,117,116,101,32,116,104,101,32,115,112, - 101,99,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,67,0,0,0,78,122,14,109,105,115, - 115,105,110,103,32,108,111,97,100,101,114,114,247,0,0,0, - 84,114,0,1,0,0,41,16,114,177,0,0,0,114,67,0, - 0,0,114,106,0,0,0,218,12,97,99,113,117,105,114,101, - 95,108,111,99,107,114,103,0,0,0,114,7,0,0,0,114, - 73,0,0,0,114,93,0,0,0,114,47,0,0,0,114,153, - 0,0,0,114,169,0,0,0,114,220,0,0,0,114,253,0, - 0,0,114,60,0,0,0,218,11,108,111,97,100,95,109,111, - 100,117,108,101,114,1,1,0,0,41,4,114,71,0,0,0, - 114,179,0,0,0,114,67,0,0,0,114,171,0,0,0,114, - 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,175, - 0,0,0,108,4,0,0,115,32,0,0,0,0,2,12,1, - 10,1,13,1,24,1,15,1,21,1,18,1,18,1,27,2, - 19,1,4,1,19,1,21,2,22,2,19,1,122,17,95,83, - 112,101,99,77,101,116,104,111,100,115,46,101,120,101,99,99, - 1,0,0,0,0,0,0,0,3,0,0,0,27,0,0,0, - 67,0,0,0,115,24,1,0,0,124,0,0,106,0,0,125, - 1,0,124,1,0,106,1,0,106,2,0,124,1,0,106,3, - 0,131,1,0,1,116,4,0,106,5,0,124,1,0,106,3, - 0,25,125,2,0,116,6,0,124,2,0,100,1,0,100,0, - 0,131,3,0,100,0,0,107,8,0,114,108,0,121,16,0, - 124,1,0,106,1,0,124,2,0,95,7,0,87,113,108,0, - 4,116,8,0,107,10,0,114,104,0,1,1,1,89,113,108, - 0,88,110,0,0,116,6,0,124,2,0,100,2,0,100,0, - 0,131,3,0,100,0,0,107,8,0,114,215,0,121,59,0, - 124,2,0,106,9,0,124,2,0,95,10,0,116,11,0,124, - 2,0,100,3,0,131,2,0,115,190,0,124,1,0,106,3, - 0,106,12,0,100,4,0,131,1,0,100,5,0,25,124,2, - 0,95,10,0,110,0,0,87,113,215,0,4,116,8,0,107, - 10,0,114,211,0,1,1,1,89,113,215,0,88,110,0,0, - 116,6,0,124,2,0,100,6,0,100,0,0,131,3,0,100, - 0,0,107,8,0,114,20,1,121,13,0,124,1,0,124,2, - 0,95,13,0,87,113,20,1,4,116,8,0,107,10,0,114, - 16,1,1,1,1,89,113,20,1,88,110,0,0,124,2,0, - 83,41,7,78,114,204,0,0,0,114,249,0,0,0,114,242, - 0,0,0,114,116,0,0,0,114,84,0,0,0,114,208,0, - 0,0,41,14,114,177,0,0,0,114,169,0,0,0,114,3, - 1,0,0,114,67,0,0,0,114,7,0,0,0,114,73,0, - 0,0,114,62,0,0,0,114,204,0,0,0,114,209,0,0, - 0,114,57,0,0,0,114,249,0,0,0,114,60,0,0,0, - 114,32,0,0,0,114,208,0,0,0,41,3,114,71,0,0, - 0,114,177,0,0,0,114,179,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,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,130,4,0,0,115,42,0,0,0,0,2, - 9,2,19,1,16,1,24,1,3,1,16,1,13,1,8,1, - 24,1,3,4,12,1,15,1,32,1,13,1,8,1,24,1, - 3,1,13,1,13,1,8,1,122,38,95,83,112,101,99,77, - 101,116,104,111,100,115,46,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, - 99,2,0,0,0,0,0,0,0,3,0,0,0,9,0,0, - 0,67,0,0,0,115,38,0,0,0,116,0,0,124,1,0, - 131,1,0,143,20,0,1,124,0,0,106,1,0,124,1,0, - 131,1,0,125,2,0,87,100,1,0,81,88,124,2,0,83, - 41,2,122,60,69,120,101,99,32,116,104,101,32,115,112,101, - 99,39,101,100,32,109,111,100,117,108,101,32,105,110,116,111, - 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, - 78,41,2,114,212,0,0,0,114,175,0,0,0,41,3,114, - 71,0,0,0,114,179,0,0,0,90,6,108,111,97,100,101, - 100,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 218,14,95,108,111,97,100,95,101,120,105,115,116,105,110,103, - 160,4,0,0,115,6,0,0,0,0,3,13,1,21,1,122, - 27,95,83,112,101,99,77,101,116,104,111,100,115,46,95,108, - 111,97,100,95,101,120,105,115,116,105,110,103,99,1,0,0, - 0,0,0,0,0,2,0,0,0,11,0,0,0,67,0,0, - 0,115,179,0,0,0,124,0,0,106,0,0,106,1,0,100, - 0,0,107,9,0,114,52,0,116,2,0,124,0,0,106,0, - 0,106,1,0,100,1,0,131,2,0,115,52,0,124,0,0, - 106,3,0,131,0,0,83,110,0,0,124,0,0,106,4,0, - 131,0,0,125,1,0,116,5,0,124,1,0,131,1,0,143, - 84,0,1,124,0,0,106,0,0,106,1,0,100,0,0,107, - 8,0,114,143,0,124,0,0,106,0,0,106,6,0,100,0, - 0,107,8,0,114,156,0,116,7,0,100,2,0,100,3,0, - 124,0,0,106,0,0,106,8,0,131,1,1,130,1,0,113, - 156,0,110,13,0,124,0,0,106,9,0,124,1,0,131,1, - 0,1,87,100,0,0,81,88,116,10,0,106,11,0,124,0, - 0,106,0,0,106,8,0,25,83,41,4,78,114,0,1,0, - 0,122,14,109,105,115,115,105,110,103,32,108,111,97,100,101, - 114,114,67,0,0,0,41,12,114,177,0,0,0,114,169,0, - 0,0,114,60,0,0,0,114,4,1,0,0,114,255,0,0, - 0,114,212,0,0,0,114,220,0,0,0,114,153,0,0,0, - 114,67,0,0,0,114,1,1,0,0,114,7,0,0,0,114, - 73,0,0,0,41,2,114,71,0,0,0,114,179,0,0,0, - 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,218, - 14,95,108,111,97,100,95,117,110,108,111,99,107,101,100,167, - 4,0,0,115,20,0,0,0,0,2,18,2,21,1,13,2, - 12,1,13,1,18,1,18,1,30,3,19,5,122,27,95,83, - 112,101,99,77,101,116,104,111,100,115,46,95,108,111,97,100, - 95,117,110,108,111,99,107,101,100,99,1,0,0,0,0,0, - 0,0,1,0,0,0,8,0,0,0,67,0,0,0,115,49, + 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,218,6,111,114, + 105,103,105,110,78,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,3,0,0,0,6,0,0,0,2,0,0,0, + 67,0,0,0,115,79,0,0,0,124,1,0,124,0,0,95, + 0,0,124,2,0,124,0,0,95,1,0,124,3,0,124,0, + 0,95,2,0,124,4,0,124,0,0,95,3,0,124,5,0, + 114,48,0,103,0,0,110,3,0,100,0,0,124,0,0,95, + 4,0,100,1,0,124,0,0,95,5,0,100,0,0,124,0, + 0,95,6,0,100,0,0,83,41,2,78,70,41,7,114,15, + 0,0,0,114,99,0,0,0,114,107,0,0,0,114,108,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,19,0,0,0,114,15,0, + 0,0,114,99,0,0,0,114,107,0,0,0,114,108,0,0, + 0,114,109,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,20,0,0,0,116,1,0,0,115,14, + 0,0,0,0,2,9,1,9,1,9,1,9,1,21,3,9, + 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,2, + 0,0,0,4,0,0,0,67,0,0,0,115,147,0,0,0, + 100,1,0,106,0,0,124,0,0,106,1,0,131,1,0,100, + 2,0,106,0,0,124,0,0,106,2,0,131,1,0,103,2, + 0,125,1,0,124,0,0,106,3,0,100,0,0,107,9,0, + 114,76,0,124,1,0,106,4,0,100,3,0,106,0,0,124, + 0,0,106,3,0,131,1,0,131,1,0,1,124,0,0,106, + 5,0,100,0,0,107,9,0,114,116,0,124,1,0,106,4, + 0,100,4,0,106,0,0,124,0,0,106,5,0,131,1,0, + 131,1,0,1,100,5,0,106,0,0,124,0,0,106,6,0, + 106,7,0,100,6,0,106,8,0,124,1,0,131,1,0,131, + 2,0,83,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,50,0,0,0,114,15,0, + 0,0,114,99,0,0,0,114,107,0,0,0,218,6,97,112, + 112,101,110,100,114,110,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,19,0,0,0,114,29,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,114,52,0,0,0,128, + 1,0,0,115,16,0,0,0,0,1,15,1,21,1,15,1, + 25,1,15,1,12,1,13,1,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,3,0,0,0,11,0,0,0,67,0, + 0,0,115,145,0,0,0,124,0,0,106,0,0,125,2,0, + 121,107,0,124,0,0,106,1,0,124,1,0,106,1,0,107, + 2,0,111,114,0,124,0,0,106,2,0,124,1,0,106,2, + 0,107,2,0,111,114,0,124,0,0,106,3,0,124,1,0, + 106,3,0,107,2,0,111,114,0,124,2,0,124,1,0,106, + 0,0,107,2,0,111,114,0,124,0,0,106,4,0,124,1, + 0,106,4,0,107,2,0,111,114,0,124,0,0,106,5,0, + 124,1,0,106,5,0,107,2,0,83,87,110,22,0,4,116, + 6,0,107,10,0,114,140,0,1,1,1,100,1,0,83,89, + 110,1,0,88,100,0,0,83,41,2,78,70,41,7,114,110, + 0,0,0,114,15,0,0,0,114,99,0,0,0,114,107,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,96,0,0,0,41,3,114, + 19,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,138,1,0,0,115,20,0,0, + 0,0,1,9,1,3,1,18,1,18,1,18,1,15,1,18, + 1,20,1,13,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,1,0,0,0,2,0,0,0,67,0,0,0,115,85,0, + 0,0,124,0,0,106,0,0,100,0,0,107,8,0,114,78, + 0,124,0,0,106,1,0,100,0,0,107,9,0,114,78,0, + 124,0,0,106,2,0,114,78,0,116,3,0,100,0,0,107, + 8,0,114,57,0,116,4,0,130,1,0,116,3,0,106,5, + 0,124,0,0,106,1,0,131,1,0,124,0,0,95,0,0, + 124,0,0,106,0,0,83,41,1,78,41,6,114,112,0,0, + 0,114,107,0,0,0,114,111,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,41,1,114,19,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,116,0,0,0,150,1,0, + 0,115,12,0,0,0,0,2,15,1,24,1,12,1,6,1, + 21,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,2,0, + 0,0,2,0,0,0,67,0,0,0,115,13,0,0,0,124, + 1,0,124,0,0,95,0,0,100,0,0,83,41,1,78,41, + 1,114,112,0,0,0,41,2,114,19,0,0,0,114,116,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,116,0,0,0,159,1,0,0,115,2,0,0,0,0, + 2,99,1,0,0,0,0,0,0,0,1,0,0,0,2,0, + 0,0,67,0,0,0,115,46,0,0,0,124,0,0,106,0, + 0,100,1,0,107,8,0,114,35,0,124,0,0,106,1,0, + 106,2,0,100,2,0,131,1,0,100,3,0,25,83,124,0, + 0,106,1,0,83,100,1,0,83,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,33,0,0,0,41,3,114,110,0,0,0,114,15,0, + 0,0,218,10,114,112,97,114,116,105,116,105,111,110,41,1, + 114,19,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,163,1,0,0, + 115,6,0,0,0,0,3,15,1,20,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,1,0,0,0,1,0,0,0,67, + 0,0,0,115,7,0,0,0,124,0,0,106,0,0,83,41, + 1,78,41,1,114,111,0,0,0,41,1,114,19,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 117,0,0,0,171,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,2,0,0,0,2,0,0,0,67,0,0,0,115,19,0, + 0,0,116,0,0,124,1,0,131,1,0,124,0,0,95,1, + 0,100,0,0,83,41,1,78,41,2,218,4,98,111,111,108, + 114,111,0,0,0,41,2,114,19,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,117,0,0,0,175,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,20,0,0,0,114,52,0, + 0,0,114,118,0,0,0,218,8,112,114,111,112,101,114,116, + 121,114,116,0,0,0,218,6,115,101,116,116,101,114,114,123, + 0,0,0,114,117,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,114,106,0,0, + 0,79,1,0,0,115,20,0,0,0,12,35,6,2,15,1, + 15,11,12,10,12,12,18,9,21,4,18,8,18,4,114,106, + 0,0,0,114,107,0,0,0,114,109,0,0,0,99,2,0, + 0,0,2,0,0,0,6,0,0,0,15,0,0,0,67,0, + 0,0,115,217,0,0,0,116,0,0,124,1,0,100,1,0, + 131,2,0,114,110,0,116,1,0,100,2,0,107,8,0,114, + 33,0,116,2,0,130,1,0,116,1,0,106,3,0,125,4, + 0,124,3,0,100,2,0,107,8,0,114,70,0,124,4,0, + 124,0,0,100,3,0,124,1,0,131,1,1,83,124,3,0, + 114,82,0,103,0,0,110,3,0,100,2,0,125,5,0,124, + 4,0,124,0,0,100,3,0,124,1,0,100,4,0,124,5, + 0,131,1,2,83,124,3,0,100,2,0,107,8,0,114,192, + 0,116,0,0,124,1,0,100,5,0,131,2,0,114,186,0, + 121,19,0,124,1,0,106,4,0,124,0,0,131,1,0,125, + 3,0,87,113,192,0,4,116,5,0,107,10,0,114,182,0, + 1,1,1,100,2,0,125,3,0,89,113,192,0,88,110,6, + 0,100,6,0,125,3,0,116,6,0,124,0,0,124,1,0, + 100,7,0,124,2,0,100,5,0,124,3,0,131,2,2,83, + 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,114,99,0,0,0,114,110,0, + 0,0,114,109,0,0,0,70,114,107,0,0,0,41,7,114, + 4,0,0,0,114,119,0,0,0,114,120,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,109,0,0,0,114,77,0,0, + 0,114,106,0,0,0,41,6,114,15,0,0,0,114,99,0, + 0,0,114,107,0,0,0,114,109,0,0,0,114,128,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,85,0,0,0,180,1,0, + 0,115,34,0,0,0,0,2,15,1,12,1,6,1,9,2, + 12,1,16,1,18,1,15,1,7,2,12,1,15,1,3,1, + 19,1,13,1,14,3,6,2,114,85,0,0,0,99,3,0, + 0,0,0,0,0,0,8,0,0,0,53,0,0,0,67,0, + 0,0,115,118,1,0,0,121,13,0,124,0,0,106,0,0, + 125,3,0,87,110,18,0,4,116,1,0,107,10,0,114,33, + 0,1,1,1,89,110,17,0,88,124,3,0,100,0,0,107, + 9,0,114,50,0,124,3,0,83,124,0,0,106,2,0,125, + 4,0,124,1,0,100,0,0,107,8,0,114,105,0,121,13, + 0,124,0,0,106,3,0,125,1,0,87,110,18,0,4,116, + 1,0,107,10,0,114,104,0,1,1,1,89,110,1,0,88, + 121,13,0,124,0,0,106,4,0,125,5,0,87,110,24,0, + 4,116,1,0,107,10,0,114,144,0,1,1,1,100,0,0, + 125,5,0,89,110,1,0,88,124,2,0,100,0,0,107,8, + 0,114,218,0,124,5,0,100,0,0,107,8,0,114,212,0, + 121,13,0,124,1,0,106,5,0,125,2,0,87,113,218,0, + 4,116,1,0,107,10,0,114,208,0,1,1,1,100,0,0, + 125,2,0,89,113,218,0,88,110,6,0,124,5,0,125,2, + 0,121,13,0,124,0,0,106,6,0,125,6,0,87,110,24, + 0,4,116,1,0,107,10,0,114,1,1,1,1,1,100,0, + 0,125,6,0,89,110,1,0,88,121,19,0,116,7,0,124, + 0,0,106,8,0,131,1,0,125,7,0,87,110,24,0,4, + 116,1,0,107,10,0,114,47,1,1,1,1,100,0,0,125, + 7,0,89,110,1,0,88,116,9,0,124,4,0,124,1,0, + 100,1,0,124,2,0,131,2,1,125,3,0,124,5,0,100, + 0,0,107,8,0,114,87,1,100,2,0,110,3,0,100,3, + 0,124,3,0,95,10,0,124,6,0,124,3,0,95,11,0, + 124,7,0,124,3,0,95,12,0,124,3,0,83,41,4,78, + 114,107,0,0,0,70,84,41,13,114,95,0,0,0,114,96, + 0,0,0,114,1,0,0,0,114,91,0,0,0,114,98,0, + 0,0,90,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,106,0,0,0,114,111,0,0, + 0,114,116,0,0,0,114,110,0,0,0,41,8,114,89,0, + 0,0,114,99,0,0,0,114,107,0,0,0,114,88,0,0, + 0,114,15,0,0,0,90,8,108,111,99,97,116,105,111,110, + 114,116,0,0,0,114,110,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,209,1,0,0, + 115,72,0,0,0,0,2,3,1,13,1,13,1,5,2,12, + 1,4,2,9,1,12,1,3,1,13,1,13,2,5,1,3, + 1,13,1,13,1,11,1,12,1,12,1,3,1,13,1,13, + 1,14,2,6,1,3,1,13,1,13,1,11,1,3,1,19, + 1,13,1,11,2,21,1,27,1,9,1,9,1,114,132,0, + 0,0,218,8,111,118,101,114,114,105,100,101,70,99,2,0, + 0,0,1,0,0,0,5,0,0,0,59,0,0,0,67,0, + 0,0,115,54,2,0,0,124,2,0,115,30,0,116,0,0, + 124,1,0,100,1,0,100,0,0,131,3,0,100,0,0,107, + 8,0,114,67,0,121,16,0,124,0,0,106,1,0,124,1, + 0,95,2,0,87,110,18,0,4,116,3,0,107,10,0,114, + 66,0,1,1,1,89,110,1,0,88,124,2,0,115,97,0, + 116,0,0,124,1,0,100,2,0,100,0,0,131,3,0,100, + 0,0,107,8,0,114,221,0,124,0,0,106,4,0,125,3, + 0,124,3,0,100,0,0,107,8,0,114,187,0,124,0,0, + 106,5,0,100,0,0,107,9,0,114,187,0,116,6,0,100, + 0,0,107,8,0,114,151,0,116,7,0,130,1,0,116,6, + 0,106,8,0,125,4,0,124,4,0,106,9,0,124,4,0, + 131,1,0,125,3,0,124,0,0,106,5,0,124,3,0,95, + 10,0,121,13,0,124,3,0,124,1,0,95,11,0,87,110, + 18,0,4,116,3,0,107,10,0,114,220,0,1,1,1,89, + 110,1,0,88,124,2,0,115,251,0,116,0,0,124,1,0, + 100,3,0,100,0,0,131,3,0,100,0,0,107,8,0,114, + 32,1,121,16,0,124,0,0,106,12,0,124,1,0,95,13, + 0,87,110,18,0,4,116,3,0,107,10,0,114,31,1,1, + 1,1,89,110,1,0,88,121,13,0,124,0,0,124,1,0, + 95,14,0,87,110,18,0,4,116,3,0,107,10,0,114,65, + 1,1,1,1,89,110,1,0,88,124,2,0,115,96,1,116, + 0,0,124,1,0,100,4,0,100,0,0,131,3,0,100,0, + 0,107,8,0,114,148,1,124,0,0,106,5,0,100,0,0, + 107,9,0,114,148,1,121,16,0,124,0,0,106,5,0,124, + 1,0,95,15,0,87,110,18,0,4,116,3,0,107,10,0, + 114,147,1,1,1,1,89,110,1,0,88,124,0,0,106,16, + 0,114,50,2,124,2,0,115,187,1,116,0,0,124,1,0, + 100,5,0,100,0,0,131,3,0,100,0,0,107,8,0,114, + 224,1,121,16,0,124,0,0,106,17,0,124,1,0,95,18, + 0,87,110,18,0,4,116,3,0,107,10,0,114,223,1,1, + 1,1,89,110,1,0,88,124,2,0,115,254,1,116,0,0, + 124,1,0,100,6,0,100,0,0,131,3,0,100,0,0,107, + 8,0,114,50,2,124,0,0,106,19,0,100,0,0,107,9, + 0,114,50,2,121,16,0,124,0,0,106,19,0,124,1,0, + 95,20,0,87,110,18,0,4,116,3,0,107,10,0,114,49, + 2,1,1,1,89,110,1,0,88,124,1,0,83,41,7,78, + 114,1,0,0,0,114,91,0,0,0,218,11,95,95,112,97, + 99,107,97,103,101,95,95,114,131,0,0,0,114,98,0,0, + 0,114,129,0,0,0,41,21,114,6,0,0,0,114,15,0, + 0,0,114,1,0,0,0,114,96,0,0,0,114,99,0,0, + 0,114,110,0,0,0,114,119,0,0,0,114,120,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,91,0,0,0,114,123,0,0,0,114,134,0,0, + 0,114,95,0,0,0,114,131,0,0,0,114,117,0,0,0, + 114,107,0,0,0,114,98,0,0,0,114,116,0,0,0,114, + 129,0,0,0,41,5,114,88,0,0,0,114,89,0,0,0, + 114,133,0,0,0,114,99,0,0,0,114,135,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,254,1,0,0,115,92,0,0,0,0,4,30,1,3, + 1,16,1,13,1,5,2,30,1,9,1,12,2,15,1,12, + 1,6,1,9,2,15,1,12,1,3,1,13,1,13,1,5, + 2,30,1,3,1,16,1,13,1,5,2,3,1,13,1,13, + 1,5,2,30,1,15,1,3,1,16,1,13,1,5,2,9, + 1,30,1,3,1,16,1,13,1,5,2,30,1,15,1,3, + 1,16,1,13,1,5,1,114,137,0,0,0,99,1,0,0, + 0,0,0,0,0,2,0,0,0,5,0,0,0,67,0,0, + 0,115,129,0,0,0,100,1,0,125,1,0,116,0,0,124, + 0,0,106,1,0,100,2,0,131,2,0,114,45,0,124,0, + 0,106,1,0,106,2,0,124,0,0,131,1,0,125,1,0, + 110,40,0,116,0,0,124,0,0,106,1,0,100,3,0,131, + 2,0,114,85,0,116,3,0,106,4,0,100,4,0,116,5, + 0,100,5,0,100,6,0,131,2,1,1,124,1,0,100,1, + 0,107,8,0,114,112,0,116,6,0,124,0,0,106,7,0, + 131,1,0,125,1,0,116,8,0,124,0,0,124,1,0,131, + 2,0,1,124,1,0,83,41,7,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,87,115,116,97,114,116,105,110,103,32,105,110, + 32,80,121,116,104,111,110,32,51,46,54,44,32,108,111,97, + 100,101,114,115,32,100,101,102,105,110,105,110,103,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,90,10,115,116, + 97,99,107,108,101,118,101,108,233,2,0,0,0,41,9,114, + 4,0,0,0,114,99,0,0,0,114,138,0,0,0,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,114,16,0,0,0,114,15,0,0,0,114,137,0, + 0,0,41,2,114,88,0,0,0,114,89,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,58, + 2,0,0,115,20,0,0,0,0,3,6,1,18,3,21,1, + 18,1,9,2,13,1,12,1,15,1,13,1,114,144,0,0, + 0,99,1,0,0,0,0,0,0,0,2,0,0,0,3,0, + 0,0,67,0,0,0,115,149,0,0,0,124,0,0,106,0, + 0,100,1,0,107,8,0,114,21,0,100,2,0,110,6,0, + 124,0,0,106,0,0,125,1,0,124,0,0,106,1,0,100, + 1,0,107,8,0,114,95,0,124,0,0,106,2,0,100,1, + 0,107,8,0,114,73,0,100,3,0,106,3,0,124,1,0, + 131,1,0,83,100,4,0,106,3,0,124,1,0,124,0,0, + 106,2,0,131,2,0,83,110,50,0,124,0,0,106,4,0, + 114,123,0,100,5,0,106,3,0,124,1,0,124,0,0,106, + 1,0,131,2,0,83,100,6,0,106,3,0,124,0,0,106, + 0,0,124,0,0,106,1,0,131,2,0,83,100,1,0,83, + 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,93,0,0,0, + 122,13,60,109,111,100,117,108,101,32,123,33,114,125,62,122, + 20,60,109,111,100,117,108,101,32,123,33,114,125,32,40,123, + 33,114,125,41,62,122,23,60,109,111,100,117,108,101,32,123, + 33,114,125,32,102,114,111,109,32,123,33,114,125,62,122,18, + 60,109,111,100,117,108,101,32,123,33,114,125,32,40,123,125, + 41,62,41,5,114,15,0,0,0,114,107,0,0,0,114,99, + 0,0,0,114,50,0,0,0,114,117,0,0,0,41,2,114, + 88,0,0,0,114,15,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,97,0,0,0,76,2,0, + 0,115,16,0,0,0,0,3,30,1,15,1,15,1,13,2, + 22,2,9,1,19,2,114,97,0,0,0,99,2,0,0,0, + 0,0,0,0,4,0,0,0,12,0,0,0,67,0,0,0, + 115,253,0,0,0,124,0,0,106,0,0,125,2,0,116,1, + 0,106,2,0,131,0,0,1,116,3,0,124,2,0,131,1, + 0,143,208,0,1,116,4,0,106,5,0,106,6,0,124,2, + 0,131,1,0,124,1,0,107,9,0,114,89,0,100,1,0, + 106,7,0,124,2,0,131,1,0,125,3,0,116,8,0,124, + 3,0,100,2,0,124,2,0,131,1,1,130,1,0,124,0, + 0,106,9,0,100,3,0,107,8,0,114,163,0,124,0,0, + 106,10,0,100,3,0,107,8,0,114,140,0,116,8,0,100, + 4,0,100,2,0,124,0,0,106,0,0,131,1,1,130,1, + 0,116,11,0,124,0,0,124,1,0,100,5,0,100,6,0, + 131,2,1,1,124,1,0,83,116,11,0,124,0,0,124,1, + 0,100,5,0,100,6,0,131,2,1,1,116,12,0,124,0, + 0,106,9,0,100,7,0,131,2,0,115,219,0,124,0,0, + 106,9,0,106,13,0,124,2,0,131,1,0,1,110,16,0, + 124,0,0,106,9,0,106,14,0,124,1,0,131,1,0,1, + 87,100,3,0,81,82,88,116,4,0,106,5,0,124,2,0, + 25,83,41,8,122,51,69,120,101,99,117,116,101,32,116,104, + 101,32,115,112,101,99,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,15,0,0,0,78,122, + 14,109,105,115,115,105,110,103,32,108,111,97,100,101,114,114, + 133,0,0,0,84,114,139,0,0,0,41,15,114,15,0,0, + 0,114,57,0,0,0,218,12,97,99,113,117,105,114,101,95, + 108,111,99,107,114,54,0,0,0,114,14,0,0,0,114,21, + 0,0,0,114,42,0,0,0,114,50,0,0,0,114,77,0, + 0,0,114,99,0,0,0,114,110,0,0,0,114,137,0,0, + 0,114,4,0,0,0,218,11,108,111,97,100,95,109,111,100, + 117,108,101,114,139,0,0,0,41,4,114,88,0,0,0,114, + 89,0,0,0,114,15,0,0,0,218,3,109,115,103,114,10, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,86,0, + 0,0,93,2,0,0,115,32,0,0,0,0,2,9,1,10, + 1,13,1,24,1,15,1,18,1,15,1,15,1,21,2,19, + 1,4,1,19,1,18,4,19,2,23,1,114,86,0,0,0, + 99,1,0,0,0,0,0,0,0,2,0,0,0,27,0,0, + 0,67,0,0,0,115,3,1,0,0,124,0,0,106,0,0, + 106,1,0,124,0,0,106,2,0,131,1,0,1,116,3,0, + 106,4,0,124,0,0,106,2,0,25,125,1,0,116,5,0, + 124,1,0,100,1,0,100,0,0,131,3,0,100,0,0,107, + 8,0,114,96,0,121,16,0,124,0,0,106,0,0,124,1, + 0,95,6,0,87,110,18,0,4,116,7,0,107,10,0,114, + 95,0,1,1,1,89,110,1,0,88,116,5,0,124,1,0, + 100,2,0,100,0,0,131,3,0,100,0,0,107,8,0,114, + 197,0,121,56,0,124,1,0,106,8,0,124,1,0,95,9, + 0,116,10,0,124,1,0,100,3,0,131,2,0,115,175,0, + 124,0,0,106,2,0,106,11,0,100,4,0,131,1,0,100, + 5,0,25,124,1,0,95,9,0,87,110,18,0,4,116,7, + 0,107,10,0,114,196,0,1,1,1,89,110,1,0,88,116, + 5,0,124,1,0,100,6,0,100,0,0,131,3,0,100,0, + 0,107,8,0,114,255,0,121,13,0,124,0,0,124,1,0, + 95,12,0,87,110,18,0,4,116,7,0,107,10,0,114,254, + 0,1,1,1,89,110,1,0,88,124,1,0,83,41,7,78, + 114,91,0,0,0,114,134,0,0,0,114,131,0,0,0,114, + 121,0,0,0,114,33,0,0,0,114,95,0,0,0,41,13, + 114,99,0,0,0,114,146,0,0,0,114,15,0,0,0,114, + 14,0,0,0,114,21,0,0,0,114,6,0,0,0,114,91, + 0,0,0,114,96,0,0,0,114,1,0,0,0,114,134,0, + 0,0,114,4,0,0,0,114,122,0,0,0,114,95,0,0, + 0,41,2,114,88,0,0,0,114,89,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,118,2,0,0,115,40,0,0,0, + 0,4,19,2,16,1,24,1,3,1,16,1,13,1,5,1, + 24,1,3,4,12,1,15,1,29,1,13,1,5,1,24,1, + 3,1,13,1,13,1,5,1,114,148,0,0,0,99,1,0, + 0,0,0,0,0,0,2,0,0,0,11,0,0,0,67,0, + 0,0,115,159,0,0,0,124,0,0,106,0,0,100,0,0, + 107,9,0,114,43,0,116,1,0,124,0,0,106,0,0,100, + 1,0,131,2,0,115,43,0,116,2,0,124,0,0,131,1, + 0,83,116,3,0,124,0,0,131,1,0,125,1,0,116,4, + 0,124,1,0,131,1,0,143,75,0,1,124,0,0,106,0, + 0,100,0,0,107,8,0,114,122,0,124,0,0,106,5,0, + 100,0,0,107,8,0,114,138,0,116,6,0,100,2,0,100, + 3,0,124,0,0,106,7,0,131,1,1,130,1,0,110,16, + 0,124,0,0,106,0,0,106,8,0,124,1,0,131,1,0, + 1,87,100,0,0,81,82,88,116,9,0,106,10,0,124,0, + 0,106,7,0,25,83,41,4,78,114,139,0,0,0,122,14, + 109,105,115,115,105,110,103,32,108,111,97,100,101,114,114,15, + 0,0,0,41,11,114,99,0,0,0,114,4,0,0,0,114, + 148,0,0,0,114,144,0,0,0,114,102,0,0,0,114,110, + 0,0,0,114,77,0,0,0,114,15,0,0,0,114,139,0, + 0,0,114,14,0,0,0,114,21,0,0,0,41,2,114,88, + 0,0,0,114,89,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,147,2,0,0,115,20,0,0,0, + 0,2,15,2,18,1,10,2,12,1,13,1,15,1,15,1, + 24,3,23,5,114,149,0,0,0,99,1,0,0,0,0,0, + 0,0,1,0,0,0,9,0,0,0,67,0,0,0,115,47, 0,0,0,116,0,0,106,1,0,131,0,0,1,116,2,0, - 124,0,0,106,3,0,106,4,0,131,1,0,143,15,0,1, - 124,0,0,106,5,0,131,0,0,83,87,100,1,0,81,88, - 100,1,0,83,41,2,122,207,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,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,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,32, - 32,32,32,99,108,111,98,98,101,114,101,100,46,10,10,32, - 32,32,32,32,32,32,32,78,41,6,114,106,0,0,0,114, - 2,1,0,0,114,103,0,0,0,114,177,0,0,0,114,67, - 0,0,0,114,6,1,0,0,41,1,114,71,0,0,0,114, - 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,176, - 0,0,0,190,4,0,0,115,6,0,0,0,0,9,10,1, - 19,1,122,17,95,83,112,101,99,77,101,116,104,111,100,115, - 46,108,111,97,100,78,41,16,114,57,0,0,0,114,56,0, - 0,0,114,58,0,0,0,114,59,0,0,0,114,72,0,0, - 0,218,11,99,108,97,115,115,109,101,116,104,111,100,114,246, - 0,0,0,114,205,0,0,0,114,253,0,0,0,114,255,0, - 0,0,114,1,1,0,0,114,175,0,0,0,114,4,1,0, - 0,114,5,1,0,0,114,6,1,0,0,114,176,0,0,0, - 114,4,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,114,174,0,0,0,211,3,0,0,115,24,0, - 0,0,12,3,6,2,12,3,18,16,12,16,24,80,12,23, - 12,10,12,22,12,30,12,7,12,23,114,174,0,0,0,99, - 0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, - 64,0,0,0,115,181,0,0,0,101,0,0,90,1,0,100, - 0,0,90,2,0,100,1,0,90,3,0,101,4,0,100,2, - 0,100,3,0,132,0,0,131,1,0,90,5,0,101,6,0, - 100,4,0,100,4,0,100,5,0,100,6,0,132,2,0,131, - 1,0,90,7,0,101,6,0,100,4,0,100,7,0,100,8, - 0,132,1,0,131,1,0,90,8,0,101,6,0,101,9,0, - 100,9,0,100,10,0,132,0,0,131,1,0,131,1,0,90, - 10,0,101,6,0,101,9,0,100,11,0,100,12,0,132,0, - 0,131,1,0,131,1,0,90,11,0,101,6,0,101,9,0, - 100,13,0,100,14,0,132,0,0,131,1,0,131,1,0,90, - 12,0,101,6,0,101,9,0,100,15,0,100,16,0,132,0, - 0,131,1,0,131,1,0,90,13,0,100,4,0,83,41,17, - 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,1,0,0,0, - 2,0,0,0,67,0,0,0,115,16,0,0,0,100,1,0, - 106,0,0,124,0,0,106,1,0,131,1,0,83,41,2,78, - 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,47,0,0, - 0,114,57,0,0,0,41,1,114,179,0,0,0,114,4,0, - 0,0,114,4,0,0,0,114,5,0,0,0,114,205,0,0, - 0,215,4,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,109,111, - 100,117,108,101,95,114,101,112,114,78,99,4,0,0,0,0, - 0,0,0,4,0,0,0,5,0,0,0,67,0,0,0,115, - 58,0,0,0,124,2,0,100,0,0,107,9,0,114,16,0, - 100,0,0,83,116,0,0,106,1,0,124,1,0,131,1,0, - 114,50,0,116,2,0,124,1,0,124,0,0,100,1,0,100, - 2,0,131,2,1,83,100,0,0,83,100,0,0,83,41,3, - 78,114,217,0,0,0,122,8,98,117,105,108,116,45,105,110, - 41,3,114,106,0,0,0,90,10,105,115,95,98,117,105,108, - 116,105,110,114,173,0,0,0,41,4,114,245,0,0,0,114, - 158,0,0,0,114,35,0,0,0,218,6,116,97,114,103,101, - 116,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 218,9,102,105,110,100,95,115,112,101,99,220,4,0,0,115, - 10,0,0,0,0,2,12,1,4,1,15,1,19,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,4,0,0,0,3,0,0,0,67,0,0,0,115,41, - 0,0,0,124,0,0,106,0,0,124,1,0,124,2,0,131, - 2,0,125,3,0,124,3,0,100,1,0,107,9,0,114,37, - 0,124,3,0,106,1,0,83,100,1,0,83,41,2,122,113, - 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,78,41,2,114,10,1,0,0,114,169,0,0,0,41,4, - 114,245,0,0,0,114,158,0,0,0,114,35,0,0,0,114, - 177,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,11,102,105,110,100,95,109,111,100,117,108,101, - 229,4,0,0,115,4,0,0,0,0,7,18,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,3,0,0,0,10,0,0,0,67,0,0,0,115, - 59,0,0,0,116,0,0,124,1,0,131,1,0,143,23,0, - 1,116,1,0,116,2,0,106,3,0,124,1,0,131,2,0, - 125,2,0,87,100,1,0,81,88,124,0,0,124,2,0,95, - 4,0,100,2,0,124,2,0,95,5,0,124,2,0,83,41, - 3,122,23,76,111,97,100,32,97,32,98,117,105,108,116,45, - 105,110,32,109,111,100,117,108,101,46,78,114,30,0,0,0, - 41,6,114,69,0,0,0,114,114,0,0,0,114,106,0,0, - 0,90,12,105,110,105,116,95,98,117,105,108,116,105,110,114, - 204,0,0,0,114,249,0,0,0,41,3,114,245,0,0,0, - 114,158,0,0,0,114,179,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,114,3,1,0,0,239,4, - 0,0,115,10,0,0,0,0,4,13,1,24,1,9,1,9, - 1,122,27,66,117,105,108,116,105,110,73,109,112,111,114,116, - 101,114,46,108,111,97,100,95,109,111,100,117,108,101,99,2, + 124,0,0,106,3,0,131,1,0,143,15,0,1,116,4,0, + 124,0,0,131,1,0,83,87,100,1,0,81,82,88,100,1, + 0,83,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,5,114,57,0,0,0,114,145,0, + 0,0,114,54,0,0,0,114,15,0,0,0,114,149,0,0, + 0,41,1,114,88,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,87,0,0,0,170,2,0,0, + 115,6,0,0,0,0,9,10,1,16,1,114,87,0,0,0, + 99,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0, + 0,64,0,0,0,115,205,0,0,0,101,0,0,90,1,0, + 100,0,0,90,2,0,100,1,0,90,3,0,101,4,0,100, + 2,0,100,3,0,132,0,0,131,1,0,90,5,0,101,6, + 0,100,4,0,100,4,0,100,5,0,100,6,0,132,2,0, + 131,1,0,90,7,0,101,6,0,100,4,0,100,7,0,100, + 8,0,132,1,0,131,1,0,90,8,0,101,6,0,100,9, + 0,100,10,0,132,0,0,131,1,0,90,9,0,101,6,0, + 100,11,0,100,12,0,132,0,0,131,1,0,90,10,0,101, + 6,0,101,11,0,100,13,0,100,14,0,132,0,0,131,1, + 0,131,1,0,90,12,0,101,6,0,101,11,0,100,15,0, + 100,16,0,132,0,0,131,1,0,131,1,0,90,13,0,101, + 6,0,101,11,0,100,17,0,100,18,0,132,0,0,131,1, + 0,131,1,0,90,14,0,101,6,0,101,15,0,131,1,0, + 90,16,0,100,4,0,83,41,19,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,1,0,0,0,2,0,0,0,67,0,0, + 0,115,16,0,0,0,100,1,0,106,0,0,124,0,0,106, + 1,0,131,1,0,83,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,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,50,0,0,0,114,1, + 0,0,0,41,1,114,89,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,92,0,0,0,195,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, + 4,0,0,0,5,0,0,0,67,0,0,0,115,58,0,0, + 0,124,2,0,100,0,0,107,9,0,114,16,0,100,0,0, + 83,116,0,0,106,1,0,124,1,0,131,1,0,114,50,0, + 116,2,0,124,1,0,124,0,0,100,1,0,100,2,0,131, + 2,1,83,100,0,0,83,100,0,0,83,41,3,78,114,107, + 0,0,0,122,8,98,117,105,108,116,45,105,110,41,3,114, + 57,0,0,0,90,10,105,115,95,98,117,105,108,116,105,110, + 114,85,0,0,0,41,4,218,3,99,108,115,114,78,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,204,2,0,0,115,10,0, + 0,0,0,2,12,1,4,1,15,1,19,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, + 4,0,0,0,3,0,0,0,67,0,0,0,115,41,0,0, + 0,124,0,0,106,0,0,124,1,0,124,2,0,131,2,0, + 125,3,0,124,3,0,100,1,0,107,9,0,114,37,0,124, + 3,0,106,1,0,83,100,1,0,83,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,154,0,0,0,114,99,0,0,0,41,4,114,151,0,0, + 0,114,78,0,0,0,114,152,0,0,0,114,88,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,213,2,0,0, + 115,4,0,0,0,0,9,18,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,2, + 0,0,0,4,0,0,0,67,0,0,0,115,67,0,0,0, + 124,1,0,106,0,0,116,1,0,106,2,0,107,7,0,114, + 51,0,116,3,0,100,1,0,106,4,0,124,1,0,106,0, + 0,131,1,0,100,2,0,124,1,0,106,0,0,131,1,1, + 130,1,0,116,5,0,116,6,0,106,7,0,124,1,0,131, + 2,0,83,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,122, + 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,15, + 0,0,0,41,8,114,15,0,0,0,114,14,0,0,0,114, + 76,0,0,0,114,77,0,0,0,114,50,0,0,0,114,65, + 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,19,0,0,0,114, + 88,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,114,138,0,0,0,225,2,0,0,115,8,0,0, + 0,0,3,18,1,21,1,12,1,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,2,0,0,0,3,0,0,0,67,0,0,0,115,20,0, + 0,0,116,0,0,116,1,0,106,2,0,124,1,0,131,2, + 0,1,100,1,0,83,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,65,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,19,0, + 0,0,114,89,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,11,0,0,0,114,139,0,0,0,233,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,2,0,0,0, + 1,0,0,0,67,0,0,0,115,4,0,0,0,100,1,0, + 83,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,41,2,114,151,0,0,0,114,78,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,238,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,2,0,0,0,1,0,0,0,67, - 0,0,0,115,4,0,0,0,100,1,0,83,41,2,122,57, + 0,0,0,115,4,0,0,0,100,1,0,83,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,99,111,100,101, - 32,111,98,106,101,99,116,115,46,78,114,4,0,0,0,41, - 2,114,245,0,0,0,114,158,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,218,8,103,101,116,95, - 99,111,100,101,249,4,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,2,0,0,0,1,0,0,0,67,0,0,0,115,4, - 0,0,0,100,1,0,83,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,4,0,0,0,41,2,114,245,0,0,0, - 114,158,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,218,10,103,101,116,95,115,111,117,114,99,101, - 255,4,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, - 2,0,0,0,1,0,0,0,67,0,0,0,115,4,0,0, - 0,100,1,0,83,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,4, - 0,0,0,41,2,114,245,0,0,0,114,158,0,0,0,114, - 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,219, - 0,0,0,5,5,0,0,115,2,0,0,0,0,5,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,14,114,57,0,0, - 0,114,56,0,0,0,114,58,0,0,0,114,59,0,0,0, - 218,12,115,116,97,116,105,99,109,101,116,104,111,100,114,205, - 0,0,0,114,7,1,0,0,114,10,1,0,0,114,11,1, - 0,0,114,161,0,0,0,114,3,1,0,0,114,12,1,0, - 0,114,13,1,0,0,114,219,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, - 8,1,0,0,206,4,0,0,115,28,0,0,0,12,7,6, - 2,18,5,3,1,21,8,3,1,18,9,3,1,21,9,3, - 1,21,5,3,1,21,5,3,1,114,8,1,0,0,99,0, - 0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,64, - 0,0,0,115,193,0,0,0,101,0,0,90,1,0,100,0, - 0,90,2,0,100,1,0,90,3,0,101,4,0,100,2,0, - 100,3,0,132,0,0,131,1,0,90,5,0,101,6,0,100, - 4,0,100,4,0,100,5,0,100,6,0,132,2,0,131,1, - 0,90,7,0,101,6,0,100,4,0,100,7,0,100,8,0, - 132,1,0,131,1,0,90,8,0,101,4,0,100,9,0,100, - 10,0,132,0,0,131,1,0,90,9,0,101,6,0,100,11, - 0,100,12,0,132,0,0,131,1,0,90,10,0,101,6,0, - 101,11,0,100,13,0,100,14,0,132,0,0,131,1,0,131, - 1,0,90,12,0,101,6,0,101,11,0,100,15,0,100,16, - 0,132,0,0,131,1,0,131,1,0,90,13,0,101,6,0, - 101,11,0,100,17,0,100,18,0,132,0,0,131,1,0,131, - 1,0,90,14,0,100,4,0,83,41,19,218,14,70,114,111, + 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,41,2, + 114,151,0,0,0,114,78,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,244,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,2,0,0,0,1,0,0,0,67,0,0, + 0,115,4,0,0,0,100,1,0,83,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,41,2,114,151,0,0,0,114, + 78,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,114,109,0,0,0,250,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,105,115,95,112,97,99,107,97,103,101,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,92,0,0,0,218,11,99,108,97,115,115,109, + 101,116,104,111,100,114,154,0,0,0,114,155,0,0,0,114, + 138,0,0,0,114,139,0,0,0,114,81,0,0,0,114,156, + 0,0,0,114,157,0,0,0,114,109,0,0,0,114,90,0, + 0,0,114,146,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,150,0,0,0, + 186,2,0,0,115,30,0,0,0,12,7,6,2,18,9,3, + 1,21,8,3,1,18,11,18,8,18,5,3,1,21,5,3, + 1,21,5,3,1,21,5,114,150,0,0,0,99,0,0,0, + 0,0,0,0,0,0,0,0,0,5,0,0,0,64,0,0, + 0,115,211,0,0,0,101,0,0,90,1,0,100,0,0,90, + 2,0,100,1,0,90,3,0,101,4,0,100,2,0,100,3, + 0,132,0,0,131,1,0,90,5,0,101,6,0,100,4,0, + 100,4,0,100,5,0,100,6,0,132,2,0,131,1,0,90, + 7,0,101,6,0,100,4,0,100,7,0,100,8,0,132,1, + 0,131,1,0,90,8,0,101,6,0,100,9,0,100,10,0, + 132,0,0,131,1,0,90,9,0,101,4,0,100,11,0,100, + 12,0,132,0,0,131,1,0,90,10,0,101,6,0,100,13, + 0,100,14,0,132,0,0,131,1,0,90,11,0,101,6,0, + 101,12,0,100,15,0,100,16,0,132,0,0,131,1,0,131, + 1,0,90,13,0,101,6,0,101,12,0,100,17,0,100,18, + 0,132,0,0,131,1,0,131,1,0,90,14,0,101,6,0, + 101,12,0,100,19,0,100,20,0,132,0,0,131,1,0,131, + 1,0,90,15,0,100,4,0,83,41,21,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, @@ -2181,1623 +1379,254 @@ const unsigned char _Py_M__importlib[] = { 108,97,115,115,46,10,10,32,32,32,32,99,1,0,0,0, 0,0,0,0,1,0,0,0,2,0,0,0,67,0,0,0, 115,16,0,0,0,100,1,0,106,0,0,124,0,0,106,1, - 0,131,1,0,83,41,2,78,122,22,60,109,111,100,117,108, - 101,32,123,33,114,125,32,40,102,114,111,122,101,110,41,62, - 41,2,114,47,0,0,0,114,57,0,0,0,41,1,218,1, - 109,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,205,0,0,0,22,5,0,0,115,2,0,0,0,0,3, - 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,4,0,0,0,5,0,0,0,67,0, - 0,0,115,42,0,0,0,116,0,0,106,1,0,124,1,0, - 131,1,0,114,34,0,116,2,0,124,1,0,124,0,0,100, - 1,0,100,2,0,131,2,1,83,100,0,0,83,100,0,0, - 83,41,3,78,114,217,0,0,0,90,6,102,114,111,122,101, - 110,41,3,114,106,0,0,0,114,162,0,0,0,114,173,0, - 0,0,41,4,114,245,0,0,0,114,158,0,0,0,114,35, - 0,0,0,114,9,1,0,0,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,114,10,1,0,0,27,5,0,0, - 115,6,0,0,0,0,2,15,1,19,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,3,0, - 0,0,2,0,0,0,67,0,0,0,115,23,0,0,0,116, - 0,0,106,1,0,124,1,0,131,1,0,114,19,0,124,0, - 0,83,100,1,0,83,41,2,122,21,70,105,110,100,32,97, - 32,102,114,111,122,101,110,32,109,111,100,117,108,101,46,78, - 41,2,114,106,0,0,0,114,162,0,0,0,41,3,114,245, - 0,0,0,114,158,0,0,0,114,35,0,0,0,114,4,0, - 0,0,114,4,0,0,0,114,5,0,0,0,114,11,1,0, - 0,34,5,0,0,115,2,0,0,0,0,3,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,1,0,0,0,0,0,0, - 0,3,0,0,0,4,0,0,0,67,0,0,0,115,95,0, - 0,0,124,0,0,106,0,0,106,1,0,125,1,0,116,2, - 0,106,3,0,124,1,0,131,1,0,115,57,0,116,4,0, - 100,1,0,106,5,0,124,1,0,131,1,0,100,2,0,124, - 1,0,131,1,1,130,1,0,110,0,0,116,6,0,116,2, - 0,106,7,0,124,1,0,131,2,0,125,2,0,116,8,0, - 124,2,0,124,0,0,106,9,0,131,2,0,1,100,0,0, - 83,41,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,67,0,0,0,41,10,114,208,0,0,0,114,67,0, - 0,0,114,106,0,0,0,114,162,0,0,0,114,153,0,0, - 0,114,47,0,0,0,114,114,0,0,0,218,17,103,101,116, - 95,102,114,111,122,101,110,95,111,98,106,101,99,116,114,175, - 0,0,0,114,63,0,0,0,41,3,114,179,0,0,0,114, - 67,0,0,0,114,194,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,0,1,0,0,39,5,0, - 0,115,12,0,0,0,0,2,12,1,15,1,18,1,12,1, - 18,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,2,0,0,0,3,0,0,0,67, - 0,0,0,115,13,0,0,0,116,0,0,124,0,0,124,1, - 0,131,2,0,83,41,1,122,21,76,111,97,100,32,97,32, - 102,114,111,122,101,110,32,109,111,100,117,108,101,46,41,1, - 114,180,0,0,0,41,2,114,245,0,0,0,114,158,0,0, - 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,3,1,0,0,48,5,0,0,115,2,0,0,0,0,3, - 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,2,0,0,0,2,0,0,0,67,0,0, - 0,115,13,0,0,0,116,0,0,106,1,0,124,1,0,131, - 1,0,83,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,106,0,0,0,114,17,1,0,0, - 41,2,114,245,0,0,0,114,158,0,0,0,114,4,0,0, - 0,114,4,0,0,0,114,5,0,0,0,114,12,1,0,0, - 53,5,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,2,0,0, + 0,131,1,0,83,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,22,60,109, + 111,100,117,108,101,32,123,33,114,125,32,40,102,114,111,122, + 101,110,41,62,41,2,114,50,0,0,0,114,1,0,0,0, + 41,1,218,1,109,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,114,92,0,0,0,12,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,4,0,0,0,5,0, + 0,0,67,0,0,0,115,42,0,0,0,116,0,0,106,1, + 0,124,1,0,131,1,0,114,34,0,116,2,0,124,1,0, + 124,0,0,100,1,0,100,2,0,131,2,1,83,100,0,0, + 83,100,0,0,83,41,3,78,114,107,0,0,0,90,6,102, + 114,111,122,101,110,41,3,114,57,0,0,0,114,82,0,0, + 0,114,85,0,0,0,41,4,114,151,0,0,0,114,78,0, + 0,0,114,152,0,0,0,114,153,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,154,0,0,0, + 21,3,0,0,115,6,0,0,0,0,2,15,1,19,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,3,0,0,0,2,0,0,0,67,0,0,0,115,23, + 0,0,0,116,0,0,106,1,0,124,1,0,131,1,0,114, + 19,0,124,0,0,83,100,1,0,83,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,82,0,0,0,41,3,114,151,0,0,0,114, + 78,0,0,0,114,152,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,155,0,0,0,28,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,2,0,0, 0,1,0,0,0,67,0,0,0,115,4,0,0,0,100,1, - 0,83,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,4,0, - 0,0,41,2,114,245,0,0,0,114,158,0,0,0,114,4, - 0,0,0,114,4,0,0,0,114,5,0,0,0,114,13,1, - 0,0,59,5,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,2,0,0,0,2,0,0,0,67,0,0,0,115,13,0, - 0,0,116,0,0,106,1,0,124,1,0,131,1,0,83,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,106,0,0,0,90,17,105,115,95,102,114,111, - 122,101,110,95,112,97,99,107,97,103,101,41,2,114,245,0, - 0,0,114,158,0,0,0,114,4,0,0,0,114,4,0,0, - 0,114,5,0,0,0,114,219,0,0,0,65,5,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,15,114,57,0,0,0,114,56,0,0,0,114,58,0, - 0,0,114,59,0,0,0,114,14,1,0,0,114,205,0,0, - 0,114,7,1,0,0,114,10,1,0,0,114,11,1,0,0, - 114,0,1,0,0,114,3,1,0,0,114,164,0,0,0,114, - 12,1,0,0,114,13,1,0,0,114,219,0,0,0,114,4, - 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, - 0,0,114,15,1,0,0,13,5,0,0,115,28,0,0,0, - 12,7,6,2,18,5,3,1,21,6,3,1,18,4,18,9, - 18,5,3,1,21,5,3,1,21,5,3,1,114,15,1,0, - 0,99,0,0,0,0,0,0,0,0,0,0,0,0,5,0, - 0,0,64,0,0,0,115,121,0,0,0,101,0,0,90,1, - 0,100,0,0,90,2,0,100,1,0,90,3,0,100,2,0, - 90,4,0,100,3,0,90,5,0,100,4,0,90,6,0,101, - 7,0,100,5,0,100,6,0,132,0,0,131,1,0,90,8, - 0,101,7,0,100,7,0,100,8,0,132,0,0,131,1,0, - 90,9,0,101,7,0,100,9,0,100,9,0,100,10,0,100, - 11,0,132,2,0,131,1,0,90,10,0,101,7,0,100,9, - 0,100,12,0,100,13,0,132,1,0,131,1,0,90,11,0, - 100,9,0,83,41,14,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,2,0,0,0,11,0,0,0,67, - 0,0,0,115,67,0,0,0,121,23,0,116,0,0,106,1, - 0,116,0,0,106,2,0,124,1,0,131,2,0,83,87,110, - 37,0,4,116,3,0,107,10,0,114,62,0,1,1,1,116, - 0,0,106,1,0,116,0,0,106,4,0,124,1,0,131,2, - 0,83,89,110,1,0,88,100,0,0,83,41,1,78,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,40,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, - 114,245,0,0,0,218,3,107,101,121,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,218,14,95,111,112,101,110, - 95,114,101,103,105,115,116,114,121,84,5,0,0,115,8,0, - 0,0,0,2,3,1,23,1,13,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,6,0,0,0,16,0,0, - 0,67,0,0,0,115,142,0,0,0,124,0,0,106,0,0, - 114,21,0,124,0,0,106,1,0,125,2,0,110,9,0,124, - 0,0,106,2,0,125,2,0,124,2,0,106,3,0,100,1, - 0,124,1,0,100,2,0,116,4,0,106,5,0,100,0,0, - 100,3,0,133,2,0,25,131,0,2,125,3,0,121,46,0, - 124,0,0,106,6,0,124,3,0,131,1,0,143,25,0,125, - 4,0,116,7,0,106,8,0,124,4,0,100,4,0,131,2, - 0,125,5,0,87,100,0,0,81,88,87,110,22,0,4,116, - 9,0,107,10,0,114,137,0,1,1,1,100,0,0,83,89, - 110,1,0,88,124,5,0,83,41,5,78,114,158,0,0,0, - 90,11,115,121,115,95,118,101,114,115,105,111,110,114,136,0, - 0,0,114,30,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,47,0,0,0,114,7,0, - 0,0,218,7,118,101,114,115,105,111,110,114,21,1,0,0, - 114,19,1,0,0,90,10,81,117,101,114,121,86,97,108,117, - 101,114,40,0,0,0,41,6,114,245,0,0,0,114,158,0, - 0,0,90,12,114,101,103,105,115,116,114,121,95,107,101,121, - 114,20,1,0,0,90,4,104,107,101,121,218,8,102,105,108, - 101,112,97,116,104,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,218,16,95,115,101,97,114,99,104,95,114,101, - 103,105,115,116,114,121,91,5,0,0,115,22,0,0,0,0, - 2,9,1,12,2,9,1,15,1,22,1,3,1,18,1,28, - 1,13,1,9,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,8,0,0,0,14,0,0,0,67, - 0,0,0,115,155,0,0,0,124,0,0,106,0,0,124,1, - 0,131,1,0,125,4,0,124,4,0,100,0,0,107,8,0, - 114,31,0,100,0,0,83,121,14,0,116,1,0,124,4,0, - 131,1,0,1,87,110,22,0,4,116,2,0,107,10,0,114, - 69,0,1,1,1,100,0,0,83,89,110,1,0,88,120,78, - 0,116,3,0,131,0,0,68,93,67,0,92,2,0,125,5, - 0,125,6,0,124,4,0,106,4,0,116,5,0,124,6,0, - 131,1,0,131,1,0,114,80,0,116,6,0,124,1,0,124, - 5,0,124,1,0,124,4,0,131,2,0,100,1,0,124,4, - 0,131,2,1,125,7,0,124,7,0,83,113,80,0,87,100, - 0,0,83,41,2,78,114,217,0,0,0,41,7,114,27,1, - 0,0,114,39,0,0,0,114,40,0,0,0,114,236,0,0, - 0,114,228,0,0,0,114,229,0,0,0,114,173,0,0,0, - 41,8,114,245,0,0,0,114,158,0,0,0,114,35,0,0, - 0,114,9,1,0,0,114,26,1,0,0,114,169,0,0,0, - 114,127,0,0,0,114,177,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,114,10,1,0,0,106,5, - 0,0,115,24,0,0,0,0,3,15,1,12,1,4,1,3, - 1,14,1,13,1,9,1,22,1,21,1,21,1,9,1,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,4,0,0,0,3,0,0, - 0,67,0,0,0,115,45,0,0,0,116,0,0,106,1,0, - 124,1,0,124,2,0,131,2,0,125,3,0,124,3,0,100, - 1,0,107,9,0,114,37,0,124,3,0,106,2,0,83,100, - 1,0,83,100,1,0,83,41,2,122,34,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,78,41,3, - 114,71,0,0,0,114,10,1,0,0,114,169,0,0,0,41, - 4,114,245,0,0,0,114,158,0,0,0,114,35,0,0,0, - 114,177,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,114,11,1,0,0,122,5,0,0,115,8,0, - 0,0,0,3,18,1,12,1,7,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,12,114, - 57,0,0,0,114,56,0,0,0,114,58,0,0,0,114,59, - 0,0,0,114,24,1,0,0,114,23,1,0,0,114,22,1, - 0,0,114,7,1,0,0,114,21,1,0,0,114,27,1,0, - 0,114,10,1,0,0,114,11,1,0,0,114,4,0,0,0, - 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, - 18,1,0,0,72,5,0,0,115,20,0,0,0,12,2,6, - 3,6,3,6,2,6,2,18,7,18,15,3,1,21,15,3, - 1,114,18,1,0,0,99,0,0,0,0,0,0,0,0,0, - 0,0,0,2,0,0,0,64,0,0,0,115,52,0,0,0, + 0,83,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,151,0,0,0,114,88,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,138,0,0,0,37,3,0,0,115,0,0,0,0,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,3,0,0,0,4,0,0,0,67,0, + 0,0,115,92,0,0,0,124,0,0,106,0,0,106,1,0, + 125,1,0,116,2,0,106,3,0,124,1,0,131,1,0,115, + 54,0,116,4,0,100,1,0,106,5,0,124,1,0,131,1, + 0,100,2,0,124,1,0,131,1,1,130,1,0,116,6,0, + 116,2,0,106,7,0,124,1,0,131,2,0,125,2,0,116, + 8,0,124,2,0,124,0,0,106,9,0,131,2,0,1,100, + 0,0,83,41,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,15,0,0,0,41,10,114,95,0,0,0,114, + 15,0,0,0,114,57,0,0,0,114,82,0,0,0,114,77, + 0,0,0,114,50,0,0,0,114,65,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,89,0, + 0,0,114,15,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,139,0,0, + 0,41,3,0,0,115,12,0,0,0,0,2,12,1,15,1, + 18,1,9,1,18,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,2,0,0,0,3, + 0,0,0,67,0,0,0,115,13,0,0,0,116,0,0,124, + 0,0,124,1,0,131,2,0,83,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,90, + 0,0,0,41,2,114,151,0,0,0,114,78,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,146, + 0,0,0,50,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,2,0,0,0,2,0,0,0,67,0,0,0,115, + 13,0,0,0,116,0,0,106,1,0,124,1,0,131,1,0, + 83,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,162,0,0,0,41,2, + 114,151,0,0,0,114,78,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,156,0,0,0,59,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,2,0,0,0,1, + 0,0,0,67,0,0,0,115,4,0,0,0,100,1,0,83, + 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, + 41,2,114,151,0,0,0,114,78,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,157,0,0,0, + 65,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,2, + 0,0,0,2,0,0,0,67,0,0,0,115,13,0,0,0, + 116,0,0,106,1,0,124,1,0,131,1,0,83,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,41,2,114,151,0,0,0, + 114,78,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,114,109,0,0,0,71,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, + 16,114,1,0,0,0,114,0,0,0,0,114,2,0,0,0, + 114,3,0,0,0,114,158,0,0,0,114,92,0,0,0,114, + 159,0,0,0,114,154,0,0,0,114,155,0,0,0,114,138, + 0,0,0,114,139,0,0,0,114,146,0,0,0,114,84,0, + 0,0,114,156,0,0,0,114,157,0,0,0,114,109,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,3,3,0,0,115,30, + 0,0,0,12,7,6,2,18,9,3,1,21,6,3,1,18, + 8,18,4,18,9,18,9,3,1,21,5,3,1,21,5,3, + 1,114,160,0,0,0,99,0,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,64,0,0,0,115,46,0,0,0, 101,0,0,90,1,0,100,0,0,90,2,0,100,1,0,90, 3,0,100,2,0,100,3,0,132,0,0,90,4,0,100,4, - 0,100,5,0,132,0,0,90,5,0,101,6,0,90,7,0, - 100,6,0,83,41,7,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,5,0,0,0,3,0,0,0,67,0,0,0,115, - 88,0,0,0,116,0,0,124,0,0,106,1,0,124,1,0, - 131,1,0,131,1,0,100,1,0,25,125,2,0,124,2,0, - 106,2,0,100,2,0,100,1,0,131,2,0,100,3,0,25, - 125,3,0,124,1,0,106,3,0,100,2,0,131,1,0,100, - 4,0,25,125,4,0,124,3,0,100,5,0,107,2,0,111, - 87,0,124,4,0,100,5,0,107,3,0,83,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,29,0, - 0,0,114,116,0,0,0,114,84,0,0,0,114,115,0,0, - 0,114,72,0,0,0,41,4,114,38,0,0,0,114,234,0, - 0,0,114,34,0,0,0,114,32,0,0,0,41,5,114,71, - 0,0,0,114,158,0,0,0,114,131,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,4,0,0,0,114,4,0,0, - 0,114,5,0,0,0,114,219,0,0,0,138,5,0,0,115, - 8,0,0,0,0,3,25,1,22,1,19,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,3, - 0,0,0,4,0,0,0,67,0,0,0,115,80,0,0,0, - 124,0,0,106,0,0,124,1,0,106,1,0,131,1,0,125, - 2,0,124,2,0,100,1,0,107,8,0,114,57,0,116,2, - 0,100,2,0,106,3,0,124,1,0,106,1,0,131,1,0, - 131,1,0,130,1,0,110,0,0,116,4,0,116,5,0,124, - 2,0,124,1,0,106,6,0,131,3,0,1,100,1,0,83, - 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,7, - 114,12,1,0,0,114,57,0,0,0,114,153,0,0,0,114, - 47,0,0,0,114,114,0,0,0,114,175,0,0,0,114,63, - 0,0,0,41,3,114,71,0,0,0,114,179,0,0,0,114, - 194,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,0,1,0,0,146,5,0,0,115,10,0,0, - 0,0,2,18,1,12,1,3,1,24,1,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,78,41,8,114,57,0,0,0,114,56, - 0,0,0,114,58,0,0,0,114,59,0,0,0,114,219,0, - 0,0,114,0,1,0,0,114,180,0,0,0,114,3,1,0, - 0,114,4,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,28,1,0,0,132,5,0,0,115,8, - 0,0,0,12,3,6,3,12,8,12,8,114,28,1,0,0, - 99,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0, - 0,64,0,0,0,115,106,0,0,0,101,0,0,90,1,0, - 100,0,0,90,2,0,100,1,0,100,2,0,132,0,0,90, - 3,0,100,3,0,100,4,0,132,0,0,90,4,0,100,5, - 0,100,6,0,132,0,0,90,5,0,100,7,0,100,8,0, - 132,0,0,90,6,0,100,9,0,100,10,0,132,0,0,90, - 7,0,100,11,0,100,18,0,100,13,0,100,14,0,132,0, - 1,90,8,0,100,15,0,100,16,0,132,0,0,90,9,0, - 100,17,0,83,41,19,218,12,83,111,117,114,99,101,76,111, - 97,100,101,114,99,2,0,0,0,0,0,0,0,2,0,0, - 0,1,0,0,0,67,0,0,0,115,10,0,0,0,116,0, - 0,130,1,0,100,1,0,83,41,2,122,178,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,44,32,119,104,101,114,101,32,112,97, - 116,104,32,105,115,32,97,32,115,116,114,46,10,10,32,32, - 32,32,32,32,32,32,82,97,105,115,101,115,32,73,79,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,218,7,73,79,69,114,114,111,114,41,2,114,71,0,0, - 0,114,35,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,218,10,112,97,116,104,95,109,116,105,109, - 101,159,5,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,2,0, - 0,0,3,0,0,0,67,0,0,0,115,20,0,0,0,105, - 1,0,124,0,0,106,0,0,124,1,0,131,1,0,100,1, - 0,54,83,41,2,97,170,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,32,112,97,116,104,10,32,32,32,32,32, - 32,32,32,116,111,32,98,121,32,116,104,101,32,112,97,116, - 104,32,40,115,116,114,41,46,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,73,79,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,183,0,0,0,41,1,114,31,1,0,0, - 41,2,114,71,0,0,0,114,35,0,0,0,114,4,0,0, - 0,114,4,0,0,0,114,5,0,0,0,218,10,112,97,116, - 104,95,115,116,97,116,115,167,5,0,0,115,2,0,0,0, - 0,11,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,4,0,0,0,3,0,0,0,67,0,0,0, - 115,16,0,0,0,124,0,0,106,0,0,124,2,0,124,3, - 0,131,2,0,83,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,71,0,0,0, - 114,141,0,0,0,90,10,99,97,99,104,101,95,112,97,116, - 104,114,53,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,218,15,95,99,97,99,104,101,95,98,121, - 116,101,99,111,100,101,180,5,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,3,0,0,0,1,0,0,0, - 67,0,0,0,115,4,0,0,0,100,1,0,83,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,4,0,0,0,41,3,114, - 71,0,0,0,114,35,0,0,0,114,53,0,0,0,114,4, - 0,0,0,114,4,0,0,0,114,5,0,0,0,114,33,1, - 0,0,190,5,0,0,115,0,0,0,0,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,5,0,0,0,16, - 0,0,0,67,0,0,0,115,105,0,0,0,124,0,0,106, - 0,0,124,1,0,131,1,0,125,2,0,121,19,0,124,0, - 0,106,1,0,124,2,0,131,1,0,125,3,0,87,110,58, - 0,4,116,2,0,107,10,0,114,94,0,1,125,4,0,1, - 122,26,0,116,3,0,100,1,0,100,2,0,124,1,0,131, - 1,1,124,4,0,130,2,0,87,89,100,3,0,100,3,0, - 125,4,0,126,4,0,88,110,1,0,88,116,4,0,124,3, - 0,131,1,0,83,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,67,0,0,0,78,41,5,114,234, - 0,0,0,218,8,103,101,116,95,100,97,116,97,114,40,0, - 0,0,114,153,0,0,0,114,203,0,0,0,41,5,114,71, - 0,0,0,114,158,0,0,0,114,35,0,0,0,114,201,0, - 0,0,218,3,101,120,99,114,4,0,0,0,114,4,0,0, - 0,114,5,0,0,0,114,13,1,0,0,197,5,0,0,115, - 14,0,0,0,0,2,15,1,3,1,19,1,18,1,9,1, - 31,1,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,218,9,95,111,112, - 116,105,109,105,122,101,114,29,0,0,0,99,3,0,0,0, - 1,0,0,0,4,0,0,0,9,0,0,0,67,0,0,0, - 115,31,0,0,0,116,0,0,116,1,0,124,1,0,124,2, - 0,100,1,0,100,2,0,100,3,0,100,4,0,124,3,0, - 131,4,2,83,41,5,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,175,0,0,0,218, - 12,100,111,110,116,95,105,110,104,101,114,105,116,84,114,118, - 0,0,0,41,2,114,114,0,0,0,218,7,99,111,109,112, - 105,108,101,41,4,114,71,0,0,0,114,53,0,0,0,114, - 35,0,0,0,114,37,1,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,218,14,115,111,117,114,99,101, - 95,116,111,95,99,111,100,101,207,5,0,0,115,4,0,0, - 0,0,5,18,1,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,10,0,0,0,45, - 0,0,0,67,0,0,0,115,177,1,0,0,124,0,0,106, - 0,0,124,1,0,131,1,0,125,2,0,100,1,0,125,3, - 0,121,16,0,116,1,0,124,2,0,131,1,0,125,4,0, - 87,110,24,0,4,116,2,0,107,10,0,114,63,0,1,1, - 1,100,1,0,125,4,0,89,110,202,0,88,121,19,0,124, - 0,0,106,3,0,124,2,0,131,1,0,125,5,0,87,110, - 18,0,4,116,4,0,107,10,0,114,103,0,1,1,1,89, - 110,162,0,88,116,5,0,124,5,0,100,2,0,25,131,1, - 0,125,3,0,121,19,0,124,0,0,106,6,0,124,4,0, - 131,1,0,125,6,0,87,110,18,0,4,116,7,0,107,10, - 0,114,159,0,1,1,1,89,110,106,0,88,121,34,0,116, - 8,0,124,6,0,100,3,0,124,5,0,100,4,0,124,1, - 0,100,5,0,124,4,0,131,1,3,125,7,0,87,110,24, - 0,4,116,9,0,116,10,0,102,2,0,107,10,0,114,220, - 0,1,1,1,89,110,45,0,88,116,11,0,100,6,0,124, - 4,0,124,2,0,131,3,0,1,116,12,0,124,7,0,100, - 4,0,124,1,0,100,7,0,124,4,0,100,8,0,124,2, - 0,131,1,3,83,124,0,0,106,6,0,124,2,0,131,1, - 0,125,8,0,124,0,0,106,13,0,124,8,0,124,2,0, - 131,2,0,125,9,0,116,11,0,100,9,0,124,2,0,131, - 2,0,1,116,14,0,106,15,0,12,114,173,1,124,4,0, - 100,1,0,107,9,0,114,173,1,124,3,0,100,1,0,107, - 9,0,114,173,1,116,16,0,124,9,0,124,3,0,116,17, - 0,124,8,0,131,1,0,131,3,0,125,6,0,121,36,0, - 124,0,0,106,18,0,124,2,0,124,4,0,124,6,0,131, - 3,0,1,116,11,0,100,10,0,124,4,0,131,2,0,1, - 87,113,173,1,4,116,2,0,107,10,0,114,169,1,1,1, - 1,89,113,173,1,88,110,0,0,124,9,0,83,41,11,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, - 114,183,0,0,0,114,187,0,0,0,114,67,0,0,0,114, - 35,0,0,0,122,13,123,125,32,109,97,116,99,104,101,115, - 32,123,125,114,140,0,0,0,114,141,0,0,0,122,19,99, - 111,100,101,32,111,98,106,101,99,116,32,102,114,111,109,32, - 123,125,122,10,119,114,111,116,101,32,123,33,114,125,41,19, - 114,234,0,0,0,114,132,0,0,0,114,124,0,0,0,114, - 32,1,0,0,114,30,1,0,0,114,14,0,0,0,114,35, - 1,0,0,114,40,0,0,0,114,190,0,0,0,114,153,0, - 0,0,114,186,0,0,0,114,152,0,0,0,114,195,0,0, - 0,114,40,1,0,0,114,7,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,198,0,0,0,114,31,0,0,0,114,34,1,0,0,41, - 10,114,71,0,0,0,114,158,0,0,0,114,141,0,0,0, - 114,188,0,0,0,114,140,0,0,0,218,2,115,116,114,53, - 0,0,0,218,10,98,121,116,101,115,95,100,97,116,97,114, - 201,0,0,0,90,11,99,111,100,101,95,111,98,106,101,99, - 116,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,12,1,0,0,215,5,0,0,115,78,0,0,0,0,7, - 15,1,6,1,3,1,16,1,13,1,11,2,3,1,19,1, - 13,1,5,2,16,1,3,1,19,1,13,1,5,2,3,1, - 9,1,12,1,13,1,19,1,5,2,9,1,7,1,15,1, - 6,1,7,1,15,1,18,1,13,1,22,1,12,1,9,1, - 15,1,3,1,19,1,17,1,13,1,8,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,114,138,0,0,0,41,10,114,57,0,0,0, - 114,56,0,0,0,114,58,0,0,0,114,31,1,0,0,114, - 32,1,0,0,114,34,1,0,0,114,33,1,0,0,114,13, - 1,0,0,114,40,1,0,0,114,12,1,0,0,114,4,0, - 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, - 0,114,29,1,0,0,157,5,0,0,115,14,0,0,0,12, - 2,12,8,12,13,12,10,12,7,12,10,18,8,114,29,1, - 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,4, - 0,0,0,0,0,0,0,115,88,0,0,0,101,0,0,90, - 1,0,100,0,0,90,2,0,100,1,0,90,3,0,100,2, - 0,100,3,0,132,0,0,90,4,0,101,5,0,135,0,0, - 102,1,0,100,4,0,100,5,0,134,0,0,131,1,0,90, - 6,0,101,5,0,100,6,0,100,7,0,132,0,0,131,1, - 0,90,7,0,100,8,0,100,9,0,132,0,0,90,8,0, - 135,0,0,83,41,10,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,3,0,0,0,2,0,0,0,67,0,0,0, - 115,22,0,0,0,124,1,0,124,0,0,95,0,0,124,2, - 0,124,0,0,95,1,0,100,1,0,83,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,41,2,114,67,0, - 0,0,114,35,0,0,0,41,3,114,71,0,0,0,114,158, - 0,0,0,114,35,0,0,0,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,114,72,0,0,0,16,6,0,0, - 115,4,0,0,0,0,3,9,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,2,0,0,0,3,0,0,0,3, - 0,0,0,115,22,0,0,0,116,0,0,116,1,0,124,0, - 0,131,2,0,106,2,0,124,1,0,131,1,0,83,41,1, - 122,26,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,41,3,218,5, - 115,117,112,101,114,114,44,1,0,0,114,3,1,0,0,41, - 2,114,71,0,0,0,114,158,0,0,0,41,1,114,224,0, - 0,0,114,4,0,0,0,114,5,0,0,0,114,3,1,0, - 0,22,6,0,0,115,2,0,0,0,0,7,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,2,0,0, - 0,1,0,0,0,67,0,0,0,115,7,0,0,0,124,0, - 0,106,0,0,83,41,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,41,1,114,35,0,0,0,41,2,114,71,0,0, - 0,114,158,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,234,0,0,0,31,6,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,3,0,0,0,8,0,0,0,67, - 0,0,0,115,41,0,0,0,116,0,0,106,1,0,124,1, - 0,100,1,0,131,2,0,143,17,0,125,2,0,124,2,0, - 106,2,0,131,0,0,83,87,100,2,0,81,88,100,2,0, - 83,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,3,114,49,0,0,0,114,50,0,0,0,90,4,114,101, - 97,100,41,3,114,71,0,0,0,114,35,0,0,0,114,54, - 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, - 0,0,114,35,1,0,0,36,6,0,0,115,4,0,0,0, - 0,2,21,1,122,19,70,105,108,101,76,111,97,100,101,114, - 46,103,101,116,95,100,97,116,97,41,9,114,57,0,0,0, - 114,56,0,0,0,114,58,0,0,0,114,59,0,0,0,114, - 72,0,0,0,114,156,0,0,0,114,3,1,0,0,114,234, - 0,0,0,114,35,1,0,0,114,4,0,0,0,114,4,0, - 0,0,41,1,114,224,0,0,0,114,5,0,0,0,114,44, - 1,0,0,11,6,0,0,115,10,0,0,0,12,3,6,2, - 12,6,24,9,18,5,114,44,1,0,0,99,0,0,0,0, - 0,0,0,0,0,0,0,0,4,0,0,0,64,0,0,0, - 115,64,0,0,0,101,0,0,90,1,0,100,0,0,90,2, - 0,100,1,0,90,3,0,100,2,0,100,3,0,132,0,0, - 90,4,0,100,4,0,100,5,0,132,0,0,90,5,0,100, - 6,0,100,7,0,100,8,0,100,9,0,132,0,1,90,6, - 0,100,10,0,83,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,3,0,0,0,3,0,0,0,67,0,0,0,115,36, - 0,0,0,116,0,0,124,1,0,131,1,0,125,2,0,105, - 2,0,124,2,0,106,1,0,100,1,0,54,124,2,0,106, - 2,0,100,2,0,54,83,41,3,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,114,183,0,0, - 0,114,184,0,0,0,41,3,114,39,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,71,0,0,0,114,35,0,0,0,114,42,1,0, - 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,32,1,0,0,46,6,0,0,115,4,0,0,0,0,2, - 12,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,5,0,0,0,5,0,0,0, - 67,0,0,0,115,34,0,0,0,116,0,0,124,1,0,131, - 1,0,125,4,0,124,0,0,106,1,0,124,2,0,124,3, - 0,100,1,0,124,4,0,131,2,1,83,41,2,78,218,5, - 95,109,111,100,101,41,2,114,144,0,0,0,114,33,1,0, - 0,41,5,114,71,0,0,0,114,141,0,0,0,114,140,0, - 0,0,114,53,0,0,0,114,42,0,0,0,114,4,0,0, - 0,114,4,0,0,0,114,5,0,0,0,114,34,1,0,0, - 51,6,0,0,115,4,0,0,0,0,2,12,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, - 49,1,0,0,105,182,1,0,0,99,3,0,0,0,1,0, - 0,0,9,0,0,0,18,0,0,0,67,0,0,0,115,53, - 1,0,0,116,0,0,124,1,0,131,1,0,92,2,0,125, - 4,0,125,5,0,103,0,0,125,6,0,120,54,0,124,4, - 0,114,80,0,116,1,0,124,4,0,131,1,0,12,114,80, - 0,116,0,0,124,4,0,131,1,0,92,2,0,125,4,0, - 125,7,0,124,6,0,106,2,0,124,7,0,131,1,0,1, - 113,27,0,87,120,132,0,116,3,0,124,6,0,131,1,0, - 68,93,118,0,125,7,0,116,4,0,124,4,0,124,7,0, - 131,2,0,125,4,0,121,17,0,116,5,0,106,6,0,124, - 4,0,131,1,0,1,87,113,94,0,4,116,7,0,107,10, - 0,114,155,0,1,1,1,119,94,0,89,113,94,0,4,116, - 8,0,107,10,0,114,211,0,1,125,8,0,1,122,25,0, - 116,9,0,100,1,0,124,4,0,124,8,0,131,3,0,1, - 100,2,0,83,87,89,100,2,0,100,2,0,125,8,0,126, - 8,0,88,113,94,0,88,113,94,0,87,121,33,0,116,10, - 0,124,1,0,124,2,0,124,3,0,131,3,0,1,116,9, - 0,100,3,0,124,1,0,131,2,0,1,87,110,53,0,4, - 116,8,0,107,10,0,114,48,1,1,125,8,0,1,122,21, - 0,116,9,0,100,1,0,124,1,0,124,8,0,131,3,0, - 1,87,89,100,2,0,100,2,0,125,8,0,126,8,0,88, - 110,1,0,88,100,2,0,83,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,11,114,38,0,0,0,114,46,0,0,0,114, - 223,0,0,0,114,33,0,0,0,114,28,0,0,0,114,3, - 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,40,0,0,0, - 114,152,0,0,0,114,55,0,0,0,41,9,114,71,0,0, - 0,114,35,0,0,0,114,53,0,0,0,114,49,1,0,0, - 114,231,0,0,0,114,131,0,0,0,114,27,0,0,0,114, - 23,0,0,0,114,36,1,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,33,1,0,0,56,6,0, - 0,115,38,0,0,0,0,2,18,1,6,2,22,1,18,1, - 17,2,19,1,15,1,3,1,17,1,13,2,7,1,18,3, - 16,1,27,1,3,1,16,1,17,1,18,2,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,57,0,0,0,114, - 56,0,0,0,114,58,0,0,0,114,59,0,0,0,114,32, - 1,0,0,114,34,1,0,0,114,33,1,0,0,114,4,0, - 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, - 0,114,47,1,0,0,42,6,0,0,115,8,0,0,0,12, - 2,6,2,12,5,12,5,114,47,1,0,0,99,0,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,64,0,0, - 0,115,46,0,0,0,101,0,0,90,1,0,100,0,0,90, - 2,0,100,1,0,90,3,0,100,2,0,100,3,0,132,0, - 0,90,4,0,100,4,0,100,5,0,132,0,0,90,5,0, - 100,6,0,83,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,5,0,0,0,6,0,0,0,67,0,0,0, - 115,76,0,0,0,124,0,0,106,0,0,124,1,0,131,1, - 0,125,2,0,124,0,0,106,1,0,124,2,0,131,1,0, - 125,3,0,116,2,0,124,3,0,100,1,0,124,1,0,100, - 2,0,124,2,0,131,1,2,125,4,0,116,3,0,124,4, - 0,100,1,0,124,1,0,100,3,0,124,2,0,131,1,2, - 83,41,4,78,114,67,0,0,0,114,35,0,0,0,114,140, - 0,0,0,41,4,114,234,0,0,0,114,35,1,0,0,114, - 190,0,0,0,114,195,0,0,0,41,5,114,71,0,0,0, - 114,158,0,0,0,114,35,0,0,0,114,53,0,0,0,114, - 43,1,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,12,1,0,0,89,6,0,0,115,8,0,0, - 0,0,1,15,1,15,1,24,1,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,2,0,0,0,1,0,0,0,67,0,0,0,115,4,0, - 0,0,100,1,0,83,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,4,0,0,0,41,2,114,71,0,0,0,114,158, - 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, - 0,0,114,13,1,0,0,95,6,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,57,0,0,0,114,56,0,0,0, - 114,58,0,0,0,114,59,0,0,0,114,12,1,0,0,114, - 13,1,0,0,114,4,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,51,1,0,0,85,6,0, - 0,115,6,0,0,0,12,2,6,2,12,6,114,51,1,0, - 0,99,0,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,64,0,0,0,115,106,0,0,0,101,0,0,90,1, - 0,100,0,0,90,2,0,100,1,0,90,3,0,100,2,0, - 100,3,0,132,0,0,90,4,0,101,5,0,100,4,0,100, - 5,0,132,0,0,131,1,0,90,6,0,100,6,0,100,7, - 0,132,0,0,90,7,0,100,8,0,100,9,0,132,0,0, - 90,8,0,100,10,0,100,11,0,132,0,0,90,9,0,101, - 5,0,100,12,0,100,13,0,132,0,0,131,1,0,90,10, - 0,100,14,0,83,41,15,218,19,69,120,116,101,110,115,105, - 111,110,70,105,108,101,76,111,97,100,101,114,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,3,0,0,0,2,0,0,0,67,0,0,0, - 115,22,0,0,0,124,1,0,124,0,0,95,0,0,124,2, - 0,124,0,0,95,1,0,100,0,0,83,41,1,78,41,2, - 114,67,0,0,0,114,35,0,0,0,41,3,114,71,0,0, - 0,114,67,0,0,0,114,35,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,114,72,0,0,0,112, - 6,0,0,115,4,0,0,0,0,1,9,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,4,0,0,0,11,0,0,0,67,0,0,0,115, - 183,0,0,0,116,0,0,124,1,0,131,1,0,143,29,0, - 1,116,1,0,116,2,0,106,3,0,124,1,0,124,0,0, - 106,4,0,131,3,0,125,2,0,87,100,1,0,81,88,116, - 5,0,100,2,0,124,0,0,106,4,0,131,2,0,1,124, - 0,0,106,6,0,124,1,0,131,1,0,125,3,0,124,3, - 0,114,124,0,116,7,0,124,2,0,100,3,0,131,2,0, - 12,114,124,0,116,8,0,124,0,0,106,4,0,131,1,0, - 100,4,0,25,103,1,0,124,2,0,95,9,0,110,0,0, - 124,0,0,124,2,0,95,10,0,124,2,0,106,11,0,124, - 2,0,95,12,0,124,3,0,115,179,0,124,2,0,106,12, - 0,106,13,0,100,5,0,131,1,0,100,4,0,25,124,2, - 0,95,12,0,110,0,0,124,2,0,83,41,6,122,25,76, - 111,97,100,32,97,110,32,101,120,116,101,110,115,105,111,110, - 32,109,111,100,117,108,101,46,78,122,33,101,120,116,101,110, - 115,105,111,110,32,109,111,100,117,108,101,32,108,111,97,100, - 101,100,32,102,114,111,109,32,123,33,114,125,114,242,0,0, - 0,114,84,0,0,0,114,116,0,0,0,41,14,114,69,0, - 0,0,114,114,0,0,0,114,106,0,0,0,90,12,108,111, - 97,100,95,100,121,110,97,109,105,99,114,35,0,0,0,114, - 152,0,0,0,114,219,0,0,0,114,60,0,0,0,114,38, - 0,0,0,114,242,0,0,0,114,204,0,0,0,114,57,0, - 0,0,114,249,0,0,0,114,32,0,0,0,41,4,114,71, - 0,0,0,114,158,0,0,0,114,179,0,0,0,114,219,0, - 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, - 0,114,3,1,0,0,116,6,0,0,115,24,0,0,0,0, - 3,13,1,9,1,21,1,16,1,15,1,22,1,28,1,9, - 1,12,1,6,1,28,1,122,31,69,120,116,101,110,115,105, - 111,110,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,2,0,0,0,4,0,0,0,3,0,0,0,115,48,0, - 0,0,116,0,0,124,0,0,106,1,0,131,1,0,100,1, - 0,25,137,0,0,116,2,0,135,0,0,102,1,0,100,2, - 0,100,3,0,134,0,0,116,3,0,68,131,1,0,131,1, - 0,83,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,29,0,0,0,99,1,0,0, - 0,0,0,0,0,2,0,0,0,4,0,0,0,51,0,0, - 0,115,31,0,0,0,124,0,0,93,21,0,125,1,0,136, - 0,0,100,0,0,124,1,0,23,107,2,0,86,1,113,3, - 0,100,1,0,83,41,2,114,72,0,0,0,78,114,4,0, - 0,0,41,2,114,22,0,0,0,218,6,115,117,102,102,105, - 120,41,1,218,9,102,105,108,101,95,110,97,109,101,114,4, - 0,0,0,114,5,0,0,0,114,77,0,0,0,135,6,0, - 0,115,2,0,0,0,6,1,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,38,0, - 0,0,114,35,0,0,0,114,78,0,0,0,218,18,69,88, - 84,69,78,83,73,79,78,95,83,85,70,70,73,88,69,83, - 41,2,114,71,0,0,0,114,158,0,0,0,114,4,0,0, - 0,41,1,114,54,1,0,0,114,5,0,0,0,114,219,0, - 0,0,132,6,0,0,115,6,0,0,0,0,2,19,1,18, - 1,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,2,0,0,0,1,0, - 0,0,67,0,0,0,115,4,0,0,0,100,1,0,83,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,4,0,0,0,41,2,114,71,0,0,0,114, - 158,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,12,1,0,0,138,6,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,2,0,0,0,1,0, - 0,0,67,0,0,0,115,4,0,0,0,100,1,0,83,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,4,0,0,0,41,2, - 114,71,0,0,0,114,158,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,114,13,1,0,0,142,6, - 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,2,0,0,0,1,0,0,0,67,0,0,0,115,7, - 0,0,0,124,0,0,106,0,0,83,41,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,41,1,114,35,0,0,0,41, - 2,114,71,0,0,0,114,158,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,114,234,0,0,0,146, - 6,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,11,114, - 57,0,0,0,114,56,0,0,0,114,58,0,0,0,114,59, - 0,0,0,114,72,0,0,0,114,156,0,0,0,114,3,1, - 0,0,114,219,0,0,0,114,12,1,0,0,114,13,1,0, - 0,114,234,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,114,52,1,0,0,104, - 6,0,0,115,14,0,0,0,12,6,6,2,12,4,18,16, - 12,6,12,4,12,4,114,52,1,0,0,99,0,0,0,0, - 0,0,0,0,0,0,0,0,2,0,0,0,64,0,0,0, - 115,130,0,0,0,101,0,0,90,1,0,100,0,0,90,2, - 0,100,1,0,90,3,0,100,2,0,100,3,0,132,0,0, - 90,4,0,100,4,0,100,5,0,132,0,0,90,5,0,100, - 6,0,100,7,0,132,0,0,90,6,0,100,8,0,100,9, - 0,132,0,0,90,7,0,100,10,0,100,11,0,132,0,0, - 90,8,0,100,12,0,100,13,0,132,0,0,90,9,0,100, - 14,0,100,15,0,132,0,0,90,10,0,100,16,0,100,17, - 0,132,0,0,90,11,0,100,18,0,100,19,0,132,0,0, - 90,12,0,100,20,0,83,41,21,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,4,0,0, - 0,2,0,0,0,67,0,0,0,115,52,0,0,0,124,1, - 0,124,0,0,95,0,0,124,2,0,124,0,0,95,1,0, - 116,2,0,124,0,0,106,3,0,131,0,0,131,1,0,124, - 0,0,95,4,0,124,3,0,124,0,0,95,5,0,100,0, - 0,83,41,1,78,41,6,114,70,0,0,0,114,252,0,0, - 0,114,229,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,41,4,114,71,0,0,0, - 114,67,0,0,0,114,35,0,0,0,218,11,112,97,116,104, - 95,102,105,110,100,101,114,114,4,0,0,0,114,4,0,0, - 0,114,5,0,0,0,114,72,0,0,0,159,6,0,0,115, - 8,0,0,0,0,1,9,1,9,1,21,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,4,0, - 0,0,3,0,0,0,67,0,0,0,115,53,0,0,0,124, - 0,0,106,0,0,106,1,0,100,1,0,131,1,0,92,3, - 0,125,1,0,125,2,0,125,3,0,124,2,0,100,2,0, - 107,2,0,114,43,0,100,6,0,83,124,1,0,100,5,0, - 102,2,0,83,41,7,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,116,0,0,0,114,30,0,0,0, - 114,7,0,0,0,114,35,0,0,0,114,242,0,0,0,41, - 2,122,3,115,121,115,122,4,112,97,116,104,41,2,114,70, - 0,0,0,114,32,0,0,0,41,4,114,71,0,0,0,114, - 231,0,0,0,218,3,100,111,116,114,94,0,0,0,114,4, - 0,0,0,114,4,0,0,0,114,5,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,165,6,0,0,115,8,0,0,0,0, - 2,27,1,12,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,3,0,0,0,3,0,0,0, - 67,0,0,0,115,38,0,0,0,124,0,0,106,0,0,131, - 0,0,92,2,0,125,1,0,125,2,0,116,1,0,116,2, - 0,106,3,0,124,1,0,25,124,2,0,131,2,0,83,41, - 1,78,41,4,114,62,1,0,0,114,62,0,0,0,114,7, - 0,0,0,114,73,0,0,0,41,3,114,71,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,4,0,0,0,114,4,0,0,0,114,5,0, - 0,0,114,57,1,0,0,175,6,0,0,115,4,0,0,0, - 0,1,18,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,3,0, - 0,0,3,0,0,0,67,0,0,0,115,127,0,0,0,116, - 0,0,124,0,0,106,1,0,131,0,0,131,1,0,125,1, - 0,124,1,0,124,0,0,106,2,0,107,3,0,114,120,0, - 124,0,0,106,3,0,124,0,0,106,4,0,124,1,0,131, - 2,0,125,2,0,124,2,0,100,0,0,107,9,0,114,108, - 0,124,2,0,106,5,0,100,0,0,107,8,0,114,108,0, - 124,2,0,106,6,0,114,108,0,124,2,0,106,6,0,124, - 0,0,95,7,0,113,108,0,110,0,0,124,1,0,124,0, - 0,95,2,0,110,0,0,124,0,0,106,7,0,83,41,1, - 78,41,8,114,229,0,0,0,114,57,1,0,0,114,58,1, - 0,0,114,59,1,0,0,114,70,0,0,0,114,169,0,0, - 0,114,220,0,0,0,114,252,0,0,0,41,3,114,71,0, - 0,0,90,11,112,97,114,101,110,116,95,112,97,116,104,114, - 177,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,12,95,114,101,99,97,108,99,117,108,97,116, - 101,179,6,0,0,115,16,0,0,0,0,2,18,1,15,1, - 21,3,27,1,9,1,18,1,12,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, - 1,0,0,0,2,0,0,0,67,0,0,0,115,16,0,0, - 0,116,0,0,124,0,0,106,1,0,131,0,0,131,1,0, - 83,41,1,78,41,2,218,4,105,116,101,114,114,63,1,0, - 0,41,1,114,71,0,0,0,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,218,8,95,95,105,116,101,114,95, - 95,192,6,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,1,0,0,0,0,0,0,0,1,0, - 0,0,2,0,0,0,67,0,0,0,115,16,0,0,0,116, - 0,0,124,0,0,106,1,0,131,0,0,131,1,0,83,41, - 1,78,41,2,114,31,0,0,0,114,63,1,0,0,41,1, - 114,71,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,218,7,95,95,108,101,110,95,95,195,6,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,1,0,0,0,2,0,0, - 0,67,0,0,0,115,16,0,0,0,100,1,0,106,0,0, - 124,0,0,106,1,0,131,1,0,83,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,47,0,0,0,114,252,0,0,0,41, - 1,114,71,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,101,0,0,0,198,6,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,2,0,0,0,2,0,0,0,67, - 0,0,0,115,16,0,0,0,124,1,0,124,0,0,106,0, - 0,131,0,0,107,6,0,83,41,1,78,41,1,114,63,1, - 0,0,41,2,114,71,0,0,0,218,4,105,116,101,109,114, - 4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,12, - 95,95,99,111,110,116,97,105,110,115,95,95,201,6,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,2,0,0, - 0,2,0,0,0,67,0,0,0,115,20,0,0,0,124,0, - 0,106,0,0,106,1,0,124,1,0,131,1,0,1,100,0, - 0,83,41,1,78,41,2,114,252,0,0,0,114,223,0,0, - 0,41,2,114,71,0,0,0,114,67,1,0,0,114,4,0, - 0,0,114,4,0,0,0,114,5,0,0,0,114,223,0,0, - 0,204,6,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,13,114,57,0,0,0,114,56,0,0,0, - 114,58,0,0,0,114,59,0,0,0,114,72,0,0,0,114, - 62,1,0,0,114,57,1,0,0,114,63,1,0,0,114,65, - 1,0,0,114,66,1,0,0,114,101,0,0,0,114,68,1, - 0,0,114,223,0,0,0,114,4,0,0,0,114,4,0,0, - 0,114,4,0,0,0,114,5,0,0,0,114,56,1,0,0, - 152,6,0,0,115,20,0,0,0,12,5,6,2,12,6,12, - 10,12,4,12,13,12,3,12,3,12,3,12,3,114,56,1, - 0,0,99,0,0,0,0,0,0,0,0,0,0,0,0,3, - 0,0,0,64,0,0,0,115,94,0,0,0,101,0,0,90, - 1,0,100,0,0,90,2,0,100,1,0,100,2,0,132,0, - 0,90,3,0,101,4,0,100,3,0,100,4,0,132,0,0, - 131,1,0,90,5,0,100,5,0,100,6,0,132,0,0,90, - 6,0,100,7,0,100,8,0,132,0,0,90,7,0,100,9, - 0,100,10,0,132,0,0,90,8,0,100,11,0,100,12,0, - 132,0,0,90,9,0,100,13,0,83,41,14,114,250,0,0, - 0,99,4,0,0,0,0,0,0,0,4,0,0,0,4,0, - 0,0,67,0,0,0,115,25,0,0,0,116,0,0,124,1, - 0,124,2,0,124,3,0,131,3,0,124,0,0,95,1,0, - 100,0,0,83,41,1,78,41,2,114,56,1,0,0,114,252, - 0,0,0,41,4,114,71,0,0,0,114,67,0,0,0,114, - 35,0,0,0,114,60,1,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,72,0,0,0,210,6,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,2,0,0,0, - 2,0,0,0,67,0,0,0,115,16,0,0,0,100,1,0, - 106,0,0,124,1,0,106,1,0,131,1,0,83,41,2,78, - 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,47,0, - 0,0,114,57,0,0,0,41,2,114,245,0,0,0,114,179, - 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, - 0,0,114,205,0,0,0,214,6,0,0,115,2,0,0,0, - 0,2,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,2,0,0,0,1,0,0, - 0,67,0,0,0,115,4,0,0,0,100,1,0,83,41,2, - 78,84,114,4,0,0,0,41,2,114,71,0,0,0,114,158, - 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, - 0,0,114,219,0,0,0,218,6,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,2,0,0,0,1,0,0,0, - 67,0,0,0,115,4,0,0,0,100,1,0,83,41,2,78, - 114,30,0,0,0,114,4,0,0,0,41,2,114,71,0,0, - 0,114,158,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,13,1,0,0,221,6,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,2,0,0,0,6, - 0,0,0,67,0,0,0,115,22,0,0,0,116,0,0,100, - 1,0,100,2,0,100,3,0,100,4,0,100,5,0,131,3, - 1,83,41,6,78,114,30,0,0,0,122,8,60,115,116,114, - 105,110,103,62,114,175,0,0,0,114,38,1,0,0,84,41, - 1,114,39,1,0,0,41,2,114,71,0,0,0,114,158,0, - 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, - 0,114,12,1,0,0,224,6,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,2,0,0,0,3,0,0,0,67,0,0, - 0,115,29,0,0,0,116,0,0,100,1,0,124,0,0,106, - 1,0,131,2,0,1,116,2,0,124,0,0,124,1,0,131, - 2,0,83,41,2,122,24,76,111,97,100,32,97,32,110,97, - 109,101,115,112,97,99,101,32,109,111,100,117,108,101,46,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,3,114,152,0,0,0,114,252, - 0,0,0,114,180,0,0,0,41,2,114,71,0,0,0,114, - 158,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,3,1,0,0,228,6,0,0,115,4,0,0, - 0,0,2,16,1,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,10,114,57,0,0,0,114,56,0,0,0, - 114,58,0,0,0,114,72,0,0,0,114,7,1,0,0,114, - 205,0,0,0,114,219,0,0,0,114,13,1,0,0,114,12, - 1,0,0,114,3,1,0,0,114,4,0,0,0,114,4,0, - 0,0,114,4,0,0,0,114,5,0,0,0,114,250,0,0, - 0,209,6,0,0,115,12,0,0,0,12,1,12,4,18,4, - 12,3,12,3,12,4,114,250,0,0,0,99,0,0,0,0, - 0,0,0,0,0,0,0,0,5,0,0,0,64,0,0,0, - 115,160,0,0,0,101,0,0,90,1,0,100,0,0,90,2, - 0,100,1,0,90,3,0,101,4,0,100,2,0,100,3,0, - 132,0,0,131,1,0,90,5,0,101,4,0,100,4,0,100, - 5,0,132,0,0,131,1,0,90,6,0,101,4,0,100,6, - 0,100,7,0,132,0,0,131,1,0,90,7,0,101,4,0, - 100,8,0,100,9,0,132,0,0,131,1,0,90,8,0,101, - 4,0,100,10,0,100,11,0,100,12,0,132,1,0,131,1, - 0,90,9,0,101,4,0,100,10,0,100,10,0,100,13,0, - 100,14,0,132,2,0,131,1,0,90,10,0,101,4,0,100, - 10,0,100,15,0,100,16,0,132,1,0,131,1,0,90,11, - 0,100,10,0,83,41,17,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,2,0,0,0, - 4,0,0,0,67,0,0,0,115,58,0,0,0,120,51,0, - 116,0,0,106,1,0,106,2,0,131,0,0,68,93,34,0, - 125,1,0,116,3,0,124,1,0,100,1,0,131,2,0,114, - 16,0,124,1,0,106,4,0,131,0,0,1,113,16,0,113, - 16,0,87,100,2,0,83,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,218,17,105,110,118,97,108,105, - 100,97,116,101,95,99,97,99,104,101,115,78,41,5,114,7, - 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,6,118,97,108,117,101,115, - 114,60,0,0,0,114,70,1,0,0,41,2,114,245,0,0, - 0,218,6,102,105,110,100,101,114,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,70,1,0,0,240,6,0, - 0,115,6,0,0,0,0,4,22,1,15,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,3,0,0,0,12,0,0,0,67,0,0,0,115, - 94,0,0,0,116,0,0,106,1,0,115,28,0,116,2,0, - 106,3,0,100,1,0,116,4,0,131,2,0,1,110,0,0, - 120,59,0,116,0,0,106,1,0,68,93,44,0,125,2,0, - 121,14,0,124,2,0,124,1,0,131,1,0,83,87,113,38, - 0,4,116,5,0,107,10,0,114,81,0,1,1,1,119,38, - 0,89,113,38,0,88,113,38,0,87,100,2,0,83,100,2, - 0,83,41,3,122,113,83,101,97,114,99,104,32,115,101,113, - 117,101,110,99,101,32,111,102,32,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,10,10,32,32,32,32,32,32,32, - 32,73,102,32,39,104,111,111,107,115,39,32,105,115,32,102, - 97,108,115,101,32,116,104,101,110,32,117,115,101,32,115,121, - 115,46,112,97,116,104,95,104,111,111,107,115,46,10,10,32, - 32,32,32,32,32,32,32,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, - 78,41,6,114,7,0,0,0,218,10,112,97,116,104,95,104, - 111,111,107,115,114,166,0,0,0,114,167,0,0,0,114,168, - 0,0,0,114,153,0,0,0,41,3,114,245,0,0,0,114, - 35,0,0,0,90,4,104,111,111,107,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,218,11,95,112,97,116,104, - 95,104,111,111,107,115,248,6,0,0,115,16,0,0,0,0, - 7,9,1,19,1,16,1,3,1,14,1,13,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, - 3,0,0,0,11,0,0,0,67,0,0,0,115,97,0,0, - 0,124,1,0,100,1,0,107,2,0,114,27,0,116,0,0, - 106,1,0,131,0,0,125,1,0,110,0,0,121,17,0,116, - 2,0,106,3,0,124,1,0,25,125,2,0,87,110,46,0, - 4,116,4,0,107,10,0,114,92,0,1,1,1,124,0,0, - 106,5,0,124,1,0,131,1,0,125,2,0,124,2,0,116, - 2,0,106,3,0,124,1,0,60,89,110,1,0,88,124,2, - 0,83,41,2,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,30,0,0,0,41,6,114, - 3,0,0,0,114,45,0,0,0,114,7,0,0,0,114,71, - 1,0,0,114,79,0,0,0,114,75,1,0,0,41,3,114, - 245,0,0,0,114,35,0,0,0,114,73,1,0,0,114,4, - 0,0,0,114,4,0,0,0,114,5,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,9,7,0,0,115,16,0,0,0,0,8,12,1, - 15,1,3,1,17,1,13,1,15,1,18,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,6,0,0,0,3,0,0,0,67,0, - 0,0,115,113,0,0,0,116,0,0,124,2,0,100,1,0, - 131,2,0,114,39,0,124,2,0,106,1,0,124,1,0,131, - 1,0,92,2,0,125,3,0,125,4,0,110,21,0,124,2, - 0,106,2,0,124,1,0,131,1,0,125,3,0,100,0,0, - 125,4,0,124,3,0,100,0,0,107,9,0,114,85,0,116, - 3,0,124,1,0,124,3,0,131,2,0,83,116,4,0,124, - 1,0,100,0,0,131,2,0,125,5,0,124,4,0,124,5, - 0,95,5,0,124,5,0,83,41,2,78,114,165,0,0,0, - 41,6,114,60,0,0,0,114,165,0,0,0,114,11,1,0, - 0,114,173,0,0,0,114,216,0,0,0,114,220,0,0,0, - 41,6,114,245,0,0,0,114,158,0,0,0,114,73,1,0, - 0,114,169,0,0,0,114,170,0,0,0,114,177,0,0,0, - 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,218, - 16,95,108,101,103,97,99,121,95,103,101,116,95,115,112,101, - 99,26,7,0,0,115,18,0,0,0,0,2,15,1,24,2, - 15,1,6,1,12,1,13,1,15,1,9,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,9,0,0,0,5,0,0,0,67,0,0,0,115, - 252,0,0,0,103,0,0,125,4,0,120,239,0,124,2,0, - 68,93,203,0,125,5,0,116,0,0,124,5,0,116,1,0, - 116,2,0,102,2,0,131,2,0,115,46,0,113,13,0,110, - 0,0,124,0,0,106,3,0,124,5,0,131,1,0,125,6, - 0,124,6,0,100,1,0,107,9,0,114,13,0,116,4,0, - 124,6,0,100,2,0,131,2,0,114,109,0,124,6,0,106, - 5,0,124,1,0,124,3,0,131,2,0,125,7,0,110,18, - 0,124,0,0,106,6,0,124,1,0,124,6,0,131,2,0, - 125,7,0,124,7,0,100,1,0,107,8,0,114,145,0,113, - 13,0,110,0,0,124,7,0,106,7,0,100,1,0,107,9, - 0,114,164,0,124,7,0,83,124,7,0,106,8,0,125,8, - 0,124,8,0,100,1,0,107,8,0,114,200,0,116,9,0, - 100,3,0,131,1,0,130,1,0,110,0,0,124,4,0,106, - 10,0,124,8,0,131,1,0,1,113,13,0,113,13,0,87, - 116,11,0,124,1,0,100,1,0,131,2,0,125,7,0,124, - 4,0,124,7,0,95,8,0,124,7,0,83,100,1,0,83, - 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,10,1,0,0,122,19,115,112,101,99,32, - 109,105,115,115,105,110,103,32,108,111,97,100,101,114,41,12, - 114,192,0,0,0,218,3,115,116,114,218,5,98,121,116,101, - 115,114,76,1,0,0,114,60,0,0,0,114,10,1,0,0, - 114,77,1,0,0,114,169,0,0,0,114,220,0,0,0,114, - 153,0,0,0,114,197,0,0,0,114,216,0,0,0,41,9, - 114,245,0,0,0,114,158,0,0,0,114,35,0,0,0,114, - 9,1,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,177,0,0,0,114,170,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,218,9,95,103,101,116,95, - 115,112,101,99,39,7,0,0,115,40,0,0,0,0,5,6, - 1,13,1,21,1,6,1,15,1,12,1,15,1,21,2,18, - 1,12,1,6,1,15,1,4,1,9,1,12,1,15,5,20, - 2,15,1,9,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,6,0,0,0,4,0,0,0,67,0,0,0, - 115,143,0,0,0,124,2,0,100,1,0,107,8,0,114,24, - 0,116,0,0,106,1,0,125,2,0,110,0,0,124,0,0, - 106,2,0,124,1,0,124,2,0,124,3,0,131,3,0,125, - 4,0,124,4,0,100,1,0,107,8,0,114,61,0,100,1, - 0,83,124,4,0,106,3,0,100,1,0,107,8,0,114,135, - 0,124,4,0,106,4,0,125,5,0,124,5,0,114,128,0, - 100,2,0,124,4,0,95,5,0,116,6,0,124,1,0,124, - 5,0,124,0,0,106,2,0,131,3,0,124,4,0,95,4, - 0,124,4,0,83,100,1,0,83,110,4,0,124,4,0,83, - 100,1,0,83,41,3,122,98,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,78,90,9,110,97,109, - 101,115,112,97,99,101,41,7,114,7,0,0,0,114,35,0, - 0,0,114,81,1,0,0,114,169,0,0,0,114,220,0,0, - 0,114,217,0,0,0,114,56,1,0,0,41,6,114,245,0, - 0,0,114,158,0,0,0,114,35,0,0,0,114,9,1,0, - 0,114,177,0,0,0,114,80,1,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,114,10,1,0,0,71, - 7,0,0,115,26,0,0,0,0,4,12,1,12,1,21,1, - 12,1,4,1,15,1,9,1,6,3,9,1,24,1,4,2, - 7,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,4,0,0,0,3,0,0,0,67,0,0,0,115,41,0, - 0,0,124,0,0,106,0,0,124,1,0,124,2,0,131,2, - 0,125,3,0,124,3,0,100,1,0,107,8,0,114,34,0, - 100,1,0,83,124,3,0,106,1,0,83,41,2,122,98,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,78,41,2,114,10,1,0,0,114,169,0,0,0,41,4, - 114,245,0,0,0,114,158,0,0,0,114,35,0,0,0,114, - 177,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,11,1,0,0,93,7,0,0,115,8,0,0, - 0,0,5,18,1,12,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,41,12,114,57,0,0,0,114,56,0,0,0,114,58,0, - 0,0,114,59,0,0,0,114,7,1,0,0,114,70,1,0, - 0,114,75,1,0,0,114,76,1,0,0,114,77,1,0,0, - 114,81,1,0,0,114,10,1,0,0,114,11,1,0,0,114, - 4,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,69,1,0,0,236,6,0,0,115,22,0,0, - 0,12,2,6,2,18,8,18,17,18,17,18,13,3,1,18, - 31,3,1,21,21,3,1,114,69,1,0,0,99,0,0,0, - 0,0,0,0,0,0,0,0,0,3,0,0,0,64,0,0, - 0,115,133,0,0,0,101,0,0,90,1,0,100,0,0,90, - 2,0,100,1,0,90,3,0,100,2,0,100,3,0,132,0, - 0,90,4,0,100,4,0,100,5,0,132,0,0,90,5,0, - 101,6,0,90,7,0,100,6,0,100,7,0,132,0,0,90, - 8,0,100,8,0,100,9,0,132,0,0,90,9,0,100,10, - 0,100,11,0,100,12,0,132,1,0,90,10,0,100,13,0, - 100,14,0,132,0,0,90,11,0,101,12,0,100,15,0,100, - 16,0,132,0,0,131,1,0,90,13,0,100,17,0,100,18, - 0,132,0,0,90,14,0,100,10,0,83,41,19,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, - 5,0,0,0,5,0,0,0,7,0,0,0,115,122,0,0, - 0,103,0,0,125,3,0,120,52,0,124,2,0,68,93,44, - 0,92,2,0,137,0,0,125,4,0,124,3,0,106,0,0, - 135,0,0,102,1,0,100,1,0,100,2,0,134,0,0,124, - 4,0,68,131,1,0,131,1,0,1,113,13,0,87,124,3, - 0,124,0,0,95,1,0,124,1,0,112,79,0,100,3,0, - 124,0,0,95,2,0,100,6,0,124,0,0,95,3,0,116, - 4,0,131,0,0,124,0,0,95,5,0,116,4,0,131,0, - 0,124,0,0,95,6,0,100,5,0,83,41,7,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,2,0,0,0,3,0,0,0,51,0,0,0,115,27, - 0,0,0,124,0,0,93,17,0,125,1,0,124,1,0,136, - 0,0,102,2,0,86,1,113,3,0,100,0,0,83,41,1, - 78,114,4,0,0,0,41,2,114,22,0,0,0,114,53,1, - 0,0,41,1,114,169,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,77,0,0,0,119,7,0,0,115,2,0,0, - 0,6,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,116,0,0,0, - 114,29,0,0,0,78,114,138,0,0,0,41,7,114,197,0, - 0,0,218,8,95,108,111,97,100,101,114,115,114,35,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,71,0,0,0,114,35,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,127,0,0,0,114, - 4,0,0,0,41,1,114,169,0,0,0,114,5,0,0,0, - 114,72,0,0,0,113,7,0,0,115,16,0,0,0,0,4, - 6,1,19,1,36,1,9,2,15,1,9,1,12,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,1,0,0,0, - 2,0,0,0,67,0,0,0,115,13,0,0,0,100,3,0, - 124,0,0,95,0,0,100,2,0,83,41,4,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,29,0, - 0,0,78,114,138,0,0,0,41,1,114,84,1,0,0,41, - 1,114,71,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,70,1,0,0,127,7,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,3,0,0,0, - 3,0,0,0,67,0,0,0,115,59,0,0,0,124,0,0, - 106,0,0,124,1,0,131,1,0,125,2,0,124,2,0,100, - 1,0,107,8,0,114,37,0,100,1,0,103,0,0,102,2, - 0,83,124,2,0,106,1,0,124,2,0,106,2,0,112,55, - 0,103,0,0,102,2,0,83,41,2,122,125,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,78,41,3,114,10,1,0, - 0,114,169,0,0,0,114,220,0,0,0,41,3,114,71,0, - 0,0,114,158,0,0,0,114,177,0,0,0,114,4,0,0, - 0,114,4,0,0,0,114,5,0,0,0,114,165,0,0,0, - 133,7,0,0,115,8,0,0,0,0,3,15,1,12,1,10, - 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,8,0,0,0,13,0,0,0,67,0,0,0,115,97, - 0,0,0,124,1,0,124,2,0,124,3,0,131,2,0,125, - 6,0,121,13,0,124,6,0,106,0,0,125,7,0,87,110, - 43,0,4,116,1,0,107,10,0,114,73,0,1,1,1,116, - 2,0,124,2,0,124,3,0,100,1,0,124,6,0,100,2, - 0,124,4,0,131,2,2,83,89,110,20,0,88,124,7,0, - 124,2,0,124,3,0,124,4,0,124,5,0,131,4,0,83, - 100,0,0,83,41,3,78,114,169,0,0,0,114,220,0,0, - 0,41,3,114,81,1,0,0,114,209,0,0,0,114,235,0, - 0,0,41,8,114,71,0,0,0,114,239,0,0,0,114,158, - 0,0,0,114,35,0,0,0,114,220,0,0,0,114,9,1, - 0,0,114,169,0,0,0,90,8,103,101,116,95,115,112,101, - 99,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,81,1,0,0,141,7,0,0,115,14,0,0,0,0,1, - 15,1,3,1,13,1,13,1,18,1,12,2,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,14,0,0,0, - 15,0,0,0,67,0,0,0,115,240,1,0,0,100,1,0, - 125,3,0,124,1,0,106,0,0,100,2,0,131,1,0,100, - 3,0,25,125,4,0,121,34,0,116,1,0,124,0,0,106, - 2,0,112,49,0,116,3,0,106,4,0,131,0,0,131,1, - 0,106,5,0,125,5,0,87,110,24,0,4,116,6,0,107, - 10,0,114,85,0,1,1,1,100,10,0,125,5,0,89,110, - 1,0,88,124,5,0,124,0,0,106,7,0,107,3,0,114, - 123,0,124,0,0,106,8,0,131,0,0,1,124,5,0,124, - 0,0,95,7,0,110,0,0,116,9,0,131,0,0,114,156, - 0,124,0,0,106,10,0,125,6,0,124,4,0,106,11,0, - 131,0,0,125,7,0,110,15,0,124,0,0,106,12,0,125, - 6,0,124,4,0,125,7,0,124,7,0,124,6,0,107,6, - 0,114,51,1,116,13,0,124,0,0,106,2,0,124,4,0, - 131,2,0,125,8,0,120,103,0,124,0,0,106,14,0,68, - 93,77,0,92,2,0,125,9,0,125,10,0,100,5,0,124, - 9,0,23,125,11,0,116,13,0,124,8,0,124,11,0,131, - 2,0,125,12,0,116,15,0,124,12,0,131,1,0,114,211, - 0,124,0,0,106,16,0,124,10,0,124,1,0,124,12,0, - 124,8,0,103,1,0,124,2,0,131,5,0,83,113,211,0, - 87,116,17,0,124,8,0,131,1,0,125,3,0,110,0,0, - 120,126,0,124,0,0,106,14,0,68,93,115,0,92,2,0, - 125,9,0,125,10,0,116,13,0,124,0,0,106,2,0,124, - 4,0,124,9,0,23,131,2,0,125,12,0,116,18,0,100, - 6,0,106,19,0,124,12,0,131,1,0,100,7,0,100,3, - 0,131,1,1,1,124,7,0,124,9,0,23,124,6,0,107, - 6,0,114,61,1,116,15,0,124,12,0,131,1,0,114,176, - 1,124,0,0,106,16,0,124,10,0,124,1,0,124,12,0, - 100,8,0,124,2,0,131,5,0,83,113,61,1,113,61,1, - 87,124,3,0,114,236,1,116,18,0,100,9,0,106,19,0, - 124,8,0,131,1,0,131,1,0,1,116,20,0,124,1,0, - 100,8,0,131,2,0,125,13,0,124,8,0,103,1,0,124, - 13,0,95,21,0,124,13,0,83,100,8,0,83,41,11,122, - 125,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,70,114, - 116,0,0,0,114,115,0,0,0,114,29,0,0,0,114,72, - 0,0,0,122,9,116,114,121,105,110,103,32,123,125,114,145, - 0,0,0,78,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,114, - 138,0,0,0,41,22,114,32,0,0,0,114,39,0,0,0, - 114,35,0,0,0,114,3,0,0,0,114,45,0,0,0,114, - 48,1,0,0,114,40,0,0,0,114,84,1,0,0,218,11, - 95,102,105,108,108,95,99,97,99,104,101,114,6,0,0,0, - 114,87,1,0,0,114,139,0,0,0,114,86,1,0,0,114, - 28,0,0,0,114,83,1,0,0,114,44,0,0,0,114,81, - 1,0,0,114,46,0,0,0,114,152,0,0,0,114,47,0, - 0,0,114,216,0,0,0,114,220,0,0,0,41,14,114,71, - 0,0,0,114,158,0,0,0,114,9,1,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,183,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,53,1, - 0,0,114,239,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,177,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,10,1,0,0,151,7,0,0,115,68, - 0,0,0,0,3,6,1,19,1,3,1,34,1,13,1,11, - 1,15,1,10,1,12,2,9,1,9,1,15,2,9,1,6, - 2,12,1,18,1,22,1,10,1,15,1,12,1,32,4,15, - 2,22,1,22,1,25,1,16,1,12,1,32,1,6,1,19, - 1,15,1,12,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,9,0,0,0,13,0,0,0,67,0, - 0,0,115,14,1,0,0,124,0,0,106,0,0,125,1,0, - 121,31,0,116,1,0,106,2,0,124,1,0,112,33,0,116, - 1,0,106,3,0,131,0,0,131,1,0,125,2,0,87,110, - 33,0,4,116,4,0,116,5,0,116,6,0,102,3,0,107, - 10,0,114,75,0,1,1,1,103,0,0,125,2,0,89,110, - 1,0,88,116,7,0,106,8,0,106,9,0,100,1,0,131, - 1,0,115,112,0,116,10,0,124,2,0,131,1,0,124,0, - 0,95,11,0,110,111,0,116,10,0,131,0,0,125,3,0, - 120,90,0,124,2,0,68,93,82,0,125,4,0,124,4,0, - 106,12,0,100,2,0,131,1,0,92,3,0,125,5,0,125, - 6,0,125,7,0,124,6,0,114,191,0,100,3,0,106,13, - 0,124,5,0,124,7,0,106,14,0,131,0,0,131,2,0, - 125,8,0,110,6,0,124,5,0,125,8,0,124,3,0,106, - 15,0,124,8,0,131,1,0,1,113,128,0,87,124,3,0, - 124,0,0,95,11,0,116,7,0,106,8,0,106,9,0,116, - 16,0,131,1,0,114,10,1,100,4,0,100,5,0,132,0, - 0,124,2,0,68,131,1,0,124,0,0,95,17,0,110,0, - 0,100,6,0,83,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,0,0, - 0,0,114,116,0,0,0,122,5,123,125,46,123,125,99,1, - 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,83, - 0,0,0,115,28,0,0,0,104,0,0,124,0,0,93,18, - 0,125,1,0,124,1,0,106,0,0,131,0,0,146,2,0, - 113,6,0,83,114,4,0,0,0,41,1,114,139,0,0,0, - 41,2,114,22,0,0,0,90,2,102,110,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,250,9,60,115,101,116, - 99,111,109,112,62,225,7,0,0,115,2,0,0,0,9,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,35, - 0,0,0,114,3,0,0,0,90,7,108,105,115,116,100,105, - 114,114,45,0,0,0,218,17,70,105,108,101,78,111,116,70, - 111,117,110,100,69,114,114,111,114,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,7, - 0,0,0,114,8,0,0,0,114,9,0,0,0,114,85,1, - 0,0,114,86,1,0,0,114,121,0,0,0,114,47,0,0, - 0,114,139,0,0,0,218,3,97,100,100,114,10,0,0,0, - 114,87,1,0,0,41,9,114,71,0,0,0,114,35,0,0, - 0,90,8,99,111,110,116,101,110,116,115,90,21,108,111,119, - 101,114,95,115,117,102,102,105,120,95,99,111,110,116,101,110, - 116,115,114,67,1,0,0,114,67,0,0,0,114,61,1,0, - 0,114,53,1,0,0,90,8,110,101,119,95,110,97,109,101, - 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, - 89,1,0,0,196,7,0,0,115,34,0,0,0,0,2,9, - 1,3,1,31,1,22,3,11,3,18,1,18,7,9,1,13, - 1,24,1,6,1,27,2,6,1,17,1,9,1,18,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, - 3,0,0,0,3,0,0,0,7,0,0,0,115,25,0,0, - 0,135,0,0,135,1,0,102,2,0,100,1,0,100,2,0, - 134,0,0,125,2,0,124,2,0,83,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,1,0, - 0,0,4,0,0,0,19,0,0,0,115,46,0,0,0,116, - 0,0,124,0,0,131,1,0,115,33,0,116,1,0,100,1, - 0,100,2,0,124,0,0,131,1,1,130,1,0,110,0,0, - 136,0,0,124,0,0,136,1,0,140,1,0,83,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,35, - 0,0,0,41,2,114,46,0,0,0,114,153,0,0,0,41, - 1,114,35,0,0,0,41,2,114,245,0,0,0,114,88,1, - 0,0,114,4,0,0,0,114,5,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,237,7,0,0,115,6,0,0,0,0, - 2,12,1,21,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,4,0, - 0,0,41,3,114,245,0,0,0,114,88,1,0,0,114,95, - 1,0,0,114,4,0,0,0,41,2,114,245,0,0,0,114, - 88,1,0,0,114,5,0,0,0,218,9,112,97,116,104,95, - 104,111,111,107,227,7,0,0,115,4,0,0,0,0,10,21, - 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, - 1,0,0,0,2,0,0,0,67,0,0,0,115,16,0,0, - 0,100,1,0,106,0,0,124,0,0,106,1,0,131,1,0, - 83,41,2,78,122,16,70,105,108,101,70,105,110,100,101,114, - 40,123,33,114,125,41,41,2,114,47,0,0,0,114,35,0, - 0,0,41,1,114,71,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,101,0,0,0,245,7,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,15,114, - 57,0,0,0,114,56,0,0,0,114,58,0,0,0,114,59, - 0,0,0,114,72,0,0,0,114,70,1,0,0,114,172,0, - 0,0,114,11,1,0,0,114,165,0,0,0,114,81,1,0, - 0,114,10,1,0,0,114,89,1,0,0,114,7,1,0,0, - 114,96,1,0,0,114,101,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,82, - 1,0,0,104,7,0,0,115,20,0,0,0,12,7,6,2, - 12,14,12,4,6,2,12,8,12,10,15,45,12,31,18,18, - 114,82,1,0,0,99,0,0,0,0,0,0,0,0,0,0, - 0,0,2,0,0,0,64,0,0,0,115,46,0,0,0,101, - 0,0,90,1,0,100,0,0,90,2,0,100,1,0,90,3, - 0,100,2,0,100,3,0,132,0,0,90,4,0,100,4,0, - 100,5,0,132,0,0,90,5,0,100,6,0,83,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,1,0,0,0,1,0,0,0,67,0,0,0,115,14, - 0,0,0,116,0,0,106,1,0,131,0,0,1,100,1,0, - 83,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,106,0,0,0,114,2,1,0,0,41,1,114,71,0,0, - 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,75,0,0,0,255,7,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,4,0,0,0,1,0,0,0,67, - 0,0,0,115,14,0,0,0,116,0,0,106,1,0,131,0, - 0,1,100,1,0,83,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,106,0,0,0,114,107, - 0,0,0,41,4,114,71,0,0,0,90,8,101,120,99,95, - 116,121,112,101,90,9,101,120,99,95,118,97,108,117,101,90, - 13,101,120,99,95,116,114,97,99,101,98,97,99,107,114,4, - 0,0,0,114,4,0,0,0,114,5,0,0,0,114,81,0, - 0,0,3,8,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,57,0, - 0,0,114,56,0,0,0,114,58,0,0,0,114,59,0,0, - 0,114,75,0,0,0,114,81,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, - 97,1,0,0,251,7,0,0,115,6,0,0,0,12,2,6, - 2,12,4,114,97,1,0,0,99,3,0,0,0,0,0,0, - 0,5,0,0,0,4,0,0,0,67,0,0,0,115,91,0, - 0,0,124,1,0,106,0,0,100,1,0,124,2,0,100,2, - 0,24,131,2,0,125,3,0,116,1,0,124,3,0,131,1, - 0,124,2,0,107,0,0,114,55,0,116,2,0,100,3,0, - 131,1,0,130,1,0,110,0,0,124,3,0,100,4,0,25, - 125,4,0,124,0,0,114,87,0,100,5,0,106,3,0,124, - 4,0,124,0,0,131,2,0,83,124,4,0,83,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,116,0,0,0,114,29,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,84,0,0,0,122,5,123,125,46,123,125,41,4,114, - 34,0,0,0,114,31,0,0,0,114,133,0,0,0,114,47, - 0,0,0,41,5,114,67,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,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,218,13,95,114,101,115,111,108,118,101,95, - 110,97,109,101,8,8,0,0,115,10,0,0,0,0,2,22, - 1,18,1,15,1,10,1,114,100,1,0,0,99,3,0,0, - 0,0,0,0,0,10,0,0,0,27,0,0,0,67,0,0, - 0,115,49,1,0,0,116,0,0,106,1,0,115,28,0,116, - 2,0,106,3,0,100,1,0,116,4,0,131,2,0,1,110, - 0,0,124,0,0,116,0,0,106,5,0,107,6,0,125,3, - 0,120,255,0,116,0,0,106,1,0,68,93,240,0,125,4, - 0,116,6,0,131,0,0,143,108,0,1,121,13,0,124,4, - 0,106,7,0,125,5,0,87,110,69,0,4,116,8,0,107, - 10,0,114,153,0,1,1,1,124,4,0,106,9,0,124,0, - 0,124,1,0,131,2,0,125,6,0,124,6,0,100,2,0, - 107,8,0,114,134,0,119,53,0,110,0,0,116,10,0,124, - 0,0,124,6,0,131,2,0,125,7,0,89,110,19,0,88, - 124,5,0,124,0,0,124,1,0,124,2,0,131,3,0,125, - 7,0,87,100,2,0,81,88,124,7,0,100,2,0,107,9, - 0,114,53,0,124,3,0,12,114,30,1,124,0,0,116,0, - 0,106,5,0,107,6,0,114,30,1,116,0,0,106,5,0, - 124,0,0,25,125,8,0,121,13,0,124,8,0,106,11,0, - 125,9,0,87,110,22,0,4,116,8,0,107,10,0,114,6, - 1,1,1,1,124,7,0,83,89,113,34,1,88,124,9,0, - 100,2,0,107,8,0,114,23,1,124,7,0,83,124,9,0, - 83,113,37,1,124,7,0,83,113,53,0,113,53,0,87,100, - 2,0,83,100,2,0,83,41,3,122,23,70,105,110,100,32, - 97,32,109,111,100,117,108,101,39,115,32,108,111,97,100,101, - 114,46,122,22,115,121,115,46,109,101,116,97,95,112,97,116, - 104,32,105,115,32,101,109,112,116,121,78,41,12,114,7,0, - 0,0,218,9,109,101,116,97,95,112,97,116,104,114,166,0, - 0,0,114,167,0,0,0,114,168,0,0,0,114,73,0,0, - 0,114,97,1,0,0,114,10,1,0,0,114,209,0,0,0, - 114,11,1,0,0,114,173,0,0,0,114,208,0,0,0,41, - 10,114,67,0,0,0,114,35,0,0,0,114,9,1,0,0, - 90,9,105,115,95,114,101,108,111,97,100,114,73,1,0,0, - 114,10,1,0,0,114,169,0,0,0,114,177,0,0,0,114, - 179,0,0,0,114,208,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,244,0,0,0,17,8,0, - 0,115,50,0,0,0,0,2,9,1,19,4,15,1,16,1, - 10,1,3,1,13,1,13,1,18,1,12,1,6,1,20,2, - 24,1,12,2,22,1,13,1,3,1,13,1,13,4,9,2, - 12,1,4,2,7,2,11,2,114,244,0,0,0,99,3,0, - 0,0,0,0,0,0,4,0,0,0,4,0,0,0,67,0, - 0,0,115,194,0,0,0,116,0,0,124,0,0,116,1,0, - 131,2,0,115,45,0,116,2,0,100,1,0,106,3,0,116, - 4,0,124,0,0,131,1,0,131,1,0,131,1,0,130,1, - 0,110,0,0,124,2,0,100,2,0,107,0,0,114,72,0, - 116,5,0,100,3,0,131,1,0,130,1,0,110,0,0,124, - 1,0,114,156,0,116,0,0,124,1,0,116,1,0,131,2, - 0,115,108,0,116,2,0,100,4,0,131,1,0,130,1,0, - 113,156,0,124,1,0,116,6,0,106,7,0,107,7,0,114, - 156,0,100,5,0,125,3,0,116,8,0,124,3,0,106,3, - 0,124,1,0,131,1,0,131,1,0,130,1,0,113,156,0, - 110,0,0,124,0,0,12,114,190,0,124,2,0,100,2,0, - 107,2,0,114,190,0,116,5,0,100,6,0,131,1,0,130, - 1,0,110,0,0,100,7,0,83,41,8,122,28,86,101,114, + 0,100,5,0,132,0,0,90,5,0,100,6,0,83,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,1,0,0,0,1,0,0,0,67,0,0,0,115, + 14,0,0,0,116,0,0,106,1,0,131,0,0,1,100,1, + 0,83,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,145,0,0,0,41,1,114,19,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,23,0,0,0,84,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,4,0,0,0,1,0,0,0, + 67,0,0,0,115,14,0,0,0,116,0,0,106,1,0,131, + 0,0,1,100,1,0,83,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, + 58,0,0,0,41,4,114,19,0,0,0,90,8,101,120,99, + 95,116,121,112,101,90,9,101,120,99,95,118,97,108,117,101, + 90,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,30, + 0,0,0,88,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,23,0,0,0,114,30,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 114,165,0,0,0,80,3,0,0,115,6,0,0,0,12,2, + 6,2,12,4,114,165,0,0,0,99,3,0,0,0,0,0, + 0,0,5,0,0,0,4,0,0,0,67,0,0,0,115,88, + 0,0,0,124,1,0,106,0,0,100,1,0,124,2,0,100, + 2,0,24,131,2,0,125,3,0,116,1,0,124,3,0,131, + 1,0,124,2,0,107,0,0,114,52,0,116,2,0,100,3, + 0,131,1,0,130,1,0,124,3,0,100,4,0,25,125,4, + 0,124,0,0,114,84,0,100,5,0,106,3,0,124,4,0, + 124,0,0,131,2,0,83,124,4,0,83,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,121,0,0,0,114,45,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, + 33,0,0,0,122,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,50,0,0,0,41,5,114,15,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,93,3,0,0, + 115,10,0,0,0,0,2,22,1,18,1,12,1,10,1,114, + 171,0,0,0,99,3,0,0,0,0,0,0,0,4,0,0, + 0,3,0,0,0,67,0,0,0,115,47,0,0,0,124,0, + 0,106,0,0,124,1,0,124,2,0,131,2,0,125,3,0, + 124,3,0,100,0,0,107,8,0,114,34,0,100,0,0,83, + 116,1,0,124,1,0,124,3,0,131,2,0,83,41,1,78, + 41,2,114,155,0,0,0,114,85,0,0,0,41,4,218,6, + 102,105,110,100,101,114,114,15,0,0,0,114,152,0,0,0, + 114,99,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,102,3,0,0,115,8,0,0,0, + 0,3,18,1,12,1,4,1,114,173,0,0,0,99,3,0, + 0,0,0,0,0,0,9,0,0,0,27,0,0,0,67,0, + 0,0,115,42,1,0,0,116,0,0,106,1,0,100,1,0, + 107,9,0,114,41,0,116,0,0,106,1,0,12,114,41,0, + 116,2,0,106,3,0,100,2,0,116,4,0,131,2,0,1, + 124,0,0,116,0,0,106,5,0,107,6,0,125,3,0,120, + 235,0,116,0,0,106,1,0,68,93,220,0,125,4,0,116, + 6,0,131,0,0,143,90,0,1,121,13,0,124,4,0,106, + 7,0,125,5,0,87,110,51,0,4,116,8,0,107,10,0, + 114,148,0,1,1,1,116,9,0,124,4,0,124,0,0,124, + 1,0,131,3,0,125,6,0,124,6,0,100,1,0,107,8, + 0,114,144,0,119,66,0,89,110,19,0,88,124,5,0,124, + 0,0,124,1,0,124,2,0,131,3,0,125,6,0,87,100, + 1,0,81,82,88,124,6,0,100,1,0,107,9,0,114,66, + 0,124,3,0,12,114,26,1,124,0,0,116,0,0,106,5, + 0,107,6,0,114,26,1,116,0,0,106,5,0,124,0,0, + 25,125,7,0,121,13,0,124,7,0,106,10,0,125,8,0, + 87,110,22,0,4,116,8,0,107,10,0,114,2,1,1,1, + 1,124,6,0,83,89,113,30,1,88,124,8,0,100,1,0, + 107,8,0,114,19,1,124,6,0,83,124,8,0,83,113,66, + 0,124,6,0,83,113,66,0,87,100,1,0,83,100,1,0, + 83,41,3,122,23,70,105,110,100,32,97,32,109,111,100,117, + 108,101,39,115,32,108,111,97,100,101,114,46,78,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,11,114,14,0,0,0,218,9,109,101, + 116,97,95,112,97,116,104,114,141,0,0,0,114,142,0,0, + 0,218,13,73,109,112,111,114,116,87,97,114,110,105,110,103, + 114,21,0,0,0,114,165,0,0,0,114,154,0,0,0,114, + 96,0,0,0,114,173,0,0,0,114,95,0,0,0,41,9, + 114,15,0,0,0,114,152,0,0,0,114,153,0,0,0,90, + 9,105,115,95,114,101,108,111,97,100,114,172,0,0,0,114, + 154,0,0,0,114,88,0,0,0,114,89,0,0,0,114,95, + 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,111,3, + 0,0,115,48,0,0,0,0,2,25,1,16,4,15,1,16, + 1,10,1,3,1,13,1,13,1,18,1,12,1,8,2,25, + 1,12,2,22,1,13,1,3,1,13,1,13,4,9,2,12, + 1,4,2,7,2,8,2,114,176,0,0,0,99,3,0,0, + 0,0,0,0,0,4,0,0,0,4,0,0,0,67,0,0, + 0,115,179,0,0,0,116,0,0,124,0,0,116,1,0,131, + 2,0,115,42,0,116,2,0,100,1,0,106,3,0,116,4, + 0,124,0,0,131,1,0,131,1,0,131,1,0,130,1,0, + 124,2,0,100,2,0,107,0,0,114,66,0,116,5,0,100, + 3,0,131,1,0,130,1,0,124,1,0,114,144,0,116,0, + 0,124,1,0,116,1,0,131,2,0,115,102,0,116,2,0, + 100,4,0,131,1,0,130,1,0,110,42,0,124,1,0,116, + 6,0,106,7,0,107,7,0,114,144,0,100,5,0,125,3, + 0,116,8,0,124,3,0,106,3,0,124,1,0,131,1,0, + 131,1,0,130,1,0,124,0,0,12,114,175,0,124,2,0, + 100,2,0,107,2,0,114,175,0,116,5,0,100,6,0,131, + 1,0,130,1,0,100,7,0,83,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,84,0,0,0,122, + 116,114,44,32,110,111,116,32,123,125,114,33,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, @@ -3806,456 +1635,354 @@ const unsigned char _Py_M__importlib[] = { 100,101,100,44,32,99,97,110,110,111,116,32,112,101,114,102, 111,114,109,32,114,101,108,97,116,105,118,101,32,105,109,112, 111,114,116,122,17,69,109,112,116,121,32,109,111,100,117,108, - 101,32,110,97,109,101,78,41,9,114,192,0,0,0,114,78, - 1,0,0,218,9,84,121,112,101,69,114,114,111,114,114,47, - 0,0,0,114,66,0,0,0,114,133,0,0,0,114,7,0, - 0,0,114,73,0,0,0,218,11,83,121,115,116,101,109,69, - 114,114,111,114,41,4,114,67,0,0,0,114,98,1,0,0, - 114,99,1,0,0,114,171,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,218,13,95,115,97,110,105, - 116,121,95,99,104,101,99,107,58,8,0,0,115,24,0,0, - 0,0,2,15,1,30,1,12,1,15,1,6,1,15,1,15, - 1,15,1,6,2,27,1,19,1,114,104,1,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,8, - 0,0,0,12,0,0,0,67,0,0,0,115,52,1,0,0, - 100,0,0,125,2,0,124,0,0,106,0,0,100,1,0,131, - 1,0,100,2,0,25,125,3,0,124,3,0,114,178,0,124, - 3,0,116,1,0,106,2,0,107,7,0,114,62,0,116,3, - 0,124,1,0,124,3,0,131,2,0,1,110,0,0,124,0, - 0,116,1,0,106,2,0,107,6,0,114,88,0,116,1,0, - 106,2,0,124,0,0,25,83,116,1,0,106,2,0,124,3, - 0,25,125,4,0,121,13,0,124,4,0,106,4,0,125,2, - 0,87,113,178,0,4,116,5,0,107,10,0,114,174,0,1, - 1,1,116,6,0,100,3,0,23,106,7,0,124,0,0,124, - 3,0,131,2,0,125,5,0,116,8,0,124,5,0,100,4, - 0,124,0,0,131,1,1,130,1,0,89,113,178,0,88,110, - 0,0,116,9,0,124,0,0,124,2,0,131,2,0,125,6, - 0,124,6,0,100,0,0,107,8,0,114,235,0,116,8,0, - 116,6,0,106,7,0,124,0,0,131,1,0,100,4,0,124, - 0,0,131,1,1,130,1,0,110,18,0,116,10,0,124,6, - 0,131,1,0,106,11,0,131,0,0,125,7,0,124,3,0, - 114,48,1,116,1,0,106,2,0,124,3,0,25,125,4,0, - 116,12,0,124,4,0,124,0,0,106,0,0,100,1,0,131, - 1,0,100,5,0,25,124,7,0,131,3,0,1,110,0,0, - 124,7,0,83,41,6,78,114,116,0,0,0,114,84,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,67,0,0,0,114, - 115,0,0,0,41,13,114,32,0,0,0,114,7,0,0,0, - 114,73,0,0,0,114,114,0,0,0,114,242,0,0,0,114, - 209,0,0,0,218,8,95,69,82,82,95,77,83,71,114,47, - 0,0,0,114,153,0,0,0,114,244,0,0,0,114,174,0, - 0,0,114,6,1,0,0,114,61,0,0,0,41,8,114,67, - 0,0,0,218,7,105,109,112,111,114,116,95,114,35,0,0, - 0,114,231,0,0,0,90,13,112,97,114,101,110,116,95,109, - 111,100,117,108,101,114,171,0,0,0,114,177,0,0,0,114, - 179,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 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,78,8,0,0, - 115,42,0,0,0,0,1,6,1,19,1,6,1,15,1,16, - 2,15,1,11,1,13,1,3,1,13,1,13,1,22,1,26, - 1,15,1,12,1,30,2,18,1,6,2,13,1,32,1,114, - 107,1,0,0,99,2,0,0,0,0,0,0,0,2,0,0, - 0,10,0,0,0,67,0,0,0,115,36,0,0,0,116,0, - 0,124,0,0,131,1,0,143,18,0,1,116,1,0,124,0, - 0,124,1,0,131,2,0,83,87,100,1,0,81,88,100,1, - 0,83,41,2,122,54,70,105,110,100,32,97,110,100,32,108, - 111,97,100,32,116,104,101,32,109,111,100,117,108,101,44,32, - 97,110,100,32,114,101,108,101,97,115,101,32,116,104,101,32, - 105,109,112,111,114,116,32,108,111,99,107,46,78,41,2,114, - 103,0,0,0,114,107,1,0,0,41,2,114,67,0,0,0, - 114,106,1,0,0,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,218,14,95,102,105,110,100,95,97,110,100,95, - 108,111,97,100,105,8,0,0,115,4,0,0,0,0,2,13, - 1,114,108,1,0,0,99,3,0,0,0,0,0,0,0,5, - 0,0,0,4,0,0,0,67,0,0,0,115,172,0,0,0, - 116,0,0,124,0,0,124,1,0,124,2,0,131,3,0,1, - 124,2,0,100,1,0,107,4,0,114,49,0,116,1,0,124, - 0,0,124,1,0,124,2,0,131,3,0,125,0,0,110,0, - 0,116,2,0,106,3,0,131,0,0,1,124,0,0,116,4, - 0,106,5,0,107,7,0,114,87,0,116,6,0,124,0,0, - 116,7,0,131,2,0,83,116,4,0,106,5,0,124,0,0, - 25,125,3,0,124,3,0,100,2,0,107,8,0,114,158,0, - 116,2,0,106,8,0,131,0,0,1,100,3,0,106,9,0, - 124,0,0,131,1,0,125,4,0,116,10,0,124,4,0,100, - 4,0,124,0,0,131,1,1,130,1,0,110,0,0,116,11, - 0,124,0,0,131,1,0,1,124,3,0,83,41,5,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,84,0,0,0,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,67,0,0,0,41,12,114,104,1,0, - 0,114,100,1,0,0,114,106,0,0,0,114,2,1,0,0, - 114,7,0,0,0,114,73,0,0,0,114,108,1,0,0,218, - 11,95,103,99,100,95,105,109,112,111,114,116,114,107,0,0, - 0,114,47,0,0,0,114,153,0,0,0,114,112,0,0,0, - 41,5,114,67,0,0,0,114,98,1,0,0,114,99,1,0, - 0,114,179,0,0,0,114,151,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,114,109,1,0,0,111, - 8,0,0,115,26,0,0,0,0,9,16,1,12,1,21,1, - 10,1,15,1,13,1,13,1,12,1,10,2,15,1,21,1, - 10,1,114,109,1,0,0,99,3,0,0,0,0,0,0,0, - 6,0,0,0,17,0,0,0,67,0,0,0,115,1,1,0, - 0,116,0,0,124,0,0,100,1,0,131,2,0,114,253,0, - 100,2,0,124,1,0,107,6,0,114,89,0,116,1,0,124, - 1,0,131,1,0,125,1,0,124,1,0,106,2,0,100,2, - 0,131,1,0,1,116,0,0,124,0,0,100,3,0,131,2, - 0,114,89,0,124,1,0,106,3,0,124,0,0,106,4,0, - 131,1,0,1,113,89,0,110,0,0,120,161,0,124,1,0, - 68,93,150,0,125,3,0,116,0,0,124,0,0,124,3,0, - 131,2,0,115,96,0,100,4,0,106,5,0,124,0,0,106, - 6,0,124,3,0,131,2,0,125,4,0,121,17,0,116,7, - 0,124,2,0,124,4,0,131,2,0,1,87,113,246,0,4, - 116,8,0,107,10,0,114,242,0,1,125,5,0,1,122,53, - 0,116,9,0,124,5,0,131,1,0,106,10,0,116,11,0, - 131,1,0,114,221,0,124,5,0,106,12,0,124,4,0,107, - 2,0,114,221,0,119,96,0,113,221,0,110,0,0,130,0, - 0,87,89,100,5,0,100,5,0,125,5,0,126,5,0,88, - 113,246,0,88,113,96,0,113,96,0,87,110,0,0,124,0, - 0,83,41,6,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,114,242,0,0,0,250,1,42,218,7,95,95, - 97,108,108,95,95,122,5,123,125,46,123,125,78,41,13,114, - 60,0,0,0,114,241,0,0,0,218,6,114,101,109,111,118, - 101,114,197,0,0,0,114,111,1,0,0,114,47,0,0,0, - 114,57,0,0,0,114,114,0,0,0,114,153,0,0,0,114, - 78,1,0,0,114,9,0,0,0,218,15,95,69,82,82,95, - 77,83,71,95,80,82,69,70,73,88,114,67,0,0,0,41, - 6,114,179,0,0,0,218,8,102,114,111,109,108,105,115,116, - 114,106,1,0,0,114,16,0,0,0,90,9,102,114,111,109, - 95,110,97,109,101,114,36,1,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,218,16,95,104,97,110,100, - 108,101,95,102,114,111,109,108,105,115,116,135,8,0,0,115, - 34,0,0,0,0,10,15,1,12,1,12,1,13,1,15,1, - 22,1,13,1,15,1,21,1,3,1,17,1,18,4,21,1, - 15,1,9,1,32,1,114,115,1,0,0,99,1,0,0,0, - 0,0,0,0,2,0,0,0,2,0,0,0,67,0,0,0, - 115,78,0,0,0,124,0,0,106,0,0,100,1,0,131,1, - 0,125,1,0,124,1,0,100,2,0,107,8,0,114,74,0, - 124,0,0,100,3,0,25,125,1,0,100,4,0,124,0,0, - 107,7,0,114,74,0,124,1,0,106,1,0,100,5,0,131, - 1,0,100,6,0,25,125,1,0,113,74,0,110,0,0,124, - 1,0,83,41,7,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,249, - 0,0,0,78,114,57,0,0,0,114,242,0,0,0,114,116, - 0,0,0,114,84,0,0,0,41,2,114,93,0,0,0,114, - 32,0,0,0,41,2,218,7,103,108,111,98,97,108,115,114, - 98,1,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,17,95,99,97,108,99,95,95,95,112,97,99, - 107,97,103,101,95,95,167,8,0,0,115,12,0,0,0,0, - 7,15,1,12,1,10,1,12,1,25,1,114,117,1,0,0, - 99,0,0,0,0,0,0,0,0,3,0,0,0,3,0,0, - 0,67,0,0,0,115,55,0,0,0,116,0,0,116,1,0, - 106,2,0,131,0,0,102,2,0,125,0,0,116,3,0,116, - 4,0,102,2,0,125,1,0,116,5,0,116,6,0,102,2, - 0,125,2,0,124,0,0,124,1,0,124,2,0,103,3,0, - 83,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,52,1,0,0,114,106,0,0,0, - 218,18,101,120,116,101,110,115,105,111,110,95,115,117,102,102, - 105,120,101,115,114,47,1,0,0,114,134,0,0,0,114,51, - 1,0,0,114,230,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,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,114,236,0,0,0,182,8,0,0, - 115,8,0,0,0,0,5,18,1,12,1,12,1,114,236,0, - 0,0,99,5,0,0,0,0,0,0,0,9,0,0,0,5, - 0,0,0,67,0,0,0,115,227,0,0,0,124,4,0,100, - 1,0,107,2,0,114,27,0,116,0,0,124,0,0,131,1, - 0,125,5,0,110,54,0,124,1,0,100,2,0,107,9,0, - 114,45,0,124,1,0,110,3,0,105,0,0,125,6,0,116, - 1,0,124,6,0,131,1,0,125,7,0,116,0,0,124,0, - 0,124,7,0,124,4,0,131,3,0,125,5,0,124,3,0, - 115,207,0,124,4,0,100,1,0,107,2,0,114,122,0,116, - 0,0,124,0,0,106,2,0,100,3,0,131,1,0,100,1, - 0,25,131,1,0,83,124,0,0,115,132,0,124,5,0,83, - 116,3,0,124,0,0,131,1,0,116,3,0,124,0,0,106, - 2,0,100,3,0,131,1,0,100,1,0,25,131,1,0,24, - 125,8,0,116,4,0,106,5,0,124,5,0,106,6,0,100, - 2,0,116,3,0,124,5,0,106,6,0,131,1,0,124,8, - 0,24,133,2,0,25,25,83,110,16,0,116,7,0,124,5, - 0,124,3,0,116,0,0,131,3,0,83,100,2,0,83,41, - 4,97,214,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,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,84,0,0, - 0,78,114,116,0,0,0,41,8,114,109,1,0,0,114,117, - 1,0,0,114,121,0,0,0,114,31,0,0,0,114,7,0, - 0,0,114,73,0,0,0,114,57,0,0,0,114,115,1,0, - 0,41,9,114,67,0,0,0,114,116,1,0,0,218,6,108, - 111,99,97,108,115,114,114,1,0,0,114,99,1,0,0,114, - 179,0,0,0,90,8,103,108,111,98,97,108,115,95,114,98, - 1,0,0,90,7,99,117,116,95,111,102,102,114,4,0,0, - 0,114,4,0,0,0,114,5,0,0,0,218,10,95,95,105, - 109,112,111,114,116,95,95,193,8,0,0,115,26,0,0,0, - 0,11,12,1,15,2,24,1,12,1,18,1,6,3,12,1, - 23,1,6,1,4,4,35,3,40,2,114,120,1,0,0,99, - 1,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0, - 67,0,0,0,115,68,0,0,0,116,0,0,106,1,0,124, - 0,0,131,1,0,125,1,0,124,1,0,100,0,0,107,8, - 0,114,46,0,116,2,0,100,1,0,124,0,0,23,131,1, - 0,130,1,0,110,0,0,116,3,0,124,1,0,131,1,0, - 125,2,0,124,2,0,106,4,0,131,0,0,83,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,5,114,8,1, - 0,0,114,10,1,0,0,114,153,0,0,0,114,174,0,0, - 0,114,6,1,0,0,41,3,114,67,0,0,0,114,177,0, - 0,0,114,178,0,0,0,114,4,0,0,0,114,4,0,0, - 0,114,5,0,0,0,218,18,95,98,117,105,108,116,105,110, - 95,102,114,111,109,95,110,97,109,101,228,8,0,0,115,10, - 0,0,0,0,1,15,1,12,1,19,1,12,1,114,121,1, - 0,0,99,2,0,0,0,0,0,0,0,19,0,0,0,12, - 0,0,0,67,0,0,0,115,232,2,0,0,124,1,0,97, - 0,0,124,0,0,97,1,0,116,1,0,106,2,0,106,3, - 0,114,33,0,116,4,0,97,5,0,110,6,0,116,6,0, - 97,5,0,116,7,0,116,1,0,131,1,0,125,2,0,120, - 138,0,116,1,0,106,8,0,106,9,0,131,0,0,68,93, - 121,0,92,2,0,125,3,0,125,4,0,116,10,0,124,4, - 0,124,2,0,131,2,0,114,67,0,124,3,0,116,1,0, - 106,11,0,107,6,0,114,118,0,116,12,0,125,5,0,110, - 27,0,116,0,0,106,13,0,124,3,0,131,1,0,114,67, - 0,116,14,0,125,5,0,110,3,0,113,67,0,116,15,0, - 124,4,0,124,5,0,131,2,0,125,6,0,116,16,0,124, - 6,0,131,1,0,125,7,0,124,7,0,106,17,0,124,4, - 0,131,1,0,1,113,67,0,113,67,0,87,116,1,0,106, - 8,0,116,18,0,25,125,8,0,120,73,0,100,26,0,68, - 93,65,0,125,9,0,124,9,0,116,1,0,106,8,0,107, - 7,0,114,248,0,116,19,0,124,9,0,131,1,0,125,10, - 0,110,13,0,116,1,0,106,8,0,124,9,0,25,125,10, - 0,116,20,0,124,8,0,124,9,0,124,10,0,131,3,0, - 1,113,212,0,87,100,5,0,100,6,0,103,1,0,102,2, - 0,100,7,0,100,8,0,100,6,0,103,2,0,102,2,0, - 102,2,0,125,11,0,120,146,0,124,11,0,68,93,126,0, - 92,2,0,125,12,0,125,13,0,116,21,0,100,9,0,100, - 10,0,132,0,0,124,13,0,68,131,1,0,131,1,0,115, - 108,1,116,22,0,130,1,0,124,13,0,100,11,0,25,125, - 14,0,124,12,0,116,1,0,106,8,0,107,6,0,114,150, - 1,116,1,0,106,8,0,124,12,0,25,125,15,0,80,113, - 65,1,121,17,0,116,19,0,124,12,0,131,1,0,125,15, - 0,80,87,113,65,1,4,116,23,0,107,10,0,114,190,1, - 1,1,1,119,65,1,89,113,65,1,88,113,65,1,87,116, - 23,0,100,12,0,131,1,0,130,1,0,116,20,0,124,8, - 0,100,13,0,124,15,0,131,3,0,1,116,20,0,124,8, - 0,100,14,0,124,14,0,131,3,0,1,116,20,0,124,8, - 0,100,15,0,100,16,0,106,24,0,124,13,0,131,1,0, - 131,3,0,1,121,16,0,116,19,0,100,17,0,131,1,0, - 125,16,0,87,110,24,0,4,116,23,0,107,10,0,114,50, - 2,1,1,1,100,18,0,125,16,0,89,110,1,0,88,116, - 20,0,124,8,0,100,17,0,124,16,0,131,3,0,1,116, - 19,0,100,19,0,131,1,0,125,17,0,116,20,0,124,8, - 0,100,19,0,124,17,0,131,3,0,1,124,12,0,100,7, - 0,107,2,0,114,138,2,116,19,0,100,20,0,131,1,0, - 125,18,0,116,20,0,124,8,0,100,21,0,124,18,0,131, - 3,0,1,110,0,0,116,20,0,124,8,0,100,22,0,116, - 25,0,131,0,0,131,3,0,1,116,26,0,106,27,0,116, - 0,0,106,28,0,131,0,0,131,1,0,1,124,12,0,100, - 7,0,107,2,0,114,228,2,116,29,0,106,30,0,100,23, - 0,131,1,0,1,100,24,0,116,26,0,107,6,0,114,228, - 2,100,25,0,116,31,0,95,32,0,113,228,2,110,0,0, - 100,18,0,83,41,27,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,114,49,0,0,0,114,166,0,0,0,218,8,98,117, - 105,108,116,105,110,115,114,191,0,0,0,90,5,112,111,115, - 105,120,250,1,47,218,2,110,116,250,1,92,99,1,0,0, - 0,0,0,0,0,2,0,0,0,3,0,0,0,115,0,0, - 0,115,33,0,0,0,124,0,0,93,23,0,125,1,0,116, - 0,0,124,1,0,131,1,0,100,0,0,107,2,0,86,1, - 113,3,0,100,1,0,83,41,2,114,29,0,0,0,78,41, - 1,114,31,0,0,0,41,2,114,22,0,0,0,114,130,0, - 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, - 0,114,77,0,0,0,24,9,0,0,115,2,0,0,0,6, - 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,84,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,3,0,0,0,114,25,0,0,0,114,21,0,0,0, - 114,30,0,0,0,114,85,0,0,0,78,114,111,0,0,0, - 90,6,119,105,110,114,101,103,114,19,1,0,0,114,6,0, - 0,0,122,4,46,112,121,119,122,6,95,100,46,112,121,100, - 84,41,4,122,3,95,105,111,122,9,95,119,97,114,110,105, - 110,103,115,122,8,98,117,105,108,116,105,110,115,122,7,109, - 97,114,115,104,97,108,41,33,114,106,0,0,0,114,7,0, - 0,0,114,117,0,0,0,114,118,0,0,0,114,120,0,0, - 0,114,230,0,0,0,114,119,0,0,0,114,66,0,0,0, - 114,73,0,0,0,218,5,105,116,101,109,115,114,192,0,0, - 0,114,157,0,0,0,114,8,1,0,0,114,162,0,0,0, - 114,15,1,0,0,114,243,0,0,0,114,174,0,0,0,114, - 253,0,0,0,114,57,0,0,0,114,121,1,0,0,114,61, - 0,0,0,218,3,97,108,108,114,100,0,0,0,114,153,0, - 0,0,114,26,0,0,0,114,11,0,0,0,114,55,1,0, - 0,114,197,0,0,0,114,118,1,0,0,114,134,0,0,0, - 114,223,0,0,0,114,18,1,0,0,114,22,1,0,0,41, - 19,218,10,115,121,115,95,109,111,100,117,108,101,218,11,95, + 101,32,110,97,109,101,78,41,9,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,50,0,0,0,114,13,0,0,0,114, + 168,0,0,0,114,14,0,0,0,114,21,0,0,0,218,11, + 83,121,115,116,101,109,69,114,114,111,114,41,4,114,15,0, + 0,0,114,169,0,0,0,114,170,0,0,0,114,147,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,151, + 3,0,0,115,24,0,0,0,0,2,15,1,27,1,12,1, + 12,1,6,1,15,1,15,1,15,1,6,2,21,1,19,1, + 114,181,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,8,0,0,0,12,0,0,0,67,0, + 0,0,115,40,1,0,0,100,0,0,125,2,0,124,0,0, + 106,0,0,100,1,0,131,1,0,100,2,0,25,125,3,0, + 124,3,0,114,175,0,124,3,0,116,1,0,106,2,0,107, + 7,0,114,59,0,116,3,0,124,1,0,124,3,0,131,2, + 0,1,124,0,0,116,1,0,106,2,0,107,6,0,114,85, + 0,116,1,0,106,2,0,124,0,0,25,83,116,1,0,106, + 2,0,124,3,0,25,125,4,0,121,13,0,124,4,0,106, + 4,0,125,2,0,87,110,61,0,4,116,5,0,107,10,0, + 114,174,0,1,1,1,116,6,0,100,3,0,23,106,7,0, + 124,0,0,124,3,0,131,2,0,125,5,0,116,8,0,124, + 5,0,100,4,0,124,0,0,131,1,1,100,0,0,130,2, + 0,89,110,1,0,88,116,9,0,124,0,0,124,2,0,131, + 2,0,125,6,0,124,6,0,100,0,0,107,8,0,114,232, + 0,116,8,0,116,6,0,106,7,0,124,0,0,131,1,0, + 100,4,0,124,0,0,131,1,1,130,1,0,110,12,0,116, + 10,0,124,6,0,131,1,0,125,7,0,124,3,0,114,36, + 1,116,1,0,106,2,0,124,3,0,25,125,4,0,116,11, + 0,124,4,0,124,0,0,106,0,0,100,1,0,131,1,0, + 100,5,0,25,124,7,0,131,3,0,1,124,7,0,83,41, + 6,78,114,121,0,0,0,114,33,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,15,0,0,0,114,140,0,0,0,41, + 12,114,122,0,0,0,114,14,0,0,0,114,21,0,0,0, + 114,65,0,0,0,114,131,0,0,0,114,96,0,0,0,218, + 8,95,69,82,82,95,77,83,71,114,50,0,0,0,114,77, + 0,0,0,114,176,0,0,0,114,149,0,0,0,114,5,0, + 0,0,41,8,114,15,0,0,0,218,7,105,109,112,111,114, + 116,95,114,152,0,0,0,114,123,0,0,0,90,13,112,97, + 114,101,110,116,95,109,111,100,117,108,101,114,147,0,0,0, + 114,88,0,0,0,114,89,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,171,3,0,0,115,42,0,0,0,0,1,6,1,19, + 1,6,1,15,1,13,2,15,1,11,1,13,1,3,1,13, + 1,13,1,22,1,26,1,15,1,12,1,30,2,12,1,6, + 2,13,1,29,1,114,184,0,0,0,99,2,0,0,0,0, + 0,0,0,2,0,0,0,10,0,0,0,67,0,0,0,115, + 37,0,0,0,116,0,0,124,0,0,131,1,0,143,18,0, + 1,116,1,0,124,0,0,124,1,0,131,2,0,83,87,100, + 1,0,81,82,88,100,1,0,83,41,2,122,54,70,105,110, + 100,32,97,110,100,32,108,111,97,100,32,116,104,101,32,109, + 111,100,117,108,101,44,32,97,110,100,32,114,101,108,101,97, + 115,101,32,116,104,101,32,105,109,112,111,114,116,32,108,111, + 99,107,46,78,41,2,114,54,0,0,0,114,184,0,0,0, + 41,2,114,15,0,0,0,114,183,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,198,3,0,0,115, + 4,0,0,0,0,2,13,1,114,185,0,0,0,114,33,0, + 0,0,99,3,0,0,0,0,0,0,0,5,0,0,0,4, + 0,0,0,67,0,0,0,115,166,0,0,0,116,0,0,124, + 0,0,124,1,0,124,2,0,131,3,0,1,124,2,0,100, + 1,0,107,4,0,114,46,0,116,1,0,124,0,0,124,1, + 0,124,2,0,131,3,0,125,0,0,116,2,0,106,3,0, + 131,0,0,1,124,0,0,116,4,0,106,5,0,107,7,0, + 114,84,0,116,6,0,124,0,0,116,7,0,131,2,0,83, + 116,4,0,106,5,0,124,0,0,25,125,3,0,124,3,0, + 100,2,0,107,8,0,114,152,0,116,2,0,106,8,0,131, + 0,0,1,100,3,0,106,9,0,124,0,0,131,1,0,125, + 4,0,116,10,0,124,4,0,100,4,0,124,0,0,131,1, + 1,130,1,0,116,11,0,124,0,0,131,1,0,1,124,3, + 0,83,41,5,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,33,0,0,0, + 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,15,0,0,0, + 41,12,114,181,0,0,0,114,171,0,0,0,114,57,0,0, + 0,114,145,0,0,0,114,14,0,0,0,114,21,0,0,0, + 114,185,0,0,0,218,11,95,103,99,100,95,105,109,112,111, + 114,116,114,58,0,0,0,114,50,0,0,0,114,77,0,0, + 0,114,63,0,0,0,41,5,114,15,0,0,0,114,169,0, + 0,0,114,170,0,0,0,114,89,0,0,0,114,74,0,0, + 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 114,186,0,0,0,204,3,0,0,115,28,0,0,0,0,9, + 16,1,12,1,18,1,10,1,15,1,13,1,13,1,12,1, + 10,1,6,1,9,1,18,1,10,1,114,186,0,0,0,99, + 3,0,0,0,0,0,0,0,6,0,0,0,17,0,0,0, + 67,0,0,0,115,239,0,0,0,116,0,0,124,0,0,100, + 1,0,131,2,0,114,235,0,100,2,0,124,1,0,107,6, + 0,114,83,0,116,1,0,124,1,0,131,1,0,125,1,0, + 124,1,0,106,2,0,100,2,0,131,1,0,1,116,0,0, + 124,0,0,100,3,0,131,2,0,114,83,0,124,1,0,106, + 3,0,124,0,0,106,4,0,131,1,0,1,120,149,0,124, + 1,0,68,93,141,0,125,3,0,116,0,0,124,0,0,124, + 3,0,131,2,0,115,90,0,100,4,0,106,5,0,124,0, + 0,106,6,0,124,3,0,131,2,0,125,4,0,121,17,0, + 116,7,0,124,2,0,124,4,0,131,2,0,1,87,113,90, + 0,4,116,8,0,107,10,0,114,230,0,1,125,5,0,1, + 122,47,0,116,9,0,124,5,0,131,1,0,106,10,0,116, + 11,0,131,1,0,114,209,0,124,5,0,106,12,0,124,4, + 0,107,2,0,114,209,0,119,90,0,130,0,0,87,89,100, + 5,0,100,5,0,125,5,0,126,5,0,88,113,90,0,88, + 113,90,0,87,124,0,0,83,41,6,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,114,131,0,0,0,250, + 1,42,218,7,95,95,97,108,108,95,95,122,5,123,125,46, + 123,125,78,41,13,114,4,0,0,0,114,130,0,0,0,218, + 6,114,101,109,111,118,101,218,6,101,120,116,101,110,100,114, + 188,0,0,0,114,50,0,0,0,114,1,0,0,0,114,65, + 0,0,0,114,77,0,0,0,114,178,0,0,0,114,71,0, + 0,0,218,15,95,69,82,82,95,77,83,71,95,80,82,69, + 70,73,88,114,15,0,0,0,41,6,114,89,0,0,0,218, + 8,102,114,111,109,108,105,115,116,114,183,0,0,0,218,1, + 120,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, + 218,16,95,104,97,110,100,108,101,95,102,114,111,109,108,105, + 115,116,228,3,0,0,115,34,0,0,0,0,10,15,1,12, + 1,12,1,13,1,15,1,16,1,13,1,15,1,21,1,3, + 1,17,1,18,4,21,1,15,1,3,1,26,1,114,194,0, + 0,0,99,1,0,0,0,0,0,0,0,2,0,0,0,2, + 0,0,0,67,0,0,0,115,72,0,0,0,124,0,0,106, + 0,0,100,1,0,131,1,0,125,1,0,124,1,0,100,2, + 0,107,8,0,114,68,0,124,0,0,100,3,0,25,125,1, + 0,100,4,0,124,0,0,107,7,0,114,68,0,124,1,0, + 106,1,0,100,5,0,131,1,0,100,6,0,25,125,1,0, + 124,1,0,83,41,7,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, + 134,0,0,0,78,114,1,0,0,0,114,131,0,0,0,114, + 121,0,0,0,114,33,0,0,0,41,2,114,42,0,0,0, + 114,122,0,0,0,41,2,218,7,103,108,111,98,97,108,115, + 114,169,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,4,4,0,0,115,12,0,0,0, + 0,7,15,1,12,1,10,1,12,1,19,1,114,196,0,0, + 0,99,5,0,0,0,0,0,0,0,9,0,0,0,5,0, + 0,0,67,0,0,0,115,227,0,0,0,124,4,0,100,1, + 0,107,2,0,114,27,0,116,0,0,124,0,0,131,1,0, + 125,5,0,110,54,0,124,1,0,100,2,0,107,9,0,114, + 45,0,124,1,0,110,3,0,105,0,0,125,6,0,116,1, + 0,124,6,0,131,1,0,125,7,0,116,0,0,124,0,0, + 124,7,0,124,4,0,131,3,0,125,5,0,124,3,0,115, + 207,0,124,4,0,100,1,0,107,2,0,114,122,0,116,0, + 0,124,0,0,106,2,0,100,3,0,131,1,0,100,1,0, + 25,131,1,0,83,124,0,0,115,132,0,124,5,0,83,116, + 3,0,124,0,0,131,1,0,116,3,0,124,0,0,106,2, + 0,100,3,0,131,1,0,100,1,0,25,131,1,0,24,125, + 8,0,116,4,0,106,5,0,124,5,0,106,6,0,100,2, + 0,116,3,0,124,5,0,106,6,0,131,1,0,124,8,0, + 24,133,2,0,25,25,83,110,16,0,116,7,0,124,5,0, + 124,3,0,116,0,0,131,3,0,83,100,2,0,83,41,4, + 97,214,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,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,33,0,0,0, + 78,114,121,0,0,0,41,8,114,186,0,0,0,114,196,0, + 0,0,218,9,112,97,114,116,105,116,105,111,110,114,167,0, + 0,0,114,14,0,0,0,114,21,0,0,0,114,1,0,0, + 0,114,194,0,0,0,41,9,114,15,0,0,0,114,195,0, + 0,0,218,6,108,111,99,97,108,115,114,192,0,0,0,114, + 170,0,0,0,114,89,0,0,0,90,8,103,108,111,98,97, + 108,115,95,114,169,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,19,4,0,0, + 115,26,0,0,0,0,11,12,1,15,2,24,1,12,1,18, + 1,6,3,12,1,23,1,6,1,4,4,35,3,40,2,114, + 199,0,0,0,99,1,0,0,0,0,0,0,0,2,0,0, + 0,3,0,0,0,67,0,0,0,115,53,0,0,0,116,0, + 0,106,1,0,124,0,0,131,1,0,125,1,0,124,1,0, + 100,0,0,107,8,0,114,43,0,116,2,0,100,1,0,124, + 0,0,23,131,1,0,130,1,0,116,3,0,124,1,0,131, + 1,0,83,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,150,0,0,0,114,154,0,0,0,114,77,0, + 0,0,114,149,0,0,0,41,2,114,15,0,0,0,114,88, + 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,54,4,0,0,115,8,0,0,0,0, + 1,15,1,12,1,16,1,114,200,0,0,0,99,2,0,0, + 0,0,0,0,0,12,0,0,0,12,0,0,0,67,0,0, + 0,115,74,1,0,0,124,1,0,97,0,0,124,0,0,97, + 1,0,116,2,0,116,1,0,131,1,0,125,2,0,120,123, + 0,116,1,0,106,3,0,106,4,0,131,0,0,68,93,106, + 0,92,2,0,125,3,0,125,4,0,116,5,0,124,4,0, + 124,2,0,131,2,0,114,40,0,124,3,0,116,1,0,106, + 6,0,107,6,0,114,91,0,116,7,0,125,5,0,110,27, + 0,116,0,0,106,8,0,124,3,0,131,1,0,114,40,0, + 116,9,0,125,5,0,110,3,0,113,40,0,116,10,0,124, + 4,0,124,5,0,131,2,0,125,6,0,116,11,0,124,6, + 0,124,4,0,131,2,0,1,113,40,0,87,116,1,0,106, + 3,0,116,12,0,25,125,7,0,120,73,0,100,5,0,68, + 93,65,0,125,8,0,124,8,0,116,1,0,106,3,0,107, + 7,0,114,206,0,116,13,0,124,8,0,131,1,0,125,9, + 0,110,13,0,116,1,0,106,3,0,124,8,0,25,125,9, + 0,116,14,0,124,7,0,124,8,0,124,9,0,131,3,0, + 1,113,170,0,87,121,16,0,116,13,0,100,2,0,131,1, + 0,125,10,0,87,110,24,0,4,116,15,0,107,10,0,114, + 25,1,1,1,1,100,3,0,125,10,0,89,110,1,0,88, + 116,14,0,124,7,0,100,2,0,124,10,0,131,3,0,1, + 116,13,0,100,4,0,131,1,0,125,11,0,116,14,0,124, + 7,0,100,4,0,124,11,0,131,3,0,1,100,3,0,83, + 41,6,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,114,141, + 0,0,0,114,34,0,0,0,78,114,62,0,0,0,41,1, + 122,9,95,119,97,114,110,105,110,103,115,41,16,114,57,0, + 0,0,114,14,0,0,0,114,13,0,0,0,114,21,0,0, + 0,218,5,105,116,101,109,115,114,177,0,0,0,114,76,0, + 0,0,114,150,0,0,0,114,82,0,0,0,114,160,0,0, + 0,114,132,0,0,0,114,137,0,0,0,114,1,0,0,0, + 114,200,0,0,0,114,5,0,0,0,114,77,0,0,0,41, + 12,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,67,0,0,0,114,179,0,0, - 0,114,169,0,0,0,114,177,0,0,0,114,178,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,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,21,0,0,0,114,25,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,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,218,6,95,115,101,116,117,112,236,8,0, - 0,115,108,0,0,0,0,9,6,1,6,2,12,1,9,2, - 6,3,12,1,28,1,15,1,15,1,9,1,15,1,9,2, - 3,1,15,1,12,1,20,3,13,1,13,1,15,1,15,2, - 13,1,20,3,33,1,19,2,31,1,10,1,15,1,13,1, - 4,2,3,1,12,1,5,1,13,1,12,2,12,1,16,1, - 16,1,25,3,3,1,16,1,13,2,11,1,16,3,12,1, - 16,3,12,1,12,1,19,3,19,1,19,1,12,1,13,1, - 12,1,114,130,1,0,0,99,2,0,0,0,0,0,0,0, - 3,0,0,0,3,0,0,0,67,0,0,0,115,136,0,0, - 0,116,0,0,124,0,0,124,1,0,131,2,0,1,116,1, - 0,131,0,0,125,2,0,116,2,0,106,3,0,106,4,0, - 116,5,0,106,6,0,124,2,0,140,0,0,103,1,0,131, - 1,0,1,116,2,0,106,7,0,106,8,0,116,9,0,131, - 1,0,1,116,2,0,106,7,0,106,8,0,116,10,0,131, - 1,0,1,116,11,0,106,12,0,100,1,0,107,2,0,114, - 116,0,116,2,0,106,7,0,106,8,0,116,13,0,131,1, - 0,1,110,0,0,116,2,0,106,7,0,106,8,0,116,14, - 0,131,1,0,1,100,2,0,83,41,3,122,50,73,110,115, - 116,97,108,108,32,105,109,112,111,114,116,108,105,98,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,114, - 124,1,0,0,78,41,15,114,130,1,0,0,114,236,0,0, - 0,114,7,0,0,0,114,74,1,0,0,114,197,0,0,0, - 114,82,1,0,0,114,96,1,0,0,114,101,1,0,0,114, - 223,0,0,0,114,8,1,0,0,114,15,1,0,0,114,3, - 0,0,0,114,57,0,0,0,114,18,1,0,0,114,69,1, - 0,0,41,3,114,128,1,0,0,114,129,1,0,0,90,17, - 115,117,112,112,111,114,116,101,100,95,108,111,97,100,101,114, - 115,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 218,8,95,105,110,115,116,97,108,108,67,9,0,0,115,16, - 0,0,0,0,2,13,1,9,1,28,1,16,1,16,1,15, - 1,19,1,114,131,1,0,0,41,3,122,3,119,105,110,114, - 1,0,0,0,114,2,0,0,0,41,90,114,59,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,17,0,0,0,114, - 19,0,0,0,114,28,0,0,0,114,38,0,0,0,114,39, - 0,0,0,114,43,0,0,0,114,44,0,0,0,114,46,0, - 0,0,114,55,0,0,0,114,65,0,0,0,114,68,0,0, - 0,114,66,0,0,0,218,8,95,95,99,111,100,101,95,95, - 114,193,0,0,0,114,69,0,0,0,114,109,0,0,0,114, - 92,0,0,0,114,99,0,0,0,114,82,0,0,0,114,83, - 0,0,0,114,102,0,0,0,114,103,0,0,0,114,105,0, - 0,0,114,112,0,0,0,114,114,0,0,0,114,15,0,0, - 0,114,185,0,0,0,114,14,0,0,0,114,18,0,0,0, - 90,17,95,82,65,87,95,77,65,71,73,67,95,78,85,77, - 66,69,82,114,125,0,0,0,114,134,0,0,0,114,119,0, - 0,0,114,120,0,0,0,114,132,0,0,0,114,135,0,0, - 0,114,142,0,0,0,114,144,0,0,0,114,152,0,0,0, - 114,156,0,0,0,114,161,0,0,0,114,164,0,0,0,114, - 172,0,0,0,114,180,0,0,0,114,190,0,0,0,114,195, - 0,0,0,114,198,0,0,0,114,203,0,0,0,114,211,0, - 0,0,114,212,0,0,0,114,216,0,0,0,114,173,0,0, - 0,218,6,111,98,106,101,99,116,114,237,0,0,0,114,235, - 0,0,0,114,243,0,0,0,114,174,0,0,0,114,8,1, - 0,0,114,15,1,0,0,114,18,1,0,0,114,28,1,0, - 0,114,29,1,0,0,114,44,1,0,0,114,47,1,0,0, - 114,51,1,0,0,114,55,1,0,0,114,52,1,0,0,114, - 56,1,0,0,114,250,0,0,0,114,69,1,0,0,114,82, - 1,0,0,114,97,1,0,0,114,100,1,0,0,114,244,0, - 0,0,114,104,1,0,0,114,113,1,0,0,114,105,1,0, - 0,114,107,1,0,0,114,108,1,0,0,114,109,1,0,0, - 114,115,1,0,0,114,117,1,0,0,114,236,0,0,0,114, - 120,1,0,0,114,121,1,0,0,114,130,1,0,0,114,131, - 1,0,0,114,4,0,0,0,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,218,8,60,109,111,100,117,108,101, - 62,8,0,0,0,115,166,0,0,0,6,17,6,3,12,12, - 12,5,12,5,12,6,12,12,12,10,12,9,12,5,12,7, - 15,22,12,8,12,4,15,4,19,20,6,2,6,3,22,4, - 19,68,19,21,19,19,12,19,12,20,12,113,22,1,18,2, - 6,2,9,2,9,1,9,2,15,27,12,23,12,19,12,12, - 18,8,12,18,12,11,12,11,12,13,12,13,21,55,21,12, - 18,10,12,14,12,34,19,27,19,102,24,22,9,3,12,1, - 15,63,18,45,19,251,19,63,19,59,19,60,19,25,22,110, - 19,31,25,43,25,16,6,3,19,48,19,57,19,27,19,124, - 19,147,19,13,12,9,15,41,12,17,6,1,10,2,12,27, - 12,6,18,24,12,32,12,15,12,11,24,35,12,8,12,87, + 108,101,95,116,121,112,101,114,15,0,0,0,114,89,0,0, + 0,114,99,0,0,0,114,88,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,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,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,218,6,95,115,101,116,117,112,61,4,0,0, + 115,50,0,0,0,0,9,6,1,6,3,12,1,28,1,15, + 1,15,1,9,1,15,1,9,2,3,1,15,1,17,3,13, + 1,13,1,15,1,15,2,13,1,20,3,3,1,16,1,13, + 2,11,1,16,3,12,1,114,204,0,0,0,99,2,0,0, + 0,0,0,0,0,3,0,0,0,3,0,0,0,67,0,0, + 0,115,87,0,0,0,116,0,0,124,0,0,124,1,0,131, + 2,0,1,116,1,0,106,2,0,106,3,0,116,4,0,131, + 1,0,1,116,1,0,106,2,0,106,3,0,116,5,0,131, + 1,0,1,100,1,0,100,2,0,108,6,0,125,2,0,124, + 2,0,97,7,0,124,2,0,106,8,0,116,1,0,106,9, + 0,116,10,0,25,131,1,0,1,100,2,0,83,41,3,122, + 50,73,110,115,116,97,108,108,32,105,109,112,111,114,116,108, + 105,98,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,114,33,0,0,0,78,41,11,114,204,0,0,0, + 114,14,0,0,0,114,174,0,0,0,114,113,0,0,0,114, + 150,0,0,0,114,160,0,0,0,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,119,0,0,0,218,8,95,105,110,115, + 116,97,108,108,114,21,0,0,0,114,1,0,0,0,41,3, + 114,202,0,0,0,114,203,0,0,0,114,205,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,206, + 0,0,0,108,4,0,0,115,12,0,0,0,0,2,13,2, + 16,1,16,3,12,1,6,1,114,206,0,0,0,41,51,114, + 3,0,0,0,114,119,0,0,0,114,12,0,0,0,114,16, + 0,0,0,114,17,0,0,0,114,59,0,0,0,114,41,0, + 0,0,114,48,0,0,0,114,31,0,0,0,114,32,0,0, + 0,114,53,0,0,0,114,54,0,0,0,114,56,0,0,0, + 114,63,0,0,0,114,65,0,0,0,114,75,0,0,0,114, + 81,0,0,0,114,84,0,0,0,114,90,0,0,0,114,101, + 0,0,0,114,102,0,0,0,114,106,0,0,0,114,85,0, + 0,0,218,6,111,98,106,101,99,116,90,9,95,80,79,80, + 85,76,65,84,69,114,132,0,0,0,114,137,0,0,0,114, + 144,0,0,0,114,97,0,0,0,114,86,0,0,0,114,148, + 0,0,0,114,149,0,0,0,114,87,0,0,0,114,150,0, + 0,0,114,160,0,0,0,114,165,0,0,0,114,171,0,0, + 0,114,173,0,0,0,114,176,0,0,0,114,181,0,0,0, + 114,191,0,0,0,114,182,0,0,0,114,184,0,0,0,114, + 185,0,0,0,114,186,0,0,0,114,194,0,0,0,114,196, + 0,0,0,114,199,0,0,0,114,200,0,0,0,114,204,0, + 0,0,114,206,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,8,0,0,0,115,96,0,0,0,6,17, + 6,2,12,8,12,4,19,20,6,2,6,3,22,4,19,68, + 19,21,19,19,12,19,12,19,12,11,18,8,12,11,12,12, + 12,16,12,36,19,27,19,101,24,26,9,3,18,45,18,60, + 12,18,12,17,12,25,12,29,12,23,12,16,19,73,19,77, + 19,13,12,9,12,9,15,40,12,17,6,1,10,2,12,27, + 12,6,18,24,12,32,12,15,24,35,12,7,12,47, }; diff --git a/Python/importlib_external.h b/Python/importlib_external.h new file mode 100644 index 000000000000..c4b6dc96be48 --- /dev/null +++ b/Python/importlib_external.h @@ -0,0 +1,2580 @@ +/* Auto-generated by Programs/_freeze_importlib.c */ +const unsigned char _Py_M__importlib_external[] = { + 99,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0, + 0,64,0,0,0,115,210,2,0,0,100,0,0,90,0,0, + 100,92,0,90,1,0,100,4,0,100,5,0,132,0,0,90, + 2,0,100,6,0,100,7,0,132,0,0,90,3,0,100,8, + 0,100,9,0,132,0,0,90,4,0,100,10,0,100,11,0, + 132,0,0,90,5,0,100,12,0,100,13,0,132,0,0,90, + 6,0,100,14,0,100,15,0,132,0,0,90,7,0,100,16, + 0,100,17,0,132,0,0,90,8,0,100,18,0,100,19,0, + 132,0,0,90,9,0,100,20,0,100,21,0,132,0,0,90, + 10,0,100,22,0,100,23,0,100,24,0,132,1,0,90,11, + 0,101,12,0,101,11,0,106,13,0,131,1,0,90,14,0, + 100,25,0,106,15,0,100,26,0,100,27,0,131,2,0,100, + 28,0,23,90,16,0,101,17,0,106,18,0,101,16,0,100, + 27,0,131,2,0,90,19,0,100,29,0,90,20,0,100,30, + 0,90,21,0,100,31,0,103,1,0,90,22,0,100,32,0, + 103,1,0,90,23,0,101,23,0,4,90,24,0,90,25,0, + 100,33,0,100,34,0,100,33,0,100,35,0,100,36,0,132, + 1,1,90,26,0,100,37,0,100,38,0,132,0,0,90,27, + 0,100,39,0,100,40,0,132,0,0,90,28,0,100,41,0, + 100,42,0,132,0,0,90,29,0,100,43,0,100,44,0,132, + 0,0,90,30,0,100,45,0,100,46,0,132,0,0,90,31, + 0,100,47,0,100,48,0,132,0,0,90,32,0,100,33,0, + 100,33,0,100,33,0,100,49,0,100,50,0,132,3,0,90, + 33,0,100,33,0,100,33,0,100,33,0,100,51,0,100,52, + 0,132,3,0,90,34,0,100,53,0,100,53,0,100,54,0, + 100,55,0,132,2,0,90,35,0,100,56,0,100,57,0,132, + 0,0,90,36,0,101,37,0,131,0,0,90,38,0,100,33, + 0,100,58,0,100,33,0,100,59,0,101,38,0,100,60,0, + 100,61,0,132,1,2,90,39,0,71,100,62,0,100,63,0, + 132,0,0,100,63,0,131,2,0,90,40,0,71,100,64,0, + 100,65,0,132,0,0,100,65,0,131,2,0,90,41,0,71, + 100,66,0,100,67,0,132,0,0,100,67,0,101,41,0,131, + 3,0,90,42,0,71,100,68,0,100,69,0,132,0,0,100, + 69,0,131,2,0,90,43,0,71,100,70,0,100,71,0,132, + 0,0,100,71,0,101,43,0,101,42,0,131,4,0,90,44, + 0,71,100,72,0,100,73,0,132,0,0,100,73,0,101,43, + 0,101,41,0,131,4,0,90,45,0,103,0,0,90,46,0, + 71,100,74,0,100,75,0,132,0,0,100,75,0,101,43,0, + 101,41,0,131,4,0,90,47,0,71,100,76,0,100,77,0, + 132,0,0,100,77,0,131,2,0,90,48,0,71,100,78,0, + 100,79,0,132,0,0,100,79,0,131,2,0,90,49,0,71, + 100,80,0,100,81,0,132,0,0,100,81,0,131,2,0,90, + 50,0,71,100,82,0,100,83,0,132,0,0,100,83,0,131, + 2,0,90,51,0,100,33,0,100,84,0,100,85,0,132,1, + 0,90,52,0,100,86,0,100,87,0,132,0,0,90,53,0, + 100,88,0,100,89,0,132,0,0,90,54,0,100,90,0,100, + 91,0,132,0,0,90,55,0,100,33,0,83,41,93,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,218,3,119,105,110,218,6,99,121,103,119,105,110,218,6, + 100,97,114,119,105,110,99,0,0,0,0,0,0,0,0,1, + 0,0,0,2,0,0,0,67,0,0,0,115,49,0,0,0, + 116,0,0,106,1,0,106,2,0,116,3,0,131,1,0,114, + 33,0,100,1,0,100,2,0,132,0,0,125,0,0,110,12, + 0,100,3,0,100,2,0,132,0,0,125,0,0,124,0,0, + 83,41,4,78,99,0,0,0,0,0,0,0,0,0,0,0, + 0,2,0,0,0,83,0,0,0,115,13,0,0,0,100,1, + 0,116,0,0,106,1,0,107,6,0,83,41,2,122,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,115,12,0,0,0,80,89,84,72,79,78,67, + 65,83,69,79,75,41,2,218,3,95,111,115,90,7,101,110, + 118,105,114,111,110,169,0,114,4,0,0,0,114,4,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,11,95,114,101,108,97, + 120,95,99,97,115,101,30,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,1,0,0,0,83,0,0,0,115,4,0, + 0,0,100,1,0,83,41,2,122,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,70, + 114,4,0,0,0,114,4,0,0,0,114,4,0,0,0,114, + 4,0,0,0,114,5,0,0,0,114,6,0,0,0,34,0, + 0,0,115,2,0,0,0,0,2,41,4,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,41,1,114,6,0,0,0,114,4,0,0,0,114, + 4,0,0,0,114,5,0,0,0,218,16,95,109,97,107,101, + 95,114,101,108,97,120,95,99,97,115,101,28,0,0,0,115, + 8,0,0,0,0,1,18,1,15,4,12,3,114,11,0,0, + 0,99,1,0,0,0,0,0,0,0,1,0,0,0,3,0, + 0,0,67,0,0,0,115,26,0,0,0,116,0,0,124,0, + 0,131,1,0,100,1,0,64,106,1,0,100,2,0,100,3, + 0,131,2,0,83,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,108,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,4,0,0,0,114,4,0,0,0,114,5,0,0,0, + 218,7,95,119,95,108,111,110,103,40,0,0,0,115,2,0, + 0,0,0,2,114,17,0,0,0,99,1,0,0,0,0,0, + 0,0,1,0,0,0,3,0,0,0,67,0,0,0,115,16, + 0,0,0,116,0,0,106,1,0,124,0,0,100,1,0,131, + 2,0,83,41,2,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,13,0,0,0,41,2,114,14,0, + 0,0,218,10,102,114,111,109,95,98,121,116,101,115,41,1, + 90,9,105,110,116,95,98,121,116,101,115,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,218,7,95,114,95,108, + 111,110,103,45,0,0,0,115,2,0,0,0,0,2,114,19, + 0,0,0,99,0,0,0,0,0,0,0,0,1,0,0,0, + 3,0,0,0,71,0,0,0,115,26,0,0,0,116,0,0, + 106,1,0,100,1,0,100,2,0,132,0,0,124,0,0,68, + 131,1,0,131,1,0,83,41,3,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,106,111,105,110,40,41,46,99,1,0,0,0,0, + 0,0,0,2,0,0,0,4,0,0,0,83,0,0,0,115, + 37,0,0,0,103,0,0,124,0,0,93,27,0,125,1,0, + 124,1,0,114,6,0,124,1,0,106,0,0,116,1,0,131, + 1,0,145,2,0,113,6,0,83,114,4,0,0,0,41,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,41,2,218,2,46,48,218, + 4,112,97,114,116,114,4,0,0,0,114,4,0,0,0,114, + 5,0,0,0,250,10,60,108,105,115,116,99,111,109,112,62, + 52,0,0,0,115,2,0,0,0,9,1,122,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,2,218,8,112, + 97,116,104,95,115,101,112,218,4,106,111,105,110,41,1,218, + 10,112,97,116,104,95,112,97,114,116,115,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,218,10,95,112,97,116, + 104,95,106,111,105,110,50,0,0,0,115,4,0,0,0,0, + 2,15,1,114,28,0,0,0,99,1,0,0,0,0,0,0, + 0,5,0,0,0,5,0,0,0,67,0,0,0,115,134,0, + 0,0,116,0,0,116,1,0,131,1,0,100,1,0,107,2, + 0,114,52,0,124,0,0,106,2,0,116,3,0,131,1,0, + 92,3,0,125,1,0,125,2,0,125,3,0,124,1,0,124, + 3,0,102,2,0,83,120,69,0,116,4,0,124,0,0,131, + 1,0,68,93,55,0,125,4,0,124,4,0,116,1,0,107, + 6,0,114,65,0,124,0,0,106,5,0,124,4,0,100,2, + 0,100,1,0,131,1,1,92,2,0,125,1,0,125,3,0, + 124,1,0,124,3,0,102,2,0,83,113,65,0,87,100,3, + 0,124,0,0,102,2,0,83,41,4,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,233,1,0,0, + 0,90,8,109,97,120,115,112,108,105,116,218,0,41,6,218, + 3,108,101,110,114,21,0,0,0,218,10,114,112,97,114,116, + 105,116,105,111,110,114,25,0,0,0,218,8,114,101,118,101, + 114,115,101,100,218,6,114,115,112,108,105,116,41,5,218,4, + 112,97,116,104,90,5,102,114,111,110,116,218,1,95,218,4, + 116,97,105,108,114,16,0,0,0,114,4,0,0,0,114,4, + 0,0,0,114,5,0,0,0,218,11,95,112,97,116,104,95, + 115,112,108,105,116,56,0,0,0,115,16,0,0,0,0,2, + 18,1,24,1,10,1,19,1,12,1,27,1,14,1,114,38, + 0,0,0,99,1,0,0,0,0,0,0,0,1,0,0,0, + 2,0,0,0,67,0,0,0,115,13,0,0,0,116,0,0, + 106,1,0,124,0,0,131,1,0,83,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,3, + 0,0,0,90,4,115,116,97,116,41,1,114,35,0,0,0, + 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,218, + 10,95,112,97,116,104,95,115,116,97,116,68,0,0,0,115, + 2,0,0,0,0,7,114,39,0,0,0,99,2,0,0,0, + 0,0,0,0,3,0,0,0,11,0,0,0,67,0,0,0, + 115,58,0,0,0,121,16,0,116,0,0,124,0,0,131,1, + 0,125,2,0,87,110,22,0,4,116,1,0,107,10,0,114, + 40,0,1,1,1,100,1,0,83,89,110,1,0,88,124,2, + 0,106,2,0,100,2,0,64,124,1,0,107,2,0,83,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,39,0,0, + 0,218,7,79,83,69,114,114,111,114,218,7,115,116,95,109, + 111,100,101,41,3,114,35,0,0,0,218,4,109,111,100,101, + 90,9,115,116,97,116,95,105,110,102,111,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,218,18,95,112,97,116, + 104,95,105,115,95,109,111,100,101,95,116,121,112,101,78,0, + 0,0,115,10,0,0,0,0,2,3,1,16,1,13,1,9, + 1,114,43,0,0,0,99,1,0,0,0,0,0,0,0,1, + 0,0,0,3,0,0,0,67,0,0,0,115,13,0,0,0, + 116,0,0,124,0,0,100,1,0,131,2,0,83,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,43,0,0,0,41,1,114,35, + 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, + 0,0,218,12,95,112,97,116,104,95,105,115,102,105,108,101, + 87,0,0,0,115,2,0,0,0,0,2,114,44,0,0,0, + 99,1,0,0,0,0,0,0,0,1,0,0,0,3,0,0, + 0,67,0,0,0,115,31,0,0,0,124,0,0,115,18,0, + 116,0,0,106,1,0,131,0,0,125,0,0,116,2,0,124, + 0,0,100,1,0,131,2,0,83,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,3,0,0,0,218,6,103,101,116,99,119,100,114, + 43,0,0,0,41,1,114,35,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,218,11,95,112,97,116, + 104,95,105,115,100,105,114,92,0,0,0,115,6,0,0,0, + 0,2,6,1,12,1,114,46,0,0,0,105,182,1,0,0, + 99,3,0,0,0,0,0,0,0,6,0,0,0,17,0,0, + 0,67,0,0,0,115,193,0,0,0,100,1,0,106,0,0, + 124,0,0,116,1,0,124,0,0,131,1,0,131,2,0,125, + 3,0,116,2,0,106,3,0,124,3,0,116,2,0,106,4, + 0,116,2,0,106,5,0,66,116,2,0,106,6,0,66,124, + 2,0,100,2,0,64,131,3,0,125,4,0,121,61,0,116, + 7,0,106,8,0,124,4,0,100,3,0,131,2,0,143,20, + 0,125,5,0,124,5,0,106,9,0,124,1,0,131,1,0, + 1,87,100,4,0,81,82,88,116,2,0,106,10,0,124,3, + 0,124,0,0,131,2,0,1,87,110,59,0,4,116,11,0, + 107,10,0,114,188,0,1,1,1,121,17,0,116,2,0,106, + 12,0,124,3,0,131,1,0,1,87,110,18,0,4,116,11, + 0,107,10,0,114,180,0,1,1,1,89,110,1,0,88,130, + 0,0,89,110,1,0,88,100,4,0,83,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,122,5,123,125,46,123,125,105,182,1,0,0,90,2,119, + 98,78,41,13,218,6,102,111,114,109,97,116,218,2,105,100, + 114,3,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,218,7,114,101,112,108, + 97,99,101,114,40,0,0,0,90,6,117,110,108,105,110,107, + 41,6,114,35,0,0,0,218,4,100,97,116,97,114,42,0, + 0,0,90,8,112,97,116,104,95,116,109,112,90,2,102,100, + 218,4,102,105,108,101,114,4,0,0,0,114,4,0,0,0, + 114,5,0,0,0,218,13,95,119,114,105,116,101,95,97,116, + 111,109,105,99,99,0,0,0,115,26,0,0,0,0,5,24, + 1,9,1,33,1,3,3,21,1,20,1,20,1,13,1,3, + 1,17,1,13,1,5,1,114,55,0,0,0,105,22,13,0, + 0,233,2,0,0,0,114,13,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, + 78,218,12,111,112,116,105,109,105,122,97,116,105,111,110,99, + 2,0,0,0,1,0,0,0,11,0,0,0,6,0,0,0, + 67,0,0,0,115,87,1,0,0,124,1,0,100,1,0,107, + 9,0,114,76,0,116,0,0,106,1,0,100,2,0,116,2, + 0,131,2,0,1,124,2,0,100,1,0,107,9,0,114,58, + 0,100,3,0,125,3,0,116,3,0,124,3,0,131,1,0, + 130,1,0,124,1,0,114,70,0,100,4,0,110,3,0,100, + 5,0,125,2,0,116,4,0,124,0,0,131,1,0,92,2, + 0,125,4,0,125,5,0,124,5,0,106,5,0,100,6,0, + 131,1,0,92,3,0,125,6,0,125,7,0,125,8,0,116, + 6,0,106,7,0,106,8,0,125,9,0,124,9,0,100,1, + 0,107,8,0,114,154,0,116,9,0,100,7,0,131,1,0, + 130,1,0,100,4,0,106,10,0,124,6,0,114,172,0,124, + 6,0,110,3,0,124,8,0,124,7,0,124,9,0,103,3, + 0,131,1,0,125,10,0,124,2,0,100,1,0,107,8,0, + 114,241,0,116,6,0,106,11,0,106,12,0,100,8,0,107, + 2,0,114,229,0,100,4,0,125,2,0,110,12,0,116,6, + 0,106,11,0,106,12,0,125,2,0,116,13,0,124,2,0, + 131,1,0,125,2,0,124,2,0,100,4,0,107,3,0,114, + 63,1,124,2,0,106,14,0,131,0,0,115,42,1,116,15, + 0,100,9,0,106,16,0,124,2,0,131,1,0,131,1,0, + 130,1,0,100,10,0,106,16,0,124,10,0,116,17,0,124, + 2,0,131,3,0,125,10,0,116,18,0,124,4,0,116,19, + 0,124,10,0,116,20,0,100,8,0,25,23,131,3,0,83, + 41,11,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,30,0,0,0,114,29,0,0,0,218,1,46,122, + 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,233,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,41,21,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, + 38,0,0,0,114,32,0,0,0,114,7,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,26, + 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,47, + 0,0,0,218,4,95,79,80,84,114,28,0,0,0,218,8, + 95,80,89,67,65,67,72,69,218,17,66,89,84,69,67,79, + 68,69,95,83,85,70,70,73,88,69,83,41,11,114,35,0, + 0,0,90,14,100,101,98,117,103,95,111,118,101,114,114,105, + 100,101,114,57,0,0,0,218,7,109,101,115,115,97,103,101, + 218,4,104,101,97,100,114,37,0,0,0,90,4,98,97,115, + 101,218,3,115,101,112,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,114,4,0,0,0,114,4,0,0,0,114,5,0,0, + 0,218,17,99,97,99,104,101,95,102,114,111,109,95,115,111, + 117,114,99,101,243,0,0,0,115,46,0,0,0,0,18,12, + 1,9,1,7,1,12,1,6,1,12,1,18,1,18,1,24, + 1,12,1,12,1,12,1,36,1,12,1,18,1,9,2,12, + 1,12,1,12,1,12,1,21,1,21,1,114,79,0,0,0, + 99,1,0,0,0,0,0,0,0,8,0,0,0,5,0,0, + 0,67,0,0,0,115,62,1,0,0,116,0,0,106,1,0, + 106,2,0,100,1,0,107,8,0,114,30,0,116,3,0,100, + 2,0,131,1,0,130,1,0,116,4,0,124,0,0,131,1, + 0,92,2,0,125,1,0,125,2,0,116,4,0,124,1,0, + 131,1,0,92,2,0,125,1,0,125,3,0,124,3,0,116, + 5,0,107,3,0,114,102,0,116,6,0,100,3,0,106,7, + 0,116,5,0,124,0,0,131,2,0,131,1,0,130,1,0, + 124,2,0,106,8,0,100,4,0,131,1,0,125,4,0,124, + 4,0,100,11,0,107,7,0,114,153,0,116,6,0,100,7, + 0,106,7,0,124,2,0,131,1,0,131,1,0,130,1,0, + 110,125,0,124,4,0,100,6,0,107,2,0,114,22,1,124, + 2,0,106,9,0,100,4,0,100,5,0,131,2,0,100,12, + 0,25,125,5,0,124,5,0,106,10,0,116,11,0,131,1, + 0,115,223,0,116,6,0,100,8,0,106,7,0,116,11,0, + 131,1,0,131,1,0,130,1,0,124,5,0,116,12,0,116, + 11,0,131,1,0,100,1,0,133,2,0,25,125,6,0,124, + 6,0,106,13,0,131,0,0,115,22,1,116,6,0,100,9, + 0,106,7,0,124,5,0,131,1,0,131,1,0,130,1,0, + 124,2,0,106,14,0,100,4,0,131,1,0,100,10,0,25, + 125,7,0,116,15,0,124,1,0,124,7,0,116,16,0,100, + 10,0,25,23,131,2,0,83,41,13,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,122,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,122,37,123,125,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,123,33,114,125,114,58,0,0,0, + 114,56,0,0,0,233,3,0,0,0,122,33,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,123,33,114,125,122,57,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,123,33,114,125,122,52,111,112,116,105,109,105, + 122,97,116,105,111,110,32,108,101,118,101,108,32,123,33,114, + 125,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,59, + 0,0,0,62,2,0,0,0,114,56,0,0,0,114,80,0, + 0,0,233,254,255,255,255,41,17,114,7,0,0,0,114,64, + 0,0,0,114,65,0,0,0,114,66,0,0,0,114,38,0, + 0,0,114,73,0,0,0,114,71,0,0,0,114,47,0,0, + 0,218,5,99,111,117,110,116,114,34,0,0,0,114,9,0, + 0,0,114,72,0,0,0,114,31,0,0,0,114,70,0,0, + 0,218,9,112,97,114,116,105,116,105,111,110,114,28,0,0, + 0,218,15,83,79,85,82,67,69,95,83,85,70,70,73,88, + 69,83,41,8,114,35,0,0,0,114,76,0,0,0,90,16, + 112,121,99,97,99,104,101,95,102,105,108,101,110,97,109,101, + 90,7,112,121,99,97,99,104,101,90,9,100,111,116,95,99, + 111,117,110,116,114,57,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,4,0,0,0,114,4,0,0,0,114,5,0, + 0,0,218,17,115,111,117,114,99,101,95,102,114,111,109,95, + 99,97,99,104,101,31,1,0,0,115,44,0,0,0,0,9, + 18,1,12,1,18,1,18,1,12,1,9,1,15,1,15,1, + 12,1,9,1,15,1,12,1,22,1,15,1,9,1,12,1, + 22,1,12,1,9,1,12,1,19,1,114,85,0,0,0,99, + 1,0,0,0,0,0,0,0,5,0,0,0,12,0,0,0, + 67,0,0,0,115,164,0,0,0,116,0,0,124,0,0,131, + 1,0,100,1,0,107,2,0,114,22,0,100,2,0,83,124, + 0,0,106,1,0,100,3,0,131,1,0,92,3,0,125,1, + 0,125,2,0,125,3,0,124,1,0,12,115,81,0,124,3, + 0,106,2,0,131,0,0,100,7,0,100,8,0,133,2,0, + 25,100,6,0,107,3,0,114,85,0,124,0,0,83,121,16, + 0,116,3,0,124,0,0,131,1,0,125,4,0,87,110,40, + 0,4,116,4,0,116,5,0,102,2,0,107,10,0,114,143, + 0,1,1,1,124,0,0,100,2,0,100,9,0,133,2,0, + 25,125,4,0,89,110,1,0,88,116,6,0,124,4,0,131, + 1,0,114,160,0,124,4,0,83,124,0,0,83,41,10,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,59,0, + 0,0,78,114,58,0,0,0,114,80,0,0,0,114,29,0, + 0,0,90,2,112,121,233,253,255,255,255,233,255,255,255,255, + 114,87,0,0,0,41,7,114,31,0,0,0,114,32,0,0, + 0,218,5,108,111,119,101,114,114,85,0,0,0,114,66,0, + 0,0,114,71,0,0,0,114,44,0,0,0,41,5,218,13, + 98,121,116,101,99,111,100,101,95,112,97,116,104,114,78,0, + 0,0,114,36,0,0,0,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, + 4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,15, + 95,103,101,116,95,115,111,117,114,99,101,102,105,108,101,64, + 1,0,0,115,20,0,0,0,0,7,18,1,4,1,24,1, + 35,1,4,1,3,1,16,1,19,1,21,1,114,91,0,0, + 0,99,1,0,0,0,0,0,0,0,1,0,0,0,11,0, + 0,0,67,0,0,0,115,92,0,0,0,124,0,0,106,0, + 0,116,1,0,116,2,0,131,1,0,131,1,0,114,59,0, + 121,14,0,116,3,0,124,0,0,131,1,0,83,87,113,88, + 0,4,116,4,0,107,10,0,114,55,0,1,1,1,89,113, + 88,0,88,110,29,0,124,0,0,106,0,0,116,1,0,116, + 5,0,131,1,0,131,1,0,114,84,0,124,0,0,83,100, + 0,0,83,100,0,0,83,41,1,78,41,6,218,8,101,110, + 100,115,119,105,116,104,218,5,116,117,112,108,101,114,84,0, + 0,0,114,79,0,0,0,114,66,0,0,0,114,74,0,0, + 0,41,1,218,8,102,105,108,101,110,97,109,101,114,4,0, + 0,0,114,4,0,0,0,114,5,0,0,0,218,11,95,103, + 101,116,95,99,97,99,104,101,100,83,1,0,0,115,16,0, + 0,0,0,1,21,1,3,1,14,1,13,1,8,1,21,1, + 4,2,114,95,0,0,0,99,1,0,0,0,0,0,0,0, + 2,0,0,0,11,0,0,0,67,0,0,0,115,60,0,0, + 0,121,19,0,116,0,0,124,0,0,131,1,0,106,1,0, + 125,1,0,87,110,24,0,4,116,2,0,107,10,0,114,45, + 0,1,1,1,100,1,0,125,1,0,89,110,1,0,88,124, + 1,0,100,2,0,79,125,1,0,124,1,0,83,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,105,182,1,0,0,233,128,0,0,0,41,3, + 114,39,0,0,0,114,41,0,0,0,114,40,0,0,0,41, + 2,114,35,0,0,0,114,42,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,218,10,95,99,97,108, + 99,95,109,111,100,101,95,1,0,0,115,12,0,0,0,0, + 2,3,1,19,1,13,1,11,3,10,1,114,97,0,0,0, + 99,1,0,0,0,0,0,0,0,3,0,0,0,11,0,0, + 0,3,0,0,0,115,84,0,0,0,100,1,0,135,0,0, + 102,1,0,100,2,0,100,3,0,134,1,0,125,1,0,121, + 13,0,116,0,0,106,1,0,125,2,0,87,110,30,0,4, + 116,2,0,107,10,0,114,66,0,1,1,1,100,4,0,100, + 5,0,132,0,0,125,2,0,89,110,1,0,88,124,2,0, + 124,1,0,136,0,0,131,2,0,1,124,1,0,83,41,6, + 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,4,0,0,0,5,0,0,0, + 31,0,0,0,115,89,0,0,0,124,1,0,100,0,0,107, + 8,0,114,24,0,124,0,0,106,0,0,125,1,0,110,46, + 0,124,0,0,106,0,0,124,1,0,107,3,0,114,70,0, + 116,1,0,100,1,0,124,0,0,106,0,0,124,1,0,102, + 2,0,22,100,2,0,124,1,0,131,1,1,130,1,0,136, + 0,0,124,0,0,124,1,0,124,2,0,124,3,0,142,2, + 0,83,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,218,4,110,97,109,101,41,2,114,98,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,98,0,0,0,218,4,97,114, + 103,115,90,6,107,119,97,114,103,115,41,1,218,6,109,101, + 116,104,111,100,114,4,0,0,0,114,5,0,0,0,218,19, + 95,99,104,101,99,107,95,110,97,109,101,95,119,114,97,112, + 112,101,114,115,1,0,0,115,12,0,0,0,0,1,12,1, + 12,1,15,1,6,1,25,1,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,3,0,0,0,7, + 0,0,0,83,0,0,0,115,92,0,0,0,120,66,0,100, + 1,0,100,2,0,100,3,0,100,4,0,103,4,0,68,93, + 46,0,125,2,0,116,0,0,124,1,0,124,2,0,131,2, + 0,114,19,0,116,1,0,124,0,0,124,2,0,116,2,0, + 124,1,0,124,2,0,131,2,0,131,3,0,1,113,19,0, + 87,124,0,0,106,3,0,106,4,0,124,1,0,106,3,0, + 131,1,0,1,100,0,0,83,41,5,78,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,52,0,0,0,114,4,0,0,0,114,4,0, + 0,0,114,5,0,0,0,218,5,95,119,114,97,112,126,1, + 0,0,115,8,0,0,0,0,1,25,1,15,1,29,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,3,218,10,95, + 98,111,111,116,115,116,114,97,112,114,113,0,0,0,218,9, + 78,97,109,101,69,114,114,111,114,41,3,114,102,0,0,0, + 114,103,0,0,0,114,113,0,0,0,114,4,0,0,0,41, + 1,114,102,0,0,0,114,5,0,0,0,218,11,95,99,104, + 101,99,107,95,110,97,109,101,107,1,0,0,115,14,0,0, + 0,0,8,21,7,3,1,13,1,13,2,17,5,13,1,114, + 116,0,0,0,99,2,0,0,0,0,0,0,0,5,0,0, + 0,4,0,0,0,67,0,0,0,115,84,0,0,0,124,0, + 0,106,0,0,124,1,0,131,1,0,92,2,0,125,2,0, + 125,3,0,124,2,0,100,1,0,107,8,0,114,80,0,116, + 1,0,124,3,0,131,1,0,114,80,0,100,2,0,125,4, + 0,116,2,0,106,3,0,124,4,0,106,4,0,124,3,0, + 100,3,0,25,131,1,0,116,5,0,131,2,0,1,124,2, + 0,83,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,59,0,0,0,41,6,218,11,102,105,110,100,95,108,111, + 97,100,101,114,114,31,0,0,0,114,60,0,0,0,114,61, + 0,0,0,114,47,0,0,0,218,13,73,109,112,111,114,116, + 87,97,114,110,105,110,103,41,5,114,100,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, + 4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,17, + 95,102,105,110,100,95,109,111,100,117,108,101,95,115,104,105, + 109,135,1,0,0,115,10,0,0,0,0,10,21,1,24,1, + 6,1,29,1,114,123,0,0,0,99,4,0,0,0,0,0, + 0,0,11,0,0,0,19,0,0,0,67,0,0,0,115,252, + 1,0,0,105,0,0,125,4,0,124,2,0,100,1,0,107, + 9,0,114,31,0,124,2,0,124,4,0,100,2,0,60,110, + 6,0,100,3,0,125,2,0,124,3,0,100,1,0,107,9, + 0,114,59,0,124,3,0,124,4,0,100,4,0,60,124,0, + 0,100,1,0,100,5,0,133,2,0,25,125,5,0,124,0, + 0,100,5,0,100,6,0,133,2,0,25,125,6,0,124,0, + 0,100,6,0,100,7,0,133,2,0,25,125,7,0,124,5, + 0,116,0,0,107,3,0,114,171,0,100,8,0,106,1,0, + 124,2,0,124,5,0,131,2,0,125,8,0,116,2,0,106, + 3,0,100,9,0,124,8,0,131,2,0,1,116,4,0,124, + 8,0,124,4,0,141,1,0,130,1,0,110,125,0,116,5, + 0,124,6,0,131,1,0,100,5,0,107,3,0,114,235,0, + 100,10,0,106,1,0,124,2,0,131,1,0,125,8,0,116, + 2,0,106,3,0,100,9,0,124,8,0,131,2,0,1,116, + 6,0,124,8,0,131,1,0,130,1,0,110,61,0,116,5, + 0,124,7,0,131,1,0,100,5,0,107,3,0,114,40,1, + 100,11,0,106,1,0,124,2,0,131,1,0,125,8,0,116, + 2,0,106,3,0,100,9,0,124,8,0,131,2,0,1,116, + 6,0,124,8,0,131,1,0,130,1,0,124,1,0,100,1, + 0,107,9,0,114,238,1,121,20,0,116,7,0,124,1,0, + 100,12,0,25,131,1,0,125,9,0,87,110,18,0,4,116, + 8,0,107,10,0,114,92,1,1,1,1,89,110,65,0,88, + 116,9,0,124,6,0,131,1,0,124,9,0,107,3,0,114, + 157,1,100,13,0,106,1,0,124,2,0,131,1,0,125,8, + 0,116,2,0,106,3,0,100,9,0,124,8,0,131,2,0, + 1,116,4,0,124,8,0,124,4,0,141,1,0,130,1,0, + 121,18,0,124,1,0,100,14,0,25,100,15,0,64,125,10, + 0,87,110,18,0,4,116,8,0,107,10,0,114,195,1,1, + 1,1,89,110,43,0,88,116,9,0,124,7,0,131,1,0, + 124,10,0,107,3,0,114,238,1,116,4,0,100,13,0,106, + 1,0,124,2,0,131,1,0,124,4,0,141,1,0,130,1, + 0,124,0,0,100,7,0,100,1,0,133,2,0,25,83,41, + 16,97,122,1,0,0,86,97,108,105,100,97,116,101,32,116, + 104,101,32,104,101,97,100,101,114,32,111,102,32,116,104,101, + 32,112,97,115,115,101,100,45,105,110,32,98,121,116,101,99, + 111,100,101,32,97,103,97,105,110,115,116,32,115,111,117,114, + 99,101,95,115,116,97,116,115,32,40,105,102,10,32,32,32, + 32,103,105,118,101,110,41,32,97,110,100,32,114,101,116,117, + 114,110,105,110,103,32,116,104,101,32,98,121,116,101,99,111, + 100,101,32,116,104,97,116,32,99,97,110,32,98,101,32,99, + 111,109,112,105,108,101,100,32,98,121,32,99,111,109,112,105, + 108,101,40,41,46,10,10,32,32,32,32,65,108,108,32,111, + 116,104,101,114,32,97,114,103,117,109,101,110,116,115,32,97, + 114,101,32,117,115,101,100,32,116,111,32,101,110,104,97,110, + 99,101,32,101,114,114,111,114,32,114,101,112,111,114,116,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,116,104,101,32,98,121,116,101,99,111,100, + 101,32,105,115,10,32,32,32,32,102,111,117,110,100,32,116, + 111,32,98,101,32,115,116,97,108,101,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,10,32,32,32,32, + 116,114,117,110,99,97,116,101,100,46,10,10,32,32,32,32, + 78,114,98,0,0,0,122,10,60,98,121,116,101,99,111,100, + 101,62,114,35,0,0,0,114,12,0,0,0,233,8,0,0, + 0,233,12,0,0,0,122,30,98,97,100,32,109,97,103,105, + 99,32,110,117,109,98,101,114,32,105,110,32,123,33,114,125, + 58,32,123,33,114,125,122,2,123,125,122,43,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,116,105,109,101,115,116,97,109,112,32, + 105,110,32,123,33,114,125,122,48,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,115,105,122,101,32,111,102,32,115,111,117,114,99, + 101,32,105,110,32,123,33,114,125,218,5,109,116,105,109,101, + 122,26,98,121,116,101,99,111,100,101,32,105,115,32,115,116, + 97,108,101,32,102,111,114,32,123,33,114,125,218,4,115,105, + 122,101,108,3,0,0,0,255,127,255,127,3,0,41,10,218, + 12,77,65,71,73,67,95,78,85,77,66,69,82,114,47,0, + 0,0,114,114,0,0,0,218,16,95,118,101,114,98,111,115, + 101,95,109,101,115,115,97,103,101,114,99,0,0,0,114,31, + 0,0,0,218,8,69,79,70,69,114,114,111,114,114,14,0, + 0,0,218,8,75,101,121,69,114,114,111,114,114,19,0,0, + 0,41,11,114,53,0,0,0,218,12,115,111,117,114,99,101, + 95,115,116,97,116,115,114,98,0,0,0,114,35,0,0,0, + 90,11,101,120,99,95,100,101,116,97,105,108,115,90,5,109, + 97,103,105,99,90,13,114,97,119,95,116,105,109,101,115,116, + 97,109,112,90,8,114,97,119,95,115,105,122,101,114,75,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,4,0, + 0,0,114,4,0,0,0,114,5,0,0,0,218,25,95,118, + 97,108,105,100,97,116,101,95,98,121,116,101,99,111,100,101, + 95,104,101,97,100,101,114,152,1,0,0,115,76,0,0,0, + 0,11,6,1,12,1,13,3,6,1,12,1,10,1,16,1, + 16,1,16,1,12,1,18,1,16,1,18,1,18,1,15,1, + 16,1,15,1,18,1,15,1,16,1,12,1,12,1,3,1, + 20,1,13,1,5,2,18,1,15,1,16,1,15,1,3,1, + 18,1,13,1,5,2,18,1,15,1,9,1,114,135,0,0, + 0,99,4,0,0,0,0,0,0,0,5,0,0,0,6,0, + 0,0,67,0,0,0,115,115,0,0,0,116,0,0,106,1, + 0,124,0,0,131,1,0,125,4,0,116,2,0,124,4,0, + 116,3,0,131,2,0,114,78,0,116,4,0,106,5,0,100, + 1,0,124,2,0,131,2,0,1,124,3,0,100,2,0,107, + 9,0,114,74,0,116,6,0,106,7,0,124,4,0,124,3, + 0,131,2,0,1,124,4,0,83,116,8,0,100,3,0,106, + 9,0,124,2,0,131,1,0,100,4,0,124,1,0,100,5, + 0,124,2,0,131,1,2,130,1,0,100,2,0,83,41,6, + 122,60,67,111,109,112,105,108,101,32,98,121,116,101,99,111, + 100,101,32,97,115,32,114,101,116,117,114,110,101,100,32,98, + 121,32,95,118,97,108,105,100,97,116,101,95,98,121,116,101, + 99,111,100,101,95,104,101,97,100,101,114,40,41,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,114, + 98,0,0,0,114,35,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,114,0,0,0,114,129,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,99,0,0,0,114,47,0,0,0,41, + 5,114,53,0,0,0,114,98,0,0,0,114,89,0,0,0, + 114,90,0,0,0,218,4,99,111,100,101,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,218,17,95,99,111,109, + 112,105,108,101,95,98,121,116,101,99,111,100,101,207,1,0, + 0,115,16,0,0,0,0,2,15,1,15,1,16,1,12,1, + 16,1,4,2,18,1,114,141,0,0,0,114,59,0,0,0, + 99,3,0,0,0,0,0,0,0,4,0,0,0,3,0,0, + 0,67,0,0,0,115,76,0,0,0,116,0,0,116,1,0, + 131,1,0,125,3,0,124,3,0,106,2,0,116,3,0,124, + 1,0,131,1,0,131,1,0,1,124,3,0,106,2,0,116, + 3,0,124,2,0,131,1,0,131,1,0,1,124,3,0,106, + 2,0,116,4,0,106,5,0,124,0,0,131,1,0,131,1, + 0,1,124,3,0,83,41,1,122,80,67,111,109,112,105,108, + 101,32,97,32,99,111,100,101,32,111,98,106,101,99,116,32, + 105,110,116,111,32,98,121,116,101,99,111,100,101,32,102,111, + 114,32,119,114,105,116,105,110,103,32,111,117,116,32,116,111, + 32,97,32,98,121,116,101,45,99,111,109,112,105,108,101,100, + 10,32,32,32,32,102,105,108,101,46,41,6,218,9,98,121, + 116,101,97,114,114,97,121,114,128,0,0,0,218,6,101,120, + 116,101,110,100,114,17,0,0,0,114,136,0,0,0,90,5, + 100,117,109,112,115,41,4,114,140,0,0,0,114,126,0,0, + 0,114,134,0,0,0,114,53,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,218,17,95,99,111,100, + 101,95,116,111,95,98,121,116,101,99,111,100,101,219,1,0, + 0,115,10,0,0,0,0,3,12,1,19,1,19,1,22,1, + 114,144,0,0,0,99,1,0,0,0,0,0,0,0,5,0, + 0,0,4,0,0,0,67,0,0,0,115,89,0,0,0,100, + 1,0,100,2,0,108,0,0,125,1,0,116,1,0,106,2, + 0,124,0,0,131,1,0,106,3,0,125,2,0,124,1,0, + 106,4,0,124,2,0,131,1,0,125,3,0,116,1,0,106, + 5,0,100,2,0,100,3,0,131,2,0,125,4,0,124,4, + 0,106,6,0,124,0,0,106,6,0,124,3,0,100,1,0, + 25,131,1,0,131,1,0,83,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,59,0,0,0,78,84,41,7,218,8, + 116,111,107,101,110,105,122,101,114,49,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,145,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,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,218,13,100,101,99,111, + 100,101,95,115,111,117,114,99,101,229,1,0,0,115,10,0, + 0,0,0,5,12,1,18,1,15,1,18,1,114,149,0,0, + 0,114,120,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,2,0,0,0,9,0,0,0,19, + 0,0,0,67,0,0,0,115,89,1,0,0,124,1,0,100, + 1,0,107,8,0,114,73,0,100,2,0,125,1,0,116,0, + 0,124,2,0,100,3,0,131,2,0,114,73,0,121,19,0, + 124,2,0,106,1,0,124,0,0,131,1,0,125,1,0,87, + 110,18,0,4,116,2,0,107,10,0,114,72,0,1,1,1, + 89,110,1,0,88,116,3,0,106,4,0,124,0,0,124,2, + 0,100,4,0,124,1,0,131,2,1,125,4,0,100,5,0, + 124,4,0,95,5,0,124,2,0,100,1,0,107,8,0,114, + 194,0,120,73,0,116,6,0,131,0,0,68,93,58,0,92, + 2,0,125,5,0,125,6,0,124,1,0,106,7,0,116,8, + 0,124,6,0,131,1,0,131,1,0,114,128,0,124,5,0, + 124,0,0,124,1,0,131,2,0,125,2,0,124,2,0,124, + 4,0,95,9,0,80,113,128,0,87,100,1,0,83,124,3, + 0,116,10,0,107,8,0,114,23,1,116,0,0,124,2,0, + 100,6,0,131,2,0,114,32,1,121,19,0,124,2,0,106, + 11,0,124,0,0,131,1,0,125,7,0,87,110,18,0,4, + 116,2,0,107,10,0,114,4,1,1,1,1,89,113,32,1, + 88,124,7,0,114,32,1,103,0,0,124,4,0,95,12,0, + 110,9,0,124,3,0,124,4,0,95,12,0,124,4,0,106, + 12,0,103,0,0,107,2,0,114,85,1,124,1,0,114,85, + 1,116,13,0,124,1,0,131,1,0,100,7,0,25,125,8, + 0,124,4,0,106,12,0,106,14,0,124,8,0,131,1,0, + 1,124,4,0,83,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,218,6,111,114,105,103,105,110,84,218,10,105,115, + 95,112,97,99,107,97,103,101,114,59,0,0,0,41,15,114, + 108,0,0,0,114,151,0,0,0,114,99,0,0,0,114,114, + 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,92,0,0,0, + 114,93,0,0,0,114,120,0,0,0,218,9,95,80,79,80, + 85,76,65,84,69,114,153,0,0,0,114,150,0,0,0,114, + 38,0,0,0,218,6,97,112,112,101,110,100,41,9,114,98, + 0,0,0,90,8,108,111,99,97,116,105,111,110,114,120,0, + 0,0,114,150,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,153,0,0,0,90,7,100,105,114,110, + 97,109,101,114,4,0,0,0,114,4,0,0,0,114,5,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,246,1,0,0,115, + 60,0,0,0,0,12,12,4,6,1,15,2,3,1,19,1, + 13,1,5,8,24,1,9,3,12,1,22,1,21,1,15,1, + 9,1,5,2,4,3,12,2,15,1,3,1,19,1,13,1, + 5,2,6,1,12,2,9,1,15,1,6,1,16,1,16,2, + 114,161,0,0,0,99,0,0,0,0,0,0,0,0,0,0, + 0,0,5,0,0,0,64,0,0,0,115,121,0,0,0,101, + 0,0,90,1,0,100,0,0,90,2,0,100,1,0,90,3, + 0,100,2,0,90,4,0,100,3,0,90,5,0,100,4,0, + 90,6,0,101,7,0,100,5,0,100,6,0,132,0,0,131, + 1,0,90,8,0,101,7,0,100,7,0,100,8,0,132,0, + 0,131,1,0,90,9,0,101,7,0,100,9,0,100,9,0, + 100,10,0,100,11,0,132,2,0,131,1,0,90,10,0,101, + 7,0,100,9,0,100,12,0,100,13,0,132,1,0,131,1, + 0,90,11,0,100,9,0,83,41,14,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,2,0,0,0,11, + 0,0,0,67,0,0,0,115,67,0,0,0,121,23,0,116, + 0,0,106,1,0,116,0,0,106,2,0,124,1,0,131,2, + 0,83,87,110,37,0,4,116,3,0,107,10,0,114,62,0, + 1,1,1,116,0,0,106,1,0,116,0,0,106,4,0,124, + 1,0,131,2,0,83,89,110,1,0,88,100,0,0,83,41, + 1,78,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,40,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,218,3,107,101,121,114,4, + 0,0,0,114,4,0,0,0,114,5,0,0,0,218,14,95, + 111,112,101,110,95,114,101,103,105,115,116,114,121,68,2,0, + 0,115,8,0,0,0,0,2,3,1,23,1,13,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,6,0,0, + 0,16,0,0,0,67,0,0,0,115,143,0,0,0,124,0, + 0,106,0,0,114,21,0,124,0,0,106,1,0,125,2,0, + 110,9,0,124,0,0,106,2,0,125,2,0,124,2,0,106, + 3,0,100,1,0,124,1,0,100,2,0,116,4,0,106,5, + 0,100,0,0,100,3,0,133,2,0,25,131,0,2,125,3, + 0,121,47,0,124,0,0,106,6,0,124,3,0,131,1,0, + 143,25,0,125,4,0,116,7,0,106,8,0,124,4,0,100, + 4,0,131,2,0,125,5,0,87,100,0,0,81,82,88,87, + 110,22,0,4,116,9,0,107,10,0,114,138,0,1,1,1, + 100,0,0,83,89,110,1,0,88,124,5,0,83,41,5,78, + 114,119,0,0,0,90,11,115,121,115,95,118,101,114,115,105, + 111,110,114,80,0,0,0,114,30,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,47,0, + 0,0,114,7,0,0,0,218,7,118,101,114,115,105,111,110, + 114,166,0,0,0,114,163,0,0,0,90,10,81,117,101,114, + 121,86,97,108,117,101,114,40,0,0,0,41,6,114,164,0, + 0,0,114,119,0,0,0,90,12,114,101,103,105,115,116,114, + 121,95,107,101,121,114,165,0,0,0,90,4,104,107,101,121, + 218,8,102,105,108,101,112,97,116,104,114,4,0,0,0,114, + 4,0,0,0,114,5,0,0,0,218,16,95,115,101,97,114, + 99,104,95,114,101,103,105,115,116,114,121,75,2,0,0,115, + 22,0,0,0,0,2,9,1,12,2,9,1,15,1,22,1, + 3,1,18,1,29,1,13,1,9,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,8,0,0,0, + 14,0,0,0,67,0,0,0,115,158,0,0,0,124,0,0, + 106,0,0,124,1,0,131,1,0,125,4,0,124,4,0,100, + 0,0,107,8,0,114,31,0,100,0,0,83,121,14,0,116, + 1,0,124,4,0,131,1,0,1,87,110,22,0,4,116,2, + 0,107,10,0,114,69,0,1,1,1,100,0,0,83,89,110, + 1,0,88,120,81,0,116,3,0,131,0,0,68,93,70,0, + 92,2,0,125,5,0,125,6,0,124,4,0,106,4,0,116, + 5,0,124,6,0,131,1,0,131,1,0,114,80,0,116,6, + 0,106,7,0,124,1,0,124,5,0,124,1,0,124,4,0, + 131,2,0,100,1,0,124,4,0,131,2,1,125,7,0,124, + 7,0,83,113,80,0,87,100,0,0,83,41,2,78,114,152, + 0,0,0,41,8,114,172,0,0,0,114,39,0,0,0,114, + 40,0,0,0,114,155,0,0,0,114,92,0,0,0,114,93, + 0,0,0,114,114,0,0,0,218,16,115,112,101,99,95,102, + 114,111,109,95,108,111,97,100,101,114,41,8,114,164,0,0, + 0,114,119,0,0,0,114,35,0,0,0,218,6,116,97,114, + 103,101,116,114,171,0,0,0,114,120,0,0,0,114,160,0, + 0,0,114,158,0,0,0,114,4,0,0,0,114,4,0,0, + 0,114,5,0,0,0,218,9,102,105,110,100,95,115,112,101, + 99,90,2,0,0,115,26,0,0,0,0,2,15,1,12,1, + 4,1,3,1,14,1,13,1,9,1,22,1,21,1,9,1, + 15,1,9,1,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,4,0, + 0,0,3,0,0,0,67,0,0,0,115,45,0,0,0,124, + 0,0,106,0,0,124,1,0,124,2,0,131,2,0,125,3, + 0,124,3,0,100,1,0,107,9,0,114,37,0,124,3,0, + 106,1,0,83,100,1,0,83,100,1,0,83,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,41,2,114, + 175,0,0,0,114,120,0,0,0,41,4,114,164,0,0,0, + 114,119,0,0,0,114,35,0,0,0,114,158,0,0,0,114, + 4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,11, + 102,105,110,100,95,109,111,100,117,108,101,106,2,0,0,115, + 8,0,0,0,0,7,18,1,12,1,7,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, + 12,114,105,0,0,0,114,104,0,0,0,114,106,0,0,0, + 114,107,0,0,0,114,169,0,0,0,114,168,0,0,0,114, + 167,0,0,0,218,11,99,108,97,115,115,109,101,116,104,111, + 100,114,166,0,0,0,114,172,0,0,0,114,175,0,0,0, + 114,176,0,0,0,114,4,0,0,0,114,4,0,0,0,114, + 4,0,0,0,114,5,0,0,0,114,162,0,0,0,56,2, + 0,0,115,20,0,0,0,12,2,6,3,6,3,6,2,6, + 2,18,7,18,15,3,1,21,15,3,1,114,162,0,0,0, + 99,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,64,0,0,0,115,70,0,0,0,101,0,0,90,1,0, + 100,0,0,90,2,0,100,1,0,90,3,0,100,2,0,100, + 3,0,132,0,0,90,4,0,100,4,0,100,5,0,132,0, + 0,90,5,0,100,6,0,100,7,0,132,0,0,90,6,0, + 100,8,0,100,9,0,132,0,0,90,7,0,100,10,0,83, + 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,5, + 0,0,0,3,0,0,0,67,0,0,0,115,88,0,0,0, + 116,0,0,124,0,0,106,1,0,124,1,0,131,1,0,131, + 1,0,100,1,0,25,125,2,0,124,2,0,106,2,0,100, + 2,0,100,1,0,131,2,0,100,3,0,25,125,3,0,124, + 1,0,106,3,0,100,2,0,131,1,0,100,4,0,25,125, + 4,0,124,3,0,100,5,0,107,2,0,111,87,0,124,4, + 0,100,5,0,107,3,0,83,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,29,0,0,0,114,58, + 0,0,0,114,59,0,0,0,114,56,0,0,0,218,8,95, + 95,105,110,105,116,95,95,41,4,114,38,0,0,0,114,151, + 0,0,0,114,34,0,0,0,114,32,0,0,0,41,5,114, + 100,0,0,0,114,119,0,0,0,114,94,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,4,0,0,0,114,4,0, + 0,0,114,5,0,0,0,114,153,0,0,0,125,2,0,0, + 115,8,0,0,0,0,3,25,1,22,1,19,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, + 2,0,0,0,1,0,0,0,67,0,0,0,115,4,0,0, + 0,100,1,0,83,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,4,0,0,0,41,2,114,100,0,0,0, + 114,158,0,0,0,114,4,0,0,0,114,4,0,0,0,114, + 5,0,0,0,218,13,99,114,101,97,116,101,95,109,111,100, + 117,108,101,133,2,0,0,115,0,0,0,0,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,3,0,0,0,4,0,0,0,67,0,0,0,115,80, + 0,0,0,124,0,0,106,0,0,124,1,0,106,1,0,131, + 1,0,125,2,0,124,2,0,100,1,0,107,8,0,114,54, + 0,116,2,0,100,2,0,106,3,0,124,1,0,106,1,0, + 131,1,0,131,1,0,130,1,0,116,4,0,106,5,0,116, + 6,0,124,2,0,124,1,0,106,7,0,131,3,0,1,100, + 1,0,83,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,105,0, + 0,0,114,99,0,0,0,114,47,0,0,0,114,114,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,111,0,0,0,41,3,114,100,0,0,0,218,6, + 109,111,100,117,108,101,114,140,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,218,11,101,120,101,99, + 95,109,111,100,117,108,101,136,2,0,0,115,10,0,0,0, + 0,2,18,1,12,1,9,1,15,1,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,2,0, + 0,0,3,0,0,0,67,0,0,0,115,16,0,0,0,116, + 0,0,106,1,0,124,0,0,124,1,0,131,2,0,83,41, + 1,78,41,2,114,114,0,0,0,218,17,95,108,111,97,100, + 95,109,111,100,117,108,101,95,115,104,105,109,41,2,114,100, + 0,0,0,114,119,0,0,0,114,4,0,0,0,114,4,0, + 0,0,114,5,0,0,0,218,11,108,111,97,100,95,109,111, + 100,117,108,101,144,2,0,0,115,2,0,0,0,0,1,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,105,0, + 0,0,114,104,0,0,0,114,106,0,0,0,114,107,0,0, + 0,114,153,0,0,0,114,180,0,0,0,114,185,0,0,0, + 114,187,0,0,0,114,4,0,0,0,114,4,0,0,0,114, + 4,0,0,0,114,5,0,0,0,114,178,0,0,0,120,2, + 0,0,115,10,0,0,0,12,3,6,2,12,8,12,3,12, + 8,114,178,0,0,0,99,0,0,0,0,0,0,0,0,0, + 0,0,0,4,0,0,0,64,0,0,0,115,106,0,0,0, + 101,0,0,90,1,0,100,0,0,90,2,0,100,1,0,100, + 2,0,132,0,0,90,3,0,100,3,0,100,4,0,132,0, + 0,90,4,0,100,5,0,100,6,0,132,0,0,90,5,0, + 100,7,0,100,8,0,132,0,0,90,6,0,100,9,0,100, + 10,0,132,0,0,90,7,0,100,11,0,100,18,0,100,13, + 0,100,14,0,132,0,1,90,8,0,100,15,0,100,16,0, + 132,0,0,90,9,0,100,17,0,83,41,19,218,12,83,111, + 117,114,99,101,76,111,97,100,101,114,99,2,0,0,0,0, + 0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,115, + 10,0,0,0,116,0,0,130,1,0,100,1,0,83,41,2, + 122,178,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,44,32,119,104, + 101,114,101,32,112,97,116,104,32,105,115,32,97,32,115,116, + 114,46,10,10,32,32,32,32,32,32,32,32,82,97,105,115, + 101,115,32,73,79,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,218,7,73,79,69,114,114,111,114, + 41,2,114,100,0,0,0,114,35,0,0,0,114,4,0,0, + 0,114,4,0,0,0,114,5,0,0,0,218,10,112,97,116, + 104,95,109,116,105,109,101,150,2,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,2,0,0,0,3,0,0,0,67,0,0,0, + 115,19,0,0,0,100,1,0,124,0,0,106,0,0,124,1, + 0,131,1,0,105,1,0,83,41,2,97,170,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,32,112,97,116,104,10, + 32,32,32,32,32,32,32,32,116,111,32,98,121,32,116,104, + 101,32,112,97,116,104,32,40,115,116,114,41,46,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,73,79,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,126,0,0,0,41,1, + 114,190,0,0,0,41,2,114,100,0,0,0,114,35,0,0, + 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, + 218,10,112,97,116,104,95,115,116,97,116,115,158,2,0,0, + 115,2,0,0,0,0,11,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,4,0,0,0,3,0,0, + 0,67,0,0,0,115,16,0,0,0,124,0,0,106,0,0, + 124,2,0,124,3,0,131,2,0,83,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,100,0,0,0,114,90,0,0,0,90,10,99,97,99,104, + 101,95,112,97,116,104,114,53,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,218,15,95,99,97,99, + 104,101,95,98,121,116,101,99,111,100,101,171,2,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,3,0,0, + 0,1,0,0,0,67,0,0,0,115,4,0,0,0,100,1, + 0,83,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,4,0, + 0,0,41,3,114,100,0,0,0,114,35,0,0,0,114,53, + 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, + 0,0,114,192,0,0,0,181,2,0,0,115,0,0,0,0, + 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, + 5,0,0,0,16,0,0,0,67,0,0,0,115,105,0,0, + 0,124,0,0,106,0,0,124,1,0,131,1,0,125,2,0, + 121,19,0,124,0,0,106,1,0,124,2,0,131,1,0,125, + 3,0,87,110,58,0,4,116,2,0,107,10,0,114,94,0, + 1,125,4,0,1,122,26,0,116,3,0,100,1,0,100,2, + 0,124,1,0,131,1,1,124,4,0,130,2,0,87,89,100, + 3,0,100,3,0,125,4,0,126,4,0,88,110,1,0,88, + 116,4,0,124,3,0,131,1,0,83,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,98,0,0,0, + 78,41,5,114,151,0,0,0,218,8,103,101,116,95,100,97, + 116,97,114,40,0,0,0,114,99,0,0,0,114,149,0,0, + 0,41,5,114,100,0,0,0,114,119,0,0,0,114,35,0, + 0,0,114,147,0,0,0,218,3,101,120,99,114,4,0,0, + 0,114,4,0,0,0,114,5,0,0,0,218,10,103,101,116, + 95,115,111,117,114,99,101,188,2,0,0,115,14,0,0,0, + 0,2,15,1,3,1,19,1,18,1,9,1,31,1,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,218,9,95,111,112,116,105,109,105, + 122,101,114,29,0,0,0,99,3,0,0,0,1,0,0,0, + 4,0,0,0,9,0,0,0,67,0,0,0,115,34,0,0, + 0,116,0,0,106,1,0,116,2,0,124,1,0,124,2,0, + 100,1,0,100,2,0,100,3,0,100,4,0,124,3,0,131, + 4,2,83,41,5,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,183,0,0,0,218,12, + 100,111,110,116,95,105,110,104,101,114,105,116,84,114,68,0, + 0,0,41,3,114,114,0,0,0,114,182,0,0,0,218,7, + 99,111,109,112,105,108,101,41,4,114,100,0,0,0,114,53, + 0,0,0,114,35,0,0,0,114,197,0,0,0,114,4,0, + 0,0,114,4,0,0,0,114,5,0,0,0,218,14,115,111, + 117,114,99,101,95,116,111,95,99,111,100,101,198,2,0,0, + 115,4,0,0,0,0,5,21,1,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,10, + 0,0,0,43,0,0,0,67,0,0,0,115,183,1,0,0, + 124,0,0,106,0,0,124,1,0,131,1,0,125,2,0,100, + 1,0,125,3,0,121,16,0,116,1,0,124,2,0,131,1, + 0,125,4,0,87,110,24,0,4,116,2,0,107,10,0,114, + 63,0,1,1,1,100,1,0,125,4,0,89,110,205,0,88, + 121,19,0,124,0,0,106,3,0,124,2,0,131,1,0,125, + 5,0,87,110,18,0,4,116,4,0,107,10,0,114,103,0, + 1,1,1,89,110,165,0,88,116,5,0,124,5,0,100,2, + 0,25,131,1,0,125,3,0,121,19,0,124,0,0,106,6, + 0,124,4,0,131,1,0,125,6,0,87,110,18,0,4,116, + 7,0,107,10,0,114,159,0,1,1,1,89,110,109,0,88, + 121,34,0,116,8,0,124,6,0,100,3,0,124,5,0,100, + 4,0,124,1,0,100,5,0,124,4,0,131,1,3,125,7, + 0,87,110,24,0,4,116,9,0,116,10,0,102,2,0,107, + 10,0,114,220,0,1,1,1,89,110,48,0,88,116,11,0, + 106,12,0,100,6,0,124,4,0,124,2,0,131,3,0,1, + 116,13,0,124,7,0,100,4,0,124,1,0,100,7,0,124, + 4,0,100,8,0,124,2,0,131,1,3,83,124,0,0,106, + 6,0,124,2,0,131,1,0,125,8,0,124,0,0,106,14, + 0,124,8,0,124,2,0,131,2,0,125,9,0,116,11,0, + 106,12,0,100,9,0,124,2,0,131,2,0,1,116,15,0, + 106,16,0,12,114,179,1,124,4,0,100,1,0,107,9,0, + 114,179,1,124,3,0,100,1,0,107,9,0,114,179,1,116, + 17,0,124,9,0,124,3,0,116,18,0,124,8,0,131,1, + 0,131,3,0,125,6,0,121,39,0,124,0,0,106,19,0, + 124,2,0,124,4,0,124,6,0,131,3,0,1,116,11,0, + 106,12,0,100,10,0,124,4,0,131,2,0,1,87,110,18, + 0,4,116,2,0,107,10,0,114,178,1,1,1,1,89,110, + 1,0,88,124,9,0,83,41,11,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,114,126,0,0,0,114, + 132,0,0,0,114,98,0,0,0,114,35,0,0,0,122,13, + 123,125,32,109,97,116,99,104,101,115,32,123,125,114,89,0, + 0,0,114,90,0,0,0,122,19,99,111,100,101,32,111,98, + 106,101,99,116,32,102,114,111,109,32,123,125,122,10,119,114, + 111,116,101,32,123,33,114,125,41,20,114,151,0,0,0,114, + 79,0,0,0,114,66,0,0,0,114,191,0,0,0,114,189, + 0,0,0,114,14,0,0,0,114,194,0,0,0,114,40,0, + 0,0,114,135,0,0,0,114,99,0,0,0,114,130,0,0, + 0,114,114,0,0,0,114,129,0,0,0,114,141,0,0,0, + 114,200,0,0,0,114,7,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, + 144,0,0,0,114,31,0,0,0,114,193,0,0,0,41,10, + 114,100,0,0,0,114,119,0,0,0,114,90,0,0,0,114, + 133,0,0,0,114,89,0,0,0,218,2,115,116,114,53,0, + 0,0,218,10,98,121,116,101,115,95,100,97,116,97,114,147, + 0,0,0,90,11,99,111,100,101,95,111,98,106,101,99,116, + 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, + 181,0,0,0,206,2,0,0,115,78,0,0,0,0,7,15, + 1,6,1,3,1,16,1,13,1,11,2,3,1,19,1,13, + 1,5,2,16,1,3,1,19,1,13,1,5,2,3,1,9, + 1,12,1,13,1,19,1,5,2,12,1,7,1,15,1,6, + 1,7,1,15,1,18,1,16,1,22,1,12,1,9,1,15, + 1,3,1,19,1,20,1,13,1,5,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,114,87,0,0,0,41,10,114,105,0,0,0,114, + 104,0,0,0,114,106,0,0,0,114,190,0,0,0,114,191, + 0,0,0,114,193,0,0,0,114,192,0,0,0,114,196,0, + 0,0,114,200,0,0,0,114,181,0,0,0,114,4,0,0, + 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, + 114,188,0,0,0,148,2,0,0,115,14,0,0,0,12,2, + 12,8,12,13,12,10,12,7,12,10,18,8,114,188,0,0, + 0,99,0,0,0,0,0,0,0,0,0,0,0,0,4,0, + 0,0,0,0,0,0,115,112,0,0,0,101,0,0,90,1, + 0,100,0,0,90,2,0,100,1,0,90,3,0,100,2,0, + 100,3,0,132,0,0,90,4,0,100,4,0,100,5,0,132, + 0,0,90,5,0,100,6,0,100,7,0,132,0,0,90,6, + 0,101,7,0,135,0,0,102,1,0,100,8,0,100,9,0, + 134,0,0,131,1,0,90,8,0,101,7,0,100,10,0,100, + 11,0,132,0,0,131,1,0,90,9,0,100,12,0,100,13, + 0,132,0,0,90,10,0,135,0,0,83,41,14,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,3,0,0,0,2, + 0,0,0,67,0,0,0,115,22,0,0,0,124,1,0,124, + 0,0,95,0,0,124,2,0,124,0,0,95,1,0,100,1, + 0,83,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,41,2,114,98,0,0,0,114,35,0,0,0,41,3, + 114,100,0,0,0,114,119,0,0,0,114,35,0,0,0,114, + 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,179, + 0,0,0,7,3,0,0,115,4,0,0,0,0,3,9,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,2,0, + 0,0,2,0,0,0,67,0,0,0,115,34,0,0,0,124, + 0,0,106,0,0,124,1,0,106,0,0,107,2,0,111,33, + 0,124,0,0,106,1,0,124,1,0,106,1,0,107,2,0, + 83,41,1,78,41,2,218,9,95,95,99,108,97,115,115,95, + 95,114,111,0,0,0,41,2,114,100,0,0,0,218,5,111, + 116,104,101,114,114,4,0,0,0,114,4,0,0,0,114,5, + 0,0,0,218,6,95,95,101,113,95,95,13,3,0,0,115, + 4,0,0,0,0,1,18,1,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,1,0,0,0,3,0,0,0,67,0,0,0, + 115,26,0,0,0,116,0,0,124,0,0,106,1,0,131,1, + 0,116,0,0,124,0,0,106,2,0,131,1,0,65,83,41, + 1,78,41,3,218,4,104,97,115,104,114,98,0,0,0,114, + 35,0,0,0,41,1,114,100,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,218,8,95,95,104,97, + 115,104,95,95,17,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,2,0,0, + 0,3,0,0,0,3,0,0,0,115,22,0,0,0,116,0, + 0,116,1,0,124,0,0,131,2,0,106,2,0,124,1,0, + 131,1,0,83,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,204,0,0,0,114,187,0,0,0,41, + 2,114,100,0,0,0,114,119,0,0,0,41,1,114,205,0, + 0,0,114,4,0,0,0,114,5,0,0,0,114,187,0,0, + 0,20,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,2,0,0, + 0,1,0,0,0,67,0,0,0,115,7,0,0,0,124,0, + 0,106,0,0,83,41,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,41,1,114,35,0,0,0,41,2,114,100,0,0, + 0,114,119,0,0,0,114,4,0,0,0,114,4,0,0,0, + 114,5,0,0,0,114,151,0,0,0,32,3,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,3,0,0,0,9,0,0,0,67, + 0,0,0,115,42,0,0,0,116,0,0,106,1,0,124,1, + 0,100,1,0,131,2,0,143,17,0,125,2,0,124,2,0, + 106,2,0,131,0,0,83,87,100,2,0,81,82,88,100,2, + 0,83,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,3,114,49,0,0,0,114,50,0,0,0,90,4,114, + 101,97,100,41,3,114,100,0,0,0,114,35,0,0,0,114, + 54,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, + 0,0,0,114,194,0,0,0,37,3,0,0,115,4,0,0, + 0,0,2,21,1,122,19,70,105,108,101,76,111,97,100,101, + 114,46,103,101,116,95,100,97,116,97,41,11,114,105,0,0, + 0,114,104,0,0,0,114,106,0,0,0,114,107,0,0,0, + 114,179,0,0,0,114,207,0,0,0,114,209,0,0,0,114, + 116,0,0,0,114,187,0,0,0,114,151,0,0,0,114,194, + 0,0,0,114,4,0,0,0,114,4,0,0,0,41,1,114, + 205,0,0,0,114,5,0,0,0,114,204,0,0,0,2,3, + 0,0,115,14,0,0,0,12,3,6,2,12,6,12,4,12, + 3,24,12,18,5,114,204,0,0,0,99,0,0,0,0,0, + 0,0,0,0,0,0,0,4,0,0,0,64,0,0,0,115, + 64,0,0,0,101,0,0,90,1,0,100,0,0,90,2,0, + 100,1,0,90,3,0,100,2,0,100,3,0,132,0,0,90, + 4,0,100,4,0,100,5,0,132,0,0,90,5,0,100,6, + 0,100,7,0,100,8,0,100,9,0,132,0,1,90,6,0, + 100,10,0,83,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,3,0,0,0,4,0,0,0,67,0,0,0,115,34,0, + 0,0,116,0,0,124,1,0,131,1,0,125,2,0,100,1, + 0,124,2,0,106,1,0,100,2,0,124,2,0,106,2,0, + 105,2,0,83,41,3,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,114,126,0,0,0,114,127, + 0,0,0,41,3,114,39,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, + 100,0,0,0,114,35,0,0,0,114,202,0,0,0,114,4, + 0,0,0,114,4,0,0,0,114,5,0,0,0,114,191,0, + 0,0,47,3,0,0,115,4,0,0,0,0,2,12,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,5,0,0,0,5,0,0,0,67,0,0, + 0,115,34,0,0,0,116,0,0,124,1,0,131,1,0,125, + 4,0,124,0,0,106,1,0,124,2,0,124,3,0,100,1, + 0,124,4,0,131,2,1,83,41,2,78,218,5,95,109,111, + 100,101,41,2,114,97,0,0,0,114,192,0,0,0,41,5, + 114,100,0,0,0,114,90,0,0,0,114,89,0,0,0,114, + 53,0,0,0,114,42,0,0,0,114,4,0,0,0,114,4, + 0,0,0,114,5,0,0,0,114,193,0,0,0,52,3,0, + 0,115,4,0,0,0,0,2,12,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,214,0,0, + 0,105,182,1,0,0,99,3,0,0,0,1,0,0,0,9, + 0,0,0,17,0,0,0,67,0,0,0,115,62,1,0,0, + 116,0,0,124,1,0,131,1,0,92,2,0,125,4,0,125, + 5,0,103,0,0,125,6,0,120,54,0,124,4,0,114,80, + 0,116,1,0,124,4,0,131,1,0,12,114,80,0,116,0, + 0,124,4,0,131,1,0,92,2,0,125,4,0,125,7,0, + 124,6,0,106,2,0,124,7,0,131,1,0,1,113,27,0, + 87,120,135,0,116,3,0,124,6,0,131,1,0,68,93,121, + 0,125,7,0,116,4,0,124,4,0,124,7,0,131,2,0, + 125,4,0,121,17,0,116,5,0,106,6,0,124,4,0,131, + 1,0,1,87,113,94,0,4,116,7,0,107,10,0,114,155, + 0,1,1,1,119,94,0,89,113,94,0,4,116,8,0,107, + 10,0,114,214,0,1,125,8,0,1,122,28,0,116,9,0, + 106,10,0,100,1,0,124,4,0,124,8,0,131,3,0,1, + 100,2,0,83,87,89,100,2,0,100,2,0,125,8,0,126, + 8,0,88,113,94,0,88,113,94,0,87,121,36,0,116,11, + 0,124,1,0,124,2,0,124,3,0,131,3,0,1,116,9, + 0,106,10,0,100,3,0,124,1,0,131,2,0,1,87,110, + 56,0,4,116,8,0,107,10,0,114,57,1,1,125,8,0, + 1,122,24,0,116,9,0,106,10,0,100,1,0,124,1,0, + 124,8,0,131,3,0,1,87,89,100,2,0,100,2,0,125, + 8,0,126,8,0,88,110,1,0,88,100,2,0,83,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,38,0,0,0, + 114,46,0,0,0,114,157,0,0,0,114,33,0,0,0,114, + 28,0,0,0,114,3,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,40,0,0,0,114,114,0,0,0,114,129,0,0,0, + 114,55,0,0,0,41,9,114,100,0,0,0,114,35,0,0, + 0,114,53,0,0,0,114,214,0,0,0,218,6,112,97,114, + 101,110,116,114,94,0,0,0,114,27,0,0,0,114,23,0, + 0,0,114,195,0,0,0,114,4,0,0,0,114,4,0,0, + 0,114,5,0,0,0,114,192,0,0,0,57,3,0,0,115, + 42,0,0,0,0,2,18,1,6,2,22,1,18,1,17,2, + 19,1,15,1,3,1,17,1,13,2,7,1,18,3,9,1, + 10,1,27,1,3,1,16,1,20,1,18,2,12,1,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,105,0,0, + 0,114,104,0,0,0,114,106,0,0,0,114,107,0,0,0, + 114,191,0,0,0,114,193,0,0,0,114,192,0,0,0,114, + 4,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, + 0,0,0,114,212,0,0,0,43,3,0,0,115,8,0,0, + 0,12,2,6,2,12,5,12,5,114,212,0,0,0,99,0, + 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,64, + 0,0,0,115,46,0,0,0,101,0,0,90,1,0,100,0, + 0,90,2,0,100,1,0,90,3,0,100,2,0,100,3,0, + 132,0,0,90,4,0,100,4,0,100,5,0,132,0,0,90, + 5,0,100,6,0,83,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,5,0,0,0,6,0,0,0,67,0, + 0,0,115,76,0,0,0,124,0,0,106,0,0,124,1,0, + 131,1,0,125,2,0,124,0,0,106,1,0,124,2,0,131, + 1,0,125,3,0,116,2,0,124,3,0,100,1,0,124,1, + 0,100,2,0,124,2,0,131,1,2,125,4,0,116,3,0, + 124,4,0,100,1,0,124,1,0,100,3,0,124,2,0,131, + 1,2,83,41,4,78,114,98,0,0,0,114,35,0,0,0, + 114,89,0,0,0,41,4,114,151,0,0,0,114,194,0,0, + 0,114,135,0,0,0,114,141,0,0,0,41,5,114,100,0, + 0,0,114,119,0,0,0,114,35,0,0,0,114,53,0,0, + 0,114,203,0,0,0,114,4,0,0,0,114,4,0,0,0, + 114,5,0,0,0,114,181,0,0,0,92,3,0,0,115,8, + 0,0,0,0,1,15,1,15,1,24,1,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,2,0,0,0,1,0,0,0,67,0,0,0,115, + 4,0,0,0,100,1,0,83,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,4,0,0,0,41,2,114,100,0,0,0, + 114,119,0,0,0,114,4,0,0,0,114,4,0,0,0,114, + 5,0,0,0,114,196,0,0,0,98,3,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,105,0,0,0,114,104,0, + 0,0,114,106,0,0,0,114,107,0,0,0,114,181,0,0, + 0,114,196,0,0,0,114,4,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,114,217,0,0,0,88, + 3,0,0,115,6,0,0,0,12,2,6,2,12,6,114,217, + 0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,64,0,0,0,115,136,0,0,0,101,0,0, + 90,1,0,100,0,0,90,2,0,100,1,0,90,3,0,100, + 2,0,100,3,0,132,0,0,90,4,0,100,4,0,100,5, + 0,132,0,0,90,5,0,100,6,0,100,7,0,132,0,0, + 90,6,0,100,8,0,100,9,0,132,0,0,90,7,0,100, + 10,0,100,11,0,132,0,0,90,8,0,100,12,0,100,13, + 0,132,0,0,90,9,0,100,14,0,100,15,0,132,0,0, + 90,10,0,100,16,0,100,17,0,132,0,0,90,11,0,101, + 12,0,100,18,0,100,19,0,132,0,0,131,1,0,90,13, + 0,100,20,0,83,41,21,218,19,69,120,116,101,110,115,105, + 111,110,70,105,108,101,76,111,97,100,101,114,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,3,0,0,0,2,0,0,0,67,0,0,0, + 115,22,0,0,0,124,1,0,124,0,0,95,0,0,124,2, + 0,124,0,0,95,1,0,100,0,0,83,41,1,78,41,2, + 114,98,0,0,0,114,35,0,0,0,41,3,114,100,0,0, + 0,114,98,0,0,0,114,35,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,5,0,0,0,114,179,0,0,0,115, + 3,0,0,115,4,0,0,0,0,1,9,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,2,0,0,0,2,0,0,0,67,0,0,0,115, + 34,0,0,0,124,0,0,106,0,0,124,1,0,106,0,0, + 107,2,0,111,33,0,124,0,0,106,1,0,124,1,0,106, + 1,0,107,2,0,83,41,1,78,41,2,114,205,0,0,0, + 114,111,0,0,0,41,2,114,100,0,0,0,114,206,0,0, + 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, + 114,207,0,0,0,119,3,0,0,115,4,0,0,0,0,1, + 18,1,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,1,0,0,0,3,0,0,0,67, + 0,0,0,115,26,0,0,0,116,0,0,124,0,0,106,1, + 0,131,1,0,116,0,0,124,0,0,106,2,0,131,1,0, + 65,83,41,1,78,41,3,114,208,0,0,0,114,98,0,0, + 0,114,35,0,0,0,41,1,114,100,0,0,0,114,4,0, + 0,0,114,4,0,0,0,114,5,0,0,0,114,209,0,0, + 0,123,3,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,3,0,0,0,4,0,0,0,67,0,0,0,115, + 50,0,0,0,116,0,0,106,1,0,116,2,0,106,3,0, + 124,1,0,131,2,0,125,2,0,116,0,0,106,4,0,100, + 1,0,124,1,0,106,5,0,124,0,0,106,6,0,131,3, + 0,1,124,2,0,83,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,114,0,0,0,114, + 182,0,0,0,114,139,0,0,0,90,14,99,114,101,97,116, + 101,95,100,121,110,97,109,105,99,114,129,0,0,0,114,98, + 0,0,0,114,35,0,0,0,41,3,114,100,0,0,0,114, + 158,0,0,0,114,184,0,0,0,114,4,0,0,0,114,4, + 0,0,0,114,5,0,0,0,114,180,0,0,0,126,3,0, + 0,115,10,0,0,0,0,2,6,1,15,1,9,1,16,1, + 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,2,0,0,0, + 4,0,0,0,67,0,0,0,115,48,0,0,0,116,0,0, + 106,1,0,116,2,0,106,3,0,124,1,0,131,2,0,1, + 116,0,0,106,4,0,100,1,0,124,0,0,106,5,0,124, + 0,0,106,6,0,131,3,0,1,100,2,0,83,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,114,0,0, + 0,114,182,0,0,0,114,139,0,0,0,90,12,101,120,101, + 99,95,100,121,110,97,109,105,99,114,129,0,0,0,114,98, + 0,0,0,114,35,0,0,0,41,2,114,100,0,0,0,114, + 184,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, + 0,0,0,114,185,0,0,0,134,3,0,0,115,6,0,0, + 0,0,2,19,1,9,1,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,2,0,0,0,4,0,0,0,3,0,0,0,115,48,0, + 0,0,116,0,0,124,0,0,106,1,0,131,1,0,100,1, + 0,25,137,0,0,116,2,0,135,0,0,102,1,0,100,2, + 0,100,3,0,134,0,0,116,3,0,68,131,1,0,131,1, + 0,83,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,29,0,0,0,99,1,0,0, + 0,0,0,0,0,2,0,0,0,4,0,0,0,51,0,0, + 0,115,31,0,0,0,124,0,0,93,21,0,125,1,0,136, + 0,0,100,0,0,124,1,0,23,107,2,0,86,1,113,3, + 0,100,1,0,83,41,2,114,179,0,0,0,78,114,4,0, + 0,0,41,2,114,22,0,0,0,218,6,115,117,102,102,105, + 120,41,1,218,9,102,105,108,101,95,110,97,109,101,114,4, + 0,0,0,114,5,0,0,0,250,9,60,103,101,110,101,120, + 112,114,62,143,3,0,0,115,2,0,0,0,6,1,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,38,0,0,0,114,35,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,41,2,114,100,0,0,0,114,119,0, + 0,0,114,4,0,0,0,41,1,114,220,0,0,0,114,5, + 0,0,0,114,153,0,0,0,140,3,0,0,115,6,0,0, + 0,0,2,19,1,18,1,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, + 2,0,0,0,1,0,0,0,67,0,0,0,115,4,0,0, + 0,100,1,0,83,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,4,0,0,0,41,2, + 114,100,0,0,0,114,119,0,0,0,114,4,0,0,0,114, + 4,0,0,0,114,5,0,0,0,114,181,0,0,0,146,3, + 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, + 2,0,0,0,1,0,0,0,67,0,0,0,115,4,0,0, + 0,100,1,0,83,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, + 4,0,0,0,41,2,114,100,0,0,0,114,119,0,0,0, + 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, + 196,0,0,0,150,3,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,2,0,0,0,1,0,0,0, + 67,0,0,0,115,7,0,0,0,124,0,0,106,0,0,83, + 41,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,41,1, + 114,35,0,0,0,41,2,114,100,0,0,0,114,119,0,0, + 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, + 114,151,0,0,0,154,3,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,105,0,0,0,114,104,0,0,0,114, + 106,0,0,0,114,107,0,0,0,114,179,0,0,0,114,207, + 0,0,0,114,209,0,0,0,114,180,0,0,0,114,185,0, + 0,0,114,153,0,0,0,114,181,0,0,0,114,196,0,0, + 0,114,116,0,0,0,114,151,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, + 218,0,0,0,107,3,0,0,115,20,0,0,0,12,6,6, + 2,12,4,12,4,12,3,12,8,12,6,12,6,12,4,12, + 4,114,218,0,0,0,99,0,0,0,0,0,0,0,0,0, + 0,0,0,2,0,0,0,64,0,0,0,115,130,0,0,0, + 101,0,0,90,1,0,100,0,0,90,2,0,100,1,0,90, + 3,0,100,2,0,100,3,0,132,0,0,90,4,0,100,4, + 0,100,5,0,132,0,0,90,5,0,100,6,0,100,7,0, + 132,0,0,90,6,0,100,8,0,100,9,0,132,0,0,90, + 7,0,100,10,0,100,11,0,132,0,0,90,8,0,100,12, + 0,100,13,0,132,0,0,90,9,0,100,14,0,100,15,0, + 132,0,0,90,10,0,100,16,0,100,17,0,132,0,0,90, + 11,0,100,18,0,100,19,0,132,0,0,90,12,0,100,20, + 0,83,41,21,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,4,0,0,0,2,0,0,0, + 67,0,0,0,115,52,0,0,0,124,1,0,124,0,0,95, + 0,0,124,2,0,124,0,0,95,1,0,116,2,0,124,0, + 0,106,3,0,131,0,0,131,1,0,124,0,0,95,4,0, + 124,3,0,124,0,0,95,5,0,100,0,0,83,41,1,78, + 41,6,218,5,95,110,97,109,101,218,5,95,112,97,116,104, + 114,93,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,41,4,114,100,0,0,0,114, + 98,0,0,0,114,35,0,0,0,218,11,112,97,116,104,95, + 102,105,110,100,101,114,114,4,0,0,0,114,4,0,0,0, + 114,5,0,0,0,114,179,0,0,0,167,3,0,0,115,8, + 0,0,0,0,1,9,1,9,1,21,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,4,0,0, + 0,3,0,0,0,67,0,0,0,115,53,0,0,0,124,0, + 0,106,0,0,106,1,0,100,1,0,131,1,0,92,3,0, + 125,1,0,125,2,0,125,3,0,124,2,0,100,2,0,107, + 2,0,114,43,0,100,6,0,83,124,1,0,100,5,0,102, + 2,0,83,41,7,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,58,0,0,0,114,30,0,0,0,114, + 7,0,0,0,114,35,0,0,0,90,8,95,95,112,97,116, + 104,95,95,41,2,122,3,115,121,115,122,4,112,97,116,104, + 41,2,114,225,0,0,0,114,32,0,0,0,41,4,114,100, + 0,0,0,114,216,0,0,0,218,3,100,111,116,90,2,109, + 101,114,4,0,0,0,114,4,0,0,0,114,5,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,173,3,0,0,115,8,0, + 0,0,0,2,27,1,12,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,3,0,0,0,3, + 0,0,0,67,0,0,0,115,38,0,0,0,124,0,0,106, + 0,0,131,0,0,92,2,0,125,1,0,125,2,0,116,1, + 0,116,2,0,106,3,0,124,1,0,25,124,2,0,131,2, + 0,83,41,1,78,41,4,114,232,0,0,0,114,110,0,0, + 0,114,7,0,0,0,218,7,109,111,100,117,108,101,115,41, + 3,114,100,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,4,0,0,0,114, + 4,0,0,0,114,5,0,0,0,114,227,0,0,0,183,3, + 0,0,115,4,0,0,0,0,1,18,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,3,0,0,0,3,0,0,0,67,0,0, + 0,115,118,0,0,0,116,0,0,124,0,0,106,1,0,131, + 0,0,131,1,0,125,1,0,124,1,0,124,0,0,106,2, + 0,107,3,0,114,111,0,124,0,0,106,3,0,124,0,0, + 106,4,0,124,1,0,131,2,0,125,2,0,124,2,0,100, + 0,0,107,9,0,114,102,0,124,2,0,106,5,0,100,0, + 0,107,8,0,114,102,0,124,2,0,106,6,0,114,102,0, + 124,2,0,106,6,0,124,0,0,95,7,0,124,1,0,124, + 0,0,95,2,0,124,0,0,106,7,0,83,41,1,78,41, + 8,114,93,0,0,0,114,227,0,0,0,114,228,0,0,0, + 114,229,0,0,0,114,225,0,0,0,114,120,0,0,0,114, + 150,0,0,0,114,226,0,0,0,41,3,114,100,0,0,0, + 90,11,112,97,114,101,110,116,95,112,97,116,104,114,158,0, + 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, + 0,218,12,95,114,101,99,97,108,99,117,108,97,116,101,187, + 3,0,0,115,16,0,0,0,0,2,18,1,15,1,21,3, + 27,1,9,1,12,1,9,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,1,0, + 0,0,2,0,0,0,67,0,0,0,115,16,0,0,0,116, + 0,0,124,0,0,106,1,0,131,0,0,131,1,0,83,41, + 1,78,41,2,218,4,105,116,101,114,114,234,0,0,0,41, + 1,114,100,0,0,0,114,4,0,0,0,114,4,0,0,0, + 114,5,0,0,0,218,8,95,95,105,116,101,114,95,95,200, + 3,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,1,0,0,0,0,0,0,0,1,0,0,0, + 2,0,0,0,67,0,0,0,115,16,0,0,0,116,0,0, + 124,0,0,106,1,0,131,0,0,131,1,0,83,41,1,78, + 41,2,114,31,0,0,0,114,234,0,0,0,41,1,114,100, + 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, + 0,0,218,7,95,95,108,101,110,95,95,203,3,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,1,0,0,0,2,0,0,0,67, + 0,0,0,115,16,0,0,0,100,1,0,106,0,0,124,0, + 0,106,1,0,131,1,0,83,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,47,0,0,0,114,226,0,0,0,41,1,114, + 100,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, + 0,0,0,218,8,95,95,114,101,112,114,95,95,206,3,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,2,0,0,0,2,0, + 0,0,67,0,0,0,115,16,0,0,0,124,1,0,124,0, + 0,106,0,0,131,0,0,107,6,0,83,41,1,78,41,1, + 114,234,0,0,0,41,2,114,100,0,0,0,218,4,105,116, + 101,109,114,4,0,0,0,114,4,0,0,0,114,5,0,0, + 0,218,12,95,95,99,111,110,116,97,105,110,115,95,95,209, + 3,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, + 2,0,0,0,2,0,0,0,67,0,0,0,115,20,0,0, + 0,124,0,0,106,0,0,106,1,0,124,1,0,131,1,0, + 1,100,0,0,83,41,1,78,41,2,114,226,0,0,0,114, + 157,0,0,0,41,2,114,100,0,0,0,114,239,0,0,0, + 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, + 157,0,0,0,212,3,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,13,114,105,0,0,0,114,104, + 0,0,0,114,106,0,0,0,114,107,0,0,0,114,179,0, + 0,0,114,232,0,0,0,114,227,0,0,0,114,234,0,0, + 0,114,236,0,0,0,114,237,0,0,0,114,238,0,0,0, + 114,240,0,0,0,114,157,0,0,0,114,4,0,0,0,114, + 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,224, + 0,0,0,160,3,0,0,115,20,0,0,0,12,5,6,2, + 12,6,12,10,12,4,12,13,12,3,12,3,12,3,12,3, + 114,224,0,0,0,99,0,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,0,64,0,0,0,115,118,0,0,0,101, + 0,0,90,1,0,100,0,0,90,2,0,100,1,0,100,2, + 0,132,0,0,90,3,0,101,4,0,100,3,0,100,4,0, + 132,0,0,131,1,0,90,5,0,100,5,0,100,6,0,132, + 0,0,90,6,0,100,7,0,100,8,0,132,0,0,90,7, + 0,100,9,0,100,10,0,132,0,0,90,8,0,100,11,0, + 100,12,0,132,0,0,90,9,0,100,13,0,100,14,0,132, + 0,0,90,10,0,100,15,0,100,16,0,132,0,0,90,11, + 0,100,17,0,83,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,4,0,0,0,4,0,0,0,67,0,0,0,115,25, + 0,0,0,116,0,0,124,1,0,124,2,0,124,3,0,131, + 3,0,124,0,0,95,1,0,100,0,0,83,41,1,78,41, + 2,114,224,0,0,0,114,226,0,0,0,41,4,114,100,0, + 0,0,114,98,0,0,0,114,35,0,0,0,114,230,0,0, + 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, + 114,179,0,0,0,218,3,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,2,0,0,0,2,0,0,0,67,0,0,0, + 115,16,0,0,0,100,1,0,106,0,0,124,1,0,106,1, + 0,131,1,0,83,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,47,0,0,0,114,105, + 0,0,0,41,2,114,164,0,0,0,114,184,0,0,0,114, + 4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,11, + 109,111,100,117,108,101,95,114,101,112,114,221,3,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,2,0,0, + 0,1,0,0,0,67,0,0,0,115,4,0,0,0,100,1, + 0,83,41,2,78,84,114,4,0,0,0,41,2,114,100,0, + 0,0,114,119,0,0,0,114,4,0,0,0,114,4,0,0, + 0,114,5,0,0,0,114,153,0,0,0,230,3,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,2,0,0,0, + 1,0,0,0,67,0,0,0,115,4,0,0,0,100,1,0, + 83,41,2,78,114,30,0,0,0,114,4,0,0,0,41,2, + 114,100,0,0,0,114,119,0,0,0,114,4,0,0,0,114, + 4,0,0,0,114,5,0,0,0,114,196,0,0,0,233,3, + 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,2, + 0,0,0,6,0,0,0,67,0,0,0,115,22,0,0,0, + 116,0,0,100,1,0,100,2,0,100,3,0,100,4,0,100, + 5,0,131,3,1,83,41,6,78,114,30,0,0,0,122,8, + 60,115,116,114,105,110,103,62,114,183,0,0,0,114,198,0, + 0,0,84,41,1,114,199,0,0,0,41,2,114,100,0,0, + 0,114,119,0,0,0,114,4,0,0,0,114,4,0,0,0, + 114,5,0,0,0,114,181,0,0,0,236,3,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,2,0,0,0,1,0,0, + 0,67,0,0,0,115,4,0,0,0,100,1,0,83,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,4,0, + 0,0,41,2,114,100,0,0,0,114,158,0,0,0,114,4, + 0,0,0,114,4,0,0,0,114,5,0,0,0,114,180,0, + 0,0,239,3,0,0,115,0,0,0,0,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,2,0,0,0,1,0,0,0,67,0,0,0, + 115,4,0,0,0,100,0,0,83,41,1,78,114,4,0,0, + 0,41,2,114,100,0,0,0,114,184,0,0,0,114,4,0, + 0,0,114,4,0,0,0,114,5,0,0,0,114,185,0,0, + 0,242,3,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,2,0,0,0,3,0,0,0,67,0,0,0,115, + 35,0,0,0,116,0,0,106,1,0,100,1,0,124,0,0, + 106,2,0,131,2,0,1,116,0,0,106,3,0,124,0,0, + 124,1,0,131,2,0,83,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,114,0,0,0,114,129,0,0, + 0,114,226,0,0,0,114,186,0,0,0,41,2,114,100,0, + 0,0,114,119,0,0,0,114,4,0,0,0,114,4,0,0, + 0,114,5,0,0,0,114,187,0,0,0,245,3,0,0,115, + 6,0,0,0,0,7,9,1,10,1,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,105,0,0,0, + 114,104,0,0,0,114,106,0,0,0,114,179,0,0,0,114, + 177,0,0,0,114,242,0,0,0,114,153,0,0,0,114,196, + 0,0,0,114,181,0,0,0,114,180,0,0,0,114,185,0, + 0,0,114,187,0,0,0,114,4,0,0,0,114,4,0,0, + 0,114,4,0,0,0,114,5,0,0,0,114,241,0,0,0, + 217,3,0,0,115,16,0,0,0,12,1,12,3,18,9,12, + 3,12,3,12,3,12,3,12,3,114,241,0,0,0,99,0, + 0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,64, + 0,0,0,115,160,0,0,0,101,0,0,90,1,0,100,0, + 0,90,2,0,100,1,0,90,3,0,101,4,0,100,2,0, + 100,3,0,132,0,0,131,1,0,90,5,0,101,4,0,100, + 4,0,100,5,0,132,0,0,131,1,0,90,6,0,101,4, + 0,100,6,0,100,7,0,132,0,0,131,1,0,90,7,0, + 101,4,0,100,8,0,100,9,0,132,0,0,131,1,0,90, + 8,0,101,4,0,100,10,0,100,11,0,100,12,0,132,1, + 0,131,1,0,90,9,0,101,4,0,100,10,0,100,10,0, + 100,13,0,100,14,0,132,2,0,131,1,0,90,10,0,101, + 4,0,100,10,0,100,15,0,100,16,0,132,1,0,131,1, + 0,90,11,0,100,10,0,83,41,17,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,2, + 0,0,0,4,0,0,0,67,0,0,0,115,55,0,0,0, + 120,48,0,116,0,0,106,1,0,106,2,0,131,0,0,68, + 93,31,0,125,1,0,116,3,0,124,1,0,100,1,0,131, + 2,0,114,16,0,124,1,0,106,4,0,131,0,0,1,113, + 16,0,87,100,2,0,83,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,218,17,105,110,118,97,108,105, + 100,97,116,101,95,99,97,99,104,101,115,78,41,5,114,7, + 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,6,118,97,108,117,101,115, + 114,108,0,0,0,114,244,0,0,0,41,2,114,164,0,0, + 0,218,6,102,105,110,100,101,114,114,4,0,0,0,114,4, + 0,0,0,114,5,0,0,0,114,244,0,0,0,7,4,0, + 0,115,6,0,0,0,0,4,22,1,15,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,3,0,0,0,12,0,0,0,67,0,0,0,115, + 107,0,0,0,116,0,0,106,1,0,100,1,0,107,9,0, + 114,41,0,116,0,0,106,1,0,12,114,41,0,116,2,0, + 106,3,0,100,2,0,116,4,0,131,2,0,1,120,59,0, + 116,0,0,106,1,0,68,93,44,0,125,2,0,121,14,0, + 124,2,0,124,1,0,131,1,0,83,87,113,51,0,4,116, + 5,0,107,10,0,114,94,0,1,1,1,119,51,0,89,113, + 51,0,88,113,51,0,87,100,1,0,83,100,1,0,83,41, + 3,122,113,83,101,97,114,99,104,32,115,101,113,117,101,110, + 99,101,32,111,102,32,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,10,10,32,32,32,32,32,32,32,32,73,102, + 32,39,104,111,111,107,115,39,32,105,115,32,102,97,108,115, + 101,32,116,104,101,110,32,117,115,101,32,115,121,115,46,112, + 97,116,104,95,104,111,111,107,115,46,10,10,32,32,32,32, + 32,32,32,32,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,7,0,0,0,218,10,112,97,116,104,95,104,111,111,107, + 115,114,60,0,0,0,114,61,0,0,0,114,118,0,0,0, + 114,99,0,0,0,41,3,114,164,0,0,0,114,35,0,0, + 0,90,4,104,111,111,107,114,4,0,0,0,114,4,0,0, + 0,114,5,0,0,0,218,11,95,112,97,116,104,95,104,111, + 111,107,115,15,4,0,0,115,16,0,0,0,0,7,25,1, + 16,1,16,1,3,1,14,1,13,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,3,0,0, + 0,19,0,0,0,67,0,0,0,115,123,0,0,0,124,1, + 0,100,1,0,107,2,0,114,53,0,121,16,0,116,0,0, + 106,1,0,131,0,0,125,1,0,87,110,22,0,4,116,2, + 0,107,10,0,114,52,0,1,1,1,100,2,0,83,89,110, + 1,0,88,121,17,0,116,3,0,106,4,0,124,1,0,25, + 125,2,0,87,110,46,0,4,116,5,0,107,10,0,114,118, + 0,1,1,1,124,0,0,106,6,0,124,1,0,131,1,0, + 125,2,0,124,2,0,116,3,0,106,4,0,124,1,0,60, + 89,110,1,0,88,124,2,0,83,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, + 30,0,0,0,78,41,7,114,3,0,0,0,114,45,0,0, + 0,218,17,70,105,108,101,78,111,116,70,111,117,110,100,69, + 114,114,111,114,114,7,0,0,0,114,245,0,0,0,114,131, + 0,0,0,114,249,0,0,0,41,3,114,164,0,0,0,114, + 35,0,0,0,114,247,0,0,0,114,4,0,0,0,114,4, + 0,0,0,114,5,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,32,4, + 0,0,115,22,0,0,0,0,8,12,1,3,1,16,1,13, + 3,9,1,3,1,17,1,13,1,15,1,18,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,6,0,0,0,3,0,0,0,67, + 0,0,0,115,119,0,0,0,116,0,0,124,2,0,100,1, + 0,131,2,0,114,39,0,124,2,0,106,1,0,124,1,0, + 131,1,0,92,2,0,125,3,0,125,4,0,110,21,0,124, + 2,0,106,2,0,124,1,0,131,1,0,125,3,0,103,0, + 0,125,4,0,124,3,0,100,0,0,107,9,0,114,88,0, + 116,3,0,106,4,0,124,1,0,124,3,0,131,2,0,83, + 116,3,0,106,5,0,124,1,0,100,0,0,131,2,0,125, + 5,0,124,4,0,124,5,0,95,6,0,124,5,0,83,41, + 2,78,114,117,0,0,0,41,7,114,108,0,0,0,114,117, + 0,0,0,114,176,0,0,0,114,114,0,0,0,114,173,0, + 0,0,114,154,0,0,0,114,150,0,0,0,41,6,114,164, + 0,0,0,114,119,0,0,0,114,247,0,0,0,114,120,0, + 0,0,114,121,0,0,0,114,158,0,0,0,114,4,0,0, + 0,114,4,0,0,0,114,5,0,0,0,218,16,95,108,101, + 103,97,99,121,95,103,101,116,95,115,112,101,99,54,4,0, + 0,115,18,0,0,0,0,4,15,1,24,2,15,1,6,1, + 12,1,16,1,18,1,9,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,9, + 0,0,0,5,0,0,0,67,0,0,0,115,243,0,0,0, + 103,0,0,125,4,0,120,230,0,124,2,0,68,93,191,0, + 125,5,0,116,0,0,124,5,0,116,1,0,116,2,0,102, + 2,0,131,2,0,115,43,0,113,13,0,124,0,0,106,3, + 0,124,5,0,131,1,0,125,6,0,124,6,0,100,1,0, + 107,9,0,114,13,0,116,4,0,124,6,0,100,2,0,131, + 2,0,114,106,0,124,6,0,106,5,0,124,1,0,124,3, + 0,131,2,0,125,7,0,110,18,0,124,0,0,106,6,0, + 124,1,0,124,6,0,131,2,0,125,7,0,124,7,0,100, + 1,0,107,8,0,114,139,0,113,13,0,124,7,0,106,7, + 0,100,1,0,107,9,0,114,158,0,124,7,0,83,124,7, + 0,106,8,0,125,8,0,124,8,0,100,1,0,107,8,0, + 114,191,0,116,9,0,100,3,0,131,1,0,130,1,0,124, + 4,0,106,10,0,124,8,0,131,1,0,1,113,13,0,87, + 116,11,0,106,12,0,124,1,0,100,1,0,131,2,0,125, + 7,0,124,4,0,124,7,0,95,8,0,124,7,0,83,100, + 1,0,83,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,175,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,137,0,0,0,114,69,0,0,0,218,5,98, + 121,116,101,115,114,251,0,0,0,114,108,0,0,0,114,175, + 0,0,0,114,252,0,0,0,114,120,0,0,0,114,150,0, + 0,0,114,99,0,0,0,114,143,0,0,0,114,114,0,0, + 0,114,154,0,0,0,41,9,114,164,0,0,0,114,119,0, + 0,0,114,35,0,0,0,114,174,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,247,0,0,0,114,158,0,0,0,114,121,0, + 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, + 0,218,9,95,103,101,116,95,115,112,101,99,69,4,0,0, + 115,40,0,0,0,0,5,6,1,13,1,21,1,3,1,15, + 1,12,1,15,1,21,2,18,1,12,1,3,1,15,1,4, + 1,9,1,12,1,12,5,17,2,18,1,9,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,6,0,0,0, + 4,0,0,0,67,0,0,0,115,140,0,0,0,124,2,0, + 100,1,0,107,8,0,114,21,0,116,0,0,106,1,0,125, + 2,0,124,0,0,106,2,0,124,1,0,124,2,0,124,3, + 0,131,3,0,125,4,0,124,4,0,100,1,0,107,8,0, + 114,58,0,100,1,0,83,124,4,0,106,3,0,100,1,0, + 107,8,0,114,132,0,124,4,0,106,4,0,125,5,0,124, + 5,0,114,125,0,100,2,0,124,4,0,95,5,0,116,6, + 0,124,1,0,124,5,0,124,0,0,106,2,0,131,3,0, + 124,4,0,95,4,0,124,4,0,83,100,1,0,83,110,4, + 0,124,4,0,83,100,1,0,83,41,3,122,98,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,78, + 90,9,110,97,109,101,115,112,97,99,101,41,7,114,7,0, + 0,0,114,35,0,0,0,114,255,0,0,0,114,120,0,0, + 0,114,150,0,0,0,114,152,0,0,0,114,224,0,0,0, + 41,6,114,164,0,0,0,114,119,0,0,0,114,35,0,0, + 0,114,174,0,0,0,114,158,0,0,0,114,254,0,0,0, + 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, + 175,0,0,0,101,4,0,0,115,26,0,0,0,0,4,12, + 1,9,1,21,1,12,1,4,1,15,1,9,1,6,3,9, + 1,24,1,4,2,7,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,4,0,0,0,3,0,0,0,67,0, + 0,0,115,41,0,0,0,124,0,0,106,0,0,124,1,0, + 124,2,0,131,2,0,125,3,0,124,3,0,100,1,0,107, + 8,0,114,34,0,100,1,0,83,124,3,0,106,1,0,83, + 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,41, + 2,114,175,0,0,0,114,120,0,0,0,41,4,114,164,0, + 0,0,114,119,0,0,0,114,35,0,0,0,114,158,0,0, + 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, + 114,176,0,0,0,123,4,0,0,115,8,0,0,0,0,8, + 18,1,12,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,41,12, + 114,105,0,0,0,114,104,0,0,0,114,106,0,0,0,114, + 107,0,0,0,114,177,0,0,0,114,244,0,0,0,114,249, + 0,0,0,114,251,0,0,0,114,252,0,0,0,114,255,0, + 0,0,114,175,0,0,0,114,176,0,0,0,114,4,0,0, + 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, + 114,243,0,0,0,3,4,0,0,115,22,0,0,0,12,2, + 6,2,18,8,18,17,18,22,18,15,3,1,18,31,3,1, + 21,21,3,1,114,243,0,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,3,0,0,0,64,0,0,0,115,133, + 0,0,0,101,0,0,90,1,0,100,0,0,90,2,0,100, + 1,0,90,3,0,100,2,0,100,3,0,132,0,0,90,4, + 0,100,4,0,100,5,0,132,0,0,90,5,0,101,6,0, + 90,7,0,100,6,0,100,7,0,132,0,0,90,8,0,100, + 8,0,100,9,0,132,0,0,90,9,0,100,10,0,100,11, + 0,100,12,0,132,1,0,90,10,0,100,13,0,100,14,0, + 132,0,0,90,11,0,101,12,0,100,15,0,100,16,0,132, + 0,0,131,1,0,90,13,0,100,17,0,100,18,0,132,0, + 0,90,14,0,100,10,0,83,41,19,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,5,0,0, + 0,5,0,0,0,7,0,0,0,115,122,0,0,0,103,0, + 0,125,3,0,120,52,0,124,2,0,68,93,44,0,92,2, + 0,137,0,0,125,4,0,124,3,0,106,0,0,135,0,0, + 102,1,0,100,1,0,100,2,0,134,0,0,124,4,0,68, + 131,1,0,131,1,0,1,113,13,0,87,124,3,0,124,0, + 0,95,1,0,124,1,0,112,79,0,100,3,0,124,0,0, + 95,2,0,100,6,0,124,0,0,95,3,0,116,4,0,131, + 0,0,124,0,0,95,5,0,116,4,0,131,0,0,124,0, + 0,95,6,0,100,5,0,83,41,7,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,2, + 0,0,0,3,0,0,0,51,0,0,0,115,27,0,0,0, + 124,0,0,93,17,0,125,1,0,124,1,0,136,0,0,102, + 2,0,86,1,113,3,0,100,0,0,83,41,1,78,114,4, + 0,0,0,41,2,114,22,0,0,0,114,219,0,0,0,41, + 1,114,120,0,0,0,114,4,0,0,0,114,5,0,0,0, + 114,221,0,0,0,152,4,0,0,115,2,0,0,0,6,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,58,0,0,0,114,29,0, + 0,0,78,114,87,0,0,0,41,7,114,143,0,0,0,218, + 8,95,108,111,97,100,101,114,115,114,35,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,100,0,0,0,114,35,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,160,0,0,0,114,4,0,0, + 0,41,1,114,120,0,0,0,114,5,0,0,0,114,179,0, + 0,0,146,4,0,0,115,16,0,0,0,0,4,6,1,19, + 1,36,1,9,2,15,1,9,1,12,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,1,0,0,0,2,0,0, + 0,67,0,0,0,115,13,0,0,0,100,3,0,124,0,0, + 95,0,0,100,2,0,83,41,4,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,29,0,0,0,78, + 114,87,0,0,0,41,1,114,2,1,0,0,41,1,114,100, + 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, + 0,0,114,244,0,0,0,160,4,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,3,0,0,0,2,0,0, + 0,67,0,0,0,115,59,0,0,0,124,0,0,106,0,0, + 124,1,0,131,1,0,125,2,0,124,2,0,100,1,0,107, + 8,0,114,37,0,100,1,0,103,0,0,102,2,0,83,124, + 2,0,106,1,0,124,2,0,106,2,0,112,55,0,103,0, + 0,102,2,0,83,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,175,0,0,0,114,120,0,0,0,114,150,0,0,0, + 41,3,114,100,0,0,0,114,119,0,0,0,114,158,0,0, + 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, + 114,117,0,0,0,166,4,0,0,115,8,0,0,0,0,7, + 15,1,12,1,10,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,7,0,0,0,7,0,0,0,67, + 0,0,0,115,40,0,0,0,124,1,0,124,2,0,124,3, + 0,131,2,0,125,6,0,116,0,0,124,2,0,124,3,0, + 100,1,0,124,6,0,100,2,0,124,4,0,131,2,2,83, + 41,3,78,114,120,0,0,0,114,150,0,0,0,41,1,114, + 161,0,0,0,41,7,114,100,0,0,0,114,159,0,0,0, + 114,119,0,0,0,114,35,0,0,0,90,4,115,109,115,108, + 114,174,0,0,0,114,120,0,0,0,114,4,0,0,0,114, + 4,0,0,0,114,5,0,0,0,114,255,0,0,0,178,4, + 0,0,115,6,0,0,0,0,1,15,1,18,1,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,14,0,0, + 0,15,0,0,0,67,0,0,0,115,228,1,0,0,100,1, + 0,125,3,0,124,1,0,106,0,0,100,2,0,131,1,0, + 100,3,0,25,125,4,0,121,34,0,116,1,0,124,0,0, + 106,2,0,112,49,0,116,3,0,106,4,0,131,0,0,131, + 1,0,106,5,0,125,5,0,87,110,24,0,4,116,6,0, + 107,10,0,114,85,0,1,1,1,100,10,0,125,5,0,89, + 110,1,0,88,124,5,0,124,0,0,106,7,0,107,3,0, + 114,120,0,124,0,0,106,8,0,131,0,0,1,124,5,0, + 124,0,0,95,7,0,116,9,0,131,0,0,114,153,0,124, + 0,0,106,10,0,125,6,0,124,4,0,106,11,0,131,0, + 0,125,7,0,110,15,0,124,0,0,106,12,0,125,6,0, + 124,4,0,125,7,0,124,7,0,124,6,0,107,6,0,114, + 45,1,116,13,0,124,0,0,106,2,0,124,4,0,131,2, + 0,125,8,0,120,100,0,124,0,0,106,14,0,68,93,77, + 0,92,2,0,125,9,0,125,10,0,100,5,0,124,9,0, + 23,125,11,0,116,13,0,124,8,0,124,11,0,131,2,0, + 125,12,0,116,15,0,124,12,0,131,1,0,114,208,0,124, + 0,0,106,16,0,124,10,0,124,1,0,124,12,0,124,8, + 0,103,1,0,124,2,0,131,5,0,83,113,208,0,87,116, + 17,0,124,8,0,131,1,0,125,3,0,120,120,0,124,0, + 0,106,14,0,68,93,109,0,92,2,0,125,9,0,125,10, + 0,116,13,0,124,0,0,106,2,0,124,4,0,124,9,0, + 23,131,2,0,125,12,0,116,18,0,106,19,0,100,6,0, + 124,12,0,100,7,0,100,3,0,131,2,1,1,124,7,0, + 124,9,0,23,124,6,0,107,6,0,114,55,1,116,15,0, + 124,12,0,131,1,0,114,55,1,124,0,0,106,16,0,124, + 10,0,124,1,0,124,12,0,100,8,0,124,2,0,131,5, + 0,83,113,55,1,87,124,3,0,114,224,1,116,18,0,106, + 19,0,100,9,0,124,8,0,131,2,0,1,116,18,0,106, + 20,0,124,1,0,100,8,0,131,2,0,125,13,0,124,8, + 0,103,1,0,124,13,0,95,21,0,124,13,0,83,100,8, + 0,83,41,11,122,125,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,70,114,58,0,0,0,114,56,0,0,0,114,29, + 0,0,0,114,179,0,0,0,122,9,116,114,121,105,110,103, + 32,123,125,90,9,118,101,114,98,111,115,105,116,121,78,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,114,87,0,0,0,41, + 22,114,32,0,0,0,114,39,0,0,0,114,35,0,0,0, + 114,3,0,0,0,114,45,0,0,0,114,213,0,0,0,114, + 40,0,0,0,114,2,1,0,0,218,11,95,102,105,108,108, + 95,99,97,99,104,101,114,6,0,0,0,114,5,1,0,0, + 114,88,0,0,0,114,4,1,0,0,114,28,0,0,0,114, + 1,1,0,0,114,44,0,0,0,114,255,0,0,0,114,46, + 0,0,0,114,114,0,0,0,114,129,0,0,0,114,154,0, + 0,0,114,150,0,0,0,41,14,114,100,0,0,0,114,119, + 0,0,0,114,174,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,126,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,219,0,0,0,114,159,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,158,0,0, + 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, + 114,175,0,0,0,183,4,0,0,115,70,0,0,0,0,3, + 6,1,19,1,3,1,34,1,13,1,11,1,15,1,10,1, + 9,2,9,1,9,1,15,2,9,1,6,2,12,1,18,1, + 22,1,10,1,15,1,12,1,32,4,12,2,22,1,22,1, + 22,1,16,1,12,1,15,1,14,1,6,1,16,1,18,1, + 12,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,9,0,0,0,13,0,0,0,67,0,0,0,115, + 11,1,0,0,124,0,0,106,0,0,125,1,0,121,31,0, + 116,1,0,106,2,0,124,1,0,112,33,0,116,1,0,106, + 3,0,131,0,0,131,1,0,125,2,0,87,110,33,0,4, + 116,4,0,116,5,0,116,6,0,102,3,0,107,10,0,114, + 75,0,1,1,1,103,0,0,125,2,0,89,110,1,0,88, + 116,7,0,106,8,0,106,9,0,100,1,0,131,1,0,115, + 112,0,116,10,0,124,2,0,131,1,0,124,0,0,95,11, + 0,110,111,0,116,10,0,131,0,0,125,3,0,120,90,0, + 124,2,0,68,93,82,0,125,4,0,124,4,0,106,12,0, + 100,2,0,131,1,0,92,3,0,125,5,0,125,6,0,125, + 7,0,124,6,0,114,191,0,100,3,0,106,13,0,124,5, + 0,124,7,0,106,14,0,131,0,0,131,2,0,125,8,0, + 110,6,0,124,5,0,125,8,0,124,3,0,106,15,0,124, + 8,0,131,1,0,1,113,128,0,87,124,3,0,124,0,0, + 95,11,0,116,7,0,106,8,0,106,9,0,116,16,0,131, + 1,0,114,7,1,100,4,0,100,5,0,132,0,0,124,2, + 0,68,131,1,0,124,0,0,95,17,0,100,6,0,83,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,0,0,0,0,114,58,0,0, + 0,122,5,123,125,46,123,125,99,1,0,0,0,0,0,0, + 0,2,0,0,0,3,0,0,0,83,0,0,0,115,28,0, + 0,0,104,0,0,124,0,0,93,18,0,125,1,0,124,1, + 0,106,0,0,131,0,0,146,2,0,113,6,0,83,114,4, + 0,0,0,41,1,114,88,0,0,0,41,2,114,22,0,0, + 0,90,2,102,110,114,4,0,0,0,114,4,0,0,0,114, + 5,0,0,0,250,9,60,115,101,116,99,111,109,112,62,2, + 5,0,0,115,2,0,0,0,9,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,35,0,0,0,114,3,0, + 0,0,90,7,108,105,115,116,100,105,114,114,45,0,0,0, + 114,250,0,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,7,0,0,0,114, + 8,0,0,0,114,9,0,0,0,114,3,1,0,0,114,4, + 1,0,0,114,83,0,0,0,114,47,0,0,0,114,88,0, + 0,0,218,3,97,100,100,114,10,0,0,0,114,5,1,0, + 0,41,9,114,100,0,0,0,114,35,0,0,0,90,8,99, + 111,110,116,101,110,116,115,90,21,108,111,119,101,114,95,115, + 117,102,102,105,120,95,99,111,110,116,101,110,116,115,114,239, + 0,0,0,114,98,0,0,0,114,231,0,0,0,114,219,0, + 0,0,90,8,110,101,119,95,110,97,109,101,114,4,0,0, + 0,114,4,0,0,0,114,5,0,0,0,114,7,1,0,0, + 229,4,0,0,115,34,0,0,0,0,2,9,1,3,1,31, + 1,22,3,11,3,18,1,18,7,9,1,13,1,24,1,6, + 1,27,2,6,1,17,1,9,1,18,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,3,0,0,0, + 3,0,0,0,7,0,0,0,115,25,0,0,0,135,0,0, + 135,1,0,102,2,0,100,1,0,100,2,0,134,0,0,125, + 2,0,124,2,0,83,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,1,0,0,0,4,0, + 0,0,19,0,0,0,115,43,0,0,0,116,0,0,124,0, + 0,131,1,0,115,30,0,116,1,0,100,1,0,100,2,0, + 124,0,0,131,1,1,130,1,0,136,0,0,124,0,0,136, + 1,0,140,1,0,83,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,35,0,0,0,41,2,114,46, + 0,0,0,114,99,0,0,0,41,1,114,35,0,0,0,41, + 2,114,164,0,0,0,114,6,1,0,0,114,4,0,0,0, + 114,5,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,14, + 5,0,0,115,6,0,0,0,0,2,12,1,18,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,4,0,0,0,41,3,114,164,0, + 0,0,114,6,1,0,0,114,12,1,0,0,114,4,0,0, + 0,41,2,114,164,0,0,0,114,6,1,0,0,114,5,0, + 0,0,218,9,112,97,116,104,95,104,111,111,107,4,5,0, + 0,115,4,0,0,0,0,10,21,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,1,0,0,0,2,0,0, + 0,67,0,0,0,115,16,0,0,0,100,1,0,106,0,0, + 124,0,0,106,1,0,131,1,0,83,41,2,78,122,16,70, + 105,108,101,70,105,110,100,101,114,40,123,33,114,125,41,41, + 2,114,47,0,0,0,114,35,0,0,0,41,1,114,100,0, + 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, + 0,114,238,0,0,0,22,5,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,15,114,105,0,0,0,114,104,0, + 0,0,114,106,0,0,0,114,107,0,0,0,114,179,0,0, + 0,114,244,0,0,0,114,123,0,0,0,114,176,0,0,0, + 114,117,0,0,0,114,255,0,0,0,114,175,0,0,0,114, + 7,1,0,0,114,177,0,0,0,114,13,1,0,0,114,238, + 0,0,0,114,4,0,0,0,114,4,0,0,0,114,4,0, + 0,0,114,5,0,0,0,114,0,1,0,0,137,4,0,0, + 115,20,0,0,0,12,7,6,2,12,14,12,4,6,2,12, + 12,12,5,15,46,12,31,18,18,114,0,1,0,0,99,4, + 0,0,0,0,0,0,0,6,0,0,0,11,0,0,0,67, + 0,0,0,115,195,0,0,0,124,0,0,106,0,0,100,1, + 0,131,1,0,125,4,0,124,0,0,106,0,0,100,2,0, + 131,1,0,125,5,0,124,4,0,115,99,0,124,5,0,114, + 54,0,124,5,0,106,1,0,125,4,0,110,45,0,124,2, + 0,124,3,0,107,2,0,114,84,0,116,2,0,124,1,0, + 124,2,0,131,2,0,125,4,0,110,15,0,116,3,0,124, + 1,0,124,2,0,131,2,0,125,4,0,124,5,0,115,126, + 0,116,4,0,124,1,0,124,2,0,100,3,0,124,4,0, + 131,2,1,125,5,0,121,44,0,124,5,0,124,0,0,100, + 2,0,60,124,4,0,124,0,0,100,1,0,60,124,2,0, + 124,0,0,100,4,0,60,124,3,0,124,0,0,100,5,0, + 60,87,110,18,0,4,116,5,0,107,10,0,114,190,0,1, + 1,1,89,110,1,0,88,100,0,0,83,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,120,0,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,120,0,0,0,114,217,0,0,0, + 114,212,0,0,0,114,161,0,0,0,218,9,69,120,99,101, + 112,116,105,111,110,41,6,90,2,110,115,114,98,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,120,0,0,0,114,158,0,0,0,114, + 4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,14, + 95,102,105,120,95,117,112,95,109,111,100,117,108,101,28,5, + 0,0,115,34,0,0,0,0,2,15,1,15,1,6,1,6, + 1,12,1,12,1,18,2,15,1,6,1,21,1,3,1,10, + 1,10,1,10,1,14,1,13,2,114,18,1,0,0,99,0, + 0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,67, + 0,0,0,115,55,0,0,0,116,0,0,116,1,0,106,2, + 0,131,0,0,102,2,0,125,0,0,116,3,0,116,4,0, + 102,2,0,125,1,0,116,5,0,116,6,0,102,2,0,125, + 2,0,124,0,0,124,1,0,124,2,0,103,3,0,83,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,218,0,0,0,114,139,0,0,0,218,18, + 101,120,116,101,110,115,105,111,110,95,115,117,102,102,105,120, + 101,115,114,212,0,0,0,114,84,0,0,0,114,217,0,0, + 0,114,74,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,4,0,0,0,114,4,0,0,0, + 114,5,0,0,0,114,155,0,0,0,51,5,0,0,115,8, + 0,0,0,0,5,18,1,12,1,12,1,114,155,0,0,0, + 99,1,0,0,0,0,0,0,0,12,0,0,0,12,0,0, + 0,67,0,0,0,115,70,2,0,0,124,0,0,97,0,0, + 116,0,0,106,1,0,97,1,0,116,0,0,106,2,0,97, + 2,0,116,1,0,106,3,0,116,4,0,25,125,1,0,120, + 76,0,100,26,0,68,93,68,0,125,2,0,124,2,0,116, + 1,0,106,3,0,107,7,0,114,83,0,116,0,0,106,5, + 0,124,2,0,131,1,0,125,3,0,110,13,0,116,1,0, + 106,3,0,124,2,0,25,125,3,0,116,6,0,124,1,0, + 124,2,0,124,3,0,131,3,0,1,113,44,0,87,100,5, + 0,100,6,0,103,1,0,102,2,0,100,7,0,100,8,0, + 100,6,0,103,2,0,102,2,0,102,2,0,125,4,0,120, + 149,0,124,4,0,68,93,129,0,92,2,0,125,5,0,125, + 6,0,116,7,0,100,9,0,100,10,0,132,0,0,124,6, + 0,68,131,1,0,131,1,0,115,199,0,116,8,0,130,1, + 0,124,6,0,100,11,0,25,125,7,0,124,5,0,116,1, + 0,106,3,0,107,6,0,114,241,0,116,1,0,106,3,0, + 124,5,0,25,125,8,0,80,113,156,0,121,20,0,116,0, + 0,106,5,0,124,5,0,131,1,0,125,8,0,80,87,113, + 156,0,4,116,9,0,107,10,0,114,28,1,1,1,1,119, + 156,0,89,113,156,0,88,113,156,0,87,116,9,0,100,12, + 0,131,1,0,130,1,0,116,6,0,124,1,0,100,13,0, + 124,8,0,131,3,0,1,116,6,0,124,1,0,100,14,0, + 124,7,0,131,3,0,1,116,6,0,124,1,0,100,15,0, + 100,16,0,106,10,0,124,6,0,131,1,0,131,3,0,1, + 121,19,0,116,0,0,106,5,0,100,17,0,131,1,0,125, + 9,0,87,110,24,0,4,116,9,0,107,10,0,114,147,1, + 1,1,1,100,18,0,125,9,0,89,110,1,0,88,116,6, + 0,124,1,0,100,17,0,124,9,0,131,3,0,1,116,0, + 0,106,5,0,100,19,0,131,1,0,125,10,0,116,6,0, + 124,1,0,100,19,0,124,10,0,131,3,0,1,124,5,0, + 100,7,0,107,2,0,114,238,1,116,0,0,106,5,0,100, + 20,0,131,1,0,125,11,0,116,6,0,124,1,0,100,21, + 0,124,11,0,131,3,0,1,116,6,0,124,1,0,100,22, + 0,116,11,0,131,0,0,131,3,0,1,116,12,0,106,13, + 0,116,2,0,106,14,0,131,0,0,131,1,0,1,124,5, + 0,100,7,0,107,2,0,114,66,2,116,15,0,106,16,0, + 100,23,0,131,1,0,1,100,24,0,116,12,0,107,6,0, + 114,66,2,100,25,0,116,17,0,95,18,0,100,18,0,83, + 41,27,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,114,49,0,0,0,114,60,0,0,0,218,8,98,117,105, + 108,116,105,110,115,114,136,0,0,0,90,5,112,111,115,105, + 120,250,1,47,218,2,110,116,250,1,92,99,1,0,0,0, + 0,0,0,0,2,0,0,0,3,0,0,0,115,0,0,0, + 115,33,0,0,0,124,0,0,93,23,0,125,1,0,116,0, + 0,124,1,0,131,1,0,100,0,0,107,2,0,86,1,113, + 3,0,100,1,0,83,41,2,114,29,0,0,0,78,41,1, + 114,31,0,0,0,41,2,114,22,0,0,0,114,77,0,0, + 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, + 114,221,0,0,0,87,5,0,0,115,2,0,0,0,6,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,59,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,3,0,0,0,114,25,0,0,0,114,21,0,0,0,114, + 30,0,0,0,90,7,95,116,104,114,101,97,100,78,90,8, + 95,119,101,97,107,114,101,102,90,6,119,105,110,114,101,103, + 114,163,0,0,0,114,6,0,0,0,122,4,46,112,121,119, + 122,6,95,100,46,112,121,100,84,41,4,122,3,95,105,111, + 122,9,95,119,97,114,110,105,110,103,115,122,8,98,117,105, + 108,116,105,110,115,122,7,109,97,114,115,104,97,108,41,19, + 114,114,0,0,0,114,7,0,0,0,114,139,0,0,0,114, + 233,0,0,0,114,105,0,0,0,90,18,95,98,117,105,108, + 116,105,110,95,102,114,111,109,95,110,97,109,101,114,109,0, + 0,0,218,3,97,108,108,218,14,65,115,115,101,114,116,105, + 111,110,69,114,114,111,114,114,99,0,0,0,114,26,0,0, + 0,114,11,0,0,0,114,223,0,0,0,114,143,0,0,0, + 114,19,1,0,0,114,84,0,0,0,114,157,0,0,0,114, + 162,0,0,0,114,167,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,21,0,0,0,114,25,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,4,0,0,0,114,4,0,0,0,114,5, + 0,0,0,218,6,95,115,101,116,117,112,62,5,0,0,115, + 82,0,0,0,0,8,6,1,9,1,9,3,13,1,13,1, + 15,1,18,2,13,1,20,3,33,1,19,2,31,1,10,1, + 15,1,13,1,4,2,3,1,15,1,5,1,13,1,12,2, + 12,1,16,1,16,1,25,3,3,1,19,1,13,2,11,1, + 16,3,15,1,16,3,12,1,15,1,16,3,19,1,19,1, + 12,1,13,1,12,1,114,27,1,0,0,99,1,0,0,0, + 0,0,0,0,2,0,0,0,3,0,0,0,67,0,0,0, + 115,116,0,0,0,116,0,0,124,0,0,131,1,0,1,116, + 1,0,131,0,0,125,1,0,116,2,0,106,3,0,106,4, + 0,116,5,0,106,6,0,124,1,0,140,0,0,103,1,0, + 131,1,0,1,116,7,0,106,8,0,100,1,0,107,2,0, + 114,78,0,116,2,0,106,9,0,106,10,0,116,11,0,131, + 1,0,1,116,2,0,106,9,0,106,10,0,116,12,0,131, + 1,0,1,116,5,0,124,0,0,95,5,0,116,13,0,124, + 0,0,95,13,0,100,2,0,83,41,3,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,114,22,1,0,0,78,41,14,114,27, + 1,0,0,114,155,0,0,0,114,7,0,0,0,114,248,0, + 0,0,114,143,0,0,0,114,0,1,0,0,114,13,1,0, + 0,114,3,0,0,0,114,105,0,0,0,218,9,109,101,116, + 97,95,112,97,116,104,114,157,0,0,0,114,162,0,0,0, + 114,243,0,0,0,114,212,0,0,0,41,2,114,26,1,0, + 0,90,17,115,117,112,112,111,114,116,101,100,95,108,111,97, + 100,101,114,115,114,4,0,0,0,114,4,0,0,0,114,5, + 0,0,0,218,8,95,105,110,115,116,97,108,108,130,5,0, + 0,115,16,0,0,0,0,2,10,1,9,1,28,1,15,1, + 16,1,16,4,9,1,114,29,1,0,0,41,3,122,3,119, + 105,110,114,1,0,0,0,114,2,0,0,0,41,56,114,107, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,17,0, + 0,0,114,19,0,0,0,114,28,0,0,0,114,38,0,0, + 0,114,39,0,0,0,114,43,0,0,0,114,44,0,0,0, + 114,46,0,0,0,114,55,0,0,0,218,4,116,121,112,101, + 218,8,95,95,99,111,100,101,95,95,114,138,0,0,0,114, + 15,0,0,0,114,128,0,0,0,114,14,0,0,0,114,18, + 0,0,0,90,17,95,82,65,87,95,77,65,71,73,67,95, + 78,85,77,66,69,82,114,73,0,0,0,114,72,0,0,0, + 114,84,0,0,0,114,74,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,79,0,0,0,114,85,0,0,0,114,91,0,0,0,114, + 95,0,0,0,114,97,0,0,0,114,116,0,0,0,114,123, + 0,0,0,114,135,0,0,0,114,141,0,0,0,114,144,0, + 0,0,114,149,0,0,0,218,6,111,98,106,101,99,116,114, + 156,0,0,0,114,161,0,0,0,114,162,0,0,0,114,178, + 0,0,0,114,188,0,0,0,114,204,0,0,0,114,212,0, + 0,0,114,217,0,0,0,114,223,0,0,0,114,218,0,0, + 0,114,224,0,0,0,114,241,0,0,0,114,243,0,0,0, + 114,0,1,0,0,114,18,1,0,0,114,155,0,0,0,114, + 27,1,0,0,114,29,1,0,0,114,4,0,0,0,114,4, + 0,0,0,114,4,0,0,0,114,5,0,0,0,218,8,60, + 109,111,100,117,108,101,62,8,0,0,0,115,98,0,0,0, + 6,17,6,3,12,12,12,5,12,5,12,6,12,12,12,10, + 12,9,12,5,12,7,15,22,15,110,22,1,18,2,6,1, + 6,2,9,2,9,2,10,2,21,44,12,33,12,19,12,12, + 12,12,12,28,12,17,21,55,21,12,18,10,12,14,9,3, + 12,1,15,65,19,64,19,28,22,110,19,41,25,45,25,16, + 6,3,25,53,19,57,19,42,19,134,19,147,15,23,12,11, + 12,68, +}; diff --git a/Python/marshal.c b/Python/marshal.c index dc5411c1ff76..f89cd04b6553 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -12,8 +12,7 @@ #include "longintrepr.h" #include "code.h" #include "marshal.h" - -#define ABS(x) ((x) < 0 ? -(x) : (x)) +#include "../Modules/hashtable.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, @@ -21,7 +20,7 @@ * On Windows debug builds, reduce this value. */ #if defined(MS_WINDOWS) && defined(_DEBUG) -#define MAX_MARSHAL_STACK_DEPTH 1500 +#define MAX_MARSHAL_STACK_DEPTH 1000 #else #define MAX_MARSHAL_STACK_DEPTH 2000 #endif @@ -66,54 +65,83 @@ typedef struct { FILE *fp; int error; /* see WFERR_* values */ int depth; - /* If fp == NULL, the following are valid: */ - PyObject *readable; /* Stream-like object being read from */ PyObject *str; - PyObject *current_filename; char *ptr; char *end; char *buf; - Py_ssize_t buf_size; - PyObject *refs; /* dict on marshal, list on unmarshal */ + _Py_hashtable_t *hashtable; int version; } WFILE; -#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \ - else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \ - else w_more((c), p) +#define w_byte(c, p) do { \ + if ((p)->ptr != (p)->end || w_reserve((p), 1)) \ + *(p)->ptr++ = (c); \ + } while(0) static void -w_more(char c, WFILE *p) +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 size, newsize; - if (p->str == NULL) - return; /* An error already occurred */ + 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); - newsize = size + size + 1024; - if (newsize > 32*1024*1024) { - newsize = size + (size >> 3); /* 12.5% overallocation */ + 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; } - if (_PyBytes_Resize(&p->str, newsize) != 0) { - p->ptr = p->end = NULL; + size += delta; + if (_PyBytes_Resize(&p->str, size) != 0) { + p->ptr = p->buf = p->end = NULL; + return 0; } else { - p->ptr = PyBytes_AS_STRING((PyBytesObject *)p->str) + size; - p->end = - PyBytes_AS_STRING((PyBytesObject *)p->str) + newsize; - *p->ptr++ = c; + 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) { - fwrite(s, 1, n, p->fp); + if (n <= m) { + Py_MEMCPY(p->ptr, s, n); + p->ptr += n; + } + else { + w_flush(p); + fwrite(s, 1, n, p->fp); + } } else { - while (--n >= 0) { - w_byte(*s, p); - s++; + if (n <= m || w_reserve(p, n - m)) { + Py_MEMCPY(p->ptr, s, n); + p->ptr += n; } } } @@ -192,7 +220,7 @@ w_PyLong(const PyLongObject *ob, char flag, WFILE *p) } /* set l to number of base PyLong_MARSHAL_BASE digits */ - n = ABS(Py_SIZE(ob)); + 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 */ @@ -225,46 +253,38 @@ w_PyLong(const PyLongObject *ob, char flag, WFILE *p) static int w_ref(PyObject *v, char *flag, WFILE *p) { - PyObject *id; - PyObject *idx; + _Py_hashtable_entry_t *entry; + int w; - if (p->version < 3 || p->refs == NULL) + 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; - id = PyLong_FromVoidPtr((void*)v); - if (id == NULL) - goto err; - idx = PyDict_GetItem(p->refs, id); - if (idx != NULL) { + entry = _Py_hashtable_get_entry(p->hashtable, v); + if (entry != NULL) { /* write the reference index to the stream */ - long w = PyLong_AsLong(idx); - Py_DECREF(id); - if (w == -1 && PyErr_Occurred()) { - goto err; - } + _Py_HASHTABLE_ENTRY_READ_DATA(p->hashtable, &w, sizeof(w), entry); /* 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 { - int ok; - Py_ssize_t s = PyDict_Size(p->refs); + size_t s = p->hashtable->entries; /* we don't support long indices */ if (s >= 0x7fffffff) { PyErr_SetString(PyExc_ValueError, "too many objects"); goto err; } - idx = PyLong_FromSsize_t(s); - ok = idx && PyDict_SetItem(p->refs, id, idx) == 0; - Py_DECREF(id); - Py_XDECREF(idx); - if (!ok) + 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; } @@ -529,7 +549,7 @@ w_complex_object(PyObject *v, char flag, WFILE *p) w_object(co->co_lnotab, p); } else if (PyObject_CheckBuffer(v)) { - /* Write unknown buffer-style objects as a string */ + /* Write unknown bytes-like objects as a byte string */ Py_buffer view; if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) != 0) { w_byte(TYPE_UNKNOWN, p); @@ -547,37 +567,81 @@ w_complex_object(PyObject *v, char flag, WFILE *p) } } +static int +w_init_refs(WFILE *wf, int version) +{ + if (version >= 3) { + wf->hashtable = _Py_hashtable_new(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_entry_t *entry, void *Py_UNUSED(data)) +{ + 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.depth = 0; - wf.refs = NULL; 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.depth = 0; - if (version >= 3) { - if ((wf.refs = PyDict_New()) == NULL) - return; /* caller mush check PyErr_Occurred() */ - } else - wf.refs = NULL; wf.version = version; + if (w_init_refs(&wf, version)) + return; /* caller mush check PyErr_Occurred() */ w_object(x, &wf); - Py_XDECREF(wf.refs); + w_clear_refs(&wf); + w_flush(&wf); } -typedef WFILE RFILE; /* Same struct with different invariants */ +typedef struct { + FILE *fp; + int depth; + PyObject *readable; /* Stream-like object being read from */ + PyObject *current_filename; + char *ptr; + char *end; + char *buf; + Py_ssize_t buf_size; + PyObject *refs; /* a list */ +} RFILE; static char * r_string(Py_ssize_t n, RFILE *p) @@ -727,8 +791,8 @@ r_PyLong(RFILE *p) return NULL; } - size = 1 + (ABS(n) - 1) / PyLong_MARSHAL_RATIO; - shorts_in_top_digit = 1 + (ABS(n) - 1) % PyLong_MARSHAL_RATIO; + 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; @@ -1417,18 +1481,20 @@ PyMarshal_ReadLongFromFile(FILE *fp) return res; } -#ifdef HAVE_FSTAT -/* Return size of file in bytes; < 0 if unknown. */ +/* Return size of file in bytes; < 0 if unknown or INT_MAX if too big */ static off_t getfilesize(FILE *fp) { - struct stat st; - if (fstat(fileno(fp), &st) != 0) + 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 st.st_size; + return (off_t)st.st_size; } -#endif /* 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 @@ -1441,7 +1507,6 @@ PyMarshal_ReadLastObjectFromFile(FILE *fp) { /* REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc. */ #define REASONABLE_FILE_LIMIT (1L << 18) -#ifdef HAVE_FSTAT off_t filesize; filesize = getfilesize(fp); if (filesize > 0 && filesize <= REASONABLE_FILE_LIMIT) { @@ -1454,7 +1519,6 @@ PyMarshal_ReadLastObjectFromFile(FILE *fp) } } -#endif /* 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. */ @@ -1511,23 +1575,20 @@ PyMarshal_WriteObjectToString(PyObject *x, int version) { WFILE wf; - wf.fp = NULL; - wf.readable = NULL; + memset(&wf, 0, sizeof(wf)); wf.str = PyBytes_FromStringAndSize((char *)NULL, 50); if (wf.str == NULL) return NULL; - wf.ptr = PyBytes_AS_STRING((PyBytesObject *)wf.str); + wf.ptr = wf.buf = PyBytes_AS_STRING((PyBytesObject *)wf.str); wf.end = wf.ptr + PyBytes_Size(wf.str); wf.error = WFERR_OK; - wf.depth = 0; wf.version = version; - if (version >= 3) { - if ((wf.refs = PyDict_New()) == NULL) - return NULL; - } else - wf.refs = NULL; + if (w_init_refs(&wf, version)) { + Py_DECREF(wf.str); + return NULL; + } w_object(x, &wf); - Py_XDECREF(wf.refs); + w_clear_refs(&wf); if (wf.str != NULL) { char *base = PyBytes_AS_STRING((PyBytesObject *)wf.str); if (wf.ptr - base > PY_SSIZE_T_MAX) { diff --git a/Python/modsupport.c b/Python/modsupport.c index 428914f3788a..6c938ddd797e 100644 --- a/Python/modsupport.c +++ b/Python/modsupport.c @@ -161,7 +161,17 @@ do_mktuple(const char **p_format, va_list *p_va, int endchar, int n, int flags) /* 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); + PyObject *w; + + if (itemfailed) { + PyObject *exception, *value, *tb; + PyErr_Fetch(&exception, &value, &tb); + w = do_mkvalue(p_format, p_va, flags); + PyErr_Restore(exception, value, tb); + } + else { + w = do_mkvalue(p_format, p_va, flags); + } if (w == NULL) { itemfailed = 1; Py_INCREF(Py_None); diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index f90a17a7ee27..19259e1a71fd 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -15,8 +15,8 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&TARGET_UNARY_INVERT, - &&_unknown_opcode, - &&_unknown_opcode, + &&TARGET_BINARY_MATRIX_MULTIPLY, + &&TARGET_INPLACE_MATRIX_MULTIPLY, &&_unknown_opcode, &&TARGET_BINARY_POWER, &&TARGET_BINARY_MULTIPLY, @@ -49,11 +49,11 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, + &&TARGET_GET_AITER, + &&TARGET_GET_ANEXT, + &&TARGET_BEFORE_ASYNC_WITH, &&_unknown_opcode, &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&TARGET_STORE_MAP, &&TARGET_INPLACE_ADD, &&TARGET_INPLACE_SUBTRACT, &&TARGET_INPLACE_MULTIPLY, @@ -68,11 +68,11 @@ static void *opcode_targets[256] = { &&TARGET_BINARY_OR, &&TARGET_INPLACE_POWER, &&TARGET_GET_ITER, - &&_unknown_opcode, + &&TARGET_GET_YIELD_FROM_ITER, &&TARGET_PRINT_EXPR, &&TARGET_LOAD_BUILD_CLASS, &&TARGET_YIELD_FROM, - &&_unknown_opcode, + &&TARGET_GET_AWAITABLE, &&_unknown_opcode, &&TARGET_INPLACE_LSHIFT, &&TARGET_INPLACE_RSHIFT, @@ -80,8 +80,8 @@ static void *opcode_targets[256] = { &&TARGET_INPLACE_XOR, &&TARGET_INPLACE_OR, &&TARGET_BREAK_LOOP, - &&TARGET_WITH_CLEANUP, - &&_unknown_opcode, + &&TARGET_WITH_CLEANUP_START, + &&TARGET_WITH_CLEANUP_FINISH, &&TARGET_RETURN_VALUE, &&TARGET_IMPORT_STAR, &&_unknown_opcode, @@ -148,12 +148,12 @@ static void *opcode_targets[256] = { &&TARGET_SET_ADD, &&TARGET_MAP_ADD, &&TARGET_LOAD_CLASSDEREF, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, + &&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, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, diff --git a/Python/peephole.c b/Python/peephole.c index 4185462b34af..59ad3b762f8b 100644 --- a/Python/peephole.c +++ b/Python/peephole.c @@ -18,7 +18,11 @@ || 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) (GETARG(arr,i) + (ABSOLUTE_JUMP(arr[i]) ? 0 : i+3)) -#define SETARG(arr, i, val) arr[i+2] = val>>8; arr[i+1] = val & 255 +#define SETARG(arr, i, val) do { \ + assert(0 <= val && val <= 0xffff); \ + arr[i+2] = (unsigned char)(((unsigned int)val)>>8); \ + arr[i+1] = (unsigned char)(((unsigned int)val) & 255); \ +} while(0) #define CODESIZE(op) (HAS_ARG(op) ? 3 : 1) #define ISBASICBLOCK(blocks, start, bytes) \ (blocks[start]==blocks[start+bytes-1]) @@ -290,7 +294,7 @@ fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts, PyObject *v static unsigned int * markblocks(unsigned char *code, Py_ssize_t len) { - unsigned int *blocks = (unsigned int *)PyMem_Malloc(len*sizeof(int)); + unsigned int *blocks = PyMem_New(unsigned int, len); int i,j, opcode, blockcnt = 0; if (blocks == NULL) { @@ -315,6 +319,7 @@ markblocks(unsigned char *code, Py_ssize_t len) case SETUP_EXCEPT: case SETUP_FINALLY: case SETUP_WITH: + case SETUP_ASYNC_WITH: j = GETJUMPTGT(code, i); blocks[j] = 1; break; @@ -355,7 +360,8 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, unsigned char *codestr = NULL; unsigned char *lineno; int *addrmap = NULL; - int new_line, cum_orig_line, last_line, tabsiz; + int new_line, cum_orig_line, last_line; + Py_ssize_t tabsiz; PyObject **const_stack = NULL; Py_ssize_t *load_const_stack = NULL; Py_ssize_t const_stack_top = -1; @@ -398,7 +404,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, goto exitUnchanged; /* Mapping to new jump targets after NOPs are removed */ - addrmap = (int *)PyMem_Malloc(codelen * sizeof(int)); + addrmap = PyMem_New(int, codelen); if (addrmap == NULL) { PyErr_NoMemory(); goto exitError; @@ -615,6 +621,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, case SETUP_EXCEPT: case SETUP_FINALLY: case SETUP_WITH: + case SETUP_ASYNC_WITH: tgt = GETJUMPTGT(codestr, i); /* Replace JUMP_* to a RETURN into just a RETURN */ if (UNCONDITIONAL_JUMP(opcode) && @@ -660,7 +667,8 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, /* Fixup linenotab */ for (i=0, nops=0 ; i + +#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" +#endif + +_Py_IDENTIFIER(flush); +_Py_IDENTIFIER(name); +_Py_IDENTIFIER(stdin); +_Py_IDENTIFIER(stdout); +_Py_IDENTIFIER(stderr); + +#ifdef __cplusplus +extern "C" { +#endif + +extern wchar_t *Py_GetPath(void); + +extern grammar _PyParser_Grammar; /* From graminit.c */ + +/* Forward */ +static void initmain(PyInterpreterState *interp); +static int initfsencoding(PyInterpreterState *interp); +static void initsite(void); +static int initstdio(void); +static void initsigs(void); +static void call_py_exitfuncs(void); +static void wait_for_thread_shutdown(void); +static void call_ll_exitfuncs(void); +extern int _PyUnicode_Init(void); +extern int _PyStructSequence_Init(void); +extern void _PyUnicode_Fini(void); +extern int _PyLong_Init(void); +extern void PyLong_Fini(void); +extern int _PyFaulthandler_Init(void); +extern void _PyFaulthandler_Fini(void); +extern void _PyHash_Fini(void); +extern int _PyTraceMalloc_Init(void); +extern int _PyTraceMalloc_Fini(void); + +#ifdef WITH_THREAD +extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *); +extern void _PyGILState_Fini(void); +#endif /* WITH_THREAD */ + +/* Global configuration variable declarations are in pydebug.h */ +/* XXX (ncoghlan): move those declarations to pylifecycle.h? */ +int Py_DebugFlag; /* Needed by parser.c */ +int Py_VerboseFlag; /* Needed by import.c */ +int Py_QuietFlag; /* Needed by sysmodule.c */ +int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */ +int Py_InspectFlag; /* Needed to determine whether to exit at SystemExit */ +int Py_OptimizeFlag = 0; /* Needed by compile.c */ +int Py_NoSiteFlag; /* Suppress 'import site' */ +int Py_BytesWarningFlag; /* Warn on str(bytes) and str(buffer) */ +int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */ +int Py_FrozenFlag; /* Needed by getpath.c */ +int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */ +int Py_DontWriteBytecodeFlag; /* Suppress writing bytecode files (*.py[co]) */ +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 */ + +PyThreadState *_Py_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"); +} + +static int initialized = 0; + +/* API to access the initialized flag -- useful for esoteric use */ + +int +Py_IsInitialized(void) +{ + return initialized; +} + +/* 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; + } + /* 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) { + _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding); + if (!_Py_StandardStreamEncoding) { + return -2; + } + } + if (errors) { + _Py_StandardStreamErrors = _PyMem_RawStrdup(errors); + if (!_Py_StandardStreamErrors) { + if (_Py_StandardStreamEncoding) { + PyMem_RawFree(_Py_StandardStreamEncoding); + } + return -3; + } + } + return 0; +} + +/* Global initializations. Can be undone by Py_Finalize(). Don't + call this twice without an intervening Py_Finalize() 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 int +add_flag(int flag, const char *envs) +{ + int env = atoi(envs); + if (flag < env) + flag = env; + if (flag < 1) + flag = 1; + return flag; +} + +static char* +get_codec_name(const char *encoding) +{ + char *name_utf8, *name_str; + PyObject *codec, *name = NULL; + + codec = _PyCodec_Lookup(encoding); + if (!codec) + goto error; + + name = _PyObject_GetAttrId(codec, &PyId_name); + Py_CLEAR(codec); + if (!name) + goto error; + + name_utf8 = _PyUnicode_AsString(name); + if (name_utf8 == NULL) + goto error; + name_str = _PyMem_RawStrdup(name_utf8); + Py_DECREF(name); + if (name_str == NULL) { + PyErr_NoMemory(); + return NULL; + } + return name_str; + +error: + Py_XDECREF(codec); + Py_XDECREF(name); + return NULL; +} + +static char* +get_locale_encoding(void) +{ +#ifdef MS_WINDOWS + char codepage[100]; + PyOS_snprintf(codepage, sizeof(codepage), "cp%d", GetACP()); + return get_codec_name(codepage); +#elif defined(HAVE_LANGINFO_H) && defined(CODESET) + char* codeset = nl_langinfo(CODESET); + if (!codeset || codeset[0] == '\0') { + PyErr_SetString(PyExc_ValueError, "CODESET is not set or empty"); + return NULL; + } + return get_codec_name(codeset); +#else + PyErr_SetNone(PyExc_NotImplementedError); + return NULL; +#endif +} + +static void +import_init(PyInterpreterState *interp, PyObject *sysmod) +{ + PyObject *importlib; + PyObject *impmod; + PyObject *sys_modules; + PyObject *value; + + /* Import _importlib through its frozen version, _frozen_importlib. */ + if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) { + Py_FatalError("Py_Initialize: can't import _frozen_importlib"); + } + else if (Py_VerboseFlag) { + PySys_FormatStderr("import _frozen_importlib # frozen\n"); + } + importlib = PyImport_AddModule("_frozen_importlib"); + if (importlib == NULL) { + Py_FatalError("Py_Initialize: couldn't get _frozen_importlib from " + "sys.modules"); + } + interp->importlib = importlib; + Py_INCREF(interp->importlib); + + /* Import the _imp module */ + impmod = PyInit_imp(); + if (impmod == NULL) { + Py_FatalError("Py_Initialize: can't import _imp"); + } + else if (Py_VerboseFlag) { + PySys_FormatStderr("import _imp # builtin\n"); + } + sys_modules = PyImport_GetModuleDict(); + if (Py_VerboseFlag) { + PySys_FormatStderr("import sys # builtin\n"); + } + if (PyDict_SetItemString(sys_modules, "_imp", impmod) < 0) { + Py_FatalError("Py_Initialize: 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(); + Py_FatalError("Py_Initialize: importlib install failed"); + } + Py_DECREF(value); + Py_DECREF(impmod); + + _PyImportZip_Init(); +} + + +void +_Py_InitializeEx_Private(int install_sigs, int install_importlib) +{ + PyInterpreterState *interp; + PyThreadState *tstate; + PyObject *bimod, *sysmod, *pstderr; + char *p; + extern void _Py_ReadyTypes(void); + + if (initialized) + return; + initialized = 1; + _Py_Finalizing = NULL; + +#if defined(HAVE_LANGINFO_H) && defined(HAVE_SETLOCALE) + /* Set up the LC_CTYPE locale, so we can obtain + the locale's charset without having to switch + locales. */ + setlocale(LC_CTYPE, ""); +#endif + + if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0') + Py_DebugFlag = add_flag(Py_DebugFlag, p); + if ((p = Py_GETENV("PYTHONVERBOSE")) && *p != '\0') + Py_VerboseFlag = add_flag(Py_VerboseFlag, p); + if ((p = Py_GETENV("PYTHONOPTIMIZE")) && *p != '\0') + Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p); + if ((p = Py_GETENV("PYTHONDONTWRITEBYTECODE")) && *p != '\0') + Py_DontWriteBytecodeFlag = add_flag(Py_DontWriteBytecodeFlag, p); + /* The variable is only tested for existence here; _PyRandom_Init will + check its value further. */ + if ((p = Py_GETENV("PYTHONHASHSEED")) && *p != '\0') + Py_HashRandomizationFlag = add_flag(Py_HashRandomizationFlag, p); + + _PyRandom_Init(); + + interp = PyInterpreterState_New(); + if (interp == NULL) + Py_FatalError("Py_Initialize: can't make first interpreter"); + + tstate = PyThreadState_New(interp); + if (tstate == NULL) + Py_FatalError("Py_Initialize: can't make first thread"); + (void) PyThreadState_Swap(tstate); + +#ifdef WITH_THREAD + /* We can't call _PyEval_FiniThreads() in Py_Finalize 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_Finalize multiple times. */ + _PyEval_FiniThreads(); + + /* Auto-thread-state API */ + _PyGILState_Init(interp, tstate); +#endif /* WITH_THREAD */ + + _Py_ReadyTypes(); + + if (!_PyFrame_Init()) + Py_FatalError("Py_Initialize: can't init frames"); + + if (!_PyLong_Init()) + Py_FatalError("Py_Initialize: can't init longs"); + + if (!PyByteArray_Init()) + Py_FatalError("Py_Initialize: can't init bytearray"); + + if (!_PyFloat_Init()) + Py_FatalError("Py_Initialize: can't init float"); + + interp->modules = PyDict_New(); + if (interp->modules == NULL) + Py_FatalError("Py_Initialize: can't make modules dictionary"); + + /* Init Unicode implementation; relies on the codec registry */ + if (_PyUnicode_Init() < 0) + Py_FatalError("Py_Initialize: can't initialize unicode"); + if (_PyStructSequence_Init() < 0) + Py_FatalError("Py_Initialize: can't initialize structseq"); + + bimod = _PyBuiltin_Init(); + if (bimod == NULL) + Py_FatalError("Py_Initialize: can't initialize builtins modules"); + _PyImport_FixupBuiltin(bimod, "builtins"); + interp->builtins = PyModule_GetDict(bimod); + if (interp->builtins == NULL) + Py_FatalError("Py_Initialize: can't initialize builtins dict"); + Py_INCREF(interp->builtins); + + /* initialize builtin exceptions */ + _PyExc_Init(bimod); + + sysmod = _PySys_Init(); + if (sysmod == NULL) + Py_FatalError("Py_Initialize: can't initialize sys"); + interp->sysdict = PyModule_GetDict(sysmod); + if (interp->sysdict == NULL) + Py_FatalError("Py_Initialize: can't initialize sys dict"); + Py_INCREF(interp->sysdict); + _PyImport_FixupBuiltin(sysmod, "sys"); + PySys_SetPath(Py_GetPath()); + PyDict_SetItemString(interp->sysdict, "modules", + interp->modules); + + /* Set up a preliminary stderr printer until we have enough + infrastructure for the io module in place. */ + pstderr = PyFile_NewStdPrinter(fileno(stderr)); + if (pstderr == NULL) + Py_FatalError("Py_Initialize: can't set preliminary stderr"); + _PySys_SetObjectId(&PyId_stderr, pstderr); + PySys_SetObject("__stderr__", pstderr); + Py_DECREF(pstderr); + + _PyImport_Init(); + + _PyImportHooks_Init(); + + /* Initialize _warnings. */ + _PyWarnings_Init(); + + if (!install_importlib) + return; + + if (_PyTime_Init() < 0) + Py_FatalError("Py_Initialize: can't initialize time"); + + import_init(interp, sysmod); + + /* initialize the faulthandler module */ + if (_PyFaulthandler_Init()) + Py_FatalError("Py_Initialize: can't initialize faulthandler"); + + if (initfsencoding(interp) < 0) + Py_FatalError("Py_Initialize: unable to load the file system codec"); + + if (install_sigs) + initsigs(); /* Signal handling stuff, including initintr() */ + + if (_PyTraceMalloc_Init() < 0) + Py_FatalError("Py_Initialize: can't initialize tracemalloc"); + + initmain(interp); /* Module __main__ */ + if (initstdio() < 0) + Py_FatalError( + "Py_Initialize: can't initialize sys standard streams"); + + /* Initialize warnings. */ + if (PySys_HasWarnOptions()) { + PyObject *warnings_module = PyImport_ImportModule("warnings"); + if (warnings_module == NULL) { + fprintf(stderr, "'import warnings' failed; traceback:\n"); + PyErr_Print(); + } + Py_XDECREF(warnings_module); + } + + if (!Py_NoSiteFlag) + initsite(); /* Module site */ +} + +void +Py_InitializeEx(int install_sigs) +{ + _Py_InitializeEx_Private(install_sigs, 1); +} + +void +Py_Initialize(void) +{ + Py_InitializeEx(1); +} + + +#ifdef COUNT_ALLOCS +extern void 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 void +flush_std_files(void) +{ + PyObject *fout = _PySys_GetObjectId(&PyId_stdout); + PyObject *ferr = _PySys_GetObjectId(&PyId_stderr); + PyObject *tmp; + + if (fout != NULL && fout != Py_None && !file_is_closed(fout)) { + tmp = _PyObject_CallMethodId(fout, &PyId_flush, ""); + if (tmp == NULL) + PyErr_WriteUnraisable(fout); + else + Py_DECREF(tmp); + } + + if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) { + tmp = _PyObject_CallMethodId(ferr, &PyId_flush, ""); + if (tmp == NULL) + PyErr_Clear(); + else + Py_DECREF(tmp); + } +} + +/* 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. + +*/ + +void +Py_Finalize(void) +{ + PyInterpreterState *interp; + PyThreadState *tstate; + + if (!initialized) + return; + + wait_for_thread_shutdown(); + + /* 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 + * interpreter 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(); + + /* Get current thread state and interpreter pointer */ + tstate = PyThreadState_GET(); + interp = tstate->interp; + + /* Remaining threads (e.g. daemon threads) will automatically exit + after taking the GIL (in PyEval_RestoreThread()). */ + _Py_Finalizing = tstate; + initialized = 0; + + /* Flush sys.stdout and sys.stderr */ + flush_std_files(); + + /* 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_Collect(); +#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_Collect() > 0) + /* nothing */; +#endif + /* Destroy all modules */ + PyImport_Cleanup(); + + /* Flush sys.stdout and sys.stderr (again, in case more was printed) */ + flush_std_files(); + + /* 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_Collect(); +#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 + dump_counts(stdout); +#endif + /* dump hash stats */ + _PyHash_Fini(); + + _PY_DEBUG_PRINT_TOTAL_REFS(); + +#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 (Py_GETENV("PYTHONDUMPREFS")) + _Py_PrintReferences(stderr); +#endif /* Py_TRACE_REFS */ + + /* Clear interpreter state and all thread states. */ + PyInterpreterState_Clear(interp); + + /* 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(); + PyByteArray_Fini(); + PyLong_Fini(); + PyFloat_Fini(); + PyDict_Fini(); + PySlice_Fini(); + _PyGC_Fini(); + _PyRandom_Fini(); + + /* Cleanup Unicode implementation */ + _PyUnicode_Fini(); + + /* reset file system default encoding */ + if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) { + PyMem_RawFree((char*)Py_FileSystemDefaultEncoding); + Py_FileSystemDefaultEncoding = NULL; + } + + /* 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 */ +#ifdef WITH_THREAD + _PyGILState_Fini(); +#endif /* WITH_THREAD */ + + /* 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 (Py_GETENV("PYTHONDUMPREFS")) + _Py_PrintReferenceAddresses(stderr); +#endif /* Py_TRACE_REFS */ +#ifdef PYMALLOC_DEBUG + if (Py_GETENV("PYTHONMALLOCSTATS")) + _PyObject_DebugMallocStats(stderr); +#endif + + call_ll_exitfuncs(); +} + +/* 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. + +*/ + +PyThreadState * +Py_NewInterpreter(void) +{ + PyInterpreterState *interp; + PyThreadState *tstate, *save_tstate; + PyObject *bimod, *sysmod; + + if (!initialized) + Py_FatalError("Py_NewInterpreter: call Py_Initialize first"); + + interp = PyInterpreterState_New(); + if (interp == NULL) + return NULL; + + tstate = PyThreadState_New(interp); + if (tstate == NULL) { + PyInterpreterState_Delete(interp); + return NULL; + } + + save_tstate = PyThreadState_Swap(tstate); + + /* XXX The following is lax in error checking */ + + interp->modules = PyDict_New(); + + bimod = _PyImport_FindBuiltin("builtins"); + if (bimod != NULL) { + interp->builtins = PyModule_GetDict(bimod); + if (interp->builtins == NULL) + goto handle_error; + Py_INCREF(interp->builtins); + } + + /* initialize builtin exceptions */ + _PyExc_Init(bimod); + + sysmod = _PyImport_FindBuiltin("sys"); + if (bimod != NULL && sysmod != NULL) { + PyObject *pstderr; + + interp->sysdict = PyModule_GetDict(sysmod); + if (interp->sysdict == NULL) + goto handle_error; + Py_INCREF(interp->sysdict); + PySys_SetPath(Py_GetPath()); + PyDict_SetItemString(interp->sysdict, "modules", + interp->modules); + /* Set up a preliminary stderr printer until we have enough + infrastructure for the io module in place. */ + pstderr = PyFile_NewStdPrinter(fileno(stderr)); + if (pstderr == NULL) + Py_FatalError("Py_Initialize: can't set preliminary stderr"); + _PySys_SetObjectId(&PyId_stderr, pstderr); + PySys_SetObject("__stderr__", pstderr); + Py_DECREF(pstderr); + + _PyImportHooks_Init(); + + import_init(interp, sysmod); + + if (initfsencoding(interp) < 0) + goto handle_error; + + if (initstdio() < 0) + Py_FatalError( + "Py_Initialize: can't initialize sys standard streams"); + initmain(interp); + if (!Py_NoSiteFlag) + initsite(); + } + + if (!PyErr_Occurred()) + return tstate; + +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); + + return NULL; +} + +/* 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_Finalize() 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"); + + wait_for_thread_shutdown(); + + 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); +} + +#ifdef MS_WINDOWS +static wchar_t *progname = L"python"; +#else +static wchar_t *progname = L"python3"; +#endif + +void +Py_SetProgramName(wchar_t *pn) +{ + if (pn && *pn) + progname = pn; +} + +wchar_t * +Py_GetProgramName(void) +{ + return progname; +} + +static wchar_t *default_home = NULL; +static wchar_t env_home[MAXPATHLEN+1]; + +void +Py_SetPythonHome(wchar_t *home) +{ + default_home = home; +} + +wchar_t * +Py_GetPythonHome(void) +{ + wchar_t *home = default_home; + if (home == NULL && !Py_IgnoreEnvironmentFlag) { + char* chome = Py_GETENV("PYTHONHOME"); + if (chome) { + size_t size = Py_ARRAY_LENGTH(env_home); + size_t r = mbstowcs(env_home, chome, size); + if (r != (size_t)-1 && r < size) + home = env_home; + } + + } + return home; +} + +/* Create __main__ module */ + +static void +initmain(PyInterpreterState *interp) +{ + PyObject *m, *d, *loader; + m = PyImport_AddModule("__main__"); + if (m == NULL) + Py_FatalError("can't create __main__ module"); + d = PyModule_GetDict(m); + if (PyDict_GetItemString(d, "__builtins__") == NULL) { + PyObject *bimod = PyImport_ImportModule("builtins"); + if (bimod == NULL) { + Py_FatalError("Failed to retrieve builtins module"); + } + if (PyDict_SetItemString(d, "__builtins__", bimod) < 0) { + Py_FatalError("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) { + Py_FatalError("Failed to retrieve BuiltinImporter"); + } + if (PyDict_SetItemString(d, "__loader__", loader) < 0) { + Py_FatalError("Failed to initialize __main__.__loader__"); + } + Py_DECREF(loader); + } +} + +static int +initfsencoding(PyInterpreterState *interp) +{ + PyObject *codec; + + if (Py_FileSystemDefaultEncoding == NULL) + { + Py_FileSystemDefaultEncoding = get_locale_encoding(); + if (Py_FileSystemDefaultEncoding == NULL) + Py_FatalError("Py_Initialize: Unable to get the locale encoding"); + + Py_HasFileSystemDefaultEncoding = 0; + interp->fscodec_initialized = 1; + return 0; + } + + /* the encoding is mbcs, utf-8 or ascii */ + codec = _PyCodec_Lookup(Py_FileSystemDefaultEncoding); + if (!codec) { + /* Such error can only occurs in critical situations: no more + * memory, import a module of the standard library failed, + * etc. */ + return -1; + } + Py_DECREF(codec); + interp->fscodec_initialized = 1; + return 0; +} + +/* Import the site module (not into __main__ though) */ + +static void +initsite(void) +{ + PyObject *m; + m = PyImport_ImportModule("site"); + if (m == NULL) { + fprintf(stderr, "Failed to import the site module\n"); + PyErr_Print(); + Py_Finalize(); + exit(1); + } + else { + Py_DECREF(m); + } +} + +/* 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) +{ + int fd2; + if (fd < 0 || !_PyVerify_fd(fd)) + return 0; + _Py_BEGIN_SUPPRESS_IPH + /* Prefer dup() over fstat(). fstat() can require input/output whereas + dup() doesn't, there is a low risk of EMFILE/ENFILE at Python + startup. */ + fd2 = dup(fd); + if (fd2 >= 0) + close(fd2); + _Py_END_SUPPRESS_IPH + return fd2 >= 0; +} + +/* returns Py_None if the fd is not valid */ +static PyObject* +create_stdio(PyObject* io, + int fd, int write_mode, char* name, + char* encoding, char* errors) +{ + PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res; + const char* mode; + const char* newline; + PyObject *line_buffering; + int buffering, isatty; + _Py_IDENTIFIER(open); + _Py_IDENTIFIER(isatty); + _Py_IDENTIFIER(TextIOWrapper); + _Py_IDENTIFIER(mode); + + 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 (Py_UnbufferedStdioFlag && 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, Py_None, 0); + 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); + } + + text = PyUnicode_FromString(name); + if (text == NULL || _PyObject_SetAttrId(raw, &PyId_name, text) < 0) + goto error; + res = _PyObject_CallMethodId(raw, &PyId_isatty, ""); + if (res == NULL) + goto error; + isatty = PyObject_IsTrue(res); + Py_DECREF(res); + if (isatty == -1) + goto error; + if (isatty || Py_UnbufferedStdioFlag) + 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 + + stream = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "OsssO", + buf, encoding, errors, + newline, line_buffering); + Py_CLEAR(buf); + 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 int +initstdio(void) +{ + PyObject *iomod = NULL, *wrapper; + PyObject *bimod = NULL; + PyObject *m; + PyObject *std = NULL; + int status = 0, fd; + PyObject * encoding_attr; + char *pythonioencoding = NULL, *encoding, *errors; + + /* 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); + + encoding = _Py_StandardStreamEncoding; + errors = _Py_StandardStreamErrors; + if (!encoding || !errors) { + if (!errors) { + /* When the LC_CTYPE locale is the POSIX locale ("C locale"), + stdin and stdout use the surrogateescape error handler by + default, instead of the strict error handler. */ + char *loc = setlocale(LC_CTYPE, NULL); + if (loc != NULL && strcmp(loc, "C") == 0) + errors = "surrogateescape"; + } + + pythonioencoding = Py_GETENV("PYTHONIOENCODING"); + if (pythonioencoding) { + char *err; + pythonioencoding = _PyMem_Strdup(pythonioencoding); + if (pythonioencoding == NULL) { + PyErr_NoMemory(); + goto error; + } + err = strchr(pythonioencoding, ':'); + if (err) { + *err = '\0'; + err++; + if (*err && !_Py_StandardStreamErrors) { + errors = err; + } + } + if (*pythonioencoding && !encoding) { + encoding = pythonioencoding; + } + } + } + + /* 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(iomod, fd, 0, "", encoding, 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(iomod, fd, 1, "", encoding, 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(iomod, fd, 1, "", encoding, "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; + std_encoding = _PyUnicode_AsString(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 + + if (0) { + error: + status = -1; + } + + /* 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_Free(pythonioencoding); + Py_XDECREF(bimod); + Py_XDECREF(iomod); + return status; +} + + +/* 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. */ + +static void +_Py_PrintFatalError(int fd) +{ + PyObject *ferr, *res; + PyObject *exception, *v, *tb; + int has_tb; + PyThreadState *tstate; + + PyErr_Fetch(&exception, &v, &tb); + if (exception == NULL) { + /* No current exception */ + goto display_stack; + } + + 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 */ + goto display_stack; + } + + PyErr_NormalizeException(&exception, &v, &tb); + if (tb == NULL) { + tb = Py_None; + Py_INCREF(tb); + } + PyException_SetTraceback(v, tb); + if (exception == NULL) { + /* PyErr_NormalizeException() failed */ + goto display_stack; + } + + 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, ""); + if (res == NULL) + PyErr_Clear(); + else + Py_DECREF(res); + + if (has_tb) + return; + +display_stack: +#ifdef WITH_THREAD + /* PyGILState_GetThisThreadState() works even if the GIL was released */ + tstate = PyGILState_GetThisThreadState(); +#else + tstate = PyThreadState_GET(); +#endif + if (tstate == NULL) { + /* _Py_DumpTracebackThreads() requires the thread state to display + * frames */ + return; + } + + fputc('\n', stderr); + fflush(stderr); + + /* display the current Python stack */ + _Py_DumpTracebackThreads(fd, tstate->interp, tstate); +} +/* Print fatal error message and abort */ + +void +Py_FatalError(const char *msg) +{ + const int fd = fileno(stderr); + static int reentrant = 0; +#ifdef MS_WINDOWS + size_t len; + WCHAR* buffer; + size_t i; +#endif + + if (reentrant) { + /* Py_FatalError() caused a second fatal error. + Example: flush_std_files() raises a recursion error. */ + goto exit; + } + reentrant = 1; + + fprintf(stderr, "Fatal Python error: %s\n", msg); + fflush(stderr); /* it helps in Windows debug build */ + + /* Print the exception (if an exception is set) with its traceback, + * or display the current Python stack. */ + _Py_PrintFatalError(fd); + + /* Flush sys.stdout and sys.stderr */ + flush_std_files(); + + /* The main purpose of faulthandler is to display the traceback. We already + * did our best to display it. So faulthandler can now be disabled. + * (Don't trigger it on abort().) */ + _PyFaulthandler_Fini(); + +#ifdef MS_WINDOWS + len = strlen(msg); + + /* 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. */ + buffer = alloca( (len+1) * (sizeof *buffer)); + for( i=0; i<=len; ++i) + buffer[i] = msg[i]; + OutputDebugStringW(L"Fatal Python error: "); + OutputDebugStringW(buffer); + OutputDebugStringW(L"\n"); +#endif /* MS_WINDOWS */ + +exit: +#if defined(MS_WINDOWS) && defined(_DEBUG) + DebugBreak(); +#endif + abort(); +} + +/* Clean up and exit */ + +#ifdef WITH_THREAD +#include "pythread.h" +#endif + +static void (*pyexitfunc)(void) = NULL; +/* For the atexit module. */ +void _Py_PyAtExit(void (*func)(void)) +{ + pyexitfunc = func; +} + +static void +call_py_exitfuncs(void) +{ + if (pyexitfunc == NULL) + return; + + (*pyexitfunc)(); + 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) +{ +#ifdef WITH_THREAD + _Py_IDENTIFIER(_shutdown); + PyObject *result; + PyThreadState *tstate = PyThreadState_GET(); + PyObject *threading = PyMapping_GetItemString(tstate->interp->modules, + "threading"); + if (threading == NULL) { + /* threading not imported */ + PyErr_Clear(); + return; + } + result = _PyObject_CallMethodId(threading, &PyId__shutdown, ""); + if (result == NULL) { + PyErr_WriteUnraisable(threading); + } + else { + Py_DECREF(result); + } + Py_DECREF(threading); +#endif +} + +#define NEXITFUNCS 32 +static void (*exitfuncs[NEXITFUNCS])(void); +static int nexitfuncs = 0; + +int Py_AtExit(void (*func)(void)) +{ + if (nexitfuncs >= NEXITFUNCS) + return -1; + exitfuncs[nexitfuncs++] = func; + return 0; +} + +static void +call_ll_exitfuncs(void) +{ + while (nexitfuncs > 0) + (*exitfuncs[--nexitfuncs])(); + + fflush(stdout); + fflush(stderr); +} + +void +Py_Exit(int sts) +{ + Py_Finalize(); + + exit(sts); +} + +static void +initsigs(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 + PyOS_InitInterrupts(); /* May imply initsignal() */ + if (PyErr_Occurred()) { + Py_FatalError("Py_Initialize: can't import signal"); + } +} + + +/* 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/pymath.c b/Python/pymath.c index 827a773a6a3e..6799d200caf6 100644 --- a/Python/pymath.c +++ b/Python/pymath.c @@ -73,7 +73,7 @@ round(double x) absx = fabs(x); y = floor(absx); if (absx - y >= 0.5) - y += 1.0; + y += 1.0; return copysign(y, x); } #endif /* HAVE_ROUND */ diff --git a/Python/pystate.c b/Python/pystate.c index 6be71de2ae0b..7e0267ae1d04 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -72,6 +72,7 @@ PyInterpreterState_New(void) interp->modules_by_index = NULL; interp->sysdict = NULL; interp->builtins = NULL; + interp->builtins_copy = NULL; interp->tstate_head = NULL; interp->codec_search_path = NULL; interp->codec_search_cache = NULL; @@ -115,6 +116,7 @@ PyInterpreterState_Clear(PyInterpreterState *interp) Py_CLEAR(interp->modules_by_index); Py_CLEAR(interp->sysdict); Py_CLEAR(interp->builtins); + Py_CLEAR(interp->builtins_copy); Py_CLEAR(interp->importlib); } @@ -210,6 +212,9 @@ new_threadstate(PyInterpreterState *interp, int init) tstate->on_delete = NULL; tstate->on_delete_data = NULL; + tstate->coroutine_wrapper = NULL; + tstate->in_coroutine_wrapper = 0; + if (init) _PyThreadState_Init(tstate); @@ -251,6 +256,9 @@ PyState_FindModule(struct PyModuleDef* module) Py_ssize_t index = module->m_base.m_index; PyInterpreterState *state = PyThreadState_GET()->interp; PyObject *res; + if (module->m_slots) { + return NULL; + } if (index == 0) return NULL; if (state->modules_by_index == NULL) @@ -264,7 +272,13 @@ PyState_FindModule(struct PyModuleDef* module) int _PyState_AddModule(PyObject* module, struct PyModuleDef* def) { - PyInterpreterState *state = PyThreadState_GET()->interp; + PyInterpreterState *state; + if (def->m_slots) { + PyErr_SetString(PyExc_SystemError, + "PyState_AddModule called on module with slots"); + return -1; + } + state = PyThreadState_GET()->interp; if (!def) return -1; if (!state->modules_by_index) { @@ -304,8 +318,14 @@ PyState_AddModule(PyObject* module, struct PyModuleDef* def) int PyState_RemoveModule(struct PyModuleDef* def) { + PyInterpreterState *state; Py_ssize_t index = def->m_base.m_index; - PyInterpreterState *state = PyThreadState_GET()->interp; + if (def->m_slots) { + PyErr_SetString(PyExc_SystemError, + "PyState_RemoveModule called on module with slots"); + return -1; + } + state = PyThreadState_GET()->interp; if (index == 0) { Py_FatalError("PyState_RemoveModule: Module index invalid."); return -1; @@ -370,6 +390,8 @@ PyThreadState_Clear(PyThreadState *tstate) tstate->c_tracefunc = NULL; Py_CLEAR(tstate->c_profileobj); Py_CLEAR(tstate->c_traceobj); + + Py_CLEAR(tstate->coroutine_wrapper); } @@ -401,7 +423,7 @@ tstate_delete_common(PyThreadState *tstate) void PyThreadState_Delete(PyThreadState *tstate) { - if (tstate == _Py_atomic_load_relaxed(&_PyThreadState_Current)) + if (tstate == (PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)) Py_FatalError("PyThreadState_Delete: tstate is still current"); #ifdef WITH_THREAD if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate) @@ -660,7 +682,7 @@ PyThreadState_IsCurrent(PyThreadState *tstate) { /* Must be the tstate for this thread */ assert(PyGILState_GetThisThreadState()==tstate); - return tstate == _Py_atomic_load_relaxed(&_PyThreadState_Current); + return tstate == (PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current); } /* Internal initialization/finalization functions called by @@ -723,18 +745,18 @@ _PyGILState_NoteThreadState(PyThreadState* tstate) The only situation where you can legitimately have more than one thread state for an OS level thread is when there are multiple - interpreters, when: + interpreters. - a) You shouldn't really be using the PyGILState_ APIs anyway, - and: + You shouldn't really be using the PyGILState_ APIs anyway (see issues + #10915 and #15751). - b) The slightly odd way PyThread_set_key_value works (see - comments by its implementation) means that the first thread - state created for that given OS level thread will "win", - which seems reasonable behaviour. + The first thread state created for that given OS level thread will + "win", which seems reasonable behaviour. */ - if (PyThread_set_key_value(autoTLSkey, (void *)tstate) < 0) - Py_FatalError("Couldn't create autoTLSkey mapping"); + if (PyThread_get_key_value(autoTLSkey) == NULL) { + if (PyThread_set_key_value(autoTLSkey, (void *)tstate) < 0) + Py_FatalError("Couldn't create autoTLSkey mapping"); + } /* PyGILState_Release must not try to delete this thread state. */ tstate->gilstate_counter = 1; @@ -771,6 +793,11 @@ PyGILState_Ensure(void) assert(autoInterpreterState); /* Py_Initialize() hasn't been called! */ tcur = (PyThreadState *)PyThread_get_key_value(autoTLSkey); if (tcur == NULL) { + /* 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(); + /* Create a new thread state for this thread */ tcur = PyThreadState_New(autoInterpreterState); if (tcur == NULL) diff --git a/Python/pystrhex.c b/Python/pystrhex.c new file mode 100644 index 000000000000..1259ed12dffe --- /dev/null +++ b/Python/pystrhex.c @@ -0,0 +1,61 @@ +/* bytes to hex implementation */ + +#include "Python.h" + +static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen, + int return_bytes) +{ + PyObject *retval; + Py_UCS1* retbuf; + Py_ssize_t i, j; + + assert(arglen >= 0); + if (arglen > PY_SSIZE_T_MAX / 2) + return PyErr_NoMemory(); + + if (return_bytes) { + /* If _PyBytes_FromSize() were public we could avoid malloc+copy. */ + retbuf = (Py_UCS1*) PyMem_Malloc(arglen*2); + if (!retbuf) + return PyErr_NoMemory(); + retval = NULL; /* silence a compiler warning, assigned later. */ + } else { + retval = PyUnicode_New(arglen*2, 127); + if (!retval) + return NULL; + retbuf = PyUnicode_1BYTE_DATA(retval); + } + + /* make hex version of string, taken from shamodule.c */ + for (i=j=0; i < arglen; i++) { + unsigned char c; + c = (argbuf[i] >> 4) & 0xf; + retbuf[j++] = Py_hexdigits[c]; + c = argbuf[i] & 0xf; + retbuf[j++] = Py_hexdigits[c]; + } + + if (return_bytes) { + retval = PyBytes_FromStringAndSize((const char *)retbuf, arglen*2); + PyMem_Free(retbuf); + } +#ifdef Py_DEBUG + else { + assert(_PyUnicode_CheckConsistency(retval, 1)); + } +#endif + + return retval; +} + +PyAPI_FUNC(PyObject *) _Py_strhex(const char* argbuf, const Py_ssize_t arglen) +{ + return _Py_strhex_impl(argbuf, arglen, 0); +} + +/* Same as above but returns a bytes() instead of str() to avoid the + * need to decode the str() when bytes are needed. */ +PyAPI_FUNC(PyObject *) _Py_strhex_bytes(const char* argbuf, const Py_ssize_t arglen) +{ + return _Py_strhex_impl(argbuf, arglen, 1); +} diff --git a/Python/pystrtod.c b/Python/pystrtod.c index b8dd919a26e7..209c9086c87b 100644 --- a/Python/pystrtod.c +++ b/Python/pystrtod.c @@ -325,7 +325,7 @@ _PyOS_ascii_strtod(const char *nptr, char **endptr) 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 + 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. diff --git a/Python/pythonrun.c b/Python/pythonrun.c index ccf82af36bad..1a5dab5f3a0b 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -15,6 +15,7 @@ #include "ast.h" #include "marshal.h" #include "osdefs.h" +#include #ifdef HAVE_SIGNAL_H #include @@ -25,14 +26,12 @@ #endif #ifdef HAVE_LANGINFO_H -#include #include #endif #ifdef MS_WINDOWS #undef BYTE #include "windows.h" -#define PATH_MAX MAXPATHLEN #endif _Py_IDENTIFIER(builtins); @@ -41,7 +40,6 @@ _Py_IDENTIFIER(flush); _Py_IDENTIFIER(last_traceback); _Py_IDENTIFIER(last_type); _Py_IDENTIFIER(last_value); -_Py_IDENTIFIER(name); _Py_IDENTIFIER(ps1); _Py_IDENTIFIER(ps2); _Py_IDENTIFIER(stdin); @@ -49,43 +47,13 @@ _Py_IDENTIFIER(stdout); _Py_IDENTIFIER(stderr); _Py_static_string(PyId_string, ""); -#ifdef Py_REF_DEBUG -static -void _print_total_refs(void) { - PyObject *xoptions, *value; - _Py_IDENTIFIER(showrefcount); - - xoptions = PySys_GetXOptions(); - if (xoptions == NULL) - return; - value = _PyDict_GetItemId(xoptions, &PyId_showrefcount); - if (value == Py_True) - fprintf(stderr, - "[%" PY_FORMAT_SIZE_T "d refs, " - "%" PY_FORMAT_SIZE_T "d blocks]\n", - _Py_GetRefTotal(), _Py_GetAllocatedBlocks()); -} -#endif - -#ifndef Py_REF_DEBUG -#define PRINT_TOTAL_REFS() -#else /* Py_REF_DEBUG */ -#define PRINT_TOTAL_REFS() _print_total_refs() -#endif - #ifdef __cplusplus extern "C" { #endif -extern wchar_t *Py_GetPath(void); - extern grammar _PyParser_Grammar; /* From graminit.c */ /* Forward */ -static void initmain(PyInterpreterState *interp); -static int initfsencoding(PyInterpreterState *interp); -static void initsite(void); -static int initstdio(void); static void flush_io(void); static PyObject *run_mod(mod_ty, PyObject *, PyObject *, PyObject *, PyCompilerFlags *, PyArena *); @@ -93,1192 +61,6 @@ static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *, PyCompilerFlags *); static void err_input(perrdetail *); static void err_free(perrdetail *); -static void initsigs(void); -static void call_py_exitfuncs(void); -static void wait_for_thread_shutdown(void); -static void call_ll_exitfuncs(void); -extern int _PyUnicode_Init(void); -extern int _PyStructSequence_Init(void); -extern void _PyUnicode_Fini(void); -extern int _PyLong_Init(void); -extern void PyLong_Fini(void); -extern int _PyFaulthandler_Init(void); -extern void _PyFaulthandler_Fini(void); -extern void _PyHash_Fini(void); -extern int _PyTraceMalloc_Init(void); -extern int _PyTraceMalloc_Fini(void); - -#ifdef WITH_THREAD -extern void _PyGILState_Init(PyInterpreterState *, PyThreadState *); -extern void _PyGILState_Fini(void); -#endif /* WITH_THREAD */ - -int Py_DebugFlag; /* Needed by parser.c */ -int Py_VerboseFlag; /* Needed by import.c */ -int Py_QuietFlag; /* Needed by sysmodule.c */ -int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */ -int Py_InspectFlag; /* Needed to determine whether to exit at SystemExit */ -int Py_NoSiteFlag; /* Suppress 'import site' */ -int Py_BytesWarningFlag; /* Warn on str(bytes) and str(buffer) */ -int Py_DontWriteBytecodeFlag; /* Suppress writing bytecode files (*.py[co]) */ -int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */ -int Py_FrozenFlag; /* Needed by getpath.c */ -int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */ -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 */ - -PyThreadState *_Py_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"); -} - -static int initialized = 0; - -/* API to access the initialized flag -- useful for esoteric use */ - -int -Py_IsInitialized(void) -{ - return initialized; -} - -/* 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; - } - /* 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) { - _Py_StandardStreamEncoding = _PyMem_RawStrdup(encoding); - if (!_Py_StandardStreamEncoding) { - return -2; - } - } - if (errors) { - _Py_StandardStreamErrors = _PyMem_RawStrdup(errors); - if (!_Py_StandardStreamErrors) { - if (_Py_StandardStreamEncoding) { - PyMem_RawFree(_Py_StandardStreamEncoding); - } - return -3; - } - } - return 0; -} - -/* Global initializations. Can be undone by Py_Finalize(). Don't - call this twice without an intervening Py_Finalize() 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 int -add_flag(int flag, const char *envs) -{ - int env = atoi(envs); - if (flag < env) - flag = env; - if (flag < 1) - flag = 1; - return flag; -} - -static char* -get_codec_name(const char *encoding) -{ - char *name_utf8, *name_str; - PyObject *codec, *name = NULL; - - codec = _PyCodec_Lookup(encoding); - if (!codec) - goto error; - - name = _PyObject_GetAttrId(codec, &PyId_name); - Py_CLEAR(codec); - if (!name) - goto error; - - name_utf8 = _PyUnicode_AsString(name); - if (name_utf8 == NULL) - goto error; - name_str = _PyMem_RawStrdup(name_utf8); - Py_DECREF(name); - if (name_str == NULL) { - PyErr_NoMemory(); - return NULL; - } - return name_str; - -error: - Py_XDECREF(codec); - Py_XDECREF(name); - return NULL; -} - -static char* -get_locale_encoding(void) -{ -#ifdef MS_WINDOWS - char codepage[100]; - PyOS_snprintf(codepage, sizeof(codepage), "cp%d", GetACP()); - return get_codec_name(codepage); -#elif defined(HAVE_LANGINFO_H) && defined(CODESET) - char* codeset = nl_langinfo(CODESET); - if (!codeset || codeset[0] == '\0') { - PyErr_SetString(PyExc_ValueError, "CODESET is not set or empty"); - return NULL; - } - return get_codec_name(codeset); -#else - PyErr_SetNone(PyExc_NotImplementedError); - return NULL; -#endif -} - -static void -import_init(PyInterpreterState *interp, PyObject *sysmod) -{ - PyObject *importlib; - PyObject *impmod; - PyObject *sys_modules; - PyObject *value; - - /* Import _importlib through its frozen version, _frozen_importlib. */ - if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) { - Py_FatalError("Py_Initialize: can't import _frozen_importlib"); - } - else if (Py_VerboseFlag) { - PySys_FormatStderr("import _frozen_importlib # frozen\n"); - } - importlib = PyImport_AddModule("_frozen_importlib"); - if (importlib == NULL) { - Py_FatalError("Py_Initialize: couldn't get _frozen_importlib from " - "sys.modules"); - } - interp->importlib = importlib; - Py_INCREF(interp->importlib); - - /* Install _importlib as __import__ */ - impmod = PyInit_imp(); - if (impmod == NULL) { - Py_FatalError("Py_Initialize: can't import imp"); - } - else if (Py_VerboseFlag) { - PySys_FormatStderr("import imp # builtin\n"); - } - sys_modules = PyImport_GetModuleDict(); - if (Py_VerboseFlag) { - PySys_FormatStderr("import sys # builtin\n"); - } - if (PyDict_SetItemString(sys_modules, "_imp", impmod) < 0) { - Py_FatalError("Py_Initialize: can't save _imp to sys.modules"); - } - - value = PyObject_CallMethod(importlib, "_install", "OO", sysmod, impmod); - if (value == NULL) { - PyErr_Print(); - Py_FatalError("Py_Initialize: importlib install failed"); - } - Py_DECREF(value); - Py_DECREF(impmod); - - _PyImportZip_Init(); -} - - -void -_Py_InitializeEx_Private(int install_sigs, int install_importlib) -{ - PyInterpreterState *interp; - PyThreadState *tstate; - PyObject *bimod, *sysmod, *pstderr; - char *p; - extern void _Py_ReadyTypes(void); - - if (initialized) - return; - initialized = 1; - _Py_Finalizing = NULL; - -#if defined(HAVE_LANGINFO_H) && defined(HAVE_SETLOCALE) - /* Set up the LC_CTYPE locale, so we can obtain - the locale's charset without having to switch - locales. */ - setlocale(LC_CTYPE, ""); -#endif - - if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0') - Py_DebugFlag = add_flag(Py_DebugFlag, p); - if ((p = Py_GETENV("PYTHONVERBOSE")) && *p != '\0') - Py_VerboseFlag = add_flag(Py_VerboseFlag, p); - if ((p = Py_GETENV("PYTHONOPTIMIZE")) && *p != '\0') - Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p); - if ((p = Py_GETENV("PYTHONDONTWRITEBYTECODE")) && *p != '\0') - Py_DontWriteBytecodeFlag = add_flag(Py_DontWriteBytecodeFlag, p); - /* The variable is only tested for existence here; _PyRandom_Init will - check its value further. */ - if ((p = Py_GETENV("PYTHONHASHSEED")) && *p != '\0') - Py_HashRandomizationFlag = add_flag(Py_HashRandomizationFlag, p); - - _PyRandom_Init(); - - interp = PyInterpreterState_New(); - if (interp == NULL) - Py_FatalError("Py_Initialize: can't make first interpreter"); - - tstate = PyThreadState_New(interp); - if (tstate == NULL) - Py_FatalError("Py_Initialize: can't make first thread"); - (void) PyThreadState_Swap(tstate); - -#ifdef WITH_THREAD - /* We can't call _PyEval_FiniThreads() in Py_Finalize 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_Finalize multiple times. */ - _PyEval_FiniThreads(); - - /* Auto-thread-state API */ - _PyGILState_Init(interp, tstate); -#endif /* WITH_THREAD */ - - _Py_ReadyTypes(); - - if (!_PyFrame_Init()) - Py_FatalError("Py_Initialize: can't init frames"); - - if (!_PyLong_Init()) - Py_FatalError("Py_Initialize: can't init longs"); - - if (!PyByteArray_Init()) - Py_FatalError("Py_Initialize: can't init bytearray"); - - if (!_PyFloat_Init()) - Py_FatalError("Py_Initialize: can't init float"); - - interp->modules = PyDict_New(); - if (interp->modules == NULL) - Py_FatalError("Py_Initialize: can't make modules dictionary"); - - /* Init Unicode implementation; relies on the codec registry */ - if (_PyUnicode_Init() < 0) - Py_FatalError("Py_Initialize: can't initialize unicode"); - if (_PyStructSequence_Init() < 0) - Py_FatalError("Py_Initialize: can't initialize structseq"); - - bimod = _PyBuiltin_Init(); - if (bimod == NULL) - Py_FatalError("Py_Initialize: can't initialize builtins modules"); - _PyImport_FixupBuiltin(bimod, "builtins"); - interp->builtins = PyModule_GetDict(bimod); - if (interp->builtins == NULL) - Py_FatalError("Py_Initialize: can't initialize builtins dict"); - Py_INCREF(interp->builtins); - - /* initialize builtin exceptions */ - _PyExc_Init(bimod); - - sysmod = _PySys_Init(); - if (sysmod == NULL) - Py_FatalError("Py_Initialize: can't initialize sys"); - interp->sysdict = PyModule_GetDict(sysmod); - if (interp->sysdict == NULL) - Py_FatalError("Py_Initialize: can't initialize sys dict"); - Py_INCREF(interp->sysdict); - _PyImport_FixupBuiltin(sysmod, "sys"); - PySys_SetPath(Py_GetPath()); - PyDict_SetItemString(interp->sysdict, "modules", - interp->modules); - - /* Set up a preliminary stderr printer until we have enough - infrastructure for the io module in place. */ - pstderr = PyFile_NewStdPrinter(fileno(stderr)); - if (pstderr == NULL) - Py_FatalError("Py_Initialize: can't set preliminary stderr"); - _PySys_SetObjectId(&PyId_stderr, pstderr); - PySys_SetObject("__stderr__", pstderr); - Py_DECREF(pstderr); - - _PyImport_Init(); - - _PyImportHooks_Init(); - - /* Initialize _warnings. */ - _PyWarnings_Init(); - - if (!install_importlib) - return; - - import_init(interp, sysmod); - - /* initialize the faulthandler module */ - if (_PyFaulthandler_Init()) - Py_FatalError("Py_Initialize: can't initialize faulthandler"); - - _PyTime_Init(); - - if (initfsencoding(interp) < 0) - Py_FatalError("Py_Initialize: unable to load the file system codec"); - - if (install_sigs) - initsigs(); /* Signal handling stuff, including initintr() */ - - if (_PyTraceMalloc_Init() < 0) - Py_FatalError("Py_Initialize: can't initialize tracemalloc"); - - initmain(interp); /* Module __main__ */ - if (initstdio() < 0) - Py_FatalError( - "Py_Initialize: can't initialize sys standard streams"); - - /* Initialize warnings. */ - if (PySys_HasWarnOptions()) { - PyObject *warnings_module = PyImport_ImportModule("warnings"); - if (warnings_module == NULL) { - fprintf(stderr, "'import warnings' failed; traceback:\n"); - PyErr_Print(); - } - Py_XDECREF(warnings_module); - } - - if (!Py_NoSiteFlag) - initsite(); /* Module site */ -} - -void -Py_InitializeEx(int install_sigs) -{ - _Py_InitializeEx_Private(install_sigs, 1); -} - -void -Py_Initialize(void) -{ - Py_InitializeEx(1); -} - - -#ifdef COUNT_ALLOCS -extern void 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 void -flush_std_files(void) -{ - PyObject *fout = _PySys_GetObjectId(&PyId_stdout); - PyObject *ferr = _PySys_GetObjectId(&PyId_stderr); - PyObject *tmp; - - if (fout != NULL && fout != Py_None && !file_is_closed(fout)) { - tmp = _PyObject_CallMethodId(fout, &PyId_flush, ""); - if (tmp == NULL) - PyErr_WriteUnraisable(fout); - else - Py_DECREF(tmp); - } - - if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) { - tmp = _PyObject_CallMethodId(ferr, &PyId_flush, ""); - if (tmp == NULL) - PyErr_Clear(); - else - Py_DECREF(tmp); - } -} - -/* 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. - -*/ - -void -Py_Finalize(void) -{ - PyInterpreterState *interp; - PyThreadState *tstate; - - if (!initialized) - return; - - wait_for_thread_shutdown(); - - /* 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 - * interpreter 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(); - - /* Get current thread state and interpreter pointer */ - tstate = PyThreadState_GET(); - interp = tstate->interp; - - /* Remaining threads (e.g. daemon threads) will automatically exit - after taking the GIL (in PyEval_RestoreThread()). */ - _Py_Finalizing = tstate; - initialized = 0; - - /* Destroy the state of all threads except of the current thread: in - practice, only daemon threads should still be alive. Clear frames of - other threads to call objects destructor. Destructors will be called in - the current Python thread. Since _Py_Finalizing has been set, no other - Python threads can lock the GIL at this point (if they try, they will - exit immediately). */ - _PyThreadState_DeleteExcept(tstate); - - /* 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_Collect(); - -#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_Collect() > 0) - /* nothing */; -#endif - - /* Flush stdout+stderr */ - flush_std_files(); - - /* Disable signal handling */ - PyOS_FiniInterrupts(); - - /* Destroy all modules */ - PyImport_Cleanup(); - - /* Flush stdout+stderr (again, in case more was printed) */ - flush_std_files(); - - /* 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_Collect(); -#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 - dump_counts(stdout); -#endif - /* dump hash stats */ - _PyHash_Fini(); - - PRINT_TOTAL_REFS(); - -#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 (Py_GETENV("PYTHONDUMPREFS")) - _Py_PrintReferences(stderr); -#endif /* Py_TRACE_REFS */ - - /* Clear interpreter state and all thread states. */ - PyInterpreterState_Clear(interp); - - /* 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(); - PyByteArray_Fini(); - PyLong_Fini(); - PyFloat_Fini(); - PyDict_Fini(); - PySlice_Fini(); - _PyGC_Fini(); - _PyRandom_Fini(); - - /* Cleanup Unicode implementation */ - _PyUnicode_Fini(); - - /* reset file system default encoding */ - if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) { - PyMem_RawFree((char*)Py_FileSystemDefaultEncoding); - Py_FileSystemDefaultEncoding = NULL; - } - - /* 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 */ -#ifdef WITH_THREAD - _PyGILState_Fini(); -#endif /* WITH_THREAD */ - - /* 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 (Py_GETENV("PYTHONDUMPREFS")) - _Py_PrintReferenceAddresses(stderr); -#endif /* Py_TRACE_REFS */ -#ifdef PYMALLOC_DEBUG - if (Py_GETENV("PYTHONMALLOCSTATS")) - _PyObject_DebugMallocStats(stderr); -#endif - - call_ll_exitfuncs(); -} - -/* 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. - -*/ - -PyThreadState * -Py_NewInterpreter(void) -{ - PyInterpreterState *interp; - PyThreadState *tstate, *save_tstate; - PyObject *bimod, *sysmod; - - if (!initialized) - Py_FatalError("Py_NewInterpreter: call Py_Initialize first"); - - interp = PyInterpreterState_New(); - if (interp == NULL) - return NULL; - - tstate = PyThreadState_New(interp); - if (tstate == NULL) { - PyInterpreterState_Delete(interp); - return NULL; - } - - save_tstate = PyThreadState_Swap(tstate); - - /* XXX The following is lax in error checking */ - - interp->modules = PyDict_New(); - - bimod = _PyImport_FindBuiltin("builtins"); - if (bimod != NULL) { - interp->builtins = PyModule_GetDict(bimod); - if (interp->builtins == NULL) - goto handle_error; - Py_INCREF(interp->builtins); - } - - /* initialize builtin exceptions */ - _PyExc_Init(bimod); - - sysmod = _PyImport_FindBuiltin("sys"); - if (bimod != NULL && sysmod != NULL) { - PyObject *pstderr; - - interp->sysdict = PyModule_GetDict(sysmod); - if (interp->sysdict == NULL) - goto handle_error; - Py_INCREF(interp->sysdict); - PySys_SetPath(Py_GetPath()); - PyDict_SetItemString(interp->sysdict, "modules", - interp->modules); - /* Set up a preliminary stderr printer until we have enough - infrastructure for the io module in place. */ - pstderr = PyFile_NewStdPrinter(fileno(stderr)); - if (pstderr == NULL) - Py_FatalError("Py_Initialize: can't set preliminary stderr"); - _PySys_SetObjectId(&PyId_stderr, pstderr); - PySys_SetObject("__stderr__", pstderr); - Py_DECREF(pstderr); - - _PyImportHooks_Init(); - - import_init(interp, sysmod); - - if (initfsencoding(interp) < 0) - goto handle_error; - - if (initstdio() < 0) - Py_FatalError( - "Py_Initialize: can't initialize sys standard streams"); - initmain(interp); - if (!Py_NoSiteFlag) - initsite(); - } - - if (!PyErr_Occurred()) - return tstate; - -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); - - return NULL; -} - -/* 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_Finalize() 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"); - - wait_for_thread_shutdown(); - - 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); -} - -#ifdef MS_WINDOWS -static wchar_t *progname = L"python"; -#else -static wchar_t *progname = L"python3"; -#endif - -void -Py_SetProgramName(wchar_t *pn) -{ - if (pn && *pn) - progname = pn; -} - -wchar_t * -Py_GetProgramName(void) -{ - return progname; -} - -static wchar_t *default_home = NULL; -static wchar_t env_home[MAXPATHLEN+1]; - -void -Py_SetPythonHome(wchar_t *home) -{ - default_home = home; -} - -wchar_t * -Py_GetPythonHome(void) -{ - wchar_t *home = default_home; - if (home == NULL && !Py_IgnoreEnvironmentFlag) { - char* chome = Py_GETENV("PYTHONHOME"); - if (chome) { - size_t size = Py_ARRAY_LENGTH(env_home); - size_t r = mbstowcs(env_home, chome, size); - if (r != (size_t)-1 && r < size) - home = env_home; - } - - } - return home; -} - -/* Create __main__ module */ - -static void -initmain(PyInterpreterState *interp) -{ - PyObject *m, *d, *loader; - m = PyImport_AddModule("__main__"); - if (m == NULL) - Py_FatalError("can't create __main__ module"); - d = PyModule_GetDict(m); - if (PyDict_GetItemString(d, "__builtins__") == NULL) { - PyObject *bimod = PyImport_ImportModule("builtins"); - if (bimod == NULL) { - Py_FatalError("Failed to retrieve builtins module"); - } - if (PyDict_SetItemString(d, "__builtins__", bimod) < 0) { - Py_FatalError("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) { - Py_FatalError("Failed to retrieve BuiltinImporter"); - } - if (PyDict_SetItemString(d, "__loader__", loader) < 0) { - Py_FatalError("Failed to initialize __main__.__loader__"); - } - Py_DECREF(loader); - } -} - -static int -initfsencoding(PyInterpreterState *interp) -{ - PyObject *codec; - - if (Py_FileSystemDefaultEncoding == NULL) - { - Py_FileSystemDefaultEncoding = get_locale_encoding(); - if (Py_FileSystemDefaultEncoding == NULL) - Py_FatalError("Py_Initialize: Unable to get the locale encoding"); - - Py_HasFileSystemDefaultEncoding = 0; - interp->fscodec_initialized = 1; - return 0; - } - - /* the encoding is mbcs, utf-8 or ascii */ - codec = _PyCodec_Lookup(Py_FileSystemDefaultEncoding); - if (!codec) { - /* Such error can only occurs in critical situations: no more - * memory, import a module of the standard library failed, - * etc. */ - return -1; - } - Py_DECREF(codec); - interp->fscodec_initialized = 1; - return 0; -} - -/* Import the site module (not into __main__ though) */ - -static void -initsite(void) -{ - PyObject *m; - m = PyImport_ImportModule("site"); - if (m == NULL) { - fprintf(stderr, "Failed to import the site module\n"); - PyErr_Print(); - Py_Finalize(); - exit(1); - } - else { - Py_DECREF(m); - } -} - -static PyObject* -create_stdio(PyObject* io, - int fd, int write_mode, char* name, - char* encoding, char* errors) -{ - PyObject *buf = NULL, *stream = NULL, *text = NULL, *raw = NULL, *res; - const char* mode; - const char* newline; - PyObject *line_buffering; - int buffering, isatty; - _Py_IDENTIFIER(open); - _Py_IDENTIFIER(isatty); - _Py_IDENTIFIER(TextIOWrapper); - _Py_IDENTIFIER(mode); - - /* 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 (Py_UnbufferedStdioFlag && 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, Py_None, 0); - 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); - } - - text = PyUnicode_FromString(name); - if (text == NULL || _PyObject_SetAttrId(raw, &PyId_name, text) < 0) - goto error; - res = _PyObject_CallMethodId(raw, &PyId_isatty, ""); - if (res == NULL) - goto error; - isatty = PyObject_IsTrue(res); - Py_DECREF(res); - if (isatty == -1) - goto error; - if (isatty || Py_UnbufferedStdioFlag) - 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 - - stream = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "OsssO", - buf, encoding, errors, - newline, line_buffering); - Py_CLEAR(buf); - 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); - return NULL; -} - -static int -is_valid_fd(int fd) -{ - int dummy_fd; - if (fd < 0 || !_PyVerify_fd(fd)) - return 0; - dummy_fd = dup(fd); - if (dummy_fd < 0) - return 0; - close(dummy_fd); - return 1; -} - -/* Initialize sys.stdin, stdout, stderr and builtins.open */ -static int -initstdio(void) -{ - PyObject *iomod = NULL, *wrapper; - PyObject *bimod = NULL; - PyObject *m; - PyObject *std = NULL; - int status = 0, fd; - PyObject * encoding_attr; - char *pythonioencoding = NULL, *encoding, *errors; - - /* 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); - - encoding = _Py_StandardStreamEncoding; - errors = _Py_StandardStreamErrors; - if (!encoding || !errors) { - pythonioencoding = Py_GETENV("PYTHONIOENCODING"); - if (pythonioencoding) { - char *err; - pythonioencoding = _PyMem_Strdup(pythonioencoding); - if (pythonioencoding == NULL) { - PyErr_NoMemory(); - goto error; - } - err = strchr(pythonioencoding, ':'); - if (err) { - *err = '\0'; - err++; - if (*err && !errors) { - errors = err; - } - } - if (*pythonioencoding && !encoding) { - encoding = pythonioencoding; - } - } - } - - /* 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. - */ - if (!is_valid_fd(fd)) { - std = Py_None; - Py_INCREF(std); - } - else { - std = create_stdio(iomod, fd, 0, "", encoding, errors); - if (std == NULL) - goto error; - } /* if (fd < 0) */ - PySys_SetObject("__stdin__", std); - _PySys_SetObjectId(&PyId_stdin, std); - Py_DECREF(std); - - /* Set sys.stdout */ - fd = fileno(stdout); - if (!is_valid_fd(fd)) { - std = Py_None; - Py_INCREF(std); - } - else { - std = create_stdio(iomod, fd, 1, "", encoding, errors); - if (std == NULL) - goto error; - } /* if (fd < 0) */ - 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); - if (!is_valid_fd(fd)) { - std = Py_None; - Py_INCREF(std); - } - else { - std = create_stdio(iomod, fd, 1, "", encoding, "backslashreplace"); - if (std == NULL) - goto error; - } /* if (fd < 0) */ - - /* 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; - std_encoding = _PyUnicode_AsString(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 - - if (0) { - error: - status = -1; - } - - /* 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_Free(pythonioencoding); - Py_XDECREF(bimod); - Py_XDECREF(iomod); - return status; -} /* Parse input from a file and execute it */ @@ -1328,7 +110,7 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags * err = -1; for (;;) { ret = PyRun_InteractiveOneObject(fp, filename, flags); - PRINT_TOTAL_REFS(); + _PY_DEBUG_PRINT_TOTAL_REFS(); if (ret == E_EOF) { err = 0; break; @@ -1450,12 +232,13 @@ PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags) d = PyModule_GetDict(m); v = run_mod(mod, filename, d, d, flags, arena); PyArena_Free(arena); - flush_io(); if (v == NULL) { PyErr_Print(); + flush_io(); return -1; } Py_DECREF(v); + flush_io(); return 0; } @@ -1482,7 +265,7 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename_str, PyCompilerFlags *f static int maybe_pyc_file(FILE *fp, const char* filename, const char* ext, int closeit) { - if (strcmp(ext, ".pyc") == 0 || strcmp(ext, ".pyo") == 0) + if (strcmp(ext, ".pyc") == 0) return 1; /* Only look into the file if we are allowed to close it, since @@ -1521,7 +304,7 @@ set_main_loader(PyObject *d, const char *filename, const char *loader_name) { PyInterpreterState *interp; PyThreadState *tstate; - PyObject *filename_obj, *loader_type, *loader; + PyObject *filename_obj, *bootstrap, *loader_type = NULL, *loader; int result = 0; filename_obj = PyUnicode_DecodeFSDefault(filename); @@ -1530,7 +313,12 @@ set_main_loader(PyObject *d, const char *filename, const char *loader_name) /* Get current thread state and interpreter pointer */ tstate = PyThreadState_GET(); interp = tstate->interp; - loader_type = PyObject_GetAttrString(interp->importlib, loader_name); + bootstrap = PyObject_GetAttrString(interp->importlib, + "_bootstrap_external"); + if (bootstrap != NULL) { + loader_type = PyObject_GetAttrString(bootstrap, loader_name); + Py_DECREF(bootstrap); + } if (loader_type == NULL) { Py_DECREF(filename_obj); return -1; @@ -1588,9 +376,6 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit, fprintf(stderr, "python: Can't reopen .pyc file\n"); goto done; } - /* Turn on optimization if a .pyo file is given */ - if (strcmp(ext, ".pyo") == 0) - Py_OptimizeFlag = 1; if (set_main_loader(d, filename, "SourcelessFileLoader") < 0) { fprintf(stderr, "python: failed to set __main__.__loader__\n"); @@ -1646,7 +431,7 @@ static int parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, int *lineno, int *offset, PyObject **text) { - long hold; + int hold; PyObject *v; _Py_IDENTIFIER(msg); _Py_IDENTIFIER(filename); @@ -1679,11 +464,11 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, v = _PyObject_GetAttrId(err, &PyId_lineno); if (!v) goto finally; - hold = PyLong_AsLong(v); + hold = _PyLong_AsInt(v); Py_DECREF(v); if (hold < 0 && PyErr_Occurred()) goto finally; - *lineno = (int)hold; + *lineno = hold; v = _PyObject_GetAttrId(err, &PyId_offset); if (!v) @@ -1692,11 +477,11 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, *offset = -1; Py_DECREF(v); } else { - hold = PyLong_AsLong(v); + hold = _PyLong_AsInt(v); Py_DECREF(v); if (hold < 0 && PyErr_Occurred()) goto finally; - *offset = (int)hold; + *offset = hold; } v = _PyObject_GetAttrId(err, &PyId_text); @@ -1734,7 +519,7 @@ print_error_text(PyObject *f, int offset, PyObject *text_obj) return; if (offset >= 0) { - if (offset > 0 && offset == strlen(text) && text[offset - 1] == '\n') + if (offset > 0 && (size_t)offset == strlen(text) && text[offset - 1] == '\n') offset--; for (;;) { nl = strchr(text, '\n'); @@ -1792,6 +577,11 @@ handle_system_exit(void) 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 { @@ -1888,9 +678,11 @@ print_exception(PyObject *f, PyObject *value) _Py_IDENTIFIER(print_file_and_line); if (!PyExceptionInstance_Check(value)) { - PyFile_WriteString("TypeError: print_exception(): Exception expected for value, ", f); - PyFile_WriteString(Py_TYPE(value)->tp_name, f); - PyFile_WriteString(" found\n", f); + 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; } @@ -2191,13 +983,17 @@ run_pyc_file(FILE *fp, const char *filename, PyObject *globals, magic = PyMarshal_ReadLongFromFile(fp); if (magic != PyImport_GetMagicNumber()) { - PyErr_SetString(PyExc_RuntimeError, - "Bad magic number in .pyc file"); + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_RuntimeError, + "Bad magic number in .pyc file"); return NULL; } /* Skip mtime and size */ (void) PyMarshal_ReadLongFromFile(fp); (void) PyMarshal_ReadLongFromFile(fp); + if (PyErr_Occurred()) + return NULL; + v = PyMarshal_ReadLastObjectFromFile(fp); if (v == NULL || !PyCode_Check(v)) { Py_XDECREF(v); @@ -2468,6 +1264,7 @@ err_input(perrdetail *err) PyObject *v, *w, *errtype, *errtext; PyObject *msg_obj = NULL; char *msg = NULL; + int offset = err->offset; errtype = PyExc_SyntaxError; switch (err->error) { @@ -2552,11 +1349,20 @@ err_input(perrdetail *err) errtext = Py_None; Py_INCREF(Py_None); } else { - errtext = PyUnicode_DecodeUTF8(err->text, strlen(err->text), + 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, err->offset, errtext); + err->lineno, offset, errtext); if (v != NULL) { if (msg_obj) w = Py_BuildValue("(OO)", msg_obj, v); @@ -2575,192 +1381,6 @@ err_input(perrdetail *err) } } -/* Print fatal error message and abort */ - -void -Py_FatalError(const char *msg) -{ - const int fd = fileno(stderr); - PyThreadState *tstate; - - fprintf(stderr, "Fatal Python error: %s\n", msg); - fflush(stderr); /* it helps in Windows debug build */ - if (PyErr_Occurred()) { - PyErr_PrintEx(0); - } - else { - tstate = _Py_atomic_load_relaxed(&_PyThreadState_Current); - if (tstate != NULL) { - fputc('\n', stderr); - fflush(stderr); - _Py_DumpTracebackThreads(fd, tstate->interp, tstate); - } - _PyFaulthandler_Fini(); - } - -#ifdef MS_WINDOWS - { - size_t len = strlen(msg); - WCHAR* buffer; - size_t i; - - /* 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. */ - buffer = alloca( (len+1) * (sizeof *buffer)); - for( i=0; i<=len; ++i) - buffer[i] = msg[i]; - OutputDebugStringW(L"Fatal Python error: "); - OutputDebugStringW(buffer); - OutputDebugStringW(L"\n"); - } -#ifdef _DEBUG - DebugBreak(); -#endif -#endif /* MS_WINDOWS */ - abort(); -} - -/* Clean up and exit */ - -#ifdef WITH_THREAD -#include "pythread.h" -#endif - -static void (*pyexitfunc)(void) = NULL; -/* For the atexit module. */ -void _Py_PyAtExit(void (*func)(void)) -{ - pyexitfunc = func; -} - -static void -call_py_exitfuncs(void) -{ - if (pyexitfunc == NULL) - return; - - (*pyexitfunc)(); - 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) -{ -#ifdef WITH_THREAD - _Py_IDENTIFIER(_shutdown); - PyObject *result; - PyThreadState *tstate = PyThreadState_GET(); - PyObject *threading = PyMapping_GetItemString(tstate->interp->modules, - "threading"); - if (threading == NULL) { - /* threading not imported */ - PyErr_Clear(); - return; - } - result = _PyObject_CallMethodId(threading, &PyId__shutdown, ""); - if (result == NULL) { - PyErr_WriteUnraisable(threading); - } - else { - Py_DECREF(result); - } - Py_DECREF(threading); -#endif -} - -#define NEXITFUNCS 32 -static void (*exitfuncs[NEXITFUNCS])(void); -static int nexitfuncs = 0; - -int Py_AtExit(void (*func)(void)) -{ - if (nexitfuncs >= NEXITFUNCS) - return -1; - exitfuncs[nexitfuncs++] = func; - return 0; -} - -static void -call_ll_exitfuncs(void) -{ - while (nexitfuncs > 0) - (*exitfuncs[--nexitfuncs])(); - - fflush(stdout); - fflush(stderr); -} - -void -Py_Exit(int sts) -{ - Py_Finalize(); - - exit(sts); -} - -static void -initsigs(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 - PyOS_InitInterrupts(); /* May imply initsignal() */ - if (PyErr_Occurred()) { - Py_FatalError("Py_Initialize: can't import signal"); - } -} - - -/* 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); -} - #if defined(USE_STACKCHECK) #if defined(WIN32) && defined(_MSC_VER) @@ -2799,73 +1419,6 @@ PyOS_CheckStack(void) #endif /* USE_STACKCHECK */ - -/* 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 -} - /* Deprecated C API functions still provided for binary compatiblity */ #undef PyParser_SimpleParseFile diff --git a/Python/pytime.c b/Python/pytime.c index beeab87e2c73..53611b1ec15f 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -3,115 +3,30 @@ #include #endif -#if defined(__APPLE__) && defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME) - /* - * _PyTime_gettimeofday falls back to ftime when getttimeofday fails because the latter - * might fail on some platforms. This fallback is unwanted on MacOSX because - * that makes it impossible to use a binary build on OSX 10.4 on earlier - * releases of the OS. Therefore claim we don't support ftime. - */ -# undef HAVE_FTIME +#if defined(__APPLE__) +#include /* mach_absolute_time(), mach_timebase_info() */ #endif -#if defined(HAVE_FTIME) && !defined(MS_WINDOWS) -#include -extern int ftime(struct timeb *); -#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)) -static void -pygettimeofday(_PyTime_timeval *tp, _Py_clock_info_t *info) -{ -#ifdef MS_WINDOWS - FILETIME system_time; - ULARGE_INTEGER large; - ULONGLONG microseconds; - - GetSystemTimeAsFileTime(&system_time); - large.u.LowPart = system_time.dwLowDateTime; - large.u.HighPart = system_time.dwHighDateTime; - /* 11,644,473,600,000,000: number of microseconds between - the 1st january 1601 and the 1st january 1970 (369 years + 89 leap - days). */ - microseconds = large.QuadPart / 10 - 11644473600000000; - tp->tv_sec = microseconds / 1000000; - tp->tv_usec = microseconds % 1000000; - if (info) { - DWORD timeAdjustment, timeIncrement; - BOOL isTimeAdjustmentDisabled; - - info->implementation = "GetSystemTimeAsFileTime()"; - info->monotonic = 0; - (void) GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement, - &isTimeAdjustmentDisabled); - info->resolution = timeIncrement * 1e-7; - info->adjustable = 1; - } -#else - /* There are three ways to get the time: - (1) gettimeofday() -- resolution in microseconds - (2) ftime() -- resolution in milliseconds - (3) time() -- resolution in seconds - In all cases the return value in a timeval struct. - Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may - fail, so we fall back on ftime() or time(). - Note: clock resolution does not imply clock accuracy! */ - -#ifdef HAVE_GETTIMEOFDAY - int err; -#ifdef GETTIMEOFDAY_NO_TZ - err = gettimeofday(tp); -#else - err = gettimeofday(tp, (struct timezone *)NULL); -#endif - if (err == 0) { - if (info) { - info->implementation = "gettimeofday()"; - info->resolution = 1e-6; - info->monotonic = 0; - info->adjustable = 1; - } - return; - } -#endif /* HAVE_GETTIMEOFDAY */ - -#if defined(HAVE_FTIME) - { - struct timeb t; - ftime(&t); - tp->tv_sec = t.time; - tp->tv_usec = t.millitm * 1000; - if (info) { - info->implementation = "ftime()"; - info->resolution = 1e-3; - info->monotonic = 0; - info->adjustable = 1; - } - } -#else /* !HAVE_FTIME */ - tp->tv_sec = time(NULL); - tp->tv_usec = 0; - if (info) { - info->implementation = "time()"; - info->resolution = 1.0; - info->monotonic = 0; - info->adjustable = 1; - } -#endif /* !HAVE_FTIME */ +/* To millisecond (10^-3) */ +#define SEC_TO_MS 1000 -#endif /* MS_WINDOWS */ -} +/* To microseconds (10^-6) */ +#define MS_TO_US 1000 +#define SEC_TO_US (SEC_TO_MS * MS_TO_US) -void -_PyTime_gettimeofday(_PyTime_timeval *tp) -{ - pygettimeofday(tp, NULL); -} +/* 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) -void -_PyTime_gettimeofday_info(_PyTime_timeval *tp, _Py_clock_info_t *info) -{ - pygettimeofday(tp, info); -} +/* Conversion from nanoseconds */ +#define NS_TO_MS (1000 * 1000) +#define NS_TO_US (1000) static void error_time_t_overflow(void) @@ -150,50 +65,97 @@ _PyLong_FromTime_t(time_t 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 + d = floor(d); + return d; +} + static int -_PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator, - double denominator) +_PyTime_DoubleToDenominator(double d, time_t *sec, long *numerator, + double denominator, _PyTime_round_t round) { - assert(denominator <= LONG_MAX); - if (PyFloat_Check(obj)) { - double d, intpart, err; - /* volatile avoids unsafe optimization on float enabled by gcc -O3 */ - volatile double floatpart; + double intpart, err; + /* volatile avoids optimization changing how numbers are rounded */ + volatile double floatpart; - d = PyFloat_AsDouble(obj); - floatpart = modf(d, &intpart); - if (floatpart < 0) { - floatpart = 1.0 + floatpart; - intpart -= 1.0; - } + floatpart = modf(d, &intpart); - *sec = (time_t)intpart; - err = intpart - (double)*sec; - if (err <= -1.0 || err >= 1.0) { - error_time_t_overflow(); - return -1; - } + 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); - floatpart *= denominator; - *numerator = (long)floatpart; - return 0; + *sec = (time_t)intpart; + *numerator = (long)floatpart; + + err = intpart - (double)*sec; + if (err <= -1.0 || err >= 1.0) { + error_time_t_overflow(); + return -1; + } + return 0; +} + +static int +_PyTime_ObjectToDenominator(PyObject *obj, time_t *sec, long *numerator, + double denominator, _PyTime_round_t round) +{ + assert(denominator <= (double)LONG_MAX); + + if (PyFloat_Check(obj)) { + double d = PyFloat_AsDouble(obj); + 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; - *numerator = 0; return 0; } } int -_PyTime_ObjectToTime_t(PyObject *obj, time_t *sec) +_PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round) { if (PyFloat_Check(obj)) { - double d, intpart, err; + double intpart, err; + /* volatile avoids optimization changing how numbers are rounded */ + volatile double d; d = PyFloat_AsDouble(obj); + d = _PyTime_Round(d, round); (void)modf(d, &intpart); *sec = (time_t)intpart; @@ -213,19 +175,607 @@ _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec) } int -_PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec) +_PyTime_ObjectToTimespec(PyObject *obj, time_t *sec, long *nsec, + _PyTime_round_t round) +{ + int res; + res = _PyTime_ObjectToDenominator(obj, sec, nsec, 1e9, round); + assert(0 <= *nsec && *nsec < SEC_TO_NS); + return res; +} + +int +_PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec, + _PyTime_round_t round) +{ + int res; + res = _PyTime_ObjectToDenominator(obj, sec, usec, 1e6, round); + assert(0 <= *usec && *usec < SEC_TO_US); + return res; +} + +static void +_PyTime_overflow(void) +{ + PyErr_SetString(PyExc_OverflowError, + "timestamp too large to convert to C _PyTime_t"); +} + +_PyTime_t +_PyTime_FromSeconds(int seconds) +{ + _PyTime_t t; + t = (_PyTime_t)seconds; + /* 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). */ + 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(PY_LONG_LONG ns) +{ + _PyTime_t t; + assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t)); + t = Py_SAFE_DOWNCAST(ns, PY_LONG_LONG, _PyTime_t); + return t; +} + +#ifdef HAVE_CLOCK_GETTIME +static int +_PyTime_FromTimespec(_PyTime_t *tp, struct timespec *ts, int raise) +{ + _PyTime_t t; + int res = 0; + + 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 * SEC_TO_NS; + + t += ts->tv_nsec; + + *tp = t; + return res; +} +#elif !defined(MS_WINDOWS) +static int +_PyTime_FromTimeval(_PyTime_t *tp, struct timeval *tv, int raise) +{ + _PyTime_t t; + int res = 0; + + 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 * SEC_TO_NS; + + t += (_PyTime_t)tv->tv_usec * US_TO_NS; + + *tp = t; + return res; +} +#endif + +static int +_PyTime_FromFloatObject(_PyTime_t *t, double value, _PyTime_round_t round, + long unit_to_ns) +{ + double err; + /* 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); + + *t = (_PyTime_t)d; + err = d - (double)*t; + if (fabs(err) >= 1.0) { + _PyTime_overflow(); + return -1; + } + 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); + return _PyTime_FromFloatObject(t, d, round, unit_to_ns); + } + else { +#ifdef HAVE_LONG_LONG + PY_LONG_LONG sec; + assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t)); + + sec = PyLong_AsLongLong(obj); +#else + long sec; + assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t)); + + sec = PyLong_AsLong(obj); +#endif + 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) +{ +#ifdef HAVE_LONG_LONG + assert(sizeof(PY_LONG_LONG) >= sizeof(_PyTime_t)); + return PyLong_FromLongLong((PY_LONG_LONG)t); +#else + assert(sizeof(long) >= sizeof(_PyTime_t)); + return PyLong_FromLong((long)t); +#endif +} + +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 (t >= 0) + return t / 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_ObjectToDenominator(obj, sec, nsec, 1e9); + return _PyTime_AsTimevalStruct_impl(t, tv, round, 1); } int -_PyTime_ObjectToTimeval(PyObject *obj, time_t *sec, long *usec) +_PyTime_AsTimeval_noraise(_PyTime_t t, struct timeval *tv, _PyTime_round_t round) { - return _PyTime_ObjectToDenominator(obj, sec, usec, 1e6); + return _PyTime_AsTimevalStruct_impl(t, tv, round, 0); } -void -_PyTime_Init() +int +_PyTime_AsTimevalTime_t(_PyTime_t t, time_t *p_secs, int *us, + _PyTime_round_t round) { - /* Do nothing. Needed to force linking. */ + _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_new(_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_new(&t, NULL, 0) < 0) { + /* should not happen, _PyTime_Init() checked the clock at startup */ + assert(0); + + /* use a fixed value instead of a random value from the stack */ + t = 0; + } + return t; +} + +int +_PyTime_GetSystemClockWithInfo(_PyTime_t *t, _Py_clock_info_t *info) +{ + return pygettimeofday_new(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(); + 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! */ + assert(0); + } + *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; + uint64_t time; + + 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); + } + + time = mach_absolute_time(); + + /* apply timebase factor */ + time *= timebase.numer; + time /= timebase.denom; + + *tp = time; + + if (info) { + info->implementation = "mach_absolute_time()"; + info->resolution = (double)timebase.numer / timebase.denom * 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 */ + assert(0); + + /* use a fixed value instead of a random value from the stack */ + t = 0; + } + return t; +} + +int +_PyTime_GetMonotonicClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) +{ + return pymonotonic(tp, info, 1); +} + +int +_PyTime_Init(void) +{ + _PyTime_t t; + + /* ensure that the system clock works */ + if (_PyTime_GetSystemClockWithInfo(&t, NULL) < 0) + return -1; + + /* ensure that the operating system provides a monotonic clock */ + if (_PyTime_GetMonotonicClockWithInfo(&t, NULL) < 0) + return -1; + + /* check that _PyTime_FromSeconds() cannot overflow */ + assert(INT_MAX <= _PyTime_MAX / SEC_TO_NS); + assert(INT_MIN >= _PyTime_MIN / SEC_TO_NS); + return 0; } diff --git a/Python/random.c b/Python/random.c index de8e9e72c74c..772bfef0e876 100644 --- a/Python/random.c +++ b/Python/random.c @@ -1,8 +1,16 @@ #include "Python.h" #ifdef MS_WINDOWS -#include +# include #else -#include +# include +# ifdef HAVE_SYS_STAT_H +# include +# endif +# ifdef HAVE_GETRANDOM +# include +# elif defined(HAVE_GETRANDOM_SYSCALL) +# include +# endif #endif #ifdef Py_DEBUG @@ -12,8 +20,6 @@ static int _Py_HashSecret_Initialized = 0; #endif #ifdef MS_WINDOWS -/* This handle is never explicitly released. Instead, the operating - system will release it when the process terminates. */ static HCRYPTPROV hCryptProv = 0; static int @@ -35,7 +41,7 @@ win32_urandom_init(int raise) } /* Fill buffer with size pseudo-random bytes generated by the Windows CryptoGen - API. Return 0 on success, or -1 on error. */ + 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) { @@ -65,32 +71,127 @@ win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise) } return 0; } -#endif /* MS_WINDOWS */ +#elif defined(HAVE_GETENTROPY) && !defined(sun) +#define PY_GETENTROPY 1 -#ifdef __VMS -/* Use openssl random routine */ -#include +/* Fill buffer with size pseudo-random bytes generated by getentropy(). + Return 0 on success, or raise an exception and return -1 on error. + + If fatal is nonzero, call Py_FatalError() instead of raising an exception + on error. */ static int -vms_urandom(unsigned char *buffer, Py_ssize_t size, int raise) +py_getentropy(unsigned char *buffer, Py_ssize_t size, int fatal) { - if (RAND_pseudo_bytes(buffer, size) < 0) { - if (raise) { - PyErr_Format(PyExc_ValueError, - "RAND_pseudo_bytes"); - } else { - Py_FatalError("Failed to initialize the randomized hash " - "secret using RAND_pseudo_bytes"); + while (size > 0) { + Py_ssize_t len = Py_MIN(size, 256); + int res; + + if (!fatal) { + Py_BEGIN_ALLOW_THREADS + res = getentropy(buffer, len); + Py_END_ALLOW_THREADS + + if (res < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return -1; + } } - return -1; + else { + res = getentropy(buffer, len); + if (res < 0) + Py_FatalError("getentropy() failed"); + } + + buffer += len; + size -= len; } return 0; } -#endif /* __VMS */ +#else + +/* Issue #25003: Don' use getentropy() on Solaris (available since + * Solaris 11.3), it is blocking whereas os.urandom() should not block. */ +#if defined(HAVE_GETRANDOM) || defined(HAVE_GETRANDOM_SYSCALL) +#define PY_GETRANDOM 1 + +static int +py_getrandom(void *buffer, Py_ssize_t size, int raise) +{ + /* Is getrandom() supported by the running kernel? + * Need Linux kernel 3.17 or newer, or Solaris 11.3 or newer */ + static int getrandom_works = 1; + /* Use non-blocking /dev/urandom device. On Linux at boot, the getrandom() + * syscall blocks until /dev/urandom is initialized with enough entropy. */ + const int flags = 0; + int n; + + if (!getrandom_works) + return 0; + + while (0 < size) { + errno = 0; + +#ifdef HAVE_GETRANDOM + if (raise) { + Py_BEGIN_ALLOW_THREADS + n = getrandom(buffer, size, flags); + Py_END_ALLOW_THREADS + } + else { + n = getrandom(buffer, size, 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, buffer, size, flags); + Py_END_ALLOW_THREADS + } + else { + n = syscall(SYS_getrandom, buffer, size, flags); + } +#endif + + if (n < 0) { + if (errno == ENOSYS) { + getrandom_works = 0; + return 0; + } + + if (errno == EINTR) { + if (PyErr_CheckSignals()) { + if (!raise) + Py_FatalError("getrandom() interrupted by a signal"); + return -1; + } + /* retry getrandom() */ + continue; + } + + if (raise) + PyErr_SetFromErrno(PyExc_OSError); + else + Py_FatalError("getrandom() failed"); + return -1; + } + + buffer += n; + size -= n; + } + return 1; +} +#endif + +static struct { + int fd; + dev_t st_dev; + ino_t st_ino; +} urandom_cache = { -1 }; -#if !defined(MS_WINDOWS) && !defined(__VMS) -static int urandom_fd = -1; /* Read size bytes from /dev/urandom into buffer. Call Py_FatalError() on error. */ @@ -102,7 +203,14 @@ dev_urandom_noraise(unsigned char *buffer, Py_ssize_t size) assert (0 < size); - fd = _Py_open("/dev/urandom", O_RDONLY); +#ifdef PY_GETRANDOM + if (py_getrandom(buffer, size, 0) == 1) + return; + /* getrandom() is not supported by the running kernel, fall back + * on reading /dev/urandom */ +#endif + + fd = _Py_open_noraise("/dev/urandom", O_RDONLY); if (fd < 0) Py_FatalError("Failed to open /dev/urandom"); @@ -130,72 +238,94 @@ dev_urandom_python(char *buffer, Py_ssize_t size) { int fd; Py_ssize_t n; + struct _Py_stat_struct st; +#ifdef PY_GETRANDOM + int res; +#endif if (size <= 0) return 0; - if (urandom_fd >= 0) - fd = urandom_fd; +#ifdef PY_GETRANDOM + res = py_getrandom(buffer, size, 1); + if (res < 0) + return -1; + if (res == 1) + return 0; + /* getrandom() is not supported by the running kernel, fall back + * on reading /dev/urandom */ +#endif + + if (urandom_cache.fd >= 0) { + /* Does the fd point to the same thing as before? (issue #21207) */ + if (_Py_fstat_noraise(urandom_cache.fd, &st) + || 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 { - Py_BEGIN_ALLOW_THREADS fd = _Py_open("/dev/urandom", O_RDONLY); - Py_END_ALLOW_THREADS - if (fd < 0) - { + if (fd < 0) { if (errno == ENOENT || errno == ENXIO || errno == ENODEV || errno == EACCES) PyErr_SetString(PyExc_NotImplementedError, "/dev/urandom (or equivalent) not found"); - else - PyErr_SetFromErrno(PyExc_OSError); + /* otherwise, keep the OSError exception raised by _Py_open() */ return -1; } - if (urandom_fd >= 0) { + 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_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; + } } - else - urandom_fd = fd; } - Py_BEGIN_ALLOW_THREADS do { - do { - n = read(fd, buffer, (size_t)size); - } while (n < 0 && errno == EINTR); - if (n <= 0) - break; + 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 -= (Py_ssize_t)n; + size -= n; } while (0 < size); - Py_END_ALLOW_THREADS - if (n <= 0) - { - /* stop on error or if read(size) returned 0 */ - if (n < 0) - PyErr_SetFromErrno(PyExc_OSError); - else - PyErr_Format(PyExc_RuntimeError, - "Failed to read %zi bytes from /dev/urandom", - size); - return -1; - } return 0; } static void dev_urandom_close(void) { - if (urandom_fd >= 0) { - close(urandom_fd); - urandom_fd = -1; + if (urandom_cache.fd >= 0) { + close(urandom_cache.fd); + urandom_cache.fd = -1; } } -#endif /* !defined(MS_WINDOWS) && !defined(__VMS) */ +#endif /* Fill buffer with pseudo-random bytes generated by a linear congruent generator (LCG): @@ -219,7 +349,7 @@ lcg_urandom(unsigned int x0, unsigned char *buffer, size_t size) } /* Fill buffer with size pseudo-random bytes from the operating system random - number generator (RNG). It is suitable for for most cryptographic purposes + number generator (RNG). It is suitable for most cryptographic purposes except long living private keys for asymmetric encryption. Return 0 on success, raise an exception and return -1 on error. */ @@ -236,12 +366,10 @@ _PyOS_URandom(void *buffer, Py_ssize_t size) #ifdef MS_WINDOWS return win32_urandom((unsigned char *)buffer, size, 1); +#elif defined(PY_GETENTROPY) + return py_getentropy(buffer, size, 0); #else -# ifdef __VMS - return vms_urandom((unsigned char *)buffer, size, 1); -# else return dev_urandom_python((char*)buffer, size); -# endif #endif } @@ -285,12 +413,10 @@ _PyRandom_Init(void) else { #ifdef MS_WINDOWS (void)win32_urandom(secret, secret_size, 0); -#else /* #ifdef MS_WINDOWS */ -# ifdef __VMS - vms_urandom(secret, secret_size, 0); -# else +#elif defined(PY_GETENTROPY) + (void)py_getentropy(secret, secret_size, 1); +#else dev_urandom_noraise(secret, secret_size); -# endif #endif } } @@ -298,7 +424,14 @@ _PyRandom_Init(void) void _PyRandom_Fini(void) { -#if !defined(MS_WINDOWS) && !defined(__VMS) +#ifdef MS_WINDOWS + if (hCryptProv) { + CryptReleaseContext(hCryptProv, 0); + hCryptProv = 0; + } +#elif defined(PY_GETENTROPY) + /* nothing to clean */ +#else dev_urandom_close(); #endif } diff --git a/Python/symtable.c b/Python/symtable.c index da164aa877d3..8431d514f613 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -47,7 +47,6 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block, ste->ste_directives = NULL; ste->ste_type = block; - ste->ste_unoptimized = 0; ste->ste_nested = 0; ste->ste_free = 0; ste->ste_varargs = 0; @@ -113,7 +112,6 @@ static PyMemberDef ste_memberlist[] = { {"symbols", T_OBJECT, OFF(ste_symbols), READONLY}, {"varnames", T_OBJECT, OFF(ste_varnames), READONLY}, {"children", T_OBJECT, OFF(ste_children), READONLY}, - {"optimized",T_INT, OFF(ste_unoptimized), READONLY}, {"nested", T_INT, OFF(ste_nested), READONLY}, {"type", T_INT, OFF(ste_type), READONLY}, {"lineno", T_INT, OFF(ste_lineno), READONLY}, @@ -182,7 +180,7 @@ 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); +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); @@ -271,7 +269,6 @@ PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future) } st->st_top = st->st_cur; - st->st_cur->ste_unoptimized = OPT_TOPLEVEL; switch (mod->kind) { case Module_kind: seq = mod->v.Module.body; @@ -583,35 +580,6 @@ drop_class_free(PySTEntryObject *ste, PyObject *free) return 1; } -/* Check for illegal statements in unoptimized namespaces */ -static int -check_unoptimized(const PySTEntryObject* ste) { - const char* trailer; - - if (ste->ste_type != FunctionBlock || !ste->ste_unoptimized - || !(ste->ste_free || ste->ste_child_free)) - return 1; - - trailer = (ste->ste_child_free ? - "contains a nested function with free variables" : - "is a nested function"); - - switch (ste->ste_unoptimized) { - case OPT_TOPLEVEL: /* import * at top-level is fine */ - return 1; - case OPT_IMPORT_STAR: - PyErr_Format(PyExc_SyntaxError, - "import * is not allowed in function '%U' because it %s", - ste->ste_name, trailer); - break; - } - - PyErr_SyntaxLocationObject(ste->ste_table->st_filename, - ste->ste_opt_lineno, - ste->ste_opt_col_offset); - return 0; -} - /* Enter the final scope information into the ste_symbols dict. * * All arguments are dicts. Modifies symbols, others are read-only. @@ -854,8 +822,6 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, if (!update_symbols(ste->ste_symbols, scopes, bound, newfree, ste->ste_type == ClassBlock)) goto error; - if (!check_unoptimized(ste)) - goto error; temp = PyNumber_InPlaceOr(free, newfree); if (!temp) @@ -1117,13 +1083,13 @@ symtable_add_def(struct symtable *st, PyObject *name, int flag) } \ } -#define VISIT_KWONLYDEFAULTS(ST, KW_DEFAULTS) { \ +#define VISIT_SEQ_WITH_NULL(ST, TYPE, SEQ) { \ int i = 0; \ - asdl_seq *seq = (KW_DEFAULTS); /* avoid variable capture */ \ + asdl_seq *seq = (SEQ); /* avoid variable capture */ \ for (i = 0; i < asdl_seq_LEN(seq); i++) { \ - expr_ty elt = (expr_ty)asdl_seq_GET(seq, i); \ + TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ if (!elt) continue; /* can be NULL */ \ - if (!symtable_visit_expr((ST), elt)) \ + if (!symtable_visit_ ## TYPE((ST), elt)) \ VISIT_QUIT((ST), 0); \ } \ } @@ -1169,7 +1135,7 @@ static int symtable_visit_stmt(struct symtable *st, stmt_ty s) { if (++st->recursion_depth > st->recursion_limit) { - PyErr_SetString(PyExc_RuntimeError, + PyErr_SetString(PyExc_RecursionError, "maximum recursion depth exceeded during compilation"); VISIT_QUIT(st, 0); } @@ -1180,9 +1146,9 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) if (s->v.FunctionDef.args->defaults) VISIT_SEQ(st, expr, s->v.FunctionDef.args->defaults); if (s->v.FunctionDef.args->kw_defaults) - VISIT_KWONLYDEFAULTS(st, - s->v.FunctionDef.args->kw_defaults); - if (!symtable_visit_annotations(st, s)) + 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); @@ -1201,10 +1167,6 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) VISIT_QUIT(st, 0); VISIT_SEQ(st, expr, s->v.ClassDef.bases); VISIT_SEQ(st, keyword, s->v.ClassDef.keywords); - if (s->v.ClassDef.starargs) - VISIT(st, expr, s->v.ClassDef.starargs); - if (s->v.ClassDef.kwargs) - VISIT(st, expr, s->v.ClassDef.kwargs); 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, @@ -1276,21 +1238,9 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) break; case Import_kind: VISIT_SEQ(st, alias, s->v.Import.names); - /* XXX Don't have the lineno available inside - visit_alias */ - if (st->st_cur->ste_unoptimized && !st->st_cur->ste_opt_lineno) { - st->st_cur->ste_opt_lineno = s->lineno; - st->st_cur->ste_opt_col_offset = s->col_offset; - } break; case ImportFrom_kind: VISIT_SEQ(st, alias, s->v.ImportFrom.names); - /* XXX Don't have the lineno available inside - visit_alias */ - if (st->st_cur->ste_unoptimized && !st->st_cur->ste_opt_lineno) { - st->st_cur->ste_opt_lineno = s->lineno; - st->st_cur->ste_opt_col_offset = s->col_offset; - } break; case Global_kind: { int i; @@ -1366,6 +1316,39 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) 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); + 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); } @@ -1374,7 +1357,7 @@ static int symtable_visit_expr(struct symtable *st, expr_ty e) { if (++st->recursion_depth > st->recursion_limit) { - PyErr_SetString(PyExc_RuntimeError, + PyErr_SetString(PyExc_RecursionError, "maximum recursion depth exceeded during compilation"); VISIT_QUIT(st, 0); } @@ -1395,8 +1378,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e) if (e->v.Lambda.args->defaults) VISIT_SEQ(st, expr, e->v.Lambda.args->defaults); if (e->v.Lambda.args->kw_defaults) - VISIT_KWONLYDEFAULTS(st, - 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)) @@ -1413,7 +1395,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e) VISIT(st, expr, e->v.IfExp.orelse); break; case Dict_kind: - VISIT_SEQ(st, expr, e->v.Dict.keys); + VISIT_SEQ_WITH_NULL(st, expr, e->v.Dict.keys); VISIT_SEQ(st, expr, e->v.Dict.values); break; case Set_kind: @@ -1444,6 +1426,10 @@ symtable_visit_expr(struct symtable *st, expr_ty e) 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_generator = 1; + break; case Compare_kind: VISIT(st, expr, e->v.Compare.left); VISIT_SEQ(st, expr, e->v.Compare.comparators); @@ -1451,11 +1437,15 @@ symtable_visit_expr(struct symtable *st, expr_ty e) case Call_kind: VISIT(st, expr, e->v.Call.func); VISIT_SEQ(st, expr, e->v.Call.args); - VISIT_SEQ(st, keyword, e->v.Call.keywords); - if (e->v.Call.starargs) - VISIT(st, expr, e->v.Call.starargs); - if (e->v.Call.kwargs) - VISIT(st, expr, e->v.Call.kwargs); + 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 Num_kind: case Str_kind: @@ -1548,10 +1538,9 @@ symtable_visit_argannotations(struct symtable *st, asdl_seq *args) } static int -symtable_visit_annotations(struct symtable *st, stmt_ty s) +symtable_visit_annotations(struct symtable *st, stmt_ty s, + arguments_ty a, expr_ty returns) { - arguments_ty a = s->v.FunctionDef.args; - if (a->args && !symtable_visit_argannotations(st, a->args)) return 0; if (a->vararg && a->vararg->annotation) @@ -1560,8 +1549,8 @@ symtable_visit_annotations(struct symtable *st, stmt_ty s) VISIT(st, expr, a->kwarg->annotation); if (a->kwonlyargs && !symtable_visit_argannotations(st, a->kwonlyargs)) return 0; - if (s->v.FunctionDef.returns) - VISIT(st, expr, s->v.FunctionDef.returns); + if (returns) + VISIT(st, expr, returns); return 1; } @@ -1646,7 +1635,6 @@ symtable_visit_alias(struct symtable *st, alias_ty a) Py_DECREF(store_name); return 0; } - st->st_cur->ste_unoptimized |= OPT_IMPORT_STAR; Py_DECREF(store_name); return 1; } diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 4028a01dab77..334f5d0c8e95 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -32,10 +32,6 @@ extern void *PyWin_DLLhModule; extern const char *PyWin_DLLVersionString; #endif -#ifdef __VMS -#include -#endif - #ifdef HAVE_LANGINFO_H #include #include @@ -367,7 +363,7 @@ trace_init(void) static PyObject * -call_trampoline(PyThreadState *tstate, PyObject* callback, +call_trampoline(PyObject* callback, PyFrameObject *frame, int what, PyObject *arg) { PyObject *args; @@ -405,12 +401,11 @@ static int profile_trampoline(PyObject *self, PyFrameObject *frame, int what, PyObject *arg) { - PyThreadState *tstate = frame->f_tstate; PyObject *result; if (arg == NULL) arg = Py_None; - result = call_trampoline(tstate, self, frame, what, arg); + result = call_trampoline(self, frame, what, arg); if (result == NULL) { PyEval_SetProfile(NULL, NULL); return -1; @@ -423,7 +418,6 @@ static int trace_trampoline(PyObject *self, PyFrameObject *frame, int what, PyObject *arg) { - PyThreadState *tstate = frame->f_tstate; PyObject *callback; PyObject *result; @@ -433,11 +427,10 @@ trace_trampoline(PyObject *self, PyFrameObject *frame, callback = frame->f_trace; if (callback == NULL) return 0; - result = call_trampoline(tstate, callback, frame, what, arg); + result = call_trampoline(callback, frame, what, arg); if (result == NULL) { PyEval_SetTrace(NULL, NULL); - Py_XDECREF(frame->f_trace); - frame->f_trace = NULL; + Py_CLEAR(frame->f_trace); return -1; } if (result != Py_None) { @@ -639,19 +632,84 @@ processor's time-stamp counter." static PyObject * sys_setrecursionlimit(PyObject *self, PyObject *args) { - int new_limit; + int new_limit, mark; + PyThreadState *tstate; + if (!PyArg_ParseTuple(args, "i:setrecursionlimit", &new_limit)) return NULL; - if (new_limit <= 0) { + + if (new_limit < 1) { PyErr_SetString(PyExc_ValueError, - "recursion limit must be positive"); + "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_INCREF(Py_None); return Py_None; } +static PyObject * +sys_set_coroutine_wrapper(PyObject *self, PyObject *wrapper) +{ + if (wrapper != Py_None) { + if (!PyCallable_Check(wrapper)) { + PyErr_Format(PyExc_TypeError, + "callable expected, got %.50s", + Py_TYPE(wrapper)->tp_name); + return NULL; + } + _PyEval_SetCoroutineWrapper(wrapper); + } + else { + _PyEval_SetCoroutineWrapper(NULL); + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(set_coroutine_wrapper_doc, +"set_coroutine_wrapper(wrapper)\n\ +\n\ +Set a wrapper for coroutine objects." +); + +static PyObject * +sys_get_coroutine_wrapper(PyObject *self, PyObject *args) +{ + PyObject *wrapper = _PyEval_GetCoroutineWrapper(); + if (wrapper == NULL) { + wrapper = Py_None; + } + Py_INCREF(wrapper); + return wrapper; +} + +PyDoc_STRVAR(get_coroutine_wrapper_doc, +"get_coroutine_wrapper()\n\ +\n\ +Return the wrapper for coroutine objects set by sys.set_coroutine_wrapper." +); + + static PyTypeObject Hash_InfoType; PyDoc_STRVAR(hash_info_doc, @@ -779,6 +837,12 @@ static PyStructSequence_Desc windows_version_desc = { 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) + static PyObject * sys_getwindowsversion(PyObject *self) { @@ -803,9 +867,15 @@ sys_getwindowsversion(PyObject *self) PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wSuiteMask)); PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wProductType)); + if (PyErr_Occurred()) { + Py_DECREF(version); + return NULL; + } return version; } +#pragma warning(pop) + #endif /* MS_WINDOWS */ #ifdef HAVE_DLOPEN @@ -866,29 +936,16 @@ sys_mdebug(PyObject *self, PyObject *args) } #endif /* USE_MALLOPT */ -static PyObject * -sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds) +size_t +_PySys_GetSizeOf(PyObject *o) { PyObject *res = NULL; - static PyObject *gc_head_size = NULL; - static char *kwlist[] = {"object", "default", 0}; - PyObject *o, *dflt = NULL; PyObject *method; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof", - kwlist, &o, &dflt)) - return NULL; - - /* Initialize static variable for GC head size */ - if (gc_head_size == NULL) { - gc_head_size = PyLong_FromSsize_t(sizeof(PyGC_Head)); - if (gc_head_size == NULL) - return NULL; - } + Py_ssize_t size; /* Make sure the type is initialized. float gets initialized late */ if (PyType_Ready(Py_TYPE(o)) < 0) - return NULL; + return (size_t)-1; method = _PyObject_LookupSpecial(o, &PyId___sizeof__); if (method == NULL) { @@ -902,24 +959,50 @@ sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds) Py_DECREF(method); } - /* Has a default value been given */ - if ((res == NULL) && (dflt != NULL) && - PyErr_ExceptionMatches(PyExc_TypeError)) - { - PyErr_Clear(); - Py_INCREF(dflt); - return dflt; + 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; } - else if (res == NULL) - return res; /* add gc_head size */ - if (PyObject_IS_GC(o)) { - PyObject *tmp = res; - res = PyNumber_Add(tmp, gc_head_size); - Py_DECREF(tmp); + 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 res; + + return PyLong_FromSize_t(size); } PyDoc_STRVAR(getsizeof_doc, @@ -1111,6 +1194,16 @@ PyDoc_STRVAR(sys_clear_type_cache__doc__, "_clear_type_cache() -> None\n\ Clear the internal type lookup cache."); +static PyObject * +sys_is_finalizing(PyObject* self, PyObject* args) +{ + return PyBool_FromLong(_Py_Finalizing != NULL); +} + +PyDoc_STRVAR(is_finalizing_doc, +"is_finalizing()\n\ +Return True if Python is exiting."); + static PyMethodDef sys_methods[] = { /* Might as well keep this in alphabetic order */ @@ -1157,6 +1250,7 @@ static PyMethodDef sys_methods[] = { getwindowsversion_doc}, #endif /* MS_WINDOWS */ {"intern", sys_intern, METH_VARARGS, intern_doc}, + {"is_finalizing", sys_is_finalizing, METH_NOARGS, is_finalizing_doc}, #ifdef USE_MALLOPT {"mdebug", sys_mdebug, METH_VARARGS}, #endif @@ -1184,8 +1278,12 @@ static PyMethodDef sys_methods[] = { {"settrace", sys_settrace, METH_O, settrace_doc}, {"gettrace", sys_gettrace, METH_NOARGS, gettrace_doc}, {"call_tracing", sys_call_tracing, METH_VARARGS, call_tracing_doc}, - {"_debugmallocstats", sys_debugmallocstats, METH_VARARGS, + {"_debugmallocstats", sys_debugmallocstats, METH_NOARGS, debugmallocstats_doc}, + {"set_coroutine_wrapper", sys_set_coroutine_wrapper, METH_O, + set_coroutine_wrapper_doc}, + {"get_coroutine_wrapper", sys_get_coroutine_wrapper, METH_NOARGS, + get_coroutine_wrapper_doc}, {NULL, NULL} /* sentinel */ }; @@ -1358,7 +1456,7 @@ hexversion -- version information encoded as a single integer\n\ implementation -- Python implementation information.\n\ int_info -- a struct sequence with information about the int implementation.\n\ maxsize -- the largest supported length of containers.\n\ -maxunicode -- the value of the largest Unicode codepoint\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 struct sequence with information about the thread implementation.\n\ @@ -1467,6 +1565,7 @@ make_flags(void) #undef SetFlag if (PyErr_Occurred()) { + Py_DECREF(seq); return NULL; } return seq; @@ -1548,7 +1647,7 @@ const char *_PySys_ImplName = NAME; #define STRIFY(name) QUOTE(name) #define MAJOR STRIFY(PY_MAJOR_VERSION) #define MINOR STRIFY(PY_MINOR_VERSION) -#define TAG NAME "-" MAJOR MINOR; +#define TAG NAME "-" MAJOR MINOR const char *_PySys_ImplCacheTag = TAG; #undef NAME #undef QUOTE @@ -1624,6 +1723,7 @@ PyObject * _PySys_Init(void) { PyObject *m, *sysdict, *version_info; + int res; m = PyModule_Create(&sysmodule); if (m == NULL) @@ -1631,7 +1731,6 @@ _PySys_Init(void) sysdict = PyModule_GetDict(m); #define SET_SYS_FROM_STRING_BORROW(key, value) \ do { \ - int res; \ PyObject *v = (value); \ if (v == NULL) \ return NULL; \ @@ -1642,7 +1741,6 @@ _PySys_Init(void) } while (0) #define SET_SYS_FROM_STRING(key, value) \ do { \ - int res; \ PyObject *v = (value); \ if (v == NULL) \ return NULL; \ @@ -1660,8 +1758,8 @@ _PySys_Init(void) the shell already prevents that. */ #if !defined(MS_WINDOWS) { - struct stat sb; - if (fstat(fileno(stdin), &sb) == 0 && + struct _Py_stat_struct sb; + if (_Py_fstat_noraise(fileno(stdin), &sb) == 0 && S_ISDIR(sb.st_mode)) { /* There's nothing more we can do. */ /* Py_FatalError() will core dump, so just exit. */ @@ -1671,7 +1769,7 @@ _PySys_Init(void) } #endif - /* stdin/stdout/stderr are now set by pythonrun.c */ + /* stdin/stdout/stderr are set in pylifecycle.c */ SET_SYS_FROM_STRING_BORROW("__displayhook__", PyDict_GetItemString(sysdict, "displayhook")); @@ -1761,6 +1859,9 @@ _PySys_Init(void) /* 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)); @@ -1774,7 +1875,9 @@ _PySys_Init(void) /* prevent user from creating new instances */ FlagsType.tp_init = NULL; FlagsType.tp_new = NULL; - + res = PyDict_DelItemString(FlagsType.tp_dict, "__new__"); + if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) + PyErr_Clear(); #if defined(MS_WINDOWS) /* getwindowsversion */ @@ -1785,6 +1888,9 @@ _PySys_Init(void) /* prevent user from creating new instances */ WindowsVersionType.tp_init = NULL; WindowsVersionType.tp_new = NULL; + 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) */ @@ -1801,6 +1907,7 @@ _PySys_Init(void) #endif #undef SET_SYS_FROM_STRING +#undef SET_SYS_FROM_STRING_BORROW if (PyErr_Occurred()) return NULL; return m; @@ -1864,22 +1971,7 @@ makeargvobject(int argc, wchar_t **argv) if (av != NULL) { int i; for (i = 0; i < argc; i++) { -#ifdef __VMS - PyObject *v; - - /* argv[0] is the script pathname if known */ - if (i == 0) { - char* fn = decc$translate_vms(argv[0]); - if ((fn == (char *)0) || fn == (char *)-1) - v = PyUnicode_FromString(argv[0]); - else - v = PyUnicode_FromString( - decc$translate_vms(argv[0])); - } else - v = PyUnicode_FromString(argv[i]); -#else PyObject *v = PyUnicode_FromWideChar(argv[i], -1); -#endif if (v == NULL) { Py_DECREF(av); av = NULL; diff --git a/Python/thread.c b/Python/thread.c index 8540942e28a1..44c071eafe6a 100644 --- a/Python/thread.c +++ b/Python/thread.c @@ -205,7 +205,7 @@ static int nkeys = 0; /* PyThread_create_key() hands out nkeys+1 next */ * segfaults. Now we lock the whole routine. */ static struct key * -find_key(int key, void *value) +find_key(int set_value, int key, void *value) { struct key *p, *prev_p; long id = PyThread_get_thread_ident(); @@ -215,10 +215,13 @@ find_key(int key, void *value) PyThread_acquire_lock(keymutex, 1); prev_p = NULL; for (p = keyhead; p != NULL; p = p->next) { - if (p->id == id && p->key == key) + if (p->id == id && p->key == key) { + if (set_value) + p->value = value; goto Done; + } /* Sanity check. These states should never happen but if - * they do we must abort. Otherwise we'll end up spinning in + * they do we must abort. Otherwise we'll end up spinning * in a tight loop with the lock held. A similar check is done * in pystate.c tstate_delete_common(). */ if (p == prev_p) @@ -227,7 +230,7 @@ find_key(int key, void *value) if (p->next == keyhead) Py_FatalError("tls find_key: circular list(!)"); } - if (value == NULL) { + if (!set_value && value == NULL) { assert(p == NULL); goto Done; } @@ -279,19 +282,12 @@ PyThread_delete_key(int key) PyThread_release_lock(keymutex); } -/* Confusing: If the current thread has an association for key, - * value is ignored, and 0 is returned. Else an attempt is made to create - * an association of key to value for the current thread. 0 is returned - * if that succeeds, but -1 is returned if there's not enough memory - * to create the association. value must not be NULL. - */ int PyThread_set_key_value(int key, void *value) { struct key *p; - assert(value != NULL); - p = find_key(key, value); + p = find_key(1, key, value); if (p == NULL) return -1; else @@ -304,7 +300,7 @@ PyThread_set_key_value(int key, void *value) void * PyThread_get_key_value(int key) { - struct key *p = find_key(key, NULL); + struct key *p = find_key(0, key, NULL); if (p == NULL) return NULL; @@ -435,7 +431,7 @@ PyThread_GetInfo(void) && defined(_CS_GNU_LIBPTHREAD_VERSION)) value = NULL; len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer)); - if (1 < len && len < sizeof(buffer)) { + if (1 < len && (size_t)len < sizeof(buffer)) { value = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1); if (value == NULL) PyErr_Clear(); diff --git a/Python/thread_foobar.h b/Python/thread_foobar.h index d2b78c5caed0..ea96f9c9d79f 100644 --- a/Python/thread_foobar.h +++ b/Python/thread_foobar.h @@ -1,4 +1,3 @@ - /* * Initialization. */ @@ -60,11 +59,19 @@ PyThread_free_lock(PyThread_type_lock lock) int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag) +{ + return PyThread_acquire_lock_timed(lock, waitflag ? -1 : 0, 0); +} + +PyLockStatus +PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, + int intr_flag) { int success; - dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag)); - dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success)); + dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n", lock, microseconds, intr_flag)); + dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n", + lock, microseconds, intr_flag, success)); return success; } @@ -73,3 +80,53 @@ PyThread_release_lock(PyThread_type_lock lock) { dprintf(("PyThread_release_lock(%p) called\n", lock)); } + +/* The following are only needed if native TLS support exists */ +#define Py_HAVE_NATIVE_TLS + +#ifdef Py_HAVE_NATIVE_TLS +int +PyThread_create_key(void) +{ + int result; + return result; +} + +void +PyThread_delete_key(int key) +{ + +} + +int +PyThread_set_key_value(int key, void *value) +{ + int ok; + + /* A failure in this case returns -1 */ + if (!ok) + return -1; + return 0; +} + +void * +PyThread_get_key_value(int key) +{ + void *result; + + return result; +} + +void +PyThread_delete_key_value(int key) +{ + +} + +void +PyThread_ReInitTLS(void) +{ + +} + +#endif diff --git a/Python/thread_nt.h b/Python/thread_nt.h index ab5a08168f7d..84452cdac4ec 100644 --- a/Python/thread_nt.h +++ b/Python/thread_nt.h @@ -77,7 +77,7 @@ EnterNonRecursiveMutex(PNRMUTEX mutex, DWORD milliseconds) /* wait at least until the target */ DWORD now, target = GetTickCount() + milliseconds; while (mutex->locked) { - if (PyCOND_TIMEDWAIT(&mutex->cv, &mutex->cs, milliseconds*1000) < 0) { + if (PyCOND_TIMEDWAIT(&mutex->cv, &mutex->cs, (PY_LONG_LONG)milliseconds*1000) < 0) { result = WAIT_FAILED; break; } @@ -389,20 +389,11 @@ PyThread_delete_key(int key) TlsFree(key); } -/* We must be careful to emulate the strange semantics implemented in thread.c, - * where the value is only set if it hasn't been set before. - */ int PyThread_set_key_value(int key, void *value) { BOOL ok; - void *oldvalue; - assert(value != NULL); - oldvalue = TlsGetValue(key); - if (oldvalue != NULL) - /* ignore value if already set */ - return 0; ok = TlsSetValue(key, value); if (!ok) return -1; diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index 20f85358968b..27e0dc84bcb5 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -608,7 +608,15 @@ PyThread_create_key(void) { pthread_key_t key; int fail = pthread_key_create(&key, NULL); - return fail ? -1 : key; + if (fail) + return -1; + if (key > INT_MAX) { + /* Issue #22206: handle integer overflow */ + pthread_key_delete(key); + errno = ENOMEM; + return -1; + } + return (int)key; } void @@ -627,9 +635,6 @@ int PyThread_set_key_value(int key, void *value) { int fail; - void *oldValue = pthread_getspecific(key); - if (oldValue != NULL) - return 0; fail = pthread_setspecific(key, value); return fail ? -1 : 0; } diff --git a/Python/traceback.c b/Python/traceback.c index e9169ce5e060..941d1cbbbb4a 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -13,7 +13,7 @@ #define OFF(x) offsetof(PyTracebackObject, x) -#define PUTS(fd, str) write(fd, str, (int)strlen(str)) +#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 @@ -142,6 +142,39 @@ PyTraceBack_Here(PyFrameObject *frame) 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 = NULL; + PyCodeObject *code = NULL; + PyFrameObject *frame = NULL; + PyObject *exception, *value, *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(&exception, &value, &tb); + + globals = PyDict_New(); + if (!globals) + goto done; + code = PyCode_NewEmpty(filename, funcname, lineno); + if (!code) + goto done; + frame = PyFrame_New(PyThreadState_Get(), code, globals, NULL); + if (!frame) + goto done; + frame->f_lineno = lineno; + + PyErr_Restore(exception, value, tb); + PyTraceBack_Here(frame); + +done: + Py_XDECREF(globals); + Py_XDECREF(code); + Py_XDECREF(frame); +} + static PyObject * _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *io) { @@ -198,7 +231,7 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject * } strcpy(namebuf, PyBytes_AS_STRING(path)); Py_DECREF(path); - if (strlen(namebuf) != len) + if (strlen(namebuf) != (size_t)len) continue; /* v contains '\0' */ if (len > 0 && namebuf[len-1] != SEP) namebuf[len++] = SEP; @@ -264,6 +297,8 @@ _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent) 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) { @@ -274,19 +309,27 @@ _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent) } fob = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "Os", binary, encoding); Py_DECREF(io); - Py_DECREF(binary); PyMem_FREE(found_encoding); if (fob == NULL) { PyErr_Clear(); + + res = _PyObject_CallMethodId(binary, &PyId_close, ""); + 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; } @@ -469,7 +512,7 @@ dump_decimal(int fd, int value) len++; } while (value); reverse_string(buffer, len); - write(fd, buffer, len); + _Py_write_noraise(fd, buffer, len); } /* Format an integer in range [0; 0xffffffff] to hexadecimal of 'width' digits, @@ -489,7 +532,7 @@ dump_hexadecimal(int fd, unsigned long value, int width) len++; } while (len < width || value); reverse_string(buffer, len); - write(fd, buffer, len); + _Py_write_noraise(fd, buffer, len); } /* Write an unicode object into the file fd using ascii+backslashreplace. @@ -539,15 +582,16 @@ dump_ascii(int fd, PyObject *text) ch = PyUnicode_READ(kind, data, i); else ch = wstr[i]; - if (ch < 128) { + if (' ' <= ch && ch <= 126) { + /* printable ASCII character */ char c = (char)ch; - write(fd, &c, 1); + _Py_write_noraise(fd, &c, 1); } - else if (ch < 0xff) { + else if (ch <= 0xff) { PUTS(fd, "\\x"); dump_hexadecimal(fd, ch, 2); } - else if (ch < 0xffff) { + else if (ch <= 0xffff) { PUTS(fd, "\\u"); dump_hexadecimal(fd, ch, 4); } @@ -575,9 +619,9 @@ dump_frame(int fd, PyFrameObject *frame) if (code != NULL && code->co_filename != NULL && PyUnicode_Check(code->co_filename)) { - write(fd, "\"", 1); + PUTS(fd, "\""); dump_ascii(fd, code->co_filename); - write(fd, "\"", 1); + PUTS(fd, "\""); } else { PUTS(fd, "???"); } @@ -594,7 +638,7 @@ dump_frame(int fd, PyFrameObject *frame) else PUTS(fd, "???"); - write(fd, "\n", 1); + PUTS(fd, "\n"); } static void @@ -624,6 +668,12 @@ dump_traceback(int fd, PyThreadState *tstate, int write_header) } } +/* 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) { @@ -642,10 +692,16 @@ write_thread_id(int fd, PyThreadState *tstate, int is_current) PUTS(fd, "Current thread 0x"); else PUTS(fd, "Thread 0x"); - dump_hexadecimal(fd, (unsigned long)tstate->thread_id, sizeof(long)*2); + dump_hexadecimal(fd, (unsigned long)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_thread) @@ -661,10 +717,11 @@ _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp, /* Dump the traceback of each thread */ tstate = PyInterpreterState_ThreadHead(interp); nthreads = 0; + _Py_BEGIN_SUPPRESS_IPH do { if (nthreads != 0) - write(fd, "\n", 1); + PUTS(fd, "\n"); if (nthreads >= MAX_NTHREADS) { PUTS(fd, "...\n"); break; @@ -674,6 +731,7 @@ _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp, tstate = PyThreadState_Next(tstate); nthreads++; } while (tstate != NULL); + _Py_END_SUPPRESS_IPH return NULL; } diff --git a/README b/README index 6a78046d9fa4..d682a2bdd310 100644 --- a/README +++ b/README @@ -1,13 +1,14 @@ -This is Python version 3.4.0 beta 1 -=================================== +This is Python version 3.6.0 alpha 1 +==================================== Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -2012, 2013 Python Software Foundation. All rights reserved. +2012, 2013, 2014, 2015 Python Software Foundation. All rights reserved. -Python 3.x is a new version of the language, which is incompatible with the 2.x -line of releases. The language is mostly the same, but many details, especially -how built-in objects like dictionaries and strings work, have changed -considerably, and a lot of deprecated features have finally been removed. +Python 3.x is a new version of the language, which is incompatible with the +2.x line of releases. The language is mostly the same, but many details, +especially how built-in objects like dictionaries and strings work, +have changed considerably, and a lot of deprecated features have finally +been removed. Build Instructions @@ -15,8 +16,6 @@ Build Instructions On Unix, Linux, BSD, OSX, and Cygwin: -New text - ./configure make make test @@ -35,8 +34,8 @@ set up a symlink in /usr/local/bin. On Windows, see PCbuild/readme.txt. -If you wish, you can create a subdirectory and invoke configure from there. For -example: +If you wish, you can create a subdirectory and invoke configure from there. +For example: mkdir debug cd debug @@ -44,21 +43,49 @@ example: make make test -(This will fail if you *also* built at the top-level directory. You should do a -"make clean" at the toplevel first.) +(This will fail if you *also* built at the top-level directory. +You should do a "make clean" at the toplevel first.) + +If you need an optimized version of Python, you type "make profile-opt" in the +top level directory. This will rebuild the interpreter executable using Profile +Guided Optimization (PGO). For more details, see the section bellow. + + +Profile Guided Optimization +--------------------------- + +PGO takes advantage of recent versions of the GCC or Clang compilers. +If ran, the "profile-opt" rule will do several steps. + +First, the entire Python directory is cleaned of temporary files that +may resulted in a previous compilation. + +Then, an instrumented version of the interpreter is built, using suitable +compiler flags for each flavour. Note that this is just an intermediary +step and the binary resulted after this step is not good for real life +workloads, as it has profiling instructions embedded inside. + +After this instrumented version of the interpreter is built, the Makefile +will automatically run a training workload. This is necessary in order to +profile the interpreter execution. Note also that any output, both stdout +and stderr, that may appear at this step is supressed. + +Finally, the last step is to rebuild the interpreter, using the information +collected in the previous one. The end result will be a the Python binary +that is optimized and suitable for distribution or production installation. What's New ---------- -We try to have a comprehensive overview of the changes in the "What's New in -Python 3.4" document, found at +We have a comprehensive overview of the changes in the "What's New in +Python 3.6" document, found at - http://docs.python.org/3.4/whatsnew/3.4.html + http://docs.python.org/3.6/whatsnew/3.6.html -For a more detailed change log, read Misc/NEWS (though this file, too, is -incomplete, and also doesn't list anything merged in from the 2.7 release under -development). +For a more detailed change log, read Misc/NEWS (though this file, too, +is incomplete, and also doesn't list anything merged in from the 2.7 +release under development). If you want to install multiple versions of Python see the section below entitled "Installing multiple versions". @@ -67,9 +94,9 @@ entitled "Installing multiple versions". Documentation ------------- -Documentation for Python 3.4 is online, updated daily: +Documentation for Python 3.6 is online, updated daily: - http://docs.python.org/3.4/ + http://docs.python.org/3.6/ It can also be downloaded in many formats for faster access. The documentation is downloadable in HTML, PDF, and reStructuredText formats; the latter version @@ -94,16 +121,17 @@ backported versions of certain key Python 3.x features. A source-to-source translation tool, "2to3", can take care of the mundane task of converting large amounts of source code. It is not a complete solution but is complemented by the deprecation warnings in 2.6. See -http://docs.python.org/3.4/library/2to3.html for more information. +http://docs.python.org/3.6/library/2to3.html for more information. Testing ------- -To test the interpreter, type "make test" in the top-level directory. The test -set produces some output. You can generally ignore the messages about skipped -tests due to optional features which can't be imported. If a message is printed -about a failed test or a traceback or core dump is produced, something is wrong. +To test the interpreter, type "make test" in the top-level directory. +The test set produces some output. You can generally ignore the messages +about skipped tests due to optional features which can't be imported. +If a message is printed about a failed test or a traceback or core dump +is produced, something is wrong. By default, tests are prevented from overusing resources like disk space and memory. To enable these tests, run "make testall". @@ -132,7 +160,7 @@ same prefix you must decide which version (if any) is your "primary" version. Install that version using "make install". Install all other versions using "make altinstall". -For example, if you want to install Python 2.6, 2.7 and 3.4 with 2.7 being the +For example, if you want to install Python 2.6, 2.7 and 3.6 with 2.7 being the primary version, you would execute "make install" in your 2.7 build directory and "make altinstall" in the others. @@ -141,7 +169,7 @@ Issue Tracker and Mailing List ------------------------------ We're soliciting bug reports about all aspects of the language. Fixes are also -welcome, preferable in unified diff format. Please use the issue tracker: +welcome, preferably in unified diff format. Please use the issue tracker: http://bugs.python.org/ @@ -168,14 +196,14 @@ http://www.python.org/dev/peps/. Release Schedule ---------------- -See PEP 429 for release details: http://www.python.org/dev/peps/pep-0429/ +See PEP 494 for release details: http://www.python.org/dev/peps/pep-0494/ Copyright and License Information --------------------------------- Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -2012, 2013 Python Software Foundation. All rights reserved. +2012, 2013, 2014, 2015 Python Software Foundation. All rights reserved. Copyright (c) 2000 BeOpen.com. All rights reserved. @@ -184,11 +212,11 @@ rights reserved. Copyright (c) 1991-1995 Stichting Mathematisch Centrum. All rights reserved. -See the file "LICENSE" for information on the history of this software, terms & -conditions for usage, and a DISCLAIMER OF ALL WARRANTIES. +See the file "LICENSE" for information on the history of this software, +terms & conditions for usage, and a DISCLAIMER OF ALL WARRANTIES. -This Python distribution contains *no* GNU General Public License (GPL) code, so -it may be used in proprietary projects. There are interfaces to some GNU code -but these are entirely optional. +This Python distribution contains *no* GNU General Public License (GPL) code, +so it may be used in proprietary projects. There are interfaces to some GNU +code but these are entirely optional. All trademarks referenced herein are property of their respective holders. diff --git a/Tools/buildbot/README.tcltk-AMD64 b/Tools/buildbot/README.tcltk-AMD64 deleted file mode 100644 index edc89eba9e66..000000000000 --- a/Tools/buildbot/README.tcltk-AMD64 +++ /dev/null @@ -1,36 +0,0 @@ -Comments on building tcl/tk for AMD64 with the MS SDK compiler -============================================================== - -I did have to build tcl/tk manually. - -First, I had to build the nmakehlp.exe helper utility manually by executing - cl nmakehlp.c /link bufferoverflowU.lib -in both the tcl8.4.12\win and tk8.4.12\win directories. - -Second, the AMD64 compiler refuses to compile the file -tcl8.4.12\generic\tclExecute.c because it insists on using intrinsics -for the 'ceil' and 'floor' functions: - - ..\generic\tclExecute.c(394) : error C2099: initializer is not a constant - ..\generic\tclExecute.c(398) : error C2099: initializer is not a constant - -I did comment out these lines; an alternative would have been to use -the /Oi- compiler flag to disable the intrinsic functions. -The commands then used were these: - - svn export http://svn.python.org/projects/external/tcl8.4.12 - cd tcl8.4.12\win - REM - echo patch the tcl8.4.12\generic\tclExecute.c file - pause - REM - cl nmakehlp.c /link bufferoverflowU.lib - nmake -f makefile.vc MACHINE=AMD64 - nmake -f makefile.vc INSTALLDIR=..\..\tcltk install - cd ..\.. - svn export http://svn.python.org/projects/external/tk8.4.12 - cd tk8.4.12\win - cl nmakehlp.c /link bufferoverflowU.lib - nmake -f makefile.vc TCLDIR=..\..\tcl8.4.12 MACHINE=AMD64 - nmake -f makefile.vc TCLDIR=..\..\tcl8.4.12 INSTALLDIR=..\..\tcltk install - cd ..\.. diff --git a/Tools/buildbot/build-amd64.bat b/Tools/buildbot/build-amd64.bat index 493e74de5a3e..f77407bcf703 100644 --- a/Tools/buildbot/build-amd64.bat +++ b/Tools/buildbot/build-amd64.bat @@ -1,6 +1,5 @@ -@rem Used by the buildbot "compile" step. -cmd /c Tools\buildbot\external-amd64.bat -call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64 -cmd /c Tools\buildbot\clean-amd64.bat - -msbuild PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=x64 +@rem Formerly used by the buildbot "compile" step. +@echo This script is no longer used and may be removed in the future. +@echo To get the same effect as this script, use +@echo PCbuild\build.bat -d -e -k -p x64 +call "%~dp0build.bat" -p x64 %* diff --git a/Tools/buildbot/build.bat b/Tools/buildbot/build.bat index be79b10726d7..5e840cc7eaca 100644 --- a/Tools/buildbot/build.bat +++ b/Tools/buildbot/build.bat @@ -1,7 +1,17 @@ -@rem Used by the buildbot "compile" step. -cmd /c Tools\buildbot\external.bat -call "%VS100COMNTOOLS%vsvars32.bat" -cmd /c Tools\buildbot\clean.bat - -msbuild PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=Win32 - +@rem Used by the buildbot "compile" step. + +@rem Clean up +call "%~dp0clean.bat" %* + +@rem If you need the buildbots to start fresh (such as when upgrading to +@rem a new version of an external library, especially Tcl/Tk): +@rem 1) uncomment the following line: + +@rem call "%~dp0..\..\PCbuild\get_externals.bat" --clean-only + +@rem 2) commit and push +@rem 3) wait for all Windows bots to start a build with that changeset +@rem 4) re-comment, commit and push again + +@rem Do the build +call "%~dp0..\..\PCbuild\build.bat" -e -d -k -v %* diff --git a/Tools/buildbot/buildmsi.bat b/Tools/buildbot/buildmsi.bat index ae93e6729565..e3c2dbd73d00 100644 --- a/Tools/buildbot/buildmsi.bat +++ b/Tools/buildbot/buildmsi.bat @@ -1,21 +1,9 @@ -@rem Used by the buildbot "buildmsi" step. - -cmd /c Tools\buildbot\external.bat -@rem build release versions of things -call "%VS100COMNTOOLS%vsvars32.bat" - -@rem build Python -msbuild /p:useenv=true PCbuild\pcbuild.sln /p:Configuration=Release /p:Platform=Win32 - -@rem build the documentation -bash.exe -c 'cd Doc;make PYTHON=python2.5 update htmlhelp' -"%ProgramFiles%\HTML Help Workshop\hhc.exe" Doc\build\htmlhelp\python26a3.hhp - -@rem build the MSI file -cd PC -nmake /f icons.mak -cd ..\Tools\msi -del *.msi -nmake /f msisupport.mak -%HOST_PYTHON% msi.py - +@rem Used by the buildbot "buildmsi" step. +setlocal + +pushd + +@rem build both snapshot MSIs +call "%~dp0..\msi\build.bat" -x86 -x64 + +popd \ No newline at end of file diff --git a/Tools/buildbot/clean-amd64.bat b/Tools/buildbot/clean-amd64.bat index 24660af012a2..b53c7c1038d3 100644 --- a/Tools/buildbot/clean-amd64.bat +++ b/Tools/buildbot/clean-amd64.bat @@ -1,10 +1,5 @@ -@rem Used by the buildbot "clean" step. -call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64 -@echo Deleting .pyc/.pyo files ... -del /s Lib\*.pyc Lib\*.pyo -@echo Deleting test leftovers ... -rmdir /s /q build -cd PCbuild -msbuild /target:clean pcbuild.sln /p:Configuration=Release /p:PlatformTarget=x64 -msbuild /target:clean pcbuild.sln /p:Configuration=Debug /p:PlatformTarget=x64 -cd .. +@rem Formerly used by the buildbot "clean" step. +@echo This script is no longer used and may be removed in the future. +@echo To get the same effect as this script, use `clean.bat` from this +@echo directory and pass `-p x64` as two arguments. +call "%~dp0clean.bat" -p x64 %* diff --git a/Tools/buildbot/clean.bat b/Tools/buildbot/clean.bat index 218facc3b179..0fc68fd72719 100644 --- a/Tools/buildbot/clean.bat +++ b/Tools/buildbot/clean.bat @@ -1,8 +1,16 @@ -@rem Used by the buildbot "clean" step. -call "%VS100COMNTOOLS%vsvars32.bat" -@echo Deleting test leftovers ... -rmdir /s /q build -cd PCbuild -msbuild /target:clean pcbuild.sln /p:Configuration=Release /p:PlatformTarget=x86 -msbuild /target:clean pcbuild.sln /p:Configuration=Debug /p:PlatformTarget=x86 -cd .. +@echo off +rem Used by the buildbot "clean" step. + +setlocal +set root=%~dp0..\.. +set pcbuild=%root%\PCbuild + +echo Deleting build +call "%pcbuild%\build.bat" -t Clean -k %* +call "%pcbuild%\build.bat" -t Clean -k -d %* + +echo Deleting .pyc/.pyo files ... +del /s "%root%\Lib\*.pyc" "%root%\Lib\*.pyo" + +echo Deleting test leftovers ... +rmdir /s /q "%root%\build" diff --git a/Tools/buildbot/external-amd64.bat b/Tools/buildbot/external-amd64.bat index 4c3b67b55f32..bfaef055f54b 100644 --- a/Tools/buildbot/external-amd64.bat +++ b/Tools/buildbot/external-amd64.bat @@ -1,21 +1,3 @@ -@rem Fetches (and builds if necessary) external dependencies - -@rem Assume we start inside the Python source directory -call "Tools\buildbot\external-common.bat" -call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64 - -if not exist tcltk64\bin\tcl86tg.dll ( - cd tcl-8.6.1.0\win - nmake -f makefile.vc DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 clean all - nmake -f makefile.vc DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 install - cd ..\.. -) - -if not exist tcltk64\bin\tk86tg.dll ( - cd tk-8.6.1.0\win - nmake -f makefile.vc OPTS=noxp DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 TCLDIR=..\..\tcl-8.6.1.0 clean - nmake -f makefile.vc OPTS=noxp DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 TCLDIR=..\..\tcl-8.6.1.0 all - nmake -f makefile.vc OPTS=noxp DEBUG=1 MACHINE=AMD64 INSTALLDIR=..\..\tcltk64 TCLDIR=..\..\tcl-8.6.1.0 install - cd ..\.. -) - +@echo This script is no longer used and may be removed in the future. +@echo Please use PCbuild\get_externals.bat instead. +@"%~dp0..\..\PCbuild\get_externals.bat" %* diff --git a/Tools/buildbot/external-common.bat b/Tools/buildbot/external-common.bat deleted file mode 100644 index 244abd2d932d..000000000000 --- a/Tools/buildbot/external-common.bat +++ /dev/null @@ -1,49 +0,0 @@ -@rem Common file shared between external.bat and external-amd64.bat. Responsible for -@rem fetching external components into the root\.. buildbot directories. - -cd .. -@rem XXX: If you need to force the buildbots to start from a fresh environment, uncomment -@rem the following, check it in, then check it out, comment it out, then check it back in. -@rem if exist bzip2-1.0.6 rd /s/q bzip2-1.0.6 -@rem if exist tcltk rd /s/q tcltk -@rem if exist tcltk64 rd /s/q tcltk64 -@rem if exist tcl8.4.12 rd /s/q tcl8.4.12 -@rem if exist tcl8.4.16 rd /s/q tcl8.4.16 -@rem if exist tcl-8.4.18.1 rd /s/q tcl-8.4.18.1 -@rem if exist tk8.4.12 rd /s/q tk8.4.12 -@rem if exist tk8.4.16 rd /s/q tk8.4.16 -@rem if exist tk-8.4.18.1 rd /s/q tk-8.4.18.1 -@rem if exist db-4.4.20 rd /s/q db-4.4.20 -@rem if exist openssl-1.0.1e rd /s/q openssl-1.0.1e -@rem if exist sqlite-3.7.12 rd /s/q sqlite-3.7.12 - -@rem bzip -if not exist bzip2-1.0.6 ( - rd /s/q bzip2-1.0.5 - svn export http://svn.python.org/projects/external/bzip2-1.0.6 -) - -@rem OpenSSL -if not exist openssl-1.0.1e ( - rd /s/q openssl-1.0.1d - svn export http://svn.python.org/projects/external/openssl-1.0.1e -) - -@rem tcl/tk -if not exist tcl-8.6.1.0 ( - rd /s/q tcltk tcltk64 tcl-8.5.11.0 tk-8.5.11.0 - svn export http://svn.python.org/projects/external/tcl-8.6.1.0 -) -if not exist tk-8.6.1.0 svn export http://svn.python.org/projects/external/tk-8.6.1.0 - -@rem sqlite3 -if not exist sqlite-3.8.1 ( - rd /s/q sqlite-source-3.7.12 - svn export http://svn.python.org/projects/external/sqlite-3.8.1 -) - -@rem lzma -if not exist xz-5.0.5 ( - rd /s/q xz-5.0.3 - svn export http://svn.python.org/projects/external/xz-5.0.5 -) diff --git a/Tools/buildbot/external.bat b/Tools/buildbot/external.bat index c580a149705f..bfaef055f54b 100644 --- a/Tools/buildbot/external.bat +++ b/Tools/buildbot/external.bat @@ -1,21 +1,3 @@ -@rem Fetches (and builds if necessary) external dependencies - -@rem Assume we start inside the Python source directory -call "Tools\buildbot\external-common.bat" -call "%VS100COMNTOOLS%\vsvars32.bat" - -if not exist tcltk\bin\tcl86tg.dll ( - @rem all and install need to be separate invocations, otherwise nmakehlp is not found on install - cd tcl-8.6.1.0\win - nmake -f makefile.vc DEBUG=1 INSTALLDIR=..\..\tcltk clean all - nmake -f makefile.vc DEBUG=1 INSTALLDIR=..\..\tcltk install - cd ..\.. -) - -if not exist tcltk\bin\tk86tg.dll ( - cd tk-8.6.1.0\win - nmake -f makefile.vc OPTS=noxp DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl-8.6.1.0 clean - nmake -f makefile.vc OPTS=noxp DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl-8.6.1.0 all - nmake -f makefile.vc OPTS=noxp DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl-8.6.1.0 install - cd ..\.. -) +@echo This script is no longer used and may be removed in the future. +@echo Please use PCbuild\get_externals.bat instead. +@"%~dp0..\..\PCbuild\get_externals.bat" %* diff --git a/Tools/buildbot/test-amd64.bat b/Tools/buildbot/test-amd64.bat index 1bf124cd9215..e48329c0b30f 100644 --- a/Tools/buildbot/test-amd64.bat +++ b/Tools/buildbot/test-amd64.bat @@ -1,3 +1,6 @@ -@rem Used by the buildbot "test" step. -cd PCbuild -call rt.bat -d -q -x64 -uall -rwW -n %1 %2 %3 %4 %5 %6 %7 %8 %9 +@rem Formerly used by the buildbot "test" step. +@echo This script is no longer used and may be removed in the future. +@echo To get the same effect as this script, use +@echo PCbuild\rt.bat -q -d -x64 -uall -rwW +@echo or use `test.bat` in this directory and pass `-x64` as an argument. +call "%~dp0test.bat" -x64 %* diff --git a/Tools/buildbot/test.bat b/Tools/buildbot/test.bat index 4f4c6aa9e1f1..ff7d167e6a7b 100644 --- a/Tools/buildbot/test.bat +++ b/Tools/buildbot/test.bat @@ -1,3 +1,19 @@ -@rem Used by the buildbot "test" step. -cd PCbuild -call rt.bat -d -q -uall -rwW -n %1 %2 %3 %4 %5 %6 %7 %8 %9 +@echo off +rem Used by the buildbot "test" step. +setlocal + +set here=%~dp0 +set rt_opts=-q -d +set regrtest_args= + +:CheckOpts +if "%1"=="-x64" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts +if "%1"=="-d" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts +if "%1"=="-O" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts +if "%1"=="-q" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts +if "%1"=="+d" (set rt_opts=%rt_opts:-d=%) & shift & goto CheckOpts +if "%1"=="+q" (set rt_opts=%rt_opts:-q=%) & shift & goto CheckOpts +if NOT "%1"=="" (set regrtest_args=%regrtest_args% %1) & shift & goto CheckOpts + +echo on +call "%here%..\..\PCbuild\rt.bat" %rt_opts% -uall -rwW --timeout=3600 %regrtest_args% diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index c332b0cb5a5c..3ce3587db51b 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -8,20 +8,29 @@ import abc import ast import atexit -import clinic import collections import contextlib +import copy +import cpp import functools import hashlib import inspect import io import itertools import os +import pprint import re import shlex +import string import sys import tempfile import textwrap +import traceback +import types +import uuid + +from types import * +NoneType = type(None) # TODO: # @@ -39,6 +48,7 @@ _empty = inspect._empty _void = inspect._void +NoneType = type(None) class Unspecified: def __repr__(self): @@ -54,14 +64,27 @@ def __repr__(self): NULL = Null() +class Unknown: + def __repr__(self): + return '' + +unknown = Unknown() + +sig_end_marker = '--' + + +_text_accumulator_nt = collections.namedtuple("_text_accumulator", "text append output") + def _text_accumulator(): text = [] def output(): s = ''.join(text) text.clear() return s - return text, text.append, output + return _text_accumulator_nt(text, text.append, output) + +text_accumulator_nt = collections.namedtuple("text_accumulator", "text append") def text_accumulator(): """ @@ -75,17 +98,20 @@ def text_accumulator(): empties the accumulator. """ text, append, output = _text_accumulator() - return append, output + return text_accumulator_nt(append, output) -def fail(*args, filename=None, line_number=None): +def warn_or_fail(fail=False, *args, filename=None, line_number=None): joined = " ".join([str(a) for a in args]) add, output = text_accumulator() - add("Error") + if fail: + add("Error") + else: + add("Warning") if clinic: if filename is None: filename = clinic.filename - if clinic.block_parser and (line_number is None): + if getattr(clinic, 'block_parser', None) and (line_number is None): line_number = clinic.block_parser.line_number if filename is not None: add(' in file "' + filename + '"') @@ -94,29 +120,42 @@ def fail(*args, filename=None, line_number=None): add(':\n') add(joined) print(output()) - sys.exit(-1) + if fail: + sys.exit(-1) + + +def warn(*args, filename=None, line_number=None): + return warn_or_fail(False, *args, filename=filename, line_number=line_number) +def fail(*args, filename=None, line_number=None): + return warn_or_fail(True, *args, filename=filename, line_number=line_number) def quoted_for_c_string(s): for old, new in ( + ('\\', '\\\\'), # must be first! ('"', '\\"'), ("'", "\\'"), ): s = s.replace(old, new) return s +def c_repr(s): + return '"' + s + '"' + + is_legal_c_identifier = re.compile('^[A-Za-z_][A-Za-z0-9_]*$').match def is_legal_py_identifier(s): return all(is_legal_c_identifier(field) for field in s.split('.')) -# added "module", "self", "cls", and "null" just to be safe -# (clinic will generate variables with these names) +# identifiers that are okay in Python but aren't a good idea in C. +# so if they're used Argument Clinic will add "_value" to the end +# of the name in C. c_keywords = set(""" -asm auto break case char cls const continue default do double -else enum extern float for goto if inline int long module null -register return self short signed sizeof static struct switch +asm auto break case char const continue default do double +else enum extern float for goto if inline int long +register return short signed sizeof static struct switch typedef typeof union unsigned void volatile while """.strip().split()) @@ -144,6 +183,8 @@ def linear_format(s, **kwargs): themselves. (This line is the "source line".) * If the substitution text is empty, the source line is removed in the output. + * If the field is not recognized, the original line + is passed unmodified through to the output. * If the substitution text is not empty: * Each line of the substituted text is indented by the indent of the source line. @@ -179,6 +220,47 @@ def linear_format(s, **kwargs): return output()[:-1] +def indent_all_lines(s, prefix): + """ + Returns 's', with 'prefix' prepended to all lines. + + If the last line is empty, prefix is not prepended + to it. (If s is blank, returns s unchanged.) + + (textwrap.indent only adds to non-blank lines.) + """ + split = s.split('\n') + last = split.pop() + final = [] + for line in split: + final.append(prefix) + final.append(line) + final.append('\n') + if last: + final.append(prefix) + final.append(last) + return ''.join(final) + +def suffix_all_lines(s, suffix): + """ + Returns 's', with 'suffix' appended to all lines. + + If the last line is empty, suffix is not appended + to it. (If s is blank, returns s unchanged.) + """ + split = s.split('\n') + last = split.pop() + final = [] + for line in split: + final.append(line) + final.append(suffix) + final.append('\n') + if last: + final.append(last) + final.append(suffix) + return ''.join(final) + + def version_splitter(s): """Splits a version string into a tuple of integers. @@ -193,7 +275,7 @@ def version_splitter(s): accumulator = [] def flush(): if not accumulator: - raise ValueError('Malformed version string: ' + repr(s)) + raise ValueError('Unsupported version string: ' + repr(s)) version.append(int(''.join(accumulator))) accumulator.clear() @@ -231,6 +313,10 @@ def __init__(self): # Should be full lines with \n eol characters. self.initializers = [] + # The C statements needed to dynamically modify the values + # parsed by the parse call, before calling the impl. + self.modifications = [] + # The entries for the "keywords" array for PyArg_ParseTuple. # Should be individual strings representing the names. self.keywords = [] @@ -262,6 +348,22 @@ def __init__(self): self.cleanup = [] +class FormatCounterFormatter(string.Formatter): + """ + This counts how many instances of each formatter + "replacement string" appear in the format string. + + e.g. after evaluating "string {a}, {b}, {c}, {a}" + the counts dict would now look like + {'a': 2, 'b': 1, 'c': 1} + """ + def __init__(self): + self.counts = collections.Counter() + + def get_value(self, key, args, kwargs): + self.counts[key] += 1 + return '' + class Language(metaclass=abc.ABCMeta): start_line = "" @@ -269,33 +371,80 @@ class Language(metaclass=abc.ABCMeta): stop_line = "" checksum_line = "" + def __init__(self, filename): + pass + @abc.abstractmethod - def render(self, block): + def render(self, clinic, signatures): + pass + + def parse_line(self, line): pass def validate(self): - def assert_only_one(field, token='dsl_name'): - line = getattr(self, field) - token = '{' + token + '}' - if len(line.split(token)) != 2: - fail(self.__class__.__name__ + " " + field + " must contain " + token + " exactly once!") + def assert_only_one(attr, *additional_fields): + """ + Ensures that the string found at getattr(self, attr) + contains exactly one formatter replacement string for + each valid field. The list of valid fields is + ['dsl_name'] extended by additional_fields. + + e.g. + self.fmt = "{dsl_name} {a} {b}" + + # this passes + self.assert_only_one('fmt', 'a', 'b') + + # this fails, the format string has a {b} in it + self.assert_only_one('fmt', 'a') + + # this fails, the format string doesn't have a {c} in it + self.assert_only_one('fmt', 'a', 'b', 'c') + + # this fails, the format string has two {a}s in it, + # it must contain exactly one + self.fmt2 = '{dsl_name} {a} {a}' + self.assert_only_one('fmt2', 'a') + + """ + fields = ['dsl_name'] + fields.extend(additional_fields) + line = getattr(self, attr) + fcf = FormatCounterFormatter() + fcf.format(line) + def local_fail(should_be_there_but_isnt): + if should_be_there_but_isnt: + fail("{} {} must contain {{{}}} exactly once!".format( + self.__class__.__name__, attr, name)) + else: + fail("{} {} must not contain {{{}}}!".format( + self.__class__.__name__, attr, name)) + + for name, count in fcf.counts.items(): + if name in fields: + if count > 1: + local_fail(True) + else: + local_fail(False) + for name in fields: + if fcf.counts.get(name) != 1: + local_fail(True) + assert_only_one('start_line') assert_only_one('stop_line') - assert_only_one('checksum_line') - assert_only_one('checksum_line', 'checksum') - if len(self.body_prefix.split('{dsl_name}')) >= 3: - fail(self.__class__.__name__ + " body_prefix may contain " + token + " once at most!") + field = "arguments" if "{arguments}" in self.checksum_line else "checksum" + assert_only_one('checksum_line', field) class PythonLanguage(Language): language = 'Python' - start_line = "#/*[{dsl_name}]" + start_line = "#/*[{dsl_name} input]" body_prefix = "#" - stop_line = "#[{dsl_name}]*/" - checksum_line = "#/*[{dsl_name} checksum: {checksum}]*/" + stop_line = "#[{dsl_name} start generated code]*/" + checksum_line = "#/*[{dsl_name} end generated code: {arguments}]*/" def permute_left_option_groups(l): @@ -358,22 +507,107 @@ def permute_optional_groups(left, required, right): return tuple(accumulator) +def strip_leading_and_trailing_blank_lines(s): + lines = s.rstrip().split('\n') + while lines: + line = lines[0] + if line.strip(): + break + del lines[0] + return '\n'.join(lines) + +@functools.lru_cache() +def normalize_snippet(s, *, indent=0): + """ + Reformats s: + * removes leading and trailing blank lines + * ensures that it does not end with a newline + * dedents so the first nonwhite character on any line is at column "indent" + """ + s = strip_leading_and_trailing_blank_lines(s) + s = textwrap.dedent(s) + if indent: + s = textwrap.indent(s, ' ' * indent) + return s + + +def wrap_declarations(text, length=78): + """ + A simple-minded text wrapper for C function declarations. + + It views a declaration line as looking like this: + xxxxxxxx(xxxxxxxxx,xxxxxxxxx) + If called with length=30, it would wrap that line into + xxxxxxxx(xxxxxxxxx, + xxxxxxxxx) + (If the declaration has zero or one parameters, this + function won't wrap it.) + + If this doesn't work properly, it's probably better to + start from scratch with a more sophisticated algorithm, + rather than try and improve/debug this dumb little function. + """ + lines = [] + for line in text.split('\n'): + prefix, _, after_l_paren = line.partition('(') + if not after_l_paren: + lines.append(line) + continue + parameters, _, after_r_paren = after_l_paren.partition(')') + if not _: + lines.append(line) + continue + if ',' not in parameters: + lines.append(line) + continue + parameters = [x.strip() + ", " for x in parameters.split(',')] + prefix += "(" + if len(prefix) < length: + spaces = " " * len(prefix) + else: + spaces = " " * 4 + + while parameters: + line = prefix + first = True + while parameters: + if (not first and + (len(line) + len(parameters[0]) > length)): + break + line += parameters.pop(0) + first = False + if not parameters: + line = line.rstrip(", ") + ")" + after_r_paren + lines.append(line.rstrip()) + prefix = spaces + return "\n".join(lines) + + class CLanguage(Language): + body_prefix = "#" language = 'C' - start_line = "/*[{dsl_name}]" + start_line = "/*[{dsl_name} input]" body_prefix = "" - stop_line = "[{dsl_name}]*/" - checksum_line = "/*[{dsl_name} checksum: {checksum}]*/" + stop_line = "[{dsl_name} start generated code]*/" + checksum_line = "/*[{dsl_name} end generated code: {arguments}]*/" + + def __init__(self, filename): + super().__init__(filename) + self.cpp = cpp.Monitor(filename) + self.cpp.fail = fail - def render(self, signatures): + def parse_line(self, line): + self.cpp.writeline(line) + + def render(self, clinic, signatures): function = None for o in signatures: if isinstance(o, Function): if function: fail("You may specify at most one function per block.\nFound a block containing at least two:\n\t" + repr(function) + " and " + repr(o)) function = o - return self.render_function(function) + return self.render_function(clinic, function) def docstring_for_c_string(self, f): text, add, output = _text_accumulator() @@ -383,163 +617,332 @@ def docstring_for_c_string(self, f): add(quoted_for_c_string(line)) add('\\n"\n') - text.pop() - add('"') + if text[-2] == sig_end_marker: + # If we only have a signature, add the blank line that the + # __text_signature__ getter expects to be there. + add('"\\n"') + else: + text.pop() + add('"') return ''.join(text) - impl_prototype_template = "{c_basename}_impl({impl_parameters})" + def output_templates(self, f): + parameters = list(f.parameters.values()) + assert parameters + assert isinstance(parameters[0].converter, self_converter) + del parameters[0] + converters = [p.converter for p in parameters] - @staticmethod - def template_base(*args): - flags = '|'.join(f for f in args if f) - return """ -PyDoc_STRVAR({c_basename}__doc__, -{docstring}); - -#define {methoddef_name} \\ - {{"{name}", (PyCFunction){c_basename}, {methoddef_flags}, {c_basename}__doc__}}, -""".replace('{methoddef_flags}', flags) - - def meth_noargs_pyobject_template(self, methoddef_flags=""): - return self.template_base("METH_NOARGS", methoddef_flags) + """ -static PyObject * -{c_basename}({impl_parameters}) -""" + has_option_groups = parameters and (parameters[0].group or parameters[-1].group) + default_return_converter = (not f.return_converter or + f.return_converter.type == 'PyObject *') - def meth_noargs_template(self, methoddef_flags=""): - return self.template_base("METH_NOARGS", methoddef_flags) + """ -static {impl_return_type} -{impl_prototype}; + positional = parameters and (parameters[-1].kind == inspect.Parameter.POSITIONAL_ONLY) + all_boring_objects = False # yes, this will be false if there are 0 parameters, it's fine + first_optional = len(parameters) + for i, p in enumerate(parameters): + c = p.converter + if type(c) != object_converter: + break + if c.format_unit != 'O': + break + if p.default is not unspecified: + first_optional = min(first_optional, i) + else: + all_boring_objects = True -static PyObject * -{c_basename}({self_type}{self_name}) -{{ - PyObject *return_value = NULL; - {declarations} - {initializers} + new_or_init = f.kind in (METHOD_NEW, METHOD_INIT) - {return_value} = {c_basename}_impl({impl_arguments}); - {return_conversion} + meth_o = (len(parameters) == 1 and + parameters[0].kind == inspect.Parameter.POSITIONAL_ONLY and + not converters[0].is_optional() and + not new_or_init) -{exit_label} - {cleanup} - return return_value; -}} + # we have to set these things before we're done: + # + # docstring_prototype + # docstring_definition + # impl_prototype + # methoddef_define + # parser_prototype + # parser_definition + # impl_definition + # cpp_if + # cpp_endif + # methoddef_ifndef + + return_value_declaration = "PyObject *return_value = NULL;" + + methoddef_define = normalize_snippet(""" + #define {methoddef_name} \\ + {{"{name}", (PyCFunction){c_basename}, {methoddef_flags}, {c_basename}__doc__}}, + """) + if new_or_init and not f.docstring: + docstring_prototype = docstring_definition = '' + else: + docstring_prototype = normalize_snippet(""" + PyDoc_VAR({c_basename}__doc__); + """) + docstring_definition = normalize_snippet(""" + PyDoc_STRVAR({c_basename}__doc__, + {docstring}); + """) + impl_definition = normalize_snippet(""" + static {impl_return_type} + {c_basename}_impl({impl_parameters}) + """) + impl_prototype = parser_prototype = parser_definition = None + + parser_prototype_keyword = normalize_snippet(""" + static PyObject * + {c_basename}({self_type}{self_name}, PyObject *args, PyObject *kwargs) + """) + + parser_prototype_varargs = normalize_snippet(""" + static PyObject * + {c_basename}({self_type}{self_name}, PyObject *args) + """) + + # parser_body_fields remembers the fields passed in to the + # previous call to parser_body. this is used for an awful hack. + parser_body_fields = () + def parser_body(prototype, *fields): + nonlocal parser_body_fields + add, output = text_accumulator() + add(prototype) + parser_body_fields = fields + + fields = list(fields) + fields.insert(0, normalize_snippet(""" + {{ + {return_value_declaration} + {declarations} + {initializers} + """) + "\n") + # just imagine--your code is here in the middle + fields.append(normalize_snippet(""" + {modifications} + {return_value} = {c_basename}_impl({impl_arguments}); + {return_conversion} + + {exit_label} + {cleanup} + return return_value; + }} + """)) + for field in fields: + add('\n') + add(field) + return output() -static {impl_return_type} -{impl_prototype} -""" + def insert_keywords(s): + return linear_format(s, declarations="static char *_keywords[] = {{{keywords}, NULL}};\n{declarations}") - def meth_o_template(self, methoddef_flags=""): - return self.template_base("METH_O", methoddef_flags) + """ -static PyObject * -{c_basename}({impl_parameters}) -""" + if not parameters: + # no parameters, METH_NOARGS - def meth_o_return_converter_template(self, methoddef_flags=""): - return self.template_base("METH_O", methoddef_flags) + """ -static {impl_return_type} -{impl_prototype}; - -static PyObject * -{c_basename}({impl_parameters}) -{{ - PyObject *return_value = NULL; - {declarations} - {initializers} - _return_value = {c_basename}_impl({impl_arguments}); - {return_conversion} - -{exit_label} - {cleanup} - return return_value; -}} - -static {impl_return_type} -{impl_prototype} -""" + flags = "METH_NOARGS" - def option_group_template(self, methoddef_flags=""): - return self.template_base("METH_VARARGS", methoddef_flags) + """ -static {impl_return_type} -{impl_prototype}; - -static PyObject * -{c_basename}({self_type}{self_name}, PyObject *args) -{{ - PyObject *return_value = NULL; - {declarations} - {initializers} - - {option_group_parsing} - {return_value} = {c_basename}_impl({impl_arguments}); - {return_conversion} - -{exit_label} - {cleanup} - return return_value; -}} - -static {impl_return_type} -{impl_prototype} -""" + parser_prototype = normalize_snippet(""" + static PyObject * + {c_basename}({self_type}{self_name}, PyObject *Py_UNUSED(ignored)) + """) + parser_definition = parser_prototype - def keywords_template(self, methoddef_flags=""): - return self.template_base("METH_VARARGS|METH_KEYWORDS", methoddef_flags) + """ -static {impl_return_type} -{impl_prototype}; - -static PyObject * -{c_basename}({self_type}{self_name}, PyObject *args, PyObject *kwargs) -{{ - PyObject *return_value = NULL; - static char *_keywords[] = {{{keywords}, NULL}}; - {declarations} - {initializers} - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "{format_units}:{name}", _keywords, - {parse_arguments})) - goto exit; - {return_value} = {c_basename}_impl({impl_arguments}); - {return_conversion} - -{exit_label} - {cleanup} - return return_value; -}} - -static {impl_return_type} -{impl_prototype} -""" + if default_return_converter: + parser_definition = parser_prototype + '\n' + normalize_snippet(""" + {{ + return {c_basename}_impl({impl_arguments}); + }} + """) + else: + parser_definition = parser_body(parser_prototype) + + elif meth_o: + flags = "METH_O" + + if (isinstance(converters[0], object_converter) and + converters[0].format_unit == 'O'): + meth_o_prototype = normalize_snippet(""" + static PyObject * + {c_basename}({impl_parameters}) + """) + + if default_return_converter: + # maps perfectly to METH_O, doesn't need a return converter. + # so we skip making a parse function + # and call directly into the impl function. + impl_prototype = parser_prototype = parser_definition = '' + impl_definition = meth_o_prototype + else: + # SLIGHT HACK + # use impl_parameters for the parser here! + parser_prototype = meth_o_prototype + parser_definition = parser_body(parser_prototype) - def positional_only_template(self, methoddef_flags=""): - return self.template_base("METH_VARARGS", methoddef_flags) + """ -static {impl_return_type} -{impl_prototype}; - -static PyObject * -{c_basename}({self_type}{self_name}, PyObject *args) -{{ - PyObject *return_value = NULL; - {declarations} - {initializers} - - if (!PyArg_ParseTuple(args, - "{format_units}:{name}", - {parse_arguments})) - goto exit; - {return_value} = {c_basename}_impl({impl_arguments}); - {return_conversion} - -{exit_label} - {cleanup} - return return_value; -}} - -static {impl_return_type} -{impl_prototype} -""" + else: + argname = 'arg' + if parameters[0].name == argname: + argname += '_' + parser_prototype = normalize_snippet(""" + static PyObject * + {c_basename}({self_type}{self_name}, PyObject *%s) + """ % argname) + + parser_definition = parser_body(parser_prototype, normalize_snippet(""" + if (!PyArg_Parse(%s, "{format_units}:{name}", {parse_arguments})) + goto exit; + """ % argname, indent=4)) + + elif has_option_groups: + # positional parameters with option groups + # (we have to generate lots of PyArg_ParseTuple calls + # in a big switch statement) + + flags = "METH_VARARGS" + parser_prototype = parser_prototype_varargs + + parser_definition = parser_body(parser_prototype, ' {option_group_parsing}') + + elif positional and all_boring_objects: + # positional-only, but no option groups, + # and nothing but normal objects: + # PyArg_UnpackTuple! + + flags = "METH_VARARGS" + parser_prototype = parser_prototype_varargs + + parser_definition = parser_body(parser_prototype, normalize_snippet(""" + if (!PyArg_UnpackTuple(args, "{name}", + {unpack_min}, {unpack_max}, + {parse_arguments})) + goto exit; + """, indent=4)) + + elif positional: + # positional-only, but no option groups + # we only need one call to PyArg_ParseTuple + + flags = "METH_VARARGS" + parser_prototype = parser_prototype_varargs + + parser_definition = parser_body(parser_prototype, normalize_snippet(""" + if (!PyArg_ParseTuple(args, "{format_units}:{name}", + {parse_arguments})) + goto exit; + """, indent=4)) + + else: + # positional-or-keyword arguments + flags = "METH_VARARGS|METH_KEYWORDS" + + parser_prototype = parser_prototype_keyword + + body = normalize_snippet(""" + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "{format_units}:{name}", _keywords, + {parse_arguments})) + goto exit; + """, indent=4) + parser_definition = parser_body(parser_prototype, normalize_snippet(""" + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "{format_units}:{name}", _keywords, + {parse_arguments})) + goto exit; + """, indent=4)) + parser_definition = insert_keywords(parser_definition) + + + if new_or_init: + methoddef_define = '' + + if f.kind == METHOD_NEW: + parser_prototype = parser_prototype_keyword + else: + return_value_declaration = "int return_value = -1;" + parser_prototype = normalize_snippet(""" + static int + {c_basename}({self_type}{self_name}, PyObject *args, PyObject *kwargs) + """) + + fields = list(parser_body_fields) + parses_positional = 'METH_NOARGS' not in flags + parses_keywords = 'METH_KEYWORDS' in flags + if parses_keywords: + assert parses_positional + + if not parses_keywords: + fields.insert(0, normalize_snippet(""" + if ({self_type_check}!_PyArg_NoKeywords("{name}", kwargs)) + goto exit; + """, indent=4)) + if not parses_positional: + fields.insert(0, normalize_snippet(""" + if ({self_type_check}!_PyArg_NoPositional("{name}", args)) + goto exit; + """, indent=4)) + + parser_definition = parser_body(parser_prototype, *fields) + if parses_keywords: + parser_definition = insert_keywords(parser_definition) + + + if f.methoddef_flags: + flags += '|' + f.methoddef_flags + + methoddef_define = methoddef_define.replace('{methoddef_flags}', flags) + + methoddef_ifndef = '' + conditional = self.cpp.condition() + if not conditional: + cpp_if = cpp_endif = '' + else: + cpp_if = "#if " + conditional + cpp_endif = "#endif /* " + conditional + " */" + + if methoddef_define and f.name not in clinic.ifndef_symbols: + clinic.ifndef_symbols.add(f.name) + methoddef_ifndef = normalize_snippet(""" + #ifndef {methoddef_name} + #define {methoddef_name} + #endif /* !defined({methoddef_name}) */ + """) + + + # add ';' to the end of parser_prototype and impl_prototype + # (they mustn't be None, but they could be an empty string.) + assert parser_prototype is not None + if parser_prototype: + assert not parser_prototype.endswith(';') + parser_prototype += ';' + + if impl_prototype is None: + impl_prototype = impl_definition + if impl_prototype: + impl_prototype += ";" + + parser_definition = parser_definition.replace("{return_value_declaration}", return_value_declaration) + + d = { + "docstring_prototype" : docstring_prototype, + "docstring_definition" : docstring_definition, + "impl_prototype" : impl_prototype, + "methoddef_define" : methoddef_define, + "parser_prototype" : parser_prototype, + "parser_definition" : parser_definition, + "impl_definition" : impl_definition, + "cpp_if" : cpp_if, + "cpp_endif" : cpp_endif, + "methoddef_ifndef" : methoddef_ifndef, + } + + # make sure we didn't forget to assign something, + # and wrap each non-empty value in \n's + d2 = {} + for name, value in d.items(): + assert value is not None, "got a None value for template " + repr(name) + if value: + value = '\n' + value + '\n' + d2[name] = value + return d2 @staticmethod def group_to_variable_name(group): @@ -567,6 +970,8 @@ def render_option_group_parsing(self, f, template_dict): add, output = text_accumulator() parameters = list(f.parameters.values()) + if isinstance(parameters[0].converter, self_converter): + del parameters[0] groups = [] group = None @@ -591,12 +996,18 @@ def render_option_group_parsing(self, f, template_dict): count_min = sys.maxsize count_max = -1 - add("switch (PyTuple_Size(args)) {{\n") + add("switch (PyTuple_GET_SIZE(args)) {{\n") for subset in permute_optional_groups(left, required, right): count = len(subset) count_min = min(count_min, count) count_max = max(count_max, count) + if count == 0: + add(""" case 0: + break; +""") + continue + group_ids = {p.group for p in subset} # eliminate duplicates d = {} d['count'] = count @@ -616,7 +1027,7 @@ def render_option_group_parsing(self, f, template_dict): s = """ case {count}: if (!PyArg_ParseTuple(args, "{format_units}:{name}", {parse_arguments})) - return NULL; + goto exit; {group_booleans} break; """[1:] @@ -627,29 +1038,90 @@ def render_option_group_parsing(self, f, template_dict): add(" default:\n") s = ' PyErr_SetString(PyExc_TypeError, "{} requires {} to {} arguments");\n' add(s.format(f.full_name, count_min, count_max)) - add(' return NULL;\n') + add(' goto exit;\n') add("}}") template_dict['option_group_parsing'] = output() - def render_function(self, f): + def render_function(self, clinic, f): if not f: return "" add, output = text_accumulator() data = CRenderData() - parameters = list(f.parameters.values()) + assert f.parameters, "We should always have a 'self' at this point!" + parameters = f.render_parameters converters = [p.converter for p in parameters] + templates = self.output_templates(f) + + f_self = parameters[0] + selfless = parameters[1:] + assert isinstance(f_self.converter, self_converter), "No self parameter in " + repr(f.full_name) + "!" + + last_group = 0 + first_optional = len(selfless) + positional = selfless and selfless[-1].kind == inspect.Parameter.POSITIONAL_ONLY + new_or_init = f.kind in (METHOD_NEW, METHOD_INIT) + default_return_converter = (not f.return_converter or + f.return_converter.type == 'PyObject *') + has_option_groups = False + + # offset i by -1 because first_optional needs to ignore self + for i, p in enumerate(parameters, -1): + c = p.converter + + if (i != -1) and (p.default is not unspecified): + first_optional = min(first_optional, i) + + # insert group variable + group = p.group + if last_group != group: + last_group = group + if group: + group_name = self.group_to_variable_name(group) + data.impl_arguments.append(group_name) + data.declarations.append("int " + group_name + " = 0;") + data.impl_parameters.append("int " + group_name) + has_option_groups = True + + c.render(p, data) + + if has_option_groups and (not positional): + fail("You cannot use optional groups ('[' and ']')\nunless all parameters are positional-only ('/').") + + # HACK + # when we're METH_O, but have a custom return converter, + # we use "impl_parameters" for the parsing function + # because that works better. but that means we must + # suppress actually declaring the impl's parameters + # as variables in the parsing function. but since it's + # METH_O, we have exactly one anyway, so we know exactly + # where it is. + if ("METH_O" in templates['methoddef_define'] and + '{impl_parameters}' in templates['parser_prototype']): + data.declarations.pop(0) + template_dict = {} full_name = f.full_name template_dict['full_name'] = full_name - name = full_name.rpartition('.')[2] + if new_or_init: + name = f.cls.name + else: + name = f.name + template_dict['name'] = name - c_basename = f.c_basename or full_name.replace(".", "_") + if f.c_basename: + c_basename = f.c_basename + else: + fields = full_name.split(".") + if fields[-1] == '__new__': + fields.pop() + c_basename = "_".join(fields) + template_dict['c_basename'] = c_basename methoddef_name = "{}_METHODDEF".format(c_basename.upper()) @@ -657,47 +1129,15 @@ def render_function(self, f): template_dict['docstring'] = self.docstring_for_c_string(f) - positional = has_option_groups = False - - if parameters: - last_group = 0 - - for p in parameters: - c = p.converter - - # insert group variable - group = p.group - if last_group != group: - last_group = group - if group: - group_name = self.group_to_variable_name(group) - data.impl_arguments.append(group_name) - data.declarations.append("int " + group_name + " = 0;") - data.impl_parameters.append("int " + group_name) - has_option_groups = True - c.render(p, data) - - positional = parameters[-1].kind == inspect.Parameter.POSITIONAL_ONLY - if has_option_groups: - assert positional - - # now insert our "self" (or whatever) parameters - # (we deliberately don't call render on self converters) - stock_self = self_converter('self', f) - template_dict['self_name'] = stock_self.name - template_dict['self_type'] = stock_self.type - data.impl_parameters.insert(0, f.self_converter.type + ("" if f.self_converter.type.endswith('*') else " ") + f.self_converter.name) - if f.self_converter.type != stock_self.type: - self_cast = '(' + f.self_converter.type + ')' - else: - self_cast = '' - data.impl_arguments.insert(0, self_cast + stock_self.name) + template_dict['self_name'] = template_dict['self_type'] = template_dict['self_type_check'] = '' + f_self.converter.set_template_dict(template_dict) f.return_converter.render(f, data) template_dict['impl_return_type'] = f.return_converter.type template_dict['declarations'] = "\n".join(data.declarations) template_dict['initializers'] = "\n\n".join(data.initializers) + template_dict['modifications'] = '\n\n'.join(data.modifications) template_dict['keywords'] = '"' + '", "'.join(data.keywords) + '"' template_dict['format_units'] = ''.join(data.format_units) template_dict['parse_arguments'] = ', '.join(data.parse_arguments) @@ -707,66 +1147,54 @@ def render_function(self, f): template_dict['cleanup'] = "".join(data.cleanup) template_dict['return_value'] = data.return_value - template_dict['impl_prototype'] = self.impl_prototype_template.format_map(template_dict) + # used by unpack tuple code generator + ignore_self = -1 if isinstance(converters[0], self_converter) else 0 + unpack_min = first_optional + unpack_max = len(selfless) + template_dict['unpack_min'] = str(unpack_min) + template_dict['unpack_max'] = str(unpack_max) - default_return_converter = (not f.return_converter or - f.return_converter.type == 'PyObject *') - - if not parameters: - if default_return_converter: - template = self.meth_noargs_pyobject_template(f.methoddef_flags) - else: - template = self.meth_noargs_template(f.methoddef_flags) - elif (len(parameters) == 1 and - parameters[0].kind == inspect.Parameter.POSITIONAL_ONLY and - not converters[0].is_optional() and - isinstance(converters[0], object_converter) and - converters[0].format_unit == 'O'): - if default_return_converter: - template = self.meth_o_template(f.methoddef_flags) - else: - # HACK - # we're using "impl_parameters" for the - # non-impl function, because that works - # better for METH_O. but that means we - # must supress actually declaring the - # impl's parameters as variables in the - # non-impl. but since it's METH_O, we - # only have one anyway, so - # we don't have any problem finding it. - declarations_copy = list(data.declarations) - before, pyobject, after = declarations_copy[0].partition('PyObject *') - assert not before, "hack failed, see comment" - assert pyobject, "hack failed, see comment" - assert after and after[0].isalpha(), "hack failed, see comment" - del declarations_copy[0] - template_dict['declarations'] = "\n".join(declarations_copy) - template = self.meth_o_return_converter_template(f.methoddef_flags) - elif has_option_groups: + if has_option_groups: self.render_option_group_parsing(f, template_dict) - template = self.option_group_template(f.methoddef_flags) + + # buffers, not destination + for name, destination in clinic.destination_buffers.items(): + template = templates[name] + if has_option_groups: + template = linear_format(template, + option_group_parsing=template_dict['option_group_parsing']) template = linear_format(template, - option_group_parsing=template_dict['option_group_parsing']) - elif positional: - template = self.positional_only_template(f.methoddef_flags) - else: - template = self.keywords_template(f.methoddef_flags) + declarations=template_dict['declarations'], + return_conversion=template_dict['return_conversion'], + initializers=template_dict['initializers'], + modifications=template_dict['modifications'], + cleanup=template_dict['cleanup'], + ) + + # Only generate the "exit:" label + # if we have any gotos + need_exit_label = "goto exit;" in template + template = linear_format(template, + exit_label="exit:" if need_exit_label else '' + ) + + s = template.format_map(template_dict) - template = linear_format(template, - declarations=template_dict['declarations'], - return_conversion=template_dict['return_conversion'], - initializers=template_dict['initializers'], - cleanup=template_dict['cleanup'], - ) + # mild hack: + # reflow long impl declarations + if name in {"impl_prototype", "impl_definition"}: + s = wrap_declarations(s) + + if clinic.line_prefix: + s = indent_all_lines(s, clinic.line_prefix) + if clinic.line_suffix: + s = suffix_all_lines(s, clinic.line_suffix) + + destination.append(s) + + return clinic.get_destination('block').dump() - # Only generate the "exit:" label - # if we have any gotos - need_exit_label = "goto exit;" in template - template = linear_format(template, - exit_label="exit:" if need_exit_label else '' - ) - return template.format_map(template_dict) @contextlib.contextmanager @@ -780,10 +1208,14 @@ def OverrideStdioWith(stdout): sys.stdout = saved_stdout -def create_regex(before, after): +def create_regex(before, after, word=True, whole_line=True): """Create an re object for matching marker lines.""" - pattern = r'^{}(\w+){}$' - return re.compile(pattern.format(re.escape(before), re.escape(after))) + group_re = "\w+" if word else ".+" + pattern = r'{}({}){}' + if whole_line: + pattern = '^' + pattern + '$' + pattern = pattern.format(re.escape(before), group_re, re.escape(after)) + return re.compile(pattern) class Block: @@ -841,6 +1273,16 @@ def __init__(self, input, dsl_name=None, signatures=None, output=None, indent='' self.indent = indent self.preindent = preindent + def __repr__(self): + dsl_name = self.dsl_name or "text" + def summarize(s): + s = repr(s) + if len(s) > 30: + return s[:26] + "..." + s[0] + return s + return "".join(( + "")) + class BlockParser: """ @@ -863,32 +1305,44 @@ def __init__(self, input, language, *, verify=True): self.language = language before, _, after = language.start_line.partition('{dsl_name}') assert _ == '{dsl_name}' + self.find_start_re = create_regex(before, after, whole_line=False) self.start_re = create_regex(before, after) self.verify = verify self.last_checksum_re = None self.last_dsl_name = None self.dsl_name = None + self.first_block = True def __iter__(self): return self def __next__(self): - if not self.input: - raise StopIteration + while True: + if not self.input: + raise StopIteration + + if self.dsl_name: + return_value = self.parse_clinic_block(self.dsl_name) + self.dsl_name = None + self.first_block = False + return return_value + block = self.parse_verbatim_block() + if self.first_block and not block.input: + continue + self.first_block = False + return block - if self.dsl_name: - return_value = self.parse_clinic_block(self.dsl_name) - self.dsl_name = None - return return_value - return self.parse_verbatim_block() def is_start_line(self, line): match = self.start_re.match(line.lstrip()) return match.group(1) if match else None - def _line(self): + def _line(self, lookahead=False): self.line_number += 1 - return self.input.pop() + line = self.input.pop() + if not lookahead: + self.language.parse_line(line) + return line def parse_verbatim_block(self): add, output = text_accumulator() @@ -907,13 +1361,21 @@ def parse_verbatim_block(self): def parse_clinic_block(self, dsl_name): input_add, input_output = text_accumulator() self.block_start_line_number = self.line_number + 1 - stop_line = self.language.stop_line.format(dsl_name=dsl_name) + '\n' + stop_line = self.language.stop_line.format(dsl_name=dsl_name) body_prefix = self.language.body_prefix.format(dsl_name=dsl_name) + def is_stop_line(line): + # make sure to recognize stop line even if it + # doesn't end with EOL (it could be the very end of the file) + if not line.startswith(stop_line): + return False + remainder = line[len(stop_line):] + return (not remainder) or remainder.isspace() + # consume body of program while self.input: line = self._line() - if line == stop_line or self.is_start_line(line): + if is_stop_line(line) or self.is_start_line(line): break if body_prefix: line = line.lstrip() @@ -925,35 +1387,54 @@ def parse_clinic_block(self, dsl_name): if self.last_dsl_name == dsl_name: checksum_re = self.last_checksum_re else: - before, _, after = self.language.checksum_line.format(dsl_name=dsl_name, checksum='{checksum}').partition('{checksum}') - assert _ == '{checksum}' - checksum_re = create_regex(before, after) + before, _, after = self.language.checksum_line.format(dsl_name=dsl_name, arguments='{arguments}').partition('{arguments}') + assert _ == '{arguments}' + checksum_re = create_regex(before, after, word=False) self.last_dsl_name = dsl_name self.last_checksum_re = checksum_re # scan forward for checksum line output_add, output_output = text_accumulator() - checksum = None + arguments = None while self.input: - line = self._line() + line = self._line(lookahead=True) match = checksum_re.match(line.lstrip()) - checksum = match.group(1) if match else None - if checksum: + arguments = match.group(1) if match else None + if arguments: break output_add(line) if self.is_start_line(line): break output = output_output() - if checksum: + if arguments: + d = {} + for field in shlex.split(arguments): + name, equals, value = field.partition('=') + if not equals: + fail("Mangled Argument Clinic marker line: {!r}".format(line)) + d[name.strip()] = value.strip() + if self.verify: - computed = compute_checksum(output) + if 'input' in d: + checksum = d['output'] + input_checksum = d['input'] + else: + checksum = d['checksum'] + input_checksum = None + + computed = compute_checksum(output, len(checksum)) if checksum != computed: - fail("Checksum mismatch!\nExpected: {}\nComputed: {}".format(checksum, computed)) + fail("Checksum mismatch!\nExpected: {}\nComputed: {}\n" + "Suggested fix: remove all generated code including " + "the end marker,\n" + "or use the '-f' option." + .format(checksum, computed)) else: # put back output - self.input.extend(reversed(output.splitlines(keepends=True))) - self.line_number -= len(output) + output_lines = output.splitlines(keepends=True) + self.line_number -= len(output_lines) + self.input.extend(reversed(output_lines)) output = None return Block(input_output(), dsl_name, output=output) @@ -992,21 +1473,106 @@ def print_block(self, block): write(self.language.stop_line.format(dsl_name=dsl_name)) write("\n") - output = block.output + input = ''.join(block.input) + output = ''.join(block.output) if output: - write(output) if not output.endswith('\n'): - write('\n') + output += '\n' + write(output) - write(self.language.checksum_line.format(dsl_name=dsl_name, checksum=compute_checksum(output))) + arguments="output={} input={}".format(compute_checksum(output, 16), compute_checksum(input, 16)) + write(self.language.checksum_line.format(dsl_name=dsl_name, arguments=arguments)) write("\n") + def write(self, text): + self.f.write(text) + + +class BufferSeries: + """ + Behaves like a "defaultlist". + When you ask for an index that doesn't exist yet, + the object grows the list until that item exists. + So o[n] will always work. + + Supports negative indices for actual items. + e.g. o[-1] is an element immediately preceding o[0]. + """ + + def __init__(self): + self._start = 0 + self._array = [] + self._constructor = _text_accumulator + + def __getitem__(self, i): + i -= self._start + if i < 0: + self._start += i + prefix = [self._constructor() for x in range(-i)] + self._array = prefix + self._array + i = 0 + while i >= len(self._array): + self._array.append(self._constructor()) + return self._array[i] + + def clear(self): + for ta in self._array: + ta._text.clear() + + def dump(self): + texts = [ta.output() for ta in self._array] + return "".join(texts) + + +class Destination: + def __init__(self, name, type, clinic, *args): + self.name = name + self.type = type + self.clinic = clinic + valid_types = ('buffer', 'file', 'suppress') + if type not in valid_types: + fail("Invalid destination type " + repr(type) + " for " + name + " , must be " + ', '.join(valid_types)) + extra_arguments = 1 if type == "file" else 0 + if len(args) < extra_arguments: + fail("Not enough arguments for destination " + name + " new " + type) + if len(args) > extra_arguments: + fail("Too many arguments for destination " + name + " new " + type) + if type =='file': + d = {} + filename = clinic.filename + d['path'] = filename + dirname, basename = os.path.split(filename) + if not dirname: + dirname = '.' + d['dirname'] = dirname + d['basename'] = basename + d['basename_root'], d['basename_extension'] = os.path.splitext(filename) + self.filename = args[0].format_map(d) + + self.buffers = BufferSeries() + + def __repr__(self): + if self.type == 'file': + file_repr = " " + repr(self.filename) + else: + file_repr = '' + return "".join(("")) + + def clear(self): + if self.type != 'buffer': + fail("Can't clear destination" + self.name + " , it's not of type buffer") + self.buffers.clear() + + def dump(self): + return self.buffers.dump() + # maps strings to Language objects. # "languages" maps the name of the language ("C", "Python"). # "extensions" maps the file extension ("c", "py"). languages = { 'C': CLanguage, 'Python': PythonLanguage } -extensions = { 'c': CLanguage, 'h': CLanguage, 'py': PythonLanguage } +extensions = { name: CLanguage for name in "c cc cpp cxx h hh hpp hxx".split() } +extensions['py'] = PythonLanguage # maps strings to callables. @@ -1031,21 +1597,136 @@ def print_block(self, block): # The callable should not call builtins.print. return_converters = {} +clinic = None class Clinic: - def __init__(self, language, printer=None, *, verify=True, filename=None): + + presets_text = """ +preset block +everything block +methoddef_ifndef buffer 1 +docstring_prototype suppress +parser_prototype suppress +cpp_if suppress +cpp_endif suppress + +preset original +everything block +methoddef_ifndef buffer 1 +docstring_prototype suppress +parser_prototype suppress +cpp_if suppress +cpp_endif suppress + +preset file +everything file +methoddef_ifndef file 1 +docstring_prototype suppress +parser_prototype suppress +impl_definition block + +preset buffer +everything buffer +methoddef_ifndef buffer 1 +impl_definition block +docstring_prototype suppress +impl_prototype suppress +parser_prototype suppress + +preset partial-buffer +everything buffer +methoddef_ifndef buffer 1 +docstring_prototype block +impl_prototype suppress +methoddef_define block +parser_prototype block +impl_definition block + +""" + + def __init__(self, language, printer=None, *, force=False, verify=True, filename=None): # maps strings to Parser objects. # (instantiated from the "parsers" global.) self.parsers = {} self.language = language + if printer: + fail("Custom printers are broken right now") self.printer = printer or BlockPrinter(language) self.verify = verify + self.force = force self.filename = filename self.modules = collections.OrderedDict() self.classes = collections.OrderedDict() + self.functions = [] + + self.line_prefix = self.line_suffix = '' + + self.destinations = {} + self.add_destination("block", "buffer") + self.add_destination("suppress", "suppress") + self.add_destination("buffer", "buffer") + if filename: + self.add_destination("file", "file", "{dirname}/clinic/{basename}.h") + + d = self.get_destination_buffer + self.destination_buffers = collections.OrderedDict(( + ('cpp_if', d('file')), + ('docstring_prototype', d('suppress')), + ('docstring_definition', d('file')), + ('methoddef_define', d('file')), + ('impl_prototype', d('file')), + ('parser_prototype', d('suppress')), + ('parser_definition', d('file')), + ('cpp_endif', d('file')), + ('methoddef_ifndef', d('file', 1)), + ('impl_definition', d('block')), + )) + + self.destination_buffers_stack = [] + self.ifndef_symbols = set() + + self.presets = {} + preset = None + for line in self.presets_text.strip().split('\n'): + line = line.strip() + if not line: + continue + name, value, *options = line.split() + if name == 'preset': + self.presets[value] = preset = collections.OrderedDict() + continue + + if len(options): + index = int(options[0]) + else: + index = 0 + buffer = self.get_destination_buffer(value, index) + + if name == 'everything': + for name in self.destination_buffers: + preset[name] = buffer + continue + + assert name in self.destination_buffers + preset[name] = buffer global clinic clinic = self + def add_destination(self, name, type, *args): + if name in self.destinations: + fail("Destination already exists: " + repr(name)) + self.destinations[name] = Destination(name, type, self, *args) + + def get_destination(self, name): + d = self.destinations.get(name) + if not d: + fail("Destination does not exist: " + repr(name)) + return d + + def get_destination_buffer(self, name, item=0): + d = self.get_destination(name) + return d.buffers[item] + def parse(self, input): printer = self.printer self.block_parser = BlockParser(input, self.language, verify=self.verify) @@ -1056,9 +1737,75 @@ def parse(self, input): assert dsl_name in parsers, "No parser to handle {!r} block.".format(dsl_name) self.parsers[dsl_name] = parsers[dsl_name](self) parser = self.parsers[dsl_name] - parser.parse(block) + try: + parser.parse(block) + except Exception: + fail('Exception raised during parsing:\n' + + traceback.format_exc().rstrip()) printer.print_block(block) - return printer.f.getvalue() + + second_pass_replacements = {} + + # these are destinations not buffers + for name, destination in self.destinations.items(): + if destination.type == 'suppress': + continue + output = destination.dump() + + if output: + + block = Block("", dsl_name="clinic", output=output) + + if destination.type == 'buffer': + block.input = "dump " + name + "\n" + warn("Destination buffer " + repr(name) + " not empty at end of file, emptying.") + printer.write("\n") + printer.print_block(block) + continue + + if destination.type == 'file': + try: + dirname = os.path.dirname(destination.filename) + try: + os.makedirs(dirname) + except FileExistsError: + if not os.path.isdir(dirname): + fail("Can't write to destination {}, " + "can't make directory {}!".format( + destination.filename, dirname)) + if self.verify: + with open(destination.filename, "rt") as f: + parser_2 = BlockParser(f.read(), language=self.language) + blocks = list(parser_2) + if (len(blocks) != 1) or (blocks[0].input != 'preserve\n'): + fail("Modified destination file " + repr(destination.filename) + ", not overwriting!") + except FileNotFoundError: + pass + + block.input = 'preserve\n' + printer_2 = BlockPrinter(self.language) + printer_2.print_block(block) + with open(destination.filename, "wt") as f: + f.write(printer_2.f.getvalue()) + continue + text = printer.f.getvalue() + + if second_pass_replacements: + printer_2 = BlockPrinter(self.language) + parser_2 = BlockParser(text, self.language) + changed = False + for block in parser_2: + if block.dsl_name: + for id, replacement in second_pass_replacements.items(): + if id in block.output: + changed = True + block.output = block.output.replace(id, replacement) + printer_2.print_block(block) + if changed: + text = printer_2.f.getvalue() + + return text + def _module_and_class(self, fields): """ @@ -1091,23 +1838,27 @@ def _module_and_class(self, fields): return module, cls -def parse_file(filename, *, verify=True, output=None, encoding='utf-8'): +def parse_file(filename, *, force=False, verify=True, output=None, encoding='utf-8'): extension = os.path.splitext(filename)[1][1:] if not extension: fail("Can't extract file type for file " + repr(filename)) try: - language = extensions[extension]() + language = extensions[extension](filename) except KeyError: fail("Can't identify file type for file " + repr(filename)) - clinic = Clinic(language, verify=verify, filename=filename) - with open(filename, 'r', encoding=encoding) as f: raw = f.read() + # exit quickly if there are no clinic markers in the file + find_start_re = BlockParser("", language).find_start_re + if not find_start_re.search(raw): + return + + clinic = Clinic(language, force=force, verify=verify, filename=filename) cooked = clinic.parse(raw) - if cooked == raw: + if (cooked == raw) and not force: return directory = os.path.dirname(filename) or '.' @@ -1120,9 +1871,12 @@ def parse_file(filename, *, verify=True, output=None, encoding='utf-8'): os.replace(tmpfilename, output or filename) -def compute_checksum(input): +def compute_checksum(input, length=None): input = input or '' - return hashlib.sha1(input.encode('utf-8')).hexdigest() + s = hashlib.sha1(input.encode('utf-8')).hexdigest() + if length: + s = s[:length] + return s @@ -1151,10 +1905,12 @@ def __repr__(self): return "" class Class: - def __init__(self, name, module=None, cls=None): + def __init__(self, name, module=None, cls=None, typedef=None, type_object=None): self.name = name self.module = module self.cls = cls + self.typedef = typedef + self.type_object = type_object self.parent = cls or module self.classes = collections.OrderedDict() @@ -1163,8 +1919,85 @@ def __init__(self, name, module=None, cls=None): def __repr__(self): return "" +unsupported_special_methods = set(""" + +__abs__ +__add__ +__and__ +__bytes__ +__call__ +__complex__ +__delitem__ +__divmod__ +__eq__ +__float__ +__floordiv__ +__ge__ +__getattr__ +__getattribute__ +__getitem__ +__gt__ +__hash__ +__iadd__ +__iand__ +__ifloordiv__ +__ilshift__ +__imatmul__ +__imod__ +__imul__ +__index__ +__int__ +__invert__ +__ior__ +__ipow__ +__irshift__ +__isub__ +__iter__ +__itruediv__ +__ixor__ +__le__ +__len__ +__lshift__ +__lt__ +__matmul__ +__mod__ +__mul__ +__neg__ +__new__ +__next__ +__or__ +__pos__ +__pow__ +__radd__ +__rand__ +__rdivmod__ +__repr__ +__rfloordiv__ +__rlshift__ +__rmatmul__ +__rmod__ +__rmul__ +__ror__ +__round__ +__rpow__ +__rrshift__ +__rshift__ +__rsub__ +__rtruediv__ +__rxor__ +__setattr__ +__setitem__ +__str__ +__sub__ +__truediv__ +__xor__ + +""".strip().split()) -DATA, CALLABLE, METHOD, STATIC_METHOD, CLASS_METHOD = range(5) + +INVALID, CALLABLE, STATIC_METHOD, CLASS_METHOD, METHOD_INIT, METHOD_NEW = """ +INVALID, CALLABLE, STATIC_METHOD, CLASS_METHOD, METHOD_INIT, METHOD_NEW +""".replace(",", "").strip().split() class Function: """ @@ -1182,7 +2015,8 @@ def __init__(self, parameters=None, *, name, module, cls=None, c_basename=None, full_name=None, return_converter, return_annotation=_empty, - docstring=None, kind=CALLABLE, coexist=False): + docstring=None, kind=CALLABLE, coexist=False, + docstring_only=False): self.parameters = parameters or collections.OrderedDict() self.return_annotation = return_annotation self.name = name @@ -1196,9 +2030,29 @@ def __init__(self, parameters=None, *, name, self.kind = kind self.coexist = coexist self.self_converter = None + # docstring_only means "don't generate a machine-readable + # signature, just a normal docstring". it's True for + # functions with optional groups because we can't represent + # those accurately with inspect.Signature in 3.4. + self.docstring_only = docstring_only + + self.rendered_parameters = None + + __render_parameters__ = None + @property + def render_parameters(self): + if not self.__render_parameters__: + self.__render_parameters__ = l = [] + for p in self.parameters.values(): + p = p.copy() + p.converter.pre_render() + l.append(p) + return self.__render_parameters__ @property def methoddef_flags(self): + if self.kind in (METHOD_INIT, METHOD_NEW): + return None flags = [] if self.kind == CLASS_METHOD: flags.append('METH_CLASS') @@ -1213,6 +2067,25 @@ def methoddef_flags(self): def __repr__(self): return '' + def copy(self, **overrides): + kwargs = { + 'name': self.name, 'module': self.module, 'parameters': self.parameters, + 'cls': self.cls, 'c_basename': self.c_basename, + 'full_name': self.full_name, + 'return_converter': self.return_converter, 'return_annotation': self.return_annotation, + 'docstring': self.docstring, 'kind': self.kind, 'coexist': self.coexist, + 'docstring_only': self.docstring_only, + } + kwargs.update(overrides) + f = Function(**kwargs) + + parameters = collections.OrderedDict() + for name, value in f.parameters.items(): + value = value.copy(function=f) + parameters[name] = value + f.parameters = parameters + return f + class Parameter: """ @@ -1237,29 +2110,38 @@ def __repr__(self): def is_keyword_only(self): return self.kind == inspect.Parameter.KEYWORD_ONLY -py_special_values = { - NULL: "None", -} + def is_positional_only(self): + return self.kind == inspect.Parameter.POSITIONAL_ONLY + + def copy(self, **overrides): + kwargs = { + 'name': self.name, 'kind': self.kind, 'default':self.default, + 'function': self.function, 'converter': self.converter, 'annotation': self.annotation, + 'docstring': self.docstring, 'group': self.group, + } + kwargs.update(overrides) + if 'converter' not in overrides: + converter = copy.copy(self.converter) + converter.function = kwargs['function'] + kwargs['converter'] = converter + return Parameter(**kwargs) -def py_repr(o): - special = py_special_values.get(o) - if special: - return special - return repr(o) -c_special_values = { - NULL: "NULL", - None: "Py_None", -} +class LandMine: + # try to access any + def __init__(self, message): + self.__message__ = message + + def __repr__(self): + return '" + + def __getattribute__(self, name): + if name in ('__repr__', '__message__'): + return super().__getattribute__(name) + # raise RuntimeError(repr(name)) + fail("Stepped on a land mine, trying to access attribute " + repr(name) + ":\n" + self.__message__) -def c_repr(o): - special = c_special_values.get(o) - if special: - return special - if isinstance(o, str): - return '"' + quoted_for_c_string(o) + '"' - return repr(o) def add_c_converter(f, name=None): if not name: @@ -1274,7 +2156,7 @@ def add_default_legacy_c_converter(cls): # automatically add converter for default format unit # (but without stomping on the existing one if it's already # set, in case you subclass) - if ((cls.format_unit != 'O&') and + if ((cls.format_unit not in ('O&', '')) and (cls.format_unit not in legacy_converters)): legacy_converters[cls.format_unit] = cls return cls @@ -1288,7 +2170,8 @@ def closure(f): added_f = f else: added_f = functools.partial(f, **kwargs) - legacy_converters[format_unit] = added_f + if format_unit: + legacy_converters[format_unit] = added_f return f return closure @@ -1301,28 +2184,39 @@ class CConverter(metaclass=CConverterAutoRegister): """ For the init function, self, name, function, and default must be keyword-or-positional parameters. All other - parameters (including "required" and "doc_default") - must be keyword-only. + parameters must be keyword-only. """ + # The C name to use for this variable. + name = None + + # The Python name to use for this variable. + py_name = None + + # The C type to use for this variable. + # 'type' should be a Python string specifying the type, e.g. "int". + # If this is a pointer type, the type string should end with ' *'. type = None - format_unit = 'O&' # The Python default value for this parameter, as a Python value. - # Or "unspecified" if there is no default. + # Or the magic value "unspecified" if there is no default. + # Or the magic value "unknown" if this value is a cannot be evaluated + # at Argument-Clinic-preprocessing time (but is presumed to be valid + # at runtime). default = unspecified - # "default" as it should appear in the documentation, as a string. - # Or None if there is no default. - doc_default = None - - # "default" converted into a str for rendering into Python code. - py_default = None + # If not None, default must be isinstance() of this type. + # (You can also specify a tuple of types.) + default_type = None # "default" converted into a C value, as a string. # Or None if there is no default. c_default = None + # "default" converted into a Python value, as a string. + # Or None if there is no default. + py_default = None + # The default value used to initialize the C variable when # there is no default, but not specifying a default may # result in an "uninitialized variable" warning. This can @@ -1339,40 +2233,110 @@ class CConverter(metaclass=CConverterAutoRegister): # (If this is not None, format_unit must be 'O&'.) converter = None - encoding = None + # Should Argument Clinic add a '&' before the name of + # the variable when passing it into the _impl function? impl_by_reference = False + + # Should Argument Clinic add a '&' before the name of + # the variable when passing it into PyArg_ParseTuple (AndKeywords)? parse_by_reference = True + + ############################################################# + ############################################################# + ## You shouldn't need to read anything below this point to ## + ## write your own converter functions. ## + ############################################################# + ############################################################# + + # The "format unit" to specify for this variable when + # parsing arguments using PyArg_ParseTuple (AndKeywords). + # Custom converters should always use the default value of 'O&'. + format_unit = 'O&' + + # What encoding do we want for this variable? Only used + # by format units starting with 'e'. + encoding = None + + # Should this object be required to be a subclass of a specific type? + # If not None, should be a string representing a pointer to a + # PyTypeObject (e.g. "&PyUnicode_Type"). + # Only used by the 'O!' format unit (and the "object" converter). + subclass_of = None + + # Do we want an adjacent '_length' variable for this variable? + # Only used by format units ending with '#'. length = False - def __init__(self, name, function, default=unspecified, *, doc_default=None, required=False, annotation=unspecified, **kwargs): - self.function = function + # Should we show this parameter in the generated + # __text_signature__? This is *almost* always True. + # (It's only False for __new__, __init__, and METH_STATIC functions.) + show_in_signature = True + + # Overrides the name used in a text signature. + # The name used for a "self" parameter must be one of + # self, type, or module; however users can set their own. + # This lets the self_converter overrule the user-settable + # name, *just* for the text signature. + # Only set by self_converter. + signature_name = None + + # keep in sync with self_converter.__init__! + def __init__(self, name, py_name, function, default=unspecified, *, c_default=None, py_default=None, annotation=unspecified, **kwargs): self.name = name + self.py_name = py_name if default is not unspecified: + if self.default_type and not isinstance(default, (self.default_type, Unknown)): + if isinstance(self.default_type, type): + types_str = self.default_type.__name__ + else: + types_str = ', '.join((cls.__name__ for cls in self.default_type)) + fail("{}: default value {!r} for field {} is not of type {}".format( + self.__class__.__name__, default, name, types_str)) self.default = default - self.py_default = py_repr(default) - self.doc_default = doc_default if doc_default is not None else self.py_default - self.c_default = c_repr(default) - elif doc_default is not None: - fail(function.fullname + " argument " + name + " specified a 'doc_default' without having a 'default'") + + if c_default: + self.c_default = c_default + if py_default: + self.py_default = py_default + if annotation != unspecified: fail("The 'annotation' parameter is not currently permitted.") - self.required = required + + # this is deliberate, to prevent you from caching information + # about the function in the init. + # (that breaks if we get cloned.) + # so after this change we will noisily fail. + self.function = LandMine("Don't access members of self.function inside converter_init!") self.converter_init(**kwargs) + self.function = function def converter_init(self): pass def is_optional(self): - return (self.default is not unspecified) and (not self.required) + return (self.default is not unspecified) - def render(self, parameter, data): - """ - parameter is a clinic.Parameter instance. - data is a CRenderData instance. - """ + def _render_self(self, parameter, data): self.parameter = parameter - name = ensure_legal_c_identifier(self.name) + original_name = self.name + name = ensure_legal_c_identifier(original_name) + + # impl_arguments + s = ("&" if self.impl_by_reference else "") + name + data.impl_arguments.append(s) + if self.length: + data.impl_arguments.append(self.length_name()) + + # impl_parameters + data.impl_parameters.append(self.simple_declaration(by_reference=self.impl_by_reference)) + if self.length: + data.impl_parameters.append("Py_ssize_clean_t " + self.length_name()) + + def _render_non_self(self, parameter, data): + self.parameter = parameter + original_name = self.name + name = ensure_legal_c_identifier(original_name) # declarations d = self.declaration() @@ -1383,14 +2347,13 @@ def render(self, parameter, data): if initializers: data.initializers.append('/* initializers for ' + name + ' */\n' + initializers.rstrip()) - # impl_arguments - s = ("&" if self.impl_by_reference else "") + name - data.impl_arguments.append(s) - if self.length: - data.impl_arguments.append(self.length_name()) + # modifications + modifications = self.modify() + if modifications: + data.modifications.append('/* modifications for ' + name + ' */\n' + modifications.rstrip()) # keywords - data.keywords.append(name) + data.keywords.append(parameter.name) # format_units if self.is_optional() and '|' not in data.format_units: @@ -1402,16 +2365,19 @@ def render(self, parameter, data): # parse_arguments self.parse_argument(data.parse_arguments) - # impl_parameters - data.impl_parameters.append(self.simple_declaration(by_reference=self.impl_by_reference)) - if self.length: - data.impl_parameters.append("Py_ssize_clean_t " + self.length_name()) - # cleanup cleanup = self.cleanup() if cleanup: data.cleanup.append('/* Cleanup for ' + name + ' */\n' + cleanup.rstrip() + "\n") + def render(self, parameter, data): + """ + parameter is a clinic.Parameter instance. + data is a CRenderData instance. + """ + self._render_self(parameter, data) + self._render_non_self(parameter, data) + def length_name(self): """Computes the name of the associated "length" variable.""" if not self.length: @@ -1428,7 +2394,9 @@ def parse_argument(self, list): list.append(self.converter) if self.encoding: - list.append(self.encoding) + list.append(c_repr(self.encoding)) + elif self.subclass_of: + list.append(self.subclass_of) legal_name = ensure_legal_c_identifier(self.name) s = ("&" if self.parse_by_reference else "") + legal_name @@ -1471,7 +2439,12 @@ def declaration(self): declaration.append('\nPy_ssize_clean_t ') declaration.append(self.length_name()) declaration.append(';') - return "".join(declaration) + s = "".join(declaration) + # double up curly-braces, this string will be used + # as part of a format_map() template later + s = s.replace("{", "{{") + s = s.replace("}", "}}") + return s def initialize(self): """ @@ -1481,6 +2454,14 @@ def initialize(self): """ return "" + def modify(self): + """ + The C statements required to modify this variable after parsing. + Returns a string containing this code indented at column 0. + If no initialization is necessary, returns an empty string. + """ + return "" + def cleanup(self): """ The C statements required to clean up after this variable. @@ -1489,24 +2470,41 @@ def cleanup(self): """ return "" + def pre_render(self): + """ + A second initialization function, like converter_init, + called just before rendering. + You are permitted to examine self.function here. + """ + pass + class bool_converter(CConverter): type = 'int' + default_type = bool format_unit = 'p' c_ignored_default = '0' def converter_init(self): - self.default = bool(self.default) - self.c_default = str(int(self.default)) + if self.default is not unspecified: + self.default = bool(self.default) + self.c_default = str(int(self.default)) class char_converter(CConverter): type = 'char' + default_type = (bytes, bytearray) format_unit = 'c' c_ignored_default = "'\0'" + def converter_init(self): + if isinstance(self.default, self.default_type) and (len(self.default) != 1): + fail("char_converter: illegal default value " + repr(self.default)) + + @add_legacy_c_converter('B', bitwise=True) -class byte_converter(CConverter): - type = 'byte' +class unsigned_char_converter(CConverter): + type = 'unsigned char' + default_type = int format_unit = 'b' c_ignored_default = "'\0'" @@ -1514,13 +2512,17 @@ def converter_init(self, *, bitwise=False): if bitwise: self.format_unit = 'B' +class byte_converter(unsigned_char_converter): pass + class short_converter(CConverter): type = 'short' + default_type = int format_unit = 'h' c_ignored_default = "0" class unsigned_short_converter(CConverter): type = 'unsigned short' + default_type = int format_unit = 'H' c_ignored_default = "0" @@ -1528,20 +2530,24 @@ def converter_init(self, *, bitwise=False): if not bitwise: fail("Unsigned shorts must be bitwise (for now).") -@add_legacy_c_converter('C', types='str') +@add_legacy_c_converter('C', accept={str}) class int_converter(CConverter): type = 'int' + default_type = int format_unit = 'i' c_ignored_default = "0" - def converter_init(self, *, types='int'): - if types == 'str': + def converter_init(self, *, accept={int}, type=None): + if accept == {str}: self.format_unit = 'C' - elif types != 'int': - fail("int_converter: illegal 'types' argument") + elif accept != {int}: + fail("int_converter: illegal 'accept' argument " + repr(accept)) + if type != None: + self.type = type class unsigned_int_converter(CConverter): type = 'unsigned int' + default_type = int format_unit = 'I' c_ignored_default = "0" @@ -1551,11 +2557,13 @@ def converter_init(self, *, bitwise=False): class long_converter(CConverter): type = 'long' + default_type = int format_unit = 'l' c_ignored_default = "0" class unsigned_long_converter(CConverter): type = 'unsigned long' + default_type = int format_unit = 'k' c_ignored_default = "0" @@ -1565,11 +2573,13 @@ def converter_init(self, *, bitwise=False): class PY_LONG_LONG_converter(CConverter): type = 'PY_LONG_LONG' + default_type = int format_unit = 'L' c_ignored_default = "0" class unsigned_PY_LONG_LONG_converter(CConverter): type = 'unsigned PY_LONG_LONG' + default_type = int format_unit = 'K' c_ignored_default = "0" @@ -1579,23 +2589,27 @@ def converter_init(self, *, bitwise=False): class Py_ssize_t_converter(CConverter): type = 'Py_ssize_t' + default_type = int format_unit = 'n' c_ignored_default = "0" class float_converter(CConverter): type = 'float' + default_type = float format_unit = 'f' c_ignored_default = "0.0" class double_converter(CConverter): type = 'double' + default_type = float format_unit = 'd' c_ignored_default = "0.0" class Py_complex_converter(CConverter): type = 'Py_complex' + default_type = complex format_unit = 'D' c_ignored_default = "{0.0, 0.0}" @@ -1604,154 +2618,192 @@ class object_converter(CConverter): type = 'PyObject *' format_unit = 'O' - def converter_init(self, *, type=None): - if type: - assert isinstance(type, str) - assert type.isidentifier() - try: - type = eval(type) - # need more of these! - type = { - str: '&PyUnicode_Type', - }[type] - except NameError: - type = type + def converter_init(self, *, converter=None, type=None, subclass_of=None): + if converter: + if subclass_of: + fail("object: Cannot pass in both 'converter' and 'subclass_of'") + self.format_unit = 'O&' + self.converter = converter + elif subclass_of: self.format_unit = 'O!' - self.encoding = type + self.subclass_of = subclass_of + if type is not None: + self.type = type + + +# +# We define three conventions for buffer types in the 'accept' argument: +# +# buffer : any object supporting the buffer interface +# rwbuffer: any object supporting the buffer interface, but must be writeable +# robuffer: any object supporting the buffer interface, but must not be writeable +# + +class buffer: pass +class rwbuffer: pass +class robuffer: pass + +def str_converter_key(types, encoding, zeroes): + return (frozenset(types), bool(encoding), bool(zeroes)) + +str_converter_argument_map = {} -@add_legacy_c_converter('s#', length=True) -@add_legacy_c_converter('y', type="bytes") -@add_legacy_c_converter('y#', type="bytes", length=True) -@add_legacy_c_converter('z', nullable=True) -@add_legacy_c_converter('z#', nullable=True, length=True) class str_converter(CConverter): type = 'const char *' + default_type = (str, Null, NoneType) format_unit = 's' - def converter_init(self, *, encoding=None, types="str", - length=False, nullable=False, zeroes=False): + def converter_init(self, *, accept={str}, encoding=None, zeroes=False): - types = set(types.strip().split()) - bytes_type = set(("bytes",)) - str_type = set(("str",)) - all_3_type = set(("bytearray",)) | bytes_type | str_type - is_bytes = types == bytes_type - is_str = types == str_type - is_all_3 = types == all_3_type - - self.length = bool(length) - format_unit = None + key = str_converter_key(accept, encoding, zeroes) + format_unit = str_converter_argument_map.get(key) + if not format_unit: + fail("str_converter: illegal combination of arguments", key) + self.format_unit = format_unit + self.length = bool(zeroes) if encoding: + if self.default not in (Null, None, unspecified): + fail("str_converter: Argument Clinic doesn't support default values for encoded strings") self.encoding = encoding + self.type = 'char *' + # sorry, clinic can't support preallocated buffers + # for es# and et# + self.c_default = "NULL" - if is_str and not (length or zeroes or nullable): - format_unit = 'es' - elif is_all_3 and not (length or zeroes or nullable): - format_unit = 'et' - elif is_str and length and zeroes and not nullable: - format_unit = 'es#' - elif is_all_3 and length and not (nullable or zeroes): - format_unit = 'et#' - - if format_unit.endswith('#'): - print("Warning: code using format unit ", repr(format_unit), "probably doesn't work properly.") - # TODO set pointer to NULL - # TODO add cleanup for buffer - pass + def cleanup(self): + if self.encoding: + name = ensure_legal_c_identifier(self.name) + return "".join(["if (", name, ")\n PyMem_FREE(", name, ");\n"]) - else: - if zeroes: - fail("str_converter: illegal combination of arguments (zeroes is only legal with an encoding)") - - if is_bytes and not (nullable or length): - format_unit = 'y' - elif is_bytes and length and not nullable: - format_unit = 'y#' - elif is_str and not (nullable or length): - format_unit = 's' - elif is_str and length and not nullable: - format_unit = 's#' - elif is_str and nullable and not length: - format_unit = 'z' - elif is_str and nullable and length: - format_unit = 'z#' +# +# This is the fourth or fifth rewrite of registering all the +# crazy string converter format units. Previous approaches hid +# bugs--generally mismatches between the semantics of the format +# unit and the arguments necessary to represent those semantics +# properly. Hopefully with this approach we'll get it 100% right. +# +# The r() function (short for "register") both registers the +# mapping from arguments to format unit *and* registers the +# legacy C converter for that format unit. +# +def r(format_unit, *, accept, encoding=False, zeroes=False): + if not encoding and format_unit != 's': + # add the legacy c converters here too. + # + # note: add_legacy_c_converter can't work for + # es, es#, et, or et# + # because of their extra encoding argument + # + # also don't add the converter for 's' because + # the metaclass for CConverter adds it for us. + kwargs = {} + if accept != {str}: + kwargs['accept'] = accept + if zeroes: + kwargs['zeroes'] = True + added_f = functools.partial(str_converter, **kwargs) + legacy_converters[format_unit] = added_f - if not format_unit: - fail("str_converter: illegal combination of arguments") - self.format_unit = format_unit + d = str_converter_argument_map + key = str_converter_key(accept, encoding, zeroes) + if key in d: + sys.exit("Duplicate keys specified for str_converter_argument_map!") + d[key] = format_unit + +r('es', encoding=True, accept={str}) +r('es#', encoding=True, zeroes=True, accept={str}) +r('et', encoding=True, accept={bytes, bytearray, str}) +r('et#', encoding=True, zeroes=True, accept={bytes, bytearray, str}) +r('s', accept={str}) +r('s#', zeroes=True, accept={robuffer, str}) +r('y', accept={robuffer}) +r('y#', zeroes=True, accept={robuffer}) +r('z', accept={str, NoneType}) +r('z#', zeroes=True, accept={robuffer, str, NoneType}) +del r class PyBytesObject_converter(CConverter): type = 'PyBytesObject *' format_unit = 'S' + # accept = {bytes} class PyByteArrayObject_converter(CConverter): type = 'PyByteArrayObject *' format_unit = 'Y' + # accept = {bytearray} class unicode_converter(CConverter): type = 'PyObject *' + default_type = (str, Null, NoneType) format_unit = 'U' -@add_legacy_c_converter('u#', length=True) -@add_legacy_c_converter('Z', nullable=True) -@add_legacy_c_converter('Z#', nullable=True, length=True) +@add_legacy_c_converter('u#', zeroes=True) +@add_legacy_c_converter('Z', accept={str, NoneType}) +@add_legacy_c_converter('Z#', accept={str, NoneType}, zeroes=True) class Py_UNICODE_converter(CConverter): type = 'Py_UNICODE *' + default_type = (str, Null, NoneType) format_unit = 'u' - def converter_init(self, *, nullable=False, length=False): - format_unit = 'Z' if nullable else 'u' - if length: + def converter_init(self, *, accept={str}, zeroes=False): + format_unit = 'Z' if accept=={str, NoneType} else 'u' + if zeroes: format_unit += '#' self.length = True self.format_unit = format_unit -# -# We define three string conventions for buffer types in the 'types' argument: -# 'buffer' : any object supporting the buffer interface -# 'rwbuffer': any object supporting the buffer interface, but must be writeable -# 'robuffer': any object supporting the buffer interface, but must not be writeable -# -@add_legacy_c_converter('s*', types='str bytes bytearray buffer') -@add_legacy_c_converter('z*', types='str bytes bytearray buffer', nullable=True) -@add_legacy_c_converter('w*', types='bytearray rwbuffer') +@add_legacy_c_converter('s*', accept={str, buffer}) +@add_legacy_c_converter('z*', accept={str, buffer, NoneType}) +@add_legacy_c_converter('w*', accept={rwbuffer}) class Py_buffer_converter(CConverter): type = 'Py_buffer' format_unit = 'y*' impl_by_reference = True - c_ignored_default = "{NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL}" - - def converter_init(self, *, types='bytes bytearray buffer', nullable=False): - types = set(types.strip().split()) - bytes_type = set(('bytes',)) - bytearray_type = set(('bytearray',)) - buffer_type = set(('buffer',)) - rwbuffer_type = set(('rwbuffer',)) - robuffer_type = set(('robuffer',)) - str_type = set(('str',)) - bytes_bytearray_buffer_type = bytes_type | bytearray_type | buffer_type - - format_unit = None - if types == (str_type | bytes_bytearray_buffer_type): - format_unit = 's*' if not nullable else 'z*' + c_ignored_default = "{NULL, NULL}" + + def converter_init(self, *, accept={buffer}): + if self.default not in (unspecified, None): + fail("The only legal default value for Py_buffer is None.") + + self.c_default = self.c_ignored_default + + if accept == {str, buffer, NoneType}: + format_unit = 'z*' + elif accept == {str, buffer}: + format_unit = 's*' + elif accept == {buffer}: + format_unit = 'y*' + elif accept == {rwbuffer}: + format_unit = 'w*' else: - if nullable: - fail('Py_buffer_converter: illegal combination of arguments (nullable=True)') - elif types == (bytes_bytearray_buffer_type): - format_unit = 'y*' - elif types == (bytearray_type | rwuffer_type): - format_unit = 'w*' - if not format_unit: fail("Py_buffer_converter: illegal combination of arguments") self.format_unit = format_unit def cleanup(self): name = ensure_legal_c_identifier(self.name) - return "".join(["if (", name, ".buf)\n PyBuffer_Release(&", name, ");\n"]) + return "".join(["if (", name, ".obj)\n PyBuffer_Release(&", name, ");\n"]) + + +def correct_name_for_self(f): + if f.kind in (CALLABLE, METHOD_INIT): + if f.cls: + return "PyObject *", "self" + return "PyModuleDef *", "module" + if f.kind == STATIC_METHOD: + return "void *", "null" + if f.kind in (CLASS_METHOD, METHOD_NEW): + return "PyTypeObject *", "type" + raise RuntimeError("Unhandled type of function f: " + repr(f.kind)) + +def required_type_for_self_for_parser(f): + type, _ = correct_name_for_self(f) + if f.kind in (METHOD_INIT, METHOD_NEW, STATIC_METHOD, CLASS_METHOD): + return type + return None class self_converter(CConverter): @@ -1759,24 +2811,103 @@ class self_converter(CConverter): A special-case converter: this is the default converter used for "self". """ - type = "PyObject *" - def converter_init(self): + type = None + format_unit = '' + + def converter_init(self, *, type=None): + self.specified_type = type + + def pre_render(self): f = self.function - if f.kind == CALLABLE: - if f.cls: - self.name = "self" - else: - self.name = "module" - self.type = "PyModuleDef *" - elif f.kind == STATIC_METHOD: - self.name = "null" - self.type = "void *" - elif f.kind == CLASS_METHOD: - self.name = "cls" - self.type = "PyTypeObject *" + default_type, default_name = correct_name_for_self(f) + self.signature_name = default_name + self.type = self.specified_type or self.type or default_type + + kind = self.function.kind + new_or_init = kind in (METHOD_NEW, METHOD_INIT) + + if (kind == STATIC_METHOD) or new_or_init: + self.show_in_signature = False + + # tp_new (METHOD_NEW) functions are of type newfunc: + # typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *); + # PyTypeObject is a typedef for struct _typeobject. + # + # tp_init (METHOD_INIT) functions are of type initproc: + # typedef int (*initproc)(PyObject *, PyObject *, PyObject *); + # + # All other functions generated by Argument Clinic are stored in + # PyMethodDef structures, in the ml_meth slot, which is of type PyCFunction: + # typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); + # However! We habitually cast these functions to PyCFunction, + # since functions that accept keyword arguments don't fit this signature + # but are stored there anyway. So strict type equality isn't important + # for these functions. + # + # So: + # + # * The name of the first parameter to the impl and the parsing function will always + # be self.name. + # + # * The type of the first parameter to the impl will always be of self.type. + # + # * If the function is neither tp_new (METHOD_NEW) nor tp_init (METHOD_INIT): + # * The type of the first parameter to the parsing function is also self.type. + # This means that if you step into the parsing function, your "self" parameter + # is of the correct type, which may make debugging more pleasant. + # + # * Else if the function is tp_new (METHOD_NEW): + # * The type of the first parameter to the parsing function is "PyTypeObject *", + # so the type signature of the function call is an exact match. + # * If self.type != "PyTypeObject *", we cast the first parameter to self.type + # in the impl call. + # + # * Else if the function is tp_init (METHOD_INIT): + # * The type of the first parameter to the parsing function is "PyObject *", + # so the type signature of the function call is an exact match. + # * If self.type != "PyObject *", we cast the first parameter to self.type + # in the impl call. + + @property + def parser_type(self): + return required_type_for_self_for_parser(self.function) or self.type def render(self, parameter, data): - fail("render() should never be called on self_converter instances") + """ + parameter is a clinic.Parameter instance. + data is a CRenderData instance. + """ + if self.function.kind == STATIC_METHOD: + return + + self._render_self(parameter, data) + + if self.type != self.parser_type: + # insert cast to impl_argument[0], aka self. + # we know we're in the first slot in all the CRenderData lists, + # because we render parameters in order, and self is always first. + assert len(data.impl_arguments) == 1 + assert data.impl_arguments[0] == self.name + data.impl_arguments[0] = '(' + self.type + ")" + data.impl_arguments[0] + + def set_template_dict(self, template_dict): + template_dict['self_name'] = self.name + template_dict['self_type'] = self.parser_type + kind = self.function.kind + cls = self.function.cls + + if ((kind in (METHOD_NEW, METHOD_INIT)) and cls and cls.typedef): + if kind == METHOD_NEW: + passed_in_type = self.name + else: + passed_in_type = 'Py_TYPE({})'.format(self.name) + + line = '({passed_in_type} == {type_object}) &&\n ' + d = { + 'type_object': self.function.cls.type_object, + 'passed_in_type': passed_in_type + } + template_dict['self_type_check'] = line.format_map(d) @@ -1796,11 +2927,17 @@ def __init__(cls, name, bases, classdict): class CReturnConverter(metaclass=CReturnConverterAutoRegister): + # The C type to use for this variable. + # 'type' should be a Python string specifying the type, e.g. "int". + # If this is a pointer type, the type string should end with ' *'. type = 'PyObject *' + + # The Python default value for this parameter, as a Python value. + # Or the magic value "unspecified" if there is no default. default = None - def __init__(self, *, doc_default=None, **kwargs): - self.doc_default = doc_default + def __init__(self, *, py_default=None, **kwargs): + self.py_default = py_default try: self.return_converter_init(**kwargs) except TypeError as e: @@ -1835,34 +2972,83 @@ def render(self, function, data): add_c_return_converter(CReturnConverter, 'object') -class int_return_converter(CReturnConverter): +class NoneType_return_converter(CReturnConverter): + def render(self, function, data): + self.declare(data) + data.return_conversion.append(''' +if (_return_value != Py_None) + goto exit; +return_value = Py_None; +Py_INCREF(Py_None); +'''.strip()) + +class bool_return_converter(CReturnConverter): type = 'int' def render(self, function, data): self.declare(data) self.err_occurred_if("_return_value == -1", data) - data.return_conversion.append( - 'return_value = PyLong_FromLong((long)_return_value);\n') - + data.return_conversion.append('return_value = PyBool_FromLong((long)_return_value);\n') class long_return_converter(CReturnConverter): type = 'long' + conversion_fn = 'PyLong_FromLong' + cast = '' + unsigned_cast = '' def render(self, function, data): self.declare(data) - self.err_occurred_if("_return_value == -1", data) + self.err_occurred_if("_return_value == {}-1".format(self.unsigned_cast), data) data.return_conversion.append( - 'return_value = PyLong_FromLong(_return_value);\n') + ''.join(('return_value = ', self.conversion_fn, '(', self.cast, '_return_value);\n'))) +class int_return_converter(long_return_converter): + type = 'int' + cast = '(long)' -class Py_ssize_t_return_converter(CReturnConverter): +class init_return_converter(long_return_converter): + """ + Special return converter for __init__ functions. + """ + type = 'int' + cast = '(long)' + + def render(self, function, data): + pass + +class unsigned_long_return_converter(long_return_converter): + type = 'unsigned long' + conversion_fn = 'PyLong_FromUnsignedLong' + unsigned_cast = '(unsigned long)' + +class unsigned_int_return_converter(unsigned_long_return_converter): + type = 'unsigned int' + cast = '(unsigned long)' + unsigned_cast = '(unsigned int)' + +class Py_ssize_t_return_converter(long_return_converter): type = 'Py_ssize_t' + conversion_fn = 'PyLong_FromSsize_t' + +class size_t_return_converter(long_return_converter): + type = 'size_t' + conversion_fn = 'PyLong_FromSize_t' + unsigned_cast = '(size_t)' + + +class double_return_converter(CReturnConverter): + type = 'double' + cast = '' def render(self, function, data): self.declare(data) - self.err_occurred_if("_return_value == -1", data) + self.err_occurred_if("_return_value == -1.0", data) data.return_conversion.append( - 'return_value = PyLong_FromSsize_t(_return_value);\n') + 'return_value = PyFloat_FromDouble(' + self.cast + '_return_value);\n') + +class float_return_converter(double_return_converter): + type = 'float' + cast = '(double)' class DecodeFSDefault_return_converter(CReturnConverter): @@ -1875,6 +3061,24 @@ def render(self, function, data): 'return_value = PyUnicode_DecodeFSDefault(_return_value);\n') +def eval_ast_expr(node, globals, *, filename='-'): + """ + Takes an ast.Expr node. Compiles and evaluates it. + Returns the result of the expression. + + globals represents the globals dict the expression + should see. (There's no equivalent for "locals" here.) + """ + + if isinstance(node, ast.Expr): + node = node.value + + node = ast.Expression(node) + co = compile(node, filename, 'eval') + fn = types.FunctionType(co, globals) + return fn() + + class IndentStack: def __init__(self): self.indents = [] @@ -1889,7 +3093,7 @@ def measure(self, line): Returns the length of the line's margin. """ if '\t' in line: - fail('Tab characters are illegal in the Clinic DSL.') + fail('Tab characters are illegal in the Argument Clinic DSL.') stripped = line.lstrip() if not len(stripped): # we can't tell anything from an empty line @@ -1980,9 +3184,12 @@ def reset(self): self.keyword_only = False self.group = 0 self.parameter_state = self.ps_start + self.seen_positional_with_default = False self.indent = IndentStack() self.kind = CALLABLE self.coexist = False + self.parameter_continuation = '' + self.preserve_output = False def directive_version(self, required): global version @@ -1995,11 +3202,15 @@ def directive_module(self, name): module, cls = self.clinic._module_and_class(fields) if cls: fail("Can't nest a module inside a class!") + + if name in module.classes: + fail("Already defined module " + repr(name) + "!") + m = Module(name, module) module.modules[name] = m self.block.signatures.append(m) - def directive_class(self, name): + def directive_class(self, name, typedef, type_object): fields = name.split('.') in_classes = False parent = self @@ -2007,29 +3218,105 @@ def directive_class(self, name): so_far = [] module, cls = self.clinic._module_and_class(fields) - c = Class(name, module, cls) - if cls: - cls.classes[name] = c - else: - module.classes[name] = c + parent = cls or module + if name in parent.classes: + fail("Already defined class " + repr(name) + "!") + + c = Class(name, module, cls, typedef, type_object) + parent.classes[name] = c self.block.signatures.append(c) + def directive_set(self, name, value): + if name not in ("line_prefix", "line_suffix"): + fail("unknown variable", repr(name)) + + value = value.format_map({ + 'block comment start': '/*', + 'block comment end': '*/', + }) + + self.clinic.__dict__[name] = value + + def directive_destination(self, name, command, *args): + if command == 'new': + self.clinic.add_destination(name, *args) + return + + if command == 'clear': + self.clinic.get_destination(name).clear() + fail("unknown destination command", repr(command)) + + + def directive_output(self, command_or_name, destination=''): + fd = self.clinic.destination_buffers + + if command_or_name == "preset": + preset = self.clinic.presets.get(destination) + if not preset: + fail("Unknown preset " + repr(destination) + "!") + fd.update(preset) + return + + if command_or_name == "push": + self.clinic.destination_buffers_stack.append(fd.copy()) + return + + if command_or_name == "pop": + if not self.clinic.destination_buffers_stack: + fail("Can't 'output pop', stack is empty!") + previous_fd = self.clinic.destination_buffers_stack.pop() + fd.update(previous_fd) + return + + # secret command for debugging! + if command_or_name == "print": + self.block.output.append(pprint.pformat(fd)) + self.block.output.append('\n') + return + + d = self.clinic.get_destination(destination) + + if command_or_name == "everything": + for name in list(fd): + fd[name] = d + return + + if command_or_name not in fd: + fail("Invalid command / destination name " + repr(command_or_name) + ", must be one of:\n preset push pop print everything " + " ".join(fd)) + fd[command_or_name] = d + + def directive_dump(self, name): + self.block.output.append(self.clinic.get_destination(name).dump()) + + def directive_print(self, *args): + self.block.output.append(' '.join(args)) + self.block.output.append('\n') + + def directive_preserve(self): + if self.preserve_output: + fail("Can't have preserve twice in one block!") + self.preserve_output = True + def at_classmethod(self): - assert self.kind is CALLABLE + if self.kind is not CALLABLE: + fail("Can't set @classmethod, function is not a normal callable") self.kind = CLASS_METHOD def at_staticmethod(self): - assert self.kind is CALLABLE + if self.kind is not CALLABLE: + fail("Can't set @staticmethod, function is not a normal callable") self.kind = STATIC_METHOD def at_coexist(self): - assert self.coexist == False + if self.coexist: + fail("Called @coexist twice!") self.coexist = True - def parse(self, block): self.reset() self.block = block + self.saved_output = self.block.output + block.output = [] block_start = self.clinic.block_parser.line_number lines = block.input.split('\n') for line_number, line in enumerate(lines, self.clinic.block_parser.block_start_line_number): @@ -2040,7 +3327,12 @@ def parse(self, block): self.next(self.state_terminal) self.state(None) - block.output = self.clinic.language.render(block.signatures) + block.output.extend(self.clinic.language.render(clinic, block.signatures)) + + if self.preserve_output: + if block.output: + fail("'preserve' only works for blocks that don't produce any output!") + block.output = self.saved_output @staticmethod def ignore_line(line): @@ -2069,6 +3361,18 @@ def state_dsl_start(self, line): # self.block = self.ClinicOutputBlock(self) if self.ignore_line(line): return + + # is it a directive? + fields = shlex.split(line) + directive_name = fields[0] + directive = self.directives.get(directive_name, None) + if directive: + try: + directive(*fields[1:]) + except TypeError as e: + fail(str(e)) + return + self.next(self.state_modulename_name, line) def state_modulename_name(self, line): @@ -2077,6 +3381,12 @@ def state_modulename_name(self, line): # modulename.fnname [as c_basename] [-> return annotation] # square brackets denote optional syntax. # + # alternatively: + # modulename.fnname [as c_basename] = modulename.existing_fn_name + # clones the parameters and return converter from that + # function. you can't modify them. you must enter a + # new docstring. + # # (but we might find a directive first!) # # this line is permitted to start with whitespace. @@ -2087,13 +3397,43 @@ def state_modulename_name(self, line): self.indent.infer(line) - # is it a directive? - fields = shlex.split(line) - directive_name = fields[0] - directive = self.directives.get(directive_name, None) - if directive: - directive(*fields[1:]) - return + # are we cloning? + before, equals, existing = line.rpartition('=') + if equals: + full_name, _, c_basename = before.partition(' as ') + full_name = full_name.strip() + c_basename = c_basename.strip() + existing = existing.strip() + if (is_legal_py_identifier(full_name) and + (not c_basename or is_legal_c_identifier(c_basename)) and + is_legal_py_identifier(existing)): + # we're cloning! + fields = [x.strip() for x in existing.split('.')] + function_name = fields.pop() + module, cls = self.clinic._module_and_class(fields) + + for existing_function in (cls or module).functions: + if existing_function.name == function_name: + break + else: + existing_function = None + if not existing_function: + print("class", cls, "module", module, "existing", existing) + print("cls. functions", cls.functions) + fail("Couldn't find existing function " + repr(existing) + "!") + + fields = [x.strip() for x in full_name.split('.')] + function_name = fields.pop() + module, cls = self.clinic._module_and_class(fields) + + if not (existing_function.kind == self.kind and existing_function.coexist == self.coexist): + fail("'kind' of function and cloned function don't match! (@classmethod/@staticmethod/@coexist)") + self.function = existing_function.copy(name=function_name, full_name=full_name, module=module, cls=cls, c_basename=c_basename, docstring='') + + self.block.signatures.append(self.function) + (cls or module).functions.append(self.function) + self.next(self.state_function_docstring) + return line, _, returns = line.partition('->') @@ -2106,9 +3446,8 @@ def state_modulename_name(self, line): if c_basename and not is_legal_c_identifier(c_basename): fail("Illegal C basename: {}".format(c_basename)) - if not returns: - return_converter = CReturnConverter() - else: + return_converter = None + if returns: ast_input = "def x() -> {}: pass".format(returns) module = None try: @@ -2119,9 +3458,11 @@ def state_modulename_name(self, line): fail("Badly-formed annotation for " + full_name + ": " + returns) try: name, legacy, kwargs = self.parse_converter(module.body[0].returns) - assert not legacy + if legacy: + fail("Legacy converter {!r} not allowed as a return converter" + .format(name)) if name not in return_converters: - fail("Error: No available return converter called " + repr(name)) + fail("No available return converter called " + repr(name)) return_converter = return_converters[name](**kwargs) except ValueError: fail("Badly-formed annotation for " + full_name + ": " + returns) @@ -2130,11 +3471,39 @@ def state_modulename_name(self, line): function_name = fields.pop() module, cls = self.clinic._module_and_class(fields) + fields = full_name.split('.') + if fields[-1] == '__new__': + if (self.kind != CLASS_METHOD) or (not cls): + fail("__new__ must be a class method!") + self.kind = METHOD_NEW + elif fields[-1] == '__init__': + if (self.kind != CALLABLE) or (not cls): + fail("__init__ must be a normal method, not a class or static method!") + self.kind = METHOD_INIT + if not return_converter: + return_converter = init_return_converter() + elif fields[-1] in unsupported_special_methods: + fail(fields[-1] + " is a special method and cannot be converted to Argument Clinic! (Yet.)") + + if not return_converter: + return_converter = CReturnConverter() + if not module: fail("Undefined module used in declaration of " + repr(full_name.strip()) + ".") self.function = Function(name=function_name, full_name=full_name, module=module, cls=cls, c_basename=c_basename, return_converter=return_converter, kind=self.kind, coexist=self.coexist) self.block.signatures.append(self.function) + + # insert a self converter automatically + type, name = correct_name_for_self(self.function) + kwargs = {} + if cls and type == "PyObject *": + kwargs['type'] = cls.typedef + sc = self.function.self_converter = self_converter(name, name, self.function, **kwargs) + p_self = Parameter(sc.name, inspect.Parameter.POSITIONAL_ONLY, function=self.function, converter=sc) + self.function.parameters[sc.name] = p_self + + (cls or module).functions.append(self.function) self.next(self.state_parameters_start) # Now entering the parameters section. The rules, formally stated: @@ -2164,8 +3533,6 @@ def state_modulename_name(self, line): # with X spaces such that F < X < P. (As before, F is the indent # of the function declaration.) # - ############## - # # Also, currently Argument Clinic places the following restrictions on groups: # * Each group must contain at least one parameter. # * Each group may contain at most one group, which must be the furthest @@ -2193,18 +3560,21 @@ def state_modulename_name(self, line): # "parameter_state". (Previously the code was a miasma of ifs and # separate boolean state variables.) The states are: # - # [ [ a, b, ] c, ] d, e, f, [ g, h, [ i ] ] / <- line - # 01 2 3 4 5 6 <- state transitions + # [ [ a, b, ] c, ] d, e, f=3, [ g, h, [ i ] ] / <- line + # 01 2 3 4 5 6 7 <- state transitions # # 0: ps_start. before we've seen anything. legal transitions are to 1 or 3. # 1: ps_left_square_before. left square brackets before required parameters. # 2: ps_group_before. in a group, before required parameters. - # 3: ps_required. required parameters. (renumber left groups!) - # 4: ps_group_after. in a group, after required parameters. - # 5: ps_right_square_after. right square brackets after required parameters. - # 6: ps_seen_slash. seen slash. + # 3: ps_required. required parameters, positional-or-keyword or positional-only + # (we don't know yet). (renumber left groups!) + # 4: ps_optional. positional-or-keyword or positional-only parameters that + # now must have default values. + # 5: ps_group_after. in a group, after required parameters. + # 6: ps_right_square_after. right square brackets after required parameters. + # 7: ps_seen_slash. seen slash. ps_start, ps_left_square_before, ps_group_before, ps_required, \ - ps_group_after, ps_right_square_after, ps_seen_slash = range(7) + ps_optional, ps_group_after, ps_right_square_after, ps_seen_slash = range(8) def state_parameters_start(self, line): if self.ignore_line(line): @@ -2214,6 +3584,7 @@ def state_parameters_start(self, line): if not self.indent.infer(line): return self.next(self.state_function_docstring, line) + self.parameter_continuation = '' return self.next(self.state_parameter, line) @@ -2227,6 +3598,10 @@ def to_required(self): p.group = -p.group def state_parameter(self, line): + if self.parameter_continuation: + line = self.parameter_continuation + ' ' + line.lstrip() + self.parameter_continuation = '' + if self.ignore_line(line): return @@ -2240,6 +3615,11 @@ def state_parameter(self, line): # we indented, must be to new parameter docstring column return self.next(self.state_parameter_docstring_start, line) + line = line.rstrip() + if line.endswith('\\'): + self.parameter_continuation = line[:-1] + return + line = line.lstrip() if line in ('*', '/', '[', ']'): @@ -2253,54 +3633,207 @@ def state_parameter(self, line): elif self.parameter_state == self.ps_group_before: if not self.group: self.to_required() - elif self.parameter_state == self.ps_group_after: + elif self.parameter_state in (self.ps_group_after, self.ps_optional): pass else: - fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ")") + fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".a)") + + # handle "as" for parameters too + c_name = None + name, have_as_token, trailing = line.partition(' as ') + if have_as_token: + name = name.strip() + if ' ' not in name: + fields = trailing.strip().split(' ') + if not fields: + fail("Invalid 'as' clause!") + c_name = fields[0] + if c_name.endswith(':'): + name += ':' + c_name = c_name[:-1] + fields[0] = name + line = ' '.join(fields) + + base, equals, default = line.rpartition('=') + if not equals: + base = default + default = None - ast_input = "def x({}): pass".format(line) module = None try: + ast_input = "def x({}): pass".format(base) module = ast.parse(ast_input) except SyntaxError: - pass + try: + # the last = was probably inside a function call, like + # c: int(accept={str}) + # so assume there was no actual default value. + default = None + ast_input = "def x({}): pass".format(line) + module = ast.parse(ast_input) + except SyntaxError: + pass if not module: fail("Function " + self.function.name + " has an invalid parameter declaration:\n\t" + line) function_args = module.body[0].args - parameter = function_args.args[0] - if function_args.defaults: - expr = function_args.defaults[0] - # mild hack: explicitly support NULL as a default value - if isinstance(expr, ast.Name) and expr.id == 'NULL': - value = NULL - else: - value = ast.literal_eval(expr) - else: - value = unspecified + if len(function_args.args) > 1: + fail("Function " + self.function.name + " has an invalid parameter declaration (comma?):\n\t" + line) + if function_args.defaults or function_args.kw_defaults: + fail("Function " + self.function.name + " has an invalid parameter declaration (default value?):\n\t" + line) + if function_args.vararg or function_args.kwarg: + fail("Function " + self.function.name + " has an invalid parameter declaration (*args? **kwargs?):\n\t" + line) + + parameter = function_args.args[0] parameter_name = parameter.arg name, legacy, kwargs = self.parse_converter(parameter.annotation) + + if not default: + if self.parameter_state == self.ps_optional: + fail("Can't have a parameter without a default (" + repr(parameter_name) + ")\nafter a parameter with a default!") + value = unspecified + if 'py_default' in kwargs: + fail("You can't specify py_default without specifying a default value!") + else: + if self.parameter_state == self.ps_required: + self.parameter_state = self.ps_optional + default = default.strip() + bad = False + ast_input = "x = {}".format(default) + bad = False + try: + module = ast.parse(ast_input) + + if 'c_default' not in kwargs: + # we can only represent very simple data values in C. + # detect whether default is okay, via a blacklist + # of disallowed ast nodes. + class DetectBadNodes(ast.NodeVisitor): + bad = False + def bad_node(self, node): + self.bad = True + + # inline function call + visit_Call = bad_node + # inline if statement ("x = 3 if y else z") + visit_IfExp = bad_node + + # comprehensions and generator expressions + visit_ListComp = visit_SetComp = bad_node + visit_DictComp = visit_GeneratorExp = bad_node + + # literals for advanced types + visit_Dict = visit_Set = bad_node + visit_List = visit_Tuple = bad_node + + # "starred": "a = [1, 2, 3]; *a" + visit_Starred = bad_node + + # allow ellipsis, for now + # visit_Ellipsis = bad_node + + blacklist = DetectBadNodes() + blacklist.visit(module) + bad = blacklist.bad + else: + # if they specify a c_default, we can be more lenient about the default value. + # but at least make an attempt at ensuring it's a valid expression. + try: + value = eval(default) + if value == unspecified: + fail("'unspecified' is not a legal default value!") + except NameError: + pass # probably a named constant + except Exception as e: + fail("Malformed expression given as default value\n" + "{!r} caused {!r}".format(default, e)) + if bad: + fail("Unsupported expression as default value: " + repr(default)) + + expr = module.body[0].value + # mild hack: explicitly support NULL as a default value + if isinstance(expr, ast.Name) and expr.id == 'NULL': + value = NULL + py_default = 'None' + c_default = "NULL" + elif (isinstance(expr, ast.BinOp) or + (isinstance(expr, ast.UnaryOp) and not isinstance(expr.operand, ast.Num))): + c_default = kwargs.get("c_default") + if not (isinstance(c_default, str) and c_default): + fail("When you specify an expression (" + repr(default) + ") as your default value,\nyou MUST specify a valid c_default.") + py_default = default + value = unknown + elif isinstance(expr, ast.Attribute): + a = [] + n = expr + while isinstance(n, ast.Attribute): + a.append(n.attr) + n = n.value + if not isinstance(n, ast.Name): + fail("Unsupported default value " + repr(default) + " (looked like a Python constant)") + a.append(n.id) + py_default = ".".join(reversed(a)) + + c_default = kwargs.get("c_default") + if not (isinstance(c_default, str) and c_default): + fail("When you specify a named constant (" + repr(py_default) + ") as your default value,\nyou MUST specify a valid c_default.") + + try: + value = eval(py_default) + except NameError: + value = unknown + else: + value = ast.literal_eval(expr) + py_default = repr(value) + if isinstance(value, (bool, None.__class__)): + c_default = "Py_" + py_default + elif isinstance(value, str): + c_default = c_repr(value) + else: + c_default = py_default + + except SyntaxError as e: + fail("Syntax error: " + repr(e.text)) + except (ValueError, AttributeError): + value = unknown + c_default = kwargs.get("c_default") + py_default = default + if not (isinstance(c_default, str) and c_default): + fail("When you specify a named constant (" + repr(py_default) + ") as your default value,\nyou MUST specify a valid c_default.") + + kwargs.setdefault('c_default', c_default) + kwargs.setdefault('py_default', py_default) + dict = legacy_converters if legacy else converters legacy_str = "legacy " if legacy else "" if name not in dict: fail('{} is not a valid {}converter'.format(name, legacy_str)) - converter = dict[name](parameter_name, self.function, value, **kwargs) + # if you use a c_name for the parameter, we just give that name to the converter + # but the parameter object gets the python name + converter = dict[name](c_name or parameter_name, parameter_name, self.function, value, **kwargs) + + kind = inspect.Parameter.KEYWORD_ONLY if self.keyword_only else inspect.Parameter.POSITIONAL_OR_KEYWORD - # special case: if it's the self converter, - # don't actually add it to the parameter list if isinstance(converter, self_converter): - if self.function.parameters or (self.parameter_state != self.ps_required): - fail("The 'self' parameter, if specified, must be the very first thing in the parameter block.") - if self.function.self_converter: - fail("You can't specify the 'self' parameter more than once.") - self.function.self_converter = converter - self.parameter_state = self.ps_start - return + if len(self.function.parameters) == 1: + if (self.parameter_state != self.ps_required): + fail("A 'self' parameter cannot be marked optional.") + if value is not unspecified: + fail("A 'self' parameter cannot have a default value.") + if self.group: + fail("A 'self' parameter cannot be in an optional group.") + kind = inspect.Parameter.POSITIONAL_ONLY + self.parameter_state = self.ps_start + self.function.parameters.clear() + else: + fail("A 'self' parameter, if specified, must be the very first thing in the parameter block.") - kind = inspect.Parameter.KEYWORD_ONLY if self.keyword_only else inspect.Parameter.POSITIONAL_OR_KEYWORD p = Parameter(parameter_name, kind, function=self.function, converter=converter, default=value, group=self.group) + + if parameter_name in self.function.parameters: + fail("You can't have two parameters named " + repr(parameter_name) + "!") self.function.parameters[parameter_name] = p def parse_converter(self, annotation): @@ -2310,10 +3843,13 @@ def parse_converter(self, annotation): if isinstance(annotation, ast.Name): return annotation.id, False, {} - assert isinstance(annotation, ast.Call) + if not isinstance(annotation, ast.Call): + fail("Annotations must be either a name, a function call, or a string.") name = annotation.func.id - kwargs = {node.arg: ast.literal_eval(node.value) for node in annotation.keywords} + symbols = globals() + + kwargs = {node.arg: eval_ast_expr(node.value, symbols) for node in annotation.keywords} return name, False, kwargs def parse_special_symbol(self, symbol): @@ -2330,8 +3866,9 @@ def parse_special_symbol(self, symbol): elif self.parameter_state in (self.ps_required, self.ps_group_after): self.parameter_state = self.ps_group_after else: - fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ")") + fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".b)") self.group += 1 + self.function.docstring_only = True elif symbol == ']': if not self.group: fail("Function " + self.function.name + " has a ] without a matching [.") @@ -2343,18 +3880,18 @@ def parse_special_symbol(self, symbol): elif self.parameter_state in (self.ps_group_after, self.ps_right_square_after): self.parameter_state = self.ps_right_square_after else: - fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ")") + fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".c)") elif symbol == '/': - # ps_required is allowed here, that allows positional-only without option groups + # ps_required and ps_optional are allowed here, that allows positional-only without option groups # to work (and have default values!) - if (self.parameter_state not in (self.ps_required, self.ps_right_square_after, self.ps_group_before)) or self.group: - fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ")") + if (self.parameter_state not in (self.ps_required, self.ps_optional, self.ps_right_square_after, self.ps_group_before)) or self.group: + fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".d)") if self.keyword_only: fail("Function " + self.function.name + " mixes keyword-only and positional-only parameters, which is unsupported.") self.parameter_state = self.ps_seen_slash - # fixup preceeding parameters + # fixup preceding parameters for p in self.function.parameters.values(): - if p.kind != inspect.Parameter.POSITIONAL_OR_KEYWORD: + if (p.kind != inspect.Parameter.POSITIONAL_OR_KEYWORD and not isinstance(p.converter, self_converter)): fail("Function " + self.function.name + " mixes keyword-only and positional-only parameters, which is unsupported.") p.kind = inspect.Parameter.POSITIONAL_ONLY @@ -2395,9 +3932,6 @@ def state_parameter_docstring(self, line): # the final stanza of the DSL is the docstring. def state_function_docstring(self, line): - if not self.function.self_converter: - self.function.self_converter = self_converter("self", self.function) - if self.group: fail("Function " + self.function.name + " has a ] without a matching [.") @@ -2418,28 +3952,46 @@ def state_function_docstring(self, line): def format_docstring(self): f = self.function - add, output = text_accumulator() - parameters = list(f.parameters.values()) + new_or_init = f.kind in (METHOD_NEW, METHOD_INIT) + if new_or_init and not f.docstring: + # don't render a docstring at all, no signature, nothing. + return f.docstring + + text, add, output = _text_accumulator() + parameters = f.render_parameters ## ## docstring first line ## - add(f.name) + if new_or_init: + # classes get *just* the name of the class + # not __new__, not __init__, and not module.classname + assert f.cls + add(f.cls.name) + else: + add(f.name) add('(') # populate "right_bracket_count" field for every parameter - if parameters: + assert parameters, "We should always have a self parameter. " + repr(f) + assert isinstance(parameters[0].converter, self_converter) + parameters[0].right_bracket_count = 0 + parameters_after_self = parameters[1:] + if parameters_after_self: # for now, the only way Clinic supports positional-only parameters - # is if all of them are positional-only. - positional_only_parameters = [p.kind == inspect.Parameter.POSITIONAL_ONLY for p in parameters] - if parameters[0].kind == inspect.Parameter.POSITIONAL_ONLY: + # is if all of them are positional-only... + # + # ... except for self! self is always positional-only. + + positional_only_parameters = [p.kind == inspect.Parameter.POSITIONAL_ONLY for p in parameters_after_self] + if parameters_after_self[0].kind == inspect.Parameter.POSITIONAL_ONLY: assert all(positional_only_parameters) for p in parameters: p.right_bracket_count = abs(p.group) else: # don't put any right brackets around non-positional-only parameters, ever. - for p in parameters: + for p in parameters_after_self: p.right_bracket_count = 0 right_bracket_count = 0 @@ -2455,36 +4007,122 @@ def fix_right_bracket_count(desired): right_bracket_count -= 1 return s + need_slash = False + added_slash = False + need_a_trailing_slash = False + + # we only need a trailing slash: + # * if this is not a "docstring_only" signature + # * and if the last *shown* parameter is + # positional only + if not f.docstring_only: + for p in reversed(parameters): + if not p.converter.show_in_signature: + continue + if p.is_positional_only(): + need_a_trailing_slash = True + break + + added_star = False - add_comma = False + + first_parameter = True + last_p = parameters[-1] + line_length = len(''.join(text)) + indent = " " * line_length + def add_parameter(text): + nonlocal line_length + nonlocal first_parameter + if first_parameter: + s = text + first_parameter = False + else: + s = ' ' + text + if line_length + len(s) >= 72: + add('\n') + add(indent) + line_length = len(indent) + s = text + line_length += len(s) + add(s) for p in parameters: + if not p.converter.show_in_signature: + continue assert p.name + is_self = isinstance(p.converter, self_converter) + if is_self and f.docstring_only: + # this isn't a real machine-parsable signature, + # so let's not print the "self" parameter + continue + + if p.is_positional_only(): + need_slash = not f.docstring_only + elif need_slash and not (added_slash or p.is_positional_only()): + added_slash = True + add_parameter('/,') + if p.is_keyword_only() and not added_star: added_star = True - if add_comma: - add(', ') - add('*') + add_parameter('*,') + + p_add, p_output = text_accumulator() + p_add(fix_right_bracket_count(p.right_bracket_count)) + + if isinstance(p.converter, self_converter): + # annotate first parameter as being a "self". + # + # if inspect.Signature gets this function, + # and it's already bound, the self parameter + # will be stripped off. + # + # if it's not bound, it should be marked + # as positional-only. + # + # note: we don't print "self" for __init__, + # because this isn't actually the signature + # for __init__. (it can't be, __init__ doesn't + # have a docstring.) if this is an __init__ + # (or __new__), then this signature is for + # calling the class to construct a new instance. + p_add('$') + + name = p.converter.signature_name or p.name + p_add(name) - a = [p.name] if p.converter.is_optional(): - a.append('=') - value = p.converter.default - a.append(p.converter.doc_default) - s = fix_right_bracket_count(p.right_bracket_count) - s += "".join(a) - if add_comma: - add(', ') - add(s) - add_comma = True + p_add('=') + value = p.converter.py_default + if not value: + value = repr(p.converter.default) + p_add(value) + + if (p != last_p) or need_a_trailing_slash: + p_add(',') + + add_parameter(p_output()) add(fix_right_bracket_count(0)) + if need_a_trailing_slash: + add_parameter('/') add(')') - # if f.return_converter.doc_default: + # PEP 8 says: + # + # The Python standard library will not use function annotations + # as that would result in a premature commitment to a particular + # annotation style. Instead, the annotations are left for users + # to discover and experiment with useful annotation styles. + # + # therefore this is commented out: + # + # if f.return_converter.py_default: # add(' -> ') - # add(f.return_converter.doc_default) + # add(f.return_converter.py_default) + + if not f.docstring_only: + add("\n" + sig_end_marker + "\n") docstring_first_line = output() @@ -2588,6 +4226,8 @@ def state_terminal(self, line): self.function.docstring = self.format_docstring() + + # maps strings to callables. # the callable should return an object # that implements the clinic parser @@ -2613,6 +4253,7 @@ def main(argv): cmdline = argparse.ArgumentParser() cmdline.add_argument("-f", "--force", action='http://github.com/store_true') cmdline.add_argument("-o", "--output", type=str) + cmdline.add_argument("-v", "--verbose", action='http://github.com/store_true') cmdline.add_argument("--converters", action='http://github.com/store_true') cmdline.add_argument("--make", action='http://github.com/store_true') cmdline.add_argument("filename", type=str, nargs="*") @@ -2674,23 +4315,9 @@ def main(argv): s = parameter_name parameters.append(s) print(' {}({})'.format(short_name, ', '.join(parameters))) - # add_comma = False - # for parameter_name, parameter in signature.parameters.items(): - # if parameter.kind == inspect.Parameter.KEYWORD_ONLY: - # if add_comma: - # parameters.append(', ') - # else: - # add_comma = True - # s = parameter_name - # if parameter.default != inspect.Parameter.empty: - # s += '=' + repr(parameter.default) - # parameters.append(s) - # parameters.append(')') - - # print(" ", short_name + "".join(parameters)) print() - print("All converters also accept (doc_default=None, required=False).") - print("All return converters also accept (doc_default=None).") + print("All converters also accept (c_default=None, py_default=None, annotation=None).") + print("All return converters also accept (py_default=None).") sys.exit(0) if ns.make: @@ -2700,14 +4327,16 @@ def main(argv): cmdline.print_usage() sys.exit(-1) for root, dirs, files in os.walk('.'): - for rcs_dir in ('.svn', '.git', '.hg'): + for rcs_dir in ('.svn', '.git', '.hg', 'build', 'externals'): if rcs_dir in dirs: dirs.remove(rcs_dir) for filename in files: - if not filename.endswith('.c'): + if not (filename.endswith('.c') or filename.endswith('.h')): continue path = os.path.join(root, filename) - parse_file(path, verify=not ns.force) + if ns.verbose: + print(path) + parse_file(path, force=ns.force, verify=not ns.force) return if not ns.filename: @@ -2721,7 +4350,9 @@ def main(argv): sys.exit(-1) for filename in ns.filename: - parse_file(filename, output=ns.output, verify=not ns.force) + if ns.verbose: + print(filename) + parse_file(filename, output=ns.output, force=ns.force, verify=not ns.force) if __name__ == "__main__": diff --git a/Tools/clinic/clinic_test.py b/Tools/clinic/clinic_test.py index 7baf3801bdac..cd21000c050c 100644 --- a/Tools/clinic/clinic_test.py +++ b/Tools/clinic/clinic_test.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 -# # Argument Clinic # Copyright 2012-2013 by Larry Hastings. # Licensed to the PSF under a contributor agreement. @@ -11,9 +9,11 @@ import collections import inspect from test import support +import sys import unittest from unittest import TestCase + class FakeConverter: def __init__(self, name, args): self.name = name @@ -35,16 +35,46 @@ def __init__(self): def get(self, name, default): return self.used_converters.setdefault(name, FakeConverterFactory(name)) +clinic.Clinic.presets_text = '' +c = clinic.Clinic(language='C') + class FakeClinic: def __init__(self): self.converters = FakeConvertersDict() self.legacy_converters = FakeConvertersDict() - self.language = clinic.CLanguage() + self.language = clinic.CLanguage(None) self.filename = None self.block_parser = clinic.BlockParser('', self.language) self.modules = collections.OrderedDict() + self.classes = collections.OrderedDict() clinic.clinic = self self.name = "FakeClinic" + self.line_prefix = self.line_suffix = '' + self.destinations = {} + self.add_destination("block", "buffer") + self.add_destination("file", "buffer") + self.add_destination("suppress", "suppress") + d = self.destinations.get + self.field_destinations = collections.OrderedDict(( + ('docstring_prototype', d('suppress')), + ('docstring_definition', d('block')), + ('methoddef_define', d('block')), + ('impl_prototype', d('block')), + ('parser_prototype', d('suppress')), + ('parser_definition', d('block')), + ('impl_definition', d('block')), + )) + + def get_destination(self, name): + d = self.destinations.get(name) + if not d: + sys.exit("Destination does not exist: " + repr(name)) + return d + + def add_destination(self, name, type, *args): + if name in self.destinations: + sys.exit("Destination already exists: " + repr(name)) + self.destinations[name] = clinic.Destination(name, type, self, *args) def is_directive(self, name): return name == "module" @@ -54,6 +84,25 @@ def directive(self, name, args): _module_and_class = clinic.Clinic._module_and_class +class ClinicWholeFileTest(TestCase): + def test_eol(self): + # regression test: + # clinic's block parser didn't recognize + # the "end line" for the block if it + # didn't end in "\n" (as in, the last) + # byte of the file was '/'. + # so it woudl spit out an end line for you. + # and since you really already had one, + # the last line of the block got corrupted. + c = clinic.Clinic(clinic.CLanguage(None)) + raw = "/*[clinic]\nfoo\n[clinic]*/" + cooked = c.parse(raw).splitlines() + end_line = cooked[2].rstrip() + # this test is redundant, it's just here explicitly to catch + # the regression test so we don't forget what it looked like + self.assertNotEqual(end_line, "[clinic]*/[clinic]*/") + self.assertEqual(end_line, "[clinic]*/") + class ClinicGroupPermuterTest(TestCase): @@ -173,7 +222,7 @@ def parse(self, block): class ClinicBlockParserTest(TestCase): def _test(self, input, output): - language = clinic.CLanguage() + language = clinic.CLanguage(None) blocks = list(clinic.BlockParser(input, language)) writer = clinic.BlockPrinter(language) @@ -203,7 +252,7 @@ def test_round_trip_2(self): """) def _test_clinic(self, input, output): - language = clinic.CLanguage() + language = clinic.CLanguage(None) c = clinic.Clinic(language) c.parsers['inert'] = InertParser(c) c.parsers['copy'] = CopyParser(c) @@ -214,20 +263,20 @@ def test_clinic_1(self): self._test_clinic(""" verbatim text here lah dee dah -/*[copy] +/*[copy input] def -[copy]*/ +[copy start generated code]*/ abc -/*[copy checksum: 03cfd743661f07975fa2f1220c5194cbaff48451]*/ +/*[copy end generated code: output=03cfd743661f0797 input=7b18d017f89f61cf]*/ xyz """, """ verbatim text here lah dee dah -/*[copy] +/*[copy input] def -[copy]*/ +[copy start generated code]*/ def -/*[copy checksum: 7b18d017f89f61cf17d47f92749ea6930a3f1deb]*/ +/*[copy end generated code: output=7b18d017f89f61cf input=7b18d017f89f61cf]*/ xyz """) @@ -250,7 +299,7 @@ def test_ignore_line(self): def test_param(self): function = self.parse_function("module os\nos.access\n path: int") self.assertEqual("access", function.name) - self.assertEqual(1, len(function.parameters)) + self.assertEqual(2, len(function.parameters)) p = function.parameters['path'] self.assertEqual('path', p.name) self.assertIsInstance(p.converter, clinic.int_converter) @@ -260,32 +309,46 @@ def test_param_default(self): p = function.parameters['follow_symlinks'] self.assertEqual(True, p.default) + def test_param_with_continuations(self): + function = self.parse_function("module os\nos.access\n follow_symlinks: \\\n bool \\\n =\\\n True") + p = function.parameters['follow_symlinks'] + self.assertEqual(True, p.default) + + def test_param_default_expression(self): + function = self.parse_function("module os\nos.access\n follow_symlinks: int(c_default='MAXSIZE') = sys.maxsize") + p = function.parameters['follow_symlinks'] + self.assertEqual(sys.maxsize, p.default) + self.assertEqual("MAXSIZE", p.converter.c_default) + + s = self.parse_function_should_fail("module os\nos.access\n follow_symlinks: int = sys.maxsize") + self.assertEqual(s, "Error on line 0:\nWhen you specify a named constant ('sys.maxsize') as your default value,\nyou MUST specify a valid c_default.\n") + def test_param_no_docstring(self): function = self.parse_function(""" module os os.access follow_symlinks: bool = True - something_else: str""") + something_else: str = ''""") p = function.parameters['follow_symlinks'] - self.assertEqual(2, len(function.parameters)) + self.assertEqual(3, len(function.parameters)) self.assertIsInstance(function.parameters['something_else'].converter, clinic.str_converter) + def test_param_default_parameters_out_of_order(self): + s = self.parse_function_should_fail(""" +module os +os.access + follow_symlinks: bool = True + something_else: str""") + self.assertEqual(s, """Error on line 0: +Can't have a parameter without a default ('something_else') +after a parameter with a default! +""") + def disabled_test_converter_arguments(self): function = self.parse_function("module os\nos.access\n path: path_t(allow_fd=1)") p = function.parameters['path'] self.assertEqual(1, p.converter.args['allow_fd']) - def test_param_docstring(self): - function = self.parse_function(""" -module os -os.stat as os_stat_fn -> object(doc_default='stat_result') - - path: str - Path to be examined""") - p = function.parameters['path'] - self.assertEqual("Path to be examined", p.docstring) - self.assertEqual(function.return_converter.doc_default, 'stat_result') - def test_function_docstring(self): function = self.parse_function(""" module os @@ -296,9 +359,11 @@ def test_function_docstring(self): Perform a stat system call on the given path.""") self.assertEqual(""" +stat($module, /, path) +-- + Perform a stat system call on the given path. -os.stat(path) path Path to be examined """.strip(), function.docstring) @@ -316,9 +381,11 @@ def test_explicit_parameters_in_docstring(self): Okay, we're done here. """) self.assertEqual(""" +bar($module, /, x, y) +-- + This is the documentation for foo. -foo.bar(x, y) x Documentation for x. @@ -332,7 +399,7 @@ def test_parser_regression_special_character_in_parameter_column_of_docstring_fi path: str This/used to break Clinic! """) - self.assertEqual("os.stat(path)\n\nThis/used to break Clinic!", function.docstring) + self.assertEqual("stat($module, /, path)\n--\n\nThis/used to break Clinic!", function.docstring) def test_c_name(self): function = self.parse_function("module os\nos.stat as os_stat_fn") @@ -356,7 +423,7 @@ def test_group(self): def test_left_group(self): function = self.parse_function(""" module curses -curses.window.addch +curses.addch [ y: int Y-coordinate. @@ -380,7 +447,9 @@ def test_left_group(self): self.assertEqual(p.group, group) self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY) self.assertEqual(function.docstring.strip(), """ -curses.window.addch([y, x,] ch, [attr]) +addch([y, x,] ch, [attr]) + + y Y-coordinate. x @@ -394,7 +463,7 @@ def test_left_group(self): def test_nested_groups(self): function = self.parse_function(""" module curses -curses.window.imaginary +curses.imaginary [ [ y1: int @@ -439,7 +508,10 @@ def test_nested_groups(self): self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY) self.assertEqual(function.docstring.strip(), """ -curses.window.imaginary([[y1, y2,] x1, x2,] ch, [attr1, attr2, attr3, [attr4, attr5, attr6]]) +imaginary([[y1, y2,] x1, x2,] ch, [attr1, attr2, attr3, [attr4, attr5, + attr6]]) + + y1 Y-coordinate. y2 @@ -484,7 +556,7 @@ def test_disallowed_grouping__two_top_groups_on_left(self): """) self.assertEqual(s, ('Error on line 0:\n' - 'Function two_top_groups_on_left has an unsupported group configuration. (Unexpected state 2)\n')) + 'Function two_top_groups_on_left has an unsupported group configuration. (Unexpected state 2.b)\n')) def test_disallowed_grouping__two_top_groups_on_right(self): self.parse_function_should_fail(""" @@ -557,8 +629,22 @@ def test_no_parameters(self): Docstring """) - self.assertEqual("Docstring\n\nfoo.bar()", function.docstring) - self.assertEqual(0, len(function.parameters)) + self.assertEqual("bar($module, /)\n--\n\nDocstring", function.docstring) + self.assertEqual(1, len(function.parameters)) # self! + + def test_init_with_no_parameters(self): + function = self.parse_function(""" +module foo +class foo.Bar "unused" "notneeded" +foo.Bar.__init__ + +Docstring + +""", signatures_in_block=3, function_index=2) + # self is not in the signature + self.assertEqual("Bar()\n--\n\nDocstring", function.docstring) + # but it *is* a parameter + self.assertEqual(1, len(function.parameters)) def test_illegal_module_line(self): self.parse_function_should_fail(""" @@ -652,9 +738,11 @@ def test_function_not_at_column_0(self): Not at column 0! """) self.assertEqual(""" +bar($module, /, x, *, y) +-- + Not at column 0! -foo.bar(x, *, y) x Nested docstring here, goeth. """.strip(), function.docstring) @@ -666,7 +754,7 @@ def test_parser_regression_special_character_in_parameter_column_of_docstring_fi path: str This/used to break Clinic! """) - self.assertEqual("This/used to break Clinic!\n\nos.stat(path)", function.docstring) + self.assertEqual("stat($module, /, path)\n--\n\nThis/used to break Clinic!", function.docstring) def test_directive(self): c = FakeClinic() @@ -689,13 +777,13 @@ def parse(self, text): parser.parse(block) return block - def parse_function(self, text): + def parse_function(self, text, signatures_in_block=2, function_index=1): block = self.parse(text) s = block.signatures - assert len(s) == 2 + self.assertEqual(len(s), signatures_in_block) assert isinstance(s[0], clinic.Module) - assert isinstance(s[1], clinic.Function) - return s[1] + assert isinstance(s[function_index], clinic.Function) + return s[function_index] def test_scaffolding(self): # test repr on special values diff --git a/Tools/clinic/cpp.py b/Tools/clinic/cpp.py new file mode 100644 index 000000000000..e099590a3326 --- /dev/null +++ b/Tools/clinic/cpp.py @@ -0,0 +1,191 @@ +import re +import sys + +def negate(condition): + """ + Returns a CPP conditional that is the opposite of the conditional passed in. + """ + if condition.startswith('!'): + return condition[1:] + return "!" + condition + +class Monitor: + """ + A simple C preprocessor that scans C source and computes, line by line, + what the current C preprocessor #if state is. + + Doesn't handle everything--for example, if you have /* inside a C string, + without a matching */ (also inside a C string), or with a */ inside a C + string but on another line and with preprocessor macros in between... + the parser will get lost. + + Anyway this implementation seems to work well enough for the CPython sources. + """ + + is_a_simple_defined = re.compile(r'^defined\s*\(\s*[A-Za-z0-9_]+\s*\)$').match + + def __init__(self, filename=None, *, verbose=False): + self.stack = [] + self.in_comment = False + self.continuation = None + self.line_number = 0 + self.filename = filename + self.verbose = verbose + + def __repr__(self): + return ''.join(( + '")) + + def status(self): + return str(self.line_number).rjust(4) + ": " + self.condition() + + def condition(self): + """ + Returns the current preprocessor state, as a single #if condition. + """ + return " && ".join(condition for token, condition in self.stack) + + def fail(self, *a): + if self.filename: + filename = " " + self.filename + else: + filename = '' + print("Error at" + filename, "line", self.line_number, ":") + print(" ", ' '.join(str(x) for x in a)) + sys.exit(-1) + + def close(self): + if self.stack: + self.fail("Ended file while still in a preprocessor conditional block!") + + def write(self, s): + for line in s.split("\n"): + self.writeline(line) + + def writeline(self, line): + self.line_number += 1 + line = line.strip() + + def pop_stack(): + if not self.stack: + self.fail("#" + token + " without matching #if / #ifdef / #ifndef!") + return self.stack.pop() + + if self.continuation: + line = self.continuation + line + self.continuation = None + + if not line: + return + + if line.endswith('\\'): + self.continuation = line[:-1].rstrip() + " " + return + + # we have to ignore preprocessor commands inside comments + # + # we also have to handle this: + # /* start + # ... + # */ /* <-- tricky! + # ... + # */ + # and this: + # /* start + # ... + # */ /* also tricky! */ + if self.in_comment: + if '*/' in line: + # snip out the comment and continue + # + # GCC allows + # /* comment + # */ #include + # maybe other compilers too? + _, _, line = line.partition('*/') + self.in_comment = False + + while True: + if '/*' in line: + if self.in_comment: + self.fail("Nested block comment!") + + before, _, remainder = line.partition('/*') + comment, comment_ends, after = remainder.partition('*/') + if comment_ends: + # snip out the comment + line = before.rstrip() + ' ' + after.lstrip() + continue + # comment continues to eol + self.in_comment = True + line = before.rstrip() + break + + # we actually have some // comments + # (but block comments take precedence) + before, line_comment, comment = line.partition('//') + if line_comment: + line = before.rstrip() + + if not line.startswith('#'): + return + + line = line[1:].lstrip() + assert line + + fields = line.split() + token = fields[0].lower() + condition = ' '.join(fields[1:]).strip() + + if_tokens = {'if', 'ifdef', 'ifndef'} + all_tokens = if_tokens | {'elif', 'else', 'endif'} + + if token not in all_tokens: + return + + # cheat a little here, to reuse the implementation of if + if token == 'elif': + pop_stack() + token = 'if' + + if token in if_tokens: + if not condition: + self.fail("Invalid format for #" + token + " line: no argument!") + if token == 'if': + if not self.is_a_simple_defined(condition): + condition = "(" + condition + ")" + else: + fields = condition.split() + if len(fields) != 1: + self.fail("Invalid format for #" + token + " line: should be exactly one argument!") + symbol = fields[0] + condition = 'defined(' + symbol + ')' + if token == 'ifndef': + condition = '!' + condition + + self.stack.append(("if", condition)) + if self.verbose: + print(self.status()) + return + + previous_token, previous_condition = pop_stack() + + if token == 'else': + self.stack.append(('else', negate(previous_condition))) + elif token == 'endif': + pass + if self.verbose: + print(self.status()) + +if __name__ == '__main__': + for filename in sys.argv[1:]: + with open(filename, "rt") as f: + cpp = Monitor(filename, verbose=True) + print() + print(filename) + for line_number, line in enumerate(f.read().split('\n'), 1): + cpp.writeline(line) diff --git a/Tools/demo/ss1.py b/Tools/demo/ss1.py index 649790f49308..c51f04193325 100755 --- a/Tools/demo/ss1.py +++ b/Tools/demo/ss1.py @@ -261,7 +261,7 @@ def start_value(self, attrs): def end_int(self, text): try: self.value = int(text) - except: + except (TypeError, ValueError): self.value = None end_long = end_int @@ -269,13 +269,13 @@ def end_int(self, text): def end_double(self, text): try: self.value = float(text) - except: + except (TypeError, ValueError): self.value = None def end_complex(self, text): try: self.value = complex(text) - except: + except (TypeError, ValueError): self.value = None def end_string(self, text): @@ -763,7 +763,7 @@ def change_cell(self): for cls in int, float, complex: try: value = cls(text) - except: + except (TypeError, ValueError): continue else: cell = NumericCell(value) diff --git a/Tools/freeze/README b/Tools/freeze/README index 81be2c84326a..5bc5b049d5b8 100644 --- a/Tools/freeze/README +++ b/Tools/freeze/README @@ -100,8 +100,8 @@ to place the Tcl and Tk library files in the distributed setup, and then declare these directories in your frozen Python program using the TCL_LIBRARY, TK_LIBRARY and TIX_LIBRARY environment variables. -For example, assume you will ship your frozen program in the directory -/bin/windows-x86 and will place your Tcl library files +For example, assume you will ship your frozen program in the directory +/bin/windows-x86 and will place your Tcl library files in /lib/tcl8.2 and your Tk library files in /lib/tk8.2. Then placing the following lines in your frozen Python script before importing Tkinter or Tix would set the environment correctly for Tcl/Tk/Tix: @@ -138,8 +138,8 @@ variable PATH is consulted, and under Unix, it may be the environment variable LD_LIBRARY_PATH and/or the system shared library cache (ld.so). An additional preferred directory for finding the dynamic libraries is built into the .dll or .so files at -compile time - see the LIB_RUNTIME_DIR variable in the Tcl makefile. -The OS must find the dynamic libraries or your frozen program won't start. +compile time - see the LIB_RUNTIME_DIR variable in the Tcl makefile. +The OS must find the dynamic libraries or your frozen program won't start. Usually I make sure that the .so or .dll files are in the same directory as the executable, but this may not be foolproof. @@ -149,8 +149,8 @@ incorporated in a frozen Python module as string literals and written to a temporary location when the program runs; this is currently left as an exercise for the reader. An easier approach is to freeze the Tcl/Tk/Tix code into the dynamic libraries using the Tcl ET code, -or the Tix Stand-Alone-Module code. Of course, you can also simply -require that Tcl/Tk is required on the target installation, but be +or the Tix Stand-Alone-Module code. Of course, you can also simply +require that Tcl/Tk is required on the target installation, but be careful that the version corresponds. There are some caveats using frozen Tkinter applications: @@ -164,7 +164,7 @@ program was frozen, not where it is run from. A warning about shared library modules -------------------------------------- -When your Python installation uses shared library modules such as +When your Python installation uses shared library modules such as _tkinter.pyd, these will not be incorporated in the frozen program. Again, the frozen program will work when you test it, but it won't work when you ship it to a site without a Python installation. @@ -275,9 +275,9 @@ Options: are read and the -i option replaced with the parsed params (note - quoting args in this file is NOT supported) --s subsystem: Specify the subsystem (For Windows only.); +-s subsystem: Specify the subsystem (For Windows only.); 'console' (default), 'windows', 'service' or 'com_dll' - + -w: Toggle Windows (NT or 95) behavior. (For debugging only -- on a win32 platform, win32 behavior is automatic.) diff --git a/Tools/freeze/bkfile.py b/Tools/freeze/bkfile.py index 58246fa2ad98..20a70b0639d2 100644 --- a/Tools/freeze/bkfile.py +++ b/Tools/freeze/bkfile.py @@ -1,49 +1,26 @@ -_orig_open = open +from builtins import open as _orig_open -class _BkFile: - def __init__(self, file, mode, bufsize): - import os - self.__filename = file - self.__backup = file + '~' - try: - os.unlink(self.__backup) - except OSError: - pass - try: - os.rename(file, self.__backup) - except OSError: - self.__backup = None - self.__file = _orig_open(file, mode, bufsize) - self.closed = self.__file.closed - self.fileno = self.__file.fileno - self.flush = self.__file.flush - self.isatty = self.__file.isatty - self.mode = self.__file.mode - self.name = self.__file.name - self.read = self.__file.read - try: - self.readinto = self.__file.readinto - except AttributeError: - pass - self.readline = self.__file.readline - self.readlines = self.__file.readlines - self.seek = self.__file.seek - self.tell = self.__file.tell - self.truncate = self.__file.truncate - self.write = self.__file.write - self.writelines = self.__file.writelines - - def close(self): - self.__file.close() - if self.__backup is None: - return - import filecmp - if filecmp.cmp(self.__backup, self.__filename, shallow = 0): - import os - os.unlink(self.__filename) - os.rename(self.__backup, self.__filename) - -def open(file, mode = 'r', bufsize = -1): +def open(file, mode='r', bufsize=-1): if 'w' not in mode: return _orig_open(file, mode, bufsize) - return _BkFile(file, mode, bufsize) + import os + backup = file + '~' + try: + os.unlink(backup) + except OSError: + pass + try: + os.rename(file, backup) + except OSError: + return _orig_open(file, mode, bufsize) + f = _orig_open(file, mode, bufsize) + _orig_close = f.close + def close(): + _orig_close() + import filecmp + if filecmp.cmp(backup, file, shallow=False): + import os + os.unlink(file) + os.rename(backup, file) + f.close = close + return f diff --git a/Tools/freeze/extensions_win32.ini b/Tools/freeze/extensions_win32.ini index 1e36abad57c9..d01fd6b9f520 100644 --- a/Tools/freeze/extensions_win32.ini +++ b/Tools/freeze/extensions_win32.ini @@ -6,7 +6,7 @@ ; This is all setup for all the win32 extension modules ; released by Mark Hammond. -; You must ensure that the environment variable PYTHONEX is set +; You must ensure that the environment variable PYTHONEX is set ; to point to the root win32 extensions directory ; PYTHONPREFIX must point to the Python build root directory @@ -49,7 +49,7 @@ dsp=%PYTHONPREFIX%\PCBuild\select.dsp [zlib] dsp=%PYTHONPREFIX%\PCBuild\zlib.dsp -cl=/I %PYTHONPREFIX%\..\zlib-1.1.4 /D _WINDOWS /D WIN32 +cl=/I %PYTHONPREFIX%\..\zlib-1.1.4 /D _WINDOWS /D WIN32 libs=%PYTHONPREFIX%\..\zlib-1.1.4\zlib.lib /nodefaultlib:libc [winreg] @@ -95,7 +95,7 @@ dsp=%PYTHONEX%\win32\win32event.dsp cl=/I %PYTHONEX%\win32\src [win32file] -dsp=%PYTHONEX%\win32\win32file.dsp +dsp=%PYTHONEX%\win32\win32file.dsp cl=/I %PYTHONEX%\win32\src [win32net] @@ -108,7 +108,7 @@ dsp=%PYTHONEX%\win32\win32pdh.dsp cl=/I %PYTHONEX%\win32\src [win32pipe] -dsp=%PYTHONEX%\win32\win32pipe.dsp +dsp=%PYTHONEX%\win32\win32pipe.dsp cl=/I %PYTHONEX%\win32\src [win32security] diff --git a/Tools/freeze/freeze.py b/Tools/freeze/freeze.py index 479ca3c14b47..c0758078f87e 100755 --- a/Tools/freeze/freeze.py +++ b/Tools/freeze/freeze.py @@ -219,6 +219,7 @@ def main(): # locations derived from options version = sys.version[:3] + flagged_version = version + sys.abiflags if win: extensions_c = 'frozen_extensions.c' if ishome: @@ -233,10 +234,11 @@ def main(): frozendllmain_c = os.path.join(exec_prefix, 'Pc\\frozen_dllmain.c') else: binlib = os.path.join(exec_prefix, - 'lib', 'python%s' % version, 'config') - incldir = os.path.join(prefix, 'include', 'python%s' % version) + 'lib', 'python%s' % version, + 'config-%s' % flagged_version) + incldir = os.path.join(prefix, 'include', 'python%s' % flagged_version) config_h_dir = os.path.join(exec_prefix, 'include', - 'python%s' % version) + 'python%s' % flagged_version) config_c_in = os.path.join(binlib, 'config.c.in') frozenmain_c = os.path.join(binlib, 'frozenmain.c') makefile_in = os.path.join(binlib, 'Makefile') @@ -363,6 +365,12 @@ def main(): else: mf.load_file(mod) + # Alias "importlib._bootstrap" to "_frozen_importlib" so that the + # import machinery can bootstrap. Do the same for + # importlib._bootstrap_external. + mf.modules["_frozen_importlib"] = mf.modules["importlib._bootstrap"] + mf.modules["_frozen_importlib_external"] = mf.modules["importlib._bootstrap_external"] + # Add the main script as either __main__, or the actual module name. if python_entry_is_main: mf.run_script(scriptfile) @@ -433,29 +441,21 @@ def main(): frozendllmain_c, os.path.basename(extensions_c)] + files maindefn = checkextensions_win32.CExtension( '__main__', xtras ) frozen_extensions.append( maindefn ) - outfp = open(makefile, 'w') - try: + with open(makefile, 'w') as outfp: winmakemakefile.makemakefile(outfp, locals(), frozen_extensions, os.path.basename(target)) - finally: - outfp.close() return # generate config.c and Makefile builtins.sort() - infp = open(config_c_in) - outfp = bkfile.open(config_c, 'w') - try: + with open(config_c_in) as infp, bkfile.open(config_c, 'w') as outfp: makeconfig.makeconfig(infp, outfp, builtins) - finally: - outfp.close() - infp.close() cflags = ['$(OPT)'] cppflags = defines + includes - libs = [os.path.join(binlib, 'libpython$(VERSION).a')] + libs = [os.path.join(binlib, '$(LDLIBRARY)')] somevars = {} if os.path.exists(makefile_in): @@ -469,11 +469,8 @@ def main(): files + supp_sources + addfiles + libs + \ ['$(MODLIBS)', '$(LIBS)', '$(SYSLIBS)'] - outfp = bkfile.open(makefile, 'w') - try: + with bkfile.open(makefile, 'w') as outfp: makemakefile.makemakefile(outfp, somevars, files, base_target) - finally: - outfp.close() # Done! diff --git a/Tools/freeze/makeconfig.py b/Tools/freeze/makeconfig.py index 018992c75347..fabaace07a83 100644 --- a/Tools/freeze/makeconfig.py +++ b/Tools/freeze/makeconfig.py @@ -3,7 +3,7 @@ # Write the config.c file -never = ['marshal', 'imp', '_ast', '__main__', 'builtins', +never = ['marshal', '_imp', '_ast', '__main__', 'builtins', 'sys', 'gc', '_warnings'] def makeconfig(infp, outfp, modules, with_ifdef=0): diff --git a/Tools/freeze/makefreeze.py b/Tools/freeze/makefreeze.py index ef18ec7b2861..64e3e6bf71e7 100644 --- a/Tools/freeze/makefreeze.py +++ b/Tools/freeze/makefreeze.py @@ -39,36 +39,34 @@ def makefreeze(base, dict, debug=0, entry_point=None, fail_import=()): mangled = "__".join(mod.split(".")) if m.__code__: file = 'M_' + mangled + '.c' - outfp = bkfile.open(base + file, 'w') - files.append(file) - if debug: - print("freezing", mod, "...") - str = marshal.dumps(m.__code__) - size = len(str) - if m.__path__: - # Indicate package by negative size - size = -size - done.append((mod, mangled, size)) - writecode(outfp, mangled, str) - outfp.close() + with bkfile.open(base + file, 'w') as outfp: + files.append(file) + if debug: + print("freezing", mod, "...") + str = marshal.dumps(m.__code__) + size = len(str) + if m.__path__: + # Indicate package by negative size + size = -size + done.append((mod, mangled, size)) + writecode(outfp, mangled, str) if debug: print("generating table of frozen modules") - outfp = bkfile.open(base + 'frozen.c', 'w') - for mod, mangled, size in done: - outfp.write('extern unsigned char M_%s[];\n' % mangled) - outfp.write(header) - for mod, mangled, size in done: - outfp.write('\t{"%s", M_%s, %d},\n' % (mod, mangled, size)) - outfp.write('\n') - # The following modules have a NULL code pointer, indicating - # that the frozen program should not search for them on the host - # system. Importing them will *always* raise an ImportError. - # The zero value size is never used. - for mod in fail_import: - outfp.write('\t{"%s", NULL, 0},\n' % (mod,)) - outfp.write(trailer) - outfp.write(entry_point) - outfp.close() + with bkfile.open(base + 'frozen.c', 'w') as outfp: + for mod, mangled, size in done: + outfp.write('extern unsigned char M_%s[];\n' % mangled) + outfp.write(header) + for mod, mangled, size in done: + outfp.write('\t{"%s", M_%s, %d},\n' % (mod, mangled, size)) + outfp.write('\n') + # The following modules have a NULL code pointer, indicating + # that the frozen program should not search for them on the host + # system. Importing them will *always* raise an ImportError. + # The zero value size is never used. + for mod in fail_import: + outfp.write('\t{"%s", NULL, 0},\n' % (mod,)) + outfp.write(trailer) + outfp.write(entry_point) return files diff --git a/Tools/freeze/test/Makefile b/Tools/freeze/test/Makefile new file mode 100644 index 000000000000..1679f723e7ac --- /dev/null +++ b/Tools/freeze/test/Makefile @@ -0,0 +1,11 @@ +# Makefile to test freeze +# set PYTHON to path of Python interpreter to test +PYTHON=python +# set OUTDIR to the temp directory for freeze +OUTDIR=outdir + +test: + $(PYTHON) ../freeze.py -o $(OUTDIR) ok.py + make -C $(OUTDIR) + $(OUTDIR)/ok + diff --git a/Tools/freeze/test/ok.py b/Tools/freeze/test/ok.py new file mode 100644 index 000000000000..e15e0b45032e --- /dev/null +++ b/Tools/freeze/test/ok.py @@ -0,0 +1,2 @@ +import sys +sys.exit(0) diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py old mode 100644 new mode 100755 diff --git a/Tools/hg/hgtouch.py b/Tools/hg/hgtouch.py index cf139202ea24..119d81214826 100644 --- a/Tools/hg/hgtouch.py +++ b/Tools/hg/hgtouch.py @@ -36,12 +36,16 @@ def parse_config(repo): result[o] = inputs return result -def check_rule(ui, repo, modified, output, inputs): +def check_rule(ui, repo, modified, basedir, output, inputs): """Verify that the output is newer than any of the inputs. Return (status, stamp), where status is True if the update succeeded, and stamp is the newest time stamp assigned to any file (might be in - the future).""" - f_output = repo.wjoin(output) + the future). + + If basedir is nonempty, it gives a directory in which the tree is to + be checked. + """ + f_output = repo.wjoin(os.path.join(basedir, output)) try: o_time = os.stat(f_output).st_mtime except OSError: @@ -51,7 +55,7 @@ def check_rule(ui, repo, modified, output, inputs): backdate = None backdate_source = None for i in inputs: - f_i = repo.wjoin(i) + f_i = repo.wjoin(os.path.join(basedir, i)) try: i_time = os.stat(f_i).st_mtime except OSError: @@ -79,8 +83,14 @@ def check_rule(ui, repo, modified, output, inputs): # Nothing to update return True, 0 -def do_touch(ui, repo): - modified = repo.status()[0] +def do_touch(ui, repo, basedir): + if basedir: + if not os.path.isdir(repo.wjoin(basedir)): + ui.warn("Abort: basedir %r does not exist\n" % basedir) + return + modified = [] + else: + modified = repo.status()[0] dependencies = parse_config(repo) success = True tstamp = 0 # newest time stamp assigned @@ -93,8 +103,8 @@ def do_touch(ui, repo): if i in dependencies: hold_back[output] = inputs continue - _success, _tstamp = check_rule(ui, repo, modified, output, inputs) - sucess = success and _success + _success, _tstamp = check_rule(ui, repo, modified, basedir, output, inputs) + success = success and _success tstamp = max(tstamp, _tstamp) # put back held back rules dependencies.update(hold_back) @@ -109,11 +119,12 @@ def do_touch(ui, repo): return False return success -def touch(ui, repo): +def touch(ui, repo, basedir): "touch generated files that are older than their sources after an update." - do_touch(ui, repo) + do_touch(ui, repo, basedir) cmdtable = { - "touch": (touch, [], - "touch generated files according to the .hgtouch configuration") + "touch": (touch, + [('b', 'basedir', '', 'base dir of the tree to apply touching')], + "hg touch [-b BASEDIR]") } diff --git a/Tools/i18n/makelocalealias.py b/Tools/i18n/makelocalealias.py old mode 100644 new mode 100755 index 68544ac27b9b..c7ecacec3877 --- a/Tools/i18n/makelocalealias.py +++ b/Tools/i18n/makelocalealias.py @@ -7,14 +7,18 @@ """ import locale +import sys +_locale = locale -# Location of the alias file +# Location of the X11 alias file. LOCALE_ALIAS = '/usr/share/X11/locale/locale.alias' +# Location of the glibc SUPPORTED locales file. +SUPPORTED = '/usr/share/i18n/SUPPORTED' def parse(filename): - f = open(filename) - lines = f.read().splitlines() + with open(filename, encoding='latin1') as f: + lines = list(f) data = {} for line in lines: line = line.strip() @@ -23,6 +27,12 @@ def parse(filename): if line[:1] == '#': continue locale, alias = line.split() + # Fix non-standard locale names, e.g. ks_IN@devanagari.UTF-8 + if '@' in alias: + alias_lang, _, alias_mod = alias.partition('@') + if '.' in alias_mod: + alias_mod, _, alias_enc = alias_mod.partition('.') + alias = alias_lang + '.' + alias_enc + '@' + alias_mod # Strip ':' if locale[-1] == ':': locale = locale[:-1] @@ -37,31 +47,102 @@ def parse(filename): encoding = encoding.replace('-', '') encoding = encoding.replace('_', '') locale = lang + '.' + encoding - if encoding.lower() == 'utf8': - # Ignore UTF-8 mappings - this encoding should be - # available for all locales - continue + data[locale] = alias + return data + +def parse_glibc_supported(filename): + + with open(filename, encoding='latin1') as f: + lines = list(f) + data = {} + for line in lines: + line = line.strip() + if not line: + continue + if line[:1] == '#': + continue + line = line.replace('/', ' ').strip() + line = line.rstrip('\\').rstrip() + words = line.split() + if len(words) != 2: + continue + alias, alias_encoding = words + # Lower-case locale + locale = alias.lower() + # Normalize encoding, if given + if '.' in locale: + lang, encoding = locale.split('.')[:2] + encoding = encoding.replace('-', '') + encoding = encoding.replace('_', '') + locale = lang + '.' + encoding + # Add an encoding to alias + alias, _, modifier = alias.partition('@') + alias = _locale._replace_encoding(alias, alias_encoding) + if modifier and not (modifier == 'euro' and alias_encoding == 'ISO-8859-15'): + alias += '@' + modifier data[locale] = alias return data def pprint(data): items = sorted(data.items()) for k, v in items: - print(' %-40s%r,' % ('%r:' % k, v)) + print(' %-40s%a,' % ('%a:' % k, v)) def print_differences(data, olddata): items = sorted(olddata.items()) for k, v in items: if k not in data: - print('# removed %r' % k) + print('# removed %a' % k) elif olddata[k] != data[k]: - print('# updated %r -> %r to %r' % \ + print('# updated %a -> %a to %a' % \ (k, olddata[k], data[k])) # Additions are not mentioned +def optimize(data): + locale_alias = locale.locale_alias + locale.locale_alias = data.copy() + for k, v in data.items(): + del locale.locale_alias[k] + if locale.normalize(k) != v: + locale.locale_alias[k] = v + newdata = locale.locale_alias + errors = check(data) + locale.locale_alias = locale_alias + if errors: + sys.exit(1) + return newdata + +def check(data): + # Check that all alias definitions from the X11 file + # are actually mapped to the correct alias locales. + errors = 0 + for k, v in data.items(): + if locale.normalize(k) != v: + print('ERROR: %a -> %a != %a' % (k, locale.normalize(k), v), + file=sys.stderr) + errors += 1 + return errors + if __name__ == '__main__': + import argparse + parser = argparse.ArgumentParser() + parser.add_argument('--locale-alias', default=LOCALE_ALIAS, + help='location of the X11 alias file ' + '(default: %a)' % LOCALE_ALIAS) + parser.add_argument('--glibc-supported', default=SUPPORTED, + help='location of the glibc SUPPORTED locales file ' + '(default: %a)' % SUPPORTED) + args = parser.parse_args() + data = locale.locale_alias.copy() - data.update(parse(LOCALE_ALIAS)) + data.update(parse_glibc_supported(args.glibc_supported)) + data.update(parse(args.locale_alias)) + while True: + # Repeat optimization while the size is decreased. + n = len(data) + data = optimize(data) + if len(data) == n: + break print_differences(data, locale.locale_alias) print() print('locale_alias = {') diff --git a/Tools/i18n/pygettext.py b/Tools/i18n/pygettext.py index 79d976bc01fe..3c6c14c8362e 100755 --- a/Tools/i18n/pygettext.py +++ b/Tools/i18n/pygettext.py @@ -1,6 +1,6 @@ #! /usr/bin/env python3 # -*- coding: iso-8859-1 -*- -# Originally written by Barry Warsaw +# Originally written by Barry Warsaw # # Minimally patched to make it even more xgettext compatible # by Peter Funk @@ -441,9 +441,7 @@ def set_filename(self, filename): def write(self, fp): options = self.__options - timestamp = time.strftime('%Y-%m-%d %H:%M+%Z') - # The time stamp in the header doesn't have the same format as that - # generated by xgettext... + timestamp = time.strftime('%Y-%m-%d %H:%M%z') encoding = fp.encoding if fp.encoding else 'UTF-8' print(pot_header % {'time': timestamp, 'version': __version__, 'charset': encoding, diff --git a/Tools/msi/README.txt b/Tools/msi/README.txt index dc4ae90cf2b9..25dcf32c2c46 100644 --- a/Tools/msi/README.txt +++ b/Tools/msi/README.txt @@ -1,25 +1,492 @@ -Packaging Python as a Microsoft Installer Package (MSI) -======================================================= - -Using this library, Python can be packaged as a MS-Windows -MSI file. To generate an installer package, you need -a build tree. By default, the build tree root directory -is assumed to be in "../..". This location can be changed -by adding a file config.py; see the beginning of msi.py -for additional customization options. - -The packaging process assumes that binaries have been -generated according to the instructions in PCBuild/README.txt, -and that you have either Visual Studio or the Platform SDK -installed. In addition, you need the Python COM extensions, -either from PythonWin, or from ActivePython. - -To invoke the script, open a cmd.exe window which has -cabarc.exe in its PATH (e.g. "Visual Studio .NET 2003 -Command Prompt"). Then invoke - - msi.py - -If everything succeeds, pythonX.Y.Z.msi is generated -in the current directory. +Quick Build Info +================ + +For testing, the installer should be built with the Tools/msi/build.bat +script: + + build.bat [-x86] [-x64] [--doc] + +For an official release, the installer should be built with the +Tools/msi/buildrelease.bat script and environment variables: + + set PYTHON= + set SPHINXBUILD= + set PATH=; + ;%PATH% + + buildrelease.bat [-x86] [-x64] [-D] [-B] + [-o ] [-c ] + +See the Building the Installer section for more information. + +Overview +======== + +Python is distributed on Windows as an installer that will configure the +user's system. This allows users to have a functioning copy of Python +without having to build it themselves. + +The main tasks of the installer are: + +* copy required files into the expected layout +* configure system settings so the installation can be located by + other programs +* add entry points for modifying, repairing and uninstalling Python +* make it easy to launch Python, its documentation, and IDLE + +Each of these is discussed in a later section of this document. + +Structure of the Installer +========================== + +The installer is structured as a 'layout', which consists of a number of +CAB and MSI files and a single EXE. + +The EXE is the main entry point into the installer. It contains the UI +and command-line logic, as well as the ability to locate and optionally +download other parts of the layout. + +Each MSI contains the logic required to install a component or feature +of Python. These MSIs should not be launched directly by users. MSIs can +be embedded into the EXE or automatically downloaded as needed. + +Each CAB contains the files making up a Python installation. CABs are +embedded into their associated MSI and are never seen by users. + +MSIs are only required when the related feature or component is being +installed. When components are not selected for installation, the +associated MSI is not downloaded. This allows the installer to offer +options to install debugging symbols and binaries without increasing +the initial download size by separating them into their own MSIs. + +Building the Installer +====================== + +For testing, the installer should be built with the Tools/msi/build.bat +script: + + build.bat [-x86] [-x64] [--doc] + +This script will build the required configurations of Python and +generate an installer layout in PCBuild/(win32|amd64)/en-us. + +Specify -x86 and/or -x64 to build for each platform. If neither is +specified, both platforms will be built. Currently, both the debug and +release versions of Python are required for the installer. + +Specify --doc to build the documentation (.chm) file. If the file is not +available, it will simply be excluded from the installer. Ensure +%PYTHON% and %SPHINXBUILD% are set when passing this option. You may +also set %HTMLHELP% to the Html Help Compiler (hhc.exe), or put HHC on +your PATH or in externals/. + +If WiX is not found on your system, it will be automatically downloaded +and extracted to the externals/ directory. + + +For an official release, the installer should be built with the +Tools/msi/buildrelease.bat script: + + set PYTHON= + set SPHINXBUILD= + set PATH=; + ;%PATH% + + buildrelease.bat [-x86] [-x64] [-D] [-B] + [-o ] [-c ] + +Specify -x86 and/or -x64 to build for each platform. If neither is +specified, both platforms will be built. Currently, both the debug and +release versions of Python are required for the installer. + +Specify -D to skip rebuilding the documentation. The documentation is +required for a release and the build will fail if it is not available. + +Specify -B to skip rebuilding Python. This is useful to only rebuild the +installer layout after a previous call to buildrelease.bat. + +Specify -o to set an output directory. The installer layouts will be +copied to platform-specific subdirectories of this path. + +Specify -c to choose a code-signing certificate to be used for all the +signable binaries in Python as well as each file making up the +installer. Official releases of Python must be signed. + +Ensure %PYTHON% and %SPHINXBUILD% are set when passing this option. You +may also set %HTMLHELP% to the Html Help Compiler (hhc.exe), or put HHC +on your PATH or in externals/. You will also need Mercurial (hg.exe) on +your PATH. + +If WiX is not found on your system, it will be automatically downloaded +and extracted to the externals/ directory. + +To manually build layouts of the installer, build one of the projects in +the bundle folder. + + msbuild bundle\snapshot.wixproj + msbuild bundle\releaseweb.wixproj + msbuild bundle\releaselocal.wixproj + msbuild bundle\full.wixproj + +snapshot.wixproj produces a test installer versioned based on the date. + +releaseweb.wixproj produces a release installer that does not embed any +of the layout. + +releaselocal.wixproj produces a release installer that embeds the files +required for a default installation. + +full.wixproj produces a test installer that embeds the entire layout. + +The following properties may be passed when building these projects. + + /p:BuildForRelease=(true|false) + When true, adds extra verification to ensure a complete installer is + produced. For example, binutils is required when building for a release + to generate MinGW-compatible libraries, and the build will be aborted if + this fails. Defaults to false. + + /p:ReleaseUri=(any URI) + Used to generate unique IDs for the installers to allow side-by-side + installation. Forks of Python can use the same installer infrastructure + by providing a unique URI for this property. It does not need to be an + active internet address. Defaults to $(ComputerName). + + Official releases use http://www.python.org/(architecture name) + + /p:DownloadUrlBase=(any URI) + Specifies the base of a URL where missing parts of the installer layout + can be downloaded from. The build version and architecture will be + appended to create the full address. If omitted, missing components will + not be automatically downloaded. + + /p:DownloadUrl=(any URI) + Specifies the full URL where missing parts of the installer layout can + be downloaded from. Should normally include '{2}', which will be + substituted for the filename. If omitted, missing components will not be + automatically downloaded. If specified, this value overrides + DownloadUrlBase. + + /p:SigningCertificate=(certificate name) + Specifies the certificate to sign the installer layout with. If omitted, + the layout will not be signed. + + /p:RebuildAll=(true|false) + When true, rebuilds all of the MSIs making up the layout. Defaults to + true. + +Modifying the Installer +======================= + +The code for the installer is divided into three main groups: packages, +the bundle and the bootstrap application. + +Packages +-------- + +Packages appear as subdirectories of Tools/msi (other than the bundle/ +directory). The project file is a .wixproj and the build output is a +single MSI. Packages are built with the WiX Toolset. Some project files +share source files and use preprocessor directives to enable particular +features. These are typically used to keep the sources close when the +files are related, but produce multiple independent packages. + +A package is the smallest element that may be independently installed or +uninstalled (as used in this installer). For example, the test suite has +its own package, as users can choose to add or remove it after the +initial installation. + +All the files installed by a single package should be related, though +some packages may not install any files. For example, the pip package +executes the ensurepip package, but does not add or remove any of its +own files. (It is represented as a package because of its +installed/uninstalled nature, as opposed to the "precompile standard +library" option, for example.) Dependencies between packages are handled +by the bundle, but packages should detect when dependencies are missing +and raise an error. + +Packages that include a lot of files may use an InstallFiles element in +the .wixproj file to generate sources. See lib/lib.wixproj for an +example, and msi.targets and csv_to_wxs.py for the implementation. This +element is also responsible for generating the code for cleaning up and +removing __pycache__ folders in any directory containing .py files. + +All packages are built with the Tools/msi/common.wxs file, and so any +directory or property in this file may be referenced. Of particular +interest: + + REGISTRYKEY (property) + The registry key for the current installation. + + InstallDirectory (directory) + The root install directory for the current installation. Subdirectories + are also specified in this file (DLLs, Lib, etc.) + + MenuDir (directory) + The Start Menu folder for the current installation. + + UpgradeTable (property) + Every package should reference this property to include upgrade + information. + + OptionalFeature (Component) + Packages that may be enabled or disabled should reference this component + and have an OPTIONAL_FEATURES entry in the bootstrap application to + properly handle Modify and Upgrade. + +The .wxl_template file is specially handled by the build system for this +project to perform {{substitutions}} as defined in msi.targets. They +should be included in projects as items, where .wxl files +are normally included as items. + +Bundle +------ + +The bundle is compiled to the main EXE entry point that for most users +will represent the Python installer. It is built from Tools/msi/bundle +with packages references in Tools/msi/bundle/packagegroups. + +Build logic for the bundle is in bundle.targets, but should be invoked +through one of the .wixproj files as described in Building the +Installer. + +The UI is separated between Default.thm (UI layout), Default.wxl +(strings), bundle.wxs (properties) and the bootstrap application. +Bundle.wxs also contains the chain, which is the list of packages to +install and the order they should be installed in. These refer to named +package groups in bundle/packagegroups. + +Each package group specifies one or more packages to install. Most +packages require two separate entries to support both per-user and +all-users installations. Because these reuse the same package, it does +not increase the overall size of the package. + +Package groups refer to payload groups, which allow better control over +embedding and downloading files than the default settings. Whether files +are embedded and where they are downloaded from depends on settings +created by the project files. + +Package references can include install conditions that determine when to +install the package. When a package is a dependency for others, the +condition should be crafted to ensure it is installed. + +MSI packages are installed or uninstalled based on their current state +and the install condition. This makes them most suitable for features +that are clearly present or absent from the user's machine. + +EXE packages are executed based on a customisable condition that can be +omitted. This makes them suitable for pre- or post-install tasks that +need to run regardless of whether features have been added or removed. + +Bootstrap Application +--------------------- + +The bootstrap application is a C++ application that controls the UI and +installation. While it does not directly compile into the main EXE of +the installer, it forms the main active component. Most of the +installation functionality is provided by WiX, and so the bootstrap +application is predominantly responsible for the code behind the UI that +is defined in the Default.thm file. The bootstrap application code is in +bundle/bootstrap and is built automatically when building the bundle. + +Installation Layout +=================== + +There are two installation layouts for Python on Windows, with the only +differences being supporting files. A layout is selected implicitly +based on whether the install is for all users of the machine or just for +the user performing the installation. + +The default installation location when installing for all users is +"%ProgramFiles%\Python 3.X" for the 64-bit interpreter and +"%ProgramFiles(x86)%\Python 3.X" for the 32-bit interpreter. (Note that +the latter path is equivalent to "%ProgramFiles%\Python 3.X" when +running a 32-bit version of Windows.) This location requires +administrative privileges to install or later modify the installation. + +The default installation location when installing for the current user +is "%LocalAppData%\Programs\Python\Python3X" for the 64-bit interpreter +and "%LocalAppData%\Programs\Python\Python3X-32" for the 32-bit +interpreter. Only the current user can access this location. This +provides a suitable level of protection against malicious modification +of Python's files. + +Within this install directory is the following approximate layout: + +.\python[w].exe The core executable files +.\DLLs Stdlib extensions (*.pyd) and dependencies +.\Doc Documentation (*.chm) +.\include Development headers (*.h) +.\Lib Standard library +.\Lib\test Test suite +.\libs Development libraries (*.lib) +.\Scripts Launcher scripts (*.exe, *.py) +.\tcl Tcl dependencies (*.dll, *.tcl and others) +.\Tools Tool scripts (*.py) + +When installed for all users, the following files are installed to +either "%SystemRoot%\System32" or "%SystemRoot%\SysWOW64" as +appropriate. For the current user, they are installed in the Python +install directory. + +.\python3x.dll The core interpreter +.\python3.dll The stable ABI reference + +When installed for all users, the following files are installed to +"%SystemRoot%" (typically "C:\Windows") to ensure they are always +available on PATH. (See Launching Python below.) For the current user, +they are installed in "%LocalAppData%\Programs\Python\PyLauncher". + +.\py[w].exe PEP 397 launcher + +System Settings +=============== + +On installation, registry keys are created so that other applications +can locate and identify installations of Python. The locations of these +keys vary based on the install type. + +For 64-bit interpreters installed for all users, the root key is: + HKEY_LOCAL_MACHINE\Software\Python\PythonCore\3.X + +For 32-bit interpreters installed for all users on a 64-bit operating +system, the root key is: + HKEY_LOCAL_MACHINE\Software\Wow6432Node\Python\PythonCore\3.X-32 + +For 32-bit interpreters installed for all users on a 32-bit operating +system, the root key is: + HKEY_LOCAL_MACHINE\Software\Python\PythonCore\3.X-32 + +For 64-bit interpreters installed for the current user: + HKEY_CURRENT_USER\Software\Python\PythonCore\3.X + +For 32-bit interpreters installed for the current user: + HKEY_CURRENT_USER\Software\Python\PythonCore\3.X-32 + +When the core Python executables are installed, a key "InstallPath" is +created within the root key with its default value set to the +executable's install directory. A value named "ExecutablePath" is added +with the full path to the main Python interpreter, and a key +"InstallGroup" is created with its default value set to the product +name "Python 3.X". + +When the Python standard library is installed, a key "PythonPath" is +created within the root key with its default value set to the full path +to the Lib folder followed by the path to the DLLs folder, separated by +a semicolon. + +When the documentation is installed, a key "Help" is created within the +root key, with a subkey "Main Python Documentation" with its default +value set to the full path to the installed CHM file. + + +The py.exe launcher is installed as part of a regular Python install, +but using a separate mechanism that allows it to more easily span +versions of Python. As a result, it has different root keys for its +registry entries: + +When installed for all users on a 64-bit operating system, the +launcher's root key is: + HKEY_LOCAL_MACHINE\Software\Wow6432Node\Python\Launcher + +When installed for all users on a 32-bit operating system, the +launcher's root key is: + HKEY_LOCAL_MACHINE\Software\Python\Launcher + +When installed for the current user: + HKEY_CURRENT_USER\Software\Python\Launcher + +When the launcher is installed, a key "InstallPath" is created within +its root key with its default value set to the launcher's install +directory. File associations are also created for .py, .pyw, .pyc and +.pyo files. + +Launching Python +================ + +When a feature offering user entry points in the Start Menu is +installed, a folder "Python 3.X" is created. Every shortcut should be +created within this folder, and each shortcut should include the version +and platform to allow users to identify the shortcut in a search results +page. + +The core Python executables creates a shortcut "Python 3.X (32-bit)" or +"Python 3.X (64-bit)" depending on the interpreter. + +The documentation creates a shortcut "Python 3.X 32-bit Manuals" or +"Python 3.X 64-bit Manuals". The documentation is identical for all +platforms, but the shortcuts need to be separate to avoid uninstallation +conflicts. + +Installing IDLE creates a shortcut "IDLE (Python 3.X 32-bit)" or "IDLE +(Python 3.X 64-bit)" depending on the interpreter. + + +For users who often launch Python from a Command Prompt, an option is +provided to add the directory containing python.exe to the user or +system PATH variable. If the option is selected, the install directory +and the Scripts directory will be added at the start of the system PATH +for an all users install and the user PATH for a per-user install. + +When the user only has one version of Python installed, this will behave +as expected. However, because Windows searches the system PATH before +the user PATH, users cannot override a system-wide installation of +Python on their PATH. Further, because the installer can only prepend to +the path, later installations of Python will take precedence over +earlier installations, regardless of interpreter version. + +Because it is not possible to automatically create a sensible PATH +configuration, users are recommended to use the py.exe launcher and +manually modify their PATH variable to add Scripts directories in their +preferred order. System-wide installations of Python should consider not +modifying PATH, or using an alternative technology to modify their +users' PATH variables. + + +The py.exe launcher is recommended because it uses a consistent and +sensible search order for Python installations. User installations are +preferred over system-wide installs, and later versions are preferred +regardless of installation order (with the exception that py.exe +currently prefers 2.x versions over 3.x versions without the -3 command +line argument). + +For both 32-bit and 64-bit interpreters, the 32-bit version of the +launcher is installed. This ensures that the search order is always +consistent (as the 64-bit launcher is subtly different from the 32-bit +launcher) and also avoids the need to install it multiple times. Future +versions of Python will upgrade the launcher in-place, using Windows +Installer's upgrade functionality to avoid conflicts with earlier +installed versions. + +When installed, file associations are created for .py, .pyc and .pyo +files to launch with py.exe and .pyw files to launch with pyw.exe. This +makes Python files respect shebang lines by default and also avoids +conflicts between multiple Python installations. + + +Repair, Modify and Uninstall +============================ + +After installation, Python may be modified, repaired or uninstalled by +running the original EXE again or via the Programs and Features applet +(formerly known as Add or Remove Programs). + +Modifications allow features to be added or removed. The install +directory and kind (all users/single user) cannot be modified. Because +Windows Installer caches installation packages, removing features will +not require internet access unless the package cache has been corrupted +or deleted. Adding features that were not previously installed and are +not embedded or otherwise available will require internet access. + +Repairing will rerun the installation for all currently installed +features, restoring files and registry keys that have been modified or +removed. This operation generally will not redownload any files unless +the cached packages have been corrupted or deleted. + +Removing Python will clean up all the files and registry keys that were +created by the installer, as well as __pycache__ folders that are +explicitly handled by the installer. Python packages installed later +using a tool like pip will not be removed. Some components may be +installed by other installers (such as the MSVCRT) and these will not be +removed if another product has a dependency on them. diff --git a/Tools/msi/build.bat b/Tools/msi/build.bat new file mode 100644 index 000000000000..5f53a1be6cbc --- /dev/null +++ b/Tools/msi/build.bat @@ -0,0 +1,70 @@ +@echo off +setlocal +set D=%~dp0 +set PCBUILD=%D%..\..\PCBuild\ + +set BUILDX86= +set BUILDX64= +set BUILDDOC= +set BUILDPX= +set BUILDPACK= + +:CheckOpts +if "%~1" EQU "-h" goto Help +if "%~1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts +if "%~1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts +if "%~1" EQU "--doc" (set BUILDDOC=1) && shift && goto CheckOpts +if "%~1" EQU "--test-marker" (set BUILDPX=1) && shift && goto CheckOpts +if "%~1" EQU "--pack" (set BUILDPACK=1) && shift && goto CheckOpts + +if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1) + +call "%PCBUILD%env.bat" x86 + +if defined BUILDX86 ( + call "%PCBUILD%build.bat" -d -e + if errorlevel 1 goto :eof + call "%PCBUILD%build.bat" -e + if errorlevel 1 goto :eof +) +if defined BUILDX64 ( + call "%PCBUILD%build.bat" -p x64 -d -e + if errorlevel 1 goto :eof + call "%PCBUILD%build.bat" -p x64 -e + if errorlevel 1 goto :eof +) + +if defined BUILDDOC ( + call "%PCBUILD%..\Doc\make.bat" htmlhelp + if errorlevel 1 goto :eof +) + +set BUILD_CMD="%D%bundle\snapshot.wixproj" +if defined BUILDPX ( + set BUILD_CMD=%BUILD_CMD% /p:UseTestMarker=true +) +if defined BUILDPACK ( + set BUILD_CMD=%BUILD_CMD% /p:Pack=true +) + +if defined BUILDX86 ( + "%PCBUILD%win32\python.exe" "%D%get_wix.py" + msbuild %BUILD_CMD% + if errorlevel 1 goto :eof +) +if defined BUILDX64 ( + "%PCBUILD%amd64\python.exe" "%D%get_wix.py" + msbuild /p:Platform=x64 %BUILD_CMD% + if errorlevel 1 goto :eof +) + +exit /B 0 + +:Help +echo build.bat [-x86] [-x64] [--doc] [-h] [--test-marker] [--pack] +echo. +echo -x86 Build x86 installers +echo -x64 Build x64 installers +echo --doc Build CHM documentation +echo --test-marker Build installers with 'x' markers +echo --pack Embed core MSIs into installer diff --git a/Tools/msi/buildrelease.bat b/Tools/msi/buildrelease.bat new file mode 100644 index 000000000000..ca08df840323 --- /dev/null +++ b/Tools/msi/buildrelease.bat @@ -0,0 +1,226 @@ +@setlocal +@echo off + +rem This script is intended for building official releases of Python. +rem To use it to build alternative releases, you should clone this file +rem and modify the following three URIs. + +rem These two will ensure that your release can be installed +rem alongside an official Python release, by modifying the GUIDs used +rem for all components. +rem +rem The following substitutions will be applied to the release URI: +rem Variable Description Example +rem {arch} architecture amd64, win32 +set RELEASE_URI=http://www.python.org/{arch} + +rem This is the URL that will be used to download installation files. +rem The files available from the default URL *will* conflict with your +rem installer. Trust me, you don't want them, even if it seems like a +rem good idea. +rem +rem The following substitutions will be applied to the download URL: +rem Variable Description Example +rem {version} version number 3.5.0 +rem {arch} architecture amd64, win32 +rem {releasename} release name a1, b2, rc3 (or blank for final) +rem {msi} MSI filename core.msi +set DOWNLOAD_URL=https://www.python.org/ftp/python/{version}/{arch}{releasename}/{msi} + +set D=%~dp0 +set PCBUILD=%D%..\..\PCBuild\ + +set BUILDX86= +set BUILDX64= +set TARGET=Rebuild +set TESTTARGETDIR= +set PGO= + + +:CheckOpts +if "%1" EQU "-h" goto Help +if "%1" EQU "-c" (set CERTNAME=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--certificate" (set CERTNAME=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-o" (set OUTDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--out" (set OUTDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-D" (set SKIPDOC=1) && shift && goto CheckOpts +if "%1" EQU "--skip-doc" (set SKIPDOC=1) && shift && goto CheckOpts +if "%1" EQU "-B" (set SKIPBUILD=1) && shift && goto CheckOpts +if "%1" EQU "--skip-build" (set SKIPBUILD=1) && shift && goto CheckOpts +if "%1" EQU "--download" (set DOWNLOAD_URL=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--test" (set TESTTARGETDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-b" (set TARGET=Build) && shift && goto CheckOpts +if "%1" EQU "--build" (set TARGET=Build) && shift && goto CheckOpts +if "%1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts +if "%1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts +if "%1" EQU "--pgo" (set PGO=%~2) && shift && shift && goto CheckOpts + +if "%1" NEQ "" echo Invalid option: "%1" && exit /B 1 + +if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1) + +:builddoc +if "%SKIPBUILD%" EQU "1" goto skipdoc +if "%SKIPDOC%" EQU "1" goto skipdoc + +if not defined PYTHON where py -q || echo Cannot find py on path and PYTHON is not set. && exit /B 1 +if not defined SPHINXBUILD where sphinx-build -q || echo Cannot find sphinx-build on path and SPHINXBUILD is not set. && exit /B 1 +call "%D%..\..\doc\make.bat" htmlhelp +if errorlevel 1 goto :eof +:skipdoc + +where hg /q || echo Cannot find Mercurial on PATH && exit /B 1 + +where dlltool /q && goto skipdlltoolsearch +set _DLLTOOL_PATH= +where /R "%D%..\..\externals" dlltool > "%TEMP%\dlltool.loc" 2> nul && set /P _DLLTOOL_PATH= < "%TEMP%\dlltool.loc" & del "%TEMP%\dlltool.loc" +if not exist "%_DLLTOOL_PATH%" echo Cannot find binutils on PATH or in external && exit /B 1 +for %%f in (%_DLLTOOL_PATH%) do set PATH=%PATH%;%%~dpf +set _DLLTOOL_PATH= +:skipdlltoolsearch + +if defined BUILDX86 ( + call :build x86 + if errorlevel 1 exit /B +) + +if defined BUILDX64 ( + call :build x64 "%PGO%" + if errorlevel 1 exit /B +) + +if defined TESTTARGETDIR ( + call "%D%testrelease.bat" -t "%TESTTARGETDIR%" +) + +exit /B 0 + +:build +@setlocal +@echo off + +if "%1" EQU "x86" ( + call "%PCBUILD%env.bat" x86 + set BUILD=%PCBUILD%win32\ + set BUILD_PLAT=Win32 + set OUTDIR_PLAT=win32 + set OBJDIR_PLAT=x86 +) else if "%~2" NEQ "" ( + call "%PCBUILD%env.bat" amd64 + set PGO=%~2 + set BUILD=%PCBUILD%amd64-pgo\ + set BUILD_PLAT=x64 + set OUTDIR_PLAT=amd64 + set OBJDIR_PLAT=x64 +) else ( + call "%PCBUILD%env.bat" amd64 + set BUILD=%PCBUILD%amd64\ + set BUILD_PLAT=x64 + set OUTDIR_PLAT=amd64 + set OBJDIR_PLAT=x64 +) + +if exist "%BUILD%en-us" ( + echo Deleting %BUILD%en-us + rmdir /q/s "%BUILD%en-us" + if errorlevel 1 exit /B +) + +if exist "%D%obj\Release_%OBJDIR_PLAT%" ( + echo Deleting "%D%obj\Release_%OBJDIR_PLAT%" + rmdir /q/s "%D%obj\Release_%OBJDIR_PLAT%" + if errorlevel 1 exit /B +) + +if not "%CERTNAME%" EQU "" ( + set CERTOPTS="/p:SigningCertificate=%CERTNAME%" +) else ( + set CERTOPTS= +) + +if not "%SKIPBUILD%" EQU "1" ( + @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -d -t %TARGET% %CERTOPTS% + @if errorlevel 1 exit /B + @rem build.bat turns echo back on, so we disable it again + @echo off + + if "%PGO%" EQU "" ( + @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %CERTOPTS% + ) else ( + @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -c PGInstrument -t %TARGET% %CERTOPTS% + @if errorlevel 1 exit /B + + @del "%BUILD%*.pgc" + if "%PGO%" EQU "default" ( + "%BUILD%python.exe" -m test -q --pgo + ) else if "%PGO%" EQU "default2" ( + "%BUILD%python.exe" -m test -r -q --pgo + "%BUILD%python.exe" -m test -r -q --pgo + ) else if "%PGO%" EQU "default10" ( + for /L %%i in (0, 1, 9) do "%BUILD%python.exe" -m test -q -r --pgo + ) else if "%PGO%" EQU "pybench" ( + "%BUILD%python.exe" "%PCBUILD%..\Tools\pybench\pybench.py" + ) else ( + "%BUILD%python.exe" %PGO% + ) + + @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -c PGUpdate -t %TARGET% %CERTOPTS% + ) + @if errorlevel 1 exit /B + @echo off +) + +"%BUILD%python.exe" "%D%get_wix.py" + +set BUILDOPTS=/p:Platform=%1 /p:BuildForRelease=true /p:DownloadUrl=%DOWNLOAD_URL% /p:DownloadUrlBase=%DOWNLOAD_URL_BASE% /p:ReleaseUri=%RELEASE_URI% +if "%PGO%" NEQ "" set BUILDOPTS=%BUILDOPTS% /p:PGOBuildPath=%BUILD% +msbuild "%D%bundle\releaselocal.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=true +if errorlevel 1 exit /B +msbuild "%D%bundle\releaseweb.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=false +if errorlevel 1 exit /B + +msbuild "%D%make_zip.proj" /t:Build %BUILDOPTS% %CERTOPTS% + +if not "%OUTDIR%" EQU "" ( + mkdir "%OUTDIR%\%OUTDIR_PLAT%" + copy /Y "%BUILD%en-us\*.cab" "%OUTDIR%\%OUTDIR_PLAT%" + copy /Y "%BUILD%en-us\*.exe" "%OUTDIR%\%OUTDIR_PLAT%" + copy /Y "%BUILD%en-us\*.msi" "%OUTDIR%\%OUTDIR_PLAT%" + copy /Y "%BUILD%en-us\*.msu" "%OUTDIR%\%OUTDIR_PLAT%" +) + +exit /B 0 + +:Help +echo buildrelease.bat [--out DIR] [-x86] [-x64] [--certificate CERTNAME] [--build] [--skip-build] +echo [--pgo COMMAND] [--skip-doc] [--download DOWNLOAD URL] [--test TARGETDIR] +echo [-h] +echo. +echo --out (-o) Specify an additional output directory for installers +echo -x86 Build x86 installers +echo -x64 Build x64 installers +echo --build (-b) Incrementally build Python rather than rebuilding +echo --skip-build (-B) Do not build Python (just do the installers) +echo --skip-doc (-D) Do not build documentation +echo --pgo Build x64 installers using PGO +echo --download Specify the full download URL for MSIs +echo --test Specify the test directory to run the installer tests +echo -h Display this help information +echo. +echo If no architecture is specified, all architectures will be built. +echo If --test is not specified, the installer tests are not run. +echo. +echo For the --pgo option, any Python command line can be used as well as the +echo following shortcuts: +echo Shortcut Description +echo default Test suite with --pgo +echo default2 2x test suite with --pgo and randomized test order +echo default10 10x test suite with --pgo and randomized test order +echo pybench pybench script +echo. +echo The following substitutions will be applied to the download URL: +echo Variable Description Example +echo {version} version number 3.5.0 +echo {arch} architecture amd64, win32 +echo {releasename} release name a1, b2, rc3 (or blank for final) +echo {msi} MSI filename core.msi diff --git a/Tools/msi/bundle/Default.thm b/Tools/msi/bundle/Default.thm new file mode 100644 index 000000000000..903af4f12dc5 --- /dev/null +++ b/Tools/msi/bundle/Default.thm @@ -0,0 +1,136 @@ + + + #(loc.Caption) + Segoe UI + Segoe UI + Segoe UI + Segoe UI + Segoe UI + Segoe UI + + + #(loc.HelpHeader) + + + #(loc.HelpText) + + + + #(loc.InstallHeader) + + + #(loc.InstallMessage) + + + + + #(loc.ShortInstallLauncherAllUsersLabel) + #(loc.ShortPrependPathLabel) + + + + + #(loc.InstallUpgradeHeader) + + + #(loc.InstallUpgradeMessage) + + + + + + + + #(loc.InstallHeader) + + + + + + + + #(loc.Custom1Header) + + + #(loc.Include_docLabel) + #(loc.Include_docHelpLabel) + + #(loc.Include_pipLabel) + #(loc.Include_pipHelpLabel) + + #(loc.Include_tcltkLabel) + #(loc.Include_tcltkHelpLabel) + + #(loc.Include_testLabel) + #(loc.Include_testHelpLabel) + + #(loc.Include_launcherLabel) + #(loc.InstallLauncherAllUsersLabel) + #(loc.Include_launcherHelpLabel) + + + + + + + #(loc.Custom2Header) + + + #(loc.InstallAllUsersLabel) + #(loc.AssociateFilesLabel) + #(loc.ShortcutsLabel) + #(loc.PrependPathLabel) + #(loc.PrecompileLabel) + #(loc.Include_symbolsLabel) + #(loc.Include_debugLabel) + + #(loc.CustomLocationLabel) + + + #(loc.CustomLocationHelpLabel) + + + + + + + #(loc.ProgressHeader) + + + #(loc.ProgressLabel) + #(loc.OverallProgressPackageText) + + + + + #(loc.ModifyHeader) + + + + + + + + + + #(loc.SuccessHeader) + + + + + #(loc.SuccessRestartText) + + + + + + #(loc.FailureHeader) + + + #(loc.FailureHyperlinkLogText) + + #(loc.FailureRestartText) + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/Default.wxl b/Tools/msi/bundle/Default.wxl new file mode 100644 index 000000000000..1f3e77c59d39 --- /dev/null +++ b/Tools/msi/bundle/Default.wxl @@ -0,0 +1,133 @@ + + + [WixBundleName] Setup + [WixBundleName] + Installing + Setup + Updating + Modify + Repairing + Repair + Removing + Uninstall + + You will be prompted for Administrator privileges to install a C Runtime Library update (KB2999226). + + +Continue? + + &Cancel + &Close + Install [WixBundleName] + Select Install Now to install Python with default settings, or choose Customize to enable or disable features. + Version [WixBundleVersion] + Upgrade to [WixBundleName] + Select Upgrade Now to keep your current settings, or choose Customize to enable or disable features. + Are you sure you want to cancel? + Previous version + Setup Help + Visit <a href="http://docs.python.org/[ShortVersion]/using/windows.html">docs.python.org/[ShortVersion]/using/windows.html</a> for the full list of options, including the ability to enable and disable specific features. + +"/passive" to display progress without requiring user interaction + +"/quiet" to install/uninstall without displaying any UI + +"/simple" to prevent user customization + +"/uninstall" to remove Python (without confirmation) + +"/layout [\[]directory[\]]" to pre-download all components + +"/log [\[]filename[\]]" to specify log files location + [WixBundleName] <a href="#">license terms</a>. + I &agree to the license terms and conditions + &Install Now + [TargetDir] + +Includes IDLE, pip and documentation +Creates shortcuts and file associations + C&ustomize installation + Choose location and features + &Install + Use settings preselected by your administrator + +[SimpleInstallDescription] + Up&grade Now + [TargetDir] + +Replaces your existing installation without changing settings. +Select Customize to review current options. + C&ustomize installation + Choose location and features + Optional Features + Advanced Options + Customize install location + You will require write permissions for the selected location. + &Install + &Next + &Back + B&rowse + &Documentation + Installs the Python documentation file. + &pip + Installs pip, which can download and install other Python packages. + tcl/tk and &IDLE + Installs tkinter and the IDLE development environment. + Python &test suite + Installs the standard library test suite. + py &launcher + Installs the global 'py' launcher to make it easier to start Python. + + Associate &files with Python (requires the py launcher) + Create shortcuts for installed applications + Add Python to &environment variables + Add &Python [ShortVersion] to PATH + Install for &all users + for &all users (requires elevation) + Install &launcher for all users (recommended) + &Precompile standard library + Download debugging &symbols + Download debu&g binaries (requires VS 2015 or later) + + [ActionLikeInstallation] Progress + [ActionLikeInstalling]: + Initializing... + Modify Setup + &Modify + Add or remove individual features. + &Repair + Ensure all current features are correctly installed. + &Uninstall + Remove the entire [WixBundleName] installation. + [ActionLikeInstallation] was successful + &Launch + You may need to restart your computer to finish updating files. + &Restart + Special thanks to Mark Hammond, without whose years of freely shared Windows expertise, Python for Windows would still be Python for DOS. + +New to Python? Start with the <a href="https://docs.python.org/[ShortVersion]/tutorial/index.html">online tutorial</a> and <a href="https://docs.python.org/[ShortVersion]/index.html">documentation</a>. + +See <a href="https://docs.python.org/[ShortVersion]/whatsnew/[ShortVersion].html">what's new</a> in this release. + Thank you for using [WixBundleName]. + Thank you for using [WixBundleName]. + +Feel free to email <a href="/service/mailto:python-list@python.org">python-list@python.org</a> if you continue to encounter issues. + Thank you for using [WixBundleName]. + +Feel free to email <a href="/service/mailto:python-list@python.org">python-list@python.org</a> if you encountered problems. + Setup failed + One or more issues caused the setup to fail. Please fix the issues and then retry setup. For more information see the <a href="#">log file</a>. + You must restart your computer to complete the rollback of the software. + &Restart + Unable to install [WixBundleName] due to an existing install. Use Programs and Features to modify, repair or remove [WixBundleName]. + + Windows 7 Service Pack 1 and all applicable updates are required to install [WixBundleName]. + +Please <a href="https://www.bing.com/search?q=how%20to%20install%20windows%207%20service%20pack%201">update your machine</a> and then restart the installation. + Windows Vista Service Pack 2 and all applicable updates are required to install [WixBundleName]. + +Please <a href="https://www.bing.com/search?q=how%20to%20install%20windows%20vista%20service%20pack%202">update your machine</a> and then restart the installation. + Windows Vista or later is required to install and use [WixBundleName]. + +Visit <a href="https://www.python.org/">python.org</a> to download Python 3.4. + diff --git a/Tools/msi/bundle/SideBar.png b/Tools/msi/bundle/SideBar.png new file mode 100644 index 000000000000..a23ce5e14584 Binary files /dev/null and b/Tools/msi/bundle/SideBar.png differ diff --git a/Tools/msi/bundle/bootstrap/LICENSE.txt b/Tools/msi/bundle/bootstrap/LICENSE.txt new file mode 100644 index 000000000000..5791a7e81d74 --- /dev/null +++ b/Tools/msi/bundle/bootstrap/LICENSE.txt @@ -0,0 +1,25 @@ +This license applies to the bootstrapper application that is embedded within the installer. It has no impact on the licensing for the rest of the installer or Python itself, as no code covered by this license exists in any other part of the product. + +--- + +Microsoft Reciprocal License (MS-RL) + +This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. + +1. Definitions + The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. + A "contribution" is the original software, or any additions or changes to the software. + A "contributor" is any person that distributes its contribution under this license. + "Licensed patents" are a contributor's patent claims that read directly on its contribution. + +2. Grant of Rights + (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. + (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. + +3. Conditions and Limitations + (A) Reciprocal Grants- For any file you distribute that contains code from the software (in source code or binary format), you must provide recipients the source code to that file along with a copy of this license, which license will govern that file. You may license other files that are entirely your own work and do not contain code from the software under any terms you choose. + (B) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. + (C) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. + (D) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. + (E) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. + (F) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. diff --git a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp new file mode 100644 index 000000000000..9d94e3b46f6e --- /dev/null +++ b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp @@ -0,0 +1,3232 @@ +//------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2004, Outercurve Foundation. +// This software is released under Microsoft Reciprocal License (MS-RL). +// The license and further copyright text can be found in the file +// LICENSE.TXT at the root directory of the distribution. +// +//------------------------------------------------------------------------------------------------- + + +#include "pch.h" + +static const LPCWSTR PYBA_WINDOW_CLASS = L"PythonBA"; +static const LPCWSTR PYBA_VARIABLE_LAUNCH_TARGET_PATH = L"LaunchTarget"; +static const LPCWSTR PYBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID = L"LaunchTargetElevatedId"; +static const LPCWSTR PYBA_VARIABLE_LAUNCH_ARGUMENTS = L"LaunchArguments"; +static const LPCWSTR PYBA_VARIABLE_LAUNCH_HIDDEN = L"LaunchHidden"; +static const DWORD PYBA_ACQUIRE_PERCENTAGE = 30; +static const LPCWSTR PYBA_VARIABLE_BUNDLE_FILE_VERSION = L"WixBundleFileVersion"; + +enum PYBA_STATE { + PYBA_STATE_INITIALIZING, + PYBA_STATE_INITIALIZED, + PYBA_STATE_HELP, + PYBA_STATE_DETECTING, + PYBA_STATE_DETECTED, + PYBA_STATE_PLANNING, + PYBA_STATE_PLANNED, + PYBA_STATE_APPLYING, + PYBA_STATE_CACHING, + PYBA_STATE_CACHED, + PYBA_STATE_EXECUTING, + PYBA_STATE_EXECUTED, + PYBA_STATE_APPLIED, + PYBA_STATE_FAILED, +}; + +static const int WM_PYBA_SHOW_HELP = WM_APP + 100; +static const int WM_PYBA_DETECT_PACKAGES = WM_APP + 101; +static const int WM_PYBA_PLAN_PACKAGES = WM_APP + 102; +static const int WM_PYBA_APPLY_PACKAGES = WM_APP + 103; +static const int WM_PYBA_CHANGE_STATE = WM_APP + 104; +static const int WM_PYBA_SHOW_FAILURE = WM_APP + 105; + +// This enum must be kept in the same order as the PAGE_NAMES array. +enum PAGE { + PAGE_LOADING, + PAGE_HELP, + PAGE_INSTALL, + PAGE_UPGRADE, + PAGE_SIMPLE_INSTALL, + PAGE_CUSTOM1, + PAGE_CUSTOM2, + PAGE_MODIFY, + PAGE_PROGRESS, + PAGE_PROGRESS_PASSIVE, + PAGE_SUCCESS, + PAGE_FAILURE, + COUNT_PAGE, +}; + +// This array must be kept in the same order as the PAGE enum. +static LPCWSTR PAGE_NAMES[] = { + L"Loading", + L"Help", + L"Install", + L"Upgrade", + L"SimpleInstall", + L"Custom1", + L"Custom2", + L"Modify", + L"Progress", + L"ProgressPassive", + L"Success", + L"Failure", +}; + +enum CONTROL_ID { + // Non-paged controls + ID_CLOSE_BUTTON = THEME_FIRST_ASSIGN_CONTROL_ID, + ID_MINIMIZE_BUTTON, + + // Welcome page + ID_INSTALL_BUTTON, + ID_INSTALL_CUSTOM_BUTTON, + ID_INSTALL_SIMPLE_BUTTON, + ID_INSTALL_UPGRADE_BUTTON, + ID_INSTALL_UPGRADE_CUSTOM_BUTTON, + ID_INSTALL_CANCEL_BUTTON, + ID_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX, + + // Customize Page + ID_TARGETDIR_EDITBOX, + ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX, + ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX, + ID_CUSTOM_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX, + ID_CUSTOM_COMPILE_ALL_CHECKBOX, + ID_CUSTOM_BROWSE_BUTTON, + ID_CUSTOM_BROWSE_BUTTON_LABEL, + ID_CUSTOM_INSTALL_BUTTON, + ID_CUSTOM_NEXT_BUTTON, + ID_CUSTOM1_BACK_BUTTON, + ID_CUSTOM2_BACK_BUTTON, + ID_CUSTOM1_CANCEL_BUTTON, + ID_CUSTOM2_CANCEL_BUTTON, + + // Modify page + ID_MODIFY_BUTTON, + ID_REPAIR_BUTTON, + ID_UNINSTALL_BUTTON, + ID_MODIFY_CANCEL_BUTTON, + + // Progress page + ID_CACHE_PROGRESS_PACKAGE_TEXT, + ID_CACHE_PROGRESS_BAR, + ID_CACHE_PROGRESS_TEXT, + + ID_EXECUTE_PROGRESS_PACKAGE_TEXT, + ID_EXECUTE_PROGRESS_BAR, + ID_EXECUTE_PROGRESS_TEXT, + ID_EXECUTE_PROGRESS_ACTIONDATA_TEXT, + + ID_OVERALL_PROGRESS_PACKAGE_TEXT, + ID_OVERALL_PROGRESS_BAR, + ID_OVERALL_CALCULATED_PROGRESS_BAR, + ID_OVERALL_PROGRESS_TEXT, + + ID_PROGRESS_CANCEL_BUTTON, + + // Success page + ID_LAUNCH_BUTTON, + ID_SUCCESS_TEXT, + ID_SUCCESS_RESTART_TEXT, + ID_SUCCESS_RESTART_BUTTON, + ID_SUCCESS_CANCEL_BUTTON, + + // Failure page + ID_FAILURE_LOGFILE_LINK, + ID_FAILURE_MESSAGE_TEXT, + ID_FAILURE_RESTART_TEXT, + ID_FAILURE_RESTART_BUTTON, + ID_FAILURE_CANCEL_BUTTON +}; + +static THEME_ASSIGN_CONTROL_ID CONTROL_ID_NAMES[] = { + { ID_CLOSE_BUTTON, L"CloseButton" }, + { ID_MINIMIZE_BUTTON, L"MinimizeButton" }, + + { ID_INSTALL_BUTTON, L"InstallButton" }, + { ID_INSTALL_CUSTOM_BUTTON, L"InstallCustomButton" }, + { ID_INSTALL_SIMPLE_BUTTON, L"InstallSimpleButton" }, + { ID_INSTALL_UPGRADE_BUTTON, L"InstallUpgradeButton" }, + { ID_INSTALL_UPGRADE_CUSTOM_BUTTON, L"InstallUpgradeCustomButton" }, + { ID_INSTALL_CANCEL_BUTTON, L"InstallCancelButton" }, + { ID_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX, L"InstallLauncherAllUsers" }, + + { ID_TARGETDIR_EDITBOX, L"TargetDir" }, + { ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX, L"AssociateFiles" }, + { ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX, L"InstallAllUsers" }, + { ID_CUSTOM_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX, L"CustomInstallLauncherAllUsers" }, + { ID_CUSTOM_COMPILE_ALL_CHECKBOX, L"CompileAll" }, + { ID_CUSTOM_BROWSE_BUTTON, L"CustomBrowseButton" }, + { ID_CUSTOM_BROWSE_BUTTON_LABEL, L"CustomBrowseButtonLabel" }, + { ID_CUSTOM_INSTALL_BUTTON, L"CustomInstallButton" }, + { ID_CUSTOM_NEXT_BUTTON, L"CustomNextButton" }, + { ID_CUSTOM1_BACK_BUTTON, L"Custom1BackButton" }, + { ID_CUSTOM2_BACK_BUTTON, L"Custom2BackButton" }, + { ID_CUSTOM1_CANCEL_BUTTON, L"Custom1CancelButton" }, + { ID_CUSTOM2_CANCEL_BUTTON, L"Custom2CancelButton" }, + + { ID_MODIFY_BUTTON, L"ModifyButton" }, + { ID_REPAIR_BUTTON, L"RepairButton" }, + { ID_UNINSTALL_BUTTON, L"UninstallButton" }, + { ID_MODIFY_CANCEL_BUTTON, L"ModifyCancelButton" }, + + { ID_CACHE_PROGRESS_PACKAGE_TEXT, L"CacheProgressPackageText" }, + { ID_CACHE_PROGRESS_BAR, L"CacheProgressbar" }, + { ID_CACHE_PROGRESS_TEXT, L"CacheProgressText" }, + { ID_EXECUTE_PROGRESS_PACKAGE_TEXT, L"ExecuteProgressPackageText" }, + { ID_EXECUTE_PROGRESS_BAR, L"ExecuteProgressbar" }, + { ID_EXECUTE_PROGRESS_TEXT, L"ExecuteProgressText" }, + { ID_EXECUTE_PROGRESS_ACTIONDATA_TEXT, L"ExecuteProgressActionDataText" }, + { ID_OVERALL_PROGRESS_PACKAGE_TEXT, L"OverallProgressPackageText" }, + { ID_OVERALL_PROGRESS_BAR, L"OverallProgressbar" }, + { ID_OVERALL_CALCULATED_PROGRESS_BAR, L"OverallCalculatedProgressbar" }, + { ID_OVERALL_PROGRESS_TEXT, L"OverallProgressText" }, + { ID_PROGRESS_CANCEL_BUTTON, L"ProgressCancelButton" }, + + { ID_LAUNCH_BUTTON, L"LaunchButton" }, + { ID_SUCCESS_TEXT, L"SuccessText" }, + { ID_SUCCESS_RESTART_TEXT, L"SuccessRestartText" }, + { ID_SUCCESS_RESTART_BUTTON, L"SuccessRestartButton" }, + { ID_SUCCESS_CANCEL_BUTTON, L"SuccessCancelButton" }, + + { ID_FAILURE_LOGFILE_LINK, L"FailureLogFileLink" }, + { ID_FAILURE_MESSAGE_TEXT, L"FailureMessageText" }, + { ID_FAILURE_RESTART_TEXT, L"FailureRestartText" }, + { ID_FAILURE_RESTART_BUTTON, L"FailureRestartButton" }, + { ID_FAILURE_CANCEL_BUTTON, L"FailureCancelButton" }, +}; + +static struct { LPCWSTR regName; LPCWSTR variableName; } OPTIONAL_FEATURES[] = { + { L"core_d", L"Include_debug" }, + { L"core_pdb", L"Include_symbols" }, + { L"dev", L"Include_dev" }, + { L"doc", L"Include_doc" }, + { L"exe", L"Include_exe" }, + { L"lib", L"Include_lib" }, + { L"path", L"PrependPath" }, + { L"pip", L"Include_pip" }, + { L"tcltk", L"Include_tcltk" }, + { L"test", L"Include_test" }, + { L"tools", L"Include_tools" }, + { L"Shortcuts", L"Shortcuts" }, + // Include_launcher and AssociateFiles are handled separately and so do + // not need to be included in this list. + { nullptr, nullptr } +}; + + + +class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { + void ShowPage(DWORD newPageId) { + // Process each control for special handling in the new page. + ProcessPageControls(ThemeGetPage(_theme, newPageId)); + + // Enable disable controls per-page. + if (_pageIds[PAGE_INSTALL] == newPageId || + _pageIds[PAGE_SIMPLE_INSTALL] == newPageId || + _pageIds[PAGE_UPGRADE] == newPageId) { + InstallPage_Show(); + } else if (_pageIds[PAGE_CUSTOM1] == newPageId) { + Custom1Page_Show(); + } else if (_pageIds[PAGE_CUSTOM2] == newPageId) { + Custom2Page_Show(); + } else if (_pageIds[PAGE_MODIFY] == newPageId) { + ModifyPage_Show(); + } else if (_pageIds[PAGE_SUCCESS] == newPageId) { + SuccessPage_Show(); + } else if (_pageIds[PAGE_FAILURE] == newPageId) { + FailurePage_Show(); + } + + // Prevent repainting while switching page to avoid ugly flickering + _suppressPaint = TRUE; + ThemeShowPage(_theme, newPageId, SW_SHOW); + ThemeShowPage(_theme, _visiblePageId, SW_HIDE); + _suppressPaint = FALSE; + InvalidateRect(_theme->hwndParent, nullptr, TRUE); + _visiblePageId = newPageId; + + // On the install page set the focus to the install button or + // the next enabled control if install is disabled + if (_pageIds[PAGE_INSTALL] == newPageId) { + ThemeSetFocus(_theme, ID_INSTALL_BUTTON); + } else if (_pageIds[PAGE_SIMPLE_INSTALL] == newPageId) { + ThemeSetFocus(_theme, ID_INSTALL_SIMPLE_BUTTON); + } + } + + // + // Handles control clicks + // + void OnCommand(CONTROL_ID id) { + LPWSTR defaultDir = nullptr; + LPWSTR targetDir = nullptr; + LONGLONG elevated, crtInstalled, installAllUsers; + BOOL checked, launcherChecked; + WCHAR wzPath[MAX_PATH] = { }; + BROWSEINFOW browseInfo = { }; + PIDLIST_ABSOLUTE pidl = nullptr; + DWORD pageId; + HRESULT hr = S_OK; + + switch(id) { + case ID_CLOSE_BUTTON: + OnClickCloseButton(); + break; + + // Install commands + case ID_INSTALL_SIMPLE_BUTTON: __fallthrough; + case ID_INSTALL_UPGRADE_BUTTON: __fallthrough; + case ID_INSTALL_BUTTON: + SavePageSettings(); + + if (!WillElevate() && !QueryElevateForCrtInstall()) { + break; + } + + hr = BalGetNumericVariable(L"InstallAllUsers", &installAllUsers); + ExitOnFailure(hr, L"Failed to get install scope"); + + hr = _engine->SetVariableNumeric(L"CompileAll", installAllUsers); + ExitOnFailure(hr, L"Failed to update CompileAll"); + + hr = EnsureTargetDir(); + ExitOnFailure(hr, L"Failed to set TargetDir"); + + OnPlan(BOOTSTRAPPER_ACTION_INSTALL); + break; + + case ID_CUSTOM1_BACK_BUTTON: + SavePageSettings(); + if (_modifying) { + GoToPage(PAGE_MODIFY); + } else if (_upgrading) { + GoToPage(PAGE_UPGRADE); + } else { + GoToPage(PAGE_INSTALL); + } + break; + + case ID_INSTALL_CUSTOM_BUTTON: __fallthrough; + case ID_INSTALL_UPGRADE_CUSTOM_BUTTON: __fallthrough; + case ID_CUSTOM2_BACK_BUTTON: + SavePageSettings(); + GoToPage(PAGE_CUSTOM1); + break; + + case ID_CUSTOM_NEXT_BUTTON: + SavePageSettings(); + GoToPage(PAGE_CUSTOM2); + break; + + case ID_CUSTOM_INSTALL_BUTTON: + SavePageSettings(); + + hr = BalGetStringVariable(L"TargetDir", &targetDir); + if (SUCCEEDED(hr)) { + // TODO: Check whether directory exists and contains another installation + ReleaseStr(targetDir); + } + + if (!WillElevate() && !QueryElevateForCrtInstall()) { + break; + } + + OnPlan(_command.action); + break; + + case ID_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX: + checked = ThemeIsControlChecked(_theme, ID_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX); + _engine->SetVariableNumeric(L"InstallLauncherAllUsers", checked); + + ThemeControlElevates(_theme, ID_INSTALL_BUTTON, WillElevate()); + break; + + case ID_CUSTOM_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX: + checked = ThemeIsControlChecked(_theme, ID_CUSTOM_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX); + _engine->SetVariableNumeric(L"InstallLauncherAllUsers", checked); + + ThemeControlElevates(_theme, ID_CUSTOM_INSTALL_BUTTON, WillElevate()); + break; + + case ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX: + checked = ThemeIsControlChecked(_theme, ID_CUSTOM_INSTALL_ALL_USERS_CHECKBOX); + _engine->SetVariableNumeric(L"InstallAllUsers", checked); + + ThemeControlElevates(_theme, ID_CUSTOM_INSTALL_BUTTON, WillElevate()); + ThemeControlEnable(_theme, ID_CUSTOM_BROWSE_BUTTON_LABEL, !checked); + if (checked) { + _engine->SetVariableNumeric(L"CompileAll", 1); + ThemeSendControlMessage(_theme, ID_CUSTOM_COMPILE_ALL_CHECKBOX, BM_SETCHECK, BST_CHECKED, 0); + } + ThemeGetTextControl(_theme, ID_TARGETDIR_EDITBOX, &targetDir); + if (targetDir) { + // Check the current value against the default to see + // if we should switch it automatically. + hr = BalGetStringVariable( + checked ? L"DefaultJustForMeTargetDir" : L"DefaultAllUsersTargetDir", + &defaultDir + ); + + if (SUCCEEDED(hr) && defaultDir) { + LPWSTR formatted = nullptr; + if (defaultDir[0] && SUCCEEDED(BalFormatString(defaultDir, &formatted))) { + if (wcscmp(formatted, targetDir) == 0) { + ReleaseStr(defaultDir); + defaultDir = nullptr; + ReleaseStr(formatted); + formatted = nullptr; + + hr = BalGetStringVariable( + checked ? L"DefaultAllUsersTargetDir" : L"DefaultJustForMeTargetDir", + &defaultDir + ); + if (SUCCEEDED(hr) && defaultDir && defaultDir[0] && SUCCEEDED(BalFormatString(defaultDir, &formatted))) { + ThemeSetTextControl(_theme, ID_TARGETDIR_EDITBOX, formatted); + ReleaseStr(formatted); + } + } else { + ReleaseStr(formatted); + } + } + + ReleaseStr(defaultDir); + } + } + break; + + case ID_CUSTOM_BROWSE_BUTTON: + browseInfo.hwndOwner = _hWnd; + browseInfo.pszDisplayName = wzPath; + browseInfo.lpszTitle = _theme->sczCaption; + browseInfo.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI; + pidl = ::SHBrowseForFolderW(&browseInfo); + if (pidl && ::SHGetPathFromIDListW(pidl, wzPath)) { + ThemeSetTextControl(_theme, ID_TARGETDIR_EDITBOX, wzPath); + } + + if (pidl) { + ::CoTaskMemFree(pidl); + } + break; + + // Modify commands + case ID_MODIFY_BUTTON: + // Some variables cannot be modified + _engine->SetVariableString(L"InstallAllUsersState", L"disable"); + _engine->SetVariableString(L"InstallLauncherAllUsersState", L"disable"); + _engine->SetVariableString(L"TargetDirState", L"disable"); + _engine->SetVariableString(L"CustomBrowseButtonState", L"disable"); + _modifying = TRUE; + GoToPage(PAGE_CUSTOM1); + break; + + case ID_REPAIR_BUTTON: + OnPlan(BOOTSTRAPPER_ACTION_REPAIR); + break; + + case ID_UNINSTALL_BUTTON: + OnPlan(BOOTSTRAPPER_ACTION_UNINSTALL); + break; + } + + LExit: + return; + } + + void InstallPage_Show() { + // Ensure the All Users install button has a UAC shield + BOOL elevated = WillElevate(); + ThemeControlElevates(_theme, ID_INSTALL_BUTTON, elevated); + ThemeControlElevates(_theme, ID_INSTALL_SIMPLE_BUTTON, elevated); + ThemeControlElevates(_theme, ID_INSTALL_UPGRADE_BUTTON, elevated); + } + + void Custom1Page_Show() { + LONGLONG installLauncherAllUsers; + + if (FAILED(BalGetNumericVariable(L"InstallLauncherAllUsers", &installLauncherAllUsers))) { + installLauncherAllUsers = 0; + } + + ThemeSendControlMessage(_theme, ID_CUSTOM_INSTALL_LAUNCHER_ALL_USERS_CHECKBOX, BM_SETCHECK, + installLauncherAllUsers ? BST_CHECKED : BST_UNCHECKED, 0); + } + + void Custom2Page_Show() { + HRESULT hr; + LONGLONG installAll, includeLauncher; + + if (FAILED(BalGetNumericVariable(L"InstallAllUsers", &installAll))) { + installAll = 0; + } + + if (WillElevate()) { + ThemeControlElevates(_theme, ID_CUSTOM_INSTALL_BUTTON, TRUE); + ThemeShowControl(_theme, ID_CUSTOM_BROWSE_BUTTON_LABEL, SW_HIDE); + } else { + ThemeControlElevates(_theme, ID_CUSTOM_INSTALL_BUTTON, FALSE); + ThemeShowControl(_theme, ID_CUSTOM_BROWSE_BUTTON_LABEL, SW_SHOW); + } + + if (SUCCEEDED(BalGetNumericVariable(L"Include_launcher", &includeLauncher)) && includeLauncher) { + ThemeControlEnable(_theme, ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX, TRUE); + } else { + ThemeSendControlMessage(_theme, ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX, BM_SETCHECK, BST_UNCHECKED, 0); + ThemeControlEnable(_theme, ID_CUSTOM_ASSOCIATE_FILES_CHECKBOX, FALSE); + } + + LPWSTR targetDir = nullptr; + hr = BalGetStringVariable(L"TargetDir", &targetDir); + if (SUCCEEDED(hr) && targetDir && targetDir[0]) { + ThemeSetTextControl(_theme, ID_TARGETDIR_EDITBOX, targetDir); + StrFree(targetDir); + } else if (SUCCEEDED(hr)) { + StrFree(targetDir); + targetDir = nullptr; + + LPWSTR defaultTargetDir = nullptr; + hr = BalGetStringVariable(L"DefaultCustomTargetDir", &defaultTargetDir); + if (SUCCEEDED(hr) && defaultTargetDir && !defaultTargetDir[0]) { + StrFree(defaultTargetDir); + defaultTargetDir = nullptr; + + hr = BalGetStringVariable( + installAll ? L"DefaultAllUsersTargetDir" : L"DefaultJustForMeTargetDir", + &defaultTargetDir + ); + } + if (SUCCEEDED(hr) && defaultTargetDir) { + if (defaultTargetDir[0] && SUCCEEDED(BalFormatString(defaultTargetDir, &targetDir))) { + ThemeSetTextControl(_theme, ID_TARGETDIR_EDITBOX, targetDir); + StrFree(targetDir); + } + StrFree(defaultTargetDir); + } + } + } + + void ModifyPage_Show() { + ThemeControlEnable(_theme, ID_REPAIR_BUTTON, !_suppressRepair); + } + + void SuccessPage_Show() { + // on the "Success" page, check if the restart or launch button should be enabled. + BOOL showRestartButton = FALSE; + BOOL launchTargetExists = FALSE; + LOC_STRING *successText = nullptr; + HRESULT hr = S_OK; + + if (_restartRequired) { + if (BOOTSTRAPPER_RESTART_PROMPT == _command.restart) { + showRestartButton = TRUE; + } + } else if (ThemeControlExists(_theme, ID_LAUNCH_BUTTON)) { + launchTargetExists = BalStringVariableExists(PYBA_VARIABLE_LAUNCH_TARGET_PATH); + } + + switch (_plannedAction) { + case BOOTSTRAPPER_ACTION_INSTALL: + hr = LocGetString(_wixLoc, L"#(loc.SuccessInstallMessage)", &successText); + break; + case BOOTSTRAPPER_ACTION_MODIFY: + hr = LocGetString(_wixLoc, L"#(loc.SuccessModifyMessage)", &successText); + break; + case BOOTSTRAPPER_ACTION_REPAIR: + hr = LocGetString(_wixLoc, L"#(loc.SuccessRepairMessage)", &successText); + break; + case BOOTSTRAPPER_ACTION_UNINSTALL: + hr = LocGetString(_wixLoc, L"#(loc.SuccessRemoveMessage)", &successText); + break; + } + + if (successText) { + LPWSTR formattedString = nullptr; + BalFormatString(successText->wzText, &formattedString); + if (formattedString) { + ThemeSetTextControl(_theme, ID_SUCCESS_TEXT, formattedString); + StrFree(formattedString); + } + } + + ThemeControlEnable(_theme, ID_LAUNCH_BUTTON, launchTargetExists && BOOTSTRAPPER_ACTION_UNINSTALL < _plannedAction); + ThemeControlEnable(_theme, ID_SUCCESS_RESTART_TEXT, showRestartButton); + ThemeControlEnable(_theme, ID_SUCCESS_RESTART_BUTTON, showRestartButton); + } + + void FailurePage_Show() { + // on the "Failure" page, show error message and check if the restart button should be enabled. + + // if there is a log file variable then we'll assume the log file exists. + BOOL showLogLink = (_bundle.sczLogVariable && *_bundle.sczLogVariable); + BOOL showErrorMessage = FALSE; + BOOL showRestartButton = FALSE; + + if (FAILED(_hrFinal)) { + LPWSTR unformattedText = nullptr; + LPWSTR text = nullptr; + + // If we know the failure message, use that. + if (_failedMessage && *_failedMessage) { + StrAllocString(&unformattedText, _failedMessage, 0); + } else { + // try to get the error message from the error code. + StrAllocFromError(&unformattedText, _hrFinal, nullptr); + if (!unformattedText || !*unformattedText) { + StrAllocFromError(&unformattedText, E_FAIL, nullptr); + } + } + + if (E_WIXSTDBA_CONDITION_FAILED == _hrFinal) { + if (unformattedText) { + StrAllocString(&text, unformattedText, 0); + } + } else { + StrAllocFormatted(&text, L"0x%08x - %ls", _hrFinal, unformattedText); + } + + if (text) { + ThemeSetTextControl(_theme, ID_FAILURE_MESSAGE_TEXT, text); + showErrorMessage = TRUE; + } + + ReleaseStr(text); + ReleaseStr(unformattedText); + } + + if (_restartRequired && BOOTSTRAPPER_RESTART_PROMPT == _command.restart) { + showRestartButton = TRUE; + } + + ThemeControlEnable(_theme, ID_FAILURE_LOGFILE_LINK, showLogLink); + ThemeControlEnable(_theme, ID_FAILURE_MESSAGE_TEXT, showErrorMessage); + ThemeControlEnable(_theme, ID_FAILURE_RESTART_TEXT, showRestartButton); + ThemeControlEnable(_theme, ID_FAILURE_RESTART_BUTTON, showRestartButton); + } + + +public: // IBootstrapperApplication + virtual STDMETHODIMP OnStartup() { + HRESULT hr = S_OK; + DWORD dwUIThreadId = 0; + + // create UI thread + _hUiThread = ::CreateThread(nullptr, 0, UiThreadProc, this, 0, &dwUIThreadId); + if (!_hUiThread) { + ExitWithLastError(hr, "Failed to create UI thread."); + } + + LExit: + return hr; + } + + + virtual STDMETHODIMP_(int) OnShutdown() { + int nResult = IDNOACTION; + + // wait for UI thread to terminate + if (_hUiThread) { + ::WaitForSingleObject(_hUiThread, INFINITE); + ReleaseHandle(_hUiThread); + } + + // If a restart was required. + if (_restartRequired && _allowRestart) { + nResult = IDRESTART; + } + + return nResult; + } + + + virtual STDMETHODIMP_(int) OnDetectRelatedBundle( + __in LPCWSTR wzBundleId, + __in BOOTSTRAPPER_RELATION_TYPE relationType, + __in LPCWSTR /*wzBundleTag*/, + __in BOOL fPerMachine, + __in DWORD64 /*dw64Version*/, + __in BOOTSTRAPPER_RELATED_OPERATION operation + ) { + BalInfoAddRelatedBundleAsPackage(&_bundle.packages, wzBundleId, relationType, fPerMachine); + + // Remember when our bundle would cause a downgrade. + if (BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE == operation) { + _downgradingOtherVersion = TRUE; + } else if (BOOTSTRAPPER_RELATED_OPERATION_MAJOR_UPGRADE == operation) { + _upgradingOldVersion = TRUE; + + // Assume we don't want the launcher or file associations, and if + // they have already been installed then loading the state will + // reactivate these settings. + _engine->SetVariableNumeric(L"Include_launcher", 0); + _engine->SetVariableNumeric(L"AssociateFiles", 0); + auto hr = LoadLauncherStateFromKey(_engine, HKEY_CURRENT_USER); + if (hr == S_FALSE) { + hr = LoadLauncherStateFromKey(_engine, HKEY_LOCAL_MACHINE); + } + if (FAILED(hr)) { + BalLog( + BOOTSTRAPPER_LOG_LEVEL_ERROR, + "Failed to load launcher state: error code 0x%08X", + hr + ); + } + + LoadOptionalFeatureStates(_engine); + } else if (BOOTSTRAPPER_RELATED_OPERATION_NONE == operation) { + if (_command.action == BOOTSTRAPPER_ACTION_INSTALL) { + LOC_STRING *pLocString = nullptr; + if (SUCCEEDED(LocGetString(_wixLoc, L"#(loc.FailureExistingInstall)", &pLocString)) && pLocString) { + BalFormatString(pLocString->wzText, &_failedMessage); + } else { + BalFormatString(L"Cannot install [WixBundleName] because it is already installed.", &_failedMessage); + } + BalLog( + BOOTSTRAPPER_LOG_LEVEL_ERROR, + "Related bundle %ls is preventing install", + wzBundleId + ); + SetState(PYBA_STATE_FAILED, E_WIXSTDBA_CONDITION_FAILED); + } + } + + return CheckCanceled() ? IDCANCEL : IDOK; + } + + + virtual STDMETHODIMP_(void) OnDetectPackageComplete( + __in LPCWSTR wzPackageId, + __in HRESULT /*hrStatus*/, + __in BOOTSTRAPPER_PACKAGE_STATE state + ) { } + + + virtual STDMETHODIMP_(void) OnDetectComplete(__in HRESULT hrStatus) { + if (SUCCEEDED(hrStatus) && _baFunction) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Running detect complete BA function"); + _baFunction->OnDetectComplete(); + } + + if (SUCCEEDED(hrStatus)) { + hrStatus = EvaluateConditions(); + } + + if (SUCCEEDED(hrStatus)) { + // Ensure the default path has been set + LONGLONG installAll; + LPWSTR targetDir = nullptr; + LPWSTR defaultTargetDir = nullptr; + + hrStatus = BalGetStringVariable(L"TargetDir", &targetDir); + if (FAILED(hrStatus) || !targetDir || !targetDir[0]) { + ReleaseStr(targetDir); + targetDir = nullptr; + + if (FAILED(BalGetNumericVariable(L"InstallAllUsers", &installAll))) { + installAll = 0; + } + + hrStatus = BalGetStringVariable( + installAll ? L"DefaultAllUsersTargetDir" : L"DefaultJustForMeTargetDir", + &defaultTargetDir + ); + + if (SUCCEEDED(hrStatus) && defaultTargetDir) { + if (defaultTargetDir[0] && SUCCEEDED(BalFormatString(defaultTargetDir, &targetDir))) { + hrStatus = _engine->SetVariableString(L"TargetDir", targetDir); + ReleaseStr(targetDir); + } + ReleaseStr(defaultTargetDir); + } + } + } + + SetState(PYBA_STATE_DETECTED, hrStatus); + + // If we're not interacting with the user or we're doing a layout or we're just after a force restart + // then automatically start planning. + if (BOOTSTRAPPER_DISPLAY_FULL > _command.display || + BOOTSTRAPPER_ACTION_LAYOUT == _command.action || + BOOTSTRAPPER_ACTION_UNINSTALL == _command.action || + BOOTSTRAPPER_RESUME_TYPE_REBOOT == _command.resumeType) { + if (SUCCEEDED(hrStatus)) { + ::PostMessageW(_hWnd, WM_PYBA_PLAN_PACKAGES, 0, _command.action); + } + } + } + + + virtual STDMETHODIMP_(int) OnPlanRelatedBundle( + __in_z LPCWSTR /*wzBundleId*/, + __inout_z BOOTSTRAPPER_REQUEST_STATE* pRequestedState + ) { + return CheckCanceled() ? IDCANCEL : IDOK; + } + + + virtual STDMETHODIMP_(int) OnPlanPackageBegin( + __in_z LPCWSTR wzPackageId, + __inout BOOTSTRAPPER_REQUEST_STATE *pRequestState + ) { + HRESULT hr = S_OK; + BAL_INFO_PACKAGE* pPackage = nullptr; + + if (_nextPackageAfterRestart) { + // After restart we need to finish the dependency registration for our package so allow the package + // to go present. + if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzPackageId, -1, _nextPackageAfterRestart, -1)) { + // Do not allow a repair because that could put us in a perpetual restart loop. + if (BOOTSTRAPPER_REQUEST_STATE_REPAIR == *pRequestState) { + *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; + } + + ReleaseNullStr(_nextPackageAfterRestart); // no more skipping now. + } else { + // not the matching package, so skip it. + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Skipping package: %ls, after restart because it was applied before the restart.", wzPackageId); + + *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; + } + } else if ((_plannedAction == BOOTSTRAPPER_ACTION_INSTALL || _plannedAction == BOOTSTRAPPER_ACTION_MODIFY) && + SUCCEEDED(BalInfoFindPackageById(&_bundle.packages, wzPackageId, &pPackage))) { + BOOL f = FALSE; + if (SUCCEEDED(_engine->EvaluateCondition(pPackage->sczInstallCondition, &f)) && f) { + *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; + } + } + + return CheckCanceled() ? IDCANCEL : IDOK; + } + + virtual STDMETHODIMP_(int) OnPlanMsiFeature( + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzFeatureId, + __inout BOOTSTRAPPER_FEATURE_STATE* pRequestedState + ) { + LONGLONG install; + + if (wcscmp(wzFeatureId, L"AssociateFiles") == 0 || wcscmp(wzFeatureId, L"Shortcuts") == 0) { + if (SUCCEEDED(_engine->GetVariableNumeric(wzFeatureId, &install)) && install) { + *pRequestedState = BOOTSTRAPPER_FEATURE_STATE_LOCAL; + } else { + *pRequestedState = BOOTSTRAPPER_FEATURE_STATE_ABSENT; + } + } else { + *pRequestedState = BOOTSTRAPPER_FEATURE_STATE_LOCAL; + } + return CheckCanceled() ? IDCANCEL : IDNOACTION; + } + + virtual STDMETHODIMP_(void) OnPlanComplete(__in HRESULT hrStatus) { + if (SUCCEEDED(hrStatus) && _baFunction) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Running plan complete BA function"); + _baFunction->OnPlanComplete(); + } + + SetState(PYBA_STATE_PLANNED, hrStatus); + + if (SUCCEEDED(hrStatus)) { + ::PostMessageW(_hWnd, WM_PYBA_APPLY_PACKAGES, 0, 0); + } + + _startedExecution = FALSE; + _calculatedCacheProgress = 0; + _calculatedExecuteProgress = 0; + } + + + virtual STDMETHODIMP_(int) OnCachePackageBegin( + __in_z LPCWSTR wzPackageId, + __in DWORD cCachePayloads, + __in DWORD64 dw64PackageCacheSize + ) { + if (wzPackageId && *wzPackageId) { + BAL_INFO_PACKAGE* pPackage = nullptr; + HRESULT hr = BalInfoFindPackageById(&_bundle.packages, wzPackageId, &pPackage); + LPCWSTR wz = (SUCCEEDED(hr) && pPackage->sczDisplayName) ? pPackage->sczDisplayName : wzPackageId; + + ThemeSetTextControl(_theme, ID_CACHE_PROGRESS_PACKAGE_TEXT, wz); + + // If something started executing, leave it in the overall progress text. + if (!_startedExecution) { + ThemeSetTextControl(_theme, ID_OVERALL_PROGRESS_PACKAGE_TEXT, wz); + } + } + + return __super::OnCachePackageBegin(wzPackageId, cCachePayloads, dw64PackageCacheSize); + } + + + virtual STDMETHODIMP_(int) OnCacheAcquireProgress( + __in_z LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in DWORD64 dw64Progress, + __in DWORD64 dw64Total, + __in DWORD dwOverallPercentage + ) { + WCHAR wzProgress[5] = { }; + +#ifdef DEBUG + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "PYBA: OnCacheAcquireProgress() - container/package: %ls, payload: %ls, progress: %I64u, total: %I64u, overall progress: %u%%", wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage); +#endif + + ::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallPercentage); + ThemeSetTextControl(_theme, ID_CACHE_PROGRESS_TEXT, wzProgress); + + ThemeSetProgressControl(_theme, ID_CACHE_PROGRESS_BAR, dwOverallPercentage); + + _calculatedCacheProgress = dwOverallPercentage * PYBA_ACQUIRE_PERCENTAGE / 100; + ThemeSetProgressControl(_theme, ID_OVERALL_CALCULATED_PROGRESS_BAR, _calculatedCacheProgress + _calculatedExecuteProgress); + + SetTaskbarButtonProgress(_calculatedCacheProgress + _calculatedExecuteProgress); + + return __super::OnCacheAcquireProgress(wzPackageOrContainerId, wzPayloadId, dw64Progress, dw64Total, dwOverallPercentage); + } + + + virtual STDMETHODIMP_(int) OnCacheAcquireComplete( + __in_z LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in HRESULT hrStatus, + __in int nRecommendation + ) { + SetProgressState(hrStatus); + return __super::OnCacheAcquireComplete(wzPackageOrContainerId, wzPayloadId, hrStatus, nRecommendation); + } + + + virtual STDMETHODIMP_(int) OnCacheVerifyComplete( + __in_z LPCWSTR wzPackageId, + __in_z LPCWSTR wzPayloadId, + __in HRESULT hrStatus, + __in int nRecommendation + ) { + SetProgressState(hrStatus); + return __super::OnCacheVerifyComplete(wzPackageId, wzPayloadId, hrStatus, nRecommendation); + } + + + virtual STDMETHODIMP_(void) OnCacheComplete(__in HRESULT /*hrStatus*/) { + ThemeSetTextControl(_theme, ID_CACHE_PROGRESS_PACKAGE_TEXT, L""); + SetState(PYBA_STATE_CACHED, S_OK); // we always return success here and let OnApplyComplete() deal with the error. + } + + + virtual STDMETHODIMP_(int) OnError( + __in BOOTSTRAPPER_ERROR_TYPE errorType, + __in LPCWSTR wzPackageId, + __in DWORD dwCode, + __in_z LPCWSTR wzError, + __in DWORD dwUIHint, + __in DWORD /*cData*/, + __in_ecount_z_opt(cData) LPCWSTR* /*rgwzData*/, + __in int nRecommendation + ) { + int nResult = nRecommendation; + LPWSTR sczError = nullptr; + + if (BOOTSTRAPPER_DISPLAY_EMBEDDED == _command.display) { + HRESULT hr = _engine->SendEmbeddedError(dwCode, wzError, dwUIHint, &nResult); + if (FAILED(hr)) { + nResult = IDERROR; + } + } else if (BOOTSTRAPPER_DISPLAY_FULL == _command.display) { + // If this is an authentication failure, let the engine try to handle it for us. + if (BOOTSTRAPPER_ERROR_TYPE_HTTP_AUTH_SERVER == errorType || BOOTSTRAPPER_ERROR_TYPE_HTTP_AUTH_PROXY == errorType) { + nResult = IDTRYAGAIN; + } else // show a generic error message box. + { + BalRetryErrorOccurred(wzPackageId, dwCode); + + if (!_showingInternalUIThisPackage) { + // If no error message was provided, use the error code to try and get an error message. + if (!wzError || !*wzError || BOOTSTRAPPER_ERROR_TYPE_WINDOWS_INSTALLER != errorType) { + HRESULT hr = StrAllocFromError(&sczError, dwCode, nullptr); + if (FAILED(hr) || !sczError || !*sczError) { + StrAllocFormatted(&sczError, L"0x%x", dwCode); + } + } + + nResult = ::MessageBoxW(_hWnd, sczError ? sczError : wzError, _theme->sczCaption, dwUIHint); + } + } + + SetProgressState(HRESULT_FROM_WIN32(dwCode)); + } else { + // just take note of the error code and let things continue. + BalRetryErrorOccurred(wzPackageId, dwCode); + } + + ReleaseStr(sczError); + return nResult; + } + + + virtual STDMETHODIMP_(int) OnExecuteMsiMessage( + __in_z LPCWSTR wzPackageId, + __in INSTALLMESSAGE mt, + __in UINT uiFlags, + __in_z LPCWSTR wzMessage, + __in DWORD cData, + __in_ecount_z_opt(cData) LPCWSTR* rgwzData, + __in int nRecommendation + ) { +#ifdef DEBUG + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "PYBA: OnExecuteMsiMessage() - package: %ls, message: %ls", wzPackageId, wzMessage); +#endif + if (BOOTSTRAPPER_DISPLAY_FULL == _command.display && (INSTALLMESSAGE_WARNING == mt || INSTALLMESSAGE_USER == mt)) { + int nResult = ::MessageBoxW(_hWnd, wzMessage, _theme->sczCaption, uiFlags); + return nResult; + } + + if (INSTALLMESSAGE_ACTIONSTART == mt) { + ThemeSetTextControl(_theme, ID_EXECUTE_PROGRESS_ACTIONDATA_TEXT, wzMessage); + } + + return __super::OnExecuteMsiMessage(wzPackageId, mt, uiFlags, wzMessage, cData, rgwzData, nRecommendation); + } + + + virtual STDMETHODIMP_(int) OnProgress(__in DWORD dwProgressPercentage, __in DWORD dwOverallProgressPercentage) { + WCHAR wzProgress[5] = { }; + +#ifdef DEBUG + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "PYBA: OnProgress() - progress: %u%%, overall progress: %u%%", dwProgressPercentage, dwOverallProgressPercentage); +#endif + + ::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallProgressPercentage); + ThemeSetTextControl(_theme, ID_OVERALL_PROGRESS_TEXT, wzProgress); + + ThemeSetProgressControl(_theme, ID_OVERALL_PROGRESS_BAR, dwOverallProgressPercentage); + SetTaskbarButtonProgress(dwOverallProgressPercentage); + + return __super::OnProgress(dwProgressPercentage, dwOverallProgressPercentage); + } + + + virtual STDMETHODIMP_(int) OnExecutePackageBegin(__in_z LPCWSTR wzPackageId, __in BOOL fExecute) { + LPWSTR sczFormattedString = nullptr; + + _startedExecution = TRUE; + + if (wzPackageId && *wzPackageId) { + BAL_INFO_PACKAGE* pPackage = nullptr; + BalInfoFindPackageById(&_bundle.packages, wzPackageId, &pPackage); + + LPCWSTR wz = wzPackageId; + if (pPackage) { + LOC_STRING* pLocString = nullptr; + + switch (pPackage->type) { + case BAL_INFO_PACKAGE_TYPE_BUNDLE_ADDON: + LocGetString(_wixLoc, L"#(loc.ExecuteAddonRelatedBundleMessage)", &pLocString); + break; + + case BAL_INFO_PACKAGE_TYPE_BUNDLE_PATCH: + LocGetString(_wixLoc, L"#(loc.ExecutePatchRelatedBundleMessage)", &pLocString); + break; + + case BAL_INFO_PACKAGE_TYPE_BUNDLE_UPGRADE: + LocGetString(_wixLoc, L"#(loc.ExecuteUpgradeRelatedBundleMessage)", &pLocString); + break; + } + + if (pLocString) { + // If the wix developer is showing a hidden variable in the UI, then obviously they don't care about keeping it safe + // so don't go down the rabbit hole of making sure that this is securely freed. + BalFormatString(pLocString->wzText, &sczFormattedString); + } + + wz = sczFormattedString ? sczFormattedString : pPackage->sczDisplayName ? pPackage->sczDisplayName : wzPackageId; + } + + _showingInternalUIThisPackage = pPackage && pPackage->fDisplayInternalUI; + + ThemeSetTextControl(_theme, ID_EXECUTE_PROGRESS_PACKAGE_TEXT, wz); + ThemeSetTextControl(_theme, ID_OVERALL_PROGRESS_PACKAGE_TEXT, wz); + } else { + _showingInternalUIThisPackage = FALSE; + } + + ReleaseStr(sczFormattedString); + return __super::OnExecutePackageBegin(wzPackageId, fExecute); + } + + + virtual int __stdcall OnExecuteProgress( + __in_z LPCWSTR wzPackageId, + __in DWORD dwProgressPercentage, + __in DWORD dwOverallProgressPercentage + ) { + WCHAR wzProgress[8] = { }; + +#ifdef DEBUG + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "PYBA: OnExecuteProgress() - package: %ls, progress: %u%%, overall progress: %u%%", wzPackageId, dwProgressPercentage, dwOverallProgressPercentage); +#endif + + ::StringCchPrintfW(wzProgress, countof(wzProgress), L"%u%%", dwOverallProgressPercentage); + ThemeSetTextControl(_theme, ID_EXECUTE_PROGRESS_TEXT, wzProgress); + + ThemeSetProgressControl(_theme, ID_EXECUTE_PROGRESS_BAR, dwOverallProgressPercentage); + + _calculatedExecuteProgress = dwOverallProgressPercentage * (100 - PYBA_ACQUIRE_PERCENTAGE) / 100; + ThemeSetProgressControl(_theme, ID_OVERALL_CALCULATED_PROGRESS_BAR, _calculatedCacheProgress + _calculatedExecuteProgress); + + SetTaskbarButtonProgress(_calculatedCacheProgress + _calculatedExecuteProgress); + + return __super::OnExecuteProgress(wzPackageId, dwProgressPercentage, dwOverallProgressPercentage); + } + + + virtual STDMETHODIMP_(int) OnExecutePackageComplete( + __in_z LPCWSTR wzPackageId, + __in HRESULT hrExitCode, + __in BOOTSTRAPPER_APPLY_RESTART restart, + __in int nRecommendation + ) { + SetProgressState(hrExitCode); + + if (_wcsnicmp(wzPackageId, L"path_", 5) == 0 && SUCCEEDED(hrExitCode)) { + SendMessageTimeoutW( + HWND_BROADCAST, + WM_SETTINGCHANGE, + 0, + reinterpret_cast(L"Environment"), + SMTO_ABORTIFHUNG, + 1000, + nullptr + ); + } + + int nResult = __super::OnExecutePackageComplete(wzPackageId, hrExitCode, restart, nRecommendation); + + return nResult; + } + + + virtual STDMETHODIMP_(void) OnExecuteComplete(__in HRESULT hrStatus) { + ThemeSetTextControl(_theme, ID_EXECUTE_PROGRESS_PACKAGE_TEXT, L""); + ThemeSetTextControl(_theme, ID_EXECUTE_PROGRESS_ACTIONDATA_TEXT, L""); + ThemeSetTextControl(_theme, ID_OVERALL_PROGRESS_PACKAGE_TEXT, L""); + ThemeControlEnable(_theme, ID_PROGRESS_CANCEL_BUTTON, FALSE); // no more cancel. + + SetState(PYBA_STATE_EXECUTED, S_OK); // we always return success here and let OnApplyComplete() deal with the error. + SetProgressState(hrStatus); + } + + + virtual STDMETHODIMP_(int) OnResolveSource( + __in_z LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in_z LPCWSTR wzLocalSource, + __in_z_opt LPCWSTR wzDownloadSource + ) { + int nResult = IDERROR; // assume we won't resolve source and that is unexpected. + + if (BOOTSTRAPPER_DISPLAY_FULL == _command.display) { + if (wzDownloadSource) { + nResult = IDDOWNLOAD; + } else { + // prompt to change the source location. + OPENFILENAMEW ofn = { }; + WCHAR wzFile[MAX_PATH] = { }; + + ::StringCchCopyW(wzFile, countof(wzFile), wzLocalSource); + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = _hWnd; + ofn.lpstrFile = wzFile; + ofn.nMaxFile = countof(wzFile); + ofn.lpstrFilter = L"All Files\0*.*\0"; + ofn.nFilterIndex = 1; + ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; + ofn.lpstrTitle = _theme->sczCaption; + + if (::GetOpenFileNameW(&ofn)) { + HRESULT hr = _engine->SetLocalSource(wzPackageOrContainerId, wzPayloadId, ofn.lpstrFile); + nResult = SUCCEEDED(hr) ? IDRETRY : IDERROR; + } else { + nResult = IDCANCEL; + } + } + } else if (wzDownloadSource) { + // If doing a non-interactive install and download source is available, let's try downloading the package silently + nResult = IDDOWNLOAD; + } + // else there's nothing more we can do in non-interactive mode + + return CheckCanceled() ? IDCANCEL : nResult; + } + + + virtual STDMETHODIMP_(int) OnApplyComplete(__in HRESULT hrStatus, __in BOOTSTRAPPER_APPLY_RESTART restart) { + _restartResult = restart; // remember the restart result so we return the correct error code no matter what the user chooses to do in the UI. + + // If a restart was encountered and we are not suppressing restarts, then restart is required. + _restartRequired = (BOOTSTRAPPER_APPLY_RESTART_NONE != restart && BOOTSTRAPPER_RESTART_NEVER < _command.restart); + // If a restart is required and we're not displaying a UI or we are not supposed to prompt for restart then allow the restart. + _allowRestart = _restartRequired && (BOOTSTRAPPER_DISPLAY_FULL > _command.display || BOOTSTRAPPER_RESTART_PROMPT < _command.restart); + + // If we are showing UI, wait a beat before moving to the final screen. + if (BOOTSTRAPPER_DISPLAY_NONE < _command.display) { + ::Sleep(250); + } + + SetState(PYBA_STATE_APPLIED, hrStatus); + SetTaskbarButtonProgress(100); // show full progress bar, green, yellow, or red + + return IDNOACTION; + } + + virtual STDMETHODIMP_(void) OnLaunchApprovedExeComplete(__in HRESULT hrStatus, __in DWORD /*processId*/) { + if (HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) == hrStatus) { + //try with ShelExec next time + OnClickLaunchButton(); + } else { + ::PostMessageW(_hWnd, WM_CLOSE, 0, 0); + } + } + + +private: + // + // UiThreadProc - entrypoint for UI thread. + // + static DWORD WINAPI UiThreadProc(__in LPVOID pvContext) { + HRESULT hr = S_OK; + PythonBootstrapperApplication* pThis = (PythonBootstrapperApplication*)pvContext; + BOOL comInitialized = FALSE; + BOOL ret = FALSE; + MSG msg = { }; + + // Initialize COM and theme. + hr = ::CoInitialize(nullptr); + BalExitOnFailure(hr, "Failed to initialize COM."); + comInitialized = TRUE; + + hr = ThemeInitialize(pThis->_hModule); + BalExitOnFailure(hr, "Failed to initialize theme manager."); + + hr = pThis->InitializeData(); + BalExitOnFailure(hr, "Failed to initialize data in bootstrapper application."); + + // Create main window. + pThis->InitializeTaskbarButton(); + hr = pThis->CreateMainWindow(); + BalExitOnFailure(hr, "Failed to create main window."); + + pThis->ValidateOperatingSystem(); + + if (FAILED(pThis->_hrFinal)) { + pThis->SetState(PYBA_STATE_FAILED, hr); + ::PostMessageW(pThis->_hWnd, WM_PYBA_SHOW_FAILURE, 0, 0); + } else { + // Okay, we're ready for packages now. + pThis->SetState(PYBA_STATE_INITIALIZED, hr); + ::PostMessageW(pThis->_hWnd, BOOTSTRAPPER_ACTION_HELP == pThis->_command.action ? WM_PYBA_SHOW_HELP : WM_PYBA_DETECT_PACKAGES, 0, 0); + } + + // message pump + while (0 != (ret = ::GetMessageW(&msg, nullptr, 0, 0))) { + if (-1 == ret) { + hr = E_UNEXPECTED; + BalExitOnFailure(hr, "Unexpected return value from message pump."); + } else if (!ThemeHandleKeyboardMessage(pThis->_theme, msg.hwnd, &msg)) { + ::TranslateMessage(&msg); + ::DispatchMessageW(&msg); + } + } + + // Succeeded thus far, check to see if anything went wrong while actually + // executing changes. + if (FAILED(pThis->_hrFinal)) { + hr = pThis->_hrFinal; + } else if (pThis->CheckCanceled()) { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + + LExit: + // destroy main window + pThis->DestroyMainWindow(); + + // initiate engine shutdown + DWORD dwQuit = HRESULT_CODE(hr); + if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == pThis->_restartResult) { + dwQuit = ERROR_SUCCESS_REBOOT_INITIATED; + } else if (BOOTSTRAPPER_APPLY_RESTART_REQUIRED == pThis->_restartResult) { + dwQuit = ERROR_SUCCESS_REBOOT_REQUIRED; + } + pThis->_engine->Quit(dwQuit); + + ReleaseTheme(pThis->_theme); + ThemeUninitialize(); + + // uninitialize COM + if (comInitialized) { + ::CoUninitialize(); + } + + return hr; + } + + // + // ParseVariablesFromUnattendXml - reads options from unattend.xml if it + // exists + // + HRESULT ParseVariablesFromUnattendXml() { + HRESULT hr = S_OK; + LPWSTR sczUnattendXmlPath = nullptr; + IXMLDOMDocument *pixdUnattend = nullptr; + IXMLDOMNodeList *pNodes = nullptr; + IXMLDOMNode *pNode = nullptr; + long cNodes; + DWORD dwAttr; + LPWSTR scz = nullptr; + BOOL bValue; + int iValue; + BOOL tryConvert; + BSTR bstrValue = nullptr; + + hr = BalFormatString(L"[WixBundleOriginalSourceFolder]unattend.xml", &sczUnattendXmlPath); + BalExitOnFailure(hr, "Failed to calculate path to unattend.xml"); + + if (!FileExistsEx(sczUnattendXmlPath, &dwAttr)) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_VERBOSE, "Did not find %ls", sczUnattendXmlPath); + hr = S_FALSE; + goto LExit; + } + + hr = XmlLoadDocumentFromFile(sczUnattendXmlPath, &pixdUnattend); + BalExitOnFailure1(hr, "Failed to read %ls", sczUnattendXmlPath); + + // get the list of variables users have overridden + hr = XmlSelectNodes(pixdUnattend, L"/Options/Option", &pNodes); + if (S_FALSE == hr) { + ExitFunction1(hr = S_OK); + } + BalExitOnFailure(hr, "Failed to select option nodes."); + + hr = pNodes->get_length((long*)&cNodes); + BalExitOnFailure(hr, "Failed to get option node count."); + + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Reading settings from %ls", sczUnattendXmlPath); + + for (DWORD i = 0; i < cNodes; ++i) { + hr = XmlNextElement(pNodes, &pNode, nullptr); + BalExitOnFailure(hr, "Failed to get next node."); + + // @Name + hr = XmlGetAttributeEx(pNode, L"Name", &scz); + BalExitOnFailure(hr, "Failed to get @Name."); + + tryConvert = TRUE; + hr = XmlGetAttribute(pNode, L"Value", &bstrValue); + if (FAILED(hr) || !bstrValue || !*bstrValue) { + hr = XmlGetText(pNode, &bstrValue); + tryConvert = FALSE; + } + BalExitOnFailure(hr, "Failed to get @Value."); + + if (tryConvert && + CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, bstrValue, -1, L"yes", -1)) { + _engine->SetVariableNumeric(scz, 1); + } else if (tryConvert && + CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, bstrValue, -1, L"no", -1)) { + _engine->SetVariableNumeric(scz, 0); + } else if (tryConvert && ::StrToIntExW(bstrValue, STIF_DEFAULT, &iValue)) { + _engine->SetVariableNumeric(scz, iValue); + } else { + _engine->SetVariableString(scz, bstrValue); + } + + ReleaseNullBSTR(bstrValue); + ReleaseNullStr(scz); + ReleaseNullObject(pNode); + } + + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Finished reading from %ls", sczUnattendXmlPath); + + LExit: + ReleaseObject(pNode); + ReleaseObject(pNodes); + ReleaseObject(pixdUnattend); + ReleaseStr(sczUnattendXmlPath); + + return hr; + } + + + // + // InitializeData - initializes all the package information. + // + HRESULT InitializeData() { + HRESULT hr = S_OK; + LPWSTR sczModulePath = nullptr; + IXMLDOMDocument *pixdManifest = nullptr; + + hr = BalManifestLoad(_hModule, &pixdManifest); + BalExitOnFailure(hr, "Failed to load bootstrapper application manifest."); + + hr = ParseOverridableVariablesFromXml(pixdManifest); + BalExitOnFailure(hr, "Failed to read overridable variables."); + + hr = ParseVariablesFromUnattendXml(); + ExitOnFailure(hr, "Failed to read unattend.ini file."); + + hr = ProcessCommandLine(&_language); + ExitOnFailure(hr, "Unknown commandline parameters."); + + hr = PathRelativeToModule(&sczModulePath, nullptr, _hModule); + BalExitOnFailure(hr, "Failed to get module path."); + + hr = LoadLocalization(sczModulePath, _language); + ExitOnFailure(hr, "Failed to load localization."); + + hr = LoadTheme(sczModulePath, _language); + ExitOnFailure(hr, "Failed to load theme."); + + hr = BalInfoParseFromXml(&_bundle, pixdManifest); + BalExitOnFailure(hr, "Failed to load bundle information."); + + hr = BalConditionsParseFromXml(&_conditions, pixdManifest, _wixLoc); + BalExitOnFailure(hr, "Failed to load conditions from XML."); + + hr = LoadBootstrapperBAFunctions(); + BalExitOnFailure(hr, "Failed to load bootstrapper functions."); + hr = UpdateUIStrings(_command.action); + BalExitOnFailure(hr, "Failed to load UI strings."); + + GetBundleFileVersion(); + // don't fail if we couldn't get the version info; best-effort only + LExit: + ReleaseObject(pixdManifest); + ReleaseStr(sczModulePath); + + return hr; + } + + + // + // ProcessCommandLine - process the provided command line arguments. + // + HRESULT ProcessCommandLine(__inout LPWSTR* psczLanguage) { + HRESULT hr = S_OK; + int argc = 0; + LPWSTR* argv = nullptr; + LPWSTR sczVariableName = nullptr; + LPWSTR sczVariableValue = nullptr; + + if (_command.wzCommandLine && *_command.wzCommandLine) { + argv = ::CommandLineToArgvW(_command.wzCommandLine, &argc); + ExitOnNullWithLastError(argv, hr, "Failed to get command line."); + + for (int i = 0; i < argc; ++i) { + if (argv[i][0] == L'-' || argv[i][0] == L'/') { + if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"lang", -1)) { + if (i + 1 >= argc) { + hr = E_INVALIDARG; + BalExitOnFailure(hr, "Must specify a language."); + } + + ++i; + + hr = StrAllocString(psczLanguage, &argv[i][0], 0); + BalExitOnFailure(hr, "Failed to copy language."); + } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"simple", -1)) { + _engine->SetVariableNumeric(L"SimpleInstall", 1); + } + } else if (_overridableVariables) { + int value; + const wchar_t* pwc = wcschr(argv[i], L'='); + if (pwc) { + hr = StrAllocString(&sczVariableName, argv[i], pwc - argv[i]); + BalExitOnFailure(hr, "Failed to copy variable name."); + + hr = DictKeyExists(_overridableVariables, sczVariableName); + if (E_NOTFOUND == hr) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Ignoring attempt to set non-overridable variable: '%ls'.", sczVariableName); + hr = S_OK; + continue; + } + ExitOnFailure(hr, "Failed to check the dictionary of overridable variables."); + + hr = StrAllocString(&sczVariableValue, ++pwc, 0); + BalExitOnFailure(hr, "Failed to copy variable value."); + + if (::StrToIntEx(sczVariableValue, STIF_DEFAULT, &value)) { + hr = _engine->SetVariableNumeric(sczVariableName, value); + } else { + hr = _engine->SetVariableString(sczVariableName, sczVariableValue); + } + BalExitOnFailure(hr, "Failed to set variable."); + } else { + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Ignoring unknown argument: %ls", argv[i]); + } + } + } + } + + LExit: + if (argv) { + ::LocalFree(argv); + } + + ReleaseStr(sczVariableName); + ReleaseStr(sczVariableValue); + + return hr; + } + + HRESULT LoadLocalization(__in_z LPCWSTR wzModulePath, __in_z_opt LPCWSTR wzLanguage) { + HRESULT hr = S_OK; + LPWSTR sczLocPath = nullptr; + LPCWSTR wzLocFileName = L"Default.wxl"; + + hr = LocProbeForFile(wzModulePath, wzLocFileName, wzLanguage, &sczLocPath); + BalExitOnFailure2(hr, "Failed to probe for loc file: %ls in path: %ls", wzLocFileName, wzModulePath); + + hr = LocLoadFromFile(sczLocPath, &_wixLoc); + BalExitOnFailure1(hr, "Failed to load loc file from path: %ls", sczLocPath); + + if (WIX_LOCALIZATION_LANGUAGE_NOT_SET != _wixLoc->dwLangId) { + ::SetThreadLocale(_wixLoc->dwLangId); + } + + hr = StrAllocString(&_confirmCloseMessage, L"#(loc.ConfirmCancelMessage)", 0); + ExitOnFailure(hr, "Failed to initialize confirm message loc identifier."); + + hr = LocLocalizeString(_wixLoc, &_confirmCloseMessage); + BalExitOnFailure1(hr, "Failed to localize confirm close message: %ls", _confirmCloseMessage); + + LExit: + ReleaseStr(sczLocPath); + + return hr; + } + + + HRESULT LoadTheme(__in_z LPCWSTR wzModulePath, __in_z_opt LPCWSTR wzLanguage) { + HRESULT hr = S_OK; + LPWSTR sczThemePath = nullptr; + LPCWSTR wzThemeFileName = L"Default.thm"; + LPWSTR sczCaption = nullptr; + + hr = LocProbeForFile(wzModulePath, wzThemeFileName, wzLanguage, &sczThemePath); + BalExitOnFailure2(hr, "Failed to probe for theme file: %ls in path: %ls", wzThemeFileName, wzModulePath); + + hr = ThemeLoadFromFile(sczThemePath, &_theme); + BalExitOnFailure1(hr, "Failed to load theme from path: %ls", sczThemePath); + + hr = ThemeLocalize(_theme, _wixLoc); + BalExitOnFailure1(hr, "Failed to localize theme: %ls", sczThemePath); + + // Update the caption if there are any formatted strings in it. + // If the wix developer is showing a hidden variable in the UI, then + // obviously they don't care about keeping it safe so don't go down the + // rabbit hole of making sure that this is securely freed. + hr = BalFormatString(_theme->sczCaption, &sczCaption); + if (SUCCEEDED(hr)) { + ThemeUpdateCaption(_theme, sczCaption); + } + + LExit: + ReleaseStr(sczCaption); + ReleaseStr(sczThemePath); + + return hr; + } + + + HRESULT ParseOverridableVariablesFromXml(__in IXMLDOMDocument* pixdManifest) { + HRESULT hr = S_OK; + IXMLDOMNode* pNode = nullptr; + IXMLDOMNodeList* pNodes = nullptr; + DWORD cNodes = 0; + LPWSTR scz = nullptr; + BOOL hidden = FALSE; + + // get the list of variables users can override on the command line + hr = XmlSelectNodes(pixdManifest, L"/BootstrapperApplicationData/WixStdbaOverridableVariable", &pNodes); + if (S_FALSE == hr) { + ExitFunction1(hr = S_OK); + } + ExitOnFailure(hr, "Failed to select overridable variable nodes."); + + hr = pNodes->get_length((long*)&cNodes); + ExitOnFailure(hr, "Failed to get overridable variable node count."); + + if (cNodes) { + hr = DictCreateStringList(&_overridableVariables, 32, DICT_FLAG_NONE); + ExitOnFailure(hr, "Failed to create the string dictionary."); + + for (DWORD i = 0; i < cNodes; ++i) { + hr = XmlNextElement(pNodes, &pNode, nullptr); + ExitOnFailure(hr, "Failed to get next node."); + + // @Name + hr = XmlGetAttributeEx(pNode, L"Name", &scz); + ExitOnFailure(hr, "Failed to get @Name."); + + hr = XmlGetYesNoAttribute(pNode, L"Hidden", &hidden); + + if (!hidden) { + hr = DictAddKey(_overridableVariables, scz); + ExitOnFailure1(hr, "Failed to add \"%ls\" to the string dictionary.", scz); + } + + // prepare next iteration + ReleaseNullObject(pNode); + } + } + + LExit: + ReleaseObject(pNode); + ReleaseObject(pNodes); + ReleaseStr(scz); + return hr; + } + + + // + // Get the file version of the bootstrapper and record in bootstrapper log file + // + HRESULT GetBundleFileVersion() { + HRESULT hr = S_OK; + ULARGE_INTEGER uliVersion = { }; + LPWSTR sczCurrentPath = nullptr; + + hr = PathForCurrentProcess(&sczCurrentPath, nullptr); + BalExitOnFailure(hr, "Failed to get bundle path."); + + hr = FileVersion(sczCurrentPath, &uliVersion.HighPart, &uliVersion.LowPart); + BalExitOnFailure(hr, "Failed to get bundle file version."); + + hr = _engine->SetVariableVersion(PYBA_VARIABLE_BUNDLE_FILE_VERSION, uliVersion.QuadPart); + BalExitOnFailure(hr, "Failed to set WixBundleFileVersion variable."); + + LExit: + ReleaseStr(sczCurrentPath); + + return hr; + } + + + // + // CreateMainWindow - creates the main install window. + // + HRESULT CreateMainWindow() { + HRESULT hr = S_OK; + HICON hIcon = reinterpret_cast(_theme->hIcon); + WNDCLASSW wc = { }; + DWORD dwWindowStyle = 0; + int x = CW_USEDEFAULT; + int y = CW_USEDEFAULT; + POINT ptCursor = { }; + HMONITOR hMonitor = nullptr; + MONITORINFO mi = { }; + COLORREF fg, bg; + HBRUSH bgBrush; + + // If the theme did not provide an icon, try using the icon from the bundle engine. + if (!hIcon) { + HMODULE hBootstrapperEngine = ::GetModuleHandleW(nullptr); + if (hBootstrapperEngine) { + hIcon = ::LoadIconW(hBootstrapperEngine, MAKEINTRESOURCEW(1)); + } + } + + fg = RGB(0, 0, 0); + bg = RGB(255, 255, 255); + bgBrush = (HBRUSH)(COLOR_WINDOW+1); + if (_theme->dwFontId < _theme->cFonts) { + THEME_FONT *font = &_theme->rgFonts[_theme->dwFontId]; + fg = font->crForeground; + bg = font->crBackground; + bgBrush = font->hBackground; + RemapColor(&fg, &bg, &bgBrush); + } + + // Register the window class and create the window. + wc.lpfnWndProc = PythonBootstrapperApplication::WndProc; + wc.hInstance = _hModule; + wc.hIcon = hIcon; + wc.hCursor = ::LoadCursorW(nullptr, (LPCWSTR)IDC_ARROW); + wc.hbrBackground = bgBrush; + wc.lpszMenuName = nullptr; + wc.lpszClassName = PYBA_WINDOW_CLASS; + if (!::RegisterClassW(&wc)) { + ExitWithLastError(hr, "Failed to register window."); + } + + _registered = TRUE; + + // Calculate the window style based on the theme style and command display value. + dwWindowStyle = _theme->dwStyle; + if (BOOTSTRAPPER_DISPLAY_NONE >= _command.display) { + dwWindowStyle &= ~WS_VISIBLE; + } + + // Don't show the window if there is a splash screen (it will be made visible when the splash screen is hidden) + if (::IsWindow(_command.hwndSplashScreen)) { + dwWindowStyle &= ~WS_VISIBLE; + } + + // Center the window on the monitor with the mouse. + if (::GetCursorPos(&ptCursor)) { + hMonitor = ::MonitorFromPoint(ptCursor, MONITOR_DEFAULTTONEAREST); + if (hMonitor) { + mi.cbSize = sizeof(mi); + if (::GetMonitorInfoW(hMonitor, &mi)) { + x = mi.rcWork.left + (mi.rcWork.right - mi.rcWork.left - _theme->nWidth) / 2; + y = mi.rcWork.top + (mi.rcWork.bottom - mi.rcWork.top - _theme->nHeight) / 2; + } + } + } + + _hWnd = ::CreateWindowExW( + 0, + wc.lpszClassName, + _theme->sczCaption, + dwWindowStyle, + x, + y, + _theme->nWidth, + _theme->nHeight, + HWND_DESKTOP, + nullptr, + _hModule, + this + ); + ExitOnNullWithLastError(_hWnd, hr, "Failed to create window."); + + hr = S_OK; + + LExit: + return hr; + } + + + // + // InitializeTaskbarButton - initializes taskbar button for progress. + // + void InitializeTaskbarButton() { + HRESULT hr = S_OK; + + hr = ::CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_ALL, __uuidof(ITaskbarList3), reinterpret_cast(&_taskbarList)); + if (REGDB_E_CLASSNOTREG == hr) { + // not supported before Windows 7 + ExitFunction1(hr = S_OK); + } + BalExitOnFailure(hr, "Failed to create ITaskbarList3. Continuing."); + + _taskbarButtonCreatedMessage = ::RegisterWindowMessageW(L"TaskbarButtonCreated"); + BalExitOnNullWithLastError(_taskbarButtonCreatedMessage, hr, "Failed to get TaskbarButtonCreated message. Continuing."); + + LExit: + return; + } + + // + // DestroyMainWindow - clean up all the window registration. + // + void DestroyMainWindow() { + if (::IsWindow(_hWnd)) { + ::DestroyWindow(_hWnd); + _hWnd = nullptr; + _taskbarButtonOK = FALSE; + } + + if (_registered) { + ::UnregisterClassW(PYBA_WINDOW_CLASS, _hModule); + _registered = FALSE; + } + } + + + // + // WndProc - standard windows message handler. + // + static LRESULT CALLBACK WndProc( + __in HWND hWnd, + __in UINT uMsg, + __in WPARAM wParam, + __in LPARAM lParam + ) { +#pragma warning(suppress:4312) + auto pBA = reinterpret_cast(::GetWindowLongPtrW(hWnd, GWLP_USERDATA)); + + switch (uMsg) { + case WM_NCCREATE: { + LPCREATESTRUCT lpcs = reinterpret_cast(lParam); + pBA = reinterpret_cast(lpcs->lpCreateParams); +#pragma warning(suppress:4244) + ::SetWindowLongPtrW(hWnd, GWLP_USERDATA, reinterpret_cast(pBA)); + break; + } + + case WM_NCDESTROY: { + LRESULT lres = ThemeDefWindowProc(pBA ? pBA->_theme : nullptr, hWnd, uMsg, wParam, lParam); + ::SetWindowLongPtrW(hWnd, GWLP_USERDATA, 0); + return lres; + } + + case WM_CREATE: + if (!pBA->OnCreate(hWnd)) { + return -1; + } + break; + + case WM_QUERYENDSESSION: + return IDCANCEL != pBA->OnSystemShutdown(static_cast(lParam), IDCANCEL); + + case WM_CLOSE: + // If the user chose not to close, do *not* let the default window proc handle the message. + if (!pBA->OnClose()) { + return 0; + } + break; + + case WM_DESTROY: + ::PostQuitMessage(0); + break; + + case WM_PAINT: __fallthrough; + case WM_ERASEBKGND: + if (pBA && pBA->_suppressPaint) { + return TRUE; + } + break; + + case WM_PYBA_SHOW_HELP: + pBA->OnShowHelp(); + return 0; + + case WM_PYBA_DETECT_PACKAGES: + pBA->OnDetect(); + return 0; + + case WM_PYBA_PLAN_PACKAGES: + pBA->OnPlan(static_cast(lParam)); + return 0; + + case WM_PYBA_APPLY_PACKAGES: + pBA->OnApply(); + return 0; + + case WM_PYBA_CHANGE_STATE: + pBA->OnChangeState(static_cast(lParam)); + return 0; + + case WM_PYBA_SHOW_FAILURE: + pBA->OnShowFailure(); + return 0; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + // Customize commands + // Success/failure commands + case ID_LAUNCH_BUTTON: + pBA->OnClickLaunchButton(); + return 0; + + case ID_SUCCESS_RESTART_BUTTON: __fallthrough; + case ID_FAILURE_RESTART_BUTTON: + pBA->OnClickRestartButton(); + return 0; + + case IDCANCEL: __fallthrough; + case ID_INSTALL_CANCEL_BUTTON: __fallthrough; + case ID_CUSTOM1_CANCEL_BUTTON: __fallthrough; + case ID_CUSTOM2_CANCEL_BUTTON: __fallthrough; + case ID_MODIFY_CANCEL_BUTTON: __fallthrough; + case ID_PROGRESS_CANCEL_BUTTON: __fallthrough; + case ID_SUCCESS_CANCEL_BUTTON: __fallthrough; + case ID_FAILURE_CANCEL_BUTTON: __fallthrough; + case ID_CLOSE_BUTTON: + pBA->OnCommand(ID_CLOSE_BUTTON); + return 0; + + default: + pBA->OnCommand((CONTROL_ID)LOWORD(wParam)); + } + break; + + case WM_NOTIFY: + if (lParam) { + LPNMHDR pnmhdr = reinterpret_cast(lParam); + switch (pnmhdr->code) { + case NM_CLICK: __fallthrough; + case NM_RETURN: + switch (static_cast(pnmhdr->idFrom)) { + case ID_FAILURE_LOGFILE_LINK: + pBA->OnClickLogFileLink(); + return 1; + } + } + } + break; + + case WM_CTLCOLORSTATIC: + case WM_CTLCOLORBTN: + if (pBA) { + HBRUSH brush = nullptr; + if (pBA->SetControlColor((HWND)lParam, (HDC)wParam, &brush)) { + return (LRESULT)brush; + } + } + break; + } + + if (pBA && pBA->_taskbarList && uMsg == pBA->_taskbarButtonCreatedMessage) { + pBA->_taskbarButtonOK = TRUE; + return 0; + } + + return ThemeDefWindowProc(pBA ? pBA->_theme : nullptr, hWnd, uMsg, wParam, lParam); + } + + // + // OnCreate - finishes loading the theme. + // + BOOL OnCreate(__in HWND hWnd) { + HRESULT hr = S_OK; + + hr = ThemeLoadControls(_theme, hWnd, CONTROL_ID_NAMES, countof(CONTROL_ID_NAMES)); + BalExitOnFailure(hr, "Failed to load theme controls."); + + C_ASSERT(COUNT_PAGE == countof(PAGE_NAMES)); + C_ASSERT(countof(_pageIds) == countof(PAGE_NAMES)); + + ThemeGetPageIds(_theme, PAGE_NAMES, _pageIds, countof(_pageIds)); + + // Initialize the text on all "application" (non-page) controls. + for (DWORD i = 0; i < _theme->cControls; ++i) { + THEME_CONTROL* pControl = _theme->rgControls + i; + LPWSTR text = nullptr; + LPWSTR name = nullptr; + LOC_STRING *locText = nullptr; + + // If a command link has a note, then add it. + if ((pControl->dwStyle & BS_TYPEMASK) == BS_COMMANDLINK || + (pControl->dwStyle & BS_TYPEMASK) == BS_DEFCOMMANDLINK) { + hr = StrAllocFormatted(&name, L"#(loc.%lsNote)", pControl->sczName); + if (SUCCEEDED(hr)) { + hr = LocGetString(_wixLoc, name, &locText); + ReleaseStr(name); + if (SUCCEEDED(hr) && locText && locText->wzText && locText->wzText[0]) { + hr = BalFormatString(locText->wzText, &text); + if (SUCCEEDED(hr) && text && text[0]) { + ThemeSendControlMessage(_theme, pControl->wId, BCM_SETNOTE, 0, (LPARAM)text); + ReleaseStr(text); + text = nullptr; + } + } + } + hr = S_OK; + } + + if (!pControl->wPageId && pControl->sczText && *pControl->sczText) { + HRESULT hrFormat; + + // If the wix developer is showing a hidden variable in the UI, + // then obviously they don't care about keeping it safe so don't + // go down the rabbit hole of making sure that this is securely + // freed. + hrFormat = BalFormatString(pControl->sczText, &text); + if (SUCCEEDED(hrFormat)) { + ThemeSetTextControl(_theme, pControl->wId, text); + ReleaseStr(text); + } + } + } + + LExit: + return SUCCEEDED(hr); + } + + void RemapColor(COLORREF *fg, COLORREF *bg, HBRUSH *bgBrush) { + if (*fg == RGB(0, 0, 0)) { + *fg = GetSysColor(COLOR_WINDOWTEXT); + } else if (*fg == RGB(128, 128, 128)) { + *fg = GetSysColor(COLOR_GRAYTEXT); + } + if (*bgBrush && *bg == RGB(255, 255, 255)) { + *bg = GetSysColor(COLOR_WINDOW); + *bgBrush = GetSysColorBrush(COLOR_WINDOW); + } + } + + BOOL SetControlColor(HWND hWnd, HDC hDC, HBRUSH *brush) { + for (int i = 0; i < _theme->cControls; ++i) { + if (_theme->rgControls[i].hWnd != hWnd) { + continue; + } + + DWORD fontId = _theme->rgControls[i].dwFontId; + if (fontId > _theme->cFonts) { + fontId = 0; + } + THEME_FONT *fnt = &_theme->rgFonts[fontId]; + + COLORREF fg = fnt->crForeground, bg = fnt->crBackground; + *brush = fnt->hBackground; + RemapColor(&fg, &bg, brush); + ::SetTextColor(hDC, fg); + ::SetBkColor(hDC, bg); + + return TRUE; + } + return FALSE; + } + + // + // OnShowFailure - display the failure page. + // + void OnShowFailure() { + SetState(PYBA_STATE_FAILED, S_OK); + + // If the UI should be visible, display it now and hide the splash screen + if (BOOTSTRAPPER_DISPLAY_NONE < _command.display) { + ::ShowWindow(_theme->hwndParent, SW_SHOW); + } + + _engine->CloseSplashScreen(); + + return; + } + + + // + // OnShowHelp - display the help page. + // + void OnShowHelp() { + SetState(PYBA_STATE_HELP, S_OK); + + // If the UI should be visible, display it now and hide the splash screen + if (BOOTSTRAPPER_DISPLAY_NONE < _command.display) { + ::ShowWindow(_theme->hwndParent, SW_SHOW); + } + + _engine->CloseSplashScreen(); + + return; + } + + + // + // OnDetect - start the processing of packages. + // + void OnDetect() { + HRESULT hr = S_OK; + + if (_baFunction) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Running detect BA function"); + hr = _baFunction->OnDetect(); + BalExitOnFailure(hr, "Failed calling detect BA function."); + } + + SetState(PYBA_STATE_DETECTING, hr); + + // If the UI should be visible, display it now and hide the splash screen + if (BOOTSTRAPPER_DISPLAY_NONE < _command.display) { + ::ShowWindow(_theme->hwndParent, SW_SHOW); + } + + _engine->CloseSplashScreen(); + + // Tell the core we're ready for the packages to be processed now. + hr = _engine->Detect(); + BalExitOnFailure(hr, "Failed to start detecting chain."); + + LExit: + if (FAILED(hr)) { + SetState(PYBA_STATE_DETECTING, hr); + } + + return; + } + HRESULT UpdateUIStrings(__in BOOTSTRAPPER_ACTION action) { + HRESULT hr = S_OK; + LPCWSTR likeInstalling = nullptr; + LPCWSTR likeInstallation = nullptr; + switch (action) { + case BOOTSTRAPPER_ACTION_INSTALL: + likeInstalling = L"Installing"; + likeInstallation = L"Installation"; + break; + case BOOTSTRAPPER_ACTION_MODIFY: + // For modify, we actually want to pass INSTALL + action = BOOTSTRAPPER_ACTION_INSTALL; + likeInstalling = L"Modifying"; + likeInstallation = L"Modification"; + break; + case BOOTSTRAPPER_ACTION_REPAIR: + likeInstalling = L"Repairing"; + likeInstallation = L"Repair"; + break; + case BOOTSTRAPPER_ACTION_UNINSTALL: + likeInstalling = L"Uninstalling"; + likeInstallation = L"Uninstallation"; + break; + } + + if (likeInstalling) { + LPWSTR locName = nullptr; + LOC_STRING *locText = nullptr; + hr = StrAllocFormatted(&locName, L"#(loc.%ls)", likeInstalling); + if (SUCCEEDED(hr)) { + hr = LocGetString(_wixLoc, locName, &locText); + ReleaseStr(locName); + } + _engine->SetVariableString( + L"ActionLikeInstalling", + SUCCEEDED(hr) && locText ? locText->wzText : likeInstalling + ); + } + + if (likeInstallation) { + LPWSTR locName = nullptr; + LOC_STRING *locText = nullptr; + hr = StrAllocFormatted(&locName, L"#(loc.%ls)", likeInstallation); + if (SUCCEEDED(hr)) { + hr = LocGetString(_wixLoc, locName, &locText); + ReleaseStr(locName); + } + _engine->SetVariableString( + L"ActionLikeInstallation", + SUCCEEDED(hr) && locText ? locText->wzText : likeInstallation + ); + } + return hr; + } + + // + // OnPlan - plan the detected changes. + // + void OnPlan(__in BOOTSTRAPPER_ACTION action) { + HRESULT hr = S_OK; + + _plannedAction = action; + + hr = UpdateUIStrings(action); + BalExitOnFailure(hr, "Failed to update strings"); + + // If we are going to apply a downgrade, bail. + if (_downgradingOtherVersion && BOOTSTRAPPER_ACTION_UNINSTALL < action) { + if (_suppressDowngradeFailure) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "A newer version of this product is installed but downgrade failure has been suppressed; continuing..."); + } else { + hr = HRESULT_FROM_WIN32(ERROR_PRODUCT_VERSION); + BalExitOnFailure(hr, "Cannot install a product when a newer version is installed."); + } + } + + SetState(PYBA_STATE_PLANNING, hr); + + if (_baFunction) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Running plan BA function"); + _baFunction->OnPlan(); + } + + hr = _engine->Plan(action); + BalExitOnFailure(hr, "Failed to start planning packages."); + + LExit: + if (FAILED(hr)) { + SetState(PYBA_STATE_PLANNING, hr); + } + + return; + } + + + // + // OnApply - apply the packages. + // + void OnApply() { + HRESULT hr = S_OK; + + SetState(PYBA_STATE_APPLYING, hr); + SetProgressState(hr); + SetTaskbarButtonProgress(0); + + hr = _engine->Apply(_hWnd); + BalExitOnFailure(hr, "Failed to start applying packages."); + + ThemeControlEnable(_theme, ID_PROGRESS_CANCEL_BUTTON, TRUE); // ensure the cancel button is enabled before starting. + + LExit: + if (FAILED(hr)) { + SetState(PYBA_STATE_APPLYING, hr); + } + + return; + } + + + // + // OnChangeState - change state. + // + void OnChangeState(__in PYBA_STATE state) { + LPWSTR unformattedText = nullptr; + + _state = state; + + // If our install is at the end (success or failure) and we're not showing full UI + // then exit (prompt for restart if required). + if ((PYBA_STATE_APPLIED <= _state && BOOTSTRAPPER_DISPLAY_FULL > _command.display)) { + // If a restart was required but we were not automatically allowed to + // accept the reboot then do the prompt. + if (_restartRequired && !_allowRestart) { + StrAllocFromError(&unformattedText, HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED), nullptr); + + _allowRestart = IDOK == ::MessageBoxW( + _hWnd, + unformattedText ? unformattedText : L"The requested operation is successful. Changes will not be effective until the system is rebooted.", + _theme->sczCaption, + MB_ICONEXCLAMATION | MB_OKCANCEL + ); + } + + // Quietly exit. + ::PostMessageW(_hWnd, WM_CLOSE, 0, 0); + } else { // try to change the pages. + DWORD newPageId = 0; + DeterminePageId(_state, &newPageId); + + if (_visiblePageId != newPageId) { + ShowPage(newPageId); + } + } + + ReleaseStr(unformattedText); + } + + // + // Called before showing a page to handle all controls. + // + void ProcessPageControls(THEME_PAGE *pPage) { + if (!pPage) { + return; + } + + for (DWORD i = 0; i < pPage->cControlIndices; ++i) { + THEME_CONTROL* pControl = _theme->rgControls + pPage->rgdwControlIndices[i]; + BOOL enableControl = TRUE; + + // If this is a named control, try to set its default state. + if (pControl->sczName && *pControl->sczName) { + // If this is a checkable control, try to set its default state + // to the state of a matching named Burn variable. + if (IsCheckable(pControl)) { + LONGLONG llValue = 0; + HRESULT hr = BalGetNumericVariable(pControl->sczName, &llValue); + + // If the control value isn't set then disable it. + if (!SUCCEEDED(hr)) { + enableControl = FALSE; + } else { + ThemeSendControlMessage( + _theme, + pControl->wId, + BM_SETCHECK, + SUCCEEDED(hr) && llValue ? BST_CHECKED : BST_UNCHECKED, + 0 + ); + } + } + + // Hide or disable controls based on the control name with 'State' appended + LPWSTR controlName = nullptr; + HRESULT hr = StrAllocFormatted(&controlName, L"%lsState", pControl->sczName); + if (SUCCEEDED(hr)) { + LPWSTR controlState = nullptr; + hr = BalGetStringVariable(controlName, &controlState); + if (SUCCEEDED(hr) && controlState && *controlState) { + if (controlState[0] == '[') { + LPWSTR formatted = nullptr; + if (SUCCEEDED(BalFormatString(controlState, &formatted))) { + StrFree(controlState); + controlState = formatted; + } + } + + if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, controlState, -1, L"disable", -1)) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Disable control %ls", pControl->sczName); + enableControl = FALSE; + } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, controlState, -1, L"hide", -1)) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Hide control %ls", pControl->sczName); + // TODO: This doesn't work + ThemeShowControl(_theme, pControl->wId, SW_HIDE); + } else { + // An explicit state can override the lack of a + // backing variable. + enableControl = TRUE; + } + } + StrFree(controlState); + } + StrFree(controlName); + } + + ThemeControlEnable(_theme, pControl->wId, enableControl); + + // Format the text in each of the new page's controls + if (pControl->sczText && *pControl->sczText) { + // If the wix developer is showing a hidden variable + // in the UI, then obviously they don't care about + // keeping it safe so don't go down the rabbit hole + // of making sure that this is securely freed. + LPWSTR text = nullptr; + HRESULT hr = BalFormatString(pControl->sczText, &text); + if (SUCCEEDED(hr)) { + ThemeSetTextControl(_theme, pControl->wId, text); + } + } + } + } + + // + // OnClose - called when the window is trying to be closed. + // + BOOL OnClose() { + BOOL close = FALSE; + + // If we've already succeeded or failed or showing the help page, just close (prompts are annoying if the bootstrapper is done). + if (PYBA_STATE_APPLIED <= _state || PYBA_STATE_HELP == _state) { + close = TRUE; + } else { + // prompt the user or force the cancel if there is no UI. + close = PromptCancel( + _hWnd, + BOOTSTRAPPER_DISPLAY_FULL != _command.display, + _confirmCloseMessage ? _confirmCloseMessage : L"Are you sure you want to cancel?", + _theme->sczCaption + ); + } + + // If we're doing progress then we never close, we just cancel to let rollback occur. + if (PYBA_STATE_APPLYING <= _state && PYBA_STATE_APPLIED > _state) { + // If we canceled disable cancel button since clicking it again is silly. + if (close) { + ThemeControlEnable(_theme, ID_PROGRESS_CANCEL_BUTTON, FALSE); + } + + close = FALSE; + } + + return close; + } + + // + // OnClickCloseButton - close the application. + // + void OnClickCloseButton() { + ::SendMessageW(_hWnd, WM_CLOSE, 0, 0); + } + + + // + // OnClickLaunchButton - launch the app from the success page. + // + void OnClickLaunchButton() { + HRESULT hr = S_OK; + LPWSTR sczUnformattedLaunchTarget = nullptr; + LPWSTR sczLaunchTarget = nullptr; + LPWSTR sczLaunchTargetElevatedId = nullptr; + LPWSTR sczUnformattedArguments = nullptr; + LPWSTR sczArguments = nullptr; + int nCmdShow = SW_SHOWNORMAL; + + hr = BalGetStringVariable(PYBA_VARIABLE_LAUNCH_TARGET_PATH, &sczUnformattedLaunchTarget); + BalExitOnFailure1(hr, "Failed to get launch target variable '%ls'.", PYBA_VARIABLE_LAUNCH_TARGET_PATH); + + hr = BalFormatString(sczUnformattedLaunchTarget, &sczLaunchTarget); + BalExitOnFailure1(hr, "Failed to format launch target variable: %ls", sczUnformattedLaunchTarget); + + if (BalStringVariableExists(PYBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID)) { + hr = BalGetStringVariable(PYBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID, &sczLaunchTargetElevatedId); + BalExitOnFailure1(hr, "Failed to get launch target elevated id '%ls'.", PYBA_VARIABLE_LAUNCH_TARGET_ELEVATED_ID); + } + + if (BalStringVariableExists(PYBA_VARIABLE_LAUNCH_ARGUMENTS)) { + hr = BalGetStringVariable(PYBA_VARIABLE_LAUNCH_ARGUMENTS, &sczUnformattedArguments); + BalExitOnFailure1(hr, "Failed to get launch arguments '%ls'.", PYBA_VARIABLE_LAUNCH_ARGUMENTS); + } + + if (BalStringVariableExists(PYBA_VARIABLE_LAUNCH_HIDDEN)) { + nCmdShow = SW_HIDE; + } + + if (sczLaunchTargetElevatedId && !_triedToLaunchElevated) { + _triedToLaunchElevated = TRUE; + hr = _engine->LaunchApprovedExe(_hWnd, sczLaunchTargetElevatedId, sczUnformattedArguments, 0); + if (FAILED(hr)) { + BalLogError(hr, "Failed to launch elevated target: %ls", sczLaunchTargetElevatedId); + + //try with ShelExec next time + OnClickLaunchButton(); + } + } else { + if (sczUnformattedArguments) { + hr = BalFormatString(sczUnformattedArguments, &sczArguments); + BalExitOnFailure1(hr, "Failed to format launch arguments variable: %ls", sczUnformattedArguments); + } + + hr = ShelExec(sczLaunchTarget, sczArguments, L"open", nullptr, nCmdShow, _hWnd, nullptr); + BalExitOnFailure1(hr, "Failed to launch target: %ls", sczLaunchTarget); + + ::PostMessageW(_hWnd, WM_CLOSE, 0, 0); + } + + LExit: + StrSecureZeroFreeString(sczArguments); + ReleaseStr(sczUnformattedArguments); + ReleaseStr(sczLaunchTargetElevatedId); + StrSecureZeroFreeString(sczLaunchTarget); + ReleaseStr(sczUnformattedLaunchTarget); + + return; + } + + + // + // OnClickRestartButton - allows the restart and closes the app. + // + void OnClickRestartButton() { + AssertSz(_restartRequired, "Restart must be requested to be able to click on the restart button."); + + _allowRestart = TRUE; + ::SendMessageW(_hWnd, WM_CLOSE, 0, 0); + + return; + } + + + // + // OnClickLogFileLink - show the log file. + // + void OnClickLogFileLink() { + HRESULT hr = S_OK; + LPWSTR sczLogFile = nullptr; + + hr = BalGetStringVariable(_bundle.sczLogVariable, &sczLogFile); + BalExitOnFailure1(hr, "Failed to get log file variable '%ls'.", _bundle.sczLogVariable); + + hr = ShelExec(L"notepad.exe", sczLogFile, L"open", nullptr, SW_SHOWDEFAULT, _hWnd, nullptr); + BalExitOnFailure1(hr, "Failed to open log file target: %ls", sczLogFile); + + LExit: + ReleaseStr(sczLogFile); + + return; + } + + + // + // SetState + // + void SetState(__in PYBA_STATE state, __in HRESULT hrStatus) { + if (FAILED(hrStatus)) { + _hrFinal = hrStatus; + } + + if (FAILED(_hrFinal)) { + state = PYBA_STATE_FAILED; + } + + if (_state != state) { + ::PostMessageW(_hWnd, WM_PYBA_CHANGE_STATE, 0, state); + } + } + + // + // GoToPage + // + void GoToPage(__in PAGE page) { + _installPage = page; + ::PostMessageW(_hWnd, WM_PYBA_CHANGE_STATE, 0, _state); + } + + void DeterminePageId(__in PYBA_STATE state, __out DWORD* pdwPageId) { + LONGLONG simple; + + if (BOOTSTRAPPER_DISPLAY_PASSIVE == _command.display) { + switch (state) { + case PYBA_STATE_INITIALIZED: + *pdwPageId = BOOTSTRAPPER_ACTION_HELP == _command.action + ? _pageIds[PAGE_HELP] + : _pageIds[PAGE_LOADING]; + break; + + case PYBA_STATE_HELP: + *pdwPageId = _pageIds[PAGE_HELP]; + break; + + case PYBA_STATE_DETECTING: + *pdwPageId = _pageIds[PAGE_LOADING] + ? _pageIds[PAGE_LOADING] + : _pageIds[PAGE_PROGRESS_PASSIVE] + ? _pageIds[PAGE_PROGRESS_PASSIVE] + : _pageIds[PAGE_PROGRESS]; + break; + + case PYBA_STATE_DETECTED: __fallthrough; + case PYBA_STATE_PLANNING: __fallthrough; + case PYBA_STATE_PLANNED: __fallthrough; + case PYBA_STATE_APPLYING: __fallthrough; + case PYBA_STATE_CACHING: __fallthrough; + case PYBA_STATE_CACHED: __fallthrough; + case PYBA_STATE_EXECUTING: __fallthrough; + case PYBA_STATE_EXECUTED: + *pdwPageId = _pageIds[PAGE_PROGRESS_PASSIVE] + ? _pageIds[PAGE_PROGRESS_PASSIVE] + : _pageIds[PAGE_PROGRESS]; + break; + + default: + *pdwPageId = 0; + break; + } + } else if (BOOTSTRAPPER_DISPLAY_FULL == _command.display) { + switch (state) { + case PYBA_STATE_INITIALIZING: + *pdwPageId = 0; + break; + + case PYBA_STATE_INITIALIZED: + *pdwPageId = BOOTSTRAPPER_ACTION_HELP == _command.action + ? _pageIds[PAGE_HELP] + : _pageIds[PAGE_LOADING]; + break; + + case PYBA_STATE_HELP: + *pdwPageId = _pageIds[PAGE_HELP]; + break; + + case PYBA_STATE_DETECTING: + *pdwPageId = _pageIds[PAGE_LOADING]; + break; + + case PYBA_STATE_DETECTED: + if (_installPage == PAGE_LOADING) { + switch (_command.action) { + case BOOTSTRAPPER_ACTION_INSTALL: + if (_upgradingOldVersion) { + _installPage = PAGE_UPGRADE; + _upgrading = TRUE; + } else if (SUCCEEDED(BalGetNumericVariable(L"SimpleInstall", &simple)) && simple) { + _installPage = PAGE_SIMPLE_INSTALL; + } else { + _installPage = PAGE_INSTALL; + } + break; + + case BOOTSTRAPPER_ACTION_MODIFY: __fallthrough; + case BOOTSTRAPPER_ACTION_REPAIR: __fallthrough; + case BOOTSTRAPPER_ACTION_UNINSTALL: + _installPage = PAGE_MODIFY; + break; + } + } + *pdwPageId = _pageIds[_installPage]; + break; + + case PYBA_STATE_PLANNING: __fallthrough; + case PYBA_STATE_PLANNED: __fallthrough; + case PYBA_STATE_APPLYING: __fallthrough; + case PYBA_STATE_CACHING: __fallthrough; + case PYBA_STATE_CACHED: __fallthrough; + case PYBA_STATE_EXECUTING: __fallthrough; + case PYBA_STATE_EXECUTED: + *pdwPageId = _pageIds[PAGE_PROGRESS]; + break; + + case PYBA_STATE_APPLIED: + *pdwPageId = _pageIds[PAGE_SUCCESS]; + break; + + case PYBA_STATE_FAILED: + *pdwPageId = _pageIds[PAGE_FAILURE]; + break; + } + } + } + + BOOL WillElevate() { + static BAL_CONDITION WILL_ELEVATE_CONDITION = { + L"not WixBundleElevated and (" + /*Elevate when installing for all users*/ + L"InstallAllUsers or" + /*Elevate when installing the launcher for all users and it was not detected*/ + L"(InstallLauncherAllUsers and Include_launcher and not DetectedLauncher) or" + /*Elevate when the launcher was installed for all users and it is being removed*/ + L"(DetectedLauncher and DetectedLauncherAllUsers and not Include_launcher)" + L")", + L"" + }; + BOOL result; + + return SUCCEEDED(BalConditionEvaluate(&WILL_ELEVATE_CONDITION, _engine, &result, nullptr)) && result; + } + + BOOL IsCrtInstalled() { + if (_crtInstalledToken > 0) { + return TRUE; + } else if (_crtInstalledToken == 0) { + return FALSE; + } + + // Check whether at least CRT v10.0.10137.0 is available. + // It should only be installed as a Windows Update package, which means + // we don't need to worry about 32-bit/64-bit. + LPCWSTR crtFile = L"ucrtbase.dll"; + + DWORD cbVer = GetFileVersionInfoSizeW(crtFile, nullptr); + if (!cbVer) { + _crtInstalledToken = 0; + return FALSE; + } + + void *pData = malloc(cbVer); + if (!pData) { + _crtInstalledToken = 0; + return FALSE; + } + + if (!GetFileVersionInfoW(crtFile, 0, cbVer, pData)) { + free(pData); + _crtInstalledToken = 0; + return FALSE; + } + + VS_FIXEDFILEINFO *ffi; + UINT cb; + BOOL result = FALSE; + + if (VerQueryValueW(pData, L"\\", (LPVOID*)&ffi, &cb) && + ffi->dwFileVersionMS == 0x000A0000 && ffi->dwFileVersionLS >= 0x27990000) { + result = TRUE; + } + + free(pData); + _crtInstalledToken = result ? 1 : 0; + return result; + } + + BOOL QueryElevateForCrtInstall() { + // Called to prompt the user that even though they think they won't need + // to elevate, they actually will because of the CRT install. + if (IsCrtInstalled()) { + // CRT is already installed - no need to prompt + return TRUE; + } + + LONGLONG elevated; + HRESULT hr = BalGetNumericVariable(L"WixBundleElevated", &elevated); + if (SUCCEEDED(hr) && elevated) { + // Already elevated - no need to prompt + return TRUE; + } + + LOC_STRING *locStr; + hr = LocGetString(_wixLoc, L"#(loc.ElevateForCRTInstall)", &locStr); + if (FAILED(hr)) { + BalLogError(hr, "Failed to get ElevateForCRTInstall string"); + return FALSE; + } + return ::MessageBoxW(_hWnd, locStr->wzText, _theme->sczCaption, MB_YESNO) != IDNO; + } + + HRESULT EvaluateConditions() { + HRESULT hr = S_OK; + BOOL result = FALSE; + + for (DWORD i = 0; i < _conditions.cConditions; ++i) { + BAL_CONDITION* pCondition = _conditions.rgConditions + i; + + hr = BalConditionEvaluate(pCondition, _engine, &result, &_failedMessage); + BalExitOnFailure(hr, "Failed to evaluate condition."); + + if (!result) { + // Hope they didn't have hidden variables in their message, because it's going in the log in plaintext. + BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "%ls", _failedMessage); + + hr = E_WIXSTDBA_CONDITION_FAILED; + // todo: remove in WiX v4, in case people are relying on v3.x logging behavior + BalExitOnFailure1(hr, "Bundle condition evaluated to false: %ls", pCondition->sczCondition); + } + } + + ReleaseNullStrSecure(_failedMessage); + + LExit: + return hr; + } + + + void SetTaskbarButtonProgress(__in DWORD dwOverallPercentage) { + HRESULT hr = S_OK; + + if (_taskbarButtonOK) { + hr = _taskbarList->SetProgressValue(_hWnd, dwOverallPercentage, 100UL); + BalExitOnFailure1(hr, "Failed to set taskbar button progress to: %d%%.", dwOverallPercentage); + } + + LExit: + return; + } + + + void SetTaskbarButtonState(__in TBPFLAG tbpFlags) { + HRESULT hr = S_OK; + + if (_taskbarButtonOK) { + hr = _taskbarList->SetProgressState(_hWnd, tbpFlags); + BalExitOnFailure1(hr, "Failed to set taskbar button state.", tbpFlags); + } + + LExit: + return; + } + + + void SetProgressState(__in HRESULT hrStatus) { + TBPFLAG flag = TBPF_NORMAL; + + if (IsCanceled() || HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) == hrStatus) { + flag = TBPF_PAUSED; + } else if (IsRollingBack() || FAILED(hrStatus)) { + flag = TBPF_ERROR; + } + + SetTaskbarButtonState(flag); + } + + + HRESULT LoadBootstrapperBAFunctions() { + HRESULT hr = S_OK; + LPWSTR sczBafPath = nullptr; + + hr = PathRelativeToModule(&sczBafPath, L"bafunctions.dll", _hModule); + BalExitOnFailure(hr, "Failed to get path to BA function DLL."); + +#ifdef DEBUG + BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "PYBA: LoadBootstrapperBAFunctions() - BA function DLL %ls", sczBafPath); +#endif + + _hBAFModule = ::LoadLibraryW(sczBafPath); + if (_hBAFModule) { + auto pfnBAFunctionCreate = reinterpret_cast(::GetProcAddress(_hBAFModule, "CreateBootstrapperBAFunction")); + BalExitOnNullWithLastError1(pfnBAFunctionCreate, hr, "Failed to get CreateBootstrapperBAFunction entry-point from: %ls", sczBafPath); + + hr = pfnBAFunctionCreate(_engine, _hBAFModule, &_baFunction); + BalExitOnFailure(hr, "Failed to create BA function."); + } +#ifdef DEBUG + else { + BalLogError(HRESULT_FROM_WIN32(::GetLastError()), "PYBA: LoadBootstrapperBAFunctions() - Failed to load DLL %ls", sczBafPath); + } +#endif + + LExit: + if (_hBAFModule && !_baFunction) { + ::FreeLibrary(_hBAFModule); + _hBAFModule = nullptr; + } + ReleaseStr(sczBafPath); + + return hr; + } + + BOOL IsCheckable(THEME_CONTROL* pControl) { + if (!pControl->sczName || !pControl->sczName[0]) { + return FALSE; + } + + if (pControl->type == THEME_CONTROL_TYPE_CHECKBOX) { + return TRUE; + } + + if (pControl->type == THEME_CONTROL_TYPE_BUTTON) { + if ((pControl->dwStyle & BS_TYPEMASK) == BS_AUTORADIOBUTTON) { + return TRUE; + } + } + + return FALSE; + } + + void SavePageSettings() { + DWORD pageId = 0; + THEME_PAGE* pPage = nullptr; + + DeterminePageId(_state, &pageId); + pPage = ThemeGetPage(_theme, pageId); + if (!pPage) { + return; + } + + for (DWORD i = 0; i < pPage->cControlIndices; ++i) { + // Loop through all the checkable controls and set a Burn variable + // with that name to true or false. + THEME_CONTROL* pControl = _theme->rgControls + pPage->rgdwControlIndices[i]; + if (IsCheckable(pControl) && ThemeControlEnabled(_theme, pControl->wId)) { + BOOL checked = ThemeIsControlChecked(_theme, pControl->wId); + _engine->SetVariableNumeric(pControl->sczName, checked ? 1 : 0); + } + + // Loop through all the editbox controls with names and set a + // Burn variable with that name to the contents. + if (THEME_CONTROL_TYPE_EDITBOX == pControl->type && pControl->sczName && *pControl->sczName) { + LPWSTR sczValue = nullptr; + ThemeGetTextControl(_theme, pControl->wId, &sczValue); + _engine->SetVariableString(pControl->sczName, sczValue); + } + } + } + + static bool IsTargetPlatformx64(__in IBootstrapperEngine* pEngine) { + WCHAR platform[8]; + DWORD platformLen = 8; + + if (FAILED(pEngine->GetVariableString(L"TargetPlatform", platform, &platformLen))) { + return S_FALSE; + } + + return ::CompareStringW(LOCALE_NEUTRAL, 0, platform, -1, L"x64", -1) == CSTR_EQUAL; + } + + static HRESULT LoadOptionalFeatureStatesFromKey( + __in IBootstrapperEngine* pEngine, + __in HKEY hkHive, + __in LPCWSTR subkey + ) { + HKEY hKey; + LRESULT res; + + if (IsTargetPlatformx64(pEngine)) { + res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_64KEY, &hKey); + } else { + res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_32KEY, &hKey); + } + if (res == ERROR_FILE_NOT_FOUND) { + return S_FALSE; + } + if (res != ERROR_SUCCESS) { + return HRESULT_FROM_WIN32(res); + } + + for (auto p = OPTIONAL_FEATURES; p->regName; ++p) { + res = RegQueryValueExW(hKey, p->regName, nullptr, nullptr, nullptr, nullptr); + if (res == ERROR_FILE_NOT_FOUND) { + pEngine->SetVariableNumeric(p->variableName, 0); + } else if (res == ERROR_SUCCESS) { + pEngine->SetVariableNumeric(p->variableName, 1); + } else { + RegCloseKey(hKey); + return HRESULT_FROM_WIN32(res); + } + } + + RegCloseKey(hKey); + return S_OK; + } + + static HRESULT LoadTargetDirFromKey( + __in IBootstrapperEngine* pEngine, + __in HKEY hkHive, + __in LPCWSTR subkey + ) { + HKEY hKey; + LRESULT res; + DWORD dataType; + BYTE buffer[1024]; + DWORD bufferLen = sizeof(buffer); + + if (IsTargetPlatformx64(pEngine)) { + res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_64KEY, &hKey); + } else { + res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_32KEY, &hKey); + } + if (res == ERROR_FILE_NOT_FOUND) { + return S_FALSE; + } + if (res != ERROR_SUCCESS) { + return HRESULT_FROM_WIN32(res); + } + + res = RegQueryValueExW(hKey, nullptr, nullptr, &dataType, buffer, &bufferLen); + if (res == ERROR_SUCCESS && dataType == REG_SZ && bufferLen < sizeof(buffer)) { + pEngine->SetVariableString(L"TargetDir", reinterpret_cast(buffer)); + } + RegCloseKey(hKey); + return HRESULT_FROM_WIN32(res); + } + + static HRESULT LoadLauncherStateFromKey( + __in IBootstrapperEngine* pEngine, + __in HKEY hkHive + ) { + const LPCWSTR subkey = L"Software\\Python\\PyLauncher"; + HKEY hKey; + LRESULT res; + + if (IsTargetPlatformx64(pEngine)) { + res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_64KEY, &hKey); + } else { + res = RegOpenKeyExW(hkHive, subkey, 0, KEY_READ | KEY_WOW64_32KEY, &hKey); + } + + if (res == ERROR_FILE_NOT_FOUND) { + return S_FALSE; + } + if (res != ERROR_SUCCESS) { + return HRESULT_FROM_WIN32(res); + } + + res = RegQueryValueExW(hKey, nullptr, nullptr, nullptr, nullptr, nullptr); + if (res == ERROR_FILE_NOT_FOUND) { + pEngine->SetVariableNumeric(L"Include_launcher", 0); + } else if (res == ERROR_SUCCESS) { + pEngine->SetVariableNumeric(L"Include_launcher", 1); + pEngine->SetVariableNumeric(L"DetectedLauncher", 1); + pEngine->SetVariableNumeric(L"InstallLauncherAllUsers", (hkHive == HKEY_LOCAL_MACHINE) ? 1 : 0); + pEngine->SetVariableNumeric(L"DetectedLauncherAllUsers", (hkHive == HKEY_LOCAL_MACHINE) ? 1 : 0); + pEngine->SetVariableString(L"InstallLauncherAllUsersState", L"disable"); + } + + res = RegQueryValueExW(hKey, L"AssociateFiles", nullptr, nullptr, nullptr, nullptr); + if (res == ERROR_FILE_NOT_FOUND) { + pEngine->SetVariableNumeric(L"AssociateFiles", 0); + } else if (res == ERROR_SUCCESS) { + pEngine->SetVariableNumeric(L"AssociateFiles", 1); + } + + RegCloseKey(hKey); + return S_OK; + } + + static void LoadOptionalFeatureStates(__in IBootstrapperEngine* pEngine) { + WCHAR subkeyFmt[256]; + WCHAR subkey[256]; + DWORD subkeyLen; + HRESULT hr; + HKEY hkHive; + + // The launcher installation is separate from the Python install, so we + // check its state later. This also checks the file association option. + + // Get the registry key from the bundle, to save having to duplicate it + // in multiple places. + subkeyLen = sizeof(subkeyFmt) / sizeof(subkeyFmt[0]); + hr = pEngine->GetVariableString(L"OptionalFeaturesRegistryKey", subkeyFmt, &subkeyLen); + BalExitOnFailure(hr, "Failed to locate registry key"); + subkeyLen = sizeof(subkey) / sizeof(subkey[0]); + hr = pEngine->FormatString(subkeyFmt, subkey, &subkeyLen); + BalExitOnFailure1(hr, "Failed to format %ls", subkeyFmt); + + // Check the current user's registry for existing features + hkHive = HKEY_CURRENT_USER; + hr = LoadOptionalFeatureStatesFromKey(pEngine, hkHive, subkey); + BalExitOnFailure1(hr, "Failed to read from HKCU\\%ls", subkey); + if (hr == S_FALSE) { + // Now check the local machine registry + hkHive = HKEY_LOCAL_MACHINE; + hr = LoadOptionalFeatureStatesFromKey(pEngine, hkHive, subkey); + BalExitOnFailure1(hr, "Failed to read from HKLM\\%ls", subkey); + if (hr == S_OK) { + // Found a system-wide install, so enable these settings. + pEngine->SetVariableNumeric(L"InstallAllUsers", 1); + pEngine->SetVariableNumeric(L"CompileAll", 1); + } + } + + if (hr == S_OK) { + // Cannot change InstallAllUsersState when upgrading. While there's + // no good reason to not allow installing a per-user and an all-user + // version simultaneously, Burn can't handle the state management + // and will need to uninstall the old one. + pEngine->SetVariableString(L"InstallAllUsersState", L"disable"); + + // Get the previous install directory. This can be changed by the + // user. + subkeyLen = sizeof(subkeyFmt) / sizeof(subkeyFmt[0]); + hr = pEngine->GetVariableString(L"TargetDirRegistryKey", subkeyFmt, &subkeyLen); + BalExitOnFailure(hr, "Failed to locate registry key"); + subkeyLen = sizeof(subkey) / sizeof(subkey[0]); + hr = pEngine->FormatString(subkeyFmt, subkey, &subkeyLen); + BalExitOnFailure1(hr, "Failed to format %ls", subkeyFmt); + LoadTargetDirFromKey(pEngine, hkHive, subkey); + } + + LExit: + return; + } + + HRESULT EnsureTargetDir() { + LONGLONG installAllUsers; + LPWSTR targetDir = nullptr, defaultDir = nullptr; + HRESULT hr = BalGetStringVariable(L"TargetDir", &targetDir); + if (FAILED(hr) || !targetDir || !targetDir[0]) { + ReleaseStr(targetDir); + targetDir = nullptr; + + hr = BalGetNumericVariable(L"InstallAllUsers", &installAllUsers); + ExitOnFailure(hr, L"Failed to get install scope"); + + hr = BalGetStringVariable( + installAllUsers ? L"DefaultAllUsersTargetDir" : L"DefaultJustForMeTargetDir", + &defaultDir + ); + BalExitOnFailure(hr, "Failed to get the default install directory"); + + if (!defaultDir || !defaultDir[0]) { + BalLogError(E_INVALIDARG, "Default install directory is blank"); + } + + hr = BalFormatString(defaultDir, &targetDir); + BalExitOnFailure1(hr, "Failed to format '%ls'", defaultDir); + + hr = _engine->SetVariableString(L"TargetDir", targetDir); + BalExitOnFailure(hr, "Failed to set install target directory"); + } + LExit: + ReleaseStr(defaultDir); + ReleaseStr(targetDir); + return hr; + } + + void ValidateOperatingSystem() { + LOC_STRING *pLocString = nullptr; + + if (IsWindows7SP1OrGreater()) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Target OS is Windows 7 SP1 or later"); + return; + } else if (IsWindows7OrGreater()) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Detected Windows 7 RTM"); + BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Service Pack 1 is required to continue installation"); + LocGetString(_wixLoc, L"#(loc.FailureWin7MissingSP1)", &pLocString); + } else if (IsWindowsVistaSP2OrGreater()) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Target OS is Windows Vista SP2"); + return; + } else if (IsWindowsVistaOrGreater()) { + BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Detected Windows Vista RTM or SP1"); + BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Service Pack 2 is required to continue installation"); + LocGetString(_wixLoc, L"#(loc.FailureVistaMissingSP2)", &pLocString); + } else { + BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Detected Windows XP or earlier"); + BalLog(BOOTSTRAPPER_LOG_LEVEL_ERROR, "Windows Vista SP2 or later is required to continue installation"); + LocGetString(_wixLoc, L"#(loc.FailureXPOrEarlier)", &pLocString); + } + + if (pLocString && pLocString->wzText) { + BalFormatString(pLocString->wzText, &_failedMessage); + } + + _hrFinal = E_WIXSTDBA_CONDITION_FAILED; + } + +public: + // + // Constructor - initialize member variables. + // + PythonBootstrapperApplication( + __in HMODULE hModule, + __in BOOL fPrereq, + __in HRESULT hrHostInitialization, + __in IBootstrapperEngine* pEngine, + __in const BOOTSTRAPPER_COMMAND* pCommand + ) : CBalBaseBootstrapperApplication(pEngine, pCommand, 3, 3000) { + _hModule = hModule; + memcpy_s(&_command, sizeof(_command), pCommand, sizeof(BOOTSTRAPPER_COMMAND)); + + LONGLONG llInstalled = 0; + HRESULT hr = BalGetNumericVariable(L"WixBundleInstalled", &llInstalled); + if (SUCCEEDED(hr) && BOOTSTRAPPER_RESUME_TYPE_REBOOT != _command.resumeType && 0 < llInstalled && BOOTSTRAPPER_ACTION_INSTALL == _command.action) { + _command.action = BOOTSTRAPPER_ACTION_MODIFY; + } else if (0 == llInstalled && (BOOTSTRAPPER_ACTION_MODIFY == _command.action || BOOTSTRAPPER_ACTION_REPAIR == _command.action)) { + _command.action = BOOTSTRAPPER_ACTION_INSTALL; + } + + _plannedAction = BOOTSTRAPPER_ACTION_UNKNOWN; + + + // When resuming from restart doing some install-like operation, try to find the package that forced the + // restart. We'll use this information during planning. + _nextPackageAfterRestart = nullptr; + + if (BOOTSTRAPPER_RESUME_TYPE_REBOOT == _command.resumeType && BOOTSTRAPPER_ACTION_UNINSTALL < _command.action) { + // Ensure the forced restart package variable is null when it is an empty string. + HRESULT hr = BalGetStringVariable(L"WixBundleForcedRestartPackage", &_nextPackageAfterRestart); + if (FAILED(hr) || !_nextPackageAfterRestart || !*_nextPackageAfterRestart) { + ReleaseNullStr(_nextPackageAfterRestart); + } + } + + _crtInstalledToken = -1; + pEngine->SetVariableNumeric(L"CRTInstalled", IsCrtInstalled() ? 1 : 0); + + _wixLoc = nullptr; + memset(&_bundle, 0, sizeof(_bundle)); + memset(&_conditions, 0, sizeof(_conditions)); + _confirmCloseMessage = nullptr; + _failedMessage = nullptr; + + _language = nullptr; + _theme = nullptr; + memset(_pageIds, 0, sizeof(_pageIds)); + _hUiThread = nullptr; + _registered = FALSE; + _hWnd = nullptr; + + _state = PYBA_STATE_INITIALIZING; + _visiblePageId = 0; + _installPage = PAGE_LOADING; + _hrFinal = hrHostInitialization; + + _downgradingOtherVersion = FALSE; + _upgradingOldVersion = FALSE; + _restartResult = BOOTSTRAPPER_APPLY_RESTART_NONE; + _restartRequired = FALSE; + _allowRestart = FALSE; + + _suppressDowngradeFailure = FALSE; + _suppressRepair = FALSE; + _modifying = FALSE; + _upgrading = FALSE; + + _overridableVariables = nullptr; + _taskbarList = nullptr; + _taskbarButtonCreatedMessage = UINT_MAX; + _taskbarButtonOK = FALSE; + _showingInternalUIThisPackage = FALSE; + _triedToLaunchElevated = FALSE; + + _suppressPaint = FALSE; + + pEngine->AddRef(); + _engine = pEngine; + + _hBAFModule = nullptr; + _baFunction = nullptr; + + EnsureTargetDir(); + } + + + // + // Destructor - release member variables. + // + ~PythonBootstrapperApplication() { + AssertSz(!::IsWindow(_hWnd), "Window should have been destroyed before destructor."); + AssertSz(!_theme, "Theme should have been released before destructor."); + + ReleaseObject(_taskbarList); + ReleaseDict(_overridableVariables); + ReleaseStr(_failedMessage); + ReleaseStr(_confirmCloseMessage); + BalConditionsUninitialize(&_conditions); + BalInfoUninitialize(&_bundle); + LocFree(_wixLoc); + + ReleaseStr(_language); + ReleaseStr(_nextPackageAfterRestart); + ReleaseNullObject(_engine); + + if (_hBAFModule) { + ::FreeLibrary(_hBAFModule); + _hBAFModule = nullptr; + } + } + +private: + HMODULE _hModule; + BOOTSTRAPPER_COMMAND _command; + IBootstrapperEngine* _engine; + BOOTSTRAPPER_ACTION _plannedAction; + + LPWSTR _nextPackageAfterRestart; + + WIX_LOCALIZATION* _wixLoc; + BAL_INFO_BUNDLE _bundle; + BAL_CONDITIONS _conditions; + LPWSTR _failedMessage; + LPWSTR _confirmCloseMessage; + + LPWSTR _language; + THEME* _theme; + DWORD _pageIds[countof(PAGE_NAMES)]; + HANDLE _hUiThread; + BOOL _registered; + HWND _hWnd; + + PYBA_STATE _state; + HRESULT _hrFinal; + DWORD _visiblePageId; + PAGE _installPage; + + BOOL _startedExecution; + DWORD _calculatedCacheProgress; + DWORD _calculatedExecuteProgress; + + BOOL _downgradingOtherVersion; + BOOL _upgradingOldVersion; + BOOTSTRAPPER_APPLY_RESTART _restartResult; + BOOL _restartRequired; + BOOL _allowRestart; + + BOOL _suppressDowngradeFailure; + BOOL _suppressRepair; + BOOL _modifying; + BOOL _upgrading; + + int _crtInstalledToken; + + STRINGDICT_HANDLE _overridableVariables; + + ITaskbarList3* _taskbarList; + UINT _taskbarButtonCreatedMessage; + BOOL _taskbarButtonOK; + BOOL _showingInternalUIThisPackage; + BOOL _triedToLaunchElevated; + + BOOL _suppressPaint; + + HMODULE _hBAFModule; + IBootstrapperBAFunction* _baFunction; +}; + +// +// CreateBootstrapperApplication - creates a new IBootstrapperApplication object. +// +HRESULT CreateBootstrapperApplication( + __in HMODULE hModule, + __in BOOL fPrereq, + __in HRESULT hrHostInitialization, + __in IBootstrapperEngine* pEngine, + __in const BOOTSTRAPPER_COMMAND* pCommand, + __out IBootstrapperApplication** ppApplication + ) { + HRESULT hr = S_OK; + + if (fPrereq) { + hr = E_INVALIDARG; + ExitWithLastError(hr, "Failed to create UI thread."); + } + + PythonBootstrapperApplication* pApplication = nullptr; + + pApplication = new PythonBootstrapperApplication(hModule, fPrereq, hrHostInitialization, pEngine, pCommand); + ExitOnNull(pApplication, hr, E_OUTOFMEMORY, "Failed to create new standard bootstrapper application object."); + + *ppApplication = pApplication; + pApplication = nullptr; + +LExit: + ReleaseObject(pApplication); + return hr; +} diff --git a/Tools/msi/bundle/bootstrap/pch.cpp b/Tools/msi/bundle/bootstrap/pch.cpp new file mode 100644 index 000000000000..1d9f38c57d63 --- /dev/null +++ b/Tools/msi/bundle/bootstrap/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/Tools/msi/bundle/bootstrap/pch.h b/Tools/msi/bundle/bootstrap/pch.h new file mode 100644 index 000000000000..6a66fa5a51eb --- /dev/null +++ b/Tools/msi/bundle/bootstrap/pch.h @@ -0,0 +1,60 @@ +//------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2004, Outercurve Foundation. +// This software is released under Microsoft Reciprocal License (MS-RL). +// The license and further copyright text can be found in the file +// LICENSE.TXT at the root directory of the distribution. +// +// +//

+// Precompiled header for standard bootstrapper application. +// +//------------------------------------------------------------------------------------------------- + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dutil.h" +#include "memutil.h" +#include "dictutil.h" +#include "dirutil.h" +#include "fileutil.h" +#include "locutil.h" +#include "logutil.h" +#include "pathutil.h" +#include "resrutil.h" +#include "shelutil.h" +#include "strutil.h" +#include "thmutil.h" +#include "uriutil.h" +#include "xmlutil.h" + +#include "IBootstrapperEngine.h" +#include "IBootstrapperApplication.h" + +#include "BalBaseBootstrapperApplication.h" +#include "balinfo.h" +#include "balcondition.h" + +HRESULT CreateBootstrapperApplication( + __in HMODULE hModule, + __in BOOL fPrereq, + __in HRESULT hrHostInitialization, + __in IBootstrapperEngine* pEngine, + __in const BOOTSTRAPPER_COMMAND* pCommand, + __out IBootstrapperApplication** ppApplication +); + +#include "IBootstrapperBAFunction.h" + diff --git a/Tools/msi/bundle/bootstrap/pythonba.cpp b/Tools/msi/bundle/bootstrap/pythonba.cpp new file mode 100644 index 000000000000..0ce45ad31d95 --- /dev/null +++ b/Tools/msi/bundle/bootstrap/pythonba.cpp @@ -0,0 +1,76 @@ +//------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2004, Outercurve Foundation. +// This software is released under Microsoft Reciprocal License (MS-RL). +// The license and further copyright text can be found in the file +// LICENSE.TXT at the root directory of the distribution. +// +// +// +// Setup chainer/bootstrapper standard UI for WiX toolset. +// +//------------------------------------------------------------------------------------------------- + +#include "pch.h" + +static HINSTANCE vhInstance = NULL; + +extern "C" BOOL WINAPI DllMain( + IN HINSTANCE hInstance, + IN DWORD dwReason, + IN LPVOID /* pvReserved */ + ) +{ + switch(dwReason) + { + case DLL_PROCESS_ATTACH: + ::DisableThreadLibraryCalls(hInstance); + vhInstance = hInstance; + break; + + case DLL_PROCESS_DETACH: + vhInstance = NULL; + break; + } + + return TRUE; +} + + +extern "C" HRESULT WINAPI BootstrapperApplicationCreate( + __in IBootstrapperEngine* pEngine, + __in const BOOTSTRAPPER_COMMAND* pCommand, + __out IBootstrapperApplication** ppApplication + ) +{ + HRESULT hr = S_OK; + + BalInitialize(pEngine); + + hr = CreateBootstrapperApplication(vhInstance, FALSE, S_OK, pEngine, pCommand, ppApplication); + BalExitOnFailure(hr, "Failed to create bootstrapper application interface."); + +LExit: + return hr; +} + + +extern "C" void WINAPI BootstrapperApplicationDestroy() +{ + BalUninitialize(); +} + + +extern "C" HRESULT WINAPI MbaPrereqBootstrapperApplicationCreate( + __in HRESULT hrHostInitialization, + __in IBootstrapperEngine* pEngine, + __in const BOOTSTRAPPER_COMMAND* pCommand, + __out IBootstrapperApplication** ppApplication + ) +{ + return E_NOTIMPL; +} + + +extern "C" void WINAPI MbaPrereqBootstrapperApplicationDestroy() +{ } diff --git a/Tools/msi/bundle/bootstrap/pythonba.def b/Tools/msi/bundle/bootstrap/pythonba.def new file mode 100644 index 000000000000..29b3fa50dfa9 --- /dev/null +++ b/Tools/msi/bundle/bootstrap/pythonba.def @@ -0,0 +1,18 @@ +;------------------------------------------------------------------------------------------------- +; +; Copyright (c) 2004, Outercurve Foundation. +; This software is released under Microsoft Reciprocal License (MS-RL). +; The license and further copyright text can be found in the file +; LICENSE.TXT at the root directory of the distribution. +; +; +; +; WiX Standard Bootstrapper Application DLL entry points. +; +;------------------------------------------------------------------------------------------------- + +EXPORTS + BootstrapperApplicationCreate + BootstrapperApplicationDestroy + MbaPrereqBootstrapperApplicationCreate + MbaPrereqBootstrapperApplicationDestroy diff --git a/Tools/msi/bundle/bootstrap/pythonba.sln b/Tools/msi/bundle/bootstrap/pythonba.sln new file mode 100644 index 000000000000..bf43fed9018e --- /dev/null +++ b/Tools/msi/bundle/bootstrap/pythonba.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.30501.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonba", "pythonba.vcxproj", "{7A09B132-B3EE-499B-A700-A4B2157FEA3D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7A09B132-B3EE-499B-A700-A4B2157FEA3D}.Debug|Win32.ActiveCfg = Debug|Win32 + {7A09B132-B3EE-499B-A700-A4B2157FEA3D}.Debug|Win32.Build.0 = Debug|Win32 + {7A09B132-B3EE-499B-A700-A4B2157FEA3D}.Release|Win32.ActiveCfg = Release|Win32 + {7A09B132-B3EE-499B-A700-A4B2157FEA3D}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Tools/msi/bundle/bootstrap/pythonba.vcxproj b/Tools/msi/bundle/bootstrap/pythonba.vcxproj new file mode 100644 index 000000000000..be12957112fa --- /dev/null +++ b/Tools/msi/bundle/bootstrap/pythonba.vcxproj @@ -0,0 +1,69 @@ + + + + + + Debug + Win32 + + + Release + Win32 + + + + Release + Win32 + v140 + v120 + {7A09B132-B3EE-499B-A700-A4B2157FEA3D} + PythonBA + + + + + DynamicLibrary + Unicode + $(PySourcePath)PCBuild\obj\$(Configuration)_$(Platform)_Setup\Bootstrap\ + $(IntDir) + + + + + _CRT_STDIO_LEGACY_WIDE_SPECIFIERS=1;%(PreprocessorDefinitions) + $(WixInstallPath)sdk\inc + Use + pch.h + MultiThreaded + + + comctl32.lib;gdiplus.lib;msimg32.lib;shlwapi.lib;wininet.lib;dutil.lib;balutil.lib;version.lib;uxtheme.lib;%(AdditionalDependencies) + $(WixInstallPath)sdk\vs2015\lib\x86 + $(WixInstallPath)sdk\vs2013\lib\x86 + pythonba.def + true + + + + + + + Create + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/bootstrap/resource.h b/Tools/msi/bundle/bootstrap/resource.h new file mode 100644 index 000000000000..53c03c319f09 --- /dev/null +++ b/Tools/msi/bundle/bootstrap/resource.h @@ -0,0 +1,25 @@ +//------------------------------------------------------------------------------------------------- +// +// Copyright (c) 2004, Outercurve Foundation. +// This software is released under Microsoft Reciprocal License (MS-RL). +// The license and further copyright text can be found in the file +// LICENSE.TXT at the root directory of the distribution. +// +//------------------------------------------------------------------------------------------------- + +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// +#define IDC_STATIC -1 + + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1003 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Tools/msi/bundle/bundle.ico b/Tools/msi/bundle/bundle.ico new file mode 100644 index 000000000000..1ab629eff269 Binary files /dev/null and b/Tools/msi/bundle/bundle.ico differ diff --git a/Tools/msi/bundle/bundle.targets b/Tools/msi/bundle/bundle.targets new file mode 100644 index 000000000000..9b7d09015fdd --- /dev/null +++ b/Tools/msi/bundle/bundle.targets @@ -0,0 +1,112 @@ + + + + 2.0 + Bundle + + Release + 1132;1135;1140 + $(OutputName)-$(PythonVersion) + $(OutputName)-$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber).$(RevisionNumber) + $(OutputName)-amd64 + $(OutputName)-$(OutputSuffix) + $(OutputName)-d + $(OutputName) + + $(OutputPath)en-us\ + $(OutputPath) + + + $(DownloadUrlBase.TrimEnd(`/`))/{version}/{arch}{releasename}/{msi} + $(DefineConstants);DownloadUrl=$(DownloadUrl.Replace(`{version}`, `$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)`).Replace(`{arch}`, `$(ArchName)`).Replace(`{releasename}`, `$(ReleaseName)`).Replace(`{msi}`, `{2}`)) + $(DefineConstants);DownloadUrl={2} + + + + + WixUtilExtension + WixUtilExtension + + + WixDependencyExtension + WixDependencyExtension + + + WixBalExtension + WixBalExtension + + + + + + + + + + + + + + + + + + + + + + + + BuildForRelease=$(BuildForRelease) + + + + + + + + + + + + + + + + + Build + + + + + Rebuild + + + + + + + + + + + + + + + + + + + + + $(DefineConstants);BootstrapApp=$(BootstrapAppPath) + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/bundle.wxl b/Tools/msi/bundle/bundle.wxl new file mode 100644 index 000000000000..d7a65c48dc4d --- /dev/null +++ b/Tools/msi/bundle/bundle.wxl @@ -0,0 +1,7 @@ + + + C Runtime Update (KB2999226) + Precompiling standard library + Precompiling standard library (-O) + Precompiling standard library (-OO) + diff --git a/Tools/msi/bundle/bundle.wxs b/Tools/msi/bundle/bundle.wxs new file mode 100644 index 000000000000..ffaadbd91f73 --- /dev/null +++ b/Tools/msi/bundle/bundle.wxs @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/bundle/full.wixproj b/Tools/msi/bundle/full.wixproj new file mode 100644 index 000000000000..bdbdd8e175c0 --- /dev/null +++ b/Tools/msi/bundle/full.wixproj @@ -0,0 +1,21 @@ + + + + {3E204ADD-238D-4D10-852C-4F859325C839} + python + full + + + + + + + $(DefineConstants); + CompressMSI=yes; + CompressPDB=yes; + CompressMSI_D=yes; + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/core.wxs b/Tools/msi/bundle/packagegroups/core.wxs new file mode 100644 index 000000000000..eb3d0b7733cf --- /dev/null +++ b/Tools/msi/bundle/packagegroups/core.wxs @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/crt.wxs b/Tools/msi/bundle/packagegroups/crt.wxs new file mode 100644 index 000000000000..dc4047590e88 --- /dev/null +++ b/Tools/msi/bundle/packagegroups/crt.wxs @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/dev.wxs b/Tools/msi/bundle/packagegroups/dev.wxs new file mode 100644 index 000000000000..4284dba2c205 --- /dev/null +++ b/Tools/msi/bundle/packagegroups/dev.wxs @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/doc.wxs b/Tools/msi/bundle/packagegroups/doc.wxs new file mode 100644 index 000000000000..6639ff5c25b2 --- /dev/null +++ b/Tools/msi/bundle/packagegroups/doc.wxs @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/exe.wxs b/Tools/msi/bundle/packagegroups/exe.wxs new file mode 100644 index 000000000000..79464c4aca66 --- /dev/null +++ b/Tools/msi/bundle/packagegroups/exe.wxs @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/launcher.wxs b/Tools/msi/bundle/packagegroups/launcher.wxs new file mode 100644 index 000000000000..4b03fd29b625 --- /dev/null +++ b/Tools/msi/bundle/packagegroups/launcher.wxs @@ -0,0 +1,27 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/lib.wxs b/Tools/msi/bundle/packagegroups/lib.wxs new file mode 100644 index 000000000000..0b3fbc00c4a3 --- /dev/null +++ b/Tools/msi/bundle/packagegroups/lib.wxs @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/packageinstall.wxs b/Tools/msi/bundle/packagegroups/packageinstall.wxs new file mode 100644 index 000000000000..e5e7d4d1a94c --- /dev/null +++ b/Tools/msi/bundle/packagegroups/packageinstall.wxs @@ -0,0 +1,26 @@ + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/pip.wxs b/Tools/msi/bundle/packagegroups/pip.wxs new file mode 100644 index 000000000000..201a6c445b23 --- /dev/null +++ b/Tools/msi/bundle/packagegroups/pip.wxs @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/postinstall.wxs b/Tools/msi/bundle/packagegroups/postinstall.wxs new file mode 100644 index 000000000000..11ab67390705 --- /dev/null +++ b/Tools/msi/bundle/packagegroups/postinstall.wxs @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/tcltk.wxs b/Tools/msi/bundle/packagegroups/tcltk.wxs new file mode 100644 index 000000000000..0d029a90cd96 --- /dev/null +++ b/Tools/msi/bundle/packagegroups/tcltk.wxs @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/test.wxs b/Tools/msi/bundle/packagegroups/test.wxs new file mode 100644 index 000000000000..32acaef64efe --- /dev/null +++ b/Tools/msi/bundle/packagegroups/test.wxs @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/packagegroups/tools.wxs b/Tools/msi/bundle/packagegroups/tools.wxs new file mode 100644 index 000000000000..1d9ab19f3e09 --- /dev/null +++ b/Tools/msi/bundle/packagegroups/tools.wxs @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/releaselocal.wixproj b/Tools/msi/bundle/releaselocal.wixproj new file mode 100644 index 000000000000..0c3dee7ad81e --- /dev/null +++ b/Tools/msi/bundle/releaselocal.wixproj @@ -0,0 +1,21 @@ + + + + {FCD43AC9-969F-49A1-8AC5-EDC27599D1EB} + python + + + + + + + + $(DefineConstants); + CompressMSI=yes; + CompressPDB=no; + CompressMSI_D=no + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/releaseweb.wixproj b/Tools/msi/bundle/releaseweb.wixproj new file mode 100644 index 000000000000..350c735878c0 --- /dev/null +++ b/Tools/msi/bundle/releaseweb.wixproj @@ -0,0 +1,21 @@ + + + + {71CDE213-CB39-4BD9-B89D-BBB878689144} + python + webinstall + + + + + + + $(DefineConstants); + CompressMSI=no; + CompressPDB=no; + CompressMSI_D=no + + + + + \ No newline at end of file diff --git a/Tools/msi/bundle/snapshot.wixproj b/Tools/msi/bundle/snapshot.wixproj new file mode 100644 index 000000000000..cc4504329906 --- /dev/null +++ b/Tools/msi/bundle/snapshot.wixproj @@ -0,0 +1,26 @@ + + + + {8A4A1162-4BF9-4FF6-9A98-315F01E44932} + python + + + + + + + + $(DefineConstants);CompressMSI=no; + + + $(DefineConstants);CompressMSI=yes; + + + $(DefineConstants); + CompressPDB=no; + CompressMSI_D=no; + + + + + \ No newline at end of file diff --git a/Tools/msi/common.wxs b/Tools/msi/common.wxs new file mode 100644 index 000000000000..100a0138db31 --- /dev/null +++ b/Tools/msi/common.wxs @@ -0,0 +1,112 @@ + + + + + + + + + OPTIONALFEATURESREGISTRYKEY + + + + + + + + + + + + + + + + + + + + Installed OR NOT MISSING_CORE + + + + Installed OR NOT DOWNGRADE + Installed OR TARGETDIR OR Suppress_TARGETDIR_Check + + + UPGRADE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/common_en-US.wxl_template b/Tools/msi/common_en-US.wxl_template new file mode 100644 index 000000000000..8d0352688207 --- /dev/null +++ b/Tools/msi/common_en-US.wxl_template @@ -0,0 +1,17 @@ + + + 1033 + en-us + Python {{ShortVersion}} + Python {{LongVersion}} ({{Bitness}}) + Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}}) + Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}}) + Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}} symbols) + Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}} symbols) + Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}} debug) + Python {{LongVersion}} !(loc.Descriptor) ({{Bitness}} debug) + Python Software Foundation + A newer version of !(loc.ProductName) is already installed. + An incorrect version of a prerequisite package is installed. Please uninstall any other versions of !(loc.ProductName) and try installing this again. + The TARGETDIR variable must be provided when invoking this installer. + diff --git a/Tools/msi/core/core.wixproj b/Tools/msi/core/core.wixproj new file mode 100644 index 000000000000..68e8bab3109d --- /dev/null +++ b/Tools/msi/core/core.wixproj @@ -0,0 +1,19 @@ + + + + {1B4502D5-B627-4F50-ABEA-4CC5A8E88265} + 2.0 + core + Package + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/core/core.wxs b/Tools/msi/core/core.wxs new file mode 100644 index 000000000000..0d4fbde9787c --- /dev/null +++ b/Tools/msi/core/core.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tools/msi/core/core_d.wixproj b/Tools/msi/core/core_d.wixproj new file mode 100644 index 000000000000..5b296bf35f95 --- /dev/null +++ b/Tools/msi/core/core_d.wixproj @@ -0,0 +1,19 @@ + + + + {D3677DCF-098A-4398-9FA5-8E74AC37E0DF} + 2.0 + core_d + Package + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/core/core_d.wxs b/Tools/msi/core/core_d.wxs new file mode 100644 index 000000000000..07e0397686b7 --- /dev/null +++ b/Tools/msi/core/core_d.wxs @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/Tools/msi/core/core_en-US.wxl b/Tools/msi/core/core_en-US.wxl new file mode 100644 index 000000000000..7977470d7c1c --- /dev/null +++ b/Tools/msi/core/core_en-US.wxl @@ -0,0 +1,5 @@ + + + Core Interpreter + core + diff --git a/Tools/msi/core/core_files.wxs b/Tools/msi/core/core_files.wxs new file mode 100644 index 000000000000..145e1471247a --- /dev/null +++ b/Tools/msi/core/core_files.wxs @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/core/core_pdb.wixproj b/Tools/msi/core/core_pdb.wixproj new file mode 100644 index 000000000000..9c8838970b6f --- /dev/null +++ b/Tools/msi/core/core_pdb.wixproj @@ -0,0 +1,19 @@ + + + + {E98E7539-64E7-4DCE-AACD-01E3ADE40EFD} + 2.0 + core_pdb + Package + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/core/core_pdb.wxs b/Tools/msi/core/core_pdb.wxs new file mode 100644 index 000000000000..c2c3178973cd --- /dev/null +++ b/Tools/msi/core/core_pdb.wxs @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/Tools/msi/csv_to_wxs.py b/Tools/msi/csv_to_wxs.py new file mode 100644 index 000000000000..235c8f8b0be5 --- /dev/null +++ b/Tools/msi/csv_to_wxs.py @@ -0,0 +1,127 @@ +''' +Processes a CSV file containing a list of files into a WXS file with +components for each listed file. + +The CSV columns are: + source of file, target for file, group name + +Usage:: + py txt_to_wxs.py [path to file list .csv] [path to destination .wxs] + +This is necessary to handle structures where some directories only +contain other directories. MSBuild is not able to generate the +Directory entries in the WXS file correctly, as it operates on files. +Python, however, can easily fill in the gap. +''' + +__author__ = "Steve Dower " + +import csv +import re +import sys + +from collections import defaultdict +from itertools import chain, zip_longest +from pathlib import PureWindowsPath +from uuid import uuid1 + +ID_CHAR_SUBS = { + '-': '_', + '+': '_P', +} + +def make_id(path): + return re.sub( + r'[^A-Za-z0-9_.]', + lambda m: ID_CHAR_SUBS.get(m.group(0), '_'), + str(path).rstrip('/\\'), + flags=re.I + ) + +DIRECTORIES = set() + +def main(file_source, install_target): + with open(file_source, 'r', newline='') as f: + files = list(csv.reader(f)) + + assert len(files) == len(set(make_id(f[1]) for f in files)), "Duplicate file IDs exist" + + directories = defaultdict(set) + cache_directories = defaultdict(set) + groups = defaultdict(list) + for source, target, group, disk_id, condition in files: + target = PureWindowsPath(target) + groups[group].append((source, target, disk_id, condition)) + + if target.suffix.lower() in {".py", ".pyw"}: + cache_directories[group].add(target.parent) + + for dirname in target.parents: + parent = make_id(dirname.parent) + if parent and parent != '.': + directories[parent].add(dirname.name) + + lines = [ + '', + ' ', + ] + for dir_parent in sorted(directories): + lines.append(' '.format(dir_parent)) + for dir_name in sorted(directories[dir_parent]): + lines.append(' '.format(dir_parent, make_id(dir_name), dir_name)) + lines.append(' ') + for dir_parent in (make_id(d) for group in cache_directories.values() for d in group): + lines.append(' '.format(dir_parent)) + lines.append(' '.format(dir_parent)) + lines.append(' ') + lines.append(' ') + + for group in sorted(groups): + lines.extend([ + ' ', + ' '.format(group), + ]) + for source, target, disk_id, condition in groups[group]: + lines.append(' '.format(make_id(target), make_id(target.parent))) + if condition: + lines.append(' {}'.format(condition)) + + if disk_id: + lines.append(' '.format(make_id(target), target.name, source, disk_id)) + else: + lines.append(' '.format(make_id(target), target.name, source)) + lines.append(' ') + + create_folders = {make_id(p) + "___pycache__" for p in cache_directories[group]} + remove_folders = {make_id(p2) for p1 in cache_directories[group] for p2 in chain((p1,), p1.parents)} + create_folders.discard(".") + remove_folders.discard(".") + if create_folders or remove_folders: + lines.append(' '.format(group, uuid1())) + lines.extend(' '.format(p) for p in create_folders) + lines.extend(' '.format(p) for p in create_folders) + lines.extend(' '.format(p) for p in create_folders | remove_folders) + lines.append(' ') + + lines.extend([ + ' ', + ' ', + ]) + lines.append('') + + # Check if the file matches. If so, we don't want to touch it so + # that we can skip rebuilding. + try: + with open(install_target, 'r') as f: + if all(x.rstrip('\r\n') == y for x, y in zip_longest(f, lines)): + print('File is up to date') + return + except IOError: + pass + + with open(install_target, 'w') as f: + f.writelines(line + '\n' for line in lines) + print('Wrote {} lines to {}'.format(len(lines), install_target)) + +if __name__ == '__main__': + main(sys.argv[1], sys.argv[2]) diff --git a/Tools/msi/dev/dev.wixproj b/Tools/msi/dev/dev.wixproj new file mode 100644 index 000000000000..682b66031f1e --- /dev/null +++ b/Tools/msi/dev/dev.wixproj @@ -0,0 +1,49 @@ + + + + {5F23F608-D74B-4259-A0CE-8DC65CC7FE53} + 2.0 + dev + Package + + + + + $(DefineConstants); + IncludeMinGWLib=1; + + + + + + + + + + + + $(PySourcePath) + !(bindpath.src) + $(PySourcePath) + + dev_include + + + + + + + <_DllToolOpts>-m i386 --as-flags=--32 + <_DllToolOpts Condition="$(Platform) == 'x64'">-m i386:x86-64 + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/dev/dev.wxs b/Tools/msi/dev/dev.wxs new file mode 100644 index 000000000000..a09e139c428b --- /dev/null +++ b/Tools/msi/dev/dev.wxs @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/dev/dev_d.wixproj b/Tools/msi/dev/dev_d.wixproj new file mode 100644 index 000000000000..b3b05326d419 --- /dev/null +++ b/Tools/msi/dev/dev_d.wixproj @@ -0,0 +1,19 @@ + + + + {C11B4945-76BD-4137-B2E3-649460117A77} + 2.0 + dev_d + Package + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/dev/dev_d.wxs b/Tools/msi/dev/dev_d.wxs new file mode 100644 index 000000000000..c467aac57b95 --- /dev/null +++ b/Tools/msi/dev/dev_d.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tools/msi/dev/dev_en-US.wxl b/Tools/msi/dev/dev_en-US.wxl new file mode 100644 index 000000000000..2546e13e47a0 --- /dev/null +++ b/Tools/msi/dev/dev_en-US.wxl @@ -0,0 +1,5 @@ + + + Development Libraries + dev + diff --git a/Tools/msi/dev/dev_files.wxs b/Tools/msi/dev/dev_files.wxs new file mode 100644 index 000000000000..9654d2e3e600 --- /dev/null +++ b/Tools/msi/dev/dev_files.wxs @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/doc/doc.wixproj b/Tools/msi/doc/doc.wixproj new file mode 100644 index 000000000000..ea9929acd05f --- /dev/null +++ b/Tools/msi/doc/doc.wixproj @@ -0,0 +1,30 @@ + + + + {0D62A2BB-5F71-4447-8C8C-9708407B3674} + 2.0 + doc + Package + + ICE43 + + + + python$(MajorVersionNumber)$(MinorVersionNumber)$(MicroVersionNumber)$(ReleaseLevelName).chm + false + true + + + $(DefineConstants);DocFilename=$(DocFilename); + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/doc/doc.wxs b/Tools/msi/doc/doc.wxs new file mode 100644 index 000000000000..bbe30a13e326 --- /dev/null +++ b/Tools/msi/doc/doc.wxs @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/doc/doc_en-US.wxl_template b/Tools/msi/doc/doc_en-US.wxl_template new file mode 100644 index 000000000000..809556e29fb9 --- /dev/null +++ b/Tools/msi/doc/doc_en-US.wxl_template @@ -0,0 +1,7 @@ + + + doc + Documentation + Python {{ShortVersion}} Manuals ({{Bitness}}) + View the !(loc.ProductName) documentation. + diff --git a/Tools/msi/doc/doc_files.wxs b/Tools/msi/doc/doc_files.wxs new file mode 100644 index 000000000000..fe09afe4d3c7 --- /dev/null +++ b/Tools/msi/doc/doc_files.wxs @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/Tools/msi/doc/doc_no_files.wxs b/Tools/msi/doc/doc_no_files.wxs new file mode 100644 index 000000000000..7ab7c2690689 --- /dev/null +++ b/Tools/msi/doc/doc_no_files.wxs @@ -0,0 +1,17 @@ + + + + + + + + + + + + diff --git a/Tools/msi/crtlicense.txt b/Tools/msi/exe/crtlicense.txt similarity index 94% rename from Tools/msi/crtlicense.txt rename to Tools/msi/exe/crtlicense.txt index 936bc5ad532d..f86841f263ef 100644 --- a/Tools/msi/crtlicense.txt +++ b/Tools/msi/exe/crtlicense.txt @@ -5,11 +5,8 @@ Additional Conditions for this Windows binary build This program is linked with and uses Microsoft Distributable Code, copyrighted by Microsoft Corporation. The Microsoft Distributable Code -includes the following files: - -msvcr90.dll -msvcp90.dll -msvcm90.dll +is embedded in each .exe, .dll and .pyd file as a result of running +the code through a linker. If you further distribute programs that include the Microsoft Distributable Code, you must comply with the restrictions on diff --git a/Tools/msi/exe/exe.wixproj b/Tools/msi/exe/exe.wixproj new file mode 100644 index 000000000000..d26a603268b4 --- /dev/null +++ b/Tools/msi/exe/exe.wixproj @@ -0,0 +1,43 @@ + + + + {6BD53305-B03E-49DC-85FB-5551B8CCC843} + 2.0 + exe + Package + + + + ICE43 + + + + + + + + + + + + + + + <_LicenseFiles Include="@(LicenseFiles)"> + $([System.IO.File]::ReadAllText(%(FullPath))) + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/exe/exe.wxs b/Tools/msi/exe/exe.wxs new file mode 100644 index 000000000000..dcbf646da0f1 --- /dev/null +++ b/Tools/msi/exe/exe.wxs @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/exe/exe_d.wixproj b/Tools/msi/exe/exe_d.wixproj new file mode 100644 index 000000000000..27545caf7d16 --- /dev/null +++ b/Tools/msi/exe/exe_d.wixproj @@ -0,0 +1,20 @@ + + + + {B1CA739C-8DB0-403B-9010-D79507507CE9} + 2.0 + exe_d + Package + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/exe/exe_d.wxs b/Tools/msi/exe/exe_d.wxs new file mode 100644 index 000000000000..eedb6bb640ee --- /dev/null +++ b/Tools/msi/exe/exe_d.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tools/msi/exe/exe_en-US.wxl_template b/Tools/msi/exe/exe_en-US.wxl_template new file mode 100644 index 000000000000..577fbe51a52a --- /dev/null +++ b/Tools/msi/exe/exe_en-US.wxl_template @@ -0,0 +1,7 @@ + + + Executables + executable + Python {{ShortVersion}} ({{Bitness}}) + Launches the !(loc.ProductName) interpreter. + diff --git a/Tools/msi/exe/exe_files.wxs b/Tools/msi/exe/exe_files.wxs new file mode 100644 index 000000000000..9e47b5d9809d --- /dev/null +++ b/Tools/msi/exe/exe_files.wxs @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/exe/exe_pdb.wixproj b/Tools/msi/exe/exe_pdb.wixproj new file mode 100644 index 000000000000..4f4c86992606 --- /dev/null +++ b/Tools/msi/exe/exe_pdb.wixproj @@ -0,0 +1,20 @@ + + + + {4A1F7045-8EE2-4276-ABB8-5E0C40E5F38B} + 2.0 + exe_pdb + Package + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/exe/exe_pdb.wxs b/Tools/msi/exe/exe_pdb.wxs new file mode 100644 index 000000000000..f25094f82813 --- /dev/null +++ b/Tools/msi/exe/exe_pdb.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tools/msi/generate_md5.py b/Tools/msi/generate_md5.py new file mode 100644 index 000000000000..9e4c14731bd1 --- /dev/null +++ b/Tools/msi/generate_md5.py @@ -0,0 +1,27 @@ +import hashlib +import os +import sys + +def main(): + filenames, hashes, sizes = [], [], [] + + for file in sys.argv[1:]: + if not os.path.isfile(file): + continue + + with open(file, 'rb') as f: + data = f.read() + md5 = hashlib.md5() + md5.update(data) + filenames.append(os.path.split(file)[1]) + hashes.append(md5.hexdigest()) + sizes.append(str(len(data))) + + print('{:40s} {:<32s} {:<9s}'.format('File', 'MD5', 'Size')) + for f, h, s in zip(filenames, hashes, sizes): + print('{:40s} {:>32s} {:>9s}'.format(f, h, s)) + + + +if __name__ == "__main__": + sys.exit(int(main() or 0)) diff --git a/Tools/msi/get_wix.py b/Tools/msi/get_wix.py new file mode 100644 index 000000000000..db141567cbdd --- /dev/null +++ b/Tools/msi/get_wix.py @@ -0,0 +1,49 @@ +''' +Downloads and extracts WiX to a local directory +''' + +__author__ = 'Steve Dower ' + +import io +import os +import sys + +from pathlib import Path +from subprocess import Popen +from zipfile import ZipFile + +EXTERNALS_DIR = None +for p in (Path.cwd() / __file__).parents: + if any(p.glob("PCBuild/*.vcxproj")): + EXTERNALS_DIR = p / "externals" + break + +if not EXTERNALS_DIR: + print("Cannot find project root") + sys.exit(1) + +WIX_BINARIES_ZIP = 'http://wixtoolset.org/downloads/v3.10.0.1823/wix310-binaries.zip' +TARGET_BIN_ZIP = EXTERNALS_DIR / "wix.zip" +TARGET_BIN_DIR = EXTERNALS_DIR / "wix" + +POWERSHELL_COMMAND = "[IO.File]::WriteAllBytes('{}', (Invoke-WebRequest {} -UseBasicParsing).Content)" + +if __name__ == '__main__': + if TARGET_BIN_DIR.exists() and any(TARGET_BIN_DIR.glob("*")): + print('WiX is already installed') + sys.exit(0) + + try: + TARGET_BIN_DIR.mkdir() + except FileExistsError: + pass + + print('Downloading WiX to', TARGET_BIN_ZIP) + p = Popen(["powershell.exe", "-Command", POWERSHELL_COMMAND.format(TARGET_BIN_ZIP, WIX_BINARIES_ZIP)]) + p.wait() + print('Extracting WiX to', TARGET_BIN_DIR) + with ZipFile(str(TARGET_BIN_ZIP)) as z: + z.extractall(str(TARGET_BIN_DIR)) + TARGET_BIN_ZIP.unlink() + + print('Extracted WiX') diff --git a/Tools/msi/launcher/launcher.wixproj b/Tools/msi/launcher/launcher.wixproj new file mode 100644 index 000000000000..a0f1d574fca0 --- /dev/null +++ b/Tools/msi/launcher/launcher.wixproj @@ -0,0 +1,21 @@ + + + + {921CF0E6-AEBC-4376-BA1D-CD46EBFE6DA5} + 2.0 + launcher + Package + SkipMissingCore=1;$(DefineConstants) + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/launcher/launcher.wxs b/Tools/msi/launcher/launcher.wxs new file mode 100644 index 000000000000..718b666a5c74 --- /dev/null +++ b/Tools/msi/launcher/launcher.wxs @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + NOT Installed AND NOT ALLUSERS=1 + NOT Installed AND ALLUSERS=1 + + UPGRADE or REMOVE_OLD_LAUNCHER + + + + + + + + diff --git a/Tools/msi/launcher/launcher_en-US.wxl b/Tools/msi/launcher/launcher_en-US.wxl new file mode 100644 index 000000000000..d961fff3c68d --- /dev/null +++ b/Tools/msi/launcher/launcher_en-US.wxl @@ -0,0 +1,10 @@ + + + Launcher + launcher + Python File + Python File (no console) + Compiled Python File + Python Zip Application File + Python Zip Application File (no console) + diff --git a/Tools/msi/launcher/launcher_files.wxs b/Tools/msi/launcher/launcher_files.wxs new file mode 100644 index 000000000000..7148258a000b --- /dev/null +++ b/Tools/msi/launcher/launcher_files.wxs @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + NOT ALLUSERS=1 + + + + + + ALLUSERS=1 + + + + + diff --git a/Tools/msi/launcher/launcher_reg.wxs b/Tools/msi/launcher/launcher_reg.wxs new file mode 100644 index 000000000000..d00f442fd083 --- /dev/null +++ b/Tools/msi/launcher/launcher_reg.wxs @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/lib/lib.wixproj b/Tools/msi/lib/lib.wixproj new file mode 100644 index 000000000000..64e58787b88e --- /dev/null +++ b/Tools/msi/lib/lib.wixproj @@ -0,0 +1,34 @@ + + + + {11367E76-3337-4602-8F1E-77DB4F370D7E} + 2.0 + lib + Package + + + + + + + + + + + + + $(PySourcePath)Lib + !(bindpath.src)Lib\ + $(PySourcePath)Lib + Lib\ + lib_py + + + + + \ No newline at end of file diff --git a/Tools/msi/lib/lib.wxs b/Tools/msi/lib/lib.wxs new file mode 100644 index 000000000000..2b04bcb3049c --- /dev/null +++ b/Tools/msi/lib/lib.wxs @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/lib/lib_d.wixproj b/Tools/msi/lib/lib_d.wixproj new file mode 100644 index 000000000000..587a82c1929d --- /dev/null +++ b/Tools/msi/lib/lib_d.wixproj @@ -0,0 +1,19 @@ + + + + {6C443CD3-8258-4335-BA03-49DA9C34CE4D} + 2.0 + lib_d + Package + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/lib/lib_d.wxs b/Tools/msi/lib/lib_d.wxs new file mode 100644 index 000000000000..8a8a530d41a8 --- /dev/null +++ b/Tools/msi/lib/lib_d.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tools/msi/lib/lib_en-US.wxl b/Tools/msi/lib/lib_en-US.wxl new file mode 100644 index 000000000000..305bcc73afc8 --- /dev/null +++ b/Tools/msi/lib/lib_en-US.wxl @@ -0,0 +1,5 @@ + + + Standard Library + lib + diff --git a/Tools/msi/lib/lib_files.wxs b/Tools/msi/lib/lib_files.wxs new file mode 100644 index 000000000000..fa79a8d692d3 --- /dev/null +++ b/Tools/msi/lib/lib_files.wxs @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + SYMBOLS=1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/lib/lib_pdb.wixproj b/Tools/msi/lib/lib_pdb.wixproj new file mode 100644 index 000000000000..db1b5bb316cf --- /dev/null +++ b/Tools/msi/lib/lib_pdb.wixproj @@ -0,0 +1,19 @@ + + + + {5E0BCE93-D1AC-4591-BBCB-3A2BE5A4B3D1} + 2.0 + lib_pdb + Package + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/lib/lib_pdb.wxs b/Tools/msi/lib/lib_pdb.wxs new file mode 100644 index 000000000000..8839e8a429f7 --- /dev/null +++ b/Tools/msi/lib/lib_pdb.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tools/msi/make_zip.proj b/Tools/msi/make_zip.proj new file mode 100644 index 000000000000..d2e031f6b6ab --- /dev/null +++ b/Tools/msi/make_zip.proj @@ -0,0 +1,41 @@ + + + + {10487945-15D1-4092-A214-338395C4116B} + python + + false + + + + + + false + python-$(PythonVersion)-embed-$(ArchName) + .zip + $(OutputPath)\en-us\$(TargetName)$(TargetExt) + rmdir /q/s "$(IntermediateOutputPath)\zip_$(ArchName)" + "$(PythonExe)" "$(MSBuildThisFileDirectory)\make_zip.py" + $(Arguments) -e -o "$(TargetPath)" -t "$(IntermediateOutputPath)\zip_$(ArchName)" -a $(ArchName) + set DOC_FILENAME=python$(PythonVersion).chm +set VCREDIST_PATH=$(VS140COMNTOOLS)\..\..\VC\redist\$(Platform)\Microsoft.VC140.CRT + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/make_zip.py b/Tools/msi/make_zip.py new file mode 100644 index 000000000000..96fdad2197b3 --- /dev/null +++ b/Tools/msi/make_zip.py @@ -0,0 +1,200 @@ +import argparse +import py_compile +import re +import sys +import shutil +import stat +import os +import tempfile + +from pathlib import Path +from zipfile import ZipFile, ZIP_DEFLATED +import subprocess + +TKTCL_RE = re.compile(r'^(_?tk|tcl).+\.(pyd|dll)', re.IGNORECASE) +DEBUG_RE = re.compile(r'_d\.(pyd|dll|exe)$', re.IGNORECASE) +PYTHON_DLL_RE = re.compile(r'python\d\d?\.dll$', re.IGNORECASE) + +EXCLUDE_FROM_LIBRARY = { + '__pycache__', + 'ensurepip', + 'idlelib', + 'pydoc_data', + 'site-packages', + 'tkinter', + 'turtledemo', +} + +EXCLUDE_FILE_FROM_LIBRARY = { + 'bdist_wininst.py', +} + +def is_not_debug(p): + if DEBUG_RE.search(p.name): + return False + + if TKTCL_RE.search(p.name): + return False + + return p.name.lower() not in { + '_ctypes_test.pyd', + '_testbuffer.pyd', + '_testcapi.pyd', + '_testimportmultiple.pyd', + '_testmultiphase.pyd', + 'xxlimited.pyd', + } + +def is_not_debug_or_python(p): + return is_not_debug(p) and not PYTHON_DLL_RE.search(p.name) + +def include_in_lib(p): + name = p.name.lower() + if p.is_dir(): + if name in EXCLUDE_FROM_LIBRARY: + return False + if name.startswith('plat-'): + return False + if name == 'test' and p.parts[-2].lower() == 'lib': + return False + if name in {'test', 'tests'} and p.parts[-3].lower() == 'lib': + return False + return True + + if name in EXCLUDE_FILE_FROM_LIBRARY: + return False + + suffix = p.suffix.lower() + return suffix not in {'.pyc', '.pyo', '.exe'} + +def include_in_tools(p): + if p.is_dir() and p.name.lower() in {'scripts', 'i18n', 'pynche', 'demo', 'parser'}: + return True + + return p.suffix.lower() in {'.py', '.pyw', '.txt'} + +FULL_LAYOUT = [ + ('/', 'PCBuild/$arch', 'python*.exe', is_not_debug), + ('/', 'PCBuild/$arch', 'python*.dll', is_not_debug), + ('DLLs/', 'PCBuild/$arch', '*.pyd', is_not_debug), + ('DLLs/', 'PCBuild/$arch', '*.dll', is_not_debug), + ('include/', 'include', '*.h', None), + ('include/', 'PC', 'pyconfig.h', None), + ('Lib/', 'Lib', '**/*', include_in_lib), + ('Tools/', 'Tools', '**/*', include_in_tools), +] + +EMBED_LAYOUT = [ + ('/', 'PCBuild/$arch', 'python*.exe', is_not_debug), + ('/', 'PCBuild/$arch', '*.pyd', is_not_debug), + ('/', 'PCBuild/$arch', '*.dll', is_not_debug), + ('python35.zip', 'Lib', '**/*', include_in_lib), +] + +if os.getenv('DOC_FILENAME'): + FULL_LAYOUT.append(('Doc/', 'Doc/build/htmlhelp', os.getenv('DOC_FILENAME'), None)) +if os.getenv('VCREDIST_PATH'): + FULL_LAYOUT.append(('/', os.getenv('VCREDIST_PATH'), 'vcruntime*.dll', None)) + EMBED_LAYOUT.append(('/', os.getenv('VCREDIST_PATH'), 'vcruntime*.dll', None)) + +def copy_to_layout(target, rel_sources): + count = 0 + + if target.suffix.lower() == '.zip': + if target.exists(): + target.unlink() + + with ZipFile(str(target), 'w', ZIP_DEFLATED) as f: + with tempfile.TemporaryDirectory() as tmpdir: + for s, rel in rel_sources: + if rel.suffix.lower() == '.py': + pyc = Path(tmpdir) / rel.with_suffix('.pyc').name + try: + py_compile.compile(str(s), str(pyc), str(rel), doraise=True, optimize=2) + except py_compile.PyCompileError: + f.write(str(s), str(rel)) + else: + f.write(str(pyc), str(rel.with_suffix('.pyc'))) + else: + f.write(str(s), str(rel)) + count += 1 + + else: + for s, rel in rel_sources: + dest = target / rel + try: + dest.parent.mkdir(parents=True) + except FileExistsError: + pass + if dest.is_file(): + dest.chmod(stat.S_IWRITE) + shutil.copy(str(s), str(dest)) + if dest.is_file(): + dest.chmod(stat.S_IWRITE) + count += 1 + + return count + +def rglob(root, pattern, condition): + dirs = [root] + recurse = pattern[:3] in {'**/', '**\\'} + while dirs: + d = dirs.pop(0) + for f in d.glob(pattern[3:] if recurse else pattern): + if recurse and f.is_dir() and (not condition or condition(f)): + dirs.append(f) + elif f.is_file() and (not condition or condition(f)): + yield f, f.relative_to(root) + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('-s', '--source', metavar='dir', help='The directory containing the repository root', type=Path) + parser.add_argument('-o', '--out', metavar='file', help='The name of the output self-extracting archive', type=Path, required=True) + parser.add_argument('-t', '--temp', metavar='dir', help='A directory to temporarily extract files into', type=Path, default=None) + parser.add_argument('-e', '--embed', help='Create an embedding layout', action='http://github.com/store_true', default=False) + parser.add_argument('-a', '--arch', help='Specify the architecture to use (win32/amd64)', type=str, default="win32") + ns = parser.parse_args() + + source = ns.source or (Path(__file__).parent.parent.parent) + out = ns.out + arch = ns.arch + assert isinstance(source, Path) + assert isinstance(out, Path) + assert isinstance(arch, str) + + if ns.temp: + temp = ns.temp + delete_temp = False + else: + temp = Path(tempfile.mkdtemp()) + delete_temp = True + + try: + out.parent.mkdir(parents=True) + except FileExistsError: + pass + try: + temp.mkdir(parents=True) + except FileExistsError: + pass + + layout = EMBED_LAYOUT if ns.embed else FULL_LAYOUT + + try: + for t, s, p, c in layout: + s = source / s.replace("$arch", arch) + copied = copy_to_layout(temp / t.rstrip('/'), rglob(s, p, c)) + print('Copied {} files'.format(copied)) + + with open(str(temp / 'pyvenv.cfg'), 'w') as f: + print('applocal = true', file=f) + + total = copy_to_layout(out, rglob(temp, '*', None)) + print('Wrote {} files to {}'.format(total, out)) + finally: + if delete_temp: + shutil.rmtree(temp, True) + + +if __name__ == "__main__": + sys.exit(int(main() or 0)) diff --git a/Tools/msi/msi.props b/Tools/msi/msi.props new file mode 100644 index 000000000000..1e2d3e28f57a --- /dev/null +++ b/Tools/msi/msi.props @@ -0,0 +1,175 @@ + + + + $(OutputName) + false + false + $(SuppressIces);ICE03;ICE57;ICE61 + 1026 + false + true + Release + x86 + perUser + + + + + + + + $(ComputerName)/$(ArchName)/ + $(ReleaseUri)/ + + + + + + + + WixUtilExtension + WixUtilExtension + + + + + $(PySourcePath)PCBuild\obj\$(Configuration)_$(Platform)_Setup\$(OutputName) + $(IntermediateOutputPath)_$(OutputSuffix) + $(BuildPath) + $(OutputPath)\ + $(OutputPath) + true + $(ExternalsDir)\redist + + python$(MajorVersionNumber)$(MinorVersionNumber)$(MicroVersionNumber)$(ReleaseLevelName).chm + + $(MajorVersionNumber).$(MinorVersionNumber).$(Field3Value).0 + + + + $([System.Math]::Floor($([System.DateTime]::Now.Subtract($([System.DateTime]::new(2001, 1, 1))).TotalDays))) + $(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)dev$(RevisionNumber) + $(MajorVersionNumber).$(MinorVersionNumber).$(RevisionNumber).0 + + + + 32-bit + 64-bit + + $(DefineConstants); + Version=$(InstallerVersion); + ShortVersion=$(MajorVersionNumber).$(MinorVersionNumber); + LongVersion=$(PythonVersion); + MajorVersionNumber=$(MajorVersionNumber); + MinorVersionNumber=$(MinorVersionNumber); + UpgradeMinimumVersion=$(MajorVersionNumber).$(MinorVersionNumber).0.0; + NextMajorVersionNumber=$(MajorVersionNumber).$([msbuild]::Add($(MinorVersionNumber), 1)).0.0; + Bitness=$(Bitness); + PyDebugExt=$(PyDebugExt); + OptionalFeatureName=$(OutputName); + + + $(DefineConstants);CRTRedist=$(CRTRedist); + + + $(DefineConstants);TestPrefix=;FileExtension=py; + + + $(DefineConstants);TestPrefix=x;FileExtension=px; + + + $(DefineConstants);Suffix32=-32; + + + $(DefineConstants);Suffix32=; + + + + + + generated_filelist + + + + + false + + + + + + + + + + + src + + + tcltk + + + redist + + + redist + + + + + + + + + <_Uuid Include="CoreUpgradeCode"> + upgradecode + + <_Uuid Include="UpgradeCode"> + upgradecode/$(OutputName) + + <_Uuid Include="InstallDirectoryGuidSeed"> + installdirectoryseed + + <_Uuid Include="PythonExeComponentGuid"> + python.exe + + <_Uuid Include="PythonwExeComponentGuid"> + pythonw.exe + + <_Uuid Include="RemoveLib2to3PickleComponentGuid"> + lib2to3/pickles + + + + + <_Uuids>@(_Uuid->'("%(Identity)", "$(MajorVersionNumber).$(MinorVersionNumber)/%(Uri)")',',') + <_GenerateCommand>import uuid; print('\n'.join('{}={}'.format(i, uuid.uuid5(uuid.UUID('c8d9733e-a70c-43ff-ab0c-e26456f11083'), '$(ReleaseUri.Replace(`{arch}`, `$(ArchName)`))' + j)) for i,j in [$(_Uuids.Replace(`"`,`'`))])) + + + + + + + + + + $(DefineConstants);@(_UuidValue,';'); + + + \ No newline at end of file diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py deleted file mode 100644 index 694875a682ec..000000000000 --- a/Tools/msi/msi.py +++ /dev/null @@ -1,1444 +0,0 @@ -# Python MSI Generator -# (C) 2003 Martin v. Loewis -# See "FOO" in comments refers to MSDN sections with the title FOO. -import msilib, schema, sequence, os, glob, time, re, shutil, zipfile -import subprocess, tempfile -from msilib import Feature, CAB, Directory, Dialog, Binary, add_data -import uisample -from win32com.client import constants -from distutils.spawn import find_executable - -# Settings can be overridden in config.py below -# 0 for official python.org releases -# 1 for intermediate releases by anybody, with -# a new product code for every package. -snapshot = 1 -# 1 means that file extension is px, not py, -# and binaries start with x -testpackage = 0 -# Location of build tree -srcdir = os.path.abspath("../..") -# Text to be displayed as the version in dialogs etc. -# goes into file name and ProductCode. Defaults to -# current_version.day for Snapshot, current_version otherwise -full_current_version = None -# Is Tcl available at all? -have_tcl = True -# path to PCbuild directory -PCBUILD="PCbuild" -# msvcrt version -MSVCR = "100" -# Name of certificate in default store to sign MSI with -certname = None -# Make a zip file containing the PDB files for this build? -pdbzip = True - -try: - from config import * -except ImportError: - pass - -# Extract current version from Include/patchlevel.h -lines = open(srcdir + "/Include/patchlevel.h").readlines() -major = minor = micro = level = serial = None -levels = { - 'PY_RELEASE_LEVEL_ALPHA':0xA, - 'PY_RELEASE_LEVEL_BETA': 0xB, - 'PY_RELEASE_LEVEL_GAMMA':0xC, - 'PY_RELEASE_LEVEL_FINAL':0xF - } -for l in lines: - if not l.startswith("#define"): - continue - l = l.split() - if len(l) != 3: - continue - _, name, value = l - if name == 'PY_MAJOR_VERSION': major = value - if name == 'PY_MINOR_VERSION': minor = value - if name == 'PY_MICRO_VERSION': micro = value - if name == 'PY_RELEASE_LEVEL': level = levels[value] - if name == 'PY_RELEASE_SERIAL': serial = value - -short_version = major+"."+minor -# See PC/make_versioninfo.c -FIELD3 = 1000*int(micro) + 10*level + int(serial) -current_version = "%s.%d" % (short_version, FIELD3) - -# This should never change. The UpgradeCode of this package can be -# used in the Upgrade table of future packages to make the future -# package replace this one. See "UpgradeCode Property". -# upgrade_code gets set to upgrade_code_64 when we have determined -# that the target is Win64. -upgrade_code_snapshot='{92A24481-3ECB-40FC-8836-04B7966EC0D5}' -upgrade_code='{65E6DE48-A358-434D-AA4F-4AF72DB4718F}' -upgrade_code_64='{6A965A0C-6EE6-4E3A-9983-3263F56311EC}' - -if snapshot: - current_version = "%s.%s.%s" % (major, minor, int(time.time()/3600/24)) - -if full_current_version is None: - full_current_version = current_version - -extensions = [ - 'pyexpat.pyd', - 'select.pyd', - 'unicodedata.pyd', - 'winsound.pyd', - '_bz2.pyd', - '_elementtree.pyd', - '_socket.pyd', - '_ssl.pyd', - '_testcapi.pyd', - '_tkinter.pyd', - '_msi.pyd', - '_ctypes.pyd', - '_ctypes_test.pyd', - '_sqlite3.pyd', - '_hashlib.pyd', - '_multiprocessing.pyd', - '_lzma.pyd', - '_decimal.pyd', - '_testbuffer.pyd', - '_sha3.pyd', - '_testimportmultiple.pyd', - '_overlapped.pyd', -] - -# Well-known component UUIDs -# These are needed for SharedDLLs reference counter; if -# a different UUID was used for each incarnation of, say, -# python24.dll, an upgrade would set the reference counter -# from 1 to 2 (due to what I consider a bug in MSI) -# Using the same UUID is fine since these files are versioned, -# so Installer will always keep the newest version. -# NOTE: All uuids are self generated. -pythondll_uuid = { - "24":"{9B81E618-2301-4035-AC77-75D9ABEB7301}", - "25":"{2e41b118-38bd-4c1b-a840-6977efd1b911}", - "26":"{34ebecac-f046-4e1c-b0e3-9bac3cdaacfa}", - "27":"{4fe21c76-1760-437b-a2f2-99909130a175}", - "30":"{6953bc3b-6768-4291-8410-7914ce6e2ca8}", - "31":"{4afcba0b-13e4-47c3-bebe-477428b46913}", - "32":"{3ff95315-1096-4d31-bd86-601d5438ad5e}", - "33":"{f7581ca4-d368-4eea-8f82-d48c64c4f047}", - "34":"{7A0C5812-2583-40D9-BCBB-CD7485F11377}", - } [major+minor] - -# Compute the name that Sphinx gives to the docfile -docfile = micro -if level < 0xf: - if level == 0xC: - docfile += "rc%s" % (serial,) - else: - docfile += '%x%s' % (level, serial) -docfile = 'python%s%s%s.chm' % (major, minor, docfile) - -# Build the mingw import library, libpythonXY.a -# This requires 'nm' and 'dlltool' executables on your PATH -def build_mingw_lib(lib_file, def_file, dll_file, mingw_lib): - warning = "WARNING: %s - libpythonXX.a not built" - nm = find_executable('nm') - dlltool = find_executable('dlltool') - - if not nm or not dlltool: - print(warning % "nm and/or dlltool were not found") - return False - - nm_command = '%s -Cs %s' % (nm, lib_file) - dlltool_command = "%s --dllname %s --def %s --output-lib %s" % \ - (dlltool, dll_file, def_file, mingw_lib) - export_match = re.compile(r"^_imp__(.*) in python\d+\.dll").match - - f = open(def_file,'w') - f.write("LIBRARY %s\n" % dll_file) - f.write("EXPORTS\n") - - nm_pipe = os.popen(nm_command) - for line in nm_pipe.readlines(): - m = export_match(line) - if m: - f.write(m.group(1)+"\n") - f.close() - exit = nm_pipe.close() - - if exit: - print(warning % "nm did not run successfully") - return False - - if os.system(dlltool_command) != 0: - print(warning % "dlltool did not run successfully") - return False - - return True - -# Target files (.def and .a) go in PCBuild directory -lib_file = os.path.join(srcdir, PCBUILD, "python%s%s.lib" % (major, minor)) -def_file = os.path.join(srcdir, PCBUILD, "python%s%s.def" % (major, minor)) -dll_file = "python%s%s.dll" % (major, minor) -mingw_lib = os.path.join(srcdir, PCBUILD, "libpython%s%s.a" % (major, minor)) - -have_mingw = build_mingw_lib(lib_file, def_file, dll_file, mingw_lib) - -# Determine the target architecture -if os.system("nmake /nologo /c /f msisupport.mak") != 0: - raise RuntimeError("'nmake /f msisupport.mak' failed") -dll_path = os.path.join(srcdir, PCBUILD, dll_file) -msilib.set_arch_from_file(dll_path) -if msilib.pe_type(dll_path) != msilib.pe_type("msisupport.dll"): - raise SystemError("msisupport.dll for incorrect architecture") - -if msilib.Win64: - upgrade_code = upgrade_code_64 - -if snapshot: - product_code = msilib.gen_uuid() -else: - # official release: generate UUID from the download link that the file will have - import uuid - product_code = uuid.uuid3(uuid.NAMESPACE_URL, - 'http://www.python.org/ftp/python/%s.%s.%s/python-%s%s.msi' % - (major, minor, micro, full_current_version, msilib.arch_ext)) - product_code = '{%s}' % product_code - -if testpackage: - ext = 'px' - testprefix = 'x' -else: - ext = 'py' - testprefix = '' - -if msilib.Win64: - SystemFolderName = "[System64Folder]" - registry_component = 4|256 -else: - SystemFolderName = "[SystemFolder]" - registry_component = 4 - -msilib.reset() - -# condition in which to install pythonxy.dll in system32: -# a) it is Windows 9x or -# b) it is NT, the user is privileged, and has chosen per-machine installation -sys32cond = "(Windows9x or (Privileged and ALLUSERS))" - -def build_database(): - """Generate an empty database, with just the schema and the - Summary information stream.""" - if snapshot: - uc = upgrade_code_snapshot - else: - uc = upgrade_code - if msilib.Win64: - productsuffix = " (64-bit)" - else: - productsuffix = "" - # schema represents the installer 2.0 database schema. - # sequence is the set of standard sequences - # (ui/execute, admin/advt/install) - msiname = "python-%s%s.msi" % (full_current_version, msilib.arch_ext) - db = msilib.init_database(msiname, - schema, ProductName="Python "+full_current_version+productsuffix, - ProductCode=product_code, - ProductVersion=current_version, - Manufacturer=u"Python Software Foundation", - request_uac = True) - # The default sequencing of the RemoveExistingProducts action causes - # removal of files that got just installed. Place it after - # InstallInitialize, so we first uninstall everything, but still roll - # back in case the installation is interrupted - msilib.change_sequence(sequence.InstallExecuteSequence, - "RemoveExistingProducts", 1510) - msilib.add_tables(db, sequence) - # We cannot set ALLUSERS in the property table, as this cannot be - # reset if the user choses a per-user installation. Instead, we - # maintain WhichUsers, which can be "ALL" or "JUSTME". The UI manages - # this property, and when the execution starts, ALLUSERS is set - # accordingly. - add_data(db, "Property", [("UpgradeCode", uc), - ("WhichUsers", "ALL"), - ("ProductLine", "Python%s%s" % (major, minor)), - ]) - db.Commit() - return db, msiname - -def remove_old_versions(db): - "Fill the upgrade table." - start = "%s.%s.0" % (major, minor) - # This requests that feature selection states of an older - # installation should be forwarded into this one. Upgrading - # requires that both the old and the new installation are - # either both per-machine or per-user. - migrate_features = 1 - # See "Upgrade Table". We remove releases with the same major and - # minor version. For an snapshot, we remove all earlier snapshots. For - # a release, we remove all snapshots, and all earlier releases. - if snapshot: - add_data(db, "Upgrade", - [(upgrade_code_snapshot, start, - current_version, - None, # Ignore language - migrate_features, - None, # Migrate ALL features - "REMOVEOLDSNAPSHOT")]) - props = "REMOVEOLDSNAPSHOT" - else: - add_data(db, "Upgrade", - [(upgrade_code, start, current_version, - None, migrate_features, None, "REMOVEOLDVERSION"), - (upgrade_code_snapshot, start, "%s.%d.0" % (major, int(minor)+1), - None, migrate_features, None, "REMOVEOLDSNAPSHOT")]) - props = "REMOVEOLDSNAPSHOT;REMOVEOLDVERSION" - - props += ";TARGETDIR;DLLDIR;LAUNCHERDIR" - # Installer collects the product codes of the earlier releases in - # these properties. In order to allow modification of the properties, - # they must be declared as secure. See "SecureCustomProperties Property" - add_data(db, "Property", [("SecureCustomProperties", props)]) - -class PyDialog(Dialog): - """Dialog class with a fixed layout: controls at the top, then a ruler, - then a list of buttons: back, next, cancel. Optionally a bitmap at the - left.""" - def __init__(self, *args, **kw): - """Dialog(database, name, x, y, w, h, attributes, title, first, - default, cancel, bitmap=true)""" - Dialog.__init__(self, *args) - ruler = self.h - 36 - bmwidth = 152*ruler/328 - if kw.get("bitmap", True): - self.bitmap("Bitmap", 0, 0, bmwidth, ruler, "PythonWin") - self.line("BottomLine", 0, ruler, self.w, 0) - - def title(self, title): - "Set the title text of the dialog at the top." - # name, x, y, w, h, flags=Visible|Enabled|Transparent|NoPrefix, - # text, in VerdanaBold10 - self.text("Title", 135, 10, 220, 60, 0x30003, - r"{\VerdanaBold10}%s" % title) - - def back(self, title, next, name = "Back", active = 1): - """Add a back button with a given title, the tab-next button, - its name in the Control table, possibly initially disabled. - - Return the button, so that events can be associated""" - if active: - flags = 3 # Visible|Enabled - else: - flags = 1 # Visible - return self.pushbutton(name, 180, self.h-27 , 56, 17, flags, title, next) - - def cancel(self, title, next, name = "Cancel", active = 1): - """Add a cancel button with a given title, the tab-next button, - its name in the Control table, possibly initially disabled. - - Return the button, so that events can be associated""" - if active: - flags = 3 # Visible|Enabled - else: - flags = 1 # Visible - return self.pushbutton(name, 304, self.h-27, 56, 17, flags, title, next) - - def next(self, title, next, name = "Next", active = 1): - """Add a Next button with a given title, the tab-next button, - its name in the Control table, possibly initially disabled. - - Return the button, so that events can be associated""" - if active: - flags = 3 # Visible|Enabled - else: - flags = 1 # Visible - return self.pushbutton(name, 236, self.h-27, 56, 17, flags, title, next) - - def xbutton(self, name, title, next, xpos): - """Add a button with a given title, the tab-next button, - its name in the Control table, giving its x position; the - y-position is aligned with the other buttons. - - Return the button, so that events can be associated""" - return self.pushbutton(name, int(self.w*xpos - 28), self.h-27, 56, 17, 3, title, next) - -def add_ui(db): - x = y = 50 - w = 370 - h = 300 - title = "[ProductName] Setup" - - # see "Dialog Style Bits" - modal = 3 # visible | modal - modeless = 1 # visible - track_disk_space = 32 - - add_data(db, 'ActionText', uisample.ActionText) - add_data(db, 'UIText', uisample.UIText) - - # Bitmaps - if not os.path.exists(srcdir+r"\PC\python_icon.exe"): - raise RuntimeError("Run icons.mak in PC directory") - add_data(db, "Binary", - [("PythonWin", msilib.Binary(r"%s\PCbuild\installer.bmp" % srcdir)), # 152x328 pixels - ("py.ico",msilib.Binary(srcdir+r"\PC\py.ico")), - ]) - add_data(db, "Icon", - [("python_icon.exe", msilib.Binary(srcdir+r"\PC\python_icon.exe"))]) - - # Scripts - # CheckDir sets TargetExists if TARGETDIR exists. - # UpdateEditIDLE sets the REGISTRY.tcl component into - # the installed/uninstalled state according to both the - # Extensions and TclTk features. - add_data(db, "Binary", [("Script", msilib.Binary("msisupport.dll"))]) - # See "Custom Action Type 1" - if msilib.Win64: - CheckDir = "CheckDir" - UpdateEditIDLE = "UpdateEditIDLE" - else: - CheckDir = "_CheckDir@4" - UpdateEditIDLE = "_UpdateEditIDLE@4" - add_data(db, "CustomAction", - [("CheckDir", 1, "Script", CheckDir)]) - if have_tcl: - add_data(db, "CustomAction", - [("UpdateEditIDLE", 1, "Script", UpdateEditIDLE)]) - - # UI customization properties - add_data(db, "Property", - # See "DefaultUIFont Property" - [("DefaultUIFont", "DlgFont8"), - # See "ErrorDialog Style Bit" - ("ErrorDialog", "ErrorDlg"), - ("Progress1", "Install"), # modified in maintenance type dlg - ("Progress2", "installs"), - ("MaintenanceForm_Action", "Repair")]) - - # Fonts, see "TextStyle Table" - add_data(db, "TextStyle", - [("DlgFont8", "Tahoma", 9, None, 0), - ("DlgFontBold8", "Tahoma", 8, None, 1), #bold - ("VerdanaBold10", "Verdana", 10, None, 1), - ("VerdanaRed9", "Verdana", 9, 255, 0), - ]) - - compileargs = r'-Wi "[TARGETDIR]Lib\compileall.py" -f -x "bad_coding|badsyntax|site-packages|py2_|lib2to3\\tests|venv\\scripts" "[TARGETDIR]Lib"' - lib2to3args = r'-c "import lib2to3.pygram, lib2to3.patcomp;lib2to3.patcomp.PatternCompiler()"' - updatepipargs = r'-m ensurepip -U' - removepipargs = r'-m ensurepip -r' # does not yet work - # See "CustomAction Table" - add_data(db, "CustomAction", [ - # msidbCustomActionTypeFirstSequence + msidbCustomActionTypeTextData + msidbCustomActionTypeProperty - # See "Custom Action Type 51", - # "Custom Action Execution Scheduling Options" - ("InitialTargetDir", 307, "TARGETDIR", - "[WindowsVolume]Python%s%s" % (major, minor)), - ("SetDLLDirToTarget", 307, "DLLDIR", "[TARGETDIR]"), - ("SetDLLDirToSystem32", 307, "DLLDIR", SystemFolderName), - ("SetLauncherDirToTarget", 307, "LAUNCHERDIR", "[TARGETDIR]"), - ("SetLauncherDirToWindows", 307, "LAUNCHERDIR", "[WindowsFolder]"), - # msidbCustomActionTypeExe + msidbCustomActionTypeSourceFile - # See "Custom Action Type 18" - ("CompilePyc", 18, "python.exe", compileargs), - ("CompilePyo", 18, "python.exe", "-O "+compileargs), - ("CompileGrammar", 18, "python.exe", lib2to3args), - # msidbCustomActionTypeInScript (1024); run during actual installation - ("UpdatePip", 18+1024, "python.exe", updatepipargs), - #("RemovePip", 18, "python.exe", removepipargs), - ]) - - # UI Sequences, see "InstallUISequence Table", "Using a Sequence Table" - # Numbers indicate sequence; see sequence.py for how these action integrate - add_data(db, "InstallUISequence", - [("PrepareDlg", "Not Privileged or Windows9x or Installed", 140), - ("WhichUsersDlg", "Privileged and not Windows9x and not Installed", 141), - ("InitialTargetDir", 'TARGETDIR=""', 750), - # In the user interface, assume all-users installation if privileged. - ("SetDLLDirToSystem32", 'DLLDIR="" and ' + sys32cond, 751), - ("SetDLLDirToTarget", 'DLLDIR="" and not ' + sys32cond, 752), - ("SetLauncherDirToWindows", 'LAUNCHERDIR="" and ' + sys32cond, 753), - ("SetLauncherDirToTarget", 'LAUNCHERDIR="" and not ' + sys32cond, 754), - ("SelectDirectoryDlg", "Not Installed", 1230), - # XXX no support for resume installations yet - #("ResumeDlg", "Installed AND (RESUME OR Preselected)", 1240), - ("MaintenanceTypeDlg", "Installed AND NOT RESUME AND NOT Preselected", 1250), - ("ProgressDlg", None, 1280)]) - add_data(db, "AdminUISequence", - [("InitialTargetDir", 'TARGETDIR=""', 750), - ("SetDLLDirToTarget", 'DLLDIR=""', 751), - ("SetLauncherDirToTarget", 'LAUNCHERDIR=""', 752), - ]) - - # Prepend TARGETDIR to the system path, and remove it on uninstall. - add_data(db, "Environment", - [("PathAddition", "=-*Path", "[TARGETDIR];[TARGETDIR]Scripts;[~]", "REGISTRY.path")]) - - # Execute Sequences - add_data(db, "InstallExecuteSequence", - [("InitialTargetDir", 'TARGETDIR=""', 750), - ("SetDLLDirToSystem32", 'DLLDIR="" and ' + sys32cond, 751), - ("SetDLLDirToTarget", 'DLLDIR="" and not ' + sys32cond, 752), - ("SetLauncherDirToWindows", 'LAUNCHERDIR="" and ' + sys32cond, 753), - ("SetLauncherDirToTarget", 'LAUNCHERDIR="" and not ' + sys32cond, 754), - ("UpdateEditIDLE", None, 1050), - # run command if install state of pip changes to INSTALLSTATE_LOCAL - # run after InstallFiles - ("UpdatePip", "&pip=3", 4001), - # remove pip when state changes to INSTALLSTATE_ABSENT - # run before RemoveFiles - #("RemovePip", "&pip=2", 3499), - ("CompilePyc", "COMPILEALL", 6800), - ("CompilePyo", "COMPILEALL", 6801), - ("CompileGrammar", "COMPILEALL", 6802), - ]) - add_data(db, "AdminExecuteSequence", - [("InitialTargetDir", 'TARGETDIR=""', 750), - ("SetDLLDirToTarget", 'DLLDIR=""', 751), - ("SetLauncherDirToTarget", 'LAUNCHERDIR=""', 752), - ("CompilePyc", "COMPILEALL", 6800), - ("CompilePyo", "COMPILEALL", 6801), - ("CompileGrammar", "COMPILEALL", 6802), - ]) - - ##################################################################### - # Standard dialogs: FatalError, UserExit, ExitDialog - fatal=PyDialog(db, "FatalError", x, y, w, h, modal, title, - "Finish", "Finish", "Finish") - fatal.title("[ProductName] Installer ended prematurely") - fatal.back("< Back", "Finish", active = 0) - fatal.cancel("Cancel", "Back", active = 0) - fatal.text("Description1", 135, 70, 220, 80, 0x30003, - "[ProductName] setup ended prematurely because of an error. Your system has not been modified. To install this program at a later time, please run the installation again.") - fatal.text("Description2", 135, 155, 220, 20, 0x30003, - "Click the Finish button to exit the Installer.") - c=fatal.next("Finish", "Cancel", name="Finish") - # See "ControlEvent Table". Parameters are the event, the parameter - # to the action, and optionally the condition for the event, and the order - # of events. - c.event("EndDialog", "Exit") - - user_exit=PyDialog(db, "UserExit", x, y, w, h, modal, title, - "Finish", "Finish", "Finish") - user_exit.title("[ProductName] Installer was interrupted") - user_exit.back("< Back", "Finish", active = 0) - user_exit.cancel("Cancel", "Back", active = 0) - user_exit.text("Description1", 135, 70, 220, 80, 0x30003, - "[ProductName] setup was interrupted. Your system has not been modified. " - "To install this program at a later time, please run the installation again.") - user_exit.text("Description2", 135, 155, 220, 20, 0x30003, - "Click the Finish button to exit the Installer.") - c = user_exit.next("Finish", "Cancel", name="Finish") - c.event("EndDialog", "Exit") - - exit_dialog = PyDialog(db, "ExitDialog", x, y, w, h, modal, title, - "Finish", "Finish", "Finish") - exit_dialog.title("Complete the [ProductName] Installer") - exit_dialog.back("< Back", "Finish", active = 0) - exit_dialog.cancel("Cancel", "Back", active = 0) - exit_dialog.text("Acknowledgements", 135, 95, 220, 120, 0x30003, - "Special Windows thanks to:\n" - " Mark Hammond, without whose years of freely \n" - " shared Windows expertise, Python for Windows \n" - " would still be Python for DOS.") - - c = exit_dialog.text("warning", 135, 200, 220, 40, 0x30003, - "{\\VerdanaRed9}Warning: Python 2.5.x is the last " - "Python release for Windows 9x.") - c.condition("Hide", "NOT Version9X") - - exit_dialog.text("Description", 135, 235, 220, 20, 0x30003, - "Click the Finish button to exit the Installer.") - c = exit_dialog.next("Finish", "Cancel", name="Finish") - c.event("EndDialog", "Return") - - ##################################################################### - # Required dialog: FilesInUse, ErrorDlg - inuse = PyDialog(db, "FilesInUse", - x, y, w, h, - 19, # KeepModeless|Modal|Visible - title, - "Retry", "Retry", "Retry", bitmap=False) - inuse.text("Title", 15, 6, 200, 15, 0x30003, - r"{\DlgFontBold8}Files in Use") - inuse.text("Description", 20, 23, 280, 20, 0x30003, - "Some files that need to be updated are currently in use.") - inuse.text("Text", 20, 55, 330, 50, 3, - "The following applications are using files that need to be updated by this setup. Close these applications and then click Retry to continue the installation or Cancel to exit it.") - inuse.control("List", "ListBox", 20, 107, 330, 130, 7, "FileInUseProcess", - None, None, None) - c=inuse.back("Exit", "Ignore", name="Exit") - c.event("EndDialog", "Exit") - c=inuse.next("Ignore", "Retry", name="Ignore") - c.event("EndDialog", "Ignore") - c=inuse.cancel("Retry", "Exit", name="Retry") - c.event("EndDialog","Retry") - - - # See "Error Dialog". See "ICE20" for the required names of the controls. - error = Dialog(db, "ErrorDlg", - 50, 10, 330, 101, - 65543, # Error|Minimize|Modal|Visible - title, - "ErrorText", None, None) - error.text("ErrorText", 50,9,280,48,3, "") - error.control("ErrorIcon", "Icon", 15, 9, 24, 24, 5242881, None, "py.ico", None, None) - error.pushbutton("N",120,72,81,21,3,"No",None).event("EndDialog","ErrorNo") - error.pushbutton("Y",240,72,81,21,3,"Yes",None).event("EndDialog","ErrorYes") - error.pushbutton("A",0,72,81,21,3,"Abort",None).event("EndDialog","ErrorAbort") - error.pushbutton("C",42,72,81,21,3,"Cancel",None).event("EndDialog","ErrorCancel") - error.pushbutton("I",81,72,81,21,3,"Ignore",None).event("EndDialog","ErrorIgnore") - error.pushbutton("O",159,72,81,21,3,"Ok",None).event("EndDialog","ErrorOk") - error.pushbutton("R",198,72,81,21,3,"Retry",None).event("EndDialog","ErrorRetry") - - ##################################################################### - # Global "Query Cancel" dialog - cancel = Dialog(db, "CancelDlg", 50, 10, 260, 85, 3, title, - "No", "No", "No") - cancel.text("Text", 48, 15, 194, 30, 3, - "Are you sure you want to cancel [ProductName] installation?") - cancel.control("Icon", "Icon", 15, 15, 24, 24, 5242881, None, - "py.ico", None, None) - c=cancel.pushbutton("Yes", 72, 57, 56, 17, 3, "Yes", "No") - c.event("EndDialog", "Exit") - - c=cancel.pushbutton("No", 132, 57, 56, 17, 3, "No", "Yes") - c.event("EndDialog", "Return") - - ##################################################################### - # Global "Wait for costing" dialog - costing = Dialog(db, "WaitForCostingDlg", 50, 10, 260, 85, modal, title, - "Return", "Return", "Return") - costing.text("Text", 48, 15, 194, 30, 3, - "Please wait while the installer finishes determining your disk space requirements.") - costing.control("Icon", "Icon", 15, 15, 24, 24, 5242881, None, - "py.ico", None, None) - c = costing.pushbutton("Return", 102, 57, 56, 17, 3, "Return", None) - c.event("EndDialog", "Exit") - - ##################################################################### - # Preparation dialog: no user input except cancellation - prep = PyDialog(db, "PrepareDlg", x, y, w, h, modeless, title, - "Cancel", "Cancel", "Cancel") - prep.text("Description", 135, 70, 220, 40, 0x30003, - "Please wait while the Installer prepares to guide you through the installation.") - prep.title("Welcome to the [ProductName] Installer") - c=prep.text("ActionText", 135, 110, 220, 20, 0x30003, "Pondering...") - c.mapping("ActionText", "Text") - c=prep.text("ActionData", 135, 135, 220, 30, 0x30003, None) - c.mapping("ActionData", "Text") - prep.back("Back", None, active=0) - prep.next("Next", None, active=0) - c=prep.cancel("Cancel", None) - c.event("SpawnDialog", "CancelDlg") - - ##################################################################### - # Target directory selection - seldlg = PyDialog(db, "SelectDirectoryDlg", x, y, w, h, modal, title, - "Next", "Next", "Cancel") - seldlg.title("Select Destination Directory") - c = seldlg.text("Existing", 135, 25, 235, 30, 0x30003, - "{\VerdanaRed9}This update will replace your existing [ProductLine] installation.") - c.condition("Hide", 'REMOVEOLDVERSION="" and REMOVEOLDSNAPSHOT=""') - seldlg.text("Description", 135, 50, 220, 40, 0x30003, - "Please select a directory for the [ProductName] files.") - - seldlg.back("< Back", None, active=0) - c = seldlg.next("Next >", "Cancel") - c.event("DoAction", "CheckDir", "TargetExistsOk<>1", order=1) - # If the target exists, but we found that we are going to remove old versions, don't bother - # confirming that the target directory exists. Strictly speaking, we should determine that - # the target directory is indeed the target of the product that we are going to remove, but - # I don't know how to do that. - c.event("SpawnDialog", "ExistingDirectoryDlg", 'TargetExists=1 and REMOVEOLDVERSION="" and REMOVEOLDSNAPSHOT=""', 2) - c.event("SetTargetPath", "TARGETDIR", 'TargetExists=0 or REMOVEOLDVERSION<>"" or REMOVEOLDSNAPSHOT<>""', 3) - c.event("SpawnWaitDialog", "WaitForCostingDlg", "CostingComplete=1", 4) - c.event("NewDialog", "SelectFeaturesDlg", 'TargetExists=0 or REMOVEOLDVERSION<>"" or REMOVEOLDSNAPSHOT<>""', 5) - - c = seldlg.cancel("Cancel", "DirectoryCombo") - c.event("SpawnDialog", "CancelDlg") - - seldlg.control("DirectoryCombo", "DirectoryCombo", 135, 70, 172, 80, 393219, - "TARGETDIR", None, "DirectoryList", None) - seldlg.control("DirectoryList", "DirectoryList", 135, 90, 208, 136, 3, "TARGETDIR", - None, "PathEdit", None) - seldlg.control("PathEdit", "PathEdit", 135, 230, 206, 16, 3, "TARGETDIR", None, "Next", None) - c = seldlg.pushbutton("Up", 306, 70, 18, 18, 3, "Up", None) - c.event("DirectoryListUp", "0") - c = seldlg.pushbutton("NewDir", 324, 70, 30, 18, 3, "New", None) - c.event("DirectoryListNew", "0") - - ##################################################################### - # SelectFeaturesDlg - features = PyDialog(db, "SelectFeaturesDlg", x, y, w, h, modal|track_disk_space, - title, "Tree", "Next", "Cancel") - features.title("Customize [ProductName]") - features.text("Description", 135, 35, 220, 15, 0x30003, - "Select the way you want features to be installed.") - features.text("Text", 135,45,220,30, 3, - "Click on the icons in the tree below to change the way features will be installed.") - - c=features.back("< Back", "Next") - c.event("NewDialog", "SelectDirectoryDlg") - - c=features.next("Next >", "Cancel") - c.mapping("SelectionNoItems", "Enabled") - c.event("SpawnDialog", "DiskCostDlg", "OutOfDiskSpace=1", order=1) - c.event("EndDialog", "Return", "OutOfDiskSpace<>1", order=2) - - c=features.cancel("Cancel", "Tree") - c.event("SpawnDialog", "CancelDlg") - - # The browse property is not used, since we have only a single target path (selected already) - features.control("Tree", "SelectionTree", 135, 75, 220, 95, 7, "_BrowseProperty", - "Tree of selections", "Back", None) - - #c=features.pushbutton("Reset", 42, 243, 56, 17, 3, "Reset", "DiskCost") - #c.mapping("SelectionNoItems", "Enabled") - #c.event("Reset", "0") - - features.control("Box", "GroupBox", 135, 170, 225, 90, 1, None, None, None, None) - - c=features.xbutton("DiskCost", "Disk &Usage", None, 0.10) - c.mapping("SelectionNoItems","Enabled") - c.event("SpawnDialog", "DiskCostDlg") - - c=features.xbutton("Advanced", "Advanced", None, 0.30) - c.event("SpawnDialog", "AdvancedDlg") - - c=features.text("ItemDescription", 140, 180, 210, 40, 3, - "Multiline description of the currently selected item.") - c.mapping("SelectionDescription","Text") - - c=features.text("ItemSize", 140, 225, 210, 33, 3, - "The size of the currently selected item.") - c.mapping("SelectionSize", "Text") - - ##################################################################### - # Disk cost - cost = PyDialog(db, "DiskCostDlg", x, y, w, h, modal, title, - "OK", "OK", "OK", bitmap=False) - cost.text("Title", 15, 6, 200, 15, 0x30003, - "{\DlgFontBold8}Disk Space Requirements") - cost.text("Description", 20, 20, 280, 20, 0x30003, - "The disk space required for the installation of the selected features.") - cost.text("Text", 20, 53, 330, 60, 3, - "The highlighted volumes (if any) do not have enough disk space " - "available for the currently selected features. You can either " - "remove some files from the highlighted volumes, or choose to " - "install less features onto local drive(s), or select different " - "destination drive(s).") - cost.control("VolumeList", "VolumeCostList", 20, 100, 330, 150, 393223, - None, "{120}{70}{70}{70}{70}", None, None) - cost.xbutton("OK", "Ok", None, 0.5).event("EndDialog", "Return") - - ##################################################################### - # WhichUsers Dialog. Only available on NT, and for privileged users. - # This must be run before FindRelatedProducts, because that will - # take into account whether the previous installation was per-user - # or per-machine. We currently don't support going back to this - # dialog after "Next" was selected; to support this, we would need to - # find how to reset the ALLUSERS property, and how to re-run - # FindRelatedProducts. - # On Windows9x, the ALLUSERS property is ignored on the command line - # and in the Property table, but installer fails according to the documentation - # if a dialog attempts to set ALLUSERS. - whichusers = PyDialog(db, "WhichUsersDlg", x, y, w, h, modal, title, - "AdminInstall", "Next", "Cancel") - whichusers.title("Select whether to install [ProductName] for all users of this computer.") - # A radio group with two options: allusers, justme - g = whichusers.radiogroup("AdminInstall", 135, 60, 235, 80, 3, - "WhichUsers", "", "Next") - g.condition("Disable", "VersionNT=600") # Not available on Vista and Windows 2008 - g.add("ALL", 0, 5, 150, 20, "Install for all users") - g.add("JUSTME", 0, 25, 235, 20, "Install just for me (not available on Windows Vista)") - - whichusers.back("Back", None, active=0) - - c = whichusers.next("Next >", "Cancel") - c.event("[ALLUSERS]", "1", 'WhichUsers="ALL"', 1) - c.event("EndDialog", "Return", order = 2) - - c = whichusers.cancel("Cancel", "AdminInstall") - c.event("SpawnDialog", "CancelDlg") - - ##################################################################### - # Advanced Dialog. - advanced = PyDialog(db, "AdvancedDlg", x, y, w, h, modal, title, - "CompilePyc", "Ok", "Ok") - advanced.title("Advanced Options for [ProductName]") - - # A checkbox whether to build pyc files - advanced.checkbox("CompilePyc", 135, 60, 230, 50, 3, - "COMPILEALL", "Compile .py files to byte code after installation", "Ok") - - c = advanced.cancel("Ok", "CompilePyc", name="Ok") # Button just has location of cancel button. - c.event("EndDialog", "Return") - - ##################################################################### - # Existing Directory dialog - dlg = Dialog(db, "ExistingDirectoryDlg", 50, 30, 200, 80, modal, title, - "No", "No", "No") - dlg.text("Title", 10, 20, 180, 40, 3, - "[TARGETDIR] exists. Are you sure you want to overwrite existing files?") - c=dlg.pushbutton("Yes", 30, 60, 55, 17, 3, "Yes", "No") - c.event("[TargetExists]", "0", order=1) - c.event("[TargetExistsOk]", "1", order=2) - c.event("EndDialog", "Return", order=3) - c=dlg.pushbutton("No", 115, 60, 55, 17, 3, "No", "Yes") - c.event("EndDialog", "Return") - - ##################################################################### - # Installation Progress dialog (modeless) - progress = PyDialog(db, "ProgressDlg", x, y, w, h, modeless, title, - "Cancel", "Cancel", "Cancel", bitmap=False) - progress.text("Title", 20, 15, 200, 15, 0x30003, - "{\DlgFontBold8}[Progress1] [ProductName]") - progress.text("Text", 35, 65, 300, 30, 3, - "Please wait while the Installer [Progress2] [ProductName]. " - "This may take several minutes.") - progress.text("StatusLabel", 35, 100, 35, 20, 3, "Status:") - - c=progress.text("ActionText", 70, 100, w-70, 20, 3, "Pondering...") - c.mapping("ActionText", "Text") - - #c=progress.text("ActionData", 35, 140, 300, 20, 3, None) - #c.mapping("ActionData", "Text") - - c=progress.control("ProgressBar", "ProgressBar", 35, 120, 300, 10, 65537, - None, "Progress done", None, None) - c.mapping("SetProgress", "Progress") - - progress.back("< Back", "Next", active=False) - progress.next("Next >", "Cancel", active=False) - progress.cancel("Cancel", "Back").event("SpawnDialog", "CancelDlg") - - # Maintenance type: repair/uninstall - maint = PyDialog(db, "MaintenanceTypeDlg", x, y, w, h, modal, title, - "Next", "Next", "Cancel") - maint.title("Welcome to the [ProductName] Setup Wizard") - maint.text("BodyText", 135, 63, 230, 42, 3, - "Select whether you want to repair or remove [ProductName].") - g=maint.radiogroup("RepairRadioGroup", 135, 108, 230, 60, 3, - "MaintenanceForm_Action", "", "Next") - g.add("Change", 0, 0, 200, 17, "&Change [ProductName]") - g.add("Repair", 0, 18, 200, 17, "&Repair [ProductName]") - g.add("Remove", 0, 36, 200, 17, "Re&move [ProductName]") - - maint.back("< Back", None, active=False) - c=maint.next("Finish", "Cancel") - # Change installation: Change progress dialog to "Change", then ask - # for feature selection - c.event("[Progress1]", "Change", 'MaintenanceForm_Action="Change"', 1) - c.event("[Progress2]", "changes", 'MaintenanceForm_Action="Change"', 2) - - # Reinstall: Change progress dialog to "Repair", then invoke reinstall - # Also set list of reinstalled features to "ALL" - c.event("[REINSTALL]", "ALL", 'MaintenanceForm_Action="Repair"', 5) - c.event("[Progress1]", "Repairing", 'MaintenanceForm_Action="Repair"', 6) - c.event("[Progress2]", "repairs", 'MaintenanceForm_Action="Repair"', 7) - c.event("Reinstall", "ALL", 'MaintenanceForm_Action="Repair"', 8) - - # Uninstall: Change progress to "Remove", then invoke uninstall - # Also set list of removed features to "ALL" - c.event("[REMOVE]", "ALL", 'MaintenanceForm_Action="Remove"', 11) - c.event("[Progress1]", "Removing", 'MaintenanceForm_Action="Remove"', 12) - c.event("[Progress2]", "removes", 'MaintenanceForm_Action="Remove"', 13) - c.event("Remove", "ALL", 'MaintenanceForm_Action="Remove"', 14) - - # Close dialog when maintenance action scheduled - c.event("EndDialog", "Return", 'MaintenanceForm_Action<>"Change"', 20) - c.event("NewDialog", "SelectFeaturesDlg", 'MaintenanceForm_Action="Change"', 21) - - maint.cancel("Cancel", "RepairRadioGroup").event("SpawnDialog", "CancelDlg") - - -# See "Feature Table". The feature level is 1 for all features, -# and the feature attributes are 0 for the DefaultFeature, and -# FollowParent for all other features. The numbers are the Display -# column. -def add_features(db): - # feature attributes: - # msidbFeatureAttributesFollowParent == 2 - # msidbFeatureAttributesDisallowAdvertise == 8 - # Features that need to be installed with together with the main feature - # (i.e. additional Python libraries) need to follow the parent feature. - # Features that have no advertisement trigger (e.g. the test suite) - # must not support advertisement - global default_feature, tcltk, htmlfiles, tools, testsuite - global ext_feature, private_crt, prepend_path, update_pip - default_feature = Feature(db, "DefaultFeature", "Python", - "Python Interpreter and Libraries", - 1, directory = "TARGETDIR") - shared_crt = Feature(db, "SharedCRT", "MSVCRT", "C Run-Time (system-wide)", 0, - level=0) - private_crt = Feature(db, "PrivateCRT", "MSVCRT", "C Run-Time (private)", 0, - level=0) - add_data(db, "Condition", [("SharedCRT", 1, sys32cond), - ("PrivateCRT", 1, "not "+sys32cond)]) - # We don't support advertisement of extensions - ext_feature = Feature(db, "Extensions", "Register Extensions", - "Make this Python installation the default Python installation", 3, - parent = default_feature, attributes=2|8) - if have_tcl: - tcltk = Feature(db, "TclTk", "Tcl/Tk", "Tkinter, IDLE, pydoc", 5, - parent = default_feature, attributes=2) - htmlfiles = Feature(db, "Documentation", "Documentation", - "Python HTMLHelp File", 7, parent = default_feature) - tools = Feature(db, "Tools", "Utility Scripts", - "Python utility scripts (Tools/)", 9, - parent = default_feature, attributes=2) - # pip installation isn't enabled by default until a clean uninstall procedure - # becomes possible - update_pip = Feature(db, "pip", "pip", - "Install (or upgrade from an earlier version) pip, " - "a tool for installing and managing Python packages.", 11, - parent = default_feature, attributes=2|8, level=2) - testsuite = Feature(db, "Testsuite", "Test suite", - "Python test suite (Lib/test/)", 13, - parent = default_feature, attributes=2|8) - # prepend_path is an additional feature which is to be off by default. - # Since the default level for the above features is 1, this needs to be - # at least level higher. - prepend_path = Feature(db, "PrependPath", "Add python.exe to Path", - "Prepend [TARGETDIR] to the system Path variable. " - "This allows you to type 'python' into a command " - "prompt without needing the full path.", 15, - parent = default_feature, attributes=2|8, - level=2) - -def extract_msvcr100(): - # Find the redistributable files - if msilib.Win64: - arch = "x64" - else: - arch = "x86" - dir = os.path.join(os.environ['VS100COMNTOOLS'], r"..\..\VC\redist\%s\Microsoft.VC100.CRT" % arch) - - result = [] - installer = msilib.MakeInstaller() - # At least for VS2010, manifests are no longer provided - name = "msvcr100.dll" - path = os.path.join(dir, name) - kw = {'src':path} - kw['version'] = installer.FileVersion(path, 0) - kw['language'] = installer.FileVersion(path, 1) - return name, kw - -def generate_license(): - import shutil, glob - out = open("LICENSE.txt", "w") - shutil.copyfileobj(open(os.path.join(srcdir, "LICENSE")), out) - shutil.copyfileobj(open("crtlicense.txt"), out) - for name, pat, file in (("bzip2","bzip2-*", "LICENSE"), - ("openssl", "openssl-*", "LICENSE"), - ("Tcl", "tcl8*", "license.terms"), - ("Tk", "tk8*", "license.terms"), - ("Tix", "tix-*", "license.terms")): - out.write("\nThis copy of Python includes a copy of %s, which is licensed under the following terms:\n\n" % name) - dirs = glob.glob(srcdir+"/../"+pat) - if not dirs: - raise ValueError, "Could not find "+srcdir+"/../"+pat - if len(dirs) > 2 and not snapshot: - raise ValueError, "Multiple copies of "+pat - dir = dirs[0] - shutil.copyfileobj(open(os.path.join(dir, file)), out) - out.close() - - -class PyDirectory(Directory): - """By default, all components in the Python installer - can run from source.""" - def __init__(self, *args, **kw): - if "componentflags" not in kw: - kw['componentflags'] = 2 #msidbComponentAttributesOptional - Directory.__init__(self, *args, **kw) - -def hgmanifest(): - # Fetch file list from Mercurial - process = subprocess.Popen(['hg', 'manifest'], stdout=subprocess.PIPE) - stdout, stderr = process.communicate() - # Create nested directories for file tree - result = {} - for line in stdout.splitlines(): - components = line.split('/') - d = result - while len(components) > 1: - d1 = d.setdefault(components[0], {}) - d = d1 - del components[0] - d[components[0]] = None - return result - - -# See "File Table", "Component Table", "Directory Table", -# "FeatureComponents Table" -def add_files(db): - installer = msilib.MakeInstaller() - hgfiles = hgmanifest() - cab = CAB("python") - tmpfiles = [] - # Add all executables, icons, text files into the TARGETDIR component - root = PyDirectory(db, cab, None, srcdir, "TARGETDIR", "SourceDir") - default_feature.set_current() - root.add_file("README.txt", src="http://github.com/README") - root.add_file("NEWS.txt", src="http://github.com/Misc/NEWS") - generate_license() - root.add_file("LICENSE.txt", src=os.path.abspath("LICENSE.txt")) - root.start_component("python.exe", keyfile="python.exe") - root.add_file("%s/python.exe" % PCBUILD) - root.start_component("pythonw.exe", keyfile="pythonw.exe") - root.add_file("%s/pythonw.exe" % PCBUILD) - - # msidbComponentAttributesSharedDllRefCount = 8, see "Component Table" - dlldir = PyDirectory(db, cab, root, srcdir, "DLLDIR", ".") - launcherdir = PyDirectory(db, cab, root, srcdir, "LAUNCHERDIR", ".") - - # msidbComponentAttributes64bit = 256; this disables registry redirection - # to allow setting the SharedDLLs key in the 64-bit portion even for a - # 32-bit installer. - # XXX does this still allow to install the component on a 32-bit system? - # Pick up 32-bit binary always - launchersrc = PCBUILD - if launchersrc.lower() == 'pcbuild\\x64-pgo': - launchersrc = 'PCBuild\\win32-pgo' - if launchersrc.lower() == 'pcbuild\\amd64': - launchersrc = 'PCBuild' - launcher = os.path.join(srcdir, launchersrc, "py.exe") - launcherdir.start_component("launcher", flags = 8+256, keyfile="py.exe") - launcherdir.add_file(launcher, - version=installer.FileVersion(launcher, 0), - language=installer.FileVersion(launcher, 1)) - launcherw = os.path.join(srcdir, launchersrc, "pyw.exe") - launcherdir.start_component("launcherw", flags = 8+256, keyfile="pyw.exe") - launcherdir.add_file(launcherw, - version=installer.FileVersion(launcherw, 0), - language=installer.FileVersion(launcherw, 1)) - - pydll = "python%s%s.dll" % (major, minor) - pydllsrc = os.path.join(srcdir, PCBUILD, pydll) - dlldir.start_component("DLLDIR", flags = 8, keyfile = pydll, uuid = pythondll_uuid) - pyversion = installer.FileVersion(pydllsrc, 0) - if not snapshot: - # For releases, the Python DLL has the same version as the - # installer package. - assert pyversion.split(".")[:3] == current_version.split(".") - dlldir.add_file("%s/python%s%s.dll" % (PCBUILD, major, minor), - version=pyversion, - language=installer.FileVersion(pydllsrc, 1)) - DLLs = PyDirectory(db, cab, root, srcdir + "/" + PCBUILD, "DLLs", "DLLS|DLLs") - - # msvcr90.dll: Need to place the DLL and the manifest into the root directory, - # plus another copy of the manifest in the DLLs directory, with the manifest - # pointing to the root directory - root.start_component("msvcr90", feature=private_crt) - # Results are ID,keyword pairs - crtdll, kwds = extract_msvcr100() - root.add_file(crtdll, **kwds) - # Copy the manifest - # Actually, don't do that anymore - no DLL in DLLs should have a manifest - # dependency on msvcr90.dll anymore, so this should not be necessary - #manifest_dlls = manifest[0]+".root" - #open(manifest_dlls, "w").write(open(manifest[1]['src']).read().replace("msvcr","../msvcr")) - #DLLs.start_component("msvcr90_dlls", feature=private_crt) - #DLLs.add_file(manifest[0], src=os.path.abspath(manifest_dlls)) - - # Now start the main component for the DLLs directory; - # no regular files have been added to the directory yet. - DLLs.start_component() - - # Check if _ctypes.pyd exists - have_ctypes = os.path.exists(srcdir+"/%s/_ctypes.pyd" % PCBUILD) - if not have_ctypes: - print("WARNING: _ctypes.pyd not found, ctypes will not be included") - extensions.remove("_ctypes.pyd") - - # Add all .py files in Lib, except tkinter, test - dirs = [] - pydirs = [(root, "Lib", hgfiles["Lib"], default_feature)] - while pydirs: - # Commit every now and then, or else installer will complain - db.Commit() - parent, dir, files, feature = pydirs.pop() - if dir.startswith("plat-"): - continue - if dir in ["tkinter", "idlelib", "turtledemo"]: - if not have_tcl: - continue - feature = tcltk - tcltk.set_current() - elif dir in ('test', 'tests'): - feature = testsuite - elif not have_ctypes and dir == "ctypes": - continue - feature.set_current() - lib = PyDirectory(db, cab, parent, dir, dir, "%s|%s" % (parent.make_short(dir), dir)) - dirs.append(lib) - has_py = False - for name, subdir in files.items(): - if subdir is None: - assert os.path.isfile(os.path.join(lib.absolute, name)) - if name == 'README': - lib.add_file("README.txt", src="http://github.com/README") - else: - lib.add_file(name) - has_py = has_py or name.endswith(".py") or name.endswith(".pyw") - else: - assert os.path.isdir(os.path.join(lib.absolute, name)) - pydirs.append((lib, name, subdir, feature)) - - if has_py: - lib.remove_pyc() - # Add DLLs - default_feature.set_current() - lib = DLLs - lib.add_file("py.ico", src=srcdir+"/PC/py.ico") - lib.add_file("pyc.ico", src=srcdir+"/PC/pyc.ico") - dlls = [] - tclfiles = [] - for f in extensions: - if f=="_tkinter.pyd": - continue - if not os.path.exists(srcdir + "/" + PCBUILD + "/" + f): - print("WARNING: Missing extension", f) - continue - dlls.append(f) - lib.add_file(f) - lib.add_file('python3.dll') - # Add sqlite - if msilib.msi_type=="Intel64;1033": - sqlite_arch = "/ia64" - elif msilib.msi_type=="x64;1033": - sqlite_arch = "/amd64" - tclsuffix = "64" - else: - sqlite_arch = "" - tclsuffix = "" - lib.add_file("sqlite3.dll") - if have_tcl: - if not os.path.exists("%s/%s/_tkinter.pyd" % (srcdir, PCBUILD)): - print("WARNING: Missing _tkinter.pyd") - else: - lib.start_component("TkDLLs", tcltk) - lib.add_file("_tkinter.pyd") - dlls.append("_tkinter.pyd") - tcldir = os.path.normpath(srcdir+("/../tcltk%s/bin" % tclsuffix)) - for f in glob.glob1(tcldir, "*.dll"): - lib.add_file(f, src=os.path.join(tcldir, f)) - # check whether there are any unknown extensions - for f in glob.glob1(srcdir+"/"+PCBUILD, "*.pyd"): - if f.endswith("_d.pyd"): continue # debug version - if f in dlls: continue - print("WARNING: Unknown extension", f) - - # Add headers - default_feature.set_current() - lib = PyDirectory(db, cab, root, "include", "include", "INCLUDE|include") - lib.glob("*.h") - lib.add_file("pyconfig.h", src="http://github.com/PC/pyconfig.h") - # Add import libraries - lib = PyDirectory(db, cab, root, PCBUILD, "libs", "LIBS|libs") - for f in dlls: - lib.add_file(f.replace('pyd','lib')) - lib.add_file('python%s%s.lib' % (major, minor)) - lib.add_file('python3.lib') - # Add the mingw-format library - if have_mingw: - lib.add_file('libpython%s%s.a' % (major, minor)) - if have_tcl: - # Add Tcl/Tk - tcldirs = [(root, '../tcltk%s/lib' % tclsuffix, 'tcl')] - tcltk.set_current() - while tcldirs: - parent, phys, dir = tcldirs.pop() - lib = PyDirectory(db, cab, parent, phys, dir, "%s|%s" % (parent.make_short(dir), dir)) - if not os.path.exists(lib.absolute): - continue - for f in os.listdir(lib.absolute): - if os.path.isdir(os.path.join(lib.absolute, f)): - tcldirs.append((lib, f, f)) - else: - lib.add_file(f) - # Add tools - tools.set_current() - tooldir = PyDirectory(db, cab, root, "Tools", "Tools", "TOOLS|Tools") - for f in ['i18n', 'pynche', 'Scripts']: - lib = PyDirectory(db, cab, tooldir, f, f, "%s|%s" % (tooldir.make_short(f), f)) - lib.glob("*.py") - lib.glob("*.pyw", exclude=['pydocgui.pyw']) - lib.remove_pyc() - lib.glob("*.txt") - if f == "pynche": - x = PyDirectory(db, cab, lib, "X", "X", "X|X") - x.glob("*.txt") - if os.path.exists(os.path.join(lib.absolute, "README")): - lib.add_file("README.txt", src="http://github.com/README") - if f == 'Scripts': - lib.add_file("2to3.py", src="http://github.com/2to3") - lib.add_file("pydoc3.py", src="http://github.com/pydoc3") - lib.add_file("pyvenv.py", src="http://github.com/pyvenv") - if have_tcl: - lib.start_component("pydocgui.pyw", tcltk, keyfile="pydocgui.pyw") - lib.add_file("pydocgui.pyw") - # Add documentation - htmlfiles.set_current() - lib = PyDirectory(db, cab, root, "Doc", "Doc", "DOC|Doc") - lib.start_component("documentation", keyfile=docfile) - lib.add_file(docfile, src="http://github.com/build/htmlhelp/"+docfile) - - cab.commit(db) - - for f in tmpfiles: - os.unlink(f) - -# See "Registry Table", "Component Table" -def add_registry(db): - # File extensions, associated with the REGISTRY.def component - # IDLE verbs depend on the tcltk feature. - # msidbComponentAttributesRegistryKeyPath = 4 - # -1 for Root specifies "dependent on ALLUSERS property" - tcldata = [] - if have_tcl: - tcldata = [ - ("REGISTRY.tcl", msilib.gen_uuid(), "TARGETDIR", registry_component, None, - "py.IDLE")] - add_data(db, "Component", - # msidbComponentAttributesRegistryKeyPath = 4 - [("REGISTRY", msilib.gen_uuid(), "TARGETDIR", registry_component, None, - "InstallPath"), - ("REGISTRY.doc", msilib.gen_uuid(), "TARGETDIR", registry_component, None, - "Documentation"), - ("REGISTRY.path", msilib.gen_uuid(), "TARGETDIR", registry_component, None, - None), - ("REGISTRY.def", msilib.gen_uuid(), "TARGETDIR", registry_component, - None, None)] + tcldata) - # See "FeatureComponents Table". - # The association between TclTk and pythonw.exe is necessary to make ICE59 - # happy, because the installer otherwise believes that the IDLE and PyDoc - # shortcuts might get installed without pythonw.exe being install. This - # is not true, since installing TclTk will install the default feature, which - # will cause pythonw.exe to be installed. - # REGISTRY.tcl is not associated with any feature, as it will be requested - # through a custom action - tcldata = [] - if have_tcl: - tcldata = [(tcltk.id, "pythonw.exe")] - add_data(db, "FeatureComponents", - [(default_feature.id, "REGISTRY"), - (htmlfiles.id, "REGISTRY.doc"), - (prepend_path.id, "REGISTRY.path"), - (ext_feature.id, "REGISTRY.def")] + - tcldata - ) - # Extensions are not advertised. For advertised extensions, - # we would need separate binaries that install along with the - # extension. - pat = r"Software\Classes\%sPython.%sFile\shell\%s\command" - ewi = "Edit with IDLE" - pat2 = r"Software\Classes\%sPython.%sFile\DefaultIcon" - pat3 = r"Software\Classes\%sPython.%sFile" - pat4 = r"Software\Classes\%sPython.%sFile\shellex\DropHandler" - tcl_verbs = [] - if have_tcl: - tcl_verbs=[ - ("py.IDLE", -1, pat % (testprefix, "", ewi), "", - r'"[TARGETDIR]pythonw.exe" "[TARGETDIR]Lib\idlelib\idle.pyw" -e "%1"', - "REGISTRY.tcl"), - ("pyw.IDLE", -1, pat % (testprefix, "NoCon", ewi), "", - r'"[TARGETDIR]pythonw.exe" "[TARGETDIR]Lib\idlelib\idle.pyw" -e "%1"', - "REGISTRY.tcl"), - ] - add_data(db, "Registry", - [# Extensions - ("py.ext", -1, r"Software\Classes\."+ext, "", - "Python.File", "REGISTRY.def"), - ("pyw.ext", -1, r"Software\Classes\."+ext+'w', "", - "Python.NoConFile", "REGISTRY.def"), - ("pyc.ext", -1, r"Software\Classes\."+ext+'c', "", - "Python.CompiledFile", "REGISTRY.def"), - ("pyo.ext", -1, r"Software\Classes\."+ext+'o', "", - "Python.CompiledFile", "REGISTRY.def"), - # MIME types - ("py.mime", -1, r"Software\Classes\."+ext, "Content Type", - "text/plain", "REGISTRY.def"), - ("pyw.mime", -1, r"Software\Classes\."+ext+'w', "Content Type", - "text/plain", "REGISTRY.def"), - #Verbs - ("py.open", -1, pat % (testprefix, "", "open"), "", - r'"[LAUNCHERDIR]py.exe" "%1" %*', "REGISTRY.def"), - ("pyw.open", -1, pat % (testprefix, "NoCon", "open"), "", - r'"[LAUNCHERDIR]pyw.exe" "%1" %*', "REGISTRY.def"), - ("pyc.open", -1, pat % (testprefix, "Compiled", "open"), "", - r'"[LAUNCHERDIR]py.exe" "%1" %*', "REGISTRY.def"), - ] + tcl_verbs + [ - #Icons - ("py.icon", -1, pat2 % (testprefix, ""), "", - r'[DLLs]py.ico', "REGISTRY.def"), - ("pyw.icon", -1, pat2 % (testprefix, "NoCon"), "", - r'[DLLs]py.ico', "REGISTRY.def"), - ("pyc.icon", -1, pat2 % (testprefix, "Compiled"), "", - r'[DLLs]pyc.ico', "REGISTRY.def"), - # Descriptions - ("py.txt", -1, pat3 % (testprefix, ""), "", - "Python File", "REGISTRY.def"), - ("pyw.txt", -1, pat3 % (testprefix, "NoCon"), "", - "Python File (no console)", "REGISTRY.def"), - ("pyc.txt", -1, pat3 % (testprefix, "Compiled"), "", - "Compiled Python File", "REGISTRY.def"), - # Drop Handler - ("py.drop", -1, pat4 % (testprefix, ""), "", - "{60254CA5-953B-11CF-8C96-00AA00B8708C}", "REGISTRY.def"), - ("pyw.drop", -1, pat4 % (testprefix, "NoCon"), "", - "{60254CA5-953B-11CF-8C96-00AA00B8708C}", "REGISTRY.def"), - ("pyc.drop", -1, pat4 % (testprefix, "Compiled"), "", - "{60254CA5-953B-11CF-8C96-00AA00B8708C}", "REGISTRY.def"), - ]) - - # PATHEXT - add_data(db, "Environment", - [("PathExtAddition", "=-*PathExt", "[~];.PY", "REGISTRY.def")]) - - # Registry keys - prefix = r"Software\%sPython\PythonCore\%s" % (testprefix, short_version) - add_data(db, "Registry", - [("InstallPath", -1, prefix+r"\InstallPath", "", "[TARGETDIR]", "REGISTRY"), - ("InstallGroup", -1, prefix+r"\InstallPath\InstallGroup", "", - "Python %s" % short_version, "REGISTRY"), - ("PythonPath", -1, prefix+r"\PythonPath", "", - r"[TARGETDIR]Lib;[TARGETDIR]DLLs", "REGISTRY"), - ("Documentation", -1, prefix+r"\Help\Main Python Documentation", "", - "[TARGETDIR]Doc\\"+docfile , "REGISTRY.doc"), - ("Modules", -1, prefix+r"\Modules", "+", None, "REGISTRY"), - ("AppPaths", -1, r"Software\Microsoft\Windows\CurrentVersion\App Paths\Python.exe", - "", r"[TARGETDIR]Python.exe", "REGISTRY.def"), - ("DisplayIcon", -1, - r"Software\Microsoft\Windows\CurrentVersion\Uninstall\%s" % product_code, - "DisplayIcon", "[TARGETDIR]python.exe", "REGISTRY") - ]) - # Shortcuts, see "Shortcut Table" - add_data(db, "Directory", - [("ProgramMenuFolder", "TARGETDIR", "."), - ("MenuDir", "ProgramMenuFolder", "PY%s%s|%sPython %s.%s" % (major,minor,testprefix,major,minor))]) - add_data(db, "RemoveFile", - [("MenuDir", "TARGETDIR", None, "MenuDir", 2)]) - tcltkshortcuts = [] - if have_tcl: - tcltkshortcuts = [ - ("IDLE", "MenuDir", "IDLE|IDLE (Python GUI)", "pythonw.exe", - tcltk.id, r'"[TARGETDIR]Lib\idlelib\idle.pyw"', None, None, "python_icon.exe", 0, None, "TARGETDIR"), - ("PyDoc", "MenuDir", "MODDOCS|Module Docs", "pythonw.exe", - tcltk.id, r'"[TARGETDIR]Tools\scripts\pydocgui.pyw"', None, None, "python_icon.exe", 0, None, "TARGETDIR"), - ] - add_data(db, "Shortcut", - tcltkshortcuts + - [# Advertised shortcuts: targets are features, not files - ("Python", "MenuDir", "PYTHON|Python (command line)", "python.exe", - default_feature.id, None, None, None, "python_icon.exe", 2, None, "TARGETDIR"), - # Advertising the Manual breaks on (some?) Win98, and the shortcut lacks an - # icon first. - #("Manual", "MenuDir", "MANUAL|Python Manuals", "documentation", - # htmlfiles.id, None, None, None, None, None, None, None), - ## Non-advertised shortcuts: must be associated with a registry component - ("Manual", "MenuDir", "MANUAL|Python Manuals", "REGISTRY.doc", - "[#%s]" % docfile, None, - None, None, None, None, None, None), - ("Uninstall", "MenuDir", "UNINST|Uninstall Python", "REGISTRY", - SystemFolderName+"msiexec", "/x%s" % product_code, - None, None, None, None, None, None), - ]) - db.Commit() - -def build_pdbzip(): - pdbexclude = ['kill_python.pdb', 'make_buildinfo.pdb', - 'make_versioninfo.pdb'] - path = "python-%s%s-pdb.zip" % (full_current_version, msilib.arch_ext) - pdbzip = zipfile.ZipFile(path, 'w') - for f in glob.glob1(os.path.join(srcdir, PCBUILD), "*.pdb"): - if f not in pdbexclude and not f.endswith('_d.pdb'): - pdbzip.write(os.path.join(srcdir, PCBUILD, f), f) - pdbzip.close() - -db,msiname = build_database() -try: - add_features(db) - add_ui(db) - add_files(db) - add_registry(db) - remove_old_versions(db) - db.Commit() -finally: - del db - -# Merge CRT into MSI file. This requires the database to be closed. -mod_dir = os.path.join(os.environ["ProgramFiles"], "Common Files", "Merge Modules") -if msilib.Win64: - modules = ["Microsoft_VC100_CRT_x64.msm"] -else: - modules = ["Microsoft_VC100_CRT_x86.msm"] - -for i, n in enumerate(modules): - modules[i] = os.path.join(mod_dir, n) - -def merge(msi, feature, rootdir, modules): - cab_and_filecount = [] - # Step 1: Merge databases, extract cabfiles - m = msilib.MakeMerge2() - m.OpenLog("merge.log") - m.OpenDatabase(msi) - for module in modules: - print module - m.OpenModule(module,0) - m.Merge(feature, rootdir) - print "Errors:" - for e in m.Errors: - print e.Type, e.ModuleTable, e.DatabaseTable - print " Modkeys:", - for s in e.ModuleKeys: print s, - print - print " DBKeys:", - for s in e.DatabaseKeys: print s, - print - cabname = tempfile.mktemp(suffix=".cab") - m.ExtractCAB(cabname) - cab_and_filecount.append((cabname, len(m.ModuleFiles))) - m.CloseModule() - m.CloseDatabase(True) - m.CloseLog() - - # Step 2: Add CAB files - i = msilib.MakeInstaller() - db = i.OpenDatabase(msi, constants.msiOpenDatabaseModeTransact) - - v = db.OpenView("SELECT LastSequence FROM Media") - v.Execute(None) - maxmedia = -1 - while 1: - r = v.Fetch() - if not r: break - seq = r.IntegerData(1) - if seq > maxmedia: - maxmedia = seq - print "Start of Media", maxmedia - - for cabname, count in cab_and_filecount: - stream = "merged%d" % maxmedia - msilib.add_data(db, "Media", - [(maxmedia+1, maxmedia+count, None, "#"+stream, None, None)]) - msilib.add_stream(db, stream, cabname) - os.unlink(cabname) - maxmedia += count - # The merge module sets ALLUSERS to 1 in the property table. - # This is undesired; delete that - v = db.OpenView("DELETE FROM Property WHERE Property='ALLUSERS'") - v.Execute(None) - v.Close() - db.Commit() - -merge(msiname, "SharedCRT", "TARGETDIR", modules) - -# certname (from config.py) should be (a substring of) -# the certificate subject, e.g. "Python Software Foundation" -if certname: - os.system('signtool sign /n "%s" ' - '/t http://timestamp.verisign.com/scripts/timestamp.dll ' - '/d "Python %s" ' - '%s' % (certname, full_current_version, msiname)) - -if pdbzip: - build_pdbzip() diff --git a/Tools/msi/msi.targets b/Tools/msi/msi.targets new file mode 100644 index 000000000000..2431dc2f2f96 --- /dev/null +++ b/Tools/msi/msi.targets @@ -0,0 +1,62 @@ + + + + + + <_FileListTarget>$(IntermediateOutputPath)$(MSBuildProjectName).g.csv + <_InstallFilesTarget>$(IntermediateOutputPath)$(MSBuildProjectName).g.wxs + + + + + <_Source>%(Source)$([msbuild]::MakeRelative(%(SourceBase), %(FullPath))) + <_Target>%(Target_)$([msbuild]::MakeRelative(%(TargetBase), %(FullPath))) + + + + + + + + + + + + + + + <_Content>$([System.IO.File]::ReadAllText(%(WxlTemplate.FullPath)).Replace(`{{ShortVersion}}`, `$(MajorVersionNumber).$(MinorVersionNumber)`).Replace(`{{LongVersion}}`, `$(PythonVersion)`).Replace(`{{Bitness}}`, `$(Bitness)`)) + <_ExistingContent Condition="Exists('$(IntermediateOutputPath)%(WxlTemplate.Filename).wxl')">$([System.IO.File]::ReadAllText($(IntermediateOutputPath)%(WxlTemplate.Filename).wxl)) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/msilib.py b/Tools/msi/msilib.py deleted file mode 100644 index c208b9107494..000000000000 --- a/Tools/msi/msilib.py +++ /dev/null @@ -1,679 +0,0 @@ -# Microsoft Installer Library -# (C) 2003 Martin v. Loewis - -import win32com.client.gencache -import win32com.client -import pythoncom, pywintypes -from win32com.client import constants -import re, string, os, sets, glob, subprocess, sys, _winreg, struct, _msi - -try: - basestring -except NameError: - basestring = (str, unicode) - -# Partially taken from Wine -datasizemask= 0x00ff -type_valid= 0x0100 -type_localizable= 0x0200 - -typemask= 0x0c00 -type_long= 0x0000 -type_short= 0x0400 -type_string= 0x0c00 -type_binary= 0x0800 - -type_nullable= 0x1000 -type_key= 0x2000 -# XXX temporary, localizable? -knownbits = datasizemask | type_valid | type_localizable | \ - typemask | type_nullable | type_key - -# Summary Info Property IDs -PID_CODEPAGE=1 -PID_TITLE=2 -PID_SUBJECT=3 -PID_AUTHOR=4 -PID_KEYWORDS=5 -PID_COMMENTS=6 -PID_TEMPLATE=7 -PID_LASTAUTHOR=8 -PID_REVNUMBER=9 -PID_LASTPRINTED=11 -PID_CREATE_DTM=12 -PID_LASTSAVE_DTM=13 -PID_PAGECOUNT=14 -PID_WORDCOUNT=15 -PID_CHARCOUNT=16 -PID_APPNAME=18 -PID_SECURITY=19 - -def reset(): - global _directories - _directories = sets.Set() - -def EnsureMSI(): - win32com.client.gencache.EnsureModule('{000C1092-0000-0000-C000-000000000046}', 1033, 1, 0) - -def EnsureMSM(): - try: - win32com.client.gencache.EnsureModule('{0ADDA82F-2C26-11D2-AD65-00A0C9AF11A6}', 0, 1, 0) - except pywintypes.com_error: - win32com.client.gencache.EnsureModule('{0ADDA82F-2C26-11D2-AD65-00A0C9AF11A6}', 0, 2, 0) - -_Installer=None -def MakeInstaller(): - global _Installer - if _Installer is None: - EnsureMSI() - _Installer = win32com.client.Dispatch('WindowsInstaller.Installer', - resultCLSID='{000C1090-0000-0000-C000-000000000046}') - return _Installer - -_Merge=None -def MakeMerge2(): - global _Merge - if _Merge is None: - EnsureMSM() - _Merge = win32com.client.Dispatch("Msm.Merge2.1") - return _Merge - -class Table: - def __init__(self, name): - self.name = name - self.fields = [] - - def add_field(self, index, name, type): - self.fields.append((index,name,type)) - - def sql(self): - fields = [] - keys = [] - self.fields.sort() - fields = [None]*len(self.fields) - for index, name, type in self.fields: - index -= 1 - unk = type & ~knownbits - if unk: - print "%s.%s unknown bits %x" % (self.name, name, unk) - size = type & datasizemask - dtype = type & typemask - if dtype == type_string: - if size: - tname="CHAR(%d)" % size - else: - tname="CHAR" - elif dtype == type_short: - assert size==2 - tname = "SHORT" - elif dtype == type_long: - assert size==4 - tname="LONG" - elif dtype == type_binary: - assert size==0 - tname="OBJECT" - else: - tname="unknown" - print "%s.%sunknown integer type %d" % (self.name, name, size) - if type & type_nullable: - flags = "" - else: - flags = " NOT NULL" - if type & type_localizable: - flags += " LOCALIZABLE" - fields[index] = "`%s` %s%s" % (name, tname, flags) - if type & type_key: - keys.append("`%s`" % name) - fields = ", ".join(fields) - keys = ", ".join(keys) - return "CREATE TABLE %s (%s PRIMARY KEY %s)" % (self.name, fields, keys) - - def create(self, db): - v = db.OpenView(self.sql()) - v.Execute(None) - v.Close() - -class Binary: - def __init__(self, fname): - self.name = fname - def __repr__(self): - return 'msilib.Binary(os.path.join(dirname,"%s"))' % self.name - -def gen_schema(destpath, schemapath): - d = MakeInstaller() - schema = d.OpenDatabase(schemapath, - win32com.client.constants.msiOpenDatabaseModeReadOnly) - - # XXX ORBER BY - v=schema.OpenView("SELECT * FROM _Columns") - curtable=None - tables = [] - v.Execute(None) - f = open(destpath, "wt") - f.write("from msilib import Table\n") - while 1: - r=v.Fetch() - if not r:break - name=r.StringData(1) - if curtable != name: - f.write("\n%s = Table('%s')\n" % (name,name)) - curtable = name - tables.append(name) - f.write("%s.add_field(%d,'%s',%d)\n" % - (name, r.IntegerData(2), r.StringData(3), r.IntegerData(4))) - v.Close() - - f.write("\ntables=[%s]\n\n" % (", ".join(tables))) - - # Fill the _Validation table - f.write("_Validation_records = [\n") - v = schema.OpenView("SELECT * FROM _Validation") - v.Execute(None) - while 1: - r = v.Fetch() - if not r:break - # Table, Column, Nullable - f.write("(%s,%s,%s," % - (`r.StringData(1)`, `r.StringData(2)`, `r.StringData(3)`)) - def put_int(i): - if r.IsNull(i):f.write("None, ") - else:f.write("%d," % r.IntegerData(i)) - def put_str(i): - if r.IsNull(i):f.write("None, ") - else:f.write("%s," % `r.StringData(i)`) - put_int(4) # MinValue - put_int(5) # MaxValue - put_str(6) # KeyTable - put_int(7) # KeyColumn - put_str(8) # Category - put_str(9) # Set - put_str(10)# Description - f.write("),\n") - f.write("]\n\n") - - f.close() - -def gen_sequence(destpath, msipath): - dir = os.path.dirname(destpath) - d = MakeInstaller() - seqmsi = d.OpenDatabase(msipath, - win32com.client.constants.msiOpenDatabaseModeReadOnly) - - v = seqmsi.OpenView("SELECT * FROM _Tables"); - v.Execute(None) - f = open(destpath, "w") - print >>f, "import msilib,os;dirname=os.path.dirname(__file__)" - tables = [] - while 1: - r = v.Fetch() - if not r:break - table = r.StringData(1) - tables.append(table) - f.write("%s = [\n" % table) - v1 = seqmsi.OpenView("SELECT * FROM `%s`" % table) - v1.Execute(None) - info = v1.ColumnInfo(constants.msiColumnInfoTypes) - while 1: - r = v1.Fetch() - if not r:break - rec = [] - for i in range(1,r.FieldCount+1): - if r.IsNull(i): - rec.append(None) - elif info.StringData(i)[0] in "iI": - rec.append(r.IntegerData(i)) - elif info.StringData(i)[0] in "slSL": - rec.append(r.StringData(i)) - elif info.StringData(i)[0]=="v": - size = r.DataSize(i) - bytes = r.ReadStream(i, size, constants.msiReadStreamBytes) - bytes = bytes.encode("latin-1") # binary data represented "as-is" - if table == "Binary": - fname = rec[0]+".bin" - open(os.path.join(dir,fname),"wb").write(bytes) - rec.append(Binary(fname)) - else: - rec.append(bytes) - else: - raise "Unsupported column type", info.StringData(i) - f.write(repr(tuple(rec))+",\n") - v1.Close() - f.write("]\n\n") - v.Close() - f.write("tables=%s\n" % repr(map(str,tables))) - f.close() - -class _Unspecified:pass -def change_sequence(seq, action, seqno=_Unspecified, cond = _Unspecified): - "Change the sequence number of an action in a sequence list" - for i in range(len(seq)): - if seq[i][0] == action: - if cond is _Unspecified: - cond = seq[i][1] - if seqno is _Unspecified: - seqno = seq[i][2] - seq[i] = (action, cond, seqno) - return - raise ValueError, "Action not found in sequence" - -def add_data(db, table, values): - d = MakeInstaller() - v = db.OpenView("SELECT * FROM `%s`" % table) - count = v.ColumnInfo(0).FieldCount - r = d.CreateRecord(count) - for value in values: - assert len(value) == count, value - for i in range(count): - field = value[i] - if isinstance(field, (int, long)): - r.SetIntegerData(i+1,field) - elif isinstance(field, basestring): - r.SetStringData(i+1,field) - elif field is None: - pass - elif isinstance(field, Binary): - r.SetStream(i+1, field.name) - else: - raise TypeError, "Unsupported type %s" % field.__class__.__name__ - v.Modify(win32com.client.constants.msiViewModifyInsert, r) - r.ClearData() - v.Close() - -def add_stream(db, name, path): - d = MakeInstaller() - v = db.OpenView("INSERT INTO _Streams (Name, Data) VALUES ('%s', ?)" % name) - r = d.CreateRecord(1) - r.SetStream(1, path) - v.Execute(r) - v.Close() - -def init_database(name, schema, - ProductName, ProductCode, ProductVersion, - Manufacturer, - request_uac = False): - try: - os.unlink(name) - except OSError: - pass - ProductCode = ProductCode.upper() - d = MakeInstaller() - # Create the database - db = d.OpenDatabase(name, - win32com.client.constants.msiOpenDatabaseModeCreate) - # Create the tables - for t in schema.tables: - t.create(db) - # Fill the validation table - add_data(db, "_Validation", schema._Validation_records) - # Initialize the summary information, allowing at most 20 properties - si = db.GetSummaryInformation(20) - si.SetProperty(PID_TITLE, "Installation Database") - si.SetProperty(PID_SUBJECT, ProductName) - si.SetProperty(PID_AUTHOR, Manufacturer) - si.SetProperty(PID_TEMPLATE, msi_type) - si.SetProperty(PID_REVNUMBER, gen_uuid()) - if request_uac: - wc = 2 # long file names, compressed, original media - else: - wc = 2 | 8 # +never invoke UAC - si.SetProperty(PID_WORDCOUNT, wc) - si.SetProperty(PID_PAGECOUNT, 200) - si.SetProperty(PID_APPNAME, "Python MSI Library") - # XXX more properties - si.Persist() - add_data(db, "Property", [ - ("ProductName", ProductName), - ("ProductCode", ProductCode), - ("ProductVersion", ProductVersion), - ("Manufacturer", Manufacturer), - ("ProductLanguage", "1033")]) - db.Commit() - return db - -def add_tables(db, module): - for table in module.tables: - add_data(db, table, getattr(module, table)) - -def make_id(str): - #str = str.replace(".", "_") # colons are allowed - str = str.replace(" ", "_") - str = str.replace("-", "_") - str = str.replace("+", "_") - if str[0] in string.digits: - str = "_"+str - assert re.match("^[A-Za-z_][A-Za-z0-9_.]*$", str), "FILE"+str - return str - -def gen_uuid(): - return str(pythoncom.CreateGuid()) - -class CAB: - def __init__(self, name): - self.name = name - self.files = [] - self.filenames = sets.Set() - self.index = 0 - - def gen_id(self, dir, file): - logical = _logical = make_id(file) - pos = 1 - while logical in self.filenames: - logical = "%s.%d" % (_logical, pos) - pos += 1 - self.filenames.add(logical) - return logical - - def append(self, full, file, logical = None): - if os.path.isdir(full): - return - if not logical: - logical = self.gen_id(dir, file) - self.index += 1 - self.files.append((full, logical)) - return self.index, logical - - def commit(self, db): - try: - os.unlink(self.name+".cab") - except OSError: - pass - _msi.FCICreate(self.name+".cab", self.files) - add_data(db, "Media", - [(1, self.index, None, "#"+self.name, None, None)]) - add_stream(db, self.name, self.name+".cab") - os.unlink(self.name+".cab") - db.Commit() - -_directories = sets.Set() -class Directory: - def __init__(self, db, cab, basedir, physical, _logical, default, componentflags=None): - """Create a new directory in the Directory table. There is a current component - at each point in time for the directory, which is either explicitly created - through start_component, or implicitly when files are added for the first - time. Files are added into the current component, and into the cab file. - To create a directory, a base directory object needs to be specified (can be - None), the path to the physical directory, and a logical directory name. - Default specifies the DefaultDir slot in the directory table. componentflags - specifies the default flags that new components get.""" - index = 1 - _logical = make_id(_logical) - logical = _logical - while logical in _directories: - logical = "%s%d" % (_logical, index) - index += 1 - _directories.add(logical) - self.db = db - self.cab = cab - self.basedir = basedir - self.physical = physical - self.logical = logical - self.component = None - self.short_names = {} - self.ids = sets.Set() - self.keyfiles = {} - self.componentflags = componentflags - if basedir: - self.absolute = os.path.join(basedir.absolute, physical) - blogical = basedir.logical - else: - self.absolute = physical - blogical = None - # initially assume that all files in this directory are unpackaged - # as files from self.absolute get added, this set is reduced - self.unpackaged_files = set() - for f in os.listdir(self.absolute): - if os.path.isfile(os.path.join(self.absolute, f)): - self.unpackaged_files.add(f) - add_data(db, "Directory", [(logical, blogical, default)]) - - def start_component(self, component = None, feature = None, flags = None, keyfile = None, uuid=None): - """Add an entry to the Component table, and make this component the current for this - directory. If no component name is given, the directory name is used. If no feature - is given, the current feature is used. If no flags are given, the directory's default - flags are used. If no keyfile is given, the KeyPath is left null in the Component - table.""" - if flags is None: - flags = self.componentflags - if uuid is None: - uuid = gen_uuid() - else: - uuid = uuid.upper() - if component is None: - component = self.logical - self.component = component - if Win64: - flags |= 256 - if keyfile: - keyid = self.cab.gen_id(self.absolute, keyfile) - self.keyfiles[keyfile] = keyid - else: - keyid = None - add_data(self.db, "Component", - [(component, uuid, self.logical, flags, None, keyid)]) - if feature is None: - feature = current_feature - add_data(self.db, "FeatureComponents", - [(feature.id, component)]) - - def make_short(self, file): - long = file - file = re.sub(r'[\?|><:/*"+,;=\[\]]', '_', file) # restrictions on short names - parts = file.split(".", 1) - if len(parts)>1: - suffix = parts[1].upper() - else: - suffix = '' - prefix = parts[0].upper() - if len(prefix) <= 8 and '.' not in suffix and len(suffix) <= 3: - if suffix: - file = prefix+"."+suffix - else: - file = prefix - assert file not in self.short_names, (file, self.short_names[file]) - else: - prefix = prefix[:6] - if suffix: - # last three characters of last suffix - suffix = suffix.rsplit('.')[-1][:3] - pos = 1 - while 1: - if suffix: - file = "%s~%d.%s" % (prefix, pos, suffix) - else: - file = "%s~%d" % (prefix, pos) - if file not in self.short_names: break - pos += 1 - assert pos < 10000 - if pos in (10, 100, 1000): - prefix = prefix[:-1] - self.short_names[file] = long - return file - - def add_file(self, file, src=None, version=None, language=None): - """Add a file to the current component of the directory, starting a new one - if there is no current component. By default, the file name in the source - and the file table will be identical. If the src file is specified, it is - interpreted relative to the current directory. Optionally, a version and a - language can be specified for the entry in the File table.""" - if not self.component: - self.start_component(self.logical, current_feature) - if not src: - # Allow relative paths for file if src is not specified - src = file - file = os.path.basename(file) - absolute = os.path.join(self.absolute, src) - if absolute.startswith(self.absolute): - # mark file as packaged - relative = absolute[len(self.absolute)+1:] - if relative in self.unpackaged_files: - self.unpackaged_files.remove(relative) - assert not re.search(r'[\?|><:/*]"', file) # restrictions on long names - if self.keyfiles.has_key(file): - logical = self.keyfiles[file] - else: - logical = None - sequence, logical = self.cab.append(absolute, file, logical) - assert logical not in self.ids - self.ids.add(logical) - short = self.make_short(file) - full = "%s|%s" % (short, file) - filesize = os.stat(absolute).st_size - # constants.msidbFileAttributesVital - # Compressed omitted, since it is the database default - # could add r/o, system, hidden - attributes = 512 - add_data(self.db, "File", - [(logical, self.component, full, filesize, version, - language, attributes, sequence)]) - if not version: - # Add hash if the file is not versioned - filehash = MakeInstaller().FileHash(absolute, 0) - add_data(self.db, "MsiFileHash", - [(logical, 0, filehash.IntegerData(1), - filehash.IntegerData(2), filehash.IntegerData(3), - filehash.IntegerData(4))]) - # Automatically remove .pyc/.pyo files on uninstall (2) - # XXX: adding so many RemoveFile entries makes installer unbelievably - # slow. So instead, we have to use wildcard remove entries - # if file.endswith(".py"): - # add_data(self.db, "RemoveFile", - # [(logical+"c", self.component, "%sC|%sc" % (short, file), - # self.logical, 2), - # (logical+"o", self.component, "%sO|%so" % (short, file), - # self.logical, 2)]) - - def glob(self, pattern, exclude = None): - """Add a list of files to the current component as specified in the - glob pattern. Individual files can be excluded in the exclude list.""" - files = glob.glob1(self.absolute, pattern) - for f in files: - if exclude and f in exclude: continue - self.add_file(f) - return files - - def remove_pyc(self): - "Remove .pyc/.pyo files from __pycache__ on uninstall" - directory = self.logical + "_pycache" - add_data(self.db, "Directory", [(directory, self.logical, "__PYCA~1|__pycache__")]) - flags = 256 if Win64 else 0 - add_data(self.db, "Component", - [(directory, gen_uuid(), directory, flags, None, None)]) - add_data(self.db, "FeatureComponents", [(current_feature.id, directory)]) - add_data(self.db, "CreateFolder", [(directory, directory)]) - add_data(self.db, "RemoveFile", - [(self.component, self.component, "*.*", directory, 2), - ]) - - def removefile(self, key, pattern): - "Add a RemoveFile entry" - add_data(self.db, "RemoveFile", [(self.component+key, self.component, pattern, self.logical, 2)]) - - -class Feature: - def __init__(self, db, id, title, desc, display, level = 1, - parent=None, directory = None, attributes=0): - self.id = id - if parent: - parent = parent.id - add_data(db, "Feature", - [(id, parent, title, desc, display, - level, directory, attributes)]) - def set_current(self): - global current_feature - current_feature = self - -class Control: - def __init__(self, dlg, name): - self.dlg = dlg - self.name = name - - def event(self, ev, arg, cond = "1", order = None): - add_data(self.dlg.db, "ControlEvent", - [(self.dlg.name, self.name, ev, arg, cond, order)]) - - def mapping(self, ev, attr): - add_data(self.dlg.db, "EventMapping", - [(self.dlg.name, self.name, ev, attr)]) - - def condition(self, action, condition): - add_data(self.dlg.db, "ControlCondition", - [(self.dlg.name, self.name, action, condition)]) - -class RadioButtonGroup(Control): - def __init__(self, dlg, name, property): - self.dlg = dlg - self.name = name - self.property = property - self.index = 1 - - def add(self, name, x, y, w, h, text, value = None): - if value is None: - value = name - add_data(self.dlg.db, "RadioButton", - [(self.property, self.index, value, - x, y, w, h, text, None)]) - self.index += 1 - -class Dialog: - def __init__(self, db, name, x, y, w, h, attr, title, first, default, cancel): - self.db = db - self.name = name - self.x, self.y, self.w, self.h = x,y,w,h - add_data(db, "Dialog", [(name, x,y,w,h,attr,title,first,default,cancel)]) - - def control(self, name, type, x, y, w, h, attr, prop, text, next, help): - add_data(self.db, "Control", - [(self.name, name, type, x, y, w, h, attr, prop, text, next, help)]) - return Control(self, name) - - def text(self, name, x, y, w, h, attr, text): - return self.control(name, "Text", x, y, w, h, attr, None, - text, None, None) - - def bitmap(self, name, x, y, w, h, text): - return self.control(name, "Bitmap", x, y, w, h, 1, None, text, None, None) - - def line(self, name, x, y, w, h): - return self.control(name, "Line", x, y, w, h, 1, None, None, None, None) - - def pushbutton(self, name, x, y, w, h, attr, text, next): - return self.control(name, "PushButton", x, y, w, h, attr, None, text, next, None) - - def radiogroup(self, name, x, y, w, h, attr, prop, text, next): - add_data(self.db, "Control", - [(self.name, name, "RadioButtonGroup", - x, y, w, h, attr, prop, text, next, None)]) - return RadioButtonGroup(self, name, prop) - - def checkbox(self, name, x, y, w, h, attr, prop, text, next): - return self.control(name, "CheckBox", x, y, w, h, attr, prop, text, next, None) - -def pe_type(path): - header = open(path, "rb").read(1000) - # offset of PE header is at offset 0x3c - pe_offset = struct.unpack(" + + + {91C99298-8E2E-4422-A5AF-CC4FFF9A58D3} + 2.0 + path + Package + ICE71 + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/path/path.wxs b/Tools/msi/path/path.wxs new file mode 100644 index 000000000000..8b37936cc938 --- /dev/null +++ b/Tools/msi/path/path.wxs @@ -0,0 +1,39 @@ + + + + + + + + + + + NOT ALLUSERS=1 + + + + + + + + + + + + ALLUSERS=1 + + + + + + + + + + + + + + + + diff --git a/Tools/msi/path/path_en-US.wxl b/Tools/msi/path/path_en-US.wxl new file mode 100644 index 000000000000..33a7886fe2d6 --- /dev/null +++ b/Tools/msi/path/path_en-US.wxl @@ -0,0 +1,6 @@ + + + Add to Path + Path + No !(loc.ProductName) installation was detected. + diff --git a/Tools/msi/pip/pip.wixproj b/Tools/msi/pip/pip.wixproj new file mode 100644 index 000000000000..718c02c032b7 --- /dev/null +++ b/Tools/msi/pip/pip.wixproj @@ -0,0 +1,19 @@ + + + + {91C99298-8E2E-4422-A5AF-CC4FFF9A58D3} + 2.0 + pip + Package + ICE71 + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/pip/pip.wxs b/Tools/msi/pip/pip.wxs new file mode 100644 index 000000000000..19e9f5fd2088 --- /dev/null +++ b/Tools/msi/pip/pip.wxs @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + PYTHON_EXE + + + + + + + + + + + + + + + + + (&DefaultFeature=3) AND NOT (!DefaultFeature=3) + (&DefaultFeature=2) AND (!DefaultFeature=3) + + UpdatePip + + + + diff --git a/Tools/msi/pip/pip_en-US.wxl b/Tools/msi/pip/pip_en-US.wxl new file mode 100644 index 000000000000..cd0d9edf3a6b --- /dev/null +++ b/Tools/msi/pip/pip_en-US.wxl @@ -0,0 +1,6 @@ + + + pip Bootstrap + pip + No !(loc.ProductName) installation was detected. + diff --git a/Tools/msi/schema.py b/Tools/msi/schema.py deleted file mode 100644 index 1f72e5ac78b7..000000000000 --- a/Tools/msi/schema.py +++ /dev/null @@ -1,1007 +0,0 @@ -from msilib import Table - -_Validation = Table('_Validation') -_Validation.add_field(1,'Table',11552) -_Validation.add_field(2,'Column',11552) -_Validation.add_field(3,'Nullable',3332) -_Validation.add_field(4,'MinValue',4356) -_Validation.add_field(5,'MaxValue',4356) -_Validation.add_field(6,'KeyTable',7679) -_Validation.add_field(7,'KeyColumn',5378) -_Validation.add_field(8,'Category',7456) -_Validation.add_field(9,'Set',7679) -_Validation.add_field(10,'Description',7679) - -ActionText = Table('ActionText') -ActionText.add_field(1,'Action',11592) -ActionText.add_field(2,'Description',7936) -ActionText.add_field(3,'Template',7936) - -AdminExecuteSequence = Table('AdminExecuteSequence') -AdminExecuteSequence.add_field(1,'Action',0x2DFF) -AdminExecuteSequence.add_field(2,'Condition',7679) -AdminExecuteSequence.add_field(3,'Sequence',5378) - -Condition = Table('Condition') -Condition.add_field(1,'Feature_',11558) -Condition.add_field(2,'Level',9474) -Condition.add_field(3,'Condition',7679) - -AdminUISequence = Table('AdminUISequence') -AdminUISequence.add_field(1,'Action',0x2DFF) -AdminUISequence.add_field(2,'Condition',7679) -AdminUISequence.add_field(3,'Sequence',5378) - -AdvtExecuteSequence = Table('AdvtExecuteSequence') -AdvtExecuteSequence.add_field(1,'Action',0x2DFF) -AdvtExecuteSequence.add_field(2,'Condition',7679) -AdvtExecuteSequence.add_field(3,'Sequence',5378) - -AdvtUISequence = Table('AdvtUISequence') -AdvtUISequence.add_field(1,'Action',11592) -AdvtUISequence.add_field(2,'Condition',7679) -AdvtUISequence.add_field(3,'Sequence',5378) - -AppId = Table('AppId') -AppId.add_field(1,'AppId',11558) -AppId.add_field(2,'RemoteServerName',7679) -AppId.add_field(3,'LocalService',7679) -AppId.add_field(4,'ServiceParameters',7679) -AppId.add_field(5,'DllSurrogate',7679) -AppId.add_field(6,'ActivateAtStorage',5378) -AppId.add_field(7,'RunAsInteractiveUser',5378) - -AppSearch = Table('AppSearch') -AppSearch.add_field(1,'Property',11592) -AppSearch.add_field(2,'Signature_',11592) - -Property = Table('Property') -Property.add_field(1,'Property',11592) -Property.add_field(2,'Value',3840) - -BBControl = Table('BBControl') -BBControl.add_field(1,'Billboard_',11570) -BBControl.add_field(2,'BBControl',11570) -BBControl.add_field(3,'Type',3378) -BBControl.add_field(4,'X',1282) -BBControl.add_field(5,'Y',1282) -BBControl.add_field(6,'Width',1282) -BBControl.add_field(7,'Height',1282) -BBControl.add_field(8,'Attributes',4356) -BBControl.add_field(9,'Text',7986) - -Billboard = Table('Billboard') -Billboard.add_field(1,'Billboard',11570) -Billboard.add_field(2,'Feature_',3366) -Billboard.add_field(3,'Action',7474) -Billboard.add_field(4,'Ordering',5378) - -Feature = Table('Feature') -Feature.add_field(1,'Feature',11558) -Feature.add_field(2,'Feature_Parent',7462) -Feature.add_field(3,'Title',8000) -Feature.add_field(4,'Description',8191) -Feature.add_field(5,'Display',5378) -Feature.add_field(6,'Level',1282) -Feature.add_field(7,'Directory_',0x1DFF) -Feature.add_field(8,'Attributes',1282) - -Binary = Table('Binary') -Binary.add_field(1,'Name',11592) -Binary.add_field(2,'Data',2304) - -BindImage = Table('BindImage') -BindImage.add_field(1,'File_',0x2DFF) -BindImage.add_field(2,'Path',7679) - -File = Table('File') -File.add_field(1,'File',0x2DFF) -File.add_field(2,'Component_',0xDFF) -File.add_field(3,'FileName',4095) -File.add_field(4,'FileSize',260) -File.add_field(5,'Version',0x1DFF) -File.add_field(6,'Language',7444) -File.add_field(7,'Attributes',5378) -File.add_field(8,'Sequence',1282) - -CCPSearch = Table('CCPSearch') -CCPSearch.add_field(1,'Signature_',11592) - -CheckBox = Table('CheckBox') -CheckBox.add_field(1,'Property',11592) -CheckBox.add_field(2,'Value',7488) - -Class = Table('Class') -Class.add_field(1,'CLSID',11558) -Class.add_field(2,'Context',11552) -Class.add_field(3,'Component_',0x2DFF) -Class.add_field(4,'ProgId_Default',7679) -Class.add_field(5,'Description',8191) -Class.add_field(6,'AppId_',7462) -Class.add_field(7,'FileTypeMask',7679) -Class.add_field(8,'Icon_',7496) -Class.add_field(9,'IconIndex',5378) -Class.add_field(10,'DefInprocHandler',7456) -Class.add_field(11,'Argument',7679) -Class.add_field(12,'Feature_',3366) -Class.add_field(13,'Attributes',5378) - -Component = Table('Component') -Component.add_field(1,'Component',0x2DFF) -Component.add_field(2,'ComponentId',7462) -Component.add_field(3,'Directory_',0xDFF) -Component.add_field(4,'Attributes',1282) -Component.add_field(5,'Condition',7679) -Component.add_field(6,'KeyPath',0x1DFF) - -Icon = Table('Icon') -Icon.add_field(1,'Name',11592) -Icon.add_field(2,'Data',2304) - -ProgId = Table('ProgId') -ProgId.add_field(1,'ProgId',11775) -ProgId.add_field(2,'ProgId_Parent',7679) -ProgId.add_field(3,'Class_',7462) -ProgId.add_field(4,'Description',8191) -ProgId.add_field(5,'Icon_',7496) -ProgId.add_field(6,'IconIndex',5378) - -ComboBox = Table('ComboBox') -ComboBox.add_field(1,'Property',11592) -ComboBox.add_field(2,'Order',9474) -ComboBox.add_field(3,'Value',3392) -ComboBox.add_field(4,'Text',8000) - -CompLocator = Table('CompLocator') -CompLocator.add_field(1,'Signature_',11592) -CompLocator.add_field(2,'ComponentId',3366) -CompLocator.add_field(3,'Type',5378) - -Complus = Table('Complus') -Complus.add_field(1,'Component_',0x2DFF) -Complus.add_field(2,'ExpType',13570) - -Directory = Table('Directory') -Directory.add_field(1,'Directory',0x2DFF) -Directory.add_field(2,'Directory_Parent',0x1DFF) -Directory.add_field(3,'DefaultDir',4095) - -Control = Table('Control') -Control.add_field(1,'Dialog_',11592) -Control.add_field(2,'Control',11570) -Control.add_field(3,'Type',3348) -Control.add_field(4,'X',1282) -Control.add_field(5,'Y',1282) -Control.add_field(6,'Width',1282) -Control.add_field(7,'Height',1282) -Control.add_field(8,'Attributes',4356) -Control.add_field(9,'Property',7474) -Control.add_field(10,'Text',7936) -Control.add_field(11,'Control_Next',7474) -Control.add_field(12,'Help',7986) - -Dialog = Table('Dialog') -Dialog.add_field(1,'Dialog',11592) -Dialog.add_field(2,'HCentering',1282) -Dialog.add_field(3,'VCentering',1282) -Dialog.add_field(4,'Width',1282) -Dialog.add_field(5,'Height',1282) -Dialog.add_field(6,'Attributes',4356) -Dialog.add_field(7,'Title',8064) -Dialog.add_field(8,'Control_First',3378) -Dialog.add_field(9,'Control_Default',7474) -Dialog.add_field(10,'Control_Cancel',7474) - -ControlCondition = Table('ControlCondition') -ControlCondition.add_field(1,'Dialog_',11592) -ControlCondition.add_field(2,'Control_',11570) -ControlCondition.add_field(3,'Action',11570) -ControlCondition.add_field(4,'Condition',11775) - -ControlEvent = Table('ControlEvent') -ControlEvent.add_field(1,'Dialog_',11592) -ControlEvent.add_field(2,'Control_',11570) -ControlEvent.add_field(3,'Event',11570) -ControlEvent.add_field(4,'Argument',11775) -ControlEvent.add_field(5,'Condition',15871) -ControlEvent.add_field(6,'Ordering',5378) - -CreateFolder = Table('CreateFolder') -CreateFolder.add_field(1,'Directory_',0x2DFF) -CreateFolder.add_field(2,'Component_',0x2DFF) - -CustomAction = Table('CustomAction') -CustomAction.add_field(1,'Action',0x2DFF) -CustomAction.add_field(2,'Type',1282) -CustomAction.add_field(3,'Source',0x1DFF) -CustomAction.add_field(4,'Target',7679) - -DrLocator = Table('DrLocator') -DrLocator.add_field(1,'Signature_',11592) -DrLocator.add_field(2,'Parent',15688) -DrLocator.add_field(3,'Path',15871) -DrLocator.add_field(4,'Depth',5378) - -DuplicateFile = Table('DuplicateFile') -DuplicateFile.add_field(1,'FileKey',11592) -DuplicateFile.add_field(2,'Component_',0xDFF) -DuplicateFile.add_field(3,'File_',0xDFF) -DuplicateFile.add_field(4,'DestName',8191) -DuplicateFile.add_field(5,'DestFolder',7496) - -Environment = Table('Environment') -Environment.add_field(1,'Environment',11592) -Environment.add_field(2,'Name',4095) -Environment.add_field(3,'Value',8191) -Environment.add_field(4,'Component_',0xDFF) - -Error = Table('Error') -Error.add_field(1,'Error',9474) -Error.add_field(2,'Message',7936) - -EventMapping = Table('EventMapping') -EventMapping.add_field(1,'Dialog_',11592) -EventMapping.add_field(2,'Control_',11570) -EventMapping.add_field(3,'Event',11570) -EventMapping.add_field(4,'Attribute',3378) - -Extension = Table('Extension') -Extension.add_field(1,'Extension',11775) -Extension.add_field(2,'Component_',0x2DFF) -Extension.add_field(3,'ProgId_',7679) -Extension.add_field(4,'MIME_',7488) -Extension.add_field(5,'Feature_',3366) - -MIME = Table('MIME') -MIME.add_field(1,'ContentType',11584) -MIME.add_field(2,'Extension_',3583) -MIME.add_field(3,'CLSID',7462) - -FeatureComponents = Table('FeatureComponents') -FeatureComponents.add_field(1,'Feature_',11558) -FeatureComponents.add_field(2,'Component_',0x2DFF) - -FileSFPCatalog = Table('FileSFPCatalog') -FileSFPCatalog.add_field(1,'File_',0x2DFF) -FileSFPCatalog.add_field(2,'SFPCatalog_',11775) - -SFPCatalog = Table('SFPCatalog') -SFPCatalog.add_field(1,'SFPCatalog',11775) -SFPCatalog.add_field(2,'Catalog',2304) -SFPCatalog.add_field(3,'Dependency',7424) - -Font = Table('Font') -Font.add_field(1,'File_',0x2DFF) -Font.add_field(2,'FontTitle',7552) - -IniFile = Table('IniFile') -IniFile.add_field(1,'IniFile',11592) -IniFile.add_field(2,'FileName',4095) -IniFile.add_field(3,'DirProperty',7496) -IniFile.add_field(4,'Section',3936) -IniFile.add_field(5,'Key',3968) -IniFile.add_field(6,'Value',4095) -IniFile.add_field(7,'Action',1282) -IniFile.add_field(8,'Component_',0xDFF) - -IniLocator = Table('IniLocator') -IniLocator.add_field(1,'Signature_',11592) -IniLocator.add_field(2,'FileName',3583) -IniLocator.add_field(3,'Section',3424) -IniLocator.add_field(4,'Key',3456) -IniLocator.add_field(5,'Field',5378) -IniLocator.add_field(6,'Type',5378) - -InstallExecuteSequence = Table('InstallExecuteSequence') -InstallExecuteSequence.add_field(1,'Action',0x2DFF) -InstallExecuteSequence.add_field(2,'Condition',7679) -InstallExecuteSequence.add_field(3,'Sequence',5378) - -InstallUISequence = Table('InstallUISequence') -InstallUISequence.add_field(1,'Action',0x2DFF) -InstallUISequence.add_field(2,'Condition',7679) -InstallUISequence.add_field(3,'Sequence',5378) - -IsolatedComponent = Table('IsolatedComponent') -IsolatedComponent.add_field(1,'Component_Shared',0x2DFF) -IsolatedComponent.add_field(2,'Component_Application',0x2DFF) - -LaunchCondition = Table('LaunchCondition') -LaunchCondition.add_field(1,'Condition',11775) -LaunchCondition.add_field(2,'Description',4095) - -ListBox = Table('ListBox') -ListBox.add_field(1,'Property',11592) -ListBox.add_field(2,'Order',9474) -ListBox.add_field(3,'Value',3392) -ListBox.add_field(4,'Text',8000) - -ListView = Table('ListView') -ListView.add_field(1,'Property',11592) -ListView.add_field(2,'Order',9474) -ListView.add_field(3,'Value',3392) -ListView.add_field(4,'Text',8000) -ListView.add_field(5,'Binary_',7496) - -LockPermissions = Table('LockPermissions') -LockPermissions.add_field(1,'LockObject',11592) -LockPermissions.add_field(2,'Table',11552) -LockPermissions.add_field(3,'Domain',15871) -LockPermissions.add_field(4,'User',11775) -LockPermissions.add_field(5,'Permission',4356) - -Media = Table('Media') -Media.add_field(1,'DiskId',9474) -Media.add_field(2,'LastSequence',1282) -Media.add_field(3,'DiskPrompt',8000) -Media.add_field(4,'Cabinet',7679) -Media.add_field(5,'VolumeLabel',7456) -Media.add_field(6,'Source',7496) - -MoveFile = Table('MoveFile') -MoveFile.add_field(1,'FileKey',11592) -MoveFile.add_field(2,'Component_',0xDFF) -MoveFile.add_field(3,'SourceName',8191) -MoveFile.add_field(4,'DestName',8191) -MoveFile.add_field(5,'SourceFolder',7496) -MoveFile.add_field(6,'DestFolder',3400) -MoveFile.add_field(7,'Options',1282) - -MsiAssembly = Table('MsiAssembly') -MsiAssembly.add_field(1,'Component_',0x2DFF) -MsiAssembly.add_field(2,'Feature_',3366) -MsiAssembly.add_field(3,'File_Manifest',0x1DFF) -MsiAssembly.add_field(4,'File_Application',0x1DFF) -MsiAssembly.add_field(5,'Attributes',5378) - -MsiAssemblyName = Table('MsiAssemblyName') -MsiAssemblyName.add_field(1,'Component_',0x2DFF) -MsiAssemblyName.add_field(2,'Name',11775) -MsiAssemblyName.add_field(3,'Value',3583) - -MsiDigitalCertificate = Table('MsiDigitalCertificate') -MsiDigitalCertificate.add_field(1,'DigitalCertificate',11592) -MsiDigitalCertificate.add_field(2,'CertData',2304) - -MsiDigitalSignature = Table('MsiDigitalSignature') -MsiDigitalSignature.add_field(1,'Table',11552) -MsiDigitalSignature.add_field(2,'SignObject',11592) -MsiDigitalSignature.add_field(3,'DigitalCertificate_',3400) -MsiDigitalSignature.add_field(4,'Hash',6400) - -MsiFileHash = Table('MsiFileHash') -MsiFileHash.add_field(1,'File_',0x2DFF) -MsiFileHash.add_field(2,'Options',1282) -MsiFileHash.add_field(3,'HashPart1',260) -MsiFileHash.add_field(4,'HashPart2',260) -MsiFileHash.add_field(5,'HashPart3',260) -MsiFileHash.add_field(6,'HashPart4',260) - -MsiPatchHeaders = Table('MsiPatchHeaders') -MsiPatchHeaders.add_field(1,'StreamRef',11558) -MsiPatchHeaders.add_field(2,'Header',2304) - -ODBCAttribute = Table('ODBCAttribute') -ODBCAttribute.add_field(1,'Driver_',11592) -ODBCAttribute.add_field(2,'Attribute',11560) -ODBCAttribute.add_field(3,'Value',8191) - -ODBCDriver = Table('ODBCDriver') -ODBCDriver.add_field(1,'Driver',11592) -ODBCDriver.add_field(2,'Component_',0xDFF) -ODBCDriver.add_field(3,'Description',3583) -ODBCDriver.add_field(4,'File_',0xDFF) -ODBCDriver.add_field(5,'File_Setup',0x1DFF) - -ODBCDataSource = Table('ODBCDataSource') -ODBCDataSource.add_field(1,'DataSource',0x2DFF) -ODBCDataSource.add_field(2,'Component_',0xDFF) -ODBCDataSource.add_field(3,'Description',3583) -ODBCDataSource.add_field(4,'DriverDescription',3583) -ODBCDataSource.add_field(5,'Registration',1282) - -ODBCSourceAttribute = Table('ODBCSourceAttribute') -ODBCSourceAttribute.add_field(1,'DataSource_',11592) -ODBCSourceAttribute.add_field(2,'Attribute',11552) -ODBCSourceAttribute.add_field(3,'Value',8191) - -ODBCTranslator = Table('ODBCTranslator') -ODBCTranslator.add_field(1,'Translator',11592) -ODBCTranslator.add_field(2,'Component_',0xDFF) -ODBCTranslator.add_field(3,'Description',3583) -ODBCTranslator.add_field(4,'File_',0xDFF) -ODBCTranslator.add_field(5,'File_Setup',0x1DFF) - -Patch = Table('Patch') -Patch.add_field(1,'File_',11592) -Patch.add_field(2,'Sequence',9474) -Patch.add_field(3,'PatchSize',260) -Patch.add_field(4,'Attributes',1282) -Patch.add_field(5,'Header',6400) -Patch.add_field(6,'StreamRef_',7462) - -PatchPackage = Table('PatchPackage') -PatchPackage.add_field(1,'PatchId',11558) -PatchPackage.add_field(2,'Media_',1282) - -PublishComponent = Table('PublishComponent') -PublishComponent.add_field(1,'ComponentId',11558) -PublishComponent.add_field(2,'Qualifier',11775) -PublishComponent.add_field(3,'Component_',0x2DFF) -PublishComponent.add_field(4,'AppData',8191) -PublishComponent.add_field(5,'Feature_',3366) - -RadioButton = Table('RadioButton') -RadioButton.add_field(1,'Property',11592) -RadioButton.add_field(2,'Order',9474) -RadioButton.add_field(3,'Value',3392) -RadioButton.add_field(4,'X',1282) -RadioButton.add_field(5,'Y',1282) -RadioButton.add_field(6,'Width',1282) -RadioButton.add_field(7,'Height',1282) -RadioButton.add_field(8,'Text',8000) -RadioButton.add_field(9,'Help',7986) - -Registry = Table('Registry') -Registry.add_field(1,'Registry',0x2DFF) -Registry.add_field(2,'Root',1282) -Registry.add_field(3,'Key',4095) -Registry.add_field(4,'Name',8191) -Registry.add_field(5,'Value',7936) -Registry.add_field(6,'Component_',0xDFF) - -RegLocator = Table('RegLocator') -RegLocator.add_field(1,'Signature_',11592) -RegLocator.add_field(2,'Root',1282) -RegLocator.add_field(3,'Key',3583) -RegLocator.add_field(4,'Name',7679) -RegLocator.add_field(5,'Type',5378) - -RemoveFile = Table('RemoveFile') -RemoveFile.add_field(1,'FileKey',11592) -RemoveFile.add_field(2,'Component_',0xDFF) -RemoveFile.add_field(3,'FileName',8191) -RemoveFile.add_field(4,'DirProperty',3400) -RemoveFile.add_field(5,'InstallMode',1282) - -RemoveIniFile = Table('RemoveIniFile') -RemoveIniFile.add_field(1,'RemoveIniFile',11592) -RemoveIniFile.add_field(2,'FileName',4095) -RemoveIniFile.add_field(3,'DirProperty',7496) -RemoveIniFile.add_field(4,'Section',3936) -RemoveIniFile.add_field(5,'Key',3968) -RemoveIniFile.add_field(6,'Value',8191) -RemoveIniFile.add_field(7,'Action',1282) -RemoveIniFile.add_field(8,'Component_',0xDFF) - -RemoveRegistry = Table('RemoveRegistry') -RemoveRegistry.add_field(1,'RemoveRegistry',11592) -RemoveRegistry.add_field(2,'Root',1282) -RemoveRegistry.add_field(3,'Key',4095) -RemoveRegistry.add_field(4,'Name',8191) -RemoveRegistry.add_field(5,'Component_',0xDFF) - -ReserveCost = Table('ReserveCost') -ReserveCost.add_field(1,'ReserveKey',11592) -ReserveCost.add_field(2,'Component_',0xDFF) -ReserveCost.add_field(3,'ReserveFolder',7496) -ReserveCost.add_field(4,'ReserveLocal',260) -ReserveCost.add_field(5,'ReserveSource',260) - -SelfReg = Table('SelfReg') -SelfReg.add_field(1,'File_',0x2DFF) -SelfReg.add_field(2,'Cost',5378) - -ServiceControl = Table('ServiceControl') -ServiceControl.add_field(1,'ServiceControl',11592) -ServiceControl.add_field(2,'Name',4095) -ServiceControl.add_field(3,'Event',1282) -ServiceControl.add_field(4,'Arguments',8191) -ServiceControl.add_field(5,'Wait',5378) -ServiceControl.add_field(6,'Component_',0xDFF) - -ServiceInstall = Table('ServiceInstall') -ServiceInstall.add_field(1,'ServiceInstall',11592) -ServiceInstall.add_field(2,'Name',3583) -ServiceInstall.add_field(3,'DisplayName',8191) -ServiceInstall.add_field(4,'ServiceType',260) -ServiceInstall.add_field(5,'StartType',260) -ServiceInstall.add_field(6,'ErrorControl',260) -ServiceInstall.add_field(7,'LoadOrderGroup',7679) -ServiceInstall.add_field(8,'Dependencies',7679) -ServiceInstall.add_field(9,'StartName',7679) -ServiceInstall.add_field(10,'Password',7679) -ServiceInstall.add_field(11,'Arguments',7679) -ServiceInstall.add_field(12,'Component_',0xDFF) -ServiceInstall.add_field(13,'Description',8191) - -Shortcut = Table('Shortcut') -Shortcut.add_field(1,'Shortcut',11592) -Shortcut.add_field(2,'Directory_',0xDFF) -Shortcut.add_field(3,'Name',3968) -Shortcut.add_field(4,'Component_',0xDFF) -Shortcut.add_field(5,'Target',3400) -Shortcut.add_field(6,'Arguments',7679) -Shortcut.add_field(7,'Description',8191) -Shortcut.add_field(8,'Hotkey',5378) -Shortcut.add_field(9,'Icon_',7496) -Shortcut.add_field(10,'IconIndex',5378) -Shortcut.add_field(11,'ShowCmd',5378) -Shortcut.add_field(12,'WkDir',7496) - -Signature = Table('Signature') -Signature.add_field(1,'Signature',11592) -Signature.add_field(2,'FileName',3583) -Signature.add_field(3,'MinVersion',7444) -Signature.add_field(4,'MaxVersion',7444) -Signature.add_field(5,'MinSize',4356) -Signature.add_field(6,'MaxSize',4356) -Signature.add_field(7,'MinDate',4356) -Signature.add_field(8,'MaxDate',4356) -Signature.add_field(9,'Languages',7679) - -TextStyle = Table('TextStyle') -TextStyle.add_field(1,'TextStyle',11592) -TextStyle.add_field(2,'FaceName',3360) -TextStyle.add_field(3,'Size',1282) -TextStyle.add_field(4,'Color',4356) -TextStyle.add_field(5,'StyleBits',5378) - -TypeLib = Table('TypeLib') -TypeLib.add_field(1,'LibID',11558) -TypeLib.add_field(2,'Language',9474) -TypeLib.add_field(3,'Component_',0x2DFF) -TypeLib.add_field(4,'Version',4356) -TypeLib.add_field(5,'Description',8064) -TypeLib.add_field(6,'Directory_',0x1DFF) -TypeLib.add_field(7,'Feature_',3366) -TypeLib.add_field(8,'Cost',4356) - -UIText = Table('UIText') -UIText.add_field(1,'Key',11592) -UIText.add_field(2,'Text',8191) - -Upgrade = Table('Upgrade') -Upgrade.add_field(1,'UpgradeCode',11558) -Upgrade.add_field(2,'VersionMin',15636) -Upgrade.add_field(3,'VersionMax',15636) -Upgrade.add_field(4,'Language',15871) -Upgrade.add_field(5,'Attributes',8452) -Upgrade.add_field(6,'Remove',7679) -Upgrade.add_field(7,'ActionProperty',3400) - -Verb = Table('Verb') -Verb.add_field(1,'Extension_',11775) -Verb.add_field(2,'Verb',11552) -Verb.add_field(3,'Sequence',5378) -Verb.add_field(4,'Command',8191) -Verb.add_field(5,'Argument',8191) - -tables=[_Validation, ActionText, AdminExecuteSequence, Condition, AdminUISequence, AdvtExecuteSequence, AdvtUISequence, AppId, AppSearch, Property, BBControl, Billboard, Feature, Binary, BindImage, File, CCPSearch, CheckBox, Class, Component, Icon, ProgId, ComboBox, CompLocator, Complus, Directory, Control, Dialog, ControlCondition, ControlEvent, CreateFolder, CustomAction, DrLocator, DuplicateFile, Environment, Error, EventMapping, Extension, MIME, FeatureComponents, FileSFPCatalog, SFPCatalog, Font, IniFile, IniLocator, InstallExecuteSequence, InstallUISequence, IsolatedComponent, LaunchCondition, ListBox, ListView, LockPermissions, Media, MoveFile, MsiAssembly, MsiAssemblyName, MsiDigitalCertificate, MsiDigitalSignature, MsiFileHash, MsiPatchHeaders, ODBCAttribute, ODBCDriver, ODBCDataSource, ODBCSourceAttribute, ODBCTranslator, Patch, PatchPackage, PublishComponent, RadioButton, Registry, RegLocator, RemoveFile, RemoveIniFile, RemoveRegistry, ReserveCost, SelfReg, ServiceControl, ServiceInstall, Shortcut, Signature, TextStyle, TypeLib, UIText, Upgrade, Verb] - -_Validation_records = [ -(u'_Validation',u'Table',u'N',None, None, None, None, u'Identifier',None, u'Name of table',), -(u'_Validation',u'Column',u'N',None, None, None, None, u'Identifier',None, u'Name of column',), -(u'_Validation',u'Description',u'Y',None, None, None, None, u'Text',None, u'Description of column',), -(u'_Validation',u'Set',u'Y',None, None, None, None, u'Text',None, u'Set of values that are permitted',), -(u'_Validation',u'Category',u'Y',None, None, None, None, None, u'Text;Formatted;Template;Condition;Guid;Path;Version;Language;Identifier;Binary;UpperCase;LowerCase;Filename;Paths;AnyPath;WildCardFilename;RegPath;KeyFormatted;CustomSource;Property;Cabinet;Shortcut;URL',u'String category',), -(u'_Validation',u'KeyColumn',u'Y',1,32,None, None, None, None, u'Column to which foreign key connects',), -(u'_Validation',u'KeyTable',u'Y',None, None, None, None, u'Identifier',None, u'For foreign key, Name of table to which data must link',), -(u'_Validation',u'MaxValue',u'Y',-2147483647,2147483647,None, None, None, None, u'Maximum value allowed',), -(u'_Validation',u'MinValue',u'Y',-2147483647,2147483647,None, None, None, None, u'Minimum value allowed',), -(u'_Validation',u'Nullable',u'N',None, None, None, None, None, u'Y;N;@',u'Whether the column is nullable',), -(u'ActionText',u'Description',u'Y',None, None, None, None, u'Text',None, u'Localized description displayed in progress dialog and log when action is executing.',), -(u'ActionText',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to be described.',), -(u'ActionText',u'Template',u'Y',None, None, None, None, u'Template',None, u'Optional localized format template used to format action data records for display during action execution.',), -(u'AdminExecuteSequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',), -(u'AdminExecuteSequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',), -(u'AdminExecuteSequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.',), -(u'Condition',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Expression evaluated to determine if Level in the Feature table is to change.',), -(u'Condition',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Reference to a Feature entry in Feature table.',), -(u'Condition',u'Level',u'N',0,32767,None, None, None, None, u'New selection Level to set in Feature table if Condition evaluates to TRUE.',), -(u'AdminUISequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',), -(u'AdminUISequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',), -(u'AdminUISequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.',), -(u'AdvtExecuteSequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',), -(u'AdvtExecuteSequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',), -(u'AdvtExecuteSequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.',), -(u'AdvtUISequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',), -(u'AdvtUISequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',), -(u'AdvtUISequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.',), -(u'AppId',u'AppId',u'N',None, None, None, None, u'Guid',None, None, ), -(u'AppId',u'ActivateAtStorage',u'Y',0,1,None, None, None, None, None, ), -(u'AppId',u'DllSurrogate',u'Y',None, None, None, None, u'Text',None, None, ), -(u'AppId',u'LocalService',u'Y',None, None, None, None, u'Text',None, None, ), -(u'AppId',u'RemoteServerName',u'Y',None, None, None, None, u'Formatted',None, None, ), -(u'AppId',u'RunAsInteractiveUser',u'Y',0,1,None, None, None, None, None, ), -(u'AppId',u'ServiceParameters',u'Y',None, None, None, None, u'Text',None, None, ), -(u'AppSearch',u'Property',u'N',None, None, None, None, u'Identifier',None, u'The property associated with a Signature',), -(u'AppSearch',u'Signature_',u'N',None, None, u'Signature;RegLocator;IniLocator;DrLocator;CompLocator',1,u'Identifier',None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature, RegLocator, IniLocator, CompLocator and the DrLocator tables.',), -(u'Property',u'Property',u'N',None, None, None, None, u'Identifier',None, u'Name of property, uppercase if settable by launcher or loader.',), -(u'Property',u'Value',u'N',None, None, None, None, u'Text',None, u'String value for property. Never null or empty.',), -(u'BBControl',u'Type',u'N',None, None, None, None, u'Identifier',None, u'The type of the control.',), -(u'BBControl',u'Y',u'N',0,32767,None, None, None, None, u'Vertical coordinate of the upper left corner of the bounding rectangle of the control.',), -(u'BBControl',u'Text',u'Y',None, None, None, None, u'Text',None, u'A string used to set the initial text contained within a control (if appropriate).',), -(u'BBControl',u'BBControl',u'N',None, None, None, None, u'Identifier',None, u'Name of the control. This name must be unique within a billboard, but can repeat on different billboard.',), -(u'BBControl',u'Attributes',u'Y',0,2147483647,None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this control.',), -(u'BBControl',u'Billboard_',u'N',None, None, u'Billboard',1,u'Identifier',None, u'External key to the Billboard table, name of the billboard.',), -(u'BBControl',u'Height',u'N',0,32767,None, None, None, None, u'Height of the bounding rectangle of the control.',), -(u'BBControl',u'Width',u'N',0,32767,None, None, None, None, u'Width of the bounding rectangle of the control.',), -(u'BBControl',u'X',u'N',0,32767,None, None, None, None, u'Horizontal coordinate of the upper left corner of the bounding rectangle of the control.',), -(u'Billboard',u'Action',u'Y',None, None, None, None, u'Identifier',None, u'The name of an action. The billboard is displayed during the progress messages received from this action.',), -(u'Billboard',u'Billboard',u'N',None, None, None, None, u'Identifier',None, u'Name of the billboard.',), -(u'Billboard',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'An external key to the Feature Table. The billboard is shown only if this feature is being installed.',), -(u'Billboard',u'Ordering',u'Y',0,32767,None, None, None, None, u'A positive integer. If there is more than one billboard corresponding to an action they will be shown in the order defined by this column.',), -(u'Feature',u'Description',u'Y',None, None, None, None, u'Text',None, u'Longer descriptive text describing a visible feature item.',), -(u'Feature',u'Attributes',u'N',None, None, None, None, None, u'0;1;2;4;5;6;8;9;10;16;17;18;20;21;22;24;25;26;32;33;34;36;37;38;48;49;50;52;53;54',u'Feature attributes',), -(u'Feature',u'Feature',u'N',None, None, None, None, u'Identifier',None, u'Primary key used to identify a particular feature record.',), -(u'Feature',u'Directory_',u'Y',None, None, u'Directory',1,u'UpperCase',None, u'The name of the Directory that can be configured by the UI. A non-null value will enable the browse button.',), -(u'Feature',u'Level',u'N',0,32767,None, None, None, None, u'The install level at which record will be initially selected. An install level of 0 will disable an item and prevent its display.',), -(u'Feature',u'Title',u'Y',None, None, None, None, u'Text',None, u'Short text identifying a visible feature item.',), -(u'Feature',u'Display',u'Y',0,32767,None, None, None, None, u'Numeric sort order, used to force a specific display ordering.',), -(u'Feature',u'Feature_Parent',u'Y',None, None, u'Feature',1,u'Identifier',None, u'Optional key of a parent record in the same table. If the parent is not selected, then the record will not be installed. Null indicates a root item.',), -(u'Binary',u'Name',u'N',None, None, None, None, u'Identifier',None, u'Unique key identifying the binary data.',), -(u'Binary',u'Data',u'N',None, None, None, None, u'Binary',None, u'The unformatted binary data.',), -(u'BindImage',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'The index into the File table. This must be an executable file.',), -(u'BindImage',u'Path',u'Y',None, None, None, None, u'Paths',None, u'A list of ; delimited paths that represent the paths to be searched for the import DLLS. The list is usually a list of properties each enclosed within square brackets [] .',), -(u'File',u'Sequence',u'N',1,32767,None, None, None, None, u'Sequence with respect to the media images; order must track cabinet order.',), -(u'File',u'Attributes',u'Y',0,32767,None, None, None, None, u'Integer containing bit flags representing file attributes (with the decimal value of each bit position in parentheses)',), -(u'File',u'File',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token, must match identifier in cabinet. For uncompressed files, this field is ignored.',), -(u'File',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key referencing Component that controls the file.',), -(u'File',u'FileName',u'N',None, None, None, None, u'Filename',None, u'File name used for installation, may be localized. This may contain a "short name|long name" pair.',), -(u'File',u'FileSize',u'N',0,2147483647,None, None, None, None, u'Size of file in bytes (long integer).',), -(u'File',u'Language',u'Y',None, None, None, None, u'Language',None, u'List of decimal language Ids, comma-separated if more than one.',), -(u'File',u'Version',u'Y',None, None, u'File',1,u'Version',None, u'Version string for versioned files; Blank for unversioned files.',), -(u'CCPSearch',u'Signature_',u'N',None, None, u'Signature;RegLocator;IniLocator;DrLocator;CompLocator',1,u'Identifier',None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature, RegLocator, IniLocator, CompLocator and the DrLocator tables.',), -(u'CheckBox',u'Property',u'N',None, None, None, None, u'Identifier',None, u'A named property to be tied to the item.',), -(u'CheckBox',u'Value',u'Y',None, None, None, None, u'Formatted',None, u'The value string associated with the item.',), -(u'Class',u'Description',u'Y',None, None, None, None, u'Text',None, u'Localized description for the Class.',), -(u'Class',u'Attributes',u'Y',None, 32767,None, None, None, None, u'Class registration attributes.',), -(u'Class',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the CLSID factory to be operational.',), -(u'Class',u'AppId_',u'Y',None, None, u'AppId',1,u'Guid',None, u'Optional AppID containing DCOM information for associated application (string GUID).',), -(u'Class',u'Argument',u'Y',None, None, None, None, u'Formatted',None, u'optional argument for LocalServers.',), -(u'Class',u'CLSID',u'N',None, None, None, None, u'Guid',None, u'The CLSID of an OLE factory.',), -(u'Class',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.',), -(u'Class',u'Context',u'N',None, None, None, None, u'Identifier',None, u'The numeric server context for this server. CLSCTX_xxxx',), -(u'Class',u'DefInprocHandler',u'Y',None, None, None, None, u'Filename',u'1;2;3',u'Optional default inproc handler. Only optionally provided if Context=CLSCTX_LOCAL_SERVER. Typically "ole32.dll" or "mapi32.dll"',), -(u'Class',u'FileTypeMask',u'Y',None, None, None, None, u'Text',None, u'Optional string containing information for the HKCRthis CLSID) key. If multiple patterns exist, they must be delimited by a semicolon, and numeric subkeys will be generated: 0,1,2...',), -(u'Class',u'Icon_',u'Y',None, None, u'Icon',1,u'Identifier',None, u'Optional foreign key into the Icon Table, specifying the icon file associated with this CLSID. Will be written under the DefaultIcon key.',), -(u'Class',u'IconIndex',u'Y',-32767,32767,None, None, None, None, u'Optional icon index.',), -(u'Class',u'ProgId_Default',u'Y',None, None, u'ProgId',1,u'Text',None, u'Optional ProgId associated with this CLSID.',), -(u'Component',u'Condition',u'Y',None, None, None, None, u'Condition',None, u"A conditional statement that will disable this component if the specified condition evaluates to the 'True' state. If a component is disabled, it will not be installed, regardless of the 'Action' state associated with the component.",), -(u'Component',u'Attributes',u'N',None, None, None, None, None, None, u'Remote execution option, one of irsEnum',), -(u'Component',u'Component',u'N',None, None, None, None, u'Identifier',None, u'Primary key used to identify a particular component record.',), -(u'Component',u'ComponentId',u'Y',None, None, None, None, u'Guid',None, u'A string GUID unique to this component, version, and language.',), -(u'Component',u'Directory_',u'N',None, None, u'Directory',1,u'Identifier',None, u'Required key of a Directory table record. This is actually a property name whose value contains the actual path, set either by the AppSearch action or with the default setting obtained from the Directory table.',), -(u'Component',u'KeyPath',u'Y',None, None, u'File;Registry;ODBCDataSource',1,u'Identifier',None, u'Either the primary key into the File table, Registry table, or ODBCDataSource table. This extract path is stored when the component is installed, and is used to detect the presence of the component and to return the path to it.',), -(u'Icon',u'Name',u'N',None, None, None, None, u'Identifier',None, u'Primary key. Name of the icon file.',), -(u'Icon',u'Data',u'N',None, None, None, None, u'Binary',None, u'Binary stream. The binary icon data in PE (.DLL or .EXE) or icon (.ICO) format.',), -(u'ProgId',u'Description',u'Y',None, None, None, None, u'Text',None, u'Localized description for the Program identifier.',), -(u'ProgId',u'Icon_',u'Y',None, None, u'Icon',1,u'Identifier',None, u'Optional foreign key into the Icon Table, specifying the icon file associated with this ProgId. Will be written under the DefaultIcon key.',), -(u'ProgId',u'IconIndex',u'Y',-32767,32767,None, None, None, None, u'Optional icon index.',), -(u'ProgId',u'ProgId',u'N',None, None, None, None, u'Text',None, u'The Program Identifier. Primary key.',), -(u'ProgId',u'Class_',u'Y',None, None, u'Class',1,u'Guid',None, u'The CLSID of an OLE factory corresponding to the ProgId.',), -(u'ProgId',u'ProgId_Parent',u'Y',None, None, u'ProgId',1,u'Text',None, u'The Parent Program Identifier. If specified, the ProgId column becomes a version independent prog id.',), -(u'ComboBox',u'Text',u'Y',None, None, None, None, u'Formatted',None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.',), -(u'ComboBox',u'Property',u'N',None, None, None, None, u'Identifier',None, u'A named property to be tied to this item. All the items tied to the same property become part of the same combobox.',), -(u'ComboBox',u'Value',u'N',None, None, None, None, u'Formatted',None, u'The value string associated with this item. Selecting the line will set the associated property to this value.',), -(u'ComboBox',u'Order',u'N',1,32767,None, None, None, None, u'A positive integer used to determine the ordering of the items within one list.\tThe integers do not have to be consecutive.',), -(u'CompLocator',u'Type',u'Y',0,1,None, None, None, None, u'A boolean value that determines if the registry value is a filename or a directory location.',), -(u'CompLocator',u'Signature_',u'N',None, None, None, None, u'Identifier',None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table.',), -(u'CompLocator',u'ComponentId',u'N',None, None, None, None, u'Guid',None, u'A string GUID unique to this component, version, and language.',), -(u'Complus',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key referencing Component that controls the ComPlus component.',), -(u'Complus',u'ExpType',u'Y',0,32767,None, None, None, None, u'ComPlus component attributes.',), -(u'Directory',u'Directory',u'N',None, None, None, None, u'Identifier',None, u'Unique identifier for directory entry, primary key. If a property by this name is defined, it contains the full path to the directory.',), -(u'Directory',u'DefaultDir',u'N',None, None, None, None, u'DefaultDir',None, u"The default sub-path under parent's path.",), -(u'Directory',u'Directory_Parent',u'Y',None, None, u'Directory',1,u'Identifier',None, u'Reference to the entry in this table specifying the default parent directory. A record parented to itself or with a Null parent represents a root of the install tree.',), -(u'Control',u'Type',u'N',None, None, None, None, u'Identifier',None, u'The type of the control.',), -(u'Control',u'Y',u'N',0,32767,None, None, None, None, u'Vertical coordinate of the upper left corner of the bounding rectangle of the control.',), -(u'Control',u'Text',u'Y',None, None, None, None, u'Formatted',None, u'A string used to set the initial text contained within a control (if appropriate).',), -(u'Control',u'Property',u'Y',None, None, None, None, u'Identifier',None, u'The name of a defined property to be linked to this control. ',), -(u'Control',u'Attributes',u'Y',0,2147483647,None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this control.',), -(u'Control',u'Height',u'N',0,32767,None, None, None, None, u'Height of the bounding rectangle of the control.',), -(u'Control',u'Width',u'N',0,32767,None, None, None, None, u'Width of the bounding rectangle of the control.',), -(u'Control',u'X',u'N',0,32767,None, None, None, None, u'Horizontal coordinate of the upper left corner of the bounding rectangle of the control.',), -(u'Control',u'Control',u'N',None, None, None, None, u'Identifier',None, u'Name of the control. This name must be unique within a dialog, but can repeat on different dialogs. ',), -(u'Control',u'Control_Next',u'Y',None, None, u'Control',2,u'Identifier',None, u'The name of an other control on the same dialog. This link defines the tab order of the controls. The links have to form one or more cycles!',), -(u'Control',u'Dialog_',u'N',None, None, u'Dialog',1,u'Identifier',None, u'External key to the Dialog table, name of the dialog.',), -(u'Control',u'Help',u'Y',None, None, None, None, u'Text',None, u'The help strings used with the button. The text is optional. ',), -(u'Dialog',u'Attributes',u'Y',0,2147483647,None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this dialog.',), -(u'Dialog',u'Height',u'N',0,32767,None, None, None, None, u'Height of the bounding rectangle of the dialog.',), -(u'Dialog',u'Width',u'N',0,32767,None, None, None, None, u'Width of the bounding rectangle of the dialog.',), -(u'Dialog',u'Dialog',u'N',None, None, None, None, u'Identifier',None, u'Name of the dialog.',), -(u'Dialog',u'Control_Cancel',u'Y',None, None, u'Control',2,u'Identifier',None, u'Defines the cancel control. Hitting escape or clicking on the close icon on the dialog is equivalent to pushing this button.',), -(u'Dialog',u'Control_Default',u'Y',None, None, u'Control',2,u'Identifier',None, u'Defines the default control. Hitting return is equivalent to pushing this button.',), -(u'Dialog',u'Control_First',u'N',None, None, u'Control',2,u'Identifier',None, u'Defines the control that has the focus when the dialog is created.',), -(u'Dialog',u'HCentering',u'N',0,100,None, None, None, None, u'Horizontal position of the dialog on a 0-100 scale. 0 means left end, 100 means right end of the screen, 50 center.',), -(u'Dialog',u'Title',u'Y',None, None, None, None, u'Formatted',None, u"A text string specifying the title to be displayed in the title bar of the dialog's window.",), -(u'Dialog',u'VCentering',u'N',0,100,None, None, None, None, u'Vertical position of the dialog on a 0-100 scale. 0 means top end, 100 means bottom end of the screen, 50 center.',), -(u'ControlCondition',u'Action',u'N',None, None, None, None, None, u'Default;Disable;Enable;Hide;Show',u'The desired action to be taken on the specified control.',), -(u'ControlCondition',u'Condition',u'N',None, None, None, None, u'Condition',None, u'A standard conditional statement that specifies under which conditions the action should be triggered.',), -(u'ControlCondition',u'Dialog_',u'N',None, None, u'Dialog',1,u'Identifier',None, u'A foreign key to the Dialog table, name of the dialog.',), -(u'ControlCondition',u'Control_',u'N',None, None, u'Control',2,u'Identifier',None, u'A foreign key to the Control table, name of the control.',), -(u'ControlEvent',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'A standard conditional statement that specifies under which conditions an event should be triggered.',), -(u'ControlEvent',u'Ordering',u'Y',0,2147483647,None, None, None, None, u'An integer used to order several events tied to the same control. Can be left blank.',), -(u'ControlEvent',u'Argument',u'N',None, None, None, None, u'Formatted',None, u'A value to be used as a modifier when triggering a particular event.',), -(u'ControlEvent',u'Dialog_',u'N',None, None, u'Dialog',1,u'Identifier',None, u'A foreign key to the Dialog table, name of the dialog.',), -(u'ControlEvent',u'Control_',u'N',None, None, u'Control',2,u'Identifier',None, u'A foreign key to the Control table, name of the control',), -(u'ControlEvent',u'Event',u'N',None, None, None, None, u'Formatted',None, u'An identifier that specifies the type of the event that should take place when the user interacts with control specified by the first two entries.',), -(u'CreateFolder',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table.',), -(u'CreateFolder',u'Directory_',u'N',None, None, u'Directory',1,u'Identifier',None, u'Primary key, could be foreign key into the Directory table.',), -(u'CustomAction',u'Type',u'N',1,16383,None, None, None, None, u'The numeric custom action type, consisting of source location, code type, entry, option flags.',), -(u'CustomAction',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Primary key, name of action, normally appears in sequence table unless private use.',), -(u'CustomAction',u'Source',u'Y',None, None, None, None, u'CustomSource',None, u'The table reference of the source of the code.',), -(u'CustomAction',u'Target',u'Y',None, None, None, None, u'Formatted',None, u'Excecution parameter, depends on the type of custom action',), -(u'DrLocator',u'Signature_',u'N',None, None, None, None, u'Identifier',None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature table.',), -(u'DrLocator',u'Path',u'Y',None, None, None, None, u'AnyPath',None, u'The path on the user system. This is a either a subpath below the value of the Parent or a full path. The path may contain properties enclosed within [ ] that will be expanded.',), -(u'DrLocator',u'Depth',u'Y',0,32767,None, None, None, None, u'The depth below the path to which the Signature_ is recursively searched. If absent, the depth is assumed to be 0.',), -(u'DrLocator',u'Parent',u'Y',None, None, None, None, u'Identifier',None, u'The parent file signature. It is also a foreign key in the Signature table. If null and the Path column does not expand to a full path, then all the fixed drives of the user system are searched using the Path.',), -(u'DuplicateFile',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Foreign key referencing the source file to be duplicated.',), -(u'DuplicateFile',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key referencing Component that controls the duplicate file.',), -(u'DuplicateFile',u'DestFolder',u'Y',None, None, None, None, u'Identifier',None, u'Name of a property whose value is assumed to resolve to the full pathname to a destination folder.',), -(u'DuplicateFile',u'DestName',u'Y',None, None, None, None, u'Filename',None, u'Filename to be given to the duplicate file.',), -(u'DuplicateFile',u'FileKey',u'N',None, None, None, None, u'Identifier',None, u'Primary key used to identify a particular file entry',), -(u'Environment',u'Name',u'N',None, None, None, None, u'Text',None, u'The name of the environmental value.',), -(u'Environment',u'Value',u'Y',None, None, None, None, u'Formatted',None, u'The value to set in the environmental settings.',), -(u'Environment',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table referencing component that controls the installing of the environmental value.',), -(u'Environment',u'Environment',u'N',None, None, None, None, u'Identifier',None, u'Unique identifier for the environmental variable setting',), -(u'Error',u'Error',u'N',0,32767,None, None, None, None, u'Integer error number, obtained from header file IError(...) macros.',), -(u'Error',u'Message',u'Y',None, None, None, None, u'Template',None, u'Error formatting template, obtained from user ed. or localizers.',), -(u'EventMapping',u'Dialog_',u'N',None, None, u'Dialog',1,u'Identifier',None, u'A foreign key to the Dialog table, name of the Dialog.',), -(u'EventMapping',u'Control_',u'N',None, None, u'Control',2,u'Identifier',None, u'A foreign key to the Control table, name of the control.',), -(u'EventMapping',u'Event',u'N',None, None, None, None, u'Identifier',None, u'An identifier that specifies the type of the event that the control subscribes to.',), -(u'EventMapping',u'Attribute',u'N',None, None, None, None, u'Identifier',None, u'The name of the control attribute, that is set when this event is received.',), -(u'Extension',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the CLSID factory to be operational.',), -(u'Extension',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.',), -(u'Extension',u'Extension',u'N',None, None, None, None, u'Text',None, u'The extension associated with the table row.',), -(u'Extension',u'MIME_',u'Y',None, None, u'MIME',1,u'Text',None, u'Optional Context identifier, typically "type/format" associated with the extension',), -(u'Extension',u'ProgId_',u'Y',None, None, u'ProgId',1,u'Text',None, u'Optional ProgId associated with this extension.',), -(u'MIME',u'CLSID',u'Y',None, None, None, None, u'Guid',None, u'Optional associated CLSID.',), -(u'MIME',u'ContentType',u'N',None, None, None, None, u'Text',None, u'Primary key. Context identifier, typically "type/format".',), -(u'MIME',u'Extension_',u'N',None, None, u'Extension',1,u'Text',None, u'Optional associated extension (without dot)',), -(u'FeatureComponents',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Foreign key into Feature table.',), -(u'FeatureComponents',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into Component table.',), -(u'FileSFPCatalog',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'File associated with the catalog',), -(u'FileSFPCatalog',u'SFPCatalog_',u'N',None, None, u'SFPCatalog',1,u'Filename',None, u'Catalog associated with the file',), -(u'SFPCatalog',u'SFPCatalog',u'N',None, None, None, None, u'Filename',None, u'File name for the catalog.',), -(u'SFPCatalog',u'Catalog',u'N',None, None, None, None, u'Binary',None, u'SFP Catalog',), -(u'SFPCatalog',u'Dependency',u'Y',None, None, None, None, u'Formatted',None, u'Parent catalog - only used by SFP',), -(u'Font',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Primary key, foreign key into File table referencing font file.',), -(u'Font',u'FontTitle',u'Y',None, None, None, None, u'Text',None, u'Font name.',), -(u'IniFile',u'Action',u'N',None, None, None, None, None, u'0;1;3',u'The type of modification to be made, one of iifEnum',), -(u'IniFile',u'Value',u'N',None, None, None, None, u'Formatted',None, u'The value to be written.',), -(u'IniFile',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table referencing component that controls the installing of the .INI value.',), -(u'IniFile',u'FileName',u'N',None, None, None, None, u'Filename',None, u'The .INI file name in which to write the information',), -(u'IniFile',u'IniFile',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',), -(u'IniFile',u'DirProperty',u'Y',None, None, None, None, u'Identifier',None, u'Foreign key into the Directory table denoting the directory where the .INI file is.',), -(u'IniFile',u'Key',u'N',None, None, None, None, u'Formatted',None, u'The .INI file key below Section.',), -(u'IniFile',u'Section',u'N',None, None, None, None, u'Formatted',None, u'The .INI file Section.',), -(u'IniLocator',u'Type',u'Y',0,2,None, None, None, None, u'An integer value that determines if the .INI value read is a filename or a directory location or to be used as is w/o interpretation.',), -(u'IniLocator',u'Signature_',u'N',None, None, None, None, u'Identifier',None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table.',), -(u'IniLocator',u'FileName',u'N',None, None, None, None, u'Filename',None, u'The .INI file name.',), -(u'IniLocator',u'Key',u'N',None, None, None, None, u'Text',None, u'Key value (followed by an equals sign in INI file).',), -(u'IniLocator',u'Section',u'N',None, None, None, None, u'Text',None, u'Section name within in file (within square brackets in INI file).',), -(u'IniLocator',u'Field',u'Y',0,32767,None, None, None, None, u'The field in the .INI line. If Field is null or 0 the entire line is read.',), -(u'InstallExecuteSequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',), -(u'InstallExecuteSequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',), -(u'InstallExecuteSequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.',), -(u'InstallUISequence',u'Action',u'N',None, None, None, None, u'Identifier',None, u'Name of action to invoke, either in the engine or the handler DLL.',), -(u'InstallUISequence',u'Condition',u'Y',None, None, None, None, u'Condition',None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.',), -(u'InstallUISequence',u'Sequence',u'Y',-4,32767,None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.',), -(u'IsolatedComponent',u'Component_Application',u'N',None, None, u'Component',1,u'Identifier',None, u'Key to Component table item for application',), -(u'IsolatedComponent',u'Component_Shared',u'N',None, None, u'Component',1,u'Identifier',None, u'Key to Component table item to be isolated',), -(u'LaunchCondition',u'Description',u'N',None, None, None, None, u'Formatted',None, u'Localizable text to display when condition fails and install must abort.',), -(u'LaunchCondition',u'Condition',u'N',None, None, None, None, u'Condition',None, u'Expression which must evaluate to TRUE in order for install to commence.',), -(u'ListBox',u'Text',u'Y',None, None, None, None, u'Text',None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.',), -(u'ListBox',u'Property',u'N',None, None, None, None, u'Identifier',None, u'A named property to be tied to this item. All the items tied to the same property become part of the same listbox.',), -(u'ListBox',u'Value',u'N',None, None, None, None, u'Formatted',None, u'The value string associated with this item. Selecting the line will set the associated property to this value.',), -(u'ListBox',u'Order',u'N',1,32767,None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.',), -(u'ListView',u'Text',u'Y',None, None, None, None, u'Text',None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.',), -(u'ListView',u'Property',u'N',None, None, None, None, u'Identifier',None, u'A named property to be tied to this item. All the items tied to the same property become part of the same listview.',), -(u'ListView',u'Value',u'N',None, None, None, None, u'Identifier',None, u'The value string associated with this item. Selecting the line will set the associated property to this value.',), -(u'ListView',u'Order',u'N',1,32767,None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.',), -(u'ListView',u'Binary_',u'Y',None, None, u'Binary',1,u'Identifier',None, u'The name of the icon to be displayed with the icon. The binary information is looked up from the Binary Table.',), -(u'LockPermissions',u'Table',u'N',None, None, None, None, u'Identifier',u'Directory;File;Registry',u'Reference to another table name',), -(u'LockPermissions',u'Domain',u'Y',None, None, None, None, u'Formatted',None, u'Domain name for user whose permissions are being set. (usually a property)',), -(u'LockPermissions',u'LockObject',u'N',None, None, None, None, u'Identifier',None, u'Foreign key into Registry or File table',), -(u'LockPermissions',u'Permission',u'Y',-2147483647,2147483647,None, None, None, None, u'Permission Access mask. Full Control = 268435456 (GENERIC_ALL = 0x10000000)',), -(u'LockPermissions',u'User',u'N',None, None, None, None, u'Formatted',None, u'User for permissions to be set. (usually a property)',), -(u'Media',u'Source',u'Y',None, None, None, None, u'Property',None, u'The property defining the location of the cabinet file.',), -(u'Media',u'Cabinet',u'Y',None, None, None, None, u'Cabinet',None, u'If some or all of the files stored on the media are compressed in a cabinet, the name of that cabinet.',), -(u'Media',u'DiskId',u'N',1,32767,None, None, None, None, u'Primary key, integer to determine sort order for table.',), -(u'Media',u'DiskPrompt',u'Y',None, None, None, None, u'Text',None, u'Disk name: the visible text actually printed on the disk. This will be used to prompt the user when this disk needs to be inserted.',), -(u'Media',u'LastSequence',u'N',0,32767,None, None, None, None, u'File sequence number for the last file for this media.',), -(u'Media',u'VolumeLabel',u'Y',None, None, None, None, u'Text',None, u'The label attributed to the volume.',), -(u'ModuleComponents',u'Component',u'N',None, None, u'Component',1,u'Identifier',None, u'Component contained in the module.',), -(u'ModuleComponents',u'Language',u'N',None, None, u'ModuleSignature',2,None, None, u'Default language ID for module (may be changed by transform).',), -(u'ModuleComponents',u'ModuleID',u'N',None, None, u'ModuleSignature',1,u'Identifier',None, u'Module containing the component.',), -(u'ModuleSignature',u'Language',u'N',None, None, None, None, None, None, u'Default decimal language of module.',), -(u'ModuleSignature',u'Version',u'N',None, None, None, None, u'Version',None, u'Version of the module.',), -(u'ModuleSignature',u'ModuleID',u'N',None, None, None, None, u'Identifier',None, u'Module identifier (String.GUID).',), -(u'ModuleDependency',u'ModuleID',u'N',None, None, u'ModuleSignature',1,u'Identifier',None, u'Module requiring the dependency.',), -(u'ModuleDependency',u'ModuleLanguage',u'N',None, None, u'ModuleSignature',2,None, None, u'Language of module requiring the dependency.',), -(u'ModuleDependency',u'RequiredID',u'N',None, None, None, None, None, None, u'String.GUID of required module.',), -(u'ModuleDependency',u'RequiredLanguage',u'N',None, None, None, None, None, None, u'LanguageID of the required module.',), -(u'ModuleDependency',u'RequiredVersion',u'Y',None, None, None, None, u'Version',None, u'Version of the required version.',), -(u'ModuleExclusion',u'ModuleID',u'N',None, None, u'ModuleSignature',1,u'Identifier',None, u'String.GUID of module with exclusion requirement.',), -(u'ModuleExclusion',u'ModuleLanguage',u'N',None, None, u'ModuleSignature',2,None, None, u'LanguageID of module with exclusion requirement.',), -(u'ModuleExclusion',u'ExcludedID',u'N',None, None, None, None, None, None, u'String.GUID of excluded module.',), -(u'ModuleExclusion',u'ExcludedLanguage',u'N',None, None, None, None, None, None, u'Language of excluded module.',), -(u'ModuleExclusion',u'ExcludedMaxVersion',u'Y',None, None, None, None, u'Version',None, u'Maximum version of excluded module.',), -(u'ModuleExclusion',u'ExcludedMinVersion',u'Y',None, None, None, None, u'Version',None, u'Minimum version of excluded module.',), -(u'MoveFile',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'If this component is not "selected" for installation or removal, no action will be taken on the associated MoveFile entry',), -(u'MoveFile',u'DestFolder',u'N',None, None, None, None, u'Identifier',None, u'Name of a property whose value is assumed to resolve to the full path to the destination directory',), -(u'MoveFile',u'DestName',u'Y',None, None, None, None, u'Filename',None, u'Name to be given to the original file after it is moved or copied. If blank, the destination file will be given the same name as the source file',), -(u'MoveFile',u'FileKey',u'N',None, None, None, None, u'Identifier',None, u'Primary key that uniquely identifies a particular MoveFile record',), -(u'MoveFile',u'Options',u'N',0,1,None, None, None, None, u'Integer value specifying the MoveFile operating mode, one of imfoEnum',), -(u'MoveFile',u'SourceFolder',u'Y',None, None, None, None, u'Identifier',None, u'Name of a property whose value is assumed to resolve to the full path to the source directory',), -(u'MoveFile',u'SourceName',u'Y',None, None, None, None, u'Text',None, u"Name of the source file(s) to be moved or copied. Can contain the '*' or '?' wildcards.",), -(u'MsiAssembly',u'Attributes',u'Y',None, None, None, None, None, None, u'Assembly attributes',), -(u'MsiAssembly',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Foreign key into Feature table.',), -(u'MsiAssembly',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into Component table.',), -(u'MsiAssembly',u'File_Application',u'Y',None, None, u'File',1,u'Identifier',None, u'Foreign key into File table, denoting the application context for private assemblies. Null for global assemblies.',), -(u'MsiAssembly',u'File_Manifest',u'Y',None, None, u'File',1,u'Identifier',None, u'Foreign key into the File table denoting the manifest file for the assembly.',), -(u'MsiAssemblyName',u'Name',u'N',None, None, None, None, u'Text',None, u'The name part of the name-value pairs for the assembly name.',), -(u'MsiAssemblyName',u'Value',u'N',None, None, None, None, u'Text',None, u'The value part of the name-value pairs for the assembly name.',), -(u'MsiAssemblyName',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into Component table.',), -(u'MsiDigitalCertificate',u'CertData',u'N',None, None, None, None, u'Binary',None, u'A certificate context blob for a signer certificate',), -(u'MsiDigitalCertificate',u'DigitalCertificate',u'N',None, None, None, None, u'Identifier',None, u'A unique identifier for the row',), -(u'MsiDigitalSignature',u'Table',u'N',None, None, None, None, None, u'Media',u'Reference to another table name (only Media table is supported)',), -(u'MsiDigitalSignature',u'DigitalCertificate_',u'N',None, None, u'MsiDigitalCertificate',1,u'Identifier',None, u'Foreign key to MsiDigitalCertificate table identifying the signer certificate',), -(u'MsiDigitalSignature',u'Hash',u'Y',None, None, None, None, u'Binary',None, u'The encoded hash blob from the digital signature',), -(u'MsiDigitalSignature',u'SignObject',u'N',None, None, None, None, u'Text',None, u'Foreign key to Media table',), -(u'MsiFileHash',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Primary key, foreign key into File table referencing file with this hash',), -(u'MsiFileHash',u'Options',u'N',0,32767,None, None, None, None, u'Various options and attributes for this hash.',), -(u'MsiFileHash',u'HashPart1',u'N',None, None, None, None, None, None, u'Size of file in bytes (long integer).',), -(u'MsiFileHash',u'HashPart2',u'N',None, None, None, None, None, None, u'Size of file in bytes (long integer).',), -(u'MsiFileHash',u'HashPart3',u'N',None, None, None, None, None, None, u'Size of file in bytes (long integer).',), -(u'MsiFileHash',u'HashPart4',u'N',None, None, None, None, None, None, u'Size of file in bytes (long integer).',), -(u'MsiPatchHeaders',u'StreamRef',u'N',None, None, None, None, u'Identifier',None, u'Primary key. A unique identifier for the row.',), -(u'MsiPatchHeaders',u'Header',u'N',None, None, None, None, u'Binary',None, u'Binary stream. The patch header, used for patch validation.',), -(u'ODBCAttribute',u'Value',u'Y',None, None, None, None, u'Text',None, u'Value for ODBC driver attribute',), -(u'ODBCAttribute',u'Attribute',u'N',None, None, None, None, u'Text',None, u'Name of ODBC driver attribute',), -(u'ODBCAttribute',u'Driver_',u'N',None, None, u'ODBCDriver',1,u'Identifier',None, u'Reference to ODBC driver in ODBCDriver table',), -(u'ODBCDriver',u'Description',u'N',None, None, None, None, u'Text',None, u'Text used as registered name for driver, non-localized',), -(u'ODBCDriver',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Reference to key driver file',), -(u'ODBCDriver',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Reference to associated component',), -(u'ODBCDriver',u'Driver',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized.internal token for driver',), -(u'ODBCDriver',u'File_Setup',u'Y',None, None, u'File',1,u'Identifier',None, u'Optional reference to key driver setup DLL',), -(u'ODBCDataSource',u'Description',u'N',None, None, None, None, u'Text',None, u'Text used as registered name for data source',), -(u'ODBCDataSource',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Reference to associated component',), -(u'ODBCDataSource',u'DataSource',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized.internal token for data source',), -(u'ODBCDataSource',u'DriverDescription',u'N',None, None, None, None, u'Text',None, u'Reference to driver description, may be existing driver',), -(u'ODBCDataSource',u'Registration',u'N',0,1,None, None, None, None, u'Registration option: 0=machine, 1=user, others t.b.d.',), -(u'ODBCSourceAttribute',u'Value',u'Y',None, None, None, None, u'Text',None, u'Value for ODBC data source attribute',), -(u'ODBCSourceAttribute',u'Attribute',u'N',None, None, None, None, u'Text',None, u'Name of ODBC data source attribute',), -(u'ODBCSourceAttribute',u'DataSource_',u'N',None, None, u'ODBCDataSource',1,u'Identifier',None, u'Reference to ODBC data source in ODBCDataSource table',), -(u'ODBCTranslator',u'Description',u'N',None, None, None, None, u'Text',None, u'Text used as registered name for translator',), -(u'ODBCTranslator',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Reference to key translator file',), -(u'ODBCTranslator',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Reference to associated component',), -(u'ODBCTranslator',u'File_Setup',u'Y',None, None, u'File',1,u'Identifier',None, u'Optional reference to key translator setup DLL',), -(u'ODBCTranslator',u'Translator',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized.internal token for translator',), -(u'Patch',u'Sequence',u'N',0,32767,None, None, None, None, u'Primary key, sequence with respect to the media images; order must track cabinet order.',), -(u'Patch',u'Attributes',u'N',0,32767,None, None, None, None, u'Integer containing bit flags representing patch attributes',), -(u'Patch',u'File_',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token, foreign key to File table, must match identifier in cabinet.',), -(u'Patch',u'Header',u'Y',None, None, None, None, u'Binary',None, u'Binary stream. The patch header, used for patch validation.',), -(u'Patch',u'PatchSize',u'N',0,2147483647,None, None, None, None, u'Size of patch in bytes (long integer).',), -(u'Patch',u'StreamRef_',u'Y',None, None, None, None, u'Identifier',None, u'Identifier. Foreign key to the StreamRef column of the MsiPatchHeaders table.',), -(u'PatchPackage',u'Media_',u'N',0,32767,None, None, None, None, u'Foreign key to DiskId column of Media table. Indicates the disk containing the patch package.',), -(u'PatchPackage',u'PatchId',u'N',None, None, None, None, u'Guid',None, u'A unique string GUID representing this patch.',), -(u'PublishComponent',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Foreign key into the Feature table.',), -(u'PublishComponent',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table.',), -(u'PublishComponent',u'ComponentId',u'N',None, None, None, None, u'Guid',None, u'A string GUID that represents the component id that will be requested by the alien product.',), -(u'PublishComponent',u'AppData',u'Y',None, None, None, None, u'Text',None, u'This is localisable Application specific data that can be associated with a Qualified Component.',), -(u'PublishComponent',u'Qualifier',u'N',None, None, None, None, u'Text',None, u'This is defined only when the ComponentId column is an Qualified Component Id. This is the Qualifier for ProvideComponentIndirect.',), -(u'RadioButton',u'Y',u'N',0,32767,None, None, None, None, u'The vertical coordinate of the upper left corner of the bounding rectangle of the radio button.',), -(u'RadioButton',u'Text',u'Y',None, None, None, None, u'Text',None, u'The visible title to be assigned to the radio button.',), -(u'RadioButton',u'Property',u'N',None, None, None, None, u'Identifier',None, u'A named property to be tied to this radio button. All the buttons tied to the same property become part of the same group.',), -(u'RadioButton',u'Height',u'N',0,32767,None, None, None, None, u'The height of the button.',), -(u'RadioButton',u'Width',u'N',0,32767,None, None, None, None, u'The width of the button.',), -(u'RadioButton',u'X',u'N',0,32767,None, None, None, None, u'The horizontal coordinate of the upper left corner of the bounding rectangle of the radio button.',), -(u'RadioButton',u'Value',u'N',None, None, None, None, u'Formatted',None, u'The value string associated with this button. Selecting the button will set the associated property to this value.',), -(u'RadioButton',u'Order',u'N',1,32767,None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.',), -(u'RadioButton',u'Help',u'Y',None, None, None, None, u'Text',None, u'The help strings used with the button. The text is optional.',), -(u'Registry',u'Name',u'Y',None, None, None, None, u'Formatted',None, u'The registry value name.',), -(u'Registry',u'Value',u'Y',None, None, None, None, u'Formatted',None, u'The registry value.',), -(u'Registry',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table referencing component that controls the installing of the registry value.',), -(u'Registry',u'Key',u'N',None, None, None, None, u'RegPath',None, u'The key for the registry value.',), -(u'Registry',u'Registry',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',), -(u'Registry',u'Root',u'N',-1,3,None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum.',), -(u'RegLocator',u'Name',u'Y',None, None, None, None, u'Formatted',None, u'The registry value name.',), -(u'RegLocator',u'Type',u'Y',0,18,None, None, None, None, u'An integer value that determines if the registry value is a filename or a directory location or to be used as is w/o interpretation.',), -(u'RegLocator',u'Signature_',u'N',None, None, None, None, u'Identifier',None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table. If the type is 0, the registry values refers a directory, and _Signature is not a foreign key.',), -(u'RegLocator',u'Key',u'N',None, None, None, None, u'RegPath',None, u'The key for the registry value.',), -(u'RegLocator',u'Root',u'N',0,3,None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum.',), -(u'RemoveFile',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key referencing Component that controls the file to be removed.',), -(u'RemoveFile',u'FileKey',u'N',None, None, None, None, u'Identifier',None, u'Primary key used to identify a particular file entry',), -(u'RemoveFile',u'FileName',u'Y',None, None, None, None, u'WildCardFilename',None, u'Name of the file to be removed.',), -(u'RemoveFile',u'DirProperty',u'N',None, None, None, None, u'Identifier',None, u'Name of a property whose value is assumed to resolve to the full pathname to the folder of the file to be removed.',), -(u'RemoveFile',u'InstallMode',u'N',None, None, None, None, None, u'1;2;3',u'Installation option, one of iimEnum.',), -(u'RemoveIniFile',u'Action',u'N',None, None, None, None, None, u'2;4',u'The type of modification to be made, one of iifEnum.',), -(u'RemoveIniFile',u'Value',u'Y',None, None, None, None, u'Formatted',None, u'The value to be deleted. The value is required when Action is iifIniRemoveTag',), -(u'RemoveIniFile',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table referencing component that controls the deletion of the .INI value.',), -(u'RemoveIniFile',u'FileName',u'N',None, None, None, None, u'Filename',None, u'The .INI file name in which to delete the information',), -(u'RemoveIniFile',u'DirProperty',u'Y',None, None, None, None, u'Identifier',None, u'Foreign key into the Directory table denoting the directory where the .INI file is.',), -(u'RemoveIniFile',u'Key',u'N',None, None, None, None, u'Formatted',None, u'The .INI file key below Section.',), -(u'RemoveIniFile',u'Section',u'N',None, None, None, None, u'Formatted',None, u'The .INI file Section.',), -(u'RemoveIniFile',u'RemoveIniFile',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',), -(u'RemoveRegistry',u'Name',u'Y',None, None, None, None, u'Formatted',None, u'The registry value name.',), -(u'RemoveRegistry',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table referencing component that controls the deletion of the registry value.',), -(u'RemoveRegistry',u'Key',u'N',None, None, None, None, u'RegPath',None, u'The key for the registry value.',), -(u'RemoveRegistry',u'Root',u'N',-1,3,None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum',), -(u'RemoveRegistry',u'RemoveRegistry',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',), -(u'ReserveCost',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Reserve a specified amount of space if this component is to be installed.',), -(u'ReserveCost',u'ReserveFolder',u'Y',None, None, None, None, u'Identifier',None, u'Name of a property whose value is assumed to resolve to the full path to the destination directory',), -(u'ReserveCost',u'ReserveKey',u'N',None, None, None, None, u'Identifier',None, u'Primary key that uniquely identifies a particular ReserveCost record',), -(u'ReserveCost',u'ReserveLocal',u'N',0,2147483647,None, None, None, None, u'Disk space to reserve if linked component is installed locally.',), -(u'ReserveCost',u'ReserveSource',u'N',0,2147483647,None, None, None, None, u'Disk space to reserve if linked component is installed to run from the source location.',), -(u'SelfReg',u'File_',u'N',None, None, u'File',1,u'Identifier',None, u'Foreign key into the File table denoting the module that needs to be registered.',), -(u'SelfReg',u'Cost',u'Y',0,32767,None, None, None, None, u'The cost of registering the module.',), -(u'ServiceControl',u'Name',u'N',None, None, None, None, u'Formatted',None, u'Name of a service. /, \\, comma and space are invalid',), -(u'ServiceControl',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Required foreign key into the Component Table that controls the startup of the service',), -(u'ServiceControl',u'Event',u'N',0,187,None, None, None, None, u'Bit field: Install: 0x1 = Start, 0x2 = Stop, 0x8 = Delete, Uninstall: 0x10 = Start, 0x20 = Stop, 0x80 = Delete',), -(u'ServiceControl',u'ServiceControl',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',), -(u'ServiceControl',u'Arguments',u'Y',None, None, None, None, u'Formatted',None, u'Arguments for the service. Separate by [~].',), -(u'ServiceControl',u'Wait',u'Y',0,1,None, None, None, None, u'Boolean for whether to wait for the service to fully start',), -(u'ServiceInstall',u'Name',u'N',None, None, None, None, u'Formatted',None, u'Internal Name of the Service',), -(u'ServiceInstall',u'Description',u'Y',None, None, None, None, u'Text',None, u'Description of service.',), -(u'ServiceInstall',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Required foreign key into the Component Table that controls the startup of the service',), -(u'ServiceInstall',u'Arguments',u'Y',None, None, None, None, u'Formatted',None, u'Arguments to include in every start of the service, passed to WinMain',), -(u'ServiceInstall',u'ServiceInstall',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',), -(u'ServiceInstall',u'Dependencies',u'Y',None, None, None, None, u'Formatted',None, u'Other services this depends on to start. Separate by [~], and end with [~][~]',), -(u'ServiceInstall',u'DisplayName',u'Y',None, None, None, None, u'Formatted',None, u'External Name of the Service',), -(u'ServiceInstall',u'ErrorControl',u'N',-2147483647,2147483647,None, None, None, None, u'Severity of error if service fails to start',), -(u'ServiceInstall',u'LoadOrderGroup',u'Y',None, None, None, None, u'Formatted',None, u'LoadOrderGroup',), -(u'ServiceInstall',u'Password',u'Y',None, None, None, None, u'Formatted',None, u'password to run service with. (with StartName)',), -(u'ServiceInstall',u'ServiceType',u'N',-2147483647,2147483647,None, None, None, None, u'Type of the service',), -(u'ServiceInstall',u'StartName',u'Y',None, None, None, None, u'Formatted',None, u'User or object name to run service as',), -(u'ServiceInstall',u'StartType',u'N',0,4,None, None, None, None, u'Type of the service',), -(u'Shortcut',u'Name',u'N',None, None, None, None, u'Filename',None, u'The name of the shortcut to be created.',), -(u'Shortcut',u'Description',u'Y',None, None, None, None, u'Text',None, u'The description for the shortcut.',), -(u'Shortcut',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Foreign key into the Component table denoting the component whose selection gates the shortcut creation/deletion.',), -(u'Shortcut',u'Icon_',u'Y',None, None, u'Icon',1,u'Identifier',None, u'Foreign key into the File table denoting the external icon file for the shortcut.',), -(u'Shortcut',u'IconIndex',u'Y',-32767,32767,None, None, None, None, u'The icon index for the shortcut.',), -(u'Shortcut',u'Directory_',u'N',None, None, u'Directory',1,u'Identifier',None, u'Foreign key into the Directory table denoting the directory where the shortcut file is created.',), -(u'Shortcut',u'Target',u'N',None, None, None, None, u'Shortcut',None, u'The shortcut target. This is usually a property that is expanded to a file or a folder that the shortcut points to.',), -(u'Shortcut',u'Arguments',u'Y',None, None, None, None, u'Formatted',None, u'The command-line arguments for the shortcut.',), -(u'Shortcut',u'Shortcut',u'N',None, None, None, None, u'Identifier',None, u'Primary key, non-localized token.',), -(u'Shortcut',u'Hotkey',u'Y',0,32767,None, None, None, None, u'The hotkey for the shortcut. It has the virtual-key code for the key in the low-order byte, and the modifier flags in the high-order byte. ',), -(u'Shortcut',u'ShowCmd',u'Y',None, None, None, None, None, u'1;3;7',u'The show command for the application window.The following values may be used.',), -(u'Shortcut',u'WkDir',u'Y',None, None, None, None, u'Identifier',None, u'Name of property defining location of working directory.',), -(u'Signature',u'FileName',u'N',None, None, None, None, u'Filename',None, u'The name of the file. This may contain a "short name|long name" pair.',), -(u'Signature',u'Signature',u'N',None, None, None, None, u'Identifier',None, u'The table key. The Signature represents a unique file signature.',), -(u'Signature',u'Languages',u'Y',None, None, None, None, u'Language',None, u'The languages supported by the file.',), -(u'Signature',u'MaxDate',u'Y',0,2147483647,None, None, None, None, u'The maximum creation date of the file.',), -(u'Signature',u'MaxSize',u'Y',0,2147483647,None, None, None, None, u'The maximum size of the file. ',), -(u'Signature',u'MaxVersion',u'Y',None, None, None, None, u'Text',None, u'The maximum version of the file.',), -(u'Signature',u'MinDate',u'Y',0,2147483647,None, None, None, None, u'The minimum creation date of the file.',), -(u'Signature',u'MinSize',u'Y',0,2147483647,None, None, None, None, u'The minimum size of the file.',), -(u'Signature',u'MinVersion',u'Y',None, None, None, None, u'Text',None, u'The minimum version of the file.',), -(u'TextStyle',u'TextStyle',u'N',None, None, None, None, u'Identifier',None, u'Name of the style. The primary key of this table. This name is embedded in the texts to indicate a style change.',), -(u'TextStyle',u'Color',u'Y',0,16777215,None, None, None, None, u'A long integer indicating the color of the string in the RGB format (Red, Green, Blue each 0-255, RGB = R + 256*G + 256^2*B).',), -(u'TextStyle',u'FaceName',u'N',None, None, None, None, u'Text',None, u'A string indicating the name of the font used. Required. The string must be at most 31 characters long.',), -(u'TextStyle',u'Size',u'N',0,32767,None, None, None, None, u'The size of the font used. This size is given in our units (1/12 of the system font height). Assuming that the system font is set to 12 point size, this is equivalent to the point size.',), -(u'TextStyle',u'StyleBits',u'Y',0,15,None, None, None, None, u'A combination of style bits.',), -(u'TypeLib',u'Description',u'Y',None, None, None, None, u'Text',None, None, ), -(u'TypeLib',u'Feature_',u'N',None, None, u'Feature',1,u'Identifier',None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the type library to be operational.',), -(u'TypeLib',u'Component_',u'N',None, None, u'Component',1,u'Identifier',None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.',), -(u'TypeLib',u'Directory_',u'Y',None, None, u'Directory',1,u'Identifier',None, u'Optional. The foreign key into the Directory table denoting the path to the help file for the type library.',), -(u'TypeLib',u'Language',u'N',0,32767,None, None, None, None, u'The language of the library.',), -(u'TypeLib',u'Version',u'Y',0,16777215,None, None, None, None, u'The version of the library. The minor version is in the lower 8 bits of the integer. The major version is in the next 16 bits. ',), -(u'TypeLib',u'Cost',u'Y',0,2147483647,None, None, None, None, u'The cost associated with the registration of the typelib. This column is currently optional.',), -(u'TypeLib',u'LibID',u'N',None, None, None, None, u'Guid',None, u'The GUID that represents the library.',), -(u'UIText',u'Text',u'Y',None, None, None, None, u'Text',None, u'The localized version of the string.',), -(u'UIText',u'Key',u'N',None, None, None, None, u'Identifier',None, u'A unique key that identifies the particular string.',), -(u'Upgrade',u'Attributes',u'N',0,2147483647,None, None, None, None, u'The attributes of this product set.',), -(u'Upgrade',u'Language',u'Y',None, None, None, None, u'Language',None, u'A comma-separated list of languages for either products in this set or products not in this set.',), -(u'Upgrade',u'ActionProperty',u'N',None, None, None, None, u'UpperCase',None, u'The property to set when a product in this set is found.',), -(u'Upgrade',u'Remove',u'Y',None, None, None, None, u'Formatted',None, u'The list of features to remove when uninstalling a product from this set. The default is "ALL".',), -(u'Upgrade',u'UpgradeCode',u'N',None, None, None, None, u'Guid',None, u'The UpgradeCode GUID belonging to the products in this set.',), -(u'Upgrade',u'VersionMax',u'Y',None, None, None, None, u'Text',None, u'The maximum ProductVersion of the products in this set. The set may or may not include products with this particular version.',), -(u'Upgrade',u'VersionMin',u'Y',None, None, None, None, u'Text',None, u'The minimum ProductVersion of the products in this set. The set may or may not include products with this particular version.',), -(u'Verb',u'Sequence',u'Y',0,32767,None, None, None, None, u'Order within the verbs for a particular extension. Also used simply to specify the default verb.',), -(u'Verb',u'Argument',u'Y',None, None, None, None, u'Formatted',None, u'Optional value for the command arguments.',), -(u'Verb',u'Extension_',u'N',None, None, u'Extension',1,u'Text',None, u'The extension associated with the table row.',), -(u'Verb',u'Verb',u'N',None, None, None, None, u'Text',None, u'The verb for the command.',), -(u'Verb',u'Command',u'Y',None, None, None, None, u'Formatted',None, u'The command text.',), -] diff --git a/Tools/msi/sequence.py b/Tools/msi/sequence.py deleted file mode 100644 index 1138f7a2345b..000000000000 --- a/Tools/msi/sequence.py +++ /dev/null @@ -1,126 +0,0 @@ -AdminExecuteSequence = [ -(u'InstallInitialize', None, 1500), -(u'InstallFinalize', None, 6600), -(u'InstallFiles', None, 4000), -(u'InstallAdminPackage', None, 3900), -(u'FileCost', None, 900), -(u'CostInitialize', None, 800), -(u'CostFinalize', None, 1000), -(u'InstallValidate', None, 1400), -] - -AdminUISequence = [ -(u'FileCost', None, 900), -(u'CostInitialize', None, 800), -(u'CostFinalize', None, 1000), -(u'ExecuteAction', None, 1300), -(u'ExitDialog', None, -1), -(u'FatalError', None, -3), -(u'UserExit', None, -2), -] - -AdvtExecuteSequence = [ -(u'InstallInitialize', None, 1500), -(u'InstallFinalize', None, 6600), -(u'CostInitialize', None, 800), -(u'CostFinalize', None, 1000), -(u'InstallValidate', None, 1400), -(u'CreateShortcuts', None, 4500), -(u'MsiPublishAssemblies', None, 6250), -(u'PublishComponents', None, 6200), -(u'PublishFeatures', None, 6300), -(u'PublishProduct', None, 6400), -(u'RegisterClassInfo', None, 4600), -(u'RegisterExtensionInfo', None, 4700), -(u'RegisterMIMEInfo', None, 4900), -(u'RegisterProgIdInfo', None, 4800), -] - -InstallExecuteSequence = [ -(u'InstallInitialize', None, 1500), -(u'InstallFinalize', None, 6600), -(u'InstallFiles', None, 4000), -(u'FileCost', None, 900), -(u'CostInitialize', None, 800), -(u'CostFinalize', None, 1000), -(u'InstallValidate', None, 1400), -(u'CreateShortcuts', None, 4500), -(u'MsiPublishAssemblies', None, 6250), -(u'PublishComponents', None, 6200), -(u'PublishFeatures', None, 6300), -(u'PublishProduct', None, 6400), -(u'RegisterClassInfo', None, 4600), -(u'RegisterExtensionInfo', None, 4700), -(u'RegisterMIMEInfo', None, 4900), -(u'RegisterProgIdInfo', None, 4800), -(u'AllocateRegistrySpace', u'NOT Installed', 1550), -(u'AppSearch', None, 400), -(u'BindImage', None, 4300), -(u'CCPSearch', u'NOT Installed', 500), -(u'CreateFolders', None, 3700), -(u'DeleteServices', u'VersionNT', 2000), -(u'DuplicateFiles', None, 4210), -(u'FindRelatedProducts', None, 200), -(u'InstallODBC', None, 5400), -(u'InstallServices', u'VersionNT', 5800), -(u'IsolateComponents', None, 950), -(u'LaunchConditions', None, 100), -(u'MigrateFeatureStates', None, 1200), -(u'MoveFiles', None, 3800), -(u'PatchFiles', None, 4090), -(u'ProcessComponents', None, 1600), -(u'RegisterComPlus', None, 5700), -(u'RegisterFonts', None, 5300), -(u'RegisterProduct', None, 6100), -(u'RegisterTypeLibraries', None, 5500), -(u'RegisterUser', None, 6000), -(u'RemoveDuplicateFiles', None, 3400), -(u'RemoveEnvironmentStrings', None, 3300), -(u'RemoveExistingProducts', None, 6700), -(u'RemoveFiles', None, 3500), -(u'RemoveFolders', None, 3600), -(u'RemoveIniValues', None, 3100), -(u'RemoveODBC', None, 2400), -(u'RemoveRegistryValues', None, 2600), -(u'RemoveShortcuts', None, 3200), -(u'RMCCPSearch', u'NOT Installed', 600), -(u'SelfRegModules', None, 5600), -(u'SelfUnregModules', None, 2200), -(u'SetODBCFolders', None, 1100), -(u'StartServices', u'VersionNT', 5900), -(u'StopServices', u'VersionNT', 1900), -(u'MsiUnpublishAssemblies', None, 1750), -(u'UnpublishComponents', None, 1700), -(u'UnpublishFeatures', None, 1800), -(u'UnregisterClassInfo', None, 2700), -(u'UnregisterComPlus', None, 2100), -(u'UnregisterExtensionInfo', None, 2800), -(u'UnregisterFonts', None, 2500), -(u'UnregisterMIMEInfo', None, 3000), -(u'UnregisterProgIdInfo', None, 2900), -(u'UnregisterTypeLibraries', None, 2300), -(u'ValidateProductID', None, 700), -(u'WriteEnvironmentStrings', None, 5200), -(u'WriteIniValues', None, 5100), -(u'WriteRegistryValues', None, 5000), -] - -InstallUISequence = [ -(u'FileCost', None, 900), -(u'CostInitialize', None, 800), -(u'CostFinalize', None, 1000), -(u'ExecuteAction', None, 1300), -(u'ExitDialog', None, -1), -(u'FatalError', None, -3), -(u'UserExit', None, -2), -(u'AppSearch', None, 400), -(u'CCPSearch', u'NOT Installed', 500), -(u'FindRelatedProducts', None, 200), -(u'IsolateComponents', None, 950), -(u'LaunchConditions', None, 100), -(u'MigrateFeatureStates', None, 1200), -(u'RMCCPSearch', u'NOT Installed', 600), -(u'ValidateProductID', None, 700), -] - -tables=['AdminExecuteSequence', 'AdminUISequence', 'AdvtExecuteSequence', 'InstallExecuteSequence', 'InstallUISequence'] diff --git a/Tools/msi/tcltk/tcltk.wixproj b/Tools/msi/tcltk/tcltk.wixproj new file mode 100644 index 000000000000..f66fc149884f --- /dev/null +++ b/Tools/msi/tcltk/tcltk.wixproj @@ -0,0 +1,50 @@ + + + + {DB350600-186C-4E52-BA98-26A7CECB067F} + 2.0 + tcltk + Package + + + + ICE43 + + + + + + + + + + + + + $(tcltkDir) + !(bindpath.tcltk) + $(tcltkDir)bin + DLLs\ + tcltk_dlls + + + + $(tcltkDir) + !(bindpath.tcltk) + $(tcltkDir)lib + tcl\ + tcltk_lib + + + + $(PySourcePath) + !(bindpath.src) + $(PySourcePath) + + tkinter_lib + + + + + \ No newline at end of file diff --git a/Tools/msi/tcltk/tcltk.wxs b/Tools/msi/tcltk/tcltk.wxs new file mode 100644 index 000000000000..0b83c5cb5c05 --- /dev/null +++ b/Tools/msi/tcltk/tcltk.wxs @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + PYTHON_EXE and PYTHONW_EXE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/tcltk/tcltk_d.wixproj b/Tools/msi/tcltk/tcltk_d.wixproj new file mode 100644 index 000000000000..3266190da0c9 --- /dev/null +++ b/Tools/msi/tcltk/tcltk_d.wixproj @@ -0,0 +1,28 @@ + + + + {EDA1FA5A-E2AA-4EAF-B49B-87D981CD0F16} + 2.0 + tcltk_d + Package + + + + + + + + + + + + $(tcltkDir) + !(bindpath.tcltk) + $(tcltkDir)bin + DLLs\ + tcltk_dlls_d + + + + + \ No newline at end of file diff --git a/Tools/msi/tcltk/tcltk_d.wxs b/Tools/msi/tcltk/tcltk_d.wxs new file mode 100644 index 000000000000..01d0d2439ddc --- /dev/null +++ b/Tools/msi/tcltk/tcltk_d.wxs @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/Tools/msi/tcltk/tcltk_en-US.wxl_template b/Tools/msi/tcltk/tcltk_en-US.wxl_template new file mode 100644 index 000000000000..f40fd6239dea --- /dev/null +++ b/Tools/msi/tcltk/tcltk_en-US.wxl_template @@ -0,0 +1,12 @@ + + + Tcl/Tk Support + tcltk + No !(loc.ProductName) installation was detected. + IDLE (Python {{ShortVersion}} {{Bitness}}) + Launches IDLE, the interactive environment for !(loc.ProductName). + Python {{ShortVersion}} Module Docs ({{Bitness}}) + Start the !(loc.ProductName) documentation server. + &Edit with IDLE + Edit with IDLE {{ShortVersion}} ({{Bitness}}) + diff --git a/Tools/msi/tcltk/tcltk_files.wxs b/Tools/msi/tcltk/tcltk_files.wxs new file mode 100644 index 000000000000..0d1b4a93a3a4 --- /dev/null +++ b/Tools/msi/tcltk/tcltk_files.wxs @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/tcltk/tcltk_pdb.wixproj b/Tools/msi/tcltk/tcltk_pdb.wixproj new file mode 100644 index 000000000000..3370798a0559 --- /dev/null +++ b/Tools/msi/tcltk/tcltk_pdb.wixproj @@ -0,0 +1,19 @@ + + + + {02053AFA-1831-499A-B3EA-D8B223D3C40D} + 2.0 + tcltk_pdb + Package + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/tcltk/tcltk_pdb.wxs b/Tools/msi/tcltk/tcltk_pdb.wxs new file mode 100644 index 000000000000..04454f3849fc --- /dev/null +++ b/Tools/msi/tcltk/tcltk_pdb.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tools/msi/tcltk/tcltk_reg.wxs b/Tools/msi/tcltk/tcltk_reg.wxs new file mode 100644 index 000000000000..e09892747ecf --- /dev/null +++ b/Tools/msi/tcltk/tcltk_reg.wxs @@ -0,0 +1,48 @@ + + + + + + + VersionNT > 600 + + + + + VersionNT > 600 + + + + + + VersionNT > 600 + + + + + + + VersionNT > 600 + + + + + + + + VersionNT = 600 + + + + + + + VersionNT = 600 + + + + + + + + diff --git a/Tools/msi/test/test.wixproj b/Tools/msi/test/test.wixproj new file mode 100644 index 000000000000..8347e3f1d3db --- /dev/null +++ b/Tools/msi/test/test.wixproj @@ -0,0 +1,29 @@ + + + + {DE0B7CC2-4358-4131-B3F4-C31C7F2CD468} + 2.0 + test + Package + + + + + + + + + + + + $(PySourcePath) + !(bindpath.src) + $(PySourcePath) + + test_py + + + + + \ No newline at end of file diff --git a/Tools/msi/test/test.wxs b/Tools/msi/test/test.wxs new file mode 100644 index 000000000000..f2ed64f07bf2 --- /dev/null +++ b/Tools/msi/test/test.wxs @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/Tools/msi/test/test_d.wixproj b/Tools/msi/test/test_d.wixproj new file mode 100644 index 000000000000..33b04be1fe60 --- /dev/null +++ b/Tools/msi/test/test_d.wixproj @@ -0,0 +1,19 @@ + + + + {41F5AE8D-24CD-4D03-BE75-AA6F7FAB4097} + 2.0 + test_d + Package + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/test/test_d.wxs b/Tools/msi/test/test_d.wxs new file mode 100644 index 000000000000..a954876755c4 --- /dev/null +++ b/Tools/msi/test/test_d.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tools/msi/test/test_en-US.wxl b/Tools/msi/test/test_en-US.wxl new file mode 100644 index 000000000000..e615c7a6b7f7 --- /dev/null +++ b/Tools/msi/test/test_en-US.wxl @@ -0,0 +1,7 @@ + + + Test Suite + test + !(loc.FullProductName) native libtest + !(loc.ProductName) Native Test Modules + diff --git a/Tools/msi/test/test_files.wxs b/Tools/msi/test/test_files.wxs new file mode 100644 index 000000000000..e803aa0f5541 --- /dev/null +++ b/Tools/msi/test/test_files.wxs @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/test/test_pdb.wixproj b/Tools/msi/test/test_pdb.wixproj new file mode 100644 index 000000000000..965f0edd9b49 --- /dev/null +++ b/Tools/msi/test/test_pdb.wixproj @@ -0,0 +1,19 @@ + + + + {7CF48ADD-CFAA-499F-9A05-BA18440A3344} + 2.0 + test_pdb + Package + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/msi/test/test_pdb.wxs b/Tools/msi/test/test_pdb.wxs new file mode 100644 index 000000000000..de634a390bab --- /dev/null +++ b/Tools/msi/test/test_pdb.wxs @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tools/msi/testrelease.bat b/Tools/msi/testrelease.bat new file mode 100644 index 000000000000..a989575ed6f0 --- /dev/null +++ b/Tools/msi/testrelease.bat @@ -0,0 +1,117 @@ +@setlocal enableextensions +@echo off + +set D=%~dp0 +set PCBUILD=%D%..\..\PCBuild\ + +set TARGETDIR=%TEMP% +set TESTX86= +set TESTX64= +set TESTALLUSER= +set TESTPERUSER= + +:CheckOpts +if "%1" EQU "-h" goto Help +if "%1" EQU "-x86" (set TESTX86=1) && shift && goto CheckOpts +if "%1" EQU "-x64" (set TESTX64=1) && shift && goto CheckOpts +if "%1" EQU "-t" (set TARGETDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--target" (set TARGETDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-a" (set TESTALLUSER=1) && shift && goto CheckOpts +if "%1" EQU "--alluser" (set TESTALLUSER=1) && shift && goto CheckOpts +if "%1" EQU "-p" (set TESTPERUSER=1) && shift && goto CheckOpts +if "%1" EQU "--peruser" (set TESTPERUSER=1) && shift && goto CheckOpts + +if not defined TESTX86 if not defined TESTX64 (set TESTX86=1) && (set TESTX64=1) +if not defined TESTALLUSER if not defined TESTPERUSER (set TESTALLUSER=1) && (set TESTPERUSER=1) + + +if defined TESTX86 ( + for %%f in ("%PCBUILD%win32\en-us\*.exe") do ( + if defined TESTALLUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-alluser" "InstallAllUsers=1 CompileAll=1" + if errorlevel 1 exit /B + if defined TESTPERUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-peruser" "InstallAllUsers=0 CompileAll=0" + if errorlevel 1 exit /B + ) +) + +if defined TESTX64 ( + for %%f in ("%PCBUILD%amd64\en-us\*.exe") do ( + if defined TESTALLUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-alluser" "InstallAllUsers=1 CompileAll=1" + if errorlevel 1 exit /B + if defined TESTPERUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-peruser" "InstallAllUsers=0 CompileAll=0" + if errorlevel 1 exit /B + ) +) + +exit /B 0 + +:test +@setlocal +@echo on + +@if not exist "%~1" exit /B 1 + +@set EXE=%~1 +@if not "%EXE:embed=%"=="%EXE%" exit /B 0 + +@set EXITCODE=0 +@echo Installing %1 into %2 +"%~1" /passive /log "%~2\install\log.txt" TargetDir="%~2\Python" Include_debug=1 Include_symbols=1 %~3 + +@if not errorlevel 1 ( + @echo Printing version + "%~2\Python\python.exe" -c "import sys; print(sys.version)" > "%~2\version.txt" 2>&1 +) + +@if not errorlevel 1 ( + @echo Capturing Start Menu + @dir /s/b "%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs" | findstr /ic:"python" > "%~2\startmenu.txt" 2>&1 + @dir /s/b "%APPDATA%\Microsoft\Windows\Start Menu\Programs" | findstr /ic:"python" >> "%~2\startmenu.txt" 2>&1 + + @echo Capturing registry + @for /F "usebackq" %%f in (`reg query HKCR /s /f python /k`) do @( + echo %%f >> "%~2\hkcr.txt" + reg query "%%f" /s >> "%~2\hkcr.txt" 2>&1 + ) + @reg query HKCU\Software\Python /s > "%~2\hkcu.txt" 2>&1 + @reg query HKLM\Software\Python /reg:32 /s > "%~2\hklm.txt" 2>&1 + @reg query HKLM\Software\Python /reg:64 /s >> "%~2\hklm.txt" 2>&1 + cmd /k exit 0 +) + +@if not errorlevel 1 ( + @echo Installing package + "%~2\Python\python.exe" -m pip install "azure<0.10" > "%~2\pip.txt" 2>&1 + @if not errorlevel 1 ( + "%~2\Python\python.exe" -m pip uninstall -y azure python-dateutil six >> "%~2\pip.txt" 2>&1 + ) +) +@if not errorlevel 1 ( + @echo Testing Tcl/tk + @set TCL_LIBRARY=%~2\Python\tcl\tcl8.6 + "%~2\Python\python.exe" -m test -uall -v test_ttk_guionly test_tk test_idle > "%~2\tcltk.txt" 2>&1 + @set TCL_LIBRARY= +) + +@set EXITCODE=%ERRORLEVEL% + +@echo Result was %EXITCODE% +@echo Removing %1 +"%~1" /passive /uninstall /log "%~2\uninstall\log.txt" + +@echo off +exit /B %EXITCODE% + +:Help +echo testrelease.bat [--target TARGET] [-x86] [-x64] [--alluser] [--peruser] [-h] +echo. +echo --target (-t) Specify the target directory for installs and logs +echo -x86 Run tests for x86 installers +echo -x64 Run tests for x64 installers +echo --alluser (-a) Run tests for all-user installs (requires Administrator) +echo --peruser (-p) Run tests for per-user installs +echo -h Display this help information +echo. +echo If no test architecture is specified, all architectures will be tested. +echo If no install type is selected, all install types will be tested. +echo. diff --git a/Tools/msi/tools/tools.wixproj b/Tools/msi/tools/tools.wixproj new file mode 100644 index 000000000000..f43cf3309e9b --- /dev/null +++ b/Tools/msi/tools/tools.wixproj @@ -0,0 +1,43 @@ + + + + {24CBEB95-BC1E-4EA9-AEA9-33834BCCD0EC} + 2.0 + tools + Package + + + + + + + + + + + + + + + $(PySourcePath) + !(bindpath.src) + $(PySourcePath) + + tools_py + + + + + \ No newline at end of file diff --git a/Tools/msi/tools/tools.wxs b/Tools/msi/tools/tools.wxs new file mode 100644 index 000000000000..8f8418a46c2d --- /dev/null +++ b/Tools/msi/tools/tools.wxs @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/Tools/msi/tools/tools_en-US.wxl b/Tools/msi/tools/tools_en-US.wxl new file mode 100644 index 000000000000..a1384177ea26 --- /dev/null +++ b/Tools/msi/tools/tools_en-US.wxl @@ -0,0 +1,5 @@ + + + Utility Scripts + tools + diff --git a/Tools/msi/tools/tools_files.wxs b/Tools/msi/tools/tools_files.wxs new file mode 100644 index 000000000000..3ae0db2e1fd3 --- /dev/null +++ b/Tools/msi/tools/tools_files.wxs @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/Tools/msi/uisample.py b/Tools/msi/uisample.py deleted file mode 100644 index 543080554e87..000000000000 --- a/Tools/msi/uisample.py +++ /dev/null @@ -1,1400 +0,0 @@ - -import msilib,os;dirname=os.path.dirname(__file__) -AdminExecuteSequence = [ -(u'InstallValidate', None, 1400), -(u'InstallInitialize', None, 1500), -(u'InstallFinalize', None, 6600), -(u'InstallFiles', None, 4000), -(u'InstallAdminPackage', None, 3900), -(u'FileCost', None, 900), -(u'CostInitialize', None, 800), -(u'CostFinalize', None, 1000), -] - -AdminUISequence = [ -(u'AdminWelcomeDlg', None, 1230), -(u'FileCost', None, 900), -(u'CostInitialize', None, 800), -(u'CostFinalize', None, 1000), -(u'ExecuteAction', None, 1300), -(u'ExitDialog', None, -1), -(u'FatalError', None, -3), -(u'PrepareDlg', None, 140), -(u'ProgressDlg', None, 1280), -(u'UserExit', None, -2), -] - -AdvtExecuteSequence = [ -(u'InstallValidate', None, 1400), -(u'InstallInitialize', None, 1500), -(u'InstallFinalize', None, 6600), -(u'CostInitialize', None, 800), -(u'CostFinalize', None, 1000), -(u'CreateShortcuts', None, 4500), -(u'PublishComponents', None, 6200), -(u'PublishFeatures', None, 6300), -(u'PublishProduct', None, 6400), -(u'RegisterClassInfo', None, 4600), -(u'RegisterExtensionInfo', None, 4700), -(u'RegisterMIMEInfo', None, 4900), -(u'RegisterProgIdInfo', None, 4800), -] - -BBControl = [ -] - -Billboard = [ -] - -Binary = [ -(u'bannrbmp', msilib.Binary(os.path.join(dirname,"bannrbmp.bin"))), -(u'completi', msilib.Binary(os.path.join(dirname,"completi.bin"))), -(u'custicon', msilib.Binary(os.path.join(dirname,"custicon.bin"))), -(u'dlgbmp', msilib.Binary(os.path.join(dirname,"dlgbmp.bin"))), -(u'exclamic', msilib.Binary(os.path.join(dirname,"exclamic.bin"))), -(u'info', msilib.Binary(os.path.join(dirname,"info.bin"))), -(u'insticon', msilib.Binary(os.path.join(dirname,"insticon.bin"))), -(u'New', msilib.Binary(os.path.join(dirname,"New.bin"))), -(u'removico', msilib.Binary(os.path.join(dirname,"removico.bin"))), -(u'repairic', msilib.Binary(os.path.join(dirname,"repairic.bin"))), -(u'Up', msilib.Binary(os.path.join(dirname,"Up.bin"))), -] - -CheckBox = [ -] - -Property = [ -(u'BannerBitmap', u'bannrbmp'), -(u'IAgree', u'No'), -(u'ProductID', u'none'), -(u'ARPHELPLINK', u'http://www.microsoft.com/management'), -(u'ButtonText_Back', u'< &Back'), -(u'ButtonText_Browse', u'Br&owse'), -(u'ButtonText_Cancel', u'Cancel'), -(u'ButtonText_Exit', u'&Exit'), -(u'ButtonText_Finish', u'&Finish'), -(u'ButtonText_Ignore', u'&Ignore'), -(u'ButtonText_Install', u'&Install'), -(u'ButtonText_Next', u'&Next >'), -(u'ButtonText_No', u'&No'), -(u'ButtonText_OK', u'OK'), -(u'ButtonText_Remove', u'&Remove'), -(u'ButtonText_Repair', u'&Repair'), -(u'ButtonText_Reset', u'&Reset'), -(u'ButtonText_Resume', u'&Resume'), -(u'ButtonText_Retry', u'&Retry'), -(u'ButtonText_Return', u'&Return'), -(u'ButtonText_Yes', u'&Yes'), -(u'CompleteSetupIcon', u'completi'), -(u'ComponentDownload', u'ftp://anonymous@microsoft.com/components/'), -(u'CustomSetupIcon', u'custicon'), -(u'DefaultUIFont', u'DlgFont8'), -(u'DialogBitmap', u'dlgbmp'), -(u'DlgTitleFont', u'{&DlgFontBold8}'), -(u'ErrorDialog', u'ErrorDlg'), -(u'ExclamationIcon', u'exclamic'), -(u'InfoIcon', u'info'), -(u'InstallerIcon', u'insticon'), -(u'INSTALLLEVEL', u'3'), -(u'InstallMode', u'Typical'), -(u'PIDTemplate', u'12345<###-%%%%%%%>@@@@@'), -#(u'ProductLanguage', u'1033'), -(u'Progress1', u'Installing'), -(u'Progress2', u'installs'), -(u'PROMPTROLLBACKCOST', u'P'), -(u'RemoveIcon', u'removico'), -(u'RepairIcon', u'repairic'), -(u'Setup', u'Setup'), -(u'ShowUserRegistrationDlg', u'1'), -(u'Wizard', u'Setup Wizard'), -] - -ComboBox = [ -] - -Control = [ -(u'AdminWelcomeDlg', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None), -(u'AdminWelcomeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'AdminWelcomeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'Bitmap', None), -(u'AdminWelcomeDlg', u'Description', u'Text', 135, 70, 220, 30, 196611, None, u'The [Wizard] will create a server image of [ProductName], at a specified network location. Click Next to continue or Cancel to exit the [Wizard].', None, None), -(u'AdminWelcomeDlg', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}Welcome to the [ProductName] [Wizard]', None, None), -(u'AdminWelcomeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Next', None), -(u'AdminWelcomeDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None), -(u'ExitDialog', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None), -(u'ExitDialog', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'ExitDialog', u'Cancel', u'PushButton', 304, 243, 56, 17, 1, None, u'[ButtonText_Cancel]', u'Bitmap', None), -(u'ExitDialog', u'Description', u'Text', 135, 70, 220, 20, 196611, None, u'Click the Finish button to exit the [Wizard].', None, None), -(u'ExitDialog', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}Completing the [ProductName] [Wizard]', None, None), -(u'ExitDialog', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Finish', None), -(u'ExitDialog', u'Finish', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Finish]', u'Cancel', None), -(u'FatalError', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None), -(u'FatalError', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'FatalError', u'Cancel', u'PushButton', 304, 243, 56, 17, 1, None, u'[ButtonText_Cancel]', u'Bitmap', None), -(u'FatalError', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}[ProductName] [Wizard] ended prematurely', None, None), -(u'FatalError', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Finish', None), -(u'FatalError', u'Finish', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Finish]', u'Cancel', None), -(u'FatalError', u'Description1', u'Text', 135, 70, 220, 40, 196611, None, u'[ProductName] setup ended prematurely because of an error. Your system has not been modified. To install this program at a later time, please run the installation again.', None, None), -(u'FatalError', u'Description2', u'Text', 135, 115, 220, 20, 196611, None, u'Click the Finish button to exit the [Wizard].', None, None), -(u'PrepareDlg', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Cancel', None), -(u'PrepareDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'PrepareDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'Bitmap', None), -(u'PrepareDlg', u'Description', u'Text', 135, 70, 220, 20, 196611, None, u'Please wait while the [Wizard] prepares to guide you through the installation.', None, None), -(u'PrepareDlg', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}Welcome to the [ProductName] [Wizard]', None, None), -(u'PrepareDlg', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', None, None), -(u'PrepareDlg', u'Next', u'PushButton', 236, 243, 56, 17, 1, None, u'[ButtonText_Next]', None, None), -(u'PrepareDlg', u'ActionData', u'Text', 135, 125, 220, 30, 196611, None, None, None, None), -(u'PrepareDlg', u'ActionText', u'Text', 135, 100, 220, 20, 196611, None, None, None, None), -(u'ProgressDlg', u'Text', u'Text', 35, 65, 300, 20, 3, None, u'Please wait while the [Wizard] [Progress2] [ProductName]. This may take several minutes.', None, None), -(u'ProgressDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Back', None), -(u'ProgressDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'ProgressDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'ProgressDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'ProgressDlg', u'Title', u'Text', 20, 15, 200, 15, 196611, None, u'[DlgTitleFont][Progress1] [ProductName]', None, None), -(u'ProgressDlg', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Next', None), -(u'ProgressDlg', u'Next', u'PushButton', 236, 243, 56, 17, 1, None, u'[ButtonText_Next]', u'Cancel', None), -(u'ProgressDlg', u'ActionText', u'Text', 70, 100, 265, 10, 3, None, None, None, None), -(u'ProgressDlg', u'ProgressBar', u'ProgressBar', 35, 115, 300, 10, 65537, None, u'Progress done', None, None), -(u'ProgressDlg', u'StatusLabel', u'Text', 35, 100, 35, 10, 3, None, u'Status:', None, None), -(u'UserExit', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None), -(u'UserExit', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'UserExit', u'Cancel', u'PushButton', 304, 243, 56, 17, 1, None, u'[ButtonText_Cancel]', u'Bitmap', None), -(u'UserExit', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}[ProductName] [Wizard] was interrupted', None, None), -(u'UserExit', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Finish', None), -(u'UserExit', u'Finish', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Finish]', u'Cancel', None), -(u'UserExit', u'Description1', u'Text', 135, 70, 220, 40, 196611, None, u'[ProductName] setup was interrupted. Your system has not been modified. To install this program at a later time, please run the installation again.', None, None), -(u'UserExit', u'Description2', u'Text', 135, 115, 220, 20, 196611, None, u'Click the Finish button to exit the [Wizard].', None, None), -(u'AdminBrowseDlg', u'Up', u'PushButton', 298, 55, 19, 19, 3670019, None, u'Up', u'NewFolder', u'Up One Level|'), -(u'AdminBrowseDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'PathEdit', None), -(u'AdminBrowseDlg', u'PathEdit', u'PathEdit', 84, 202, 261, 17, 3, u'TARGETDIR', None, u'OK', None), -(u'AdminBrowseDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'AdminBrowseDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'AdminBrowseDlg', u'Cancel', u'PushButton', 240, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'ComboLabel', None), -(u'AdminBrowseDlg', u'ComboLabel', u'Text', 25, 58, 44, 10, 3, None, u'&Look in:', u'DirectoryCombo', None), -(u'AdminBrowseDlg', u'DirectoryCombo', u'DirectoryCombo', 70, 55, 220, 80, 458755, u'TARGETDIR', None, u'Up', None), -(u'AdminBrowseDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Browse to the destination folder', None, None), -(u'AdminBrowseDlg', u'DirectoryList', u'DirectoryList', 25, 83, 320, 110, 7, u'TARGETDIR', None, u'PathLabel', None), -(u'AdminBrowseDlg', u'PathLabel', u'Text', 25, 205, 59, 10, 3, None, u'&Folder name:', u'BannerBitmap', None), -(u'AdminBrowseDlg', u'NewFolder', u'PushButton', 325, 55, 19, 19, 3670019, None, u'New', u'DirectoryList', u'Create A New Folder|'), -(u'AdminBrowseDlg', u'OK', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_OK]', u'Cancel', None), -(u'AdminBrowseDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Change current destination folder', None, None), -(u'AdminInstallPointDlg', u'Text', u'Text', 25, 80, 320, 10, 3, None, u'&Enter a new network location or click Browse to browse to one.', u'PathEdit', None), -(u'AdminInstallPointDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Text', None), -(u'AdminInstallPointDlg', u'PathEdit', u'PathEdit', 25, 93, 320, 18, 3, u'TARGETDIR', None, u'Browse', None), -(u'AdminInstallPointDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'AdminInstallPointDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'AdminInstallPointDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'AdminInstallPointDlg', u'Description', u'Text', 25, 20, 280, 20, 196611, None, u'Please specify a network location for the server image of [ProductName] product', None, None), -(u'AdminInstallPointDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Network Location', None, None), -(u'AdminInstallPointDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Next', None), -(u'AdminInstallPointDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None), -(u'AdminInstallPointDlg', u'Browse', u'PushButton', 289, 119, 56, 17, 3, None, u'[ButtonText_Browse]', u'Back', None), -(u'AdminRegistrationDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'OrganizationLabel', None), -(u'AdminRegistrationDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'AdminRegistrationDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'AdminRegistrationDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'AdminRegistrationDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Please enter your company information', None, None), -(u'AdminRegistrationDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Company Information', None, None), -(u'AdminRegistrationDlg', u'Back', u'PushButton', 180, 243, 56, 17, 65539, None, u'[ButtonText_Back]', u'Next', None), -(u'AdminRegistrationDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None), -(u'AdminRegistrationDlg', u'OrganizationLabel', u'Text', 45, 71, 285, 30, 3, None, u'&Please enter the name of your organization in the box below. This will be used as default company name for subsequent installations of [ProductName]:', u'OrganizationEdit', None), -(u'AdminRegistrationDlg', u'CDKeyEdit', u'MaskedEdit', 45, 143, 250, 16, 3, u'PIDKEY', u'[PIDTemplate]', u'Back', None), -(u'AdminRegistrationDlg', u'CDKeyLabel', u'Text', 45, 130, 50, 10, 3, None, u'CD &Key:', u'CDKeyEdit', None), -(u'AdminRegistrationDlg', u'OrganizationEdit', u'Edit', 45, 105, 220, 18, 3, u'COMPANYNAME', u'{80}', u'CDKeyLabel', None), -(u'BrowseDlg', u'Up', u'PushButton', 298, 55, 19, 19, 3670019, None, u'Up', u'NewFolder', u'Up One Level|'), -(u'BrowseDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'PathEdit', None), -(u'BrowseDlg', u'PathEdit', u'PathEdit', 84, 202, 261, 18, 11, u'_BrowseProperty', None, u'OK', None), -(u'BrowseDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'BrowseDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'BrowseDlg', u'Cancel', u'PushButton', 240, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'ComboLabel', None), -(u'BrowseDlg', u'ComboLabel', u'Text', 25, 58, 44, 10, 3, None, u'&Look in:', u'DirectoryCombo', None), -(u'BrowseDlg', u'DirectoryCombo', u'DirectoryCombo', 70, 55, 220, 80, 393227, u'_BrowseProperty', None, u'Up', None), -(u'BrowseDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Browse to the destination folder', None, None), -(u'BrowseDlg', u'DirectoryList', u'DirectoryList', 25, 83, 320, 110, 15, u'_BrowseProperty', None, u'PathLabel', None), -(u'BrowseDlg', u'PathLabel', u'Text', 25, 205, 59, 10, 3, None, u'&Folder name:', u'BannerBitmap', None), -(u'BrowseDlg', u'NewFolder', u'PushButton', 325, 55, 19, 19, 3670019, None, u'New', u'DirectoryList', u'Create A New Folder|'), -(u'BrowseDlg', u'OK', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_OK]', u'Cancel', None), -(u'BrowseDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Change current destination folder', None, None), -(u'CancelDlg', u'Text', u'Text', 48, 15, 194, 30, 3, None, u'Are you sure you want to cancel [ProductName] installation?', None, None), -(u'CancelDlg', u'Icon', u'Icon', 15, 15, 24, 24, 5242881, None, u'[InfoIcon]', None, u'Information icon|'), -(u'CancelDlg', u'No', u'PushButton', 132, 57, 56, 17, 3, None, u'[ButtonText_No]', u'Yes', None), -(u'CancelDlg', u'Yes', u'PushButton', 72, 57, 56, 17, 3, None, u'[ButtonText_Yes]', u'No', None), -(u'CustomizeDlg', u'Text', u'Text', 25, 55, 320, 20, 3, None, u'Click on the icons in the tree below to change the way features will be installed.', None, None), -(u'CustomizeDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Tree', None), -(u'CustomizeDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'CustomizeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'CustomizeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'CustomizeDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Select the way you want features to be installed.', None, None), -(u'CustomizeDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Custom Setup', None, None), -(u'CustomizeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Next', None), -(u'CustomizeDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None), -(u'CustomizeDlg', u'Browse', u'PushButton', 304, 200, 56, 17, 3, None, u'[ButtonText_Browse]', u'Reset', None), -(u'CustomizeDlg', u'Tree', u'SelectionTree', 25, 85, 175, 95, 7, u'_BrowseProperty', u'Tree of selections', u'Browse', None), -(u'CustomizeDlg', u'Box', u'GroupBox', 210, 81, 140, 98, 1, None, None, None, None), -(u'CustomizeDlg', u'Reset', u'PushButton', 42, 243, 56, 17, 3, None, u'[ButtonText_Reset]', u'DiskCost', None), -(u'CustomizeDlg', u'DiskCost', u'PushButton', 111, 243, 56, 17, 3, None, u'Disk &Usage', u'Back', None), -(u'CustomizeDlg', u'ItemDescription', u'Text', 215, 90, 131, 30, 3, None, u'Multiline description of the currently selected item.', None, None), -(u'CustomizeDlg', u'ItemSize', u'Text', 215, 130, 131, 45, 3, None, u'The size of the currently selected item.', None, None), -(u'CustomizeDlg', u'Location', u'Text', 75, 200, 215, 20, 3, None, u"", None, None), -(u'CustomizeDlg', u'LocationLabel', u'Text', 25, 200, 50, 10, 3, None, u'Location:', None, None), -(u'DiskCostDlg', u'Text', u'Text', 20, 53, 330, 40, 3, None, u'The highlighted volumes (if any) do not have enough disk space available for the currently selected features. You can either remove some files from the highlighted volumes, or choose to install less features onto local drive(s), or select different destination drive(s).', None, None), -(u'DiskCostDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'OK', None), -(u'DiskCostDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'DiskCostDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'DiskCostDlg', u'Description', u'Text', 20, 20, 280, 20, 196611, None, u'The disk space required for the installation of the selected features.', None, None), -(u'DiskCostDlg', u'OK', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_OK]', u'BannerBitmap', None), -(u'DiskCostDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Disk Space Requirements', None, None), -(u'DiskCostDlg', u'VolumeList', u'VolumeCostList', 20, 100, 330, 120, 393223, None, u'{120}{70}{70}{70}{70}', None, None), -(u'ErrorDlg', u'Y', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_Yes]', None, None), -(u'ErrorDlg', u'A', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_Cancel]', None, None), -(u'ErrorDlg', u'C', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_Cancel]', None, None), -(u'ErrorDlg', u'ErrorIcon', u'Icon', 15, 15, 24, 24, 5242881, None, u'[InfoIcon]', None, u'Information icon|'), -(u'ErrorDlg', u'ErrorText', u'Text', 48, 15, 205, 60, 3, None, u'Information text', None, None), -(u'ErrorDlg', u'I', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_Ignore]', None, None), -(u'ErrorDlg', u'N', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_No]', None, None), -(u'ErrorDlg', u'O', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_OK]', None, None), -(u'ErrorDlg', u'R', u'PushButton', 100, 80, 56, 17, 3, None, u'[ButtonText_Retry]', None, None), -(u'FilesInUse', u'Text', u'Text', 20, 55, 330, 30, 3, None, u'The following applications are using files that need to be updated by this setup. Close these applications and then click Retry to continue the installation or Cancel to exit it.', None, None), -(u'FilesInUse', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Retry', None), -(u'FilesInUse', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'FilesInUse', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'FilesInUse', u'Description', u'Text', 20, 23, 280, 20, 196611, None, u'Some files that need to be updated are currently in use.', None, None), -(u'FilesInUse', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Files in Use', None, None), -(u'FilesInUse', u'Retry', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Retry]', u'Ignore', None), -(u'FilesInUse', u'Exit', u'PushButton', 166, 243, 56, 17, 3, None, u'[ButtonText_Exit]', u'BannerBitmap', None), -(u'FilesInUse', u'Ignore', u'PushButton', 235, 243, 56, 17, 3, None, u'[ButtonText_Ignore]', u'Exit', None), -(u'FilesInUse', u'List', u'ListBox', 20, 87, 330, 130, 7, u'FileInUseProcess', None, None, None), -(u'LicenseAgreementDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'AgreementText', None), -(u'LicenseAgreementDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'LicenseAgreementDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'LicenseAgreementDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'LicenseAgreementDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Please read the following license agreement carefully', None, None), -(u'LicenseAgreementDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]End-User License Agreement', None, None), -(u'LicenseAgreementDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Next', None), -(u'LicenseAgreementDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None), -(u'LicenseAgreementDlg', u'AgreementText', u'ScrollableText', 20, 60, 330, 120, 7, None, u'{\\rtf1\\ansi\\ansicpg1252\\deff0\\deftab720{\\fonttbl{\\f0\\froman\\fprq2 Times New Roman;}}{\\colortbl\\red0\\green0\\blue0;} \\deflang1033\\horzdoc{\\*\\fchars }{\\*\\lchars }\\pard\\plain\\f0\\fs20 \\par }', u'Buttons', None), -(u'LicenseAgreementDlg', u'Buttons', u'RadioButtonGroup', 20, 187, 330, 40, 3, u'IAgree', None, u'Back', None), -(u'MaintenanceTypeDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'ChangeLabel', None), -(u'MaintenanceTypeDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'MaintenanceTypeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'MaintenanceTypeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'MaintenanceTypeDlg', u'Description', u'Text', 25, 23, 280, 20, 196611, None, u'Select the operation you wish to perform.', None, None), -(u'MaintenanceTypeDlg', u'Title', u'Text', 15, 6, 240, 15, 196611, None, u'[DlgTitleFont]Modify, Repair or Remove installation', None, None), -(u'MaintenanceTypeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Next', None), -(u'MaintenanceTypeDlg', u'Next', u'PushButton', 236, 243, 56, 17, 1, None, u'[ButtonText_Next]', u'Cancel', None), -(u'MaintenanceTypeDlg', u'ChangeLabel', u'Text', 105, 65, 100, 10, 3, None, u'[DlgTitleFont]&Modify', u'ChangeButton', None), -(u'MaintenanceTypeDlg', u'ChangeButton', u'PushButton', 50, 65, 38, 38, 5767171, None, u'[CustomSetupIcon]', u'RepairLabel', u'Modify Installation|'), -(u'MaintenanceTypeDlg', u'RepairLabel', u'Text', 105, 114, 100, 10, 3, None, u'[DlgTitleFont]Re&pair', u'RepairButton', None), -(u'MaintenanceTypeDlg', u'ChangeText', u'Text', 105, 78, 230, 20, 3, None, u'Allows users to change the way features are installed.', None, None), -(u'MaintenanceTypeDlg', u'RemoveButton', u'PushButton', 50, 163, 38, 38, 5767171, None, u'[RemoveIcon]', u'Back', u'Remove Installation|'), -(u'MaintenanceTypeDlg', u'RemoveLabel', u'Text', 105, 163, 100, 10, 3, None, u'[DlgTitleFont]&Remove', u'RemoveButton', None), -(u'MaintenanceTypeDlg', u'RemoveText', u'Text', 105, 176, 230, 20, 3, None, u'Removes [ProductName] from your computer.', None, None), -(u'MaintenanceTypeDlg', u'RepairButton', u'PushButton', 50, 114, 38, 38, 5767171, None, u'[RepairIcon]', u'RemoveLabel', u'Repair Installation|'), -(u'MaintenanceTypeDlg', u'RepairText', u'Text', 105, 127, 230, 30, 3, None, u'Repairs errors in the most recent installation state - fixes missing or corrupt files, shortcuts and registry entries.', None, None), -(u'MaintenanceWelcomeDlg', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None), -(u'MaintenanceWelcomeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'MaintenanceWelcomeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'Bitmap', None), -(u'MaintenanceWelcomeDlg', u'Description', u'Text', 135, 70, 220, 60, 196611, None, u'The [Wizard] will allow you to change the way [ProductName] features are installed on your computer or even to remove [ProductName] from your computer. Click Next to continue or Cancel to exit the [Wizard].', None, None), -(u'MaintenanceWelcomeDlg', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}Welcome to the [ProductName] [Wizard]', None, None), -(u'MaintenanceWelcomeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Next', None), -(u'MaintenanceWelcomeDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None), -(u'OutOfDiskDlg', u'Text', u'Text', 20, 53, 330, 40, 3, None, u'The highlighted volumes do not have enough disk space available for the currently selected features. You can either remove some files from the highlighted volumes, or choose to install less features onto local drive(s), or select different destination drive(s).', None, None), -(u'OutOfDiskDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'OK', None), -(u'OutOfDiskDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'OutOfDiskDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'OutOfDiskDlg', u'Description', u'Text', 20, 20, 280, 20, 196611, None, u'Disk space required for the installation exceeds available disk space.', None, None), -(u'OutOfDiskDlg', u'OK', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_OK]', u'BannerBitmap', None), -(u'OutOfDiskDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Out of Disk Space', None, None), -(u'OutOfDiskDlg', u'VolumeList', u'VolumeCostList', 20, 100, 330, 120, 393223, None, u'{120}{70}{70}{70}{70}', None, None), -(u'OutOfRbDiskDlg', u'Text', u'Text', 20, 53, 330, 40, 3, None, u'The highlighted volumes do not have enough disk space available for the currently selected features. You can either remove some files from the highlighted volumes, or choose to install less features onto local drive(s), or select different destination drive(s).', None, None), -(u'OutOfRbDiskDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'No', None), -(u'OutOfRbDiskDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'OutOfRbDiskDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'OutOfRbDiskDlg', u'Description', u'Text', 20, 20, 280, 20, 196611, None, u'Disk space required for the installation exceeds available disk space.', None, None), -(u'OutOfRbDiskDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Out of Disk Space', None, None), -(u'OutOfRbDiskDlg', u'No', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_No]', u'Yes', None), -(u'OutOfRbDiskDlg', u'Yes', u'PushButton', 240, 243, 56, 17, 3, None, u'[ButtonText_Yes]', u'BannerBitmap', None), -(u'OutOfRbDiskDlg', u'VolumeList', u'VolumeCostList', 20, 140, 330, 80, 4587527, None, u'{120}{70}{70}{70}{70}', None, None), -(u'OutOfRbDiskDlg', u'Text2', u'Text', 20, 94, 330, 40, 3, None, u"Alternatively, you may choose to disable the installer's rollback functionality. This allows the installer to restore your computer's original state should the installation be interrupted in any way. Click Yes if you wish to take the risk to disable rollback.", None, None), -(u'ResumeDlg', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None), -(u'ResumeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'ResumeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'Bitmap', None), -(u'ResumeDlg', u'Description', u'Text', 135, 70, 220, 30, 196611, None, u'The [Wizard] will complete the installation of [ProductName] on your computer. Click Install to continue or Cancel to exit the [Wizard].', None, None), -(u'ResumeDlg', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}Resuming the [ProductName] [Wizard]', None, None), -(u'ResumeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Install', None), -(u'ResumeDlg', u'Install', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Install]', u'Cancel', None), -(u'SetupTypeDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'TypicalLabel', None), -(u'SetupTypeDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'SetupTypeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'SetupTypeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'SetupTypeDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Choose the setup type that best suits your needs', None, None), -(u'SetupTypeDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Choose Setup Type', None, None), -(u'SetupTypeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Next', None), -(u'SetupTypeDlg', u'Next', u'PushButton', 236, 243, 56, 17, 1, None, u'[ButtonText_Next]', u'Cancel', None), -(u'SetupTypeDlg', u'TypicalLabel', u'Text', 105, 65, 100, 10, 3, None, u'[DlgTitleFont]&Typical', u'TypicalButton', None), -(u'SetupTypeDlg', u'CompleteButton', u'PushButton', 50, 171, 38, 38, 5767171, None, u'[CompleteSetupIcon]', u'Back', u'Complete Installation|'), -(u'SetupTypeDlg', u'CompleteLabel', u'Text', 105, 171, 100, 10, 3, None, u'[DlgTitleFont]C&omplete', u'CompleteButton', None), -(u'SetupTypeDlg', u'CompleteText', u'Text', 105, 184, 230, 20, 3, None, u'All program features will be installed. (Requires most disk space)', None, None), -(u'SetupTypeDlg', u'CustomButton', u'PushButton', 50, 118, 38, 38, 5767171, None, u'[CustomSetupIcon]', u'CompleteLabel', u'Custom Installation|'), -(u'SetupTypeDlg', u'CustomLabel', u'Text', 105, 118, 100, 10, 3, None, u'[DlgTitleFont]C&ustom', u'CustomButton', None), -(u'SetupTypeDlg', u'CustomText', u'Text', 105, 131, 230, 30, 3, None, u'Allows users to choose which program features will be installed and where they will be installed. Recommended for advanced users.', None, None), -(u'SetupTypeDlg', u'TypicalButton', u'PushButton', 50, 65, 38, 38, 5767171, None, u'[InstallerIcon]', u'CustomLabel', u'Typical Installation|'), -(u'SetupTypeDlg', u'TypicalText', u'Text', 105, 78, 230, 20, 3, None, u'Installs the most common program features. Recommended for most users.', None, None), -(u'UserRegistrationDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'NameLabel', None), -(u'UserRegistrationDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'UserRegistrationDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'UserRegistrationDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'UserRegistrationDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'Please enter your customer information', None, None), -(u'UserRegistrationDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Customer Information', None, None), -(u'UserRegistrationDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Next', None), -(u'UserRegistrationDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None), -(u'UserRegistrationDlg', u'OrganizationLabel', u'Text', 45, 110, 100, 15, 3, None, u'&Organization:', u'OrganizationEdit', None), -(u'UserRegistrationDlg', u'CDKeyEdit', u'MaskedEdit', 45, 159, 250, 16, 3, u'PIDKEY', u'[PIDTemplate]', u'Back', None), -(u'UserRegistrationDlg', u'CDKeyLabel', u'Text', 45, 147, 50, 10, 3, None, u'CD &Key:', u'CDKeyEdit', None), -(u'UserRegistrationDlg', u'OrganizationEdit', u'Edit', 45, 122, 220, 18, 3, u'COMPANYNAME', u'{80}', u'CDKeyLabel', None), -(u'UserRegistrationDlg', u'NameLabel', u'Text', 45, 73, 100, 15, 3, None, u'&User Name:', u'NameEdit', None), -(u'UserRegistrationDlg', u'NameEdit', u'Edit', 45, 85, 220, 18, 3, u'USERNAME', u'{80}', u'OrganizationLabel', None), -(u'VerifyReadyDlg', u'Text', u'Text', 25, 70, 320, 20, 3, None, u'Click Install to begin the installation. If you want to review or change any of your installation settings, click Back. Click Cancel to exit the wizard.', None, None), -(u'VerifyReadyDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Back', None), -(u'VerifyReadyDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'VerifyReadyDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'VerifyReadyDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'VerifyReadyDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'The [Wizard] is ready to begin the [InstallMode] installation', None, None), -(u'VerifyReadyDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Ready to Install', None, None), -(u'VerifyReadyDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Install', None), -(u'VerifyReadyDlg', u'Install', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Install]', u'Cancel', None), -(u'VerifyRemoveDlg', u'Text', u'Text', 25, 70, 320, 30, 3, None, u'Click Remove to remove [ProductName] from your computer. If you want to review or change any of your installation settings, click Back. Click Cancel to exit the wizard.', None, None), -(u'VerifyRemoveDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Back', None), -(u'VerifyRemoveDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'VerifyRemoveDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'VerifyRemoveDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'VerifyRemoveDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'You have chosen to remove the program from your computer.', None, None), -(u'VerifyRemoveDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Remove [ProductName]', None, None), -(u'VerifyRemoveDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Remove', None), -(u'VerifyRemoveDlg', u'Remove', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Remove]', u'Cancel', None), -(u'VerifyRepairDlg', u'Text', u'Text', 25, 70, 320, 30, 3, None, u'Click Repair to repair the installation of [ProductName]. If you want to review or change any of your installation settings, click Back. Click Cancel to exit the wizard.', None, None), -(u'VerifyRepairDlg', u'BannerBitmap', u'Bitmap', 0, 0, 374, 44, 1, None, u'[BannerBitmap]', u'Back', None), -(u'VerifyRepairDlg', u'BannerLine', u'Line', 0, 44, 374, 0, 1, None, None, None, None), -(u'VerifyRepairDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'VerifyRepairDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'BannerBitmap', None), -(u'VerifyRepairDlg', u'Description', u'Text', 25, 23, 280, 15, 196611, None, u'The [Wizard] is ready to begin the repair of [ProductName].', None, None), -(u'VerifyRepairDlg', u'Title', u'Text', 15, 6, 200, 15, 196611, None, u'[DlgTitleFont]Repair [ProductName]', None, None), -(u'VerifyRepairDlg', u'Back', u'PushButton', 180, 243, 56, 17, 3, None, u'[ButtonText_Back]', u'Repair', None), -(u'VerifyRepairDlg', u'Repair', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Repair]', u'Cancel', None), -(u'WaitForCostingDlg', u'Text', u'Text', 48, 15, 194, 30, 3, None, u'Please wait while the installer finishes determining your disk space requirements.', None, None), -(u'WaitForCostingDlg', u'Icon', u'Icon', 15, 15, 24, 24, 5242881, None, u'[ExclamationIcon]', None, u'Exclamation icon|'), -(u'WaitForCostingDlg', u'Return', u'PushButton', 102, 57, 56, 17, 3, None, u'[ButtonText_Return]', None, None), -(u'WelcomeDlg', u'Bitmap', u'Bitmap', 0, 0, 370, 234, 1, None, u'[DialogBitmap]', u'Back', None), -(u'WelcomeDlg', u'BottomLine', u'Line', 0, 234, 374, 0, 1, None, None, None, None), -(u'WelcomeDlg', u'Cancel', u'PushButton', 304, 243, 56, 17, 3, None, u'[ButtonText_Cancel]', u'Bitmap', None), -(u'WelcomeDlg', u'Description', u'Text', 135, 70, 220, 30, 196611, None, u'The [Wizard] will install [ProductName] on your computer. Click Next to continue or Cancel to exit the [Wizard].', None, None), -(u'WelcomeDlg', u'Title', u'Text', 135, 20, 220, 60, 196611, None, u'{\\VerdanaBold13}Welcome to the [ProductName] [Wizard]', None, None), -(u'WelcomeDlg', u'Back', u'PushButton', 180, 243, 56, 17, 1, None, u'[ButtonText_Back]', u'Next', None), -(u'WelcomeDlg', u'Next', u'PushButton', 236, 243, 56, 17, 3, None, u'[ButtonText_Next]', u'Cancel', None), -] - -ListBox = [ -] - -ActionText = [ -(u'InstallValidate', u'Validating install', None), -(u'InstallFiles', u'Copying new files', u'File: [1], Directory: [9], Size: [6]'), -(u'InstallAdminPackage', u'Copying network install files', u'File: [1], Directory: [9], Size: [6]'), -(u'FileCost', u'Computing space requirements', None), -(u'CostInitialize', u'Computing space requirements', None), -(u'CostFinalize', u'Computing space requirements', None), -(u'CreateShortcuts', u'Creating shortcuts', u'Shortcut: [1]'), -(u'PublishComponents', u'Publishing Qualified Components', u'Component ID: [1], Qualifier: [2]'), -(u'PublishFeatures', u'Publishing Product Features', u'Feature: [1]'), -(u'PublishProduct', u'Publishing product information', None), -(u'RegisterClassInfo', u'Registering Class servers', u'Class Id: [1]'), -(u'RegisterExtensionInfo', u'Registering extension servers', u'Extension: [1]'), -(u'RegisterMIMEInfo', u'Registering MIME info', u'MIME Content Type: [1], Extension: [2]'), -(u'RegisterProgIdInfo', u'Registering program identifiers', u'ProgId: [1]'), -(u'AllocateRegistrySpace', u'Allocating registry space', u'Free space: [1]'), -(u'AppSearch', u'Searching for installed applications', u'Property: [1], Signature: [2]'), -(u'BindImage', u'Binding executables', u'File: [1]'), -(u'CCPSearch', u'Searching for qualifying products', None), -(u'CreateFolders', u'Creating folders', u'Folder: [1]'), -(u'DeleteServices', u'Deleting services', u'Service: [1]'), -(u'DuplicateFiles', u'Creating duplicate files', u'File: [1], Directory: [9], Size: [6]'), -(u'FindRelatedProducts', u'Searching for related applications', u'Found application: [1]'), -(u'InstallODBC', u'Installing ODBC components', None), -(u'InstallServices', u'Installing new services', u'Service: [2]'), -(u'LaunchConditions', u'Evaluating launch conditions', None), -(u'MigrateFeatureStates', u'Migrating feature states from related applications', u'Application: [1]'), -(u'MoveFiles', u'Moving files', u'File: [1], Directory: [9], Size: [6]'), -(u'PatchFiles', u'Patching files', u'File: [1], Directory: [2], Size: [3]'), -(u'ProcessComponents', u'Updating component registration', None), -(u'RegisterComPlus', u'Registering COM+ Applications and Components', u'AppId: [1]{{, AppType: [2], Users: [3], RSN: [4]}}'), -(u'RegisterFonts', u'Registering fonts', u'Font: [1]'), -(u'RegisterProduct', u'Registering product', u'[1]'), -(u'RegisterTypeLibraries', u'Registering type libraries', u'LibID: [1]'), -(u'RegisterUser', u'Registering user', u'[1]'), -(u'RemoveDuplicateFiles', u'Removing duplicated files', u'File: [1], Directory: [9]'), -(u'RemoveEnvironmentStrings', u'Updating environment strings', u'Name: [1], Value: [2], Action [3]'), -(u'RemoveExistingProducts', u'Removing applications', u'Application: [1], Command line: [2]'), -(u'RemoveFiles', u'Removing files', u'File: [1], Directory: [9]'), -(u'RemoveFolders', u'Removing folders', u'Folder: [1]'), -(u'RemoveIniValues', u'Removing INI files entries', u'File: [1], Section: [2], Key: [3], Value: [4]'), -(u'RemoveODBC', u'Removing ODBC components', None), -(u'RemoveRegistryValues', u'Removing system registry values', u'Key: [1], Name: [2]'), -(u'RemoveShortcuts', u'Removing shortcuts', u'Shortcut: [1]'), -(u'RMCCPSearch', u'Searching for qualifying products', None), -(u'SelfRegModules', u'Registering modules', u'File: [1], Folder: [2]'), -(u'SelfUnregModules', u'Unregistering modules', u'File: [1], Folder: [2]'), -(u'SetODBCFolders', u'Initializing ODBC directories', None), -(u'StartServices', u'Starting services', u'Service: [1]'), -(u'StopServices', u'Stopping services', u'Service: [1]'), -(u'UnpublishComponents', u'Unpublishing Qualified Components', u'Component ID: [1], Qualifier: [2]'), -(u'UnpublishFeatures', u'Unpublishing Product Features', u'Feature: [1]'), -(u'UnregisterClassInfo', u'Unregister Class servers', u'Class Id: [1]'), -(u'UnregisterComPlus', u'Unregistering COM+ Applications and Components', u'AppId: [1]{{, AppType: [2]}}'), -(u'UnregisterExtensionInfo', u'Unregistering extension servers', u'Extension: [1]'), -(u'UnregisterFonts', u'Unregistering fonts', u'Font: [1]'), -(u'UnregisterMIMEInfo', u'Unregistering MIME info', u'MIME Content Type: [1], Extension: [2]'), -(u'UnregisterProgIdInfo', u'Unregistering program identifiers', u'ProgId: [1]'), -(u'UnregisterTypeLibraries', u'Unregistering type libraries', u'LibID: [1]'), -(u'WriteEnvironmentStrings', u'Updating environment strings', u'Name: [1], Value: [2], Action [3]'), -(u'WriteIniValues', u'Writing INI files values', u'File: [1], Section: [2], Key: [3], Value: [4]'), -(u'WriteRegistryValues', u'Writing system registry values', u'Key: [1], Name: [2], Value: [3]'), -(u'Advertise', u'Advertising application', None), -(u'GenerateScript', u'Generating script operations for action:', u'[1]'), -(u'InstallSFPCatalogFile', u'Installing system catalog', u'File: [1], Dependencies: [2]'), -(u'MsiPublishAssemblies', u'Publishing assembly information', u'Application Context:[1], Assembly Name:[2]'), -(u'MsiUnpublishAssemblies', u'Unpublishing assembly information', u'Application Context:[1], Assembly Name:[2]'), -(u'Rollback', u'Rolling back action:', u'[1]'), -(u'RollbackCleanup', u'Removing backup files', u'File: [1]'), -(u'UnmoveFiles', u'Removing moved files', u'File: [1], Directory: [9]'), -(u'UnpublishProduct', u'Unpublishing product information', None), -] - -ControlCondition = [ -(u'CustomizeDlg', u'Browse', u'Hide', u'Installed'), -(u'CustomizeDlg', u'Location', u'Hide', u'Installed'), -(u'CustomizeDlg', u'LocationLabel', u'Hide', u'Installed'), -(u'LicenseAgreementDlg', u'Next', u'Disable', u'IAgree <> "Yes"'), -(u'LicenseAgreementDlg', u'Next', u'Enable', u'IAgree = "Yes"'), -] - -ControlEvent = [ -(u'AdminWelcomeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'AdminWelcomeDlg', u'Next', u'NewDialog', u'AdminRegistrationDlg', u'1', 2), -(u'AdminWelcomeDlg', u'Next', u'[InstallMode]', u'Server Image', u'1', 1), -(u'ExitDialog', u'Finish', u'EndDialog', u'Return', u'1', None), -(u'FatalError', u'Finish', u'EndDialog', u'Exit', u'1', None), -(u'PrepareDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'ProgressDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'UserExit', u'Finish', u'EndDialog', u'Exit', u'1', None), -(u'AdminBrowseDlg', u'Up', u'DirectoryListUp', u'0', u'1', None), -(u'AdminBrowseDlg', u'Cancel', u'Reset', u'0', u'1', 1), -(u'AdminBrowseDlg', u'Cancel', u'EndDialog', u'Return', u'1', 2), -(u'AdminBrowseDlg', u'NewFolder', u'DirectoryListNew', u'0', u'1', None), -(u'AdminBrowseDlg', u'OK', u'EndDialog', u'Return', u'1', 2), -(u'AdminBrowseDlg', u'OK', u'SetTargetPath', u'TARGETDIR', u'1', 1), -(u'AdminInstallPointDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'AdminInstallPointDlg', u'Back', u'NewDialog', u'AdminRegistrationDlg', u'1', None), -(u'AdminInstallPointDlg', u'Next', u'SetTargetPath', u'TARGETDIR', u'1', 1), -(u'AdminInstallPointDlg', u'Next', u'NewDialog', u'VerifyReadyDlg', u'1', 2), -(u'AdminInstallPointDlg', u'Browse', u'SpawnDialog', u'AdminBrowseDlg', u'1', None), -(u'AdminRegistrationDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'AdminRegistrationDlg', u'Back', u'NewDialog', u'AdminWelcomeDlg', u'1', None), -(u'AdminRegistrationDlg', u'Next', u'NewDialog', u'AdminInstallPointDlg', u'ProductID', 2), -(u'AdminRegistrationDlg', u'Next', u'ValidateProductID', u'0', u'0', 1), -(u'BrowseDlg', u'Up', u'DirectoryListUp', u'0', u'1', None), -(u'BrowseDlg', u'Cancel', u'Reset', u'0', u'1', 1), -(u'BrowseDlg', u'Cancel', u'EndDialog', u'Return', u'1', 2), -(u'BrowseDlg', u'NewFolder', u'DirectoryListNew', u'0', u'1', None), -(u'BrowseDlg', u'OK', u'EndDialog', u'Return', u'1', 2), -(u'BrowseDlg', u'OK', u'SetTargetPath', u'[_BrowseProperty]', u'1', 1), -(u'CancelDlg', u'No', u'EndDialog', u'Return', u'1', None), -(u'CancelDlg', u'Yes', u'EndDialog', u'Exit', u'1', None), -(u'CustomizeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'CustomizeDlg', u'Back', u'NewDialog', u'MaintenanceTypeDlg', u'InstallMode = "Change"', None), -(u'CustomizeDlg', u'Back', u'NewDialog', u'SetupTypeDlg', u'InstallMode = "Custom"', None), -(u'CustomizeDlg', u'Next', u'NewDialog', u'VerifyReadyDlg', u'1', None), -(u'CustomizeDlg', u'Browse', u'SelectionBrowse', u'BrowseDlg', u'1', None), -(u'CustomizeDlg', u'Reset', u'Reset', u'0', u'1', None), -(u'CustomizeDlg', u'DiskCost', u'SpawnDialog', u'DiskCostDlg', u'1', 2), -(u'DiskCostDlg', u'OK', u'EndDialog', u'Return', u'1', None), -(u'ErrorDlg', u'Y', u'EndDialog', u'ErrorYes', u'1', None), -(u'ErrorDlg', u'A', u'EndDialog', u'ErrorAbort', u'1', None), -(u'ErrorDlg', u'C', u'EndDialog', u'ErrorCancel', u'1', None), -(u'ErrorDlg', u'I', u'EndDialog', u'ErrorIgnore', u'1', None), -(u'ErrorDlg', u'N', u'EndDialog', u'ErrorNo', u'1', None), -(u'ErrorDlg', u'O', u'EndDialog', u'ErrorOk', u'1', None), -(u'ErrorDlg', u'R', u'EndDialog', u'ErrorRetry', u'1', None), -(u'FilesInUse', u'Retry', u'EndDialog', u'Retry', u'1', None), -(u'FilesInUse', u'Exit', u'EndDialog', u'Exit', u'1', None), -(u'FilesInUse', u'Ignore', u'EndDialog', u'Ignore', u'1', None), -(u'LicenseAgreementDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'LicenseAgreementDlg', u'Back', u'NewDialog', u'WelcomeDlg', u'1', None), -(u'LicenseAgreementDlg', u'Next', u'NewDialog', u'SetupTypeDlg', u'IAgree = "Yes" AND ShowUserRegistrationDlg <> 1', 3), -(u'LicenseAgreementDlg', u'Next', u'NewDialog', u'UserRegistrationDlg', u'IAgree = "Yes" AND ShowUserRegistrationDlg = 1', 1), -(u'LicenseAgreementDlg', u'Next', u'SpawnWaitDialog', u'WaitForCostingDlg', u'CostingComplete = 1', 2), -(u'MaintenanceTypeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'MaintenanceTypeDlg', u'Back', u'NewDialog', u'MaintenanceWelcomeDlg', u'1', None), -(u'MaintenanceTypeDlg', u'ChangeButton', u'NewDialog', u'CustomizeDlg', u'1', 4), -(u'MaintenanceTypeDlg', u'ChangeButton', u'[InstallMode]', u'Change', u'1', 1), -(u'MaintenanceTypeDlg', u'ChangeButton', u'[Progress1]', u'Changing', u'1', 2), -(u'MaintenanceTypeDlg', u'ChangeButton', u'[Progress2]', u'changes', u'1', 3), -(u'MaintenanceTypeDlg', u'RemoveButton', u'NewDialog', u'VerifyRemoveDlg', u'1', 4), -(u'MaintenanceTypeDlg', u'RemoveButton', u'[InstallMode]', u'Remove', u'1', 1), -(u'MaintenanceTypeDlg', u'RemoveButton', u'[Progress1]', u'Removing', u'1', 2), -(u'MaintenanceTypeDlg', u'RemoveButton', u'[Progress2]', u'removes', u'1', 3), -(u'MaintenanceTypeDlg', u'RepairButton', u'NewDialog', u'VerifyRepairDlg', u'1', 4), -(u'MaintenanceTypeDlg', u'RepairButton', u'[InstallMode]', u'Repair', u'1', 1), -(u'MaintenanceTypeDlg', u'RepairButton', u'[Progress1]', u'Repairing', u'1', 2), -(u'MaintenanceTypeDlg', u'RepairButton', u'[Progress2]', u'repairs', u'1', 3), -(u'MaintenanceWelcomeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'MaintenanceWelcomeDlg', u'Next', u'NewDialog', u'MaintenanceTypeDlg', u'1', 2), -(u'MaintenanceWelcomeDlg', u'Next', u'SpawnWaitDialog', u'WaitForCostingDlg', u'CostingComplete = 1', 1), -(u'OutOfDiskDlg', u'OK', u'EndDialog', u'Return', u'1', None), -(u'OutOfRbDiskDlg', u'No', u'EndDialog', u'Return', u'1', None), -(u'OutOfRbDiskDlg', u'Yes', u'EndDialog', u'Return', u'1', 2), -(u'OutOfRbDiskDlg', u'Yes', u'EnableRollback', u'False', u'1', 1), -(u'ResumeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'ResumeDlg', u'Install', u'EndDialog', u'Return', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 4), -(u'ResumeDlg', u'Install', u'EndDialog', u'Return', u'OutOfDiskSpace <> 1', 2), -(u'ResumeDlg', u'Install', u'SpawnDialog', u'OutOfDiskDlg', u'(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")', 6), -(u'ResumeDlg', u'Install', u'SpawnDialog', u'OutOfRbDiskDlg', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)', 3), -(u'ResumeDlg', u'Install', u'SpawnWaitDialog', u'WaitForCostingDlg', u'CostingComplete = 1', 1), -(u'ResumeDlg', u'Install', u'EnableRollback', u'False', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 5), -(u'SetupTypeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'SetupTypeDlg', u'Back', u'NewDialog', u'LicenseAgreementDlg', u'ShowUserRegistrationDlg <> 1', None), -(u'SetupTypeDlg', u'Back', u'NewDialog', u'UserRegistrationDlg', u'ShowUserRegistrationDlg = 1', None), -(u'SetupTypeDlg', u'CompleteButton', u'NewDialog', u'VerifyReadyDlg', u'1', 3), -(u'SetupTypeDlg', u'CompleteButton', u'[InstallMode]', u'Complete', u'1', 1), -(u'SetupTypeDlg', u'CompleteButton', u'SetInstallLevel', u'1000', u'1', 2), -(u'SetupTypeDlg', u'CustomButton', u'NewDialog', u'CustomizeDlg', u'1', 2), -(u'SetupTypeDlg', u'CustomButton', u'[InstallMode]', u'Custom', u'1', 1), -(u'SetupTypeDlg', u'TypicalButton', u'NewDialog', u'VerifyReadyDlg', u'1', 3), -(u'SetupTypeDlg', u'TypicalButton', u'[InstallMode]', u'Typical', u'1', 1), -(u'SetupTypeDlg', u'TypicalButton', u'SetInstallLevel', u'3', u'1', 2), -(u'UserRegistrationDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'UserRegistrationDlg', u'Back', u'NewDialog', u'LicenseAgreementDlg', u'1', None), -(u'UserRegistrationDlg', u'Next', u'NewDialog', u'SetupTypeDlg', u'ProductID', 3), -(u'UserRegistrationDlg', u'Next', u'ValidateProductID', u'0', u'0', 1), -(u'UserRegistrationDlg', u'Next', u'SpawnWaitDialog', u'WaitForCostingDlg', u'CostingComplete = 1', 2), -(u'VerifyReadyDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'VerifyReadyDlg', u'Back', u'NewDialog', u'AdminInstallPointDlg', u'InstallMode = "Server Image"', None), -(u'VerifyReadyDlg', u'Back', u'NewDialog', u'CustomizeDlg', u'InstallMode = "Custom" OR InstallMode = "Change"', None), -(u'VerifyReadyDlg', u'Back', u'NewDialog', u'MaintenanceTypeDlg', u'InstallMode = "Repair"', None), -(u'VerifyReadyDlg', u'Back', u'NewDialog', u'SetupTypeDlg', u'InstallMode = "Typical" OR InstallMode = "Complete"', None), -(u'VerifyReadyDlg', u'Install', u'EndDialog', u'Return', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 3), -(u'VerifyReadyDlg', u'Install', u'EndDialog', u'Return', u'OutOfDiskSpace <> 1', 1), -(u'VerifyReadyDlg', u'Install', u'SpawnDialog', u'OutOfDiskDlg', u'(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")', 5), -(u'VerifyReadyDlg', u'Install', u'SpawnDialog', u'OutOfRbDiskDlg', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)', 2), -(u'VerifyReadyDlg', u'Install', u'EnableRollback', u'False', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 4), -(u'VerifyRemoveDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'VerifyRemoveDlg', u'Back', u'NewDialog', u'MaintenanceTypeDlg', u'1', None), -(u'VerifyRemoveDlg', u'Remove', u'Remove', u'All', u'OutOfDiskSpace <> 1', 1), -(u'VerifyRemoveDlg', u'Remove', u'EndDialog', u'Return', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 4), -(u'VerifyRemoveDlg', u'Remove', u'EndDialog', u'Return', u'OutOfDiskSpace <> 1', 2), -(u'VerifyRemoveDlg', u'Remove', u'SpawnDialog', u'OutOfDiskDlg', u'(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")', 6), -(u'VerifyRemoveDlg', u'Remove', u'SpawnDialog', u'OutOfRbDiskDlg', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)', 3), -(u'VerifyRemoveDlg', u'Remove', u'EnableRollback', u'False', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 5), -(u'VerifyRepairDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'VerifyRepairDlg', u'Back', u'NewDialog', u'MaintenanceTypeDlg', u'1', None), -(u'VerifyRepairDlg', u'Repair', u'EndDialog', u'Return', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 5), -(u'VerifyRepairDlg', u'Repair', u'EndDialog', u'Return', u'OutOfDiskSpace <> 1', 3), -(u'VerifyRepairDlg', u'Repair', u'SpawnDialog', u'OutOfDiskDlg', u'(OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 1) OR (OutOfDiskSpace = 1 AND PROMPTROLLBACKCOST="F")', 7), -(u'VerifyRepairDlg', u'Repair', u'SpawnDialog', u'OutOfRbDiskDlg', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND (PROMPTROLLBACKCOST="P" OR NOT PROMPTROLLBACKCOST)', 4), -(u'VerifyRepairDlg', u'Repair', u'EnableRollback', u'False', u'OutOfDiskSpace = 1 AND OutOfNoRbDiskSpace = 0 AND PROMPTROLLBACKCOST="D"', 6), -(u'VerifyRepairDlg', u'Repair', u'Reinstall', u'All', u'OutOfDiskSpace <> 1', 2), -(u'VerifyRepairDlg', u'Repair', u'ReinstallMode', u'ecmus', u'OutOfDiskSpace <> 1', 1), -(u'WaitForCostingDlg', u'Return', u'EndDialog', u'Exit', u'1', None), -(u'WelcomeDlg', u'Cancel', u'SpawnDialog', u'CancelDlg', u'1', None), -(u'WelcomeDlg', u'Next', u'NewDialog', u'LicenseAgreementDlg', u'1', None), -] - -Dialog = [ -(u'AdminWelcomeDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Next', u'Next', u'Cancel'), -(u'ExitDialog', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Finish', u'Finish', u'Finish'), -(u'FatalError', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Finish', u'Finish', u'Finish'), -(u'PrepareDlg', 50, 50, 370, 270, 1, u'[ProductName] [Setup]', u'Cancel', u'Cancel', u'Cancel'), -(u'ProgressDlg', 50, 50, 370, 270, 1, u'[ProductName] [Setup]', u'Cancel', u'Cancel', u'Cancel'), -(u'UserExit', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Finish', u'Finish', u'Finish'), -(u'AdminBrowseDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'PathEdit', u'OK', u'Cancel'), -(u'AdminInstallPointDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Text', u'Next', u'Cancel'), -(u'AdminRegistrationDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'OrganizationLabel', u'Next', u'Cancel'), -(u'BrowseDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'PathEdit', u'OK', u'Cancel'), -(u'CancelDlg', 50, 10, 260, 85, 3, u'[ProductName] [Setup]', u'No', u'No', u'No'), -(u'CustomizeDlg', 50, 50, 370, 270, 35, u'[ProductName] [Setup]', u'Tree', u'Next', u'Cancel'), -(u'DiskCostDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'OK', u'OK', u'OK'), -(u'ErrorDlg', 50, 10, 270, 105, 65539, u'Installer Information', u'ErrorText', None, None), -(u'FilesInUse', 50, 50, 370, 270, 19, u'[ProductName] [Setup]', u'Retry', u'Retry', u'Retry'), -(u'LicenseAgreementDlg', 50, 50, 370, 270, 3, u'[ProductName] License Agreement', u'Buttons', u'Next', u'Cancel'), -(u'MaintenanceTypeDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'ChangeLabel', u'ChangeButton', u'Cancel'), -(u'MaintenanceWelcomeDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Next', u'Next', u'Cancel'), -(u'OutOfDiskDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'OK', u'OK', u'OK'), -(u'OutOfRbDiskDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'No', u'No', u'No'), -(u'ResumeDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Install', u'Install', u'Cancel'), -(u'SetupTypeDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'TypicalLabel', u'TypicalButton', u'Cancel'), -(u'UserRegistrationDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'NameLabel', u'Next', u'Cancel'), -(u'VerifyReadyDlg', 50, 50, 370, 270, 35, u'[ProductName] [Setup]', u'Install', u'Install', u'Cancel'), -(u'VerifyRemoveDlg', 50, 50, 370, 270, 35, u'[ProductName] [Setup]', u'Back', u'Back', u'Cancel'), -(u'VerifyRepairDlg', 50, 50, 370, 270, 35, u'[ProductName] [Setup]', u'Repair', u'Repair', u'Cancel'), -(u'WaitForCostingDlg', 50, 10, 260, 85, 3, u'[ProductName] [Setup]', u'Return', u'Return', u'Return'), -(u'WelcomeDlg', 50, 50, 370, 270, 3, u'[ProductName] [Setup]', u'Next', u'Next', u'Cancel'), -] - -EventMapping = [ -(u'PrepareDlg', u'ActionData', u'ActionData', u'Text'), -(u'PrepareDlg', u'ActionText', u'ActionText', u'Text'), -(u'ProgressDlg', u'ActionText', u'ActionText', u'Text'), -(u'ProgressDlg', u'ProgressBar', u'SetProgress', u'Progress'), -(u'AdminBrowseDlg', u'DirectoryCombo', u'IgnoreChange', u'IgnoreChange'), -(u'BrowseDlg', u'DirectoryCombo', u'IgnoreChange', u'IgnoreChange'), -(u'CustomizeDlg', u'Next', u'SelectionNoItems', u'Enabled'), -(u'CustomizeDlg', u'Reset', u'SelectionNoItems', u'Enabled'), -(u'CustomizeDlg', u'DiskCost', u'SelectionNoItems', u'Enabled'), -(u'CustomizeDlg', u'ItemDescription', u'SelectionDescription', u'Text'), -(u'CustomizeDlg', u'ItemSize', u'SelectionSize', u'Text'), -(u'CustomizeDlg', u'Location', u'SelectionPath', u'Text'), -(u'CustomizeDlg', u'Location', u'SelectionPathOn', u'Visible'), -(u'CustomizeDlg', u'LocationLabel', u'SelectionPathOn', u'Visible'), -] - -InstallExecuteSequence = [ -(u'InstallValidate', None, 1400), -(u'InstallInitialize', None, 1500), -(u'InstallFinalize', None, 6600), -(u'InstallFiles', None, 4000), -(u'FileCost', None, 900), -(u'CostInitialize', None, 800), -(u'CostFinalize', None, 1000), -(u'CreateShortcuts', None, 4500), -(u'PublishComponents', None, 6200), -(u'PublishFeatures', None, 6300), -(u'PublishProduct', None, 6400), -(u'RegisterClassInfo', None, 4600), -(u'RegisterExtensionInfo', None, 4700), -(u'RegisterMIMEInfo', None, 4900), -(u'RegisterProgIdInfo', None, 4800), -(u'ValidateProductID', None, 700), -(u'AllocateRegistrySpace', u'NOT Installed', 1550), -(u'AppSearch', None, 400), -(u'BindImage', None, 4300), -(u'CCPSearch', u'NOT Installed', 500), -(u'CreateFolders', None, 3700), -(u'DeleteServices', u'VersionNT', 2000), -(u'DuplicateFiles', None, 4210), -(u'FindRelatedProducts', None, 200), -(u'InstallODBC', None, 5400), -(u'InstallServices', u'VersionNT', 5800), -(u'LaunchConditions', None, 100), -(u'MigrateFeatureStates', None, 1200), -(u'MoveFiles', None, 3800), -(u'PatchFiles', None, 4090), -(u'ProcessComponents', None, 1600), -(u'RegisterComPlus', None, 5700), -(u'RegisterFonts', None, 5300), -(u'RegisterProduct', None, 6100), -(u'RegisterTypeLibraries', None, 5500), -(u'RegisterUser', None, 6000), -(u'RemoveDuplicateFiles', None, 3400), -(u'RemoveEnvironmentStrings', None, 3300), -(u'RemoveExistingProducts', None, 6700), -(u'RemoveFiles', None, 3500), -(u'RemoveFolders', None, 3600), -(u'RemoveIniValues', None, 3100), -(u'RemoveODBC', None, 2400), -(u'RemoveRegistryValues', None, 2600), -(u'RemoveShortcuts', None, 3200), -(u'RMCCPSearch', u'NOT Installed', 600), -(u'SelfRegModules', None, 5600), -(u'SelfUnregModules', None, 2200), -(u'SetODBCFolders', None, 1100), -(u'StartServices', u'VersionNT', 5900), -(u'StopServices', u'VersionNT', 1900), -(u'UnpublishComponents', None, 1700), -(u'UnpublishFeatures', None, 1800), -(u'UnregisterClassInfo', None, 2700), -(u'UnregisterComPlus', None, 2100), -(u'UnregisterExtensionInfo', None, 2800), -(u'UnregisterFonts', None, 2500), -(u'UnregisterMIMEInfo', None, 3000), -(u'UnregisterProgIdInfo', None, 2900), -(u'UnregisterTypeLibraries', None, 2300), -(u'WriteEnvironmentStrings', None, 5200), -(u'WriteIniValues', None, 5100), -(u'WriteRegistryValues', None, 5000), -] - -InstallUISequence = [ -#(u'FileCost', None, 900), -#(u'CostInitialize', None, 800), -#(u'CostFinalize', None, 1000), -#(u'ExecuteAction', None, 1300), -#(u'ExitDialog', None, -1), -#(u'FatalError', None, -3), -(u'PrepareDlg', None, 140), -(u'ProgressDlg', None, 1280), -#(u'UserExit', None, -2), -(u'MaintenanceWelcomeDlg', u'Installed AND NOT RESUME AND NOT Preselected', 1250), -(u'ResumeDlg', u'Installed AND (RESUME OR Preselected)', 1240), -(u'WelcomeDlg', u'NOT Installed', 1230), -#(u'AppSearch', None, 400), -#(u'CCPSearch', u'NOT Installed', 500), -#(u'FindRelatedProducts', None, 200), -#(u'LaunchConditions', None, 100), -#(u'MigrateFeatureStates', None, 1200), -#(u'RMCCPSearch', u'NOT Installed', 600), -] - -ListView = [ -] - -RadioButton = [ -(u'IAgree', 1, u'Yes', 5, 0, 250, 15, u'{\\DlgFont8}I &accept the terms in the License Agreement', None), -(u'IAgree', 2, u'No', 5, 20, 250, 15, u'{\\DlgFont8}I &do not accept the terms in the License Agreement', None), -] - -TextStyle = [ -(u'DlgFont8', u'Tahoma', 8, None, 0), -(u'DlgFontBold8', u'Tahoma', 8, None, 1), -(u'VerdanaBold13', u'Verdana', 13, None, 1), -] - -UIText = [ -(u'AbsentPath', None), -(u'bytes', u'bytes'), -(u'GB', u'GB'), -(u'KB', u'KB'), -(u'MB', u'MB'), -(u'MenuAbsent', u'Entire feature will be unavailable'), -(u'MenuAdvertise', u'Feature will be installed when required'), -(u'MenuAllCD', u'Entire feature will be installed to run from CD'), -(u'MenuAllLocal', u'Entire feature will be installed on local hard drive'), -(u'MenuAllNetwork', u'Entire feature will be installed to run from network'), -(u'MenuCD', u'Will be installed to run from CD'), -(u'MenuLocal', u'Will be installed on local hard drive'), -(u'MenuNetwork', u'Will be installed to run from network'), -(u'ScriptInProgress', u'Gathering required information...'), -(u'SelAbsentAbsent', u'This feature will remain uninstalled'), -(u'SelAbsentAdvertise', u'This feature will be set to be installed when required'), -(u'SelAbsentCD', u'This feature will be installed to run from CD'), -(u'SelAbsentLocal', u'This feature will be installed on the local hard drive'), -(u'SelAbsentNetwork', u'This feature will be installed to run from the network'), -(u'SelAdvertiseAbsent', u'This feature will become unavailable'), -(u'SelAdvertiseAdvertise', u'Will be installed when required'), -(u'SelAdvertiseCD', u'This feature will be available to run from CD'), -(u'SelAdvertiseLocal', u'This feature will be installed on your local hard drive'), -(u'SelAdvertiseNetwork', u'This feature will be available to run from the network'), -(u'SelCDAbsent', u"This feature will be uninstalled completely, you won't be able to run it from CD"), -(u'SelCDAdvertise', u'This feature will change from run from CD state to set to be installed when required'), -(u'SelCDCD', u'This feature will remain to be run from CD'), -(u'SelCDLocal', u'This feature will change from run from CD state to be installed on the local hard drive'), -(u'SelChildCostNeg', u'This feature frees up [1] on your hard drive.'), -(u'SelChildCostPos', u'This feature requires [1] on your hard drive.'), -(u'SelCostPending', u'Compiling cost for this feature...'), -(u'SelLocalAbsent', u'This feature will be completely removed'), -(u'SelLocalAdvertise', u'This feature will be removed from your local hard drive, but will be set to be installed when required'), -(u'SelLocalCD', u'This feature will be removed from your local hard drive, but will be still available to run from CD'), -(u'SelLocalLocal', u'This feature will remain on you local hard drive'), -(u'SelLocalNetwork', u'This feature will be removed from your local hard drive, but will be still available to run from the network'), -(u'SelNetworkAbsent', u"This feature will be uninstalled completely, you won't be able to run it from the network"), -(u'SelNetworkAdvertise', u'This feature will change from run from network state to set to be installed when required'), -(u'SelNetworkLocal', u'This feature will change from run from network state to be installed on the local hard drive'), -(u'SelNetworkNetwork', u'This feature will remain to be run from the network'), -(u'SelParentCostNegNeg', u'This feature frees up [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures free up [4] on your hard drive.'), -(u'SelParentCostNegPos', u'This feature frees up [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures require [4] on your hard drive.'), -(u'SelParentCostPosNeg', u'This feature requires [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures free up [4] on your hard drive.'), -(u'SelParentCostPosPos', u'This feature requires [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures require [4] on your hard drive.'), -(u'TimeRemaining', u'Time remaining: {[1] minutes }{[2] seconds}'), -(u'VolumeCostAvailable', u'Available'), -(u'VolumeCostDifference', u'Difference'), -(u'VolumeCostRequired', u'Required'), -(u'VolumeCostSize', u'Disk Size'), -(u'VolumeCostVolume', u'Volume'), -] - -_Validation = [ -(u'AdminExecuteSequence', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to invoke, either in the engine or the handler DLL.'), -(u'AdminExecuteSequence', u'Sequence', u'Y', -4, 32767, None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.'), -(u'AdminExecuteSequence', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.'), -(u'AdminUISequence', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to invoke, either in the engine or the handler DLL.'), -(u'AdminUISequence', u'Sequence', u'Y', -4, 32767, None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.'), -(u'AdminUISequence', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.'), -(u'Condition', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Expression evaluated to determine if Level in the Feature table is to change.'), -(u'Condition', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Reference to a Feature entry in Feature table.'), -(u'Condition', u'Level', u'N', 0, 32767, None, None, None, None, u'New selection Level to set in Feature table if Condition evaluates to TRUE.'), -(u'AdvtExecuteSequence', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to invoke, either in the engine or the handler DLL.'), -(u'AdvtExecuteSequence', u'Sequence', u'Y', -4, 32767, None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.'), -(u'AdvtExecuteSequence', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.'), -(u'BBControl', u'Type', u'N', None, None, None, None, u'Identifier', None, u'The type of the control.'), -(u'BBControl', u'BBControl', u'N', None, None, None, None, u'Identifier', None, u'Name of the control. This name must be unique within a billboard, but can repeat on different billboard.'), -(u'BBControl', u'Billboard_', u'N', None, None, u'Billboard', 1, u'Identifier', None, u'External key to the Billboard table, name of the billboard.'), -(u'BBControl', u'X', u'N', 0, 32767, None, None, None, None, u'Horizontal coordinate of the upper left corner of the bounding rectangle of the control.'), -(u'BBControl', u'Y', u'N', 0, 32767, None, None, None, None, u'Vertical coordinate of the upper left corner of the bounding rectangle of the control.'), -(u'BBControl', u'Width', u'N', 0, 32767, None, None, None, None, u'Width of the bounding rectangle of the control.'), -(u'BBControl', u'Height', u'N', 0, 32767, None, None, None, None, u'Height of the bounding rectangle of the control.'), -(u'BBControl', u'Attributes', u'Y', 0, 2147483647, None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this control.'), -(u'BBControl', u'Text', u'Y', None, None, None, None, u'Text', None, u'A string used to set the initial text contained within a control (if appropriate).'), -(u'Billboard', u'Action', u'Y', None, None, None, None, u'Identifier', None, u'The name of an action. The billboard is displayed during the progress messages received from this action.'), -(u'Billboard', u'Billboard', u'N', None, None, None, None, u'Identifier', None, u'Name of the billboard.'), -(u'Billboard', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'An external key to the Feature Table. The billboard is shown only if this feature is being installed.'), -(u'Billboard', u'Ordering', u'Y', 0, 32767, None, None, None, None, u'A positive integer. If there is more than one billboard corresponding to an action they will be shown in the order defined by this column.'), -(u'Binary', u'Name', u'N', None, None, None, None, u'Identifier', None, u'Unique key identifying the binary data.'), -(u'Binary', u'Data', u'N', None, None, None, None, u'Binary', None, u'The unformatted binary data.'), -(u'CheckBox', u'Property', u'N', None, None, None, None, u'Identifier', None, u'A named property to be tied to the item.'), -(u'CheckBox', u'Value', u'Y', None, None, None, None, u'Formatted', None, u'The value string associated with the item.'), -(u'Property', u'Property', u'N', None, None, None, None, u'Identifier', None, u'Name of property, uppercase if settable by launcher or loader.'), -(u'Property', u'Value', u'N', None, None, None, None, u'Text', None, u'String value for property. Never null or empty.'), -(u'ComboBox', u'Text', u'Y', None, None, None, None, u'Formatted', None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.'), -(u'ComboBox', u'Property', u'N', None, None, None, None, u'Identifier', None, u'A named property to be tied to this item. All the items tied to the same property become part of the same combobox.'), -(u'ComboBox', u'Value', u'N', None, None, None, None, u'Formatted', None, u'The value string associated with this item. Selecting the line will set the associated property to this value.'), -(u'ComboBox', u'Order', u'N', 1, 32767, None, None, None, None, u'A positive integer used to determine the ordering of the items within one list.\tThe integers do not have to be consecutive.'), -(u'Control', u'Type', u'N', None, None, None, None, u'Identifier', None, u'The type of the control.'), -(u'Control', u'X', u'N', 0, 32767, None, None, None, None, u'Horizontal coordinate of the upper left corner of the bounding rectangle of the control.'), -(u'Control', u'Y', u'N', 0, 32767, None, None, None, None, u'Vertical coordinate of the upper left corner of the bounding rectangle of the control.'), -(u'Control', u'Width', u'N', 0, 32767, None, None, None, None, u'Width of the bounding rectangle of the control.'), -(u'Control', u'Height', u'N', 0, 32767, None, None, None, None, u'Height of the bounding rectangle of the control.'), -(u'Control', u'Attributes', u'Y', 0, 2147483647, None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this control.'), -(u'Control', u'Text', u'Y', None, None, None, None, u'Formatted', None, u'A string used to set the initial text contained within a control (if appropriate).'), -(u'Control', u'Property', u'Y', None, None, None, None, u'Identifier', None, u'The name of a defined property to be linked to this control. '), -(u'Control', u'Control', u'N', None, None, None, None, u'Identifier', None, u'Name of the control. This name must be unique within a dialog, but can repeat on different dialogs. '), -(u'Control', u'Dialog_', u'N', None, None, u'Dialog', 1, u'Identifier', None, u'External key to the Dialog table, name of the dialog.'), -(u'Control', u'Control_Next', u'Y', None, None, u'Control', 2, u'Identifier', None, u'The name of an other control on the same dialog. This link defines the tab order of the controls. The links have to form one or more cycles!'), -(u'Control', u'Help', u'Y', None, None, None, None, u'Text', None, u'The help strings used with the button. The text is optional. '), -(u'Icon', u'Name', u'N', None, None, None, None, u'Identifier', None, u'Primary key. Name of the icon file.'), -(u'Icon', u'Data', u'N', None, None, None, None, u'Binary', None, u'Binary stream. The binary icon data in PE (.DLL or .EXE) or icon (.ICO) format.'), -(u'ListBox', u'Text', u'Y', None, None, None, None, u'Text', None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.'), -(u'ListBox', u'Property', u'N', None, None, None, None, u'Identifier', None, u'A named property to be tied to this item. All the items tied to the same property become part of the same listbox.'), -(u'ListBox', u'Value', u'N', None, None, None, None, u'Formatted', None, u'The value string associated with this item. Selecting the line will set the associated property to this value.'), -(u'ListBox', u'Order', u'N', 1, 32767, None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.'), -(u'ActionText', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to be described.'), -(u'ActionText', u'Description', u'Y', None, None, None, None, u'Text', None, u'Localized description displayed in progress dialog and log when action is executing.'), -(u'ActionText', u'Template', u'Y', None, None, None, None, u'Template', None, u'Optional localized format template used to format action data records for display during action execution.'), -(u'ControlCondition', u'Action', u'N', None, None, None, None, None, u'Default;Disable;Enable;Hide;Show', u'The desired action to be taken on the specified control.'), -(u'ControlCondition', u'Condition', u'N', None, None, None, None, u'Condition', None, u'A standard conditional statement that specifies under which conditions the action should be triggered.'), -(u'ControlCondition', u'Dialog_', u'N', None, None, u'Dialog', 1, u'Identifier', None, u'A foreign key to the Dialog table, name of the dialog.'), -(u'ControlCondition', u'Control_', u'N', None, None, u'Control', 2, u'Identifier', None, u'A foreign key to the Control table, name of the control.'), -(u'ControlEvent', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'A standard conditional statement that specifies under which conditions an event should be triggered.'), -(u'ControlEvent', u'Ordering', u'Y', 0, 2147483647, None, None, None, None, u'An integer used to order several events tied to the same control. Can be left blank.'), -(u'ControlEvent', u'Dialog_', u'N', None, None, u'Dialog', 1, u'Identifier', None, u'A foreign key to the Dialog table, name of the dialog.'), -(u'ControlEvent', u'Control_', u'N', None, None, u'Control', 2, u'Identifier', None, u'A foreign key to the Control table, name of the control'), -(u'ControlEvent', u'Event', u'N', None, None, None, None, u'Formatted', None, u'An identifier that specifies the type of the event that should take place when the user interacts with control specified by the first two entries.'), -(u'ControlEvent', u'Argument', u'N', None, None, None, None, u'Formatted', None, u'A value to be used as a modifier when triggering a particular event.'), -(u'Dialog', u'Width', u'N', 0, 32767, None, None, None, None, u'Width of the bounding rectangle of the dialog.'), -(u'Dialog', u'Height', u'N', 0, 32767, None, None, None, None, u'Height of the bounding rectangle of the dialog.'), -(u'Dialog', u'Attributes', u'Y', 0, 2147483647, None, None, None, None, u'A 32-bit word that specifies the attribute flags to be applied to this dialog.'), -(u'Dialog', u'Title', u'Y', None, None, None, None, u'Formatted', None, u"A text string specifying the title to be displayed in the title bar of the dialog's window."), -(u'Dialog', u'Dialog', u'N', None, None, None, None, u'Identifier', None, u'Name of the dialog.'), -(u'Dialog', u'HCentering', u'N', 0, 100, None, None, None, None, u'Horizontal position of the dialog on a 0-100 scale. 0 means left end, 100 means right end of the screen, 50 center.'), -(u'Dialog', u'VCentering', u'N', 0, 100, None, None, None, None, u'Vertical position of the dialog on a 0-100 scale. 0 means top end, 100 means bottom end of the screen, 50 center.'), -(u'Dialog', u'Control_First', u'N', None, None, u'Control', 2, u'Identifier', None, u'Defines the control that has the focus when the dialog is created.'), -(u'Dialog', u'Control_Default', u'Y', None, None, u'Control', 2, u'Identifier', None, u'Defines the default control. Hitting return is equivalent to pushing this button.'), -(u'Dialog', u'Control_Cancel', u'Y', None, None, u'Control', 2, u'Identifier', None, u'Defines the cancel control. Hitting escape or clicking on the close icon on the dialog is equivalent to pushing this button.'), -(u'EventMapping', u'Dialog_', u'N', None, None, u'Dialog', 1, u'Identifier', None, u'A foreign key to the Dialog table, name of the Dialog.'), -(u'EventMapping', u'Control_', u'N', None, None, u'Control', 2, u'Identifier', None, u'A foreign key to the Control table, name of the control.'), -(u'EventMapping', u'Event', u'N', None, None, None, None, u'Identifier', None, u'An identifier that specifies the type of the event that the control subscribes to.'), -(u'EventMapping', u'Attribute', u'N', None, None, None, None, u'Identifier', None, u'The name of the control attribute, that is set when this event is received.'), -(u'InstallExecuteSequence', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to invoke, either in the engine or the handler DLL.'), -(u'InstallExecuteSequence', u'Sequence', u'Y', -4, 32767, None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.'), -(u'InstallExecuteSequence', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.'), -(u'AppSearch', u'Property', u'N', None, None, None, None, u'Identifier', None, u'The property associated with a Signature'), -(u'AppSearch', u'Signature_', u'N', None, None, u'Signature;RegLocator;IniLocator;DrLocator;CompLocator', 1, u'Identifier', None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature, RegLocator, IniLocator, CompLocator and the DrLocator tables.'), -(u'BindImage', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'The index into the File table. This must be an executable file.'), -(u'BindImage', u'Path', u'Y', None, None, None, None, u'Paths', None, u'A list of ; delimited paths that represent the paths to be searched for the import DLLS. The list is usually a list of properties each enclosed within square brackets [] .'), -(u'CCPSearch', u'Signature_', u'N', None, None, u'Signature;RegLocator;IniLocator;DrLocator;CompLocator', 1, u'Identifier', None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature, RegLocator, IniLocator, CompLocator and the DrLocator tables.'), -(u'InstallUISequence', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to invoke, either in the engine or the handler DLL.'), -(u'InstallUISequence', u'Sequence', u'Y', -4, 32767, None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.'), -(u'InstallUISequence', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.'), -(u'ListView', u'Text', u'Y', None, None, None, None, u'Text', None, u'The visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value.'), -(u'ListView', u'Property', u'N', None, None, None, None, u'Identifier', None, u'A named property to be tied to this item. All the items tied to the same property become part of the same listview.'), -(u'ListView', u'Value', u'N', None, None, None, None, u'Identifier', None, u'The value string associated with this item. Selecting the line will set the associated property to this value.'), -(u'ListView', u'Order', u'N', 1, 32767, None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.'), -(u'ListView', u'Binary_', u'Y', None, None, u'Binary', 1, u'Identifier', None, u'The name of the icon to be displayed with the icon. The binary information is looked up from the Binary Table.'), -(u'RadioButton', u'X', u'N', 0, 32767, None, None, None, None, u'The horizontal coordinate of the upper left corner of the bounding rectangle of the radio button.'), -(u'RadioButton', u'Y', u'N', 0, 32767, None, None, None, None, u'The vertical coordinate of the upper left corner of the bounding rectangle of the radio button.'), -(u'RadioButton', u'Width', u'N', 0, 32767, None, None, None, None, u'The width of the button.'), -(u'RadioButton', u'Height', u'N', 0, 32767, None, None, None, None, u'The height of the button.'), -(u'RadioButton', u'Text', u'Y', None, None, None, None, u'Text', None, u'The visible title to be assigned to the radio button.'), -(u'RadioButton', u'Property', u'N', None, None, None, None, u'Identifier', None, u'A named property to be tied to this radio button. All the buttons tied to the same property become part of the same group.'), -(u'RadioButton', u'Value', u'N', None, None, None, None, u'Formatted', None, u'The value string associated with this button. Selecting the button will set the associated property to this value.'), -(u'RadioButton', u'Order', u'N', 1, 32767, None, None, None, None, u'A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive.'), -(u'RadioButton', u'Help', u'Y', None, None, None, None, u'Text', None, u'The help strings used with the button. The text is optional.'), -(u'TextStyle', u'TextStyle', u'N', None, None, None, None, u'Identifier', None, u'Name of the style. The primary key of this table. This name is embedded in the texts to indicate a style change.'), -(u'TextStyle', u'FaceName', u'N', None, None, None, None, u'Text', None, u'A string indicating the name of the font used. Required. The string must be at most 31 characters long.'), -(u'TextStyle', u'Size', u'N', 0, 32767, None, None, None, None, u'The size of the font used. This size is given in our units (1/12 of the system font height). Assuming that the system font is set to 12 point size, this is equivalent to the point size.'), -(u'TextStyle', u'Color', u'Y', 0, 16777215, None, None, None, None, u'A long integer indicating the color of the string in the RGB format (Red, Green, Blue each 0-255, RGB = R + 256*G + 256^2*B).'), -(u'TextStyle', u'StyleBits', u'Y', 0, 15, None, None, None, None, u'A combination of style bits.'), -(u'UIText', u'Text', u'Y', None, None, None, None, u'Text', None, u'The localized version of the string.'), -(u'UIText', u'Key', u'N', None, None, None, None, u'Identifier', None, u'A unique key that identifies the particular string.'), -(u'_Validation', u'Table', u'N', None, None, None, None, u'Identifier', None, u'Name of table'), -(u'_Validation', u'Description', u'Y', None, None, None, None, u'Text', None, u'Description of column'), -(u'_Validation', u'Column', u'N', None, None, None, None, u'Identifier', None, u'Name of column'), -(u'_Validation', u'Nullable', u'N', None, None, None, None, None, u'Y;N;@', u'Whether the column is nullable'), -(u'_Validation', u'MinValue', u'Y', -2147483647, 2147483647, None, None, None, None, u'Minimum value allowed'), -(u'_Validation', u'MaxValue', u'Y', -2147483647, 2147483647, None, None, None, None, u'Maximum value allowed'), -(u'_Validation', u'KeyTable', u'Y', None, None, None, None, u'Identifier', None, u'For foreign key, Name of table to which data must link'), -(u'_Validation', u'KeyColumn', u'Y', 1, 32, None, None, None, None, u'Column to which foreign key connects'), -(u'_Validation', u'Category', u'Y', None, None, None, None, None, u'Text;Formatted;Template;Condition;Guid;Path;Version;Language;Identifier;Binary;UpperCase;LowerCase;Filename;Paths;AnyPath;WildCardFilename;RegPath;KeyFormatted;CustomSource;Property;Cabinet;Shortcut;URL', u'String category'), -(u'_Validation', u'Set', u'Y', None, None, None, None, u'Text', None, u'Set of values that are permitted'), -(u'AdvtUISequence', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Name of action to invoke, either in the engine or the handler DLL.'), -(u'AdvtUISequence', u'Sequence', u'Y', -4, 32767, None, None, None, None, u'Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action.'), -(u'AdvtUISequence', u'Condition', u'Y', None, None, None, None, u'Condition', None, u'Optional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData.'), -(u'AppId', u'AppId', u'N', None, None, None, None, u'Guid', None, None), -(u'AppId', u'ActivateAtStorage', u'Y', 0, 1, None, None, None, None, None), -(u'AppId', u'DllSurrogate', u'Y', None, None, None, None, u'Text', None, None), -(u'AppId', u'LocalService', u'Y', None, None, None, None, u'Text', None, None), -(u'AppId', u'RemoteServerName', u'Y', None, None, None, None, u'Formatted', None, None), -(u'AppId', u'RunAsInteractiveUser', u'Y', 0, 1, None, None, None, None, None), -(u'AppId', u'ServiceParameters', u'Y', None, None, None, None, u'Text', None, None), -(u'Feature', u'Attributes', u'N', None, None, None, None, None, u'0;1;2;4;5;6;8;9;10;16;17;18;20;21;22;24;25;26;32;33;34;36;37;38;48;49;50;52;53;54', u'Feature attributes'), -(u'Feature', u'Description', u'Y', None, None, None, None, u'Text', None, u'Longer descriptive text describing a visible feature item.'), -(u'Feature', u'Title', u'Y', None, None, None, None, u'Text', None, u'Short text identifying a visible feature item.'), -(u'Feature', u'Feature', u'N', None, None, None, None, u'Identifier', None, u'Primary key used to identify a particular feature record.'), -(u'Feature', u'Directory_', u'Y', None, None, u'Directory', 1, u'UpperCase', None, u'The name of the Directory that can be configured by the UI. A non-null value will enable the browse button.'), -(u'Feature', u'Level', u'N', 0, 32767, None, None, None, None, u'The install level at which record will be initially selected. An install level of 0 will disable an item and prevent its display.'), -(u'Feature', u'Display', u'Y', 0, 32767, None, None, None, None, u'Numeric sort order, used to force a specific display ordering.'), -(u'Feature', u'Feature_Parent', u'Y', None, None, u'Feature', 1, u'Identifier', None, u'Optional key of a parent record in the same table. If the parent is not selected, then the record will not be installed. Null indicates a root item.'), -(u'File', u'Sequence', u'N', 1, 32767, None, None, None, None, u'Sequence with respect to the media images; order must track cabinet order.'), -(u'File', u'Attributes', u'Y', 0, 32767, None, None, None, None, u'Integer containing bit flags representing file attributes (with the decimal value of each bit position in parentheses)'), -(u'File', u'File', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token, must match identifier in cabinet. For uncompressed files, this field is ignored.'), -(u'File', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key referencing Component that controls the file.'), -(u'File', u'FileName', u'N', None, None, None, None, u'Filename', None, u'File name used for installation, may be localized. This may contain a "short name|long name" pair.'), -(u'File', u'FileSize', u'N', 0, 2147483647, None, None, None, None, u'Size of file in bytes (long integer).'), -(u'File', u'Language', u'Y', None, None, None, None, u'Language', None, u'List of decimal language Ids, comma-separated if more than one.'), -(u'File', u'Version', u'Y', None, None, u'File', 1, u'Version', None, u'Version string for versioned files; Blank for unversioned files.'), -(u'Class', u'Attributes', u'Y', None, 32767, None, None, None, None, u'Class registration attributes.'), -(u'Class', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the CLSID factory to be operational.'), -(u'Class', u'Description', u'Y', None, None, None, None, u'Text', None, u'Localized description for the Class.'), -(u'Class', u'Argument', u'Y', None, None, None, None, u'Formatted', None, u'optional argument for LocalServers.'), -(u'Class', u'AppId_', u'Y', None, None, u'AppId', 1, u'Guid', None, u'Optional AppID containing DCOM information for associated application (string GUID).'), -(u'Class', u'CLSID', u'N', None, None, None, None, u'Guid', None, u'The CLSID of an OLE factory.'), -(u'Class', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.'), -(u'Class', u'Context', u'N', None, None, None, None, u'Identifier', None, u'The numeric server context for this server. CLSCTX_xxxx'), -(u'Class', u'DefInprocHandler', u'Y', None, None, None, None, u'Filename', u'1;2;3', u'Optional default inproc handler. Only optionally provided if Context=CLSCTX_LOCAL_SERVER. Typically "ole32.dll" or "mapi32.dll"'), -(u'Class', u'FileTypeMask', u'Y', None, None, None, None, u'Text', None, u'Optional string containing information for the HKCRthis CLSID) key. If multiple patterns exist, they must be delimited by a semicolon, and numeric subkeys will be generated: 0,1,2...'), -(u'Class', u'Icon_', u'Y', None, None, u'Icon', 1, u'Identifier', None, u'Optional foreign key into the Icon Table, specifying the icon file associated with this CLSID. Will be written under the DefaultIcon key.'), -(u'Class', u'IconIndex', u'Y', -32767, 32767, None, None, None, None, u'Optional icon index.'), -(u'Class', u'ProgId_Default', u'Y', None, None, u'ProgId', 1, u'Text', None, u'Optional ProgId associated with this CLSID.'), -(u'Component', u'Condition', u'Y', None, None, None, None, u'Condition', None, u"A conditional statement that will disable this component if the specified condition evaluates to the 'True' state. If a component is disabled, it will not be installed, regardless of the 'Action' state associated with the component."), -(u'Component', u'Attributes', u'N', None, None, None, None, None, None, u'Remote execution option, one of irsEnum'), -(u'Component', u'Component', u'N', None, None, None, None, u'Identifier', None, u'Primary key used to identify a particular component record.'), -(u'Component', u'ComponentId', u'Y', None, None, None, None, u'Guid', None, u'A string GUID unique to this component, version, and language.'), -(u'Component', u'Directory_', u'N', None, None, u'Directory', 1, u'Identifier', None, u'Required key of a Directory table record. This is actually a property name whose value contains the actual path, set either by the AppSearch action or with the default setting obtained from the Directory table.'), -(u'Component', u'KeyPath', u'Y', None, None, u'File;Registry;ODBCDataSource', 1, u'Identifier', None, u'Either the primary key into the File table, Registry table, or ODBCDataSource table. This extract path is stored when the component is installed, and is used to detect the presence of the component and to return the path to it.'), -(u'ProgId', u'Description', u'Y', None, None, None, None, u'Text', None, u'Localized description for the Program identifier.'), -(u'ProgId', u'Icon_', u'Y', None, None, u'Icon', 1, u'Identifier', None, u'Optional foreign key into the Icon Table, specifying the icon file associated with this ProgId. Will be written under the DefaultIcon key.'), -(u'ProgId', u'IconIndex', u'Y', -32767, 32767, None, None, None, None, u'Optional icon index.'), -(u'ProgId', u'ProgId', u'N', None, None, None, None, u'Text', None, u'The Program Identifier. Primary key.'), -(u'ProgId', u'Class_', u'Y', None, None, u'Class', 1, u'Guid', None, u'The CLSID of an OLE factory corresponding to the ProgId.'), -(u'ProgId', u'ProgId_Parent', u'Y', None, None, u'ProgId', 1, u'Text', None, u'The Parent Program Identifier. If specified, the ProgId column becomes a version independent prog id.'), -(u'CompLocator', u'Type', u'Y', 0, 1, None, None, None, None, u'A boolean value that determines if the registry value is a filename or a directory location.'), -(u'CompLocator', u'Signature_', u'N', None, None, None, None, u'Identifier', None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table.'), -(u'CompLocator', u'ComponentId', u'N', None, None, None, None, u'Guid', None, u'A string GUID unique to this component, version, and language.'), -(u'Complus', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key referencing Component that controls the ComPlus component.'), -(u'Complus', u'ExpType', u'Y', 0, 32767, None, None, None, None, u'ComPlus component attributes.'), -(u'Directory', u'Directory', u'N', None, None, None, None, u'Identifier', None, u'Unique identifier for directory entry, primary key. If a property by this name is defined, it contains the full path to the directory.'), -(u'Directory', u'DefaultDir', u'N', None, None, None, None, u'DefaultDir', None, u"The default sub-path under parent's path."), -(u'Directory', u'Directory_Parent', u'Y', None, None, u'Directory', 1, u'Identifier', None, u'Reference to the entry in this table specifying the default parent directory. A record parented to itself or with a Null parent represents a root of the install tree.'), -(u'CreateFolder', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table.'), -(u'CreateFolder', u'Directory_', u'N', None, None, u'Directory', 1, u'Identifier', None, u'Primary key, could be foreign key into the Directory table.'), -(u'CustomAction', u'Type', u'N', 1, 16383, None, None, None, None, u'The numeric custom action type, consisting of source location, code type, entry, option flags.'), -(u'CustomAction', u'Action', u'N', None, None, None, None, u'Identifier', None, u'Primary key, name of action, normally appears in sequence table unless private use.'), -(u'CustomAction', u'Source', u'Y', None, None, None, None, u'CustomSource', None, u'The table reference of the source of the code.'), -(u'CustomAction', u'Target', u'Y', None, None, None, None, u'Formatted', None, u'Excecution parameter, depends on the type of custom action'), -(u'DrLocator', u'Signature_', u'N', None, None, None, None, u'Identifier', None, u'The Signature_ represents a unique file signature and is also the foreign key in the Signature table.'), -(u'DrLocator', u'Path', u'Y', None, None, None, None, u'AnyPath', None, u'The path on the user system. This is a either a subpath below the value of the Parent or a full path. The path may contain properties enclosed within [ ] that will be expanded.'), -(u'DrLocator', u'Depth', u'Y', 0, 32767, None, None, None, None, u'The depth below the path to which the Signature_ is recursively searched. If absent, the depth is assumed to be 0.'), -(u'DrLocator', u'Parent', u'Y', None, None, None, None, u'Identifier', None, u'The parent file signature. It is also a foreign key in the Signature table. If null and the Path column does not expand to a full path, then all the fixed drives of the user system are searched using the Path.'), -(u'DuplicateFile', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'Foreign key referencing the source file to be duplicated.'), -(u'DuplicateFile', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key referencing Component that controls the duplicate file.'), -(u'DuplicateFile', u'DestFolder', u'Y', None, None, None, None, u'Identifier', None, u'Name of a property whose value is assumed to resolve to the full pathname to a destination folder.'), -(u'DuplicateFile', u'DestName', u'Y', None, None, None, None, u'Filename', None, u'Filename to be given to the duplicate file.'), -(u'DuplicateFile', u'FileKey', u'N', None, None, None, None, u'Identifier', None, u'Primary key used to identify a particular file entry'), -(u'Environment', u'Name', u'N', None, None, None, None, u'Text', None, u'The name of the environmental value.'), -(u'Environment', u'Value', u'Y', None, None, None, None, u'Formatted', None, u'The value to set in the environmental settings.'), -(u'Environment', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table referencing component that controls the installing of the environmental value.'), -(u'Environment', u'Environment', u'N', None, None, None, None, u'Identifier', None, u'Unique identifier for the environmental variable setting'), -(u'Error', u'Error', u'N', 0, 32767, None, None, None, None, u'Integer error number, obtained from header file IError(...) macros.'), -(u'Error', u'Message', u'Y', None, None, None, None, u'Template', None, u'Error formatting template, obtained from user ed. or localizers.'), -(u'Extension', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the CLSID factory to be operational.'), -(u'Extension', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.'), -(u'Extension', u'Extension', u'N', None, None, None, None, u'Text', None, u'The extension associated with the table row.'), -(u'Extension', u'MIME_', u'Y', None, None, u'MIME', 1, u'Text', None, u'Optional Context identifier, typically "type/format" associated with the extension'), -(u'Extension', u'ProgId_', u'Y', None, None, u'ProgId', 1, u'Text', None, u'Optional ProgId associated with this extension.'), -(u'MIME', u'CLSID', u'Y', None, None, None, None, u'Guid', None, u'Optional associated CLSID.'), -(u'MIME', u'ContentType', u'N', None, None, None, None, u'Text', None, u'Primary key. Context identifier, typically "type/format".'), -(u'MIME', u'Extension_', u'N', None, None, u'Extension', 1, u'Text', None, u'Optional associated extension (without dot)'), -(u'FeatureComponents', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Foreign key into Feature table.'), -(u'FeatureComponents', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into Component table.'), -(u'FileSFPCatalog', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'File associated with the catalog'), -(u'FileSFPCatalog', u'SFPCatalog_', u'N', None, None, u'SFPCatalog', 1, u'Filename', None, u'Catalog associated with the file'), -(u'SFPCatalog', u'SFPCatalog', u'N', None, None, None, None, u'Filename', None, u'File name for the catalog.'), -(u'SFPCatalog', u'Catalog', u'N', None, None, None, None, u'Binary', None, u'SFP Catalog'), -(u'SFPCatalog', u'Dependency', u'Y', None, None, None, None, u'Formatted', None, u'Parent catalog - only used by SFP'), -(u'Font', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'Primary key, foreign key into File table referencing font file.'), -(u'Font', u'FontTitle', u'Y', None, None, None, None, u'Text', None, u'Font name.'), -(u'IniFile', u'Action', u'N', None, None, None, None, None, u'0;1;3', u'The type of modification to be made, one of iifEnum'), -(u'IniFile', u'Value', u'N', None, None, None, None, u'Formatted', None, u'The value to be written.'), -(u'IniFile', u'Key', u'N', None, None, None, None, u'Formatted', None, u'The .INI file key below Section.'), -(u'IniFile', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table referencing component that controls the installing of the .INI value.'), -(u'IniFile', u'FileName', u'N', None, None, None, None, u'Filename', None, u'The .INI file name in which to write the information'), -(u'IniFile', u'IniFile', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'), -(u'IniFile', u'DirProperty', u'Y', None, None, None, None, u'Identifier', None, u'Foreign key into the Directory table denoting the directory where the .INI file is.'), -(u'IniFile', u'Section', u'N', None, None, None, None, u'Formatted', None, u'The .INI file Section.'), -(u'IniLocator', u'Type', u'Y', 0, 2, None, None, None, None, u'An integer value that determines if the .INI value read is a filename or a directory location or to be used as is w/o interpretation.'), -(u'IniLocator', u'Key', u'N', None, None, None, None, u'Text', None, u'Key value (followed by an equals sign in INI file).'), -(u'IniLocator', u'Signature_', u'N', None, None, None, None, u'Identifier', None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table.'), -(u'IniLocator', u'FileName', u'N', None, None, None, None, u'Filename', None, u'The .INI file name.'), -(u'IniLocator', u'Section', u'N', None, None, None, None, u'Text', None, u'Section name within in file (within square brackets in INI file).'), -(u'IniLocator', u'Field', u'Y', 0, 32767, None, None, None, None, u'The field in the .INI line. If Field is null or 0 the entire line is read.'), -(u'IsolatedComponent', u'Component_Application', u'N', None, None, u'Component', 1, u'Identifier', None, u'Key to Component table item for application'), -(u'IsolatedComponent', u'Component_Shared', u'N', None, None, u'Component', 1, u'Identifier', None, u'Key to Component table item to be isolated'), -(u'LaunchCondition', u'Condition', u'N', None, None, None, None, u'Condition', None, u'Expression which must evaluate to TRUE in order for install to commence.'), -(u'LaunchCondition', u'Description', u'N', None, None, None, None, u'Formatted', None, u'Localizable text to display when condition fails and install must abort.'), -(u'LockPermissions', u'Table', u'N', None, None, None, None, u'Identifier', u'Directory;File;Registry', u'Reference to another table name'), -(u'LockPermissions', u'Domain', u'Y', None, None, None, None, u'Formatted', None, u'Domain name for user whose permissions are being set. (usually a property)'), -(u'LockPermissions', u'LockObject', u'N', None, None, None, None, u'Identifier', None, u'Foreign key into Registry or File table'), -(u'LockPermissions', u'Permission', u'Y', -2147483647, 2147483647, None, None, None, None, u'Permission Access mask. Full Control = 268435456 (GENERIC_ALL = 0x10000000)'), -(u'LockPermissions', u'User', u'N', None, None, None, None, u'Formatted', None, u'User for permissions to be set. (usually a property)'), -(u'Media', u'Source', u'Y', None, None, None, None, u'Property', None, u'The property defining the location of the cabinet file.'), -(u'Media', u'Cabinet', u'Y', None, None, None, None, u'Cabinet', None, u'If some or all of the files stored on the media are compressed in a cabinet, the name of that cabinet.'), -(u'Media', u'DiskId', u'N', 1, 32767, None, None, None, None, u'Primary key, integer to determine sort order for table.'), -(u'Media', u'DiskPrompt', u'Y', None, None, None, None, u'Text', None, u'Disk name: the visible text actually printed on the disk. This will be used to prompt the user when this disk needs to be inserted.'), -(u'Media', u'LastSequence', u'N', 0, 32767, None, None, None, None, u'File sequence number for the last file for this media.'), -(u'Media', u'VolumeLabel', u'Y', None, None, None, None, u'Text', None, u'The label attributed to the volume.'), -(u'ModuleComponents', u'Component', u'N', None, None, u'Component', 1, u'Identifier', None, u'Component contained in the module.'), -(u'ModuleComponents', u'Language', u'N', None, None, u'ModuleSignature', 2, None, None, u'Default language ID for module (may be changed by transform).'), -(u'ModuleComponents', u'ModuleID', u'N', None, None, u'ModuleSignature', 1, u'Identifier', None, u'Module containing the component.'), -(u'ModuleSignature', u'Language', u'N', None, None, None, None, None, None, u'Default decimal language of module.'), -(u'ModuleSignature', u'Version', u'N', None, None, None, None, u'Version', None, u'Version of the module.'), -(u'ModuleSignature', u'ModuleID', u'N', None, None, None, None, u'Identifier', None, u'Module identifier (String.GUID).'), -(u'ModuleDependency', u'ModuleID', u'N', None, None, u'ModuleSignature', 1, u'Identifier', None, u'Module requiring the dependency.'), -(u'ModuleDependency', u'ModuleLanguage', u'N', None, None, u'ModuleSignature', 2, None, None, u'Language of module requiring the dependency.'), -(u'ModuleDependency', u'RequiredID', u'N', None, None, None, None, None, None, u'String.GUID of required module.'), -(u'ModuleDependency', u'RequiredLanguage', u'N', None, None, None, None, None, None, u'LanguageID of the required module.'), -(u'ModuleDependency', u'RequiredVersion', u'Y', None, None, None, None, u'Version', None, u'Version of the required version.'), -(u'ModuleExclusion', u'ModuleID', u'N', None, None, u'ModuleSignature', 1, u'Identifier', None, u'String.GUID of module with exclusion requirement.'), -(u'ModuleExclusion', u'ModuleLanguage', u'N', None, None, u'ModuleSignature', 2, None, None, u'LanguageID of module with exclusion requirement.'), -(u'ModuleExclusion', u'ExcludedID', u'N', None, None, None, None, None, None, u'String.GUID of excluded module.'), -(u'ModuleExclusion', u'ExcludedLanguage', u'N', None, None, None, None, None, None, u'Language of excluded module.'), -(u'ModuleExclusion', u'ExcludedMaxVersion', u'Y', None, None, None, None, u'Version', None, u'Maximum version of excluded module.'), -(u'ModuleExclusion', u'ExcludedMinVersion', u'Y', None, None, None, None, u'Version', None, u'Minimum version of excluded module.'), -(u'MoveFile', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'If this component is not "selected" for installation or removal, no action will be taken on the associated MoveFile entry'), -(u'MoveFile', u'DestFolder', u'N', None, None, None, None, u'Identifier', None, u'Name of a property whose value is assumed to resolve to the full path to the destination directory'), -(u'MoveFile', u'DestName', u'Y', None, None, None, None, u'Filename', None, u'Name to be given to the original file after it is moved or copied. If blank, the destination file will be given the same name as the source file'), -(u'MoveFile', u'FileKey', u'N', None, None, None, None, u'Identifier', None, u'Primary key that uniquely identifies a particular MoveFile record'), -(u'MoveFile', u'Options', u'N', 0, 1, None, None, None, None, u'Integer value specifying the MoveFile operating mode, one of imfoEnum'), -(u'MoveFile', u'SourceFolder', u'Y', None, None, None, None, u'Identifier', None, u'Name of a property whose value is assumed to resolve to the full path to the source directory'), -(u'MoveFile', u'SourceName', u'Y', None, None, None, None, u'Text', None, u"Name of the source file(s) to be moved or copied. Can contain the '*' or '?' wildcards."), -(u'MsiAssembly', u'Attributes', u'Y', None, None, None, None, None, None, u'Assembly attributes'), -(u'MsiAssembly', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Foreign key into Feature table.'), -(u'MsiAssembly', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into Component table.'), -(u'MsiAssembly', u'File_Application', u'Y', None, None, u'File', 1, u'Identifier', None, u'Foreign key into File table, denoting the application context for private assemblies. Null for global assemblies.'), -(u'MsiAssembly', u'File_Manifest', u'Y', None, None, u'File', 1, u'Identifier', None, u'Foreign key into the File table denoting the manifest file for the assembly.'), -(u'MsiAssemblyName', u'Name', u'N', None, None, None, None, u'Text', None, u'The name part of the name-value pairs for the assembly name.'), -(u'MsiAssemblyName', u'Value', u'N', None, None, None, None, u'Text', None, u'The value part of the name-value pairs for the assembly name.'), -(u'MsiAssemblyName', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into Component table.'), -(u'MsiDigitalCertificate', u'CertData', u'N', None, None, None, None, u'Binary', None, u'A certificate context blob for a signer certificate'), -(u'MsiDigitalCertificate', u'DigitalCertificate', u'N', None, None, None, None, u'Identifier', None, u'A unique identifier for the row'), -(u'MsiDigitalSignature', u'Table', u'N', None, None, None, None, None, u'Media', u'Reference to another table name (only Media table is supported)'), -(u'MsiDigitalSignature', u'DigitalCertificate_', u'N', None, None, u'MsiDigitalCertificate', 1, u'Identifier', None, u'Foreign key to MsiDigitalCertificate table identifying the signer certificate'), -(u'MsiDigitalSignature', u'Hash', u'Y', None, None, None, None, u'Binary', None, u'The encoded hash blob from the digital signature'), -(u'MsiDigitalSignature', u'SignObject', u'N', None, None, None, None, u'Text', None, u'Foreign key to Media table'), -(u'MsiFileHash', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'Primary key, foreign key into File table referencing file with this hash'), -(u'MsiFileHash', u'Options', u'N', 0, 32767, None, None, None, None, u'Various options and attributes for this hash.'), -(u'MsiFileHash', u'HashPart1', u'N', None, None, None, None, None, None, u'Size of file in bytes (long integer).'), -(u'MsiFileHash', u'HashPart2', u'N', None, None, None, None, None, None, u'Size of file in bytes (long integer).'), -(u'MsiFileHash', u'HashPart3', u'N', None, None, None, None, None, None, u'Size of file in bytes (long integer).'), -(u'MsiFileHash', u'HashPart4', u'N', None, None, None, None, None, None, u'Size of file in bytes (long integer).'), -(u'MsiPatchHeaders', u'StreamRef', u'N', None, None, None, None, u'Identifier', None, u'Primary key. A unique identifier for the row.'), -(u'MsiPatchHeaders', u'Header', u'N', None, None, None, None, u'Binary', None, u'Binary stream. The patch header, used for patch validation.'), -(u'ODBCAttribute', u'Value', u'Y', None, None, None, None, u'Text', None, u'Value for ODBC driver attribute'), -(u'ODBCAttribute', u'Attribute', u'N', None, None, None, None, u'Text', None, u'Name of ODBC driver attribute'), -(u'ODBCAttribute', u'Driver_', u'N', None, None, u'ODBCDriver', 1, u'Identifier', None, u'Reference to ODBC driver in ODBCDriver table'), -(u'ODBCDriver', u'Description', u'N', None, None, None, None, u'Text', None, u'Text used as registered name for driver, non-localized'), -(u'ODBCDriver', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'Reference to key driver file'), -(u'ODBCDriver', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Reference to associated component'), -(u'ODBCDriver', u'Driver', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized.internal token for driver'), -(u'ODBCDriver', u'File_Setup', u'Y', None, None, u'File', 1, u'Identifier', None, u'Optional reference to key driver setup DLL'), -(u'ODBCDataSource', u'Description', u'N', None, None, None, None, u'Text', None, u'Text used as registered name for data source'), -(u'ODBCDataSource', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Reference to associated component'), -(u'ODBCDataSource', u'DataSource', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized.internal token for data source'), -(u'ODBCDataSource', u'DriverDescription', u'N', None, None, None, None, u'Text', None, u'Reference to driver description, may be existing driver'), -(u'ODBCDataSource', u'Registration', u'N', 0, 1, None, None, None, None, u'Registration option: 0=machine, 1=user, others t.b.d.'), -(u'ODBCSourceAttribute', u'Value', u'Y', None, None, None, None, u'Text', None, u'Value for ODBC data source attribute'), -(u'ODBCSourceAttribute', u'Attribute', u'N', None, None, None, None, u'Text', None, u'Name of ODBC data source attribute'), -(u'ODBCSourceAttribute', u'DataSource_', u'N', None, None, u'ODBCDataSource', 1, u'Identifier', None, u'Reference to ODBC data source in ODBCDataSource table'), -(u'ODBCTranslator', u'Description', u'N', None, None, None, None, u'Text', None, u'Text used as registered name for translator'), -(u'ODBCTranslator', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'Reference to key translator file'), -(u'ODBCTranslator', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Reference to associated component'), -(u'ODBCTranslator', u'File_Setup', u'Y', None, None, u'File', 1, u'Identifier', None, u'Optional reference to key translator setup DLL'), -(u'ODBCTranslator', u'Translator', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized.internal token for translator'), -(u'Patch', u'Sequence', u'N', 0, 32767, None, None, None, None, u'Primary key, sequence with respect to the media images; order must track cabinet order.'), -(u'Patch', u'Attributes', u'N', 0, 32767, None, None, None, None, u'Integer containing bit flags representing patch attributes'), -(u'Patch', u'File_', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token, foreign key to File table, must match identifier in cabinet.'), -(u'Patch', u'Header', u'Y', None, None, None, None, u'Binary', None, u'Binary stream. The patch header, used for patch validation.'), -(u'Patch', u'PatchSize', u'N', 0, 2147483647, None, None, None, None, u'Size of patch in bytes (long integer).'), -(u'Patch', u'StreamRef_', u'Y', None, None, None, None, u'Identifier', None, u'Identifier. Foreign key to the StreamRef column of the MsiPatchHeaders table.'), -(u'PatchPackage', u'Media_', u'N', 0, 32767, None, None, None, None, u'Foreign key to DiskId column of Media table. Indicates the disk containing the patch package.'), -(u'PatchPackage', u'PatchId', u'N', None, None, None, None, u'Guid', None, u'A unique string GUID representing this patch.'), -(u'PublishComponent', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Foreign key into the Feature table.'), -(u'PublishComponent', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table.'), -(u'PublishComponent', u'ComponentId', u'N', None, None, None, None, u'Guid', None, u'A string GUID that represents the component id that will be requested by the alien product.'), -(u'PublishComponent', u'AppData', u'Y', None, None, None, None, u'Text', None, u'This is localisable Application specific data that can be associated with a Qualified Component.'), -(u'PublishComponent', u'Qualifier', u'N', None, None, None, None, u'Text', None, u'This is defined only when the ComponentId column is an Qualified Component Id. This is the Qualifier for ProvideComponentIndirect.'), -(u'Registry', u'Name', u'Y', None, None, None, None, u'Formatted', None, u'The registry value name.'), -(u'Registry', u'Value', u'Y', None, None, None, None, u'Formatted', None, u'The registry value.'), -(u'Registry', u'Key', u'N', None, None, None, None, u'RegPath', None, u'The key for the registry value.'), -(u'Registry', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table referencing component that controls the installing of the registry value.'), -(u'Registry', u'Registry', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'), -(u'Registry', u'Root', u'N', -1, 3, None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum.'), -(u'RegLocator', u'Name', u'Y', None, None, None, None, u'Formatted', None, u'The registry value name.'), -(u'RegLocator', u'Type', u'Y', 0, 18, None, None, None, None, u'An integer value that determines if the registry value is a filename or a directory location or to be used as is w/o interpretation.'), -(u'RegLocator', u'Key', u'N', None, None, None, None, u'RegPath', None, u'The key for the registry value.'), -(u'RegLocator', u'Signature_', u'N', None, None, None, None, u'Identifier', None, u'The table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table. If the type is 0, the registry values refers a directory, and _Signature is not a foreign key.'), -(u'RegLocator', u'Root', u'N', 0, 3, None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum.'), -(u'RemoveFile', u'InstallMode', u'N', None, None, None, None, None, u'1;2;3', u'Installation option, one of iimEnum.'), -(u'RemoveFile', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key referencing Component that controls the file to be removed.'), -(u'RemoveFile', u'FileKey', u'N', None, None, None, None, u'Identifier', None, u'Primary key used to identify a particular file entry'), -(u'RemoveFile', u'FileName', u'Y', None, None, None, None, u'WildCardFilename', None, u'Name of the file to be removed.'), -(u'RemoveFile', u'DirProperty', u'N', None, None, None, None, u'Identifier', None, u'Name of a property whose value is assumed to resolve to the full pathname to the folder of the file to be removed.'), -(u'RemoveIniFile', u'Action', u'N', None, None, None, None, None, u'2;4', u'The type of modification to be made, one of iifEnum.'), -(u'RemoveIniFile', u'Value', u'Y', None, None, None, None, u'Formatted', None, u'The value to be deleted. The value is required when Action is iifIniRemoveTag'), -(u'RemoveIniFile', u'Key', u'N', None, None, None, None, u'Formatted', None, u'The .INI file key below Section.'), -(u'RemoveIniFile', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table referencing component that controls the deletion of the .INI value.'), -(u'RemoveIniFile', u'FileName', u'N', None, None, None, None, u'Filename', None, u'The .INI file name in which to delete the information'), -(u'RemoveIniFile', u'DirProperty', u'Y', None, None, None, None, u'Identifier', None, u'Foreign key into the Directory table denoting the directory where the .INI file is.'), -(u'RemoveIniFile', u'Section', u'N', None, None, None, None, u'Formatted', None, u'The .INI file Section.'), -(u'RemoveIniFile', u'RemoveIniFile', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'), -(u'RemoveRegistry', u'Name', u'Y', None, None, None, None, u'Formatted', None, u'The registry value name.'), -(u'RemoveRegistry', u'Key', u'N', None, None, None, None, u'RegPath', None, u'The key for the registry value.'), -(u'RemoveRegistry', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table referencing component that controls the deletion of the registry value.'), -(u'RemoveRegistry', u'Root', u'N', -1, 3, None, None, None, None, u'The predefined root key for the registry value, one of rrkEnum'), -(u'RemoveRegistry', u'RemoveRegistry', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'), -(u'ReserveCost', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Reserve a specified amount of space if this component is to be installed.'), -(u'ReserveCost', u'ReserveFolder', u'Y', None, None, None, None, u'Identifier', None, u'Name of a property whose value is assumed to resolve to the full path to the destination directory'), -(u'ReserveCost', u'ReserveKey', u'N', None, None, None, None, u'Identifier', None, u'Primary key that uniquely identifies a particular ReserveCost record'), -(u'ReserveCost', u'ReserveLocal', u'N', 0, 2147483647, None, None, None, None, u'Disk space to reserve if linked component is installed locally.'), -(u'ReserveCost', u'ReserveSource', u'N', 0, 2147483647, None, None, None, None, u'Disk space to reserve if linked component is installed to run from the source location.'), -(u'SelfReg', u'File_', u'N', None, None, u'File', 1, u'Identifier', None, u'Foreign key into the File table denoting the module that needs to be registered.'), -(u'SelfReg', u'Cost', u'Y', 0, 32767, None, None, None, None, u'The cost of registering the module.'), -(u'ServiceControl', u'Name', u'N', None, None, None, None, u'Formatted', None, u'Name of a service. /, \\, comma and space are invalid'), -(u'ServiceControl', u'Event', u'N', 0, 187, None, None, None, None, u'Bit field: Install: 0x1 = Start, 0x2 = Stop, 0x8 = Delete, Uninstall: 0x10 = Start, 0x20 = Stop, 0x80 = Delete'), -(u'ServiceControl', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Required foreign key into the Component Table that controls the startup of the service'), -(u'ServiceControl', u'ServiceControl', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'), -(u'ServiceControl', u'Arguments', u'Y', None, None, None, None, u'Formatted', None, u'Arguments for the service. Separate by [~].'), -(u'ServiceControl', u'Wait', u'Y', 0, 1, None, None, None, None, u'Boolean for whether to wait for the service to fully start'), -(u'ServiceInstall', u'Name', u'N', None, None, None, None, u'Formatted', None, u'Internal Name of the Service'), -(u'ServiceInstall', u'Description', u'Y', None, None, None, None, u'Text', None, u'Description of service.'), -(u'ServiceInstall', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Required foreign key into the Component Table that controls the startup of the service'), -(u'ServiceInstall', u'Arguments', u'Y', None, None, None, None, u'Formatted', None, u'Arguments to include in every start of the service, passed to WinMain'), -(u'ServiceInstall', u'ServiceInstall', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'), -(u'ServiceInstall', u'Dependencies', u'Y', None, None, None, None, u'Formatted', None, u'Other services this depends on to start. Separate by [~], and end with [~][~]'), -(u'ServiceInstall', u'DisplayName', u'Y', None, None, None, None, u'Formatted', None, u'External Name of the Service'), -(u'ServiceInstall', u'ErrorControl', u'N', -2147483647, 2147483647, None, None, None, None, u'Severity of error if service fails to start'), -(u'ServiceInstall', u'LoadOrderGroup', u'Y', None, None, None, None, u'Formatted', None, u'LoadOrderGroup'), -(u'ServiceInstall', u'Password', u'Y', None, None, None, None, u'Formatted', None, u'password to run service with. (with StartName)'), -(u'ServiceInstall', u'ServiceType', u'N', -2147483647, 2147483647, None, None, None, None, u'Type of the service'), -(u'ServiceInstall', u'StartName', u'Y', None, None, None, None, u'Formatted', None, u'User or object name to run service as'), -(u'ServiceInstall', u'StartType', u'N', 0, 4, None, None, None, None, u'Type of the service'), -(u'Shortcut', u'Name', u'N', None, None, None, None, u'Filename', None, u'The name of the shortcut to be created.'), -(u'Shortcut', u'Description', u'Y', None, None, None, None, u'Text', None, u'The description for the shortcut.'), -(u'Shortcut', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Foreign key into the Component table denoting the component whose selection gates the shortcut creation/deletion.'), -(u'Shortcut', u'Icon_', u'Y', None, None, u'Icon', 1, u'Identifier', None, u'Foreign key into the File table denoting the external icon file for the shortcut.'), -(u'Shortcut', u'IconIndex', u'Y', -32767, 32767, None, None, None, None, u'The icon index for the shortcut.'), -(u'Shortcut', u'Directory_', u'N', None, None, u'Directory', 1, u'Identifier', None, u'Foreign key into the Directory table denoting the directory where the shortcut file is created.'), -(u'Shortcut', u'Target', u'N', None, None, None, None, u'Shortcut', None, u'The shortcut target. This is usually a property that is expanded to a file or a folder that the shortcut points to.'), -(u'Shortcut', u'Arguments', u'Y', None, None, None, None, u'Formatted', None, u'The command-line arguments for the shortcut.'), -(u'Shortcut', u'Shortcut', u'N', None, None, None, None, u'Identifier', None, u'Primary key, non-localized token.'), -(u'Shortcut', u'Hotkey', u'Y', 0, 32767, None, None, None, None, u'The hotkey for the shortcut. It has the virtual-key code for the key in the low-order byte, and the modifier flags in the high-order byte. '), -(u'Shortcut', u'ShowCmd', u'Y', None, None, None, None, None, u'1;3;7', u'The show command for the application window.The following values may be used.'), -(u'Shortcut', u'WkDir', u'Y', None, None, None, None, u'Identifier', None, u'Name of property defining location of working directory.'), -(u'Signature', u'FileName', u'N', None, None, None, None, u'Filename', None, u'The name of the file. This may contain a "short name|long name" pair.'), -(u'Signature', u'Signature', u'N', None, None, None, None, u'Identifier', None, u'The table key. The Signature represents a unique file signature.'), -(u'Signature', u'Languages', u'Y', None, None, None, None, u'Language', None, u'The languages supported by the file.'), -(u'Signature', u'MaxDate', u'Y', 0, 2147483647, None, None, None, None, u'The maximum creation date of the file.'), -(u'Signature', u'MaxSize', u'Y', 0, 2147483647, None, None, None, None, u'The maximum size of the file. '), -(u'Signature', u'MaxVersion', u'Y', None, None, None, None, u'Text', None, u'The maximum version of the file.'), -(u'Signature', u'MinDate', u'Y', 0, 2147483647, None, None, None, None, u'The minimum creation date of the file.'), -(u'Signature', u'MinSize', u'Y', 0, 2147483647, None, None, None, None, u'The minimum size of the file.'), -(u'Signature', u'MinVersion', u'Y', None, None, None, None, u'Text', None, u'The minimum version of the file.'), -(u'TypeLib', u'Feature_', u'N', None, None, u'Feature', 1, u'Identifier', None, u'Required foreign key into the Feature Table, specifying the feature to validate or install in order for the type library to be operational.'), -(u'TypeLib', u'Description', u'Y', None, None, None, None, u'Text', None, None), -(u'TypeLib', u'Component_', u'N', None, None, u'Component', 1, u'Identifier', None, u'Required foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent.'), -(u'TypeLib', u'Directory_', u'Y', None, None, u'Directory', 1, u'Identifier', None, u'Optional. The foreign key into the Directory table denoting the path to the help file for the type library.'), -(u'TypeLib', u'Language', u'N', 0, 32767, None, None, None, None, u'The language of the library.'), -(u'TypeLib', u'Version', u'Y', 0, 16777215, None, None, None, None, u'The version of the library. The minor version is in the lower 8 bits of the integer. The major version is in the next 16 bits. '), -(u'TypeLib', u'Cost', u'Y', 0, 2147483647, None, None, None, None, u'The cost associated with the registration of the typelib. This column is currently optional.'), -(u'TypeLib', u'LibID', u'N', None, None, None, None, u'Guid', None, u'The GUID that represents the library.'), -(u'Upgrade', u'Attributes', u'N', 0, 2147483647, None, None, None, None, u'The attributes of this product set.'), -(u'Upgrade', u'Remove', u'Y', None, None, None, None, u'Formatted', None, u'The list of features to remove when uninstalling a product from this set. The default is "ALL".'), -(u'Upgrade', u'Language', u'Y', None, None, None, None, u'Language', None, u'A comma-separated list of languages for either products in this set or products not in this set.'), -(u'Upgrade', u'ActionProperty', u'N', None, None, None, None, u'UpperCase', None, u'The property to set when a product in this set is found.'), -(u'Upgrade', u'UpgradeCode', u'N', None, None, None, None, u'Guid', None, u'The UpgradeCode GUID belonging to the products in this set.'), -(u'Upgrade', u'VersionMax', u'Y', None, None, None, None, u'Text', None, u'The maximum ProductVersion of the products in this set. The set may or may not include products with this particular version.'), -(u'Upgrade', u'VersionMin', u'Y', None, None, None, None, u'Text', None, u'The minimum ProductVersion of the products in this set. The set may or may not include products with this particular version.'), -(u'Verb', u'Sequence', u'Y', 0, 32767, None, None, None, None, u'Order within the verbs for a particular extension. Also used simply to specify the default verb.'), -(u'Verb', u'Argument', u'Y', None, None, None, None, u'Formatted', None, u'Optional value for the command arguments.'), -(u'Verb', u'Extension_', u'N', None, None, u'Extension', 1, u'Text', None, u'The extension associated with the table row.'), -(u'Verb', u'Verb', u'N', None, None, None, None, u'Text', None, u'The verb for the command.'), -(u'Verb', u'Command', u'Y', None, None, None, None, u'Formatted', None, u'The command text.'), -] - -Error = [ -(0, u'{{Fatal error: }}'), -(1, u'{{Error [1]. }}'), -(2, u'Warning [1]. '), -(3, None), -(4, u'Info [1]. '), -(5, u'The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is [1]. {{The arguments are: [2], [3], [4]}}'), -(6, None), -(7, u'{{Disk full: }}'), -(8, u'Action [Time]: [1]. [2]'), -(9, u'[ProductName]'), -(10, u'{[2]}{, [3]}{, [4]}'), -(11, u'Message type: [1], Argument: [2]'), -(12, u'=== Logging started: [Date] [Time] ==='), -(13, u'=== Logging stopped: [Date] [Time] ==='), -(14, u'Action start [Time]: [1].'), -(15, u'Action ended [Time]: [1]. Return value [2].'), -(16, u'Time remaining: {[1] minutes }{[2] seconds}'), -(17, u'Out of memory. Shut down other applications before retrying.'), -(18, u'Installer is no longer responding.'), -(19, u'Installer stopped prematurely.'), -(20, u'Please wait while Windows configures [ProductName]'), -(21, u'Gathering required information...'), -(22, u'Removing older versions of this application...'), -(23, u'Preparing to remove older versions of this application...'), -(32, u'{[ProductName] }Setup completed successfully.'), -(33, u'{[ProductName] }Setup failed.'), -(1101, u'Error reading from file: [2]. {{ System error [3].}} Verify that the file exists and that you can access it.'), -(1301, u"Cannot create the file '[2]'. A directory with this name already exists. Cancel the install and try installing to a different location."), -(1302, u'Please insert the disk: [2]'), -(1303, u'The installer has insufficient privileges to access this directory: [2]. The installation cannot continue. Log on as administrator or contact your system administrator.'), -(1304, u'Error writing to file: [2]. Verify that you have access to that directory.'), -(1305, u'Error reading from file [2]. {{ System error [3].}} Verify that the file exists and that you can access it.'), -(1306, u"Another application has exclusive access to the file '[2]'. Please shut down all other applications, then click Retry."), -(1307, u'There is not enough disk space to install this file: [2]. Free some disk space and click Retry, or click Cancel to exit.'), -(1308, u'Source file not found: [2]. Verify that the file exists and that you can access it.'), -(1309, u'Error reading from file: [3]. {{ System error [2].}} Verify that the file exists and that you can access it.'), -(1310, u'Error writing to file: [3]. {{ System error [2].}} Verify that you have access to that directory.'), -(1311, u'Source file not found{{(cabinet)}}: [2]. Verify that the file exists and that you can access it.'), -(1312, u"Cannot create the directory '[2]'. A file with this name already exists. Please rename or remove the file and click retry, or click Cancel to exit."), -(1313, u'The volume [2] is currently unavailable. Please select another.'), -(1314, u"The specified path '[2]' is unavailable."), -(1315, u'Unable to write to the specified folder: [2].'), -(1316, u'A network error occurred while attempting to read from the file: [2]'), -(1317, u'An error occurred while attempting to create the directory: [2]'), -(1318, u'A network error occurred while attempting to create the directory: [2]'), -(1319, u'A network error occurred while attempting to open the source file cabinet: [2]'), -(1320, u'The specified path is too long: [2]'), -(1321, u'The Installer has insufficient privileges to modify this file: [2].'), -(1322, u"A portion of the folder path '[2]' is invalid. It is either empty or exceeds the length allowed by the system."), -(1323, u"The folder path '[2]' contains words that are not valid in folder paths."), -(1324, u"The folder path '[2]' contains an invalid character."), -(1325, u"'[2]' is not a valid short file name."), -(1326, u'Error getting file security: [3] GetLastError: [2]'), -(1327, u'Invalid Drive: [2]'), -(1328, u'Error applying patch to file [2]. It has probably been updated by other means, and can no longer be modified by this patch. For more information contact your patch vendor. {{System Error: [3]}}'), -(1329, u'A file that is required cannot be installed because the cabinet file [2] is not digitally signed. This may indicate that the cabinet file is corrupt.'), -(1330, u'A file that is required cannot be installed because the cabinet file [2] has an invalid digital signature. This may indicate that the cabinet file is corrupt.{{ Error [3] was returned by WinVerifyTrust.}}'), -(1331, u'Failed to correctly copy [2] file: CRC error.'), -(1332, u'Failed to correctly move [2] file: CRC error.'), -(1333, u'Failed to correctly patch [2] file: CRC error.'), -(1334, u"The file '[2]' cannot be installed because the file cannot be found in cabinet file '[3]'. This could indicate a network error, an error reading from the CD-ROM, or a problem with this package."), -(1335, u"The cabinet file '[2]' required for this installation is corrupt and cannot be used. This could indicate a network error, an error reading from the CD-ROM, or a problem with this package."), -(1336, u'There was an error creating a temporary file that is needed to complete this installation.{{ Folder: [3]. System error code: [2]}}'), -(1401, u'Could not create key: [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel. '), -(1402, u'Could not open key: [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel. '), -(1403, u'Could not delete value [2] from key [3]. {{ System error [4].}} Verify that you have sufficient access to that key, or contact your support personnel. '), -(1404, u'Could not delete key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel. '), -(1405, u'Could not read value [2] from key [3]. {{ System error [4].}} Verify that you have sufficient access to that key, or contact your support personnel. '), -(1406, u'Could not write value [2] to key [3]. {{ System error [4].}} Verify that you have sufficient access to that key, or contact your support personnel.'), -(1407, u'Could not get value names for key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel.'), -(1408, u'Could not get sub key names for key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel.'), -(1409, u'Could not read security information for key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel.'), -(1410, u'Could not increase the available registry space. [2] KB of free registry space is required for the installation of this application.'), -(1500, u'Another installation is in progress. You must complete that installation before continuing this one.'), -(1501, u'Error accessing secured data. Please make sure the Windows Installer is configured properly and try the install again.'), -(1502, u"User '[2]' has previously initiated an install for product '[3]'. That user will need to run that install again before they can use that product. Your current install will now continue."), -(1503, u"User '[2]' has previously initiated an install for product '[3]'. That user will need to run that install again before they can use that product."), -(1601, u"Out of disk space -- Volume: '[2]'; required space: [3] KB; available space: [4] KB. Free some disk space and retry."), -(1602, u'Are you sure you want to cancel?'), -(1603, u"The file [2][3] is being held in use{ by the following process: Name: [4], Id: [5], Window Title: '[6]'}. Close that application and retry."), -(1604, u"The product '[2]' is already installed, preventing the installation of this product. The two products are incompatible."), -(1605, u"There is not enough disk space on the volume '[2]' to continue the install with recovery enabled. [3] KB are required, but only [4] KB are available. Click Ignore to continue the install without saving recovery information, click Retry to check for available space again, or click Cancel to quit the installation."), -(1606, u'Could not access network location [2].'), -(1607, u'The following applications should be closed before continuing the install:'), -(1608, u'Could not find any previously installed compliant products on the machine for installing this product.'), -(1609, u"An error occurred while applying security settings. [2] is not a valid user or group. This could be a problem with the package, or a problem connecting to a domain controller on the network. Check your network connection and click Retry, or Cancel to end the install. {{Unable to locate the user's SID, system error [3]}}"), -(1701, u'The key [2] is not valid. Verify that you entered the correct key.'), -(1702, u'The installer must restart your system before configuration of [2] can continue. Click Yes to restart now or No if you plan to manually restart later.'), -(1703, u'You must restart your system for the configuration changes made to [2] to take effect. Click Yes to restart now or No if you plan to manually restart later.'), -(1704, u'An installation for [2] is currently suspended. You must undo the changes made by that installation to continue. Do you want to undo those changes?'), -(1705, u'A previous installation for this product is in progress. You must undo the changes made by that installation to continue. Do you want to undo those changes?'), -(1706, u"An installation package for the product [2] cannot be found. Try the installation again using a valid copy of the installation package '[3]'."), -(1707, u'Installation completed successfully.'), -(1708, u'Installation failed.'), -(1709, u'Product: [2] -- [3]'), -(1710, u'You may either restore your computer to its previous state or continue the install later. Would you like to restore?'), -(1711, u'An error occurred while writing installation information to disk. Check to make sure enough disk space is available, and click Retry, or Cancel to end the install.'), -(1712, u'One or more of the files required to restore your computer to its previous state could not be found. Restoration will not be possible.'), -(1713, u'[2] cannot install one of its required products. Contact your technical support group. {{System Error: [3].}}'), -(1714, u'The older version of [2] cannot be removed. Contact your technical support group. {{System Error [3].}}'), -(1715, u'Installed [2]'), -(1716, u'Configured [2]'), -(1717, u'Removed [2]'), -(1718, u'File [2] was rejected by digital signature policy.'), -(1719, u'The Windows Installer Service could not be accessed. This can occur if you are running Windows in safe mode, or if the Windows Installer is not correctly installed. Contact your support personnel for assistance.'), -(1720, u'There is a problem with this Windows Installer package. A script required for this install to complete could not be run. Contact your support personnel or package vendor. {{Custom action [2] script error [3], [4]: [5] Line [6], Column [7], [8] }}'), -(1721, u'There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor. {{Action: [2], location: [3], command: [4] }}'), -(1722, u'There is a problem with this Windows Installer package. A program run as part of the setup did not finish as expected. Contact your support personnel or package vendor. {{Action [2], location: [3], command: [4] }}'), -(1723, u'There is a problem with this Windows Installer package. A DLL required for this install to complete could not be run. Contact your support personnel or package vendor. {{Action [2], entry: [3], library: [4] }}'), -(1724, u'Removal completed successfully.'), -(1725, u'Removal failed.'), -(1726, u'Advertisement completed successfully.'), -(1727, u'Advertisement failed.'), -(1728, u'Configuration completed successfully.'), -(1729, u'Configuration failed.'), -(1730, u'You must be an Administrator to remove this application. To remove this application, you can log on as an Administrator, or contact your technical support group for assistance.'), -(1801, u'The path [2] is not valid. Please specify a valid path.'), -(1802, u'Out of memory. Shut down other applications before retrying.'), -(1803, u'There is no disk in drive [2]. Please insert one and click Retry, or click Cancel to go back to the previously selected volume.'), -(1804, u'There is no disk in drive [2]. Please insert one and click Retry, or click Cancel to return to the browse dialog and select a different volume.'), -(1805, u'The folder [2] does not exist. Please enter a path to an existing folder.'), -(1806, u'You have insufficient privileges to read this folder.'), -(1807, u'A valid destination folder for the install could not be determined.'), -(1901, u'Error attempting to read from the source install database: [2].'), -(1902, u'Scheduling reboot operation: Renaming file [2] to [3]. Must reboot to complete operation.'), -(1903, u'Scheduling reboot operation: Deleting file [2]. Must reboot to complete operation.'), -(1904, u'Module [2] failed to register. HRESULT [3]. Contact your support personnel.'), -(1905, u'Module [2] failed to unregister. HRESULT [3]. Contact your support personnel.'), -(1906, u'Failed to cache package [2]. Error: [3]. Contact your support personnel.'), -(1907, u'Could not register font [2]. Verify that you have sufficient permissions to install fonts, and that the system supports this font.'), -(1908, u'Could not unregister font [2]. Verify that you that you have sufficient permissions to remove fonts.'), -(1909, u'Could not create Shortcut [2]. Verify that the destination folder exists and that you can access it.'), -(1910, u'Could not remove Shortcut [2]. Verify that the shortcut file exists and that you can access it.'), -(1911, u'Could not register type library for file [2]. Contact your support personnel.'), -(1912, u'Could not unregister type library for file [2]. Contact your support personnel.'), -(1913, u'Could not update the ini file [2][3]. Verify that the file exists and that you can access it.'), -(1914, u'Could not schedule file [2] to replace file [3] on reboot. Verify that you have write permissions to file [3].'), -(1915, u'Error removing ODBC driver manager, ODBC error [2]: [3]. Contact your support personnel.'), -(1916, u'Error installing ODBC driver manager, ODBC error [2]: [3]. Contact your support personnel.'), -(1917, u'Error removing ODBC driver: [4], ODBC error [2]: [3]. Verify that you have sufficient privileges to remove ODBC drivers.'), -(1918, u'Error installing ODBC driver: [4], ODBC error [2]: [3]. Verify that the file [4] exists and that you can access it.'), -(1919, u'Error configuring ODBC data source: [4], ODBC error [2]: [3]. Verify that the file [4] exists and that you can access it.'), -(1920, u"Service '[2]' ([3]) failed to start. Verify that you have sufficient privileges to start system services."), -(1921, u"Service '[2]' ([3]) could not be stopped. Verify that you have sufficient privileges to stop system services."), -(1922, u"Service '[2]' ([3]) could not be deleted. Verify that you have sufficient privileges to remove system services."), -(1923, u"Service '[2]' ([3]) could not be installed. Verify that you have sufficient privileges to install system services."), -(1924, u"Could not update environment variable '[2]'. Verify that you have sufficient privileges to modify environment variables."), -(1925, u'You do not have sufficient privileges to complete this installation for all users of the machine. Log on as administrator and then retry this installation.'), -(1926, u"Could not set file security for file '[3]'. Error: [2]. Verify that you have sufficient privileges to modify the security permissions for this file."), -(1927, u'Component Services (COM+ 1.0) are not installed on this computer. This installation requires Component Services in order to complete successfully. Component Services are available on Windows 2000.'), -(1928, u'Error registering COM+ Application. Contact your support personnel for more information.'), -(1929, u'Error unregistering COM+ Application. Contact your support personnel for more information.'), -(1930, u"The description for service '[2]' ([3]) could not be changed."), -(1931, u'The Windows Installer service cannot update the system file [2] because the file is protected by Windows. You may need to update your operating system for this program to work correctly. {{Package version: [3], OS Protected version: [4]}}'), -(1932, u'The Windows Installer service cannot update the protected Windows file [2]. {{Package version: [3], OS Protected version: [4], SFP Error: [5]}}'), -(1933, u'The Windows Installer service cannot update one or more protected Windows files. {{SFP Error: [2]. List of protected files:\\r\\n[3]}}'), -(1934, u'User installations are disabled via policy on the machine.'), -(1935, u'An error occurred during the installation of assembly component [2]. HRESULT: [3]. {{assembly interface: [4], function: [5], assembly name: [6]}}'), -] - -tables=['AdminExecuteSequence', 'AdminUISequence', 'AdvtExecuteSequence', 'BBControl', 'Billboard', 'Binary', 'CheckBox', 'Property', 'ComboBox', 'Control', 'ListBox', 'ActionText', 'ControlCondition', 'ControlEvent', 'Dialog', 'EventMapping', 'InstallExecuteSequence', 'InstallUISequence', 'ListView', 'RadioButton', 'TextStyle', 'UIText', '_Validation', 'Error'] diff --git a/Tools/msi/uploadrelease.bat b/Tools/msi/uploadrelease.bat new file mode 100644 index 000000000000..796763730a61 --- /dev/null +++ b/Tools/msi/uploadrelease.bat @@ -0,0 +1,56 @@ +@setlocal +@echo off + +set D=%~dp0 +set PCBUILD=%D%..\..\PCBuild\ + +set HOST= +set USER= +set TARGET= +set DRYRUN=false + +:CheckOpts +if "%1" EQU "-h" goto Help +if "%1" EQU "-o" (set HOST=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--host" (set HOST=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-u" (set USER=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--user" (set USER=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-t" (set TARGET=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--target" (set TARGET=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--dry-run" (set DRYRUN=true) && shift && goto CheckOpts + +if not defined PLINK where plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" +if not defined PLINK where /R "%ProgramFiles(x86)%\PuTTY" plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" +if not defined PLINK where /R "%ProgramFiles(x86)%" plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" +if not defined PLINK echo Cannot locate plink.exe & exit /B 1 +echo Found plink.exe at %PLINK% + +if not defined PSCP where pscp > "%TEMP%\pscp.loc" 2> nul && set /P pscp= < "%TEMP%\pscp.loc" & del "%TEMP%\pscp.loc" +if not defined PSCP where /R "%ProgramFiles(x86)%\PuTTY" pscp > "%TEMP%\pscp.loc" 2> nul && set /P pscp= < "%TEMP%\pscp.loc" & del "%TEMP%\pscp.loc" +if not defined PSCP where /R "%ProgramFiles(x86)%" pscp > "%TEMP%\pscp.loc" 2> nul && set /P pscp= < "%TEMP%\pscp.loc" & del "%TEMP%\pscp.loc" +if not defined PSCP echo Cannot locate pscp.exe & exit /B 1 +echo Found pscp.exe at %PSCP% + +if not defined GPG where gpg2 > "%TEMP%\gpg.loc" 2> nul && set /P GPG= < "%TEMP%\gpg.loc" & del "%TEMP%\gpg.loc" +if not defined GPG where /R "%PCBUILD%..\externals" gpg2 > "%TEMP%\gpg.loc" 2> nul && set /P GPG= < "%TEMP%\gpg.loc" & del "%TEMP%\gpg.loc" +if not defined GPG echo Cannot locate gpg2.exe. Signatures will not be uploaded & pause +echo Found gpg2.exe at %GPG% + +call "%PCBUILD%env.bat" > nul 2> nul +pushd "%D%" +msbuild /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x86 +msbuild /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x64 /p:IncludeDoc=false +msbuild /v:m /nologo uploadrelease.proj /t:ShowHashes /p:Platform=x86 +msbuild /v:m /nologo uploadrelease.proj /t:ShowHashes /p:Platform=x64 /p:IncludeDoc=false +popd +exit /B 0 + +:Help +echo uploadrelease.bat --host HOST --user USERNAME [--target TARGET] [--dry-run] [-h] +echo. +echo --host (-o) Specify the upload host (required) +echo --user (-u) Specify the user on the host (required) +echo --target (-t) Specify the target directory on the host +echo --dry-run Display commands and filenames without executing them +echo -h Display this help information +echo. diff --git a/Tools/msi/uploadrelease.proj b/Tools/msi/uploadrelease.proj new file mode 100644 index 000000000000..ec4ede5950bb --- /dev/null +++ b/Tools/msi/uploadrelease.proj @@ -0,0 +1,80 @@ + + + + {2D69F2AB-D5D0-4344-84B5-EF6DB34A9BC9} + python + + + $(TARGET) + /srv/www.python.org/ftp/python + true + false + + + + + + + $(DownloadUrlBase.TrimEnd(`/`))/$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber) + $(DownloadUrl.TrimEnd(`/`)) + + + + + $(MSITarget) + + + $(EXETarget) + + + $(EXETarget) + + + + + + + + + + + + + + + + + %(File.CopyTo) + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tools/msi/wix.props b/Tools/msi/wix.props new file mode 100644 index 000000000000..35492f9b8dd1 --- /dev/null +++ b/Tools/msi/wix.props @@ -0,0 +1,12 @@ + + + + + + $(MSBuildThisFileDirectory)\Wix\ + $(ExternalsDir)\Wix\ + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Installer XML\3.9@InstallRoot) + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows Installer XML\3.9@InstallRoot) + $(WixInstallPath)\Wix.targets + + \ No newline at end of file diff --git a/Tools/parser/unparse.py b/Tools/parser/unparse.py index 837cd81aaf85..99727978f8a0 100644 --- a/Tools/parser/unparse.py +++ b/Tools/parser/unparse.py @@ -138,6 +138,14 @@ def _Nonlocal(self, t): self.fill("nonlocal ") interleave(lambda: self.write(", "), self.write, t.names) + def _Await(self, t): + self.write("(") + self.write("await") + if t.value: + self.write(" ") + self.dispatch(t.value) + self.write(")") + def _Yield(self, t): self.write("(") self.write("yield") @@ -211,16 +219,6 @@ def _ClassDef(self, t): if comma: self.write(", ") else: comma = True self.dispatch(e) - if t.starargs: - if comma: self.write(", ") - else: comma = True - self.write("*") - self.dispatch(t.starargs) - if t.kwargs: - if comma: self.write(", ") - else: comma = True - self.write("**") - self.dispatch(t.kwargs) self.write(")") self.enter() @@ -228,11 +226,18 @@ def _ClassDef(self, t): self.leave() def _FunctionDef(self, t): + self.__FunctionDef_helper(t, "def") + + def _AsyncFunctionDef(self, t): + self.__FunctionDef_helper(t, "async def") + + def __FunctionDef_helper(self, t, fill_suffix): self.write("\n") for deco in t.decorator_list: self.fill("@") self.dispatch(deco) - self.fill("def "+t.name + "(") + def_str = fill_suffix+" "+t.name + "(" + self.fill(def_str) self.dispatch(t.args) self.write(")") if t.returns: @@ -243,7 +248,13 @@ def _FunctionDef(self, t): self.leave() def _For(self, t): - self.fill("for ") + self.__For_helper("for ", t) + + def _AsyncFor(self, t): + self.__For_helper("async for ", t) + + def __For_helper(self, fill, t): + self.fill(fill) self.dispatch(t.target) self.write(" in ") self.dispatch(t.iter) @@ -297,6 +308,13 @@ def _With(self, t): self.dispatch(t.body) self.leave() + def _AsyncWith(self, t): + self.fill("async with ") + interleave(lambda: self.write(", "), self.dispatch, t.items) + self.enter() + self.dispatch(t.body) + self.leave() + # expr def _Bytes(self, t): self.write(repr(t.s)) @@ -304,6 +322,45 @@ def _Bytes(self, t): def _Str(self, tree): self.write(repr(tree.s)) + def _JoinedStr(self, t): + self.write("f") + string = io.StringIO() + self._fstring_JoinedStr(t, string.write) + self.write(repr(string.getvalue())) + + def _FormattedValue(self, t): + self.write("f") + string = io.StringIO() + self._fstring_FormattedValue(t, string.write) + self.write(repr(string.getvalue())) + + def _fstring_JoinedStr(self, t, write): + for value in t.values: + meth = getattr(self, "_fstring_" + type(value).__name__) + meth(value, write) + + def _fstring_Str(self, t, write): + value = t.s.replace("{", "{{").replace("}", "}}") + write(value) + + def _fstring_FormattedValue(self, t, write): + write("{") + expr = io.StringIO() + Unparser(t.value, expr) + expr = expr.getvalue().rstrip("\n") + if expr.startswith("{"): + write(" ") # Separate pair of opening brackets as "{ {" + write(expr) + if t.conversion != -1: + conversion = chr(t.conversion) + assert conversion in "sra" + write(f"!{conversion}") + if t.format_spec: + write(":") + meth = getattr(self, "_fstring_" + type(t.format_spec).__name__) + meth(t.format_spec, write) + write("}") + def _Name(self, t): self.write(t.id) @@ -401,7 +458,7 @@ def _UnaryOp(self, t): self.dispatch(t.operand) self.write(")") - binop = { "Add":"+", "Sub":"-", "Mult":"*", "Div":"/", "Mod":"%", + binop = { "Add":"+", "Sub":"-", "Mult":"*", "MatMult":"@", "Div":"/", "Mod":"%", "LShift":"<<", "RShift":">>", "BitOr":"|", "BitXor":"^", "BitAnd":"&", "FloorDiv":"//", "Pow": "**"} def _BinOp(self, t): @@ -450,16 +507,6 @@ def _Call(self, t): if comma: self.write(", ") else: comma = True self.dispatch(e) - if t.starargs: - if comma: self.write(", ") - else: comma = True - self.write("*") - self.dispatch(t.starargs) - if t.kwargs: - if comma: self.write(", ") - else: comma = True - self.write("**") - self.dispatch(t.kwargs) self.write(")") def _Subscript(self, t): @@ -543,8 +590,11 @@ def _arguments(self, t): self.dispatch(t.kwarg.annotation) def _keyword(self, t): - self.write(t.arg) - self.write("=") + if t.arg is None: + self.write("**") + else: + self.write(t.arg) + self.write("=") self.dispatch(t.value) def _Lambda(self, t): diff --git a/Tools/pybench/README b/Tools/pybench/README index e59e6c0ce681..40f7eec79725 100644 --- a/Tools/pybench/README +++ b/Tools/pybench/README @@ -4,7 +4,7 @@ PYBENCH - A Python Benchmark Suite ________________________________________________________________________ Extendable suite of low-level benchmarks for measuring - the performance of the Python implementation + the performance of the Python implementation (interpreter, compiler or VM). pybench is a collection of tests that provides a standardized way to @@ -34,11 +34,11 @@ to have it store the results in a file too. It is usually a good idea to run pybench.py multiple times to see whether the environment, timers and benchmark run-times are suitable -for doing benchmark tests. +for doing benchmark tests. You can use the comparison feature of pybench.py ('pybench.py -c ') to check how well the system behaves in comparison to a -reference run. +reference run. If the differences are well below 10% for each test, then you have a system that is good for doing benchmark testings. Of you get random @@ -232,7 +232,7 @@ class IntegerCounting(Test): # for comparisons of benchmark runs - tests with unequal version # number will not get compared. version = 1.0 - + # The number of abstract operations done in each round of the # test. An operation is the basic unit of what you want to # measure. The benchmark will output the amount of run-time per @@ -264,7 +264,7 @@ class IntegerCounting(Test): # Repeat the operations per round to raise the run-time # per operation significantly above the noise level of the - # for-loop overhead. + # for-loop overhead. # Execute 20 operations (a += 1): a += 1 @@ -358,8 +358,8 @@ Version History - changed the output format a bit to make it look nicer - refactored the APIs somewhat - 1.3+: Steve Holden added the NewInstances test and the filtering - option during the NeedForSpeed sprint; this also triggered a long + 1.3+: Steve Holden added the NewInstances test and the filtering + option during the NeedForSpeed sprint; this also triggered a long discussion on how to improve benchmark timing and finally resulted in the release of 2.0 1.3: initial checkin into the Python SVN repository diff --git a/Tools/pybench/systimes.py b/Tools/pybench/systimes.py old mode 100644 new mode 100755 diff --git a/Tools/pynche/ColorDB.py b/Tools/pynche/ColorDB.py index fcf1b87cd27c..5ced0e71b543 100644 --- a/Tools/pynche/ColorDB.py +++ b/Tools/pynche/ColorDB.py @@ -23,7 +23,6 @@ import sys import re from types import * -import operator class BadColor(Exception): pass @@ -230,9 +229,8 @@ def triplet_to_rrggbb(rgbtuple): return hexname -_maxtuple = (256.0,) * 3 def triplet_to_fractional_rgb(rgbtuple): - return list(map(operator.__div__, rgbtuple, _maxtuple)) + return [x / 256 for x in rgbtuple] def triplet_to_brightness(rgbtuple): diff --git a/Tools/pynche/README b/Tools/pynche/README index d20efc316499..e026159e3c67 100644 --- a/Tools/pynche/README +++ b/Tools/pynche/README @@ -48,7 +48,7 @@ Running Standalone --initfile file -i file - Alternate location of the persistent initialization file. See + Alternate location of the persistent initialization file. See the section on Persistency below. --ignore @@ -80,7 +80,7 @@ Running as a Modal Dialog pyColorChooser.askcolor() - which will popup Pynche as a modal dialog, and return the selected + which will popup Pynche as a modal dialog, and return the selected color. There are some UI differences when running as a modal @@ -106,7 +106,7 @@ Running as a Modal Dialog master[*] the master window to use as the parent of the modal - dialog. Without this argument, pyColorChooser will create + dialog. Without this argument, pyColorChooser will create its own Tkinter.Tk instance as the master. This may not be what you want. @@ -170,7 +170,7 @@ The Proof Window Selected chip color exactly matches the Nearest chip color, you will see the color name appear below the color specification for the Selected chip. - + Clicking on the Nearest color chip selects that color. Color distance is calculated in the 3D space of the RGB color solid and if more than one color name is the same distance from the selected @@ -361,7 +361,7 @@ Color Name Database Files format for both values and names webcolors.txt -- The 140 color names that Tim Peters and his - sister say NS and MSIE both understand (with some controversy over + sister say NS and MSIE both understand (with some controversy over AliceBlue). namedcolors.txt -- an alternative set of Netscape colors. @@ -369,8 +369,8 @@ Color Name Database Files You can switch between files by choosing "Load palette..." from the "File" menu. This brings up a standard Tk file dialog. Choose the file you want and then click "Ok". If Pynche - understands the format in this file, it will load the database and - update the appropriate windows. If not, it will bring up an error + understands the format in this file, it will load the database and + update the appropriate windows. If not, it will bring up an error dialog. diff --git a/Tools/scripts/checkpip.py b/Tools/scripts/checkpip.py old mode 100644 new mode 100755 index 835101e7b540..8a64eda34af6 --- a/Tools/scripts/checkpip.py +++ b/Tools/scripts/checkpip.py @@ -1,4 +1,4 @@ -#/usr/bin/env python3 +#!/usr/bin/env python3 """ Checks that the version of the projects bundled in ensurepip are the latest versions available. diff --git a/Tools/scripts/diff.py b/Tools/scripts/diff.py index 8be527fd6276..9720a431557a 100755 --- a/Tools/scripts/diff.py +++ b/Tools/scripts/diff.py @@ -8,7 +8,7 @@ """ -import sys, os, time, difflib, optparse +import sys, os, time, difflib, argparse from datetime import datetime, timezone def file_mtime(path): @@ -18,23 +18,25 @@ def file_mtime(path): def main(): - usage = "usage: %prog [options] fromfile tofile" - parser = optparse.OptionParser(usage) - parser.add_option("-c", action="http://github.com/store_true", default=False, help='Produce a context format diff (default)') - parser.add_option("-u", action="http://github.com/store_true", default=False, help='Produce a unified format diff') - parser.add_option("-m", action="http://github.com/store_true", default=False, help='Produce HTML side by side diff (can use -c and -l in conjunction)') - parser.add_option("-n", action="http://github.com/store_true", default=False, help='Produce a ndiff format diff') - parser.add_option("-l", "--lines", type="int", default=3, help='Set number of context lines (default 3)') - (options, args) = parser.parse_args() - - if len(args) == 0: - parser.print_help() - sys.exit(1) - if len(args) != 2: - parser.error("need to specify both a fromfile and tofile") + parser = argparse.ArgumentParser() + parser.add_argument('-c', action='http://github.com/store_true', default=False, + help='Produce a context format diff (default)') + parser.add_argument('-u', action='http://github.com/store_true', default=False, + help='Produce a unified format diff') + parser.add_argument('-m', action='http://github.com/store_true', default=False, + help='Produce HTML side by side diff ' + '(can use -c and -l in conjunction)') + parser.add_argument('-n', action='http://github.com/store_true', default=False, + help='Produce a ndiff format diff') + parser.add_argument('-l', '--lines', type=int, default=3, + help='Set number of context lines (default 3)') + parser.add_argument('fromfile') + parser.add_argument('tofile') + options = parser.parse_args() n = options.lines - fromfile, tofile = args + fromfile = options.fromfile + tofile = options.tofile fromdate = file_mtime(fromfile) todate = file_mtime(tofile) diff --git a/Tools/scripts/dutree.doc b/Tools/scripts/dutree.doc index 2a094261b1c1..97bd2e2e47ca 100644 --- a/Tools/scripts/dutree.doc +++ b/Tools/scripts/dutree.doc @@ -34,13 +34,13 @@ sometimes it's not worth it. I actually wrote a C program the other day : | 1 sm.bak At first I thought I could just keep one local list around -at once, but this seems inherently recursive. Which means +at once, but this seems inherently recursive. Which means I need an real recursive data structure. Maybe you could do it with one of the %assoc arrays Larry uses in the begat programs, but I broke down and got dirty. I think the hardest -part was matching Felix's desired output exactly. It's not +part was matching Felix's desired output exactly. It's not blazingly fast: I should probably inline the &childof routine, -but it *was* faster to write than I could have written the +but it *was* faster to write than I could have written the equivalent C program. diff --git a/Tools/scripts/eptags.py b/Tools/scripts/eptags.py index 671ff11e65ec..401ac7e29cd2 100755 --- a/Tools/scripts/eptags.py +++ b/Tools/scripts/eptags.py @@ -25,7 +25,7 @@ def treat_file(filename, outfp): """Append tags found in file named 'filename' to the open file 'outfp'""" try: fp = open(filename, 'r') - except: + except OSError: sys.stderr.write('Cannot open %s\n'%filename) return charno = 0 diff --git a/Tools/scripts/find_recursionlimit.py b/Tools/scripts/find_recursionlimit.py index 117114642147..b2842a62efdb 100755 --- a/Tools/scripts/find_recursionlimit.py +++ b/Tools/scripts/find_recursionlimit.py @@ -92,7 +92,7 @@ def test_cpickle(_cache={}): def test_compiler_recursion(): # The compiler uses a scaling factor to support additional levels # of recursion. This is a sanity check of that scaling to ensure - # it still raises RuntimeError even at higher recursion limits + # it still raises RecursionError even at higher recursion limits compile("()" * (10 * sys.getrecursionlimit()), "", "single") def check_limit(n, test_func_name): @@ -107,7 +107,7 @@ def check_limit(n, test_func_name): # AttributeError can be raised because of the way e.g. PyDict_GetItem() # silences all exceptions and returns NULL, which is usually interpreted # as "missing attribute". - except (RuntimeError, AttributeError): + except (RecursionError, AttributeError): pass else: print("Yikes!") diff --git a/Tools/scripts/findnocoding.py b/Tools/scripts/findnocoding.py index c0997d6598e4..5f3795e65754 100755 --- a/Tools/scripts/findnocoding.py +++ b/Tools/scripts/findnocoding.py @@ -33,6 +33,7 @@ def walk_python_files(self, paths, *args, **kwargs): decl_re = re.compile(rb'^[ \t\f]*#.*coding[:=][ \t]*([-\w.]+)') +blank_re = re.compile(rb'^[ \t\f]*(?:[#\r\n]|$)') def get_declaration(line): match = decl_re.match(line) @@ -58,7 +59,8 @@ def needs_declaration(fullpath): line1 = infile.readline() line2 = infile.readline() - if get_declaration(line1) or get_declaration(line2): + if (get_declaration(line1) or + blank_re.match(line1) and get_declaration(line2)): # the file does have an encoding declaration, so trust it return False diff --git a/Tools/scripts/ftpmirror.py b/Tools/scripts/ftpmirror.py deleted file mode 100755 index a1b683a319ad..000000000000 --- a/Tools/scripts/ftpmirror.py +++ /dev/null @@ -1,405 +0,0 @@ -#! /usr/bin/env python3 - -"""Mirror a remote ftp subtree into a local directory tree. - -usage: ftpmirror [-v] [-q] [-i] [-m] [-n] [-r] [-s pat] - [-l username [-p passwd [-a account]]] - hostname[:port] [remotedir [localdir]] --v: verbose --q: quiet --i: interactive mode --m: macintosh server (NCSA telnet 2.4) (implies -n -s '*.o') --n: don't log in --r: remove local files/directories no longer pertinent --l username [-p passwd [-a account]]: login info (default .netrc or anonymous) --s pat: skip files matching pattern -hostname: remote host w/ optional port separated by ':' -remotedir: remote directory (default initial) -localdir: local directory (default current) -""" - -import os -import sys -import time -import getopt -import ftplib -import netrc -from fnmatch import fnmatch - -# Print usage message and exit -def usage(*args): - sys.stdout = sys.stderr - for msg in args: print(msg) - print(__doc__) - sys.exit(2) - -verbose = 1 # 0 for -q, 2 for -v -interactive = 0 -mac = 0 -rmok = 0 -nologin = 0 -skippats = ['.', '..', '.mirrorinfo'] - -# Main program: parse command line and start processing -def main(): - global verbose, interactive, mac, rmok, nologin - try: - opts, args = getopt.getopt(sys.argv[1:], 'a:bil:mnp:qrs:v') - except getopt.error as msg: - usage(msg) - login = '' - passwd = '' - account = '' - if not args: usage('hostname missing') - host = args[0] - port = 0 - if ':' in host: - host, port = host.split(':', 1) - port = int(port) - try: - auth = netrc.netrc().authenticators(host) - if auth is not None: - login, account, passwd = auth - except (netrc.NetrcParseError, IOError): - pass - for o, a in opts: - if o == '-l': login = a - if o == '-p': passwd = a - if o == '-a': account = a - if o == '-v': verbose = verbose + 1 - if o == '-q': verbose = 0 - if o == '-i': interactive = 1 - if o == '-m': mac = 1; nologin = 1; skippats.append('*.o') - if o == '-n': nologin = 1 - if o == '-r': rmok = 1 - if o == '-s': skippats.append(a) - remotedir = '' - localdir = '' - if args[1:]: - remotedir = args[1] - if args[2:]: - localdir = args[2] - if args[3:]: usage('too many arguments') - # - f = ftplib.FTP() - if verbose: print("Connecting to '%s%s'..." % (host, - (port and ":%d"%port or ""))) - f.connect(host,port) - if not nologin: - if verbose: - print('Logging in as %r...' % (login or 'anonymous')) - f.login(login, passwd, account) - if verbose: print('OK.') - pwd = f.pwd() - if verbose > 1: print('PWD =', repr(pwd)) - if remotedir: - if verbose > 1: print('cwd(%s)' % repr(remotedir)) - f.cwd(remotedir) - if verbose > 1: print('OK.') - pwd = f.pwd() - if verbose > 1: print('PWD =', repr(pwd)) - # - mirrorsubdir(f, localdir) - -# Core logic: mirror one subdirectory (recursively) -def mirrorsubdir(f, localdir): - pwd = f.pwd() - if localdir and not os.path.isdir(localdir): - if verbose: print('Creating local directory', repr(localdir)) - try: - makedir(localdir) - except OSError as msg: - print("Failed to establish local directory", repr(localdir)) - return - infofilename = os.path.join(localdir, '.mirrorinfo') - try: - text = open(infofilename, 'r').read() - except IOError as msg: - text = '{}' - try: - info = eval(text) - except (SyntaxError, NameError): - print('Bad mirror info in', repr(infofilename)) - info = {} - subdirs = [] - listing = [] - if verbose: print('Listing remote directory %r...' % (pwd,)) - f.retrlines('LIST', listing.append) - filesfound = [] - for line in listing: - if verbose > 1: print('-->', repr(line)) - if mac: - # Mac listing has just filenames; - # trailing / means subdirectory - filename = line.strip() - mode = '-' - if filename[-1:] == '/': - filename = filename[:-1] - mode = 'd' - infostuff = '' - else: - # Parse, assuming a UNIX listing - words = line.split(None, 8) - if len(words) < 6: - if verbose > 1: print('Skipping short line') - continue - filename = words[-1].lstrip() - i = filename.find(" -> ") - if i >= 0: - # words[0] had better start with 'l'... - if verbose > 1: - print('Found symbolic link %r' % (filename,)) - linkto = filename[i+4:] - filename = filename[:i] - infostuff = words[-5:-1] - mode = words[0] - skip = 0 - for pat in skippats: - if fnmatch(filename, pat): - if verbose > 1: - print('Skip pattern', repr(pat), end=' ') - print('matches', repr(filename)) - skip = 1 - break - if skip: - continue - if mode[0] == 'd': - if verbose > 1: - print('Remembering subdirectory', repr(filename)) - subdirs.append(filename) - continue - filesfound.append(filename) - if filename in info and info[filename] == infostuff: - if verbose > 1: - print('Already have this version of',repr(filename)) - continue - fullname = os.path.join(localdir, filename) - tempname = os.path.join(localdir, '@'+filename) - if interactive: - doit = askabout('file', filename, pwd) - if not doit: - if filename not in info: - info[filename] = 'Not retrieved' - continue - try: - os.unlink(tempname) - except OSError: - pass - if mode[0] == 'l': - if verbose: - print("Creating symlink %r -> %r" % (filename, linkto)) - try: - os.symlink(linkto, tempname) - except IOError as msg: - print("Can't create %r: %s" % (tempname, msg)) - continue - else: - try: - fp = open(tempname, 'wb') - except IOError as msg: - print("Can't create %r: %s" % (tempname, msg)) - continue - if verbose: - print('Retrieving %r from %r as %r...' % (filename, pwd, fullname)) - if verbose: - fp1 = LoggingFile(fp, 1024, sys.stdout) - else: - fp1 = fp - t0 = time.time() - try: - f.retrbinary('RETR ' + filename, - fp1.write, 8*1024) - except ftplib.error_perm as msg: - print(msg) - t1 = time.time() - bytes = fp.tell() - fp.close() - if fp1 != fp: - fp1.close() - try: - os.unlink(fullname) - except OSError: - pass # Ignore the error - try: - os.rename(tempname, fullname) - except OSError as msg: - print("Can't rename %r to %r: %s" % (tempname, fullname, msg)) - continue - info[filename] = infostuff - writedict(info, infofilename) - if verbose and mode[0] != 'l': - dt = t1 - t0 - kbytes = bytes / 1024.0 - print(int(round(kbytes)), end=' ') - print('Kbytes in', end=' ') - print(int(round(dt)), end=' ') - print('seconds', end=' ') - if t1 > t0: - print('(~%d Kbytes/sec)' % \ - int(round(kbytes/dt),)) - print() - # - # Remove files from info that are no longer remote - deletions = 0 - for filename in list(info.keys()): - if filename not in filesfound: - if verbose: - print("Removing obsolete info entry for", end=' ') - print(repr(filename), "in", repr(localdir or ".")) - del info[filename] - deletions = deletions + 1 - if deletions: - writedict(info, infofilename) - # - # Remove local files that are no longer in the remote directory - try: - if not localdir: names = os.listdir(os.curdir) - else: names = os.listdir(localdir) - except OSError: - names = [] - for name in names: - if name[0] == '.' or name in info or name in subdirs: - continue - skip = 0 - for pat in skippats: - if fnmatch(name, pat): - if verbose > 1: - print('Skip pattern', repr(pat), end=' ') - print('matches', repr(name)) - skip = 1 - break - if skip: - continue - fullname = os.path.join(localdir, name) - if not rmok: - if verbose: - print('Local file', repr(fullname), end=' ') - print('is no longer pertinent') - continue - if verbose: print('Removing local file/dir', repr(fullname)) - remove(fullname) - # - # Recursively mirror subdirectories - for subdir in subdirs: - if interactive: - doit = askabout('subdirectory', subdir, pwd) - if not doit: continue - if verbose: print('Processing subdirectory', repr(subdir)) - localsubdir = os.path.join(localdir, subdir) - pwd = f.pwd() - if verbose > 1: - print('Remote directory now:', repr(pwd)) - print('Remote cwd', repr(subdir)) - try: - f.cwd(subdir) - except ftplib.error_perm as msg: - print("Can't chdir to", repr(subdir), ":", repr(msg)) - else: - if verbose: print('Mirroring as', repr(localsubdir)) - mirrorsubdir(f, localsubdir) - if verbose > 1: print('Remote cwd ..') - f.cwd('..') - newpwd = f.pwd() - if newpwd != pwd: - print('Ended up in wrong directory after cd + cd ..') - print('Giving up now.') - break - else: - if verbose > 1: print('OK.') - -# Helper to remove a file or directory tree -def remove(fullname): - if os.path.isdir(fullname) and not os.path.islink(fullname): - try: - names = os.listdir(fullname) - except OSError: - names = [] - ok = 1 - for name in names: - if not remove(os.path.join(fullname, name)): - ok = 0 - if not ok: - return 0 - try: - os.rmdir(fullname) - except OSError as msg: - print("Can't remove local directory %r: %s" % (fullname, msg)) - return 0 - else: - try: - os.unlink(fullname) - except OSError as msg: - print("Can't remove local file %r: %s" % (fullname, msg)) - return 0 - return 1 - -# Wrapper around a file for writing to write a hash sign every block. -class LoggingFile: - def __init__(self, fp, blocksize, outfp): - self.fp = fp - self.bytes = 0 - self.hashes = 0 - self.blocksize = blocksize - self.outfp = outfp - def write(self, data): - self.bytes = self.bytes + len(data) - hashes = int(self.bytes) / self.blocksize - while hashes > self.hashes: - self.outfp.write('#') - self.outfp.flush() - self.hashes = self.hashes + 1 - self.fp.write(data) - def close(self): - self.outfp.write('\n') - -def raw_input(prompt): - sys.stdout.write(prompt) - sys.stdout.flush() - return sys.stdin.readline() - -# Ask permission to download a file. -def askabout(filetype, filename, pwd): - prompt = 'Retrieve %s %s from %s ? [ny] ' % (filetype, filename, pwd) - while 1: - reply = raw_input(prompt).strip().lower() - if reply in ['y', 'ye', 'yes']: - return 1 - if reply in ['', 'n', 'no', 'nop', 'nope']: - return 0 - print('Please answer yes or no.') - -# Create a directory if it doesn't exist. Recursively create the -# parent directory as well if needed. -def makedir(pathname): - if os.path.isdir(pathname): - return - dirname = os.path.dirname(pathname) - if dirname: makedir(dirname) - os.mkdir(pathname, 0o777) - -# Write a dictionary to a file in a way that can be read back using -# rval() but is still somewhat readable (i.e. not a single long line). -# Also creates a backup file. -def writedict(dict, filename): - dir, fname = os.path.split(filename) - tempname = os.path.join(dir, '@' + fname) - backup = os.path.join(dir, fname + '~') - try: - os.unlink(backup) - except OSError: - pass - fp = open(tempname, 'w') - fp.write('{\n') - for key, value in dict.items(): - fp.write('%r: %r,\n' % (key, value)) - fp.write('}\n') - fp.close() - try: - os.rename(filename, backup) - except OSError: - pass - os.rename(tempname, filename) - - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/generate_opcode_h.py b/Tools/scripts/generate_opcode_h.py new file mode 100644 index 000000000000..c62f9a5b2301 --- /dev/null +++ b/Tools/scripts/generate_opcode_h.py @@ -0,0 +1,54 @@ +# This script generates the opcode.h header file. + +from __future__ import with_statement + +import sys +header = """/* Auto-generated by Tools/scripts/generate_opcode_h.py */ +#ifndef Py_OPCODE_H +#define Py_OPCODE_H +#ifdef __cplusplus +extern "C" { +#endif + + + /* Instruction opcodes for compiled code */ +""" + +footer = """ +/* 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 */ +""" + + +def main(opcode_py, outfile='Include/opcode.h'): + opcode = {} + exec(open(opcode_py).read(), opcode) + opmap = opcode['opmap'] + with open(outfile, 'w') as fobj: + fobj.write(header) + for name in opcode['opname']: + if name in opmap: + fobj.write("#define %-23s %3s\n" % (name, opmap[name])) + if name == 'POP_EXCEPT': # Special entry for HAVE_ARGUMENT + fobj.write("#define %-23s %3d\n" % + ('HAVE_ARGUMENT', opcode['HAVE_ARGUMENT'])) + fobj.write(footer) + + +if __name__ == '__main__': + main(sys.argv[1], sys.argv[2]) diff --git a/Tools/scripts/gprof2html.py b/Tools/scripts/gprof2html.py index ad828358c148..4ca705c3c61c 100755 --- a/Tools/scripts/gprof2html.py +++ b/Tools/scripts/gprof2html.py @@ -2,7 +2,11 @@ """Transform gprof(1) output into useful HTML.""" -import re, os, sys, cgi, webbrowser +import html +import os +import re +import sys +import webbrowser header = """\ @@ -22,7 +26,7 @@ def add_escapes(filename): with open(filename) as fp: for line in fp: - yield cgi.escape(line) + yield html.escape(line) def main(): diff --git a/Tools/scripts/h2py.py b/Tools/scripts/h2py.py index 4f871d90107f..0967fc29d601 100755 --- a/Tools/scripts/h2py.py +++ b/Tools/scripts/h2py.py @@ -29,7 +29,7 @@ '^[\t ]*#[\t ]*define[\t ]+' '([a-zA-Z0-9_]+)\(([_a-zA-Z][_a-zA-Z0-9]*)\)[\t ]+') -p_include = re.compile('^[\t ]*#[\t ]*include[\t ]+<([a-zA-Z0-9_/\.]+)') +p_include = re.compile('^[\t ]*#[\t ]*include[\t ]+<([^>\n]+)>') p_comment = re.compile(r'/\*([^*]+|\*+[^/])*(\*+/)?') p_cpp_comment = re.compile('//.*') diff --git a/Tools/scripts/highlight.py b/Tools/scripts/highlight.py index aff5caebdf63..66ad868ec3fe 100755 --- a/Tools/scripts/highlight.py +++ b/Tools/scripts/highlight.py @@ -3,11 +3,12 @@ __author__ = 'Raymond Hettinger' -import keyword, tokenize, cgi, re, functools -try: - import builtins -except ImportError: - import __builtin__ as builtins +import builtins +import functools +import html as html_module +import keyword +import re +import tokenize #### Analyze Python Source ################################# @@ -101,7 +102,7 @@ def html_highlight(classified_text,opener='
\n', closer='' % kind)
-        result.append(cgi.escape(text))
+        result.append(html_module.escape(text))
         if kind:
             result.append('')
     result.append(closer)
@@ -140,7 +141,7 @@ def build_html_page(classified_text, title='python',
     'Create a complete HTML page with colorized source code'
     css_str = '\n'.join(['%s %s' % item for item in css.items()])
     result = html_highlight(classified_text)
-    title = cgi.escape(title)
+    title = html_module.escape(title)
     return html.format(title=title, css=css_str, body=result)
 
 #### LaTeX Output ##########################################
@@ -193,7 +194,11 @@ def latex_highlight(classified_text, title = 'python',
 
 
 if __name__ == '__main__':
-    import sys, argparse, webbrowser, os, textwrap
+    import argparse
+    import os.path
+    import sys
+    import textwrap
+    import webbrowser
 
     parser = argparse.ArgumentParser(
             description = 'Add syntax highlighting to Python source code',
diff --git a/Tools/scripts/md5sum.py b/Tools/scripts/md5sum.py
index 521960c17dc5..9cf4bdc9c691 100755
--- a/Tools/scripts/md5sum.py
+++ b/Tools/scripts/md5sum.py
@@ -9,7 +9,7 @@
 rmode = 'rb'
 
 usage = """
-usage: sum5 [-b] [-t] [-l] [-s bufsize] [file ...]
+usage: md5sum.py [-b] [-t] [-l] [-s bufsize] [file ...]
 -b        : read files in binary mode (default)
 -t        : read files in text mode (you almost certainly don't want this!)
 -l        : print last pathname component only
@@ -17,6 +17,7 @@
 file ...  : files to sum; '-' or no files means stdin
 """ % bufsize
 
+import io
 import sys
 import os
 import getopt
@@ -24,7 +25,7 @@
 
 def sum(*files):
     sts = 0
-    if files and isinstance(files[-1], file):
+    if files and isinstance(files[-1], io.IOBase):
         out, files = files[-1], files[:-1]
     else:
         out = sys.stdout
@@ -53,12 +54,14 @@ def printsum(filename, out=sys.stdout):
     return sts
 
 def printsumfp(fp, filename, out=sys.stdout):
-    m = md5.new()
+    m = md5()
     try:
         while 1:
             data = fp.read(bufsize)
             if not data:
                 break
+            if isinstance(data, str):
+                data = data.encode(fp.encoding)
             m.update(data)
     except IOError as msg:
         sys.stderr.write('%s: I/O error: %s\n' % (filename, msg))
diff --git a/Tools/scripts/patchcheck.py b/Tools/scripts/patchcheck.py
index 6f9821bdd658..58b081a9c53f 100755
--- a/Tools/scripts/patchcheck.py
+++ b/Tools/scripts/patchcheck.py
@@ -49,15 +49,31 @@ def mq_patches_applied():
 @status("Getting the list of files that have been added/changed",
         info=lambda x: n_files_str(len(x)))
 def changed_files():
-    """Get the list of changed or added files from Mercurial."""
-    if not os.path.isdir(os.path.join(SRCDIR, '.hg')):
-        sys.exit('need a checkout to get modified files')
-
-    cmd = 'hg status --added --modified --no-status'
-    if mq_patches_applied():
-        cmd += ' --rev qparent'
-    with subprocess.Popen(cmd.split(), stdout=subprocess.PIPE) as st:
-        return [x.decode().rstrip() for x in st.stdout]
+    """Get the list of changed or added files from Mercurial or git."""
+    if os.path.isdir(os.path.join(SRCDIR, '.hg')):
+        cmd = 'hg status --added --modified --no-status'
+        if mq_patches_applied():
+            cmd += ' --rev qparent'
+        with subprocess.Popen(cmd.split(), stdout=subprocess.PIPE) as st:
+            return [x.decode().rstrip() for x in st.stdout]
+    elif os.path.isdir(os.path.join(SRCDIR, '.git')):
+        cmd = 'git status --porcelain'
+        filenames = []
+        with subprocess.Popen(cmd.split(), stdout=subprocess.PIPE) as st:
+            for line in st.stdout:
+                line = line.decode().rstrip()
+                status = set(line[:2])
+                # modified, added or unmerged files
+                if not status.intersection('MAU'):
+                    continue
+                filename = line[3:]
+                if ' -> ' in filename:
+                    # file is renamed
+                    filename = filename.split(' -> ', 2)[1].strip()
+                filenames.append(filename)
+        return filenames
+    else:
+        sys.exit('need a Mercurial or git checkout to get modified files')
 
 
 def report_modified_files(file_paths):
@@ -152,7 +168,8 @@ def main():
     file_paths = changed_files()
     python_files = [fn for fn in file_paths if fn.endswith('.py')]
     c_files = [fn for fn in file_paths if fn.endswith(('.c', '.h'))]
-    doc_files = [fn for fn in file_paths if fn.startswith('Doc')]
+    doc_files = [fn for fn in file_paths if fn.startswith('Doc') and
+                 fn.endswith(('.rst', '.inc'))]
     misc_files = {os.path.join('Misc', 'ACKS'), os.path.join('Misc', 'NEWS')}\
             & set(file_paths)
     # PEP 8 whitespace rules enforcement.
diff --git a/Tools/scripts/pydocgui.pyw b/Tools/scripts/pydocgui.pyw
deleted file mode 100644
index 8e9a3d682ed0..000000000000
--- a/Tools/scripts/pydocgui.pyw
+++ /dev/null
@@ -1,7 +0,0 @@
-# Note:  this file must not be named pydoc.pyw, lest it just end up
-# importing itself (Python began allowing import of .pyw files
-# between 2.2a1 and 2.2a2).
-import pydoc
-
-if __name__ == '__main__':
-   pydoc.gui()
diff --git a/Tools/scripts/pyvenv b/Tools/scripts/pyvenv
index 978d691d1ee6..1043efcfa7d1 100755
--- a/Tools/scripts/pyvenv
+++ b/Tools/scripts/pyvenv
@@ -1,6 +1,12 @@
 #!/usr/bin/env python3
 if __name__ == '__main__':
     import sys
+    import pathlib
+
+    executable = pathlib.Path(sys.executable or 'python3').name
+    print('WARNING: the pyenv script is deprecated in favour of '
+          '`{} -m venv`'.format(exeutable, file=sys.stderr))
+
     rc = 1
     try:
         import venv
diff --git a/Tools/scripts/run_tests.py b/Tools/scripts/run_tests.py
old mode 100755
new mode 100644
index e2a205097812..b582e1325093
--- a/Tools/scripts/run_tests.py
+++ b/Tools/scripts/run_tests.py
@@ -32,6 +32,10 @@ def main(regrtest_args):
             ]
     # Allow user-specified interpreter options to override our defaults.
     args.extend(test.support.args_from_interpreter_flags())
+
+    # Workaround for issue #20361
+    args.extend(['-W', 'error::BytesWarning'])
+
     args.extend(['-m', 'test',    # Run the test suite
                  '-r',            # Randomize test order
                  '-w',            # Re-run failed tests in verbose mode
@@ -44,7 +48,11 @@ def main(regrtest_args):
         args.extend(['-u', 'all,-largefile,-audio,-gui'])
     args.extend(regrtest_args)
     print(' '.join(args))
-    os.execv(sys.executable, args)
+    if sys.platform == 'win32':
+        from subprocess import call
+        sys.exit(call(args))
+    else:
+        os.execv(sys.executable, args)
 
 
 if __name__ == '__main__':
diff --git a/Tools/scripts/serve.py b/Tools/scripts/serve.py
index 68c25f057f32..dae21f2260ff 100755
--- a/Tools/scripts/serve.py
+++ b/Tools/scripts/serve.py
@@ -22,7 +22,7 @@ def app(environ, respond):
         return util.FileWrapper(open(fn, "rb"))
     else:
         respond('404 Not Found', [('Content-Type', 'text/plain')])
-        return ['not found']
+        return [b'not found']
 
 if __name__ == '__main__':
     path = sys.argv[1]
diff --git a/Tools/scripts/win_add2path.py b/Tools/scripts/win_add2path.py
old mode 100755
new mode 100644
index c85bea576fe8..1c9aedc5ed8d
--- a/Tools/scripts/win_add2path.py
+++ b/Tools/scripts/win_add2path.py
@@ -22,7 +22,8 @@ def modify():
     scripts = os.path.join(pythonpath, "Scripts")
     appdata = os.environ["APPDATA"]
     if hasattr(site, "USER_SITE"):
-        userpath = site.USER_SITE.replace(appdata, "%APPDATA%")
+        usersite = site.USER_SITE.replace(appdata, "%APPDATA%")
+        userpath = os.path.dirname(usersite)
         userscripts = os.path.join(userpath, "Scripts")
     else:
         userscripts = None
diff --git a/Tools/ssl/make_ssl_data.py b/Tools/ssl/make_ssl_data.py
old mode 100644
new mode 100755
index 10244d106f02..3fb49852f4c2
--- a/Tools/ssl/make_ssl_data.py
+++ b/Tools/ssl/make_ssl_data.py
@@ -5,8 +5,7 @@
 `library` and `reason` mnemnonics to a more recent OpenSSL version.
 
 It takes two arguments:
-- the path to the OpenSSL include files' directory
-  (e.g. openssl-1.0.1-beta3/include/openssl/)
+- the path to the OpenSSL source tree (e.g. git checkout)
 - the path to the C file to be generated
   (probably Modules/_ssl_data.h)
 """
@@ -15,9 +14,10 @@
 import os
 import re
 import sys
+import _ssl
 
 
-def parse_error_codes(h_file, prefix):
+def parse_error_codes(h_file, prefix, libcode):
     pat = re.compile(r"#define\W+(%s([\w]+))\W+(\d+)\b" % re.escape(prefix))
     codes = []
     with open(h_file, "r", encoding="latin1") as f:
@@ -26,7 +26,8 @@ def parse_error_codes(h_file, prefix):
             if match:
                 code, name, num = match.groups()
                 num = int(num)
-                codes.append((code, name, num))
+                # e.g. ("SSL_R_BAD_DATA", ("ERR_LIB_SSL", "BAD_DATA", 390))
+                codes.append((code, (libcode, name, num)))
     return codes
 
 if __name__ == "__main__":
@@ -34,12 +35,32 @@ def parse_error_codes(h_file, prefix):
     outfile = sys.argv[2]
     use_stdout = outfile == '-'
     f = sys.stdout if use_stdout else open(outfile, "w")
-    error_libraries = (
-        # (library code, mnemonic, error prefix, header file)
-        ('ERR_LIB_PEM', 'PEM', 'PEM_R_', 'pem.h'),
-        ('ERR_LIB_SSL', 'SSL', 'SSL_R_', 'ssl.h'),
-        ('ERR_LIB_X509', 'X509', 'X509_R_', 'x509.h'),
-        )
+    error_libraries = {
+        # mnemonic -> (library code, error prefix, header file)
+        'PEM': ('ERR_LIB_PEM', 'PEM_R_', 'crypto/pem/pem.h'),
+        'SSL': ('ERR_LIB_SSL', 'SSL_R_', 'ssl/ssl.h'),
+        'X509': ('ERR_LIB_X509', 'X509_R_', 'crypto/x509/x509.h'),
+        }
+
+    # Read codes from libraries
+    new_codes = []
+    for libcode, prefix, h_file in sorted(error_libraries.values()):
+        new_codes += parse_error_codes(os.path.join(openssl_inc, h_file),
+                                       prefix, libcode)
+    new_code_nums = set((libcode, num)
+                        for (code, (libcode, name, num)) in new_codes)
+
+    # Merge with existing codes (in case some old codes disappeared).
+    codes = {}
+    for errname, (libnum, errnum) in _ssl.err_names_to_codes.items():
+        lib = error_libraries[_ssl.lib_codes_to_names[libnum]]
+        libcode = lib[0]              # e.g. ERR_LIB_PEM
+        errcode = lib[1] + errname    # e.g. SSL_R_BAD_SSL_SESSION_ID_LENGTH
+        # Only keep it if the numeric codes weren't reused
+        if (libcode, errnum) not in new_code_nums:
+            codes[errcode] = libcode, errname, errnum
+    codes.update(dict(new_codes))
+
     def w(l):
         f.write(l + "\n")
     w("/* File generated by Tools/ssl/make_ssl_data.py */")
@@ -47,21 +68,19 @@ def w(l):
     w("")
 
     w("static struct py_ssl_library_code library_codes[] = {")
-    for libcode, mnemo, _, _ in error_libraries:
+    for mnemo, (libcode, _, _) in sorted(error_libraries.items()):
         w('    {"%s", %s},' % (mnemo, libcode))
     w('    { NULL }')
     w('};')
     w("")
 
     w("static struct py_ssl_error_code error_codes[] = {")
-    for libcode, _, prefix, h_file in error_libraries:
-        codes = parse_error_codes(os.path.join(openssl_inc, h_file), prefix)
-        for code, name, num in sorted(codes):
-            w('  #ifdef %s' % (code))
-            w('    {"%s", %s, %s},' % (name, libcode, code))
-            w('  #else')
-            w('    {"%s", %s, %d},' % (name, libcode, num))
-            w('  #endif')
+    for errcode, (libcode, name, num) in sorted(codes.items()):
+        w('  #ifdef %s' % (errcode))
+        w('    {"%s", %s, %s},' % (name, libcode, errcode))
+        w('  #else')
+        w('    {"%s", %s, %d},' % (name, libcode, num))
+        w('  #endif')
     w('    { NULL }')
     w('};')
     if not use_stdout:
diff --git a/Tools/ssl/sslspeed.vcxproj b/Tools/ssl/sslspeed.vcxproj
new file mode 100644
index 000000000000..8ec410681efa
--- /dev/null
+++ b/Tools/ssl/sslspeed.vcxproj
@@ -0,0 +1,70 @@
+
+
+  
+    
+      Debug
+      Win32
+    
+    
+      Release
+      Win32
+    
+    
+      Debug
+      x64
+    
+    
+      Release
+      x64
+    
+  
+  
+  
+    {F068BCCF-C0D6-478D-A2C5-26BA3237C992}
+    sslspeed
+  
+  
+  
+  
+  
+  
+  
+    $(OutDir)
+    $(MSBuildProjectDirectory)\$(ArchName)\
+    $(MSBuildProjectDirectory)\$(ArchName)\obj\
+    Application
+    MultiByte
+  
+  
+  
+  
+  
+    
+    
+  
+  
+  
+    
+      _CONSOLE;%(PreprocessorDefinitions)
+      $(opensslIncDir);%(AdditionalIncludeDirectories)
+    
+    
+      ws2_32.lib;crypt32.lib;libeay$(PyDebugExt).lib;ssleay$(PyDebugExt).lib;%(AdditionalDependencies)
+      $(OriginalOutDir);%(AdditionalLibraryDirectories)
+      Console
+    
+  
+
+  
+    
+      {10615b24-73bf-4efa-93aa-236916321317}
+      false
+    
+    
+      {e5b04cc0-eb4c-42ab-b4dc-18ef95f864b0}
+      false
+    
+  
+
+  
+
\ No newline at end of file
diff --git a/Tools/ssl/test_multiple_versions.py b/Tools/ssl/test_multiple_versions.py
new file mode 100644
index 000000000000..dd57dcf18b82
--- /dev/null
+++ b/Tools/ssl/test_multiple_versions.py
@@ -0,0 +1,241 @@
+#./python
+"""Run Python tests with multiple installations of OpenSSL
+
+The script
+
+  (1) downloads OpenSSL tar bundle
+  (2) extracts it to ../openssl/src/openssl-VERSION/
+  (3) compiles OpenSSL
+  (4) installs OpenSSL into ../openssl/VERSION/
+  (5) forces a recompilation of Python modules using the
+      header and library files from ../openssl/VERSION/
+  (6) runs Python's test suite
+
+The script must be run with Python's build directory as current working
+directory:
+
+    ./python Tools/ssl/test_multiple_versions.py
+
+The script uses LD_RUN_PATH, LD_LIBRARY_PATH, CPPFLAGS and LDFLAGS to bend
+search paths for header files and shared libraries. It's known to work on
+Linux with GCC 4.x.
+
+(c) 2013 Christian Heimes 
+"""
+import logging
+import os
+import tarfile
+import shutil
+import subprocess
+import sys
+from urllib.request import urlopen
+
+log = logging.getLogger("multissl")
+
+OPENSSL_VERSIONS = [
+    "0.9.7m", "0.9.8i", "0.9.8l", "0.9.8m", "0.9.8y", "1.0.0k", "1.0.1e"
+]
+FULL_TESTS = [
+    "test_asyncio", "test_ftplib", "test_hashlib", "test_httplib",
+    "test_imaplib", "test_nntplib", "test_poplib", "test_smtplib",
+    "test_smtpnet", "test_urllib2_localnet", "test_venv"
+]
+MINIMAL_TESTS = ["test_ssl", "test_hashlib"]
+CADEFAULT = True
+HERE = os.path.abspath(os.getcwd())
+DEST_DIR = os.path.abspath(os.path.join(HERE, os.pardir, "openssl"))
+
+
+class BuildSSL:
+    url_template = "https://www.openssl.org/source/openssl-%7B%7D.tar.gz"
+
+    module_files = ["Modules/_ssl.c",
+                    "Modules/socketmodule.c",
+                    "Modules/_hashopenssl.c"]
+
+    def __init__(self, version, openssl_compile_args=(), destdir=DEST_DIR):
+        self._check_python_builddir()
+        self.version = version
+        self.openssl_compile_args = openssl_compile_args
+        # installation directory
+        self.install_dir = os.path.join(destdir, version)
+        # source file
+        self.src_file = os.path.join(destdir, "src",
+                                     "openssl-{}.tar.gz".format(version))
+        # build directory (removed after install)
+        self.build_dir = os.path.join(destdir, "src",
+                                      "openssl-{}".format(version))
+
+    @property
+    def openssl_cli(self):
+        """openssl CLI binary"""
+        return os.path.join(self.install_dir, "bin", "openssl")
+
+    @property
+    def openssl_version(self):
+        """output of 'bin/openssl version'"""
+        env = os.environ.copy()
+        env["LD_LIBRARY_PATH"] = self.lib_dir
+        cmd = [self.openssl_cli, "version"]
+        return self._subprocess_output(cmd, env=env)
+
+    @property
+    def pyssl_version(self):
+        """Value of ssl.OPENSSL_VERSION"""
+        env = os.environ.copy()
+        env["LD_LIBRARY_PATH"] = self.lib_dir
+        cmd = ["./python", "-c", "import ssl; print(ssl.OPENSSL_VERSION)"]
+        return self._subprocess_output(cmd, env=env)
+
+    @property
+    def include_dir(self):
+        return os.path.join(self.install_dir, "include")
+
+    @property
+    def lib_dir(self):
+        return os.path.join(self.install_dir, "lib")
+
+    @property
+    def has_openssl(self):
+        return os.path.isfile(self.openssl_cli)
+
+    @property
+    def has_src(self):
+        return os.path.isfile(self.src_file)
+
+    def _subprocess_call(self, cmd, stdout=subprocess.DEVNULL, env=None,
+                         **kwargs):
+        log.debug("Call '{}'".format(" ".join(cmd)))
+        return subprocess.check_call(cmd, stdout=stdout, env=env, **kwargs)
+
+    def _subprocess_output(self, cmd, env=None, **kwargs):
+        log.debug("Call '{}'".format(" ".join(cmd)))
+        out = subprocess.check_output(cmd, env=env)
+        return out.strip().decode("utf-8")
+
+    def _check_python_builddir(self):
+        if not os.path.isfile("python") or not os.path.isfile("setup.py"):
+            raise ValueError("Script must be run in Python build directory")
+
+    def _download_openssl(self):
+        """Download OpenSSL source dist"""
+        src_dir = os.path.dirname(self.src_file)
+        if not os.path.isdir(src_dir):
+            os.makedirs(src_dir)
+        url = self.url_template.format(self.version)
+        log.info("Downloading OpenSSL from {}".format(url))
+        req = urlopen(url, cadefault=CADEFAULT)
+        # KISS, read all, write all
+        data = req.read()
+        log.info("Storing {}".format(self.src_file))
+        with open(self.src_file, "wb") as f:
+            f.write(data)
+
+    def _unpack_openssl(self):
+        """Unpack tar.gz bundle"""
+        # cleanup
+        if os.path.isdir(self.build_dir):
+            shutil.rmtree(self.build_dir)
+        os.makedirs(self.build_dir)
+
+        tf = tarfile.open(self.src_file)
+        base = "openssl-{}/".format(self.version)
+        # force extraction into build dir
+        members = tf.getmembers()
+        for member in members:
+            if not member.name.startswith(base):
+                raise ValueError(member.name)
+            member.name = member.name[len(base):]
+        log.info("Unpacking files to {}".format(self.build_dir))
+        tf.extractall(self.build_dir, members)
+
+    def _build_openssl(self):
+        """Now build openssl"""
+        log.info("Running build in {}".format(self.install_dir))
+        cwd = self.build_dir
+        cmd = ["./config", "shared", "--prefix={}".format(self.install_dir)]
+        cmd.extend(self.openssl_compile_args)
+        self._subprocess_call(cmd, cwd=cwd)
+        self._subprocess_call(["make"], cwd=cwd)
+
+    def _install_openssl(self, remove=True):
+        self._subprocess_call(["make", "install"], cwd=self.build_dir)
+        if remove:
+            shutil.rmtree(self.build_dir)
+
+    def install_openssl(self):
+        if not self.has_openssl:
+            if not self.has_src:
+                self._download_openssl()
+            else:
+                log.debug("Already has src {}".format(self.src_file))
+            self._unpack_openssl()
+            self._build_openssl()
+            self._install_openssl()
+        else:
+            log.info("Already has installation {}".format(self.install_dir))
+        # validate installation
+        version = self.openssl_version
+        if self.version not in version:
+            raise ValueError(version)
+
+    def touch_pymods(self):
+        # force a rebuild of all modules that use OpenSSL APIs
+        for fname in self.module_files:
+            os.utime(fname)
+
+    def recompile_pymods(self):
+        log.info("Using OpenSSL build from {}".format(self.build_dir))
+        # overwrite header and library search paths
+        env = os.environ.copy()
+        env["CPPFLAGS"] = "-I{}".format(self.include_dir)
+        env["LDFLAGS"] = "-L{}".format(self.lib_dir)
+        # set rpath
+        env["LD_RUN_PATH"] = self.lib_dir
+
+        log.info("Rebuilding Python modules")
+        self.touch_pymods()
+        cmd = ["./python", "setup.py", "build"]
+        self._subprocess_call(cmd, env=env)
+
+    def check_pyssl(self):
+        version = self.pyssl_version
+        if self.version not in version:
+            raise ValueError(version)
+
+    def run_pytests(self, *args):
+        cmd = ["./python", "-m", "test"]
+        cmd.extend(args)
+        self._subprocess_call(cmd, stdout=None)
+
+    def run_python_tests(self, *args):
+        self.recompile_pymods()
+        self.check_pyssl()
+        self.run_pytests(*args)
+
+
+def main(*args):
+    builders = []
+    for version in OPENSSL_VERSIONS:
+        if version in ("0.9.8i", "0.9.8l"):
+            openssl_compile_args = ("no-asm",)
+        else:
+            openssl_compile_args = ()
+        builder = BuildSSL(version, openssl_compile_args)
+        builder.install_openssl()
+        builders.append(builder)
+
+    for builder in builders:
+        builder.run_python_tests(*args)
+    # final touch
+    builder.touch_pymods()
+
+
+if __name__ == "__main__":
+    logging.basicConfig(level=logging.INFO,
+                        format="*** %(levelname)s %(message)s")
+    args = sys.argv[1:]
+    if not args:
+        args = ["-unetwork", "-v"]
+        args.extend(FULL_TESTS)
+    main(*args)
diff --git a/Tools/stringbench/stringbench.py b/Tools/stringbench/stringbench.py
old mode 100755
new mode 100644
diff --git a/Tools/unicode/comparecodecs.py b/Tools/unicode/comparecodecs.py
old mode 100644
new mode 100755
diff --git a/Tools/unicode/gencodec.py b/Tools/unicode/gencodec.py
index f4c7c038c41a..4c214690d376 100644
--- a/Tools/unicode/gencodec.py
+++ b/Tools/unicode/gencodec.py
@@ -34,7 +34,7 @@
 # Standard undefined Unicode code point
 UNI_UNDEFINED = chr(0xFFFE)
 
-# Placeholder for a missing codepoint
+# Placeholder for a missing code point
 MISSING_CODE = -1
 
 mapRE = re.compile('((?:0x[0-9a-fA-F]+\+?)+)'
@@ -127,7 +127,7 @@ def hexrepr(t, precision=4):
         return 'None'
     try:
         len(t)
-    except:
+    except TypeError:
         return '0x%0*X' % (precision, t)
     try:
         return '(' + ', '.join(['0x%0*X' % (precision, item)
diff --git a/Tools/unicode/genwincodecs.bat b/Tools/unicode/genwincodecs.bat
index 43cab0d6f8e7..ad45c6c44380 100644
--- a/Tools/unicode/genwincodecs.bat
+++ b/Tools/unicode/genwincodecs.bat
@@ -1,7 +1,7 @@
-@rem Recreate some python charmap codecs from the Windows function
-@rem MultiByteToWideChar.
-
-@cd /d %~dp0
-@mkdir build
-@rem Arabic DOS code page
-c:\python30\python genwincodec.py 720 > build/cp720.py
+@rem Recreate some python charmap codecs from the Windows function
+@rem MultiByteToWideChar.
+
+@cd /d %~dp0
+@mkdir build
+@rem Arabic DOS code page
+c:\python30\python genwincodec.py 720 > build/cp720.py
diff --git a/Tools/unicode/makeunicodedata.py b/Tools/unicode/makeunicodedata.py
index 0942508dff1c..713e175c501a 100644
--- a/Tools/unicode/makeunicodedata.py
+++ b/Tools/unicode/makeunicodedata.py
@@ -37,7 +37,12 @@
 VERSION = "3.2"
 
 # The Unicode Database
-UNIDATA_VERSION = "6.3.0"
+# --------------------
+# When changing UCD version please update
+#   * Doc/library/stdtypes.rst, and
+#   * Doc/library/unicodedata.rst
+#   * Doc/reference/lexical_analysis.rst (two occurrences)
+UNIDATA_VERSION = "8.0.0"
 UNICODE_DATA = "UnicodeData%s.txt"
 COMPOSITION_EXCLUSIONS = "CompositionExclusions%s.txt"
 EASTASIAN_WIDTH = "EastAsianWidth%s.txt"
@@ -94,10 +99,11 @@
 # these ranges need to match unicodedata.c:is_unified_ideograph
 cjk_ranges = [
     ('3400', '4DB5'),
-    ('4E00', '9FCC'),
+    ('4E00', '9FD5'),
     ('20000', '2A6D6'),
     ('2A700', '2B734'),
-    ('2B740', '2B81D')
+    ('2B740', '2B81D'),
+    ('2B820', '2CEA1'),
 ]
 
 def maketables(trace=0):
diff --git a/Tools/unittestgui/README.txt b/Tools/unittestgui/README.txt
index 4d809df87054..0a477e167c8d 100644
--- a/Tools/unittestgui/README.txt
+++ b/Tools/unittestgui/README.txt
@@ -1,5 +1,5 @@
-unittestgui.py is GUI framework and application for use with Python unit 
-testing framework. It executes tests written using the framework provided 
+unittestgui.py is GUI framework and application for use with Python unit
+testing framework. It executes tests written using the framework provided
 by the 'unittest' module.
 
 Based on the original by Steve Purcell, from:
diff --git a/Tools/unittestgui/unittestgui.py b/Tools/unittestgui/unittestgui.py
old mode 100644
new mode 100755
index 09a20e28e78e..c3b5fa458420
--- a/Tools/unittestgui/unittestgui.py
+++ b/Tools/unittestgui/unittestgui.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 """
 GUI framework and application for use with Python unit testing framework.
 Execute tests written using the framework provided by the 'unittest' module.
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 000000000000..7d25fb925389
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,229 @@
+# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+# pkg.m4 - Macros to locate and utilise pkg-config.            -*- Autoconf -*-
+# serial 1 (pkg-config-0.24)
+# 
+# Copyright © 2004 Scott James Remnant .
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# PKG_PROG_PKG_CONFIG([MIN-VERSION])
+# ----------------------------------
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
+m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
+AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
+AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+	AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+	_pkg_min_version=m4_default([$1], [0.9.0])
+	AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+		AC_MSG_RESULT([yes])
+	else
+		AC_MSG_RESULT([no])
+		PKG_CONFIG=""
+	fi
+fi[]dnl
+])# PKG_PROG_PKG_CONFIG
+
+# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+#
+# Check to see whether a particular set of modules exists.  Similar
+# to PKG_CHECK_MODULES(), but does not set variables or print errors.
+#
+# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+# only at the first occurence in configure.ac, so if the first place
+# it's called might be skipped (such as if it is within an "if", you
+# have to call PKG_CHECK_EXISTS manually
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+    AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+  m4_default([$2], [:])
+m4_ifvaln([$3], [else
+  $3])dnl
+fi])
+
+# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+# ---------------------------------------------
+m4_define([_PKG_CONFIG],
+[if test -n "$$1"; then
+    pkg_cv_[]$1="$$1"
+ elif test -n "$PKG_CONFIG"; then
+    PKG_CHECK_EXISTS([$3],
+                     [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes ],
+		     [pkg_failed=yes])
+ else
+    pkg_failed=untried
+fi[]dnl
+])# _PKG_CONFIG
+
+# _PKG_SHORT_ERRORS_SUPPORTED
+# -----------------------------
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi[]dnl
+])# _PKG_SHORT_ERRORS_SUPPORTED
+
+
+# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+# [ACTION-IF-NOT-FOUND])
+#
+#
+# Note that if there is a possibility the first call to
+# PKG_CHECK_MODULES might not happen, you should be sure to include an
+# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+#
+#
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+   	AC_MSG_RESULT([no])
+        _PKG_SHORT_ERRORS_SUPPORTED
+        if test $_pkg_short_errors_supported = yes; then
+	        $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
+        else 
+	        $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+	m4_default([$4], [AC_MSG_ERROR(
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT])[]dnl
+        ])
+elif test $pkg_failed = untried; then
+     	AC_MSG_RESULT([no])
+	m4_default([$4], [AC_MSG_FAILURE(
+[The pkg-config script could not be found or is too old.  Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see .])[]dnl
+        ])
+else
+	$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+	$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+        AC_MSG_RESULT([yes])
+	$3
+fi[]dnl
+])# PKG_CHECK_MODULES
+
+
+# PKG_INSTALLDIR(DIRECTORY)
+# -------------------------
+# Substitutes the variable pkgconfigdir as the location where a module
+# should install pkg-config .pc files. By default the directory is
+# $libdir/pkgconfig, but the default can be changed by passing
+# DIRECTORY. The user can override through the --with-pkgconfigdir
+# parameter.
+AC_DEFUN([PKG_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+    [pkg-config installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([pkgconfigdir],
+    [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
+    [with_pkgconfigdir=]pkg_default)
+AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+]) dnl PKG_INSTALLDIR
+
+
+# PKG_NOARCH_INSTALLDIR(DIRECTORY)
+# -------------------------
+# Substitutes the variable noarch_pkgconfigdir as the location where a
+# module should install arch-independent pkg-config .pc files. By
+# default the directory is $datadir/pkgconfig, but the default can be
+# changed by passing DIRECTORY. The user can override through the
+# --with-noarch-pkgconfigdir parameter.
+AC_DEFUN([PKG_NOARCH_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+    [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([noarch-pkgconfigdir],
+    [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
+    [with_noarch_pkgconfigdir=]pkg_default)
+AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+]) dnl PKG_NOARCH_INSTALLDIR
+
+
+# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
+# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+# -------------------------------------------
+# Retrieves the value of the pkg-config variable for the given module.
+AC_DEFUN([PKG_CHECK_VAR],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
+
+_PKG_CONFIG([$1], [variable="][$3]["], [$2])
+AS_VAR_COPY([$1], [pkg_cv_][$1])
+
+AS_VAR_IF([$1], [""], [$5], [$4])dnl
+])# PKG_CHECK_VAR
+
diff --git a/config.guess b/config.guess
index b79252d6b103..1f5c50c0d152 100755
--- a/config.guess
+++ b/config.guess
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright 1992-2013 Free Software Foundation, Inc.
+#   Copyright 1992-2014 Free Software Foundation, Inc.
 
-timestamp='2013-06-10'
+timestamp='2014-03-23'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -50,7 +50,7 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright 1992-2013 Free Software Foundation, Inc.
+Copyright 1992-2014 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -149,7 +149,7 @@ Linux|GNU|GNU/*)
 	LIBC=gnu
 	#endif
 	EOF
-	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
 	;;
 esac
 
@@ -826,7 +826,7 @@ EOF
     *:MINGW*:*)
 	echo ${UNAME_MACHINE}-pc-mingw32
 	exit ;;
-    i*:MSYS*:*)
+    *:MSYS*:*)
 	echo ${UNAME_MACHINE}-pc-msys
 	exit ;;
     i*:windows32*:*)
@@ -969,10 +969,10 @@ EOF
 	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
 	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
 	;;
-    or1k:Linux:*:*)
-	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+    openrisc*:Linux:*:*)
+	echo or1k-unknown-linux-${LIBC}
 	exit ;;
-    or32:Linux:*:*)
+    or32:Linux:*:* | or1k*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
     padre:Linux:*:*)
@@ -1260,16 +1260,26 @@ EOF
 	if test "$UNAME_PROCESSOR" = unknown ; then
 	    UNAME_PROCESSOR=powerpc
 	fi
-	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
-	    if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
-		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
-		grep IS_64BIT_ARCH >/dev/null
-	    then
-		case $UNAME_PROCESSOR in
-		    i386) UNAME_PROCESSOR=x86_64 ;;
-		    powerpc) UNAME_PROCESSOR=powerpc64 ;;
-		esac
+	if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+	    if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		    (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		    grep IS_64BIT_ARCH >/dev/null
+		then
+		    case $UNAME_PROCESSOR in
+			i386) UNAME_PROCESSOR=x86_64 ;;
+			powerpc) UNAME_PROCESSOR=powerpc64 ;;
+		    esac
+		fi
 	    fi
+	elif test "$UNAME_PROCESSOR" = i386 ; then
+	    # Avoid executing cc on OS X 10.9, as it ships with a stub
+	    # that puts up a graphical alert prompting to install
+	    # developer tools.  Any system running Mac OS X 10.7 or
+	    # later (Darwin 11 and later) is required to have a 64-bit
+	    # processor. This is not true of the ARM version of Darwin
+	    # that Apple uses in portable devices.
+	    UNAME_PROCESSOR=x86_64
 	fi
 	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
 	exit ;;
@@ -1361,154 +1371,6 @@ EOF
 	exit ;;
 esac
 
-eval $set_cc_for_build
-cat >$dummy.c <
-# include 
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
-  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
-     I don't know....  */
-  printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include 
-  printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
-	"4"
-#else
-	""
-#endif
-	); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
-  printf ("arm-acorn-riscix\n"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
-  printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
-  int version;
-  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
-  if (version < 4)
-    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
-  else
-    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
-  exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
-  printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
-  printf ("ns32k-encore-mach\n"); exit (0);
-#else
-  printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
-  printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
-  printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
-  printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
-    struct utsname un;
-
-    uname(&un);
-
-    if (strncmp(un.version, "V2", 2) == 0) {
-	printf ("i386-sequent-ptx2\n"); exit (0);
-    }
-    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
-	printf ("i386-sequent-ptx1\n"); exit (0);
-    }
-    printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-#  include 
-#  if defined (BSD)
-#   if BSD == 43
-      printf ("vax-dec-bsd4.3\n"); exit (0);
-#   else
-#    if BSD == 199006
-      printf ("vax-dec-bsd4.3reno\n"); exit (0);
-#    else
-      printf ("vax-dec-bsd\n"); exit (0);
-#    endif
-#   endif
-#  else
-    printf ("vax-dec-bsd\n"); exit (0);
-#  endif
-# else
-    printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
-  printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
-  exit (1);
-}
-EOF
-
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
-	{ echo "$SYSTEM_NAME"; exit; }
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
-    case `getsysinfo -f cpu_type` in
-    c1*)
-	echo c1-convex-bsd
-	exit ;;
-    c2*)
-	if getsysinfo -f scalar_acc
-	then echo c32-convex-bsd
-	else echo c2-convex-bsd
-	fi
-	exit ;;
-    c34*)
-	echo c34-convex-bsd
-	exit ;;
-    c38*)
-	echo c38-convex-bsd
-	exit ;;
-    c4*)
-	echo c4-convex-bsd
-	exit ;;
-    esac
-fi
-
 cat >&2 <."
 version="\
 GNU config.sub ($timestamp)
 
-Copyright 1992-2013 Free Software Foundation, Inc.
+Copyright 1992-2014 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -265,6 +265,7 @@ case $basic_machine in
 	| hexagon \
 	| i370 | i860 | i960 | ia64 \
 	| ip2k | iq2000 \
+	| k1om \
 	| le32 | le64 \
 	| lm32 \
 	| m32c | m32r | m32rle | m68000 | m68k | m88k \
@@ -282,8 +283,10 @@ case $basic_machine in
 	| mips64vr5900 | mips64vr5900el \
 	| mipsisa32 | mipsisa32el \
 	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa32r6 | mipsisa32r6el \
 	| mipsisa64 | mipsisa64el \
 	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64r6 | mipsisa64r6el \
 	| mipsisa64sb1 | mipsisa64sb1el \
 	| mipsisa64sr71k | mipsisa64sr71kel \
 	| mipsr5900 | mipsr5900el \
@@ -295,8 +298,7 @@ case $basic_machine in
 	| nds32 | nds32le | nds32be \
 	| nios | nios2 | nios2eb | nios2el \
 	| ns16k | ns32k \
-	| open8 \
-	| or1k | or32 \
+	| open8 | or1k | or1knd | or32 \
 	| pdp10 | pdp11 | pj | pjl \
 	| powerpc | powerpc64 | powerpc64le | powerpcle \
 	| pyramid \
@@ -324,7 +326,7 @@ case $basic_machine in
 	c6x)
 		basic_machine=tic6x-unknown
 		;;
-	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
+	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
 		basic_machine=$basic_machine-unknown
 		os=-none
 		;;
@@ -381,6 +383,7 @@ case $basic_machine in
 	| hexagon-* \
 	| i*86-* | i860-* | i960-* | ia64-* \
 	| ip2k-* | iq2000-* \
+	| k1om-* \
 	| le32-* | le64-* \
 	| lm32-* \
 	| m32c-* | m32r-* | m32rle-* \
@@ -400,8 +403,10 @@ case $basic_machine in
 	| mips64vr5900-* | mips64vr5900el-* \
 	| mipsisa32-* | mipsisa32el-* \
 	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa32r6-* | mipsisa32r6el-* \
 	| mipsisa64-* | mipsisa64el-* \
 	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64r6-* | mipsisa64r6el-* \
 	| mipsisa64sb1-* | mipsisa64sb1el-* \
 	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
 	| mipsr5900-* | mipsr5900el-* \
@@ -413,6 +418,7 @@ case $basic_machine in
 	| nios-* | nios2-* | nios2eb-* | nios2el-* \
 	| none-* | np1-* | ns16k-* | ns32k-* \
 	| open8-* \
+	| or1k*-* \
 	| orion-* \
 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
 	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
@@ -1374,7 +1380,7 @@ case $os in
 	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
 	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
 	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	-qnx*)
@@ -1592,9 +1598,6 @@ case $basic_machine in
 	mips*-*)
 		os=-elf
 		;;
-	or1k-*)
-		os=-elf
-		;;
 	or32-*)
 		os=-coff
 		;;
diff --git a/configure b/configure
index 5d666ed93eb4..1046f0a1ba86 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for python 3.4.
+# Generated by GNU Autoconf 2.69 for python 3.6.
 #
 # Report bugs to .
 #
@@ -580,8 +580,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='python'
 PACKAGE_TARNAME='python'
-PACKAGE_VERSION='3.4'
-PACKAGE_STRING='python 3.4'
+PACKAGE_VERSION='3.6'
+PACKAGE_STRING='python 3.6'
 PACKAGE_BUGREPORT='http://bugs.python.org/'
 PACKAGE_URL=''
 
@@ -650,6 +650,8 @@ USE_SIGNAL_MODULE
 TCLTK_LIBS
 TCLTK_INCLUDES
 LIBFFI_INCLUDEDIR
+PKG_CONFIG_LIBDIR
+PKG_CONFIG_PATH
 PKG_CONFIG
 SHLIBS
 CFLAGSFORSHARED
@@ -662,14 +664,22 @@ SHLIB_SUFFIX
 LIBTOOL_CRUFT
 OTHER_LIBTOOL_OPT
 UNIVERSAL_ARCH_FLAGS
+CFLAGS_NODIST
 BASECFLAGS
 OPT
+LLVM_PROF_FOUND
+LLVM_PROF_ERR
+LLVM_PROF_FILE
+LLVM_PROF_MERGER
+PGO_PROF_USE_FLAG
+PGO_PROF_GEN_FLAG
 ABIFLAGS
 LN
 MKDIR_P
 INSTALL_DATA
 INSTALL_SCRIPT
 INSTALL_PROGRAM
+OPCODEHGEN
 PYTHON
 ASDLGEN
 ac_ct_READELF
@@ -690,15 +700,17 @@ BLDLIBRARY
 DLLLIBRARY
 LDLIBRARY
 LIBRARY
-MULTIARCH
 BUILDEXEEXT
 EGREP
-GREP
-CPP
 NO_AS_NEEDED
+PLATFORM_TRIPLET
+PLATDIR
+MULTIARCH
 ac_ct_CXX
 MAINCC
 CXX
+GREP
+CPP
 OBJEXT
 EXEEXT
 ac_ct_CC
@@ -795,6 +807,7 @@ enable_shared
 enable_profiling
 with_pydebug
 with_hash_algorithm
+with_address_sanitizer
 with_libs
 with_system_expat
 with_system_ffi
@@ -827,7 +840,10 @@ CFLAGS
 LDFLAGS
 LIBS
 CPPFLAGS
-CPP'
+CPP
+PKG_CONFIG
+PKG_CONFIG_PATH
+PKG_CONFIG_LIBDIR'
 
 
 # Initialize some variables set by options.
@@ -1368,7 +1384,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures python 3.4 to adapt to many kinds of systems.
+\`configure' configures python 3.6 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1433,7 +1449,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of python 3.4:";;
+     short | recursive ) echo "Configuration of python 3.6:";;
    esac
   cat <<\_ACEOF
 
@@ -1471,6 +1487,8 @@ Optional Packages:
   --with-pydebug          build with Py_DEBUG defined
   --with-hash-algorithm=[fnv|siphash24]
                           select hash algorithm
+  --with-address-sanitizer
+                          enable AddressSanitizer
   --with-libs='lib1 ...'  link against additional libs
   --with-system-expat     build pyexpat module using an installed expat
                           library
@@ -1513,6 +1531,11 @@ Some influential environment variables:
   CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I if
               you have headers in a nonstandard directory 
   CPP         C preprocessor
+  PKG_CONFIG  path to pkg-config utility
+  PKG_CONFIG_PATH
+              directories to add to pkg-config's search path
+  PKG_CONFIG_LIBDIR
+              path overriding pkg-config's built-in search path
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
@@ -1580,7 +1603,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-python configure 3.4
+python configure 3.6
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1632,21 +1655,20 @@ fi
 
 } # ac_fn_c_try_compile
 
-# ac_fn_c_try_link LINENO
-# -----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_link ()
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext conftest$ac_exeext
-  if { { ac_try="$ac_link"
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
 $as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>conftest.err
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
     grep -v '^ *+' conftest.err >conftest.er1
@@ -1654,44 +1676,37 @@ $as_echo "$ac_try_echo"; } >&5
     mv -f conftest.er1 conftest.err
   fi
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && {
-	 test -z "$ac_c_werror_flag" ||
+  test $ac_status = 0; } > conftest.i && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
 	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext && {
-	 test "$cross_compiling" = yes ||
-	 test -x conftest$ac_exeext
        }; then :
   ac_retval=0
 else
   $as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-	ac_retval=1
+    ac_retval=1
 fi
-  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
-  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
-  # interfere with the next link command; also delete a directory that is
-  # left behind by Apple's compiler.  We do this before executing the actions.
-  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
   as_fn_set_status $ac_retval
 
-} # ac_fn_c_try_link
+} # ac_fn_c_try_cpp
 
-# ac_fn_c_try_cpp LINENO
-# ----------------------
-# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_cpp ()
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if { { ac_try="$ac_cpp conftest.$ac_ext"
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
 $as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  (eval "$ac_link") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
     grep -v '^ *+' conftest.err >conftest.er1
@@ -1699,21 +1714,29 @@ $as_echo "$ac_try_echo"; } >&5
     mv -f conftest.er1 conftest.err
   fi
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } > conftest.i && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
 	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 test -x conftest$ac_exeext
        }; then :
   ac_retval=0
 else
   $as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-    ac_retval=1
+	ac_retval=1
 fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
   as_fn_set_status $ac_retval
 
-} # ac_fn_c_try_cpp
+} # ac_fn_c_try_link
 
 # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
 # -------------------------------------------------------
@@ -2419,7 +2442,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by python $as_me 3.4, which was
+It was created by python $as_me 3.6, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2949,6 +2972,9 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
 
 
 
+# pybuilddir.txt will be created by --generate-posix-vars in the Makefile
+rm -f pybuilddir.txt
+
 if test "$cross_compiling" = yes; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for python interpreter for cross build" >&5
 $as_echo_n "checking for python interpreter for cross build... " >&6; }
@@ -2989,7 +3015,7 @@ rm confdefs.h
 mv confdefs.h.new confdefs.h
 
 
-VERSION=3.4
+VERSION=3.6
 
 # Version number of Python's own shared library file.
 
@@ -3445,6 +3471,21 @@ $as_echo "#define _POSIX_C_SOURCE 200809L" >>confdefs.h
 
 fi
 
+# On HP-UX mbstate_t requires _INCLUDE__STDC_A1_SOURCE
+case $ac_sys_system in
+  hp*|HP*)
+    define_stdc_a1=yes;;
+  *)
+    define_stdc_a1=no;;
+esac
+
+if test $define_stdc_a1 = yes
+then
+
+$as_echo "#define _INCLUDE__STDC_A1_SOURCE 1" >>confdefs.h
+
+fi
+
 #
 # SGI compilers allow the specification of the both the ABI and the
 # ISA on the command line.  Depending on the values of these switches,
@@ -4370,6 +4411,206 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if ${ac_cv_prog_CPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer  to  if __STDC__ is defined, since
+  #  exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include 
+#else
+# include 
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include 
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer  to  if __STDC__ is defined, since
+  #  exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include 
+#else
+# include 
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include 
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
 
 
 
@@ -4828,238 +5069,177 @@ $as_echo "$as_me:
 fi
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wl,--no-as-needed" >&5
-$as_echo_n "checking for -Wl,--no-as-needed... " >&6; }
-save_LDFLAGS="$LDFLAGS"
-LDFLAGS="$LDFLAGS -Wl,--no-as-needed"
-
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  NO_AS_NEEDED="-Wl,--no-as-needed"
-   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
-  NO_AS_NEEDED=""
-   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LDFLAGS="$save_LDFLAGS"
-
+MULTIARCH=$($CC --print-multiarch 2>/dev/null)
 
 
-# checks for UNIX variants that set C preprocessor variables
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
-$as_echo_n "checking how to run the C preprocessor... " >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
-  CPP=
-fi
-if test -z "$CPP"; then
-  if ${ac_cv_prog_CPP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-      # Double quotes because CPP needs to be expanded
-    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
-    do
-      ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer  to  if __STDC__ is defined, since
-  #  exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the platform triplet based on compiler characteristics" >&5
+$as_echo_n "checking for the platform triplet based on compiler characteristics... " >&6; }
+cat >> conftest.c <
+# error unknown platform triplet
 #endif
-		     Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
-  # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include 
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  # Broken: success on invalid input.
-continue
-else
-  # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
 
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-  break
-fi
-
-    done
-    ac_cv_prog_CPP=$CPP
-
-fi
-  CPP=$ac_cv_prog_CPP
-else
-  ac_cv_prog_CPP=$CPP
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
-$as_echo "$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer  to  if __STDC__ is defined, since
-  #  exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include 
-#else
-# include 
-#endif
-		     Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
+EOF
 
+if $CPP conftest.c >conftest.out 2>/dev/null; then
+  PLATFORM_TRIPLET=`grep -v '^#' conftest.out | grep -v '^ *$' | tr -d ' 	'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PLATFORM_TRIPLET" >&5
+$as_echo "$PLATFORM_TRIPLET" >&6; }
 else
-  # Broken: fails on valid input.
-continue
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.c conftest.out
 
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include 
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  # Broken: success on invalid input.
-continue
-else
-  # Passes both tests.
-ac_preproc_ok=:
-break
+if test x$PLATFORM_TRIPLET != x && test x$MULTIARCH != x; then
+  if test x$PLATFORM_TRIPLET != x$MULTIARCH; then
+    as_fn_error $? "internal configure error for the platform triplet, please file a bug report" "$LINENO" 5
+  fi
 fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+PLATDIR=plat-$MACHDEP
 
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
 
-else
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5; }
-fi
 
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wl,--no-as-needed" >&5
+$as_echo_n "checking for -Wl,--no-as-needed... " >&6; }
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS -Wl,--no-as-needed"
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
-$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if ${ac_cv_path_GREP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -z "$GREP"; then
-  ac_path_GREP_found=false
-  # Loop through the user's path and test for each of PROGNAME-LIST
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in grep ggrep; do
-    for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_GREP" || continue
-# Check for GNU ac_path_GREP and select it if it is found.
-  # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
-  ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    $as_echo 'GREP' >> "conftest.nl"
-    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    as_fn_arith $ac_count + 1 && ac_count=$as_val
-    if test $ac_count -gt ${ac_path_GREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_GREP="$ac_path_GREP"
-      ac_path_GREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
 
-      $ac_path_GREP_found && break 3
-    done
-  done
-  done
-IFS=$as_save_IFS
-  if test -z "$ac_cv_path_GREP"; then
-    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
-  fi
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  NO_AS_NEEDED="-Wl,--no-as-needed"
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
 else
-  ac_cv_path_GREP=$GREP
+  NO_AS_NEEDED=""
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LDFLAGS="$save_LDFLAGS"
+
 
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
-$as_echo "$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
 
+# checks for UNIX variants that set C preprocessor variables
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
 $as_echo_n "checking for egrep... " >&6; }
@@ -5379,10 +5559,6 @@ hp*|HP*)
     esac;;
 esac
 
-MULTIARCH=$($CC --print-multiarch 2>/dev/null)
-
-
-
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking LIBRARY" >&5
 $as_echo_n "checking LIBRARY... " >&6; }
@@ -5590,7 +5766,7 @@ $as_echo_n "checking LDLIBRARY... " >&6; }
 if test "$enable_framework"
 then
   LDLIBRARY='$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
-  RUNSHARED=DYLD_FRAMEWORK_PATH="`pwd`:$DYLD_FRAMEWORK_PATH"
+  RUNSHARED=DYLD_FRAMEWORK_PATH=`pwd`${DYLD_FRAMEWORK_PATH:+:${DYLD_FRAMEWORK_PATH}}
   BLDLIBRARY=''
 else
   BLDLIBRARY='$(LDLIBRARY)'
@@ -5610,7 +5786,7 @@ $as_echo "#define Py_ENABLE_SHARED 1" >>confdefs.h
     SunOS*)
 	  LDLIBRARY='libpython$(LDVERSION).so'
 	  BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lpython$(LDVERSION)'
-	  RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}
+	  RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
 	  INSTSONAME="$LDLIBRARY".$SOVERSION
 	  if test "$with_pydebug" != yes
 	  then
@@ -5620,12 +5796,7 @@ $as_echo "#define Py_ENABLE_SHARED 1" >>confdefs.h
     Linux*|GNU*|NetBSD*|FreeBSD*|DragonFly*|OpenBSD*)
 	  LDLIBRARY='libpython$(LDVERSION).so'
 	  BLDLIBRARY='-L. -lpython$(LDVERSION)'
-	  RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}
-	  case $ac_sys_system in
-	      FreeBSD*)
-		SOVERSION=`echo $SOVERSION|cut -d "." -f 1`
-		;;
-	  esac
+	  RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
 	  INSTSONAME="$LDLIBRARY".$SOVERSION
 	  if test "$with_pydebug" != yes
           then
@@ -5642,16 +5813,16 @@ $as_echo "#define Py_ENABLE_SHARED 1" >>confdefs.h
 			;;
 	  esac
 	  BLDLIBRARY='-Wl,+b,$(LIBDIR) -L. -lpython$(LDVERSION)'
-	  RUNSHARED=SHLIB_PATH=`pwd`:${SHLIB_PATH}
+	  RUNSHARED=SHLIB_PATH=`pwd`${SHLIB_PATH:+:${SHLIB_PATH}}
 	  ;;
     Darwin*)
     	LDLIBRARY='libpython$(LDVERSION).dylib'
 	BLDLIBRARY='-L. -lpython$(LDVERSION)'
-	RUNSHARED='DYLD_LIBRARY_PATH=`pwd`:${DYLD_LIBRARY_PATH}'
+	RUNSHARED=DYLD_LIBRARY_PATH=`pwd`${DYLD_LIBRARY_PATH:+:${DYLD_LIBRARY_PATH}}
 	;;
     AIX*)
 	LDLIBRARY='libpython$(LDVERSION).so'
-	RUNSHARED=LIBPATH=`pwd`:${LIBPATH}
+	RUNSHARED=LIBPATH=`pwd`${LIBPATH:+:${LIBPATH}}
 	;;
 
   esac
@@ -6033,6 +6204,57 @@ else
 fi
 
 
+for ac_prog in python$PACKAGE_VERSION python3 python
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_PYTHON+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$PYTHON"; then
+  ac_cv_prog_PYTHON="$PYTHON" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_PYTHON="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+PYTHON=$ac_cv_prog_PYTHON
+if test -n "$PYTHON"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5
+$as_echo "$PYTHON" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$PYTHON" && break
+done
+test -n "$PYTHON" || PYTHON="not-found"
+
+if test "$PYTHON" = not-found; then
+    OPCODEHGEN="@echo python: $PYTHON! cannot run Tools/scripts/generate_opcode_h.py"
+else
+    OPCODEHGEN="$PYTHON"
+fi
+
+
+
 case $MACHDEP in
 bsdos*|hp*|HP*)
 	# install -d does not work on BSDI or HP-UX
@@ -6215,6 +6437,80 @@ $as_echo "no" >&6; }
 fi
 
 
+# Enable PGO flags.
+# Extract the first word of "llvm-profdata", so it can be a program name with args.
+set dummy llvm-profdata; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LLVM_PROF_FOUND+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$LLVM_PROF_FOUND"; then
+  ac_cv_prog_LLVM_PROF_FOUND="$LLVM_PROF_FOUND" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_LLVM_PROF_FOUND="found"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_prog_LLVM_PROF_FOUND" && ac_cv_prog_LLVM_PROF_FOUND="not-found"
+fi
+fi
+LLVM_PROF_FOUND=$ac_cv_prog_LLVM_PROF_FOUND
+if test -n "$LLVM_PROF_FOUND"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LLVM_PROF_FOUND" >&5
+$as_echo "$LLVM_PROF_FOUND" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+LLVM_PROF_ERR=no
+case $CC in
+  *clang*)
+    # Any changes made here should be reflected in the GCC+Darwin case below
+    PGO_PROF_GEN_FLAG="-fprofile-instr-generate"
+    PGO_PROF_USE_FLAG="-fprofile-instr-use=code.profclangd"
+    LLVM_PROF_MERGER="llvm-profdata merge -output=code.profclangd *.profclangr"
+    LLVM_PROF_FILE="LLVM_PROFILE_FILE=\"code-%p.profclangr\""
+    if test $LLVM_PROF_FOUND = not-found
+    then
+      LLVM_PROF_ERR=yes
+    fi
+    ;;
+  *gcc*)
+    case $ac_sys_system in
+      Darwin*)
+        PGO_PROF_GEN_FLAG="-fprofile-instr-generate"
+        PGO_PROF_USE_FLAG="-fprofile-instr-use=code.profclangd"
+        LLVM_PROF_MERGER="llvm-profdata merge -output=code.profclangd *.profclangr"
+        LLVM_PROF_FILE="LLVM_PROFILE_FILE=\"code-%p.profclangr\""
+        if test $LLVM_PROF_FOUND = not-found
+        then
+          LLVM_PROF_ERR=yes
+        fi
+        ;;
+      *)
+        PGO_PROF_GEN_FLAG="-fprofile-generate"
+        PGO_PROF_USE_FLAG="-fprofile-use -fprofile-correction"
+        LLVM_PROF_MERGER="true"
+        LLVM_PROF_FILE=""
+        ;;
+    esac
+    ;;
+esac
+
 # XXX Shouldn't the code above that fiddles with BASECFLAGS and OPT be
 # merged with this chunk of code?
 
@@ -6254,7 +6550,11 @@ then
 	    if test "$Py_DEBUG" = 'true' ; then
 		# Optimization messes up debuggers, so turn it off for
 		# debug builds.
-		OPT="-g -O0 -Wall $STRICT_PROTO"
+                if "$CC" -v --help 2>/dev/null |grep -- -Og > /dev/null; then
+                    OPT="-g -Og -Wall $STRICT_PROTO"
+                else
+                    OPT="-g -O0 -Wall $STRICT_PROTO"
+                fi
 	    else
 		OPT="-g $WRAP -O3 -Wall $STRICT_PROTO"
 	    fi
@@ -6277,6 +6577,7 @@ fi
 
 
 
+
 # The -arch flags for universal builds on OSX
 UNIVERSAL_ARCH_FLAGS=
 
@@ -6437,7 +6738,95 @@ $as_echo "$ac_cv_declaration_after_statement_warning" >&6; }
 
     if test $ac_cv_declaration_after_statement_warning = yes
     then
-      BASECFLAGS="$BASECFLAGS -Werror=declaration-after-statement"
+      CFLAGS_NODIST="$CFLAGS_NODIST -Werror=declaration-after-statement"
+    fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can turn on $CC mixed sign comparison warning" >&5
+$as_echo_n "checking if we can turn on $CC mixed sign comparison warning... " >&6; }
+     ac_save_cc="$CC"
+     CC="$CC -Wsign-compare"
+     save_CFLAGS="$CFLAGS"
+     if ${ac_cv_enable_sign_compare_warning+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+           ac_cv_enable_sign_compare_warning=yes
+
+else
+
+           ac_cv_enable_sign_compare_warning=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+     CFLAGS="$save_CFLAGS"
+     CC="$ac_save_cc"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_sign_compare_warning" >&5
+$as_echo "$ac_cv_enable_sign_compare_warning" >&6; }
+
+    if test $ac_cv_enable_sign_compare_warning = yes
+    then
+      BASECFLAGS="$BASECFLAGS -Wsign-compare"
+    fi
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can turn on $CC unreachable code warning" >&5
+$as_echo_n "checking if we can turn on $CC unreachable code warning... " >&6; }
+     ac_save_cc="$CC"
+     CC="$CC -Wunreachable-code"
+     save_CFLAGS="$CFLAGS"
+     if ${ac_cv_enable_unreachable_code_warning+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+           ac_cv_enable_unreachable_code_warning=yes
+
+else
+
+           ac_cv_enable_unreachable_code_warning=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+     CFLAGS="$save_CFLAGS"
+     CC="$ac_save_cc"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_unreachable_code_warning" >&5
+$as_echo "$ac_cv_enable_unreachable_code_warning" >&6; }
+
+    # Don't enable unreachable code warning in debug mode, since it usually
+    # results in non-standard code paths.
+    if test $ac_cv_enable_unreachable_code_warning = yes && test "$Py_DEBUG" != "true"
+    then
+      BASECFLAGS="$BASECFLAGS -Wunreachable-code"
     fi
 
     # if using gcc on alpha, use -mieee to get (near) full IEEE 754
@@ -6536,10 +6925,16 @@ $as_echo "$CC" >&6; }
 
         { $as_echo "$as_me:${as_lineno-$LINENO}: checking which MACOSX_DEPLOYMENT_TARGET to use" >&5
 $as_echo_n "checking which MACOSX_DEPLOYMENT_TARGET to use... " >&6; }
-        cur_target=`sw_vers -productVersion | sed 's/\(10\.[0-9]*\).*/\1/'`
-        if test ${cur_target} '>' 10.2 && \
-           test ${cur_target} '<' 10.6
+        cur_target_major=`sw_vers -productVersion | \
+                sed 's/\([0-9]*\)\.\([0-9]*\).*/\1/'`
+        cur_target_minor=`sw_vers -productVersion | \
+                sed 's/\([0-9]*\)\.\([0-9]*\).*/\2/'`
+        cur_target="${cur_target_major}.${cur_target_minor}"
+        if test ${cur_target_major} -eq 10 && \
+           test ${cur_target_minor} -ge 3 && \
+           test ${cur_target_minor} -le 5
         then
+            # OS X 10.3 through 10.5
             cur_target=10.3
             if test ${enable_universalsdk}
             then
@@ -6954,11 +7349,9 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h
 
 fi
 
-ac_save_cppflags="$CPPFLAGS"
-CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw"
-for ac_header in asm/types.h conio.h curses.h direct.h dlfcn.h errno.h \
+for ac_header in asm/types.h conio.h direct.h dlfcn.h errno.h \
 fcntl.h grp.h \
-ieeefp.h io.h langinfo.h libintl.h ncurses.h process.h pthread.h \
+ieeefp.h io.h langinfo.h libintl.h process.h pthread.h \
 sched.h shadow.h signal.h stdint.h stropts.h termios.h \
 unistd.h utime.h \
 poll.h sys/devpoll.h sys/epoll.h sys/poll.h \
@@ -6982,7 +7375,6 @@ fi
 
 done
 
-CPPFLAGS=$ac_save_cppflags
 ac_header_dirent=no
 for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
   as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
@@ -7219,26 +7611,6 @@ fi
 done
 
 
-
-# On Solaris, term.h requires curses.h
-for ac_header in term.h
-do :
-  ac_fn_c_check_header_compile "$LINENO" "term.h" "ac_cv_header_term_h" "
-#ifdef HAVE_CURSES_H
-#include 
-#endif
-
-"
-if test "x$ac_cv_header_term_h" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_TERM_H 1
-_ACEOF
-
-fi
-
-done
-
-
 # On Linux, netlink.h requires asm/types.h
 for ac_header in linux/netlink.h
 do :
@@ -8548,12 +8920,14 @@ then
 		# Use -undefined dynamic_lookup whenever possible (10.3 and later).
 		# This allows an extension to be used in any Python
 
-		if test ${MACOSX_DEPLOYMENT_TARGET} '>' 10.2
+		dep_target_major=`echo ${MACOSX_DEPLOYMENT_TARGET} | \
+				sed 's/\([0-9]*\)\.\([0-9]*\).*/\1/'`
+		dep_target_minor=`echo ${MACOSX_DEPLOYMENT_TARGET} | \
+				sed 's/\([0-9]*\)\.\([0-9]*\).*/\2/'`
+		if test ${dep_target_major} -eq 10 && \
+		   test ${dep_target_minor} -le 2
 		then
-			LDSHARED='$(CC) -bundle -undefined dynamic_lookup'
-			LDCXXSHARED='$(CXX) -bundle -undefined dynamic_lookup'
-			BLDSHARED="$LDSHARED"
-		else
+			# building for OS X 10.0 through 10.2
 			LDSHARED='$(CC) -bundle'
 			LDCXXSHARED='$(CXX) -bundle'
 			if test "$enable_framework" ; then
@@ -8567,6 +8941,11 @@ then
 				LDSHARED="$LDSHARED "'-bundle_loader $(BINDIR)/python$(VERSION)$(EXE)'
 				LDCXXSHARED="$LDCXXSHARED "'-bundle_loader $(BINDIR)/python$(VERSION)$(EXE)'
 			fi
+		else
+			# building for OS X 10.3 and later
+			LDSHARED='$(CC) -bundle -undefined dynamic_lookup'
+			LDCXXSHARED='$(CXX) -bundle -undefined dynamic_lookup'
+			BLDSHARED="$LDSHARED"
 		fi
 		;;
 	Linux*|GNU*|QNX*)
@@ -8889,10 +9268,52 @@ if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
 #define HAVE_LIBDLD 1
 _ACEOF
 
-  LIBS="-ldld $LIBS"
+  LIBS="-ldld $LIBS"
+
+fi
+	# Dynamic linking for HP-UX
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for RAND_egd in -lcrypto" >&5
+$as_echo_n "checking for RAND_egd in -lcrypto... " >&6; }
+if ${ac_cv_lib_crypto_RAND_egd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char RAND_egd ();
+int
+main ()
+{
+return RAND_egd ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_crypto_RAND_egd=yes
+else
+  ac_cv_lib_crypto_RAND_egd=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_RAND_egd" >&5
+$as_echo "$ac_cv_lib_crypto_RAND_egd" >&6; }
+if test "x$ac_cv_lib_crypto_RAND_egd" = xyes; then :
+
+$as_echo "#define HAVE_RAND_EGD 1" >>confdefs.h
 
 fi
-	# Dynamic linking for HP-UX
+
 
 # only check for sem_init if thread support is requested
 if test "$with_threads" = "yes" -o -z "$with_threads"; then
@@ -9110,6 +9531,23 @@ $as_echo "default" >&6; }
 fi
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-address-sanitizer" >&5
+$as_echo_n "checking for --with-address-sanitizer... " >&6; }
+
+# Check whether --with-address_sanitizer was given.
+if test "${with_address_sanitizer+set}" = set; then :
+  withval=$with_address_sanitizer;
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $withval" >&5
+$as_echo "$withval" >&6; }
+BASECFLAGS="-fsanitize=address -fno-omit-frame-pointer $BASECFLAGS"
+LDFLAGS="-fsanitize=address $LDFLAGS"
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
 # Most SVR4 platforms (e.g. Solaris) need -lsocket and -lnsl.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for t_open in -lnsl" >&5
 $as_echo_n "checking for t_open in -lnsl... " >&6; }
@@ -9208,7 +9646,15 @@ $as_echo "no" >&6; }
 fi
 
 
-if test -n "$ac_tool_prefix"; then
+
+
+
+
+
+
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+	if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
 set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@@ -9306,6 +9752,20 @@ else
   PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
 fi
 
+fi
+if test -n "$PKG_CONFIG"; then
+	_pkg_min_version=0.9.0
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		PKG_CONFIG=""
+	fi
+fi
 
 # Check for use of the system expat library
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-system-expat" >&5
@@ -10248,6 +10708,36 @@ if test "$ipv6" = "yes" -a "$ipv6lib" != "none"; then
 	fi
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CAN_RAW_FD_FRAMES" >&5
+$as_echo_n "checking for CAN_RAW_FD_FRAMES... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+ /* CAN_RAW_FD_FRAMES available check */
+#include 
+int
+main ()
+{
+int can_raw_fd_frames = CAN_RAW_FD_FRAMES;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+
+$as_echo "#define HAVE_LINUX_CAN_RAW_FD_FRAMES 1" >>confdefs.h
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OSX 10.5 SDK or later" >&5
 $as_echo_n "checking for OSX 10.5 SDK or later... " >&6; }
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -10453,7 +10943,7 @@ fi
 for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
  clock confstr ctermid dup3 execv faccessat fchmod fchmodat fchown fchownat \
  fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
- futimens futimes gai_strerror \
+ futimens futimes gai_strerror getentropy \
  getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \
  getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
  if_nameindex \
@@ -11734,6 +12224,7 @@ fi
 $as_echo "$ac_cv_lib_rt_clock_gettime" >&6; }
 if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then :
 
+        LIBS="$LIBS -lrt"
         $as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h
 
 
@@ -12986,12 +13477,13 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"; then :
   have_gcc_asm_for_x64=yes
 else
   have_gcc_asm_for_x64=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_asm_for_x64" >&5
 $as_echo "$have_gcc_asm_for_x64" >&6; }
 if test "$have_gcc_asm_for_x64" = yes
@@ -13162,12 +13654,13 @@ main ()
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"; then :
   have_gcc_asm_for_x87=yes
 else
   have_gcc_asm_for_x87=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_asm_for_x87" >&5
 $as_echo "$have_gcc_asm_for_x87" >&6; }
 if test "$have_gcc_asm_for_x87" = yes
@@ -13177,6 +13670,39 @@ $as_echo "#define HAVE_GCC_ASM_FOR_X87 1" >>confdefs.h
 
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we can use gcc inline assembler to get and set mc68881 fpcr" >&5
+$as_echo_n "checking whether we can use gcc inline assembler to get and set mc68881 fpcr... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  unsigned int fpcr;
+  __asm__ __volatile__ ("fmove.l %%fpcr,%0" : "=g" (fpcr));
+  __asm__ __volatile__ ("fmove.l %0,%%fpcr" : : "g" (fpcr));
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  have_gcc_asm_for_mc68881=yes
+else
+  have_gcc_asm_for_mc68881=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_asm_for_mc68881" >&5
+$as_echo "$have_gcc_asm_for_mc68881" >&6; }
+if test "$have_gcc_asm_for_mc68881" = yes
+then
+
+$as_echo "#define HAVE_GCC_ASM_FOR_MC68881 1" >>confdefs.h
+
+fi
+
 # Detect whether system arithmetic is subject to x87-style double
 # rounding issues.  The result of this test has little meaning on non
 # IEEE 754 platforms.  On IEEE 754, test should return 1 if rounding
@@ -13919,13 +14445,13 @@ $as_echo_n "checking ABIFLAGS... " >&6; }
 $as_echo "$ABIFLAGS" >&6; }
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking SOABI" >&5
 $as_echo_n "checking SOABI... " >&6; }
-SOABI='cpython-'`echo $VERSION | tr -d .`${ABIFLAGS}
+SOABI='cpython-'`echo $VERSION | tr -d .`${ABIFLAGS}${PLATFORM_TRIPLET:+-$PLATFORM_TRIPLET}
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SOABI" >&5
 $as_echo "$SOABI" >&6; }
 
 
 case $ac_sys_system in
-    Linux*|GNU*)
+    Linux*|GNU*|Darwin)
 	EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX};;
     *)
 	EXT_SUFFIX=${SHLIB_SUFFIX};;
@@ -13938,7 +14464,7 @@ LDVERSION='$(VERSION)$(ABIFLAGS)'
 $as_echo "$LDVERSION" >&6; }
 
 
-LIBPL="${prefix}/lib/python${VERSION}/config-${LDVERSION}"
+LIBPL='$(prefix)'"/lib/python${VERSION}/config-${LDVERSION}"
 
 
 # Check whether right shifting a negative integer extends the sign bit
@@ -14326,6 +14852,49 @@ rm -f conftest*
 
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for append_history in -lreadline" >&5
+$as_echo_n "checking for append_history in -lreadline... " >&6; }
+if ${ac_cv_lib_readline_append_history+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lreadline $READLINE_LIBS $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char append_history ();
+int
+main ()
+{
+return append_history ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_readline_append_history=yes
+else
+  ac_cv_lib_readline_append_history=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_append_history" >&5
+$as_echo "$ac_cv_lib_readline_append_history" >&6; }
+if test "x$ac_cv_lib_readline_append_history" = xyes; then :
+
+$as_echo "#define HAVE_RL_APPEND_HISTORY 1" >>confdefs.h
+
+fi
+
+
 # End of readline checks: restore LIBS
 LIBS=$LIBS_no_readline
 
@@ -14662,8 +15231,43 @@ $as_echo "#define HAVE_STAT_TV_NSEC2 1" >>confdefs.h
 
 fi
 
+# first curses header check
 ac_save_cppflags="$CPPFLAGS"
 CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw"
+
+for ac_header in curses.h ncurses.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+# On Solaris, term.h requires curses.h
+for ac_header in term.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "term.h" "ac_cv_header_term_h" "
+#ifdef HAVE_CURSES_H
+#include 
+#endif
+
+"
+if test "x$ac_cv_header_term_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_TERM_H 1
+_ACEOF
+
+fi
+
+done
+
+
 # On HP/UX 11.0, mvwdelch is a block with a return statement
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mvwdelch is an expression" >&5
 $as_echo_n "checking whether mvwdelch is an expression... " >&6; }
@@ -15207,7 +15811,7 @@ do
 done
 
 
-SRCDIRS="Parser Grammar Objects Python Modules Mac"
+SRCDIRS="Parser Grammar Objects Python Modules Mac Programs"
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build directories" >&5
 $as_echo_n "checking for build directories... " >&6; }
 for dir in $SRCDIRS; do
@@ -15348,6 +15952,72 @@ $as_echo "#define HAVE_IPA_PURE_CONST_BUG 1" >>confdefs.h
     esac
 fi
 
+# Check for stdatomic.h
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdatomic.h" >&5
+$as_echo_n "checking for stdatomic.h... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+    #include 
+    atomic_int value = ATOMIC_VAR_INIT(1);
+    _Atomic void *py_atomic_address = (void*) &value;
+    int main() {
+      int loaded_value = atomic_load(&value);
+      return 0;
+    }
+
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  have_stdatomic_h=yes
+else
+  have_stdatomic_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_stdatomic_h" >&5
+$as_echo "$have_stdatomic_h" >&6; }
+
+if test "$have_stdatomic_h" = yes; then
+
+$as_echo "#define HAVE_STD_ATOMIC 1" >>confdefs.h
+
+fi
+
+# Check for GCC >= 4.7 __atomic builtins
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC >= 4.7 __atomic builtins" >&5
+$as_echo_n "checking for GCC >= 4.7 __atomic builtins... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+    volatile int val = 1;
+    int main() {
+      __atomic_load_n(&val, __ATOMIC_SEQ_CST);
+      return 0;
+    }
+
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  have_builtin_atomic=yes
+else
+  have_builtin_atomic=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_builtin_atomic" >&5
+$as_echo "$have_builtin_atomic" >&6; }
+
+if test "$have_builtin_atomic" = yes; then
+
+$as_echo "#define HAVE_BUILTIN_ATOMIC 1" >>confdefs.h
+
+fi
+
 # ensurepip option
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ensurepip" >&5
 $as_echo_n "checking for ensurepip... " >&6; }
@@ -15373,6 +16043,111 @@ esac
 $as_echo "$ENSUREPIP" >&6; }
 
 
+# check if the dirent structure of a d_type field and DT_UNKNOWN is defined
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the dirent structure of a d_type field" >&5
+$as_echo_n "checking if the dirent structure of a d_type field... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+    #include 
+
+    int main() {
+      struct dirent entry;
+      return entry.d_type == DT_UNKNOWN;
+    }
+
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  have_dirent_d_type=yes
+else
+  have_dirent_d_type=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_dirent_d_type" >&5
+$as_echo "$have_dirent_d_type" >&6; }
+
+if test "$have_dirent_d_type" = yes; then
+
+$as_echo "#define HAVE_DIRENT_D_TYPE 1" >>confdefs.h
+
+fi
+
+# check if the Linux getrandom() syscall is available
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the Linux getrandom() syscall" >&5
+$as_echo_n "checking for the Linux getrandom() syscall... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+    #include 
+
+    int main() {
+        char buffer[1];
+        const size_t buflen = sizeof(buffer);
+        const int flags = 0;
+        /* ignore the result, Python checks for ENOSYS at runtime */
+        (void)syscall(SYS_getrandom, buffer, buflen, flags);
+        return 0;
+    }
+
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  have_getrandom_syscall=yes
+else
+  have_getrandom_syscall=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_getrandom_syscall" >&5
+$as_echo "$have_getrandom_syscall" >&6; }
+
+if test "$have_getrandom_syscall" = yes; then
+
+$as_echo "#define HAVE_GETRANDOM_SYSCALL 1" >>confdefs.h
+
+fi
+
+# check if the getrandom() function is available
+# the test was written for the Solaris function of 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the getrandom() function" >&5
+$as_echo_n "checking for the getrandom() function... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+    #include 
+
+    int main() {
+        char buffer[1];
+        const size_t buflen = sizeof(buffer);
+        const int flags = 0;
+        /* ignore the result, Python checks for ENOSYS at runtime */
+        (void)getrandom(buffer, buflen, flags);
+        return 0;
+    }
+
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  have_getrandom=yes
+else
+  have_getrandom=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_getrandom" >&5
+$as_echo "$have_getrandom" >&6; }
+
+if test "$have_getrandom" = yes; then
+
+$as_echo "#define HAVE_GETRANDOM 1" >>confdefs.h
+
+fi
+
 # generate output files
 ac_config_files="$ac_config_files Makefile.pre Modules/Setup.config Misc/python.pc Misc/python-config.sh"
 
@@ -15885,7 +16660,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by python $as_me 3.4, which was
+This file was extended by python $as_me 3.6, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -15947,7 +16722,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-python config.status 3.4
+python config.status 3.6
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index 14b3aef6046c..1f8b9eafdec4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,7 +3,7 @@ dnl * Please run autoreconf to test your changes! *
 dnl ***********************************************
 
 # Set VERSION so we only need to edit in one place (i.e., here)
-m4_define(PYTHON_VERSION, 3.4)
+m4_define(PYTHON_VERSION, 3.6)
 
 AC_PREREQ(2.65)
 
@@ -53,6 +53,9 @@ AC_CANONICAL_HOST
 AC_SUBST(build)
 AC_SUBST(host)
 
+# pybuilddir.txt will be created by --generate-posix-vars in the Makefile
+rm -f pybuilddir.txt
+
 if test "$cross_compiling" = yes; then
     AC_MSG_CHECKING([for python interpreter for cross build])
     if test -z "$PYTHON_FOR_BUILD"; then
@@ -422,7 +425,7 @@ if test "$cross_compiling" = yes; then
 	esac
 	_PYTHON_HOST_PLATFORM="$MACHDEP${_host_cpu:+-$_host_cpu}"
 fi
-	
+
 # Some systems cannot stand _XOPEN_SOURCE being defined at all; they
 # disable features if it is defined, without any means to access these
 # features as extensions. For these systems, we skip the definition of
@@ -522,6 +525,19 @@ then
   AC_DEFINE(_POSIX_C_SOURCE, 200809L, Define to activate features from IEEE Stds 1003.1-2008)
 fi
 
+# On HP-UX mbstate_t requires _INCLUDE__STDC_A1_SOURCE
+case $ac_sys_system in
+  hp*|HP*)
+    define_stdc_a1=yes;;
+  *)
+    define_stdc_a1=no;;
+esac
+
+if test $define_stdc_a1 = yes
+then
+  AC_DEFINE(_INCLUDE__STDC_A1_SOURCE, 1, Define to include mbstate_t for mbrtowc)
+fi
+
 #
 # SGI compilers allow the specification of the both the ABI and the
 # ISA on the command line.  Depending on the values of these switches,
@@ -648,6 +664,8 @@ then
 	fi
 fi
 AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_GREP
 
 AC_SUBST(CXX)
 AC_SUBST(MAINCC)
@@ -705,6 +723,142 @@ then
 fi
 
 
+MULTIARCH=$($CC --print-multiarch 2>/dev/null)
+AC_SUBST(MULTIARCH)
+
+AC_MSG_CHECKING([for the platform triplet based on compiler characteristics])
+cat >> conftest.c <conftest.out 2>/dev/null; then
+  PLATFORM_TRIPLET=`grep -v '^#' conftest.out | grep -v '^ *$' | tr -d ' 	'`
+  AC_MSG_RESULT([$PLATFORM_TRIPLET])
+else
+  AC_MSG_RESULT([none])
+fi
+rm -f conftest.c conftest.out
+
+if test x$PLATFORM_TRIPLET != x && test x$MULTIARCH != x; then
+  if test x$PLATFORM_TRIPLET != x$MULTIARCH; then
+    AC_MSG_ERROR([internal configure error for the platform triplet, please file a bug report])
+  fi
+fi 
+PLATDIR=plat-$MACHDEP
+AC_SUBST(PLATDIR)
+AC_SUBST(PLATFORM_TRIPLET)
+
+
 AC_MSG_CHECKING([for -Wl,--no-as-needed])
 save_LDFLAGS="$LDFLAGS"
 LDFLAGS="$LDFLAGS -Wl,--no-as-needed"
@@ -772,10 +926,6 @@ hp*|HP*)
     esac;;
 esac
 
-MULTIARCH=$($CC --print-multiarch 2>/dev/null)
-AC_SUBST(MULTIARCH)
-
-
 AC_SUBST(LIBRARY)
 AC_MSG_CHECKING(LIBRARY)
 if test -z "$LIBRARY"
@@ -915,7 +1065,7 @@ AC_MSG_CHECKING(LDLIBRARY)
 if test "$enable_framework"
 then
   LDLIBRARY='$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
-  RUNSHARED=DYLD_FRAMEWORK_PATH="`pwd`:$DYLD_FRAMEWORK_PATH"
+  RUNSHARED=DYLD_FRAMEWORK_PATH=`pwd`${DYLD_FRAMEWORK_PATH:+:${DYLD_FRAMEWORK_PATH}}
   BLDLIBRARY=''
 else
   BLDLIBRARY='$(LDLIBRARY)'
@@ -933,7 +1083,7 @@ if test $enable_shared = "yes"; then
     SunOS*)
 	  LDLIBRARY='libpython$(LDVERSION).so'
 	  BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lpython$(LDVERSION)'
-	  RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}
+	  RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
 	  INSTSONAME="$LDLIBRARY".$SOVERSION
 	  if test "$with_pydebug" != yes
 	  then
@@ -943,12 +1093,7 @@ if test $enable_shared = "yes"; then
     Linux*|GNU*|NetBSD*|FreeBSD*|DragonFly*|OpenBSD*)
 	  LDLIBRARY='libpython$(LDVERSION).so'
 	  BLDLIBRARY='-L. -lpython$(LDVERSION)'
-	  RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}
-	  case $ac_sys_system in
-	      FreeBSD*)
-		SOVERSION=`echo $SOVERSION|cut -d "." -f 1`
-		;;
-	  esac
+	  RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
 	  INSTSONAME="$LDLIBRARY".$SOVERSION
 	  if test "$with_pydebug" != yes
           then
@@ -965,16 +1110,16 @@ if test $enable_shared = "yes"; then
 			;;
 	  esac
 	  BLDLIBRARY='-Wl,+b,$(LIBDIR) -L. -lpython$(LDVERSION)'
-	  RUNSHARED=SHLIB_PATH=`pwd`:${SHLIB_PATH}
+	  RUNSHARED=SHLIB_PATH=`pwd`${SHLIB_PATH:+:${SHLIB_PATH}}
 	  ;;
     Darwin*)
     	LDLIBRARY='libpython$(LDVERSION).dylib'
 	BLDLIBRARY='-L. -lpython$(LDVERSION)'
-	RUNSHARED='DYLD_LIBRARY_PATH=`pwd`:${DYLD_LIBRARY_PATH}'
+	RUNSHARED=DYLD_LIBRARY_PATH=`pwd`${DYLD_LIBRARY_PATH:+:${DYLD_LIBRARY_PATH}}
 	;;
     AIX*)
 	LDLIBRARY='libpython$(LDVERSION).so'
-	RUNSHARED=LIBPATH=`pwd`:${LIBPATH}
+	RUNSHARED=LIBPATH=`pwd`${LIBPATH:+:${LIBPATH}}
 	;;
 
   esac
@@ -1023,6 +1168,15 @@ else
     ASDLGEN="$PYTHON"
 fi
 
+AC_SUBST(OPCODEHGEN)
+AC_CHECK_PROGS(PYTHON, python$PACKAGE_VERSION python3 python, not-found)
+if test "$PYTHON" = not-found; then
+    OPCODEHGEN="@echo python: $PYTHON! cannot run Tools/scripts/generate_opcode_h.py"
+else
+    OPCODEHGEN="$PYTHON"
+fi
+
+
 
 case $MACHDEP in
 bsdos*|hp*|HP*)
@@ -1064,6 +1218,49 @@ else AC_MSG_RESULT(no); Py_DEBUG='false'
 fi],
 [AC_MSG_RESULT(no)])
 
+# Enable PGO flags.
+AC_SUBST(PGO_PROF_GEN_FLAG)
+AC_SUBST(PGO_PROF_USE_FLAG)
+AC_SUBST(LLVM_PROF_MERGER)
+AC_SUBST(LLVM_PROF_FILE)
+AC_SUBST(LLVM_PROF_ERR)
+AC_SUBST(LLVM_PROF_FOUND)
+AC_CHECK_PROG(LLVM_PROF_FOUND, llvm-profdata, found, not-found)
+LLVM_PROF_ERR=no
+case $CC in
+  *clang*)
+    # Any changes made here should be reflected in the GCC+Darwin case below
+    PGO_PROF_GEN_FLAG="-fprofile-instr-generate"
+    PGO_PROF_USE_FLAG="-fprofile-instr-use=code.profclangd"
+    LLVM_PROF_MERGER="llvm-profdata merge -output=code.profclangd *.profclangr"
+    LLVM_PROF_FILE="LLVM_PROFILE_FILE=\"code-%p.profclangr\""
+    if test $LLVM_PROF_FOUND = not-found
+    then
+      LLVM_PROF_ERR=yes
+    fi
+    ;;
+  *gcc*)
+    case $ac_sys_system in
+      Darwin*)
+        PGO_PROF_GEN_FLAG="-fprofile-instr-generate"
+        PGO_PROF_USE_FLAG="-fprofile-instr-use=code.profclangd"
+        LLVM_PROF_MERGER="llvm-profdata merge -output=code.profclangd *.profclangr"
+        LLVM_PROF_FILE="LLVM_PROFILE_FILE=\"code-%p.profclangr\""
+        if test $LLVM_PROF_FOUND = not-found
+        then
+          LLVM_PROF_ERR=yes
+        fi
+        ;;
+      *)
+        PGO_PROF_GEN_FLAG="-fprofile-generate"
+        PGO_PROF_USE_FLAG="-fprofile-use -fprofile-correction"
+        LLVM_PROF_MERGER="true"
+        LLVM_PROF_FILE=""
+        ;;
+    esac
+    ;;
+esac
+
 # XXX Shouldn't the code above that fiddles with BASECFLAGS and OPT be
 # merged with this chunk of code?
 
@@ -1103,7 +1300,11 @@ then
 	    if test "$Py_DEBUG" = 'true' ; then
 		# Optimization messes up debuggers, so turn it off for
 		# debug builds.
-		OPT="-g -O0 -Wall $STRICT_PROTO"
+                if "$CC" -v --help 2>/dev/null |grep -- -Og > /dev/null; then
+                    OPT="-g -Og -Wall $STRICT_PROTO"
+                else
+                    OPT="-g -O0 -Wall $STRICT_PROTO"
+                fi
 	    else
 		OPT="-g $WRAP -O3 -Wall $STRICT_PROTO"
 	    fi
@@ -1125,6 +1326,7 @@ then
 fi
 
 AC_SUBST(BASECFLAGS)
+AC_SUBST(CFLAGS_NODIST)
 
 # The -arch flags for universal builds on OSX
 UNIVERSAL_ARCH_FLAGS=
@@ -1209,7 +1411,53 @@ yes)
 
     if test $ac_cv_declaration_after_statement_warning = yes
     then
-      BASECFLAGS="$BASECFLAGS -Werror=declaration-after-statement"
+      CFLAGS_NODIST="$CFLAGS_NODIST -Werror=declaration-after-statement"
+    fi
+
+    AC_MSG_CHECKING(if we can turn on $CC mixed sign comparison warning)
+     ac_save_cc="$CC"
+     CC="$CC -Wsign-compare"
+     save_CFLAGS="$CFLAGS"
+     AC_CACHE_VAL(ac_cv_enable_sign_compare_warning,
+       AC_COMPILE_IFELSE(
+         [
+	   AC_LANG_PROGRAM([[]], [[]])
+	 ],[
+           ac_cv_enable_sign_compare_warning=yes
+	 ],[
+           ac_cv_enable_sign_compare_warning=no
+	 ]))
+     CFLAGS="$save_CFLAGS"
+     CC="$ac_save_cc"
+    AC_MSG_RESULT($ac_cv_enable_sign_compare_warning)
+
+    if test $ac_cv_enable_sign_compare_warning = yes
+    then
+      BASECFLAGS="$BASECFLAGS -Wsign-compare"
+    fi
+
+    AC_MSG_CHECKING(if we can turn on $CC unreachable code warning)
+     ac_save_cc="$CC"
+     CC="$CC -Wunreachable-code"
+     save_CFLAGS="$CFLAGS"
+     AC_CACHE_VAL(ac_cv_enable_unreachable_code_warning,
+       AC_COMPILE_IFELSE(
+         [
+	   AC_LANG_PROGRAM([[]], [[]])
+	 ],[
+           ac_cv_enable_unreachable_code_warning=yes
+	 ],[
+           ac_cv_enable_unreachable_code_warning=no
+	 ]))
+     CFLAGS="$save_CFLAGS"
+     CC="$ac_save_cc"
+    AC_MSG_RESULT($ac_cv_enable_unreachable_code_warning)
+
+    # Don't enable unreachable code warning in debug mode, since it usually
+    # results in non-standard code paths.
+    if test $ac_cv_enable_unreachable_code_warning = yes && test "$Py_DEBUG" != "true"
+    then
+      BASECFLAGS="$BASECFLAGS -Wunreachable-code"
     fi
 
     # if using gcc on alpha, use -mieee to get (near) full IEEE 754
@@ -1305,10 +1553,16 @@ yes)
         # 4. If we are running on OS X 10.2 or earlier, good luck!
 
         AC_MSG_CHECKING(which MACOSX_DEPLOYMENT_TARGET to use)
-        cur_target=`sw_vers -productVersion | sed 's/\(10\.[[0-9]]*\).*/\1/'`
-        if test ${cur_target} '>' 10.2 && \
-           test ${cur_target} '<' 10.6
+        cur_target_major=`sw_vers -productVersion | \
+                sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
+        cur_target_minor=`sw_vers -productVersion | \
+                sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
+        cur_target="${cur_target_major}.${cur_target_minor}"
+        if test ${cur_target_major} -eq 10 && \
+           test ${cur_target_minor} -ge 3 && \
+           test ${cur_target_minor} -le 5
         then
+            # OS X 10.3 through 10.5
             cur_target=10.3
             if test ${enable_universalsdk}
             then
@@ -1533,11 +1787,9 @@ dnl AC_MSG_RESULT($cpp_type)
 
 # checks for header files
 AC_HEADER_STDC
-ac_save_cppflags="$CPPFLAGS"
-CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw"
-AC_CHECK_HEADERS(asm/types.h conio.h curses.h direct.h dlfcn.h errno.h \
+AC_CHECK_HEADERS(asm/types.h conio.h direct.h dlfcn.h errno.h \
 fcntl.h grp.h \
-ieeefp.h io.h langinfo.h libintl.h ncurses.h process.h pthread.h \
+ieeefp.h io.h langinfo.h libintl.h process.h pthread.h \
 sched.h shadow.h signal.h stdint.h stropts.h termios.h \
 unistd.h utime.h \
 poll.h sys/devpoll.h sys/epoll.h sys/poll.h \
@@ -1549,7 +1801,6 @@ sys/times.h sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h pty.h \
 libutil.h sys/resource.h netpacket/packet.h sysexits.h bluetooth.h \
 bluetooth/bluetooth.h linux/tipc.h spawn.h util.h alloca.h endian.h \
 sys/endian.h)
-CPPFLAGS=$ac_save_cppflags
 AC_HEADER_DIRENT
 AC_HEADER_MAJOR
 
@@ -1569,14 +1820,6 @@ AC_CHECK_HEADERS([net/if.h], [], [],
 #endif
 ])
 
-
-# On Solaris, term.h requires curses.h
-AC_CHECK_HEADERS(term.h,,,[
-#ifdef HAVE_CURSES_H
-#include 
-#endif
-])
-
 # On Linux, netlink.h requires asm/types.h
 AC_CHECK_HEADERS(linux/netlink.h,,,[
 #ifdef HAVE_ASM_TYPES_H
@@ -2015,12 +2258,14 @@ then
 		# Use -undefined dynamic_lookup whenever possible (10.3 and later).
 		# This allows an extension to be used in any Python
 
-		if test ${MACOSX_DEPLOYMENT_TARGET} '>' 10.2
+		dep_target_major=`echo ${MACOSX_DEPLOYMENT_TARGET} | \
+				sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
+		dep_target_minor=`echo ${MACOSX_DEPLOYMENT_TARGET} | \
+				sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
+		if test ${dep_target_major} -eq 10 && \
+		   test ${dep_target_minor} -le 2
 		then
-			LDSHARED='$(CC) -bundle -undefined dynamic_lookup'
-			LDCXXSHARED='$(CXX) -bundle -undefined dynamic_lookup'
-			BLDSHARED="$LDSHARED"
-		else
+			# building for OS X 10.0 through 10.2
 			LDSHARED='$(CC) -bundle'
 			LDCXXSHARED='$(CXX) -bundle'
 			if test "$enable_framework" ; then
@@ -2034,6 +2279,11 @@ then
 				LDSHARED="$LDSHARED "'-bundle_loader $(BINDIR)/python$(VERSION)$(EXE)'
 				LDCXXSHARED="$LDCXXSHARED "'-bundle_loader $(BINDIR)/python$(VERSION)$(EXE)'
 			fi
+		else
+			# building for OS X 10.3 and later
+			LDSHARED='$(CC) -bundle -undefined dynamic_lookup'
+			LDCXXSHARED='$(CXX) -bundle -undefined dynamic_lookup'
+			BLDSHARED="$LDSHARED"
 		fi
 		;;
 	Linux*|GNU*|QNX*)
@@ -2219,6 +2469,9 @@ AC_MSG_RESULT($SHLIBS)
 AC_CHECK_LIB(sendfile, sendfile)
 AC_CHECK_LIB(dl, dlopen)	# Dynamic linking for SunOS/Solaris and SYSV
 AC_CHECK_LIB(dld, shl_load)	# Dynamic linking for HP-UX
+AC_CHECK_LIB(crypto, RAND_egd,
+             AC_DEFINE(HAVE_RAND_EGD, 1,
+             [Define if the libcrypto has RAND_egd]))
 
 # only check for sem_init if thread support is requested
 if test "$with_threads" = "yes" -o -z "$with_threads"; then
@@ -2303,6 +2556,17 @@ esac
 ],
 [AC_MSG_RESULT(default)])
 
+AC_MSG_CHECKING(for --with-address-sanitizer)
+AC_ARG_WITH(address_sanitizer,
+            AS_HELP_STRING([--with-address-sanitizer],
+                           [enable AddressSanitizer]),
+[
+AC_MSG_RESULT($withval)
+BASECFLAGS="-fsanitize=address -fno-omit-frame-pointer $BASECFLAGS"
+LDFLAGS="-fsanitize=address $LDFLAGS"
+],
+[AC_MSG_RESULT(no)])
+
 # Most SVR4 platforms (e.g. Solaris) need -lsocket and -lnsl.
 AC_CHECK_LIB(nsl, t_open, [LIBS="-lnsl $LIBS"]) # SVR4
 AC_CHECK_LIB(socket, socket, [LIBS="-lsocket $LIBS"], [], $LIBS) # SVR4 sockets
@@ -2316,7 +2580,7 @@ LIBS="$withval $LIBS"
 ],
 [AC_MSG_RESULT(no)])
 
-AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+PKG_PROG_PKG_CONFIG
 
 # Check for use of the system expat library
 AC_MSG_CHECKING(for --with-system-expat)
@@ -2786,6 +3050,16 @@ if test "$ipv6" = "yes" -a "$ipv6lib" != "none"; then
 	fi
 fi
 
+AC_MSG_CHECKING(for CAN_RAW_FD_FRAMES)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ /* CAN_RAW_FD_FRAMES available check */
+#include ]],
+[[int can_raw_fd_frames = CAN_RAW_FD_FRAMES;]])],[
+  AC_DEFINE(HAVE_LINUX_CAN_RAW_FD_FRAMES, 1, [Define if compiling using Linux 3.6 or later.])
+  AC_MSG_RESULT(yes)
+],[
+  AC_MSG_RESULT(no)
+])
+
 AC_MSG_CHECKING(for OSX 10.5 SDK or later)
 AC_COMPILE_IFELSE([
   AC_LANG_PROGRAM([[#include ]], [[FSIORefNum fRef = 0]])
@@ -2916,7 +3190,7 @@ fi
 AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
  clock confstr ctermid dup3 execv faccessat fchmod fchmodat fchown fchownat \
  fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
- futimens futimes gai_strerror \
+ futimens futimes gai_strerror getentropy \
  getgrouplist getgroups getlogin getloadavg getpeername getpgid getpid \
  getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \
  if_nameindex \
@@ -3234,6 +3508,7 @@ AC_CHECK_FUNCS(gettimeofday,
 
 AC_CHECK_FUNCS(clock_gettime, [], [
     AC_CHECK_LIB(rt, clock_gettime, [
+        LIBS="$LIBS -lrt"
         AC_DEFINE(HAVE_CLOCK_GETTIME, 1)
         AC_DEFINE(TIMEMODULE_LIB, [rt],
                   [Library needed by timemodule.c: librt may be needed for clock_gettime()])
@@ -3678,7 +3953,7 @@ fi],
 # **************************************
 
 AC_MSG_CHECKING(for x64 gcc inline assembler)
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[
+AC_LINK_IFELSE(   [AC_LANG_PROGRAM([[]], [[
   __asm__ __volatile__ ("movq %rcx, %rax");
 ]])],[have_gcc_asm_for_x64=yes],[have_gcc_asm_for_x64=no])
 AC_MSG_RESULT($have_gcc_asm_for_x64)
@@ -3776,7 +4051,7 @@ fi
 # so we try it on all platforms.
 
 AC_MSG_CHECKING(whether we can use gcc inline assembler to get and set x87 control word)
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[
+AC_LINK_IFELSE(   [AC_LANG_PROGRAM([[]], [[
   unsigned short cw;
   __asm__ __volatile__ ("fnstcw %0" : "=m" (cw));
   __asm__ __volatile__ ("fldcw %0" : : "m" (cw));
@@ -3788,6 +4063,19 @@ then
     [Define if we can use gcc inline assembler to get and set x87 control word])
 fi
 
+AC_MSG_CHECKING(whether we can use gcc inline assembler to get and set mc68881 fpcr)
+AC_LINK_IFELSE(   [AC_LANG_PROGRAM([[]], [[
+  unsigned int fpcr;
+  __asm__ __volatile__ ("fmove.l %%fpcr,%0" : "=g" (fpcr));
+  __asm__ __volatile__ ("fmove.l %0,%%fpcr" : : "g" (fpcr));
+]])],[have_gcc_asm_for_mc68881=yes],[have_gcc_asm_for_mc68881=no])
+AC_MSG_RESULT($have_gcc_asm_for_mc68881)
+if test "$have_gcc_asm_for_mc68881" = yes
+then
+    AC_DEFINE(HAVE_GCC_ASM_FOR_MC68881, 1,
+    [Define if we can use gcc inline assembler to get and set mc68881 fpcr])
+fi
+
 # Detect whether system arithmetic is subject to x87-style double
 # rounding issues.  The result of this test has little meaning on non
 # IEEE 754 platforms.  On IEEE 754, test should return 1 if rounding
@@ -4069,12 +4357,12 @@ AC_SUBST(SOABI)
 AC_MSG_CHECKING(ABIFLAGS)
 AC_MSG_RESULT($ABIFLAGS)
 AC_MSG_CHECKING(SOABI)
-SOABI='cpython-'`echo $VERSION | tr -d .`${ABIFLAGS}
+SOABI='cpython-'`echo $VERSION | tr -d .`${ABIFLAGS}${PLATFORM_TRIPLET:+-$PLATFORM_TRIPLET}
 AC_MSG_RESULT($SOABI)
 
 AC_SUBST(EXT_SUFFIX)
 case $ac_sys_system in
-    Linux*|GNU*)
+    Linux*|GNU*|Darwin)
 	EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX};;
     *)
 	EXT_SUFFIX=${SHLIB_SUFFIX};;
@@ -4086,7 +4374,7 @@ AC_MSG_RESULT($LDVERSION)
 
 dnl define LIBPL after ABIFLAGS and LDVERSION is defined.
 AC_SUBST(PY_ENABLE_SHARED)
-LIBPL="${prefix}/lib/python${VERSION}/config-${LDVERSION}"
+LIBPL='$(prefix)'"/lib/python${VERSION}/config-${LDVERSION}"
 AC_SUBST(LIBPL)
 
 # Check whether right shifting a negative integer extends the sign bit
@@ -4209,6 +4497,10 @@ then
   [Define if you can turn off readline's signal handling.]), )
 fi
 
+AC_CHECK_LIB(readline, append_history,
+	AC_DEFINE(HAVE_RL_APPEND_HISTORY, 1,
+        [Define if readline supports append_history]), ,$READLINE_LIBS)
+
 # End of readline checks: restore LIBS
 LIBS=$LIBS_no_readline
 
@@ -4378,8 +4670,19 @@ then
   [Define if you have struct stat.st_mtimensec])
 fi
 
+# first curses header check
 ac_save_cppflags="$CPPFLAGS"
 CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw"
+
+AC_CHECK_HEADERS(curses.h ncurses.h)
+
+# On Solaris, term.h requires curses.h
+AC_CHECK_HEADERS(term.h,,,[
+#ifdef HAVE_CURSES_H
+#include 
+#endif
+])
+
 # On HP/UX 11.0, mvwdelch is a block with a return statement
 AC_MSG_CHECKING(whether mvwdelch is an expression)
 AC_CACHE_VAL(ac_cv_mvwdelch_is_expression,
@@ -4675,7 +4978,7 @@ do
 done
 
 AC_SUBST(SRCDIRS)
-SRCDIRS="Parser Grammar Objects Python Modules Mac"
+SRCDIRS="Parser Grammar Objects Python Modules Mac Programs"
 AC_MSG_CHECKING(for build directories)
 for dir in $SRCDIRS; do
     if test ! -d $dir; then
@@ -4767,6 +5070,47 @@ if test "$have_gcc_asm_for_x87" = yes; then
     esac
 fi
 
+# Check for stdatomic.h
+AC_MSG_CHECKING(for stdatomic.h)
+AC_LINK_IFELSE(
+[
+  AC_LANG_SOURCE([[
+    #include 
+    atomic_int value = ATOMIC_VAR_INIT(1);
+    _Atomic void *py_atomic_address = (void*) &value;
+    int main() {
+      int loaded_value = atomic_load(&value);
+      return 0;
+    }
+  ]])
+],[have_stdatomic_h=yes],[have_stdatomic_h=no])
+
+AC_MSG_RESULT($have_stdatomic_h)
+
+if test "$have_stdatomic_h" = yes; then
+    AC_DEFINE(HAVE_STD_ATOMIC, 1,
+              [Has stdatomic.h, atomic_int and _Atomic void* types work])
+fi
+
+# Check for GCC >= 4.7 __atomic builtins
+AC_MSG_CHECKING(for GCC >= 4.7 __atomic builtins)
+AC_LINK_IFELSE(
+[
+  AC_LANG_SOURCE([[
+    volatile int val = 1;
+    int main() {
+      __atomic_load_n(&val, __ATOMIC_SEQ_CST);
+      return 0;
+    }
+  ]])
+],[have_builtin_atomic=yes],[have_builtin_atomic=no])
+
+AC_MSG_RESULT($have_builtin_atomic)
+
+if test "$have_builtin_atomic" = yes; then
+    AC_DEFINE(HAVE_BUILTIN_ATOMIC, 1, [Has builtin atomics])
+fi
+
 # ensurepip option
 AC_MSG_CHECKING(for ensurepip)
 AC_ARG_WITH(ensurepip,
@@ -4782,6 +5126,75 @@ AS_CASE($with_ensurepip,
 AC_MSG_RESULT($ENSUREPIP)
 AC_SUBST(ENSUREPIP)
 
+# check if the dirent structure of a d_type field and DT_UNKNOWN is defined
+AC_MSG_CHECKING(if the dirent structure of a d_type field)
+AC_LINK_IFELSE(
+[
+  AC_LANG_SOURCE([[
+    #include 
+
+    int main() {
+      struct dirent entry;
+      return entry.d_type == DT_UNKNOWN;
+    }
+  ]])
+],[have_dirent_d_type=yes],[have_dirent_d_type=no])
+AC_MSG_RESULT($have_dirent_d_type)
+
+if test "$have_dirent_d_type" = yes; then
+    AC_DEFINE(HAVE_DIRENT_D_TYPE, 1,
+              [Define to 1 if the dirent structure has a d_type field])
+fi
+
+# check if the Linux getrandom() syscall is available
+AC_MSG_CHECKING(for the Linux getrandom() syscall)
+AC_LINK_IFELSE(
+[
+  AC_LANG_SOURCE([[
+    #include 
+
+    int main() {
+        char buffer[1];
+        const size_t buflen = sizeof(buffer);
+        const int flags = 0;
+        /* ignore the result, Python checks for ENOSYS at runtime */
+        (void)syscall(SYS_getrandom, buffer, buflen, flags);
+        return 0;
+    }
+  ]])
+],[have_getrandom_syscall=yes],[have_getrandom_syscall=no])
+AC_MSG_RESULT($have_getrandom_syscall)
+
+if test "$have_getrandom_syscall" = yes; then
+    AC_DEFINE(HAVE_GETRANDOM_SYSCALL, 1,
+              [Define to 1 if the Linux getrandom() syscall is available])
+fi
+
+# check if the getrandom() function is available
+# the test was written for the Solaris function of 
+AC_MSG_CHECKING(for the getrandom() function)
+AC_LINK_IFELSE(
+[
+  AC_LANG_SOURCE([[
+    #include 
+
+    int main() {
+        char buffer[1];
+        const size_t buflen = sizeof(buffer);
+        const int flags = 0;
+        /* ignore the result, Python checks for ENOSYS at runtime */
+        (void)getrandom(buffer, buflen, flags);
+        return 0;
+    }
+  ]])
+],[have_getrandom=yes],[have_getrandom=no])
+AC_MSG_RESULT($have_getrandom)
+
+if test "$have_getrandom" = yes; then
+    AC_DEFINE(HAVE_GETRANDOM, 1,
+              [Define to 1 if the getrandom() function is available])
+fi
+
 # generate output files
 AC_CONFIG_FILES(Makefile.pre Modules/Setup.config Misc/python.pc Misc/python-config.sh)
 AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix])
diff --git a/pyconfig.h.in b/pyconfig.h.in
index 29e1bfa89afe..b0cafb318574 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -101,6 +101,9 @@
 /* Define if `unsetenv` does not return an int. */
 #undef HAVE_BROKEN_UNSETENV
 
+/* Has builtin atomics */
+#undef HAVE_BUILTIN_ATOMIC
+
 /* Define this if you have the type _Bool. */
 #undef HAVE_C99_BOOL
 
@@ -180,6 +183,9 @@
 /* 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 */
+#undef HAVE_DIRENT_D_TYPE
+
 /* Define to 1 if you have the  header file, and it defines `DIR'.
    */
 #undef HAVE_DIRENT_H
@@ -313,6 +319,9 @@
 /* Define to 1 if you have the `gamma' function. */
 #undef HAVE_GAMMA
 
+/* 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
 
@@ -329,6 +338,9 @@
 /* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */
 #undef HAVE_GETC_UNLOCKED
 
+/* Define to 1 if you have the `getentropy' function. */
+#undef HAVE_GETENTROPY
+
 /* Define to 1 if you have the `getgrouplist' function. */
 #undef HAVE_GETGROUPLIST
 
@@ -383,6 +395,12 @@
 /* Define to 1 if you have the `getpwent' function. */
 #undef HAVE_GETPWENT
 
+/* Define to 1 if the getrandom() function is available */
+#undef HAVE_GETRANDOM
+
+/* Define to 1 if the Linux getrandom() syscall is available */
+#undef HAVE_GETRANDOM_SYSCALL
+
 /* Define to 1 if you have the `getresgid' function. */
 #undef HAVE_GETRESGID
 
@@ -516,6 +534,9 @@
 /* Define to 1 if you have the  header file. */
 #undef HAVE_LINUX_CAN_H
 
+/* Define if compiling using Linux 3.6 or later. */
+#undef HAVE_LINUX_CAN_RAW_FD_FRAMES
+
 /* Define to 1 if you have the  header file. */
 #undef HAVE_LINUX_CAN_RAW_H
 
@@ -672,6 +693,9 @@
 /* Define to 1 if you have the `pwrite' function. */
 #undef HAVE_PWRITE
 
+/* Define if the libcrypto has RAND_egd */
+#undef HAVE_RAND_EGD
+
 /* Define to 1 if you have the `readlink' function. */
 #undef HAVE_READLINK
 
@@ -687,6 +711,9 @@
 /* Define to 1 if you have the `renameat' function. */
 #undef HAVE_RENAMEAT
 
+/* Define if readline supports append_history */
+#undef HAVE_RL_APPEND_HISTORY
+
 /* Define if you have readline 2.1 */
 #undef HAVE_RL_CALLBACK
 
@@ -865,6 +892,9 @@
 /* Define to 1 if you have the  header file. */
 #undef HAVE_STDLIB_H
 
+/* Has stdatomic.h, atomic_int and _Atomic void* types work */
+#undef HAVE_STD_ATOMIC
+
 /* Define to 1 if you have the `strdup' function. */
 #undef HAVE_STRDUP
 
@@ -1382,6 +1412,9 @@
 /* Define on Linux to activate all library features */
 #undef _GNU_SOURCE
 
+/* Define to include mbstate_t for mbrtowc */
+#undef _INCLUDE__STDC_A1_SOURCE
+
 /* This must be defined on some systems to enable large file support. */
 #undef _LARGEFILE_SOURCE
 
diff --git a/setup.py b/setup.py
index d7f52afc81b5..da67731aa19f 100644
--- a/setup.py
+++ b/setup.py
@@ -3,6 +3,8 @@
 
 import sys, os, importlib.machinery, re, optparse
 from glob import glob
+import importlib._bootstrap
+import importlib.util
 import sysconfig
 
 from distutils import log
@@ -17,6 +19,17 @@
 
 cross_compiling = "_PYTHON_HOST_PLATFORM" in os.environ
 
+# Add special CFLAGS reserved for building the interpreter and the stdlib
+# modules (Issue #21121).
+cflags = sysconfig.get_config_var('CFLAGS')
+py_cflags_nodist = sysconfig.get_config_var('PY_CFLAGS_NODIST')
+sysconfig.get_config_vars()['CFLAGS'] = cflags + ' ' + py_cflags_nodist
+
+class Dummy:
+    """Hack for parallel build"""
+    ProcessPoolExecutor = None
+sys.modules['concurrent.futures.process'] = Dummy
+
 def get_platform():
     # cross build
     if "_PYTHON_HOST_PLATFORM" in os.environ:
@@ -165,6 +178,9 @@ class PyBuildExt(build_ext):
     def __init__(self, dist):
         build_ext.__init__(self, dist)
         self.failed = []
+        self.failed_on_import = []
+        if '-j' in os.environ.get('MAKEFLAGS', ''):
+            self.parallel = True
 
     def build_extensions(self):
 
@@ -244,9 +260,13 @@ def build_extensions(self):
 
         build_ext.build_extensions(self)
 
-        longest = max([len(e.name) for e in self.extensions])
-        if self.failed:
-            longest = max(longest, max([len(name) for name in self.failed]))
+        for ext in self.extensions:
+            self.check_extension_import(ext)
+
+        longest = max([len(e.name) for e in self.extensions], default=0)
+        if self.failed or self.failed_on_import:
+            all_failed = self.failed + self.failed_on_import
+            longest = max(longest, max([len(name) for name in all_failed]))
 
         def print_three_column(lst):
             lst.sort(key=str.lower)
@@ -274,6 +294,14 @@ def print_three_column(lst):
             print_three_column(failed)
             print()
 
+        if self.failed_on_import:
+            failed = self.failed_on_import[:]
+            print()
+            print("Following modules built successfully"
+                  " but were removed because they could not be imported:")
+            print_three_column(failed)
+            print()
+
     def build_extension(self, ext):
 
         if ext.name == '_ctypes':
@@ -287,6 +315,15 @@ def build_extension(self, ext):
                           (ext.name, sys.exc_info()[1]))
             self.failed.append(ext.name)
             return
+
+    def check_extension_import(self, ext):
+        # Don't try to import an extension that has failed to compile
+        if ext.name in self.failed:
+            self.announce(
+                'WARNING: skipping import check for failed build "%s"' %
+                ext.name, level=1)
+            return
+
         # Workaround for Mac OS X: The Carbon-based modules cannot be
         # reliably imported into a command-line Python
         if 'Carbon' in ext.extra_link_args:
@@ -327,10 +364,12 @@ def build_extension(self, ext):
             return
 
         loader = importlib.machinery.ExtensionFileLoader(ext.name, ext_filename)
+        spec = importlib.util.spec_from_file_location(ext.name, ext_filename,
+                                                      loader=loader)
         try:
-            loader.load_module()
+            importlib._bootstrap._load(spec)
         except ImportError as why:
-            self.failed.append(ext.name)
+            self.failed_on_import.append(ext.name)
             self.announce('*** WARNING: renaming "%s" since importing it'
                           ' failed: %s' % (ext.name, why), level=3)
             assert not self.inplace
@@ -340,17 +379,6 @@ def build_extension(self, ext):
                 os.remove(newname)
             os.rename(ext_filename, newname)
 
-            # XXX -- This relies on a Vile HACK in
-            # distutils.command.build_ext.build_extension().  The
-            # _built_objects attribute is stored there strictly for
-            # use here.
-            # If there is a failure, _built_objects may not be there,
-            # so catch the AttributeError and move on.
-            try:
-                for filename in self._built_objects:
-                    os.remove(filename)
-            except AttributeError:
-                self.announce('unable to remove files (ignored)')
         except:
             exc_type, why, tb = sys.exc_info()
             self.announce('*** WARNING: importing extension "%s" '
@@ -592,6 +620,8 @@ def detect_modules(self):
         exts.append( Extension('_testbuffer', ['_testbuffer.c']) )
         # Test loading multiple modules from one compiled file (http://bugs.python.org/issue16421)
         exts.append( Extension('_testimportmultiple', ['_testimportmultiple.c']) )
+        # Test multi-phase extension module init (PEP 489)
+        exts.append( Extension('_testmultiphase', ['_testmultiphase.c']) )
         # profiler (_lsprof is for cProfile.py)
         exts.append( Extension('_lsprof', ['_lsprof.c', 'rotatingtree.c']) )
         # static Unicode character database
@@ -693,7 +723,9 @@ def detect_modules(self):
         if host_platform == 'darwin':
             os_release = int(os.uname()[2].split('.')[0])
             dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
-            if dep_target and dep_target.split('.') < ['10', '5']:
+            if (dep_target and
+                    (tuple(int(n) for n in dep_target.split('.')[0:2])
+                        < (10, 5) ) ):
                 os_release = 8
             if os_release < 9:
                 # MacOSX 10.4 has a broken readline. Don't try to build
@@ -827,15 +859,6 @@ def detect_modules(self):
         exts.append( Extension('_sha1', ['sha1module.c'],
                                depends=['hashlib.h']) )
 
-        # SHA-3 (Keccak) module
-        sha3_depends = ['hashlib.h']
-        keccak = os.path.join(os.getcwd(), srcdir, 'Modules', '_sha3',
-                              'keccak')
-        for pattern in ('*.c', '*.h', '*.macros'):
-            sha3_depends.extend(glob(os.path.join(keccak, pattern)))
-        exts.append(Extension("_sha3", ["_sha3/sha3module.c"],
-                              depends=sha3_depends))
-
         # 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
@@ -1027,8 +1050,16 @@ class db_found(Exception): pass
             if db_setup_debug:
                 print("bsddb using BerkeleyDB lib:", db_ver, dblib)
                 print("bsddb lib dir:", dblib_dir, " inc dir:", db_incdir)
-            db_incs = [db_incdir]
             dblibs = [dblib]
+            # Only add the found library and include directories if they aren't
+            # already being searched. This avoids an explicit runtime library
+            # dependency.
+            if db_incdir in inc_dirs:
+                db_incs = None
+            else:
+                db_incs = [db_incdir]
+            if dblib_dir[0] in lib_dirs:
+                dblib_dir = None
         else:
             if db_setup_debug: print("db: no appropriate library found")
             db_incs = None
@@ -1139,11 +1170,13 @@ class db_found(Exception): pass
             # can end up with a bad search path order.
             if sqlite_incdir not in self.compiler.include_dirs:
                 include_dirs.append(sqlite_incdir)
+            # avoid a runtime library path for a system library dir
+            if sqlite_libdir and sqlite_libdir[0] in lib_dirs:
+                sqlite_libdir = None
             exts.append(Extension('_sqlite3', sqlite_srcs,
                                   define_macros=sqlite_defines,
                                   include_dirs=include_dirs,
                                   library_dirs=sqlite_libdir,
-                                  runtime_library_dirs=sqlite_libdir,
                                   extra_link_args=sqlite_extra_link_args,
                                   libraries=["sqlite3",]))
         else:
@@ -1208,7 +1241,7 @@ class db_found(Exception): pass
                                 libraries = gdbm_libs)
                             break
                 elif cand == "bdb":
-                    if db_incs is not None:
+                    if dblibs:
                         if dbm_setup_debug: print("building dbm using bdb")
                         dbmext = Extension('_dbm', ['_dbmmodule.c'],
                                            library_dirs=dblib_dir,
@@ -1544,7 +1577,7 @@ class db_found(Exception): pass
 
         if 'd' not in sys.abiflags:
             ext = Extension('xxlimited', ['xxlimited.c'],
-                            define_macros=[('Py_LIMITED_API', 1)])
+                            define_macros=[('Py_LIMITED_API', '0x03050000')])
             self.extensions.append(ext)
 
         return missing